diff --git a/designs/Caliptra/LICENSE-AdamsBridge b/designs/Caliptra/LICENSE-AdamsBridge new file mode 100644 index 0000000..261eeb9 --- /dev/null +++ b/designs/Caliptra/LICENSE-AdamsBridge @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. diff --git a/designs/Caliptra/LICENSE-Caliptra b/designs/Caliptra/LICENSE-Caliptra new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/designs/Caliptra/LICENSE-Caliptra @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. diff --git a/designs/Caliptra/descriptor.yaml b/designs/Caliptra/descriptor.yaml new file mode 100644 index 0000000..9b8dcfe --- /dev/null +++ b/designs/Caliptra/descriptor.yaml @@ -0,0 +1,706 @@ +origin: + - repository: https://github.com/chipsalliance/caliptra-rtl.git + revision: 0d5d4097f461ad225edc7a040834fb4b4dae2138 + licenses: + - LICENSE-Caliptra + - repository: https://github.com/chipsalliance/adams-bridge.git + revision: b694086587c3338047e28e40083337b3428022c0 + licenses: + - LICENSE-AdamsBridge + +compile: + verilogSourceFiles: + # caliptra-rtl + - src/caliptra-rtl/config_defines.svh + - src/caliptra-rtl/common_defines.sv + - src/caliptra-rtl/el2_pdef.vh + - src/caliptra-rtl/el2_def.sv + - src/caliptra-rtl/aes_clp_reg_pkg.sv + - src/caliptra-rtl/aes_pkg.sv + - src/caliptra-rtl/aes_reg_pkg.sv + - src/caliptra-rtl/aes_sbox_canright_pkg.sv + - src/caliptra-rtl/ahb_defines_pkg.sv + - src/caliptra-rtl/axi_dma_reg_pkg.sv + - src/caliptra-rtl/axi_pkg.sv + - src/caliptra-rtl/caliptra_prim_alert_pkg.sv + - src/caliptra-rtl/caliptra_prim_cipher_pkg.sv + - src/caliptra-rtl/caliptra_prim_count_pkg.sv + - src/caliptra-rtl/caliptra_prim_esc_pkg.sv + - src/caliptra-rtl/caliptra_prim_mubi_pkg.sv + - src/caliptra-rtl/caliptra_prim_otp_pkg.sv + - src/caliptra-rtl/caliptra_prim_pkg.sv + - src/caliptra-rtl/caliptra_prim_ram_1p_pkg.sv + - src/caliptra-rtl/caliptra_prim_secded_pkg.sv + - src/caliptra-rtl/caliptra_prim_sparse_fsm_pkg.sv + - src/caliptra-rtl/caliptra_prim_subreg_pkg.sv + - src/caliptra-rtl/caliptra_prim_trivium_pkg.sv + - src/caliptra-rtl/caliptra_prim_util_pkg.sv + - src/caliptra-rtl/caliptra_tlul_pkg.sv + - src/caliptra-rtl/caliptra_top_tb_pkg.sv + - src/caliptra-rtl/csrng_pkg.sv + - src/caliptra-rtl/csrng_reg_pkg.sv + - src/caliptra-rtl/doe_defines_pkg.sv + - src/caliptra-rtl/doe_reg_pkg.sv + - src/caliptra-rtl/dv_defines_pkg.sv + - src/caliptra-rtl/dv_reg_pkg.sv + - src/caliptra-rtl/ecc_defines_pkg.sv + - src/caliptra-rtl/ecc_dsa_uop_pkg.sv + - src/caliptra-rtl/ecc_params_pkg.sv + - src/caliptra-rtl/ecc_pm_uop_pkg.sv + - src/caliptra-rtl/ecc_reg_pkg.sv + - src/caliptra-rtl/edn_pkg.sv + - src/caliptra-rtl/entropy_src_ack_sm_pkg.sv + - src/caliptra-rtl/entropy_src_main_sm_pkg.sv + - src/caliptra-rtl/entropy_src_pkg.sv + - src/caliptra-rtl/entropy_src_reg_pkg.sv + - src/caliptra-rtl/hmac_param_pkg.sv + - src/caliptra-rtl/hmac_reg_pkg.sv + - src/caliptra-rtl/keymgr_pkg.sv + - src/caliptra-rtl/kmac_pkg.sv + - src/caliptra-rtl/kmac_reg_pkg.sv + - src/caliptra-rtl/kv_defines_pkg.sv + - src/caliptra-rtl/kv_reg_pkg.sv + - src/caliptra-rtl/lc_ctrl_pkg.sv + - src/caliptra-rtl/lc_ctrl_reg_pkg.sv + - src/caliptra-rtl/lc_ctrl_state_pkg.sv + - src/caliptra-rtl/mbox_csr_pkg.sv + - src/caliptra-rtl/mbox_pkg.sv + - src/caliptra-rtl/ot_sha3_pkg.sv + - src/caliptra-rtl/pv_defines_pkg.sv + - src/caliptra-rtl/pv_reg_pkg.sv + - src/caliptra-rtl/sha256_params_pkg.sv + - src/caliptra-rtl/sha256_reg_pkg.sv + - src/caliptra-rtl/sha3_param_pkg.sv + - src/caliptra-rtl/sha3_pkg.sv + - src/caliptra-rtl/sha3_reg_pkg.sv + - src/caliptra-rtl/sha512_acc_csr_pkg.sv + - src/caliptra-rtl/sha512_masked_defines_pkg.sv + - src/caliptra-rtl/sha512_params_pkg.sv + - src/caliptra-rtl/sha512_reg_pkg.sv + - src/caliptra-rtl/soc_ifc_pkg.sv + - src/caliptra-rtl/soc_ifc_reg_pkg.sv + - src/caliptra-rtl/aes_cipher_control_fsm_n.sv + - src/caliptra-rtl/aes_cipher_control_fsm_p.sv + - src/caliptra-rtl/aes_cipher_control_fsm.sv + - src/caliptra-rtl/aes_cipher_control.sv + - src/caliptra-rtl/aes_cipher_core.sv + - src/caliptra-rtl/aes_clp_reg.sv + - src/caliptra-rtl/aes_clp_wrapper.sv + - src/caliptra-rtl/aes_control_fsm_n.sv + - src/caliptra-rtl/aes_control_fsm_p.sv + - src/caliptra-rtl/aes_control_fsm.sv + - src/caliptra-rtl/aes_control.sv + - src/caliptra-rtl/aes_core.sv + - src/caliptra-rtl/aes_cov_bind.sv + - src/caliptra-rtl/aes_cov_if.sv + - src/caliptra-rtl/aes_ctr_fsm_n.sv + - src/caliptra-rtl/aes_ctr_fsm_p.sv + - src/caliptra-rtl/aes_ctr_fsm.sv + - src/caliptra-rtl/aes_ctrl_gcm_reg_shadowed.sv + - src/caliptra-rtl/aes_ctrl_reg_shadowed.sv + - src/caliptra-rtl/aes_ctr.sv + - src/caliptra-rtl/aes_ghash.sv + - src/caliptra-rtl/aes_key_expand.sv + - src/caliptra-rtl/aes_mix_columns.sv + - src/caliptra-rtl/aes_mix_single_column.sv + - src/caliptra-rtl/aes_prng_clearing.sv + - src/caliptra-rtl/aes_prng_masking.sv + - src/caliptra-rtl/aes_reduced_round.sv + - src/caliptra-rtl/aes_reg_status.sv + - src/caliptra-rtl/aes_reg_top.sv + - src/caliptra-rtl/aes_sbox_canright_masked_noreuse.sv + - src/caliptra-rtl/aes_sbox_canright_masked.sv + - src/caliptra-rtl/aes_sbox_canright.sv + - src/caliptra-rtl/aes_sbox_dom.sv + - src/caliptra-rtl/aes_sbox_lut.sv + - src/caliptra-rtl/aes_sbox.sv + - src/caliptra-rtl/aes_sel_buf_chk.sv + - src/caliptra-rtl/aes_shift_rows.sv + - src/caliptra-rtl/aes_sub_bytes.sv + - src/caliptra-rtl/aes.sv + - src/caliptra-rtl/ahb_lite_2to1_mux.sv + - src/caliptra-rtl/ahb_lite_address_decoder.sv + - src/caliptra-rtl/ahb_lite_bus_inf.sv + - src/caliptra-rtl/ahb_lite_bus.sv + - src/caliptra-rtl/ahb_slv_sif.sv + - src/caliptra-rtl/ahb_to_axi4.sv + - src/caliptra-rtl/ahb_to_reg_adapter.sv + - src/caliptra-rtl/axi4_to_ahb.sv + - src/caliptra-rtl/axi_addr.v + - src/caliptra-rtl/axi_dma_ctrl.sv + - src/caliptra-rtl/axi_dma_reg.sv + - src/caliptra-rtl/axi_dma_req_if.sv + - src/caliptra-rtl/axi_dma_top_cov_bind.sv + - src/caliptra-rtl/axi_dma_top_cov_if.sv + - src/caliptra-rtl/axi_dma_top_cov_props.sv + - src/caliptra-rtl/axi_dma_top.sv + - src/caliptra-rtl/axi_if.sv + - src/caliptra-rtl/axi_mgr_rd.sv + - src/caliptra-rtl/axi_mgr_wr.sv + - src/caliptra-rtl/axi_sub_arb.sv + - src/caliptra-rtl/axi_sub_rd.sv + - src/caliptra-rtl/axi_sub.sv + - src/caliptra-rtl/axi_sub_wr.sv + - src/caliptra-rtl/beh_lib.sv + - src/caliptra-rtl/caliptra_2ff_sync.sv + - src/caliptra-rtl/caliptra_ahb_srom.sv + - src/caliptra-rtl/caliptra_axi_sram.sv + - src/caliptra-rtl/caliptra_icg.sv + - src/caliptra-rtl/caliptra_prim_alert_receiver.sv + - src/caliptra-rtl/caliptra_prim_alert_sender.sv + - src/caliptra-rtl/caliptra_prim_arbiter_fixed.sv + - src/caliptra-rtl/caliptra_prim_arbiter_ppc.sv + - src/caliptra-rtl/caliptra_prim_arbiter_tree.sv + - src/caliptra-rtl/caliptra_prim_blanker.sv + - src/caliptra-rtl/caliptra_prim_buf.sv + - src/caliptra-rtl/caliptra_prim_cdc_rand_delay.sv + - src/caliptra-rtl/caliptra_prim_clock_mux2.sv + - src/caliptra-rtl/caliptra_prim_count.sv + - src/caliptra-rtl/caliptra_prim_diff_decode.sv + - src/caliptra-rtl/caliptra_prim_dom_and_2share.sv + - src/caliptra-rtl/caliptra_prim_double_lfsr.sv + - src/caliptra-rtl/caliptra_prim_edge_detector.sv + - src/caliptra-rtl/caliptra_prim_edn_req.sv + - src/caliptra-rtl/caliptra_prim_esc_receiver.sv + - src/caliptra-rtl/caliptra_prim_fifo_async_simple.sv + - src/caliptra-rtl/caliptra_prim_fifo_async.sv + - src/caliptra-rtl/caliptra_prim_fifo_sync_cnt.sv + - src/caliptra-rtl/caliptra_prim_fifo_sync.sv + - src/caliptra-rtl/caliptra_prim_flop_2sync.sv + - src/caliptra-rtl/caliptra_prim_flop_en.sv + - src/caliptra-rtl/caliptra_prim_flop.sv + - src/caliptra-rtl/caliptra_prim_generic_and2.sv + - src/caliptra-rtl/caliptra_prim_generic_buf.sv + - src/caliptra-rtl/caliptra_prim_generic_clock_inv.sv + - src/caliptra-rtl/caliptra_prim_generic_clock_mux2.sv + - src/caliptra-rtl/caliptra_prim_generic_flop_en.sv + - src/caliptra-rtl/caliptra_prim_generic_flop.sv + - src/caliptra-rtl/caliptra_prim_generic_ram_1p.sv + - src/caliptra-rtl/caliptra_prim_generic_xnor2.sv + - src/caliptra-rtl/caliptra_prim_generic_xor2.sv + - src/caliptra-rtl/caliptra_prim_gf_mult.sv + - src/caliptra-rtl/caliptra_prim_intr_hw.sv + - src/caliptra-rtl/caliptra_prim_lc_sender.sv + - src/caliptra-rtl/caliptra_prim_lc_sync.sv + - src/caliptra-rtl/caliptra_prim_lfsr.sv + - src/caliptra-rtl/caliptra_prim_max_tree.sv + - src/caliptra-rtl/caliptra_prim_mubi4_dec.sv + - src/caliptra-rtl/caliptra_prim_mubi4_sender.sv + - src/caliptra-rtl/caliptra_prim_mubi4_sync.sv + - src/caliptra-rtl/caliptra_prim_mubi8_sender.sv + - src/caliptra-rtl/caliptra_prim_mubi8_sync.sv + - src/caliptra-rtl/caliptra_prim_onehot_check.sv + - src/caliptra-rtl/caliptra_prim_onehot_enc.sv + - src/caliptra-rtl/caliptra_prim_onehot_mux.sv + - src/caliptra-rtl/caliptra_prim_packer_fifo.sv + - src/caliptra-rtl/caliptra_prim_packer.sv + - src/caliptra-rtl/caliptra_prim_present.sv + - src/caliptra-rtl/caliptra_prim_ram_1p_adv.sv + - src/caliptra-rtl/caliptra_prim_reg_we_check.sv + - src/caliptra-rtl/caliptra_prim_sec_anchor_buf.sv + - src/caliptra-rtl/caliptra_prim_sec_anchor_flop.sv + - src/caliptra-rtl/caliptra_prim_secded_22_16_dec.sv + - src/caliptra-rtl/caliptra_prim_secded_22_16_enc.sv + - src/caliptra-rtl/caliptra_prim_secded_28_22_dec.sv + - src/caliptra-rtl/caliptra_prim_secded_28_22_enc.sv + - src/caliptra-rtl/caliptra_prim_secded_39_32_dec.sv + - src/caliptra-rtl/caliptra_prim_secded_39_32_enc.sv + - src/caliptra-rtl/caliptra_prim_secded_64_57_dec.sv + - src/caliptra-rtl/caliptra_prim_secded_64_57_enc.sv + - src/caliptra-rtl/caliptra_prim_secded_72_64_dec.sv + - src/caliptra-rtl/caliptra_prim_secded_72_64_enc.sv + - src/caliptra-rtl/caliptra_prim_secded_hamming_22_16_dec.sv + - src/caliptra-rtl/caliptra_prim_secded_hamming_22_16_enc.sv + - src/caliptra-rtl/caliptra_prim_secded_hamming_39_32_dec.sv + - src/caliptra-rtl/caliptra_prim_secded_hamming_39_32_enc.sv + - src/caliptra-rtl/caliptra_prim_secded_hamming_72_64_dec.sv + - src/caliptra-rtl/caliptra_prim_secded_hamming_72_64_enc.sv + - src/caliptra-rtl/caliptra_prim_secded_hamming_76_68_dec.sv + - src/caliptra-rtl/caliptra_prim_secded_hamming_76_68_enc.sv + - src/caliptra-rtl/caliptra_prim_secded_inv_22_16_dec.sv + - src/caliptra-rtl/caliptra_prim_secded_inv_22_16_enc.sv + - src/caliptra-rtl/caliptra_prim_secded_inv_28_22_dec.sv + - src/caliptra-rtl/caliptra_prim_secded_inv_28_22_enc.sv + - src/caliptra-rtl/caliptra_prim_secded_inv_39_32_dec.sv + - src/caliptra-rtl/caliptra_prim_secded_inv_39_32_enc.sv + - src/caliptra-rtl/caliptra_prim_secded_inv_64_57_dec.sv + - src/caliptra-rtl/caliptra_prim_secded_inv_64_57_enc.sv + - src/caliptra-rtl/caliptra_prim_secded_inv_72_64_dec.sv + - src/caliptra-rtl/caliptra_prim_secded_inv_72_64_enc.sv + - src/caliptra-rtl/caliptra_prim_secded_inv_hamming_22_16_dec.sv + - src/caliptra-rtl/caliptra_prim_secded_inv_hamming_22_16_enc.sv + - src/caliptra-rtl/caliptra_prim_secded_inv_hamming_39_32_dec.sv + - src/caliptra-rtl/caliptra_prim_secded_inv_hamming_39_32_enc.sv + - src/caliptra-rtl/caliptra_prim_secded_inv_hamming_72_64_dec.sv + - src/caliptra-rtl/caliptra_prim_secded_inv_hamming_72_64_enc.sv + - src/caliptra-rtl/caliptra_prim_secded_inv_hamming_76_68_dec.sv + - src/caliptra-rtl/caliptra_prim_secded_inv_hamming_76_68_enc.sv + - src/caliptra-rtl/caliptra_prim_slicer.sv + - src/caliptra-rtl/caliptra_prim_sparse_fsm_flop.sv + - src/caliptra-rtl/caliptra_prim_subreg_arb.sv + - src/caliptra-rtl/caliptra_prim_subreg_ext.sv + - src/caliptra-rtl/caliptra_prim_subreg_shadow.sv + - src/caliptra-rtl/caliptra_prim_subreg.sv + - src/caliptra-rtl/caliptra_prim_sum_tree.sv + - src/caliptra-rtl/caliptra_prim_sync_reqack_data.sv + - src/caliptra-rtl/caliptra_prim_sync_reqack.sv + - src/caliptra-rtl/caliptra_prim_trivium.sv + - src/caliptra-rtl/caliptra_sram.sv + - src/caliptra-rtl/caliptra_tlul_adapter_reg.sv + - src/caliptra-rtl/caliptra_tlul_adapter_sram.sv + - src/caliptra-rtl/caliptra_tlul_adapter_vh.sv + - src/caliptra-rtl/caliptra_tlul_cmd_intg_chk.sv + - src/caliptra-rtl/caliptra_tlul_cmd_intg_gen.sv + - src/caliptra-rtl/caliptra_tlul_data_integ_dec.sv + - src/caliptra-rtl/caliptra_tlul_data_integ_enc.sv + - src/caliptra-rtl/caliptra_tlul_err_resp.sv + - src/caliptra-rtl/caliptra_tlul_err.sv + - src/caliptra-rtl/caliptra_tlul_fifo_sync.sv + - src/caliptra-rtl/caliptra_tlul_rsp_intg_chk.sv + - src/caliptra-rtl/caliptra_tlul_rsp_intg_gen.sv + - src/caliptra-rtl/caliptra_tlul_socket_1n.sv + - src/caliptra-rtl/caliptra_tlul_sram_byte.sv + - src/caliptra-rtl/caliptra_top_cov_bind.sv + - src/caliptra-rtl/caliptra_top_cov_if.sv + - src/caliptra-rtl/caliptra_top_cov_props.sv + - src/caliptra-rtl/caliptra_top.sv + - src/caliptra-rtl/caliptra_top_sva.sv + - src/caliptra-rtl/caliptra_top_tb_axi_complex.sv + - src/caliptra-rtl/caliptra_top_tb_axi_fifo.sv + - src/caliptra-rtl/caliptra_top_tb_services.sv + - src/caliptra-rtl/caliptra_top_tb_soc_bfm.sv + - src/caliptra-rtl/caliptra_top_tb.sv + - src/caliptra-rtl/caliptra_veer_sram_export.sv + - src/caliptra-rtl/clk_gate.sv + - src/caliptra-rtl/clp_abr_top_cov_bind.sv + - src/caliptra-rtl/clp_abr_top_cov_if.sv + - src/caliptra-rtl/csrng_block_encrypt.sv + - src/caliptra-rtl/csrng_cmd_stage.sv + - src/caliptra-rtl/csrng_core.sv + - src/caliptra-rtl/csrng_ctr_drbg_cmd.sv + - src/caliptra-rtl/csrng_ctr_drbg_gen.sv + - src/caliptra-rtl/csrng_ctr_drbg_upd.sv + - src/caliptra-rtl/csrng_main_sm.sv + - src/caliptra-rtl/csrng_reg_top.sv + - src/caliptra-rtl/csrng_state_db.sv + - src/caliptra-rtl/csrng.sv + - src/caliptra-rtl/dma_testcase_generator.sv + - src/caliptra-rtl/dmi_jtag_to_core_sync.v + - src/caliptra-rtl/dmi_mux.v + - src/caliptra-rtl/dmi_wrapper.v + - src/caliptra-rtl/doe_cbc.sv + - src/caliptra-rtl/doe_core_cbc.sv + - src/caliptra-rtl/doe_cov_bind.sv + - src/caliptra-rtl/doe_cov_if.sv + - src/caliptra-rtl/doe_ctrl.sv + - src/caliptra-rtl/doe_decipher_block.sv + - src/caliptra-rtl/doe_encipher_block.sv + - src/caliptra-rtl/doe_fsm.sv + - src/caliptra-rtl/doe_inv_sbox.sv + - src/caliptra-rtl/doe_key_mem.sv + - src/caliptra-rtl/doe_reg.sv + - src/caliptra-rtl/doe_sbox.sv + - src/caliptra-rtl/dv_reg.sv + - src/caliptra-rtl/dv.sv + - src/caliptra-rtl/ecc_adder.sv + - src/caliptra-rtl/ecc_add_sub_mod_alter.sv + - src/caliptra-rtl/ecc_arith_unit.sv + - src/caliptra-rtl/ecc_dsa_ctrl.sv + - src/caliptra-rtl/ecc_dsa_sequencer.sv + - src/caliptra-rtl/ecc_fau.sv + - src/caliptra-rtl/ecc_hmac_drbg_interface.sv + - src/caliptra-rtl/ecc_montgomerymultiplier.sv + - src/caliptra-rtl/ecc_mult_dsp.sv + - src/caliptra-rtl/ecc_pe_final.sv + - src/caliptra-rtl/ecc_pe_first.sv + - src/caliptra-rtl/ecc_pe.sv + - src/caliptra-rtl/ecc_pm_ctrl.sv + - src/caliptra-rtl/ecc_pm_sequencer.sv + - src/caliptra-rtl/ecc_ram_tdp_file.sv + - src/caliptra-rtl/ecc_reg.sv + - src/caliptra-rtl/ecc_scalar_blinding.sv + - src/caliptra-rtl/ecc_top_cov_bind.sv + - src/caliptra-rtl/ecc_top_cov_if.sv + - src/caliptra-rtl/ecc_top.sv + - src/caliptra-rtl/el2_dbg.sv + - src/caliptra-rtl/el2_dec_decode_ctl.sv + - src/caliptra-rtl/el2_dec_gpr_ctl.sv + - src/caliptra-rtl/el2_dec_ib_ctl.sv + - src/caliptra-rtl/el2_dec_pmp_ctl.sv + - src/caliptra-rtl/el2_dec.sv + - src/caliptra-rtl/el2_dec_tlu_ctl.sv + - src/caliptra-rtl/el2_dec_trigger.sv + - src/caliptra-rtl/el2_dma_ctrl.sv + - src/caliptra-rtl/el2_exu_alu_ctl.sv + - src/caliptra-rtl/el2_exu_div_ctl.sv + - src/caliptra-rtl/el2_exu_mul_ctl.sv + - src/caliptra-rtl/el2_exu.sv + - src/caliptra-rtl/el2_ifu_aln_ctl.sv + - src/caliptra-rtl/el2_ifu_bp_ctl.sv + - src/caliptra-rtl/el2_ifu_compress_ctl.sv + - src/caliptra-rtl/el2_ifu_iccm_mem.sv + - src/caliptra-rtl/el2_ifu_ic_mem.sv + - src/caliptra-rtl/el2_ifu_ifc_ctl.sv + - src/caliptra-rtl/el2_ifu_mem_ctl.sv + - src/caliptra-rtl/el2_ifu.sv + - src/caliptra-rtl/el2_lib.sv + - src/caliptra-rtl/el2_lsu_addrcheck.sv + - src/caliptra-rtl/el2_lsu_bus_buffer.sv + - src/caliptra-rtl/el2_lsu_bus_intf.sv + - src/caliptra-rtl/el2_lsu_clkdomain.sv + - src/caliptra-rtl/el2_lsu_dccm_ctl.sv + - src/caliptra-rtl/el2_lsu_dccm_mem.sv + - src/caliptra-rtl/el2_lsu_ecc.sv + - src/caliptra-rtl/el2_lsu_lsc_ctl.sv + - src/caliptra-rtl/el2_lsu_stbuf.sv + - src/caliptra-rtl/el2_lsu.sv + - src/caliptra-rtl/el2_lsu_trigger.sv + - src/caliptra-rtl/el2_mem_if.sv + - src/caliptra-rtl/el2_mem.sv + - src/caliptra-rtl/el2_pic_ctrl.sv + - src/caliptra-rtl/el2_pmp.sv + - src/caliptra-rtl/el2_veer.sv + - src/caliptra-rtl/el2_veer_wrapper.sv + - src/caliptra-rtl/entropy_src_ack_sm.sv + - src/caliptra-rtl/entropy_src_adaptp_ht.sv + - src/caliptra-rtl/entropy_src_bucket_ht.sv + - src/caliptra-rtl/entropy_src_cntr_reg.sv + - src/caliptra-rtl/entropy_src_core.sv + - src/caliptra-rtl/entropy_src_enable_delay.sv + - src/caliptra-rtl/entropy_src_main_sm.sv + - src/caliptra-rtl/entropy_src_markov_ht.sv + - src/caliptra-rtl/entropy_src_reg_top.sv + - src/caliptra-rtl/entropy_src_repcnt_ht.sv + - src/caliptra-rtl/entropy_src_repcnts_ht.sv + - src/caliptra-rtl/entropy_src.sv + - src/caliptra-rtl/entropy_src_watermark_reg.sv + - src/caliptra-rtl/hmac_core.sv + - src/caliptra-rtl/hmac_ctrl_cov_bind.sv + - src/caliptra-rtl/hmac_ctrl_cov_if.sv + - src/caliptra-rtl/hmac_ctrl.sv + - src/caliptra-rtl/hmac_drbg_cov_bind.sv + - src/caliptra-rtl/hmac_drbg_cov_if.sv + - src/caliptra-rtl/hmac_drbg.sv + - src/caliptra-rtl/hmac_reg.sv + - src/caliptra-rtl/hmac.sv + - src/caliptra-rtl/keccak_2share.sv + - src/caliptra-rtl/keccak_round.sv + - src/caliptra-rtl/keyvault_cov_if.sv + - src/caliptra-rtl/keyvault_cov_props.sv + - src/caliptra-rtl/kmac_app.sv + - src/caliptra-rtl/kmac_core.sv + - src/caliptra-rtl/kmac_entropy.sv + - src/caliptra-rtl/kmac_errchk.sv + - src/caliptra-rtl/kmac_msgfifo.sv + - src/caliptra-rtl/kmac_reg_top.sv + - src/caliptra-rtl/kmac_staterd.sv + - src/caliptra-rtl/kmac.sv + - src/caliptra-rtl/kv_fsm.sv + - src/caliptra-rtl/kv_read_client.sv + - src/caliptra-rtl/kv_read_rule_check.sv + - src/caliptra-rtl/kv_reg.sv + - src/caliptra-rtl/kv.sv + - src/caliptra-rtl/kv_write_client.sv + - src/caliptra-rtl/kv_write_rule_check.sv + - src/caliptra-rtl/mbox_csr.sv + - src/caliptra-rtl/mbox.sv + - src/caliptra-rtl/mem_lib.sv + - src/caliptra-rtl/ot_keccak_2share.sv + - src/caliptra-rtl/ot_keccak_round.sv + - src/caliptra-rtl/ot_sha3pad.sv + - src/caliptra-rtl/ot_sha3.sv + - src/caliptra-rtl/pcrvault_cov_bind.sv + - src/caliptra-rtl/pcrvault_cov_if.sv + - src/caliptra-rtl/pcrvault_cov_props.sv + - src/caliptra-rtl/physical_rng.sv + - src/caliptra-rtl/pv_gen_hash.sv + - src/caliptra-rtl/pv_reg.sv + - src/caliptra-rtl/pv.sv + - src/caliptra-rtl/rvjtag_tap.v + - src/caliptra-rtl/sha256_core.v + - src/caliptra-rtl/sha256_ctrl_cov_bind.sv + - src/caliptra-rtl/sha256_ctrl_cov_if.sv + - src/caliptra-rtl/sha256_ctrl.sv + - src/caliptra-rtl/sha256_k_constants.v + - src/caliptra-rtl/sha256_reg.sv + - src/caliptra-rtl/sha256.sv + - src/caliptra-rtl/sha256_w_mem.v + - src/caliptra-rtl/sha3_ctrl.sv + - src/caliptra-rtl/sha3pad.sv + - src/caliptra-rtl/sha3_reg.sv + - src/caliptra-rtl/sha3.sv + - src/caliptra-rtl/sha512_acc_csr.sv + - src/caliptra-rtl/sha512_acc_top.sv + - src/caliptra-rtl/sha512_core.v + - src/caliptra-rtl/sha512_ctrl_cov_bind.sv + - src/caliptra-rtl/sha512_ctrl_cov_if.sv + - src/caliptra-rtl/sha512_ctrl.sv + - src/caliptra-rtl/sha512_h_constants.v + - src/caliptra-rtl/sha512_k_constants.v + - src/caliptra-rtl/sha512_masked_core.sv + - src/caliptra-rtl/sha512_masked_w_mem.sv + - src/caliptra-rtl/sha512_reg.sv + - src/caliptra-rtl/sha512.sv + - src/caliptra-rtl/sha512_w_mem.v + - src/caliptra-rtl/skidbuffer.v + - src/caliptra-rtl/soc_ifc_arb.sv + - src/caliptra-rtl/soc_ifc_boot_fsm.sv + - src/caliptra-rtl/soc_ifc_cov_bind.sv + - src/caliptra-rtl/soc_ifc_cov_if.sv + - src/caliptra-rtl/soc_ifc_reg.sv + - src/caliptra-rtl/soc_ifc_top.sv + - src/caliptra-rtl/wdt.sv + # adams-bridge + - src/adams-bridge/abr_ahb_defines_pkg.sv + - src/adams-bridge/abr_sampler_pkg.sv + - src/adams-bridge/abr_ctrl_pkg.sv + - src/adams-bridge/abr_params_pkg.sv + - src/adams-bridge/abr_prim_alert_pkg.sv + - src/adams-bridge/abr_prim_cipher_pkg.sv + - src/adams-bridge/abr_prim_mubi_pkg.sv + - src/adams-bridge/abr_prim_pkg.sv + - src/adams-bridge/abr_prim_sparse_fsm_pkg.sv + - src/adams-bridge/abr_prim_subreg_pkg.sv + - src/adams-bridge/abr_prim_util_pkg.sv + - src/adams-bridge/abr_reg_pkg.sv + - src/adams-bridge/abr_sha3_pkg.sv + - src/adams-bridge/compress_defines_pkg.sv + - src/adams-bridge/decompose_defines_pkg.sv + - src/adams-bridge/decompress_defines_pkg.sv + - src/adams-bridge/makehint_defines_pkg.sv + - src/adams-bridge/norm_check_defines_pkg.sv + - src/adams-bridge/ntt_defines_pkg.sv + - src/adams-bridge/power2round_defines_pkg.sv + - src/adams-bridge/sample_in_ball_pkg.sv + - src/adams-bridge/sigdecode_h_defines_pkg.sv + - src/adams-bridge/sigdecode_z_defines_pkg.sv + - src/adams-bridge/sigencode_z_defines_pkg.sv + - src/adams-bridge/skdecode_defines_pkg.sv + - src/adams-bridge/abr_1r1w_512x4_ram.sv + - src/adams-bridge/abr_1r1w_be_ram.sv + - src/adams-bridge/abr_1r1w_ram.sv + - src/adams-bridge/abr_2ff_sync.sv + - src/adams-bridge/abr_adder.sv + - src/adams-bridge/abr_add_sub_mod.sv + - src/adams-bridge/abr_ahb_slv_sif.sv + - src/adams-bridge/abr_ctrl.sv + - src/adams-bridge/abr_delay_masked_shares.sv + - src/adams-bridge/abr_icg.sv + - src/adams-bridge/abr_keccak_2share.sv + - src/adams-bridge/abr_keccak_round.sv + - src/adams-bridge/abr_masked_A2B_conv.sv + - src/adams-bridge/abr_masked_add_sub_mod_Boolean.sv + - src/adams-bridge/abr_masked_AND.sv + - src/adams-bridge/abr_masked_B2A_conv.sv + - src/adams-bridge/abr_masked_full_adder.sv + - src/adams-bridge/abr_masked_MUX.sv + - src/adams-bridge/abr_masked_N_bit_Arith_adder.sv + - src/adams-bridge/abr_masked_N_bit_Boolean_adder.sv + - src/adams-bridge/abr_masked_N_bit_Boolean_sub.sv + - src/adams-bridge/abr_masked_N_bit_mult.sv + - src/adams-bridge/abr_masked_N_bit_mult_two_share.sv + - src/adams-bridge/abr_masked_OR.sv + - src/adams-bridge/abr_mem_if.sv + - src/adams-bridge/abr_mem_top.sv + - src/adams-bridge/abr_msg_buffer.sv + - src/adams-bridge/abr_ntt_add_sub_mod.sv + - src/adams-bridge/abr_piso_multi.sv + - src/adams-bridge/abr_piso.sv + - src/adams-bridge/abr_prim_alert_receiver.sv + - src/adams-bridge/abr_prim_alert_sender.sv + - src/adams-bridge/abr_prim_arbiter_ppc.sv + - src/adams-bridge/abr_prim_buf.sv + - src/adams-bridge/abr_prim_cdc_rand_delay.sv + - src/adams-bridge/abr_prim_count.sv + - src/adams-bridge/abr_prim_diff_decode.sv + - src/adams-bridge/abr_prim_dom_and_2share.sv + - src/adams-bridge/abr_prim_edge_detector.sv + - src/adams-bridge/abr_prim_fifo_sync_cnt.sv + - src/adams-bridge/abr_prim_fifo_sync.sv + - src/adams-bridge/abr_prim_flop_2sync.sv + - src/adams-bridge/abr_prim_flop_en.sv + - src/adams-bridge/abr_prim_flop.sv + - src/adams-bridge/abr_prim_generic_buf.sv + - src/adams-bridge/abr_prim_generic_flop_en.sv + - src/adams-bridge/abr_prim_generic_flop.sv + - src/adams-bridge/abr_prim_intr_hw.sv + - src/adams-bridge/abr_prim_lfsr.sv + - src/adams-bridge/abr_prim_max_tree.sv + - src/adams-bridge/abr_prim_mubi4_sync.sv + - src/adams-bridge/abr_prim_mubi8_sync.sv + - src/adams-bridge/abr_prim_onehot_check.sv + - src/adams-bridge/abr_prim_packer_fifo.sv + - src/adams-bridge/abr_prim_reg_we_check.sv + - src/adams-bridge/abr_prim_sec_anchor_buf.sv + - src/adams-bridge/abr_prim_sec_anchor_flop.sv + - src/adams-bridge/abr_prim_slicer.sv + - src/adams-bridge/abr_prim_sparse_fsm_flop.sv + - src/adams-bridge/abr_prim_subreg_arb.sv + - src/adams-bridge/abr_prim_subreg_ext.sv + - src/adams-bridge/abr_prim_subreg.sv + - src/adams-bridge/abr_prim_sum_tree.sv + - src/adams-bridge/abr_ram_regout.sv + - src/adams-bridge/abr_reg.sv + - src/adams-bridge/abr_sample_buffer.sv + - src/adams-bridge/abr_sampler_top.sv + - src/adams-bridge/abr_seq.sv + - src/adams-bridge/abr_sha3pad.sv + - src/adams-bridge/abr_sha3.sv + - src/adams-bridge/abr_top_cov_bind.sv + - src/adams-bridge/abr_top_cov_if.sv + - src/adams-bridge/abr_top.sv + - src/adams-bridge/barrett_reduction.sv + - src/adams-bridge/cbd_sampler_ctrl.sv + - src/adams-bridge/cbd_sampler.sv + - src/adams-bridge/compress_ctrl.sv + - src/adams-bridge/compress.sv + - src/adams-bridge/compress_top.sv + - src/adams-bridge/decompose_ctrl.sv + - src/adams-bridge/decompose_mod_2gamma2.sv + - src/adams-bridge/decompose_r1_lut.sv + - src/adams-bridge/decompose.sv + - src/adams-bridge/decompose_usehint.sv + - src/adams-bridge/decompose_w1_encode.sv + - src/adams-bridge/decompose_w1_mem.sv + - src/adams-bridge/decompress_ctrl.sv + - src/adams-bridge/decompress.sv + - src/adams-bridge/decompress_top.sv + - src/adams-bridge/exp_mask_ctrl.sv + - src/adams-bridge/exp_mask.sv + - src/adams-bridge/hintgen.sv + - src/adams-bridge/makehint.sv + - src/adams-bridge/masked_barrett_if_cond.sv + - src/adams-bridge/masked_barrett_if_cond_v2.sv + - src/adams-bridge/masked_barrett_reduction.sv + - src/adams-bridge/norm_check_ctrl.sv + - src/adams-bridge/norm_check.sv + - src/adams-bridge/norm_check_top.sv + - src/adams-bridge/ntt_buffer.sv + - src/adams-bridge/ntt_butterfly2x2.sv + - src/adams-bridge/ntt_butterfly.sv + - src/adams-bridge/ntt_ctrl.sv + - src/adams-bridge/ntt_div2.sv + - src/adams-bridge/ntt_hybrid_butterfly_2x2.sv + - src/adams-bridge/ntt_karatsuba_pairwm.sv + - src/adams-bridge/ntt_masked_BFU_add_sub.sv + - src/adams-bridge/ntt_masked_BFU_mult.sv + - src/adams-bridge/ntt_masked_butterfly1x2.sv + - src/adams-bridge/ntt_masked_gs_butterfly.sv + - src/adams-bridge/ntt_masked_mult_redux46.sv + - src/adams-bridge/ntt_masked_pairwm.sv + - src/adams-bridge/ntt_masked_pwm.sv + - src/adams-bridge/ntt_masked_special_adder.sv + - src/adams-bridge/ntt_mlkem_masked_BFU_add_sub.sv + - src/adams-bridge/ntt_mlkem_masked_BFU_mult.sv + - src/adams-bridge/ntt_mlkem_masked_butterfly1x2.sv + - src/adams-bridge/ntt_mlkem_masked_gs_butterfly.sv + - src/adams-bridge/ntt_mult_dsp.sv + - src/adams-bridge/ntt_mult_reduction.sv + - src/adams-bridge/ntt_shuffle_buffer.sv + - src/adams-bridge/ntt_special_adder.sv + - src/adams-bridge/ntt_top.sv + - src/adams-bridge/ntt_twiddle_lookup.sv + - src/adams-bridge/pkdecode.sv + - src/adams-bridge/power2round_core.sv + - src/adams-bridge/power2round_ctrl.sv + - src/adams-bridge/power2round_skencode.sv + - src/adams-bridge/power2round_top.sv + - src/adams-bridge/rej_bounded2.sv + - src/adams-bridge/rej_bounded_ctrl.sv + - src/adams-bridge/rej_sampler_ctrl.sv + - src/adams-bridge/rej_sampler.sv + - src/adams-bridge/sample_in_ball_ctrl.sv + - src/adams-bridge/sample_in_ball_shuffler.sv + - src/adams-bridge/sample_in_ball.sv + - src/adams-bridge/sib_mem.sv + - src/adams-bridge/sigdecode_h_ctrl.sv + - src/adams-bridge/sigdecode_h.sv + - src/adams-bridge/sigdecode_z_top.sv + - src/adams-bridge/sigdecode_z_unit.sv + - src/adams-bridge/sigencode_z_top.sv + - src/adams-bridge/sigencode_z_unit.sv + - src/adams-bridge/skdecode_ctrl.sv + - src/adams-bridge/skdecode_s1s2_unpack.sv + - src/adams-bridge/skdecode_t0_unpack.sv + - src/adams-bridge/skdecode_top.sv + - src/adams-bridge/skencode.sv + verilogIncludeFiles: + # caliptra-rtl + - src/caliptra-rtl/caliptra_prim_assert.sv + - src/caliptra-rtl/caliptra_prim_assert_dummy_macros.svh + - src/caliptra-rtl/caliptra_prim_assert_sec_cm.svh + - src/caliptra-rtl/caliptra_prim_flop_macros.sv + - src/caliptra-rtl/caliptra_prim_module_name_macros.svh + - src/caliptra-rtl/caliptra_prim_util_memload.svh + - src/caliptra-rtl/caliptra_reg_defines.svh + - src/caliptra-rtl/caliptra_reg_field_defines.svh + - src/caliptra-rtl/caliptra_sva.svh + - src/caliptra-rtl/kv_macros.svh + - src/caliptra-rtl/pv_macros.svh + - src/caliptra-rtl/el2_param.vh + - src/caliptra-rtl/config_defines.svh + - src/caliptra-rtl/caliptra_macros.svh + - src/caliptra-rtl/common_defines.sv + - src/caliptra-rtl/dma_transfer_randomizer.sv + - src/caliptra-rtl/dasm.svi + - src/caliptra-rtl/el2_dec_csr_equ_m.svh + - src/caliptra-rtl/el2_pdef.vh + - src/caliptra-rtl/pic_map_auto.h + # adams-bridge + - src/adams-bridge/abr_config_defines.svh + - src/adams-bridge/abr_macros.svh + - src/adams-bridge/abr_sva.svh + - src/adams-bridge/abr_prim_assert.sv + - src/adams-bridge/abr_prim_assert_dummy_macros.svh + - src/adams-bridge/abr_prim_assert_sec_cm.svh + - src/adams-bridge/abr_prim_flop_macros.sv + verilogDefines: + RV_OPENSOURCE: 1 + CALIPTRA_INTERNAL_TRNG: 1 + topModule: caliptra_top_tb + mainClock: caliptra_top_tb.core_clk + verilatorArgs: [ + --autoflush, + --timescale, 1ns/100ps + ] + +execute: + common: + postHook: tests/post.bash + tests: + hello: + tags: [ sanity ] + files: + - tests/hello/dccm.hex + - tests/hello/iccm.hex + - tests/hello/mailbox.hex + - tests/hello/program.hex + hmac: + args: [ +iterations=1 ] + tags: [ standard ] + files: + - tests/hmac/dccm.hex + - tests/hmac/iccm.hex + - tests/hmac/mailbox.hex + - tests/hmac/program.hex + mlkem: + args: [ +iterations=1 ] + files: + - tests/mlkem/dccm.hex + - tests/mlkem/iccm.hex + - tests/mlkem/mailbox.hex + - tests/mlkem/program.hex + sha3: + args: [ +iterations=1 ] + files: + - tests/sha3/dccm.hex + - tests/sha3/iccm.hex + - tests/sha3/mailbox.hex + - tests/sha3/program.hex + trng: + args: [ +iterations=1 ] + files: + - tests/trng/dccm.hex + - tests/trng/iccm.hex + - tests/trng/mailbox.hex + - tests/trng/program.hex diff --git a/designs/Caliptra/src/adams-bridge/abr_1r1w_512x4_ram.sv b/designs/Caliptra/src/adams-bridge/abr_1r1w_512x4_ram.sv new file mode 100644 index 0000000..4068d0f --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/abr_1r1w_512x4_ram.sv @@ -0,0 +1,51 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. + +module abr_1r1w_512x4_ram #( + parameter DEPTH = 512 + ,parameter DATA_WIDTH = 4 + ,parameter ADDR_WIDTH = $clog2(DEPTH) + + ) + ( + input logic clk_i, + + input logic we_i, + input logic [ADDR_WIDTH-1:0] waddr_i, + input logic [DATA_WIDTH-1:0] wdata_i, + input logic re_i, + input logic [ADDR_WIDTH-1:0] raddr_i, + output logic [DATA_WIDTH-1:0] rdata_o + ); + + //storage element +`ifndef RV_FPGA_OPTIMIZE + logic [DEPTH-1:0][DATA_WIDTH-1:0] ram; +`else + (* ram_style = "block" *) logic [DATA_WIDTH-1:0] ram [DEPTH-1:0]; +`endif + + always @(posedge clk_i) begin + if (we_i) begin + ram[waddr_i] <= wdata_i; + end + end + + always @(posedge clk_i) begin + if (re_i) begin + rdata_o <= ram[raddr_i]; + end + end + +endmodule diff --git a/designs/Caliptra/src/adams-bridge/abr_1r1w_be_ram.sv b/designs/Caliptra/src/adams-bridge/abr_1r1w_be_ram.sv new file mode 100644 index 0000000..2ccde62 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/abr_1r1w_be_ram.sv @@ -0,0 +1,150 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. + +module abr_1r1w_be_ram #( + parameter DEPTH = 64 + ,parameter DATA_WIDTH = 32 + ,parameter STROBE_WIDTH = 8 + ,localparam ADDR_WIDTH = $clog2(DEPTH) + ) + ( + input logic clk_i, + + input logic we_i, + input logic [(DATA_WIDTH/STROBE_WIDTH)-1:0] wstrobe_i, + input logic [ADDR_WIDTH-1:0] waddr_i, + input logic [(DATA_WIDTH/STROBE_WIDTH)-1:0][STROBE_WIDTH-1:0] wdata_i, + input logic re_i, + input logic [ADDR_WIDTH-1:0] raddr_i, + output logic [DATA_WIDTH-1:0] rdata_o + ); + +`ifdef RV_FPGA_OPTIMIZE + + + logic [DATA_WIDTH-1:0] flattened_wdata; + + // Create a flattened version of the wdata_i using always_comb + always_comb begin + flattened_wdata = '0; // Initialize to zero + for (int i = 0; i < (DATA_WIDTH/STROBE_WIDTH); i++) begin + flattened_wdata[i*STROBE_WIDTH +: STROBE_WIDTH] = wdata_i[i]; + end + end + + // Instantiation of the dual-port byte-write RAM + bytewrite_tdp_ram_rf #( + .NUM_COL(DATA_WIDTH / STROBE_WIDTH), // Number of columns (bytes) + .COL_WIDTH(STROBE_WIDTH), // Width of each column (byte width) + .ADDR_WIDTH(ADDR_WIDTH), // Address width + .DATA_WIDTH(DATA_WIDTH), // Data width (total) + .DEPTH(DEPTH) + ) bytewrite_ram_inst ( + .clkA(clk_i), // Clock for Port A (write) + .enaA(we_i), // Enable for Port A (write enable) + .weA(wstrobe_i), // Byte-wise write enable for Port A + .addrA(waddr_i), // Address for Port A (write) + .dinA(flattened_wdata), // Data input for Port A (flattened) + .doutA(), // Data output for Port A (unused in write-only) + + .clkB(clk_i), // Clock for Port B (read) + .enaB(re_i), // Enable for Port B (read enable) + .weB({(DATA_WIDTH/STROBE_WIDTH){1'b0}}), // No write enable for Port B + .addrB(raddr_i), // Address for Port B (read) + .dinB({DATA_WIDTH{1'b0}}), // No data input for Port B + .doutB(rdata_o) // Data output for Port B (read data) + ); + +`else + + //storage element + logic [(DATA_WIDTH/STROBE_WIDTH)-1:0][STROBE_WIDTH-1:0] ram [DEPTH-1:0]; + + always @(posedge clk_i) begin + if (we_i) begin + for (int i = 0; i < (DATA_WIDTH/STROBE_WIDTH); i++) begin + if (wstrobe_i[i]) + ram[waddr_i][i] <= wdata_i[i]; + end + end + end + + always @(posedge clk_i) begin + if (re_i) begin + rdata_o <= ram[raddr_i]; + end + end + + +`endif + + +endmodule + +`ifdef RV_FPGA_OPTIMIZE + +module bytewrite_tdp_ram_rf #( + parameter NUM_COL = 4, // Number of columns (bytes) + parameter COL_WIDTH = 8, // Width of each column (byte) + parameter ADDR_WIDTH = 10, // Address width + parameter DATA_WIDTH = NUM_COL * COL_WIDTH, // Data width (total) + parameter DEPTH = 64 +) ( + input wire clkA, // Clock for Port A + input wire enaA, // Enable for Port A + input wire [NUM_COL-1:0] weA, // Write enable for Port A (byte-wise) + input wire [ADDR_WIDTH-1:0] addrA, // Address for Port A + input wire [DATA_WIDTH-1:0] dinA, // Data input for Port A + output reg [DATA_WIDTH-1:0] doutA, // Data output for Port A + + input wire clkB, // Clock for Port B + input wire enaB, // Enable for Port B + input wire [NUM_COL-1:0] weB, // Write enable for Port B (byte-wise) + input wire [ADDR_WIDTH-1:0] addrB, // Address for Port B + input wire [DATA_WIDTH-1:0] dinB, // Data input for Port B + output reg [DATA_WIDTH-1:0] doutB // Data output for Port B +); + + // Core memory storage (True Dual Port) + (* ram_style = "block" *) reg [DATA_WIDTH-1:0] ram_block [DEPTH-1:0]; // Memory array + + integer i; + + // Port A Operations + always @(posedge clkA) begin + if (enaA) begin + for (i = 0; i < NUM_COL; i = i + 1) begin + if (weA[i]) begin + ram_block[addrA][i*COL_WIDTH +: COL_WIDTH] <= dinA[i*COL_WIDTH +: COL_WIDTH]; // Write byte + end + end + doutA <= ram_block[addrA]; // Read operation (read-first) + end + end + + // Port B Operations + always @(posedge clkB) begin + if (enaB) begin + for (i = 0; i < NUM_COL; i = i + 1) begin + if (weB[i]) begin + ram_block[addrB][i*COL_WIDTH +: COL_WIDTH] <= dinB[i*COL_WIDTH +: COL_WIDTH]; // Write byte + end + end + doutB <= ram_block[addrB]; // Read operation (read-first) + end + end + +endmodule + +`endif diff --git a/designs/Caliptra/src/adams-bridge/abr_1r1w_ram.sv b/designs/Caliptra/src/adams-bridge/abr_1r1w_ram.sv new file mode 100644 index 0000000..ddf4d26 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/abr_1r1w_ram.sv @@ -0,0 +1,84 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. + +`ifndef RV_FPGA_OPTIMIZE +module abr_1r1w_ram #( + parameter DEPTH = 64 + ,parameter DATA_WIDTH = 32 + ,parameter ADDR_WIDTH = $clog2(DEPTH) + + ) + ( + input logic clk_i, + + input logic we_i, + input logic [ADDR_WIDTH-1:0] waddr_i, + input logic [DATA_WIDTH-1:0] wdata_i, + input logic re_i, + input logic [ADDR_WIDTH-1:0] raddr_i, + output logic [DATA_WIDTH-1:0] rdata_o + ); + + //storage element + logic [DEPTH-1:0][DATA_WIDTH-1:0] ram; + + always @(posedge clk_i) begin + if (we_i) begin + ram[waddr_i] <= wdata_i; + end + end + + always @(posedge clk_i) begin + if (re_i) begin + rdata_o <= ram[raddr_i]; + end + end + +endmodule + +`else +module abr_1r1w_ram #( + parameter DEPTH = 64 + ,parameter DATA_WIDTH = 32 + ,parameter ADDR_WIDTH = $clog2(DEPTH) + + ) + ( + input logic clk_i, + + input logic we_i, + input logic [ADDR_WIDTH-1:0] waddr_i, + input logic [DATA_WIDTH-1:0] wdata_i, + input logic re_i, + input logic [ADDR_WIDTH-1:0] raddr_i, + output logic [DATA_WIDTH-1:0] rdata_o + ); + + (* ram_style = "block" *) reg [DATA_WIDTH-1:0] ram [DEPTH-1:0]; + + always @(posedge clk_i) begin + if (we_i) begin + if (we_i) + ram[waddr_i] <= wdata_i; + end + end + + always @(posedge clk_i) begin + if (re_i) + rdata_o <= ram[raddr_i]; + end + +endmodule + +`endif diff --git a/designs/Caliptra/src/adams-bridge/abr_2ff_sync.sv b/designs/Caliptra/src/adams-bridge/abr_2ff_sync.sv new file mode 100644 index 0000000..0a375ec --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/abr_2ff_sync.sv @@ -0,0 +1,39 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. + +module abr_2ff_sync #( parameter WIDTH=1, + parameter RST_VAL=0) + ( + input logic clk, + input logic rst_b, + input logic [WIDTH-1:0] din, + output logic [WIDTH-1:0] dout + +); + +logic din_ff; + +always_ff@(posedge clk or negedge rst_b) begin + if(!rst_b) begin + dout <= RST_VAL; + din_ff <= RST_VAL; + end + else begin + din_ff <= din; + dout <= din_ff; + end +end + + +endmodule \ No newline at end of file diff --git a/designs/Caliptra/src/adams-bridge/abr_add_sub_mod.sv b/designs/Caliptra/src/adams-bridge/abr_add_sub_mod.sv new file mode 100644 index 0000000..2964de5 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/abr_add_sub_mod.sv @@ -0,0 +1,122 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +// +//====================================================================== +// +// abr_add_sub_mod.sv +// -------- +// modular addtion/subtraction module to compute opa+-opb % prime +// +// +//====================================================================== + +module abr_add_sub_mod #( + parameter REG_SIZE = 384 + ) + ( + // Clock and reset. + input wire clk, + input wire reset_n, + input wire zeroize, + + // DATA PORT + input wire add_en_i, + input wire sub_i, + input wire [REG_SIZE-1:0] opa_i, + input wire [REG_SIZE-1:0] opb_i, + input wire [REG_SIZE-1:0] prime_i, + output logic [REG_SIZE-1:0] res_o, + output logic ready_o +); + + logic [REG_SIZE-1 : 0] opb0; + logic [REG_SIZE-1 : 0] opb1; + logic [REG_SIZE-1 : 0] r0; + logic [REG_SIZE-1 : 0] r1; + logic carry0; + + logic sub_n; + logic [REG_SIZE-1 : 0] r0_reg; + logic carry0_reg; + + logic carry1; + logic [1 : 0] push_result_reg; + + abr_adder #( + .RADIX(REG_SIZE) + ) + adder_inst_0( + .a_i(opa_i), + .b_i(opb0), + .cin_i(sub_i), + .s_o(r0), + .cout_o(carry0) + ); + + abr_adder #( + .RADIX(REG_SIZE) + ) + adder_inst_1( + .a_i(r0_reg), + .b_i(opb1), + .cin_i(sub_n), + .s_o(r1), + .cout_o(carry1) + ); + + + assign opb0 = sub_i ? ~opb_i : opb_i; + + always_ff @(posedge clk or negedge reset_n) + begin + if(!reset_n) begin + r0_reg <= '0; + carry0_reg <= '0; + sub_n <= '0; + opb1 <= '0; + end + else if (zeroize) begin + r0_reg <= '0; + carry0_reg <= '0; + sub_n <= '0; + opb1 <= '0; + end + else if (add_en_i) begin + r0_reg <= r0; + carry0_reg <= carry0; + sub_n <= !sub_i; + if (sub_i) + opb1 <= prime_i; + else + opb1 <= ~prime_i; + end + end + + // Determines when results are ready + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) + push_result_reg <= 2'b0; + else if (zeroize) + push_result_reg <= 2'b0; + else if (add_en_i) + push_result_reg <= 2'b10; + else // one shift to right + push_result_reg <= 2'(push_result_reg >> 1); + end + + assign ready_o = push_result_reg[0]; + + assign res_o = sub_n ? (carry0_reg ^ carry1)? r1 : r0_reg : (carry0_reg) ? r0_reg : r1; + +endmodule \ No newline at end of file diff --git a/designs/Caliptra/src/adams-bridge/abr_adder.sv b/designs/Caliptra/src/adams-bridge/abr_adder.sv new file mode 100644 index 0000000..2ed0af8 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/abr_adder.sv @@ -0,0 +1,46 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +// +//====================================================================== +// +// abr_adder.sv +// -------- +// Full adder module to compute a + b in RADIX bits and output add result +// with carry +// +// +//====================================================================== + +module abr_adder #( + parameter RADIX = 8 +) +( + // DATA PORT + input wire [RADIX-1:0] a_i, + input wire [RADIX-1:0] b_i, + input wire cin_i, + output wire [RADIX-1:0] s_o, + output wire cout_o +); + + logic [RADIX : 0] s_full; + + always_comb begin + s_full = a_i + b_i + cin_i; + end + + assign s_o = s_full[RADIX-1 : 0]; + assign cout_o = s_full[RADIX]; + +endmodule diff --git a/designs/Caliptra/src/adams-bridge/abr_ahb_defines_pkg.sv b/designs/Caliptra/src/adams-bridge/abr_ahb_defines_pkg.sv new file mode 100644 index 0000000..3598c4d --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/abr_ahb_defines_pkg.sv @@ -0,0 +1,25 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +// +`ifndef ABR_AHB_DEFINES_PKG +`define ABR_AHB_DEFINES_PKG + +package abr_ahb_defines_pkg; + + parameter ABR_H_OKAY=1'b0; + parameter ABR_H_ERROR=1'b1; + +endpackage + +`endif diff --git a/designs/Caliptra/src/adams-bridge/abr_ahb_slv_sif.sv b/designs/Caliptra/src/adams-bridge/abr_ahb_slv_sif.sv new file mode 100644 index 0000000..8e37922 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/abr_ahb_slv_sif.sv @@ -0,0 +1,166 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. + +module abr_ahb_slv_sif + import abr_ahb_defines_pkg::*; + #( + parameter AHB_DATA_WIDTH = 64 + ,parameter CLIENT_DATA_WIDTH = 32 + ,parameter AHB_ADDR_WIDTH = 32 + ,parameter CLIENT_ADDR_WIDTH = AHB_ADDR_WIDTH + + ) + ( + //AMBA AHB Lite INF + input logic hclk, + input logic hreset_n, + input logic [AHB_ADDR_WIDTH-1:0] haddr_i, + input logic [AHB_DATA_WIDTH-1:0] hwdata_i, + input logic hsel_i, + input logic hwrite_i, + + input logic hready_i, + input logic [1:0] htrans_i, + input logic [2:0] hsize_i, + + + output logic hresp_o, + output logic hreadyout_o, + output logic [AHB_DATA_WIDTH-1:0] hrdata_o, + + //COMPONENT INF + output logic dv, + input logic hld, + input logic err, + output logic write, + output logic [CLIENT_DATA_WIDTH-1:0] wdata, + output logic [CLIENT_ADDR_WIDTH-1:0] addr, + + input logic [CLIENT_DATA_WIDTH-1:0] rdata + ); + +logic err_f; + +localparam BITS_WDATA = $bits(wdata); + +//support bus widths: +//64b ahb, 32b client +//64b ahb, 64b client +generate + if ((AHB_DATA_WIDTH == 32) & (CLIENT_DATA_WIDTH == 32)) begin + always_comb begin + unique case (hsize_i) inside + 3'b000: //byte + //wdata = {{$bits(wdata)-8{1'b0}},hwdata_i[7:0]}; + wdata = {{BITS_WDATA-8{1'b0}},hwdata_i[7:0]}; + 3'b001: //halfword + //wdata = {{$bits(wdata)-16{1'b0}},hwdata_i[15:0]}; + wdata = {{BITS_WDATA-16{1'b0}},hwdata_i[15:0]}; + 3'b010: //word + wdata = hwdata_i[31:0]; + default: //word + wdata = hwdata_i[31:0]; + endcase + end + always_comb hrdata_o = rdata; + end else if ((AHB_DATA_WIDTH == 64) & (CLIENT_DATA_WIDTH == 32)) begin + always_comb begin + unique case (hsize_i) inside + 3'b000: //byte + //wdata = addr[2] ? {{$bits(wdata)-8{1'b0}},hwdata_i[39:32]} : {{$bits(wdata)-8{1'b0}},hwdata_i[7:0]}; + wdata = addr[2] ? {{BITS_WDATA-8{1'b0}},hwdata_i[39:32]} : {{BITS_WDATA-8{1'b0}},hwdata_i[7:0]}; + 3'b001: //halfword + //wdata = addr[2] ? {{$bits(wdata)-16{1'b0}},hwdata_i[47:32]} : {{$bits(wdata)-16{1'b0}},hwdata_i[15:0]}; + wdata = addr[2] ? {{BITS_WDATA-16{1'b0}},hwdata_i[47:32]} : {{BITS_WDATA-16{1'b0}},hwdata_i[15:0]}; + 3'b010: //word + wdata = addr[2] ? hwdata_i[63:32] : hwdata_i[31:0]; + default: //word + wdata = addr[2] ? hwdata_i[63:32] : hwdata_i[31:0]; + endcase + end + always_comb hrdata_o = addr[2] ? {rdata, 32'b0} : {32'b0, rdata}; + end else if ((AHB_DATA_WIDTH == 64) & (CLIENT_DATA_WIDTH == 64)) begin + always_comb begin + unique case (hsize_i) inside + 3'b000: //byte + //wdata = {{$bits(wdata)-8{1'b0}},hwdata_i[7:0]}; + wdata = {{BITS_WDATA-8{1'b0}},hwdata_i[7:0]}; + 3'b001: //halfword + //wdata = {{$bits(wdata)-16{1'b0}},hwdata_i[15:0]}; + wdata = {{BITS_WDATA-16{1'b0}},hwdata_i[15:0]}; + 3'b010: //word + wdata = addr[2]? hwdata_i[63:32] : hwdata_i[31:0]; + 3'b011: //dword + wdata = hwdata_i; + default: //dword + wdata = hwdata_i; + endcase + end + always_comb hrdata_o = rdata; + end + +endgenerate + + always_ff @(posedge hclk or negedge hreset_n) begin + if(!hreset_n) begin + dv <= 1'b0; + write <= 1'b0; + addr <= '0; + err_f <= '0; + end + else begin + err_f <= err; + if (hready_i) begin + dv <= hsel_i & htrans_i inside {2'b10, 2'b11}; + end + if(hready_i & hsel_i) begin + addr <= haddr_i[CLIENT_ADDR_WIDTH-1:0]; + write <= hwrite_i & |htrans_i; + end + end + end + +always_comb begin : response_block + hreadyout_o = 1'b1; + hresp_o = ABR_H_OKAY; + //first err cycle, de-assert ready and drive err + if (err & ~err_f) begin + hreadyout_o = 1'b0; + hresp_o = ABR_H_ERROR; + end else if (hld) begin + hreadyout_o = 1'b0; + hresp_o = ABR_H_OKAY; + end else if (err_f) begin + hreadyout_o = 1'b1; + hresp_o = ABR_H_ERROR; + end +end + +//Coverage +`ifndef VERILATOR +`ifdef FCOV + +covergroup ahb_slv_sif_cov_grp @(posedge hclk); + option.per_instance = 1; + + ahb_read_cp: coverpoint (dv & ~write) {option.comment = "AHB read transaction";} + ahb_write_cp: coverpoint (dv & write) {option.comment = "AHB write transaction";} +endgroup + +ahb_slv_sif_cov_grp ahb_slv_sif_cov_grp1 = new(); + +`endif +`endif + +endmodule diff --git a/designs/Caliptra/src/adams-bridge/abr_config_defines.svh b/designs/Caliptra/src/adams-bridge/abr_config_defines.svh new file mode 100644 index 0000000..8ee56a4 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/abr_config_defines.svh @@ -0,0 +1,86 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +// +`ifndef ABR_CFG_SV +`define ABR_CFG_SV + + `include "abr_sva.svh" + // `define RV_FPGA_OPTIMIZE + // `define RV_FPGA_SCA + `define MLDSA_MASKING + + `define ABR_ICG abr_clk_gate + + `define ABR_MEM(_depth, _width, _mem_name) \ + abr_1r1w_ram \ + #( .DEPTH(``_depth``), \ + .DATA_WIDTH(``_width``)) \ + abr_``_mem_name``_inst\ + (\ + .clk_i(clk_i),\ + .we_i(abr_memory_export.``_mem_name``_we_i),\ + .waddr_i(abr_memory_export.``_mem_name``_waddr_i),\ + .wdata_i(abr_memory_export.``_mem_name``_wdata_i),\ + .re_i(abr_memory_export.``_mem_name``_re_i),\ + .raddr_i(abr_memory_export.``_mem_name``_raddr_i),\ + .rdata_o(abr_memory_export.``_mem_name``_rdata_o)\ + ); + + `define ABR_MEM_BE(_depth, _width, _mem_name) \ + abr_1r1w_be_ram \ + #( .DEPTH(``_depth``), \ + .DATA_WIDTH(``_width``)) \ + abr_``_mem_name``_inst\ + (\ + .clk_i(clk_i),\ + .we_i(abr_memory_export.``_mem_name``_we_i),\ + .waddr_i(abr_memory_export.``_mem_name``_waddr_i),\ + .wdata_i(abr_memory_export.``_mem_name``_wdata_i),\ + .wstrobe_i(abr_memory_export.``_mem_name``_wstrobe_i),\ + .re_i(abr_memory_export.``_mem_name``_re_i),\ + .raddr_i(abr_memory_export.``_mem_name``_raddr_i),\ + .rdata_o(abr_memory_export.``_mem_name``_rdata_o)\ + ); + + `define CALIPTRA_KV_RD_TIEOFF(sig_prefix, hwif_name = hwif_in)\ + assign ``hwif_name.``sig_prefix``_rd_status.ERROR.next = '0;\ + assign ``hwif_name.``sig_prefix``_rd_status.READY.next = '0;\ + assign ``hwif_name.``sig_prefix``_rd_status.VALID.hwset = '0;\ + assign ``hwif_name.``sig_prefix``_rd_status.VALID.hwclr = '0;\ + assign ``hwif_name.``sig_prefix``_rd_ctrl.read_en.hwclr = '0;\ + assign ``hwif_name.``sig_prefix``_rd_ctrl.read_en.swwe = '0;\ + assign ``hwif_name.``sig_prefix``_rd_ctrl.read_entry.swwe = '0;\ + assign ``hwif_name.``sig_prefix``_rd_ctrl.pcr_hash_extend.swwe = '0;\ + assign ``hwif_name.``sig_prefix``_rd_ctrl.rsvd.swwe = '0; + + `define CALIPTRA_KV_WR_TIEOFF(sig_prefix, hwif_name = hwif_in)\ + assign ``hwif_name.``sig_prefix``_wr_status.ERROR.next = '0;\ + assign ``hwif_name.``sig_prefix``_wr_status.READY.next = '0;\ + assign ``hwif_name.``sig_prefix``_wr_status.VALID.hwset = '0;\ + assign ``hwif_name.``sig_prefix``_wr_status.VALID.hwclr = '0;\ + assign ``hwif_name.``sig_prefix``_wr_ctrl.write_en.hwclr = '0;\ + assign ``hwif_name.``sig_prefix``_wr_ctrl.write_en.swwe = '0;\ + assign ``hwif_name.``sig_prefix``_wr_ctrl.write_entry.swwe = '0;\ + assign ``hwif_name.``sig_prefix``_wr_ctrl.hmac_key_dest_valid.swwe = '0;\ + assign ``hwif_name.``sig_prefix``_wr_ctrl.hmac_block_dest_valid.swwe = '0;\ + assign ``hwif_name.``sig_prefix``_wr_ctrl.mldsa_seed_dest_valid.swwe = '0;\ + assign ``hwif_name.``sig_prefix``_wr_ctrl.ecc_pkey_dest_valid.swwe = '0;\ + assign ``hwif_name.``sig_prefix``_wr_ctrl.ecc_seed_dest_valid.swwe = '0;\ + assign ``hwif_name.``sig_prefix``_wr_ctrl.aes_key_dest_valid.swwe = '0;\ + assign ``hwif_name.``sig_prefix``_wr_ctrl.mlkem_seed_dest_valid.swwe = '0;\ + assign ``hwif_name.``sig_prefix``_wr_ctrl.mlkem_msg_dest_valid.swwe = '0;\ + assign ``hwif_name.``sig_prefix``_wr_ctrl.dma_data_dest_valid.swwe = '0;\ + assign ``hwif_name.``sig_prefix``_wr_ctrl.rsvd.swwe = '0; + +`endif diff --git a/designs/Caliptra/src/adams-bridge/abr_ctrl.sv b/designs/Caliptra/src/adams-bridge/abr_ctrl.sv new file mode 100644 index 0000000..124d3af --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/abr_ctrl.sv @@ -0,0 +1,2222 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. + +//High level controller block for executing +//Adams Bridge functions +// ML-DSA Keygen +// ML-DSA Signing +// ML-DSA Verifying +// ML-KEM Keygen +// ML-KEM Encaps +// ML-KEM Decaps + +`include "abr_config_defines.svh" +`ifdef CALIPTRA +`include "kv_macros.svh" +`endif + +module abr_ctrl + import abr_reg_pkg::*; + import abr_sha3_pkg::*; + import abr_sampler_pkg::*; + import abr_ctrl_pkg::*; + import abr_params_pkg::*; + import ntt_defines_pkg::*; + import compress_defines_pkg::*; + import decompress_defines_pkg::*; + `ifdef CALIPTRA + import kv_defines_pkg::*; + `endif + #( + ) + ( + input logic clk, + input logic rst_b, + output logic zeroize, + +`ifdef RV_FPGA_SCA + output logic NTT_trigger, + output logic PWM_trigger, + output logic PWA_trigger, + output logic INTT_trigger, +`endif + + output abr_reg__in_t abr_reg_hwif_in_o, + input abr_reg__out_t abr_reg_hwif_out_i, + + //sampler interface + output abr_sampler_mode_e sampler_mode_o, + output logic sha3_start_o, + output logic msg_start_o, + output logic msg_valid_o, + input logic msg_rdy_i, + output logic [MsgStrbW-1:0] msg_strobe_o, + output logic [MsgWidth-1:0] msg_data_o[Sha3Share], + output logic sampler_start_o, + + input logic sampler_busy_i, + input logic sampler_state_dv_i, + input logic [abr_sha3_pkg::StateW-1:0] sampler_state_data_i [Sha3Share], + + output logic [ABR_MEM_ADDR_WIDTH-1:0] dest_base_addr_o, + + //ntt interfaces + output logic [ABR_NUM_NTT-1:0] ntt_enable_o, + output abr_ntt_mode_e [ABR_NUM_NTT-1:0] ntt_mode_o, + output ntt_mem_addr_t [ABR_NUM_NTT-1:0] ntt_mem_base_addr_o, + output pwo_mem_addr_t [ABR_NUM_NTT-1:0] pwo_mem_base_addr_o, + output logic [ABR_NUM_NTT-1:0] ntt_masking_en_o, + output logic [ABR_NUM_NTT-1:0] ntt_shuffling_en_o, + input logic [ABR_NUM_NTT-1:0] ntt_busy_i, + + //aux interfaces + output logic [ABR_MEM_ADDR_WIDTH-1:0] aux_src0_base_addr_o, + output logic [ABR_MEM_ADDR_WIDTH-1:0] aux_src1_base_addr_o, + output logic [ABR_MEM_ADDR_WIDTH-1:0] aux_dest_base_addr_o, + + output logic power2round_enable_o, + input mem_if_t [1:0] pwr2rnd_keymem_if_i, + input logic [1:0] [DATA_WIDTH-1:0] pwr2rnd_wr_data_i, + input logic pk_t1_wren_i, + input logic [7:0][T1_COEFF_W-1:0] pk_t1_wrdata_i, + input logic [7:0] pk_t1_wr_addr_i, + input logic power2round_done_i, + + output logic decompose_enable_o, + output logic decompose_mode_o, + input logic decompose_done_i, + + output logic skencode_enable_o, + input mem_if_t skencode_keymem_if_i, + input logic [DATA_WIDTH-1:0] skencode_wr_data_i, + input logic skencode_done_i, + + output logic skdecode_enable_o, + input mem_if_t [1:0] skdecode_keymem_if_i, + output logic [1:0][DATA_WIDTH-1:0] skdecode_rd_data_o, + input logic skdecode_done_i, + input logic skdecode_error_i, + + output logic makehint_enable_o, + input logic makehint_invalid_i, + input logic makehint_done_i, + input logic makehint_reg_wren_i, + input logic [3:0][7:0] makehint_reg_wrdata_i, + input logic [ABR_MEM_ADDR_WIDTH-1:0] makehint_reg_wr_addr_i, + + output logic normcheck_enable_o, + output logic [1:0] normcheck_mode_o, + input logic normcheck_invalid_i, + input logic normcheck_done_i, + + output logic sigencode_enable_o, + input mem_if_t sigencode_wr_req_i, + input logic [1:0][3:0][19:0] sigencode_wr_data_i, + input logic sigencode_done_i, + + output logic pkdecode_enable_o, + input logic [7:0] pkdecode_rd_addr_i, + output logic [7:0][T1_COEFF_W-1:0] pkdecode_rd_data_o, + input logic pkdecode_done_i, + + output logic sigdecode_h_enable_o, + output logic [SIGNATURE_H_VALID_NUM_BYTES-1:0][7:0] signature_h_o, + input logic sigdecode_h_invalid_i, + input logic sigdecode_h_done_i, + + output logic sigdecode_z_enable_o, + input mem_if_t sigdecode_z_rd_req_i, + output logic [1:0][3:0][19:0] sigdecode_z_rd_data_o, + input logic sigdecode_z_done_i, + + output logic compress_enable_o, + output compress_mode_t compress_mode_o, + output logic compress_compare_mode_o, + output logic [2:0] compress_num_poly_o, + input logic compress_done_i, + input logic compress_compare_failed_i, + input logic [1:0] compress_api_rw_en_i, + input logic [ABR_MEM_ADDR_WIDTH-1:0] compress_api_rw_addr_i, + input logic [DATA_WIDTH-1:0] compress_api_wr_data_i, + output logic [DATA_WIDTH-1:0] compress_api_rd_data_o, + + output logic decompress_enable_o, + input logic decompress_done_i, + output decompress_mode_t decompress_mode_o, + output logic [2:0] decompress_num_poly_o, + input logic decompress_api_rd_en_i, + input logic [ABR_MEM_ADDR_WIDTH-1:0] decompress_api_rd_addr_i, + output logic [1:0][DATA_WIDTH-1:0] decompress_api_rd_data_o, + + output logic lfsr_enable_o, + output logic [1:0][LFSR_W-1:0] lfsr_seed_o, + + //Memory interface export + abr_sram_if.req sk_bank0_mem_if, + abr_sram_if.req sk_bank1_mem_if, + abr_sram_be_if.req sig_z_mem_if, + abr_sram_be_if.req pk_mem_if, + + output mem_if_t zeroize_mem_o, + + `ifdef CALIPTRA + // KV interface + output kv_read_t [2:0] kv_read, + input kv_rd_resp_t [2:0] kv_rd_resp, + output kv_write_t kv_write, + input kv_wr_resp_t kv_wr_resp, + //PCR Signing + input pcr_signing_t pcr_signing_data, + input logic ocp_lock_in_progress, + `endif + + input logic debugUnlock_or_scan_mode_switch, + output logic busy_o, + + //Interrupts + output logic error_intr, + output logic notif_intr + + ); + + abr_reg__in_t abr_reg_hwif_in; + abr_reg__out_t abr_reg_hwif_out; + abr_scratch_reg_u abr_scratch_reg; + logic abr_ready; + logic abr_idle; + logic mldsa_valid_reg; + logic mlkem_valid_reg; + logic mldsa_privkey_lock, mlkem_dk_lock; + logic kv_mldsa_seed_data_present, kv_mlkem_seed_data_present, kv_mlkem_msg_data_present; + logic kv_mlkem_msg_write_en; + logic [$clog2(MLKEM_MSG_MEM_NUM_DWORDS)-1:0] kv_mlkem_msg_write_offset; + logic [DATA_WIDTH-1:0] kv_mlkem_msg_write_data; + + logic external_mu; + logic external_mu_mode, external_mu_mode_nxt; + + `ifdef CALIPTRA + //Custom keyvault logic for Caliptra + logic kv_mldsa_seed_write_en; + logic [$clog2(SEED_NUM_DWORDS)-1:0] kv_mldsa_seed_write_offset; + logic [DATA_WIDTH-1:0] kv_mldsa_seed_write_data; + logic kv_mlkem_seed_write_en; + logic [$clog2(2*SEED_NUM_DWORDS)-1:0] kv_mlkem_seed_write_offset; + logic [DATA_WIDTH-1:0] kv_mlkem_seed_write_data; + kv_read_ctrl_reg_t kv_mldsa_seed_read_ctrl_reg; + kv_read_ctrl_reg_t kv_mlkem_seed_read_ctrl_reg; + kv_read_ctrl_reg_t kv_mlkem_msg_read_ctrl_reg; + kv_write_ctrl_reg_t kv_mlkem_sharedkey_write_ctrl_reg; + kv_read_filter_metrics_t kv_mldsa_seed_read_metrics; + kv_read_filter_metrics_t kv_mlkem_seed_read_metrics; + kv_read_filter_metrics_t kv_mlkem_msg_read_metrics; + kv_write_filter_metrics_t kv_mlkem_sharedkey_write_metrics; + kv_error_code_e kv_mldsa_seed_error; + kv_error_code_e kv_mlkem_seed_error; + kv_error_code_e kv_mlkem_msg_error; + kv_error_code_e kv_mlkem_sharedkey_error; + logic kv_mldsa_seed_ready, kv_mldsa_seed_done; + logic kv_mlkem_seed_ready, kv_mlkem_seed_done; + logic kv_mlkem_msg_ready, kv_mlkem_msg_done; + logic kv_mlkem_sharedkey_ready, kv_mlkem_sharedkey_done; + logic kv_mldsa_seed_data_present_set; + logic kv_mlkem_seed_data_present_set; + logic kv_mlkem_msg_data_present_set; + logic pcr_sign_mode; + logic pcr_sign_input_invalid; + logic dest_keyvault; + logic kv_dest_data_avail; + + logic [SHAREDKEY_NUM_DWORDS-1:0][3:0][7:0] mlkem_sharedkey_data; + + `CALIPTRA_KV_READ_STATUS_ASSIGN(kv_mldsa_seed, abr_reg_hwif_in) + `CALIPTRA_KV_READ_STATUS_ASSIGN(kv_mlkem_seed, abr_reg_hwif_in) + `CALIPTRA_KV_READ_STATUS_ASSIGN(kv_mlkem_msg, abr_reg_hwif_in) + `CALIPTRA_KV_WRITE_STATUS_ASSIGN(kv_mlkem_sharedkey, abr_reg_hwif_in) + `CALIPTRA_KV_READ_CTRL_REG2STRUCT(kv_mldsa_seed_read_ctrl_reg, kv_mldsa_seed_rd_ctrl, abr_reg_hwif_out) + `CALIPTRA_KV_READ_CTRL_REG2STRUCT(kv_mlkem_seed_read_ctrl_reg, kv_mlkem_seed_rd_ctrl, abr_reg_hwif_out) + `CALIPTRA_KV_READ_CTRL_REG2STRUCT(kv_mlkem_msg_read_ctrl_reg, kv_mlkem_msg_rd_ctrl, abr_reg_hwif_out) + `CALIPTRA_KV_WRITE_CTRL_REG2STRUCT(kv_mlkem_sharedkey_write_ctrl_reg, kv_mlkem_sharedkey_wr_ctrl, abr_reg_hwif_out) + + //Detect keyvault data coming in to lock api registers and protect outputs + always_comb kv_mldsa_seed_data_present_set = kv_mldsa_seed_read_ctrl_reg.read_en | pcr_sign_mode; + always_comb kv_mlkem_seed_data_present_set = kv_mlkem_seed_read_ctrl_reg.read_en; + always_comb kv_mlkem_msg_data_present_set = kv_mlkem_msg_read_ctrl_reg.read_en; + + //lock kv controls + always_comb abr_reg_hwif_in.kv_mldsa_seed_rd_ctrl.read_en.swwe = !kv_mldsa_seed_data_present && abr_ready; + always_comb abr_reg_hwif_in.kv_mldsa_seed_rd_ctrl.read_entry.swwe = !kv_mldsa_seed_data_present && abr_ready; + always_comb abr_reg_hwif_in.kv_mldsa_seed_rd_ctrl.pcr_hash_extend.swwe = !kv_mldsa_seed_data_present && abr_ready; + always_comb abr_reg_hwif_in.kv_mldsa_seed_rd_ctrl.rsvd.swwe = !kv_mldsa_seed_data_present && abr_ready; + always_comb abr_reg_hwif_in.kv_mlkem_seed_rd_ctrl.read_en.swwe = !kv_mlkem_seed_data_present && abr_ready; + always_comb abr_reg_hwif_in.kv_mlkem_seed_rd_ctrl.read_entry.swwe = !kv_mlkem_seed_data_present && abr_ready; + always_comb abr_reg_hwif_in.kv_mlkem_seed_rd_ctrl.pcr_hash_extend.swwe = !kv_mlkem_seed_data_present && abr_ready; + always_comb abr_reg_hwif_in.kv_mlkem_seed_rd_ctrl.rsvd.swwe = !kv_mlkem_seed_data_present && abr_ready; + always_comb abr_reg_hwif_in.kv_mlkem_msg_rd_ctrl.read_en.swwe = !kv_mlkem_msg_data_present && abr_ready; + always_comb abr_reg_hwif_in.kv_mlkem_msg_rd_ctrl.read_entry.swwe = !kv_mlkem_msg_data_present && abr_ready; + always_comb abr_reg_hwif_in.kv_mlkem_msg_rd_ctrl.pcr_hash_extend.swwe = !kv_mlkem_msg_data_present && abr_ready; + always_comb abr_reg_hwif_in.kv_mlkem_msg_rd_ctrl.rsvd.swwe = !kv_mlkem_msg_data_present && abr_ready; + always_comb abr_reg_hwif_in.kv_mlkem_sharedkey_wr_ctrl.write_en.swwe = abr_ready; + always_comb abr_reg_hwif_in.kv_mlkem_sharedkey_wr_ctrl.write_entry.swwe = abr_ready; + always_comb abr_reg_hwif_in.kv_mlkem_sharedkey_wr_ctrl.hmac_key_dest_valid.swwe = abr_ready; + always_comb abr_reg_hwif_in.kv_mlkem_sharedkey_wr_ctrl.hmac_block_dest_valid.swwe = abr_ready; + always_comb abr_reg_hwif_in.kv_mlkem_sharedkey_wr_ctrl.mldsa_seed_dest_valid.swwe = abr_ready; + always_comb abr_reg_hwif_in.kv_mlkem_sharedkey_wr_ctrl.ecc_pkey_dest_valid.swwe = abr_ready; + always_comb abr_reg_hwif_in.kv_mlkem_sharedkey_wr_ctrl.ecc_seed_dest_valid.swwe = abr_ready; + always_comb abr_reg_hwif_in.kv_mlkem_sharedkey_wr_ctrl.aes_key_dest_valid.swwe = abr_ready; + always_comb abr_reg_hwif_in.kv_mlkem_sharedkey_wr_ctrl.mlkem_seed_dest_valid.swwe = abr_ready; + always_comb abr_reg_hwif_in.kv_mlkem_sharedkey_wr_ctrl.mlkem_msg_dest_valid.swwe = abr_ready; + always_comb abr_reg_hwif_in.kv_mlkem_sharedkey_wr_ctrl.dma_data_dest_valid.swwe = abr_ready; + always_comb abr_reg_hwif_in.kv_mlkem_sharedkey_wr_ctrl.rsvd.swwe = abr_ready; + + //OCP Lock filtering rules inputs + always_comb begin + //MLDSA SEED + kv_mldsa_seed_read_metrics.ocp_lock_in_progress = ocp_lock_in_progress; + kv_mldsa_seed_read_metrics.kv_read_dest = KV_NUM_READ'(1<= ctx_cnt_required; + stream_msg_strobe = stream_msg_last ? ~(STREAM_MSG_STROBE_W'('1) << ctx_cnt_offset) : '1; + stream_msg_data = ctx_reg[ctx_cnt]; + if (ctx_cnt >= ctx_cnt_required) begin + stream_msg_fsm_ns = MLDSA_MSG_RDY; + ctx_cnt_nxt = 0; + end + end + MLDSA_MSG_RDY: begin + //Stream msg + stream_msg_rdy = 1; + stream_msg_strobe = stream_msg_valid ? abr_reg_hwif_out.MLDSA_MSG_STROBE.STROBE.value : '0; + stream_msg_data = abr_reg_hwif_out.MLDSA_MSG[0].MSG.value; + if ((stream_msg_strobe != '1) & stream_msg_valid) begin + stream_msg_fsm_ns = MLDSA_MSG_FLUSH; + end + end + MLDSA_MSG_FLUSH: begin + //Flush buffer + stream_msg_buffer_flush = 1; + if (stream_msg_buffer_strobe == '0) begin + stream_msg_fsm_ns = MLDSA_MSG_DONE; + end + end + MLDSA_MSG_DONE: begin + stream_msg_done = 1; + stream_msg_fsm_ns = MLDSA_MSG_IDLE; + end + default: begin + end + endcase +end + +//State flop +always_ff @(posedge clk or negedge rst_b) begin : stream_msg_fsm_flops + if (!rst_b) begin + stream_msg_fsm_ps <= MLDSA_MSG_IDLE; + end + else if (zeroize) begin + stream_msg_fsm_ps <= MLDSA_MSG_IDLE; + end + else begin + stream_msg_fsm_ps <= stream_msg_fsm_ns; + end +end + +//Buffer msg data to align to msg interface +abr_msg_buffer #( + .NUM_WR(STREAM_MSG_STROBE_W), + .NUM_RD(MsgStrbW), + .BUFFER_DATA_W(8) //stores on byte level +) stream_msg_buffer ( + .clk(clk), + .rst_b(rst_b), + .flush(stream_msg_buffer_flush), + //input data + .data_valid_i(stream_msg_strobe), + .data_i(stream_msg_data), + .buffer_full_o(), + //output data + .data_valid_o(stream_msg_buffer_strobe), + .data_hold_i('0), + .data_o(stream_msg_buffer_data) +); + +//send valid when full packet, or when flushing +always_comb stream_msg_buffer_valid = stream_msg_buffer_flush ? (|stream_msg_buffer_strobe) : (&stream_msg_buffer_strobe); + +//determine the number of bytes in the last message +//operand 2 contains the length of the message being fed to sha3 +//shift a zero into the strobe for each byte, and invert to get the valid bytes +always_comb last_msg_strobe = ~(MsgStrbW'('1) << abr_instr.length[$clog2(MsgStrbW)-1:0]); + +always_comb msg_hold = msg_valid_o & ~msg_rdy_i; + +//Last cycle when msg count is equal to length +//length is in bytes - compare against MSB from strobe width gets us the length in msg interface chunks +always_comb msg_last = stream_msg_ip ? '0 : (msg_cnt == abr_instr.length[ABR_OPR_WIDTH-1:$clog2(MsgStrbW)]); +always_comb msg_done = stream_msg_ip ? stream_msg_done : (msg_cnt > abr_instr.length[ABR_OPR_WIDTH-1:$clog2(MsgStrbW)]); + +//overload msg interface with stream msg interface +always_comb msg_cnt_nxt = stream_msg_ip ? '0 : + msg_done ? '0 : + msg_valid ? msg_cnt + 'd1 : msg_cnt; +always_comb msg_valid_nxt = stream_msg_ip ? stream_msg_buffer_valid : msg_valid; +always_comb msg_strobe_nxt = stream_msg_ip ? stream_msg_buffer_strobe : + msg_last ? last_msg_strobe : '1; + +always_ff @(posedge clk or negedge rst_b) begin + if (!rst_b) begin + msg_cnt <= 0; + msg_valid_o <= 0; + msg_strobe_o <= 0; + end + else if (zeroize) begin + msg_cnt <= 0; + msg_valid_o <= 0; + msg_strobe_o <= 0; + end + else begin + msg_cnt <= msg_hold ? msg_cnt : msg_cnt_nxt; + msg_valid_o <= msg_hold ? msg_valid_o : msg_valid_nxt; + msg_strobe_o <= msg_hold ? msg_strobe_o : msg_strobe_nxt; + end +end + +//State logic +always_comb begin : ctrl_fsm_out_combo + abr_ctrl_fsm_ns = abr_ctrl_fsm_ps; + sha3_start_o = '0; + msg_start_o = '0; + msg_valid = '0; + sampler_start_o = '0; + sampler_src = '0; + sampler_imm = '0; + ntt_en[0] = '0; + power2round_enable_o = '0; + decompose_enable_o = '0; + skencode_enable_o = '0; + pkdecode_enable_o = '0; + sigdecode_h_enable_o = '0; + sigdecode_z_enable_o = '0; + skdecode_enable_o = '0; + makehint_enable_o = '0; + sigencode_enable_o = '0; + normcheck_enable_o = '0; + compress_enable_o = '0; + decompress_enable_o = '0; + lfsr_enable_o = '0; + + unique case (abr_ctrl_fsm_ps) + ABR_CTRL_IDLE: begin + //load keccak data to SIPO + if (abr_instr.opcode.keccak_en) + abr_ctrl_fsm_ns = ABR_CTRL_SHA3_START; + else if (abr_instr.opcode.ntt_en & ntt_busy[0]) + abr_ctrl_fsm_ns = ABR_CTRL_STALLED; + else if ((abr_instr.opcode.sampler_en | abr_instr.opcode.aux_en | abr_instr.opcode.ntt_en)) + abr_ctrl_fsm_ns = ABR_CTRL_FUNC_START; + end + ABR_CTRL_SHA3_START: begin + abr_ctrl_fsm_ns = ABR_CTRL_MSG_START; + //drive start + sha3_start_o = 1; + end + ABR_CTRL_MSG_START: begin + abr_ctrl_fsm_ns = ABR_CTRL_MSG_LOAD; + msg_start_o = 1; + end + ABR_CTRL_MSG_LOAD: begin + msg_valid = 1; + sampler_src = abr_instr.operand1; + sampler_imm = abr_instr.imm; + if (msg_done & ~msg_hold) begin + msg_valid = 0; + if (abr_instr.opcode.ntt_en & ntt_busy[0]) abr_ctrl_fsm_ns = ABR_CTRL_STALLED; + else if (abr_instr.opcode.sampler_en | abr_instr.opcode.aux_en | abr_instr.opcode.ntt_en) abr_ctrl_fsm_ns = ABR_CTRL_FUNC_START; + else abr_ctrl_fsm_ns = ABR_CTRL_MSG_WAIT; + end + end + ABR_CTRL_MSG_WAIT: begin + //load another message + if (abr_instr.opcode.keccak_en) + abr_ctrl_fsm_ns = ABR_CTRL_MSG_LOAD; + //NTT is stalled + else if (abr_instr.opcode.ntt_en & ntt_busy[0]) + abr_ctrl_fsm_ns = ABR_CTRL_STALLED; + //Start the function + else if ((abr_instr.opcode.sampler_en | abr_instr.opcode.aux_en | abr_instr.opcode.ntt_en)) + abr_ctrl_fsm_ns = ABR_CTRL_FUNC_START; + end + ABR_CTRL_STALLED: begin + if (abr_instr.opcode.ntt_en & ~ntt_busy[0]) + abr_ctrl_fsm_ns = ABR_CTRL_FUNC_START; + end + ABR_CTRL_FUNC_START: begin + abr_ctrl_fsm_ns = ABR_CTRL_DONE; + sampler_start_o = abr_instr.opcode.sampler_en; + ntt_en[0] = abr_instr.opcode.ntt_en; + if (abr_instr.opcode.aux_en) begin + power2round_enable_o = (abr_instr.opcode.mode.aux_mode == MLDSA_PWR2RND); + decompose_enable_o = (abr_instr.opcode.mode.aux_mode inside {MLDSA_DECOMP,MLDSA_USEHINT}); + skencode_enable_o = (abr_instr.opcode.mode.aux_mode == MLDSA_SKENCODE); + pkdecode_enable_o = (abr_instr.opcode.mode.aux_mode == MLDSA_PKDECODE); + sigdecode_h_enable_o = (abr_instr.opcode.mode.aux_mode == MLDSA_SIGDEC_H); + sigdecode_z_enable_o = (abr_instr.opcode.mode.aux_mode == MLDSA_SIGDEC_Z); + skdecode_enable_o = (abr_instr.opcode.mode.aux_mode == MLDSA_SKDECODE); + makehint_enable_o = (abr_instr.opcode.mode.aux_mode == MLDSA_MAKEHINT); + sigencode_enable_o = (abr_instr.opcode.mode.aux_mode == MLDSA_SIGENC); + normcheck_enable_o = (abr_instr.opcode.mode.aux_mode == MLDSA_NORMCHK); + compress_enable_o = (abr_instr.opcode.mode.aux_mode == MLKEM_COMPRESS); + decompress_enable_o = (abr_instr.opcode.mode.aux_mode == MLKEM_DECOMPRESS); + lfsr_enable_o = (abr_instr.opcode.mode.aux_mode == MLDSA_LFSR); + end + end + ABR_CTRL_DONE: begin + if ((~sampler_busy_i & ~ntt_busy[0] & ~abr_instr.opcode.aux_en) | + (abr_instr.opcode.aux_en & (abr_instr.opcode.mode.aux_mode inside {MLDSA_DECOMP,MLDSA_USEHINT}) & decompose_done_i) | + (abr_instr.opcode.aux_en & (abr_instr.opcode.mode.aux_mode == MLDSA_PWR2RND) & power2round_done_i) | + (abr_instr.opcode.aux_en & (abr_instr.opcode.mode.aux_mode == MLDSA_SKENCODE) & skencode_done_i) | + (abr_instr.opcode.aux_en & (abr_instr.opcode.mode.aux_mode == MLDSA_PKDECODE) & pkdecode_done_i) | + (abr_instr.opcode.aux_en & (abr_instr.opcode.mode.aux_mode == MLDSA_SIGDEC_H) & sigdecode_h_done_i) | + (abr_instr.opcode.aux_en & (abr_instr.opcode.mode.aux_mode == MLDSA_SIGDEC_Z) & sigdecode_z_done_i) | + (abr_instr.opcode.aux_en & (abr_instr.opcode.mode.aux_mode == MLDSA_NORMCHK) & normcheck_done_i) | + (abr_instr.opcode.aux_en & (abr_instr.opcode.mode.aux_mode == MLDSA_SKDECODE) & skdecode_done_i) | + (abr_instr.opcode.aux_en & (abr_instr.opcode.mode.aux_mode == MLDSA_MAKEHINT) & makehint_done_i) | + (abr_instr.opcode.aux_en & (abr_instr.opcode.mode.aux_mode == MLDSA_SIGENC) & sigencode_done_i) | + (abr_instr.opcode.aux_en & (abr_instr.opcode.mode.aux_mode == MLKEM_COMPRESS) & compress_done_i) | + (abr_instr.opcode.aux_en & (abr_instr.opcode.mode.aux_mode == MLKEM_DECOMPRESS) & decompress_done_i) | + (abr_instr.opcode.aux_en & (abr_instr.opcode.mode.aux_mode == MLDSA_LFSR)) ) begin + + abr_ctrl_fsm_ns = ABR_CTRL_IDLE; + + end + end + default: begin + end + endcase +end + +//State flop +always_ff @(posedge clk or negedge rst_b) begin : ctrl_fsm_flops + if (!rst_b) begin + abr_ctrl_fsm_ps <= ABR_CTRL_IDLE; + end + else if (zeroize) begin + abr_ctrl_fsm_ps <= ABR_CTRL_IDLE; + end + else begin + abr_ctrl_fsm_ps <= abr_ctrl_fsm_ns; + end +end + +abr_seq abr_seq_inst +( + .clk(clk), + + .en_i(abr_seq_en), + .addr_i(abr_prog_cntr_nxt), + .data_o(abr_instr_o) +); + +//NTT gasket +//Removed support for 2 NTT +localparam ABR_SEQ_NTT = 0; + +//Check if ntt is being enabled in this clock also +always_comb ntt_busy[ABR_SEQ_NTT] = abr_instr.opcode.ntt_en & (ntt_busy_i[ABR_SEQ_NTT] | ntt_enable_o[ABR_SEQ_NTT]); + +always_comb begin + ntt_enable_o[ABR_SEQ_NTT] = ntt_en[ABR_SEQ_NTT]; + ntt_mode_o[ABR_SEQ_NTT] = abr_instr.opcode.mode.ntt_mode; + ntt_masking_en_o[ABR_SEQ_NTT] = abr_instr.opcode.masking_en; + ntt_shuffling_en_o[ABR_SEQ_NTT] = abr_instr.opcode.shuffling_en; + //passing a bit on the immediate field to mux between temp address locations + ntt_temp_address[ABR_SEQ_NTT] = abr_instr.imm[0] ? MLDSA_TEMP2_BASE[ABR_MEM_ADDR_WIDTH-1:0] : MLDSA_TEMP0_BASE[ABR_MEM_ADDR_WIDTH-1:0]; + //optimization - could be one interface here? + ntt_mem_base_addr_o[ABR_SEQ_NTT] = '{src_base_addr:abr_instr.operand1[ABR_MEM_ADDR_WIDTH-1:0], + interim_base_addr:ntt_temp_address[ABR_SEQ_NTT], + dest_base_addr:abr_instr.operand3[ABR_MEM_ADDR_WIDTH-1:0]}; + pwo_mem_base_addr_o[ABR_SEQ_NTT] = '{pw_base_addr_b:abr_instr.operand1[ABR_MEM_ADDR_WIDTH-1:0], //PWO src + pw_base_addr_a:abr_instr.operand2[ABR_MEM_ADDR_WIDTH-1:0], //PWO src or sampler src + pw_base_addr_c:abr_instr.operand3[ABR_MEM_ADDR_WIDTH-1:0]}; +end + +//Zeroizer +always_comb abr_instr = ((abr_prog_cntr == ABR_ZEROIZE) | (abr_prog_cntr == ABR_RESET)) ? '0 : abr_instr_o; + +always_ff @(posedge clk or negedge rst_b) begin + if (!rst_b) begin + zeroize_mem_addr <= 0; + zeroize_mem_done <= 0; + end + else if (abr_prog_cntr == ABR_ZEROIZE) begin + if (zeroize_mem_addr == ABR_MEM_MAX_DEPTH) begin + zeroize_mem_addr <= 0; + zeroize_mem_done <= 1; + end else if (!zeroize_mem_done) begin + zeroize_mem_addr <= zeroize_mem_addr + 1; + end + end else begin + zeroize_mem_addr <= 0; + zeroize_mem_done <= 0; + end +end + +always_comb zeroize_mem_we = (abr_prog_cntr == ABR_ZEROIZE) & !zeroize_mem_done; + +always_comb zeroize_mem_o.rd_wr_en = zeroize_mem_we? RW_WRITE : RW_IDLE; +always_comb zeroize_mem_o.addr = zeroize_mem_addr; + +`ifdef RV_FPGA_SCA + //=========================================================================== + // + // ************** TRIGER Functionality ************** + // + //=========================================================================== + logic NTT_raw_signal, PWM_raw_signal, PWA_raw_signal, INTT_raw_signal; + gen_pulse_custom NTT_pulse + ( + .clk(clk), + .reset_n(rst_b), + .raw_signal(NTT_raw_signal), + .trigger_pulse(NTT_trigger) + ); + + gen_pulse_custom PWM_pulse + ( + .clk(clk), + .reset_n(rst_b), + .raw_signal(PWM_raw_signal), + .trigger_pulse(PWM_trigger) + ); + + gen_pulse_custom PWA_pulse + ( + .clk(clk), + .reset_n(rst_b), + .raw_signal(PWA_raw_signal), + .trigger_pulse(PWA_trigger) + ); + + gen_pulse_custom INTT_pulse + ( + .clk(clk), + .reset_n(rst_b), + .raw_signal(INTT_raw_signal), + .trigger_pulse(INTT_trigger) + ); + + always_ff @(posedge clk or negedge rst_b) begin + if (!rst_b) begin + NTT_raw_signal <= 'h0; + PWM_raw_signal <= 'h0; + PWA_raw_signal <= 'h0; + INTT_raw_signal <= 'h0; + end + else if (zeroize) begin + NTT_raw_signal <= 'h0; + PWM_raw_signal <= 'h0; + PWA_raw_signal <= 'h0; + INTT_raw_signal <= 'h0; + end + else begin + if (sec_seq_en) begin + unique case(sec_prog_cntr_nxt) + MLDSA_SIGN_VALID_S : begin //NTT(C) + NTT_raw_signal <= 'h1; + PWM_raw_signal <= 'h0; + PWA_raw_signal <= 'h0; + INTT_raw_signal <= 'h0; + end + MLDSA_SIGN_VALID_S+2 : begin + NTT_raw_signal <= 'h0; + PWM_raw_signal <= 'h1; + PWA_raw_signal <= 'h0; + INTT_raw_signal <= 'h0; + end + MLDSA_SIGN_VALID_S+4 : begin + NTT_raw_signal <= 'h0; + PWM_raw_signal <= 'h0; + PWA_raw_signal <= 'h1; + INTT_raw_signal <= 'h0; + end + MLDSA_SIGN_VALID_S+3 : begin + NTT_raw_signal <= 'h0; + PWM_raw_signal <= 'h0; + PWA_raw_signal <= 'h0; + INTT_raw_signal <= 'h1; + end + default : begin + NTT_raw_signal <= 'h0; + PWM_raw_signal <= 'h0; + PWA_raw_signal <= 'h0; + INTT_raw_signal <= 'h0; + end + endcase + end + end + end +`endif + + `ABR_ASSERT_KNOWN(ERR_ABR_CTRL_FSM_X, {abr_ctrl_fsm_ps}, clk, !rst_b) + `ABR_ASSERT_KNOWN(ERR_NTT_MEM_X, {ntt_mem_base_addr_o}, clk, !rst_b) + `ABR_ASSERT_KNOWN(ERR_PWO_MEM_X, {pwo_mem_base_addr_o}, clk, !rst_b) + `ABR_ASSERT_KNOWN(ERR_REG_HWIF_X, {abr_reg_hwif_in_o}, clk, !rst_b) + `ABR_ASSERT(ZEROIZE_SEED_REG, $fell(zeroize) |-> (mldsa_seed_reg === '0), clk, !rst_b) + //Assumption that stream message is never fast enough to get stalled + `ABR_ASSERT_NEVER(ERR_STREAM_MSG_STALLED, !(stream_msg_fsm_ps inside {MLDSA_MSG_IDLE}) & msg_hold, clk, !rst_b) + +`ifdef CALIPTRA + `ABR_ASSERT_STABLE(ERR_ABR_MLDSA_SEED_RD_CTRL_NOT_STABLE, kv_mldsa_seed_read_ctrl_reg, clk, (!rst_b || (abr_prog_cntr == ABR_RESET)) ) + `ABR_ASSERT_STABLE(ERR_ABR_MLKEM_SEED_RD_CTRL_NOT_STABLE, kv_mlkem_seed_read_ctrl_reg, clk, (!rst_b || (abr_prog_cntr == ABR_RESET)) ) + `ABR_ASSERT_STABLE(ERR_ABR_MLKEM_MSG_RD_CTRL_NOT_STABLE, kv_mlkem_msg_read_ctrl_reg , clk, (!rst_b || (abr_prog_cntr == ABR_RESET)) ) + //Zeroize clears these, some simulators will see this change on the same clock edge + //as the assertion becomes enabled and fire. Excluding zeroize phase from the assertion stability check + `ABR_ASSERT_STABLE(ERR_ABR_MLDSA_SEED_NOT_STABLE, mldsa_seed_reg, clk, (!rst_b || (abr_prog_cntr == ABR_RESET) || (abr_prog_cntr == ABR_ZEROIZE)) ) + `ABR_ASSERT_STABLE(ERR_ABR_MLKEM_SEED_NOT_STABLE, mlkem_seed_d_reg, clk, (!rst_b || (abr_prog_cntr == ABR_RESET) || (abr_prog_cntr == ABR_ZEROIZE)) ) +`endif + +endmodule diff --git a/designs/Caliptra/src/adams-bridge/abr_ctrl_pkg.sv b/designs/Caliptra/src/adams-bridge/abr_ctrl_pkg.sv new file mode 100644 index 0000000..67e9db6 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/abr_ctrl_pkg.sv @@ -0,0 +1,579 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +// +//====================================================================== +// +// abr_ctrl_pkg.sv +// -------- +// ABR instructions for MLDSA. +// +// +//====================================================================== + +`ifndef ABR_CTRL_PKG +`define ABR_CTRL_PKG + +package abr_ctrl_pkg; + import abr_params_pkg::*; + import abr_sampler_pkg::*; + + localparam integer ABR_OPR_WIDTH = 15; + localparam integer ABR_IMM_WIDTH = 16; + localparam ABR_PROG_ADDR_W = 10; + + localparam SEED_NUM_DWORDS = 8; + localparam MLDSA_MSG_NUM_DWORDS = 16; + localparam MLKEM_MSG_NUM_DWORDS = 8; + localparam MU_NUM_DWORDS = 16; + localparam PRIVKEY_NUM_DWORDS = 1224; + localparam PRIVKEY_REG_NUM_DWORDS = 32; + localparam PRIVKEY_REG_RHO_NUM_DWORDS = 8; + localparam PRIVKEY_MEM_NUM_DWORDS = PRIVKEY_NUM_DWORDS - PRIVKEY_REG_NUM_DWORDS; + localparam SIGN_RND_NUM_DWORDS = 8; + localparam PUBKEY_NUM_DWORDS = 648; + localparam PUBKEY_NUM_BYTES = PUBKEY_NUM_DWORDS * 4; + localparam SIGNATURE_H_NUM_DWORDS = 21; + localparam SIGNATURE_H_VALID_NUM_BYTES = 83; + localparam SIGNATURE_Z_NUM_DWORDS = 1120; + localparam SIGNATURE_C_NUM_DWORDS = 16; + localparam SIGNATURE_NUM_DWORDS = SIGNATURE_H_NUM_DWORDS + SIGNATURE_Z_NUM_DWORDS + SIGNATURE_C_NUM_DWORDS; + localparam SIGNATURE_REG_NUM_DWORDS = SIGNATURE_H_NUM_DWORDS + SIGNATURE_C_NUM_DWORDS; + localparam VERIFY_RES_NUM_DWORDS = 16; + localparam ENTROPY_NUM_DWORDS = 16; + localparam CTX_NUM_DWORDS = 64; + localparam CTX_SIZE_W = $clog2(CTX_NUM_DWORDS*4); + localparam STREAM_MSG_W = 32; + localparam STREAM_MSG_STROBE_W = STREAM_MSG_W/8; + localparam SHAREDKEY_NUM_DWORDS = 8; + localparam EK_NUM_DWORDS = 392; + localparam EK_NUM_BYTES = EK_NUM_DWORDS * 4; + localparam DK_NUM_DWORDS = 792; + localparam DK_NUM_BYTES = DK_NUM_DWORDS * 4; + localparam MLKEM_EK_MEM_NUM_DWORDS = 384; + localparam MLKEM_DK_MEM_NUM_DWORDS = 768; + localparam MLKEM_CIPHERTEXT_MEM_NUM_DWORDS = 392; + localparam CT_NUM_BYTES = MLKEM_CIPHERTEXT_MEM_NUM_DWORDS*4; + localparam MLKEM_MSG_MEM_NUM_DWORDS = 8; + localparam SCRATCH_REG_NUM_DWORDS = 48; + + localparam T1_NUM_COEFF = 2048; + localparam T1_COEFF_W = 10; + + localparam RND_W = 236; //5*46 + 6 + localparam LFSR_W = RND_W / 2; + + localparam SK_MEM_DEPTH = 1192; + localparam SK_MEM_BANK_DEPTH = SK_MEM_DEPTH/2; + localparam SK_MEM_BANK_ADDR_W = $clog2(SK_MEM_BANK_DEPTH); + localparam SK_MEM_BANK_DATA_W = DATA_WIDTH; + + localparam SIG_Z_MEM_DATA_W = 160; + localparam SIG_Z_MEM_NUM_DWORD = SIG_Z_MEM_DATA_W/32; + localparam SIG_Z_MEM_WSTROBE_W = SIG_Z_MEM_DATA_W/8; + localparam SIG_Z_MEM_DEPTH = (SIGNATURE_Z_NUM_DWORDS*32)/SIG_Z_MEM_DATA_W; + localparam SIG_ADDR_W = $clog2(SIGNATURE_NUM_DWORDS); + localparam SIG_Z_MEM_ADDR_W = $clog2(SIG_Z_MEM_DEPTH); + localparam SIG_Z_MEM_OFFSET_W = $clog2(SIG_Z_MEM_DATA_W/32); + localparam SIG_H_REG_ADDR_W = $clog2(SIGNATURE_H_NUM_DWORDS); + localparam SIG_C_REG_ADDR_W = $clog2(SIGNATURE_C_NUM_DWORDS); + + localparam PK_MEM_DEPTH = 64; + localparam PK_MEM_DATA_W = 320; + localparam PK_MEM_NUM_DWORDS = (PK_MEM_DATA_W)/32; + localparam PK_MEM_WSTROBE_W = PK_MEM_DATA_W/8; + localparam PK_ADDR_W = $clog2(PUBKEY_NUM_DWORDS); + localparam PK_MEM_ADDR_W = $clog2(PK_MEM_DEPTH); + localparam PK_MEM_OFFSET_W = $clog2(PK_MEM_DATA_W/32); + localparam PK_RHO_REG_ADDR_W = $clog2(PRIVKEY_REG_RHO_NUM_DWORDS); + + typedef struct packed { + logic [SIGNATURE_H_NUM_DWORDS-1:0][31:0] h; + logic [SIGNATURE_C_NUM_DWORDS-1:0][31:0] c; + } mldsa_signature_t; //37 dwords + + typedef union packed { + mldsa_signature_t enc; + logic [SIGNATURE_REG_NUM_DWORDS-1:0][31:0] raw; + } mldsa_signature_u; + + typedef struct packed { + logic [SIG_Z_MEM_ADDR_W-1:0] addr; + logic [SIG_Z_MEM_OFFSET_W-1:0] offset; + } mldsa_signature_z_addr_t; + + typedef struct packed { + logic [PK_MEM_ADDR_W-1:0] addr; + logic [PK_MEM_OFFSET_W-1:0] offset; + } mldsa_pubkey_mem_addr_t; + + typedef struct packed { + logic [7:0][63:0] rho_p; + logic [7:0][63:0] tr; + logic [3:0][63:0] K; + logic [3:0][63:0] rho; + } mldsa_scratch_reg_t; //48 dwords + + typedef struct packed { + logic [3:0][63:0] rsvd; + logic [7:0][31:0] shared_key; + logic [3:0][63:0] sigma; //cbd input randomness + logic [7:0][31:0] seed_z; + logic [3:0][63:0] tr; //hash of EK + logic [3:0][63:0] rho; + } mlkem_scratch_reg_t; //48 dwords + + typedef union packed { + mlkem_scratch_reg_t mlkem_enc; + mldsa_scratch_reg_t mldsa_enc; + logic [SCRATCH_REG_NUM_DWORDS-1:0][31:0] raw; + } abr_scratch_reg_u; + + //FSM Controller for streaming msg + typedef enum logic [2:0] { + MLDSA_MSG_IDLE, + MLDSA_MSG_CTX_SIZE, + MLDSA_MSG_CTX, + MLDSA_MSG_RDY, + MLDSA_MSG_FLUSH, + MLDSA_MSG_DONE + } mldsa_stream_msg_fsm_state_e; + + //FSM Controller for driving sampler + typedef enum logic [2:0] { + ABR_CTRL_IDLE, + ABR_CTRL_SHA3_START, + ABR_CTRL_MSG_START, + ABR_CTRL_MSG_LOAD, + ABR_CTRL_MSG_WAIT, + ABR_CTRL_FUNC_START, + ABR_CTRL_DONE, + ABR_CTRL_STALLED + } abr_ctrl_fsm_state_e; + + typedef enum logic[4:0] { + ABR_NTT_NONE, + MLDSA_NTT, + MLDSA_INTT, + MLDSA_PWM, + MLDSA_PWM_ACCUM, + MLDSA_PWM_SMPL, + MLDSA_PWM_ACCUM_SMPL, + MLDSA_PWA, + MLDSA_PWS, + MLDSA_PWM_INTT, + MLKEM_NTT, + MLKEM_INTT, + MLKEM_PWM, + MLKEM_PWM_ACCUM, + MLKEM_PWM_SMPL, + MLKEM_PWM_ACCUM_SMPL, + MLKEM_PWA, + MLKEM_PWS, + MLKEM_PWM_INTT + } abr_ntt_mode_e; + + typedef enum logic[4:0] { + ABR_AUX_NONE, + MLDSA_SKDECODE, + MLDSA_SKENCODE, + MLDSA_PKDECODE, + MLDSA_MAKEHINT, + MLDSA_USEHINT, + MLDSA_NORMCHK, + MLDSA_PWR2RND, + MLDSA_SIGENC, + MLDSA_SIGDEC_H, + MLDSA_SIGDEC_Z, + MLDSA_HINTSUM, + MLDSA_DECOMP, + MLDSA_LFSR, + MLKEM_COMPRESS, + MLKEM_DECOMPRESS + } abr_aux_mode_e; + + typedef union packed { + abr_sampler_mode_e sampler_mode; + abr_aux_mode_e aux_mode; + abr_ntt_mode_e ntt_mode; + } abr_opcode_mode_u; + + typedef struct packed { + logic keccak_en; + logic sampler_en; + logic ntt_en; + logic aux_en; + abr_opcode_mode_u mode; + logic masking_en; + logic shuffling_en; + } abr_opcode_t; + + typedef struct packed { + abr_opcode_t opcode; + logic [ABR_IMM_WIDTH-1 : 0] imm; + logic [ABR_OPR_WIDTH-1 : 0] length; + logic [ABR_OPR_WIDTH-1 : 0] operand1; + logic [ABR_OPR_WIDTH-1 : 0] operand2; + logic [ABR_OPR_WIDTH-1 : 0] operand3; + } abr_seq_instr_t; + + // MLDSA ISA + localparam abr_opcode_t ABR_UOP_NOP = '{keccak_en: 1'b0, sampler_en:1'b0, ntt_en:1'b0, aux_en: 1'b0, mode:ABR_SAMPLER_NONE, masking_en:1'b0, shuffling_en:1'b0}; + localparam abr_opcode_t ABR_UOP_SHAKE256 = '{keccak_en: 1'b1, sampler_en:1'b1, ntt_en:1'b0, aux_en: 1'b0, mode:ABR_SHAKE256, masking_en:1'b0, shuffling_en:1'b0}; + localparam abr_opcode_t ABR_UOP_SHAKE128 = '{keccak_en: 1'b1, sampler_en:1'b1, ntt_en:1'b0, aux_en: 1'b0, mode:ABR_SHAKE128, masking_en:1'b0, shuffling_en:1'b0}; + localparam abr_opcode_t ABR_UOP_REJB = '{keccak_en: 1'b1, sampler_en:1'b1, ntt_en:1'b0, aux_en: 1'b0, mode:ABR_REJ_BOUNDED, masking_en:1'b0, shuffling_en:1'b0}; + localparam abr_opcode_t ABR_UOP_REJS_PWM = '{keccak_en: 1'b1, sampler_en:1'b1, ntt_en:1'b1, aux_en: 1'b0, mode:MLDSA_PWM_SMPL, masking_en:1'b0, shuffling_en:1'b0}; + localparam abr_opcode_t ABR_UOP_REJS_PWMA = '{keccak_en: 1'b1, sampler_en:1'b1, ntt_en:1'b1, aux_en: 1'b0, mode:MLDSA_PWM_ACCUM_SMPL, masking_en:1'b0, shuffling_en:1'b0}; + localparam abr_opcode_t ABR_UOP_REJS_MASKED_PWM = '{keccak_en: 1'b1, sampler_en:1'b1, ntt_en:1'b1, aux_en: 1'b0, mode:MLDSA_PWM_SMPL, masking_en:1'b1, shuffling_en:1'b0}; + localparam abr_opcode_t ABR_UOP_REJS_MASKED_PWMA = '{keccak_en: 1'b1, sampler_en:1'b1, ntt_en:1'b1, aux_en: 1'b0, mode:MLDSA_PWM_ACCUM_SMPL, masking_en:1'b1, shuffling_en:1'b0}; + localparam abr_opcode_t ABR_UOP_SIB = '{keccak_en: 1'b1, sampler_en:1'b1, ntt_en:1'b0, aux_en: 1'b0, mode:ABR_SAMPLE_IN_BALL, masking_en:1'b0, shuffling_en:1'b0}; + localparam abr_opcode_t ABR_UOP_EXP_MASK = '{keccak_en: 1'b1, sampler_en:1'b1, ntt_en:1'b0, aux_en: 1'b0, mode:ABR_EXP_MASK, masking_en:1'b0, shuffling_en:1'b0}; + localparam abr_opcode_t ABR_UOP_NTT = '{keccak_en: 1'b0, sampler_en:1'b0, ntt_en:1'b1, aux_en: 1'b0, mode:MLDSA_NTT, masking_en:1'b0, shuffling_en:1'b1}; + localparam abr_opcode_t ABR_UOP_INTT = '{keccak_en: 1'b0, sampler_en:1'b0, ntt_en:1'b1, aux_en: 1'b0, mode:MLDSA_INTT, masking_en:1'b0, shuffling_en:1'b1}; + localparam abr_opcode_t ABR_UOP_PWM = '{keccak_en: 1'b0, sampler_en:1'b0, ntt_en:1'b1, aux_en: 1'b0, mode:MLDSA_PWM, masking_en:1'b0, shuffling_en:1'b1}; + localparam abr_opcode_t ABR_UOP_PWA = '{keccak_en: 1'b0, sampler_en:1'b0, ntt_en:1'b1, aux_en: 1'b0, mode:MLDSA_PWA, masking_en:1'b0, shuffling_en:1'b1}; + localparam abr_opcode_t ABR_UOP_PWS = '{keccak_en: 1'b0, sampler_en:1'b0, ntt_en:1'b1, aux_en: 1'b0, mode:MLDSA_PWS, masking_en:1'b0, shuffling_en:1'b1}; + localparam abr_opcode_t ABR_UOP_MASKED_NTT = '{keccak_en: 1'b0, sampler_en:1'b0, ntt_en:1'b1, aux_en: 1'b0, mode:MLDSA_NTT, masking_en:1'b1, shuffling_en:1'b1}; + localparam abr_opcode_t ABR_UOP_MASKED_INTT = '{keccak_en: 1'b0, sampler_en:1'b0, ntt_en:1'b1, aux_en: 1'b0, mode:MLDSA_INTT, masking_en:1'b1, shuffling_en:1'b1}; + localparam abr_opcode_t ABR_UOP_MASKED_PWM = '{keccak_en: 1'b0, sampler_en:1'b0, ntt_en:1'b1, aux_en: 1'b0, mode:MLDSA_PWM, masking_en:1'b1, shuffling_en:1'b1}; //TODO: if shuffling_en can be kept 1 always, we don't need sampler_mode input to ntt. Else, we need to distinguish between sampelr and non-sampler PWM with masking and no shuffling (since input delay balancing is diff for both these cases) + localparam abr_opcode_t ABR_UOP_MASKED_PWA = '{keccak_en: 1'b0, sampler_en:1'b0, ntt_en:1'b1, aux_en: 1'b0, mode:MLDSA_PWA, masking_en:1'b1, shuffling_en:1'b1}; + localparam abr_opcode_t ABR_UOP_MASKED_PWS = '{keccak_en: 1'b0, sampler_en:1'b0, ntt_en:1'b1, aux_en: 1'b0, mode:MLDSA_PWS, masking_en:1'b1, shuffling_en:1'b1}; + // MLKEM ISA + localparam abr_opcode_t ABR_UOP_SHA512 = '{keccak_en: 1'b1, sampler_en:1'b1, ntt_en:1'b0, aux_en: 1'b0, mode:ABR_SHA512, masking_en:1'b0, shuffling_en:1'b0}; + localparam abr_opcode_t ABR_UOP_SHA256 = '{keccak_en: 1'b1, sampler_en:1'b1, ntt_en:1'b0, aux_en: 1'b0, mode:ABR_SHA256, masking_en:1'b0, shuffling_en:1'b0}; + localparam abr_opcode_t ABR_UOP_CBD = '{keccak_en: 1'b1, sampler_en:1'b1, ntt_en:1'b0, aux_en: 1'b0, mode:ABR_CBD_SAMPLER, masking_en:1'b0, shuffling_en:1'b0}; + localparam abr_opcode_t ABR_UOP_MLKEM_REJS_PWM = '{keccak_en: 1'b1, sampler_en:1'b1, ntt_en:1'b1, aux_en: 1'b0, mode:MLKEM_PWM_SMPL, masking_en:1'b0, shuffling_en:1'b0}; + localparam abr_opcode_t ABR_UOP_MLKEM_REJS_PWMA = '{keccak_en: 1'b1, sampler_en:1'b1, ntt_en:1'b1, aux_en: 1'b0, mode:MLKEM_PWM_ACCUM_SMPL, masking_en:1'b0, shuffling_en:1'b0}; + localparam abr_opcode_t ABR_UOP_MLKEM_MASKED_REJS_PWM = '{keccak_en: 1'b1, sampler_en:1'b1, ntt_en:1'b1, aux_en: 1'b0, mode:MLKEM_PWM_SMPL, masking_en:1'b1, shuffling_en:1'b0}; + localparam abr_opcode_t ABR_UOP_MLKEM_MASKED_REJS_PWMA = '{keccak_en: 1'b1, sampler_en:1'b1, ntt_en:1'b1, aux_en: 1'b0, mode:MLKEM_PWM_ACCUM_SMPL, masking_en:1'b1, shuffling_en:1'b0}; + localparam abr_opcode_t ABR_UOP_MLKEM_NTT = '{keccak_en: 1'b0, sampler_en:1'b0, ntt_en:1'b1, aux_en: 1'b0, mode:MLKEM_NTT, masking_en:1'b0, shuffling_en:1'b1}; + localparam abr_opcode_t ABR_UOP_MLKEM_INTT = '{keccak_en: 1'b0, sampler_en:1'b0, ntt_en:1'b1, aux_en: 1'b0, mode:MLKEM_INTT, masking_en:1'b0, shuffling_en:1'b1}; + localparam abr_opcode_t ABR_UOP_MLKEM_MASKED_INTT = '{keccak_en: 1'b0, sampler_en:1'b0, ntt_en:1'b1, aux_en: 1'b0, mode:MLKEM_INTT, masking_en:1'b1, shuffling_en:1'b1}; + localparam abr_opcode_t ABR_UOP_MLKEM_PWA = '{keccak_en: 1'b0, sampler_en:1'b0, ntt_en:1'b1, aux_en: 1'b0, mode:MLKEM_PWA, masking_en:1'b0, shuffling_en:1'b1}; + localparam abr_opcode_t ABR_UOP_MLKEM_PWM = '{keccak_en: 1'b0, sampler_en:1'b0, ntt_en:1'b1, aux_en: 1'b0, mode:MLKEM_PWM, masking_en:1'b0, shuffling_en:1'b1}; + localparam abr_opcode_t ABR_UOP_MLKEM_PWMA = '{keccak_en: 1'b0, sampler_en:1'b0, ntt_en:1'b1, aux_en: 1'b0, mode:MLKEM_PWM_ACCUM, masking_en:1'b0, shuffling_en:1'b1}; + localparam abr_opcode_t ABR_UOP_MLKEM_MASKED_PWM = '{keccak_en: 1'b0, sampler_en:1'b0, ntt_en:1'b1, aux_en: 1'b0, mode:MLKEM_PWM, masking_en:1'b1, shuffling_en:1'b1}; + localparam abr_opcode_t ABR_UOP_MLKEM_MASKED_PWMA = '{keccak_en: 1'b0, sampler_en:1'b0, ntt_en:1'b1, aux_en: 1'b0, mode:MLKEM_PWM_ACCUM, masking_en:1'b1, shuffling_en:1'b1}; + localparam abr_opcode_t ABR_UOP_MLKEM_PWS = '{keccak_en: 1'b0, sampler_en:1'b0, ntt_en:1'b1, aux_en: 1'b0, mode:MLKEM_PWS, masking_en:1'b0, shuffling_en:1'b1}; + + //Load Keccak with data but don't run it yet + localparam abr_opcode_t ABR_UOP_LD_SHAKE256 = '{keccak_en: 1'b1, sampler_en:1'b0, ntt_en:1'b0, aux_en: 1'b0, mode:ABR_SHAKE256, masking_en:1'b0, shuffling_en:1'b0}; + localparam abr_opcode_t ABR_UOP_LD_SHAKE128 = '{keccak_en: 1'b1, sampler_en:1'b0, ntt_en:1'b0, aux_en: 1'b0, mode:ABR_SHAKE128, masking_en:1'b0, shuffling_en:1'b0}; + localparam abr_opcode_t ABR_UOP_LD_SHA512 = '{keccak_en: 1'b1, sampler_en:1'b0, ntt_en:1'b0, aux_en: 1'b0, mode:ABR_SHA512, masking_en:1'b0, shuffling_en:1'b0}; + localparam abr_opcode_t ABR_UOP_LD_SHA256 = '{keccak_en: 1'b1, sampler_en:1'b0, ntt_en:1'b0, aux_en: 1'b0, mode:ABR_SHA256, masking_en:1'b0, shuffling_en:1'b0}; + //Run Keccak but don't load it + localparam abr_opcode_t ABR_UOP_RUN_SHAKE256 = '{keccak_en: 1'b0, sampler_en:1'b1, ntt_en:1'b0, aux_en: 1'b0, mode:ABR_SHAKE256, masking_en:1'b0, shuffling_en:1'b0}; + localparam abr_opcode_t ABR_UOP_RUN_SHAKE128 = '{keccak_en: 1'b0, sampler_en:1'b1, ntt_en:1'b0, aux_en: 1'b0, mode:ABR_SHAKE128, masking_en:1'b0, shuffling_en:1'b0}; + localparam abr_opcode_t ABR_UOP_RUN_SHA512 = '{keccak_en: 1'b0, sampler_en:1'b1, ntt_en:1'b0, aux_en: 1'b0, mode:ABR_SHA512, masking_en:1'b0, shuffling_en:1'b0}; + localparam abr_opcode_t ABR_UOP_RUN_SHA256 = '{keccak_en: 1'b0, sampler_en:1'b1, ntt_en:1'b0, aux_en: 1'b0, mode:ABR_SHA256, masking_en:1'b0, shuffling_en:1'b0}; + // Aux functions + localparam abr_opcode_t ABR_UOP_DECOMPOSE = '{keccak_en: 1'b0, sampler_en:1'b0, ntt_en:1'b0, aux_en: 1'b1, mode:MLDSA_DECOMP, masking_en:1'b0, shuffling_en:1'b0}; + localparam abr_opcode_t ABR_UOP_SKDECODE = '{keccak_en: 1'b0, sampler_en:1'b0, ntt_en:1'b0, aux_en: 1'b1, mode:MLDSA_SKDECODE, masking_en:1'b0, shuffling_en:1'b0}; + localparam abr_opcode_t ABR_UOP_SKENCODE = '{keccak_en: 1'b0, sampler_en:1'b0, ntt_en:1'b0, aux_en: 1'b1, mode:MLDSA_SKENCODE, masking_en:1'b0, shuffling_en:1'b0}; + localparam abr_opcode_t ABR_UOP_MAKEHINT = '{keccak_en: 1'b0, sampler_en:1'b0, ntt_en:1'b0, aux_en: 1'b1, mode:MLDSA_MAKEHINT, masking_en:1'b0, shuffling_en:1'b0}; + localparam abr_opcode_t ABR_UOP_NORMCHK = '{keccak_en: 1'b0, sampler_en:1'b0, ntt_en:1'b0, aux_en: 1'b1, mode:MLDSA_NORMCHK, masking_en:1'b0, shuffling_en:1'b0}; + localparam abr_opcode_t ABR_UOP_SIGENCODE = '{keccak_en: 1'b0, sampler_en:1'b0, ntt_en:1'b0, aux_en: 1'b1, mode:MLDSA_SIGENC, masking_en:1'b0, shuffling_en:1'b0}; + localparam abr_opcode_t ABR_UOP_PKDECODE = '{keccak_en: 1'b0, sampler_en:1'b0, ntt_en:1'b0, aux_en: 1'b1, mode:MLDSA_PKDECODE, masking_en:1'b0, shuffling_en:1'b0}; + localparam abr_opcode_t ABR_UOP_SIGDEC_H = '{keccak_en: 1'b0, sampler_en:1'b0, ntt_en:1'b0, aux_en: 1'b1, mode:MLDSA_SIGDEC_H, masking_en:1'b0, shuffling_en:1'b0}; + localparam abr_opcode_t ABR_UOP_SIGDEC_Z = '{keccak_en: 1'b0, sampler_en:1'b0, ntt_en:1'b0, aux_en: 1'b1, mode:MLDSA_SIGDEC_Z, masking_en:1'b0, shuffling_en:1'b0}; + localparam abr_opcode_t ABR_UOP_HINTSUM = '{keccak_en: 1'b0, sampler_en:1'b0, ntt_en:1'b0, aux_en: 1'b1, mode:MLDSA_HINTSUM, masking_en:1'b0, shuffling_en:1'b0}; + localparam abr_opcode_t ABR_UOP_USEHINT = '{keccak_en: 1'b0, sampler_en:1'b0, ntt_en:1'b0, aux_en: 1'b1, mode:MLDSA_USEHINT, masking_en:1'b0, shuffling_en:1'b0}; + localparam abr_opcode_t ABR_UOP_PWR2RND = '{keccak_en: 1'b0, sampler_en:1'b0, ntt_en:1'b0, aux_en: 1'b1, mode:MLDSA_PWR2RND, masking_en:1'b0, shuffling_en:1'b0}; + localparam abr_opcode_t ABR_UOP_LFSR = '{keccak_en: 1'b0, sampler_en:1'b0, ntt_en:1'b0, aux_en: 1'b1, mode:MLDSA_LFSR, masking_en:1'b0, shuffling_en:1'b0}; + localparam abr_opcode_t ABR_UOP_COMPRESS = '{keccak_en: 1'b0, sampler_en:1'b0, ntt_en:1'b0, aux_en: 1'b1, mode:MLKEM_COMPRESS, masking_en:1'b0, shuffling_en:1'b0}; + localparam abr_opcode_t ABR_UOP_DECOMPRESS = '{keccak_en: 1'b0, sampler_en:1'b0, ntt_en:1'b0, aux_en: 1'b1, mode:MLKEM_DECOMPRESS, masking_en:1'b0, shuffling_en:1'b0}; + + //Immediate encodings + localparam [ABR_IMM_WIDTH-1:0] MLDSA_NORMCHK_Z = 'h0000; + localparam [ABR_IMM_WIDTH-1:0] MLDSA_NORMCHK_R0 = 'h0001; + localparam [ABR_IMM_WIDTH-1:0] MLDSA_NORMCHK_CT0 = 'h0002; + + // MLDSA REGISTERS ID listing + localparam [ABR_OPR_WIDTH-1 : 0] ABR_NOP = 'd0; + localparam [ABR_OPR_WIDTH-1 : 0] MLKEM_NOP = 'd0; + + // DEST register IDs + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_DEST_K_RHO_REG_ID = 'd2; + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_DEST_MU_REG_ID = 'd3; + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_DEST_RHO_P_REG_ID = 'd4; + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_DEST_SIG_C_REG_ID = 'd5; + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_DEST_TR_REG_ID = 'd6; + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_DEST_VERIFY_RES_REG_ID = 'd7; + localparam [ABR_OPR_WIDTH-1 : 0] ABR_DEST_LFSR_SEED_REG_ID = 'd8; + localparam [ABR_OPR_WIDTH-1 : 0] MLKEM_DEST_RHO_SIGMA_REG_ID = 'd9; + localparam [ABR_OPR_WIDTH-1 : 0] MLKEM_DEST_TR_REG_ID = 'd10; + localparam [ABR_OPR_WIDTH-1 : 0] MLKEM_DEST_K_R_REG_ID = 'd11; + localparam [ABR_OPR_WIDTH-1 : 0] MLKEM_DEST_K_REG_ID = 'd12; + // DEST Mem overloaded into SK ram + localparam [ABR_OPR_WIDTH-1 : 0] MLKEM_DEST_DK_MEM_OFFSET = 'd0; + localparam [ABR_OPR_WIDTH-1 : 0] MLKEM_SRC_DK_MEM_OFFSET = MLKEM_DEST_DK_MEM_OFFSET/2; + localparam [ABR_OPR_WIDTH-1 : 0] MLKEM_DEST_EK_MEM_OFFSET = 'd384; + localparam [ABR_OPR_WIDTH-1 : 0] MLKEM_SRC_EK_MEM_OFFSET = MLKEM_DEST_EK_MEM_OFFSET/2; + localparam [ABR_OPR_WIDTH-1 : 0] MLKEM_DEST_C1_MEM_OFFSET = 'd768; + localparam [ABR_OPR_WIDTH-1 : 0] MLKEM_SRC_C1_MEM_OFFSET = MLKEM_DEST_C1_MEM_OFFSET/2; + localparam [ABR_OPR_WIDTH-1 : 0] MLKEM_DEST_C2_MEM_OFFSET = 'd1120; + localparam [ABR_OPR_WIDTH-1 : 0] MLKEM_SRC_C2_MEM_OFFSET = MLKEM_DEST_C2_MEM_OFFSET/2; + localparam [ABR_OPR_WIDTH-1 : 0] MLKEM_DEST_MSG_MEM_OFFSET = 'd1160; + localparam [ABR_OPR_WIDTH-1 : 0] MLKEM_SRC_MSG_MEM_OFFSET = MLKEM_DEST_MSG_MEM_OFFSET/2; + + //SRC register IDs + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_MSG_ID = 'd15; + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_SEED_ID = 'd16; + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_SIGN_RND_ID = 'd17; + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_K_ID = 'd18; + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_RHO_ID = 'd19; + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_RHO_P_ID = 'd20; + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_MU_ID = 'd21; + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_TR_ID = 'd22; + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_RHO_P_KAPPA_ID = 'd23; + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_SIG_C_REG_ID = 'd24; + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_PK_REG_ID = 'd25; + localparam [ABR_OPR_WIDTH-1 : 0] ABR_ENTROPY_ID = 'd26; + localparam [ABR_OPR_WIDTH-1 : 0] ABR_CNT_ID = 'd27; + localparam [ABR_OPR_WIDTH-1 : 0] MLKEM_SEED_D_ID = 'd28; + localparam [ABR_OPR_WIDTH-1 : 0] MLKEM_RHO_ID = 'd29; + localparam [ABR_OPR_WIDTH-1 : 0] MLKEM_SIGMA_ID = 'd30; + localparam [ABR_OPR_WIDTH-1 : 0] MLKEM_EK_REG_ID = 'd31; + localparam [ABR_OPR_WIDTH-1 : 0] MLKEM_TR_ID = 'd32; + localparam [ABR_OPR_WIDTH-1 : 0] MLKEM_MSG_ID = 'd33; + localparam [ABR_OPR_WIDTH-1 : 0] MLKEM_R_ID = 'd34; + localparam [ABR_OPR_WIDTH-1 : 0] MLKEM_SEED_Z_ID = 'd35; + localparam [ABR_OPR_WIDTH-1 : 0] MLKEM_CIPHERTEXT_ID = 'd36; + + //SK offsets in dwords + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_SK_S1_OFFSET = 'd32; + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_SK_T0_OFFSET = 'd360; + + // MLDSA MEMORY LOCATIONS + //COEFF DEPTH is 256/4 + localparam MLDSA_COEFF_DEPTH = MLDSA_N/COEFF_PER_CLK; + localparam MLKEM_COEFF_DEPTH = MLKEM_N/COEFF_PER_CLK; + //MEMORY INST 0 + localparam [ABR_OPR_WIDTH-1 : 0] ABR_INST0_BASE = 0 << (ABR_MEM_ADDR_WIDTH-3); + //S1 / NTT(S1) + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_S1_0_BASE = ABR_INST0_BASE; + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_S1_1_BASE = MLDSA_S1_0_BASE + MLDSA_COEFF_DEPTH; + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_S1_2_BASE = MLDSA_S1_1_BASE + MLDSA_COEFF_DEPTH; + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_S1_3_BASE = MLDSA_S1_2_BASE + MLDSA_COEFF_DEPTH; + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_S1_4_BASE = MLDSA_S1_3_BASE + MLDSA_COEFF_DEPTH; + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_S1_5_BASE = MLDSA_S1_4_BASE + MLDSA_COEFF_DEPTH; + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_S1_6_BASE = MLDSA_S1_5_BASE + MLDSA_COEFF_DEPTH; + // z for VERIFY + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_Z_0_BASE = ABR_INST0_BASE; + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_Z_1_BASE = MLDSA_Z_0_BASE + MLDSA_COEFF_DEPTH; + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_Z_2_BASE = MLDSA_Z_1_BASE + MLDSA_COEFF_DEPTH; + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_Z_3_BASE = MLDSA_Z_2_BASE + MLDSA_COEFF_DEPTH; + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_Z_4_BASE = MLDSA_Z_3_BASE + MLDSA_COEFF_DEPTH; + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_Z_5_BASE = MLDSA_Z_4_BASE + MLDSA_COEFF_DEPTH; + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_Z_6_BASE = MLDSA_Z_5_BASE + MLDSA_COEFF_DEPTH; + // z NTT for VERIFY + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_Z_NTT_0_BASE = ABR_INST0_BASE; + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_Z_NTT_1_BASE = MLDSA_Z_NTT_0_BASE + MLDSA_COEFF_DEPTH; + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_Z_NTT_2_BASE = MLDSA_Z_NTT_1_BASE + MLDSA_COEFF_DEPTH; + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_Z_NTT_3_BASE = MLDSA_Z_NTT_2_BASE + MLDSA_COEFF_DEPTH; + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_Z_NTT_4_BASE = MLDSA_Z_NTT_3_BASE + MLDSA_COEFF_DEPTH; + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_Z_NTT_5_BASE = MLDSA_Z_NTT_4_BASE + MLDSA_COEFF_DEPTH; + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_Z_NTT_6_BASE = MLDSA_Z_NTT_5_BASE + MLDSA_COEFF_DEPTH; + //s2 / NTT(s2) + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_S2_0_BASE = MLDSA_S1_6_BASE + MLDSA_COEFF_DEPTH; + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_S2_1_BASE = MLDSA_S2_0_BASE + MLDSA_COEFF_DEPTH; + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_S2_2_BASE = MLDSA_S2_1_BASE + MLDSA_COEFF_DEPTH; + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_S2_3_BASE = MLDSA_S2_2_BASE + MLDSA_COEFF_DEPTH; + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_S2_4_BASE = MLDSA_S2_3_BASE + MLDSA_COEFF_DEPTH; + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_S2_5_BASE = MLDSA_S2_4_BASE + MLDSA_COEFF_DEPTH; + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_S2_6_BASE = MLDSA_S2_5_BASE + MLDSA_COEFF_DEPTH; + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_S2_7_BASE = MLDSA_S2_6_BASE + MLDSA_COEFF_DEPTH; + //t0 / NTT(t0) t1 / NTT(t1) + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_T0_BASE = MLDSA_S2_7_BASE + MLDSA_COEFF_DEPTH; + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_T1_BASE = MLDSA_T0_BASE + MLDSA_COEFF_DEPTH; + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_T2_BASE = MLDSA_T1_BASE + MLDSA_COEFF_DEPTH; + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_T3_BASE = MLDSA_T2_BASE + MLDSA_COEFF_DEPTH; + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_T4_BASE = MLDSA_T3_BASE + MLDSA_COEFF_DEPTH; + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_T5_BASE = MLDSA_T4_BASE + MLDSA_COEFF_DEPTH; + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_T6_BASE = MLDSA_T5_BASE + MLDSA_COEFF_DEPTH; + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_T7_BASE = MLDSA_T6_BASE + MLDSA_COEFF_DEPTH; + //c.s1 + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_CS1_BASE = MLDSA_T7_BASE + MLDSA_COEFF_DEPTH; + // z + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_Z_BASE = MLDSA_T7_BASE + MLDSA_COEFF_DEPTH; + // CT for VERIFY + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_CT_BASE = MLDSA_T7_BASE + MLDSA_COEFF_DEPTH; + //c.s2 + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_CS2_BASE = MLDSA_CS1_BASE + MLDSA_COEFF_DEPTH; + // R0 + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_R0_BASE = MLDSA_CS1_BASE + MLDSA_COEFF_DEPTH; + //TEMP storage for NTT ops + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_TEMP0_BASE = MLDSA_CS2_BASE + MLDSA_COEFF_DEPTH; + //MLKEM KeyGen S/E/T memory locations + localparam [ABR_OPR_WIDTH-1 : 0] MLKEM_S0_BASE = ABR_INST0_BASE; + localparam [ABR_OPR_WIDTH-1 : 0] MLKEM_S1_BASE = MLKEM_S0_BASE + MLKEM_COEFF_DEPTH; + localparam [ABR_OPR_WIDTH-1 : 0] MLKEM_S2_BASE = MLKEM_S1_BASE + MLKEM_COEFF_DEPTH; + localparam [ABR_OPR_WIDTH-1 : 0] MLKEM_S3_BASE = MLKEM_S2_BASE + MLKEM_COEFF_DEPTH; + localparam [ABR_OPR_WIDTH-1 : 0] MLKEM_T0_BASE = MLKEM_S3_BASE + MLKEM_COEFF_DEPTH; + localparam [ABR_OPR_WIDTH-1 : 0] MLKEM_T1_BASE = MLKEM_T0_BASE + MLKEM_COEFF_DEPTH; + localparam [ABR_OPR_WIDTH-1 : 0] MLKEM_T2_BASE = MLKEM_T1_BASE + MLKEM_COEFF_DEPTH; + localparam [ABR_OPR_WIDTH-1 : 0] MLKEM_T3_BASE = MLKEM_T2_BASE + MLKEM_COEFF_DEPTH; + localparam [ABR_OPR_WIDTH-1 : 0] MLKEM_E0_BASE = MLKEM_T3_BASE + MLKEM_COEFF_DEPTH; + localparam [ABR_OPR_WIDTH-1 : 0] MLKEM_E1_BASE = MLKEM_E0_BASE + MLKEM_COEFF_DEPTH; + localparam [ABR_OPR_WIDTH-1 : 0] MLKEM_E2_BASE = MLKEM_E1_BASE + MLKEM_COEFF_DEPTH; + localparam [ABR_OPR_WIDTH-1 : 0] MLKEM_E3_BASE = MLKEM_E2_BASE + MLKEM_COEFF_DEPTH; + localparam [ABR_OPR_WIDTH-1 : 0] MLKEM_MU_BASE = MLKEM_E3_BASE + MLKEM_COEFF_DEPTH; + localparam [ABR_OPR_WIDTH-1 : 0] MLKEM_U0_BASE = MLKEM_MU_BASE + MLKEM_COEFF_DEPTH; + localparam [ABR_OPR_WIDTH-1 : 0] MLKEM_U1_BASE = MLKEM_U0_BASE + MLKEM_COEFF_DEPTH; + localparam [ABR_OPR_WIDTH-1 : 0] MLKEM_U2_BASE = MLKEM_U1_BASE + MLKEM_COEFF_DEPTH; + localparam [ABR_OPR_WIDTH-1 : 0] MLKEM_U3_BASE = MLKEM_U2_BASE + MLKEM_COEFF_DEPTH; + localparam [ABR_OPR_WIDTH-1 : 0] MLKEM_V_BASE = MLKEM_U3_BASE + MLKEM_COEFF_DEPTH; + + //MEMORY INST 1 + localparam [ABR_OPR_WIDTH-1 : 0] ABR_INST1_BASE = 1 << (ABR_MEM_ADDR_WIDTH-3); + // NTT(C) + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_C_NTT_BASE = ABR_INST1_BASE; + // NTT(s1) for KEYGEN + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_S1_0_NTT_BASE = MLDSA_C_NTT_BASE + MLDSA_COEFF_DEPTH; + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_S1_1_NTT_BASE = MLDSA_S1_0_NTT_BASE + MLDSA_COEFF_DEPTH; + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_S1_2_NTT_BASE = MLDSA_S1_1_NTT_BASE + MLDSA_COEFF_DEPTH; + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_S1_3_NTT_BASE = MLDSA_S1_2_NTT_BASE + MLDSA_COEFF_DEPTH; + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_S1_4_NTT_BASE = MLDSA_S1_3_NTT_BASE + MLDSA_COEFF_DEPTH; + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_S1_5_NTT_BASE = MLDSA_S1_4_NTT_BASE + MLDSA_COEFF_DEPTH; + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_S1_6_NTT_BASE = MLDSA_S1_5_NTT_BASE + MLDSA_COEFF_DEPTH; + // c.t0 for SIGNING + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_CT_0_BASE = MLDSA_C_NTT_BASE + MLDSA_COEFF_DEPTH; + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_CT_1_BASE = MLDSA_CT_0_BASE + MLDSA_COEFF_DEPTH; + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_CT_2_BASE = MLDSA_CT_1_BASE + MLDSA_COEFF_DEPTH; + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_CT_3_BASE = MLDSA_CT_2_BASE + MLDSA_COEFF_DEPTH; + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_CT_4_BASE = MLDSA_CT_3_BASE + MLDSA_COEFF_DEPTH; + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_CT_5_BASE = MLDSA_CT_4_BASE + MLDSA_COEFF_DEPTH; + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_CT_6_BASE = MLDSA_CT_5_BASE + MLDSA_COEFF_DEPTH; + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_CT_7_BASE = MLDSA_CT_6_BASE + MLDSA_COEFF_DEPTH; + //hint_r + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_HINT_R_0_BASE = MLDSA_C_NTT_BASE + MLDSA_COEFF_DEPTH; + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_HINT_R_1_BASE = MLDSA_HINT_R_0_BASE + MLDSA_COEFF_DEPTH; + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_HINT_R_2_BASE = MLDSA_HINT_R_1_BASE + MLDSA_COEFF_DEPTH; + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_HINT_R_3_BASE = MLDSA_HINT_R_2_BASE + MLDSA_COEFF_DEPTH; + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_HINT_R_4_BASE = MLDSA_HINT_R_3_BASE + MLDSA_COEFF_DEPTH; + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_HINT_R_5_BASE = MLDSA_HINT_R_4_BASE + MLDSA_COEFF_DEPTH; + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_HINT_R_6_BASE = MLDSA_HINT_R_5_BASE + MLDSA_COEFF_DEPTH; + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_HINT_R_7_BASE = MLDSA_HINT_R_6_BASE + MLDSA_COEFF_DEPTH; + //ML-KEM + localparam [ABR_OPR_WIDTH-1 : 0] MLKEM_Y0_BASE = ABR_INST1_BASE; + localparam [ABR_OPR_WIDTH-1 : 0] MLKEM_Y1_BASE = MLKEM_Y0_BASE + MLKEM_COEFF_DEPTH; + localparam [ABR_OPR_WIDTH-1 : 0] MLKEM_Y2_BASE = MLKEM_Y1_BASE + MLKEM_COEFF_DEPTH; + localparam [ABR_OPR_WIDTH-1 : 0] MLKEM_Y3_BASE = MLKEM_Y2_BASE + MLKEM_COEFF_DEPTH; + localparam [ABR_OPR_WIDTH-1 : 0] MLKEM_E_2_BASE = MLKEM_Y3_BASE + MLKEM_COEFF_DEPTH; + localparam [ABR_OPR_WIDTH-1 : 0] MLKEM_UP0_BASE = ABR_INST1_BASE; + localparam [ABR_OPR_WIDTH-1 : 0] MLKEM_UP1_BASE = MLKEM_UP0_BASE + MLKEM_COEFF_DEPTH; + localparam [ABR_OPR_WIDTH-1 : 0] MLKEM_UP2_BASE = MLKEM_UP1_BASE + MLKEM_COEFF_DEPTH; + localparam [ABR_OPR_WIDTH-1 : 0] MLKEM_UP3_BASE = MLKEM_UP2_BASE + MLKEM_COEFF_DEPTH; + + //MEMORY INST 2 + localparam [ABR_OPR_WIDTH-1 : 0] ABR_INST2_BASE = 2 << (ABR_MEM_ADDR_WIDTH-3); + //Y + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_Y_0_BASE = ABR_INST2_BASE; + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_Y_1_BASE = MLDSA_Y_0_BASE + MLDSA_COEFF_DEPTH; + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_Y_2_BASE = MLDSA_Y_1_BASE + MLDSA_COEFF_DEPTH; + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_Y_3_BASE = MLDSA_Y_2_BASE + MLDSA_COEFF_DEPTH; + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_Y_4_BASE = MLDSA_Y_3_BASE + MLDSA_COEFF_DEPTH; + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_Y_5_BASE = MLDSA_Y_4_BASE + MLDSA_COEFF_DEPTH; + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_Y_6_BASE = MLDSA_Y_5_BASE + MLDSA_COEFF_DEPTH; + //NTT(Y) + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_Y_0_NTT_BASE = MLDSA_Y_6_BASE + MLDSA_COEFF_DEPTH; + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_Y_1_NTT_BASE = MLDSA_Y_0_NTT_BASE + MLDSA_COEFF_DEPTH; + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_Y_2_NTT_BASE = MLDSA_Y_1_NTT_BASE + MLDSA_COEFF_DEPTH; + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_Y_3_NTT_BASE = MLDSA_Y_2_NTT_BASE + MLDSA_COEFF_DEPTH; + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_Y_4_NTT_BASE = MLDSA_Y_3_NTT_BASE + MLDSA_COEFF_DEPTH; + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_Y_5_NTT_BASE = MLDSA_Y_4_NTT_BASE + MLDSA_COEFF_DEPTH; + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_Y_6_NTT_BASE = MLDSA_Y_5_NTT_BASE + MLDSA_COEFF_DEPTH; + //W0 + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_W0_0_BASE = MLDSA_Y_6_NTT_BASE + MLDSA_COEFF_DEPTH; + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_W0_1_BASE = MLDSA_W0_0_BASE + MLDSA_COEFF_DEPTH; + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_W0_2_BASE = MLDSA_W0_1_BASE + MLDSA_COEFF_DEPTH; + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_W0_3_BASE = MLDSA_W0_2_BASE + MLDSA_COEFF_DEPTH; + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_W0_4_BASE = MLDSA_W0_3_BASE + MLDSA_COEFF_DEPTH; + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_W0_5_BASE = MLDSA_W0_4_BASE + MLDSA_COEFF_DEPTH; + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_W0_6_BASE = MLDSA_W0_5_BASE + MLDSA_COEFF_DEPTH; + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_W0_7_BASE = MLDSA_W0_6_BASE + MLDSA_COEFF_DEPTH; + //ML-KEM + localparam [ABR_OPR_WIDTH-1 : 0] MLKEM_TY_BASE = ABR_INST2_BASE; + localparam [ABR_OPR_WIDTH-1 : 0] MLKEM_SU_BASE = ABR_INST2_BASE; + //TEMP for NTT + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_TEMP2_BASE = MLDSA_W0_7_BASE + MLDSA_COEFF_DEPTH; + + //MEMORY INST 3 - masked storage + localparam [ABR_OPR_WIDTH-1 : 0] ABR_INST3_BASE = 3 << (ABR_MEM_ADDR_WIDTH-3); + + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_AS0_BASE = ABR_INST3_BASE; + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_AS0_INTT_BASE = MLDSA_AS0_BASE; + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_AY0_BASE = ABR_INST3_BASE; + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_AZ0_BASE = ABR_INST3_BASE; + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_CS_NTT_BASE = ABR_INST3_BASE; + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_CT_NTT_BASE = ABR_INST3_BASE; + localparam [ABR_OPR_WIDTH-1 : 0] MLKEM_AS0_BASE = ABR_INST3_BASE; + localparam [ABR_OPR_WIDTH-1 : 0] MLKEM_AY0_BASE = ABR_INST3_BASE; + localparam [ABR_OPR_WIDTH-1 : 0] MLKEM_TY_MASKED_BASE = ABR_INST3_BASE; + localparam [ABR_OPR_WIDTH-1 : 0] MLKEM_SU_MASKED_BASE = ABR_INST3_BASE; + + //SIB MEMORY + localparam [ABR_OPR_WIDTH-1 : 0] ABR_INST4_BASE = 4 << (ABR_MEM_ADDR_WIDTH-3); + //C + localparam [ABR_OPR_WIDTH-1 : 0] MLDSA_C_BASE = ABR_INST4_BASE; + + // MLDSA Subroutine listing + //KG + localparam [ABR_PROG_ADDR_W-1 : 0] ABR_RESET = 'd0; + localparam [ABR_PROG_ADDR_W-1 : 0] ABR_ZEROIZE = ABR_RESET + 1; + localparam [ABR_PROG_ADDR_W-1 : 0] MLDSA_KG_S = ABR_ZEROIZE + 1; + localparam [ABR_PROG_ADDR_W-1 : 0] MLDSA_KG_JUMP_SIGN = MLDSA_KG_S + 101; + localparam [ABR_PROG_ADDR_W-1 : 0] MLDSA_KG_E = MLDSA_KG_JUMP_SIGN + 1; + //Signing + localparam [ABR_PROG_ADDR_W-1 : 0] MLDSA_SIGN_S = MLDSA_KG_E + 2; + localparam [ABR_PROG_ADDR_W-1 : 0] MLDSA_SIGN_CHECK_MODE = MLDSA_SIGN_S + 3; + localparam [ABR_PROG_ADDR_W-1 : 0] MLDSA_SIGN_H_MU = MLDSA_SIGN_CHECK_MODE + 1; + localparam [ABR_PROG_ADDR_W-1 : 0] MLDSA_SIGN_H_RHO_P = MLDSA_SIGN_H_MU + 2; + localparam [ABR_PROG_ADDR_W-1 : 0] MLDSA_SIGN_INIT_S = MLDSA_SIGN_H_RHO_P + 3; + localparam [ABR_PROG_ADDR_W-1 : 0] MLDSA_SIGN_LFSR_S = MLDSA_SIGN_INIT_S+24; + localparam [ABR_PROG_ADDR_W-1 : 0] MLDSA_SIGN_MAKE_Y_S = MLDSA_SIGN_LFSR_S + 3; + localparam [ABR_PROG_ADDR_W-1 : 0] MLDSA_SIGN_MAKE_W_S = MLDSA_SIGN_MAKE_Y_S+ 14; + localparam [ABR_PROG_ADDR_W-1 : 0] MLDSA_SIGN_MAKE_W = MLDSA_SIGN_MAKE_W_S+ 65; + localparam [ABR_PROG_ADDR_W-1 : 0] MLDSA_SIGN_MAKE_C = MLDSA_SIGN_MAKE_W+ 1; + localparam [ABR_PROG_ADDR_W-1 : 0] MLDSA_SIGN_VALID_S = MLDSA_SIGN_MAKE_C+ 2; + localparam [ABR_PROG_ADDR_W-1 : 0] MLDSA_SIGN_CHL_E = MLDSA_SIGN_VALID_S + 101; + localparam [ABR_PROG_ADDR_W-1 : 0] MLDSA_SIGN_E = MLDSA_SIGN_CHL_E + 1; + //Verify + localparam [ABR_PROG_ADDR_W-1 : 0] MLDSA_VERIFY_S = MLDSA_SIGN_E + 2; + localparam [ABR_PROG_ADDR_W-1 : 0] MLDSA_VERIFY_H_TR = MLDSA_VERIFY_S + 9; + localparam [ABR_PROG_ADDR_W-1 : 0] MLDSA_VERIFY_CHECK_MODE = MLDSA_VERIFY_H_TR + 1; + localparam [ABR_PROG_ADDR_W-1 : 0] MLDSA_VERIFY_H_MU = MLDSA_VERIFY_CHECK_MODE + 1; + localparam [ABR_PROG_ADDR_W-1 : 0] MLDSA_VERIFY_MAKE_C = MLDSA_VERIFY_H_MU + 2; + localparam [ABR_PROG_ADDR_W-1 : 0] MLDSA_VERIFY_NTT_C = MLDSA_VERIFY_MAKE_C + 1; + localparam [ABR_PROG_ADDR_W-1 : 0] MLDSA_VERIFY_NTT_T1 = MLDSA_VERIFY_NTT_C + 1; + localparam [ABR_PROG_ADDR_W-1 : 0] MLDSA_VERIFY_NTT_Z = MLDSA_VERIFY_NTT_T1 + 8; + localparam [ABR_PROG_ADDR_W-1 : 0] MLDSA_VERIFY_EXP_A = MLDSA_VERIFY_NTT_Z + 7; + localparam [ABR_PROG_ADDR_W-1 : 0] MLDSA_VERIFY_RES = MLDSA_VERIFY_EXP_A + 80; + localparam [ABR_PROG_ADDR_W-1 : 0] MLDSA_VERIFY_E = MLDSA_VERIFY_RES + 4; + + localparam [ABR_PROG_ADDR_W-1 : 0] ABR_ERROR = '1; + + localparam [ABR_PROG_ADDR_W-1 : 0] MLKEM_RESET = 'd0; + localparam [ABR_PROG_ADDR_W-1 : 0] MLKEM_KG_S = MLDSA_VERIFY_E + 1; + localparam [ABR_PROG_ADDR_W-1 : 0] MLKEM_KG_E = MLKEM_KG_S + 43; + localparam [ABR_PROG_ADDR_W-1 : 0] MLKEM_DECAPS_S = MLKEM_KG_E + 1; + localparam [ABR_PROG_ADDR_W-1 : 0] MLKEM_ENCAPS_S = MLKEM_DECAPS_S + 18; + localparam [ABR_PROG_ADDR_W-1 : 0] MLKEM_ENCAPS_E = MLKEM_ENCAPS_S + 56; + localparam [ABR_PROG_ADDR_W-1 : 0] MLKEM_DECAPS_CHK = MLKEM_ENCAPS_E + 1; + localparam [ABR_PROG_ADDR_W-1 : 0] MLKEM_DECAPS_E = MLKEM_DECAPS_CHK + 2; + + + +endpackage + +`endif diff --git a/designs/Caliptra/src/adams-bridge/abr_delay_masked_shares.sv b/designs/Caliptra/src/adams-bridge/abr_delay_masked_shares.sv new file mode 100644 index 0000000..bb10e9e --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/abr_delay_masked_shares.sv @@ -0,0 +1,71 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +// +//====================================================================== +// +// abr_delay_masked_shares +// Buffers the masked shares for the N cycle +//====================================================================== + +module abr_delay_masked_shares +#( + parameter WIDTH = 46, // Width of the input array + parameter N = 5 // Number of cycles to delay +) +( + input wire clk, + input wire rst_n, + input wire zeroize, + input wire [1:0] input_reg [WIDTH-1:0], // Input signal + output logic [1:0] delayed_reg [WIDTH-1:0] // Delayed output +); + + // Create an array of shift registers to store the delayed values + logic [N-1:0][WIDTH-1:0][1:0] shift_reg ; + + // Use an always_ff block to implement the shift register + always_ff @(posedge clk or negedge rst_n) begin + if (!rst_n) begin + // Reset all shift register values to 0 + for (int j = 0; j < N; j = j + 1) begin + shift_reg[j] <= '0; + end + end + else if (zeroize) begin + // Reset all shift register values to 0 + for (int j = 0; j < N; j = j + 1) begin + shift_reg[j] <= '0; + end + end + else begin + // Shift the values through the registers + for (int j = 0; j < N-1; j = j + 1) begin + shift_reg[j+1] <= shift_reg[j]; + end + + // Load the input values into the first shift register stage + for (int i = 0; i < WIDTH; i = i + 1) begin + shift_reg[0][i] <= input_reg[i]; + end + end + end + + // Assign the output to the last stage of the shift register + always_comb begin + for (int i = 0; i < WIDTH; i = i + 1) begin + delayed_reg[i] = shift_reg[N-1][i]; + end + end + +endmodule: abr_delay_masked_shares \ No newline at end of file diff --git a/designs/Caliptra/src/adams-bridge/abr_icg.sv b/designs/Caliptra/src/adams-bridge/abr_icg.sv new file mode 100644 index 0000000..247f93c --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/abr_icg.sv @@ -0,0 +1,34 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. + +`ifndef TECH_SPECIFIC_ICG + module `ABR_ICG ( + input logic clk, + input logic en, + output clk_cg + ); + logic en_lat; + + //Latch disable for both clk and soc_ifc clk + always_latch begin + if(!clk) begin + en_lat = en; + end + end + + //Gate clk + assign clk_cg = clk && en_lat; + + endmodule +`endif \ No newline at end of file diff --git a/designs/Caliptra/src/adams-bridge/abr_keccak_2share.sv b/designs/Caliptra/src/adams-bridge/abr_keccak_2share.sv new file mode 100644 index 0000000..9bb7de3 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/abr_keccak_2share.sv @@ -0,0 +1,636 @@ +// Copyright lowRISC contributors. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// This module is the single round keccak permutation module +// It supports Keccak with up to 1600b of state + +`include "abr_sva.svh" +`include "abr_prim_assert.sv" + +module abr_keccak_2share + import abr_prim_mubi_pkg::*; +#( + parameter int Width = 1600, // b= {25, 50, 100, 200, 400, 800, 1600} + + // Derived + localparam int W = Width/25, + localparam int L = $clog2(W), + localparam int MaxRound = 12 + 2*L, // Keccak-f only + localparam int RndW = $clog2(MaxRound+1), // Representing up to MaxRound + + // Control parameters + parameter bit EnMasking = 0, // Enable secure hardening + localparam int Share = EnMasking ? 2 : 1 +) ( + input clk_i, + input rst_b, + + input [RndW-1:0] rnd_i, // Current round index + input mubi4_t phase_sel_i, // Output mux contol. Used when EnMasking := 1 + input [1:0] cycle_i, // Current cycle index. Used when EnMasking := 1 + input rand_aux_i, // Auxiliary randomness input. Used when EnMasking := 1 + input [Width/2-1:0] rand_i, // Randomness for remasking. Used when EnMasking := 1 + input [Width-1:0] s_i [Share], + output logic [Width-1:0] s_o [Share] +); + /////////// + // Types // + /////////// + // x y z + typedef logic [4:0][4:0][W-1:0] box_t; // (x,y,z) state + typedef logic [W-1:0] lane_t; // (z) + typedef logic [4:0] [W-1:0] plane_t; // (x,z) + typedef logic [4:0][4:0] slice_t; // (x,y) + typedef logic [4:0][W-1:0] sheet_t; // (y,z) identical to plane_t + typedef logic [4:0] row_t; // (x) + typedef logic [4:0] col_t; // (y) identical to row_t + + ////////////// + // Keccak_f // + ////////////// + box_t state_in [Share]; + box_t state_out [Share]; + box_t theta_data [Share]; + box_t rho_data [Share]; + box_t pi_data [Share]; + box_t chi_data [Share]; + box_t iota_data [Share]; + + box_t phase1_in [Share]; + box_t phase1_out [Share]; + box_t phase2_in [Share]; + box_t phase2_out [Share]; + + ///////////////// + // Unused nets // + ///////////////// + // Tie off input signals that aren't used in the unmasked implementation. + if (!EnMasking) begin : gen_tie_unused + logic unused_clk; + logic unused_rst_n; + mubi4_t unused_phase_sel; + logic [1:0] unused_cycle; + logic unused_rand_aux; + logic [Width/2-1:0] unused_rand; + assign unused_clk = clk_i; + assign unused_rst_n = rst_b; + assign unused_phase_sel = phase_sel_i; + assign unused_cycle = cycle_i; + assign unused_rand_aux = rand_aux_i; + assign unused_rand = rand_i; + end + + ////////////////////////////////////////////////// + // Input/output type conversion and interfacing // + ////////////////////////////////////////////////// + for (genvar i = 0 ; i < Share ; i++) begin : g_state_inout + assign state_in[i] = bitarray_to_box(s_i[i]); + assign s_o[i] = box_to_bitarray(state_out[i]); + end : g_state_inout + + if (EnMasking) begin : g_2share_data + assign phase1_in = state_in; + assign phase2_in = state_in; + + always_comb begin + unique case (phase_sel_i) + MuBi4False: state_out = phase1_out; + MuBi4True: state_out = phase2_out; + default: state_out = phase1_out; + endcase + end + end else begin : g_single_data + assign phase1_in = state_in; + assign phase2_in = phase1_out; + assign state_out = phase2_out; + end + + ////////////// + // Datapath // + ////////////// + // This module has two phases. First phase, it calculates Theta, Rho, Pi steps + // in SHA3. At the second phase, it computes Chi and Iota steps. If masking is + // not enabled, the two phases are completed within a single clock cycle. + // + // If masking is enabled, the first phase (Phase1) completes in one cycle. + // Then, the output should be stored in the state and given to the input of + // this module again. The second phase in the masked version needs three + // clock cycles to complete. In the first clock cycle, the first stage of Chi + // is computed for the first lane halves. In the second clock cycle, the + // module then outputs the updated first lane halves. In the third clock + // cycle, the new second lane halves are output. To aggravate SCA, we + // randomly decide which lane halves to process first on a per-round basis. + // We use additional randomness generated by the PRNG to take this decision + // (rand_aux_i). For more details, refer to the comments in the "MUX control" + // section below. + + for (genvar i = 0 ; i < Share ; i++) begin : g_datapath + + // Phase 1: + assign theta_data[i] = theta(phase1_in[i]); + // Commented out rho function as vcs complains z-Offset%W isn't constant + // assign rho_data[i] = rho(theta_data[i]); + + assign pi_data[i] = pi(rho_data[i]); + + // Phase 2 (Cycles 1, 2 and 3): + // Chi : See below + // Iota: See below + end : g_datapath + + assign phase1_out = pi_data; + + // Iota adds Round Constants(RC), so only one share should be XORed + if (EnMasking) begin : g_2share_iota + assign iota_data[0] = iota(chi_data[0], rnd_i); + assign iota_data[1] = chi_data[1]; + end else begin : g_single_iota + assign iota_data[0] = iota(chi_data[0], rnd_i); + end + + if (EnMasking) begin : g_2share_chi + // Domain-Oriented Masking + // reference: https://eprint.iacr.org/2017/395.pdf + + localparam int unsigned WSheetHalf = $bits(sheet_t)/2; + logic [4:0][WSheetHalf-1:0] in_prd, out_prd; + + logic low_then_high_d, low_then_high_q; + logic in_data_low, out_data_low; + logic in_rand_ext; + logic update_dom; + + ///////////////// + // MUX control // + ///////////////// + + // Update lane-half processing order in Phase 1 and keep the value constant + // for the entire round. + assign low_then_high_d = + mubi4_test_false_strict(phase_sel_i) ? rand_aux_i : low_then_high_q; + + always_ff @(posedge clk_i or negedge rst_b) begin + if (!rst_b) begin + low_then_high_q <= 1'b 0; + end else begin + low_then_high_q <= low_then_high_d; + end + end + + // This implementation uses both randomness provided from an external PRNG + // as well as intermediate results for remasking the DOM multipliers below. + // Per clock cycle, 800b of pseudo-random data (PRD) are required. The + // following schedule is used to only ever update the input data when also + // providing fresh randomness and vice versa. + // + // Cycle 0: Compute Theta, Rho, Pi - The DOM multipliers are not evaluated + // at all: the inputs are driven by the first lane halves (same + // values as in Cycle 3). Also the intermediate results we already + // had in Cycle 3 didn't change. + // Cycle 1: Compute first stage of Chi for first lane halves using the DOM + // multipliers. We use the fresh randomness provided from the + // PRNG for remasking. + // Cycle 2: Compute second stage of Chi and Iota for first lane halves. + // Compute first stage of Chi for second lane halves. We use the + // fresh randomness provided from the PRNG for remasking the + // DOM multipliers. + // Cycle 3: Compute second stage of Chi and Iota for second lane halves. + // Feed again first lane halves to DOM multiplier inputs (now + // the updated values become visible) together with intermediate + // results of Cycle 2. Don't update the register stage inside + // the DOM multipliers. + always_comb begin + unique case (cycle_i) + 2'h0: begin + in_data_low = low_then_high_q; + in_rand_ext = 1'b0; + update_dom = 1'b0; + end + 2'h1: begin + in_data_low = low_then_high_q; + in_rand_ext = 1'b1; + update_dom = 1'b1; + end + 2'h2: begin + in_data_low = ~low_then_high_q; + in_rand_ext = 1'b1; + update_dom = 1'b1; + end + 2'h3: begin + in_data_low = low_then_high_q; + in_rand_ext = 1'b0; + update_dom = 1'b0; + end + default: begin + in_data_low = low_then_high_q; + in_rand_ext = 1'b0; + update_dom = 1'b0; + end + endcase + end + + // When taking the lower lane halves in, the upper lane halves are output + // and vice versa. + assign out_data_low = ~in_data_low; + + ///////////////////// + // DOM multipliers // + ///////////////////// + + for (genvar x = 0 ; x < 5 ; x++) begin : g_chi_w + localparam int X1 = (x + 1) % 5; + localparam int X2 = (x + 2) % 5; + + sheet_t sheet0[Share]; // Inverted input X1 + sheet_t sheet1[Share]; // X2 + sheet_t sheet2[Share]; // DOM output + + assign sheet0[0] = ~phase2_in[0][X1]; + assign sheet0[1] = phase2_in[1][X1]; + + assign sheet1[0] = phase2_in[0][X2]; + assign sheet1[1] = phase2_in[1][X2]; + + // Convert sheet_t to 1D arrays, one for the upper and lower half lane. + logic [WSheetHalf-1:0] a0_l, a1_l, b0_l, b1_l; + logic [WSheetHalf-1:0] a0_h, a1_h, b0_h, b1_h; + logic [WSheetHalf-1:0] a0, a1, b0, b1, q0, q1; + + assign a0_l = {sheet0[0][0][W/2-1:0], + sheet0[0][1][W/2-1:0], + sheet0[0][2][W/2-1:0], + sheet0[0][3][W/2-1:0], + sheet0[0][4][W/2-1:0]}; + assign a1_l = {sheet0[1][0][W/2-1:0], + sheet0[1][1][W/2-1:0], + sheet0[1][2][W/2-1:0], + sheet0[1][3][W/2-1:0], + sheet0[1][4][W/2-1:0]}; + + assign a0_h = {sheet0[0][0][W-1:W/2], + sheet0[0][1][W-1:W/2], + sheet0[0][2][W-1:W/2], + sheet0[0][3][W-1:W/2], + sheet0[0][4][W-1:W/2]}; + assign a1_h = {sheet0[1][0][W-1:W/2], + sheet0[1][1][W-1:W/2], + sheet0[1][2][W-1:W/2], + sheet0[1][3][W-1:W/2], + sheet0[1][4][W-1:W/2]}; + + assign b0_l = {sheet1[0][0][W/2-1:0], + sheet1[0][1][W/2-1:0], + sheet1[0][2][W/2-1:0], + sheet1[0][3][W/2-1:0], + sheet1[0][4][W/2-1:0]}; + assign b1_l = {sheet1[1][0][W/2-1:0], + sheet1[1][1][W/2-1:0], + sheet1[1][2][W/2-1:0], + sheet1[1][3][W/2-1:0], + sheet1[1][4][W/2-1:0]}; + + assign b0_h = {sheet1[0][0][W-1:W/2], + sheet1[0][1][W-1:W/2], + sheet1[0][2][W-1:W/2], + sheet1[0][3][W-1:W/2], + sheet1[0][4][W-1:W/2]}; + assign b1_h = {sheet1[1][0][W-1:W/2], + sheet1[1][1][W-1:W/2], + sheet1[1][2][W-1:W/2], + sheet1[1][3][W-1:W/2], + sheet1[1][4][W-1:W/2]}; + + // Input muxing + assign a0 = in_data_low ? a0_l : a0_h; + assign a1 = in_data_low ? a1_l : a1_h; + assign b0 = in_data_low ? b0_l : b0_h; + assign b1 = in_data_low ? b1_l : b1_h; + + // Randomness muxing + // Intermediate results are rotated across rows. The new Row x depends on + // data from Rows x + 1 and x + 2. Hence we don't want to use intermediate + // results from Rows x, x + 1, and x + 2 for remasking. + assign in_prd[x] = in_rand_ext ? rand_i[x * WSheetHalf +: WSheetHalf] : + out_prd[rot_int(x, 5)]; + + abr_prim_dom_and_2share #( + .DW (WSheetHalf), // a half sheet + .Pipeline(1) // Process the full sheet in 3 clock cycles. This reduces + // SCA leakage. + ) u_dom ( + .clk_i, + .rst_b, + + .a0_i (a0), + .a1_i (a1), + .b0_i (b0), + .b1_i (b1), + .z_valid_i (update_dom), + .z_i (in_prd[x]), + .q0_o (q0), + .q1_o (q1), + .prd_o (out_prd[x]) + ); + + // Output conversion from q0, q1 to sheet_t + // For simplicity, we forward the generated lane half to both the upper + // and lower lane halves at this point. The actual output muxing/selection + // happens after the Iota step when generating phase2_out from iota_data + // and state_in below. + assign sheet2[0][4] = {2{q0[W/2*0+:W/2]}}; + assign sheet2[0][3] = {2{q0[W/2*1+:W/2]}}; + assign sheet2[0][2] = {2{q0[W/2*2+:W/2]}}; + assign sheet2[0][1] = {2{q0[W/2*3+:W/2]}}; + assign sheet2[0][0] = {2{q0[W/2*4+:W/2]}}; + + assign sheet2[1][4] = {2{q1[W/2*0+:W/2]}}; + assign sheet2[1][3] = {2{q1[W/2*1+:W/2]}}; + assign sheet2[1][2] = {2{q1[W/2*2+:W/2]}}; + assign sheet2[1][1] = {2{q1[W/2*3+:W/2]}}; + assign sheet2[1][0] = {2{q1[W/2*4+:W/2]}}; + + // Final XOR to generate the output + assign chi_data[0][x] = sheet2[0] ^ phase2_in[0][x]; + assign chi_data[1][x] = sheet2[1] ^ phase2_in[1][x]; + end : g_chi_w + + // Since Chi and thus Iota are separately applied to the lower and upper half + // lanes, we need to forward the input to the other half. + for (genvar x = 0 ; x < 5 ; x++) begin : g_2share_phase2_out_row + for (genvar y = 0 ; y < 5 ; y++) begin : g_2share_phase2_out_col + assign phase2_out[0][x][y] = out_data_low ? + { state_in[0][x][y][W-1:W/2], iota_data[0][x][y][W/2-1:0]} : + {iota_data[0][x][y][W-1:W/2], state_in[0][x][y][W/2-1:0]}; + assign phase2_out[1][x][y] = out_data_low ? + { state_in[1][x][y][W-1:W/2], iota_data[1][x][y][W/2-1:0]} : + {iota_data[1][x][y][W-1:W/2], state_in[1][x][y][W/2-1:0]}; + end + end + + end else begin : g_single_chi + assign chi_data[0] = chi(phase2_in[0]); + assign phase2_out = iota_data; + end + + // Rho ====================================================================== + // As RhoOffset[x][y] is considered as variable int in VCS, + // it is replaced with generate statement. + // Revised to meet verilator lint. Now RhoOffset is 1-D array + localparam int RhoOffset [25] = '{ + //y 0 1 2 3 4 x + 0, 36, 3, 105, 210, // 0: 0 1 2 3 4 + 1, 300, 10, 45, 66, // 1: 5 6 7 8 9 + 190, 6, 171, 15, 253, // 2: 10 11 12 13 14 + 28, 55, 153, 21, 120, // 3: 15 16 17 18 19 + 91, 276, 231, 136, 78 // 4: 20 21 22 23 24 + }; + for (genvar i = 0 ; i < Share ; i++) begin : g_rho + box_t rho_in, rho_out; + assign rho_in = theta_data[i]; + assign rho_data[i] = rho_out; + + for (genvar x = 0 ; x < 5 ; x++) begin : gen_rho_x + for (genvar y = 0 ; y < 5 ; y++) begin : gen_rho_y + localparam int Offset = RhoOffset[5*x+y]%W; + localparam int ShiftAmt = W- Offset; + if (Offset == 0) begin : gen_offset0 + assign rho_out[x][y][W-1:0] = rho_in[x][y][W-1:0]; + end else begin : gen_others + assign rho_out[x][y][W-1:0] = {rho_in[x][y][0+:ShiftAmt], + rho_in[x][y][ShiftAmt+:Offset]}; + end + end + end + end : g_rho + + //////////////// + // Assertions // + //////////////// + + `ABR_ASSERT_INIT(ValidWidth_A, + EnMasking == 0 && Width inside {25, 50, 100, 200, 400, 800, 1600} || + EnMasking == 1 && Width inside {50, 100, 200, 400, 800, 1600}) + `ABR_ASSERT_INIT(ValidW_A, W inside {1, 2, 4, 8, 16, 32, 64}) + `ABR_ASSERT_INIT(ValidL_A, L inside {0, 1, 2, 3, 4, 5, 6}) + `ABR_ASSERT_INIT(ValidRound_A, MaxRound <= 24) // Keccak-f only + + // phase_sel_i shall stay for two cycle after change to 1. + if (EnMasking) begin : gen_selperiod_chk + `ABR_ASSERT(SelStayTwoCycleIfTrue_A, + ($past(phase_sel_i) == MuBi4False) && (phase_sel_i == MuBi4True) + |=> phase_sel_i == MuBi4True, clk_i, !rst_b) + end + + /////////////// + // Functions // + /////////////// + + // Convert bitarray to 3D box + // Please take a look at FIPS PUB 202 + // https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf + // > For all triples (x,y,z) such that 0<=x<5, 0<=y<5, and 0<=z A[x,y,z]=S[w(5y+x)+z] + function automatic box_t bitarray_to_box(logic [Width-1:0] s_in); + automatic box_t box; + for (int y = 0 ; y < 5 ; y++) begin + for (int x = 0 ; x < 5 ; x++) begin + for (int z = 0 ; z < W ; z++) begin + box[x][y][z] = s_in[W*(5*y+x) + z]; + end + end + end + return box; + endfunction : bitarray_to_box + + // Convert 3D cube to bitarray + function automatic logic [Width-1:0] box_to_bitarray(box_t state); + automatic logic [Width-1:0] bitarray; + for (int y = 0 ; y < 5 ; y++) begin + for (int x = 0 ; x < 5 ; x++) begin + for (int z = 0 ; z < W ; z++) begin + bitarray[W*(5*y+x)+z] = state[x][y][z]; + end + end + end + return bitarray; + endfunction : box_to_bitarray + + // Rotate integer indices + function automatic integer rot_int(integer in, integer num); + integer out; + if (in == 0) begin + out = num - 1; + end else begin + out = in - 1; + end + return out; + endfunction + + // Step Mapping ============================================================= + // theta + // XOR each bit in the state with the parity of two columns + // C[x,z] = A[x,0,z] ^ A[x,1,z] ^ A[x,2,z] ^ A[x,3,z] ^ A[x,4,z] + // D[x,z] = C[x-1,z] ^ C[x+1,z-1] + // theta = A[x,y,z] ^ D[x,z] + parameter logic [2:0] ThetaIndexX1 [5] = '{4, 0, 1, 2, 3}; // (x-1)%5 + parameter logic [2:0] ThetaIndexX2 [5] = '{1, 2, 3, 4, 0}; // (x+1)%5 + function automatic box_t theta(box_t state); + plane_t c; + plane_t d; + box_t result; + for (int x = 0 ; x < 5 ; x++) begin + c[x] = state[x][0] ^ state[x][1] ^ state[x][2] ^ state[x][3] ^ state[x][4]; + end + for (int x = 0 ; x < 5 ; x++) begin + for (int z = 0 ; z < W ; z++) begin + logic [$clog2(W)-1:0] index_z; + index_z = (z == 0) ? W-1 : z-1; // (z+1)%W + d[x][z] = c[ThetaIndexX1[x]][z] ^ c[ThetaIndexX2[x]][index_z]; + end + end + for (int x = 0 ; x < 5 ; x++) begin + for (int y = 0 ; y < 5 ; y++) begin + result[x][y] = state[x][y] ^ d[x]; + end + end + return result; + endfunction : theta + + // rho + + // Commented out entire rho function due to VCS elaboration error. + // (z-RhoOffset[x][y]%W) isn't considered as a constant in VCS. + // Even changing it to W-RhoOffset[x][y]%W and assign to ShiftAmt + // creates same error. + + // Offset : Look at Table 2 in FIPS PUB 202 + //localparam int RhoOffset [5][5] = '{ + // //y 0 1 2 3 4 x + // '{ 0, 36, 3, 105, 210},// 0 + // '{ 1, 300, 10, 45, 66},// 1 + // '{ 190, 6, 171, 15, 253},// 2 + // '{ 28, 55, 153, 21, 120},// 3 + // '{ 91, 276, 231, 136, 78} // 4 + //}; + + // rotate bits of each lane by offset + // 1. rho[0,0,z] = A[0,0,z] + // 2. Offset swap + // a. (x,y) := (1,0) + // b. for t [0..23] + // i. rho[x,y,z] = A[x,y,z-(t+1)(t+2)/2] + // ii. (x,y) = (y, (2x+3y)) + //function automatic box_t rho(box_t state); + // box_t result; + // for (int x = 0 ; x < 5 ; x++) begin + // for (int y = 0 ; y < 5 ; y++) begin + // for (int z = 0 ; z < W ; z++) begin + // automatic int index_z; + // index_z = (z-RhoOffset[x][y])%W; + // result[x][y][z] = state[x][y][(z-RhoOffset[x][y])%W]; + // end + // end + // end + // return result; + //endfunction : rho + + // pi + // rearrange the position of lanes + // pi[x,y,z] = state[(x+3y),x,z] + localparam logic [2:0] PiRotate [5][5] = '{ + //y 0 1 2 3 4 x + '{ 0, 3, 1, 4, 2},// 0 + '{ 1, 4, 2, 0, 3},// 1 + '{ 2, 0, 3, 1, 4},// 2 + '{ 3, 1, 4, 2, 0},// 3 + '{ 4, 2, 0, 3, 1} // 4 + }; + function automatic box_t pi(box_t state); + box_t result; + for (int x = 0 ; x < 5 ; x++) begin + for (int y = 0 ; y < 5 ; y++) begin + result[x][y][W-1:0] = state[PiRotate[x][y]][x][W-1:0]; + end + end + return result; + endfunction : pi + + // chi + // chi[x,y,z] = state[x,y,z] ^ ((state[x+1,y,z] ^ 1) & state[x+2,y,z]) + parameter logic [2:0] ChiIndexX1 [5] = '{1, 2, 3, 4, 0}; // (x+1)%5 + parameter logic [2:0] ChiIndexX2 [5] = '{2, 3, 4, 0, 1}; // (x+2)%5 + function automatic box_t chi(box_t state); + box_t result; + for (int x = 0 ; x < 5 ; x++) begin + result[x] = state[x] ^ ((~state[ChiIndexX1[x]]) & state[ChiIndexX2[x]]); + end + return result; + endfunction : chi + + // iota + // XOR (x,y) = (0,0) with Round Constant (RC) + + // RC parameter: Precomputed by util/keccak_rc.py. Only up-to 0..L-1 is used + // RC = '0 + // RC[2**j-1] = rc(j+7*rnd) + // rc(t) = + // 1. t%255 == 0 -> 1 + // 2. R[0:7] = 'b10000000 + // 3. for i = [1..t%255] + // a. R = 0 || R + // b. R[0] = R[0] ^ R[8] + // c. R[4] = R[4] ^ R[8] + // d. R[5] = R[5] ^ R[8] + // e. R[6] = R[6] ^ R[8] + // f. R = R[0:7] + // 4. return R[0] + // RC has L = [0..6] + // for lower L case, only chopping lower part of 64bit RC is sufficient. + localparam logic [63:0] RC [24] = '{ + 64'h 0000_0000_0000_0001, // Round 0 + 64'h 0000_0000_0000_8082, // Round 1 + 64'h 8000_0000_0000_808A, // Round 2 + 64'h 8000_0000_8000_8000, // Round 3 + 64'h 0000_0000_0000_808B, // Round 4 + 64'h 0000_0000_8000_0001, // Round 5 + 64'h 8000_0000_8000_8081, // Round 6 + 64'h 8000_0000_0000_8009, // Round 7 + 64'h 0000_0000_0000_008A, // Round 8 + 64'h 0000_0000_0000_0088, // Round 9 + 64'h 0000_0000_8000_8009, // Round 10 + 64'h 0000_0000_8000_000A, // Round 11 + 64'h 0000_0000_8000_808B, // Round 12 + 64'h 8000_0000_0000_008B, // Round 13 + 64'h 8000_0000_0000_8089, // Round 14 + 64'h 8000_0000_0000_8003, // Round 15 + 64'h 8000_0000_0000_8002, // Round 16 + 64'h 8000_0000_0000_0080, // Round 17 + 64'h 0000_0000_0000_800A, // Round 18 + 64'h 8000_0000_8000_000A, // Round 19 + 64'h 8000_0000_8000_8081, // Round 20 + 64'h 8000_0000_0000_8080, // Round 21 + 64'h 0000_0000_8000_0001, // Round 22 + 64'h 8000_0000_8000_8008 // Round 23 + }; + + // iota: XOR with RC for (x,y) = (0,0) + function automatic box_t iota(box_t state, logic [RndW-1:0] rnd); + box_t result; + result = state; + result[0][0][W-1:0] = state[0][0][W-1:0] ^ RC[rnd][W-1:0]; + + return result; + endfunction : iota + + // Round function : Rnd(A,i_r) + // Not used due to rho function issue described above. + + //function automatic box_t keccak_rnd(box_t state, logic [RndW-1:0] rnd); + // box_t keccak_state; + // keccak_state = iota(chi(pi(rho(theta(state)))), rnd); + // + // return keccak_state; + //endfunction : keccak_rnd + +endmodule diff --git a/designs/Caliptra/src/adams-bridge/abr_keccak_round.sv b/designs/Caliptra/src/adams-bridge/abr_keccak_round.sv new file mode 100644 index 0000000..3ce4a12 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/abr_keccak_round.sv @@ -0,0 +1,501 @@ +// Copyright lowRISC contributors. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Keccak full round logic based on given input `Width` +// e.g. Width 800 requires 22 rounds + +`include "abr_sva.svh" +`include "abr_prim_assert.sv" + +module abr_keccak_round + import abr_prim_mubi_pkg::*; +#( + parameter int Width = 1600, // b= {25, 50, 100, 200, 400, 800, 1600} + parameter int RoundsPerClock = 1, + + // Derived + localparam int W = Width/25, + localparam int L = $clog2(W), + localparam int MaxRound = 12 + 2*L, // Keccak-f only + localparam int RndW = $clog2(MaxRound+1), // Representing up to MaxRound-1 + + // Control parameters + parameter bit EnMasking = 1'b0, // Enable SCA hardening, requires Width >= 50 + localparam int Share = EnMasking ? 2 : 1 +) ( + input clk_i, + input rst_b, + input logic zeroize, + + // Message Feed + input [Width-1:0] data_i [Share], + output ready_o, + + // In-process control + input logic run_i, // Pulse signal to initiates Keccak full round + input logic squeezing_i, + input logic rand_valid_i, + input logic rand_early_i, + input logic [Width/2-1:0] rand_data_i, + input logic rand_aux_i, + output logic rand_consumed_o, + + output logic complete_o, // Indicates full round is done + + // State out. This can be used as Digest + output logic [Width-1:0] state_o [Share], + + // Errors: + // sparse_fsm_error: Checking if FSM state falls into unknown value + output logic sparse_fsm_error_o, + // round_count_error: abr_prim_count checks round value consistency + output logic round_count_error_o, + // rst_storage_error: check if reset signal asserted out of the + // permitted window + output logic rst_storage_error_o, + + input abr_prim_mubi_pkg::mubi4_t clear_i // Clear internal state to '0 +); + + ///////////////////// + // Control signals // + ///////////////////// + + // Update storage register + logic update_storage; + logic update_serial_buffer; + + // Reset the storage to 0 to initiate new Hash operation + logic rst_storage; + logic rst_serial_buffer; + + // XOR message into storage register + logic xor_message; + + // Select Keccak_p datapath + // 0: Select Phase1 (Theta -> Rho -> Pi) + // 1: Select Phase2 (Chi -> Iota) + // `phase_sel` needs to be asserted until the Chi stage is consumed, + mubi4_t phase_sel; + + // Cycle index used for controlling input/output muxes and write enables inside + // keccak_2share. + logic [1:0] cycle; + + // Increase/ Reset Round number + logic inc_rnd_num; + logic rst_rnd_num; + + // Round reaches end + // This signal indicates the round reaches desired number, which is MaxRound -1. + // MaxRound is dependant on the Width. In case of SHA3/SHAKE, MaxRound is 24. + logic rnd_eq_end; + + // Complete of Keccak_f + // State machine asserts `complete_d` when it reaches at the end of round and + // operation (Phase3 if Masked). The the stage, the storage still doesn't have + // the valid states. So precisely it is not completed yet. + // State generated `complete_d` is latched with the clock and creates a pulse + // signal one cycle later. The signal is the indication of completion. + // + // Intentionally removed any intermediate step (so called StComplete) in order + // to save a clock to proceeds next round. + logic complete_d; + + ////////////////////// + // Datapath Signals // + ////////////////////// + + // Single round keccak output data + logic [Width-1:0] keccak_out [Share]; + + // Keccak Round indicator: range from 0 .. MaxRound + logic [RndW-1:0] round; + + // Random value and valid signal used in Keccak_p + logic keccak_rand_consumed; + logic [Width/2-1:0] keccak_rand_data; + logic keccak_rand_aux; + + ////////////////////// + // Keccak Round FSM // + ////////////////////// + + // state inputs + assign rnd_eq_end = (int'(round) == MaxRound - RoundsPerClock); + + // Encoding generated with: + // $ ./util/design/sparse-fsm-encode.py -d 3 -m 8 -n 6 \ + // -s 1363425333 --language=sv + // + // Hamming distance histogram: + // + // 0: -- + // 1: -- + // 2: -- + // 3: |||||||||||||||||||| (57.14%) + // 4: ||||||||||||||| (42.86%) + // 5: -- + // 6: -- + // + // Minimum Hamming distance: 3 + // Maximum Hamming distance: 4 + // Minimum Hamming weight: 1 + // Maximum Hamming weight: 5 + // + localparam int StateWidth = 6; + typedef enum logic [StateWidth-1:0] { + StIdle = 6'b011111, + + // Active state is used in Unmasked version only. + // It handles keccak round in a cycle + StActive = 6'b000100, + + // Phase1 --> Phase2Cycle1 --> Phase2Cycle2 --> Phase2Cycle3 + // Activated only in Masked version. + // Phase1 processes Theta, Rho, Pi steps in a cycle and stores the states + // into storage. It only moves to Phase2 once the randomness required for + // Phase2 is available. + StPhase1 = 6'b101101, + + // Chi Stage 1 for first lane halves. Unconditionally move to Phase2Cycle2. + StPhase2Cycle1 = 6'b000011, + + // Chi Stage 2 and Iota for first lane halves. Chi Stage 1 for second + // lane halves. We only move forward if the fresh randomness required for + // remasking is available. Otherwise, keep computing Phase2Cycle1. + StPhase2Cycle2 = 6'b011000, + + // Chi Stage 2 and Iota for second lane halves. + // This state doesn't require random value as it is XORed into the states + // in Phase1 and Phase2Cycle2. When doing the last round (MaxRound -1) + // it completes the process and goes back to Idle. If not, it repeats + // the phases again. + StPhase2Cycle3 = 6'b101010, + + // Error state. Not clearly defined yet. + // Intention is if any unexpected input in the process, state moves to + // here and report through the error fifo with debugging information. + StError = 6'b110001, + + StTerminalError = 6'b110110 + } keccak_st_e; + keccak_st_e keccak_st, keccak_st_d; + `ABR_PRIM_FLOP_SPARSE_FSM(u_state_regs, keccak_st_d, keccak_st, keccak_st_e, StIdle) + + // Next state logic and output logic + // SEC_CM: FSM.SPARSE + always_comb begin + // Default values + keccak_st_d = keccak_st; + + xor_message = 1'b 0; + update_storage = 1'b 0; + rst_storage = 1'b 0; + rst_serial_buffer = 1'b 0; + + inc_rnd_num = 1'b 0; + rst_rnd_num = 1'b 0; + + keccak_rand_consumed = 1'b 0; + + phase_sel = MuBi4False; + cycle = 2'h 0; + + complete_d = 1'b 0; + + sparse_fsm_error_o = 1'b 0; + + unique case (keccak_st) + StIdle: begin + if (abr_prim_mubi_pkg::mubi4_test_true_strict(clear_i)) begin + // Opt1. State machine allows resetting the storage only in Idle + // Opt2. storage resets regardless of states but clear_i + // Both are added in the design at this time. Will choose the + // direction later. + keccak_st_d = StIdle; + + rst_storage = 1'b 1; + rst_serial_buffer = 1'b 1; + end else if (EnMasking && run_i) begin + // Masked version of Keccak handling + keccak_st_d = StPhase1; + xor_message = ~squeezing_i; + update_storage = ~squeezing_i; + end else if (!EnMasking && run_i) begin + // Unmasked version of Keccak handling + keccak_st_d = StActive; + xor_message = ~squeezing_i; + update_storage = ~squeezing_i; + end else begin + keccak_st_d = StIdle; + end + end + + StActive: begin + // Run Keccak single round logic until it reaches MaxRound - 1 + update_storage = 1'b 1; + + if (rnd_eq_end) begin + keccak_st_d = StIdle; + + rst_rnd_num = 1'b 1; + complete_d = 1'b 1; + end else begin + keccak_st_d = StActive; + + inc_rnd_num = 1'b 1; + end + end + + StPhase1: begin + // Theta, Rho and Pi + phase_sel = MuBi4False; + cycle = 2'h 0; + + // Only update state and move on once we know the randomness required + // for Phase2 will be available in the next clock cycle. This way the + // DOM multipliers inside keccak_2share will be presented the new + // state (updated with update_storage) at the same time as the new + // randomness (updated with rand_early_i). Otherwise, stale entropy is + // paired with fresh data or vice versa. This could lead to undesired + // SCA leakage. + if (rand_early_i || rand_valid_i) begin + keccak_st_d = StPhase2Cycle1; + update_storage = 1'b 1; + end else begin + keccak_st_d = StPhase1; + end + end + + StPhase2Cycle1: begin + // Chi Stage 1 for first lane halves. + phase_sel = MuBi4True; + cycle = 2'h 1; + + // Trigger randomness update for next cycle. + keccak_rand_consumed = 1'b 1; + + // Unconditionally move to next phase/cycle. + keccak_st_d = StPhase2Cycle2; + end + + StPhase2Cycle2: begin + // Chi Stage 1 for second lane halves. + // Chi Stage 2 and Iota for first lane halves. + phase_sel = MuBi4True; + + // Only update state and move on if the required randomness is + // available. This way the DOM multipliers inside keccak_2share will be + // presented the second lane halves at the same time as the new + // randomness. Otherwise, stale entropy is paired with fresh data or + // vice versa. This could lead to undesired SCA leakage. + if (rand_valid_i) begin + cycle = 2'h 2; + + // Trigger randomness update for next round. + keccak_rand_consumed = 1'b 1; + + // Update first lane halves. + update_storage = 1'b 1; + + keccak_st_d = StPhase2Cycle3; + end else begin + cycle = 2'h 1; + keccak_st_d = StPhase2Cycle2; + end + end + + StPhase2Cycle3: begin + // Chi Stage 2 and Iota for second lane halves. + phase_sel = MuBi4True; + cycle = 2'h 3; + + // Update second lane halves. + update_storage = 1'b 1; + + if (rnd_eq_end) begin + keccak_st_d = StIdle; + + rst_rnd_num = 1'b 1; + complete_d = 1'b 1; + end else begin + keccak_st_d = StPhase1; + + inc_rnd_num = 1'b 1; + end + end + + StError: begin + keccak_st_d = StError; + end + + StTerminalError: begin + //this state is terminal + keccak_st_d = keccak_st; + sparse_fsm_error_o = 1'b 1; + end + + default: begin + keccak_st_d = StTerminalError; + sparse_fsm_error_o = 1'b 1; + end + endcase + + if (zeroize) keccak_st_d =StIdle; + + end + + // Ready indicates the keccak_round is able to receive new message. + // While keccak_round is processing the data, it blocks the new message to be + // XORed into the current state. + assign ready_o = (keccak_st == StIdle) ? 1'b 1 : 1'b 0; + + //////////////////////////// + // Keccak state registers // + //////////////////////////// + + // SEC_CM: LOGIC.INTEGRITY + logic rst_n; + abr_prim_sec_anchor_buf #( + .Width(1) + ) u_abr_prim_sec_anchor_buf ( + .in_i(rst_b), + .out_o(rst_n) + ); + + logic [Width-1:0] storage_datapath[RoundsPerClock:0][Share]; + logic [Width-1:0] storage [Share]; + logic [Width-1:0] storage_d [Share]; + always_ff @(posedge clk_i or negedge rst_n) begin + if (!rst_n) begin + storage <= '{default:'0}; + end else if (zeroize) begin + storage <= '{default:'0}; + end else if (rst_storage) begin + storage <= '{default:'0}; + end else if (update_storage) begin + storage <= storage_d; + end + end + + assign state_o = storage; + + // Storage register input + // The incoming message is XORed with the existing storage registers. + always_comb begin + storage_d = storage_datapath[RoundsPerClock]; + if (xor_message) begin + for (int j = 0 ; j < Share ; j++) begin + storage_d[j] = storage[j] ^ data_i[j]; + end // for j + end // if xor_message + end + + // Check the rst_storage integrity + logic rst_storage_error; + + always_comb begin : chk_rst_storage + rst_storage_error = 1'b 0; + + if (rst_storage) begin + // FSM should be in StIdle and clear_i should be high + if ((keccak_st != StIdle) || + abr_prim_mubi_pkg::mubi4_test_false_loose(clear_i)) begin + rst_storage_error = 1'b 1; + end + end + end : chk_rst_storage + + assign rst_storage_error_o = rst_storage_error ; + + ////////////// + // Datapath // + ////////////// + assign storage_datapath[0] = storage; + + generate + for (genvar inst_g = 0; inst_g < RoundsPerClock; inst_g++) begin : round_gen + abr_keccak_2share #( + .Width (Width), + .EnMasking (EnMasking) + ) u_keccak_p ( + .clk_i, + .rst_b, + + .rnd_i (RndW'(round+inst_g)), + .phase_sel_i (phase_sel), + .cycle_i (cycle), + .rand_aux_i (keccak_rand_aux), + .rand_i (keccak_rand_data), + .s_i (storage_datapath[inst_g]), + .s_o (storage_datapath[inst_g+1]) + ); + end + endgenerate + + // keccak entropy handling + assign rand_consumed_o = keccak_rand_consumed; + + assign keccak_rand_data = rand_data_i; + assign keccak_rand_aux = rand_aux_i; + + // Round number + // This primitive is used to place a hardened counter + // SEC_CM: CTR.REDUN + abr_prim_count #( + .Width(RndW) + ) u_round_count ( + .clk_i, + .rst_b, + .clr_i(rst_rnd_num | zeroize), + .set_i(1'b0), + .set_cnt_i('0), + .incr_en_i(inc_rnd_num), + .decr_en_i(1'b0), + .step_i(RndW'(RoundsPerClock)), + .cnt_o(round), + .cnt_next_o(), + .err_o(round_count_error_o) + ); + + // completion signal + always_ff @(posedge clk_i or negedge rst_b) begin + if (!rst_b) begin + complete_o <= 1'b 0; + end else if (zeroize) begin + complete_o <= 1'b 0; + end else begin + complete_o <= complete_d; + end + end + + //////////////// + // Assertions // + //////////////// + + // Only allow RoundsPerClock of 1-4 + `ABR_ASSERT_INIT(RoundsPerClockLTE_4_A, (RoundsPerClock > 0) && (RoundsPerClock <= 4)) + + // If `run_i` triggerred, it shall complete + //`ABR_ASSERT(RunResultComplete_A, run_i ##[MaxRound:] complete_o, clk_i, !rst_b) + + // run_i only asserted in Idle state + `ABR_ASSERT(ValidRunAssertStIdle_A, run_i |-> keccak_st == StIdle, clk_i, !rst_b) + + // clear_i is assumed to be asserted in Idle state + `ABR_ASSERT(ClearAssertStIdle_A, + abr_prim_mubi_pkg::mubi4_test_true_strict(clear_i) + |-> keccak_st == StIdle, clk_i, !rst_b) + + // EnMasking controls the valid states + if (EnMasking) begin : gen_mask_st_chk + `ABR_ASSERT(EnMaskingValidStates_A, keccak_st != StActive, clk_i, !rst_b) + end else begin : gen_unmask_st_chk + `ABR_ASSERT(UnmaskValidStates_A, !(keccak_st + inside {StPhase1, StPhase2Cycle1, StPhase2Cycle2, StPhase2Cycle3}), + clk_i, !rst_b) + end + +endmodule diff --git a/designs/Caliptra/src/adams-bridge/abr_macros.svh b/designs/Caliptra/src/adams-bridge/abr_macros.svh new file mode 100644 index 0000000..835f42c --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/abr_macros.svh @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. + +`ifndef ABR_MACROS +`define ABR_MACROS + +`endif diff --git a/designs/Caliptra/src/adams-bridge/abr_masked_A2B_conv.sv b/designs/Caliptra/src/adams-bridge/abr_masked_A2B_conv.sv new file mode 100644 index 0000000..40dd225 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/abr_masked_A2B_conv.sv @@ -0,0 +1,141 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +// +//====================================================================== +// +// Module: abr_masked_A2B_conv +// Description: This module implements a pipelined, parametric ripple-carry adder using the abr_masked_full_adder. +// It performs addition of two boolean shared inputs, producing a boolean shared output. +// +// Parameters: +// - WIDTH: Specifies the bit-width of the operands. +// +// Functionality: +// - The module performs a share conversion between arithmetic and Boolean shares. +// - It takes WIDTH+2 cycle latency +// +//====================================================================== + + module abr_masked_A2B_conv #( + parameter WIDTH = 8 // Default width is 8 bits +)( + input wire clk, // Clock signal + input wire rst_n, // Active low reset signal + input wire zeroize, // Zeroize signal + input wire [1:0] x [WIDTH-1:0], // WIDTH-bit arithmetic shares operand x + input wire [WIDTH-1:0] rnd, // Random bits for masking + input wire [WIDTH-1:0] rnd_for_Boolean0, // Random bits for masking + input wire [WIDTH-1:0] rnd_for_Boolean1, // Random bits for masking + + output logic [1:0] s [WIDTH-1:0] +); + + // Internal signals + logic [WIDTH:0] [1:0] carry; // Carry signals for each stage + logic [WIDTH-1:0] [1:0] sum; // Sum signals for each stage + logic [WIDTH-1:0][WIDTH-1:0][1:0] x_reg; // Pipeline registers for x + logic [WIDTH-1:0][WIDTH-1:0][1:0] y_reg; // Pipeline registers for y + logic [WIDTH-1:0][WIDTH-1:0][1:0] sum_reg; // Pipeline registers for sum + logic [1:0] the_last_sum; + + // Initialize the first carry input to 0 + assign carry[0] = 2'b00; + + // Generate the full adders for each bit + genvar i; + generate + for (i = 0; i < WIDTH; i = i + 1) begin : gen_full_adders + // Pipeline registers for x and y inputs + always_ff @(posedge clk or negedge rst_n) begin + if (!rst_n) begin + x_reg[i] <= '0; + y_reg[i] <= '0; + end + else if (zeroize) begin + x_reg[i] <= '0; + y_reg[i] <= '0; + end + else begin + for (int j = 0; j < WIDTH; j = j + 1) begin + if (j == 0) begin + x_reg[i][j] <= {rnd_for_Boolean0[i], (x[i][0] ^ rnd_for_Boolean0[i])}; + y_reg[i][j] <= {rnd_for_Boolean1[i], (x[i][1] ^ rnd_for_Boolean1[i])}; + end + else begin + x_reg[i][j] <= x_reg[i][j-1]; + y_reg[i][j] <= y_reg[i][j-1]; + end + end + end + end + + // Pipeline registers for sum output + always_ff @(posedge clk or negedge rst_n) begin + if (!rst_n) begin + sum_reg[i] <= '0; + end + else if (zeroize) begin + sum_reg[i] <= '0; + end + else begin + for (int j = i; j < WIDTH; j = j + 1) begin + if (j == i && i == WIDTH-1) begin + sum_reg[i][j] <= the_last_sum; + end + else if (j == i) begin + sum_reg[i][j] <= sum[i]; + end + else begin + sum_reg[i][j] <= sum_reg[i][j-1]; + end + end + end + end + if (i<(WIDTH-1)) begin : gen_masked_full_adder + // Instance of abr_masked_full_adder + abr_masked_full_adder u_abr_masked_full_adder ( + .clk(clk), // Connect clk to clk + .rst_n(rst_n), // Connect rst_n to rst_n + .zeroize(zeroize), // Connect zeroize to zeroize + .x(x_reg[i][i]), // Connect x to the last stage of the x pipeline + .y(y_reg[i][i]), // Connect y to the last stage of the y pipeline + .c_in(carry[i]), // Connect c_in to carry[i] + .rnd(rnd[i]), // Connect rnd to corresponding random bit + .s(sum[i]), // Connect sum to sum[i] + .c_out(carry[i+1]) // Connect carry out to carry[i+1] + ); + end + end + endgenerate + + always_ff @(posedge clk or negedge rst_n) begin + if (!rst_n) begin + the_last_sum <= 2'b00; + end + else if (zeroize) begin + the_last_sum <= 2'b00; + end + else begin + the_last_sum <= x_reg[WIDTH-1][WIDTH-1] ^ y_reg[WIDTH-1][WIDTH-1] ^ carry[WIDTH-1]; + end + end + + // Assign the outputs + always_comb begin + for (int i =0; i> (NUM_RD*BUFFER_DATA_W)) : buffer; + buffer_valid_shift = buffer_rd ? BUFFER_DEPTH'(buffer_valid >> NUM_RD) : buffer_valid; + + //OR together the write data and the buffer data + buffer_d = buffer_shift | buffer_wr_data_shift; + buffer_valid_d = buffer_valid_shift | buffer_wr_valid_shift; + end + + always_ff @(posedge clk or negedge rst_b) begin + if (!rst_b) begin + buffer <= '0; + buffer_valid <= '0; + end else if (update_buffer) begin + buffer <= buffer_d; + buffer_valid <= buffer_valid_d; + end + end + + //Set output valid bits + always_comb data_valid_o = buffer_valid[NUM_RD-1:0]; + always_comb data_o = buffer[NUM_RD-1:0]; + + `ABR_ASSERT(ERR_INV_STROBE, data_valid_i inside {4'b0000, 4'b0001, 4'b0011, 4'b0111, 4'b1111}, clk, !rst_b) + +endmodule \ No newline at end of file diff --git a/designs/Caliptra/src/adams-bridge/abr_ntt_add_sub_mod.sv b/designs/Caliptra/src/adams-bridge/abr_ntt_add_sub_mod.sv new file mode 100644 index 0000000..f0eb378 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/abr_ntt_add_sub_mod.sv @@ -0,0 +1,134 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +// +//====================================================================== +// +// abr_ntt_add_sub_mod.sv +// -------- +// modular addtion/subtraction module to compute opa+-opb % prime +// This is intended specifically for ntt usage, where input sizes differ for MLDSA vs MLKEM +// +//====================================================================== + +module abr_ntt_add_sub_mod + import abr_params_pkg::*; + #( + parameter REG_SIZE = 384 + ) + ( + // Clock and reset. + input wire clk, + input wire reset_n, + input wire zeroize, + + // DATA PORT + input wire add_en_i, + input wire sub_i, + input wire [REG_SIZE-1:0] opa_i, + input wire [REG_SIZE-1:0] opb_i, + input wire [REG_SIZE-1:0] prime_i, + input wire mlkem, + output logic [REG_SIZE-1:0] res_o, + output logic ready_o +); + + logic [REG_SIZE-1 : 0] opb0; + logic [REG_SIZE-1 : 0] opb1; + logic [REG_SIZE-1 : 0] r0; + logic [REG_SIZE-1 : 0] r1; + logic carry0; + logic carry0_int; + + logic sub_n; + logic [REG_SIZE-1 : 0] r0_reg; + logic carry0_reg; + + logic carry1; + logic carry1_int; + logic [1 : 0] push_result_reg; + + abr_adder #( + .RADIX(REG_SIZE) + ) + adder_inst_0( + .a_i(opa_i), + .b_i(mlkem ? {{(REG_SIZE-MLKEM_REG_SIZE){1'b0}}, opb0[MLKEM_REG_SIZE-1:0]} : opb0), + .cin_i(sub_i), + .s_o(r0), + .cout_o(carry0_int) + ); + + abr_adder #( + .RADIX(REG_SIZE) + ) + adder_inst_1( + .a_i(mlkem ? {{(REG_SIZE-MLKEM_REG_SIZE){1'b0}}, r0_reg[MLKEM_REG_SIZE-1:0]} : r0_reg), //discard carry bit (bit 12) in mlkem + .b_i(mlkem ? {{(REG_SIZE-MLKEM_REG_SIZE){1'b0}}, opb1[MLKEM_REG_SIZE-1:0]} : opb1), + .cin_i(sub_n), + .s_o(r1), + .cout_o(carry1_int) + ); + + assign carry0 = mlkem ? r0[MLKEM_REG_SIZE] : carry0_int; + assign carry1 = mlkem ? r1[MLKEM_REG_SIZE] : carry1_int; + + assign opb0 = sub_i ? ~opb_i : opb_i; + + always_ff @(posedge clk or negedge reset_n) + begin + if(!reset_n) begin + r0_reg <= '0; + carry0_reg <= '0; + sub_n <= '0; + opb1 <= '0; + end + else if (zeroize) begin + r0_reg <= '0; + carry0_reg <= '0; + sub_n <= '0; + opb1 <= '0; + end + else if (add_en_i) begin + r0_reg <= r0; + carry0_reg <= carry0; + sub_n <= !sub_i; + if (sub_i) + opb1 <= prime_i; + else + opb1 <= ~prime_i; + end + end + + // Determines when results are ready + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) + push_result_reg <= 2'b0; + else if (zeroize) + push_result_reg <= 2'b0; + else if (add_en_i) + push_result_reg <= 2'b10; + else // one shift to right + push_result_reg <= 2'(push_result_reg >> 1); + end + + assign ready_o = push_result_reg[0]; + + always_comb begin + if (mlkem) + res_o = sub_n ? (carry0_reg ^ carry1)? {{(REG_SIZE-MLKEM_REG_SIZE){1'b0}}, r1[MLKEM_REG_SIZE-1:0]} : {{(REG_SIZE-MLKEM_REG_SIZE){1'b0}}, r0_reg[MLKEM_REG_SIZE-1:0]} : (carry0_reg) ? {{(REG_SIZE-MLKEM_REG_SIZE){1'b0}}, r0_reg[MLKEM_REG_SIZE-1:0]} : {{(REG_SIZE-MLKEM_REG_SIZE){1'b0}}, r1[MLKEM_REG_SIZE-1:0]}; + else + res_o = sub_n ? (carry0_reg ^ carry1)? r1 : r0_reg : (carry0_reg) ? r0_reg : r1; + end + +endmodule diff --git a/designs/Caliptra/src/adams-bridge/abr_params_pkg.sv b/designs/Caliptra/src/adams-bridge/abr_params_pkg.sv new file mode 100644 index 0000000..596a133 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/abr_params_pkg.sv @@ -0,0 +1,123 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +// +//====================================================================== +// +// abr_params_pkg.sv +// -------- +// Common params and defines for ML-DSA 87 +// +//====================================================================== + +`ifndef ABR_PARAMS_PKG +`define ABR_PARAMS_PKG + +package abr_params_pkg; + + //---------------------------------------------------------------- + // Internal constant and parameter definitions. + //---------------------------------------------------------------- + parameter MLDSA_Q = 23'd8380417; + parameter MLDSA_Q_WIDTH = $clog2(MLDSA_Q) + 1; //24 + parameter REG_SIZE = 24; + parameter MLDSA_N = 256; + parameter MLDSA_GAMMA2 = (MLDSA_Q-1)/32; + parameter MLDSA_K = 8; + parameter [10:0][7:0] PREHASH_OID = 88'h0302040365014886600906; + + parameter MLKEM_NTT_N = 128; + parameter MLKEM_REG_SIZE = 12; + + parameter MLKEM_Q = 12'd3329; + parameter MLKEM_Q_WIDTH = $clog2(MLKEM_Q); //12 + parameter MLKEM_N = 256; + parameter MLKEM_K = 4; + parameter MLKEM_ETA = 2; + + parameter COEFF_PER_CLK = 4; + + parameter MLDSA_NUM_SHARES = 2; //set this to 1 if masking disabled + parameter MLDSA_SHARE_WIDTH = MLDSA_Q_WIDTH * MLDSA_NUM_SHARES; + + parameter MLKEM_NUM_SHARES = 2; //set this to 1 if masking disabled + parameter MLKEM_SHARE_WIDTH = MLKEM_Q_WIDTH * MLKEM_NUM_SHARES; + + //Can be 1 or 2 only + parameter ABR_NUM_NTT = 1; + + //Memory interface + parameter ABR_MEM_DATA_WIDTH = COEFF_PER_CLK * MLDSA_Q_WIDTH; //96 + parameter ABR_MEM_MASKED_DATA_WIDTH = (COEFF_PER_CLK * MLDSA_NUM_SHARES) * (MLDSA_Q_WIDTH * MLDSA_NUM_SHARES); //384 + + parameter ABR_MEM_MASKED_INST = 3; + + //parameter ABR_MEM_INST0_DEPTH = 1664; //19.5 KB + //parameter ABR_MEM_INST0_ADDR_W = $clog2(ABR_MEM_INST0_DEPTH); + parameter ABR_MEM_INST0_DEPTH = 1664/2; //9.75 KB + parameter ABR_MEM_INST0_ADDR_W = $clog2(ABR_MEM_INST0_DEPTH); + parameter ABR_MEM_INST0_DATA_W = ABR_MEM_DATA_WIDTH; + parameter ABR_MEM_INST1_DEPTH = 576; //6.75 KB + parameter ABR_MEM_INST1_ADDR_W = $clog2(ABR_MEM_INST1_DEPTH); + parameter ABR_MEM_INST1_DATA_W = ABR_MEM_DATA_WIDTH; + parameter ABR_MEM_INST2_DEPTH = 1472; //17.25 KB + parameter ABR_MEM_INST2_ADDR_W = $clog2(ABR_MEM_INST2_DEPTH); + parameter ABR_MEM_INST2_DATA_W = ABR_MEM_DATA_WIDTH; + parameter ABR_MEM_INST3_DEPTH = 64; //3 KB + parameter ABR_MEM_INST3_ADDR_W = $clog2(ABR_MEM_INST3_DEPTH); + parameter ABR_MEM_INST3_DATA_W = ABR_MEM_MASKED_DATA_WIDTH; + parameter ABR_MEM_W1_DEPTH = 512; + parameter ABR_MEM_W1_ADDR_W = $clog2(ABR_MEM_W1_DEPTH); + parameter ABR_MEM_W1_DATA_W = 4; + + parameter ABR_MEM_MAX_DEPTH = ABR_MEM_INST2_DEPTH; + parameter ABR_MEM_ADDR_WIDTH = $clog2(ABR_MEM_MAX_DEPTH) + 3; //+ 3 bits for bank selection + + typedef enum logic [2:0] { + MLDSA_NONE = 3'b000, + MLDSA_KEYGEN = 3'b001, + MLDSA_SIGN = 3'b010, + MLDSA_VERIFY = 3'b011, + MLDSA_KEYGEN_SIGN = 3'b100 + } mldsa_cmd_e; + + typedef enum logic [2:0] { + MLKEM_NONE = 3'b000, + MLKEM_KEYGEN = 3'b001, + MLKEM_ENCAPS = 3'b010, + MLKEM_DECAPS = 3'b011, + MLKEM_KEYGEN_DEC = 3'b100 + } mlkem_cmd_e; + + parameter [63 : 0] MLDSA_CORE_NAME = 64'h3837412D_44534D4C; // "MLDSA-87" + parameter [63 : 0] MLDSA_CORE_VERSION = 64'h00000000_3030312e; // "1.00" + parameter [63 : 0] MLKEM_CORE_NAME = 64'h32343130_4D2D4B45; // "KEM-1024" + parameter [63 : 0] MLKEM_CORE_VERSION = 64'h00000000_3030312e; // "1.00" + + // Implementation parameters + parameter DATA_WIDTH = 32; + + //Common structs + typedef enum logic [1:0] {RW_IDLE = 2'b00, RW_READ = 2'b01, RW_WRITE = 2'b10} mem_rw_mode_e; + + typedef struct packed { + mem_rw_mode_e rd_wr_en; + logic [ABR_MEM_ADDR_WIDTH-1:0] addr; + } mem_if_t; + +endpackage + +`endif +//====================================================================== +// EOF abr_params_pkg.sv +//====================================================================== diff --git a/designs/Caliptra/src/adams-bridge/abr_piso.sv b/designs/Caliptra/src/adams-bridge/abr_piso.sv new file mode 100644 index 0000000..29a45f0 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/abr_piso.sv @@ -0,0 +1,108 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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 sibress or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// PISO supports 1 mode of operation + +module abr_piso + #( parameter PISO_BUFFER_W = 1344 + ,parameter PISO_PTR_W = $clog2(PISO_BUFFER_W) + ,parameter PISO_INPUT_RATE = 1088 + ,parameter PISO_OUTPUT_RATE = 80 + ) + ( + input logic clk, + input logic rst_b, + input logic zeroize, + + //input data + input logic valid_i, + output logic hold_o, + input logic [PISO_INPUT_RATE-1:0] data_i, + + //Output data + output logic valid_o, + input logic hold_i, + output logic [PISO_OUTPUT_RATE-1:0] data_o + + ); + parameter BUFFER_W_DELTA = PISO_BUFFER_W - PISO_INPUT_RATE; + + logic [PISO_BUFFER_W-1:0] buffer, buffer_d; + logic [PISO_PTR_W-1:0] buffer_wr_ptr, buffer_wr_ptr_d; + + logic [PISO_PTR_W-1:0] current_input_rate, current_output_rate; + + logic buffer_wr, buffer_rd; + logic update_buffer; + + always_comb current_input_rate = PISO_INPUT_RATE; + always_comb current_output_rate = PISO_OUTPUT_RATE; + + //hold when not enough room for full input data + always_comb hold_o = buffer_wr_ptr > (PISO_BUFFER_W[PISO_PTR_W-1:0] - current_input_rate); + + always_comb data_o = buffer[PISO_OUTPUT_RATE-1:0]; + always_comb valid_o = buffer_wr_ptr >= current_output_rate; + + always_comb buffer_wr = valid_i & ~hold_o; + always_comb buffer_rd = valid_o & ~hold_i; + always_comb update_buffer = buffer_rd | buffer_wr; + + //storage element + always_ff @(posedge clk or negedge rst_b) begin + if (!rst_b) begin + buffer <= '0; + buffer_wr_ptr <= '0; + end else if (zeroize) begin + buffer <= '0; + buffer_wr_ptr <= '0; + end else if (update_buffer) begin + buffer <= buffer_d; + buffer_wr_ptr <= buffer_wr_ptr_d; + end + end + + //write pointer control + always_comb begin + unique case ({buffer_rd, buffer_wr}) + 2'b00 : buffer_wr_ptr_d = buffer_wr_ptr; + 2'b01 : buffer_wr_ptr_d = buffer_wr_ptr + current_input_rate; + 2'b10 : buffer_wr_ptr_d = buffer_wr_ptr - current_output_rate; + 2'b11 : buffer_wr_ptr_d = buffer_wr_ptr + (current_input_rate - current_output_rate); + default : buffer_wr_ptr_d = buffer_wr_ptr; + endcase + end + + logic [PISO_BUFFER_W-1:0] buffer_wdata; + logic [PISO_BUFFER_W-1:0] buffer_wdata_mask; + + always_comb begin + buffer_wdata = '0; + buffer_wdata_mask = '1; + buffer_wdata_mask = PISO_BUFFER_W'(buffer_wdata_mask >> (PISO_BUFFER_W[PISO_PTR_W-1:0] - current_input_rate)); + buffer_wdata = {{BUFFER_W_DELTA{1'b0}},data_i} & buffer_wdata_mask; + end + + //buffer next logic + always_comb begin + unique case ({buffer_rd, buffer_wr}) + 2'b00 : buffer_d = buffer; + 2'b10 : buffer_d = PISO_BUFFER_W'(buffer >> current_output_rate); + 2'b01 : buffer_d = PISO_BUFFER_W'(buffer_wdata << buffer_wr_ptr) | buffer; + 2'b11 : buffer_d = PISO_BUFFER_W'(buffer_wdata << (buffer_wr_ptr - current_output_rate)) | PISO_BUFFER_W'(buffer >> current_output_rate); + default : buffer_d = buffer; + endcase + end + +endmodule diff --git a/designs/Caliptra/src/adams-bridge/abr_piso_multi.sv b/designs/Caliptra/src/adams-bridge/abr_piso_multi.sv new file mode 100644 index 0000000..882a918 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/abr_piso_multi.sv @@ -0,0 +1,110 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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 sibress or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// PISO supports multiple modes of operation, each with unique input and output rates + +module abr_piso_multi #( + parameter int NUM_MODES = 5, + parameter int PISO_BUFFER_W = 1344, + parameter int PISO_PTR_W = $clog2(PISO_BUFFER_W), + parameter int PISO_ACT_INPUT_RATE = 1088, + parameter int PISO_ACT_OUTPUT_RATE = 80, + parameter int INPUT_RATES [NUM_MODES] = '{1088, 1088, 1088, 1088, 1088}, + parameter int OUTPUT_RATES[NUM_MODES] = '{80, 80, 80, 80, 80} +)( + input logic clk, + input logic rst_b, + input logic zeroize, + input logic [$clog2(NUM_MODES)-1:0] mode, + input logic valid_i, + output logic hold_o, + input logic [PISO_ACT_INPUT_RATE-1:0] data_i, + output logic valid_o, + input logic hold_i, + output logic [PISO_ACT_OUTPUT_RATE-1:0] data_o +); + + localparam BUFFER_W_DELTA = PISO_BUFFER_W - PISO_ACT_INPUT_RATE; + + logic [PISO_BUFFER_W-1:0] buffer, buffer_d; + logic [PISO_PTR_W-1:0] buffer_wr_ptr, buffer_wr_ptr_d; + logic [PISO_PTR_W-1:0] current_input_rate, current_output_rate; + + logic buffer_wr, buffer_rd; + logic update_buffer; + + // Select input/output rates based on mode + always_comb begin + current_input_rate = INPUT_RATES[mode][PISO_PTR_W-1:0]; + current_output_rate = OUTPUT_RATES[mode][PISO_PTR_W-1:0]; + end + + // Flow control + always_comb hold_o = buffer_wr_ptr > (PISO_BUFFER_W[PISO_PTR_W-1:0] - current_input_rate); + always_comb data_o = buffer[PISO_ACT_OUTPUT_RATE-1:0]; + always_comb valid_o = buffer_wr_ptr >= current_output_rate; + + always_comb buffer_wr = valid_i & ~hold_o; + always_comb buffer_rd = valid_o & ~hold_i; + always_comb update_buffer = buffer_rd | buffer_wr; + + // Storage element + always_ff @(posedge clk or negedge rst_b) begin + if (!rst_b) begin + buffer <= '0; + buffer_wr_ptr <= '0; + end else if (zeroize) begin + buffer <= '0; + buffer_wr_ptr <= '0; + end else if (update_buffer) begin + buffer <= buffer_d; + buffer_wr_ptr <= buffer_wr_ptr_d; + end + end + + // Write pointer control + always_comb begin + unique case ({buffer_rd, buffer_wr}) + 2'b00 : buffer_wr_ptr_d = buffer_wr_ptr; + 2'b01 : buffer_wr_ptr_d = buffer_wr_ptr + current_input_rate; + 2'b10 : buffer_wr_ptr_d = buffer_wr_ptr - current_output_rate; + 2'b11 : buffer_wr_ptr_d = buffer_wr_ptr + (current_input_rate - current_output_rate); + default : buffer_wr_ptr_d = buffer_wr_ptr; + endcase + end + + // Write data and mask + logic [PISO_BUFFER_W-1:0] buffer_wdata; + logic [PISO_BUFFER_W-1:0] buffer_wdata_mask; + + always_comb begin + buffer_wdata = '0; + buffer_wdata_mask = '1; + buffer_wdata_mask = PISO_BUFFER_W'(buffer_wdata_mask >> (PISO_BUFFER_W[PISO_PTR_W-1:0] - current_input_rate)); + buffer_wdata = {{BUFFER_W_DELTA{1'b0}}, data_i} & buffer_wdata_mask; + end + + // Buffer update logic + always_comb begin + unique case ({buffer_rd, buffer_wr}) + 2'b00 : buffer_d = buffer; + 2'b10 : buffer_d = PISO_BUFFER_W'(buffer >> current_output_rate); + 2'b01 : buffer_d = PISO_BUFFER_W'(buffer_wdata << buffer_wr_ptr) | buffer; + 2'b11 : buffer_d = PISO_BUFFER_W'(buffer_wdata << (buffer_wr_ptr - current_output_rate)) | + PISO_BUFFER_W'(buffer >> current_output_rate); + default : buffer_d = buffer; + endcase + end + +endmodule diff --git a/designs/Caliptra/src/adams-bridge/abr_prim_alert_pkg.sv b/designs/Caliptra/src/adams-bridge/abr_prim_alert_pkg.sv new file mode 100644 index 0000000..dbd50c2 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/abr_prim_alert_pkg.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 + +package abr_prim_alert_pkg; + + parameter int NumAlerts = 3; + + typedef struct packed { + logic alert_p; + logic alert_n; + } alert_tx_t; + + typedef struct packed { + logic ping_p; + logic ping_n; + logic ack_p; + logic ack_n; + } alert_rx_t; + + parameter alert_tx_t ALERT_TX_DEFAULT = '{alert_p: 1'b0, + alert_n: 1'b1}; + + parameter alert_rx_t ALERT_RX_DEFAULT = '{ping_p: 1'b0, + ping_n: 1'b1, + ack_p: 1'b0, + ack_n: 1'b1}; + +endpackage : abr_prim_alert_pkg diff --git a/designs/Caliptra/src/adams-bridge/abr_prim_alert_receiver.sv b/designs/Caliptra/src/adams-bridge/abr_prim_alert_receiver.sv new file mode 100644 index 0000000..26078fb --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/abr_prim_alert_receiver.sv @@ -0,0 +1,386 @@ +// Copyright lowRISC contributors. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// The alert receiver primitive decodes alerts that have been differentially +// encoded and transmitted via a handshake protocol on alert_p/n and +// ack_p/n. In case an alert handshake is initiated, the output alert_o will +// immediately be asserted (even before completion of the handshake). +// +// In case the differential input is not correctly encoded, this module will +// raise an error by asserting integ_fail_o. +// +// Further, the module supports ping testing of the alert diff pair. In order to +// initiate a ping test, ping_req_i shall be set to 1'b1 until ping_ok_o is +// asserted for one cycle. The signal may be de-asserted (e.g. after a long) +// timeout period. However note that all ping responses that come in after +// deasserting ping_req_i will be treated as native alerts. +// +// The protocol works in both asynchronous and synchronous cases. In the +// asynchronous case, the parameter AsyncOn must be set to 1'b1 in order to +// instantiate additional synchronization logic. Further, it must be ensured +// that the timing skew between all diff pairs is smaller than the shortest +// clock period of the involved clocks. +// +// Note that in case of synchronous operation, alerts on the diffpair are +// decoded combinationally and forwarded on alert_o within the same cycle. +// +// See also: abr_prim_alert_sender, abr_prim_diff_decode, alert_handler + +`include "abr_prim_assert.sv" + +module abr_prim_alert_receiver + import abr_prim_alert_pkg::*; + import abr_prim_mubi_pkg::mubi4_t; +#( + // enables additional synchronization logic + parameter bit AsyncOn = 1'b0 +) ( + input clk_i, + input rst_b, + // if set to lc_ctrl_pkg::On, this triggers the in-band alert channel + // reset, which resets both the sender and receiver FSMs into IDLE. + input mubi4_t init_trig_i, + // this triggers a ping test. keep asserted + // until ping_ok_o is asserted. + input ping_req_i, + output logic ping_ok_o, + // asserted if signal integrity issue detected + output logic integ_fail_o, + // alert output (pulsed high) if a handshake is initiated + // on alert_p/n and no ping request is outstanding + output logic alert_o, + // ping input diff pair and ack diff pair + output alert_rx_t alert_rx_o, + // alert output diff pair + input alert_tx_t alert_tx_i +); + + import abr_prim_mubi_pkg::mubi4_test_true_strict; + + ///////////////////////////////// + // decode differential signals // + ///////////////////////////////// + logic alert_level, alert_sigint, alert_p, alert_n; + + // This prevents further tool optimizations of the differential signal. + abr_prim_sec_anchor_buf #( + .Width(2) + ) u_abr_prim_buf_in ( + .in_i({alert_tx_i.alert_n, + alert_tx_i.alert_p}), + .out_o({alert_n, + alert_p}) + ); + + abr_prim_diff_decode #( + .AsyncOn(AsyncOn) + ) u_decode_alert ( + .clk_i, + .rst_b, + .diff_pi ( alert_p ), + .diff_ni ( alert_n ), + .level_o ( alert_level ), + .rise_o ( ), + .fall_o ( ), + .event_o ( ), + .sigint_o ( alert_sigint ) + ); + + ///////////////////////////////////////////////////// + // main protocol FSM that drives the diff outputs // + ///////////////////////////////////////////////////// + typedef enum logic [2:0] {Idle, HsAckWait, Pause0, Pause1, InitReq, InitAckWait} state_e; + state_e state_d, state_q; + logic ping_rise; + logic ping_tog_pd, ping_tog_pq, ping_tog_dn, ping_tog_nq; + logic ack_pd, ack_pq, ack_dn, ack_nq; + logic ping_req_d, ping_req_q; + logic ping_pending_d, ping_pending_q; + logic send_init; + logic send_ping; + + // signal ping request upon positive transition on ping_req_i + // signalling is performed by a level change event on the diff output + assign ping_req_d = ping_req_i; + assign ping_rise = ping_req_d && !ping_req_q; + assign ping_tog_pd = (send_init) ? 1'b0 : + (send_ping) ? ~ping_tog_pq : ping_tog_pq; + + // in-band reset is performed by sending out an integrity error on purpose. + assign ack_dn = (send_init) ? ack_pd : ~ack_pd; + assign ping_tog_dn = ~ping_tog_pd; + + // This prevents further tool optimizations of the differential signal. + abr_prim_sec_anchor_flop #( + .Width (2), + .ResetValue(2'b10) + ) u_abr_prim_generic_flop_ack ( + .clk_i, + .rst_b, + .d_i({ack_dn, + ack_pd}), + .q_o({ack_nq, + ack_pq}) + ); + + abr_prim_sec_anchor_flop #( + .Width (2), + .ResetValue(2'b10) + ) u_abr_prim_generic_flop_ping ( + .clk_i, + .rst_b, + .d_i({ping_tog_dn, + ping_tog_pd}), + .q_o({ping_tog_nq, + ping_tog_pq}) + ); + + // the ping pending signal is used in the FSM to distinguish whether the + // incoming handshake shall be treated as an alert or a ping response. + // it is important that this is only set on a rising ping_en level change, since + // otherwise the ping enable signal could be abused to "mask" all native alerts + // as ping responses by constantly tying it to 1. + assign ping_pending_d = ping_rise | ((~ping_ok_o) & ping_req_i & ping_pending_q); + + // diff pair outputs + assign alert_rx_o.ack_p = ack_pq; + assign alert_rx_o.ack_n = ack_nq; + + assign alert_rx_o.ping_p = ping_tog_pq; + assign alert_rx_o.ping_n = ping_tog_nq; + + // this FSM receives the four phase handshakes from the alert receiver + // note that the latency of the alert_p/n input diff pair is at least one + // cycle until it enters the receiver FSM. the same holds for the ack_* diff + // pair outputs. + always_comb begin : p_fsm + // default + state_d = state_q; + ack_pd = 1'b0; + ping_ok_o = 1'b0; + integ_fail_o = 1'b0; + alert_o = 1'b0; + send_init = 1'b0; + // by default, a ping request leads to a toogle on the differential ping pair + send_ping = ping_rise; + + unique case (state_q) + Idle: begin + // wait for handshake to be initiated + if (alert_level) begin + state_d = HsAckWait; + ack_pd = 1'b1; + // signal either an alert or ping received on the output + if (ping_pending_q) begin + ping_ok_o = 1'b1; + end else begin + alert_o = 1'b1; + end + end + end + // waiting for deassertion of alert to complete HS + HsAckWait: begin + if (!alert_level) begin + state_d = Pause0; + end else begin + ack_pd = 1'b1; + end + end + // pause cycles between back-to-back handshakes + Pause0: state_d = Pause1; + Pause1: state_d = Idle; + // this state is only reached if an in-band reset is + // requested via the low-power logic. + InitReq: begin + // we deliberately place a sigint error on the ack and ping lines in this case. + send_init = 1'b1; + // suppress any toggles on the ping line while we are in the init phase. + send_ping = 1'b0; + // As long as init req is asserted, we remain in this state and acknowledge all incoming + // ping requests. As soon as the init request is dropped however, ping requests are not + // acked anymore such that the ping mechanism can also flag alert channels that got stuck + // in the initialization sequence. + if (mubi4_test_true_strict(init_trig_i)) begin + ping_ok_o = ping_pending_q; + // the sender will respond to the sigint error above with a sigint error on the alert lines. + // hence we treat the alert_sigint like an acknowledgement in this case. + end else if (alert_sigint) begin + state_d = InitAckWait; + end + end + // We get here if the sender has responded with alert_sigint, and init_trig_i==lc_ctrl_pkg::On + // has been deasserted. At this point, we need to wait for the alert_sigint to drop again + // before resuming normal operation. + InitAckWait: begin + // suppress any toggles on the ping line while we are in the init phase. + send_ping = 1'b0; + if (!alert_sigint) begin + state_d = Pause0; + // If we get a ping request in this cycle, or if we realize that there is an unhandled + // ping request that came in during initialization (but after init_trig_i has been + // deasserted), we signal this to the alert sender by toggling the request line. + send_ping = ping_rise || ping_pending_q; + end + end + default: state_d = Idle; + endcase + + // once the initialization sequence has been triggered, + // overrides are not allowed anymore until the initialization has been completed. + if (!(state_q inside {InitReq, InitAckWait})) begin + // in this case, abort and jump into the initialization sequence + if (mubi4_test_true_strict(init_trig_i)) begin + state_d = InitReq; + ack_pd = 1'b0; + ping_ok_o = 1'b0; + integ_fail_o = 1'b0; + alert_o = 1'b0; + send_init = 1'b1; + // if we're not busy with an init request, we clamp down all outputs + // and indicate an integrity failure. + end else if (alert_sigint) begin + state_d = Idle; + ack_pd = 1'b0; + ping_ok_o = 1'b0; + integ_fail_o = 1'b1; + alert_o = 1'b0; + end + end + end + + always_ff @(posedge clk_i or negedge rst_b) begin : p_reg + if (!rst_b) begin + // Reset into the init request so that an alert handler reset implicitly + // triggers an in-band reset of all alert channels. + state_q <= InitReq; + ping_req_q <= 1'b0; + ping_pending_q <= 1'b0; + end else begin + state_q <= state_d; + ping_req_q <= ping_req_d; + ping_pending_q <= ping_pending_d; + end + end + + + //////////////// + // assertions // + //////////////// + +`ifdef ABR_INC_ASSERT + import abr_prim_mubi_pkg::mubi4_test_false_loose; +`endif + + // check whether all outputs have a good known state after reset + `ABR_ASSERT_KNOWN(PingOkKnownO_A, ping_ok_o) + `ABR_ASSERT_KNOWN(IntegFailKnownO_A, integ_fail_o) + `ABR_ASSERT_KNOWN(AlertKnownO_A, alert_o) + `ABR_ASSERT_KNOWN(PingPKnownO_A, alert_rx_o) + + // check encoding of outgoing diffpairs. note that during init, the outgoing diffpairs are + // supposed to be incorrectly encoded on purpose. + // shift sequence two cycles to the right to avoid reset effects. + `ABR_ASSERT(PingDiffOk_A, alert_rx_o.ping_p ^ alert_rx_o.ping_n) + `ABR_ASSERT(AckDiffOk_A, ##2 $past(send_init) ^ alert_rx_o.ack_p ^ alert_rx_o.ack_n) + `ABR_ASSERT(InitReq_A, mubi4_test_true_strict(init_trig_i) && + !(state_q inside {InitReq, InitAckWait}) |=> send_init) + + // ping request at input -> need to see encoded ping request + `ABR_ASSERT(PingRequest0_A, ##1 $rose(ping_req_i) && !state_q inside {InitReq, InitAckWait} + |=> $changed(alert_rx_o.ping_p)) + // ping response implies it has been requested + `ABR_ASSERT(PingResponse0_A, ping_ok_o |-> ping_pending_q) + // correctly latch ping request + `ABR_ASSERT(PingPending_A, ##1 $rose(ping_req_i) |=> ping_pending_q) + + if (AsyncOn) begin : gen_async_assert + // signal integrity check propagation + `ABR_ASSERT(SigInt_A, + alert_tx_i.alert_p == alert_tx_i.alert_n [*2] ##2 + !(state_q inside {InitReq, InitAckWait}) && + mubi4_test_false_loose(init_trig_i) + |-> + integ_fail_o) + // TODO: need to add skewed cases as well, the assertions below assume no skew at the moment + // ping response + `ABR_ASSERT(PingResponse1_A, + ##1 $rose(alert_tx_i.alert_p) && + (alert_tx_i.alert_p ^ alert_tx_i.alert_n) ##2 + state_q == Idle && ping_pending_q + |-> + ping_ok_o, + clk_i, !rst_b || integ_fail_o || mubi4_test_true_strict(init_trig_i)) + // alert + `ABR_ASSERT(Alert_A, + ##1 $rose(alert_tx_i.alert_p) && + (alert_tx_i.alert_p ^ alert_tx_i.alert_n) ##2 + state_q == Idle && + !ping_pending_q + |-> + alert_o, + clk_i, !rst_b || integ_fail_o || mubi4_test_true_strict(init_trig_i)) + end else begin : gen_sync_assert + // signal integrity check propagation + `ABR_ASSERT(SigInt_A, + alert_tx_i.alert_p == alert_tx_i.alert_n && + !(state_q inside {InitReq, InitAckWait}) && + mubi4_test_false_loose(init_trig_i) + |-> + integ_fail_o) + // ping response + `ABR_ASSERT(PingResponse1_A, + ##1 $rose(alert_tx_i.alert_p) && + state_q == Idle && + ping_pending_q + |-> + ping_ok_o, + clk_i, !rst_b || integ_fail_o || mubi4_test_true_strict(init_trig_i)) + // alert + `ABR_ASSERT(Alert_A, + ##1 $rose(alert_tx_i.alert_p) && + state_q == Idle && + !ping_pending_q + |-> + alert_o, + clk_i, !rst_b || integ_fail_o || mubi4_test_true_strict(init_trig_i)) + end + + // check in-band init request is always accepted + `ABR_ASSERT(InBandInitRequest_A, + mubi4_test_true_strict(init_trig_i) && + state_q != InitAckWait + |=> + state_q == InitReq) + // check in-band init sequence moves FSM into IDLE state + `ABR_ASSERT(InBandInitSequence_A, + (state_q == InitReq && + mubi4_test_true_strict(init_trig_i)) ##1 + (alert_sigint && + mubi4_test_false_loose(init_trig_i)) [*1:$] ##1 + (!alert_sigint && + mubi4_test_false_loose(init_trig_i)) [*3] + |=> + state_q == Idle) + // check there are no spurious alerts during init + `ABR_ASSERT(NoSpuriousAlertsDuringInit_A, + mubi4_test_true_strict(init_trig_i) || + (state_q inside {InitReq, InitAckWait}) + |-> + !alert_o) + // check that there are no spurious ping OKs + `ABR_ASSERT(NoSpuriousPingOksDuringInit_A, + (mubi4_test_true_strict(init_trig_i) || + (state_q inside {InitReq, InitAckWait})) && + !ping_pending_q + |-> + !ping_ok_o) + // check ping request is bypassed when in init state + `ABR_ASSERT(PingOkBypassDuringInit_A, + $rose(ping_req_i) ##1 + state_q == InitReq && + mubi4_test_true_strict(init_trig_i) + |-> + ping_ok_o) + +endmodule : abr_prim_alert_receiver diff --git a/designs/Caliptra/src/adams-bridge/abr_prim_alert_sender.sv b/designs/Caliptra/src/adams-bridge/abr_prim_alert_sender.sv new file mode 100644 index 0000000..7c90315 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/abr_prim_alert_sender.sv @@ -0,0 +1,392 @@ +// Copyright lowRISC contributors. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// The alert sender primitive module differentially encodes and transmits an +// alert signal to the abr_prim_alert_receiver module. An alert will be signalled +// by a full handshake on alert_p/n and ack_p/n. The alert_req_i signal may +// be continuously asserted, in which case the alert signalling handshake +// will be repeatedly initiated. +// +// The alert_req_i signal may also be used as part of req/ack. The parent module +// can keep alert_req_i asserted until it has been ack'd (transferred to the alert +// receiver). The parent module is not required to use this. +// +// In case the alert sender parameter IsFatal is set to 1, an incoming alert +// alert_req_i is latched in a local register until the next reset, causing the +// alert sender to behave as if alert_req_i were continously asserted. +// The alert_state_o output reflects the state of this internal latching register. +// +// The alert sender also exposes an alert test input, which can be used to trigger +// single alert handshakes. This input behaves exactly the same way as the +// alert_req_i input with IsFatal set to 0. Test alerts do not cause alert_ack_o +// to be asserted, nor are they latched until reset (regardless of the value of the +// IsFatal parameter). +// +// Further, this module supports in-band ping testing, which means that a level +// change on the ping_p/n diff pair will result in a full-handshake response +// on alert_p/n and ack_p/n. +// +// The protocol works in both asynchronous and synchronous cases. In the +// asynchronous case, the parameter AsyncOn must be set to 1'b1 in order to +// instantiate additional synchronization logic. Further, it must be ensured +// that the timing skew between all diff pairs is smaller than the shortest +// clock period of the involved clocks. +// +// Incorrectly encoded diff inputs can be detected and will be signalled +// to the receiver by placing an inconsistent diff value on the differential +// output (and continuously toggling it). +// +// See also: abr_prim_alert_receiver, abr_prim_diff_decode, alert_handler + +`include "abr_prim_assert.sv" + +module abr_prim_alert_sender + import abr_prim_alert_pkg::*; +#( + // enables additional synchronization logic + parameter bit AsyncOn = 1'b1, + // alert sender will latch the incoming alert event permanently and + // keep on sending alert events until the next reset. + parameter bit IsFatal = 1'b0 +) ( + input clk_i, + input rst_b, + // alert test trigger (this will never be latched, even if IsFatal == 1) + input alert_test_i, + // native alert from the peripheral + input alert_req_i, + output logic alert_ack_o, + // state of the alert latching register + output logic alert_state_o, + // ping input diff pair and ack diff pair + input alert_rx_t alert_rx_i, + // alert output diff pair + output alert_tx_t alert_tx_o +); + + + ///////////////////////////////// + // decode differential signals // + ///////////////////////////////// + logic ping_sigint, ping_event, ping_n, ping_p; + + // This prevents further tool optimizations of the differential signal. + abr_prim_sec_anchor_buf #( + .Width(2) + ) u_abr_prim_buf_ping ( + .in_i({alert_rx_i.ping_n, + alert_rx_i.ping_p}), + .out_o({ping_n, + ping_p}) + ); + + abr_prim_diff_decode #( + .AsyncOn(AsyncOn) + ) u_decode_ping ( + .clk_i, + .rst_b, + .diff_pi ( ping_p ), + .diff_ni ( ping_n ), + .level_o ( ), + .rise_o ( ), + .fall_o ( ), + .event_o ( ping_event ), + .sigint_o ( ping_sigint ) + ); + + logic ack_sigint, ack_level, ack_n, ack_p; + + // This prevents further tool optimizations of the differential signal. + abr_prim_sec_anchor_buf #( + .Width(2) + ) u_abr_prim_buf_ack ( + .in_i({alert_rx_i.ack_n, + alert_rx_i.ack_p}), + .out_o({ack_n, + ack_p}) + ); + + abr_prim_diff_decode #( + .AsyncOn(AsyncOn) + ) u_decode_ack ( + .clk_i, + .rst_b, + .diff_pi ( ack_p ), + .diff_ni ( ack_n ), + .level_o ( ack_level ), + .rise_o ( ), + .fall_o ( ), + .event_o ( ), + .sigint_o ( ack_sigint ) + ); + + + /////////////////////////////////////////////////// + // main protocol FSM that drives the diff output // + /////////////////////////////////////////////////// + typedef enum logic [2:0] { + Idle, + AlertHsPhase1, + AlertHsPhase2, + PingHsPhase1, + PingHsPhase2, + Pause0, + Pause1 + } state_e; + state_e state_d, state_q; + logic alert_pq, alert_nq, alert_pd, alert_nd; + logic sigint_detected; + + assign sigint_detected = ack_sigint | ping_sigint; + + + // diff pair output + assign alert_tx_o.alert_p = alert_pq; + assign alert_tx_o.alert_n = alert_nq; + + // alert and ping set regs + logic alert_set_d, alert_set_q, alert_clr; + logic alert_test_set_d, alert_test_set_q; + logic ping_set_d, ping_set_q, ping_clr; + logic alert_req_trigger, alert_test_trigger, ping_trigger; + + // if handshake is ongoing, capture additional alert requests. + logic alert_req; + abr_prim_sec_anchor_buf #( + .Width(1) + ) u_abr_prim_buf_in_req ( + .in_i(alert_req_i), + .out_o(alert_req) + ); + + assign alert_req_trigger = alert_req | alert_set_q; + if (IsFatal) begin : gen_fatal + assign alert_set_d = alert_req_trigger; + end else begin : gen_recov + assign alert_set_d = (alert_clr) ? 1'b0 : alert_req_trigger; + end + + // the alert test request is always cleared. + assign alert_test_trigger = alert_test_i | alert_test_set_q; + assign alert_test_set_d = (alert_clr) ? 1'b0 : alert_test_trigger; + + logic alert_trigger; + assign alert_trigger = alert_req_trigger | alert_test_trigger; + + assign ping_trigger = ping_set_q | ping_event; + assign ping_set_d = (ping_clr) ? 1'b0 : ping_trigger; + + + // alert event acknowledge and state (not affected by alert_test_i) + assign alert_ack_o = alert_clr & alert_set_q; + assign alert_state_o = alert_set_q; + + // this FSM performs a full four phase handshake upon a ping or alert trigger. + // note that the latency of the alert_p/n diff pair is at least one cycle + // until it enters the receiver FSM. the same holds for the ack_* diff pair + // input. in case a signal integrity issue is detected, the FSM bails out, + // sets the alert_p/n diff pair to the same value and toggles it in order to + // signal that condition over to the receiver. + always_comb begin : p_fsm + // default + state_d = state_q; + alert_pd = 1'b0; + alert_nd = 1'b1; + ping_clr = 1'b0; + alert_clr = 1'b0; + + unique case (state_q) + Idle: begin + // alert always takes precedence + if (alert_trigger || ping_trigger) begin + state_d = (alert_trigger) ? AlertHsPhase1 : PingHsPhase1; + alert_pd = 1'b1; + alert_nd = 1'b0; + end + end + // waiting for ack from receiver + AlertHsPhase1: begin + if (ack_level) begin + state_d = AlertHsPhase2; + end else begin + alert_pd = 1'b1; + alert_nd = 1'b0; + end + end + // wait for deassertion of ack + AlertHsPhase2: begin + if (!ack_level) begin + state_d = Pause0; + alert_clr = 1'b1; + end + end + // waiting for ack from receiver + PingHsPhase1: begin + if (ack_level) begin + state_d = PingHsPhase2; + end else begin + alert_pd = 1'b1; + alert_nd = 1'b0; + end + end + // wait for deassertion of ack + PingHsPhase2: begin + if (!ack_level) begin + ping_clr = 1'b1; + state_d = Pause0; + end + end + // pause cycles between back-to-back handshakes + Pause0: begin + state_d = Pause1; + end + // clear and ack alert request if it was set + Pause1: begin + state_d = Idle; + end + // catch parasitic states + default : state_d = Idle; + endcase + + // we have a signal integrity issue at one of the incoming diff pairs. this condition is + // signalled by setting the output diffpair to zero. If the sigint has disappeared, we clear + // the ping request state of this sender and go back to idle. + if (sigint_detected) begin + state_d = Idle; + alert_pd = 1'b0; + alert_nd = 1'b0; + ping_clr = 1'b1; + alert_clr = 1'b0; + end + end + + // This prevents further tool optimizations of the differential signal. + abr_prim_sec_anchor_flop #( + .Width (2), + .ResetValue(2'b10) + ) u_abr_prim_flop_alert ( + .clk_i, + .rst_b, + .d_i({alert_nd, alert_pd}), + .q_o({alert_nq, alert_pq}) + ); + + always_ff @(posedge clk_i or negedge rst_b) begin : p_reg + if (!rst_b) begin + state_q <= Idle; + alert_set_q <= 1'b0; + alert_test_set_q <= 1'b0; + ping_set_q <= 1'b0; + end else begin + state_q <= state_d; + alert_set_q <= alert_set_d; + alert_test_set_q <= alert_test_set_d; + ping_set_q <= ping_set_d; + end + end + + + //////////////// + // assertions // + //////////////// + +// however, since we use sequence constructs below, we need to wrap the entire block again. +// typically, the ABR_ASSERT macros already contain this ABR_INC_ASSERT macro. +`ifdef ABR_INC_ASSERT + // check whether all outputs have a good known state after reset + `ABR_ASSERT_KNOWN(AlertPKnownO_A, alert_tx_o) + + if (AsyncOn) begin : gen_async_assert + sequence PingSigInt_S; + alert_rx_i.ping_p == alert_rx_i.ping_n [*2]; + endsequence + sequence AckSigInt_S; + alert_rx_i.ping_p == alert_rx_i.ping_n [*2]; + endsequence + + `ifndef FPV_ALERT_NO_SIGINT_ERR + // check propagation of sigint issues to output within three cycles + // shift sequence to the right to avoid reset effects. + `ABR_ASSERT(SigIntPing_A, ##1 PingSigInt_S |-> + ##3 alert_tx_o.alert_p == alert_tx_o.alert_n) + `ABR_ASSERT(SigIntAck_A, ##1 AckSigInt_S |-> + ##3 alert_tx_o.alert_p == alert_tx_o.alert_n) + `endif + + // Test in-band FSM reset request (via signal integrity error) + `ABR_ASSERT(InBandInitFsm_A, PingSigInt_S or AckSigInt_S |-> ##3 state_q == Idle) + `ABR_ASSERT(InBandInitPing_A, PingSigInt_S or AckSigInt_S |-> ##3 !ping_set_q) + // output must be driven diff unless sigint issue detected + `ABR_ASSERT(DiffEncoding_A, (alert_rx_i.ack_p ^ alert_rx_i.ack_n) && + (alert_rx_i.ping_p ^ alert_rx_i.ping_n) |-> + ##[3:4] alert_tx_o.alert_p ^ alert_tx_o.alert_n) + + // handshakes can take indefinite time if blocked due to sigint on outgoing + // lines (which is not visible here). thus, we only check whether the + // handshake is correctly initiated and defer the full handshake checking to the testbench. + // TODO: add the staggered cases as well + `ABR_ASSERT(PingHs_A, ##1 $changed(alert_rx_i.ping_p) && + (alert_rx_i.ping_p ^ alert_rx_i.ping_n) ##2 state_q == Idle |=> + $rose(alert_tx_o.alert_p), clk_i, !rst_b || (alert_tx_o.alert_p == alert_tx_o.alert_n)) + end else begin : gen_sync_assert + sequence PingSigInt_S; + alert_rx_i.ping_p == alert_rx_i.ping_n; + endsequence + sequence AckSigInt_S; + alert_rx_i.ping_p == alert_rx_i.ping_n; + endsequence + + `ifndef FPV_ALERT_NO_SIGINT_ERR + // check propagation of sigint issues to output within one cycle + `ABR_ASSERT(SigIntPing_A, PingSigInt_S |=> + alert_tx_o.alert_p == alert_tx_o.alert_n) + `ABR_ASSERT(SigIntAck_A, AckSigInt_S |=> + alert_tx_o.alert_p == alert_tx_o.alert_n) + `endif + + // Test in-band FSM reset request (via signal integrity error) + `ABR_ASSERT(InBandInitFsm_A, PingSigInt_S or AckSigInt_S |=> state_q == Idle) + `ABR_ASSERT(InBandInitPing_A, PingSigInt_S or AckSigInt_S |=> !ping_set_q) + // output must be driven diff unless sigint issue detected + `ABR_ASSERT(DiffEncoding_A, (alert_rx_i.ack_p ^ alert_rx_i.ack_n) && + (alert_rx_i.ping_p ^ alert_rx_i.ping_n) |=> alert_tx_o.alert_p ^ alert_tx_o.alert_n) + // handshakes can take indefinite time if blocked due to sigint on outgoing + // lines (which is not visible here). thus, we only check whether the handshake + // is correctly initiated and defer the full handshake checking to the testbench. + `ABR_ASSERT(PingHs_A, ##1 $changed(alert_rx_i.ping_p) && state_q == Idle |=> + $rose(alert_tx_o.alert_p), clk_i, !rst_b || (alert_tx_o.alert_p == alert_tx_o.alert_n)) + end + + // Test the alert state output. + `ABR_ASSERT(AlertState0_A, alert_set_q === alert_state_o) + + if (IsFatal) begin : gen_fatal_assert + `ABR_ASSERT(AlertState1_A, alert_req_i |=> alert_state_o) + `ABR_ASSERT(AlertState2_A, alert_state_o |=> $stable(alert_state_o)) + `ABR_ASSERT(AlertState3_A, alert_ack_o |=> alert_state_o) + end else begin : gen_recov_assert + `ABR_ASSERT(AlertState1_A, alert_req_i && !alert_clr |=> alert_state_o) + `ABR_ASSERT(AlertState2_A, alert_req_i && alert_ack_o |=> !alert_state_o) + end + + // The alert test input should not set the alert state register. + `ABR_ASSERT(AlertTest1_A, alert_test_i && !alert_req_i && !alert_state_o |=> $stable(alert_state_o)) + + // if alert_req_i is true, handshakes should be continuously repeated + `ABR_ASSERT(AlertHs_A, alert_req_i && state_q == Idle |=> $rose(alert_tx_o.alert_p), + clk_i, !rst_b || (alert_tx_o.alert_p == alert_tx_o.alert_n)) + + // if alert_test_i is true, handshakes should be continuously repeated + `ABR_ASSERT(AlertTestHs_A, alert_test_i && state_q == Idle |=> $rose(alert_tx_o.alert_p), + clk_i, !rst_b || (alert_tx_o.alert_p == alert_tx_o.alert_n)) +`endif + +`ifdef FPV_ALERT_NO_SIGINT_ERR + // Assumptions for FPV security countermeasures to ensure the alert protocol functions collectly. + `ABR_ASSUME_FPV(AckPFollowsAlertP_S, alert_rx_i.ack_p == $past(alert_tx_o.alert_p)) + `ABR_ASSUME_FPV(AckNFollowsAlertN_S, alert_rx_i.ack_n == $past(alert_tx_o.alert_n)) + `ABR_ASSUME_FPV(TriggerAlertInit_S, $stable(rst_b) == 0 |=> alert_rx_i.ping_p == alert_rx_i.ping_n) + `ABR_ASSUME_FPV(PingDiffPair_S, ##2 alert_rx_i.ping_p != alert_rx_i.ping_n) +`endif +endmodule : abr_prim_alert_sender diff --git a/designs/Caliptra/src/adams-bridge/abr_prim_arbiter_ppc.sv b/designs/Caliptra/src/adams-bridge/abr_prim_arbiter_ppc.sv new file mode 100644 index 0000000..c4d4bfa --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/abr_prim_arbiter_ppc.sv @@ -0,0 +1,225 @@ +// Copyright lowRISC contributors. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// N:1 arbiter module +// +// Verilog parameter +// N: Number of request ports +// DW: Data width +// DataPort: Set to 1 to enable the data port. Otherwise that port will be ignored. +// +// This is the original implementation of the arbiter which relies on parallel prefix computing +// optimization to optimize the request / arbiter tree. Not all synthesis tools may support this. +// +// Note that the currently winning request is held if the data sink is not ready. This behavior is +// required by some interconnect protocols (AXI, TL). The module contains an assertion that checks +// this behavior. +// +// Also, this module contains a request stability assertion that checks that requests stay asserted +// until they have been served. This assertion can be gated by driving the req_chk_i low. This is +// a non-functional input and does not affect the designs behavior. +// +// See also: abr_prim_arbiter_tree + +`include "abr_prim_assert.sv" + +module abr_prim_arbiter_ppc #( + parameter int unsigned N = 8, + parameter int unsigned DW = 32, + + // Configurations + // EnDataPort: {0, 1}, if 0, input data will be ignored + parameter bit EnDataPort = 1, + + // Derived parameters + localparam int IdxW = $clog2(N) +) ( + input clk_i, + input rst_b, + + input req_chk_i, // Used for gating assertions. Drive to 1 during normal + // operation. + input [ N-1:0] req_i, + input [DW-1:0] data_i [N], + output logic [ N-1:0] gnt_o, + output logic [IdxW-1:0] idx_o, + + output logic valid_o, + output logic [DW-1:0] data_o, + input ready_i +); + + // req_chk_i is used for gating assertions only. + logic unused_req_chk; + assign unused_req_chk = req_chk_i; + + `ABR_ASSERT_INIT(CheckNGreaterZero_A, N > 0) + + // this case is basically just a bypass + if (N == 1) begin : gen_degenerate_case + + assign valid_o = req_i[0]; + assign data_o = data_i[0]; + assign gnt_o[0] = valid_o & ready_i; + assign idx_o = '0; + + end else begin : gen_normal_case + + logic [N-1:0] masked_req; + logic [N-1:0] ppc_out; + logic [N-1:0] arb_req; + logic [N-1:0] mask, mask_next; + logic [N-1:0] winner; + + assign masked_req = mask & req_i; + assign arb_req = (|masked_req) ? masked_req : req_i; + + // PPC + // Even below code looks O(n) but DC optimizes it to O(log(N)) + // Using Parallel Prefix Computation + always_comb begin + ppc_out[0] = arb_req[0]; + for (int i = 1 ; i < N ; i++) begin + ppc_out[i] = ppc_out[i-1] | arb_req[i]; + end + end + + // Grant Generation: Leading-One detector + assign winner = ppc_out ^ {ppc_out[N-2:0], 1'b0}; + assign gnt_o = (ready_i) ? winner : '0; + + assign valid_o = |req_i; + // Mask Generation + assign mask_next = {ppc_out[N-2:0], 1'b0}; + always_ff @(posedge clk_i or negedge rst_b) begin + if (!rst_b) begin + mask <= '0; + end else if (valid_o && ready_i) begin + // Latch only when requests accepted + mask <= mask_next; + end else if (valid_o && !ready_i) begin + // Downstream isn't yet ready so, keep current request alive. (First come first serve) + mask <= ppc_out; + end + end + + if (EnDataPort == 1) begin: gen_datapath + always_comb begin + data_o = '0; + for (int i = 0 ; i < N ; i++) begin + if (winner[i]) begin + data_o = data_i[i]; + end + end + end + end else begin: gen_nodatapath + assign data_o = '1; + // The following signal is used to avoid possible lint errors. + logic [DW-1:0] unused_data [N]; + assign unused_data = data_i; + end + + always_comb begin + idx_o = '0; + for (int unsigned i = 0 ; i < N ; i++) begin + if (winner[i]) begin + idx_o = i[IdxW-1:0]; + end + end + end + end + + //////////////// + // assertions // + //////////////// + + // KNOWN assertions on outputs, except for data as that may be partially X in simulation + // e.g. when used on a BUS + `ABR_ASSERT_KNOWN(ValidKnown_A, valid_o) + `ABR_ASSERT_KNOWN(GrantKnown_A, gnt_o) + `ABR_ASSERT_KNOWN(IdxKnown_A, idx_o) + + // grant index shall be higher index than previous index, unless no higher requests exist. + `ABR_ASSERT(RoundRobin_A, + ##1 valid_o && ready_i && $past(ready_i) && $past(valid_o) && + |(req_i & ~((N'(1) << $past(idx_o)+1) - 1)) |-> + idx_o > $past(idx_o)) + // we can only grant one requestor at a time + `ABR_ASSERT(CheckHotOne_A, $onehot0(gnt_o)) + // A grant implies that the sink is ready + `ABR_ASSERT(GntImpliesReady_A, |gnt_o |-> ready_i) + // A grant implies that the arbiter asserts valid as well + `ABR_ASSERT(GntImpliesValid_A, |gnt_o |-> valid_o) + // A request and a sink that is ready imply a grant + `ABR_ASSERT(ReqAndReadyImplyGrant_A, |req_i && ready_i |-> |gnt_o) + // A request and a sink that is ready imply a grant + `ABR_ASSERT(ReqImpliesValid_A, |req_i |-> valid_o) + // Both conditions above combined and reversed + `ABR_ASSERT(ReadyAndValidImplyGrant_A, ready_i && valid_o |-> |gnt_o) + // Both conditions above combined and reversed + `ABR_ASSERT(NoReadyValidNoGrant_A, !(ready_i || valid_o) |-> gnt_o == 0) + // check index / grant correspond + `ABR_ASSERT(IndexIsCorrect_A, ready_i && valid_o |-> gnt_o[idx_o] && req_i[idx_o]) + +if (EnDataPort) begin: gen_data_port_assertion + // data flow + `ABR_ASSERT(DataFlow_A, ready_i && valid_o |-> data_o == data_i[idx_o]) +end + + // requests must stay asserted until they have been granted + `ABR_ASSUME(ReqStaysHighUntilGranted0_M, |req_i && !ready_i |=> + (req_i & $past(req_i)) == $past(req_i), clk_i, !rst_b || !req_chk_i) + // check that the arbitration decision is held if the sink is not ready + `ABR_ASSERT(LockArbDecision_A, |req_i && !ready_i |=> idx_o == $past(idx_o), + clk_i, !rst_b || !req_chk_i) + +// FPV-only assertions with symbolic variables +`ifdef FPV_ON + // symbolic variables + int unsigned k; + bit ReadyIsStable; + bit ReqsAreStable; + + // constraints for symbolic variables + `ABR_ASSUME(KStable_M, ##1 $stable(k)) + `ABR_ASSUME(KRange_M, k < N) + // this is used enable checking for stable and unstable ready_i and req_i signals in the same run. + // the symbolic variables act like a switch that the solver can trun on and off. + `ABR_ASSUME(ReadyIsStable_M, ##1 $stable(ReadyIsStable)) + `ABR_ASSUME(ReqsAreStable_M, ##1 $stable(ReqsAreStable)) + `ABR_ASSUME(ReadyStable_M, ##1 !ReadyIsStable || $stable(ready_i)) + `ABR_ASSUME(ReqsStable_M, ##1 !ReqsAreStable || $stable(req_i)) + + // A grant implies a request + `ABR_ASSERT(GntImpliesReq_A, gnt_o[k] |-> req_i[k]) + + // if request and ready are constantly held at 1, we should eventually get a grant + `ABR_ASSERT(NoStarvation_A, + ReqsAreStable && ReadyIsStable && ready_i && req_i[k] |-> + strong(##[0:$] gnt_o[k])) + + // if N requests are constantly asserted and ready is constant 1, each request must + // be granted exactly once over a time window of N cycles for the arbiter to be fair. + for (genvar n = 1; n <= N; n++) begin : gen_fairness + integer gnt_cnt; + `ABR_ASSERT(Fairness_A, + ReqsAreStable && ReadyIsStable && ready_i && req_i[k] && + $countones(req_i) == n |-> + ##n gnt_cnt == $past(gnt_cnt, n) + 1) + + always_ff @(posedge clk_i or negedge rst_b) begin : p_cnt + if (!rst_b) begin + gnt_cnt <= 0; + end else begin + gnt_cnt <= gnt_cnt + gnt_o[k]; + end + end + end + + // requests must stay asserted until they have been granted + `ABR_ASSUME(ReqStaysHighUntilGranted1_M, req_i[k] && !gnt_o[k] |=> + req_i[k], clk_i, !rst_b || !req_chk_i) +`endif + +endmodule : abr_prim_arbiter_ppc diff --git a/designs/Caliptra/src/adams-bridge/abr_prim_assert.sv b/designs/Caliptra/src/adams-bridge/abr_prim_assert.sv new file mode 100644 index 0000000..d2731a9 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/abr_prim_assert.sv @@ -0,0 +1,182 @@ +// Copyright lowRISC contributors. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// Macros and helper code for using assertions. +// - Provides default clk and rst options to simplify code +// - Provides boiler plate template for common assertions + +`ifndef ABR_PRIM_ASSERT_SV +`define ABR_PRIM_ASSERT_SV + +/////////////////// +// Helper macros // +/////////////////// + +`include "abr_sva.svh" +`ifndef ABR_SVA +// Default clk and reset signals used by assertion macros below. +`define ABR_ASSERT_DEFAULT_CLK clk_i +`define ABR_ASSERT_DEFAULT_RST !rst_b +`endif + +// Converts an arbitrary block of code into a Verilog string +`define ABR_PRIM_STRINGIFY(__x) `"__x`" + +// ABR_ASSERT_ERROR logs an error message with either `uvm_error or with $error. +// +// This somewhat duplicates `DV_ERROR macro defined in hw/dv/sv/dv_utils/dv_macros.svh. The reason +// for redefining it here is to avoid creating a dependency. +`define ABR_ASSERT_ERROR(__name) \ +`ifdef UVM \ + uvm_pkg::uvm_report_error("ABR_ASSERT FAILED", `ABR_PRIM_STRINGIFY(__name), uvm_pkg::UVM_NONE, \ + `__FILE__, `__LINE__); \ +`else \ + $error("%0t: (%0s:%0d) [%m] [ABR_ASSERT FAILED] %0s", $time, `__FILE__, `__LINE__, \ + `ABR_PRIM_STRINGIFY(__name)); \ +`endif + +// This macro is suitable for conditionally triggering lint errors, e.g., if a Sec parameter takes +// on a non-default value. This may be required for pre-silicon/FPGA evaluation but we don't want +// to allow this for tapeout. +`define ABR_ASSERT_STATIC_LINT_ERROR(__name, __prop) \ + localparam int __name = (__prop) ? 1 : 2; \ + always_comb begin \ + logic unused_assert_static_lint_error; \ + unused_assert_static_lint_error = __name'(1'b1); \ + end + +// Static assertions for checks inside SV packages. If the conditions is not true, this will +// trigger an error during elaboration. +`define ABR_ASSERT_STATIC_IN_PACKAGE(__name, __prop) \ + function automatic logic assert_static_in_package_``__name(); \ + logic unused_bit [((__prop) ? 1 : -1)]; \ + unused_bit = '{default: 1'b0}; \ + return unused_bit[0]; \ + endfunction + +// The basic helper macros are actually defined in "implementation headers". The macros should do +// the same thing in each case (except for the dummy flavour), but in a way that the respective +// tools support. +// +// If the tool supports assertions in some form, we also define ABR_INC_ASSERT (which can be +// used to hide signal definitions that are only used for assertions). +// +// The list of basic macros supported is: +// +// ABR_ASSERT_I: Immediate assertion. Note that immediate assertions are sensitive to simulation +// glitches. +// +// ABR_ASSERT_INIT: Assertion in initial block. Can be used for things like parameter checking. +// +// ABR_ASSERT_INIT_NET: Assertion in initial block. Can be used for initial value of a net. +// +// ABR_ASSERT_FINAL: Assertion in final block. Can be used for things like queues being empty at end of +// sim, all credits returned at end of sim, state machines in idle at end of sim. +// +// ABR_ASSERT: Assert a concurrent property directly. It can be called as a module (or +// interface) body item. +// +// Note: We use (__rst !== '0) in the disable iff statements instead of (__rst == +// '1). This properly disables the assertion in cases when reset is X at the +// beginning of a simulation. For that case, (reset == '1) does not disable the +// assertion. +// +// ABR_ASSERT_NEVER: Assert a concurrent property NEVER happens +// +// ABR_ASSERT_KNOWN: Assert that signal has a known value (each bit is either '0' or '1') after reset. +// It can be called as a module (or interface) body item. +// +// ABR_COVER: Cover a concurrent property +// +// ABR_ASSUME: Assume a concurrent property +// +// ABR_ASSUME_I: Assume an immediate property + +`ifdef VERILATOR + `include "abr_prim_assert_dummy_macros.svh" +`elsif SYNTHESIS + `include "abr_prim_assert_dummy_macros.svh" +`elsif YOSYS + `include "abr_prim_assert_yosys_macros.svh" + `define ABR_INC_ASSERT +`else + `include "abr_prim_assert_standard_macros.svh" + `define ABR_INC_ASSERT +`endif + +////////////////////////////// +// Complex assertion macros // +////////////////////////////// + +// Assert that signal is an active-high pulse with pulse length of 1 clock cycle +`define ABR_ASSERT_PULSE(__name, __sig, __clk = `ABR_ASSERT_DEFAULT_CLK, __rst = `ABR_ASSERT_DEFAULT_RST) \ + `ABR_ASSERT(__name, $rose(__sig) |=> !(__sig), __clk, __rst) + +// Assert that a property is true only when an enable signal is set. It can be called as a module +// (or interface) body item. +`define ABR_ASSERT_IF(__name, __prop, __enable, __clk = `ABR_ASSERT_DEFAULT_CLK, __rst = `ABR_ASSERT_DEFAULT_RST) \ + `ABR_ASSERT(__name, (__enable) |-> (__prop), __clk, __rst) + +// Assert that signal has a known value (each bit is either '0' or '1') after reset if enable is +// set. It can be called as a module (or interface) body item. +`define ABR_ASSERT_KNOWN_IF(__name, __sig, __enable, __clk = `ABR_ASSERT_DEFAULT_CLK, __rst = `ABR_ASSERT_DEFAULT_RST) \ + `ABR_ASSERT_KNOWN(__name``KnownEnable, __enable, __clk, __rst) \ + `ABR_ASSERT_IF(__name, !$isunknown(__sig), __enable, __clk, __rst) + +////////////////////////////////// +// For formal verification only // +////////////////////////////////// + +// Note that the existing set of ABR_ASSERT macros specified above shall be used for FPV, +// thereby ensuring that the assertions are evaluated during DV simulations as well. + +// ABR_ASSUME_FPV +// Assume a concurrent property during formal verification only. +`define ABR_ASSUME_FPV(__name, __prop, __clk = `ABR_ASSERT_DEFAULT_CLK, __rst = `ABR_ASSERT_DEFAULT_RST) \ +`ifdef FPV_ON \ + `ABR_ASSUME(__name, __prop, __clk, __rst) \ +`endif + +// ABR_ASSUME_I_FPV +// Assume a concurrent property during formal verification only. +`define ABR_ASSUME_I_FPV(__name, __prop) \ +`ifdef FPV_ON \ + `ABR_ASSUME_I(__name, __prop) \ +`endif + +// ABR_COVER_FPV +// Cover a concurrent property during formal verification +`define ABR_COVER_FPV(__name, __prop, __clk = `ABR_ASSERT_DEFAULT_CLK, __rst = `ABR_ASSERT_DEFAULT_RST) \ +`ifdef FPV_ON \ + `ABR_COVER(__name, __prop, __clk, __rst) \ +`endif + +// FPV assertion that proves that the FSM control flow is linear (no loops) +// The sequence triggers whenever the state changes and stores the current state as "initial_state". +// Then thereafter we must never see that state again until reset. +// It is possible for the reset to release ahead of the clock. +// Create a small "gray" window beyond the usual rst time to avoid +// checking. +`define ABR_ASSERT_FPV_LINEAR_FSM(__name, __state, __type, __clk = `ABR_ASSERT_DEFAULT_CLK, __rst = `ABR_ASSERT_DEFAULT_RST) \ + `ifdef ABR_INC_ASSERT \ + bit __name``_cond; \ + always_ff @(posedge __clk or posedge __rst) begin \ + if (__rst) begin \ + __name``_cond <= 0; \ + end else begin \ + __name``_cond <= 1; \ + end \ + end \ + property __name``_p; \ + __type initial_state; \ + (!$stable(__state) & __name``_cond, initial_state = $past(__state)) |-> \ + (__state != initial_state) until (__rst == 1'b1); \ + endproperty \ + `ABR_ASSERT(__name, __name``_p, __clk, __rst) \ + `endif + +`include "abr_prim_assert_sec_cm.svh" +`include "abr_prim_flop_macros.sv" + +`endif // PRIM_ASSERT_SV diff --git a/designs/Caliptra/src/adams-bridge/abr_prim_assert_dummy_macros.svh b/designs/Caliptra/src/adams-bridge/abr_prim_assert_dummy_macros.svh new file mode 100644 index 0000000..6d6210c --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/abr_prim_assert_dummy_macros.svh @@ -0,0 +1,19 @@ +// Copyright lowRISC contributors. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// Macro bodies included by abr_prim_assert.sv for tools that don't support assertions. See +// abr_prim_assert.sv for documentation for each of the macros. + +`define ABR_ASSERT_I(__name, __prop) +`define ABR_ASSERT_INIT(__name, __prop) +`define ABR_ASSERT_INIT_NET(__name, __prop) +`define ABR_ASSERT_FINAL(__name, __prop) +`ifndef ABR_SVA +`define ABR_ASSERT(__name, __prop, __clk = `ABR_ASSERT_DEFAULT_CLK, __rst = `ABR_ASSERT_DEFAULT_RST) +`define ABR_ASSERT_NEVER(__name, __prop, __clk = `ABR_ASSERT_DEFAULT_CLK, __rst = `ABR_ASSERT_DEFAULT_RST) +`define ABR_ASSERT_KNOWN(__name, __sig, __clk = `ABR_ASSERT_DEFAULT_CLK, __rst = `ABR_ASSERT_DEFAULT_RST) +`endif +`define ABR_COVER(__name, __prop, __clk = `ABR_ASSERT_DEFAULT_CLK, __rst = `ABR_ASSERT_DEFAULT_RST) +`define ABR_ASSUME(__name, __prop, __clk = `ABR_ASSERT_DEFAULT_CLK, __rst = `ABR_ASSERT_DEFAULT_RST) +`define ABR_ASSUME_I(__name, __prop) diff --git a/designs/Caliptra/src/adams-bridge/abr_prim_assert_sec_cm.svh b/designs/Caliptra/src/adams-bridge/abr_prim_assert_sec_cm.svh new file mode 100644 index 0000000..028f40b --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/abr_prim_assert_sec_cm.svh @@ -0,0 +1,48 @@ +// Copyright lowRISC contributors. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// // Macros and helper code for security countermeasures. + +`ifndef ABR_PRIM_ASSERT_SEC_CM_SVH +`define ABR_PRIM_ASSERT_SEC_CM_SVH + +`define _ABR_SEC_CM_ALERT_MAX_CYC 30 + +// Helper macros +`define ABR_ASSERT_ERROR_TRIGGER_ALERT(NAME_, PRIM_HIER_, ALERT_, GATE_, MAX_CYCLES_, ERR_NAME_) \ + `ABR_ASSERT(FpvSecCm``NAME_``, \ + $rose(PRIM_HIER_.ERR_NAME_) && !(GATE_) \ + |-> ##[0:MAX_CYCLES_] (ALERT_.alert_p)) \ + `ifdef ABR_INC_ASSERT \ + assign PRIM_HIER_.unused_assert_connected = 1'b1; \ + `endif \ + `ABR_ASSUME_FPV(``NAME_``TriggerAfterAlertInit_S, $stable(rst_b) == 0 |-> \ + PRIM_HIER_.ERR_NAME_ == 0 [*10]) + +`define ABR_ASSERT_ERROR_TRIGGER_ERR(NAME_, PRIM_HIER_, ERR_, GATE_, MAX_CYCLES_, ERR_NAME_, CLK_, RST_) \ + `ABR_ASSERT(FpvSecCm``NAME_``, \ + $rose(PRIM_HIER_.ERR_NAME_) && !(GATE_) \ + |-> ##[0:MAX_CYCLES_] (ERR_), CLK_, RST_) \ + `ifdef ABR_INC_ASSERT \ + assign PRIM_HIER_.unused_assert_connected = 1'b1; \ + `endif + +// macros for security countermeasures that will trigger alert +`define ABR_ASSERT_PRIM_COUNT_ERROR_TRIGGER_ALERT(NAME_, PRIM_HIER_, ALERT_, GATE_ = 0, MAX_CYCLES_ = `_ABR_SEC_CM_ALERT_MAX_CYC) \ + `ABR_ASSERT_ERROR_TRIGGER_ALERT(NAME_, PRIM_HIER_, ALERT_, GATE_, MAX_CYCLES_, err_o) + +`define ABR_ASSERT_PRIM_DOUBLE_LFSR_ERROR_TRIGGER_ALERT(NAME_, PRIM_HIER_, ALERT_, GATE_ = 0, MAX_CYCLES_ = `_ABR_SEC_CM_ALERT_MAX_CYC) \ + `ABR_ASSERT_ERROR_TRIGGER_ALERT(NAME_, PRIM_HIER_, ALERT_, GATE_, MAX_CYCLES_, err_o) + +`define ABR_ASSERT_PRIM_FSM_ERROR_TRIGGER_ALERT(NAME_, PRIM_HIER_, ALERT_, GATE_ = 0, MAX_CYCLES_ = `_ABR_SEC_CM_ALERT_MAX_CYC) \ + `ABR_ASSERT_ERROR_TRIGGER_ALERT(NAME_, PRIM_HIER_, ALERT_, GATE_, MAX_CYCLES_, unused_err_o) + +`define ABR_ASSERT_PRIM_ONEHOT_ERROR_TRIGGER_ALERT(NAME_, PRIM_HIER_, ALERT_, GATE_ = 0, MAX_CYCLES_ = `_ABR_SEC_CM_ALERT_MAX_CYC) \ + `ABR_ASSERT_ERROR_TRIGGER_ALERT(NAME_, PRIM_HIER_, ALERT_, GATE_, MAX_CYCLES_, err_o) + +`define ABR_ASSERT_PRIM_REG_WE_ONEHOT_ERROR_TRIGGER_ALERT(NAME_, REG_TOP_HIER_, ALERT_, GATE_ = 0, MAX_CYCLES_ = `_ABR_SEC_CM_ALERT_MAX_CYC) \ + `ABR_ASSERT_PRIM_ONEHOT_ERROR_TRIGGER_ALERT(NAME_, \ + REG_TOP_HIER_.u_abr_prim_reg_we_check.u_abr_prim_onehot_check, ALERT_, GATE_, MAX_CYCLES_) + +`endif // PRIM_ASSERT_SEC_CM_SVH diff --git a/designs/Caliptra/src/adams-bridge/abr_prim_buf.sv b/designs/Caliptra/src/adams-bridge/abr_prim_buf.sv new file mode 100755 index 0000000..72e0e68 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/abr_prim_buf.sv @@ -0,0 +1,42 @@ +// Copyright lowRISC contributors. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// This file is auto-generated. +// Used parser: Verible + +`ifndef ABR_PRIM_DEFAULT_IMPL + `define ABR_PRIM_DEFAULT_IMPL abr_prim_pkg::ImplGeneric +`endif + +// This is to prevent AscentLint warnings in the generated +// abstract prim wrapper. These warnings occur due to the .* +// use. TODO: we may want to move these inline waivers +// into a separate, generated waiver file for consistency. +//ri lint_check_off OUTPUT_NOT_DRIVEN INPUT_NOT_READ HIER_BRANCH_NOT_READ +module abr_prim_buf + +#( +parameter int Width = 1 +) ( + input [Width-1:0] in_i, + output logic [Width-1:0] out_o +); + parameter abr_prim_pkg::impl_e Impl = `ABR_PRIM_DEFAULT_IMPL; + +if (Impl == abr_prim_pkg::ImplXilinx) begin : gen_xilinx + abr_prim_xilinx_buf #( + .Width(Width) + ) u_impl_xilinx ( + .* + ); +end else begin : gen_generic + abr_prim_generic_buf #( + .Width(Width) + ) u_impl_generic ( + .* + ); +end + +endmodule +//ri lint_check_on OUTPUT_NOT_DRIVEN INPUT_NOT_READ HIER_BRANCH_NOT_READ diff --git a/designs/Caliptra/src/adams-bridge/abr_prim_cdc_rand_delay.sv b/designs/Caliptra/src/adams-bridge/abr_prim_cdc_rand_delay.sv new file mode 100644 index 0000000..b68c793 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/abr_prim_cdc_rand_delay.sv @@ -0,0 +1,63 @@ +// Copyright lowRISC contributors. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// This module should be instantiated within flops of CDC synchronization primitives, +// and allows DV to model real CDC delays within simulations, especially useful at the chip level +// or in IPs that communicate across clock domains. +// +// The instrumentation is very simple: when this is enabled the input into the first +// synchronizer flop has a mux where the select is randomly set. One of the mux inputs is the input +// of this module, and the other is the output of the first flop: selecting the latter models the +// effect of the first flop missing the input transition. +// +// Notice the delay should cause the input to be skipped by at most a single cycle. As a perhaps +// unnecessary precaution, the select will only be allowed to be random when the input changes. + +module abr_prim_cdc_rand_delay #( + parameter int DataWidth = 1, + parameter bit Enable = 1 +) ( + input logic clk_i, + input logic rst_b, + input logic [DataWidth-1:0] prev_data_i, + input logic [DataWidth-1:0] src_data_i, + output logic [DataWidth-1:0] dst_data_o +); +`ifdef ABR_SIMULATION + if (Enable) begin : gen_enable + + // This controls dst_data_o: any bit with its data_sel set uses prev_data_i, others use + // src_data_i. + bit [DataWidth-1:0] data_sel; + bit cdc_instrumentation_enabled; + + function automatic bit [DataWidth-1:0] fast_randomize(); + bit [DataWidth-1:0] data; + bit [31:0] urandom_result; + for (int i = 0; i < DataWidth; i += 32) begin + data = data << 32; + urandom_result = $urandom(); + data = data | urandom_result; + end + return data; + endfunction + + initial begin + void'($value$plusargs("cdc_instrumentation_enabled=%d", cdc_instrumentation_enabled)); + data_sel = '0; + end + + // Set data_sel at random combinationally when the input changes. + always @(src_data_i) begin + data_sel = cdc_instrumentation_enabled ? fast_randomize() : 0; + end + + always_comb dst_data_o = (prev_data_i & data_sel) | (src_data_i & ~data_sel); + end else begin : gen_no_enable + assign dst_data_o = src_data_i; + end +`else // ABR_SIMULATION + assign dst_data_o = src_data_i; +`endif // ABR_SIMULATION +endmodule diff --git a/designs/Caliptra/src/adams-bridge/abr_prim_cipher_pkg.sv b/designs/Caliptra/src/adams-bridge/abr_prim_cipher_pkg.sv new file mode 100644 index 0000000..0513e38 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/abr_prim_cipher_pkg.sv @@ -0,0 +1,397 @@ +// Copyright lowRISC contributors. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// This package holds common constants and functions for PRESENT- and +// PRINCE-based scrambling devices. +// +// See also: abr_prim_present, abr_prim_prince +// +// References: - https://en.wikipedia.org/wiki/PRESENT +// - https://en.wikipedia.org/wiki/Prince_(cipher) +// - http://www.lightweightcrypto.org/present/present_ches2007.pdf +// - https://eprint.iacr.org/2012/529.pdf +// - https://eprint.iacr.org/2015/372.pdf +// - https://eprint.iacr.org/2014/656.pdf + +package abr_prim_cipher_pkg; + + /////////////////// + // PRINCE Cipher // + /////////////////// + + parameter logic [15:0][3:0] PRINCE_SBOX4 = {4'h4, 4'hD, 4'h5, 4'hE, + 4'h0, 4'h8, 4'h7, 4'h6, + 4'h1, 4'h9, 4'hC, 4'hA, + 4'h2, 4'h3, 4'hF, 4'hB}; + + parameter logic [15:0][3:0] PRINCE_SBOX4_INV = {4'h1, 4'hC, 4'hE, 4'h5, + 4'h0, 4'h4, 4'h6, 4'hA, + 4'h9, 4'h8, 4'hD, 4'hF, + 4'h2, 4'h3, 4'h7, 4'hB}; + // nibble permutations + parameter logic [15:0][3:0] PRINCE_SHIFT_ROWS64 = '{4'hF, 4'hA, 4'h5, 4'h0, + 4'hB, 4'h6, 4'h1, 4'hC, + 4'h7, 4'h2, 4'hD, 4'h8, + 4'h3, 4'hE, 4'h9, 4'h4}; + + parameter logic [15:0][3:0] PRINCE_SHIFT_ROWS64_INV = '{4'hF, 4'h2, 4'h5, 4'h8, + 4'hB, 4'hE, 4'h1, 4'h4, + 4'h7, 4'hA, 4'hD, 4'h0, + 4'h3, 4'h6, 4'h9, 4'hC}; + + // these are the round constants + parameter logic [11:0][63:0] PRINCE_ROUND_CONST = {64'hC0AC29B7C97C50DD, + 64'hD3B5A399CA0C2399, + 64'h64A51195E0E3610D, + 64'hC882D32F25323C54, + 64'h85840851F1AC43AA, + 64'h7EF84F78FD955CB1, + 64'hBE5466CF34E90C6C, + 64'h452821E638D01377, + 64'h082EFA98EC4E6C89, + 64'hA4093822299F31D0, + 64'h13198A2E03707344, + 64'h0000000000000000}; + + // tweak constant for key modification between enc/dec modes + parameter logic [63:0] PRINCE_ALPHA_CONST = 64'hC0AC29B7C97C50DD; + + // masking constants for shift rows function below + parameter logic [15:0] PRINCE_SHIFT_ROWS_CONST0 = 16'h7BDE; + parameter logic [15:0] PRINCE_SHIFT_ROWS_CONST1 = 16'hBDE7; + parameter logic [15:0] PRINCE_SHIFT_ROWS_CONST2 = 16'hDE7B; + parameter logic [15:0] PRINCE_SHIFT_ROWS_CONST3 = 16'hE7BD; + + // nibble shifts + function automatic logic [31:0] prince_shiftrows_32bit(logic [31:0] state_in, + logic [15:0][3:0] shifts ); + logic [31:0] state_out; + // note that if simulation performance becomes an issue, this loop can be unrolled + for (int k = 0; k < 32/2; k++) begin + // operate on pairs of 2bit instead of nibbles + state_out[k*2 +: 2] = state_in[shifts[k]*2 +: 2]; + end + return state_out; + endfunction : prince_shiftrows_32bit + + function automatic logic [63:0] prince_shiftrows_64bit(logic [63:0] state_in, + logic [15:0][3:0] shifts ); + logic [63:0] state_out; + // note that if simulation performance becomes an issue, this loop can be unrolled + for (int k = 0; k < 64/4; k++) begin + state_out[k*4 +: 4] = state_in[shifts[k]*4 +: 4]; + end + return state_out; + endfunction : prince_shiftrows_64bit + + // XOR reduction of four nibbles in a 16bit subvector + function automatic logic [3:0] prince_nibble_red16(logic [15:0] vect); + return vect[0 +: 4] ^ vect[4 +: 4] ^ vect[8 +: 4] ^ vect[12 +: 4]; + endfunction : prince_nibble_red16 + + // M prime multiplication + function automatic logic [31:0] prince_mult_prime_32bit(logic [31:0] state_in); + logic [31:0] state_out; + // M0 + state_out[0 +: 4] = prince_nibble_red16(state_in[ 0 +: 16] & PRINCE_SHIFT_ROWS_CONST3); + state_out[4 +: 4] = prince_nibble_red16(state_in[ 0 +: 16] & PRINCE_SHIFT_ROWS_CONST2); + state_out[8 +: 4] = prince_nibble_red16(state_in[ 0 +: 16] & PRINCE_SHIFT_ROWS_CONST1); + state_out[12 +: 4] = prince_nibble_red16(state_in[ 0 +: 16] & PRINCE_SHIFT_ROWS_CONST0); + // M1 + state_out[16 +: 4] = prince_nibble_red16(state_in[16 +: 16] & PRINCE_SHIFT_ROWS_CONST0); + state_out[20 +: 4] = prince_nibble_red16(state_in[16 +: 16] & PRINCE_SHIFT_ROWS_CONST3); + state_out[24 +: 4] = prince_nibble_red16(state_in[16 +: 16] & PRINCE_SHIFT_ROWS_CONST2); + state_out[28 +: 4] = prince_nibble_red16(state_in[16 +: 16] & PRINCE_SHIFT_ROWS_CONST1); + return state_out; + endfunction : prince_mult_prime_32bit + + // M prime multiplication + function automatic logic [63:0] prince_mult_prime_64bit(logic [63:0] state_in); + logic [63:0] state_out; + // M0 + state_out[0 +: 4] = prince_nibble_red16(state_in[ 0 +: 16] & PRINCE_SHIFT_ROWS_CONST3); + state_out[4 +: 4] = prince_nibble_red16(state_in[ 0 +: 16] & PRINCE_SHIFT_ROWS_CONST2); + state_out[8 +: 4] = prince_nibble_red16(state_in[ 0 +: 16] & PRINCE_SHIFT_ROWS_CONST1); + state_out[12 +: 4] = prince_nibble_red16(state_in[ 0 +: 16] & PRINCE_SHIFT_ROWS_CONST0); + // M1 + state_out[16 +: 4] = prince_nibble_red16(state_in[16 +: 16] & PRINCE_SHIFT_ROWS_CONST0); + state_out[20 +: 4] = prince_nibble_red16(state_in[16 +: 16] & PRINCE_SHIFT_ROWS_CONST3); + state_out[24 +: 4] = prince_nibble_red16(state_in[16 +: 16] & PRINCE_SHIFT_ROWS_CONST2); + state_out[28 +: 4] = prince_nibble_red16(state_in[16 +: 16] & PRINCE_SHIFT_ROWS_CONST1); + // M1 + state_out[32 +: 4] = prince_nibble_red16(state_in[32 +: 16] & PRINCE_SHIFT_ROWS_CONST0); + state_out[36 +: 4] = prince_nibble_red16(state_in[32 +: 16] & PRINCE_SHIFT_ROWS_CONST3); + state_out[40 +: 4] = prince_nibble_red16(state_in[32 +: 16] & PRINCE_SHIFT_ROWS_CONST2); + state_out[44 +: 4] = prince_nibble_red16(state_in[32 +: 16] & PRINCE_SHIFT_ROWS_CONST1); + // M0 + state_out[48 +: 4] = prince_nibble_red16(state_in[48 +: 16] & PRINCE_SHIFT_ROWS_CONST3); + state_out[52 +: 4] = prince_nibble_red16(state_in[48 +: 16] & PRINCE_SHIFT_ROWS_CONST2); + state_out[56 +: 4] = prince_nibble_red16(state_in[48 +: 16] & PRINCE_SHIFT_ROWS_CONST1); + state_out[60 +: 4] = prince_nibble_red16(state_in[48 +: 16] & PRINCE_SHIFT_ROWS_CONST0); + return state_out; + endfunction : prince_mult_prime_64bit + + + //////////////////// + // PRESENT Cipher // + //////////////////// + + // this is the sbox from the present cipher + parameter logic [15:0][3:0] PRESENT_SBOX4 = {4'h2, 4'h1, 4'h7, 4'h4, + 4'h8, 4'hF, 4'hE, 4'h3, + 4'hD, 4'hA, 4'h0, 4'h9, + 4'hB, 4'h6, 4'h5, 4'hC}; + + parameter logic [15:0][3:0] PRESENT_SBOX4_INV = {4'hA, 4'h9, 4'h7, 4'h0, + 4'h3, 4'h6, 4'h4, 4'hB, + 4'hD, 4'h2, 4'h1, 4'hC, + 4'h8, 4'hF, 4'hE, 4'h5}; + + // these are modified permutation indices for a 32bit version that + // follow the same pattern as for the 64bit version + parameter logic [31:0][4:0] PRESENT_PERM32 = {5'd31, 5'd23, 5'd15, 5'd07, + 5'd30, 5'd22, 5'd14, 5'd06, + 5'd29, 5'd21, 5'd13, 5'd05, + 5'd28, 5'd20, 5'd12, 5'd04, + 5'd27, 5'd19, 5'd11, 5'd03, + 5'd26, 5'd18, 5'd10, 5'd02, + 5'd25, 5'd17, 5'd09, 5'd01, + 5'd24, 5'd16, 5'd08, 5'd00}; + + parameter logic [31:0][4:0] PRESENT_PERM32_INV = {5'd31, 5'd27, 5'd23, 5'd19, + 5'd15, 5'd11, 5'd07, 5'd03, + 5'd30, 5'd26, 5'd22, 5'd18, + 5'd14, 5'd10, 5'd06, 5'd02, + 5'd29, 5'd25, 5'd21, 5'd17, + 5'd13, 5'd09, 5'd05, 5'd01, + 5'd28, 5'd24, 5'd20, 5'd16, + 5'd12, 5'd08, 5'd04, 5'd00}; + + // these are the permutation indices of the present cipher + parameter logic [63:0][5:0] PRESENT_PERM64 = {6'd63, 6'd47, 6'd31, 6'd15, + 6'd62, 6'd46, 6'd30, 6'd14, + 6'd61, 6'd45, 6'd29, 6'd13, + 6'd60, 6'd44, 6'd28, 6'd12, + 6'd59, 6'd43, 6'd27, 6'd11, + 6'd58, 6'd42, 6'd26, 6'd10, + 6'd57, 6'd41, 6'd25, 6'd09, + 6'd56, 6'd40, 6'd24, 6'd08, + 6'd55, 6'd39, 6'd23, 6'd07, + 6'd54, 6'd38, 6'd22, 6'd06, + 6'd53, 6'd37, 6'd21, 6'd05, + 6'd52, 6'd36, 6'd20, 6'd04, + 6'd51, 6'd35, 6'd19, 6'd03, + 6'd50, 6'd34, 6'd18, 6'd02, + 6'd49, 6'd33, 6'd17, 6'd01, + 6'd48, 6'd32, 6'd16, 6'd00}; + + parameter logic [63:0][5:0] PRESENT_PERM64_INV = {6'd63, 6'd59, 6'd55, 6'd51, + 6'd47, 6'd43, 6'd39, 6'd35, + 6'd31, 6'd27, 6'd23, 6'd19, + 6'd15, 6'd11, 6'd07, 6'd03, + 6'd62, 6'd58, 6'd54, 6'd50, + 6'd46, 6'd42, 6'd38, 6'd34, + 6'd30, 6'd26, 6'd22, 6'd18, + 6'd14, 6'd10, 6'd06, 6'd02, + 6'd61, 6'd57, 6'd53, 6'd49, + 6'd45, 6'd41, 6'd37, 6'd33, + 6'd29, 6'd25, 6'd21, 6'd17, + 6'd13, 6'd09, 6'd05, 6'd01, + 6'd60, 6'd56, 6'd52, 6'd48, + 6'd44, 6'd40, 6'd36, 6'd32, + 6'd28, 6'd24, 6'd20, 6'd16, + 6'd12, 6'd08, 6'd04, 6'd00}; + + // forward key schedule + function automatic logic [63:0] present_update_key64(logic [63:0] key_in, + logic [4:0] round_idx); + logic [63:0] key_out; + // rotate by 61 to the left + key_out = {key_in[63-61:0], key_in[63:64-61]}; + // sbox on uppermost 4 bits + key_out[63 -: 4] = PRESENT_SBOX4[key_out[63 -: 4]]; + // xor in round counter on bits 19 to 15 + key_out[19:15] ^= round_idx; + return key_out; + endfunction : present_update_key64 + + function automatic logic [79:0] present_update_key80(logic [79:0] key_in, + logic [4:0] round_idx); + logic [79:0] key_out; + // rotate by 61 to the left + key_out = {key_in[79-61:0], key_in[79:80-61]}; + // sbox on uppermost 4 bits + key_out[79 -: 4] = PRESENT_SBOX4[key_out[79 -: 4]]; + // xor in round counter on bits 19 to 15 + key_out[19:15] ^= round_idx; + return key_out; + endfunction : present_update_key80 + + function automatic logic [127:0] present_update_key128(logic [127:0] key_in, + logic [4:0] round_idx); + logic [127:0] key_out; + // rotate by 61 to the left + key_out = {key_in[127-61:0], key_in[127:128-61]}; + // sbox on uppermost 4 bits + key_out[127 -: 4] = PRESENT_SBOX4[key_out[127 -: 4]]; + // sbox on second nibble from top + key_out[123 -: 4] = PRESENT_SBOX4[key_out[123 -: 4]]; + // xor in round counter on bits 66 to 62 + key_out[66:62] ^= round_idx; + return key_out; + endfunction : present_update_key128 + + + // inverse key schedule + function automatic logic [63:0] present_inv_update_key64(logic [63:0] key_in, + logic [4:0] round_idx); + logic [63:0] key_out = key_in; + // xor in round counter on bits 19 to 15 + key_out[19:15] ^= round_idx; + // sbox on uppermost 4 bits + key_out[63 -: 4] = PRESENT_SBOX4_INV[key_out[63 -: 4]]; + // rotate by 61 to the right + key_out = {key_out[60:0], key_out[63:61]}; + return key_out; + endfunction : present_inv_update_key64 + + function automatic logic [79:0] present_inv_update_key80(logic [79:0] key_in, + logic [4:0] round_idx); + logic [79:0] key_out = key_in; + // xor in round counter on bits 19 to 15 + key_out[19:15] ^= round_idx; + // sbox on uppermost 4 bits + key_out[79 -: 4] = PRESENT_SBOX4_INV[key_out[79 -: 4]]; + // rotate by 61 to the right + key_out = {key_out[60:0], key_out[79:61]}; + return key_out; + endfunction : present_inv_update_key80 + + function automatic logic [127:0] present_inv_update_key128(logic [127:0] key_in, + logic [4:0] round_idx); + logic [127:0] key_out = key_in; + // xor in round counter on bits 66 to 62 + key_out[66:62] ^= round_idx; + // sbox on second highest nibble + key_out[123 -: 4] = PRESENT_SBOX4_INV[key_out[123 -: 4]]; + // sbox on uppermost 4 bits + key_out[127 -: 4] = PRESENT_SBOX4_INV[key_out[127 -: 4]]; + // rotate by 61 to the right + key_out = {key_out[60:0], key_out[127:61]}; + return key_out; + endfunction : present_inv_update_key128 + + + // these functions can be used to derive the DEC key from the ENC key by + // stepping the key by the correct number of rounds using the keyschedule functions above. + function automatic logic [63:0] present_get_dec_key64(logic [63:0] key_in, + // total number of rounds employed + logic [4:0] round_cnt); + logic [63:0] key_out; + key_out = key_in; + for (int unsigned k = 0; k < round_cnt; k++) begin + key_out = present_update_key64(key_out, 5'(k + 1)); + end + return key_out; + endfunction : present_get_dec_key64 + + function automatic logic [79:0] present_get_dec_key80(logic [79:0] key_in, + // total number of rounds employed + logic [4:0] round_cnt); + logic [79:0] key_out; + key_out = key_in; + for (int unsigned k = 0; k < round_cnt; k++) begin + key_out = present_update_key80(key_out, 5'(k + 1)); + end + return key_out; + endfunction : present_get_dec_key80 + + function automatic logic [127:0] present_get_dec_key128(logic [127:0] key_in, + // total number of rounds employed + logic [4:0] round_cnt); + logic [127:0] key_out; + key_out = key_in; + for (int unsigned k = 0; k < round_cnt; k++) begin + key_out = present_update_key128(key_out, 5'(k + 1)); + end + return key_out; + endfunction : present_get_dec_key128 + + ///////////////////////// + // Common Subfunctions // + ///////////////////////// + + function automatic logic [7:0] sbox4_8bit(logic [7:0] state_in, logic [15:0][3:0] sbox4); + logic [7:0] state_out; + // note that if simulation performance becomes an issue, this loop can be unrolled + for (int k = 0; k < 8/4; k++) begin + state_out[k*4 +: 4] = sbox4[state_in[k*4 +: 4]]; + end + return state_out; + endfunction : sbox4_8bit + + function automatic logic [15:0] sbox4_16bit(logic [15:0] state_in, logic [15:0][3:0] sbox4); + logic [15:0] state_out; + // note that if simulation performance becomes an issue, this loop can be unrolled + for (int k = 0; k < 2; k++) begin + state_out[k*8 +: 8] = sbox4_8bit(state_in[k*8 +: 8], sbox4); + end + return state_out; + endfunction : sbox4_16bit + + function automatic logic [31:0] sbox4_32bit(logic [31:0] state_in, logic [15:0][3:0] sbox4); + logic [31:0] state_out; + // note that if simulation performance becomes an issue, this loop can be unrolled + for (int k = 0; k < 4; k++) begin + state_out[k*8 +: 8] = sbox4_8bit(state_in[k*8 +: 8], sbox4); + end + return state_out; + endfunction : sbox4_32bit + + function automatic logic [63:0] sbox4_64bit(logic [63:0] state_in, logic [15:0][3:0] sbox4); + logic [63:0] state_out; + // note that if simulation performance becomes an issue, this loop can be unrolled + for (int k = 0; k < 8; k++) begin + state_out[k*8 +: 8] = sbox4_8bit(state_in[k*8 +: 8], sbox4); + end + return state_out; + endfunction : sbox4_64bit + + function automatic logic [7:0] perm_8bit(logic [7:0] state_in, logic [7:0][2:0] perm); + logic [7:0] state_out; + // note that if simulation performance becomes an issue, this loop can be unrolled + for (int k = 0; k < 8; k++) begin + state_out[perm[k]] = state_in[k]; + end + return state_out; + endfunction : perm_8bit + + function automatic logic [15:0] perm_16bit(logic [15:0] state_in, logic [15:0][3:0] perm); + logic [15:0] state_out; + // note that if simulation performance becomes an issue, this loop can be unrolled + for (int k = 0; k < 16; k++) begin + state_out[perm[k]] = state_in[k]; + end + return state_out; + endfunction : perm_16bit + + function automatic logic [31:0] perm_32bit(logic [31:0] state_in, logic [31:0][4:0] perm); + logic [31:0] state_out; + // note that if simulation performance becomes an issue, this loop can be unrolled + for (int k = 0; k < 32; k++) begin + state_out[perm[k]] = state_in[k]; + end + return state_out; + endfunction : perm_32bit + + function automatic logic [63:0] perm_64bit(logic [63:0] state_in, logic [63:0][5:0] perm); + logic [63:0] state_out; + // note that if simulation performance becomes an issue, this loop can be unrolled + for (int k = 0; k < 64; k++) begin + state_out[perm[k]] = state_in[k]; + end + return state_out; + endfunction : perm_64bit + +endpackage : abr_prim_cipher_pkg diff --git a/designs/Caliptra/src/adams-bridge/abr_prim_count.sv b/designs/Caliptra/src/adams-bridge/abr_prim_count.sv new file mode 100644 index 0000000..9f413b4 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/abr_prim_count.sv @@ -0,0 +1,261 @@ +// Copyright lowRISC contributors. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Hardened counter primitive: +// +// This internally uses a cross counter scheme with primary and a secondary counter, where the +// secondary counter counts in reverse direction. The sum of both counters must remain constant and +// equal to 2**Width-1 or otherwise an err_o will be asserted. +// +// This counter supports a generic clear / set / increment / decrement interface: +// +// clr_i: This clears the primary counter to ResetValue and adjusts the secondary counter to match +// (i.e. 2**Width-1-ResetValue). Clear has priority over set, increment and decrement. +// set_i: This sets the primary counter to set_cnt_i and adjusts the secondary counter to match +// (i.e. 2**Width-1-set_cnt_i). Set has priority over increment and decrement. +// incr_en_i: Increments the primary counter by step_i, and decrements the secondary by step_i. +// decr_en_i: Decrements the primary counter by step_i, and increments the secondary by step_i. +// +// Note that if both incr_en_i and decr_en_i are asserted at the same time, the counter remains +// unchanged. The counter is also protected against under- and overflows. + +`include "abr_prim_assert.sv" + +module abr_prim_count #( + parameter int Width = 2, + // Can be used to reset the counter to a different value than 0, for example when + // the counter is used as a down-counter. + parameter logic [Width-1:0] ResetValue = '0, + // This should only be disabled in special circumstances, for example + // in non-comportable IPs where an error does not trigger an alert. + parameter bit EnableAlertTriggerSVA = 1 +) ( + input clk_i, + input rst_b, + input clr_i, + input set_i, + input [Width-1:0] set_cnt_i, // Set value for the counter. + input incr_en_i, + input decr_en_i, + input [Width-1:0] step_i, // Increment/decrement step when enabled. + output logic [Width-1:0] cnt_o, // Current counter state + output logic [Width-1:0] cnt_next_o, // Next counter state + output logic err_o +); + + /////////////////// + // Counter logic // + /////////////////// + + // Reset Values for primary and secondary counters. + localparam int NumCnt = 2; + localparam logic [NumCnt-1:0][Width-1:0] ResetValues = {{Width{1'b1}} - ResetValue, // secondary + ResetValue}; // primary + + logic [NumCnt-1:0][Width-1:0] cnt_d, cnt_q, fpv_force; + +`ifndef FPV_SEC_CM_ON + // This becomes a free variable in FPV. + assign fpv_force = '0; +`endif + + for (genvar k = 0; k < NumCnt; k++) begin : gen_cnts + // Note that increments / decrements are reversed for the secondary counter. + logic incr_en, decr_en; + logic [Width-1:0] set_val; + if (k == 0) begin : gen_up_cnt + assign incr_en = incr_en_i; + assign decr_en = decr_en_i; + assign set_val = set_cnt_i; + end else begin : gen_dn_cnt + assign incr_en = decr_en_i; + assign decr_en = incr_en_i; + // The secondary value needs to be adjusted accordingly. + assign set_val = {Width{1'b1}} - set_cnt_i; + end + + // Main counter logic + logic [Width:0] ext_cnt; + assign ext_cnt = (decr_en) ? {1'b0, cnt_q[k]} - {1'b0, step_i} : + (incr_en) ? {1'b0, cnt_q[k]} + {1'b0, step_i} : {1'b0, cnt_q[k]}; + + // Saturation logic + logic uflow, oflow; + assign oflow = incr_en && ext_cnt[Width]; + assign uflow = decr_en && ext_cnt[Width]; + logic [Width-1:0] cnt_sat; + assign cnt_sat = (uflow) ? '0 : + (oflow) ? {Width{1'b1}} : ext_cnt[Width-1:0]; + + // Clock gate flops when in saturation, and do not + // count if both incr_en and decr_en are asserted. + logic cnt_en; + assign cnt_en = (incr_en ^ decr_en) && + ((incr_en && !(&cnt_q[k])) || + (decr_en && !(cnt_q[k] == '0))); + + // Counter muxes + assign cnt_d[k] = (clr_i) ? ResetValues[k] : + (set_i) ? set_val : + (cnt_en) ? cnt_sat : cnt_q[k]; + + logic [Width-1:0] cnt_unforced_q; + abr_prim_flop #( + .Width(Width), + .ResetValue(ResetValues[k]) + ) u_cnt_flop ( + .clk_i, + .rst_b, + .d_i(cnt_d[k]), + .q_o(cnt_unforced_q) + ); + + // fpv_force is only used during FPV. + assign cnt_q[k] = fpv_force[k] + cnt_unforced_q; + end + + // The sum of both counters must always equal the counter maximum. + logic [Width:0] sum; + assign sum = (cnt_q[0] + cnt_q[1]); + assign err_o = (sum != {1'b0, {Width{1'b1}}}); + + // Output count values + assign cnt_o = cnt_q[0]; + assign cnt_next_o = cnt_d[0]; + + //////////////// + // Assertions // + //////////////// +`ifdef ABR_INC_ASSERT + //VCS coverage off + // pragma coverage off + + // We need to disable most assertions in that case using a helper signal. + // We can't rely on err_o since some error patterns cannot be detected (e.g. all error + // patterns that still fullfill the sum constraint). + logic fpv_err_present; + assign fpv_err_present = |fpv_force; + + // Helper functions for assertions. + function automatic logic signed [Width+1:0] max(logic signed [Width+1:0] a, + logic signed [Width+1:0] b); + return (a > b) ? a : b; + endfunction + + function automatic logic signed [Width+1:0] min(logic signed [Width+1:0] a, + logic signed [Width+1:0] b); + return (a < b) ? a : b; + endfunction + //VCS coverage on + // pragma coverage on + + // Cnt next + `ABR_ASSERT(CntNext_A, + rst_b + |=> + cnt_o == $past(cnt_next_o), + clk_i, err_o || fpv_err_present || !rst_b) + + // Clear + `ABR_ASSERT(ClrFwd_A, + rst_b && clr_i + |=> + (cnt_o == ResetValue) && + (cnt_q[1] == ({Width{1'b1}} - ResetValue)), + clk_i, err_o || fpv_err_present || !rst_b) + `ABR_ASSERT(ClrBkwd_A, + rst_b && !(incr_en_i || decr_en_i || set_i) ##1 + $changed(cnt_o) && $changed(cnt_q[1]) + |-> + $past(clr_i), + clk_i, err_o || fpv_err_present || !rst_b) + + // Set + `ABR_ASSERT(SetFwd_A, + rst_b && set_i && !clr_i + |=> + (cnt_o == $past(set_cnt_i)) && + (cnt_q[1] == ({Width{1'b1}} - $past(set_cnt_i))), + clk_i, err_o || fpv_err_present || !rst_b) + `ABR_ASSERT(SetBkwd_A, + rst_b && !(incr_en_i || decr_en_i || clr_i) ##1 + $changed(cnt_o) && $changed(cnt_q[1]) + |-> + $past(set_i), + clk_i, err_o || fpv_err_present || !rst_b) + + // Do not count if both increment and decrement are asserted. + `ABR_ASSERT(IncrDecrUpDnCnt_A, + rst_b && incr_en_i && decr_en_i && !(clr_i || set_i) + |=> + $stable(cnt_o) && $stable(cnt_q[1]), + clk_i, err_o || fpv_err_present || !rst_b) + + // Up counter + `ABR_ASSERT(IncrUpCnt_A, + rst_b && incr_en_i && !(clr_i || set_i || decr_en_i) + |=> + cnt_o == min($past(cnt_o) + $past({2'b0, step_i}), {2'b0, {Width{1'b1}}}), + clk_i, err_o || fpv_err_present || !rst_b) + `ABR_ASSERT(IncrDnCnt_A, + rst_b && incr_en_i && !(clr_i || set_i || decr_en_i) + |=> + cnt_q[1] == max($past(signed'({2'b0, cnt_q[1]})) - $past({2'b0, step_i}), '0), + clk_i, err_o || fpv_err_present || !rst_b) + `ABR_ASSERT(UpCntIncrStable_A, + incr_en_i && !(clr_i || set_i || decr_en_i) && + cnt_o == {Width{1'b1}} + |=> + $stable(cnt_o), + clk_i, err_o || fpv_err_present || !rst_b) + `ABR_ASSERT(UpCntDecrStable_A, + decr_en_i && !(clr_i || set_i || incr_en_i) && + cnt_o == '0 + |=> + $stable(cnt_o), + clk_i, err_o || fpv_err_present || !rst_b) + + // Down counter + `ABR_ASSERT(DecrUpCnt_A, + rst_b && decr_en_i && !(clr_i || set_i || incr_en_i) + |=> + cnt_o == max($past(signed'({2'b0, cnt_o})) - $past({2'b0, step_i}), '0), + clk_i, err_o || fpv_err_present || !rst_b) + `ABR_ASSERT(DecrDnCnt_A, + rst_b && decr_en_i && !(clr_i || set_i || incr_en_i) + |=> + cnt_q[1] == min($past(cnt_q[1]) + $past({2'b0, step_i}), {2'b0, {Width{1'b1}}}), + clk_i, err_o || fpv_err_present || !rst_b) + `ABR_ASSERT(DnCntIncrStable_A, + rst_b && incr_en_i && !(clr_i || set_i || decr_en_i) && + cnt_q[1] == '0 + |=> + $stable(cnt_q[1]), + clk_i, err_o || fpv_err_present || !rst_b) + `ABR_ASSERT(DnCntDecrStable_A, + rst_b && decr_en_i && !(clr_i || set_i || incr_en_i) && + cnt_q[1] == {Width{1'b1}} + |=> + $stable(cnt_q[1]), + clk_i, err_o || fpv_err_present || !rst_b) + + // Error + `ABR_ASSERT(CntErrForward_A, + (cnt_q[1] + cnt_q[0]) != {Width{1'b1}} + |-> + err_o) + `ABR_ASSERT(CntErrBackward_A, + err_o + |-> + (cnt_q[1] + cnt_q[0]) != {Width{1'b1}}) + + // This logic that will be assign to one, when user adds macro + // ABR_ASSERT_PRIM_COUNT_ERROR_TRIGGER_ALERT to check the error with alert, in case that abr_prim_count + // is used in design without adding this assertion check. + logic unused_assert_connected; + + `ABR_ASSERT_INIT_NET(AssertConnected_A, unused_assert_connected === 1'b1 || !EnableAlertTriggerSVA) +`endif + +endmodule // abr_prim_count diff --git a/designs/Caliptra/src/adams-bridge/abr_prim_diff_decode.sv b/designs/Caliptra/src/adams-bridge/abr_prim_diff_decode.sv new file mode 100644 index 0000000..868f062 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/abr_prim_diff_decode.sv @@ -0,0 +1,285 @@ +// Copyright lowRISC contributors. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// This module decodes a differentially encoded signal and detects +// incorrectly encoded differential states. +// +// In case the differential pair crosses an asynchronous boundary, it has +// to be re-synchronized to the local clock. This can be achieved by +// setting the AsyncOn parameter to 1'b1. In that case, two additional +// input registers are added (to counteract metastability), and +// a pattern detector is instantiated that detects skewed level changes on +// the differential pair (i.e., when level changes on the diff pair are +// sampled one cycle apart due to a timing skew between the two wires). +// +// See also: abr_prim_alert_sender, abr_prim_alert_receiver, alert_handler + +`include "abr_prim_assert.sv" + +module abr_prim_diff_decode #( + // enables additional synchronization logic + parameter bit AsyncOn = 1'b0 +) ( + input clk_i, + input rst_b, + // input diff pair + input diff_pi, + input diff_ni, + // logical level and + // detected edges + output logic level_o, + output logic rise_o, + output logic fall_o, + // either rise or fall + output logic event_o, + //signal integrity issue detected + output logic sigint_o +); + + logic level_d, level_q; + + /////////////////////////////////////////////////////////////// + // synchronization regs for incoming diff pair (if required) // + /////////////////////////////////////////////////////////////// + if (AsyncOn) begin : gen_async + + typedef enum logic [1:0] {IsStd, IsSkewed, SigInt} state_e; + state_e state_d, state_q; + logic diff_p_edge, diff_n_edge, diff_check_ok, level; + + // 2 sync regs, one reg for edge detection + logic diff_pq, diff_nq, diff_pd, diff_nd; + + abr_prim_flop_2sync #( + .Width(1), + .ResetValue('0) + ) i_sync_p ( + .clk_i, + .rst_b, + .d_i(diff_pi), + .q_o(diff_pd) + ); + + abr_prim_flop_2sync #( + .Width(1), + .ResetValue(1'b1) + ) i_sync_n ( + .clk_i, + .rst_b, + .d_i(diff_ni), + .q_o(diff_nd) + ); + + // detect level transitions + assign diff_p_edge = diff_pq ^ diff_pd; + assign diff_n_edge = diff_nq ^ diff_nd; + + // detect sigint issue + assign diff_check_ok = diff_pd ^ diff_nd; + + // this is the current logical level + assign level = diff_pd; + + // outputs + assign level_o = level_d; + assign event_o = rise_o | fall_o; + + // sigint detection is a bit more involved in async case since + // we might have skew on the diff pair, which can result in a + // one cycle sampling delay between the two wires + // so we need a simple pattern matcher + // the following waves are legal + // clk | | | | | | | | + // _______ _______ + // p _______/ ... \________ + // _______ ________ + // n \_______ ... _______/ + // ____ ___ + // p __________/ ... \________ + // _______ ________ + // n \_______ ... _______/ + // + // i.e., level changes may be off by one cycle - which is permissible + // as long as this condition is only one cycle long. + + + always_comb begin : p_diff_fsm + // default + state_d = state_q; + level_d = level_q; + rise_o = 1'b0; + fall_o = 1'b0; + sigint_o = 1'b0; + + unique case (state_q) + // we remain here as long as + // the diff pair is correctly encoded + IsStd: begin + if (diff_check_ok) begin + level_d = level; + if (diff_p_edge && diff_n_edge) begin + if (level) begin + rise_o = 1'b1; + end else begin + fall_o = 1'b1; + end + end + end else begin + if (diff_p_edge || diff_n_edge) begin + state_d = IsSkewed; + end else begin + state_d = SigInt; + sigint_o = 1'b1; + end + end + end + // diff pair must be correctly encoded, otherwise we got a sigint + IsSkewed: begin + if (diff_check_ok) begin + state_d = IsStd; + level_d = level; + if (level) rise_o = 1'b1; + else fall_o = 1'b1; + end else begin + state_d = SigInt; + sigint_o = 1'b1; + end + end + // Signal integrity issue detected, remain here + // until resolved + SigInt: begin + sigint_o = 1'b1; + if (diff_check_ok) begin + state_d = IsStd; + sigint_o = 1'b0; + end + end + default : ; + endcase + end + + always_ff @(posedge clk_i or negedge rst_b) begin : p_sync_reg + if (!rst_b) begin + state_q <= IsStd; + diff_pq <= 1'b0; + diff_nq <= 1'b1; + level_q <= 1'b0; + end else begin + state_q <= state_d; + diff_pq <= diff_pd; + diff_nq <= diff_nd; + level_q <= level_d; + end + end + + ////////////////////////////////////////////////////////// + // fully synchronous case, no skew present in this case // + ////////////////////////////////////////////////////////// + end else begin : gen_no_async + logic diff_pq, diff_pd; + + // one reg for edge detection + assign diff_pd = diff_pi; + + // incorrect encoding -> signal integrity issue + assign sigint_o = ~(diff_pi ^ diff_ni); + + assign level_o = (sigint_o) ? level_q : diff_pi; + assign level_d = level_o; + + // detect level transitions + assign rise_o = (~diff_pq & diff_pi) & ~sigint_o; + assign fall_o = ( diff_pq & ~diff_pi) & ~sigint_o; + assign event_o = rise_o | fall_o; + + always_ff @(posedge clk_i or negedge rst_b) begin : p_edge_reg + if (!rst_b) begin + diff_pq <= 1'b0; + level_q <= 1'b0; + end else begin + diff_pq <= diff_pd; + level_q <= level_d; + end + end + end + + //////////////// + // assertions // + //////////////// + + // shared assertions + // sigint -> level stays the same during sigint + // $isunknown is needed to avoid false assertion in first clock cycle + `ABR_ASSERT(SigintLevelCheck_A, ##1 sigint_o |-> $stable(level_o)) + // sigint -> no additional events asserted at output + `ABR_ASSERT(SigintEventCheck_A, sigint_o |-> !event_o) + `ABR_ASSERT(SigintRiseCheck_A, sigint_o |-> !rise_o) + `ABR_ASSERT(SigintFallCheck_A, sigint_o |-> !fall_o) + + if (AsyncOn) begin : gen_async_assert + // assertions for asynchronous case +`ifdef ABR_INC_ASSERT + `ifndef FPV_ALERT_NO_SIGINT_ERR + // correctly detect sigint issue (only one transition cycle of permissible due to skew) + `ABR_ASSERT(SigintCheck0_A, gen_async.diff_pd == gen_async.diff_nd [*2] |-> sigint_o) + // the synchronizer adds 2 cycles of latency with respect to input signals. + `ABR_ASSERT(SigintCheck1_A, + ##1 (gen_async.diff_pd ^ gen_async.diff_nd) && + $stable(gen_async.diff_pd) && $stable(gen_async.diff_nd) ##1 + $rose(gen_async.diff_pd) && $stable(gen_async.diff_nd) ##1 + $stable(gen_async.diff_pd) && $fell(gen_async.diff_nd) + |-> rise_o) + `ABR_ASSERT(SigintCheck2_A, + ##1 (gen_async.diff_pd ^ gen_async.diff_nd) && + $stable(gen_async.diff_pd) && $stable(gen_async.diff_nd) ##1 + $fell(gen_async.diff_pd) && $stable(gen_async.diff_nd) ##1 + $stable(gen_async.diff_pd) && $rose(gen_async.diff_nd) + |-> fall_o) + `ABR_ASSERT(SigintCheck3_A, + ##1 (gen_async.diff_pd ^ gen_async.diff_nd) && + $stable(gen_async.diff_pd) && $stable(gen_async.diff_nd) ##1 + $rose(gen_async.diff_nd) && $stable(gen_async.diff_pd) ##1 + $stable(gen_async.diff_nd) && $fell(gen_async.diff_pd) + |-> fall_o) + `ABR_ASSERT(SigintCheck4_A, + ##1 (gen_async.diff_pd ^ gen_async.diff_nd) && + $stable(gen_async.diff_pd) && $stable(gen_async.diff_nd) ##1 + $fell(gen_async.diff_nd) && $stable(gen_async.diff_pd) ##1 + $stable(gen_async.diff_nd) && $rose(gen_async.diff_pd) + |-> rise_o) + `endif + + // correctly detect edges + `ABR_ASSERT(RiseCheck_A, + !sigint_o ##1 $rose(gen_async.diff_pd) && (gen_async.diff_pd ^ gen_async.diff_nd) |-> + ##[0:1] rise_o, clk_i, !rst_b || sigint_o) + `ABR_ASSERT(FallCheck_A, + !sigint_o ##1 $fell(gen_async.diff_pd) && (gen_async.diff_pd ^ gen_async.diff_nd) |-> + ##[0:1] fall_o, clk_i, !rst_b || sigint_o) + `ABR_ASSERT(EventCheck_A, + !sigint_o ##1 $changed(gen_async.diff_pd) && (gen_async.diff_pd ^ gen_async.diff_nd) |-> + ##[0:1] event_o, clk_i, !rst_b || sigint_o) + // correctly detect level + `ABR_ASSERT(LevelCheck0_A, + !sigint_o && (gen_async.diff_pd ^ gen_async.diff_nd) [*2] |-> + gen_async.diff_pd == level_o, + clk_i, !rst_b || sigint_o) +`endif + end else begin : gen_sync_assert + // assertions for synchronous case + + `ifndef FPV_ALERT_NO_SIGINT_ERR + // correctly detect sigint issue + `ABR_ASSERT(SigintCheck_A, diff_pi == diff_ni |-> sigint_o) + `endif + + // correctly detect edges + `ABR_ASSERT(RiseCheck_A, ##1 $rose(diff_pi) && (diff_pi ^ diff_ni) |-> rise_o) + `ABR_ASSERT(FallCheck_A, ##1 $fell(diff_pi) && (diff_pi ^ diff_ni) |-> fall_o) + `ABR_ASSERT(EventCheck_A, ##1 $changed(diff_pi) && (diff_pi ^ diff_ni) |-> event_o) + // correctly detect level + `ABR_ASSERT(LevelCheck_A, (diff_pi ^ diff_ni) |-> diff_pi == level_o) + end + +endmodule : abr_prim_diff_decode diff --git a/designs/Caliptra/src/adams-bridge/abr_prim_dom_and_2share.sv b/designs/Caliptra/src/adams-bridge/abr_prim_dom_and_2share.sv new file mode 100644 index 0000000..e1f6eb9 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/abr_prim_dom_and_2share.sv @@ -0,0 +1,173 @@ +// Copyright lowRISC contributors. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Domain-Oriented Masking GF(2) Multiplier with 2-shares +// ref: Higher-Order Side-Channel Protected Implementations of Keccak +// https://eprint.iacr.org/2017/395.pdf +// +// q0 = a0 & b0 + (a0 & b1 + z) +// q1 = a1 & b1 + (a1 & b0 + z) +// () ==> registered +// +// all input should be stable for two clocks +// as the output is valid after a clock +// For z, it can use other slice from the state +// as it is fairly random w.r.t the current inputs. + +// General formula of Q in the paper +// Qi = t{i,i} + Sig(j>i,d)(t{i,j}+Z{i+j*(j-1)/2}) + Sig(j0,1)(t{0,j}+Z{j(j-1)/2}) + Sig(j<0,d)(..) +// = a0&b0 + (a0&b1 + z0 + 0) +// Q1 = t{1,1} + sig(j>1,1)(...) + sig(j<1,1)(t{1,j} + Z{j}) +// = a1&b1 + (0 + a1&b0 + z0) + +`include "abr_prim_assert.sv" + +module abr_prim_dom_and_2share #( + parameter int DW = 64, // Input width + parameter bit Pipeline = 1'b0 // Enable full pipelining +) ( + input clk_i, + input rst_b, + + input [DW-1:0] a0_i, // share0 of a + input [DW-1:0] a1_i, // share1 of a + input [DW-1:0] b0_i, // share0 of b + input [DW-1:0] b1_i, // share1 of b + input z_valid_i, // random number input validity + input [DW-1:0] z_i, // random number + + output logic [DW-1:0] q0_o, // share0 of q + output logic [DW-1:0] q1_o, // share1 of q + output logic [DW-1:0] prd_o // pseudo-random data for other instances +); + + logic [DW-1:0] t0_d, t0_q, t1_d, t1_q; + logic [DW-1:0] t_a0b0, t_a1b1; + logic [DW-1:0] t_a0b0_d, t_a1b1_d; + logic [DW-1:0] t_a0b1, t_a1b0; + + ///////////////// + // Calculation // + ///////////////// + // Inner-domain terms + assign t_a0b0_d = a0_i & b0_i; + assign t_a1b1_d = a1_i & b1_i; + + // Cross-domain terms + assign t_a0b1 = a0_i & b1_i; + assign t_a1b0 = a1_i & b0_i; + + /////////////// + // Resharing // + /////////////// + // Resharing of cross-domain terms + + // Preserve the logic sequence for XOR not to proceed cross-domain AND. + abr_prim_xor2 #( + .Width ( DW*2 ) + ) u_abr_prim_xor_t01 ( + .in0_i ( {t_a0b1, t_a1b0} ), + .in1_i ( {z_i, z_i} ), + .out_o ( {t0_d, t1_d} ) + ); + + // Register stage + abr_prim_flop_en #( + .Width ( DW*2 ), + .ResetValue ( '0 ) + ) u_abr_prim_flop_t01 ( + .clk_i ( clk_i ), + .rst_b ( rst_b ), + .en_i ( z_valid_i ), + .d_i ( {t0_d, t1_d} ), + .q_o ( {t0_q, t1_q} ) + ); + + ///////////////////////// + // Optional Pipelining // + ///////////////////////// + + if (Pipeline == 1'b1) begin : gen_inner_domain_regs + // Add pipeline registers on inner-domain terms prior to integration. This allows accepting new + // input data every clock cycle and prevents SCA leakage occurring due to the integration of + // reshared cross-domain terms with inner-domain terms derived from different input data. + + logic [DW-1:0] t_a0b0_q, t_a1b1_q; + abr_prim_flop_en #( + .Width ( DW*2 ), + .ResetValue ( '0 ) + ) u_abr_prim_flop_tab01 ( + .clk_i ( clk_i ), + .rst_b ( rst_b ), + .en_i ( z_valid_i ), + .d_i ( {t_a0b0_d, t_a1b1_d} ), + .q_o ( {t_a0b0_q, t_a1b1_q} ) + ); + + assign t_a0b0 = t_a0b0_q; + assign t_a1b1 = t_a1b1_q; + + end else begin : gen_no_inner_domain_regs + // Do not add the optional pipeline registers on the inner-domain terms. This allows to save + // some area in case the multiplier does not need to accept new data in every cycle. However, + // this can cause SCA leakage as during the clock cycle in which new data arrives, the new + // inner-domain terms are integrated with the previous, reshared cross-domain terms. + + assign t_a0b0 = t_a0b0_d; + assign t_a1b1 = t_a1b1_d; + end + + ///////////////// + // Integration // + ///////////////// + + // Preserve the logic sequence for XOR not to proceed the inner-domain AND. + abr_prim_xor2 #( + .Width ( DW*2 ) + ) u_abr_prim_xor_q01 ( + .in0_i ( {t_a0b0, t_a1b1} ), + .in1_i ( {t0_q, t1_q} ), + .out_o ( {q0_o, q1_o} ) + ); + + // Use intermediate results for remasking computations in another instance in the following + // clock cycle. Use one share only. Directly use output of flops updating with z_valid_i. + // t1_q is obtained by remasking t_a1b0 with z_i. Since z_i is uniformly distributed and + // independent of a1/b0_i, t1_q is also uniformly distributed and independent of a1/b0_i. + // For details, see Lemma 1 in Canright, "A very compact 'perfectly masked' S-box for AES + // (corrected)" available at https://eprint.iacr.org/2009/011.pdf + assign prd_o = t1_q; + + // DOM AND should be same as unmasked computation + // The correct test sequence will be: + // 1. inputs are changed + // 2. check if z_valid_i, + // 3. at the next cycle, inputs are still stable (assumption) - only in case Pipeline = 0 + // 4. and results Q == A & B (assertion) + + // To speed up the FPV process, random value is ready in less than or + // equal to two cycles. + `ABR_ASSUME_FPV(RandomReadyInShortTime_A, + $changed(a0_i) || $changed(a1_i) || $changed(b0_i) || $changed(b1_i) + |-> ##[0:2] z_valid_i, + clk_i, !rst_b) + + if (Pipeline == 0) begin: g_assert_stable + // If Pipeline is not set, the computation takes two cycles without flop + // crossing the domain. In this case, the signal should be stable for at + // least two cycles. + `ABR_ASSUME(StableTwoCycles_M, + ($changed(a0_i) || $changed(a1_i) || $changed(b0_i) || $changed(b1_i)) + ##[0:$] z_valid_i |=> + $stable(a0_i) && $stable(a1_i) && $stable(b0_i) && $stable(b1_i)) + end + + `ABR_ASSERT(UnmaskedAndMatched_A, + z_valid_i |=> (q0_o ^ q1_o) == + (($past(a0_i) ^ $past(a1_i)) & ($past(b0_i) ^ $past(b1_i))), + clk_i, !rst_b) + +endmodule diff --git a/designs/Caliptra/src/adams-bridge/abr_prim_edge_detector.sv b/designs/Caliptra/src/adams-bridge/abr_prim_edge_detector.sv new file mode 100644 index 0000000..ebed843 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/abr_prim_edge_detector.sv @@ -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 +// +// Edge Detector + +module abr_prim_edge_detector #( + parameter int unsigned Width = 1, + + parameter logic [Width-1:0] ResetValue = '0, + + // EnSync + // + // Enable Synchronizer to the input signal. + // It is assumed that the input signal is glitch free (registered input). + parameter bit EnSync = 1'b 1 +) ( + input clk_i, + input rst_b, + + input [Width-1:0] d_i, + output logic [Width-1:0] q_sync_o, + + output logic [Width-1:0] q_posedge_pulse_o, + output logic [Width-1:0] q_negedge_pulse_o +); + + logic [Width-1:0] q_sync_d, q_sync_q; + + if (EnSync) begin : g_sync + abr_prim_flop_2sync #( + .Width (Width), + .ResetValue (ResetValue) + ) u_sync ( + .clk_i, + .rst_b, + .d_i, + .q_o (q_sync_d) + ); + end : g_sync + else begin : g_nosync + assign q_sync_d = d_i; + end : g_nosync + + assign q_sync_o = q_sync_d; + + always_ff @(posedge clk_i or negedge rst_b) begin + if (!rst_b) q_sync_q <= ResetValue; + else q_sync_q <= q_sync_d; + end + + assign q_posedge_pulse_o = q_sync_d & ~q_sync_q; + assign q_negedge_pulse_o = ~q_sync_d & q_sync_q; + +endmodule : abr_prim_edge_detector diff --git a/designs/Caliptra/src/adams-bridge/abr_prim_fifo_sync.sv b/designs/Caliptra/src/adams-bridge/abr_prim_fifo_sync.sv new file mode 100644 index 0000000..7c269ec --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/abr_prim_fifo_sync.sv @@ -0,0 +1,198 @@ +// Copyright lowRISC contributors. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Generic synchronous fifo for use in a variety of devices. + +`include "abr_prim_assert.sv" + +module abr_prim_fifo_sync #( + parameter int unsigned Width = 16, + parameter bit Pass = 1'b1, // if == 1 allow requests to pass through empty FIFO + parameter int unsigned Depth = 4, + parameter bit OutputZeroIfEmpty = 1'b1, // if == 1 always output 0 when FIFO is empty + parameter bit Secure = 1'b0, // use prim count for pointers + // derived parameter + localparam int DepthW = abr_prim_util_pkg::vbits(Depth+1) +) ( + input clk_i, + input rst_b, + // synchronous clear / flush port + input clr_i, + // write port + input wvalid_i, + output wready_o, + input [Width-1:0] wdata_i, + // read port + output rvalid_o, + input rready_i, + output [Width-1:0] rdata_o, + // occupancy + output full_o, + output [DepthW-1:0] depth_o, + output err_o +); + + + // FIFO is in complete passthrough mode + if (Depth == 0) begin : gen_passthru_fifo + `ABR_ASSERT_INIT(paramCheckPass, Pass == 1) + + assign depth_o = 1'b0; //output is meaningless + + // devie facing + assign rvalid_o = wvalid_i; + assign rdata_o = wdata_i; + + // host facing + assign wready_o = rready_i; + assign full_o = rready_i; + + // this avoids lint warnings + logic unused_clr; + assign unused_clr = clr_i; + + // No error + assign err_o = 1'b 0; + + // Normal FIFO construction + end else begin : gen_normal_fifo + + localparam int unsigned PTRV_W = abr_prim_util_pkg::vbits(Depth); + localparam int unsigned PTR_WIDTH = PTRV_W+1; + + logic [PTR_WIDTH-1:0] fifo_wptr, fifo_rptr; + logic fifo_incr_wptr, fifo_incr_rptr, fifo_empty; + + // module under reset flag + logic under_rst; + always_ff @(posedge clk_i or negedge rst_b) begin + if (!rst_b) begin + under_rst <= 1'b1; + end else if (under_rst) begin + under_rst <= ~under_rst; + end + end + + // create the write and read pointers + logic full, empty; + logic wptr_msb; + logic rptr_msb; + logic [PTRV_W-1:0] wptr_value; + logic [PTRV_W-1:0] rptr_value; + + assign wptr_msb = fifo_wptr[PTR_WIDTH-1]; + assign rptr_msb = fifo_rptr[PTR_WIDTH-1]; + assign wptr_value = fifo_wptr[0+:PTRV_W]; + assign rptr_value = fifo_rptr[0+:PTRV_W]; + assign depth_o = (full) ? DepthW'(Depth) : + (wptr_msb == rptr_msb) ? DepthW'(wptr_value) - DepthW'(rptr_value) : + (DepthW'(Depth) - DepthW'(rptr_value) + DepthW'(wptr_value)) ; + + assign fifo_incr_wptr = wvalid_i & wready_o & ~under_rst; + assign fifo_incr_rptr = rvalid_o & rready_i & ~under_rst; + + // full and not ready for write are two different concepts. + // The latter can be '0' when under reset, while the former is an indication that no more + // entries can be written. + assign wready_o = ~full & ~under_rst; + assign full_o = full; + assign rvalid_o = ~empty & ~under_rst; + + abr_prim_fifo_sync_cnt #( + .Width(PTR_WIDTH), + .Depth(Depth), + .Secure(Secure) + ) u_fifo_cnt ( + .clk_i, + .rst_b, + .clr_i, + .incr_wptr_i(fifo_incr_wptr), + .incr_rptr_i(fifo_incr_rptr), + .wptr_o(fifo_wptr), + .rptr_o(fifo_rptr), + .err_o + ); + + //always_ff @(posedge clk_i or negedge rst_b) begin + // if (!rst_b) begin + // fifo_wptr <= {(PTR_WIDTH){1'b0}}; + // end else if (clr_i) begin + // fifo_wptr <= {(PTR_WIDTH){1'b0}}; + // end else if (fifo_incr_wptr) begin + // if (fifo_wptr[PTR_WIDTH-2:0] == (PTR_WIDTH-1)'(Depth-1)) begin + // fifo_wptr <= {~fifo_wptr[PTR_WIDTH-1],{(PTR_WIDTH-1){1'b0}}}; + // end else begin + // fifo_wptr <= fifo_wptr + {{(PTR_WIDTH-1){1'b0}},1'b1}; + // end + // end + //end + // + //always_ff @(posedge clk_i or negedge rst_b) begin + // if (!rst_b) begin + // fifo_rptr <= {(PTR_WIDTH){1'b0}}; + // end else if (clr_i) begin + // fifo_rptr <= {(PTR_WIDTH){1'b0}}; + // end else if (fifo_incr_rptr) begin + // if (fifo_rptr[PTR_WIDTH-2:0] == (PTR_WIDTH-1)'(Depth-1)) begin + // fifo_rptr <= {~fifo_rptr[PTR_WIDTH-1],{(PTR_WIDTH-1){1'b0}}}; + // end else begin + // fifo_rptr <= fifo_rptr + {{(PTR_WIDTH-1){1'b0}},1'b1}; + // end + // end + //end + + assign full = (fifo_wptr == (fifo_rptr ^ {1'b1,{(PTR_WIDTH-1){1'b0}}})); + assign fifo_empty = (fifo_wptr == fifo_rptr); + + + // the generate blocks below are needed to avoid lint errors due to array indexing + // in the where the fifo only has one storage element + logic [Depth-1:0][Width-1:0] storage; + logic [Width-1:0] storage_rdata; + if (Depth == 1) begin : gen_depth_eq1 + assign storage_rdata = storage[0]; + + always_ff @(posedge clk_i) + if (fifo_incr_wptr) begin + storage[0] <= wdata_i; + end + // fifo with more than one storage element + end else begin : gen_depth_gt1 + assign storage_rdata = storage[fifo_rptr[PTR_WIDTH-2:0]]; + + always_ff @(posedge clk_i) + if (fifo_incr_wptr) begin + storage[fifo_wptr[PTR_WIDTH-2:0]] <= wdata_i; + end + end + + logic [Width-1:0] rdata_int; + if (Pass == 1'b1) begin : gen_pass + assign rdata_int = (fifo_empty && wvalid_i) ? wdata_i : storage_rdata; + assign empty = fifo_empty & ~wvalid_i; + end else begin : gen_nopass + assign rdata_int = storage_rdata; + assign empty = fifo_empty; + end + + if (OutputZeroIfEmpty == 1'b1) begin : gen_output_zero + assign rdata_o = empty ? 'b0 : rdata_int; + end else begin : gen_no_output_zero + assign rdata_o = rdata_int; + end + + `ABR_ASSERT(depthShallNotExceedParamDepth, !empty |-> depth_o <= DepthW'(Depth)) + end // block: gen_normal_fifo + + + ////////////////////// + // Known Assertions // + ////////////////////// + + `ABR_ASSERT(DataKnown_A, rvalid_o |-> !$isunknown(rdata_o)) + `ABR_ASSERT_KNOWN(DepthKnown_A, depth_o) + `ABR_ASSERT_KNOWN(RvalidKnown_A, rvalid_o) + `ABR_ASSERT_KNOWN(WreadyKnown_A, wready_o) + +endmodule diff --git a/designs/Caliptra/src/adams-bridge/abr_prim_fifo_sync_cnt.sv b/designs/Caliptra/src/adams-bridge/abr_prim_fifo_sync_cnt.sv new file mode 100644 index 0000000..6649f24 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/abr_prim_fifo_sync_cnt.sv @@ -0,0 +1,102 @@ +// Copyright lowRISC contributors. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Generic synchronous fifo for use in a variety of devices. + +`include "abr_prim_assert.sv" + +module abr_prim_fifo_sync_cnt #( + parameter int Depth = 4, + parameter int Width = 16, + parameter bit Secure = 1'b0 +) ( + input clk_i, + input rst_b, + input clr_i, + input incr_wptr_i, + input incr_rptr_i, + output logic [Width-1:0] wptr_o, + output logic [Width-1:0] rptr_o, + output logic err_o +); + + logic wptr_wrap; + logic [Width-1:0] wptr_wrap_cnt; + logic rptr_wrap; + logic [Width-1:0] rptr_wrap_cnt; + + assign wptr_wrap = incr_wptr_i & (wptr_o[Width-2:0] == unsigned'((Width-1)'(Depth-1))); + assign rptr_wrap = incr_rptr_i & (rptr_o[Width-2:0] == unsigned'((Width-1)'(Depth-1))); + + assign wptr_wrap_cnt = {~wptr_o[Width-1],{(Width-1){1'b0}}}; + assign rptr_wrap_cnt = {~rptr_o[Width-1],{(Width-1){1'b0}}}; + + if (Secure) begin : gen_secure_ptrs + logic wptr_err; + abr_prim_count #( + .Width(Width) + ) u_wptr ( + .clk_i, + .rst_b, + .clr_i, + .set_i(wptr_wrap), + .set_cnt_i(wptr_wrap_cnt), + .incr_en_i(incr_wptr_i), + .decr_en_i(1'b0), + .step_i(Width'(1'b1)), + .cnt_o(wptr_o), + .cnt_next_o(), + .err_o(wptr_err) + ); + + logic rptr_err; + abr_prim_count #( + .Width(Width) + ) u_rptr ( + .clk_i, + .rst_b, + .clr_i, + .set_i(rptr_wrap), + .set_cnt_i(rptr_wrap_cnt), + .incr_en_i(incr_rptr_i), + .decr_en_i(1'b0), + .step_i(Width'(1'b1)), + .cnt_o(rptr_o), + .cnt_next_o(), + .err_o(rptr_err) + ); + + assign err_o = wptr_err | rptr_err; + + end else begin : gen_normal_ptrs + always_ff @(posedge clk_i or negedge rst_b) begin + if (!rst_b) begin + wptr_o <= {(Width){1'b0}}; + end else if (clr_i) begin + wptr_o <= {(Width){1'b0}}; + end else if (wptr_wrap) begin + wptr_o <= wptr_wrap_cnt; + end else if (incr_wptr_i) begin + wptr_o <= wptr_o + {{(Width-1){1'b0}},1'b1}; + end + end + + always_ff @(posedge clk_i or negedge rst_b) begin + if (!rst_b) begin + rptr_o <= {(Width){1'b0}}; + end else if (clr_i) begin + rptr_o <= {(Width){1'b0}}; + end else if (rptr_wrap) begin + rptr_o <= rptr_wrap_cnt; + end else if (incr_rptr_i) begin + rptr_o <= rptr_o + {{(Width-1){1'b0}},1'b1}; + end + end + + assign err_o = '0; + end + + + +endmodule // abr_prim_fifo_sync_cnt diff --git a/designs/Caliptra/src/adams-bridge/abr_prim_flop.sv b/designs/Caliptra/src/adams-bridge/abr_prim_flop.sv new file mode 100755 index 0000000..e88cc3d --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/abr_prim_flop.sv @@ -0,0 +1,49 @@ +// Copyright lowRISC contributors. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// This file is auto-generated. +// Used parser: Fallback (regex) + +`ifndef ABR_PRIM_DEFAULT_IMPL + `define ABR_PRIM_DEFAULT_IMPL abr_prim_pkg::ImplGeneric +`endif + +// This is to prevent AscentLint warnings in the generated +// abstract prim wrapper. These warnings occur due to the .* +// use. TODO: we may want to move these inline waivers +// into a separate, generated waiver file for consistency. +//ri lint_check_off OUTPUT_NOT_DRIVEN INPUT_NOT_READ HIER_BRANCH_NOT_READ +module abr_prim_flop + +#( + + parameter int Width = 1, + parameter logic [Width-1:0] ResetValue = 0 + +) ( + input clk_i, + input rst_b, + input [Width-1:0] d_i, + output logic [Width-1:0] q_o +); + parameter abr_prim_pkg::impl_e Impl = `ABR_PRIM_DEFAULT_IMPL; + +if (Impl == abr_prim_pkg::ImplXilinx) begin : gen_xilinx + abr_prim_xilinx_flop #( + .ResetValue(ResetValue), + .Width(Width) + ) u_impl_xilinx ( + .* + ); +end else begin : gen_generic + abr_prim_generic_flop #( + .ResetValue(ResetValue), + .Width(Width) + ) u_impl_generic ( + .* + ); +end + +endmodule +//ri lint_check_on OUTPUT_NOT_DRIVEN INPUT_NOT_READ HIER_BRANCH_NOT_READ diff --git a/designs/Caliptra/src/adams-bridge/abr_prim_flop_2sync.sv b/designs/Caliptra/src/adams-bridge/abr_prim_flop_2sync.sv new file mode 100644 index 0000000..301968f --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/abr_prim_flop_2sync.sv @@ -0,0 +1,61 @@ +// Copyright lowRISC contributors. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Generic double-synchronizer flop +// This may need to be moved to abr_prim_generic if libraries have a specific cell +// for synchronization + +module abr_prim_flop_2sync #( + parameter int Width = 16, + parameter logic [Width-1:0] ResetValue = '0, + parameter bit EnablePrimCdcRand = 1 +) ( + input clk_i, + input rst_b, + input [Width-1:0] d_i, + output logic [Width-1:0] q_o +); + + logic [Width-1:0] d_o; + logic [Width-1:0] intq; + +`ifdef ABR_SIMULATION + + abr_prim_cdc_rand_delay #( + .DataWidth(Width), + .Enable(EnablePrimCdcRand) + ) u_abr_prim_cdc_rand_delay ( + .clk_i, + .rst_b, + .src_data_i(d_i), + .prev_data_i(intq), + .dst_data_o(d_o) + ); +`else // !`ifdef ABR_SIMULATION + logic unused_sig; + assign unused_sig = EnablePrimCdcRand; + always_comb d_o = d_i; +`endif // !`ifdef ABR_SIMULATION + + abr_prim_flop #( + .Width(Width), + .ResetValue(ResetValue) + ) u_sync_1 ( + .clk_i, + .rst_b, + .d_i(d_o), + .q_o(intq) + ); + + abr_prim_flop #( + .Width(Width), + .ResetValue(ResetValue) + ) u_sync_2 ( + .clk_i, + .rst_b, + .d_i(intq), + .q_o + ); + +endmodule : abr_prim_flop_2sync diff --git a/designs/Caliptra/src/adams-bridge/abr_prim_flop_en.sv b/designs/Caliptra/src/adams-bridge/abr_prim_flop_en.sv new file mode 100644 index 0000000..655ab0f --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/abr_prim_flop_en.sv @@ -0,0 +1,53 @@ +// Copyright lowRISC contributors. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// This file is auto-generated. +// Used parser: Fallback (regex) + +`ifndef ABR_PRIM_DEFAULT_IMPL + `define ABR_PRIM_DEFAULT_IMPL abr_prim_pkg::ImplGeneric +`endif + +// This is to prevent AscentLint warnings in the generated +// abstract prim wrapper. These warnings occur due to the .* +// use. TODO: we may want to move these inline waivers +// into a separate, generated waiver file for consistency. +//ri lint_check_off OUTPUT_NOT_DRIVEN INPUT_NOT_READ HIER_BRANCH_NOT_READ +module abr_prim_flop_en + +#( + + parameter int Width = 1, + parameter bit EnSecBuf = 0, + parameter logic [Width-1:0] ResetValue = 0 + +) ( + input clk_i, + input rst_b, + input en_i, + input [Width-1:0] d_i, + output logic [Width-1:0] q_o +); + parameter abr_prim_pkg::impl_e Impl = `ABR_PRIM_DEFAULT_IMPL; + +if (Impl == abr_prim_pkg::ImplXilinx) begin : gen_xilinx + abr_prim_xilinx_flop_en #( + .EnSecBuf(EnSecBuf), + .ResetValue(ResetValue), + .Width(Width) + ) u_impl_xilinx ( + .* + ); +end else begin : gen_generic + abr_prim_generic_flop_en #( + .EnSecBuf(EnSecBuf), + .ResetValue(ResetValue), + .Width(Width) + ) u_impl_generic ( + .* + ); +end + +endmodule +//ri lint_check_on OUTPUT_NOT_DRIVEN INPUT_NOT_READ HIER_BRANCH_NOT_READ diff --git a/designs/Caliptra/src/adams-bridge/abr_prim_flop_macros.sv b/designs/Caliptra/src/adams-bridge/abr_prim_flop_macros.sv new file mode 100644 index 0000000..81392b4 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/abr_prim_flop_macros.sv @@ -0,0 +1,74 @@ +// Copyright lowRISC contributors. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +`ifndef ABR_PRIM_FLOP_MACROS_SV +`define ABR_PRIM_FLOP_MACROS_SV + +///////////////////////////////////// +// Default Values for Macros below // +///////////////////////////////////// + +`define ABR_PRIM_FLOP_CLK clk_i +`define ABR_PRIM_FLOP_RST rst_b +`define ABR_PRIM_FLOP_RESVAL '0 + +///////////////////// +// Register Macros // +///////////////////// + +// TODO: define other variations of register macros so that they can be used throughout all designs +// to make the code more concise. + +// Register with asynchronous reset. +`define ABR_PRIM_FLOP_A(__d, __q, __resval = `ABR_PRIM_FLOP_RESVAL, __clk = `ABR_PRIM_FLOP_CLK, __rst_n = `ABR_PRIM_FLOP_RST) \ + always_ff @(posedge __clk or negedge __rst_n) begin \ + if (!__rst_n) begin \ + __q <= __resval; \ + end else begin \ + __q <= __d; \ + end \ + end + +/////////////////////////// +// Macro for Sparse FSMs // +/////////////////////////// + +// Simulation tools typically infer FSMs and report coverage for these separately. However, tools +// like Xcelium and VCS seem to have problems inferring FSMs if the state register is not coded in +// a behavioral always_ff block in the same hierarchy. To that end, this uses a modified variant +// with a second behavioral register definition for RTL simulations so that FSMs can be inferred. +// Note that in this variant, the __q output is disconnected from abr_prim_sparse_fsm_flop and attached +// to the behavioral flop. An assertion is added to ensure equivalence between the +// abr_prim_sparse_fsm_flop output and the behavioral flop output in that case. +`define ABR_PRIM_FLOP_SPARSE_FSM(__name, __d, __q, __type, __resval = `ABR_PRIM_FLOP_RESVAL, __clk = `ABR_PRIM_FLOP_CLK, __rst_n = `ABR_PRIM_FLOP_RST, __alert_trigger_sva_en = 1) \ + `ifdef ABR_SIMULATION \ + abr_prim_sparse_fsm_flop #( \ + .StateEnumT(__type), \ + .Width($bits(__type)), \ + .ResetValue($bits(__type)'(__resval)), \ + .EnableAlertTriggerSVA(__alert_trigger_sva_en), \ + .CustomForceName(`ABR_PRIM_STRINGIFY(__q)) \ + ) __name ( \ + .clk_i ( __clk ), \ + .rst_b ( __rst_n ), \ + .state_i ( __d ), \ + .state_o ( ) \ + ); \ + `ABR_PRIM_FLOP_A(__d, __q, __resval, __clk, __rst_n) \ + `ABR_ASSERT(``__name``_A, __q === ``__name``.state_o) \ + `else \ + abr_prim_sparse_fsm_flop #( \ + .StateEnumT(__type), \ + .Width($bits(__type)), \ + .ResetValue($bits(__type)'(__resval)), \ + .EnableAlertTriggerSVA(__alert_trigger_sva_en) \ + ) __name ( \ + .clk_i ( __clk ), \ + .rst_b ( __rst_n ), \ + .state_i ( __d ), \ + .state_o ( __q ) \ + ); \ + `endif + +`endif // PRIM_FLOP_MACROS_SV diff --git a/designs/Caliptra/src/adams-bridge/abr_prim_generic_buf.sv b/designs/Caliptra/src/adams-bridge/abr_prim_generic_buf.sv new file mode 100644 index 0000000..c611138 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/abr_prim_generic_buf.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 + +`include "abr_prim_assert.sv" + +module abr_prim_generic_buf #( + parameter int Width = 1 +) ( + input [Width-1:0] in_i, + output logic [Width-1:0] out_o +); + + logic [Width-1:0] inv; + assign inv = ~in_i; + assign out_o = ~inv; + +endmodule diff --git a/designs/Caliptra/src/adams-bridge/abr_prim_generic_flop.sv b/designs/Caliptra/src/adams-bridge/abr_prim_generic_flop.sv new file mode 100644 index 0000000..1c05820 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/abr_prim_generic_flop.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 + +`include "abr_prim_assert.sv" + +module abr_prim_generic_flop #( + parameter int Width = 1, + parameter logic [Width-1:0] ResetValue = 0 +) ( + input clk_i, + input rst_b, + input [Width-1:0] d_i, + output logic [Width-1:0] q_o +); + + always_ff @(posedge clk_i or negedge rst_b) begin + if (!rst_b) begin + q_o <= ResetValue; + end else begin + q_o <= d_i; + end + end + +endmodule diff --git a/designs/Caliptra/src/adams-bridge/abr_prim_generic_flop_en.sv b/designs/Caliptra/src/adams-bridge/abr_prim_generic_flop_en.sv new file mode 100644 index 0000000..a4f711e --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/abr_prim_generic_flop_en.sv @@ -0,0 +1,39 @@ +// Copyright lowRISC contributors. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +`include "abr_prim_assert.sv" + +module abr_prim_generic_flop_en #( + parameter int Width = 1, + parameter bit EnSecBuf = 0, + parameter logic [Width-1:0] ResetValue = 0 +) ( + input clk_i, + input rst_b, + input en_i, + input [Width-1:0] d_i, + output logic [Width-1:0] q_o +); + + logic en; + if (EnSecBuf) begin : gen_en_sec_buf + abr_prim_sec_anchor_buf #( + .Width(1) + ) u_en_buf ( + .in_i(en_i), + .out_o(en) + ); + end else begin : gen_en_no_sec_buf + assign en = en_i; + end + + always_ff @(posedge clk_i or negedge rst_b) begin + if (!rst_b) begin + q_o <= ResetValue; + end else if (en) begin + q_o <= d_i; + end + end + +endmodule diff --git a/designs/Caliptra/src/adams-bridge/abr_prim_intr_hw.sv b/designs/Caliptra/src/adams-bridge/abr_prim_intr_hw.sv new file mode 100644 index 0000000..b363fe2 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/abr_prim_intr_hw.sv @@ -0,0 +1,100 @@ +// Copyright lowRISC contributors. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Primitive interrupt handler. This assumes the existence of three +// controller registers: INTR_ENABLE, INTR_STATE, INTR_TEST. +// This module can be instantiated once per interrupt field, or +// "bussified" with all fields of the interrupt vector. + +`include "abr_sva.svh" +`include "abr_prim_assert.sv" + +module abr_prim_intr_hw # ( + parameter int unsigned Width = 1, + parameter bit FlopOutput = 1, + + // IntrT parameter is to hint the logic for the interrupt type. Module + // supports two interrupt types, *Status* and *Event*. + // + // The differences between those two types are: + // - Status is persistent. Until the root cause is alleviated, the interrupt + // keeps asserting. + // - Event remains high for a relatively short period time without SW + // intervention. One distinct example is an error (error could be status + // though). If a certain error condition is captured, HW logic may create a + // pulse. In this case the interrupt is assumed as an Event interrupt. + parameter IntrT = "Event" // Event or Status +) ( + // event + input clk_i, + input rst_b, + input [Width-1:0] event_intr_i, + + // register interface + input [Width-1:0] reg2hw_intr_enable_q_i, + input [Width-1:0] reg2hw_intr_test_q_i, + input reg2hw_intr_test_qe_i, + input [Width-1:0] reg2hw_intr_state_q_i, + output hw2reg_intr_state_de_o, + output [Width-1:0] hw2reg_intr_state_d_o, + + // outgoing interrupt + output logic [Width-1:0] intr_o +); + + logic [Width-1:0] status; // incl. test + + if (IntrT == "Event") begin : g_intr_event + logic [Width-1:0] new_event; + assign new_event = + (({Width{reg2hw_intr_test_qe_i}} & reg2hw_intr_test_q_i) | event_intr_i); + assign hw2reg_intr_state_de_o = |new_event; + // for scalar interrupts, this resolves to '1' with new event + // for vector interrupts, new events are OR'd in to existing interrupt state + assign hw2reg_intr_state_d_o = new_event | reg2hw_intr_state_q_i; + + assign status = reg2hw_intr_state_q_i ; + end : g_intr_event + else if (IntrT == "Status") begin : g_intr_status + logic [Width-1:0] test_q; // Storing test. Cleared by SW + + always_ff @(posedge clk_i or negedge rst_b) begin + if (!rst_b) test_q <= '0; + else if (reg2hw_intr_test_qe_i) test_q <= reg2hw_intr_test_q_i; + end + + // TODO: In Status type, INTR_STATE is better to be external type and RO. + assign hw2reg_intr_state_de_o = 1'b 1; // always represent the status + assign hw2reg_intr_state_d_o = event_intr_i | test_q; + + assign status = event_intr_i | test_q; + + // To make the timing same to event type, status signal does not use CSR.q, + // rather the input of the CSR. + logic unused_reg2hw; + assign unused_reg2hw = ^reg2hw_intr_state_q_i; + end : g_intr_status + + + if (FlopOutput == 1) begin : gen_flop_intr_output + // flop the interrupt output + always_ff @(posedge clk_i or negedge rst_b) begin + if (!rst_b) begin + intr_o <= '0; + end else begin + intr_o <= status & reg2hw_intr_enable_q_i; + end + end + + end else begin : gen_intr_passthrough_output + logic unused_clk; + logic unused_rst_n; + assign unused_clk = clk_i; + assign unused_rst_n = rst_b; + assign intr_o = reg2hw_intr_state_q_i & reg2hw_intr_enable_q_i; + end + + `ABR_ASSERT_INIT(IntrTKind_A, IntrT inside {"Event", "Status"}) + +endmodule diff --git a/designs/Caliptra/src/adams-bridge/abr_prim_lfsr.sv b/designs/Caliptra/src/adams-bridge/abr_prim_lfsr.sv new file mode 100644 index 0000000..f5c92c2 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/abr_prim_lfsr.sv @@ -0,0 +1,699 @@ +// Copyright lowRISC contributors. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// This module implements different LFSR types: +// +// 0) Galois XOR type LFSR ([1], internal XOR gates, very fast). +// Parameterizable width from 4 to 64 bits. +// Coefficients obtained from [2]. +// +// 1) Fibonacci XNOR type LFSR, parameterizable from 3 to 168 bits. +// Coefficients obtained from [3]. +// +// All flavors have an additional entropy input and lockup protection, which +// reseeds the state once it has accidentally fallen into the all-zero (XOR) or +// all-one (XNOR) state. Further, an external seed can be loaded into the LFSR +// state at runtime. If that seed is all-zero (XOR case) or all-one (XNOR case), +// the state will be reseeded in the next cycle using the lockup protection mechanism. +// Note that the external seed input takes precedence over internal state updates. +// +// All polynomials up to 34 bit in length have been verified in simulation. +// +// Refs: [1] https://en.wikipedia.org/wiki/Linear-feedback_shift_register +// [2] https://users.ece.cmu.edu/~koopman/lfsr/ +// [3] https://www.xilinx.com/support/documentation/application_notes/xapp052.pdf + +`include "abr_prim_assert.sv" + +module abr_prim_lfsr #( + // Lfsr Type, can be FIB_XNOR or GAL_XOR + parameter LfsrType = "GAL_XOR", + // Lfsr width + parameter int unsigned LfsrDw = 32, + // Derived parameter, do not override + localparam int unsigned LfsrIdxDw = $clog2(LfsrDw), + // Width of the entropy input to be XOR'd into state (lfsr_q[EntropyDw-1:0]) + parameter int unsigned EntropyDw = 8, + // Width of output tap (from lfsr_q[StateOutDw-1:0]) + parameter int unsigned StateOutDw = 8, + // Lfsr reset state, must be nonzero! + parameter logic [LfsrDw-1:0] DefaultSeed = LfsrDw'(1), + // Custom polynomial coeffs + parameter logic [LfsrDw-1:0] CustomCoeffs = '0, + // If StatePermEn is set to 1, the custom permutation specified via StatePerm is applied to the + // state output, in order to break linear shifting patterns of the LFSR. Note that this + // permutation represents a way of customizing the LFSR via a random netlist constant. This is + // different from the NonLinearOut feature below which just transforms the output non-linearly + // with a fixed function. In most cases, designers should consider enabling StatePermEn as it + // comes basically "for free" in terms of area and timing impact. NonLinearOut on the other hand + // has area and timing implications and designers should consider whether the use of that feature + // is justified. + parameter bit StatePermEn = 1'b0, + parameter logic [LfsrDw-1:0][LfsrIdxDw-1:0] StatePerm = '0, + // Enable this for DV, disable this for long LFSRs in FPV + parameter bit MaxLenSVA = 1'b1, + // Can be disabled in cases where seed and entropy + // inputs are unused in order to not distort coverage + // (the SVA will be unreachable in such cases) + parameter bit LockupSVA = 1'b1, + parameter bit ExtSeedSVA = 1'b1, + // Introduce non-linearity to lfsr output. Note, unlike StatePermEn, this feature is not "for + // free". Please double check that this feature is indeed required. Also note that this feature + // is only available for LFSRs that have a power-of-two width greater or equal 16bit. + parameter bit NonLinearOut = 1'b0 +) ( + input clk_i, + input rst_b, + input seed_en_i, // load external seed into the state (takes precedence) + input [LfsrDw-1:0] seed_i, // external seed input + input lfsr_en_i, // enables the LFSR + input [EntropyDw-1:0] entropy_i, // additional entropy to be XOR'ed into the state + output logic [StateOutDw-1:0] state_o // (partial) LFSR state output +); + + // automatically generated with util/design/get-lfsr-coeffs.py script + localparam int unsigned GAL_XOR_LUT_OFF = 4; + localparam logic [63:0] GAL_XOR_COEFFS [61] = + '{ 64'h9, + 64'h12, + 64'h21, + 64'h41, + 64'h8E, + 64'h108, + 64'h204, + 64'h402, + 64'h829, + 64'h100D, + 64'h2015, + 64'h4001, + 64'h8016, + 64'h10004, + 64'h20013, + 64'h40013, + 64'h80004, + 64'h100002, + 64'h200001, + 64'h400010, + 64'h80000D, + 64'h1000004, + 64'h2000023, + 64'h4000013, + 64'h8000004, + 64'h10000002, + 64'h20000029, + 64'h40000004, + 64'h80000057, + 64'h100000029, + 64'h200000073, + 64'h400000002, + 64'h80000003B, + 64'h100000001F, + 64'h2000000031, + 64'h4000000008, + 64'h800000001C, + 64'h10000000004, + 64'h2000000001F, + 64'h4000000002C, + 64'h80000000032, + 64'h10000000000D, + 64'h200000000097, + 64'h400000000010, + 64'h80000000005B, + 64'h1000000000038, + 64'h200000000000E, + 64'h4000000000025, + 64'h8000000000004, + 64'h10000000000023, + 64'h2000000000003E, + 64'h40000000000023, + 64'h8000000000004A, + 64'h100000000000016, + 64'h200000000000031, + 64'h40000000000003D, + 64'h800000000000001, + 64'h1000000000000013, + 64'h2000000000000034, + 64'h4000000000000001, + 64'h800000000000000D }; + + // automatically generated with get-lfsr-coeffs.py script + localparam int unsigned FIB_XNOR_LUT_OFF = 3; + localparam logic [167:0] FIB_XNOR_COEFFS [166] = + '{ 168'h6, + 168'hC, + 168'h14, + 168'h30, + 168'h60, + 168'hB8, + 168'h110, + 168'h240, + 168'h500, + 168'h829, + 168'h100D, + 168'h2015, + 168'h6000, + 168'hD008, + 168'h12000, + 168'h20400, + 168'h40023, + 168'h90000, + 168'h140000, + 168'h300000, + 168'h420000, + 168'hE10000, + 168'h1200000, + 168'h2000023, + 168'h4000013, + 168'h9000000, + 168'h14000000, + 168'h20000029, + 168'h48000000, + 168'h80200003, + 168'h100080000, + 168'h204000003, + 168'h500000000, + 168'h801000000, + 168'h100000001F, + 168'h2000000031, + 168'h4400000000, + 168'hA000140000, + 168'h12000000000, + 168'h300000C0000, + 168'h63000000000, + 168'hC0000030000, + 168'h1B0000000000, + 168'h300003000000, + 168'h420000000000, + 168'hC00000180000, + 168'h1008000000000, + 168'h3000000C00000, + 168'h6000C00000000, + 168'h9000000000000, + 168'h18003000000000, + 168'h30000000030000, + 168'h40000040000000, + 168'hC0000600000000, + 168'h102000000000000, + 168'h200004000000000, + 168'h600003000000000, + 168'hC00000000000000, + 168'h1800300000000000, + 168'h3000000000000030, + 168'h6000000000000000, + 168'hD800000000000000, + 168'h10000400000000000, + 168'h30180000000000000, + 168'h60300000000000000, + 168'h80400000000000000, + 168'h140000028000000000, + 168'h300060000000000000, + 168'h410000000000000000, + 168'h820000000001040000, + 168'h1000000800000000000, + 168'h3000600000000000000, + 168'h6018000000000000000, + 168'hC000000018000000000, + 168'h18000000600000000000, + 168'h30000600000000000000, + 168'h40200000000000000000, + 168'hC0000000060000000000, + 168'h110000000000000000000, + 168'h240000000480000000000, + 168'h600000000003000000000, + 168'h800400000000000000000, + 168'h1800000300000000000000, + 168'h3003000000000000000000, + 168'h4002000000000000000000, + 168'hC000000000000000018000, + 168'h10000000004000000000000, + 168'h30000C00000000000000000, + 168'h600000000000000000000C0, + 168'hC00C0000000000000000000, + 168'h140000000000000000000000, + 168'h200001000000000000000000, + 168'h400800000000000000000000, + 168'hA00000000001400000000000, + 168'h1040000000000000000000000, + 168'h2004000000000000000000000, + 168'h5000000000028000000000000, + 168'h8000000004000000000000000, + 168'h18600000000000000000000000, + 168'h30000000000000000C00000000, + 168'h40200000000000000000000000, + 168'hC0300000000000000000000000, + 168'h100010000000000000000000000, + 168'h200040000000000000000000000, + 168'h5000000000000000A0000000000, + 168'h800000010000000000000000000, + 168'h1860000000000000000000000000, + 168'h3003000000000000000000000000, + 168'h4010000000000000000000000000, + 168'hA000000000140000000000000000, + 168'h10080000000000000000000000000, + 168'h30000000000000000000180000000, + 168'h60018000000000000000000000000, + 168'hC0000000000000000300000000000, + 168'h140005000000000000000000000000, + 168'h200000001000000000000000000000, + 168'h404000000000000000000000000000, + 168'h810000000000000000000000000102, + 168'h1000040000000000000000000000000, + 168'h3000000000000006000000000000000, + 168'h5000000000000000000000000000000, + 168'h8000000004000000000000000000000, + 168'h18000000000000000000000000030000, + 168'h30000000030000000000000000000000, + 168'h60000000000000000000000000000000, + 168'hA0000014000000000000000000000000, + 168'h108000000000000000000000000000000, + 168'h240000000000000000000000000000000, + 168'h600000000000C00000000000000000000, + 168'h800000040000000000000000000000000, + 168'h1800000000000300000000000000000000, + 168'h2000000000000010000000000000000000, + 168'h4008000000000000000000000000000000, + 168'hC000000000000000000000000000000600, + 168'h10000080000000000000000000000000000, + 168'h30600000000000000000000000000000000, + 168'h4A400000000000000000000000000000000, + 168'h80000004000000000000000000000000000, + 168'h180000003000000000000000000000000000, + 168'h200001000000000000000000000000000000, + 168'h600006000000000000000000000000000000, + 168'hC00000000000000006000000000000000000, + 168'h1000000000000100000000000000000000000, + 168'h3000000000000006000000000000000000000, + 168'h6000000003000000000000000000000000000, + 168'h8000001000000000000000000000000000000, + 168'h1800000000000000000000000000C000000000, + 168'h20000000000001000000000000000000000000, + 168'h48000000000000000000000000000000000000, + 168'hC0000000000000006000000000000000000000, + 168'h180000000000000000000000000000000000000, + 168'h280000000000000000000000000000005000000, + 168'h60000000C000000000000000000000000000000, + 168'hC00000000000000000000000000018000000000, + 168'h1800000600000000000000000000000000000000, + 168'h3000000C00000000000000000000000000000000, + 168'h4000000080000000000000000000000000000000, + 168'hC000300000000000000000000000000000000000, + 168'h10000400000000000000000000000000000000000, + 168'h30000000000000000000006000000000000000000, + 168'h600000000000000C0000000000000000000000000, + 168'hC0060000000000000000000000000000000000000, + 168'h180000006000000000000000000000000000000000, + 168'h3000000000C0000000000000000000000000000000, + 168'h410000000000000000000000000000000000000000, + 168'hA00140000000000000000000000000000000000000 }; + + logic lockup; + logic [LfsrDw-1:0] lfsr_d, lfsr_q; + logic [LfsrDw-1:0] next_lfsr_state, coeffs; + + // Enable the randomization of DefaultSeed using DefaultSeedLocal in DV simulations. + `ifdef ABR_SIMULATION + `ifdef VERILATOR + localparam logic [LfsrDw-1:0] DefaultSeedLocal = DefaultSeed; + + `else + logic [LfsrDw-1:0] DefaultSeedLocal; + logic abr_prim_lfsr_use_default_seed; + + initial begin : p_randomize_default_seed + if (!$value$plusargs("abr_prim_lfsr_use_default_seed=%0d", abr_prim_lfsr_use_default_seed)) begin + // 30% of the time, use the DefaultSeed parameter; 70% of the time, randomize it. + `ABR_ASSERT_I(UseDefaultSeedRandomizeCheck_A, std::randomize(abr_prim_lfsr_use_default_seed) with { + abr_prim_lfsr_use_default_seed dist {0:/7, 1:/3};}) + end + if (abr_prim_lfsr_use_default_seed) begin + DefaultSeedLocal = DefaultSeed; + end else begin + // Randomize the DefaultSeedLocal ensuring its not all 0s or all 1s. + `ABR_ASSERT_I(DefaultSeedLocalRandomizeCheck_A, std::randomize(DefaultSeedLocal) with { + !(DefaultSeedLocal inside {'0, '1});}) + end + $display("%m: DefaultSeed = 0x%0h, DefaultSeedLocal = 0x%0h", DefaultSeed, DefaultSeedLocal); + end + `endif // ifdef VERILATOR + + `else + localparam logic [LfsrDw-1:0] DefaultSeedLocal = DefaultSeed; + + `endif // ifdef ABR_SIMULATION + + //////////////// + // Galois XOR // + //////////////// + if (64'(LfsrType) == 64'("GAL_XOR")) begin : gen_gal_xor + + // if custom polynomial is provided + if (CustomCoeffs > 0) begin : gen_custom + assign coeffs = CustomCoeffs[LfsrDw-1:0]; + end else begin : gen_lut + assign coeffs = GAL_XOR_COEFFS[LfsrDw-GAL_XOR_LUT_OFF][LfsrDw-1:0]; + // check that the most significant bit of polynomial is 1 + `ABR_ASSERT_INIT(MinLfsrWidth_A, LfsrDw >= $low(GAL_XOR_COEFFS)+GAL_XOR_LUT_OFF) + `ABR_ASSERT_INIT(MaxLfsrWidth_A, LfsrDw <= $high(GAL_XOR_COEFFS)+GAL_XOR_LUT_OFF) + end + + // calculate next state using internal XOR feedback and entropy input + assign next_lfsr_state = LfsrDw'(entropy_i) ^ ({LfsrDw{lfsr_q[0]}} & coeffs) ^ (lfsr_q >> 1); + + // lockup condition is all-zero + assign lockup = ~(|lfsr_q); + + // check that seed is not all-zero + `ABR_ASSERT_INIT(DefaultSeedNzCheck_A, |DefaultSeedLocal) + + + //////////////////// + // Fibonacci XNOR // + //////////////////// + end else if (64'(LfsrType) == "FIB_XNOR") begin : gen_fib_xnor + + // if custom polynomial is provided + if (CustomCoeffs > 0) begin : gen_custom + assign coeffs = CustomCoeffs[LfsrDw-1:0]; + end else begin : gen_lut + assign coeffs = FIB_XNOR_COEFFS[LfsrDw-FIB_XNOR_LUT_OFF][LfsrDw-1:0]; + // check that the most significant bit of polynomial is 1 + `ABR_ASSERT_INIT(MinLfsrWidth_A, LfsrDw >= $low(FIB_XNOR_COEFFS)+FIB_XNOR_LUT_OFF) + `ABR_ASSERT_INIT(MaxLfsrWidth_A, LfsrDw <= $high(FIB_XNOR_COEFFS)+FIB_XNOR_LUT_OFF) + end + + // calculate next state using external XNOR feedback and entropy input + assign next_lfsr_state = LfsrDw'(entropy_i) ^ {lfsr_q[LfsrDw-2:0], ~(^(lfsr_q & coeffs))}; + + // lockup condition is all-ones + assign lockup = &lfsr_q; + + // check that seed is not all-ones + `ABR_ASSERT_INIT(DefaultSeedNzCheck_A, !(&DefaultSeedLocal)) + + + ///////////// + // Unknown // + ///////////// + end else begin : gen_unknown_type + assign coeffs = '0; + assign next_lfsr_state = '0; + assign lockup = 1'b0; + `ABR_ASSERT_INIT(UnknownLfsrType_A, 0) + end + + + ////////////////// + // Shared logic // + ////////////////// + + assign lfsr_d = (seed_en_i) ? seed_i : + (lfsr_en_i && lockup) ? DefaultSeedLocal : + (lfsr_en_i) ? next_lfsr_state : + lfsr_q; + + logic [LfsrDw-1:0] sbox_out; + if (NonLinearOut) begin : gen_out_non_linear + // The "aligned" permutation ensures that adjacent bits do not go into the same SBox. It is + // different from the state permutation that can be specified via the StatePerm parameter. The + // permutation taps out 4 SBox input bits at regular stride intervals. E.g., for a 16bit + // vector, the input assignment looks as follows: + // + // SBox0: 0, 4, 8, 12 + // SBox1: 1, 5, 9, 13 + // SBox2: 2, 6, 10, 14 + // SBox3: 3, 7, 11, 15 + // + // Note that this permutation can be produced by filling the input vector into matrix columns + // and reading out the SBox inputs as matrix rows. + localparam int NumSboxes = LfsrDw / 4; + // Fill in the input vector in col-major order. + logic [3:0][NumSboxes-1:0][LfsrIdxDw-1:0] matrix_indices; + for (genvar j = 0; j < LfsrDw; j++) begin : gen_input_idx_map + assign matrix_indices[j / NumSboxes][j % NumSboxes] = j; + end + // Due to the LFSR shifting pattern, the above permutation has the property that the output of + // SBox(n) is going to be equal to SBox(n+1) in the subsequent cycle (unless the LFSR polynomial + // modifies some of the associated shifted bits via an XOR tap). + // We therefore tweak this permutation by rotating and reversing some of the assignment matrix + // columns. The rotation and reversion operations have been chosen such that this + // generalizes to all power of two widths supported by the LFSR primitive. For 16bit, this + // looks as follows: + // + // SBox0: 0, 6, 11, 14 + // SBox1: 1, 7, 10, 13 + // SBox2: 2, 4, 9, 12 + // SBox3: 3, 5, 8, 15 + // + // This can be achieved by: + // 1) down rotating the second column by NumSboxes/2 + // 2) reversing the third column + // 3) down rotating the fourth column by 1 and reversing it + // + logic [3:0][NumSboxes-1:0][LfsrIdxDw-1:0] matrix_rotrev_indices; + typedef logic [NumSboxes-1:0][LfsrIdxDw-1:0] matrix_col_t; + + // left-rotates a matrix column by the shift amount + function automatic matrix_col_t lrotcol(matrix_col_t col, integer shift); + matrix_col_t out; + for (int k = 0; k < NumSboxes; k++) begin + out[(k + shift) % NumSboxes] = col[k]; + end + return out; + endfunction : lrotcol + + // reverses a matrix column + function automatic matrix_col_t revcol(matrix_col_t col); + return {< StateOutDw) begin : gen_tieoff_unused + logic unused_sbox_out; + assign unused_sbox_out = ^sbox_out; + end + + end else begin : gen_no_state_perm + assign state_o = StateOutDw'(sbox_out); + end + + always_ff @(posedge clk_i or negedge rst_b) begin : p_reg + if (!rst_b) begin + lfsr_q <= DefaultSeedLocal; + end else begin + lfsr_q <= lfsr_d; + end + end + + + /////////////////////// + // shared assertions // + /////////////////////// + + `ABR_ASSERT_KNOWN(DataKnownO_A, state_o) + +// the code below is not meant to be synthesized, +// but it is intended to be used in simulation and FPV +`ifndef SYNTHESIS + function automatic logic [LfsrDw-1:0] compute_next_state(logic [LfsrDw-1:0] lfsrcoeffs, + logic [EntropyDw-1:0] entropy, + logic [LfsrDw-1:0] current_state); + logic state0; + logic [LfsrDw-1:0] next_state; + + next_state = current_state; + + // Galois XOR + if (64'(LfsrType) == 64'("GAL_XOR")) begin + if (next_state == 0) begin + next_state = DefaultSeedLocal; + end else begin + state0 = next_state[0]; + next_state = next_state >> 1; + if (state0) next_state ^= lfsrcoeffs; + next_state ^= LfsrDw'(entropy); + end + // Fibonacci XNOR + end else if (64'(LfsrType) == "FIB_XNOR") begin + if (&next_state) begin + next_state = DefaultSeedLocal; + end else begin + state0 = ~(^(next_state & lfsrcoeffs)); + next_state = next_state << 1; + next_state[0] = state0; + next_state ^= LfsrDw'(entropy); + end + end else begin + $error("unknown lfsr type"); + end + + return next_state; + endfunction : compute_next_state + + // check whether next state is computed correctly + // we shift the assertion by one clock cycle (##1) in order to avoid + // erroneous SVA triggers right after reset deassertion in cases where + // the precondition is true throughout the reset. + // this can happen since the disable_iff evaluates using unsampled values, + // meaning that the assertion may already read rst_b == 1 on an active + // clock edge while the flops in the design have not yet changed state. + `ABR_ASSERT(NextStateCheck_A, ##1 lfsr_en_i && !seed_en_i |=> lfsr_q == + compute_next_state(coeffs, $past(entropy_i), $past(lfsr_q))) + + // Only check this if enabled. + if (StatePermEn) begin : gen_perm_check + // Check that the supplied permutation is valid. + logic [LfsrDw-1:0] lfsr_perm_test; + initial begin : p_perm_check + lfsr_perm_test = '0; + for (int k = 0; k < LfsrDw; k++) begin + lfsr_perm_test[StatePerm[k]] = 1'b1; + end + // All bit positions must be marked with 1. + `ABR_ASSERT_I(PermutationCheck_A, &lfsr_perm_test) + end + end + +`endif + + `ABR_ASSERT_INIT(InputWidth_A, LfsrDw >= EntropyDw) + `ABR_ASSERT_INIT(OutputWidth_A, LfsrDw >= StateOutDw) + + // MSB must be one in any case + `ABR_ASSERT(CoeffCheck_A, coeffs[LfsrDw-1]) + + // output check + `ABR_ASSERT_KNOWN(OutputKnown_A, state_o) + if (!StatePermEn && !NonLinearOut) begin : gen_output_sva + `ABR_ASSERT(OutputCheck_A, state_o == StateOutDw'(lfsr_q)) + end + // if no external input changes the lfsr state, a lockup must not occur (by design) + //`ABR_ASSERT(NoLockups_A, (!entropy_i) && (!seed_en_i) |=> !lockup, clk_i, !rst_b) + `ABR_ASSERT(NoLockups_A, lfsr_en_i && !entropy_i && !seed_en_i |=> !lockup) + + // this can be disabled if unused in order to not distort coverage + if (ExtSeedSVA) begin : gen_ext_seed_sva + // check that external seed is correctly loaded into the state + // rst_b is used directly as part of the pre-condition since the usage of rst_b + // in disable_iff is unsampled. See #1985 for more details + `ABR_ASSERT(ExtDefaultSeedInputCheck_A, (seed_en_i && rst_b) |=> lfsr_q == $past(seed_i)) + end + + // if the external seed mechanism is not used, + // there is theoretically no way we end up in a lockup condition + // in order to not distort coverage, this SVA can be disabled in such cases + if (LockupSVA) begin : gen_lockup_mechanism_sva + // check that a stuck LFSR is correctly reseeded + `ABR_ASSERT(LfsrLockupCheck_A, lfsr_en_i && lockup && !seed_en_i |=> !lockup) + end + + // If non-linear output requested, the LFSR width must be a power of 2 and greater than 16. + if(NonLinearOut) begin : gen_nonlinear_align_check_sva + `ABR_ASSERT_INIT(SboxByteAlign_A, 2**$clog2(LfsrDw) == LfsrDw && LfsrDw >= 16) + end + + if (MaxLenSVA) begin : gen_max_len_sva +`ifndef SYNTHESIS + // the code below is a workaround to enable long sequences to be checked. + // some simulators do not support SVA sequences longer than 2**32-1. + logic [LfsrDw-1:0] cnt_d, cnt_q; + logic perturbed_d, perturbed_q; + logic [LfsrDw-1:0] cmp_val; + + assign cmp_val = {{(LfsrDw-1){1'b1}}, 1'b0}; // 2**LfsrDw-2 + assign cnt_d = (lfsr_en_i && lockup) ? '0 : + (lfsr_en_i && (cnt_q == cmp_val)) ? '0 : + (lfsr_en_i) ? cnt_q + 1'b1 : + cnt_q; + + assign perturbed_d = perturbed_q | (|entropy_i) | seed_en_i; + + always_ff @(posedge clk_i or negedge rst_b) begin : p_max_len + if (!rst_b) begin + cnt_q <= '0; + perturbed_q <= 1'b0; + end else begin + cnt_q <= cnt_d; + perturbed_q <= perturbed_d; + end + end + + `ABR_ASSERT(MaximalLengthCheck0_A, cnt_q == 0 |-> lfsr_q == DefaultSeedLocal, + clk_i, !rst_b || perturbed_q) + `ABR_ASSERT(MaximalLengthCheck1_A, cnt_q != 0 |-> lfsr_q != DefaultSeedLocal, + clk_i, !rst_b || perturbed_q) +`endif + end + +endmodule diff --git a/designs/Caliptra/src/adams-bridge/abr_prim_max_tree.sv b/designs/Caliptra/src/adams-bridge/abr_prim_max_tree.sv new file mode 100644 index 0000000..d14d157 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/abr_prim_max_tree.sv @@ -0,0 +1,152 @@ +// Copyright lowRISC contributors. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// The module implements a binary tree to find the maximal entry. the solution +// has O(N) area and O(log(N)) delay complexity, and thus scales well with +// many input sources. +// +// Note that only input values marked as "valid" are respected in the maximum computation. +// If there are multiple valid inputs with the same value, the tree will always select the input +// with the smallest index. +// +// If none of the input values are valid, the output index will be 0 and the output value will +// be equal to the input value at index 0. + + +`include "abr_prim_assert.sv" + +module abr_prim_max_tree #( + parameter int NumSrc = 32, + parameter int Width = 8, + // Derived parameters + localparam int SrcWidth = $clog2(NumSrc) +) ( + // The module is combinational - the clock and reset are only used for assertions. + input clk_i, + input rst_b, + input [NumSrc-1:0][Width-1:0] values_i, // Input values + input [NumSrc-1:0] valid_i, // Input valid bits + output logic [Width-1:0] max_value_o, // Maximum value + output logic [SrcWidth-1:0] max_idx_o, // Index of the maximum value + output logic max_valid_o // Whether any of the inputs is valid +); + + /////////////////////// + // Binary tree logic // + /////////////////////// + + // This only works with 2 or more sources. + `ABR_ASSERT_INIT(NumSources_A, NumSrc >= 2) + + // Align to powers of 2 for simplicity. + // A full binary tree with N levels has 2**N + 2**N-1 nodes. + localparam int NumLevels = $clog2(NumSrc); + logic [2**(NumLevels+1)-2:0] vld_tree; + logic [2**(NumLevels+1)-2:0][SrcWidth-1:0] idx_tree; + logic [2**(NumLevels+1)-2:0][Width-1:0] max_tree; + + for (genvar level = 0; level < NumLevels+1; level++) begin : gen_tree + // + // level+1 C0 C1 <- "Base1" points to the first node on "level+1", + // \ / these nodes are the children of the nodes one level below + // level Pa <- "Base0", points to the first node on "level", + // these nodes are the parents of the nodes one level above + // + // hence we have the following indices for the paPa, C0, C1 nodes: + // Pa = 2**level - 1 + offset = Base0 + offset + // C0 = 2**(level+1) - 1 + 2*offset = Base1 + 2*offset + // C1 = 2**(level+1) - 1 + 2*offset + 1 = Base1 + 2*offset + 1 + // + localparam int Base0 = (2**level)-1; + localparam int Base1 = (2**(level+1))-1; + + for (genvar offset = 0; offset < 2**level; offset++) begin : gen_level + localparam int Pa = Base0 + offset; + localparam int C0 = Base1 + 2*offset; + localparam int C1 = Base1 + 2*offset + 1; + + // This assigns the input values, their corresponding IDs and valid signals to the tree leafs. + if (level == NumLevels) begin : gen_leafs + if (offset < NumSrc) begin : gen_assign + assign vld_tree[Pa] = valid_i[offset]; + assign idx_tree[Pa] = offset; + assign max_tree[Pa] = values_i[offset]; + end else begin : gen_tie_off + assign vld_tree[Pa] = '0; + assign idx_tree[Pa] = '0; + assign max_tree[Pa] = '0; + end + // This creates the node assignments. + end else begin : gen_nodes + logic sel; // Local helper variable + // In case only one of the parents is valid, forward that one + // In case both parents are valid, forward the one with higher value + assign sel = (~vld_tree[C0] & vld_tree[C1]) | + (vld_tree[C0] & vld_tree[C1] & logic'(max_tree[C1] > max_tree[C0])); + // Forwarding muxes + // Note: these ternaries have triggered a synthesis bug in Vivado versions older + // than 2020.2. If the problem resurfaces again, have a look at issue #1408. + assign vld_tree[Pa] = (sel) ? vld_tree[C1] : vld_tree[C0]; + assign idx_tree[Pa] = (sel) ? idx_tree[C1] : idx_tree[C0]; + assign max_tree[Pa] = (sel) ? max_tree[C1] : max_tree[C0]; + end + end : gen_level + end : gen_tree + + + // The results can be found at the tree root + assign max_valid_o = vld_tree[0]; + assign max_idx_o = idx_tree[0]; + assign max_value_o = max_tree[0]; + + //////////////// + // Assertions // + //////////////// + +`ifdef ABR_INC_ASSERT + //VCS coverage off + // pragma coverage off + + // Helper functions for assertions below. + function automatic logic [Width-1:0] max_value (input logic [NumSrc-1:0][Width-1:0] values_i, + input logic [NumSrc-1:0] valid_i); + logic [Width-1:0] value = '0; + for (int k = 0; k < NumSrc; k++) begin + if (valid_i[k] && values_i[k] > value) begin + value = values_i[k]; + end + end + return value; + endfunction : max_value + + function automatic logic [SrcWidth-1:0] max_idx (input logic [NumSrc-1:0][Width-1:0] values_i, + input logic [NumSrc-1:0] valid_i); + logic [Width-1:0] value = '0; + logic [SrcWidth-1:0] idx = '0; + for (int k = NumSrc-1; k >= 0; k--) begin + if (valid_i[k] && values_i[k] >= value) begin + value = values_i[k]; + idx = k; + end + end + return idx; + endfunction : max_idx + + logic [Width-1:0] max_value_exp; + logic [SrcWidth-1:0] max_idx_exp; + assign max_value_exp = max_value(values_i, valid_i); + assign max_idx_exp = max_idx(values_i, valid_i); + //VCS coverage on + // pragma coverage on + + // TODO(10588): Below syntax is not supported in xcelium, track xcelium cases #46591452. + // `ABR_ASSERT(ValidInImpliesValidOut_A, |valid_i <-> max_valid_o) + `ABR_ASSERT(ValidInImpliesValidOut_A, |valid_i === max_valid_o) + `ABR_ASSERT(MaxComputation_A, max_valid_o |-> max_value_o == max_value_exp) + `ABR_ASSERT(MaxComputationInvalid_A, !max_valid_o |-> max_value_o == values_i[0]) + `ABR_ASSERT(MaxIndexComputation_A, max_valid_o |-> max_idx_o == max_idx_exp) + `ABR_ASSERT(MaxIndexComputationInvalid_A, !max_valid_o |-> max_idx_o == '0) +`endif + +endmodule : abr_prim_max_tree diff --git a/designs/Caliptra/src/adams-bridge/abr_prim_mubi4_sync.sv b/designs/Caliptra/src/adams-bridge/abr_prim_mubi4_sync.sv new file mode 100644 index 0000000..35550bf --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/abr_prim_mubi4_sync.sv @@ -0,0 +1,178 @@ +// Copyright lowRISC contributors. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// ------------------- W A R N I N G: A U T O - G E N E R A T E D C O D E !! -------------------// +// PLEASE DO NOT HAND-EDIT THIS FILE. IT HAS BEEN AUTO-GENERATED WITH THE FOLLOWING COMMAND: +// +// util/design/gen-mubi.py +// +// Double-synchronizer flop for multibit signals with additional output buffers. + +`include "abr_prim_assert.sv" + +module abr_prim_mubi4_sync + import abr_prim_mubi_pkg::*; +#( + // Number of separately buffered output signals. + // The buffer cells have a don't touch constraint + // on them such that synthesis tools won't collapse + // all copies into one signal. + parameter int NumCopies = 1, + // This instantiates the synchronizer flops if set to 1. + // In special cases where the receiver is in the same clock domain as the sender, + // this can be set to 0. However, it is recommended to leave this at 1. + parameter bit AsyncOn = 1, + // This controls whether the mubi module institutes stability checks when + // AsyncOn is set. If stability checks are on, a 3rd stage of storage is + // added after the synchronizers and the outputs only updated if the 3rd + // stage and sychronizer agree. If they do not agree, the ResetValue is + // output instead. + parameter bit StabilityCheck = 0, + // Reset value for the sync flops + parameter mubi4_t ResetValue = MuBi4False +) ( + input clk_i, + input rst_b, + input mubi4_t mubi_i, + output mubi4_t [NumCopies-1:0] mubi_o +); + + `ABR_ASSERT_INIT(NumCopiesMustBeGreaterZero_A, NumCopies > 0) + + logic [MuBi4Width-1:0] mubi; + if (AsyncOn) begin : gen_flops + logic [MuBi4Width-1:0] mubi_sync; + abr_prim_flop_2sync #( + .Width(MuBi4Width), + .ResetValue(MuBi4Width'(ResetValue)) + ) u_abr_prim_flop_2sync ( + .clk_i, + .rst_b, + .d_i(MuBi4Width'(mubi_i)), + .q_o(mubi_sync) + ); + + if (StabilityCheck) begin : gen_stable_chks + logic [MuBi4Width-1:0] mubi_q; + abr_prim_flop #( + .Width(MuBi4Width), + .ResetValue(MuBi4Width'(ResetValue)) + ) u_abr_prim_flop_3rd_stage ( + .clk_i, + .rst_b, + .d_i(mubi_sync), + .q_o(mubi_q) + ); + + logic [MuBi4Width-1:0] sig_unstable; + abr_prim_xor2 #( + .Width(MuBi4Width) + ) u_mubi_xor ( + .in0_i(mubi_sync), + .in1_i(mubi_q), + .out_o(sig_unstable) + ); + + logic [MuBi4Width-1:0] reset_value; + assign reset_value = ResetValue; + + for (genvar k = 0; k < MuBi4Width; k++) begin : gen_bufs_muxes + logic [MuBi4Width-1:0] sig_unstable_buf; + + // each mux gets its own buffered output, this ensures the OR-ing + // cannot be defeated in one place. + abr_prim_sec_anchor_buf #( + .Width(MuBi4Width) + ) u_sig_unstable_buf ( + .in_i(sig_unstable), + .out_o(sig_unstable_buf) + ); + + // if any xor indicates signal is unstable, output the reset + // value. note that the input and output signals of this mux + // are driven/read by constrained primitive cells (regs, buffers), + // hence this mux can be implemented behaviorally. + assign mubi[k] = (|sig_unstable_buf) ? reset_value[k] : mubi_q[k]; + end + +// Note regarding SVAs below: +// +// 1) Without the sampled rst_b pre-condition, this may cause false assertion failures right after +// a reset release, since the "disable iff" condition with the rst_b is sampled in the "observed" +// SV scheduler region after all assignments have been evaluated (see also LRM section 16.12, page +// 423). This is a simulation artifact due to reset synchronization in RTL, which releases rst_b +// on the active clock edge. This causes the assertion to evaluate although the reset was actually +// 0 when entering this simulation cycle. +// +// 2) Similarly to 1) there can be sampling mismatches of the lc_en_i signal since that signal may +// originate from a different clock domain. I.e., in cases where the lc_en_i signal changes exactly +// at the same time that the clk_i signal rises, the SVA will not pick up that change in that clock +// cycle, whereas RTL will because SVAs sample values in the "preponed" region. To that end we make +// use of an RTL helper variable to sample the lc_en_i signal, hence ensuring that there are no +// sampling mismatches. +`ifdef ABR_INC_ASSERT + mubi4_t mubi_in_sva_q; + always_ff @(posedge clk_i) begin + mubi_in_sva_q <= mubi_i; + end + `ABR_ASSERT(OutputIfUnstable_A, sig_unstable |-> mubi_o == {NumCopies{reset_value}}) + `ABR_ASSERT(OutputDelay_A, + rst_b |-> ##[3:4] sig_unstable || mubi_o == {NumCopies{$past(mubi_in_sva_q, 2)}}) +`endif + end else begin : gen_no_stable_chks + assign mubi = mubi_sync; +`ifdef ABR_INC_ASSERT + mubi4_t mubi_in_sva_q; + always_ff @(posedge clk_i) begin + mubi_in_sva_q <= mubi_i; + end + `ABR_ASSERT(OutputDelay_A, + rst_b |-> ##3 (mubi_o == {NumCopies{$past(mubi_in_sva_q, 2)}} || + $past(mubi_in_sva_q, 2) != $past(mubi_in_sva_q, 1))) +`endif + end + end else begin : gen_no_flops + + //VCS coverage off + // pragma coverage off + + // This unused companion logic helps remove lint errors + // for modules where clock and reset are used for assertions only + // This logic will be removed for synthesis since it is unloaded. + mubi4_t unused_logic; + always_ff @(posedge clk_i or negedge rst_b) begin + if (!rst_b) begin + unused_logic <= MuBi4False; + end else begin + unused_logic <= mubi_i; + end + end + + //VCS coverage on + // pragma coverage on + + assign mubi = MuBi4Width'(mubi_i); + + `ABR_ASSERT(OutputDelay_A, mubi_o == {NumCopies{mubi_i}}) + end + + for (genvar j = 0; j < NumCopies; j++) begin : gen_buffs + logic [MuBi4Width-1:0] mubi_out; + for (genvar k = 0; k < MuBi4Width; k++) begin : gen_bits + abr_prim_buf u_abr_prim_buf ( + .in_i(mubi[k]), + .out_o(mubi_out[k]) + ); + end + assign mubi_o[j] = mubi4_t'(mubi_out); + end + + //////////////// + // Assertions // + //////////////// + + // The outputs should be known at all times. + `ABR_ASSERT_KNOWN(OutputsKnown_A, mubi_o) + +endmodule : abr_prim_mubi4_sync diff --git a/designs/Caliptra/src/adams-bridge/abr_prim_mubi8_sync.sv b/designs/Caliptra/src/adams-bridge/abr_prim_mubi8_sync.sv new file mode 100644 index 0000000..120060a --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/abr_prim_mubi8_sync.sv @@ -0,0 +1,179 @@ +// Copyright lowRISC contributors. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// ------------------- W A R N I N G: A U T O - G E N E R A T E D C O D E !! -------------------// +// PLEASE DO NOT HAND-EDIT THIS FILE. IT HAS BEEN AUTO-GENERATED WITH THE FOLLOWING COMMAND: +// +// util/design/gen-mubi.py +// +// Double-synchronizer flop for multibit signals with additional output buffers. + +`include "abr_prim_assert.sv" + +module abr_prim_mubi8_sync + import abr_prim_mubi_pkg::*; +#( + // Number of separately buffered output signals. + // The buffer cells have a don't touch constraint + // on them such that synthesis tools won't collapse + // all copies into one signal. + parameter int NumCopies = 1, + // This instantiates the synchronizer flops if set to 1. + // In special cases where the receiver is in the same clock domain as the sender, + // this can be set to 0. However, it is recommended to leave this at 1. + parameter bit AsyncOn = 1, + // This controls whether the mubi module institutes stability checks when + // AsyncOn is set. If stability checks are on, a 3rd stage of storage is + // added after the synchronizers and the outputs only updated if the 3rd + // stage and sychronizer agree. If they do not agree, the ResetValue is + // output instead. + parameter bit StabilityCheck = 0, + // Reset value for the sync flops + parameter mubi8_t ResetValue = MuBi8False +) ( + input clk_i, + input rst_b, + input mubi8_t mubi_i, + output mubi8_t [NumCopies-1:0] mubi_o +); + + `ABR_ASSERT_INIT(NumCopiesMustBeGreaterZero_A, NumCopies > 0) + + logic [MuBi8Width-1:0] mubi; + if (AsyncOn) begin : gen_flops + logic [MuBi8Width-1:0] mubi_sync; + abr_prim_flop_2sync #( + .Width(MuBi8Width), + .ResetValue(MuBi8Width'(ResetValue)) + ) u_abr_prim_flop_2sync ( + .clk_i, + .rst_b, + .d_i(MuBi8Width'(mubi_i)), + .q_o(mubi_sync) + ); + + if (StabilityCheck) begin : gen_stable_chks + logic [MuBi8Width-1:0] mubi_q; + abr_prim_flop #( + .Width(MuBi8Width), + .ResetValue(MuBi8Width'(ResetValue)) + ) u_abr_prim_flop_3rd_stage ( + .clk_i, + .rst_b, + .d_i(mubi_sync), + .q_o(mubi_q) + ); + + logic [MuBi8Width-1:0] sig_unstable; + abr_prim_xor2 #( + .Width(MuBi8Width) + ) u_mubi_xor ( + .in0_i(mubi_sync), + .in1_i(mubi_q), + .out_o(sig_unstable) + ); + + logic [MuBi8Width-1:0] reset_value; + assign reset_value = ResetValue; + + for (genvar k = 0; k < MuBi8Width; k++) begin : gen_bufs_muxes + logic [MuBi8Width-1:0] sig_unstable_buf; + + // each mux gets its own buffered output, this ensures the OR-ing + // cannot be defeated in one place. + abr_prim_sec_anchor_buf #( + .Width(MuBi8Width) + ) u_sig_unstable_buf ( + .in_i(sig_unstable), + .out_o(sig_unstable_buf) + ); + + // if any xor indicates signal is unstable, output the reset + // value. note that the input and output signals of this mux + // are driven/read by constrained primitive cells (regs, buffers), + // hence this mux can be implemented behaviorally. + assign mubi[k] = (|sig_unstable_buf) ? reset_value[k] : mubi_q[k]; + end + +// Note regarding SVAs below: +// +// 1) Without the sampled rst_b pre-condition, this may cause false assertion failures right after +// a reset release, since the "disable iff" condition with the rst_b is sampled in the "observed" +// SV scheduler region after all assignments have been evaluated (see also LRM section 16.12, page +// 423). This is a simulation artifact due to reset synchronization in RTL, which releases rst_b +// on the active clock edge. This causes the assertion to evaluate although the reset was actually +// 0 when entering this simulation cycle. +// +// 2) Similarly to 1) there can be sampling mismatches of the lc_en_i signal since that signal may +// originate from a different clock domain. I.e., in cases where the lc_en_i signal changes exactly +// at the same time that the clk_i signal rises, the SVA will not pick up that change in that clock +// cycle, whereas RTL will because SVAs sample values in the "preponed" region. To that end we make +// use of an RTL helper variable to sample the lc_en_i signal, hence ensuring that there are no +// sampling mismatches. +`ifdef ABR_INC_ASSERT + mubi8_t mubi_in_sva_q; + always_ff @(posedge clk_i) begin + mubi_in_sva_q <= mubi_i; + end + `ABR_ASSERT(OutputIfUnstable_A, sig_unstable |-> mubi_o == {NumCopies{reset_value}}) + `ABR_ASSERT(OutputDelay_A, + rst_b |-> ##[3:4] sig_unstable || mubi_o == {NumCopies{$past(mubi_in_sva_q, 2)}}) +`endif + end else begin : gen_no_stable_chks + assign mubi = mubi_sync; +`ifdef ABR_INC_ASSERT + mubi8_t mubi_in_sva_q; + always_ff @(posedge clk_i) begin + mubi_in_sva_q <= mubi_i; + end + `ABR_ASSERT(OutputDelay_A, + rst_b |-> ##3 (mubi_o == {NumCopies{$past(mubi_in_sva_q, 2)}} || + ($past(mubi_in_sva_q, 2) != $past(mubi_in_sva_q, 1)) || + !rst_b)) +`endif + end + end else begin : gen_no_flops + + //VCS coverage off + // pragma coverage off + + // This unused companion logic helps remove lint errors + // for modules where clock and reset are used for assertions only + // This logic will be removed for synthesis since it is unloaded. + mubi8_t unused_logic; + always_ff @(posedge clk_i or negedge rst_b) begin + if (!rst_b) begin + unused_logic <= MuBi8False; + end else begin + unused_logic <= mubi_i; + end + end + + //VCS coverage on + // pragma coverage on + + assign mubi = MuBi8Width'(mubi_i); + + `ABR_ASSERT(OutputDelay_A, mubi_o == {NumCopies{mubi_i}}) + end + + for (genvar j = 0; j < NumCopies; j++) begin : gen_buffs + logic [MuBi8Width-1:0] mubi_out; + for (genvar k = 0; k < MuBi8Width; k++) begin : gen_bits + abr_prim_buf u_abr_prim_buf ( + .in_i(mubi[k]), + .out_o(mubi_out[k]) + ); + end + assign mubi_o[j] = mubi8_t'(mubi_out); + end + + //////////////// + // Assertions // + //////////////// + + // The outputs should be known at all times. + `ABR_ASSERT_KNOWN(OutputsKnown_A, mubi_o) + +endmodule : abr_prim_mubi8_sync diff --git a/designs/Caliptra/src/adams-bridge/abr_prim_mubi_pkg.sv b/designs/Caliptra/src/adams-bridge/abr_prim_mubi_pkg.sv new file mode 100644 index 0000000..4d19238 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/abr_prim_mubi_pkg.sv @@ -0,0 +1,545 @@ +// Copyright lowRISC contributors. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// ------------------- W A R N I N G: A U T O - G E N E R A T E D C O D E !! -------------------// +// PLEASE DO NOT HAND-EDIT THIS FILE. IT HAS BEEN AUTO-GENERATED WITH THE FOLLOWING COMMAND: +// +// util/design/gen-mubi.py +// +// This package defines common multibit signal types, active high and active low values and +// the corresponding functions to test whether the values are set or not. + +`include "abr_prim_assert.sv" + +package abr_prim_mubi_pkg; + + ////////////////////////////////////////////// + // 4 Bit Multibit Type and Functions // + ////////////////////////////////////////////// + + parameter int MuBi4Width = 4; + typedef enum logic [MuBi4Width-1:0] { + MuBi4True = 4'h6, // enabled + MuBi4False = 4'h9 // disabled + } mubi4_t; + + // This is a prerequisite for the multibit functions below to work. + `ABR_ASSERT_STATIC_IN_PACKAGE(CheckMuBi4ValsComplementary_A, MuBi4True == ~MuBi4False) + + // Test whether the value is supplied is one of the valid enumerations + function automatic logic mubi4_test_invalid(mubi4_t val); + return ~(val inside {MuBi4True, MuBi4False}); + endfunction : mubi4_test_invalid + + // Convert a 1 input value to a mubi output + function automatic mubi4_t mubi4_bool_to_mubi(logic val); + return (val ? MuBi4True : MuBi4False); + endfunction : mubi4_bool_to_mubi + + // Test whether the multibit value signals an "enabled" condition. + // The strict version of this function requires + // the multibit value to equal True. + function automatic logic mubi4_test_true_strict(mubi4_t val); + return MuBi4True == val; + endfunction : mubi4_test_true_strict + + // Test whether the multibit value signals a "disabled" condition. + // The strict version of this function requires + // the multibit value to equal False. + function automatic logic mubi4_test_false_strict(mubi4_t val); + return MuBi4False == val; + endfunction : mubi4_test_false_strict + + // Test whether the multibit value signals an "enabled" condition. + // The loose version of this function interprets all + // values other than False as "enabled". + function automatic logic mubi4_test_true_loose(mubi4_t val); + return MuBi4False != val; + endfunction : mubi4_test_true_loose + + // Test whether the multibit value signals a "disabled" condition. + // The loose version of this function interprets all + // values other than True as "disabled". + function automatic logic mubi4_test_false_loose(mubi4_t val); + return MuBi4True != val; + endfunction : mubi4_test_false_loose + + + // Performs a logical OR operation between two multibit values. + // This treats "act" as logical 1, and all other values are + // treated as 0. Truth table: + // + // A | B | OUT + //------+------+----- + // !act | !act | !act + // act | !act | act + // !act | act | act + // act | act | act + // + function automatic mubi4_t mubi4_or(mubi4_t a, mubi4_t b, mubi4_t act); + logic [MuBi4Width-1:0] a_in, b_in, act_in, out; + a_in = a; + b_in = b; + act_in = act; + for (int k = 0; k < MuBi4Width; k++) begin + if (act_in[k]) begin + out[k] = a_in[k] || b_in[k]; + end else begin + out[k] = a_in[k] && b_in[k]; + end + end + return mubi4_t'(out); + endfunction : mubi4_or + + // Performs a logical AND operation between two multibit values. + // This treats "act" as logical 1, and all other values are + // treated as 0. Truth table: + // + // A | B | OUT + //------+------+----- + // !act | !act | !act + // act | !act | !act + // !act | act | !act + // act | act | act + // + function automatic mubi4_t mubi4_and(mubi4_t a, mubi4_t b, mubi4_t act); + logic [MuBi4Width-1:0] a_in, b_in, act_in, out; + a_in = a; + b_in = b; + act_in = act; + for (int k = 0; k < MuBi4Width; k++) begin + if (act_in[k]) begin + out[k] = a_in[k] && b_in[k]; + end else begin + out[k] = a_in[k] || b_in[k]; + end + end + return mubi4_t'(out); + endfunction : mubi4_and + + // Performs a logical OR operation between two multibit values. + // This treats "True" as logical 1, and all other values are + // treated as 0. + function automatic mubi4_t mubi4_or_hi(mubi4_t a, mubi4_t b); + return mubi4_or(a, b, MuBi4True); + endfunction : mubi4_or_hi + + // Performs a logical AND operation between two multibit values. + // This treats "True" as logical 1, and all other values are + // treated as 0. + function automatic mubi4_t mubi4_and_hi(mubi4_t a, mubi4_t b); + return mubi4_and(a, b, MuBi4True); + endfunction : mubi4_and_hi + + // Performs a logical OR operation between two multibit values. + // This treats "False" as logical 1, and all other values are + // treated as 0. + function automatic mubi4_t mubi4_or_lo(mubi4_t a, mubi4_t b); + return mubi4_or(a, b, MuBi4False); + endfunction : mubi4_or_lo + + // Performs a logical AND operation between two multibit values. + // Tlos treats "False" as logical 1, and all other values are + // treated as 0. + function automatic mubi4_t mubi4_and_lo(mubi4_t a, mubi4_t b); + return mubi4_and(a, b, MuBi4False); + endfunction : mubi4_and_lo + + ////////////////////////////////////////////// + // 8 Bit Multibit Type and Functions // + ////////////////////////////////////////////// + + parameter int MuBi8Width = 8; + typedef enum logic [MuBi8Width-1:0] { + MuBi8True = 8'h96, // enabled + MuBi8False = 8'h69 // disabled + } mubi8_t; + + // This is a prerequisite for the multibit functions below to work. + `ABR_ASSERT_STATIC_IN_PACKAGE(CheckMuBi8ValsComplementary_A, MuBi8True == ~MuBi8False) + + // Test whether the value is supplied is one of the valid enumerations + function automatic logic mubi8_test_invalid(mubi8_t val); + return ~(val inside {MuBi8True, MuBi8False}); + endfunction : mubi8_test_invalid + + // Convert a 1 input value to a mubi output + function automatic mubi8_t mubi8_bool_to_mubi(logic val); + return (val ? MuBi8True : MuBi8False); + endfunction : mubi8_bool_to_mubi + + // Test whether the multibit value signals an "enabled" condition. + // The strict version of this function requires + // the multibit value to equal True. + function automatic logic mubi8_test_true_strict(mubi8_t val); + return MuBi8True == val; + endfunction : mubi8_test_true_strict + + // Test whether the multibit value signals a "disabled" condition. + // The strict version of this function requires + // the multibit value to equal False. + function automatic logic mubi8_test_false_strict(mubi8_t val); + return MuBi8False == val; + endfunction : mubi8_test_false_strict + + // Test whether the multibit value signals an "enabled" condition. + // The loose version of this function interprets all + // values other than False as "enabled". + function automatic logic mubi8_test_true_loose(mubi8_t val); + return MuBi8False != val; + endfunction : mubi8_test_true_loose + + // Test whether the multibit value signals a "disabled" condition. + // The loose version of this function interprets all + // values other than True as "disabled". + function automatic logic mubi8_test_false_loose(mubi8_t val); + return MuBi8True != val; + endfunction : mubi8_test_false_loose + + + // Performs a logical OR operation between two multibit values. + // This treats "act" as logical 1, and all other values are + // treated as 0. Truth table: + // + // A | B | OUT + //------+------+----- + // !act | !act | !act + // act | !act | act + // !act | act | act + // act | act | act + // + function automatic mubi8_t mubi8_or(mubi8_t a, mubi8_t b, mubi8_t act); + logic [MuBi8Width-1:0] a_in, b_in, act_in, out; + a_in = a; + b_in = b; + act_in = act; + for (int k = 0; k < MuBi8Width; k++) begin + if (act_in[k]) begin + out[k] = a_in[k] || b_in[k]; + end else begin + out[k] = a_in[k] && b_in[k]; + end + end + return mubi8_t'(out); + endfunction : mubi8_or + + // Performs a logical AND operation between two multibit values. + // This treats "act" as logical 1, and all other values are + // treated as 0. Truth table: + // + // A | B | OUT + //------+------+----- + // !act | !act | !act + // act | !act | !act + // !act | act | !act + // act | act | act + // + function automatic mubi8_t mubi8_and(mubi8_t a, mubi8_t b, mubi8_t act); + logic [MuBi8Width-1:0] a_in, b_in, act_in, out; + a_in = a; + b_in = b; + act_in = act; + for (int k = 0; k < MuBi8Width; k++) begin + if (act_in[k]) begin + out[k] = a_in[k] && b_in[k]; + end else begin + out[k] = a_in[k] || b_in[k]; + end + end + return mubi8_t'(out); + endfunction : mubi8_and + + // Performs a logical OR operation between two multibit values. + // This treats "True" as logical 1, and all other values are + // treated as 0. + function automatic mubi8_t mubi8_or_hi(mubi8_t a, mubi8_t b); + return mubi8_or(a, b, MuBi8True); + endfunction : mubi8_or_hi + + // Performs a logical AND operation between two multibit values. + // This treats "True" as logical 1, and all other values are + // treated as 0. + function automatic mubi8_t mubi8_and_hi(mubi8_t a, mubi8_t b); + return mubi8_and(a, b, MuBi8True); + endfunction : mubi8_and_hi + + // Performs a logical OR operation between two multibit values. + // This treats "False" as logical 1, and all other values are + // treated as 0. + function automatic mubi8_t mubi8_or_lo(mubi8_t a, mubi8_t b); + return mubi8_or(a, b, MuBi8False); + endfunction : mubi8_or_lo + + // Performs a logical AND operation between two multibit values. + // Tlos treats "False" as logical 1, and all other values are + // treated as 0. + function automatic mubi8_t mubi8_and_lo(mubi8_t a, mubi8_t b); + return mubi8_and(a, b, MuBi8False); + endfunction : mubi8_and_lo + + ////////////////////////////////////////////// + // 12 Bit Multibit Type and Functions // + ////////////////////////////////////////////// + + parameter int MuBi12Width = 12; + typedef enum logic [MuBi12Width-1:0] { + MuBi12True = 12'h696, // enabled + MuBi12False = 12'h969 // disabled + } mubi12_t; + + // This is a prerequisite for the multibit functions below to work. + `ABR_ASSERT_STATIC_IN_PACKAGE(CheckMuBi12ValsComplementary_A, MuBi12True == ~MuBi12False) + + // Test whether the value is supplied is one of the valid enumerations + function automatic logic mubi12_test_invalid(mubi12_t val); + return ~(val inside {MuBi12True, MuBi12False}); + endfunction : mubi12_test_invalid + + // Convert a 1 input value to a mubi output + function automatic mubi12_t mubi12_bool_to_mubi(logic val); + return (val ? MuBi12True : MuBi12False); + endfunction : mubi12_bool_to_mubi + + // Test whether the multibit value signals an "enabled" condition. + // The strict version of this function requires + // the multibit value to equal True. + function automatic logic mubi12_test_true_strict(mubi12_t val); + return MuBi12True == val; + endfunction : mubi12_test_true_strict + + // Test whether the multibit value signals a "disabled" condition. + // The strict version of this function requires + // the multibit value to equal False. + function automatic logic mubi12_test_false_strict(mubi12_t val); + return MuBi12False == val; + endfunction : mubi12_test_false_strict + + // Test whether the multibit value signals an "enabled" condition. + // The loose version of this function interprets all + // values other than False as "enabled". + function automatic logic mubi12_test_true_loose(mubi12_t val); + return MuBi12False != val; + endfunction : mubi12_test_true_loose + + // Test whether the multibit value signals a "disabled" condition. + // The loose version of this function interprets all + // values other than True as "disabled". + function automatic logic mubi12_test_false_loose(mubi12_t val); + return MuBi12True != val; + endfunction : mubi12_test_false_loose + + + // Performs a logical OR operation between two multibit values. + // This treats "act" as logical 1, and all other values are + // treated as 0. Truth table: + // + // A | B | OUT + //------+------+----- + // !act | !act | !act + // act | !act | act + // !act | act | act + // act | act | act + // + function automatic mubi12_t mubi12_or(mubi12_t a, mubi12_t b, mubi12_t act); + logic [MuBi12Width-1:0] a_in, b_in, act_in, out; + a_in = a; + b_in = b; + act_in = act; + for (int k = 0; k < MuBi12Width; k++) begin + if (act_in[k]) begin + out[k] = a_in[k] || b_in[k]; + end else begin + out[k] = a_in[k] && b_in[k]; + end + end + return mubi12_t'(out); + endfunction : mubi12_or + + // Performs a logical AND operation between two multibit values. + // This treats "act" as logical 1, and all other values are + // treated as 0. Truth table: + // + // A | B | OUT + //------+------+----- + // !act | !act | !act + // act | !act | !act + // !act | act | !act + // act | act | act + // + function automatic mubi12_t mubi12_and(mubi12_t a, mubi12_t b, mubi12_t act); + logic [MuBi12Width-1:0] a_in, b_in, act_in, out; + a_in = a; + b_in = b; + act_in = act; + for (int k = 0; k < MuBi12Width; k++) begin + if (act_in[k]) begin + out[k] = a_in[k] && b_in[k]; + end else begin + out[k] = a_in[k] || b_in[k]; + end + end + return mubi12_t'(out); + endfunction : mubi12_and + + // Performs a logical OR operation between two multibit values. + // This treats "True" as logical 1, and all other values are + // treated as 0. + function automatic mubi12_t mubi12_or_hi(mubi12_t a, mubi12_t b); + return mubi12_or(a, b, MuBi12True); + endfunction : mubi12_or_hi + + // Performs a logical AND operation between two multibit values. + // This treats "True" as logical 1, and all other values are + // treated as 0. + function automatic mubi12_t mubi12_and_hi(mubi12_t a, mubi12_t b); + return mubi12_and(a, b, MuBi12True); + endfunction : mubi12_and_hi + + // Performs a logical OR operation between two multibit values. + // This treats "False" as logical 1, and all other values are + // treated as 0. + function automatic mubi12_t mubi12_or_lo(mubi12_t a, mubi12_t b); + return mubi12_or(a, b, MuBi12False); + endfunction : mubi12_or_lo + + // Performs a logical AND operation between two multibit values. + // Tlos treats "False" as logical 1, and all other values are + // treated as 0. + function automatic mubi12_t mubi12_and_lo(mubi12_t a, mubi12_t b); + return mubi12_and(a, b, MuBi12False); + endfunction : mubi12_and_lo + + ////////////////////////////////////////////// + // 16 Bit Multibit Type and Functions // + ////////////////////////////////////////////// + + parameter int MuBi16Width = 16; + typedef enum logic [MuBi16Width-1:0] { + MuBi16True = 16'h9696, // enabled + MuBi16False = 16'h6969 // disabled + } mubi16_t; + + // This is a prerequisite for the multibit functions below to work. + `ABR_ASSERT_STATIC_IN_PACKAGE(CheckMuBi16ValsComplementary_A, MuBi16True == ~MuBi16False) + + // Test whether the value is supplied is one of the valid enumerations + function automatic logic mubi16_test_invalid(mubi16_t val); + return ~(val inside {MuBi16True, MuBi16False}); + endfunction : mubi16_test_invalid + + // Convert a 1 input value to a mubi output + function automatic mubi16_t mubi16_bool_to_mubi(logic val); + return (val ? MuBi16True : MuBi16False); + endfunction : mubi16_bool_to_mubi + + // Test whether the multibit value signals an "enabled" condition. + // The strict version of this function requires + // the multibit value to equal True. + function automatic logic mubi16_test_true_strict(mubi16_t val); + return MuBi16True == val; + endfunction : mubi16_test_true_strict + + // Test whether the multibit value signals a "disabled" condition. + // The strict version of this function requires + // the multibit value to equal False. + function automatic logic mubi16_test_false_strict(mubi16_t val); + return MuBi16False == val; + endfunction : mubi16_test_false_strict + + // Test whether the multibit value signals an "enabled" condition. + // The loose version of this function interprets all + // values other than False as "enabled". + function automatic logic mubi16_test_true_loose(mubi16_t val); + return MuBi16False != val; + endfunction : mubi16_test_true_loose + + // Test whether the multibit value signals a "disabled" condition. + // The loose version of this function interprets all + // values other than True as "disabled". + function automatic logic mubi16_test_false_loose(mubi16_t val); + return MuBi16True != val; + endfunction : mubi16_test_false_loose + + + // Performs a logical OR operation between two multibit values. + // This treats "act" as logical 1, and all other values are + // treated as 0. Truth table: + // + // A | B | OUT + //------+------+----- + // !act | !act | !act + // act | !act | act + // !act | act | act + // act | act | act + // + function automatic mubi16_t mubi16_or(mubi16_t a, mubi16_t b, mubi16_t act); + logic [MuBi16Width-1:0] a_in, b_in, act_in, out; + a_in = a; + b_in = b; + act_in = act; + for (int k = 0; k < MuBi16Width; k++) begin + if (act_in[k]) begin + out[k] = a_in[k] || b_in[k]; + end else begin + out[k] = a_in[k] && b_in[k]; + end + end + return mubi16_t'(out); + endfunction : mubi16_or + + // Performs a logical AND operation between two multibit values. + // This treats "act" as logical 1, and all other values are + // treated as 0. Truth table: + // + // A | B | OUT + //------+------+----- + // !act | !act | !act + // act | !act | !act + // !act | act | !act + // act | act | act + // + function automatic mubi16_t mubi16_and(mubi16_t a, mubi16_t b, mubi16_t act); + logic [MuBi16Width-1:0] a_in, b_in, act_in, out; + a_in = a; + b_in = b; + act_in = act; + for (int k = 0; k < MuBi16Width; k++) begin + if (act_in[k]) begin + out[k] = a_in[k] && b_in[k]; + end else begin + out[k] = a_in[k] || b_in[k]; + end + end + return mubi16_t'(out); + endfunction : mubi16_and + + // Performs a logical OR operation between two multibit values. + // This treats "True" as logical 1, and all other values are + // treated as 0. + function automatic mubi16_t mubi16_or_hi(mubi16_t a, mubi16_t b); + return mubi16_or(a, b, MuBi16True); + endfunction : mubi16_or_hi + + // Performs a logical AND operation between two multibit values. + // This treats "True" as logical 1, and all other values are + // treated as 0. + function automatic mubi16_t mubi16_and_hi(mubi16_t a, mubi16_t b); + return mubi16_and(a, b, MuBi16True); + endfunction : mubi16_and_hi + + // Performs a logical OR operation between two multibit values. + // This treats "False" as logical 1, and all other values are + // treated as 0. + function automatic mubi16_t mubi16_or_lo(mubi16_t a, mubi16_t b); + return mubi16_or(a, b, MuBi16False); + endfunction : mubi16_or_lo + + // Performs a logical AND operation between two multibit values. + // Tlos treats "False" as logical 1, and all other values are + // treated as 0. + function automatic mubi16_t mubi16_and_lo(mubi16_t a, mubi16_t b); + return mubi16_and(a, b, MuBi16False); + endfunction : mubi16_and_lo + +endpackage : abr_prim_mubi_pkg diff --git a/designs/Caliptra/src/adams-bridge/abr_prim_onehot_check.sv b/designs/Caliptra/src/adams-bridge/abr_prim_onehot_check.sv new file mode 100644 index 0000000..db16d3f --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/abr_prim_onehot_check.sv @@ -0,0 +1,155 @@ +// Copyright lowRISC contributors. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// Onehot checker. +// +// This module checks whether the input vector oh_i is onehot0 and generates an error if not. +// +// Optionally, two additional checks can be activated: +// +// 1) EnableCheck: this check performs an OR reduction of the onehot vector, and compares +// the result with en_i. If there is a mismatch, an error is generated. +// 2) AddrCheck: this checks whether the onehot bit is in the correct position. +// It requires an additional address addr_i to be supplied to the module. +// +// All checks make use of an explicit binary tree implementation in order to minimize the delay. +// + +`include "abr_prim_assert.sv" + +module abr_prim_onehot_check #( + parameter int unsigned AddrWidth = 5, + // The onehot width can be <= 2**AddrWidth and does not have to be a power of two. + parameter int unsigned OneHotWidth = 2**AddrWidth, + // If set to 0, the addr_i input will not be used for the check and can be tied off. + parameter bit AddrCheck = 1, + // If set to 0, the en_i value will not be used for the check and can be tied off. + parameter bit EnableCheck = 1, + // If set to 1, the oh_i vector must always be one hot if en_i is set to 1. + // If set to 0, the oh_i vector may be 0 if en_i is set to 1 (useful when oh_i can be masked). + parameter bit StrictCheck = 1, + // This should only be disabled in special circumstances, for example + // in non-comportable IPs where an error does not trigger an alert. + parameter bit EnableAlertTriggerSVA = 1 +) ( + // The module is combinational - the clock and reset are only used for assertions. + input clk_i, + input rst_b, + + input logic [OneHotWidth-1:0] oh_i, + input logic [AddrWidth-1:0] addr_i, + input logic en_i, + + output logic err_o +); + + /////////////////////// + // Binary tree logic // + /////////////////////// + + `ABR_ASSERT_INIT(NumSources_A, OneHotWidth >= 1) + `ABR_ASSERT_INIT(AddrWidth_A, AddrWidth >= 1) + `ABR_ASSERT_INIT(AddrRange_A, OneHotWidth <= 2**AddrWidth) + `ABR_ASSERT_INIT(AddrImpliesEnable_A, AddrCheck && EnableCheck || !AddrCheck) + + // Align to powers of 2 for simplicity. + // A full binary tree with N levels has 2**N + 2**N-1 nodes. + localparam int NumLevels = AddrWidth; + logic [2**(NumLevels+1)-2:0] or_tree; + logic [2**(NumLevels+1)-2:0] and_tree; // Used for the address check + logic [2**(NumLevels+1)-2:0] err_tree; // Used for the enable check + + for (genvar level = 0; level < NumLevels+1; level++) begin : gen_tree + // + // level+1 C0 C1 <- "Base1" points to the first node on "level+1", + // \ / these nodes are the children of the nodes one level below + // level Pa <- "Base0", points to the first node on "level", + // these nodes are the parents of the nodes one level above + // + // hence we have the following indices for the paPa, C0, C1 nodes: + // Pa = 2**level - 1 + offset = Base0 + offset + // C0 = 2**(level+1) - 1 + 2*offset = Base1 + 2*offset + // C1 = 2**(level+1) - 1 + 2*offset + 1 = Base1 + 2*offset + 1 + // + localparam int Base0 = (2**level)-1; + localparam int Base1 = (2**(level+1))-1; + + for (genvar offset = 0; offset < 2**level; offset++) begin : gen_level + localparam int Pa = Base0 + offset; + localparam int C0 = Base1 + 2*offset; + localparam int C1 = Base1 + 2*offset + 1; + + // This assigns the input values, their corresponding IDs and valid signals to the tree leafs. + if (level == NumLevels) begin : gen_leafs + if (offset < OneHotWidth) begin : gen_assign + assign or_tree[Pa] = oh_i[offset]; + assign and_tree[Pa] = oh_i[offset]; + end else begin : gen_tie_off + assign or_tree[Pa] = 1'b0; + assign and_tree[Pa] = 1'b0; + end + assign err_tree[Pa] = 1'b0; + // This creates the node assignments. + end else begin : gen_nodes + assign or_tree[Pa] = or_tree[C0] || or_tree[C1]; + assign and_tree[Pa] = (!addr_i[AddrWidth-1-level] && and_tree[C0]) || + (addr_i[AddrWidth-1-level] && and_tree[C1]); + assign err_tree[Pa] = (or_tree[C0] && or_tree[C1]) || err_tree[C0] || err_tree[C1]; + end + end : gen_level + end : gen_tree + + /////////////////// + // Onehot Checks // + /////////////////// + + logic enable_err, addr_err, oh0_err; + assign err_o = oh0_err || enable_err || addr_err; + + // Check that no more than 1 bit is set in the vector. + assign oh0_err = err_tree[0]; + `ABR_ASSERT(Onehot0Check_A, !$onehot0(oh_i) |-> err_o) + + // Check that en_i agrees with (|oh_i). + // Note: if StrictCheck 0, the oh_i vector may be all-zero if en_i == 1 (but not vice versa). + if (EnableCheck) begin : gen_enable_check + if (StrictCheck) begin : gen_strict + assign enable_err = or_tree[0] ^ en_i; + `ABR_ASSERT(EnableCheck_A, (|oh_i) != en_i |-> err_o) + end else begin : gen_not_strict + assign enable_err = !en_i && or_tree[0]; + `ABR_ASSERT(EnableCheck_A, !en_i && (|oh_i) |-> err_o) + end + end else begin : gen_no_enable_check + logic unused_or_tree; + assign unused_or_tree = ^or_tree; + assign enable_err = 1'b0; + end + + // Check that the set bit is actually in the correct position. + if (AddrCheck) begin : gen_addr_check_strict + assign addr_err = or_tree[0] ^ and_tree[0]; + `ABR_ASSERT(AddrCheck_A, oh_i[addr_i] != (|oh_i) |-> err_o) + end else begin : gen_no_addr_check_strict + logic unused_and_tree; + assign unused_and_tree = ^and_tree; + assign addr_err = 1'b0; + end + + // This logic that will be assign to one, when user adds macro + // ABR_ASSERT_PRIM_ONEHOT_ERROR_TRIGGER_ALERT to check the error with alert, in case that + // abr_prim_onehot_check is used in design without adding this assertion check. + `ifdef ABR_INC_ASSERT + `ifndef PRIM_DEFAULT_IMPL + `define ABR_PRIM_DEFAULT_IMPL abr_prim_pkg::ImplGeneric + `endif + parameter abr_prim_pkg::impl_e Impl = `ABR_PRIM_DEFAULT_IMPL; + + logic unused_assert_connected; + // TODO(#13337): only check generic for now. The path of this prim in other Impl may differ + if (Impl == abr_prim_pkg::ImplGeneric) begin : gen_generic + `ABR_ASSERT_INIT_NET(AssertConnected_A, unused_assert_connected === 1'b1 || !EnableAlertTriggerSVA) + end + `endif +endmodule : abr_prim_onehot_check diff --git a/designs/Caliptra/src/adams-bridge/abr_prim_packer_fifo.sv b/designs/Caliptra/src/adams-bridge/abr_prim_packer_fifo.sv new file mode 100644 index 0000000..287b3b4 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/abr_prim_packer_fifo.sv @@ -0,0 +1,180 @@ +// Copyright lowRISC contributors. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Supports packed and unpacked modes +// Uses FIFO timing on the control signals +// No masking or flush functions supported + +// Timings - case where InW < OutW +// clk_i __|~~|__~~|__|~~|__~~|__|~~|__~~|__|~~|__~~|__|~~|__~~|__|~~|__ +// wvalid_i _____|~~~~|_____|~~~~|_____|~~~~|_____|~~~~|___________________ +// wdata_i Val N |Val N+1 |Val N+2 |Val N+3 |------------------- +// wready_o ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~|__________|~~~~~~~~ +// rvalid_o ___________________________________________|~~~~~~~~~~|________ +// rdata_o -------------------------------------------|Val |-------- +// rready_i _________________________________________________|~~~~|________ +// depth_o 0000000000|1111111111|2222222222|3333333333|4444444444|00000000 + + +// Timings - case where InW > OutW +// clk_i __|~~|__~~|__|~~|__~~|__|~~|__~~|__|~~|__~~|__|~~|__~~|__|~~|__ +// wvalid_i _____|~~~~|____________________________________________________ +// wdata_i -----|Val |---------------------------------------------------- +// wready_o ~~~~~~~~~~|___________________________________________|~~~~~~~~ +// rvalid_o __________|~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~|________ +// rdata_o ----------|Val N |Val N+1 |Val N+2 |Val N+3 |-------- +// rready_i ________________|~~~~|_____|~~~~|_____|~~~~|_____|~~~~|________ +// depth_o 0000000000|4444444444|3333333333|2222222222|1111111111|00000000 + + +// Timings - case where InW = OutW +// clk_i __|~~|__~~|__|~~|__~~|__|~~|__~~|__|~~|__~~|__|~~|__~~|__|~~|__ +// wvalid_i _____|~~~~|____________________________________________________ +// wdata_i -----|Val |---------------------------------------------------- +// wready_o ~~~~~~~~~~|__________|~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// rvalid_o __________|~~~~~~~~~~|_________________________________________ +// rdata_o ----------|Val |----------------------------------------- +// rready_i ________________|~~~~|_________________________________________ +// depth_o 0000000000|1111111111|00000000000000000000000000000000000000000 + + +`include "abr_prim_assert.sv" + +module abr_prim_packer_fifo #( + parameter int InW = 32, + parameter int OutW = 8, + parameter bit ClearOnRead = 1'b1, // if == 1 always output 0 after read + // derived parameters + localparam int MaxW = (InW > OutW) ? InW : OutW, + localparam int MinW = (InW < OutW) ? InW : OutW, + localparam int DepthW = $clog2(MaxW/MinW) +) ( + input logic clk_i , + input logic rst_b, + + input logic clr_i, + input logic wvalid_i, + input logic [InW-1:0] wdata_i, + output logic wready_o, + + output logic rvalid_o, + output logic [OutW-1:0] rdata_o, + input logic rready_i, + output logic [DepthW:0] depth_o +); + + localparam int unsigned WidthRatio = MaxW / MinW; + localparam bit [DepthW:0] FullDepth = WidthRatio[DepthW:0]; + + // signals + logic load_data; + logic clear_data; + logic clear_status; + + // flops + logic [DepthW:0] depth_q, depth_d; + logic [MaxW-1:0] data_q, data_d; + logic clr_q, clr_d; + + always_ff @(posedge clk_i or negedge rst_b) begin + if (!rst_b) begin + depth_q <= '0; + data_q <= '0; + clr_q <= 1'b1; + end else begin + depth_q <= depth_d; + data_q <= data_d; + clr_q <= clr_d; + end + end + + // flop for handling reset case for clr + assign clr_d = clr_i; + + assign depth_o = depth_q; + + if (InW < OutW) begin : gen_pack_mode + logic [MaxW-1:0] wdata_shifted; + + assign wdata_shifted = {{OutW - InW{1'b0}}, wdata_i} << (depth_q*InW); + assign clear_status = (rready_i && rvalid_o) || clr_q; + assign clear_data = (ClearOnRead && clear_status) || clr_q; + assign load_data = wvalid_i && wready_o; + + assign depth_d = clear_status ? '0 : + load_data ? depth_q+1 : + depth_q; + + assign data_d = clear_data ? '0 : + load_data ? (wdata_shifted | (depth_q == 0 ? '0 : data_q)) : + data_q; + + // set outputs + assign wready_o = !(depth_q == FullDepth) && !clr_q; + assign rdata_o = data_q; + assign rvalid_o = (depth_q == FullDepth) && !clr_q; + + end else begin : gen_unpack_mode + logic [MaxW-1:0] rdata_shifted; + logic pull_data; + logic [DepthW:0] ptr_q, ptr_d; + logic [DepthW:0] lsb_is_one; + logic [DepthW:0] max_value; + + always_ff @(posedge clk_i or negedge rst_b) begin + if (!rst_b) begin + ptr_q <= '0; + end else begin + ptr_q <= ptr_d; + end + end + + assign lsb_is_one = {{DepthW{1'b0}},1'b1}; + assign max_value = FullDepth; + assign rdata_shifted = MaxW'(data_q >> ptr_q*OutW); + assign clear_status = (rready_i && (depth_q == lsb_is_one)) || clr_q; + assign clear_data = (ClearOnRead && clear_status) || clr_q; + assign load_data = wvalid_i && wready_o; + assign pull_data = rvalid_o && rready_i; + + assign depth_d = clear_status ? '0 : + load_data ? max_value : + pull_data ? depth_q-1 : + depth_q; + + assign ptr_d = clear_status ? '0 : + pull_data ? ptr_q+1 : + ptr_q; + + assign data_d = clear_data ? '0 : + load_data ? wdata_i : + data_q; + + // set outputs + assign wready_o = (depth_q == '0) && !clr_q; + assign rdata_o = rdata_shifted[OutW-1:0]; + assign rvalid_o = !(depth_q == '0) && !clr_q; + + // Avoid possible lint errors in case InW > OutW. + if (InW > OutW) begin : gen_unused + logic [MaxW-MinW-1:0] unused_rdata_shifted; + assign unused_rdata_shifted = rdata_shifted[MaxW-1:MinW]; + end + end + + + ////////////////////////////////////////////// + // Assertions, Assumptions, and Coverpoints // + ////////////////////////////////////////////// + + // If not acked, valid_o should keep asserting + `ABR_ASSERT(ValidOPairedWithReadyI_A, + rvalid_o && !rready_i && !clr_i |=> rvalid_o) + + // If output port doesn't accept the data, the data should be stable + `ABR_ASSERT(DataOStableWhenPending_A, + ##1 rvalid_o && $past(rvalid_o) + && !$past(rready_i) && !$past(clr_i) |-> $stable(rdata_o)) + +endmodule diff --git a/designs/Caliptra/src/adams-bridge/abr_prim_pkg.sv b/designs/Caliptra/src/adams-bridge/abr_prim_pkg.sv new file mode 100755 index 0000000..37662ec --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/abr_prim_pkg.sv @@ -0,0 +1,17 @@ +// Copyright lowRISC contributors. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Constants for use in primitives + +// This file is auto-generated. + +package abr_prim_pkg; + + // Implementation target specialization + typedef enum logic [31:0] { + ImplGeneric, + ImplXilinx, + ImplBadbit + } impl_e; +endpackage : abr_prim_pkg diff --git a/designs/Caliptra/src/adams-bridge/abr_prim_reg_we_check.sv b/designs/Caliptra/src/adams-bridge/abr_prim_reg_we_check.sv new file mode 100644 index 0000000..1da408c --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/abr_prim_reg_we_check.sv @@ -0,0 +1,54 @@ +// Copyright lowRISC contributors. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// Spurious write-enable checker for autogenerated CSR node. +// This module has additional simulation features for error injection testing. + +`include "abr_prim_assert.sv" + +module abr_prim_reg_we_check #( + parameter int unsigned OneHotWidth = 32 +) ( + // The module is combinational - the clock and reset are only used for assertions. + input clk_i, + input rst_b, + + input logic [OneHotWidth-1:0] oh_i, + input logic en_i, + + output logic err_o +); + + // Prevent optimization of the onehot input buffer. + logic [OneHotWidth-1:0] oh_buf; + abr_prim_buf #( + .Width(OneHotWidth) + ) u_abr_prim_buf ( + .in_i(oh_i), + .out_o(oh_buf) + ); + + abr_prim_onehot_check #( + .OneHotWidth(OneHotWidth), + .AddrWidth (abr_prim_util_pkg::vbits(OneHotWidth)), + .EnableCheck(1), + // Since certain peripherals may have a very large address space + // (e.g. > 20bit), the inverse address decoding check (which is + // essentially an indexing operation) does not scale well and is + // hence omitted. + .AddrCheck(0), + // Due to REGWEN masking of write enable strobes, + // we do not perform strict checks. I.e., we allow cases + // where en_i is set to 1, but the oh_i vector is all-zeroes. + .StrictCheck(0) + ) u_abr_prim_onehot_check ( + .clk_i, + .rst_b, + .oh_i(oh_buf), + .addr_i('0), + .en_i, + .err_o + ); + +endmodule : abr_prim_reg_we_check diff --git a/designs/Caliptra/src/adams-bridge/abr_prim_sec_anchor_buf.sv b/designs/Caliptra/src/adams-bridge/abr_prim_sec_anchor_buf.sv new file mode 100644 index 0000000..e1f4032 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/abr_prim_sec_anchor_buf.sv @@ -0,0 +1,21 @@ +// Copyright lowRISC contributors. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +`include "abr_prim_assert.sv" + +module abr_prim_sec_anchor_buf #( + parameter int Width = 1 +) ( + input [Width-1:0] in_i, + output logic [Width-1:0] out_o +); + + abr_prim_buf #( + .Width(Width) + ) u_secure_anchor_buf ( + .in_i, + .out_o + ); + +endmodule diff --git a/designs/Caliptra/src/adams-bridge/abr_prim_sec_anchor_flop.sv b/designs/Caliptra/src/adams-bridge/abr_prim_sec_anchor_flop.sv new file mode 100644 index 0000000..671d057 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/abr_prim_sec_anchor_flop.sv @@ -0,0 +1,27 @@ +// Copyright lowRISC contributors. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +`include "abr_prim_assert.sv" + +module abr_prim_sec_anchor_flop #( + parameter int Width = 1, + parameter logic [Width-1:0] ResetValue = 0 +) ( + input clk_i, + input rst_b, + input [Width-1:0] d_i, + output logic [Width-1:0] q_o +); + + abr_prim_flop #( + .Width(Width), + .ResetValue(ResetValue) + ) u_secure_anchor_flop ( + .clk_i, + .rst_b, + .d_i, + .q_o + ); + +endmodule diff --git a/designs/Caliptra/src/adams-bridge/abr_prim_slicer.sv b/designs/Caliptra/src/adams-bridge/abr_prim_slicer.sv new file mode 100644 index 0000000..6118c84 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/abr_prim_slicer.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 +// +// Slicer chops the incoming bitstring into OutW granularity. +// It supports fractional InW/OutW which fills 0 at the end of message. + +`include "abr_prim_assert.sv" + +module abr_prim_slicer #( + parameter int InW = 64, + parameter int OutW = 8, + + parameter int IndexW = 4 +) ( + input [IndexW-1:0] sel_i, + input [InW-1:0] data_i, + output logic [OutW-1:0] data_o +); + + localparam int UnrollW = OutW*(2**IndexW); + + logic [UnrollW-1:0] unrolled_data; + + assign unrolled_data = UnrollW'(data_i); + + assign data_o = unrolled_data[sel_i*OutW+:OutW]; + + `ABR_ASSERT_INIT(ValidWidth_A, InW <= OutW*(2**IndexW)) + +endmodule + diff --git a/designs/Caliptra/src/adams-bridge/abr_prim_sparse_fsm_flop.sv b/designs/Caliptra/src/adams-bridge/abr_prim_sparse_fsm_flop.sv new file mode 100644 index 0000000..49ca9ee --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/abr_prim_sparse_fsm_flop.sv @@ -0,0 +1,69 @@ +// Copyright lowRISC contributors. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +`include "abr_prim_assert.sv" + +module abr_prim_sparse_fsm_flop + import abr_prim_sparse_fsm_pkg::*; +#( + parameter int Width = 1, + parameter type StateEnumT = state_t, + parameter logic [Width-1:0] ResetValue = '0, + // This should only be disabled in special circumstances, for example + // in non-comportable IPs where an error does not trigger an alert. + parameter bit EnableAlertTriggerSVA = 1 +`ifdef ABR_SIMULATION + , + // In case this parameter is set to a non-empty string, the + // abr_prim_sparse_fsm_flop_if will also force the signal with this name + // in the parent module that instantiates abr_prim_sparse_fsm_flop. + parameter string CustomForceName = "" +`endif +) ( + input clk_i, + input rst_b, + input StateEnumT state_i, + output StateEnumT state_o +); + + logic unused_err_o; + + logic [Width-1:0] state_raw; + abr_prim_flop #( + .Width(Width), + .ResetValue(ResetValue) + ) u_state_flop ( + .clk_i, + .rst_b, + .d_i(state_i), + .q_o(state_raw) + ); + assign state_o = StateEnumT'(state_raw); + + `ifdef ABR_INC_ASSERT + assign unused_err_o = is_undefined_state(state_o); + + function automatic logic is_undefined_state(StateEnumT sig); + // This is written with a vector in order to make it amenable to x-prop analysis. + logic is_defined = 1'b0; + for (int i = 0, StateEnumT t = t.first(); i < t.num(); i += 1, t = t.next()) begin + is_defined |= (sig === t); + end + return ~is_defined; + endfunction + + `else + assign unused_err_o = 1'b0; + `endif + + // If ABR_ASSERT_PRIM_FSM_ERROR_TRIGGER_ALERT is declared, the unused_assert_connected signal will + // be set to 1 and the below check will pass. + // If the assertion is not declared however, the statement below will fail. + `ifdef ABR_INC_ASSERT + logic unused_assert_connected; + + `ABR_ASSERT_INIT_NET(AssertConnected_A, unused_assert_connected === 1'b1 || !EnableAlertTriggerSVA) + `endif + +endmodule diff --git a/designs/Caliptra/src/adams-bridge/abr_prim_sparse_fsm_pkg.sv b/designs/Caliptra/src/adams-bridge/abr_prim_sparse_fsm_pkg.sv new file mode 100644 index 0000000..d6ebcd9 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/abr_prim_sparse_fsm_pkg.sv @@ -0,0 +1,7 @@ +// Copyright lowRISC contributors. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +package abr_prim_sparse_fsm_pkg; + typedef enum logic {Idle, Done} state_t; +endpackage : abr_prim_sparse_fsm_pkg diff --git a/designs/Caliptra/src/adams-bridge/abr_prim_subreg.sv b/designs/Caliptra/src/adams-bridge/abr_prim_subreg.sv new file mode 100644 index 0000000..f58dff8 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/abr_prim_subreg.sv @@ -0,0 +1,66 @@ +// Copyright lowRISC contributors. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Register slice conforming to Comportibility guide. + +module abr_prim_subreg + import abr_prim_subreg_pkg::*; +#( + parameter int DW = 32, + parameter sw_access_e SwAccess = SwAccessRW, + parameter logic [DW-1:0] RESVAL = '0 // reset value +) ( + input clk_i, + input rst_b, + + // From SW: valid for RW, WO, W1C, W1S, W0C, RC + // In case of RC, Top connects Read Pulse to we + input we, + input [DW-1:0] wd, + + // From HW: valid for HRW, HWO + input de, + input [DW-1:0] d, + + // output to HW and Reg Read + output logic qe, + output logic [DW-1:0] q, + + // ds and qs have slightly different timing. + // ds is the data that will be written into the flop, + // while qs is the current flop value exposed to software. + output logic [DW-1:0] ds, + output logic [DW-1:0] qs +); + + logic wr_en; + logic [DW-1:0] wr_data; + + abr_prim_subreg_arb #( + .DW ( DW ), + .SwAccess ( SwAccess ) + ) wr_en_data_arb ( + .we, + .wd, + .de, + .d, + .q, + .wr_en, + .wr_data + ); + + always_ff @(posedge clk_i or negedge rst_b) begin + if (!rst_b) begin + q <= RESVAL; + end else if (wr_en) begin + q <= wr_data; + end + end + + // feed back out for consolidation + assign ds = wr_en ? wr_data : qs; + assign qe = wr_en; + assign qs = q; + +endmodule diff --git a/designs/Caliptra/src/adams-bridge/abr_prim_subreg_arb.sv b/designs/Caliptra/src/adams-bridge/abr_prim_subreg_arb.sv new file mode 100644 index 0000000..5f0cac3 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/abr_prim_subreg_arb.sv @@ -0,0 +1,81 @@ +// Copyright lowRISC contributors. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Write enable and data arbitration logic for register slice conforming to Comportibility guide. + +module abr_prim_subreg_arb + import abr_prim_subreg_pkg::*; +#( + parameter int DW = 32, + parameter sw_access_e SwAccess = SwAccessRW +) ( + // From SW: valid for RW, WO, W1C, W1S, W0C, RC. + // In case of RC, top connects read pulse to we. + input we, + input [DW-1:0] wd, + + // From HW: valid for HRW, HWO. + input de, + input [DW-1:0] d, + + // From register: actual reg value. + input [DW-1:0] q, + + // To register: actual write enable and write data. + output logic wr_en, + output logic [DW-1:0] wr_data +); + + if (SwAccess inside {SwAccessRW, SwAccessWO}) begin : gen_w + assign wr_en = we | de; + assign wr_data = (we == 1'b1) ? wd : d; // SW higher priority + // Unused q - Prevent lint errors. + logic [DW-1:0] unused_q; + assign unused_q = q; + end else if (SwAccess == SwAccessRO) begin : gen_ro + assign wr_en = de; + assign wr_data = d; + // Unused we, wd, q - Prevent lint errors. + logic unused_we; + logic [DW-1:0] unused_wd; + logic [DW-1:0] unused_q; + assign unused_we = we; + assign unused_wd = wd; + assign unused_q = q; + end else if (SwAccess == SwAccessW1S) begin : gen_w1s + // If SwAccess is W1S, then assume hw tries to clear. + // So, give a chance HW to clear when SW tries to set. + // If both try to set/clr at the same bit pos, SW wins. + assign wr_en = we | de; + assign wr_data = (de ? d : q) | (we ? wd : '0); + end else if (SwAccess == SwAccessW1C) begin : gen_w1c + // If SwAccess is W1C, then assume hw tries to set. + // So, give a chance HW to set when SW tries to clear. + // If both try to set/clr at the same bit pos, SW wins. + assign wr_en = we | de; + assign wr_data = (de ? d : q) & (we ? ~wd : '1); + end else if (SwAccess == SwAccessW0C) begin : gen_w0c + assign wr_en = we | de; + assign wr_data = (de ? d : q) & (we ? wd : '1); + end else if (SwAccess == SwAccessRC) begin : gen_rc + // This swtype is not recommended but exists for compatibility. + // WARN: we signal is actually read signal not write enable. + assign wr_en = we | de; + assign wr_data = (de ? d : q) & (we ? '0 : '1); + // Unused wd - Prevent lint errors. + logic [DW-1:0] unused_wd; + assign unused_wd = wd; + end else begin : gen_hw + assign wr_en = de; + assign wr_data = d; + // Unused we, wd, q - Prevent lint errors. + logic unused_we; + logic [DW-1:0] unused_wd; + logic [DW-1:0] unused_q; + assign unused_we = we; + assign unused_wd = wd; + assign unused_q = q; + end + +endmodule diff --git a/designs/Caliptra/src/adams-bridge/abr_prim_subreg_ext.sv b/designs/Caliptra/src/adams-bridge/abr_prim_subreg_ext.sv new file mode 100644 index 0000000..dd40a44 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/abr_prim_subreg_ext.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 +// +// Register slice conforming to Comportibility guide. + +module abr_prim_subreg_ext #( + parameter int unsigned DW = 32 +) ( + input re, + input we, + input [DW-1:0] wd, + + input [DW-1:0] d, + + // output to HW and Reg Read + output logic qe, + output logic qre, + output logic [DW-1:0] q, + output logic [DW-1:0] ds, + output logic [DW-1:0] qs +); + + // for external registers, there is no difference + // between qs and ds + assign ds = d; + assign qs = d; + assign q = wd; + assign qe = we; + assign qre = re; + +endmodule diff --git a/designs/Caliptra/src/adams-bridge/abr_prim_subreg_pkg.sv b/designs/Caliptra/src/adams-bridge/abr_prim_subreg_pkg.sv new file mode 100644 index 0000000..c42a07b --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/abr_prim_subreg_pkg.sv @@ -0,0 +1,17 @@ +// Copyright lowRISC contributors. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +package abr_prim_subreg_pkg; + + // Register access specifier + typedef enum logic [2:0] { + SwAccessRW = 3'd0, // Read-write + SwAccessRO = 3'd1, // Read-only + SwAccessWO = 3'd2, // Write-only + SwAccessW1C = 3'd3, // Write 1 to clear + SwAccessW1S = 3'd4, // Write 1 to set + SwAccessW0C = 3'd5, // Write 0 to clear + SwAccessRC = 3'd6 // Read to clear. Do not use, only exists for compatibility. + } sw_access_e; +endpackage diff --git a/designs/Caliptra/src/adams-bridge/abr_prim_sum_tree.sv b/designs/Caliptra/src/adams-bridge/abr_prim_sum_tree.sv new file mode 100644 index 0000000..f4c5225 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/abr_prim_sum_tree.sv @@ -0,0 +1,124 @@ +// Copyright lowRISC contributors. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Based on abr_prim_max_tree, this module implements an explicit binary tree to find the +// sum of this inputs. The solution has O(N) area and O(log(N)) delay complexity, and +// thus scales well with many input sources. +// +// Note that only input values marked as "valid" are respected in the maximum computation. +// Invalid values are treated as 0. +// + +`include "abr_prim_assert.sv" + +module abr_prim_sum_tree #( + parameter int NumSrc = 32, + parameter int Width = 8 +) ( + // The module is combinational - the clock and reset are only used for assertions. + input clk_i, + input rst_b, + input [NumSrc-1:0][Width-1:0] values_i, // Input values + input [NumSrc-1:0] valid_i, // Input valid bits + output logic [Width-1:0] sum_value_o, // Summation result + output logic sum_valid_o // Whether any of the inputs is valid +); + + /////////////////////// + // Binary tree logic // + /////////////////////// + + // This only works with 2 or more sources. + `ABR_ASSERT_INIT(NumSources_A, NumSrc >= 2) + + // Align to powers of 2 for simplicity. + // A full binary tree with N levels has 2**N + 2**N-1 nodes. + localparam int NumLevels = $clog2(NumSrc); + logic [2**(NumLevels+1)-2:0] vld_tree; + logic [2**(NumLevels+1)-2:0][Width-1:0] sum_tree; + + for (genvar level = 0; level < NumLevels+1; level++) begin : gen_tree + // + // level+1 C0 C1 <- "Base1" points to the first node on "level+1", + // \ / these nodes are the children of the nodes one level below + // level Pa <- "Base0", points to the first node on "level", + // these nodes are the parents of the nodes one level above + // + // hence we have the following indices for the paPa, C0, C1 nodes: + // Pa = 2**level - 1 + offset = Base0 + offset + // C0 = 2**(level+1) - 1 + 2*offset = Base1 + 2*offset + // C1 = 2**(level+1) - 1 + 2*offset + 1 = Base1 + 2*offset + 1 + // + localparam int Base0 = (2**level)-1; + localparam int Base1 = (2**(level+1))-1; + + for (genvar offset = 0; offset < 2**level; offset++) begin : gen_level + localparam int Pa = Base0 + offset; + localparam int C0 = Base1 + 2*offset; + localparam int C1 = Base1 + 2*offset + 1; + + // This assigns the input values, their corresponding IDs and valid signals to the tree leafs. + if (level == NumLevels) begin : gen_leafs + if (offset < NumSrc) begin : gen_assign + assign vld_tree[Pa] = valid_i[offset]; + assign sum_tree[Pa] = values_i[offset]; + end else begin : gen_tie_off + assign vld_tree[Pa] = '0; + assign sum_tree[Pa] = '0; + end + // This creates the node assignments. + end else begin : gen_nodes + logic [Width-1:0] node_sum; // Local helper variable + // In case only one of the parents is valid, forward that one + // In case both parents are valid, forward the one with higher value + assign node_sum = (vld_tree[C0] & vld_tree[C1]) ? sum_tree[C1] + sum_tree[C0] : + (vld_tree[C0]) ? sum_tree[C0] : + (vld_tree[C1]) ? sum_tree[C1] : + {Width'(0)}; + + // Forwarding muxes + // Note: these ternaries have triggered a synthesis bug in Vivado versions older + // than 2020.2. If the problem resurfaces again, have a look at issue #1408. + assign vld_tree[Pa] = vld_tree[C1] | vld_tree[C0]; + assign sum_tree[Pa] = node_sum; + end + end : gen_level + end : gen_tree + + + // The results can be found at the tree root + assign sum_valid_o = vld_tree[0]; + assign sum_value_o = sum_tree[0]; + + //////////////// + // Assertions // + //////////////// + +`ifdef ABR_INC_ASSERT + //VCS coverage off + // pragma coverage off + + // Helper functions for assertions below. + function automatic logic [Width-1:0] sum_value (input logic [NumSrc-1:0][Width-1:0] values_i, + input logic [NumSrc-1:0] valid_i); + logic [Width-1:0] sum = '0; + for (int k = 0; k < NumSrc; k++) begin + if (valid_i[k]) begin + sum += values_i[k]; + end + end + return sum; + endfunction : sum_value + + logic [Width-1:0] sum_value_exp; + assign sum_value_exp = sum_value(values_i, valid_i); + //VCS coverage on + // pragma coverage on + + `ABR_ASSERT(ValidInImpliesValidOut_A, |valid_i === sum_valid_o) + `ABR_ASSERT(SumComputation_A, sum_valid_o |-> sum_value_o == sum_value_exp) + `ABR_ASSERT(SumComputationInvalid_A, !sum_valid_o |-> sum_value_o == '0) +`endif + +endmodule : abr_prim_sum_tree diff --git a/designs/Caliptra/src/adams-bridge/abr_prim_util_pkg.sv b/designs/Caliptra/src/adams-bridge/abr_prim_util_pkg.sv new file mode 100644 index 0000000..e09c4b1 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/abr_prim_util_pkg.sv @@ -0,0 +1,56 @@ +// Copyright lowRISC contributors. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + + +/** + * Utility functions + */ +package abr_prim_util_pkg; + /** + * Math function: Number of bits needed to address |value| items. + * + * 0 for value == 0 + * vbits = 1 for value == 1 + * ceil(log2(value)) for value > 1 + * + * + * The primary use case for this function is the definition of registers/arrays + * which are wide enough to contain |value| items. + * + * This function identical to $clog2() for all input values except the value 1; + * it could be considered an "enhanced" $clog2() function. + * + * + * Example 1: + * parameter Items = 1; + * localparam ItemsWidth = vbits(Items); // 1 + * logic [ItemsWidth-1:0] item_register; // items_register is now [0:0] + * + * Example 2: + * parameter Items = 64; + * localparam ItemsWidth = vbits(Items); // 6 + * logic [ItemsWidth-1:0] item_register; // items_register is now [5:0] + * + * Note: If you want to store the number "value" inside a register, you need + * a register with size vbits(value + 1), since you also need to store + * the number 0. + * + * Example 3: + * logic [vbits(64)-1:0] store_64_logic_values; // width is [5:0] + * logic [vbits(64 + 1)-1:0] store_number_64; // width is [6:0] + */ + function automatic integer vbits(integer value); + return (value == 1) ? 1 : $clog2(value); + endfunction + +`ifdef ABR_INC_ASSERT + // Package-scoped variable to detect the end of simulation. + // + // Used only in DV simulations. The bit will be used by assertions in RTL to perform end-of-test + // cleanup. It is set to 1 in `dv_test_status_pkg::dv_test_status()`, which is invoked right + // before the simulation is terminated, to signal the status of the test. + bit end_of_simulation; +`endif + +endpackage diff --git a/designs/Caliptra/src/adams-bridge/abr_ram_regout.sv b/designs/Caliptra/src/adams-bridge/abr_ram_regout.sv new file mode 100644 index 0000000..0679c53 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/abr_ram_regout.sv @@ -0,0 +1,61 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. + +module abr_ram_regout #( + parameter DEPTH = 64 + ,parameter DATA_WIDTH = 32 + ,parameter NUM_RD_PORTS = 1 + ,parameter NUM_WR_PORTS = 1 + ,parameter ADDR_WIDTH = $clog2(DEPTH) + + ) + ( + input logic clk_i, + input logic zeroize_i, + input logic [NUM_WR_PORTS-1:0] we_i, + input logic [NUM_WR_PORTS-1:0][ADDR_WIDTH-1:0] waddr_i, + input logic [NUM_WR_PORTS-1:0][DATA_WIDTH-1:0] wdata_i, + input logic [NUM_RD_PORTS-1:0] re_i, + input logic [NUM_RD_PORTS-1:0][ADDR_WIDTH-1:0] raddr_i, + output logic [NUM_RD_PORTS-1:0][DATA_WIDTH-1:0] rdata_o, + output logic [DEPTH-1:0][DATA_WIDTH-1:0] reg_o + ); + + //storage element + logic [DEPTH-1:0][DATA_WIDTH-1:0] ram; + + always @(posedge clk_i) begin + if (zeroize_i) begin + ram <= '0; + end + else begin + for (int port = 0; port < NUM_WR_PORTS; port++) begin + if (we_i[port]) begin + ram[waddr_i[port]] <= wdata_i[port]; + end + end + end + end + + always @(posedge clk_i) begin + for (int port = 0; port < NUM_RD_PORTS; port++) begin + if (re_i[port]) begin + rdata_o[port] <= ram[raddr_i[port]]; + end + end + end + + assign reg_o = ram; + +endmodule diff --git a/designs/Caliptra/src/adams-bridge/abr_reg.sv b/designs/Caliptra/src/adams-bridge/abr_reg.sv new file mode 100644 index 0000000..186bfb0 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/abr_reg.sv @@ -0,0 +1,2564 @@ +// Generated by PeakRDL-regblock - A free and open-source SystemVerilog generator +// https://github.com/SystemRDL/PeakRDL-regblock + +module abr_reg ( + input wire clk, + input wire rst, + + input wire s_cpuif_req, + input wire s_cpuif_req_is_wr, + input wire [15:0] s_cpuif_addr, + input wire [31:0] s_cpuif_wr_data, + input wire [31:0] s_cpuif_wr_biten, + output wire s_cpuif_req_stall_wr, + output wire s_cpuif_req_stall_rd, + output wire s_cpuif_rd_ack, + output wire s_cpuif_rd_err, + output wire [31:0] s_cpuif_rd_data, + output wire s_cpuif_wr_ack, + output wire s_cpuif_wr_err, + + input abr_reg_pkg::abr_reg__in_t hwif_in, + output abr_reg_pkg::abr_reg__out_t hwif_out + ); + + //-------------------------------------------------------------------------- + // CPU Bus interface logic + //-------------------------------------------------------------------------- + logic cpuif_req; + logic cpuif_req_is_wr; + logic [15:0] cpuif_addr; + logic [31:0] cpuif_wr_data; + logic [31:0] cpuif_wr_biten; + logic cpuif_req_stall_wr; + logic cpuif_req_stall_rd; + + logic cpuif_rd_ack; + logic cpuif_rd_err; + logic [31:0] cpuif_rd_data; + + logic cpuif_wr_ack; + logic cpuif_wr_err; + + assign cpuif_req = s_cpuif_req; + assign cpuif_req_is_wr = s_cpuif_req_is_wr; + assign cpuif_addr = s_cpuif_addr; + assign cpuif_wr_data = s_cpuif_wr_data; + assign cpuif_wr_biten = s_cpuif_wr_biten; + assign s_cpuif_req_stall_wr = cpuif_req_stall_wr; + assign s_cpuif_req_stall_rd = cpuif_req_stall_rd; + assign s_cpuif_rd_ack = cpuif_rd_ack; + assign s_cpuif_rd_err = cpuif_rd_err; + assign s_cpuif_rd_data = cpuif_rd_data; + assign s_cpuif_wr_ack = cpuif_wr_ack; + assign s_cpuif_wr_err = cpuif_wr_err; + + logic cpuif_req_masked; + logic external_req; + logic external_pending; + logic external_wr_ack; + logic external_rd_ack; + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + external_pending <= '0; + end else begin + if(external_req & ~external_wr_ack & ~external_rd_ack) external_pending <= '1; + else if(external_wr_ack | external_rd_ack) external_pending <= '0; + assert(!external_wr_ack || (external_pending | external_req)) + else $error("An external wr_ack strobe was asserted when no external request was active"); + assert(!external_rd_ack || (external_pending | external_req)) + else $error("An external rd_ack strobe was asserted when no external request was active"); + end + end + + // Read & write latencies are balanced. Stalls not required + // except if external + assign cpuif_req_stall_rd = external_pending; + assign cpuif_req_stall_wr = external_pending; + assign cpuif_req_masked = cpuif_req + & !(!cpuif_req_is_wr & cpuif_req_stall_rd) + & !(cpuif_req_is_wr & cpuif_req_stall_wr); + + //-------------------------------------------------------------------------- + // Address Decode + //-------------------------------------------------------------------------- + typedef struct packed{ + logic [2-1:0]MLDSA_NAME; + logic [2-1:0]MLDSA_VERSION; + logic MLDSA_CTRL; + logic MLDSA_STATUS; + logic [16-1:0]ABR_ENTROPY; + logic [8-1:0]MLDSA_SEED; + logic [8-1:0]MLDSA_SIGN_RND; + logic [16-1:0]MLDSA_MSG; + logic [16-1:0]MLDSA_VERIFY_RES; + logic [16-1:0]MLDSA_EXTERNAL_MU; + logic MLDSA_MSG_STROBE; + logic MLDSA_CTX_CONFIG; + logic [64-1:0]MLDSA_CTX; + logic MLDSA_PUBKEY; + logic MLDSA_SIGNATURE; + logic MLDSA_PRIVKEY_OUT; + logic MLDSA_PRIVKEY_IN; + logic kv_mldsa_seed_rd_ctrl; + logic kv_mldsa_seed_rd_status; + struct packed{ + logic global_intr_en_r; + logic error_intr_en_r; + logic notif_intr_en_r; + logic error_global_intr_r; + logic notif_global_intr_r; + logic error_internal_intr_r; + logic notif_internal_intr_r; + logic error_intr_trig_r; + logic notif_intr_trig_r; + logic error_internal_intr_count_r; + logic notif_cmd_done_intr_count_r; + logic error_internal_intr_count_incr_r; + logic notif_cmd_done_intr_count_incr_r; + } intr_block_rf; + logic [2-1:0]MLKEM_NAME; + logic [2-1:0]MLKEM_VERSION; + logic MLKEM_CTRL; + logic MLKEM_STATUS; + logic [8-1:0]MLKEM_SEED_D; + logic [8-1:0]MLKEM_SEED_Z; + logic [8-1:0]MLKEM_SHARED_KEY; + logic MLKEM_MSG; + logic MLKEM_DECAPS_KEY; + logic MLKEM_ENCAPS_KEY; + logic MLKEM_CIPHERTEXT; + logic kv_mlkem_seed_rd_ctrl; + logic kv_mlkem_seed_rd_status; + logic kv_mlkem_msg_rd_ctrl; + logic kv_mlkem_msg_rd_status; + logic kv_mlkem_sharedkey_wr_ctrl; + logic kv_mlkem_sharedkey_wr_status; + } decoded_reg_strb_t; + decoded_reg_strb_t decoded_reg_strb; + logic decoded_strb_is_external; + + logic [15:0] decoded_addr; + + logic decoded_req; + logic decoded_req_is_wr; + logic [31:0] decoded_wr_data; + logic [31:0] decoded_wr_biten; + + always_comb begin + automatic logic is_external; + is_external = '0; + for(int i0=0; i0<2; i0++) begin + decoded_reg_strb.MLDSA_NAME[i0] = cpuif_req_masked & (cpuif_addr == 16'h0 + i0*16'h4); + end + for(int i0=0; i0<2; i0++) begin + decoded_reg_strb.MLDSA_VERSION[i0] = cpuif_req_masked & (cpuif_addr == 16'h8 + i0*16'h4); + end + decoded_reg_strb.MLDSA_CTRL = cpuif_req_masked & (cpuif_addr == 16'h10); + decoded_reg_strb.MLDSA_STATUS = cpuif_req_masked & (cpuif_addr == 16'h14); + for(int i0=0; i0<16; i0++) begin + decoded_reg_strb.ABR_ENTROPY[i0] = cpuif_req_masked & (cpuif_addr == 16'h18 + i0*16'h4); + end + for(int i0=0; i0<8; i0++) begin + decoded_reg_strb.MLDSA_SEED[i0] = cpuif_req_masked & (cpuif_addr == 16'h58 + i0*16'h4); + end + for(int i0=0; i0<8; i0++) begin + decoded_reg_strb.MLDSA_SIGN_RND[i0] = cpuif_req_masked & (cpuif_addr == 16'h78 + i0*16'h4); + end + for(int i0=0; i0<16; i0++) begin + decoded_reg_strb.MLDSA_MSG[i0] = cpuif_req_masked & (cpuif_addr == 16'h98 + i0*16'h4); + end + for(int i0=0; i0<16; i0++) begin + decoded_reg_strb.MLDSA_VERIFY_RES[i0] = cpuif_req_masked & (cpuif_addr == 16'hd8 + i0*16'h4); + end + for(int i0=0; i0<16; i0++) begin + decoded_reg_strb.MLDSA_EXTERNAL_MU[i0] = cpuif_req_masked & (cpuif_addr == 16'h118 + i0*16'h4); + end + decoded_reg_strb.MLDSA_MSG_STROBE = cpuif_req_masked & (cpuif_addr == 16'h158); + decoded_reg_strb.MLDSA_CTX_CONFIG = cpuif_req_masked & (cpuif_addr == 16'h15c); + for(int i0=0; i0<64; i0++) begin + decoded_reg_strb.MLDSA_CTX[i0] = cpuif_req_masked & (cpuif_addr == 16'h160 + i0*16'h4); + end + decoded_reg_strb.MLDSA_PUBKEY = cpuif_req_masked & (cpuif_addr >= 16'h1000) & (cpuif_addr <= 16'h1000 + 16'ha1f); + is_external |= cpuif_req_masked & (cpuif_addr >= 16'h1000) & (cpuif_addr <= 16'h1000 + 16'ha1f); + decoded_reg_strb.MLDSA_SIGNATURE = cpuif_req_masked & (cpuif_addr >= 16'h2000) & (cpuif_addr <= 16'h2000 + 16'h1213); + is_external |= cpuif_req_masked & (cpuif_addr >= 16'h2000) & (cpuif_addr <= 16'h2000 + 16'h1213); + decoded_reg_strb.MLDSA_PRIVKEY_OUT = cpuif_req_masked & (cpuif_addr >= 16'h4000) & (cpuif_addr <= 16'h4000 + 16'h131f); + is_external |= cpuif_req_masked & (cpuif_addr >= 16'h4000) & (cpuif_addr <= 16'h4000 + 16'h131f); + decoded_reg_strb.MLDSA_PRIVKEY_IN = cpuif_req_masked & (cpuif_addr >= 16'h6000) & (cpuif_addr <= 16'h6000 + 16'h131f); + is_external |= cpuif_req_masked & (cpuif_addr >= 16'h6000) & (cpuif_addr <= 16'h6000 + 16'h131f); + decoded_reg_strb.kv_mldsa_seed_rd_ctrl = cpuif_req_masked & (cpuif_addr == 16'h8000); + decoded_reg_strb.kv_mldsa_seed_rd_status = cpuif_req_masked & (cpuif_addr == 16'h8004); + decoded_reg_strb.intr_block_rf.global_intr_en_r = cpuif_req_masked & (cpuif_addr == 16'h8100); + decoded_reg_strb.intr_block_rf.error_intr_en_r = cpuif_req_masked & (cpuif_addr == 16'h8104); + decoded_reg_strb.intr_block_rf.notif_intr_en_r = cpuif_req_masked & (cpuif_addr == 16'h8108); + decoded_reg_strb.intr_block_rf.error_global_intr_r = cpuif_req_masked & (cpuif_addr == 16'h810c); + decoded_reg_strb.intr_block_rf.notif_global_intr_r = cpuif_req_masked & (cpuif_addr == 16'h8110); + decoded_reg_strb.intr_block_rf.error_internal_intr_r = cpuif_req_masked & (cpuif_addr == 16'h8114); + decoded_reg_strb.intr_block_rf.notif_internal_intr_r = cpuif_req_masked & (cpuif_addr == 16'h8118); + decoded_reg_strb.intr_block_rf.error_intr_trig_r = cpuif_req_masked & (cpuif_addr == 16'h811c); + decoded_reg_strb.intr_block_rf.notif_intr_trig_r = cpuif_req_masked & (cpuif_addr == 16'h8120); + decoded_reg_strb.intr_block_rf.error_internal_intr_count_r = cpuif_req_masked & (cpuif_addr == 16'h8200); + decoded_reg_strb.intr_block_rf.notif_cmd_done_intr_count_r = cpuif_req_masked & (cpuif_addr == 16'h8280); + decoded_reg_strb.intr_block_rf.error_internal_intr_count_incr_r = cpuif_req_masked & (cpuif_addr == 16'h8300); + decoded_reg_strb.intr_block_rf.notif_cmd_done_intr_count_incr_r = cpuif_req_masked & (cpuif_addr == 16'h8304); + for(int i0=0; i0<2; i0++) begin + decoded_reg_strb.MLKEM_NAME[i0] = cpuif_req_masked & (cpuif_addr == 16'h9000 + i0*16'h4); + end + for(int i0=0; i0<2; i0++) begin + decoded_reg_strb.MLKEM_VERSION[i0] = cpuif_req_masked & (cpuif_addr == 16'h9008 + i0*16'h4); + end + decoded_reg_strb.MLKEM_CTRL = cpuif_req_masked & (cpuif_addr == 16'h9010); + decoded_reg_strb.MLKEM_STATUS = cpuif_req_masked & (cpuif_addr == 16'h9014); + for(int i0=0; i0<8; i0++) begin + decoded_reg_strb.MLKEM_SEED_D[i0] = cpuif_req_masked & (cpuif_addr == 16'h9018 + i0*16'h4); + end + for(int i0=0; i0<8; i0++) begin + decoded_reg_strb.MLKEM_SEED_Z[i0] = cpuif_req_masked & (cpuif_addr == 16'h9038 + i0*16'h4); + is_external |= cpuif_req_masked & (cpuif_addr == 16'h9038 + i0*16'h4) & cpuif_req_is_wr; + end + for(int i0=0; i0<8; i0++) begin + decoded_reg_strb.MLKEM_SHARED_KEY[i0] = cpuif_req_masked & (cpuif_addr == 16'h9058 + i0*16'h4); + is_external |= cpuif_req_masked & (cpuif_addr == 16'h9058 + i0*16'h4) & !cpuif_req_is_wr; + end + decoded_reg_strb.MLKEM_MSG = cpuif_req_masked & (cpuif_addr >= 16'h9080) & (cpuif_addr <= 16'h9080 + 16'h1f); + is_external |= cpuif_req_masked & (cpuif_addr >= 16'h9080) & (cpuif_addr <= 16'h9080 + 16'h1f); + decoded_reg_strb.MLKEM_DECAPS_KEY = cpuif_req_masked & (cpuif_addr >= 16'ha000) & (cpuif_addr <= 16'ha000 + 16'hc5f); + is_external |= cpuif_req_masked & (cpuif_addr >= 16'ha000) & (cpuif_addr <= 16'ha000 + 16'hc5f); + decoded_reg_strb.MLKEM_ENCAPS_KEY = cpuif_req_masked & (cpuif_addr >= 16'hb000) & (cpuif_addr <= 16'hb000 + 16'h61f); + is_external |= cpuif_req_masked & (cpuif_addr >= 16'hb000) & (cpuif_addr <= 16'hb000 + 16'h61f); + decoded_reg_strb.MLKEM_CIPHERTEXT = cpuif_req_masked & (cpuif_addr >= 16'hb800) & (cpuif_addr <= 16'hb800 + 16'h61f); + is_external |= cpuif_req_masked & (cpuif_addr >= 16'hb800) & (cpuif_addr <= 16'hb800 + 16'h61f); + decoded_reg_strb.kv_mlkem_seed_rd_ctrl = cpuif_req_masked & (cpuif_addr == 16'hc000); + decoded_reg_strb.kv_mlkem_seed_rd_status = cpuif_req_masked & (cpuif_addr == 16'hc004); + decoded_reg_strb.kv_mlkem_msg_rd_ctrl = cpuif_req_masked & (cpuif_addr == 16'hc008); + decoded_reg_strb.kv_mlkem_msg_rd_status = cpuif_req_masked & (cpuif_addr == 16'hc00c); + decoded_reg_strb.kv_mlkem_sharedkey_wr_ctrl = cpuif_req_masked & (cpuif_addr == 16'hc010); + decoded_reg_strb.kv_mlkem_sharedkey_wr_status = cpuif_req_masked & (cpuif_addr == 16'hc014); + decoded_strb_is_external = is_external; + external_req = is_external; + end + + // Pass down signals to next stage + assign decoded_addr = cpuif_addr; + + assign decoded_req = cpuif_req_masked; + assign decoded_req_is_wr = cpuif_req_is_wr; + assign decoded_wr_data = cpuif_wr_data; + assign decoded_wr_biten = cpuif_wr_biten; + + //-------------------------------------------------------------------------- + // Field logic + //-------------------------------------------------------------------------- + typedef struct packed{ + struct packed{ + struct packed{ + logic [2:0] next; + logic load_next; + } CTRL; + struct packed{ + logic next; + logic load_next; + } ZEROIZE; + struct packed{ + logic next; + logic load_next; + } PCR_SIGN; + struct packed{ + logic next; + logic load_next; + } EXTERNAL_MU; + struct packed{ + logic next; + logic load_next; + } STREAM_MSG; + } MLDSA_CTRL; + struct packed{ + struct packed{ + logic next; + logic load_next; + } VALID; + struct packed{ + logic next; + logic load_next; + } ERROR; + } MLDSA_STATUS; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } ENTROPY; + } [16-1:0]ABR_ENTROPY; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } SEED; + } [8-1:0]MLDSA_SEED; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } SIGN_RND; + } [8-1:0]MLDSA_SIGN_RND; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } MSG; + } [16-1:0]MLDSA_MSG; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } VERIFY_RES; + } [16-1:0]MLDSA_VERIFY_RES; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } EXTERNAL_MU; + } [16-1:0]MLDSA_EXTERNAL_MU; + struct packed{ + struct packed{ + logic [3:0] next; + logic load_next; + } STROBE; + } MLDSA_MSG_STROBE; + struct packed{ + struct packed{ + logic [7:0] next; + logic load_next; + } CTX_SIZE; + } MLDSA_CTX_CONFIG; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } CTX; + } [64-1:0]MLDSA_CTX; + struct packed{ + struct packed{ + logic next; + logic load_next; + } read_en; + struct packed{ + logic [4:0] next; + logic load_next; + } read_entry; + struct packed{ + logic next; + logic load_next; + } pcr_hash_extend; + struct packed{ + logic [24:0] next; + logic load_next; + } rsvd; + } kv_mldsa_seed_rd_ctrl; + struct packed{ + struct packed{ + logic next; + logic load_next; + } VALID; + } kv_mldsa_seed_rd_status; + struct packed{ + struct packed{ + struct packed{ + logic next; + logic load_next; + } error_en; + struct packed{ + logic next; + logic load_next; + } notif_en; + } global_intr_en_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + } error_internal_en; + } error_intr_en_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + } notif_cmd_done_en; + } notif_intr_en_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + } agg_sts; + } error_global_intr_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + } agg_sts; + } notif_global_intr_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + } error_internal_sts; + } error_internal_intr_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + } notif_cmd_done_sts; + } notif_internal_intr_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + } error_internal_trig; + } error_intr_trig_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + } notif_cmd_done_trig; + } notif_intr_trig_r; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + logic incrthreshold; + logic incrsaturate; + } cnt; + } error_internal_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + logic incrthreshold; + logic incrsaturate; + } cnt; + } notif_cmd_done_intr_count_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + logic decrthreshold; + logic underflow; + } pulse; + } error_internal_intr_count_incr_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + logic decrthreshold; + logic underflow; + } pulse; + } notif_cmd_done_intr_count_incr_r; + } intr_block_rf; + struct packed{ + struct packed{ + logic [2:0] next; + logic load_next; + } CTRL; + struct packed{ + logic next; + logic load_next; + } ZEROIZE; + } MLKEM_CTRL; + struct packed{ + struct packed{ + logic next; + logic load_next; + } VALID; + struct packed{ + logic next; + logic load_next; + } ERROR; + } MLKEM_STATUS; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } SEED; + } [8-1:0]MLKEM_SEED_D; + struct packed{ + struct packed{ + logic next; + logic load_next; + } read_en; + struct packed{ + logic [4:0] next; + logic load_next; + } read_entry; + struct packed{ + logic next; + logic load_next; + } pcr_hash_extend; + struct packed{ + logic [24:0] next; + logic load_next; + } rsvd; + } kv_mlkem_seed_rd_ctrl; + struct packed{ + struct packed{ + logic next; + logic load_next; + } VALID; + } kv_mlkem_seed_rd_status; + struct packed{ + struct packed{ + logic next; + logic load_next; + } read_en; + struct packed{ + logic [4:0] next; + logic load_next; + } read_entry; + struct packed{ + logic next; + logic load_next; + } pcr_hash_extend; + struct packed{ + logic [24:0] next; + logic load_next; + } rsvd; + } kv_mlkem_msg_rd_ctrl; + struct packed{ + struct packed{ + logic next; + logic load_next; + } VALID; + } kv_mlkem_msg_rd_status; + struct packed{ + struct packed{ + logic next; + logic load_next; + } write_en; + struct packed{ + logic [4:0] next; + logic load_next; + } write_entry; + struct packed{ + logic next; + logic load_next; + } hmac_key_dest_valid; + struct packed{ + logic next; + logic load_next; + } hmac_block_dest_valid; + struct packed{ + logic next; + logic load_next; + } mldsa_seed_dest_valid; + struct packed{ + logic next; + logic load_next; + } ecc_pkey_dest_valid; + struct packed{ + logic next; + logic load_next; + } ecc_seed_dest_valid; + struct packed{ + logic next; + logic load_next; + } aes_key_dest_valid; + struct packed{ + logic next; + logic load_next; + } mlkem_seed_dest_valid; + struct packed{ + logic next; + logic load_next; + } mlkem_msg_dest_valid; + struct packed{ + logic next; + logic load_next; + } dma_data_dest_valid; + struct packed{ + logic [16:0] next; + logic load_next; + } rsvd; + } kv_mlkem_sharedkey_wr_ctrl; + struct packed{ + struct packed{ + logic next; + logic load_next; + } VALID; + } kv_mlkem_sharedkey_wr_status; + } field_combo_t; + field_combo_t field_combo; + + typedef struct packed{ + struct packed{ + struct packed{ + logic [2:0] value; + } CTRL; + struct packed{ + logic value; + } ZEROIZE; + struct packed{ + logic value; + } PCR_SIGN; + struct packed{ + logic value; + } EXTERNAL_MU; + struct packed{ + logic value; + } STREAM_MSG; + } MLDSA_CTRL; + struct packed{ + struct packed{ + logic value; + } VALID; + struct packed{ + logic value; + } ERROR; + } MLDSA_STATUS; + struct packed{ + struct packed{ + logic [31:0] value; + } ENTROPY; + } [16-1:0]ABR_ENTROPY; + struct packed{ + struct packed{ + logic [31:0] value; + } SEED; + } [8-1:0]MLDSA_SEED; + struct packed{ + struct packed{ + logic [31:0] value; + } SIGN_RND; + } [8-1:0]MLDSA_SIGN_RND; + struct packed{ + struct packed{ + logic [31:0] value; + } MSG; + } [16-1:0]MLDSA_MSG; + struct packed{ + struct packed{ + logic [31:0] value; + } VERIFY_RES; + } [16-1:0]MLDSA_VERIFY_RES; + struct packed{ + struct packed{ + logic [31:0] value; + } EXTERNAL_MU; + } [16-1:0]MLDSA_EXTERNAL_MU; + struct packed{ + struct packed{ + logic [3:0] value; + } STROBE; + } MLDSA_MSG_STROBE; + struct packed{ + struct packed{ + logic [7:0] value; + } CTX_SIZE; + } MLDSA_CTX_CONFIG; + struct packed{ + struct packed{ + logic [31:0] value; + } CTX; + } [64-1:0]MLDSA_CTX; + struct packed{ + struct packed{ + logic value; + } read_en; + struct packed{ + logic [4:0] value; + } read_entry; + struct packed{ + logic value; + } pcr_hash_extend; + struct packed{ + logic [24:0] value; + } rsvd; + } kv_mldsa_seed_rd_ctrl; + struct packed{ + struct packed{ + logic value; + } VALID; + } kv_mldsa_seed_rd_status; + struct packed{ + struct packed{ + struct packed{ + logic value; + } error_en; + struct packed{ + logic value; + } notif_en; + } global_intr_en_r; + struct packed{ + struct packed{ + logic value; + } error_internal_en; + } error_intr_en_r; + struct packed{ + struct packed{ + logic value; + } notif_cmd_done_en; + } notif_intr_en_r; + struct packed{ + struct packed{ + logic value; + } agg_sts; + } error_global_intr_r; + struct packed{ + struct packed{ + logic value; + } agg_sts; + } notif_global_intr_r; + struct packed{ + struct packed{ + logic value; + } error_internal_sts; + } error_internal_intr_r; + struct packed{ + struct packed{ + logic value; + } notif_cmd_done_sts; + } notif_internal_intr_r; + struct packed{ + struct packed{ + logic value; + } error_internal_trig; + } error_intr_trig_r; + struct packed{ + struct packed{ + logic value; + } notif_cmd_done_trig; + } notif_intr_trig_r; + struct packed{ + struct packed{ + logic [31:0] value; + } cnt; + } error_internal_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] value; + } cnt; + } notif_cmd_done_intr_count_r; + struct packed{ + struct packed{ + logic value; + } pulse; + } error_internal_intr_count_incr_r; + struct packed{ + struct packed{ + logic value; + } pulse; + } notif_cmd_done_intr_count_incr_r; + } intr_block_rf; + struct packed{ + struct packed{ + logic [2:0] value; + } CTRL; + struct packed{ + logic value; + } ZEROIZE; + } MLKEM_CTRL; + struct packed{ + struct packed{ + logic value; + } VALID; + struct packed{ + logic value; + } ERROR; + } MLKEM_STATUS; + struct packed{ + struct packed{ + logic [31:0] value; + } SEED; + } [8-1:0]MLKEM_SEED_D; + struct packed{ + struct packed{ + logic value; + } read_en; + struct packed{ + logic [4:0] value; + } read_entry; + struct packed{ + logic value; + } pcr_hash_extend; + struct packed{ + logic [24:0] value; + } rsvd; + } kv_mlkem_seed_rd_ctrl; + struct packed{ + struct packed{ + logic value; + } VALID; + } kv_mlkem_seed_rd_status; + struct packed{ + struct packed{ + logic value; + } read_en; + struct packed{ + logic [4:0] value; + } read_entry; + struct packed{ + logic value; + } pcr_hash_extend; + struct packed{ + logic [24:0] value; + } rsvd; + } kv_mlkem_msg_rd_ctrl; + struct packed{ + struct packed{ + logic value; + } VALID; + } kv_mlkem_msg_rd_status; + struct packed{ + struct packed{ + logic value; + } write_en; + struct packed{ + logic [4:0] value; + } write_entry; + struct packed{ + logic value; + } hmac_key_dest_valid; + struct packed{ + logic value; + } hmac_block_dest_valid; + struct packed{ + logic value; + } mldsa_seed_dest_valid; + struct packed{ + logic value; + } ecc_pkey_dest_valid; + struct packed{ + logic value; + } ecc_seed_dest_valid; + struct packed{ + logic value; + } aes_key_dest_valid; + struct packed{ + logic value; + } mlkem_seed_dest_valid; + struct packed{ + logic value; + } mlkem_msg_dest_valid; + struct packed{ + logic value; + } dma_data_dest_valid; + struct packed{ + logic [16:0] value; + } rsvd; + } kv_mlkem_sharedkey_wr_ctrl; + struct packed{ + struct packed{ + logic value; + } VALID; + } kv_mlkem_sharedkey_wr_status; + } field_storage_t; + field_storage_t field_storage; + + // Field: abr_reg.MLDSA_CTRL.CTRL + always_comb begin + automatic logic [2:0] next_c; + automatic logic load_next_c; + next_c = field_storage.MLDSA_CTRL.CTRL.value; + load_next_c = '0; + if(decoded_reg_strb.MLDSA_CTRL && decoded_req_is_wr && hwif_in.abr_ready) begin // SW write + next_c = (field_storage.MLDSA_CTRL.CTRL.value & ~decoded_wr_biten[2:0]) | (decoded_wr_data[2:0] & decoded_wr_biten[2:0]); + load_next_c = '1; + end else if(hwif_in.MLDSA_CTRL.CTRL.hwclr) begin // HW Clear + next_c = '0; + load_next_c = '1; + end + field_combo.MLDSA_CTRL.CTRL.next = next_c; + field_combo.MLDSA_CTRL.CTRL.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.MLDSA_CTRL.CTRL.value <= 3'h0; + end else if(field_combo.MLDSA_CTRL.CTRL.load_next) begin + field_storage.MLDSA_CTRL.CTRL.value <= field_combo.MLDSA_CTRL.CTRL.next; + end + end + assign hwif_out.MLDSA_CTRL.CTRL.value = field_storage.MLDSA_CTRL.CTRL.value; + // Field: abr_reg.MLDSA_CTRL.ZEROIZE + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.MLDSA_CTRL.ZEROIZE.value; + load_next_c = '0; + if(decoded_reg_strb.MLDSA_CTRL && decoded_req_is_wr) begin // SW write + next_c = (field_storage.MLDSA_CTRL.ZEROIZE.value & ~decoded_wr_biten[3:3]) | (decoded_wr_data[3:3] & decoded_wr_biten[3:3]); + load_next_c = '1; + end else begin // singlepulse clears back to 0 + next_c = '0; + load_next_c = '1; + end + field_combo.MLDSA_CTRL.ZEROIZE.next = next_c; + field_combo.MLDSA_CTRL.ZEROIZE.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.MLDSA_CTRL.ZEROIZE.value <= 1'h0; + end else if(field_combo.MLDSA_CTRL.ZEROIZE.load_next) begin + field_storage.MLDSA_CTRL.ZEROIZE.value <= field_combo.MLDSA_CTRL.ZEROIZE.next; + end + end + assign hwif_out.MLDSA_CTRL.ZEROIZE.value = field_storage.MLDSA_CTRL.ZEROIZE.value; + // Field: abr_reg.MLDSA_CTRL.PCR_SIGN + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.MLDSA_CTRL.PCR_SIGN.value; + load_next_c = '0; + if(decoded_reg_strb.MLDSA_CTRL && decoded_req_is_wr && hwif_in.abr_ready) begin // SW write + next_c = (field_storage.MLDSA_CTRL.PCR_SIGN.value & ~decoded_wr_biten[4:4]) | (decoded_wr_data[4:4] & decoded_wr_biten[4:4]); + load_next_c = '1; + end else if(hwif_in.MLDSA_CTRL.PCR_SIGN.hwclr) begin // HW Clear + next_c = '0; + load_next_c = '1; + end + field_combo.MLDSA_CTRL.PCR_SIGN.next = next_c; + field_combo.MLDSA_CTRL.PCR_SIGN.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.MLDSA_CTRL.PCR_SIGN.value <= 1'h0; + end else if(field_combo.MLDSA_CTRL.PCR_SIGN.load_next) begin + field_storage.MLDSA_CTRL.PCR_SIGN.value <= field_combo.MLDSA_CTRL.PCR_SIGN.next; + end + end + assign hwif_out.MLDSA_CTRL.PCR_SIGN.value = field_storage.MLDSA_CTRL.PCR_SIGN.value; + // Field: abr_reg.MLDSA_CTRL.EXTERNAL_MU + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.MLDSA_CTRL.EXTERNAL_MU.value; + load_next_c = '0; + if(decoded_reg_strb.MLDSA_CTRL && decoded_req_is_wr && hwif_in.abr_ready) begin // SW write + next_c = (field_storage.MLDSA_CTRL.EXTERNAL_MU.value & ~decoded_wr_biten[5:5]) | (decoded_wr_data[5:5] & decoded_wr_biten[5:5]); + load_next_c = '1; + end else if(hwif_in.MLDSA_CTRL.EXTERNAL_MU.hwclr) begin // HW Clear + next_c = '0; + load_next_c = '1; + end + field_combo.MLDSA_CTRL.EXTERNAL_MU.next = next_c; + field_combo.MLDSA_CTRL.EXTERNAL_MU.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.MLDSA_CTRL.EXTERNAL_MU.value <= 1'h0; + end else if(field_combo.MLDSA_CTRL.EXTERNAL_MU.load_next) begin + field_storage.MLDSA_CTRL.EXTERNAL_MU.value <= field_combo.MLDSA_CTRL.EXTERNAL_MU.next; + end + end + assign hwif_out.MLDSA_CTRL.EXTERNAL_MU.value = field_storage.MLDSA_CTRL.EXTERNAL_MU.value; + // Field: abr_reg.MLDSA_CTRL.STREAM_MSG + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.MLDSA_CTRL.STREAM_MSG.value; + load_next_c = '0; + if(decoded_reg_strb.MLDSA_CTRL && decoded_req_is_wr && hwif_in.abr_ready) begin // SW write + next_c = (field_storage.MLDSA_CTRL.STREAM_MSG.value & ~decoded_wr_biten[6:6]) | (decoded_wr_data[6:6] & decoded_wr_biten[6:6]); + load_next_c = '1; + end else if(hwif_in.MLDSA_CTRL.STREAM_MSG.hwclr) begin // HW Clear + next_c = '0; + load_next_c = '1; + end + field_combo.MLDSA_CTRL.STREAM_MSG.next = next_c; + field_combo.MLDSA_CTRL.STREAM_MSG.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.MLDSA_CTRL.STREAM_MSG.value <= 1'h0; + end else if(field_combo.MLDSA_CTRL.STREAM_MSG.load_next) begin + field_storage.MLDSA_CTRL.STREAM_MSG.value <= field_combo.MLDSA_CTRL.STREAM_MSG.next; + end + end + assign hwif_out.MLDSA_CTRL.STREAM_MSG.value = field_storage.MLDSA_CTRL.STREAM_MSG.value; + // Field: abr_reg.MLDSA_STATUS.VALID + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.MLDSA_STATUS.VALID.value; + load_next_c = '0; + + // HW Write + next_c = hwif_in.MLDSA_STATUS.VALID.next; + load_next_c = '1; + field_combo.MLDSA_STATUS.VALID.next = next_c; + field_combo.MLDSA_STATUS.VALID.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.MLDSA_STATUS.VALID.value <= 1'h0; + end else if(field_combo.MLDSA_STATUS.VALID.load_next) begin + field_storage.MLDSA_STATUS.VALID.value <= field_combo.MLDSA_STATUS.VALID.next; + end + end + assign hwif_out.MLDSA_STATUS.VALID.value = field_storage.MLDSA_STATUS.VALID.value; + // Field: abr_reg.MLDSA_STATUS.ERROR + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.MLDSA_STATUS.ERROR.value; + load_next_c = '0; + + // HW Write + next_c = hwif_in.MLDSA_STATUS.ERROR.next; + load_next_c = '1; + field_combo.MLDSA_STATUS.ERROR.next = next_c; + field_combo.MLDSA_STATUS.ERROR.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.MLDSA_STATUS.ERROR.value <= 1'h0; + end else if(field_combo.MLDSA_STATUS.ERROR.load_next) begin + field_storage.MLDSA_STATUS.ERROR.value <= field_combo.MLDSA_STATUS.ERROR.next; + end + end + assign hwif_out.MLDSA_STATUS.ERROR.value = field_storage.MLDSA_STATUS.ERROR.value; + for(genvar i0=0; i0<16; i0++) begin + // Field: abr_reg.ABR_ENTROPY[].ENTROPY + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.ABR_ENTROPY[i0].ENTROPY.value; + load_next_c = '0; + if(decoded_reg_strb.ABR_ENTROPY[i0] && decoded_req_is_wr && hwif_in.abr_ready) begin // SW write + next_c = (field_storage.ABR_ENTROPY[i0].ENTROPY.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end else if(hwif_in.ABR_ENTROPY[i0].ENTROPY.hwclr) begin // HW Clear + next_c = '0; + load_next_c = '1; + end + field_combo.ABR_ENTROPY[i0].ENTROPY.next = next_c; + field_combo.ABR_ENTROPY[i0].ENTROPY.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.ABR_ENTROPY[i0].ENTROPY.value <= 32'h0; + end else if(field_combo.ABR_ENTROPY[i0].ENTROPY.load_next) begin + field_storage.ABR_ENTROPY[i0].ENTROPY.value <= field_combo.ABR_ENTROPY[i0].ENTROPY.next; + end + end + assign hwif_out.ABR_ENTROPY[i0].ENTROPY.value = field_storage.ABR_ENTROPY[i0].ENTROPY.value; + end + for(genvar i0=0; i0<8; i0++) begin + // Field: abr_reg.MLDSA_SEED[].SEED + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.MLDSA_SEED[i0].SEED.value; + load_next_c = '0; + if(decoded_reg_strb.MLDSA_SEED[i0] && decoded_req_is_wr && hwif_in.MLDSA_SEED[i0].SEED.swwe) begin // SW write + next_c = (field_storage.MLDSA_SEED[i0].SEED.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end else if(hwif_in.MLDSA_SEED[i0].SEED.we) begin // HW Write - we + next_c = hwif_in.MLDSA_SEED[i0].SEED.next; + load_next_c = '1; + end else if(hwif_in.MLDSA_SEED[i0].SEED.hwclr) begin // HW Clear + next_c = '0; + load_next_c = '1; + end + field_combo.MLDSA_SEED[i0].SEED.next = next_c; + field_combo.MLDSA_SEED[i0].SEED.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.MLDSA_SEED[i0].SEED.value <= 32'h0; + end else if(field_combo.MLDSA_SEED[i0].SEED.load_next) begin + field_storage.MLDSA_SEED[i0].SEED.value <= field_combo.MLDSA_SEED[i0].SEED.next; + end + end + assign hwif_out.MLDSA_SEED[i0].SEED.value = field_storage.MLDSA_SEED[i0].SEED.value; + end + for(genvar i0=0; i0<8; i0++) begin + // Field: abr_reg.MLDSA_SIGN_RND[].SIGN_RND + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.MLDSA_SIGN_RND[i0].SIGN_RND.value; + load_next_c = '0; + if(decoded_reg_strb.MLDSA_SIGN_RND[i0] && decoded_req_is_wr && hwif_in.abr_ready) begin // SW write + next_c = (field_storage.MLDSA_SIGN_RND[i0].SIGN_RND.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end else if(hwif_in.MLDSA_SIGN_RND[i0].SIGN_RND.hwclr) begin // HW Clear + next_c = '0; + load_next_c = '1; + end + field_combo.MLDSA_SIGN_RND[i0].SIGN_RND.next = next_c; + field_combo.MLDSA_SIGN_RND[i0].SIGN_RND.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.MLDSA_SIGN_RND[i0].SIGN_RND.value <= 32'h0; + end else if(field_combo.MLDSA_SIGN_RND[i0].SIGN_RND.load_next) begin + field_storage.MLDSA_SIGN_RND[i0].SIGN_RND.value <= field_combo.MLDSA_SIGN_RND[i0].SIGN_RND.next; + end + end + assign hwif_out.MLDSA_SIGN_RND[i0].SIGN_RND.value = field_storage.MLDSA_SIGN_RND[i0].SIGN_RND.value; + end + for(genvar i0=0; i0<16; i0++) begin + // Field: abr_reg.MLDSA_MSG[].MSG + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.MLDSA_MSG[i0].MSG.value; + load_next_c = '0; + if(decoded_reg_strb.MLDSA_MSG[i0] && decoded_req_is_wr && hwif_in.MLDSA_MSG[i0].MSG.swwe) begin // SW write + next_c = (field_storage.MLDSA_MSG[i0].MSG.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end else if(hwif_in.MLDSA_MSG[i0].MSG.we) begin // HW Write - we + next_c = hwif_in.MLDSA_MSG[i0].MSG.next; + load_next_c = '1; + end else if(hwif_in.MLDSA_MSG[i0].MSG.hwclr) begin // HW Clear + next_c = '0; + load_next_c = '1; + end + field_combo.MLDSA_MSG[i0].MSG.next = next_c; + field_combo.MLDSA_MSG[i0].MSG.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.MLDSA_MSG[i0].MSG.value <= 32'h0; + end else if(field_combo.MLDSA_MSG[i0].MSG.load_next) begin + field_storage.MLDSA_MSG[i0].MSG.value <= field_combo.MLDSA_MSG[i0].MSG.next; + end + end + assign hwif_out.MLDSA_MSG[i0].MSG.value = field_storage.MLDSA_MSG[i0].MSG.value; + assign hwif_out.MLDSA_MSG[i0].MSG.swmod = decoded_reg_strb.MLDSA_MSG[i0] && decoded_req_is_wr; + end + for(genvar i0=0; i0<16; i0++) begin + // Field: abr_reg.MLDSA_VERIFY_RES[].VERIFY_RES + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.MLDSA_VERIFY_RES[i0].VERIFY_RES.value; + load_next_c = '0; + if(hwif_in.MLDSA_VERIFY_RES[i0].VERIFY_RES.we) begin // HW Write - we + next_c = hwif_in.MLDSA_VERIFY_RES[i0].VERIFY_RES.next; + load_next_c = '1; + end else if(hwif_in.MLDSA_VERIFY_RES[i0].VERIFY_RES.hwclr) begin // HW Clear + next_c = '0; + load_next_c = '1; + end + field_combo.MLDSA_VERIFY_RES[i0].VERIFY_RES.next = next_c; + field_combo.MLDSA_VERIFY_RES[i0].VERIFY_RES.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.MLDSA_VERIFY_RES[i0].VERIFY_RES.value <= 32'h0; + end else if(field_combo.MLDSA_VERIFY_RES[i0].VERIFY_RES.load_next) begin + field_storage.MLDSA_VERIFY_RES[i0].VERIFY_RES.value <= field_combo.MLDSA_VERIFY_RES[i0].VERIFY_RES.next; + end + end + assign hwif_out.MLDSA_VERIFY_RES[i0].VERIFY_RES.value = field_storage.MLDSA_VERIFY_RES[i0].VERIFY_RES.value; + end + for(genvar i0=0; i0<16; i0++) begin + // Field: abr_reg.MLDSA_EXTERNAL_MU[].EXTERNAL_MU + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.MLDSA_EXTERNAL_MU[i0].EXTERNAL_MU.value; + load_next_c = '0; + if(decoded_reg_strb.MLDSA_EXTERNAL_MU[i0] && decoded_req_is_wr && hwif_in.abr_ready) begin // SW write + next_c = (field_storage.MLDSA_EXTERNAL_MU[i0].EXTERNAL_MU.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end else if(hwif_in.MLDSA_EXTERNAL_MU[i0].EXTERNAL_MU.we) begin // HW Write - we + next_c = hwif_in.MLDSA_EXTERNAL_MU[i0].EXTERNAL_MU.next; + load_next_c = '1; + end else if(hwif_in.MLDSA_EXTERNAL_MU[i0].EXTERNAL_MU.hwclr) begin // HW Clear + next_c = '0; + load_next_c = '1; + end + field_combo.MLDSA_EXTERNAL_MU[i0].EXTERNAL_MU.next = next_c; + field_combo.MLDSA_EXTERNAL_MU[i0].EXTERNAL_MU.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.MLDSA_EXTERNAL_MU[i0].EXTERNAL_MU.value <= 32'h0; + end else if(field_combo.MLDSA_EXTERNAL_MU[i0].EXTERNAL_MU.load_next) begin + field_storage.MLDSA_EXTERNAL_MU[i0].EXTERNAL_MU.value <= field_combo.MLDSA_EXTERNAL_MU[i0].EXTERNAL_MU.next; + end + end + assign hwif_out.MLDSA_EXTERNAL_MU[i0].EXTERNAL_MU.value = field_storage.MLDSA_EXTERNAL_MU[i0].EXTERNAL_MU.value; + end + // Field: abr_reg.MLDSA_MSG_STROBE.STROBE + always_comb begin + automatic logic [3:0] next_c; + automatic logic load_next_c; + next_c = field_storage.MLDSA_MSG_STROBE.STROBE.value; + load_next_c = '0; + if(decoded_reg_strb.MLDSA_MSG_STROBE && decoded_req_is_wr && hwif_in.MLDSA_MSG_STROBE.STROBE.swwe) begin // SW write + next_c = (field_storage.MLDSA_MSG_STROBE.STROBE.value & ~decoded_wr_biten[3:0]) | (decoded_wr_data[3:0] & decoded_wr_biten[3:0]); + load_next_c = '1; + end else if(hwif_in.MLDSA_MSG_STROBE.STROBE.hwclr) begin // HW Clear + next_c = '0; + load_next_c = '1; + end + field_combo.MLDSA_MSG_STROBE.STROBE.next = next_c; + field_combo.MLDSA_MSG_STROBE.STROBE.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.MLDSA_MSG_STROBE.STROBE.value <= 4'hf; + end else if(field_combo.MLDSA_MSG_STROBE.STROBE.load_next) begin + field_storage.MLDSA_MSG_STROBE.STROBE.value <= field_combo.MLDSA_MSG_STROBE.STROBE.next; + end + end + assign hwif_out.MLDSA_MSG_STROBE.STROBE.value = field_storage.MLDSA_MSG_STROBE.STROBE.value; + // Field: abr_reg.MLDSA_CTX_CONFIG.CTX_SIZE + always_comb begin + automatic logic [7:0] next_c; + automatic logic load_next_c; + next_c = field_storage.MLDSA_CTX_CONFIG.CTX_SIZE.value; + load_next_c = '0; + if(decoded_reg_strb.MLDSA_CTX_CONFIG && decoded_req_is_wr && hwif_in.abr_ready) begin // SW write + next_c = (field_storage.MLDSA_CTX_CONFIG.CTX_SIZE.value & ~decoded_wr_biten[7:0]) | (decoded_wr_data[7:0] & decoded_wr_biten[7:0]); + load_next_c = '1; + end else if(hwif_in.MLDSA_CTX_CONFIG.CTX_SIZE.hwclr) begin // HW Clear + next_c = '0; + load_next_c = '1; + end + field_combo.MLDSA_CTX_CONFIG.CTX_SIZE.next = next_c; + field_combo.MLDSA_CTX_CONFIG.CTX_SIZE.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.MLDSA_CTX_CONFIG.CTX_SIZE.value <= 8'h0; + end else if(field_combo.MLDSA_CTX_CONFIG.CTX_SIZE.load_next) begin + field_storage.MLDSA_CTX_CONFIG.CTX_SIZE.value <= field_combo.MLDSA_CTX_CONFIG.CTX_SIZE.next; + end + end + assign hwif_out.MLDSA_CTX_CONFIG.CTX_SIZE.value = field_storage.MLDSA_CTX_CONFIG.CTX_SIZE.value; + for(genvar i0=0; i0<64; i0++) begin + // Field: abr_reg.MLDSA_CTX[].CTX + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.MLDSA_CTX[i0].CTX.value; + load_next_c = '0; + if(decoded_reg_strb.MLDSA_CTX[i0] && decoded_req_is_wr && hwif_in.abr_ready) begin // SW write + next_c = (field_storage.MLDSA_CTX[i0].CTX.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end else if(hwif_in.MLDSA_CTX[i0].CTX.hwclr) begin // HW Clear + next_c = '0; + load_next_c = '1; + end + field_combo.MLDSA_CTX[i0].CTX.next = next_c; + field_combo.MLDSA_CTX[i0].CTX.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.MLDSA_CTX[i0].CTX.value <= 32'h0; + end else if(field_combo.MLDSA_CTX[i0].CTX.load_next) begin + field_storage.MLDSA_CTX[i0].CTX.value <= field_combo.MLDSA_CTX[i0].CTX.next; + end + end + assign hwif_out.MLDSA_CTX[i0].CTX.value = field_storage.MLDSA_CTX[i0].CTX.value; + end + assign hwif_out.MLDSA_PUBKEY.req = decoded_reg_strb.MLDSA_PUBKEY; + assign hwif_out.MLDSA_PUBKEY.addr = decoded_addr[11:0]; + assign hwif_out.MLDSA_PUBKEY.req_is_wr = decoded_req_is_wr; + assign hwif_out.MLDSA_PUBKEY.wr_data = decoded_wr_data; + assign hwif_out.MLDSA_PUBKEY.wr_biten = decoded_wr_biten; + assign hwif_out.MLDSA_SIGNATURE.req = decoded_reg_strb.MLDSA_SIGNATURE; + assign hwif_out.MLDSA_SIGNATURE.addr = decoded_addr[12:0]; + assign hwif_out.MLDSA_SIGNATURE.req_is_wr = decoded_req_is_wr; + assign hwif_out.MLDSA_SIGNATURE.wr_data = decoded_wr_data; + assign hwif_out.MLDSA_SIGNATURE.wr_biten = decoded_wr_biten; + assign hwif_out.MLDSA_PRIVKEY_OUT.req = decoded_reg_strb.MLDSA_PRIVKEY_OUT; + assign hwif_out.MLDSA_PRIVKEY_OUT.addr = decoded_addr[12:0]; + assign hwif_out.MLDSA_PRIVKEY_OUT.req_is_wr = decoded_req_is_wr; + assign hwif_out.MLDSA_PRIVKEY_OUT.wr_data = decoded_wr_data; + assign hwif_out.MLDSA_PRIVKEY_OUT.wr_biten = decoded_wr_biten; + assign hwif_out.MLDSA_PRIVKEY_IN.req = decoded_reg_strb.MLDSA_PRIVKEY_IN; + assign hwif_out.MLDSA_PRIVKEY_IN.addr = decoded_addr[12:0]; + assign hwif_out.MLDSA_PRIVKEY_IN.req_is_wr = decoded_req_is_wr; + assign hwif_out.MLDSA_PRIVKEY_IN.wr_data = decoded_wr_data; + assign hwif_out.MLDSA_PRIVKEY_IN.wr_biten = decoded_wr_biten; + // Field: abr_reg.kv_mldsa_seed_rd_ctrl.read_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.kv_mldsa_seed_rd_ctrl.read_en.value; + load_next_c = '0; + if(decoded_reg_strb.kv_mldsa_seed_rd_ctrl && decoded_req_is_wr && hwif_in.kv_mldsa_seed_rd_ctrl.read_en.swwe) begin // SW write + next_c = (field_storage.kv_mldsa_seed_rd_ctrl.read_en.value & ~decoded_wr_biten[0:0]) | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end else if(hwif_in.kv_mldsa_seed_rd_ctrl.read_en.hwclr) begin // HW Clear + next_c = '0; + load_next_c = '1; + end + field_combo.kv_mldsa_seed_rd_ctrl.read_en.next = next_c; + field_combo.kv_mldsa_seed_rd_ctrl.read_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.kv_mldsa_seed_rd_ctrl.read_en.value <= 1'h0; + end else if(field_combo.kv_mldsa_seed_rd_ctrl.read_en.load_next) begin + field_storage.kv_mldsa_seed_rd_ctrl.read_en.value <= field_combo.kv_mldsa_seed_rd_ctrl.read_en.next; + end + end + assign hwif_out.kv_mldsa_seed_rd_ctrl.read_en.value = field_storage.kv_mldsa_seed_rd_ctrl.read_en.value; + // Field: abr_reg.kv_mldsa_seed_rd_ctrl.read_entry + always_comb begin + automatic logic [4:0] next_c; + automatic logic load_next_c; + next_c = field_storage.kv_mldsa_seed_rd_ctrl.read_entry.value; + load_next_c = '0; + if(decoded_reg_strb.kv_mldsa_seed_rd_ctrl && decoded_req_is_wr && hwif_in.kv_mldsa_seed_rd_ctrl.read_entry.swwe) begin // SW write + next_c = (field_storage.kv_mldsa_seed_rd_ctrl.read_entry.value & ~decoded_wr_biten[5:1]) | (decoded_wr_data[5:1] & decoded_wr_biten[5:1]); + load_next_c = '1; + end + field_combo.kv_mldsa_seed_rd_ctrl.read_entry.next = next_c; + field_combo.kv_mldsa_seed_rd_ctrl.read_entry.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.kv_mldsa_seed_rd_ctrl.read_entry.value <= 5'h0; + end else if(field_combo.kv_mldsa_seed_rd_ctrl.read_entry.load_next) begin + field_storage.kv_mldsa_seed_rd_ctrl.read_entry.value <= field_combo.kv_mldsa_seed_rd_ctrl.read_entry.next; + end + end + assign hwif_out.kv_mldsa_seed_rd_ctrl.read_entry.value = field_storage.kv_mldsa_seed_rd_ctrl.read_entry.value; + // Field: abr_reg.kv_mldsa_seed_rd_ctrl.pcr_hash_extend + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.kv_mldsa_seed_rd_ctrl.pcr_hash_extend.value; + load_next_c = '0; + if(decoded_reg_strb.kv_mldsa_seed_rd_ctrl && decoded_req_is_wr && hwif_in.kv_mldsa_seed_rd_ctrl.pcr_hash_extend.swwe) begin // SW write + next_c = (field_storage.kv_mldsa_seed_rd_ctrl.pcr_hash_extend.value & ~decoded_wr_biten[6:6]) | (decoded_wr_data[6:6] & decoded_wr_biten[6:6]); + load_next_c = '1; + end + field_combo.kv_mldsa_seed_rd_ctrl.pcr_hash_extend.next = next_c; + field_combo.kv_mldsa_seed_rd_ctrl.pcr_hash_extend.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.kv_mldsa_seed_rd_ctrl.pcr_hash_extend.value <= 1'h0; + end else if(field_combo.kv_mldsa_seed_rd_ctrl.pcr_hash_extend.load_next) begin + field_storage.kv_mldsa_seed_rd_ctrl.pcr_hash_extend.value <= field_combo.kv_mldsa_seed_rd_ctrl.pcr_hash_extend.next; + end + end + assign hwif_out.kv_mldsa_seed_rd_ctrl.pcr_hash_extend.value = field_storage.kv_mldsa_seed_rd_ctrl.pcr_hash_extend.value; + // Field: abr_reg.kv_mldsa_seed_rd_ctrl.rsvd + always_comb begin + automatic logic [24:0] next_c; + automatic logic load_next_c; + next_c = field_storage.kv_mldsa_seed_rd_ctrl.rsvd.value; + load_next_c = '0; + if(decoded_reg_strb.kv_mldsa_seed_rd_ctrl && decoded_req_is_wr && hwif_in.kv_mldsa_seed_rd_ctrl.rsvd.swwe) begin // SW write + next_c = (field_storage.kv_mldsa_seed_rd_ctrl.rsvd.value & ~decoded_wr_biten[31:7]) | (decoded_wr_data[31:7] & decoded_wr_biten[31:7]); + load_next_c = '1; + end + field_combo.kv_mldsa_seed_rd_ctrl.rsvd.next = next_c; + field_combo.kv_mldsa_seed_rd_ctrl.rsvd.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.kv_mldsa_seed_rd_ctrl.rsvd.value <= 25'h0; + end else if(field_combo.kv_mldsa_seed_rd_ctrl.rsvd.load_next) begin + field_storage.kv_mldsa_seed_rd_ctrl.rsvd.value <= field_combo.kv_mldsa_seed_rd_ctrl.rsvd.next; + end + end + assign hwif_out.kv_mldsa_seed_rd_ctrl.rsvd.value = field_storage.kv_mldsa_seed_rd_ctrl.rsvd.value; + // Field: abr_reg.kv_mldsa_seed_rd_status.VALID + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.kv_mldsa_seed_rd_status.VALID.value; + load_next_c = '0; + if(hwif_in.kv_mldsa_seed_rd_status.VALID.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end else if(hwif_in.kv_mldsa_seed_rd_status.VALID.hwclr) begin // HW Clear + next_c = '0; + load_next_c = '1; + end + field_combo.kv_mldsa_seed_rd_status.VALID.next = next_c; + field_combo.kv_mldsa_seed_rd_status.VALID.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.kv_mldsa_seed_rd_status.VALID.value <= 1'h0; + end else if(field_combo.kv_mldsa_seed_rd_status.VALID.load_next) begin + field_storage.kv_mldsa_seed_rd_status.VALID.value <= field_combo.kv_mldsa_seed_rd_status.VALID.next; + end + end + // Field: abr_reg.intr_block_rf.global_intr_en_r.error_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.global_intr_en_r.error_en.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.global_intr_en_r && decoded_req_is_wr) begin // SW write + next_c = (field_storage.intr_block_rf.global_intr_en_r.error_en.value & ~decoded_wr_biten[0:0]) | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end + field_combo.intr_block_rf.global_intr_en_r.error_en.next = next_c; + field_combo.intr_block_rf.global_intr_en_r.error_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.global_intr_en_r.error_en.value <= 1'h0; + end else if(field_combo.intr_block_rf.global_intr_en_r.error_en.load_next) begin + field_storage.intr_block_rf.global_intr_en_r.error_en.value <= field_combo.intr_block_rf.global_intr_en_r.error_en.next; + end + end + // Field: abr_reg.intr_block_rf.global_intr_en_r.notif_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.global_intr_en_r.notif_en.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.global_intr_en_r && decoded_req_is_wr) begin // SW write + next_c = (field_storage.intr_block_rf.global_intr_en_r.notif_en.value & ~decoded_wr_biten[1:1]) | (decoded_wr_data[1:1] & decoded_wr_biten[1:1]); + load_next_c = '1; + end + field_combo.intr_block_rf.global_intr_en_r.notif_en.next = next_c; + field_combo.intr_block_rf.global_intr_en_r.notif_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.global_intr_en_r.notif_en.value <= 1'h0; + end else if(field_combo.intr_block_rf.global_intr_en_r.notif_en.load_next) begin + field_storage.intr_block_rf.global_intr_en_r.notif_en.value <= field_combo.intr_block_rf.global_intr_en_r.notif_en.next; + end + end + // Field: abr_reg.intr_block_rf.error_intr_en_r.error_internal_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_intr_en_r.error_internal_en.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_intr_en_r && decoded_req_is_wr) begin // SW write + next_c = (field_storage.intr_block_rf.error_intr_en_r.error_internal_en.value & ~decoded_wr_biten[0:0]) | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end + field_combo.intr_block_rf.error_intr_en_r.error_internal_en.next = next_c; + field_combo.intr_block_rf.error_intr_en_r.error_internal_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.error_intr_en_r.error_internal_en.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_intr_en_r.error_internal_en.load_next) begin + field_storage.intr_block_rf.error_intr_en_r.error_internal_en.value <= field_combo.intr_block_rf.error_intr_en_r.error_internal_en.next; + end + end + // Field: abr_reg.intr_block_rf.notif_intr_en_r.notif_cmd_done_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_intr_en_r.notif_cmd_done_en.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.notif_intr_en_r && decoded_req_is_wr) begin // SW write + next_c = (field_storage.intr_block_rf.notif_intr_en_r.notif_cmd_done_en.value & ~decoded_wr_biten[0:0]) | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end + field_combo.intr_block_rf.notif_intr_en_r.notif_cmd_done_en.next = next_c; + field_combo.intr_block_rf.notif_intr_en_r.notif_cmd_done_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.notif_intr_en_r.notif_cmd_done_en.value <= 1'h0; + end else if(field_combo.intr_block_rf.notif_intr_en_r.notif_cmd_done_en.load_next) begin + field_storage.intr_block_rf.notif_intr_en_r.notif_cmd_done_en.value <= field_combo.intr_block_rf.notif_intr_en_r.notif_cmd_done_en.next; + end + end + // Field: abr_reg.intr_block_rf.error_global_intr_r.agg_sts + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_global_intr_r.agg_sts.value; + load_next_c = '0; + + // HW Write + next_c = hwif_out.intr_block_rf.error_internal_intr_r.intr; + load_next_c = '1; + field_combo.intr_block_rf.error_global_intr_r.agg_sts.next = next_c; + field_combo.intr_block_rf.error_global_intr_r.agg_sts.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.error_global_intr_r.agg_sts.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_global_intr_r.agg_sts.load_next) begin + field_storage.intr_block_rf.error_global_intr_r.agg_sts.value <= field_combo.intr_block_rf.error_global_intr_r.agg_sts.next; + end + end + assign hwif_out.intr_block_rf.error_global_intr_r.intr = + |(field_storage.intr_block_rf.error_global_intr_r.agg_sts.value & field_storage.intr_block_rf.global_intr_en_r.error_en.value); + // Field: abr_reg.intr_block_rf.notif_global_intr_r.agg_sts + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_global_intr_r.agg_sts.value; + load_next_c = '0; + + // HW Write + next_c = hwif_out.intr_block_rf.notif_internal_intr_r.intr; + load_next_c = '1; + field_combo.intr_block_rf.notif_global_intr_r.agg_sts.next = next_c; + field_combo.intr_block_rf.notif_global_intr_r.agg_sts.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.notif_global_intr_r.agg_sts.value <= 1'h0; + end else if(field_combo.intr_block_rf.notif_global_intr_r.agg_sts.load_next) begin + field_storage.intr_block_rf.notif_global_intr_r.agg_sts.value <= field_combo.intr_block_rf.notif_global_intr_r.agg_sts.next; + end + end + assign hwif_out.intr_block_rf.notif_global_intr_r.intr = + |(field_storage.intr_block_rf.notif_global_intr_r.agg_sts.value & field_storage.intr_block_rf.global_intr_en_r.notif_en.value); + // Field: abr_reg.intr_block_rf.error_internal_intr_r.error_internal_sts + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_internal_intr_r.error_internal_sts.value; + load_next_c = '0; + if(field_storage.intr_block_rf.error_intr_trig_r.error_internal_trig.value != '0) begin // stickybit + next_c = field_storage.intr_block_rf.error_internal_intr_r.error_internal_sts.value | field_storage.intr_block_rf.error_intr_trig_r.error_internal_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.error_internal_intr_r.error_internal_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end else if(decoded_reg_strb.intr_block_rf.error_internal_intr_r && decoded_req_is_wr) begin // SW write 1 clear + next_c = field_storage.intr_block_rf.error_internal_intr_r.error_internal_sts.value & ~(decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end + field_combo.intr_block_rf.error_internal_intr_r.error_internal_sts.next = next_c; + field_combo.intr_block_rf.error_internal_intr_r.error_internal_sts.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.hard_reset_b) begin + if(~hwif_in.hard_reset_b) begin + field_storage.intr_block_rf.error_internal_intr_r.error_internal_sts.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_internal_intr_r.error_internal_sts.load_next) begin + field_storage.intr_block_rf.error_internal_intr_r.error_internal_sts.value <= field_combo.intr_block_rf.error_internal_intr_r.error_internal_sts.next; + end + end + assign hwif_out.intr_block_rf.error_internal_intr_r.intr = + |(field_storage.intr_block_rf.error_internal_intr_r.error_internal_sts.value & field_storage.intr_block_rf.error_intr_en_r.error_internal_en.value); + // Field: abr_reg.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.value; + load_next_c = '0; + if(field_storage.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.value != '0) begin // stickybit + next_c = field_storage.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.value | field_storage.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end else if(decoded_reg_strb.intr_block_rf.notif_internal_intr_r && decoded_req_is_wr) begin // SW write 1 clear + next_c = field_storage.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.value & ~(decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end + field_combo.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.next = next_c; + field_combo.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.value <= 1'h0; + end else if(field_combo.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.load_next) begin + field_storage.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.value <= field_combo.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.next; + end + end + assign hwif_out.intr_block_rf.notif_internal_intr_r.intr = + |(field_storage.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.value & field_storage.intr_block_rf.notif_intr_en_r.notif_cmd_done_en.value); + // Field: abr_reg.intr_block_rf.error_intr_trig_r.error_internal_trig + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_intr_trig_r.error_internal_trig.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_intr_trig_r && decoded_req_is_wr) begin // SW write 1 set + next_c = field_storage.intr_block_rf.error_intr_trig_r.error_internal_trig.value | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end else begin // singlepulse clears back to 0 + next_c = '0; + load_next_c = '1; + end + field_combo.intr_block_rf.error_intr_trig_r.error_internal_trig.next = next_c; + field_combo.intr_block_rf.error_intr_trig_r.error_internal_trig.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.error_intr_trig_r.error_internal_trig.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_intr_trig_r.error_internal_trig.load_next) begin + field_storage.intr_block_rf.error_intr_trig_r.error_internal_trig.value <= field_combo.intr_block_rf.error_intr_trig_r.error_internal_trig.next; + end + end + // Field: abr_reg.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.notif_intr_trig_r && decoded_req_is_wr) begin // SW write 1 set + next_c = field_storage.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.value | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end else begin // singlepulse clears back to 0 + next_c = '0; + load_next_c = '1; + end + field_combo.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.next = next_c; + field_combo.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.value <= 1'h0; + end else if(field_combo.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.load_next) begin + field_storage.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.value <= field_combo.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.next; + end + end + // Field: abr_reg.intr_block_rf.error_internal_intr_count_r.cnt + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_internal_intr_count_r.cnt.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_internal_intr_count_r && decoded_req_is_wr) begin // SW write + next_c = (field_storage.intr_block_rf.error_internal_intr_count_r.cnt.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + if(field_storage.intr_block_rf.error_internal_intr_count_incr_r.pulse.value) begin // increment + if(((33)'(next_c) + 32'h1) > 32'hffffffff) begin // up-counter saturated + next_c = 32'hffffffff; + end else begin + next_c = next_c + 32'h1; + end + load_next_c = '1; + end + field_combo.intr_block_rf.error_internal_intr_count_r.cnt.incrthreshold = (field_storage.intr_block_rf.error_internal_intr_count_r.cnt.value >= 32'hffffffff); + field_combo.intr_block_rf.error_internal_intr_count_r.cnt.incrsaturate = (field_storage.intr_block_rf.error_internal_intr_count_r.cnt.value >= 32'hffffffff); + if(next_c > 32'hffffffff) begin + next_c = 32'hffffffff; + load_next_c = '1; + end + field_combo.intr_block_rf.error_internal_intr_count_r.cnt.next = next_c; + field_combo.intr_block_rf.error_internal_intr_count_r.cnt.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.hard_reset_b) begin + if(~hwif_in.hard_reset_b) begin + field_storage.intr_block_rf.error_internal_intr_count_r.cnt.value <= 32'h0; + end else if(field_combo.intr_block_rf.error_internal_intr_count_r.cnt.load_next) begin + field_storage.intr_block_rf.error_internal_intr_count_r.cnt.value <= field_combo.intr_block_rf.error_internal_intr_count_r.cnt.next; + end + end + // Field: abr_reg.intr_block_rf.notif_cmd_done_intr_count_r.cnt + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_cmd_done_intr_count_r.cnt.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.notif_cmd_done_intr_count_r && decoded_req_is_wr) begin // SW write + next_c = (field_storage.intr_block_rf.notif_cmd_done_intr_count_r.cnt.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + if(field_storage.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.value) begin // increment + if(((33)'(next_c) + 32'h1) > 32'hffffffff) begin // up-counter saturated + next_c = 32'hffffffff; + end else begin + next_c = next_c + 32'h1; + end + load_next_c = '1; + end + field_combo.intr_block_rf.notif_cmd_done_intr_count_r.cnt.incrthreshold = (field_storage.intr_block_rf.notif_cmd_done_intr_count_r.cnt.value >= 32'hffffffff); + field_combo.intr_block_rf.notif_cmd_done_intr_count_r.cnt.incrsaturate = (field_storage.intr_block_rf.notif_cmd_done_intr_count_r.cnt.value >= 32'hffffffff); + if(next_c > 32'hffffffff) begin + next_c = 32'hffffffff; + load_next_c = '1; + end + field_combo.intr_block_rf.notif_cmd_done_intr_count_r.cnt.next = next_c; + field_combo.intr_block_rf.notif_cmd_done_intr_count_r.cnt.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.notif_cmd_done_intr_count_r.cnt.value <= 32'h0; + end else if(field_combo.intr_block_rf.notif_cmd_done_intr_count_r.cnt.load_next) begin + field_storage.intr_block_rf.notif_cmd_done_intr_count_r.cnt.value <= field_combo.intr_block_rf.notif_cmd_done_intr_count_r.cnt.next; + end + end + // Field: abr_reg.intr_block_rf.error_internal_intr_count_incr_r.pulse + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_internal_intr_count_incr_r.pulse.value; + load_next_c = '0; + if(field_storage.intr_block_rf.error_intr_trig_r.error_internal_trig.value) begin // HW Write - we + next_c = field_storage.intr_block_rf.error_intr_trig_r.error_internal_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.error_internal_intr_r.error_internal_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end + if(field_storage.intr_block_rf.error_internal_intr_count_incr_r.pulse.value) begin // decrement + field_combo.intr_block_rf.error_internal_intr_count_incr_r.pulse.underflow = (next_c < (1'h1)); + next_c = next_c - 1'h1; + load_next_c = '1; + end else begin + field_combo.intr_block_rf.error_internal_intr_count_incr_r.pulse.underflow = '0; + end + field_combo.intr_block_rf.error_internal_intr_count_incr_r.pulse.decrthreshold = (field_storage.intr_block_rf.error_internal_intr_count_incr_r.pulse.value <= 1'd0); + field_combo.intr_block_rf.error_internal_intr_count_incr_r.pulse.next = next_c; + field_combo.intr_block_rf.error_internal_intr_count_incr_r.pulse.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.error_internal_intr_count_incr_r.pulse.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_internal_intr_count_incr_r.pulse.load_next) begin + field_storage.intr_block_rf.error_internal_intr_count_incr_r.pulse.value <= field_combo.intr_block_rf.error_internal_intr_count_incr_r.pulse.next; + end + end + // Field: abr_reg.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.value; + load_next_c = '0; + if(field_storage.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.value) begin // HW Write - we + next_c = field_storage.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end + if(field_storage.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.value) begin // decrement + field_combo.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.underflow = (next_c < (1'h1)); + next_c = next_c - 1'h1; + load_next_c = '1; + end else begin + field_combo.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.underflow = '0; + end + field_combo.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.decrthreshold = (field_storage.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.value <= 1'd0); + field_combo.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.next = next_c; + field_combo.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.value <= 1'h0; + end else if(field_combo.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.load_next) begin + field_storage.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.value <= field_combo.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.next; + end + end + // Field: abr_reg.MLKEM_CTRL.CTRL + always_comb begin + automatic logic [2:0] next_c; + automatic logic load_next_c; + next_c = field_storage.MLKEM_CTRL.CTRL.value; + load_next_c = '0; + if(decoded_reg_strb.MLKEM_CTRL && decoded_req_is_wr && hwif_in.abr_ready) begin // SW write + next_c = (field_storage.MLKEM_CTRL.CTRL.value & ~decoded_wr_biten[2:0]) | (decoded_wr_data[2:0] & decoded_wr_biten[2:0]); + load_next_c = '1; + end else if(hwif_in.MLKEM_CTRL.CTRL.hwclr) begin // HW Clear + next_c = '0; + load_next_c = '1; + end + field_combo.MLKEM_CTRL.CTRL.next = next_c; + field_combo.MLKEM_CTRL.CTRL.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.MLKEM_CTRL.CTRL.value <= 3'h0; + end else if(field_combo.MLKEM_CTRL.CTRL.load_next) begin + field_storage.MLKEM_CTRL.CTRL.value <= field_combo.MLKEM_CTRL.CTRL.next; + end + end + assign hwif_out.MLKEM_CTRL.CTRL.value = field_storage.MLKEM_CTRL.CTRL.value; + // Field: abr_reg.MLKEM_CTRL.ZEROIZE + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.MLKEM_CTRL.ZEROIZE.value; + load_next_c = '0; + if(decoded_reg_strb.MLKEM_CTRL && decoded_req_is_wr) begin // SW write + next_c = (field_storage.MLKEM_CTRL.ZEROIZE.value & ~decoded_wr_biten[3:3]) | (decoded_wr_data[3:3] & decoded_wr_biten[3:3]); + load_next_c = '1; + end else begin // singlepulse clears back to 0 + next_c = '0; + load_next_c = '1; + end + field_combo.MLKEM_CTRL.ZEROIZE.next = next_c; + field_combo.MLKEM_CTRL.ZEROIZE.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.MLKEM_CTRL.ZEROIZE.value <= 1'h0; + end else if(field_combo.MLKEM_CTRL.ZEROIZE.load_next) begin + field_storage.MLKEM_CTRL.ZEROIZE.value <= field_combo.MLKEM_CTRL.ZEROIZE.next; + end + end + assign hwif_out.MLKEM_CTRL.ZEROIZE.value = field_storage.MLKEM_CTRL.ZEROIZE.value; + // Field: abr_reg.MLKEM_STATUS.VALID + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.MLKEM_STATUS.VALID.value; + load_next_c = '0; + + // HW Write + next_c = hwif_in.MLKEM_STATUS.VALID.next; + load_next_c = '1; + field_combo.MLKEM_STATUS.VALID.next = next_c; + field_combo.MLKEM_STATUS.VALID.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.MLKEM_STATUS.VALID.value <= 1'h0; + end else if(field_combo.MLKEM_STATUS.VALID.load_next) begin + field_storage.MLKEM_STATUS.VALID.value <= field_combo.MLKEM_STATUS.VALID.next; + end + end + assign hwif_out.MLKEM_STATUS.VALID.value = field_storage.MLKEM_STATUS.VALID.value; + // Field: abr_reg.MLKEM_STATUS.ERROR + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.MLKEM_STATUS.ERROR.value; + load_next_c = '0; + + // HW Write + next_c = hwif_in.MLKEM_STATUS.ERROR.next; + load_next_c = '1; + field_combo.MLKEM_STATUS.ERROR.next = next_c; + field_combo.MLKEM_STATUS.ERROR.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.MLKEM_STATUS.ERROR.value <= 1'h0; + end else if(field_combo.MLKEM_STATUS.ERROR.load_next) begin + field_storage.MLKEM_STATUS.ERROR.value <= field_combo.MLKEM_STATUS.ERROR.next; + end + end + assign hwif_out.MLKEM_STATUS.ERROR.value = field_storage.MLKEM_STATUS.ERROR.value; + for(genvar i0=0; i0<8; i0++) begin + // Field: abr_reg.MLKEM_SEED_D[].SEED + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.MLKEM_SEED_D[i0].SEED.value; + load_next_c = '0; + if(decoded_reg_strb.MLKEM_SEED_D[i0] && decoded_req_is_wr && hwif_in.MLKEM_SEED_D[i0].SEED.swwe) begin // SW write + next_c = (field_storage.MLKEM_SEED_D[i0].SEED.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end else if(hwif_in.MLKEM_SEED_D[i0].SEED.we) begin // HW Write - we + next_c = hwif_in.MLKEM_SEED_D[i0].SEED.next; + load_next_c = '1; + end else if(hwif_in.MLKEM_SEED_D[i0].SEED.hwclr) begin // HW Clear + next_c = '0; + load_next_c = '1; + end + field_combo.MLKEM_SEED_D[i0].SEED.next = next_c; + field_combo.MLKEM_SEED_D[i0].SEED.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.MLKEM_SEED_D[i0].SEED.value <= 32'h0; + end else if(field_combo.MLKEM_SEED_D[i0].SEED.load_next) begin + field_storage.MLKEM_SEED_D[i0].SEED.value <= field_combo.MLKEM_SEED_D[i0].SEED.next; + end + end + assign hwif_out.MLKEM_SEED_D[i0].SEED.value = field_storage.MLKEM_SEED_D[i0].SEED.value; + end + for(genvar i0=0; i0<8; i0++) begin + + assign hwif_out.MLKEM_SEED_Z[i0].req = decoded_req_is_wr ? decoded_reg_strb.MLKEM_SEED_Z[i0] : '0; + assign hwif_out.MLKEM_SEED_Z[i0].req_is_wr = decoded_req_is_wr; + assign hwif_out.MLKEM_SEED_Z[i0].wr_data = decoded_wr_data; + assign hwif_out.MLKEM_SEED_Z[i0].wr_biten = decoded_wr_biten; + end + for(genvar i0=0; i0<8; i0++) begin + + assign hwif_out.MLKEM_SHARED_KEY[i0].req = !decoded_req_is_wr ? decoded_reg_strb.MLKEM_SHARED_KEY[i0] : '0; + assign hwif_out.MLKEM_SHARED_KEY[i0].req_is_wr = decoded_req_is_wr; + end + assign hwif_out.MLKEM_MSG.req = decoded_reg_strb.MLKEM_MSG; + assign hwif_out.MLKEM_MSG.addr = decoded_addr[5:0]; + assign hwif_out.MLKEM_MSG.req_is_wr = decoded_req_is_wr; + assign hwif_out.MLKEM_MSG.wr_data = decoded_wr_data; + assign hwif_out.MLKEM_MSG.wr_biten = decoded_wr_biten; + assign hwif_out.MLKEM_DECAPS_KEY.req = decoded_reg_strb.MLKEM_DECAPS_KEY; + assign hwif_out.MLKEM_DECAPS_KEY.addr = decoded_addr[11:0]; + assign hwif_out.MLKEM_DECAPS_KEY.req_is_wr = decoded_req_is_wr; + assign hwif_out.MLKEM_DECAPS_KEY.wr_data = decoded_wr_data; + assign hwif_out.MLKEM_DECAPS_KEY.wr_biten = decoded_wr_biten; + assign hwif_out.MLKEM_ENCAPS_KEY.req = decoded_reg_strb.MLKEM_ENCAPS_KEY; + assign hwif_out.MLKEM_ENCAPS_KEY.addr = decoded_addr[10:0]; + assign hwif_out.MLKEM_ENCAPS_KEY.req_is_wr = decoded_req_is_wr; + assign hwif_out.MLKEM_ENCAPS_KEY.wr_data = decoded_wr_data; + assign hwif_out.MLKEM_ENCAPS_KEY.wr_biten = decoded_wr_biten; + assign hwif_out.MLKEM_CIPHERTEXT.req = decoded_reg_strb.MLKEM_CIPHERTEXT; + assign hwif_out.MLKEM_CIPHERTEXT.addr = decoded_addr[10:0]; + assign hwif_out.MLKEM_CIPHERTEXT.req_is_wr = decoded_req_is_wr; + assign hwif_out.MLKEM_CIPHERTEXT.wr_data = decoded_wr_data; + assign hwif_out.MLKEM_CIPHERTEXT.wr_biten = decoded_wr_biten; + // Field: abr_reg.kv_mlkem_seed_rd_ctrl.read_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.kv_mlkem_seed_rd_ctrl.read_en.value; + load_next_c = '0; + if(decoded_reg_strb.kv_mlkem_seed_rd_ctrl && decoded_req_is_wr && hwif_in.kv_mlkem_seed_rd_ctrl.read_en.swwe) begin // SW write + next_c = (field_storage.kv_mlkem_seed_rd_ctrl.read_en.value & ~decoded_wr_biten[0:0]) | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end else if(hwif_in.kv_mlkem_seed_rd_ctrl.read_en.hwclr) begin // HW Clear + next_c = '0; + load_next_c = '1; + end + field_combo.kv_mlkem_seed_rd_ctrl.read_en.next = next_c; + field_combo.kv_mlkem_seed_rd_ctrl.read_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.kv_mlkem_seed_rd_ctrl.read_en.value <= 1'h0; + end else if(field_combo.kv_mlkem_seed_rd_ctrl.read_en.load_next) begin + field_storage.kv_mlkem_seed_rd_ctrl.read_en.value <= field_combo.kv_mlkem_seed_rd_ctrl.read_en.next; + end + end + assign hwif_out.kv_mlkem_seed_rd_ctrl.read_en.value = field_storage.kv_mlkem_seed_rd_ctrl.read_en.value; + // Field: abr_reg.kv_mlkem_seed_rd_ctrl.read_entry + always_comb begin + automatic logic [4:0] next_c; + automatic logic load_next_c; + next_c = field_storage.kv_mlkem_seed_rd_ctrl.read_entry.value; + load_next_c = '0; + if(decoded_reg_strb.kv_mlkem_seed_rd_ctrl && decoded_req_is_wr && hwif_in.kv_mlkem_seed_rd_ctrl.read_entry.swwe) begin // SW write + next_c = (field_storage.kv_mlkem_seed_rd_ctrl.read_entry.value & ~decoded_wr_biten[5:1]) | (decoded_wr_data[5:1] & decoded_wr_biten[5:1]); + load_next_c = '1; + end + field_combo.kv_mlkem_seed_rd_ctrl.read_entry.next = next_c; + field_combo.kv_mlkem_seed_rd_ctrl.read_entry.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.kv_mlkem_seed_rd_ctrl.read_entry.value <= 5'h0; + end else if(field_combo.kv_mlkem_seed_rd_ctrl.read_entry.load_next) begin + field_storage.kv_mlkem_seed_rd_ctrl.read_entry.value <= field_combo.kv_mlkem_seed_rd_ctrl.read_entry.next; + end + end + assign hwif_out.kv_mlkem_seed_rd_ctrl.read_entry.value = field_storage.kv_mlkem_seed_rd_ctrl.read_entry.value; + // Field: abr_reg.kv_mlkem_seed_rd_ctrl.pcr_hash_extend + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.kv_mlkem_seed_rd_ctrl.pcr_hash_extend.value; + load_next_c = '0; + if(decoded_reg_strb.kv_mlkem_seed_rd_ctrl && decoded_req_is_wr && hwif_in.kv_mlkem_seed_rd_ctrl.pcr_hash_extend.swwe) begin // SW write + next_c = (field_storage.kv_mlkem_seed_rd_ctrl.pcr_hash_extend.value & ~decoded_wr_biten[6:6]) | (decoded_wr_data[6:6] & decoded_wr_biten[6:6]); + load_next_c = '1; + end + field_combo.kv_mlkem_seed_rd_ctrl.pcr_hash_extend.next = next_c; + field_combo.kv_mlkem_seed_rd_ctrl.pcr_hash_extend.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.kv_mlkem_seed_rd_ctrl.pcr_hash_extend.value <= 1'h0; + end else if(field_combo.kv_mlkem_seed_rd_ctrl.pcr_hash_extend.load_next) begin + field_storage.kv_mlkem_seed_rd_ctrl.pcr_hash_extend.value <= field_combo.kv_mlkem_seed_rd_ctrl.pcr_hash_extend.next; + end + end + assign hwif_out.kv_mlkem_seed_rd_ctrl.pcr_hash_extend.value = field_storage.kv_mlkem_seed_rd_ctrl.pcr_hash_extend.value; + // Field: abr_reg.kv_mlkem_seed_rd_ctrl.rsvd + always_comb begin + automatic logic [24:0] next_c; + automatic logic load_next_c; + next_c = field_storage.kv_mlkem_seed_rd_ctrl.rsvd.value; + load_next_c = '0; + if(decoded_reg_strb.kv_mlkem_seed_rd_ctrl && decoded_req_is_wr && hwif_in.kv_mlkem_seed_rd_ctrl.rsvd.swwe) begin // SW write + next_c = (field_storage.kv_mlkem_seed_rd_ctrl.rsvd.value & ~decoded_wr_biten[31:7]) | (decoded_wr_data[31:7] & decoded_wr_biten[31:7]); + load_next_c = '1; + end + field_combo.kv_mlkem_seed_rd_ctrl.rsvd.next = next_c; + field_combo.kv_mlkem_seed_rd_ctrl.rsvd.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.kv_mlkem_seed_rd_ctrl.rsvd.value <= 25'h0; + end else if(field_combo.kv_mlkem_seed_rd_ctrl.rsvd.load_next) begin + field_storage.kv_mlkem_seed_rd_ctrl.rsvd.value <= field_combo.kv_mlkem_seed_rd_ctrl.rsvd.next; + end + end + assign hwif_out.kv_mlkem_seed_rd_ctrl.rsvd.value = field_storage.kv_mlkem_seed_rd_ctrl.rsvd.value; + // Field: abr_reg.kv_mlkem_seed_rd_status.VALID + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.kv_mlkem_seed_rd_status.VALID.value; + load_next_c = '0; + if(hwif_in.kv_mlkem_seed_rd_status.VALID.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end else if(hwif_in.kv_mlkem_seed_rd_status.VALID.hwclr) begin // HW Clear + next_c = '0; + load_next_c = '1; + end + field_combo.kv_mlkem_seed_rd_status.VALID.next = next_c; + field_combo.kv_mlkem_seed_rd_status.VALID.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.kv_mlkem_seed_rd_status.VALID.value <= 1'h0; + end else if(field_combo.kv_mlkem_seed_rd_status.VALID.load_next) begin + field_storage.kv_mlkem_seed_rd_status.VALID.value <= field_combo.kv_mlkem_seed_rd_status.VALID.next; + end + end + // Field: abr_reg.kv_mlkem_msg_rd_ctrl.read_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.kv_mlkem_msg_rd_ctrl.read_en.value; + load_next_c = '0; + if(decoded_reg_strb.kv_mlkem_msg_rd_ctrl && decoded_req_is_wr && hwif_in.kv_mlkem_msg_rd_ctrl.read_en.swwe) begin // SW write + next_c = (field_storage.kv_mlkem_msg_rd_ctrl.read_en.value & ~decoded_wr_biten[0:0]) | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end else if(hwif_in.kv_mlkem_msg_rd_ctrl.read_en.hwclr) begin // HW Clear + next_c = '0; + load_next_c = '1; + end + field_combo.kv_mlkem_msg_rd_ctrl.read_en.next = next_c; + field_combo.kv_mlkem_msg_rd_ctrl.read_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.kv_mlkem_msg_rd_ctrl.read_en.value <= 1'h0; + end else if(field_combo.kv_mlkem_msg_rd_ctrl.read_en.load_next) begin + field_storage.kv_mlkem_msg_rd_ctrl.read_en.value <= field_combo.kv_mlkem_msg_rd_ctrl.read_en.next; + end + end + assign hwif_out.kv_mlkem_msg_rd_ctrl.read_en.value = field_storage.kv_mlkem_msg_rd_ctrl.read_en.value; + // Field: abr_reg.kv_mlkem_msg_rd_ctrl.read_entry + always_comb begin + automatic logic [4:0] next_c; + automatic logic load_next_c; + next_c = field_storage.kv_mlkem_msg_rd_ctrl.read_entry.value; + load_next_c = '0; + if(decoded_reg_strb.kv_mlkem_msg_rd_ctrl && decoded_req_is_wr && hwif_in.kv_mlkem_msg_rd_ctrl.read_entry.swwe) begin // SW write + next_c = (field_storage.kv_mlkem_msg_rd_ctrl.read_entry.value & ~decoded_wr_biten[5:1]) | (decoded_wr_data[5:1] & decoded_wr_biten[5:1]); + load_next_c = '1; + end + field_combo.kv_mlkem_msg_rd_ctrl.read_entry.next = next_c; + field_combo.kv_mlkem_msg_rd_ctrl.read_entry.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.kv_mlkem_msg_rd_ctrl.read_entry.value <= 5'h0; + end else if(field_combo.kv_mlkem_msg_rd_ctrl.read_entry.load_next) begin + field_storage.kv_mlkem_msg_rd_ctrl.read_entry.value <= field_combo.kv_mlkem_msg_rd_ctrl.read_entry.next; + end + end + assign hwif_out.kv_mlkem_msg_rd_ctrl.read_entry.value = field_storage.kv_mlkem_msg_rd_ctrl.read_entry.value; + // Field: abr_reg.kv_mlkem_msg_rd_ctrl.pcr_hash_extend + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.kv_mlkem_msg_rd_ctrl.pcr_hash_extend.value; + load_next_c = '0; + if(decoded_reg_strb.kv_mlkem_msg_rd_ctrl && decoded_req_is_wr && hwif_in.kv_mlkem_msg_rd_ctrl.pcr_hash_extend.swwe) begin // SW write + next_c = (field_storage.kv_mlkem_msg_rd_ctrl.pcr_hash_extend.value & ~decoded_wr_biten[6:6]) | (decoded_wr_data[6:6] & decoded_wr_biten[6:6]); + load_next_c = '1; + end + field_combo.kv_mlkem_msg_rd_ctrl.pcr_hash_extend.next = next_c; + field_combo.kv_mlkem_msg_rd_ctrl.pcr_hash_extend.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.kv_mlkem_msg_rd_ctrl.pcr_hash_extend.value <= 1'h0; + end else if(field_combo.kv_mlkem_msg_rd_ctrl.pcr_hash_extend.load_next) begin + field_storage.kv_mlkem_msg_rd_ctrl.pcr_hash_extend.value <= field_combo.kv_mlkem_msg_rd_ctrl.pcr_hash_extend.next; + end + end + assign hwif_out.kv_mlkem_msg_rd_ctrl.pcr_hash_extend.value = field_storage.kv_mlkem_msg_rd_ctrl.pcr_hash_extend.value; + // Field: abr_reg.kv_mlkem_msg_rd_ctrl.rsvd + always_comb begin + automatic logic [24:0] next_c; + automatic logic load_next_c; + next_c = field_storage.kv_mlkem_msg_rd_ctrl.rsvd.value; + load_next_c = '0; + if(decoded_reg_strb.kv_mlkem_msg_rd_ctrl && decoded_req_is_wr && hwif_in.kv_mlkem_msg_rd_ctrl.rsvd.swwe) begin // SW write + next_c = (field_storage.kv_mlkem_msg_rd_ctrl.rsvd.value & ~decoded_wr_biten[31:7]) | (decoded_wr_data[31:7] & decoded_wr_biten[31:7]); + load_next_c = '1; + end + field_combo.kv_mlkem_msg_rd_ctrl.rsvd.next = next_c; + field_combo.kv_mlkem_msg_rd_ctrl.rsvd.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.kv_mlkem_msg_rd_ctrl.rsvd.value <= 25'h0; + end else if(field_combo.kv_mlkem_msg_rd_ctrl.rsvd.load_next) begin + field_storage.kv_mlkem_msg_rd_ctrl.rsvd.value <= field_combo.kv_mlkem_msg_rd_ctrl.rsvd.next; + end + end + assign hwif_out.kv_mlkem_msg_rd_ctrl.rsvd.value = field_storage.kv_mlkem_msg_rd_ctrl.rsvd.value; + // Field: abr_reg.kv_mlkem_msg_rd_status.VALID + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.kv_mlkem_msg_rd_status.VALID.value; + load_next_c = '0; + if(hwif_in.kv_mlkem_msg_rd_status.VALID.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end else if(hwif_in.kv_mlkem_msg_rd_status.VALID.hwclr) begin // HW Clear + next_c = '0; + load_next_c = '1; + end + field_combo.kv_mlkem_msg_rd_status.VALID.next = next_c; + field_combo.kv_mlkem_msg_rd_status.VALID.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.kv_mlkem_msg_rd_status.VALID.value <= 1'h0; + end else if(field_combo.kv_mlkem_msg_rd_status.VALID.load_next) begin + field_storage.kv_mlkem_msg_rd_status.VALID.value <= field_combo.kv_mlkem_msg_rd_status.VALID.next; + end + end + // Field: abr_reg.kv_mlkem_sharedkey_wr_ctrl.write_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.kv_mlkem_sharedkey_wr_ctrl.write_en.value; + load_next_c = '0; + if(decoded_reg_strb.kv_mlkem_sharedkey_wr_ctrl && decoded_req_is_wr && hwif_in.kv_mlkem_sharedkey_wr_ctrl.write_en.swwe) begin // SW write + next_c = (field_storage.kv_mlkem_sharedkey_wr_ctrl.write_en.value & ~decoded_wr_biten[0:0]) | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end else if(hwif_in.kv_mlkem_sharedkey_wr_ctrl.write_en.hwclr) begin // HW Clear + next_c = '0; + load_next_c = '1; + end + field_combo.kv_mlkem_sharedkey_wr_ctrl.write_en.next = next_c; + field_combo.kv_mlkem_sharedkey_wr_ctrl.write_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.kv_mlkem_sharedkey_wr_ctrl.write_en.value <= 1'h0; + end else if(field_combo.kv_mlkem_sharedkey_wr_ctrl.write_en.load_next) begin + field_storage.kv_mlkem_sharedkey_wr_ctrl.write_en.value <= field_combo.kv_mlkem_sharedkey_wr_ctrl.write_en.next; + end + end + assign hwif_out.kv_mlkem_sharedkey_wr_ctrl.write_en.value = field_storage.kv_mlkem_sharedkey_wr_ctrl.write_en.value; + // Field: abr_reg.kv_mlkem_sharedkey_wr_ctrl.write_entry + always_comb begin + automatic logic [4:0] next_c; + automatic logic load_next_c; + next_c = field_storage.kv_mlkem_sharedkey_wr_ctrl.write_entry.value; + load_next_c = '0; + if(decoded_reg_strb.kv_mlkem_sharedkey_wr_ctrl && decoded_req_is_wr && hwif_in.kv_mlkem_sharedkey_wr_ctrl.write_entry.swwe) begin // SW write + next_c = (field_storage.kv_mlkem_sharedkey_wr_ctrl.write_entry.value & ~decoded_wr_biten[5:1]) | (decoded_wr_data[5:1] & decoded_wr_biten[5:1]); + load_next_c = '1; + end + field_combo.kv_mlkem_sharedkey_wr_ctrl.write_entry.next = next_c; + field_combo.kv_mlkem_sharedkey_wr_ctrl.write_entry.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.kv_mlkem_sharedkey_wr_ctrl.write_entry.value <= 5'h0; + end else if(field_combo.kv_mlkem_sharedkey_wr_ctrl.write_entry.load_next) begin + field_storage.kv_mlkem_sharedkey_wr_ctrl.write_entry.value <= field_combo.kv_mlkem_sharedkey_wr_ctrl.write_entry.next; + end + end + assign hwif_out.kv_mlkem_sharedkey_wr_ctrl.write_entry.value = field_storage.kv_mlkem_sharedkey_wr_ctrl.write_entry.value; + // Field: abr_reg.kv_mlkem_sharedkey_wr_ctrl.hmac_key_dest_valid + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.kv_mlkem_sharedkey_wr_ctrl.hmac_key_dest_valid.value; + load_next_c = '0; + if(decoded_reg_strb.kv_mlkem_sharedkey_wr_ctrl && decoded_req_is_wr && hwif_in.kv_mlkem_sharedkey_wr_ctrl.hmac_key_dest_valid.swwe) begin // SW write + next_c = (field_storage.kv_mlkem_sharedkey_wr_ctrl.hmac_key_dest_valid.value & ~decoded_wr_biten[6:6]) | (decoded_wr_data[6:6] & decoded_wr_biten[6:6]); + load_next_c = '1; + end + field_combo.kv_mlkem_sharedkey_wr_ctrl.hmac_key_dest_valid.next = next_c; + field_combo.kv_mlkem_sharedkey_wr_ctrl.hmac_key_dest_valid.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.kv_mlkem_sharedkey_wr_ctrl.hmac_key_dest_valid.value <= 1'h0; + end else if(field_combo.kv_mlkem_sharedkey_wr_ctrl.hmac_key_dest_valid.load_next) begin + field_storage.kv_mlkem_sharedkey_wr_ctrl.hmac_key_dest_valid.value <= field_combo.kv_mlkem_sharedkey_wr_ctrl.hmac_key_dest_valid.next; + end + end + assign hwif_out.kv_mlkem_sharedkey_wr_ctrl.hmac_key_dest_valid.value = field_storage.kv_mlkem_sharedkey_wr_ctrl.hmac_key_dest_valid.value; + // Field: abr_reg.kv_mlkem_sharedkey_wr_ctrl.hmac_block_dest_valid + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.kv_mlkem_sharedkey_wr_ctrl.hmac_block_dest_valid.value; + load_next_c = '0; + if(decoded_reg_strb.kv_mlkem_sharedkey_wr_ctrl && decoded_req_is_wr && hwif_in.kv_mlkem_sharedkey_wr_ctrl.hmac_block_dest_valid.swwe) begin // SW write + next_c = (field_storage.kv_mlkem_sharedkey_wr_ctrl.hmac_block_dest_valid.value & ~decoded_wr_biten[7:7]) | (decoded_wr_data[7:7] & decoded_wr_biten[7:7]); + load_next_c = '1; + end + field_combo.kv_mlkem_sharedkey_wr_ctrl.hmac_block_dest_valid.next = next_c; + field_combo.kv_mlkem_sharedkey_wr_ctrl.hmac_block_dest_valid.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.kv_mlkem_sharedkey_wr_ctrl.hmac_block_dest_valid.value <= 1'h0; + end else if(field_combo.kv_mlkem_sharedkey_wr_ctrl.hmac_block_dest_valid.load_next) begin + field_storage.kv_mlkem_sharedkey_wr_ctrl.hmac_block_dest_valid.value <= field_combo.kv_mlkem_sharedkey_wr_ctrl.hmac_block_dest_valid.next; + end + end + assign hwif_out.kv_mlkem_sharedkey_wr_ctrl.hmac_block_dest_valid.value = field_storage.kv_mlkem_sharedkey_wr_ctrl.hmac_block_dest_valid.value; + // Field: abr_reg.kv_mlkem_sharedkey_wr_ctrl.mldsa_seed_dest_valid + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.kv_mlkem_sharedkey_wr_ctrl.mldsa_seed_dest_valid.value; + load_next_c = '0; + if(decoded_reg_strb.kv_mlkem_sharedkey_wr_ctrl && decoded_req_is_wr && hwif_in.kv_mlkem_sharedkey_wr_ctrl.mldsa_seed_dest_valid.swwe) begin // SW write + next_c = (field_storage.kv_mlkem_sharedkey_wr_ctrl.mldsa_seed_dest_valid.value & ~decoded_wr_biten[8:8]) | (decoded_wr_data[8:8] & decoded_wr_biten[8:8]); + load_next_c = '1; + end + field_combo.kv_mlkem_sharedkey_wr_ctrl.mldsa_seed_dest_valid.next = next_c; + field_combo.kv_mlkem_sharedkey_wr_ctrl.mldsa_seed_dest_valid.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.kv_mlkem_sharedkey_wr_ctrl.mldsa_seed_dest_valid.value <= 1'h0; + end else if(field_combo.kv_mlkem_sharedkey_wr_ctrl.mldsa_seed_dest_valid.load_next) begin + field_storage.kv_mlkem_sharedkey_wr_ctrl.mldsa_seed_dest_valid.value <= field_combo.kv_mlkem_sharedkey_wr_ctrl.mldsa_seed_dest_valid.next; + end + end + assign hwif_out.kv_mlkem_sharedkey_wr_ctrl.mldsa_seed_dest_valid.value = field_storage.kv_mlkem_sharedkey_wr_ctrl.mldsa_seed_dest_valid.value; + // Field: abr_reg.kv_mlkem_sharedkey_wr_ctrl.ecc_pkey_dest_valid + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.kv_mlkem_sharedkey_wr_ctrl.ecc_pkey_dest_valid.value; + load_next_c = '0; + if(decoded_reg_strb.kv_mlkem_sharedkey_wr_ctrl && decoded_req_is_wr && hwif_in.kv_mlkem_sharedkey_wr_ctrl.ecc_pkey_dest_valid.swwe) begin // SW write + next_c = (field_storage.kv_mlkem_sharedkey_wr_ctrl.ecc_pkey_dest_valid.value & ~decoded_wr_biten[9:9]) | (decoded_wr_data[9:9] & decoded_wr_biten[9:9]); + load_next_c = '1; + end + field_combo.kv_mlkem_sharedkey_wr_ctrl.ecc_pkey_dest_valid.next = next_c; + field_combo.kv_mlkem_sharedkey_wr_ctrl.ecc_pkey_dest_valid.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.kv_mlkem_sharedkey_wr_ctrl.ecc_pkey_dest_valid.value <= 1'h0; + end else if(field_combo.kv_mlkem_sharedkey_wr_ctrl.ecc_pkey_dest_valid.load_next) begin + field_storage.kv_mlkem_sharedkey_wr_ctrl.ecc_pkey_dest_valid.value <= field_combo.kv_mlkem_sharedkey_wr_ctrl.ecc_pkey_dest_valid.next; + end + end + assign hwif_out.kv_mlkem_sharedkey_wr_ctrl.ecc_pkey_dest_valid.value = field_storage.kv_mlkem_sharedkey_wr_ctrl.ecc_pkey_dest_valid.value; + // Field: abr_reg.kv_mlkem_sharedkey_wr_ctrl.ecc_seed_dest_valid + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.kv_mlkem_sharedkey_wr_ctrl.ecc_seed_dest_valid.value; + load_next_c = '0; + if(decoded_reg_strb.kv_mlkem_sharedkey_wr_ctrl && decoded_req_is_wr && hwif_in.kv_mlkem_sharedkey_wr_ctrl.ecc_seed_dest_valid.swwe) begin // SW write + next_c = (field_storage.kv_mlkem_sharedkey_wr_ctrl.ecc_seed_dest_valid.value & ~decoded_wr_biten[10:10]) | (decoded_wr_data[10:10] & decoded_wr_biten[10:10]); + load_next_c = '1; + end + field_combo.kv_mlkem_sharedkey_wr_ctrl.ecc_seed_dest_valid.next = next_c; + field_combo.kv_mlkem_sharedkey_wr_ctrl.ecc_seed_dest_valid.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.kv_mlkem_sharedkey_wr_ctrl.ecc_seed_dest_valid.value <= 1'h0; + end else if(field_combo.kv_mlkem_sharedkey_wr_ctrl.ecc_seed_dest_valid.load_next) begin + field_storage.kv_mlkem_sharedkey_wr_ctrl.ecc_seed_dest_valid.value <= field_combo.kv_mlkem_sharedkey_wr_ctrl.ecc_seed_dest_valid.next; + end + end + assign hwif_out.kv_mlkem_sharedkey_wr_ctrl.ecc_seed_dest_valid.value = field_storage.kv_mlkem_sharedkey_wr_ctrl.ecc_seed_dest_valid.value; + // Field: abr_reg.kv_mlkem_sharedkey_wr_ctrl.aes_key_dest_valid + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.kv_mlkem_sharedkey_wr_ctrl.aes_key_dest_valid.value; + load_next_c = '0; + if(decoded_reg_strb.kv_mlkem_sharedkey_wr_ctrl && decoded_req_is_wr && hwif_in.kv_mlkem_sharedkey_wr_ctrl.aes_key_dest_valid.swwe) begin // SW write + next_c = (field_storage.kv_mlkem_sharedkey_wr_ctrl.aes_key_dest_valid.value & ~decoded_wr_biten[11:11]) | (decoded_wr_data[11:11] & decoded_wr_biten[11:11]); + load_next_c = '1; + end + field_combo.kv_mlkem_sharedkey_wr_ctrl.aes_key_dest_valid.next = next_c; + field_combo.kv_mlkem_sharedkey_wr_ctrl.aes_key_dest_valid.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.kv_mlkem_sharedkey_wr_ctrl.aes_key_dest_valid.value <= 1'h0; + end else if(field_combo.kv_mlkem_sharedkey_wr_ctrl.aes_key_dest_valid.load_next) begin + field_storage.kv_mlkem_sharedkey_wr_ctrl.aes_key_dest_valid.value <= field_combo.kv_mlkem_sharedkey_wr_ctrl.aes_key_dest_valid.next; + end + end + assign hwif_out.kv_mlkem_sharedkey_wr_ctrl.aes_key_dest_valid.value = field_storage.kv_mlkem_sharedkey_wr_ctrl.aes_key_dest_valid.value; + // Field: abr_reg.kv_mlkem_sharedkey_wr_ctrl.mlkem_seed_dest_valid + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.kv_mlkem_sharedkey_wr_ctrl.mlkem_seed_dest_valid.value; + load_next_c = '0; + if(decoded_reg_strb.kv_mlkem_sharedkey_wr_ctrl && decoded_req_is_wr && hwif_in.kv_mlkem_sharedkey_wr_ctrl.mlkem_seed_dest_valid.swwe) begin // SW write + next_c = (field_storage.kv_mlkem_sharedkey_wr_ctrl.mlkem_seed_dest_valid.value & ~decoded_wr_biten[12:12]) | (decoded_wr_data[12:12] & decoded_wr_biten[12:12]); + load_next_c = '1; + end + field_combo.kv_mlkem_sharedkey_wr_ctrl.mlkem_seed_dest_valid.next = next_c; + field_combo.kv_mlkem_sharedkey_wr_ctrl.mlkem_seed_dest_valid.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.kv_mlkem_sharedkey_wr_ctrl.mlkem_seed_dest_valid.value <= 1'h0; + end else if(field_combo.kv_mlkem_sharedkey_wr_ctrl.mlkem_seed_dest_valid.load_next) begin + field_storage.kv_mlkem_sharedkey_wr_ctrl.mlkem_seed_dest_valid.value <= field_combo.kv_mlkem_sharedkey_wr_ctrl.mlkem_seed_dest_valid.next; + end + end + assign hwif_out.kv_mlkem_sharedkey_wr_ctrl.mlkem_seed_dest_valid.value = field_storage.kv_mlkem_sharedkey_wr_ctrl.mlkem_seed_dest_valid.value; + // Field: abr_reg.kv_mlkem_sharedkey_wr_ctrl.mlkem_msg_dest_valid + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.kv_mlkem_sharedkey_wr_ctrl.mlkem_msg_dest_valid.value; + load_next_c = '0; + if(decoded_reg_strb.kv_mlkem_sharedkey_wr_ctrl && decoded_req_is_wr && hwif_in.kv_mlkem_sharedkey_wr_ctrl.mlkem_msg_dest_valid.swwe) begin // SW write + next_c = (field_storage.kv_mlkem_sharedkey_wr_ctrl.mlkem_msg_dest_valid.value & ~decoded_wr_biten[13:13]) | (decoded_wr_data[13:13] & decoded_wr_biten[13:13]); + load_next_c = '1; + end + field_combo.kv_mlkem_sharedkey_wr_ctrl.mlkem_msg_dest_valid.next = next_c; + field_combo.kv_mlkem_sharedkey_wr_ctrl.mlkem_msg_dest_valid.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.kv_mlkem_sharedkey_wr_ctrl.mlkem_msg_dest_valid.value <= 1'h0; + end else if(field_combo.kv_mlkem_sharedkey_wr_ctrl.mlkem_msg_dest_valid.load_next) begin + field_storage.kv_mlkem_sharedkey_wr_ctrl.mlkem_msg_dest_valid.value <= field_combo.kv_mlkem_sharedkey_wr_ctrl.mlkem_msg_dest_valid.next; + end + end + assign hwif_out.kv_mlkem_sharedkey_wr_ctrl.mlkem_msg_dest_valid.value = field_storage.kv_mlkem_sharedkey_wr_ctrl.mlkem_msg_dest_valid.value; + // Field: abr_reg.kv_mlkem_sharedkey_wr_ctrl.dma_data_dest_valid + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.kv_mlkem_sharedkey_wr_ctrl.dma_data_dest_valid.value; + load_next_c = '0; + if(decoded_reg_strb.kv_mlkem_sharedkey_wr_ctrl && decoded_req_is_wr && hwif_in.kv_mlkem_sharedkey_wr_ctrl.dma_data_dest_valid.swwe) begin // SW write + next_c = (field_storage.kv_mlkem_sharedkey_wr_ctrl.dma_data_dest_valid.value & ~decoded_wr_biten[14:14]) | (decoded_wr_data[14:14] & decoded_wr_biten[14:14]); + load_next_c = '1; + end + field_combo.kv_mlkem_sharedkey_wr_ctrl.dma_data_dest_valid.next = next_c; + field_combo.kv_mlkem_sharedkey_wr_ctrl.dma_data_dest_valid.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.kv_mlkem_sharedkey_wr_ctrl.dma_data_dest_valid.value <= 1'h0; + end else if(field_combo.kv_mlkem_sharedkey_wr_ctrl.dma_data_dest_valid.load_next) begin + field_storage.kv_mlkem_sharedkey_wr_ctrl.dma_data_dest_valid.value <= field_combo.kv_mlkem_sharedkey_wr_ctrl.dma_data_dest_valid.next; + end + end + assign hwif_out.kv_mlkem_sharedkey_wr_ctrl.dma_data_dest_valid.value = field_storage.kv_mlkem_sharedkey_wr_ctrl.dma_data_dest_valid.value; + // Field: abr_reg.kv_mlkem_sharedkey_wr_ctrl.rsvd + always_comb begin + automatic logic [16:0] next_c; + automatic logic load_next_c; + next_c = field_storage.kv_mlkem_sharedkey_wr_ctrl.rsvd.value; + load_next_c = '0; + if(decoded_reg_strb.kv_mlkem_sharedkey_wr_ctrl && decoded_req_is_wr && hwif_in.kv_mlkem_sharedkey_wr_ctrl.rsvd.swwe) begin // SW write + next_c = (field_storage.kv_mlkem_sharedkey_wr_ctrl.rsvd.value & ~decoded_wr_biten[31:15]) | (decoded_wr_data[31:15] & decoded_wr_biten[31:15]); + load_next_c = '1; + end + field_combo.kv_mlkem_sharedkey_wr_ctrl.rsvd.next = next_c; + field_combo.kv_mlkem_sharedkey_wr_ctrl.rsvd.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.kv_mlkem_sharedkey_wr_ctrl.rsvd.value <= 17'h0; + end else if(field_combo.kv_mlkem_sharedkey_wr_ctrl.rsvd.load_next) begin + field_storage.kv_mlkem_sharedkey_wr_ctrl.rsvd.value <= field_combo.kv_mlkem_sharedkey_wr_ctrl.rsvd.next; + end + end + assign hwif_out.kv_mlkem_sharedkey_wr_ctrl.rsvd.value = field_storage.kv_mlkem_sharedkey_wr_ctrl.rsvd.value; + // Field: abr_reg.kv_mlkem_sharedkey_wr_status.VALID + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.kv_mlkem_sharedkey_wr_status.VALID.value; + load_next_c = '0; + if(hwif_in.kv_mlkem_sharedkey_wr_status.VALID.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end else if(hwif_in.kv_mlkem_sharedkey_wr_status.VALID.hwclr) begin // HW Clear + next_c = '0; + load_next_c = '1; + end + field_combo.kv_mlkem_sharedkey_wr_status.VALID.next = next_c; + field_combo.kv_mlkem_sharedkey_wr_status.VALID.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.kv_mlkem_sharedkey_wr_status.VALID.value <= 1'h0; + end else if(field_combo.kv_mlkem_sharedkey_wr_status.VALID.load_next) begin + field_storage.kv_mlkem_sharedkey_wr_status.VALID.value <= field_combo.kv_mlkem_sharedkey_wr_status.VALID.next; + end + end + + //-------------------------------------------------------------------------- + // Write response + //-------------------------------------------------------------------------- + always_comb begin + automatic logic wr_ack; + wr_ack = '0; + wr_ack |= hwif_in.MLDSA_PUBKEY.wr_ack; + wr_ack |= hwif_in.MLDSA_SIGNATURE.wr_ack; + wr_ack |= hwif_in.MLDSA_PRIVKEY_OUT.wr_ack; + wr_ack |= hwif_in.MLDSA_PRIVKEY_IN.wr_ack; + for(int i0=0; i0<8; i0++) begin + wr_ack |= hwif_in.MLKEM_SEED_Z[i0].wr_ack; + end + wr_ack |= hwif_in.MLKEM_MSG.wr_ack; + wr_ack |= hwif_in.MLKEM_DECAPS_KEY.wr_ack; + wr_ack |= hwif_in.MLKEM_ENCAPS_KEY.wr_ack; + wr_ack |= hwif_in.MLKEM_CIPHERTEXT.wr_ack; + external_wr_ack = wr_ack; + end + assign cpuif_wr_ack = external_wr_ack | (decoded_req & decoded_req_is_wr & ~decoded_strb_is_external); + // Writes are always granted with no error response + assign cpuif_wr_err = '0; + + //-------------------------------------------------------------------------- + // Readback + //-------------------------------------------------------------------------- + logic readback_external_rd_ack_c; + always_comb begin + automatic logic rd_ack; + rd_ack = '0; + rd_ack |= hwif_in.MLDSA_PUBKEY.rd_ack; + rd_ack |= hwif_in.MLDSA_SIGNATURE.rd_ack; + rd_ack |= hwif_in.MLDSA_PRIVKEY_OUT.rd_ack; + rd_ack |= hwif_in.MLDSA_PRIVKEY_IN.rd_ack; + for(int i0=0; i0<8; i0++) begin + rd_ack |= hwif_in.MLKEM_SHARED_KEY[i0].rd_ack; + end + rd_ack |= hwif_in.MLKEM_MSG.rd_ack; + rd_ack |= hwif_in.MLKEM_DECAPS_KEY.rd_ack; + rd_ack |= hwif_in.MLKEM_ENCAPS_KEY.rd_ack; + rd_ack |= hwif_in.MLKEM_CIPHERTEXT.rd_ack; + readback_external_rd_ack_c = rd_ack; + end + + logic readback_external_rd_ack; + + assign readback_external_rd_ack = readback_external_rd_ack_c; + + logic readback_err; + logic readback_done; + logic [31:0] readback_data; + + // Assign readback values to a flattened array + logic [63-1:0][31:0] readback_array; + for(genvar i0=0; i0<2; i0++) begin + assign readback_array[i0*1 + 0][31:0] = (decoded_reg_strb.MLDSA_NAME[i0] && !decoded_req_is_wr) ? hwif_in.MLDSA_NAME[i0].NAME.next : '0; + end + for(genvar i0=0; i0<2; i0++) begin + assign readback_array[i0*1 + 2][31:0] = (decoded_reg_strb.MLDSA_VERSION[i0] && !decoded_req_is_wr) ? hwif_in.MLDSA_VERSION[i0].VERSION.next : '0; + end + assign readback_array[4][0:0] = (decoded_reg_strb.MLDSA_STATUS && !decoded_req_is_wr) ? hwif_in.MLDSA_STATUS.READY.next : '0; + assign readback_array[4][1:1] = (decoded_reg_strb.MLDSA_STATUS && !decoded_req_is_wr) ? field_storage.MLDSA_STATUS.VALID.value : '0; + assign readback_array[4][2:2] = (decoded_reg_strb.MLDSA_STATUS && !decoded_req_is_wr) ? hwif_in.MLDSA_STATUS.MSG_STREAM_READY.next : '0; + assign readback_array[4][3:3] = (decoded_reg_strb.MLDSA_STATUS && !decoded_req_is_wr) ? field_storage.MLDSA_STATUS.ERROR.value : '0; + assign readback_array[4][31:4] = '0; + for(genvar i0=0; i0<16; i0++) begin + assign readback_array[i0*1 + 5][31:0] = (decoded_reg_strb.MLDSA_VERIFY_RES[i0] && !decoded_req_is_wr) ? field_storage.MLDSA_VERIFY_RES[i0].VERIFY_RES.value : '0; + end + assign readback_array[21] = hwif_in.MLDSA_PUBKEY.rd_ack ? hwif_in.MLDSA_PUBKEY.rd_data : '0; + assign readback_array[22] = hwif_in.MLDSA_SIGNATURE.rd_ack ? hwif_in.MLDSA_SIGNATURE.rd_data : '0; + assign readback_array[23] = hwif_in.MLDSA_PRIVKEY_OUT.rd_ack ? hwif_in.MLDSA_PRIVKEY_OUT.rd_data : '0; + assign readback_array[24] = hwif_in.MLDSA_PRIVKEY_IN.rd_ack ? hwif_in.MLDSA_PRIVKEY_IN.rd_data : '0; + assign readback_array[25][0:0] = (decoded_reg_strb.kv_mldsa_seed_rd_ctrl && !decoded_req_is_wr) ? field_storage.kv_mldsa_seed_rd_ctrl.read_en.value : '0; + assign readback_array[25][5:1] = (decoded_reg_strb.kv_mldsa_seed_rd_ctrl && !decoded_req_is_wr) ? field_storage.kv_mldsa_seed_rd_ctrl.read_entry.value : '0; + assign readback_array[25][6:6] = (decoded_reg_strb.kv_mldsa_seed_rd_ctrl && !decoded_req_is_wr) ? field_storage.kv_mldsa_seed_rd_ctrl.pcr_hash_extend.value : '0; + assign readback_array[25][31:7] = (decoded_reg_strb.kv_mldsa_seed_rd_ctrl && !decoded_req_is_wr) ? field_storage.kv_mldsa_seed_rd_ctrl.rsvd.value : '0; + assign readback_array[26][0:0] = (decoded_reg_strb.kv_mldsa_seed_rd_status && !decoded_req_is_wr) ? hwif_in.kv_mldsa_seed_rd_status.READY.next : '0; + assign readback_array[26][1:1] = (decoded_reg_strb.kv_mldsa_seed_rd_status && !decoded_req_is_wr) ? field_storage.kv_mldsa_seed_rd_status.VALID.value : '0; + assign readback_array[26][9:2] = (decoded_reg_strb.kv_mldsa_seed_rd_status && !decoded_req_is_wr) ? hwif_in.kv_mldsa_seed_rd_status.ERROR.next : '0; + assign readback_array[26][31:10] = '0; + assign readback_array[27][0:0] = (decoded_reg_strb.intr_block_rf.global_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.global_intr_en_r.error_en.value : '0; + assign readback_array[27][1:1] = (decoded_reg_strb.intr_block_rf.global_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.global_intr_en_r.notif_en.value : '0; + assign readback_array[27][31:2] = '0; + assign readback_array[28][0:0] = (decoded_reg_strb.intr_block_rf.error_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_en_r.error_internal_en.value : '0; + assign readback_array[28][31:1] = '0; + assign readback_array[29][0:0] = (decoded_reg_strb.intr_block_rf.notif_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_intr_en_r.notif_cmd_done_en.value : '0; + assign readback_array[29][31:1] = '0; + assign readback_array[30][0:0] = (decoded_reg_strb.intr_block_rf.error_global_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_global_intr_r.agg_sts.value : '0; + assign readback_array[30][31:1] = '0; + assign readback_array[31][0:0] = (decoded_reg_strb.intr_block_rf.notif_global_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_global_intr_r.agg_sts.value : '0; + assign readback_array[31][31:1] = '0; + assign readback_array[32][0:0] = (decoded_reg_strb.intr_block_rf.error_internal_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_internal_intr_r.error_internal_sts.value : '0; + assign readback_array[32][31:1] = '0; + assign readback_array[33][0:0] = (decoded_reg_strb.intr_block_rf.notif_internal_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.value : '0; + assign readback_array[33][31:1] = '0; + assign readback_array[34][0:0] = (decoded_reg_strb.intr_block_rf.error_intr_trig_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_trig_r.error_internal_trig.value : '0; + assign readback_array[34][31:1] = '0; + assign readback_array[35][0:0] = (decoded_reg_strb.intr_block_rf.notif_intr_trig_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.value : '0; + assign readback_array[35][31:1] = '0; + assign readback_array[36][31:0] = (decoded_reg_strb.intr_block_rf.error_internal_intr_count_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_internal_intr_count_r.cnt.value : '0; + assign readback_array[37][31:0] = (decoded_reg_strb.intr_block_rf.notif_cmd_done_intr_count_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_cmd_done_intr_count_r.cnt.value : '0; + assign readback_array[38][0:0] = (decoded_reg_strb.intr_block_rf.error_internal_intr_count_incr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_internal_intr_count_incr_r.pulse.value : '0; + assign readback_array[38][31:1] = '0; + assign readback_array[39][0:0] = (decoded_reg_strb.intr_block_rf.notif_cmd_done_intr_count_incr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.value : '0; + assign readback_array[39][31:1] = '0; + for(genvar i0=0; i0<2; i0++) begin + assign readback_array[i0*1 + 40][31:0] = (decoded_reg_strb.MLKEM_NAME[i0] && !decoded_req_is_wr) ? hwif_in.MLKEM_NAME[i0].NAME.next : '0; + end + for(genvar i0=0; i0<2; i0++) begin + assign readback_array[i0*1 + 42][31:0] = (decoded_reg_strb.MLKEM_VERSION[i0] && !decoded_req_is_wr) ? hwif_in.MLKEM_VERSION[i0].VERSION.next : '0; + end + assign readback_array[44][0:0] = (decoded_reg_strb.MLKEM_STATUS && !decoded_req_is_wr) ? hwif_in.MLKEM_STATUS.READY.next : '0; + assign readback_array[44][1:1] = (decoded_reg_strb.MLKEM_STATUS && !decoded_req_is_wr) ? field_storage.MLKEM_STATUS.VALID.value : '0; + assign readback_array[44][2:2] = (decoded_reg_strb.MLKEM_STATUS && !decoded_req_is_wr) ? field_storage.MLKEM_STATUS.ERROR.value : '0; + assign readback_array[44][31:3] = '0; + for(genvar i0=0; i0<8; i0++) begin + assign readback_array[i0*1 + 45] = hwif_in.MLKEM_SHARED_KEY[i0].rd_ack ? hwif_in.MLKEM_SHARED_KEY[i0].rd_data : '0; + end + assign readback_array[53] = hwif_in.MLKEM_MSG.rd_ack ? hwif_in.MLKEM_MSG.rd_data : '0; + assign readback_array[54] = hwif_in.MLKEM_DECAPS_KEY.rd_ack ? hwif_in.MLKEM_DECAPS_KEY.rd_data : '0; + assign readback_array[55] = hwif_in.MLKEM_ENCAPS_KEY.rd_ack ? hwif_in.MLKEM_ENCAPS_KEY.rd_data : '0; + assign readback_array[56] = hwif_in.MLKEM_CIPHERTEXT.rd_ack ? hwif_in.MLKEM_CIPHERTEXT.rd_data : '0; + assign readback_array[57][0:0] = (decoded_reg_strb.kv_mlkem_seed_rd_ctrl && !decoded_req_is_wr) ? field_storage.kv_mlkem_seed_rd_ctrl.read_en.value : '0; + assign readback_array[57][5:1] = (decoded_reg_strb.kv_mlkem_seed_rd_ctrl && !decoded_req_is_wr) ? field_storage.kv_mlkem_seed_rd_ctrl.read_entry.value : '0; + assign readback_array[57][6:6] = (decoded_reg_strb.kv_mlkem_seed_rd_ctrl && !decoded_req_is_wr) ? field_storage.kv_mlkem_seed_rd_ctrl.pcr_hash_extend.value : '0; + assign readback_array[57][31:7] = (decoded_reg_strb.kv_mlkem_seed_rd_ctrl && !decoded_req_is_wr) ? field_storage.kv_mlkem_seed_rd_ctrl.rsvd.value : '0; + assign readback_array[58][0:0] = (decoded_reg_strb.kv_mlkem_seed_rd_status && !decoded_req_is_wr) ? hwif_in.kv_mlkem_seed_rd_status.READY.next : '0; + assign readback_array[58][1:1] = (decoded_reg_strb.kv_mlkem_seed_rd_status && !decoded_req_is_wr) ? field_storage.kv_mlkem_seed_rd_status.VALID.value : '0; + assign readback_array[58][9:2] = (decoded_reg_strb.kv_mlkem_seed_rd_status && !decoded_req_is_wr) ? hwif_in.kv_mlkem_seed_rd_status.ERROR.next : '0; + assign readback_array[58][31:10] = '0; + assign readback_array[59][0:0] = (decoded_reg_strb.kv_mlkem_msg_rd_ctrl && !decoded_req_is_wr) ? field_storage.kv_mlkem_msg_rd_ctrl.read_en.value : '0; + assign readback_array[59][5:1] = (decoded_reg_strb.kv_mlkem_msg_rd_ctrl && !decoded_req_is_wr) ? field_storage.kv_mlkem_msg_rd_ctrl.read_entry.value : '0; + assign readback_array[59][6:6] = (decoded_reg_strb.kv_mlkem_msg_rd_ctrl && !decoded_req_is_wr) ? field_storage.kv_mlkem_msg_rd_ctrl.pcr_hash_extend.value : '0; + assign readback_array[59][31:7] = (decoded_reg_strb.kv_mlkem_msg_rd_ctrl && !decoded_req_is_wr) ? field_storage.kv_mlkem_msg_rd_ctrl.rsvd.value : '0; + assign readback_array[60][0:0] = (decoded_reg_strb.kv_mlkem_msg_rd_status && !decoded_req_is_wr) ? hwif_in.kv_mlkem_msg_rd_status.READY.next : '0; + assign readback_array[60][1:1] = (decoded_reg_strb.kv_mlkem_msg_rd_status && !decoded_req_is_wr) ? field_storage.kv_mlkem_msg_rd_status.VALID.value : '0; + assign readback_array[60][9:2] = (decoded_reg_strb.kv_mlkem_msg_rd_status && !decoded_req_is_wr) ? hwif_in.kv_mlkem_msg_rd_status.ERROR.next : '0; + assign readback_array[60][31:10] = '0; + assign readback_array[61][0:0] = (decoded_reg_strb.kv_mlkem_sharedkey_wr_ctrl && !decoded_req_is_wr) ? field_storage.kv_mlkem_sharedkey_wr_ctrl.write_en.value : '0; + assign readback_array[61][5:1] = (decoded_reg_strb.kv_mlkem_sharedkey_wr_ctrl && !decoded_req_is_wr) ? field_storage.kv_mlkem_sharedkey_wr_ctrl.write_entry.value : '0; + assign readback_array[61][6:6] = (decoded_reg_strb.kv_mlkem_sharedkey_wr_ctrl && !decoded_req_is_wr) ? field_storage.kv_mlkem_sharedkey_wr_ctrl.hmac_key_dest_valid.value : '0; + assign readback_array[61][7:7] = (decoded_reg_strb.kv_mlkem_sharedkey_wr_ctrl && !decoded_req_is_wr) ? field_storage.kv_mlkem_sharedkey_wr_ctrl.hmac_block_dest_valid.value : '0; + assign readback_array[61][8:8] = (decoded_reg_strb.kv_mlkem_sharedkey_wr_ctrl && !decoded_req_is_wr) ? field_storage.kv_mlkem_sharedkey_wr_ctrl.mldsa_seed_dest_valid.value : '0; + assign readback_array[61][9:9] = (decoded_reg_strb.kv_mlkem_sharedkey_wr_ctrl && !decoded_req_is_wr) ? field_storage.kv_mlkem_sharedkey_wr_ctrl.ecc_pkey_dest_valid.value : '0; + assign readback_array[61][10:10] = (decoded_reg_strb.kv_mlkem_sharedkey_wr_ctrl && !decoded_req_is_wr) ? field_storage.kv_mlkem_sharedkey_wr_ctrl.ecc_seed_dest_valid.value : '0; + assign readback_array[61][11:11] = (decoded_reg_strb.kv_mlkem_sharedkey_wr_ctrl && !decoded_req_is_wr) ? field_storage.kv_mlkem_sharedkey_wr_ctrl.aes_key_dest_valid.value : '0; + assign readback_array[61][12:12] = (decoded_reg_strb.kv_mlkem_sharedkey_wr_ctrl && !decoded_req_is_wr) ? field_storage.kv_mlkem_sharedkey_wr_ctrl.mlkem_seed_dest_valid.value : '0; + assign readback_array[61][13:13] = (decoded_reg_strb.kv_mlkem_sharedkey_wr_ctrl && !decoded_req_is_wr) ? field_storage.kv_mlkem_sharedkey_wr_ctrl.mlkem_msg_dest_valid.value : '0; + assign readback_array[61][14:14] = (decoded_reg_strb.kv_mlkem_sharedkey_wr_ctrl && !decoded_req_is_wr) ? field_storage.kv_mlkem_sharedkey_wr_ctrl.dma_data_dest_valid.value : '0; + assign readback_array[61][31:15] = (decoded_reg_strb.kv_mlkem_sharedkey_wr_ctrl && !decoded_req_is_wr) ? field_storage.kv_mlkem_sharedkey_wr_ctrl.rsvd.value : '0; + assign readback_array[62][0:0] = (decoded_reg_strb.kv_mlkem_sharedkey_wr_status && !decoded_req_is_wr) ? hwif_in.kv_mlkem_sharedkey_wr_status.READY.next : '0; + assign readback_array[62][1:1] = (decoded_reg_strb.kv_mlkem_sharedkey_wr_status && !decoded_req_is_wr) ? field_storage.kv_mlkem_sharedkey_wr_status.VALID.value : '0; + assign readback_array[62][9:2] = (decoded_reg_strb.kv_mlkem_sharedkey_wr_status && !decoded_req_is_wr) ? hwif_in.kv_mlkem_sharedkey_wr_status.ERROR.next : '0; + assign readback_array[62][31:10] = '0; + + // Reduce the array + always_comb begin + automatic logic [31:0] readback_data_var; + readback_done = decoded_req & ~decoded_req_is_wr & ~decoded_strb_is_external; + readback_err = '0; + readback_data_var = '0; + for(int i=0; i<63; i++) readback_data_var |= readback_array[i]; + readback_data = readback_data_var; + end + + assign external_rd_ack = readback_external_rd_ack; + assign cpuif_rd_ack = readback_done | readback_external_rd_ack; + assign cpuif_rd_data = readback_data; + assign cpuif_rd_err = readback_err; + +`ABR_ASSERT_KNOWN(ERR_HWIF_IN, hwif_in, clk, !hwif_in.hard_reset_b) + +endmodule diff --git a/designs/Caliptra/src/adams-bridge/abr_reg_pkg.sv b/designs/Caliptra/src/adams-bridge/abr_reg_pkg.sv new file mode 100644 index 0000000..3c6452f --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/abr_reg_pkg.sv @@ -0,0 +1,808 @@ +// Generated by PeakRDL-regblock - A free and open-source SystemVerilog generator +// https://github.com/SystemRDL/PeakRDL-regblock + +package abr_reg_pkg; + + localparam ABR_REG_DATA_WIDTH = 32; + localparam ABR_REG_MIN_ADDR_WIDTH = 16; + + typedef struct packed{ + logic [31:0] next; + } abr_reg__MLDSA_NAME__NAME__in_t; + + typedef struct packed{ + abr_reg__MLDSA_NAME__NAME__in_t NAME; + } abr_reg__MLDSA_NAME__in_t; + + typedef struct packed{ + logic [31:0] next; + } abr_reg__MLDSA_VERSION__VERSION__in_t; + + typedef struct packed{ + abr_reg__MLDSA_VERSION__VERSION__in_t VERSION; + } abr_reg__MLDSA_VERSION__in_t; + + typedef struct packed{ + logic hwclr; + } abr_reg__MLDSA_CTRL__CTRL__in_t; + + typedef struct packed{ + logic hwclr; + } abr_reg__MLDSA_CTRL__PCR_SIGN__in_t; + + typedef struct packed{ + logic hwclr; + } abr_reg__MLDSA_CTRL__EXTERNAL_MU__in_t; + + typedef struct packed{ + logic hwclr; + } abr_reg__MLDSA_CTRL__STREAM_MSG__in_t; + + typedef struct packed{ + abr_reg__MLDSA_CTRL__CTRL__in_t CTRL; + abr_reg__MLDSA_CTRL__PCR_SIGN__in_t PCR_SIGN; + abr_reg__MLDSA_CTRL__EXTERNAL_MU__in_t EXTERNAL_MU; + abr_reg__MLDSA_CTRL__STREAM_MSG__in_t STREAM_MSG; + } abr_reg__MLDSA_CTRL__in_t; + + typedef struct packed{ + logic next; + } abr_reg__MLDSA_STATUS__READY__in_t; + + typedef struct packed{ + logic next; + } abr_reg__MLDSA_STATUS__VALID__in_t; + + typedef struct packed{ + logic next; + } abr_reg__MLDSA_STATUS__MSG_STREAM_READY__in_t; + + typedef struct packed{ + logic next; + } abr_reg__MLDSA_STATUS__ERROR__in_t; + + typedef struct packed{ + abr_reg__MLDSA_STATUS__READY__in_t READY; + abr_reg__MLDSA_STATUS__VALID__in_t VALID; + abr_reg__MLDSA_STATUS__MSG_STREAM_READY__in_t MSG_STREAM_READY; + abr_reg__MLDSA_STATUS__ERROR__in_t ERROR; + } abr_reg__MLDSA_STATUS__in_t; + + typedef struct packed{ + logic hwclr; + } abr_reg__ABR_ENTROPY__ENTROPY__in_t; + + typedef struct packed{ + abr_reg__ABR_ENTROPY__ENTROPY__in_t ENTROPY; + } abr_reg__ABR_ENTROPY__in_t; + + typedef struct packed{ + logic [31:0] next; + logic we; + logic swwe; + logic hwclr; + } abr_reg__MLDSA_SEED__SEED__in_t; + + typedef struct packed{ + abr_reg__MLDSA_SEED__SEED__in_t SEED; + } abr_reg__MLDSA_SEED__in_t; + + typedef struct packed{ + logic hwclr; + } abr_reg__MLDSA_SIGN_RND__SIGN_RND__in_t; + + typedef struct packed{ + abr_reg__MLDSA_SIGN_RND__SIGN_RND__in_t SIGN_RND; + } abr_reg__MLDSA_SIGN_RND__in_t; + + typedef struct packed{ + logic [31:0] next; + logic we; + logic swwe; + logic hwclr; + } abr_reg__MLDSA_MSG__MSG__in_t; + + typedef struct packed{ + abr_reg__MLDSA_MSG__MSG__in_t MSG; + } abr_reg__MLDSA_MSG__in_t; + + typedef struct packed{ + logic [31:0] next; + logic we; + logic hwclr; + } abr_reg__MLDSA_VERIFY_RES__VERIFY_RES__in_t; + + typedef struct packed{ + abr_reg__MLDSA_VERIFY_RES__VERIFY_RES__in_t VERIFY_RES; + } abr_reg__MLDSA_VERIFY_RES__in_t; + + typedef struct packed{ + logic [31:0] next; + logic we; + logic hwclr; + } abr_reg__MLDSA_EXTERNAL_MU__EXTERNAL_MU__in_t; + + typedef struct packed{ + abr_reg__MLDSA_EXTERNAL_MU__EXTERNAL_MU__in_t EXTERNAL_MU; + } abr_reg__MLDSA_EXTERNAL_MU__in_t; + + typedef struct packed{ + logic swwe; + logic hwclr; + } abr_reg__MLDSA_MSG_STROBE__STROBE__in_t; + + typedef struct packed{ + abr_reg__MLDSA_MSG_STROBE__STROBE__in_t STROBE; + } abr_reg__MLDSA_MSG_STROBE__in_t; + + typedef struct packed{ + logic hwclr; + } abr_reg__MLDSA_CTX_CONFIG__CTX_SIZE__in_t; + + typedef struct packed{ + abr_reg__MLDSA_CTX_CONFIG__CTX_SIZE__in_t CTX_SIZE; + } abr_reg__MLDSA_CTX_CONFIG__in_t; + + typedef struct packed{ + logic hwclr; + } abr_reg__MLDSA_CTX__CTX__in_t; + + typedef struct packed{ + abr_reg__MLDSA_CTX__CTX__in_t CTX; + } abr_reg__MLDSA_CTX__in_t; + + typedef struct packed{ + logic rd_ack; + logic [31:0] rd_data; + logic wr_ack; + } abr_reg__MLDSA_PUBKEY__external__in_t; + + typedef struct packed{ + logic rd_ack; + logic [31:0] rd_data; + logic wr_ack; + } abr_reg__MLDSA_SIGNATURE__external__in_t; + + typedef struct packed{ + logic rd_ack; + logic [31:0] rd_data; + logic wr_ack; + } abr_reg__MLDSA_PRIVKEY_OUT__external__in_t; + + typedef struct packed{ + logic rd_ack; + logic [31:0] rd_data; + logic wr_ack; + } abr_reg__MLDSA_PRIVKEY_IN__external__in_t; + + typedef struct packed{ + logic swwe; + logic hwclr; + } kv_read_ctrl_reg__read_en__in_t; + + typedef struct packed{ + logic swwe; + } kv_read_ctrl_reg__read_entry__in_t; + + typedef struct packed{ + logic swwe; + } kv_read_ctrl_reg__pcr_hash_extend__in_t; + + typedef struct packed{ + logic swwe; + } kv_read_ctrl_reg__rsvd__in_t; + + typedef struct packed{ + kv_read_ctrl_reg__read_en__in_t read_en; + kv_read_ctrl_reg__read_entry__in_t read_entry; + kv_read_ctrl_reg__pcr_hash_extend__in_t pcr_hash_extend; + kv_read_ctrl_reg__rsvd__in_t rsvd; + } kv_read_ctrl_reg__in_t; + + typedef struct packed{ + logic next; + } kv_status_reg__READY__in_t; + + typedef struct packed{ + logic hwclr; + logic hwset; + } kv_status_reg__VALID__in_t; + + typedef struct packed{ + logic [7:0] next; + } kv_status_reg__ERROR__in_t; + + typedef struct packed{ + kv_status_reg__READY__in_t READY; + kv_status_reg__VALID__in_t VALID; + kv_status_reg__ERROR__in_t ERROR; + } kv_status_reg__in_t; + + typedef struct packed{ + logic hwset; + } abr_reg__intr_block_t__error_intr_t_error_internal_sts_83adab02__error_internal_sts_enable_d33001bb_next_52b75ffa_resetsignal_0d7eaa27__in_t; + + typedef struct packed{ + abr_reg__intr_block_t__error_intr_t_error_internal_sts_83adab02__error_internal_sts_enable_d33001bb_next_52b75ffa_resetsignal_0d7eaa27__in_t error_internal_sts; + } abr_reg__intr_block_t__error_intr_t_error_internal_sts_83adab02__in_t; + + typedef struct packed{ + logic hwset; + } abr_reg__intr_block_t__notif_intr_t_notif_cmd_done_sts_1c68637e__notif_cmd_done_sts_enable_dabe0b8b_next_540fa3b7__in_t; + + typedef struct packed{ + abr_reg__intr_block_t__notif_intr_t_notif_cmd_done_sts_1c68637e__notif_cmd_done_sts_enable_dabe0b8b_next_540fa3b7__in_t notif_cmd_done_sts; + } abr_reg__intr_block_t__notif_intr_t_notif_cmd_done_sts_1c68637e__in_t; + + typedef struct packed{ + abr_reg__intr_block_t__error_intr_t_error_internal_sts_83adab02__in_t error_internal_intr_r; + abr_reg__intr_block_t__notif_intr_t_notif_cmd_done_sts_1c68637e__in_t notif_internal_intr_r; + } abr_reg__intr_block_t__in_t; + + typedef struct packed{ + logic [31:0] next; + } abr_reg__MLKEM_NAME__NAME__in_t; + + typedef struct packed{ + abr_reg__MLKEM_NAME__NAME__in_t NAME; + } abr_reg__MLKEM_NAME__in_t; + + typedef struct packed{ + logic [31:0] next; + } abr_reg__MLKEM_VERSION__VERSION__in_t; + + typedef struct packed{ + abr_reg__MLKEM_VERSION__VERSION__in_t VERSION; + } abr_reg__MLKEM_VERSION__in_t; + + typedef struct packed{ + logic hwclr; + } abr_reg__MLKEM_CTRL__CTRL__in_t; + + typedef struct packed{ + abr_reg__MLKEM_CTRL__CTRL__in_t CTRL; + } abr_reg__MLKEM_CTRL__in_t; + + typedef struct packed{ + logic next; + } abr_reg__MLKEM_STATUS__READY__in_t; + + typedef struct packed{ + logic next; + } abr_reg__MLKEM_STATUS__VALID__in_t; + + typedef struct packed{ + logic next; + } abr_reg__MLKEM_STATUS__ERROR__in_t; + + typedef struct packed{ + abr_reg__MLKEM_STATUS__READY__in_t READY; + abr_reg__MLKEM_STATUS__VALID__in_t VALID; + abr_reg__MLKEM_STATUS__ERROR__in_t ERROR; + } abr_reg__MLKEM_STATUS__in_t; + + typedef struct packed{ + logic [31:0] next; + logic we; + logic swwe; + logic hwclr; + } abr_reg__MLKEM_SEED_D__SEED__in_t; + + typedef struct packed{ + abr_reg__MLKEM_SEED_D__SEED__in_t SEED; + } abr_reg__MLKEM_SEED_D__in_t; + + typedef struct packed{ + logic wr_ack; + } abr_reg__MLKEM_SEED_Z__external__in_t; + + typedef struct packed{ + logic rd_ack; + logic [31:0] rd_data; + } abr_reg__MLKEM_SHARED_KEY__external__in_t; + + typedef struct packed{ + logic rd_ack; + logic [31:0] rd_data; + logic wr_ack; + } abr_reg__MLKEM_MSG__external__in_t; + + typedef struct packed{ + logic rd_ack; + logic [31:0] rd_data; + logic wr_ack; + } abr_reg__MLKEM_DECAPS_KEY__external__in_t; + + typedef struct packed{ + logic rd_ack; + logic [31:0] rd_data; + logic wr_ack; + } abr_reg__MLKEM_ENCAPS_KEY__external__in_t; + + typedef struct packed{ + logic rd_ack; + logic [31:0] rd_data; + logic wr_ack; + } abr_reg__MLKEM_CIPHERTEXT__external__in_t; + + typedef struct packed{ + logic swwe; + logic hwclr; + } kv_write_ctrl_reg__write_en__in_t; + + typedef struct packed{ + logic swwe; + } kv_write_ctrl_reg__write_entry__in_t; + + typedef struct packed{ + logic swwe; + } kv_write_ctrl_reg__hmac_key_dest_valid__in_t; + + typedef struct packed{ + logic swwe; + } kv_write_ctrl_reg__hmac_block_dest_valid__in_t; + + typedef struct packed{ + logic swwe; + } kv_write_ctrl_reg__mldsa_seed_dest_valid__in_t; + + typedef struct packed{ + logic swwe; + } kv_write_ctrl_reg__ecc_pkey_dest_valid__in_t; + + typedef struct packed{ + logic swwe; + } kv_write_ctrl_reg__ecc_seed_dest_valid__in_t; + + typedef struct packed{ + logic swwe; + } kv_write_ctrl_reg__aes_key_dest_valid__in_t; + + typedef struct packed{ + logic swwe; + } kv_write_ctrl_reg__mlkem_seed_dest_valid__in_t; + + typedef struct packed{ + logic swwe; + } kv_write_ctrl_reg__mlkem_msg_dest_valid__in_t; + + typedef struct packed{ + logic swwe; + } kv_write_ctrl_reg__dma_data_dest_valid__in_t; + + typedef struct packed{ + logic swwe; + } kv_write_ctrl_reg__rsvd__in_t; + + typedef struct packed{ + kv_write_ctrl_reg__write_en__in_t write_en; + kv_write_ctrl_reg__write_entry__in_t write_entry; + kv_write_ctrl_reg__hmac_key_dest_valid__in_t hmac_key_dest_valid; + kv_write_ctrl_reg__hmac_block_dest_valid__in_t hmac_block_dest_valid; + kv_write_ctrl_reg__mldsa_seed_dest_valid__in_t mldsa_seed_dest_valid; + kv_write_ctrl_reg__ecc_pkey_dest_valid__in_t ecc_pkey_dest_valid; + kv_write_ctrl_reg__ecc_seed_dest_valid__in_t ecc_seed_dest_valid; + kv_write_ctrl_reg__aes_key_dest_valid__in_t aes_key_dest_valid; + kv_write_ctrl_reg__mlkem_seed_dest_valid__in_t mlkem_seed_dest_valid; + kv_write_ctrl_reg__mlkem_msg_dest_valid__in_t mlkem_msg_dest_valid; + kv_write_ctrl_reg__dma_data_dest_valid__in_t dma_data_dest_valid; + kv_write_ctrl_reg__rsvd__in_t rsvd; + } kv_write_ctrl_reg__in_t; + + typedef struct packed{ + logic reset_b; + logic hard_reset_b; + logic abr_ready; + abr_reg__MLDSA_NAME__in_t [2-1:0]MLDSA_NAME; + abr_reg__MLDSA_VERSION__in_t [2-1:0]MLDSA_VERSION; + abr_reg__MLDSA_CTRL__in_t MLDSA_CTRL; + abr_reg__MLDSA_STATUS__in_t MLDSA_STATUS; + abr_reg__ABR_ENTROPY__in_t [16-1:0]ABR_ENTROPY; + abr_reg__MLDSA_SEED__in_t [8-1:0]MLDSA_SEED; + abr_reg__MLDSA_SIGN_RND__in_t [8-1:0]MLDSA_SIGN_RND; + abr_reg__MLDSA_MSG__in_t [16-1:0]MLDSA_MSG; + abr_reg__MLDSA_VERIFY_RES__in_t [16-1:0]MLDSA_VERIFY_RES; + abr_reg__MLDSA_EXTERNAL_MU__in_t [16-1:0]MLDSA_EXTERNAL_MU; + abr_reg__MLDSA_MSG_STROBE__in_t MLDSA_MSG_STROBE; + abr_reg__MLDSA_CTX_CONFIG__in_t MLDSA_CTX_CONFIG; + abr_reg__MLDSA_CTX__in_t [64-1:0]MLDSA_CTX; + abr_reg__MLDSA_PUBKEY__external__in_t MLDSA_PUBKEY; + abr_reg__MLDSA_SIGNATURE__external__in_t MLDSA_SIGNATURE; + abr_reg__MLDSA_PRIVKEY_OUT__external__in_t MLDSA_PRIVKEY_OUT; + abr_reg__MLDSA_PRIVKEY_IN__external__in_t MLDSA_PRIVKEY_IN; + kv_read_ctrl_reg__in_t kv_mldsa_seed_rd_ctrl; + kv_status_reg__in_t kv_mldsa_seed_rd_status; + abr_reg__intr_block_t__in_t intr_block_rf; + abr_reg__MLKEM_NAME__in_t [2-1:0]MLKEM_NAME; + abr_reg__MLKEM_VERSION__in_t [2-1:0]MLKEM_VERSION; + abr_reg__MLKEM_CTRL__in_t MLKEM_CTRL; + abr_reg__MLKEM_STATUS__in_t MLKEM_STATUS; + abr_reg__MLKEM_SEED_D__in_t [8-1:0]MLKEM_SEED_D; + abr_reg__MLKEM_SEED_Z__external__in_t [8-1:0]MLKEM_SEED_Z; + abr_reg__MLKEM_SHARED_KEY__external__in_t [8-1:0]MLKEM_SHARED_KEY; + abr_reg__MLKEM_MSG__external__in_t MLKEM_MSG; + abr_reg__MLKEM_DECAPS_KEY__external__in_t MLKEM_DECAPS_KEY; + abr_reg__MLKEM_ENCAPS_KEY__external__in_t MLKEM_ENCAPS_KEY; + abr_reg__MLKEM_CIPHERTEXT__external__in_t MLKEM_CIPHERTEXT; + kv_read_ctrl_reg__in_t kv_mlkem_seed_rd_ctrl; + kv_status_reg__in_t kv_mlkem_seed_rd_status; + kv_read_ctrl_reg__in_t kv_mlkem_msg_rd_ctrl; + kv_status_reg__in_t kv_mlkem_msg_rd_status; + kv_write_ctrl_reg__in_t kv_mlkem_sharedkey_wr_ctrl; + kv_status_reg__in_t kv_mlkem_sharedkey_wr_status; + } abr_reg__in_t; + + typedef struct packed{ + logic [2:0] value; + } abr_reg__MLDSA_CTRL__CTRL__out_t; + + typedef struct packed{ + logic value; + } abr_reg__MLDSA_CTRL__ZEROIZE__out_t; + + typedef struct packed{ + logic value; + } abr_reg__MLDSA_CTRL__PCR_SIGN__out_t; + + typedef struct packed{ + logic value; + } abr_reg__MLDSA_CTRL__EXTERNAL_MU__out_t; + + typedef struct packed{ + logic value; + } abr_reg__MLDSA_CTRL__STREAM_MSG__out_t; + + typedef struct packed{ + abr_reg__MLDSA_CTRL__CTRL__out_t CTRL; + abr_reg__MLDSA_CTRL__ZEROIZE__out_t ZEROIZE; + abr_reg__MLDSA_CTRL__PCR_SIGN__out_t PCR_SIGN; + abr_reg__MLDSA_CTRL__EXTERNAL_MU__out_t EXTERNAL_MU; + abr_reg__MLDSA_CTRL__STREAM_MSG__out_t STREAM_MSG; + } abr_reg__MLDSA_CTRL__out_t; + + typedef struct packed{ + logic value; + } abr_reg__MLDSA_STATUS__VALID__out_t; + + typedef struct packed{ + logic value; + } abr_reg__MLDSA_STATUS__ERROR__out_t; + + typedef struct packed{ + abr_reg__MLDSA_STATUS__VALID__out_t VALID; + abr_reg__MLDSA_STATUS__ERROR__out_t ERROR; + } abr_reg__MLDSA_STATUS__out_t; + + typedef struct packed{ + logic [31:0] value; + } abr_reg__ABR_ENTROPY__ENTROPY__out_t; + + typedef struct packed{ + abr_reg__ABR_ENTROPY__ENTROPY__out_t ENTROPY; + } abr_reg__ABR_ENTROPY__out_t; + + typedef struct packed{ + logic [31:0] value; + } abr_reg__MLDSA_SEED__SEED__out_t; + + typedef struct packed{ + abr_reg__MLDSA_SEED__SEED__out_t SEED; + } abr_reg__MLDSA_SEED__out_t; + + typedef struct packed{ + logic [31:0] value; + } abr_reg__MLDSA_SIGN_RND__SIGN_RND__out_t; + + typedef struct packed{ + abr_reg__MLDSA_SIGN_RND__SIGN_RND__out_t SIGN_RND; + } abr_reg__MLDSA_SIGN_RND__out_t; + + typedef struct packed{ + logic [31:0] value; + logic swmod; + } abr_reg__MLDSA_MSG__MSG__out_t; + + typedef struct packed{ + abr_reg__MLDSA_MSG__MSG__out_t MSG; + } abr_reg__MLDSA_MSG__out_t; + + typedef struct packed{ + logic [31:0] value; + } abr_reg__MLDSA_VERIFY_RES__VERIFY_RES__out_t; + + typedef struct packed{ + abr_reg__MLDSA_VERIFY_RES__VERIFY_RES__out_t VERIFY_RES; + } abr_reg__MLDSA_VERIFY_RES__out_t; + + typedef struct packed{ + logic [31:0] value; + } abr_reg__MLDSA_EXTERNAL_MU__EXTERNAL_MU__out_t; + + typedef struct packed{ + abr_reg__MLDSA_EXTERNAL_MU__EXTERNAL_MU__out_t EXTERNAL_MU; + } abr_reg__MLDSA_EXTERNAL_MU__out_t; + + typedef struct packed{ + logic [3:0] value; + } abr_reg__MLDSA_MSG_STROBE__STROBE__out_t; + + typedef struct packed{ + abr_reg__MLDSA_MSG_STROBE__STROBE__out_t STROBE; + } abr_reg__MLDSA_MSG_STROBE__out_t; + + typedef struct packed{ + logic [7:0] value; + } abr_reg__MLDSA_CTX_CONFIG__CTX_SIZE__out_t; + + typedef struct packed{ + abr_reg__MLDSA_CTX_CONFIG__CTX_SIZE__out_t CTX_SIZE; + } abr_reg__MLDSA_CTX_CONFIG__out_t; + + typedef struct packed{ + logic [31:0] value; + } abr_reg__MLDSA_CTX__CTX__out_t; + + typedef struct packed{ + abr_reg__MLDSA_CTX__CTX__out_t CTX; + } abr_reg__MLDSA_CTX__out_t; + + typedef struct packed{ + logic req; + logic [11:0] addr; + logic req_is_wr; + logic [31:0] wr_data; + logic [31:0] wr_biten; + } abr_reg__MLDSA_PUBKEY__external__out_t; + + typedef struct packed{ + logic req; + logic [12:0] addr; + logic req_is_wr; + logic [31:0] wr_data; + logic [31:0] wr_biten; + } abr_reg__MLDSA_SIGNATURE__external__out_t; + + typedef struct packed{ + logic req; + logic [12:0] addr; + logic req_is_wr; + logic [31:0] wr_data; + logic [31:0] wr_biten; + } abr_reg__MLDSA_PRIVKEY_OUT__external__out_t; + + typedef struct packed{ + logic req; + logic [12:0] addr; + logic req_is_wr; + logic [31:0] wr_data; + logic [31:0] wr_biten; + } abr_reg__MLDSA_PRIVKEY_IN__external__out_t; + + typedef struct packed{ + logic value; + } kv_read_ctrl_reg__read_en__out_t; + + typedef struct packed{ + logic [4:0] value; + } kv_read_ctrl_reg__read_entry__out_t; + + typedef struct packed{ + logic value; + } kv_read_ctrl_reg__pcr_hash_extend__out_t; + + typedef struct packed{ + logic [24:0] value; + } kv_read_ctrl_reg__rsvd__out_t; + + typedef struct packed{ + kv_read_ctrl_reg__read_en__out_t read_en; + kv_read_ctrl_reg__read_entry__out_t read_entry; + kv_read_ctrl_reg__pcr_hash_extend__out_t pcr_hash_extend; + kv_read_ctrl_reg__rsvd__out_t rsvd; + } kv_read_ctrl_reg__out_t; + + typedef struct packed{ + logic intr; + } abr_reg__intr_block_t__global_intr_t_agg_sts_dd3dcf0a__out_t; + + typedef struct packed{ + logic intr; + } abr_reg__intr_block_t__global_intr_t_agg_sts_e6399b4a__out_t; + + typedef struct packed{ + logic intr; + } abr_reg__intr_block_t__error_intr_t_error_internal_sts_83adab02__out_t; + + typedef struct packed{ + logic intr; + } abr_reg__intr_block_t__notif_intr_t_notif_cmd_done_sts_1c68637e__out_t; + + typedef struct packed{ + abr_reg__intr_block_t__global_intr_t_agg_sts_dd3dcf0a__out_t error_global_intr_r; + abr_reg__intr_block_t__global_intr_t_agg_sts_e6399b4a__out_t notif_global_intr_r; + abr_reg__intr_block_t__error_intr_t_error_internal_sts_83adab02__out_t error_internal_intr_r; + abr_reg__intr_block_t__notif_intr_t_notif_cmd_done_sts_1c68637e__out_t notif_internal_intr_r; + } abr_reg__intr_block_t__out_t; + + typedef struct packed{ + logic [2:0] value; + } abr_reg__MLKEM_CTRL__CTRL__out_t; + + typedef struct packed{ + logic value; + } abr_reg__MLKEM_CTRL__ZEROIZE__out_t; + + typedef struct packed{ + abr_reg__MLKEM_CTRL__CTRL__out_t CTRL; + abr_reg__MLKEM_CTRL__ZEROIZE__out_t ZEROIZE; + } abr_reg__MLKEM_CTRL__out_t; + + typedef struct packed{ + logic value; + } abr_reg__MLKEM_STATUS__VALID__out_t; + + typedef struct packed{ + logic value; + } abr_reg__MLKEM_STATUS__ERROR__out_t; + + typedef struct packed{ + abr_reg__MLKEM_STATUS__VALID__out_t VALID; + abr_reg__MLKEM_STATUS__ERROR__out_t ERROR; + } abr_reg__MLKEM_STATUS__out_t; + + typedef struct packed{ + logic [31:0] value; + } abr_reg__MLKEM_SEED_D__SEED__out_t; + + typedef struct packed{ + abr_reg__MLKEM_SEED_D__SEED__out_t SEED; + } abr_reg__MLKEM_SEED_D__out_t; + + typedef struct packed{ + logic req; + logic req_is_wr; + logic [31:0] wr_data; + logic [31:0] wr_biten; + } abr_reg__MLKEM_SEED_Z__external__out_t; + + typedef struct packed{ + logic req; + logic req_is_wr; + } abr_reg__MLKEM_SHARED_KEY__external__out_t; + + typedef struct packed{ + logic req; + logic [4:0] addr; + logic req_is_wr; + logic [31:0] wr_data; + logic [31:0] wr_biten; + } abr_reg__MLKEM_MSG__external__out_t; + + typedef struct packed{ + logic req; + logic [11:0] addr; + logic req_is_wr; + logic [31:0] wr_data; + logic [31:0] wr_biten; + } abr_reg__MLKEM_DECAPS_KEY__external__out_t; + + typedef struct packed{ + logic req; + logic [10:0] addr; + logic req_is_wr; + logic [31:0] wr_data; + logic [31:0] wr_biten; + } abr_reg__MLKEM_ENCAPS_KEY__external__out_t; + + typedef struct packed{ + logic req; + logic [10:0] addr; + logic req_is_wr; + logic [31:0] wr_data; + logic [31:0] wr_biten; + } abr_reg__MLKEM_CIPHERTEXT__external__out_t; + + typedef struct packed{ + logic value; + } kv_write_ctrl_reg__write_en__out_t; + + typedef struct packed{ + logic [4:0] value; + } kv_write_ctrl_reg__write_entry__out_t; + + typedef struct packed{ + logic value; + } kv_write_ctrl_reg__hmac_key_dest_valid__out_t; + + typedef struct packed{ + logic value; + } kv_write_ctrl_reg__hmac_block_dest_valid__out_t; + + typedef struct packed{ + logic value; + } kv_write_ctrl_reg__mldsa_seed_dest_valid__out_t; + + typedef struct packed{ + logic value; + } kv_write_ctrl_reg__ecc_pkey_dest_valid__out_t; + + typedef struct packed{ + logic value; + } kv_write_ctrl_reg__ecc_seed_dest_valid__out_t; + + typedef struct packed{ + logic value; + } kv_write_ctrl_reg__aes_key_dest_valid__out_t; + + typedef struct packed{ + logic value; + } kv_write_ctrl_reg__mlkem_seed_dest_valid__out_t; + + typedef struct packed{ + logic value; + } kv_write_ctrl_reg__mlkem_msg_dest_valid__out_t; + + typedef struct packed{ + logic value; + } kv_write_ctrl_reg__dma_data_dest_valid__out_t; + + typedef struct packed{ + logic [16:0] value; + } kv_write_ctrl_reg__rsvd__out_t; + + typedef struct packed{ + kv_write_ctrl_reg__write_en__out_t write_en; + kv_write_ctrl_reg__write_entry__out_t write_entry; + kv_write_ctrl_reg__hmac_key_dest_valid__out_t hmac_key_dest_valid; + kv_write_ctrl_reg__hmac_block_dest_valid__out_t hmac_block_dest_valid; + kv_write_ctrl_reg__mldsa_seed_dest_valid__out_t mldsa_seed_dest_valid; + kv_write_ctrl_reg__ecc_pkey_dest_valid__out_t ecc_pkey_dest_valid; + kv_write_ctrl_reg__ecc_seed_dest_valid__out_t ecc_seed_dest_valid; + kv_write_ctrl_reg__aes_key_dest_valid__out_t aes_key_dest_valid; + kv_write_ctrl_reg__mlkem_seed_dest_valid__out_t mlkem_seed_dest_valid; + kv_write_ctrl_reg__mlkem_msg_dest_valid__out_t mlkem_msg_dest_valid; + kv_write_ctrl_reg__dma_data_dest_valid__out_t dma_data_dest_valid; + kv_write_ctrl_reg__rsvd__out_t rsvd; + } kv_write_ctrl_reg__out_t; + + typedef struct packed{ + abr_reg__MLDSA_CTRL__out_t MLDSA_CTRL; + abr_reg__MLDSA_STATUS__out_t MLDSA_STATUS; + abr_reg__ABR_ENTROPY__out_t [16-1:0]ABR_ENTROPY; + abr_reg__MLDSA_SEED__out_t [8-1:0]MLDSA_SEED; + abr_reg__MLDSA_SIGN_RND__out_t [8-1:0]MLDSA_SIGN_RND; + abr_reg__MLDSA_MSG__out_t [16-1:0]MLDSA_MSG; + abr_reg__MLDSA_VERIFY_RES__out_t [16-1:0]MLDSA_VERIFY_RES; + abr_reg__MLDSA_EXTERNAL_MU__out_t [16-1:0]MLDSA_EXTERNAL_MU; + abr_reg__MLDSA_MSG_STROBE__out_t MLDSA_MSG_STROBE; + abr_reg__MLDSA_CTX_CONFIG__out_t MLDSA_CTX_CONFIG; + abr_reg__MLDSA_CTX__out_t [64-1:0]MLDSA_CTX; + abr_reg__MLDSA_PUBKEY__external__out_t MLDSA_PUBKEY; + abr_reg__MLDSA_SIGNATURE__external__out_t MLDSA_SIGNATURE; + abr_reg__MLDSA_PRIVKEY_OUT__external__out_t MLDSA_PRIVKEY_OUT; + abr_reg__MLDSA_PRIVKEY_IN__external__out_t MLDSA_PRIVKEY_IN; + kv_read_ctrl_reg__out_t kv_mldsa_seed_rd_ctrl; + abr_reg__intr_block_t__out_t intr_block_rf; + abr_reg__MLKEM_CTRL__out_t MLKEM_CTRL; + abr_reg__MLKEM_STATUS__out_t MLKEM_STATUS; + abr_reg__MLKEM_SEED_D__out_t [8-1:0]MLKEM_SEED_D; + abr_reg__MLKEM_SEED_Z__external__out_t [8-1:0]MLKEM_SEED_Z; + abr_reg__MLKEM_SHARED_KEY__external__out_t [8-1:0]MLKEM_SHARED_KEY; + abr_reg__MLKEM_MSG__external__out_t MLKEM_MSG; + abr_reg__MLKEM_DECAPS_KEY__external__out_t MLKEM_DECAPS_KEY; + abr_reg__MLKEM_ENCAPS_KEY__external__out_t MLKEM_ENCAPS_KEY; + abr_reg__MLKEM_CIPHERTEXT__external__out_t MLKEM_CIPHERTEXT; + kv_read_ctrl_reg__out_t kv_mlkem_seed_rd_ctrl; + kv_read_ctrl_reg__out_t kv_mlkem_msg_rd_ctrl; + kv_write_ctrl_reg__out_t kv_mlkem_sharedkey_wr_ctrl; + } abr_reg__out_t; + + typedef enum logic [31:0] { + kv_status_reg__ERROR__kv_error_e__SUCCESS = 'h0, + kv_status_reg__ERROR__kv_error_e__KV_READ_FAIL = 'h1, + kv_status_reg__ERROR__kv_error_e__KV_WRITE_FAIL = 'h2 + } kv_status_reg__ERROR__kv_error_e_e; + + localparam ABR_REG_ADDR_WIDTH = 32'd16; + +endpackage \ No newline at end of file diff --git a/designs/Caliptra/src/adams-bridge/abr_sample_buffer.sv b/designs/Caliptra/src/adams-bridge/abr_sample_buffer.sv new file mode 100644 index 0000000..9e76666 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/abr_sample_buffer.sv @@ -0,0 +1,131 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. + +// Sample Buffer takes in NUM_WR samples and valid bits +// Valid samples are packed and shifted onto a buffer +// Outputs are presented valid once NUM_RD entries are valid in the buffer + +module abr_sample_buffer + // import ::*; + #( + parameter NUM_WR = 5 + ,parameter NUM_RD = 4 + ,parameter BUFFER_DATA_W = 32 + ,parameter OPT_BUFFER_DEPTH = 0 + ,localparam BUFFER_DEPTH = (NUM_WR + NUM_RD) + ,localparam BUF_W = BUFFER_DEPTH*BUFFER_DATA_W + ) + ( + input logic clk, + input logic rst_b, + + input logic zeroize, + + //input data + input logic [NUM_WR-1:0] data_valid_i, + input logic [NUM_WR-1:0][BUFFER_DATA_W-1:0] data_i, + output logic buffer_full_o, + //output data + output logic data_valid_o, + output logic [NUM_RD-1:0][BUFFER_DATA_W-1:0] data_o + + ); + + logic buffer_rd, buffer_wr; + logic update_buffer; + + //Incoming samples to write to buffer + logic [BUFFER_DEPTH-1:0][BUFFER_DATA_W-1:0] buffer_wr_data, buffer_wr_data_shift; + logic [BUFFER_DEPTH-1:0] buffer_wr_valid, buffer_wr_valid_shift; + + //Valid sample buffer + logic [BUFFER_DEPTH-1:0] buffer_valid, buffer_valid_d, buffer_valid_shift; + logic [BUFFER_DEPTH-1:0][BUFFER_DATA_W-1:0] buffer, buffer_d, buffer_shift; + logic [$clog2(BUFFER_DEPTH):0] num_valid; + + + //Buffer is full when it can't take a full write cycle + //Check for at least N entries available, where N is the difference between WR/RD bandwidth + generate + if (NUM_WR == NUM_RD) always_comb buffer_full_o = '0; + else always_comb buffer_full_o = buffer_valid[(BUFFER_DEPTH-(NUM_WR-NUM_RD))]; + endgenerate + //Read when we have NUM_RD worth of valid data + always_comb buffer_rd = buffer_valid[NUM_RD-1]; + //Write as long as we have 1 valid sample and not full + always_comb buffer_wr = (|data_valid_i) & ~buffer_full_o; + //update buffer for any read or write + always_comb update_buffer = buffer_rd | buffer_wr; + + always_comb begin + //count the valid entries in the buffer already + num_valid = '0; + for (int i = 0; i < BUFFER_DEPTH; i++) begin + if (buffer_valid[i] == 1'b1) num_valid += 1'b1; + end + end + + //Concat the valid samples + logic [$clog2(BUFFER_DEPTH)-1:0] sample_wr_ptr; + always_comb begin + sample_wr_ptr = '0; + buffer_wr_data = '0; + buffer_wr_valid = '0; + for (int sample = 0; sample < NUM_WR; sample++) begin + if (data_valid_i[sample]) begin + //concat the next valid sample + buffer_wr_data[sample_wr_ptr] = data_i[sample][BUFFER_DATA_W-1:0]; + buffer_wr_valid[sample_wr_ptr] = 1'b1; + //increment the write pointer + sample_wr_ptr += 1; + end + end + + //shift the write data left by the count, or count - NUM_RD if there is a read + buffer_wr_data_shift = buffer_rd ? buffer_wr_data << (num_valid - NUM_RD)*BUFFER_DATA_W : + buffer_wr_data << (num_valid)*BUFFER_DATA_W; + buffer_wr_valid_shift = buffer_wr ? + (buffer_rd ? buffer_wr_valid << (num_valid - NUM_RD) : + buffer_wr_valid << (num_valid)) : '0; + end + + //Shift the buffer contents and append new samples + always_comb begin + //shift the buffer data right by NUM_RD if there is a read + buffer_shift = buffer_rd ? BUF_W'(buffer >> (NUM_RD*BUFFER_DATA_W)) : buffer; + buffer_valid_shift = buffer_rd ? BUFFER_DEPTH'(buffer_valid >> NUM_RD) : buffer_valid; + + //OR together the write data and the buffer data + buffer_d = buffer_shift | buffer_wr_data_shift; + buffer_valid_d = buffer_valid_shift | buffer_wr_valid_shift; + end + + always_ff @(posedge clk or negedge rst_b) begin + if (!rst_b) begin + buffer <= '0; + buffer_valid <= '0; + end else if (zeroize) begin + buffer <= '0; + buffer_valid <= '0; + end else if (update_buffer) begin + buffer <= buffer_d; + buffer_valid <= buffer_valid_d; + end + end + + //Output is valid when we have NUM_RD worth of valid data + always_comb data_valid_o = buffer_rd & ~zeroize; + always_comb data_o = buffer[NUM_RD-1:0]; + +endmodule \ No newline at end of file diff --git a/designs/Caliptra/src/adams-bridge/abr_sampler_pkg.sv b/designs/Caliptra/src/adams-bridge/abr_sampler_pkg.sv new file mode 100644 index 0000000..91c71fa --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/abr_sampler_pkg.sv @@ -0,0 +1,127 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +// +//====================================================================== +// +// abr_sampler_pkg.sv +// -------- +// required parameters for sampler top +// +//====================================================================== + +`ifndef ABR_SAMPLER_PKG +`define ABR_SAMPLER_PKG + +package abr_sampler_pkg; + import abr_params_pkg::*; + + parameter ABR_COEFF_CNT = 256; + +//SHA3 Configuration +// Keccak Rounds per clock + parameter RoundsPerClock = 2; +// Do not enable masking + parameter Sha3EnMasking = 0; + parameter Sha3Share = (Sha3EnMasking) ? 2 : 1; + +//Sampler Configurations +//MLDSA Rej Sampler + parameter MLDSA_REJS_NUM_SAMPLERS = 5; + parameter MLDSA_REJS_SAMPLE_W = 24; + +//MLKEM Rej Sampler + parameter MLKEM_REJS_NUM_SAMPLERS = 10; + parameter MLKEM_REJS_SAMPLE_W = 12; + + //Rej Sampler common params + //MLDSA and MLKEM output rate should match + parameter REJS_VLD_SAMPLES = COEFF_PER_CLK; + parameter REJS_PISO_BUFFER_W = 1440; + parameter REJS_PISO_INPUT_RATE = 1344; + parameter REJS_PISO_OUTPUT_RATE = MLDSA_REJS_NUM_SAMPLERS*MLDSA_REJS_SAMPLE_W; + +//Rej Bounded + parameter REJB_NUM_SAMPLERS = 8; + parameter REJB_SAMPLE_W = 4; + parameter REJB_VLD_SAMPLES = COEFF_PER_CLK; + parameter REJB_VLD_SAMPLES_W = 24; + parameter REJB_VALUE = 15; + parameter REJB_VLD_SAMPLE_W = $clog2(REJB_VALUE); + parameter REJB_PISO_BUFFER_W = 1334; + parameter REJB_PISO_INPUT_RATE = 1088; + parameter REJB_PISO_OUTPUT_RATE = REJB_NUM_SAMPLERS*REJB_SAMPLE_W; + +//Exp Mask + parameter EXP_NUM_SAMPLERS = 4; + parameter EXP_SAMPLE_W = 20; + parameter EXP_VLD_SAMPLES = COEFF_PER_CLK; + parameter EXP_VLD_SAMPLE_W = 24; + parameter EXP_PISO_BUFFER_W = 1152; + parameter EXP_PISO_INPUT_RATE = 1088; + parameter EXP_PISO_OUTPUT_RATE = EXP_NUM_SAMPLERS*EXP_SAMPLE_W; + +//Sample In Ball + parameter SIB_NUM_SAMPLERS = 4; + parameter SIB_SAMPLE_W = 8; + parameter SIB_TAU = 60; + parameter SIB_PISO_BUFFER_W = 1344; + parameter SIB_PISO_INPUT_RATE = 1088; + parameter SIB_PISO_OUTPUT_RATE = SIB_NUM_SAMPLERS*SIB_SAMPLE_W; + + //CBD Sampler + parameter CBD_NUM_SAMPLERS = COEFF_PER_CLK; + parameter CBD_SAMPLE_W = 2*MLKEM_ETA; + parameter CBD_VLD_SAMPLES = COEFF_PER_CLK; + parameter CBD_PISO_BUFFER_W = 1344; + parameter CBD_PISO_INPUT_RATE = 1088; + parameter CBD_PISO_OUTPUT_RATE = CBD_NUM_SAMPLERS*CBD_SAMPLE_W; + + + //declare fsm state variables + typedef enum logic [2:0] { + ABR_SAMPLER_IDLE = 3'b000, + ABR_SAMPLER_PROC = 3'b001, + ABR_SAMPLER_WAIT = 3'b010, + ABR_SAMPLER_RUN = 3'b011, + ABR_SAMPLER_DONE = 3'b100 + } abr_sampler_fsm_state_e; + + typedef enum logic [2:0] { + ABR_REJS_MODE, + ABR_REJB_MODE, + ABR_EXP_MODE, + ABR_SIB_MODE, + ABR_CBD_MODE + } abr_piso_mode_e; + + //common structures + typedef enum logic [4:0] { + ABR_SAMPLER_NONE, + //SHA/SHAKE only modes + ABR_SHAKE256, + ABR_SHAKE128, + ABR_SHA512, + ABR_SHA256, + //SAMPLER MODES + MLDSA_REJ_SAMPLER, + MLKEM_REJ_SAMPLER, + ABR_EXP_MASK, + ABR_REJ_BOUNDED, + ABR_SAMPLE_IN_BALL, + ABR_CBD_SAMPLER + } abr_sampler_mode_e; + +endpackage + +`endif diff --git a/designs/Caliptra/src/adams-bridge/abr_sampler_top.sv b/designs/Caliptra/src/adams-bridge/abr_sampler_top.sv new file mode 100644 index 0000000..08c05f8 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/abr_sampler_top.sv @@ -0,0 +1,638 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. + +module abr_sampler_top + import abr_sampler_pkg::*; + import abr_sha3_pkg::*; + import abr_params_pkg::*; + import abr_prim_alert_pkg::*; + #( + //top level params + ) + ( + input logic clk, + input logic rst_b, + input logic zeroize, + + //input + input abr_sampler_mode_e sampler_mode_i, + + input logic sha3_start_i, + + input logic msg_start_i, + input logic msg_valid_i, + output logic msg_rdy_o, + input logic [MsgStrbW-1:0] msg_strobe_i, + input logic [MsgWidth-1:0] msg_data_i[Sha3Share], + + input logic sampler_start_i, + + input logic [ABR_MEM_ADDR_WIDTH-1:0] dest_base_addr_i, + + //NTT read from sib_mem + input mem_if_t sib_mem_rd_req_i, + output logic [ABR_MEM_DATA_WIDTH-1:0] sib_mem_rd_data_o, + + //output + output logic sampler_busy_o, + + output logic sampler_ntt_dv_o, + output logic [COEFF_PER_CLK-1:0][MLDSA_Q_WIDTH-1:0] sampler_ntt_data_o, + + output logic sampler_mem_dv_o, + output logic [COEFF_PER_CLK-1:0][MLDSA_Q_WIDTH-1:0] sampler_mem_data_o, + output logic [ABR_MEM_ADDR_WIDTH-1:0] sampler_mem_addr_o, + + output logic sampler_state_dv_o, + output logic [abr_sha3_pkg::StateW-1:0] sampler_state_data_o [Sha3Share] + + ); + +//Signal Declarations + logic sha3_process; + logic sha3_run; + + logic sha3_squeezing; + + logic sha3_block_processed; + + abr_sha3_pkg::sha3_st_e sha3_fsm; + abr_sha3_pkg::err_t sha3_err; + + abr_sha3_pkg::sha3_mode_e mode; + abr_sha3_pkg::keccak_strength_e strength; + + logic sha3_state_dv; + logic sha3_state_hold; + logic [abr_sha3_pkg::StateW-1:0] sha3_state[Sha3Share]; + + logic sha3_state_error; + logic sha3_count_error; + logic sha3_rst_storage_err; + + //mldsa rej sampler + logic mldsa_rejs_piso_dv; + logic mldsa_rejs_piso_hold; + + logic mldsa_rejs_dv; + logic [REJS_VLD_SAMPLES-1:0][MLDSA_Q_WIDTH-1:0] mldsa_rejs_data_q; + + //mlkem rej sampler + logic mlkem_rejs_piso_dv; + logic mlkem_rejs_piso_hold; + + logic mlkem_rejs_dv; + logic [REJS_VLD_SAMPLES-1:0][MLKEM_Q_WIDTH-1:0] mlkem_rejs_data_q; + + //common rejs piso data + logic [MLDSA_REJS_NUM_SAMPLERS-1:0][MLDSA_REJS_SAMPLE_W-1:0] rejs_piso_data; + + //rej bounded + logic rejb_piso_dv; + logic rejb_piso_hold; + logic [REJB_NUM_SAMPLERS-1:0][REJB_SAMPLE_W-1:0] rejb_piso_data; + + logic rejb_dv; + logic [REJB_VLD_SAMPLES-1:0][MLDSA_Q_WIDTH-1:0] rejb_data; + + //exp mask + logic exp_piso_dv; + logic exp_piso_hold; + logic [EXP_NUM_SAMPLERS-1:0][EXP_SAMPLE_W-1:0] exp_piso_data; + + logic exp_dv; + logic [EXP_VLD_SAMPLES-1:0][EXP_VLD_SAMPLE_W-1:0] exp_data; + + //sample in ball + logic sib_piso_dv; + logic sib_piso_hold; + logic [SIB_NUM_SAMPLERS-1:0][SIB_SAMPLE_W-1:0] sib_piso_data; + + logic sib_done; + + logic [1:0] sib_mem_cs, sib_mem_cs_mux; + logic [1:0] sib_mem_we; + logic [1:0][7:2] sib_mem_addr, sib_mem_addr_mux; + logic [1:0][3:0][MLDSA_Q_WIDTH-2:0] sib_mem_wrdata; + logic [1:0][3:0][MLDSA_Q_WIDTH-2:0] sib_mem_rddata; + + //cbd + logic cbd_piso_dv; + logic cbd_piso_hold; + logic [CBD_NUM_SAMPLERS-1:0][CBD_SAMPLE_W-1:0] cbd_piso_data; + + logic cbd_dv; + logic [CBD_VLD_SAMPLES-1:0][MLKEM_Q_WIDTH-1:0] cbd_data; + + logic [ABR_MEM_ADDR_WIDTH-1:0] dest_addr; + logic [$clog2(ABR_COEFF_CNT/4):0] coeff_cnt; + logic vld_cycle; + logic sampler_done; + + logic zeroize_sha3, zeroize_rejb, zeroize_mldsa_rejs, zeroize_sib, zeroize_exp_mask; + logic zeroize_cbd, zeroize_mlkem_rejs; + logic zeroize_sib_mem; + logic zeroize_piso; + + abr_piso_mode_e piso_mode; + logic sha3_piso_dv; + logic piso_dv, piso_hold; + logic [REJS_PISO_OUTPUT_RATE-1:0] piso_data; + + abr_sampler_fsm_state_e sampler_fsm_ps, sampler_fsm_ns; + + //Sampler mode muxes + always_comb begin + mode = abr_sha3_pkg::Shake; + strength = abr_sha3_pkg::L256; + vld_cycle = 0; + sampler_done = 0; + sampler_mem_dv_o = 0; + sampler_mem_data_o = 0; + sampler_mem_addr_o = 0; + sampler_state_dv_o = 0; + sampler_state_data_o[0] = 0; + zeroize_rejb = zeroize; + zeroize_mldsa_rejs = zeroize; + zeroize_mlkem_rejs = zeroize; + zeroize_exp_mask = zeroize; + zeroize_sib = zeroize; + zeroize_sib_mem = zeroize; + zeroize_sha3 = zeroize; + zeroize_cbd = zeroize; + zeroize_piso = zeroize; + piso_mode = ABR_REJS_MODE; + + unique case (sampler_mode_i) inside + ABR_SHAKE256: begin + mode = abr_sha3_pkg::Shake; + strength = abr_sha3_pkg::L256; + sampler_state_dv_o = sha3_state_dv; + sampler_state_data_o[0] = sha3_state[0]; + sampler_done = sha3_state_dv; + zeroize_sha3 |= sha3_state_dv; + end + ABR_SHAKE128: begin + mode = abr_sha3_pkg::Shake; + strength = abr_sha3_pkg::L128; + sampler_state_dv_o = sha3_state_dv; + sampler_state_data_o [0]= sha3_state[0]; + sampler_done = sha3_state_dv; + zeroize_sha3 |= sha3_state_dv; + end + ABR_SHA512: begin + mode = abr_sha3_pkg::Sha3; + strength = abr_sha3_pkg::L512; + sampler_state_dv_o = sha3_state_dv; + sampler_state_data_o[0] = sha3_state[0]; + sampler_done = sha3_state_dv; + zeroize_sha3 |= sha3_state_dv; + end + ABR_SHA256: begin + mode = abr_sha3_pkg::Sha3; + strength = abr_sha3_pkg::L256; + sampler_state_dv_o = sha3_state_dv; + sampler_state_data_o [0]= sha3_state[0]; + sampler_done = sha3_state_dv; + zeroize_sha3 |= sha3_state_dv; + end + MLKEM_REJ_SAMPLER: begin + mode = abr_sha3_pkg::Shake; + strength = abr_sha3_pkg::L128; + vld_cycle = mlkem_rejs_dv; + sampler_done = (coeff_cnt == (ABR_COEFF_CNT/4)); + zeroize_mlkem_rejs |= sampler_done; + zeroize_sha3 |= sampler_done; + zeroize_piso |= sampler_done; + piso_mode = ABR_REJS_MODE; + end + MLDSA_REJ_SAMPLER: begin + mode = abr_sha3_pkg::Shake; + strength = abr_sha3_pkg::L128; + vld_cycle = mldsa_rejs_dv; + sampler_done = (coeff_cnt == (ABR_COEFF_CNT/4)); + zeroize_mldsa_rejs |= sampler_done; + zeroize_sha3 |= sampler_done; + zeroize_piso |= sampler_done; + piso_mode = ABR_REJS_MODE; + end + ABR_EXP_MASK: begin + mode = abr_sha3_pkg::Shake; + strength = abr_sha3_pkg::L256; + vld_cycle = exp_dv; + sampler_mem_dv_o = exp_dv; + sampler_mem_data_o = exp_data; + sampler_mem_addr_o = dest_addr; + sampler_done = (coeff_cnt == (ABR_COEFF_CNT/4)); + zeroize_exp_mask |= sampler_done; + zeroize_sha3 |= sampler_done; + zeroize_piso |= sampler_done; + piso_mode = ABR_EXP_MODE; + end + ABR_REJ_BOUNDED: begin + mode = abr_sha3_pkg::Shake; + strength = abr_sha3_pkg::L256; + vld_cycle = rejb_dv; + sampler_mem_dv_o = rejb_dv; + sampler_mem_data_o = rejb_data; + sampler_mem_addr_o = dest_addr; + sampler_done = (coeff_cnt == (ABR_COEFF_CNT/4)); + zeroize_rejb |= sampler_done; + zeroize_sha3 |= sampler_done; + zeroize_piso |= sampler_done; + piso_mode = ABR_REJB_MODE; + end + ABR_SAMPLE_IN_BALL: begin + mode = abr_sha3_pkg::Shake; + strength = abr_sha3_pkg::L256; + zeroize_sib_mem = sampler_start_i; + sampler_done = sib_done; + zeroize_sib |= sampler_done; + zeroize_sha3 |= sampler_done; + zeroize_piso |= sampler_done; + piso_mode = ABR_SIB_MODE; + end + ABR_CBD_SAMPLER: begin + mode = abr_sha3_pkg::Shake; + strength = abr_sha3_pkg::L256; + vld_cycle = cbd_dv; + sampler_mem_dv_o = cbd_dv; + for (int coeff = 0; coeff < COEFF_PER_CLK; coeff++) begin + sampler_mem_data_o[coeff][MLKEM_Q_WIDTH-1:0] = cbd_data[coeff]; + end + sampler_mem_addr_o = dest_addr; + sampler_done = (coeff_cnt == (ABR_COEFF_CNT/4)); + zeroize_cbd |= sampler_done; + zeroize_sha3 |= sampler_done; + zeroize_piso |= sampler_done; + piso_mode = ABR_CBD_MODE; + end + default: begin + + end + endcase + end + +//FSM Controller + +//Count coefficients +//Load and increment dest address +always_ff @(posedge clk or negedge rst_b) begin + if (!rst_b) begin + coeff_cnt <= 0; + dest_addr <= 0; + end + else if (zeroize | sampler_done) begin + coeff_cnt <= 0; + dest_addr <= 0; + end + else begin + coeff_cnt <= sampler_start_i ? 'd0 : + vld_cycle ? coeff_cnt + 'd1 : coeff_cnt; + dest_addr <= sampler_start_i ? dest_base_addr_i : + vld_cycle ? dest_addr + 'd1 : dest_addr; + end +end + +always_comb sampler_busy_o = sampler_start_i | (sampler_fsm_ps != ABR_SAMPLER_IDLE); + +//State logic +always_comb begin : sampler_fsm_out_comb + sampler_fsm_ns = sampler_fsm_ps; + sha3_process = 0; + sha3_run = 0; + + unique case (sampler_fsm_ps) + ABR_SAMPLER_IDLE: begin + //wait for start + if (sampler_start_i) + sampler_fsm_ns = ABR_SAMPLER_PROC; + end + ABR_SAMPLER_PROC: begin + sampler_fsm_ns = ABR_SAMPLER_WAIT; + //drive process signal + sha3_process = 1; + end + ABR_SAMPLER_WAIT: begin + if (sampler_done) begin + sampler_fsm_ns = ABR_SAMPLER_DONE; + end else if (sha3_state_dv & ~sha3_state_hold) begin + sampler_fsm_ns = ABR_SAMPLER_RUN; + end + end + ABR_SAMPLER_RUN: begin + if (sampler_done) begin + sampler_fsm_ns = ABR_SAMPLER_DONE; + end else begin + sampler_fsm_ns = ABR_SAMPLER_WAIT; + //drive run signal + sha3_run = 1; + end + end + ABR_SAMPLER_DONE: begin + //Go to IDLE when sha3 resets + if (~sha3_squeezing) begin + sampler_fsm_ns = ABR_SAMPLER_IDLE; + end + end + default: begin + end + endcase +end + +//State flop +always_ff @(posedge clk or negedge rst_b) begin : sampler_fsm_flops + if (!rst_b) begin + sampler_fsm_ps <= ABR_SAMPLER_IDLE; + end + else if (zeroize) begin + sampler_fsm_ps <= ABR_SAMPLER_IDLE; + end + else begin + sampler_fsm_ps <= sampler_fsm_ns; + end +end + +//SHA3 instance + abr_sha3 #( + .RoundsPerClock(RoundsPerClock), + .EnMasking (Sha3EnMasking) + ) sha3_inst ( + .clk_i (clk), + .rst_b (rst_b), + .zeroize (zeroize_sha3), + + // MSG_FIFO interface + .msg_start_i (msg_start_i), + .msg_valid_i (msg_valid_i), + .msg_data_i (msg_data_i), + .msg_strb_i (msg_strobe_i), + .msg_ready_o (msg_rdy_o), + + // Entropy interface - not using + .rand_valid_i (1'b0), + .rand_early_i (1'b0), + .rand_data_i ('0), + .rand_aux_i ('0), + .rand_consumed_o (), + + // N, S: Used in cSHAKE mode + .ns_data_i ('0), + + // Configurations + .mode_i (mode), + .strength_i (strength), + + // Controls (CMD register) + .start_i (sha3_start_i), + .process_i (sha3_process), + .run_i (sha3_run), // For squeeze + + .absorbed_o (), + .squeezing_o (sha3_squeezing), + + .block_processed_o (sha3_block_processed), + + .sha3_fsm_o (sha3_fsm), + + .state_valid_o (sha3_state_dv), + .state_valid_hold_i (sha3_state_hold), + .state_o (sha3_state), + + .error_o (sha3_err), + .sparse_fsm_error_o (sha3_state_error), + .count_error_o (sha3_count_error), + .keccak_storage_rst_error_o (sha3_rst_storage_err) + ); + + always_comb sha3_piso_dv = sha3_state_dv & (sampler_mode_i inside {MLKEM_REJ_SAMPLER, MLDSA_REJ_SAMPLER, ABR_EXP_MASK, + ABR_REJ_BOUNDED, ABR_SAMPLE_IN_BALL, ABR_CBD_SAMPLER}); + + //Multi-rate piso + abr_piso_multi #( + .NUM_MODES(5), + .PISO_BUFFER_W(REJS_PISO_BUFFER_W), + .PISO_ACT_INPUT_RATE(REJS_PISO_INPUT_RATE), + .PISO_ACT_OUTPUT_RATE(REJS_PISO_OUTPUT_RATE), + .INPUT_RATES('{REJS_PISO_INPUT_RATE, REJB_PISO_INPUT_RATE, EXP_PISO_INPUT_RATE, SIB_PISO_INPUT_RATE, CBD_PISO_INPUT_RATE}), + .OUTPUT_RATES('{REJS_PISO_OUTPUT_RATE, REJB_PISO_OUTPUT_RATE, EXP_PISO_OUTPUT_RATE, SIB_PISO_OUTPUT_RATE, CBD_PISO_OUTPUT_RATE}) + ) abr_piso_inst ( + .clk(clk), + .rst_b(rst_b), + .zeroize(zeroize_piso), + .mode(piso_mode), + .valid_i(sha3_piso_dv), + .hold_o(sha3_state_hold), + .data_i(sha3_state[0][REJS_PISO_INPUT_RATE-1:0]), + .valid_o(piso_dv), + .hold_i(piso_hold), + .data_o(piso_data) + ); + + always_comb mldsa_rejs_piso_dv = piso_dv & (sampler_mode_i == MLDSA_REJ_SAMPLER); + always_comb mlkem_rejs_piso_dv = piso_dv & (sampler_mode_i == MLKEM_REJ_SAMPLER); + always_comb rejb_piso_dv = piso_dv & (sampler_mode_i == ABR_REJ_BOUNDED); + always_comb exp_piso_dv = piso_dv & (sampler_mode_i == ABR_EXP_MASK); + always_comb sib_piso_dv = piso_dv & (sampler_mode_i == ABR_SAMPLE_IN_BALL); + always_comb cbd_piso_dv = piso_dv & (sampler_mode_i == ABR_CBD_SAMPLER); + + always_comb piso_hold = ((sampler_mode_i == MLDSA_REJ_SAMPLER) & mldsa_rejs_piso_hold) | + ((sampler_mode_i == MLKEM_REJ_SAMPLER) & mlkem_rejs_piso_hold) | + ((sampler_mode_i == ABR_REJ_BOUNDED) & rejb_piso_hold) | + ((sampler_mode_i == ABR_EXP_MASK) & exp_piso_hold) | + ((sampler_mode_i == ABR_SAMPLE_IN_BALL) & sib_piso_hold) | + ((sampler_mode_i == ABR_CBD_SAMPLER) & cbd_piso_hold); + + always_comb rejs_piso_data = piso_data[REJS_PISO_OUTPUT_RATE-1:0]; + always_comb rejb_piso_data = piso_data[REJB_PISO_OUTPUT_RATE-1:0]; + always_comb exp_piso_data = piso_data[EXP_PISO_OUTPUT_RATE-1:0]; + always_comb sib_piso_data = piso_data[SIB_PISO_OUTPUT_RATE-1:0]; + always_comb cbd_piso_data = piso_data[CBD_PISO_OUTPUT_RATE-1:0]; + + rej_sampler_ctrl#( + .REJ_NUM_SAMPLERS(MLDSA_REJS_NUM_SAMPLERS), + .REJ_SAMPLE_W(MLDSA_REJS_SAMPLE_W), + .REJ_VLD_SAMPLES(REJS_VLD_SAMPLES), + .REJ_VLD_SAMPLES_W(MLDSA_Q_WIDTH), + .REJ_VALUE(MLDSA_Q) + ) mldsa_rej_sampler_inst ( + .clk(clk), + .rst_b(rst_b), + .zeroize(zeroize_mldsa_rejs), + //input data + .data_valid_i(mldsa_rejs_piso_dv), + .data_hold_o(mldsa_rejs_piso_hold), + .data_i(rejs_piso_data), + + //output data + .data_valid_o(mldsa_rejs_dv), + .data_o(mldsa_rejs_data_q) + ); + + rej_sampler_ctrl#( + .REJ_NUM_SAMPLERS(MLKEM_REJS_NUM_SAMPLERS), + .REJ_SAMPLE_W(MLKEM_REJS_SAMPLE_W), + .REJ_VLD_SAMPLES(REJS_VLD_SAMPLES), + .REJ_VLD_SAMPLES_W(MLKEM_Q_WIDTH), + .REJ_VALUE(MLKEM_Q) + ) mlkem_rej_sampler_inst ( + .clk(clk), + .rst_b(rst_b), + .zeroize(zeroize_mlkem_rejs), + //input data + .data_valid_i(mlkem_rejs_piso_dv), + .data_hold_o(mlkem_rejs_piso_hold), + .data_i(rejs_piso_data), + + //output data + .data_valid_o(mlkem_rejs_dv), + .data_o(mlkem_rejs_data_q) + ); + +//optimization - align sampler data in ntt +always_ff @(posedge clk or negedge rst_b) begin : delay_rejs_data + if (!rst_b) begin + sampler_ntt_data_o <= 0; + end + else if (zeroize) begin + sampler_ntt_data_o <= 0; + end + else begin + for (int i = 0; i < COEFF_PER_CLK; i++) begin + sampler_ntt_data_o[i] <= {MLDSA_Q_WIDTH{(sampler_mode_i == MLDSA_REJ_SAMPLER)}} & mldsa_rejs_data_q[i] | + {MLDSA_Q_WIDTH{(sampler_mode_i == MLKEM_REJ_SAMPLER)}} & {{MLDSA_Q_WIDTH-MLKEM_Q_WIDTH{1'b0}},mlkem_rejs_data_q[i]}; + end + end +end + +//rej sampler output gets sent to NTT +always_comb sampler_ntt_dv_o = mldsa_rejs_dv | mlkem_rejs_dv; + +//rej bounded + rej_bounded_ctrl #( + .REJ_NUM_SAMPLERS(REJB_NUM_SAMPLERS), + .REJ_SAMPLE_W(REJB_SAMPLE_W), + .REJ_VLD_SAMPLES(REJB_VLD_SAMPLES), + .REJ_VALUE(REJB_VALUE) + ) rej_bounded_inst ( + .clk(clk), + .rst_b(rst_b), + .zeroize(zeroize_rejb), + //input data + .data_valid_i(rejb_piso_dv), + .data_hold_o(rejb_piso_hold), + .data_i(rejb_piso_data), + + //output data + .data_valid_o(rejb_dv), + .data_o(rejb_data) + ); + +//exp mask + exp_mask_ctrl #( + .EXP_NUM_SAMPLERS(EXP_NUM_SAMPLERS), + .EXP_SAMPLE_W(EXP_SAMPLE_W), + .EXP_VLD_SAMPLES(EXP_VLD_SAMPLES), + .EXP_VLD_SAMPLE_W(EXP_VLD_SAMPLE_W) + ) exp_mask_inst ( + .clk(clk), + .rst_b(rst_b), + .zeroize(zeroize_exp_mask), + //input data + .data_valid_i(exp_piso_dv), + .data_hold_o(exp_piso_hold), + .data_i(exp_piso_data), + + //output data + .data_valid_o(exp_dv), + .data_o(exp_data) + ); + +//sample in ball + //Mux read from NTT in here + always_comb sib_mem_addr_mux[0] = (sib_mem_rd_req_i.rd_wr_en == RW_READ) ? sib_mem_rd_req_i.addr[5:0] : sib_mem_addr[0]; + always_comb sib_mem_addr_mux[1] = sib_mem_addr[1]; + always_comb sib_mem_cs_mux[0] = (sib_mem_rd_req_i.rd_wr_en == RW_READ) | sib_mem_cs[0]; + always_comb sib_mem_cs_mux[1] = sib_mem_cs[1]; + + //ugly expansion of 23->24 bits + assign sib_mem_rd_data_o = {1'b0,sib_mem_rddata[0][3],1'b0,sib_mem_rddata[0][2],1'b0,sib_mem_rddata[0][1],1'b0,sib_mem_rddata[0][0]}; + + sib_mem + #( + .DATA_WIDTH((MLDSA_Q_WIDTH-1)*4), + .DEPTH (MLDSA_N/4), + .NUM_PORTS (2) + ) + sib_mem_inst + ( + .clk_i(clk), + .rst_b(rst_b), + .zeroize(zeroize_sib_mem), + .cs_i(sib_mem_cs_mux), + .we_i(sib_mem_we), + .addr_i(sib_mem_addr_mux), + .wdata_i(sib_mem_wrdata), + + .rdata_o(sib_mem_rddata) + ); + + sample_in_ball_ctrl #( + .SIB_NUM_SAMPLERS(SIB_NUM_SAMPLERS), + .SIB_SAMPLE_W(SIB_SAMPLE_W), + .SIB_TAU(SIB_TAU) + ) sib_inst ( + .clk(clk), + .rst_b(rst_b), + .zeroize(zeroize_sib), + //input data + .data_valid_i(sib_piso_dv), + .data_hold_o(sib_piso_hold), + .data_i(sib_piso_data), + .sib_done_o(sib_done), + + //memory_if + .cs_o(sib_mem_cs), + .we_o(sib_mem_we), + .addr_o(sib_mem_addr), + .wrdata_o(sib_mem_wrdata), + .rddata_i(sib_mem_rddata) + ); + + cbd_sampler_ctrl + cbd_sampler_inst ( + .clk(clk), + .rst_b(rst_b), + .zeroize(zeroize_cbd), + //input data + .data_valid_i(cbd_piso_dv), + .data_hold_o(cbd_piso_hold), + .data_i(cbd_piso_data), + + //output data + .data_valid_o(cbd_dv), + .data_o(cbd_data) + ); + + `ABR_ASSERT_MUTEX(ERR_SAMPLER_O_MUTEX, {sampler_ntt_dv_o,sampler_mem_dv_o,sampler_state_dv_o}, clk, !rst_b) + + `ABR_ASSERT_NEVER(ERR_SIBMEM_ACCESS, (sib_mem_rd_req_i.rd_wr_en == RW_READ) && |sib_mem_cs, clk, !rst_b) + + `ABR_ASSERT_KNOWN(ERR_SAMPLER_FSM_X, sampler_fsm_ps, clk, !rst_b) + `ABR_ASSERT_KNOWN(ERR_SAMPLER_MODE_X, sampler_mode_i, clk, !rst_b) + `ABR_ASSERT_KNOWN(ERR_SAMPLER_NTT_DATA_X, sampler_ntt_data_o, clk, !rst_b, sampler_ntt_dv_o) + `ABR_ASSERT_KNOWN(ERR_SAMPLER_MEM_DATA_X, sampler_mem_data_o, clk, !rst_b, sampler_mem_dv_o) + `ABR_ASSERT_KNOWN(ERR_SAMPLER_STATE_DATA_X, sampler_state_data_o[0], clk, !rst_b, sampler_state_dv_o) + +endmodule diff --git a/designs/Caliptra/src/adams-bridge/abr_seq.sv b/designs/Caliptra/src/adams-bridge/abr_seq.sv new file mode 100644 index 0000000..b1defed --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/abr_seq.sv @@ -0,0 +1,741 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. + +//Sequencer for ABR +//ML-DSA functions +// Keygen +// Signing +// Verify +//ML-KEM functions +// Keygen + +module abr_seq + import abr_ctrl_pkg::*; + ( + input logic clk, + + input logic en_i, + input logic [ABR_PROG_ADDR_W-1 : 0] addr_i, + output abr_seq_instr_t data_o + ); + + +`ifdef RV_FPGA_OPTIMIZE + (*rom_style = "block" *) abr_seq_instr_t data_o_rom; +`else + abr_seq_instr_t data_o_rom; +`endif + assign data_o = data_o_rom; + + //---------------------------------------------------------------- + // ROM content + //---------------------------------------------------------------- + + always_ff @(posedge clk) begin + if (en_i) begin + unique case(addr_i) + //RESET + ABR_RESET : data_o_rom <= '{opcode:ABR_UOP_NOP, imm:'h0000, length:'d00, operand1:ABR_NOP, operand2:ABR_NOP, operand3:ABR_NOP}; + + //ZEROIZE + ABR_ZEROIZE : data_o_rom <= '{opcode:ABR_UOP_NOP, imm:'h0000, length:'d00, operand1:ABR_NOP, operand2:ABR_NOP, operand3:ABR_NOP}; + + //KEYGEN + //rnd_seed=Keccak(entropy||counter) + MLDSA_KG_S : data_o_rom <= '{opcode:ABR_UOP_LD_SHAKE256, imm:'h0000, length:'d64, operand1:ABR_ENTROPY_ID, operand2:ABR_NOP, operand3:ABR_NOP}; + MLDSA_KG_S+ 1 : data_o_rom <= '{opcode:ABR_UOP_SHAKE256, imm:'h0000, length:'d08, operand1:ABR_CNT_ID, operand2:ABR_NOP, operand3:ABR_DEST_LFSR_SEED_REG_ID}; + MLDSA_KG_S+ 2 : data_o_rom <= '{opcode:ABR_UOP_LFSR, imm:'h0000, length:'d00, operand1:ABR_NOP, operand2:ABR_NOP, operand3:ABR_NOP}; + //(p,p',K)=Keccak(seed) + // //SHAKE256 operation //SRC //SRC2 //DEST + MLDSA_KG_S+ 3 : data_o_rom <= '{opcode:ABR_UOP_SHAKE256, imm:'h0708, length:'d34, operand1:MLDSA_SEED_ID, operand2:ABR_NOP, operand3:MLDSA_DEST_K_RHO_REG_ID}; + //s1=expandS + // //Rej Bounded op //SRC imm //SRC1 //SRC2 //DEST + MLDSA_KG_S+ 4 : data_o_rom <= '{opcode:ABR_UOP_REJB, imm:'h0000, length:'d66, operand1:MLDSA_RHO_P_ID, operand2:ABR_NOP, operand3:MLDSA_S1_0_BASE}; + MLDSA_KG_S+ 5 : data_o_rom <= '{opcode:ABR_UOP_REJB, imm:'h0001, length:'d66, operand1:MLDSA_RHO_P_ID, operand2:ABR_NOP, operand3:MLDSA_S1_1_BASE}; + MLDSA_KG_S+ 6 : data_o_rom <= '{opcode:ABR_UOP_REJB, imm:'h0002, length:'d66, operand1:MLDSA_RHO_P_ID, operand2:ABR_NOP, operand3:MLDSA_S1_2_BASE}; + MLDSA_KG_S+ 7 : data_o_rom <= '{opcode:ABR_UOP_REJB, imm:'h0003, length:'d66, operand1:MLDSA_RHO_P_ID, operand2:ABR_NOP, operand3:MLDSA_S1_3_BASE}; + MLDSA_KG_S+ 8 : data_o_rom <= '{opcode:ABR_UOP_REJB, imm:'h0004, length:'d66, operand1:MLDSA_RHO_P_ID, operand2:ABR_NOP, operand3:MLDSA_S1_4_BASE}; + MLDSA_KG_S+ 9 : data_o_rom <= '{opcode:ABR_UOP_REJB, imm:'h0005, length:'d66, operand1:MLDSA_RHO_P_ID, operand2:ABR_NOP, operand3:MLDSA_S1_5_BASE}; + MLDSA_KG_S+ 10 : data_o_rom <= '{opcode:ABR_UOP_REJB, imm:'h0006, length:'d66, operand1:MLDSA_RHO_P_ID, operand2:ABR_NOP, operand3:MLDSA_S1_6_BASE}; + //s1=expandS + MLDSA_KG_S+ 11 : data_o_rom <= '{opcode:ABR_UOP_REJB, imm:'h0007, length:'d66, operand1:MLDSA_RHO_P_ID, operand2:ABR_NOP, operand3:MLDSA_S2_0_BASE}; + MLDSA_KG_S+ 12 : data_o_rom <= '{opcode:ABR_UOP_REJB, imm:'h0008, length:'d66, operand1:MLDSA_RHO_P_ID, operand2:ABR_NOP, operand3:MLDSA_S2_1_BASE}; + MLDSA_KG_S+ 13 : data_o_rom <= '{opcode:ABR_UOP_REJB, imm:'h0009, length:'d66, operand1:MLDSA_RHO_P_ID, operand2:ABR_NOP, operand3:MLDSA_S2_2_BASE}; + MLDSA_KG_S+ 14 : data_o_rom <= '{opcode:ABR_UOP_REJB, imm:'h000A, length:'d66, operand1:MLDSA_RHO_P_ID, operand2:ABR_NOP, operand3:MLDSA_S2_3_BASE}; + MLDSA_KG_S+ 15 : data_o_rom <= '{opcode:ABR_UOP_REJB, imm:'h000B, length:'d66, operand1:MLDSA_RHO_P_ID, operand2:ABR_NOP, operand3:MLDSA_S2_4_BASE}; + MLDSA_KG_S+ 16 : data_o_rom <= '{opcode:ABR_UOP_REJB, imm:'h000C, length:'d66, operand1:MLDSA_RHO_P_ID, operand2:ABR_NOP, operand3:MLDSA_S2_5_BASE}; + MLDSA_KG_S+ 17 : data_o_rom <= '{opcode:ABR_UOP_REJB, imm:'h000D, length:'d66, operand1:MLDSA_RHO_P_ID, operand2:ABR_NOP, operand3:MLDSA_S2_6_BASE}; + MLDSA_KG_S+ 18 : data_o_rom <= '{opcode:ABR_UOP_REJB, imm:'h000E, length:'d66, operand1:MLDSA_RHO_P_ID, operand2:ABR_NOP, operand3:MLDSA_S2_7_BASE}; + //NTT(s1) + MLDSA_KG_S+ 19 : data_o_rom <= '{opcode:ABR_UOP_NTT, imm:'h0000, length:'d00, operand1:MLDSA_S1_0_BASE, operand2:MLDSA_TEMP0_BASE, operand3:MLDSA_S1_0_NTT_BASE}; + MLDSA_KG_S+ 20 : data_o_rom <= '{opcode:ABR_UOP_NTT, imm:'h0000, length:'d00, operand1:MLDSA_S1_1_BASE, operand2:MLDSA_TEMP0_BASE, operand3:MLDSA_S1_1_NTT_BASE}; + MLDSA_KG_S+ 21 : data_o_rom <= '{opcode:ABR_UOP_NTT, imm:'h0000, length:'d00, operand1:MLDSA_S1_2_BASE, operand2:MLDSA_TEMP0_BASE, operand3:MLDSA_S1_2_NTT_BASE}; + MLDSA_KG_S+ 22 : data_o_rom <= '{opcode:ABR_UOP_NTT, imm:'h0000, length:'d00, operand1:MLDSA_S1_3_BASE, operand2:MLDSA_TEMP0_BASE, operand3:MLDSA_S1_3_NTT_BASE}; + MLDSA_KG_S+ 23 : data_o_rom <= '{opcode:ABR_UOP_NTT, imm:'h0000, length:'d00, operand1:MLDSA_S1_4_BASE, operand2:MLDSA_TEMP0_BASE, operand3:MLDSA_S1_4_NTT_BASE}; + MLDSA_KG_S+ 24 : data_o_rom <= '{opcode:ABR_UOP_NTT, imm:'h0000, length:'d00, operand1:MLDSA_S1_5_BASE, operand2:MLDSA_TEMP0_BASE, operand3:MLDSA_S1_5_NTT_BASE}; + MLDSA_KG_S+ 25 : data_o_rom <= '{opcode:ABR_UOP_NTT, imm:'h0000, length:'d00, operand1:MLDSA_S1_6_BASE, operand2:MLDSA_TEMP0_BASE, operand3:MLDSA_S1_6_NTT_BASE}; + //ExpandA(ρ) AND Aˆ NTT(s1) + MLDSA_KG_S+ 26 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWM, imm:'h0000, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_S1_0_NTT_BASE, operand3:MLDSA_AS0_BASE}; + MLDSA_KG_S+ 27 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWMA, imm:'h0001, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_S1_1_NTT_BASE, operand3:MLDSA_AS0_BASE}; + MLDSA_KG_S+ 28 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWMA, imm:'h0002, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_S1_2_NTT_BASE, operand3:MLDSA_AS0_BASE}; + MLDSA_KG_S+ 29 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWMA, imm:'h0003, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_S1_3_NTT_BASE, operand3:MLDSA_AS0_BASE}; + MLDSA_KG_S+ 30 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWMA, imm:'h0004, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_S1_4_NTT_BASE, operand3:MLDSA_AS0_BASE}; + MLDSA_KG_S+ 31 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWMA, imm:'h0005, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_S1_5_NTT_BASE, operand3:MLDSA_AS0_BASE}; + MLDSA_KG_S+ 32 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWMA, imm:'h0006, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_S1_6_NTT_BASE, operand3:MLDSA_AS0_BASE}; + //NTT−1(Aˆ ◦NTT(s1)) + MLDSA_KG_S+ 33 : data_o_rom <= '{opcode:ABR_UOP_INTT, imm:'d01, length:'d00, operand1:MLDSA_AS0_BASE, operand2:MLDSA_TEMP2_BASE, operand3:MLDSA_AS0_INTT_BASE}; + //t ←NTT−1(Aˆ ◦NTT(s1))+s2 + MLDSA_KG_S+ 34 : data_o_rom <= '{opcode:ABR_UOP_PWA, imm:'d00, length:'d00, operand1:MLDSA_AS0_INTT_BASE, operand2:MLDSA_S2_0_BASE, operand3:MLDSA_T0_BASE}; + //ExpandA(ρ) AND Aˆ NTT(s1) + MLDSA_KG_S+ 35 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWM, imm:'h0100, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_S1_0_NTT_BASE, operand3:MLDSA_AS0_BASE}; + MLDSA_KG_S+ 36 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWMA, imm:'h0101, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_S1_1_NTT_BASE, operand3:MLDSA_AS0_BASE}; + MLDSA_KG_S+ 37 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWMA, imm:'h0102, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_S1_2_NTT_BASE, operand3:MLDSA_AS0_BASE}; + MLDSA_KG_S+ 38 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWMA, imm:'h0103, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_S1_3_NTT_BASE, operand3:MLDSA_AS0_BASE}; + MLDSA_KG_S+ 39 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWMA, imm:'h0104, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_S1_4_NTT_BASE, operand3:MLDSA_AS0_BASE}; + MLDSA_KG_S+ 40 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWMA, imm:'h0105, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_S1_5_NTT_BASE, operand3:MLDSA_AS0_BASE}; + MLDSA_KG_S+ 41 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWMA, imm:'h0106, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_S1_6_NTT_BASE, operand3:MLDSA_AS0_BASE}; + //NTT−1(Aˆ ◦NTT(s1)) + MLDSA_KG_S+ 42 : data_o_rom <= '{opcode:ABR_UOP_INTT, imm:'d01, length:'d00, operand1:MLDSA_AS0_BASE, operand2:MLDSA_TEMP2_BASE, operand3:MLDSA_AS0_INTT_BASE}; + //t ←NTT−1(Aˆ ◦NTT(s1))+s2 + MLDSA_KG_S+ 43 : data_o_rom <= '{opcode:ABR_UOP_PWA, imm:'d00, length:'d00, operand1:MLDSA_AS0_INTT_BASE, operand2:MLDSA_S2_1_BASE, operand3:MLDSA_T1_BASE}; + //ExpandA(ρ) AND Aˆ NTT(s1) + MLDSA_KG_S+ 44 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWM, imm:'h0200, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_S1_0_NTT_BASE, operand3:MLDSA_AS0_BASE}; + MLDSA_KG_S+ 45 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWMA, imm:'h0201, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_S1_1_NTT_BASE, operand3:MLDSA_AS0_BASE}; + MLDSA_KG_S+ 46 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWMA, imm:'h0202, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_S1_2_NTT_BASE, operand3:MLDSA_AS0_BASE}; + MLDSA_KG_S+ 47 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWMA, imm:'h0203, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_S1_3_NTT_BASE, operand3:MLDSA_AS0_BASE}; + MLDSA_KG_S+ 48 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWMA, imm:'h0204, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_S1_4_NTT_BASE, operand3:MLDSA_AS0_BASE}; + MLDSA_KG_S+ 49 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWMA, imm:'h0205, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_S1_5_NTT_BASE, operand3:MLDSA_AS0_BASE}; + MLDSA_KG_S+ 50 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWMA, imm:'h0206, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_S1_6_NTT_BASE, operand3:MLDSA_AS0_BASE}; + //NTT−1(Aˆ ◦NTT(s1)) + MLDSA_KG_S+ 51 : data_o_rom <= '{opcode:ABR_UOP_INTT, imm:'d01, length:'d00, operand1:MLDSA_AS0_BASE, operand2:MLDSA_TEMP2_BASE, operand3:MLDSA_AS0_INTT_BASE}; + //t ←NTT−1(Aˆ ◦NTT(s1))+s2 + MLDSA_KG_S+ 52 : data_o_rom <= '{opcode:ABR_UOP_PWA, imm:'d00, length:'d00, operand1:MLDSA_AS0_INTT_BASE, operand2:MLDSA_S2_2_BASE, operand3:MLDSA_T2_BASE}; + //ExpandA(ρ) AND Aˆ NTT(s1) + MLDSA_KG_S+ 53 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWM, imm:'h0300, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_S1_0_NTT_BASE, operand3:MLDSA_AS0_BASE}; + MLDSA_KG_S+ 54 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWMA, imm:'h0301, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_S1_1_NTT_BASE, operand3:MLDSA_AS0_BASE}; + MLDSA_KG_S+ 55 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWMA, imm:'h0302, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_S1_2_NTT_BASE, operand3:MLDSA_AS0_BASE}; + MLDSA_KG_S+ 56 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWMA, imm:'h0303, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_S1_3_NTT_BASE, operand3:MLDSA_AS0_BASE}; + MLDSA_KG_S+ 57 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWMA, imm:'h0304, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_S1_4_NTT_BASE, operand3:MLDSA_AS0_BASE}; + MLDSA_KG_S+ 58 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWMA, imm:'h0305, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_S1_5_NTT_BASE, operand3:MLDSA_AS0_BASE}; + MLDSA_KG_S+ 59 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWMA, imm:'h0306, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_S1_6_NTT_BASE, operand3:MLDSA_AS0_BASE}; + //NTT−1(Aˆ ◦NTT(s1)) + MLDSA_KG_S+ 60 : data_o_rom <= '{opcode:ABR_UOP_INTT, imm:'d01, length:'d00, operand1:MLDSA_AS0_BASE, operand2:MLDSA_TEMP2_BASE, operand3:MLDSA_AS0_INTT_BASE}; + //t ←NTT−1(Aˆ ◦NTT(s1))+s2 + MLDSA_KG_S+ 61 : data_o_rom <= '{opcode:ABR_UOP_PWA, imm:'d00, length:'d00, operand1:MLDSA_AS0_INTT_BASE, operand2:MLDSA_S2_3_BASE, operand3:MLDSA_T3_BASE}; + //ExpandA(ρ) AND Aˆ NTT(s1) + MLDSA_KG_S+ 62 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWM, imm:'h0400, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_S1_0_NTT_BASE, operand3:MLDSA_AS0_BASE}; + MLDSA_KG_S+ 63 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWMA, imm:'h0401, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_S1_1_NTT_BASE, operand3:MLDSA_AS0_BASE}; + MLDSA_KG_S+ 64 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWMA, imm:'h0402, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_S1_2_NTT_BASE, operand3:MLDSA_AS0_BASE}; + MLDSA_KG_S+ 65 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWMA, imm:'h0403, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_S1_3_NTT_BASE, operand3:MLDSA_AS0_BASE}; + MLDSA_KG_S+ 66 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWMA, imm:'h0404, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_S1_4_NTT_BASE, operand3:MLDSA_AS0_BASE}; + MLDSA_KG_S+ 67 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWMA, imm:'h0405, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_S1_5_NTT_BASE, operand3:MLDSA_AS0_BASE}; + MLDSA_KG_S+ 68 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWMA, imm:'h0406, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_S1_6_NTT_BASE, operand3:MLDSA_AS0_BASE}; + //NTT−1(Aˆ ◦NTT(s1)) + MLDSA_KG_S+ 69 : data_o_rom <= '{opcode:ABR_UOP_INTT, imm:'d01, length:'d00, operand1:MLDSA_AS0_BASE, operand2:MLDSA_TEMP2_BASE, operand3:MLDSA_AS0_INTT_BASE}; + //t ←NTT−1(Aˆ ◦NTT(s1))+s2 + MLDSA_KG_S+ 70 : data_o_rom <= '{opcode:ABR_UOP_PWA, imm:'d00, length:'d00, operand1:MLDSA_AS0_INTT_BASE, operand2:MLDSA_S2_4_BASE, operand3:MLDSA_T4_BASE}; + //ExpandA(ρ) AND Aˆ NTT(s1) + MLDSA_KG_S+ 71 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWM, imm:'h0500, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_S1_0_NTT_BASE, operand3:MLDSA_AS0_BASE}; + MLDSA_KG_S+ 72 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWMA, imm:'h0501, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_S1_1_NTT_BASE, operand3:MLDSA_AS0_BASE}; + MLDSA_KG_S+ 73 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWMA, imm:'h0502, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_S1_2_NTT_BASE, operand3:MLDSA_AS0_BASE}; + MLDSA_KG_S+ 74 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWMA, imm:'h0503, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_S1_3_NTT_BASE, operand3:MLDSA_AS0_BASE}; + MLDSA_KG_S+ 75 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWMA, imm:'h0504, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_S1_4_NTT_BASE, operand3:MLDSA_AS0_BASE}; + MLDSA_KG_S+ 76 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWMA, imm:'h0505, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_S1_5_NTT_BASE, operand3:MLDSA_AS0_BASE}; + MLDSA_KG_S+ 77 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWMA, imm:'h0506, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_S1_6_NTT_BASE, operand3:MLDSA_AS0_BASE}; + //NTT−1(Aˆ ◦NTT(s1)) + MLDSA_KG_S+ 78 : data_o_rom <= '{opcode:ABR_UOP_INTT, imm:'d01, length:'d00, operand1:MLDSA_AS0_BASE, operand2:MLDSA_TEMP2_BASE, operand3:MLDSA_AS0_INTT_BASE}; + //t ←NTT−1(Aˆ ◦NTT(s1))+s2 + MLDSA_KG_S+ 79 : data_o_rom <= '{opcode:ABR_UOP_PWA, imm:'d00, length:'d00, operand1:MLDSA_AS0_INTT_BASE, operand2:MLDSA_S2_5_BASE, operand3:MLDSA_T5_BASE}; + //ExpandA(ρ) AND Aˆ NTT(s1) + MLDSA_KG_S+ 80 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWM, imm:'h0600, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_S1_0_NTT_BASE, operand3:MLDSA_AS0_BASE}; + MLDSA_KG_S+ 81 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWMA, imm:'h0601, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_S1_1_NTT_BASE, operand3:MLDSA_AS0_BASE}; + MLDSA_KG_S+ 82 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWMA, imm:'h0602, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_S1_2_NTT_BASE, operand3:MLDSA_AS0_BASE}; + MLDSA_KG_S+ 83 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWMA, imm:'h0603, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_S1_3_NTT_BASE, operand3:MLDSA_AS0_BASE}; + MLDSA_KG_S+ 84 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWMA, imm:'h0604, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_S1_4_NTT_BASE, operand3:MLDSA_AS0_BASE}; + MLDSA_KG_S+ 85 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWMA, imm:'h0605, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_S1_5_NTT_BASE, operand3:MLDSA_AS0_BASE}; + MLDSA_KG_S+ 86 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWMA, imm:'h0606, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_S1_6_NTT_BASE, operand3:MLDSA_AS0_BASE}; + //NTT−1(Aˆ ◦NTT(s1)) + MLDSA_KG_S+ 87 : data_o_rom <= '{opcode:ABR_UOP_INTT, imm:'d01, length:'d00, operand1:MLDSA_AS0_BASE, operand2:MLDSA_TEMP2_BASE, operand3:MLDSA_AS0_INTT_BASE}; + //t ←NTT−1(Aˆ ◦NTT(s1))+s2 + MLDSA_KG_S+ 88 : data_o_rom <= '{opcode:ABR_UOP_PWA, imm:'d00, length:'d00, operand1:MLDSA_AS0_INTT_BASE, operand2:MLDSA_S2_6_BASE, operand3:MLDSA_T6_BASE}; + //ExpandA(ρ) AND Aˆ NTT(s1) + MLDSA_KG_S+ 89 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWM, imm:'h0700, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_S1_0_NTT_BASE, operand3:MLDSA_AS0_BASE}; + MLDSA_KG_S+ 90 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWMA, imm:'h0701, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_S1_1_NTT_BASE, operand3:MLDSA_AS0_BASE}; + MLDSA_KG_S+ 91 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWMA, imm:'h0702, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_S1_2_NTT_BASE, operand3:MLDSA_AS0_BASE}; + MLDSA_KG_S+ 92 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWMA, imm:'h0703, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_S1_3_NTT_BASE, operand3:MLDSA_AS0_BASE}; + MLDSA_KG_S+ 93 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWMA, imm:'h0704, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_S1_4_NTT_BASE, operand3:MLDSA_AS0_BASE}; + MLDSA_KG_S+ 94 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWMA, imm:'h0705, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_S1_5_NTT_BASE, operand3:MLDSA_AS0_BASE}; + MLDSA_KG_S+ 95 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWMA, imm:'h0706, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_S1_6_NTT_BASE, operand3:MLDSA_AS0_BASE}; + //NTT−1(Aˆ ◦NTT(s1)) + MLDSA_KG_S+ 96 : data_o_rom <= '{opcode:ABR_UOP_INTT, imm:'d01, length:'d00, operand1:MLDSA_AS0_BASE, operand2:MLDSA_TEMP2_BASE, operand3:MLDSA_AS0_INTT_BASE}; + //t ←NTT−1(Aˆ ◦NTT(s1))+s2 + MLDSA_KG_S+ 97 : data_o_rom <= '{opcode:ABR_UOP_PWA, imm:'d00, length:'d00, operand1:MLDSA_AS0_INTT_BASE, operand2:MLDSA_S2_7_BASE, operand3:MLDSA_T7_BASE}; + //(t1,t0)←Power2Round(t,d) AND pk ←pkEncode(ρ,t1) + MLDSA_KG_S+ 98 : data_o_rom <= '{opcode:ABR_UOP_PWR2RND, imm:'h0000, length:'d00, operand1:MLDSA_T0_BASE, operand2:ABR_NOP, operand3:MLDSA_SK_T0_OFFSET}; + //tr ←H(BytesToBits(pk),512) + MLDSA_KG_S+ 99 : data_o_rom <= '{opcode:ABR_UOP_SHAKE256, imm:'h0000, length:PUBKEY_NUM_BYTES, operand1:MLDSA_PK_REG_ID, operand2:ABR_NOP, operand3:MLDSA_DEST_TR_REG_ID}; + //sk ←skEncode(ρ,K,tr,s1,s2,t0) + MLDSA_KG_S+ 100 : data_o_rom <= '{opcode:ABR_UOP_SKENCODE, imm:'h0000, length:'d00, operand1:MLDSA_S1_0_BASE, operand2:ABR_NOP, operand3:ABR_NOP}; + MLDSA_KG_JUMP_SIGN : data_o_rom <= '{opcode:ABR_UOP_NOP, imm:'h0000, length:'d00, operand1:ABR_NOP, operand2:ABR_NOP, operand3:ABR_NOP}; + //KG end + MLDSA_KG_E : data_o_rom <= '{opcode:ABR_UOP_NOP, imm:'h0000, length:'d00, operand1:ABR_NOP, operand2:ABR_NOP, operand3:ABR_NOP}; + + //rnd_seed=Keccak(entropy||counter) + MLDSA_SIGN_S : data_o_rom <= '{opcode:ABR_UOP_LD_SHAKE256, imm:'h0000, length:'d64, operand1:ABR_ENTROPY_ID, operand2:ABR_NOP, operand3:ABR_NOP}; + MLDSA_SIGN_S+ 1 : data_o_rom <= '{opcode:ABR_UOP_SHAKE256, imm:'h0000, length:'d08, operand1:ABR_CNT_ID, operand2:ABR_NOP, operand3:ABR_DEST_LFSR_SEED_REG_ID}; + MLDSA_SIGN_S+ 2 : data_o_rom <= '{opcode:ABR_UOP_LFSR, imm:'h0000, length:'d00, operand1:ABR_NOP, operand2:ABR_NOP, operand3:ABR_NOP}; + MLDSA_SIGN_CHECK_MODE : data_o_rom <= '{opcode:ABR_UOP_NOP, imm:'h0000, length:'d00, operand1:ABR_NOP, operand2:ABR_NOP, operand3:ABR_NOP}; + //μ ←H(tr||M,512) + MLDSA_SIGN_H_MU : data_o_rom <= '{opcode:ABR_UOP_LD_SHAKE256, imm:'h0000, length:'d64, operand1:MLDSA_TR_ID, operand2:ABR_NOP, operand3:ABR_NOP}; + MLDSA_SIGN_H_MU + 1 : data_o_rom <= '{opcode:ABR_UOP_SHAKE256, imm:'h0000, length:'d66, operand1:MLDSA_MSG_ID, operand2:ABR_NOP, operand3:MLDSA_DEST_MU_REG_ID}; + //ρ′=Keccak(K||rnd|| μ) + MLDSA_SIGN_H_RHO_P : data_o_rom <= '{opcode:ABR_UOP_LD_SHAKE256, imm:'h0000, length:'d32, operand1:MLDSA_K_ID, operand2:ABR_NOP, operand3:ABR_NOP}; + MLDSA_SIGN_H_RHO_P+ 1 : data_o_rom <= '{opcode:ABR_UOP_LD_SHAKE256, imm:'h0000, length:'d32, operand1:MLDSA_SIGN_RND_ID, operand2:ABR_NOP, operand3:ABR_NOP}; + MLDSA_SIGN_H_RHO_P+ 2 : data_o_rom <= '{opcode:ABR_UOP_SHAKE256, imm:'h0000, length:'d64, operand1:MLDSA_MU_ID, operand2:ABR_NOP, operand3:MLDSA_DEST_RHO_P_REG_ID}; + + //Signing initial steps start + MLDSA_SIGN_INIT_S : data_o_rom <= '{opcode:ABR_UOP_SKDECODE, imm:'h0000, length:'d00, operand1:ABR_NOP, operand2:ABR_NOP, operand3:MLDSA_S1_0_BASE}; + //NTT(t0) + MLDSA_SIGN_INIT_S+1 : data_o_rom <= '{opcode:ABR_UOP_NTT, imm:'h0000, length:'d00, operand1:MLDSA_T0_BASE, operand2:MLDSA_TEMP0_BASE, operand3:MLDSA_T0_BASE}; + MLDSA_SIGN_INIT_S+2 : data_o_rom <= '{opcode:ABR_UOP_NTT, imm:'h0000, length:'d00, operand1:MLDSA_T1_BASE, operand2:MLDSA_TEMP0_BASE, operand3:MLDSA_T1_BASE}; + MLDSA_SIGN_INIT_S+3 : data_o_rom <= '{opcode:ABR_UOP_NTT, imm:'h0000, length:'d00, operand1:MLDSA_T2_BASE, operand2:MLDSA_TEMP0_BASE, operand3:MLDSA_T2_BASE}; + MLDSA_SIGN_INIT_S+4 : data_o_rom <= '{opcode:ABR_UOP_NTT, imm:'h0000, length:'d00, operand1:MLDSA_T3_BASE, operand2:MLDSA_TEMP0_BASE, operand3:MLDSA_T3_BASE}; + MLDSA_SIGN_INIT_S+5 : data_o_rom <= '{opcode:ABR_UOP_NTT, imm:'h0000, length:'d00, operand1:MLDSA_T4_BASE, operand2:MLDSA_TEMP0_BASE, operand3:MLDSA_T4_BASE}; + MLDSA_SIGN_INIT_S+6 : data_o_rom <= '{opcode:ABR_UOP_NTT, imm:'h0000, length:'d00, operand1:MLDSA_T5_BASE, operand2:MLDSA_TEMP0_BASE, operand3:MLDSA_T5_BASE}; + MLDSA_SIGN_INIT_S+7 : data_o_rom <= '{opcode:ABR_UOP_NTT, imm:'h0000, length:'d00, operand1:MLDSA_T6_BASE, operand2:MLDSA_TEMP0_BASE, operand3:MLDSA_T6_BASE}; + MLDSA_SIGN_INIT_S+8 : data_o_rom <= '{opcode:ABR_UOP_NTT, imm:'h0000, length:'d00, operand1:MLDSA_T7_BASE, operand2:MLDSA_TEMP0_BASE, operand3:MLDSA_T7_BASE}; + //NTT(s1) + MLDSA_SIGN_INIT_S+9 : data_o_rom <= '{opcode:ABR_UOP_NTT, imm:'h0000, length:'d00, operand1:MLDSA_S1_0_BASE, operand2:MLDSA_TEMP0_BASE, operand3:MLDSA_S1_0_BASE}; + MLDSA_SIGN_INIT_S+10 : data_o_rom <= '{opcode:ABR_UOP_NTT, imm:'h0000, length:'d00, operand1:MLDSA_S1_1_BASE, operand2:MLDSA_TEMP0_BASE, operand3:MLDSA_S1_1_BASE}; + MLDSA_SIGN_INIT_S+11: data_o_rom <= '{opcode:ABR_UOP_NTT, imm:'h0000, length:'d00, operand1:MLDSA_S1_2_BASE, operand2:MLDSA_TEMP0_BASE, operand3:MLDSA_S1_2_BASE}; + MLDSA_SIGN_INIT_S+12: data_o_rom <= '{opcode:ABR_UOP_NTT, imm:'h0000, length:'d00, operand1:MLDSA_S1_3_BASE, operand2:MLDSA_TEMP0_BASE, operand3:MLDSA_S1_3_BASE}; + MLDSA_SIGN_INIT_S+13: data_o_rom <= '{opcode:ABR_UOP_NTT, imm:'h0000, length:'d00, operand1:MLDSA_S1_4_BASE, operand2:MLDSA_TEMP0_BASE, operand3:MLDSA_S1_4_BASE}; + MLDSA_SIGN_INIT_S+14: data_o_rom <= '{opcode:ABR_UOP_NTT, imm:'h0000, length:'d00, operand1:MLDSA_S1_5_BASE, operand2:MLDSA_TEMP0_BASE, operand3:MLDSA_S1_5_BASE}; + MLDSA_SIGN_INIT_S+15: data_o_rom <= '{opcode:ABR_UOP_NTT, imm:'h0000, length:'d00, operand1:MLDSA_S1_6_BASE, operand2:MLDSA_TEMP0_BASE, operand3:MLDSA_S1_6_BASE}; + //NTT(s2) + MLDSA_SIGN_INIT_S+16: data_o_rom <= '{opcode:ABR_UOP_NTT, imm:'h0000, length:'d00, operand1:MLDSA_S2_0_BASE, operand2:MLDSA_TEMP0_BASE, operand3:MLDSA_S2_0_BASE}; + MLDSA_SIGN_INIT_S+17: data_o_rom <= '{opcode:ABR_UOP_NTT, imm:'h0000, length:'d00, operand1:MLDSA_S2_1_BASE, operand2:MLDSA_TEMP0_BASE, operand3:MLDSA_S2_1_BASE}; + MLDSA_SIGN_INIT_S+18 : data_o_rom <= '{opcode:ABR_UOP_NTT, imm:'h0000, length:'d00, operand1:MLDSA_S2_2_BASE, operand2:MLDSA_TEMP0_BASE, operand3:MLDSA_S2_2_BASE}; + MLDSA_SIGN_INIT_S+19 : data_o_rom <= '{opcode:ABR_UOP_NTT, imm:'h0000, length:'d00, operand1:MLDSA_S2_3_BASE, operand2:MLDSA_TEMP0_BASE, operand3:MLDSA_S2_3_BASE}; + MLDSA_SIGN_INIT_S+20 : data_o_rom <= '{opcode:ABR_UOP_NTT, imm:'h0000, length:'d00, operand1:MLDSA_S2_4_BASE, operand2:MLDSA_TEMP0_BASE, operand3:MLDSA_S2_4_BASE}; + MLDSA_SIGN_INIT_S+21 : data_o_rom <= '{opcode:ABR_UOP_NTT, imm:'h0000, length:'d00, operand1:MLDSA_S2_5_BASE, operand2:MLDSA_TEMP0_BASE, operand3:MLDSA_S2_5_BASE}; + MLDSA_SIGN_INIT_S+22 : data_o_rom <= '{opcode:ABR_UOP_NTT, imm:'h0000, length:'d00, operand1:MLDSA_S2_6_BASE, operand2:MLDSA_TEMP0_BASE, operand3:MLDSA_S2_6_BASE}; + MLDSA_SIGN_INIT_S+23 : data_o_rom <= '{opcode:ABR_UOP_NTT, imm:'h0000, length:'d00, operand1:MLDSA_S2_7_BASE, operand2:MLDSA_TEMP0_BASE, operand3:MLDSA_S2_7_BASE}; + + //lfsr_seed=Keccak(re_entropy||counter) + MLDSA_SIGN_LFSR_S : data_o_rom <= '{opcode:ABR_UOP_LD_SHAKE256, imm:'h0000, length:'d64, operand1:ABR_ENTROPY_ID, operand2:ABR_NOP, operand3:ABR_NOP}; + MLDSA_SIGN_LFSR_S+ 1 : data_o_rom <= '{opcode:ABR_UOP_SHAKE256, imm:'h0000, length:'d08, operand1:ABR_CNT_ID, operand2:ABR_NOP, operand3:ABR_DEST_LFSR_SEED_REG_ID}; + MLDSA_SIGN_LFSR_S+ 2 : data_o_rom <= '{opcode:ABR_UOP_LFSR, imm:'h0000, length:'d00, operand1:ABR_NOP, operand2:ABR_NOP, operand3:ABR_NOP}; + //y=ExpandMask(ρ’ ,κ) + MLDSA_SIGN_MAKE_Y_S : data_o_rom <= '{opcode:ABR_UOP_EXP_MASK, imm:'h0000, length:'d66, operand1:MLDSA_RHO_P_KAPPA_ID, operand2:ABR_NOP, operand3:MLDSA_Y_0_BASE}; + MLDSA_SIGN_MAKE_Y_S+ 1 : data_o_rom <= '{opcode:ABR_UOP_EXP_MASK, imm:'h0001, length:'d66, operand1:MLDSA_RHO_P_KAPPA_ID, operand2:ABR_NOP, operand3:MLDSA_Y_1_BASE}; + MLDSA_SIGN_MAKE_Y_S+ 2 : data_o_rom <= '{opcode:ABR_UOP_EXP_MASK, imm:'h0002, length:'d66, operand1:MLDSA_RHO_P_KAPPA_ID, operand2:ABR_NOP, operand3:MLDSA_Y_2_BASE}; + MLDSA_SIGN_MAKE_Y_S+ 3 : data_o_rom <= '{opcode:ABR_UOP_EXP_MASK, imm:'h0003, length:'d66, operand1:MLDSA_RHO_P_KAPPA_ID, operand2:ABR_NOP, operand3:MLDSA_Y_3_BASE}; + MLDSA_SIGN_MAKE_Y_S+ 4 : data_o_rom <= '{opcode:ABR_UOP_EXP_MASK, imm:'h0004, length:'d66, operand1:MLDSA_RHO_P_KAPPA_ID, operand2:ABR_NOP, operand3:MLDSA_Y_4_BASE}; + MLDSA_SIGN_MAKE_Y_S+ 5 : data_o_rom <= '{opcode:ABR_UOP_EXP_MASK, imm:'h0005, length:'d66, operand1:MLDSA_RHO_P_KAPPA_ID, operand2:ABR_NOP, operand3:MLDSA_Y_5_BASE}; + MLDSA_SIGN_MAKE_Y_S+ 6 : data_o_rom <= '{opcode:ABR_UOP_EXP_MASK, imm:'h0006, length:'d66, operand1:MLDSA_RHO_P_KAPPA_ID, operand2:ABR_NOP, operand3:MLDSA_Y_6_BASE}; + //NTT(Y) + MLDSA_SIGN_MAKE_Y_S+ 7 : data_o_rom <= '{opcode:ABR_UOP_NTT, imm:'h0001, length:'d00, operand1:MLDSA_Y_0_BASE, operand2:MLDSA_TEMP2_BASE, operand3:MLDSA_Y_0_NTT_BASE}; + MLDSA_SIGN_MAKE_Y_S+ 8 : data_o_rom <= '{opcode:ABR_UOP_NTT, imm:'h0001, length:'d00, operand1:MLDSA_Y_1_BASE, operand2:MLDSA_TEMP2_BASE, operand3:MLDSA_Y_1_NTT_BASE}; + MLDSA_SIGN_MAKE_Y_S+ 9 : data_o_rom <= '{opcode:ABR_UOP_NTT, imm:'h0001, length:'d00, operand1:MLDSA_Y_2_BASE, operand2:MLDSA_TEMP2_BASE, operand3:MLDSA_Y_2_NTT_BASE}; + MLDSA_SIGN_MAKE_Y_S+ 10 : data_o_rom <= '{opcode:ABR_UOP_NTT, imm:'h0001, length:'d00, operand1:MLDSA_Y_3_BASE, operand2:MLDSA_TEMP2_BASE, operand3:MLDSA_Y_3_NTT_BASE}; + MLDSA_SIGN_MAKE_Y_S+ 11 : data_o_rom <= '{opcode:ABR_UOP_NTT, imm:'h0001, length:'d00, operand1:MLDSA_Y_4_BASE, operand2:MLDSA_TEMP2_BASE, operand3:MLDSA_Y_4_NTT_BASE}; + MLDSA_SIGN_MAKE_Y_S+ 12 : data_o_rom <= '{opcode:ABR_UOP_NTT, imm:'h0001, length:'d00, operand1:MLDSA_Y_5_BASE, operand2:MLDSA_TEMP2_BASE, operand3:MLDSA_Y_5_NTT_BASE}; + MLDSA_SIGN_MAKE_Y_S+ 13 : data_o_rom <= '{opcode:ABR_UOP_NTT, imm:'h0001, length:'d00, operand1:MLDSA_Y_6_BASE, operand2:MLDSA_TEMP2_BASE, operand3:MLDSA_Y_6_NTT_BASE}; + //Aˆ ←ExpandA(ρ) AND Aˆ ◦NTT(y) + MLDSA_SIGN_MAKE_W_S : data_o_rom <= '{opcode:ABR_UOP_REJS_MASKED_PWM, imm:'h0000, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Y_0_NTT_BASE, operand3:MLDSA_AY0_BASE}; + MLDSA_SIGN_MAKE_W_S+ 1 : data_o_rom <= '{opcode:ABR_UOP_REJS_MASKED_PWMA, imm:'h0001, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Y_1_NTT_BASE, operand3:MLDSA_AY0_BASE}; + MLDSA_SIGN_MAKE_W_S+ 2 : data_o_rom <= '{opcode:ABR_UOP_REJS_MASKED_PWMA, imm:'h0002, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Y_2_NTT_BASE, operand3:MLDSA_AY0_BASE}; + MLDSA_SIGN_MAKE_W_S+ 3 : data_o_rom <= '{opcode:ABR_UOP_REJS_MASKED_PWMA, imm:'h0003, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Y_3_NTT_BASE, operand3:MLDSA_AY0_BASE}; + MLDSA_SIGN_MAKE_W_S+ 4 : data_o_rom <= '{opcode:ABR_UOP_REJS_MASKED_PWMA, imm:'h0004, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Y_4_NTT_BASE, operand3:MLDSA_AY0_BASE}; + MLDSA_SIGN_MAKE_W_S+ 5 : data_o_rom <= '{opcode:ABR_UOP_REJS_MASKED_PWMA, imm:'h0005, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Y_5_NTT_BASE, operand3:MLDSA_AY0_BASE}; + MLDSA_SIGN_MAKE_W_S+ 6 : data_o_rom <= '{opcode:ABR_UOP_REJS_MASKED_PWMA, imm:'h0006, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Y_6_NTT_BASE, operand3:MLDSA_AY0_BASE}; + + MLDSA_SIGN_MAKE_W_S+ 7 : data_o_rom <= '{opcode:ABR_UOP_MASKED_INTT, imm:'h0001, length:'d00, operand1:MLDSA_AY0_BASE, operand2:MLDSA_TEMP2_BASE, operand3:MLDSA_W0_0_BASE}; + + MLDSA_SIGN_MAKE_W_S+ 8 : data_o_rom <= '{opcode:ABR_UOP_REJS_MASKED_PWM, imm:'h0100, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Y_0_NTT_BASE, operand3:MLDSA_AY0_BASE}; + MLDSA_SIGN_MAKE_W_S+ 9 : data_o_rom <= '{opcode:ABR_UOP_REJS_MASKED_PWMA, imm:'h0101, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Y_1_NTT_BASE, operand3:MLDSA_AY0_BASE}; + MLDSA_SIGN_MAKE_W_S+ 10 : data_o_rom <= '{opcode:ABR_UOP_REJS_MASKED_PWMA, imm:'h0102, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Y_2_NTT_BASE, operand3:MLDSA_AY0_BASE}; + MLDSA_SIGN_MAKE_W_S+ 11 : data_o_rom <= '{opcode:ABR_UOP_REJS_MASKED_PWMA, imm:'h0103, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Y_3_NTT_BASE, operand3:MLDSA_AY0_BASE}; + MLDSA_SIGN_MAKE_W_S+ 12 : data_o_rom <= '{opcode:ABR_UOP_REJS_MASKED_PWMA, imm:'h0104, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Y_4_NTT_BASE, operand3:MLDSA_AY0_BASE}; + MLDSA_SIGN_MAKE_W_S+ 13 : data_o_rom <= '{opcode:ABR_UOP_REJS_MASKED_PWMA, imm:'h0105, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Y_5_NTT_BASE, operand3:MLDSA_AY0_BASE}; + MLDSA_SIGN_MAKE_W_S+ 14 : data_o_rom <= '{opcode:ABR_UOP_REJS_MASKED_PWMA, imm:'h0106, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Y_6_NTT_BASE, operand3:MLDSA_AY0_BASE}; + + MLDSA_SIGN_MAKE_W_S+ 15 : data_o_rom <= '{opcode:ABR_UOP_MASKED_INTT, imm:'h0001, length:'d00, operand1:MLDSA_AY0_BASE, operand2:MLDSA_TEMP2_BASE, operand3:MLDSA_W0_1_BASE}; + + MLDSA_SIGN_MAKE_W_S+ 16 : data_o_rom <= '{opcode:ABR_UOP_REJS_MASKED_PWM, imm:'h0200, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Y_0_NTT_BASE, operand3:MLDSA_AY0_BASE}; + MLDSA_SIGN_MAKE_W_S+ 17 : data_o_rom <= '{opcode:ABR_UOP_REJS_MASKED_PWMA, imm:'h0201, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Y_1_NTT_BASE, operand3:MLDSA_AY0_BASE}; + MLDSA_SIGN_MAKE_W_S+ 18 : data_o_rom <= '{opcode:ABR_UOP_REJS_MASKED_PWMA, imm:'h0202, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Y_2_NTT_BASE, operand3:MLDSA_AY0_BASE}; + MLDSA_SIGN_MAKE_W_S+ 19 : data_o_rom <= '{opcode:ABR_UOP_REJS_MASKED_PWMA, imm:'h0203, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Y_3_NTT_BASE, operand3:MLDSA_AY0_BASE}; + MLDSA_SIGN_MAKE_W_S+ 20 : data_o_rom <= '{opcode:ABR_UOP_REJS_MASKED_PWMA, imm:'h0204, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Y_4_NTT_BASE, operand3:MLDSA_AY0_BASE}; + MLDSA_SIGN_MAKE_W_S+ 21 : data_o_rom <= '{opcode:ABR_UOP_REJS_MASKED_PWMA, imm:'h0205, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Y_5_NTT_BASE, operand3:MLDSA_AY0_BASE}; + MLDSA_SIGN_MAKE_W_S+ 22 : data_o_rom <= '{opcode:ABR_UOP_REJS_MASKED_PWMA, imm:'h0206, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Y_6_NTT_BASE, operand3:MLDSA_AY0_BASE}; + + MLDSA_SIGN_MAKE_W_S+ 23 : data_o_rom <= '{opcode:ABR_UOP_MASKED_INTT, imm:'h0001, length:'d00, operand1:MLDSA_AY0_BASE, operand2:MLDSA_TEMP2_BASE, operand3:MLDSA_W0_2_BASE}; + + MLDSA_SIGN_MAKE_W_S+ 24 : data_o_rom <= '{opcode:ABR_UOP_REJS_MASKED_PWM, imm:'h0300, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Y_0_NTT_BASE, operand3:MLDSA_AY0_BASE}; + MLDSA_SIGN_MAKE_W_S+ 25 : data_o_rom <= '{opcode:ABR_UOP_REJS_MASKED_PWMA, imm:'h0301, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Y_1_NTT_BASE, operand3:MLDSA_AY0_BASE}; + MLDSA_SIGN_MAKE_W_S+ 26 : data_o_rom <= '{opcode:ABR_UOP_REJS_MASKED_PWMA, imm:'h0302, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Y_2_NTT_BASE, operand3:MLDSA_AY0_BASE}; + MLDSA_SIGN_MAKE_W_S+ 27 : data_o_rom <= '{opcode:ABR_UOP_REJS_MASKED_PWMA, imm:'h0303, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Y_3_NTT_BASE, operand3:MLDSA_AY0_BASE}; + MLDSA_SIGN_MAKE_W_S+ 28 : data_o_rom <= '{opcode:ABR_UOP_REJS_MASKED_PWMA, imm:'h0304, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Y_4_NTT_BASE, operand3:MLDSA_AY0_BASE}; + MLDSA_SIGN_MAKE_W_S+ 29 : data_o_rom <= '{opcode:ABR_UOP_REJS_MASKED_PWMA, imm:'h0305, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Y_5_NTT_BASE, operand3:MLDSA_AY0_BASE}; + MLDSA_SIGN_MAKE_W_S+ 30 : data_o_rom <= '{opcode:ABR_UOP_REJS_MASKED_PWMA, imm:'h0306, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Y_6_NTT_BASE, operand3:MLDSA_AY0_BASE}; + + MLDSA_SIGN_MAKE_W_S+ 31 : data_o_rom <= '{opcode:ABR_UOP_MASKED_INTT, imm:'h0001, length:'d00, operand1:MLDSA_AY0_BASE, operand2:MLDSA_TEMP2_BASE, operand3:MLDSA_W0_3_BASE}; + + MLDSA_SIGN_MAKE_W_S+ 32 : data_o_rom <= '{opcode:ABR_UOP_REJS_MASKED_PWM, imm:'h0400, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Y_0_NTT_BASE, operand3:MLDSA_AY0_BASE}; + MLDSA_SIGN_MAKE_W_S+ 33 : data_o_rom <= '{opcode:ABR_UOP_REJS_MASKED_PWMA, imm:'h0401, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Y_1_NTT_BASE, operand3:MLDSA_AY0_BASE}; + MLDSA_SIGN_MAKE_W_S+ 34 : data_o_rom <= '{opcode:ABR_UOP_REJS_MASKED_PWMA, imm:'h0402, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Y_2_NTT_BASE, operand3:MLDSA_AY0_BASE}; + MLDSA_SIGN_MAKE_W_S+ 35 : data_o_rom <= '{opcode:ABR_UOP_REJS_MASKED_PWMA, imm:'h0403, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Y_3_NTT_BASE, operand3:MLDSA_AY0_BASE}; + MLDSA_SIGN_MAKE_W_S+ 36 : data_o_rom <= '{opcode:ABR_UOP_REJS_MASKED_PWMA, imm:'h0404, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Y_4_NTT_BASE, operand3:MLDSA_AY0_BASE}; + MLDSA_SIGN_MAKE_W_S+ 37 : data_o_rom <= '{opcode:ABR_UOP_REJS_MASKED_PWMA, imm:'h0405, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Y_5_NTT_BASE, operand3:MLDSA_AY0_BASE}; + MLDSA_SIGN_MAKE_W_S+ 38 : data_o_rom <= '{opcode:ABR_UOP_REJS_MASKED_PWMA, imm:'h0406, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Y_6_NTT_BASE, operand3:MLDSA_AY0_BASE}; + + MLDSA_SIGN_MAKE_W_S+ 39 : data_o_rom <= '{opcode:ABR_UOP_MASKED_INTT, imm:'h0001, length:'d00, operand1:MLDSA_AY0_BASE, operand2:MLDSA_TEMP2_BASE, operand3:MLDSA_W0_4_BASE}; + + MLDSA_SIGN_MAKE_W_S+ 40 : data_o_rom <= '{opcode:ABR_UOP_REJS_MASKED_PWM, imm:'h0500, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Y_0_NTT_BASE, operand3:MLDSA_AY0_BASE}; + MLDSA_SIGN_MAKE_W_S+ 41 : data_o_rom <= '{opcode:ABR_UOP_REJS_MASKED_PWMA, imm:'h0501, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Y_1_NTT_BASE, operand3:MLDSA_AY0_BASE}; + MLDSA_SIGN_MAKE_W_S+ 42 : data_o_rom <= '{opcode:ABR_UOP_REJS_MASKED_PWMA, imm:'h0502, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Y_2_NTT_BASE, operand3:MLDSA_AY0_BASE}; + MLDSA_SIGN_MAKE_W_S+ 43 : data_o_rom <= '{opcode:ABR_UOP_REJS_MASKED_PWMA, imm:'h0503, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Y_3_NTT_BASE, operand3:MLDSA_AY0_BASE}; + MLDSA_SIGN_MAKE_W_S+ 44 : data_o_rom <= '{opcode:ABR_UOP_REJS_MASKED_PWMA, imm:'h0504, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Y_4_NTT_BASE, operand3:MLDSA_AY0_BASE}; + MLDSA_SIGN_MAKE_W_S+ 45 : data_o_rom <= '{opcode:ABR_UOP_REJS_MASKED_PWMA, imm:'h0505, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Y_5_NTT_BASE, operand3:MLDSA_AY0_BASE}; + MLDSA_SIGN_MAKE_W_S+ 46 : data_o_rom <= '{opcode:ABR_UOP_REJS_MASKED_PWMA, imm:'h0506, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Y_6_NTT_BASE, operand3:MLDSA_AY0_BASE}; + + MLDSA_SIGN_MAKE_W_S+ 47 : data_o_rom <= '{opcode:ABR_UOP_MASKED_INTT, imm:'h0001, length:'d00, operand1:MLDSA_AY0_BASE, operand2:MLDSA_TEMP2_BASE, operand3:MLDSA_W0_5_BASE}; + + MLDSA_SIGN_MAKE_W_S+ 48 : data_o_rom <= '{opcode:ABR_UOP_REJS_MASKED_PWM, imm:'h0600, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Y_0_NTT_BASE, operand3:MLDSA_AY0_BASE}; + MLDSA_SIGN_MAKE_W_S+ 49 : data_o_rom <= '{opcode:ABR_UOP_REJS_MASKED_PWMA, imm:'h0601, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Y_1_NTT_BASE, operand3:MLDSA_AY0_BASE}; + MLDSA_SIGN_MAKE_W_S+ 50 : data_o_rom <= '{opcode:ABR_UOP_REJS_MASKED_PWMA, imm:'h0602, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Y_2_NTT_BASE, operand3:MLDSA_AY0_BASE}; + MLDSA_SIGN_MAKE_W_S+ 51 : data_o_rom <= '{opcode:ABR_UOP_REJS_MASKED_PWMA, imm:'h0603, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Y_3_NTT_BASE, operand3:MLDSA_AY0_BASE}; + MLDSA_SIGN_MAKE_W_S+ 52 : data_o_rom <= '{opcode:ABR_UOP_REJS_MASKED_PWMA, imm:'h0604, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Y_4_NTT_BASE, operand3:MLDSA_AY0_BASE}; + MLDSA_SIGN_MAKE_W_S+ 53 : data_o_rom <= '{opcode:ABR_UOP_REJS_MASKED_PWMA, imm:'h0605, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Y_5_NTT_BASE, operand3:MLDSA_AY0_BASE}; + MLDSA_SIGN_MAKE_W_S+ 54 : data_o_rom <= '{opcode:ABR_UOP_REJS_MASKED_PWMA, imm:'h0606, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Y_6_NTT_BASE, operand3:MLDSA_AY0_BASE}; + + MLDSA_SIGN_MAKE_W_S+ 55 : data_o_rom <= '{opcode:ABR_UOP_MASKED_INTT, imm:'h0001, length:'d00, operand1:MLDSA_AY0_BASE, operand2:MLDSA_TEMP2_BASE, operand3:MLDSA_W0_6_BASE}; + + MLDSA_SIGN_MAKE_W_S+ 56 : data_o_rom <= '{opcode:ABR_UOP_REJS_MASKED_PWM, imm:'h0700, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Y_0_NTT_BASE, operand3:MLDSA_AY0_BASE}; + MLDSA_SIGN_MAKE_W_S+ 57 : data_o_rom <= '{opcode:ABR_UOP_REJS_MASKED_PWMA, imm:'h0701, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Y_1_NTT_BASE, operand3:MLDSA_AY0_BASE}; + MLDSA_SIGN_MAKE_W_S+ 58 : data_o_rom <= '{opcode:ABR_UOP_REJS_MASKED_PWMA, imm:'h0702, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Y_2_NTT_BASE, operand3:MLDSA_AY0_BASE}; + MLDSA_SIGN_MAKE_W_S+ 59 : data_o_rom <= '{opcode:ABR_UOP_REJS_MASKED_PWMA, imm:'h0703, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Y_3_NTT_BASE, operand3:MLDSA_AY0_BASE}; + MLDSA_SIGN_MAKE_W_S+ 60 : data_o_rom <= '{opcode:ABR_UOP_REJS_MASKED_PWMA, imm:'h0704, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Y_4_NTT_BASE, operand3:MLDSA_AY0_BASE}; + MLDSA_SIGN_MAKE_W_S+ 61 : data_o_rom <= '{opcode:ABR_UOP_REJS_MASKED_PWMA, imm:'h0705, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Y_5_NTT_BASE, operand3:MLDSA_AY0_BASE}; + MLDSA_SIGN_MAKE_W_S+ 62 : data_o_rom <= '{opcode:ABR_UOP_REJS_MASKED_PWMA, imm:'h0706, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Y_6_NTT_BASE, operand3:MLDSA_AY0_BASE}; + + MLDSA_SIGN_MAKE_W_S+ 63 : data_o_rom <= '{opcode:ABR_UOP_MASKED_INTT, imm:'h0001, length:'d00, operand1:MLDSA_AY0_BASE, operand2:MLDSA_TEMP2_BASE, operand3:MLDSA_W0_7_BASE}; + + //(w1,w0) ←Decompose(w) AND c˜←H(μ||w1Encode(w1),2λ) + MLDSA_SIGN_MAKE_W_S+ 64 : data_o_rom <= '{opcode:ABR_UOP_LD_SHAKE256, imm:'h0000, length:'d64, operand1:MLDSA_MU_ID, operand2:ABR_NOP, operand3:ABR_NOP}; + MLDSA_SIGN_MAKE_W : data_o_rom <= '{opcode:ABR_UOP_DECOMPOSE, imm:'h0000, length:'d00, operand1:MLDSA_W0_0_BASE, operand2:ABR_NOP, operand3:MLDSA_W0_0_BASE}; + + MLDSA_SIGN_MAKE_C : data_o_rom <= '{opcode:ABR_UOP_RUN_SHAKE256, imm:'h0000, length:'d00, operand1:ABR_NOP, operand2:ABR_NOP, operand3:MLDSA_DEST_SIG_C_REG_ID}; + MLDSA_SIGN_MAKE_C+ 1 : data_o_rom <= '{opcode:ABR_UOP_SIB, imm:'h0000, length:'d64, operand1:MLDSA_SIG_C_REG_ID, operand2:ABR_NOP, operand3:ABR_NOP}; + + //NTT(C) + MLDSA_SIGN_VALID_S : data_o_rom <= '{opcode:ABR_UOP_NTT, imm:'h0000, length:'d00, operand1:MLDSA_C_BASE, operand2:MLDSA_TEMP0_BASE, operand3:MLDSA_C_NTT_BASE}; + + //Compute Z and perform norm check + MLDSA_SIGN_VALID_S+1 : data_o_rom <= '{opcode:ABR_UOP_MASKED_PWM, imm:'h0000, length:'d00, operand1:MLDSA_C_NTT_BASE, operand2:MLDSA_S1_0_BASE, operand3:MLDSA_CS_NTT_BASE}; + MLDSA_SIGN_VALID_S+2 : data_o_rom <= '{opcode:ABR_UOP_MASKED_INTT, imm:'h0000, length:'d00, operand1:MLDSA_CS_NTT_BASE, operand2:MLDSA_TEMP2_BASE, operand3:MLDSA_CS1_BASE}; + MLDSA_SIGN_VALID_S+3 : data_o_rom <= '{opcode:ABR_UOP_PWA, imm:'h0000, length:'d00, operand1:MLDSA_Y_0_BASE, operand2:MLDSA_CS1_BASE, operand3:MLDSA_Z_BASE}; + MLDSA_SIGN_VALID_S+4 : data_o_rom <= '{opcode:ABR_UOP_NORMCHK, imm:MLDSA_NORMCHK_Z, length:'d00, operand1:MLDSA_Z_BASE, operand2:ABR_NOP, operand3:ABR_NOP}; + MLDSA_SIGN_VALID_S+5 : data_o_rom <= '{opcode:ABR_UOP_SIGENCODE, imm:'h0000, length:'d00, operand1:MLDSA_Z_BASE, operand2:ABR_NOP, operand3:15'h000}; + + MLDSA_SIGN_VALID_S+6 : data_o_rom <= '{opcode:ABR_UOP_MASKED_PWM, imm:'h0000, length:'d00, operand1:MLDSA_C_NTT_BASE, operand2:MLDSA_S1_1_BASE, operand3:MLDSA_CS_NTT_BASE}; + MLDSA_SIGN_VALID_S+7 : data_o_rom <= '{opcode:ABR_UOP_MASKED_INTT, imm:'h0000, length:'d00, operand1:MLDSA_CS_NTT_BASE, operand2:MLDSA_TEMP2_BASE, operand3:MLDSA_CS1_BASE}; + MLDSA_SIGN_VALID_S+8 : data_o_rom <= '{opcode:ABR_UOP_PWA, imm:'h0000, length:'d00, operand1:MLDSA_Y_1_BASE, operand2:MLDSA_CS1_BASE, operand3:MLDSA_Z_BASE}; + MLDSA_SIGN_VALID_S+9 : data_o_rom <= '{opcode:ABR_UOP_NORMCHK, imm:MLDSA_NORMCHK_Z, length:'d00, operand1:MLDSA_Z_BASE, operand2:ABR_NOP, operand3:ABR_NOP}; + MLDSA_SIGN_VALID_S+10 : data_o_rom <= '{opcode:ABR_UOP_SIGENCODE, imm:'h0000, length:'d00, operand1:MLDSA_Z_BASE, operand2:ABR_NOP, operand3:15'h040}; + + MLDSA_SIGN_VALID_S+11 : data_o_rom <= '{opcode:ABR_UOP_MASKED_PWM, imm:'h0000, length:'d00, operand1:MLDSA_C_NTT_BASE, operand2:MLDSA_S1_2_BASE, operand3:MLDSA_CS_NTT_BASE}; + MLDSA_SIGN_VALID_S+12 : data_o_rom <= '{opcode:ABR_UOP_MASKED_INTT, imm:'h0000, length:'d00, operand1:MLDSA_CS_NTT_BASE, operand2:MLDSA_TEMP2_BASE, operand3:MLDSA_CS1_BASE}; + MLDSA_SIGN_VALID_S+13 : data_o_rom <= '{opcode:ABR_UOP_PWA, imm:'h0000, length:'d00, operand1:MLDSA_Y_2_BASE, operand2:MLDSA_CS1_BASE, operand3:MLDSA_Z_BASE}; + MLDSA_SIGN_VALID_S+14 : data_o_rom <= '{opcode:ABR_UOP_NORMCHK, imm:MLDSA_NORMCHK_Z, length:'d00, operand1:MLDSA_Z_BASE, operand2:ABR_NOP, operand3:ABR_NOP}; + MLDSA_SIGN_VALID_S+15 : data_o_rom <= '{opcode:ABR_UOP_SIGENCODE, imm:'h0000, length:'d00, operand1:MLDSA_Z_BASE, operand2:ABR_NOP, operand3:15'h080}; + + MLDSA_SIGN_VALID_S+16 : data_o_rom <= '{opcode:ABR_UOP_MASKED_PWM, imm:'h0000, length:'d00, operand1:MLDSA_C_NTT_BASE, operand2:MLDSA_S1_3_BASE, operand3:MLDSA_CS_NTT_BASE}; + MLDSA_SIGN_VALID_S+17 : data_o_rom <= '{opcode:ABR_UOP_MASKED_INTT, imm:'h0000, length:'d00, operand1:MLDSA_CS_NTT_BASE, operand2:MLDSA_TEMP2_BASE, operand3:MLDSA_CS1_BASE}; + MLDSA_SIGN_VALID_S+18 : data_o_rom <= '{opcode:ABR_UOP_PWA, imm:'h0000, length:'d00, operand1:MLDSA_Y_3_BASE, operand2:MLDSA_CS1_BASE, operand3:MLDSA_Z_BASE}; + MLDSA_SIGN_VALID_S+19 : data_o_rom <= '{opcode:ABR_UOP_NORMCHK, imm:MLDSA_NORMCHK_Z, length:'d00, operand1:MLDSA_Z_BASE, operand2:ABR_NOP, operand3:ABR_NOP}; + MLDSA_SIGN_VALID_S+20 : data_o_rom <= '{opcode:ABR_UOP_SIGENCODE, imm:'h0000, length:'d00, operand1:MLDSA_Z_BASE, operand2:ABR_NOP, operand3:15'h0C0}; + + MLDSA_SIGN_VALID_S+21 : data_o_rom <= '{opcode:ABR_UOP_MASKED_PWM, imm:'h0000, length:'d00, operand1:MLDSA_C_NTT_BASE, operand2:MLDSA_S1_4_BASE, operand3:MLDSA_CS_NTT_BASE}; + MLDSA_SIGN_VALID_S+22 : data_o_rom <= '{opcode:ABR_UOP_MASKED_INTT, imm:'h0000, length:'d00, operand1:MLDSA_CS_NTT_BASE, operand2:MLDSA_TEMP2_BASE, operand3:MLDSA_CS1_BASE}; + MLDSA_SIGN_VALID_S+23 : data_o_rom <= '{opcode:ABR_UOP_PWA, imm:'h0000, length:'d00, operand1:MLDSA_Y_4_BASE, operand2:MLDSA_CS1_BASE, operand3:MLDSA_Z_BASE}; + MLDSA_SIGN_VALID_S+24 : data_o_rom <= '{opcode:ABR_UOP_NORMCHK, imm:MLDSA_NORMCHK_Z, length:'d00, operand1:MLDSA_Z_BASE, operand2:ABR_NOP, operand3:ABR_NOP}; + MLDSA_SIGN_VALID_S+25 : data_o_rom <= '{opcode:ABR_UOP_SIGENCODE, imm:'h0000, length:'d00, operand1:MLDSA_Z_BASE, operand2:ABR_NOP, operand3:15'h100}; + + MLDSA_SIGN_VALID_S+26 : data_o_rom <= '{opcode:ABR_UOP_MASKED_PWM, imm:'h0000, length:'d00, operand1:MLDSA_C_NTT_BASE, operand2:MLDSA_S1_5_BASE, operand3:MLDSA_CS_NTT_BASE}; + MLDSA_SIGN_VALID_S+27 : data_o_rom <= '{opcode:ABR_UOP_MASKED_INTT, imm:'h0000, length:'d00, operand1:MLDSA_CS_NTT_BASE, operand2:MLDSA_TEMP2_BASE, operand3:MLDSA_CS1_BASE}; + MLDSA_SIGN_VALID_S+28 : data_o_rom <= '{opcode:ABR_UOP_PWA, imm:'h0000, length:'d00, operand1:MLDSA_Y_5_BASE, operand2:MLDSA_CS1_BASE, operand3:MLDSA_Z_BASE}; + MLDSA_SIGN_VALID_S+29 : data_o_rom <= '{opcode:ABR_UOP_NORMCHK, imm:MLDSA_NORMCHK_Z, length:'d00, operand1:MLDSA_Z_BASE, operand2:ABR_NOP, operand3:ABR_NOP}; + MLDSA_SIGN_VALID_S+30 : data_o_rom <= '{opcode:ABR_UOP_SIGENCODE, imm:'h0000, length:'d00, operand1:MLDSA_Z_BASE, operand2:ABR_NOP, operand3:15'h140}; + + MLDSA_SIGN_VALID_S+31 : data_o_rom <= '{opcode:ABR_UOP_MASKED_PWM, imm:'h0000, length:'d00, operand1:MLDSA_C_NTT_BASE, operand2:MLDSA_S1_6_BASE, operand3:MLDSA_CS_NTT_BASE}; + MLDSA_SIGN_VALID_S+32 : data_o_rom <= '{opcode:ABR_UOP_MASKED_INTT, imm:'h0000, length:'d00, operand1:MLDSA_CS_NTT_BASE, operand2:MLDSA_TEMP2_BASE, operand3:MLDSA_CS1_BASE}; + MLDSA_SIGN_VALID_S+33 : data_o_rom <= '{opcode:ABR_UOP_PWA, imm:'h0000, length:'d00, operand1:MLDSA_Y_6_BASE, operand2:MLDSA_CS1_BASE, operand3:MLDSA_Z_BASE}; + MLDSA_SIGN_VALID_S+34 : data_o_rom <= '{opcode:ABR_UOP_NORMCHK, imm:MLDSA_NORMCHK_Z, length:'d00, operand1:MLDSA_Z_BASE, operand2:ABR_NOP, operand3:ABR_NOP}; + MLDSA_SIGN_VALID_S+35 : data_o_rom <= '{opcode:ABR_UOP_SIGENCODE, imm:'h0000, length:'d00, operand1:MLDSA_Z_BASE, operand2:ABR_NOP, operand3:15'h180}; + + MLDSA_SIGN_VALID_S+36 : data_o_rom <= '{opcode:ABR_UOP_MASKED_PWM, imm:'h0000, length:'d00, operand1:MLDSA_C_NTT_BASE, operand2:MLDSA_T0_BASE, operand3:MLDSA_CT_NTT_BASE}; + MLDSA_SIGN_VALID_S+37 : data_o_rom <= '{opcode:ABR_UOP_MASKED_INTT, imm:'h0000, length:'d00, operand1:MLDSA_CT_NTT_BASE, operand2:MLDSA_TEMP2_BASE, operand3:MLDSA_CT_0_BASE}; + MLDSA_SIGN_VALID_S+38 : data_o_rom <= '{opcode:ABR_UOP_MASKED_PWM, imm:'h0000, length:'d00, operand1:MLDSA_C_NTT_BASE, operand2:MLDSA_T1_BASE, operand3:MLDSA_CT_NTT_BASE}; + MLDSA_SIGN_VALID_S+39 : data_o_rom <= '{opcode:ABR_UOP_MASKED_INTT, imm:'h0000, length:'d00, operand1:MLDSA_CT_NTT_BASE, operand2:MLDSA_TEMP2_BASE, operand3:MLDSA_CT_1_BASE}; + MLDSA_SIGN_VALID_S+40 : data_o_rom <= '{opcode:ABR_UOP_MASKED_PWM, imm:'h0000, length:'d00, operand1:MLDSA_C_NTT_BASE, operand2:MLDSA_T2_BASE, operand3:MLDSA_CT_NTT_BASE}; + MLDSA_SIGN_VALID_S+41 : data_o_rom <= '{opcode:ABR_UOP_MASKED_INTT, imm:'h0000, length:'d00, operand1:MLDSA_CT_NTT_BASE, operand2:MLDSA_TEMP2_BASE, operand3:MLDSA_CT_2_BASE}; + MLDSA_SIGN_VALID_S+42 : data_o_rom <= '{opcode:ABR_UOP_MASKED_PWM, imm:'h0000, length:'d00, operand1:MLDSA_C_NTT_BASE, operand2:MLDSA_T3_BASE, operand3:MLDSA_CT_NTT_BASE}; + MLDSA_SIGN_VALID_S+43 : data_o_rom <= '{opcode:ABR_UOP_MASKED_INTT, imm:'h0000, length:'d00, operand1:MLDSA_CT_NTT_BASE, operand2:MLDSA_TEMP2_BASE, operand3:MLDSA_CT_3_BASE}; + MLDSA_SIGN_VALID_S+44 : data_o_rom <= '{opcode:ABR_UOP_MASKED_PWM, imm:'h0000, length:'d00, operand1:MLDSA_C_NTT_BASE, operand2:MLDSA_T4_BASE, operand3:MLDSA_CT_NTT_BASE}; + MLDSA_SIGN_VALID_S+45 : data_o_rom <= '{opcode:ABR_UOP_MASKED_INTT, imm:'h0000, length:'d00, operand1:MLDSA_CT_NTT_BASE, operand2:MLDSA_TEMP2_BASE, operand3:MLDSA_CT_4_BASE}; + MLDSA_SIGN_VALID_S+46 : data_o_rom <= '{opcode:ABR_UOP_MASKED_PWM, imm:'h0000, length:'d00, operand1:MLDSA_C_NTT_BASE, operand2:MLDSA_T5_BASE, operand3:MLDSA_CT_NTT_BASE}; + MLDSA_SIGN_VALID_S+47 : data_o_rom <= '{opcode:ABR_UOP_MASKED_INTT, imm:'h0000, length:'d00, operand1:MLDSA_CT_NTT_BASE, operand2:MLDSA_TEMP2_BASE, operand3:MLDSA_CT_5_BASE}; + MLDSA_SIGN_VALID_S+48 : data_o_rom <= '{opcode:ABR_UOP_MASKED_PWM, imm:'h0000, length:'d00, operand1:MLDSA_C_NTT_BASE, operand2:MLDSA_T6_BASE, operand3:MLDSA_CT_NTT_BASE}; + MLDSA_SIGN_VALID_S+49 : data_o_rom <= '{opcode:ABR_UOP_MASKED_INTT, imm:'h0000, length:'d00, operand1:MLDSA_CT_NTT_BASE, operand2:MLDSA_TEMP2_BASE, operand3:MLDSA_CT_6_BASE}; + MLDSA_SIGN_VALID_S+50 : data_o_rom <= '{opcode:ABR_UOP_MASKED_PWM, imm:'h0000, length:'d00, operand1:MLDSA_C_NTT_BASE, operand2:MLDSA_T7_BASE, operand3:MLDSA_CT_NTT_BASE}; + MLDSA_SIGN_VALID_S+51 : data_o_rom <= '{opcode:ABR_UOP_MASKED_INTT, imm:'h0000, length:'d00, operand1:MLDSA_CT_NTT_BASE, operand2:MLDSA_TEMP2_BASE, operand3:MLDSA_CT_7_BASE}; + + //Make R0, CT0 and Hint_r + MLDSA_SIGN_VALID_S+52 : data_o_rom <= '{opcode:ABR_UOP_MASKED_PWM, imm:'h0000, length:'d00, operand1:MLDSA_C_NTT_BASE, operand2:MLDSA_S2_0_BASE, operand3:MLDSA_CS_NTT_BASE}; + MLDSA_SIGN_VALID_S+53 : data_o_rom <= '{opcode:ABR_UOP_MASKED_INTT, imm:'h0000, length:'d00, operand1:MLDSA_CS_NTT_BASE, operand2:MLDSA_TEMP2_BASE, operand3:MLDSA_CS2_BASE}; + MLDSA_SIGN_VALID_S+54 : data_o_rom <= '{opcode:ABR_UOP_PWS, imm:'h0000, length:'d00, operand1:MLDSA_CS2_BASE, operand2:MLDSA_W0_0_BASE, operand3:MLDSA_R0_BASE}; + MLDSA_SIGN_VALID_S+55 : data_o_rom <= '{opcode:ABR_UOP_NORMCHK, imm:MLDSA_NORMCHK_R0, length:'d00, operand1:MLDSA_R0_BASE, operand2:ABR_NOP, operand3:ABR_NOP}; + MLDSA_SIGN_VALID_S+56 : data_o_rom <= '{opcode:ABR_UOP_NORMCHK, imm:MLDSA_NORMCHK_CT0, length:'d00, operand1:MLDSA_CT_0_BASE, operand2:ABR_NOP, operand3:ABR_NOP}; + MLDSA_SIGN_VALID_S+57 : data_o_rom <= '{opcode:ABR_UOP_PWA, imm:'h0000, length:'d00, operand1:MLDSA_R0_BASE, operand2:MLDSA_CT_0_BASE, operand3:MLDSA_HINT_R_0_BASE}; + + MLDSA_SIGN_VALID_S+58 : data_o_rom <= '{opcode:ABR_UOP_MASKED_PWM, imm:'h0000, length:'d00, operand1:MLDSA_C_NTT_BASE, operand2:MLDSA_S2_1_BASE, operand3:MLDSA_CS_NTT_BASE}; + MLDSA_SIGN_VALID_S+59 : data_o_rom <= '{opcode:ABR_UOP_MASKED_INTT, imm:'h0000, length:'d00, operand1:MLDSA_CS_NTT_BASE, operand2:MLDSA_TEMP2_BASE, operand3:MLDSA_CS2_BASE}; + MLDSA_SIGN_VALID_S+60 : data_o_rom <= '{opcode:ABR_UOP_PWS, imm:'h0000, length:'d00, operand1:MLDSA_CS2_BASE, operand2:MLDSA_W0_1_BASE, operand3:MLDSA_R0_BASE}; + MLDSA_SIGN_VALID_S+61 : data_o_rom <= '{opcode:ABR_UOP_NORMCHK, imm:MLDSA_NORMCHK_R0, length:'d00, operand1:MLDSA_R0_BASE, operand2:ABR_NOP, operand3:ABR_NOP}; + MLDSA_SIGN_VALID_S+62 : data_o_rom <= '{opcode:ABR_UOP_NORMCHK, imm:MLDSA_NORMCHK_CT0, length:'d00, operand1:MLDSA_CT_1_BASE, operand2:ABR_NOP, operand3:ABR_NOP}; + MLDSA_SIGN_VALID_S+63 : data_o_rom <= '{opcode:ABR_UOP_PWA, imm:'h0000, length:'d00, operand1:MLDSA_R0_BASE, operand2:MLDSA_CT_1_BASE, operand3:MLDSA_HINT_R_1_BASE}; + + MLDSA_SIGN_VALID_S+64 : data_o_rom <= '{opcode:ABR_UOP_MASKED_PWM, imm:'h0000, length:'d00, operand1:MLDSA_C_NTT_BASE, operand2:MLDSA_S2_2_BASE, operand3:MLDSA_CS_NTT_BASE}; + MLDSA_SIGN_VALID_S+65 : data_o_rom <= '{opcode:ABR_UOP_MASKED_INTT, imm:'h0000, length:'d00, operand1:MLDSA_CS_NTT_BASE, operand2:MLDSA_TEMP2_BASE, operand3:MLDSA_CS2_BASE}; + MLDSA_SIGN_VALID_S+66 : data_o_rom <= '{opcode:ABR_UOP_PWS, imm:'h0000, length:'d00, operand1:MLDSA_CS2_BASE, operand2:MLDSA_W0_2_BASE, operand3:MLDSA_R0_BASE}; + MLDSA_SIGN_VALID_S+67 : data_o_rom <= '{opcode:ABR_UOP_NORMCHK, imm:MLDSA_NORMCHK_R0, length:'d00, operand1:MLDSA_R0_BASE, operand2:ABR_NOP, operand3:ABR_NOP}; + MLDSA_SIGN_VALID_S+68 : data_o_rom <= '{opcode:ABR_UOP_NORMCHK, imm:MLDSA_NORMCHK_CT0, length:'d00, operand1:MLDSA_CT_2_BASE, operand2:ABR_NOP, operand3:ABR_NOP}; + MLDSA_SIGN_VALID_S+69 : data_o_rom <= '{opcode:ABR_UOP_PWA, imm:'h0000, length:'d00, operand1:MLDSA_R0_BASE, operand2:MLDSA_CT_2_BASE, operand3:MLDSA_HINT_R_2_BASE}; + + MLDSA_SIGN_VALID_S+70 : data_o_rom <= '{opcode:ABR_UOP_MASKED_PWM, imm:'h0000, length:'d00, operand1:MLDSA_C_NTT_BASE, operand2:MLDSA_S2_3_BASE, operand3:MLDSA_CS_NTT_BASE}; + MLDSA_SIGN_VALID_S+71 : data_o_rom <= '{opcode:ABR_UOP_MASKED_INTT, imm:'h0000, length:'d00, operand1:MLDSA_CS_NTT_BASE, operand2:MLDSA_TEMP2_BASE, operand3:MLDSA_CS2_BASE}; + MLDSA_SIGN_VALID_S+72 : data_o_rom <= '{opcode:ABR_UOP_PWS, imm:'h0000, length:'d00, operand1:MLDSA_CS2_BASE, operand2:MLDSA_W0_3_BASE, operand3:MLDSA_R0_BASE}; + MLDSA_SIGN_VALID_S+73 : data_o_rom <= '{opcode:ABR_UOP_NORMCHK, imm:MLDSA_NORMCHK_R0, length:'d00, operand1:MLDSA_R0_BASE, operand2:ABR_NOP, operand3:ABR_NOP}; + MLDSA_SIGN_VALID_S+74 : data_o_rom <= '{opcode:ABR_UOP_NORMCHK, imm:MLDSA_NORMCHK_CT0, length:'d00, operand1:MLDSA_CT_3_BASE, operand2:ABR_NOP, operand3:ABR_NOP}; + MLDSA_SIGN_VALID_S+75 : data_o_rom <= '{opcode:ABR_UOP_PWA, imm:'h0000, length:'d00, operand1:MLDSA_R0_BASE, operand2:MLDSA_CT_3_BASE, operand3:MLDSA_HINT_R_3_BASE}; + + MLDSA_SIGN_VALID_S+76 : data_o_rom <= '{opcode:ABR_UOP_MASKED_PWM, imm:'h0000, length:'d00, operand1:MLDSA_C_NTT_BASE, operand2:MLDSA_S2_4_BASE, operand3:MLDSA_CS_NTT_BASE}; + MLDSA_SIGN_VALID_S+77 : data_o_rom <= '{opcode:ABR_UOP_MASKED_INTT, imm:'h0000, length:'d00, operand1:MLDSA_CS_NTT_BASE, operand2:MLDSA_TEMP2_BASE, operand3:MLDSA_CS2_BASE}; + MLDSA_SIGN_VALID_S+78 : data_o_rom <= '{opcode:ABR_UOP_PWS, imm:'h0000, length:'d00, operand1:MLDSA_CS2_BASE, operand2:MLDSA_W0_4_BASE, operand3:MLDSA_R0_BASE}; + MLDSA_SIGN_VALID_S+79 : data_o_rom <= '{opcode:ABR_UOP_NORMCHK, imm:MLDSA_NORMCHK_R0, length:'d00, operand1:MLDSA_R0_BASE, operand2:ABR_NOP, operand3:ABR_NOP}; + MLDSA_SIGN_VALID_S+80 : data_o_rom <= '{opcode:ABR_UOP_NORMCHK, imm:MLDSA_NORMCHK_CT0, length:'d00, operand1:MLDSA_CT_4_BASE, operand2:ABR_NOP, operand3:ABR_NOP}; + MLDSA_SIGN_VALID_S+81 : data_o_rom <= '{opcode:ABR_UOP_PWA, imm:'h0000, length:'d00, operand1:MLDSA_R0_BASE, operand2:MLDSA_CT_4_BASE, operand3:MLDSA_HINT_R_4_BASE}; + + MLDSA_SIGN_VALID_S+82 : data_o_rom <= '{opcode:ABR_UOP_MASKED_PWM, imm:'h0000, length:'d00, operand1:MLDSA_C_NTT_BASE, operand2:MLDSA_S2_5_BASE, operand3:MLDSA_CS_NTT_BASE}; + MLDSA_SIGN_VALID_S+83 : data_o_rom <= '{opcode:ABR_UOP_MASKED_INTT, imm:'h0000, length:'d00, operand1:MLDSA_CS_NTT_BASE, operand2:MLDSA_TEMP2_BASE, operand3:MLDSA_CS2_BASE}; + MLDSA_SIGN_VALID_S+84 : data_o_rom <= '{opcode:ABR_UOP_PWS, imm:'h0000, length:'d00, operand1:MLDSA_CS2_BASE, operand2:MLDSA_W0_5_BASE, operand3:MLDSA_R0_BASE}; + MLDSA_SIGN_VALID_S+85 : data_o_rom <= '{opcode:ABR_UOP_NORMCHK, imm:MLDSA_NORMCHK_R0, length:'d00, operand1:MLDSA_R0_BASE, operand2:ABR_NOP, operand3:ABR_NOP}; + MLDSA_SIGN_VALID_S+86 : data_o_rom <= '{opcode:ABR_UOP_NORMCHK, imm:MLDSA_NORMCHK_CT0, length:'d00, operand1:MLDSA_CT_5_BASE, operand2:ABR_NOP, operand3:ABR_NOP}; + MLDSA_SIGN_VALID_S+87 : data_o_rom <= '{opcode:ABR_UOP_PWA, imm:'h0000, length:'d00, operand1:MLDSA_R0_BASE, operand2:MLDSA_CT_5_BASE, operand3:MLDSA_HINT_R_5_BASE}; + + MLDSA_SIGN_VALID_S+88 : data_o_rom <= '{opcode:ABR_UOP_MASKED_PWM, imm:'h0000, length:'d00, operand1:MLDSA_C_NTT_BASE, operand2:MLDSA_S2_6_BASE, operand3:MLDSA_CS_NTT_BASE}; + MLDSA_SIGN_VALID_S+89 : data_o_rom <= '{opcode:ABR_UOP_MASKED_INTT, imm:'h0000, length:'d00, operand1:MLDSA_CS_NTT_BASE, operand2:MLDSA_TEMP2_BASE, operand3:MLDSA_CS2_BASE}; + MLDSA_SIGN_VALID_S+90 : data_o_rom <= '{opcode:ABR_UOP_PWS, imm:'h0000, length:'d00, operand1:MLDSA_CS2_BASE, operand2:MLDSA_W0_6_BASE, operand3:MLDSA_R0_BASE}; + MLDSA_SIGN_VALID_S+91 : data_o_rom <= '{opcode:ABR_UOP_NORMCHK, imm:MLDSA_NORMCHK_R0, length:'d00, operand1:MLDSA_R0_BASE, operand2:ABR_NOP, operand3:ABR_NOP}; + MLDSA_SIGN_VALID_S+92 : data_o_rom <= '{opcode:ABR_UOP_NORMCHK, imm:MLDSA_NORMCHK_CT0, length:'d00, operand1:MLDSA_CT_6_BASE, operand2:ABR_NOP, operand3:ABR_NOP}; + MLDSA_SIGN_VALID_S+93 : data_o_rom <= '{opcode:ABR_UOP_PWA, imm:'h0000, length:'d00, operand1:MLDSA_R0_BASE, operand2:MLDSA_CT_6_BASE, operand3:MLDSA_HINT_R_6_BASE}; + + MLDSA_SIGN_VALID_S+94 : data_o_rom <= '{opcode:ABR_UOP_MASKED_PWM, imm:'h0000, length:'d00, operand1:MLDSA_C_NTT_BASE, operand2:MLDSA_S2_7_BASE, operand3:MLDSA_CS_NTT_BASE}; + MLDSA_SIGN_VALID_S+95 : data_o_rom <= '{opcode:ABR_UOP_MASKED_INTT, imm:'h0000, length:'d00, operand1:MLDSA_CS_NTT_BASE, operand2:MLDSA_TEMP2_BASE, operand3:MLDSA_CS2_BASE}; + MLDSA_SIGN_VALID_S+96 : data_o_rom <= '{opcode:ABR_UOP_PWS, imm:'h0000, length:'d00, operand1:MLDSA_CS2_BASE, operand2:MLDSA_W0_7_BASE, operand3:MLDSA_R0_BASE}; + MLDSA_SIGN_VALID_S+97 : data_o_rom <= '{opcode:ABR_UOP_NORMCHK, imm:MLDSA_NORMCHK_R0, length:'d00, operand1:MLDSA_R0_BASE, operand2:ABR_NOP, operand3:ABR_NOP}; + MLDSA_SIGN_VALID_S+98 : data_o_rom <= '{opcode:ABR_UOP_NORMCHK, imm:MLDSA_NORMCHK_CT0, length:'d00, operand1:MLDSA_CT_7_BASE, operand2:ABR_NOP, operand3:ABR_NOP}; + MLDSA_SIGN_VALID_S+99 : data_o_rom <= '{opcode:ABR_UOP_PWA, imm:'h0000, length:'d00, operand1:MLDSA_R0_BASE, operand2:MLDSA_CT_7_BASE, operand3:MLDSA_HINT_R_7_BASE}; + + MLDSA_SIGN_VALID_S+100: data_o_rom <= '{opcode:ABR_UOP_MAKEHINT, imm:'h0000, length:'d00, operand1:MLDSA_HINT_R_0_BASE, operand2:ABR_NOP, operand3:ABR_NOP}; + + MLDSA_SIGN_CHL_E : data_o_rom <= '{opcode:ABR_UOP_NOP, imm:'h0000, length:'d00, operand1:ABR_NOP, operand2:ABR_NOP, operand3:ABR_NOP}; + MLDSA_SIGN_E : data_o_rom <= '{opcode:ABR_UOP_NOP, imm:'h0000, length:'d00, operand1:ABR_NOP, operand2:ABR_NOP, operand3:ABR_NOP}; + + //Verify flow + //(ρ,t1)←pkDecode(pk) + MLDSA_VERIFY_S : data_o_rom <= '{opcode:ABR_UOP_PKDECODE, imm:'h0000, length:'d00, operand1:ABR_NOP, operand2:ABR_NOP, operand3:MLDSA_T0_BASE}; + //(c˜,z,h)←sigDecode(σ) + MLDSA_VERIFY_S+ 1 : data_o_rom <= '{opcode:ABR_UOP_SIGDEC_Z, imm:'h0000, length:'d00, operand1:ABR_NOP, operand2:ABR_NOP, operand3:MLDSA_Z_0_BASE}; + //||z||∞ ≥ γ1 −β + MLDSA_VERIFY_S+ 2 : data_o_rom <= '{opcode:ABR_UOP_NORMCHK, imm:MLDSA_NORMCHK_Z, length:'d00, operand1:MLDSA_Z_0_BASE, operand2:ABR_NOP, operand3:ABR_NOP}; + MLDSA_VERIFY_S+ 3 : data_o_rom <= '{opcode:ABR_UOP_NORMCHK, imm:MLDSA_NORMCHK_Z, length:'d00, operand1:MLDSA_Z_1_BASE, operand2:ABR_NOP, operand3:ABR_NOP}; + MLDSA_VERIFY_S+ 4 : data_o_rom <= '{opcode:ABR_UOP_NORMCHK, imm:MLDSA_NORMCHK_Z, length:'d00, operand1:MLDSA_Z_2_BASE, operand2:ABR_NOP, operand3:ABR_NOP}; + MLDSA_VERIFY_S+ 5 : data_o_rom <= '{opcode:ABR_UOP_NORMCHK, imm:MLDSA_NORMCHK_Z, length:'d00, operand1:MLDSA_Z_3_BASE, operand2:ABR_NOP, operand3:ABR_NOP}; + MLDSA_VERIFY_S+ 6 : data_o_rom <= '{opcode:ABR_UOP_NORMCHK, imm:MLDSA_NORMCHK_Z, length:'d00, operand1:MLDSA_Z_4_BASE, operand2:ABR_NOP, operand3:ABR_NOP}; + MLDSA_VERIFY_S+ 7 : data_o_rom <= '{opcode:ABR_UOP_NORMCHK, imm:MLDSA_NORMCHK_Z, length:'d00, operand1:MLDSA_Z_5_BASE, operand2:ABR_NOP, operand3:ABR_NOP}; + MLDSA_VERIFY_S+ 8 : data_o_rom <= '{opcode:ABR_UOP_NORMCHK, imm:MLDSA_NORMCHK_Z, length:'d00, operand1:MLDSA_Z_6_BASE, operand2:ABR_NOP, operand3:ABR_NOP}; + //tr ←H(pk,512) + MLDSA_VERIFY_H_TR : data_o_rom <= '{opcode:ABR_UOP_SHAKE256, imm:'h0000, length:PUBKEY_NUM_BYTES, operand1:MLDSA_PK_REG_ID, operand2:ABR_NOP, operand3:MLDSA_DEST_TR_REG_ID}; + MLDSA_VERIFY_CHECK_MODE : data_o_rom <= '{opcode:ABR_UOP_NOP, imm:'h0000, length:'d00, operand1:ABR_NOP, operand2:ABR_NOP, operand3:ABR_NOP}; + //μ ←H(tr||M,512) + MLDSA_VERIFY_H_MU : data_o_rom <= '{opcode:ABR_UOP_LD_SHAKE256, imm:'h0000, length:'d64, operand1:MLDSA_TR_ID, operand2:ABR_NOP, operand3:ABR_NOP}; + MLDSA_VERIFY_H_MU+ 1 : data_o_rom <= '{opcode:ABR_UOP_SHAKE256, imm:'h0000, length:'d66, operand1:MLDSA_MSG_ID, operand2:ABR_NOP, operand3:MLDSA_DEST_MU_REG_ID}; + //c ←SampleInBall(c˜1) + MLDSA_VERIFY_MAKE_C : data_o_rom <= '{opcode:ABR_UOP_SIB, imm:'h0000, length:'d64, operand1:MLDSA_SIG_C_REG_ID, operand2:ABR_NOP, operand3:ABR_NOP}; + //cˆ ←NTT(c) + MLDSA_VERIFY_NTT_C : data_o_rom <= '{opcode:ABR_UOP_NTT, imm:'h0000, length:'d00, operand1:MLDSA_C_BASE, operand2:MLDSA_TEMP0_BASE, operand3:MLDSA_C_NTT_BASE}; + //t1 ←NTT(t1) + MLDSA_VERIFY_NTT_T1 : data_o_rom <= '{opcode:ABR_UOP_NTT, imm:'h0000, length:'d00, operand1:MLDSA_T0_BASE, operand2:MLDSA_TEMP0_BASE, operand3:MLDSA_T0_BASE}; + MLDSA_VERIFY_NTT_T1+ 1 : data_o_rom <= '{opcode:ABR_UOP_NTT, imm:'h0000, length:'d00, operand1:MLDSA_T1_BASE, operand2:MLDSA_TEMP0_BASE, operand3:MLDSA_T1_BASE}; + MLDSA_VERIFY_NTT_T1+ 2 : data_o_rom <= '{opcode:ABR_UOP_NTT, imm:'h0000, length:'d00, operand1:MLDSA_T2_BASE, operand2:MLDSA_TEMP0_BASE, operand3:MLDSA_T2_BASE}; + MLDSA_VERIFY_NTT_T1+ 3 : data_o_rom <= '{opcode:ABR_UOP_NTT, imm:'h0000, length:'d00, operand1:MLDSA_T3_BASE, operand2:MLDSA_TEMP0_BASE, operand3:MLDSA_T3_BASE}; + MLDSA_VERIFY_NTT_T1+ 4 : data_o_rom <= '{opcode:ABR_UOP_NTT, imm:'h0000, length:'d00, operand1:MLDSA_T4_BASE, operand2:MLDSA_TEMP0_BASE, operand3:MLDSA_T4_BASE}; + MLDSA_VERIFY_NTT_T1+ 5 : data_o_rom <= '{opcode:ABR_UOP_NTT, imm:'h0000, length:'d00, operand1:MLDSA_T5_BASE, operand2:MLDSA_TEMP0_BASE, operand3:MLDSA_T5_BASE}; + MLDSA_VERIFY_NTT_T1+ 6 : data_o_rom <= '{opcode:ABR_UOP_NTT, imm:'h0000, length:'d00, operand1:MLDSA_T6_BASE, operand2:MLDSA_TEMP0_BASE, operand3:MLDSA_T6_BASE}; + MLDSA_VERIFY_NTT_T1+ 7 : data_o_rom <= '{opcode:ABR_UOP_NTT, imm:'h0000, length:'d00, operand1:MLDSA_T7_BASE, operand2:MLDSA_TEMP0_BASE, operand3:MLDSA_T7_BASE}; + + //z ←NTT(z) + MLDSA_VERIFY_NTT_Z : data_o_rom <= '{opcode:ABR_UOP_NTT, imm:'h0000, length:'d00, operand1:MLDSA_Z_0_BASE, operand2:MLDSA_TEMP0_BASE, operand3:MLDSA_Z_NTT_0_BASE}; + MLDSA_VERIFY_NTT_Z+ 1 : data_o_rom <= '{opcode:ABR_UOP_NTT, imm:'h0000, length:'d00, operand1:MLDSA_Z_1_BASE, operand2:MLDSA_TEMP0_BASE, operand3:MLDSA_Z_NTT_1_BASE}; + MLDSA_VERIFY_NTT_Z+ 2 : data_o_rom <= '{opcode:ABR_UOP_NTT, imm:'h0000, length:'d00, operand1:MLDSA_Z_2_BASE, operand2:MLDSA_TEMP0_BASE, operand3:MLDSA_Z_NTT_2_BASE}; + MLDSA_VERIFY_NTT_Z+ 3 : data_o_rom <= '{opcode:ABR_UOP_NTT, imm:'h0000, length:'d00, operand1:MLDSA_Z_3_BASE, operand2:MLDSA_TEMP0_BASE, operand3:MLDSA_Z_NTT_3_BASE}; + MLDSA_VERIFY_NTT_Z+ 4 : data_o_rom <= '{opcode:ABR_UOP_NTT, imm:'h0000, length:'d00, operand1:MLDSA_Z_4_BASE, operand2:MLDSA_TEMP0_BASE, operand3:MLDSA_Z_NTT_4_BASE}; + MLDSA_VERIFY_NTT_Z+ 5 : data_o_rom <= '{opcode:ABR_UOP_NTT, imm:'h0000, length:'d00, operand1:MLDSA_Z_5_BASE, operand2:MLDSA_TEMP0_BASE, operand3:MLDSA_Z_NTT_5_BASE}; + MLDSA_VERIFY_NTT_Z+ 6 : data_o_rom <= '{opcode:ABR_UOP_NTT, imm:'h0000, length:'d00, operand1:MLDSA_Z_6_BASE, operand2:MLDSA_TEMP0_BASE, operand3:MLDSA_Z_NTT_6_BASE}; + //Aˆ ←ExpandA(ρ) AND Aˆ ◦NTT(z) + MLDSA_VERIFY_EXP_A+ 0 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWM, imm:'h0000, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Z_NTT_0_BASE, operand3:MLDSA_AZ0_BASE}; + MLDSA_VERIFY_EXP_A+ 1 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWMA, imm:'h0001, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Z_NTT_1_BASE, operand3:MLDSA_AZ0_BASE}; + MLDSA_VERIFY_EXP_A+ 2 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWMA, imm:'h0002, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Z_NTT_2_BASE, operand3:MLDSA_AZ0_BASE}; + MLDSA_VERIFY_EXP_A+ 3 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWMA, imm:'h0003, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Z_NTT_3_BASE, operand3:MLDSA_AZ0_BASE}; + MLDSA_VERIFY_EXP_A+ 4 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWMA, imm:'h0004, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Z_NTT_4_BASE, operand3:MLDSA_AZ0_BASE}; + MLDSA_VERIFY_EXP_A+ 5 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWMA, imm:'h0005, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Z_NTT_5_BASE, operand3:MLDSA_AZ0_BASE}; + MLDSA_VERIFY_EXP_A+ 6 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWMA, imm:'h0006, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Z_NTT_6_BASE, operand3:MLDSA_AZ0_BASE}; + MLDSA_VERIFY_EXP_A+ 7 : data_o_rom <= '{opcode:ABR_UOP_PWM, imm:'h0000, length:'d00, operand1:MLDSA_C_NTT_BASE, operand2:MLDSA_T0_BASE, operand3:MLDSA_CT_BASE}; + MLDSA_VERIFY_EXP_A+ 8 : data_o_rom <= '{opcode:ABR_UOP_PWS, imm:'h0000, length:'d00, operand1:MLDSA_CT_BASE, operand2:MLDSA_AZ0_BASE, operand3:MLDSA_AZ0_BASE}; + MLDSA_VERIFY_EXP_A+ 9 : data_o_rom <= '{opcode:ABR_UOP_INTT, imm:'h0000, length:'d00, operand1:MLDSA_AZ0_BASE, operand2:MLDSA_TEMP0_BASE, operand3:MLDSA_W0_0_BASE}; + + MLDSA_VERIFY_EXP_A+ 10 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWM, imm:'h0100, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Z_NTT_0_BASE, operand3:MLDSA_AZ0_BASE}; + MLDSA_VERIFY_EXP_A+ 11 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWMA, imm:'h0101, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Z_NTT_1_BASE, operand3:MLDSA_AZ0_BASE}; + MLDSA_VERIFY_EXP_A+ 12 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWMA, imm:'h0102, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Z_NTT_2_BASE, operand3:MLDSA_AZ0_BASE}; + MLDSA_VERIFY_EXP_A+ 13 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWMA, imm:'h0103, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Z_NTT_3_BASE, operand3:MLDSA_AZ0_BASE}; + MLDSA_VERIFY_EXP_A+ 14 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWMA, imm:'h0104, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Z_NTT_4_BASE, operand3:MLDSA_AZ0_BASE}; + MLDSA_VERIFY_EXP_A+ 15 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWMA, imm:'h0105, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Z_NTT_5_BASE, operand3:MLDSA_AZ0_BASE}; + MLDSA_VERIFY_EXP_A+ 16 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWMA, imm:'h0106, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Z_NTT_6_BASE, operand3:MLDSA_AZ0_BASE}; + MLDSA_VERIFY_EXP_A+ 17 : data_o_rom <= '{opcode:ABR_UOP_PWM, imm:'h0000, length:'d00, operand1:MLDSA_C_NTT_BASE, operand2:MLDSA_T1_BASE, operand3:MLDSA_CT_BASE}; + MLDSA_VERIFY_EXP_A+ 18 : data_o_rom <= '{opcode:ABR_UOP_PWS, imm:'h0000, length:'d00, operand1:MLDSA_CT_BASE, operand2:MLDSA_AZ0_BASE, operand3:MLDSA_AZ0_BASE}; + MLDSA_VERIFY_EXP_A+ 19 : data_o_rom <= '{opcode:ABR_UOP_INTT, imm:'h0000, length:'d00, operand1:MLDSA_AZ0_BASE, operand2:MLDSA_TEMP0_BASE, operand3:MLDSA_W0_1_BASE}; + + MLDSA_VERIFY_EXP_A+ 20 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWM, imm:'h0200, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Z_NTT_0_BASE, operand3:MLDSA_AZ0_BASE}; + MLDSA_VERIFY_EXP_A+ 21 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWMA, imm:'h0201, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Z_NTT_1_BASE, operand3:MLDSA_AZ0_BASE}; + MLDSA_VERIFY_EXP_A+ 22 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWMA, imm:'h0202, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Z_NTT_2_BASE, operand3:MLDSA_AZ0_BASE}; + MLDSA_VERIFY_EXP_A+ 23 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWMA, imm:'h0203, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Z_NTT_3_BASE, operand3:MLDSA_AZ0_BASE}; + MLDSA_VERIFY_EXP_A+ 24 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWMA, imm:'h0204, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Z_NTT_4_BASE, operand3:MLDSA_AZ0_BASE}; + MLDSA_VERIFY_EXP_A+ 25 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWMA, imm:'h0205, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Z_NTT_5_BASE, operand3:MLDSA_AZ0_BASE}; + MLDSA_VERIFY_EXP_A+ 26 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWMA, imm:'h0206, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Z_NTT_6_BASE, operand3:MLDSA_AZ0_BASE}; + MLDSA_VERIFY_EXP_A+ 27 : data_o_rom <= '{opcode:ABR_UOP_PWM, imm:'h0000, length:'d00, operand1:MLDSA_C_NTT_BASE, operand2:MLDSA_T2_BASE, operand3:MLDSA_CT_BASE}; + MLDSA_VERIFY_EXP_A+ 28 : data_o_rom <= '{opcode:ABR_UOP_PWS, imm:'h0000, length:'d00, operand1:MLDSA_CT_BASE, operand2:MLDSA_AZ0_BASE, operand3:MLDSA_AZ0_BASE}; + MLDSA_VERIFY_EXP_A+ 29 : data_o_rom <= '{opcode:ABR_UOP_INTT, imm:'h0000, length:'d00, operand1:MLDSA_AZ0_BASE, operand2:MLDSA_TEMP0_BASE, operand3:MLDSA_W0_2_BASE}; + + MLDSA_VERIFY_EXP_A+ 30 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWM, imm:'h0300, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Z_NTT_0_BASE, operand3:MLDSA_AZ0_BASE}; + MLDSA_VERIFY_EXP_A+ 31 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWMA, imm:'h0301, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Z_NTT_1_BASE, operand3:MLDSA_AZ0_BASE}; + MLDSA_VERIFY_EXP_A+ 32 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWMA, imm:'h0302, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Z_NTT_2_BASE, operand3:MLDSA_AZ0_BASE}; + MLDSA_VERIFY_EXP_A+ 33 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWMA, imm:'h0303, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Z_NTT_3_BASE, operand3:MLDSA_AZ0_BASE}; + MLDSA_VERIFY_EXP_A+ 34 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWMA, imm:'h0304, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Z_NTT_4_BASE, operand3:MLDSA_AZ0_BASE}; + MLDSA_VERIFY_EXP_A+ 35 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWMA, imm:'h0305, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Z_NTT_5_BASE, operand3:MLDSA_AZ0_BASE}; + MLDSA_VERIFY_EXP_A+ 36 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWMA, imm:'h0306, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Z_NTT_6_BASE, operand3:MLDSA_AZ0_BASE}; + MLDSA_VERIFY_EXP_A+ 37 : data_o_rom <= '{opcode:ABR_UOP_PWM, imm:'h0000, length:'d00, operand1:MLDSA_C_NTT_BASE, operand2:MLDSA_T3_BASE, operand3:MLDSA_CT_BASE}; + MLDSA_VERIFY_EXP_A+ 38 : data_o_rom <= '{opcode:ABR_UOP_PWS, imm:'h0000, length:'d00, operand1:MLDSA_CT_BASE, operand2:MLDSA_AZ0_BASE, operand3:MLDSA_AZ0_BASE}; + MLDSA_VERIFY_EXP_A+ 39 : data_o_rom <= '{opcode:ABR_UOP_INTT, imm:'h0000, length:'d00, operand1:MLDSA_AZ0_BASE, operand2:MLDSA_TEMP0_BASE, operand3:MLDSA_W0_3_BASE}; + + MLDSA_VERIFY_EXP_A+ 40 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWM, imm:'h0400, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Z_NTT_0_BASE, operand3:MLDSA_AZ0_BASE}; + MLDSA_VERIFY_EXP_A+ 41 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWMA, imm:'h0401, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Z_NTT_1_BASE, operand3:MLDSA_AZ0_BASE}; + MLDSA_VERIFY_EXP_A+ 42 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWMA, imm:'h0402, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Z_NTT_2_BASE, operand3:MLDSA_AZ0_BASE}; + MLDSA_VERIFY_EXP_A+ 43 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWMA, imm:'h0403, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Z_NTT_3_BASE, operand3:MLDSA_AZ0_BASE}; + MLDSA_VERIFY_EXP_A+ 44 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWMA, imm:'h0404, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Z_NTT_4_BASE, operand3:MLDSA_AZ0_BASE}; + MLDSA_VERIFY_EXP_A+ 45 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWMA, imm:'h0405, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Z_NTT_5_BASE, operand3:MLDSA_AZ0_BASE}; + MLDSA_VERIFY_EXP_A+ 46 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWMA, imm:'h0406, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Z_NTT_6_BASE, operand3:MLDSA_AZ0_BASE}; + MLDSA_VERIFY_EXP_A+ 47 : data_o_rom <= '{opcode:ABR_UOP_PWM, imm:'h0000, length:'d00, operand1:MLDSA_C_NTT_BASE, operand2:MLDSA_T4_BASE, operand3:MLDSA_CT_BASE}; + MLDSA_VERIFY_EXP_A+ 48 : data_o_rom <= '{opcode:ABR_UOP_PWS, imm:'h0000, length:'d00, operand1:MLDSA_CT_BASE, operand2:MLDSA_AZ0_BASE, operand3:MLDSA_AZ0_BASE}; + MLDSA_VERIFY_EXP_A+ 49 : data_o_rom <= '{opcode:ABR_UOP_INTT, imm:'h0000, length:'d00, operand1:MLDSA_AZ0_BASE, operand2:MLDSA_TEMP0_BASE, operand3:MLDSA_W0_4_BASE}; + + MLDSA_VERIFY_EXP_A+ 50 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWM, imm:'h0500, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Z_NTT_0_BASE, operand3:MLDSA_AZ0_BASE}; + MLDSA_VERIFY_EXP_A+ 51 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWMA, imm:'h0501, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Z_NTT_1_BASE, operand3:MLDSA_AZ0_BASE}; + MLDSA_VERIFY_EXP_A+ 52 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWMA, imm:'h0502, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Z_NTT_2_BASE, operand3:MLDSA_AZ0_BASE}; + MLDSA_VERIFY_EXP_A+ 53 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWMA, imm:'h0503, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Z_NTT_3_BASE, operand3:MLDSA_AZ0_BASE}; + MLDSA_VERIFY_EXP_A+ 54 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWMA, imm:'h0504, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Z_NTT_4_BASE, operand3:MLDSA_AZ0_BASE}; + MLDSA_VERIFY_EXP_A+ 55 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWMA, imm:'h0505, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Z_NTT_5_BASE, operand3:MLDSA_AZ0_BASE}; + MLDSA_VERIFY_EXP_A+ 56 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWMA, imm:'h0506, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Z_NTT_6_BASE, operand3:MLDSA_AZ0_BASE}; + MLDSA_VERIFY_EXP_A+ 57 : data_o_rom <= '{opcode:ABR_UOP_PWM, imm:'h0000, length:'d00, operand1:MLDSA_C_NTT_BASE, operand2:MLDSA_T5_BASE, operand3:MLDSA_CT_BASE}; + MLDSA_VERIFY_EXP_A+ 58 : data_o_rom <= '{opcode:ABR_UOP_PWS, imm:'h0000, length:'d00, operand1:MLDSA_CT_BASE, operand2:MLDSA_AZ0_BASE, operand3:MLDSA_AZ0_BASE}; + MLDSA_VERIFY_EXP_A+ 59 : data_o_rom <= '{opcode:ABR_UOP_INTT, imm:'h0000, length:'d00, operand1:MLDSA_AZ0_BASE, operand2:MLDSA_TEMP0_BASE, operand3:MLDSA_W0_5_BASE}; + + MLDSA_VERIFY_EXP_A+ 60 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWM, imm:'h0600, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Z_NTT_0_BASE, operand3:MLDSA_AZ0_BASE}; + MLDSA_VERIFY_EXP_A+ 61 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWMA, imm:'h0601, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Z_NTT_1_BASE, operand3:MLDSA_AZ0_BASE}; + MLDSA_VERIFY_EXP_A+ 62 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWMA, imm:'h0602, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Z_NTT_2_BASE, operand3:MLDSA_AZ0_BASE}; + MLDSA_VERIFY_EXP_A+ 63 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWMA, imm:'h0603, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Z_NTT_3_BASE, operand3:MLDSA_AZ0_BASE}; + MLDSA_VERIFY_EXP_A+ 64 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWMA, imm:'h0604, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Z_NTT_4_BASE, operand3:MLDSA_AZ0_BASE}; + MLDSA_VERIFY_EXP_A+ 65 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWMA, imm:'h0605, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Z_NTT_5_BASE, operand3:MLDSA_AZ0_BASE}; + MLDSA_VERIFY_EXP_A+ 66 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWMA, imm:'h0606, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Z_NTT_6_BASE, operand3:MLDSA_AZ0_BASE}; + MLDSA_VERIFY_EXP_A+ 67 : data_o_rom <= '{opcode:ABR_UOP_PWM, imm:'h0000, length:'d00, operand1:MLDSA_C_NTT_BASE, operand2:MLDSA_T6_BASE, operand3:MLDSA_CT_BASE}; + MLDSA_VERIFY_EXP_A+ 68 : data_o_rom <= '{opcode:ABR_UOP_PWS, imm:'h0000, length:'d00, operand1:MLDSA_CT_BASE, operand2:MLDSA_AZ0_BASE, operand3:MLDSA_AZ0_BASE}; + MLDSA_VERIFY_EXP_A+ 69 : data_o_rom <= '{opcode:ABR_UOP_INTT, imm:'h0000, length:'d00, operand1:MLDSA_AZ0_BASE, operand2:MLDSA_TEMP0_BASE, operand3:MLDSA_W0_6_BASE}; + + MLDSA_VERIFY_EXP_A+ 70 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWM, imm:'h0700, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Z_NTT_0_BASE, operand3:MLDSA_AZ0_BASE}; + MLDSA_VERIFY_EXP_A+ 71 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWMA, imm:'h0701, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Z_NTT_1_BASE, operand3:MLDSA_AZ0_BASE}; + MLDSA_VERIFY_EXP_A+ 72 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWMA, imm:'h0702, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Z_NTT_2_BASE, operand3:MLDSA_AZ0_BASE}; + MLDSA_VERIFY_EXP_A+ 73 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWMA, imm:'h0703, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Z_NTT_3_BASE, operand3:MLDSA_AZ0_BASE}; + MLDSA_VERIFY_EXP_A+ 74 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWMA, imm:'h0704, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Z_NTT_4_BASE, operand3:MLDSA_AZ0_BASE}; + MLDSA_VERIFY_EXP_A+ 75 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWMA, imm:'h0705, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Z_NTT_5_BASE, operand3:MLDSA_AZ0_BASE}; + MLDSA_VERIFY_EXP_A+ 76 : data_o_rom <= '{opcode:ABR_UOP_REJS_PWMA, imm:'h0706, length:'d34, operand1:MLDSA_RHO_ID, operand2:MLDSA_Z_NTT_6_BASE, operand3:MLDSA_AZ0_BASE}; + MLDSA_VERIFY_EXP_A+ 77 : data_o_rom <= '{opcode:ABR_UOP_PWM, imm:'h0000, length:'d00, operand1:MLDSA_C_NTT_BASE, operand2:MLDSA_T7_BASE, operand3:MLDSA_CT_BASE}; + MLDSA_VERIFY_EXP_A+ 78 : data_o_rom <= '{opcode:ABR_UOP_PWS, imm:'h0000, length:'d00, operand1:MLDSA_CT_BASE, operand2:MLDSA_AZ0_BASE, operand3:MLDSA_AZ0_BASE}; + MLDSA_VERIFY_EXP_A+ 79 : data_o_rom <= '{opcode:ABR_UOP_INTT, imm:'h0000, length:'d00, operand1:MLDSA_AZ0_BASE, operand2:MLDSA_TEMP0_BASE, operand3:MLDSA_W0_7_BASE}; + + MLDSA_VERIFY_RES+ 0 : data_o_rom <= '{opcode:ABR_UOP_SIGDEC_H, imm:'h0000, length:'d00, operand1:ABR_NOP, operand2:ABR_NOP, operand3:MLDSA_HINT_R_0_BASE}; + MLDSA_VERIFY_RES+ 1 : data_o_rom <= '{opcode:ABR_UOP_LD_SHAKE256, imm:'h0000, length:'d64, operand1:MLDSA_MU_ID, operand2:ABR_NOP, operand3:ABR_NOP}; + MLDSA_VERIFY_RES+ 2 : data_o_rom <= '{opcode:ABR_UOP_USEHINT, imm:'h0000, length:'d00, operand1:MLDSA_W0_0_BASE, operand2:MLDSA_HINT_R_0_BASE, operand3:ABR_NOP}; + MLDSA_VERIFY_RES+ 3 : data_o_rom <= '{opcode:ABR_UOP_RUN_SHAKE256, imm:'h0000, length:'d00, operand1:ABR_NOP, operand2:ABR_NOP, operand3:MLDSA_DEST_VERIFY_RES_REG_ID}; + MLDSA_VERIFY_E : data_o_rom <= '{opcode:ABR_UOP_NOP, imm:'h0000, length:'d00, operand1:ABR_NOP, operand2:ABR_NOP, operand3:ABR_NOP}; + + //MLKEM Keygen + //rnd_seed=Keccak(entropy||counter) + MLKEM_KG_S + 0 : data_o_rom <= '{opcode:ABR_UOP_LD_SHAKE256, imm:'h0000, length:'d64, operand1:ABR_ENTROPY_ID, operand2:ABR_NOP, operand3:ABR_NOP}; + MLKEM_KG_S + 1 : data_o_rom <= '{opcode:ABR_UOP_SHAKE256, imm:'h0000, length:'d08, operand1:ABR_CNT_ID, operand2:ABR_NOP, operand3:ABR_DEST_LFSR_SEED_REG_ID}; + MLKEM_KG_S + 2 : data_o_rom <= '{opcode:ABR_UOP_LFSR, imm:'h0000, length:'d00, operand1:ABR_NOP, operand2:ABR_NOP, operand3:ABR_NOP}; + MLKEM_KG_S + 3 : data_o_rom <= '{opcode:ABR_UOP_SHA512, imm:'h0004, length:'d33, operand1:MLKEM_SEED_D_ID, operand2:ABR_NOP, operand3:MLKEM_DEST_RHO_SIGMA_REG_ID}; + MLKEM_KG_S + 4 : data_o_rom <= '{opcode:ABR_UOP_CBD, imm:'h0000, length:'d33, operand1:MLKEM_SIGMA_ID, operand2:ABR_NOP, operand3:MLKEM_S0_BASE}; + MLKEM_KG_S + 5 : data_o_rom <= '{opcode:ABR_UOP_CBD, imm:'h0001, length:'d33, operand1:MLKEM_SIGMA_ID, operand2:ABR_NOP, operand3:MLKEM_S1_BASE}; + MLKEM_KG_S + 6 : data_o_rom <= '{opcode:ABR_UOP_CBD, imm:'h0002, length:'d33, operand1:MLKEM_SIGMA_ID, operand2:ABR_NOP, operand3:MLKEM_S2_BASE}; + MLKEM_KG_S + 7 : data_o_rom <= '{opcode:ABR_UOP_CBD, imm:'h0003, length:'d33, operand1:MLKEM_SIGMA_ID, operand2:ABR_NOP, operand3:MLKEM_S3_BASE}; + MLKEM_KG_S + 8 : data_o_rom <= '{opcode:ABR_UOP_CBD, imm:'h0004, length:'d33, operand1:MLKEM_SIGMA_ID, operand2:ABR_NOP, operand3:MLKEM_E0_BASE}; + MLKEM_KG_S + 9 : data_o_rom <= '{opcode:ABR_UOP_CBD, imm:'h0005, length:'d33, operand1:MLKEM_SIGMA_ID, operand2:ABR_NOP, operand3:MLKEM_E1_BASE}; + MLKEM_KG_S + 10: data_o_rom <= '{opcode:ABR_UOP_CBD, imm:'h0006, length:'d33, operand1:MLKEM_SIGMA_ID, operand2:ABR_NOP, operand3:MLKEM_E2_BASE}; + MLKEM_KG_S + 11: data_o_rom <= '{opcode:ABR_UOP_CBD, imm:'h0007, length:'d33, operand1:MLKEM_SIGMA_ID, operand2:ABR_NOP, operand3:MLKEM_E3_BASE}; + MLKEM_KG_S + 12: data_o_rom <= '{opcode:ABR_UOP_MLKEM_NTT, imm:'h0000, length:'d00, operand1:MLKEM_S0_BASE, operand2:ABR_NOP, operand3:MLKEM_S0_BASE}; + MLKEM_KG_S + 13: data_o_rom <= '{opcode:ABR_UOP_MLKEM_NTT, imm:'h0000, length:'d00, operand1:MLKEM_S1_BASE, operand2:ABR_NOP, operand3:MLKEM_S1_BASE}; + MLKEM_KG_S + 14: data_o_rom <= '{opcode:ABR_UOP_MLKEM_NTT, imm:'h0000, length:'d00, operand1:MLKEM_S2_BASE, operand2:ABR_NOP, operand3:MLKEM_S2_BASE}; + MLKEM_KG_S + 15: data_o_rom <= '{opcode:ABR_UOP_MLKEM_NTT, imm:'h0000, length:'d00, operand1:MLKEM_S3_BASE, operand2:ABR_NOP, operand3:MLKEM_S3_BASE}; + MLKEM_KG_S + 16: data_o_rom <= '{opcode:ABR_UOP_MLKEM_NTT, imm:'h0000, length:'d00, operand1:MLKEM_E0_BASE, operand2:ABR_NOP, operand3:MLKEM_E0_BASE}; + MLKEM_KG_S + 17: data_o_rom <= '{opcode:ABR_UOP_MLKEM_NTT, imm:'h0000, length:'d00, operand1:MLKEM_E1_BASE, operand2:ABR_NOP, operand3:MLKEM_E1_BASE}; + MLKEM_KG_S + 18: data_o_rom <= '{opcode:ABR_UOP_MLKEM_NTT, imm:'h0000, length:'d00, operand1:MLKEM_E2_BASE, operand2:ABR_NOP, operand3:MLKEM_E2_BASE}; + MLKEM_KG_S + 19: data_o_rom <= '{opcode:ABR_UOP_MLKEM_NTT, imm:'h0000, length:'d00, operand1:MLKEM_E3_BASE, operand2:ABR_NOP, operand3:MLKEM_E3_BASE}; + MLKEM_KG_S + 20: data_o_rom <= '{opcode:ABR_UOP_MLKEM_REJS_PWM , imm:'h0000, length:'d34, operand1:MLKEM_RHO_ID, operand2:MLKEM_S0_BASE, operand3:MLKEM_AS0_BASE}; + MLKEM_KG_S + 21: data_o_rom <= '{opcode:ABR_UOP_MLKEM_REJS_PWMA, imm:'h0001, length:'d34, operand1:MLKEM_RHO_ID, operand2:MLKEM_S1_BASE, operand3:MLKEM_AS0_BASE}; + MLKEM_KG_S + 22: data_o_rom <= '{opcode:ABR_UOP_MLKEM_REJS_PWMA, imm:'h0002, length:'d34, operand1:MLKEM_RHO_ID, operand2:MLKEM_S2_BASE, operand3:MLKEM_AS0_BASE}; + MLKEM_KG_S + 23: data_o_rom <= '{opcode:ABR_UOP_MLKEM_REJS_PWMA, imm:'h0003, length:'d34, operand1:MLKEM_RHO_ID, operand2:MLKEM_S3_BASE, operand3:MLKEM_AS0_BASE}; + MLKEM_KG_S + 24: data_o_rom <= '{opcode:ABR_UOP_MLKEM_PWA, imm:'h0000, length:'d00, operand1:MLKEM_AS0_BASE, operand2:MLKEM_E0_BASE, operand3:MLKEM_T0_BASE}; + MLKEM_KG_S + 25: data_o_rom <= '{opcode:ABR_UOP_MLKEM_REJS_PWM , imm:'h0100, length:'d34, operand1:MLKEM_RHO_ID, operand2:MLKEM_S0_BASE, operand3:MLKEM_AS0_BASE}; + MLKEM_KG_S + 26: data_o_rom <= '{opcode:ABR_UOP_MLKEM_REJS_PWMA, imm:'h0101, length:'d34, operand1:MLKEM_RHO_ID, operand2:MLKEM_S1_BASE, operand3:MLKEM_AS0_BASE}; + MLKEM_KG_S + 27: data_o_rom <= '{opcode:ABR_UOP_MLKEM_REJS_PWMA, imm:'h0102, length:'d34, operand1:MLKEM_RHO_ID, operand2:MLKEM_S2_BASE, operand3:MLKEM_AS0_BASE}; + MLKEM_KG_S + 28: data_o_rom <= '{opcode:ABR_UOP_MLKEM_REJS_PWMA, imm:'h0103, length:'d34, operand1:MLKEM_RHO_ID, operand2:MLKEM_S3_BASE, operand3:MLKEM_AS0_BASE}; + MLKEM_KG_S + 29: data_o_rom <= '{opcode:ABR_UOP_MLKEM_PWA, imm:'h0000, length:'d00, operand1:MLKEM_AS0_BASE, operand2:MLKEM_E1_BASE, operand3:MLKEM_T1_BASE}; + MLKEM_KG_S + 30: data_o_rom <= '{opcode:ABR_UOP_MLKEM_REJS_PWM , imm:'h0200, length:'d34, operand1:MLKEM_RHO_ID, operand2:MLKEM_S0_BASE, operand3:MLKEM_AS0_BASE}; + MLKEM_KG_S + 31: data_o_rom <= '{opcode:ABR_UOP_MLKEM_REJS_PWMA, imm:'h0201, length:'d34, operand1:MLKEM_RHO_ID, operand2:MLKEM_S1_BASE, operand3:MLKEM_AS0_BASE}; + MLKEM_KG_S + 32: data_o_rom <= '{opcode:ABR_UOP_MLKEM_REJS_PWMA, imm:'h0202, length:'d34, operand1:MLKEM_RHO_ID, operand2:MLKEM_S2_BASE, operand3:MLKEM_AS0_BASE}; + MLKEM_KG_S + 33: data_o_rom <= '{opcode:ABR_UOP_MLKEM_REJS_PWMA, imm:'h0203, length:'d34, operand1:MLKEM_RHO_ID, operand2:MLKEM_S3_BASE, operand3:MLKEM_AS0_BASE}; + MLKEM_KG_S + 34: data_o_rom <= '{opcode:ABR_UOP_MLKEM_PWA, imm:'h0000, length:'d00, operand1:MLKEM_AS0_BASE, operand2:MLKEM_E2_BASE, operand3:MLKEM_T2_BASE}; + MLKEM_KG_S + 35: data_o_rom <= '{opcode:ABR_UOP_MLKEM_REJS_PWM , imm:'h0300, length:'d34, operand1:MLKEM_RHO_ID, operand2:MLKEM_S0_BASE, operand3:MLKEM_AS0_BASE}; + MLKEM_KG_S + 36: data_o_rom <= '{opcode:ABR_UOP_MLKEM_REJS_PWMA, imm:'h0301, length:'d34, operand1:MLKEM_RHO_ID, operand2:MLKEM_S1_BASE, operand3:MLKEM_AS0_BASE}; + MLKEM_KG_S + 37: data_o_rom <= '{opcode:ABR_UOP_MLKEM_REJS_PWMA, imm:'h0302, length:'d34, operand1:MLKEM_RHO_ID, operand2:MLKEM_S2_BASE, operand3:MLKEM_AS0_BASE}; + MLKEM_KG_S + 38: data_o_rom <= '{opcode:ABR_UOP_MLKEM_REJS_PWMA, imm:'h0303, length:'d34, operand1:MLKEM_RHO_ID, operand2:MLKEM_S3_BASE, operand3:MLKEM_AS0_BASE}; + MLKEM_KG_S + 39: data_o_rom <= '{opcode:ABR_UOP_MLKEM_PWA, imm:'h0000, length:'d00, operand1:MLKEM_AS0_BASE, operand2:MLKEM_E3_BASE, operand3:MLKEM_T3_BASE}; + MLKEM_KG_S + 40: data_o_rom <= '{opcode:ABR_UOP_COMPRESS, imm:'h0403, length:'d00, operand1:MLKEM_T0_BASE, operand2:ABR_NOP, operand3:MLKEM_DEST_EK_MEM_OFFSET}; + MLKEM_KG_S + 41: data_o_rom <= '{opcode:ABR_UOP_COMPRESS, imm:'h0403, length:'d00, operand1:MLKEM_S0_BASE, operand2:ABR_NOP, operand3:MLKEM_DEST_DK_MEM_OFFSET}; + MLKEM_KG_S + 42: data_o_rom <= '{opcode:ABR_UOP_SHA256, imm:'h0000, length:EK_NUM_BYTES, operand1:MLKEM_EK_REG_ID, operand2:ABR_NOP, operand3:MLKEM_DEST_TR_REG_ID}; + MLKEM_KG_E : data_o_rom <= '{opcode:ABR_UOP_NOP, imm:'h0000, length:'d00, operand1:ABR_NOP, operand2:ABR_NOP, operand3:ABR_NOP}; + //MLKEM Decaps + //rnd_seed=Keccak(entropy||counter) + MLKEM_DECAPS_S + 0 : data_o_rom <= '{opcode:ABR_UOP_LD_SHAKE256, imm:'h0000, length:'d64, operand1:ABR_ENTROPY_ID, operand2:ABR_NOP, operand3:ABR_NOP}; + MLKEM_DECAPS_S + 1 : data_o_rom <= '{opcode:ABR_UOP_SHAKE256, imm:'h0000, length:'d08, operand1:ABR_CNT_ID, operand2:ABR_NOP, operand3:ABR_DEST_LFSR_SEED_REG_ID}; + MLKEM_DECAPS_S + 2 : data_o_rom <= '{opcode:ABR_UOP_LFSR, imm:'h0000, length:'d00, operand1:ABR_NOP, operand2:ABR_NOP, operand3:ABR_NOP}; + MLKEM_DECAPS_S + 3 : data_o_rom <= '{opcode:ABR_UOP_SHA256, imm:'h0000, length:EK_NUM_BYTES, operand1:MLKEM_EK_REG_ID, operand2:ABR_NOP, operand3:MLKEM_DEST_TR_REG_ID}; + MLKEM_DECAPS_S + 4 : data_o_rom <= '{opcode:ABR_UOP_DECOMPRESS, imm:'h0403, length:'d00, operand1:MLKEM_SRC_DK_MEM_OFFSET, operand2:ABR_NOP, operand3:MLKEM_S0_BASE}; + MLKEM_DECAPS_S + 5 : data_o_rom <= '{opcode:ABR_UOP_DECOMPRESS, imm:'h0402, length:'d00, operand1:MLKEM_SRC_C1_MEM_OFFSET, operand2:ABR_NOP, operand3:MLKEM_U0_BASE}; + MLKEM_DECAPS_S + 6 : data_o_rom <= '{opcode:ABR_UOP_DECOMPRESS, imm:'h0101, length:'d00, operand1:MLKEM_SRC_C2_MEM_OFFSET, operand2:ABR_NOP, operand3:MLKEM_V_BASE}; + MLKEM_DECAPS_S + 7 : data_o_rom <= '{opcode:ABR_UOP_MLKEM_NTT, imm:'h0000, length:'d00, operand1:MLKEM_U0_BASE, operand2:ABR_NOP, operand3:MLKEM_UP0_BASE}; + MLKEM_DECAPS_S + 8 : data_o_rom <= '{opcode:ABR_UOP_MLKEM_NTT, imm:'h0000, length:'d00, operand1:MLKEM_U1_BASE, operand2:ABR_NOP, operand3:MLKEM_UP1_BASE}; + MLKEM_DECAPS_S + 9 : data_o_rom <= '{opcode:ABR_UOP_MLKEM_NTT, imm:'h0000, length:'d00, operand1:MLKEM_U2_BASE, operand2:ABR_NOP, operand3:MLKEM_UP2_BASE}; + MLKEM_DECAPS_S + 10 : data_o_rom <= '{opcode:ABR_UOP_MLKEM_NTT, imm:'h0000, length:'d00, operand1:MLKEM_U3_BASE, operand2:ABR_NOP, operand3:MLKEM_UP3_BASE}; + MLKEM_DECAPS_S + 11: data_o_rom <= '{opcode:ABR_UOP_MLKEM_MASKED_PWM, imm:'h0000, length:'d00, operand1:MLKEM_S0_BASE, operand2:MLKEM_UP0_BASE, operand3:MLKEM_SU_MASKED_BASE}; + MLKEM_DECAPS_S + 12: data_o_rom <= '{opcode:ABR_UOP_MLKEM_MASKED_PWMA, imm:'h0000, length:'d00, operand1:MLKEM_S1_BASE, operand2:MLKEM_UP1_BASE, operand3:MLKEM_SU_MASKED_BASE}; + MLKEM_DECAPS_S + 13: data_o_rom <= '{opcode:ABR_UOP_MLKEM_MASKED_PWMA, imm:'h0000, length:'d00, operand1:MLKEM_S2_BASE, operand2:MLKEM_UP2_BASE, operand3:MLKEM_SU_MASKED_BASE}; + MLKEM_DECAPS_S + 14: data_o_rom <= '{opcode:ABR_UOP_MLKEM_MASKED_PWMA, imm:'h0000, length:'d00, operand1:MLKEM_S3_BASE, operand2:MLKEM_UP3_BASE, operand3:MLKEM_SU_MASKED_BASE}; + MLKEM_DECAPS_S + 15: data_o_rom <= '{opcode:ABR_UOP_MLKEM_MASKED_INTT, imm:'h0000, length:'d00, operand1:MLKEM_SU_MASKED_BASE, operand2:ABR_NOP, operand3:MLKEM_SU_BASE}; + MLKEM_DECAPS_S + 16: data_o_rom <= '{opcode:ABR_UOP_MLKEM_PWS, imm:'h0000, length:'d00, operand1:MLKEM_SU_BASE, operand2:MLKEM_V_BASE, operand3:MLKEM_V_BASE}; + MLKEM_DECAPS_S + 17: data_o_rom <= '{opcode:ABR_UOP_COMPRESS, imm:'h0100, length:'d00, operand1:MLKEM_V_BASE, operand2:ABR_NOP, operand3:MLKEM_DEST_MSG_MEM_OFFSET}; + //MLKEM Encaps + //rnd_seed=Keccak(entropy||counter) + MLKEM_ENCAPS_S + 0 : data_o_rom <= '{opcode:ABR_UOP_LD_SHAKE256, imm:'h0000, length:'d64, operand1:ABR_ENTROPY_ID, operand2:ABR_NOP, operand3:ABR_NOP}; + MLKEM_ENCAPS_S + 1 : data_o_rom <= '{opcode:ABR_UOP_SHAKE256, imm:'h0000, length:'d08, operand1:ABR_CNT_ID, operand2:ABR_NOP, operand3:ABR_DEST_LFSR_SEED_REG_ID}; + MLKEM_ENCAPS_S + 2 : data_o_rom <= '{opcode:ABR_UOP_LFSR, imm:'h0000, length:'d00, operand1:ABR_NOP, operand2:ABR_NOP, operand3:ABR_NOP}; + MLKEM_ENCAPS_S + 3 : data_o_rom <= '{opcode:ABR_UOP_DECOMPRESS, imm:'h0403, length:'d00, operand1:MLKEM_SRC_EK_MEM_OFFSET, operand2:ABR_NOP, operand3:MLKEM_T0_BASE}; + MLKEM_ENCAPS_S + 4 : data_o_rom <= '{opcode:ABR_UOP_COMPRESS, imm:'h0413, length:'d00, operand1:MLKEM_T0_BASE, operand2:ABR_NOP, operand3:MLKEM_DEST_EK_MEM_OFFSET}; + MLKEM_ENCAPS_S + 5 : data_o_rom <= '{opcode:ABR_UOP_SHA256, imm:'h0000, length:EK_NUM_BYTES, operand1:MLKEM_EK_REG_ID, operand2:ABR_NOP, operand3:MLKEM_DEST_TR_REG_ID}; + MLKEM_ENCAPS_S + 6 : data_o_rom <= '{opcode:ABR_UOP_LD_SHA512, imm:'h0000, length:'d32, operand1:MLKEM_MSG_ID, operand2:ABR_NOP, operand3:ABR_NOP}; + MLKEM_ENCAPS_S + 7 : data_o_rom <= '{opcode:ABR_UOP_SHA512, imm:'h0000, length:'d32, operand1:MLKEM_TR_ID, operand2:ABR_NOP, operand3:MLKEM_DEST_K_R_REG_ID}; + MLKEM_ENCAPS_S + 8 : data_o_rom <= '{opcode:ABR_UOP_CBD, imm:'h0000, length:'d33, operand1:MLKEM_R_ID, operand2:ABR_NOP, operand3:MLKEM_Y0_BASE}; + MLKEM_ENCAPS_S + 9 : data_o_rom <= '{opcode:ABR_UOP_CBD, imm:'h0001, length:'d33, operand1:MLKEM_R_ID, operand2:ABR_NOP, operand3:MLKEM_Y1_BASE}; + MLKEM_ENCAPS_S + 10: data_o_rom <= '{opcode:ABR_UOP_CBD, imm:'h0002, length:'d33, operand1:MLKEM_R_ID, operand2:ABR_NOP, operand3:MLKEM_Y2_BASE}; + MLKEM_ENCAPS_S + 11: data_o_rom <= '{opcode:ABR_UOP_CBD, imm:'h0003, length:'d33, operand1:MLKEM_R_ID, operand2:ABR_NOP, operand3:MLKEM_Y3_BASE}; + MLKEM_ENCAPS_S + 12: data_o_rom <= '{opcode:ABR_UOP_CBD, imm:'h0004, length:'d33, operand1:MLKEM_R_ID, operand2:ABR_NOP, operand3:MLKEM_E0_BASE}; + MLKEM_ENCAPS_S + 13: data_o_rom <= '{opcode:ABR_UOP_CBD, imm:'h0005, length:'d33, operand1:MLKEM_R_ID, operand2:ABR_NOP, operand3:MLKEM_E1_BASE}; + MLKEM_ENCAPS_S + 14: data_o_rom <= '{opcode:ABR_UOP_CBD, imm:'h0006, length:'d33, operand1:MLKEM_R_ID, operand2:ABR_NOP, operand3:MLKEM_E2_BASE}; + MLKEM_ENCAPS_S + 15: data_o_rom <= '{opcode:ABR_UOP_CBD, imm:'h0007, length:'d33, operand1:MLKEM_R_ID, operand2:ABR_NOP, operand3:MLKEM_E3_BASE}; + MLKEM_ENCAPS_S + 16: data_o_rom <= '{opcode:ABR_UOP_CBD, imm:'h0008, length:'d33, operand1:MLKEM_R_ID, operand2:ABR_NOP, operand3:MLKEM_E_2_BASE}; + MLKEM_ENCAPS_S + 17: data_o_rom <= '{opcode:ABR_UOP_MLKEM_NTT, imm:'h0000, length:'d00, operand1:MLKEM_Y0_BASE, operand2:ABR_NOP, operand3:MLKEM_Y0_BASE}; + MLKEM_ENCAPS_S + 18: data_o_rom <= '{opcode:ABR_UOP_MLKEM_NTT, imm:'h0000, length:'d00, operand1:MLKEM_Y1_BASE, operand2:ABR_NOP, operand3:MLKEM_Y1_BASE}; + MLKEM_ENCAPS_S + 19: data_o_rom <= '{opcode:ABR_UOP_MLKEM_NTT, imm:'h0000, length:'d00, operand1:MLKEM_Y2_BASE, operand2:ABR_NOP, operand3:MLKEM_Y2_BASE}; + MLKEM_ENCAPS_S + 20: data_o_rom <= '{opcode:ABR_UOP_MLKEM_NTT, imm:'h0000, length:'d00, operand1:MLKEM_Y3_BASE, operand2:ABR_NOP, operand3:MLKEM_Y3_BASE}; + MLKEM_ENCAPS_S + 21: data_o_rom <= '{opcode:ABR_UOP_MLKEM_MASKED_REJS_PWM, imm:'h0000, length:'d34, operand1:MLKEM_RHO_ID, operand2:MLKEM_Y0_BASE, operand3:MLKEM_AY0_BASE}; + MLKEM_ENCAPS_S + 22: data_o_rom <= '{opcode:ABR_UOP_MLKEM_MASKED_REJS_PWMA, imm:'h0100, length:'d34, operand1:MLKEM_RHO_ID, operand2:MLKEM_Y1_BASE, operand3:MLKEM_AY0_BASE}; + MLKEM_ENCAPS_S + 23: data_o_rom <= '{opcode:ABR_UOP_MLKEM_MASKED_REJS_PWMA, imm:'h0200, length:'d34, operand1:MLKEM_RHO_ID, operand2:MLKEM_Y2_BASE, operand3:MLKEM_AY0_BASE}; + MLKEM_ENCAPS_S + 24: data_o_rom <= '{opcode:ABR_UOP_MLKEM_MASKED_REJS_PWMA, imm:'h0300, length:'d34, operand1:MLKEM_RHO_ID, operand2:MLKEM_Y3_BASE, operand3:MLKEM_AY0_BASE}; + MLKEM_ENCAPS_S + 25: data_o_rom <= '{opcode:ABR_UOP_MLKEM_MASKED_INTT, imm:'h0000, length:'d00, operand1:MLKEM_AY0_BASE, operand2:ABR_NOP, operand3:MLKEM_AY0_BASE}; + MLKEM_ENCAPS_S + 26: data_o_rom <= '{opcode:ABR_UOP_MLKEM_PWA, imm:'h0000, length:'d00, operand1:MLKEM_AY0_BASE, operand2:MLKEM_E0_BASE, operand3:MLKEM_U0_BASE}; + MLKEM_ENCAPS_S + 27: data_o_rom <= '{opcode:ABR_UOP_MLKEM_MASKED_REJS_PWM, imm:'h0001, length:'d34, operand1:MLKEM_RHO_ID, operand2:MLKEM_Y0_BASE, operand3:MLKEM_AY0_BASE}; + MLKEM_ENCAPS_S + 28: data_o_rom <= '{opcode:ABR_UOP_MLKEM_MASKED_REJS_PWMA, imm:'h0101, length:'d34, operand1:MLKEM_RHO_ID, operand2:MLKEM_Y1_BASE, operand3:MLKEM_AY0_BASE}; + MLKEM_ENCAPS_S + 29: data_o_rom <= '{opcode:ABR_UOP_MLKEM_MASKED_REJS_PWMA, imm:'h0201, length:'d34, operand1:MLKEM_RHO_ID, operand2:MLKEM_Y2_BASE, operand3:MLKEM_AY0_BASE}; + MLKEM_ENCAPS_S + 30: data_o_rom <= '{opcode:ABR_UOP_MLKEM_MASKED_REJS_PWMA, imm:'h0301, length:'d34, operand1:MLKEM_RHO_ID, operand2:MLKEM_Y3_BASE, operand3:MLKEM_AY0_BASE}; + MLKEM_ENCAPS_S + 31: data_o_rom <= '{opcode:ABR_UOP_MLKEM_MASKED_INTT, imm:'h0000, length:'d00, operand1:MLKEM_AY0_BASE, operand2:ABR_NOP, operand3:MLKEM_AY0_BASE}; + MLKEM_ENCAPS_S + 32: data_o_rom <= '{opcode:ABR_UOP_MLKEM_PWA, imm:'h0000, length:'d00, operand1:MLKEM_AY0_BASE, operand2:MLKEM_E1_BASE, operand3:MLKEM_U1_BASE}; + MLKEM_ENCAPS_S + 33: data_o_rom <= '{opcode:ABR_UOP_MLKEM_MASKED_REJS_PWM, imm:'h0002, length:'d34, operand1:MLKEM_RHO_ID, operand2:MLKEM_Y0_BASE, operand3:MLKEM_AY0_BASE}; + MLKEM_ENCAPS_S + 34: data_o_rom <= '{opcode:ABR_UOP_MLKEM_MASKED_REJS_PWMA, imm:'h0102, length:'d34, operand1:MLKEM_RHO_ID, operand2:MLKEM_Y1_BASE, operand3:MLKEM_AY0_BASE}; + MLKEM_ENCAPS_S + 35: data_o_rom <= '{opcode:ABR_UOP_MLKEM_MASKED_REJS_PWMA, imm:'h0202, length:'d34, operand1:MLKEM_RHO_ID, operand2:MLKEM_Y2_BASE, operand3:MLKEM_AY0_BASE}; + MLKEM_ENCAPS_S + 36: data_o_rom <= '{opcode:ABR_UOP_MLKEM_MASKED_REJS_PWMA, imm:'h0302, length:'d34, operand1:MLKEM_RHO_ID, operand2:MLKEM_Y3_BASE, operand3:MLKEM_AY0_BASE}; + MLKEM_ENCAPS_S + 37: data_o_rom <= '{opcode:ABR_UOP_MLKEM_MASKED_INTT, imm:'h0000, length:'d00, operand1:MLKEM_AY0_BASE, operand2:ABR_NOP, operand3:MLKEM_AY0_BASE}; + MLKEM_ENCAPS_S + 38: data_o_rom <= '{opcode:ABR_UOP_MLKEM_PWA, imm:'h0000, length:'d00, operand1:MLKEM_AY0_BASE, operand2:MLKEM_E2_BASE, operand3:MLKEM_U2_BASE}; + MLKEM_ENCAPS_S + 39: data_o_rom <= '{opcode:ABR_UOP_MLKEM_MASKED_REJS_PWM, imm:'h0003, length:'d34, operand1:MLKEM_RHO_ID, operand2:MLKEM_Y0_BASE, operand3:MLKEM_AY0_BASE}; + MLKEM_ENCAPS_S + 40: data_o_rom <= '{opcode:ABR_UOP_MLKEM_MASKED_REJS_PWMA, imm:'h0103, length:'d34, operand1:MLKEM_RHO_ID, operand2:MLKEM_Y1_BASE, operand3:MLKEM_AY0_BASE}; + MLKEM_ENCAPS_S + 41: data_o_rom <= '{opcode:ABR_UOP_MLKEM_MASKED_REJS_PWMA, imm:'h0203, length:'d34, operand1:MLKEM_RHO_ID, operand2:MLKEM_Y2_BASE, operand3:MLKEM_AY0_BASE}; + MLKEM_ENCAPS_S + 42: data_o_rom <= '{opcode:ABR_UOP_MLKEM_MASKED_REJS_PWMA, imm:'h0303, length:'d34, operand1:MLKEM_RHO_ID, operand2:MLKEM_Y3_BASE, operand3:MLKEM_AY0_BASE}; + MLKEM_ENCAPS_S + 43: data_o_rom <= '{opcode:ABR_UOP_MLKEM_MASKED_INTT, imm:'h0000, length:'d00, operand1:MLKEM_AY0_BASE, operand2:ABR_NOP, operand3:MLKEM_AY0_BASE}; + MLKEM_ENCAPS_S + 44: data_o_rom <= '{opcode:ABR_UOP_MLKEM_PWA, imm:'h0000, length:'d00, operand1:MLKEM_AY0_BASE, operand2:MLKEM_E3_BASE, operand3:MLKEM_U3_BASE}; + MLKEM_ENCAPS_S + 45: data_o_rom <= '{opcode:ABR_UOP_MLKEM_MASKED_PWM, imm:'h0000, length:'d00, operand1:MLKEM_T0_BASE, operand2:MLKEM_Y0_BASE, operand3:MLKEM_TY_MASKED_BASE}; + MLKEM_ENCAPS_S + 46: data_o_rom <= '{opcode:ABR_UOP_MLKEM_MASKED_PWMA, imm:'h0000, length:'d00, operand1:MLKEM_T1_BASE, operand2:MLKEM_Y1_BASE, operand3:MLKEM_TY_MASKED_BASE}; + MLKEM_ENCAPS_S + 47: data_o_rom <= '{opcode:ABR_UOP_MLKEM_MASKED_PWMA, imm:'h0000, length:'d00, operand1:MLKEM_T2_BASE, operand2:MLKEM_Y2_BASE, operand3:MLKEM_TY_MASKED_BASE}; + MLKEM_ENCAPS_S + 48: data_o_rom <= '{opcode:ABR_UOP_MLKEM_MASKED_PWMA, imm:'h0000, length:'d00, operand1:MLKEM_T3_BASE, operand2:MLKEM_Y3_BASE, operand3:MLKEM_TY_MASKED_BASE}; + MLKEM_ENCAPS_S + 49: data_o_rom <= '{opcode:ABR_UOP_MLKEM_MASKED_INTT, imm:'h0000, length:'d00, operand1:MLKEM_TY_MASKED_BASE, operand2:ABR_NOP, operand3:MLKEM_V_BASE}; + MLKEM_ENCAPS_S + 50: data_o_rom <= '{opcode:ABR_UOP_DECOMPRESS, imm:'h0100, length:'d00, operand1:MLKEM_SRC_MSG_MEM_OFFSET, operand2:ABR_NOP, operand3:MLKEM_MU_BASE}; + MLKEM_ENCAPS_S + 51: data_o_rom <= '{opcode:ABR_UOP_MLKEM_PWA, imm:'h0000, length:'d00, operand1:MLKEM_MU_BASE, operand2:MLKEM_E_2_BASE, operand3:MLKEM_E_2_BASE}; + MLKEM_ENCAPS_S + 52: data_o_rom <= '{opcode:ABR_UOP_MLKEM_PWA, imm:'h0000, length:'d00, operand1:MLKEM_V_BASE, operand2:MLKEM_E_2_BASE, operand3:MLKEM_V_BASE}; + MLKEM_ENCAPS_S + 53: data_o_rom <= '{opcode:ABR_UOP_COMPRESS, imm:'h0422, length:'d00, operand1:MLKEM_U0_BASE, operand2:ABR_NOP, operand3:MLKEM_DEST_C1_MEM_OFFSET}; + MLKEM_ENCAPS_S + 54: data_o_rom <= '{opcode:ABR_UOP_COMPRESS, imm:'h0121, length:'d00, operand1:MLKEM_V_BASE, operand2:ABR_NOP, operand3:MLKEM_DEST_C2_MEM_OFFSET}; + MLKEM_ENCAPS_E + 0 : data_o_rom <= '{opcode:ABR_UOP_NOP, imm:'h0000, length:'d00, operand1:ABR_NOP, operand2:ABR_NOP, operand3:ABR_NOP}; + MLKEM_DECAPS_CHK + 0: data_o_rom <= '{opcode:ABR_UOP_LD_SHAKE256, imm:'h0000, length:'d32, operand1:MLKEM_SEED_Z_ID, operand2:ABR_NOP, operand3:ABR_NOP}; + MLKEM_DECAPS_CHK + 1: data_o_rom <= '{opcode:ABR_UOP_SHAKE256, imm:'h0000, length:CT_NUM_BYTES, operand1:MLKEM_CIPHERTEXT_ID, operand2:ABR_NOP, operand3:MLKEM_DEST_K_REG_ID}; + MLKEM_DECAPS_E + 0 : data_o_rom <= '{opcode:ABR_UOP_NOP, imm:'h0000, length:'d00, operand1:ABR_NOP, operand2:ABR_NOP, operand3:ABR_NOP}; + + default : data_o_rom <= '{opcode: ABR_UOP_NOP, imm:'h0000, length:'d00, operand1:ABR_NOP, operand2:ABR_NOP, operand3:ABR_NOP}; + endcase + end + else begin + data_o_rom <= '{opcode: ABR_UOP_NOP, imm:'h0000, length:'d00, operand1:ABR_NOP, operand2:ABR_NOP, operand3:ABR_NOP}; + end +end + +endmodule diff --git a/designs/Caliptra/src/adams-bridge/abr_sha3.sv b/designs/Caliptra/src/adams-bridge/abr_sha3.sv new file mode 100644 index 0000000..505652e --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/abr_sha3.sv @@ -0,0 +1,466 @@ +// Copyright lowRISC contributors. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// SHA3 core is a fully functional SHA3/SHAKE/cSHAKE hashing module. +// +// It instantiates a keccak_round with 1600 bits of the state. + +`include "abr_sva.svh" +`include "abr_prim_assert.sv" + +module abr_sha3 + import abr_sha3_pkg::*; +#( + // Number of Keccak Rounds performed each clock cycle + parameter int RoundsPerClock = 1, + // Enable Masked Keccak if 1 + parameter bit EnMasking = 0, + // derived parameter + localparam int Share = (EnMasking) ? 2 : 1 +) ( + input logic clk_i, + input logic rst_b, + input logic zeroize, + // MSG interface + input logic msg_start_i, + input logic msg_valid_i, + input logic [MsgWidth-1:0] msg_data_i [Share], + input logic [MsgStrbW-1:0] msg_strb_i, // one strobe for shares + output logic msg_ready_o, + + // Entropy interface + input logic rand_valid_i, + input logic rand_early_i, + input logic [StateW/2-1:0] rand_data_i, + input logic rand_aux_i, + output logic rand_consumed_o, + + // N, S: Used in cSHAKE mode only + input logic [NSRegisterSize*8-1:0] ns_data_i, // See abr_sha3_pkg for details + + // configurations + input sha3_mode_e mode_i, // see abr_sha3pad for details + input keccak_strength_e strength_i, // see abr_sha3pad for details + + // controls + input logic start_i, // see abr_sha3pad for details + input logic process_i, // see abr_sha3pad for details + + // run_i is a pulse signal to trigger the keccak_round manually by SW. + // It is used to run additional keccak_f after sponge absorbing is completed. + // See `keccak_run` signal + input logic run_i, + + output abr_prim_mubi_pkg::mubi4_t absorbed_o, + output logic squeezing_o, + + // Indicate of one block processed. KMAC main state tracks the progression + // based on this signal. + output logic block_processed_o, + + output sha3_st_e sha3_fsm_o, + + // digest output + // This value is valid only after all absorbing process is completed. + // In invalid state, the output `state` will be zero to prevent information + // leakage. + output logic state_valid_o, + input logic state_valid_hold_i, + output logic [StateW-1:0] state_o [Share], + + // error_o value is pushed to Error FIFO at KMAC/SHA3 top and reported to SW + output err_t error_o, + + // sparse_fsm_alert + output logic sparse_fsm_error_o, + + // counter error + output logic count_error_o, + + // error on rst_storage in Keccak + output logic keccak_storage_rst_error_o + +); + ///////////////// + // Definitions // + ///////////////// + + typedef enum logic[2:0] { + MuxGuard = 3'b 010, + MuxRelease = 3'b 101 + } state_mux_sel_e; + + ///////////// + // Signals // + ///////////// + + // State --> Digest + // State is exposed to the outside if the hashing process is completed. + logic state_valid; + logic [StateW-1:0] state [Share]; + logic [StateW-1:0] state_guarded [Share]; + + // State --> digest mux select signal + state_mux_sel_e mux_sel; + + // absorbed is a pulse signal that indicates sponge absorbing is done. + // After this, sha3 core allows software to manually run until squeezing + // is completed + abr_prim_mubi_pkg::mubi4_t absorbed; + + // `squeezing` is a status indicator that SHA3 core is in sponge squeezing + // stage. In this stage, the state output is valid, and software can manually + // trigger keccak_round logic to get more digest outputs in case the output + // length is bigger than the block limit. + logic squeezing; + + // If process_i is received, the logic initiates the final absorbing process. + // While absorbing, the processing inticator is turned on. This signal is used + // to check if multiple process_i is received or not. + logic processing; + + // FSM variable + sha3_st_sparse_e st, st_d; + + // Keccak control signal (filtered by State Machine) + logic keccak_start, keccak_process; + abr_prim_mubi_pkg::mubi4_t keccak_done; + + // alert signals + logic round_count_error, msg_count_error; + assign count_error_o = round_count_error | msg_count_error; + + logic sha3_state_error; + logic keccak_round_state_error; + logic sha3pad_state_error; + + assign sparse_fsm_error_o = sha3_state_error | keccak_round_state_error | sha3pad_state_error; + + // Keccak rst_storage is asserted unexpectedly + logic keccak_storage_rst_error; + assign keccak_storage_rst_error_o = keccak_storage_rst_error; + + ///////////////// + // Connections // + ///////////////// + + logic [abr_sha3_pkg::StateW-1:0] keccak_data [Share]; + logic keccak_ready; + + // Keccak round run signal can be controlled by sha3pad and also by software + // after all message feeding is done. it is mainly used for sponge squeezing + // operation after absorbing is completed when output length is longer than + // the block size. + logic keccak_run, sha3pad_keccak_run, sw_keccak_run; + logic keccak_complete; + + assign keccak_run = sha3pad_keccak_run | sw_keccak_run; + + // Absorb pulse output : used to generate interrupts + // Latch absorbed signal as kmac_keymgr asserts `CmdDone` when it sees + // `absorbed` signal. When this signal goes out, the state is still in + // `StAbsorb`. Next state is `StSqueeze`. + always_ff @(posedge clk_i or negedge rst_b) begin + if (!rst_b) absorbed_o <= abr_prim_mubi_pkg::MuBi4False; + else if (zeroize) absorbed_o <= abr_prim_mubi_pkg::MuBi4False; + else absorbed_o <= absorbed; + end + + // Squeezing output + assign squeezing_o = squeezing; + + // processing + always_ff @(posedge clk_i or negedge rst_b) begin + if (!rst_b) processing <= 1'b 0; + else if (zeroize) processing <= 1'b 0; + else if (process_i) processing <= 1'b 1; + else if (abr_prim_mubi_pkg::mubi4_test_true_strict(absorbed)) begin + processing <= 1'b 0; + end + end + + always_ff @(posedge clk_i or negedge rst_b) begin + if (!rst_b) state_valid <= 1'b0; //reset + else if (zeroize) state_valid <= 1'b0; //zeroize + else if ((st_d == StSqueeze_sparse) & (st != StSqueeze_sparse)) state_valid <= 1'b1; //assert on transition to squeeze + else if (state_valid_hold_i) state_valid <= state_valid; //hold current value + else state_valid <= 1'b0; //de-assert + end + + assign block_processed_o = keccak_complete; + + // State connection + assign state_valid_o = state_valid; + assign state_o = state_guarded; + + assign sha3_fsm_o = sparse2logic(st); + + + + /////////////////// + // State Machine // + /////////////////// + + // State Register + `ABR_PRIM_FLOP_SPARSE_FSM(u_state_regs, st_d, st, sha3_st_sparse_e, StIdle_sparse) + + + // Next State and Output Logic + // Mainly the FSM controls the input signal access + // StIdle: only start_i signal is allowed + // StAbsorb: only process_i signal is allowed + // StSqueeze: only run_i is allowed + + always_comb begin + st_d = st; + + // default output values + keccak_start = 1'b 0; + keccak_process = 1'b 0; + sw_keccak_run = 1'b 0; + keccak_done = abr_prim_mubi_pkg::MuBi4False; + + squeezing = 1'b 0; + + sha3_state_error = 1'b 0; + + unique case (st) + StIdle_sparse: begin + if (start_i) begin + st_d = StAbsorb_sparse; + + keccak_start = 1'b 1; + end else begin + st_d = StIdle_sparse; + end + end + + StAbsorb_sparse: begin + if (process_i && !processing) begin + st_d = StAbsorb_sparse; + + keccak_process = 1'b 1; + end else if (abr_prim_mubi_pkg::mubi4_test_true_strict(absorbed)) begin + st_d = StSqueeze_sparse; + end else begin + st_d = StAbsorb_sparse; + end + end + + StSqueeze_sparse: begin + + squeezing = 1'b 1; + + if (run_i) begin + st_d = StManualRun_sparse; + + sw_keccak_run = 1'b 1; + end else begin + st_d = StSqueeze_sparse; + end + end + + StManualRun_sparse: begin + squeezing = 1'b 1; + if (keccak_complete) begin + st_d = StSqueeze_sparse; + end else begin + st_d = StManualRun_sparse; + end + end + + StTerminalError_sparse: begin + //this state is terminal + st_d = StTerminalError_sparse; + sha3_state_error = 1'b 1; + end + + default: begin + st_d = StTerminalError_sparse; + sha3_state_error = 1'b 1; + end + endcase + + if (zeroize) st_d = StIdle_sparse; + + end + + ////////////// + // Datapath // + ////////////// + + // State --> Digest output + always_comb begin + if (state_valid) mux_sel = MuxRelease; // Expose state to register interfac + else mux_sel = MuxGuard ; + end + + always_comb begin : state_guarded_mux + unique case (mux_sel) + MuxGuard: state_guarded = '{default: '0}; + MuxRelease: state_guarded = state; + default: state_guarded = '{default: '0}; // a valid, safe output + endcase + end + + + // Error Detecting + // ErrSha3SwControl: + // info[ 0]: start_i set + // info[ 1]: process_i set + // info[ 2]: run_i set + // - Sw set process_i, run_i, without start_i + + always_comb begin + error_o = '{valid: 1'b0, code: ErrNone, info: '0}; + + unique case (st) + StIdle_sparse: begin + if (process_i || run_i) begin + error_o = '{ + valid: 1'b 1, + code: ErrSha3SwControl, + info: 24'({run_i, process_i, start_i}) + }; + end + end + + StAbsorb_sparse: begin + if (start_i || run_i || (process_i && processing)) begin + error_o = '{ + valid: 1'b 1, + code: ErrSha3SwControl, + info: 24'({run_i, process_i, start_i}) + }; + end + end + + StSqueeze_sparse: begin + if (start_i || process_i) begin + error_o = '{ + valid: 1'b 1, + code: ErrSha3SwControl, + info: 24'({run_i, process_i, start_i}) + }; + end + end + + StManualRun_sparse: begin + if (start_i || process_i || run_i) begin + error_o = '{ + valid: 1'b 1, + code: ErrSha3SwControl, + info: 24'({run_i, process_i, start_i}) + }; + end + end + + default: begin + end + endcase + end + /////////////// + // Instances // + /////////////// + + // SHA3 pad logic + abr_sha3pad #( + .EnMasking (EnMasking) + ) u_pad ( + .clk_i, + .rst_b, + .zeroize, + + // MSG_FIFO (or from KMAC core) + .msg_valid_i, + .msg_data_i, // [Share] + .msg_strb_i, + .msg_ready_o, + + // Encoded N, S + .ns_data_i, + + // output to keccak_round: message path + .keccak_data_o (keccak_data ), // [Share] + .keccak_ready_i (keccak_ready & ~squeezing), + + .keccak_run_o (sha3pad_keccak_run), + .keccak_complete_i (keccak_complete ), + + // configurations + .mode_i, + .strength_i, + + // controls + .start_i (msg_start_i), + .process_i (keccak_process), + + // output + .absorbed_o (absorbed), + .sparse_fsm_error_o (sha3pad_state_error), + .msg_count_error_o (msg_count_error) + ); + + // Keccak round logic + abr_keccak_round #( + .Width (abr_sha3_pkg::StateW), + .RoundsPerClock(RoundsPerClock), + .EnMasking (EnMasking) + ) u_keccak ( + .clk_i, + .rst_b, + .zeroize, + + .data_i (keccak_data ), + .ready_o (keccak_ready), + + .rand_valid_i, + .rand_early_i, + .rand_data_i, + .rand_aux_i, + .rand_consumed_o, + + .run_i (keccak_run ), + .squeezing_i(squeezing ), + .complete_o (keccak_complete), + + .state_o (state), + + .sparse_fsm_error_o (keccak_round_state_error), + .round_count_error_o (round_count_error), + .rst_storage_error_o (keccak_storage_rst_error), + + .clear_i (keccak_done) + ); + + //////////////// + // Assertions // + //////////////// + + // Unknown check for case statement + `ABR_ASSERT(MuxSelKnown_A, mux_sel inside {MuxGuard, MuxRelease}) + `ABR_ASSERT(FsmKnown_A, st inside {StIdle_sparse, StAbsorb_sparse, StSqueeze_sparse, + StManualRun_sparse, StTerminalError_sparse}) + + // `state` shall be 0 in invalid + if (EnMasking) begin: gen_chk_digest_masked + `ABR_ASSERT(StateZeroInvalid_A, !state_valid_o |-> ((|state_o[0]) | (|state_o[1])) == 1'b 0) + end else begin : gen_chk_digest_unmasked + `ABR_ASSERT(StateZeroInvalid_A, !state_valid_o |-> (|state_o[0]) == 1'b 0) + end + + // `state_valid_o` asserts only in between the completion and done + //`ABR_ASSERT(StateValidPeriod_A, state_valid_o |-> ) + + // skip the msg interface assertions as they are in abr_sha3pad.sv + + // Software run signal happens in Squeezing stage + `ABR_ASSERT(SwRunInSqueezing_a, run_i |-> error_o.valid || (st == StSqueeze_sparse)) + + // If control received but not propagated into submodules, it is error condition + `ABR_ASSERT(ErrDetection_A, error_o.valid + |-> {start_i, process_i, run_i} + != {keccak_start, keccak_process, sw_keccak_run}) + +endmodule diff --git a/designs/Caliptra/src/adams-bridge/abr_sha3_pkg.sv b/designs/Caliptra/src/adams-bridge/abr_sha3_pkg.sv new file mode 100644 index 0000000..837b9e4 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/abr_sha3_pkg.sv @@ -0,0 +1,213 @@ +// Copyright lowRISC contributors. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// abr_sha3_pkg + +package abr_sha3_pkg; + + // StateW represents the width of Keccak state variable. + // As Sha3 assume the state value as 1600, this shouldn't be modified. + // Note that keccak_round is flexible. It can have any values defined in SHA3 + // specification. But sha3pad logic assumes the value as 1600. + parameter int StateW = 1600; + + // Function Name (N) and Customzation String (S) shall be + // smaller than 2**256 bits and integer divisiable by 8. + parameter int FnWidth = 32; // up to 32bit Function Name + parameter int CsWidth = 256; // up to 256bit Customization Input + + // Calculate left_encode(len( X )) bit size. + // Assume the enc_8(n) is always 1 (up to 255 byte of len(S) size) + // e.g) 248bit --> two bytes , 256bit --> three bytes + // round8bit(clog2(X+1))/8 + + parameter int MaxFnEncodeSize = ($clog2(FnWidth+1) + 8 - 1) / 8 + 1; + parameter int MaxCsEncodeSize = ($clog2(CsWidth+1) + 8 - 1) / 8 + 1; + + parameter int NSRegisterSizePre = FnWidth/8 + CsWidth/8 + + MaxFnEncodeSize + MaxCsEncodeSize; + // Round up to 32bit word base + parameter int NSRegisterSize = ((NSRegisterSizePre + 4 - 1 ) / 4) * 4; + + // Prefix represents bytepad(encode_string(N) || encode_string(S), 168 or 136) + // +2 represents left_encoding(168 or 136) which could be either: + // 10000000 || 00010101 // 168 + // 10000000 || 00010001 // 136 + parameter int PrefixSize = NSRegisterSize + 2; + + // index width for `N` and `S` + parameter int PrefixIndexW = $clog2(PrefixSize/64); + + // Datapath width in KMAC, this also affects the output of MSG_FIFO + // This is assumed as 64 in KMAC design. If this value is changed, some parts + // of the KMAC design need to be changed. + // + // 1. keccak_round logic datapath. Keccak round logic assumes MsgWidth + // divides 1600 keccak state `Width`. Choose the value accordingly. + // 2. sha3pad module has fixed width mux for funcpad logic. If MsgWidth is + // changed, the logic also need to be revised. + // 3. kmac core logic also has fixed size mux for appeding output length. + // Revise the case statement to fit into revised MsgWidth value. + parameter int MsgWidth = 64; + parameter int MsgStrbW = MsgWidth / 8; + + // Keccak module supports SHA3, SHAKE, cSHAKE function. + // This mode determines if the module uses encoded N and S or not. + // Also it chooses the padding value. + // + // mode | little-endian + // -------|---------------- + // Sha3 | 2'b 10 + // Shake | 4'b 1111 + // CShake | 2'b 00 + // + // Please remind that if input strings N and S are empty, SW shall + // choose SHAKE even for cSHAKE operation. + typedef enum logic[1:0] { + Sha3 = 2'b 00, + Shake = 2'b 10, + CShake = 2'b 11 + } sha3_mode_e; + + // keccak_strength_e determines the security strength against collision attack + // This value decides the _rate_ and _capacity_ of the keccak states. + // It affects the sha3pad module too. the padding module implements + // `bytepad(X,168)` for L128, `bytepad(X,136)` for L256 in cSHAKE + typedef enum logic [2:0] { + L128 = 3'b 000, // rate: 1344 bit / capacity: 256 bit Keccak[ 256](, 128) + L224 = 3'b 001, // rate: 1152 bit / capacity: 448 bit Keccak[ 448](, 224) + L256 = 3'b 010, // rate: 1088 bit / capacity: 512 bit Keccak[ 512](, 256) + L384 = 3'b 011, // rate: 832 bit / capacity: 768 bit Keccak[ 768](, 384) + L512 = 3'b 100 // rate: 576 bit / capacity: 1024 bit Keccak[1024](, 512) + } keccak_strength_e; + + parameter int unsigned KeccakRate [5] = '{ + (1344+MsgWidth-1)/MsgWidth, // 21 depth := (1600 - 128*2) + (1152+MsgWidth-1)/MsgWidth, // 18 depth := (1600 - 224*2) + (1088+MsgWidth-1)/MsgWidth, // 17 depth := (1600 - 256*2) + (832+MsgWidth-1)/MsgWidth, // 13 depth := (1600 - 384*2) + (576+MsgWidth-1)/MsgWidth // 9 depth := (1600 - 512*2) + }; + + parameter int unsigned MaxBlockSize = KeccakRate[0]; + + parameter int unsigned MsgEntries = (StateW+MsgWidth-1)/MsgWidth; + parameter int unsigned MsgAddrW = $clog2(MsgEntries); + + parameter int unsigned MsgCountW = $clog2(MsgEntries+1); + + // SHA3 core state. This state value is used in sha3core module + // and also in KMAC top module and the register interface for sw to track the + // sha3 status. + // Encoding generated with: + // $ ./util/design/sparse-fsm-encode.py -d 3 -m 7 -n 6 \ + // -s 4082450958 --language=sv + // + // Hamming distance histogram: + // + // 0: -- + // 1: -- + // 2: -- + // 3: |||||||||||||||||||| (57.14%) + // 4: ||||||||||||||| (42.86%) + // 5: -- + // 6: -- + // + // Minimum Hamming distance: 3 + // Maximum Hamming distance: 4 + // Minimum Hamming weight: 1 + // Maximum Hamming weight: 4 + // + localparam int StateWidth = 6; + typedef enum logic [StateWidth-1:0] { + StIdle_sparse = 6'b101100, + + // Absorb stage receives the message bitstream and computes the keccak + // rounds. This internal operation is mainly done inside sha3pad module + // not sha3core. The core module and this state machine observe the status + // of the process and mainly waits until all the sponge absorbing is + // completed. The main indicator is `absorbed` signal. + StAbsorb_sparse = 6'b100001, + + // Squeeze stage allows the software to read the internal state. + // If `EnMasking`, it opens the read permission of two share of the state. + // The squeezing in SHA3 specification describes the software to read up to + // the rate of SHA3 algorithm but this logic opens up the entire 1600 bits + // of the state (3200bits if `EnMasking`). + StSqueeze_sparse = 6'b001011, + + // ManualRun stage initiaties the keccak round and waits the completion. + // This state is moved from Squeeze state by writing 1 to manual_run CSR. + // When keccak round is completed, it goes back to Squeeze state. + StManualRun_sparse = 6'b010000, + + StTerminalError_sparse = 6'b111010 + } sha3_st_sparse_e; + + localparam int StateWidthLogic = 3; + typedef enum logic [StateWidthLogic-1:0] { + StIdle, + StAbsorb, + //StAbort, + StSqueeze, + StManualRun, + StFlush, + StError + } sha3_st_e; + + function automatic sha3_st_e sparse2logic(sha3_st_sparse_e st); + unique case (st) + StIdle_sparse : return StIdle; + StAbsorb_sparse : return StAbsorb; + //StAbort_sparse : return StAbort; + StSqueeze_sparse : return StSqueeze; + StManualRun_sparse : return StManualRun; + default : return StError; + endcase + endfunction : sparse2logic + + ////////////////// + // Error Report // + ////////////////// + typedef enum logic [7:0] { + ErrNone = 8'h 00, + + // ErrSha3SwControl occurs when software sent wrong flow signal. + // e.g) Sw set `process_i` without `start_i`. The state machine ignores + // the signal and report through the error FIFO. + ErrSha3SwControl = 8'h 80 + } err_code_e; + + typedef struct packed { + logic valid; + err_code_e code; // Type of error + logic [23:0] info; // Additional Debug info + } err_t; + + + /////////////// + // Functions // + /////////////// + + // Bytepading function + // `encode_bytepad_len` represents the first two bytes of bytepad() + // It depends on the block size. We can reuse KeccakRate + // 10000000 || 00010101 // 168 + // 10000000 || 00010001 // 136 + function automatic logic [15:0] encode_bytepad_len(keccak_strength_e kstrength); + logic [15:0] result; + unique case (kstrength) + L128: result = 16'h A801; // cSHAKE128 + L224: result = 16'h 9001; // not used + L256: result = 16'h 8801; // cSHAKE256 + L384: result = 16'h 6801; // not used + L512: result = 16'h 4801; // not used + + default: result = 16'h 0000; + endcase + return result; + endfunction : encode_bytepad_len + + +endpackage : abr_sha3_pkg diff --git a/designs/Caliptra/src/adams-bridge/abr_sha3pad.sv b/designs/Caliptra/src/adams-bridge/abr_sha3pad.sv new file mode 100644 index 0000000..1739fd1 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/abr_sha3pad.sv @@ -0,0 +1,936 @@ +// Copyright lowRISC contributors. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// ABR_SHA3 padding logic + +`include "abr_sva.svh" +`include "abr_prim_assert.sv" + +module abr_sha3pad + import abr_sha3_pkg::*; +#( + parameter int Width = 1600, // b= {25, 50, 100, 200, 400, 800, 1600} + parameter bit EnMasking = 0, + localparam int Share = (EnMasking) ? 2 : 1 +) ( + input clk_i, + input rst_b, + input logic zeroize, + + // Message interface (FIFO) + input msg_valid_i, + input [MsgWidth-1:0] msg_data_i [Share], + input [MsgStrbW-1:0] msg_strb_i, // one strobe for shares + output logic msg_ready_o, + + // N, S: Used in cSHAKE mode only + input [NSRegisterSize*8-1:0] ns_data_i, // See abr_sha3_pkg for details + + // output to keccak_round: message path + output logic [Width-1:0] keccak_data_o [Share], + input logic keccak_ready_i, + + // keccak_round control and status + // `run` initiates the keccak_round to process full keccak_f (24rounds). + // `complete` is an input from keccak round showing the current keccak_f is + // completed. + output logic keccak_run_o, + input keccak_complete_i, + + // configurations + input sha3_mode_e mode_i, + // strength_i is used in bytepad operation. bytepad() is used in cSHAKE only. + // SHA3, SHAKE doesn't have encode_N,S + input keccak_strength_e strength_i, + + // control signal + // start_i is a pulse signal triggers the padding logic (and the rest of SHA) + // to accept the incoming messages. This signal is used in the pad module, + // to initiate the prefix transmitting to keccak_round + input start_i, + // process_i is a pulse signal triggers the pad logic to stop receiving the + // message from MSG_FIFO and pad the trailing bits specified in the SHA3 + // standard. Look at `funcpad` signal for the values. + input process_i, + + // Indication of the Keccak Sponge Absorbing is complete, it is time for SW to + // control the Keccak-round if it needs more digest + output abr_prim_mubi_pkg::mubi4_t absorbed_o, + + // Indication that there was a fault in the sparse encoding + output logic sparse_fsm_error_o, + + // Indication that there was a fault in the counter + output logic msg_count_error_o +); + + ///////////////// + // Definitions // + ///////////////// + + // Padding States + // Encoding generated with: + // $ ./util/design/sparse-fsm-encode.py -d 3 -m 10 -n 7 \ + // -s 1116691466 --language=sv + // + // Hamming distance histogram: + // + // 0: -- + // 1: -- + // 2: -- + // 3: |||||||||||||||||||| (42.22%) + // 4: |||||||||||||||||| (40.00%) + // 5: ||||| (11.11%) + // 6: || (4.44%) + // 7: | (2.22%) + // + // Minimum Hamming distance: 3 + // Maximum Hamming distance: 7 + // Minimum Hamming weight: 2 + // Maximum Hamming weight: 5 + // + localparam int StateWidthPad = 7; + typedef enum logic [StateWidthPad-1:0] { + StPadIdle = 7'b1000010, + + // Sending a block of prefix, if cSHAKE mode is turned on. For the rest + // (SHA3, SHAKE), sending prefix is not needed. FSM moves from Idle to + // Message directly in that case. + // + // As abr_prim_slicer is instantiated, zerofill after the actual prefix is done + // by the module. + StPrefix = 7'b0111100, + StPrefixWait =7'b1001100, + + // Sending Message. In this state, it directly forwards the incoming data + // to Keccak round module. If `process_i` is asserted, then the rest of the + // messages will be discarded until new `start_i` is asserted. + // + // The incoming data can be partial write. Padding logic counts the number + // of bytes received and pause if a block size is transferred. + StMessage = 7'b0100101, + StMessageWait = 7'b0001111, + + // After sending the messages, then `process_i` is set, the FSM pads at the + // end of the message based on `mode_i`. If this is the last byte of the + // block, then it pads [7] to 1 to complete `pad10*1()` function. + StPad = 7'b1111010, + StPadRun = 7'b0011001, + + // If the padding isn't the end of the block byte (which will be rare case), + // FSM moves to another zerofill state. In contrast to StZerofill, this state + StPad01 = 7'b1101001, + + // Flushing the internal packers in front of the Keccak data output port. + StPadFlush = 7'b1010111, + + StTerminalError = 7'b0110011 + } pad_st_e; + + typedef enum logic [2:0] { + MuxNone = 3'b 000, + MuxFifo = 3'b 001, + MuxPrefix = 3'b 010, + MuxFuncPad = 3'b 011, + MuxZeroEnd = 3'b 100 + } mux_sel_e; + + //////////////////// + // Configurations // + //////////////////// + + logic [MsgCountW-1:0] block_addr_limit; + + // Block size based on the address. + // This is used for bytepad() and also pad10*1() + // assign block_addr_limit = KeccakRate[strength_i]; + // but below is easier to understand + always_comb begin + unique case (strength_i) + L128: block_addr_limit = MsgCountW'(KeccakRate[L128]); + L224: block_addr_limit = MsgCountW'(KeccakRate[L224]); + L256: block_addr_limit = MsgCountW'(KeccakRate[L256]); + L384: block_addr_limit = MsgCountW'(KeccakRate[L384]); + L512: block_addr_limit = MsgCountW'(KeccakRate[L512]); + + default: block_addr_limit = '0; + endcase + end + + ///////////////////// + // Control Signals // + ///////////////////// + + // `sel_mux` selects the output data among the incoming or internally generated data. + // MuxFifo: data from external (msg_data_i) + // MuxPrefix: bytepad(encode_string(N)||encode_string(S), ) + // MuxFuncPad: function_pad with end of message + // MuxZeroEnd: all 0 + mux_sel_e sel_mux; + + // `wr_message` indicates the number of entries sent to keccak round per + // block. The value shall be enough to cover Maximum entry of the Keccak + // storage as defined in abr_sha3_pkg, `$clog2(MsgEntries+1)`. Logically, + // it is not needed to have more than MsgEntries but for safety in case of + // SHA3 context switch resuming the SHA3 from the middle of sponge + // construction. If needed, the software should be able to write whole 1600 + // bits. The `wr_message` is used to check sent_blocksize. + logic [MsgCountW-1:0] wr_message; + logic inc_wrmsg, clr_wrmsg; + + + logic update_serial_buffer; + logic rst_serial_buffer; + logic [MsgAddrW-1:0] serial_buffer_wraddr; + logic [MsgWidth-1:0] serial_buffer_wrdata [Share]; + + // This primitive is used to place a hardened counter + // SEC_CM: CTR.REDUN + abr_prim_count #( + .Width(MsgCountW) + ) u_wrmsg_count ( + .clk_i, + .rst_b, + .clr_i(clr_wrmsg | zeroize), + .set_i(1'b0), + .set_cnt_i(MsgCountW'(0)), + .incr_en_i(inc_wrmsg), + .decr_en_i(1'b0), + .step_i(MsgCountW'(1)), + .cnt_o(wr_message), + .cnt_next_o(), + .err_o(msg_count_error_o) + ); + + assign inc_wrmsg = update_serial_buffer; + assign rst_serial_buffer = clr_wrmsg | zeroize; + // Prefix index to slice the `prefix` n-bits into multiple of 64bit. + logic [MsgAddrW-1:0] prefix_index; + assign prefix_index = (wr_message < block_addr_limit) ? wr_message : '0; + + // fsm_keccak_valid is an output signal from FSM which to send data generated + // inside the pad logic to keccak_round + logic fsm_keccak_valid; + + // hold_msg to prevent message from being forwarded into keccak_round and + // acked. Mainly the usage is to hold the message and initiates the + // keccak_round for current block. + logic hold_msg; + + // latch the partial write. Latched data is used for funcpad_merged + logic en_msgbuf; + logic clr_msgbuf; + + /////////////////// + // State Machine // + /////////////////// + + // Inputs + + // FSM moves to StPrefix only when cSHAKE is enabled + logic mode_eq_cshake; + assign mode_eq_cshake = (mode_i == CShake) ? 1'b 1 : 1'b 0; + + // `sent_blocksize` indicates the pad logic pushed block size data into + // keccak round logic. + logic sent_blocksize; + + assign sent_blocksize = (wr_message == block_addr_limit) ? 1'b 1 : 1'b 0; + + // `keccak_ack` indicates the request is accepted in keccak_round + logic keccak_ack; + + assign keccak_ack = keccak_ready_i ; + + // msg_partial indicates the incoming message is partial write or not. + // This is used to check if the incoming message need to be latched inside or + // not. If no partial message is at the end, msg_buf doesn't have to latch + // msg_data_i. It is assumed that the partial message is permitted only at + // the end of the message. + // Shall be used with msg_valid_i together. + logic msg_partial; + assign msg_partial = (&msg_strb_i != 1'b 1); + + + // `process_latched` latches the `process_i` input before it is seen in the + // FSM. + logic process_latched; + + always_ff @(posedge clk_i or negedge rst_b) begin + if (!rst_b) begin + process_latched <= 1'b 0; + end else if (process_i) begin + process_latched <= 1'b 1; + end else if (start_i) begin + process_latched <= 1'b0; + end + end + + // State Register =========================================================== + pad_st_e st, st_d; + + `ABR_PRIM_FLOP_SPARSE_FSM(u_state_regs, st_d, st, pad_st_e, StPadIdle) + + // `end_of_block` indicates current beat is end of the block + // It shall set when the address reaches to the end of the block. End address + // is set by the strength_i, which is `block_addr_limit`. + logic end_of_block; + + assign end_of_block = ((wr_message + 1'b1) == block_addr_limit) ? 1'b 1 : 1'b 0; + + + // Next logic and output logic ============================================== + // SEC_CM: ABSORBED.CTRL.MUBI + abr_prim_mubi_pkg::mubi4_t absorbed_d; + always_ff @(posedge clk_i or negedge rst_b) begin + if (!rst_b) absorbed_o <= abr_prim_mubi_pkg::MuBi4False; + else if (zeroize) absorbed_o <= abr_prim_mubi_pkg::MuBi4False; + else absorbed_o <= absorbed_d; + end + + always_comb begin + st_d = st; + + // FSM output : default values + keccak_run_o = 1'b 0; + sel_mux = MuxNone; + + fsm_keccak_valid = 1'b 0; + + hold_msg = 1'b 0; + clr_wrmsg = 1'b 0; + + en_msgbuf = 1'b 0; + clr_msgbuf = 1'b 0; + + absorbed_d = abr_prim_mubi_pkg::MuBi4False; + + sparse_fsm_error_o = 1'b 0; + + unique case (st) + + // In Idle state, the FSM checks if the software (or upper FSM) initiates + // the hash process. If `start_i` is asserted (assume it is pulse), FSM + // starts to push the data into the keccak round logic. Depending on the + // hashing mode, FSM may push additional prefex in front of the actual + // message. It means, the message could be back-pressured until the first + // prefix is processed. + StPadIdle: begin + if (start_i) begin + // If cSHAKE, move to Prefix state + if (mode_eq_cshake) begin + st_d = StPrefix; + end else begin + st_d = StMessage; + end + end else begin + st_d = StPadIdle; + end + end + + // At Prefix state, FSM pushes + // `bytepad(encode_string(N)||encode_string(S), 168or136)`. The software + // already prepared `encode_string(N) || encode_string(S)` in the regs. + // So, the FSM adds 2Byte in front of ns_data_i, which is an encoded + // block size (see `encoded_bytepad` below) + // After pushing the prefix, it initiates the hash process and move to + // Message state. + StPrefix: begin + sel_mux = MuxPrefix; + + if (sent_blocksize) begin + st_d = StPrefixWait; + + keccak_run_o = 1'b 1; + fsm_keccak_valid = 1'b 0; + clr_wrmsg = 1'b 1; + end else begin + st_d = StPrefix; + + fsm_keccak_valid = 1'b 1; + end + end + + StPrefixWait: begin + sel_mux = MuxPrefix; + + if (keccak_complete_i) begin + st_d = StMessage; + end else begin + st_d = StPrefixWait; + end + end + + // Message state pushes the incoming message into keccak round logic. + // It forwards the message while counting the data and if it reaches + // the block size, it triggers the keccak round to run. If `process` is + // set, it moves to Pad state. + StMessage: begin + sel_mux = MuxFifo; + en_msgbuf = msg_valid_i && msg_partial; + + if (sent_blocksize & keccak_ack) begin + // Check block completion first even process is set. + st_d = StMessage; + + keccak_run_o = 1'b 1; + clr_wrmsg = 1'b 1; + hold_msg = 1'b 1; + end else if (sent_blocksize & ~keccak_ack) begin + // Check block completion first even process is set. + st_d = StMessage; + + hold_msg = 1'b 1; + end else if (process_latched || process_i) begin + st_d = StPad; + + // Not asserting the msg_ready_o + hold_msg = 1'b 1; + end else begin + st_d = StMessage; + + end + end + + // Keccak round is running, we can send another block but can't start a + // new round until the current one completes. + StMessageWait: begin + sel_mux = MuxFifo; + en_msgbuf = msg_valid_i && msg_partial; + + if (sent_blocksize) begin + st_d = StMessageWait; + + hold_msg = 1'b 1; + end else if (process_i) begin + st_d = StPad; + + // Not asserting the msg_ready_o + hold_msg = 1'b 1; + end else if (keccak_complete_i) begin + st_d = StMessage; + end else begin + st_d = StMessageWait; + end + end + + // Pad state just pushes the ending suffix. Depending on the mode, the + // padding value is unique. SHA3 adds 2'b10, SHAKE adds 4'b1111, and + // cSHAKE adds 2'b 00. Refer `function_pad`. The signal has one more bit + // defined to accomodate first 1 bit of `pad10*1()` function. + StPad: begin + sel_mux = MuxFuncPad; + + fsm_keccak_valid = 1'b 1; + + if (end_of_block && keccak_ack) begin + // If padding is the last block, don't have to move to StPad01, just + // run Keccak and complete + st_d = StPadRun; + + // always clear the latched msgbuf + clr_msgbuf = 1'b 1; + //clr_wrmsg = 1'b 1; + end else if (end_of_block && ~keccak_ack) begin + // Wait until Keccak is available + st_d = StPad; + + fsm_keccak_valid = 1'b 0; + end else begin + st_d = StPad01; + clr_msgbuf = 1'b 1; + end + end + + StPadRun: begin + st_d = StPadFlush; + + keccak_run_o = 1'b 1; + clr_wrmsg = 1'b 1; + end + + // Pad01 pushes the end bit of pad10*1() function. As keccak accepts byte + // size only, StPad always pushes partial (5bits). So at this state, it + // pushes rest of 3bits. If the data pushed in StPad is the last byte of + // the block, then Pad01 pushes to the same byte, if not, it first + // zero-fill the block then pad 1 to the end. + StPad01: begin + sel_mux = MuxZeroEnd; + + // There's no chance StPad01 can be a start of the block. So can be + // discard that the sent_blocksize is set at the beginning. + if (sent_blocksize && keccak_ack) begin + st_d = StPadFlush; + + fsm_keccak_valid = 1'b 0; + keccak_run_o = 1'b 1; + clr_wrmsg = 1'b 1; + end else if (sent_blocksize && ~keccak_ack) begin + st_d = StPad01; + + fsm_keccak_valid = 1'b 0; + end else begin + st_d = StPad01; + + fsm_keccak_valid = 1'b 1; + end + end + + StPadFlush: begin + // Wait completion from keccak_round or wait SW indicator. + clr_wrmsg = 1'b 1; + clr_msgbuf = 1'b 1; + + if (keccak_complete_i) begin + st_d = StPadIdle; + + absorbed_d = abr_prim_mubi_pkg::MuBi4True; + end else begin + st_d = StPadFlush; + end + end + + StTerminalError: begin + // this state is terminal + st_d = st; + sparse_fsm_error_o = 1'b 1; + end + + default: begin + // this state is terminal + st_d = StTerminalError; + sparse_fsm_error_o = 1'b 1; + end + endcase + + if (zeroize) st_d = StPadIdle; + + end + + ////////////// + // Datapath // + ////////////// + + // `encode_bytepad` represents the first two bytes of bytepad() + // It depends on the block size. We can reuse KeccakRate + // 10000000 || 00010101 // 168 + // 10000000 || 00010001 // 136 + logic [15:0] encode_bytepad; + + assign encode_bytepad = encode_bytepad_len(strength_i); + + // Prefix size ============================================================== + // Prefix represents bytepad(encode_string(N) || encode_string(S), 168 or 136) + // encode_string(N) || encode_string(S) is prepared by the software and given + // through `ns_data_i`. The first part of bytepad is determined by the + // `strength_i` and stored into `encode_bytepad`. + + // It is assumed that the prefix always smaller than the block size. + logic [PrefixSize*8-1:0] prefix; + + assign prefix = {ns_data_i, encode_bytepad}; + + logic [MsgWidth-1:0] prefix_sliced; + logic [MsgWidth-1:0] prefix_data [Share]; + + abr_prim_slicer #( + .InW (PrefixSize*8), + .IndexW(MsgAddrW), + .OutW(MsgWidth) + ) u_prefix_slicer ( + .sel_i (prefix_index), + .data_i (prefix), + .data_o (prefix_sliced) + ); + + if (EnMasking) begin : gen_prefix_masked + // If Masking is enabled, prefix is two share. + assign prefix_data[0] = '0; + assign prefix_data[1] = prefix_sliced; + end else begin : gen_prefix_unmasked + // If Unmasked, only one share exists. + assign prefix_data[0] = prefix_sliced; + end + + // ========================================================================== + // function_pad is the unique value padded at the end of the message based on + // the function among SHA3, SHAKE, cSHAKE. The standard mentioned that SHA3 + // pads `01` , SHAKE pads `1111`, and cSHAKE pads `00`. + // + // Then pad10*1() function follows. It adds `1` first then fill 0 until it + // reaches the block size -1, then adds `1`. + // + // It means always `1` is followed by the function pad. + logic [4:0] funcpad; + + logic [MsgWidth-1:0] funcpad_data [Share]; + + always_comb begin + unique case (mode_i) + Sha3: funcpad = 5'b 00110; + Shake: funcpad = 5'b 11111; + CShake: funcpad = 5'b 00100; + + default: begin + // Just create non-padding but pad10*1 only + funcpad = 5'b 00001; + end + endcase + end + + // ========================================================================== + // `zero_with_endbit` contains all zero unless the message is for the last + // MsgWidth beat in the block. If it is the end of the block, the last bit + // will be set to complete pad10*1() functionality. + logic [MsgWidth-1:0] zero_with_endbit [Share]; + + if (EnMasking) begin : gen_zeroend_masked + assign zero_with_endbit[0] = '0; + assign zero_with_endbit[1][MsgWidth-1] = end_of_block; + assign zero_with_endbit[1][MsgWidth-2:0] = '0; + end else begin : gen_zeroend_unmasked + assign zero_with_endbit[0][MsgWidth-1] = end_of_block; + assign zero_with_endbit[0][MsgWidth-2:0] = '0; + end + + // ========================================================================== + // Data mux for writing to serial buffer + + always_comb serial_buffer_wraddr = (wr_message < block_addr_limit) ? wr_message : '0; + + always_comb begin + unique case (sel_mux) + MuxFifo: serial_buffer_wrdata = msg_data_i; + MuxPrefix: serial_buffer_wrdata = prefix_data; + MuxFuncPad: serial_buffer_wrdata = funcpad_data; + MuxZeroEnd: serial_buffer_wrdata = zero_with_endbit; + + // MuxNone + default: serial_buffer_wrdata = '{default:'0}; + endcase + end + + always_comb begin + unique case (sel_mux) + MuxFifo: update_serial_buffer = msg_valid_i & ~hold_msg & ~en_msgbuf; + MuxPrefix: update_serial_buffer = fsm_keccak_valid; + MuxFuncPad: update_serial_buffer = fsm_keccak_valid; + MuxZeroEnd: update_serial_buffer = fsm_keccak_valid; + + // MuxNone + default: update_serial_buffer = 1'b 0; + endcase + end + + always_comb begin + unique case (sel_mux) + MuxFifo: msg_ready_o = en_msgbuf | ~hold_msg; + MuxPrefix: msg_ready_o = 1'b 0; + MuxFuncPad: msg_ready_o = 1'b 0; + MuxZeroEnd: msg_ready_o = 1'b 0; + + // MuxNone + default: msg_ready_o = 1'b 0; + endcase + end + + // abr_prim_packer : packing to 64bit to update keccak storage + // two abr_prim_packer in this module are used to pack the data received from + // upper layer (KMAC core) and also the 5bit padding bits. + // It is assumed that the message from upper layer could be partial at the + // end of the message. Then the 2 or 4bit padding is required. It can be + // handled by some custom logic or could be done by abr_prim_packer. + // If packer is used, the MSG_FIFO doesn't have to have another abr_prim_packer + // in front of the FIFO. This logic can handle the partial writes from the + // software. + // + // If a custom logic is implemented here, abr_prim_packer is necessary in front + // of the FIFO, as this logic only appends at the end of the message when + // `process_i` is asserted. Also, in this case, even abr_prim_packer is not + // needed, still 64bit registers to latch the partial write is required. + // If not, the logic has to delay the acceptance of the incoming write + // accesses. It may trigger the back-pressuring in some case which may result + // that the software(or upper layer) may not set process_i. + // + // For custom logic, it could be implemented by the 8 mux selection. + // for instance: (subject to be changed) + // unique case (sent_byte[2:0]) // generated from msg_strb_i + // 3'b 000: funcpad_merged = {end_of_block, 63'(function_pad) }; + // 3'b 001: funcpad_merged = {end_of_block, 55'(function_pad), msg_data_i[ 7:0]}; + // 3'b 010: funcpad_merged = {end_of_block, 47'(function_pad), msg_data_i[15:0]}; + // 3'b 011: funcpad_merged = {end_of_block, 39'(function_pad), msg_data_i[23:0]}; + // 3'b 100: funcpad_merged = {end_of_block, 31'(function_pad), msg_data_i[31:0]}; + // 3'b 101: funcpad_merged = {end_of_block, 23'(function_pad), msg_data_i[39:0]}; + // 3'b 110: funcpad_merged = {end_of_block, 15'(function_pad), msg_data_i[47:0]}; + // 3'b 111: funcpad_merged = {end_of_block, 7'(function_pad), msg_data_i[55:0]}; + // default: funcpad_merged = '0; + // endcase + + // internal buffer to store partial write. It doesn't have to store last byte as it + // stores only when partial write. + logic [MsgWidth-8-1:0] msg_buf [Share]; + logic [MsgStrbW-1-1:0] msg_strb; + + always_ff @(posedge clk_i or negedge rst_b) begin + if (!rst_b) begin + msg_buf <= '{default:'0}; + msg_strb <= '0; + end else if (en_msgbuf) begin + for (int i = 0 ; i < Share ; i++) begin + msg_buf[i] <= msg_data_i[i][0+:(MsgWidth-8)]; + end + msg_strb <= msg_strb_i[0+:(MsgStrbW-1)]; + end else if (clr_msgbuf) begin + msg_buf <= '{default:'0}; + msg_strb <= '0; + end + end + + if (EnMasking) begin : gen_funcpad_data_masked + always_comb begin + unique case (msg_strb) + 7'b 000_0000: begin + funcpad_data[0] = '0; + funcpad_data[1] = {end_of_block, 63'(funcpad) }; + end + 7'b 000_0001: begin + funcpad_data[0] = {56'h0, msg_buf[0][ 7:0]}; + funcpad_data[1] = {end_of_block, 55'(funcpad), msg_buf[1][ 7:0]}; + end + 7'b 000_0011: begin + funcpad_data[0] = {48'h0, msg_buf[0][15:0]}; + funcpad_data[1] = {end_of_block, 47'(funcpad), msg_buf[1][15:0]}; + end + 7'b 000_0111: begin + funcpad_data[0] = {40'h0, msg_buf[0][23:0]}; + funcpad_data[1] = {end_of_block, 39'(funcpad), msg_buf[1][23:0]}; + end + 7'b 000_1111: begin + funcpad_data[0] = {32'h0, msg_buf[0][31:0]}; + funcpad_data[1] = {end_of_block, 31'(funcpad), msg_buf[1][31:0]}; + end + 7'b 001_1111: begin + funcpad_data[0] = {24'h0, msg_buf[0][39:0]}; + funcpad_data[1] = {end_of_block, 23'(funcpad), msg_buf[1][39:0]}; + end + 7'b 011_1111: begin + funcpad_data[0] = {16'h0, msg_buf[0][47:0]}; + funcpad_data[1] = {end_of_block, 15'(funcpad), msg_buf[1][47:0]}; + end + 7'b 111_1111: begin + funcpad_data[0] = { 8'h0, msg_buf[0][55:0]}; + funcpad_data[1] = {end_of_block, 7'(funcpad), msg_buf[1][55:0]}; + end + + default: funcpad_data = '{default:'0}; + endcase + end + end else if (MsgWidth == 128) begin : gen_128_funcpad_data_unmasked + always_comb begin + unique case (msg_strb) + 15'b 000_0000_0000_0000: funcpad_data[0] = {end_of_block, 127'(funcpad) }; + 15'b 000_0000_0000_0001: funcpad_data[0] = {end_of_block, 119'(funcpad), msg_buf[0][ 7:0]}; + 15'b 000_0000_0000_0011: funcpad_data[0] = {end_of_block, 111'(funcpad), msg_buf[0][15:0]}; + 15'b 000_0000_0000_0111: funcpad_data[0] = {end_of_block, 103'(funcpad), msg_buf[0][23:0]}; + 15'b 000_0000_0000_1111: funcpad_data[0] = {end_of_block, 95'(funcpad), msg_buf[0][31:0]}; + 15'b 000_0000_0001_1111: funcpad_data[0] = {end_of_block, 87'(funcpad), msg_buf[0][39:0]}; + 15'b 000_0000_0011_1111: funcpad_data[0] = {end_of_block, 79'(funcpad), msg_buf[0][47:0]}; + 15'b 000_0000_0111_1111: funcpad_data[0] = {end_of_block, 71'(funcpad), msg_buf[0][55:0]}; + 15'b 000_0000_1111_1111: funcpad_data[0] = {end_of_block, 63'(funcpad), msg_buf[0][63:0]}; + 15'b 000_0001_1111_1111: funcpad_data[0] = {end_of_block, 55'(funcpad), msg_buf[0][71:0]}; + 15'b 000_0011_1111_1111: funcpad_data[0] = {end_of_block, 47'(funcpad), msg_buf[0][79:0]}; + 15'b 000_0111_1111_1111: funcpad_data[0] = {end_of_block, 39'(funcpad), msg_buf[0][87:0]}; + 15'b 000_1111_1111_1111: funcpad_data[0] = {end_of_block, 31'(funcpad), msg_buf[0][95:0]}; + 15'b 001_1111_1111_1111: funcpad_data[0] = {end_of_block, 23'(funcpad), msg_buf[0][103:0]}; + 15'b 011_1111_1111_1111: funcpad_data[0] = {end_of_block, 15'(funcpad), msg_buf[0][111:0]}; + 15'b 111_1111_1111_1111: funcpad_data[0] = {end_of_block, 7'(funcpad), msg_buf[0][119:0]}; + default: funcpad_data = '{default:'0}; + endcase + end + end else if (MsgWidth == 64) begin : gen_64_funcpad_data_unmasked + always_comb begin + unique case (msg_strb) + 7'b 000_0000: funcpad_data[0] = {end_of_block, 63'(funcpad) }; + 7'b 000_0001: funcpad_data[0] = {end_of_block, 55'(funcpad), msg_buf[0][ 7:0]}; + 7'b 000_0011: funcpad_data[0] = {end_of_block, 47'(funcpad), msg_buf[0][15:0]}; + 7'b 000_0111: funcpad_data[0] = {end_of_block, 39'(funcpad), msg_buf[0][23:0]}; + 7'b 000_1111: funcpad_data[0] = {end_of_block, 31'(funcpad), msg_buf[0][31:0]}; + 7'b 001_1111: funcpad_data[0] = {end_of_block, 23'(funcpad), msg_buf[0][39:0]}; + 7'b 011_1111: funcpad_data[0] = {end_of_block, 15'(funcpad), msg_buf[0][47:0]}; + 7'b 111_1111: funcpad_data[0] = {end_of_block, 7'(funcpad), msg_buf[0][55:0]}; + default: funcpad_data = '{default:'0}; + endcase + end + end + + logic [MsgEntries-1:0][MsgWidth-1:0] serial_buffer [Share]; + logic [MsgEntries-1:0][MsgWidth-1:0] serial_buffer_d [Share]; + + assign keccak_data_o = serial_buffer; + + // Serial input buffer + + always_ff @(posedge clk_i or negedge rst_b) begin + if (!rst_b) begin + serial_buffer <= '{default:'0}; + end else if (rst_serial_buffer) begin + serial_buffer <= '{default:'0}; + end else if (update_serial_buffer) begin + serial_buffer <= serial_buffer_d; + end + end + + always_comb begin + serial_buffer_d = serial_buffer; + for (int j = 0 ; j < Share ; j++) begin + for (int unsigned i = 0 ; i < MsgEntries ; i++) begin + if (serial_buffer_wraddr == i[MsgAddrW-1:0]) begin + serial_buffer_d[j][i] = serial_buffer_wrdata[j]; + end else begin + serial_buffer_d[j][i] = serial_buffer[j][i]; + end + end // for i + end // for j + end + + + //////////////// + // Assertions // + //////////////// + + // Prefix size is smaller than the smallest Keccak Block Size, which is 72 bytes. + `ABR_ASSERT_INIT(PrefixLessThanBlock_A, PrefixSize/8 < KeccakRate[4]) + + // Some part of datapath in sha3pad assumes Data width as 64bit. + // If data width need to be changed, funcpad_data part should be changed too. + // Also, The blocksize shall be divided by MsgWidth, which means, MsgWidth + // can be {16, 32, 64} even funcpad_data mux is fully flexible. + //`ABR_ASSERT_INIT(MsgWidthidth_A, MsgWidth == 64) + + // Assume pulse signals: start, process, done + `ABR_ASSERT(StartPulse_A, start_i |=> !start_i) + `ABR_ASSERT(ProcessPulse_A, process_i |=> !process_i) + + // ABR_ASSERT output pulse signals: absorbed_o, keccak_run_o + `ABR_ASSERT(AbsorbedPulse_A, + abr_prim_mubi_pkg::mubi4_test_true_strict(absorbed_o) |=> + abr_prim_mubi_pkg::mubi4_test_false_strict(absorbed_o)) + `ABR_ASSERT(KeccakRunPulse_A, keccak_run_o |=> !keccak_run_o) + + // start_i, process_i cannot set high at the same time + `ABR_ASSERT(StartProcessMutex_a, + $onehot0({ + start_i, + process_i + })) + +`ifndef SYNTHESIS + // Process only asserts after start and all message are fed. + // These valid signals are qualifier of FPV to trigger the control signal + // It is a little bit hard to specify these criteria in SVA property so creating + // qualifiers in RTL form is easier. + logic start_valid, process_valid, absorb_valid, done_valid; + + always_ff @(posedge clk_i or negedge rst_b) begin + if (!rst_b) begin + start_valid <= 1'b 1; + end else if (zeroize) begin + start_valid <= 1'b 1; + end else if (start_i) begin + start_valid <= 1'b 0; + end else if (process_i) begin + start_valid <= 1'b 1; + end + end + always_ff @(posedge clk_i or negedge rst_b) begin + if (!rst_b) begin + process_valid <= 1'b 0; + end else if (zeroize) begin + process_valid <= 1'b 0; + end else if (start_i) begin + process_valid <= 1'b 1; + end else if (process_i) begin + process_valid <= 1'b 0; + end + end + + // Message can be fed in between start_i and process_i. + `ABR_ASSERT(MessageCondition_M, msg_valid_i && msg_ready_o |-> process_valid && !process_i) + + // Message ready should be asserted only in between start_i and process_i + `ABR_ASSERT(MsgReadyCondition_A, msg_ready_o |-> process_valid && !process_i) + + `ABR_ASSERT(ProcessCondition_M, process_i |-> process_valid) + `ABR_ASSERT(StartCondition_M, start_i |-> start_valid) + + // Assume mode_i and strength_i are stable during the operation + // This will be guarded at the kmac top level + `ABR_ASSERT(ModeStableDuringOp_M, + $changed(mode_i) |-> start_valid) + `ABR_ASSERT(StrengthStableDuringOp_M, + $changed(strength_i) |-> start_valid) + +`endif // SYNTHESIS + + // If `process_i` is asserted, eventually sha3pad trigger run signal + `ABR_ASSERT(ProcessToRun_A, process_i |-> strong(##[2:$] keccak_run_o), + clk_i, !rst_b) + + // If process_i asserted, completion shall be asserted shall be asserted + //`ABR_ASSERT(ProcessToAbsorbed_A, process_i |=> strong(##[24*Share:$] absorbed_o)) + + + // Assumption of input mode_i and strength_i + // SHA3 variants: SHA3-224, SHA3-256, SHA3-384, SHA3-512 + // SHAKE, cSHAKE variants: SHAKE128, SHAKE256, cSHAKE128, cSHAKE256 + `ABR_ASSERT(ModeStrengthCombinations_M, + start_i |-> + (mode_i == Sha3 && (strength_i inside {L224, L256, L384, L512})) || + ((mode_i == Shake || mode_i == CShake) && (strength_i inside {L128, L256})), + clk_i, !rst_b) + + // Keccak control interface + // Keccak run triggered -> completion should come + `ABR_ASSERT(RunThenComplete_M, + keccak_run_o |-> strong(##[12*Share:$] keccak_complete_i), + clk_i, !rst_b) + + // No partial write is allowed for Message FIFO interface + `ABR_ASSERT(NoPartialMsgFifo_M, + update_serial_buffer && (sel_mux == MuxFifo) |-> (&msg_strb_i) == 1'b1, + clk_i, !rst_b) + + // When transaction is stored into msg_buf, it shall be partial write. + `ABR_ASSERT(AlwaysPartialMsgBuf_M, + en_msgbuf |-> msg_valid_i && (msg_strb_i[MsgStrbW-1] == 1'b0), + clk_i, !rst_b) + + // if partial write comes and is acked, then no more msg_valid_i until + // next message + `ABR_ASSERT(PartialEndOfMsg_M, + msg_valid_i && msg_ready_o && msg_partial |=> + !msg_valid_i ##[1:$] $stable(msg_valid_i) ##1 start_i, + clk_i, !rst_b) + + // At the first clock in StPad01 state, sent_blocksize shall not be set + `ABR_ASSERT(Pad01NotAttheEndOfBlock_A, + (st == StPad && st_d == StPad01) |-> !end_of_block, + clk_i, !rst_b) + + // When data sent to the keccak_round, the address should be in the range + `ABR_ASSERT(KeccakAddrInRange_A, + update_serial_buffer |-> serial_buffer_wraddr < KeccakRate[strength_i], + clk_i, !rst_b) + + // NS data shall be stable during the operation. + //`ABR_ASSERT(NsStableInProcess_A, + // $stable(ns_data_i) throughout(start_i ##[1:$] process_i ##[1:$] absorbed_o), + // clk_i, !rst_b) + + // Functional Coverage + `ABR_COVER(StMessageFeed_C, st == StMessage) + `ABR_COVER(StPad_C, st == StPad01 && sent_blocksize) + `ABR_COVER(StPadSendMsg_C, st == StPad01 && keccak_ack) + `ABR_COVER(StComplete_C, st == StPadFlush) +endmodule diff --git a/designs/Caliptra/src/adams-bridge/abr_sva.svh b/designs/Caliptra/src/adams-bridge/abr_sva.svh new file mode 100644 index 0000000..a0a4027 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/abr_sva.svh @@ -0,0 +1,64 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. + +`ifndef ABR_SVA +`define ABR_SVA + +// Default clk and reset signals used by assertion macros below. +`define ABR_ASSERT_DEFAULT_CLK clk_i +`define ABR_ASSERT_DEFAULT_RST !rst_b + +// Converts an arbitrary block of code into a Verilog string +`define STRINGIFY(__x) `"__x`" + +// ABR_ASSERT_RPT is available to change the reporting mechanism when an assert fails +`define ABR_ASSERT_RPT(name) \ +`ifdef UVM \ + uvm_pkg::uvm_report_error("ABR_ASSERT FAILED", name, uvm_pkg::UVM_NONE, \ + `__FILE__, `__LINE__); \ +`else \ + $fatal(1, "[ABR_ASSERT FAILED] [%m] %s (%s:%0d)",name, `__FILE__, `__LINE__); \ +`endif + +// Assert a concurrent property directly. +`define ABR_ASSERT(assert_name, prop, clk = `ABR_ASSERT_DEFAULT_CLK, rst = `ABR_ASSERT_DEFAULT_RST, en = 1) \ +`ifdef ABR_ASSERT_ON \ + assert_name: assert property (@(posedge clk) disable iff ((rst !== 0) | (en === 0)) (prop)) \ + else begin \ + `ABR_ASSERT_RPT(`STRINGIFY(assert_name)) \ + end \ +`endif + +// Assert a concurrent property NEVER happens +`define ABR_ASSERT_NEVER(assert_name, prop, clk = `ABR_ASSERT_DEFAULT_CLK, rst = `ABR_ASSERT_DEFAULT_RST, en = 1) \ +`ifdef ABR_ASSERT_ON \ + assert_name: assert property (@(posedge clk) disable iff ((rst !== 0) | (en === 0)) not (prop)) \ + else begin \ + `ABR_ASSERT_RPT(`STRINGIFY(assert_name)) \ + end \ +`endif + +// Assert that signal is not x +`define ABR_ASSERT_KNOWN(assert_name, sig, clk = `ABR_ASSERT_DEFAULT_CLK, rst = `ABR_ASSERT_DEFAULT_RST, en = 1) \ + `ABR_ASSERT(assert_name, !$isunknown(sig), clk, rst, en) + +// Assert that a vector of signals is mutually exclusive +`define ABR_ASSERT_MUTEX(assert_name, sig, clk = `ABR_ASSERT_DEFAULT_CLK, rst = `ABR_ASSERT_DEFAULT_RST, en = 1) \ + `ABR_ASSERT(assert_name, $onehot0(sig), clk, rst, en) + +// Assert that a vector of signals is stable (does not change value) +`define ABR_ASSERT_STABLE(assert_name, sig, clk = `ABR_ASSERT_DEFAULT_CLK, rst = `ABR_ASSERT_DEFAULT_RST) \ + `ABR_ASSERT(assert_name, $stable(sig), clk, rst) + +`endif diff --git a/designs/Caliptra/src/adams-bridge/abr_top.sv b/designs/Caliptra/src/adams-bridge/abr_top.sv new file mode 100644 index 0000000..ac4635c --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/abr_top.sv @@ -0,0 +1,1486 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. + +//Initial top level module +`include "abr_config_defines.svh" +`include "abr_prim_assert.sv" + +module abr_top + import abr_prim_alert_pkg::*; + import abr_reg_pkg::*; + import abr_params_pkg::*; + import abr_ctrl_pkg::*; + import abr_sampler_pkg::*; + import abr_sha3_pkg::*; + import ntt_defines_pkg::*; + import decompose_defines_pkg::*; + import compress_defines_pkg::*; + import decompress_defines_pkg::*; + `ifdef CALIPTRA + import kv_defines_pkg::*; + `endif + #( + //top level params + parameter AHB_ADDR_WIDTH = 32, + parameter AHB_DATA_WIDTH = 64, + parameter CLIENT_DATA_WIDTH = 32 + ) + ( + input logic clk, + input logic rst_b, + +`ifdef RV_FPGA_SCA + output wire NTT_trigger, + output wire PWM_trigger, + output wire PWA_trigger, + output wire INTT_trigger, +`endif + + + //ahb input + input logic [AHB_ADDR_WIDTH-1:0] haddr_i, + input logic [AHB_DATA_WIDTH-1:0] hwdata_i, + input logic hsel_i, + input logic hwrite_i, + input logic hready_i, + input logic [1:0] htrans_i, + input logic [2:0] hsize_i, + + //ahb output + output logic hresp_o, + output logic hreadyout_o, + output logic [AHB_DATA_WIDTH-1:0] hrdata_o, + + abr_mem_if.req abr_memory_export, + + `ifdef CALIPTRA + // KV interface + output kv_read_t [2:0] kv_read, + input kv_rd_resp_t [2:0] kv_rd_resp, + output kv_write_t kv_write, + input kv_wr_resp_t kv_wr_resp, + //PCR Signing + input pcr_signing_t pcr_signing_data, + input logic ocp_lock_in_progress, + `endif + //Zeroize the engine if entering debug or scan mode + input logic debugUnlock_or_scan_mode_switch, + + output logic busy_o, + + output logic error_intr, + output logic notif_intr + + + ); + + localparam DATA_WIDTH = 32; + +//Signal Declarations + logic zeroize_reg; + + abr_sampler_mode_e sampler_mode; + logic sha3_start; + logic msg_start; + logic msg_valid; + logic msg_rdy; + logic [MsgStrbW-1:0] msg_strobe; + logic [MsgWidth-1:0] msg_data[Sha3Share]; + logic sampler_start; + logic [ABR_MEM_ADDR_WIDTH-1:0] dest_base_addr; + + logic sampler_busy; + logic sampler_state_dv; + logic [abr_sha3_pkg::StateW-1:0] sampler_state_data[Sha3Share]; + + logic sampler_mem_dv; + logic [ABR_MEM_DATA_WIDTH-1:0] sampler_mem_data; + logic [ABR_MEM_ADDR_WIDTH-1:0] sampler_mem_addr; + + logic [1:0] sampler_ntt_dv, sampler_ntt_dv_f; + logic [ABR_NUM_NTT-1:0] sampler_ntt_mode; + logic [ABR_NUM_NTT-1:0] sampler_valid; + logic [COEFF_PER_CLK-1:0][MLDSA_Q_WIDTH-1:0] sampler_ntt_data; + + abr_ntt_mode_e [ABR_NUM_NTT-1:0] ntt_mode; + mode_t [ABR_NUM_NTT-1:0] mode; + logic [ABR_NUM_NTT-1:0] accumulate; + logic [ABR_NUM_NTT-1:0] ntt_enable; + logic [ABR_NUM_NTT-1:0] mlkem_mode; + ntt_mem_addr_t [ABR_NUM_NTT-1:0] ntt_mem_base_addr; + pwo_mem_addr_t [ABR_NUM_NTT-1:0] pwo_mem_base_addr; + mem_if_t [ABR_NUM_NTT-1:0] ntt_mem_wr_req; + logic [3:0][ABR_MEM_ADDR_WIDTH-1:0] ntt_mem_wr_req_mux; + mem_if_t [ABR_NUM_NTT-1:0] ntt_mem_rd_req; + logic [3:0][ABR_MEM_ADDR_WIDTH-1:0] ntt_mem_rd_req_mux; + logic [ABR_NUM_NTT-1:0][ABR_MEM_MASKED_DATA_WIDTH-1:0] ntt_mem_wr_data; + logic [2:0][ABR_MEM_DATA_WIDTH-1:0] ntt_mem_wr_data_mux; + logic [ABR_NUM_NTT-1:0][ABR_MEM_MASKED_DATA_WIDTH-1:0] ntt_mem_rd_data; + mem_if_t [ABR_NUM_NTT-1:0] pwm_a_rd_req; + logic [3:0][ABR_MEM_ADDR_WIDTH-1:0] pwm_a_rd_req_mux; + mem_if_t [ABR_NUM_NTT-1:0] pwm_b_rd_req; + logic [3:0][ABR_MEM_ADDR_WIDTH-1:0] pwm_b_rd_req_mux; + logic [ABR_NUM_NTT-1:0][ABR_MEM_MASKED_DATA_WIDTH-1:0] pwm_a_rd_data; + logic [ABR_NUM_NTT-1:0][ABR_MEM_MASKED_DATA_WIDTH-1:0] pwm_b_rd_data; + logic [ABR_NUM_NTT-1:0] ntt_busy; + logic [ABR_NUM_NTT-1:0] ntt_random_en; + logic [ABR_NUM_NTT-1:0] ntt_shuffling_en; + logic [ABR_NUM_NTT-1:0] ntt_masking_en; + + mem_if_t w1_mem_wr_req; + logic [ABR_MEM_W1_DATA_W-1:0] w1_mem_wr_data; + mem_if_t w1_mem_rd_req; + logic [ABR_MEM_W1_DATA_W-1:0] w1_mem_rd_data; + + logic decomp_msg_valid; + logic [MsgWidth-1:0] decomp_msg_data[Sha3Share]; + + logic [ABR_MEM_ADDR_WIDTH-1:0] aux_src0_base_addr; + logic [ABR_MEM_ADDR_WIDTH-1:0] aux_src1_base_addr; + logic [ABR_MEM_ADDR_WIDTH-1:0] aux_dest_base_addr; + + logic power2round_enable, power2round_done; + mem_if_t [1:0] pwr2rnd_mem_rd_req; + logic [1:0][ABR_MEM_DATA_WIDTH-1:0] pwr2rnd_mem_rd_data; + mem_if_t [1:0] pwr2rnd_keymem_if; + logic [1:0] [DATA_WIDTH-1:0] pwr2rnd_wr_data; + logic pk_t1_wren; + logic [7:0][T1_COEFF_W-1:0] pk_t1_wrdata; + logic [7:0] pk_t1_wr_addr; + + logic decompose_enable, decompose_done; + mem_if_t decomp_mem_wr_req; + mem_if_t [1:0] decomp_mem_rd_req; + logic [ABR_MEM_DATA_WIDTH-1:0] decomp_mem_wr_data; + logic [1:0][ABR_MEM_DATA_WIDTH-1:0] decomp_mem_rd_data; + logic decompose_mode; + + logic skencode_enable, skencode_done; + mem_if_t skencode_keymem_if; + logic [DATA_WIDTH-1:0] skencode_wr_data; + mem_if_t [1:0] skencode_mem_rd_req; + logic [1:0][ABR_MEM_DATA_WIDTH-1:0] skencode_mem_rd_data; + + logic skdecode_enable, skdecode_done; + mem_if_t [1:0] skdecode_keymem_if; + logic [1:0][DATA_WIDTH-1:0] skdecode_rd_data; + mem_if_t [1:0] skdecode_mem_wr_req; + logic [1:0][ABR_MEM_DATA_WIDTH-1:0] skdecode_mem_wr_data; + logic skdecode_error; + + logic makehint_enable, makehint_done; + logic makehint_invalid; + mem_if_t makehint_mem_rd_req; + logic [ABR_MEM_DATA_WIDTH-1:0] makehint_mem_rd_data; + logic makehint_reg_wren; + logic [3:0][7:0] makehint_reg_wrdata; + logic [ABR_MEM_ADDR_WIDTH-1:0] makehint_reg_wr_addr; + + logic normcheck_enable; + logic normcheck_done; + logic [1:0] normcheck_mode; + logic normcheck_invalid; + mem_if_t normcheck_mem_rd_req; + logic [ABR_MEM_DATA_WIDTH-1:0] normcheck_mem_rd_data; + + logic compress_enable; + logic compress_done; + logic compress_compare_failed; + compress_mode_t compress_mode; + logic compress_compare_mode; + logic [2:0] compress_num_poly; + mem_if_t compress_mem_rd_req; + logic [ABR_MEM_DATA_WIDTH-1:0] compress_mem_rd_data; + logic [1:0] compress_api_rw_en; + logic [ABR_MEM_ADDR_WIDTH-1:0] compress_api_rw_addr; + logic [DATA_WIDTH-1:0] compress_api_wr_data; + logic [DATA_WIDTH-1:0] compress_api_rd_data; + + logic decompress_enable; + logic decompress_done; + decompress_mode_t decompress_mode; + logic [2:0] decompress_num_poly; + mem_if_t decompress_mem_wr_req; + logic [ABR_MEM_DATA_WIDTH-1:0] decompress_mem_wr_data; + logic decompress_api_rd_en; + logic [ABR_MEM_ADDR_WIDTH-1:0] decompress_api_rd_addr; + logic [1:0][DATA_WIDTH-1:0] decompress_api_rd_data; + + logic sigencode_enable, sigencode_done; + mem_if_t [1:0] sigencode_mem_rd_req; + logic [1:0][ABR_MEM_DATA_WIDTH-1:0] sigencode_mem_rd_data; + mem_if_t sigencode_mem_wr_req; + logic [1:0][3:0][19:0] sigencode_mem_wr_data; + + logic pkdecode_enable, pkdecode_done; + mem_if_t [1:0] pkdecode_mem_wr_req; + logic [1:0][ABR_MEM_DATA_WIDTH-1:0] pkdecode_mem_wr_data; + logic [7:0] pkdecode_rd_addr; + logic [7:0][T1_COEFF_W-1:0] pkdecode_rd_data; + + logic sigdecode_z_enable, sigdecode_z_done; + mem_if_t [1:0] sigdecode_z_mem_wr_req; + logic [1:0][ABR_MEM_DATA_WIDTH-1:0] sigdecode_z_mem_wr_data; + mem_if_t sigdecode_z_mem_rd_req; + logic [1:0][3:0][19:0] sigdecode_z_mem_rd_data; + + logic sigdecode_h_enable, sigdecode_h_done; + logic [SIGNATURE_H_VALID_NUM_BYTES-1:0][7:0] signature_h; + logic sigdecode_h_invalid; + mem_if_t sigdecode_h_mem_wr_req; + logic [ABR_MEM_DATA_WIDTH-1:0] sigdecode_h_mem_wr_data; + + mem_if_t sib_mem_rd_req; + logic [ABR_MEM_DATA_WIDTH-1:0] sib_mem_rd_data; + + logic lfsr_enable; + logic [1:0][LFSR_W-1:0] lfsr_seed; + logic [RND_W-1:0] rand_bits; + logic [RND_W-7:0] ntt_rand_bits; + + //gasket to assemble reg requests + logic abr_reg_dv; + logic abr_reg_hold; + logic abr_reg_rd_ack, abr_reg_wr_ack; + logic [CLIENT_DATA_WIDTH-1:0] abr_reg_rdata; + logic [AHB_ADDR_WIDTH-1:0] abr_reg_addr; + logic [CLIENT_DATA_WIDTH-1:0] abr_reg_wdata; + logic abr_reg_write; + + logic abr_reg_err, abr_reg_read_err, abr_reg_write_err; + + abr_reg__in_t abr_reg_hwif_in; + abr_reg__out_t abr_reg_hwif_out; + + mem_if_t zeroize_mem; + logic zeroize_mem_we; + logic zeroize_mem_re; + logic [ABR_MEM_ADDR_WIDTH-1:0] zeroize_mem_addr; + + //memory interfaces + abr_sram_if #(.ADDR_W(SK_MEM_BANK_ADDR_W), .DATA_W(SK_MEM_BANK_DATA_W)) sk_bank0_mem_if(); + abr_sram_if #(.ADDR_W(SK_MEM_BANK_ADDR_W), .DATA_W(SK_MEM_BANK_DATA_W)) sk_bank1_mem_if(); + abr_sram_be_if #(.ADDR_W(SIG_Z_MEM_ADDR_W), .DATA_W(SIG_Z_MEM_DATA_W)) sig_z_mem_if(); + abr_sram_be_if #(.ADDR_W(PK_MEM_ADDR_W), .DATA_W(PK_MEM_DATA_W)) pk_mem_if(); + + `ifdef MLDSA_MASKING + assign ntt_rand_bits = rand_bits[RND_W-1:6]; + `else + assign ntt_rand_bits = (RND_W-6)'(0); + `endif + + abr_ahb_slv_sif #( + .AHB_ADDR_WIDTH(AHB_ADDR_WIDTH), + .AHB_DATA_WIDTH(AHB_DATA_WIDTH), + .CLIENT_DATA_WIDTH(CLIENT_DATA_WIDTH) +) + mldsa_ahb_slv_inst ( + //AMBA AHB Lite INF + .hclk(clk), + .hreset_n(rst_b), + .haddr_i(haddr_i), + .hwdata_i(hwdata_i), + .hsel_i(hsel_i), + .hwrite_i(hwrite_i), + .hready_i(hready_i), + .htrans_i(htrans_i), + .hsize_i(hsize_i), + + .hresp_o(hresp_o), + .hreadyout_o(hreadyout_o), + .hrdata_o(hrdata_o), + + //COMPONENT INF + .dv(abr_reg_dv), + .hld(abr_reg_hold), + .err(abr_reg_err), + .write(abr_reg_write), + .wdata(abr_reg_wdata), + .addr(abr_reg_addr[AHB_ADDR_WIDTH-1:0]), + + .rdata(abr_reg_rdata) +); + +always_comb abr_reg_err = (abr_reg_rd_ack & abr_reg_read_err) | (abr_reg_wr_ack & abr_reg_write_err); +always_comb abr_reg_hold = abr_reg_dv & ~(abr_reg_rd_ack | abr_reg_wr_ack); + +abr_reg abr_reg_inst ( + .clk(clk), + .rst(rst_b), + + .s_cpuif_req(abr_reg_dv), + .s_cpuif_req_is_wr(abr_reg_write), + .s_cpuif_addr(abr_reg_addr[ABR_REG_ADDR_WIDTH-1:0]), + .s_cpuif_wr_data(abr_reg_wdata), + .s_cpuif_wr_biten('1), + .s_cpuif_req_stall_wr(), + .s_cpuif_req_stall_rd(), + .s_cpuif_rd_ack(abr_reg_rd_ack), + .s_cpuif_rd_err(abr_reg_read_err), + .s_cpuif_rd_data(abr_reg_rdata), + .s_cpuif_wr_ack(abr_reg_wr_ack), + .s_cpuif_wr_err(abr_reg_write_err), + + .hwif_in(abr_reg_hwif_in), + .hwif_out(abr_reg_hwif_out) +); + +abr_ctrl abr_ctrl_inst +( + .clk(clk), + .rst_b(rst_b), + .zeroize(zeroize_reg), + + .sk_bank0_mem_if(sk_bank0_mem_if.req), + .sk_bank1_mem_if(sk_bank1_mem_if.req), + .sig_z_mem_if(sig_z_mem_if.req), + .pk_mem_if(pk_mem_if.req), + +`ifdef RV_FPGA_SCA + .NTT_trigger(NTT_trigger), + .PWM_trigger(PWM_trigger), + .PWA_trigger(PWA_trigger), + .INTT_trigger(INTT_trigger), +`endif + +`ifdef CALIPTRA + .kv_read(kv_read), + .kv_rd_resp(kv_rd_resp), + .kv_write(kv_write), + .kv_wr_resp(kv_wr_resp), + .pcr_signing_data(pcr_signing_data), + .ocp_lock_in_progress(ocp_lock_in_progress), +`endif + + //control interface + .abr_reg_hwif_in_o(abr_reg_hwif_in), + .abr_reg_hwif_out_i(abr_reg_hwif_out), + + //sampler interface + .sampler_mode_o(sampler_mode), + .sha3_start_o(sha3_start), //start the sha3 engine + .msg_start_o(msg_start), //start a new message + .msg_valid_o(msg_valid), //msg interface valid + .msg_rdy_i(msg_rdy), //msg interface rdy (~hold) + .msg_strobe_o(msg_strobe), //msg byte enables + .msg_data_o(msg_data), + + .sampler_start_o(sampler_start), + .dest_base_addr_o(dest_base_addr), + + .sampler_state_dv_i(sampler_state_dv), + .sampler_state_data_i(sampler_state_data), + .sampler_busy_i(sampler_busy), + + //ntt interface + .ntt_enable_o(ntt_enable), + .ntt_mode_o(ntt_mode), + .ntt_mem_base_addr_o(ntt_mem_base_addr), + .pwo_mem_base_addr_o(pwo_mem_base_addr), + .ntt_masking_en_o(ntt_masking_en), + .ntt_shuffling_en_o(ntt_shuffling_en), + .ntt_busy_i(ntt_busy), + + //aux interface + .aux_src0_base_addr_o(aux_src0_base_addr), + .aux_src1_base_addr_o(aux_src1_base_addr), + .aux_dest_base_addr_o(aux_dest_base_addr), + + .power2round_enable_o(power2round_enable), + .pwr2rnd_keymem_if_i(pwr2rnd_keymem_if), + .pwr2rnd_wr_data_i(pwr2rnd_wr_data), + .pk_t1_wren_i(pk_t1_wren), + .pk_t1_wr_addr_i(pk_t1_wr_addr), + .pk_t1_wrdata_i(pk_t1_wrdata), + .power2round_done_i(power2round_done), + + .decompose_enable_o(decompose_enable), + .decompose_mode_o(decompose_mode), + .decompose_done_i(decompose_done), + + .skdecode_enable_o(skdecode_enable), + .skdecode_keymem_if_i(skdecode_keymem_if), + .skdecode_rd_data_o(skdecode_rd_data), + .skdecode_done_i(skdecode_done), + .skdecode_error_i(skdecode_error), + + .skencode_enable_o(skencode_enable), + .skencode_keymem_if_i(skencode_keymem_if), + .skencode_wr_data_i(skencode_wr_data), + .skencode_done_i(skencode_done), + + .makehint_enable_o(makehint_enable), + .makehint_invalid_i(makehint_invalid), + .makehint_done_i(makehint_done), + .makehint_reg_wren_i(makehint_reg_wren), + .makehint_reg_wr_addr_i(makehint_reg_wr_addr), + .makehint_reg_wrdata_i(makehint_reg_wrdata), + + .normcheck_enable_o(normcheck_enable), + .normcheck_mode_o(normcheck_mode), + .normcheck_invalid_i(normcheck_invalid), + .normcheck_done_i(normcheck_done), + + .sigencode_enable_o(sigencode_enable), + .sigencode_wr_req_i(sigencode_mem_wr_req), + .sigencode_wr_data_i(sigencode_mem_wr_data), + .sigencode_done_i(sigencode_done), + + .pkdecode_enable_o(pkdecode_enable), + .pkdecode_rd_addr_i(pkdecode_rd_addr), + .pkdecode_rd_data_o(pkdecode_rd_data), + .pkdecode_done_i(pkdecode_done), + + .sigdecode_h_enable_o(sigdecode_h_enable), + .signature_h_o(signature_h), + .sigdecode_h_invalid_i(sigdecode_h_invalid), + .sigdecode_h_done_i(sigdecode_h_done), + + .sigdecode_z_enable_o(sigdecode_z_enable), + .sigdecode_z_rd_req_i(sigdecode_z_mem_rd_req), + .sigdecode_z_rd_data_o(sigdecode_z_mem_rd_data), + .sigdecode_z_done_i(sigdecode_z_done), + + .compress_enable_o(compress_enable), + .compress_mode_o(compress_mode), + .compress_num_poly_o(compress_num_poly), + .compress_compare_mode_o(compress_compare_mode), + .compress_done_i(compress_done), + .compress_compare_failed_i(compress_compare_failed), + .compress_api_rw_en_i(compress_api_rw_en), + .compress_api_rw_addr_i(compress_api_rw_addr), + .compress_api_wr_data_i(compress_api_wr_data), + .compress_api_rd_data_o(compress_api_rd_data), + + .decompress_enable_o(decompress_enable), + .decompress_mode_o(decompress_mode), + .decompress_num_poly_o(decompress_num_poly), + .decompress_done_i(decompress_done), + .decompress_api_rd_en_i(decompress_api_rd_en), + .decompress_api_rd_addr_i(decompress_api_rd_addr), + .decompress_api_rd_data_o(decompress_api_rd_data), + + .lfsr_enable_o(lfsr_enable), + .lfsr_seed_o(lfsr_seed), + + .busy_o(busy_o), + .zeroize_mem_o(zeroize_mem), + + .error_intr(error_intr), + .notif_intr(notif_intr), + .debugUnlock_or_scan_mode_switch(debugUnlock_or_scan_mode_switch) +); + +always_comb zeroize_mem_we = (zeroize_mem.rd_wr_en == RW_WRITE); +//read pulse to clear flopped output after first entry has been zeroized +always_comb zeroize_mem_re = (zeroize_mem_we) && (zeroize_mem.addr == 'd1); +always_comb zeroize_mem_addr = zeroize_mem.addr; + +logic [MsgWidth-1:0] msg_data_i[Sha3Share]; +assign msg_data_i = decomp_msg_valid ? decomp_msg_data : msg_data; + +abr_sampler_top sampler_top_inst +( + .clk(clk), + .rst_b(rst_b), + .zeroize(zeroize_reg), + + .sampler_mode_i(sampler_mode), + .sha3_start_i(sha3_start), //start the sha3 engine + .msg_start_i(msg_start), //start a new message + .msg_valid_i(msg_valid | decomp_msg_valid), + .msg_rdy_o(msg_rdy), + .msg_strobe_i(decomp_msg_valid ? '1 : msg_strobe), + .msg_data_i(msg_data_i), + + .sib_mem_rd_req_i(sib_mem_rd_req), + .sib_mem_rd_data_o(sib_mem_rd_data), + + .sampler_start_i(sampler_start), + .dest_base_addr_i(dest_base_addr), + + .sampler_busy_o(sampler_busy), + + .sampler_ntt_dv_o(sampler_ntt_dv[0]), + .sampler_ntt_data_o(sampler_ntt_data), + + .sampler_mem_dv_o(sampler_mem_dv), + .sampler_mem_data_o(sampler_mem_data), + .sampler_mem_addr_o(sampler_mem_addr), + + .sampler_state_dv_o(sampler_state_dv), + .sampler_state_data_o(sampler_state_data) +); + +//no sampler connect for ntt 1 if present +assign sampler_ntt_dv[1] = 0; + +always_ff @(posedge clk or negedge rst_b) begin + if (!rst_b) begin + sampler_ntt_dv_f <= 0; + end + else if (zeroize_reg) begin + sampler_ntt_dv_f <= 0; + end + else begin + sampler_ntt_dv_f <= sampler_ntt_dv; + end +end + +generate + for (genvar g_inst = 0; g_inst < ABR_NUM_NTT; g_inst++) begin : ntt_gen + //NTT + //gasket here, create common interfaces? + always_comb begin + mode[g_inst] = '0; + accumulate[g_inst] = '0; + sampler_valid[g_inst] = 0; + sampler_ntt_mode[g_inst] = 0; + ntt_random_en[g_inst] = 0; //Turn off random in NTT for all ops except PWM, INTT + mlkem_mode[g_inst] = 0; + + unique case (ntt_mode[g_inst]) inside + ABR_NTT_NONE: begin + end + MLDSA_NTT: begin + mode[g_inst] = ct; + end + MLDSA_INTT: begin + mode[g_inst] = gs; + ntt_random_en[g_inst] = 1; + end + MLDSA_PWM_SMPL: begin + mode[g_inst] = pwm; + sampler_valid[g_inst] = sampler_ntt_dv[g_inst]; + sampler_ntt_mode[g_inst] = 1; + end + MLDSA_PWM_ACCUM_SMPL: begin + mode[g_inst] = pwm; + accumulate[g_inst] = 1; + sampler_valid[g_inst] = sampler_ntt_dv[g_inst]; + sampler_ntt_mode[g_inst] = 1; + end + MLDSA_PWM: begin + mode[g_inst] = pwm; + sampler_valid[g_inst] = 1; + ntt_random_en[g_inst] = 1; + end + MLDSA_PWM_ACCUM: begin + mode[g_inst] = pwm; + accumulate[g_inst] = 1; + sampler_valid[g_inst] = 1; + ntt_random_en[g_inst] = 1; + end + MLDSA_PWA: begin + mode[g_inst] = pwa; + sampler_valid[g_inst] = 1; + end + MLDSA_PWS: begin + mode[g_inst] = pws; + sampler_valid[g_inst] = 1; + end + MLKEM_NTT: begin + mode[g_inst] = ct; + mlkem_mode[g_inst] = 1; + end + MLKEM_INTT: begin + mode[g_inst] = gs; + ntt_random_en[g_inst] = 1; + mlkem_mode[g_inst] = 1; + end + MLKEM_PWM_SMPL: begin + mode[g_inst] = pairwm; + sampler_valid[g_inst] = sampler_ntt_dv[g_inst]; + sampler_ntt_mode[g_inst] = 1; + mlkem_mode[g_inst] = 1; + end + MLKEM_PWM_ACCUM_SMPL: begin + mode[g_inst] = pairwm; + accumulate[g_inst] = 1; + sampler_valid[g_inst] = sampler_ntt_dv[g_inst]; + sampler_ntt_mode[g_inst] = 1; + mlkem_mode[g_inst] = 1; + end + MLKEM_PWM: begin + mode[g_inst] = pairwm; + sampler_valid[g_inst] = 1; + ntt_random_en[g_inst] = 1; + mlkem_mode[g_inst] = 1; + end + MLKEM_PWM_ACCUM: begin + mode[g_inst] = pairwm; + accumulate[g_inst] = 1; + sampler_valid[g_inst] = 1; + ntt_random_en[g_inst] = 1; + mlkem_mode[g_inst] = 1; + end + MLKEM_PWA: begin + mode[g_inst] = pwa; + sampler_valid[g_inst] = 1; + mlkem_mode[g_inst] = 1; + end + MLKEM_PWS: begin + mode[g_inst] = pws; + sampler_valid[g_inst] = 1; + mlkem_mode[g_inst] = 1; + end + default: begin + end + endcase + + + end + + ntt_top #( + .REG_SIZE(REG_SIZE), + .MLDSA_Q(MLDSA_Q), + .MLDSA_N(MLDSA_N), + .MEM_ADDR_WIDTH(ABR_MEM_ADDR_WIDTH) + ) + ntt_top_inst ( + .clk(clk), + .reset_n(rst_b), + .zeroize(zeroize_reg), + + .mode(mode[g_inst]), + .ntt_enable(ntt_enable[g_inst]), + .mlkem(mlkem_mode[g_inst]), + .ntt_mem_base_addr(ntt_mem_base_addr[g_inst]), + .pwo_mem_base_addr(pwo_mem_base_addr[g_inst]), + .accumulate(accumulate[g_inst]), + .sampler_valid(sampler_valid[g_inst]), + .shuffle_en(ntt_shuffling_en[g_inst]), + .random(rand_bits[5:0]), + .masking_en(ntt_masking_en[g_inst]), + .rnd_i(ntt_random_en[g_inst] ? ntt_rand_bits : (RND_W-6)'(0)), //(ntt_rand_bits & {(RND_W-6){ntt_random_en[g_inst]}}), + //NTT mem IF + .mem_wr_req(ntt_mem_wr_req[g_inst]), + .mem_rd_req(ntt_mem_rd_req[g_inst]), + .mem_wr_data(ntt_mem_wr_data[g_inst]), + .mem_rd_data(ntt_mem_rd_data[g_inst]), + //PWM mem IF + .pwm_a_rd_req(pwm_a_rd_req[g_inst]), + .pwm_b_rd_req(pwm_b_rd_req[g_inst]), + .pwm_a_rd_data(pwm_a_rd_data[g_inst]), + .pwm_b_rd_data(sampler_ntt_mode[g_inst] ? ABR_MEM_MASKED_DATA_WIDTH'(sampler_ntt_data) : pwm_b_rd_data[g_inst]), + .ntt_busy(ntt_busy[g_inst]), + .ntt_done() + ); + end +endgenerate + +//aux functions +power2round_top +power2round_inst ( + .clk(clk), + .reset_n(rst_b), + .zeroize(zeroize_reg), + + .enable(power2round_enable), + .done(power2round_done), + + .src_base_addr(aux_src0_base_addr), + .mem_a_rd_req(pwr2rnd_mem_rd_req[0]), + .mem_rd_data_a(pwr2rnd_mem_rd_data[0]), + .mem_b_rd_req(pwr2rnd_mem_rd_req[1]), + .mem_rd_data_b(pwr2rnd_mem_rd_data[1]), + + .pk_t1_wren(pk_t1_wren), + .pk_t1_wr_addr(pk_t1_wr_addr), + .pk_t1_wrdata(pk_t1_wrdata), + + .skmem_dest_base_addr(aux_dest_base_addr), + .skmem_a_wr_req(pwr2rnd_keymem_if[0]), + .skmem_wr_data_a(pwr2rnd_wr_data[0]), + .skmem_b_wr_req(pwr2rnd_keymem_if[1]), + .skmem_wr_data_b(pwr2rnd_wr_data[1]) +); + +decompose +decompose_inst ( + .clk(clk), + .reset_n(rst_b), + .zeroize(zeroize_reg), + + .decompose_enable(decompose_enable), + .dcmp_mode(decompose_mode), + .src_base_addr(aux_src0_base_addr), + .dest_base_addr(aux_dest_base_addr), + .hint_src_base_addr(aux_src1_base_addr), + + //Output to memory - r0 + .mem_rd_req(decomp_mem_rd_req[0]), + .mem_wr_req(decomp_mem_wr_req), + .mem_rd_data(decomp_mem_rd_data[0]), + .mem_wr_data(decomp_mem_wr_data), + + //Output to memory - h (sigDecode) + .mem_hint_rd_req(decomp_mem_rd_req[1]), + .mem_hint_rd_data(decomp_mem_rd_data[1]), + + //Output to z mem - z != 0 + .z_mem_wr_req(w1_mem_wr_req), + .z_neq_z(w1_mem_wr_data), + + //Output of w1_encode - r1 + .w1_o(decomp_msg_data[0]), + .buffer_en(decomp_msg_valid), + + .decompose_done(decompose_done) +); + +skencode +#( + .MEM_ADDR_WIDTH(ABR_MEM_ADDR_WIDTH) +) +skencode_inst +( + .clk(clk), + .reset_n(rst_b), + .zeroize(zeroize_reg), + + .src_base_addr(aux_src0_base_addr), + .dest_base_addr(aux_dest_base_addr), + + .skencode_enable(skencode_enable), + .skencode_done(skencode_done), + + .keymem_a_wr_req(skencode_keymem_if), + .keymem_a_wr_data(skencode_wr_data), + .mem_a_rd_req(skencode_mem_rd_req[0]), + .mem_a_rd_data(skencode_mem_rd_data[0]), + .mem_b_rd_req(skencode_mem_rd_req[1]), + .mem_b_rd_data(skencode_mem_rd_data[1]) +); + +skdecode_top +skdecode_inst +( + .clk(clk), + .reset_n(rst_b), + .zeroize(zeroize_reg), + + .skdecode_enable(skdecode_enable), + .skdecode_done(skdecode_done), + + .keymem_src_base_addr(aux_src0_base_addr), + .dest_base_addr(aux_dest_base_addr), + + .keymem_a_rd_req(skdecode_keymem_if[0]), + .keymem_a_rd_data(skdecode_rd_data[0]), + .keymem_b_rd_req(skdecode_keymem_if[1]), + .keymem_b_rd_data(skdecode_rd_data[1]), + + .mem_a_wr_req(skdecode_mem_wr_req[0]), + .mem_a_wr_data(skdecode_mem_wr_data[0]), + .mem_b_wr_req(skdecode_mem_wr_req[1]), + .mem_b_wr_data(skdecode_mem_wr_data[1]), + + .s1_done(), + .s2_done(), + .t0_done(), + .skdecode_error(skdecode_error) +); + +makehint +makehint_inst +( + .clk(clk), + .reset_n(rst_b), + .zeroize(zeroize_reg), + + .makehint_enable(makehint_enable), + .makehint_done(makehint_done), + + .mem_base_addr(aux_src0_base_addr), + + .mem_rd_req(makehint_mem_rd_req), + .r(makehint_mem_rd_data), + + .reg_wren(makehint_reg_wren), + .reg_wr_addr(makehint_reg_wr_addr), + .reg_wrdata(makehint_reg_wrdata), + + .z_rd_req(w1_mem_rd_req), + .z(w1_mem_rd_data), + + .invalid_h(makehint_invalid) +); + +norm_check_top +norm_check_inst +( + .clk(clk), + .reset_n(rst_b), + .zeroize(zeroize_reg), + + .mode(normcheck_mode), + .norm_check_enable(normcheck_enable), + + .randomness(rand_bits[5:0]), + + .norm_check_ready(), + .norm_check_done(normcheck_done), + + .mem_base_addr(aux_src0_base_addr), + .mem_rd_req(normcheck_mem_rd_req), + .mem_rd_data(normcheck_mem_rd_data), + + .invalid(normcheck_invalid) + +); + +sigencode_z_top +sigencode_z_inst +( + .clk(clk), + .reset_n(rst_b), + .zeroize(zeroize_reg), + + .sigencode_z_enable(sigencode_enable), + .sigencode_z_done(sigencode_done), + + .src_base_addr(aux_src0_base_addr), + .sigmem_dest_base_addr(aux_dest_base_addr), + + .mem_a_rd_req(sigencode_mem_rd_req[0]), + .mem_a_rd_data(sigencode_mem_rd_data[0]), + .mem_b_rd_req(sigencode_mem_rd_req[1]), + .mem_b_rd_data(sigencode_mem_rd_data[1]), + + .sigmem_a_wr_req(sigencode_mem_wr_req), + .sigmem_a_wr_data(sigencode_mem_wr_data[0]), + .sigmem_b_wr_req(), + .sigmem_b_wr_data(sigencode_mem_wr_data[1]) +); + +pkdecode +#( + .API_ADDR_WIDTH(8) +) +pkdecode_inst ( + .clk(clk), + .reset_n(rst_b), + .zeroize(zeroize_reg), + + .pkdecode_enable(pkdecode_enable), + .pkdecode_done(pkdecode_done), + + .dest_base_addr(aux_dest_base_addr), + + .API_rd_address(pkdecode_rd_addr), + .API_rd_data(pkdecode_rd_data), + + .mem_a_wr_req(pkdecode_mem_wr_req[0]), + .mem_a_wr_data(pkdecode_mem_wr_data[0]), + .mem_b_wr_req(pkdecode_mem_wr_req[1]), + .mem_b_wr_data(pkdecode_mem_wr_data[1]) +); + +sigdecode_z_top +sigdecode_z_inst ( + .clk(clk), + .reset_n(rst_b), + .zeroize(zeroize_reg), + + .sigdecode_z_enable(sigdecode_z_enable), + .sigdecode_z_done(sigdecode_z_done), + + .dest_base_addr(aux_dest_base_addr), + + .mem_a_wr_req(sigdecode_z_mem_wr_req[0]), + .mem_a_wr_data(sigdecode_z_mem_wr_data[0]), + .mem_b_wr_req(sigdecode_z_mem_wr_req[1]), + .mem_b_wr_data(sigdecode_z_mem_wr_data[1]), + + .sigmem_a_rd_req(sigdecode_z_mem_rd_req), + .sigmem_a_rd_data(sigdecode_z_mem_rd_data[0]), + .sigmem_b_rd_req(), + .sigmem_b_rd_data(sigdecode_z_mem_rd_data[1]) +); + +sigdecode_h +sigdecode_h_inst ( + .clk(clk), + .reset_n(rst_b), + .zeroize(zeroize_reg), + + .sigdecode_h_enable(sigdecode_h_enable), + .sigdecode_h_done(sigdecode_h_done), + + .dest_base_addr(aux_dest_base_addr), + + .encoded_h_i(signature_h), + .mem_wr_req(sigdecode_h_mem_wr_req), + .mem_wr_data(sigdecode_h_mem_wr_data), + + .sigdecode_h_error(sigdecode_h_invalid) +); + +compress_top +compress_top_inst +( + .clk(clk), + .reset_n(rst_b), + .zeroize(zeroize_reg), + + .mode(compress_mode), + .compare_mode(compress_compare_mode), + .num_poly(compress_num_poly), + .src_base_addr(aux_src0_base_addr), + .dest_base_addr(aux_dest_base_addr), + + .compress_enable(compress_enable), + .compress_done(compress_done), + .compare_failed(compress_compare_failed), + + .mem_rd_req(compress_mem_rd_req), + .mem_rd_data(compress_mem_rd_data), + + .api_rw_en(compress_api_rw_en), + .api_rw_addr(compress_api_rw_addr), + .api_wr_data(compress_api_wr_data), + .api_rd_data(compress_api_rd_data) +); + +decompress_top +decompress_top_inst +( + .clk(clk), + .reset_n(rst_b), + .zeroize(zeroize_reg), + + .mode(decompress_mode), + .num_poly(decompress_num_poly), + .src_base_addr(aux_src0_base_addr), + .dest_base_addr(aux_dest_base_addr), + + .decompress_enable(decompress_enable), + .decompress_done(decompress_done), + + .mem_wr_req(decompress_mem_wr_req), + .mem_wr_data(decompress_mem_wr_data), + .api_rd_en(decompress_api_rd_en), + .api_rd_addr(decompress_api_rd_addr), + .api_rd_data(decompress_api_rd_data) +); + +abr_prim_lfsr +#( + .LfsrType("FIB_XNOR"), + .LfsrDw(LFSR_W), + .StateOutDw(LFSR_W) +) abr_prim_lfsr_inst0 +( + .clk_i(clk), + .rst_b(rst_b), + .seed_en_i(lfsr_enable), + .seed_i(lfsr_seed[0]), + .lfsr_en_i(1'b1), + .entropy_i('0), + .state_o(rand_bits[LFSR_W-1:0]) +); + +abr_prim_lfsr +#( + .LfsrType("FIB_XNOR"), + .LfsrDw(LFSR_W), + .StateOutDw(LFSR_W) +) abr_prim_lfsr_inst1 +( + .clk_i(clk), + .rst_b(rst_b), + .seed_en_i(lfsr_enable), + .seed_i(lfsr_seed[1]), + .lfsr_en_i(1'b1), + .entropy_i('0), + .state_o(rand_bits[RND_W-1 : LFSR_W]) +); + +always_comb begin + abr_memory_export.w1_mem_we_i = (w1_mem_wr_req.rd_wr_en == RW_WRITE) | zeroize_mem_we; + abr_memory_export.w1_mem_waddr_i = (w1_mem_wr_req.addr[ABR_MEM_W1_ADDR_W-1:0]) | + ({ABR_MEM_W1_ADDR_W{zeroize_mem_we}} & zeroize_mem_addr[ABR_MEM_W1_ADDR_W-1:0]); + abr_memory_export.w1_mem_wdata_i = zeroize_mem_we ? '0 : w1_mem_wr_data; + abr_memory_export.w1_mem_re_i = w1_mem_rd_req.rd_wr_en == RW_READ; + abr_memory_export.w1_mem_raddr_i = w1_mem_rd_req.addr[ABR_MEM_W1_ADDR_W-1:0]; + w1_mem_rd_data = abr_memory_export.w1_mem_rdata_o; +end + +//Decode request to sample in ball memory +logic [ABR_NUM_NTT-1:0] sib_mem_re, sib_mem_re_f; +always_comb begin + sib_mem_rd_req.addr = '0; + for (int ntt = 0; ntt < ABR_NUM_NTT; ntt++) begin + sib_mem_re[ntt] = (ntt_mem_rd_req[ntt].rd_wr_en == RW_READ) & (ntt_mem_rd_req[ntt].addr[ABR_MEM_ADDR_WIDTH-1:ABR_MEM_ADDR_WIDTH-3] == 3'b100); + + sib_mem_rd_req.addr |= {ABR_MEM_ADDR_WIDTH{sib_mem_re[ntt]}} & ntt_mem_rd_req[ntt].addr; + end + //if any request, set to read else idle + sib_mem_rd_req.rd_wr_en = |sib_mem_re ? RW_READ : RW_IDLE; +end + + +//MUX memory accesses +logic [3:1] abr_mem_re; +logic [3:1][ABR_MEM_ADDR_WIDTH-4:0] abr_mem_raddr; +logic [2:1][ABR_MEM_DATA_WIDTH-1:0] abr_mem_rdata; +logic [3:3][ABR_MEM_MASKED_DATA_WIDTH-1:0] abr_mem_masked_rdata; +logic [1:0] abr_mem_re0_bank; +logic [1:0][ABR_MEM_ADDR_WIDTH-5:0] abr_mem_raddr0_bank; +logic [1:0][ABR_MEM_DATA_WIDTH-1:0] abr_mem_rdata0_bank; +logic [3:1] abr_mem_we; +logic [3:1][ABR_MEM_ADDR_WIDTH-4:0] abr_mem_waddr; +logic [2:1][ABR_MEM_DATA_WIDTH-1:0] abr_mem_wdata; +logic [3:3][ABR_MEM_MASKED_DATA_WIDTH-1:0] abr_mem_masked_wdata; +logic [1:0] abr_mem_we0_bank; +logic [1:0][ABR_MEM_ADDR_WIDTH-5:0] abr_mem_waddr0_bank; +logic [1:0][ABR_MEM_DATA_WIDTH-1:0] abr_mem_wdata0_bank; + +logic [3:1] sampler_mem_we; +logic [ABR_NUM_NTT-1:0][3:0] ntt_mem_we; +logic [3:0] ntt_mem_we_mux; +logic [1:0] ntt_mem_we0_bank; +logic [3:1] decomp_mem_we; +logic [1:0] sampler_mem_we0_bank; +logic [1:0] decomp_mem_we0_bank; +logic [1:0] skdecode_mem_we0_bank; +logic [1:0] pkdecode_mem_we0_bank; +logic [1:0] sigdecode_z_mem_we0_bank; +logic [3:1] sigdecode_h_mem_we; +logic [1:0] sigdecode_h_mem_we0_bank; +logic [1:0] decompress_mem_we0_bank; + +logic [ABR_NUM_NTT-1:0][3:0] ntt_mem_re,ntt_mem_re_f; +logic [ABR_NUM_NTT-1:0][3:0] pwo_a_mem_re,pwo_a_mem_re_f; +logic [ABR_NUM_NTT-1:0][3:0] pwo_b_mem_re,pwo_b_mem_re_f; +logic [3:0] ntt_mem_re_mux; +logic [3:0] pwo_a_mem_re_mux; +logic [3:0] pwo_b_mem_re_mux; +logic [1:0][3:1] decomp_mem_re,decomp_mem_re_f; +logic [3:1] normcheck_mem_re,normcheck_mem_re_f; +logic [3:1] compress_mem_re,compress_mem_re_f; +logic [3:1] makehint_mem_re; +logic [ABR_NUM_NTT-1:0][1:0] ntt_mem_re0_bank,ntt_mem_re0_bank_f; +logic [ABR_NUM_NTT-1:0][1:0] pwo_a_mem_re0_bank,pwo_a_mem_re0_bank_f; +logic [ABR_NUM_NTT-1:0][1:0] pwo_b_mem_re0_bank,pwo_b_mem_re0_bank_f; +logic [1:0] ntt_mem_re0_bank_mux; +logic [1:0] pwo_a_mem_re0_bank_mux; +logic [1:0] pwo_b_mem_re0_bank_mux; +logic [1:0][1:0] decomp_mem_re0_bank,decomp_mem_re0_bank_f; +logic [1:0] normcheck_mem_re0_bank,normcheck_mem_re0_bank_f; +logic [1:0] compress_mem_re0_bank,compress_mem_re0_bank_f; +logic [1:0] skencode_mem_re0_bank; +logic [1:0] sigencode_mem_re0_bank; +logic [1:0] pwr2rnd_mem_re0_bank; + +//NTT Muxes +always_comb begin + ntt_mem_we_mux = '0; + ntt_mem_re_mux = '0; + pwo_a_mem_re_mux = '0; + pwo_b_mem_re_mux = '0; + ntt_mem_wr_req_mux = '0; + ntt_mem_wr_data_mux = '0; + ntt_mem_rd_req_mux = '0; + pwm_a_rd_req_mux = '0; + pwm_b_rd_req_mux = '0; + for (int ntt= 0; ntt < ABR_NUM_NTT; ntt++) begin + for (int i = 0; i < 4; i++) begin + ntt_mem_we[ntt][i] = (ntt_mem_wr_req[ntt].rd_wr_en == RW_WRITE) & (ntt_mem_wr_req[ntt].addr[ABR_MEM_ADDR_WIDTH-1:ABR_MEM_ADDR_WIDTH-3] == i[2:0]); + ntt_mem_re[ntt][i] = (ntt_mem_rd_req[ntt].rd_wr_en == RW_READ) & (ntt_mem_rd_req[ntt].addr[ABR_MEM_ADDR_WIDTH-1:ABR_MEM_ADDR_WIDTH-3] == i[2:0]); + pwo_a_mem_re[ntt][i] = (pwm_a_rd_req[ntt].rd_wr_en == RW_READ) & (pwm_a_rd_req[ntt].addr[ABR_MEM_ADDR_WIDTH-1:ABR_MEM_ADDR_WIDTH-3] == i[2:0]); + pwo_b_mem_re[ntt][i] = (ntt_shuffling_en[ntt] ? ~sampler_ntt_dv_f[ntt] : ~sampler_ntt_dv[ntt]) & (pwm_b_rd_req[ntt].rd_wr_en == RW_READ) & (pwm_b_rd_req[ntt].addr[ABR_MEM_ADDR_WIDTH-1:ABR_MEM_ADDR_WIDTH-3] == i[2:0]); + + ntt_mem_we_mux[i] |= ntt_mem_we[ntt][i]; + ntt_mem_re_mux[i] |= ntt_mem_re[ntt][i]; + pwo_a_mem_re_mux[i] |= pwo_a_mem_re[ntt][i]; + pwo_b_mem_re_mux[i] |= pwo_b_mem_re[ntt][i]; + + ntt_mem_wr_req_mux[i] |= ({ABR_MEM_ADDR_WIDTH{ntt_mem_we[ntt][i]}} & ntt_mem_wr_req[ntt].addr); + ntt_mem_rd_req_mux[i] |= ({ABR_MEM_ADDR_WIDTH{ntt_mem_re[ntt][i]}} & ntt_mem_rd_req[ntt].addr); + pwm_a_rd_req_mux[i] |= ({ABR_MEM_ADDR_WIDTH{pwo_a_mem_re[ntt][i]}} & pwm_a_rd_req[ntt].addr); + pwm_b_rd_req_mux[i] |= ({ABR_MEM_ADDR_WIDTH{pwo_b_mem_re[ntt][i]}} & pwm_b_rd_req[ntt].addr); + end + + for (int i = 0; i < 3; i++) begin + ntt_mem_wr_data_mux[i] |= ({ABR_MEM_DATA_WIDTH{ntt_mem_we[ntt][i]}} & ntt_mem_wr_data[ntt][ABR_MEM_DATA_WIDTH-1:0]); + end + end +end + +//Write Muxes +always_comb begin + for (int i = 0; i < 4; i++) begin + if (i == 0) begin + for (int bank = 0; bank < 2; bank++) begin + ntt_mem_we0_bank[bank] = ntt_mem_we_mux[i] & (ntt_mem_wr_req_mux[i][0] == bank); + sampler_mem_we0_bank[bank] = sampler_mem_dv & (sampler_mem_addr[ABR_MEM_ADDR_WIDTH-1:ABR_MEM_ADDR_WIDTH-3] == i[2:0]) & (sampler_mem_addr[0] == bank); + decomp_mem_we0_bank[bank] = (decomp_mem_wr_req.rd_wr_en == RW_WRITE) & (decomp_mem_wr_req.addr[ABR_MEM_ADDR_WIDTH-1:ABR_MEM_ADDR_WIDTH-3] == i[2:0]) & (decomp_mem_wr_req.addr[0] == bank); + sigdecode_h_mem_we0_bank[bank] = (sigdecode_h_mem_wr_req.rd_wr_en == RW_WRITE) & (sigdecode_h_mem_wr_req.addr[ABR_MEM_ADDR_WIDTH-1:ABR_MEM_ADDR_WIDTH-3] == i[2:0]) & (sigdecode_h_mem_wr_req.addr[0] == bank); + skdecode_mem_we0_bank[bank] = (skdecode_mem_wr_req[bank].rd_wr_en == RW_WRITE); + pkdecode_mem_we0_bank[bank] = (pkdecode_mem_wr_req[bank].rd_wr_en == RW_WRITE); + sigdecode_z_mem_we0_bank[bank] = (sigdecode_z_mem_wr_req[bank].rd_wr_en == RW_WRITE); + decompress_mem_we0_bank[bank] = (decompress_mem_wr_req.rd_wr_en == RW_WRITE) & (decompress_mem_wr_req.addr[ABR_MEM_ADDR_WIDTH-1:ABR_MEM_ADDR_WIDTH-3] == i[2:0]) & (decompress_mem_wr_req.addr[0] == bank); + + abr_mem_we0_bank[bank] = sampler_mem_we0_bank[bank] | ntt_mem_we0_bank[bank] | decompress_mem_we0_bank[bank] | + decomp_mem_we0_bank[bank] | skdecode_mem_we0_bank[bank] | pkdecode_mem_we0_bank[bank] | + sigdecode_h_mem_we0_bank[bank] | sigdecode_z_mem_we0_bank[bank] | zeroize_mem_we; + + abr_mem_waddr0_bank[bank] = ({ABR_MEM_ADDR_WIDTH-4{sampler_mem_we0_bank[bank]}} & sampler_mem_addr[ABR_MEM_ADDR_WIDTH-4:1]) | + ({ABR_MEM_ADDR_WIDTH-4{ntt_mem_we0_bank[bank]}} & ntt_mem_wr_req_mux[0][ABR_MEM_ADDR_WIDTH-4:1]) | + ({ABR_MEM_ADDR_WIDTH-4{decomp_mem_we0_bank[bank]}} & decomp_mem_wr_req.addr[ABR_MEM_ADDR_WIDTH-4:1]) | + ({ABR_MEM_ADDR_WIDTH-4{decompress_mem_we0_bank[bank]}} & decompress_mem_wr_req.addr[ABR_MEM_ADDR_WIDTH-4:1]) | + ({ABR_MEM_ADDR_WIDTH-4{sigdecode_h_mem_we0_bank[bank]}} & sigdecode_h_mem_wr_req.addr[ABR_MEM_ADDR_WIDTH-4:1]) | + ({ABR_MEM_ADDR_WIDTH-4{skdecode_mem_we0_bank[bank]}} & skdecode_mem_wr_req[bank].addr[ABR_MEM_ADDR_WIDTH-4:1]) | + ({ABR_MEM_ADDR_WIDTH-4{pkdecode_mem_we0_bank[bank]}} & pkdecode_mem_wr_req[bank].addr[ABR_MEM_ADDR_WIDTH-4:1]) | + ({ABR_MEM_ADDR_WIDTH-4{sigdecode_z_mem_we0_bank[bank]}} & sigdecode_z_mem_wr_req[bank].addr[ABR_MEM_ADDR_WIDTH-4:1]) | + ({ABR_MEM_ADDR_WIDTH-4{zeroize_mem_we}} & (zeroize_mem_addr[ABR_MEM_ADDR_WIDTH-5:0])); + + abr_mem_wdata0_bank[bank] = ({ABR_MEM_DATA_WIDTH{sampler_mem_we0_bank[bank]}} & sampler_mem_data) | + ({ABR_MEM_DATA_WIDTH{ntt_mem_we0_bank[bank]}} & ntt_mem_wr_data_mux[0][ABR_MEM_DATA_WIDTH-1:0]) | + ({ABR_MEM_DATA_WIDTH{decomp_mem_we0_bank[bank]}} & decomp_mem_wr_data) | + ({ABR_MEM_DATA_WIDTH{decompress_mem_we0_bank[bank]}} & decompress_mem_wr_data) | + ({ABR_MEM_DATA_WIDTH{sigdecode_h_mem_we0_bank[bank]}} & sigdecode_h_mem_wr_data) | + ({ABR_MEM_DATA_WIDTH{skdecode_mem_we0_bank[bank]}} & skdecode_mem_wr_data[bank]) | + ({ABR_MEM_DATA_WIDTH{pkdecode_mem_we0_bank[bank]}} & pkdecode_mem_wr_data[bank]) | + ({ABR_MEM_DATA_WIDTH{sigdecode_z_mem_we0_bank[bank]}} & sigdecode_z_mem_wr_data[bank]); + end + end else begin + sampler_mem_we[i] = sampler_mem_dv & (sampler_mem_addr[ABR_MEM_ADDR_WIDTH-1:ABR_MEM_ADDR_WIDTH-3] == i[2:0]); + decomp_mem_we[i] = (decomp_mem_wr_req.rd_wr_en == RW_WRITE) & (decomp_mem_wr_req.addr[ABR_MEM_ADDR_WIDTH-1:ABR_MEM_ADDR_WIDTH-3] == i[2:0]); + sigdecode_h_mem_we[i] = (sigdecode_h_mem_wr_req.rd_wr_en == RW_WRITE) & (sigdecode_h_mem_wr_req.addr[ABR_MEM_ADDR_WIDTH-1:ABR_MEM_ADDR_WIDTH-3] == i[2:0]); + + abr_mem_we[i] = sampler_mem_we[i] | ntt_mem_we_mux[i] | decomp_mem_we[i] | sigdecode_h_mem_we[i] | zeroize_mem_we; + abr_mem_waddr[i] = ({ABR_MEM_ADDR_WIDTH-3{sampler_mem_we[i]}} & sampler_mem_addr[ABR_MEM_ADDR_WIDTH-4:0]) | + ({ABR_MEM_ADDR_WIDTH-3{ntt_mem_we_mux[i]}} & ntt_mem_wr_req_mux[i][ABR_MEM_ADDR_WIDTH-4:0]) | + ({ABR_MEM_ADDR_WIDTH-3{decomp_mem_we[i]}} & decomp_mem_wr_req.addr[ABR_MEM_ADDR_WIDTH-4:0]) | + ({ABR_MEM_ADDR_WIDTH-3{sigdecode_h_mem_we[i]}} & sigdecode_h_mem_wr_req.addr[ABR_MEM_ADDR_WIDTH-4:0]) | + ({ABR_MEM_ADDR_WIDTH-3{zeroize_mem_we}} & zeroize_mem_addr[ABR_MEM_ADDR_WIDTH-4:0]); + + end + end +end + +//Write Data Muxes +always_comb begin + for (int i = 1; i < ABR_MEM_MASKED_INST; i++) begin + abr_mem_wdata[i] = ({ABR_MEM_DATA_WIDTH{sampler_mem_we[i]}} & sampler_mem_data) | + ({ABR_MEM_DATA_WIDTH{ntt_mem_we_mux[i]}} & ntt_mem_wr_data_mux[i][ABR_MEM_DATA_WIDTH-1:0]) | + ({ABR_MEM_DATA_WIDTH{decomp_mem_we[i]}} & decomp_mem_wr_data) | + ({ABR_MEM_DATA_WIDTH{sigdecode_h_mem_we[i]}} & sigdecode_h_mem_wr_data); + end + abr_mem_masked_wdata = '0; + for (int ntt= 0; ntt < ABR_NUM_NTT; ntt++) begin + abr_mem_masked_wdata[ABR_MEM_MASKED_INST] |= ({ABR_MEM_MASKED_DATA_WIDTH{ntt_mem_we[ntt][ABR_MEM_MASKED_INST]}} & ntt_mem_wr_data[ntt]); + end +end + +//Read Muxes +always_comb begin + for (int i = 0; i < 4; i++) begin + if (i == 0) begin + ntt_mem_re0_bank_mux = '0; + pwo_a_mem_re0_bank_mux = '0; + pwo_b_mem_re0_bank_mux = '0; + for (int bank = 0; bank < 2; bank++) begin + for (int ntt = 0; ntt < ABR_NUM_NTT; ntt++) begin + ntt_mem_re0_bank[ntt][bank] = (ntt_mem_rd_req[ntt].rd_wr_en == RW_READ) & (ntt_mem_rd_req[ntt].addr[ABR_MEM_ADDR_WIDTH-1:ABR_MEM_ADDR_WIDTH-3] == i[2:0]) & (ntt_mem_rd_req[ntt].addr[0] == bank); + pwo_a_mem_re0_bank[ntt][bank] = (pwm_a_rd_req[ntt].rd_wr_en == RW_READ) & (pwm_a_rd_req[ntt].addr[ABR_MEM_ADDR_WIDTH-1:ABR_MEM_ADDR_WIDTH-3] == i[2:0]) & (pwm_a_rd_req[ntt].addr[0] == bank); + pwo_b_mem_re0_bank[ntt][bank] = (ntt_shuffling_en[ntt] ? ~sampler_ntt_dv_f[ntt] : ~sampler_ntt_dv[ntt]) & (pwm_b_rd_req[ntt].rd_wr_en == RW_READ) & (pwm_b_rd_req[ntt].addr[ABR_MEM_ADDR_WIDTH-1:ABR_MEM_ADDR_WIDTH-3] == i[2:0]) & (pwm_b_rd_req[ntt].addr[0] == bank); + ntt_mem_re0_bank_mux[bank] |= ntt_mem_re0_bank[ntt][bank]; + pwo_a_mem_re0_bank_mux[bank] |= pwo_a_mem_re0_bank[ntt][bank]; + pwo_b_mem_re0_bank_mux[bank] |= pwo_b_mem_re0_bank[ntt][bank]; + end + + decomp_mem_re0_bank[0][bank] = (decomp_mem_rd_req[0].rd_wr_en == RW_READ) & (decomp_mem_rd_req[0].addr[ABR_MEM_ADDR_WIDTH-1:ABR_MEM_ADDR_WIDTH-3] == i[2:0]) & (decomp_mem_rd_req[0].addr[0] == bank); + decomp_mem_re0_bank[1][bank] = (decomp_mem_rd_req[1].rd_wr_en == RW_READ) & (decomp_mem_rd_req[1].addr[ABR_MEM_ADDR_WIDTH-1:ABR_MEM_ADDR_WIDTH-3] == i[2:0]) & (decomp_mem_rd_req[1].addr[0] == bank); + normcheck_mem_re0_bank[bank] = (normcheck_mem_rd_req.rd_wr_en == RW_READ) & (normcheck_mem_rd_req.addr[ABR_MEM_ADDR_WIDTH-1:ABR_MEM_ADDR_WIDTH-3] == i[2:0]) & (normcheck_mem_rd_req.addr[0] == bank); + compress_mem_re0_bank[bank] = (compress_mem_rd_req.rd_wr_en == RW_READ) & (compress_mem_rd_req.addr[ABR_MEM_ADDR_WIDTH-1:ABR_MEM_ADDR_WIDTH-3] == i[2:0]) & (compress_mem_rd_req.addr[0] == bank); + skencode_mem_re0_bank[bank] = (skencode_mem_rd_req[bank].rd_wr_en == RW_READ); + sigencode_mem_re0_bank[bank] = (sigencode_mem_rd_req[bank].rd_wr_en == RW_READ); + pwr2rnd_mem_re0_bank[bank] = (pwr2rnd_mem_rd_req[bank].rd_wr_en == RW_READ); + + abr_mem_re0_bank[bank] = ntt_mem_re0_bank_mux[bank] | pwo_a_mem_re0_bank_mux[bank] | pwo_b_mem_re0_bank_mux[bank] | + decomp_mem_re0_bank[0][bank] | decomp_mem_re0_bank[1][bank] | + skencode_mem_re0_bank[bank] | normcheck_mem_re0_bank[bank] | + sigencode_mem_re0_bank[bank] | pwr2rnd_mem_re0_bank[bank] | + compress_mem_re0_bank[bank]; + abr_mem_raddr0_bank[bank] = ({ABR_MEM_ADDR_WIDTH-4{ntt_mem_re0_bank_mux[bank]}} & ntt_mem_rd_req_mux[i][ABR_MEM_ADDR_WIDTH-4:1]) | + ({ABR_MEM_ADDR_WIDTH-4{pwo_a_mem_re0_bank_mux[bank]}} & pwm_a_rd_req_mux[i][ABR_MEM_ADDR_WIDTH-4:1]) | + ({ABR_MEM_ADDR_WIDTH-4{pwo_b_mem_re0_bank_mux[bank]}} & pwm_b_rd_req_mux[i][ABR_MEM_ADDR_WIDTH-4:1]) | + ({ABR_MEM_ADDR_WIDTH-4{decomp_mem_re0_bank[0][bank]}} & decomp_mem_rd_req[0].addr[ABR_MEM_ADDR_WIDTH-4:1]) | + ({ABR_MEM_ADDR_WIDTH-4{decomp_mem_re0_bank[1][bank]}} & decomp_mem_rd_req[1].addr[ABR_MEM_ADDR_WIDTH-4:1]) | + ({ABR_MEM_ADDR_WIDTH-4{skencode_mem_re0_bank[bank]}} & skencode_mem_rd_req[bank].addr[ABR_MEM_ADDR_WIDTH-4:1]) | + ({ABR_MEM_ADDR_WIDTH-4{normcheck_mem_re0_bank[bank]}} & normcheck_mem_rd_req.addr[ABR_MEM_ADDR_WIDTH-4:1]) | + ({ABR_MEM_ADDR_WIDTH-4{sigencode_mem_re0_bank[bank]}} & sigencode_mem_rd_req[bank].addr[ABR_MEM_ADDR_WIDTH-4:1])| + ({ABR_MEM_ADDR_WIDTH-4{pwr2rnd_mem_re0_bank[bank]}} & pwr2rnd_mem_rd_req[bank].addr[ABR_MEM_ADDR_WIDTH-4:1]) | + ({ABR_MEM_ADDR_WIDTH-4{compress_mem_re0_bank[bank]}} & compress_mem_rd_req.addr[ABR_MEM_ADDR_WIDTH-4:1]); + end + end else begin + decomp_mem_re[0][i] = (decomp_mem_rd_req[0].rd_wr_en == RW_READ) & (decomp_mem_rd_req[0].addr[ABR_MEM_ADDR_WIDTH-1:ABR_MEM_ADDR_WIDTH-3] == i[2:0]); + decomp_mem_re[1][i] = (decomp_mem_rd_req[1].rd_wr_en == RW_READ) & (decomp_mem_rd_req[1].addr[ABR_MEM_ADDR_WIDTH-1:ABR_MEM_ADDR_WIDTH-3] == i[2:0]); + normcheck_mem_re[i] = (normcheck_mem_rd_req.rd_wr_en == RW_READ) & (normcheck_mem_rd_req.addr[ABR_MEM_ADDR_WIDTH-1:ABR_MEM_ADDR_WIDTH-3] == i[2:0]); + makehint_mem_re[i] = (makehint_mem_rd_req.rd_wr_en == RW_READ) & (makehint_mem_rd_req.addr[ABR_MEM_ADDR_WIDTH-1:ABR_MEM_ADDR_WIDTH-3] == i[2:0]); + compress_mem_re[i] = (compress_mem_rd_req.rd_wr_en == RW_READ) & (compress_mem_rd_req.addr[ABR_MEM_ADDR_WIDTH-1:ABR_MEM_ADDR_WIDTH-3] == i[2:0]); + + abr_mem_re[i] = ntt_mem_re_mux[i] | pwo_a_mem_re_mux[i] | pwo_b_mem_re_mux[i] | + decomp_mem_re[0][i] | decomp_mem_re[1][i] | + normcheck_mem_re[i] | makehint_mem_re[i] | compress_mem_re[i]; + abr_mem_raddr[i] = ({ABR_MEM_ADDR_WIDTH-3{ntt_mem_re_mux[i]}} & ntt_mem_rd_req_mux[i][ABR_MEM_ADDR_WIDTH-4:0]) | + ({ABR_MEM_ADDR_WIDTH-3{pwo_a_mem_re_mux[i]}} & pwm_a_rd_req_mux[i][ABR_MEM_ADDR_WIDTH-4:0]) | + ({ABR_MEM_ADDR_WIDTH-3{pwo_b_mem_re_mux[i]}} & pwm_b_rd_req_mux[i][ABR_MEM_ADDR_WIDTH-4:0]) | + ({ABR_MEM_ADDR_WIDTH-3{decomp_mem_re[0][i]}} & decomp_mem_rd_req[0].addr[ABR_MEM_ADDR_WIDTH-4:0]) | + ({ABR_MEM_ADDR_WIDTH-3{decomp_mem_re[1][i]}} & decomp_mem_rd_req[1].addr[ABR_MEM_ADDR_WIDTH-4:0]) | + ({ABR_MEM_ADDR_WIDTH-3{normcheck_mem_re[i]}} & normcheck_mem_rd_req.addr[ABR_MEM_ADDR_WIDTH-4:0]) | + ({ABR_MEM_ADDR_WIDTH-3{makehint_mem_re[i]}} & makehint_mem_rd_req.addr[ABR_MEM_ADDR_WIDTH-4:0]) | + ({ABR_MEM_ADDR_WIDTH-3{compress_mem_re[i]}} & compress_mem_rd_req.addr[ABR_MEM_ADDR_WIDTH-4:0]); + end + end +end + +//Align read enables +always_ff @(posedge clk or negedge rst_b) begin : read_mux_flops + if (!rst_b) begin + ntt_mem_re_f <= 0; + pwo_a_mem_re_f <= 0; + pwo_b_mem_re_f <= 0; + decomp_mem_re_f <= 0; + normcheck_mem_re_f <= 0; + compress_mem_re_f <= 0; + ntt_mem_re0_bank_f <= 0; + pwo_a_mem_re0_bank_f <= 0; + pwo_b_mem_re0_bank_f <= 0; + decomp_mem_re0_bank_f <= 0; + normcheck_mem_re0_bank_f <= 0; + compress_mem_re0_bank_f <= 0; + sib_mem_re_f <= 0; + end + else if (zeroize_reg) begin + ntt_mem_re_f <= 0; + pwo_a_mem_re_f <= 0; + pwo_b_mem_re_f <= 0; + decomp_mem_re_f <= 0; + normcheck_mem_re_f <= 0; + compress_mem_re_f <= 0; + ntt_mem_re0_bank_f <= 0; + pwo_a_mem_re0_bank_f <= 0; + pwo_b_mem_re0_bank_f <= 0; + decomp_mem_re0_bank_f <= 0; + normcheck_mem_re0_bank_f <= 0; + compress_mem_re0_bank_f <= 0; + sib_mem_re_f <= 0; + end + else begin + ntt_mem_re_f <= ntt_mem_re; + pwo_a_mem_re_f<= pwo_a_mem_re; + pwo_b_mem_re_f <= pwo_b_mem_re; + decomp_mem_re_f <= decomp_mem_re; + normcheck_mem_re_f <= normcheck_mem_re; + compress_mem_re_f <= compress_mem_re; + ntt_mem_re0_bank_f <= ntt_mem_re0_bank; + pwo_a_mem_re0_bank_f <= pwo_a_mem_re0_bank; + pwo_b_mem_re0_bank_f <= pwo_b_mem_re0_bank; + decomp_mem_re0_bank_f <= decomp_mem_re0_bank; + normcheck_mem_re0_bank_f <= normcheck_mem_re0_bank; + compress_mem_re0_bank_f <= compress_mem_re0_bank; + sib_mem_re_f <= sib_mem_re; + end +end + +//Read data muxes +always_comb begin + ntt_mem_rd_data = 0; + pwm_a_rd_data = 0; + pwm_b_rd_data = 0; + decomp_mem_rd_data = 0; + normcheck_mem_rd_data = 0; + compress_mem_rd_data = 0; + + for (int i = 0; i < ABR_MEM_MASKED_INST; i++) begin + if (i == 0) begin + for (int bank = 0; bank < 2; bank++) begin + for (int ntt = 0; ntt < ABR_NUM_NTT; ntt++) begin + ntt_mem_rd_data[ntt][ABR_MEM_DATA_WIDTH-1:0] |= ({ABR_MEM_DATA_WIDTH{ntt_mem_re0_bank_f[ntt][bank]}} & abr_mem_rdata0_bank[bank]); + pwm_a_rd_data[ntt][ABR_MEM_DATA_WIDTH-1:0] |= ({ABR_MEM_DATA_WIDTH{pwo_a_mem_re0_bank_f[ntt][bank]}} & abr_mem_rdata0_bank[bank]); + pwm_b_rd_data[ntt][ABR_MEM_DATA_WIDTH-1:0] |= ({ABR_MEM_DATA_WIDTH{pwo_b_mem_re0_bank_f[ntt][bank]}} & abr_mem_rdata0_bank[bank]); + end + decomp_mem_rd_data[0] |= ({ABR_MEM_DATA_WIDTH{decomp_mem_re0_bank_f[0][bank]}} & abr_mem_rdata0_bank[bank]); + decomp_mem_rd_data[1] |= ({ABR_MEM_DATA_WIDTH{decomp_mem_re0_bank_f[1][bank]}} & abr_mem_rdata0_bank[bank]); + normcheck_mem_rd_data |= ({ABR_MEM_DATA_WIDTH{normcheck_mem_re0_bank_f[bank]}} & abr_mem_rdata0_bank[bank]); + compress_mem_rd_data |= ({ABR_MEM_DATA_WIDTH{compress_mem_re0_bank_f[bank]}} & abr_mem_rdata0_bank[bank]); + end + end else begin + for (int ntt = 0; ntt < ABR_NUM_NTT; ntt++) begin + ntt_mem_rd_data[ntt][ABR_MEM_DATA_WIDTH-1:0] |= ({ABR_MEM_DATA_WIDTH{ntt_mem_re_f[ntt][i]}} & abr_mem_rdata[i]); + pwm_a_rd_data[ntt][ABR_MEM_DATA_WIDTH-1:0] |= ({ABR_MEM_DATA_WIDTH{pwo_a_mem_re_f[ntt][i]}} & abr_mem_rdata[i]); + pwm_b_rd_data[ntt][ABR_MEM_DATA_WIDTH-1:0] |= ({ABR_MEM_DATA_WIDTH{pwo_b_mem_re_f[ntt][i]}} & abr_mem_rdata[i]); + end + decomp_mem_rd_data[0] |= ({ABR_MEM_DATA_WIDTH{decomp_mem_re_f[0][i]}} & abr_mem_rdata[i]); + decomp_mem_rd_data[1] |= ({ABR_MEM_DATA_WIDTH{decomp_mem_re_f[1][i]}} & abr_mem_rdata[i]); + normcheck_mem_rd_data |= ({ABR_MEM_DATA_WIDTH{normcheck_mem_re_f[i]}} & abr_mem_rdata[i]); + compress_mem_rd_data |= ({ABR_MEM_DATA_WIDTH{compress_mem_re_f[i]}} & abr_mem_rdata[i]); + end + end + //Masked memory uses full width + for (int ntt = 0; ntt < ABR_NUM_NTT; ntt++) begin + ntt_mem_rd_data[ntt] |= ({ABR_MEM_MASKED_DATA_WIDTH{ntt_mem_re_f[ntt][3]}} & abr_mem_masked_rdata[3]); + pwm_a_rd_data[ntt] |= ({ABR_MEM_MASKED_DATA_WIDTH{pwo_a_mem_re_f[ntt][3]}} & abr_mem_masked_rdata[3]); + pwm_b_rd_data[ntt] |= ({ABR_MEM_MASKED_DATA_WIDTH{pwo_b_mem_re_f[ntt][3]}} & abr_mem_masked_rdata[3]); + end + for (int ntt = 0; ntt < ABR_NUM_NTT; ntt++) begin + ntt_mem_rd_data[ntt][ABR_MEM_DATA_WIDTH-1:0] |= ({ABR_MEM_DATA_WIDTH{sib_mem_re_f[ntt]}} & sib_mem_rd_data); + end +end + +always_comb skencode_mem_rd_data = abr_mem_rdata0_bank; +always_comb makehint_mem_rd_data = abr_mem_rdata[1]; +always_comb sigencode_mem_rd_data = abr_mem_rdata0_bank; +always_comb pwr2rnd_mem_rd_data = abr_mem_rdata0_bank; + +///Memory instance 0 bank 0 +always_comb abr_memory_export.mem_inst0_bank0_we_i = (abr_mem_we0_bank[0]); +always_comb abr_memory_export.mem_inst0_bank0_waddr_i = (abr_mem_waddr0_bank[0][ABR_MEM_INST0_ADDR_W-1:0]); +always_comb abr_memory_export.mem_inst0_bank0_wdata_i = (abr_mem_wdata0_bank[0]); +always_comb abr_memory_export.mem_inst0_bank0_re_i = zeroize_mem_re ? 1'b1: (abr_mem_re0_bank[0]); +always_comb abr_memory_export.mem_inst0_bank0_raddr_i = zeroize_mem_re ? '0: (abr_mem_raddr0_bank[0][ABR_MEM_INST0_ADDR_W-1:0]); +always_comb abr_mem_rdata0_bank[0] = abr_memory_export.mem_inst0_bank0_rdata_o; + +//Memory instance 0 bank 1 +always_comb abr_memory_export.mem_inst0_bank1_we_i = (abr_mem_we0_bank[1]); +always_comb abr_memory_export.mem_inst0_bank1_waddr_i = (abr_mem_waddr0_bank[1][ABR_MEM_INST0_ADDR_W-1:0]); +always_comb abr_memory_export.mem_inst0_bank1_wdata_i = (abr_mem_wdata0_bank[1]); +always_comb abr_memory_export.mem_inst0_bank1_re_i = zeroize_mem_re ? 1'b1: (abr_mem_re0_bank[1]); +always_comb abr_memory_export.mem_inst0_bank1_raddr_i = zeroize_mem_re ? '0: (abr_mem_raddr0_bank[1][ABR_MEM_INST0_ADDR_W-1:0]); +always_comb abr_mem_rdata0_bank[1] = abr_memory_export.mem_inst0_bank1_rdata_o; + +//Memory instance 1 +always_comb abr_memory_export.mem_inst1_we_i = (abr_mem_we[1]); +always_comb abr_memory_export.mem_inst1_waddr_i = (abr_mem_waddr[1][ABR_MEM_INST1_ADDR_W-1:0]); +always_comb abr_memory_export.mem_inst1_wdata_i = (abr_mem_wdata[1]); +always_comb abr_memory_export.mem_inst1_re_i = zeroize_mem_re ? 1'b1: (abr_mem_re[1]); +always_comb abr_memory_export.mem_inst1_raddr_i = zeroize_mem_re ? '0: (abr_mem_raddr[1][ABR_MEM_INST1_ADDR_W-1:0]); +always_comb abr_mem_rdata[1] = abr_memory_export.mem_inst1_rdata_o; + +//Memory instance 2 +always_comb abr_memory_export.mem_inst2_we_i = (abr_mem_we[2]); +always_comb abr_memory_export.mem_inst2_waddr_i = (abr_mem_waddr[2][ABR_MEM_INST2_ADDR_W-1:0]); +always_comb abr_memory_export.mem_inst2_wdata_i = (abr_mem_wdata[2]); +always_comb abr_memory_export.mem_inst2_re_i = zeroize_mem_re ? 1'b1: (abr_mem_re[2]); +always_comb abr_memory_export.mem_inst2_raddr_i = zeroize_mem_re ? '0: (abr_mem_raddr[2][ABR_MEM_INST2_ADDR_W-1:0]); +always_comb abr_mem_rdata[2] = abr_memory_export.mem_inst2_rdata_o; + +//Memory instance 3 +always_comb abr_memory_export.mem_inst3_we_i = (abr_mem_we[3]); +always_comb abr_memory_export.mem_inst3_waddr_i = (abr_mem_waddr[3][ABR_MEM_INST3_ADDR_W-1:0]); +always_comb abr_memory_export.mem_inst3_wdata_i = (abr_mem_masked_wdata[3]); +always_comb abr_memory_export.mem_inst3_re_i = zeroize_mem_re ? 1'b1: (abr_mem_re[3]); +always_comb abr_memory_export.mem_inst3_raddr_i = zeroize_mem_re ? '0: (abr_mem_raddr[3][ABR_MEM_INST3_ADDR_W-1:0]); +always_comb abr_mem_masked_rdata[3] = abr_memory_export.mem_inst3_rdata_o; + +//SK Memory Bank 0 +always_comb abr_memory_export.sk_mem_bank0_we_i = sk_bank0_mem_if.we_i; +always_comb abr_memory_export.sk_mem_bank0_waddr_i = sk_bank0_mem_if.waddr_i; +always_comb abr_memory_export.sk_mem_bank0_wdata_i = sk_bank0_mem_if.wdata_i; +always_comb abr_memory_export.sk_mem_bank0_re_i = zeroize_mem_re ? 1'b1: sk_bank0_mem_if.re_i; +always_comb abr_memory_export.sk_mem_bank0_raddr_i = zeroize_mem_re ? '0: sk_bank0_mem_if.raddr_i; +always_comb sk_bank0_mem_if.rdata_o = abr_memory_export.sk_mem_bank0_rdata_o; + +//SK Memory Bank 1 +always_comb abr_memory_export.sk_mem_bank1_we_i = sk_bank1_mem_if.we_i; +always_comb abr_memory_export.sk_mem_bank1_waddr_i = sk_bank1_mem_if.waddr_i; +always_comb abr_memory_export.sk_mem_bank1_wdata_i = sk_bank1_mem_if.wdata_i; +always_comb abr_memory_export.sk_mem_bank1_re_i = zeroize_mem_re ? 1'b1: sk_bank1_mem_if.re_i; +always_comb abr_memory_export.sk_mem_bank1_raddr_i = zeroize_mem_re ? '0: sk_bank1_mem_if.raddr_i; +always_comb sk_bank1_mem_if.rdata_o = abr_memory_export.sk_mem_bank1_rdata_o; + +//Sig Z Memory +always_comb abr_memory_export.sig_z_mem_we_i = sig_z_mem_if.we_i; +always_comb abr_memory_export.sig_z_mem_waddr_i = sig_z_mem_if.waddr_i; +always_comb abr_memory_export.sig_z_mem_wdata_i = sig_z_mem_if.wdata_i; +always_comb abr_memory_export.sig_z_mem_wstrobe_i = sig_z_mem_if.wstrobe_i; +always_comb abr_memory_export.sig_z_mem_re_i = zeroize_mem_re ? 1'b1: sig_z_mem_if.re_i; +always_comb abr_memory_export.sig_z_mem_raddr_i = zeroize_mem_re ? '0: sig_z_mem_if.raddr_i; +always_comb sig_z_mem_if.rdata_o = abr_memory_export.sig_z_mem_rdata_o; + +//PK Memory +always_comb abr_memory_export.pk_mem_we_i = pk_mem_if.we_i; +always_comb abr_memory_export.pk_mem_waddr_i = pk_mem_if.waddr_i; +always_comb abr_memory_export.pk_mem_wdata_i = pk_mem_if.wdata_i; +always_comb abr_memory_export.pk_mem_wstrobe_i = pk_mem_if.wstrobe_i; +always_comb abr_memory_export.pk_mem_re_i = zeroize_mem_re ? 1'b1: pk_mem_if.re_i; +always_comb abr_memory_export.pk_mem_raddr_i = zeroize_mem_re ? '0: pk_mem_if.raddr_i; +always_comb pk_mem_if.rdata_o = abr_memory_export.pk_mem_rdata_o; + +`ABR_ASSERT_MUTEX(ERR_MEM_0_0_RD_ACCESS_MUTEX, {ntt_mem_re0_bank_mux[0],pwo_a_mem_re0_bank_mux[0],pwo_b_mem_re0_bank_mux[0], + decomp_mem_re0_bank[0][0],decomp_mem_re0_bank[1][0], pwr2rnd_mem_re0_bank[0], + skencode_mem_re0_bank[0], normcheck_mem_re0_bank[0], sigencode_mem_re0_bank[0], + compress_mem_re0_bank[0]}, clk, !rst_b) +`ABR_ASSERT_MUTEX(ERR_MEM_0_1_RD_ACCESS_MUTEX, {ntt_mem_re0_bank_mux[1],pwo_a_mem_re0_bank_mux[1],pwo_b_mem_re0_bank_mux[1], + decomp_mem_re0_bank[0][1],decomp_mem_re0_bank[1][1], pwr2rnd_mem_re0_bank[1], + skencode_mem_re0_bank[1],normcheck_mem_re0_bank[1],sigencode_mem_re0_bank[1], + compress_mem_re0_bank[1]}, clk, !rst_b) +`ABR_ASSERT_MUTEX(ERR_MEM_1_RD_ACCESS_MUTEX, {ntt_mem_re_mux[1],pwo_a_mem_re_mux[1],pwo_b_mem_re_mux[1],compress_mem_re[1], + normcheck_mem_re[1], decomp_mem_re[0][1],decomp_mem_re[1][1],makehint_mem_re[1]}, clk, !rst_b) +`ABR_ASSERT_MUTEX(ERR_MEM_2_RD_ACCESS_MUTEX, {ntt_mem_re_mux[2],pwo_a_mem_re_mux[2],pwo_b_mem_re_mux[2],compress_mem_re[2], + normcheck_mem_re[2], decomp_mem_re[0][2],decomp_mem_re[1][2],makehint_mem_re[2]}, clk, !rst_b) +`ABR_ASSERT_MUTEX(ERR_MEM_3_RD_ACCESS_MUTEX, {ntt_mem_re_mux[3],pwo_a_mem_re_mux[3],pwo_b_mem_re_mux[3],compress_mem_re[3], + normcheck_mem_re[3], decomp_mem_re[0][3],decomp_mem_re[1][3],makehint_mem_re[3]}, clk, !rst_b) + +`ABR_ASSERT_MUTEX(ERR_MEM_0_0_WR_ACCESS_MUTEX, {sampler_mem_we0_bank[0],ntt_mem_we0_bank[0],decomp_mem_we0_bank[0],decompress_mem_we0_bank[0], + skdecode_mem_we0_bank[0], pkdecode_mem_we0_bank[0], sigdecode_h_mem_we0_bank[0], + sigdecode_z_mem_we0_bank[0]}, clk, !rst_b) +`ABR_ASSERT_MUTEX(ERR_MEM_0_1_WR_ACCESS_MUTEX, {sampler_mem_we0_bank[1],ntt_mem_we0_bank[1],decomp_mem_we0_bank[1],decompress_mem_we0_bank[1], + skdecode_mem_we0_bank[1], pkdecode_mem_we0_bank[1], sigdecode_h_mem_we0_bank[1], + sigdecode_z_mem_we0_bank[1]}, clk, !rst_b) + +`ABR_ASSERT_MUTEX(ERR_MEM_1_WR_ACCESS_MUTEX, {sampler_mem_we[1],ntt_mem_we_mux[1],decomp_mem_we[1],sigdecode_h_mem_we[1]}, clk, !rst_b) +`ABR_ASSERT_MUTEX(ERR_MEM_2_WR_ACCESS_MUTEX, {sampler_mem_we[2],ntt_mem_we_mux[2],decomp_mem_we[2],sigdecode_h_mem_we[2]}, clk, !rst_b) +`ABR_ASSERT_MUTEX(ERR_MEM_3_WR_ACCESS_MUTEX, {sampler_mem_we[3],ntt_mem_we_mux[3],decomp_mem_we[3],sigdecode_h_mem_we[3]}, clk, !rst_b) + +`ABR_ASSERT_KNOWN(ERR_MEM_0_0_WDATA_X, {abr_mem_wdata0_bank[0]}, clk, !rst_b, abr_mem_we0_bank[0]) +`ABR_ASSERT_KNOWN(ERR_MEM_0_1_WDATA_X, {abr_mem_wdata0_bank[1]}, clk, !rst_b, abr_mem_we0_bank[1]) +`ABR_ASSERT_KNOWN(ERR_MEM_1_WDATA_X, {abr_mem_wdata[1]}, clk, !rst_b, abr_mem_we[1]) +`ABR_ASSERT_KNOWN(ERR_MEM_2_WDATA_X, {abr_mem_wdata[2]}, clk, !rst_b, abr_mem_we[2]) +`ABR_ASSERT_KNOWN(ERR_MEM_3_WDATA_X, {abr_mem_masked_wdata[3]}, clk, !rst_b, abr_mem_we[3]) + +`ABR_ASSERT_KNOWN(ERR_MEM_0_RDATA_X, {ntt_mem_rd_data}, clk, !rst_b) +`ABR_ASSERT_KNOWN(ERR_MEM_1_RDATA_X, {pwm_a_rd_data}, clk, !rst_b) +`ABR_ASSERT_KNOWN(ERR_MEM_2_RDATA_X, {pwm_b_rd_data}, clk, !rst_b) + +//Only NTT reads/writes to MEM 3 +`ABR_ASSERT_NEVER(ERR_MEM_3_WR, (sampler_mem_we[3] | decomp_mem_we[3] | sigdecode_h_mem_we[3]), clk, !rst_b) +`ABR_ASSERT_NEVER(ERR_MEM_3_RD, (compress_mem_re_f[3] | normcheck_mem_re_f[3] | decomp_mem_re_f[0][3] | decomp_mem_re_f[1][3]), clk, !rst_b) + + abr_prim_alert_pkg::alert_tx_t [NumAlerts-1:0] alert_tx_o; + logic clk_i; + + assign clk_i = clk; + + `ABR_ASSERT_PRIM_FSM_ERROR_TRIGGER_ALERT(SHA3FsmCheck_A, + sampler_top_inst.sha3_inst.u_state_regs, alert_tx_o[1]) + + `ABR_ASSERT_PRIM_FSM_ERROR_TRIGGER_ALERT(KeccakRoundFsmCheck_A, + sampler_top_inst.sha3_inst.u_keccak.u_state_regs, alert_tx_o[1]) + + `ABR_ASSERT_PRIM_FSM_ERROR_TRIGGER_ALERT(SHA3padFsmCheck_A, + sampler_top_inst.sha3_inst.u_pad.u_state_regs, alert_tx_o[1]) + + `ABR_ASSERT_PRIM_COUNT_ERROR_TRIGGER_ALERT(WrMsgCountCheck_A, + sampler_top_inst.sha3_inst.u_pad.u_wrmsg_count, alert_tx_o[1]) + + `ABR_ASSERT_PRIM_COUNT_ERROR_TRIGGER_ALERT(RoundCountCheck_A, + sampler_top_inst.sha3_inst.u_keccak.u_round_count, alert_tx_o[1]) + +endmodule diff --git a/designs/Caliptra/src/adams-bridge/abr_top_cov_bind.sv b/designs/Caliptra/src/adams-bridge/abr_top_cov_bind.sv new file mode 100644 index 0000000..0fb6bbc --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/abr_top_cov_bind.sv @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. + + +module abr_top_cov_bind; + `ifdef FCOV + bind abr_top abr_top_cov_if i_abr_top_cov_if(.*); + `endif +endmodule diff --git a/designs/Caliptra/src/adams-bridge/abr_top_cov_if.sv b/designs/Caliptra/src/adams-bridge/abr_top_cov_if.sv new file mode 100644 index 0000000..020eb10 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/abr_top_cov_if.sv @@ -0,0 +1,370 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. + +`ifndef VERILATOR + +interface abr_top_cov_if + import abr_params_pkg::*; + `ifdef CALIPTRA + import kv_defines_pkg::*; + `endif + ( + + `ifdef CALIPTRA + input logic ocp_lock_in_progress, + `endif + + input logic clk, + input logic rst_b, + input logic debugUnlock_or_scan_mode_switch + +); + + logic [2 : 0] mldsa_cmd; + logic [2 : 0] mlkem_cmd; + logic [2 : 0] mldsa_sw_cmd; + logic zeroize; + logic ready; + logic mldsa_valid; + logic mlkem_valid; + logic pcr_process; + + logic error_flag; + logic skdecode_error; + logic mldsa_keygen_process; + logic mldsa_signing_process; + logic mldsa_verifying_process; + logic mldsa_keygen_signing_process; + logic mlkem_keygen_process; + logic mlkem_encaps_process; + logic mlkem_decaps_process; + logic mlkem_keygen_decaps_process; + + logic verify_failure; + logic normcheck_failure; + logic [2 : 0] normcheck_mode; + logic makehint_failure; + logic invalid_hint; + + `ifdef CALIPTRA + logic pcr_sign_mode; + logic pcr_sign_input_invalid; + logic kv_mldsa_seed_data_present; + logic kv_mlkem_seed_data_present; + logic kv_mlkem_msg_data_present; + + assign pcr_sign_input_invalid = abr_top.abr_ctrl_inst.pcr_sign_input_invalid; + assign pcr_sign_mode = abr_top.abr_ctrl_inst.pcr_sign_mode; + + assign kv_mldsa_seed_data_present = abr_top.abr_ctrl_inst.kv_mldsa_seed_data_present; + assign kv_mlkem_seed_data_present = abr_top.abr_ctrl_inst.kv_mlkem_seed_data_present; + assign kv_mlkem_msg_data_present = abr_top.abr_ctrl_inst.kv_mlkem_msg_data_present; + + always_ff @(posedge clk) begin + if (!rst_b) begin + pcr_process <= '0; + end + else if (pcr_sign_mode) begin + pcr_process <= '1; + end + else if (!mldsa_signing_process & !mldsa_keygen_signing_process) begin + pcr_process <= '0; + end + end + + kv_write_filter_metrics_t kv_write_metrics; + kv_write_ctrl_reg_t kv_write_ctrl_reg; + kv_read_ctrl_reg_t kv_read_ctrl_reg; + + assign kv_write_metrics = abr_top.abr_ctrl_inst.kv_mlkem_sharedkey_write_metrics; + assign kv_write_ctrl_reg = abr_top.abr_ctrl_inst.kv_mlkem_sharedkey_write_ctrl_reg; + assign kv_read_ctrl_reg = abr_top.abr_ctrl_inst.kv_mldsa_seed_read_ctrl_reg; + `endif + + assign mldsa_cmd = abr_top.abr_ctrl_inst.mldsa_cmd_reg; + assign mlkem_cmd = abr_top.abr_ctrl_inst.mlkem_cmd_reg; + assign zeroize = abr_top.abr_ctrl_inst.zeroize; + assign ready = abr_top.abr_ctrl_inst.abr_ready; + assign mldsa_valid = abr_top.abr_ctrl_inst.mldsa_valid_reg; + assign mlkem_valid = abr_top.abr_ctrl_inst.mlkem_valid_reg; + + always_ff @(posedge clk) begin + if (!rst_b) begin + mldsa_sw_cmd <= '0; + end + else if (abr_top.abr_reg_inst.decoded_reg_strb.MLDSA_CTRL && abr_top.abr_reg_inst.decoded_req_is_wr) begin // SW write + mldsa_sw_cmd <= (abr_top.abr_reg_inst.field_storage.MLDSA_CTRL.CTRL.value & ~abr_top.abr_reg_inst.decoded_wr_biten[2:0]) | (abr_top.abr_reg_inst.decoded_wr_data[2:0] & abr_top.abr_reg_inst.decoded_wr_biten[2:0]); + end + end + + + assign error_flag = abr_top.abr_ctrl_inst.error_flag | abr_top.abr_ctrl_inst.error_flag_reg; + assign skdecode_error = abr_top.abr_ctrl_inst.skdecode_error_i; + + assign mldsa_keygen_process = abr_top.abr_ctrl_inst.mldsa_keygen_process; + assign mldsa_signing_process = abr_top.abr_ctrl_inst.mldsa_signing_process; + assign mldsa_verifying_process = abr_top.abr_ctrl_inst.mldsa_verifying_process; + assign mldsa_keygen_signing_process = abr_top.abr_ctrl_inst.mldsa_keygen_signing_process; + assign mlkem_keygen_process = abr_top.abr_ctrl_inst.mldsa_keygen_process; + assign mlkem_encaps_process = abr_top.abr_ctrl_inst.mlkem_encaps_process; + assign mlkem_decaps_process = abr_top.abr_ctrl_inst.mlkem_decaps_process; + assign mlkem_keygen_decaps_process = abr_top.abr_ctrl_inst.mlkem_keygen_decaps_process; + + assign verify_failure = abr_top.abr_ctrl_inst.clear_verify_valid; + assign normcheck_failure = abr_top.abr_ctrl_inst.normcheck_done_i & abr_top.abr_ctrl_inst.normcheck_invalid_i; + assign normcheck_mode[0] = (abr_top.abr_ctrl_inst.normcheck_mode_o == 2'b00); + assign normcheck_mode[1] = (abr_top.abr_ctrl_inst.normcheck_mode_o == 2'b01); + assign normcheck_mode[2] = (abr_top.abr_ctrl_inst.normcheck_mode_o == 2'b10); + assign makehint_failure = abr_top.abr_ctrl_inst.makehint_done_i & abr_top.abr_ctrl_inst.makehint_invalid_i; + assign invalid_hint = abr_top.abr_ctrl_inst.sigdecode_h_invalid_i; + + covergroup abr_top_cov_grp @(posedge clk); + reset_cp: coverpoint rst_b; + debugUnlock_or_scan_mode_switch_cp: coverpoint debugUnlock_or_scan_mode_switch; + + mldsa_cmd_cp: coverpoint mldsa_cmd{ + illegal_bins illegal_values = {5, 6, 7}; + } + mlkem_cmd_cp: coverpoint mlkem_cmd{ + illegal_bins illegal_values = {5, 6, 7}; + } + zeroize_cp: coverpoint zeroize; + ready_cp: coverpoint ready; + mldsa_valid_cp: coverpoint mldsa_valid; + mlkem_valid_cp: coverpoint mlkem_valid; + mldsa_keygen_process_cp: coverpoint mldsa_keygen_process; + mldsa_signing_process_cp: coverpoint mldsa_signing_process; + mldsa_verifying_process_cp: coverpoint mldsa_verifying_process; + mldsa_keygen_signing_process_cp: coverpoint mldsa_keygen_signing_process; + + mlkem_keygen_process_cp: coverpoint mlkem_keygen_process; + mlkem_encaps_process_cp: coverpoint mlkem_encaps_process; + mlkem_decaps_process_cp: coverpoint mlkem_decaps_process; + mlkem_keygen_decaps_process_cp: coverpoint mlkem_keygen_decaps_process; + + error_flag_cp: coverpoint error_flag; + skdecode_error_cp: coverpoint skdecode_error; + verify_failure_cp: coverpoint verify_failure; + normcheck_mode_sign_cp: coverpoint normcheck_mode { + bins mode_0 = {1}; + bins mode_1 = {2}; + bins mode_2 = {4}; + } + normcheck_mode_verify_cp: coverpoint normcheck_mode { + bins mode_0 = {1}; + } + normcheck_failure_cp: coverpoint normcheck_failure; + makehint_failure_cp: coverpoint makehint_failure; + invalid_hint_cp: coverpoint invalid_hint; + clear_decaps_valid_cp: coverpoint abr_top.abr_ctrl_inst.clear_decaps_valid; + encaps_input_check_failure_cp: coverpoint abr_top.abr_ctrl_inst.encaps_input_check_failure; + decaps_input_check_failure_cp: coverpoint abr_top.abr_ctrl_inst.decaps_input_check_failure; + + stream_msg_strobe_cp: coverpoint abr_top.abr_ctrl_inst.stream_msg_strobe { + bins one_byte = {4'b0001}; + bins two_bytes = {4'b0011}; + bins three_bytes = {4'b0111}; + bins four_bytes = {4'b1111}; + } + + mldsa_sw_cmd_cp: coverpoint mldsa_sw_cmd { + illegal_bins illegal_values = {5, 6, 7}; + } + + mldsa_cmdXready: cross mldsa_sw_cmd_cp, ready_cp; + + zeroizeXerror: cross zeroize_cp, error_flag_cp; + readyXzeroize: cross ready_cp, zeroize_cp; + mldsa_validXzeroize: cross mldsa_valid_cp, zeroize_cp; + mlkem_validXzeroize: cross mlkem_valid_cp, zeroize_cp; + errorXmldsa_signing: cross error_flag_cp, mldsa_signing_process_cp; + + normcheckXsigning_failure: cross normcheck_mode_sign_cp, normcheck_failure_cp iff (mldsa_signing_process | mldsa_keygen_signing_process); + normcheckXverifying_failure: cross normcheck_mode_verify_cp, normcheck_failure_cp iff (mldsa_verifying_process); + + `ifdef CALIPTRA + kv_mldsa_seed_data_present_cp: coverpoint kv_mldsa_seed_data_present; + mldsa_keygenXkv: cross mldsa_keygen_process_cp, kv_mldsa_seed_data_present_cp; + + kv_mlkem_seed_data_present_cp: coverpoint kv_mlkem_seed_data_present; + mlkem_keygenXkv: cross mlkem_keygen_process_cp, kv_mlkem_seed_data_present_cp; + mlkem_keygen_decapsXkv: cross mlkem_keygen_decaps_process_cp, kv_mlkem_seed_data_present_cp; + + kv_mlkem_msg_data_present_cp: coverpoint kv_mlkem_msg_data_present; + mlkem_encapsXkv: cross mlkem_encaps_process_cp, kv_mlkem_msg_data_present_cp; + + pcr_sign_cp: coverpoint pcr_sign_mode; + pcr_sign_input_invalid_cp: coverpoint pcr_sign_input_invalid; + + readyXpcr_sign: cross ready_cp, pcr_sign_cp; + pcr_signXmldsa_cmd: cross pcr_sign_cp, mldsa_cmd_cp { + ignore_bins illegal_crosses = binsof(mldsa_cmd_cp.illegal_values); + } + zeroizeXpcr_sign: cross zeroize_cp, pcr_sign_cp; + + errorXmldsa_keygen: cross error_flag_cp, mldsa_keygen_process_cp; // due to pcr_sign_input_invalid + errorXmldsa_verifying: cross error_flag_cp, mldsa_verifying_process_cp; // due to pcr_sign_input_invalid + errorXmldsa_keygen_signing: cross error_flag_cp, mldsa_keygen_signing_process_cp; // due to pcr_sign_input_invalid + + normcheck_fail_signXpcr_sign: cross normcheck_mode_sign_cp, normcheck_failure_cp iff (pcr_process); + makehint_failXpcr_sign: cross makehint_failure_cp, pcr_sign_cp; + `endif + + endgroup + + + + + // SIGN Z encoding + localparam int NUM_ENC = 4; + localparam int GAMMA1 = 19; + localparam int REG_SIZE = 23; + localparam int MLDSA_GAMMA1_RANGE = 2**GAMMA1; + localparam int MLDSA_Q = 8380417; + + logic [(NUM_ENC*2)-1:0] eq_flags; + logic [(NUM_ENC*2)-1:0] less_flags; + logic [(NUM_ENC*2)-1:0] greater_flags; + logic enc_unit_equal; + logic enc_unit_less; + logic enc_unit_greater; + + genvar sig_enc_i; + generate + for(sig_enc_i = 0; sig_enc_i < NUM_ENC; sig_enc_i++) begin : enc_loop + // For the upper instance + assign eq_flags[sig_enc_i*2] = (abr_top.sigencode_z_inst.enc_unit[sig_enc_i].upper_encode.data_i == MLDSA_GAMMA1_RANGE); + assign less_flags[sig_enc_i*2] = (abr_top.sigencode_z_inst.enc_unit[sig_enc_i].upper_encode.data_i < MLDSA_GAMMA1_RANGE); + assign greater_flags[sig_enc_i*2] = (abr_top.sigencode_z_inst.enc_unit[sig_enc_i].upper_encode.data_i > MLDSA_GAMMA1_RANGE); + + // For the lower instance + assign eq_flags[sig_enc_i*2+1] = (abr_top.sigencode_z_inst.enc_unit[sig_enc_i].lower_encode.data_i == MLDSA_GAMMA1_RANGE); + assign less_flags[sig_enc_i*2+1] = (abr_top.sigencode_z_inst.enc_unit[sig_enc_i].lower_encode.data_i < MLDSA_GAMMA1_RANGE); + assign greater_flags[sig_enc_i*2+1] = (abr_top.sigencode_z_inst.enc_unit[sig_enc_i].lower_encode.data_i > MLDSA_GAMMA1_RANGE); + end + endgenerate + + // OR-reduce the flags: if any instance meets the condition, the corresponding signal is 1. + assign enc_unit_equal = (|eq_flags) & (abr_top.sigencode_z_inst.state != abr_top.sigencode_z_inst.IDLE); + assign enc_unit_less = (|less_flags) & (abr_top.sigencode_z_inst.state != abr_top.sigencode_z_inst.IDLE); + assign enc_unit_greater = (|greater_flags) & (abr_top.sigencode_z_inst.state != abr_top.sigencode_z_inst.IDLE); + // Sign_z to cover the aggregated conditions + covergroup mldsa_sign_z_enc_agg_cg @(posedge clk); + coverpoint enc_unit_equal { + bins hit = {1'b1}; + } + coverpoint enc_unit_less { + bins hit = {1'b1}; + } + coverpoint enc_unit_greater { + bins hit = {1'b1}; + } + endgroup + + // The FSM cases are: 'h0, 'h1, 'h2, MLDSA_Q-1, MLDSA_Q-2, and default. + logic [(NUM_ENC*2)-1:0] skenc_state0_flags; + logic [(NUM_ENC*2)-1:0] skenc_state1_flags; + logic [(NUM_ENC*2)-1:0] skenc_state2_flags; + logic [(NUM_ENC*2)-1:0] skenc_state_mq1_flags; + logic [(NUM_ENC*2)-1:0] skenc_state_mq2_flags; + logic skenc_state0_agg, skenc_state1_agg, skenc_state2_agg, skenc_state_mq1_agg, skenc_state_mq2_agg; + + genvar sk_enc_i; + generate + for (sk_enc_i = 0; sk_enc_i < NUM_ENC; sk_enc_i++) begin : sk_enc_loop + // For mem_a_rd_data element + assign skenc_state0_flags[sk_enc_i*2] = (abr_top.skencode_inst.mem_a_rd_data[sk_enc_i] == 'h0); + assign skenc_state1_flags[sk_enc_i*2] = (abr_top.skencode_inst.mem_a_rd_data[sk_enc_i] == 'h1); + assign skenc_state2_flags[sk_enc_i*2] = (abr_top.skencode_inst.mem_a_rd_data[sk_enc_i] == 'h2); + assign skenc_state_mq1_flags[sk_enc_i*2] = (abr_top.skencode_inst.mem_a_rd_data[sk_enc_i] == MLDSA_Q - 1); + assign skenc_state_mq2_flags[sk_enc_i*2] = (abr_top.skencode_inst.mem_a_rd_data[sk_enc_i] == MLDSA_Q - 2); + // For mem_b_rd_data element + assign skenc_state0_flags[sk_enc_i*2+1] = (abr_top.skencode_inst.mem_b_rd_data[sk_enc_i] == 'h0); + assign skenc_state1_flags[sk_enc_i*2+1] = (abr_top.skencode_inst.mem_b_rd_data[sk_enc_i] == 'h1); + assign skenc_state2_flags[sk_enc_i*2+1] = (abr_top.skencode_inst.mem_b_rd_data[sk_enc_i] == 'h2); + assign skenc_state_mq1_flags[sk_enc_i*2+1] = (abr_top.skencode_inst.mem_b_rd_data[sk_enc_i] == MLDSA_Q - 1); + assign skenc_state_mq2_flags[sk_enc_i*2+1] = (abr_top.skencode_inst.mem_b_rd_data[sk_enc_i] == MLDSA_Q - 2); + end + endgenerate + + // OR-reduce each set of flags and ensure the FSM is not in IDLE. + // (Assuming abr_top.skencode_inst.state and its IDLE constant are accessible.) + assign skenc_state0_agg = (|skenc_state0_flags) & (abr_top.skencode_inst.main_state != abr_top.skencode_inst.IDLE); + assign skenc_state1_agg = (|skenc_state1_flags) & (abr_top.skencode_inst.main_state != abr_top.skencode_inst.IDLE); + assign skenc_state2_agg = (|skenc_state2_flags) & (abr_top.skencode_inst.main_state != abr_top.skencode_inst.IDLE); + assign skenc_state_mq1_agg = (|skenc_state_mq1_flags) & (abr_top.skencode_inst.main_state != abr_top.skencode_inst.IDLE); + assign skenc_state_mq2_agg = (|skenc_state_mq2_flags) & (abr_top.skencode_inst.main_state != abr_top.skencode_inst.IDLE); + + // Now create a covergroup that samples these aggregated flags. + covergroup mldsa_skencode_agg_cg @(posedge clk); + coverpoint skenc_state0_agg { bins hit = {1'b1}; } + coverpoint skenc_state1_agg { bins hit = {1'b1}; } + coverpoint skenc_state2_agg { bins hit = {1'b1}; } + coverpoint skenc_state_mq1_agg { bins hit = {1'b1}; } + coverpoint skenc_state_mq2_agg { bins hit = {1'b1}; } + endgroup + + `ifdef CALIPTRA + covergroup abr_ocp_lock_cov_grp @(posedge clk); + + ocp_lock_in_progress_cp: coverpoint ocp_lock_in_progress; + + kv_read_entry_mldsa_cp: coverpoint {kv_mldsa_seed_data_present, kv_read_ctrl_reg.read_entry } + iff (mldsa_cmd inside {MLDSA_KEYGEN, MLDSA_KEYGEN_SIGN}) { + bins fw = {1'b0, [0:$]}; + bins lower_slots = {1'b1, [0:15]}; + bins upper_slots = {1'b1, [16:22]}; + bins slot_23 = {1'b1, 23}; + } + + kv_read_entry_0_cp: coverpoint {kv_write_metrics.kv_data0_present, kv_write_metrics.kv_data0_entry} + iff (mlkem_cmd inside {MLKEM_KEYGEN_DEC}) { + bins fw = {1'b0, [0:$]}; + bins lower_slots = {1'b1, [0:15]}; + bins upper_slots = {1'b1, [16:22]}; + bins slot_23 = {1'b1, 23}; + } + + kv_read_entry_1_cp: coverpoint {kv_write_metrics.kv_data1_present, kv_write_metrics.kv_data1_entry} + iff (mlkem_cmd inside {MLKEM_ENCAPS}) { + bins fw = {1'b0, [0:$]}; + bins lower_slots = {1'b1, [0:15]}; + bins upper_slots = {1'b1, [16:22]}; + bins slot_23 = {1'b1, 23}; + } + + kv_write_entry_cp: coverpoint {kv_write_ctrl_reg.write_en, kv_write_metrics.kv_write_entry} + iff (mlkem_encaps_process | mlkem_keygen_decaps_process) { + bins fw = {1'b0, [0:$]}; + bins lower_slots = {1'b1, [0:15]}; + bins upper_slots = {1'b1, [16:22]}; + bins slot_23 = {1'b1, 23}; + } + + ocp_lock_X_kv_read_entry0: cross ocp_lock_in_progress_cp, kv_write_entry_cp, kv_read_entry_0_cp; + ocp_lock_X_kv_read_entry1: cross ocp_lock_in_progress_cp, kv_write_entry_cp, kv_read_entry_1_cp; + ocp_lock_X_kv_read_entry_mldsa: cross ocp_lock_in_progress_cp, kv_read_entry_mldsa_cp; + endgroup + abr_ocp_lock_cov_grp abr_ocp_lock_cov_grp1 = new(); + `endif + + // Instantiate the covergroup + mldsa_skencode_agg_cg mldsa_skencode_agg_cov = new(); + mldsa_sign_z_enc_agg_cg mldsa_sign_z_enc_agg_cov_grp1 = new(); + + abr_top_cov_grp abr_top_cov_grp1 = new(); + +endinterface + +`endif diff --git a/designs/Caliptra/src/adams-bridge/barrett_reduction.sv b/designs/Caliptra/src/adams-bridge/barrett_reduction.sv new file mode 100644 index 0000000..263e595 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/barrett_reduction.sv @@ -0,0 +1,56 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +//====================================================================== +// +// barrett_reduction.sv +// ----------- + +module barrett_reduction #( + parameter int prime = 3329, + parameter int REG_SIZE = $clog2(prime) +)( + input logic [2*REG_SIZE-1:0] x, + output logic [REG_SIZE-1:0] inv, // x / prime + output logic [REG_SIZE-1:0] r // x % prime +); + + // K is derived from REG_SIZE + localparam int K = 2*REG_SIZE; + + // Compute M = floor(2^K / Q) + localparam logic [REG_SIZE:0] m = (1 << K) / prime; + + logic [3*REG_SIZE:0] mult_full; + logic [REG_SIZE:0] u_est, u_plus_one; + logic [2*REG_SIZE:0] u_prime, r_est, r_sub_prime; + logic additional_reduction; + + assign mult_full = x * m; + + assign u_est = mult_full >> K; + assign u_prime = u_est * prime; + assign r_est = {1'b0, x} - u_prime; + + // conditional outputs + assign r_sub_prime = r_est - prime; + assign u_plus_one = u_est + 1; + + //condition for the output + assign additional_reduction = (r_est >= prime); + + // Compute output + assign r = additional_reduction? r_sub_prime[REG_SIZE-1 : 0] : r_est[REG_SIZE-1 : 0]; + assign inv = additional_reduction? u_plus_one[REG_SIZE-1 : 0] : u_est[REG_SIZE-1 : 0]; + +endmodule diff --git a/designs/Caliptra/src/adams-bridge/cbd_sampler.sv b/designs/Caliptra/src/adams-bridge/cbd_sampler.sv new file mode 100644 index 0000000..e7d6fc5 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/cbd_sampler.sv @@ -0,0 +1,49 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. + +//Computes the centered binomial distribution for ML-KEM + +module cbd_sampler + import abr_params_pkg::*; + #( + localparam CBD_SAMPLE_W = 2*MLKEM_ETA + ) + ( + //input data + input logic [CBD_SAMPLE_W-1:0] data_i, + + //output data + output logic [2:0] data_o + + ); + + logic [CBD_SAMPLE_W-1:0] a; + logic [MLKEM_ETA-1:0] b; + logic [MLKEM_ETA-1:0] c; + + assign a = data_i; + + //Check sample validity + always_comb begin + //Perform x - y + b = 0; + c = 0; + for (int i = 0; i < MLKEM_ETA; i++) begin + b += a[i]; + c += a[i+MLKEM_ETA]; + end + data_o = b - c; + end + +endmodule diff --git a/designs/Caliptra/src/adams-bridge/cbd_sampler_ctrl.sv b/designs/Caliptra/src/adams-bridge/cbd_sampler_ctrl.sv new file mode 100644 index 0000000..27619a9 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/cbd_sampler_ctrl.sv @@ -0,0 +1,71 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. + + +module cbd_sampler_ctrl + import abr_params_pkg::*; + #( + localparam CBD_NUM_SAMPLERS = COEFF_PER_CLK + ,localparam CBD_SAMPLE_W = 2*MLKEM_ETA + ,localparam CBD_VLD_SAMPLES = CBD_NUM_SAMPLERS + ,localparam CBD_VLD_SAMPLES_W = MLKEM_Q_WIDTH + ) + ( + input logic clk, + input logic rst_b, + input logic zeroize, + //input data + input logic data_valid_i, + output logic data_hold_o, + input logic [CBD_NUM_SAMPLERS-1:0][CBD_SAMPLE_W-1:0] data_i, + + //output data + output logic data_valid_o, + output logic [CBD_VLD_SAMPLES-1:0][CBD_VLD_SAMPLES_W-1:0] data_o + + ); + + logic [CBD_NUM_SAMPLERS-1:0][2:0] sample_data; + + //Hold if the buffer is full + always_comb data_hold_o = 0; + + generate + for (genvar inst_g = 0; inst_g < CBD_NUM_SAMPLERS; inst_g++) begin : cbd_sampler_inst + cbd_sampler + cbd_sampler_i ( + .data_i(data_i[inst_g]), + .data_o(sample_data[inst_g]) + ); + end + endgenerate + + + //No rejection, so data is valid when we have valid input data + always_comb data_valid_o = data_valid_i & ~zeroize; + //CBD buffer value selects between 5 possible outputs (x - y mod q) + always_comb begin + for (int sample = 0; sample < CBD_VLD_SAMPLES; sample++) begin + unique case (sample_data[sample]) + 3'd0 : data_o[sample] = 0; + 3'd1 : data_o[sample] = 1; + 3'd2 : data_o[sample] = 2; + 3'd7 : data_o[sample] = MLKEM_Q-1; + 3'd6 : data_o[sample] = MLKEM_Q-2; + default : data_o[sample] = '0; + endcase + end + end + +endmodule diff --git a/designs/Caliptra/src/adams-bridge/compress.sv b/designs/Caliptra/src/adams-bridge/compress.sv new file mode 100644 index 0000000..fdb03d5 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/compress.sv @@ -0,0 +1,59 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +//====================================================================== +// +// compress.sv +// -------- +// Converts 12-bit coefficients into d-bit representation where d is the compression level. +// Based on input mode, d is selected and the following equation is performed: +// ((data[11:0] << d) + q/2) / q +// To efficiently perform /q operation, barrett reduction is used. + +module compress + import abr_params_pkg::*; + import compress_defines_pkg::*; + ( + input wire [MLKEM_Q_WIDTH-1:0] op_i, + input compress_mode_t mode, + output logic [MLKEM_Q_WIDTH-1:0] op_o + ); + + localparam HALF_Q = MLKEM_Q / 2; + + logic [3:0] d; + logic [(2*MLKEM_Q_WIDTH)-1:0] data_lsh_d, lsh_plus_halfq; + logic [MLKEM_Q_WIDTH-1:0] red_o; + + always_comb begin + unique case(mode) + 0: d = 1; + 1: d = 5; + 2: d = 11; + default: d = 1; + endcase + end + + always_comb data_lsh_d = (2*MLKEM_Q_WIDTH)'(op_i << d); + always_comb lsh_plus_halfq = data_lsh_d + HALF_Q; + + always_comb op_o = (mode == 3) ? op_i : red_o; // No compression, just pass through if mode == 3 + + barrett_reduction #( + .prime(MLKEM_Q) + ) compress_barret_reduction_inst ( + .x(lsh_plus_halfq), + .inv(red_o), + .r() + ); +endmodule \ No newline at end of file diff --git a/designs/Caliptra/src/adams-bridge/compress_ctrl.sv b/designs/Caliptra/src/adams-bridge/compress_ctrl.sv new file mode 100644 index 0000000..1fa1b98 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/compress_ctrl.sv @@ -0,0 +1,123 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +//====================================================================== +// +// compress_ctrl.sv +// --------- +// Controls memory accesses and iterates over MLKEM_K = 4 polynomials before generating done + +module compress_ctrl + import abr_params_pkg::*; + import compress_defines_pkg::*; + ( + input wire clk, + input wire reset_n, + input wire zeroize, + + input wire cmp_enable, + input wire [2:0] num_poly, + input wire [ABR_MEM_ADDR_WIDTH-1:0] src_base_addr, + + output mem_if_t mem_rd_req, + output logic mem_rd_data_valid, + input logic mem_rd_data_hold, + output logic done + ); + + //Internals + logic [ABR_MEM_ADDR_WIDTH-1:0] mem_rd_addr, mem_rd_addr_nxt; + logic upd_rd_addr; + logic ld_rd_addr; + logic last_poly_last_addr_rd; + + cmp_read_state_e read_fsm_state_ps, read_fsm_state_ns; + + logic arc_CMP_RD_IDLE_CMP_RD_MEM; + logic arc_CMP_RD_MEM_CMD_RD_IDLE; + + //Read addr counter + //Go back and read previous address if mem_rd_data_hold is set, else increment by 1 + always_comb mem_rd_addr_nxt = mem_rd_data_hold ? mem_rd_addr : mem_rd_addr + 'h1; + + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) begin + mem_rd_addr <= '0; + end + else if (zeroize) begin + mem_rd_addr <= '0; + end + else if (ld_rd_addr) begin + mem_rd_addr <= src_base_addr; + end + else if (upd_rd_addr) begin + mem_rd_addr <= mem_rd_addr_nxt; + end + end + + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) begin + mem_rd_data_valid <= '0; + end + else if (zeroize) begin + mem_rd_data_valid <= '0; + end + else begin + mem_rd_data_valid <= (mem_rd_req.rd_wr_en == RW_READ); + end + end + + //Flags + always_comb begin + last_poly_last_addr_rd = (mem_rd_addr == (src_base_addr + ((num_poly * (MLKEM_N/4))-1))) & ~mem_rd_data_hold; + + done = read_fsm_state_ps == CMP_RD_IDLE; + ld_rd_addr = arc_CMP_RD_IDLE_CMP_RD_MEM | arc_CMP_RD_MEM_CMD_RD_IDLE; + end + + //Read FSM + always_comb begin + arc_CMP_RD_IDLE_CMP_RD_MEM = (read_fsm_state_ps == CMP_RD_IDLE) & cmp_enable; + arc_CMP_RD_MEM_CMD_RD_IDLE = (read_fsm_state_ps == CMP_RD_MEM) & last_poly_last_addr_rd; + end + + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) + read_fsm_state_ps <= CMP_RD_IDLE; + else if (zeroize) + read_fsm_state_ps <= CMP_RD_IDLE; + else + read_fsm_state_ps <= read_fsm_state_ns; + end + + always_comb begin + upd_rd_addr = '0; + + case(read_fsm_state_ps) + CMP_RD_IDLE: begin + read_fsm_state_ns = arc_CMP_RD_IDLE_CMP_RD_MEM ? CMP_RD_MEM : CMP_RD_IDLE; + end + CMP_RD_MEM: begin + read_fsm_state_ns = arc_CMP_RD_MEM_CMD_RD_IDLE ? CMP_RD_IDLE : CMP_RD_MEM; + upd_rd_addr = 1'b1; + end + endcase + end + + //Assign outputs + always_comb begin + mem_rd_req.rd_wr_en = (read_fsm_state_ps == CMP_RD_MEM) ? RW_READ : RW_IDLE; + mem_rd_req.addr = mem_rd_addr; + end + +endmodule \ No newline at end of file diff --git a/designs/Caliptra/src/adams-bridge/compress_defines_pkg.sv b/designs/Caliptra/src/adams-bridge/compress_defines_pkg.sv new file mode 100644 index 0000000..c7bb4f4 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/compress_defines_pkg.sv @@ -0,0 +1,37 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +//====================================================================== +// +// compress_defines_pkg.sv +// -------- +// compress parameters for mlkem +//====================================================================== + +`ifndef MLKEM_COMPRESS_DEFINES +`define MLKEM_COMPRESS_DEFINES + +package compress_defines_pkg; + + typedef enum logic {CMP_RD_IDLE, CMP_RD_MEM} cmp_read_state_e; + typedef enum logic {CMP_WR_IDLE, CMP_WR_MEM} cmp_write_state_e; + + localparam compress1 = 'h0, + compress5 = 'h1, + compress11 = 'h2, + compress12 = 'h3; + + typedef logic [1:0] compress_mode_t; +endpackage + +`endif \ No newline at end of file diff --git a/designs/Caliptra/src/adams-bridge/compress_top.sv b/designs/Caliptra/src/adams-bridge/compress_top.sv new file mode 100644 index 0000000..f54c8c8 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/compress_top.sv @@ -0,0 +1,194 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +//====================================================================== +// +// compress_top.sv +// -------- +// This module processes 4 coeffs/clk and is fully pipelined. +// Each command trigger will compute compression over num_polynomials and produces a done signal at the end of the last polynomial. +// Compare mode is used to compare encaps resulting ciphertext with the ciphertext from decaps step +// Instead of writing to the API memory, reads are made and the data is compared against the compressed data + +module compress_top + import abr_params_pkg::*; + import compress_defines_pkg::*; + ( + input wire clk, + input wire reset_n, + input wire zeroize, + + input wire compress_enable, + input compress_mode_t mode, + input logic compare_mode, + input wire [2:0] num_poly, + input wire [ABR_MEM_ADDR_WIDTH-1:0] src_base_addr, + input wire [ABR_MEM_ADDR_WIDTH-1:0] dest_base_addr, + + output mem_if_t mem_rd_req, + input wire [COEFF_PER_CLK-1:0][REG_SIZE-1:0] mem_rd_data, + + output logic [1:0] api_rw_en, + output logic [ABR_MEM_ADDR_WIDTH-1:0] api_rw_addr, + output logic [DATA_WIDTH-1:0] api_wr_data, + input logic [DATA_WIDTH-1:0] api_rd_data, + output logic compare_failed, + output logic compress_done + ); + + localparam COMP_DATA_W = MLKEM_Q_WIDTH; + + logic [COEFF_PER_CLK-1:0][MLKEM_Q_WIDTH-1:0] compress_data_i, compress_data_o, compress_data; + logic [COEFF_PER_CLK-1:0][MLKEM_Q_WIDTH-1:0] mem_rd_data_stalled; + logic [COMP_DATA_W-1:0] compress_data_valid; + logic read_done; + logic mem_rd_data_valid; + logic mem_rd_data_hold,mem_rd_data_hold_f ; + logic buffer_valid, buffer_valid_f; + logic [DATA_WIDTH-1:0] buffer_data, buffer_data_f; + logic compress_busy; + + always_comb compress_done = compress_busy & read_done & ~(mem_rd_data_valid | (|api_rw_en) | buffer_valid | buffer_valid_f); + + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) begin + compress_busy <= '0; + mem_rd_data_hold_f <= '0; + end + else if (zeroize) begin + compress_busy <= '0; + mem_rd_data_hold_f <= '0; + end + else begin + compress_busy <= compress_enable ? '1 : + compress_done ? '0 : compress_busy; + mem_rd_data_hold_f <= mem_rd_data_hold; + end + end + + compress_ctrl cmp_ctrl_inst ( + .clk(clk), + .reset_n(reset_n), + .zeroize(zeroize), + .cmp_enable(compress_enable), + .num_poly(num_poly), + .src_base_addr(src_base_addr), + .mem_rd_req(mem_rd_req), + .mem_rd_data_valid(mem_rd_data_valid), + .mem_rd_data_hold(mem_rd_data_hold), + .done(read_done) + ); + + generate + for (genvar i = 0; i < COEFF_PER_CLK; i++) begin : gen_mem_rd_data_stalled + + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) begin + mem_rd_data_stalled[i] <= '0; + end + else if (zeroize) begin + mem_rd_data_stalled[i] <= '0; + end + else begin + mem_rd_data_stalled[i] <= mem_rd_data[i][MLKEM_Q_WIDTH-1:0]; + end + end + + always_comb compress_data_i[i] = mem_rd_data_hold_f ? mem_rd_data_stalled[i] : mem_rd_data[i][MLKEM_Q_WIDTH-1:0]; + + compress cmp_inst ( + .op_i(compress_data_i[i]), + .mode(mode), + .op_o(compress_data_o[i]) + ); + end + endgenerate + + always_comb begin + unique case (mode) + compress1: begin + compress_data = {44'b0, compress_data_o[3][0:0], compress_data_o[2][0:0], compress_data_o[1][0:0],compress_data_o[0][0:0]}; + compress_data_valid = COMP_DATA_W'({COMP_DATA_W{mem_rd_data_valid | mem_rd_data_hold_f}} >> 11); + end + compress5: begin + compress_data = {28'b0, compress_data_o[3][4:0], compress_data_o[2][4:0], compress_data_o[1][4:0],compress_data_o[0][4:0]}; + compress_data_valid = COMP_DATA_W'({COMP_DATA_W{mem_rd_data_valid | mem_rd_data_hold_f}} >> 7); + end + compress11: begin + compress_data = {4'b0, compress_data_o[3][10:0], compress_data_o[2][10:0], compress_data_o[1][10:0],compress_data_o[0][10:0]}; + compress_data_valid = COMP_DATA_W'({COMP_DATA_W{mem_rd_data_valid | mem_rd_data_hold_f}} >> 1); + end + compress12: begin + compress_data = compress_data_o; + compress_data_valid = {COMP_DATA_W{mem_rd_data_valid | mem_rd_data_hold_f}}; + end + default: begin + compress_data = compress_data_o; // Default case + compress_data_valid = '0; + end + endcase + end + + abr_sample_buffer #( + .BUFFER_DATA_W(4), + .NUM_WR(12), + .NUM_RD(8) + ) compress_sample_buffer_inst ( + .clk(clk), + .rst_b(reset_n), + .zeroize(zeroize), + .data_i(compress_data), + .data_valid_i(compress_data_valid), + .buffer_full_o(mem_rd_data_hold), + .data_valid_o(buffer_valid), + .data_o(buffer_data) + ); + + //Compute API write address + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) begin + api_rw_addr <= '0; + end + else if (zeroize) begin + api_rw_addr <= '0; + end + else if (compress_enable) begin + api_rw_addr <= dest_base_addr; + end + else if (|api_rw_en) begin + api_rw_addr <= api_rw_addr + 'd1; + end + end + //api write interface + always_comb api_rw_en[0] = buffer_valid & ~compare_mode; + always_comb api_wr_data = buffer_data; + //api read interface for compare mode + always_comb api_rw_en[1] = buffer_valid & compare_mode; + always_comb compare_failed = compare_mode & buffer_valid_f & (buffer_data_f != api_rd_data); + + always_ff@(posedge clk or negedge reset_n) begin + if (!reset_n) begin + buffer_valid_f <= '0; + buffer_data_f <= '0; + end + else if (zeroize) begin + buffer_valid_f <= '0; + buffer_data_f <= '0; + end + else begin + buffer_valid_f <= buffer_valid; + buffer_data_f <= buffer_valid ? buffer_data : buffer_data_f; + end + end + +endmodule diff --git a/designs/Caliptra/src/adams-bridge/decompose.sv b/designs/Caliptra/src/adams-bridge/decompose.sv new file mode 100644 index 0000000..f722dff --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/decompose.sv @@ -0,0 +1,273 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +//====================================================================== +// +// decompose.sv +// -------- +// Breaks down r coefficient into high and low bits such that +// r = r1*(2*GAMMA2) + r0 mod q where +// r0 is between -GAMMA2 and +GAMMA2. For a corner case where +// r-r0 = q-1, r1 is made 0 and r0 is reduced by 1 i.e., +// r0 = r0 - 1 == r mod q (See HW spec for more details) +// Decompose unit also optimizes makehint arch by generating a bit that +// computes z = (r1 != 0) check and directly stores the result in a buffer. +// Makehint is able to read the buffer during hint gen and receives 4 bits per 4 coeff per cycle + +// Output of mod_2gamma2 goes through further calc to compute r0 mod+- (2gamma2) mod q. This is the +// final r0 output to be stored in memory. + +// Decompose unit produces 3 outputs: +// 1. r0 --> store in memory +// 2. r1 --> pass to sample inball/hash interface +// 3. z_neq_z --> store in a buffer that is ready by makehint simultaneously when it reads main mem + +`include "abr_prim_assert.sv" + +module decompose + import abr_params_pkg::*; + import decompose_defines_pkg::*; + #( + parameter Q_MINUS_2GAMMA2 = MLDSA_Q - (2*MLDSA_GAMMA2) + ) + ( + input wire clk, + input wire reset_n, + input wire zeroize, + + input wire decompose_enable, + input dcmp_mode_t dcmp_mode, + input wire [ABR_MEM_ADDR_WIDTH-1:0] src_base_addr, + input wire [ABR_MEM_ADDR_WIDTH-1:0] dest_base_addr, + input wire [ABR_MEM_ADDR_WIDTH-1:0] hint_src_base_addr, + + //Output to memory - r0 + output mem_if_t mem_rd_req, + output mem_if_t mem_wr_req, + input wire [(4*REG_SIZE)-1:0] mem_rd_data, + output logic [(4*REG_SIZE)-1:0] mem_wr_data, + + //Output to memory - h (sigDecode) + output mem_if_t mem_hint_rd_req, + input wire [(4*REG_SIZE)-1:0] mem_hint_rd_data, + + //Output to z mem - z != 0 + output mem_if_t z_mem_wr_req, + output logic [3:0] z_neq_z, + + //Output of w1_encode - r1 + output logic [63:0] w1_o, + output logic buffer_en, + + output logic decompose_done + + + ); + + //Coefficient wires + logic [3:0][3:0] r1, r1_reg, r1_usehint, r1_mux; + logic [3:0] r_corner, r_corner_reg; + logic [3:0][18:0] r0_mod_2gamma2; + logic [3:0][REG_SIZE-2:0] r0_mod_q, r0, r0_reg; //23-bit value + logic [(4*REG_SIZE)-1:0] mem_rd_data_reg, mem_hint_rd_data_reg, mem_wr_data_int; + mem_if_t mem_wr_req_int, mem_hint_rd_req_int, z_mem_wr_req_int; + logic [3:0] z_neq_z_d1, z_neq_z_d2, z_neq_z_int, z_neq_z_mux; + + //Control wires + logic mod_enable; + logic [1:0] enable_reg; + logic [3:0] mod_ready; + logic verify; + logic [3:0] usehint_ready; + + always_comb verify = (dcmp_mode == verify_op); + + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) begin + enable_reg <= 'b0; + z_neq_z_d1 <= 'h0; + z_neq_z_d2 <= 'h0; + end + else if (zeroize) begin + enable_reg <= 'b0; + z_neq_z_d1 <= 'h0; + z_neq_z_d2 <= 'h0; + end + else begin + enable_reg <= {mod_enable, enable_reg[1]}; + z_neq_z_d1 <= z_neq_z_int; + z_neq_z_d2 <= z_neq_z_d1; + end + end + + decompose_ctrl + dcmp_ctrl_inst ( + .clk(clk), + .reset_n(reset_n), + .zeroize(zeroize), + .decompose_enable(decompose_enable), + .src_base_addr(src_base_addr), + .dest_base_addr(dest_base_addr), + .r0_ready(&mod_ready), //all redux units must be ready at the same time + .mem_rd_req(mem_rd_req), + .mem_wr_req(mem_wr_req_int), + .mod_enable(mod_enable), + .decompose_done(decompose_done) + ); + + generate + for (genvar i = 0; i < 4; i++) begin : gen_r1_lut + decompose_r1_lut #( + .REG_SIZE(REG_SIZE-1) + ) + r1_lut_inst ( + .r(mem_rd_data[(REG_SIZE-2)+(i*REG_SIZE):i*REG_SIZE]), + .r1(r1[i]), + .r_corner(r_corner[i]), + .z_nez(z_neq_z_int[i]) + ); + end + endgenerate + + generate + for(genvar i = 0; i < 4; i++) begin : gen_dcmp_redux + decompose_mod_2gamma2 #( + .REG_SIZE(REG_SIZE-1) + ) + dcmp_redux_inst ( + .clk(clk), + .reset_n(reset_n), + .zeroize(zeroize), + .add_en_i(enable_reg[1]), //delayed by 1 clk + .opa_i(mem_rd_data[(REG_SIZE-2)+(i*REG_SIZE):i*REG_SIZE]), + .res_o(r0_mod_2gamma2[i]), + .ready_o(mod_ready[i]) + ); + end + endgenerate + + generate + for (genvar i = 0; i < 4; i++) begin + always_comb begin + r0_mod_q[i] = (r0_mod_2gamma2[i] <= MLDSA_GAMMA2) ? {4'h0, r0_mod_2gamma2[i]} : (REG_SIZE-1)'(r0_mod_2gamma2[i] + Q_MINUS_2GAMMA2); + end + end + endgenerate + + //Delay flops + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) begin + r_corner_reg <= 'h0; + mem_rd_data_reg <= 'h0; + r0_reg <= 'h0; + r1_reg <= 'h0; + mem_hint_rd_data_reg <= 'h0; + end + else if (zeroize) begin + r_corner_reg <= 'h0; + mem_rd_data_reg <= 'h0; + r0_reg <= 'h0; + r1_reg <= 'h0; + mem_hint_rd_data_reg <= 'h0; + end + else begin + r_corner_reg <= r_corner; + mem_rd_data_reg <= mem_rd_data; + r0_reg <= r0; + r1_reg <= r1; + mem_hint_rd_data_reg <= mem_hint_rd_data; + end + end + + generate + for (genvar i = 0; i < 4; i++) begin + always_comb begin + r0[i] = r_corner_reg[i] ? mem_rd_data_reg[i*REG_SIZE+(REG_SIZE-2):i*REG_SIZE] : r0_mod_q[i]; + mem_wr_data_int[i*REG_SIZE+(REG_SIZE-1):i*REG_SIZE] = verify ? 'h0 : {1'b0, r0_reg[i]}; + end + end + endgenerate + + generate + for (genvar i = 0; i < 4; i++) begin : gen_usehint + decompose_usehint #( + .REG_SIZE(REG_SIZE-1) + ) + usehint_inst ( + .clk(clk), + .reset_n(reset_n), + .zeroize(zeroize), + .usehint_enable(verify & enable_reg[0]), //delayed by 2 clks to match addr input flops + .w0_i(r0[i]), + .w1_i(r1_reg[i]), + .hint_i(mem_hint_rd_data_reg[i*REG_SIZE]), //LSB is the hint, rest are 0s + .w1_o(r1_usehint[i]), + .ready_o(usehint_ready[i]) + + ); + end + endgenerate + + always_comb begin + z_neq_z_mux = verify ? 'h0 : z_neq_z_d2; + z_mem_wr_req_int.rd_wr_en = verify ? RW_IDLE : mem_wr_req_int.rd_wr_en; + z_mem_wr_req_int.addr = verify ? 'h0 : ABR_MEM_ADDR_WIDTH'(mem_wr_req_int.addr - dest_base_addr); + r1_mux = verify & (&usehint_ready) ? r1_usehint : r1_reg; + + mem_hint_rd_req.addr = verify ? ABR_MEM_ADDR_WIDTH'(mem_rd_req.addr - src_base_addr + hint_src_base_addr) : 'h0; + mem_hint_rd_req.rd_wr_en = verify ? mem_rd_req.rd_wr_en : RW_IDLE; + end + + //Output flops + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) begin + z_mem_wr_req <= '{rd_wr_en: RW_IDLE, addr: '0}; + mem_wr_req <= '{rd_wr_en: RW_IDLE, addr: '0}; + + z_neq_z <= '0; + mem_wr_data <= '0; + end + else if (zeroize) begin + z_mem_wr_req <= '{rd_wr_en: RW_IDLE, addr: '0}; + mem_wr_req <= '{rd_wr_en: RW_IDLE, addr: '0}; + + z_neq_z <= '0; + mem_wr_data <= '0; + end + else begin + z_mem_wr_req <= z_mem_wr_req_int; + mem_wr_req.addr <= verify ? 'h0 : mem_wr_req_int.addr; + mem_wr_req.rd_wr_en <= verify ? RW_IDLE : mem_wr_req_int.rd_wr_en; + + z_neq_z <= z_neq_z_mux; + mem_wr_data <= mem_wr_data_int; + end + end + + //w1 Encode + decompose_w1_encode w1_enc_inst ( + .clk(clk), + .reset_n(reset_n), + .zeroize(zeroize), + .w1_encode_enable(verify ? &usehint_ready : &mod_ready), + .r1_i(r1_mux), + .w1_o(w1_o), + .buffer_en(buffer_en) + ); + + + `ABR_ASSERT_MUTEX(ASSERT_R0_CORNER_MUTEX, {r_corner[0], r1[0]}, clk, reset_n) + `ABR_ASSERT_MUTEX(ASSERT_R1_CORNER_MUTEX, {r_corner[1], r1[1]}, clk, reset_n) + `ABR_ASSERT_MUTEX(ASSERT_R2_CORNER_MUTEX, {r_corner[2], r1[2]}, clk, reset_n) + `ABR_ASSERT_MUTEX(ASSERT_R3_CORNER_MUTEX, {r_corner[3], r1[3]}, clk, reset_n) +endmodule diff --git a/designs/Caliptra/src/adams-bridge/decompose_ctrl.sv b/designs/Caliptra/src/adams-bridge/decompose_ctrl.sv new file mode 100644 index 0000000..1a30a26 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/decompose_ctrl.sv @@ -0,0 +1,181 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +//====================================================================== +// +// decompose_ctrl.sv +// ----------- +// Takes care of memory accesses during decompose function + +module decompose_ctrl + import abr_params_pkg::*; + import decompose_defines_pkg::*; + ( + input wire clk, + input wire reset_n, + input wire zeroize, + + input wire decompose_enable, //Assumes polynomials are stored in contiguous locations and 1 enable will trig all 8 at once + input wire [ABR_MEM_ADDR_WIDTH-1:0] src_base_addr, + input wire [ABR_MEM_ADDR_WIDTH-1:0] dest_base_addr, + input wire r0_ready, + + output mem_if_t mem_rd_req, + output mem_if_t mem_wr_req, + output logic mod_enable, + output logic decompose_done + ); + + //Internals + logic [ABR_MEM_ADDR_WIDTH-1:0] src_base_addr_reg, dest_base_addr_reg; + logic [ABR_MEM_ADDR_WIDTH-1:0] mem_rd_addr_nxt, mem_wr_addr_nxt; + logic [ABR_MEM_ADDR_WIDTH-1:0] mem_rd_addr, mem_wr_addr; + logic incr_rd_addr, incr_wr_addr; + logic rst_rd_addr, rst_wr_addr; + logic last_poly_last_addr_rd; //TODO: confirm that decompose take 8 polys. If there's a case with 7 polys, need to change code + logic last_poly_last_addr_wr; + logic decompose_busy; + + dcmp_read_state_e read_fsm_state_ps, read_fsm_state_ns; + dcmp_write_state_e write_fsm_state_ps, write_fsm_state_ns; + + logic arc_DCMP_RD_IDLE_DCMP_RD_MEM; + logic arc_DCMP_RD_MEM_DCMP_RD_IDLE; + + logic arc_DCMP_WR_IDLE_DCMP_WR_MEM; + logic arc_DCMP_WR_MEM_DCMP_WR_IDLE; + + //Read addr counter + always_comb mem_rd_addr_nxt = mem_rd_addr + 'h1; + + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) begin + mem_rd_addr <= 'h0; + src_base_addr_reg <= 'h0; + end + else if (zeroize) begin + mem_rd_addr <= 'h0; + src_base_addr_reg <= 'h0; + end + else if (rst_rd_addr) begin + mem_rd_addr <= src_base_addr; + src_base_addr_reg <= src_base_addr; + end + else if (incr_rd_addr) begin + mem_rd_addr <= last_poly_last_addr_rd ? 'h0 : mem_rd_addr_nxt; + end + end + + //Write addr counter + always_comb mem_wr_addr_nxt = mem_wr_addr + 'h1; + + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) begin + mem_wr_addr <= 'h0; + dest_base_addr_reg <= 'h0; + end + else if (zeroize) begin + mem_wr_addr <= 'h0; + dest_base_addr_reg <= 'h0; + end + else if (rst_wr_addr) begin + mem_wr_addr <= dest_base_addr; + dest_base_addr_reg <= dest_base_addr; + end + else if (incr_wr_addr) begin + mem_wr_addr <= last_poly_last_addr_wr ? 'h0 : mem_wr_addr_nxt; + end + end + + //Flags + assign last_poly_last_addr_rd = (mem_rd_addr == src_base_addr_reg + (MLDSA_K * (MLDSA_N/4))-1); + assign last_poly_last_addr_wr = (mem_wr_addr == dest_base_addr_reg + (MLDSA_K * (MLDSA_N/4))-1); + assign decompose_busy = (read_fsm_state_ps != DCMP_RD_IDLE); + assign decompose_done = (read_fsm_state_ps == DCMP_RD_IDLE) & (write_fsm_state_ps == DCMP_WR_IDLE); + + //Read fsm + always_comb begin + arc_DCMP_RD_IDLE_DCMP_RD_MEM = (read_fsm_state_ps == DCMP_RD_IDLE) && decompose_enable; + arc_DCMP_RD_MEM_DCMP_RD_IDLE = (read_fsm_state_ps == DCMP_RD_MEM) && last_poly_last_addr_rd; + end + + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) + read_fsm_state_ps <= DCMP_RD_IDLE; + else if (zeroize) + read_fsm_state_ps <= DCMP_RD_IDLE; + else + read_fsm_state_ps <= read_fsm_state_ns; + end + + always_comb begin + incr_rd_addr = 'b0; + rst_rd_addr = 'b0; + mod_enable = 'b0; + + case(read_fsm_state_ps) + DCMP_RD_IDLE: begin + read_fsm_state_ns = arc_DCMP_RD_IDLE_DCMP_RD_MEM ? DCMP_RD_MEM : DCMP_RD_IDLE; + rst_rd_addr = 'b1; + end + DCMP_RD_MEM: begin + read_fsm_state_ns = arc_DCMP_RD_MEM_DCMP_RD_IDLE ? DCMP_RD_IDLE : DCMP_RD_MEM; + incr_rd_addr = 'b1; + mod_enable = 'b1; + end + endcase + end + + //Write fsm + always_comb begin + //Move to write mem state when reads are ongoing and mod 2gamma2 block has valid outputs + arc_DCMP_WR_IDLE_DCMP_WR_MEM = (write_fsm_state_ps == DCMP_WR_IDLE) && decompose_busy && r0_ready; + arc_DCMP_WR_MEM_DCMP_WR_IDLE = (write_fsm_state_ps == DCMP_WR_MEM) && last_poly_last_addr_wr; + end + + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) + write_fsm_state_ps <= DCMP_WR_IDLE; + else if (zeroize) + write_fsm_state_ps <= DCMP_WR_IDLE; + else + write_fsm_state_ps <= write_fsm_state_ns; + end + + always_comb begin + incr_wr_addr = 'b0; + rst_wr_addr = 'b0; + + case(write_fsm_state_ps) + DCMP_WR_IDLE: begin + write_fsm_state_ns = arc_DCMP_WR_IDLE_DCMP_WR_MEM ? DCMP_WR_MEM : DCMP_WR_IDLE; + rst_wr_addr = 'b1; + end + DCMP_WR_MEM: begin + write_fsm_state_ns = arc_DCMP_WR_MEM_DCMP_WR_IDLE ? DCMP_WR_IDLE : DCMP_WR_MEM; + incr_wr_addr = 'b1; + end + endcase + end + + //Assign outputs + always_comb begin + mem_rd_req.rd_wr_en = (read_fsm_state_ps == DCMP_RD_MEM) ? RW_READ : RW_IDLE; + mem_rd_req.addr = mem_rd_addr; + + mem_wr_req.rd_wr_en = (write_fsm_state_ps == DCMP_WR_MEM) ? RW_WRITE : RW_IDLE; + mem_wr_req.addr = mem_wr_addr; + end + + +endmodule \ No newline at end of file diff --git a/designs/Caliptra/src/adams-bridge/decompose_defines_pkg.sv b/designs/Caliptra/src/adams-bridge/decompose_defines_pkg.sv new file mode 100644 index 0000000..c6eb601 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/decompose_defines_pkg.sv @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +//====================================================================== +// +// decompose_defines_pkg.sv +// -------- +// Decompose parameters for Mldsa +//====================================================================== + +`ifndef MLDSA_DECOMPOSE_DEFINES +`define MLDSA_DECOMPOSE_DEFINES + +package decompose_defines_pkg; + + typedef enum logic {DCMP_RD_IDLE, DCMP_RD_MEM} dcmp_read_state_e; + typedef enum logic {DCMP_WR_IDLE, DCMP_WR_MEM} dcmp_write_state_e; + + localparam sign_op = 'h0, + verify_op = 'h1; + + typedef logic dcmp_mode_t; +endpackage + +`endif \ No newline at end of file diff --git a/designs/Caliptra/src/adams-bridge/decompose_mod_2gamma2.sv b/designs/Caliptra/src/adams-bridge/decompose_mod_2gamma2.sv new file mode 100644 index 0000000..299b059 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/decompose_mod_2gamma2.sv @@ -0,0 +1,106 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +//====================================================================== +// +// decompose_mod_2gamma2.sv +// ------------ +// computes r0 mod (2gamma2). Input is 23 bit and produces r0 mod 2gamma2 is 19 bits + + +module decompose_mod_2gamma2 + import abr_params_pkg::*; + #( + parameter REG_SIZE = abr_params_pkg::REG_SIZE-1, + localparam MLDSA_2GAMMA2_SIZE = $clog2(2*MLDSA_GAMMA2) + ) + ( + // Clock and reset. + input wire clk, + input wire reset_n, + input wire zeroize, + + // DATA PORT + input wire add_en_i, + input wire [REG_SIZE-1:0] opa_i, + output logic [MLDSA_2GAMMA2_SIZE-1:0] res_o, + output logic ready_o +); + + logic [12:0] opa0; + logic [MLDSA_2GAMMA2_SIZE-1:0] opb0; + logic [MLDSA_2GAMMA2_SIZE-1:0] opb1; + logic [MLDSA_2GAMMA2_SIZE-1:0] r0; + logic [MLDSA_2GAMMA2_SIZE-1:0] r1; + logic carry0; + + logic [MLDSA_2GAMMA2_SIZE-1:0] r0_reg; + logic carry0_reg; + + logic carry1; + + assign opa0 = 13'(opa_i[22:19] << 9); + assign opb0 = opa_i[MLDSA_2GAMMA2_SIZE-1:0]; + + abr_adder #( + .RADIX(MLDSA_2GAMMA2_SIZE) + ) + adder_inst_0( + .a_i({6'h0,opa0}), + .b_i(opb0), + .cin_i(1'b0), + .s_o(r0), + .cout_o(carry0) + ); + + abr_adder #( + .RADIX(MLDSA_2GAMMA2_SIZE) + ) + adder_inst_1( + .a_i(r0_reg), + .b_i(opb1), + .cin_i(1'b1), + .s_o(r1), + .cout_o(carry1) + ); + + + always_ff @(posedge clk or negedge reset_n) + begin + if(!reset_n) begin + r0_reg <= '0; + carry0_reg <= '0; + opb1 <= '0; + end + else if (zeroize) begin + r0_reg <= '0; + carry0_reg <= '0; + opb1 <= '0; + end + else if (add_en_i) begin + r0_reg <= r0; + carry0_reg <= carry0; + opb1 <= ~MLDSA_2GAMMA2_SIZE'(2*MLDSA_GAMMA2); + end + end + + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) ready_o <= 'b0; + else if (zeroize) ready_o <= 'b0; + else ready_o <= add_en_i; + end + + assign res_o = (carry0_reg ^ carry1) ? r1 : r0_reg; + + +endmodule \ No newline at end of file diff --git a/designs/Caliptra/src/adams-bridge/decompose_r1_lut.sv b/designs/Caliptra/src/adams-bridge/decompose_r1_lut.sv new file mode 100644 index 0000000..ce41208 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/decompose_r1_lut.sv @@ -0,0 +1,62 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +//====================================================================== +// +// decompose_r1_lut.sv +// -------- +// Breaks down input coefficient r into highbits(r) +// Follows a look up table to determine the value of r1 based on input r +// In a corner case, when r is greater than 31γ2+1 and less than q-1, r1 is made 0 +//====================================================================== + +module decompose_r1_lut + import abr_params_pkg::*; + #( + parameter REG_SIZE = 23 + ) + ( + input wire [REG_SIZE-1:0] r, + output logic [3:0] r1, + output logic r_corner, //Indicates if coeff r is in the corner case range + output logic z_nez + ); + + always_comb begin + r_corner = 'b0; + if (r <= MLDSA_GAMMA2) r1 = 'd0; + else if (r <= 3*MLDSA_GAMMA2) r1 = 'd1; + else if (r <= 5*MLDSA_GAMMA2) r1 = 'd2; + else if (r <= 7*MLDSA_GAMMA2) r1 = 'd3; + else if (r <= 9*MLDSA_GAMMA2) r1 = 'd4; + else if (r <= 11*MLDSA_GAMMA2) r1 = 'd5; + else if (r <= 13*MLDSA_GAMMA2) r1 = 'd6; + else if (r <= 15*MLDSA_GAMMA2) r1 = 'd7; + else if (r <= 17*MLDSA_GAMMA2) r1 = 'd8; + else if (r <= 19*MLDSA_GAMMA2) r1 = 'd9; + else if (r <= 21*MLDSA_GAMMA2) r1 = 'd10; + else if (r <= 23*MLDSA_GAMMA2) r1 = 'd11; + else if (r <= 25*MLDSA_GAMMA2) r1 = 'd12; + else if (r <= 27*MLDSA_GAMMA2) r1 = 'd13; + else if (r <= 29*MLDSA_GAMMA2) r1 = 'd14; + else if (r <= 31*MLDSA_GAMMA2) r1 = 'd15; + else + begin + r1 = 'd0; + r_corner = 'b1; + end + end + + always_comb z_nez = (r1 != 'h0); + +endmodule \ No newline at end of file diff --git a/designs/Caliptra/src/adams-bridge/decompose_usehint.sv b/designs/Caliptra/src/adams-bridge/decompose_usehint.sv new file mode 100644 index 0000000..4818e21 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/decompose_usehint.sv @@ -0,0 +1,124 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +//====================================================================== +// +// decompose_usehint.sv +// ------------ +// Consumes output of decompose and hint bit from makehint to modify w1 component +// before performing w1Encode on it +// This unit performs the following calc: +// (w0 == 0 || w0 > gamma2) ? (w1 = (w1-1) mod 16) : (w1 = (w1 + 1) mod 16) +// If makehint hint bit is 0, w1 is directly passed onto w1 encode. If makehint hint bit is 1, +// above modified w1 is passed onto w1 encode + +module decompose_usehint + import abr_params_pkg::*; + #( + parameter REG_SIZE = 23 + ) + ( + input wire clk, + input wire reset_n, + input wire zeroize, + + input wire usehint_enable, + input wire [REG_SIZE-1:0] w0_i, + input wire [3:0] w1_i, + input wire hint_i, + + //output to w1 encode + output logic [3:0] w1_o, + output logic ready_o + ); + + logic [3:0] w1_plus_one, w1_minus_one; + logic [3:0] w1_mux; + logic ready; + logic [REG_SIZE-1:0] w0_reg; + logic [3:0] w1_reg; + logic hint_reg; + + //Delay flops + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) begin + w0_reg <= 'h0; + w1_reg <= 'h0; + hint_reg <= 'h0; + end + else if (zeroize) begin + w0_reg <= 'h0; + w1_reg <= 'h0; + hint_reg <= 'h0; + end + else begin + w0_reg <= w0_i; + w1_reg <= w1_i; + hint_reg <= hint_i; + end + end + + abr_add_sub_mod #( + .REG_SIZE(4) + ) + usehint_add_inst ( + .clk(clk), + .reset_n(reset_n), + .zeroize(zeroize), + .add_en_i(usehint_enable), + .sub_i(1'b0), + .opa_i(w1_i), + .opb_i(4'(1)), + .prime_i(4'(16)), + .res_o(w1_plus_one), + .ready_o() + ); + + abr_add_sub_mod #( + .REG_SIZE(4) + ) + usehint_sub_inst ( + .clk(clk), + .reset_n(reset_n), + .zeroize(zeroize), + .add_en_i(usehint_enable), + .sub_i(1'b1), + .opa_i(w1_i), + .opb_i(4'(1)), + .prime_i(4'(16)), + .res_o(w1_minus_one), + .ready_o() + ); + + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) + ready <= 'b0; + else if (zeroize) + ready <= 'b0; + else + ready <= usehint_enable; + end + + always_comb begin + if (ready) begin + w1_mux = ((w0_reg == 'h0) | (w0_reg > MLDSA_GAMMA2)) ? w1_minus_one : w1_plus_one; + w1_o = hint_reg ? w1_mux : w1_reg; + end + else begin + w1_mux = 'h0; + w1_o = 'h0; + end + end + + always_comb ready_o = ready; +endmodule diff --git a/designs/Caliptra/src/adams-bridge/decompose_w1_encode.sv b/designs/Caliptra/src/adams-bridge/decompose_w1_encode.sv new file mode 100644 index 0000000..fc65fba --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/decompose_w1_encode.sv @@ -0,0 +1,93 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +//====================================================================== +// +// decompose_w1_encode.sv +// -------- +// 1. Decompose produces 4-bits * 4 = 16-bits of r1 per cycle. This needs to be +// consumed by Keccak which takes 64-bits per cycle. w1_encode block buffers +// 16-bits per cycle and asserts a valid every 4 cycles indicating 64-bits are ready +// for Keccak to sample. +// 2. Keccak also needs an enable once every 1088 bits (block length) to process the buffered +// data. w1_encode also provides this enable by counting 17 iterations of buffer valid +// i.e., 17 * 64-bits = 1088 bits. For every 17 4-cycle loops, keccak is enabled. +// 3. Corner case: the 1st iteration of Keccak takes mu || w1 as input where mu is 512 bits +// So, only 576 bits of w1 are needed and then Keccak can be enabled. In this case, +// the keccak_en is asserted after 9 loops (9*64-bits = 576 bits). +// 4. w1_encode must be performed on 8 input polynomials. Once 8-rounds are Keccak are done, +// high level controller issues the last round with padding and enables Keccak. + +module decompose_w1_encode + import abr_params_pkg::*; + ( + input wire clk, + input wire reset_n, + input wire zeroize, + + input wire w1_encode_enable, //level not pulse. Indicates r1 lut is valid from decompose block + input wire [3:0][3:0] r1_i, + + output logic [63:0] w1_o, + output logic buffer_en + ); + + localparam BUFFER_CYC = 4; + + //Enable counter + logic [1:0] buffer_count; + + //Flags + logic w1_en_reg; + logic init_count_first; + logic decr_buf_count; + + //Generate a pulse to init counters + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) + w1_en_reg <= 'b0; + else if (zeroize) + w1_en_reg <= 'b0; + else + w1_en_reg <= w1_encode_enable; + end + assign init_count_first = w1_encode_enable & ~w1_en_reg; + + //Decr logic + assign decr_buf_count = w1_en_reg; + + //Buffer enable counter + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) + buffer_count <= 'h0; + else if (zeroize) + buffer_count <= 'h0; + else if (init_count_first) + buffer_count <= BUFFER_CYC-1; + else if (decr_buf_count) + buffer_count <= buffer_count - 'h1; + end + + assign buffer_en = w1_en_reg && (buffer_count == 'h0); + + //r1 shift reg + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) + w1_o <= 'h0; + else if (zeroize) + w1_o <= 'h0; + else if (w1_encode_enable) + w1_o <= {r1_i, w1_o[63:16]}; + end + +endmodule \ No newline at end of file diff --git a/designs/Caliptra/src/adams-bridge/decompose_w1_mem.sv b/designs/Caliptra/src/adams-bridge/decompose_w1_mem.sv new file mode 100644 index 0000000..0e8abd7 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/decompose_w1_mem.sv @@ -0,0 +1,76 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +//====================================================================== +// +// decompose_w1_mem.sv +// -------- +// Stores 256-bit z components for 8 polynomials (256*8 = 2048 bits) +// z value is derived from r1 of decompose unit. z = (r1 != 0) +// Decompose unit writes to this buffer. Makehint reads from this buffer +// to calculate hint as needed. +// To align with main memory access pattern, this buffer also stores 4 bits per addr +// that represent 4 coeffs. Hence, 64 locations are needed per poly + +module decompose_w1_mem #( + parameter ADDR_WIDTH = 9, //8 poly * 64 addr per poly = 512 locations + parameter DATA_WIDTH = 4 + ) + ( + input wire clk, + input wire reset_n, + input wire zeroize, + + input wire rden, //read en + input wire wren, //write en + input wire [ADDR_WIDTH-1 : 0] addr, + input wire [DATA_WIDTH-1 : 0] din, + output logic [DATA_WIDTH-1 : 0] dout + ); + + // Declare the RAM variable + localparam ADDR_LENGTH = 2**ADDR_WIDTH; + reg [DATA_WIDTH-1:0] mem[ADDR_LENGTH-1:0]; + + + always_ff @ (posedge clk or negedge reset_n) + begin : reading_memory + if (!reset_n) begin + dout <= '0; + end + else if (zeroize) begin + dout <= '0; + end + else begin + if (rden) + dout <= mem[addr]; + end + end // reading_memory + + always_ff @ (posedge clk or negedge reset_n) + begin : writing_memory + if (!reset_n) begin + for (int i0 = 0; i0 < ADDR_LENGTH; i0++) + mem[i0] <= '0; + end + else if (zeroize) begin + for (int i0 = 0; i0 < ADDR_LENGTH; i0++) + mem[i0] <= '0; + end + else begin + if (wren) + mem[addr] <= din; + end + end // writing_memory + +endmodule diff --git a/designs/Caliptra/src/adams-bridge/decompress.sv b/designs/Caliptra/src/adams-bridge/decompress.sv new file mode 100644 index 0000000..48b5e79 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/decompress.sv @@ -0,0 +1,47 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +//====================================================================== +// +// decompress.sv +// -------- +// Converts d-bit coefficients into 12-bit representation where d is the decompression level. + +module decompress + import abr_params_pkg::*; + import decompress_defines_pkg::*; + ( + input wire [MLKEM_Q_WIDTH-1:0] op_i, + input decompress_mode_t mode, + output logic [MLKEM_Q_WIDTH-1:0] op_o + ); + + logic [3:0] d; + logic [(2*MLKEM_Q_WIDTH)-1:0] op_mult_add; + logic [MLKEM_Q_WIDTH-1:0] op; + + always_comb begin + unique case(mode) + DECOMPRESS1: d = 1; + DECOMPRESS5: d = 5; + DECOMPRESS11: d = 11; + default: d = 1; + endcase + end + + always_comb op = (op_i < MLKEM_Q) ? op_i : '0; // Sanitize input to be in range [0, q-1] + always_comb op_mult_add = (MLKEM_Q * op_i) + 2**(d - 1); + always_comb op_o = (mode == 3) ? op : MLKEM_Q_WIDTH'(op_mult_add >> d); + + +endmodule \ No newline at end of file diff --git a/designs/Caliptra/src/adams-bridge/decompress_ctrl.sv b/designs/Caliptra/src/adams-bridge/decompress_ctrl.sv new file mode 100644 index 0000000..25b412d --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/decompress_ctrl.sv @@ -0,0 +1,68 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +//====================================================================== +// +// decompress_ctrl.sv +// --------- +// Controls memory accesses and iterates over MLKEM_K = 4 polynomials before generating done + +module decompress_ctrl + import abr_params_pkg::*; + import decompress_defines_pkg::*; + ( + input wire clk, + input wire reset_n, + input wire zeroize, + + input wire decompress_enable, + input wire [2:0] num_poly, + input wire mem_wr_valid, + input wire [ABR_MEM_ADDR_WIDTH-1:0] dest_base_addr, + output logic [ABR_MEM_ADDR_WIDTH-1:0] mem_wr_addr, + output logic done + ); + + //Internals + logic last_poly_last_addr_wr; + + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) begin + mem_wr_addr <= '0; + end + else if (zeroize) begin + mem_wr_addr <= '0; + end + else if (last_poly_last_addr_wr) begin + mem_wr_addr <= '0; + end + else if (decompress_enable) begin + mem_wr_addr <= dest_base_addr; + end + else if (mem_wr_valid) begin + mem_wr_addr <= mem_wr_addr + 'h1; + end + end + + always_comb last_poly_last_addr_wr = (mem_wr_addr == (dest_base_addr + ((num_poly * (MLKEM_N/4))-1))); + + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) + done <= '0; + else if (zeroize) + done <= '0; + else + done <= last_poly_last_addr_wr; + end + +endmodule diff --git a/designs/Caliptra/src/adams-bridge/decompress_defines_pkg.sv b/designs/Caliptra/src/adams-bridge/decompress_defines_pkg.sv new file mode 100644 index 0000000..747f637 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/decompress_defines_pkg.sv @@ -0,0 +1,37 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +//====================================================================== +// +// decompress_defines_pkg.sv +// -------- +// decompress parameters for mlkem +//====================================================================== + +`ifndef MLKEM_DECOMPRESS_DEFINES +`define MLKEM_DECOMPRESS_DEFINES + +package decompress_defines_pkg; + + typedef enum logic {DCMP_RD_IDLE, DCMP_RD_MEM} decomp_read_state_e; + typedef enum logic {DCMP_WR_IDLE, DCMP_WR_MEM} decomp_write_state_e; + + localparam DECOMPRESS1 = 'h0, + DECOMPRESS5 = 'h1, + DECOMPRESS11 = 'h2, + DECOMPRESS12 = 'h3; + + typedef logic [1:0] decompress_mode_t; +endpackage + +`endif \ No newline at end of file diff --git a/designs/Caliptra/src/adams-bridge/decompress_top.sv b/designs/Caliptra/src/adams-bridge/decompress_top.sv new file mode 100644 index 0000000..f818a8d --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/decompress_top.sv @@ -0,0 +1,195 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +//====================================================================== +// +// decompress_top.sv +// -------- +// This module processes 4 coeffs/clk and is fully pipelined. +// Each command trigger will compute decompression over 4 polynomials and produces a done signal at the end of the last polynomial. + +module decompress_top + import abr_params_pkg::*; + import decompress_defines_pkg::*; + ( + input logic clk, + input logic reset_n, + input logic zeroize, + + input logic decompress_enable, + input decompress_mode_t mode, + input logic [2:0] num_poly, + input logic [ABR_MEM_ADDR_WIDTH-1:0] src_base_addr, + input logic [ABR_MEM_ADDR_WIDTH-1:0] dest_base_addr, + + output mem_if_t mem_wr_req, + output logic [COEFF_PER_CLK-1:0][MLDSA_Q_WIDTH-1:0] mem_wr_data, //Match memory width of ABR + + output logic api_rd_en, + output logic [ABR_MEM_ADDR_WIDTH-1:0] api_rd_addr, + input logic [1:0][DATA_WIDTH-1:0] api_rd_data, + + output logic decompress_done + ); + + localparam DECOMP_DATA_W = MLKEM_Q_WIDTH; + + logic api_rd_en_f; + logic piso_hold_o; + logic read_done; + logic [3:0] d; // Decompression count + logic piso_data_valid; + logic [(COEFF_PER_CLK*DECOMP_DATA_W)-1:0] piso_data_o; + logic [COEFF_PER_CLK-1:0][DECOMP_DATA_W-1:0] decompress_data_i; + logic [COEFF_PER_CLK-1:0][MLKEM_Q_WIDTH-1:0] decompress_data_o; + logic [ABR_MEM_ADDR_WIDTH-1:0] mem_wr_addr; + logic write_done; + logic decompress_busy; + + always_comb decompress_done = decompress_busy & write_done; + + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) begin + decompress_busy <= '0; + end + else if (zeroize) begin + decompress_busy <= '0; + end + else begin + decompress_busy <= decompress_enable ? '1 : + decompress_done ? '0 : decompress_busy; + end + end + + //Multi-rate piso + abr_piso_multi #( + .NUM_MODES(4), + .PISO_BUFFER_W(104), + .PISO_ACT_INPUT_RATE(64), + .PISO_ACT_OUTPUT_RATE(48), + `ifdef VERILATOR + .INPUT_RATES('{64, 64, 64, 64, 0}), + .OUTPUT_RATES('{4, 20, 44, 48, 0}) + `else + .INPUT_RATES('{64, 64, 64, 64}), + .OUTPUT_RATES('{4, 20, 44, 48}) + `endif + ) abr_piso_inst ( + .clk(clk), + .rst_b(reset_n), + .zeroize(zeroize), + .mode(mode), + .valid_i(api_rd_en_f), + .hold_o(piso_hold_o), + .data_i(api_rd_data), + .valid_o(piso_data_valid), + .hold_i('0), + .data_o(piso_data_o) + ); + + //Cast the API bitstream into 12 bit vectors per coefficient + always_comb begin + for (int i = 0; i < COEFF_PER_CLK; i++) begin + unique case (mode) + DECOMPRESS1: begin + decompress_data_i[i] = 12'(piso_data_o[i*1 +: 1]); + end + DECOMPRESS5: begin + decompress_data_i[i] = 12'(piso_data_o[i*5 +: 5]); + end + DECOMPRESS11: begin + decompress_data_i[i] = 12'(piso_data_o[i*11 +: 11]); + end + DECOMPRESS12: begin + decompress_data_i[i] = 12'(piso_data_o[i*12 +: 12]); + end + default: begin + decompress_data_i[i] = 12'(piso_data_o[i*12 +: 12]); // Default case + end + endcase + end + end + + generate + for (genvar i = 0; i < COEFF_PER_CLK; i++) begin : gen_decompress_data_o + decompress decompress_inst ( + .op_i(decompress_data_i[i]), + .mode(mode), + .op_o(decompress_data_o[i]) + ); + + assign mem_wr_data[i][MLKEM_Q_WIDTH-1:0] = decompress_data_o[i]; + assign mem_wr_data[i][MLDSA_Q_WIDTH-1:MLKEM_Q_WIDTH] = '0; //Zero padding for memory width + + end + endgenerate + + always_comb api_rd_en = decompress_busy & ~read_done & ~piso_hold_o; + + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) begin + api_rd_en_f <= '0; + end + else if (zeroize) begin + api_rd_en_f <= '0; + end + else begin + api_rd_en_f <= api_rd_en | (api_rd_en_f & piso_hold_o); + end + end + + //Compute API read address + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) begin + api_rd_addr <= '0; + end + else if (zeroize) begin + api_rd_addr <= '0; + end + else if (decompress_enable) begin + api_rd_addr <= src_base_addr; + end + else if (api_rd_en) begin + api_rd_addr <= api_rd_addr + 'd1; + end + end + + always_comb begin + unique case (mode) + DECOMPRESS1: d = 1; + DECOMPRESS5: d = 5; + DECOMPRESS11: d = 11; + DECOMPRESS12: d = 12; + default: d = 12; // Default case + endcase + end + + always_comb read_done = api_rd_addr == (src_base_addr + (num_poly * d * MLKEM_N)/64); + + //Compute Memory Write Requests + decompress_ctrl decomp_ctrl_inst ( + .clk(clk), + .reset_n(reset_n), + .zeroize(zeroize), + .decompress_enable(decompress_enable), + .num_poly(num_poly), + .dest_base_addr(dest_base_addr), + .mem_wr_valid(piso_data_valid), + .mem_wr_addr(mem_wr_addr), + .done(write_done) + ); + + always_comb mem_wr_req.addr = mem_wr_addr; + always_comb mem_wr_req.rd_wr_en = piso_data_valid ? RW_WRITE : RW_IDLE; + +endmodule diff --git a/designs/Caliptra/src/adams-bridge/exp_mask.sv b/designs/Caliptra/src/adams-bridge/exp_mask.sv new file mode 100644 index 0000000..933ea8d --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/exp_mask.sv @@ -0,0 +1,43 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. + +//Expand Mask function takes in a sample from the Keccak core +//and returns a coefficient calculated by the function 2^19-a%q + +module exp_mask + import abr_params_pkg::*; + #( + parameter EXP_SAMPLE_W = 20 + ,parameter EXP_VLD_SAMPLE_W = 23 + ) + ( + //input data + input logic [EXP_SAMPLE_W-1:0] data_i, + + //output data + output logic [EXP_VLD_SAMPLE_W-1:0] data_o + + ); + + logic [22:0] r0, r1; + logic c0, c1; + + //compute 2^19 - a + always_comb {c0,r0} = (24'd1 << 19) - data_i; + //compute potential % q value + always_comb {c1,r1} = r0 + MLDSA_Q; + //determine if we can take 2^19-a or need to take + q value + always_comb data_o = (c0 & c1) ? {1'b0,r1} : {1'b0,r0}; + +endmodule diff --git a/designs/Caliptra/src/adams-bridge/exp_mask_ctrl.sv b/designs/Caliptra/src/adams-bridge/exp_mask_ctrl.sv new file mode 100644 index 0000000..7f37c51 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/exp_mask_ctrl.sv @@ -0,0 +1,56 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. + + +module exp_mask_ctrl + import abr_params_pkg::*; + #( + parameter EXP_NUM_SAMPLERS = 4 + ,parameter EXP_SAMPLE_W = 20 + ,parameter EXP_VLD_SAMPLES = 4 + ,parameter EXP_VLD_SAMPLE_W = 23 + ) + ( + input logic clk, + input logic rst_b, + input logic zeroize, + //input data + input logic data_valid_i, + output logic data_hold_o, + input logic [EXP_NUM_SAMPLERS-1:0][EXP_SAMPLE_W-1:0] data_i, + + //output data + output logic data_valid_o, + output logic [EXP_VLD_SAMPLES-1:0][EXP_VLD_SAMPLE_W-1:0] data_o + + ); + + //No hold here, remove this + always_comb data_hold_o = '0; + + generate + for (genvar inst_g = 0; inst_g < EXP_NUM_SAMPLERS; inst_g++) begin : exp_mask_inst + exp_mask #( + .EXP_SAMPLE_W(EXP_SAMPLE_W), + .EXP_VLD_SAMPLE_W(EXP_VLD_SAMPLE_W) + ) exp_mask_i ( + .data_i(data_i[inst_g]), + .data_o(data_o[inst_g]) + ); + end + endgenerate + +always_comb data_valid_o = data_valid_i & ~zeroize; + +endmodule diff --git a/designs/Caliptra/src/adams-bridge/hintgen.sv b/designs/Caliptra/src/adams-bridge/hintgen.sv new file mode 100644 index 0000000..48e4ba8 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/hintgen.sv @@ -0,0 +1,73 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +//====================================================================== +// +// hintgen.sv +// -------- +// Processes (r, z) inputs and produces a 4-bit hint vector per coefficient +// of a given polynomial. +//====================================================================== + +module hintgen + import abr_params_pkg::*; + #( + parameter REG_SIZE = 23, + parameter MLDSA_Q = 23'd8380417, + // parameter GAMMA2 = (MLDSA_Q-1)/32, + parameter Q_MINUS_GAMMA2 = MLDSA_Q - MLDSA_GAMMA2 + ) + ( + input wire clk, + input wire reset_n, + input wire zeroize, + + input wire enable, + input wire [REG_SIZE-1:0] r, + input wire z_neq_z, + output logic h + + ); + + logic r_lt_gamma2; + logic r_gt_q_minus_gamma2; + logic r_eq_q_minus_gamma2; + logic or1_res, or2_res, and_res, not_res; + + //TODO: need flop here? commenting out for now + // always_ff @(posedge clk or negedge reset_n) begin + // if (!reset_n) + // h <= 'b0; + // else if (zeroize) + // h <= 'b0; + // else if (enable) + // h <= or2_res; + // else + // h <= 'b0; + // end + + assign h = (enable & ~zeroize) ? or2_res : 'b0; + + always_comb begin + r_lt_gamma2 = (r <= MLDSA_GAMMA2) ? 1'b1 : 1'b0; + r_gt_q_minus_gamma2 = (r >= Q_MINUS_GAMMA2) ? 1'b1 : 1'b0; + r_eq_q_minus_gamma2 = (r == Q_MINUS_GAMMA2) ? 1'b1 : 1'b0; + end + + always_comb begin + or1_res = r_lt_gamma2 | r_gt_q_minus_gamma2; + and_res = r_eq_q_minus_gamma2 & z_neq_z; + not_res = ~or1_res; + or2_res = not_res | and_res; + end +endmodule \ No newline at end of file diff --git a/designs/Caliptra/src/adams-bridge/makehint.sv b/designs/Caliptra/src/adams-bridge/makehint.sv new file mode 100644 index 0000000..aae494d --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/makehint.sv @@ -0,0 +1,400 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +//====================================================================== +// +// makehint.sv +// -------- +// Processes (r, z) inputs and produces a 4-bit hint vector per coefficient +// of a given polynomial. The hint is then checked and the index corresponding +// to 1 in the hint vector is captured in the sample buffer. 1 dword at a time +// is written to reg API +// 1. For the last poly, buffer data_o is written irrespective of number of index +// 2. If only a few indices were captured, we still need to fill rest of bytes of +// 'h' component of signature with 0s. (Length of h is 84 bytes). +// So, we need a check to see how many dwords were written and fill in rest with 0s +// 3. At the end of all polys, another write is required to 83rd byte with max index +// vector +// 4. Generate an invalid flag if any of the max indices is > 75 and keep it set until +// a zeroize or restart is given (TODO: check how restart is given - in the form of a zeroize? Or do we keep track here) +// TODO: we need a separate restart bit that is HW driven while zeroize is SW driven +// Restart bit is asserted for every signing iteration to reset sensitive flops +//====================================================================== + +module makehint + import abr_params_pkg::*; + import makehint_defines_pkg::*; + #( + parameter REG_SIZE = 24, + parameter MLDSA_Q = 23'd8380417, + parameter MLDSA_N = 256, + parameter MLDSA_K = 8, + parameter OMEGA = 75, + parameter BUFFER_DATA_W = 8 + ) + ( + input wire clk, + input wire reset_n, + input wire zeroize, + + input wire makehint_enable, + input wire [(4*REG_SIZE)-1:0] r, + input wire [3:0] z, + input wire [ABR_MEM_ADDR_WIDTH-1:0] mem_base_addr, + output logic invalid_h, + output mem_if_t mem_rd_req, + output mem_if_t z_rd_req, + output logic makehint_done, + output logic reg_wren, + output logic [3:0][7:0] reg_wrdata, + output logic [ABR_MEM_ADDR_WIDTH-1:0] reg_wr_addr + ); + + //Internal wires + logic hintgen_enable, hintgen_enable_reg; + logic [3:0] hint; + logic [MLDSA_K-1:0][7:0] max_index_buffer; + logic [31:0] max_index_buffer_data; + logic max_index_buffer_rd_lo, max_index_buffer_rd_mid, max_index_buffer_rd_hi; + logic max_index_buffer_rd; + + //Sample buffer wires + //Flush buffer will perform last write of last polynomial irrespective of data_valid from sample buffer. + //This will take care of the case where at the end of index count, if buffer has < NUM_WR values, we still want to capture into reg API, padded with 0s + //For each poly_done, sample_buffer continues to capture values as they come in and this extra write is not required until the end + logic flush_buffer, flush_buffer_reg; + logic sample_valid; + logic [3:0][BUFFER_DATA_W-1:0] sample_data; + + //Index counter + logic [3:0][7:0] index; + logic [7:0] index_count; + logic incr_index, incr_index_d1, incr_index_d2; + + //Polynomial counter + logic [$clog2(MLDSA_K)-1:0] poly_count; + logic incr_poly; + logic poly_done; + logic poly_last, poly_last_reg; + + //Read addr counter + logic [ABR_MEM_ADDR_WIDTH-1:0] mem_rd_addr, reg_wr_addr_nxt, z_rd_addr; + logic incr_mem_rd_addr; + logic rst_rd_addr; + logic last_addr_read; + + //Read fsm + mh_read_state_e read_fsm_state_ps, read_fsm_state_ns; + logic arc_MH_IDLE_MH_RD_MEM; + logic arc_MH_RD_MEM_MH_WAIT1; + logic arc_MH_WAIT2_MH_IDLE; + // logic arc_MH_WAIT_MH_RD_MEM; //TODO don't need wait if we do all polys back to back? check this later + logic arc_MH_WAIT2_MH_FLUSH; + + //Hint sum + logic [7:0] hintsum; + logic busy_reg; + logic latch_hintsum_addr; + + //Busy flag + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) + busy_reg <= 'b0; + else if (zeroize) + busy_reg <= 'b0; + else + busy_reg <= (read_fsm_state_ps != MH_IDLE); + end + + //Delay adjustment + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) + hintgen_enable_reg <= 'b0; + else if (zeroize) + hintgen_enable_reg <= 'b0; + else + hintgen_enable_reg <= hintgen_enable; + end + + //Keep count of index. Input is 4 coeffs per cycle. Have a vector that counts + //(0, 1, 2, 3), (4, 5, 6, 7), etc + //Flop incr_index twice to account for 1 cycle of mem read latency + 1 cycle of hintgen latency + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) begin + incr_index_d1 <= 'h0; + incr_index_d2 <= 'h0; + end + else if (zeroize | makehint_done) begin + incr_index_d1 <= 'h0; + incr_index_d2 <= 'h0; + end + else begin + incr_index_d1 <= incr_index; + incr_index_d2 <= incr_index_d1; + end + end + + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) begin + index_count <= 'h0; + end + else if (zeroize | makehint_done) begin + index_count <= 'h0; + end + else if (incr_index_d1) begin + index_count <= index_count + 'h4; + end + end + + always_comb begin + index[0] = incr_index_d1 ? index_count : 'h0; + index[1] = incr_index_d1 ? index_count + 'h1 : 'h0; + index[2] = incr_index_d1 ? index_count + 'h2 : 'h0; + index[3] = incr_index_d1 ? index_count + 'h3 : 'h0; + end + + //Keep count of polynomial. 1 polynomial needs 64 memory addr accesses == 256 index count (0 to 255) + //After each poly_done, record the last index into max_index_buffer + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) + poly_count <= 'h0; + else if (zeroize | makehint_done) + poly_count <= 'h0; + else if (incr_poly) + poly_count <= poly_count + 'h1; + end + + always_comb begin + poly_done = incr_poly; //last_addr_read; + poly_last = (poly_count == 'h7); + flush_buffer = (read_fsm_state_ps == MH_FLUSH_SBUF); //poly_last & poly_done; //TODO: check to make sure all indexes have been processed before this flag goes high + end + + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) begin + poly_last_reg <= 'b0; + flush_buffer_reg <= 'b0; + end + else if (zeroize | makehint_done) begin + poly_last_reg <= 'b0; + flush_buffer_reg <= 'b0; + end + else begin + poly_last_reg <= poly_last; + flush_buffer_reg <= flush_buffer; + end + end + + //----------------------- + //Count number of 1s in each poly + //----------------------- + //Sample_data from sample buffer also gives this, but we don't know where the last index would be in the 4 bytes of data received from the buffer + //Instead count 1s manually and store sum into max_index_buffer for every poly_done + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) + hintsum <= 'h0; + else if (zeroize | makehint_done) + hintsum <= 'h0; + else + hintsum <= hintsum + hint[3] + hint[2] + hint[1] + hint[0]; + end + + + //----------------------- + //Populate max_index_buffer + //----------------------- + always_comb max_index_buffer_rd = max_index_buffer_rd_lo | max_index_buffer_rd_mid | max_index_buffer_rd_hi; + + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) + max_index_buffer <= 'h0; + else if (zeroize | makehint_done) + max_index_buffer <= 'h0; + else if (poly_done) + max_index_buffer <= {hintsum, max_index_buffer[MLDSA_K-1:1]}; + end + assign max_index_buffer_data = max_index_buffer_rd_lo ? {max_index_buffer[0], 24'h0} : + max_index_buffer_rd_mid ? max_index_buffer[4:1] : + max_index_buffer_rd_hi ? {8'h0, max_index_buffer[7:5]} : 'h0; + + //Reg API + //Write from sample buffer for each dword captured per polynomial. + //If last poly is done, flush buffer and write to reg API + //After that, write the max_index_buffer contents to reg API - using delayed poly_last as the wren in this case + assign reg_wren = sample_valid | flush_buffer | max_index_buffer_rd; + assign reg_wrdata = max_index_buffer_rd ? max_index_buffer_data : (sample_valid | flush_buffer) ? sample_data : 'h0; + + always_comb reg_wr_addr_nxt = latch_hintsum_addr ? (OMEGA/4) : reg_wr_addr + 'h1; //Latch hintsum dword addr at the end of hint processing + + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) begin + reg_wr_addr <= 'h0; + end + else if (zeroize | makehint_done) begin + reg_wr_addr <= 'h0; + end + else if (sample_valid | flush_buffer | max_index_buffer_rd) begin + reg_wr_addr <= reg_wr_addr_nxt; + end + end + + assign invalid_h = (hintsum > OMEGA); + + //---------------------------- + //Read addr counter + //---------------------------- + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) begin + mem_rd_addr <= 'h0; + z_rd_addr <= 'h0; + end + else if (zeroize) begin + mem_rd_addr <= 'h0; + z_rd_addr <= 'h0; + end + else if (rst_rd_addr) begin + mem_rd_addr <= mem_base_addr; + z_rd_addr <= 'h0; + end + else if (incr_mem_rd_addr) begin + mem_rd_addr <= (poly_last && last_addr_read) ? mem_base_addr : mem_rd_addr + 'h1; + z_rd_addr <= (poly_last && last_addr_read) ? 'h0 : z_rd_addr + 'h1; + end + end + + assign last_addr_read = (mem_rd_addr == mem_base_addr + ABR_MEM_ADDR_WIDTH'(((poly_count+1) * (MLDSA_N/4))-1)); + + //---------------------------- + //Read fsm + //---------------------------- + //State machine to control memory rd addr/en and buffer read + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) + read_fsm_state_ps <= MH_IDLE; + else if (zeroize) + read_fsm_state_ps <= MH_IDLE; + else + read_fsm_state_ps <= read_fsm_state_ns; + end + + //Arc assignment + always_comb begin + //Start makehint upon seeing enable trigger + arc_MH_IDLE_MH_RD_MEM = (read_fsm_state_ps == MH_IDLE) && makehint_enable; + //When any poly is done (last or not), wait for 1 cyc to give time for sample buffer to process last coeffs + arc_MH_RD_MEM_MH_WAIT1 = (read_fsm_state_ps == MH_RD_MEM) && last_addr_read; + //When non-last poly is done, move to IDLE and wait for next enable. Opt - if we know all 8 poly will be back to back, we can remain in RD_MEM and wrap addr around + take new base addr if needed, calc hints and continue execution without waiting in IDLE for HLC to give enable + arc_MH_WAIT2_MH_IDLE = (read_fsm_state_ps == MH_WAIT2) && !poly_last; + //When non-last poly is done, go back to RD_MEM and continue executing + arc_MH_WAIT2_MH_FLUSH = (read_fsm_state_ps == MH_WAIT2) && (poly_count == MLDSA_K-1); + end + + always_comb begin + read_fsm_state_ns = read_fsm_state_ps; + incr_mem_rd_addr = 'b0; + incr_index = 'b0; + rst_rd_addr = 'b0; + hintgen_enable = 'b0; + max_index_buffer_rd_lo = 'b0; + max_index_buffer_rd_mid = 'b0; + max_index_buffer_rd_hi = 'b0; + incr_poly = 'b0; + latch_hintsum_addr = 'b0; + unique case(read_fsm_state_ps) + MH_IDLE: begin + read_fsm_state_ns = arc_MH_IDLE_MH_RD_MEM ? MH_RD_MEM : MH_IDLE; + rst_rd_addr = 'b1; + end + MH_RD_MEM: begin + //Read memory and produce hints for (r,z) + read_fsm_state_ns = arc_MH_RD_MEM_MH_WAIT1 ? MH_WAIT1 : MH_RD_MEM; + incr_mem_rd_addr = 'b1; + incr_index = 'b1; + hintgen_enable = 'b1; + end + MH_WAIT1: begin + read_fsm_state_ns = MH_WAIT2; + end + MH_WAIT2: begin + //After all 64 addr are done, wait for 1 clk to let sample buffer finish last coeff + read_fsm_state_ns = arc_MH_WAIT2_MH_FLUSH ? MH_FLUSH_SBUF : MH_RD_MEM; //arc_MH_WAIT2_MH_RD_MEM ? MH_RD_MEM : MH_FLUSH_SBUF_LOW; + incr_poly = 'b1; + end + MH_FLUSH_SBUF: begin + //If last poly, flush sample buffer + read_fsm_state_ns = MH_RD_IBUF_LOW; + latch_hintsum_addr = 'b1; //prepare for next state + end + MH_RD_IBUF_LOW: begin + //last poly, write lower dword of max idx buf to reg API + read_fsm_state_ns = MH_RD_IBUF_MID; + max_index_buffer_rd_lo = 'b1; + end + MH_RD_IBUF_MID: begin + read_fsm_state_ns = MH_RD_IBUF_HIGH; + max_index_buffer_rd_mid = 'b1; + end + MH_RD_IBUF_HIGH: begin + //last poly, write higher dword of max idx buf to reg API + read_fsm_state_ns = MH_IDLE; + max_index_buffer_rd_hi = 'b1; + end + default: begin + read_fsm_state_ns = MH_IDLE; + end + endcase + end + + //Assign output + assign mem_rd_req.rd_wr_en = (read_fsm_state_ps == MH_RD_MEM) ? RW_READ : RW_IDLE; + assign mem_rd_req.addr = mem_rd_addr; + assign z_rd_req.rd_wr_en = (read_fsm_state_ps == MH_RD_MEM) ? RW_READ : RW_IDLE; + assign z_rd_req.addr = z_rd_addr; + assign makehint_done = (read_fsm_state_ps == MH_IDLE); + + generate + for (genvar i = 0; i < 4; i++) begin : gen_hint + hintgen #( + .REG_SIZE(REG_SIZE-1) + ) + hint_inst ( + .clk(clk), + .reset_n(reset_n), + .zeroize(zeroize), + .enable(hintgen_enable_reg), + .r(r[(REG_SIZE*i)+(REG_SIZE-2):(REG_SIZE*i)]), //remove MSB 0 since coeff coming from memory is 24 bit + .z_neq_z(z[i]), + .h(hint[i]) + ); + end + endgenerate + + abr_sample_buffer #( + .NUM_WR(4), + .NUM_RD(4), + .BUFFER_DATA_W(BUFFER_DATA_W) + ) + hint_index_buffer_inst ( + .clk(clk), + .rst_b(reset_n), + .zeroize(zeroize | flush_buffer), + .data_valid_i(hint), + .data_i(index), + .buffer_full_o(), + .data_valid_o(sample_valid), + .data_o(sample_data) + ); + + + +endmodule diff --git a/designs/Caliptra/src/adams-bridge/makehint_defines_pkg.sv b/designs/Caliptra/src/adams-bridge/makehint_defines_pkg.sv new file mode 100644 index 0000000..e401ae9 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/makehint_defines_pkg.sv @@ -0,0 +1,30 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +//====================================================================== +// +// makehint_defines_pkg.sv +// -------- +// Makehint parameters for Mldsa +//====================================================================== + +`ifndef MLDSA_MAKEHINT_DEFINES +`define MLDSA_MAKEHINT_DEFINES + +package makehint_defines_pkg; + + typedef enum logic [2:0] {MH_IDLE, MH_RD_MEM, MH_WAIT1, MH_WAIT2, MH_FLUSH_SBUF, MH_RD_IBUF_LOW, MH_RD_IBUF_HIGH, MH_RD_IBUF_MID} mh_read_state_e; + +endpackage + +`endif \ No newline at end of file diff --git a/designs/Caliptra/src/adams-bridge/masked_barrett_if_cond.sv b/designs/Caliptra/src/adams-bridge/masked_barrett_if_cond.sv new file mode 100644 index 0000000..5c8a140 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/masked_barrett_if_cond.sv @@ -0,0 +1,122 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +// +//====================================================================== +// masked_barrett_if_cond.sv +// ----------- +// Performs masked Barrett reduction on a given input x. +// Latency: 20 cycles //TODO + +module masked_barrett_if_cond + import abr_params_pkg::*; + import ntt_defines_pkg::*; + #( + parameter MASKED_REG_SIZE = 2 * MLKEM_Q_WIDTH + ) + ( + input wire clk, + input wire rst_n, + input wire zeroize, + input wire [1:0][13:0] c_rolled, + input wire [11:0] rnd_12bit, + input wire [13:0] rnd_14bit, + input wire [13:0] rnd_for_Boolean0, + input wire [13:0] rnd_for_Boolean1, + input wire rnd_1bit, + output logic [1:0][MLKEM_Q_WIDTH-1:0] arith_Q + ); + + logic [1:0] c_rolled_unpacked [13:0]; + logic [1:0] c_boolean [13:0]; + logic [1:0] c_carry; + logic [1:0][MLKEM_Q_WIDTH-1:0] q_share ; + logic [1:0][MLKEM_Q_WIDTH-1:0] boolean_y; + logic [1:0] boolean_y_unpacked [MLKEM_Q_WIDTH-1:0]; + logic [1:0] arith_Q_unpacked [MLKEM_Q_WIDTH-1:0]; + + always_comb begin + for (int i = 0; i < 14; i++) begin + c_rolled_unpacked[i][1] = c_rolled[1][i]; + c_rolled_unpacked[i][0] = c_rolled[0][i]; + end + end + + //Convert input to boolean domain - 14+2 = 16 cycles + abr_masked_A2B_conv #( + .WIDTH(14) + ) barrett_a2b_inst ( + .clk(clk), + .rst_n(rst_n), + .zeroize(zeroize), + .x(c_rolled_unpacked), + .rnd(rnd_14bit), + .rnd_for_Boolean0(rnd_for_Boolean0), + .rnd_for_Boolean1(rnd_for_Boolean1), + .s(c_boolean) + ); + + //Compute carry - 1 cycle + abr_masked_OR barrett_or_inst ( + .clk(clk), + .rst_n(rst_n), + .zeroize(zeroize), + .rnd(rnd_1bit), + .x(c_boolean[13]), + .y(c_boolean[12]), + .z(c_carry) + ); + + //Split q into shares + always_comb begin + q_share[0] = MLKEM_Q ^ rnd_12bit; + q_share[1] = rnd_12bit; + end + + //And q with carry - 1 cycle + // Instantiate masked AND gates (DOM) for each bit + genvar i_AND; + generate + for (i_AND = 0; i_AND < MLKEM_Q_WIDTH; i_AND++) begin : gen_DOM_AND + abr_masked_AND and_gate_inst ( + .clk(clk), + .rst_n(rst_n), + .zeroize(zeroize), + .x(c_carry), + .y({q_share[1][i_AND], q_share[0][i_AND]}), + .rnd(rnd_12bit[i_AND]), + .c(boolean_y_unpacked[i_AND]) + ); + end + endgenerate + + //Convert boolean_y to arithmetic domain - 2 cycles + abr_masked_B2A_conv #( + .WIDTH(MLKEM_Q_WIDTH) + ) barrett_b2a_inst ( + .clk(clk), + .rst_n(rst_n), + .zeroize(zeroize), + .x_boolean(boolean_y_unpacked), + .rnd(rnd_12bit), + .x_arith(arith_Q_unpacked) + ); + + //Convert arithQ to packed + always_comb begin + for (int i = 0; i < MLKEM_Q_WIDTH; i++) begin + arith_Q[0][i] = arith_Q_unpacked[i][0]; + arith_Q[1][i] = arith_Q_unpacked[i][1]; + end + end +endmodule \ No newline at end of file diff --git a/designs/Caliptra/src/adams-bridge/masked_barrett_if_cond_v2.sv b/designs/Caliptra/src/adams-bridge/masked_barrett_if_cond_v2.sv new file mode 100644 index 0000000..72548e0 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/masked_barrett_if_cond_v2.sv @@ -0,0 +1,112 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +// +//====================================================================== +// masked_barrett_if_cond_v2.sv +// ----------- +// Checks if input is greater than 2^12. +// Latency: 3 cycles + +module masked_barrett_if_cond_v2 + import abr_params_pkg::*; + import ntt_defines_pkg::*; + #( + parameter MASKED_REG_SIZE = 2 * MLKEM_Q_WIDTH + ) + ( + input wire clk, + input wire rst_n, + input wire zeroize, + input wire [1:0][13:0] c_rolled, + input wire [11:0] rnd_12bit, + input wire [13:0] rnd_14bit, + input wire [13:0] rnd_for_Boolean0, + input wire [13:0] rnd_for_Boolean1, + input wire rnd_1bit, + output logic [1:0][MLKEM_Q_WIDTH-1:0] arith_Q + ); + + logic [1:0] c_rolled_unpacked [13:0]; + logic [1:0] c_boolean [13:0]; + logic [1:0] c_carry; + logic [1:0][MLKEM_Q_WIDTH-1:0] q_share ; + logic [1:0][MLKEM_Q_WIDTH-1:0] boolean_y; + logic [1:0] boolean_y_unpacked [MLKEM_Q_WIDTH-1:0]; + logic [1:0] arith_Q_unpacked [MLKEM_Q_WIDTH-1:0]; + + logic [14:0] c_rolled_comb; + logic carry0, carry1; + logic c_carry_comb; + + always_comb begin + for (int i = 0; i < 14; i++) begin + c_rolled_unpacked[i][1] = c_rolled[1][i]; + c_rolled_unpacked[i][0] = c_rolled[0][i]; + end + end + + always_comb begin + c_rolled_comb = c_rolled[0] + c_rolled[1]; + carry0 = c_rolled_comb[12]; + carry1 = c_rolled_comb[13]; + c_carry_comb = carry0 | carry1; + + //Refresh randomness + c_carry[0] = c_carry_comb ^ rnd_1bit; + c_carry[1] = rnd_1bit; + end + + //Split q into shares + always_comb begin + q_share[0] = MLKEM_Q ^ rnd_12bit; + q_share[1] = rnd_12bit; + end + + //And q with carry - 1 cycle + // Instantiate masked AND gates (DOM) for each bit + genvar i_AND; + generate + for (i_AND = 0; i_AND < MLKEM_Q_WIDTH; i_AND++) begin : gen_DOM_AND + abr_masked_AND and_gate_inst ( + .clk(clk), + .rst_n(rst_n), + .zeroize(zeroize), + .x(c_carry), + .y({q_share[1][i_AND], q_share[0][i_AND]}), + .rnd(rnd_14bit[i_AND]), + .c(boolean_y_unpacked[i_AND]) + ); + end + endgenerate + + //Convert boolean_y to arithmetic domain - 2 cycles + abr_masked_B2A_conv #( + .WIDTH(MLKEM_Q_WIDTH) + ) barrett_b2a_inst ( + .clk(clk), + .rst_n(rst_n), + .zeroize(zeroize), + .x_boolean(boolean_y_unpacked), + .rnd(rnd_14bit[MLKEM_Q_WIDTH-1:0]), + .x_arith(arith_Q_unpacked) + ); + + //Convert arithQ to packed + always_comb begin + for (int i = 0; i < MLKEM_Q_WIDTH; i++) begin + arith_Q[0][i] = arith_Q_unpacked[i][0]; + arith_Q[1][i] = arith_Q_unpacked[i][1]; + end + end +endmodule \ No newline at end of file diff --git a/designs/Caliptra/src/adams-bridge/masked_barrett_reduction.sv b/designs/Caliptra/src/adams-bridge/masked_barrett_reduction.sv new file mode 100644 index 0000000..01b2b27 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/masked_barrett_reduction.sv @@ -0,0 +1,178 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +// +//====================================================================== +// masked_barrett_reduction.sv +// ----------- +// Performs masked Barrett reduction on a given input x. +// Latency: 6 cycles + +module masked_barrett_reduction + import abr_params_pkg::*; + import ntt_defines_pkg::*; + #( + parameter MASKED_REG_SIZE = 2 * MLKEM_Q_WIDTH + ) + ( + input wire clk, + input wire rst_n, + input wire zeroize, + input wire [1:0][MASKED_REG_SIZE-1:0] x, + input wire [11:0] rnd_12bit, + input wire [13:0] rnd_14bit, + input wire [MASKED_REG_SIZE-1:0] rnd_24bit, + input wire [13:0] rnd_for_Boolean0, + input wire [13:0] rnd_for_Boolean1, + input wire rnd_1bit, + output logic [1:0][MASKED_REG_SIZE-1:0] y + ); + localparam ROLLER = (2**9)+(2**8)-1; + + logic [1:0][MASKED_REG_SIZE+13-1:0] tmp ; + logic [1:0][12:0] t_int, c_int, c, t; + + logic [13:0] t0_plus_carry, t0_plus_t1, c0_plus_c1; + logic [1:0][13:0] c_rolled; + logic carry_x, carry_tmp, carry_t, carry_c, carry_y_int; + logic [1:0][MASKED_REG_SIZE:0] qt; + logic [1:0][MASKED_REG_SIZE-1:0] x_reg; + logic [1:0][11:0] arith_Q; + logic [2:0][1:0][12:0] c_reg ; + logic [13:0] carry_t_int; + + logic [1:0][MASKED_REG_SIZE+13-1:0] correction; + logic [MASKED_REG_SIZE:0] carry_x_ext; + + logic [1:0][MLKEM_Q_WIDTH-1:0] y_int; + logic [MLKEM_Q_WIDTH:0] carry_y_int_ext; + + logic [MLKEM_Q_WIDTH:0] y_int_comb; + logic [MASKED_REG_SIZE:0] x_comb; + + always_comb begin + //Calculate carry_x + x_comb = x[0] + x[1]; + carry_x = x_comb[MASKED_REG_SIZE]; //(x[0] + x[1]) >> MASKED_REG_SIZE; + carry_x_ext = {carry_x, {(MASKED_REG_SIZE){1'b0}}}; + + //Calculate correction + correction[0] = 37'((carry_x_ext << 5) + (carry_x_ext << 3) + (carry_x_ext << 2) + (carry_x_ext << 1) + carry_x_ext); + correction[1] = 37'((carry_x_ext << 12) + (carry_x_ext << 9) + (carry_x_ext << 8) + (carry_x_ext << 7)); + + // x*mu + tmp[0] = (x[0] << 12) + (x[0] << 9) + (x[0] << 8) + (x[0] << 7) + (x[0] << 5) + (x[0] << 3) + (x[0] << 2) + (x[0] << 1) + x[0]; + tmp[1] = (x[1] << 12) + (x[1] << 9) + (x[1] << 8) + (x[1] << 7) + (x[1] << 5) + (x[1] << 3) + (x[1] << 2) + (x[1] << 1) + x[1]; + + //Apply correction to tmp + tmp[0] = (tmp[0] - correction[0]); + tmp[1] = (tmp[1] - correction[1]); + + // Calculate carry_tmp and mask tmp to 13 bits (tmp >> K) + carry_tmp = 25'(tmp[0][MASKED_REG_SIZE-1:0] + tmp[1][MASKED_REG_SIZE-1:0]) >> MASKED_REG_SIZE; + t_int[0] = (tmp[0] >> MASKED_REG_SIZE); + t_int[1] = (tmp[1] >> MASKED_REG_SIZE); + + // Add carry_tmp to t0 + t0_plus_carry = (t_int[0] + {{MLKEM_Q_WIDTH{1'b0}},carry_tmp}); + end + + //Flop t0 and t1 + always_ff @(posedge clk or negedge rst_n) begin + if (!rst_n) begin + t <= '0; + x_reg <= '0; + c <= '0; + + for (int i = 0; i < 3; i++) begin + c_reg[i] <= '0; + end + end + else if (zeroize) begin + t <= '0; + x_reg <= '0; + c <= '0; + for (int i = 0; i < 3; i++) begin + c_reg[i] <= '0; + end + end + else begin + // Update t0 and t1 with the new values + t[0] <= t0_plus_carry[12:0]; + t[1] <= t_int[1]; + x_reg <= x; + c <= c_int; + c_reg <= {c, c_reg[2:1]}; + end + end + + // Calculate q * t + always_comb begin + t0_plus_t1 = t[0] + t[1]; + carry_t = t0_plus_t1[13]; + carry_t_int = carry_t ? 'h2000 : 'h0; + qt[0] = ((t[0] << 11) + (t[0] << 10) + (t[0] << 8) + t[0] - carry_t_int - (carry_t_int << 10)); + qt[1] = 25'(((t[1] << 11) + (t[1] << 10) + (t[1] << 8) + t[1] - (carry_t_int << 8))) - (carry_t_int << 11); + + //Calculate c = x-t; - 13-bits + c_int[0] = 13'(25'(x_reg[0]) - qt[0]); + c_int[1] = 13'(25'(x_reg[1]) - qt[1]); + + //Use registered version of c0 and c1 to calculate carry_c and add roller + c0_plus_c1 = (c[0] + c[1]); + carry_c = c0_plus_c1[13]; + + c_rolled[0] = c[0] + (ROLLER-(carry_c ? 'h2000 : 'h0)); + c_rolled[1] = {1'b0, c[1]}; + end + + //Barrett if condition masked instance - 3 cycles + masked_barrett_if_cond_v2 masked_barrett_if_cond_inst ( + .clk(clk), + .rst_n(rst_n), + .zeroize(zeroize), + .c_rolled(c_rolled), + .rnd_12bit(rnd_12bit), + .rnd_14bit(rnd_14bit), + .rnd_for_Boolean0(rnd_for_Boolean0), + .rnd_for_Boolean1(rnd_for_Boolean1), + .rnd_1bit(rnd_1bit), + .arith_Q(arith_Q) + ); + + //Calculate t = y - q + + always_comb begin + y_int[0] = MLKEM_Q_WIDTH'(c_reg[0][0] - 13'(arith_Q[0])); + y_int[1] = MLKEM_Q_WIDTH'(c_reg[0][1] - 13'(arith_Q[1])); + + y_int_comb = y_int[0] + y_int[1]; + carry_y_int = y_int_comb[MLKEM_Q_WIDTH]; + carry_y_int_ext = {carry_y_int, {(MLKEM_Q_WIDTH){1'b0}}}; + end + + always_ff @(posedge clk or negedge rst_n) begin + if (!rst_n) begin + y <= '0; + end + else if (zeroize) begin + y <= '0; + end + else begin + y[0] <= MASKED_REG_SIZE'(MASKED_REG_SIZE'(y_int[0]) - rnd_24bit - MASKED_REG_SIZE'(carry_y_int_ext)); + y[1] <= MASKED_REG_SIZE'(MASKED_REG_SIZE'(y_int[1]) + rnd_24bit); + end + end + + +endmodule \ No newline at end of file diff --git a/designs/Caliptra/src/adams-bridge/norm_check.sv b/designs/Caliptra/src/adams-bridge/norm_check.sv new file mode 100644 index 0000000..39f9327 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/norm_check.sv @@ -0,0 +1,53 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +//====================================================================== +// +// norm_check.sv +// -------- +// Performs: invalid = (coeff > bound) && (coeff < q-bound) + +module norm_check + import norm_check_defines_pkg::*; + import abr_params_pkg::*; + #( + parameter MLDSA_Q = 8380417, + parameter GAMMA1 = 2**19, + // parameter MLDSA_GAMMA2 = (MLDSA_Q-1)/32, + parameter BETA = 120, + parameter GAMMA1_MINUS_BETA = GAMMA1 - BETA, + parameter GAMMA2_MINUS_BETA = MLDSA_GAMMA2 - BETA + ) + ( + input wire enable, + input chk_norm_mode_t mode, + input wire [REG_SIZE-2:0] opa_i, + output logic invalid + ); + + logic [REG_SIZE-2:0] bound; + logic [REG_SIZE-2:0] q_minus_bound; + + always_comb begin + case(mode) + z_bound: bound = GAMMA1_MINUS_BETA; + r0_bound: bound = GAMMA2_MINUS_BETA; + ct0_bound: bound = MLDSA_GAMMA2; + default: bound = 'h0; + endcase + + q_minus_bound = MLDSA_Q - bound; + end + + always_comb invalid = enable & (opa_i >= bound) & (opa_i <= q_minus_bound); +endmodule \ No newline at end of file diff --git a/designs/Caliptra/src/adams-bridge/norm_check_ctrl.sv b/designs/Caliptra/src/adams-bridge/norm_check_ctrl.sv new file mode 100644 index 0000000..e25083c --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/norm_check_ctrl.sv @@ -0,0 +1,159 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +//====================================================================== +// +// norm_check_ctrl.sv +// -------- +// Manages memory accesses for check norm module. Two reads are done +// to perform 8 coeff checks per cycle. First port reads 0, 2, 4, etc, while second +// port reads 1, 3, 5, etc +// Assumes that one enable triggers check for all polynomials of chosen vector and +// assumes all polynomials of the vector are stored in continuous addr space in memory + +module norm_check_ctrl + import abr_params_pkg::*; + import norm_check_defines_pkg::*; + #( + parameter MLDSA_N = 256, + parameter MLDSA_L = 7, + parameter MLDSA_K = 8 + ) + ( + input wire clk, + input wire reset_n, + input wire zeroize, + + input wire norm_check_enable, + input chk_norm_mode_t mode, + + input wire [5:0] randomness, + + input wire [ABR_MEM_ADDR_WIDTH-1:0] mem_base_addr, + output mem_if_t mem_rd_req, + output logic check_enable, + output logic norm_check_done + ); + + + chk_read_state_e read_fsm_state_ps, read_fsm_state_ns; + logic [ABR_MEM_ADDR_WIDTH-1:0] mem_rd_addr, locked_based_addr; + + //Flags + logic incr_rd_addr; + logic last_poly_last_addr; + logic norm_check_busy; + + logic [4:0] latched_out_randomness; + logic latched_in_randomness; + logic [4:0] increment_addr; + logic [6:0] neutral_cnt; + + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) begin + latched_out_randomness <= 'h0; + latched_in_randomness <= 'h0; + increment_addr <= 'h0; + mem_rd_addr <= 'h0; + neutral_cnt <= 'h0; + locked_based_addr <= 'h0; + end + else if (zeroize) begin + latched_out_randomness <= 'h0; + latched_in_randomness <= 'h0; + increment_addr <= 'h0; + mem_rd_addr <= 'h0; + neutral_cnt <= 'h0; + locked_based_addr <= 'h0; + end + else begin + if (norm_check_enable) begin + latched_out_randomness <= randomness[5:1]; + latched_in_randomness <= randomness[0]; + increment_addr <= randomness[5:1]; + mem_rd_addr <= {{(ABR_MEM_ADDR_WIDTH-6){1'b0}}, randomness}; + neutral_cnt <= 'h0; + locked_based_addr <= mem_base_addr; + end + else if (incr_rd_addr) begin + latched_in_randomness <= latched_in_randomness; + latched_out_randomness <= latched_out_randomness; + increment_addr <= increment_addr; + mem_rd_addr <= {mem_rd_addr[ABR_MEM_ADDR_WIDTH-1:6], increment_addr, latched_in_randomness}; + neutral_cnt <= neutral_cnt + 'h1; + end + else if (~incr_rd_addr) begin + latched_in_randomness <= randomness[0]; + latched_out_randomness <= latched_out_randomness; + increment_addr <= increment_addr + 'h1; + mem_rd_addr <= {mem_rd_addr[ABR_MEM_ADDR_WIDTH-1:1], ~latched_in_randomness}; + neutral_cnt <= neutral_cnt + 'h1; + end + end + end + + //Addr assignment + always_comb begin + mem_rd_req.addr = mem_rd_addr+locked_based_addr; + + mem_rd_req.rd_wr_en = ((read_fsm_state_ps == CHK_RD_MEM) | (read_fsm_state_ps == CHK_WAIT)) ? RW_READ : RW_IDLE; + end + + //Last addr flag + always_comb last_poly_last_addr = (neutral_cnt == ((MLDSA_N/4))-1); + + //Ctrl flags + always_comb begin + norm_check_busy = (read_fsm_state_ps != CHK_IDLE); + end + + //FSM + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) + read_fsm_state_ps <= CHK_IDLE; + else if (zeroize) + read_fsm_state_ps <= CHK_IDLE; + else + read_fsm_state_ps <= read_fsm_state_ns; + end + + always_comb begin + read_fsm_state_ns = read_fsm_state_ps; + incr_rd_addr = 'b0; + norm_check_done = 0; + + case(read_fsm_state_ps) + CHK_IDLE: begin + read_fsm_state_ns = norm_check_enable ? CHK_RD_MEM : CHK_IDLE; + end + CHK_RD_MEM: begin + read_fsm_state_ns = last_poly_last_addr ? CHK_DONE : CHK_WAIT; + incr_rd_addr = 'b0; + end + CHK_WAIT: begin + read_fsm_state_ns = last_poly_last_addr ? CHK_DONE : CHK_RD_MEM; + incr_rd_addr = 'b1; + end + CHK_DONE: begin + read_fsm_state_ns = CHK_IDLE; + norm_check_done = 'b1; + end + default begin + read_fsm_state_ns = CHK_IDLE; + end + endcase + end + + always_comb check_enable = (read_fsm_state_ps == CHK_RD_MEM) | (read_fsm_state_ps == CHK_WAIT); + +endmodule \ No newline at end of file diff --git a/designs/Caliptra/src/adams-bridge/norm_check_defines_pkg.sv b/designs/Caliptra/src/adams-bridge/norm_check_defines_pkg.sv new file mode 100644 index 0000000..a43a619 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/norm_check_defines_pkg.sv @@ -0,0 +1,34 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +//====================================================================== +// +// norm_check_defines_pkg.sv +// -------- +// Validity norm check parameters for the digital signature algorithm (DSA). +// +// +//====================================================================== + +`ifndef ABR_NORM_CHECK_DEFINES +`define ABR_NORM_CHECK_DEFINES + +package norm_check_defines_pkg; + + parameter z_bound = 2'h0, r0_bound = 2'h1, ct0_bound = 2'h2; + typedef logic [1:0] chk_norm_mode_t; + + typedef enum logic [1:0] {CHK_IDLE, CHK_RD_MEM, CHK_WAIT, CHK_DONE} chk_read_state_e; +endpackage + +`endif \ No newline at end of file diff --git a/designs/Caliptra/src/adams-bridge/norm_check_top.sv b/designs/Caliptra/src/adams-bridge/norm_check_top.sv new file mode 100644 index 0000000..babf090 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/norm_check_top.sv @@ -0,0 +1,121 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +//====================================================================== +// +// norm_check_top.sv +// -------- +// Performs the 3 validity checks (z, r0, ct0) needed for signing algorithm based on mode selection +// Generates one final invalid bit that is accumulated across all polynomials of the chosen vector +// Since this module only has to read from memory, two addresses are read per cycle to increase bandwidth +// and reduce latency, i.e. 8 coeffs are processed per cycle, and 8 check units are instantiated + +// Once the norm_check_done is asserted, the invalid flag needs to be latched at the top level +// for future use in signing algo. Assuming it takes 1 cycle to latch the value, ready is asserted 1 cycle later +// to let HLC know that norm_check operation is done for that vector and next one can be queued +// TODO: see if this needs any changes + +// TODO: embed z and r0 checks in decompose? +// TODO: need a restart input (other than zeroize) + +module norm_check_top + import abr_params_pkg::*; + import norm_check_defines_pkg::*; + #( + parameter MLDSA_N = 256 + ) + ( + input wire clk, + input wire reset_n, + input wire zeroize, + + input wire norm_check_enable, + input chk_norm_mode_t mode, + + input wire [5:0] randomness, + + input wire [ABR_MEM_ADDR_WIDTH-1:0] mem_base_addr, + output mem_if_t mem_rd_req, + input [4*REG_SIZE-1:0] mem_rd_data, + output logic invalid, + output logic norm_check_ready, + output logic norm_check_done + ); + + logic [3:0] check_a_invalid; + logic check_enable, check_enable_reg; + logic norm_check_done_int; + + generate + for (genvar i = 0; i < 4; i++) begin : gen_check_a_invalid + norm_check check_inst ( + .enable(check_enable_reg), + .mode(mode), + .opa_i(mem_rd_data[(REG_SIZE-2)+(i*REG_SIZE):i*REG_SIZE]), + .invalid(check_a_invalid[i]) + ); + end + endgenerate + + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) + norm_check_done <= 'b0; + else if (zeroize) + norm_check_done <= 'b0; + else + norm_check_done <= norm_check_done_int; + end + + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) + invalid <= 'b0; + else if (zeroize | norm_check_done) + invalid <= 'b0; + else + invalid <= invalid | (|check_a_invalid);// | (|check_b_invalid); + end + + //Delay flops + //Give one cycle for HLC to capture invalid flag + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) begin + norm_check_ready <= 'b0; + check_enable_reg <= 'b0; + end + else if (zeroize) begin + norm_check_ready <= 'b0; + check_enable_reg <= 'b0; + end + else begin + norm_check_ready <= norm_check_done; + check_enable_reg <= check_enable; + end + + end + + norm_check_ctrl + norm_check_ctrl_inst ( + .clk(clk), + .reset_n(reset_n), + .zeroize(zeroize), + .norm_check_enable(norm_check_enable), + .randomness(randomness), + .mode(mode), + .mem_base_addr(mem_base_addr), + .mem_rd_req(mem_rd_req), + .norm_check_done(norm_check_done_int), + .check_enable(check_enable) + ); + + +endmodule \ No newline at end of file diff --git a/designs/Caliptra/src/adams-bridge/ntt_buffer.sv b/designs/Caliptra/src/adams-bridge/ntt_buffer.sv new file mode 100644 index 0000000..922a1d2 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/ntt_buffer.sv @@ -0,0 +1,123 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +// +//====================================================================== +// +// ntt_buffer.sv +// -------- +// Set of 4 buffers of widths 4, 5, 6 and 7 slots. These buffers will +// temporarily hold data from NTT memory and collect 4 coefficients for each +// address being read/written to. This buffer will be configured based on bf mode at ntt_top level. +// In NTT mode (ct mode), buffer will contain data read from memory before +// it is consumed by butterfly2x2. In INTT mode (gs mode), buffer will contain +// data to be written to memory (bf2x2 outputs). When all 4 coefficients for a given +// op have arrived, the data is passed to bf2x2 module or written to NTT memory (based on bf mode) +//====================================================================== + +module ntt_buffer + import ntt_defines_pkg::*; +#( + parameter REG_SIZE = 23 + // parameter NUM_COEFF = 4 +) +( + input wire clk, + input wire reset_n, + input wire zeroize, + input wire wren, //enables writes to the buffer + input wire rden, //enables reads to the buffer + input wire wr_rst_count, + input wire rd_rst_count, + input mode_t mode, + input wire [(4*REG_SIZE)-1:0] data_i, + output logic buf0_valid, + output logic [(4*REG_SIZE)-1:0] data_o +); + + logic [3:0][REG_SIZE-1:0] buf0; //holds 4 entries + logic [4:0][REG_SIZE-1:0] buf1; //holds 5 entries + logic [5:0][REG_SIZE-1:0] buf2; //holds 6 entries + logic [6:0][REG_SIZE-1:0] buf3; //holds 7 entries + + logic [1:0] data_i_count, data_i_count_reg; + logic [1:0] data_o_count; + logic wren_reg; + + + //Write/read + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) begin + buf0 <= 'h0; + buf1 <= 'h0; + buf2 <= 'h0; + buf3 <= 'h0; + + end + else if (zeroize) begin + buf0 <= 'h0; + buf1 <= 'h0; + buf2 <= 'h0; + buf3 <= 'h0; + + end + else if (wren) begin + buf0 <= {data_i[REG_SIZE-1:0], buf0[3:1]}; + buf1 <= {data_i[(2*REG_SIZE)-1:REG_SIZE], buf1[4:1]}; + buf2 <= {data_i[(3*REG_SIZE)-1:(2*REG_SIZE)], buf2[5:1]}; + buf3 <= {data_i[(4*REG_SIZE)-1:(3*REG_SIZE)], buf3[6:1]}; + end + end + + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) + data_o_count <= 'h0; + else if (zeroize) + data_o_count <= 'h0; + else if (rd_rst_count) + data_o_count <= 'h0; + else if (rden) + data_o_count <= data_o_count + 'h1; + end + + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) begin + data_i_count <= 'h0; + data_i_count_reg <= 'h0; + end + else if (zeroize) begin + data_i_count <= 'h0; + data_i_count_reg <= 'h0; + end + else if (wr_rst_count) begin + data_i_count <= 'h0; + data_i_count_reg <= 'h0; + end + else if (wren) begin + data_i_count <= data_i_count + 'h1; + data_i_count_reg <= data_i_count; + end + end + + assign buf0_valid = (data_i_count_reg == 'd3); + + always_comb begin + case(data_o_count) + 'd0: data_o = {buf0[3],buf0[2],buf0[1],buf0[0]}; + 'd1: data_o = {buf1[3],buf1[2],buf1[1],buf1[0]}; + 'd2: data_o = {buf2[3],buf2[2],buf2[1],buf2[0]}; + 'd3: data_o = {buf3[3],buf3[2],buf3[1],buf3[0]}; + endcase + end + +endmodule \ No newline at end of file diff --git a/designs/Caliptra/src/adams-bridge/ntt_butterfly.sv b/designs/Caliptra/src/adams-bridge/ntt_butterfly.sv new file mode 100644 index 0000000..dcd109d --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/ntt_butterfly.sv @@ -0,0 +1,353 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +// +//====================================================================== +// +// ntt_butterfly.sv +// -------- +// Combined butterfly unit that performs NTT and INTT. All operations +// are modular. This unit operates in 5 modes - NTT, INTT and PWM, PWA, PWS +// Inputs u and v are fetched from s memory, w values come from ROM +// containing required twiddle factors. +// PWM mode performs point-wise multiplication and accumulation +//====================================================================== + +module ntt_butterfly + import ntt_defines_pkg::*; + import abr_params_pkg::*; +#( + parameter REG_SIZE = 23, + parameter MLDSA_Q = 23'd8380417, + parameter MLDSA_Q_DIV2_ODD = (MLDSA_Q + 1) / 2, + parameter MLKEM_Q = 12'd3329, + parameter MLKEM_Q_DIV2_ODD = (MLKEM_Q + 1) / 2 +) +( + //Clock and reset + input wire clk, + input wire reset_n, + input wire zeroize, + + //Data ports + input mode_t mode, + input wire accumulate, + input wire mlkem, + + input wire [REG_SIZE-1:0] opu_i, + input wire [REG_SIZE-1:0] opv_i, + input wire [REG_SIZE-1:0] opw_i, + + output logic [REG_SIZE-1:0] u_o, + output logic [REG_SIZE-1:0] v_o, + output logic [REG_SIZE-1:0] pwm_res_o +); + + //Input wires + logic [REG_SIZE-1:0] u_reg, u_reg_d2, u_reg_d3, u_reg_d4; + // logic [REG_SIZE-1:0] v_reg, v_reg_d2, v_reg_d3, v_reg_d4; + logic [REG_SIZE-1:0] w_reg, w_reg_d2, w_reg_d3, w_reg_d4; //w_reg_d4 only used in pwm mode + + //Multiplier wires + logic [(2*REG_SIZE)-1:0] vw, vw_reg, mul_res; + logic [(2*MLKEM_REG_SIZE)-1:0] mul_res_reg; //used in MLKEM + logic [MLKEM_REG_SIZE-1:0] mlkem_mul_res_reduced; + logic [22:0] mldsa_mul_res_reduced; + logic [MLKEM_REG_SIZE-1:0] mlkem_mul_res_reduced_reg; //used in MLKEM + logic [REG_SIZE-1:0] mul_opa, mul_opb; + + //Subtractor wires + logic [REG_SIZE-1:0] u_minus_v, mldsa_u_minus_v_div2; + logic [MLKEM_REG_SIZE-1:0] mlkem_u_minus_v_div2; + + //Adder wires + logic [REG_SIZE-1:0] add_opa, add_opb; + logic [REG_SIZE-1:0] add_res, add_res_d1, add_res_d2, add_res_d3, add_res_d4, sub_res; + logic [REG_SIZE-1:0] mldsa_add_res_div2, sub_res_div2, mul_res_reduced_div2; + logic [MLKEM_REG_SIZE-1:0] mlkem_add_res_div2; + + //Flop u input to match multiplier output (4 cycle delay) + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) begin + u_reg <= 'h0; + u_reg_d2 <= 'h0; + u_reg_d3 <= 'h0; + u_reg_d4 <= 'h0; + + w_reg <= 'h0; + w_reg_d2 <= 'h0; + w_reg_d3 <= 'h0; + w_reg_d4 <= 'h0; + + mul_res_reg <= '0; + mlkem_mul_res_reduced_reg <= '0; + end + else if (zeroize) begin + u_reg <= 'h0; + u_reg_d2 <= 'h0; + u_reg_d3 <= 'h0; + u_reg_d4 <= 'h0; + + w_reg <= 'h0; + w_reg_d2 <= 'h0; + w_reg_d3 <= 'h0; + w_reg_d4 <= 'h0; + + mul_res_reg <= '0; + mlkem_mul_res_reduced_reg <= '0; + end + else begin + u_reg <= opu_i; + u_reg_d2 <= u_reg; + u_reg_d3 <= u_reg_d2; + u_reg_d4 <= u_reg_d3; + + //Used in GS/PWM mode only + w_reg <= opw_i; + w_reg_d2 <= w_reg; + w_reg_d3 <= w_reg_d2; + w_reg_d4 <= w_reg_d3; + + //Used in MLKEM + mul_res_reg <= (2*MLKEM_REG_SIZE)'(mul_res); + mlkem_mul_res_reduced_reg <= mlkem_mul_res_reduced; + end + end + + //4 cycle delay to match critical path + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) begin + add_res_d1 <= 'h0; + add_res_d2 <= 'h0; + add_res_d3 <= 'h0; + add_res_d4 <= 'h0; + end + else if (zeroize) begin + add_res_d1 <= 'h0; + add_res_d2 <= 'h0; + add_res_d3 <= 'h0; + add_res_d4 <= 'h0; + end + else begin + add_res_d1 <= add_res; + add_res_d2 <= add_res_d1; + add_res_d3 <= add_res_d2; + add_res_d4 <= add_res_d3; + end + end + + //Mode mux for outputs + always_comb begin + unique case(mode) + ct: begin + u_o = add_res; + v_o = sub_res; + pwm_res_o = 'h0; + end + gs: begin + u_o = mlkem ? REG_SIZE'(mlkem_add_res_div2) : mldsa_add_res_div2; + v_o = mlkem ? REG_SIZE'(mlkem_mul_res_reduced_reg) : mldsa_mul_res_reduced[REG_SIZE-1:0]; //_div2; + pwm_res_o = 'h0; + end + pwm:begin + u_o = 'h0; //accumulate ? add_res : mlkem ? REG_SIZE'(mlkem_mul_res_reduced_reg) : mldsa_mul_res_reduced[REG_SIZE-1:0]; //TODO: see if pwm_res_o is good enough or reuse u_o to save routing/area + v_o = 'h0; + pwm_res_o = mlkem ? 'h0 : accumulate ? add_res : mldsa_mul_res_reduced[REG_SIZE-1:0]; + end + pwa:begin + u_o = 'h0; //add_res; + v_o = 'h0; + pwm_res_o = add_res; + end + pws:begin + u_o = 'h0; //u_minus_v; + v_o = 'h0; + pwm_res_o = u_minus_v; + end + pairwm: begin //Karatsuba pairwm is used instead of this butterfly + u_o = 'h0; + v_o = 'h0; + pwm_res_o = 'h0; + end + default: begin + u_o = 'h0; + v_o = 'h0; + pwm_res_o = 'h0; + end + endcase + end + + //Mode mux for inputs + //0 - NTT, 1 - INTT, 2 - PWM + always_comb begin + unique case(mode) + ct: begin + add_opa = mlkem ? u_reg_d2 : u_reg_d4; + add_opb = mlkem ? REG_SIZE'(mlkem_mul_res_reduced_reg) : mldsa_mul_res_reduced[REG_SIZE-1:0]; + mul_opa = opv_i; + mul_opb = opw_i; + end + gs: begin + add_opa = opu_i; + add_opb = opv_i; + mul_opa = mlkem ? REG_SIZE'(mlkem_u_minus_v_div2) : mldsa_u_minus_v_div2; //u_minus_v + mul_opb = w_reg; + end + pwm:begin + add_opa = mlkem ? 'h0 : w_reg_d4; + add_opb = mlkem ? 'h0 : mldsa_mul_res_reduced[REG_SIZE-1:0]; + mul_opa = opu_i; + mul_opb = opv_i; + end + pwa:begin + add_opa = opu_i; + add_opb = opv_i; + mul_opa = 'h0; + mul_opb = 'h0; + end + default: begin + add_opa = 'h0; + add_opb = 'h0; + mul_opa = 'h0; + mul_opb = 'h0; + end + endcase + end + + //Mod sub - used in GS + abr_ntt_add_sub_mod #( + .REG_SIZE(REG_SIZE) + ) + sub_inst_0( + .clk(clk), + .reset_n(reset_n), + .zeroize(zeroize), + .add_en_i(1'b1), + .sub_i(1'b1), + .opa_i(opu_i), + .opb_i(opv_i), + .prime_i(mlkem ? REG_SIZE'(MLKEM_Q) : REG_SIZE'(MLDSA_Q)), + .mlkem(mlkem), + .res_o(u_minus_v), + .ready_o() + ); + + //Mod sub - used in CT + abr_ntt_add_sub_mod #( + .REG_SIZE(REG_SIZE) + ) + sub_inst_1( + .clk(clk), + .reset_n(reset_n), + .zeroize(zeroize), + .add_en_i(1'b1), + .sub_i(1'b1), + .opa_i(mlkem ? u_reg_d2 : u_reg_d4), + .opb_i(mlkem ? REG_SIZE'(mlkem_mul_res_reduced_reg) : mldsa_mul_res_reduced[REG_SIZE-1:0]), + .prime_i(mlkem ? REG_SIZE'(MLKEM_Q) : REG_SIZE'(MLDSA_Q)), + .mlkem(mlkem), + .res_o(sub_res), + .ready_o() + ); + + //Mod add - used in CT and GS, PWM + abr_ntt_add_sub_mod #( + .REG_SIZE(REG_SIZE) + ) + add_inst_0( + .clk(clk), + .reset_n(reset_n), + .zeroize(zeroize), + .add_en_i(1'b1), + .sub_i(1'b0), + .opa_i(add_opa), + .opb_i(add_opb), + .prime_i(mlkem ? REG_SIZE'(MLKEM_Q) : REG_SIZE'(MLDSA_Q)), + .mlkem(mlkem), + .res_o(add_res), + .ready_o() + ); + + //Mod mult - used in CT, GS, PWM + + ntt_mult_dsp #( + .RADIX(REG_SIZE) + ) + mul_inst_0 ( + .A_i(mul_opa), + .B_i(mul_opb), + .P_o(mul_res) + ); + + ntt_mult_reduction #( + .REG_SIZE(23), + .PRIME(MLDSA_Q) + ) + mldsa_mul_redux_inst_0 ( + .clk(clk), + .reset_n(reset_n), + .zeroize(zeroize), + .opa_i(mlkem ? '0 : 46'(mul_res)), + .res_o(mldsa_mul_res_reduced), + .ready_o() + ); + + barrett_reduction #( + .REG_SIZE(MLKEM_REG_SIZE), + .prime(MLKEM_Q) + ) + mlkem_mul_redux_inst_0 ( + .x(mlkem ? mul_res_reg : '0), + .inv(), + .r(mlkem_mul_res_reduced) + ); + + //Output div2 - used in MLDSA GS + ntt_div2 #( + .REG_SIZE(REG_SIZE), + .PRIME(MLDSA_Q) + ) + mldsa_div2_inst_0 ( + .op_i (add_res_d4), + .res_o (mldsa_add_res_div2) + ); + + ntt_div2 #( + .REG_SIZE(REG_SIZE), + .PRIME(MLDSA_Q) + ) + mldsa_div2_inst_2 ( + .op_i (u_minus_v), + .res_o (mldsa_u_minus_v_div2) + ); + + //Output div2 - used in MLKEM GS + ntt_div2 #( + .REG_SIZE(MLKEM_REG_SIZE), + .PRIME(MLKEM_Q) + ) + mlkem_div2_inst_0 ( + .op_i (add_res_d2[MLKEM_REG_SIZE-1:0]), + .res_o (mlkem_add_res_div2) + ); + + ntt_div2 #( + .REG_SIZE(MLKEM_REG_SIZE), + .PRIME(MLKEM_Q) + ) + mlkem_div2_inst_2 ( + .op_i (u_minus_v[MLKEM_REG_SIZE-1:0]), + .res_o (mlkem_u_minus_v_div2) + ); + +endmodule diff --git a/designs/Caliptra/src/adams-bridge/ntt_butterfly2x2.sv b/designs/Caliptra/src/adams-bridge/ntt_butterfly2x2.sv new file mode 100644 index 0000000..f7b4d0c --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/ntt_butterfly2x2.sv @@ -0,0 +1,319 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +// +//====================================================================== +// +// ntt_butterfly2x2.sv +// -------- +// Network of 4 butterfly units connected in a 2x2 layout. Inputs to these +// are u00, v00, u01, v01, w00, w01 (as an example), coming from a buffer. Outputs of +// the 1st stage are passed onto the second stage (u10, v10, u11, v11, w10, w11). +// The final outputs are buffered and written back to memory at the top level +//====================================================================== + +module ntt_butterfly2x2 + import ntt_defines_pkg::*; + import abr_params_pkg::*; +#( + parameter REG_SIZE = 23, + parameter MLDSA_Q = 23'd8380417, + parameter MLDSA_Q_DIV2_ODD = (MLDSA_Q + 1) / 2 +) +( + //Clock and reset + input wire clk, + input wire reset_n, + input wire zeroize, + + //Data ports + input mode_t mode, + input wire enable, + input bf_uvwi_t uvw_i, + input pwo_uvwi_t pw_uvw_i, + input wire accumulate, + input wire mlkem, + input mlkem_pairwm_zeta_t mlkem_pairwm_zeta13_i, + output bf_uvo_t uv_o, + output pwo_t pwo_uv_o, + output logic ready_o +); + + logic [REG_SIZE-1:0] u00; + logic [REG_SIZE-1:0] u01; + logic [REG_SIZE-1:0] v00; + logic [REG_SIZE-1:0] v01; + + logic [REG_SIZE-1:0] u10_int, u10; + logic [REG_SIZE-1:0] u11_int, u11; + logic [REG_SIZE-1:0] v10_int, v10; + logic [REG_SIZE-1:0] v11_int, v11; + + logic [REG_SIZE-1:0] w00; + logic [REG_SIZE-1:0] w01; + logic [REG_SIZE-1:0] w10; + logic [REG_SIZE-1:0] w11; + logic [MLKEM_REG_SIZE-1:0] mlkem_w10; + logic [MLKEM_REG_SIZE-1:0] mlkem_w11; + logic [UNMASKED_BF_STAGE1_LATENCY-1:0][REG_SIZE-1:0] mldsa_w10_reg, mldsa_w11_reg; //Shift w10 by 5 cycles to match 1st stage BF latency + logic [MLKEM_UNMASKED_BF_STAGE1_LATENCY-1:0][MLKEM_REG_SIZE-1:0] mlkem_w10_reg, mlkem_w11_reg; //Shift w10/w11 by 3 cycles to match 1st stage of MLKEM BF latency + logic pwo_mode; + logic [UNMASKED_BF_LATENCY-1:0] ready_reg; + + pwo_t mldsa_pwo_uv_o; + + //Each butterfly unit takes u, v, w inputs and produces + //u, v outputs for the next stage to consume. Each butterfly + //has a maximum latency of 5 clks + //Each worst-case path (ct or gs) contains a modular multiplication + //and a modular add/sub. Multiplication takes a max of 4 clks + //(Multiplication module has 2 flops + 2 add/sub reductions in a single path). + //Add/sub takes 1 clk to produce results. + //So, worst case latency = 4 + 1 = 5 clks + + //Flop the twiddle factor 5x to correctly pass in values to the 2nd set of bf units + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) begin + mldsa_w10_reg <= 'h0; + mldsa_w11_reg <= 'h0; + mlkem_w10_reg <= 'h0; + mlkem_w11_reg <= 'h0; + end + else if (zeroize) begin + mldsa_w10_reg <= 'h0; + mldsa_w11_reg <= 'h0; + mlkem_w10_reg <= 'h0; + mlkem_w11_reg <= 'h0; + end + else begin + mldsa_w10_reg <= {uvw_i.w10_i, mldsa_w10_reg[UNMASKED_BF_STAGE1_LATENCY-1:1]}; + mldsa_w11_reg <= {uvw_i.w11_i, mldsa_w11_reg[UNMASKED_BF_STAGE1_LATENCY-1:1]}; + + mlkem_w10_reg <= {uvw_i.w10_i[MLKEM_REG_SIZE-1:0], mlkem_w10_reg[MLKEM_UNMASKED_BF_STAGE1_LATENCY-1:1]}; + mlkem_w11_reg <= {uvw_i.w11_i[MLKEM_REG_SIZE-1:0], mlkem_w11_reg[MLKEM_UNMASKED_BF_STAGE1_LATENCY-1:1]}; + end + end + + assign pwo_mode = (mode inside {pwm, pwa, pws}); + + always_comb begin + if (pwo_mode) begin + u00 = pw_uvw_i.u0_i; + v00 = pw_uvw_i.v0_i; + w00 = pw_uvw_i.w0_i; + + u01 = pw_uvw_i.u1_i; + v01 = pw_uvw_i.v1_i; + w01 = pw_uvw_i.w1_i; + + u10 = pw_uvw_i.u2_i; + v10 = pw_uvw_i.v2_i; + w10 = pw_uvw_i.w2_i; + + u11 = pw_uvw_i.u3_i; + v11 = pw_uvw_i.v3_i; + w11 = pw_uvw_i.w3_i; + + end + else begin + u00 = uvw_i.u00_i; + v00 = uvw_i.v00_i; + w00 = uvw_i.w00_i; + + u01 = uvw_i.u01_i; + v01 = uvw_i.v01_i; + w01 = uvw_i.w01_i; + + u10 = u10_int; + v10 = v10_int; + w10 = mlkem ? mlkem_w10_reg[0] : mldsa_w10_reg[0]; + + u11 = u11_int; + v11 = v11_int; + w11 = mlkem ? mlkem_w11_reg[0] : mldsa_w11_reg[0]; + end + end + + //-------------------------- + //Butterfly instances + //-------------------------- + ntt_butterfly #( + .REG_SIZE(REG_SIZE) + ) + bf_inst00( + .clk(clk), + .reset_n(reset_n), + .zeroize(zeroize), + .mode(mode), + .mlkem(mlkem), + .opu_i(u00), + .opv_i(v00), + .opw_i(w00), + .accumulate(accumulate), + .u_o(u10_int), + .v_o(u11_int), + .pwm_res_o(mldsa_pwo_uv_o.uv0) + ); + + ntt_butterfly #( + .REG_SIZE(REG_SIZE) + ) + bf_inst01( + .clk(clk), + .reset_n(reset_n), + .zeroize(zeroize), + .mode(mode), + .mlkem(mlkem), + .opu_i(u01), + .opv_i(v01), + .opw_i(w01), + .accumulate(accumulate), + .u_o(v10_int), + .v_o(v11_int), + .pwm_res_o(mldsa_pwo_uv_o.uv1) + ); + + ntt_butterfly #( + .REG_SIZE(REG_SIZE) + ) + bf_inst10( + .clk(clk), + .reset_n(reset_n), + .zeroize(zeroize), + .mode(mode), + .mlkem(mlkem), + .opu_i(u10), + .opv_i(v10), + .opw_i(w10), + .accumulate(accumulate), + .u_o(uv_o.u20_o), + .v_o(uv_o.v20_o), + .pwm_res_o(mldsa_pwo_uv_o.uv2) + ); + + ntt_butterfly #( + .REG_SIZE(REG_SIZE), + .MLDSA_Q(MLDSA_Q) + ) + bf_inst11( + .clk(clk), + .reset_n(reset_n), + .zeroize(zeroize), + .mode(mode), + .mlkem(mlkem), + .opu_i(u11), + .opv_i(v11), + .opw_i(w11), + .accumulate(accumulate), + .u_o(uv_o.u21_o), + .v_o(uv_o.v21_o), + .pwm_res_o(mldsa_pwo_uv_o.uv3) + ); + + //MLKEM PairWM + mlkem_pwo_uvwzi_t pairwm_uvw01_i, pairwm_uvw23_i; + mlkem_pwo_t pairwm_uv01_o, pairwm_uv23_o; + + always_comb begin + if (mlkem & (mode == pairwm)) begin + pairwm_uvw01_i.u0_i = pw_uvw_i.u0_i; + pairwm_uvw01_i.v0_i = pw_uvw_i.v0_i; + pairwm_uvw01_i.w0_i = pw_uvw_i.w0_i; + + pairwm_uvw01_i.u1_i = pw_uvw_i.u1_i; + pairwm_uvw01_i.v1_i = pw_uvw_i.v1_i; + pairwm_uvw01_i.w1_i = pw_uvw_i.w1_i; + + pairwm_uvw23_i.u0_i = pw_uvw_i.u2_i; + pairwm_uvw23_i.v0_i = pw_uvw_i.v2_i; + pairwm_uvw23_i.w0_i = pw_uvw_i.w2_i; + + pairwm_uvw23_i.u1_i = pw_uvw_i.u3_i; + pairwm_uvw23_i.v1_i = pw_uvw_i.v3_i; + pairwm_uvw23_i.w1_i = pw_uvw_i.w3_i; + end + else begin + pairwm_uvw01_i = '0; + pairwm_uvw23_i = '0; + end + end + + ntt_karatsuba_pairwm mlkem_pawm_inst0 ( + .clk(clk), + .reset_n(reset_n), + .zeroize(zeroize), + .accumulate(accumulate), + .pwo_uvw_i(pairwm_uvw01_i), + .pwo_z_i(mlkem_pairwm_zeta13_i.z0_i), + .pwo_uv_o(pairwm_uv01_o) + ); + + ntt_karatsuba_pairwm mlkem_pawm_inst1 ( + .clk(clk), + .reset_n(reset_n), + .zeroize(zeroize), + .accumulate(accumulate), + .pwo_uvw_i(pairwm_uvw23_i), + .pwo_z_i(mlkem_pairwm_zeta13_i.z1_i), + .pwo_uv_o(pairwm_uv23_o) + ); + + always_comb begin + pwo_uv_o.uv0 = mlkem ? pairwm_uv01_o.uv0_o : mldsa_pwo_uv_o.uv0; + pwo_uv_o.uv1 = mlkem ? pairwm_uv01_o.uv1_o : mldsa_pwo_uv_o.uv1; + pwo_uv_o.uv2 = mlkem ? pairwm_uv23_o.uv0_o : mldsa_pwo_uv_o.uv2; + pwo_uv_o.uv3 = mlkem ? pairwm_uv23_o.uv1_o : mldsa_pwo_uv_o.uv3; + end + + //Determine when results are ready + //--------------------------------------------- + //For the first 10 cycles, ntt_butterfly2x2 does not produce any valid output. + //We wait for 10 clks before asserting ready. After that, there's a valid output every clk. + //ntt_top controller will disable bf2x2 and that will reset ready while transitioning + //from one stage to next after all writes of current stage have finished. + + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) + ready_reg <= 'b0; + else if (zeroize) + ready_reg <= 'b0; + else begin + if (mlkem) begin + unique case(mode) + ct: ready_reg <= {4'h0, enable, ready_reg[MLKEM_UNMASKED_BF_LATENCY-1:1]}; + gs: ready_reg <= {4'h0, enable, ready_reg[MLKEM_UNMASKED_BF_LATENCY-1:1]}; + pwm: ready_reg <= '0; + pwa: ready_reg <= {9'h0, enable}; + pws: ready_reg <= {9'h0, enable}; + pairwm: ready_reg <= accumulate ? {5'h0, enable, ready_reg[MLKEM_UNMASKED_PAIRWM_ACC_LATENCY-1:1]} : {6'h0, enable, ready_reg[MLKEM_UNMASKED_PAIRWM_LATENCY-1:1]}; + default: ready_reg <= 'h0; + endcase + end + else begin + unique case(mode) + ct: ready_reg <= {enable, ready_reg[UNMASKED_BF_LATENCY-1:1]}; + gs: ready_reg <= {enable, ready_reg[UNMASKED_BF_LATENCY-1:1]}; + pwm: ready_reg <= accumulate ? {5'h0, enable, ready_reg[UNMASKED_PWM_LATENCY-1:1]} : {6'h0, enable, ready_reg[UNMASKED_PWM_LATENCY-2:1]}; + pwa: ready_reg <= {9'h0, enable}; + pws: ready_reg <= {9'h0, enable}; + pairwm: ready_reg <= 'h0; + default: ready_reg <= 'h0; + endcase + end + end + end + + assign ready_o = ready_reg[0]; + + +endmodule diff --git a/designs/Caliptra/src/adams-bridge/ntt_ctrl.sv b/designs/Caliptra/src/adams-bridge/ntt_ctrl.sv new file mode 100644 index 0000000..48d4e12 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/ntt_ctrl.sv @@ -0,0 +1,1240 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +// +//====================================================================== +// +// ntt_ctrl.sv +// -------- +// This block: +// 1. Keeps track of stages of bf2x2 operation in ct, gs, pwo modes +// 2. Controls wr/rd addr of NTT mem +// 3. Controls rd addr of twiddle ROM +// 4. Performs shuffling of wr/rd addr +// Note: Latency changes in BFU must be reflected in the latency params here and in bf2x2 for correct pipeline operation +//====================================================================== + +module ntt_ctrl + import ntt_defines_pkg::*; +#( + parameter REG_SIZE = 23, + parameter RADIX = 23, + parameter MLDSA_Q = 23'd8380417, + parameter MLDSA_Q_DIV2_ODD = (MLDSA_Q+1)/2, + parameter MLDSA_N = 256, + parameter MLDSA_LOGN = 8, + parameter MEM_ADDR_WIDTH = 15 +) +( + input wire clk, + input wire reset_n, + input wire zeroize, + input mode_t ntt_mode, + input wire ntt_enable, + input wire butterfly_ready, + input wire buf0_valid, + input wire sampler_valid, + input wire accumulate, + //NTT/INTT base addr + input ntt_mem_addr_t ntt_mem_base_addr, + //PWO base addr + input pwo_mem_addr_t pwo_mem_base_addr, + input wire shuffle_en, + input wire [5:0] random, //4+2 bits + input wire masking_en, + input wire mlkem, + + output logic bf_enable, + output logic [2:0] opcode, + output logic masking_en_ctrl, + output logic buf_wren, + output logic buf_rden, + output logic [1:0] buf_wrptr, + output logic [1:0] buf_rdptr, + output logic [6:0] twiddle_addr, + + output logic [MEM_ADDR_WIDTH-1:0] mem_rd_addr, + output logic [MEM_ADDR_WIDTH-1:0] mem_wr_addr, + output logic mem_rd_en, + output logic mem_wr_en, + output logic buf_wr_rst_count, + output logic buf_rd_rst_count, + + //PWO outputs + output logic [MEM_ADDR_WIDTH-1:0] pw_mem_rd_addr_a, + output logic [MEM_ADDR_WIDTH-1:0] pw_mem_rd_addr_b, + output logic [MEM_ADDR_WIDTH-1:0] pw_mem_rd_addr_c, + output logic [MEM_ADDR_WIDTH-1:0] pw_mem_wr_addr_c, + output logic pw_rden, + output logic pw_wren, + output logic pw_share_mem_rden, + output logic busy, + output logic done, + output logic ntt_passthrough, + output logic intt_passthrough +); + +//Parameters +localparam NTT_NUM_ROUNDS = 4; +localparam PWO_NUM_ROUNDS = 1; +localparam NTT_READ_ADDR_STEP = 16; +localparam NTT_WRITE_ADDR_STEP = 1; +localparam INTT_READ_ADDR_STEP = 1; +localparam INTT_WRITE_ADDR_STEP = 16; +localparam PWO_READ_ADDR_STEP = 1; +localparam PWO_WRITE_ADDR_STEP = 1; + +localparam [MEM_ADDR_WIDTH-1:0] MEM_LAST_ADDR = 63; + +//FSM states +ntt_read_state_t read_fsm_state_ps, read_fsm_state_ns; +ntt_write_state_t write_fsm_state_ps, write_fsm_state_ns; + +//BF enable flags +logic bf_enable_fsm; +logic [2:0] bf_enable_reg; + +//Buffer signals +logic buf_wr_rst_count_ntt, buf_rd_rst_count_ntt; +logic buf_wr_rst_count_intt, buf_rd_rst_count_intt; +logic [1:0] buf_count; + +//Shuffle buffer signals +logic [3:0] chunk_rand_offset; +logic [3:0] chunk_count; +logic [1:0] index_rand_offset, index_count, mem_rd_index_ofst; +logic [2:0][1:0] index_rand_offset_reg, index_count_reg; +logic [1:0] buf_rdptr_int; +logic [1:0] buf_rdptr_f; + +logic [MASKED_INTT_WRBUF_LATENCY-1:0][1:0] buf_rdptr_reg; +logic [MASKED_INTT_WRBUF_LATENCY-1:0][1:0] buf_wrptr_reg; +logic [1:0] buf_wrptr_reg_d1; +logic [MASKED_INTT_WRBUF_LATENCY-3:0][3:0] chunk_count_reg; //buf latency not rqd +logic [1:0] masked_pwm_buf_rdptr_d1, masked_pwm_buf_rdptr_d2, masked_pwm_buf_rdptr_d3; //TODO clean up + +logic latch_chunk_rand_offset, latch_index_rand_offset; +logic last_rd_addr, last_wr_addr; +logic mem_wr_en_fsm, mem_wr_en_reg; +logic mem_rd_en_fsm, mem_rd_en_reg; +logic pw_rden_fsm, pw_rden_reg; +logic pw_wren_fsm, pw_wren_reg, pw_wren_fsm_reg; +logic [MASKED_PWM_LATENCY:0] pw_rden_fsm_reg; +logic shuffled_pw_rden_fsm_reg; + +//Mode flags +logic ct_mode, gs_mode, pwo_mode; //point-wise operations mode +logic pwm_mode, pwa_mode, pws_mode, pairwm_mode; + +//Addr internal wires +logic [MEM_ADDR_WIDTH-1:0] src_base_addr, interim_base_addr, dest_base_addr; +logic [MEM_ADDR_WIDTH-1:0] pw_base_addr_a, pw_base_addr_b, pw_base_addr_c; +logic [MEM_ADDR_WIDTH-1:0] pw_mem_rd_addr_a_nxt, pw_mem_rd_addr_b_nxt, pw_mem_rd_addr_c_nxt, pw_mem_wr_addr_c_nxt; +logic incr_mem_rd_addr; +logic incr_mem_wr_addr; +logic rst_rd_addr, rst_wr_addr; +logic [MEM_ADDR_WIDTH:0] mem_rd_addr_nxt, mem_wr_addr_nxt; //One extra bit in addr to roll over addr, so we can wraparound in the addr range +logic [MEM_ADDR_WIDTH-1:0] mem_rd_base_addr, mem_wr_base_addr; +logic [4:0] rd_addr_step, wr_addr_step; +logic rd_addr_wraparound; +logic wr_addr_wraparound; + +//PWO wires +logic incr_pw_rd_addr, incr_pw_wr_addr; +logic rst_pw_addr; +logic [MASKED_PWM_LATENCY:0] incr_pw_rd_addr_reg, incr_pw_wr_addr_reg; +logic incr_pw_rd_addr_reg_d1; + +//Twiddle ROM wires +logic incr_twiddle_addr, incr_twiddle_addr_fsm, incr_twiddle_addr_reg, incr_twiddle_addr_reg_d2; +logic rst_twiddle_addr; +logic [6:0] twiddle_rand_offset, twiddle_rand_offset_reg; +logic [6:0] twiddle_end_addr, twiddle_addr_reg, twiddle_addr_reg_d2, twiddle_addr_reg_d3, twiddle_addr_int, twiddle_offset, twiddle_addr_sampler_mode; +logic [6:0] twiddle_addr_sampler_mode_d2, twiddle_addr_sampler_mode_d3; + +//FSM round signals +logic [$clog2(NTT_NUM_ROUNDS):0] num_rounds; +logic [$clog2(NTT_NUM_ROUNDS):0] rounds_count; +logic incr_rounds; +logic rst_rounds; + +//Done, busy flags +logic stage_done; +logic ntt_done; +logic intt_done; +logic pwo_done; +logic ntt_busy; +logic pwo_busy; + +//Valid count wires - counts 64 cycles of valid +logic [6:0] wr_valid_count; +logic [6:0] rd_valid_count_int, rd_valid_count; +logic wr_data_valid; +logic rd_data_valid; +logic rst_wr_valid_count, rst_rd_valid_count; + +//Read FSM +//Common arcs +logic arc_IDLE_RD_STAGE; +logic arc_RD_EXEC_RD_STAGE; +logic arc_RD_STAGE_IDLE; + +//NTT Arcs +logic arc_RD_STAGE_RD_BUF; +logic arc_RD_BUF_RD_EXEC; +logic arc_RD_EXEC_RD_BUF; +logic arc_RD_EXEC_EXEC_WAIT; +logic arc_EXEC_WAIT_RD_STAGE; + +//INTT Arcs +logic arc_RD_STAGE_RD_EXEC; +logic arc_RD_STAGE_RD_EXEC_OPT; + +//PWO Arc +logic arc_EXEC_WAIT_RD_EXEC; + +//Other signals +logic buf_wren_ntt, buf_wren_ntt_reg; +logic buf_wren_intt, buf_wren_intt_reg; +logic buf_rden_ntt, buf_rden_ntt_reg; +logic buf_rden_intt; + +//Write FSM +//Common arcs +logic arc_IDLE_WR_STAGE; +logic arc_WR_MEM_WR_STAGE; +logic arc_WR_STAGE_IDLE; + +//NTT Arcs +logic arc_WR_STAGE_WR_MEM; + +//INTT Arcs +logic arc_WR_STAGE_WR_BUF; +logic arc_WR_BUF_WR_MEM; +logic arc_WR_MEM_WR_BUF; +logic arc_WR_MEM_WR_WAIT; +logic arc_WR_WAIT_WR_STAGE; + +//PWO Arcs +logic arc_WR_STAGE_WR_WAIT; +logic arc_WR_WAIT_WR_MEM; +logic arc_WR_STAGE_WR_MEM_OPT; + +logic masked_pwm_exec_in_progress; + +logic [MEM_ADDR_WIDTH-1:0] shuffled_pw_mem_rd_addr_c_nxt_accumulate, shuffled_pw_mem_wr_addr_c_nxt; +logic [MEM_ADDR_WIDTH-1:0] masked_shuffled_pw_mem_rd_addr_c_nxt_accumulate, masked_shuffled_pw_mem_wr_addr_c_nxt, masked_shuffled_pw_mem_wr_addr_c_nxt_accumulate; +logic [MEM_ADDR_WIDTH-1:0] mlkem_masked_shuffled_pw_mem_rd_addr_c_nxt_accumulate, mlkem_masked_shuffled_pw_mem_wr_addr_c_nxt, mlkem_masked_shuffled_pw_mem_wr_addr_c_nxt_accumulate; + +//------------------------------------------ +always_comb begin + ct_mode = (ntt_mode == ct); + gs_mode = (ntt_mode == gs); + pairwm_mode = mlkem & (ntt_mode == pairwm); + pwo_mode = (ntt_mode inside {pwm, pwa, pws}) | pairwm_mode; + pwm_mode = (ntt_mode == pwm); + pwa_mode = (ntt_mode == pwa); + pws_mode = (ntt_mode == pws); +end + +always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) begin + opcode <= ct; //default + masking_en_ctrl <= 'b0; + end + else if (zeroize) begin + opcode <= ct; + masking_en_ctrl <= 'b0; + end + else if (masking_en) begin + if (gs_mode & (rounds_count == 'h0) & (read_fsm_state_ps == RD_STAGE) & (write_fsm_state_ps == WR_STAGE)) begin //gate with fsm state to delay masking_en_ctrl to be more meaningful + opcode <= gs; + masking_en_ctrl <= 'b1; + end + else if (gs_mode & (rounds_count > 'h0)) begin //subseq rounds + opcode <= gs; + masking_en_ctrl <= 'b0; + end + else begin + opcode <= ntt_mode; //all others + end + end + else begin + opcode <= ntt_mode; + end +end + +always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) begin + buf_wrptr_reg_d1 <= '0; + end + else if (zeroize) begin + buf_wrptr_reg_d1 <= '0; + end + else begin + buf_wrptr_reg_d1 <= mlkem ? buf_wrptr_reg[MASKED_INTT_WRBUF_LATENCY-MLKEM_MASKED_INTT_WRBUF_LATENCY] : buf_wrptr_reg[0]; + end +end + +//------------------------------------------ +//Rounds counter +//------------------------------------------ +always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) + rounds_count <= 'h0; + else if (zeroize) + rounds_count <= 'h0; + else if (rst_rounds) + rounds_count <= 'h0; + else if (incr_rounds && (rounds_count < num_rounds)) + rounds_count <= rounds_count + 'h1; + else if (rounds_count == num_rounds) + rounds_count <= 'h0; +end +assign num_rounds = (ntt_mode inside {ct, gs}) ? NTT_NUM_ROUNDS : PWO_NUM_ROUNDS; + +always_comb begin + ntt_passthrough = ct_mode & mlkem & (rounds_count == NTT_NUM_ROUNDS-1); + intt_passthrough = gs_mode & mlkem & (rounds_count == 0); +end + +//------------------------------------------ +//Done flags +//------------------------------------------ +//Stage is done when round counter is incremented and both fsms are in stage state +assign stage_done = (rounds_count > 'h0) && (read_fsm_state_ps == RD_STAGE) && (write_fsm_state_ps == WR_STAGE); +assign ntt_done = ct_mode && (rounds_count == NTT_NUM_ROUNDS); +assign intt_done = gs_mode && (rounds_count == NTT_NUM_ROUNDS); +assign pwo_done = pwo_mode && (rounds_count == PWO_NUM_ROUNDS); +assign done = ntt_done | intt_done | pwo_done; + +//------------------------------------------ +//Mem read/write addr counter +//------------------------------------------ +//NTT mem addr +always_comb begin + src_base_addr = (ct_mode | gs_mode) ? ntt_mem_base_addr.src_base_addr : 'h0; + interim_base_addr = (ct_mode | gs_mode) ? ntt_mem_base_addr.interim_base_addr : 'h0; + dest_base_addr = (ct_mode | gs_mode) ? ntt_mem_base_addr.dest_base_addr : 'h0; + + pw_base_addr_a = pwo_mode ? pwo_mem_base_addr.pw_base_addr_a : 'h0; + pw_base_addr_b = pwo_mode ? pwo_mem_base_addr.pw_base_addr_b : 'h0; + pw_base_addr_c = pwo_mode ? pwo_mem_base_addr.pw_base_addr_c : 'h0; +end +//Wraparound - indicates if we need to start at next addr (Eg. 0, 16, 32, 48, 1, 17, 33, 49, 2, ...) +//Wraparound allows addr to transition from 48 to 1, 49 to 2, etc instead of overflowing +always_comb begin + mem_rd_base_addr = (rounds_count == 'h0) ? src_base_addr : rounds_count[0] ? interim_base_addr : dest_base_addr; + mem_wr_base_addr = rounds_count[0] ? dest_base_addr : interim_base_addr; + + if (shuffle_en) begin + mem_rd_addr_nxt = (gs_mode) ? (4*chunk_count) + (rd_addr_step*mem_rd_index_ofst) + mem_rd_base_addr : mem_rd_addr + rd_addr_step; + mem_wr_addr_nxt = ct_mode ? (MEM_ADDR_WIDTH+1)'((4*(mlkem ? chunk_count_reg[UNMASKED_BF_LATENCY-MLKEM_UNMASKED_BF_LATENCY] : chunk_count_reg[0])) + (wr_addr_step*(mlkem ? buf_rdptr_reg[UNMASKED_BF_LATENCY-MLKEM_UNMASKED_BF_LATENCY] : buf_rdptr_reg[0])) + mem_wr_base_addr) : gs_mode ? mem_wr_addr + wr_addr_step : (MEM_ADDR_WIDTH+1)'((4*chunk_count_reg[4]) + (wr_addr_step*buf_rdptr_reg[4])); + end + else begin + mem_rd_addr_nxt = mem_rd_addr + rd_addr_step; + mem_wr_addr_nxt = mem_wr_addr + wr_addr_step; + end + + rd_addr_wraparound = mem_rd_addr_nxt > {1'b0,mem_rd_base_addr} + MEM_LAST_ADDR; + wr_addr_wraparound = mem_wr_addr_nxt > {1'b0,mem_wr_base_addr} + MEM_LAST_ADDR; +end + +//Read addr +always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) begin + mem_rd_addr <= 'h0; + end + else if (zeroize) begin + mem_rd_addr <= 'h0; + end + else if (rst_rd_addr) begin + if (shuffle_en) + mem_rd_addr <= ct_mode ? mem_rd_base_addr + chunk_rand_offset : gs_mode ? mem_rd_base_addr + (4*chunk_rand_offset) : mem_rd_base_addr; + else + mem_rd_addr <= mem_rd_base_addr; + end + else if (incr_mem_rd_addr) begin + if (shuffle_en) + mem_rd_addr <= (ct_mode & last_rd_addr) ? mem_rd_base_addr : rd_addr_wraparound ? MEM_ADDR_WIDTH'(mem_rd_addr_nxt - MEM_LAST_ADDR) : mem_rd_addr_nxt[MEM_ADDR_WIDTH-1:0]; + else + mem_rd_addr <= rd_addr_wraparound ? MEM_ADDR_WIDTH'(mem_rd_addr_nxt - MEM_LAST_ADDR) : mem_rd_addr_nxt[MEM_ADDR_WIDTH-1:0]; + end +end + +//Write addr +always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) begin + mem_wr_addr <= 'h0; + end + else if (zeroize) begin + mem_wr_addr <= 'h0; + end + else if (rst_wr_addr) begin + if (shuffle_en) + mem_wr_addr <= ct_mode ? mem_wr_base_addr + (4*chunk_rand_offset) : gs_mode ? mem_wr_base_addr + chunk_rand_offset : mem_wr_base_addr; + else + mem_wr_addr <= mem_wr_base_addr; + end + else if (incr_mem_wr_addr) begin + if (shuffle_en) + mem_wr_addr <= (gs_mode & last_wr_addr) ? mem_wr_base_addr : wr_addr_wraparound ? MEM_ADDR_WIDTH'(mem_wr_addr_nxt - MEM_LAST_ADDR) : mem_wr_addr_nxt[MEM_ADDR_WIDTH-1:0]; + else + mem_wr_addr <= wr_addr_wraparound ? MEM_ADDR_WIDTH'(mem_wr_addr_nxt - MEM_LAST_ADDR) : mem_wr_addr_nxt[MEM_ADDR_WIDTH-1:0]; + end +end + +always_comb begin + pw_mem_rd_addr_a_nxt = pw_base_addr_a + (4*chunk_count) + (PWO_READ_ADDR_STEP*mem_rd_index_ofst); + pw_mem_rd_addr_b_nxt = pw_base_addr_b + (4*chunk_count) + (PWO_READ_ADDR_STEP*mem_rd_index_ofst); + + pw_mem_wr_addr_c_nxt = accumulate ? pw_base_addr_c + (4*chunk_count_reg[UNMASKED_PWM_LATENCY-2]) + (PWO_WRITE_ADDR_STEP*buf_rdptr_reg[UNMASKED_PWM_LATENCY-2]) + : (pwa_mode | pws_mode) ? pw_base_addr_c + (4*chunk_count_reg[7]) + (PWO_WRITE_ADDR_STEP*buf_rdptr_reg[7]) + : pw_base_addr_c + (4*chunk_count_reg[UNMASKED_PWM_LATENCY-1]) + (PWO_WRITE_ADDR_STEP*buf_rdptr_reg[UNMASKED_PWM_LATENCY-1]); //2 + + if (pwm_mode) begin + shuffled_pw_mem_wr_addr_c_nxt = accumulate ? pw_base_addr_c + (4*chunk_count_reg[UNMASKED_PWM_LATENCY-2]) + (PWO_WRITE_ADDR_STEP*buf_rdptr_reg[UNMASKED_PWM_LATENCY-2]) + : pw_base_addr_c + (4*chunk_count_reg[UNMASKED_PWM_LATENCY-1]) + (PWO_WRITE_ADDR_STEP*buf_rdptr_reg[UNMASKED_PWM_LATENCY-1]); + end + else if (pairwm_mode) begin + shuffled_pw_mem_wr_addr_c_nxt = accumulate ? pw_base_addr_c + (4*chunk_count_reg[MLKEM_UNMASKED_PAIRWM_LATENCY-1]) + (PWO_WRITE_ADDR_STEP*buf_rdptr_reg[MLKEM_UNMASKED_PAIRWM_LATENCY-1]) + : pw_base_addr_c + (4*chunk_count_reg[MLKEM_UNMASKED_PAIRWM_LATENCY]) + (PWO_WRITE_ADDR_STEP*buf_rdptr_reg[MLKEM_UNMASKED_PAIRWM_LATENCY]); + end + else if (pwa_mode | pws_mode) begin + shuffled_pw_mem_wr_addr_c_nxt = pw_base_addr_c + (4*chunk_count_reg[7]) + (PWO_WRITE_ADDR_STEP*buf_rdptr_reg[7]); + end + else + shuffled_pw_mem_wr_addr_c_nxt = 0; + + masked_shuffled_pw_mem_wr_addr_c_nxt = pw_base_addr_c + (4*chunk_count_reg[MASKED_INTT_LATENCY-MASKED_PWM_LATENCY-2]) + (PWO_WRITE_ADDR_STEP*masked_pwm_buf_rdptr_d2); + masked_shuffled_pw_mem_wr_addr_c_nxt_accumulate = pw_base_addr_c + (4*chunk_count_reg[MASKED_INTT_LATENCY-MASKED_PWM_ACC_LATENCY-3]) + (PWO_WRITE_ADDR_STEP*masked_pwm_buf_rdptr_d3); //-3 for chunk count because latency here is measured from mem read to incr_pw_wr_addr which is 264+3 cycles + + mlkem_masked_shuffled_pw_mem_wr_addr_c_nxt = pw_base_addr_c + (4*chunk_count_reg[0]) + (PWO_WRITE_ADDR_STEP*masked_pwm_buf_rdptr_d3); + mlkem_masked_shuffled_pw_mem_wr_addr_c_nxt_accumulate = pw_base_addr_c + (4*chunk_count_reg[0]) + (PWO_WRITE_ADDR_STEP*masked_pwm_buf_rdptr_d3); //-3 for chunk count because latency here is measured from mem read to incr_pw_wr_addr which is 264+3 cycles + + shuffled_pw_mem_rd_addr_c_nxt_accumulate = pw_base_addr_c + ((4*chunk_count)+(PWO_READ_ADDR_STEP*mem_rd_index_ofst)); + masked_shuffled_pw_mem_rd_addr_c_nxt_accumulate = (pwm_mode & masking_en) ? pw_base_addr_c + ((4*chunk_count_reg[MASKED_INTT_LATENCY-MASKED_PWM_LATENCY]) + (PWO_READ_ADDR_STEP*buf_rdptr_reg[MASKED_PWM_ACC_LATENCY-MASKED_PWM_LATENCY])) : 'h0; + + mlkem_masked_shuffled_pw_mem_rd_addr_c_nxt_accumulate = (pairwm_mode & masking_en) ? pw_base_addr_c + ((4*chunk_count_reg[(MLKEM_MASKED_PAIRWM_ACC_LATENCY+3)-(MLKEM_MASKED_PAIRWM_LATENCY-MLKEM_BARRETT_REDUCTION_LATENCY)]) + (PWO_READ_ADDR_STEP*buf_rdptr_reg[MLKEM_MASKED_PAIRWM_ACC_LATENCY-(MLKEM_MASKED_PAIRWM_LATENCY-MLKEM_BARRETT_REDUCTION_LATENCY)])) : 'h0; //+3 to account for flop delay in chunk count reg, -6 to remove reduction latency since w input is required before reduction is done in pairwm, //-1 in buf_rdptr because there are n+1 entries in the reg + + if ((pwm_mode | pairwm_mode) & accumulate) begin + unique case({masking_en, shuffle_en}) + 2'b00: pw_mem_rd_addr_c_nxt = pw_mem_rd_addr_c + PWO_READ_ADDR_STEP; + 2'b01: pw_mem_rd_addr_c_nxt = shuffled_pw_mem_rd_addr_c_nxt_accumulate; + 2'b10: pw_mem_rd_addr_c_nxt = pw_mem_rd_addr_c + PWO_READ_ADDR_STEP; + 2'b11: pw_mem_rd_addr_c_nxt = mlkem ? mlkem_masked_shuffled_pw_mem_rd_addr_c_nxt_accumulate : masked_shuffled_pw_mem_rd_addr_c_nxt_accumulate; + default: pw_mem_rd_addr_c_nxt = 'h0; + endcase + end + else + pw_mem_rd_addr_c_nxt = 'h0; +end + +always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) begin + incr_pw_rd_addr_reg <= '0; + incr_pw_wr_addr_reg <= '0; + incr_pw_rd_addr_reg_d1 <= '0; + end + else if (zeroize) begin + incr_pw_rd_addr_reg <= '0; + incr_pw_wr_addr_reg <= '0; + incr_pw_rd_addr_reg_d1 <= '0; + end + else if (masking_en & (pwm_mode | pairwm_mode)) begin + incr_pw_rd_addr_reg <= {incr_pw_rd_addr, incr_pw_rd_addr_reg[MASKED_PWM_LATENCY:1]}; + incr_pw_wr_addr_reg <= {incr_pw_wr_addr, incr_pw_wr_addr_reg[MASKED_PWM_LATENCY:1]}; + incr_pw_rd_addr_reg_d1 <= incr_pw_rd_addr_reg[0]; + end +end + +//PWO addr +always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) begin + pw_mem_rd_addr_a <= '0; + pw_mem_rd_addr_b <= '0; + pw_mem_rd_addr_c <= '0; + pw_mem_wr_addr_c <= '0; + end + else if (zeroize) begin + pw_mem_rd_addr_a <= '0; + pw_mem_rd_addr_b <= '0; + pw_mem_rd_addr_c <= '0; + pw_mem_wr_addr_c <= '0; + end + else if (rst_pw_addr) begin + pw_mem_rd_addr_a <= shuffle_en ? (4*chunk_rand_offset) + pw_base_addr_a : pw_base_addr_a; + pw_mem_rd_addr_b <= shuffle_en ? (4*chunk_rand_offset) + pw_base_addr_b : pw_base_addr_b; + pw_mem_rd_addr_c <= shuffle_en ? (4*chunk_rand_offset) + pw_base_addr_c : pw_base_addr_c; + pw_mem_wr_addr_c <= shuffle_en ? (4*chunk_rand_offset) + pw_base_addr_c : pw_base_addr_c; + end + else begin + if (incr_pw_rd_addr) begin + if (shuffle_en) begin + pw_mem_rd_addr_a <= pw_mem_rd_addr_a_nxt; + pw_mem_rd_addr_b <= pw_mem_rd_addr_b_nxt; + end + else begin + pw_mem_rd_addr_a <= pw_mem_rd_addr_a + PWO_READ_ADDR_STEP; + pw_mem_rd_addr_b <= pw_mem_rd_addr_b + PWO_READ_ADDR_STEP; + end + end + + //accumulate + if ((pwm_mode | pairwm_mode) & accumulate) begin + if ((masking_en & (mlkem ? (shuffle_en ? incr_pw_rd_addr_reg[MASKED_PWM_LATENCY-(MLKEM_MASKED_PAIRWM_LATENCY-MLKEM_BARRETT_REDUCTION_LATENCY)] : incr_pw_rd_addr_reg[MASKED_PWM_LATENCY-(MLKEM_MASKED_PAIRWM_LATENCY-MLKEM_BARRETT_REDUCTION_LATENCY+1)]) : incr_pw_rd_addr_reg[0])) | (~masking_en & incr_pw_rd_addr)) begin //-6 to remove reduction latency, +1 because incr reg has n+1 entries not n + pw_mem_rd_addr_c <= pw_mem_rd_addr_c_nxt; + end + end + else begin + pw_mem_rd_addr_c <= 'h0; + end + + if (incr_pw_wr_addr) begin + pw_mem_wr_addr_c <= (masking_en & shuffle_en) ? accumulate ? mlkem ? mlkem_masked_shuffled_pw_mem_wr_addr_c_nxt_accumulate : masked_shuffled_pw_mem_wr_addr_c_nxt_accumulate : mlkem ? mlkem_masked_shuffled_pw_mem_wr_addr_c_nxt : masked_shuffled_pw_mem_wr_addr_c_nxt : (~masking_en & shuffle_en) ? shuffled_pw_mem_wr_addr_c_nxt : pw_mem_wr_addr_c + PWO_WRITE_ADDR_STEP; + end + end +end + + +//------------------------------------------ +//Twiddle addr logic +//------------------------------------------ +always_comb begin + unique case(rounds_count) + 'h0: begin + twiddle_end_addr = pairwm_mode ? 'd63 : ct_mode ? 'd0 : 'd63; + twiddle_offset = pairwm_mode ? 'd21 : 'h0; + twiddle_rand_offset = pairwm_mode ? 7'((chunk_count % 'd16)*4 + buf_rdptr_int) : ct_mode ? 'h0 : (gs_mode & masking_en_ctrl) ? 7'((4*chunk_count_reg[MASKED_INTT_WRBUF_LATENCY-3]) + buf_wrptr_reg[MASKED_INTT_WRBUF_LATENCY-1]) : 7'((4*chunk_count_reg[UNMASKED_BF_LATENCY]) + buf_wrptr_reg[INTT_WRBUF_LATENCY-1]); //gs mode & masking only applies to round 0. Other rounds follow gs calc + end + 'h1: begin + twiddle_end_addr = ct_mode ? 'd3 : 'd15; + twiddle_offset = ct_mode ? 'd1 : 'd64; + twiddle_rand_offset = ct_mode ? 7'(buf_rdptr_int) : 7'((chunk_count_reg[UNMASKED_BF_LATENCY] % 4)*4 + buf_wrptr_reg[INTT_WRBUF_LATENCY-1]); + end + 'h2: begin + twiddle_end_addr = ct_mode ? 'd15 : 'd3; + twiddle_offset = ct_mode ? 'd5 : 'd80; + twiddle_rand_offset = ct_mode ? 7'((chunk_count % 'd4)*'d4 + buf_rdptr_int) : 7'(buf_wrptr_reg[INTT_WRBUF_LATENCY-1]); + end + 'h3: begin + twiddle_end_addr = ct_mode ? 'd63 : 'd0; + twiddle_offset = ct_mode ? 'd21 : 'd84; + twiddle_rand_offset = ct_mode ? 7'((chunk_count % 'd16)*4 + buf_rdptr_int) : 'h0; + end + default: begin + twiddle_end_addr = 'h0; + twiddle_offset = 'h0; + twiddle_rand_offset = 'h0; + end + endcase +end + +//Flop the incr and twiddle_addr to align with memory read latency +always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) begin + incr_twiddle_addr_reg <= 'b0; + incr_twiddle_addr_reg_d2 <= 'b0; + twiddle_rand_offset_reg <= '0; + end + else if (zeroize) begin + incr_twiddle_addr_reg <= 'b0; + incr_twiddle_addr_reg_d2 <= 'b0; + twiddle_rand_offset_reg <= '0; + end + else begin + incr_twiddle_addr_reg <= incr_twiddle_addr_fsm; + incr_twiddle_addr_reg_d2 <= incr_twiddle_addr_reg; + twiddle_rand_offset_reg <= twiddle_rand_offset; + end +end + +assign incr_twiddle_addr = ct_mode ? incr_twiddle_addr_fsm : incr_twiddle_addr_reg; + + +always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) + twiddle_addr_reg <= 'h0; + else if (zeroize) + twiddle_addr_reg <= 'h0; + else if (incr_twiddle_addr) + twiddle_addr_reg <= shuffle_en ? twiddle_rand_offset : (twiddle_addr_reg == twiddle_end_addr) ? 'h0 : twiddle_addr_reg + 'd1; + else if (rst_twiddle_addr) + twiddle_addr_reg <= 'h0; +end + +assign twiddle_addr_int = (~shuffle_en | ct_mode) ? twiddle_addr_reg + twiddle_offset : (shuffle_en & pairwm_mode) ? twiddle_rand_offset + 2'(index_count + index_rand_offset) + twiddle_offset : twiddle_rand_offset + twiddle_offset; + +//------------------------------------------ +//Busy logic +//------------------------------------------ +assign busy = ntt_busy | pwo_busy; +assign ntt_busy = (read_fsm_state_ps != RD_IDLE) && (write_fsm_state_ps != WR_IDLE) && (ct_mode | gs_mode); +assign pwo_busy = (read_fsm_state_ps != RD_IDLE) && (write_fsm_state_ps != WR_IDLE) && pwo_mode; + +//------------------------------------------ +//Valid count - to check that all 64 addr have been processed - check writes to mem +//------------------------------------------ +always_comb wr_data_valid = gs_mode ? buf0_valid : butterfly_ready; //ct or pwo mode - look for bf_ready +always_comb rd_data_valid = ct_mode ? buf0_valid : gs_mode ? bf_enable_fsm : sampler_valid; + +always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) + wr_valid_count <= 'h0; + else if (zeroize) + wr_valid_count <= 'h0; + else if (rst_wr_valid_count) + wr_valid_count <= 'h0; + else if (wr_data_valid) + wr_valid_count <= gs_mode ? (wr_valid_count > 'h40) ? 'h0 : wr_valid_count + 'h4 + : wr_valid_count + 'h1; +end + +always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) + rd_valid_count <= 'h0; + else if (zeroize) + rd_valid_count <= 'h0; + else if (rst_rd_valid_count) + rd_valid_count <= 'h0; + else if (rd_data_valid) + rd_valid_count <= ct_mode ? (rd_valid_count > 'h40) ? 'h0 : rd_valid_count + 'h4 + : rd_valid_count + 'h1; + +end + +//------------------------------------------ +//Buffer count - start count when buf0_valid is received +//Once counter starts, count until 3 to signify that all 4 buffers +//are valid. Then wait at 0 until next buf0_valid comes in +//------------------------------------------ +always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) + buf_count <= 'h0; + else if (zeroize) + buf_count <= 'h0; + else if (buf0_valid) + buf_count <= buf_count + 1; + else if (buf_count > 0 && buf_count < 3) + buf_count <= buf_count + 1; + else + buf_count <= 'h0; +end + +//------------------------------------------ +//Shuffle buffer +//------------------------------------------ +always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) begin + chunk_rand_offset <= 'h0; + chunk_count <= 'h0; + end + else if (zeroize) begin + chunk_rand_offset <= 'h0; + chunk_count <= 'h0; + end + else if (latch_chunk_rand_offset) begin + chunk_rand_offset <= random[5:2]; + chunk_count <= random[5:2]; + end + else if ((ct_mode & (buf_count == 'h3)) | ((gs_mode | (pwo_mode & incr_pw_rd_addr)) & (index_count == 'h3))) begin //update chunk after every 4 cycles - TODO: stop chunk counting when there's no incr_rd_addr in ntt/intt modes + chunk_count <= (chunk_count == 'hf) ? 'h0 : chunk_count + 'h1; + end +end + +always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) begin + index_rand_offset <= 'h0; + + end + else if (zeroize) begin + index_rand_offset <= 'h0; + + end + else if (latch_index_rand_offset) begin + index_rand_offset <= random[1:0]; + end + +end + +always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) begin + buf_rdptr_reg <= 'h0; + buf_wrptr_reg <= 'h0; + masked_pwm_buf_rdptr_d1 <= '0; + masked_pwm_buf_rdptr_d2 <= '0; + masked_pwm_buf_rdptr_d3 <= '0; + end + else if (zeroize) begin + buf_rdptr_reg <= 'h0; + buf_wrptr_reg <= 'h0; + masked_pwm_buf_rdptr_d1 <= '0; + masked_pwm_buf_rdptr_d2 <= '0; + masked_pwm_buf_rdptr_d3 <= '0; + end + else if (ct_mode & (buf_rden_ntt | butterfly_ready)) begin + buf_rdptr_reg <= {{(MASKED_INTT_WRBUF_LATENCY-UNMASKED_BF_LATENCY-1){'0}}, buf_rdptr_int, buf_rdptr_reg[UNMASKED_BF_LATENCY:1]}; + end + else if ((gs_mode & (incr_mem_rd_addr | butterfly_ready) & ~masking_en_ctrl)) begin + buf_wrptr_reg <= {{(MASKED_INTT_WRBUF_LATENCY-INTT_WRBUF_LATENCY){2'h0}}, mem_rd_index_ofst, buf_wrptr_reg[INTT_WRBUF_LATENCY-1:1]}; + end + else if ((pwo_mode & ~masking_en) & (incr_pw_rd_addr | butterfly_ready)) begin + buf_rdptr_reg <= {{(MASKED_INTT_WRBUF_LATENCY-UNMASKED_BF_LATENCY-1){'0}}, mem_rd_index_ofst, buf_rdptr_reg[UNMASKED_BF_LATENCY:1]}; + end + else if ((gs_mode & (incr_mem_rd_addr | masking_en_ctrl))) begin + buf_wrptr_reg <= {mem_rd_index_ofst, buf_wrptr_reg[MASKED_INTT_WRBUF_LATENCY-1:1]}; + end + else if ((pwm_mode & masking_en & masked_pwm_exec_in_progress)) begin + if (accumulate) + buf_rdptr_reg <= {{(MASKED_INTT_WRBUF_LATENCY-MASKED_PWM_ACC_LATENCY){1'b0}}, mem_rd_index_ofst, buf_rdptr_reg[MASKED_PWM_ACC_LATENCY:1]}; + else + buf_rdptr_reg <= {{(MASKED_INTT_WRBUF_LATENCY-MASKED_PWM_LATENCY){1'b0}}, mem_rd_index_ofst, buf_rdptr_reg[MASKED_PWM_LATENCY:1]}; + + masked_pwm_buf_rdptr_d1 <= buf_rdptr_reg[0]; + masked_pwm_buf_rdptr_d2 <= masked_pwm_buf_rdptr_d1; //Delay buf_rdptr_reg[0] by 2 cycles to accommodate delay of incr_pw_wr_addr - this delay is needed to correctly calculate wr addr in masking scenario in pwm + masked_pwm_buf_rdptr_d3 <= masked_pwm_buf_rdptr_d2; + end + else if ((pairwm_mode & masking_en & masked_pwm_exec_in_progress)) begin + if (accumulate) + buf_rdptr_reg <= {{(MASKED_INTT_WRBUF_LATENCY-MLKEM_MASKED_PAIRWM_ACC_LATENCY){1'b0}}, mem_rd_index_ofst, buf_rdptr_reg[MLKEM_MASKED_PAIRWM_ACC_LATENCY:1]}; + else + buf_rdptr_reg <= {{(MASKED_INTT_WRBUF_LATENCY-MLKEM_MASKED_PAIRWM_LATENCY){1'b0}}, mem_rd_index_ofst, buf_rdptr_reg[MLKEM_MASKED_PAIRWM_LATENCY:1]}; + + masked_pwm_buf_rdptr_d1 <= buf_rdptr_reg[0]; + masked_pwm_buf_rdptr_d2 <= masked_pwm_buf_rdptr_d1; //Delay buf_rdptr_reg[0] by 2 cycles to accommodate delay of incr_pw_wr_addr - this delay is needed to correctly calculate wr addr in masking scenario in pairwm + masked_pwm_buf_rdptr_d3 <= masked_pwm_buf_rdptr_d2; + end + else begin + buf_rdptr_reg <= 'h0; + buf_wrptr_reg <= 'h0; + masked_pwm_buf_rdptr_d1 <= '0; + masked_pwm_buf_rdptr_d2 <= '0; + masked_pwm_buf_rdptr_d3 <= '0; + end +end + +always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) begin + buf_rdptr_f <= 'h0; + end + else if (zeroize) begin + buf_rdptr_f <= 'h0; + end + else begin + buf_rdptr_f <= buf_rdptr_int; + end +end + +always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) begin + index_count <= 'h0; + end + else if (zeroize) begin + index_count <= 'h0; + end + else if ((gs_mode & incr_mem_rd_addr) | (pwo_mode & incr_pw_rd_addr)) begin + index_count <= index_count + 'h1; + end +end + +always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) begin + chunk_count_reg <= 'h0; + end + else if (zeroize) begin + chunk_count_reg <= 'h0; + end + else if ((pwm_mode & masking_en & masked_pwm_exec_in_progress) | (gs_mode & masking_en_ctrl)) begin + chunk_count_reg <= {chunk_count, chunk_count_reg[MASKED_INTT_WRBUF_LATENCY-3:1]}; + end + else if ((pairwm_mode & masking_en & masked_pwm_exec_in_progress)) begin + chunk_count_reg <= accumulate ? {{(MASKED_INTT_LATENCY-(MLKEM_MASKED_PAIRWM_ACC_LATENCY+3)){4'h0}}, chunk_count, chunk_count_reg[MLKEM_MASKED_PAIRWM_ACC_LATENCY+3:1]} : {{(MASKED_INTT_LATENCY-(MLKEM_MASKED_PAIRWM_LATENCY+3)){4'h0}}, chunk_count, chunk_count_reg[MLKEM_MASKED_PAIRWM_LATENCY+3:1]}; //incr_pw_rd_addr is asserted 4 cycles before 2x2 gets enabled, where chunk_count starts incrementing, so we need to shift chunk_count_reg by 4 cycles to account for this delay + pairwm acc delay + end + else if (buf_rden_ntt | butterfly_ready | (gs_mode & incr_mem_rd_addr) | (pwo_mode & incr_pw_rd_addr)) begin + chunk_count_reg <= {{(MASKED_BF_STAGE1_LATENCY+1-UNMASKED_BF_LATENCY){4'h0}}, chunk_count, chunk_count_reg[UNMASKED_BF_LATENCY:1]}; + end +end + +always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) begin + buf_wrptr <= 'h0; + end + else if (zeroize) begin + buf_wrptr <= 'h0; + end + else if (buf_wren & (ct_mode | ~shuffle_en)) begin //ct mode - buf writes are in order for both shuffling and non-shuffling. gs mode, non-shuffling buf writes are in order + buf_wrptr <= (buf_wrptr == 'h3) ? 'h0 : buf_wrptr + 'h1; + end + else if (buf_wren_intt & gs_mode & shuffle_en) begin // gs mode + if (masking_en_ctrl) + buf_wrptr <= buf_wrptr_reg_d1; //1 cycle extra delay for shuffling+masking case + else + buf_wrptr <= mlkem ? buf_wrptr_reg[INTT_WRBUF_LATENCY-MLKEM_INTT_WRBUF_LATENCY] : buf_wrptr_reg[0]; + + end +end + +always_comb begin + last_rd_addr = (mem_rd_addr == mem_rd_base_addr + MEM_LAST_ADDR); + last_wr_addr = (mem_wr_addr == mem_wr_base_addr + MEM_LAST_ADDR); + buf_rdptr_int = (shuffle_en & ct_mode) ? index_rand_offset + buf_count : buf_count; //TODO: flop? + buf_rdptr = (shuffle_en & ct_mode) ? buf_rdptr_f : buf_count; + latch_chunk_rand_offset = arc_IDLE_WR_STAGE | arc_WR_MEM_WR_STAGE | arc_WR_WAIT_WR_STAGE; + latch_index_rand_offset = ct_mode ? (buf_wrptr == 'h3) : (gs_mode | (pwo_mode & incr_pw_rd_addr)) & (arc_RD_STAGE_RD_EXEC | (index_count == 'h3)); + mem_rd_index_ofst = (pwo_mode | gs_mode) ? (index_count + index_rand_offset) : 'h0; + masked_pwm_exec_in_progress = masking_en & (pwm_mode | pairwm_mode) & ~((read_fsm_state_ps inside {RD_IDLE, RD_STAGE}) & (write_fsm_state_ps inside {WR_IDLE, WR_STAGE})); +end + + +//------------------------------------------ +//NTT/INTT Read FSM +//------------------------------------------ +always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) + read_fsm_state_ps <= RD_IDLE; + else if (zeroize) + read_fsm_state_ps <= RD_IDLE; + else + read_fsm_state_ps <= read_fsm_state_ns; +end + +//Arc assignments +always_comb begin + //Start NTT/INTT op when fsm is in IDLE state and there's an enable coming in + arc_IDLE_RD_STAGE = (read_fsm_state_ps == RD_IDLE) && ntt_enable ; //FSM will not enter IDLE state until entire NTT/INTT is done, so we will not accept any new commands + //For these two arcs, perf can be possibly optimized: + //When fsm comes back to stage, reads are done, butterfly is executing the last 10 inputs + //write fsm needs to write last 10 outputs to memory + //If we let read fsm to advance to next round, there is a latency of 4 cycles (from buffer) + 10 cycles (from butterfly) + //before the output is written back to memory. This is best case (no bubbles) + //In this case, there is time for butterfly to produce output while the writes from previous round finish + //TODO: review this assumption. For now, assuming we wait until entire round on both read and write side is done + + //Check to make sure all writes from prev round have finished before moving onto next round in read fsm + arc_RD_STAGE_RD_BUF = (read_fsm_state_ps == RD_STAGE) && (write_fsm_state_ps == WR_STAGE) && (ct_mode && !ntt_done); + arc_RD_STAGE_RD_EXEC = (read_fsm_state_ps == RD_STAGE) && (write_fsm_state_ps == WR_STAGE) && (((gs_mode) && !intt_done) || (pwo_mode && (!pwo_done))); + + //Don't wait for writes to complete before transitioning to next round. (See above TODO) + arc_RD_STAGE_RD_EXEC_OPT= (read_fsm_state_ps == RD_STAGE) && ((gs_mode && !intt_done) || (pwo_mode && (!pwo_done))); + + //This arc is only for ct mode. When buffer is valid, bf2x2 can be enabled + arc_RD_BUF_RD_EXEC = (read_fsm_state_ps == RD_BUF ) && buf0_valid; + + //This arc is only for ct mode. If there's no buf0_valid, all 4 buffers have been emptied and total valid_count is < 64, go back to buf state and wait for it to fill up + //Indicates that buf0, 1, 2 3 have finished executing and there's no valid input, so wait for buf to fill up again + //Since there's an input buffer, valid_count is counted in steps of 4, so it ends at 64 + arc_RD_EXEC_RD_BUF = (read_fsm_state_ps == RD_EXEC ) && ct_mode && (!buf0_valid && (buf_count == 0)) && (rd_valid_count < 'h40); + + //This arc is only for gs/pwo mode. Execution is done when all 63 addr locations have been read. Since there's no input buffer, valid_count ends at 63. + // arc_RD_EXEC_RD_STAGE = (read_fsm_state_ps == RD_EXEC ) && ((gs_mode || pwo_mode || pwm_intt_mode) && (rd_valid_count == 'h3f)); + arc_RD_EXEC_RD_STAGE = (read_fsm_state_ps == RD_EXEC) & (((gs_mode) & (rd_valid_count == 'h3f)) | ((pwo_mode) & (rd_valid_count >= 'h3f))); //>= 3f to ensure we don't miss sampler_valid pulses or if non-sampler mode, we don't do an extra read + + //All rounds of NTT or INTT are done. Go to IDLE and wait for next command. In PWO mode, if ntt_enable is given, start next op + arc_RD_STAGE_IDLE = (read_fsm_state_ps == RD_STAGE) && (ntt_done || intt_done || (pwo_done && !ntt_enable)); + + //This arc is only for ct mode/pwo mode with sampler. Move to EXEC_WAIT state when the last read is done. No more reads to perform, but the buffer needs to be emptied + arc_RD_EXEC_EXEC_WAIT = (read_fsm_state_ps == RD_EXEC ) && ((ct_mode && (((buf_count == 'h3) && (rd_valid_count == 'h3c)))) || ((pwo_mode && !sampler_valid) && (rd_valid_count < 'h40))); + + //This arc is only for pwo mode. Move back to RD_EXEC when sampler_valid is available + arc_EXEC_WAIT_RD_EXEC = (read_fsm_state_ps == EXEC_WAIT) && (pwo_mode && sampler_valid && (rd_valid_count < 'h40)); + + //This arc is only for ct mode. When valid_count is 64 and buf_count is 3 (meaning all 4 buffers have been used), move to RD_STAGE indicating that round is done + arc_EXEC_WAIT_RD_STAGE = (read_fsm_state_ps == EXEC_WAIT) && (rd_valid_count == 'h40) && (buf_count == 'h3); +end + +always_comb begin + read_fsm_state_ns = read_fsm_state_ps; + buf_wren_ntt = 1'b0; + buf_rden_ntt = 1'b0; + incr_mem_rd_addr = 1'b0; + bf_enable_fsm = 1'b0; + mem_rd_en_fsm = 1'b0; + incr_twiddle_addr_fsm = 1'b0; + rd_addr_step = 'h0; + rst_rd_addr = 1'b0; + rst_rd_valid_count = 1'b0; + buf_wr_rst_count_ntt = 1'b0; + buf_rd_rst_count_ntt = 1'b0; + rst_twiddle_addr = 1'b0; + incr_pw_rd_addr = 1'b0; + pw_rden_fsm = 1'b0; + unique case(read_fsm_state_ps) + RD_IDLE: begin + read_fsm_state_ns = arc_IDLE_RD_STAGE ? RD_STAGE : RD_IDLE; + rst_rd_addr = 1'b1; + rst_rd_valid_count = 1'b1; + buf_wr_rst_count_ntt = 1'b1; + buf_rd_rst_count_ntt = 1'b1; + rst_twiddle_addr = 1'b1; + end + RD_STAGE: begin + read_fsm_state_ns = arc_RD_STAGE_RD_BUF ? RD_BUF : + arc_RD_STAGE_RD_EXEC ? RD_EXEC : + arc_RD_STAGE_IDLE ? RD_IDLE : RD_STAGE; + rst_rd_addr = 1'b1; + rst_rd_valid_count = 1'b1; + //reset if in ntt mode, since writes won't use the buffer, it's safe to reset buffer + buf_wr_rst_count_ntt = ct_mode; + buf_rd_rst_count_ntt = ct_mode; + rst_twiddle_addr = !butterfly_ready; + end + RD_BUF: begin + read_fsm_state_ns = arc_RD_BUF_RD_EXEC ? RD_EXEC : RD_BUF; + buf_wren_ntt = 1'b1; + buf_rden_ntt = buf0_valid; + incr_mem_rd_addr = 1'b1; + mem_rd_en_fsm = 1'b1; + bf_enable_fsm = buf0_valid; //Enable bf2x2 as soon as buf is valid + incr_twiddle_addr_fsm = buf0_valid; + rd_addr_step = NTT_READ_ADDR_STEP; + end + RD_EXEC: begin + read_fsm_state_ns = arc_RD_EXEC_RD_BUF ? RD_BUF : + arc_RD_EXEC_EXEC_WAIT ? EXEC_WAIT : + arc_RD_EXEC_RD_STAGE ? RD_STAGE : RD_EXEC; + buf_wren_ntt = ct_mode; + buf_rden_ntt = ct_mode; + incr_mem_rd_addr = (ntt_mode inside {ct, gs}); + mem_rd_en_fsm = (ntt_mode inside {ct, gs}) ? (mem_rd_addr <= MEM_LAST_ADDR + mem_rd_base_addr) & ~arc_RD_EXEC_EXEC_WAIT : 1'b0; + bf_enable_fsm = pwo_mode ? sampler_valid : 1'b1; + incr_twiddle_addr_fsm = (ntt_mode inside {ct, gs}) | (sampler_valid & pairwm_mode); + rd_addr_step = ct_mode ? NTT_READ_ADDR_STEP : INTT_READ_ADDR_STEP; + incr_pw_rd_addr = sampler_valid & pwo_mode; + pw_rden_fsm = sampler_valid & pwo_mode; + end + EXEC_WAIT: begin + read_fsm_state_ns = arc_EXEC_WAIT_RD_STAGE ? RD_STAGE : arc_EXEC_WAIT_RD_EXEC ? RD_EXEC : EXEC_WAIT; + buf_wren_ntt = (buf_count < 3) && !pwo_mode; + buf_rden_ntt = !pwo_mode; + buf_wr_rst_count_ntt = 1'b1; //There are no more mem reads, so buf writes need to halt + buf_rd_rst_count_ntt = 1'b0; //There are still some entries in buf that BF2x2 needs to pick up + bf_enable_fsm = pwo_mode ? sampler_valid : (buf_count <= 3); + incr_twiddle_addr_fsm = (ct_mode | gs_mode | (pairwm_mode & sampler_valid)); + rd_addr_step = NTT_READ_ADDR_STEP; + incr_pw_rd_addr = (pwo_mode & sampler_valid); + pw_rden_fsm = (pwo_mode & sampler_valid); + end + default: begin + read_fsm_state_ns = RD_IDLE; + end + endcase +end + +//------------------------------------------ +//NTT/INTT Write FSM +//------------------------------------------ +always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) + write_fsm_state_ps <= WR_IDLE; + else if (zeroize) + write_fsm_state_ps <= WR_IDLE; + else + write_fsm_state_ps <= write_fsm_state_ns; +end + +//Arc assignments +always_comb begin + //Start NTT/INTT op when fsm is in IDLE state and there's an enable coming in + arc_IDLE_WR_STAGE = (write_fsm_state_ps == WR_IDLE) && ntt_enable ; + + if (shuffle_en) begin + //This arc is only for ct mode. No buffer in the path, so wait for all addr to be written (0-63) before transitioning to WR_STAGE + arc_WR_MEM_WR_STAGE = (write_fsm_state_ps == WR_MEM) && ((ct_mode) && (wr_valid_count == 'h3f)); //(mem_wr_addr == (mem_wr_base_addr + MEM_LAST_ADDR)); //this arc is for ct mode, + + //This arc is only for ct mode since there's no output buffer + arc_WR_STAGE_WR_MEM = (write_fsm_state_ps == WR_STAGE) && ((ct_mode && !ntt_done) || (pwo_mode && !pwo_done)); + end + else begin + arc_WR_MEM_WR_STAGE = (write_fsm_state_ps == WR_MEM) & ((ct_mode & (wr_valid_count == 'h3f)) | (pwo_mode & (wr_valid_count == 'h40))); + arc_WR_STAGE_WR_MEM = (write_fsm_state_ps == WR_STAGE) && (ct_mode && !ntt_done); + end + + //All rounds of NTT or INTT are done. Go to IDLE and wait for next command + arc_WR_STAGE_IDLE = (write_fsm_state_ps == WR_STAGE) && (ntt_done || intt_done || pwo_done); + + //pwm arc. If in WR_STAGE, read fsm is executing, go back to WR_MEM state to perform current round's writes + arc_WR_STAGE_WR_MEM_OPT = (write_fsm_state_ps == WR_STAGE) && (read_fsm_state_ps == RD_EXEC) && (pwo_mode && pwo_busy); + + //This arc is only for gs mode + arc_WR_STAGE_WR_BUF = (write_fsm_state_ps == WR_STAGE) && gs_mode && !intt_done; + + //pwm arc. If in WR STAGE, transition directly to wait + arc_WR_STAGE_WR_WAIT = (write_fsm_state_ps == WR_STAGE) && (pwo_mode && !pwo_done); + + //This arc is only for gs mode. Start writing to memory when buf0_valid is asserted + arc_WR_BUF_WR_MEM = (write_fsm_state_ps == WR_BUF) && (gs_mode && buf0_valid); + + //This arc is only for gs mode. If there's no buf0_valid, all 4 buffers have been emptied and total valid_count is < 64, go back to buf state and wait for it to fill up + //Indicates that buf0, 1, 2 3 have finished executing and there's no valid input, so wait for buf to fill up again + //Since there's an output buffer, valid_count is counted in steps of 4, so it ends at 64 + arc_WR_MEM_WR_BUF = (write_fsm_state_ps == WR_MEM) && (gs_mode && (!buf0_valid && (buf_count == 0)) && (wr_valid_count < 'h40)); + + //Move to WR_WAIT state when the last outputs from bf2x2 have been captured in the buffers. They still need to be shifted out of the buffers and into memory, so keep buf_wren 1 here + //Assumption - no bubbles in NTT or INTT. If bubbles, need to consider sampler_valid + //TODO: can WR_WAIT state be removed? fsm can finish all 64 addr in WR_MEM state? + arc_WR_MEM_WR_WAIT = shuffle_en ? (write_fsm_state_ps == WR_MEM) && ((gs_mode && (buf0_valid && (wr_valid_count == 'h3c))) || (pwo_mode && butterfly_ready && (wr_valid_count == 'h3f))) + : (write_fsm_state_ps == WR_MEM) && ((gs_mode && (buf0_valid && (wr_valid_count == 'h3c))) || (pwo_mode && !butterfly_ready && (wr_valid_count < 'h40))); // || (ct_mode && (wr_valid_count == 'h3f))); + + //This arc is only for pwo mode. Move back from wait to write state when there's a valid BFU output + arc_WR_WAIT_WR_MEM = (write_fsm_state_ps == WR_WAIT) && (pwo_mode && butterfly_ready); + + //When valid_count is 64 and buf_count is 3 (meaning all 4 buffers have been used), move to WR_STAGE indicating that round is done + arc_WR_WAIT_WR_STAGE = shuffle_en ? (write_fsm_state_ps == WR_WAIT) && ((gs_mode && (buf_count == 'h3)) || ct_mode || pwo_mode) + : (write_fsm_state_ps == WR_WAIT) && (!pwo_mode && (buf_count == 'h3)); +end + +always_comb begin + write_fsm_state_ns = write_fsm_state_ps; + buf_wren_intt = 1'b0; + buf_rden_intt = 1'b0; + incr_mem_wr_addr = 1'b0; + mem_wr_en_fsm = 1'b0; + wr_addr_step = 'h0; + rst_wr_addr = 1'b0; + rst_wr_valid_count = 1'b0; + buf_wr_rst_count_intt = 1'b0; + buf_rd_rst_count_intt = 1'b0; + incr_pw_wr_addr = 1'b0; + pw_wren_fsm = 1'b0; + rst_pw_addr = 1'b0; + unique case(write_fsm_state_ps) + WR_IDLE: begin + write_fsm_state_ns = arc_IDLE_WR_STAGE ? WR_STAGE : WR_IDLE; + rst_wr_addr = 1'b1; + rst_wr_valid_count = 1'b1; + rst_pw_addr = 1'b1; + end + WR_STAGE: begin + if (shuffle_en) + write_fsm_state_ns = arc_WR_STAGE_WR_MEM ? WR_MEM : + arc_WR_STAGE_WR_BUF ? WR_BUF : + // arc_WR_STAGE_WR_WAIT? WR_WAIT : + arc_WR_STAGE_IDLE ? WR_IDLE : WR_STAGE; + else + write_fsm_state_ns = arc_WR_STAGE_WR_MEM ? WR_MEM : + arc_WR_STAGE_WR_BUF ? WR_BUF : + arc_WR_STAGE_WR_WAIT? WR_WAIT : + arc_WR_STAGE_IDLE ? WR_IDLE : WR_STAGE; + rst_wr_addr = 1'b1; + rst_wr_valid_count = 1'b1; + buf_wr_rst_count_intt = gs_mode; + buf_rd_rst_count_intt = gs_mode; + rst_pw_addr = pwo_mode; + end + WR_BUF: begin + write_fsm_state_ns = arc_WR_BUF_WR_MEM ? WR_MEM : WR_BUF; + buf_wren_intt = butterfly_ready; + buf_rden_intt = buf0_valid; + incr_mem_wr_addr = buf0_valid; + mem_wr_en_fsm = buf0_valid; + wr_addr_step = INTT_WRITE_ADDR_STEP; + end + WR_MEM: begin + write_fsm_state_ns = arc_WR_MEM_WR_BUF ? WR_BUF : + arc_WR_MEM_WR_STAGE ? WR_STAGE : + arc_WR_MEM_WR_WAIT ? WR_WAIT : WR_MEM; + buf_wren_intt = gs_mode; + buf_rden_intt = gs_mode; + incr_mem_wr_addr = ct_mode ? butterfly_ready : gs_mode ? 1'b1 : 1'b0; + mem_wr_en_fsm = ct_mode ? butterfly_ready : gs_mode ? 1'b1 : 1'b0; + wr_addr_step = ct_mode ? NTT_WRITE_ADDR_STEP : INTT_WRITE_ADDR_STEP; + incr_pw_wr_addr = pwo_mode & butterfly_ready; + pw_wren_fsm = pwo_mode & butterfly_ready; + end + WR_WAIT: begin + if (shuffle_en) begin + write_fsm_state_ns = arc_WR_WAIT_WR_STAGE ? WR_STAGE : WR_WAIT; + wr_addr_step = gs_mode ? INTT_WRITE_ADDR_STEP : NTT_WRITE_ADDR_STEP; + end + else begin + write_fsm_state_ns = arc_WR_WAIT_WR_STAGE ? WR_STAGE : arc_WR_WAIT_WR_MEM ? WR_MEM : WR_WAIT; + wr_addr_step = INTT_WRITE_ADDR_STEP; + end + buf_wren_intt = shuffle_en ? 'b0 : (buf_count <= 'h3); + buf_rden_intt = shuffle_en ? gs_mode : 'b1; + incr_mem_wr_addr = (ct_mode | gs_mode); + mem_wr_en_fsm = shuffle_en ? gs_mode : (ct_mode | gs_mode); + + incr_pw_wr_addr = shuffle_en ? pwo_mode & arc_WR_WAIT_WR_STAGE : arc_WR_WAIT_WR_MEM; + pw_wren_fsm = shuffle_en ? 'b0 : arc_WR_WAIT_WR_MEM; + end + default: begin + write_fsm_state_ns = WR_IDLE; + end + endcase +end + +always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) + twiddle_addr_sampler_mode <= '0; + else if (zeroize) + twiddle_addr_sampler_mode <= '0; + else if (sampler_valid) + twiddle_addr_sampler_mode <= twiddle_addr_int; +end + +always_comb begin + rst_rounds = (read_fsm_state_ps == RD_IDLE) && (write_fsm_state_ps == WR_IDLE); + incr_rounds = arc_WR_MEM_WR_STAGE | arc_WR_WAIT_WR_STAGE; //TODO: revisit for high-perf mode (if we go with above opt) + if (shuffle_en) begin + buf_wren = pwo_mode ? 1'b0 : buf_wren_ntt_reg | buf_wren_intt_reg; + buf_rden = pwo_mode ? 1'b0 : ct_mode ? buf_rden_ntt_reg : buf_rden_intt; + mem_wr_en = gs_mode ? mem_wr_en_fsm : mem_wr_en_reg; + mem_rd_en = gs_mode ? mem_rd_en_reg : mem_rd_en_fsm; + twiddle_addr = (gs_mode | pairwm_mode) ? twiddle_addr_reg_d3 : twiddle_addr_int; + pw_rden = pw_rden_reg; + pw_share_mem_rden= accumulate ? masking_en ? mlkem ? pw_rden_fsm_reg[MASKED_PWM_LATENCY-(MLKEM_MASKED_PAIRWM_LATENCY-6+1)] : shuffled_pw_rden_fsm_reg : pw_rden_reg : '0; + pw_wren = pw_wren_reg; + end + else begin + buf_wren = pwo_mode ? 1'b0 : buf_wren_ntt_reg | buf_wren_intt; + buf_rden = pwo_mode ? 1'b0 : buf_rden_ntt | buf_rden_intt; + mem_wr_en = mem_wr_en_fsm; + mem_rd_en = mem_rd_en_fsm; + twiddle_addr = twiddle_addr_int; + pw_rden = pw_rden_fsm; + pw_share_mem_rden = accumulate ? masking_en ? mlkem ? pw_rden_fsm_reg[MASKED_PWM_LATENCY-(MLKEM_MASKED_PAIRWM_LATENCY-6+1)] : pw_rden_fsm_reg[0] : pw_rden_fsm : '0; //-6 to remove reduction latency since reduction happens at the end + pw_wren = pw_wren_fsm; + end +end +always_comb begin + + if(shuffle_en & ~masking_en) begin //only shuffling + case(ntt_mode) + ct: bf_enable = bf_enable_reg[0]; + gs: bf_enable = bf_enable_reg[1]; + pwm:bf_enable = bf_enable_reg[1]; + pwa:bf_enable = bf_enable_reg[1]; + pws:bf_enable = bf_enable_reg[1]; + pairwm: bf_enable = bf_enable_reg[1]; + default: bf_enable = 0; + endcase + end + else if (shuffle_en & masking_en) begin //both + case(ntt_mode) + ct: bf_enable = 0; + gs: bf_enable = bf_enable_reg[1]; + pwm:bf_enable = bf_enable_reg[2]; + pwa:bf_enable = 0; + pws:bf_enable = 0; + pairwm: bf_enable = bf_enable_reg[2]; + default: bf_enable = 0; + endcase + end + else if (~shuffle_en & masking_en) begin //only masking + case(ntt_mode) + ct: bf_enable = 0; + gs: bf_enable = bf_enable_reg[0]; + pwm:bf_enable = bf_enable_reg[0]; + pwa:bf_enable = 0; + pws:bf_enable = 0; + pairwm: bf_enable = bf_enable_reg[0]; + default: bf_enable = 0; + endcase + end + else begin //none + case(ntt_mode) + ct: bf_enable = bf_enable_fsm; + gs: bf_enable = bf_enable_reg[0]; + pwm:bf_enable = bf_enable_reg[0]; + pwa:bf_enable = bf_enable_reg[0]; + pws:bf_enable = bf_enable_reg[0]; + pairwm: bf_enable = bf_enable_reg[0]; + default: bf_enable = 0; + endcase + end + + buf_wr_rst_count = pwo_mode ? 1'b1 : buf_wr_rst_count_ntt | buf_wr_rst_count_intt; + buf_rd_rst_count = pwo_mode ? 1'b1 : buf_rd_rst_count_ntt | buf_rd_rst_count_intt; + + +end + +always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) begin + pw_rden_fsm_reg <= '0; + pw_wren_fsm_reg <= '0; + shuffled_pw_rden_fsm_reg <= '0; + end + else if (zeroize) begin + pw_rden_fsm_reg <= '0; + pw_wren_fsm_reg <= '0; + shuffled_pw_rden_fsm_reg <= '0; + end + else begin + pw_rden_fsm_reg <= {pw_rden_fsm, pw_rden_fsm_reg[MASKED_PWM_LATENCY:1]}; + pw_wren_fsm_reg <= pw_wren_fsm; + shuffled_pw_rden_fsm_reg <= mlkem ? pw_rden_fsm_reg[MASKED_PWM_LATENCY-(MLKEM_MASKED_PAIRWM_LATENCY-6+1)] : pw_rden_fsm_reg[0]; + end +end + +always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) begin + buf_wren_ntt_reg <= 'b0; + buf_wren_intt_reg <= 'b0; + buf_rden_ntt_reg <= 'b0; + bf_enable_reg <= '0; + mem_wr_en_reg <= 'b0; + mem_rd_en_reg <= 'b0; + twiddle_addr_reg_d2 <= 'h0; + twiddle_addr_reg_d3 <= 'h0; + twiddle_addr_sampler_mode_d2 <= '0; + twiddle_addr_sampler_mode_d3 <= '0; + pw_rden_reg <= '0; + pw_wren_reg <= '0; + + index_count_reg <= '0; + index_rand_offset_reg <= '0; + end + else if (zeroize) begin + buf_wren_ntt_reg <= 'b0; + buf_wren_intt_reg <= 'b0; + buf_rden_ntt_reg <= 'b0; + bf_enable_reg <= '0; + mem_wr_en_reg <= 'b0; + mem_rd_en_reg <= 'b0; + twiddle_addr_reg_d2 <= 'h0; + twiddle_addr_reg_d3 <= 'h0; + twiddle_addr_sampler_mode_d2 <= '0; + twiddle_addr_sampler_mode_d3 <= '0; + pw_rden_reg <= '0; + pw_wren_reg <= '0; + + index_count_reg <= '0; + index_rand_offset_reg <= '0; + end + else begin + buf_wren_ntt_reg <= buf_wren_ntt; + buf_wren_intt_reg <= buf_wren_intt; + buf_rden_ntt_reg <= buf_rden_ntt; + bf_enable_reg <= {bf_enable_reg[1:0], bf_enable_fsm}; + mem_wr_en_reg <= mem_wr_en_fsm; + mem_rd_en_reg <= mem_rd_en_fsm; + twiddle_addr_reg_d2 <= twiddle_addr_int; + twiddle_addr_reg_d3 <= twiddle_addr_reg_d2; + twiddle_addr_sampler_mode_d2 <= twiddle_addr_sampler_mode; + twiddle_addr_sampler_mode_d3 <= twiddle_addr_sampler_mode_d2; + pw_rden_reg <= pw_rden_fsm; + pw_wren_reg <= pw_wren_fsm; + + index_count_reg <= {index_count_reg[1:0], index_count}; + index_rand_offset_reg <= {index_rand_offset_reg[1:0], index_rand_offset}; + end +end + + + +//TODO: add assertions for: +//1. buf_wren_ntt and buf_wren_intt should be mutex + +endmodule diff --git a/designs/Caliptra/src/adams-bridge/ntt_defines_pkg.sv b/designs/Caliptra/src/adams-bridge/ntt_defines_pkg.sv new file mode 100644 index 0000000..4790237 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/ntt_defines_pkg.sv @@ -0,0 +1,260 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +//====================================================================== +// +// ntt_defines_pkg.sv +// -------- +// NTT interface parameters for the digital signature algorithm (DSA). +// +// +//====================================================================== + +`ifndef MLDSA_NTT_DEFINES +`define MLDSA_NTT_DEFINES + +package ntt_defines_pkg; + import abr_params_pkg::*; + +// `define MLDSA_MASKING + +// `define MLDSA_MASKING + +parameter NTT_REG_SIZE = REG_SIZE-1; +parameter MASKED_WIDTH = 46; +parameter MLKEM_MASKED_WIDTH = 2 * MLKEM_Q_WIDTH; +// parameter MEM_DEPTH = 2**ABR_MEM_ADDR_WIDTH; + +//---------------------- +//Latency params for NTT +//---------------------- +parameter INTT_WRBUF_LATENCY = 13; +parameter UNMASKED_BF_LATENCY = 10; //5 cycles per butterfly * 2 instances in serial = 10 clks +parameter UNMASKED_PWM_LATENCY = 5; //latency of modular multiplier + modular addition to perform accumulation +parameter UNMASKED_PWA_LATENCY = 1; //latency of modular addition +parameter UNMASKED_PWS_LATENCY = 1; //latency of modular subtraction +parameter UNMASKED_BF_STAGE1_LATENCY = UNMASKED_BF_LATENCY/2; + +parameter MASKED_ADD_SUB_LATENCY = 53; //For 1 masked add/sub operation +parameter MASKED_PWM_LATENCY = 211; //For 1 masked pwm operation +parameter MASKED_PWM_ACC_LATENCY = MASKED_PWM_LATENCY + MASKED_ADD_SUB_LATENCY; //For 1 masked pwm + accumulate operation +parameter MASKED_BF_STAGE1_LATENCY = 266; //For 1 masked butterfly operation +parameter MASKED_PWM_MASKED_INTT_LATENCY = MASKED_PWM_LATENCY + MASKED_BF_STAGE1_LATENCY; //PWM+stage1 INTT latency +parameter MASKED_INTT_LATENCY = MASKED_BF_STAGE1_LATENCY + UNMASKED_BF_STAGE1_LATENCY; //masked INTT latency +parameter MASKED_PWM_INTT_LATENCY = MASKED_PWM_LATENCY + MASKED_INTT_LATENCY + 1; //TODO: adjust for PWMA case. Adding 1 cyc as a placeholder for it +parameter MASKED_INTT_WRBUF_LATENCY = /*MASKED_PWM_LATENCY +*/ MASKED_INTT_LATENCY + 3; //masked PWM+INTT latency + mem latency for shuffled reads to begin (does not include PWMA case) + +//---------------------- +//Latency params for MLKEM NTT +//---------------------- +parameter MLKEM_UNMASKED_PWA_LATENCY = 1; +parameter MLKEM_UNMASKED_PWS_LATENCY = 1; +parameter MLKEM_INTT_WRBUF_LATENCY = 9; +parameter MLKEM_UNMASKED_PAIRWM_ACC_LATENCY = 5; +parameter MLKEM_UNMASKED_PAIRWM_LATENCY = 4; +parameter MLKEM_UNMASKED_BF_STAGE1_LATENCY = 3; +parameter MLKEM_UNMASKED_BF_LATENCY = MLKEM_UNMASKED_BF_STAGE1_LATENCY * 2; + +parameter MLKEM_BARRETT_REDUCTION_LATENCY = 6; //latency of barrett reduction +parameter MLKEM_MASKED_PAIRWM_LATENCY = 8+8+1+MLKEM_BARRETT_REDUCTION_LATENCY; +parameter MLKEM_MASKED_PAIRWM_ACC_LATENCY = MLKEM_MASKED_PAIRWM_LATENCY + 1; +parameter MLKEM_MASKED_MULT_LATENCY = 2 + 6; //23; //2 for two-share mult, /*23*/6 for masked barrett reduction +parameter MLKEM_MASKED_ADD_SUB_LATENCY = 1+6; //internal flops + A2B + B2A conv +parameter MLKEM_MASKED_BF_STAGE1_LATENCY = 16; +parameter MLKEM_MASKED_INTT_LATENCY = MLKEM_MASKED_BF_STAGE1_LATENCY+1; //+1 for input flop //+ MLKEM_UNMASKED_BF_STAGE1_LATENCY; //masked INTT latency - in MLKEM, passthrough is applicable for masked layer, so no need for unmasked latency +parameter MLKEM_MASKED_INTT_WRBUF_LATENCY = MLKEM_MASKED_INTT_LATENCY + 3; //masked INTT latency + mem latency for shuffled reads to begin +// typedef enum logic [2:0] {ct, gs, pwm, pwa, pws} mode_t; +//TODO: tb has issue with enums in top level ports. For now, using this workaround +//Need to try something like bundling enable and mode into a struct to support enum. +localparam ct =3'd0, + gs =3'd1, + pwm=3'd2, + pwa=3'd3, + pws=3'd4, + pairwm = 3'd5; + +typedef logic [2:0] mode_t; + +//NTT ports +typedef struct packed { + logic [NTT_REG_SIZE-1:0] u00_i; + logic [NTT_REG_SIZE-1:0] u01_i; + logic [NTT_REG_SIZE-1:0] v00_i; + logic [NTT_REG_SIZE-1:0] v01_i; + logic [NTT_REG_SIZE-1:0] w00_i; + logic [NTT_REG_SIZE-1:0] w01_i; + logic [NTT_REG_SIZE-1:0] w10_i; + logic [NTT_REG_SIZE-1:0] w11_i; +} bf_uvwi_t; + +typedef struct packed { + //input a + logic [NTT_REG_SIZE-1:0] u0_i; + logic [NTT_REG_SIZE-1:0] u1_i; + logic [NTT_REG_SIZE-1:0] u2_i; + logic [NTT_REG_SIZE-1:0] u3_i; + //input b + logic [NTT_REG_SIZE-1:0] v0_i; + logic [NTT_REG_SIZE-1:0] v1_i; + logic [NTT_REG_SIZE-1:0] v2_i; + logic [NTT_REG_SIZE-1:0] v3_i; + //accumulated input c (comes from dest mem) + logic [NTT_REG_SIZE-1:0] w0_i; + logic [NTT_REG_SIZE-1:0] w1_i; + logic [NTT_REG_SIZE-1:0] w2_i; + logic [NTT_REG_SIZE-1:0] w3_i; + //input w for INTT operation that follows pwm. TODO: for only PWM/PWMA ops, this needs to be 0 + logic [NTT_REG_SIZE-1:0] twiddle_w0_i; + logic [NTT_REG_SIZE-1:0] twiddle_w1_i; + logic [NTT_REG_SIZE-1:0] twiddle_w2_i; + logic [NTT_REG_SIZE-1:0] twiddle_w3_i; +} hybrid_bf_uvwi_t; + +typedef struct packed { + logic [NTT_REG_SIZE-1:0] u20_o; + logic [NTT_REG_SIZE-1:0] u21_o; + logic [NTT_REG_SIZE-1:0] v20_o; + logic [NTT_REG_SIZE-1:0] v21_o; +} bf_uvo_t; + +typedef struct packed { + logic [1:0][MASKED_WIDTH-1:0] u00_i; + logic [1:0][MASKED_WIDTH-1:0] u01_i; + logic [1:0][MASKED_WIDTH-1:0] v00_i; + logic [1:0][MASKED_WIDTH-1:0] v01_i; + logic [1:0][MASKED_WIDTH-1:0] w00_i; + logic [1:0][MASKED_WIDTH-1:0] w01_i; +} masked_bf_uvwi_t; //Only used in MLDSA masked INTT stage 1 + +typedef struct packed { + logic [1:0][MLKEM_MASKED_WIDTH-1:0] u00_i; + logic [1:0][MLKEM_MASKED_WIDTH-1:0] u01_i; + logic [1:0][MLKEM_MASKED_WIDTH-1:0] v00_i; + logic [1:0][MLKEM_MASKED_WIDTH-1:0] v01_i; + logic [1:0][MLKEM_MASKED_WIDTH-1:0] w00_i; + logic [1:0][MLKEM_MASKED_WIDTH-1:0] w01_i; +} mlkem_masked_bf_uvwi_t; //Only used in MLKEM masked INTT stage 1 + +typedef struct packed { + logic [1:0][MASKED_WIDTH-1:0] u00_i; + logic [1:0][MASKED_WIDTH-1:0] u01_i; + logic [1:0][MASKED_WIDTH-1:0] v00_i; + logic [1:0][MASKED_WIDTH-1:0] v01_i; + logic [1:0][MASKED_WIDTH-1:0] w00_i; + logic [1:0][MASKED_WIDTH-1:0] w01_i; + logic [NTT_REG_SIZE-1:0] w10_i; + logic [NTT_REG_SIZE-1:0] w11_i; +} masked_intt_uvwi_t; //Only used in MLDSA masked INTT + +typedef struct packed { + logic [ABR_MEM_ADDR_WIDTH-1:0] src_base_addr; + logic [ABR_MEM_ADDR_WIDTH-1:0] interim_base_addr; + logic [ABR_MEM_ADDR_WIDTH-1:0] dest_base_addr; +} ntt_mem_addr_t; + +typedef struct packed { + logic [ABR_MEM_ADDR_WIDTH-1:0] pw_base_addr_a; + logic [ABR_MEM_ADDR_WIDTH-1:0] pw_base_addr_b; + logic [ABR_MEM_ADDR_WIDTH-1:0] pw_base_addr_c; +} pwo_mem_addr_t; + +//PWO ports +typedef struct packed { + //input a + logic [NTT_REG_SIZE-1:0] u0_i; + logic [NTT_REG_SIZE-1:0] u1_i; + logic [NTT_REG_SIZE-1:0] u2_i; + logic [NTT_REG_SIZE-1:0] u3_i; + //input b + logic [NTT_REG_SIZE-1:0] v0_i; + logic [NTT_REG_SIZE-1:0] v1_i; + logic [NTT_REG_SIZE-1:0] v2_i; + logic [NTT_REG_SIZE-1:0] v3_i; + //accumulated input c (comes from dest mem) + logic [NTT_REG_SIZE-1:0] w0_i; + logic [NTT_REG_SIZE-1:0] w1_i; + logic [NTT_REG_SIZE-1:0] w2_i; + logic [NTT_REG_SIZE-1:0] w3_i; +} pwo_uvwi_t; + +typedef struct packed { + //input a + logic [1:0][MASKED_WIDTH-1:0] u0_i; + logic [1:0][MASKED_WIDTH-1:0] u1_i; + logic [1:0][MASKED_WIDTH-1:0] u2_i; + logic [1:0][MASKED_WIDTH-1:0] u3_i; + //input b + logic [1:0][MASKED_WIDTH-1:0] v0_i; + logic [1:0][MASKED_WIDTH-1:0] v1_i; + logic [1:0][MASKED_WIDTH-1:0] v2_i; + logic [1:0][MASKED_WIDTH-1:0] v3_i; + //accumulated input c (comes from dest mem) + logic [1:0][MASKED_WIDTH-1:0] w0_i; + logic [1:0][MASKED_WIDTH-1:0] w1_i; + logic [1:0][MASKED_WIDTH-1:0] w2_i; + logic [1:0][MASKED_WIDTH-1:0] w3_i; +} pwm_shares_uvwi_t; + +typedef struct packed { + logic [NTT_REG_SIZE-1:0] uv0; + logic [NTT_REG_SIZE-1:0] uv1; + logic [NTT_REG_SIZE-1:0] uv2; + logic [NTT_REG_SIZE-1:0] uv3; +} pwo_t; + +typedef struct packed { + //input a + logic [MLKEM_REG_SIZE-1:0] u0_i; + logic [MLKEM_REG_SIZE-1:0] u1_i; + //input b + logic [MLKEM_REG_SIZE-1:0] v0_i; + logic [MLKEM_REG_SIZE-1:0] v1_i; + //accumulated input c (comes from dest mem) + logic [MLKEM_REG_SIZE-1:0] w0_i; + logic [MLKEM_REG_SIZE-1:0] w1_i; + //input zeta + // logic [MLKEM_REG_SIZE-1:0] z0_i; + // logic [MLKEM_REG_SIZE-1:0] z1_i; +} mlkem_pwo_uvwzi_t; + +typedef struct packed { + //input zeta + logic [MLKEM_REG_SIZE-1:0] z0_i; + logic [MLKEM_REG_SIZE-1:0] z1_i; +} mlkem_pairwm_zeta_t; + +typedef struct packed { + //input zeta + logic [1:0][MLKEM_MASKED_WIDTH-1:0] z0_i; + logic [1:0][MLKEM_MASKED_WIDTH-1:0] z1_i; +} mlkem_masked_pairwm_zeta_shares_t; + +typedef struct packed { + logic [MLKEM_REG_SIZE-1:0] uv0_o; + logic [MLKEM_REG_SIZE-1:0] uv1_o; +} mlkem_pwo_t; + +typedef struct packed { + //input a + logic [1:0][MASKED_WIDTH-1:0] uv0; + logic [1:0][MASKED_WIDTH-1:0] uv1; + logic [1:0][MASKED_WIDTH-1:0] uv2; + logic [1:0][MASKED_WIDTH-1:0] uv3; +} pwm_shares_uvo_t; + +typedef enum logic [2:0] {RD_IDLE, RD_STAGE, RD_BUF, RD_EXEC, EXEC_WAIT} ntt_read_state_t; +typedef enum logic [2:0] {WR_IDLE, WR_STAGE, WR_BUF, WR_MEM, WR_WAIT} ntt_write_state_t; + +endpackage + +`endif diff --git a/designs/Caliptra/src/adams-bridge/ntt_div2.sv b/designs/Caliptra/src/adams-bridge/ntt_div2.sv new file mode 100644 index 0000000..8bb3529 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/ntt_div2.sv @@ -0,0 +1,39 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +// +//====================================================================== +// +// ntt_div2.sv +// -------- +// This unit performs division by 2 on butterfly outputs +//====================================================================== + +module ntt_div2 + #( + parameter REG_SIZE = 23, + parameter PRIME = 23'd8380417, + parameter PRIME_DIV2_ODD = (PRIME + 1) / 2 + ) + ( + input wire [REG_SIZE-1:0] op_i, + output logic [REG_SIZE-1:0] res_o + ); + + //No need to perform reduction for the addition here. + //If op_i = Q-1 (which is max even value allowed), op_i >> 1 is less than Q. + //If op_i = Q-2 (which is max odd value allowed), (op_i >> 1) + DIITHIUM_Q_DIV2_ODD is also less than Q. + always_comb res_o = op_i[0] ? REG_SIZE'((op_i >> 1) + PRIME_DIV2_ODD) + : REG_SIZE'(op_i >> 1); + +endmodule \ No newline at end of file diff --git a/designs/Caliptra/src/adams-bridge/ntt_hybrid_butterfly_2x2.sv b/designs/Caliptra/src/adams-bridge/ntt_hybrid_butterfly_2x2.sv new file mode 100644 index 0000000..1d5076b --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/ntt_hybrid_butterfly_2x2.sv @@ -0,0 +1,649 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +// +//====================================================================== +// +// ntt_hybrid_noncascade_butterfly_2x2.sv +// -------- +// This module consists of masked PWMs, followed by 1st stage of masked and unmasked BFUs followed by +// 2nd stage of unmasked BFUs. In case of masking_en, PWMs are triggered and +// masked branch is taken for computing 1st stage outputs. In case of unmasked operation, +// both branches are enabled but unmasked outputs are passed to next stage. Final outputs are 23-bit values + +module ntt_hybrid_butterfly_2x2 + import abr_params_pkg::*; + import ntt_defines_pkg::*; +#( + parameter WIDTH = 46, + parameter HALF_WIDTH = WIDTH/2 +) +( + input wire clk, + input wire reset_n, + input wire zeroize, + + input mode_t mode, + input wire enable, + input wire masking_en, + input wire shuffle_en, + input wire mlkem, + input bf_uvwi_t uvw_i, //Inputs are original form + input pwo_uvwi_t pw_uvw_i, //PWO inputs are original form - reuse for MLKEM PairWM + input pwm_shares_uvwi_t pwm_shares_uvw_i, //masked PWM/PairWM inputs + input wire [4:0][WIDTH-1:0] rnd_i, + input wire accumulate, + input masked_intt_uvwi_t bf_shares_uvw_i, //masked INTT inputs + input mlkem_pairwm_zeta_t mlkem_pairwm_zeta13_i, + input mlkem_masked_pairwm_zeta_shares_t mlkem_shares_pairwm_zeta13_i, + input wire ntt_passthrough, + input wire intt_passthrough, + + output bf_uvo_t uv_o, //Outputs are original form + output pwo_t pwo_uv_o, + output pwm_shares_uvo_t pwm_shares_uvo, //masked PWM output + output logic ready_o +); + +//---------------------- +//Unmasked wires +//---------------------- +//Inputs to 1st stage +logic [HALF_WIDTH-1:0] u00, u01, v00, v01; +logic [HALF_WIDTH-1:0] w00, w01, w10, w11; +//Outputs of 1st stage +logic [HALF_WIDTH-1:0] u10_int, u11_int, v10_int, v11_int; +//Inputs to 2nd stage +logic [HALF_WIDTH-1:0] u10, u11, v10, v11; + +pwo_t mldsa_pwo_uv_o; + +logic gs_mode; +logic pairwm_mode; + +//Other internal wires +logic [UNMASKED_BF_STAGE1_LATENCY-1:0][HALF_WIDTH-1:0] mldsa_w10_reg, mldsa_w11_reg; //Shift w10 by 5 cycles to match 1st stage BF latency +logic [MLKEM_UNMASKED_BF_STAGE1_LATENCY-1:0][MLKEM_REG_SIZE-1:0] mlkem_w10_reg, mlkem_w11_reg; +logic [MASKED_BF_STAGE1_LATENCY-1:0][HALF_WIDTH-1:0] masked_w10_reg, masked_w11_reg; +logic [MLKEM_MASKED_BF_STAGE1_LATENCY-1:0][HALF_WIDTH-1:0] mlkem_masked_w10_reg, mlkem_masked_w11_reg; +logic pwo_mode, masked_pwm_mode; + +//Shares - TODO replace with struct? +logic [1:0][WIDTH-1:0] u00_share, u01_share, v00_share, v01_share, u10_share, v10_share, u11_share, v11_share; +logic [1:0][WIDTH-1:0] w00_share, w01_share, w10_share, w11_share; +logic [1:0][WIDTH-1:0] uv00_share, uv01_share, uv10_share, uv11_share; +logic [1:0][WIDTH-1:0] uv00_share_reg, uv01_share_reg, uv10_share_reg, uv11_share_reg; +logic [1:0][WIDTH-1:0] twiddle_w00_share, twiddle_w01_share; +bf_uvo_t mldsa_masked_gs_stage1_uvo, mlkem_masked_gs_stage1_uvo; + +//pwm output shares +logic [1:0][WIDTH-1:0] mldsa_uv0_share, mldsa_uv1_share; +pwm_shares_uvo_t bf_pwm_shares_uvo; + +//zeta shares for pairwm +logic [1:0][MLKEM_MASKED_WIDTH-1:0] z0_share, z1_share; +//pairwm output shares +logic [1:0][MLKEM_MASKED_WIDTH-1:0] mlkem_uv0_share, mlkem_uv1_share, mlkem_uv2_share, mlkem_uv3_share; + +//w delay flops +//Flop the twiddle factor 5x to correctly pass in values to the 2nd set of bf units +always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) begin + mldsa_w10_reg <= 'h0; + mldsa_w11_reg <= 'h0; + mlkem_w10_reg <= 'h0; + mlkem_w11_reg <= 'h0; + end + else if (zeroize) begin + mldsa_w10_reg <= 'h0; + mldsa_w11_reg <= 'h0; + mlkem_w10_reg <= 'h0; + mlkem_w11_reg <= 'h0; + end + else begin + mldsa_w10_reg <= {uvw_i.w10_i, mldsa_w10_reg[UNMASKED_BF_STAGE1_LATENCY-1:1]}; + mldsa_w11_reg <= {uvw_i.w11_i, mldsa_w11_reg[UNMASKED_BF_STAGE1_LATENCY-1:1]}; + + mlkem_w10_reg <= {uvw_i.w10_i[MLKEM_REG_SIZE-1:0], mlkem_w10_reg[MLKEM_UNMASKED_BF_STAGE1_LATENCY-1:1]}; + mlkem_w11_reg <= {uvw_i.w11_i[MLKEM_REG_SIZE-1:0], mlkem_w11_reg[MLKEM_UNMASKED_BF_STAGE1_LATENCY-1:1]}; + end +end + +//TODO: optimize by removing this flop and delaying twiddle addr? +always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) begin + masked_w10_reg <= 'h0; + end + else if (zeroize) begin + masked_w10_reg <= 'h0; + end + else begin + masked_w10_reg <= {bf_shares_uvw_i.w10_i, masked_w10_reg[MASKED_BF_STAGE1_LATENCY-1:1]}; + end +end + +assign masked_w11_reg = masked_w10_reg; //used only in masked INTT, both are equal, so can opt num of flops + +assign pwo_mode = (mode inside {pwm, pwa, pws}); +assign masked_pwm_mode = (mode == pwm) & masking_en; +assign gs_mode = (mode == gs); +assign pairwm_mode = mlkem & (mode == pairwm); + +//Input assignments - TODO: add input flops for u, v, w, and rnd? +always_comb begin + if (pwo_mode) begin + u00 = pw_uvw_i.u0_i; + v00 = pw_uvw_i.v0_i; + w00 = pw_uvw_i.w0_i; + + u01 = pw_uvw_i.u1_i; + v01 = pw_uvw_i.v1_i; + w01 = pw_uvw_i.w1_i; + + u10 = pw_uvw_i.u2_i; + v10 = pw_uvw_i.v2_i; + w10 = pw_uvw_i.w2_i; + + u11 = pw_uvw_i.u3_i; + v11 = pw_uvw_i.v3_i; + w11 = pw_uvw_i.w3_i; + end + else begin //Only applies to unmasked ops since in masking, intt receives inputs from pwm and not from the API + u00 = uvw_i.u00_i; + v00 = uvw_i.v00_i; + w00 = uvw_i.w00_i; + + u01 = uvw_i.u01_i; + v01 = uvw_i.v01_i; + w01 = uvw_i.w01_i; + + u10 = (masking_en & intt_passthrough) ? mlkem_masked_gs_stage1_uvo.u20_o : u10_int; + v10 = (masking_en & intt_passthrough) ? mlkem_masked_gs_stage1_uvo.v20_o : v10_int; + w10 = mlkem ? HALF_WIDTH'(mlkem_w10_reg[0]) : mldsa_w10_reg[0]; + + u11 = (masking_en & intt_passthrough) ? mlkem_masked_gs_stage1_uvo.u21_o : u11_int; + v11 = (masking_en & intt_passthrough) ? mlkem_masked_gs_stage1_uvo.v21_o : v11_int; + w11 = mlkem ? HALF_WIDTH'(mlkem_w11_reg[0]) : mldsa_w11_reg[0]; + end +end + +always_comb begin + u00_share = pwm_shares_uvw_i.u0_i; + u01_share = pwm_shares_uvw_i.u1_i; + u10_share = pwm_shares_uvw_i.u2_i; + u11_share = pwm_shares_uvw_i.u3_i; + + v00_share = pwm_shares_uvw_i.v0_i; + v01_share = pwm_shares_uvw_i.v1_i; + v10_share = pwm_shares_uvw_i.v2_i; + v11_share = pwm_shares_uvw_i.v3_i; + + w00_share = pwm_shares_uvw_i.w0_i; + w01_share = pwm_shares_uvw_i.w1_i; + w10_share = pwm_shares_uvw_i.w2_i; + w11_share = pwm_shares_uvw_i.w3_i; + + z0_share = pairwm_mode ? mlkem_shares_pairwm_zeta13_i.z0_i : '0; + z1_share = pairwm_mode ? mlkem_shares_pairwm_zeta13_i.z1_i : '0; +end + +//---------------------------------------------------- +//Masked PWMs - Used in masked PWM+INTT mode only - 210 clks +//---------------------------------------------------- +ntt_masked_pwm #( + .WIDTH(WIDTH) +) pwm_inst00 ( + .clk(clk), + .reset_n(reset_n), + .zeroize(zeroize), + .accumulate(accumulate), + .u(u00_share), + .v(v00_share), + .w(w00_share), + .rnd({rnd_i[4], rnd_i[3], rnd_i[2], rnd_i[1], rnd_i[0]}), + .res(mldsa_uv0_share) +); + +ntt_masked_pwm #( + .WIDTH(WIDTH) +) pwm_inst01 ( + .clk(clk), + .reset_n(reset_n), + .zeroize(zeroize), + .accumulate(accumulate), + .u(u01_share), + .v(v01_share), + .w(w01_share), + .rnd({rnd_i[0], rnd_i[4], rnd_i[3], rnd_i[2], rnd_i[1]}), + .res(mldsa_uv1_share) +); + +//--------------------------- +//Refresh randomness +//--------------------------- +always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) begin + for (int i = 0; i < 2; i++) begin + uv00_share_reg[i] <= 'h0; + uv01_share_reg[i] <= 'h0; + uv10_share_reg[i] <= 'h0; + uv11_share_reg[i] <= 'h0; + + twiddle_w00_share[i] <= 'h0; + twiddle_w01_share[i] <= 'h0; + end + end + else if (zeroize) begin + for (int i = 0; i < 2; i++) begin + uv00_share_reg[i] <= 'h0; + uv01_share_reg[i] <= 'h0; + uv10_share_reg[i] <= 'h0; + uv11_share_reg[i] <= 'h0; + + twiddle_w00_share[i] <= 'h0; + twiddle_w01_share[i] <= 'h0; + end + end + else begin + uv00_share_reg <= bf_shares_uvw_i.u00_i; + uv01_share_reg <= (gs_mode & masking_en & !intt_passthrough) ? bf_shares_uvw_i.v00_i : bf_shares_uvw_i.u01_i; + uv10_share_reg <= (gs_mode & masking_en & !intt_passthrough) ? bf_shares_uvw_i.u01_i : bf_shares_uvw_i.v00_i; + uv11_share_reg <= bf_shares_uvw_i.v01_i; + + //In passthrough mode, 1st stage is used instead of bypassed and 2nd stage is bypassed. Swap twiddles to ensure correct output + twiddle_w00_share[0] <= intt_passthrough ? WIDTH'(bf_shares_uvw_i.w10_i - rnd_i[0][HALF_WIDTH-1:0]) : bf_shares_uvw_i.w00_i[0]; + twiddle_w00_share[1] <= intt_passthrough ? WIDTH'(rnd_i[0][HALF_WIDTH-1:0]) : bf_shares_uvw_i.w00_i[1]; + + twiddle_w01_share[0] <= intt_passthrough ? WIDTH'(bf_shares_uvw_i.w11_i - rnd_i[0][HALF_WIDTH-1:0]) : bf_shares_uvw_i.w01_i[0]; + twiddle_w01_share[1] <= intt_passthrough ? WIDTH'(rnd_i[0][HALF_WIDTH-1:0]) : bf_shares_uvw_i.w01_i[1]; + end +end + +//---------------------------------------------------- +//MLDSA Masked BFU stage 1 - Used in masked PWM/INTT mode only - 264 clks +//PWM outputs: uv00[1:0], uv01[1:0], uv10[1:0], uv11[1:0] +//---------------------------------------------------- +ntt_masked_butterfly1x2 #( + .WIDTH(WIDTH) +) masked_bf_1x2_inst0 ( + .clk(clk), + .reset_n(reset_n), + .zeroize(zeroize), + .uvw_i(masked_pwm_mode ? {u10_share, u11_share, v10_share, v11_share, w10_share, w11_share} : {uv00_share_reg, uv10_share_reg, uv01_share_reg, uv11_share_reg, twiddle_w00_share, twiddle_w01_share}), + .rnd_i({rnd_i[1], rnd_i[0], rnd_i[4], rnd_i[3], rnd_i[2]}), + .mode(mode), + .accumulate(accumulate), + .uv_o(mldsa_masked_gs_stage1_uvo), + .bf_pwm_uv_o(bf_pwm_shares_uvo) +); + +//---------------------------------------------------- +//MLKEM Masked BFU stage 1 - Used in MLKEM masked INTT mode only - 16 clks +//---------------------------------------------------- +ntt_mlkem_masked_butterfly1x2 mlkem_masked_bf_1x2_inst0 +( + .clk(clk), + .reset_n(reset_n), + .zeroize(zeroize), + .uvw_i({{uv00_share_reg[1][MLKEM_MASKED_WIDTH-1:0], uv00_share_reg[0][MLKEM_MASKED_WIDTH-1:0]}, + {uv10_share_reg[1][MLKEM_MASKED_WIDTH-1:0], uv10_share_reg[0][MLKEM_MASKED_WIDTH-1:0]}, + {uv01_share_reg[1][MLKEM_MASKED_WIDTH-1:0], uv01_share_reg[0][MLKEM_MASKED_WIDTH-1:0]}, + {uv11_share_reg[1][MLKEM_MASKED_WIDTH-1:0], uv11_share_reg[0][MLKEM_MASKED_WIDTH-1:0]}, + {twiddle_w00_share[1][MLKEM_MASKED_WIDTH-1:0], twiddle_w00_share[0][MLKEM_MASKED_WIDTH-1:0]}, + {twiddle_w01_share[1][MLKEM_MASKED_WIDTH-1:0], twiddle_w01_share[0][MLKEM_MASKED_WIDTH-1:0]}}), + .rnd_i({rnd_i[1][13:0], rnd_i[0][13:0], rnd_i[4][13:0], rnd_i[3][13:0], rnd_i[2][13:0]}), + .uv_o(mlkem_masked_gs_stage1_uvo) +); + +//---------------------------------------------------- +//MLDSA/MLKEM - Unmasked BFU stage 1 - Used in all other modes +//---------------------------------------------------- +ntt_butterfly #( + .REG_SIZE(HALF_WIDTH) +) unmasked_bf_inst00 ( + .clk(clk), + .reset_n(reset_n), + .zeroize(zeroize), + .mode(mode), + .mlkem(mlkem), + .opu_i(masking_en ? HALF_WIDTH'(0) : intt_passthrough ? u00 : u00), + .opv_i(masking_en ? HALF_WIDTH'(0) : intt_passthrough ? u01 : v00), + .opw_i(masking_en ? HALF_WIDTH'(0) : intt_passthrough ? HALF_WIDTH'(uvw_i.w10_i[MLKEM_REG_SIZE-1:0]) : w00), + .accumulate(accumulate), + .u_o(u10_int), + .v_o(u11_int), + .pwm_res_o(mldsa_pwo_uv_o.uv0) +); + +ntt_butterfly #( + .REG_SIZE(HALF_WIDTH) +) unmasked_bf_inst01 ( + .clk(clk), + .reset_n(reset_n), + .zeroize(zeroize), + .mode(mode), + .mlkem(mlkem), + .opu_i(masking_en ? HALF_WIDTH'(0) : intt_passthrough ? v00 : u01), + .opv_i(masking_en ? HALF_WIDTH'(0) : intt_passthrough ? v01 : v01), + .opw_i(masking_en ? HALF_WIDTH'(0) : intt_passthrough ? HALF_WIDTH'(uvw_i.w11_i[MLKEM_REG_SIZE-1:0]) : w01), + .accumulate(accumulate), + .u_o(v10_int), + .v_o(v11_int), + .pwm_res_o(mldsa_pwo_uv_o.uv1) +); + +//---------------------------------------------------- +//MLDSA/MLKEM - Unmasked BFU stage 2 - Used in all modes (irrespective of masking_en) +//---------------------------------------------------- +logic [HALF_WIDTH-1:0] u20_int, v20_int, u21_int, v21_int; +logic [MLKEM_MASKED_BF_STAGE1_LATENCY-1:0][HALF_WIDTH-1:0] u10_reg, u11_reg; +logic [MLKEM_MASKED_BF_STAGE1_LATENCY-1:0][HALF_WIDTH-1:0] v10_reg, v11_reg; + +always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) begin + u10_reg <= '0; + u11_reg <= '0; + + v10_reg <= '0; + v11_reg <= '0; + end + else if (zeroize) begin + u10_reg <= '0; + u11_reg <= '0; + + v10_reg <= '0; + v11_reg <= '0; + end + else begin + u10_reg <= {u10, u10_reg[MLKEM_MASKED_BF_STAGE1_LATENCY-1:1]}; + u11_reg <= {u11, u11_reg[MLKEM_MASKED_BF_STAGE1_LATENCY-1:1]}; + + v10_reg <= {v10, v10_reg[MLKEM_MASKED_BF_STAGE1_LATENCY-1:1]}; + v11_reg <= {v11, v11_reg[MLKEM_MASKED_BF_STAGE1_LATENCY-1:1]}; + end +end + +logic [HALF_WIDTH-1:0] bf_opu10, bf_opv10, bf_opw10; +logic [HALF_WIDTH-1:0] bf_opu11, bf_opv11, bf_opw11; + +always_comb begin + if (masking_en) begin + //Assign u, v inputs - masked mode + if (mlkem) begin //during passthrough 2nd stage is not used - assigning inputs to generate noise + bf_opu10 = mlkem_masked_gs_stage1_uvo.u20_o; + bf_opv10 = mlkem_masked_gs_stage1_uvo.v20_o; + bf_opw10 = masked_w10_reg[MASKED_BF_STAGE1_LATENCY-MLKEM_MASKED_BF_STAGE1_LATENCY]; //assuming mldsa bf stage 1 latency > mlkem bf stage 1 latency + + bf_opu11 = mlkem_masked_gs_stage1_uvo.u21_o; + bf_opv11 = mlkem_masked_gs_stage1_uvo.v21_o; + bf_opw11 = masked_w11_reg[MASKED_BF_STAGE1_LATENCY-MLKEM_MASKED_BF_STAGE1_LATENCY]; + end + else begin + bf_opu10 = mldsa_masked_gs_stage1_uvo.u20_o; + bf_opv10 = mldsa_masked_gs_stage1_uvo.v20_o; + bf_opw10 = masked_w10_reg[0]; + + bf_opu11 = mldsa_masked_gs_stage1_uvo.u21_o; + bf_opv11 = mldsa_masked_gs_stage1_uvo.v21_o; + bf_opw11 = masked_w11_reg[0]; + end + + end + else begin + //Assign u, v inputs - unmasked mode + bf_opu10 = u10; + bf_opv10 = v10; + + bf_opu11 = u11; + bf_opv11 = v11; + + //Assign w inputs - unmasked mode + if (pwo_mode) begin + bf_opw10 = w10; + bf_opw11 = w11; + end + else if (mlkem) begin + bf_opw10 = HALF_WIDTH'(mlkem_w10_reg[0]); + bf_opw11 = HALF_WIDTH'(mlkem_w11_reg[0]); + end + else begin + bf_opw10 = mldsa_w10_reg[0]; + bf_opw11 = mldsa_w11_reg[0]; + end + + end +end + +ntt_butterfly #( + .REG_SIZE(HALF_WIDTH) +) unmasked_bf_inst10 ( + .clk(clk), + .reset_n(reset_n), + .zeroize(zeroize), + .mode(mode), + .mlkem(mlkem), + .opu_i(bf_opu10), + .opv_i(bf_opv10), + .opw_i(bf_opw10), + .accumulate(accumulate), + .u_o(u20_int), + .v_o(v20_int), + .pwm_res_o(mldsa_pwo_uv_o.uv2) +); + +ntt_butterfly #( + .REG_SIZE(HALF_WIDTH) +) unmasked_bf_inst11 ( + .clk(clk), + .reset_n(reset_n), + .zeroize(zeroize), + .mode(mode), + .mlkem(mlkem), + .opu_i(bf_opu11), + .opv_i(bf_opv11), + .opw_i(bf_opw11), + .accumulate(accumulate), + .u_o(u21_int), + .v_o(v21_int), + .pwm_res_o(mldsa_pwo_uv_o.uv3) +); + +always_comb begin + uv_o.u20_o = ntt_passthrough ? u10_reg[MLKEM_MASKED_BF_STAGE1_LATENCY-MLKEM_UNMASKED_BF_STAGE1_LATENCY] + : intt_passthrough ? masking_en ? u10 : u10_reg[MLKEM_MASKED_BF_STAGE1_LATENCY-MLKEM_UNMASKED_BF_STAGE1_LATENCY] + : u20_int; + uv_o.v20_o = ntt_passthrough ? v10_reg[MLKEM_MASKED_BF_STAGE1_LATENCY-MLKEM_UNMASKED_BF_STAGE1_LATENCY] + : intt_passthrough ? masking_en ? u11 : u11_reg[MLKEM_MASKED_BF_STAGE1_LATENCY-MLKEM_UNMASKED_BF_STAGE1_LATENCY] + : v20_int; + + uv_o.u21_o = ntt_passthrough ? u11_reg[MLKEM_MASKED_BF_STAGE1_LATENCY-MLKEM_UNMASKED_BF_STAGE1_LATENCY] + : intt_passthrough ? masking_en ? v10 : v10_reg[MLKEM_MASKED_BF_STAGE1_LATENCY-MLKEM_UNMASKED_BF_STAGE1_LATENCY] + : u21_int; + uv_o.v21_o = ntt_passthrough ? v11_reg[MLKEM_MASKED_BF_STAGE1_LATENCY-MLKEM_UNMASKED_BF_STAGE1_LATENCY] + : intt_passthrough ? masking_en ? v11 : v11_reg[MLKEM_MASKED_BF_STAGE1_LATENCY-MLKEM_UNMASKED_BF_STAGE1_LATENCY] + : v21_int; +end + +//---------------------------------------------------- +//MLKEM - Unmasked PairWM +//---------------------------------------------------- +mlkem_pwo_uvwzi_t pairwm_uvw01_i, pairwm_uvw23_i; +mlkem_pwo_t pairwm_uv01_o, pairwm_uv23_o; + +always_comb begin + if (pairwm_mode) begin + pairwm_uvw01_i.u0_i = pw_uvw_i.u0_i[MLKEM_REG_SIZE-1:0]; + pairwm_uvw01_i.v0_i = pw_uvw_i.v0_i[MLKEM_REG_SIZE-1:0]; + pairwm_uvw01_i.w0_i = pw_uvw_i.w0_i[MLKEM_REG_SIZE-1:0]; + + pairwm_uvw01_i.u1_i = pw_uvw_i.u1_i[MLKEM_REG_SIZE-1:0]; + pairwm_uvw01_i.v1_i = pw_uvw_i.v1_i[MLKEM_REG_SIZE-1:0]; + pairwm_uvw01_i.w1_i = pw_uvw_i.w1_i[MLKEM_REG_SIZE-1:0]; + + pairwm_uvw23_i.u0_i = pw_uvw_i.u2_i[MLKEM_REG_SIZE-1:0]; + pairwm_uvw23_i.v0_i = pw_uvw_i.v2_i[MLKEM_REG_SIZE-1:0]; + pairwm_uvw23_i.w0_i = pw_uvw_i.w2_i[MLKEM_REG_SIZE-1:0]; + + pairwm_uvw23_i.u1_i = pw_uvw_i.u3_i[MLKEM_REG_SIZE-1:0]; + pairwm_uvw23_i.v1_i = pw_uvw_i.v3_i[MLKEM_REG_SIZE-1:0]; + pairwm_uvw23_i.w1_i = pw_uvw_i.w3_i[MLKEM_REG_SIZE-1:0]; + end + else begin + pairwm_uvw01_i = '0; + pairwm_uvw23_i = '0; + end +end + +ntt_karatsuba_pairwm mlkem_pawm_inst0 ( + .clk(clk), + .reset_n(reset_n), + .zeroize(zeroize), + .accumulate(accumulate), + .pwo_uvw_i(pairwm_uvw01_i), + .pwo_z_i(mlkem_pairwm_zeta13_i.z0_i), + .pwo_uv_o(pairwm_uv01_o) +); + +ntt_karatsuba_pairwm mlkem_pawm_inst1 ( + .clk(clk), + .reset_n(reset_n), + .zeroize(zeroize), + .accumulate(accumulate), + .pwo_uvw_i(pairwm_uvw23_i), + .pwo_z_i(mlkem_pairwm_zeta13_i.z1_i), + .pwo_uv_o(pairwm_uv23_o) +); + +always_comb begin + pwo_uv_o.uv0 = pairwm_mode ? HALF_WIDTH'(pairwm_uv01_o.uv0_o) : mldsa_pwo_uv_o.uv0; + pwo_uv_o.uv1 = pairwm_mode ? HALF_WIDTH'(pairwm_uv01_o.uv1_o) : mldsa_pwo_uv_o.uv1; + pwo_uv_o.uv2 = pairwm_mode ? HALF_WIDTH'(pairwm_uv23_o.uv0_o) : mldsa_pwo_uv_o.uv2; + pwo_uv_o.uv3 = pairwm_mode ? HALF_WIDTH'(pairwm_uv23_o.uv1_o) : mldsa_pwo_uv_o.uv3; +end + +//---------------------------------------------------- +//MLKEM - Unmasked PairWM - TODO: check input/output widths +//---------------------------------------------------- +ntt_masked_pairwm mlkem_masked_pawm_inst0 ( + .clk(clk), + .reset_n(reset_n), + .zeroize(zeroize), + .accumulate(accumulate), + .u0({u00_share[1][MLKEM_MASKED_WIDTH-1:0], u00_share[0][MLKEM_MASKED_WIDTH-1:0]}), + .v0({v00_share[1][MLKEM_MASKED_WIDTH-1:0], v00_share[0][MLKEM_MASKED_WIDTH-1:0]}), + .w0({w00_share[1][MLKEM_MASKED_WIDTH-1:0], w00_share[0][MLKEM_MASKED_WIDTH-1:0]}), + .u1({u01_share[1][MLKEM_MASKED_WIDTH-1:0], u01_share[0][MLKEM_MASKED_WIDTH-1:0]}), + .v1({v01_share[1][MLKEM_MASKED_WIDTH-1:0], v01_share[0][MLKEM_MASKED_WIDTH-1:0]}), + .w1({w01_share[1][MLKEM_MASKED_WIDTH-1:0], w01_share[0][MLKEM_MASKED_WIDTH-1:0]}), + .zeta(z0_share), + .rnd({rnd_i[4][13:0], rnd_i[3][13:0], rnd_i[2][13:0], rnd_i[1][13:0], rnd_i[0][13:0]}), + .rnd_24bit({rnd_i[0][37:14]}), + .res0(mlkem_uv0_share), + .res1(mlkem_uv1_share) +); + +ntt_masked_pairwm mlkem_masked_pawm_inst1 ( + .clk(clk), + .reset_n(reset_n), + .zeroize(zeroize), + .accumulate(accumulate), + .u0({u10_share[1][MLKEM_MASKED_WIDTH-1:0], u10_share[0][MLKEM_MASKED_WIDTH-1:0]}), + .v0({v10_share[1][MLKEM_MASKED_WIDTH-1:0], v10_share[0][MLKEM_MASKED_WIDTH-1:0]}), + .w0({w10_share[1][MLKEM_MASKED_WIDTH-1:0], w10_share[0][MLKEM_MASKED_WIDTH-1:0]}), + .u1({u11_share[1][MLKEM_MASKED_WIDTH-1:0], u11_share[0][MLKEM_MASKED_WIDTH-1:0]}), + .v1({v11_share[1][MLKEM_MASKED_WIDTH-1:0], v11_share[0][MLKEM_MASKED_WIDTH-1:0]}), + .w1({w11_share[1][MLKEM_MASKED_WIDTH-1:0], w11_share[0][MLKEM_MASKED_WIDTH-1:0]}), + .zeta(z1_share), + .rnd({rnd_i[0][13:0], rnd_i[4][13:0], rnd_i[3][13:0], rnd_i[2][13:0], rnd_i[1][13:0]}), + .rnd_24bit({rnd_i[1][37:14]}), + .res0(mlkem_uv2_share), + .res1(mlkem_uv3_share) +); + +//Assign PWM output +always_comb begin + pwm_shares_uvo.uv0 = pairwm_mode ? {WIDTH'(mlkem_uv0_share[1]), WIDTH'(mlkem_uv0_share[0])} : mldsa_uv0_share; + pwm_shares_uvo.uv1 = pairwm_mode ? {WIDTH'(mlkem_uv1_share[1]), WIDTH'(mlkem_uv1_share[0])} : mldsa_uv1_share; + pwm_shares_uvo.uv2 = pairwm_mode ? {WIDTH'(mlkem_uv2_share[1]), WIDTH'(mlkem_uv2_share[0])} : bf_pwm_shares_uvo.uv2; + pwm_shares_uvo.uv3 = pairwm_mode ? {WIDTH'(mlkem_uv3_share[1]), WIDTH'(mlkem_uv3_share[0])} : bf_pwm_shares_uvo.uv3; +end + +//---------------------------------------------------- +//Determine when results are ready +//---------------------------------------------------- +//ready_o logic + +// `ifdef MLDSA_NTT_MASKING //TODO: optimize shift reg size based on masking en/dis + logic [MASKED_INTT_LATENCY-1:0] masked_ready_reg; //masked INTT is longest op + + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) + masked_ready_reg <= 'b0; + else if (zeroize) + masked_ready_reg <= 'b0; + else begin + if (mlkem) begin + unique case(mode) + ct: masked_ready_reg <= {{(MASKED_INTT_LATENCY-MLKEM_UNMASKED_BF_LATENCY){1'b0}}, enable, masked_ready_reg[MLKEM_UNMASKED_BF_LATENCY-1:1]}; + gs: begin + if (masking_en) + masked_ready_reg <= {{(MASKED_INTT_LATENCY-MLKEM_MASKED_INTT_LATENCY){1'b0}}, enable, masked_ready_reg[MLKEM_MASKED_INTT_LATENCY-1:1]}; + else + masked_ready_reg <= {{(MASKED_INTT_LATENCY-MLKEM_UNMASKED_BF_LATENCY){1'b0}}, enable, masked_ready_reg[MLKEM_UNMASKED_BF_LATENCY-1:1]}; + end + pwm: masked_ready_reg <= 'b0; + pwa: masked_ready_reg <= {{MASKED_INTT_LATENCY-1{1'b0}}, enable}; + pws: masked_ready_reg <= {{MASKED_INTT_LATENCY-1{1'b0}}, enable}; + pairwm: begin + if (masking_en) + masked_ready_reg <= accumulate ? {{(MASKED_INTT_LATENCY-MLKEM_MASKED_PAIRWM_ACC_LATENCY){1'b0}}, enable, masked_ready_reg[MLKEM_MASKED_PAIRWM_ACC_LATENCY-1:1]} + : {{(MASKED_INTT_LATENCY-MLKEM_MASKED_PAIRWM_LATENCY){1'b0}}, enable, masked_ready_reg[MLKEM_MASKED_PAIRWM_LATENCY-1:1]}; + else + masked_ready_reg <= accumulate ? {{(MASKED_INTT_LATENCY-MLKEM_UNMASKED_PAIRWM_ACC_LATENCY){1'b0}}, enable, masked_ready_reg[MLKEM_UNMASKED_PAIRWM_ACC_LATENCY-1:1]} + : {{(MASKED_INTT_LATENCY-MLKEM_UNMASKED_PAIRWM_LATENCY){1'b0}}, enable, masked_ready_reg[MLKEM_UNMASKED_PAIRWM_LATENCY-1:1]}; + end + default: masked_ready_reg <= 'b0; + endcase + end + else begin + unique case(mode) //270:0 delay flop for enable + //Add masking_en mux for gs, pwm modes + ct: masked_ready_reg <= {{(MASKED_INTT_LATENCY-UNMASKED_BF_LATENCY){1'b0}}, enable, masked_ready_reg[UNMASKED_BF_LATENCY-1:1]}; + gs: begin + if (masking_en) + masked_ready_reg <= {1'b0, enable, masked_ready_reg[MASKED_INTT_LATENCY-1:1]}; + else + masked_ready_reg <= {{(MASKED_INTT_LATENCY-UNMASKED_BF_LATENCY){1'b0}}, enable, masked_ready_reg[UNMASKED_BF_LATENCY-1:1]}; + end + pwm: begin + if (masking_en) begin + if (shuffle_en) + masked_ready_reg <= accumulate ? {{(MASKED_INTT_LATENCY-MASKED_PWM_ACC_LATENCY){1'b0}}, enable, masked_ready_reg[MASKED_PWM_ACC_LATENCY-1:1]} : {{(MASKED_INTT_LATENCY-MASKED_PWM_LATENCY-1){1'b0}}, enable, masked_ready_reg[MASKED_PWM_LATENCY-2:1]}; + else + masked_ready_reg <= accumulate ? {{(MASKED_INTT_LATENCY-MASKED_PWM_ACC_LATENCY){1'b0}}, enable, masked_ready_reg[MASKED_PWM_ACC_LATENCY-1:1]} : {{(MASKED_INTT_LATENCY-MASKED_PWM_LATENCY-1){1'b0}}, enable, masked_ready_reg[MASKED_PWM_LATENCY-2:1]}; + end + else + masked_ready_reg <= accumulate ? {{(MASKED_INTT_LATENCY-UNMASKED_PWM_LATENCY){1'b0}}, enable, masked_ready_reg[UNMASKED_PWM_LATENCY-1:1]} : {6'h0, enable, masked_ready_reg[UNMASKED_PWM_LATENCY-2:1]}; + end + pwa: masked_ready_reg <= {{MASKED_INTT_LATENCY-1{1'b0}}, enable}; + pws: masked_ready_reg <= {{MASKED_INTT_LATENCY-1{1'b0}}, enable}; + pairwm: masked_ready_reg <= 'b0; + default: masked_ready_reg <= 'h0; + endcase + end + end + end + + assign ready_o = masked_ready_reg[0]; + +endmodule diff --git a/designs/Caliptra/src/adams-bridge/ntt_karatsuba_pairwm.sv b/designs/Caliptra/src/adams-bridge/ntt_karatsuba_pairwm.sv new file mode 100644 index 0000000..1033dd5 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/ntt_karatsuba_pairwm.sv @@ -0,0 +1,307 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +// +//====================================================================== +// +// ntt_karatsuba_pairwm.sv +// -------- +// Unmasked MLKEM Karatsuba pairwise multiplier. Receives 4 coefficients - 2 from memory, 2 from sampler/memory +// and generates 2 corresponding outputs. Also needs an additional zeta input. All operations are modular. +// Supports accumulation as an additional input. +// This module uses Karatsuba technique for an optimized implementation of pairwise multiplication. However, +// in a masked version, normal multiplication is performed for a better masking structure +// (a2i, a2i+1) * (b2i, b2i+1) => +// c2i = (a2i*b2i) + (a2i+1*b2i+1*zeta) +// c2i+1 = [{(a2i+a2i+1)*(b2i+b2i+1)} - (a2i*b2i)] - (a2i+1*b2i+1) +// Total end-to-end latency without accumulate = 4 cycles +// Total end-to-end latency with accumulate = 5 cycles + +module ntt_karatsuba_pairwm + import ntt_defines_pkg::*; + import abr_params_pkg::*; +( + //Clock and reset + input wire clk, + input wire reset_n, + input wire zeroize, + + //Data ports + input wire accumulate, + input mlkem_pwo_uvwzi_t pwo_uvw_i, + input [MLKEM_REG_SIZE-1:0] pwo_z_i, + output mlkem_pwo_t pwo_uv_o +); + +logic [MLKEM_REG_SIZE-1:0] u0, u1, v0, v1, w0, w1, z1; + +logic [(2*MLKEM_REG_SIZE)-1:0] uv00, uv01, uv11, mul_res_uv12, uvz11; +logic [MLKEM_REG_SIZE-1:0] uv00_reduced, uv11_reduced, mul_res_uv12_reduced, sub_res1, uvz11_reduced; +logic [REG_SIZE-1:0] add_res_u, add_res_v, sub_res0; + +always_comb begin + u0 = pwo_uvw_i.u0_i; + u1 = pwo_uvw_i.u1_i; + + v0 = pwo_uvw_i.v0_i; + v1 = pwo_uvw_i.v1_i; + + w0 = pwo_uvw_i.w0_i; + w1 = pwo_uvw_i.w1_i; + + z1 = pwo_z_i; +end + +//-------------------------------- +ntt_mult_dsp #( + .RADIX(MLKEM_REG_SIZE) + ) + mul_inst_0 ( + .A_i(u0), + .B_i(v0), + .P_o(uv00) +); + +barrett_reduction #( + .REG_SIZE(MLKEM_REG_SIZE), + .prime(MLKEM_Q) +) +mul_redux_inst_0 ( + .x(uv00), + .inv(), + .r(uv00_reduced) +); + +logic [2:0][MLKEM_REG_SIZE-1:0] uv00_reduced_reg, uv11_reduced_reg, z1_reg; +logic [3:0][MLKEM_REG_SIZE-1:0] w0_reg, w1_reg; +logic [REG_SIZE-1:0] uv0_o_int, uv1_o_int, uv1_o_int_reg, uv0_o_acc, uv1_o_acc; +always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) begin + uv00_reduced_reg <= '0; + uv11_reduced_reg <= '0; + z1_reg <= '0; + w0_reg <= '0; + w1_reg <= '0; + uv1_o_int_reg <= '0; + end + else if (zeroize) begin + uv00_reduced_reg <= '0; + uv11_reduced_reg <= '0; + z1_reg <= '0; + w0_reg <= '0; + w1_reg <= '0; + uv1_o_int_reg <= '0; + end + else begin + uv00_reduced_reg <= {uv00_reduced_reg[1:0], uv00_reduced}; + uv11_reduced_reg <= {uv11_reduced_reg[1:0], uv11_reduced}; + z1_reg <= {z1_reg[1:0], z1}; + w0_reg <= {w0_reg[2:0], w0}; + w1_reg <= {w1_reg[2:0], w1}; + uv1_o_int_reg <= uv1_o_int; + end +end +//-------------------------------- + +//-------------------------------- +ntt_mult_dsp #( + .RADIX(MLKEM_REG_SIZE) + ) + mul_inst_3 ( + .A_i(u1), + .B_i(v1), + .P_o(uv11) +); + +barrett_reduction #( + .REG_SIZE(MLKEM_REG_SIZE), + .prime(MLKEM_Q) +) +mul_redux_inst_3 ( + .x(uv11), + .inv(), + .r(uv11_reduced) +); + +ntt_mult_dsp #( + .RADIX(MLKEM_REG_SIZE) +) +mul_inst_zeta ( + .A_i(uv11_reduced_reg[2]), + .B_i(z1_reg[2]), + .P_o(uvz11) +); + +barrett_reduction #( + .REG_SIZE(MLKEM_REG_SIZE), + .prime(MLKEM_Q) +) +mul_zeta_redux_inst ( + .x(uvz11), + .inv(), + .r(uvz11_reduced) +); + +//1 cycle +abr_ntt_add_sub_mod #( + .REG_SIZE(REG_SIZE) //generic adder works with MLDSA reg size. In MLKEM, we're keeping the same reg size and just checking [12] for carry bit to reuse butterfly units. However, this instance is specific to MLKEM, so we need to pass reg size + 1 to preserve functionality +) +add_inst_uvz11( + .clk(clk), + .reset_n(reset_n), + .zeroize(zeroize), + .add_en_i(1'b1), + .sub_i(1'b0), + .opa_i(REG_SIZE'(uvz11_reduced)), + .opb_i(REG_SIZE'(uv00_reduced_reg[2])), + .prime_i(REG_SIZE'(MLKEM_Q)), + .mlkem(1'b1), + .res_o(uv0_o_int), + .ready_o() +); +//-------------------------------- + +//-------------------------------- +//1 cycle +abr_ntt_add_sub_mod #( + .REG_SIZE(REG_SIZE) +) +add_inst_u( + .clk(clk), + .reset_n(reset_n), + .zeroize(zeroize), + .add_en_i(1'b1), + .sub_i(1'b0), + .opa_i(REG_SIZE'(u0)), + .opb_i(REG_SIZE'(u1)), + .prime_i(REG_SIZE'(MLKEM_Q)), + .mlkem(1'b1), + .res_o(add_res_u), + .ready_o() +); + +//1 cycle +abr_ntt_add_sub_mod #( + .REG_SIZE(REG_SIZE) +) +add_inst_v( + .clk(clk), + .reset_n(reset_n), + .zeroize(zeroize), + .add_en_i(1'b1), + .sub_i(1'b0), + .opa_i(REG_SIZE'(v0)), + .opb_i(REG_SIZE'(v1)), + .prime_i(REG_SIZE'(MLKEM_Q)), + .mlkem(1'b1), + .res_o(add_res_v), + .ready_o() +); +//-------------------------------- + +//-------------------------------- +ntt_mult_dsp #( + .RADIX(MLKEM_REG_SIZE) + ) + mul_inst_12 ( + .A_i(add_res_u[MLKEM_REG_SIZE-1:0]), + .B_i(add_res_v[MLKEM_REG_SIZE-1:0]), + .P_o(mul_res_uv12) +); + +barrett_reduction #( + .REG_SIZE(MLKEM_REG_SIZE), + .prime(MLKEM_Q) +) +mul_redux_inst_12 ( + .x(mul_res_uv12), + .inv(), + .r(mul_res_uv12_reduced) +); +//-------------------------------- +//1 cycle +abr_ntt_add_sub_mod #( + .REG_SIZE(REG_SIZE) +) +sub_inst_0( + .clk(clk), + .reset_n(reset_n), + .zeroize(zeroize), + .add_en_i(1'b1), + .sub_i(1'b1), + .opa_i(REG_SIZE'(mul_res_uv12_reduced)), + .opb_i(REG_SIZE'(uv00_reduced_reg[0])), + .prime_i(REG_SIZE'(MLKEM_Q)), + .mlkem(1'b1), + .res_o(sub_res0), + .ready_o() +); + +//1 cycle +abr_ntt_add_sub_mod #( + .REG_SIZE(REG_SIZE) +) +sub_inst_1( + .clk(clk), + .reset_n(reset_n), + .zeroize(zeroize), + .add_en_i(1'b1), + .sub_i(1'b1), + .opa_i(sub_res0), + .opb_i(REG_SIZE'(uv11_reduced_reg[1])), + .prime_i(REG_SIZE'(MLKEM_Q)), + .mlkem(1'b1), + .res_o(uv1_o_int), + .ready_o() +); + +//-------------------------------- +//accumulation +abr_ntt_add_sub_mod #( + .REG_SIZE(REG_SIZE) +) +add_uv0_acc_inst( + .clk(clk), + .reset_n(reset_n), + .zeroize(zeroize), + .add_en_i(1'b1), + .sub_i(1'b0), + .opa_i(uv0_o_int), + .opb_i(REG_SIZE'(w0_reg[3])), + .prime_i(REG_SIZE'(MLKEM_Q)), + .mlkem(1'b1), + .res_o(uv0_o_acc), + .ready_o() +); + +abr_ntt_add_sub_mod #( + .REG_SIZE(REG_SIZE) +) +add_uv1_acc_inst( + .clk(clk), + .reset_n(reset_n), + .zeroize(zeroize), + .add_en_i(1'b1), + .sub_i(1'b0), + .opa_i(uv1_o_int_reg), + .opb_i(REG_SIZE'(w1_reg[3])), + .prime_i(REG_SIZE'(MLKEM_Q)), + .mlkem(1'b1), + .res_o(uv1_o_acc), + .ready_o() +); + +assign pwo_uv_o.uv0_o = accumulate ? uv0_o_acc[MLKEM_REG_SIZE-1:0] : uv0_o_int[MLKEM_REG_SIZE-1:0]; +assign pwo_uv_o.uv1_o = accumulate ? uv1_o_acc[MLKEM_REG_SIZE-1:0] : uv1_o_int_reg[MLKEM_REG_SIZE-1:0]; + +endmodule \ No newline at end of file diff --git a/designs/Caliptra/src/adams-bridge/ntt_masked_BFU_add_sub.sv b/designs/Caliptra/src/adams-bridge/ntt_masked_BFU_add_sub.sv new file mode 100644 index 0000000..5ac0910 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/ntt_masked_BFU_add_sub.sv @@ -0,0 +1,188 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +// +//====================================================================== +// +// ntt_masked_BFU_adder - total end-to-end latency = 53 clks +//====================================================================== + +module ntt_masked_BFU_add_sub + import ntt_defines_pkg::*; + import abr_params_pkg::*; +#( + parameter WIDTH = 46, + parameter HALF_WIDTH = WIDTH/2, + parameter ROLLER = WIDTH'(2**13-1) +) +( + input wire clk, + input wire reset_n, + input wire zeroize, + input wire sub, + input wire [1:0][WIDTH-1:0] u, + input wire [1:0][WIDTH-1:0] v, + input wire [WIDTH-1:0] rnd0, rnd1, rnd2, rnd3, + output logic [1:0] res [WIDTH-1:0] +); + + //Internal signals + logic [1:0][WIDTH-1:0] v_int, add_res; + logic [WIDTH+4:0][1:0][WIDTH-1:0] add_res_reg; //TODO parameterize + logic [1:0] add_res_rolled [WIDTH-1:0]; + logic [1:0] add_res_bool [WIDTH-1:0]; + logic [1:0] add_res_arith [WIDTH-1:0]; + logic [WIDTH-1:0] prime0, prime1, add_res_rolled0, add_res_rolled1; + logic [1:0][WIDTH-1:0] add_res_reduced, prime_packed; + logic [1:0] prime [WIDTH-1:0]; + logic [WIDTH-1:0] add_res_bool0, add_res_bool1, add_res_arith0, add_res_arith1; + + always_comb begin + if (sub) begin + v_int[0] = MLDSA_Q - v[0]; + v_int[1] = (~v[1] + 'h1); + end + else begin + v_int[0] = v[0]; + v_int[1] = v[1]; + end + end + + //Perform addition on input shares - 1 clk latency + abr_masked_N_bit_Arith_adder #( + .WIDTH(WIDTH) + ) masked_adder_inst ( + .clk(clk), + .rst_n(reset_n), + .zeroize(zeroize), + .x(u), + .y(v_int), + .s(add_res) + ); + + //Adder delay flops + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) begin + for (int i = 0; i <= WIDTH+4; i++) begin + add_res_reg[i] <= 'h0; + end + end + else if (zeroize) begin + for (int i = 0; i <= WIDTH+4; i++) begin + add_res_reg[i] <= 'h0; + end + end + else begin + add_res_reg <= {add_res, add_res_reg[WIDTH+4:1]}; + end + end + + //maskedAdder + reduction: + always_comb begin + add_res_rolled0 = add_res[0] + ROLLER; + add_res_rolled1 = add_res[1]; + for (int i = 0; i < WIDTH; i++) begin + add_res_rolled[i][0] = add_res_rolled0[i]; + add_res_rolled[i][1] = add_res_rolled1[i]; + end + end + + //Takes 48 clks + abr_masked_A2B_conv #( + .WIDTH(WIDTH) + ) a2b_inst ( + .clk(clk), + .rst_n(reset_n), + .zeroize(zeroize), + .x(add_res_rolled), + .rnd(rnd1), + .rnd_for_Boolean0(rnd2), + .rnd_for_Boolean1(rnd3), + .s(add_res_bool) + ); + + logic [1:0] temp0 [WIDTH-1:0]; + + //Convert 1 bit to 46 bit to pass to B2A converter - 1 clk + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) begin + for (int i = 0; i < WIDTH; i++) begin + temp0[i] <= 2'b0; + end + end + else if (zeroize) begin + for (int i = 0; i < WIDTH; i++) begin + temp0[i] <= 2'b0; + end + end + else begin + for (int i = 0; i < WIDTH; i++) begin + if (i==0) begin + temp0[i] <= {add_res_bool[HALF_WIDTH][1], add_res_bool[HALF_WIDTH][0]}; + end + else begin + temp0[i] <= '0; + end + end + end + end + + //Convert 24th bit to arithmetic domain - 2 clks + abr_masked_B2A_conv #( + .WIDTH(WIDTH) + ) b2a_inst ( + .clk(clk), + .rst_n(reset_n), + .zeroize(zeroize), + .rnd(rnd0), + .x_boolean(temp0), + .x_arith(add_res_arith) + ); + + //Organize wires for easier use and debug + always_comb begin + for(int i = 0; i< WIDTH; i++) begin + add_res_bool0[i] = add_res_bool[i][0]; + add_res_bool1[i] = add_res_bool[i][1]; + add_res_arith0[i] = add_res_arith[i][0]; + add_res_arith1[i] = add_res_arith[i][1]; + end + + //If bit[23] = 1, subtract Q from adder result + prime0 = WIDTH'(add_res_arith0 * (~MLDSA_Q+'h1)); + prime1 = WIDTH'(add_res_arith1 * (~MLDSA_Q+'h1)); + prime_packed[0] = prime0; + prime_packed[1] = prime1; + add_res_reduced[0] = add_res_reg[0][0]+prime_packed[0]; + add_res_reduced[1] = add_res_reg[0][1]+prime_packed[1]; + end + + //Output flop - 1 clk + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) begin + for (int i = 0; i < WIDTH; i++) + res[i] <= 2'h0; + end + else if (zeroize) begin + for (int i = 0; i < WIDTH; i++) + res[i] <= 2'h0; + end + else begin + for (int i = 0; i < WIDTH; i++) begin + res[i] <= {add_res_reduced[1][i],add_res_reduced[0][i]}; + end + end + end + + +endmodule \ No newline at end of file diff --git a/designs/Caliptra/src/adams-bridge/ntt_masked_BFU_mult.sv b/designs/Caliptra/src/adams-bridge/ntt_masked_BFU_mult.sv new file mode 100644 index 0000000..ebc9627 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/ntt_masked_BFU_mult.sv @@ -0,0 +1,162 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +// +//====================================================================== +// +// ntt_masked_BFU_mult +// Performs two share multiplication and reduction - total latency = 210 clks +//====================================================================== + +module ntt_masked_BFU_mult + import ntt_defines_pkg::*; + import abr_params_pkg::*; +#( + parameter WIDTH = 46, + parameter HALF_WIDTH = WIDTH/2, + parameter ROLLER = WIDTH'(2**13-1) +) +( + input wire clk, + input wire reset_n, + input wire zeroize, + input wire [1:0][WIDTH-1:0] u, + input wire [1:0][WIDTH-1:0] v, + input wire [WIDTH-1:0] rnd0, rnd1, rnd2, rnd3, rnd4, + output logic [1:0] res [WIDTH-1:0] +); + + //Internal signals + logic [1:0] mul_res [WIDTH-1:0]; + logic [WIDTH-1:0] mul_res0, mul_res1, mul_res_combined, mul_res_combined_share0; + logic [1:0] mul_res_refresh [WIDTH-1:0]; + logic [1:0] mul_res_bool [WIDTH-1:0]; + logic [WIDTH-1:0] mul_res_bool0, mul_res_bool1; + logic [1:0][WIDTH-1:0] temp, final_res; + logic [1:0] mul_res_bool_reduced [HALF_WIDTH-1:0]; + logic [1:0] mul_res_bool_reduced_padded [WIDTH-1:0]; + logic [1:0] mul_res_reduced [WIDTH-1:0]; + logic [WIDTH-1:0] mul_res_bool_redux0, mul_res_bool_redux1, mul_res_redux0, mul_res_redux1; + + //Perform mul on input shares - 2 clk + abr_masked_N_bit_mult_two_share #( + .WIDTH(WIDTH) + ) masked_two_share_mult_inst ( + .clk(clk), + .rst_n(reset_n), + .zeroize(zeroize), + .random(rnd0), + .x(u), + .y(v), + .z(mul_res) + ); + + always_comb begin + for(int i = 0; i < WIDTH; i++) begin + mul_res0[i] = mul_res[i][0]; + mul_res1[i] = mul_res[i][1]; + end + mul_res_combined = (mul_res0 + mul_res1) % MLDSA_Q; + mul_res_combined_share0 = mul_res_combined - rnd0; + for (int i = 0; i < WIDTH; i++) begin + mul_res_refresh[i][0] = mul_res_combined_share0[i]; + mul_res_refresh[i][1] = rnd0[i]; + end + end + + //48 clks + abr_masked_A2B_conv #( + .WIDTH(WIDTH) + ) a2b_inst ( + .clk(clk), + .rst_n(reset_n), + .zeroize(zeroize), + .x(mul_res), + .rnd(rnd1), + .rnd_for_Boolean0(rnd2), + .rnd_for_Boolean1(rnd3), + .s(mul_res_bool) + ); + + //Mult reduction46 - 157 clks + ntt_masked_mult_redux46 #( + .WIDTH(WIDTH) + ) mult_redux46_inst ( + .clk(clk), + .rst_n(reset_n), + .zeroize(zeroize), + .rnd0_11(rnd0[10:0]), + .rnd1_11(rnd0[21:11]), + .rnd2_11(rnd0[32:22]), + .rnd0_12(rnd0[44:33]), + .rnd0_4(rnd1[3:0]), + .rnd0_14(rnd1[17:4]), + .rnd_3WIDTH({rnd4[HALF_WIDTH-1:0], rnd3[HALF_WIDTH-1:0], rnd2[HALF_WIDTH-1:0]}), + .x(mul_res_bool), + .y(mul_res_bool_reduced) + ); + + always_comb begin + for (int i = 0; i < HALF_WIDTH; i++) begin + mul_res_bool_reduced_padded[i][0] = mul_res_bool_reduced[i][0]; + mul_res_bool_reduced_padded[i][1] = mul_res_bool_reduced[i][1]; + end + for (int i = HALF_WIDTH; i < WIDTH; i++) begin + mul_res_bool_reduced_padded[i] = 2'b00; + end + end + + //B2A - 2 clks + abr_masked_B2A_conv #( + .WIDTH(WIDTH) + ) b2a_inst ( + .clk(clk), + .rst_n(reset_n), + .zeroize(zeroize), + .rnd(rnd0), + .x_boolean(mul_res_bool_reduced_padded), + .x_arith(mul_res_reduced) + ); + + always_comb begin + + for (int i = 0; i < WIDTH; i++) begin + mul_res_redux0[i] = mul_res_reduced[i][0]; + mul_res_redux1[i] = mul_res_reduced[i][1]; + end + end + + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) begin + for (int i = 0; i < WIDTH; i++) + res[i] <= 2'h0; + end + else if (zeroize) begin + for (int i = 0; i < WIDTH; i++) + res[i] <= 2'h0; + end + else begin + res <= mul_res_reduced; + end + end + + always_comb begin + for ( int i = 0; i < WIDTH; i++) begin + final_res[0][i] = res[i][0]; + final_res[1][i] = res[i][1]; + end + + end + + +endmodule \ No newline at end of file diff --git a/designs/Caliptra/src/adams-bridge/ntt_masked_butterfly1x2.sv b/designs/Caliptra/src/adams-bridge/ntt_masked_butterfly1x2.sv new file mode 100644 index 0000000..aa8c1ae --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/ntt_masked_butterfly1x2.sv @@ -0,0 +1,179 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +//====================================================================== +// +// ntt_masked_butterfly1x2.sv +// -------- +// 1. Performs 1st stage of masked INTT operation +// 2. Combines output shares +// 3. Performs div2 on combined outputs (unmasked) +// Total latency = 264 clks + +module ntt_masked_butterfly1x2 + import abr_params_pkg::*; + import ntt_defines_pkg::*; + #( + parameter WIDTH = 46, + parameter HALF_WIDTH = WIDTH/2 + ) + ( + input wire clk, + input wire reset_n, + input wire zeroize, + // input wire enable, + input masked_bf_uvwi_t uvw_i, + input [4:0][WIDTH-1:0] rnd_i, + input mode_t mode, + input accumulate, + + output bf_uvo_t uv_o, + output pwm_shares_uvo_t bf_pwm_uv_o + ); + + logic [1:0][WIDTH-1:0] u00, v00, w00; + logic [1:0][WIDTH-1:0] u01, v01, w01; + logic [1:0] u10_int [WIDTH-1:0]; + logic [1:0] v10_int [WIDTH-1:0]; + logic [1:0] u11_int [WIDTH-1:0]; + logic [1:0] v11_int [WIDTH-1:0]; + logic [1:0][WIDTH-1:0] u10_packed, v10_packed, u11_packed, v11_packed, u10_packed_reg, u11_packed_reg; + logic [HALF_WIDTH-1:0] u10_combined, v10_combined, u11_combined, v11_combined; + logic [HALF_WIDTH-1:0] u10_div2, v10_div2, u11_div2, v11_div2; + logic pwm_mode; + + always_comb begin + u00 = uvw_i.u00_i; + v00 = uvw_i.v00_i; + w00 = uvw_i.w00_i; + + u01 = uvw_i.u01_i; + v01 = uvw_i.v01_i; + w01 = uvw_i.w01_i; + + pwm_mode = (mode == pwm); + end + + //264 + ntt_masked_gs_butterfly #( + .WIDTH(WIDTH) + ) masked_bf_inst00 ( + .clk(clk), + .reset_n(reset_n), + .zeroize(zeroize), + .opu_i(u00), + .opv_i(v00), + .opw_i(w00), + .rnd_i({rnd_i[4], rnd_i[3], rnd_i[2], rnd_i[1], rnd_i[0]}), + .mode(mode), + .accumulate(accumulate), + .u_o(u10_int), + .v_o(v10_int) + ); + + ntt_masked_gs_butterfly #( + .WIDTH(WIDTH) + ) masked_bf_inst01 ( + .clk(clk), + .reset_n(reset_n), + .zeroize(zeroize), + .opu_i(u01), + .opv_i(v01), + .opw_i(w01), + .rnd_i({rnd_i[0], rnd_i[4], rnd_i[3], rnd_i[2], rnd_i[1]}), + .mode(mode), + .accumulate(accumulate), + .u_o(u11_int), + .v_o(v11_int) + ); + + always_comb begin + for (int i = 0; i < WIDTH; i++) begin + u10_packed[0][i] = u10_int[i][0]; + u10_packed[1][i] = u10_int[i][1]; + u11_packed[0][i] = u11_int[i][0]; + u11_packed[1][i] = u11_int[i][1]; + v10_packed[0][i] = v10_int[i][0]; + v10_packed[1][i] = v10_int[i][1]; + v11_packed[0][i] = v11_int[i][0]; + v11_packed[1][i] = v11_int[i][1]; + end + u10_combined = pwm_mode ? '0 : HALF_WIDTH'(u10_packed[0] + u10_packed[1]); + v10_combined = pwm_mode ? '0 : HALF_WIDTH'(v10_packed[0] + v10_packed[1]); + u11_combined = pwm_mode ? '0 : HALF_WIDTH'(u11_packed[0] + u11_packed[1]); + v11_combined = pwm_mode ? '0 : HALF_WIDTH'(v11_packed[0] + v11_packed[1]); + end + + //Perform div2 on combined outputs + ntt_div2 #( + .REG_SIZE(HALF_WIDTH), + .PRIME(abr_params_pkg::MLDSA_Q) + ) div2_inst0 ( + .op_i(u10_combined), + .res_o(u10_div2) + ); + + ntt_div2 #( + .REG_SIZE(HALF_WIDTH), + .PRIME(abr_params_pkg::MLDSA_Q) + ) div2_inst1 ( + .op_i(v10_combined), + .res_o(v10_div2) + ); + + ntt_div2 #( + .REG_SIZE(HALF_WIDTH), + .PRIME(abr_params_pkg::MLDSA_Q) + ) div2_inst2 ( + .op_i(u11_combined), + .res_o(u11_div2) + ); + + ntt_div2 #( + .REG_SIZE(HALF_WIDTH), + .PRIME(abr_params_pkg::MLDSA_Q) + ) div2_inst3 ( + .op_i(v11_combined), + .res_o(v11_div2) + ); + + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) begin + uv_o <= 'h0; + u10_packed_reg <= '0; + u11_packed_reg <= '0; + end + else if (zeroize) begin + uv_o <= 'h0; + u10_packed_reg <= '0; + u11_packed_reg <= '0; + end + else begin + uv_o.u20_o <= u10_div2; + uv_o.u21_o <= v10_div2; + uv_o.v20_o <= u11_div2; + uv_o.v21_o <= v11_div2; + u10_packed_reg <= u10_packed; + u11_packed_reg <= u11_packed; + end + end + + always_comb begin + bf_pwm_uv_o.uv0 = 0; //TODO: optimize + bf_pwm_uv_o.uv1 = 0; + bf_pwm_uv_o.uv2 = u10_packed; + bf_pwm_uv_o.uv3 = u11_packed; + end + + +endmodule \ No newline at end of file diff --git a/designs/Caliptra/src/adams-bridge/ntt_masked_gs_butterfly.sv b/designs/Caliptra/src/adams-bridge/ntt_masked_gs_butterfly.sv new file mode 100644 index 0000000..62385d3 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/ntt_masked_gs_butterfly.sv @@ -0,0 +1,200 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +//====================================================================== +// +// ntt_masked_gs_butterfly.sv +// -------- +// Only performs gs (INTT) mode of operation. All blocks are masked +// Latency = 264 clks + +module ntt_masked_gs_butterfly + import abr_params_pkg::*; + import ntt_defines_pkg::*; + #( + parameter WIDTH = 46, + parameter MASKED_ADD_SUB_LATENCY = 53 //Latency of add/sub block + ) + ( + input wire clk, + input wire reset_n, + input wire zeroize, + + input wire [1:0][WIDTH-1:0] opu_i, + input wire [1:0][WIDTH-1:0] opv_i, + input wire [1:0][WIDTH-1:0] opw_i, + input wire [4:0][WIDTH-1:0] rnd_i, + input mode_t mode, + input wire accumulate, + + output logic [1:0] u_o [WIDTH-1:0], + output logic [1:0] v_o [WIDTH-1:0] + ); + + logic [MASKED_ADD_SUB_LATENCY-1:0][1:0][WIDTH-1:0] w_reg; + logic [1:0] add_res [WIDTH-1:0]; + logic [1:0] sub_res [WIDTH-1:0]; + logic [1:0] mul_res [WIDTH-1:0]; + logic [1:0][WIDTH-1:0] sub_res_packed; + + logic [1:0] add_res_reg [WIDTH-1:0]; + logic [WIDTH-1:0] add_res_reg0, add_res_reg1; + + logic [WIDTH-1:0] add_res0, add_res1, mul_res0, mul_res1, mul_res0_reg, mul_res1_reg, u_o_0, u_o_1, v_o_0, v_o_1; + logic pwm_mode; + logic [1:0] u_o_reg [WIDTH-1:0]; + logic [1:0] v_o_reg [WIDTH-1:0]; + + assign pwm_mode = (mode == pwm); + + //MLDSA: 53 clks + //MLKEM: 21 clks + ntt_masked_BFU_add_sub #( + .WIDTH(WIDTH) + ) add_inst_0 ( + .clk(clk), + .reset_n(reset_n), + .zeroize(zeroize), + .sub(1'b0), + .u((pwm_mode & accumulate) ? {mul_res1_reg, mul_res0_reg} : opu_i), + .v((pwm_mode & accumulate) ? opw_i : opv_i), + .rnd0(rnd_i[0]), + .rnd1(rnd_i[1]), + .rnd2(rnd_i[2]), + .rnd3(rnd_i[3]), + .res(add_res) //pwm_mode & accumulate ? uv+w : u+v + ); + + abr_delay_masked_shares #( + .WIDTH(WIDTH), + .N(MASKED_PWM_LATENCY-1) //Inputs to BF multiplier are internal to this block. There's no input flop in the path, so latency is 1 clk less than the mult latency defined in the pkg + ) add_res_delay_inst ( + .clk(clk), + .rst_n(reset_n), + .zeroize(zeroize), + .input_reg(add_res), + .delayed_reg(add_res_reg) + ); + + //MLDSA: 53 clks + //MLKEM: 21 clks + ntt_masked_BFU_add_sub #( + .WIDTH(WIDTH) + ) sub_inst_0 ( + .clk(clk), + .reset_n(reset_n), + .zeroize(zeroize), + .sub(1'b1), + .u(opu_i), + .v(opv_i), + .rnd0(rnd_i[1]), //Different rand order + .rnd1(rnd_i[2]), + .rnd2(rnd_i[3]), + .rnd3(rnd_i[0]), + .res(sub_res) //u-v + ); + + always_comb begin + for (int i = 0; i < WIDTH; i++) begin + add_res0[i] = add_res[i][0]; + add_res1[i] = add_res[i][1]; + sub_res_packed[0][i] = sub_res[i][0]; + sub_res_packed[1][i] = sub_res[i][1]; + + add_res_reg0[i] = add_res_reg[i][0]; + add_res_reg1[i] = add_res_reg[i][1]; + end + end + + //w delay flops + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) begin + for (int i = 0; i < MASKED_ADD_SUB_LATENCY; i++) begin + w_reg[i] <= 'h0; + end + end + else if (zeroize) begin + for (int i = 0; i < MASKED_ADD_SUB_LATENCY; i++) begin + w_reg[i] <= 'h0; + end + end + else begin + w_reg <= {opw_i, w_reg[MASKED_ADD_SUB_LATENCY-1:1]}; + end + end + + //MLDSA: 210 clks + ntt_masked_BFU_mult #( + .WIDTH(WIDTH) + ) mult_inst_0 ( + .clk(clk), + .reset_n(reset_n), + .zeroize(zeroize), + .u(pwm_mode ? opu_i : sub_res_packed), + .v(pwm_mode ? opv_i : w_reg[0]), + .rnd0(rnd_i[2]), + .rnd1(rnd_i[3]), + .rnd2(rnd_i[0]), + .rnd3(rnd_i[1]), + .rnd4(WIDTH'(rnd_i[2]+rnd_i[3])), + .res(mul_res) + ); + + always_comb begin + for (int i = 0; i < WIDTH; i++) begin + mul_res0[i] = mul_res[i][0]; + mul_res1[i] = mul_res[i][1]; + end + end + + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) begin + for (int i = 0; i < WIDTH; i++) begin + u_o_reg[i] <= 2'b0; + v_o_reg[i] <= 2'b0; + mul_res0_reg[i] <= '0; + mul_res1_reg[i] <= '0; + end + end + else if (zeroize) begin + for (int i = 0; i < WIDTH; i++) begin + u_o_reg[i] <= 2'b0; + v_o_reg[i] <= 2'b0; + mul_res0_reg[i] <= '0; + mul_res1_reg[i] <= '0; + end + end + else begin + for (int i =0; i < WIDTH; i++) begin + mul_res0_reg[i] <= mul_res0[i]; + mul_res1_reg[i] <= mul_res1[i]; + end + u_o_reg <= add_res_reg; + v_o_reg <= mul_res; + end + end + + always_comb begin + for (int i = 0; i < WIDTH; i++) begin + u_o[i] = pwm_mode ? accumulate ? add_res[i] : mul_res[i] : u_o_reg[i]; + v_o[i] = pwm_mode ? 2'b0 : v_o_reg[i]; + + u_o_0[i] = u_o[i][0]; + u_o_1[i] = u_o[i][1]; + + v_o_0[i] = v_o[i][0]; + v_o_1[i] = v_o[i][1]; + end + end + +endmodule diff --git a/designs/Caliptra/src/adams-bridge/ntt_masked_mult_redux46.sv b/designs/Caliptra/src/adams-bridge/ntt_masked_mult_redux46.sv new file mode 100644 index 0000000..9cba899 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/ntt_masked_mult_redux46.sv @@ -0,0 +1,481 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +// +//====================================================================== +// +// ntt_masked_mult_redux46 +// Performs masked multiplication reduction for MLDSA +// It has 157 Cycle Latency +//====================================================================== + +module ntt_masked_mult_redux46 + import ntt_defines_pkg::*; + import abr_params_pkg::*; +#( + parameter WIDTH = 46 +) +( + input wire clk, + input wire rst_n, + input wire zeroize, + input wire [10:0] rnd0_11, + input wire [10:0] rnd1_11, + input wire [10:0] rnd2_11, + input wire [11:0] rnd0_12, + input wire [3:0] rnd0_4, + input wire [13:0] rnd0_14, + input wire [3*(WIDTH/2)-1:0] rnd_3WIDTH, + input wire [1:0] x [WIDTH-1:0], + output logic [1:0] y [WIDTH/2-1:0] +); + + // Intermediate wires for the sliced values + logic [4:0] cnt; + logic [1:0] z_45_23 [22:0]; + logic [1:0] z_45_23_delayed [22:0]; + logic [1:0] z_45_33 [13:0]; + logic [1:0] z_45_33_delayed [13:0]; + logic [1:0] z_45_43 [3:0]; + logic [1:0] z_45_43_delayed [3:0]; + logic [1:0] z_45_43_padded_8 [10:0]; + logic [1:0] z_12_0 [12:0]; + logic [1:0] z_12_0_delayed [12:0]; + logic [1:0] z_22_13 [10:0]; + logic [1:0] z_32_23 [10:0]; + logic [1:0] z_42_33 [10:0]; + + logic [1:0] tmp [10:0]; + logic [1:0] tmp_padded [11:0]; + logic [1:0] tmp0 [10:0]; + logic [1:0] tmp0_padded [11:0]; + logic [1:0] c0_11 [11:0]; + logic [1:0] c11_10 [1:0]; + logic [1:0] c11_10_padded_9 [10:0]; + logic [1:0] c11_10_padded_2 [3:0]; + logic [1:0] c9_0 [9:0]; + logic [1:0] c9_0_padded [10:0]; + + logic [1:0] d10_0 [10:0]; + logic [1:0] d22_0 [22:0]; + logic [1:0] d22_0_delayed [22:0]; + + + logic [1:0] f3_0 [3:0]; + logic [1:0] f3_0_padded_10 [13:0]; + logic [1:0] f13_0 [13:0]; + logic [1:0] f13_0_padded_9 [22:0]; + + + logic [1:0] e22_0 [22:0]; + + // Use always_comb block to split x into various z arrays using for loops + always_comb begin + // Counter for z_45_23 + cnt = 0; + for (int i = 23; i <= 45; i = i + 1) begin + z_45_23[cnt] = x[i]; + cnt = cnt + 1; + end + + // Counter for z_45_33 + cnt = 0; + for (int i = 33; i <= 45; i = i + 1) begin + z_45_33[cnt[3:0]] = x[i]; + cnt = cnt + 1; + end + z_45_33[13] = 2'b00; + + // Counter for z_45_43 + cnt = 0; + for (int i = 43; i <= 45; i = i + 1) begin + z_45_43[cnt[1:0]] = x[i]; + z_45_43_padded_8[cnt[3:0]] = x[i]; + cnt = cnt + 1; + end + z_45_43[3] = 2'b00; + z_45_43_padded_8[3] = 2'b00; + for (int i = 0; i < 7; i = i + 1) //i < 8 + z_45_43_padded_8[i+4] = 2'b00; + + // Counter for z_12_0 + cnt = 0; + for (int i = 0; i <= 12; i = i + 1) begin + z_12_0[cnt[3:0]] = x[i]; + cnt = cnt + 1; + end + + // Counter for z_22_13 + cnt = 0; + for (int i = 13; i <= 22; i = i + 1) begin + z_22_13[cnt[3:0]] = x[i]; + cnt = cnt + 1; + end + z_22_13[10] = 2'b00; + + // Counter for z_32_23 + cnt = 0; + for (int i = 23; i <= 32; i = i + 1) begin + z_32_23[cnt[3:0]] = x[i]; + cnt = cnt + 1; + end + z_32_23[10] = 2'b00; + + // Counter for z_42_33 + cnt = 0; + for (int i = 33; i <= 42; i = i + 1) begin + z_42_33[cnt[3:0]] = x[i]; + cnt = cnt + 1; + end + z_42_33[10] = 2'b00; + + cnt = 0; + for (int i = 10; i <= 11; i = i + 1) begin + c11_10[cnt[0]] = c0_11[i]; + c11_10_padded_9[cnt[3:0]] = c0_11[i]; + c11_10_padded_2[cnt[1:0]] = c0_11[i]; + cnt = cnt + 1; + end + c11_10_padded_2[2] = 2'b00; + c11_10_padded_2[3] = 2'b00; + for (int i = 0; i < 9; i = i + 1) + c11_10_padded_9[i+2] = 2'b00; + + cnt = 0; + for (int i = 0; i <= 9; i = i + 1) begin + c9_0[cnt[3:0]] = c0_11[i]; + c9_0_padded[cnt[3:0]] = c0_11[i]; + cnt = cnt + 1; + end + c9_0_padded[10] = 2'b00; + + + for (int i = 0; i < 4; i = i + 1) + f3_0_padded_10[i] = f3_0[i]; + for (int i = 0; i < 10; i = i + 1) + f3_0_padded_10[i+4] = 2'b00; + + for (int i = 0; i < 14; i = i + 1) + f13_0_padded_9[i] = f13_0[i]; + for (int i = 0; i < 9; i = i + 1) + f13_0_padded_9[i+14] = 2'b00; + + for (int i = 0; i < 11; i = i + 1) begin + tmp_padded[i] = tmp[i]; + tmp0_padded[i] = tmp0[i]; + end + tmp_padded[11] = 2'b00; + tmp0_padded[11] = 2'b00; + end + + // Cycle 0 to 12 + abr_masked_N_bit_Boolean_adder #( + .WIDTH(11) + ) bool_adder_22_13_and_32_23 ( + .clk(clk), + .rst_n(rst_n), + .zeroize(zeroize), + .x(z_22_13), + .y(z_32_23), + .rnd(rnd0_11), + .s(tmp) + ); + + // Cycle 0 to 12 + abr_masked_N_bit_Boolean_adder #( + .WIDTH(11) + ) bool_adder_45_43_and_42_33 ( + .clk(clk), + .rst_n(rst_n), + .zeroize(zeroize), + .x(z_42_33), + .y(z_45_43_padded_8), + .rnd(rnd1_11), + .s(tmp0) + ); + + // Cycle 12+1 to 26 + abr_masked_N_bit_Boolean_adder #( + .WIDTH(12) + ) bool_adder_tmp_and_tmp0 ( + .clk(clk), + .rst_n(rst_n), + .zeroize(zeroize), + .x(tmp_padded), + .y(tmp0_padded), + .rnd(rnd0_12), + .s(c0_11) + ); + + + // Cycle 26+1 to 39 + abr_masked_N_bit_Boolean_adder #( + .WIDTH(11) + ) bool_adder_c0_9_and_c11_10 ( + .clk(clk), + .rst_n(rst_n), + .zeroize(zeroize), + .x(c11_10_padded_9), + .y(c9_0_padded), + .rnd(rnd2_11), + .s(d10_0) + ); + + // Cycle 0 to 40 + abr_delay_masked_shares #( + .WIDTH(13), + .N(40) // Delays 36 cycles + ) delay_z12_0 ( + .clk(clk), + .rst_n(rst_n), + .zeroize(zeroize), + .input_reg(z_12_0), + .delayed_reg(z_12_0_delayed) + ); + + //28 cycles + ntt_masked_special_adder add_with_conc_d10_and_z12( + .clk(clk), + .rst_n(rst_n), + .zeroize(zeroize), + .rnd(rnd_3WIDTH), + .d10_0(d10_0), + .z_12_0(z_12_0_delayed), + .res_o_masked(d22_0) + ); + + // Cycle 0 to 26+1 + abr_delay_masked_shares #( + .WIDTH(4), + .N(27) // Delays 36 cycles + ) delay_z_45_43 ( + .clk(clk), + .rst_n(rst_n), + .zeroize(zeroize), + .input_reg(z_45_43), + .delayed_reg(z_45_43_delayed) + ); + + // Cycle 26 to 33 + abr_masked_N_bit_Boolean_adder #( + .WIDTH(4) + ) bool_adder_c11_10_and_z_45_43 ( + .clk(clk), + .rst_n(rst_n), + .zeroize(zeroize), + .x(c11_10_padded_2), + .y(z_45_43_delayed), + .rnd(rnd0_4), + .s(f3_0) + ); + + + // Cycle 0 to 33 + abr_delay_masked_shares #( + .WIDTH(14), + .N(33) // Delays 36 cycles + ) delay_z_45_33 ( + .clk(clk), + .rst_n(rst_n), + .zeroize(zeroize), + .input_reg(z_45_33), + .delayed_reg(z_45_33_delayed) + ); + + // Cycle 33 to 48 + abr_masked_N_bit_Boolean_adder #( + .WIDTH(14) + ) bool_adder_c11_10_and_z_45_33 ( + .clk(clk), + .rst_n(rst_n), + .zeroize(zeroize), + .x(f3_0_padded_10), + .y(z_45_33_delayed), + .rnd(rnd0_14), + .s(f13_0) + ); + + // Cycle 0 to 48+1 + abr_delay_masked_shares #( + .WIDTH(23), + .N(49) // Delays 36 cycles + ) delay_z_45_23 ( + .clk(clk), + .rst_n(rst_n), + .zeroize(zeroize), + .input_reg(z_45_23), + .delayed_reg(z_45_23_delayed) + ); + + //54 cycles + abr_masked_add_sub_mod_Boolean mod_adder_z_45_23_and_f13_0 ( + .clk(clk), + .rst_n(rst_n), + .zeroize(zeroize), + .rnd(rnd_3WIDTH), + .sub_i (1'b0), + .opa_i_masked(z_45_23_delayed), + .opb_i_masked(f13_0_padded_9), + .res_o_masked(e22_0) + ); + + // Cycle 39 to 94 + abr_delay_masked_shares #( + .WIDTH(23), + .N(35) // Delays 34 cycles + ) delay_d_22_0 ( + .clk(clk), + .rst_n(rst_n), + .zeroize(zeroize), + .input_reg(d22_0), + .delayed_reg(d22_0_delayed) + ); + + //54 cycles + abr_masked_add_sub_mod_Boolean mod_adder_d22_0_and_e22_0 ( + .clk(clk), + .rst_n(rst_n), + .zeroize(zeroize), + .rnd(rnd_3WIDTH), + .sub_i (1'b1), + .opa_i_masked(d22_0_delayed), + .opb_i_masked(e22_0), + .res_o_masked(y) + ); + + +endmodule: ntt_masked_mult_redux46 + + + + +// module abr_masked_add_sub_mod_Boolean #( +// parameter WIDTH = 23, +// parameter PRIME = 23'd8380417 +// ) +// ( +// // Clock and reset. +// input wire clk, +// input wire rst_n, +// input wire zeroize, +// input logic [3*WIDTH-1:0] rnd, + +// input wire sub_i, +// input wire [1:0] opa_i_masked [WIDTH-1:0], +// input wire [1:0] opb_i_masked [WIDTH-1:0], +// output logic [1:0] res_o_masked [WIDTH-1:0] +// ); + + +// // The rest of your variables +// logic [1:0] opa_i_masked_padded [WIDTH:0]; +// logic [1:0] opb_i_masked_padded [WIDTH:0]; +// logic [1:0] opa_2_masked_padded [WIDTH:0]; +// logic [1:0] prime [WIDTH:0]; +// logic [1:0] r0_c0 [WIDTH:0]; +// logic [1:0] r1_c1 [WIDTH:0]; +// logic [1:0] r0_c0_delayed [WIDTH:0]; + +// // Reconstruct unmasked inputs and prepare padded masked operands +// always_comb begin +// for (int i = 0; i < WIDTH; i = i + 1) begin +// // Combine the masked shares to get unmasked values +// opa_i_masked_padded[i] = opa_i_masked[i]; +// // Prepare padded masked operands +// if (sub_i) begin +// opb_i_masked_padded[i][0] = opb_i_masked[i][0]; +// opb_i_masked_padded[i][1] = ~opb_i_masked[i][1]; +// prime[i] = {1'b0, PRIME[i]}; +// end +// else begin +// opb_i_masked_padded[i] = opb_i_masked[i]; +// prime[i] = {1'b0, ~PRIME[i]}; +// end + +// end +// // Padded bits +// opa_i_masked_padded[WIDTH] = 2'b00; +// opb_i_masked_padded[WIDTH] = 2'b00; +// prime[WIDTH] = 2'b00; +// end + +// // Assign opa_2_masked_padded after r0_c0 is available +// always_comb begin +// for (int i = 0; i < WIDTH; i = i + 1) begin +// opa_2_masked_padded[i] = r0_c0[i]; +// end +// opa_2_masked_padded[WIDTH] = 2'b00; +// end + +// // Instantiate the masked subtractor +// abr_masked_N_bit_Boolean_sub #( +// .WIDTH(WIDTH+1) +// ) r0_sub_or_add ( +// .clk(clk), +// .rst_n(rst_n), +// .zeroize(zeroize), +// .sub_i(sub_i), +// .x(opa_i_masked_padded), +// .y(opb_i_masked_padded), +// .rnd(rnd[WIDTH:0]), +// .s(r0_c0) +// ); + + +// // Delay the masked outputs +// abr_delay_masked_shares #( +// .WIDTH(WIDTH+1), +// .N(WIDTH+3) // Delays 26 cycles +// ) delay_r0_c0 ( +// .clk(clk), +// .rst_n(rst_n), +// .zeroize(zeroize), +// .input_reg(r0_c0), +// .delayed_reg(r0_c0_delayed) +// ); + + +// // Instantiate the masked adder +// abr_masked_N_bit_Boolean_sub #( +// .WIDTH(WIDTH+1) +// ) r1_sub_or_add ( +// .clk(clk), +// .rst_n(rst_n), +// .zeroize(zeroize), +// .sub_i(~sub_i), +// .x(opa_2_masked_padded), +// .y(prime), +// .rnd(rnd[WIDTH:0]), +// .s(r1_c1) +// ); + +// // Instantiate the masked MUX +// abr_masked_MUX #( +// .WIDTH(WIDTH) +// ) r0_MUX_r0 ( +// .clk(clk), +// .rst_n(rst_n), +// .zeroize(zeroize), +// .sub_i(sub_i), +// .carry0(r0_c0_delayed[WIDTH]), +// .carry1(r1_c1[WIDTH]), +// .r0(r0_c0_delayed[WIDTH-1:0]), +// .r1(r1_c1[WIDTH-1:0]), +// .rnd_xor(rnd[WIDTH*2-1:WIDTH]), +// .rnd_and(rnd[WIDTH*3-1:2*WIDTH]), +// .res_o_masked(res_o_masked) +// ); + +// endmodule + + diff --git a/designs/Caliptra/src/adams-bridge/ntt_masked_pairwm.sv b/designs/Caliptra/src/adams-bridge/ntt_masked_pairwm.sv new file mode 100644 index 0000000..1e4d545 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/ntt_masked_pairwm.sv @@ -0,0 +1,345 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +// +//====================================================================== +// +// ntt_masked_pairwm.sv +// -------- +// This module performs masked pwm operation with or without accumulate +// on input shares. Always performs (u*v)+w (top level needs to drive 0 +// to the w input if not in accumulate mode) +// latency with accumulate: 24 clks +// latency without accumulate: 23 clks + +module ntt_masked_pairwm + import abr_params_pkg::*; + import ntt_defines_pkg::*; +#( + parameter MASKED_WIDTH = 2 * MLKEM_Q_WIDTH +) +( + input wire clk, + input wire reset_n, + input wire zeroize, + input wire accumulate, + input wire [1:0][MASKED_WIDTH-1:0] u0, + input wire [1:0][MASKED_WIDTH-1:0] v0, + input wire [1:0][MASKED_WIDTH-1:0] w0, + input wire [1:0][MASKED_WIDTH-1:0] u1, + input wire [1:0][MASKED_WIDTH-1:0] v1, + input wire [1:0][MASKED_WIDTH-1:0] w1, + input wire [1:0][MASKED_WIDTH-1:0] zeta, + input wire [4:0][13:0] rnd, + input wire [MASKED_WIDTH-1:0] rnd_24bit, + output logic [1:0][MASKED_WIDTH-1:0] res0, + output logic [1:0][MASKED_WIDTH-1:0] res1 +); + +//Multiply results +logic [1:0] u0v0 [MASKED_WIDTH-1:0]; +logic [1:0] u0v1 [MASKED_WIDTH-1:0]; +logic [1:0] u1v0 [MASKED_WIDTH-1:0]; +logic [1:0] zeta_v1 [MASKED_WIDTH-1:0]; +logic [1:0] u1v1 [MASKED_WIDTH-1:0]; +logic [1:0][MASKED_WIDTH-1:0] u0v0_packed, u0v1_packed, u1v0_packed, zeta_v1_packed, u1v1_packed; + +//Reduction results +logic [1:0][MASKED_WIDTH-1:0] u0v0_reduced, u0v1_reduced, u1v0_reduced, zeta_v1_reduced, u1v1_reduced, uv0_reduced, uv1_reduced; +logic [1:0][MASKED_WIDTH-1:0] uv0, uv1; +logic [1:0][MASKED_WIDTH-1:0] uvw0, uvw1; + +//Delay regs +logic [MLKEM_MASKED_MULT_LATENCY-1:0][1:0][MASKED_WIDTH-1:0] u1_reg; +logic [MLKEM_MASKED_MULT_LATENCY-1:0][1:0][MASKED_WIDTH-1:0] u0v0_reduced_reg; +logic [MLKEM_MASKED_MULT_LATENCY-1:0][1:0][MASKED_WIDTH-1:0] u0v1_reduced_reg; +logic [MLKEM_MASKED_MULT_LATENCY-1:0][1:0][MASKED_WIDTH-1:0] u1v0_reduced_reg; + +always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) begin + for (int i = 0; i < MLKEM_MASKED_MULT_LATENCY; i++) begin + u1_reg[i] <= '0; + u0v0_reduced_reg[i] <= '0; + u0v1_reduced_reg[i] <= '0; + u1v0_reduced_reg[i] <= '0; + end + end + else if (zeroize) begin + for (int i = 0; i < MLKEM_MASKED_MULT_LATENCY; i++) begin + u1_reg[i] <= '0; + u0v0_reduced_reg[i] <= '0; + u0v1_reduced_reg[i] <= '0; + u1v0_reduced_reg[i] <= '0; + end + end + else begin + u1_reg <= {u1, u1_reg[MLKEM_MASKED_MULT_LATENCY-1:1]}; + u0v0_reduced_reg <= {u0v0_reduced, u0v0_reduced_reg[MLKEM_MASKED_MULT_LATENCY-1:1]}; + u0v1_reduced_reg <= {u0v1_reduced, u0v1_reduced_reg[MLKEM_MASKED_MULT_LATENCY-1:1]}; + u1v0_reduced_reg <= {u1v0_reduced, u1v0_reduced_reg[MLKEM_MASKED_MULT_LATENCY-1:1]}; + end +end + +//u0 * v0 - 2 clk +abr_masked_N_bit_mult_two_share #( + .WIDTH(MASKED_WIDTH) +) masked_mult_u0_v0 ( + .clk(clk), + .rst_n(reset_n), + .zeroize(zeroize), + .random(MASKED_WIDTH'(rnd[1:0])), + .x(u0), + .y(v0), + .z(u0v0) +); + +always_comb begin + for (int i = 0; i < MASKED_WIDTH; i++) begin + u0v0_packed[0][i] = u0v0[i][0]; + u0v0_packed[1][i] = u0v0[i][1]; + end +end + +//6 clk +masked_barrett_reduction masked_u0v0_redux_inst ( + .clk(clk), + .rst_n(reset_n), + .zeroize(zeroize), + .x(u0v0_packed), + .rnd_12bit(rnd[0][11:0]), + .rnd_14bit(rnd[1][13:0]), + .rnd_24bit(rnd_24bit), + .rnd_for_Boolean0(rnd[2][13:0]), + .rnd_for_Boolean1(rnd[3][13:0]), + .rnd_1bit(rnd[0][12]), + .y(u0v0_reduced) +); + +//-------------------------------------- +//u0 * v1 +abr_masked_N_bit_mult_two_share #( + .WIDTH(MASKED_WIDTH) +) masked_mult_u0_v1 ( + .clk(clk), + .rst_n(reset_n), + .zeroize(zeroize), + .random(MASKED_WIDTH'(rnd[2:1])), + .x(u0), + .y(v1), + .z(u0v1) +); + +always_comb begin + for (int i = 0; i < MASKED_WIDTH; i++) begin + u0v1_packed[0][i] = u0v1[i][0]; + u0v1_packed[1][i] = u0v1[i][1]; + end +end + +masked_barrett_reduction masked_u0v1_redux_inst ( + .clk(clk), + .rst_n(reset_n), + .zeroize(zeroize), + .x(u0v1_packed), + .rnd_12bit(rnd[1][11:0]), + .rnd_14bit(rnd[2][13:0]), + .rnd_24bit(rnd_24bit), + .rnd_for_Boolean0(rnd[3][13:0]), + .rnd_for_Boolean1(rnd[4][13:0]), + .rnd_1bit(rnd[0][13]), + .y(u0v1_reduced) +); + +//-------------------------------------- +//u1 * v0 +abr_masked_N_bit_mult_two_share #( + .WIDTH(MASKED_WIDTH) +) masked_mult_u1_v0 ( + .clk(clk), + .rst_n(reset_n), + .zeroize(zeroize), + .random(MASKED_WIDTH'(rnd[3:2])), + .x(u1), + .y(v0), + .z(u1v0) +); + +always_comb begin + for (int i = 0; i < MASKED_WIDTH; i++) begin + u1v0_packed[0][i] = u1v0[i][0]; + u1v0_packed[1][i] = u1v0[i][1]; + end +end + +masked_barrett_reduction masked_u1v0_redux_inst ( + .clk(clk), + .rst_n(reset_n), + .zeroize(zeroize), + .x(u1v0_packed), + .rnd_12bit(rnd[2][11:0]), + .rnd_14bit(rnd[3][13:0]), + .rnd_24bit(rnd_24bit), + .rnd_for_Boolean0(rnd[4][13:0]), + .rnd_for_Boolean1(rnd[0][13:0]), + .rnd_1bit(rnd[1][0]), + .y(u1v0_reduced) +); + +//-------------------------------------- +//zeta * v1 +abr_masked_N_bit_mult_two_share #( + .WIDTH(MASKED_WIDTH) +) masked_mult_zeta_v1 ( + .clk(clk), + .rst_n(reset_n), + .zeroize(zeroize), + .random(MASKED_WIDTH'(rnd[4:3])), + .x(zeta), + .y(v1), + .z(zeta_v1) +); + +always_comb begin + for (int i = 0; i < MASKED_WIDTH; i++) begin + zeta_v1_packed[0][i] = zeta_v1[i][0]; + zeta_v1_packed[1][i] = zeta_v1[i][1]; + end +end + +masked_barrett_reduction masked_zeta_v1_redux_inst ( + .clk(clk), + .rst_n(reset_n), + .zeroize(zeroize), + .x(zeta_v1_packed), + .rnd_12bit(rnd[3][11:0]), + .rnd_14bit(rnd[4][13:0]), + .rnd_24bit(rnd_24bit), + .rnd_for_Boolean0(rnd[0][13:0]), + .rnd_for_Boolean1(rnd[1][13:0]), + .rnd_1bit(rnd[2][0]), + .y(zeta_v1_reduced) +); + +//-------------------------------------- +//u1 * (zeta * v1) +abr_masked_N_bit_mult_two_share #( + .WIDTH(MASKED_WIDTH) +) masked_mult_u1v1 ( + .clk(clk), + .rst_n(reset_n), + .zeroize(zeroize), + .random(MASKED_WIDTH'(rnd[1:0])), + .x(u1_reg[0]), //delayed by 25 clks + .y(zeta_v1_reduced), + .z(u1v1) +); + +always_comb begin + for (int i = 0; i < MASKED_WIDTH; i++) begin + u1v1_packed[0][i] = u1v1[i][0]; + u1v1_packed[1][i] = u1v1[i][1]; + end +end + +masked_barrett_reduction masked_u1v1_redux_inst ( + .clk(clk), + .rst_n(reset_n), + .zeroize(zeroize), + .x(u1v1_packed), + .rnd_12bit(rnd[4][11:0]), + .rnd_14bit(rnd[0][13:0]), + .rnd_24bit(rnd_24bit), + .rnd_for_Boolean0(rnd[1][13:0]), + .rnd_for_Boolean1(rnd[2][13:0]), + .rnd_1bit(rnd[3][0]), + .y(u1v1_reduced) +); + +//-------------------------------------- +//Compute coefficients - 1 clk +abr_masked_N_bit_Arith_adder #( + .WIDTH(MASKED_WIDTH) +) masked_uv0_coeff_adder_inst ( + .clk(clk), + .rst_n(reset_n), + .zeroize(zeroize), + .x(u0v0_reduced_reg[0]), //delayed by 25 clks + .y(u1v1_reduced), + .s(uv0) +); + +abr_masked_N_bit_Arith_adder #( + .WIDTH(MASKED_WIDTH) +) masked_uv1_coeff_adder_inst ( + .clk(clk), + .rst_n(reset_n), + .zeroize(zeroize), + .x(u0v1_reduced_reg[0]), + .y(u1v0_reduced_reg[0]), + .s(uv1) +); + +//-------------------------------------- +//Accumulation - 1 clk +abr_masked_N_bit_Arith_adder #( + .WIDTH(MASKED_WIDTH) +) masked_uv0w0_acc_adder_inst ( + .clk(clk), + .rst_n(reset_n), + .zeroize(zeroize), + .x(uv0), + .y(w0), + .s(uvw0) +); + +//6 clks +masked_barrett_reduction masked_uvw0_redux_inst ( + .clk(clk), + .rst_n(reset_n), + .zeroize(zeroize), + .x(accumulate ? uvw0 : uv0), + .rnd_12bit(rnd[0][11:0]), + .rnd_14bit(rnd[1][13:0]), + .rnd_24bit(rnd_24bit), + .rnd_for_Boolean0(rnd[2][13:0]), + .rnd_for_Boolean1(rnd[3][13:0]), + .rnd_1bit(rnd[4][0]), + .y(res0) +); + +abr_masked_N_bit_Arith_adder #( + .WIDTH(MASKED_WIDTH) +) masked_uv1w1_acc_adder_inst ( + .clk(clk), + .rst_n(reset_n), + .zeroize(zeroize), + .x(uv1), + .y(w1), + .s(uvw1) +); + +masked_barrett_reduction masked_uvw1_redux_inst ( + .clk(clk), + .rst_n(reset_n), + .zeroize(zeroize), + .x(accumulate ? uvw1 : uv1), + .rnd_12bit(rnd[1][11:0]), + .rnd_14bit(rnd[2][13:0]), + .rnd_24bit(rnd_24bit), + .rnd_for_Boolean0(rnd[3][13:0]), + .rnd_for_Boolean1(rnd[4][13:0]), + .rnd_1bit(rnd[0][0]), + .y(res1) +); + +endmodule \ No newline at end of file diff --git a/designs/Caliptra/src/adams-bridge/ntt_masked_pwm.sv b/designs/Caliptra/src/adams-bridge/ntt_masked_pwm.sv new file mode 100644 index 0000000..ae3b1cb --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/ntt_masked_pwm.sv @@ -0,0 +1,108 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +// +//====================================================================== +// +// ntt_masked_pwm.sv +// -------- +// This module performs masked pwm operation with or without accumulate +// on input shares. Always performs (u*v)+w (top level needs to drive 0 +// to the w input if not in accumulate mode) +// 210 clks if PWM, 264 clks if PWMA + +module ntt_masked_pwm + import abr_params_pkg::*; + import ntt_defines_pkg::*; +#( + parameter WIDTH = 46 +) +( + input wire clk, + input wire reset_n, + input wire zeroize, + input wire accumulate, + input wire [1:0][WIDTH-1:0] u, + input wire [1:0][WIDTH-1:0] v, + input wire [1:0][WIDTH-1:0] w, + input wire [4:0][WIDTH-1:0] rnd, + output logic [1:0][WIDTH-1:0] res +); + + logic [1:0] mul_res [WIDTH-1:0]; + logic [1:0][WIDTH-1:0] w_reg; + + logic [1:0][WIDTH-1:0] mul_res_packed; + logic [1:0] res_unpacked [WIDTH-1:0]; + + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) begin + mul_res_packed <= '0; + w_reg <= '0; + end + else if (zeroize) begin + mul_res_packed <= '0; + w_reg <= '0; + end + else begin + for (int i = 0; i < WIDTH; i++) begin + mul_res_packed[0][i] <= mul_res[i][0]; + mul_res_packed[1][i] <= mul_res[i][1]; + end + + w_reg <= w; + end + end + + //210 clks + ntt_masked_BFU_mult #( + .WIDTH(WIDTH) + ) mult_inst0 ( + .clk(clk), + .reset_n(reset_n), + .zeroize(zeroize), + .u(u), + .v(v), + .rnd0(rnd[0]), + .rnd1(rnd[1]), + .rnd2(rnd[2]), + .rnd3(rnd[3]), + .rnd4(rnd[4]), + .res(mul_res) + ); + + //53 clks (accumulate case) + ntt_masked_BFU_add_sub #( + .WIDTH(WIDTH) + ) add_inst0 ( + .clk(clk), + .reset_n(reset_n), + .zeroize(zeroize), + .sub(1'b0), + .u(mul_res_packed), + .v(w), + .rnd0(rnd[0]), + .rnd1(rnd[1]), + .rnd2(rnd[2]), + .rnd3(rnd[3]), + .res(res_unpacked) + ); + + always_comb begin + for (int i = 0; i < WIDTH; i++) begin + res[0][i] = accumulate ? res_unpacked[i][0] : mul_res[i][0]; + res[1][i] = accumulate ? res_unpacked[i][1] : mul_res[i][1]; + end + end + +endmodule \ No newline at end of file diff --git a/designs/Caliptra/src/adams-bridge/ntt_masked_special_adder.sv b/designs/Caliptra/src/adams-bridge/ntt_masked_special_adder.sv new file mode 100644 index 0000000..f20cb42 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/ntt_masked_special_adder.sv @@ -0,0 +1,109 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +// +//====================================================================== +// +// ntt_masked_special_adder.sv +// -------- +// Special modular addtion module to compute opa+-opb % prime +// to be used special multreduction module, but with masking method. +// +// +//====================================================================== + +module ntt_masked_special_adder #( + parameter WIDTH = 23, + parameter WIDTH2 = 11, + parameter WIDTH3 = 13, + parameter PRIME = 23'd8380417 + ) + ( + // Clock and reset. + input wire clk, + input wire rst_n, + input wire zeroize, + input logic [3*WIDTH-1:0] rnd, + + input wire [1:0] d10_0 [WIDTH2-1:0], + input wire [1:0] z_12_0 [WIDTH3-1:0], + output logic [1:0] res_o_masked [WIDTH-1:0] +); + + + logic [1:0] opa_2_masked_padded [WIDTH:0]; + logic [1:0] prime [WIDTH:0]; + logic [1:0] r0_c0 [WIDTH:0]; + logic [1:0] r1_c1 [WIDTH:0]; + logic [1:0] r0_c0_delayed [WIDTH:0]; + + always_comb begin + for (int i = 0; i buffer contains data read from memory before it's consumed by BF2x2 +// INTT mode --> buffer contains data from BF2x2 to be written to memory + +// This buffer is customized to support shuffling countermeasure for NTT. It's an +// addressable buffer with the following attributes: +// NTT mode --> writes to buffer are in order. Starting read addr is randomized +// INTT mode --> Starting write addr is randomized. Reads from buffer are in order + +module ntt_shuffle_buffer + import abr_params_pkg::*; + import ntt_defines_pkg::*; + #( + parameter REG_SIZE = 24 + ) + ( + input wire clk, + input wire reset_n, + input wire zeroize, + input mode_t mode, + input wire shuffle_en, + input wire wren, + input wire rden, + input wire [1:0] wrptr, + input wire [1:0] rdptr, + input wire wr_rst_count, + // input wire rd_rst_count, + input wire [(4*REG_SIZE)-1:0] data_i, + output logic buf_valid, + output logic [(4*REG_SIZE)-1:0] data_o + ); + + //buffer*[0] is lo, buffer*[1] is hi + logic [1:0][3:0][3:0][REG_SIZE-1:0] buffer; //2x4x4 buffer [lo_hi][] + + logic [1:0] data_i_count, data_i_count_reg; + logic lo_hi, lo_hi_reg, lo_hi_rd; //0 - lo, 1 - hi + + //Write + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) begin + buffer <= 'h0; + end + else if (zeroize) begin + buffer <= 'h0; + end + else if (wren) begin + buffer[lo_hi][wrptr] <= data_i; //4 coeff into lo/hi buf0/1/2/3 based on wrptr + end + end + + //Buffer valid + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) begin + data_i_count <= 'h0; + data_i_count_reg <= 'h0; + end + else if (zeroize) begin + data_i_count <= 'h0; + data_i_count_reg <= 'h0; + end + else if (wr_rst_count) begin + data_i_count <= 'h0; + data_i_count_reg <= 'h0; + end + else if (wren) begin + data_i_count <= data_i_count + 'h1; + data_i_count_reg <= data_i_count; + end + end + + always_comb begin + buf_valid = (data_i_count_reg == 'd3); + lo_hi = buf_valid ^ lo_hi_reg; + lo_hi_rd = (shuffle_en & (mode == 0)) ? lo_hi_reg : lo_hi; //shuffling delays logic by a cycle, so that needs to be accounted for here as well + end + + //lo hi + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) + lo_hi_reg <= 'b0; + else if (zeroize) + lo_hi_reg <= 'b0; + else if (buf_valid) + lo_hi_reg <= ~lo_hi_reg; + end + + //assign output + always_comb begin + data_o = '0; + if (lo_hi_rd) begin + data_o = {buffer[0][3][rdptr], buffer[0][2][rdptr], buffer[0][1][rdptr], buffer[0][0][rdptr]}; + end else if (~lo_hi_rd) begin + data_o = {buffer[1][3][rdptr], buffer[1][2][rdptr], buffer[1][1][rdptr], buffer[1][0][rdptr]}; + end + end + +endmodule \ No newline at end of file diff --git a/designs/Caliptra/src/adams-bridge/ntt_special_adder.sv b/designs/Caliptra/src/adams-bridge/ntt_special_adder.sv new file mode 100644 index 0000000..d19c5a6 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/ntt_special_adder.sv @@ -0,0 +1,101 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +// +//====================================================================== +// +// ntt_special_adder.sv +// -------- +// Special modular addtion module to compute opa+-opb % prime +// to be used special multreduction module +// +// +//====================================================================== + +module ntt_special_adder #( + parameter REG_SIZE = 24 + ) + ( + // Clock and reset. + input wire clk, + input wire reset_n, + input wire zeroize, + + // DATA PORT + input wire add_en_i, + input wire [10:0] opa_i, + input wire [12:0] opb_i, + input wire [REG_SIZE-1:0] prime_i, + output logic [REG_SIZE-1:0] res_o, + output logic ready_o +); + + logic [REG_SIZE-1 : 0] opb1; + logic [REG_SIZE-1 : 0] r0; + logic [REG_SIZE-1 : 0] r1; + logic carry0; + + logic [REG_SIZE-1 : 0] r0_reg; + logic carry0_reg; + + logic carry1; + logic [1 : 0] push_result_reg; + + + always_comb {carry0, r0} = {opa_i, opb_i}; + always_comb opb1 = ~prime_i; + + abr_adder #( + .RADIX(REG_SIZE) + ) + adder_inst_1( + .a_i(r0_reg), + .b_i(opb1), + .cin_i(1'b1), + .s_o(r1), + .cout_o(carry1) + ); + + always_ff @(posedge clk or negedge reset_n) + begin + if(!reset_n) begin + r0_reg <= '0; + carry0_reg <= '0; + end + else if (zeroize) begin + r0_reg <= '0; + carry0_reg <= '0; + end + else if (add_en_i) begin + r0_reg <= r0; + carry0_reg <= carry0; + end + end + + // Determines when results are ready + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) + push_result_reg <= 2'b0; + else if (zeroize) + push_result_reg <= 2'b0; + else if (add_en_i) + push_result_reg <= 2'b10; + else // one shift to right + push_result_reg <= 2'(push_result_reg >> 1); + end + + assign ready_o = push_result_reg[0]; + + assign res_o = (carry0_reg ^ carry1)? r1 : r0_reg; + +endmodule diff --git a/designs/Caliptra/src/adams-bridge/ntt_top.sv b/designs/Caliptra/src/adams-bridge/ntt_top.sv new file mode 100644 index 0000000..2a5e6db --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/ntt_top.sv @@ -0,0 +1,844 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +// +//====================================================================== +// +// ntt_top.sv +// -------- +// This block does multiple things: +// 1. Keeps track of stages of bf2x2 operation +// 2. Reads appropriate addr of ROM and passes w input to bf2x2 +// 3. Orchestrates memory writes and reads and passes u and v inputs to bf2x2 +// 4. Controls direct PWM inputs to bf2x2 in pwm mode +// 5. Maintains mode input to bf2x2 and related input/output muxes +// 6. Aligns data and control delays associated with bf2x2 module +// The design accounts for 1 cycle read latency from memory +// and adds flops to inputs of the bf2x2 (data and enable) +// In addition to this, data inputs are flopped internal to bf2x2 to balance +// delays between both paths and maintain constant time +//====================================================================== + +module ntt_top + import abr_params_pkg::*; + import ntt_defines_pkg::*; +#( + parameter REG_SIZE = 24, + parameter NTT_REG_SIZE = REG_SIZE-1, + parameter MLDSA_Q = 23'd8380417, + parameter MLDSA_Q_DIV2_ODD = (MLDSA_Q + 1) / 2, + parameter MLDSA_N = 256, + parameter MLDSA_LOGN = $clog2(MLDSA_N), + parameter MEM_ADDR_WIDTH = 15, + parameter MEM_DATA_WIDTH = 4*REG_SIZE, + parameter WIDTH = 46 +) +( + //Clock and reset + input wire clk, + input wire reset_n, + input wire zeroize, + + //Ctrl signal ports + input mode_t mode, + input wire ntt_enable, + input wire mlkem, + + //NTT base addr ports + input ntt_mem_addr_t ntt_mem_base_addr, + + //PWM base addr ports + input pwo_mem_addr_t pwo_mem_base_addr, + + //PWM control + input wire accumulate, + + //Sampler IF + input wire sampler_valid, + + input wire shuffle_en, + input wire masking_en, + input wire [5:0] random, + input wire [4:0][WIDTH-1:0] rnd_i, + + //Memory if + //Reuse between pwm c, ntt + output mem_if_t mem_wr_req, + output mem_if_t mem_rd_req, + output logic [ABR_MEM_MASKED_DATA_WIDTH-1:0] mem_wr_data, + input wire [ABR_MEM_MASKED_DATA_WIDTH-1:0] mem_rd_data, + + //Memory IF for PWM + output mem_if_t pwm_a_rd_req, + output mem_if_t pwm_b_rd_req, + input wire [ABR_MEM_MASKED_DATA_WIDTH-1:0] pwm_a_rd_data, + //Reuse between pwm mem data or sampler data (mux should be outside) + input wire [ABR_MEM_MASKED_DATA_WIDTH-1:0] pwm_b_rd_data, + + output logic ntt_busy, + output logic ntt_done + +); + //NTT mem signals + //Masking internal - TODO: remove and merge with mem_wr/rd interface after testing + mem_if_t share_mem_wr_req, share_mem_rd_req, share_mem_rd_req_reg; + logic [3:0][1:0][MLDSA_SHARE_WIDTH-1:0] share_mem_rd_data, share_mem_wr_data, share_mem_wr_data_reg, share_mem_wr_data_comb; + logic [(MLKEM_NUM_SHARES*COEFF_PER_CLK)-1:0][MLDSA_SHARE_WIDTH-1:0] mlkem_share_mem_rd_data; //Used for mlkem masking + + //Write IF + logic mem_wren, mem_wren_reg, mem_wren_mux; + logic [ABR_MEM_ADDR_WIDTH-1:0] mem_wr_addr, mem_wr_addr_reg, mem_wr_addr_mux; + logic [MEM_DATA_WIDTH-1:0] mem_wr_data_int, mem_wr_data_reg, mem_wr_data_reg_d2; + + //Read IF + logic mem_rden; + logic [ABR_MEM_ADDR_WIDTH-1:0] mem_rd_addr; + logic [(4*REG_SIZE)-1:0] mem_rd_data_reg; + + //Butterfly IF signals + bf_uvwi_t uvw_i; + bf_uvo_t uv_o, uv_o_reg; + logic bf_enable, bf_enable_mux; + logic [2:0] bf_enable_reg; + logic bf_ready; + logic buf0_valid; + + //Internal + logic [6:0] twiddle_addr, twiddle_addr_reg; + logic buf_wren; + logic buf_rden; + logic buf_wr_rst_count, buf_rd_rst_count; + + //buffer IF + logic [(4*REG_SIZE)-1:0] buf_data_i, buf_data_o; + logic [(3*NTT_REG_SIZE)-1:0] twiddle_factor, twiddle_factor_reg; + logic [NTT_REG_SIZE-1:0] w10_reg, w11_reg; + logic [1:0] buf_wrptr, buf_rdptr; + + //PWM mem IF + pwo_uvwi_t pw_uvw_i; //Used for unmasked PWM, PWMA and masked PWM ops. Masked PWMA will use shares struct + pwo_t pwo_uv_o; + logic pw_wren, pw_wren_reg, pw_wren_reg_d1; + logic pw_rden, pw_rden_dest_mem, pw_rden_reg; + logic sampler_valid_reg; + logic [MEM_DATA_WIDTH-1:0] pwm_b_rd_data_reg; + //PWM+INTT IF - masking + hybrid_bf_uvwi_t hybrid_pw_uvw_i; + + //PWM, INTT masking + masked_intt_uvwi_t bf_shares_uvw_i; //Used for masked INTT op + pwm_shares_uvwi_t pwm_shares_uvw_i; //Used for masked PWM op + logic [3:0][1:0][MASKED_WIDTH-1:0] share_mem_rd_data_reg, share_mem_rd_data_reg_d1; + + //Flop ntt_ctrl pwm output wr addr to align with BFU output flop + logic [ABR_MEM_ADDR_WIDTH-1:0] pwm_wr_addr_c_reg, pwm_wr_addr_c_reg_d2; + logic [(4*REG_SIZE)-1:0] pwm_wr_data_reg; + + //ntt_ctrl output connections + logic [ABR_MEM_ADDR_WIDTH-1:0] pw_mem_wr_addr_c; + logic [ABR_MEM_ADDR_WIDTH-1:0] pw_mem_rd_addr_c, pw_mem_rd_addr_a, pw_mem_rd_addr_b; + logic [ABR_MEM_ADDR_WIDTH-1:0] pw_mem_rd_addr_a_reg, pw_mem_rd_addr_b_reg; + logic ntt_done_int; + + //pwm mem data_out connections + logic [(4*REG_SIZE)-1:0] pwm_rd_data_a, pwm_rd_data_b; + logic [ABR_MEM_MASKED_DATA_WIDTH-1:0] pwm_rd_data_c; + + //Flop pwm mem data_out before sending to BFU + logic [(4*REG_SIZE)-1:0] pwm_rd_data_a_reg, pwm_rd_data_b_reg, pwm_rd_data_c_reg; + + //PWM input shares + logic [3:0][1:0][MASKED_WIDTH-1:0] pwm_rd_data_a_shares_reg, pwm_rd_data_b_shares_reg; + logic [3:0][1:0][MASKED_WIDTH-1:0] pwm_rd_data_a_shares_reg_d1, pwm_rd_data_b_shares_reg_d1; //delayed by a cycle + logic [1:0][1:0][MASKED_WIDTH-1:0] twiddle_factor_shares_reg, twiddle_factor_shares_reg_d1, twiddle_factor_shares_reg_d2; //only 2 required since only 1st stage of INTT is masked and needs this + //PWM output shares + pwm_shares_uvo_t pwm_shares_uvo, pwm_shares_uvo_reg; + + //PairWM + mlkem_pairwm_zeta_t mlkem_pairwm_zeta13_i; + mlkem_masked_pairwm_zeta_shares_t mlkem_shares_pairwm_zeta13_i; + + //Modes + logic ct_mode; + logic gs_mode; + logic pwo_mode; + logic pwm_mode, pwa_mode, pws_mode; + logic pairwm_mode; + mode_t opcode; + logic masking_en_ctrl; + + logic ntt_passthrough, intt_passthrough; + + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) begin + ct_mode <= 0; + gs_mode <= 0; + pwo_mode <= 0; + pwm_mode <= 0; + pwa_mode <= 0; + pws_mode <= 0; + pairwm_mode <= 0; + end + else if (zeroize) begin + ct_mode <= 0; + gs_mode <= 0; + pwo_mode <= 0; + pwm_mode <= 0; + pwa_mode <= 0; + pws_mode <= 0; + pairwm_mode <= 0; + end + else begin + ct_mode <= (mode == ct); + gs_mode <= (mode == gs); + pwo_mode <= (mode inside {pwm, pwa, pws}) | (mlkem & (mode == pairwm)); + pwm_mode <= (mode == pwm); + pwa_mode <= (mode == pwa); + pws_mode <= (mode == pws); + pairwm_mode <= mlkem & (mode == pairwm); + end + end + + //Mem IF assignments: + //mem wr - NTT/INTT mode, write ntt data. PWO mode, write pwm/a/s data + assign mem_wr_req.rd_wr_en = !pwo_mode ? (mem_wren_mux ? RW_WRITE : RW_IDLE) //TODO convert mem_wren_mux to rw enum + : (pw_wren_reg ? RW_WRITE : RW_IDLE); + assign mem_wr_req.addr = !pwo_mode ? mem_wr_addr_mux : pwm_wr_addr_c_reg; + assign mem_wr_data_int = !pwo_mode ? (ct_mode ? {1'b0, uv_o_reg.v21_o, 1'b0, uv_o_reg.u21_o, 1'b0, uv_o_reg.v20_o, 1'b0, uv_o_reg.u20_o} : buf_data_o) + : pwm_wr_data_reg; + + //Share mem: TODO: mlkem + assign share_mem_wr_req.rd_wr_en = ((pwm_mode | pairwm_mode) & masking_en) ? ((accumulate ? pw_wren_reg_d1 : pw_wren_reg) ? RW_WRITE : RW_IDLE) : RW_IDLE; + assign share_mem_wr_req.addr = ((pwm_mode | pairwm_mode) & masking_en) ? accumulate ? pwm_wr_addr_c_reg_d2 : pwm_wr_addr_c_reg : 'h0; //TODO: why is d2 required for accumulate case? + assign share_mem_rd_req.rd_wr_en = masking_en ? ((pwm_mode | pairwm_mode) & accumulate) ? (pw_rden_dest_mem ? RW_READ : RW_IDLE) + : (gs_mode & masking_en_ctrl) ? (mem_rden ? RW_READ : RW_IDLE) + : RW_IDLE + : RW_IDLE; + assign share_mem_rd_req.addr = masking_en ? ((pwm_mode | pairwm_mode) & accumulate) ? pw_mem_rd_addr_c + : (gs_mode & masking_en_ctrl) ? mem_rd_addr : 'h0 + : 'h0; + always_comb begin + if (!masking_en) //TODO: use flopped masking_en? + mem_wr_data = shuffle_en ? (pwm_mode | pairwm_mode) ? ABR_MEM_MASKED_DATA_WIDTH'(mem_wr_data_reg) + : (pwa_mode | pws_mode) ? ABR_MEM_MASKED_DATA_WIDTH'(mem_wr_data_reg) : ABR_MEM_MASKED_DATA_WIDTH'(mem_wr_data_int) + : ABR_MEM_MASKED_DATA_WIDTH'(mem_wr_data_int); + else + mem_wr_data = gs_mode ? ABR_MEM_MASKED_DATA_WIDTH'(mem_wr_data_int) : (pwm_mode | pairwm_mode) ? shuffle_en ? share_mem_wr_data : share_mem_wr_data_comb : '0; //In masking, only gs_mode will have mem wr data. PWM mode will write only shares + end + + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) begin + share_mem_wr_data <= '0; + share_mem_wr_data_reg <= '0; + end + else if (zeroize) begin + share_mem_wr_data <= '0; + share_mem_wr_data_reg <= '0; + end + else if (masking_en & (pwm_mode | pairwm_mode)) begin + //Pad with 0s to match port width + share_mem_wr_data[0] <= {2'b0, pwm_shares_uvo_reg.uv0[1], 2'b0, pwm_shares_uvo_reg.uv0[0]}; + share_mem_wr_data[1] <= {2'b0, pwm_shares_uvo_reg.uv1[1], 2'b0, pwm_shares_uvo_reg.uv1[0]}; + share_mem_wr_data[2] <= {2'b0, pwm_shares_uvo_reg.uv2[1], 2'b0, pwm_shares_uvo_reg.uv2[0]}; + share_mem_wr_data[3] <= {2'b0, pwm_shares_uvo_reg.uv3[1], 2'b0, pwm_shares_uvo_reg.uv3[0]}; + + share_mem_wr_data_reg <= share_mem_wr_data; + end + else begin + share_mem_wr_data <= '0; + share_mem_wr_data_reg <= '0; + end + + end + + always_comb begin + share_mem_wr_data_comb[0] = {2'b0, pwm_shares_uvo_reg.uv0[1], 2'b0, pwm_shares_uvo_reg.uv0[0]}; + share_mem_wr_data_comb[1] = {2'b0, pwm_shares_uvo_reg.uv1[1], 2'b0, pwm_shares_uvo_reg.uv1[0]}; + share_mem_wr_data_comb[2] = {2'b0, pwm_shares_uvo_reg.uv2[1], 2'b0, pwm_shares_uvo_reg.uv2[0]}; + share_mem_wr_data_comb[3] = {2'b0, pwm_shares_uvo_reg.uv3[1], 2'b0, pwm_shares_uvo_reg.uv3[0]}; + end + + //mem rd - NTT/INTT mode, read ntt data. PWM mode, read accumulate data from c mem. PWA/S mode, unused + assign mem_rd_req.rd_wr_en = (ct_mode | (gs_mode & ~masking_en_ctrl)) ? (mem_rden ? RW_READ : RW_IDLE) : (gs_mode & masking_en_ctrl) ? share_mem_rd_req.rd_wr_en : (pwm_mode | pairwm_mode) ? masking_en ? share_mem_rd_req.rd_wr_en : (pw_rden_dest_mem ? RW_READ : RW_IDLE) : RW_IDLE; + assign mem_rd_req.addr = (ct_mode | (gs_mode & ~masking_en_ctrl)) ? mem_rd_addr : (gs_mode & masking_en_ctrl) ? share_mem_rd_req.addr : (pwm_mode | pairwm_mode) ? masking_en ? share_mem_rd_req.addr : pw_mem_rd_addr_c : 'h0; + assign pwm_rd_data_c = ((pwm_mode | pairwm_mode) & accumulate) ? mem_rd_data : 'h0; + + always_comb begin + for (int i = 0; i < 8; i++) begin + mlkem_share_mem_rd_data[i] = MLDSA_SHARE_WIDTH'(mem_rd_data[(i*48) +: 47]); + end + end + + assign share_mem_rd_data = (gs_mode & masking_en_ctrl) ? (mlkem ? mlkem_share_mem_rd_data : mem_rd_data) + : ABR_MEM_MASKED_DATA_WIDTH'(pwm_rd_data_c); + + //pwm rd a - PWO mode - read a operand from mem. NTT/INTT mode, not used + assign pwm_a_rd_req.rd_wr_en = pwo_mode ? (masking_en & ~shuffle_en) ? (pw_rden_reg ? RW_READ : RW_IDLE) : (pw_rden ? RW_READ : RW_IDLE) : RW_IDLE; + assign pwm_a_rd_req.addr = pwo_mode ? (masking_en & ~shuffle_en) ? pw_mem_rd_addr_a_reg : pw_mem_rd_addr_a : 'h0; + assign pwm_rd_data_a = pwo_mode ? pwm_a_rd_data[MEM_DATA_WIDTH-1:0] : 'h0; + + //pwm rd b - PWO mode - read b operand from mem. Or operand b can also be connected directly to sampler, so in that case, addr/rden are not used + always_comb begin + if (shuffle_en) begin + pwm_b_rd_req.rd_wr_en = sampler_valid_reg & pwo_mode ? (pw_rden ? RW_READ : RW_IDLE) : RW_IDLE; //pw_rden is delayed a clk due to shuffling, so use delayed sampler_valid to line it up + pwm_b_rd_req.addr = sampler_valid_reg & pwo_mode ? pw_mem_rd_addr_b : 'h0; + pwm_rd_data_b = pwm_b_rd_data_reg; + end + else begin + pwm_b_rd_req.rd_wr_en = sampler_valid & pwo_mode ? masking_en ? (pw_rden_reg ? RW_READ : RW_IDLE) : (pw_rden ? RW_READ : RW_IDLE) : RW_IDLE; + pwm_b_rd_req.addr = sampler_valid & pwo_mode ? masking_en ? pw_mem_rd_addr_b_reg : pw_mem_rd_addr_b : 'h0; + pwm_rd_data_b = ((pwm_mode | pairwm_mode) & masking_en & ~shuffle_en) ? pwm_b_rd_data_reg : pwm_b_rd_data[MEM_DATA_WIDTH-1:0]; + end + end + + + ntt_ctrl #( + .MEM_ADDR_WIDTH(ABR_MEM_ADDR_WIDTH) + ) + ntt_ctrl_inst0 ( + .clk(clk), + .reset_n(reset_n), + .zeroize(zeroize), + .ntt_mode(mode), + .ntt_enable(ntt_enable), + .butterfly_ready(bf_ready), + .buf0_valid(buf0_valid), + .sampler_valid(sampler_valid), + .shuffle_en(shuffle_en), + .random(random), + .mlkem(mlkem), + + .ntt_mem_base_addr(ntt_mem_base_addr), + .pwo_mem_base_addr(pwo_mem_base_addr), + .accumulate(accumulate), + + .bf_enable(bf_enable), + .opcode(opcode), + .masking_en(masking_en), + .masking_en_ctrl(masking_en_ctrl), + .buf_wren(buf_wren), + .buf_rden(buf_rden), + .buf_wrptr(buf_wrptr), + .buf_rdptr(buf_rdptr), + .twiddle_addr(twiddle_addr), + + .mem_rd_addr(mem_rd_addr), + .mem_wr_addr(mem_wr_addr), + .mem_rd_en(mem_rden), + .mem_wr_en(mem_wren), + .buf_wr_rst_count(buf_wr_rst_count), + .buf_rd_rst_count(buf_rd_rst_count), + + .pw_mem_rd_addr_a(pw_mem_rd_addr_a), + .pw_mem_rd_addr_b(pw_mem_rd_addr_b), + .pw_mem_rd_addr_c(pw_mem_rd_addr_c), + .pw_mem_wr_addr_c(pw_mem_wr_addr_c), + .pw_rden(pw_rden), + .pw_share_mem_rden(pw_rden_dest_mem), + .pw_wren(pw_wren), + .busy(ntt_busy), + .done(ntt_done_int), + .ntt_passthrough(ntt_passthrough), + .intt_passthrough(intt_passthrough) + ); + + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) + ntt_done <= 'b0; + else if (zeroize) + ntt_done <= 'b0; + else + ntt_done <= ntt_done_int; + end + + //Twiddle lookup + ntt_twiddle_lookup #( + .ADDR_WIDTH(7), + .DATA_WIDTH(NTT_REG_SIZE) + ) w_rom ( + .mode(mode), + .mlkem(mlkem), + .raddr(twiddle_addr), + .rdata(twiddle_factor) + ); + + always_comb begin + unique case(mode) + ct: begin + uvw_i.w00_i = mlkem ? {12'h0, twiddle_factor[MLKEM_REG_SIZE-1:0]} : twiddle_factor[NTT_REG_SIZE-1:0]; + uvw_i.w01_i = mlkem ? {12'h0, twiddle_factor[MLKEM_REG_SIZE-1:0]} : twiddle_factor[NTT_REG_SIZE-1:0]; + uvw_i.w10_i = mlkem ? {12'h0, twiddle_factor[(2*MLKEM_REG_SIZE)-1:MLKEM_REG_SIZE]} : twiddle_factor[(2*NTT_REG_SIZE)-1:NTT_REG_SIZE]; + uvw_i.w11_i = mlkem ? {12'h0, twiddle_factor[(3*MLKEM_REG_SIZE)-1:(2*MLKEM_REG_SIZE)]} : twiddle_factor[(3*NTT_REG_SIZE)-1:(2*NTT_REG_SIZE)]; + end + gs: begin + if (shuffle_en) begin + uvw_i.w11_i = mlkem ? {12'h0, twiddle_factor[(3*MLKEM_REG_SIZE)-1:(2*MLKEM_REG_SIZE)]} : twiddle_factor[(3*NTT_REG_SIZE)-1:(2*NTT_REG_SIZE)]; + uvw_i.w10_i = mlkem ? {12'h0, twiddle_factor[(3*MLKEM_REG_SIZE)-1:(2*MLKEM_REG_SIZE)]} : twiddle_factor[(3*NTT_REG_SIZE)-1:(2*NTT_REG_SIZE)]; + uvw_i.w01_i = mlkem ? {12'h0, twiddle_factor[(2*MLKEM_REG_SIZE)-1:MLKEM_REG_SIZE]} : twiddle_factor[(2*NTT_REG_SIZE)-1:NTT_REG_SIZE]; + uvw_i.w00_i = mlkem ? {12'h0, twiddle_factor[MLKEM_REG_SIZE-1:0]} : twiddle_factor[NTT_REG_SIZE-1:0]; + end + else begin + uvw_i.w11_i = mlkem ? {12'h0, twiddle_factor_reg[(3*MLKEM_REG_SIZE)-1:(2*MLKEM_REG_SIZE)]} : twiddle_factor_reg[(3*NTT_REG_SIZE)-1:(2*NTT_REG_SIZE)]; + uvw_i.w10_i = mlkem ? {12'h0, twiddle_factor_reg[(3*MLKEM_REG_SIZE)-1:(2*MLKEM_REG_SIZE)]} : twiddle_factor_reg[(3*NTT_REG_SIZE)-1:(2*NTT_REG_SIZE)]; + uvw_i.w01_i = mlkem ? {12'h0, twiddle_factor_reg[(2*MLKEM_REG_SIZE)-1:MLKEM_REG_SIZE]} : twiddle_factor_reg[(2*NTT_REG_SIZE)-1:NTT_REG_SIZE]; + uvw_i.w00_i = mlkem ? {12'h0, twiddle_factor_reg[MLKEM_REG_SIZE-1:0]} : twiddle_factor_reg[NTT_REG_SIZE-1:0]; + end + end + default: begin + uvw_i.w11_i = 'h0; + uvw_i.w10_i = 'h0; + uvw_i.w01_i = 'h0; + uvw_i.w00_i = 'h0; + end + endcase + end + + always_comb begin + if (mlkem & (mode == pairwm)) begin + if (masking_en) begin + mlkem_shares_pairwm_zeta13_i.z0_i[0] = shuffle_en ? (MLKEM_MASKED_WIDTH)'(twiddle_factor_shares_reg_d1[0][0]) : (MLKEM_MASKED_WIDTH)'(twiddle_factor_shares_reg_d2[0][0]); //In masked + shuffled mode, twiddle addr increments 2 clks before 2x2 receives enable. Using d1 version ensures additional 2 clk delay to match latency of a/b inputs to pairwm modules. (a/b require 4 cycles from incr_rd_addr to shares going to pairwm inputs) + mlkem_shares_pairwm_zeta13_i.z0_i[1] = shuffle_en ? (MLKEM_MASKED_WIDTH)'(twiddle_factor_shares_reg_d1[0][1]) : (MLKEM_MASKED_WIDTH)'(twiddle_factor_shares_reg_d2[0][1]); //In masked only mode, twiddle addr increments 3 clks before 2x2 receives enable, hence use d2 version + + mlkem_shares_pairwm_zeta13_i.z1_i[0] = shuffle_en ? (MLKEM_MASKED_WIDTH)'(twiddle_factor_shares_reg_d1[1][0]) : (MLKEM_MASKED_WIDTH)'(twiddle_factor_shares_reg_d2[1][0]); + mlkem_shares_pairwm_zeta13_i.z1_i[1] = shuffle_en ? (MLKEM_MASKED_WIDTH)'(twiddle_factor_shares_reg_d1[1][1]) : (MLKEM_MASKED_WIDTH)'(twiddle_factor_shares_reg_d2[1][1]); + + mlkem_pairwm_zeta13_i = '0; + end + else begin + mlkem_pairwm_zeta13_i.z0_i = twiddle_factor_reg[(2*MLKEM_REG_SIZE)-1:MLKEM_REG_SIZE]; // In non-masking mode, twiddle addr increments 1 clk before 2x2 receives enable, hence use flopped twiddle_factor + mlkem_pairwm_zeta13_i.z1_i = twiddle_factor_reg[(3*MLKEM_REG_SIZE)-1:(2*MLKEM_REG_SIZE)]; + mlkem_shares_pairwm_zeta13_i = '0; + end + end + else begin + mlkem_pairwm_zeta13_i = '0; + mlkem_shares_pairwm_zeta13_i = '0; + end + end + + ntt_hybrid_butterfly_2x2 #( + .WIDTH(WIDTH) + ) + hybrid_bf2x2 ( + .clk(clk), + .reset_n(reset_n), + .zeroize(zeroize), + .mode(opcode), + .enable(bf_enable_mux), + .masking_en(gs_mode ? masking_en_ctrl : masking_en), + .shuffle_en(shuffle_en), + .mlkem(mlkem), + .uvw_i(uvw_i), + .pw_uvw_i(pw_uvw_i), + .pwm_shares_uvw_i(pwm_shares_uvw_i), + .rnd_i(rnd_i), + .accumulate(accumulate), + .bf_shares_uvw_i(bf_shares_uvw_i), + .mlkem_pairwm_zeta13_i(mlkem_pairwm_zeta13_i), + .mlkem_shares_pairwm_zeta13_i(mlkem_shares_pairwm_zeta13_i), + .ntt_passthrough(ntt_passthrough), + .intt_passthrough(intt_passthrough), + .uv_o(uv_o), + .pwo_uv_o(pwo_uv_o), + .pwm_shares_uvo(pwm_shares_uvo), + .ready_o(bf_ready) + ); + + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) begin + mem_rd_data_reg <= 'h0; + bf_enable_reg <= 'b0; + twiddle_addr_reg <= 'h0; + twiddle_factor_reg <= 'h0; + + uv_o_reg <= 'h0; + mem_wren_reg <= 'b0; + mem_wr_addr_reg <= 'h0; + + //pwm + pwm_rd_data_a_reg <= 'h0; + pwm_rd_data_b_reg <= 'h0; + pwm_rd_data_c_reg <= 'h0; + pwm_wr_data_reg <= 'h0; + + pwm_wr_addr_c_reg <= 'h0; + pwm_wr_addr_c_reg_d2 <= 'h0; + + pw_wren_reg <= 'b0; + pw_wren_reg_d1 <= 'b0; + mem_wr_data_reg <= 'h0; + mem_wr_data_reg_d2 <= 'h0; + sampler_valid_reg <= 'h0; + pwm_b_rd_data_reg <= 'h0; + + share_mem_rd_data_reg <= 'h0; + share_mem_rd_data_reg_d1 <= '0; + pwm_shares_uvo_reg <= '{uv0: '0, uv1: '0, uv2: '0, uv3: '0}; + + //PWM shares + for (int i = 0; i < 4; i++) begin + for (int j = 0; j < 2; j++) begin + pwm_rd_data_a_shares_reg[i][j] <= '0; + pwm_rd_data_b_shares_reg[i][j] <= '0; + end + end + pwm_rd_data_a_shares_reg_d1 <= '0; + pwm_rd_data_b_shares_reg_d1 <= '0; + + //INTT twiddle shares + for (int i = 0; i < 2; i++) begin + for (int j = 0; j < 2; j++) begin + twiddle_factor_shares_reg[i][j] <= '0; + end + end + + pw_rden_reg <= '0; + pw_mem_rd_addr_a_reg <= '0; + pw_mem_rd_addr_b_reg <= '0; + share_mem_rd_req_reg <= '{rd_wr_en: RW_IDLE, addr: '0}; + + w10_reg <= '0; + w11_reg <= '0; + twiddle_factor_shares_reg_d1 <= '0; + twiddle_factor_shares_reg_d2 <= '0; + + end + else if (zeroize) begin + mem_rd_data_reg <= 'h0; + bf_enable_reg <= 'b0; + twiddle_addr_reg <= 'h0; + twiddle_factor_reg <= 'h0; + + uv_o_reg <= 'h0; + mem_wren_reg <= 'b0; + mem_wr_addr_reg <= 'h0; + + pwm_rd_data_a_reg <= 'h0; + pwm_rd_data_b_reg <= 'h0; + pwm_rd_data_c_reg <= 'h0; + pwm_wr_data_reg <= 'h0; + + pwm_wr_addr_c_reg <= 'h0; + pwm_wr_addr_c_reg_d2 <= 'h0; + + pw_wren_reg <= 'b0; + pw_wren_reg_d1 <= 'b0; + mem_wr_data_reg <= 'h0; + mem_wr_data_reg_d2 <= 'h0; + sampler_valid_reg <= 'h0; + pwm_b_rd_data_reg <= 'h0; + + share_mem_rd_data_reg <= 'h0; + share_mem_rd_data_reg_d1 <= '0; + pwm_shares_uvo_reg <= '{uv0: '0, uv1: '0, uv2: '0, uv3: '0}; + + //PWM shares + for (int i = 0; i < 4; i++) begin + for (int j = 0; j < 2; j++) begin + pwm_rd_data_a_shares_reg[i][j] <= '0; + pwm_rd_data_b_shares_reg[i][j] <= '0; + end + end + pwm_rd_data_a_shares_reg_d1 <= '0; + pwm_rd_data_b_shares_reg_d1 <= '0; + + //INTT twiddle shares + for (int i = 0; i < 2; i++) begin + for (int j = 0; j < 2; j++) begin + twiddle_factor_shares_reg[i][j] <= '0; + end + end + + pw_rden_reg <= '0; + pw_mem_rd_addr_a_reg <= '0; + pw_mem_rd_addr_b_reg <= '0; + share_mem_rd_req_reg <= '{rd_wr_en: RW_IDLE, addr: '0}; + + w10_reg <= '0; + w11_reg <= '0; + twiddle_factor_shares_reg_d1 <= '0; + twiddle_factor_shares_reg_d2 <= '0; + end + else begin + mem_rd_data_reg <= mem_rd_data[MEM_DATA_WIDTH-1:0]; + bf_enable_reg <= {bf_enable_reg[1:0], bf_enable}; + twiddle_addr_reg <= twiddle_addr; + twiddle_factor_reg <= twiddle_factor; + + uv_o_reg <= uv_o; + mem_wren_reg <= mem_wren; + mem_wr_addr_reg <= mem_wr_addr; + + //pwm + pwm_wr_addr_c_reg <= pw_mem_wr_addr_c; + pwm_wr_addr_c_reg_d2 <= pwm_wr_addr_c_reg; + + pwm_rd_data_a_reg <= pwm_rd_data_a; + pwm_rd_data_b_reg <= pwm_rd_data_b; + pwm_rd_data_c_reg <= pwm_rd_data_c[MEM_DATA_WIDTH-1:0]; //used in non-masking mode + pwm_wr_data_reg <= {1'b0, pwo_uv_o.uv3, 1'b0, pwo_uv_o.uv2, 1'b0, pwo_uv_o.uv1, 1'b0, pwo_uv_o.uv0}; + + pw_wren_reg <= pw_wren; + pw_wren_reg_d1 <= pw_wren_reg; + mem_wr_data_reg <= mem_wr_data_int; + mem_wr_data_reg_d2 <= mem_wr_data_reg; + sampler_valid_reg <= sampler_valid; + pwm_b_rd_data_reg <= pwm_b_rd_data[MEM_DATA_WIDTH-1:0]; + + //Re-organize mem rd data since incoming shares are 48-bits. Internally we need 46-bit shares + for (int i = 0; i < 4; i++) begin + for (int j = 0; j < 2; j++) begin + share_mem_rd_data_reg[i][j] <= share_mem_rd_data[i][j][(MLDSA_SHARE_WIDTH-1)-2:0]; + end + end + + share_mem_rd_data_reg_d1 <= share_mem_rd_data_reg; + + //PWM shares + pwm_rd_data_a_shares_reg[0][0] <= MASKED_WIDTH'(pwm_rd_data_a[REG_SIZE-2:0]) - rnd_i[0]; + pwm_rd_data_b_shares_reg[0][0] <= MASKED_WIDTH'(pwm_rd_data_b[REG_SIZE-2:0]) - rnd_i[1]; + pwm_rd_data_a_shares_reg[0][1] <= rnd_i[0]; + pwm_rd_data_b_shares_reg[0][1] <= rnd_i[1]; + + pwm_rd_data_a_shares_reg[1][0] <= MASKED_WIDTH'(pwm_rd_data_a[(2*REG_SIZE)-2:REG_SIZE]) - rnd_i[0]; + pwm_rd_data_b_shares_reg[1][0] <= MASKED_WIDTH'(pwm_rd_data_b[(2*REG_SIZE)-2:REG_SIZE]) - rnd_i[1]; + pwm_rd_data_a_shares_reg[1][1] <= rnd_i[0]; + pwm_rd_data_b_shares_reg[1][1] <= rnd_i[1]; + + pwm_rd_data_a_shares_reg[2][0] <= MASKED_WIDTH'(pwm_rd_data_a[(3*REG_SIZE)-2:(2*REG_SIZE)]) - rnd_i[0]; + pwm_rd_data_b_shares_reg[2][0] <= MASKED_WIDTH'(pwm_rd_data_b[(3*REG_SIZE)-2:(2*REG_SIZE)]) - rnd_i[1]; + pwm_rd_data_a_shares_reg[2][1] <= rnd_i[0]; + pwm_rd_data_b_shares_reg[2][1] <= rnd_i[1]; + + pwm_rd_data_a_shares_reg[3][0] <= MASKED_WIDTH'(pwm_rd_data_a[(4*REG_SIZE)-2:(3*REG_SIZE)]) - rnd_i[0]; + pwm_rd_data_b_shares_reg[3][0] <= MASKED_WIDTH'(pwm_rd_data_b[(4*REG_SIZE)-2:(3*REG_SIZE)]) - rnd_i[1]; + pwm_rd_data_a_shares_reg[3][1] <= rnd_i[0]; + pwm_rd_data_b_shares_reg[3][1] <= rnd_i[1]; + + pwm_rd_data_a_shares_reg_d1 <= pwm_rd_data_a_shares_reg; + pwm_rd_data_b_shares_reg_d1 <= pwm_rd_data_b_shares_reg; + + pwm_shares_uvo_reg <= pwm_shares_uvo; + + //INTT shares + twiddle_factor_shares_reg[0][0] <= mlkem ? (MASKED_WIDTH)'((2*MLKEM_Q_WIDTH)'(twiddle_factor[(2*MLKEM_Q_WIDTH)-1:MLKEM_Q_WIDTH]) - (rnd_i[2][(2*MLKEM_Q_WIDTH)-1:0])) : MASKED_WIDTH'(twiddle_factor[NTT_REG_SIZE-1:0]) - rnd_i[2]; + twiddle_factor_shares_reg[0][1] <= mlkem ? (MASKED_WIDTH)'(rnd_i[2][(2*MLKEM_Q_WIDTH)-1:0]) : rnd_i[2]; + + twiddle_factor_shares_reg[1][0] <= mlkem ? (MASKED_WIDTH)'((2*MLKEM_Q_WIDTH)'(twiddle_factor[(3*MLKEM_Q_WIDTH)-1:(2*MLKEM_Q_WIDTH)]) - (rnd_i[3][(2*MLKEM_Q_WIDTH)-1:0])) : MASKED_WIDTH'(twiddle_factor[(2*NTT_REG_SIZE)-1:NTT_REG_SIZE]) - rnd_i[3]; + twiddle_factor_shares_reg[1][1] <= mlkem ? (MASKED_WIDTH)'(rnd_i[3][(2*MLKEM_Q_WIDTH)-1:0]) : rnd_i[3]; + + pw_rden_reg <= pw_rden; + pw_mem_rd_addr_a_reg <= pw_mem_rd_addr_a; + pw_mem_rd_addr_b_reg <= pw_mem_rd_addr_b; + share_mem_rd_req_reg <= share_mem_rd_req; + + w10_reg <= uvw_i.w10_i; + w11_reg <= uvw_i.w11_i; + twiddle_factor_shares_reg_d1 <= twiddle_factor_shares_reg; + twiddle_factor_shares_reg_d2 <= twiddle_factor_shares_reg_d1; + + end + end + + //Buffer (input or output side) + assign buf_data_i = ct_mode ? mem_rd_data[MEM_DATA_WIDTH-1:0] : shuffle_en ? {1'b0, uv_o_reg.v21_o, 1'b0, uv_o_reg.v20_o, 1'b0, uv_o_reg.u21_o, 1'b0, uv_o_reg.u20_o} + : {1'b0, uv_o.v21_o, 1'b0, uv_o.v20_o, 1'b0, uv_o.u21_o, 1'b0, uv_o.u20_o}; + + always_comb begin + unique case(opcode) + ct: begin + uvw_i.u00_i = buf_data_o[REG_SIZE-2:0] ; + uvw_i.u01_i = buf_data_o[(2*REG_SIZE)-2:REG_SIZE] ; + uvw_i.v00_i = buf_data_o[(3*REG_SIZE)-2:(2*REG_SIZE)] ; + uvw_i.v01_i = buf_data_o[(4*REG_SIZE)-2:(3*REG_SIZE)] ; + + pw_uvw_i = 'h0; + end + gs: begin + uvw_i.u00_i = masking_en_ctrl ? '0 : mem_rd_data_reg[REG_SIZE-2:0]; + uvw_i.u01_i = masking_en_ctrl ? '0 : mem_rd_data_reg[(3*REG_SIZE)-2:(2*REG_SIZE)]; + uvw_i.v00_i = masking_en_ctrl ? '0 : mem_rd_data_reg[(2*REG_SIZE)-2:REG_SIZE]; + uvw_i.v01_i = masking_en_ctrl ? '0 : mem_rd_data_reg[(4*REG_SIZE)-2:(3*REG_SIZE)]; + + pw_uvw_i = 'h0; + end + pwm, pairwm: begin + uvw_i.u00_i = 'h0; + uvw_i.u01_i = 'h0; + uvw_i.v00_i = 'h0; + uvw_i.v01_i = 'h0; + + if (~masking_en) begin + pw_uvw_i.u0_i = pwm_rd_data_a_reg[REG_SIZE-2:0]; + pw_uvw_i.u1_i = pwm_rd_data_a_reg[(2*REG_SIZE)-2:REG_SIZE]; + pw_uvw_i.u2_i = pwm_rd_data_a_reg[(3*REG_SIZE)-2:(2*REG_SIZE)]; + pw_uvw_i.u3_i = pwm_rd_data_a_reg[(4*REG_SIZE)-2:(3*REG_SIZE)]; + + if (shuffle_en) begin + pw_uvw_i.v0_i = pwm_rd_data_b[REG_SIZE-2:0]; + pw_uvw_i.v1_i = pwm_rd_data_b[(2*REG_SIZE)-2:REG_SIZE]; + pw_uvw_i.v2_i = pwm_rd_data_b[(3*REG_SIZE)-2:(2*REG_SIZE)]; + pw_uvw_i.v3_i = pwm_rd_data_b[(4*REG_SIZE)-2:(3*REG_SIZE)]; + end + else begin + pw_uvw_i.v0_i = pwm_rd_data_b_reg[REG_SIZE-2:0]; + pw_uvw_i.v1_i = pwm_rd_data_b_reg[(2*REG_SIZE)-2:REG_SIZE]; + pw_uvw_i.v2_i = pwm_rd_data_b_reg[(3*REG_SIZE)-2:(2*REG_SIZE)]; + pw_uvw_i.v3_i = pwm_rd_data_b_reg[(4*REG_SIZE)-2:(3*REG_SIZE)]; + end + + pw_uvw_i.w0_i = pwm_rd_data_c_reg[REG_SIZE-2:0]; + pw_uvw_i.w1_i = pwm_rd_data_c_reg[(2*REG_SIZE)-2:REG_SIZE]; + pw_uvw_i.w2_i = pwm_rd_data_c_reg[(3*REG_SIZE)-2:(2*REG_SIZE)]; + pw_uvw_i.w3_i = pwm_rd_data_c_reg[(4*REG_SIZE)-2:(3*REG_SIZE)]; + end + else begin + pw_uvw_i = '0; + end + end + pwa, pws: begin + uvw_i.u00_i = 'h0; + uvw_i.u01_i = 'h0; + uvw_i.v00_i = 'h0; + uvw_i.v01_i = 'h0; + + if (~masking_en) begin + pw_uvw_i.u0_i = pwm_rd_data_a_reg[REG_SIZE-2:0]; + pw_uvw_i.u1_i = pwm_rd_data_a_reg[(2*REG_SIZE)-2:REG_SIZE]; + pw_uvw_i.u2_i = pwm_rd_data_a_reg[(3*REG_SIZE)-2:(2*REG_SIZE)]; + pw_uvw_i.u3_i = pwm_rd_data_a_reg[(4*REG_SIZE)-2:(3*REG_SIZE)]; + + if (shuffle_en) begin + pw_uvw_i.v0_i = pwm_rd_data_b/*_reg*/[REG_SIZE-2:0]; + pw_uvw_i.v1_i = pwm_rd_data_b/*_reg*/[(2*REG_SIZE)-2:REG_SIZE]; + pw_uvw_i.v2_i = pwm_rd_data_b/*_reg*/[(3*REG_SIZE)-2:(2*REG_SIZE)]; + pw_uvw_i.v3_i = pwm_rd_data_b/*_reg*/[(4*REG_SIZE)-2:(3*REG_SIZE)]; + end + else begin + pw_uvw_i.v0_i = pwm_rd_data_b_reg[REG_SIZE-2:0]; + pw_uvw_i.v1_i = pwm_rd_data_b_reg[(2*REG_SIZE)-2:REG_SIZE]; + pw_uvw_i.v2_i = pwm_rd_data_b_reg[(3*REG_SIZE)-2:(2*REG_SIZE)]; + pw_uvw_i.v3_i = pwm_rd_data_b_reg[(4*REG_SIZE)-2:(3*REG_SIZE)]; + end + end + else begin + pw_uvw_i = '0; + end + + pw_uvw_i.w0_i = 'h0; + pw_uvw_i.w1_i = 'h0; + pw_uvw_i.w2_i = 'h0; + pw_uvw_i.w3_i = 'h0; + end + default: begin + uvw_i.u00_i = 'h0; + uvw_i.u01_i = 'h0; + uvw_i.v00_i = 'h0; + uvw_i.v01_i = 'h0; + + pw_uvw_i = '0; + end + endcase + end + + always_comb begin + //Assign masked INTT input shares coming from share mem + if (gs_mode & masking_en_ctrl) begin + bf_shares_uvw_i = '{u00_i: share_mem_rd_data_reg_d1[0], + u01_i: share_mem_rd_data_reg_d1[2], + v00_i: share_mem_rd_data_reg_d1[1], + v01_i: share_mem_rd_data_reg_d1[3], + w00_i: shuffle_en ? twiddle_factor_shares_reg[0] : twiddle_factor_shares_reg_d1[0], // shuffle mode needs twiddle to be delayed by a cycle. But here, non-shuffle mode is also delayed due to splitting. Hence other inputs are adjusted to match latency + w01_i: shuffle_en ? twiddle_factor_shares_reg[1] : twiddle_factor_shares_reg_d1[1], + w10_i: w10_reg, + w11_i: w11_reg}; + end + else begin + bf_shares_uvw_i = '{u00_i: '0, u01_i: '0, v00_i: '0, v01_i: '0, w00_i: '0, w01_i: '0, w10_i: '0, w11_i: '0}; + end + end + + always_comb begin + //Assign masked PWM input shares. a, b come from mem/sampler. c comes from share mem. In first round, accumulate = 0, c input should be 0 + if ((pwm_mode | pairwm_mode) & masking_en) begin + if (shuffle_en) begin + pwm_shares_uvw_i.u0_i = pwm_rd_data_a_shares_reg_d1[0]; + pwm_shares_uvw_i.u1_i = pwm_rd_data_a_shares_reg_d1[1]; + pwm_shares_uvw_i.u2_i = pwm_rd_data_a_shares_reg_d1[2]; + pwm_shares_uvw_i.u3_i = pwm_rd_data_a_shares_reg_d1[3]; + + pwm_shares_uvw_i.w0_i = accumulate ? share_mem_rd_data_reg[0] : '0; + pwm_shares_uvw_i.w1_i = accumulate ? share_mem_rd_data_reg[1] : '0; + pwm_shares_uvw_i.w2_i = accumulate ? share_mem_rd_data_reg[2] : '0; + pwm_shares_uvw_i.w3_i = accumulate ? share_mem_rd_data_reg[3] : '0; + + //In shuffle mode, the b input needs to be 1 cycle earlier. But here, non_shuffle mode is also delayed due to splitting. Hence other inputs are adjusted to match latency + pwm_shares_uvw_i.v0_i = pwm_rd_data_b_shares_reg[0]; + pwm_shares_uvw_i.v1_i = pwm_rd_data_b_shares_reg[1]; + pwm_shares_uvw_i.v2_i = pwm_rd_data_b_shares_reg[2]; + pwm_shares_uvw_i.v3_i = pwm_rd_data_b_shares_reg[3]; + end + else begin + pwm_shares_uvw_i.u0_i = pwm_rd_data_a_shares_reg_d1[0]; + pwm_shares_uvw_i.u1_i = pwm_rd_data_a_shares_reg_d1[1]; + pwm_shares_uvw_i.u2_i = pwm_rd_data_a_shares_reg_d1[2]; + pwm_shares_uvw_i.u3_i = pwm_rd_data_a_shares_reg_d1[3]; + + pwm_shares_uvw_i.w0_i = accumulate ? pairwm_mode ? share_mem_rd_data_reg[0] /*TODO: why not d1?*/ : share_mem_rd_data_reg_d1[0] : '0; + pwm_shares_uvw_i.w1_i = accumulate ? pairwm_mode ? share_mem_rd_data_reg[1] : share_mem_rd_data_reg_d1[1] : '0; + pwm_shares_uvw_i.w2_i = accumulate ? pairwm_mode ? share_mem_rd_data_reg[2] : share_mem_rd_data_reg_d1[2] : '0; + pwm_shares_uvw_i.w3_i = accumulate ? pairwm_mode ? share_mem_rd_data_reg[3] : share_mem_rd_data_reg_d1[3] : '0; + + pwm_shares_uvw_i.v0_i = pwm_rd_data_b_shares_reg_d1[0]; + pwm_shares_uvw_i.v1_i = pwm_rd_data_b_shares_reg_d1[1]; + pwm_shares_uvw_i.v2_i = pwm_rd_data_b_shares_reg_d1[2]; + pwm_shares_uvw_i.v3_i = pwm_rd_data_b_shares_reg_d1[3]; + end + + + end + else begin + pwm_shares_uvw_i = '{u0_i: '0, u1_i: '0, u2_i: '0, u3_i: '0, v0_i: '0, v1_i: '0, v2_i: '0, v3_i: '0, w0_i: '0, w1_i: '0, w2_i: '0, w3_i: '0}; + end + end + + always_comb hybrid_pw_uvw_i = {pw_uvw_i, uvw_i.w00_i, uvw_i.w01_i, uvw_i.w10_i, uvw_i.w11_i}; + + assign bf_enable_mux = ct_mode ? bf_enable + : gs_mode ? (masking_en_ctrl ? bf_enable_reg[1] : bf_enable_reg[0]) + : ((pwm_mode | pairwm_mode) & masking_en & ~shuffle_en) ? bf_enable_reg[2] : bf_enable_reg[0]; + assign mem_wren_mux = ~shuffle_en & ct_mode ? mem_wren_reg : mem_wren; + assign mem_wr_addr_mux = ~shuffle_en & ct_mode ? mem_wr_addr_reg : mem_wr_addr; + + + ntt_shuffle_buffer #( + .REG_SIZE(REG_SIZE) + ) buffer_inst0 ( + .clk(clk), + .reset_n(reset_n), + .zeroize(zeroize), + .mode(mode), + .shuffle_en(shuffle_en), + .wren(buf_wren), + .rden(buf_rden), + .wrptr(buf_wrptr), + .rdptr(buf_rdptr), + .wr_rst_count(buf_wr_rst_count), + .data_i(buf_data_i), + .buf_valid(buf0_valid), + .data_o(buf_data_o) + ); + + `ABR_ASSERT_NEVER(ASSERT_MASKING_EN, (masking_en & (mode inside {ct, pwa, pws})), clk, reset_n, masking_en); + +endmodule diff --git a/designs/Caliptra/src/adams-bridge/ntt_twiddle_lookup.sv b/designs/Caliptra/src/adams-bridge/ntt_twiddle_lookup.sv new file mode 100644 index 0000000..44108a5 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/ntt_twiddle_lookup.sv @@ -0,0 +1,1440 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +// +//====================================================================== +// +// twiddle_rom.sv +// -------- +// ROM contains twiddle factors for NTT and INTT +// +// +//====================================================================== + +module ntt_twiddle_lookup + import ntt_defines_pkg::*; +#( + parameter ADDR_WIDTH = 7, + parameter DATA_WIDTH = 24, + parameter KYBER_DATA_WIDTH = 12 +) +( + + input mode_t mode, + input wire [ADDR_WIDTH-1:0] raddr, + input wire mlkem, + output logic [(3*DATA_WIDTH)-1:0] rdata +); + +reg [(3*DATA_WIDTH)-1:0] ntt_twiddle_mem [84:0]; +reg [(3*DATA_WIDTH)-1:0] intt_twiddle_mem [84:0]; +reg [(3*KYBER_DATA_WIDTH)-1:0] kyber_ntt_twiddle_mem [84:0]; +reg [(3*KYBER_DATA_WIDTH)-1:0] kyber_intt_twiddle_mem [84:0]; + +always_comb begin + if (mlkem) //pairwm only uses NTT domain zeta values + rdata = (mode inside {ct, pairwm}) ? {12'h0, kyber_ntt_twiddle_mem[raddr]} : (mode == gs) ? {12'h0, kyber_intt_twiddle_mem[raddr]} : 'h0; + else + rdata = (mode == ct) ? ntt_twiddle_mem[raddr] : (mode == gs) ? intt_twiddle_mem[raddr] : 'h0; +end + +logic [255 : 0][(DATA_WIDTH)-1:0] zeta; +logic [255 : 0][(DATA_WIDTH)-1:0] zetainv; +logic [255 : 0][KYBER_DATA_WIDTH-1:0] kyber_zeta; +logic [255 : 0][KYBER_DATA_WIDTH-1:0] kyber_zetainv; + +assign zeta[0] = 23'h000001; +assign zeta[1] = 23'h495E02; +assign zeta[2] = 23'h397567; +assign zeta[3] = 23'h396569; +assign zeta[4] = 23'h4F062B; +assign zeta[5] = 23'h53DF73; +assign zeta[6] = 23'h4FE033; +assign zeta[7] = 23'h4F066B; +assign zeta[8] = 23'h76B1AE; +assign zeta[9] = 23'h360DD5; +assign zeta[10] = 23'h28EDB0; +assign zeta[11] = 23'h207FE4; +assign zeta[12] = 23'h397283; +assign zeta[13] = 23'h70894A; +assign zeta[14] = 23'h088192; +assign zeta[15] = 23'h6D3DC8; +assign zeta[16] = 23'h4C7294; +assign zeta[17] = 23'h41E0B4; +assign zeta[18] = 23'h28A3D2; +assign zeta[19] = 23'h66528A; +assign zeta[20] = 23'h4A18A7; +assign zeta[21] = 23'h794034; +assign zeta[22] = 23'h0A52EE; +assign zeta[23] = 23'h6B7D81; +assign zeta[24] = 23'h4E9F1D; +assign zeta[25] = 23'h1A2877; +assign zeta[26] = 23'h2571DF; +assign zeta[27] = 23'h1649EE; +assign zeta[28] = 23'h7611BD; +assign zeta[29] = 23'h492BB7; +assign zeta[30] = 23'h2AF697; +assign zeta[31] = 23'h22D8D5; +assign zeta[32] = 23'h36F72A; +assign zeta[33] = 23'h30911E; +assign zeta[34] = 23'h29D13F; +assign zeta[35] = 23'h492673; +assign zeta[36] = 23'h50685F; +assign zeta[37] = 23'h2010A2; +assign zeta[38] = 23'h3887F7; +assign zeta[39] = 23'h11B2C3; +assign zeta[40] = 23'h0603A4; +assign zeta[41] = 23'h0E2BED; +assign zeta[42] = 23'h10B72C; +assign zeta[43] = 23'h4A5F35; +assign zeta[44] = 23'h1F9D15; +assign zeta[45] = 23'h428CD4; +assign zeta[46] = 23'h3177F4; +assign zeta[47] = 23'h20E612; +assign zeta[48] = 23'h341C1D; +assign zeta[49] = 23'h1AD873; +assign zeta[50] = 23'h736681; +assign zeta[51] = 23'h49553F; +assign zeta[52] = 23'h3952F6; +assign zeta[53] = 23'h62564A; +assign zeta[54] = 23'h65AD05; +assign zeta[55] = 23'h439A1C; +assign zeta[56] = 23'h53AA5F; +assign zeta[57] = 23'h30B622; +assign zeta[58] = 23'h087F38; +assign zeta[59] = 23'h3B0E6D; +assign zeta[60] = 23'h2C83DA; +assign zeta[61] = 23'h1C496E; +assign zeta[62] = 23'h330E2B; +assign zeta[63] = 23'h1C5B70; +assign zeta[64] = 23'h2EE3F1; +assign zeta[65] = 23'h137EB9; +assign zeta[66] = 23'h57A930; +assign zeta[67] = 23'h3AC6EF; +assign zeta[68] = 23'h3FD54C; +assign zeta[69] = 23'h4EB2EA; +assign zeta[70] = 23'h503EE1; +assign zeta[71] = 23'h7BB175; +assign zeta[72] = 23'h2648B4; +assign zeta[73] = 23'h1EF256; +assign zeta[74] = 23'h1D90A2; +assign zeta[75] = 23'h45A6D4; +assign zeta[76] = 23'h2AE59B; +assign zeta[77] = 23'h52589C; +assign zeta[78] = 23'h6EF1F5; +assign zeta[79] = 23'h3F7288; +assign zeta[80] = 23'h175102; +assign zeta[81] = 23'h075D59; +assign zeta[82] = 23'h1187BA; +assign zeta[83] = 23'h52ACA9; +assign zeta[84] = 23'h773E9E; +assign zeta[85] = 23'h0296D8; +assign zeta[86] = 23'h2592EC; +assign zeta[87] = 23'h4CFF12; +assign zeta[88] = 23'h404CE8; +assign zeta[89] = 23'h4AA582; +assign zeta[90] = 23'h1E54E6; +assign zeta[91] = 23'h4F16C1; +assign zeta[92] = 23'h1A7E79; +assign zeta[93] = 23'h03978F; +assign zeta[94] = 23'h4E4817; +assign zeta[95] = 23'h31B859; +assign zeta[96] = 23'h5884CC; +assign zeta[97] = 23'h1B4827; +assign zeta[98] = 23'h5B63D0; +assign zeta[99] = 23'h5D787A; +assign zeta[100] = 23'h35225E; +assign zeta[101] = 23'h400C7E; +assign zeta[102] = 23'h6C09D1; +assign zeta[103] = 23'h5BD532; +assign zeta[104] = 23'h6BC4D3; +assign zeta[105] = 23'h258ECB; +assign zeta[106] = 23'h2E534C; +assign zeta[107] = 23'h097A6C; +assign zeta[108] = 23'h3B8820; +assign zeta[109] = 23'h6D285C; +assign zeta[110] = 23'h2CA4F8; +assign zeta[111] = 23'h337CAA; +assign zeta[112] = 23'h14B2A0; +assign zeta[113] = 23'h558536; +assign zeta[114] = 23'h28F186; +assign zeta[115] = 23'h55795D; +assign zeta[116] = 23'h4AF670; +assign zeta[117] = 23'h234A86; +assign zeta[118] = 23'h75E826; +assign zeta[119] = 23'h78DE66; +assign zeta[120] = 23'h05528C; +assign zeta[121] = 23'h7ADF59; +assign zeta[122] = 23'h0F6E17; +assign zeta[123] = 23'h5BF3DA; +assign zeta[124] = 23'h459B7E; +assign zeta[125] = 23'h628B34; +assign zeta[126] = 23'h5DBECB; +assign zeta[127] = 23'h1A9E7B; +assign zeta[128] = 23'h0006D9; +assign zeta[129] = 23'h6257C5; +assign zeta[130] = 23'h574B3C; +assign zeta[131] = 23'h69A8EF; +assign zeta[132] = 23'h289838; +assign zeta[133] = 23'h64B5FE; +assign zeta[134] = 23'h7EF8F5; +assign zeta[135] = 23'h2A4E78; +assign zeta[136] = 23'h120A23; +assign zeta[137] = 23'h0154A8; +assign zeta[138] = 23'h09B7FF; +assign zeta[139] = 23'h435E87; +assign zeta[140] = 23'h437FF8; +assign zeta[141] = 23'h5CD5B4; +assign zeta[142] = 23'h4DC04E; +assign zeta[143] = 23'h4728AF; +assign zeta[144] = 23'h7F735D; +assign zeta[145] = 23'h0C8D0D; +assign zeta[146] = 23'h0F66D5; +assign zeta[147] = 23'h5A6D80; +assign zeta[148] = 23'h61AB98; +assign zeta[149] = 23'h185D96; +assign zeta[150] = 23'h437F31; +assign zeta[151] = 23'h468298; +assign zeta[152] = 23'h662960; +assign zeta[153] = 23'h4BD579; +assign zeta[154] = 23'h28DE06; +assign zeta[155] = 23'h465D8D; +assign zeta[156] = 23'h49B0E3; +assign zeta[157] = 23'h09B434; +assign zeta[158] = 23'h7C0DB3; +assign zeta[159] = 23'h5A68B0; +assign zeta[160] = 23'h409BA9; +assign zeta[161] = 23'h64D3D5; +assign zeta[162] = 23'h21762A; +assign zeta[163] = 23'h658591; +assign zeta[164] = 23'h246E39; +assign zeta[165] = 23'h48C39B; +assign zeta[166] = 23'h7BC759; +assign zeta[167] = 23'h4F5859; +assign zeta[168] = 23'h392DB2; +assign zeta[169] = 23'h230923; +assign zeta[170] = 23'h12EB67; +assign zeta[171] = 23'h454DF2; +assign zeta[172] = 23'h30C31C; +assign zeta[173] = 23'h285424; +assign zeta[174] = 23'h13232E; +assign zeta[175] = 23'h7FAF80; +assign zeta[176] = 23'h2DBFCB; +assign zeta[177] = 23'h022A0B; +assign zeta[178] = 23'h7E832C; +assign zeta[179] = 23'h26587A; +assign zeta[180] = 23'h6B3375; +assign zeta[181] = 23'h095B76; +assign zeta[182] = 23'h6BE1CC; +assign zeta[183] = 23'h5E061E; +assign zeta[184] = 23'h78E00D; +assign zeta[185] = 23'h628C37; +assign zeta[186] = 23'h3DA604; +assign zeta[187] = 23'h4AE53C; +assign zeta[188] = 23'h1F1D68; +assign zeta[189] = 23'h6330BB; +assign zeta[190] = 23'h7361B8; +assign zeta[191] = 23'h5EA06C; +assign zeta[192] = 23'h671AC7; +assign zeta[193] = 23'h201FC6; +assign zeta[194] = 23'h5BA4FF; +assign zeta[195] = 23'h60D772; +assign zeta[196] = 23'h08F201; +assign zeta[197] = 23'h6DE024; +assign zeta[198] = 23'h080E6D; +assign zeta[199] = 23'h56038E; +assign zeta[200] = 23'h695688; +assign zeta[201] = 23'h1E6D3E; +assign zeta[202] = 23'h2603BD; +assign zeta[203] = 23'h6A9DFA; +assign zeta[204] = 23'h07C017; +assign zeta[205] = 23'h6DBFD4; +assign zeta[206] = 23'h74D0BD; +assign zeta[207] = 23'h63E1E3; +assign zeta[208] = 23'h519573; +assign zeta[209] = 23'h7AB60D; +assign zeta[210] = 23'h2867BA; +assign zeta[211] = 23'h2DECD4; +assign zeta[212] = 23'h58018C; +assign zeta[213] = 23'h3F4CF5; +assign zeta[214] = 23'h0B7009; +assign zeta[215] = 23'h427E23; +assign zeta[216] = 23'h3CBD37; +assign zeta[217] = 23'h273333; +assign zeta[218] = 23'h673957; +assign zeta[219] = 23'h1A4B5D; +assign zeta[220] = 23'h196926; +assign zeta[221] = 23'h1EF206; +assign zeta[222] = 23'h11C14E; +assign zeta[223] = 23'h4C76C8; +assign zeta[224] = 23'h3CF42F; +assign zeta[225] = 23'h7FB19A; +assign zeta[226] = 23'h6AF66C; +assign zeta[227] = 23'h2E1669; +assign zeta[228] = 23'h3352D6; +assign zeta[229] = 23'h034760; +assign zeta[230] = 23'h085260; +assign zeta[231] = 23'h741E78; +assign zeta[232] = 23'h2F6316; +assign zeta[233] = 23'h6F0A11; +assign zeta[234] = 23'h07C0F1; +assign zeta[235] = 23'h776D0B; +assign zeta[236] = 23'h0D1FF0; +assign zeta[237] = 23'h345824; +assign zeta[238] = 23'h0223D4; +assign zeta[239] = 23'h68C559; +assign zeta[240] = 23'h5E8885; +assign zeta[241] = 23'h2FAA32; +assign zeta[242] = 23'h23FC65; +assign zeta[243] = 23'h5E6942; +assign zeta[244] = 23'h51E0ED; +assign zeta[245] = 23'h65ADB3; +assign zeta[246] = 23'h2CA5E6; +assign zeta[247] = 23'h79E1FE; +assign zeta[248] = 23'h7B4064; +assign zeta[249] = 23'h35E1DD; +assign zeta[250] = 23'h433AAC; +assign zeta[251] = 23'h464ADE; +assign zeta[252] = 23'h1CFE14; +assign zeta[253] = 23'h73F1CE; +assign zeta[254] = 23'h10170E; +assign zeta[255] = 23'h74B6D7; + +//------------------------------------------------------------------------------------ + + +assign zetainv[0] = 23'h7FE000; +assign zetainv[1] = 23'h3681FF; +assign zetainv[2] = 23'h466A9A; +assign zetainv[3] = 23'h467A98; +assign zetainv[4] = 23'h30D9D6; +assign zetainv[5] = 23'h2C008E; +assign zetainv[6] = 23'h2FFFCE; +assign zetainv[7] = 23'h30D996; +assign zetainv[8] = 23'h092E53; +assign zetainv[9] = 23'h49D22C; +assign zetainv[10] = 23'h56F251; +assign zetainv[11] = 23'h5F601D; +assign zetainv[12] = 23'h466D7E; +assign zetainv[13] = 23'h0F56B7; +assign zetainv[14] = 23'h775E6F; +assign zetainv[15] = 23'h12A239; +assign zetainv[16] = 23'h336D6D; +assign zetainv[17] = 23'h3DFF4D; +assign zetainv[18] = 23'h573C2F; +assign zetainv[19] = 23'h198D77; +assign zetainv[20] = 23'h35C75A; +assign zetainv[21] = 23'h069FCD; +assign zetainv[22] = 23'h758D13; +assign zetainv[23] = 23'h146280; +assign zetainv[24] = 23'h3140E4; +assign zetainv[25] = 23'h65B78A; +assign zetainv[26] = 23'h5A6E22; +assign zetainv[27] = 23'h699613; +assign zetainv[28] = 23'h09CE44; +assign zetainv[29] = 23'h36B44A; +assign zetainv[30] = 23'h54E96A; +assign zetainv[31] = 23'h5D072C; +assign zetainv[32] = 23'h48E8D7; +assign zetainv[33] = 23'h4F4EE3; +assign zetainv[34] = 23'h560EC2; +assign zetainv[35] = 23'h36B98E; +assign zetainv[36] = 23'h2F77A2; +assign zetainv[37] = 23'h5FCF5F; +assign zetainv[38] = 23'h47580A; +assign zetainv[39] = 23'h6E2D3E; +assign zetainv[40] = 23'h79DC5D; +assign zetainv[41] = 23'h71B414; +assign zetainv[42] = 23'h6F28D5; +assign zetainv[43] = 23'h3580CC; +assign zetainv[44] = 23'h6042EC; +assign zetainv[45] = 23'h3D532D; +assign zetainv[46] = 23'h4E680D; +assign zetainv[47] = 23'h5EF9EF; +assign zetainv[48] = 23'h4BC3E4; +assign zetainv[49] = 23'h65078E; +assign zetainv[50] = 23'h0C7980; +assign zetainv[51] = 23'h368AC2; +assign zetainv[52] = 23'h468D0B; +assign zetainv[53] = 23'h1D89B7; +assign zetainv[54] = 23'h1A32FC; +assign zetainv[55] = 23'h3C45E5; +assign zetainv[56] = 23'h2C35A2; +assign zetainv[57] = 23'h4F29DF; +assign zetainv[58] = 23'h7760C9; +assign zetainv[59] = 23'h44D194; +assign zetainv[60] = 23'h535C27; +assign zetainv[61] = 23'h639693; +assign zetainv[62] = 23'h4CD1D6; +assign zetainv[63] = 23'h638491; +assign zetainv[64] = 23'h50FC10; +assign zetainv[65] = 23'h6C6148; +assign zetainv[66] = 23'h2836D1; +assign zetainv[67] = 23'h451912; +assign zetainv[68] = 23'h400AB5; +assign zetainv[69] = 23'h312D17; +assign zetainv[70] = 23'h2FA120; +assign zetainv[71] = 23'h042E8C; +assign zetainv[72] = 23'h59974D; +assign zetainv[73] = 23'h60EDAB; +assign zetainv[74] = 23'h624F5F; +assign zetainv[75] = 23'h3A392D; +assign zetainv[76] = 23'h54FA66; +assign zetainv[77] = 23'h2D8765; +assign zetainv[78] = 23'h10EE0C; +assign zetainv[79] = 23'h406D79; +assign zetainv[80] = 23'h688EFF; +assign zetainv[81] = 23'h7882A8; +assign zetainv[82] = 23'h6E5847; +assign zetainv[83] = 23'h2D3358; +assign zetainv[84] = 23'h08A163; +assign zetainv[85] = 23'h7D4929; +assign zetainv[86] = 23'h5A4D15; +assign zetainv[87] = 23'h32E0EF; +assign zetainv[88] = 23'h3F9319; +assign zetainv[89] = 23'h353A7F; +assign zetainv[90] = 23'h618B1B; +assign zetainv[91] = 23'h30C940; +assign zetainv[92] = 23'h656188; +assign zetainv[93] = 23'h7C4872; +assign zetainv[94] = 23'h3197EA; +assign zetainv[95] = 23'h4E27A8; +assign zetainv[96] = 23'h275B35; +assign zetainv[97] = 23'h6497DA; +assign zetainv[98] = 23'h247C31; +assign zetainv[99] = 23'h226787; +assign zetainv[100] = 23'h4ABDA3; +assign zetainv[101] = 23'h3FD383; +assign zetainv[102] = 23'h13D630; +assign zetainv[103] = 23'h240ACF; +assign zetainv[104] = 23'h141B2E; +assign zetainv[105] = 23'h5A5136; +assign zetainv[106] = 23'h518CB5; +assign zetainv[107] = 23'h766595; +assign zetainv[108] = 23'h4457E1; +assign zetainv[109] = 23'h12B7A5; +assign zetainv[110] = 23'h533B09; +assign zetainv[111] = 23'h4C6357; +assign zetainv[112] = 23'h6B2D61; +assign zetainv[113] = 23'h2A5ACB; +assign zetainv[114] = 23'h56EE7B; +assign zetainv[115] = 23'h2A66A4; +assign zetainv[116] = 23'h34E991; +assign zetainv[117] = 23'h5C957B; +assign zetainv[118] = 23'h09F7DB; +assign zetainv[119] = 23'h07019B; +assign zetainv[120] = 23'h7A8D75; +assign zetainv[121] = 23'h0500A8; +assign zetainv[122] = 23'h7071EA; +assign zetainv[123] = 23'h23EC27; +assign zetainv[124] = 23'h3A4483; +assign zetainv[125] = 23'h1D54CD; +assign zetainv[126] = 23'h222136; +assign zetainv[127] = 23'h654186; +assign zetainv[128] = 23'h7FD928; +assign zetainv[129] = 23'h1D883C; +assign zetainv[130] = 23'h2894C5; +assign zetainv[131] = 23'h163712; +assign zetainv[132] = 23'h5747C9; +assign zetainv[133] = 23'h1B2A03; +assign zetainv[134] = 23'h00E70C; +assign zetainv[135] = 23'h559189; +assign zetainv[136] = 23'h6DD5DE; +assign zetainv[137] = 23'h7E8B59; +assign zetainv[138] = 23'h762802; +assign zetainv[139] = 23'h3C817A; +assign zetainv[140] = 23'h3C6009; +assign zetainv[141] = 23'h230A4D; +assign zetainv[142] = 23'h321FB3; +assign zetainv[143] = 23'h38B752; +assign zetainv[144] = 23'h006CA4; +assign zetainv[145] = 23'h7352F4; +assign zetainv[146] = 23'h70792C; +assign zetainv[147] = 23'h257281; +assign zetainv[148] = 23'h1E3469; +assign zetainv[149] = 23'h67826B; +assign zetainv[150] = 23'h3C60D0; +assign zetainv[151] = 23'h395D69; +assign zetainv[152] = 23'h19B6A1; +assign zetainv[153] = 23'h340A88; +assign zetainv[154] = 23'h5701FB; +assign zetainv[155] = 23'h398274; +assign zetainv[156] = 23'h362F1E; +assign zetainv[157] = 23'h762BCD; +assign zetainv[158] = 23'h03D24E; +assign zetainv[159] = 23'h257751; +assign zetainv[160] = 23'h3F4458; +assign zetainv[161] = 23'h1B0C2C; +assign zetainv[162] = 23'h5E69D7; +assign zetainv[163] = 23'h1A5A70; +assign zetainv[164] = 23'h5B71C8; +assign zetainv[165] = 23'h371C66; +assign zetainv[166] = 23'h0418A8; +assign zetainv[167] = 23'h3087A8; +assign zetainv[168] = 23'h46B24F; +assign zetainv[169] = 23'h5CD6DE; +assign zetainv[170] = 23'h6CF49A; +assign zetainv[171] = 23'h3A920F; +assign zetainv[172] = 23'h4F1CE5; +assign zetainv[173] = 23'h578BDD; +assign zetainv[174] = 23'h6CBCD3; +assign zetainv[175] = 23'h003081; +assign zetainv[176] = 23'h522036; +assign zetainv[177] = 23'h7DB5F6; +assign zetainv[178] = 23'h015CD5; +assign zetainv[179] = 23'h598787; +assign zetainv[180] = 23'h14AC8C; +assign zetainv[181] = 23'h76848B; +assign zetainv[182] = 23'h13FE35; +assign zetainv[183] = 23'h21D9E3; +assign zetainv[184] = 23'h06FFF4; +assign zetainv[185] = 23'h1D53CA; +assign zetainv[186] = 23'h4239FD; +assign zetainv[187] = 23'h34FAC5; +assign zetainv[188] = 23'h60C299; +assign zetainv[189] = 23'h1CAF46; +assign zetainv[190] = 23'h0C7E49; +assign zetainv[191] = 23'h213F95; +assign zetainv[192] = 23'h18C53A; +assign zetainv[193] = 23'h5FC03B; +assign zetainv[194] = 23'h243B02; +assign zetainv[195] = 23'h1F088F; +assign zetainv[196] = 23'h76EE00; +assign zetainv[197] = 23'h11FFDD; +assign zetainv[198] = 23'h77D194; +assign zetainv[199] = 23'h29DC73; +assign zetainv[200] = 23'h168979; +assign zetainv[201] = 23'h6172C3; +assign zetainv[202] = 23'h59DC44; +assign zetainv[203] = 23'h154207; +assign zetainv[204] = 23'h781FEA; +assign zetainv[205] = 23'h12202D; +assign zetainv[206] = 23'h0B0F44; +assign zetainv[207] = 23'h1BFE1E; +assign zetainv[208] = 23'h2E4A8E; +assign zetainv[209] = 23'h0529F4; +assign zetainv[210] = 23'h577847; +assign zetainv[211] = 23'h51F32D; +assign zetainv[212] = 23'h27DE75; +assign zetainv[213] = 23'h40930C; +assign zetainv[214] = 23'h746FF8; +assign zetainv[215] = 23'h3D61DE; +assign zetainv[216] = 23'h4322CA; +assign zetainv[217] = 23'h58ACCE; +assign zetainv[218] = 23'h18A6AA; +assign zetainv[219] = 23'h6594A4; +assign zetainv[220] = 23'h6676DB; +assign zetainv[221] = 23'h60EDFB; +assign zetainv[222] = 23'h6E1EB3; +assign zetainv[223] = 23'h336939; +assign zetainv[224] = 23'h42EBD2; +assign zetainv[225] = 23'h002E67; +assign zetainv[226] = 23'h14E995; +assign zetainv[227] = 23'h51C998; +assign zetainv[228] = 23'h4C8D2B; +assign zetainv[229] = 23'h7C98A1; +assign zetainv[230] = 23'h778DA1; +assign zetainv[231] = 23'h0BC189; +assign zetainv[232] = 23'h507CEB; +assign zetainv[233] = 23'h10D5F0; +assign zetainv[234] = 23'h781F10; +assign zetainv[235] = 23'h0872F6; +assign zetainv[236] = 23'h72C011; +assign zetainv[237] = 23'h4B87DD; +assign zetainv[238] = 23'h7DBC2D; +assign zetainv[239] = 23'h171AA8; +assign zetainv[240] = 23'h21577C; +assign zetainv[241] = 23'h5035CF; +assign zetainv[242] = 23'h5BE39C; +assign zetainv[243] = 23'h2176BF; +assign zetainv[244] = 23'h2DFF14; +assign zetainv[245] = 23'h1A324E; +assign zetainv[246] = 23'h533A1B; +assign zetainv[247] = 23'h05FE03; +assign zetainv[248] = 23'h049F9D; +assign zetainv[249] = 23'h49FE24; +assign zetainv[250] = 23'h3CA555; +assign zetainv[251] = 23'h399523; +assign zetainv[252] = 23'h62E1ED; +assign zetainv[253] = 23'h0BEE33; +assign zetainv[254] = 23'h6FC8F3; +assign zetainv[255] = 23'h0B292A; + +//------------------------------------------------------------------------------------ + +assign kyber_zeta[0] = 12'h001 ; +assign kyber_zeta[1] = 12'h6C1 ; +assign kyber_zeta[2] = 12'hA14 ; +assign kyber_zeta[3] = 12'hCD9 ; +assign kyber_zeta[4] = 12'hA52 ; +assign kyber_zeta[5] = 12'h276 ; +assign kyber_zeta[6] = 12'h769 ; +assign kyber_zeta[7] = 12'h350 ; +assign kyber_zeta[8] = 12'h426 ; +assign kyber_zeta[9] = 12'h77F ; +assign kyber_zeta[10] = 12'h0C1 ; +assign kyber_zeta[11] = 12'h31D ; +assign kyber_zeta[12] = 12'hAE2 ; +assign kyber_zeta[13] = 12'hCBC ; +assign kyber_zeta[14] = 12'h239 ; +assign kyber_zeta[15] = 12'h6D2 ; +assign kyber_zeta[16] = 12'h128 ; +assign kyber_zeta[17] = 12'h98F ; +assign kyber_zeta[18] = 12'h53B ; +assign kyber_zeta[19] = 12'h5C4 ; +assign kyber_zeta[20] = 12'hBE6 ; +assign kyber_zeta[21] = 12'h038 ; +assign kyber_zeta[22] = 12'h8C0 ; +assign kyber_zeta[23] = 12'h535 ; +assign kyber_zeta[24] = 12'h592 ; +assign kyber_zeta[25] = 12'h82E ; +assign kyber_zeta[26] = 12'h217 ; +assign kyber_zeta[27] = 12'hB42 ; +assign kyber_zeta[28] = 12'h959 ; +assign kyber_zeta[29] = 12'hB3F ; +assign kyber_zeta[30] = 12'h7B6 ; +assign kyber_zeta[31] = 12'h335 ; +assign kyber_zeta[32] = 12'h121 ; +assign kyber_zeta[33] = 12'h14B ; +assign kyber_zeta[34] = 12'hCB5 ; +assign kyber_zeta[35] = 12'h6DC ; +assign kyber_zeta[36] = 12'h4AD ; +assign kyber_zeta[37] = 12'h900 ; +assign kyber_zeta[38] = 12'h8E5 ; +assign kyber_zeta[39] = 12'h807 ; +assign kyber_zeta[40] = 12'h28A ; +assign kyber_zeta[41] = 12'h7B9 ; +assign kyber_zeta[42] = 12'h9D1 ; +assign kyber_zeta[43] = 12'h278 ; +assign kyber_zeta[44] = 12'hB31 ; +assign kyber_zeta[45] = 12'h021 ; +assign kyber_zeta[46] = 12'h528 ; +assign kyber_zeta[47] = 12'h77B ; +assign kyber_zeta[48] = 12'h90F ; +assign kyber_zeta[49] = 12'h59B ; +assign kyber_zeta[50] = 12'h327 ; +assign kyber_zeta[51] = 12'h1C4 ; +assign kyber_zeta[52] = 12'h59E ; +assign kyber_zeta[53] = 12'hB34 ; +assign kyber_zeta[54] = 12'h5FE ; +assign kyber_zeta[55] = 12'h962 ; +assign kyber_zeta[56] = 12'hA57 ; +assign kyber_zeta[57] = 12'hA39 ; +assign kyber_zeta[58] = 12'h5C9 ; +assign kyber_zeta[59] = 12'h288 ; +assign kyber_zeta[60] = 12'h9AA ; +assign kyber_zeta[61] = 12'hC26 ; +assign kyber_zeta[62] = 12'h4CB ; +assign kyber_zeta[63] = 12'h38E ; +assign kyber_zeta[64] = 12'h011 ; +assign kyber_zeta[65] = 12'hAC9 ; +assign kyber_zeta[66] = 12'h247 ; +assign kyber_zeta[67] = 12'hA59 ; +assign kyber_zeta[68] = 12'h665 ; +assign kyber_zeta[69] = 12'h2D3 ; +assign kyber_zeta[70] = 12'h8F0 ; +assign kyber_zeta[71] = 12'h44C ; +assign kyber_zeta[72] = 12'h581 ; +assign kyber_zeta[73] = 12'hA66 ; +assign kyber_zeta[74] = 12'hCD1 ; +assign kyber_zeta[75] = 12'h0E9 ; +assign kyber_zeta[76] = 12'h2F4 ; +assign kyber_zeta[77] = 12'h86C ; +assign kyber_zeta[78] = 12'hBC7 ; +assign kyber_zeta[79] = 12'hBEA ; +assign kyber_zeta[80] = 12'h6A7 ; +assign kyber_zeta[81] = 12'h673 ; +assign kyber_zeta[82] = 12'hAE5 ; +assign kyber_zeta[83] = 12'h6FD ; +assign kyber_zeta[84] = 12'h737 ; +assign kyber_zeta[85] = 12'h3B8 ; +assign kyber_zeta[86] = 12'h5B5 ; +assign kyber_zeta[87] = 12'hA7F ; +assign kyber_zeta[88] = 12'h3AB ; +assign kyber_zeta[89] = 12'h904 ; +assign kyber_zeta[90] = 12'h985 ; +assign kyber_zeta[91] = 12'h954 ; +assign kyber_zeta[92] = 12'h2DD ; +assign kyber_zeta[93] = 12'h921 ; +assign kyber_zeta[94] = 12'h10C ; +assign kyber_zeta[95] = 12'h281 ; +assign kyber_zeta[96] = 12'h630 ; +assign kyber_zeta[97] = 12'h8FA ; +assign kyber_zeta[98] = 12'h7F5 ; +assign kyber_zeta[99] = 12'hC94 ; +assign kyber_zeta[100] = 12'h177 ; +assign kyber_zeta[101] = 12'h9F5 ; +assign kyber_zeta[102] = 12'h82A ; +assign kyber_zeta[103] = 12'h66D ; +assign kyber_zeta[104] = 12'h427 ; +assign kyber_zeta[105] = 12'h13F ; +assign kyber_zeta[106] = 12'hAD5 ; +assign kyber_zeta[107] = 12'h2F5 ; +assign kyber_zeta[108] = 12'h833 ; +assign kyber_zeta[109] = 12'h231 ; +assign kyber_zeta[110] = 12'h9A2 ; +assign kyber_zeta[111] = 12'hA22 ; +assign kyber_zeta[112] = 12'hAF4 ; +assign kyber_zeta[113] = 12'h444 ; +assign kyber_zeta[114] = 12'h193 ; +assign kyber_zeta[115] = 12'h402 ; +assign kyber_zeta[116] = 12'h477 ; +assign kyber_zeta[117] = 12'h866 ; +assign kyber_zeta[118] = 12'hAD7 ; +assign kyber_zeta[119] = 12'h376 ; +assign kyber_zeta[120] = 12'h6BA ; +assign kyber_zeta[121] = 12'h4BC ; +assign kyber_zeta[122] = 12'h752 ; +assign kyber_zeta[123] = 12'h405 ; +assign kyber_zeta[124] = 12'h83E ; +assign kyber_zeta[125] = 12'hB77 ; +assign kyber_zeta[126] = 12'h375 ; +assign kyber_zeta[127] = 12'h86A ; +assign kyber_zeta[128] = 12'h011 ; +assign kyber_zeta[129] = 12'hCF0 ; +assign kyber_zeta[130] = 12'hAC9 ; +assign kyber_zeta[131] = 12'h238 ; +assign kyber_zeta[132] = 12'h247 ; +assign kyber_zeta[133] = 12'hABA ; +assign kyber_zeta[134] = 12'hA59 ; +assign kyber_zeta[135] = 12'h2A8 ; +assign kyber_zeta[136] = 12'h665 ; +assign kyber_zeta[137] = 12'h69C ; +assign kyber_zeta[138] = 12'h2D3 ; +assign kyber_zeta[139] = 12'hA2E ; +assign kyber_zeta[140] = 12'h8F0 ; +assign kyber_zeta[141] = 12'h411 ; +assign kyber_zeta[142] = 12'h44C ; +assign kyber_zeta[143] = 12'h8B5 ; +assign kyber_zeta[144] = 12'h581 ; +assign kyber_zeta[145] = 12'h780 ; +assign kyber_zeta[146] = 12'hA66 ; +assign kyber_zeta[147] = 12'h29B ; +assign kyber_zeta[148] = 12'hCD1 ; +assign kyber_zeta[149] = 12'h030 ; +assign kyber_zeta[150] = 12'h0E9 ; +assign kyber_zeta[151] = 12'hC18 ; +assign kyber_zeta[152] = 12'h2F4 ; +assign kyber_zeta[153] = 12'hA0D ; +assign kyber_zeta[154] = 12'h86C ; +assign kyber_zeta[155] = 12'h495 ; +assign kyber_zeta[156] = 12'hBC7 ; +assign kyber_zeta[157] = 12'h13A ; +assign kyber_zeta[158] = 12'hBEA ; +assign kyber_zeta[159] = 12'h117 ; +assign kyber_zeta[160] = 12'h6A7 ; +assign kyber_zeta[161] = 12'h65A ; +assign kyber_zeta[162] = 12'h673 ; +assign kyber_zeta[163] = 12'h68E ; +assign kyber_zeta[164] = 12'hAE5 ; +assign kyber_zeta[165] = 12'h21C ; +assign kyber_zeta[166] = 12'h6FD ; +assign kyber_zeta[167] = 12'h604 ; +assign kyber_zeta[168] = 12'h737 ; +assign kyber_zeta[169] = 12'h5CA ; +assign kyber_zeta[170] = 12'h3B8 ; +assign kyber_zeta[171] = 12'h949 ; +assign kyber_zeta[172] = 12'h5B5 ; +assign kyber_zeta[173] = 12'h74C ; +assign kyber_zeta[174] = 12'hA7F ; +assign kyber_zeta[175] = 12'h282 ; +assign kyber_zeta[176] = 12'h3AB ; +assign kyber_zeta[177] = 12'h956 ; +assign kyber_zeta[178] = 12'h904 ; +assign kyber_zeta[179] = 12'h3FD ; +assign kyber_zeta[180] = 12'h985 ; +assign kyber_zeta[181] = 12'h37C ; +assign kyber_zeta[182] = 12'h954 ; +assign kyber_zeta[183] = 12'h3AD ; +assign kyber_zeta[184] = 12'h2DD ; +assign kyber_zeta[185] = 12'hA24 ; +assign kyber_zeta[186] = 12'h921 ; +assign kyber_zeta[187] = 12'h3E0 ; +assign kyber_zeta[188] = 12'h10C ; +assign kyber_zeta[189] = 12'hBF5 ; +assign kyber_zeta[190] = 12'h281 ; +assign kyber_zeta[191] = 12'hA80 ; +assign kyber_zeta[192] = 12'h630 ; +assign kyber_zeta[193] = 12'h6D1 ; +assign kyber_zeta[194] = 12'h8FA ; +assign kyber_zeta[195] = 12'h407 ; +assign kyber_zeta[196] = 12'h7F5 ; +assign kyber_zeta[197] = 12'h50C ; +assign kyber_zeta[198] = 12'hC94 ; +assign kyber_zeta[199] = 12'h06D ; +assign kyber_zeta[200] = 12'h177 ; +assign kyber_zeta[201] = 12'hB8A ; +assign kyber_zeta[202] = 12'h9F5 ; +assign kyber_zeta[203] = 12'h30C ; +assign kyber_zeta[204] = 12'h82A ; +assign kyber_zeta[205] = 12'h4D7 ; +assign kyber_zeta[206] = 12'h66D ; +assign kyber_zeta[207] = 12'h694 ; +assign kyber_zeta[208] = 12'h427 ; +assign kyber_zeta[209] = 12'h8DA ; +assign kyber_zeta[210] = 12'h13F ; +assign kyber_zeta[211] = 12'hBC2 ; +assign kyber_zeta[212] = 12'hAD5 ; +assign kyber_zeta[213] = 12'h22C ; +assign kyber_zeta[214] = 12'h2F5 ; +assign kyber_zeta[215] = 12'hA0C ; +assign kyber_zeta[216] = 12'h833 ; +assign kyber_zeta[217] = 12'h4CE ; +assign kyber_zeta[218] = 12'h231 ; +assign kyber_zeta[219] = 12'hAD0 ; +assign kyber_zeta[220] = 12'h9A2 ; +assign kyber_zeta[221] = 12'h35F ; +assign kyber_zeta[222] = 12'hA22 ; +assign kyber_zeta[223] = 12'h2DF ; +assign kyber_zeta[224] = 12'hAF4 ; +assign kyber_zeta[225] = 12'h20D ; +assign kyber_zeta[226] = 12'h444 ; +assign kyber_zeta[227] = 12'h8BD ; +assign kyber_zeta[228] = 12'h193 ; +assign kyber_zeta[229] = 12'hB6E ; +assign kyber_zeta[230] = 12'h402 ; +assign kyber_zeta[231] = 12'h8FF ; +assign kyber_zeta[232] = 12'h477 ; +assign kyber_zeta[233] = 12'h88A ; +assign kyber_zeta[234] = 12'h866 ; +assign kyber_zeta[235] = 12'h49B ; +assign kyber_zeta[236] = 12'hAD7 ; +assign kyber_zeta[237] = 12'h22A ; +assign kyber_zeta[238] = 12'h376 ; +assign kyber_zeta[239] = 12'h98B ; +assign kyber_zeta[240] = 12'h6BA ; +assign kyber_zeta[241] = 12'h647 ; +assign kyber_zeta[242] = 12'h4BC ; +assign kyber_zeta[243] = 12'h845 ; +assign kyber_zeta[244] = 12'h752 ; +assign kyber_zeta[245] = 12'h5AF ; +assign kyber_zeta[246] = 12'h405 ; +assign kyber_zeta[247] = 12'h8FC ; +assign kyber_zeta[248] = 12'h83E ; +assign kyber_zeta[249] = 12'h4C3 ; +assign kyber_zeta[250] = 12'hB77 ; +assign kyber_zeta[251] = 12'h18A ; +assign kyber_zeta[252] = 12'h375 ; +assign kyber_zeta[253] = 12'h98C ; +assign kyber_zeta[254] = 12'h86A ; +assign kyber_zeta[255] = 12'h497 ; + +//------------------------------------------------------------------------------------ + +assign kyber_zetainv[0] = 12'hD00 ; +assign kyber_zetainv[1] = 12'h640 ; +assign kyber_zetainv[2] = 12'h2ED ; +assign kyber_zetainv[3] = 12'h028 ; +assign kyber_zetainv[4] = 12'h2AF ; +assign kyber_zetainv[5] = 12'hA8B ; +assign kyber_zetainv[6] = 12'h598 ; +assign kyber_zetainv[7] = 12'h9B1 ; +assign kyber_zetainv[8] = 12'h8DB ; +assign kyber_zetainv[9] = 12'h582 ; +assign kyber_zetainv[10] = 12'hC40 ; +assign kyber_zetainv[11] = 12'h9E4 ; +assign kyber_zetainv[12] = 12'h21F ; +assign kyber_zetainv[13] = 12'h045 ; +assign kyber_zetainv[14] = 12'hAC8 ; +assign kyber_zetainv[15] = 12'h62F ; +assign kyber_zetainv[16] = 12'hBD9 ; +assign kyber_zetainv[17] = 12'h372 ; +assign kyber_zetainv[18] = 12'h7C6 ; +assign kyber_zetainv[19] = 12'h73D ; +assign kyber_zetainv[20] = 12'h11B ; +assign kyber_zetainv[21] = 12'hCC9 ; +assign kyber_zetainv[22] = 12'h441 ; +assign kyber_zetainv[23] = 12'h7CC ; +assign kyber_zetainv[24] = 12'h76F ; +assign kyber_zetainv[25] = 12'h4D3 ; +assign kyber_zetainv[26] = 12'hAEA ; +assign kyber_zetainv[27] = 12'h1BF ; +assign kyber_zetainv[28] = 12'h3A8 ; +assign kyber_zetainv[29] = 12'h1C2 ; +assign kyber_zetainv[30] = 12'h54B ; +assign kyber_zetainv[31] = 12'h9CC ; +assign kyber_zetainv[32] = 12'hBE0 ; +assign kyber_zetainv[33] = 12'hBB6 ; +assign kyber_zetainv[34] = 12'h04C ; +assign kyber_zetainv[35] = 12'h625 ; +assign kyber_zetainv[36] = 12'h854 ; +assign kyber_zetainv[37] = 12'h401 ; +assign kyber_zetainv[38] = 12'h41C ; +assign kyber_zetainv[39] = 12'h4FA ; +assign kyber_zetainv[40] = 12'hA77 ; +assign kyber_zetainv[41] = 12'h548 ; +assign kyber_zetainv[42] = 12'h330 ; +assign kyber_zetainv[43] = 12'hA89 ; +assign kyber_zetainv[44] = 12'h1D0 ; +assign kyber_zetainv[45] = 12'hCE0 ; +assign kyber_zetainv[46] = 12'h7D9 ; +assign kyber_zetainv[47] = 12'h586 ; +assign kyber_zetainv[48] = 12'h3F2 ; +assign kyber_zetainv[49] = 12'h766 ; +assign kyber_zetainv[50] = 12'h9DA ; +assign kyber_zetainv[51] = 12'hB3D ; +assign kyber_zetainv[52] = 12'h763 ; +assign kyber_zetainv[53] = 12'h1CD ; +assign kyber_zetainv[54] = 12'h703 ; +assign kyber_zetainv[55] = 12'h39F ; +assign kyber_zetainv[56] = 12'h2AA ; +assign kyber_zetainv[57] = 12'h2C8 ; +assign kyber_zetainv[58] = 12'h738 ; +assign kyber_zetainv[59] = 12'hA79 ; +assign kyber_zetainv[60] = 12'h357 ; +assign kyber_zetainv[61] = 12'h0DB ; +assign kyber_zetainv[62] = 12'h836 ; +assign kyber_zetainv[63] = 12'h973 ; +assign kyber_zetainv[64] = 12'hCF0 ; +assign kyber_zetainv[65] = 12'h238 ; +assign kyber_zetainv[66] = 12'hABA ; +assign kyber_zetainv[67] = 12'h2A8 ; +assign kyber_zetainv[68] = 12'h69C ; +assign kyber_zetainv[69] = 12'hA2E ; +assign kyber_zetainv[70] = 12'h411 ; +assign kyber_zetainv[71] = 12'h8B5 ; +assign kyber_zetainv[72] = 12'h780 ; +assign kyber_zetainv[73] = 12'h29B ; +assign kyber_zetainv[74] = 12'h030 ; +assign kyber_zetainv[75] = 12'hC18 ; +assign kyber_zetainv[76] = 12'hA0D ; +assign kyber_zetainv[77] = 12'h495 ; +assign kyber_zetainv[78] = 12'h13A ; +assign kyber_zetainv[79] = 12'h117 ; +assign kyber_zetainv[80] = 12'h65A ; +assign kyber_zetainv[81] = 12'h68E ; +assign kyber_zetainv[82] = 12'h21C ; +assign kyber_zetainv[83] = 12'h604 ; +assign kyber_zetainv[84] = 12'h5CA ; +assign kyber_zetainv[85] = 12'h949 ; +assign kyber_zetainv[86] = 12'h74C ; +assign kyber_zetainv[87] = 12'h282 ; +assign kyber_zetainv[88] = 12'h956 ; +assign kyber_zetainv[89] = 12'h3FD ; +assign kyber_zetainv[90] = 12'h37C ; +assign kyber_zetainv[91] = 12'h3AD ; +assign kyber_zetainv[92] = 12'hA24 ; +assign kyber_zetainv[93] = 12'h3E0 ; +assign kyber_zetainv[94] = 12'hBF5 ; +assign kyber_zetainv[95] = 12'hA80 ; +assign kyber_zetainv[96] = 12'h6D1 ; +assign kyber_zetainv[97] = 12'h407 ; +assign kyber_zetainv[98] = 12'h50C ; +assign kyber_zetainv[99] = 12'h06D ; +assign kyber_zetainv[100] = 12'hB8A ; +assign kyber_zetainv[101] = 12'h30C ; +assign kyber_zetainv[102] = 12'h4D7 ; +assign kyber_zetainv[103] = 12'h694 ; +assign kyber_zetainv[104] = 12'h8DA ; +assign kyber_zetainv[105] = 12'hBC2 ; +assign kyber_zetainv[106] = 12'h22C ; +assign kyber_zetainv[107] = 12'hA0C ; +assign kyber_zetainv[108] = 12'h4CE ; +assign kyber_zetainv[109] = 12'hAD0 ; +assign kyber_zetainv[110] = 12'h35F ; +assign kyber_zetainv[111] = 12'h2DF ; +assign kyber_zetainv[112] = 12'h20D ; +assign kyber_zetainv[113] = 12'h8BD ; +assign kyber_zetainv[114] = 12'hB6E ; +assign kyber_zetainv[115] = 12'h8FF ; +assign kyber_zetainv[116] = 12'h88A ; +assign kyber_zetainv[117] = 12'h49B ; +assign kyber_zetainv[118] = 12'h22A ; +assign kyber_zetainv[119] = 12'h98B ; +assign kyber_zetainv[120] = 12'h647 ; +assign kyber_zetainv[121] = 12'h845 ; +assign kyber_zetainv[122] = 12'h5AF ; +assign kyber_zetainv[123] = 12'h8FC ; +assign kyber_zetainv[124] = 12'h4C3 ; +assign kyber_zetainv[125] = 12'h18A ; +assign kyber_zetainv[126] = 12'h98C ; +assign kyber_zetainv[127] = 12'h497 ; +assign kyber_zetainv[128] = 12'hCF0 ; +assign kyber_zetainv[129] = 12'h011 ; +assign kyber_zetainv[130] = 12'h238 ; +assign kyber_zetainv[131] = 12'hAC9 ; +assign kyber_zetainv[132] = 12'hABA ; +assign kyber_zetainv[133] = 12'h247 ; +assign kyber_zetainv[134] = 12'h2A8 ; +assign kyber_zetainv[135] = 12'hA59 ; +assign kyber_zetainv[136] = 12'h69C ; +assign kyber_zetainv[137] = 12'h665 ; +assign kyber_zetainv[138] = 12'hA2E ; +assign kyber_zetainv[139] = 12'h2D3 ; +assign kyber_zetainv[140] = 12'h411 ; +assign kyber_zetainv[141] = 12'h8F0 ; +assign kyber_zetainv[142] = 12'h8B5 ; +assign kyber_zetainv[143] = 12'h44C ; +assign kyber_zetainv[144] = 12'h780 ; +assign kyber_zetainv[145] = 12'h581 ; +assign kyber_zetainv[146] = 12'h29B ; +assign kyber_zetainv[147] = 12'hA66 ; +assign kyber_zetainv[148] = 12'h030 ; +assign kyber_zetainv[149] = 12'hCD1 ; +assign kyber_zetainv[150] = 12'hC18 ; +assign kyber_zetainv[151] = 12'h0E9 ; +assign kyber_zetainv[152] = 12'hA0D ; +assign kyber_zetainv[153] = 12'h2F4 ; +assign kyber_zetainv[154] = 12'h495 ; +assign kyber_zetainv[155] = 12'h86C ; +assign kyber_zetainv[156] = 12'h13A ; +assign kyber_zetainv[157] = 12'hBC7 ; +assign kyber_zetainv[158] = 12'h117 ; +assign kyber_zetainv[159] = 12'hBEA ; +assign kyber_zetainv[160] = 12'h65A ; +assign kyber_zetainv[161] = 12'h6A7 ; +assign kyber_zetainv[162] = 12'h68E ; +assign kyber_zetainv[163] = 12'h673 ; +assign kyber_zetainv[164] = 12'h21C ; +assign kyber_zetainv[165] = 12'hAE5 ; +assign kyber_zetainv[166] = 12'h604 ; +assign kyber_zetainv[167] = 12'h6FD ; +assign kyber_zetainv[168] = 12'h5CA ; +assign kyber_zetainv[169] = 12'h737 ; +assign kyber_zetainv[170] = 12'h949 ; +assign kyber_zetainv[171] = 12'h3B8 ; +assign kyber_zetainv[172] = 12'h74C ; +assign kyber_zetainv[173] = 12'h5B5 ; +assign kyber_zetainv[174] = 12'h282 ; +assign kyber_zetainv[175] = 12'hA7F ; +assign kyber_zetainv[176] = 12'h956 ; +assign kyber_zetainv[177] = 12'h3AB ; +assign kyber_zetainv[178] = 12'h3FD ; +assign kyber_zetainv[179] = 12'h904 ; +assign kyber_zetainv[180] = 12'h37C ; +assign kyber_zetainv[181] = 12'h985 ; +assign kyber_zetainv[182] = 12'h3AD ; +assign kyber_zetainv[183] = 12'h954 ; +assign kyber_zetainv[184] = 12'hA24 ; +assign kyber_zetainv[185] = 12'h2DD ; +assign kyber_zetainv[186] = 12'h3E0 ; +assign kyber_zetainv[187] = 12'h921 ; +assign kyber_zetainv[188] = 12'hBF5 ; +assign kyber_zetainv[189] = 12'h10C ; +assign kyber_zetainv[190] = 12'hA80 ; +assign kyber_zetainv[191] = 12'h281 ; +assign kyber_zetainv[192] = 12'h6D1 ; +assign kyber_zetainv[193] = 12'h630 ; +assign kyber_zetainv[194] = 12'h407 ; +assign kyber_zetainv[195] = 12'h8FA ; +assign kyber_zetainv[196] = 12'h50C ; +assign kyber_zetainv[197] = 12'h7F5 ; +assign kyber_zetainv[198] = 12'h06D ; +assign kyber_zetainv[199] = 12'hC94 ; +assign kyber_zetainv[200] = 12'hB8A ; +assign kyber_zetainv[201] = 12'h177 ; +assign kyber_zetainv[202] = 12'h30C ; +assign kyber_zetainv[203] = 12'h9F5 ; +assign kyber_zetainv[204] = 12'h4D7 ; +assign kyber_zetainv[205] = 12'h82A ; +assign kyber_zetainv[206] = 12'h694 ; +assign kyber_zetainv[207] = 12'h66D ; +assign kyber_zetainv[208] = 12'h8DA ; +assign kyber_zetainv[209] = 12'h427 ; +assign kyber_zetainv[210] = 12'hBC2 ; +assign kyber_zetainv[211] = 12'h13F ; +assign kyber_zetainv[212] = 12'h22C ; +assign kyber_zetainv[213] = 12'hAD5 ; +assign kyber_zetainv[214] = 12'hA0C ; +assign kyber_zetainv[215] = 12'h2F5 ; +assign kyber_zetainv[216] = 12'h4CE ; +assign kyber_zetainv[217] = 12'h833 ; +assign kyber_zetainv[218] = 12'hAD0 ; +assign kyber_zetainv[219] = 12'h231 ; +assign kyber_zetainv[220] = 12'h35F ; +assign kyber_zetainv[221] = 12'h9A2 ; +assign kyber_zetainv[222] = 12'h2DF ; +assign kyber_zetainv[223] = 12'hA22 ; +assign kyber_zetainv[224] = 12'h20D ; +assign kyber_zetainv[225] = 12'hAF4 ; +assign kyber_zetainv[226] = 12'h8BD ; +assign kyber_zetainv[227] = 12'h444 ; +assign kyber_zetainv[228] = 12'hB6E ; +assign kyber_zetainv[229] = 12'h193 ; +assign kyber_zetainv[230] = 12'h8FF ; +assign kyber_zetainv[231] = 12'h402 ; +assign kyber_zetainv[232] = 12'h88A ; +assign kyber_zetainv[233] = 12'h477 ; +assign kyber_zetainv[234] = 12'h49B ; +assign kyber_zetainv[235] = 12'h866 ; +assign kyber_zetainv[236] = 12'h22A ; +assign kyber_zetainv[237] = 12'hAD7 ; +assign kyber_zetainv[238] = 12'h98B ; +assign kyber_zetainv[239] = 12'h376 ; +assign kyber_zetainv[240] = 12'h647 ; +assign kyber_zetainv[241] = 12'h6BA ; +assign kyber_zetainv[242] = 12'h845 ; +assign kyber_zetainv[243] = 12'h4BC ; +assign kyber_zetainv[244] = 12'h5AF ; +assign kyber_zetainv[245] = 12'h752 ; +assign kyber_zetainv[246] = 12'h8FC ; +assign kyber_zetainv[247] = 12'h405 ; +assign kyber_zetainv[248] = 12'h4C3 ; +assign kyber_zetainv[249] = 12'h83E ; +assign kyber_zetainv[250] = 12'h18A ; +assign kyber_zetainv[251] = 12'hB77 ; +assign kyber_zetainv[252] = 12'h98C ; +assign kyber_zetainv[253] = 12'h375 ; +assign kyber_zetainv[254] = 12'h497 ; +assign kyber_zetainv[255] = 12'h86A ; + +// assign ntt_twiddle_mem[0] = 'h000001; +assign ntt_twiddle_mem[0] = {zeta[3], zeta[2], zeta[1]}; +assign ntt_twiddle_mem[1] = {zeta[9], zeta[8], zeta[4]}; +assign ntt_twiddle_mem[2] = {zeta[11], zeta[10], zeta[5]}; +assign ntt_twiddle_mem[3] = {zeta[13], zeta[12], zeta[6]}; +assign ntt_twiddle_mem[4] = {zeta[15], zeta[14], zeta[7]}; +assign ntt_twiddle_mem[5] = {zeta[33], zeta[32], zeta[16]}; +assign ntt_twiddle_mem[6] = {zeta[35], zeta[34], zeta[17]}; +assign ntt_twiddle_mem[7] = {zeta[37], zeta[36], zeta[18]}; +assign ntt_twiddle_mem[8] = {zeta[39], zeta[38], zeta[19]}; +assign ntt_twiddle_mem[9] = {zeta[41], zeta[40], zeta[20]}; +assign ntt_twiddle_mem[10] = {zeta[43], zeta[42], zeta[21]}; +assign ntt_twiddle_mem[11] = {zeta[45], zeta[44], zeta[22]}; +assign ntt_twiddle_mem[12] = {zeta[47], zeta[46], zeta[23]}; +assign ntt_twiddle_mem[13] = {zeta[49], zeta[48], zeta[24]}; +assign ntt_twiddle_mem[14] = {zeta[51], zeta[50], zeta[25]}; +assign ntt_twiddle_mem[15] = {zeta[53], zeta[52], zeta[26]}; +assign ntt_twiddle_mem[16] = {zeta[55], zeta[54], zeta[27]}; +assign ntt_twiddle_mem[17] = {zeta[57], zeta[56], zeta[28]}; +assign ntt_twiddle_mem[18] = {zeta[59], zeta[58], zeta[29]}; +assign ntt_twiddle_mem[19] = {zeta[61], zeta[60], zeta[30]}; +assign ntt_twiddle_mem[20] = {zeta[63], zeta[62], zeta[31]}; +assign ntt_twiddle_mem[21] = {zeta[129], zeta[128], zeta[64]}; +assign ntt_twiddle_mem[22] = {zeta[131], zeta[130], zeta[65]}; +assign ntt_twiddle_mem[23] = {zeta[133], zeta[132], zeta[66]}; +assign ntt_twiddle_mem[24] = {zeta[135], zeta[134], zeta[67]}; +assign ntt_twiddle_mem[25] = {zeta[137], zeta[136], zeta[68]}; +assign ntt_twiddle_mem[26] = {zeta[139], zeta[138], zeta[69]}; +assign ntt_twiddle_mem[27] = {zeta[141], zeta[140], zeta[70]}; +assign ntt_twiddle_mem[28] = {zeta[143], zeta[142], zeta[71]}; +assign ntt_twiddle_mem[29] = {zeta[145], zeta[144], zeta[72]}; +assign ntt_twiddle_mem[30] = {zeta[147], zeta[146], zeta[73]}; +assign ntt_twiddle_mem[31] = {zeta[149], zeta[148], zeta[74]}; +assign ntt_twiddle_mem[32] = {zeta[151], zeta[150], zeta[75]}; +assign ntt_twiddle_mem[33] = {zeta[153], zeta[152], zeta[76]}; +assign ntt_twiddle_mem[34] = {zeta[155], zeta[154], zeta[77]}; +assign ntt_twiddle_mem[35] = {zeta[157], zeta[156], zeta[78]}; +assign ntt_twiddle_mem[36] = {zeta[159], zeta[158], zeta[79]}; +assign ntt_twiddle_mem[37] = {zeta[161], zeta[160], zeta[80]}; +assign ntt_twiddle_mem[38] = {zeta[163], zeta[162], zeta[81]}; +assign ntt_twiddle_mem[39] = {zeta[165], zeta[164], zeta[82]}; +assign ntt_twiddle_mem[40] = {zeta[167], zeta[166], zeta[83]}; +assign ntt_twiddle_mem[41] = {zeta[169], zeta[168], zeta[84]}; +assign ntt_twiddle_mem[42] = {zeta[171], zeta[170], zeta[85]}; +assign ntt_twiddle_mem[43] = {zeta[173], zeta[172], zeta[86]}; +assign ntt_twiddle_mem[44] = {zeta[175], zeta[174], zeta[87]}; +assign ntt_twiddle_mem[45] = {zeta[177], zeta[176], zeta[88]}; +assign ntt_twiddle_mem[46] = {zeta[179], zeta[178], zeta[89]}; +assign ntt_twiddle_mem[47] = {zeta[181], zeta[180], zeta[90]}; +assign ntt_twiddle_mem[48] = {zeta[183], zeta[182], zeta[91]}; +assign ntt_twiddle_mem[49] = {zeta[185], zeta[184], zeta[92]}; +assign ntt_twiddle_mem[50] = {zeta[187], zeta[186], zeta[93]}; +assign ntt_twiddle_mem[51] = {zeta[189], zeta[188], zeta[94]}; +assign ntt_twiddle_mem[52] = {zeta[191], zeta[190], zeta[95]}; +assign ntt_twiddle_mem[53] = {zeta[193], zeta[192], zeta[96]}; +assign ntt_twiddle_mem[54] = {zeta[195], zeta[194], zeta[97]}; +assign ntt_twiddle_mem[55] = {zeta[197], zeta[196], zeta[98]}; +assign ntt_twiddle_mem[56] = {zeta[199], zeta[198], zeta[99]}; +assign ntt_twiddle_mem[57] = {zeta[201], zeta[200], zeta[100]}; +assign ntt_twiddle_mem[58] = {zeta[203], zeta[202], zeta[101]}; +assign ntt_twiddle_mem[59] = {zeta[205], zeta[204], zeta[102]}; +assign ntt_twiddle_mem[60] = {zeta[207], zeta[206], zeta[103]}; +assign ntt_twiddle_mem[61] = {zeta[209], zeta[208], zeta[104]}; +assign ntt_twiddle_mem[62] = {zeta[211], zeta[210], zeta[105]}; +assign ntt_twiddle_mem[63] = {zeta[213], zeta[212], zeta[106]}; +assign ntt_twiddle_mem[64] = {zeta[215], zeta[214], zeta[107]}; +assign ntt_twiddle_mem[65] = {zeta[217], zeta[216], zeta[108]}; +assign ntt_twiddle_mem[66] = {zeta[219], zeta[218], zeta[109]}; +assign ntt_twiddle_mem[67] = {zeta[221], zeta[220], zeta[110]}; +assign ntt_twiddle_mem[68] = {zeta[223], zeta[222], zeta[111]}; +assign ntt_twiddle_mem[69] = {zeta[225], zeta[224], zeta[112]}; +assign ntt_twiddle_mem[70] = {zeta[227], zeta[226], zeta[113]}; +assign ntt_twiddle_mem[71] = {zeta[229], zeta[228], zeta[114]}; +assign ntt_twiddle_mem[72] = {zeta[231], zeta[230], zeta[115]}; +assign ntt_twiddle_mem[73] = {zeta[233], zeta[232], zeta[116]}; +assign ntt_twiddle_mem[74] = {zeta[235], zeta[234], zeta[117]}; +assign ntt_twiddle_mem[75] = {zeta[237], zeta[236], zeta[118]}; +assign ntt_twiddle_mem[76] = {zeta[239], zeta[238], zeta[119]}; +assign ntt_twiddle_mem[77] = {zeta[241], zeta[240], zeta[120]}; +assign ntt_twiddle_mem[78] = {zeta[243], zeta[242], zeta[121]}; +assign ntt_twiddle_mem[79] = {zeta[245], zeta[244], zeta[122]}; +assign ntt_twiddle_mem[80] = {zeta[247], zeta[246], zeta[123]}; +assign ntt_twiddle_mem[81] = {zeta[249], zeta[248], zeta[124]}; +assign ntt_twiddle_mem[82] = {zeta[251], zeta[250], zeta[125]}; +assign ntt_twiddle_mem[83] = {zeta[253], zeta[252], zeta[126]}; +assign ntt_twiddle_mem[84] = {zeta[255], zeta[254], zeta[127]}; +//-------------------------------------------------------- + +assign intt_twiddle_mem[0] = {zetainv[127], zetainv[254], zetainv[255]}; +assign intt_twiddle_mem[1] = {zetainv[126], zetainv[252], zetainv[253]}; +assign intt_twiddle_mem[2] = {zetainv[125], zetainv[250], zetainv[251]}; +assign intt_twiddle_mem[3] = {zetainv[124], zetainv[248], zetainv[249]}; +assign intt_twiddle_mem[4] = {zetainv[123], zetainv[246], zetainv[247]}; +assign intt_twiddle_mem[5] = {zetainv[122], zetainv[244], zetainv[245]}; +assign intt_twiddle_mem[6] = {zetainv[121], zetainv[242], zetainv[243]}; +assign intt_twiddle_mem[7] = {zetainv[120], zetainv[240], zetainv[241]}; +assign intt_twiddle_mem[8] = {zetainv[119], zetainv[238], zetainv[239]}; +assign intt_twiddle_mem[9] = {zetainv[118], zetainv[236], zetainv[237]}; +assign intt_twiddle_mem[10] = {zetainv[117], zetainv[234], zetainv[235]}; +assign intt_twiddle_mem[11] = {zetainv[116], zetainv[232], zetainv[233]}; +assign intt_twiddle_mem[12] = {zetainv[115], zetainv[230], zetainv[231]}; +assign intt_twiddle_mem[13] = {zetainv[114], zetainv[228], zetainv[229]}; +assign intt_twiddle_mem[14] = {zetainv[113], zetainv[226], zetainv[227]}; +assign intt_twiddle_mem[15] = {zetainv[112], zetainv[224], zetainv[225]}; +assign intt_twiddle_mem[16] = {zetainv[111], zetainv[222], zetainv[223]}; +assign intt_twiddle_mem[17] = {zetainv[110], zetainv[220], zetainv[221]}; +assign intt_twiddle_mem[18] = {zetainv[109], zetainv[218], zetainv[219]}; +assign intt_twiddle_mem[19] = {zetainv[108], zetainv[216], zetainv[217]}; +assign intt_twiddle_mem[20] = {zetainv[107], zetainv[214], zetainv[215]}; +assign intt_twiddle_mem[21] = {zetainv[106], zetainv[212], zetainv[213]}; +assign intt_twiddle_mem[22] = {zetainv[105], zetainv[210], zetainv[211]}; +assign intt_twiddle_mem[23] = {zetainv[104], zetainv[208], zetainv[209]}; +assign intt_twiddle_mem[24] = {zetainv[103], zetainv[206], zetainv[207]}; +assign intt_twiddle_mem[25] = {zetainv[102], zetainv[204], zetainv[205]}; +assign intt_twiddle_mem[26] = {zetainv[101], zetainv[202], zetainv[203]}; +assign intt_twiddle_mem[27] = {zetainv[100], zetainv[200], zetainv[201]}; +assign intt_twiddle_mem[28] = {zetainv[99], zetainv[198], zetainv[199]}; +assign intt_twiddle_mem[29] = {zetainv[98], zetainv[196], zetainv[197]}; +assign intt_twiddle_mem[30] = {zetainv[97], zetainv[194], zetainv[195]}; +assign intt_twiddle_mem[31] = {zetainv[96], zetainv[192], zetainv[193]}; +assign intt_twiddle_mem[32] = {zetainv[95], zetainv[190], zetainv[191]}; +assign intt_twiddle_mem[33] = {zetainv[94], zetainv[188], zetainv[189]}; +assign intt_twiddle_mem[34] = {zetainv[93], zetainv[186], zetainv[187]}; +assign intt_twiddle_mem[35] = {zetainv[92], zetainv[184], zetainv[185]}; +assign intt_twiddle_mem[36] = {zetainv[91], zetainv[182], zetainv[183]}; +assign intt_twiddle_mem[37] = {zetainv[90], zetainv[180], zetainv[181]}; +assign intt_twiddle_mem[38] = {zetainv[89], zetainv[178], zetainv[179]}; +assign intt_twiddle_mem[39] = {zetainv[88], zetainv[176], zetainv[177]}; +assign intt_twiddle_mem[40] = {zetainv[87], zetainv[174], zetainv[175]}; +assign intt_twiddle_mem[41] = {zetainv[86], zetainv[172], zetainv[173]}; +assign intt_twiddle_mem[42] = {zetainv[85], zetainv[170], zetainv[171]}; +assign intt_twiddle_mem[43] = {zetainv[84], zetainv[168], zetainv[169]}; +assign intt_twiddle_mem[44] = {zetainv[83], zetainv[166], zetainv[167]}; +assign intt_twiddle_mem[45] = {zetainv[82], zetainv[164], zetainv[165]}; +assign intt_twiddle_mem[46] = {zetainv[81], zetainv[162], zetainv[163]}; +assign intt_twiddle_mem[47] = {zetainv[80], zetainv[160], zetainv[161]}; +assign intt_twiddle_mem[48] = {zetainv[79], zetainv[158], zetainv[159]}; +assign intt_twiddle_mem[49] = {zetainv[78], zetainv[156], zetainv[157]}; +assign intt_twiddle_mem[50] = {zetainv[77], zetainv[154], zetainv[155]}; +assign intt_twiddle_mem[51] = {zetainv[76], zetainv[152], zetainv[153]}; +assign intt_twiddle_mem[52] = {zetainv[75], zetainv[150], zetainv[151]}; +assign intt_twiddle_mem[53] = {zetainv[74], zetainv[148], zetainv[149]}; +assign intt_twiddle_mem[54] = {zetainv[73], zetainv[146], zetainv[147]}; +assign intt_twiddle_mem[55] = {zetainv[72], zetainv[144], zetainv[145]}; +assign intt_twiddle_mem[56] = {zetainv[71], zetainv[142], zetainv[143]}; +assign intt_twiddle_mem[57] = {zetainv[70], zetainv[140], zetainv[141]}; +assign intt_twiddle_mem[58] = {zetainv[69], zetainv[138], zetainv[139]}; +assign intt_twiddle_mem[59] = {zetainv[68], zetainv[136], zetainv[137]}; +assign intt_twiddle_mem[60] = {zetainv[67], zetainv[134], zetainv[135]}; +assign intt_twiddle_mem[61] = {zetainv[66], zetainv[132], zetainv[133]}; +assign intt_twiddle_mem[62] = {zetainv[65], zetainv[130], zetainv[131]}; +assign intt_twiddle_mem[63] = {zetainv[64], zetainv[128], zetainv[129]}; +assign intt_twiddle_mem[64] = {zetainv[31], zetainv[62], zetainv[63]}; +assign intt_twiddle_mem[65] = {zetainv[30], zetainv[60], zetainv[61]}; +assign intt_twiddle_mem[66] = {zetainv[29], zetainv[58], zetainv[59]}; +assign intt_twiddle_mem[67] = {zetainv[28], zetainv[56], zetainv[57]}; +assign intt_twiddle_mem[68] = {zetainv[27], zetainv[54], zetainv[55]}; +assign intt_twiddle_mem[69] = {zetainv[26], zetainv[52], zetainv[53]}; +assign intt_twiddle_mem[70] = {zetainv[25], zetainv[50], zetainv[51]}; +assign intt_twiddle_mem[71] = {zetainv[24], zetainv[48], zetainv[49]}; +assign intt_twiddle_mem[72] = {zetainv[23], zetainv[46], zetainv[47]}; +assign intt_twiddle_mem[73] = {zetainv[22], zetainv[44], zetainv[45]}; +assign intt_twiddle_mem[74] = {zetainv[21], zetainv[42], zetainv[43]}; +assign intt_twiddle_mem[75] = {zetainv[20], zetainv[40], zetainv[41]}; +assign intt_twiddle_mem[76] = {zetainv[19], zetainv[38], zetainv[39]}; +assign intt_twiddle_mem[77] = {zetainv[18], zetainv[36], zetainv[37]}; +assign intt_twiddle_mem[78] = {zetainv[17], zetainv[34], zetainv[35]}; +assign intt_twiddle_mem[79] = {zetainv[16], zetainv[32], zetainv[33]}; +assign intt_twiddle_mem[80] = {zetainv[7], zetainv[14], zetainv[15]}; +assign intt_twiddle_mem[81] = {zetainv[6], zetainv[12], zetainv[13]}; +assign intt_twiddle_mem[82] = {zetainv[5], zetainv[10], zetainv[11]}; +assign intt_twiddle_mem[83] = {zetainv[4], zetainv[8], zetainv[9]}; +assign intt_twiddle_mem[84] = {zetainv[1], zetainv[2], zetainv[3]}; + +//-------------------------------------------------------- + +assign kyber_ntt_twiddle_mem[0] = {kyber_zeta[3], kyber_zeta[2], kyber_zeta[1]}; +assign kyber_ntt_twiddle_mem[1] = {kyber_zeta[9], kyber_zeta[8], kyber_zeta[4]}; +assign kyber_ntt_twiddle_mem[2] = {kyber_zeta[11], kyber_zeta[10], kyber_zeta[5]}; +assign kyber_ntt_twiddle_mem[3] = {kyber_zeta[13], kyber_zeta[12], kyber_zeta[6]}; +assign kyber_ntt_twiddle_mem[4] = {kyber_zeta[15], kyber_zeta[14], kyber_zeta[7]}; +assign kyber_ntt_twiddle_mem[5] = {kyber_zeta[33], kyber_zeta[32], kyber_zeta[16]}; +assign kyber_ntt_twiddle_mem[6] = {kyber_zeta[35], kyber_zeta[34], kyber_zeta[17]}; +assign kyber_ntt_twiddle_mem[7] = {kyber_zeta[37], kyber_zeta[36], kyber_zeta[18]}; +assign kyber_ntt_twiddle_mem[8] = {kyber_zeta[39], kyber_zeta[38], kyber_zeta[19]}; +assign kyber_ntt_twiddle_mem[9] = {kyber_zeta[41], kyber_zeta[40], kyber_zeta[20]}; +assign kyber_ntt_twiddle_mem[10] = {kyber_zeta[43], kyber_zeta[42], kyber_zeta[21]}; +assign kyber_ntt_twiddle_mem[11] = {kyber_zeta[45], kyber_zeta[44], kyber_zeta[22]}; +assign kyber_ntt_twiddle_mem[12] = {kyber_zeta[47], kyber_zeta[46], kyber_zeta[23]}; +assign kyber_ntt_twiddle_mem[13] = {kyber_zeta[49], kyber_zeta[48], kyber_zeta[24]}; +assign kyber_ntt_twiddle_mem[14] = {kyber_zeta[51], kyber_zeta[50], kyber_zeta[25]}; +assign kyber_ntt_twiddle_mem[15] = {kyber_zeta[53], kyber_zeta[52], kyber_zeta[26]}; +assign kyber_ntt_twiddle_mem[16] = {kyber_zeta[55], kyber_zeta[54], kyber_zeta[27]}; +assign kyber_ntt_twiddle_mem[17] = {kyber_zeta[57], kyber_zeta[56], kyber_zeta[28]}; +assign kyber_ntt_twiddle_mem[18] = {kyber_zeta[59], kyber_zeta[58], kyber_zeta[29]}; +assign kyber_ntt_twiddle_mem[19] = {kyber_zeta[61], kyber_zeta[60], kyber_zeta[30]}; +assign kyber_ntt_twiddle_mem[20] = {kyber_zeta[63], kyber_zeta[62], kyber_zeta[31]}; +assign kyber_ntt_twiddle_mem[21] = {kyber_zeta[129], kyber_zeta[128], kyber_zeta[64]}; +assign kyber_ntt_twiddle_mem[22] = {kyber_zeta[131], kyber_zeta[130], kyber_zeta[65]}; +assign kyber_ntt_twiddle_mem[23] = {kyber_zeta[133], kyber_zeta[132], kyber_zeta[66]}; +assign kyber_ntt_twiddle_mem[24] = {kyber_zeta[135], kyber_zeta[134], kyber_zeta[67]}; +assign kyber_ntt_twiddle_mem[25] = {kyber_zeta[137], kyber_zeta[136], kyber_zeta[68]}; +assign kyber_ntt_twiddle_mem[26] = {kyber_zeta[139], kyber_zeta[138], kyber_zeta[69]}; +assign kyber_ntt_twiddle_mem[27] = {kyber_zeta[141], kyber_zeta[140], kyber_zeta[70]}; +assign kyber_ntt_twiddle_mem[28] = {kyber_zeta[143], kyber_zeta[142], kyber_zeta[71]}; +assign kyber_ntt_twiddle_mem[29] = {kyber_zeta[145], kyber_zeta[144], kyber_zeta[72]}; +assign kyber_ntt_twiddle_mem[30] = {kyber_zeta[147], kyber_zeta[146], kyber_zeta[73]}; +assign kyber_ntt_twiddle_mem[31] = {kyber_zeta[149], kyber_zeta[148], kyber_zeta[74]}; +assign kyber_ntt_twiddle_mem[32] = {kyber_zeta[151], kyber_zeta[150], kyber_zeta[75]}; +assign kyber_ntt_twiddle_mem[33] = {kyber_zeta[153], kyber_zeta[152], kyber_zeta[76]}; +assign kyber_ntt_twiddle_mem[34] = {kyber_zeta[155], kyber_zeta[154], kyber_zeta[77]}; +assign kyber_ntt_twiddle_mem[35] = {kyber_zeta[157], kyber_zeta[156], kyber_zeta[78]}; +assign kyber_ntt_twiddle_mem[36] = {kyber_zeta[159], kyber_zeta[158], kyber_zeta[79]}; +assign kyber_ntt_twiddle_mem[37] = {kyber_zeta[161], kyber_zeta[160], kyber_zeta[80]}; +assign kyber_ntt_twiddle_mem[38] = {kyber_zeta[163], kyber_zeta[162], kyber_zeta[81]}; +assign kyber_ntt_twiddle_mem[39] = {kyber_zeta[165], kyber_zeta[164], kyber_zeta[82]}; +assign kyber_ntt_twiddle_mem[40] = {kyber_zeta[167], kyber_zeta[166], kyber_zeta[83]}; +assign kyber_ntt_twiddle_mem[41] = {kyber_zeta[169], kyber_zeta[168], kyber_zeta[84]}; +assign kyber_ntt_twiddle_mem[42] = {kyber_zeta[171], kyber_zeta[170], kyber_zeta[85]}; +assign kyber_ntt_twiddle_mem[43] = {kyber_zeta[173], kyber_zeta[172], kyber_zeta[86]}; +assign kyber_ntt_twiddle_mem[44] = {kyber_zeta[175], kyber_zeta[174], kyber_zeta[87]}; +assign kyber_ntt_twiddle_mem[45] = {kyber_zeta[177], kyber_zeta[176], kyber_zeta[88]}; +assign kyber_ntt_twiddle_mem[46] = {kyber_zeta[179], kyber_zeta[178], kyber_zeta[89]}; +assign kyber_ntt_twiddle_mem[47] = {kyber_zeta[181], kyber_zeta[180], kyber_zeta[90]}; +assign kyber_ntt_twiddle_mem[48] = {kyber_zeta[183], kyber_zeta[182], kyber_zeta[91]}; +assign kyber_ntt_twiddle_mem[49] = {kyber_zeta[185], kyber_zeta[184], kyber_zeta[92]}; +assign kyber_ntt_twiddle_mem[50] = {kyber_zeta[187], kyber_zeta[186], kyber_zeta[93]}; +assign kyber_ntt_twiddle_mem[51] = {kyber_zeta[189], kyber_zeta[188], kyber_zeta[94]}; +assign kyber_ntt_twiddle_mem[52] = {kyber_zeta[191], kyber_zeta[190], kyber_zeta[95]}; +assign kyber_ntt_twiddle_mem[53] = {kyber_zeta[193], kyber_zeta[192], kyber_zeta[96]}; +assign kyber_ntt_twiddle_mem[54] = {kyber_zeta[195], kyber_zeta[194], kyber_zeta[97]}; +assign kyber_ntt_twiddle_mem[55] = {kyber_zeta[197], kyber_zeta[196], kyber_zeta[98]}; +assign kyber_ntt_twiddle_mem[56] = {kyber_zeta[199], kyber_zeta[198], kyber_zeta[99]}; +assign kyber_ntt_twiddle_mem[57] = {kyber_zeta[201], kyber_zeta[200], kyber_zeta[100]}; +assign kyber_ntt_twiddle_mem[58] = {kyber_zeta[203], kyber_zeta[202], kyber_zeta[101]}; +assign kyber_ntt_twiddle_mem[59] = {kyber_zeta[205], kyber_zeta[204], kyber_zeta[102]}; +assign kyber_ntt_twiddle_mem[60] = {kyber_zeta[207], kyber_zeta[206], kyber_zeta[103]}; +assign kyber_ntt_twiddle_mem[61] = {kyber_zeta[209], kyber_zeta[208], kyber_zeta[104]}; +assign kyber_ntt_twiddle_mem[62] = {kyber_zeta[211], kyber_zeta[210], kyber_zeta[105]}; +assign kyber_ntt_twiddle_mem[63] = {kyber_zeta[213], kyber_zeta[212], kyber_zeta[106]}; +assign kyber_ntt_twiddle_mem[64] = {kyber_zeta[215], kyber_zeta[214], kyber_zeta[107]}; +assign kyber_ntt_twiddle_mem[65] = {kyber_zeta[217], kyber_zeta[216], kyber_zeta[108]}; +assign kyber_ntt_twiddle_mem[66] = {kyber_zeta[219], kyber_zeta[218], kyber_zeta[109]}; +assign kyber_ntt_twiddle_mem[67] = {kyber_zeta[221], kyber_zeta[220], kyber_zeta[110]}; +assign kyber_ntt_twiddle_mem[68] = {kyber_zeta[223], kyber_zeta[222], kyber_zeta[111]}; +assign kyber_ntt_twiddle_mem[69] = {kyber_zeta[225], kyber_zeta[224], kyber_zeta[112]}; +assign kyber_ntt_twiddle_mem[70] = {kyber_zeta[227], kyber_zeta[226], kyber_zeta[113]}; +assign kyber_ntt_twiddle_mem[71] = {kyber_zeta[229], kyber_zeta[228], kyber_zeta[114]}; +assign kyber_ntt_twiddle_mem[72] = {kyber_zeta[231], kyber_zeta[230], kyber_zeta[115]}; +assign kyber_ntt_twiddle_mem[73] = {kyber_zeta[233], kyber_zeta[232], kyber_zeta[116]}; +assign kyber_ntt_twiddle_mem[74] = {kyber_zeta[235], kyber_zeta[234], kyber_zeta[117]}; +assign kyber_ntt_twiddle_mem[75] = {kyber_zeta[237], kyber_zeta[236], kyber_zeta[118]}; +assign kyber_ntt_twiddle_mem[76] = {kyber_zeta[239], kyber_zeta[238], kyber_zeta[119]}; +assign kyber_ntt_twiddle_mem[77] = {kyber_zeta[241], kyber_zeta[240], kyber_zeta[120]}; +assign kyber_ntt_twiddle_mem[78] = {kyber_zeta[243], kyber_zeta[242], kyber_zeta[121]}; +assign kyber_ntt_twiddle_mem[79] = {kyber_zeta[245], kyber_zeta[244], kyber_zeta[122]}; +assign kyber_ntt_twiddle_mem[80] = {kyber_zeta[247], kyber_zeta[246], kyber_zeta[123]}; +assign kyber_ntt_twiddle_mem[81] = {kyber_zeta[249], kyber_zeta[248], kyber_zeta[124]}; +assign kyber_ntt_twiddle_mem[82] = {kyber_zeta[251], kyber_zeta[250], kyber_zeta[125]}; +assign kyber_ntt_twiddle_mem[83] = {kyber_zeta[253], kyber_zeta[252], kyber_zeta[126]}; +assign kyber_ntt_twiddle_mem[84] = {kyber_zeta[255], kyber_zeta[254], kyber_zeta[127]}; +//-------------------------------------------------------- + +assign kyber_intt_twiddle_mem[0] = {kyber_zetainv[127], kyber_zetainv[254], kyber_zetainv[255]}; +assign kyber_intt_twiddle_mem[1] = {kyber_zetainv[126], kyber_zetainv[252], kyber_zetainv[253]}; +assign kyber_intt_twiddle_mem[2] = {kyber_zetainv[125], kyber_zetainv[250], kyber_zetainv[251]}; +assign kyber_intt_twiddle_mem[3] = {kyber_zetainv[124], kyber_zetainv[248], kyber_zetainv[249]}; +assign kyber_intt_twiddle_mem[4] = {kyber_zetainv[123], kyber_zetainv[246], kyber_zetainv[247]}; +assign kyber_intt_twiddle_mem[5] = {kyber_zetainv[122], kyber_zetainv[244], kyber_zetainv[245]}; +assign kyber_intt_twiddle_mem[6] = {kyber_zetainv[121], kyber_zetainv[242], kyber_zetainv[243]}; +assign kyber_intt_twiddle_mem[7] = {kyber_zetainv[120], kyber_zetainv[240], kyber_zetainv[241]}; +assign kyber_intt_twiddle_mem[8] = {kyber_zetainv[119], kyber_zetainv[238], kyber_zetainv[239]}; +assign kyber_intt_twiddle_mem[9] = {kyber_zetainv[118], kyber_zetainv[236], kyber_zetainv[237]}; +assign kyber_intt_twiddle_mem[10] = {kyber_zetainv[117], kyber_zetainv[234], kyber_zetainv[235]}; +assign kyber_intt_twiddle_mem[11] = {kyber_zetainv[116], kyber_zetainv[232], kyber_zetainv[233]}; +assign kyber_intt_twiddle_mem[12] = {kyber_zetainv[115], kyber_zetainv[230], kyber_zetainv[231]}; +assign kyber_intt_twiddle_mem[13] = {kyber_zetainv[114], kyber_zetainv[228], kyber_zetainv[229]}; +assign kyber_intt_twiddle_mem[14] = {kyber_zetainv[113], kyber_zetainv[226], kyber_zetainv[227]}; +assign kyber_intt_twiddle_mem[15] = {kyber_zetainv[112], kyber_zetainv[224], kyber_zetainv[225]}; +assign kyber_intt_twiddle_mem[16] = {kyber_zetainv[111], kyber_zetainv[222], kyber_zetainv[223]}; +assign kyber_intt_twiddle_mem[17] = {kyber_zetainv[110], kyber_zetainv[220], kyber_zetainv[221]}; +assign kyber_intt_twiddle_mem[18] = {kyber_zetainv[109], kyber_zetainv[218], kyber_zetainv[219]}; +assign kyber_intt_twiddle_mem[19] = {kyber_zetainv[108], kyber_zetainv[216], kyber_zetainv[217]}; +assign kyber_intt_twiddle_mem[20] = {kyber_zetainv[107], kyber_zetainv[214], kyber_zetainv[215]}; +assign kyber_intt_twiddle_mem[21] = {kyber_zetainv[106], kyber_zetainv[212], kyber_zetainv[213]}; +assign kyber_intt_twiddle_mem[22] = {kyber_zetainv[105], kyber_zetainv[210], kyber_zetainv[211]}; +assign kyber_intt_twiddle_mem[23] = {kyber_zetainv[104], kyber_zetainv[208], kyber_zetainv[209]}; +assign kyber_intt_twiddle_mem[24] = {kyber_zetainv[103], kyber_zetainv[206], kyber_zetainv[207]}; +assign kyber_intt_twiddle_mem[25] = {kyber_zetainv[102], kyber_zetainv[204], kyber_zetainv[205]}; +assign kyber_intt_twiddle_mem[26] = {kyber_zetainv[101], kyber_zetainv[202], kyber_zetainv[203]}; +assign kyber_intt_twiddle_mem[27] = {kyber_zetainv[100], kyber_zetainv[200], kyber_zetainv[201]}; +assign kyber_intt_twiddle_mem[28] = {kyber_zetainv[99], kyber_zetainv[198], kyber_zetainv[199]}; +assign kyber_intt_twiddle_mem[29] = {kyber_zetainv[98], kyber_zetainv[196], kyber_zetainv[197]}; +assign kyber_intt_twiddle_mem[30] = {kyber_zetainv[97], kyber_zetainv[194], kyber_zetainv[195]}; +assign kyber_intt_twiddle_mem[31] = {kyber_zetainv[96], kyber_zetainv[192], kyber_zetainv[193]}; +assign kyber_intt_twiddle_mem[32] = {kyber_zetainv[95], kyber_zetainv[190], kyber_zetainv[191]}; +assign kyber_intt_twiddle_mem[33] = {kyber_zetainv[94], kyber_zetainv[188], kyber_zetainv[189]}; +assign kyber_intt_twiddle_mem[34] = {kyber_zetainv[93], kyber_zetainv[186], kyber_zetainv[187]}; +assign kyber_intt_twiddle_mem[35] = {kyber_zetainv[92], kyber_zetainv[184], kyber_zetainv[185]}; +assign kyber_intt_twiddle_mem[36] = {kyber_zetainv[91], kyber_zetainv[182], kyber_zetainv[183]}; +assign kyber_intt_twiddle_mem[37] = {kyber_zetainv[90], kyber_zetainv[180], kyber_zetainv[181]}; +assign kyber_intt_twiddle_mem[38] = {kyber_zetainv[89], kyber_zetainv[178], kyber_zetainv[179]}; +assign kyber_intt_twiddle_mem[39] = {kyber_zetainv[88], kyber_zetainv[176], kyber_zetainv[177]}; +assign kyber_intt_twiddle_mem[40] = {kyber_zetainv[87], kyber_zetainv[174], kyber_zetainv[175]}; +assign kyber_intt_twiddle_mem[41] = {kyber_zetainv[86], kyber_zetainv[172], kyber_zetainv[173]}; +assign kyber_intt_twiddle_mem[42] = {kyber_zetainv[85], kyber_zetainv[170], kyber_zetainv[171]}; +assign kyber_intt_twiddle_mem[43] = {kyber_zetainv[84], kyber_zetainv[168], kyber_zetainv[169]}; +assign kyber_intt_twiddle_mem[44] = {kyber_zetainv[83], kyber_zetainv[166], kyber_zetainv[167]}; +assign kyber_intt_twiddle_mem[45] = {kyber_zetainv[82], kyber_zetainv[164], kyber_zetainv[165]}; +assign kyber_intt_twiddle_mem[46] = {kyber_zetainv[81], kyber_zetainv[162], kyber_zetainv[163]}; +assign kyber_intt_twiddle_mem[47] = {kyber_zetainv[80], kyber_zetainv[160], kyber_zetainv[161]}; +assign kyber_intt_twiddle_mem[48] = {kyber_zetainv[79], kyber_zetainv[158], kyber_zetainv[159]}; +assign kyber_intt_twiddle_mem[49] = {kyber_zetainv[78], kyber_zetainv[156], kyber_zetainv[157]}; +assign kyber_intt_twiddle_mem[50] = {kyber_zetainv[77], kyber_zetainv[154], kyber_zetainv[155]}; +assign kyber_intt_twiddle_mem[51] = {kyber_zetainv[76], kyber_zetainv[152], kyber_zetainv[153]}; +assign kyber_intt_twiddle_mem[52] = {kyber_zetainv[75], kyber_zetainv[150], kyber_zetainv[151]}; +assign kyber_intt_twiddle_mem[53] = {kyber_zetainv[74], kyber_zetainv[148], kyber_zetainv[149]}; +assign kyber_intt_twiddle_mem[54] = {kyber_zetainv[73], kyber_zetainv[146], kyber_zetainv[147]}; +assign kyber_intt_twiddle_mem[55] = {kyber_zetainv[72], kyber_zetainv[144], kyber_zetainv[145]}; +assign kyber_intt_twiddle_mem[56] = {kyber_zetainv[71], kyber_zetainv[142], kyber_zetainv[143]}; +assign kyber_intt_twiddle_mem[57] = {kyber_zetainv[70], kyber_zetainv[140], kyber_zetainv[141]}; +assign kyber_intt_twiddle_mem[58] = {kyber_zetainv[69], kyber_zetainv[138], kyber_zetainv[139]}; +assign kyber_intt_twiddle_mem[59] = {kyber_zetainv[68], kyber_zetainv[136], kyber_zetainv[137]}; +assign kyber_intt_twiddle_mem[60] = {kyber_zetainv[67], kyber_zetainv[134], kyber_zetainv[135]}; +assign kyber_intt_twiddle_mem[61] = {kyber_zetainv[66], kyber_zetainv[132], kyber_zetainv[133]}; +assign kyber_intt_twiddle_mem[62] = {kyber_zetainv[65], kyber_zetainv[130], kyber_zetainv[131]}; +assign kyber_intt_twiddle_mem[63] = {kyber_zetainv[64], kyber_zetainv[128], kyber_zetainv[129]}; +assign kyber_intt_twiddle_mem[64] = {kyber_zetainv[31], kyber_zetainv[62], kyber_zetainv[63]}; +assign kyber_intt_twiddle_mem[65] = {kyber_zetainv[30], kyber_zetainv[60], kyber_zetainv[61]}; +assign kyber_intt_twiddle_mem[66] = {kyber_zetainv[29], kyber_zetainv[58], kyber_zetainv[59]}; +assign kyber_intt_twiddle_mem[67] = {kyber_zetainv[28], kyber_zetainv[56], kyber_zetainv[57]}; +assign kyber_intt_twiddle_mem[68] = {kyber_zetainv[27], kyber_zetainv[54], kyber_zetainv[55]}; +assign kyber_intt_twiddle_mem[69] = {kyber_zetainv[26], kyber_zetainv[52], kyber_zetainv[53]}; +assign kyber_intt_twiddle_mem[70] = {kyber_zetainv[25], kyber_zetainv[50], kyber_zetainv[51]}; +assign kyber_intt_twiddle_mem[71] = {kyber_zetainv[24], kyber_zetainv[48], kyber_zetainv[49]}; +assign kyber_intt_twiddle_mem[72] = {kyber_zetainv[23], kyber_zetainv[46], kyber_zetainv[47]}; +assign kyber_intt_twiddle_mem[73] = {kyber_zetainv[22], kyber_zetainv[44], kyber_zetainv[45]}; +assign kyber_intt_twiddle_mem[74] = {kyber_zetainv[21], kyber_zetainv[42], kyber_zetainv[43]}; +assign kyber_intt_twiddle_mem[75] = {kyber_zetainv[20], kyber_zetainv[40], kyber_zetainv[41]}; +assign kyber_intt_twiddle_mem[76] = {kyber_zetainv[19], kyber_zetainv[38], kyber_zetainv[39]}; +assign kyber_intt_twiddle_mem[77] = {kyber_zetainv[18], kyber_zetainv[36], kyber_zetainv[37]}; +assign kyber_intt_twiddle_mem[78] = {kyber_zetainv[17], kyber_zetainv[34], kyber_zetainv[35]}; +assign kyber_intt_twiddle_mem[79] = {kyber_zetainv[16], kyber_zetainv[32], kyber_zetainv[33]}; +assign kyber_intt_twiddle_mem[80] = {kyber_zetainv[7], kyber_zetainv[14], kyber_zetainv[15]}; +assign kyber_intt_twiddle_mem[81] = {kyber_zetainv[6], kyber_zetainv[12], kyber_zetainv[13]}; +assign kyber_intt_twiddle_mem[82] = {kyber_zetainv[5], kyber_zetainv[10], kyber_zetainv[11]}; +assign kyber_intt_twiddle_mem[83] = {kyber_zetainv[4], kyber_zetainv[8], kyber_zetainv[9]}; +assign kyber_intt_twiddle_mem[84] = {kyber_zetainv[1], kyber_zetainv[2], kyber_zetainv[3]}; + +endmodule \ No newline at end of file diff --git a/designs/Caliptra/src/adams-bridge/pkdecode.sv b/designs/Caliptra/src/adams-bridge/pkdecode.sv new file mode 100644 index 0000000..e872f6c --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/pkdecode.sv @@ -0,0 +1,226 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +//====================================================================== +// +// pkdecode.sv +// -------- +// The pkdecode module decodes the t1 polynomials according to the ML-DSA-87 protocol. +// Each set of 10 bits represents a single coefficient, which is then shifted left by +// 13 bits to produce a 24-bit output with the MSB set to zero. This module supports +// parallel processing of coefficients and interfaces with memory for storing the results. +// One cycle read and write latency +//====================================================================== + +module pkdecode + import abr_params_pkg::*; + #( + parameter MLDSA_K = 'h8, + parameter MLDSA_N = 'd256, + parameter REG_SIZE = 24, + parameter INPUT_COEFF_SIZE = 10, + parameter API_ADDR_WIDTH = 16 + ) + ( + input wire clk, + input wire reset_n, + input wire zeroize, + + input wire pkdecode_enable, + input wire [ABR_MEM_ADDR_WIDTH-1:0] dest_base_addr, + input wire [8*INPUT_COEFF_SIZE-1:0] API_rd_data, + + output logic [API_ADDR_WIDTH-1:0] API_rd_address, + output logic [3:0][REG_SIZE-1:0] mem_a_wr_data, + output logic [3:0][REG_SIZE-1:0] mem_b_wr_data, + output mem_if_t mem_a_wr_req, + output mem_if_t mem_b_wr_req, + + output logic pkdecode_done + ); + + localparam COEFF_WIDTH = 10; + localparam SHIFT_LEFT = 13; + localparam NUM_COEFFS_PER_CYCLE = 8; + localparam THE_LAST_ADDR = (MLDSA_K * MLDSA_N)/8; + // State Machine States + localparam IDLE = 3'b000, + READ = 3'b001, + READ_and_EXEC = 3'b010, + READ_and_WRITE = 3'b011, + WRITE = 3'b100, + DONE = 3'b101; + + // Internal signals + logic [7:0][REG_SIZE-1:0] coefficients; // Extracted 10-bit coefficients + logic [7:0][REG_SIZE-1:0] encoded_coeffs; // Encoded 24-bit coefficients + logic [ABR_MEM_ADDR_WIDTH-1:0] locked_dest_addr; + logic [31:0] num_mem_operands, num_api_operands; // encoded each four coeff will increment these by one + logic [2:0] state, next_state; + + + // State Machine + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) begin + state <= IDLE; + end + else if (zeroize) begin + state <= IDLE; + end + else begin + state <= next_state; + end + end + + always_comb begin + case (state) + IDLE: begin + if (pkdecode_enable) + next_state = READ; + else + next_state = IDLE; + end + READ: begin + next_state = READ_and_EXEC; + end + READ_and_EXEC: begin + next_state = READ_and_WRITE; + end + READ_and_WRITE: begin + if (num_api_operands == THE_LAST_ADDR) begin + next_state = WRITE; + end + else begin + next_state = READ_and_WRITE; + end + end + WRITE: begin + next_state = DONE; + end + DONE: begin + next_state = IDLE; + end + default: begin + next_state = IDLE; + end + endcase + end + + + // Extract 10-bit coefficients from API_rd_data + always_comb begin + for (int i = 0; i < NUM_COEFFS_PER_CYCLE; i++) begin + coefficients[i] = {24'h0, API_rd_data[COEFF_WIDTH*i +: COEFF_WIDTH]}; + end + end + + // Encode coefficients into 24-bit format + always_comb begin + for (int i = 0; i < NUM_COEFFS_PER_CYCLE; i++) begin + encoded_coeffs[i] = (coefficients[i] << SHIFT_LEFT); + end + end + + // Assign encoded data to memory write ports + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) begin + mem_a_wr_data <= '{default: 0}; + mem_b_wr_data <= '{default: 0}; + end + else if (zeroize) begin + mem_a_wr_data <= '{default: 0}; + mem_b_wr_data <= '{default: 0}; + end + else begin + mem_a_wr_data <= '{encoded_coeffs[3], encoded_coeffs[2], encoded_coeffs[1], encoded_coeffs[0]}; + mem_b_wr_data <= '{encoded_coeffs[7], encoded_coeffs[6], encoded_coeffs[5], encoded_coeffs[4]}; + end + end + + // Write request generation + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) begin + mem_a_wr_req <= '{rd_wr_en: RW_IDLE, addr: '0}; + mem_b_wr_req <= '{rd_wr_en: RW_IDLE, addr: '0}; + end + else if (zeroize) begin + mem_a_wr_req <= '{rd_wr_en: RW_IDLE, addr: '0}; + mem_b_wr_req <= '{rd_wr_en: RW_IDLE, addr: '0}; + end + else if (state == READ_and_WRITE || state == WRITE) begin + mem_a_wr_req <= '{rd_wr_en: RW_WRITE, addr: locked_dest_addr + num_mem_operands}; + mem_b_wr_req <= '{rd_wr_en: RW_WRITE, addr: locked_dest_addr + num_mem_operands + 1}; + end + else begin + mem_a_wr_req <= '{rd_wr_en: RW_IDLE, addr: '0}; + mem_b_wr_req <= '{rd_wr_en: RW_IDLE, addr: '0}; + end + end + + // Memory read request generation + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) begin + API_rd_address <= '0; + end + else if (zeroize) begin + API_rd_address <= '0; + end + else if (state == READ || state == READ_and_EXEC || state == READ_and_WRITE) begin + API_rd_address <= API_ADDR_WIDTH'(num_api_operands); + end else begin + API_rd_address <= '0; + end + end + + + + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) begin + num_mem_operands <= 'h0; + num_api_operands <= 'h0; + locked_dest_addr <= 'h0; + pkdecode_done <= 'h0; + end + else if (zeroize) begin + num_mem_operands <= 'h0; + num_api_operands <= 'h0; + locked_dest_addr <= 'h0; + pkdecode_done <= 'h0; + end + else begin + if (pkdecode_enable) begin + locked_dest_addr <= dest_base_addr; + end + if (state == READ || state == READ_and_EXEC || state == READ_and_WRITE) begin + num_api_operands <= num_api_operands +1'h1; + end + else begin + num_api_operands <= 'h0; + end + if (state == READ_and_WRITE || state == WRITE) begin + num_mem_operands <= num_mem_operands +2'h2; + end + else begin + num_mem_operands <= 'h0; + end + + if (state == DONE) begin + pkdecode_done <= 'h1; + end + else begin + pkdecode_done <= 'h0; + end + end + end + +endmodule diff --git a/designs/Caliptra/src/adams-bridge/power2round_core.sv b/designs/Caliptra/src/adams-bridge/power2round_core.sv new file mode 100644 index 0000000..311301e --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/power2round_core.sv @@ -0,0 +1,49 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +//====================================================================== +// +// power2round_core.sv +// -------- +// Breaks down input coefficient +//====================================================================== + +module power2round_core + #( + parameter REG_SIZE = 23, + parameter MLDSA_Q = 23'd8380417, + parameter MLDSA_D = 13 + ) + ( + input wire [REG_SIZE-1:0] r, + output logic [MLDSA_D-1:0] r0, + output logic [REG_SIZE-MLDSA_D-1:0] r1 + ); + + localparam power2_d_minus_one = (1 << (MLDSA_D-1)) - 1; + + logic [REG_SIZE : 0] sum0; + logic [REG_SIZE : 0] sum1; + logic [REG_SIZE-MLDSA_D-1:0] r1_temp; + logic [MLDSA_D-1 : 0] r0_temp; + + always_comb begin + sum0 = r + power2_d_minus_one; + r1_temp = sum0[REG_SIZE-1:MLDSA_D]; + sum1 = r - (r1_temp << MLDSA_D); + r0_temp = sum1[MLDSA_D-1 : 0]; + end + + assign r0 = r0_temp; + assign r1 = r1_temp; +endmodule \ No newline at end of file diff --git a/designs/Caliptra/src/adams-bridge/power2round_ctrl.sv b/designs/Caliptra/src/adams-bridge/power2round_ctrl.sv new file mode 100644 index 0000000..b913ab3 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/power2round_ctrl.sv @@ -0,0 +1,239 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +//====================================================================== +// +// power2round_ctrl.sv +// --------------------- + +module power2round_ctrl + import abr_params_pkg::*; + import power2round_defines_pkg::*; + #( + parameter MLDSA_K = 8, + parameter MLDSA_N = 256 + ) + ( + input wire clk, + input wire reset_n, + input wire zeroize, + + input wire enable, + input wire [ABR_MEM_ADDR_WIDTH-1:0] src_base_addr, + input wire [ABR_MEM_ADDR_WIDTH-1:0] skmem_dest_base_addr, + // input wire [ABR_MEM_ADDR_WIDTH-1:0] pk_dest_base_addr, + input wire r_valid, + input wire sk_buff_valid, + input wire sk_buff_full, + + output mem_if_t mem_a_rd_req, + output mem_if_t mem_b_rd_req, + output mem_if_t skmem_a_wr_req, + output mem_if_t skmem_b_wr_req, + output logic pk_t1_wren, + output logic [7 : 0] pk_t1_wr_addr, // K*N*10 / 8coeff_per_write TODO: parameter + output logic sk_buff_enable, + output logic done + ); + + localparam [ABR_MEM_ADDR_WIDTH-1 : 0] MAX_MEM_ADDR = (MLDSA_K * (MLDSA_N/4))-2; + localparam [ABR_MEM_ADDR_WIDTH-1 : 0] MAX_SKMEM_ADDR = (MLDSA_K * (MLDSA_N/32) * 13)-2; + localparam [7 : 0] MAX_PK_ADDR = ((MLDSA_K * (MLDSA_N/8))-1); + + power2round_read_state_type read_fsm_state_ps, read_fsm_state_ns; + power2round_sk_write_state_type sk_write_fsm_state_ps, sk_write_fsm_state_ns; + power2round_pk_write_state_type pk_write_fsm_state_ps, pk_write_fsm_state_ns; + + + logic [ABR_MEM_ADDR_WIDTH-1:0] mem_rd_addr, mem_rd_addr_nxt, mem_rd_addr_delay, mem_rd_addr_tmp; + logic [ABR_MEM_ADDR_WIDTH-1:0] skmem_wr_addr, skmem_wr_addr_nxt; + logic [7 : 0] pk_wr_addr, pk_wr_addr_nxt; + + logic rst_mem_rd_addr, incr_mem_rd_addr, last_mem_rd_addr; + logic rst_skmem_wr_addr, incr_rskmem_wr_addr, last_skmem_wr_addr; + logic rst_pk_wr_addr, incr_pk_wr_addr, last_pk_wr_addr; + + logic pk_t1_wren_tmp; + +//addr counter + always_comb mem_rd_addr_nxt = mem_rd_addr + 'h2; + always_comb skmem_wr_addr_nxt = skmem_wr_addr + 'h2; + always_comb pk_wr_addr_nxt = pk_wr_addr + 'h1; + + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) begin + mem_rd_addr <= 'h0; + mem_rd_addr_delay <= 'h0; + skmem_wr_addr <= 'h0; + pk_wr_addr <= 'h0; + end + else if (zeroize) begin + mem_rd_addr <= 'h0; + mem_rd_addr_delay <= 'h0; + skmem_wr_addr <= 'h0; + pk_wr_addr <= 'h0; + end + else begin + if (rst_mem_rd_addr) + mem_rd_addr <= src_base_addr; + else if (incr_mem_rd_addr & ~last_mem_rd_addr) + mem_rd_addr <= mem_rd_addr_nxt; + + mem_rd_addr_delay <= mem_rd_addr; + + if (rst_skmem_wr_addr) + skmem_wr_addr <= skmem_dest_base_addr; + else if (incr_rskmem_wr_addr & ~last_skmem_wr_addr) + skmem_wr_addr <= skmem_wr_addr_nxt; + + if (rst_pk_wr_addr) + pk_wr_addr <= 'h0; //pk_dest_base_addr; + else if (incr_pk_wr_addr & ~last_pk_wr_addr) + pk_wr_addr <= pk_wr_addr_nxt; + end + end + + assign last_mem_rd_addr = (mem_rd_addr == src_base_addr + MAX_MEM_ADDR); + assign last_skmem_wr_addr = (skmem_wr_addr == skmem_dest_base_addr + MAX_SKMEM_ADDR); + assign last_pk_wr_addr = (pk_wr_addr == MAX_PK_ADDR); //pk_dest_base_addr = 'h0; + + // READ FSM + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) + read_fsm_state_ps <= T_RD_IDLE; + else if (zeroize) + read_fsm_state_ps <= T_RD_IDLE; + else + read_fsm_state_ps <= read_fsm_state_ns; + end + + always_comb begin + rst_mem_rd_addr = 'b0; + incr_mem_rd_addr = 'b0; + + case(read_fsm_state_ps) + T_RD_IDLE: begin + read_fsm_state_ns = enable? T_RD_MEM : T_RD_IDLE; + rst_mem_rd_addr = 'b1; + end + T_RD_MEM: begin + read_fsm_state_ns = (last_mem_rd_addr & ~sk_buff_full) ? T_RD_DONE : T_RD_MEM; + incr_mem_rd_addr = ~sk_buff_full; + end + T_RD_DONE: begin + read_fsm_state_ns = sk_buff_full ? T_RD_DONE : T_RD_IDLE; //ensure to capture the last read input + end + default: read_fsm_state_ns = T_RD_IDLE; + endcase + end + + // SK MEM WRITE FSM + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) + sk_write_fsm_state_ps <= SK_WR_IDLE; + else if (zeroize) + sk_write_fsm_state_ps <= SK_WR_IDLE; + else + sk_write_fsm_state_ps <= sk_write_fsm_state_ns; + end + + always_comb begin + rst_skmem_wr_addr = 'b0; + incr_rskmem_wr_addr = 'b0; + + case(sk_write_fsm_state_ps) + SK_WR_IDLE: begin + sk_write_fsm_state_ns = (read_fsm_state_ps == T_RD_IDLE)? SK_WR_IDLE : SK_WR_WAIT; + rst_skmem_wr_addr = 'b1; + end + SK_WR_WAIT: begin + sk_write_fsm_state_ns = SK_WR_MEM; + end + SK_WR_MEM: begin + sk_write_fsm_state_ns = last_skmem_wr_addr? SK_WR_DONE : SK_WR_MEM; + incr_rskmem_wr_addr = sk_buff_valid; + end + SK_WR_DONE: begin + sk_write_fsm_state_ns = SK_WR_IDLE; + end + default: sk_write_fsm_state_ns = SK_WR_IDLE; + endcase + end + + + // PK WRITE FSM + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) + pk_write_fsm_state_ps <= PK_WR_IDLE; + else if (zeroize) + pk_write_fsm_state_ps <= PK_WR_IDLE; + else + pk_write_fsm_state_ps <= pk_write_fsm_state_ns; + end + + always_comb begin + rst_pk_wr_addr = 'b0; + incr_pk_wr_addr = 'b0; + + case(pk_write_fsm_state_ps) + PK_WR_IDLE: begin + pk_write_fsm_state_ns = (read_fsm_state_ps == T_RD_IDLE)? PK_WR_IDLE : PK_WR_API; + rst_pk_wr_addr = 'b1; + end + PK_WR_API: begin + pk_write_fsm_state_ns = (last_pk_wr_addr & pk_t1_wren_tmp)? PK_WR_DONE : PK_WR_API; + incr_pk_wr_addr = (r_valid & ~sk_buff_full); + end + PK_WR_DONE: begin + pk_write_fsm_state_ns = PK_WR_IDLE; + end + default: pk_write_fsm_state_ns = PK_WR_IDLE; + endcase + end + + always_comb begin + sk_buff_enable = (sk_write_fsm_state_ps == SK_WR_MEM)? (r_valid & ~sk_buff_full) : 'h0; + end + + always_comb mem_rd_addr_tmp = sk_buff_full? mem_rd_addr_delay : mem_rd_addr; + + always_comb begin + mem_a_rd_req.rd_wr_en = (read_fsm_state_ps != T_RD_IDLE) ? RW_READ : RW_IDLE; + mem_a_rd_req.addr = mem_rd_addr_tmp; + + mem_b_rd_req.rd_wr_en = (read_fsm_state_ps != T_RD_IDLE) ? RW_READ : RW_IDLE; + mem_b_rd_req.addr = mem_rd_addr_tmp + 1'h1; + + skmem_a_wr_req.rd_wr_en = ((sk_write_fsm_state_ps == SK_WR_MEM) & sk_buff_valid) ? RW_WRITE : RW_IDLE; + skmem_a_wr_req.addr = skmem_wr_addr; + + skmem_b_wr_req.rd_wr_en = ((sk_write_fsm_state_ps == SK_WR_MEM) & sk_buff_valid) ? RW_WRITE : RW_IDLE; + skmem_b_wr_req.addr = skmem_wr_addr + 'h1; + + pk_t1_wren_tmp = (pk_write_fsm_state_ps == PK_WR_API)? (r_valid & ~sk_buff_full) : 'h0; + pk_t1_wr_addr = pk_wr_addr; + + end + + assign pk_t1_wren = pk_t1_wren_tmp; + + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) + done <= 'h0; + else if (zeroize) + done <= 'h0; + else + done <= (sk_write_fsm_state_ps == SK_WR_DONE); + end + +endmodule \ No newline at end of file diff --git a/designs/Caliptra/src/adams-bridge/power2round_defines_pkg.sv b/designs/Caliptra/src/adams-bridge/power2round_defines_pkg.sv new file mode 100644 index 0000000..2e0c95a --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/power2round_defines_pkg.sv @@ -0,0 +1,32 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +//====================================================================== +// +// power2round_defines_pkg.sv +// -------- +// power2round parameters for Mldsa +//====================================================================== + +`ifndef MLDSA_POWER2ROUND_DEFINES +`define MLDSA_POWER2ROUND_DEFINES + +package power2round_defines_pkg; + + typedef enum logic [1:0] {T_RD_IDLE, T_RD_MEM, T_RD_DONE} power2round_read_state_type; + typedef enum logic [1:0] {SK_WR_IDLE, SK_WR_WAIT, SK_WR_MEM, SK_WR_DONE} power2round_sk_write_state_type; + typedef enum logic [1:0] {PK_WR_IDLE, PK_WR_API, PK_WR_DONE} power2round_pk_write_state_type; + +endpackage + +`endif \ No newline at end of file diff --git a/designs/Caliptra/src/adams-bridge/power2round_skencode.sv b/designs/Caliptra/src/adams-bridge/power2round_skencode.sv new file mode 100644 index 0000000..3d1cba0 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/power2round_skencode.sv @@ -0,0 +1,41 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +//====================================================================== +// +// power2round_skencode.sv +// -------- +// Breaks down input coefficient +//====================================================================== + +module power2round_skencode + #( + parameter REG_SIZE = 23, + parameter MLDSA_Q = 23'd8380417, + parameter MLDSA_D = 13 + ) + ( + input logic [MLDSA_D-1:0] r0, + output logic [MLDSA_D-1:0] r0_packed + ); + + localparam power2_d_minus_one = (1 << (MLDSA_D-1)); + + logic [MLDSA_D-1 : 0] r0_packed_temp; + + always_comb begin + r0_packed_temp = power2_d_minus_one - r0; + end + + assign r0_packed = r0_packed_temp; +endmodule \ No newline at end of file diff --git a/designs/Caliptra/src/adams-bridge/power2round_top.sv b/designs/Caliptra/src/adams-bridge/power2round_top.sv new file mode 100644 index 0000000..b7d6c86 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/power2round_top.sv @@ -0,0 +1,207 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +//====================================================================== +// +// power2round_top.sv +// -------- +//====================================================================== + +module power2round_top + import abr_params_pkg::*; + #( + parameter REG_SIZE = 24, + parameter MLDSA_Q = 23'd8380417, + parameter MLDSA_N = 256, + parameter MLDSA_K = 8, + parameter MLDSA_D = 13, + parameter AHB_DATA_WIDTH = 32 + ) + ( + input wire clk, + input wire reset_n, + input wire zeroize, + + input wire enable, + input wire [ABR_MEM_ADDR_WIDTH-1:0] src_base_addr, + input wire [ABR_MEM_ADDR_WIDTH-1:0] skmem_dest_base_addr, //skmem API base addr - TODO: finalize size + // input wire [ABR_MEM_ADDR_WIDTH-1:0] pk_dest_base_addr, //reg API base addr - TODO: finalize size + + //Input from internal memory + output mem_if_t mem_a_rd_req, + output mem_if_t mem_b_rd_req, + input wire [(4*REG_SIZE)-1:0] mem_rd_data_a, + input wire [(4*REG_SIZE)-1:0] mem_rd_data_b, + //input wire mem_rd_data_valid, // TODO: + + //output to sk mem + output mem_if_t skmem_a_wr_req, + output mem_if_t skmem_b_wr_req, + output logic [AHB_DATA_WIDTH-1:0] skmem_wr_data_a, + output logic [AHB_DATA_WIDTH-1:0] skmem_wr_data_b, + + output logic pk_t1_wren, + output logic [7:0][9:0] pk_t1_wrdata, // TODO: change to parameter + output logic [7:0] pk_t1_wr_addr, // TODO: change to parameter + + output logic done + ); + + + logic [7:0][REG_SIZE-1:0] mem_data_reg; + logic [7:0][MLDSA_D-1:0] r0, r0_packed, r0_packed_reg; + logic [7:0][REG_SIZE-MLDSA_D-2:0] r1, r1_reg; + + logic sk_buff_full; + logic mem_data_reg_valid, r_valid; + logic mem_rd_data_valid; + + logic sk_buff_enable; + logic sk_buff_valid; + + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) + mem_rd_data_valid <= 'h0; + else if (zeroize) + mem_rd_data_valid <= 'h0; + else + mem_rd_data_valid <= (mem_a_rd_req.rd_wr_en == RW_READ); //assuming data is valid 1 cycle after read request + end + + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) begin + mem_data_reg <= 'h0; + mem_data_reg_valid <= 'h0; + end + else if (zeroize) begin + mem_data_reg <= 'h0; + mem_data_reg_valid <= 'h0; + end + else if (~sk_buff_full) begin + {mem_data_reg[3], mem_data_reg[2], mem_data_reg[1], mem_data_reg[0]} <= mem_rd_data_a; + {mem_data_reg[7], mem_data_reg[6], mem_data_reg[5], mem_data_reg[4]} <= mem_rd_data_b; + mem_data_reg_valid <= mem_rd_data_valid; + end + end + + generate + for (genvar i = 0; i < 8; i++) begin : gen_r0_r1 + power2round_core #( + .REG_SIZE(REG_SIZE-1), + .MLDSA_Q(MLDSA_Q), + .MLDSA_D(MLDSA_D) + ) + power2round_core_inst ( + .r(mem_data_reg[i][REG_SIZE-2:0]), + .r0(r0[i]), + .r1(r1[i]) + ); + end + endgenerate + + + generate + for (genvar i = 0; i < 8; i++) begin : gen_r0_packed + power2round_skencode #( + .REG_SIZE(REG_SIZE-1), + .MLDSA_Q(MLDSA_Q), + .MLDSA_D(MLDSA_D) + ) + power2round_skencode_inst ( + .r0(r0[i]), + .r0_packed(r0_packed[i]) + ); + end + endgenerate + + generate + for (genvar i = 0; i < 8; i++) begin + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) begin + r0_packed_reg[i] <= 'h0; + r1_reg[i] <= 'h0; + end + else if (zeroize) begin + r0_packed_reg[i] <= 'h0; + r1_reg[i] <= 'h0; + end + else if (~sk_buff_full) begin + r0_packed_reg[i] <= r0_packed[i]; + r1_reg[i] <= r1[i]; + end + end + end + endgenerate + + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) + r_valid <= 'h0; + else if (zeroize) + r_valid <= 'h0; + else if (~sk_buff_full) + r_valid <= mem_data_reg_valid; + end + + generate + for (genvar i = 0; i < 8; i++) begin + always_comb begin + pk_t1_wrdata[i] = r1_reg[i]; + end + end + endgenerate + + + abr_sample_buffer #( + .NUM_WR(13), + .NUM_RD(8), + .BUFFER_DATA_W(8) + ) + sk_buffer_inst ( + .clk(clk), + .rst_b(reset_n), + .zeroize(zeroize), + .data_valid_i({13{sk_buff_enable}}), + .data_i(r0_packed_reg), + .buffer_full_o(sk_buff_full), + .data_valid_o(sk_buff_valid), + .data_o({skmem_wr_data_b, skmem_wr_data_a}) + ); + + + power2round_ctrl #( + .MLDSA_K(MLDSA_K), + .MLDSA_N(MLDSA_N) + ) + power2round_ctrl_inst ( + .clk(clk), + .reset_n(reset_n), + .zeroize(zeroize), + .enable(enable), + .src_base_addr(src_base_addr), + .skmem_dest_base_addr(skmem_dest_base_addr), + // .pk_dest_base_addr(pk_dest_base_addr), + .r_valid(r_valid), + .sk_buff_valid(sk_buff_valid), + .sk_buff_full(|sk_buff_full), + + .mem_a_rd_req(mem_a_rd_req), + .mem_b_rd_req(mem_b_rd_req), + .skmem_a_wr_req(skmem_a_wr_req), + .skmem_b_wr_req(skmem_b_wr_req), + .pk_t1_wren(pk_t1_wren), + .pk_t1_wr_addr(pk_t1_wr_addr), + .sk_buff_enable(sk_buff_enable), + .done(done) + ); + +endmodule diff --git a/designs/Caliptra/src/adams-bridge/rej_bounded2.sv b/designs/Caliptra/src/adams-bridge/rej_bounded2.sv new file mode 100644 index 0000000..77c2cb3 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/rej_bounded2.sv @@ -0,0 +1,48 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. + +//Rej Bounded function computes % 5 of the input sample +//Samples must be < REJ_VALUE to be valid + +module rej_bounded2 + // import ::*; + #( + parameter REJ_SAMPLE_W = 24 + ,parameter REJ_VALUE = 15 + ) + ( + //input data + input logic valid_i, + input logic [3:0] data_i, + + //output data + output logic valid_o, + output logic [2:0] data_o + + ); + + logic [3:0] a; + logic [2:0] b; + + assign a = data_i; + + //Check sample validity + always_comb begin + valid_o = valid_i & (a < REJ_VALUE); + //Perform data_i % 5 + b = a[1:0] - a[3:2]; + data_o = b[2] ? 'd5 + b[2:0] : {1'b0, b[1:0]}; + end + +endmodule diff --git a/designs/Caliptra/src/adams-bridge/rej_bounded_ctrl.sv b/designs/Caliptra/src/adams-bridge/rej_bounded_ctrl.sv new file mode 100644 index 0000000..efc0ce9 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/rej_bounded_ctrl.sv @@ -0,0 +1,102 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. + + +module rej_bounded_ctrl + import abr_params_pkg::*; + #( + parameter REJ_NUM_SAMPLERS = 8 + ,parameter REJ_SAMPLE_W = 4 + ,parameter REJ_VLD_SAMPLES = 4 + ,parameter REJ_VLD_SAMPLES_W = 24 + ,parameter REJ_VALUE = 15 + ,parameter REJ_BUFFER_W = 3 + ) + ( + input logic clk, + input logic rst_b, + input logic zeroize, + //input data + input logic data_valid_i, + output logic data_hold_o, + input logic [REJ_NUM_SAMPLERS-1:0][REJ_SAMPLE_W-1:0] data_i, + + //output data + output logic data_valid_o, + output logic [REJ_VLD_SAMPLES-1:0][REJ_VLD_SAMPLES_W-1:0] data_o + + ); + + logic [REJ_NUM_SAMPLERS-1:0] sample_valid; + logic [REJ_NUM_SAMPLERS-1:0][REJ_BUFFER_W-1:0] buffer_data; + + logic rej_buffer_valid; + logic [REJ_VLD_SAMPLES-1:0][REJ_BUFFER_W-1:0] rej_buffer; + + logic buffer_full; + + + //Hold if the buffer is full + always_comb data_hold_o = buffer_full; + + generate + for (genvar inst_g = 0; inst_g < REJ_NUM_SAMPLERS; inst_g++) begin : rej_bounded_inst + rej_bounded2 #( + .REJ_SAMPLE_W(REJ_SAMPLE_W), + .REJ_VALUE(REJ_VALUE) + ) rej_bounded_i ( + .valid_i(data_valid_i), + .data_i(data_i[inst_g]), + + .valid_o(sample_valid[inst_g]), + .data_o(buffer_data[inst_g]) + ); + end + endgenerate + + //Buffer valid samples + abr_sample_buffer #( + .NUM_WR(REJ_NUM_SAMPLERS), + .NUM_RD(REJ_VLD_SAMPLES), + .BUFFER_DATA_W(REJ_BUFFER_W) + ) mldsa_sample_buffer_i ( + .clk(clk), + .rst_b(rst_b), + .zeroize(zeroize), + //input data + .data_valid_i(sample_valid), + .data_i(buffer_data), + .buffer_full_o(buffer_full), + //output data + .data_valid_o(rej_buffer_valid), + .data_o(rej_buffer) + ); + + //Output is valid when we have REJ_VLD_SAMPLES worth of valid data + always_comb data_valid_o = rej_buffer_valid; + //Rej buffer value selects between 5 possible outputs (2-(a%5) mod q) + always_comb begin + for (int sample = 0; sample < REJ_VLD_SAMPLES; sample++) begin + unique case (rej_buffer[sample]) + 3'd0 : data_o[sample] = 2; + 3'd1 : data_o[sample] = 1; + 3'd2 : data_o[sample] = 0; + 3'd3 : data_o[sample] = MLDSA_Q-1; + 3'd4 : data_o[sample] = MLDSA_Q-2; + default : data_o[sample] = '0; + endcase + end + end + +endmodule diff --git a/designs/Caliptra/src/adams-bridge/rej_sampler.sv b/designs/Caliptra/src/adams-bridge/rej_sampler.sv new file mode 100644 index 0000000..15cd06a --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/rej_sampler.sv @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. + +//Rej sampler function tests each sample for validity +//Valid samples must be < REJ_VALUE + +module rej_sampler + // import ::*; + #( + parameter REJ_SAMPLE_W = 24 + ,parameter REJ_VALUE = 8380417 + ,localparam REJ_VLD_SAMPLE_W = $clog2(REJ_VALUE) + ) + ( + //input data + input logic valid_i, + input logic [REJ_SAMPLE_W-1:0] data_i, + + //output data + output logic valid_o, + output logic [REJ_VLD_SAMPLE_W-1:0] data_o + + ); + + //Check sample validity + always_comb begin + valid_o = valid_i & (data_i[REJ_VLD_SAMPLE_W-1:0] < REJ_VALUE[REJ_VLD_SAMPLE_W-1:0]); + data_o = data_i[REJ_VLD_SAMPLE_W-1:0]; + end + +endmodule \ No newline at end of file diff --git a/designs/Caliptra/src/adams-bridge/rej_sampler_ctrl.sv b/designs/Caliptra/src/adams-bridge/rej_sampler_ctrl.sv new file mode 100644 index 0000000..b623f76 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/rej_sampler_ctrl.sv @@ -0,0 +1,98 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. + + +module rej_sampler_ctrl + import abr_params_pkg::*; + #( + parameter REJ_NUM_SAMPLERS = 5 + ,parameter REJ_SAMPLE_W = 24 + ,parameter REJ_VLD_SAMPLES = 4 + ,parameter REJ_VLD_SAMPLES_W = 24 + ,parameter REJ_VALUE = 8380417 + ,parameter OPT_REJ_BUFFER_DEPTH = 0 + ,parameter REJ_BUFFER_W = $clog2(REJ_VALUE) + ) + ( + input logic clk, + input logic rst_b, + + input logic zeroize, + + //input data + input logic data_valid_i, + output logic data_hold_o, + input logic [REJ_NUM_SAMPLERS-1:0][REJ_SAMPLE_W-1:0] data_i, + + //output data + output logic data_valid_o, + output logic [REJ_VLD_SAMPLES-1:0][REJ_VLD_SAMPLES_W-1:0] data_o + + ); + + logic [REJ_NUM_SAMPLERS-1:0] sample_valid; + logic [REJ_NUM_SAMPLERS-1:0][REJ_BUFFER_W-1:0] buffer_data; + + logic rej_buffer_valid; + logic [REJ_VLD_SAMPLES-1:0][REJ_BUFFER_W-1:0] rej_buffer; + + logic buffer_full; + + //Hold if the buffer is full + always_comb data_hold_o = buffer_full; + + generate + for (genvar inst_g = 0; inst_g < REJ_NUM_SAMPLERS; inst_g++) begin : rej_sampler_inst + //Check sample validity + rej_sampler #( + .REJ_SAMPLE_W(REJ_SAMPLE_W), + .REJ_VALUE(REJ_VALUE) + ) rej_sampler_i ( + .valid_i(data_valid_i), + .data_i(data_i[inst_g]), + + .valid_o(sample_valid[inst_g]), + .data_o(buffer_data[inst_g]) + ); + end + endgenerate + + //Buffer valid samples + abr_sample_buffer #( + .NUM_WR(REJ_NUM_SAMPLERS), + .NUM_RD(REJ_VLD_SAMPLES), + .BUFFER_DATA_W(REJ_BUFFER_W) + ) mldsa_sample_buffer_i ( + .clk(clk), + .rst_b(rst_b), + .zeroize(zeroize), + //input data + .data_valid_i(sample_valid), + .data_i(buffer_data), + .buffer_full_o(buffer_full), + //output data + .data_valid_o(rej_buffer_valid), + .data_o(rej_buffer) + ); + + //Output is valid when we have REJ_VLD_SAMPLES worth of valid data + always_comb data_valid_o = rej_buffer_valid; + //Need to concat the zeros back for diff between sample w and the valid sample bits + always_comb begin + for (int sample = 0; sample < REJ_VLD_SAMPLES; sample++) begin + data_o[sample] = { {REJ_SAMPLE_W-REJ_BUFFER_W{1'b0}} , rej_buffer[sample] }; + end + end + +endmodule diff --git a/designs/Caliptra/src/adams-bridge/sample_in_ball.sv b/designs/Caliptra/src/adams-bridge/sample_in_ball.sv new file mode 100644 index 0000000..a9bb997 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/sample_in_ball.sv @@ -0,0 +1,36 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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 sibress or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//Sample In Ball function tests each sample for validitiy +//Valid samples must be <= rej_value_i + +module sample_in_ball + // import ::*; + #( + parameter SIB_SAMPLE_W = 8 + ) + ( + //input data + input logic valid_i, + input logic [SIB_SAMPLE_W-1:0] data_i, + input logic [SIB_SAMPLE_W-1:0] rej_value_i, + + //output data + output logic valid_o + + ); + + always_comb valid_o = valid_i & (data_i <= rej_value_i); + +endmodule diff --git a/designs/Caliptra/src/adams-bridge/sample_in_ball_ctrl.sv b/designs/Caliptra/src/adams-bridge/sample_in_ball_ctrl.sv new file mode 100644 index 0000000..177618d --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/sample_in_ball_ctrl.sv @@ -0,0 +1,245 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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 sibress or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + +module sample_in_ball_ctrl + import sib_pkg::*; + import abr_params_pkg::*; + #( + parameter SIB_NUM_SAMPLERS = 4 + ,parameter SIB_SAMPLE_W = 8 + ,parameter SIB_TAU = 60 + ,parameter SIB_NUM_COEFF = 256 + ,localparam MLDSA_Q_WIDTH = $clog2(8380417) + ) + ( + input logic clk, + input logic rst_b, + input logic zeroize, + + //input data + input logic data_valid_i, + output logic data_hold_o, + input logic [SIB_NUM_SAMPLERS-1:0][SIB_SAMPLE_W-1:0] data_i, + output logic sib_done_o, + + //memory if + output logic [1:0] cs_o, + output logic [1:0] we_o, + output logic [1:0][7:2] addr_o, + output logic [1:0][3:0][MLDSA_Q_WIDTH-1:0] wrdata_o, + input logic [1:0][3:0][MLDSA_Q_WIDTH-1:0] rddata_i + + ); + localparam SIB_NUM_DATA_BITS = $bits(data_i); + + sib_fsm_state_e sib_fsm_ns; + sib_fsm_state_e sib_fsm_ps; + + logic last_sample; + + logic [SIB_TAU-1:0] sign_buffer, sign_buffer_d; + logic [(SIB_NUM_DATA_BITS*2)-1:0] sign_buffer_nxt; + logic sign_buffer_en; + logic sign_buffer_ph; + + logic [SIB_SAMPLE_W-1:0] rej_value; + logic rej_value_en; + + logic [SIB_NUM_SAMPLERS-1:0] sampler_valid; + logic sampler_hold; + + logic index_found; + logic [$clog2(SIB_NUM_SAMPLERS)-1:0] valid_index; + logic [SIB_SAMPLE_W-1:0] valid_sample; + logic [SIB_NUM_SAMPLERS-1:0] sampler_mask, sampler_mask_d; + logic sampler_mask_en; + logic sampler_mask_clear; + logic shuffler_valid; + + logic shuffler_hold; + + //FSM Controller + always_comb begin : sib_fsm_state_combo + //default loopback assignment + sib_fsm_ns = sib_fsm_ps; + unique case (sib_fsm_ps) + SIB_IDLE: begin + if (data_valid_i) sib_fsm_ns = SIB_SIGN_BUFFER; + end + SIB_SIGN_BUFFER: begin + if (data_valid_i) sib_fsm_ns = SIB_ACTIVE; + end + SIB_ACTIVE: begin + if (last_sample) sib_fsm_ns = SIB_DONE; + end + SIB_DONE: begin + sib_fsm_ns = SIB_IDLE; + end + //ERROR + default: begin + sib_fsm_ns = SIB_IDLE; + end + endcase + end + + always_comb begin : sib_fsm_output_combo + data_hold_o = 0; + sign_buffer_en = 0; + sign_buffer_ph = 0; + rej_value_en = 0; + sampler_mask_en = 0; + sampler_mask_clear = 0; + shuffler_valid = 0; + sib_done_o = 0; + unique case (sib_fsm_ps) + SIB_IDLE: begin + sign_buffer_en = data_valid_i; + sign_buffer_ph = 0; + end + SIB_SIGN_BUFFER: begin + sign_buffer_en = data_valid_i; + sign_buffer_ph = 1; + end + SIB_ACTIVE: begin + data_hold_o = sampler_hold | shuffler_hold; + shuffler_valid = index_found; + rej_value_en = index_found & ~shuffler_hold; + sampler_mask_en = index_found & sampler_hold & ~shuffler_hold; + sampler_mask_clear = ~index_found | ~data_hold_o; + end + SIB_DONE: begin + sib_done_o = 1; + end + //ERROR + default: begin + data_hold_o = 1; + end + endcase + end + + always_ff @(posedge clk or negedge rst_b) begin : sib_fsm_state_reg + if (!rst_b) sib_fsm_ps <= SIB_IDLE; + else if (zeroize) sib_fsm_ps <= SIB_IDLE; + else sib_fsm_ps <= sib_fsm_ns; + end + + //Sign buffer + //Gather TAU bits of sign data over TAU/(SIB_NUM_SAMPLERS*SIB_SAMPLE_W) clocks + always_comb sign_buffer_nxt = sign_buffer_ph ? {data_i, {SIB_NUM_DATA_BITS{1'b0}}} : {{SIB_NUM_DATA_BITS{1'b0}}, data_i}; + always_comb sign_buffer_d = sign_buffer | sign_buffer_nxt[SIB_TAU-1:0]; + + + always_ff @(posedge clk or negedge rst_b) begin + if (!rst_b)begin + sign_buffer <= '0; + end else if (zeroize) begin + sign_buffer <= '0; + end else if (sib_done_o) begin + sign_buffer <= '0; + end else if (sign_buffer_en) begin + sign_buffer <= sign_buffer_d; + end else if (rej_value_en) begin + sign_buffer <= SIB_TAU'(sign_buffer >> 1); + end else begin + sign_buffer <= sign_buffer; + end + end + + //Initialize rejection value to 256 - TAU + //Increment the rejection value whenever a valid sample is found + always_ff @(posedge clk or negedge rst_b) begin + if (!rst_b) begin + rej_value <= SIB_NUM_COEFF - SIB_TAU; + end else if (zeroize) begin + rej_value <= SIB_NUM_COEFF - SIB_TAU; + end else if (sib_done_o) begin + rej_value <= SIB_NUM_COEFF - SIB_TAU; + end else if (rej_value_en) begin + rej_value <= rej_value + 1'b1; + end else begin + rej_value <= rej_value; + end + end + + //Find first valid sample + always_comb begin + index_found = 0; + valid_index = 0; + sampler_mask_d = sampler_mask; + for (int i = 0; i < SIB_NUM_SAMPLERS; i++) begin + if (data_valid_i & ~index_found) begin + sampler_mask_d[i] = 0; + if (sampler_valid[i]) begin + index_found = 1; + valid_index = i[$clog2(SIB_NUM_SAMPLERS)-1:0]; + end + end + end + end + + always_ff @(posedge clk or negedge rst_b) begin + if (!rst_b)begin + sampler_mask <= '1; + end else if (zeroize | sampler_mask_clear) begin + sampler_mask <= '1; + end else if (sampler_mask_en) begin + sampler_mask <= sampler_mask_d; + end else begin + sampler_mask <= sampler_mask; + end + end + + //sample in ball is done when we collect TAU samples (rej value is 255) + always_comb last_sample = (&rej_value) & shuffler_valid & ~shuffler_hold; + always_comb valid_sample = data_i[valid_index]; + + generate + for (genvar inst_g = 0; inst_g < SIB_NUM_SAMPLERS; inst_g++) begin : sample_in_ball_inst + sample_in_ball #( + .SIB_SAMPLE_W(SIB_SAMPLE_W) + ) sample_in_ball_i ( + .valid_i(sampler_mask[inst_g]), + .data_i(data_i[inst_g]), + .rej_value_i(rej_value), + .valid_o(sampler_valid[inst_g]) + ); + end + endgenerate + + always_comb sampler_hold = index_found & (valid_index != (SIB_NUM_SAMPLERS-1)); + + //Shuffler + sample_in_ball_shuffler #( + .SIB_SAMPLE_W(SIB_SAMPLE_W) + ) sib_shuffler_i ( + .clk(clk), + .rst_b(rst_b), + .zeroize(zeroize), + + .valid_i(shuffler_valid), + .hold_o(shuffler_hold), + .indexi_i(rej_value), + .indexj_i(valid_sample), + .sign_i(sign_buffer[0]), + + //memory if + .cs_o(cs_o), + .we_o(we_o), + .addr_o(addr_o), + .wrdata_o(wrdata_o), + .rddata_i(rddata_i) + ); + +endmodule diff --git a/designs/Caliptra/src/adams-bridge/sample_in_ball_pkg.sv b/designs/Caliptra/src/adams-bridge/sample_in_ball_pkg.sv new file mode 100644 index 0000000..5ac7efd --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/sample_in_ball_pkg.sv @@ -0,0 +1,28 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. + +`ifndef ABR_SIB_PKG +`define ABR_SIB_PKG + +package sib_pkg; + + typedef enum logic [1:0] { + SIB_IDLE = 2'b00, + SIB_SIGN_BUFFER = 2'b01, + SIB_ACTIVE = 2'b10, + SIB_DONE = 2'b11 +} sib_fsm_state_e; + +endpackage +`endif \ No newline at end of file diff --git a/designs/Caliptra/src/adams-bridge/sample_in_ball_shuffler.sv b/designs/Caliptra/src/adams-bridge/sample_in_ball_shuffler.sv new file mode 100644 index 0000000..c5ccb24 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/sample_in_ball_shuffler.sv @@ -0,0 +1,116 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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 sibress or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//Sample In Ball Shuffler takes in two indexes (i and j) and a sign bit +//Indexes are used to address a 256 coefficient memory +//The value found in Index j is moved to Index i +//For sign value of 1, the value Q-1 is written to Index j, else 1 is written to Index j + +module sample_in_ball_shuffler + import abr_params_pkg::*; + #( + parameter SIB_SAMPLE_W = 8 + ) + ( + input logic clk, + input logic rst_b, + input logic zeroize, + //input data + input logic valid_i, + output logic hold_o, + input logic [SIB_SAMPLE_W-1:0] indexi_i, + input logic [SIB_SAMPLE_W-1:0] indexj_i, + input logic sign_i, + + //memory if + output logic [1:0] cs_o, + output logic [1:0] we_o, + output logic [1:0][7:2] addr_o, + output logic [1:0][3:0][MLDSA_Q_WIDTH-2:0] wrdata_o, + input logic [1:0][3:0][MLDSA_Q_WIDTH-2:0] rddata_i + + ); + + logic read_valid; + logic addr_match; + logic [MLDSA_Q_WIDTH-2:0] nxt_i, nxt_j; + logic [3:0][MLDSA_Q_WIDTH-2:0] wrdata_pre; + + //hold the first phase + always_comb hold_o = valid_i & ~read_valid; + + //Read phase + //Read from entry pointed to by indexi_i and indexj_i + always_comb addr_o[0] = indexj_i[7:2]; + always_comb addr_o[1] = indexi_i[7:2]; + + always_ff @(posedge clk or negedge rst_b) begin + if (!rst_b)begin + read_valid <= 0; + end else if (zeroize) begin + read_valid <= 0; + end else if (valid_i & ~read_valid) begin + read_valid <= 1; + end else begin + read_valid <= 0; + end + end + + always_comb addr_match = indexi_i[7:2] == indexj_i[7:2]; + + //Assign the nxt j value (contents of i, modified by sign bit) + always_comb nxt_j = sign_i ? MLDSA_Q-1 : 1; + + //Write nxt_j into indexj_i location + always_comb begin + unique case (indexj_i[1:0]) + 2'b00: wrdata_o[0] = {rddata_i[0][3],rddata_i[0][2],rddata_i[0][1],nxt_j }; + 2'b01: wrdata_o[0] = {rddata_i[0][3],rddata_i[0][2],nxt_j ,rddata_i[0][0]}; + 2'b10: wrdata_o[0] = {rddata_i[0][3],nxt_j ,rddata_i[0][1],rddata_i[0][0]}; + 2'b11: wrdata_o[0] = {nxt_j ,rddata_i[0][2],rddata_i[0][1],rddata_i[0][0]}; + default: wrdata_o[0] = 'x; + endcase + end + + //Assign the nxt i value (contents of j) + always_comb nxt_i = rddata_i[0][indexj_i[1:0]]; + + //Write nxt_i into indexi_i location + always_comb begin + unique case ({indexi_i[1:0]}) + 2'b00: wrdata_pre = {rddata_i[1][3],rddata_i[1][2],rddata_i[1][1],nxt_i }; + 2'b01: wrdata_pre = {rddata_i[1][3],rddata_i[1][2],nxt_i ,rddata_i[1][0]}; + 2'b10: wrdata_pre = {rddata_i[1][3],nxt_i ,rddata_i[1][1],rddata_i[1][0]}; + 2'b11: wrdata_pre = {nxt_i ,rddata_i[1][2],rddata_i[1][1],rddata_i[1][0]}; + default: wrdata_pre = 'x; + endcase + end + + //If addr match, write nxt_j on same write port + always_comb begin + unique casez ({addr_match, indexj_i[1:0]}) + 3'b0_??: wrdata_o[1] = wrdata_pre; + 3'b1_00: wrdata_o[1] = {wrdata_pre[3],wrdata_pre[2],wrdata_pre[1],nxt_j }; + 3'b1_01: wrdata_o[1] = {wrdata_pre[3],wrdata_pre[2],nxt_j ,wrdata_pre[0]}; + 3'b1_10: wrdata_o[1] = {wrdata_pre[3],nxt_j ,wrdata_pre[1],wrdata_pre[0]}; + 3'b1_11: wrdata_o[1] = {nxt_j ,wrdata_pre[2],wrdata_pre[1],wrdata_pre[0]}; + default: wrdata_o[1] = 'x; + endcase + end + + always_comb cs_o = {2{valid_i}}; + always_comb we_o[0] = read_valid & ~addr_match; + always_comb we_o[1] = read_valid; + +endmodule diff --git a/designs/Caliptra/src/adams-bridge/sib_mem.sv b/designs/Caliptra/src/adams-bridge/sib_mem.sv new file mode 100644 index 0000000..b0ae102 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/sib_mem.sv @@ -0,0 +1,67 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. + +module sib_mem #( + parameter DEPTH = 64 + ,parameter NUM_PORTS = 1 + ,parameter DATA_WIDTH = 32 + ,parameter ADDR_WIDTH = $clog2(DEPTH) + + ) + ( + input logic clk_i, + input logic rst_b, + input logic zeroize, + + input logic [NUM_PORTS-1:0] cs_i, + input logic [NUM_PORTS-1:0] we_i, + input logic [NUM_PORTS-1:0][ADDR_WIDTH-1:0] addr_i, + input logic [NUM_PORTS-1:0][DATA_WIDTH-1:0] wdata_i, + output logic [NUM_PORTS-1:0][DATA_WIDTH-1:0] rdata_o + ); + + //storage element + logic [DEPTH-1:0][DATA_WIDTH-1:0] mem; + + always @(posedge clk_i or negedge rst_b) begin + if (!rst_b) begin + mem <= '0; + end + else if (zeroize) begin + mem <= '0; + end else begin + for (int port = 0; port < NUM_PORTS; port++) begin + if (cs_i[port] & we_i[port]) begin + mem[addr_i[port]] <= wdata_i[port]; + end + end + end + end + + always @(posedge clk_i or negedge rst_b) begin + if (!rst_b) begin + rdata_o <= '0; + end + else if (zeroize) begin + rdata_o <= '0; + end else begin + for (int port = 0; port < NUM_PORTS; port++) begin + if (cs_i[port] & ~we_i[port]) begin + rdata_o[port] <= mem[addr_i[port]]; + end + end + end + end + +endmodule diff --git a/designs/Caliptra/src/adams-bridge/sigdecode_h.sv b/designs/Caliptra/src/adams-bridge/sigdecode_h.sv new file mode 100644 index 0000000..7642604 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/sigdecode_h.sv @@ -0,0 +1,192 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +//====================================================================== +// +// sigdecode_h.sv +// ----------- +// Processes encoded h component of the signature reg and generates hint vectors per polynomial. +// Every index recorded in y byte string indicates a non-zero hint. Remaining are 0s. +// This module reads the y[w+k-1:w] locations to obtain the number of non-zero hints +// per poly. Then it begins to process y[w-1:0] locations to construct the hint vector. +// To keep it consistent with memory layout, the generated coefficients are 24-bits and +// 4 coeffs are written to each memory addr. + +module sigdecode_h + import abr_params_pkg::*; + #( + parameter REG_SIZE = 24, + parameter MLDSA_OMEGA = 75, + parameter MLDSA_K = 8, + parameter MLDSA_N = 256 + ) + ( + input wire clk, + input wire reset_n, + input wire zeroize, + + input wire [(MLDSA_OMEGA+MLDSA_K)-1:0][7:0] encoded_h_i, + + input wire sigdecode_h_enable, + input wire [ABR_MEM_ADDR_WIDTH-1:0] dest_base_addr, + + output mem_if_t mem_wr_req, + output logic [(4*REG_SIZE)-1:0] mem_wr_data, + output logic sigdecode_h_done, + output logic sigdecode_h_error + ); + + localparam SIG_H_NUM_DWORDS = ((MLDSA_OMEGA + MLDSA_K + 1)*8)/32; + + // logic [(MLDSA_OMEGA+MLDSA_K)-1:0][7:0] encoded_h; + // logic [SIG_H_NUM_DWORDS-1:0][31:0] encoded_h_reg; + logic [MLDSA_OMEGA-1:0] hint_array; + logic [7:0] hintsum, hintsum_prev_poly, hintsum_curr_poly; + logic [3:0] poly_count; + logic [6:0] rd_ptr; + logic [MLDSA_N-1:0] bitmap; + logic rst_bitmap; + logic [3:0][7:0] hint; + logic [3:0] curr_poly_map; + logic [$clog2(MLDSA_N)-1:0] bitmap_ptr; + logic hint_rd_en; + mem_if_t mem_wr_req_int; + logic OR_remaining_encoded_h_i; + logic hintsum_max_error_i; + logic hint_ok; + logic [7:0] prev_hint_byte; + logic hint_rd_en_f, hint_rd_en_pulse; + logic first_hint; + + //TODO: look into remaining_zero - to save some latency, we can save y[w-1:0] as we read them and + //keep track of what coeffs are being written to memory. If we see that the last y[i] coeff has been written + //to memory, we don't need to continue and can exit and move to the next poly. Assumption is that memory contains 0s + //and it's ok for this operation to be non-constant time. + + //Delay flops + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) begin + hintsum <= 'h0; + hintsum_prev_poly <= 'h0; + mem_wr_data <= 'h0; + hint <= 'h0; + mem_wr_req.addr <= 'h0; + mem_wr_req.rd_wr_en <= RW_IDLE; + sigdecode_h_error <= 'b0; + hint_rd_en_f <= 'b0; + hint_ok <= 'b1; + prev_hint_byte <= 'h0; + first_hint <= 'h0; + end + else if (zeroize) begin + hintsum <= 'h0; + hintsum_prev_poly <= 'h0; + mem_wr_data <= 'h0; + hint <= 'h0; + mem_wr_req.addr <= 'h0; + mem_wr_req.rd_wr_en <= RW_IDLE; + sigdecode_h_error <= 'b0; + hint_rd_en_f <= 'b0; + hint_ok <= 'b1; + prev_hint_byte <= 'h0; + first_hint <= 'h0; + end + else begin + hintsum <= sigdecode_h_done ? 'h0 : encoded_h_i[MLDSA_OMEGA+poly_count]; + hintsum_prev_poly <= hintsum; + mem_wr_data <= {REG_SIZE'(bitmap[8'(bitmap_ptr+3)]), REG_SIZE'(bitmap[8'(bitmap_ptr+2)]), REG_SIZE'(bitmap[8'(bitmap_ptr+1)]), REG_SIZE'(bitmap[8'(bitmap_ptr)])}; + hint <= hint_rd_en ? {encoded_h_i[7'(rd_ptr+3)], encoded_h_i[7'(rd_ptr+2)], encoded_h_i[7'(rd_ptr+1)], encoded_h_i[7'(rd_ptr)]} : 'h0; + mem_wr_req <= mem_wr_req_int; + + //Trigger error in the following conditions: + //1. If hintsum is not in ascending order in encoded_h[w+k-1:w] bytes + //2. If bytes after the last non-zero hint of last non-zero hintsum poly are not 0s + //3. If hints encoded in encoded_h[w-1:0] are not in ascending order + sigdecode_h_error <= ~sigdecode_h_done & ((hintsum < hintsum_prev_poly) | OR_remaining_encoded_h_i | ~hint_ok | hintsum_max_error_i); + hint_rd_en_f <= hint_rd_en; + prev_hint_byte <= hint_rd_en_f ? hint[3] : 'h0; //Latch last hint in current cycle to be compared in next cycle + first_hint <= hint_rd_en_pulse; //Indicates when first hint is processed for a given poly + + //Check correctness of hint vector. If indices are not in ascending order, hint_ok is flipped triggering an error + hint_ok <= hint_rd_en_f ? ( curr_poly_map[0] ? (first_hint ? (prev_hint_byte <= hint[0]) : (prev_hint_byte < hint[0])) : 'b1) & //for first hint, prev byte = 0, hint[0] can also be 0 which is allowed + ((curr_poly_map[0] & curr_poly_map[1]) ? (hint[0] < hint[1]) : 'b1) & + ((curr_poly_map[1] & curr_poly_map[2]) ? (hint[1] < hint[2]) : 'b1) & + ((curr_poly_map[2] & curr_poly_map[3]) ? (hint[2] < hint[3]) : 'b1) + : 'b1; + end + end + + assign hint_rd_en_pulse = hint_rd_en & ~hint_rd_en_f; + + always_comb begin + OR_remaining_encoded_h_i = 0; + for(int i=0; i= encoded_h_i[(MLDSA_OMEGA+MLDSA_K)-1]) + OR_remaining_encoded_h_i = OR_remaining_encoded_h_i | (|encoded_h_i[i]); + else + OR_remaining_encoded_h_i=0; + end + end + + always_comb begin + hintsum_max_error_i = 0; + for(int i=0; i< MLDSA_K; i++) begin + if (encoded_h_i[MLDSA_OMEGA+i] > MLDSA_OMEGA) + hintsum_max_error_i = 1'b1; + end + end + + //bitmap construction + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) begin + bitmap <= 'h0; + end + else if (zeroize) begin + bitmap <= 'h0; + end + else if (rst_bitmap) begin + bitmap <= 'h0; + end + else begin + if (curr_poly_map[0]) + bitmap[hint[0]] <= 'b1; + if (curr_poly_map[1]) + bitmap[hint[1]] <= 'b1; + if (curr_poly_map[2]) + bitmap[hint[2]] <= 'b1; + if (curr_poly_map[3]) + bitmap[hint[3]] <= 'b1; + end + end + + always_comb hintsum_curr_poly = hintsum - hintsum_prev_poly; + + sigdecode_h_ctrl sdh_ctrl_inst ( + .clk(clk), + .reset_n(reset_n), + .zeroize(zeroize), + .sigdecode_h_enable(sigdecode_h_enable), + .dest_base_addr(dest_base_addr), + .hintsum_i(hintsum_curr_poly), + .sigdecode_h_error(sigdecode_h_error), + .mem_wr_req(mem_wr_req_int), + .sigdecode_h_done(sigdecode_h_done), + .poly_count(poly_count), + .rd_ptr(rd_ptr), + .rst_bitmap(rst_bitmap), + .curr_poly_map(curr_poly_map), + .bitmap_ptr(bitmap_ptr), + .hint_rd_en(hint_rd_en) + ); + +endmodule \ No newline at end of file diff --git a/designs/Caliptra/src/adams-bridge/sigdecode_h_ctrl.sv b/designs/Caliptra/src/adams-bridge/sigdecode_h_ctrl.sv new file mode 100644 index 0000000..b84025d --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/sigdecode_h_ctrl.sv @@ -0,0 +1,311 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +//====================================================================== +// +// sigdecode_h_ctrl.sv +// ----------- +// Manages memory writes and read pointer for encoded_h array. +// Keeps track of indices and polynomial count + +module sigdecode_h_ctrl + import abr_params_pkg::*; + import sigdecode_h_defines_pkg::*; + #( + parameter MLDSA_N = 256, + parameter MLDSA_K = 8 + ) + ( + input wire clk, + input wire reset_n, + input wire zeroize, + + input wire sigdecode_h_enable, + input wire [ABR_MEM_ADDR_WIDTH-1:0] dest_base_addr, + input wire [7:0] hintsum_i, //points to hintsum of i_th poly shown by poly_count + input wire sigdecode_h_error, + + output mem_if_t mem_wr_req, + output logic sigdecode_h_done, + output logic [3:0] poly_count, //can be used to pass in hintsum + output logic [6:0] rd_ptr, + output logic rst_bitmap, + output logic [3:0] curr_poly_map, + output logic [$clog2(MLDSA_N)-1:0] bitmap_ptr, + output logic hint_rd_en + ); + + logic [ABR_MEM_ADDR_WIDTH-1:0] mem_wr_addr, mem_wr_addr_nxt; + logic incr_wr_addr, rst_wr_addr; + logic last_poly_last_addr_wr, last_poly; + logic incr_poly; + mem_rw_mode_e rd_wr_en; + // logic [3:0] poly_count; + //poly_done_rd is asserted when all indices of curr poly are processed, i.e. rem_hintsum reaches 0 + //poly_done_wr is asserted when all 256 coeffs have been written for that poly to mem (equivalent to incr_poly if incr_poly is trigd by write fsm) + logic hint_rd_en_f; + logic poly_done_rd, poly_done_wr; + logic sigdecode_h_busy; + + //read pointer + logic incr_rd_ptr; + logic [7:0] rem_hintsum, hintsum_mux_sel; + logic [3:0] curr_poly_mux; + logic latch_hintsum, decr_rem_hintsum; + + sdh_read_state_e read_fsm_state_ps, read_fsm_state_ns; + sdh_write_state_e write_fsm_state_ps, write_fsm_state_ns; + + //Read fsm arcs + logic arc_SDH_RD_EXEC_SDH_RD_IDLE; + logic arc_SDH_RD_IDLE_SDH_RD_INIT; + logic arc_SDH_RD_INIT_SDH_RD_IDLE; + logic arc_SDH_RD_INIT_SDH_RD_HINTSUM; + logic arc_SDH_RD_EXEC_SDH_RD_INIT; + // logic arc_SDH_RD_INIT_SDH_RD_IDLE; + + //Write fsm arcs + logic arc_SDH_WR_IDLE_SDH_WR_INIT; + logic arc_SDH_WR_INIT_SDH_WR_MEM; + logic arc_SDH_WR_MEM_SDH_WR_INIT; + logic arc_SDH_WR_MEM_SDH_WR_IDLE; + logic arc_SDH_WR_INIT_SDH_WR_IDLE; + + //Write addr counter + always_comb mem_wr_addr_nxt = mem_wr_addr + 'h1; + + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) begin + mem_wr_addr <= 'h0; + end + else if (zeroize) begin + mem_wr_addr <= 'h0; + end + else if (rst_wr_addr) begin + mem_wr_addr <= dest_base_addr; + end + else if (incr_wr_addr) begin + mem_wr_addr <= last_poly_last_addr_wr ? 'h0 : mem_wr_addr_nxt; + end + end + + always_comb poly_done_wr = (mem_wr_addr[5:0] == ((MLDSA_N/4 - 1))); + + //Poly counter + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) begin + poly_count <= 'h0; + end + else if (zeroize) begin + poly_count <= 'h0; + end + else if (incr_poly) + poly_count <= (poly_count == MLDSA_K) ? 'h0 : poly_count + 'h1; + end + + //bitmap ptr counter + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) begin + bitmap_ptr <= 'h0; + end + else if (zeroize) begin + bitmap_ptr <= 'h0; + end + else if (incr_wr_addr) + bitmap_ptr <= poly_done_wr ? 'h0 : bitmap_ptr + 'h4; + end + + //Flags + always_comb begin + last_poly_last_addr_wr = (mem_wr_addr == dest_base_addr + (MLDSA_K * (MLDSA_N/4))-1); + last_poly = (poly_count == MLDSA_K-1); + sigdecode_h_busy = (write_fsm_state_ps != SDH_WR_IDLE); //writes follow reads, so using that for busy + sigdecode_h_done = (read_fsm_state_ps == SDH_RD_IDLE) & (write_fsm_state_ps == SDH_WR_IDLE); + end + + //Curr poly mux + //We read 1 dword (4 bytes) from reg API by default every cycle. If hintsum >= 4, all four we read belong to curr poly + //If hintsum < 4, only a few of the bytes belong to curr poly. This mux decodes that. + //rd_ptr always starts reading from a curr poly index, so valid hints start from lsb. Meaning, there is no chance + //that there is a hint in the lsb side that belongs to next poly and a hint that belongs to curr poly on the msb side + always_comb begin + hintsum_mux_sel = latch_hintsum ? hintsum_i : rem_hintsum; //in the first cycle, take hintsum //TODO: move to reg? + case(hintsum_mux_sel) + 'h0: curr_poly_mux = 'b0000; + 'h1: curr_poly_mux = 'b0001; + 'h2: curr_poly_mux = 'b0011; + 'h3: curr_poly_mux = 'b0111; + default: curr_poly_mux = 'b0000; + endcase + end + + //Hintsum logic + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) begin + rem_hintsum <= 'h0; + curr_poly_map <= 'h0; + end + else if (zeroize) begin + rem_hintsum <= 'h0; + curr_poly_map <= 'h0; + end + else if (latch_hintsum) begin + rem_hintsum <= hintsum_i; + curr_poly_map <= 'h0; + end + else if (poly_done_rd) begin + rem_hintsum <= 'h0; + curr_poly_map <= 'h0; + end + else if (decr_rem_hintsum) begin + rem_hintsum <= (rem_hintsum >= 'h4) ? rem_hintsum - 'h4 : 'h0; //If rem_hintsum < 4, it indicates last cycle of that poly, and we have read all locations of y for that poly, so reset to 0 + curr_poly_map <= (rem_hintsum >= 'h4) ? 'b1111 : curr_poly_mux; + end + end + + always_comb poly_done_rd = (read_fsm_state_ps == SDH_RD_EXEC) & (rem_hintsum == 'h0); + + //Rd ptr logic + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) begin + rd_ptr <= 'h0; + end + else if (zeroize) begin + rd_ptr <= 'h0; + end + else if (incr_rd_ptr) begin + rd_ptr <= (rem_hintsum >= 'h4) ? rd_ptr + 'h4 : 7'(rd_ptr + rem_hintsum); + end + end + + //----------------- + //Read fsm + //----------------- + always_comb begin + arc_SDH_RD_IDLE_SDH_RD_INIT = (read_fsm_state_ps == SDH_RD_IDLE) & sigdecode_h_enable; + arc_SDH_RD_INIT_SDH_RD_HINTSUM = (read_fsm_state_ps == SDH_RD_INIT) & (write_fsm_state_ps == SDH_WR_INIT); + arc_SDH_RD_INIT_SDH_RD_IDLE = (read_fsm_state_ps == SDH_RD_INIT) & sigdecode_h_error; + arc_SDH_RD_EXEC_SDH_RD_INIT = (read_fsm_state_ps == SDH_RD_EXEC) & ~last_poly & poly_done_rd; + arc_SDH_RD_EXEC_SDH_RD_IDLE = (read_fsm_state_ps == SDH_RD_EXEC) & ((last_poly & poly_done_rd) | sigdecode_h_error); + end + + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) + read_fsm_state_ps <= SDH_RD_IDLE; + else if (zeroize) + read_fsm_state_ps <= SDH_RD_IDLE; + else + read_fsm_state_ps <= read_fsm_state_ns; + end + + + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) + hint_rd_en_f <= '0; + else if (zeroize) + hint_rd_en_f <= '0; + else + hint_rd_en_f <= hint_rd_en; + end + + always_comb begin + incr_rd_ptr = 'b0; + read_fsm_state_ns = read_fsm_state_ps; + latch_hintsum = 'b0; + decr_rem_hintsum = 'b0; + hint_rd_en = 'b0; + + case(read_fsm_state_ps) + SDH_RD_IDLE: begin + read_fsm_state_ns = arc_SDH_RD_IDLE_SDH_RD_INIT ? SDH_RD_INIT : SDH_RD_IDLE; + end + SDH_RD_INIT: begin + read_fsm_state_ns = arc_SDH_RD_INIT_SDH_RD_IDLE ? SDH_RD_IDLE : + arc_SDH_RD_INIT_SDH_RD_HINTSUM ? SDH_RD_HINTSUM : SDH_RD_INIT; + end + SDH_RD_HINTSUM: begin + read_fsm_state_ns = SDH_RD_EXEC; + latch_hintsum = 'b1; + end + SDH_RD_EXEC: begin + read_fsm_state_ns = arc_SDH_RD_EXEC_SDH_RD_IDLE ? SDH_RD_IDLE : + arc_SDH_RD_EXEC_SDH_RD_INIT ? SDH_RD_INIT : + SDH_RD_EXEC; + incr_rd_ptr = (~poly_done_rd); + decr_rem_hintsum = 'b1; + hint_rd_en = ~arc_SDH_RD_EXEC_SDH_RD_INIT & ~arc_SDH_RD_EXEC_SDH_RD_IDLE; + end + endcase + end + + //----------------- + //Write fsm + //----------------- + always_comb begin + arc_SDH_WR_IDLE_SDH_WR_INIT = (write_fsm_state_ps == SDH_WR_IDLE) & sigdecode_h_enable; + arc_SDH_WR_INIT_SDH_WR_MEM = (write_fsm_state_ps == SDH_WR_INIT) & (hint_rd_en_f | poly_done_rd); //hint_rd_en indicates bitmap is going to be constructed, so we can move to WR MEM state + arc_SDH_WR_INIT_SDH_WR_IDLE = (write_fsm_state_ps == SDH_WR_INIT) & sigdecode_h_error; + arc_SDH_WR_MEM_SDH_WR_INIT = (write_fsm_state_ps == SDH_WR_MEM) & ~last_poly & poly_done_wr; + arc_SDH_WR_MEM_SDH_WR_IDLE = (write_fsm_state_ps == SDH_WR_MEM) & ((last_poly & poly_done_wr) | sigdecode_h_error); + end + + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) + write_fsm_state_ps <= SDH_WR_IDLE; + else if (zeroize) + write_fsm_state_ps <= SDH_WR_IDLE; + else + write_fsm_state_ps <= write_fsm_state_ns; + end + + always_comb begin + incr_wr_addr = 'b0; + rst_wr_addr = 'b0; + incr_poly = 'b0; + rst_bitmap = 'b0; + rd_wr_en = RW_IDLE; + write_fsm_state_ns = write_fsm_state_ps; + + case(write_fsm_state_ps) + SDH_WR_IDLE: begin + write_fsm_state_ns = arc_SDH_WR_IDLE_SDH_WR_INIT ? SDH_WR_INIT : SDH_WR_IDLE; + rst_wr_addr = 'b1; + end + SDH_WR_INIT: begin + write_fsm_state_ns = arc_SDH_WR_INIT_SDH_WR_IDLE ? SDH_WR_IDLE : + arc_SDH_WR_INIT_SDH_WR_MEM ? SDH_WR_MEM : + SDH_WR_INIT; + end + SDH_WR_MEM: begin + write_fsm_state_ns = arc_SDH_WR_MEM_SDH_WR_IDLE ? SDH_WR_IDLE : + arc_SDH_WR_MEM_SDH_WR_INIT ? SDH_WR_INIT : + SDH_WR_MEM; + incr_wr_addr = 'b1; + incr_poly = poly_done_wr; + rd_wr_en = RW_WRITE; + rst_bitmap = arc_SDH_WR_MEM_SDH_WR_INIT | arc_SDH_WR_MEM_SDH_WR_IDLE; + end + default: begin + + end + endcase + end + + //Assign outputs + always_comb begin + mem_wr_req.addr = mem_wr_addr; + mem_wr_req.rd_wr_en = rd_wr_en; + end + + +endmodule diff --git a/designs/Caliptra/src/adams-bridge/sigdecode_h_defines_pkg.sv b/designs/Caliptra/src/adams-bridge/sigdecode_h_defines_pkg.sv new file mode 100644 index 0000000..73bb6d8 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/sigdecode_h_defines_pkg.sv @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +//====================================================================== +// +// sigdecode_h_defines_pkg.sv +// -------- +// sigdecode_h parameters for Mldsa +//====================================================================== + +`ifndef MLDSA_SIGDECODE_H_DEFINES +`define MLDSA_SIGDECODE_H_DEFINES + +package sigdecode_h_defines_pkg; + + typedef enum logic [1:0] {SDH_RD_IDLE, SDH_RD_HINTSUM, SDH_RD_INIT, SDH_RD_EXEC} sdh_read_state_e; + typedef enum logic [1:0] {SDH_WR_IDLE, SDH_WR_INIT, SDH_WR_MEM} sdh_write_state_e; + +endpackage + +`endif \ No newline at end of file diff --git a/designs/Caliptra/src/adams-bridge/sigdecode_z_defines_pkg.sv b/designs/Caliptra/src/adams-bridge/sigdecode_z_defines_pkg.sv new file mode 100644 index 0000000..6b31579 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/sigdecode_z_defines_pkg.sv @@ -0,0 +1,37 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +//====================================================================== +// +// sigdecode_z_defines_pkg.sv +// -------- +// Sigdecode parameters for Mldsa +//====================================================================== + +`ifndef MLDSA_SIGDECODE_Z_DEFINES +`define MLDSA_SIGDECODE_Z_DEFINES + +package sigdecode_z_defines_pkg; + import abr_params_pkg::*; + + parameter API_ADDR_WIDTH = ABR_MEM_ADDR_WIDTH; + parameter MLDSA_L = 7; + + typedef struct packed { + mem_rw_mode_e rd_wr_en; + logic [API_ADDR_WIDTH-1:0] addr; + } sig_mem_if_t; + +endpackage + +`endif \ No newline at end of file diff --git a/designs/Caliptra/src/adams-bridge/sigdecode_z_top.sv b/designs/Caliptra/src/adams-bridge/sigdecode_z_top.sv new file mode 100644 index 0000000..7549330 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/sigdecode_z_top.sv @@ -0,0 +1,237 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +//====================================================================== +// +// sigdecode_z_top.sv +// -------- +// @brief Top-level module for the signature decoder for z in the Mldsa scheme. +// +// This module implements the top-level logic for encoding z polynomial (a part of signature) in the +// Mldsa post-quantum cryptographic scheme. The decoder reads encoded byte string from API register, +// processes them through decoding units, and writes the decoded values to a specified +// memory locations starting from the dest address. +// The module interfaces with memory through two parallel read ports and writes the +// decoded data to a destination address in the memory. +// +//====================================================================== + +module sigdecode_z_top + import abr_params_pkg::*; + import sigdecode_z_defines_pkg::*; + #( + parameter MEM_ADDR_WIDTH = ABR_MEM_ADDR_WIDTH, + parameter REG_SIZE = 24, + parameter GAMMA1 = 19 + ) + ( + input wire clk, + input wire reset_n, + input wire zeroize, + + // Output memory ports + input wire [MEM_ADDR_WIDTH-1:0] dest_base_addr, + output mem_if_t mem_a_wr_req, + output mem_if_t mem_b_wr_req, + output logic [3:0][REG_SIZE-1:0] mem_a_wr_data, + output logic [3:0][REG_SIZE-1:0] mem_b_wr_data, + + // Input API ports + output sig_mem_if_t sigmem_a_rd_req, + output sig_mem_if_t sigmem_b_rd_req, + input wire [3:0][GAMMA1:0] sigmem_a_rd_data, + input wire [3:0][GAMMA1:0] sigmem_b_rd_data, + + //Control and status signals + input wire sigdecode_z_enable, + output logic sigdecode_z_done + ); + + localparam THE_LAST_ADDR = ((MLDSA_L * MLDSA_N)/4)-1; + // State Machine States + localparam IDLE = 3'b000, + READ = 3'b001, + READ_and_EXEC = 3'b010, + READ_EXEC_and_WRITE = 3'b011, + EXEC_and_WRITE = 3'b100, + WRITE = 3'b101, + DONE = 3'b110; + + + logic [31:0] num_mem_operands, num_api_operands; // encoded each four coeff will increment these by one + logic [MEM_ADDR_WIDTH-1:0] locked_dest_addr; // this ensures that addresses are captured when the block is enabled + logic [2:0] state, next_state; + + + // State Machine + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) begin + state <= IDLE; + end + else if (zeroize) begin + state <= IDLE; + end + else begin + state <= next_state; + end + end + + always_comb begin + case (state) + IDLE: begin + if (sigdecode_z_enable) + next_state = READ; + else + next_state = IDLE; + end + READ: begin + next_state = READ_and_EXEC; + end + READ_and_EXEC: begin + next_state = READ_EXEC_and_WRITE; + end + READ_EXEC_and_WRITE: begin + if ((num_api_operands+1) == THE_LAST_ADDR) begin + next_state = EXEC_and_WRITE; + end + else begin + next_state = READ_EXEC_and_WRITE; + end + end + EXEC_and_WRITE: begin + next_state = WRITE; + end + WRITE: begin + next_state = DONE; + end + DONE: begin + next_state = IDLE; + end + default: begin + next_state = IDLE; + end + endcase + end + + // Lock the src and dest addresses and initialize the counter + // Assert the done signal when it is needed + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) begin + num_mem_operands <= 'h0; + num_api_operands <= 'h0; + locked_dest_addr <= 'h0; + sigdecode_z_done <= 'h0; + end + else if (zeroize) begin + num_mem_operands <= 'h0; + num_api_operands <= 'h0; + locked_dest_addr <= 'h0; + sigdecode_z_done <= 'h0; + end + else begin + if (sigdecode_z_enable) begin + locked_dest_addr <= dest_base_addr; + end + + + if (state == READ || state == READ_and_EXEC || state == READ_EXEC_and_WRITE) begin + num_api_operands <= num_api_operands +2'h2; + end + else begin + num_api_operands <= 'h0; + end + if (state == READ_EXEC_and_WRITE || state == EXEC_and_WRITE || state == WRITE) begin + num_mem_operands <= num_mem_operands +2'h2; + end + else begin + num_mem_operands <= 'h0; + end + if (state == DONE) begin + sigdecode_z_done <= 'h1; + end + else begin + sigdecode_z_done <= 'h0; + end + end + end + + // Write request generation + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) begin + mem_a_wr_req <= '{rd_wr_en: RW_IDLE, addr: '0}; + mem_b_wr_req <= '{rd_wr_en: RW_IDLE, addr: '0}; + end + else if (zeroize) begin + mem_a_wr_req <= '{rd_wr_en: RW_IDLE, addr: '0}; + mem_b_wr_req <= '{rd_wr_en: RW_IDLE, addr: '0}; + end + else if (state == READ_EXEC_and_WRITE || state == EXEC_and_WRITE || state == WRITE) begin + mem_a_wr_req <= '{rd_wr_en: RW_WRITE, addr: locked_dest_addr + num_mem_operands}; + mem_b_wr_req <= '{rd_wr_en: RW_WRITE, addr: locked_dest_addr + num_mem_operands + 1}; + end + else begin + mem_a_wr_req <= '{rd_wr_en: RW_IDLE, addr: '0}; + mem_b_wr_req <= '{rd_wr_en: RW_IDLE, addr: '0}; + end + end + + // Memory read request generation + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) begin + sigmem_a_rd_req <= '{rd_wr_en: RW_IDLE, addr: '0}; + sigmem_b_rd_req <= '{rd_wr_en: RW_IDLE, addr: '0}; + end + else if (zeroize) begin + sigmem_a_rd_req <= '{rd_wr_en: RW_IDLE, addr: '0}; + sigmem_b_rd_req <= '{rd_wr_en: RW_IDLE, addr: '0}; + end + else if (state == READ || state == READ_and_EXEC || state == READ_EXEC_and_WRITE) begin + sigmem_a_rd_req <= '{rd_wr_en: RW_READ, addr: num_api_operands}; + sigmem_b_rd_req <= '{rd_wr_en: RW_READ, addr: num_api_operands + 1}; + end else begin + sigmem_a_rd_req <= '{rd_wr_en: RW_IDLE, addr: '0}; + sigmem_b_rd_req <= '{rd_wr_en: RW_IDLE, addr: '0}; + end + end + + //8 decoding instances + generate + for (genvar i = 0; i < 4; i++) begin : dec_unit + sigdecode_z_unit #( + .REG_SIZE(REG_SIZE), + .GAMMA1(GAMMA1) + ) + upper_encode ( + .clk(clk), + .reset_n(reset_n), + .zeroize(zeroize), + .data_i(sigmem_a_rd_data[i]), + .data_o(mem_a_wr_data[i]) + ); + sigdecode_z_unit #( + .REG_SIZE(REG_SIZE), + .GAMMA1(GAMMA1) + ) + lower_encode ( + .clk(clk), + .reset_n(reset_n), + .zeroize(zeroize), + .data_i(sigmem_b_rd_data[i]), + .data_o(mem_b_wr_data[i]) + ); + end : dec_unit + endgenerate + + + +endmodule \ No newline at end of file diff --git a/designs/Caliptra/src/adams-bridge/sigdecode_z_unit.sv b/designs/Caliptra/src/adams-bridge/sigdecode_z_unit.sv new file mode 100644 index 0000000..4387434 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/sigdecode_z_unit.sv @@ -0,0 +1,104 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +//====================================================================== +// +// sigdecode_z_unit.sv +// ---------------------------- +// Decodes a part of signature z from a byte string to a polynomials by calculating the following equation: +// γ1 – (z mod q) = γ1 – (q + z) = γ1 – z – q where q is modulo prime and γ1 is constnat +// parameter range. + +module sigdecode_z_unit +#( + parameter REG_SIZE = 23, + parameter MLDSA_Q = 8380417, + parameter GAMMA1 = 19 +) +( + input wire clk, + input wire reset_n, + input wire zeroize, + + input wire [GAMMA1:0] data_i, + output logic [REG_SIZE-1:0] data_o //TODO: clean up. At top level, data_o is 24-bits, so add 1 more bit here and assign 0 +); + + localparam MLDSA_GAMMA1_RANGE = 2**GAMMA1; + + logic [REG_SIZE-1:0] opa0; + logic [REG_SIZE-1:0] opb0; + logic [REG_SIZE-1:0] r0; + logic [REG_SIZE-1:0] opb1; + logic [REG_SIZE-1:0] r1; + logic [REG_SIZE-1:0] r0_reg; + + logic carry0; + logic carry1; + logic carry0_reg; + logic sub_n; + logic sub_i; + + assign sub_i = 1'b1; + assign opa0 = MLDSA_GAMMA1_RANGE; + assign opb0 = sub_i ? REG_SIZE'(~data_i) : REG_SIZE'(data_i); + + abr_adder #( + .RADIX(REG_SIZE) + ) + adder_inst_0( + .a_i(opa0), + .b_i(opb0), + .cin_i(sub_i), + .s_o(r0), + .cout_o(carry0) + ); + + abr_adder #( + .RADIX(REG_SIZE) + ) + adder_inst_1( + .a_i(r0_reg), + .b_i(opb1), + .cin_i(sub_n), + .s_o(r1), + .cout_o(carry1) + ); + + always_ff @(posedge clk or negedge reset_n) + begin + if(!reset_n) begin + r0_reg <= '0; + carry0_reg <= '0; + opb1 <= '0; + sub_n <= '0; + end + else if (zeroize) begin + r0_reg <= '0; + carry0_reg <= '0; + opb1 <= '0; + sub_n <= '0; + end + else begin + r0_reg <= r0; + carry0_reg <= carry0; + opb1 <= sub_i ? {1'b0, 23'(MLDSA_Q)} : {1'b1, 23'(~MLDSA_Q)}; + sub_n <= !sub_i; + end + end + + + assign data_o = sub_n ? (carry0_reg ^ carry1) ? {1'b0, r1} : {1'b0, r0_reg} + : (carry0_reg) ? r0_reg : r1; + +endmodule \ No newline at end of file diff --git a/designs/Caliptra/src/adams-bridge/sigencode_z_defines_pkg.sv b/designs/Caliptra/src/adams-bridge/sigencode_z_defines_pkg.sv new file mode 100644 index 0000000..0efc41a --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/sigencode_z_defines_pkg.sv @@ -0,0 +1,37 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +//====================================================================== +// +// sigencode_z_defines_pkg.sv +// -------- +// sigencode_z parameters for Mldsa +//====================================================================== + +`ifndef MLDSA_SIGENCODE_Z_DEFINES +`define MLDSA_SIGENCODE_Z_DEFINES + +package sigencode_z_defines_pkg; + import abr_params_pkg::*; + + parameter API_ADDR_WIDTH = ABR_MEM_ADDR_WIDTH; + parameter MLDSA_L = 7; + + typedef struct packed { + mem_rw_mode_e rd_wr_en; + logic [API_ADDR_WIDTH-1:0] addr; + } sig_mem_if_t; + +endpackage + +`endif \ No newline at end of file diff --git a/designs/Caliptra/src/adams-bridge/sigencode_z_top.sv b/designs/Caliptra/src/adams-bridge/sigencode_z_top.sv new file mode 100644 index 0000000..7af5f17 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/sigencode_z_top.sv @@ -0,0 +1,241 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +//====================================================================== +// +// sigencode_z_top.sv +// -------- +// @brief Top-level module for the signature encoder in the Mldsa scheme. +// +// This module implements the top-level logic for encoding z polynomial (a part of signature) in the +// Mldsa post-quantum cryptographic scheme. The encoder reads coefficients from memory, +// processes them through encoding units, and writes the encoded values to a specified +// register map. +// The module interfaces with memory through two parallel read ports and writes the +// encoded data to a destination address in the register map. +// +//====================================================================== + +module sigencode_z_top + import abr_params_pkg::*; + import sigencode_z_defines_pkg::*; + #( + parameter MEM_ADDR_WIDTH = ABR_MEM_ADDR_WIDTH, + parameter REG_SIZE = 24, + parameter GAMMA1 = 19 + ) + ( + input wire clk, + input wire reset_n, + input wire zeroize, + + // Input memory ports + input wire [MEM_ADDR_WIDTH-1:0] src_base_addr, + output mem_if_t mem_a_rd_req, + output mem_if_t mem_b_rd_req, + input wire [3:0][REG_SIZE-1:0] mem_a_rd_data, + input wire [3:0][REG_SIZE-1:0] mem_b_rd_data, + + // Output API ports + input wire [MEM_ADDR_WIDTH-1:0] sigmem_dest_base_addr, + output sig_mem_if_t sigmem_a_wr_req, + output sig_mem_if_t sigmem_b_wr_req, + output logic [3:0][GAMMA1:0] sigmem_a_wr_data, + output logic [3:0][GAMMA1:0] sigmem_b_wr_data, + + //Control and status signals + input wire sigencode_z_enable, + output logic sigencode_z_done + ); + + localparam THE_LAST_ADDR = ((MLDSA_N)/4)-1; + // State Machine States + localparam IDLE = 3'b000, + READ = 3'b001, + READ_and_EXEC = 3'b010, + READ_EXEC_and_WRITE = 3'b011, + EXEC_and_WRITE = 3'b100, + WRITE = 3'b101, + DONE = 3'b110; + + + logic [31:0] num_mem_operands, num_api_operands; // encoded each four coeff will increment these by one + logic [MEM_ADDR_WIDTH-1:0] locked_dest_addr, locked_src_addr; // this ensures that addresses are captured when the block is enabled + logic [2:0] state, next_state; + + + // State Machine + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) begin + state <= IDLE; + end + else if (zeroize) begin + state <= IDLE; + end + else begin + state <= next_state; + end + end + + always_comb begin + case (state) + IDLE: begin + if (sigencode_z_enable) + next_state = READ; + else + next_state = IDLE; + end + READ: begin + next_state = READ_and_EXEC; + end + READ_and_EXEC: begin + next_state = READ_EXEC_and_WRITE; + end + READ_EXEC_and_WRITE: begin + if ((num_mem_operands+1) == THE_LAST_ADDR) begin + next_state = EXEC_and_WRITE; + end + else begin + next_state = READ_EXEC_and_WRITE; + end + end + EXEC_and_WRITE: begin + next_state = WRITE; + end + WRITE: begin + next_state = DONE; + end + DONE: begin + next_state = IDLE; + end + default: begin + next_state = IDLE; + end + endcase + end + + // Lock the src and dest addresses and initialize the counter + // Assert the done signal when it is needed + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) begin + num_mem_operands <= 'h0; + num_api_operands <= 'h0; + locked_dest_addr <= 'h0; + locked_src_addr <= 'h0; + sigencode_z_done <= 'h0; + end + else if (zeroize) begin + num_mem_operands <= 'h0; + num_api_operands <= 'h0; + locked_dest_addr <= 'h0; + locked_src_addr <= 'h0; + sigencode_z_done <= 'h0; + end + else begin + if (sigencode_z_enable) begin + locked_dest_addr <= sigmem_dest_base_addr; + locked_src_addr <= src_base_addr; + end + + + if (state == READ || state == READ_and_EXEC || state == READ_EXEC_and_WRITE) begin + num_mem_operands <= num_mem_operands +2'h2; + end + else begin + num_mem_operands <= 'h0; + end + if (state == READ_EXEC_and_WRITE || state == EXEC_and_WRITE || state == WRITE) begin + num_api_operands <= num_api_operands +2'h2; + end + else begin + num_api_operands <= 'h0; + end + if (state == DONE) begin + sigencode_z_done <= 'h1; + end + else begin + sigencode_z_done <= 'h0; + end + end + end + + // Write request generation + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) begin + sigmem_a_wr_req <= '{rd_wr_en: RW_IDLE, addr: '0}; + sigmem_b_wr_req <= '{rd_wr_en: RW_IDLE, addr: '0}; + end + else if (zeroize) begin + sigmem_a_wr_req <= '{rd_wr_en: RW_IDLE, addr: '0}; + sigmem_b_wr_req <= '{rd_wr_en: RW_IDLE, addr: '0}; + end + else if (state == READ_EXEC_and_WRITE || state == EXEC_and_WRITE || state == WRITE) begin + sigmem_a_wr_req <= '{rd_wr_en: RW_WRITE, addr: locked_dest_addr + num_api_operands}; + sigmem_b_wr_req <= '{rd_wr_en: RW_WRITE, addr: locked_dest_addr + num_api_operands + 1}; + end + else begin + sigmem_a_wr_req <= '{rd_wr_en: RW_IDLE, addr: '0}; + sigmem_b_wr_req <= '{rd_wr_en: RW_IDLE, addr: '0}; + end + end + + // Memory read request generation + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) begin + mem_a_rd_req <= '{rd_wr_en: RW_IDLE, addr: '0}; + mem_b_rd_req <= '{rd_wr_en: RW_IDLE, addr: '0}; + end + else if (zeroize) begin + mem_a_rd_req <= '{rd_wr_en: RW_IDLE, addr: '0}; + mem_b_rd_req <= '{rd_wr_en: RW_IDLE, addr: '0}; + end + else if (state == READ || state == READ_and_EXEC || state == READ_EXEC_and_WRITE) begin + mem_a_rd_req <= '{rd_wr_en: RW_READ, addr: locked_src_addr + num_mem_operands}; + mem_b_rd_req <= '{rd_wr_en: RW_READ, addr: locked_src_addr + num_mem_operands + 1}; + end else begin + mem_a_rd_req <= '{rd_wr_en: RW_IDLE, addr: '0}; + mem_b_rd_req <= '{rd_wr_en: RW_IDLE, addr: '0}; + end + end + + //8 encoding instances + generate + for (genvar i = 0; i < 4; i++) begin : enc_unit + sigencode_z_unit #( + .REG_SIZE(REG_SIZE), + .GAMMA1(GAMMA1) + ) + upper_encode ( + .clk(clk), + .reset_n(reset_n), + .zeroize(zeroize), + .data_i(mem_a_rd_data[i]), + .data_o(sigmem_a_wr_data[i]) + ); + sigencode_z_unit #( + .REG_SIZE(REG_SIZE), + .GAMMA1(GAMMA1) + ) + lower_encode ( + .clk(clk), + .reset_n(reset_n), + .zeroize(zeroize), + .data_i(mem_b_rd_data[i]), + .data_o(sigmem_b_wr_data[i]) + ); + end : enc_unit + endgenerate + + + +endmodule \ No newline at end of file diff --git a/designs/Caliptra/src/adams-bridge/sigencode_z_unit.sv b/designs/Caliptra/src/adams-bridge/sigencode_z_unit.sv new file mode 100644 index 0000000..45d866d --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/sigencode_z_unit.sv @@ -0,0 +1,106 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +//====================================================================== +// +// sigencode_z_unit.sv +// ---------------------------- +// Encodes a part of signature z into a byte string by calculating the following equation: +// γ1 – (z mod q) = γ1 – (q + z) = γ1 – z – q where q is modulo prime and γ1 is constnat +// parameter range. + +module sigencode_z_unit + #( + parameter REG_SIZE = 23, + parameter MLDSA_Q = 8380417, + parameter GAMMA1 = 19 + ) + ( + input wire clk, + input wire reset_n, + input wire zeroize, + + input wire [REG_SIZE-1:0] data_i, + output logic [GAMMA1:0] data_o //TODO: clean up. At top level, data_o is 24-bits, so add 1 more bit here and assign 0 + ); + + localparam MLDSA_GAMMA1_RANGE = 2**GAMMA1; + + logic [REG_SIZE-1:0] opa0; + logic [REG_SIZE-1:0] opb0; + logic [REG_SIZE-1:0] r0; + logic [REG_SIZE-1:0] opb1; + logic [REG_SIZE-1:0] r1; + logic [REG_SIZE-1:0] r0_reg; + logic [REG_SIZE-1:0] raw_result; + + logic carry0; + logic carry1; + logic carry0_reg; + logic sub_n; + logic sub_i; + + assign sub_i = 1'b1; + assign opa0 = MLDSA_GAMMA1_RANGE; + assign opb0 = sub_i ? ~data_i : data_i; + + abr_adder #( + .RADIX(REG_SIZE) + ) + adder_inst_0( + .a_i(opa0), + .b_i(opb0), + .cin_i(sub_i), + .s_o(r0), + .cout_o(carry0) + ); + + abr_adder #( + .RADIX(REG_SIZE) + ) + adder_inst_1( + .a_i(r0_reg), + .b_i(opb1), + .cin_i(sub_n), + .s_o(r1), + .cout_o(carry1) + ); + + always_ff @(posedge clk or negedge reset_n) + begin + if(!reset_n) begin + r0_reg <= '0; + carry0_reg <= '0; + opb1 <= '0; + sub_n <= '0; + end + else if (zeroize) begin + r0_reg <= '0; + carry0_reg <= '0; + opb1 <= '0; + sub_n <= '0; + end + else begin + r0_reg <= r0; + carry0_reg <= carry0; + opb1 <= sub_i ? {1'b0, 23'(MLDSA_Q)} : {1'b1, 23'(~MLDSA_Q)}; + sub_n <= !sub_i; + end + end + + + assign raw_result = sub_n ? (carry0_reg ^ carry1) ? {1'b0, r1} : {1'b0, r0_reg} + : (carry0_reg) ? r0_reg : r1; + assign data_o = raw_result[GAMMA1:0]; + +endmodule \ No newline at end of file diff --git a/designs/Caliptra/src/adams-bridge/skdecode_ctrl.sv b/designs/Caliptra/src/adams-bridge/skdecode_ctrl.sv new file mode 100644 index 0000000..55efb14 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/skdecode_ctrl.sv @@ -0,0 +1,395 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +//====================================================================== +// +// skdecode_ctrl.sv +// --------------------- +// Enables unpack modules and keeps track of memory writes + +module skdecode_ctrl + import abr_params_pkg::*; + import skdecode_defines_pkg::*; + #( + parameter MLDSA_L = 7, + parameter MLDSA_K = 8, + parameter MLDSA_N = 256 + ) + ( + input wire clk, + input wire reset_n, + input wire zeroize, + + input wire skdecode_enable, //One enable for all of s0, s1, t0 unpack + input wire [ABR_MEM_ADDR_WIDTH-1:0] src_base_addr, + input wire [ABR_MEM_ADDR_WIDTH-1:0] dest_base_addr, + input wire s1s2_valid, + input wire t0_valid, + input wire s1s2_error, + input wire t0_buf_stall, + + output mem_if_t mem_a_wr_req, + output mem_if_t mem_b_wr_req, + output mem_if_t kmem_a_rd_req, + output mem_if_t kmem_b_rd_req, + output logic s1s2_enable, + output logic t0_enable, + output logic skdecode_done, + output logic s1_done, + output logic s2_done, + output logic t0_done, + output logic s1s2_buf_stall + ); + + //Memory interface wires + logic [ABR_MEM_ADDR_WIDTH-1:0] mem_wr_addr, mem_wr_addr_nxt, mem_offset; + logic [ABR_MEM_ADDR_WIDTH-1:0] kmem_rd_addr, kmem_rd_addr_nxt; + + logic incr_wr_addr, incr_skdec_count; + logic rst_wr_addr, rst_skdec_count; + logic incr_rd_addr, rst_rd_addr; + logic last_poly_last_addr; + logic skdecode_busy; + logic [3:0] num_poly, num_inst; + mem_rw_mode_e mem_rw_mode, kmem_a_rw_mode; + mem_rw_mode_e kmem_b_rw_mode; + logic [8:0] skdecode_count; + logic [3:0] poly_count; + logic s1s2_enable_fsm, t0_enable_fsm; + logic [2:0] stall_count; + logic incr_stall_count; + logic rst_stall_count; + logic mem_rd_stall_local, s1s2_buf_stall_fsm; + logic s1_mode, s2_mode, t0_mode; + + skdec_read_state_e read_fsm_state_ps, read_fsm_state_ns; + skdec_write_state_e write_fsm_state_ps, write_fsm_state_ns; + + //Write FSM arcs + logic arc_SKDEC_WR_IDLE_SKDEC_WR_S1; + logic arc_SKDEC_WR_S1_SKDEC_WR_STAGE; + logic arc_SKDEC_WR_S2_SKDEC_WR_STAGE; + logic arc_SKDEC_WR_T0_SKDEC_WR_STAGE; + logic arc_SKDEC_WR_STAGE_SKDEC_WR_S2; + logic arc_SKDEC_WR_STAGE_SKDEC_WR_T0; + logic arc_SKDEC_WR_STAGE_SKDEC_WR_IDLE; + + //Read FSM arcs + logic arc_SKDEC_RD_IDLE_SKDEC_RD_S1; + logic arc_SKDEC_RD_S1_SKDEC_RD_STAGE; + logic arc_SKDEC_RD_S2_SKDEC_RD_STAGE; + logic arc_SKDEC_RD_T0_SKDEC_RD_STAGE; + logic arc_SKDEC_RD_STAGE_SKDEC_RD_S2; + logic arc_SKDEC_RD_STAGE_SKDEC_RD_T0; + logic arc_SKDEC_RD_STAGE_SKDEC_RD_IDLE; + + //skdecode counter + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) + skdecode_count <= 'h0; + else if (zeroize) + skdecode_count <= 'h0; + else if (s1s2_error) + skdecode_count <= 'h0; + else if (rst_skdec_count) + skdecode_count <= 'h0; + else if (incr_skdec_count) begin + skdecode_count <= (skdecode_count == ((num_poly * MLDSA_N)/num_inst)-1) ? 'h0 : skdecode_count + 'h1; + end + end + + //Write addr counter + always_comb mem_wr_addr_nxt = mem_wr_addr + 'h1; + + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) + mem_wr_addr <= 'h0; + else if (zeroize) + mem_wr_addr <= 'h0; + else if (skdecode_enable) + mem_wr_addr <= dest_base_addr; + else if (arc_SKDEC_WR_STAGE_SKDEC_WR_T0) + mem_wr_addr <= mem_a_wr_req.addr; //Latch the last addr written, so we can continue from there for T0 poly //TODO revisit + else if (incr_wr_addr) + mem_wr_addr <= mem_wr_addr_nxt; + end + + //Read addr counter + always_comb kmem_rd_addr_nxt = t0_enable_fsm ? kmem_rd_addr + 'h2 : kmem_rd_addr + 'h1; + + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) + kmem_rd_addr <= 'h0; + else if (zeroize) + kmem_rd_addr <= 'h0; + else if (skdecode_enable) + kmem_rd_addr <= src_base_addr; + else if (incr_rd_addr) + kmem_rd_addr <= kmem_rd_addr_nxt; + end + + //Stall counter - needed only for s1s2 unpacking. For t0, sample buffer generates full that is used as stall condition + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) + stall_count <= 'h0; + else if (zeroize) + stall_count <= 'h0; + else if (rst_stall_count) + stall_count <= 'h0; + else if (incr_stall_count) begin + stall_count <= (stall_count == 'h3) ? 'h0 : stall_count + 'h1; + end + end + + always_comb s1s2_buf_stall_fsm = (s1s2_enable_fsm) & (stall_count == 'h3); + + //Flags + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) begin + s1_mode <= 'b0; + s2_mode <= 'b0; + t0_mode <= 'b0; + end + else if (zeroize) begin + s1_mode <= 'b0; + s2_mode <= 'b0; + t0_mode <= 'b0; + end + else begin + if (arc_SKDEC_WR_IDLE_SKDEC_WR_S1) s1_mode <= 'b1; + else if (arc_SKDEC_WR_STAGE_SKDEC_WR_S2) s1_mode <= 'b0; + + if (arc_SKDEC_WR_STAGE_SKDEC_WR_S2) s2_mode <= 'b1; + else if (arc_SKDEC_WR_STAGE_SKDEC_WR_T0) s2_mode <= 'b0; + + if (arc_SKDEC_WR_STAGE_SKDEC_WR_T0) t0_mode <= 'b1; + else if (arc_SKDEC_WR_STAGE_SKDEC_WR_IDLE) t0_mode <= 'b0; + end + end + + always_comb begin + //write fsm lags behind read fsm, so calculate flags using write states + skdecode_busy = (write_fsm_state_ps != SKDEC_WR_IDLE); + skdecode_done = (write_fsm_state_ps == SKDEC_WR_IDLE); + //last addr flag only used in read + last_poly_last_addr = (skdecode_count == (((num_poly * MLDSA_N)/num_inst)-1)); + end + + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) begin + s1_done <= 'b0; + s2_done <= 'b0; + t0_done <= 'b0; + end + else if (zeroize) begin + s1_done <= 'b0; + s2_done <= 'b0; + t0_done <= 'b0; + end + else begin + if (arc_SKDEC_WR_S1_SKDEC_WR_STAGE) + s1_done <= 'b1; + if (arc_SKDEC_WR_S2_SKDEC_WR_STAGE) + s2_done <= 'b1; + if (arc_SKDEC_WR_T0_SKDEC_WR_STAGE) + t0_done <= 'b1; + end + end + + //--------------------------------- + //Read fsm + //--------------------------------- + always_comb begin + arc_SKDEC_RD_IDLE_SKDEC_RD_S1 = (read_fsm_state_ps == SKDEC_RD_IDLE) & skdecode_enable; + arc_SKDEC_RD_S1_SKDEC_RD_STAGE = (read_fsm_state_ps == SKDEC_RD_S1) & last_poly_last_addr; + arc_SKDEC_RD_S2_SKDEC_RD_STAGE = (read_fsm_state_ps == SKDEC_RD_S2) & last_poly_last_addr; + arc_SKDEC_RD_T0_SKDEC_RD_STAGE = (read_fsm_state_ps == SKDEC_RD_T0) & last_poly_last_addr; + + arc_SKDEC_RD_STAGE_SKDEC_RD_S2 = (write_fsm_state_ps == SKDEC_WR_STAGE) & s1_done & ~s2_done & ~t0_done; + arc_SKDEC_RD_STAGE_SKDEC_RD_T0 = (write_fsm_state_ps == SKDEC_WR_STAGE) & s1_done & s2_done & ~t0_done; + arc_SKDEC_RD_STAGE_SKDEC_RD_IDLE = (write_fsm_state_ps == SKDEC_WR_STAGE) & s1_done & s2_done & t0_done; + + //TODO error conditions + end + + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) + read_fsm_state_ps <= SKDEC_RD_IDLE; + else if (zeroize) + read_fsm_state_ps <= SKDEC_RD_IDLE; + else + read_fsm_state_ps <= read_fsm_state_ns; + end + + always_comb begin + read_fsm_state_ns = read_fsm_state_ps; + incr_rd_addr = 'b0; + rst_rd_addr = 'b0; + kmem_a_rw_mode = RW_IDLE; + kmem_b_rw_mode = RW_IDLE; + incr_stall_count = 'b0; + rst_stall_count = 'b0; + incr_skdec_count = 'b0; + rst_skdec_count = 'b0; + s1s2_enable_fsm = 'b0; + t0_enable_fsm = 'b0; + num_poly = 'h0; + num_inst = 'h0; + + unique case(read_fsm_state_ps) + SKDEC_RD_IDLE: begin + read_fsm_state_ns = arc_SKDEC_RD_IDLE_SKDEC_RD_S1 ? SKDEC_RD_S1 : SKDEC_RD_IDLE; + rst_rd_addr = 'b1; + rst_stall_count = 'b1; + rst_skdec_count = 'b1; + end + SKDEC_RD_S1: begin + read_fsm_state_ns = arc_SKDEC_RD_S1_SKDEC_RD_STAGE ? SKDEC_RD_STAGE : SKDEC_RD_S1; + incr_stall_count = 'b1; + incr_rd_addr = ~s1s2_buf_stall_fsm; + kmem_a_rw_mode = ~s1s2_buf_stall_fsm & ~kmem_rd_addr[0] ? RW_READ : RW_IDLE; + kmem_b_rw_mode = ~s1s2_buf_stall_fsm & kmem_rd_addr[0] ? RW_READ : RW_IDLE; + incr_skdec_count = 'b1; + s1s2_enable_fsm = 'b1; + num_poly = MLDSA_L; + num_inst = 'd8; + end + SKDEC_RD_S2: begin + read_fsm_state_ns = arc_SKDEC_RD_S2_SKDEC_RD_STAGE ? SKDEC_RD_STAGE : SKDEC_RD_S2; + incr_stall_count = 'b1; + incr_rd_addr = ~s1s2_buf_stall_fsm; + kmem_a_rw_mode = ~s1s2_buf_stall_fsm & ~kmem_rd_addr[0] ? RW_READ : RW_IDLE; + kmem_b_rw_mode = ~s1s2_buf_stall_fsm & kmem_rd_addr[0] ? RW_READ : RW_IDLE; + incr_skdec_count = 'b1; + s1s2_enable_fsm = 'b1; + num_poly = MLDSA_K; + num_inst = 'd8; + end + SKDEC_RD_T0: begin + read_fsm_state_ns = arc_SKDEC_RD_T0_SKDEC_RD_STAGE ? SKDEC_RD_STAGE : SKDEC_RD_T0; + incr_stall_count = 'b1; + incr_rd_addr = ~t0_buf_stall; + kmem_a_rw_mode = ~t0_buf_stall ? RW_READ : RW_IDLE; + kmem_b_rw_mode = ~t0_buf_stall ? RW_READ : RW_IDLE; + incr_skdec_count = 'b1; + t0_enable_fsm = 'b1; + num_poly = MLDSA_K; + num_inst = 'd4; + end + SKDEC_RD_STAGE: begin + read_fsm_state_ns = arc_SKDEC_RD_STAGE_SKDEC_RD_S2 ? SKDEC_RD_S2 : + arc_SKDEC_RD_STAGE_SKDEC_RD_T0 ? SKDEC_RD_T0 : + arc_SKDEC_RD_STAGE_SKDEC_RD_IDLE ? SKDEC_RD_IDLE : SKDEC_RD_STAGE; + end + default: begin + read_fsm_state_ns = SKDEC_RD_IDLE; + end + endcase + end + + //--------------------------------- + //Write fsm + //--------------------------------- + always_comb begin + //TODO add error conditions + arc_SKDEC_WR_IDLE_SKDEC_WR_S1 = (write_fsm_state_ps == SKDEC_WR_IDLE) & skdecode_enable; + arc_SKDEC_WR_S1_SKDEC_WR_STAGE = (write_fsm_state_ps == SKDEC_WR_S1) & (read_fsm_state_ps == SKDEC_RD_STAGE) & !s1s2_valid; + arc_SKDEC_WR_S2_SKDEC_WR_STAGE = (write_fsm_state_ps == SKDEC_WR_S2) & (read_fsm_state_ps == SKDEC_RD_STAGE) & !s1s2_valid; + arc_SKDEC_WR_T0_SKDEC_WR_STAGE = (write_fsm_state_ps == SKDEC_WR_T0) & (read_fsm_state_ps == SKDEC_RD_STAGE) & !t0_valid; + arc_SKDEC_WR_STAGE_SKDEC_WR_S2 = (write_fsm_state_ps == SKDEC_WR_STAGE) & s1_done & ~s2_done & ~t0_done; + arc_SKDEC_WR_STAGE_SKDEC_WR_T0 = (write_fsm_state_ps == SKDEC_WR_STAGE) & s1_done & s2_done & ~t0_done; + arc_SKDEC_WR_STAGE_SKDEC_WR_IDLE = (write_fsm_state_ps == SKDEC_WR_STAGE) & s1_done & s2_done & t0_done; + end + + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) + write_fsm_state_ps <= SKDEC_WR_IDLE; + else if (zeroize) + write_fsm_state_ps <= SKDEC_WR_IDLE; + else + write_fsm_state_ps <= write_fsm_state_ns; + end + + always_comb begin + write_fsm_state_ns = write_fsm_state_ps; + incr_wr_addr = 'b0; + rst_wr_addr = 'b0; + mem_rw_mode = RW_IDLE; + + unique case(write_fsm_state_ps) + SKDEC_WR_IDLE: begin + write_fsm_state_ns = arc_SKDEC_WR_IDLE_SKDEC_WR_S1 ? SKDEC_WR_S1 : SKDEC_WR_IDLE; + rst_wr_addr = 'b1; + end + SKDEC_WR_S1: begin + write_fsm_state_ns = arc_SKDEC_WR_S1_SKDEC_WR_STAGE ? SKDEC_WR_STAGE : SKDEC_WR_S1; + incr_wr_addr = s1s2_valid; + mem_rw_mode = s1s2_valid ? RW_WRITE : RW_IDLE; + end + SKDEC_WR_S2: begin + write_fsm_state_ns = arc_SKDEC_WR_S2_SKDEC_WR_STAGE ? SKDEC_WR_STAGE : SKDEC_WR_S2; + incr_wr_addr = s1s2_valid; + mem_rw_mode = s1s2_valid ? RW_WRITE : RW_IDLE; + end + SKDEC_WR_T0: begin + write_fsm_state_ns = arc_SKDEC_WR_T0_SKDEC_WR_STAGE ? SKDEC_WR_STAGE : SKDEC_WR_T0; + incr_wr_addr = t0_valid; + mem_rw_mode = t0_valid ? RW_WRITE : RW_IDLE; + end + SKDEC_WR_STAGE: begin + write_fsm_state_ns = arc_SKDEC_WR_STAGE_SKDEC_WR_S2 ? SKDEC_WR_S2 : + arc_SKDEC_WR_STAGE_SKDEC_WR_T0 ? SKDEC_WR_T0 : + arc_SKDEC_WR_STAGE_SKDEC_WR_IDLE ? SKDEC_WR_IDLE : SKDEC_WR_STAGE; + end + default: begin + write_fsm_state_ns = SKDEC_WR_IDLE; + end + endcase + end + + //Outputs + always_comb begin + mem_a_wr_req.addr = t0_mode ? mem_wr_addr : (s1_mode | s2_mode) ? (mem_wr_addr << 1) : 'h0; + mem_a_wr_req.rd_wr_en = t0_mode & mem_a_wr_req.addr[0] ? RW_IDLE : mem_rw_mode; + + mem_b_wr_req.addr = t0_mode ? mem_wr_addr : (s1_mode | s2_mode) ? (mem_wr_addr << 1) + 'h1 : 'h0; + mem_b_wr_req.rd_wr_en = t0_mode & ~mem_a_wr_req.addr[0]? RW_IDLE : mem_rw_mode; + + kmem_a_rd_req.addr = t0_enable_fsm ? kmem_rd_addr : kmem_rd_addr; + kmem_a_rd_req.rd_wr_en = t0_enable_fsm ? kmem_a_rw_mode : kmem_a_rw_mode; + + kmem_b_rd_req.addr = t0_enable_fsm ? kmem_rd_addr + 'h1 : kmem_rd_addr; + kmem_b_rd_req.rd_wr_en = t0_enable_fsm ? kmem_b_rw_mode : kmem_b_rw_mode; + + end + + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) begin + s1s2_enable <= 'b0; + t0_enable <= 'b0; + s1s2_buf_stall <= 'b0; + end + else if (zeroize) begin + s1s2_enable <= 'b0; + t0_enable <= 'b0; + s1s2_buf_stall <= 'b0; + end + else begin + s1s2_enable <= s1s2_enable_fsm; + t0_enable <= t0_enable_fsm; + s1s2_buf_stall <= s1s2_buf_stall_fsm; + end + + end + +endmodule diff --git a/designs/Caliptra/src/adams-bridge/skdecode_defines_pkg.sv b/designs/Caliptra/src/adams-bridge/skdecode_defines_pkg.sv new file mode 100644 index 0000000..90a412a --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/skdecode_defines_pkg.sv @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +//====================================================================== +// +// skdecode_defines_pkg.sv +// -------- +// Skdecode parameters for Mldsa +//====================================================================== + +`ifndef ABR_SKDECODE_DEFINES +`define ABR_SKDECODE_DEFINES + +package skdecode_defines_pkg; + + typedef enum logic [2:0] {SKDEC_RD_IDLE, SKDEC_RD_STAGE, SKDEC_RD_S1, SKDEC_RD_S2, SKDEC_RD_T0} skdec_read_state_e; + typedef enum logic [2:0] {SKDEC_WR_IDLE, SKDEC_WR_STAGE, SKDEC_WR_S1, SKDEC_WR_S2, SKDEC_WR_T0} skdec_write_state_e; + +endpackage + +`endif diff --git a/designs/Caliptra/src/adams-bridge/skdecode_s1s2_unpack.sv b/designs/Caliptra/src/adams-bridge/skdecode_s1s2_unpack.sv new file mode 100644 index 0000000..8c68968 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/skdecode_s1s2_unpack.sv @@ -0,0 +1,71 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +//====================================================================== +// +// skdecode_s1s2_unpack.sv +// -------- +// This mux unpacks s1 and s2 polynomials from sk input. 3-bit input values +// are converted into 24-bit output values which are the final coefficients of +// s1 and s2 poly to be stored in memory + +// coeff = eta - sk_data[eta_size-1:0] +// where eta_size = bitlen(2*eta), eta = 2 and sk_data is part of the incoming sk + +// Input data must be in the range of -2 to 2 (mapped to 0 to 4 in positive range) +// Any value outside of this range is invalid and will trigger an error interrupt to FW and stops the process + +module skdecode_s1s2_unpack + #( + parameter REG_SIZE = 24, + parameter MLDSA_ETA = 2, + parameter ETA_SIZE = 3, //$clog2(2*MLDSA_ETA), + parameter MLDSA_Q = 8380417 + ) + ( + input wire [ETA_SIZE-1:0] data_i, + input wire enable, + output logic [REG_SIZE-1:0] data_o, + output logic valid_o, + output logic error_o + ); + + logic [REG_SIZE-1:0] eta_minus_data; + + always_comb begin + data_o = '0; + valid_o = '0; + error_o = '0; + eta_minus_data = '0; + + if (enable) begin + error_o = 'b0; + eta_minus_data = REG_SIZE'(MLDSA_ETA - data_i); + + unique case(data_i) + 3'h0: data_o = 'h2; + 3'h1: data_o = 'h1; + 3'h2: data_o = 'h0; + 3'h3: data_o = MLDSA_Q-1; + 3'h4: data_o = MLDSA_Q-2; + default: begin + data_o = 'h0; + error_o = 'b1; + end + endcase + + valid_o = 'b1; + end + end + +endmodule \ No newline at end of file diff --git a/designs/Caliptra/src/adams-bridge/skdecode_t0_unpack.sv b/designs/Caliptra/src/adams-bridge/skdecode_t0_unpack.sv new file mode 100644 index 0000000..97e00b4 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/skdecode_t0_unpack.sv @@ -0,0 +1,112 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +//====================================================================== +// +// skdecode_t0_unpack.sv +// ---------------------------- +// Unpacks t0 from sk by calculating the following equation: +// coeff = (2**(d-1)) - data[d-1:0] where d is a Mldsa param = 13 +// The result of this modular subtraction is a 24-bit value (2**12-a mod q) +// that is stored in memory as coefficients for further processing + +module skdecode_t0_unpack + #( + parameter REG_SIZE = 23, + parameter MLDSA_Q = 8380417, + parameter MLDSA_D = 13 + ) + ( + input wire clk, + input wire reset_n, + input wire zeroize, + + input wire enable, + input wire sub_i, + input wire [MLDSA_D-1:0] data_i, + output logic [REG_SIZE:0] data_o, //TODO: clean up. At top level, data_o is 24-bits, so add 1 more bit here and assign 0 + output logic valid_o + ); + + logic [REG_SIZE-1:0] opa0; + logic [REG_SIZE-1:0] opb0; + logic [REG_SIZE-1:0] r0; + logic [REG_SIZE-1:0] opb1; + logic [REG_SIZE-1:0] r1; + logic [REG_SIZE-1:0] r0_reg; + + logic carry0; + logic carry1; + logic carry0_reg; + logic sub_n; + + assign opa0 = (1 << (MLDSA_D-1)); + assign opb0 = sub_i ? REG_SIZE'(~data_i) : REG_SIZE'(data_i); + + abr_adder #( + .RADIX(REG_SIZE) + ) + adder_inst_0( + .a_i(opa0), + .b_i(opb0), + .cin_i(sub_i), + .s_o(r0), + .cout_o(carry0) + ); + + abr_adder #( + .RADIX(REG_SIZE) + ) + adder_inst_1( + .a_i(r0_reg), + .b_i(opb1), + .cin_i(sub_n), + .s_o(r1), + .cout_o(carry1) + ); + + always_ff @(posedge clk or negedge reset_n) + begin + if(!reset_n) begin + r0_reg <= '0; + carry0_reg <= '0; + opb1 <= '0; + sub_n <= '0; + end + else if (zeroize) begin + r0_reg <= '0; + carry0_reg <= '0; + opb1 <= '0; + sub_n <= '0; + end + else if (enable) begin + r0_reg <= r0; + carry0_reg <= carry0; + opb1 <= sub_i ? MLDSA_Q : ~MLDSA_Q; + sub_n <= !sub_i; + end + end + + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) + valid_o <= 'b0; + else if (zeroize) + valid_o <= 'b0; + else + valid_o <= enable; + end + + assign data_o = sub_n ? (carry0_reg ^ carry1) ? (REG_SIZE+1)'(r1) : (REG_SIZE+1)'(r0_reg) + : (carry0_reg) ? (REG_SIZE+1)'(r0_reg) : (REG_SIZE+1)'(r1); + +endmodule \ No newline at end of file diff --git a/designs/Caliptra/src/adams-bridge/skdecode_top.sv b/designs/Caliptra/src/adams-bridge/skdecode_top.sv new file mode 100644 index 0000000..e6a473d --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/skdecode_top.sv @@ -0,0 +1,277 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +//====================================================================== +// +// skdecode_top.sv +// -------- +// 1. Decodes sk input from reg API into s1, s2 and t0 polynomials. +// 2. Output coeffs are all in 24-bit format. 4 coeffs are written to memory per addr. +// 3. Dual writes take place per cycle, hence 8 values are processed per cycle fpr s1s2 unpack +// 4. One enable pulse from HLC will trigger all 3 polynomial decoding and control +// is transferred back to HLC only after the last poly has been written to memory +// 5. Any invalid input in sk will trigger an error within skdecode and operation +// is stopped. An error interrupt must be set (TODO: by HLC?) to notify RV core +// TODO: sk reg to skdecode interface. For now, assuming a mux. Can be shift reg? +// 6. Note, this module interfaces with a key memory to retrieve sk input. Since the memory +// interface is 32-bit data port, 8 s1s2 modules can be run in parallel to process 24-bits of data per cycle +// and 4 t0 unpack modules can be run in parallel to process 52-bits of data per cycle. t0 operation +// requires 2 memory reads per cycle and s1s2 requires 1 memory read +//====================================================================== + +module skdecode_top + import abr_params_pkg::*; + import skdecode_defines_pkg::*; + #( + parameter MLDSA_ETA = 2, + parameter MLDSA_D = 13, + parameter ETA_SIZE = 3, + parameter REG_SIZE = 24, + parameter AHB_DATA_WIDTH = 32 + ) + ( + input wire clk, + input wire reset_n, + input wire zeroize, + + input wire skdecode_enable, + input wire [ABR_MEM_ADDR_WIDTH-1:0] keymem_src_base_addr, + input wire [ABR_MEM_ADDR_WIDTH-1:0] dest_base_addr, + input wire [AHB_DATA_WIDTH-1:0] keymem_a_rd_data, + input wire [AHB_DATA_WIDTH-1:0] keymem_b_rd_data, + + output mem_if_t keymem_a_rd_req, + output mem_if_t keymem_b_rd_req, + output mem_if_t mem_a_wr_req, + output mem_if_t mem_b_wr_req, + output logic [3:0][REG_SIZE-1:0] mem_a_wr_data, + output logic [3:0][REG_SIZE-1:0] mem_b_wr_data, + output logic skdecode_error, + output logic skdecode_done, + output logic s1_done, + output logic s2_done, + output logic t0_done + ); + + logic s1s2_enable, t0_enable, s1s2_enable_reg, t0_enable_reg; + logic s1s2_enable_reg_d2, t0_enable_reg_d2; + logic [7:0] s1s2_valid; + logic [3:0] t0_valid; + logic [7:0] s1s2_error; + logic [7:0][REG_SIZE-1:0] s1s2_data; + logic [3:0][REG_SIZE-1:0] t0_data; + logic t0_done_reg; + + //IO flops + mem_if_t mem_a_wr_req_int, mem_b_wr_req_int, mem_a_wr_req_reg, mem_b_wr_req_reg; + logic [7:0][ETA_SIZE-1:0] s1s2_buf_data; + logic [3:0][MLDSA_D-1:0] t0_buf_data; + logic [3:0][REG_SIZE-1:0] mem_a_wr_data_int, mem_b_wr_data_int, mem_a_wr_data_reg, mem_b_wr_data_reg; + logic [AHB_DATA_WIDTH-1:0] keymem_a_rd_data_reg, keymem_b_rd_data_reg; + + logic s1s2_buf_stall, t0_buf_stall; + logic t0_data_valid; + logic s1s2_data_valid; + logic t0_buf_full; + logic s1s2_buf_stall_reg; + logic s1s2_buf_full; + + logic s1s2_keymem_b_valid; + + //Read address counters + logic [ABR_MEM_ADDR_WIDTH-1:0] keymem_rd_addr, keymem_rd_addr_nxt; + + + //IO flops + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) begin + s1s2_enable_reg <= 'h0; + t0_enable_reg <= 'h0; + s1s2_enable_reg_d2 <= 'h0; + t0_enable_reg_d2 <= 'h0; + mem_a_wr_req_reg.rd_wr_en <= RW_IDLE; + mem_b_wr_req_reg.rd_wr_en <= RW_IDLE; + mem_a_wr_req_reg.addr <= 'h0; + mem_b_wr_req_reg.addr <= 'h0; + mem_a_wr_data_reg <= 'h0; + mem_b_wr_data_reg <= 'h0; + t0_done_reg <= 'b0; + s1s2_keymem_b_valid <= 'b0; + end + else if (zeroize) begin + s1s2_enable_reg <= 'h0; + t0_enable_reg <= 'h0; + s1s2_enable_reg_d2 <= 'h0; + t0_enable_reg_d2 <= 'h0; + mem_a_wr_req_reg.rd_wr_en <= RW_IDLE; + mem_b_wr_req_reg.rd_wr_en <= RW_IDLE; + mem_a_wr_req_reg.addr <= 'h0; + mem_b_wr_req_reg.addr <= 'h0; + mem_a_wr_data_reg <= 'h0; + mem_b_wr_data_reg <= 'h0; + t0_done_reg <= 'b0; + s1s2_keymem_b_valid <= 'b0; + end + else begin + s1s2_enable_reg <= s1s2_enable; + t0_enable_reg <= t0_enable; + s1s2_enable_reg_d2 <= s1s2_enable_reg; + t0_enable_reg_d2 <= t0_enable_reg; + mem_a_wr_req_reg <= mem_a_wr_req_int; + mem_b_wr_req_reg <= mem_b_wr_req_int; + mem_a_wr_data_reg <= mem_a_wr_data_int; + mem_b_wr_data_reg <= mem_b_wr_data_int; + t0_done_reg <= t0_done; + s1s2_keymem_b_valid <= s1s2_enable & (keymem_b_rd_req.rd_wr_en == RW_READ); + end + end + + //Data flop with enable to sync with buf full + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) begin + keymem_a_rd_data_reg <= 'h0; + keymem_b_rd_data_reg <= 'h0; + end + else if (zeroize) begin + keymem_a_rd_data_reg <= 'h0; + keymem_b_rd_data_reg <= 'h0; + end + else if (~t0_buf_full & ~s1s2_buf_full) begin + keymem_a_rd_data_reg <= s1s2_keymem_b_valid ? keymem_b_rd_data: keymem_a_rd_data; + keymem_b_rd_data_reg <= keymem_b_rd_data; + + end + end + + //Flags + always_comb begin + mem_a_wr_data_int = |s1s2_valid ? s1s2_data[3:0] : |t0_valid ? t0_data[3:0] : 'h0; + mem_b_wr_data_int = |s1s2_valid ? s1s2_data[7:4] : |t0_valid ? t0_data[3:0] : 'h0; + skdecode_error = |s1s2_error; + end + + //Assign outputs + always_comb begin + mem_a_wr_req = mem_a_wr_req_reg; + mem_b_wr_req = mem_b_wr_req_reg; + mem_a_wr_data = mem_a_wr_data_reg; + mem_b_wr_data = mem_b_wr_data_reg; + end + + //8 s1s2 unpack instances to process 3*8 = 24-bits per cycle. In this case, one addr of key mem is read per cycle + generate + for (genvar i = 0; i < 8; i++) begin : gen_s1s2_unpack + skdecode_s1s2_unpack #( + .REG_SIZE(REG_SIZE) + ) + s1s2_unpack_inst ( + .data_i(s1s2_buf_data[i]), + .enable(s1s2_data_valid), //from buffer + .data_o(s1s2_data[i]), + .valid_o(s1s2_valid[i]), + .error_o(s1s2_error[i]) + ); + end + endgenerate + + //4 t0 unpack instances to process 13*4 = 52-bits per cycle. This makes it simpler to interface with key mem that can provide + //atmost 64-bits per cycle. Remaining bits are accumulated in buffer. in this case, 2 addr of key mem are read per cycle + generate + for (genvar i = 0; i < 4; i++) begin : gen_t0_unpack + skdecode_t0_unpack #( + .REG_SIZE(REG_SIZE-1) + ) + t0_unpack_inst ( + .clk(clk), + .reset_n(reset_n), + .zeroize(zeroize), + .enable(t0_data_valid), //from buffer + .sub_i('1), + .data_i(t0_buf_data[i]), + .data_o(t0_data[i]), + .valid_o(t0_valid[i]) + ); + end + endgenerate + + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) + s1s2_buf_stall_reg <= 'b0; + else if (zeroize) + s1s2_buf_stall_reg <= 'b0; + else + s1s2_buf_stall_reg <= s1s2_buf_stall; + end + + always_comb begin + t0_buf_stall = t0_buf_full; //(t0_buf_full & t0_enable_reg); + end + + abr_sample_buffer #( + .NUM_WR(16), + .NUM_RD(13), + .BUFFER_DATA_W(4) + ) + t0_sample_buffer_inst ( + .clk(clk), + .rst_b(reset_n), + .zeroize(zeroize), + .data_valid_i((t0_buf_full | ~t0_enable) ? 16'h0 : {16{t0_enable_reg}}), + .data_i({keymem_b_rd_data_reg, keymem_a_rd_data_reg}), + .buffer_full_o(t0_buf_full), + .data_valid_o(t0_data_valid), + .data_o(t0_buf_data) + ); + + abr_sample_buffer #( + .NUM_WR(4), + .NUM_RD(3), + .BUFFER_DATA_W(8) + ) + s1s2_sample_buffer_inst ( + .clk(clk), + .rst_b(reset_n), + .zeroize(zeroize), + .data_valid_i(s1s2_buf_stall_reg/*(s1s2_buf_full | ~s1s2_enable)*/ ? 4'h0 : {4{s1s2_enable_reg}}), + .data_i(keymem_a_rd_data_reg), + .buffer_full_o(s1s2_buf_full), + .data_valid_o(s1s2_data_valid), + .data_o(s1s2_buf_data) + ); + + skdecode_ctrl + skdecode_ctrl_inst ( + .clk(clk), + .reset_n(reset_n), + .zeroize(zeroize), + .skdecode_enable(skdecode_enable), + .src_base_addr(keymem_src_base_addr), + .dest_base_addr(dest_base_addr), + .s1s2_valid(|s1s2_valid), + .t0_valid(|t0_valid), + .s1s2_error(|s1s2_error), //TODO: enable later when tb is fixed to drive input values within range + .t0_buf_stall(t0_buf_stall), //input from buffer to ctrl + .mem_a_wr_req(mem_a_wr_req_int), + .mem_b_wr_req(mem_b_wr_req_int), + .kmem_a_rd_req(keymem_a_rd_req), + .kmem_b_rd_req(keymem_b_rd_req), + .s1s2_enable(s1s2_enable), + .t0_enable(t0_enable), + .skdecode_done(skdecode_done), + .s1_done(s1_done), + .s2_done(s2_done), + .t0_done(t0_done), + .s1s2_buf_stall(s1s2_buf_stall)//(s1s2_buf_full) + ); + +endmodule \ No newline at end of file diff --git a/designs/Caliptra/src/adams-bridge/skencode.sv b/designs/Caliptra/src/adams-bridge/skencode.sv new file mode 100644 index 0000000..0f3f983 --- /dev/null +++ b/designs/Caliptra/src/adams-bridge/skencode.sv @@ -0,0 +1,393 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +//====================================================================== +// +// skencode.sv +// -------- +// The skencode module performs the encoding of secret key components into a packed format. +// This module supports the MLDSA scheme, encoding sk inputs into s1, s2 polynomials. +// The output coefficients are packed into 24-bit format. +// The design supports dual memory writes per cycle, processing 8 values per cycle for s1 and s2 encoding. +// The module operates under the control of a single enable pulse, triggering the encoding process for all polynomials. +// Upon completion, control is transferred back to the host. If any invalid input is detected, the module raises +// an error flag, halting the operation. Error handling and notifications are left to the host's implementation. +// 8 instances of the s1s2 encoder can operate simultaneously, each handling 24 bits of data per cycle. +// +//====================================================================== + +module skencode + import abr_params_pkg::*; + import skdecode_defines_pkg::*; + #( + parameter MEM_ADDR_WIDTH = 15, + parameter MLDSA_Q = 23'd8380417, + parameter MLDSA_L = 'h7, + parameter MLDSA_K = 'h8, + parameter MLDSA_N = 'd256, + parameter REG_SIZE = 24, + parameter AHB_DATA_WIDTH = 32 + ) + ( + input wire clk, + input wire reset_n, + input wire zeroize, + + input wire skencode_enable, + input wire [MEM_ADDR_WIDTH-1:0] dest_base_addr, + input wire [MEM_ADDR_WIDTH-1:0] src_base_addr, + input wire [3:0][REG_SIZE-1:0] mem_a_rd_data, + input wire [3:0][REG_SIZE-1:0] mem_b_rd_data, + + output mem_if_t keymem_a_wr_req, + output mem_if_t mem_a_rd_req, + output mem_if_t mem_b_rd_req, + output logic [AHB_DATA_WIDTH-1:0] keymem_a_wr_data, + + output logic skencode_done + ); + + localparam THE_LAST_ADDR = ((MLDSA_K * MLDSA_N)/4)+((MLDSA_L * MLDSA_N)/4)-1; + localparam THE_LAST_API = ((MLDSA_K +MLDSA_L)*MLDSA_N*3)/32; + + // Main State Machine States + // TODO: Define the state names in a pakcage. + localparam IDLE = 3'b000, + READ = 3'b001, + READ_and_ENC = 3'b010, + READ_ENC_and_CONSUME = 3'b011, + ENC_and_CONSUME = 3'b100, + CONSUME = 3'b101, + CONSUME_LAST = 3'b110, + DONE = 3'b111; + + // Main State Machine States + localparam WAIT_BUFFER = 3'b001, + WRITE = 3'b010, + STALL = 3'b011, + GET_LAST = 3'b100; + + + logic [2:0] main_state, next_main_state, write_state, next_write_state; + logic error_flag; + logic [7:0][2:0] encoded_coeffs; + logic [7:0] encoding_error; + logic [23:0] one_encoding_string; + logic [95:0] buffer; + logic [1:0] producer_selector, consumer_selector; + logic write_buffer; + logic [31:0] num_mem_operands, num_api_operands; // encoded each four coeff will increment these by one + logic [MEM_ADDR_WIDTH-1:0] locked_dest_addr, locked_src_addr; // this ensures that addresses are captured when the block is enabled + + assign one_encoding_string = {encoded_coeffs[7],encoded_coeffs[6],encoded_coeffs[5],encoded_coeffs[4], + encoded_coeffs[3],encoded_coeffs[2],encoded_coeffs[1],encoded_coeffs[0]}; + + + // State Machine: Updates main_state and write_state based on current conditions and next states. + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) begin + main_state <= IDLE; + write_state <= IDLE; + end + else if (zeroize) begin + main_state <= IDLE; + write_state <= IDLE; + end + else begin + if (error_flag) begin + main_state <= IDLE; + write_state <= IDLE; + end + else begin + main_state <= next_main_state; + write_state <= next_write_state; + end + end + end + + // Determines next state for main_state based on current main_state and conditions. + always_comb begin + case (main_state) + IDLE: begin + if (skencode_enable) + next_main_state = READ; + else + next_main_state = IDLE; + end + READ: begin + next_main_state = READ_and_ENC; + end + READ_and_ENC: begin + next_main_state = READ_ENC_and_CONSUME; + end + READ_ENC_and_CONSUME: begin + if ((num_mem_operands+1) == THE_LAST_ADDR) begin + next_main_state = ENC_and_CONSUME; + end + else begin + next_main_state = READ_ENC_and_CONSUME; + end + end + ENC_and_CONSUME: begin + next_main_state = CONSUME; + end + CONSUME: begin + next_main_state = CONSUME_LAST; + end + CONSUME_LAST: begin + next_main_state = DONE; + end + DONE: begin + next_main_state = IDLE; + end + default: begin + next_main_state = IDLE; + end + endcase + end + + // Determines next state for write_state based on current write_state and conditions. + always_comb begin + case (write_state) + IDLE: begin + if (main_state == READ_ENC_and_CONSUME) + next_write_state = WAIT_BUFFER; + else + next_write_state = IDLE; + end + WAIT_BUFFER: begin + if (producer_selector == 'h1) + next_write_state = WRITE; + else + next_write_state = WAIT_BUFFER; + end + WRITE: begin + if (consumer_selector == 'h1) + next_write_state = STALL; + else + next_write_state = WRITE; + end + STALL: begin + if (num_api_operands == THE_LAST_API) begin + next_write_state = GET_LAST; + end + else begin + next_write_state = WAIT_BUFFER; + end + end + GET_LAST: begin + next_write_state = DONE; + end + DONE: begin + next_write_state = IDLE; + end + default: begin + next_write_state = IDLE; + end + endcase + end + + // Write request generation + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) begin + keymem_a_wr_req <= '{rd_wr_en: RW_IDLE, addr: '0}; + num_api_operands <= 'h0; + consumer_selector <= 'h0; + end + else if (zeroize) begin + keymem_a_wr_req <= '{rd_wr_en: RW_IDLE, addr: '0}; + num_api_operands <= 'h0; + consumer_selector <= 'h0; + end + else begin + if (write_state == WRITE) + consumer_selector <= consumer_selector + 'h1; + else + consumer_selector <= 'h0; + + if (write_state == IDLE ) begin + num_api_operands <= 'h0; + end + else if (write_state == WRITE || (write_state == WAIT_BUFFER && producer_selector == 'h1)) begin + num_api_operands <= num_api_operands +'h1; + end + + if (write_state == WRITE || (write_state == WAIT_BUFFER && producer_selector == 'h1)) begin + keymem_a_wr_req <= '{rd_wr_en: RW_WRITE, addr: locked_dest_addr + num_api_operands}; + end + else begin + keymem_a_wr_req <= '{rd_wr_en: RW_IDLE, addr: '0}; + end + end + end + + // Controls and updates the state of various internal signals and registers based on the state machine and input signals. + // Resets or initializes all signals execpt for the write operation related logics. + // Locks destination and source addresses when skencode_enable is active. + // Manages write_buffer and producer_selector based on the main state machine. + // Issues read requests to memory and increments num_mem_operands during appropriate states. + // Signals completion (skencode_done) based on operation progress. + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) begin + write_buffer <= 'h0; + producer_selector <= 'h0; + num_mem_operands <= 'h0; + locked_dest_addr <= 'h0; + locked_src_addr <= 'h0; + skencode_done <= 'h0; + mem_a_rd_req <= '{rd_wr_en: RW_IDLE, addr: '0}; + mem_b_rd_req <= '{rd_wr_en: RW_IDLE, addr: '0}; + end + else if (zeroize) begin + write_buffer <= 'h0; + producer_selector <= 'h0; + num_mem_operands <= 'h0; + locked_dest_addr <= 'h0; + locked_src_addr <= 'h0; + skencode_done <= 'h0; + mem_a_rd_req <= '{rd_wr_en: RW_IDLE, addr: '0}; + mem_b_rd_req <= '{rd_wr_en: RW_IDLE, addr: '0}; + end + else begin + if (skencode_enable) begin + locked_dest_addr <= dest_base_addr; + locked_src_addr <= src_base_addr; + end + + if (main_state == READ_and_ENC || main_state == READ_ENC_and_CONSUME || main_state == ENC_and_CONSUME) begin + write_buffer <= 'h1; + end + else begin + write_buffer <= 'h0; + end + + if (main_state == READ_ENC_and_CONSUME || main_state == ENC_and_CONSUME) + producer_selector <= producer_selector + 1'b1; + else + producer_selector <= 'h0; + + if (main_state == READ || main_state == READ_and_ENC || main_state == READ_ENC_and_CONSUME) begin + mem_a_rd_req <= '{rd_wr_en: RW_READ, addr: locked_src_addr + num_mem_operands}; + mem_b_rd_req <= '{rd_wr_en: RW_READ, addr: locked_src_addr + num_mem_operands + 1}; + num_mem_operands <= num_mem_operands +2'h2; + end + else begin + mem_a_rd_req <= '{rd_wr_en: RW_IDLE, addr: '0}; + mem_b_rd_req <= '{rd_wr_en: RW_IDLE, addr: '0}; + num_mem_operands <= 'h0; + end + + if (main_state == DONE) begin + skencode_done <= 'h1; + end + else begin + skencode_done <= 'h0; + end + end + end + + // Manages the 96-bit buffer register based on the write_buffer signal and producer_selector state. + // Accumulates 24-bit encoded strings into the 96-bit buffer, preparing data for further processing or output. + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) begin + buffer <= 'h0; + end + else if (zeroize) begin + buffer <= 'h0; + end + else begin + if (write_buffer) begin + if (producer_selector == 2'h0) + buffer[23:0] <= one_encoding_string; + else if (producer_selector == 2'h1) + buffer[47:24] <= one_encoding_string; + else if (producer_selector == 2'h2) + buffer[71:48] <= one_encoding_string; + else + buffer[95:72] <= one_encoding_string; + end + end + end + + // Assigns the appropriate 32-bit portion of the buffer to keymem_a_wr_data based on consumer_selector. + always_comb begin : API_org + case(consumer_selector) + 2'h0: keymem_a_wr_data = buffer[31:0]; + 2'h1: keymem_a_wr_data = buffer[63:32]; + 2'h2: keymem_a_wr_data = buffer[95:64]; + 2'h3: keymem_a_wr_data = 'h0; // Ignored case + endcase + end : API_org + + always_comb begin : encoding + for (int i = 0; i < 4; i++) begin + unique case(mem_a_rd_data[i]) + 'h0: begin + encoded_coeffs[i] = 'h2; + encoding_error[i] = 'h0; + end + 'h1: begin + encoded_coeffs[i] = 'h1; + encoding_error[i] = 'h0; + end + 'h2: begin + encoded_coeffs[i] = 'h0; + encoding_error[i] = 'h0; + end + MLDSA_Q-1: begin + encoded_coeffs[i] = 'h3; + encoding_error[i] = 'h0; + end + MLDSA_Q-2: begin + encoded_coeffs[i] = 'h4; + encoding_error[i] = 'h0; + end + default: begin + encoded_coeffs[i] = 'h0; + encoding_error[i] = 'h1; + end + endcase + unique case(mem_b_rd_data[i]) + 'h0: begin + encoded_coeffs[i+4] = 'h2; + encoding_error[i+4] = 'h0; + end + 'h1: begin + encoded_coeffs[i+4] = 'h1; + encoding_error[i+4] = 'h0; + end + 'h2: begin + encoded_coeffs[i+4] = 'h0; + encoding_error[i+4] = 'h0; + end + MLDSA_Q-1: begin + encoded_coeffs[i+4] = 'h3; + encoding_error[i+4] = 'h0; + end + MLDSA_Q-2: begin + encoded_coeffs[i+4] = 'h4; + encoding_error[i+4] = 'h0; + end + default: begin + encoded_coeffs[i+4] = 'h0; + encoding_error[i+4] = 'h1; + end + endcase + end + end : encoding + + assign error_flag = (|encoding_error) & main_state inside {READ_ENC_and_CONSUME, ENC_and_CONSUME, CONSUME, CONSUME_LAST}; + + `ABR_ASSERT_NEVER(SKENCODE_ERROR_FLAG, error_flag, clk, !reset_n) + +endmodule \ No newline at end of file diff --git a/designs/Caliptra/src/caliptra-rtl/aes.sv b/designs/Caliptra/src/caliptra-rtl/aes.sv new file mode 100644 index 0000000..7edcd01 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/aes.sv @@ -0,0 +1,485 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// AES top-level wrapper + +`include "caliptra_prim_assert.sv" + +module aes + import aes_pkg::*; + import aes_reg_pkg::*; +#( + parameter bit AES192Enable = 1, // Can be 0 (disable), or 1 (enable). + parameter bit AESGCMEnable = 1, // Can be 0 (disable), or 1 (enable). + parameter bit SecMasking = 1, // Can be 0 (no masking), or + // 1 (first-order masking) of the cipher + // core. Masking requires the use of a + // masked S-Box, see SecSBoxImpl parameter. + parameter sbox_impl_e SecSBoxImpl = SBoxImplDom, // See aes_pkg.sv + parameter int unsigned SecStartTriggerDelay = 0, // Manual start trigger delay, useful for + // SCA measurements. A value of e.g. 40 + // allows the processor to go into sleep + // before AES starts operation. + parameter bit SecAllowForcingMasks = 0, // Allow forcing masks to constant values using + // FORCE_MASKS bit in Auxiliary Control + // Register. Useful for SCA only. + parameter bit SecSkipPRNGReseeding = 0, // The current SCA setup doesn't provide enough + // resources to implement the infrastucture + // required for PRNG reseeding (CSRNG, EDN). + // To enable SCA resistance evaluations, we + // need to skip reseeding requests. + // Useful for SCA only. + parameter logic [NumAlerts-1:0] AlertAsyncOn = {NumAlerts{1'b1}}, + parameter clearing_lfsr_seed_t RndCnstClearingLfsrSeed = RndCnstClearingLfsrSeedDefault, + parameter clearing_lfsr_perm_t RndCnstClearingLfsrPerm = RndCnstClearingLfsrPermDefault, + parameter clearing_lfsr_perm_t RndCnstClearingSharePerm = RndCnstClearingSharePermDefault, + parameter masking_lfsr_seed_t RndCnstMaskingLfsrSeed = RndCnstMaskingLfsrSeedDefault, + parameter masking_lfsr_perm_t RndCnstMaskingLfsrPerm = RndCnstMaskingLfsrPermDefault +) ( + input logic clk_i, + input logic rst_ni, + input logic rst_shadowed_ni, + + // Idle indicator for clock manager + output caliptra_prim_mubi_pkg::mubi4_t idle_o, + + // Life cycle + input lc_ctrl_pkg::lc_tx_t lc_escalate_en_i, + + // Entropy distribution network (EDN) interface + input logic clk_edn_i, + input logic rst_edn_ni, + output edn_pkg::edn_req_t edn_o, + input edn_pkg::edn_rsp_t edn_i, + + // status signals + output logic input_ready_o, + output logic output_valid_o, + + // Caliptra interface + input caliptra2aes_t caliptra2aes, + output aes2caliptra_t aes2caliptra, + + + // Key manager (keymgr) key sideload interface + input keymgr_pkg::hw_key_req_t keymgr_key_i, + + // Bus interface + input caliptra_tlul_pkg::tl_h2d_t tl_i, + output caliptra_tlul_pkg::tl_d2h_t tl_o, + + // Alerts + input caliptra_prim_alert_pkg::alert_rx_t [NumAlerts-1:0] alert_rx_i, + output caliptra_prim_alert_pkg::alert_tx_t [NumAlerts-1:0] alert_tx_o +); + + localparam int unsigned EntropyWidth = edn_pkg::ENDPOINT_BUS_WIDTH; + + // Signals + aes_reg2hw_t reg2hw; + aes_hw2reg_t hw2reg; + + logic [NumAlerts-1:0] alert; + lc_ctrl_pkg::lc_tx_t lc_escalate_en; + + logic edn_req_int; + logic edn_req_hold_d, edn_req_hold_q; + logic edn_req; + logic edn_ack; + logic [EntropyWidth-1:0] edn_data; + logic unused_edn_fips; + logic entropy_clearing_req, entropy_masking_req; + logic entropy_clearing_ack, entropy_masking_ack; + + //////////// + // Inputs // + //////////// + + // SEC_CM: BUS.INTEGRITY + // SEC_CM: AUX.CONFIG.SHADOW + // SEC_CM: AUX.CONFIG.REGWEN + // SEC_CM: KEY.SW_UNREADABLE + // SEC_CM: DATA_REG.SW_UNREADABLE + // Register interface + logic intg_err_alert; + logic shadowed_storage_err, shadowed_update_err; + aes_reg_top u_reg ( + .clk_i, + .rst_ni, + .rst_shadowed_ni, + .tl_i, + .tl_o, + .input_ready_o, + .output_valid_o, + .reg2hw, + .hw2reg, + .shadowed_storage_err_o(shadowed_storage_err), + .shadowed_update_err_o(shadowed_update_err), + .intg_err_o(intg_err_alert) + ); + + // SEC_CM: LC_ESCALATE_EN.INTERSIG.MUBI + // Synchronize life cycle input + caliptra_prim_lc_sync #( + .NumCopies (1) + ) u_caliptra_prim_lc_sync ( + .clk_i, + .rst_ni, + .lc_en_i ( lc_escalate_en_i ), + .lc_en_o ( {lc_escalate_en} ) + ); + + //////////////////////////////// + // Caliptra Control Intercept // + //////////////////////////////// + localparam CLP_AES_KV_CHUNK_SIZE = NumRegsData*32; // Size of data that can be stored at once, atomically, at end of AES op + genvar kv_ii; + + aes_hw2reg_t hw2reg_caliptra; + aes_reg2hw_t reg2hw_caliptra; + logic aes2caliptra_kv_data_out_valid; + logic [CLP_AES_KV_WR_DW-1:0] aes2caliptra_kv_data_out; + logic kv_data_intercept; + logic kv_data_intercept_end; + logic [$clog2(CLP_AES_KV_WR_DW/CLP_AES_KV_CHUNK_SIZE)-1:0] kv_data_counter; // This will peg at the key_size value if decrypted plaintext is larger than CLP_AES_KV_WR_DW + logic [$clog2(CLP_AES_KV_WR_DW/CLP_AES_KV_CHUNK_SIZE)-1:0] kv_data_thresh; // Comparison value for kv_data_counter to saturate, i.e. the key_size normalized to data chunk size + logic incr_kv_data_counter; + logic hw2reg_data_out_mask_en; + logic [$bits(aes_hw2reg_data_out_mreg_t)-1:0] hw2reg_data_out_mask; + logic output_blocked_de; + logic output_valid_r; + + // Mask to conceal data_out from reg API (when dest is KV) + assign hw2reg_data_out_mask = {$bits(aes_hw2reg_data_out_mreg_t){hw2reg_data_out_mask_en}}; + + // Enable signal to drive an update to the status.output_lost register field + always_comb output_blocked_de = hw2reg_caliptra.status.output_valid.de && + hw2reg_caliptra.status.output_valid.d && + caliptra2aes.block_reg_output; + + always_comb begin + // Passthrough + hw2reg = hw2reg_caliptra; + // Augmented + // For OCP LOCK use-cases, add a condition to set output_lost if output data is required to go to KV. + // Output Lost is usually only used for Manual mode. TODO if we support manual mode with OCP LOCK flows (and KV WR) this may + // need to be updated. + hw2reg.status.output_lost.d = output_blocked_de ? 1'b1 : + hw2reg_caliptra.status.output_lost.d; + hw2reg.status.output_lost.de = hw2reg_caliptra.status.output_lost.de || + output_blocked_de; + // Concealed + foreach (hw2reg.data_out[idx]) begin + hw2reg.data_out[idx].d = hw2reg_caliptra.data_out[idx].d & hw2reg_data_out_mask; + end + end + always_comb begin + // Passthrough + reg2hw_caliptra = reg2hw; + // RE intercept + foreach (reg2hw.data_out[idx]) begin + reg2hw_caliptra.data_out[idx].q = reg2hw.data_out[idx].q ; + reg2hw_caliptra.data_out[idx].re = kv_data_intercept ? output_valid_r : + reg2hw.data_out[idx].re; + end + end + + // Flag to detect when data out shall be routed to Caliptra KeyVault + always_ff @(posedge clk_i or negedge rst_ni) begin: kv_data_intercept_reg + if (!rst_ni) begin + kv_data_intercept <= 1'b0; + hw2reg_data_out_mask_en <= 1'b1; + end + // FW must arm the KV write prior to starting AES operation + else if ((kv_data_counter == 0) && reg2hw_caliptra.data_in[0].qe) begin + kv_data_intercept <= caliptra2aes.kv_en; + hw2reg_data_out_mask_en <= ~caliptra2aes.kv_en && ~caliptra2aes.block_reg_output; // This signal winds up being effectively (~kv_data_intercept && ~caliptra2aes.block_reg_output) + end + // TODO support for Manual operation mode with trigger.start.q? + else if (kv_data_intercept_end) begin + kv_data_intercept <= 1'b0; + hw2reg_data_out_mask_en <= 1'b1; + end + end + + // NOTE if key size is not an integer multiple of CLP_AES_KV_CHUNK_SIZE, this is a rounded down value + always_comb kv_data_thresh = ($clog2(CLP_AES_KV_WR_DW/CLP_AES_KV_CHUNK_SIZE))'(caliptra2aes.key_release_key_size/(CLP_AES_KV_CHUNK_SIZE/8)-1); + // NOTE: This assumes that output_valid will always assert prior to entering idle state, which should be true. + // If this doesn't hold, then kv_data_intercept will deassert before the final data beat is captured, and + // the KV write won't be issued + always_comb kv_data_intercept_end = hw2reg.status.idle.de && hw2reg.status.idle.d && !reg2hw_caliptra.status.idle.q && (kv_data_counter == kv_data_thresh); + + // Latch when data_out is valid, used to generate read-enable and signal data capture + always_ff @(posedge clk_i or negedge rst_ni) begin: output_valid_dd_reg + if (!rst_ni) begin + output_valid_r <= 1'b0; + end + else if (hw2reg_caliptra.status.output_valid.de) begin + output_valid_r <= hw2reg_caliptra.status.output_valid.d; + end + end + + // Index into the KV output data based on number of AES rounds observed + always_comb incr_kv_data_counter = kv_data_intercept && output_valid_r; + always_ff @(posedge clk_i or negedge rst_ni) begin: aes2caliptra_kv_data_counter_reg + if (!rst_ni) begin + kv_data_counter <= '0; + end + else if (!kv_data_intercept) begin + kv_data_counter <= '0; + end + else if (incr_kv_data_counter && (kv_data_counter == kv_data_thresh)) begin + kv_data_counter <= kv_data_counter; + end + else if (incr_kv_data_counter) begin + kv_data_counter <= kv_data_counter + 1; + end + end + + // Signal data is valid for KV write client once full AES operation is done + always_ff @(posedge clk_i or negedge rst_ni) begin: aes2caliptra_kv_data_valid_reg + if (!rst_ni) begin + aes2caliptra_kv_data_out_valid <= 1'b0; + end + else if (caliptra2aes.clear_secrets || reg2hw_caliptra.trigger.data_out_clear.q) begin + aes2caliptra_kv_data_out_valid <= 1'b0; + end + else if (kv_data_intercept_end) begin + aes2caliptra_kv_data_out_valid <= 1'b1; + end + else if (caliptra2aes.kv_write_done) begin + aes2caliptra_kv_data_out_valid <= 1'b0; + end + end + assign aes2caliptra.kv_data_out_valid = aes2caliptra_kv_data_out_valid; + assign aes2caliptra.kv_key_in_use = hw2reg.ctrl_shadowed.sideload.d; + // TODO: Qualify this with anything? + // Probably not needed. Timing of the kv write request is tightly controlled, and that's the only + // place this signal is used. + always_comb aes2caliptra.aes_operation_is_ecb_decrypt = ( aes_op_e'(hw2reg.ctrl_shadowed.operation.d) == AES_DEC) && + (aes_mode_e'(hw2reg.ctrl_shadowed.mode.d) == AES_ECB); + + // Capture data_out until operation is done + generate + for (kv_ii=0; kv_ii < CLP_AES_KV_WR_DW/CLP_AES_KV_CHUNK_SIZE; kv_ii++) begin + always_ff @(posedge clk_i or negedge rst_ni) begin: aes2caliptra_kv_data_reg + if (!rst_ni) begin + aes2caliptra_kv_data_out[(kv_ii)*CLP_AES_KV_CHUNK_SIZE+:CLP_AES_KV_CHUNK_SIZE] <= CLP_AES_KV_CHUNK_SIZE'(0); + end + else if ((caliptra2aes.clear_secrets) || reg2hw_caliptra.trigger.data_out_clear.q) begin + aes2caliptra_kv_data_out[(kv_ii)*CLP_AES_KV_CHUNK_SIZE+:CLP_AES_KV_CHUNK_SIZE] <= CLP_AES_KV_CHUNK_SIZE'(0); + end + else if (incr_kv_data_counter && (kv_data_counter == kv_ii)) begin + aes2caliptra_kv_data_out[(kv_ii)*CLP_AES_KV_CHUNK_SIZE+:CLP_AES_KV_CHUNK_SIZE] <= {hw2reg_caliptra.data_out[3].d, + hw2reg_caliptra.data_out[2].d, + hw2reg_caliptra.data_out[1].d, + hw2reg_caliptra.data_out[0].d}; + end + else if (caliptra2aes.kv_write_done) begin + aes2caliptra_kv_data_out[(kv_ii)*CLP_AES_KV_CHUNK_SIZE+:CLP_AES_KV_CHUNK_SIZE] <= CLP_AES_KV_CHUNK_SIZE'(0); + end + end + end + endgenerate + assign aes2caliptra.kv_data_out = aes2caliptra_kv_data_out; + + /////////////////// + // EDN Interface // + /////////////////// + + // Internally, we have up to two PRNGs that share the EDN interface for reseeding. Here, we just + // arbitrate the requests. Upsizing of the entropy to the correct width is performed inside the + // PRNGs. + // Reseed operations for the clearing PRNG are initiated by software. Reseed operations for the + // masking PRNG can also be automatically initiated. + assign edn_req_int = entropy_clearing_req | entropy_masking_req; + // Only forward ACK to PRNG currently requesting entropy. Give higher priority to clearing PRNG. + assign entropy_clearing_ack = entropy_clearing_req & edn_ack; + assign entropy_masking_ack = ~entropy_clearing_req & entropy_masking_req & edn_ack; + + // Upon escalation or detection of a fatal alert, an EDN request signal can be dropped before + // getting acknowledged. This is okay with respect to AES as the module will need to be reset + // anyway. However, to not leave EDN in a strange state, we hold the request until it's actually + // acknowledged. + assign edn_req = edn_req_int | edn_req_hold_q; + assign edn_req_hold_d = (edn_req_hold_q | edn_req) & ~edn_ack; + always_ff @(posedge clk_i or negedge rst_ni) begin : edn_req_reg + if (!rst_ni) begin + edn_req_hold_q <= '0; + end else begin + edn_req_hold_q <= edn_req_hold_d; + end + end + + // Synchronize EDN interface + caliptra_prim_sync_reqack_data #( + .Width(EntropyWidth), + .DataSrc2Dst(1'b0), + .DataReg(1'b0) + ) u_caliptra_prim_sync_reqack_data ( + .clk_src_i ( clk_i ), + .rst_src_ni ( rst_ni ), + .clk_dst_i ( clk_edn_i ), + .rst_dst_ni ( rst_edn_ni ), + .req_chk_i ( 1'b1 ), + .src_req_i ( edn_req ), + .src_ack_o ( edn_ack ), + .dst_req_o ( edn_o.edn_req ), + .dst_ack_i ( edn_i.edn_ack ), + .data_i ( edn_i.edn_bus ), + .data_o ( edn_data ) + ); + // We don't track whether the entropy is pre-FIPS or not inside AES. + assign unused_edn_fips = edn_i.edn_fips; + + ////////// + // Core // + ////////// + + // AES core + aes_core #( + .AES192Enable ( AES192Enable ), + .AESGCMEnable ( AESGCMEnable ), + .SecMasking ( SecMasking ), + .SecSBoxImpl ( SecSBoxImpl ), + .SecStartTriggerDelay ( SecStartTriggerDelay ), + .SecAllowForcingMasks ( SecAllowForcingMasks ), + .SecSkipPRNGReseeding ( SecSkipPRNGReseeding ), + .EntropyWidth ( EntropyWidth ), + .RndCnstClearingLfsrSeed ( RndCnstClearingLfsrSeed ), + .RndCnstClearingLfsrPerm ( RndCnstClearingLfsrPerm ), + .RndCnstClearingSharePerm ( RndCnstClearingSharePerm ), + .RndCnstMaskingLfsrSeed ( RndCnstMaskingLfsrSeed ), + .RndCnstMaskingLfsrPerm ( RndCnstMaskingLfsrPerm ) + ) u_aes_core ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .rst_shadowed_ni ( rst_shadowed_ni ), + .entropy_clearing_req_o ( entropy_clearing_req ), + .entropy_clearing_ack_i ( entropy_clearing_ack ), + .entropy_clearing_i ( edn_data ), + .entropy_masking_req_o ( entropy_masking_req ), + .entropy_masking_ack_i ( entropy_masking_ack ), + .entropy_masking_i ( edn_data ), + + .keymgr_key_i ( keymgr_key_i ), + + .lc_escalate_en_i ( lc_escalate_en ), + + .shadowed_storage_err_i ( shadowed_storage_err ), + .shadowed_update_err_i ( shadowed_update_err ), + .intg_err_alert_i ( intg_err_alert ), + .alert_recov_o ( alert[0] ), + .alert_fatal_o ( alert[1] ), + + .reg2hw ( reg2hw_caliptra ), + .hw2reg ( hw2reg_caliptra ) + ); + + assign idle_o = caliptra_prim_mubi_pkg::mubi4_bool_to_mubi(reg2hw.status.idle.q); + + + //////////// + // Alerts // + //////////// + + logic [NumAlerts-1:0] alert_test; + assign alert_test = { + reg2hw.alert_test.fatal_fault.q & + reg2hw.alert_test.fatal_fault.qe, + reg2hw.alert_test.recov_ctrl_update_err.q & + reg2hw.alert_test.recov_ctrl_update_err.qe + }; + + for (genvar i = 0; i < NumAlerts; i++) begin : gen_alert_tx + caliptra_prim_alert_sender #( + .AsyncOn(AlertAsyncOn[i]), + .IsFatal(i) + ) u_caliptra_prim_alert_sender ( + .clk_i, + .rst_ni, + .alert_test_i ( alert_test[i] ), + .alert_req_i ( alert[i] ), + .alert_ack_o ( ), + .alert_state_o ( ), + .alert_rx_i ( alert_rx_i[i] ), + .alert_tx_o ( alert_tx_o[i] ) + ); + end + + //////////////// + // Assertions // + //////////////// + + // All outputs should have a known value after reset + `CALIPTRA_ASSERT_KNOWN(TlODValidKnown, tl_o.d_valid) + `CALIPTRA_ASSERT_KNOWN(TlOAReadyKnown, tl_o.a_ready) + `CALIPTRA_ASSERT_KNOWN(IdleKnown, idle_o) + `CALIPTRA_ASSERT_KNOWN(EdnReqKnown, edn_o) + `CALIPTRA_ASSERT_KNOWN(AlertTxKnown, alert_tx_o) + + // Alert assertions for sparse FSMs. + for (genvar i = 0; i < Sp2VWidth; i++) begin : gen_control_fsm_svas + if (SP2V_LOGIC_HIGH[i] == 1'b1) begin : gen_control_fsm_svas_p + `CALIPTRA_ASSERT_PRIM_FSM_ERROR_TRIGGER_ALERT(AesControlFsmCheck_A, + u_aes_core.u_aes_control.gen_fsm[i].gen_fsm_p. + u_aes_control_fsm_i.u_aes_control_fsm.u_state_regs, + alert_tx_o[1]) + end else begin : gen_control_fsm_svas_n + `CALIPTRA_ASSERT_PRIM_FSM_ERROR_TRIGGER_ALERT(AesControlFsmCheck_A, + u_aes_core.u_aes_control.gen_fsm[i].gen_fsm_n. + u_aes_control_fsm_i.u_aes_control_fsm.u_state_regs, + alert_tx_o[1]) + end + end + + for (genvar i = 0; i < Sp2VWidth; i++) begin : gen_ctr_fsm_svas + if (SP2V_LOGIC_HIGH[i] == 1'b1) begin : gen_ctr_fsm_svas_p + `CALIPTRA_ASSERT_PRIM_FSM_ERROR_TRIGGER_ALERT(AesCtrFsmCheck_A, + u_aes_core.u_aes_ctr.gen_fsm[i].gen_fsm_p. + u_aes_ctr_fsm_i.u_aes_ctr_fsm.u_state_regs, + alert_tx_o[1]) + end else begin : gen_ctr_fsm_svas_n + `CALIPTRA_ASSERT_PRIM_FSM_ERROR_TRIGGER_ALERT(AesCtrFsmCheck_A, + u_aes_core.u_aes_ctr.gen_fsm[i].gen_fsm_n. + u_aes_ctr_fsm_i.u_aes_ctr_fsm.u_state_regs, + alert_tx_o[1]) + end + end + + for (genvar i = 0; i < Sp2VWidth; i++) begin : gen_cipher_control_fsm_svas + if (SP2V_LOGIC_HIGH[i] == 1'b1) begin : gen_cipher_control_fsm_svas_p + `CALIPTRA_ASSERT_PRIM_FSM_ERROR_TRIGGER_ALERT(AesCipherControlFsmCheck_A, + u_aes_core.u_aes_cipher_core.u_aes_cipher_control.gen_fsm[i].gen_fsm_p. + u_aes_cipher_control_fsm_i.u_aes_cipher_control_fsm.u_state_regs, + alert_tx_o[1]) + end else begin : gen_cipher_control_fsm_svas_n + `CALIPTRA_ASSERT_PRIM_FSM_ERROR_TRIGGER_ALERT(AesCipherControlFsmCheck_A, + u_aes_core.u_aes_cipher_core.u_aes_cipher_control.gen_fsm[i].gen_fsm_n. + u_aes_cipher_control_fsm_i.u_aes_cipher_control_fsm.u_state_regs, + alert_tx_o[1]) + end + end + + if (AESGCMEnable) begin : gen_ghash_fsm_sva + `CALIPTRA_ASSERT_PRIM_FSM_ERROR_TRIGGER_ALERT(AesGhashFsmCheck_A, + u_aes_core.gen_ghash.u_aes_ghash.u_state_regs, + alert_tx_o[1]) + end + + if (AESGCMEnable && SecMasking) begin : gen_ghash_onehot_sva + for (genvar s = 0; s < 2; s++) begin : gen_ghash_onehot_add_in_sva + `CALIPTRA_ASSERT_PRIM_ONEHOT_ERROR_TRIGGER_ALERT(GhashAadOnehotCheck_A, + u_aes_core.gen_ghash.u_aes_ghash.gen_masked_add.gen_add_in_muxes[s]. + u_caliptra_prim_onehot_check_add_in_sel, + alert_tx_o[1]) + end + `CALIPTRA_ASSERT_PRIM_ONEHOT_ERROR_TRIGGER_ALERT(GhashMultOnehotCheck_A, + u_aes_core.gen_ghash.u_aes_ghash.gen_gf_mult1_mux.u_caliptra_prim_onehot_check_gf_mult1_in_sel, + alert_tx_o[1]) + end + + // Alert assertions for reg_we onehot check + `CALIPTRA_ASSERT_PRIM_REG_WE_ONEHOT_ERROR_TRIGGER_ALERT(RegWeOnehotCheck_A, u_reg, alert_tx_o[1]) +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/aes_cipher_control.sv b/designs/Caliptra/src/caliptra-rtl/aes_cipher_control.sv new file mode 100644 index 0000000..d8c9e9c --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/aes_cipher_control.sv @@ -0,0 +1,485 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// AES cipher core control +// +// This module controls the AES cipher core including the key expand module. + +`include "caliptra_prim_assert.sv" + +module aes_cipher_control import aes_pkg::*; +#( + parameter bit CiphOpFwdOnly = 0, + parameter bit SecMasking = 0, + parameter sbox_impl_e SecSBoxImpl = SBoxImplDom +) ( + input logic clk_i, + input logic rst_ni, + + // Input handshake signals + input sp2v_e in_valid_i, + output sp2v_e in_ready_o, + + // Output handshake signals + output sp2v_e out_valid_o, + input sp2v_e out_ready_i, + + // Control and sync signals + input logic cfg_valid_i, + input ciph_op_e op_i, + input key_len_e key_len_i, + input sp2v_e crypt_i, + output sp2v_e crypt_o, + input sp2v_e dec_key_gen_i, + output sp2v_e dec_key_gen_o, + input logic prng_reseed_i, + output logic prng_reseed_o, + input logic key_clear_i, + output logic key_clear_o, + input logic data_out_clear_i, + output logic data_out_clear_o, + input logic mux_sel_err_i, + input logic sp_enc_err_i, + input logic op_err_i, + input logic alert_fatal_i, + output logic alert_o, + + // Control signals for masking PRNG + output logic prng_update_o, + output logic prng_reseed_req_o, + input logic prng_reseed_ack_i, + + // Control and sync signals for cipher data path + output state_sel_e state_sel_o, + output sp2v_e state_we_o, + output sp2v_e sub_bytes_en_o, + input sp2v_e sub_bytes_out_req_i, + output sp2v_e sub_bytes_out_ack_o, + output add_rk_sel_e add_rk_sel_o, + + // Control and sync signals for key expand data path + output ciph_op_e key_expand_op_o, + output key_full_sel_e key_full_sel_o, + output sp2v_e key_full_we_o, + output key_dec_sel_e key_dec_sel_o, + output sp2v_e key_dec_we_o, + output sp2v_e key_expand_en_o, + input sp2v_e key_expand_out_req_i, + output sp2v_e key_expand_out_ack_o, + output logic key_expand_clear_o, + output logic [3:0] key_expand_round_o, + output key_words_sel_e key_words_sel_o, + output round_key_sel_e round_key_sel_o +); + + // Signals + logic [3:0] rnd_ctr; + sp2v_e crypt_d, crypt_q; + sp2v_e dec_key_gen_d, dec_key_gen_q; + logic prng_reseed_d, prng_reseed_q; + logic key_clear_d, key_clear_q; + logic data_out_clear_d, data_out_clear_q; + sp2v_e sub_bytes_out_req; + sp2v_e key_expand_out_req; + sp2v_e in_valid; + sp2v_e out_ready; + sp2v_e crypt; + sp2v_e dec_key_gen; + logic mux_sel_err; + logic mr_err; + logic sp_enc_err; + logic rnd_ctr_err; + + // Sparsified FSM signals. These are needed for connecting the individual bits of the Sp2V + // signals to the single-rail FSMs. + logic [Sp2VWidth-1:0] sp_in_valid; + logic [Sp2VWidth-1:0] sp_in_ready; + logic [Sp2VWidth-1:0] sp_out_valid; + logic [Sp2VWidth-1:0] sp_out_ready; + logic [Sp2VWidth-1:0] sp_crypt; + logic [Sp2VWidth-1:0] sp_dec_key_gen; + logic [Sp2VWidth-1:0] sp_state_we; + logic [Sp2VWidth-1:0] sp_sub_bytes_en; + logic [Sp2VWidth-1:0] sp_sub_bytes_out_req; + logic [Sp2VWidth-1:0] sp_sub_bytes_out_ack; + logic [Sp2VWidth-1:0] sp_key_full_we; + logic [Sp2VWidth-1:0] sp_key_dec_we; + logic [Sp2VWidth-1:0] sp_key_expand_en; + logic [Sp2VWidth-1:0] sp_key_expand_out_req; + logic [Sp2VWidth-1:0] sp_key_expand_out_ack; + logic [Sp2VWidth-1:0] sp_crypt_d; + logic [Sp2VWidth-1:0] sp_crypt_q; + logic [Sp2VWidth-1:0] sp_dec_key_gen_d; + logic [Sp2VWidth-1:0] sp_dec_key_gen_q; + + // Multi-rail signals. These are outputs of the single-rail FSMs and need combining. + logic [Sp2VWidth-1:0] mr_alert; + logic [Sp2VWidth-1:0] mr_prng_update; + logic [Sp2VWidth-1:0] mr_prng_reseed_req; + logic [Sp2VWidth-1:0] mr_key_expand_clear; + logic [Sp2VWidth-1:0] mr_prng_reseed_d; + logic [Sp2VWidth-1:0] mr_key_clear_d; + logic [Sp2VWidth-1:0] mr_data_out_clear_d; + + state_sel_e [Sp2VWidth-1:0] mr_state_sel; + add_rk_sel_e [Sp2VWidth-1:0] mr_add_rk_sel; + key_full_sel_e [Sp2VWidth-1:0] mr_key_full_sel; + key_dec_sel_e [Sp2VWidth-1:0] mr_key_dec_sel; + key_words_sel_e [Sp2VWidth-1:0] mr_key_words_sel; + round_key_sel_e [Sp2VWidth-1:0] mr_round_key_sel; + + logic [Sp2VWidth-1:0][3:0] mr_rnd_ctr; + + ///////// + // FSM // + ///////// + + // Convert sp2v_e signals to sparsified inputs. + assign sp_in_valid = {in_valid}; + assign sp_out_ready = {out_ready}; + assign sp_crypt = {crypt}; + assign sp_dec_key_gen = {dec_key_gen}; + assign sp_sub_bytes_out_req = {sub_bytes_out_req}; + assign sp_key_expand_out_req = {key_expand_out_req}; + assign sp_crypt_q = {crypt_q}; + assign sp_dec_key_gen_q = {dec_key_gen_q}; + + // SEC_CM: CIPHER.FSM.REDUN + // SEC_CM: CIPHER.CTR.REDUN + // For every bit in the Sp2V signals, one separate rail is instantiated. The inputs and outputs + // of every rail are buffered to prevent aggressive synthesis optimizations. + for (genvar i = 0; i < Sp2VWidth; i++) begin : gen_fsm + if (SP2V_LOGIC_HIGH[i] == 1'b1) begin : gen_fsm_p + aes_cipher_control_fsm_p #( + .SecMasking ( SecMasking ), + .SecSBoxImpl ( SecSBoxImpl ) + ) u_aes_cipher_control_fsm_i ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + + .in_valid_i ( sp_in_valid[i] ), // Sparsified + .in_ready_o ( sp_in_ready[i] ), // Sparsified + + .out_valid_o ( sp_out_valid[i] ), // Sparsified + .out_ready_i ( sp_out_ready[i] ), // Sparsified + + .cfg_valid_i ( cfg_valid_i ), + .op_i ( op_i ), + .key_len_i ( key_len_i ), + .crypt_i ( sp_crypt[i] ), // Sparsified + .dec_key_gen_i ( sp_dec_key_gen[i] ), // Sparsified + .prng_reseed_i ( prng_reseed_i ), + .key_clear_i ( key_clear_i ), + .data_out_clear_i ( data_out_clear_i ), + .mux_sel_err_i ( mux_sel_err ), + .sp_enc_err_i ( sp_enc_err ), + .rnd_ctr_err_i ( rnd_ctr_err ), + .op_err_i ( op_err_i ), + .alert_fatal_i ( alert_fatal_i ), + .alert_o ( mr_alert[i] ), // OR-combine + + .prng_update_o ( mr_prng_update[i] ), // OR-combine + .prng_reseed_req_o ( mr_prng_reseed_req[i] ), // OR-combine + .prng_reseed_ack_i ( prng_reseed_ack_i ), + + .state_sel_o ( mr_state_sel[i] ), // OR-combine + .state_we_o ( sp_state_we[i] ), // Sparsified + .sub_bytes_en_o ( sp_sub_bytes_en[i] ), // Sparsified + .sub_bytes_out_req_i ( sp_sub_bytes_out_req[i] ), // Sparsified + .sub_bytes_out_ack_o ( sp_sub_bytes_out_ack[i] ), // Sparsified + .add_rk_sel_o ( mr_add_rk_sel[i] ), // OR-combine + + .key_full_sel_o ( mr_key_full_sel[i] ), // OR-combine + .key_full_we_o ( sp_key_full_we[i] ), // Sparsified + .key_dec_sel_o ( mr_key_dec_sel[i] ), // OR-combine + .key_dec_we_o ( sp_key_dec_we[i] ), // Sparsified + .key_expand_en_o ( sp_key_expand_en[i] ), // Sparsified + .key_expand_out_req_i ( sp_key_expand_out_req[i] ), // Sparsified + .key_expand_out_ack_o ( sp_key_expand_out_ack[i] ), // Sparsified + .key_expand_clear_o ( mr_key_expand_clear[i] ), // OR-combine + .rnd_ctr_o ( mr_rnd_ctr[i] ), // OR-combine + .key_words_sel_o ( mr_key_words_sel[i] ), // OR-combine + .round_key_sel_o ( mr_round_key_sel[i] ), // OR-combine + + .crypt_q_i ( sp_crypt_q[i] ), // Sparsified + .crypt_d_o ( sp_crypt_d[i] ), // Sparsified + .dec_key_gen_q_i ( sp_dec_key_gen_q[i] ), // Sparsified + .dec_key_gen_d_o ( sp_dec_key_gen_d[i] ), // Sparsified + .prng_reseed_q_i ( prng_reseed_q ), + .prng_reseed_d_o ( mr_prng_reseed_d[i] ), // AND-combine + .key_clear_q_i ( key_clear_q ), + .key_clear_d_o ( mr_key_clear_d[i] ), // AND-combine + .data_out_clear_q_i ( data_out_clear_q ), + .data_out_clear_d_o ( mr_data_out_clear_d[i] ) // AND-combine + ); + end else begin : gen_fsm_n + aes_cipher_control_fsm_n #( + .SecMasking ( SecMasking ), + .SecSBoxImpl ( SecSBoxImpl ) + ) u_aes_cipher_control_fsm_i ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + + .in_valid_ni ( sp_in_valid[i] ), // Sparsified + .in_ready_no ( sp_in_ready[i] ), // Sparsified + + .out_valid_no ( sp_out_valid[i] ), // Sparsified + .out_ready_ni ( sp_out_ready[i] ), // Sparsified + + .cfg_valid_i ( cfg_valid_i ), + .op_i ( op_i ), + .key_len_i ( key_len_i ), + .crypt_ni ( sp_crypt[i] ), // Sparsified + .dec_key_gen_ni ( sp_dec_key_gen[i] ), // Sparsified + .prng_reseed_i ( prng_reseed_i ), + .key_clear_i ( key_clear_i ), + .data_out_clear_i ( data_out_clear_i ), + .mux_sel_err_i ( mux_sel_err ), + .sp_enc_err_i ( sp_enc_err ), + .rnd_ctr_err_i ( rnd_ctr_err ), + .op_err_i ( op_err_i ), + .alert_fatal_i ( alert_fatal_i ), + .alert_o ( mr_alert[i] ), // OR-combine + + .prng_update_o ( mr_prng_update[i] ), // OR-combine + .prng_reseed_req_o ( mr_prng_reseed_req[i] ), // OR-combine + .prng_reseed_ack_i ( prng_reseed_ack_i ), + + .state_sel_o ( mr_state_sel[i] ), // OR-combine + .state_we_no ( sp_state_we[i] ), // Sparsified + .sub_bytes_en_no ( sp_sub_bytes_en[i] ), // Sparsified + .sub_bytes_out_req_ni ( sp_sub_bytes_out_req[i] ), // Sparsified + .sub_bytes_out_ack_no ( sp_sub_bytes_out_ack[i] ), // Sparsified + .add_rk_sel_o ( mr_add_rk_sel[i] ), // OR-combine + + .key_full_sel_o ( mr_key_full_sel[i] ), // OR-combine + .key_full_we_no ( sp_key_full_we[i] ), // Sparsified + .key_dec_sel_o ( mr_key_dec_sel[i] ), // OR-combine + .key_dec_we_no ( sp_key_dec_we[i] ), // Sparsified + .key_expand_en_no ( sp_key_expand_en[i] ), // Sparsified + .key_expand_out_req_ni ( sp_key_expand_out_req[i] ), // Sparsified + .key_expand_out_ack_no ( sp_key_expand_out_ack[i] ), // Sparsified + .key_expand_clear_o ( mr_key_expand_clear[i] ), // OR-combine + .rnd_ctr_o ( mr_rnd_ctr[i] ), // OR-combine + .key_words_sel_o ( mr_key_words_sel[i] ), // OR-combine + .round_key_sel_o ( mr_round_key_sel[i] ), // OR-combine + + .crypt_q_ni ( sp_crypt_q[i] ), // Sparsified + .crypt_d_no ( sp_crypt_d[i] ), // Sparsified + .dec_key_gen_q_ni ( sp_dec_key_gen_q[i] ), // Sparsified + .dec_key_gen_d_no ( sp_dec_key_gen_d[i] ), // Sparsified + .prng_reseed_q_i ( prng_reseed_q ), + .prng_reseed_d_o ( mr_prng_reseed_d[i] ), // AND-combine + .key_clear_q_i ( key_clear_q ), + .key_clear_d_o ( mr_key_clear_d[i] ), // AND-combine + .data_out_clear_q_i ( data_out_clear_q ), + .data_out_clear_d_o ( mr_data_out_clear_d[i] ) // AND-combine + ); + end + end + + // Convert sparsified outputs to sp2v_e type. + assign in_ready_o = sp2v_e'(sp_in_ready); + assign out_valid_o = sp2v_e'(sp_out_valid); + assign state_we_o = sp2v_e'(sp_state_we); + assign sub_bytes_en_o = sp2v_e'(sp_sub_bytes_en); + assign sub_bytes_out_ack_o = sp2v_e'(sp_sub_bytes_out_ack); + assign key_full_we_o = sp2v_e'(sp_key_full_we); + assign key_dec_we_o = sp2v_e'(sp_key_dec_we); + assign key_expand_en_o = sp2v_e'(sp_key_expand_en); + assign key_expand_out_ack_o = sp2v_e'(sp_key_expand_out_ack); + assign crypt_d = sp2v_e'(sp_crypt_d); + assign dec_key_gen_d = sp2v_e'(sp_dec_key_gen_d); + + // Combine single-bit FSM outputs. + // OR: One bit is sufficient to drive the corresponding output bit high. + assign alert_o = |mr_alert; + assign prng_update_o = |mr_prng_update; + assign prng_reseed_req_o = |mr_prng_reseed_req; + assign key_expand_clear_o = |mr_key_expand_clear; + // AND: Only if all bits are high, the corresponding status is signaled which will lead to + // the clearing of these trigger bits. + assign prng_reseed_d = &mr_prng_reseed_d; + assign key_clear_d = &mr_key_clear_d; + assign data_out_clear_d = &mr_data_out_clear_d; + + // Combine multi-bit, sparse FSM outputs. We simply OR them together. If the FSMs don't provide + // the same outputs, two cases are possible: + // - An invalid encoding results: A downstream checker will fire, see mux_sel_err_i. + // - A valid encoding results: The outputs are compared below to cover this case, see mr_err; + always_comb begin : combine_sparse_signals + state_sel_o = state_sel_e'({StateSelWidth{1'b0}}); + add_rk_sel_o = add_rk_sel_e'({AddRKSelWidth{1'b0}}); + key_full_sel_o = key_full_sel_e'({KeyFullSelWidth{1'b0}}); + key_dec_sel_o = key_dec_sel_e'({KeyDecSelWidth{1'b0}}); + key_words_sel_o = key_words_sel_e'({KeyWordsSelWidth{1'b0}}); + round_key_sel_o = round_key_sel_e'({RoundKeySelWidth{1'b0}}); + mr_err = 1'b0; + + for (int i = 0; i < Sp2VWidth; i++) begin + state_sel_o = state_sel_e'({state_sel_o} | {mr_state_sel[i]}); + add_rk_sel_o = add_rk_sel_e'({add_rk_sel_o} | {mr_add_rk_sel[i]}); + key_full_sel_o = key_full_sel_e'({key_full_sel_o} | {mr_key_full_sel[i]}); + key_dec_sel_o = key_dec_sel_e'({key_dec_sel_o} | {mr_key_dec_sel[i]}); + key_words_sel_o = key_words_sel_e'({key_words_sel_o} | {mr_key_words_sel[i]}); + round_key_sel_o = round_key_sel_e'({round_key_sel_o} | {mr_round_key_sel[i]}); + end + + for (int i = 0; i < Sp2VWidth; i++) begin + if (state_sel_o != mr_state_sel[i] || + add_rk_sel_o != mr_add_rk_sel[i] || + key_full_sel_o != mr_key_full_sel[i] || + key_dec_sel_o != mr_key_dec_sel[i] || + key_words_sel_o != mr_key_words_sel[i] || + round_key_sel_o != mr_round_key_sel[i]) begin + mr_err = 1'b1; + end + end + end + + // Collect errors in mux selector signals. + assign mux_sel_err = mux_sel_err_i | mr_err; + + // Combine counter signals. We simply OR them together. If the FSMs don't provide the same + // outputs, rnd_ctr_err will be set. + always_comb begin : combine_counter_signals + rnd_ctr = '0; + rnd_ctr_err = 1'b0; + for (int i = 0; i < Sp2VWidth; i++) begin + rnd_ctr |= mr_rnd_ctr[i]; + end + + for (int i = 0; i < Sp2VWidth; i++) begin + if (rnd_ctr != mr_rnd_ctr[i]) begin + rnd_ctr_err = 1'b1; + end + end + end + + always_ff @(posedge clk_i or negedge rst_ni) begin : reg_fsm + if (!rst_ni) begin + prng_reseed_q <= 1'b0; + key_clear_q <= 1'b0; + data_out_clear_q <= 1'b0; + end else begin + prng_reseed_q <= prng_reseed_d; + key_clear_q <= key_clear_d; + data_out_clear_q <= data_out_clear_d; + end + end + + // Use separate signal for key expand operation, forward round. + assign key_expand_op_o = (dec_key_gen_d == SP2V_HIGH || + dec_key_gen_q == SP2V_HIGH) || CiphOpFwdOnly ? CIPH_FWD : op_i; + assign key_expand_round_o = rnd_ctr; + + // Let the main controller know whate we are doing. + assign crypt_o = crypt_q; + assign dec_key_gen_o = dec_key_gen_q; + assign prng_reseed_o = prng_reseed_q; + assign key_clear_o = key_clear_q; + assign data_out_clear_o = data_out_clear_q; + + + ////////////////////////////// + // Sparsely Encoded Signals // + ////////////////////////////// + + // SEC_CM: CTRL.SPARSE + // We use sparse encodings for various critical signals and must ensure that: + // 1. The synthesis tool doesn't optimize away the sparse encoding. + // 2. The sparsely encoded signal is always valid. More precisely, an alert or SVA is triggered + // if a sparse signal takes on an invalid value. + // 3. The alert signal remains asserted until reset even if the sparse signal becomes valid again + // This is achieved by driving the control FSM into the terminal error state whenever any + // sparsely encoded signal becomes invalid. + // + // If any sparsely encoded signal becomes invalid, the cipher core further immediately de-asserts + // the out_valid_o signal to prevent any data from being released. + + // The following primitives are used to place a size-only constraint on the + // flops in order to prevent optimizations on these status signals. + logic [Sp2VWidth-1:0] crypt_q_raw; + caliptra_prim_flop #( + .Width ( Sp2VWidth ), + .ResetValue ( Sp2VWidth'(SP2V_LOW) ) + ) u_crypt_regs ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .d_i ( crypt_d ), + .q_o ( crypt_q_raw ) + ); + + logic [Sp2VWidth-1:0] dec_key_gen_q_raw; + caliptra_prim_flop #( + .Width ( Sp2VWidth ), + .ResetValue ( Sp2VWidth'(SP2V_LOW) ) + ) u_dec_key_gen_regs ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .d_i ( dec_key_gen_d ), + .q_o ( dec_key_gen_q_raw ) + ); + + // We use vectors of sparsely encoded signals to reduce code duplication. + localparam int unsigned NumSp2VSig = 8; + sp2v_e [NumSp2VSig-1:0] sp2v_sig; + sp2v_e [NumSp2VSig-1:0] sp2v_sig_chk; + logic [NumSp2VSig-1:0][Sp2VWidth-1:0] sp2v_sig_chk_raw; + logic [NumSp2VSig-1:0] sp2v_sig_err; + + assign sp2v_sig[0] = in_valid_i; + assign sp2v_sig[1] = out_ready_i; + assign sp2v_sig[2] = crypt_i; + assign sp2v_sig[3] = dec_key_gen_i; + assign sp2v_sig[4] = sp2v_e'(crypt_q_raw); + assign sp2v_sig[5] = sp2v_e'(dec_key_gen_q_raw); + assign sp2v_sig[6] = sub_bytes_out_req_i; + assign sp2v_sig[7] = key_expand_out_req_i; + + // All signals inside sp2v_sig except for sub_bytes/key_expand_out_req_i are driven and consumed + // by multi-rail FSMs. + localparam bit [NumSp2VSig-1:0] Sp2VEnSecBuf = 8'b1100_0000; + + // Individually check sparsely encoded signals. + for (genvar i = 0; i < NumSp2VSig; i++) begin : gen_sel_buf_chk + aes_sel_buf_chk #( + .Num ( Sp2VNum ), + .Width ( Sp2VWidth ), + .EnSecBuf ( Sp2VEnSecBuf[i] ) + ) u_aes_sp2v_sig_buf_chk_i ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .sel_i ( sp2v_sig[i] ), + .sel_o ( sp2v_sig_chk_raw[i] ), + .err_o ( sp2v_sig_err[i] ) + ); + assign sp2v_sig_chk[i] = sp2v_e'(sp2v_sig_chk_raw[i]); + end + + assign in_valid = sp2v_sig_chk[0]; + assign out_ready = sp2v_sig_chk[1]; + assign crypt = sp2v_sig_chk[2]; + assign dec_key_gen = sp2v_sig_chk[3]; + assign crypt_q = sp2v_sig_chk[4]; + assign dec_key_gen_q = sp2v_sig_chk[5]; + assign sub_bytes_out_req = sp2v_sig_chk[6]; + assign key_expand_out_req = sp2v_sig_chk[7]; + + // Collect encoding errors. + // We instantiate the checker modules as close as possible to where the sparsely encoded signals + // are used. Here, we collect also encoding errors detected in other places of the cipher core. + assign sp_enc_err = |sp2v_sig_err | sp_enc_err_i; + + //////////////// + // Assertions // + //////////////// + + // Selectors must be known/valid + `CALIPTRA_ASSERT(AesCiphOpValid, cfg_valid_i |-> op_i inside { + CIPH_FWD, + CIPH_INV + }) + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/aes_cipher_control_fsm.sv b/designs/Caliptra/src/caliptra-rtl/aes_cipher_control_fsm.sv new file mode 100644 index 0000000..6de2acb --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/aes_cipher_control_fsm.sv @@ -0,0 +1,515 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// AES cipher core control FSM +// +// This module contains the AES cipher core control FSM. + +`include "caliptra_prim_assert.sv" + +module aes_cipher_control_fsm import aes_pkg::*; +#( + parameter bit SecMasking = 0, + parameter sbox_impl_e SecSBoxImpl = SBoxImplDom +) ( + input logic clk_i, + input logic rst_ni, + + // Input handshake signals + input logic in_valid_i, // Sparsify using multi-rail. + output logic in_ready_o, // Sparsify using multi-rail. + + // Output handshake signals + output logic out_valid_o, // Sparsify using multi-rail. + input logic out_ready_i, // Sparsify using multi-rail. + + // Control and sync signals + input logic cfg_valid_i, // Used for SVAs only. + input ciph_op_e op_i, + input key_len_e key_len_i, + input logic crypt_i, // Sparsify using multi-rail. + input logic dec_key_gen_i, // Sparsify using multi-rail. + input logic prng_reseed_i, + input logic key_clear_i, + input logic data_out_clear_i, + input logic mux_sel_err_i, + input logic sp_enc_err_i, + input logic rnd_ctr_err_i, + input logic op_err_i, + input logic alert_fatal_i, + output logic alert_o, + + // Control signals for masking PRNG + output logic prng_update_o, + output logic prng_reseed_req_o, + input logic prng_reseed_ack_i, + + // Control and sync signals for cipher data path + output state_sel_e state_sel_o, + output logic state_we_o, // Sparsify using multi-rail. + output logic sub_bytes_en_o, // Sparsify using multi-rail. + input logic sub_bytes_out_req_i, // Sparsify using multi-rail. + output logic sub_bytes_out_ack_o, // Sparsify using multi-rail. + output add_rk_sel_e add_rk_sel_o, + + // Control and sync signals for key expand data path + output key_full_sel_e key_full_sel_o, + output logic key_full_we_o, // Sparsify using multi-rail. + output key_dec_sel_e key_dec_sel_o, + output logic key_dec_we_o, // Sparsify using multi-rail. + output logic key_expand_en_o, // Sparsify using multi-rail. + input logic key_expand_out_req_i, // Sparsify using multi-rail. + output logic key_expand_out_ack_o, // Sparsify using multi-rail. + output logic key_expand_clear_o, + output logic [3:0] rnd_ctr_o, + output key_words_sel_e key_words_sel_o, + output round_key_sel_e round_key_sel_o, + + // Register signals + input logic crypt_q_i, // Sparsify using multi-rail. + output logic crypt_d_o, // Sparsify using multi-rail. + input logic dec_key_gen_q_i, // Sparsify using multi-rail. + output logic dec_key_gen_d_o, // Sparsify using multi-rail. + input logic prng_reseed_q_i, + output logic prng_reseed_d_o, + input logic key_clear_q_i, + output logic key_clear_d_o, + input logic data_out_clear_q_i, + output logic data_out_clear_d_o +); + + // cfg_valid_i is used for SVAs only. + logic unused_cfg_valid; + assign unused_cfg_valid = cfg_valid_i; + + // Tie off unused inputs. + if (!SecMasking) begin : gen_unused_prng_reseed + logic unused_prng_reseed; + assign unused_prng_reseed = prng_reseed_i; + end + + // Signals + aes_cipher_ctrl_e aes_cipher_ctrl_ns, aes_cipher_ctrl_cs; + logic advance; + logic [2:0] cyc_ctr_d, cyc_ctr_q; + logic cyc_ctr_expr; + logic prng_reseed_done_d, prng_reseed_done_q; + logic [3:0] rnd_ctr_d, rnd_ctr_q; + logic [3:0] num_rounds_d, num_rounds_q; + logic [3:0] num_rounds_regular; + + // Use separate signal for number of regular rounds. + assign num_rounds_regular = num_rounds_q - 4'd1; + + // FSM + always_comb begin : aes_cipher_ctrl_fsm + + // Handshake signals + in_ready_o = 1'b0; + out_valid_o = 1'b0; + + // Masking PRNG signals + prng_update_o = 1'b0; + prng_reseed_req_o = 1'b0; + + // Cipher data path + state_sel_o = STATE_ROUND; + state_we_o = 1'b0; + add_rk_sel_o = ADD_RK_ROUND; + sub_bytes_en_o = 1'b0; + sub_bytes_out_ack_o = 1'b0; + + // Key expand data path + key_full_sel_o = KEY_FULL_ROUND; + key_full_we_o = 1'b0; + key_dec_sel_o = KEY_DEC_EXPAND; + key_dec_we_o = 1'b0; + key_expand_en_o = 1'b0; + key_expand_out_ack_o = 1'b0; + key_expand_clear_o = 1'b0; + key_words_sel_o = KEY_WORDS_ZERO; + round_key_sel_o = ROUND_KEY_DIRECT; + + // FSM + aes_cipher_ctrl_ns = aes_cipher_ctrl_cs; + num_rounds_d = num_rounds_q; + rnd_ctr_d = rnd_ctr_q; + crypt_d_o = crypt_q_i; + dec_key_gen_d_o = dec_key_gen_q_i; + prng_reseed_d_o = prng_reseed_q_i; + key_clear_d_o = key_clear_q_i; + data_out_clear_d_o = data_out_clear_q_i; + prng_reseed_done_d = prng_reseed_done_q | prng_reseed_ack_i; + advance = 1'b0; + cyc_ctr_d = (SecSBoxImpl == SBoxImplDom) ? cyc_ctr_q + 3'd1 : 3'd0; + + // Alert + alert_o = 1'b0; + + unique case (aes_cipher_ctrl_cs) + + CIPHER_CTRL_IDLE: begin + cyc_ctr_d = 3'd0; + + // Signal that we are ready, wait for handshake. + in_ready_o = 1'b1; + if (in_valid_i) begin + if (SecMasking && prng_reseed_i && !dec_key_gen_i && !crypt_i) begin + // Reseed the masking PRNG without starting encryption/decryption or generation of the + // start key for decryption. + prng_reseed_d_o = 1'b1; + prng_reseed_done_d = 1'b0; + aes_cipher_ctrl_ns = CIPHER_CTRL_PRNG_RESEED; + + end else if (key_clear_i || data_out_clear_i) begin + // Clear internal key registers. The cipher core muxes are used to clear the data + // output registers. + key_clear_d_o = key_clear_i; + data_out_clear_d_o = data_out_clear_i; + + // To clear the data output registers, we must first clear the state. + aes_cipher_ctrl_ns = data_out_clear_i ? CIPHER_CTRL_CLEAR_S : CIPHER_CTRL_CLEAR_KD; + + end else if (dec_key_gen_i || crypt_i) begin + // Start encryption/decryption or generation of start key for decryption. + crypt_d_o = ~dec_key_gen_i & crypt_i; + dec_key_gen_d_o = dec_key_gen_i; + + // Latch whether we shall reseed the masking PRNG. + prng_reseed_d_o = SecMasking & prng_reseed_i; + + // Load input data to state + state_sel_o = dec_key_gen_i ? STATE_CLEAR : STATE_INIT; + state_we_o = 1'b1; + + // Make the masking PRNG advance. The current pseudo-random data is used to mask the + // input data. + prng_update_o = SecMasking; + + // Init key expand + key_expand_clear_o = 1'b1; + + // Load full key + key_full_sel_o = dec_key_gen_i ? KEY_FULL_ENC_INIT : + (op_i == CIPH_FWD) ? KEY_FULL_ENC_INIT : + (op_i == CIPH_INV) ? KEY_FULL_DEC_INIT : + KEY_FULL_ENC_INIT; + key_full_we_o = 1'b1; + + // Load num_rounds, initialize round counter. + num_rounds_d = (key_len_i == AES_128) ? 4'd10 : + (key_len_i == AES_192) ? 4'd12 : + 4'd14; + rnd_ctr_d = '0; + aes_cipher_ctrl_ns = CIPHER_CTRL_INIT; + + end else begin + // Handshake without a valid command. We should never get here. If we do (e.g. via a + // malicious glitch), error out immediately. + aes_cipher_ctrl_ns = CIPHER_CTRL_ERROR; + end + end + end + + CIPHER_CTRL_INIT: begin + // Initial round: just add key to state + add_rk_sel_o = ADD_RK_INIT; + + // Select key words for initial add_round_key + key_words_sel_o = (dec_key_gen_q_i) ? KEY_WORDS_ZERO : + (key_len_i == AES_128) ? KEY_WORDS_0123 : + (key_len_i == AES_192 && op_i == CIPH_FWD) ? KEY_WORDS_0123 : + (key_len_i == AES_192 && op_i == CIPH_INV) ? KEY_WORDS_2345 : + (key_len_i == AES_256 && op_i == CIPH_FWD) ? KEY_WORDS_0123 : + (key_len_i == AES_256 && op_i == CIPH_INV) ? KEY_WORDS_4567 : KEY_WORDS_ZERO; + + // Clear masking PRNG reseed status. + prng_reseed_done_d = 1'b0; + + // AES-256 has two round keys available right from beginning. Pseudo-random data is + // required by KeyExpand only. + if (key_len_i != AES_256) begin + // Advance in sync with KeyExpand. Based on the S-Box implementation, it can take + // multiple cycles to finish. Wait for handshake. The DOM S-Boxes consume fresh PRD + // only in the first clock cycle and that PRD is taken from the buffer stage updated + // based on key_full_we_o. The PRNG itself is updated in every clock cycle to increase + // the noise. + advance = key_expand_out_req_i & cyc_ctr_expr; + prng_update_o = SecMasking; + key_expand_en_o = 1'b1; + if (advance) begin + key_expand_out_ack_o = 1'b1; + state_we_o = ~dec_key_gen_q_i; + key_full_we_o = 1'b1; + rnd_ctr_d = rnd_ctr_q + 4'b0001; + cyc_ctr_d = 3'd0; + aes_cipher_ctrl_ns = CIPHER_CTRL_ROUND; + end + end else begin + prng_update_o = SecMasking; + state_we_o = ~dec_key_gen_q_i; + rnd_ctr_d = rnd_ctr_q + 4'b0001; + cyc_ctr_d = 3'd0; + aes_cipher_ctrl_ns = CIPHER_CTRL_ROUND; + end + end + + CIPHER_CTRL_ROUND: begin + // Normal rounds + + // Select key words for add_round_key + key_words_sel_o = (dec_key_gen_q_i) ? KEY_WORDS_ZERO : + (key_len_i == AES_128) ? KEY_WORDS_0123 : + (key_len_i == AES_192 && op_i == CIPH_FWD) ? KEY_WORDS_2345 : + (key_len_i == AES_192 && op_i == CIPH_INV) ? KEY_WORDS_0123 : + (key_len_i == AES_256 && op_i == CIPH_FWD) ? KEY_WORDS_4567 : + (key_len_i == AES_256 && op_i == CIPH_INV) ? KEY_WORDS_0123 : KEY_WORDS_ZERO; + + // Keep requesting PRNG reseeding until it is acknowledged. + prng_reseed_req_o = SecMasking & prng_reseed_q_i & ~prng_reseed_done_q; + + // Select round key: direct or mixed (equivalent inverse cipher) + round_key_sel_o = (op_i == CIPH_FWD) ? ROUND_KEY_DIRECT : + (op_i == CIPH_INV) ? ROUND_KEY_MIXED : ROUND_KEY_DIRECT; + + // Advance in sync with SubBytes and KeyExpand. Based on the S-Box implementation, both can + // take multiple cycles to finish. Wait for handshake. The DOM S-Boxes consume fresh PRD + // only in the first clock cycle and that PRD is taken from the buffer stages updated + // with state_we_o / based on key_full_we_o. The PRNG itself is updated in every clock + // cycle to increase the noise. + advance = key_expand_out_req_i & cyc_ctr_expr & (dec_key_gen_q_i | sub_bytes_out_req_i); + prng_update_o = SecMasking; + sub_bytes_en_o = ~dec_key_gen_q_i; + key_expand_en_o = 1'b1; + + if (advance) begin + sub_bytes_out_ack_o = ~dec_key_gen_q_i; + key_expand_out_ack_o = 1'b1; + + state_we_o = ~dec_key_gen_q_i; + key_full_we_o = 1'b1; + + // Update round + rnd_ctr_d = rnd_ctr_q + 4'b0001; + cyc_ctr_d = 3'd0; + + // Are we doing the last regular round? + if (rnd_ctr_q >= num_rounds_regular) begin + aes_cipher_ctrl_ns = CIPHER_CTRL_FINISH; + + if (dec_key_gen_q_i) begin + // Write decryption key. + key_dec_we_o = 1'b1; + + // Indicate that we are done, try to perform the handshake. But we don't wait here. + // If we don't get the handshake now, we will wait in the finish state. When using + // masking, we only finish if the masking PRNG has been reseeded. + out_valid_o = SecMasking ? (prng_reseed_q_i ? prng_reseed_done_q : 1'b1) : 1'b1; + if (out_valid_o && out_ready_i) begin + // Go to idle state directly. + dec_key_gen_d_o = 1'b0; + prng_reseed_d_o = 1'b0; + aes_cipher_ctrl_ns = CIPHER_CTRL_IDLE; + end + end + end // rnd_ctr_q + end // SubBytes/KeyExpand REQ/ACK + end + + CIPHER_CTRL_FINISH: begin + // Final round + + // Select key words for add_round_key + key_words_sel_o = (dec_key_gen_q_i) ? KEY_WORDS_ZERO : + (key_len_i == AES_128) ? KEY_WORDS_0123 : + (key_len_i == AES_192 && op_i == CIPH_FWD) ? KEY_WORDS_2345 : + (key_len_i == AES_192 && op_i == CIPH_INV) ? KEY_WORDS_0123 : + (key_len_i == AES_256 && op_i == CIPH_FWD) ? KEY_WORDS_4567 : + (key_len_i == AES_256 && op_i == CIPH_INV) ? KEY_WORDS_0123 : KEY_WORDS_ZERO; + + // Skip mix_columns + add_rk_sel_o = ADD_RK_FINAL; + + // Keep requesting PRNG reseeding until it is acknowledged. + prng_reseed_req_o = SecMasking & prng_reseed_q_i & ~prng_reseed_done_q; + + // SEC_CM: DATA_REG.KEY.SCA + // Once we're done, we won't need the state anymore. We actually clear it when progressing + // to the next state. + state_sel_o = STATE_CLEAR; + + // SEC_CM: DATA_REG.LOCAL_ESC + // Advance in sync with SubBytes. Based on the S-Box implementation, it can take multiple + // cycles to finish. Only indicate that we are done if: + // - we have valid output (SubBytes finished), + // - the masking PRNG has been reseeded (if masking is used), + // - all mux selector signals are valid (don't release data in case of errors), and + // - all sparsely encoded signals are valid (don't release data in case of errors). + // Perform both handshakes simultaneously. + advance = (sub_bytes_out_req_i & cyc_ctr_expr) | dec_key_gen_q_i; + sub_bytes_en_o = ~dec_key_gen_q_i; + out_valid_o = (mux_sel_err_i || sp_enc_err_i || op_err_i) ? 1'b0 : + SecMasking ? (prng_reseed_q_i ? prng_reseed_done_q & advance : advance) : advance; + + // Stop updating the cycle counter once we have valid output. + cyc_ctr_d = + (SecSBoxImpl == SBoxImplDom) ? (!advance ? cyc_ctr_q + 3'd1 : cyc_ctr_q) : 3'd0; + + // The DOM S-Boxes consume fresh PRD only in the first clock cycle and that PRD is taken + // from the buffer stages updated with state_we_o / based on key_full_we_o. The PRNG itself + // is updated in every but the last processing clock cycle to increase the noise. Once the + // processing is all done (e.g. if we're just waiting for the PRNG reseeding to finish or + // if we're waiting for out_ready_i), the PRNG is no longer updated to save power. In the + // very last clock cycle, we update the PRNG again to get ready for the next block. + prng_update_o = + ((SecSBoxImpl == SBoxImplDom) ? !advance : 1'b0) | (out_valid_o & out_ready_i); + + if (out_valid_o && out_ready_i) begin + sub_bytes_out_ack_o = ~dec_key_gen_q_i; + + // Clear the state. + state_we_o = 1'b1; + crypt_d_o = 1'b0; + cyc_ctr_d = 3'd0; + // If we were generating the decryption key and didn't get the handshake in the last + // regular round, we should clear dec_key_gen now. + dec_key_gen_d_o = 1'b0; + prng_reseed_d_o = 1'b0; + aes_cipher_ctrl_ns = CIPHER_CTRL_IDLE; + end + end + + CIPHER_CTRL_PRNG_RESEED: begin + // Keep requesting PRNG reseeding until it is acknowledged. + prng_reseed_req_o = prng_reseed_q_i & ~prng_reseed_done_q; + + // Don't update the cycle counter as we don't need it. + cyc_ctr_d = 3'd0; + + // Once we're done, wait for handshake. + out_valid_o = prng_reseed_done_q; + if (out_valid_o && out_ready_i) begin + prng_reseed_d_o = 1'b0; + aes_cipher_ctrl_ns = CIPHER_CTRL_IDLE; + end + end + + CIPHER_CTRL_CLEAR_S: begin + // Clear the state with pseudo-random data. + state_we_o = 1'b1; + state_sel_o = STATE_CLEAR; + aes_cipher_ctrl_ns = CIPHER_CTRL_CLEAR_KD; + end + + CIPHER_CTRL_CLEAR_KD: begin + // Clear internal key registers and/or external data output registers. + if (key_clear_q_i) begin + key_full_sel_o = KEY_FULL_CLEAR; + key_full_we_o = 1'b1; + key_dec_sel_o = KEY_DEC_CLEAR; + key_dec_we_o = 1'b1; + end + if (data_out_clear_q_i) begin + // Forward the state (previously cleared with psuedo-random data). + // SEC_CM: DATA_REG.SEC_WIPE + add_rk_sel_o = ADD_RK_INIT; + key_words_sel_o = KEY_WORDS_ZERO; + round_key_sel_o = ROUND_KEY_DIRECT; + end + // Indicate that we are done, wait for handshake. + out_valid_o = 1'b1; + if (out_ready_i) begin + key_clear_d_o = 1'b0; + data_out_clear_d_o = 1'b0; + aes_cipher_ctrl_ns = CIPHER_CTRL_IDLE; + end + end + + CIPHER_CTRL_ERROR: begin + // SEC_CM: CIPHER.FSM.LOCAL_ESC + // Terminal error state + alert_o = 1'b1; + end + + // We should never get here. If we do (e.g. via a malicious glitch), error out immediately. + default: begin + aes_cipher_ctrl_ns = CIPHER_CTRL_ERROR; + alert_o = 1'b1; + end + endcase + + // Unconditionally jump into the terminal error state in case a mux selector or a sparsely + // encoded signal becomes invalid, in case we have detected a fault in the round counter, + // or if a fatal alert has been triggered. + if (mux_sel_err_i || sp_enc_err_i || rnd_ctr_err_i || op_err_i || alert_fatal_i) begin + aes_cipher_ctrl_ns = CIPHER_CTRL_ERROR; + end + end + + // SEC_CM: CIPHER.FSM.SPARSE + `CALIPTRA_PRIM_FLOP_SPARSE_FSM(u_state_regs, aes_cipher_ctrl_ns, + aes_cipher_ctrl_cs, aes_cipher_ctrl_e, CIPHER_CTRL_IDLE) + + always_ff @(posedge clk_i or negedge rst_ni) begin : reg_fsm + if (!rst_ni) begin + prng_reseed_done_q <= 1'b0; + rnd_ctr_q <= '0; + num_rounds_q <= '0; + end else begin + prng_reseed_done_q <= prng_reseed_done_d; + rnd_ctr_q <= rnd_ctr_d; + num_rounds_q <= num_rounds_d; + end + end + + assign rnd_ctr_o = rnd_ctr_q; + + if (SecSBoxImpl == SBoxImplDom) begin : gen_cyc_ctr + always_ff @(posedge clk_i or negedge rst_ni) begin : reg_cyc_ctr + if (!rst_ni) begin + cyc_ctr_q <= 3'd0; + end else begin + cyc_ctr_q <= cyc_ctr_d; + end + end + assign cyc_ctr_expr = cyc_ctr_q >= 3'd4; + end else begin : gen_no_cyc_ctr + logic [2:0] unused_cyc_ctr; + assign cyc_ctr_q = cyc_ctr_d; + assign unused_cyc_ctr = cyc_ctr_q; + assign cyc_ctr_expr = 1'b1; + end + + //////////////// + // Assertions // + //////////////// + + // Create a lint error to reduce the risk of accidentally disabling the masking. + `CALIPTRA_ASSERT_STATIC_LINT_ERROR(AesCipherControlFsmSecMaskingNonDefault, SecMasking == 1) + + // Create a lint error to reduce the risk of accidentally using a less secure SBox + // implementation. + `CALIPTRA_ASSERT_STATIC_LINT_ERROR(AesCipherControlFsmSecSBoxImplNonDefault, SecSBoxImpl == SBoxImplDom) + + // Selectors must be known/valid + `CALIPTRA_ASSERT(AesCiphOpValid, cfg_valid_i |-> op_i inside { + CIPH_FWD, + CIPH_INV + }) + `CALIPTRA_ASSERT(AesKeyLenValid, cfg_valid_i |-> key_len_i inside { + AES_128, + AES_192, + AES_256 + }) + `CALIPTRA_ASSERT(AesCipherControlStateValid, !alert_o |-> aes_cipher_ctrl_cs inside { + CIPHER_CTRL_IDLE, + CIPHER_CTRL_INIT, + CIPHER_CTRL_ROUND, + CIPHER_CTRL_FINISH, + CIPHER_CTRL_PRNG_RESEED, + CIPHER_CTRL_CLEAR_S, + CIPHER_CTRL_CLEAR_KD + }) + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/aes_cipher_control_fsm_n.sv b/designs/Caliptra/src/caliptra-rtl/aes_cipher_control_fsm_n.sv new file mode 100644 index 0000000..37e3378 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/aes_cipher_control_fsm_n.sv @@ -0,0 +1,400 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// AES cipher core control FSM +// +// This module contains the AES cipher core control FSM operating on and producing the negated +// values of important control signals. This is achieved by: +// - instantiating the regular AES cipher core control FSM operating on and producing the positive +// values of these signals, and +// - inverting these signals between the regular FSM and the caliptra_prim_buf synthesis barriers. +// Synthesis tools will then push the inverters into the actual FSM. + +module aes_cipher_control_fsm_n import aes_pkg::*; +#( + parameter bit SecMasking = 0, + parameter sbox_impl_e SecSBoxImpl = SBoxImplDom +) ( + input logic clk_i, + input logic rst_ni, + + // Input handshake signals + input logic in_valid_ni, // Sparsify using multi-rail. + output logic in_ready_no, // Sparsify using multi-rail. + + // Output handshake signals + output logic out_valid_no, // Sparsify using multi-rail. + input logic out_ready_ni, // Sparsify using multi-rail. + + // Control and sync signals + input logic cfg_valid_i, // Used for SVAs only. + input ciph_op_e op_i, + input key_len_e key_len_i, + input logic crypt_ni, // Sparsify using multi-rail. + input logic dec_key_gen_ni, // Sparsify using multi-rail. + input logic prng_reseed_i, + input logic key_clear_i, + input logic data_out_clear_i, + input logic mux_sel_err_i, + input logic sp_enc_err_i, + input logic rnd_ctr_err_i, + input logic op_err_i, + input logic alert_fatal_i, + output logic alert_o, + + // Control signals for masking PRNG + output logic prng_update_o, + output logic prng_reseed_req_o, + input logic prng_reseed_ack_i, + + // Control and sync signals for cipher data path + output state_sel_e state_sel_o, + output logic state_we_no, // Sparsify using multi-rail. + output logic sub_bytes_en_no, // Sparsify using multi-rail. + input logic sub_bytes_out_req_ni, // Sparsify using multi-rail. + output logic sub_bytes_out_ack_no, // Sparsify using multi-rail. + output add_rk_sel_e add_rk_sel_o, + + // Control and sync signals for key expand data path + output key_full_sel_e key_full_sel_o, + output logic key_full_we_no, // Sparsify using multi-rail. + output key_dec_sel_e key_dec_sel_o, + output logic key_dec_we_no, // Sparsify using multi-rail. + output logic key_expand_en_no, // Sparsify using multi-rail. + input logic key_expand_out_req_ni, // Sparsify using multi-rail. + output logic key_expand_out_ack_no, // Sparsify using multi-rail. + output logic key_expand_clear_o, + output logic [3:0] rnd_ctr_o, + output key_words_sel_e key_words_sel_o, + output round_key_sel_e round_key_sel_o, + + // Register signals + input logic crypt_q_ni, // Sparsify using multi-rail. + output logic crypt_d_no, // Sparsify using multi-rail. + input logic dec_key_gen_q_ni, // Sparsify using multi-rail. + output logic dec_key_gen_d_no, // Sparsify using multi-rail. + input logic prng_reseed_q_i, + output logic prng_reseed_d_o, + input logic key_clear_q_i, + output logic key_clear_d_o, + input logic data_out_clear_q_i, + output logic data_out_clear_d_o +); + + ///////////////////// + // Input Buffering // + ///////////////////// + + localparam int NumInBufBits = $bits({ + in_valid_ni, + out_ready_ni, + cfg_valid_i, + op_i, + key_len_i, + crypt_ni, + dec_key_gen_ni, + prng_reseed_i, + key_clear_i, + data_out_clear_i, + mux_sel_err_i, + sp_enc_err_i, + rnd_ctr_err_i, + op_err_i, + alert_fatal_i, + prng_reseed_ack_i, + sub_bytes_out_req_ni, + key_expand_out_req_ni, + crypt_q_ni, + dec_key_gen_q_ni, + prng_reseed_q_i, + key_clear_q_i, + data_out_clear_q_i + }); + + logic [NumInBufBits-1:0] in, in_buf; + + assign in = { + in_valid_ni, + out_ready_ni, + cfg_valid_i, + op_i, + key_len_i, + crypt_ni, + dec_key_gen_ni, + prng_reseed_i, + key_clear_i, + data_out_clear_i, + mux_sel_err_i, + sp_enc_err_i, + rnd_ctr_err_i, + op_err_i, + alert_fatal_i, + prng_reseed_ack_i, + sub_bytes_out_req_ni, + key_expand_out_req_ni, + crypt_q_ni, + dec_key_gen_q_ni, + prng_reseed_q_i, + key_clear_q_i, + data_out_clear_q_i + }; + + // This primitive is used to place a size-only constraint on the + // buffers to act as a synthesis optimization barrier. + caliptra_prim_buf #( + .Width(NumInBufBits) + ) u_caliptra_prim_buf_in ( + .in_i(in), + .out_o(in_buf) + ); + + logic in_valid_n; + logic out_ready_n; + logic cfg_valid; + ciph_op_e op; + logic [$bits(op)-1:0] op_raw; + key_len_e key_len; + logic crypt_n; + logic dec_key_gen_n; + logic prng_reseed; + logic key_clear; + logic data_out_clear; + logic mux_sel_err; + logic sp_enc_err; + logic rnd_ctr_err; + logic op_err; + logic alert_fatal; + logic prng_reseed_ack; + logic sub_bytes_out_req_n; + logic key_expand_out_req_n; + logic crypt_q_n; + logic dec_key_gen_q_n; + logic prng_reseed_q; + logic key_clear_q; + logic data_out_clear_q; + + assign {in_valid_n, + out_ready_n, + cfg_valid, + op_raw, + key_len, + crypt_n, + dec_key_gen_n, + prng_reseed, + key_clear, + data_out_clear, + mux_sel_err, + sp_enc_err, + rnd_ctr_err, + op_err, + alert_fatal, + prng_reseed_ack, + sub_bytes_out_req_n, + key_expand_out_req_n, + crypt_q_n, + dec_key_gen_q_n, + prng_reseed_q, + key_clear_q, + data_out_clear_q} = in_buf; + + assign op = ciph_op_e'(op_raw); + + // Intermediate output signals + logic in_ready; + logic out_valid; + logic alert; + logic prng_update; + logic prng_reseed_req; + state_sel_e state_sel; + logic state_we; + logic sub_bytes_en; + logic sub_bytes_out_ack; + add_rk_sel_e add_rk_sel; + key_full_sel_e key_full_sel; + logic key_full_we; + key_dec_sel_e key_dec_sel; + logic key_dec_we; + logic key_expand_en; + logic key_expand_out_ack; + logic key_expand_clear; + key_words_sel_e key_words_sel; + round_key_sel_e round_key_sel; + logic [3:0] rnd_ctr; + logic crypt_d; + logic dec_key_gen_d; + logic prng_reseed_d; + logic key_clear_d; + logic data_out_clear_d; + + ///////////////// + // Regular FSM // + ///////////////// + + // The regular FSM operates on and produces the positive values of important control signals. + // Invert *_n input signals here to get the positive values for the regular FSM. To obtain the + // negated outputs, important output signals are inverted further below. Thanks to the caliptra_prim_buf + // synthesis optimization barriers, tools will push the inverters into the regular FSM. + aes_cipher_control_fsm #( + .SecMasking ( SecMasking ), + .SecSBoxImpl ( SecSBoxImpl ) + ) u_aes_cipher_control_fsm ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + + .in_valid_i ( ~in_valid_n ), // Invert for regular FSM. + .in_ready_o ( in_ready ), // Invert below for negated output. + + .out_valid_o ( out_valid ), // Invert below for negated output. + .out_ready_i ( ~out_ready_n ), // Invert for regular FSM. + + .cfg_valid_i ( cfg_valid ), + .op_i ( op ), + .key_len_i ( key_len ), + .crypt_i ( ~crypt_n ), // Invert for regular FSM. + .dec_key_gen_i ( ~dec_key_gen_n ), // Invert for regular FSM. + .prng_reseed_i ( prng_reseed ), + .key_clear_i ( key_clear ), + .data_out_clear_i ( data_out_clear ), + .mux_sel_err_i ( mux_sel_err ), + .sp_enc_err_i ( sp_enc_err ), + .rnd_ctr_err_i ( rnd_ctr_err ), + .op_err_i ( op_err ), + .alert_fatal_i ( alert_fatal ), + .alert_o ( alert ), + + .prng_update_o ( prng_update ), + .prng_reseed_req_o ( prng_reseed_req ), + .prng_reseed_ack_i ( prng_reseed_ack ), + + .state_sel_o ( state_sel ), + .state_we_o ( state_we ), // Invert below for negated output. + .sub_bytes_en_o ( sub_bytes_en ), // Invert below for negated output. + .sub_bytes_out_req_i ( ~sub_bytes_out_req_n ), // Invert for regular FSM. + .sub_bytes_out_ack_o ( sub_bytes_out_ack ), // Invert below for negated output. + .add_rk_sel_o ( add_rk_sel ), + + .key_full_sel_o ( key_full_sel ), + .key_full_we_o ( key_full_we ), // Invert below for negated output. + .key_dec_sel_o ( key_dec_sel ), + .key_dec_we_o ( key_dec_we ), // Invert below for negated output. + .key_expand_en_o ( key_expand_en ), // Invert below for negated output. + .key_expand_out_req_i ( ~key_expand_out_req_n ), // Invert for regular FSM. + .key_expand_out_ack_o ( key_expand_out_ack ), // Invert below for negated output. + .key_expand_clear_o ( key_expand_clear ), + .rnd_ctr_o ( rnd_ctr ), + .key_words_sel_o ( key_words_sel ), + .round_key_sel_o ( round_key_sel ), + + .crypt_q_i ( ~crypt_q_n ), // Invert for regular FSM. + .crypt_d_o ( crypt_d ), // Invert below for negated output. + .dec_key_gen_q_i ( ~dec_key_gen_q_n ), // Invert for regular FSM. + .dec_key_gen_d_o ( dec_key_gen_d ), // Invert below for negated output. + .key_clear_q_i ( key_clear_q ), + .key_clear_d_o ( key_clear_d ), + .prng_reseed_q_i ( prng_reseed_q ), + .prng_reseed_d_o ( prng_reseed_d ), + .data_out_clear_q_i ( data_out_clear_q ), + .data_out_clear_d_o ( data_out_clear_d ) + ); + + ////////////////////// + // Output Buffering // + ////////////////////// + + localparam int NumOutBufBits = $bits({ + in_ready_no, + out_valid_no, + alert_o, + prng_update_o, + prng_reseed_req_o, + state_sel_o, + state_we_no, + sub_bytes_en_no, + sub_bytes_out_ack_no, + add_rk_sel_o, + key_full_sel_o, + key_full_we_no, + key_dec_sel_o, + key_dec_we_no, + key_expand_en_no, + key_expand_out_ack_no, + key_expand_clear_o, + rnd_ctr_o, + key_words_sel_o, + round_key_sel_o, + crypt_d_no, + dec_key_gen_d_no, + key_clear_d_o, + prng_reseed_d_o, + data_out_clear_d_o + }); + + logic [NumOutBufBits-1:0] out, out_buf; + + // Important output control signals need to be inverted here. Synthesis tools will push the + // inverters back into the regular FSM. + assign out = { + ~in_ready, + ~out_valid, + alert, + prng_update, + prng_reseed_req, + state_sel, + ~state_we, + ~sub_bytes_en, + ~sub_bytes_out_ack, + add_rk_sel, + key_full_sel, + ~key_full_we, + key_dec_sel, + ~key_dec_we, + ~key_expand_en, + ~key_expand_out_ack, + key_expand_clear, + rnd_ctr, + key_words_sel, + round_key_sel, + ~crypt_d, + ~dec_key_gen_d, + key_clear_d, + prng_reseed_d, + data_out_clear_d + }; + + // This primitive is used to place a size-only constraint on the + // buffers to act as a synthesis optimization barrier. + caliptra_prim_buf #( + .Width(NumOutBufBits) + ) u_caliptra_prim_buf_out ( + .in_i(out), + .out_o(out_buf) + ); + + assign {in_ready_no, + out_valid_no, + alert_o, + prng_update_o, + prng_reseed_req_o, + state_sel_o, + state_we_no, + sub_bytes_en_no, + sub_bytes_out_ack_no, + add_rk_sel_o, + key_full_sel_o, + key_full_we_no, + key_dec_sel_o, + key_dec_we_no, + key_expand_en_no, + key_expand_out_ack_no, + key_expand_clear_o, + rnd_ctr_o, + key_words_sel_o, + round_key_sel_o, + crypt_d_no, + dec_key_gen_d_no, + key_clear_d_o, + prng_reseed_d_o, + data_out_clear_d_o} = out_buf; + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/aes_cipher_control_fsm_p.sv b/designs/Caliptra/src/caliptra-rtl/aes_cipher_control_fsm_p.sv new file mode 100644 index 0000000..35fe4b2 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/aes_cipher_control_fsm_p.sv @@ -0,0 +1,390 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// AES cipher core control FSM +// +// This module contains the AES cipher core control FSM operating on +// and producing the positive values of important control signals. + +module aes_cipher_control_fsm_p import aes_pkg::*; +#( + parameter bit SecMasking = 0, + parameter sbox_impl_e SecSBoxImpl = SBoxImplDom +) ( + input logic clk_i, + input logic rst_ni, + + // Input handshake signals + input logic in_valid_i, // Sparsify using multi-rail. + output logic in_ready_o, // Sparsify using multi-rail. + + // Output handshake signals + output logic out_valid_o, // Sparsify using multi-rail. + input logic out_ready_i, // Sparsify using multi-rail. + + // Control and sync signals + input logic cfg_valid_i, // Used for SVAs only. + input ciph_op_e op_i, + input key_len_e key_len_i, + input logic crypt_i, // Sparsify using multi-rail. + input logic dec_key_gen_i, // Sparsify using multi-rail. + input logic prng_reseed_i, + input logic key_clear_i, + input logic data_out_clear_i, + input logic mux_sel_err_i, + input logic sp_enc_err_i, + input logic rnd_ctr_err_i, + input logic op_err_i, + input logic alert_fatal_i, + output logic alert_o, + + // Control signals for masking PRNG + output logic prng_update_o, + output logic prng_reseed_req_o, + input logic prng_reseed_ack_i, + + // Control and sync signals for cipher data path + output state_sel_e state_sel_o, + output logic state_we_o, // Sparsify using multi-rail. + output logic sub_bytes_en_o, // Sparsify using multi-rail. + input logic sub_bytes_out_req_i, // Sparsify using multi-rail. + output logic sub_bytes_out_ack_o, // Sparsify using multi-rail. + output add_rk_sel_e add_rk_sel_o, + + // Control and sync signals for key expand data path + output key_full_sel_e key_full_sel_o, + output logic key_full_we_o, // Sparsify using multi-rail. + output key_dec_sel_e key_dec_sel_o, + output logic key_dec_we_o, // Sparsify using multi-rail. + output logic key_expand_en_o, // Sparsify using multi-rail. + input logic key_expand_out_req_i, // Sparsify using multi-rail. + output logic key_expand_out_ack_o, // Sparsify using multi-rail. + output logic key_expand_clear_o, + output logic [3:0] rnd_ctr_o, + output key_words_sel_e key_words_sel_o, + output round_key_sel_e round_key_sel_o, + + // Register signals + input logic crypt_q_i, // Sparsify using multi-rail. + output logic crypt_d_o, // Sparsify using multi-rail. + input logic dec_key_gen_q_i, // Sparsify using multi-rail. + output logic dec_key_gen_d_o, // Sparsify using multi-rail. + input logic prng_reseed_q_i, + output logic prng_reseed_d_o, + input logic key_clear_q_i, + output logic key_clear_d_o, + input logic data_out_clear_q_i, + output logic data_out_clear_d_o +); + + ///////////////////// + // Input Buffering // + ///////////////////// + + localparam int NumInBufBits = $bits({ + in_valid_i, + out_ready_i, + cfg_valid_i, + op_i, + key_len_i, + crypt_i, + dec_key_gen_i, + prng_reseed_i, + key_clear_i, + data_out_clear_i, + mux_sel_err_i, + sp_enc_err_i, + rnd_ctr_err_i, + op_err_i, + alert_fatal_i, + prng_reseed_ack_i, + sub_bytes_out_req_i, + key_expand_out_req_i, + crypt_q_i, + dec_key_gen_q_i, + prng_reseed_q_i, + key_clear_q_i, + data_out_clear_q_i + }); + + logic [NumInBufBits-1:0] in, in_buf; + + assign in = { + in_valid_i, + out_ready_i, + cfg_valid_i, + op_i, + key_len_i, + crypt_i, + dec_key_gen_i, + prng_reseed_i, + key_clear_i, + data_out_clear_i, + mux_sel_err_i, + sp_enc_err_i, + rnd_ctr_err_i, + op_err_i, + alert_fatal_i, + prng_reseed_ack_i, + sub_bytes_out_req_i, + key_expand_out_req_i, + crypt_q_i, + dec_key_gen_q_i, + prng_reseed_q_i, + key_clear_q_i, + data_out_clear_q_i + }; + + // This primitive is used to place a size-only constraint on the + // buffers to act as a synthesis optimization barrier. + caliptra_prim_buf #( + .Width(NumInBufBits) + ) u_caliptra_prim_buf_in ( + .in_i(in), + .out_o(in_buf) + ); + + logic in_valid; + logic out_ready; + logic cfg_valid; + ciph_op_e op; + logic [$bits(op)-1:0] op_raw; + key_len_e key_len; + logic crypt; + logic dec_key_gen; + logic prng_reseed; + logic key_clear; + logic data_out_clear; + logic mux_sel_err; + logic sp_enc_err; + logic rnd_ctr_err; + logic op_err; + logic alert_fatal; + logic prng_reseed_ack; + logic sub_bytes_out_req; + logic key_expand_out_req; + logic crypt_q; + logic dec_key_gen_q; + logic prng_reseed_q; + logic key_clear_q; + logic data_out_clear_q; + + assign {in_valid, + out_ready, + cfg_valid, + op_raw, + key_len, + crypt, + dec_key_gen, + prng_reseed, + key_clear, + data_out_clear, + mux_sel_err, + sp_enc_err, + rnd_ctr_err, + op_err, + alert_fatal, + prng_reseed_ack, + sub_bytes_out_req, + key_expand_out_req, + crypt_q, + dec_key_gen_q, + prng_reseed_q, + key_clear_q, + data_out_clear_q} = in_buf; + + assign op = ciph_op_e'(op_raw); + + // Intermediate output signals + logic in_ready; + logic out_valid; + logic alert; + logic prng_update; + logic prng_reseed_req; + state_sel_e state_sel; + logic state_we; + logic sub_bytes_en; + logic sub_bytes_out_ack; + add_rk_sel_e add_rk_sel; + key_full_sel_e key_full_sel; + logic key_full_we; + key_dec_sel_e key_dec_sel; + logic key_dec_we; + logic key_expand_en; + logic key_expand_out_ack; + logic key_expand_clear; + logic [3:0] rnd_ctr; + key_words_sel_e key_words_sel; + round_key_sel_e round_key_sel; + logic crypt_d; + logic dec_key_gen_d; + logic prng_reseed_d; + logic key_clear_d; + logic data_out_clear_d; + + ///////////////// + // Regular FSM // + ///////////////// + + aes_cipher_control_fsm #( + .SecMasking ( SecMasking ), + .SecSBoxImpl ( SecSBoxImpl ) + ) u_aes_cipher_control_fsm ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + + .in_valid_i ( in_valid ), + .in_ready_o ( in_ready ), + + .out_valid_o ( out_valid ), + .out_ready_i ( out_ready ), + + .cfg_valid_i ( cfg_valid ), + .op_i ( op ), + .key_len_i ( key_len ), + .crypt_i ( crypt ), + .dec_key_gen_i ( dec_key_gen ), + .prng_reseed_i ( prng_reseed ), + .key_clear_i ( key_clear ), + .data_out_clear_i ( data_out_clear ), + .mux_sel_err_i ( mux_sel_err ), + .sp_enc_err_i ( sp_enc_err ), + .rnd_ctr_err_i ( rnd_ctr_err ), + .op_err_i ( op_err ), + .alert_fatal_i ( alert_fatal ), + .alert_o ( alert ), + + .prng_update_o ( prng_update ), + .prng_reseed_req_o ( prng_reseed_req ), + .prng_reseed_ack_i ( prng_reseed_ack ), + + .state_sel_o ( state_sel ), + .state_we_o ( state_we ), + .sub_bytes_en_o ( sub_bytes_en ), + .sub_bytes_out_req_i ( sub_bytes_out_req ), + .sub_bytes_out_ack_o ( sub_bytes_out_ack ), + .add_rk_sel_o ( add_rk_sel ), + + .key_full_sel_o ( key_full_sel ), + .key_full_we_o ( key_full_we ), + .key_dec_sel_o ( key_dec_sel ), + .key_dec_we_o ( key_dec_we ), + .key_expand_en_o ( key_expand_en ), + .key_expand_out_req_i ( key_expand_out_req ), + .key_expand_out_ack_o ( key_expand_out_ack ), + .key_expand_clear_o ( key_expand_clear ), + .rnd_ctr_o ( rnd_ctr ), + .key_words_sel_o ( key_words_sel ), + .round_key_sel_o ( round_key_sel ), + + .crypt_q_i ( crypt_q ), + .crypt_d_o ( crypt_d ), + .dec_key_gen_q_i ( dec_key_gen_q ), + .dec_key_gen_d_o ( dec_key_gen_d ), + .key_clear_q_i ( key_clear_q ), + .key_clear_d_o ( key_clear_d ), + .prng_reseed_q_i ( prng_reseed_q ), + .prng_reseed_d_o ( prng_reseed_d ), + .data_out_clear_q_i ( data_out_clear_q ), + .data_out_clear_d_o ( data_out_clear_d ) + ); + + ////////////////////// + // Output Buffering // + ////////////////////// + + localparam int NumOutBufBits = $bits({ + in_ready_o, + out_valid_o, + alert_o, + prng_update_o, + prng_reseed_req_o, + state_sel_o, + state_we_o, + sub_bytes_en_o, + sub_bytes_out_ack_o, + add_rk_sel_o, + key_full_sel_o, + key_full_we_o, + key_dec_sel_o, + key_dec_we_o, + key_expand_en_o, + key_expand_out_ack_o, + key_expand_clear_o, + rnd_ctr_o, + key_words_sel_o, + round_key_sel_o, + crypt_d_o, + dec_key_gen_d_o, + key_clear_d_o, + prng_reseed_d_o, + data_out_clear_d_o + }); + + logic [NumOutBufBits-1:0] out, out_buf; + + assign out = { + in_ready, + out_valid, + alert, + prng_update, + prng_reseed_req, + state_sel, + state_we, + sub_bytes_en, + sub_bytes_out_ack, + add_rk_sel, + key_full_sel, + key_full_we, + key_dec_sel, + key_dec_we, + key_expand_en, + key_expand_out_ack, + key_expand_clear, + rnd_ctr, + key_words_sel, + round_key_sel, + crypt_d, + dec_key_gen_d, + key_clear_d, + prng_reseed_d, + data_out_clear_d + }; + + // This primitive is used to place a size-only constraint on the + // buffers to act as a synthesis optimization barrier. + caliptra_prim_buf #( + .Width(NumOutBufBits) + ) u_caliptra_prim_buf_out ( + .in_i(out), + .out_o(out_buf) + ); + + assign {in_ready_o, + out_valid_o, + alert_o, + prng_update_o, + prng_reseed_req_o, + state_sel_o, + state_we_o, + sub_bytes_en_o, + sub_bytes_out_ack_o, + add_rk_sel_o, + key_full_sel_o, + key_full_we_o, + key_dec_sel_o, + key_dec_we_o, + key_expand_en_o, + key_expand_out_ack_o, + key_expand_clear_o, + rnd_ctr_o, + key_words_sel_o, + round_key_sel_o, + crypt_d_o, + dec_key_gen_d_o, + key_clear_d_o, + prng_reseed_d_o, + data_out_clear_d_o} = out_buf; + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/aes_cipher_core.sv b/designs/Caliptra/src/caliptra-rtl/aes_cipher_core.sv new file mode 100644 index 0000000..1b1dbeb --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/aes_cipher_core.sv @@ -0,0 +1,932 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// AES cipher core implementation +// +// This module contains the AES cipher core including, state register, full key and decryption key +// registers as well as key expand module and control unit. +// +// +// Masking +// ------- +// +// If the parameter "Masking" is set to one, first-order masking is applied to the entire +// cipher core including key expand module. For details, see Rivain et al., "Provably secure +// higher-order masking of AES" available at https://eprint.iacr.org/2010/441.pdf . +// +// +// Details on the data formats +// --------------------------- +// +// This implementation uses 4-dimensional SystemVerilog arrays to represent the AES state: +// +// logic [3:0][3:0][7:0] state_q [NumShares]; +// +// The fourth dimension (unpacked) corresponds to the different shares. The first element holds the +// (masked) data share whereas the other elements hold the masks (masked implementation only). +// The three packed dimensions correspond to the 128-bit state matrix per share. This +// implementation uses the same encoding as the Advanced Encryption Standard (AES) FIPS Publication +// 197 available at https://www.nist.gov/publications/advanced-encryption-standard-aes (see Section +// 3.4). An input sequence of 16 bytes (128-bit, left most byte is the first one) +// +// b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 b10 b11 b12 b13 b14 b15 +// +// is mapped to the state matrix as +// +// [ b0 b4 b8 b12 ] +// [ b1 b5 b9 b13 ] +// [ b2 b6 b10 b14 ] +// [ b3 b7 b11 b15 ] . +// +// This is mapped to three packed dimensions of SystemVerilog array as follows: +// - The first dimension corresponds to the rows. Thus, state_q[0] gives +// - The first row of the state matrix [ b0 b4 b8 b12 ], or +// - A 32-bit packed SystemVerilog array 32h'{ b12, b8, b4, b0 }. +// +// - The second dimension corresponds to the columns. To access complete columns, the state matrix +// must be transposed first. Thus state_transposed = aes_pkg::aes_transpose(state_q) and then +// state_transposed[1] gives +// - The second column of the state matrix [ b4 b5 b6 b7 ], or +// - A 32-bit packed SystemVerilog array 32h'{ b7, b6, b5, b4 }. +// +// - The third dimension corresponds to the bytes. +// +// Note that the CSRs are little-endian. The input sequence above is provided to 32-bit DATA_IN_0 - +// DATA_IN_3 registers as +// MSB LSB +// - DATA_IN_0 32h'{ b3 , b2 , b1 , b0 } +// - DATA_IN_1 32h'{ b7 , b6 , b4 , b4 } +// - DATA_IN_2 32h'{ b11, b10, b9 , b8 } +// - DATA_IN_3 32h'{ b15, b14, b13, b12 } . +// +// The input state can thus be obtained by transposing the content of the DATA_IN_0 - DATA_IN_3 +// registers. +// +// Similarly, the implementation uses a 3-dimensional array to represent the AES keys: +// +// logic [7:0][31:0] key_full_q [NumShares] +// +// The third dimension (unpacked) corresponds to the different shares. The first element holds the +// (masked) key share whereas the other elements hold the masks (masked implementation only). +// The two packed dimensions correspond to the 256-bit key per share. This implementation uses +// the same encoding as the Advanced Encryption Standard (AES) FIPS Publication +// 197 available at https://www.nist.gov/publications/advanced-encryption-standard-aes . +// +// The first packed dimension corresponds to the 8 key words. The second packed dimension +// corresponds to the 32 bits per key word. A key sequence of 32 bytes (256-bit, left most byte is +// the first one) +// +// b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 b10 b11 b12 b13 b14 b15 ... ... b28 b29 b30 b31 +// +// is mapped to the key words and registers (little-endian) as +// MSB LSB +// - KEY_SHARE0_0 32h'{ b3 , b2 , b1 , b0 } +// - KEY_SHARE0_1 32h'{ b7 , b6 , b4 , b4 } +// - KEY_SHARE0_2 32h'{ b11, b10, b9 , b8 } +// - KEY_SHARE0_3 32h'{ b15, b14, b13, b12 } +// - KEY_SHARE0_4 32h'{ . . . . } +// - KEY_SHARE0_5 32h'{ . . . . } +// - KEY_SHARE0_6 32h'{ . . . . } +// - KEY_SHARE0_7 32h'{ b31, b30, b29, b28 } . + +`include "caliptra_prim_assert.sv" + +module aes_cipher_core import aes_pkg::*; +#( + parameter bit AES192Enable = 1, + parameter bit CiphOpFwdOnly = 0, + parameter bit SecMasking = 1, + parameter sbox_impl_e SecSBoxImpl = SBoxImplDom, + parameter bit SecAllowForcingMasks = 0, + parameter bit SecSkipPRNGReseeding = 0, + parameter int unsigned EntropyWidth = edn_pkg::ENDPOINT_BUS_WIDTH, + + localparam int NumShares = SecMasking ? 2 : 1, // derived parameter + + parameter masking_lfsr_seed_t RndCnstMaskingLfsrSeed = RndCnstMaskingLfsrSeedDefault, + parameter masking_lfsr_perm_t RndCnstMaskingLfsrPerm = RndCnstMaskingLfsrPermDefault +) ( + input logic clk_i, + input logic rst_ni, + + // Input handshake signals + input sp2v_e in_valid_i, + output sp2v_e in_ready_o, + + // Output handshake signals + output sp2v_e out_valid_o, + input sp2v_e out_ready_i, + + // Control and sync signals + input logic cfg_valid_i, // Used for gating assertions only. + input ciph_op_e op_i, + input key_len_e key_len_i, + input sp2v_e crypt_i, + output sp2v_e crypt_o, + input sp2v_e dec_key_gen_i, + output sp2v_e dec_key_gen_o, + input logic prng_reseed_i, + output logic prng_reseed_o, + input logic key_clear_i, + output logic key_clear_o, + input logic data_out_clear_i, // Re-use the cipher core muxes. + output logic data_out_clear_o, + input logic alert_fatal_i, + output logic alert_o, + + // Pseudo-random data for register clearing + input logic [3:0][3:0][7:0] prd_clearing_state_i [NumShares], + input logic [7:0][31:0] prd_clearing_key_i [NumShares], + + // Masking PRNG + input logic force_masks_i, // Useful for SCA only. + output logic [3:0][3:0][7:0] data_in_mask_o, + output logic entropy_req_o, + input logic entropy_ack_i, + input logic [EntropyWidth-1:0] entropy_i, + + // I/O data & initial key + input logic [3:0][3:0][7:0] state_init_i [NumShares], + input logic [7:0][31:0] key_init_i [NumShares], + output logic [3:0][3:0][7:0] state_o [NumShares] +); + + // Signals + logic [3:0][3:0][7:0] state_d [NumShares]; + logic [3:0][3:0][7:0] state_q [NumShares]; + sp2v_e state_we_ctrl; + sp2v_e state_we; + logic [StateSelWidth-1:0] state_sel_raw; + state_sel_e state_sel_ctrl; + state_sel_e state_sel; + logic state_sel_err; + + sp2v_e sub_bytes_en; + sp2v_e sub_bytes_out_req; + sp2v_e sub_bytes_out_ack; + logic sub_bytes_err; + logic [3:0][3:0][7:0] sub_bytes_out; + logic [3:0][3:0][7:0] sb_in_mask; + logic [3:0][3:0][7:0] sb_out_mask; + logic [3:0][3:0][7:0] shift_rows_in [NumShares]; + logic [3:0][3:0][7:0] shift_rows_out [NumShares]; + logic [3:0][3:0][7:0] mix_columns_out [NumShares]; + logic [3:0][3:0][7:0] add_round_key_in [NumShares]; + logic [3:0][3:0][7:0] add_round_key_out [NumShares]; + logic [AddRKSelWidth-1:0] add_rk_sel_raw; + add_rk_sel_e add_rk_sel_ctrl; + add_rk_sel_e add_rk_sel; + logic add_rk_sel_err; + + logic [7:0][31:0] key_full_d [NumShares]; + logic [7:0][31:0] key_full_q [NumShares]; + sp2v_e key_full_we_ctrl; + sp2v_e key_full_we; + logic [KeyFullSelWidth-1:0] key_full_sel_raw; + key_full_sel_e key_full_sel_ctrl; + key_full_sel_e key_full_sel; + logic key_full_sel_err; + logic [7:0][31:0] key_dec_d [NumShares]; + logic [7:0][31:0] key_dec_q [NumShares]; + sp2v_e key_dec_we_ctrl; + sp2v_e key_dec_we; + logic [KeyDecSelWidth-1:0] key_dec_sel_raw; + key_dec_sel_e key_dec_sel_ctrl; + key_dec_sel_e key_dec_sel; + logic key_dec_sel_err; + logic [7:0][31:0] key_expand_out [NumShares]; + ciph_op_e key_expand_op; + sp2v_e key_expand_en; + logic key_expand_prd_we; + sp2v_e key_expand_out_req; + sp2v_e key_expand_out_ack; + logic key_expand_err; + logic key_expand_clear; + logic [3:0] key_expand_round; + logic [KeyWordsSelWidth-1:0] key_words_sel_raw; + key_words_sel_e key_words_sel_ctrl; + key_words_sel_e key_words_sel; + logic key_words_sel_err; + logic [3:0][31:0] key_words [NumShares]; + logic [3:0][3:0][7:0] key_bytes [NumShares]; + logic [3:0][3:0][7:0] key_mix_columns_out [NumShares]; + logic [3:0][3:0][7:0] round_key [NumShares]; + logic [RoundKeySelWidth-1:0] round_key_sel_raw; + round_key_sel_e round_key_sel_ctrl; + round_key_sel_e round_key_sel; + logic round_key_sel_err; + + logic cfg_valid; + logic mux_sel_err; + logic sp_enc_err_d, sp_enc_err_q; + logic op_err; + + // Pseudo-random data for masking purposes + logic [WidthPRDMasking-1:0] prd_masking; + logic [3:0][3:0][WidthPRDSBox-1:0] prd_sub_bytes_d; + logic [3:0][3:0][WidthPRDSBox-1:0] prd_sub_bytes_q; + logic [WidthPRDKey-1:0] prd_key_expand; + logic prd_masking_upd; + logic prd_masking_rsd_req; + logic prd_masking_rsd_ack; + + logic [3:0][3:0][7:0] data_in_mask; + + // op_i is one-hot encoded. Check the provided value and trigger an alert upon detecing invalid + // encodings. + assign op_err = ~(op_i == CIPH_FWD || op_i == CIPH_INV); + assign cfg_valid = cfg_valid_i & ~op_err; + + ////////// + // Data // + ////////// + + // SEC_CM: DATA_REG.SEC_WIPE + // State registers + always_comb begin : state_mux + unique case (state_sel) + STATE_INIT: state_d = state_init_i; + STATE_ROUND: state_d = add_round_key_out; + STATE_CLEAR: state_d = prd_clearing_state_i; + default: state_d = prd_clearing_state_i; + endcase + end + + always_ff @(posedge clk_i or negedge rst_ni) begin : state_reg + if (!rst_ni) begin + state_q <= '{default: '0}; + end else if (state_we == SP2V_HIGH) begin + state_q <= state_d; + end + end + + // Masking + if (!SecMasking) begin : gen_no_masks + // The masks are ignored anyway, they can be 0. + assign sb_in_mask = '0; + assign prd_masking = '0; + + // Tie-off unused signals. + logic unused_entropy_ack; + logic [EntropyWidth-1:0] unused_entropy; + assign unused_entropy_ack = entropy_ack_i; + assign unused_entropy = entropy_i; + assign entropy_req_o = 1'b0; + + logic unused_force_masks; + logic unused_prd_masking_upd; + logic unused_prd_masking_rsd_req; + assign unused_force_masks = force_masks_i; + assign unused_prd_masking_upd = prd_masking_upd; + assign unused_prd_masking_rsd_req = prd_masking_rsd_req; + assign prd_masking_rsd_ack = 1'b0; + + logic [3:0][3:0][7:0] unused_sb_out_mask; + assign unused_sb_out_mask = sb_out_mask; + + end else begin : gen_masks + // The input mask is the mask share of the state. + assign sb_in_mask = state_q[1]; + + // The masking PRNG generates: + // - the pseudo-random data (PRD) required by SubBytes, + // - the PRD required by the key expand module (has 4 S-Boxes internally). + aes_prng_masking #( + .Width ( WidthPRDMasking ), + .EntropyWidth ( EntropyWidth ), + .SecAllowForcingMasks ( SecAllowForcingMasks ), + .SecSkipPRNGReseeding ( SecSkipPRNGReseeding ), + .RndCnstLfsrSeed ( RndCnstMaskingLfsrSeed ), + .RndCnstLfsrPerm ( RndCnstMaskingLfsrPerm ) + ) u_aes_prng_masking ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .force_masks_i ( force_masks_i ), + .data_update_i ( prd_masking_upd ), + .data_o ( prd_masking ), + .reseed_req_i ( prd_masking_rsd_req ), + .reseed_ack_o ( prd_masking_rsd_ack ), + .entropy_req_o ( entropy_req_o ), + .entropy_ack_i ( entropy_ack_i ), + .entropy_i ( entropy_i ) + ); + end + + // Extract randomness for key expand module and SubBytes. + // + // The masking PRNG output has the following shape: + // prd_masking = { prd_key_expand, prd_sub_bytes_d } + assign prd_key_expand = prd_masking[WidthPRDMasking-1 -: WidthPRDKey]; + assign prd_sub_bytes_d = prd_masking[WidthPRDData-1 -: WidthPRDData]; + + // PRD buffering + if (!SecMasking) begin : gen_no_prd_buffer + // The masks are ignored anyway. + assign prd_sub_bytes_q = prd_sub_bytes_d; + + end else begin : gen_prd_buffer + // PRD buffer stage to: + // 1. Make sure the S-Boxes get always presented new data/mask inputs together with fresh PRD + // for remasking. + // 2. Prevent glitches originating from inside the masking PRNG from propagating into the + // masked S-Boxes. + always_ff @(posedge clk_i or negedge rst_ni) begin : prd_sub_bytes_reg + if (!rst_ni) begin + prd_sub_bytes_q <= '0; + end else if (state_we == SP2V_HIGH) begin + prd_sub_bytes_q <= prd_sub_bytes_d; + end + end + end + + // Convert the 3-dimensional prd_sub_bytes_q array to a 1-dimensional packed array for the + // aes_prd_get_lsbs() function used below. + logic [WidthPRDData-1:0] prd_sub_bytes; + assign prd_sub_bytes = prd_sub_bytes_q; + + // Extract randomness for masking the input data. + // + // The masking PRNG is used for generating both the PRD for the S-Boxes/SubBytes operation as + // well as for the input data masks. When using any of the masked Canright S-Box implementations, + // it is important that the SubBytes input masks (generated by the PRNG in Round X-1) and the + // SubBytes output masks (generated by the PRNG in Round X) are independent. This can be achieved + // by using e.g. an unrolled Bivium stream cipher primitive inside the PRNG. Since the input data + // masks become the SubBytes input masks in the first round, we select the same 8 bit lanes for + // the input data masks which are also used to form the SubBytes output mask for the masked + // Canright S-Box implementations, i.e., the 8 LSBs of the per S-Box PRD. In particular, we have: + // + // prd_masking = { prd_key_expand, ... , sb_prd[4], sb_out_mask[4], sb_prd[0], sb_out_mask[0] } + // + // Where sb_out_mask[x] contains the SubBytes output mask for byte x (when using a masked + // Canright S-Box implementation) and sb_prd[x] contains additional PRD consumed by SubBytes for + // byte x. + // + // When using a masked S-Box implementation other than Canright, we still select the 8 LSBs of + // the per-S-Box PRD to form the input data mask of the corresponding byte. We do this to + // distribute the input data masks over all output bits the masking PRNG. We do the extraction on + // a row basis. + localparam int unsigned WidthPRDRow = 4*WidthPRDSBox; + for (genvar i = 0; i < 4; i++) begin : gen_in_mask + assign data_in_mask[i] = aes_prd_get_lsbs(prd_sub_bytes[i * WidthPRDRow +: WidthPRDRow]); + end + + // Rotate the data input masks by 64 bits to ensure the data input masks are independent + // from the PRD fed to the S-Boxes/SubBytes operation. + assign data_in_mask_o = {data_in_mask[1], data_in_mask[0], data_in_mask[3], data_in_mask[2]}; + + // Cipher data path + aes_sub_bytes #( + .SecSBoxImpl ( SecSBoxImpl ) + ) u_aes_sub_bytes ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .en_i ( sub_bytes_en ), + .out_req_o ( sub_bytes_out_req ), + .out_ack_i ( sub_bytes_out_ack ), + .op_i ( op_i ), + .data_i ( state_q[0] ), + .mask_i ( sb_in_mask ), + .prd_i ( prd_sub_bytes_q ), + .data_o ( sub_bytes_out ), + .mask_o ( sb_out_mask ), + .err_o ( sub_bytes_err ) + ); + + for (genvar s = 0; s < NumShares; s++) begin : gen_shares_shift_mix + if (s == 0) begin : gen_shift_in_data + // The (masked) data share + assign shift_rows_in[s] = sub_bytes_out; + end else begin : gen_shift_in_mask + // The mask share + assign shift_rows_in[s] = sb_out_mask; + end + + aes_shift_rows u_aes_shift_rows ( + .op_i ( op_i ), + .data_i ( shift_rows_in[s] ), + .data_o ( shift_rows_out[s] ) + ); + + aes_mix_columns u_aes_mix_columns ( + .op_i ( op_i ), + .data_i ( shift_rows_out[s] ), + .data_o ( mix_columns_out[s] ) + ); + end + + always_comb begin : add_round_key_in_mux + unique case (add_rk_sel) + ADD_RK_INIT: add_round_key_in = state_q; + ADD_RK_ROUND: add_round_key_in = mix_columns_out; + ADD_RK_FINAL: add_round_key_in = shift_rows_out; + default: add_round_key_in = state_q; + endcase + end + + for (genvar s = 0; s < NumShares; s++) begin : gen_shares_add_round_key + assign add_round_key_out[s] = add_round_key_in[s] ^ round_key[s]; + end + + ///////// + // Key // + ///////// + + // SEC_CM: KEY.SEC_WIPE + // Full Key registers + always_comb begin : key_full_mux + unique case (key_full_sel) + KEY_FULL_ENC_INIT: key_full_d = key_init_i; + KEY_FULL_DEC_INIT: key_full_d = !CiphOpFwdOnly ? key_dec_q : prd_clearing_key_i; + KEY_FULL_ROUND: key_full_d = key_expand_out; + KEY_FULL_CLEAR: key_full_d = prd_clearing_key_i; + default: key_full_d = prd_clearing_key_i; + endcase + end + + always_ff @(posedge clk_i or negedge rst_ni) begin : key_full_reg + if (!rst_ni) begin + key_full_q <= '{default: '0}; + end else if (key_full_we == SP2V_HIGH) begin + key_full_q <= key_full_d; + end + end + + if (!CiphOpFwdOnly) begin : gen_key_dec + // SEC_CM: KEY.SEC_WIPE + // Decryption Key registers + always_comb begin : key_dec_mux + unique case (key_dec_sel) + KEY_DEC_EXPAND: key_dec_d = key_expand_out; + KEY_DEC_CLEAR: key_dec_d = prd_clearing_key_i; + default: key_dec_d = prd_clearing_key_i; + endcase + end + + always_ff @(posedge clk_i or negedge rst_ni) begin : key_dec_reg + if (!rst_ni) begin + key_dec_q <= '{default: '0}; + end else if (key_dec_we == SP2V_HIGH) begin + key_dec_q <= key_dec_d; + end + end + end else begin : gen_no_key_dec + // No Decryption Key registers + assign key_dec_q = '{default: '0}; + assign key_dec_d = key_dec_q; + + // Tie-off unused signals. + logic unused_key_dec; + always_comb begin + unused_key_dec = ^{key_dec_sel, key_dec_we}; + for (int s = 0; s < NumShares; s++) begin + unused_key_dec ^= ^{key_dec_d[s]}; + end + end + end + + // Make sure that whenever the data/mask inputs of the S-Boxes update, the internally buffered + // PRD is updated in sync. + assign key_expand_prd_we = (key_full_we == SP2V_HIGH) ? 1'b1 : 1'b0; + + // Key expand data path + aes_key_expand #( + .AES192Enable ( AES192Enable ), + .SecMasking ( SecMasking ), + .SecSBoxImpl ( SecSBoxImpl ) + ) u_aes_key_expand ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .cfg_valid_i ( cfg_valid ), + .op_i ( key_expand_op ), + .en_i ( key_expand_en ), + .prd_we_i ( key_expand_prd_we ), + .out_req_o ( key_expand_out_req ), + .out_ack_i ( key_expand_out_ack ), + .clear_i ( key_expand_clear ), + .round_i ( key_expand_round ), + .key_len_i ( key_len_i ), + .key_i ( key_full_q ), + .key_o ( key_expand_out ), + .prd_i ( prd_key_expand ), + .err_o ( key_expand_err ) + ); + + for (genvar s = 0; s < NumShares; s++) begin : gen_shares_round_key + always_comb begin : key_words_mux + unique case (key_words_sel) + KEY_WORDS_0123: key_words[s] = key_full_q[s][3:0]; + KEY_WORDS_2345: key_words[s] = AES192Enable ? key_full_q[s][5:2] : '0; + KEY_WORDS_4567: key_words[s] = key_full_q[s][7:4]; + KEY_WORDS_ZERO: key_words[s] = '0; + default: key_words[s] = '0; + endcase + end + + // Convert words to bytes (every key word contains one column). + assign key_bytes[s] = aes_transpose(key_words[s]); + + aes_mix_columns u_aes_key_mix_columns ( + .op_i ( CIPH_INV ), + .data_i ( key_bytes[s] ), + .data_o ( key_mix_columns_out[s] ) + ); + end + + always_comb begin : round_key_mux + unique case (round_key_sel) + ROUND_KEY_DIRECT: round_key = key_bytes; + ROUND_KEY_MIXED: round_key = !CiphOpFwdOnly ? key_mix_columns_out : key_bytes; + default: round_key = key_bytes; + endcase + end + + if (CiphOpFwdOnly) begin : gen_unused_key_mix_columns_out + // Tie-off unused signals. + logic unused_key_mix_columns_out; + always_comb begin + unused_key_mix_columns_out = 1'b0; + for (int s = 0; s < NumShares; s++) begin + unused_key_mix_columns_out ^= ^{key_mix_columns_out[s]}; + end + end + end + + ///////////// + // Control // + ///////////// + + // Control + aes_cipher_control #( + .CiphOpFwdOnly ( CiphOpFwdOnly ), + .SecMasking ( SecMasking ), + .SecSBoxImpl ( SecSBoxImpl ) + ) u_aes_cipher_control ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + + .in_valid_i ( in_valid_i ), + .in_ready_o ( in_ready_o ), + + .out_valid_o ( out_valid_o ), + .out_ready_i ( out_ready_i ), + + .cfg_valid_i ( cfg_valid ), + .op_i ( op_i ), + .key_len_i ( key_len_i ), + .crypt_i ( crypt_i ), + .crypt_o ( crypt_o ), + .dec_key_gen_i ( dec_key_gen_i ), + .dec_key_gen_o ( dec_key_gen_o ), + .prng_reseed_i ( prng_reseed_i ), + .prng_reseed_o ( prng_reseed_o ), + .key_clear_i ( key_clear_i ), + .key_clear_o ( key_clear_o ), + .data_out_clear_i ( data_out_clear_i ), + .data_out_clear_o ( data_out_clear_o ), + .mux_sel_err_i ( mux_sel_err ), + .sp_enc_err_i ( sp_enc_err_q ), + .op_err_i ( op_err ), + .alert_fatal_i ( alert_fatal_i ), + .alert_o ( alert_o ), + + .prng_update_o ( prd_masking_upd ), + .prng_reseed_req_o ( prd_masking_rsd_req ), + .prng_reseed_ack_i ( prd_masking_rsd_ack ), + + .state_sel_o ( state_sel_ctrl ), + .state_we_o ( state_we_ctrl ), + .sub_bytes_en_o ( sub_bytes_en ), + .sub_bytes_out_req_i ( sub_bytes_out_req ), + .sub_bytes_out_ack_o ( sub_bytes_out_ack ), + .add_rk_sel_o ( add_rk_sel_ctrl ), + + .key_expand_op_o ( key_expand_op ), + .key_full_sel_o ( key_full_sel_ctrl ), + .key_full_we_o ( key_full_we_ctrl ), + .key_dec_sel_o ( key_dec_sel_ctrl ), + .key_dec_we_o ( key_dec_we_ctrl ), + .key_expand_en_o ( key_expand_en ), + .key_expand_out_req_i ( key_expand_out_req ), + .key_expand_out_ack_o ( key_expand_out_ack ), + .key_expand_clear_o ( key_expand_clear ), + .key_expand_round_o ( key_expand_round ), + .key_words_sel_o ( key_words_sel_ctrl ), + .round_key_sel_o ( round_key_sel_ctrl ) + ); + + /////////////// + // Selectors // + /////////////// + + // We use sparse encodings for these mux selector signals and must ensure that: + // 1. The synthesis tool doesn't optimize away the sparse encoding. + // 2. The selector signal is always valid. More precisely, an alert or SVA is triggered if a + // selector signal takes on an invalid value. + // 3. The alert signal remains asserted until reset even if the selector signal becomes valid + // again. This is achieved by driving the control FSM into the terminal error state whenever + // any mux selector signal becomes invalid. + // + // If any mux selector signal becomes invalid, the cipher core further immediately de-asserts + // the out_valid_o signal to prevent any data from being released. + + aes_sel_buf_chk #( + .Num ( StateSelNum ), + .Width ( StateSelWidth ), + .EnSecBuf ( 1'b1 ) + ) u_aes_state_sel_buf_chk ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .sel_i ( state_sel_ctrl ), + .sel_o ( state_sel_raw ), + .err_o ( state_sel_err ) + ); + assign state_sel = state_sel_e'(state_sel_raw); + + aes_sel_buf_chk #( + .Num ( AddRKSelNum ), + .Width ( AddRKSelWidth ), + .EnSecBuf ( 1'b1 ) + ) u_aes_add_rk_sel_buf_chk ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .sel_i ( add_rk_sel_ctrl ), + .sel_o ( add_rk_sel_raw ), + .err_o ( add_rk_sel_err ) + ); + assign add_rk_sel = add_rk_sel_e'(add_rk_sel_raw); + + aes_sel_buf_chk #( + .Num ( KeyFullSelNum ), + .Width ( KeyFullSelWidth ), + .EnSecBuf ( 1'b1 ) + ) u_aes_key_full_sel_buf_chk ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .sel_i ( key_full_sel_ctrl ), + .sel_o ( key_full_sel_raw ), + .err_o ( key_full_sel_err ) + ); + assign key_full_sel = key_full_sel_e'(key_full_sel_raw); + + aes_sel_buf_chk #( + .Num ( KeyDecSelNum ), + .Width ( KeyDecSelWidth ), + .EnSecBuf ( 1'b1 ) + ) u_aes_key_dec_sel_buf_chk ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .sel_i ( key_dec_sel_ctrl ), + .sel_o ( key_dec_sel_raw ), + .err_o ( key_dec_sel_err ) + ); + assign key_dec_sel = key_dec_sel_e'(key_dec_sel_raw); + + aes_sel_buf_chk #( + .Num ( KeyWordsSelNum ), + .Width ( KeyWordsSelWidth ), + .EnSecBuf ( 1'b1 ) + ) u_aes_key_words_sel_buf_chk ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .sel_i ( key_words_sel_ctrl ), + .sel_o ( key_words_sel_raw ), + .err_o ( key_words_sel_err ) + ); + assign key_words_sel = key_words_sel_e'(key_words_sel_raw); + + aes_sel_buf_chk #( + .Num ( RoundKeySelNum ), + .Width ( RoundKeySelWidth ), + .EnSecBuf ( 1'b1 ) + ) u_aes_round_key_sel_buf_chk ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .sel_i ( round_key_sel_ctrl ), + .sel_o ( round_key_sel_raw ), + .err_o ( round_key_sel_err ) + ); + assign round_key_sel = round_key_sel_e'(round_key_sel_raw); + + // Signal invalid mux selector signals to control FSM which will lock up and trigger an alert. + assign mux_sel_err = state_sel_err | add_rk_sel_err | key_full_sel_err | + key_dec_sel_err | key_words_sel_err | round_key_sel_err; + + ////////////////////////////// + // Sparsely Encoded Signals // + ////////////////////////////// + + // We use sparse encodings for various critical signals and must ensure that: + // 1. The synthesis tool doesn't optimize away the sparse encoding. + // 2. The sparsely encoded signal is always valid. More precisely, an alert or SVA is triggered + // if a sparse signal takes on an invalid value. + // 3. The alert signal remains asserted until reset even if the sparse signal becomes valid again + // This is achieved by driving the control FSM into the terminal error state whenever any + // sparsely encoded signal becomes invalid. + // + // If any sparsely encoded signal becomes invalid, the cipher core further immediately de-asserts + // the out_valid_o signal to prevent any data from being released. + + // We use vectors of sparsely encoded signals to reduce code duplication. + localparam int unsigned NumSp2VSig = 3; + sp2v_e [NumSp2VSig-1:0] sp2v_sig; + sp2v_e [NumSp2VSig-1:0] sp2v_sig_chk; + logic [NumSp2VSig-1:0][Sp2VWidth-1:0] sp2v_sig_chk_raw; + logic [NumSp2VSig-1:0] sp2v_sig_err; + + assign sp2v_sig[0] = state_we_ctrl; + assign sp2v_sig[1] = key_full_we_ctrl; + assign sp2v_sig[2] = key_dec_we_ctrl; + + // All signals inside sp2v_sig are eventually converted to single-rail signals. + localparam bit [NumSp2VSig-1:0] Sp2VEnSecBuf = {NumSp2VSig{1'b1}}; + + // Individually check sparsely encoded signals. + for (genvar i = 0; i < NumSp2VSig; i++) begin : gen_sel_buf_chk + aes_sel_buf_chk #( + .Num ( Sp2VNum ), + .Width ( Sp2VWidth ), + .EnSecBuf ( Sp2VEnSecBuf[i] ) + ) u_aes_sp2v_sig_buf_chk_i ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .sel_i ( sp2v_sig[i] ), + .sel_o ( sp2v_sig_chk_raw[i] ), + .err_o ( sp2v_sig_err[i] ) + ); + assign sp2v_sig_chk[i] = sp2v_e'(sp2v_sig_chk_raw[i]); + end + + assign state_we = sp2v_sig_chk[0]; + assign key_full_we = sp2v_sig_chk[1]; + assign key_dec_we = sp2v_sig_chk[2]; + + // Collect encoding errors. + // We instantiate the checker modules as close as possible to where the sparsely encoded signals + // are used. Here, we collect also encoding errors detected in other places of the cipher core. + assign sp_enc_err_d = |sp2v_sig_err | sub_bytes_err | key_expand_err; + + // We need to register the collected error signal to avoid circular loops in the cipher core + // controller related to out_valid_o and detecting errors in state_we_o and sub_bytes_out_ack. + always_ff @(posedge clk_i or negedge rst_ni) begin : reg_sp_enc_err + if (!rst_ni) begin + sp_enc_err_q <= 1'b0; + end else if (sp_enc_err_d) begin + sp_enc_err_q <= 1'b1; + end + end + + ///////////// + // Outputs // + ///////////// + + // The output of the last round is not stored into the state register but forwarded directly. + assign state_o = add_round_key_out; + + //////////////// + // Assertions // + //////////////// + +// Typically assertions already contain this macro, which ensures that assertions are only compiled +// in simulation and FPV. However, we wrap the entire assertion section with CALIPTRA_INC_ASSERT so that the +// helper logic below is not synthesized either, since that could cause issues in DC. +`ifdef CALIPTRA_INC_ASSERT + //VCS coverage off + // pragma coverage off + + // Create a lint error to reduce the risk of accidentally disabling the masking. + `CALIPTRA_ASSERT_STATIC_LINT_ERROR(AesSecMaskingNonDefault, SecMasking == 1) + + // Cipher core masking requires a masked SBox and vice versa. + `CALIPTRA_ASSERT_INIT(AesMaskedCoreAndSBox, + (SecMasking && + (SecSBoxImpl == SBoxImplCanrightMasked || + SecSBoxImpl == SBoxImplCanrightMaskedNoreuse || + SecSBoxImpl == SBoxImplDom)) || + (!SecMasking && + (SecSBoxImpl == SBoxImplLut || + SecSBoxImpl == SBoxImplCanright))) + + // Signals used for assertions only. + logic prd_clearing_equals_output, unused_prd_clearing_equals_output; + assign prd_clearing_equals_output = (prd_clearing_state_i == add_round_key_out); + assign unused_prd_clearing_equals_output = prd_clearing_equals_output; + + // Ensure that the state register gets cleared with pseudo-random data at the end of the last + // round. The following two scenarios are unlikely but not illegal: + // 1. The newly loaded initial state matches the previous output (the round counter is only + // cleared upon loading the new initial state). + // 2. The previous pseudo-random data is equal to the previous output. + // Otherwise, we must see an alert e.g. because the state multiplexer got glitched. + `CALIPTRA_ASSERT(AesSecCmDataRegKeySca, (state_we == SP2V_HIGH) && + ((key_len_i == AES_128 && u_aes_cipher_control.rnd_ctr == 4'd10) || + (key_len_i == AES_192 && u_aes_cipher_control.rnd_ctr == 4'd12) || + (key_len_i == AES_256 && u_aes_cipher_control.rnd_ctr == 4'd14)) |=> + (state_q != $past(add_round_key_out)) || + (state_q == $past(state_init_i)) || + $past(prd_clearing_equals_output) || alert_o) + + if (SecMasking) begin : gen_sec_cm_key_masking_svas + // The number of clock cycles a regular AES round takes - only used for assertions. + localparam int unsigned NumCyclesPerRound = (SecSBoxImpl == SBoxImplDom) ? 5 : 1; + logic unused_param; + assign unused_param = (NumCyclesPerRound == 1); + // Ensure that SubBytes gets fresh PRD input for every evaluation unless mask forcing is + // enabled. We effectively check that the PRNG has been updated at least once within the + // last NumCyclesPerRound cycles. This also holds for the very first round, as the PRNG + // is always updated in the last cycle of the IDLE state and/or the first cycle of the + // INIT state. + `CALIPTRA_ASSERT(AesSecCmKeyMaskingPrdSubBytes, + sub_bytes_en == SP2V_HIGH && ($past(sub_bytes_en) == SP2V_LOW || + ($past(sub_bytes_out_req) == SP2V_HIGH && + $past(sub_bytes_out_ack) == SP2V_HIGH)) |=> + $past(prd_sub_bytes_q) != $past(prd_sub_bytes_q, NumCyclesPerRound + 1) || + SecAllowForcingMasks && force_masks_i) + + // Ensure that the PRNG has been updated between masking the input and starting the first + // SubBytes evaluation/KeyExpand operation unless mask forcing is enabled. For AES-256, + // we just spend 1 cycle in the INIT state and KeyExpand isn't evaluating its S-Boxes, + // i.e., no fresh randomness is required. For the other key lengths, KeyExpand evaluates + // its S-Boxes which takes NumCyclesPerRound cycles. When computing the start key for + // decryption, the input isn't loaded and the PRNG is thus not advanced. + `CALIPTRA_ASSERT(AesSecCmKeyMaskingInitialPrngUpdateSubBytes, + sub_bytes_en == SP2V_HIGH && $past(sub_bytes_en) == SP2V_LOW |=> + (key_len_i == AES_256 && + $past(prd_masking) != $past(prd_masking, 3)) || + ((key_len_i == AES_128 || key_len_i == AES_192) && + $past(prd_masking) != $past(prd_masking, NumCyclesPerRound + 2)) || + (SecAllowForcingMasks && force_masks_i)) + `CALIPTRA_ASSERT(AesSecCmKeyMaskingInitialPrngUpdateKeyExpand, + key_expand_en == SP2V_HIGH && $past(key_expand_en) == SP2V_LOW |=> + (key_len_i == AES_256 && + $past(prd_masking) != $past(prd_masking, 3)) || + ((key_len_i == AES_128 || key_len_i == AES_192) && + $past(prd_masking) != $past(prd_masking, 2)) || + (SecAllowForcingMasks && force_masks_i) || dec_key_gen_o == SP2V_HIGH) + + // Ensure none of the state shares keeps being constant during encryption/decryption + // unless mask forcing is enabled. Even though unlikely it's not impossible that one + // share remains constant throughout one round. The SVAs thus only fire if a share + // remains constant across two rounds. + for (genvar s = 0; s < NumShares; s++) begin : gen_sec_cm_key_masking_share_svas + `CALIPTRA_ASSERT(AesSecCmKeyMaskingStateShare, state_we == SP2V_HIGH && + (crypt_i == SP2V_HIGH || crypt_o == SP2V_HIGH) |=> + state_q[s] != $past(state_q[s], NumCyclesPerRound) || + $past(state_q[s], NumCyclesPerRound) != $past(state_q[s], 2*NumCyclesPerRound) || + (SecAllowForcingMasks && force_masks_i) || dec_key_gen_o == SP2V_HIGH) + `CALIPTRA_ASSERT(AesSecCmKeyMaskingOutputShare, + (out_valid_o == SP2V_HIGH && $past(out_valid_o) == SP2V_LOW) && + (crypt_o == SP2V_HIGH) |=> + $past(state_o[s]) != $past(state_q[s], NumCyclesPerRound) || + $past(state_q[s], NumCyclesPerRound) != $past(state_q[s], 2*NumCyclesPerRound) || + (SecAllowForcingMasks && force_masks_i) || dec_key_gen_o == SP2V_HIGH) + end + end + + // Make sure the output of the masking PRNG is properly extracted without creating overlaps + // in the data input masks, or between the PRD fed to the key expand module and SubBytes. + if (WidthPRDSBox > 8) begin : gen_prd_extract_assert + // For one row of the state matrix, extract the WidthPRDSBox-8 MSBs of the per-S-Box PRD from + // the PRNG output. + function automatic logic [3:0][(WidthPRDSBox-8)-1:0] aes_prd_get_msbs( + logic [(4*WidthPRDSBox)-1:0] in + ); + logic [3:0][(WidthPRDSBox-8)-1:0] prd_msbs; + for (int i = 0; i < 4; i++) begin + prd_msbs[i] = in[(i*WidthPRDSBox) + 8 +: (WidthPRDSBox-8)]; + end + return prd_msbs; + endfunction + + // For one row of the state matrix, undo the extraction of LSBs and MSBs of the per-S-Box PRD + // from the PRNG output. This can be used to verify proper extraction (no overlap of output + // masks and PRD for masked Canright S-Box implementations, no unused PRNG output). + function automatic logic [4*WidthPRDSBox-1:0] aes_prd_concat_bits( + logic [3:0] [7:0] prd_lsbs, + logic [3:0][(WidthPRDSBox-8)-1:0] prd_msbs + ); + logic [(4*WidthPRDSBox)-1:0] prd; + for (int i = 0; i < 4; i++) begin + prd[(i*WidthPRDSBox) +: WidthPRDSBox] = {prd_msbs[i], prd_lsbs[i]}; + end + return prd; + endfunction + + // Check for correct extraction of masking PRNG output without overlaps. + logic [WidthPRDMasking-1:0] unused_prd_masking; + logic [3:0][3:0][(WidthPRDSBox-8)-1:0] unused_prd_msbs; + for (genvar i = 0; i < 4; i++) begin : gen_unused_prd_msbs + assign unused_prd_msbs[i] = aes_prd_get_msbs(prd_masking[i * WidthPRDRow +: WidthPRDRow]); + end + for (genvar i = 0; i < 4; i++) begin : gen_unused_prd_masking + assign unused_prd_masking[i * WidthPRDRow +: WidthPRDRow] = + aes_prd_concat_bits(data_in_mask[i], unused_prd_msbs[i]); + end + assign unused_prd_masking[WidthPRDMasking-1 -: WidthPRDKey] = prd_key_expand; + `CALIPTRA_ASSERT(AesMskgPrdExtraction, prd_masking == unused_prd_masking) + end + //VCS coverage on + // pragma coverage on +`endif + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/aes_clp_reg.sv b/designs/Caliptra/src/caliptra-rtl/aes_clp_reg.sv new file mode 100644 index 0000000..0b97a84 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/aes_clp_reg.sv @@ -0,0 +1,1928 @@ +// Generated by PeakRDL-regblock - A free and open-source SystemVerilog generator +// https://github.com/SystemRDL/PeakRDL-regblock + +module aes_clp_reg ( + input wire clk, + input wire rst, + + input wire s_cpuif_req, + input wire s_cpuif_req_is_wr, + input wire [10:0] s_cpuif_addr, + input wire [31:0] s_cpuif_wr_data, + input wire [31:0] s_cpuif_wr_biten, + output wire s_cpuif_req_stall_wr, + output wire s_cpuif_req_stall_rd, + output wire s_cpuif_rd_ack, + output wire s_cpuif_rd_err, + output wire [31:0] s_cpuif_rd_data, + output wire s_cpuif_wr_ack, + output wire s_cpuif_wr_err, + + input aes_clp_reg_pkg::aes_clp_reg__in_t hwif_in, + output aes_clp_reg_pkg::aes_clp_reg__out_t hwif_out + ); + + //-------------------------------------------------------------------------- + // CPU Bus interface logic + //-------------------------------------------------------------------------- + logic cpuif_req; + logic cpuif_req_is_wr; + logic [10:0] cpuif_addr; + logic [31:0] cpuif_wr_data; + logic [31:0] cpuif_wr_biten; + logic cpuif_req_stall_wr; + logic cpuif_req_stall_rd; + + logic cpuif_rd_ack; + logic cpuif_rd_err; + logic [31:0] cpuif_rd_data; + + logic cpuif_wr_ack; + logic cpuif_wr_err; + + assign cpuif_req = s_cpuif_req; + assign cpuif_req_is_wr = s_cpuif_req_is_wr; + assign cpuif_addr = s_cpuif_addr; + assign cpuif_wr_data = s_cpuif_wr_data; + assign cpuif_wr_biten = s_cpuif_wr_biten; + assign s_cpuif_req_stall_wr = cpuif_req_stall_wr; + assign s_cpuif_req_stall_rd = cpuif_req_stall_rd; + assign s_cpuif_rd_ack = cpuif_rd_ack; + assign s_cpuif_rd_err = cpuif_rd_err; + assign s_cpuif_rd_data = cpuif_rd_data; + assign s_cpuif_wr_ack = cpuif_wr_ack; + assign s_cpuif_wr_err = cpuif_wr_err; + + logic cpuif_req_masked; + + // Read & write latencies are balanced. Stalls not required + assign cpuif_req_stall_rd = '0; + assign cpuif_req_stall_wr = '0; + assign cpuif_req_masked = cpuif_req + & !(!cpuif_req_is_wr & cpuif_req_stall_rd) + & !(cpuif_req_is_wr & cpuif_req_stall_wr); + + //-------------------------------------------------------------------------- + // Address Decode + //-------------------------------------------------------------------------- + typedef struct packed{ + logic [2-1:0]AES_NAME; + logic [2-1:0]AES_VERSION; + logic [9-1:0]ENTROPY_IF_SEED; + logic CTRL0; + logic AES_KV_RD_KEY_CTRL; + logic AES_KV_RD_KEY_STATUS; + logic AES_KV_WR_CTRL; + logic AES_KV_WR_STATUS; + struct packed{ + logic global_intr_en_r; + logic error_intr_en_r; + logic notif_intr_en_r; + logic error_global_intr_r; + logic notif_global_intr_r; + logic error_internal_intr_r; + logic notif_internal_intr_r; + logic error_intr_trig_r; + logic notif_intr_trig_r; + logic error0_intr_count_r; + logic error1_intr_count_r; + logic error2_intr_count_r; + logic error3_intr_count_r; + logic notif_cmd_done_intr_count_r; + logic error0_intr_count_incr_r; + logic error1_intr_count_incr_r; + logic error2_intr_count_incr_r; + logic error3_intr_count_incr_r; + logic notif_cmd_done_intr_count_incr_r; + } intr_block_rf; + } decoded_reg_strb_t; + decoded_reg_strb_t decoded_reg_strb; + logic decoded_req; + logic decoded_req_is_wr; + logic [31:0] decoded_wr_data; + logic [31:0] decoded_wr_biten; + + always_comb begin + for(int i0=0; i0<2; i0++) begin + decoded_reg_strb.AES_NAME[i0] = cpuif_req_masked & (cpuif_addr == 11'h0 + i0*11'h4); + end + for(int i0=0; i0<2; i0++) begin + decoded_reg_strb.AES_VERSION[i0] = cpuif_req_masked & (cpuif_addr == 11'h8 + i0*11'h4); + end + for(int i0=0; i0<9; i0++) begin + decoded_reg_strb.ENTROPY_IF_SEED[i0] = cpuif_req_masked & (cpuif_addr == 11'h110 + i0*11'h4); + end + decoded_reg_strb.CTRL0 = cpuif_req_masked & (cpuif_addr == 11'h134); + decoded_reg_strb.AES_KV_RD_KEY_CTRL = cpuif_req_masked & (cpuif_addr == 11'h200); + decoded_reg_strb.AES_KV_RD_KEY_STATUS = cpuif_req_masked & (cpuif_addr == 11'h204); + decoded_reg_strb.AES_KV_WR_CTRL = cpuif_req_masked & (cpuif_addr == 11'h208); + decoded_reg_strb.AES_KV_WR_STATUS = cpuif_req_masked & (cpuif_addr == 11'h20c); + decoded_reg_strb.intr_block_rf.global_intr_en_r = cpuif_req_masked & (cpuif_addr == 11'h400); + decoded_reg_strb.intr_block_rf.error_intr_en_r = cpuif_req_masked & (cpuif_addr == 11'h404); + decoded_reg_strb.intr_block_rf.notif_intr_en_r = cpuif_req_masked & (cpuif_addr == 11'h408); + decoded_reg_strb.intr_block_rf.error_global_intr_r = cpuif_req_masked & (cpuif_addr == 11'h40c); + decoded_reg_strb.intr_block_rf.notif_global_intr_r = cpuif_req_masked & (cpuif_addr == 11'h410); + decoded_reg_strb.intr_block_rf.error_internal_intr_r = cpuif_req_masked & (cpuif_addr == 11'h414); + decoded_reg_strb.intr_block_rf.notif_internal_intr_r = cpuif_req_masked & (cpuif_addr == 11'h418); + decoded_reg_strb.intr_block_rf.error_intr_trig_r = cpuif_req_masked & (cpuif_addr == 11'h41c); + decoded_reg_strb.intr_block_rf.notif_intr_trig_r = cpuif_req_masked & (cpuif_addr == 11'h420); + decoded_reg_strb.intr_block_rf.error0_intr_count_r = cpuif_req_masked & (cpuif_addr == 11'h500); + decoded_reg_strb.intr_block_rf.error1_intr_count_r = cpuif_req_masked & (cpuif_addr == 11'h504); + decoded_reg_strb.intr_block_rf.error2_intr_count_r = cpuif_req_masked & (cpuif_addr == 11'h508); + decoded_reg_strb.intr_block_rf.error3_intr_count_r = cpuif_req_masked & (cpuif_addr == 11'h50c); + decoded_reg_strb.intr_block_rf.notif_cmd_done_intr_count_r = cpuif_req_masked & (cpuif_addr == 11'h580); + decoded_reg_strb.intr_block_rf.error0_intr_count_incr_r = cpuif_req_masked & (cpuif_addr == 11'h600); + decoded_reg_strb.intr_block_rf.error1_intr_count_incr_r = cpuif_req_masked & (cpuif_addr == 11'h604); + decoded_reg_strb.intr_block_rf.error2_intr_count_incr_r = cpuif_req_masked & (cpuif_addr == 11'h608); + decoded_reg_strb.intr_block_rf.error3_intr_count_incr_r = cpuif_req_masked & (cpuif_addr == 11'h60c); + decoded_reg_strb.intr_block_rf.notif_cmd_done_intr_count_incr_r = cpuif_req_masked & (cpuif_addr == 11'h610); + end + + // Pass down signals to next stage + assign decoded_req = cpuif_req_masked; + assign decoded_req_is_wr = cpuif_req_is_wr; + assign decoded_wr_data = cpuif_wr_data; + assign decoded_wr_biten = cpuif_wr_biten; + + //-------------------------------------------------------------------------- + // Field logic + //-------------------------------------------------------------------------- + typedef struct packed{ + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } ENTROPY_IF_SEED; + } [9-1:0]ENTROPY_IF_SEED; + struct packed{ + struct packed{ + logic next; + logic load_next; + } ENDIAN_SWAP; + } CTRL0; + struct packed{ + struct packed{ + logic next; + logic load_next; + } read_en; + struct packed{ + logic [4:0] next; + logic load_next; + } read_entry; + struct packed{ + logic next; + logic load_next; + } pcr_hash_extend; + struct packed{ + logic [24:0] next; + logic load_next; + } rsvd; + } AES_KV_RD_KEY_CTRL; + struct packed{ + struct packed{ + logic next; + logic load_next; + } VALID; + } AES_KV_RD_KEY_STATUS; + struct packed{ + struct packed{ + logic next; + logic load_next; + } write_en; + struct packed{ + logic [4:0] next; + logic load_next; + } write_entry; + struct packed{ + logic next; + logic load_next; + } hmac_key_dest_valid; + struct packed{ + logic next; + logic load_next; + } hmac_block_dest_valid; + struct packed{ + logic next; + logic load_next; + } mldsa_seed_dest_valid; + struct packed{ + logic next; + logic load_next; + } ecc_pkey_dest_valid; + struct packed{ + logic next; + logic load_next; + } ecc_seed_dest_valid; + struct packed{ + logic next; + logic load_next; + } aes_key_dest_valid; + struct packed{ + logic next; + logic load_next; + } mlkem_seed_dest_valid; + struct packed{ + logic next; + logic load_next; + } mlkem_msg_dest_valid; + struct packed{ + logic next; + logic load_next; + } dma_data_dest_valid; + struct packed{ + logic [16:0] next; + logic load_next; + } rsvd; + } AES_KV_WR_CTRL; + struct packed{ + struct packed{ + logic next; + logic load_next; + } VALID; + } AES_KV_WR_STATUS; + struct packed{ + struct packed{ + struct packed{ + logic next; + logic load_next; + } error_en; + struct packed{ + logic next; + logic load_next; + } notif_en; + } global_intr_en_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + } error0_en; + struct packed{ + logic next; + logic load_next; + } error1_en; + struct packed{ + logic next; + logic load_next; + } error2_en; + struct packed{ + logic next; + logic load_next; + } error3_en; + } error_intr_en_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + } notif_cmd_done_en; + } notif_intr_en_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + } agg_sts; + } error_global_intr_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + } agg_sts; + } notif_global_intr_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + } error0_sts; + struct packed{ + logic next; + logic load_next; + } error1_sts; + struct packed{ + logic next; + logic load_next; + } error2_sts; + struct packed{ + logic next; + logic load_next; + } error3_sts; + } error_internal_intr_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + } notif_cmd_done_sts; + } notif_internal_intr_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + } error0_trig; + struct packed{ + logic next; + logic load_next; + } error1_trig; + struct packed{ + logic next; + logic load_next; + } error2_trig; + struct packed{ + logic next; + logic load_next; + } error3_trig; + } error_intr_trig_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + } notif_cmd_done_trig; + } notif_intr_trig_r; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + logic incrthreshold; + logic incrsaturate; + } cnt; + } error0_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + logic incrthreshold; + logic incrsaturate; + } cnt; + } error1_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + logic incrthreshold; + logic incrsaturate; + } cnt; + } error2_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + logic incrthreshold; + logic incrsaturate; + } cnt; + } error3_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + logic incrthreshold; + logic incrsaturate; + } cnt; + } notif_cmd_done_intr_count_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + logic decrthreshold; + logic underflow; + } pulse; + } error0_intr_count_incr_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + logic decrthreshold; + logic underflow; + } pulse; + } error1_intr_count_incr_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + logic decrthreshold; + logic underflow; + } pulse; + } error2_intr_count_incr_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + logic decrthreshold; + logic underflow; + } pulse; + } error3_intr_count_incr_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + logic decrthreshold; + logic underflow; + } pulse; + } notif_cmd_done_intr_count_incr_r; + } intr_block_rf; + } field_combo_t; + field_combo_t field_combo; + + typedef struct packed{ + struct packed{ + struct packed{ + logic [31:0] value; + } ENTROPY_IF_SEED; + } [9-1:0]ENTROPY_IF_SEED; + struct packed{ + struct packed{ + logic value; + } ENDIAN_SWAP; + } CTRL0; + struct packed{ + struct packed{ + logic value; + } read_en; + struct packed{ + logic [4:0] value; + } read_entry; + struct packed{ + logic value; + } pcr_hash_extend; + struct packed{ + logic [24:0] value; + } rsvd; + } AES_KV_RD_KEY_CTRL; + struct packed{ + struct packed{ + logic value; + } VALID; + } AES_KV_RD_KEY_STATUS; + struct packed{ + struct packed{ + logic value; + } write_en; + struct packed{ + logic [4:0] value; + } write_entry; + struct packed{ + logic value; + } hmac_key_dest_valid; + struct packed{ + logic value; + } hmac_block_dest_valid; + struct packed{ + logic value; + } mldsa_seed_dest_valid; + struct packed{ + logic value; + } ecc_pkey_dest_valid; + struct packed{ + logic value; + } ecc_seed_dest_valid; + struct packed{ + logic value; + } aes_key_dest_valid; + struct packed{ + logic value; + } mlkem_seed_dest_valid; + struct packed{ + logic value; + } mlkem_msg_dest_valid; + struct packed{ + logic value; + } dma_data_dest_valid; + struct packed{ + logic [16:0] value; + } rsvd; + } AES_KV_WR_CTRL; + struct packed{ + struct packed{ + logic value; + } VALID; + } AES_KV_WR_STATUS; + struct packed{ + struct packed{ + struct packed{ + logic value; + } error_en; + struct packed{ + logic value; + } notif_en; + } global_intr_en_r; + struct packed{ + struct packed{ + logic value; + } error0_en; + struct packed{ + logic value; + } error1_en; + struct packed{ + logic value; + } error2_en; + struct packed{ + logic value; + } error3_en; + } error_intr_en_r; + struct packed{ + struct packed{ + logic value; + } notif_cmd_done_en; + } notif_intr_en_r; + struct packed{ + struct packed{ + logic value; + } agg_sts; + } error_global_intr_r; + struct packed{ + struct packed{ + logic value; + } agg_sts; + } notif_global_intr_r; + struct packed{ + struct packed{ + logic value; + } error0_sts; + struct packed{ + logic value; + } error1_sts; + struct packed{ + logic value; + } error2_sts; + struct packed{ + logic value; + } error3_sts; + } error_internal_intr_r; + struct packed{ + struct packed{ + logic value; + } notif_cmd_done_sts; + } notif_internal_intr_r; + struct packed{ + struct packed{ + logic value; + } error0_trig; + struct packed{ + logic value; + } error1_trig; + struct packed{ + logic value; + } error2_trig; + struct packed{ + logic value; + } error3_trig; + } error_intr_trig_r; + struct packed{ + struct packed{ + logic value; + } notif_cmd_done_trig; + } notif_intr_trig_r; + struct packed{ + struct packed{ + logic [31:0] value; + } cnt; + } error0_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] value; + } cnt; + } error1_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] value; + } cnt; + } error2_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] value; + } cnt; + } error3_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] value; + } cnt; + } notif_cmd_done_intr_count_r; + struct packed{ + struct packed{ + logic value; + } pulse; + } error0_intr_count_incr_r; + struct packed{ + struct packed{ + logic value; + } pulse; + } error1_intr_count_incr_r; + struct packed{ + struct packed{ + logic value; + } pulse; + } error2_intr_count_incr_r; + struct packed{ + struct packed{ + logic value; + } pulse; + } error3_intr_count_incr_r; + struct packed{ + struct packed{ + logic value; + } pulse; + } notif_cmd_done_intr_count_incr_r; + } intr_block_rf; + } field_storage_t; + field_storage_t field_storage; + + for(genvar i0=0; i0<9; i0++) begin + // Field: aes_clp_reg.ENTROPY_IF_SEED[].ENTROPY_IF_SEED + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.ENTROPY_IF_SEED[i0].ENTROPY_IF_SEED.value; + load_next_c = '0; + if(decoded_reg_strb.ENTROPY_IF_SEED[i0] && decoded_req_is_wr) begin // SW write + next_c = (field_storage.ENTROPY_IF_SEED[i0].ENTROPY_IF_SEED.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + field_combo.ENTROPY_IF_SEED[i0].ENTROPY_IF_SEED.next = next_c; + field_combo.ENTROPY_IF_SEED[i0].ENTROPY_IF_SEED.load_next = load_next_c; + end + + always_ff @(posedge clk) begin + if(field_combo.ENTROPY_IF_SEED[i0].ENTROPY_IF_SEED.load_next) begin + field_storage.ENTROPY_IF_SEED[i0].ENTROPY_IF_SEED.value <= field_combo.ENTROPY_IF_SEED[i0].ENTROPY_IF_SEED.next; + end + end + assign hwif_out.ENTROPY_IF_SEED[i0].ENTROPY_IF_SEED.value = field_storage.ENTROPY_IF_SEED[i0].ENTROPY_IF_SEED.value; + assign hwif_out.ENTROPY_IF_SEED[i0].ENTROPY_IF_SEED.swmod = decoded_reg_strb.ENTROPY_IF_SEED[i0] && decoded_req_is_wr; + end + // Field: aes_clp_reg.CTRL0.ENDIAN_SWAP + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.CTRL0.ENDIAN_SWAP.value; + load_next_c = '0; + if(decoded_reg_strb.CTRL0 && decoded_req_is_wr) begin // SW write + next_c = (field_storage.CTRL0.ENDIAN_SWAP.value & ~decoded_wr_biten[0:0]) | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end + field_combo.CTRL0.ENDIAN_SWAP.next = next_c; + field_combo.CTRL0.ENDIAN_SWAP.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.CTRL0.ENDIAN_SWAP.value <= 1'h0; + end else if(field_combo.CTRL0.ENDIAN_SWAP.load_next) begin + field_storage.CTRL0.ENDIAN_SWAP.value <= field_combo.CTRL0.ENDIAN_SWAP.next; + end + end + assign hwif_out.CTRL0.ENDIAN_SWAP.value = field_storage.CTRL0.ENDIAN_SWAP.value; + // Field: aes_clp_reg.AES_KV_RD_KEY_CTRL.read_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.AES_KV_RD_KEY_CTRL.read_en.value; + load_next_c = '0; + if(decoded_reg_strb.AES_KV_RD_KEY_CTRL && decoded_req_is_wr && hwif_in.AES_KV_RD_KEY_CTRL.read_en.swwe) begin // SW write + next_c = (field_storage.AES_KV_RD_KEY_CTRL.read_en.value & ~decoded_wr_biten[0:0]) | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end else if(hwif_in.AES_KV_RD_KEY_CTRL.read_en.hwclr) begin // HW Clear + next_c = '0; + load_next_c = '1; + end + field_combo.AES_KV_RD_KEY_CTRL.read_en.next = next_c; + field_combo.AES_KV_RD_KEY_CTRL.read_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.AES_KV_RD_KEY_CTRL.read_en.value <= 1'h0; + end else if(field_combo.AES_KV_RD_KEY_CTRL.read_en.load_next) begin + field_storage.AES_KV_RD_KEY_CTRL.read_en.value <= field_combo.AES_KV_RD_KEY_CTRL.read_en.next; + end + end + assign hwif_out.AES_KV_RD_KEY_CTRL.read_en.value = field_storage.AES_KV_RD_KEY_CTRL.read_en.value; + // Field: aes_clp_reg.AES_KV_RD_KEY_CTRL.read_entry + always_comb begin + automatic logic [4:0] next_c; + automatic logic load_next_c; + next_c = field_storage.AES_KV_RD_KEY_CTRL.read_entry.value; + load_next_c = '0; + if(decoded_reg_strb.AES_KV_RD_KEY_CTRL && decoded_req_is_wr && hwif_in.AES_KV_RD_KEY_CTRL.read_entry.swwe) begin // SW write + next_c = (field_storage.AES_KV_RD_KEY_CTRL.read_entry.value & ~decoded_wr_biten[5:1]) | (decoded_wr_data[5:1] & decoded_wr_biten[5:1]); + load_next_c = '1; + end + field_combo.AES_KV_RD_KEY_CTRL.read_entry.next = next_c; + field_combo.AES_KV_RD_KEY_CTRL.read_entry.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.AES_KV_RD_KEY_CTRL.read_entry.value <= 5'h0; + end else if(field_combo.AES_KV_RD_KEY_CTRL.read_entry.load_next) begin + field_storage.AES_KV_RD_KEY_CTRL.read_entry.value <= field_combo.AES_KV_RD_KEY_CTRL.read_entry.next; + end + end + assign hwif_out.AES_KV_RD_KEY_CTRL.read_entry.value = field_storage.AES_KV_RD_KEY_CTRL.read_entry.value; + // Field: aes_clp_reg.AES_KV_RD_KEY_CTRL.pcr_hash_extend + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.AES_KV_RD_KEY_CTRL.pcr_hash_extend.value; + load_next_c = '0; + if(decoded_reg_strb.AES_KV_RD_KEY_CTRL && decoded_req_is_wr && hwif_in.AES_KV_RD_KEY_CTRL.pcr_hash_extend.swwe) begin // SW write + next_c = (field_storage.AES_KV_RD_KEY_CTRL.pcr_hash_extend.value & ~decoded_wr_biten[6:6]) | (decoded_wr_data[6:6] & decoded_wr_biten[6:6]); + load_next_c = '1; + end + field_combo.AES_KV_RD_KEY_CTRL.pcr_hash_extend.next = next_c; + field_combo.AES_KV_RD_KEY_CTRL.pcr_hash_extend.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.AES_KV_RD_KEY_CTRL.pcr_hash_extend.value <= 1'h0; + end else if(field_combo.AES_KV_RD_KEY_CTRL.pcr_hash_extend.load_next) begin + field_storage.AES_KV_RD_KEY_CTRL.pcr_hash_extend.value <= field_combo.AES_KV_RD_KEY_CTRL.pcr_hash_extend.next; + end + end + assign hwif_out.AES_KV_RD_KEY_CTRL.pcr_hash_extend.value = field_storage.AES_KV_RD_KEY_CTRL.pcr_hash_extend.value; + // Field: aes_clp_reg.AES_KV_RD_KEY_CTRL.rsvd + always_comb begin + automatic logic [24:0] next_c; + automatic logic load_next_c; + next_c = field_storage.AES_KV_RD_KEY_CTRL.rsvd.value; + load_next_c = '0; + if(decoded_reg_strb.AES_KV_RD_KEY_CTRL && decoded_req_is_wr && hwif_in.AES_KV_RD_KEY_CTRL.rsvd.swwe) begin // SW write + next_c = (field_storage.AES_KV_RD_KEY_CTRL.rsvd.value & ~decoded_wr_biten[31:7]) | (decoded_wr_data[31:7] & decoded_wr_biten[31:7]); + load_next_c = '1; + end + field_combo.AES_KV_RD_KEY_CTRL.rsvd.next = next_c; + field_combo.AES_KV_RD_KEY_CTRL.rsvd.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.AES_KV_RD_KEY_CTRL.rsvd.value <= 25'h0; + end else if(field_combo.AES_KV_RD_KEY_CTRL.rsvd.load_next) begin + field_storage.AES_KV_RD_KEY_CTRL.rsvd.value <= field_combo.AES_KV_RD_KEY_CTRL.rsvd.next; + end + end + assign hwif_out.AES_KV_RD_KEY_CTRL.rsvd.value = field_storage.AES_KV_RD_KEY_CTRL.rsvd.value; + // Field: aes_clp_reg.AES_KV_RD_KEY_STATUS.VALID + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.AES_KV_RD_KEY_STATUS.VALID.value; + load_next_c = '0; + if(hwif_in.AES_KV_RD_KEY_STATUS.VALID.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end else if(hwif_in.AES_KV_RD_KEY_STATUS.VALID.hwclr) begin // HW Clear + next_c = '0; + load_next_c = '1; + end + field_combo.AES_KV_RD_KEY_STATUS.VALID.next = next_c; + field_combo.AES_KV_RD_KEY_STATUS.VALID.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.AES_KV_RD_KEY_STATUS.VALID.value <= 1'h0; + end else if(field_combo.AES_KV_RD_KEY_STATUS.VALID.load_next) begin + field_storage.AES_KV_RD_KEY_STATUS.VALID.value <= field_combo.AES_KV_RD_KEY_STATUS.VALID.next; + end + end + // Field: aes_clp_reg.AES_KV_WR_CTRL.write_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.AES_KV_WR_CTRL.write_en.value; + load_next_c = '0; + if(decoded_reg_strb.AES_KV_WR_CTRL && decoded_req_is_wr && hwif_in.AES_KV_WR_CTRL.write_en.swwe) begin // SW write + next_c = (field_storage.AES_KV_WR_CTRL.write_en.value & ~decoded_wr_biten[0:0]) | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end else if(hwif_in.AES_KV_WR_CTRL.write_en.hwclr) begin // HW Clear + next_c = '0; + load_next_c = '1; + end + field_combo.AES_KV_WR_CTRL.write_en.next = next_c; + field_combo.AES_KV_WR_CTRL.write_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.AES_KV_WR_CTRL.write_en.value <= 1'h0; + end else if(field_combo.AES_KV_WR_CTRL.write_en.load_next) begin + field_storage.AES_KV_WR_CTRL.write_en.value <= field_combo.AES_KV_WR_CTRL.write_en.next; + end + end + assign hwif_out.AES_KV_WR_CTRL.write_en.value = field_storage.AES_KV_WR_CTRL.write_en.value; + // Field: aes_clp_reg.AES_KV_WR_CTRL.write_entry + always_comb begin + automatic logic [4:0] next_c; + automatic logic load_next_c; + next_c = field_storage.AES_KV_WR_CTRL.write_entry.value; + load_next_c = '0; + if(decoded_reg_strb.AES_KV_WR_CTRL && decoded_req_is_wr && hwif_in.AES_KV_WR_CTRL.write_entry.swwe) begin // SW write + next_c = (field_storage.AES_KV_WR_CTRL.write_entry.value & ~decoded_wr_biten[5:1]) | (decoded_wr_data[5:1] & decoded_wr_biten[5:1]); + load_next_c = '1; + end + field_combo.AES_KV_WR_CTRL.write_entry.next = next_c; + field_combo.AES_KV_WR_CTRL.write_entry.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.AES_KV_WR_CTRL.write_entry.value <= 5'h0; + end else if(field_combo.AES_KV_WR_CTRL.write_entry.load_next) begin + field_storage.AES_KV_WR_CTRL.write_entry.value <= field_combo.AES_KV_WR_CTRL.write_entry.next; + end + end + assign hwif_out.AES_KV_WR_CTRL.write_entry.value = field_storage.AES_KV_WR_CTRL.write_entry.value; + // Field: aes_clp_reg.AES_KV_WR_CTRL.hmac_key_dest_valid + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.AES_KV_WR_CTRL.hmac_key_dest_valid.value; + load_next_c = '0; + if(decoded_reg_strb.AES_KV_WR_CTRL && decoded_req_is_wr && hwif_in.AES_KV_WR_CTRL.hmac_key_dest_valid.swwe) begin // SW write + next_c = (field_storage.AES_KV_WR_CTRL.hmac_key_dest_valid.value & ~decoded_wr_biten[6:6]) | (decoded_wr_data[6:6] & decoded_wr_biten[6:6]); + load_next_c = '1; + end + field_combo.AES_KV_WR_CTRL.hmac_key_dest_valid.next = next_c; + field_combo.AES_KV_WR_CTRL.hmac_key_dest_valid.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.AES_KV_WR_CTRL.hmac_key_dest_valid.value <= 1'h0; + end else if(field_combo.AES_KV_WR_CTRL.hmac_key_dest_valid.load_next) begin + field_storage.AES_KV_WR_CTRL.hmac_key_dest_valid.value <= field_combo.AES_KV_WR_CTRL.hmac_key_dest_valid.next; + end + end + assign hwif_out.AES_KV_WR_CTRL.hmac_key_dest_valid.value = field_storage.AES_KV_WR_CTRL.hmac_key_dest_valid.value; + // Field: aes_clp_reg.AES_KV_WR_CTRL.hmac_block_dest_valid + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.AES_KV_WR_CTRL.hmac_block_dest_valid.value; + load_next_c = '0; + if(decoded_reg_strb.AES_KV_WR_CTRL && decoded_req_is_wr && hwif_in.AES_KV_WR_CTRL.hmac_block_dest_valid.swwe) begin // SW write + next_c = (field_storage.AES_KV_WR_CTRL.hmac_block_dest_valid.value & ~decoded_wr_biten[7:7]) | (decoded_wr_data[7:7] & decoded_wr_biten[7:7]); + load_next_c = '1; + end + field_combo.AES_KV_WR_CTRL.hmac_block_dest_valid.next = next_c; + field_combo.AES_KV_WR_CTRL.hmac_block_dest_valid.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.AES_KV_WR_CTRL.hmac_block_dest_valid.value <= 1'h0; + end else if(field_combo.AES_KV_WR_CTRL.hmac_block_dest_valid.load_next) begin + field_storage.AES_KV_WR_CTRL.hmac_block_dest_valid.value <= field_combo.AES_KV_WR_CTRL.hmac_block_dest_valid.next; + end + end + assign hwif_out.AES_KV_WR_CTRL.hmac_block_dest_valid.value = field_storage.AES_KV_WR_CTRL.hmac_block_dest_valid.value; + // Field: aes_clp_reg.AES_KV_WR_CTRL.mldsa_seed_dest_valid + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.AES_KV_WR_CTRL.mldsa_seed_dest_valid.value; + load_next_c = '0; + if(decoded_reg_strb.AES_KV_WR_CTRL && decoded_req_is_wr && hwif_in.AES_KV_WR_CTRL.mldsa_seed_dest_valid.swwe) begin // SW write + next_c = (field_storage.AES_KV_WR_CTRL.mldsa_seed_dest_valid.value & ~decoded_wr_biten[8:8]) | (decoded_wr_data[8:8] & decoded_wr_biten[8:8]); + load_next_c = '1; + end + field_combo.AES_KV_WR_CTRL.mldsa_seed_dest_valid.next = next_c; + field_combo.AES_KV_WR_CTRL.mldsa_seed_dest_valid.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.AES_KV_WR_CTRL.mldsa_seed_dest_valid.value <= 1'h0; + end else if(field_combo.AES_KV_WR_CTRL.mldsa_seed_dest_valid.load_next) begin + field_storage.AES_KV_WR_CTRL.mldsa_seed_dest_valid.value <= field_combo.AES_KV_WR_CTRL.mldsa_seed_dest_valid.next; + end + end + assign hwif_out.AES_KV_WR_CTRL.mldsa_seed_dest_valid.value = field_storage.AES_KV_WR_CTRL.mldsa_seed_dest_valid.value; + // Field: aes_clp_reg.AES_KV_WR_CTRL.ecc_pkey_dest_valid + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.AES_KV_WR_CTRL.ecc_pkey_dest_valid.value; + load_next_c = '0; + if(decoded_reg_strb.AES_KV_WR_CTRL && decoded_req_is_wr && hwif_in.AES_KV_WR_CTRL.ecc_pkey_dest_valid.swwe) begin // SW write + next_c = (field_storage.AES_KV_WR_CTRL.ecc_pkey_dest_valid.value & ~decoded_wr_biten[9:9]) | (decoded_wr_data[9:9] & decoded_wr_biten[9:9]); + load_next_c = '1; + end + field_combo.AES_KV_WR_CTRL.ecc_pkey_dest_valid.next = next_c; + field_combo.AES_KV_WR_CTRL.ecc_pkey_dest_valid.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.AES_KV_WR_CTRL.ecc_pkey_dest_valid.value <= 1'h0; + end else if(field_combo.AES_KV_WR_CTRL.ecc_pkey_dest_valid.load_next) begin + field_storage.AES_KV_WR_CTRL.ecc_pkey_dest_valid.value <= field_combo.AES_KV_WR_CTRL.ecc_pkey_dest_valid.next; + end + end + assign hwif_out.AES_KV_WR_CTRL.ecc_pkey_dest_valid.value = field_storage.AES_KV_WR_CTRL.ecc_pkey_dest_valid.value; + // Field: aes_clp_reg.AES_KV_WR_CTRL.ecc_seed_dest_valid + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.AES_KV_WR_CTRL.ecc_seed_dest_valid.value; + load_next_c = '0; + if(decoded_reg_strb.AES_KV_WR_CTRL && decoded_req_is_wr && hwif_in.AES_KV_WR_CTRL.ecc_seed_dest_valid.swwe) begin // SW write + next_c = (field_storage.AES_KV_WR_CTRL.ecc_seed_dest_valid.value & ~decoded_wr_biten[10:10]) | (decoded_wr_data[10:10] & decoded_wr_biten[10:10]); + load_next_c = '1; + end + field_combo.AES_KV_WR_CTRL.ecc_seed_dest_valid.next = next_c; + field_combo.AES_KV_WR_CTRL.ecc_seed_dest_valid.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.AES_KV_WR_CTRL.ecc_seed_dest_valid.value <= 1'h0; + end else if(field_combo.AES_KV_WR_CTRL.ecc_seed_dest_valid.load_next) begin + field_storage.AES_KV_WR_CTRL.ecc_seed_dest_valid.value <= field_combo.AES_KV_WR_CTRL.ecc_seed_dest_valid.next; + end + end + assign hwif_out.AES_KV_WR_CTRL.ecc_seed_dest_valid.value = field_storage.AES_KV_WR_CTRL.ecc_seed_dest_valid.value; + // Field: aes_clp_reg.AES_KV_WR_CTRL.aes_key_dest_valid + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.AES_KV_WR_CTRL.aes_key_dest_valid.value; + load_next_c = '0; + if(decoded_reg_strb.AES_KV_WR_CTRL && decoded_req_is_wr && hwif_in.AES_KV_WR_CTRL.aes_key_dest_valid.swwe) begin // SW write + next_c = (field_storage.AES_KV_WR_CTRL.aes_key_dest_valid.value & ~decoded_wr_biten[11:11]) | (decoded_wr_data[11:11] & decoded_wr_biten[11:11]); + load_next_c = '1; + end + field_combo.AES_KV_WR_CTRL.aes_key_dest_valid.next = next_c; + field_combo.AES_KV_WR_CTRL.aes_key_dest_valid.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.AES_KV_WR_CTRL.aes_key_dest_valid.value <= 1'h0; + end else if(field_combo.AES_KV_WR_CTRL.aes_key_dest_valid.load_next) begin + field_storage.AES_KV_WR_CTRL.aes_key_dest_valid.value <= field_combo.AES_KV_WR_CTRL.aes_key_dest_valid.next; + end + end + assign hwif_out.AES_KV_WR_CTRL.aes_key_dest_valid.value = field_storage.AES_KV_WR_CTRL.aes_key_dest_valid.value; + // Field: aes_clp_reg.AES_KV_WR_CTRL.mlkem_seed_dest_valid + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.AES_KV_WR_CTRL.mlkem_seed_dest_valid.value; + load_next_c = '0; + if(decoded_reg_strb.AES_KV_WR_CTRL && decoded_req_is_wr && hwif_in.AES_KV_WR_CTRL.mlkem_seed_dest_valid.swwe) begin // SW write + next_c = (field_storage.AES_KV_WR_CTRL.mlkem_seed_dest_valid.value & ~decoded_wr_biten[12:12]) | (decoded_wr_data[12:12] & decoded_wr_biten[12:12]); + load_next_c = '1; + end + field_combo.AES_KV_WR_CTRL.mlkem_seed_dest_valid.next = next_c; + field_combo.AES_KV_WR_CTRL.mlkem_seed_dest_valid.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.AES_KV_WR_CTRL.mlkem_seed_dest_valid.value <= 1'h0; + end else if(field_combo.AES_KV_WR_CTRL.mlkem_seed_dest_valid.load_next) begin + field_storage.AES_KV_WR_CTRL.mlkem_seed_dest_valid.value <= field_combo.AES_KV_WR_CTRL.mlkem_seed_dest_valid.next; + end + end + assign hwif_out.AES_KV_WR_CTRL.mlkem_seed_dest_valid.value = field_storage.AES_KV_WR_CTRL.mlkem_seed_dest_valid.value; + // Field: aes_clp_reg.AES_KV_WR_CTRL.mlkem_msg_dest_valid + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.AES_KV_WR_CTRL.mlkem_msg_dest_valid.value; + load_next_c = '0; + if(decoded_reg_strb.AES_KV_WR_CTRL && decoded_req_is_wr && hwif_in.AES_KV_WR_CTRL.mlkem_msg_dest_valid.swwe) begin // SW write + next_c = (field_storage.AES_KV_WR_CTRL.mlkem_msg_dest_valid.value & ~decoded_wr_biten[13:13]) | (decoded_wr_data[13:13] & decoded_wr_biten[13:13]); + load_next_c = '1; + end + field_combo.AES_KV_WR_CTRL.mlkem_msg_dest_valid.next = next_c; + field_combo.AES_KV_WR_CTRL.mlkem_msg_dest_valid.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.AES_KV_WR_CTRL.mlkem_msg_dest_valid.value <= 1'h0; + end else if(field_combo.AES_KV_WR_CTRL.mlkem_msg_dest_valid.load_next) begin + field_storage.AES_KV_WR_CTRL.mlkem_msg_dest_valid.value <= field_combo.AES_KV_WR_CTRL.mlkem_msg_dest_valid.next; + end + end + assign hwif_out.AES_KV_WR_CTRL.mlkem_msg_dest_valid.value = field_storage.AES_KV_WR_CTRL.mlkem_msg_dest_valid.value; + // Field: aes_clp_reg.AES_KV_WR_CTRL.dma_data_dest_valid + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.AES_KV_WR_CTRL.dma_data_dest_valid.value; + load_next_c = '0; + if(decoded_reg_strb.AES_KV_WR_CTRL && decoded_req_is_wr && hwif_in.AES_KV_WR_CTRL.dma_data_dest_valid.swwe) begin // SW write + next_c = (field_storage.AES_KV_WR_CTRL.dma_data_dest_valid.value & ~decoded_wr_biten[14:14]) | (decoded_wr_data[14:14] & decoded_wr_biten[14:14]); + load_next_c = '1; + end + field_combo.AES_KV_WR_CTRL.dma_data_dest_valid.next = next_c; + field_combo.AES_KV_WR_CTRL.dma_data_dest_valid.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.AES_KV_WR_CTRL.dma_data_dest_valid.value <= 1'h0; + end else if(field_combo.AES_KV_WR_CTRL.dma_data_dest_valid.load_next) begin + field_storage.AES_KV_WR_CTRL.dma_data_dest_valid.value <= field_combo.AES_KV_WR_CTRL.dma_data_dest_valid.next; + end + end + assign hwif_out.AES_KV_WR_CTRL.dma_data_dest_valid.value = field_storage.AES_KV_WR_CTRL.dma_data_dest_valid.value; + // Field: aes_clp_reg.AES_KV_WR_CTRL.rsvd + always_comb begin + automatic logic [16:0] next_c; + automatic logic load_next_c; + next_c = field_storage.AES_KV_WR_CTRL.rsvd.value; + load_next_c = '0; + if(decoded_reg_strb.AES_KV_WR_CTRL && decoded_req_is_wr && hwif_in.AES_KV_WR_CTRL.rsvd.swwe) begin // SW write + next_c = (field_storage.AES_KV_WR_CTRL.rsvd.value & ~decoded_wr_biten[31:15]) | (decoded_wr_data[31:15] & decoded_wr_biten[31:15]); + load_next_c = '1; + end + field_combo.AES_KV_WR_CTRL.rsvd.next = next_c; + field_combo.AES_KV_WR_CTRL.rsvd.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.AES_KV_WR_CTRL.rsvd.value <= 17'h0; + end else if(field_combo.AES_KV_WR_CTRL.rsvd.load_next) begin + field_storage.AES_KV_WR_CTRL.rsvd.value <= field_combo.AES_KV_WR_CTRL.rsvd.next; + end + end + assign hwif_out.AES_KV_WR_CTRL.rsvd.value = field_storage.AES_KV_WR_CTRL.rsvd.value; + // Field: aes_clp_reg.AES_KV_WR_STATUS.VALID + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.AES_KV_WR_STATUS.VALID.value; + load_next_c = '0; + if(hwif_in.AES_KV_WR_STATUS.VALID.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end else if(hwif_in.AES_KV_WR_STATUS.VALID.hwclr) begin // HW Clear + next_c = '0; + load_next_c = '1; + end + field_combo.AES_KV_WR_STATUS.VALID.next = next_c; + field_combo.AES_KV_WR_STATUS.VALID.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.AES_KV_WR_STATUS.VALID.value <= 1'h0; + end else if(field_combo.AES_KV_WR_STATUS.VALID.load_next) begin + field_storage.AES_KV_WR_STATUS.VALID.value <= field_combo.AES_KV_WR_STATUS.VALID.next; + end + end + // Field: aes_clp_reg.intr_block_rf.global_intr_en_r.error_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.global_intr_en_r.error_en.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.global_intr_en_r && decoded_req_is_wr) begin // SW write + next_c = (field_storage.intr_block_rf.global_intr_en_r.error_en.value & ~decoded_wr_biten[0:0]) | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end + field_combo.intr_block_rf.global_intr_en_r.error_en.next = next_c; + field_combo.intr_block_rf.global_intr_en_r.error_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.global_intr_en_r.error_en.value <= 1'h0; + end else if(field_combo.intr_block_rf.global_intr_en_r.error_en.load_next) begin + field_storage.intr_block_rf.global_intr_en_r.error_en.value <= field_combo.intr_block_rf.global_intr_en_r.error_en.next; + end + end + // Field: aes_clp_reg.intr_block_rf.global_intr_en_r.notif_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.global_intr_en_r.notif_en.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.global_intr_en_r && decoded_req_is_wr) begin // SW write + next_c = (field_storage.intr_block_rf.global_intr_en_r.notif_en.value & ~decoded_wr_biten[1:1]) | (decoded_wr_data[1:1] & decoded_wr_biten[1:1]); + load_next_c = '1; + end + field_combo.intr_block_rf.global_intr_en_r.notif_en.next = next_c; + field_combo.intr_block_rf.global_intr_en_r.notif_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.global_intr_en_r.notif_en.value <= 1'h0; + end else if(field_combo.intr_block_rf.global_intr_en_r.notif_en.load_next) begin + field_storage.intr_block_rf.global_intr_en_r.notif_en.value <= field_combo.intr_block_rf.global_intr_en_r.notif_en.next; + end + end + // Field: aes_clp_reg.intr_block_rf.error_intr_en_r.error0_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_intr_en_r.error0_en.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_intr_en_r && decoded_req_is_wr) begin // SW write + next_c = (field_storage.intr_block_rf.error_intr_en_r.error0_en.value & ~decoded_wr_biten[0:0]) | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end + field_combo.intr_block_rf.error_intr_en_r.error0_en.next = next_c; + field_combo.intr_block_rf.error_intr_en_r.error0_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.error_intr_en_r.error0_en.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_intr_en_r.error0_en.load_next) begin + field_storage.intr_block_rf.error_intr_en_r.error0_en.value <= field_combo.intr_block_rf.error_intr_en_r.error0_en.next; + end + end + // Field: aes_clp_reg.intr_block_rf.error_intr_en_r.error1_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_intr_en_r.error1_en.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_intr_en_r && decoded_req_is_wr) begin // SW write + next_c = (field_storage.intr_block_rf.error_intr_en_r.error1_en.value & ~decoded_wr_biten[1:1]) | (decoded_wr_data[1:1] & decoded_wr_biten[1:1]); + load_next_c = '1; + end + field_combo.intr_block_rf.error_intr_en_r.error1_en.next = next_c; + field_combo.intr_block_rf.error_intr_en_r.error1_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.error_intr_en_r.error1_en.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_intr_en_r.error1_en.load_next) begin + field_storage.intr_block_rf.error_intr_en_r.error1_en.value <= field_combo.intr_block_rf.error_intr_en_r.error1_en.next; + end + end + // Field: aes_clp_reg.intr_block_rf.error_intr_en_r.error2_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_intr_en_r.error2_en.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_intr_en_r && decoded_req_is_wr) begin // SW write + next_c = (field_storage.intr_block_rf.error_intr_en_r.error2_en.value & ~decoded_wr_biten[2:2]) | (decoded_wr_data[2:2] & decoded_wr_biten[2:2]); + load_next_c = '1; + end + field_combo.intr_block_rf.error_intr_en_r.error2_en.next = next_c; + field_combo.intr_block_rf.error_intr_en_r.error2_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.error_intr_en_r.error2_en.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_intr_en_r.error2_en.load_next) begin + field_storage.intr_block_rf.error_intr_en_r.error2_en.value <= field_combo.intr_block_rf.error_intr_en_r.error2_en.next; + end + end + // Field: aes_clp_reg.intr_block_rf.error_intr_en_r.error3_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_intr_en_r.error3_en.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_intr_en_r && decoded_req_is_wr) begin // SW write + next_c = (field_storage.intr_block_rf.error_intr_en_r.error3_en.value & ~decoded_wr_biten[3:3]) | (decoded_wr_data[3:3] & decoded_wr_biten[3:3]); + load_next_c = '1; + end + field_combo.intr_block_rf.error_intr_en_r.error3_en.next = next_c; + field_combo.intr_block_rf.error_intr_en_r.error3_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.error_intr_en_r.error3_en.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_intr_en_r.error3_en.load_next) begin + field_storage.intr_block_rf.error_intr_en_r.error3_en.value <= field_combo.intr_block_rf.error_intr_en_r.error3_en.next; + end + end + // Field: aes_clp_reg.intr_block_rf.notif_intr_en_r.notif_cmd_done_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_intr_en_r.notif_cmd_done_en.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.notif_intr_en_r && decoded_req_is_wr) begin // SW write + next_c = (field_storage.intr_block_rf.notif_intr_en_r.notif_cmd_done_en.value & ~decoded_wr_biten[0:0]) | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end + field_combo.intr_block_rf.notif_intr_en_r.notif_cmd_done_en.next = next_c; + field_combo.intr_block_rf.notif_intr_en_r.notif_cmd_done_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.notif_intr_en_r.notif_cmd_done_en.value <= 1'h0; + end else if(field_combo.intr_block_rf.notif_intr_en_r.notif_cmd_done_en.load_next) begin + field_storage.intr_block_rf.notif_intr_en_r.notif_cmd_done_en.value <= field_combo.intr_block_rf.notif_intr_en_r.notif_cmd_done_en.next; + end + end + // Field: aes_clp_reg.intr_block_rf.error_global_intr_r.agg_sts + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_global_intr_r.agg_sts.value; + load_next_c = '0; + + // HW Write + next_c = hwif_out.intr_block_rf.error_internal_intr_r.intr; + load_next_c = '1; + field_combo.intr_block_rf.error_global_intr_r.agg_sts.next = next_c; + field_combo.intr_block_rf.error_global_intr_r.agg_sts.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.error_global_intr_r.agg_sts.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_global_intr_r.agg_sts.load_next) begin + field_storage.intr_block_rf.error_global_intr_r.agg_sts.value <= field_combo.intr_block_rf.error_global_intr_r.agg_sts.next; + end + end + assign hwif_out.intr_block_rf.error_global_intr_r.intr = + |(field_storage.intr_block_rf.error_global_intr_r.agg_sts.value & field_storage.intr_block_rf.global_intr_en_r.error_en.value); + // Field: aes_clp_reg.intr_block_rf.notif_global_intr_r.agg_sts + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_global_intr_r.agg_sts.value; + load_next_c = '0; + + // HW Write + next_c = hwif_out.intr_block_rf.notif_internal_intr_r.intr; + load_next_c = '1; + field_combo.intr_block_rf.notif_global_intr_r.agg_sts.next = next_c; + field_combo.intr_block_rf.notif_global_intr_r.agg_sts.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.notif_global_intr_r.agg_sts.value <= 1'h0; + end else if(field_combo.intr_block_rf.notif_global_intr_r.agg_sts.load_next) begin + field_storage.intr_block_rf.notif_global_intr_r.agg_sts.value <= field_combo.intr_block_rf.notif_global_intr_r.agg_sts.next; + end + end + assign hwif_out.intr_block_rf.notif_global_intr_r.intr = + |(field_storage.intr_block_rf.notif_global_intr_r.agg_sts.value & field_storage.intr_block_rf.global_intr_en_r.notif_en.value); + // Field: aes_clp_reg.intr_block_rf.error_internal_intr_r.error0_sts + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_internal_intr_r.error0_sts.value; + load_next_c = '0; + if(field_storage.intr_block_rf.error_intr_trig_r.error0_trig.value != '0) begin // stickybit + next_c = field_storage.intr_block_rf.error_internal_intr_r.error0_sts.value | field_storage.intr_block_rf.error_intr_trig_r.error0_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.error_internal_intr_r.error0_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end else if(decoded_reg_strb.intr_block_rf.error_internal_intr_r && decoded_req_is_wr) begin // SW write 1 clear + next_c = field_storage.intr_block_rf.error_internal_intr_r.error0_sts.value & ~(decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end + field_combo.intr_block_rf.error_internal_intr_r.error0_sts.next = next_c; + field_combo.intr_block_rf.error_internal_intr_r.error0_sts.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.error_reset_b) begin + if(~hwif_in.error_reset_b) begin + field_storage.intr_block_rf.error_internal_intr_r.error0_sts.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_internal_intr_r.error0_sts.load_next) begin + field_storage.intr_block_rf.error_internal_intr_r.error0_sts.value <= field_combo.intr_block_rf.error_internal_intr_r.error0_sts.next; + end + end + // Field: aes_clp_reg.intr_block_rf.error_internal_intr_r.error1_sts + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_internal_intr_r.error1_sts.value; + load_next_c = '0; + if(field_storage.intr_block_rf.error_intr_trig_r.error1_trig.value != '0) begin // stickybit + next_c = field_storage.intr_block_rf.error_internal_intr_r.error1_sts.value | field_storage.intr_block_rf.error_intr_trig_r.error1_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.error_internal_intr_r.error1_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end else if(decoded_reg_strb.intr_block_rf.error_internal_intr_r && decoded_req_is_wr) begin // SW write 1 clear + next_c = field_storage.intr_block_rf.error_internal_intr_r.error1_sts.value & ~(decoded_wr_data[1:1] & decoded_wr_biten[1:1]); + load_next_c = '1; + end + field_combo.intr_block_rf.error_internal_intr_r.error1_sts.next = next_c; + field_combo.intr_block_rf.error_internal_intr_r.error1_sts.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.error_reset_b) begin + if(~hwif_in.error_reset_b) begin + field_storage.intr_block_rf.error_internal_intr_r.error1_sts.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_internal_intr_r.error1_sts.load_next) begin + field_storage.intr_block_rf.error_internal_intr_r.error1_sts.value <= field_combo.intr_block_rf.error_internal_intr_r.error1_sts.next; + end + end + // Field: aes_clp_reg.intr_block_rf.error_internal_intr_r.error2_sts + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_internal_intr_r.error2_sts.value; + load_next_c = '0; + if(field_storage.intr_block_rf.error_intr_trig_r.error2_trig.value != '0) begin // stickybit + next_c = field_storage.intr_block_rf.error_internal_intr_r.error2_sts.value | field_storage.intr_block_rf.error_intr_trig_r.error2_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.error_internal_intr_r.error2_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end else if(decoded_reg_strb.intr_block_rf.error_internal_intr_r && decoded_req_is_wr) begin // SW write 1 clear + next_c = field_storage.intr_block_rf.error_internal_intr_r.error2_sts.value & ~(decoded_wr_data[2:2] & decoded_wr_biten[2:2]); + load_next_c = '1; + end + field_combo.intr_block_rf.error_internal_intr_r.error2_sts.next = next_c; + field_combo.intr_block_rf.error_internal_intr_r.error2_sts.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.error_reset_b) begin + if(~hwif_in.error_reset_b) begin + field_storage.intr_block_rf.error_internal_intr_r.error2_sts.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_internal_intr_r.error2_sts.load_next) begin + field_storage.intr_block_rf.error_internal_intr_r.error2_sts.value <= field_combo.intr_block_rf.error_internal_intr_r.error2_sts.next; + end + end + // Field: aes_clp_reg.intr_block_rf.error_internal_intr_r.error3_sts + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_internal_intr_r.error3_sts.value; + load_next_c = '0; + if(field_storage.intr_block_rf.error_intr_trig_r.error3_trig.value != '0) begin // stickybit + next_c = field_storage.intr_block_rf.error_internal_intr_r.error3_sts.value | field_storage.intr_block_rf.error_intr_trig_r.error3_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.error_internal_intr_r.error3_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end else if(decoded_reg_strb.intr_block_rf.error_internal_intr_r && decoded_req_is_wr) begin // SW write 1 clear + next_c = field_storage.intr_block_rf.error_internal_intr_r.error3_sts.value & ~(decoded_wr_data[3:3] & decoded_wr_biten[3:3]); + load_next_c = '1; + end + field_combo.intr_block_rf.error_internal_intr_r.error3_sts.next = next_c; + field_combo.intr_block_rf.error_internal_intr_r.error3_sts.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.error_reset_b) begin + if(~hwif_in.error_reset_b) begin + field_storage.intr_block_rf.error_internal_intr_r.error3_sts.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_internal_intr_r.error3_sts.load_next) begin + field_storage.intr_block_rf.error_internal_intr_r.error3_sts.value <= field_combo.intr_block_rf.error_internal_intr_r.error3_sts.next; + end + end + assign hwif_out.intr_block_rf.error_internal_intr_r.intr = + |(field_storage.intr_block_rf.error_internal_intr_r.error0_sts.value & field_storage.intr_block_rf.error_intr_en_r.error0_en.value) + || |(field_storage.intr_block_rf.error_internal_intr_r.error1_sts.value & field_storage.intr_block_rf.error_intr_en_r.error1_en.value) + || |(field_storage.intr_block_rf.error_internal_intr_r.error2_sts.value & field_storage.intr_block_rf.error_intr_en_r.error2_en.value) + || |(field_storage.intr_block_rf.error_internal_intr_r.error3_sts.value & field_storage.intr_block_rf.error_intr_en_r.error3_en.value); + // Field: aes_clp_reg.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.value; + load_next_c = '0; + if(field_storage.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.value != '0) begin // stickybit + next_c = field_storage.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.value | field_storage.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end else if(decoded_reg_strb.intr_block_rf.notif_internal_intr_r && decoded_req_is_wr) begin // SW write 1 clear + next_c = field_storage.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.value & ~(decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end + field_combo.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.next = next_c; + field_combo.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.value <= 1'h0; + end else if(field_combo.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.load_next) begin + field_storage.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.value <= field_combo.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.next; + end + end + assign hwif_out.intr_block_rf.notif_internal_intr_r.intr = + |(field_storage.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.value & field_storage.intr_block_rf.notif_intr_en_r.notif_cmd_done_en.value); + // Field: aes_clp_reg.intr_block_rf.error_intr_trig_r.error0_trig + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_intr_trig_r.error0_trig.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_intr_trig_r && decoded_req_is_wr) begin // SW write 1 set + next_c = field_storage.intr_block_rf.error_intr_trig_r.error0_trig.value | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end else begin // singlepulse clears back to 0 + next_c = '0; + load_next_c = '1; + end + field_combo.intr_block_rf.error_intr_trig_r.error0_trig.next = next_c; + field_combo.intr_block_rf.error_intr_trig_r.error0_trig.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.error_intr_trig_r.error0_trig.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_intr_trig_r.error0_trig.load_next) begin + field_storage.intr_block_rf.error_intr_trig_r.error0_trig.value <= field_combo.intr_block_rf.error_intr_trig_r.error0_trig.next; + end + end + // Field: aes_clp_reg.intr_block_rf.error_intr_trig_r.error1_trig + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_intr_trig_r.error1_trig.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_intr_trig_r && decoded_req_is_wr) begin // SW write 1 set + next_c = field_storage.intr_block_rf.error_intr_trig_r.error1_trig.value | (decoded_wr_data[1:1] & decoded_wr_biten[1:1]); + load_next_c = '1; + end else begin // singlepulse clears back to 0 + next_c = '0; + load_next_c = '1; + end + field_combo.intr_block_rf.error_intr_trig_r.error1_trig.next = next_c; + field_combo.intr_block_rf.error_intr_trig_r.error1_trig.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.error_intr_trig_r.error1_trig.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_intr_trig_r.error1_trig.load_next) begin + field_storage.intr_block_rf.error_intr_trig_r.error1_trig.value <= field_combo.intr_block_rf.error_intr_trig_r.error1_trig.next; + end + end + // Field: aes_clp_reg.intr_block_rf.error_intr_trig_r.error2_trig + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_intr_trig_r.error2_trig.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_intr_trig_r && decoded_req_is_wr) begin // SW write 1 set + next_c = field_storage.intr_block_rf.error_intr_trig_r.error2_trig.value | (decoded_wr_data[2:2] & decoded_wr_biten[2:2]); + load_next_c = '1; + end else begin // singlepulse clears back to 0 + next_c = '0; + load_next_c = '1; + end + field_combo.intr_block_rf.error_intr_trig_r.error2_trig.next = next_c; + field_combo.intr_block_rf.error_intr_trig_r.error2_trig.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.error_intr_trig_r.error2_trig.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_intr_trig_r.error2_trig.load_next) begin + field_storage.intr_block_rf.error_intr_trig_r.error2_trig.value <= field_combo.intr_block_rf.error_intr_trig_r.error2_trig.next; + end + end + // Field: aes_clp_reg.intr_block_rf.error_intr_trig_r.error3_trig + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_intr_trig_r.error3_trig.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_intr_trig_r && decoded_req_is_wr) begin // SW write 1 set + next_c = field_storage.intr_block_rf.error_intr_trig_r.error3_trig.value | (decoded_wr_data[3:3] & decoded_wr_biten[3:3]); + load_next_c = '1; + end else begin // singlepulse clears back to 0 + next_c = '0; + load_next_c = '1; + end + field_combo.intr_block_rf.error_intr_trig_r.error3_trig.next = next_c; + field_combo.intr_block_rf.error_intr_trig_r.error3_trig.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.error_intr_trig_r.error3_trig.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_intr_trig_r.error3_trig.load_next) begin + field_storage.intr_block_rf.error_intr_trig_r.error3_trig.value <= field_combo.intr_block_rf.error_intr_trig_r.error3_trig.next; + end + end + // Field: aes_clp_reg.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.notif_intr_trig_r && decoded_req_is_wr) begin // SW write 1 set + next_c = field_storage.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.value | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end else begin // singlepulse clears back to 0 + next_c = '0; + load_next_c = '1; + end + field_combo.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.next = next_c; + field_combo.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.value <= 1'h0; + end else if(field_combo.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.load_next) begin + field_storage.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.value <= field_combo.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.next; + end + end + // Field: aes_clp_reg.intr_block_rf.error0_intr_count_r.cnt + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error0_intr_count_r.cnt.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error0_intr_count_r && decoded_req_is_wr) begin // SW write + next_c = (field_storage.intr_block_rf.error0_intr_count_r.cnt.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + if(field_storage.intr_block_rf.error0_intr_count_incr_r.pulse.value) begin // increment + if(((33)'(next_c) + 32'h1) > 32'hffffffff) begin // up-counter saturated + next_c = 32'hffffffff; + end else begin + next_c = next_c + 32'h1; + end + load_next_c = '1; + end + field_combo.intr_block_rf.error0_intr_count_r.cnt.incrthreshold = (field_storage.intr_block_rf.error0_intr_count_r.cnt.value >= 32'hffffffff); + field_combo.intr_block_rf.error0_intr_count_r.cnt.incrsaturate = (field_storage.intr_block_rf.error0_intr_count_r.cnt.value >= 32'hffffffff); + if(next_c > 32'hffffffff) begin + next_c = 32'hffffffff; + load_next_c = '1; + end + field_combo.intr_block_rf.error0_intr_count_r.cnt.next = next_c; + field_combo.intr_block_rf.error0_intr_count_r.cnt.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.error_reset_b) begin + if(~hwif_in.error_reset_b) begin + field_storage.intr_block_rf.error0_intr_count_r.cnt.value <= 32'h0; + end else if(field_combo.intr_block_rf.error0_intr_count_r.cnt.load_next) begin + field_storage.intr_block_rf.error0_intr_count_r.cnt.value <= field_combo.intr_block_rf.error0_intr_count_r.cnt.next; + end + end + // Field: aes_clp_reg.intr_block_rf.error1_intr_count_r.cnt + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error1_intr_count_r.cnt.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error1_intr_count_r && decoded_req_is_wr) begin // SW write + next_c = (field_storage.intr_block_rf.error1_intr_count_r.cnt.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + if(field_storage.intr_block_rf.error1_intr_count_incr_r.pulse.value) begin // increment + if(((33)'(next_c) + 32'h1) > 32'hffffffff) begin // up-counter saturated + next_c = 32'hffffffff; + end else begin + next_c = next_c + 32'h1; + end + load_next_c = '1; + end + field_combo.intr_block_rf.error1_intr_count_r.cnt.incrthreshold = (field_storage.intr_block_rf.error1_intr_count_r.cnt.value >= 32'hffffffff); + field_combo.intr_block_rf.error1_intr_count_r.cnt.incrsaturate = (field_storage.intr_block_rf.error1_intr_count_r.cnt.value >= 32'hffffffff); + if(next_c > 32'hffffffff) begin + next_c = 32'hffffffff; + load_next_c = '1; + end + field_combo.intr_block_rf.error1_intr_count_r.cnt.next = next_c; + field_combo.intr_block_rf.error1_intr_count_r.cnt.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.error_reset_b) begin + if(~hwif_in.error_reset_b) begin + field_storage.intr_block_rf.error1_intr_count_r.cnt.value <= 32'h0; + end else if(field_combo.intr_block_rf.error1_intr_count_r.cnt.load_next) begin + field_storage.intr_block_rf.error1_intr_count_r.cnt.value <= field_combo.intr_block_rf.error1_intr_count_r.cnt.next; + end + end + // Field: aes_clp_reg.intr_block_rf.error2_intr_count_r.cnt + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error2_intr_count_r.cnt.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error2_intr_count_r && decoded_req_is_wr) begin // SW write + next_c = (field_storage.intr_block_rf.error2_intr_count_r.cnt.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + if(field_storage.intr_block_rf.error2_intr_count_incr_r.pulse.value) begin // increment + if(((33)'(next_c) + 32'h1) > 32'hffffffff) begin // up-counter saturated + next_c = 32'hffffffff; + end else begin + next_c = next_c + 32'h1; + end + load_next_c = '1; + end + field_combo.intr_block_rf.error2_intr_count_r.cnt.incrthreshold = (field_storage.intr_block_rf.error2_intr_count_r.cnt.value >= 32'hffffffff); + field_combo.intr_block_rf.error2_intr_count_r.cnt.incrsaturate = (field_storage.intr_block_rf.error2_intr_count_r.cnt.value >= 32'hffffffff); + if(next_c > 32'hffffffff) begin + next_c = 32'hffffffff; + load_next_c = '1; + end + field_combo.intr_block_rf.error2_intr_count_r.cnt.next = next_c; + field_combo.intr_block_rf.error2_intr_count_r.cnt.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.error_reset_b) begin + if(~hwif_in.error_reset_b) begin + field_storage.intr_block_rf.error2_intr_count_r.cnt.value <= 32'h0; + end else if(field_combo.intr_block_rf.error2_intr_count_r.cnt.load_next) begin + field_storage.intr_block_rf.error2_intr_count_r.cnt.value <= field_combo.intr_block_rf.error2_intr_count_r.cnt.next; + end + end + // Field: aes_clp_reg.intr_block_rf.error3_intr_count_r.cnt + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error3_intr_count_r.cnt.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error3_intr_count_r && decoded_req_is_wr) begin // SW write + next_c = (field_storage.intr_block_rf.error3_intr_count_r.cnt.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + if(field_storage.intr_block_rf.error3_intr_count_incr_r.pulse.value) begin // increment + if(((33)'(next_c) + 32'h1) > 32'hffffffff) begin // up-counter saturated + next_c = 32'hffffffff; + end else begin + next_c = next_c + 32'h1; + end + load_next_c = '1; + end + field_combo.intr_block_rf.error3_intr_count_r.cnt.incrthreshold = (field_storage.intr_block_rf.error3_intr_count_r.cnt.value >= 32'hffffffff); + field_combo.intr_block_rf.error3_intr_count_r.cnt.incrsaturate = (field_storage.intr_block_rf.error3_intr_count_r.cnt.value >= 32'hffffffff); + if(next_c > 32'hffffffff) begin + next_c = 32'hffffffff; + load_next_c = '1; + end + field_combo.intr_block_rf.error3_intr_count_r.cnt.next = next_c; + field_combo.intr_block_rf.error3_intr_count_r.cnt.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.error_reset_b) begin + if(~hwif_in.error_reset_b) begin + field_storage.intr_block_rf.error3_intr_count_r.cnt.value <= 32'h0; + end else if(field_combo.intr_block_rf.error3_intr_count_r.cnt.load_next) begin + field_storage.intr_block_rf.error3_intr_count_r.cnt.value <= field_combo.intr_block_rf.error3_intr_count_r.cnt.next; + end + end + // Field: aes_clp_reg.intr_block_rf.notif_cmd_done_intr_count_r.cnt + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_cmd_done_intr_count_r.cnt.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.notif_cmd_done_intr_count_r && decoded_req_is_wr) begin // SW write + next_c = (field_storage.intr_block_rf.notif_cmd_done_intr_count_r.cnt.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + if(field_storage.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.value) begin // increment + if(((33)'(next_c) + 32'h1) > 32'hffffffff) begin // up-counter saturated + next_c = 32'hffffffff; + end else begin + next_c = next_c + 32'h1; + end + load_next_c = '1; + end + field_combo.intr_block_rf.notif_cmd_done_intr_count_r.cnt.incrthreshold = (field_storage.intr_block_rf.notif_cmd_done_intr_count_r.cnt.value >= 32'hffffffff); + field_combo.intr_block_rf.notif_cmd_done_intr_count_r.cnt.incrsaturate = (field_storage.intr_block_rf.notif_cmd_done_intr_count_r.cnt.value >= 32'hffffffff); + if(next_c > 32'hffffffff) begin + next_c = 32'hffffffff; + load_next_c = '1; + end + field_combo.intr_block_rf.notif_cmd_done_intr_count_r.cnt.next = next_c; + field_combo.intr_block_rf.notif_cmd_done_intr_count_r.cnt.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.notif_cmd_done_intr_count_r.cnt.value <= 32'h0; + end else if(field_combo.intr_block_rf.notif_cmd_done_intr_count_r.cnt.load_next) begin + field_storage.intr_block_rf.notif_cmd_done_intr_count_r.cnt.value <= field_combo.intr_block_rf.notif_cmd_done_intr_count_r.cnt.next; + end + end + // Field: aes_clp_reg.intr_block_rf.error0_intr_count_incr_r.pulse + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error0_intr_count_incr_r.pulse.value; + load_next_c = '0; + if(field_storage.intr_block_rf.error_intr_trig_r.error0_trig.value) begin // HW Write - we + next_c = field_storage.intr_block_rf.error_intr_trig_r.error0_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.error_internal_intr_r.error0_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end + if(field_storage.intr_block_rf.error0_intr_count_incr_r.pulse.value) begin // decrement + field_combo.intr_block_rf.error0_intr_count_incr_r.pulse.underflow = (next_c < (1'h1)); + next_c = next_c - 1'h1; + load_next_c = '1; + end else begin + field_combo.intr_block_rf.error0_intr_count_incr_r.pulse.underflow = '0; + end + field_combo.intr_block_rf.error0_intr_count_incr_r.pulse.decrthreshold = (field_storage.intr_block_rf.error0_intr_count_incr_r.pulse.value <= 1'd0); + field_combo.intr_block_rf.error0_intr_count_incr_r.pulse.next = next_c; + field_combo.intr_block_rf.error0_intr_count_incr_r.pulse.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.error0_intr_count_incr_r.pulse.value <= 1'h0; + end else if(field_combo.intr_block_rf.error0_intr_count_incr_r.pulse.load_next) begin + field_storage.intr_block_rf.error0_intr_count_incr_r.pulse.value <= field_combo.intr_block_rf.error0_intr_count_incr_r.pulse.next; + end + end + // Field: aes_clp_reg.intr_block_rf.error1_intr_count_incr_r.pulse + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error1_intr_count_incr_r.pulse.value; + load_next_c = '0; + if(field_storage.intr_block_rf.error_intr_trig_r.error1_trig.value) begin // HW Write - we + next_c = field_storage.intr_block_rf.error_intr_trig_r.error1_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.error_internal_intr_r.error1_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end + if(field_storage.intr_block_rf.error1_intr_count_incr_r.pulse.value) begin // decrement + field_combo.intr_block_rf.error1_intr_count_incr_r.pulse.underflow = (next_c < (1'h1)); + next_c = next_c - 1'h1; + load_next_c = '1; + end else begin + field_combo.intr_block_rf.error1_intr_count_incr_r.pulse.underflow = '0; + end + field_combo.intr_block_rf.error1_intr_count_incr_r.pulse.decrthreshold = (field_storage.intr_block_rf.error1_intr_count_incr_r.pulse.value <= 1'd0); + field_combo.intr_block_rf.error1_intr_count_incr_r.pulse.next = next_c; + field_combo.intr_block_rf.error1_intr_count_incr_r.pulse.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.error1_intr_count_incr_r.pulse.value <= 1'h0; + end else if(field_combo.intr_block_rf.error1_intr_count_incr_r.pulse.load_next) begin + field_storage.intr_block_rf.error1_intr_count_incr_r.pulse.value <= field_combo.intr_block_rf.error1_intr_count_incr_r.pulse.next; + end + end + // Field: aes_clp_reg.intr_block_rf.error2_intr_count_incr_r.pulse + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error2_intr_count_incr_r.pulse.value; + load_next_c = '0; + if(field_storage.intr_block_rf.error_intr_trig_r.error2_trig.value) begin // HW Write - we + next_c = field_storage.intr_block_rf.error_intr_trig_r.error2_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.error_internal_intr_r.error2_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end + if(field_storage.intr_block_rf.error2_intr_count_incr_r.pulse.value) begin // decrement + field_combo.intr_block_rf.error2_intr_count_incr_r.pulse.underflow = (next_c < (1'h1)); + next_c = next_c - 1'h1; + load_next_c = '1; + end else begin + field_combo.intr_block_rf.error2_intr_count_incr_r.pulse.underflow = '0; + end + field_combo.intr_block_rf.error2_intr_count_incr_r.pulse.decrthreshold = (field_storage.intr_block_rf.error2_intr_count_incr_r.pulse.value <= 1'd0); + field_combo.intr_block_rf.error2_intr_count_incr_r.pulse.next = next_c; + field_combo.intr_block_rf.error2_intr_count_incr_r.pulse.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.error2_intr_count_incr_r.pulse.value <= 1'h0; + end else if(field_combo.intr_block_rf.error2_intr_count_incr_r.pulse.load_next) begin + field_storage.intr_block_rf.error2_intr_count_incr_r.pulse.value <= field_combo.intr_block_rf.error2_intr_count_incr_r.pulse.next; + end + end + // Field: aes_clp_reg.intr_block_rf.error3_intr_count_incr_r.pulse + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error3_intr_count_incr_r.pulse.value; + load_next_c = '0; + if(field_storage.intr_block_rf.error_intr_trig_r.error3_trig.value) begin // HW Write - we + next_c = field_storage.intr_block_rf.error_intr_trig_r.error3_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.error_internal_intr_r.error3_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end + if(field_storage.intr_block_rf.error3_intr_count_incr_r.pulse.value) begin // decrement + field_combo.intr_block_rf.error3_intr_count_incr_r.pulse.underflow = (next_c < (1'h1)); + next_c = next_c - 1'h1; + load_next_c = '1; + end else begin + field_combo.intr_block_rf.error3_intr_count_incr_r.pulse.underflow = '0; + end + field_combo.intr_block_rf.error3_intr_count_incr_r.pulse.decrthreshold = (field_storage.intr_block_rf.error3_intr_count_incr_r.pulse.value <= 1'd0); + field_combo.intr_block_rf.error3_intr_count_incr_r.pulse.next = next_c; + field_combo.intr_block_rf.error3_intr_count_incr_r.pulse.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.error3_intr_count_incr_r.pulse.value <= 1'h0; + end else if(field_combo.intr_block_rf.error3_intr_count_incr_r.pulse.load_next) begin + field_storage.intr_block_rf.error3_intr_count_incr_r.pulse.value <= field_combo.intr_block_rf.error3_intr_count_incr_r.pulse.next; + end + end + // Field: aes_clp_reg.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.value; + load_next_c = '0; + if(field_storage.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.value) begin // HW Write - we + next_c = field_storage.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end + if(field_storage.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.value) begin // decrement + field_combo.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.underflow = (next_c < (1'h1)); + next_c = next_c - 1'h1; + load_next_c = '1; + end else begin + field_combo.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.underflow = '0; + end + field_combo.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.decrthreshold = (field_storage.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.value <= 1'd0); + field_combo.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.next = next_c; + field_combo.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.value <= 1'h0; + end else if(field_combo.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.load_next) begin + field_storage.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.value <= field_combo.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.next; + end + end + + //-------------------------------------------------------------------------- + // Write response + //-------------------------------------------------------------------------- + assign cpuif_wr_ack = decoded_req & decoded_req_is_wr; + // Writes are always granted with no error response + assign cpuif_wr_err = '0; + + //-------------------------------------------------------------------------- + // Readback + //-------------------------------------------------------------------------- + + logic readback_err; + logic readback_done; + logic [31:0] readback_data; + + // Assign readback values to a flattened array + logic [28-1:0][31:0] readback_array; + for(genvar i0=0; i0<2; i0++) begin + assign readback_array[i0*1 + 0][31:0] = (decoded_reg_strb.AES_NAME[i0] && !decoded_req_is_wr) ? hwif_in.AES_NAME[i0].NAME.next : '0; + end + for(genvar i0=0; i0<2; i0++) begin + assign readback_array[i0*1 + 2][31:0] = (decoded_reg_strb.AES_VERSION[i0] && !decoded_req_is_wr) ? hwif_in.AES_VERSION[i0].VERSION.next : '0; + end + assign readback_array[4][0:0] = (decoded_reg_strb.CTRL0 && !decoded_req_is_wr) ? field_storage.CTRL0.ENDIAN_SWAP.value : '0; + assign readback_array[4][31:1] = '0; + assign readback_array[5][0:0] = (decoded_reg_strb.AES_KV_RD_KEY_CTRL && !decoded_req_is_wr) ? field_storage.AES_KV_RD_KEY_CTRL.read_en.value : '0; + assign readback_array[5][5:1] = (decoded_reg_strb.AES_KV_RD_KEY_CTRL && !decoded_req_is_wr) ? field_storage.AES_KV_RD_KEY_CTRL.read_entry.value : '0; + assign readback_array[5][6:6] = (decoded_reg_strb.AES_KV_RD_KEY_CTRL && !decoded_req_is_wr) ? field_storage.AES_KV_RD_KEY_CTRL.pcr_hash_extend.value : '0; + assign readback_array[5][31:7] = (decoded_reg_strb.AES_KV_RD_KEY_CTRL && !decoded_req_is_wr) ? field_storage.AES_KV_RD_KEY_CTRL.rsvd.value : '0; + assign readback_array[6][0:0] = (decoded_reg_strb.AES_KV_RD_KEY_STATUS && !decoded_req_is_wr) ? hwif_in.AES_KV_RD_KEY_STATUS.READY.next : '0; + assign readback_array[6][1:1] = (decoded_reg_strb.AES_KV_RD_KEY_STATUS && !decoded_req_is_wr) ? field_storage.AES_KV_RD_KEY_STATUS.VALID.value : '0; + assign readback_array[6][9:2] = (decoded_reg_strb.AES_KV_RD_KEY_STATUS && !decoded_req_is_wr) ? hwif_in.AES_KV_RD_KEY_STATUS.ERROR.next : '0; + assign readback_array[6][31:10] = '0; + assign readback_array[7][0:0] = (decoded_reg_strb.AES_KV_WR_CTRL && !decoded_req_is_wr) ? field_storage.AES_KV_WR_CTRL.write_en.value : '0; + assign readback_array[7][5:1] = (decoded_reg_strb.AES_KV_WR_CTRL && !decoded_req_is_wr) ? field_storage.AES_KV_WR_CTRL.write_entry.value : '0; + assign readback_array[7][6:6] = (decoded_reg_strb.AES_KV_WR_CTRL && !decoded_req_is_wr) ? field_storage.AES_KV_WR_CTRL.hmac_key_dest_valid.value : '0; + assign readback_array[7][7:7] = (decoded_reg_strb.AES_KV_WR_CTRL && !decoded_req_is_wr) ? field_storage.AES_KV_WR_CTRL.hmac_block_dest_valid.value : '0; + assign readback_array[7][8:8] = (decoded_reg_strb.AES_KV_WR_CTRL && !decoded_req_is_wr) ? field_storage.AES_KV_WR_CTRL.mldsa_seed_dest_valid.value : '0; + assign readback_array[7][9:9] = (decoded_reg_strb.AES_KV_WR_CTRL && !decoded_req_is_wr) ? field_storage.AES_KV_WR_CTRL.ecc_pkey_dest_valid.value : '0; + assign readback_array[7][10:10] = (decoded_reg_strb.AES_KV_WR_CTRL && !decoded_req_is_wr) ? field_storage.AES_KV_WR_CTRL.ecc_seed_dest_valid.value : '0; + assign readback_array[7][11:11] = (decoded_reg_strb.AES_KV_WR_CTRL && !decoded_req_is_wr) ? field_storage.AES_KV_WR_CTRL.aes_key_dest_valid.value : '0; + assign readback_array[7][12:12] = (decoded_reg_strb.AES_KV_WR_CTRL && !decoded_req_is_wr) ? field_storage.AES_KV_WR_CTRL.mlkem_seed_dest_valid.value : '0; + assign readback_array[7][13:13] = (decoded_reg_strb.AES_KV_WR_CTRL && !decoded_req_is_wr) ? field_storage.AES_KV_WR_CTRL.mlkem_msg_dest_valid.value : '0; + assign readback_array[7][14:14] = (decoded_reg_strb.AES_KV_WR_CTRL && !decoded_req_is_wr) ? field_storage.AES_KV_WR_CTRL.dma_data_dest_valid.value : '0; + assign readback_array[7][31:15] = (decoded_reg_strb.AES_KV_WR_CTRL && !decoded_req_is_wr) ? field_storage.AES_KV_WR_CTRL.rsvd.value : '0; + assign readback_array[8][0:0] = (decoded_reg_strb.AES_KV_WR_STATUS && !decoded_req_is_wr) ? hwif_in.AES_KV_WR_STATUS.READY.next : '0; + assign readback_array[8][1:1] = (decoded_reg_strb.AES_KV_WR_STATUS && !decoded_req_is_wr) ? field_storage.AES_KV_WR_STATUS.VALID.value : '0; + assign readback_array[8][9:2] = (decoded_reg_strb.AES_KV_WR_STATUS && !decoded_req_is_wr) ? hwif_in.AES_KV_WR_STATUS.ERROR.next : '0; + assign readback_array[8][31:10] = '0; + assign readback_array[9][0:0] = (decoded_reg_strb.intr_block_rf.global_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.global_intr_en_r.error_en.value : '0; + assign readback_array[9][1:1] = (decoded_reg_strb.intr_block_rf.global_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.global_intr_en_r.notif_en.value : '0; + assign readback_array[9][31:2] = '0; + assign readback_array[10][0:0] = (decoded_reg_strb.intr_block_rf.error_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_en_r.error0_en.value : '0; + assign readback_array[10][1:1] = (decoded_reg_strb.intr_block_rf.error_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_en_r.error1_en.value : '0; + assign readback_array[10][2:2] = (decoded_reg_strb.intr_block_rf.error_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_en_r.error2_en.value : '0; + assign readback_array[10][3:3] = (decoded_reg_strb.intr_block_rf.error_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_en_r.error3_en.value : '0; + assign readback_array[10][31:4] = '0; + assign readback_array[11][0:0] = (decoded_reg_strb.intr_block_rf.notif_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_intr_en_r.notif_cmd_done_en.value : '0; + assign readback_array[11][31:1] = '0; + assign readback_array[12][0:0] = (decoded_reg_strb.intr_block_rf.error_global_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_global_intr_r.agg_sts.value : '0; + assign readback_array[12][31:1] = '0; + assign readback_array[13][0:0] = (decoded_reg_strb.intr_block_rf.notif_global_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_global_intr_r.agg_sts.value : '0; + assign readback_array[13][31:1] = '0; + assign readback_array[14][0:0] = (decoded_reg_strb.intr_block_rf.error_internal_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_internal_intr_r.error0_sts.value : '0; + assign readback_array[14][1:1] = (decoded_reg_strb.intr_block_rf.error_internal_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_internal_intr_r.error1_sts.value : '0; + assign readback_array[14][2:2] = (decoded_reg_strb.intr_block_rf.error_internal_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_internal_intr_r.error2_sts.value : '0; + assign readback_array[14][3:3] = (decoded_reg_strb.intr_block_rf.error_internal_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_internal_intr_r.error3_sts.value : '0; + assign readback_array[14][31:4] = '0; + assign readback_array[15][0:0] = (decoded_reg_strb.intr_block_rf.notif_internal_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.value : '0; + assign readback_array[15][31:1] = '0; + assign readback_array[16][0:0] = (decoded_reg_strb.intr_block_rf.error_intr_trig_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_trig_r.error0_trig.value : '0; + assign readback_array[16][1:1] = (decoded_reg_strb.intr_block_rf.error_intr_trig_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_trig_r.error1_trig.value : '0; + assign readback_array[16][2:2] = (decoded_reg_strb.intr_block_rf.error_intr_trig_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_trig_r.error2_trig.value : '0; + assign readback_array[16][3:3] = (decoded_reg_strb.intr_block_rf.error_intr_trig_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_trig_r.error3_trig.value : '0; + assign readback_array[16][31:4] = '0; + assign readback_array[17][0:0] = (decoded_reg_strb.intr_block_rf.notif_intr_trig_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.value : '0; + assign readback_array[17][31:1] = '0; + assign readback_array[18][31:0] = (decoded_reg_strb.intr_block_rf.error0_intr_count_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error0_intr_count_r.cnt.value : '0; + assign readback_array[19][31:0] = (decoded_reg_strb.intr_block_rf.error1_intr_count_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error1_intr_count_r.cnt.value : '0; + assign readback_array[20][31:0] = (decoded_reg_strb.intr_block_rf.error2_intr_count_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error2_intr_count_r.cnt.value : '0; + assign readback_array[21][31:0] = (decoded_reg_strb.intr_block_rf.error3_intr_count_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error3_intr_count_r.cnt.value : '0; + assign readback_array[22][31:0] = (decoded_reg_strb.intr_block_rf.notif_cmd_done_intr_count_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_cmd_done_intr_count_r.cnt.value : '0; + assign readback_array[23][0:0] = (decoded_reg_strb.intr_block_rf.error0_intr_count_incr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error0_intr_count_incr_r.pulse.value : '0; + assign readback_array[23][31:1] = '0; + assign readback_array[24][0:0] = (decoded_reg_strb.intr_block_rf.error1_intr_count_incr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error1_intr_count_incr_r.pulse.value : '0; + assign readback_array[24][31:1] = '0; + assign readback_array[25][0:0] = (decoded_reg_strb.intr_block_rf.error2_intr_count_incr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error2_intr_count_incr_r.pulse.value : '0; + assign readback_array[25][31:1] = '0; + assign readback_array[26][0:0] = (decoded_reg_strb.intr_block_rf.error3_intr_count_incr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error3_intr_count_incr_r.pulse.value : '0; + assign readback_array[26][31:1] = '0; + assign readback_array[27][0:0] = (decoded_reg_strb.intr_block_rf.notif_cmd_done_intr_count_incr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.value : '0; + assign readback_array[27][31:1] = '0; + + // Reduce the array + always_comb begin + automatic logic [31:0] readback_data_var; + readback_done = decoded_req & ~decoded_req_is_wr; + readback_err = '0; + readback_data_var = '0; + for(int i=0; i<28; i++) readback_data_var |= readback_array[i]; + readback_data = readback_data_var; + end + + assign cpuif_rd_ack = readback_done; + assign cpuif_rd_data = readback_data; + assign cpuif_rd_err = readback_err; + +`CALIPTRA_ASSERT_KNOWN(ERR_HWIF_IN, hwif_in, clk, !hwif_in.error_reset_b) + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/aes_clp_reg_pkg.sv b/designs/Caliptra/src/caliptra-rtl/aes_clp_reg_pkg.sv new file mode 100644 index 0000000..e061f6f --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/aes_clp_reg_pkg.sv @@ -0,0 +1,322 @@ +// Generated by PeakRDL-regblock - A free and open-source SystemVerilog generator +// https://github.com/SystemRDL/PeakRDL-regblock + +package aes_clp_reg_pkg; + + localparam AES_CLP_REG_DATA_WIDTH = 32; + localparam AES_CLP_REG_MIN_ADDR_WIDTH = 11; + + typedef struct packed{ + logic [31:0] next; + } aes_clp_reg__AES_NAME__NAME__in_t; + + typedef struct packed{ + aes_clp_reg__AES_NAME__NAME__in_t NAME; + } aes_clp_reg__AES_NAME__in_t; + + typedef struct packed{ + logic [31:0] next; + } aes_clp_reg__AES_VERSION__VERSION__in_t; + + typedef struct packed{ + aes_clp_reg__AES_VERSION__VERSION__in_t VERSION; + } aes_clp_reg__AES_VERSION__in_t; + + typedef struct packed{ + logic swwe; + logic hwclr; + } kv_read_ctrl_reg__read_en__in_t; + + typedef struct packed{ + logic swwe; + } kv_read_ctrl_reg__read_entry__in_t; + + typedef struct packed{ + logic swwe; + } kv_read_ctrl_reg__pcr_hash_extend__in_t; + + typedef struct packed{ + logic swwe; + } kv_read_ctrl_reg__rsvd__in_t; + + typedef struct packed{ + kv_read_ctrl_reg__read_en__in_t read_en; + kv_read_ctrl_reg__read_entry__in_t read_entry; + kv_read_ctrl_reg__pcr_hash_extend__in_t pcr_hash_extend; + kv_read_ctrl_reg__rsvd__in_t rsvd; + } kv_read_ctrl_reg__in_t; + + typedef struct packed{ + logic next; + } kv_status_reg__READY__in_t; + + typedef struct packed{ + logic hwclr; + logic hwset; + } kv_status_reg__VALID__in_t; + + typedef struct packed{ + logic [7:0] next; + } kv_status_reg__ERROR__in_t; + + typedef struct packed{ + kv_status_reg__READY__in_t READY; + kv_status_reg__VALID__in_t VALID; + kv_status_reg__ERROR__in_t ERROR; + } kv_status_reg__in_t; + + typedef struct packed{ + logic swwe; + logic hwclr; + } kv_write_ctrl_reg__write_en__in_t; + + typedef struct packed{ + logic swwe; + } kv_write_ctrl_reg__write_entry__in_t; + + typedef struct packed{ + logic swwe; + } kv_write_ctrl_reg__hmac_key_dest_valid__in_t; + + typedef struct packed{ + logic swwe; + } kv_write_ctrl_reg__hmac_block_dest_valid__in_t; + + typedef struct packed{ + logic swwe; + } kv_write_ctrl_reg__mldsa_seed_dest_valid__in_t; + + typedef struct packed{ + logic swwe; + } kv_write_ctrl_reg__ecc_pkey_dest_valid__in_t; + + typedef struct packed{ + logic swwe; + } kv_write_ctrl_reg__ecc_seed_dest_valid__in_t; + + typedef struct packed{ + logic swwe; + } kv_write_ctrl_reg__aes_key_dest_valid__in_t; + + typedef struct packed{ + logic swwe; + } kv_write_ctrl_reg__mlkem_seed_dest_valid__in_t; + + typedef struct packed{ + logic swwe; + } kv_write_ctrl_reg__mlkem_msg_dest_valid__in_t; + + typedef struct packed{ + logic swwe; + } kv_write_ctrl_reg__dma_data_dest_valid__in_t; + + typedef struct packed{ + logic swwe; + } kv_write_ctrl_reg__rsvd__in_t; + + typedef struct packed{ + kv_write_ctrl_reg__write_en__in_t write_en; + kv_write_ctrl_reg__write_entry__in_t write_entry; + kv_write_ctrl_reg__hmac_key_dest_valid__in_t hmac_key_dest_valid; + kv_write_ctrl_reg__hmac_block_dest_valid__in_t hmac_block_dest_valid; + kv_write_ctrl_reg__mldsa_seed_dest_valid__in_t mldsa_seed_dest_valid; + kv_write_ctrl_reg__ecc_pkey_dest_valid__in_t ecc_pkey_dest_valid; + kv_write_ctrl_reg__ecc_seed_dest_valid__in_t ecc_seed_dest_valid; + kv_write_ctrl_reg__aes_key_dest_valid__in_t aes_key_dest_valid; + kv_write_ctrl_reg__mlkem_seed_dest_valid__in_t mlkem_seed_dest_valid; + kv_write_ctrl_reg__mlkem_msg_dest_valid__in_t mlkem_msg_dest_valid; + kv_write_ctrl_reg__dma_data_dest_valid__in_t dma_data_dest_valid; + kv_write_ctrl_reg__rsvd__in_t rsvd; + } kv_write_ctrl_reg__in_t; + + typedef struct packed{ + logic hwset; + } aes_clp_reg__error_intr_t_error0_sts_28545624_error1_sts_40e0d3e1_error2_sts_b1cf2205_error3_sts_74a35378__error0_sts_enable_528ccada_next_b1018582_resetsignal_939e99d4__in_t; + + typedef struct packed{ + logic hwset; + } aes_clp_reg__error_intr_t_error0_sts_28545624_error1_sts_40e0d3e1_error2_sts_b1cf2205_error3_sts_74a35378__error1_sts_enable_938cafef_next_f460eb81_resetsignal_939e99d4__in_t; + + typedef struct packed{ + logic hwset; + } aes_clp_reg__error_intr_t_error0_sts_28545624_error1_sts_40e0d3e1_error2_sts_b1cf2205_error3_sts_74a35378__error2_sts_enable_0dacf7a6_next_4b5b9e74_resetsignal_939e99d4__in_t; + + typedef struct packed{ + logic hwset; + } aes_clp_reg__error_intr_t_error0_sts_28545624_error1_sts_40e0d3e1_error2_sts_b1cf2205_error3_sts_74a35378__error3_sts_enable_fc3af94b_next_c3125d40_resetsignal_939e99d4__in_t; + + typedef struct packed{ + aes_clp_reg__error_intr_t_error0_sts_28545624_error1_sts_40e0d3e1_error2_sts_b1cf2205_error3_sts_74a35378__error0_sts_enable_528ccada_next_b1018582_resetsignal_939e99d4__in_t error0_sts; + aes_clp_reg__error_intr_t_error0_sts_28545624_error1_sts_40e0d3e1_error2_sts_b1cf2205_error3_sts_74a35378__error1_sts_enable_938cafef_next_f460eb81_resetsignal_939e99d4__in_t error1_sts; + aes_clp_reg__error_intr_t_error0_sts_28545624_error1_sts_40e0d3e1_error2_sts_b1cf2205_error3_sts_74a35378__error2_sts_enable_0dacf7a6_next_4b5b9e74_resetsignal_939e99d4__in_t error2_sts; + aes_clp_reg__error_intr_t_error0_sts_28545624_error1_sts_40e0d3e1_error2_sts_b1cf2205_error3_sts_74a35378__error3_sts_enable_fc3af94b_next_c3125d40_resetsignal_939e99d4__in_t error3_sts; + } aes_clp_reg__error_intr_t_error0_sts_28545624_error1_sts_40e0d3e1_error2_sts_b1cf2205_error3_sts_74a35378__in_t; + + typedef struct packed{ + logic hwset; + } aes_clp_reg__notif_intr_t_notif_cmd_done_sts_1c68637e__notif_cmd_done_sts_enable_dabe0b8b_next_540fa3b7__in_t; + + typedef struct packed{ + aes_clp_reg__notif_intr_t_notif_cmd_done_sts_1c68637e__notif_cmd_done_sts_enable_dabe0b8b_next_540fa3b7__in_t notif_cmd_done_sts; + } aes_clp_reg__notif_intr_t_notif_cmd_done_sts_1c68637e__in_t; + + typedef struct packed{ + aes_clp_reg__error_intr_t_error0_sts_28545624_error1_sts_40e0d3e1_error2_sts_b1cf2205_error3_sts_74a35378__in_t error_internal_intr_r; + aes_clp_reg__notif_intr_t_notif_cmd_done_sts_1c68637e__in_t notif_internal_intr_r; + } aes_clp_reg__intr_block_t__in_t; + + typedef struct packed{ + logic reset_b; + logic error_reset_b; + aes_clp_reg__AES_NAME__in_t [2-1:0]AES_NAME; + aes_clp_reg__AES_VERSION__in_t [2-1:0]AES_VERSION; + kv_read_ctrl_reg__in_t AES_KV_RD_KEY_CTRL; + kv_status_reg__in_t AES_KV_RD_KEY_STATUS; + kv_write_ctrl_reg__in_t AES_KV_WR_CTRL; + kv_status_reg__in_t AES_KV_WR_STATUS; + aes_clp_reg__intr_block_t__in_t intr_block_rf; + } aes_clp_reg__in_t; + + typedef struct packed{ + logic [31:0] value; + logic swmod; + } aes_clp_reg__ENTROPY_IF_SEED__ENTROPY_IF_SEED__out_t; + + typedef struct packed{ + aes_clp_reg__ENTROPY_IF_SEED__ENTROPY_IF_SEED__out_t ENTROPY_IF_SEED; + } aes_clp_reg__ENTROPY_IF_SEED__out_t; + + typedef struct packed{ + logic value; + } aes_clp_reg__CTRL0__ENDIAN_SWAP__out_t; + + typedef struct packed{ + aes_clp_reg__CTRL0__ENDIAN_SWAP__out_t ENDIAN_SWAP; + } aes_clp_reg__CTRL0__out_t; + + typedef struct packed{ + logic value; + } kv_read_ctrl_reg__read_en__out_t; + + typedef struct packed{ + logic [4:0] value; + } kv_read_ctrl_reg__read_entry__out_t; + + typedef struct packed{ + logic value; + } kv_read_ctrl_reg__pcr_hash_extend__out_t; + + typedef struct packed{ + logic [24:0] value; + } kv_read_ctrl_reg__rsvd__out_t; + + typedef struct packed{ + kv_read_ctrl_reg__read_en__out_t read_en; + kv_read_ctrl_reg__read_entry__out_t read_entry; + kv_read_ctrl_reg__pcr_hash_extend__out_t pcr_hash_extend; + kv_read_ctrl_reg__rsvd__out_t rsvd; + } kv_read_ctrl_reg__out_t; + + typedef struct packed{ + logic value; + } kv_write_ctrl_reg__write_en__out_t; + + typedef struct packed{ + logic [4:0] value; + } kv_write_ctrl_reg__write_entry__out_t; + + typedef struct packed{ + logic value; + } kv_write_ctrl_reg__hmac_key_dest_valid__out_t; + + typedef struct packed{ + logic value; + } kv_write_ctrl_reg__hmac_block_dest_valid__out_t; + + typedef struct packed{ + logic value; + } kv_write_ctrl_reg__mldsa_seed_dest_valid__out_t; + + typedef struct packed{ + logic value; + } kv_write_ctrl_reg__ecc_pkey_dest_valid__out_t; + + typedef struct packed{ + logic value; + } kv_write_ctrl_reg__ecc_seed_dest_valid__out_t; + + typedef struct packed{ + logic value; + } kv_write_ctrl_reg__aes_key_dest_valid__out_t; + + typedef struct packed{ + logic value; + } kv_write_ctrl_reg__mlkem_seed_dest_valid__out_t; + + typedef struct packed{ + logic value; + } kv_write_ctrl_reg__mlkem_msg_dest_valid__out_t; + + typedef struct packed{ + logic value; + } kv_write_ctrl_reg__dma_data_dest_valid__out_t; + + typedef struct packed{ + logic [16:0] value; + } kv_write_ctrl_reg__rsvd__out_t; + + typedef struct packed{ + kv_write_ctrl_reg__write_en__out_t write_en; + kv_write_ctrl_reg__write_entry__out_t write_entry; + kv_write_ctrl_reg__hmac_key_dest_valid__out_t hmac_key_dest_valid; + kv_write_ctrl_reg__hmac_block_dest_valid__out_t hmac_block_dest_valid; + kv_write_ctrl_reg__mldsa_seed_dest_valid__out_t mldsa_seed_dest_valid; + kv_write_ctrl_reg__ecc_pkey_dest_valid__out_t ecc_pkey_dest_valid; + kv_write_ctrl_reg__ecc_seed_dest_valid__out_t ecc_seed_dest_valid; + kv_write_ctrl_reg__aes_key_dest_valid__out_t aes_key_dest_valid; + kv_write_ctrl_reg__mlkem_seed_dest_valid__out_t mlkem_seed_dest_valid; + kv_write_ctrl_reg__mlkem_msg_dest_valid__out_t mlkem_msg_dest_valid; + kv_write_ctrl_reg__dma_data_dest_valid__out_t dma_data_dest_valid; + kv_write_ctrl_reg__rsvd__out_t rsvd; + } kv_write_ctrl_reg__out_t; + + typedef struct packed{ + logic intr; + } aes_clp_reg__global_intr_t_agg_sts_dd3dcf0a__out_t; + + typedef struct packed{ + logic intr; + } aes_clp_reg__global_intr_t_agg_sts_e6399b4a__out_t; + + typedef struct packed{ + logic intr; + } aes_clp_reg__error_intr_t_error0_sts_28545624_error1_sts_40e0d3e1_error2_sts_b1cf2205_error3_sts_74a35378__out_t; + + typedef struct packed{ + logic intr; + } aes_clp_reg__notif_intr_t_notif_cmd_done_sts_1c68637e__out_t; + + typedef struct packed{ + aes_clp_reg__global_intr_t_agg_sts_dd3dcf0a__out_t error_global_intr_r; + aes_clp_reg__global_intr_t_agg_sts_e6399b4a__out_t notif_global_intr_r; + aes_clp_reg__error_intr_t_error0_sts_28545624_error1_sts_40e0d3e1_error2_sts_b1cf2205_error3_sts_74a35378__out_t error_internal_intr_r; + aes_clp_reg__notif_intr_t_notif_cmd_done_sts_1c68637e__out_t notif_internal_intr_r; + } aes_clp_reg__intr_block_t__out_t; + + typedef struct packed{ + aes_clp_reg__ENTROPY_IF_SEED__out_t [9-1:0]ENTROPY_IF_SEED; + aes_clp_reg__CTRL0__out_t CTRL0; + kv_read_ctrl_reg__out_t AES_KV_RD_KEY_CTRL; + kv_write_ctrl_reg__out_t AES_KV_WR_CTRL; + aes_clp_reg__intr_block_t__out_t intr_block_rf; + } aes_clp_reg__out_t; + + typedef enum logic [31:0] { + kv_status_reg__ERROR__kv_error_e__SUCCESS = 'h0, + kv_status_reg__ERROR__kv_error_e__KV_READ_FAIL = 'h1, + kv_status_reg__ERROR__kv_error_e__KV_WRITE_FAIL = 'h2 + } kv_status_reg__ERROR__kv_error_e_e; + + localparam AES_CLP_REG_ADDR_WIDTH = 32'd11; + +endpackage \ No newline at end of file diff --git a/designs/Caliptra/src/caliptra-rtl/aes_clp_wrapper.sv b/designs/Caliptra/src/caliptra-rtl/aes_clp_wrapper.sv new file mode 100644 index 0000000..ae00f72 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/aes_clp_wrapper.sv @@ -0,0 +1,633 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +// +//====================================================================== +// +// aes_clp_wrapper.sv +// -------- +// Wrapper for instantiation aes engine +// +// +// +//====================================================================== + +`include "caliptra_reg_field_defines.svh" +`include "kv_macros.svh" + +module aes_clp_wrapper + import aes_pkg::*; + import kv_defines_pkg::*; + import aes_clp_reg_pkg::*; + #( + parameter AHB_DATA_WIDTH = 32, + parameter AHB_ADDR_WIDTH = 32, + parameter CIF_DATA_WIDTH = 32, + localparam CIF_DATA_NUM_BYTES = CIF_DATA_WIDTH / 8 +) +( + // Clock and reset. + input wire clk, + input wire reset_n, + input wire cptra_pwrgood, + + input logic [AHB_ADDR_WIDTH-1:0] haddr_i, + input logic [AHB_DATA_WIDTH-1:0] hwdata_i, + input logic hsel_i, + input logic hwrite_i, + input logic hready_i, + input logic [1:0] htrans_i, + input logic [2:0] hsize_i, + + output logic hresp_o, + output logic hreadyout_o, + output logic [AHB_DATA_WIDTH-1:0] hrdata_o, + + // OCP LOCK + input logic ocp_lock_in_progress, + input logic [15:0] key_release_key_size, + + // status signals + output logic input_ready_o, + output logic output_valid_o, + output logic status_idle_o, + + // DMA CIF + input logic dma_req_dv, + input logic dma_req_write, + input logic [AHB_ADDR_WIDTH-1 : 0] dma_req_addr, + input logic [CIF_DATA_WIDTH-1 : 0] dma_req_wdata, + output logic dma_req_hold, + output logic dma_req_error, + output logic [CIF_DATA_WIDTH-1 : 0] dma_req_rdata, + + // kv interface + output kv_read_t kv_read, + input kv_rd_resp_t kv_rd_resp, + output kv_write_t kv_write, + input kv_wr_resp_t kv_wr_resp, + + output logic busy_o, + + // Interrupt + output logic error_intr, + output logic notif_intr, + input logic debugUnlock_or_scan_mode_switch +); + +localparam AES_KV_KEY_DW_WIDTH = $clog2(keymgr_pkg::KeyWidth/32); + +caliptra_tlul_pkg::tl_h2d_t adapter_to_aes_tl; +caliptra_tlul_pkg::tl_d2h_t aes_to_adapter_tl; + +logic ahb_dv; +logic ahb_hold; +logic ahb_write; +logic ahb_err; +logic [AHB_ADDR_WIDTH-1 : 0] ahb_addr; +logic [CIF_DATA_WIDTH-1 : 0] ahb_wdata; +logic [CIF_DATA_WIDTH-1 : 0] ahb_rdata; + +logic req_collision; +logic aes_cif_endian_swap; + +logic aes_cif_req_dv; +logic aes_cif_req_write; +logic [AHB_ADDR_WIDTH-1 : 0] aes_cif_req_addr; +logic [CIF_DATA_WIDTH-1 : 0] aes_cif_req_wdata; +logic [CIF_DATA_WIDTH-1 : 0] aes_cif_req_wdata_post_endian; +logic aes_cif_req_hold; +logic aes_cif_req_error; +logic [CIF_DATA_WIDTH-1 : 0] aes_cif_req_rdata; +logic [CIF_DATA_WIDTH-1 : 0] aes_cif_req_rdata_post_endian; + +logic clp_reg_dv; +logic clp_reg_write; +logic [31 : 0] clp_reg_rdata; +logic [31 : 0] clp_reg_wdata; +logic [caliptra_tlul_pkg::TL_AW-1 : 0] clp_reg_addr; + +aes_clp_reg_pkg::aes_clp_reg__in_t hwif_in; +aes_clp_reg_pkg::aes_clp_reg__out_t hwif_out; + +caliptra2aes_t caliptra2aes; +aes2caliptra_t aes2caliptra; + +caliptra_prim_mubi_pkg::mubi4_t aes_idle; + +kv_read_ctrl_reg_t kv_key_read_ctrl_reg; +kv_read_filter_metrics_t kv_key_read_metrics; +kv_error_code_e kv_key_error; +logic kv_key_ready, kv_key_done; +logic [KV_ENTRY_ADDR_W-1:0] kv_key_present_slot; + +logic kv_key_write_en; +logic [AES_KV_KEY_DW_WIDTH-1:0] kv_key_write_offset; +logic [3:0][7:0] kv_key_write_data; + +kv_write_ctrl_reg_t kv_write_ctrl_reg; +kv_write_filter_metrics_t kv_write_metrics; +kv_error_code_e kv_write_error; +logic kv_write_ready; +logic [$clog2(CLP_AES_KV_WR_DW/32):0] kv_wr_num_dwords; + +edn_pkg::edn_req_t edn_req; + +keymgr_pkg::hw_key_req_t keymgr_key; + +assign error_intr = '0; // Unused +assign notif_intr = '0; // Unused + +assign busy_o = caliptra_prim_mubi_pkg::mubi4_test_false_loose(aes_idle) || ~kv_key_ready || ~kv_write_ready; +assign status_idle_o = caliptra_prim_mubi_pkg::mubi4_test_true_loose(aes_idle); + + +//AHB interface +ahb_slv_sif #( + .AHB_ADDR_WIDTH(AHB_ADDR_WIDTH), + .AHB_DATA_WIDTH(AHB_DATA_WIDTH), + .CLIENT_DATA_WIDTH(CIF_DATA_WIDTH) +) ahb_slv_sif_inst +( + //AMBA AHB Lite INF + .hclk(clk), + .hreset_n(reset_n), + .haddr_i(haddr_i), + .hwdata_i(hwdata_i), + .hsel_i(hsel_i), + .hwrite_i(hwrite_i), + .hready_i(hready_i), + .htrans_i(htrans_i), + .hsize_i(hsize_i), + + .hresp_o(hresp_o), + .hreadyout_o(hreadyout_o), + .hrdata_o(hrdata_o), + + + //COMPONENT INF + .dv(ahb_dv), + .hld(ahb_hold), + .err(ahb_err), + .write(ahb_write), + .wdata(ahb_wdata), + .addr(ahb_addr), + + .rdata(ahb_rdata) +); + +// AHB CIF Mux +// No real muxing, just respond with error if we detect a request collision. +// It is FW responsiblity to ensure only AHB or DMA accesses AES at a time +assign req_collision = dma_req_dv & ahb_dv; + +assign aes_cif_endian_swap = aes_cif_req_dv && hwif_out.CTRL0.ENDIAN_SWAP.value && ( + aes_cif_req_addr == `AES_REG_DATA_IN_0 || + aes_cif_req_addr == `AES_REG_DATA_IN_1 || + aes_cif_req_addr == `AES_REG_DATA_IN_2 || + aes_cif_req_addr == `AES_REG_DATA_IN_3 || + aes_cif_req_addr == `AES_REG_DATA_OUT_0 || + aes_cif_req_addr == `AES_REG_DATA_OUT_1 || + aes_cif_req_addr == `AES_REG_DATA_OUT_2 || + aes_cif_req_addr == `AES_REG_DATA_OUT_3 + ); + +assign aes_cif_req_dv = dma_req_dv | ahb_dv; +assign aes_cif_req_write = dma_req_dv ? dma_req_write : ahb_write ; +assign aes_cif_req_addr = dma_req_dv ? dma_req_addr : ahb_addr ; +assign aes_cif_req_wdata = dma_req_dv ? dma_req_wdata : ahb_wdata ; + +always_comb begin + for (int b=0; b>2); + +always_comb begin + kv_write_metrics.ocp_lock_in_progress = ocp_lock_in_progress; + kv_write_metrics.kv_data0_present = aes2caliptra.kv_key_in_use; // TODO -- what if FW toggles sideload while op is in progress? + kv_write_metrics.kv_data0_entry = kv_key_present_slot; + kv_write_metrics.kv_data1_present = 1'b0; + kv_write_metrics.kv_data1_entry = KV_ENTRY_ADDR_W'(0); + kv_write_metrics.kv_write_src = KV_NUM_WRITE'(1 << KV_WRITE_IDX_AES); + kv_write_metrics.kv_write_entry = kv_write_ctrl_reg.write_entry; + kv_write_metrics.aes_decrypt_ecb_op = aes2caliptra.aes_operation_is_ecb_decrypt; +end + +always_comb caliptra2aes.block_reg_output = ocp_lock_in_progress && + (aes2caliptra.kv_key_in_use && kv_key_present_slot == OCP_LOCK_RT_OBF_KEY_KV_SLOT) && + aes2caliptra.aes_operation_is_ecb_decrypt; + +//Write to keyvault +kv_write_client #( + .DATA_WIDTH(CLP_AES_KV_WR_DW), + .KV_WRITE_SWAP_DWORDS(0) +) +aes_result_kv_write +( + .clk(clk), + .rst_b(reset_n), + .zeroize(debugUnlock_or_scan_mode_switch), + + //client control register + .write_ctrl_reg(kv_write_ctrl_reg), + .num_dwords (kv_wr_num_dwords ), + + //access filtering rule metrics + .write_metrics (kv_write_metrics), + + //interface with kv + .kv_write(kv_write ), + .kv_resp (kv_wr_resp), + + //interface with client + .dest_keyvault (caliptra2aes.kv_en ), + .dest_data_avail(aes2caliptra.kv_data_out_valid), + .dest_data (aes2caliptra.kv_data_out ), + + .error_code(kv_write_error ), + .kv_ready (kv_write_ready ), + .dest_done (caliptra2aes.kv_write_done) +); + +//load keyvault key into local reg +//swizzle keyvault value to match endianness of aes engine +genvar g_dword; +genvar g_byte; +generate + for (g_dword = 0; g_dword < keymgr_pkg::KeyWidth/32; g_dword++) begin + for (g_byte = 0; g_byte < 4; g_byte++) begin + always_ff @(posedge clk or negedge reset_n) begin + if (~reset_n) begin + kv_key_reg[g_dword][g_byte] <= '0; + end else if(debugUnlock_or_scan_mode_switch) begin + kv_key_reg[g_dword][g_byte] <= '0; + // zeroize the buffered KeyVault value when reading in a new key + // On the first beat, the least-sig dword is set, all other dwords set to 0 + end else if (kv_key_write_en && (g_dword > 0) && (kv_key_write_offset < AES_KV_KEY_DW_WIDTH'(g_dword))) begin + kv_key_reg[g_dword][g_byte] <= 0; + end else if (kv_key_write_en && (kv_key_write_offset == AES_KV_KEY_DW_WIDTH'(g_dword))) begin + kv_key_reg[g_dword][g_byte] <= kv_key_write_data[3-g_byte]; + end + end + end + end +endgenerate + +//Drive keymgr interface into AES +always_ff @(posedge clk or negedge reset_n) begin + if (~reset_n) begin + keymgr_key.valid <= '0; + keymgr_key.key <= '0; + end + else if (kv_key_read_ctrl_reg.read_en || (kv_key_error == KV_READ_FAIL) || debugUnlock_or_scan_mode_switch) begin //new request, invalidate old key + keymgr_key.valid <= '0; + keymgr_key.key[0] <= '0; + keymgr_key.key[1] <= '0; + end + else if (kv_key_done) begin //key is copied, drive valid to aes + keymgr_key.valid <= '1; + keymgr_key.key[0] <= kv_key_reg; + keymgr_key.key[1] <= '0; + end +end + +// Entropy interface +// We use a Trivium stream cipher primitive which is parameterized as follows: +// - It takes 288 bits of seed material at a time provided by firmware via the ENTROPY_IF_SEED +// registers to reseed the entire Trivium state in one shot. Firmware has to perform 9 write +// operations to the ENTROPY_IF_SEED registers. +// - It delivers 32 bits per clock cycle to AES via the EDN interface. AES will repeatedly request +// fresh entropy via this interface. The rate depends on the value of +// CTRL_SHADOWED.PRNG_RESEED_RATE. +// +// Note: Upon reset, the state of the Trivium primitive is initialized to a netlist constant. The +// primitive thus always generates the same output after reset. It is the responsibility of +// firmware to provide a new state seed after reset. +localparam int unsigned NumSeedChunks = + caliptra_prim_trivium_pkg::TriviumStateWidth / aes_clp_reg_pkg::AES_CLP_REG_DATA_WIDTH; +logic [caliptra_prim_trivium_pkg::TriviumStateWidth-1:0] trivium_seed; +logic [NumSeedChunks-1:0] trivium_seed_qe; +logic [NumSeedChunks-1:0] trivium_seed_chunk_vld_q, trivium_seed_chunk_vld_d; +logic trivium_seed_en; + +// Concatenate the register values to produce the full state seed. +assign trivium_seed = {hwif_out.ENTROPY_IF_SEED[8].ENTROPY_IF_SEED.value, + hwif_out.ENTROPY_IF_SEED[7].ENTROPY_IF_SEED.value, + hwif_out.ENTROPY_IF_SEED[6].ENTROPY_IF_SEED.value, + hwif_out.ENTROPY_IF_SEED[5].ENTROPY_IF_SEED.value, + hwif_out.ENTROPY_IF_SEED[4].ENTROPY_IF_SEED.value, + hwif_out.ENTROPY_IF_SEED[3].ENTROPY_IF_SEED.value, + hwif_out.ENTROPY_IF_SEED[2].ENTROPY_IF_SEED.value, + hwif_out.ENTROPY_IF_SEED[1].ENTROPY_IF_SEED.value, + hwif_out.ENTROPY_IF_SEED[0].ENTROPY_IF_SEED.value}; + +// Concatenate the register write enables. +assign trivium_seed_qe = {hwif_out.ENTROPY_IF_SEED[8].ENTROPY_IF_SEED.swmod, + hwif_out.ENTROPY_IF_SEED[7].ENTROPY_IF_SEED.swmod, + hwif_out.ENTROPY_IF_SEED[6].ENTROPY_IF_SEED.swmod, + hwif_out.ENTROPY_IF_SEED[5].ENTROPY_IF_SEED.swmod, + hwif_out.ENTROPY_IF_SEED[4].ENTROPY_IF_SEED.swmod, + hwif_out.ENTROPY_IF_SEED[3].ENTROPY_IF_SEED.swmod, + hwif_out.ENTROPY_IF_SEED[2].ENTROPY_IF_SEED.swmod, + hwif_out.ENTROPY_IF_SEED[1].ENTROPY_IF_SEED.swmod, + hwif_out.ENTROPY_IF_SEED[0].ENTROPY_IF_SEED.swmod}; + +// Track write operations: +// - Perform the reseed once every register has been written at least once. +// - Clear the tracking upon doing the reseed operation. +assign trivium_seed_chunk_vld_d = trivium_seed_en ? '0 : trivium_seed_chunk_vld_q | trivium_seed_qe; +assign trivium_seed_en = &trivium_seed_chunk_vld_q; + +always_ff @(posedge clk or negedge reset_n) begin + if (~reset_n) begin + trivium_seed_chunk_vld_q <= '0; + end else begin + trivium_seed_chunk_vld_q <= trivium_seed_chunk_vld_d; + end +end + +caliptra_prim_trivium #( + .OutputWidth(edn_pkg::ENDPOINT_BUS_WIDTH), + .SeedType (caliptra_prim_trivium_pkg::SeedTypeStateFull) +) +u_caliptra_prim_trivium +( + .clk_i(clk), + .rst_ni(reset_n), + + .en_i (edn_req.edn_req), + .allow_lockup_i ('0), // Not used. + .seed_en_i (trivium_seed_en), + .seed_done_o (), // Not used. + .seed_req_o (), // Not used. + .seed_ack_i (trivium_seed_en), + .seed_key_i ('0), // Not used. + .seed_iv_i ('0), // Not used. + .seed_state_full_i (trivium_seed), + .seed_state_partial_i('0), // Not used. + + .key_o(edn_bus), + .err_o() +); + +`CALIPTRA_ASSERT_STABLE(ERR_AES_KEY_RD_CTRL_NOT_STABLE, kv_key_read_ctrl_reg, clk, (!reset_n || status_idle_o) ) +`CALIPTRA_ASSERT_STABLE(ERR_AES_WR_CTRL_NOT_STABLE, kv_write_ctrl_reg, clk, (!reset_n || status_idle_o) ) +`CALIPTRA_ASSERT_STABLE(ERR_AES_KEY_NOT_STABLE, kv_key_reg, clk, (!reset_n || status_idle_o) ) + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/aes_control.sv b/designs/Caliptra/src/caliptra-rtl/aes_control.sv new file mode 100644 index 0000000..c94c3c2 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/aes_control.sv @@ -0,0 +1,646 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// AES main control +// +// This module controls the interplay of input/output registers and the AES cipher core. + +`include "caliptra_prim_assert.sv" + +module aes_control + import aes_pkg::*; + import aes_reg_pkg::*; +#( + parameter bit AESGCMEnable = 0, + parameter bit SecMasking = 0, + parameter int unsigned SecStartTriggerDelay = 0 +) ( + input logic clk_i, + input logic rst_ni, + + // Main control signals + input logic ctrl_qe_i, + output logic ctrl_we_o, + input logic ctrl_phase_i, + input logic ctrl_err_storage_i, + input aes_op_e op_i, + input aes_mode_e mode_i, + input ciph_op_e cipher_op_i, + input logic sideload_i, + input prs_rate_e prng_reseed_rate_i, + input logic manual_operation_i, + input logic key_touch_forces_reseed_i, + input logic ctrl_gcm_qe_i, + output logic ctrl_gcm_we_o, + input logic ctrl_gcm_phase_i, + output logic gcm_init_done_o, + input gcm_phase_e gcm_phase_i, + input logic start_i, + input logic key_iv_data_in_clear_i, + input logic data_out_clear_i, + input logic prng_reseed_i, + input logic mux_sel_err_i, + input logic sp_enc_err_i, + input lc_ctrl_pkg::lc_tx_t lc_escalate_en_i, + input logic alert_fatal_i, + output logic alert_o, + + // I/O register read/write enables + input logic key_sideload_valid_i, + input logic [NumRegsKey-1:0] key_init_qe_i [NumSharesKey], + input logic [NumRegsIv-1:0] iv_qe_i, + input logic [NumRegsData-1:0] data_in_qe_i, + input logic [NumRegsData-1:0] data_out_re_i, + output logic data_in_we_o, + output data_out_sel_e data_out_sel_o, + output sp2v_e data_out_we_o, + + // Previous input data register + output dip_sel_e data_in_prev_sel_o, + output sp2v_e data_in_prev_we_o, + + // Cipher I/O muxes + output si_sel_e state_in_sel_o, + output add_si_sel_e add_state_in_sel_o, + output add_so_sel_e add_state_out_sel_o, + + // Counter + output sp2v_e ctr_inc32_o, + output sp2v_e ctr_incr_o, + input sp2v_e ctr_ready_i, + input sp2v_e [NumSlicesCtr-1:0] ctr_we_i, + + // Cipher core control and sync + output sp2v_e cipher_in_valid_o, + input sp2v_e cipher_in_ready_i, + input sp2v_e cipher_out_valid_i, + output sp2v_e cipher_out_ready_o, + output sp2v_e cipher_crypt_o, + input sp2v_e cipher_crypt_i, + output sp2v_e cipher_dec_key_gen_o, + input sp2v_e cipher_dec_key_gen_i, + output logic cipher_prng_reseed_o, + input logic cipher_prng_reseed_i, + output logic cipher_key_clear_o, + input logic cipher_key_clear_i, + output logic cipher_data_out_clear_o, + input logic cipher_data_out_clear_i, + + // GHASH control and sync + output sp2v_e ghash_in_valid_o, + input sp2v_e ghash_in_ready_i, + input sp2v_e ghash_out_valid_i, + output sp2v_e ghash_out_ready_o, + output sp2v_e ghash_load_hash_subkey_o, + + // Initial key registers + output key_init_sel_e key_init_sel_o, + output sp2v_e [NumRegsKey-1:0] key_init_we_o [NumSharesKey], + + // IV registers + output iv_sel_e iv_sel_o, + output sp2v_e [NumSlicesCtr-1:0] iv_we_o, + + // Pseudo-random number generator interface + output logic prng_update_o, + output logic prng_reseed_req_o, + input logic prng_reseed_ack_i, + + // Trigger register + output logic start_o, + output logic start_we_o, + output logic key_iv_data_in_clear_o, + output logic key_iv_data_in_clear_we_o, + output logic data_out_clear_o, + output logic data_out_clear_we_o, + output logic prng_reseed_o, + output logic prng_reseed_we_o, + + // Status register + output logic idle_o, + output logic idle_we_o, + output logic stall_o, + output logic stall_we_o, + input logic output_lost_i, + output logic output_lost_o, + output logic output_lost_we_o, + output logic output_valid_o, + output logic output_valid_we_o, + output logic input_ready_o, + output logic input_ready_we_o +); + + // Optional delay of manual start trigger + logic start_trigger; + + // Create a lint error to reduce the risk of accidentally enabling this feature. + `CALIPTRA_ASSERT_STATIC_LINT_ERROR(AesSecStartTriggerDelayNonDefault, SecStartTriggerDelay == 0) + + if (SecStartTriggerDelay > 0) begin : gen_start_delay + // Delay the manual start trigger input for SCA measurements. + localparam int unsigned WidthCounter = $clog2(SecStartTriggerDelay+1); + logic [WidthCounter-1:0] count_d, count_q; + + // Clear counter when input goes low. Keep value if the specified delay is reached. + assign count_d = !start_i ? '0 : + start_trigger ? count_q : count_q + 1'b1; + assign start_trigger = (count_q == SecStartTriggerDelay[WidthCounter-1:0]) ? 1'b1 : 1'b0; + + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + count_q <= '0; + end else begin + count_q <= count_d; + end + end + + end else begin : gen_no_start_delay + // Directly forward the manual start trigger input. + assign start_trigger = start_i; + end + + // Signals + sp2v_e ctr_ready; + sp2v_e [NumSlicesCtr-1:0] ctr_we; + sp2v_e cipher_in_ready; + sp2v_e cipher_out_valid; + sp2v_e cipher_crypt; + sp2v_e cipher_dec_key_gen; + sp2v_e ghash_in_ready; + sp2v_e ghash_out_valid; + logic mux_sel_err; + logic mr_err; + logic sp_enc_err; + + // Sparsified FSM signals. These are needed for connecting the individual bits of the Sp2V + // signals to the single-rail FSMs. + logic [Sp2VWidth-1:0] sp_data_out_we; + logic [Sp2VWidth-1:0] sp_data_in_prev_we; + logic [Sp2VWidth-1:0] sp_ctr_inc32; + logic [Sp2VWidth-1:0] sp_ctr_incr; + logic [Sp2VWidth-1:0] sp_ctr_ready; + logic [Sp2VWidth-1:0] sp_cipher_in_valid; + logic [Sp2VWidth-1:0] sp_cipher_in_ready; + logic [Sp2VWidth-1:0] sp_cipher_out_valid; + logic [Sp2VWidth-1:0] sp_cipher_out_ready; + logic [Sp2VWidth-1:0] sp_in_cipher_crypt; + logic [Sp2VWidth-1:0] sp_out_cipher_crypt; + logic [Sp2VWidth-1:0] sp_in_cipher_dec_key_gen; + logic [Sp2VWidth-1:0] sp_out_cipher_dec_key_gen; + logic [Sp2VWidth-1:0] sp_ghash_in_valid; + logic [Sp2VWidth-1:0] sp_ghash_in_ready; + logic [Sp2VWidth-1:0] sp_ghash_out_valid; + logic [Sp2VWidth-1:0] sp_ghash_out_ready; + logic [Sp2VWidth-1:0] sp_ghash_load_hash_subkey; + + // Multi-rail signals. These are outputs of the single-rail FSMs and need combining. + logic [Sp2VWidth-1:0] mr_ctrl_we; + logic [Sp2VWidth-1:0] mr_ctrl_gcm_we; + logic [Sp2VWidth-1:0] mr_gcm_init_done; + logic [Sp2VWidth-1:0] mr_alert; + logic [Sp2VWidth-1:0] mr_data_in_we; + data_out_sel_e [Sp2VWidth-1:0] mr_data_out_sel; + dip_sel_e [Sp2VWidth-1:0] mr_data_in_prev_sel; + si_sel_e [Sp2VWidth-1:0] mr_state_in_sel; + add_si_sel_e [Sp2VWidth-1:0] mr_add_state_in_sel; + add_so_sel_e [Sp2VWidth-1:0] mr_add_state_out_sel; + logic [Sp2VWidth-1:0] mr_cipher_prng_reseed; + logic [Sp2VWidth-1:0] mr_cipher_key_clear; + logic [Sp2VWidth-1:0] mr_cipher_data_out_clear; + key_init_sel_e [Sp2VWidth-1:0] mr_key_init_sel; + iv_sel_e [Sp2VWidth-1:0] mr_iv_sel; + logic [Sp2VWidth-1:0] mr_prng_update; + logic [Sp2VWidth-1:0] mr_prng_reseed_req; + logic [Sp2VWidth-1:0] mr_start_we; + logic [Sp2VWidth-1:0] mr_key_iv_data_in_clear_we; + logic [Sp2VWidth-1:0] mr_data_out_clear_we; + logic [Sp2VWidth-1:0] mr_prng_reseed; + logic [Sp2VWidth-1:0] mr_prng_reseed_we; + logic [Sp2VWidth-1:0] mr_idle; + logic [Sp2VWidth-1:0] mr_idle_we; + logic [Sp2VWidth-1:0] mr_stall; + logic [Sp2VWidth-1:0] mr_stall_we; + logic [Sp2VWidth-1:0] mr_output_lost; + logic [Sp2VWidth-1:0] mr_output_lost_we; + logic [Sp2VWidth-1:0] mr_output_valid; + logic [Sp2VWidth-1:0] mr_output_valid_we; + logic [Sp2VWidth-1:0] mr_input_ready; + logic [Sp2VWidth-1:0] mr_input_ready_we; + + // To ease interfacing with the individual FSM rails, some signals need to be converted to packed + // arrays. + logic [Sp2VWidth-1:0][NumSharesKey-1:0][NumRegsKey-1:0] int_key_init_we; + logic [NumSharesKey-1:0][NumRegsKey-1:0][Sp2VWidth-1:0] log_key_init_we; + logic [NumSharesKey-1:0][NumRegsKey-1:0] int_key_init_qe; + for (genvar s = 0; s < NumSharesKey; s++) begin : gen_conv_key_init_wqe_shares + for (genvar i = 0; i < NumRegsKey; i++) begin : gen_conv_key_init_wqe_regs + assign int_key_init_qe[s][i] = key_init_qe_i[s][i]; + for (genvar j = 0; j < Sp2VWidth; j++) begin : gen_conv_key_init_wqe_log + assign log_key_init_we[s][i][j] = int_key_init_we[j][s][i]; + end + assign key_init_we_o[s][i] = sp2v_e'(log_key_init_we[s][i]); + end + end + logic [Sp2VWidth-1:0][NumSlicesCtr-1:0] int_ctr_we; + logic [NumSlicesCtr-1:0][Sp2VWidth-1:0] log_ctr_we; + logic [Sp2VWidth-1:0][NumSlicesCtr-1:0] int_iv_we; + logic [NumSlicesCtr-1:0][Sp2VWidth-1:0] log_iv_we; + for (genvar i = 0; i < NumSlicesCtr; i++) begin : gen_conv_ctr_iv_we_slices + assign log_ctr_we[i] = {ctr_we[i]}; + for (genvar j = 0; j < Sp2VWidth; j++) begin : gen_conv_ctr_iv_we_log + assign int_ctr_we[j][i] = log_ctr_we[i][j]; + assign log_iv_we[i][j] = int_iv_we[j][i]; + end + assign iv_we_o[i] = sp2v_e'(log_iv_we[i]); + end + + ///////// + // FSM // + ///////// + + // Convert sp2v_e signals to sparsified inputs. + assign sp_ctr_ready = {ctr_ready}; + assign sp_cipher_in_ready = {cipher_in_ready}; + assign sp_cipher_out_valid = {cipher_out_valid}; + assign sp_in_cipher_crypt = {cipher_crypt}; + assign sp_in_cipher_dec_key_gen = {cipher_dec_key_gen}; + assign sp_ghash_in_ready = {ghash_in_ready}; + assign sp_ghash_out_valid = {ghash_out_valid}; + + // SEC_CM: MAIN.FSM.REDUN + // For every bit in the Sp2V signals, one separate rail is instantiated. The inputs and outputs + // of every rail are buffered to prevent aggressive synthesis optimizations. + for (genvar i = 0; i < Sp2VWidth; i++) begin : gen_fsm + if (SP2V_LOGIC_HIGH[i] == 1'b1) begin : gen_fsm_p + aes_control_fsm_p #( + .AESGCMEnable ( AESGCMEnable ), + .SecMasking ( SecMasking ) + ) u_aes_control_fsm_i ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + + .ctrl_qe_i ( ctrl_qe_i ), + .ctrl_we_o ( mr_ctrl_we[i] ), // AND-combine + .ctrl_phase_i ( ctrl_phase_i ), + .ctrl_err_storage_i ( ctrl_err_storage_i ), + .op_i ( op_i ), + .mode_i ( mode_i ), + .cipher_op_i ( cipher_op_i ), + .sideload_i ( sideload_i ), + .prng_reseed_rate_i ( prng_reseed_rate_i ), + .manual_operation_i ( manual_operation_i ), + .key_touch_forces_reseed_i ( key_touch_forces_reseed_i ), + .ctrl_gcm_qe_i ( ctrl_gcm_qe_i ), + .ctrl_gcm_we_o ( mr_ctrl_gcm_we[i] ), // AND-combine + .ctrl_gcm_phase_i ( ctrl_gcm_phase_i ), + .gcm_init_done_o ( mr_gcm_init_done[i] ), // AND-combine + .gcm_phase_i ( gcm_phase_i ), + .start_i ( start_trigger ), + .key_iv_data_in_clear_i ( key_iv_data_in_clear_i ), + .data_out_clear_i ( data_out_clear_i ), + .prng_reseed_i ( prng_reseed_i ), + .mux_sel_err_i ( mux_sel_err ), + .sp_enc_err_i ( sp_enc_err ), + .lc_escalate_en_i ( lc_escalate_en_i ), + .alert_fatal_i ( alert_fatal_i ), + .alert_o ( mr_alert[i] ), // OR-combine + + .key_sideload_valid_i ( key_sideload_valid_i ), + .key_init_qe_i ( int_key_init_qe ), + .iv_qe_i ( iv_qe_i ), + .data_in_qe_i ( data_in_qe_i ), + .data_out_re_i ( data_out_re_i ), + .data_in_we_o ( mr_data_in_we[i] ), // AND-combine + .data_out_sel_o ( mr_data_out_sel[i] ), // OR-combine + .data_out_we_o ( sp_data_out_we[i] ), // Sparsified + + .data_in_prev_sel_o ( mr_data_in_prev_sel[i] ), // OR-combine + .data_in_prev_we_o ( sp_data_in_prev_we[i] ), // Sparsified + + .state_in_sel_o ( mr_state_in_sel[i] ), // OR-combine + .add_state_in_sel_o ( mr_add_state_in_sel[i] ), // OR-combine + .add_state_out_sel_o ( mr_add_state_out_sel[i] ), // OR-combine + + .ctr_inc32_o ( sp_ctr_inc32[i] ), // Sparsified + .ctr_incr_o ( sp_ctr_incr[i] ), // Sparsified + .ctr_ready_i ( sp_ctr_ready[i] ), // Sparsified + .ctr_we_i ( int_ctr_we[i] ), // Sparsified + + .cipher_in_valid_o ( sp_cipher_in_valid[i] ), // Sparsified + .cipher_in_ready_i ( sp_cipher_in_ready[i] ), // Sparsified + .cipher_out_valid_i ( sp_cipher_out_valid[i] ), // Sparsified + .cipher_out_ready_o ( sp_cipher_out_ready[i] ), // Sparsified + .cipher_crypt_o ( sp_out_cipher_crypt[i] ), // Sparsified + .cipher_crypt_i ( sp_in_cipher_crypt[i] ), // Sparsified + .cipher_dec_key_gen_o ( sp_out_cipher_dec_key_gen[i] ), // Sparsified + .cipher_dec_key_gen_i ( sp_in_cipher_dec_key_gen[i] ), // Sparsified + .cipher_prng_reseed_o ( mr_cipher_prng_reseed[i] ), // OR-combine + .cipher_prng_reseed_i ( cipher_prng_reseed_i ), + .cipher_key_clear_o ( mr_cipher_key_clear[i] ), // OR-combine + .cipher_key_clear_i ( cipher_key_clear_i ), + .cipher_data_out_clear_o ( mr_cipher_data_out_clear[i] ), // OR-combine + .cipher_data_out_clear_i ( cipher_data_out_clear_i ), + + .ghash_in_valid_o ( sp_ghash_in_valid[i] ), // Sparsified + .ghash_in_ready_i ( sp_ghash_in_ready[i] ), // Sparsified + .ghash_out_valid_i ( sp_ghash_out_valid[i] ), // Sparsified + .ghash_out_ready_o ( sp_ghash_out_ready[i] ), // Sparsified + .ghash_load_hash_subkey_o ( sp_ghash_load_hash_subkey[i] ), // Sparsified + + .key_init_sel_o ( mr_key_init_sel[i] ), // OR-combine + .key_init_we_o ( int_key_init_we[i] ), // Sparsified + + .iv_sel_o ( mr_iv_sel[i] ), // OR-combine + .iv_we_o ( int_iv_we[i] ), // Sparsified + + .prng_update_o ( mr_prng_update[i] ), // OR-combine + .prng_reseed_req_o ( mr_prng_reseed_req[i] ), // OR-combine + .prng_reseed_ack_i ( prng_reseed_ack_i ), + + .start_we_o ( mr_start_we[i] ), // OR-combine + .key_iv_data_in_clear_we_o ( mr_key_iv_data_in_clear_we[i] ), // AND-combine + .data_out_clear_we_o ( mr_data_out_clear_we[i] ), // AND-combine + .prng_reseed_o ( mr_prng_reseed[i] ), // OR-combine + .prng_reseed_we_o ( mr_prng_reseed_we[i] ), // OR-combine + + .idle_o ( mr_idle[i] ), // AND-combine + .idle_we_o ( mr_idle_we[i] ), // AND-combine + .stall_o ( mr_stall[i] ), // AND-combine + .stall_we_o ( mr_stall_we[i] ), // AND-combine + .output_lost_i ( output_lost_i ), // AND-combine + .output_lost_o ( mr_output_lost[i] ), // AND-combine + .output_lost_we_o ( mr_output_lost_we[i] ), // AND-combine + .output_valid_o ( mr_output_valid[i] ), // AND-combine + .output_valid_we_o ( mr_output_valid_we[i] ), // AND-combine + .input_ready_o ( mr_input_ready[i] ), // AND-combine + .input_ready_we_o ( mr_input_ready_we[i] ) // AND-combine + ); + end else begin : gen_fsm_n + aes_control_fsm_n #( + .AESGCMEnable ( AESGCMEnable ), + .SecMasking ( SecMasking ) + ) u_aes_control_fsm_i ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + + .ctrl_qe_i ( ctrl_qe_i ), + .ctrl_we_o ( mr_ctrl_we[i] ), // AND-combine + .ctrl_phase_i ( ctrl_phase_i ), + .ctrl_err_storage_i ( ctrl_err_storage_i ), + .op_i ( op_i ), + .mode_i ( mode_i ), + .cipher_op_i ( cipher_op_i ), + .sideload_i ( sideload_i ), + .prng_reseed_rate_i ( prng_reseed_rate_i ), + .manual_operation_i ( manual_operation_i ), + .key_touch_forces_reseed_i ( key_touch_forces_reseed_i ), + .ctrl_gcm_qe_i ( ctrl_gcm_qe_i ), + .ctrl_gcm_we_o ( mr_ctrl_gcm_we[i] ), // AND-combine + .ctrl_gcm_phase_i ( ctrl_gcm_phase_i ), + .gcm_init_done_o ( mr_gcm_init_done[i] ), // AND-combine + .gcm_phase_i ( gcm_phase_i ), + .start_i ( start_trigger ), + .key_iv_data_in_clear_i ( key_iv_data_in_clear_i ), + .data_out_clear_i ( data_out_clear_i ), + .prng_reseed_i ( prng_reseed_i ), + .mux_sel_err_i ( mux_sel_err ), + .sp_enc_err_i ( sp_enc_err ), + .lc_escalate_en_i ( lc_escalate_en_i ), + .alert_fatal_i ( alert_fatal_i ), + .alert_o ( mr_alert[i] ), // OR-combine + + .key_sideload_valid_i ( key_sideload_valid_i ), + .key_init_qe_i ( int_key_init_qe ), + .iv_qe_i ( iv_qe_i ), + .data_in_qe_i ( data_in_qe_i ), + .data_out_re_i ( data_out_re_i ), + .data_in_we_o ( mr_data_in_we[i] ), // AND-combine + .data_out_sel_o ( mr_data_out_sel[i] ), // OR-combine + .data_out_we_no ( sp_data_out_we[i] ), // Sparsified + + .data_in_prev_sel_o ( mr_data_in_prev_sel[i] ), // OR-combine + .data_in_prev_we_no ( sp_data_in_prev_we[i] ), // Sparsified + + .state_in_sel_o ( mr_state_in_sel[i] ), // OR-combine + .add_state_in_sel_o ( mr_add_state_in_sel[i] ), // OR-combine + .add_state_out_sel_o ( mr_add_state_out_sel[i] ), // OR-combine + + .ctr_inc32_no ( sp_ctr_inc32[i] ), // Sparsified + .ctr_incr_no ( sp_ctr_incr[i] ), // Sparsified + .ctr_ready_ni ( sp_ctr_ready[i] ), // Sparsified + .ctr_we_ni ( int_ctr_we[i] ), // Sparsified + + .cipher_in_valid_no ( sp_cipher_in_valid[i] ), // Sparsified + .cipher_in_ready_ni ( sp_cipher_in_ready[i] ), // Sparsified + .cipher_out_valid_ni ( sp_cipher_out_valid[i] ), // Sparsified + .cipher_out_ready_no ( sp_cipher_out_ready[i] ), // Sparsified + .cipher_crypt_no ( sp_out_cipher_crypt[i] ), // Sparsified + .cipher_crypt_ni ( sp_in_cipher_crypt[i] ), // Sparsified + .cipher_dec_key_gen_no ( sp_out_cipher_dec_key_gen[i] ), // Sparsified + .cipher_dec_key_gen_ni ( sp_in_cipher_dec_key_gen[i] ), // Sparsified + .cipher_prng_reseed_o ( mr_cipher_prng_reseed[i] ), // OR-combine + .cipher_prng_reseed_i ( cipher_prng_reseed_i ), + .cipher_key_clear_o ( mr_cipher_key_clear[i] ), // OR-combine + .cipher_key_clear_i ( cipher_key_clear_i ), + .cipher_data_out_clear_o ( mr_cipher_data_out_clear[i] ), // OR-combine + .cipher_data_out_clear_i ( cipher_data_out_clear_i ), + + .ghash_in_valid_no ( sp_ghash_in_valid[i] ), // Sparsified + .ghash_in_ready_ni ( sp_ghash_in_ready[i] ), // Sparsified + .ghash_out_valid_ni ( sp_ghash_out_valid[i] ), // Sparsified + .ghash_out_ready_no ( sp_ghash_out_ready[i] ), // Sparsified + .ghash_load_hash_subkey_no ( sp_ghash_load_hash_subkey[i] ), // Sparsified + + .key_init_sel_o ( mr_key_init_sel[i] ), // OR-combine + .key_init_we_no ( int_key_init_we[i] ), // Sparsified + + .iv_sel_o ( mr_iv_sel[i] ), // OR-combine + .iv_we_no ( int_iv_we[i] ), // Sparsified + + .prng_update_o ( mr_prng_update[i] ), // OR-combine + .prng_reseed_req_o ( mr_prng_reseed_req[i] ), // OR-combine + .prng_reseed_ack_i ( prng_reseed_ack_i ), + + .start_we_o ( mr_start_we[i] ), // OR-combine + .key_iv_data_in_clear_we_o ( mr_key_iv_data_in_clear_we[i] ), // AND-combine + .data_out_clear_we_o ( mr_data_out_clear_we[i] ), // AND-combine + .prng_reseed_o ( mr_prng_reseed[i] ), // OR-combine + .prng_reseed_we_o ( mr_prng_reseed_we[i] ), // OR-combine + + .idle_o ( mr_idle[i] ), // AND-combine + .idle_we_o ( mr_idle_we[i] ), // AND-combine + .stall_o ( mr_stall[i] ), // AND-combine + .stall_we_o ( mr_stall_we[i] ), // AND-combine + .output_lost_i ( output_lost_i ), // AND-combine + .output_lost_o ( mr_output_lost[i] ), // AND-combine + .output_lost_we_o ( mr_output_lost_we[i] ), // AND-combine + .output_valid_o ( mr_output_valid[i] ), // AND-combine + .output_valid_we_o ( mr_output_valid_we[i] ), // AND-combine + .input_ready_o ( mr_input_ready[i] ), // AND-combine + .input_ready_we_o ( mr_input_ready_we[i] ) // AND-combine + ); + end + end + + // Convert sparsified outputs to sp2v_e type. + assign data_out_we_o = sp2v_e'(sp_data_out_we); + assign data_in_prev_we_o = sp2v_e'(sp_data_in_prev_we); + assign ctr_inc32_o = sp2v_e'(sp_ctr_inc32); + assign ctr_incr_o = sp2v_e'(sp_ctr_incr); + assign cipher_in_valid_o = sp2v_e'(sp_cipher_in_valid); + assign cipher_out_ready_o = sp2v_e'(sp_cipher_out_ready); + assign cipher_crypt_o = sp2v_e'(sp_out_cipher_crypt); + assign cipher_dec_key_gen_o = sp2v_e'(sp_out_cipher_dec_key_gen); + assign ghash_in_valid_o = sp2v_e'(sp_ghash_in_valid); + assign ghash_out_ready_o = sp2v_e'(sp_ghash_out_ready); + assign ghash_load_hash_subkey_o = sp2v_e'(sp_ghash_load_hash_subkey); + + // Combine single-bit FSM outputs. + // OR: One bit is sufficient to drive the corresponding output bit high. + assign alert_o = |mr_alert; + assign cipher_prng_reseed_o = |mr_cipher_prng_reseed; + assign cipher_key_clear_o = |mr_cipher_key_clear; + assign cipher_data_out_clear_o = |mr_cipher_data_out_clear; + assign prng_update_o = |mr_prng_update; + assign prng_reseed_req_o = |mr_prng_reseed_req; + assign start_we_o = |mr_start_we; + assign prng_reseed_o = |mr_prng_reseed; + assign prng_reseed_we_o = |mr_prng_reseed_we; + + // AND: Only if all bits are high, the corresponding action should be triggered. + assign ctrl_we_o = &mr_ctrl_we; + assign ctrl_gcm_we_o = &mr_ctrl_gcm_we; + assign gcm_init_done_o = &mr_gcm_init_done; + assign data_in_we_o = &mr_data_in_we; + assign key_iv_data_in_clear_we_o = &mr_key_iv_data_in_clear_we; + assign data_out_clear_we_o = &mr_data_out_clear_we; + assign idle_o = &mr_idle; + assign idle_we_o = &mr_idle_we; + assign stall_o = &mr_stall; + assign stall_we_o = &mr_stall_we; + assign output_lost_o = &mr_output_lost; + assign output_lost_we_o = &mr_output_lost_we; + assign output_valid_o = &mr_output_valid; + assign output_valid_we_o = &mr_output_valid_we; + assign input_ready_o = &mr_input_ready; + assign input_ready_we_o = &mr_input_ready_we; + + // Combine multi-bit, sparse FSM outputs. We simply OR them together. If the FSMs don't provide + // the same outputs, two cases are possible: + // - An invalid encoding results: A downstream checker will fire, see mux_sel_err_i. + // - A valid encoding results: The outputs are compared below to cover this case, see mr_err; + always_comb begin : combine_sparse_signals + data_out_sel_o = data_out_sel_e'({DataOutSelWidth{1'b0}}); + data_in_prev_sel_o = dip_sel_e'({DIPSelWidth{1'b0}}); + state_in_sel_o = si_sel_e'({SISelWidth{1'b0}}); + add_state_in_sel_o = add_si_sel_e'({AddSISelWidth{1'b0}}); + add_state_out_sel_o = add_so_sel_e'({AddSOSelWidth{1'b0}}); + key_init_sel_o = key_init_sel_e'({KeyInitSelWidth{1'b0}}); + iv_sel_o = iv_sel_e'({IVSelWidth{1'b0}}); + mr_err = 1'b0; + + for (int i = 0; i < Sp2VWidth; i++) begin + data_out_sel_o = data_out_sel_e'({data_out_sel_o} | {mr_data_out_sel[i]}); + data_in_prev_sel_o = dip_sel_e'({data_in_prev_sel_o} | {mr_data_in_prev_sel[i]}); + state_in_sel_o = si_sel_e'({state_in_sel_o} | {mr_state_in_sel[i]}); + add_state_in_sel_o = add_si_sel_e'({add_state_in_sel_o} | {mr_add_state_in_sel[i]}); + add_state_out_sel_o = add_so_sel_e'({add_state_out_sel_o} | {mr_add_state_out_sel[i]}); + key_init_sel_o = key_init_sel_e'({key_init_sel_o} | {mr_key_init_sel[i]}); + iv_sel_o = iv_sel_e'({iv_sel_o} | {mr_iv_sel[i]}); + end + + for (int i = 0; i < Sp2VWidth; i++) begin + if (data_out_sel_o != mr_data_out_sel[i] || + data_in_prev_sel_o != mr_data_in_prev_sel[i] || + state_in_sel_o != mr_state_in_sel[i] || + add_state_in_sel_o != mr_add_state_in_sel[i] || + add_state_out_sel_o != mr_add_state_out_sel[i] || + key_init_sel_o != mr_key_init_sel[i] || + iv_sel_o != mr_iv_sel[i]) begin + mr_err = 1'b1; + end + end + end + + // Collect errors in mux selector signals. + assign mux_sel_err = mux_sel_err_i | mr_err; + + ////////////////////////////// + // Sparsely Encoded Signals // + ////////////////////////////// + + // SEC_CM: CTRL.SPARSE + // We use sparse encodings for various critical signals and must ensure that: + // 1. The synthesis tool doesn't optimize away the sparse encoding. + // 2. The sparsely encoded signal is always valid. More precisely, an alert or SVA is triggered + // if a sparse signal takes on an invalid value. + // 3. The alert signal remains asserted until reset even if the sparse signal becomes valid again + // This is achieved by driving the control FSM into the terminal error state whenever any + // sparsely encoded signal becomes invalid. + // + // If any sparsely encoded signal becomes invalid, the controller further immediately de-asserts + // data_out_we_o and other write-enable signals to prevent any data from being released. + + // We use vectors of sparsely encoded signals to reduce code duplication. + localparam int unsigned NumSp2VSig = 7 + NumSlicesCtr; + sp2v_e [NumSp2VSig-1:0] sp2v_sig; + sp2v_e [NumSp2VSig-1:0] sp2v_sig_chk; + logic [NumSp2VSig-1:0][Sp2VWidth-1:0] sp2v_sig_chk_raw; + logic [NumSp2VSig-1:0] sp2v_sig_err; + + assign sp2v_sig[0] = cipher_in_ready_i; + assign sp2v_sig[1] = cipher_out_valid_i; + assign sp2v_sig[2] = cipher_crypt_i; + assign sp2v_sig[3] = cipher_dec_key_gen_i; + assign sp2v_sig[4] = ghash_in_ready_i; + assign sp2v_sig[5] = ghash_out_valid_i; + assign sp2v_sig[6] = ctr_ready_i; + for (genvar i = 0; i < NumSlicesCtr; i++) begin : gen_use_ctr_we_i + assign sp2v_sig[7+i] = ctr_we_i[i]; + end + + // All signals inside sp2v_sig are driven and consumed by multi-rail FSMs. + localparam bit [NumSp2VSig-1:0] Sp2VEnSecBuf = '0; + + // Individually check sparsely encoded signals. + for (genvar i = 0; i < NumSp2VSig; i++) begin : gen_sel_buf_chk + aes_sel_buf_chk #( + .Num ( Sp2VNum ), + .Width ( Sp2VWidth ), + .EnSecBuf ( Sp2VEnSecBuf[i] ) + ) u_aes_sp2v_sig_buf_chk_i ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .sel_i ( sp2v_sig[i] ), + .sel_o ( sp2v_sig_chk_raw[i] ), + .err_o ( sp2v_sig_err[i] ) + ); + assign sp2v_sig_chk[i] = sp2v_e'(sp2v_sig_chk_raw[i]); + end + + assign cipher_in_ready = sp2v_sig_chk[0]; + assign cipher_out_valid = sp2v_sig_chk[1]; + assign cipher_crypt = sp2v_sig_chk[2]; + assign cipher_dec_key_gen = sp2v_sig_chk[3]; + assign ghash_in_ready = sp2v_sig_chk[4]; + assign ghash_out_valid = sp2v_sig_chk[5]; + assign ctr_ready = sp2v_sig_chk[6]; + for (genvar i = 0; i < NumSlicesCtr; i++) begin : gen_ctr_we + assign ctr_we[i] = sp2v_sig_chk[7+i]; + end + + // Collect encoding errors. + // We instantiate the checker modules as close as possible to where the sparsely encoded signals + // are used. Here, we collect also encoding errors detected in other places of the core. + assign sp_enc_err = |sp2v_sig_err | sp_enc_err_i; + + ////////////////////// + // Trigger Register // + ////////////////////// + // Most triggers are only ever cleared by control. + assign start_o = 1'b0; + assign key_iv_data_in_clear_o = 1'b0; + assign data_out_clear_o = 1'b0; + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/aes_control_fsm.sv b/designs/Caliptra/src/caliptra-rtl/aes_control_fsm.sv new file mode 100644 index 0000000..21c10db --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/aes_control_fsm.sv @@ -0,0 +1,1202 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// AES main control FSM +// +// This module contains the main control FSM handling the interplay of input/output registers and +// the AES cipher core. + +`include "caliptra_prim_assert.sv" + +module aes_control_fsm + import aes_pkg::*; + import aes_reg_pkg::*; +#( + parameter bit AESGCMEnable = 0, + parameter bit SecMasking = 0 +) ( + input logic clk_i, + input logic rst_ni, + + // Main control signals + input logic ctrl_qe_i, + output logic ctrl_we_o, + input logic ctrl_phase_i, + input logic ctrl_err_storage_i, + input aes_op_e op_i, + input aes_mode_e mode_i, + input ciph_op_e cipher_op_i, + input logic sideload_i, + input prs_rate_e prng_reseed_rate_i, + input logic manual_operation_i, + input logic key_touch_forces_reseed_i, + input logic ctrl_gcm_qe_i, + output logic ctrl_gcm_we_o, + input logic ctrl_gcm_phase_i, + output logic gcm_init_done_o, + input gcm_phase_e gcm_phase_i, + input logic start_i, + input logic key_iv_data_in_clear_i, + input logic data_out_clear_i, + input logic prng_reseed_i, + input logic mux_sel_err_i, + input logic sp_enc_err_i, + input lc_ctrl_pkg::lc_tx_t lc_escalate_en_i, + input logic alert_fatal_i, + output logic alert_o, + + // I/O register read/write enables + input logic key_sideload_valid_i, + input logic [NumSharesKey-1:0][NumRegsKey-1:0] key_init_qe_i, + input logic [NumRegsIv-1:0] iv_qe_i, + input logic [NumRegsData-1:0] data_in_qe_i, + input logic [NumRegsData-1:0] data_out_re_i, + output logic data_in_we_o, + output data_out_sel_e data_out_sel_o, + output logic data_out_we_o, // Sparsify + + // Previous input data register + output dip_sel_e data_in_prev_sel_o, + output logic data_in_prev_we_o, // Sparsify + + // Cipher I/O muxes + output si_sel_e state_in_sel_o, + output add_si_sel_e add_state_in_sel_o, + output add_so_sel_e add_state_out_sel_o, + + // Counter + output logic ctr_inc32_o, // Sparsify + output logic ctr_incr_o, // Sparsify + input logic ctr_ready_i, // Sparsify + input logic [NumSlicesCtr-1:0] ctr_we_i, // Sparsify + + // Cipher core control and sync + output logic cipher_in_valid_o, // Sparsify + input logic cipher_in_ready_i, // Sparsify + input logic cipher_out_valid_i, // Sparsify + output logic cipher_out_ready_o, // Sparsify + output logic cipher_crypt_o, // Sparsify + input logic cipher_crypt_i, // Sparsify + output logic cipher_dec_key_gen_o, // Sparsify + input logic cipher_dec_key_gen_i, // Sparsify + output logic cipher_prng_reseed_o, + input logic cipher_prng_reseed_i, + output logic cipher_key_clear_o, + input logic cipher_key_clear_i, + output logic cipher_data_out_clear_o, + input logic cipher_data_out_clear_i, + + // GHASH control and sync + output logic ghash_in_valid_o, // Sparsify + input logic ghash_in_ready_i, // Sparsify + input logic ghash_out_valid_i, // Sparsify + output logic ghash_out_ready_o, // Sparsify + output logic ghash_load_hash_subkey_o, // Sparsify + + // Initial key registers + output key_init_sel_e key_init_sel_o, + output logic [NumSharesKey-1:0][NumRegsKey-1:0] key_init_we_o, // Sparsify + + // IV registers + output iv_sel_e iv_sel_o, + output logic [NumSlicesCtr-1:0] iv_we_o, // Sparsify + + // Pseudo-random number generator interface + output logic prng_update_o, + output logic prng_reseed_req_o, + input logic prng_reseed_ack_i, + + // Trigger register + output logic start_we_o, + output logic key_iv_data_in_clear_we_o, + output logic data_out_clear_we_o, + output logic prng_reseed_o, + output logic prng_reseed_we_o, + + // Status register + output logic idle_o, + output logic idle_we_o, + output logic stall_o, + output logic stall_we_o, + input logic output_lost_i, + output logic output_lost_o, + output logic output_lost_we_o, + output logic output_valid_o, + output logic output_valid_we_o, + output logic input_ready_o, + output logic input_ready_we_o +); + + // Signals + aes_ctrl_e aes_ctrl_ns, aes_ctrl_cs; + logic prng_reseed_done_d, prng_reseed_done_q; + + logic key_init_clear; + logic key_init_new; + logic key_init_new_pulse; + logic key_init_load; + logic key_init_arm; + logic key_init_ready; + logic key_sideload; + + logic [NumSlicesCtr-1:0] iv_qe; + logic iv_clear; + logic iv_load; + logic iv_arm; + logic iv_ready; + + logic [NumRegsData-1:0] data_in_new_d, data_in_new_q; + logic data_in_new; + logic data_in_load; + + logic [NumRegsData-1:0] data_out_read_d, data_out_read_q; + logic data_out_read; + logic output_valid_q; + + logic cfg_valid; + logic no_alert; + logic cipher_op_err; + logic start_common, start_ecb, start_cbc, start_cfb, start_ofb, start_ctr; + logic start; + logic start_core; + logic finish; + logic crypt; + logic cipher_out_done; + logic doing_cbc_enc, doing_cbc_dec; + logic doing_cfb_enc, doing_cfb_dec; + logic doing_ofb; + logic doing_ctr; + logic ctrl_we_q; + logic clear_in_out_status; + logic clear_on_fatal; + + logic start_we; + logic key_iv_data_in_clear_we; + logic data_out_clear_we; + logic prng_reseed_we; + + logic idle; + logic idle_we; + logic stall; + logic stall_we; + logic output_lost; + logic output_lost_we; + logic output_valid; + logic output_valid_we; + logic input_ready; + logic input_ready_we; + + logic ctrl_gcm_we_q; + logic gcm_clear; + logic gcm_init, gcm_restore, gcm_aad, gcm_txt, gcm_save, gcm_tag; + logic start_common_gcm, start_ghash; + logic start_gcm_init, start_gcm_hsk, start_gcm_s; + logic start_gcm_restore, start_gcm_aad, start_gcm_txt, start_gcm_save; + logic start_gcm_tag; + logic doing_gcm_hsk, doing_gcm_s, doing_gcm_txt; + logic hash_subkey_ready_d, hash_subkey_ready_q; + logic s_ready_d, s_ready_q; + logic doing_gcm_restore_d, doing_gcm_restore_q; + logic doing_gcm_aad_d, doing_gcm_aad_q; + logic doing_gcm_tag_d, doing_gcm_tag_q; + logic doing_gcm_save_d, doing_gcm_save_q; + logic ghash_out_done; + logic ghash_idle; + + logic block_ctr_expr; + logic block_ctr_decr; + + // Software updates IV in chunks of 32 bits, the counter updates SliceSizeCtr bits at a time. + // Convert word write enable to internal half-word write enable. + assign iv_qe = {iv_qe_i[3], iv_qe_i[3], iv_qe_i[2], iv_qe_i[2], + iv_qe_i[1], iv_qe_i[1], iv_qe_i[0], iv_qe_i[0]}; + + // The cipher core is only ever allowed to start or finish if the control register holds a valid + // configuration and if no fatal alert condition occured. + assign cfg_valid = ~((mode_i == AES_NONE) | ctrl_err_storage_i); + assign no_alert = ~alert_fatal_i; + + // cipher_op_i is obtained from the configuration of the control register with additional logic. + assign cipher_op_err = ~(cipher_op_i == CIPH_FWD || cipher_op_i == CIPH_INV); + + // Check common start conditions. These are needed for any mode, unless we are running in + // manual mode. + assign start_common = key_init_ready & data_in_new & + // If key sideload is enabled, we only start if the key is valid. + (sideload_i ? key_sideload_valid_i : 1'b1); + + // Check mode-specific start conditions. If the IV (and counter) is needed, we only start if + // also the IV (and counter) is ready. + assign start_ecb = (mode_i == AES_ECB); + assign start_cbc = (mode_i == AES_CBC) & iv_ready; + assign start_cfb = (mode_i == AES_CFB) & iv_ready; + assign start_ofb = (mode_i == AES_OFB) & iv_ready; + assign start_ctr = (mode_i == AES_CTR) & iv_ready & ctr_ready_i; + + // If set to start manually, we just wait for the trigger. Otherwise, check common as well as + // mode-specific start conditions. + assign start = cfg_valid & no_alert & + // Manual operation has priority. + (manual_operation_i ? start_i : + // Check start conditions for automatic operation. + ((start_ecb | + start_cbc | + start_cfb | + start_ofb | + start_ctr) & start_common) | + // Only the initial as well as the ciphertext/plaintext phases of GCM require operating + // the AES cipher core. Common start conditions are already factored into these signals. + (start_gcm_init | + start_gcm_txt)); + + // If not set to overwrite data, we wait for any previous output data to be read. data_out_read + // synchronously clears output_valid_q, unless new output data is written in the exact same + // clock cycle. + assign finish = cfg_valid & no_alert & + // Manual operation has priority. + (manual_operation_i ? 1'b1 : + // Make sure previous output data has been read. + (~output_valid_q | data_out_read)); + + ////////////////////////// + // GCM Start Conditions // + ////////////////////////// + // Note that only the initial as well as the ciphertext/plaintext phases of GCM require operating + // the AES cipher core. The start conditions for these phases are factored into the regular start + // signal above. In contrast, the restore, AAD, save and tag phases use the GHASH block only. The + // corresponding start conditions are handled separately by the FSM and we need to explicilty + // factor in manual operation below. + + assign gcm_init = (mode_i == AES_GCM) & (gcm_phase_i == GCM_INIT); + assign gcm_restore = (mode_i == AES_GCM) & (gcm_phase_i == GCM_RESTORE); + assign gcm_aad = (mode_i == AES_GCM) & (gcm_phase_i == GCM_AAD); + assign gcm_txt = (mode_i == AES_GCM) & (gcm_phase_i == GCM_TEXT); + assign gcm_save = (mode_i == AES_GCM) & (gcm_phase_i == GCM_SAVE); + assign gcm_tag = (mode_i == AES_GCM) & (gcm_phase_i == GCM_TAG); + + // The common start conditions for GCM don't include the input data. + assign start_common_gcm = key_init_ready & + // If key sideload is enabled, we only start if the key is valid. + (sideload_i ? key_sideload_valid_i : 1'b1); + + // For the initial GCM phase, we need key and IV but then encrypt two blocks. The input data + // is not required. Requires operating the AES cipher core and thus factors into the regular + // start signal. Delay GCM initialization while clearing GCM-related status tracking. + assign start_gcm_hsk = gcm_init & ~gcm_clear & ~hash_subkey_ready_q & iv_ready & ctr_ready_i; + assign start_gcm_s = gcm_init & ~gcm_clear & ~s_ready_q & iv_ready & ctr_ready_i; + assign start_gcm_init = (start_gcm_hsk | start_gcm_s) & start_common_gcm; + + // For the restore phase of GCM, we need key, IV and input data. If set to start manually, we + // just wait for the trigger. + assign start_gcm_restore = gcm_restore & cfg_valid & no_alert & + // Manual operation has priority. + (manual_operation_i ? start_i : iv_ready & ctr_ready_i & data_in_new & start_common_gcm); + + // For the AAD and ciphertext/plaintext phases of GCM, we need key, IV and input data. But for + // the AAD phase, only the input data is really used and marked as used. The start condition for + // the AAD phase is handled separately by the FSM and we need to factor in the manual operation + // mode here. + assign start_gcm_aad = gcm_aad & cfg_valid & no_alert & + // Manual operation has priority. + (manual_operation_i ? start_i : iv_ready & ctr_ready_i & start_common); + // The ciphertext/plaintext phase requires operating AES cipher core and thus factors into the + // regular start signal. + assign start_gcm_txt = gcm_txt & iv_ready & ctr_ready_i & start_common; + + // For the save phase of GCM, we need no inputs. But the hash subkey and S must not yet have been + // cleared (happens upon saving the GHASH state). + assign start_gcm_save = gcm_save & cfg_valid & no_alert & + // Manual operation has priority. + (manual_operation_i ? start_i : hash_subkey_ready_q & s_ready_q); + + // For the tag phase of GCM, we also need the input data. + assign start_gcm_tag = gcm_tag & cfg_valid & no_alert & + // Manual operation has priority. + (manual_operation_i ? start_i : hash_subkey_ready_q & s_ready_q & data_in_new); + + // The restore, AAD, save and tag phases use the GHASH block only. + assign start_ghash = start_gcm_restore | start_gcm_aad | start_gcm_save | start_gcm_tag; + + // The GHASH block is idle whenever it's ready to receive inputs and we're not about to start + // a GCM related operation. + assign ghash_idle = ghash_in_ready_i & ~start_ghash; + + // In GCM, the counter performs inc32() instead of inc128(), i.e., the counter wraps at 32 bits. + assign ctr_inc32_o = (mode_i == AES_GCM); + + // Helper signals for FSM + assign crypt = cipher_crypt_o | cipher_crypt_i; + + assign doing_cbc_enc = (mode_i == AES_CBC && op_i == AES_ENC) & crypt; + assign doing_cbc_dec = (mode_i == AES_CBC && op_i == AES_DEC) & crypt; + assign doing_cfb_enc = (mode_i == AES_CFB && op_i == AES_ENC) & crypt; + assign doing_cfb_dec = (mode_i == AES_CFB && op_i == AES_DEC) & crypt; + assign doing_ofb = (mode_i == AES_OFB) & crypt; + assign doing_ctr = (mode_i == AES_CTR) & crypt; + assign doing_gcm_hsk = gcm_init & ~hash_subkey_ready_q & crypt; + assign doing_gcm_s = gcm_init & hash_subkey_ready_q & crypt; + assign doing_gcm_txt = gcm_txt & crypt; + + // FSM + always_comb begin : aes_ctrl_fsm + + // Previous input data register control + data_in_prev_sel_o = DIP_CLEAR; + data_in_prev_we_o = 1'b0; + + // Cipher I/O mux control + state_in_sel_o = SI_DATA; + add_state_in_sel_o = ADD_SI_ZERO; + add_state_out_sel_o = ADD_SO_ZERO; + + // Counter control + ctr_incr_o = 1'b0; + + // Cipher core control + cipher_in_valid_o = 1'b0; + cipher_out_ready_o = 1'b0; + cipher_out_done = 1'b0; + cipher_crypt_o = 1'b0; + cipher_dec_key_gen_o = 1'b0; + cipher_prng_reseed_o = 1'b0; + cipher_key_clear_o = 1'b0; + cipher_data_out_clear_o = 1'b0; + + // GHASH control + ghash_in_valid_o = 1'b0; + ghash_out_ready_o = 1'b0; + ghash_out_done = 1'b0; + ghash_load_hash_subkey_o = ~hash_subkey_ready_q; + + // Initial key registers + key_init_sel_o = sideload_i ? KEY_INIT_KEYMGR : KEY_INIT_INPUT; + key_init_we_o = {NumSharesKey * NumRegsKey{1'b0}}; + + // IV registers + iv_sel_o = IV_INPUT; + iv_we_o = {NumSlicesCtr{1'b0}}; + + // Control registers + ctrl_we_o = 1'b0; + ctrl_gcm_we_o = 1'b0; + + // Alert + alert_o = 1'b0; + + // Pseudo-random number generator control + prng_update_o = 1'b0; + prng_reseed_req_o = 1'b0; + + // Trigger register control + start_we = 1'b0; + key_iv_data_in_clear_we = 1'b0; + data_out_clear_we = 1'b0; + prng_reseed_we = 1'b0; + + // Status register + idle = 1'b0; + idle_we = 1'b0; + stall = 1'b0; + stall_we = 1'b0; + + // Key, data I/O register control + data_in_load = 1'b0; + data_in_we_o = 1'b0; + data_out_sel_o = DATA_OUT_CIPHER; + data_out_we_o = 1'b0; + + // Register status tracker control + key_init_clear = 1'b0; + key_init_load = 1'b0; + key_init_arm = 1'b0; + iv_clear = 1'b0; + iv_load = 1'b0; + iv_arm = 1'b0; + + // Block counter + block_ctr_decr = 1'b0; + + // FSM + aes_ctrl_ns = aes_ctrl_cs; + start_core = 1'b0; + prng_reseed_done_d = prng_reseed_done_q | prng_reseed_ack_i; + hash_subkey_ready_d = hash_subkey_ready_q; + s_ready_d = s_ready_q; + doing_gcm_restore_d = doing_gcm_restore_q; + doing_gcm_aad_d = doing_gcm_aad_q; + doing_gcm_tag_d = doing_gcm_tag_q; + doing_gcm_save_d = doing_gcm_save_q; + + unique case (aes_ctrl_cs) + + CTRL_IDLE: begin + // The core is about to start encryption/decryption or another action. + start_core = start | key_iv_data_in_clear_i | data_out_clear_i | prng_reseed_i; + + // Update status register. A write to the main control register (if sideload is enabled) + // or writing the last key register can initiate a PRNG reseed operation via trigger + // register. To avoid that subsequent writes to the main control, key or IV registers + // collide with the start of the reseed operation, de-assert the idle bit. The GHASH block + // may still be busy while the cipher core is actually idle. + idle = ~(start_core | (prng_reseed_o & prng_reseed_we_o)) & ghash_idle; + idle_we = 1'b1; + + // Clear the start trigger when seeing invalid configurations or performing automatic + // operation. + start_we = start_i & ((mode_i == AES_NONE) | ~manual_operation_i); + + if (!start_core) begin + // Initial key and IV updates are ignored if the core is about to start. If key sideload + // is enabled, software writes to the initial key registers are ignored. + key_init_we_o = sideload_i ? {NumSharesKey * NumRegsKey{key_sideload}} : key_init_qe_i; + iv_we_o = iv_qe; + end + + if (!start_core && !start_ghash) begin + // Updates to the main and GCM control registers are only allowed if the cipher core and + // the GHASH block are not about to start and there isn't a storage error. A storage + // error is unrecoverable and requires a reset. + ctrl_we_o = !ctrl_err_storage_i ? ctrl_qe_i : 1'b0; + ctrl_gcm_we_o = !ctrl_err_storage_i ? ctrl_gcm_qe_i : 1'b0; + + // Control register updates clear all register status trackers. As GCM initialization + // advances the IV, we have to clear the IV status tracking when re-initializing GCM. + key_init_clear = ctrl_we_o; + iv_clear = ctrl_we_o | (gcm_init & gcm_clear); + + // Also clear GCM-specific status tracking. + if (ctrl_we_o | gcm_clear) begin + hash_subkey_ready_d = 1'b0; + s_ready_d = 1'b0; + end + end + + if (prng_reseed_i) begin + // PRNG reseeding has highest priority. + if (!SecMasking) begin + prng_reseed_done_d = 1'b0; + aes_ctrl_ns = CTRL_PRNG_RESEED; + end else begin + // In case masking is enabled, also the masking PRNG inside the cipher core needs to + // be reseeded. + cipher_prng_reseed_o = 1'b1; + + // Perform handshake. + cipher_in_valid_o = 1'b1; + if (cipher_in_ready_i) begin + prng_reseed_done_d = 1'b0; + aes_ctrl_ns = CTRL_PRNG_RESEED; + end + end + + end else if (key_iv_data_in_clear_i || data_out_clear_i) begin + // To clear registers, we update the PRNG and then wait for the GHASH block. + prng_update_o = 1'b1; + + // To clear the output data registers, we re-use the muxing resources of the cipher + // core. To clear all key material, some key registers inside the cipher core need to + // be cleared. + cipher_key_clear_o = key_iv_data_in_clear_i; + cipher_data_out_clear_o = data_out_clear_i; + + // We have work for the cipher core, perform handshake. + cipher_in_valid_o = 1'b1; + if (cipher_in_ready_i) begin + aes_ctrl_ns = CTRL_GHASH_READY; + end + + end else if (start_gcm_restore || start_gcm_aad || start_gcm_tag) begin + // We don't have work for the AES cipher core but for the GHASH block only. Load the + // input data into the previous input data register such that it can be loaded into + // the GHASH block in unmasked form. + data_in_prev_sel_o = DIP_DATA_IN; + data_in_prev_we_o = 1'b1; + + // Advance to the loading state where the input data is marked as used. + doing_gcm_restore_d = start_gcm_restore; + doing_gcm_aad_d = start_gcm_aad; + doing_gcm_tag_d = start_gcm_tag; + start_we = 1'b1; + aes_ctrl_ns = CTRL_LOAD; + + end else if (start_gcm_save) begin + // We don't have work for the AES cipher core but for the GHASH block only. Update the + // PRNG (to clear the internal state after saving it) and advance. + prng_update_o = 1'b1; + doing_gcm_save_d = 1'b1; + start_we = 1'b1; + aes_ctrl_ns = CTRL_GHASH_READY; + + end else if (start) begin + // Signal that we want to start encryption/decryption. + cipher_crypt_o = 1'b1; + + // Signal if the cipher core shall reseed the masking PRNG. + cipher_prng_reseed_o = block_ctr_expr; + + // We got a new initial key, but want to do decryption. The cipher core must first + // generate the start key for decryption. + cipher_dec_key_gen_o = (cipher_op_i == CIPH_INV) ? key_init_new : 1'b0; + + // Previous input data register control + data_in_prev_sel_o = doing_cbc_dec ? DIP_DATA_IN : + doing_cfb_enc ? DIP_DATA_IN : + doing_cfb_dec ? DIP_DATA_IN : + doing_ofb ? DIP_DATA_IN : + doing_ctr ? DIP_DATA_IN : + doing_gcm_txt ? DIP_DATA_IN : DIP_CLEAR; + data_in_prev_we_o = doing_cbc_dec | + doing_cfb_enc | + doing_cfb_dec | + doing_ofb | + doing_ctr | + doing_gcm_txt; + + // State input mux control + state_in_sel_o = doing_cfb_enc ? SI_ZERO : + doing_cfb_dec ? SI_ZERO : + doing_ofb ? SI_ZERO : + doing_ctr ? SI_ZERO : + doing_gcm_hsk ? SI_ZERO : + doing_gcm_s ? SI_ZERO : + doing_gcm_txt ? SI_ZERO : SI_DATA; + + // State input addition mux control + add_state_in_sel_o = doing_cbc_enc ? ADD_SI_IV : + doing_cfb_enc ? ADD_SI_IV : + doing_cfb_dec ? ADD_SI_IV : + doing_ofb ? ADD_SI_IV : + doing_ctr ? ADD_SI_IV : + doing_gcm_s ? ADD_SI_IV : + doing_gcm_txt ? ADD_SI_IV : ADD_SI_ZERO; + + // We have work for the cipher core, perform handshake. + cipher_in_valid_o = 1'b1; + if (cipher_in_ready_i) begin + // Do not yet clear a possible start trigger if we are just starting the generation of + // the start key for decryption. + start_we = ~cipher_dec_key_gen_o; + aes_ctrl_ns = CTRL_LOAD; + end + end + end + + CTRL_LOAD: begin + // Signal that we have used the current key, IV, data input to register status tracking. + key_init_load = cipher_dec_key_gen_i; // This key is no longer "new", but still clean. + key_init_arm = ~cipher_dec_key_gen_i; // The key is still "new", prevent partial updates. + iv_load = ~cipher_dec_key_gen_i & (doing_cbc_enc | + doing_cbc_dec | + doing_cfb_enc | + doing_cfb_dec | + doing_ofb | + doing_ctr | + doing_gcm_hsk | + doing_gcm_s | + doing_gcm_txt); + data_in_load = ~cipher_dec_key_gen_i; + + // Trigger counter increment. + ctr_incr_o = doing_ctr | doing_gcm_hsk | doing_gcm_s | doing_gcm_txt; + + // Unless we are just generating the start key for decryption, we must update the PRNG. + // Fresh pseudo-random data is used to: + // - clear the state in the final cipher round, + // - clear any other registers in the CLEAR_I/CO states. + prng_update_o = !cipher_dec_key_gen_i; + + // Unless we are just generating the start key for decryption, we may need to interface + // the GHASH block as well + aes_ctrl_ns = !cipher_dec_key_gen_i ? CTRL_GHASH_READY : CTRL_FINISH; + end + + CTRL_GHASH_READY: begin + // IV control in case of ongoing encryption/decryption + // - CTR: IV registers are updated by counter during cipher operation + iv_sel_o = doing_ctr || + doing_gcm_hsk || + doing_gcm_s || + doing_gcm_txt ? IV_CTR : IV_INPUT; + iv_we_o = doing_ctr || + doing_gcm_hsk || + doing_gcm_s || + doing_gcm_txt ? ctr_we_i : {NumSlicesCtr{1'b0}}; + + // Ongoing encryption/decryption operations have the highest priority. The clear triggers + // might for example have become asserted after the handshake with the cipher core. + if (cipher_crypt_i) begin + if (doing_gcm_hsk || doing_gcm_s || doing_gcm_txt) begin + // We actually have some work for the GHASH block. Make sure it's ready before we move. + // We send the valid in a following clock cycle. Doing this check here, allows to + // decouple the valid from the ready. + if (ghash_in_ready_i) begin + aes_ctrl_ns = CTRL_FINISH; + end + end else begin + // We're not actually using the GHASH block and don't need to check it's status. + aes_ctrl_ns = CTRL_FINISH; + end + + end else if (doing_gcm_restore_q) begin + // Pass the previously saved GHASH state to the GHASH block. We're done after the input + // handshake. + ghash_in_valid_o = 1'b1; + if (ghash_in_ready_i) begin + doing_gcm_restore_d = 1'b0; + aes_ctrl_ns = CTRL_IDLE; + end + + end else if (doing_gcm_aad_q) begin + // Pass the AAD to the GHASH block. We're done after the input handshake. + ghash_in_valid_o = 1'b1; + if (ghash_in_ready_i) begin + doing_gcm_aad_d = 1'b0; + aes_ctrl_ns = CTRL_IDLE; + end + + end else if (doing_gcm_save_q) begin + // Perform the handshake with the GHASH block and then wait for the GHASH block to output + // the state. + ghash_in_valid_o = 1'b1; + if (ghash_in_ready_i) begin + aes_ctrl_ns = CTRL_FINISH; + end + + end else if (doing_gcm_tag_q) begin + // Pass the AAD and text length to the GHASH block and wait for the final authentication + // tag afterwards. + ghash_in_valid_o = 1'b1; + if (ghash_in_ready_i) begin + aes_ctrl_ns = CTRL_FINISH; + end + + end else if (key_iv_data_in_clear_i || data_out_clear_i || + cipher_key_clear_i || cipher_data_out_clear_i) begin + // We actually have some work for the GHASH block. Make sure it's ready before we move. + // We send the valid in a following clock cycle. Doing this check here, allows to + // decouple the valid from the ready. + if (ghash_in_ready_i) begin + aes_ctrl_ns = CTRL_CLEAR_I; + end + end else begin + // Another write to the trigger register must have overwritten the trigger bits that + // actually caused us to enter this state. Just return. + aes_ctrl_ns = CTRL_IDLE; + end + end + + CTRL_PRNG_RESEED: begin + // Request a reseed of the clearing PRNG. + prng_reseed_req_o = ~prng_reseed_done_q; + + if (!SecMasking) begin + if (prng_reseed_done_q) begin + // Clear the trigger and return. + prng_reseed_we = 1'b1; + prng_reseed_done_d = 1'b0; + aes_ctrl_ns = CTRL_IDLE; + end + + end else begin + // In case masking is used, we must also wait for the cipher core to reseed the internal + // masking PRNG. Perform handshake. + cipher_out_ready_o = prng_reseed_done_q; + if (cipher_out_ready_o && cipher_out_valid_i) begin + // Clear the trigger and return. + prng_reseed_we = 1'b1; + prng_reseed_done_d = 1'b0; + aes_ctrl_ns = CTRL_IDLE; + end + end + end + + CTRL_FINISH: begin + // Wait for cipher core to finish. + + if (cipher_dec_key_gen_i) begin + // We are ready. + cipher_out_ready_o = 1'b1; + if (cipher_out_valid_i) begin + block_ctr_decr = 1'b1; + aes_ctrl_ns = CTRL_IDLE; + end + end else if (doing_gcm_save_q || doing_gcm_tag_q) begin + // Handshake signals: We are ready once the output data registers can be written. Don't + // let data propagate in case of mux selector or sparsely encoded signals taking on + // invalid values. + ghash_out_ready_o = finish; + ghash_out_done = finish & ghash_out_valid_i & + ~mux_sel_err_i & ~sp_enc_err_i & ~cipher_op_err; + + // Signal if the GHASH block is stalled (because previous output has not yet been read). + stall = ~finish & ghash_out_valid_i; + stall_we = 1'b1; + + // Forward the GHASH output instead of the cipher core output. + data_out_sel_o = DATA_OUT_GHASH; + + // Proceed upon successful handshake. Mark hash subkey and s as not ready, the GHASH + // block clears those registers after the handshake. + if (ghash_out_done) begin + doing_gcm_save_d = 1'b0; + doing_gcm_tag_d = 1'b0; + hash_subkey_ready_d = 1'b0; + s_ready_d = 1'b0; + data_out_we_o = 1'b1; + aes_ctrl_ns = CTRL_IDLE; + end + + end else begin + // Handshake signals: We are ready once the output data registers can be written. Don't + // let data propagate in case of mux selector or sparsely encoded signals taking on + // invalid values. + cipher_out_ready_o = finish; + cipher_out_done = finish & cipher_out_valid_i & + ~mux_sel_err_i & ~sp_enc_err_i & ~cipher_op_err; + + // Signal if the cipher core is stalled (because previous output has not yet been read). + stall = ~finish & cipher_out_valid_i; + stall_we = 1'b1; + + // State out addition mux control + add_state_out_sel_o = doing_cbc_dec ? ADD_SO_IV : + doing_cfb_enc ? ADD_SO_DIP : + doing_cfb_dec ? ADD_SO_DIP : + doing_ofb ? ADD_SO_DIP : + doing_ctr ? ADD_SO_DIP : + doing_gcm_txt ? ADD_SO_DIP : ADD_SO_ZERO; + + // IV control + // - CBC/CFB/OFB: IV registers are only updated when cipher finishes. + // - CTR/GCM: IV registers are updated by counter during cipher operation. + // The same holds when we're computing the hash subkey for GCM. + iv_sel_o = doing_cbc_enc ? IV_DATA_OUT : + doing_cbc_dec ? IV_DATA_IN_PREV : + doing_cfb_enc ? IV_DATA_OUT : + doing_cfb_dec ? IV_DATA_IN_PREV : + doing_ofb ? IV_DATA_OUT_RAW : + doing_ctr ? IV_CTR : + doing_gcm_hsk ? IV_CTR : + doing_gcm_s ? IV_CTR : + doing_gcm_txt ? IV_CTR : IV_INPUT; + iv_we_o = doing_cbc_enc || + doing_cbc_dec || + doing_cfb_enc || + doing_cfb_dec || + doing_ofb ? {NumSlicesCtr{cipher_out_done}} : + doing_ctr ? ctr_we_i : + doing_gcm_hsk ? ctr_we_i : + doing_gcm_s ? ctr_we_i : + doing_gcm_txt ? ctr_we_i : {NumSlicesCtr{1'b0}}; + + // Arm the IV status tracker: After finishing, the IV registers can be written again + // by software. We need to make sure software does not partially update the IV. + iv_arm = (doing_cbc_enc | + doing_cbc_dec | + doing_cfb_enc | + doing_cfb_dec | + doing_ofb | + doing_ctr | + doing_gcm_hsk | + doing_gcm_s | + doing_gcm_txt) & cipher_out_done; + + // Proceed upon successful handshake. When initializing GHASH for GCM, don't write to the + // cipher output to the output data registers but forward it to the GHASH block and + // mark the hash subkey or S as ready. + if (cipher_out_done) begin + block_ctr_decr = 1'b1; + data_out_we_o = doing_gcm_hsk | + doing_gcm_s ? 1'b0 : 1'b1; + ghash_in_valid_o = doing_gcm_hsk | + doing_gcm_s | + doing_gcm_txt ? 1'b1 : 1'b0; + hash_subkey_ready_d = doing_gcm_hsk ? 1'b1 : hash_subkey_ready_q; + s_ready_d = doing_gcm_s ? 1'b1 : s_ready_q; + aes_ctrl_ns = CTRL_IDLE; + end + end + end + + CTRL_CLEAR_I: begin + // Clear input registers such as Initial Key, IV and input data registers. + if (key_iv_data_in_clear_i) begin + // Initial Key + key_init_sel_o = KEY_INIT_CLEAR; + key_init_we_o = {NumSharesKey * NumRegsKey{1'b1}}; + key_init_clear = 1'b1; + + // IV + iv_sel_o = IV_CLEAR; + iv_we_o = {NumSlicesCtr{1'b1}}; + iv_clear = 1'b1; + + // Input data + data_in_we_o = 1'b1; + data_in_prev_sel_o = DIP_CLEAR; + data_in_prev_we_o = 1'b1; + end + aes_ctrl_ns = CTRL_CLEAR_CO; + end + + CTRL_CLEAR_CO: begin + // Wait for cipher core to clear internal Full Key and Decryption Key registers and/or + // the state register and clear output data registers afterwards. + + // Perform handshake with cipher core. + cipher_out_ready_o = 1'b1; + if (cipher_out_valid_i) begin + + // Full Key and Decryption Key registers are cleared by the cipher core. + // key_iv_data_in_clear_i is acknowledged by the cipher core with cipher_key_clear_i. + if (cipher_key_clear_i) begin + // Clear the trigger bit. + key_iv_data_in_clear_we = 1'b1; + + // The GHASH block can now clear it's internal registers. + ghash_in_valid_o = 1'b1; + end + + // To clear the output data registers, we re-use the muxing resources of the cipher core. + // data_out_clear_i is acknowledged by the cipher core with cipher_data_out_clear_i. + if (cipher_data_out_clear_i) begin + // Clear output data and the trigger bit. Don't release data from cipher core in case + // of mux selector or sparsely encoded signals taking on invalid values. + data_out_we_o = ~mux_sel_err_i & ~sp_enc_err_i & ~cipher_op_err; + data_out_clear_we = 1'b1; + end + + aes_ctrl_ns = CTRL_IDLE; + end + end + + CTRL_ERROR: begin + // SEC_CM: MAIN.FSM.GLOBAL_ESC + // SEC_CM: MAIN.FSM.LOCAL_ESC + // Terminal error state + alert_o = 1'b1; + end + + // We should never get here. If we do (e.g. via a malicious glitch), error out immediately. + default: begin + aes_ctrl_ns = CTRL_ERROR; + alert_o = 1'b1; + end + endcase + + // Unconditionally jump into the terminal error state in case a mux selector or a sparsely + // encoded signal becomes invalid, or if the life cycle controller triggers an escalation. + if (mux_sel_err_i || sp_enc_err_i || cipher_op_err || + lc_ctrl_pkg::lc_tx_test_true_loose(lc_escalate_en_i)) begin + aes_ctrl_ns = CTRL_ERROR; + end + end + + // SEC_CM: MAIN.FSM.SPARSE + `CALIPTRA_PRIM_FLOP_SPARSE_FSM(u_state_regs, aes_ctrl_ns, aes_ctrl_cs, aes_ctrl_e, CTRL_IDLE) + + always_ff @(posedge clk_i or negedge rst_ni) begin : reg_fsm + if (!rst_ni) begin + prng_reseed_done_q <= 1'b0; + end else begin + prng_reseed_done_q <= prng_reseed_done_d; + end + end + + if (AESGCMEnable) begin : gen_reg_fsm_gcm + always_ff @(posedge clk_i or negedge rst_ni) begin : reg_fsm_gcm + if (!rst_ni) begin + hash_subkey_ready_q <= 1'b0; + s_ready_q <= 1'b0; + doing_gcm_restore_q <= 1'b0; + doing_gcm_aad_q <= 1'b0; + doing_gcm_save_q <= 1'b0; + doing_gcm_tag_q <= 1'b0; + end else begin + hash_subkey_ready_q <= hash_subkey_ready_d; + s_ready_q <= s_ready_d; + doing_gcm_restore_q <= doing_gcm_restore_d; + doing_gcm_aad_q <= doing_gcm_aad_d; + doing_gcm_save_q <= doing_gcm_save_d; + doing_gcm_tag_q <= doing_gcm_tag_d; + end + end + end else begin : gen_no_reg_fsm_gcm + // GCM is simply not supported. + assign hash_subkey_ready_q = 1'b0; + assign s_ready_q = 1'b0; + assign doing_gcm_restore_q = 1'b0; + assign doing_gcm_aad_q = 1'b0; + assign doing_gcm_save_q = 1'b0; + assign doing_gcm_tag_q = 1'b0; + + // Tie-off unused signals. + logic unused_gcm_d; + assign unused_gcm_d = ^{hash_subkey_ready_d, + s_ready_d, + doing_gcm_restore_d, + doing_gcm_aad_d, + doing_gcm_save_d, + doing_gcm_tag_d}; + end + + ///////////////////// + // Status Tracking // + ///////////////////// + + // We only take a new sideload key if sideload is enabled, if the provided sideload key is marked + // as valid, and after the control register has been written for the second time. After that + // point we don't update the key anymore, as we don't have a notion of when it actually changes. + // This would be required to trigger decryption key generation for ECB/CBC decryption. + // To update the sideload key, software has to: + // 1) wait unitl AES is idle, + // 2) wait for the key manager to provide the new key, + // 3) start a new message by writing the control register and providing the IV (if needed). + assign key_sideload = sideload_i & key_sideload_valid_i & ctrl_we_q & ~ctrl_phase_i; + + // We only use clean initial keys. Either software/counter has updated + // - all initial key registers, or + // - none of the initial key registers but the registers were updated in the past. + aes_reg_status #( + .Width ( $bits(key_init_we_o) ) + ) u_reg_status_key_init ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .we_i ( key_init_we_o ), + .use_i ( key_init_load ), + .clear_i ( key_init_clear ), + .arm_i ( key_init_arm ), + .new_o ( key_init_new ), + .new_pulse_o ( key_init_new_pulse ), + .clean_o ( key_init_ready ) + ); + + // We only use clean and unused IVs. Either software/counter has updated + // - all IV registers, or + // - none of the IV registers but the registers were updated in the past + // and this particular IV has not yet been used. + aes_reg_status #( + .Width ( $bits(iv_we_o) ) + ) u_reg_status_iv ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .we_i ( iv_we_o ), + .use_i ( iv_load ), + .clear_i ( iv_clear ), + .arm_i ( iv_arm ), + .new_o ( iv_ready ), + .new_pulse_o ( ), + .clean_o ( ) + ); + + // Input and output data register status tracking detects if: + // - A complete new data input block is available, and + // - An output data block has been read completely. + // The status tracking needs to be cleared upon writes to the control register. The clearing is + // applied one cycle later here to avoid zero-latency loops. This additional delay is not + // relevant as if we are about to start encryption/decryption, we anyway don't allow writes + // to the control register. + always_ff @(posedge clk_i or negedge rst_ni) begin : reg_ctrl_we + if (!rst_ni) begin + ctrl_we_q <= 1'b0; + end else begin + ctrl_we_q <= ctrl_we_o; + end + end + assign clear_in_out_status = ctrl_we_q; + + // Collect writes to data input registers. Cleared if: + // - data is loaded into cipher core, + // - clearing data input registers with random data (all data_in_qe_i bits high in next cycle), + // - clearing the status tracking. + assign data_in_new_d = data_in_load || &data_in_qe_i || clear_in_out_status ? '0 : + data_in_new_q | data_in_qe_i; + assign data_in_new = &data_in_new_d; + + // Collect reads of data output registers. data_out_read is high for one clock cycle only and + // clears output_valid_q unless new output is written in the exact same cycle. Cleared if: + // - clearing data ouput registers with random data, + // - clearing the status tracking. + assign data_out_read_d = &data_out_read_q || clear_in_out_status ? '0 : + data_out_read_q | data_out_re_i; + assign data_out_read = &data_out_read_d; + + always_ff @(posedge clk_i or negedge rst_ni) begin : reg_edge_detection + if (!rst_ni) begin + data_in_new_q <= '0; + data_out_read_q <= '0; + end else begin + data_in_new_q <= data_in_new_d; + data_out_read_q <= data_out_read_d; + end + end + + // Status register bits for data input and output + // Cleared to 1 if: + // - data is loaded into cipher core, + // - clearing data input registers with random data, + // - clearing the status tracking. + assign input_ready = ~data_in_new; + assign input_ready_we = data_in_new | data_in_load | data_in_we_o | clear_in_out_status; + + // Cleared if: + // - all data output registers have been read (unless new output is written in the same cycle), + // - clearing data ouput registers with random data, + // - clearing the status tracking. + assign output_valid = data_out_we_o & ~data_out_clear_we; + assign output_valid_we = data_out_we_o | data_out_read | data_out_clear_we | + clear_in_out_status; + + always_ff @(posedge clk_i or negedge rst_ni) begin : reg_output_valid + if (!rst_ni) begin + output_valid_q <= '0; + end else if (output_valid_we) begin + output_valid_q <= output_valid; + end + end + + // Output lost status register bit + // Cleared when updating the Control Register. Set when overwriting previous output data that has + // not yet been read. + assign output_lost = ctrl_we_o ? 1'b0 : + output_lost_i ? 1'b1 : output_valid_q & ~data_out_read; + assign output_lost_we = ctrl_we_o | data_out_we_o; + + ///////////////////////// + // GCM Status Tracking // + ///////////////////////// + + // Clear GCM-specific status tracking if the GCM phase is set to GCM_INIT after a second write to + // the shadowed GCM control register + assign gcm_clear = (gcm_phase_i == GCM_INIT) & ctrl_gcm_we_q & ~ctrl_gcm_phase_i; + + if (AESGCMEnable) begin : gen_reg_ctrl_gcm_we + always_ff @(posedge clk_i or negedge rst_ni) begin : reg_ctrl_gcm_we + if (!rst_ni) begin + ctrl_gcm_we_q <= 1'b0; + end else begin + ctrl_gcm_we_q <= ctrl_gcm_we_o; + end + end + end else begin : gen_no_reg_ctrl_gcm_we + assign ctrl_gcm_we_q = 1'b1; + end + + // Signal when the GCM initialization is done. + assign gcm_init_done_o = hash_subkey_ready_q & s_ready_q; + + // Should fatal alerts clear the status and trigger register? + assign clear_on_fatal = ClearStatusOnFatalAlert ? alert_fatal_i : 1'b0; + + ///////////////////// + // Status Register // + ///////////////////// + assign idle_o = clear_on_fatal ? 1'b0 : idle; + assign idle_we_o = clear_on_fatal ? 1'b1 : idle_we; + assign stall_o = clear_on_fatal ? 1'b0 : stall; + assign stall_we_o = clear_on_fatal ? 1'b1 : stall_we; + assign output_lost_o = clear_on_fatal ? 1'b0 : output_lost; + assign output_lost_we_o = clear_on_fatal ? 1'b1 : output_lost_we; + assign output_valid_o = clear_on_fatal ? 1'b0 : output_valid; + assign output_valid_we_o = clear_on_fatal ? 1'b1 : output_valid_we; + assign input_ready_o = clear_on_fatal ? 1'b0 : input_ready; + assign input_ready_we_o = clear_on_fatal ? 1'b1 : input_ready_we; + + ////////////////////// + // Trigger Register // + ////////////////////// + // Most triggers are only ever cleared by control. Fatal alerts clear all bits in the trigger + // register. + assign start_we_o = clear_on_fatal ? 1'b1 : start_we; + assign key_iv_data_in_clear_we_o = clear_on_fatal ? 1'b1 : key_iv_data_in_clear_we; + assign data_out_clear_we_o = clear_on_fatal ? 1'b1 : data_out_clear_we; + + // If configured, trigger the reseeding of the PRNGs used for clearing and masking purposes after + // the key has been updated. + assign prng_reseed_o = clear_on_fatal ? 1'b0 : + key_init_new_pulse ? 1'b1 : 1'b0; + assign prng_reseed_we_o = clear_on_fatal ? 1'b1 : + key_init_new_pulse ? key_touch_forces_reseed_i : prng_reseed_we; + + //////////////////////////// + // PRNG Reseeding Counter // + //////////////////////////// + // Count the number of blocks since the start of the message to determine when the masking PRNG + // inside the cipher core needs to be reseeded. + if (SecMasking) begin : gen_block_ctr + logic block_ctr_set; + logic [BlockCtrWidth-1:0] block_ctr_d, block_ctr_q; + logic [BlockCtrWidth-1:0] block_ctr_set_val, block_ctr_decr_val; + + assign block_ctr_expr = block_ctr_q == '0; + assign block_ctr_set = ctrl_we_q | (block_ctr_decr & (block_ctr_expr | cipher_prng_reseed_i)); + + assign block_ctr_set_val = prng_reseed_rate_i == PER_1 ? '0 : + prng_reseed_rate_i == PER_64 ? BlockCtrWidth'(63) : + prng_reseed_rate_i == PER_8K ? BlockCtrWidth'(8191) : '0; + + assign block_ctr_decr_val = block_ctr_q - BlockCtrWidth'(1); + + assign block_ctr_d = block_ctr_set ? block_ctr_set_val : + block_ctr_decr ? block_ctr_decr_val : block_ctr_q; + + always_ff @(posedge clk_i or negedge rst_ni) begin : reg_block_ctr + if (!rst_ni) begin + block_ctr_q <= '0; + end else begin + block_ctr_q <= block_ctr_d; + end + end + + end else begin : gen_no_block_ctr + assign block_ctr_expr = 1'b0; + + // Tie off unused signals. + logic unused_block_ctr_decr; + prs_rate_e unused_prng_reseed_rate; + logic unused_cipher_prng_reseed; + assign unused_block_ctr_decr = block_ctr_decr; + assign unused_prng_reseed_rate = prng_reseed_rate_i; + assign unused_cipher_prng_reseed = cipher_prng_reseed_i; + end + + //////////////// + // Assertions // + //////////////// + + // Create a lint error to reduce the risk of accidentally disabling the masking. + `CALIPTRA_ASSERT_STATIC_LINT_ERROR(AesControlFsmSecMaskingNonDefault, SecMasking == 1) + + // Selectors must be known/valid + `CALIPTRA_ASSERT(AesModeValid, !ctrl_err_storage_i |-> mode_i inside { + AES_ECB, + AES_CBC, + AES_CFB, + AES_OFB, + AES_CTR, + AES_GCM, + AES_NONE + }) + `CALIPTRA_ASSERT(AesOpValid, !ctrl_err_storage_i |-> op_i inside { + AES_ENC, + AES_DEC + }) + `CALIPTRA_ASSERT(AesCiphOpValid, !cipher_op_err |-> cipher_op_i inside { + CIPH_FWD, + CIPH_INV + }) + `CALIPTRA_ASSERT(AesControlStateValid, !alert_o |-> aes_ctrl_cs inside { + CTRL_IDLE, + CTRL_LOAD, + CTRL_GHASH_READY, + CTRL_PRNG_RESEED, + CTRL_FINISH, + CTRL_CLEAR_I, + CTRL_CLEAR_CO + }) + + // Check parameters + `CALIPTRA_ASSERT_INIT(AesNumSlicesCtr, NumSlicesCtr == 8) + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/aes_control_fsm_n.sv b/designs/Caliptra/src/caliptra-rtl/aes_control_fsm_n.sv new file mode 100644 index 0000000..f62e4f1 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/aes_control_fsm_n.sv @@ -0,0 +1,638 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// AES main control FSM +// +// This module contains the main control FSM handling the interplay of input/output registers and +// the AES cipher core. This version operates on and produces the negated values of important +// control signals. This is achieved by: +// - instantiating the regular main control FSM operating on and producing the positive values of +// these signals, and +// - inverting these signals between the regular FSM and the caliptra_prim_buf synthesis barriers. +// Synthesis tools will then push the inverters into the actual FSM. + +`include "caliptra_prim_assert.sv" + +module aes_control_fsm_n + import aes_pkg::*; + import aes_reg_pkg::*; +#( + parameter bit AESGCMEnable = 0, + parameter bit SecMasking = 0 +) ( + input logic clk_i, + input logic rst_ni, + + // Main control signals + input logic ctrl_qe_i, + output logic ctrl_we_o, + input logic ctrl_phase_i, + input logic ctrl_err_storage_i, + input aes_op_e op_i, + input aes_mode_e mode_i, + input ciph_op_e cipher_op_i, + input logic sideload_i, + input prs_rate_e prng_reseed_rate_i, + input logic manual_operation_i, + input logic key_touch_forces_reseed_i, + input logic ctrl_gcm_qe_i, + output logic ctrl_gcm_we_o, + input logic ctrl_gcm_phase_i, + output logic gcm_init_done_o, + input gcm_phase_e gcm_phase_i, + input logic start_i, + input logic key_iv_data_in_clear_i, + input logic data_out_clear_i, + input logic prng_reseed_i, + input logic mux_sel_err_i, + input logic sp_enc_err_i, + input lc_ctrl_pkg::lc_tx_t lc_escalate_en_i, + input logic alert_fatal_i, + output logic alert_o, + + // I/O register read/write enables + input logic key_sideload_valid_i, + input logic [NumSharesKey-1:0][NumRegsKey-1:0] key_init_qe_i, + input logic [NumRegsIv-1:0] iv_qe_i, + input logic [NumRegsData-1:0] data_in_qe_i, + input logic [NumRegsData-1:0] data_out_re_i, + output logic data_in_we_o, + output data_out_sel_e data_out_sel_o, + output logic data_out_we_no, // Sparsify + + // Previous input data register + output dip_sel_e data_in_prev_sel_o, + output logic data_in_prev_we_no, // Sparsify + + // Cipher I/O muxes + output si_sel_e state_in_sel_o, + output add_si_sel_e add_state_in_sel_o, + output add_so_sel_e add_state_out_sel_o, + + // Counter + output logic ctr_inc32_no, // Sparsify + output logic ctr_incr_no, // Sparsify + input logic ctr_ready_ni, // Sparsify + input logic [NumSlicesCtr-1:0] ctr_we_ni, // Sparsify + + // Cipher core control and sync + output logic cipher_in_valid_no, // Sparsify + input logic cipher_in_ready_ni, // Sparsify + input logic cipher_out_valid_ni, // Sparsify + output logic cipher_out_ready_no, // Sparsify + output logic cipher_crypt_no, // Sparsify + input logic cipher_crypt_ni, // Sparsify + output logic cipher_dec_key_gen_no, // Sparsify + input logic cipher_dec_key_gen_ni, // Sparsify + output logic cipher_prng_reseed_o, + input logic cipher_prng_reseed_i, + output logic cipher_key_clear_o, + input logic cipher_key_clear_i, + output logic cipher_data_out_clear_o, + input logic cipher_data_out_clear_i, + + // GHASH control and sync + output logic ghash_in_valid_no, // Sparsify + input logic ghash_in_ready_ni, // Sparsify + input logic ghash_out_valid_ni, // Sparsify + output logic ghash_out_ready_no, // Sparsify + output logic ghash_load_hash_subkey_no, // Sparsify + + // Initial key registers + output key_init_sel_e key_init_sel_o, + output logic [NumSharesKey-1:0][NumRegsKey-1:0] key_init_we_no, // Sparsify + + // IV registers + output iv_sel_e iv_sel_o, + output logic [NumSlicesCtr-1:0] iv_we_no, // Sparsify + + // Pseudo-random number generator interface + output logic prng_update_o, + output logic prng_reseed_req_o, + input logic prng_reseed_ack_i, + + // Trigger register + output logic start_we_o, + output logic key_iv_data_in_clear_we_o, + output logic data_out_clear_we_o, + output logic prng_reseed_o, + output logic prng_reseed_we_o, + + // Status register + output logic idle_o, + output logic idle_we_o, + output logic stall_o, + output logic stall_we_o, + input logic output_lost_i, + output logic output_lost_o, + output logic output_lost_we_o, + output logic output_valid_o, + output logic output_valid_we_o, + output logic input_ready_o, + output logic input_ready_we_o +); + + ///////////////////// + // Input Buffering // + ///////////////////// + + localparam int NumInBufBits = $bits({ + ctrl_qe_i, + ctrl_phase_i, + ctrl_err_storage_i, + op_i, + mode_i, + cipher_op_i, + sideload_i, + prng_reseed_rate_i, + manual_operation_i, + key_touch_forces_reseed_i, + ctrl_gcm_qe_i, + ctrl_gcm_phase_i, + gcm_phase_i, + start_i, + key_iv_data_in_clear_i, + data_out_clear_i, + prng_reseed_i, + mux_sel_err_i, + sp_enc_err_i, + lc_escalate_en_i, + alert_fatal_i, + key_sideload_valid_i, + key_init_qe_i, + iv_qe_i, + data_in_qe_i, + data_out_re_i, + ctr_ready_ni, + ctr_we_ni, + cipher_in_ready_ni, + cipher_out_valid_ni, + cipher_crypt_ni, + cipher_dec_key_gen_ni, + cipher_prng_reseed_i, + cipher_key_clear_i, + cipher_data_out_clear_i, + ghash_in_ready_ni, + ghash_out_valid_ni, + prng_reseed_ack_i, + output_lost_i + }); + + logic [NumInBufBits-1:0] in, in_buf; + + assign in = { + ctrl_qe_i, + ctrl_phase_i, + ctrl_err_storage_i, + op_i, + mode_i, + cipher_op_i, + sideload_i, + prng_reseed_rate_i, + manual_operation_i, + key_touch_forces_reseed_i, + ctrl_gcm_qe_i, + ctrl_gcm_phase_i, + gcm_phase_i, + start_i, + key_iv_data_in_clear_i, + data_out_clear_i, + prng_reseed_i, + mux_sel_err_i, + sp_enc_err_i, + lc_escalate_en_i, + alert_fatal_i, + key_sideload_valid_i, + key_init_qe_i, + iv_qe_i, + data_in_qe_i, + data_out_re_i, + ctr_ready_ni, + ctr_we_ni, + cipher_in_ready_ni, + cipher_out_valid_ni, + cipher_crypt_ni, + cipher_dec_key_gen_ni, + cipher_prng_reseed_i, + cipher_key_clear_i, + cipher_data_out_clear_i, + ghash_in_ready_ni, + ghash_out_valid_ni, + prng_reseed_ack_i, + output_lost_i + }; + + // This primitive is used to place a size-only constraint on the + // buffers to act as a synthesis optimization barrier. + caliptra_prim_buf #( + .Width(NumInBufBits) + ) u_caliptra_prim_buf_in ( + .in_i(in), + .out_o(in_buf) + ); + + logic ctrl_qe; + logic ctrl_phase; + logic ctrl_err_storage; + aes_op_e op; + aes_mode_e mode; + ciph_op_e cipher_op; + logic [$bits(cipher_op)-1:0] cipher_op_raw; + logic sideload; + prs_rate_e prng_reseed_rate; + logic manual_operation; + logic key_touch_forces_reseed; + logic ctrl_gcm_qe; + logic ctrl_gcm_phase; + gcm_phase_e gcm_phase; + logic [$bits(gcm_phase)-1:0] gcm_phase_raw; + logic start; + logic key_iv_data_in_clear; + logic data_out_clear; + logic prng_reseed_in_buf; + logic mux_sel_err; + logic sp_enc_err; + lc_ctrl_pkg::lc_tx_t lc_escalate_en; + logic alert_fatal; + logic key_sideload_valid; + logic [NumSharesKey-1:0][NumRegsKey-1:0] key_init_qe; + logic [NumRegsIv-1:0] iv_qe; + logic [NumRegsData-1:0] data_in_qe; + logic [NumRegsData-1:0] data_out_re; + logic ctr_ready_n; + logic [NumSlicesCtr-1:0] ctr_we_n; + logic cipher_in_ready_n; + logic cipher_out_valid_n; + logic cipher_crypt_in_buf_n; + logic cipher_dec_key_gen_in_buf_n; + logic cipher_prng_reseed_in_buf; + logic cipher_key_clear_in_buf; + logic cipher_data_out_clear_in_buf; + logic ghash_in_ready_n; + logic ghash_out_valid_n; + logic prng_reseed_ack; + logic output_lost_in_buf; + + assign {ctrl_qe, + ctrl_phase, + ctrl_err_storage, + op, + mode, + cipher_op_raw, + sideload, + prng_reseed_rate, + manual_operation, + key_touch_forces_reseed, + ctrl_gcm_qe, + ctrl_gcm_phase, + gcm_phase_raw, + start, + key_iv_data_in_clear, + data_out_clear, + prng_reseed_in_buf, + mux_sel_err, + sp_enc_err, + lc_escalate_en, + alert_fatal, + key_sideload_valid, + key_init_qe, + iv_qe, + data_in_qe, + data_out_re, + ctr_ready_n, + ctr_we_n, + cipher_in_ready_n, + cipher_out_valid_n, + cipher_crypt_in_buf_n, + cipher_dec_key_gen_in_buf_n, + cipher_prng_reseed_in_buf, + cipher_key_clear_in_buf, + cipher_data_out_clear_in_buf, + ghash_in_ready_n, + ghash_out_valid_n, + prng_reseed_ack, + output_lost_in_buf} = in_buf; + + assign cipher_op = ciph_op_e'(cipher_op_raw); + assign gcm_phase = gcm_phase_e'(gcm_phase_raw); + + // Intermediate output signals + logic ctrl_we; + logic ctrl_gcm_we; + logic gcm_init_done; + logic alert; + logic data_in_we; + data_out_sel_e data_out_sel; + logic data_out_we; + dip_sel_e data_in_prev_sel; + logic data_in_prev_we; + si_sel_e state_in_sel; + add_si_sel_e add_state_in_sel; + add_so_sel_e add_state_out_sel; + logic ctr_inc32; + logic ctr_incr; + logic cipher_in_valid; + logic cipher_out_ready; + logic cipher_crypt_out_buf; + logic cipher_dec_key_gen_out_buf; + logic cipher_prng_reseed_out_buf; + logic cipher_key_clear_out_buf; + logic cipher_data_out_clear_out_buf; + logic ghash_in_valid; + logic ghash_out_ready; + logic ghash_load_hash_subkey; + key_init_sel_e key_init_sel; + logic [NumSharesKey-1:0][NumRegsKey-1:0] key_init_we; + iv_sel_e iv_sel; + logic [NumSlicesCtr-1:0] iv_we; + logic prng_update; + logic prng_reseed_req; + logic start_we; + logic key_iv_data_in_clear_we; + logic data_out_clear_we; + logic prng_reseed_out_buf; + logic prng_reseed_we; + logic idle; + logic idle_we; + logic stall; + logic stall_we; + logic output_lost_out_buf; + logic output_lost_we; + logic output_valid; + logic output_valid_we; + logic input_ready; + logic input_ready_we; + + ///////////////// + // Regular FSM // + ///////////////// + + // The regular FSM operates on and produces the positive values of important control signals. + // Invert *_n input signals here to get the positive values for the regular FSM. To obtain the + // negated outputs, important output signals are inverted further below. Thanks to the caliptra_prim_buf + // synthesis optimization barriers, tools will push the inverters into the regular FSM. + aes_control_fsm #( + .AESGCMEnable ( AESGCMEnable ), + .SecMasking ( SecMasking ) + ) u_aes_control_fsm ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + + .ctrl_qe_i ( ctrl_qe ), + .ctrl_we_o ( ctrl_we ), + .ctrl_phase_i ( ctrl_phase ), + .ctrl_err_storage_i ( ctrl_err_storage ), + .op_i ( op ), + .mode_i ( mode ), + .cipher_op_i ( cipher_op ), + .sideload_i ( sideload ), + .prng_reseed_rate_i ( prng_reseed_rate ), + .manual_operation_i ( manual_operation ), + .key_touch_forces_reseed_i ( key_touch_forces_reseed ), + .ctrl_gcm_qe_i ( ctrl_gcm_qe ), + .ctrl_gcm_we_o ( ctrl_gcm_we ), + .ctrl_gcm_phase_i ( ctrl_gcm_phase ), + .gcm_init_done_o ( gcm_init_done ), + .gcm_phase_i ( gcm_phase ), + .start_i ( start ), + .key_iv_data_in_clear_i ( key_iv_data_in_clear ), + .data_out_clear_i ( data_out_clear ), + .prng_reseed_i ( prng_reseed_in_buf ), + .mux_sel_err_i ( mux_sel_err ), + .sp_enc_err_i ( sp_enc_err ), + .lc_escalate_en_i ( lc_escalate_en ), + .alert_fatal_i ( alert_fatal ), + .alert_o ( alert ), + + .key_sideload_valid_i ( key_sideload_valid ), + .key_init_qe_i ( key_init_qe ), + .iv_qe_i ( iv_qe ), + .data_in_qe_i ( data_in_qe ), + .data_out_re_i ( data_out_re ), + .data_in_we_o ( data_in_we ), + .data_out_sel_o ( data_out_sel ), + .data_out_we_o ( data_out_we ), // Invert below for _n output. + + .data_in_prev_sel_o ( data_in_prev_sel ), + .data_in_prev_we_o ( data_in_prev_we ), // Invert below for _n output. + + .state_in_sel_o ( state_in_sel ), + .add_state_in_sel_o ( add_state_in_sel ), + .add_state_out_sel_o ( add_state_out_sel ), + + .ctr_inc32_o ( ctr_inc32 ), // Invert below for _n output. + .ctr_incr_o ( ctr_incr ), // Invert below for _n output. + .ctr_ready_i ( ~ctr_ready_n ), // Invert for regular FSM. + .ctr_we_i ( ~ctr_we_n ), // Invert for regular FSM. + + .cipher_in_valid_o ( cipher_in_valid ), // Invert below for _n output. + .cipher_in_ready_i ( ~cipher_in_ready_n ), // Invert for regular FSM. + .cipher_out_valid_i ( ~cipher_out_valid_n ), // Invert for regular FSM. + .cipher_out_ready_o ( cipher_out_ready ), // Invert below for _n output. + .cipher_crypt_o ( cipher_crypt_out_buf ), // Invert below for _n output. + .cipher_crypt_i ( ~cipher_crypt_in_buf_n ), // Invert for regular FSM. + .cipher_dec_key_gen_o ( cipher_dec_key_gen_out_buf ), // Invert below for _n output. + .cipher_dec_key_gen_i ( ~cipher_dec_key_gen_in_buf_n ), // Invert for regular FSM. + .cipher_prng_reseed_o ( cipher_prng_reseed_out_buf ), + .cipher_prng_reseed_i ( cipher_prng_reseed_in_buf ), + .cipher_key_clear_o ( cipher_key_clear_out_buf ), + .cipher_key_clear_i ( cipher_key_clear_in_buf ), + .cipher_data_out_clear_o ( cipher_data_out_clear_out_buf ), + .cipher_data_out_clear_i ( cipher_data_out_clear_in_buf ), + + .ghash_in_valid_o ( ghash_in_valid ), // Invert below for _n output. + .ghash_in_ready_i ( ~ghash_in_ready_n ), // Invert for regular FSM. + .ghash_out_valid_i ( ~ghash_out_valid_n ), // Invert for regular FSM. + .ghash_out_ready_o ( ghash_out_ready ), // Invert below for _n output. + .ghash_load_hash_subkey_o ( ghash_load_hash_subkey ), // Invert below for _n output. + + .key_init_sel_o ( key_init_sel ), + .key_init_we_o ( key_init_we ), // Invert below for _n output. + + .iv_sel_o ( iv_sel ), + .iv_we_o ( iv_we ), // Invert below for _n output. + + .prng_update_o ( prng_update ), + .prng_reseed_req_o ( prng_reseed_req ), + .prng_reseed_ack_i ( prng_reseed_ack ), + + .start_we_o ( start_we ), + .key_iv_data_in_clear_we_o ( key_iv_data_in_clear_we ), + .data_out_clear_we_o ( data_out_clear_we ), + .prng_reseed_o ( prng_reseed_out_buf ), + .prng_reseed_we_o ( prng_reseed_we ), + + .idle_o ( idle ), + .idle_we_o ( idle_we ), + .stall_o ( stall ), + .stall_we_o ( stall_we ), + .output_lost_i ( output_lost_in_buf ), + .output_lost_o ( output_lost_out_buf ), + .output_lost_we_o ( output_lost_we ), + .output_valid_o ( output_valid ), + .output_valid_we_o ( output_valid_we ), + .input_ready_o ( input_ready ), + .input_ready_we_o ( input_ready_we ) + ); + + ////////////////////// + // Output Buffering // + ////////////////////// + + localparam int NumOutBufBits = $bits({ + ctrl_we_o, + ctrl_gcm_we_o, + gcm_init_done_o, + alert_o, + data_in_we_o, + data_out_sel_o, + data_out_we_no, + data_in_prev_sel_o, + data_in_prev_we_no, + state_in_sel_o, + add_state_in_sel_o, + add_state_out_sel_o, + ctr_inc32_no, + ctr_incr_no, + cipher_in_valid_no, + cipher_out_ready_no, + cipher_crypt_no, + cipher_dec_key_gen_no, + cipher_prng_reseed_o, + cipher_key_clear_o, + cipher_data_out_clear_o, + ghash_in_valid_no, + ghash_out_ready_no, + ghash_load_hash_subkey_no, + key_init_sel_o, + key_init_we_no, + iv_sel_o, + iv_we_no, + prng_update_o, + prng_reseed_req_o, + start_we_o, + key_iv_data_in_clear_we_o, + data_out_clear_we_o, + prng_reseed_o, + prng_reseed_we_o, + idle_o, + idle_we_o, + stall_o, + stall_we_o, + output_lost_o, + output_lost_we_o, + output_valid_o, + output_valid_we_o, + input_ready_o, + input_ready_we_o + }); + + logic [NumOutBufBits-1:0] out, out_buf; + + // Important output control signals need to be inverted here. Synthesis tools will push the + // inverters back into the regular FSM. + assign out = { + ctrl_we, + ctrl_gcm_we, + gcm_init_done, + alert, + data_in_we, + data_out_sel, + ~data_out_we, + data_in_prev_sel, + ~data_in_prev_we, + state_in_sel, + add_state_in_sel, + add_state_out_sel, + ~ctr_inc32, + ~ctr_incr, + ~cipher_in_valid, + ~cipher_out_ready, + ~cipher_crypt_out_buf, + ~cipher_dec_key_gen_out_buf, + cipher_prng_reseed_out_buf, + cipher_key_clear_out_buf, + cipher_data_out_clear_out_buf, + ~ghash_in_valid, + ~ghash_out_ready, + ~ghash_load_hash_subkey, + key_init_sel, + ~key_init_we, + iv_sel, + ~iv_we, + prng_update, + prng_reseed_req, + start_we, + key_iv_data_in_clear_we, + data_out_clear_we, + prng_reseed_out_buf, + prng_reseed_we, + idle, + idle_we, + stall, + stall_we, + output_lost_out_buf, + output_lost_we, + output_valid, + output_valid_we, + input_ready, + input_ready_we + }; + + // This primitive is used to place a size-only constraint on the + // buffers to act as a synthesis optimization barrier. + caliptra_prim_buf #( + .Width(NumOutBufBits) + ) u_caliptra_prim_buf_out ( + .in_i(out), + .out_o(out_buf) + ); + + assign {ctrl_we_o, + ctrl_gcm_we_o, + gcm_init_done_o, + alert_o, + data_in_we_o, + data_out_sel_o, + data_out_we_no, + data_in_prev_sel_o, + data_in_prev_we_no, + state_in_sel_o, + add_state_in_sel_o, + add_state_out_sel_o, + ctr_inc32_no, + ctr_incr_no, + cipher_in_valid_no, + cipher_out_ready_no, + cipher_crypt_no, + cipher_dec_key_gen_no, + cipher_prng_reseed_o, + cipher_key_clear_o, + cipher_data_out_clear_o, + ghash_in_valid_no, + ghash_out_ready_no, + ghash_load_hash_subkey_no, + key_init_sel_o, + key_init_we_no, + iv_sel_o, + iv_we_no, + prng_update_o, + prng_reseed_req_o, + start_we_o, + key_iv_data_in_clear_we_o, + data_out_clear_we_o, + prng_reseed_o, + prng_reseed_we_o, + idle_o, + idle_we_o, + stall_o, + stall_we_o, + output_lost_o, + output_lost_we_o, + output_valid_o, + output_valid_we_o, + input_ready_o, + input_ready_we_o} = out_buf; + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/aes_control_fsm_p.sv b/designs/Caliptra/src/caliptra-rtl/aes_control_fsm_p.sv new file mode 100644 index 0000000..66957e5 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/aes_control_fsm_p.sv @@ -0,0 +1,628 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// AES main control FSM +// +// This module contains the main control FSM handling the interplay of input/output registers and +// the AES cipher core. This version operates on and produces the positive values of important +// control signals. + +`include "caliptra_prim_assert.sv" + +module aes_control_fsm_p + import aes_pkg::*; + import aes_reg_pkg::*; +#( + parameter bit AESGCMEnable = 0, + parameter bit SecMasking = 0 +) ( + input logic clk_i, + input logic rst_ni, + + // Main control signals + input logic ctrl_qe_i, + output logic ctrl_we_o, + input logic ctrl_phase_i, + input logic ctrl_err_storage_i, + input aes_op_e op_i, + input aes_mode_e mode_i, + input ciph_op_e cipher_op_i, + input logic sideload_i, + input prs_rate_e prng_reseed_rate_i, + input logic manual_operation_i, + input logic key_touch_forces_reseed_i, + input logic ctrl_gcm_qe_i, + output logic ctrl_gcm_we_o, + input logic ctrl_gcm_phase_i, + output logic gcm_init_done_o, + input gcm_phase_e gcm_phase_i, + input logic start_i, + input logic key_iv_data_in_clear_i, + input logic data_out_clear_i, + input logic prng_reseed_i, + input logic mux_sel_err_i, + input logic sp_enc_err_i, + input lc_ctrl_pkg::lc_tx_t lc_escalate_en_i, + input logic alert_fatal_i, + output logic alert_o, + + // I/O register read/write enables + input logic key_sideload_valid_i, + input logic [NumSharesKey-1:0][NumRegsKey-1:0] key_init_qe_i, + input logic [NumRegsIv-1:0] iv_qe_i, + input logic [NumRegsData-1:0] data_in_qe_i, + input logic [NumRegsData-1:0] data_out_re_i, + output logic data_in_we_o, + output data_out_sel_e data_out_sel_o, + output logic data_out_we_o, // Sparsify + + // Previous input data register + output dip_sel_e data_in_prev_sel_o, + output logic data_in_prev_we_o, // Sparsify + + // Cipher I/O muxes + output si_sel_e state_in_sel_o, + output add_si_sel_e add_state_in_sel_o, + output add_so_sel_e add_state_out_sel_o, + + // Counter + output logic ctr_inc32_o, // Sparsify + output logic ctr_incr_o, // Sparsify + input logic ctr_ready_i, // Sparsify + input logic [NumSlicesCtr-1:0] ctr_we_i, // Sparsify + + // Cipher core control and sync + output logic cipher_in_valid_o, // Sparsify + input logic cipher_in_ready_i, // Sparsify + input logic cipher_out_valid_i, // Sparsify + output logic cipher_out_ready_o, // Sparsify + output logic cipher_crypt_o, // Sparsify + input logic cipher_crypt_i, // Sparsify + output logic cipher_dec_key_gen_o, // Sparsify + input logic cipher_dec_key_gen_i, // Sparsify + output logic cipher_prng_reseed_o, + input logic cipher_prng_reseed_i, + output logic cipher_key_clear_o, + input logic cipher_key_clear_i, + output logic cipher_data_out_clear_o, + input logic cipher_data_out_clear_i, + + // GHASH control and sync + output logic ghash_in_valid_o, // Sparsify + input logic ghash_in_ready_i, // Sparsify + input logic ghash_out_valid_i, // Sparsify + output logic ghash_out_ready_o, // Sparsify + output logic ghash_load_hash_subkey_o, // Sparsify + + // Initial key registers + output key_init_sel_e key_init_sel_o, + output logic [NumSharesKey-1:0][NumRegsKey-1:0] key_init_we_o, // Sparsify + + // IV registers + output iv_sel_e iv_sel_o, + output logic [NumSlicesCtr-1:0] iv_we_o, // Sparsify + + // Pseudo-random number generator interface + output logic prng_update_o, + output logic prng_reseed_req_o, + input logic prng_reseed_ack_i, + + // Trigger register + output logic start_we_o, + output logic key_iv_data_in_clear_we_o, + output logic data_out_clear_we_o, + output logic prng_reseed_o, + output logic prng_reseed_we_o, + + // Status register + output logic idle_o, + output logic idle_we_o, + output logic stall_o, + output logic stall_we_o, + input logic output_lost_i, + output logic output_lost_o, + output logic output_lost_we_o, + output logic output_valid_o, + output logic output_valid_we_o, + output logic input_ready_o, + output logic input_ready_we_o +); + + ///////////////////// + // Input Buffering // + ///////////////////// + + localparam int NumInBufBits = $bits({ + ctrl_qe_i, + ctrl_phase_i, + ctrl_err_storage_i, + op_i, + mode_i, + cipher_op_i, + sideload_i, + prng_reseed_rate_i, + manual_operation_i, + key_touch_forces_reseed_i, + ctrl_gcm_qe_i, + ctrl_gcm_phase_i, + gcm_phase_i, + start_i, + key_iv_data_in_clear_i, + data_out_clear_i, + prng_reseed_i, + mux_sel_err_i, + sp_enc_err_i, + lc_escalate_en_i, + alert_fatal_i, + key_sideload_valid_i, + key_init_qe_i, + iv_qe_i, + data_in_qe_i, + data_out_re_i, + ctr_ready_i, + ctr_we_i, + cipher_in_ready_i, + cipher_out_valid_i, + cipher_crypt_i, + cipher_dec_key_gen_i, + cipher_prng_reseed_i, + cipher_key_clear_i, + cipher_data_out_clear_i, + ghash_in_ready_i, + ghash_out_valid_i, + prng_reseed_ack_i, + output_lost_i + }); + + logic [NumInBufBits-1:0] in, in_buf; + + assign in = { + ctrl_qe_i, + ctrl_phase_i, + ctrl_err_storage_i, + op_i, + mode_i, + cipher_op_i, + sideload_i, + prng_reseed_rate_i, + manual_operation_i, + key_touch_forces_reseed_i, + ctrl_gcm_qe_i, + ctrl_gcm_phase_i, + gcm_phase_i, + start_i, + key_iv_data_in_clear_i, + data_out_clear_i, + prng_reseed_i, + mux_sel_err_i, + sp_enc_err_i, + lc_escalate_en_i, + alert_fatal_i, + key_sideload_valid_i, + key_init_qe_i, + iv_qe_i, + data_in_qe_i, + data_out_re_i, + ctr_ready_i, + ctr_we_i, + cipher_in_ready_i, + cipher_out_valid_i, + cipher_crypt_i, + cipher_dec_key_gen_i, + cipher_prng_reseed_i, + cipher_key_clear_i, + cipher_data_out_clear_i, + ghash_in_ready_i, + ghash_out_valid_i, + prng_reseed_ack_i, + output_lost_i + }; + + // This primitive is used to place a size-only constraint on the + // buffers to act as a synthesis optimization barrier. + caliptra_prim_buf #( + .Width(NumInBufBits) + ) u_caliptra_prim_buf_in ( + .in_i(in), + .out_o(in_buf) + ); + + logic ctrl_qe; + logic ctrl_phase; + logic ctrl_err_storage; + aes_op_e op; + aes_mode_e mode; + ciph_op_e cipher_op; + logic [$bits(cipher_op)-1:0] cipher_op_raw; + logic sideload; + prs_rate_e prng_reseed_rate; + logic manual_operation; + logic key_touch_forces_reseed; + logic ctrl_gcm_qe; + logic ctrl_gcm_phase; + gcm_phase_e gcm_phase; + logic [$bits(gcm_phase)-1:0] gcm_phase_raw; + logic start; + logic key_iv_data_in_clear; + logic data_out_clear; + logic prng_reseed_in_buf; + logic mux_sel_err; + logic sp_enc_err; + lc_ctrl_pkg::lc_tx_t lc_escalate_en; + logic alert_fatal; + logic key_sideload_valid; + logic [NumSharesKey-1:0][NumRegsKey-1:0] key_init_qe; + logic [NumRegsIv-1:0] iv_qe; + logic [NumRegsData-1:0] data_in_qe; + logic [NumRegsData-1:0] data_out_re; + logic ctr_ready; + logic [NumSlicesCtr-1:0] ctr_we; + logic cipher_in_ready; + logic cipher_out_valid; + logic cipher_crypt_in_buf; + logic cipher_dec_key_gen_in_buf; + logic cipher_prng_reseed_in_buf; + logic cipher_key_clear_in_buf; + logic cipher_data_out_clear_in_buf; + logic ghash_in_ready; + logic ghash_out_valid; + logic prng_reseed_ack; + logic output_lost_in_buf; + + assign {ctrl_qe, + ctrl_phase, + ctrl_err_storage, + op, + mode, + cipher_op_raw, + sideload, + prng_reseed_rate, + manual_operation, + key_touch_forces_reseed, + ctrl_gcm_qe, + ctrl_gcm_phase, + gcm_phase_raw, + start, + key_iv_data_in_clear, + data_out_clear, + prng_reseed_in_buf, + mux_sel_err, + sp_enc_err, + lc_escalate_en, + alert_fatal, + key_sideload_valid, + key_init_qe, + iv_qe, + data_in_qe, + data_out_re, + ctr_ready, + ctr_we, + cipher_in_ready, + cipher_out_valid, + cipher_crypt_in_buf, + cipher_dec_key_gen_in_buf, + cipher_prng_reseed_in_buf, + cipher_key_clear_in_buf, + cipher_data_out_clear_in_buf, + ghash_in_ready, + ghash_out_valid, + prng_reseed_ack, + output_lost_in_buf} = in_buf; + + assign cipher_op = ciph_op_e'(cipher_op_raw); + assign gcm_phase = gcm_phase_e'(gcm_phase_raw); + + // Intermediate output signals + logic ctrl_we; + logic ctrl_gcm_we; + logic gcm_init_done; + logic alert; + logic data_in_we; + data_out_sel_e data_out_sel; + logic data_out_we; + dip_sel_e data_in_prev_sel; + logic data_in_prev_we; + si_sel_e state_in_sel; + add_si_sel_e add_state_in_sel; + add_so_sel_e add_state_out_sel; + logic ctr_inc32; + logic ctr_incr; + logic cipher_in_valid; + logic cipher_out_ready; + logic cipher_crypt_out_buf; + logic cipher_dec_key_gen_out_buf; + logic cipher_prng_reseed_out_buf; + logic cipher_key_clear_out_buf; + logic cipher_data_out_clear_out_buf; + logic ghash_in_valid; + logic ghash_out_ready; + logic ghash_load_hash_subkey; + key_init_sel_e key_init_sel; + logic [NumSharesKey-1:0][NumRegsKey-1:0] key_init_we; + iv_sel_e iv_sel; + logic [NumSlicesCtr-1:0] iv_we; + logic prng_update; + logic prng_reseed_req; + logic start_we; + logic key_iv_data_in_clear_we; + logic data_out_clear_we; + logic prng_reseed_out_buf; + logic prng_reseed_we; + logic idle; + logic idle_we; + logic stall; + logic stall_we; + logic output_lost_out_buf; + logic output_lost_we; + logic output_valid; + logic output_valid_we; + logic input_ready; + logic input_ready_we; + + ///////////////// + // Regular FSM // + ///////////////// + + aes_control_fsm #( + .AESGCMEnable ( AESGCMEnable ), + .SecMasking ( SecMasking ) + ) u_aes_control_fsm ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + + .ctrl_qe_i ( ctrl_qe ), + .ctrl_we_o ( ctrl_we ), + .ctrl_phase_i ( ctrl_phase ), + .ctrl_err_storage_i ( ctrl_err_storage ), + .op_i ( op ), + .mode_i ( mode ), + .cipher_op_i ( cipher_op ), + .sideload_i ( sideload ), + .prng_reseed_rate_i ( prng_reseed_rate ), + .manual_operation_i ( manual_operation ), + .key_touch_forces_reseed_i ( key_touch_forces_reseed ), + .ctrl_gcm_qe_i ( ctrl_gcm_qe ), + .ctrl_gcm_we_o ( ctrl_gcm_we ), + .ctrl_gcm_phase_i ( ctrl_gcm_phase ), + .gcm_init_done_o ( gcm_init_done ), + .gcm_phase_i ( gcm_phase ), + .start_i ( start ), + .key_iv_data_in_clear_i ( key_iv_data_in_clear ), + .data_out_clear_i ( data_out_clear ), + .prng_reseed_i ( prng_reseed_in_buf ), + .mux_sel_err_i ( mux_sel_err ), + .sp_enc_err_i ( sp_enc_err ), + .lc_escalate_en_i ( lc_escalate_en ), + .alert_fatal_i ( alert_fatal ), + .alert_o ( alert ), + + .key_sideload_valid_i ( key_sideload_valid ), + .key_init_qe_i ( key_init_qe ), + .iv_qe_i ( iv_qe ), + .data_in_qe_i ( data_in_qe ), + .data_out_re_i ( data_out_re ), + .data_in_we_o ( data_in_we ), + .data_out_sel_o ( data_out_sel ), + .data_out_we_o ( data_out_we ), + + .data_in_prev_sel_o ( data_in_prev_sel ), + .data_in_prev_we_o ( data_in_prev_we ), + + .state_in_sel_o ( state_in_sel ), + .add_state_in_sel_o ( add_state_in_sel ), + .add_state_out_sel_o ( add_state_out_sel ), + + .ctr_inc32_o ( ctr_inc32 ), + .ctr_incr_o ( ctr_incr ), + .ctr_ready_i ( ctr_ready ), + .ctr_we_i ( ctr_we ), + + .cipher_in_valid_o ( cipher_in_valid ), + .cipher_in_ready_i ( cipher_in_ready ), + .cipher_out_valid_i ( cipher_out_valid ), + .cipher_out_ready_o ( cipher_out_ready ), + .cipher_crypt_o ( cipher_crypt_out_buf ), + .cipher_crypt_i ( cipher_crypt_in_buf ), + .cipher_dec_key_gen_o ( cipher_dec_key_gen_out_buf ), + .cipher_dec_key_gen_i ( cipher_dec_key_gen_in_buf ), + .cipher_prng_reseed_o ( cipher_prng_reseed_out_buf ), + .cipher_prng_reseed_i ( cipher_prng_reseed_in_buf ), + .cipher_key_clear_o ( cipher_key_clear_out_buf ), + .cipher_key_clear_i ( cipher_key_clear_in_buf ), + .cipher_data_out_clear_o ( cipher_data_out_clear_out_buf ), + .cipher_data_out_clear_i ( cipher_data_out_clear_in_buf ), + + .ghash_in_valid_o ( ghash_in_valid ), + .ghash_in_ready_i ( ghash_in_ready ), + .ghash_out_valid_i ( ghash_out_valid ), + .ghash_out_ready_o ( ghash_out_ready ), + .ghash_load_hash_subkey_o ( ghash_load_hash_subkey ), + + .key_init_sel_o ( key_init_sel ), + .key_init_we_o ( key_init_we ), + + .iv_sel_o ( iv_sel ), + .iv_we_o ( iv_we ), + + .prng_update_o ( prng_update ), + .prng_reseed_req_o ( prng_reseed_req ), + .prng_reseed_ack_i ( prng_reseed_ack ), + + .start_we_o ( start_we ), + .key_iv_data_in_clear_we_o ( key_iv_data_in_clear_we ), + .data_out_clear_we_o ( data_out_clear_we ), + .prng_reseed_o ( prng_reseed_out_buf ), + .prng_reseed_we_o ( prng_reseed_we ), + + .idle_o ( idle ), + .idle_we_o ( idle_we ), + .stall_o ( stall ), + .stall_we_o ( stall_we ), + .output_lost_i ( output_lost_in_buf ), + .output_lost_o ( output_lost_out_buf ), + .output_lost_we_o ( output_lost_we ), + .output_valid_o ( output_valid ), + .output_valid_we_o ( output_valid_we ), + .input_ready_o ( input_ready ), + .input_ready_we_o ( input_ready_we ) + ); + + ////////////////////// + // Output Buffering // + ////////////////////// + + localparam int NumOutBufBits = $bits({ + ctrl_we_o, + ctrl_gcm_we_o, + gcm_init_done_o, + alert_o, + data_in_we_o, + data_out_sel_o, + data_out_we_o, + data_in_prev_sel_o, + data_in_prev_we_o, + state_in_sel_o, + add_state_in_sel_o, + add_state_out_sel_o, + ctr_inc32_o, + ctr_incr_o, + cipher_in_valid_o, + cipher_out_ready_o, + cipher_crypt_o, + cipher_dec_key_gen_o, + cipher_prng_reseed_o, + cipher_key_clear_o, + cipher_data_out_clear_o, + ghash_in_valid_o, + ghash_out_ready_o, + ghash_load_hash_subkey_o, + key_init_sel_o, + key_init_we_o, + iv_sel_o, + iv_we_o, + prng_update_o, + prng_reseed_req_o, + start_we_o, + key_iv_data_in_clear_we_o, + data_out_clear_we_o, + prng_reseed_o, + prng_reseed_we_o, + idle_o, + idle_we_o, + stall_o, + stall_we_o, + output_lost_o, + output_lost_we_o, + output_valid_o, + output_valid_we_o, + input_ready_o, + input_ready_we_o + }); + + logic [NumOutBufBits-1:0] out, out_buf; + + assign out = { + ctrl_we, + ctrl_gcm_we, + gcm_init_done, + alert, + data_in_we, + data_out_sel, + data_out_we, + data_in_prev_sel, + data_in_prev_we, + state_in_sel, + add_state_in_sel, + add_state_out_sel, + ctr_inc32, + ctr_incr, + cipher_in_valid, + cipher_out_ready, + cipher_crypt_out_buf, + cipher_dec_key_gen_out_buf, + cipher_prng_reseed_out_buf, + cipher_key_clear_out_buf, + cipher_data_out_clear_out_buf, + ghash_in_valid, + ghash_out_ready, + ghash_load_hash_subkey, + key_init_sel, + key_init_we, + iv_sel, + iv_we, + prng_update, + prng_reseed_req, + start_we, + key_iv_data_in_clear_we, + data_out_clear_we, + prng_reseed_out_buf, + prng_reseed_we, + idle, + idle_we, + stall, + stall_we, + output_lost_out_buf, + output_lost_we, + output_valid, + output_valid_we, + input_ready, + input_ready_we + }; + + // This primitive is used to place a size-only constraint on the + // buffers to act as a synthesis optimization barrier. + caliptra_prim_buf #( + .Width(NumOutBufBits) + ) u_caliptra_prim_buf_out ( + .in_i(out), + .out_o(out_buf) + ); + + assign {ctrl_we_o, + ctrl_gcm_we_o, + gcm_init_done_o, + alert_o, + data_in_we_o, + data_out_sel_o, + data_out_we_o, + data_in_prev_sel_o, + data_in_prev_we_o, + state_in_sel_o, + add_state_in_sel_o, + add_state_out_sel_o, + ctr_inc32_o, + ctr_incr_o, + cipher_in_valid_o, + cipher_out_ready_o, + cipher_crypt_o, + cipher_dec_key_gen_o, + cipher_prng_reseed_o, + cipher_key_clear_o, + cipher_data_out_clear_o, + ghash_in_valid_o, + ghash_out_ready_o, + ghash_load_hash_subkey_o, + key_init_sel_o, + key_init_we_o, + iv_sel_o, + iv_we_o, + prng_update_o, + prng_reseed_req_o, + start_we_o, + key_iv_data_in_clear_we_o, + data_out_clear_we_o, + prng_reseed_o, + prng_reseed_we_o, + idle_o, + idle_we_o, + stall_o, + stall_we_o, + output_lost_o, + output_lost_we_o, + output_valid_o, + output_valid_we_o, + input_ready_o, + input_ready_we_o} = out_buf; + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/aes_core.sv b/designs/Caliptra/src/caliptra-rtl/aes_core.sv new file mode 100644 index 0000000..5de0020 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/aes_core.sv @@ -0,0 +1,1143 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// AES core implementation + +`include "caliptra_prim_assert.sv" + +module aes_core + import aes_pkg::*; + import aes_reg_pkg::*; +#( + parameter bit AES192Enable = 1, + parameter bit AESGCMEnable = 1, + parameter bit SecMasking = 1, + parameter sbox_impl_e SecSBoxImpl = SBoxImplDom, + parameter int unsigned SecStartTriggerDelay = 0, + parameter bit SecAllowForcingMasks = 0, + parameter bit SecSkipPRNGReseeding = 0, + parameter int unsigned EntropyWidth = edn_pkg::ENDPOINT_BUS_WIDTH, + + localparam int NumShares = SecMasking ? 2 : 1, // derived parameter + + parameter clearing_lfsr_seed_t RndCnstClearingLfsrSeed = RndCnstClearingLfsrSeedDefault, + parameter clearing_lfsr_perm_t RndCnstClearingLfsrPerm = RndCnstClearingLfsrPermDefault, + parameter clearing_lfsr_perm_t RndCnstClearingSharePerm = RndCnstClearingSharePermDefault, + parameter masking_lfsr_seed_t RndCnstMaskingLfsrSeed = RndCnstMaskingLfsrSeedDefault, + parameter masking_lfsr_perm_t RndCnstMaskingLfsrPerm = RndCnstMaskingLfsrPermDefault +) ( + input logic clk_i, + input logic rst_ni, + input logic rst_shadowed_ni, + + // Entropy request interfaces for clearing and masking PRNGs + output logic entropy_clearing_req_o, + input logic entropy_clearing_ack_i, + input logic [EntropyWidth-1:0] entropy_clearing_i, + output logic entropy_masking_req_o, + input logic entropy_masking_ack_i, + input logic [EntropyWidth-1:0] entropy_masking_i, + + // Key manager (keymgr) key sideload interface + input keymgr_pkg::hw_key_req_t keymgr_key_i, + + // Life cycle + input lc_ctrl_pkg::lc_tx_t lc_escalate_en_i, + + // Alerts + input logic shadowed_storage_err_i, + input logic shadowed_update_err_i, + input logic intg_err_alert_i, + output logic alert_recov_o, + output logic alert_fatal_o, + + // Bus Interface + input aes_reg2hw_t reg2hw, + output aes_hw2reg_t hw2reg +); + + // Signals + logic ctrl_qe; + logic ctrl_we; + logic ctrl_phase; + aes_op_e aes_op_q; + aes_mode_e aes_mode_q; + ciph_op_e cipher_op; + ciph_op_e cipher_op_buf; + key_len_e key_len_q; + logic sideload_q; + prs_rate_e prng_reseed_rate_q; + logic manual_operation_q; + logic ctrl_reg_err_update; + logic ctrl_reg_err_storage; + logic ctrl_gcm_qe; + logic ctrl_gcm_we; + logic ctrl_gcm_phase; + logic gcm_init_done; + gcm_phase_e gcm_phase_q; + logic [4:0] num_valid_bytes_q; + logic ctrl_gcm_reg_err_update; + logic ctrl_gcm_reg_err_storage; + logic ctrl_err_update; + logic ctrl_err_storage; + logic ctrl_err_storage_d; + logic ctrl_err_storage_q; + logic ctrl_alert; + logic key_touch_forces_reseed; + logic force_masks; + logic mux_sel_err; + logic sp_enc_err_d, sp_enc_err_q; + logic clear_on_fatal; + + logic [3:0][3:0][7:0] state_in; + logic [SISelWidth-1:0] state_in_sel_raw; + si_sel_e state_in_sel_ctrl; + si_sel_e state_in_sel; + logic state_in_sel_err; + logic [3:0][3:0][7:0] add_state_in; + logic [AddSISelWidth-1:0] add_state_in_sel_raw; + add_si_sel_e add_state_in_sel_ctrl; + add_si_sel_e add_state_in_sel; + logic add_state_in_sel_err; + + logic [3:0][3:0][7:0] state_mask; + logic [3:0][3:0][7:0] state_init [NumShares]; + logic [3:0][3:0][7:0] state_done [NumShares]; + logic [3:0][3:0][7:0] state_out; + + logic [NumRegsKey-1:0][31:0] key_init [NumSharesKey]; + logic [NumRegsKey-1:0] key_init_qe [NumSharesKey]; + logic [NumRegsKey-1:0] key_init_qe_buf [NumSharesKey]; + logic [NumRegsKey-1:0][31:0] key_init_d [NumSharesKey]; + logic [NumRegsKey-1:0][31:0] key_init_q [NumSharesKey]; + logic [NumRegsKey-1:0][31:0] key_init_cipher [NumShares]; + sp2v_e [NumRegsKey-1:0] key_init_we_ctrl [NumSharesKey]; + sp2v_e [NumRegsKey-1:0] key_init_we [NumSharesKey]; + logic [KeyInitSelWidth-1:0] key_init_sel_raw; + key_init_sel_e key_init_sel_ctrl; + key_init_sel_e key_init_sel; + logic key_init_sel_err; + logic [NumRegsKey-1:0][31:0] key_sideload [NumSharesKey]; + + logic [NumRegsIv-1:0][31:0] iv; + logic [NumRegsIv-1:0] iv_qe; + logic [NumRegsIv-1:0] iv_qe_buf; + logic [NumSlicesCtr-1:0][SliceSizeCtr-1:0] iv_d; + logic [NumSlicesCtr-1:0][SliceSizeCtr-1:0] iv_q; + sp2v_e [NumSlicesCtr-1:0] iv_we_ctrl; + sp2v_e [NumSlicesCtr-1:0] iv_we; + logic [IVSelWidth-1:0] iv_sel_raw; + iv_sel_e iv_sel_ctrl; + iv_sel_e iv_sel; + logic iv_sel_err; + + logic [NumSlicesCtr-1:0][SliceSizeCtr-1:0] ctr; + sp2v_e [NumSlicesCtr-1:0] ctr_we; + sp2v_e ctr_inc32; + sp2v_e ctr_incr; + sp2v_e ctr_ready; + logic ctr_alert; + + logic [NumRegsData-1:0][31:0] data_in_prev_d; + logic [NumRegsData-1:0][31:0] data_in_prev_q; + sp2v_e data_in_prev_we_ctrl; + sp2v_e data_in_prev_we; + logic [DIPSelWidth-1:0] data_in_prev_sel_raw; + dip_sel_e data_in_prev_sel_ctrl; + dip_sel_e data_in_prev_sel; + logic data_in_prev_sel_err; + + logic [NumRegsData-1:0][31:0] data_in; + logic [NumRegsData-1:0] data_in_qe; + logic [NumRegsData-1:0] data_in_qe_buf; + logic data_in_we; + + logic [3:0][3:0][7:0] add_state_out; + logic [AddSOSelWidth-1:0] add_state_out_sel_raw; + add_so_sel_e add_state_out_sel_ctrl; + add_so_sel_e add_state_out_sel; + logic add_state_out_sel_err; + + logic [NumRegsData-1:0][31:0] data_out; + logic [NumRegsData-1:0][31:0] data_out_d; + logic [NumRegsData-1:0][31:0] data_out_q; + sp2v_e data_out_we_ctrl; + sp2v_e data_out_we; + logic [NumRegsData-1:0] data_out_re; + logic [NumRegsData-1:0] data_out_re_buf; + logic [DataOutSelWidth-1:0] data_out_sel_raw; + data_out_sel_e data_out_sel_ctrl; + data_out_sel_e data_out_sel; + logic data_out_sel_err; + + sp2v_e cipher_in_valid; + sp2v_e cipher_in_ready; + sp2v_e cipher_out_valid; + sp2v_e cipher_out_ready; + sp2v_e cipher_crypt; + sp2v_e cipher_crypt_busy; + sp2v_e cipher_dec_key_gen; + sp2v_e cipher_dec_key_gen_busy; + logic cipher_prng_reseed; + logic cipher_prng_reseed_busy; + logic cipher_key_clear; + logic cipher_key_clear_busy; + logic cipher_data_out_clear; + logic cipher_data_out_clear_busy; + logic cipher_alert; + + sp2v_e ghash_in_valid; + sp2v_e ghash_in_ready; + sp2v_e ghash_out_valid; + sp2v_e ghash_out_ready; + sp2v_e ghash_load_hash_subkey; + logic ghash_first_block; + logic ghash_alert; + + // Pseudo-random data for clearing purposes + logic [WidthPRDClearing-1:0] prd_clearing [NumSharesKey]; + logic prd_clearing_update; + logic prd_clearing_rsd_req; + logic prd_clearing_rsd_ack; + logic [127:0] prd_clearing_128 [NumShares]; + logic [255:0] prd_clearing_256 [NumShares]; + logic [3:0][31:0] prd_clearing_data; + logic [255:0] prd_clearing_key_init [NumSharesKey]; + logic [3:0][3:0][7:0] prd_clearing_state [NumShares]; + logic [7:0][31:0] prd_clearing_key [NumShares]; + + // Unused signals + logic [NumRegsData-1:0][31:0] unused_data_out_q; + + // The clearing PRNG provides pseudo-random data for register clearing purposes. + aes_prng_clearing #( + .Width ( WidthPRDClearing ), + .EntropyWidth ( EntropyWidth ), + .SecSkipPRNGReseeding ( SecSkipPRNGReseeding ), + .RndCnstLfsrSeed ( RndCnstClearingLfsrSeed ), + .RndCnstLfsrPerm ( RndCnstClearingLfsrPerm ), + .RndCnstSharePerm ( RndCnstClearingSharePerm ) + ) u_aes_prng_clearing ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + + .data_update_i ( prd_clearing_update ), + .data_o ( prd_clearing ), + .reseed_req_i ( prd_clearing_rsd_req ), + .reseed_ack_o ( prd_clearing_rsd_ack ), + + .entropy_req_o ( entropy_clearing_req_o ), + .entropy_ack_i ( entropy_clearing_ack_i ), + .entropy_i ( entropy_clearing_i ) + ); + + // Generate clearing signals of appropriate widths. + // Different shares need to be cleared with different pseudo-random data. + for (genvar s = 0; s < NumShares; s++) begin : gen_prd_clearing_shares + for (genvar c = 0; c < NumChunksPRDClearing128; c++) begin : gen_prd_clearing_128 + assign prd_clearing_128[s][c * WidthPRDClearing +: WidthPRDClearing] = prd_clearing[s]; + end + for (genvar c = 0; c < NumChunksPRDClearing256; c++) begin : gen_prd_clearing_256 + assign prd_clearing_256[s][c * WidthPRDClearing +: WidthPRDClearing] = prd_clearing[s]; + end + end + // The data registers are always unmasked. + assign prd_clearing_data = prd_clearing_128[0]; + // The initial key is always provided in two shares. The two shares of the initial key register + // need to be cleared with different pseudo-random data. + for (genvar s = 0; s < NumSharesKey; s++) begin : gen_prd_clearing_key_init_shares + for (genvar c = 0; c < NumChunksPRDClearing256; c++) begin : gen_prd_clearing_key_init + assign prd_clearing_key_init[s][c * WidthPRDClearing +: WidthPRDClearing] = prd_clearing[s]; + end + end + // The cipher core uses multiple packed dimensions internally but the number of bits remain the + // same. Since some tools fail to peform the `conversion` on input ports, we do it here. + assign prd_clearing_state = prd_clearing_128; + assign prd_clearing_key = prd_clearing_256; + + //////////// + // Inputs // + //////////// + + always_comb begin : key_init_get + for (int i = 0; i < NumRegsKey; i++) begin + key_init[0][i] = reg2hw.key_share0[i].q; + key_init_qe[0][i] = reg2hw.key_share0[i].qe; + key_init[1][i] = reg2hw.key_share1[i].q; + key_init_qe[1][i] = reg2hw.key_share1[i].qe; + end + end + + caliptra_prim_sec_anchor_buf #( + .Width ( NumSharesKey * NumRegsKey ) + ) u_caliptra_prim_buf_key_init_qe ( + .in_i ( {key_init_qe[1], key_init_qe[0]} ), + .out_o ( {key_init_qe_buf[1], key_init_qe_buf[0]} ) + ); + + always_comb begin : key_sideload_get + for (int s = 0; s < NumSharesKey; s++) begin + for (int i = 0; i < NumRegsKey; i++) begin + key_sideload[s][i] = keymgr_key_i.key[s][i * 32 +: 32]; + end + end + end + + always_comb begin : iv_get + for (int i = 0; i < NumRegsIv; i++) begin + iv[i] = reg2hw.iv[i].q; + iv_qe[i] = reg2hw.iv[i].qe; + end + end + + caliptra_prim_sec_anchor_buf #( + .Width ( NumRegsIv ) + ) u_caliptra_prim_buf_iv_qe ( + .in_i ( iv_qe ), + .out_o ( iv_qe_buf ) + ); + + always_comb begin : data_in_get + for (int i = 0; i < NumRegsData; i++) begin + data_in[i] = reg2hw.data_in[i].q; + data_in_qe[i] = reg2hw.data_in[i].qe; + end + end + + caliptra_prim_sec_anchor_buf #( + .Width ( NumRegsData ) + ) u_caliptra_prim_buf_data_in_qe ( + .in_i ( data_in_qe ), + .out_o ( data_in_qe_buf ) + ); + + always_comb begin : data_out_get + for (int i = 0; i < NumRegsData; i++) begin + // data_out is actually hwo, but we need hrw for hwre + unused_data_out_q[i] = reg2hw.data_out[i].q; + data_out_re[i] = reg2hw.data_out[i].re; + end + end + + caliptra_prim_sec_anchor_buf #( + .Width ( NumRegsData ) + ) u_caliptra_prim_buf_data_out_re ( + .in_i ( data_out_re ), + .out_o ( data_out_re_buf ) + ); + + ////////////////////// + // Key, IV and Data // + ////////////////////// + + // SEC_CM: KEY.SEC_WIPE + // SEC_CM: KEY.SIDELOAD + // Initial Key registers + always_comb begin : key_init_mux + unique case (key_init_sel) + KEY_INIT_INPUT: key_init_d = key_init; + KEY_INIT_KEYMGR: key_init_d = key_sideload; + KEY_INIT_CLEAR: key_init_d = prd_clearing_key_init; + default: key_init_d = prd_clearing_key_init; + endcase + end + + always_ff @(posedge clk_i or negedge rst_ni) begin : key_init_reg + if (!rst_ni) begin + key_init_q <= '{default: '0}; + end else begin + for (int s = 0; s < NumSharesKey; s++) begin + for (int i = 0; i < NumRegsKey; i++) begin + if (key_init_we[s][i] == SP2V_HIGH) begin + key_init_q[s][i] <= key_init_d[s][i]; + end + end + end + end + end + + // SEC_CM: IV.CONFIG.SEC_WIPE + // IV registers + always_comb begin : iv_mux + unique case (iv_sel) + IV_INPUT: iv_d = iv; + IV_DATA_OUT: iv_d = data_out_d; + IV_DATA_OUT_RAW: iv_d = aes_transpose(state_out); + IV_DATA_IN_PREV: iv_d = data_in_prev_q; + IV_CTR: iv_d = ctr; + IV_CLEAR: iv_d = prd_clearing_data; + default: iv_d = prd_clearing_data; + endcase + end + + always_ff @(posedge clk_i or negedge rst_ni) begin : iv_reg + if (!rst_ni) begin + iv_q <= '0; + end else begin + for (int i = 0; i < NumSlicesCtr; i++) begin + if (iv_we[i] == SP2V_HIGH) begin + iv_q[i] <= iv_d[i]; + end + end + end + end + + // SEC_CM: DATA_REG.SEC_WIPE + // Previous input data register + always_comb begin : data_in_prev_mux + unique case (data_in_prev_sel) + DIP_DATA_IN: data_in_prev_d = data_in; + DIP_CLEAR: data_in_prev_d = prd_clearing_data; + default: data_in_prev_d = prd_clearing_data; + endcase + end + + always_ff @(posedge clk_i or negedge rst_ni) begin : data_in_prev_reg + if (!rst_ni) begin + data_in_prev_q <= '0; + end else if (data_in_prev_we == SP2V_HIGH) begin + data_in_prev_q <= data_in_prev_d; + end + end + + ///////////// + // Counter // + ///////////// + + aes_ctr u_aes_ctr ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + + .inc32_i ( ctr_inc32 ), + .incr_i ( ctr_incr ), + .ready_o ( ctr_ready ), + .alert_o ( ctr_alert ), + + .ctr_i ( iv_q ), + .ctr_o ( ctr ), + .ctr_we_o ( ctr_we ) + ); + + ///////////////// + // Cipher Core // + ///////////////// + + // Cipher core operation + assign cipher_op = (aes_mode_q == AES_ECB && aes_op_q == AES_ENC) ? CIPH_FWD : + (aes_mode_q == AES_ECB && aes_op_q == AES_DEC) ? CIPH_INV : + (aes_mode_q == AES_CBC && aes_op_q == AES_ENC) ? CIPH_FWD : + (aes_mode_q == AES_CBC && aes_op_q == AES_DEC) ? CIPH_INV : + (aes_mode_q == AES_CFB) ? CIPH_FWD : + (aes_mode_q == AES_OFB) ? CIPH_FWD : + (aes_mode_q == AES_CTR) ? CIPH_FWD : + (aes_mode_q == AES_GCM) ? CIPH_FWD : CIPH_FWD; + + // This primitive is used to place a size-only constraint on the + // buffers to act as a synthesis optimization barrier. + logic [$bits(ciph_op_e)-1:0] cipher_op_raw; + caliptra_prim_buf #( + .Width($bits(ciph_op_e)) + ) u_caliptra_prim_buf_op ( + .in_i(cipher_op), + .out_o(cipher_op_raw) + ); + assign cipher_op_buf = ciph_op_e'(cipher_op_raw); + + // Convert input data/IV to state format (every word corresponds to one state column). + // Mux for state input + always_comb begin : state_in_mux + unique case (state_in_sel) + SI_ZERO: state_in = '0; + SI_DATA: state_in = aes_transpose(data_in); + default: state_in = '0; + endcase + end + + // Mux for addition to state input + always_comb begin : add_state_in_mux + unique case (add_state_in_sel) + ADD_SI_ZERO: add_state_in = '0; + ADD_SI_IV: add_state_in = aes_transpose(iv_q); + default: add_state_in = '0; + endcase + end + + if (!SecMasking) begin : gen_state_init_unmasked + assign state_init[0] = state_in ^ add_state_in; + + logic [3:0][3:0][7:0] unused_state_mask; + assign unused_state_mask = state_mask; + + end else begin : gen_state_init_masked + assign state_init[0] = (state_in ^ add_state_in) ^ state_mask; // Masked data share + assign state_init[1] = state_mask; // Mask share + end + + if (!SecMasking) begin : gen_key_init_unmasked + // Combine the two key shares for the unmasked cipher core. This causes SCA leakage of the key + // and thus should be avoided. + assign key_init_cipher[0] = key_init_q[0] ^ key_init_q[1]; + + end else begin : gen_key_init_masked + // Forward the masked key share and the mask share to the masked cipher core. + assign key_init_cipher = key_init_q; + end + + // SEC_CM: KEY.MASKING + // Cipher core + aes_cipher_core #( + .AES192Enable ( AES192Enable ), + .SecMasking ( SecMasking ), + .SecSBoxImpl ( SecSBoxImpl ), + .SecAllowForcingMasks ( SecAllowForcingMasks ), + .SecSkipPRNGReseeding ( SecSkipPRNGReseeding ), + .RndCnstMaskingLfsrSeed ( RndCnstMaskingLfsrSeed ), + .RndCnstMaskingLfsrPerm ( RndCnstMaskingLfsrPerm ) + ) u_aes_cipher_core ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + + .in_valid_i ( cipher_in_valid ), + .in_ready_o ( cipher_in_ready ), + + .out_valid_o ( cipher_out_valid ), + .out_ready_i ( cipher_out_ready ), + + .cfg_valid_i ( ~ctrl_err_storage ), // Used for gating assertions only. + .op_i ( cipher_op_buf ), + .key_len_i ( key_len_q ), + .crypt_i ( cipher_crypt ), + .crypt_o ( cipher_crypt_busy ), + .dec_key_gen_i ( cipher_dec_key_gen ), + .dec_key_gen_o ( cipher_dec_key_gen_busy ), + .prng_reseed_i ( cipher_prng_reseed ), + .prng_reseed_o ( cipher_prng_reseed_busy ), + .key_clear_i ( cipher_key_clear ), + .key_clear_o ( cipher_key_clear_busy ), + .data_out_clear_i ( cipher_data_out_clear ), + .data_out_clear_o ( cipher_data_out_clear_busy ), + .alert_fatal_i ( alert_fatal_o ), + .alert_o ( cipher_alert ), + + .prd_clearing_state_i ( prd_clearing_state ), + .prd_clearing_key_i ( prd_clearing_key ), + + .force_masks_i ( force_masks ), + .data_in_mask_o ( state_mask ), + .entropy_req_o ( entropy_masking_req_o ), + .entropy_ack_i ( entropy_masking_ack_i ), + .entropy_i ( entropy_masking_i ), + + .state_init_i ( state_init ), + .key_init_i ( key_init_cipher ), + .state_o ( state_done ) + ); + + if (!SecMasking) begin : gen_state_out_unmasked + assign state_out = state_done[0]; + end else begin : gen_state_out_masked + // Unmask the cipher core output. This might get reworked in the future when masking the + // counter and feedback path through the IV regs. + + // Only unmask the final cipher core output. Unmasking intermediate output data causes + // additional SCA leakage and thus has to be avoided. Forward PRD instead of a determinsitic + // value to avoid leaking the cipher core output when it becomes valid. Don't unmask the hash + // subkey in case of GCM. + logic [3:0][3:0][7:0] state_done_muxed [NumShares]; + for (genvar s = 0; s < NumShares; s++) begin : gen_state_done_muxed + assign state_done_muxed[s] = ((cipher_out_valid == SP2V_HIGH) && + !(aes_mode_q == AES_GCM && + gcm_phase_q == GCM_INIT)) ? state_done[s] : prd_clearing_state[s]; + end + + // Avoid aggressive synthesis optimizations. + logic [3:0][3:0][7:0] state_done_buf [NumShares]; + caliptra_prim_buf #( + .Width ( 128 * NumShares ) + ) u_caliptra_prim_state_done_muxed ( + .in_i ( {state_done_muxed[1], state_done_muxed[0]} ), + .out_o ( {state_done_buf[1], state_done_buf[0]} ) + ); + + // Unmask the cipher core output. + assign state_out = state_done_buf[0] ^ state_done_buf[1]; + end + + // Mux for addition to state output + always_comb begin : add_state_out_mux + unique case (add_state_out_sel) + ADD_SO_ZERO: add_state_out = '0; + ADD_SO_IV: add_state_out = aes_transpose(iv_q); + ADD_SO_DIP: add_state_out = aes_transpose(data_in_prev_q); + default: add_state_out = '0; + endcase + end + + // Convert output state to output data format (every column corresponds to one output word). + assign data_out = aes_transpose(state_out ^ add_state_out); + + /////////// + // GHASH // + /////////// + + if (AESGCMEnable) begin : gen_ghash + logic [3:0][3:0][7:0] ghash_state_out; + + logic ghash_clear; + assign ghash_clear = cipher_key_clear | cipher_key_clear_busy; + + // The number of cycles must be a power of two and ideally matches the minimum latency of the + // cipher core which is 56 clock cycles (masked) or 12 clock cycles (unmasked) for AES-128. + localparam int unsigned GhashGFMultCycles = (SecSBoxImpl == SBoxImplDom) ? 32 : 8; + + // The actual GHASH module. + aes_ghash #( + .SecMasking ( SecMasking ), + .GFMultCycles ( GhashGFMultCycles ) + ) u_aes_ghash ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + + .in_valid_i ( ghash_in_valid ), + .in_ready_o ( ghash_in_ready ), + + .out_valid_o ( ghash_out_valid ), + .out_ready_i ( ghash_out_ready ), + + .op_i ( aes_op_q ), + .gcm_phase_i ( gcm_phase_q ), + .num_valid_bytes_i ( num_valid_bytes_q ), + .load_hash_subkey_i ( ghash_load_hash_subkey ), + .clear_i ( ghash_clear ), + .first_block_o ( ghash_first_block ), + .alert_fatal_i ( alert_fatal_o ), + .alert_o ( ghash_alert ), + + .data_in_prev_i ( data_in_prev_q ), + .data_out_i ( data_out ), + .cipher_state_done_i ( state_done ), + .ghash_state_done_o ( ghash_state_out ) + ); + + // Mux for output data registers + always_comb begin : data_out_mux + unique case (data_out_sel) + DATA_OUT_CIPHER: data_out_d = data_out; + DATA_OUT_GHASH: data_out_d = ghash_state_out; + default: data_out_d = ghash_state_out; + endcase + end + + end else begin : gen_no_ghash + // GHASH isn't there and thus generates no back pressure / alerts / output to be muxed. + assign ghash_in_ready = SP2V_HIGH; + assign ghash_out_valid = SP2V_HIGH; + assign ghash_first_block = 1'b0; + assign ghash_alert = 1'b0; + assign data_out_d = data_out; + + // Tie-off unused signals. + sp2v_e unused_ghash_in_valid; + sp2v_e unused_ghash_out_ready; + sp2v_e unused_ghash_load_hash_subkey; + logic [4:0] unused_num_valid_bytes; + data_out_sel_e unused_data_out_sel; + assign unused_ghash_in_valid = ghash_in_valid; + assign unused_ghash_out_ready = ghash_out_ready; + assign unused_ghash_load_hash_subkey = ghash_load_hash_subkey; + assign unused_num_valid_bytes = num_valid_bytes_q; + assign unused_data_out_sel = data_out_sel; + end + + /////////////////////// + // Control Registers // + /////////////////////// + + // Shadowed register primitve + aes_ctrl_reg_shadowed #( + .AES192Enable ( AES192Enable ), + .AESGCMEnable ( AESGCMEnable ) + ) u_ctrl_reg_shadowed ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .rst_shadowed_ni ( rst_shadowed_ni ), + .qe_o ( ctrl_qe ), + .we_i ( ctrl_we ), + .phase_o ( ctrl_phase ), + .operation_o ( aes_op_q ), + .mode_o ( aes_mode_q ), + .key_len_o ( key_len_q ), + .sideload_o ( sideload_q ), + .prng_reseed_rate_o ( prng_reseed_rate_q ), + .manual_operation_o ( manual_operation_q ), + .err_update_o ( ctrl_reg_err_update ), + .err_storage_o ( ctrl_reg_err_storage ), + .reg2hw_ctrl_i ( reg2hw.ctrl_shadowed ), + .hw2reg_ctrl_o ( hw2reg.ctrl_shadowed ) + ); + + // Auxiliary control register signals + assign key_touch_forces_reseed = reg2hw.ctrl_aux_shadowed.key_touch_forces_reseed.q; + assign force_masks = reg2hw.ctrl_aux_shadowed.force_masks.q; + + // GCM control register + aes_ctrl_gcm_reg_shadowed #( + .AESGCMEnable ( AESGCMEnable ) + ) u_ctrl_gcm_reg_shadowed ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .rst_shadowed_ni ( rst_shadowed_ni ), + .qe_o ( ctrl_gcm_qe ), + .we_i ( ctrl_gcm_we ), + .phase_o ( ctrl_gcm_phase ), + .init_done_i ( gcm_init_done ), + .first_block_i ( ghash_first_block ), + .gcm_phase_o ( gcm_phase_q ), + .num_valid_bytes_o ( num_valid_bytes_q ), + .err_update_o ( ctrl_gcm_reg_err_update ), + .err_storage_o ( ctrl_gcm_reg_err_storage ), + .reg2hw_ctrl_gcm_i ( reg2hw.ctrl_gcm_shadowed ), + .hw2reg_ctrl_gcm_o ( hw2reg.ctrl_gcm_shadowed ) + ); + + ///////////// + // Control // + ///////////// + + // Control + aes_control #( + .AESGCMEnable ( AESGCMEnable ), + .SecMasking ( SecMasking ), + .SecStartTriggerDelay ( SecStartTriggerDelay ) + ) u_aes_control ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + + .ctrl_qe_i ( ctrl_qe ), + .ctrl_we_o ( ctrl_we ), + .ctrl_phase_i ( ctrl_phase ), + .ctrl_err_storage_i ( ctrl_err_storage ), + .op_i ( aes_op_q ), + .mode_i ( aes_mode_q ), + .cipher_op_i ( cipher_op_buf ), + .sideload_i ( sideload_q ), + .prng_reseed_rate_i ( prng_reseed_rate_q ), + .manual_operation_i ( manual_operation_q ), + .key_touch_forces_reseed_i ( key_touch_forces_reseed ), + .ctrl_gcm_qe_i ( ctrl_gcm_qe ), + .ctrl_gcm_we_o ( ctrl_gcm_we ), + .ctrl_gcm_phase_i ( ctrl_gcm_phase ), + .gcm_init_done_o ( gcm_init_done ), + .gcm_phase_i ( gcm_phase_q ), + .start_i ( reg2hw.trigger.start.q ), + .key_iv_data_in_clear_i ( reg2hw.trigger.key_iv_data_in_clear.q ), + .data_out_clear_i ( reg2hw.trigger.data_out_clear.q ), + .prng_reseed_i ( reg2hw.trigger.prng_reseed.q ), + .mux_sel_err_i ( mux_sel_err ), + .sp_enc_err_i ( sp_enc_err_q ), + .lc_escalate_en_i ( lc_escalate_en_i ), + .alert_fatal_i ( alert_fatal_o ), + .alert_o ( ctrl_alert ), + + .key_sideload_valid_i ( keymgr_key_i.valid ), + .key_init_qe_i ( key_init_qe_buf ), + .iv_qe_i ( iv_qe_buf ), + .data_in_qe_i ( data_in_qe_buf ), + .data_out_re_i ( data_out_re_buf ), + .data_in_we_o ( data_in_we ), + .data_out_sel_o ( data_out_sel_ctrl ), + .data_out_we_o ( data_out_we_ctrl ), + + .data_in_prev_sel_o ( data_in_prev_sel_ctrl ), + .data_in_prev_we_o ( data_in_prev_we_ctrl ), + + .state_in_sel_o ( state_in_sel_ctrl ), + .add_state_in_sel_o ( add_state_in_sel_ctrl ), + .add_state_out_sel_o ( add_state_out_sel_ctrl ), + + .ctr_inc32_o ( ctr_inc32 ), + .ctr_incr_o ( ctr_incr ), + .ctr_ready_i ( ctr_ready ), + .ctr_we_i ( ctr_we ), + + .cipher_in_valid_o ( cipher_in_valid ), + .cipher_in_ready_i ( cipher_in_ready ), + .cipher_out_valid_i ( cipher_out_valid ), + .cipher_out_ready_o ( cipher_out_ready ), + .cipher_crypt_o ( cipher_crypt ), + .cipher_crypt_i ( cipher_crypt_busy ), + .cipher_dec_key_gen_o ( cipher_dec_key_gen ), + .cipher_dec_key_gen_i ( cipher_dec_key_gen_busy ), + .cipher_prng_reseed_o ( cipher_prng_reseed ), + .cipher_prng_reseed_i ( cipher_prng_reseed_busy ), + .cipher_key_clear_o ( cipher_key_clear ), + .cipher_key_clear_i ( cipher_key_clear_busy ), + .cipher_data_out_clear_o ( cipher_data_out_clear ), + .cipher_data_out_clear_i ( cipher_data_out_clear_busy ), + + .ghash_in_valid_o ( ghash_in_valid ), + .ghash_in_ready_i ( ghash_in_ready ), + .ghash_out_valid_i ( ghash_out_valid ), + .ghash_out_ready_o ( ghash_out_ready ), + .ghash_load_hash_subkey_o ( ghash_load_hash_subkey ), + + .key_init_sel_o ( key_init_sel_ctrl ), + .key_init_we_o ( key_init_we_ctrl ), + .iv_sel_o ( iv_sel_ctrl ), + .iv_we_o ( iv_we_ctrl ), + + .prng_update_o ( prd_clearing_update ), + .prng_reseed_req_o ( prd_clearing_rsd_req ), + .prng_reseed_ack_i ( prd_clearing_rsd_ack ), + + .start_o ( hw2reg.trigger.start.d ), + .start_we_o ( hw2reg.trigger.start.de ), + .key_iv_data_in_clear_o ( hw2reg.trigger.key_iv_data_in_clear.d ), + .key_iv_data_in_clear_we_o ( hw2reg.trigger.key_iv_data_in_clear.de ), + .data_out_clear_o ( hw2reg.trigger.data_out_clear.d ), + .data_out_clear_we_o ( hw2reg.trigger.data_out_clear.de ), + .prng_reseed_o ( hw2reg.trigger.prng_reseed.d ), + .prng_reseed_we_o ( hw2reg.trigger.prng_reseed.de ), + + .idle_o ( hw2reg.status.idle.d ), + .idle_we_o ( hw2reg.status.idle.de ), + .stall_o ( hw2reg.status.stall.d ), + .stall_we_o ( hw2reg.status.stall.de ), + .output_lost_i ( reg2hw.status.output_lost.q ), + .output_lost_o ( hw2reg.status.output_lost.d ), + .output_lost_we_o ( hw2reg.status.output_lost.de ), + .output_valid_o ( hw2reg.status.output_valid.d ), + .output_valid_we_o ( hw2reg.status.output_valid.de ), + .input_ready_o ( hw2reg.status.input_ready.d ), + .input_ready_we_o ( hw2reg.status.input_ready.de ) + ); + + // SEC_CM: DATA_REG.SEC_WIPE + // Input data register clear + always_comb begin : data_in_reg_clear + for (int i = 0; i < NumRegsData; i++) begin + hw2reg.data_in[i].d = prd_clearing_data[i]; + hw2reg.data_in[i].de = data_in_we; + end + end + + /////////////// + // Selectors // + /////////////// + + // We use sparse encodings for these mux selector signals and must ensure that: + // 1. The synthesis tool doesn't optimize away the sparse encoding. + // 2. The selector signal is always valid. More precisely, an alert or SVA is triggered if a + // selector signal takes on an invalid value. + // 3. The alert signal remains asserted until reset even if the selector signal becomes valid + // again. This is achieved by driving the control FSM into the terminal error state whenever + // any mux selector signal becomes invalid. + // + // If any mux selector signal becomes invalid, the control FSM further prevents any data from + // being released from the cipher core by de-asserting the write enable of the output data + // registers. + + aes_sel_buf_chk #( + .Num ( DIPSelNum ), + .Width ( DIPSelWidth ), + .EnSecBuf ( 1'b1 ) + ) u_aes_data_in_prev_sel_buf_chk ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .sel_i ( data_in_prev_sel_ctrl ), + .sel_o ( data_in_prev_sel_raw ), + .err_o ( data_in_prev_sel_err ) + ); + assign data_in_prev_sel = dip_sel_e'(data_in_prev_sel_raw); + + aes_sel_buf_chk #( + .Num ( SISelNum ), + .Width ( SISelWidth ), + .EnSecBuf ( 1'b1 ) + ) u_aes_state_in_sel_buf_chk ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .sel_i ( state_in_sel_ctrl ), + .sel_o ( state_in_sel_raw ), + .err_o ( state_in_sel_err ) + ); + assign state_in_sel = si_sel_e'(state_in_sel_raw); + + aes_sel_buf_chk #( + .Num ( AddSISelNum ), + .Width ( AddSISelWidth ), + .EnSecBuf ( 1'b1 ) + ) u_aes_add_state_in_sel_buf_chk ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .sel_i ( add_state_in_sel_ctrl ), + .sel_o ( add_state_in_sel_raw ), + .err_o ( add_state_in_sel_err ) + ); + assign add_state_in_sel = add_si_sel_e'(add_state_in_sel_raw); + + aes_sel_buf_chk #( + .Num ( AddSOSelNum ), + .Width ( AddSOSelWidth ), + .EnSecBuf ( 1'b1 ) + ) u_aes_add_state_out_sel_buf_chk ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .sel_i ( add_state_out_sel_ctrl ), + .sel_o ( add_state_out_sel_raw ), + .err_o ( add_state_out_sel_err ) + ); + assign add_state_out_sel = add_so_sel_e'(add_state_out_sel_raw); + + aes_sel_buf_chk #( + .Num ( KeyInitSelNum ), + .Width ( KeyInitSelWidth ), + .EnSecBuf ( 1'b1 ) + ) u_aes_key_init_sel_buf_chk ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .sel_i ( key_init_sel_ctrl ), + .sel_o ( key_init_sel_raw ), + .err_o ( key_init_sel_err ) + ); + assign key_init_sel = key_init_sel_e'(key_init_sel_raw); + + aes_sel_buf_chk #( + .Num ( IVSelNum ), + .Width ( IVSelWidth ), + .EnSecBuf ( 1'b1 ) + ) u_aes_iv_sel_buf_chk ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .sel_i ( iv_sel_ctrl ), + .sel_o ( iv_sel_raw ), + .err_o ( iv_sel_err ) + ); + assign iv_sel = iv_sel_e'(iv_sel_raw); + + aes_sel_buf_chk #( + .Num ( DataOutSelNum ), + .Width ( DataOutSelWidth ), + .EnSecBuf ( 1'b1 ) + ) u_aes_data_out_sel_buf_chk ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .sel_i ( data_out_sel_ctrl ), + .sel_o ( data_out_sel_raw ), + .err_o ( data_out_sel_err ) + ); + assign data_out_sel = data_out_sel_e'(data_out_sel_raw); + + // Signal invalid mux selector signals to control FSM which will lock up and trigger an alert. + assign mux_sel_err = data_in_prev_sel_err | state_in_sel_err | add_state_in_sel_err | + add_state_out_sel_err | key_init_sel_err | iv_sel_err | data_out_sel_err; + + ////////////////////////////// + // Sparsely Encoded Signals // + ////////////////////////////// + + // We use sparse encodings for various critical signals and must ensure that: + // 1. The synthesis tool doesn't optimize away the sparse encoding. + // 2. The sparsely encoded signal is always valid. More precisely, an alert or SVA is triggered + // if a sparse signal takes on an invalid value. + // 3. The alert signal remains asserted until reset even if the sparse signal becomes valid again + // This is achieved by driving the control FSM into the terminal error state whenever any + // sparsely encoded signal becomes invalid. + // + // If any sparsely encoded signal becomes invalid, the core controller further immediately + // de-asserts the data_out_we_o signal to prevent any data from being released. + + // We use vectors of sparsely encoded signals to reduce code duplication. + localparam int unsigned NumSp2VSig = NumSharesKey * NumRegsKey + NumSlicesCtr + 2; + sp2v_e [NumSp2VSig-1:0] sp2v_sig; + sp2v_e [NumSp2VSig-1:0] sp2v_sig_chk; + logic [NumSp2VSig-1:0][Sp2VWidth-1:0] sp2v_sig_chk_raw; + logic [NumSp2VSig-1:0] sp2v_sig_err; + + for (genvar s = 0; s < NumSharesKey; s++) begin : gen_use_key_init_we_ctrl_shares + for (genvar i = 0; i < NumRegsKey; i++) begin : gen_use_key_init_we_ctrl + assign sp2v_sig[s * NumRegsKey + i] = key_init_we_ctrl[s][i]; + end + end + for (genvar i = 0; i < NumSlicesCtr; i++) begin : gen_use_iv_we_ctrl + assign sp2v_sig[NumSharesKey * NumRegsKey + i] = iv_we_ctrl[i]; + end + assign sp2v_sig[NumSharesKey * NumRegsKey + NumSlicesCtr + 0] = data_in_prev_we_ctrl; + assign sp2v_sig[NumSharesKey * NumRegsKey + NumSlicesCtr + 1] = data_out_we_ctrl; + + // All signals inside sp2v_sig are eventually converted to single-rail signals. + localparam bit [NumSp2VSig-1:0] Sp2VEnSecBuf = {NumSp2VSig{1'b1}}; + + // Individually check sparsely encoded signals. + for (genvar i = 0; i < NumSp2VSig; i++) begin : gen_sel_buf_chk + aes_sel_buf_chk #( + .Num ( Sp2VNum ), + .Width ( Sp2VWidth ), + .EnSecBuf ( Sp2VEnSecBuf[i] ) + ) u_aes_sp2v_sig_buf_chk_i ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .sel_i ( sp2v_sig[i] ), + .sel_o ( sp2v_sig_chk_raw[i] ), + .err_o ( sp2v_sig_err[i] ) + ); + assign sp2v_sig_chk[i] = sp2v_e'(sp2v_sig_chk_raw[i]); + end + + for (genvar s = 0; s < NumSharesKey; s++) begin : gen_key_init_we_shares + for (genvar i = 0; i < NumRegsKey; i++) begin : gen_key_init_we + assign key_init_we[s][i] = sp2v_sig_chk[s * NumRegsKey + i]; + end + end + for (genvar i = 0; i < NumSlicesCtr; i++) begin : gen_iv_we + assign iv_we[i] = sp2v_sig_chk[NumSharesKey * NumRegsKey + i]; + end + assign data_in_prev_we = sp2v_sig_chk[NumSharesKey * NumRegsKey + NumSlicesCtr + 0]; + assign data_out_we = sp2v_sig_chk[NumSharesKey * NumRegsKey + NumSlicesCtr + 1]; + + // Collect encoding errors. + // We instantiate the checker modules as close as possible to where the sparsely encoded signals + // are used. Here, we collect also encoding errors detected in other places of the core. + assign sp_enc_err_d = |sp2v_sig_err; + + // We need to register the collected error signal to avoid circular loops in the core controller + // related to iv_we and data_out_we. + always_ff @(posedge clk_i or negedge rst_ni) begin : reg_sp_enc_err + if (!rst_ni) begin + sp_enc_err_q <= 1'b0; + end else if (sp_enc_err_d) begin + sp_enc_err_q <= 1'b1; + end + end + + ///////////// + // Outputs // + ///////////// + + always_ff @(posedge clk_i or negedge rst_ni) begin : data_out_reg + if (!rst_ni) begin + data_out_q <= '0; + end else if (data_out_we == SP2V_HIGH) begin + data_out_q <= data_out_d; + end + end + + always_comb begin : key_reg_put + for (int i = 0; i < NumRegsKey; i++) begin + hw2reg.key_share0[i].d = key_init_q[0][i]; + hw2reg.key_share1[i].d = key_init_q[1][i]; + end + end + + always_comb begin : iv_reg_put + for (int i = 0; i < NumRegsIv; i++) begin + // Software updates IV in chunks of 32 bits. Internally, the counter updates SliceSizeCtr + // bits at a time. + hw2reg.iv[i].d = {iv_q[2 * i + 1], iv_q[2 * i]}; + end + end + + always_comb begin : data_out_put + for (int i = 0; i < NumRegsData; i++) begin + hw2reg.data_out[i].d = data_out_q[i]; + end + end + + //////////// + // Alerts // + //////////// + + // Should fatal alerts clear the status register? + assign clear_on_fatal = ClearStatusOnFatalAlert ? alert_fatal_o : 1'b0; + + // Recoverable alert conditions are signaled as a single alert event. + assign ctrl_err_update = ctrl_reg_err_update | shadowed_update_err_i | ctrl_gcm_reg_err_update; + assign alert_recov_o = ctrl_err_update; + + // The recoverable alert is observable via status register until the AES operation is restarted + // by re-writing the Control Register. Fatal alerts clear all other bits in the status register. + assign hw2reg.status.alert_recov_ctrl_update_err.d = ctrl_err_update & ~clear_on_fatal; + assign hw2reg.status.alert_recov_ctrl_update_err.de = ctrl_err_update | ctrl_we | clear_on_fatal; + + // Fatal alert conditions need to remain asserted until reset. + assign ctrl_err_storage_d = + ctrl_reg_err_storage | shadowed_storage_err_i | ctrl_gcm_reg_err_storage; + always_ff @(posedge clk_i or negedge rst_ni) begin : ctrl_err_storage_reg + if (!rst_ni) begin + ctrl_err_storage_q <= 1'b0; + end else if (ctrl_err_storage_d) begin + ctrl_err_storage_q <= 1'b1; + end + end + assign ctrl_err_storage = ctrl_err_storage_d | ctrl_err_storage_q; + + // Collect fatal alert signals. + assign alert_fatal_o = ctrl_err_storage | + ctr_alert | + cipher_alert | + ghash_alert | + ctrl_alert | + intg_err_alert_i; + + // Make the fatal alert observable via status register. + assign hw2reg.status.alert_fatal_fault.d = alert_fatal_o; + assign hw2reg.status.alert_fatal_fault.de = alert_fatal_o; + + // Unused alert signals + logic unused_alert_signals; + assign unused_alert_signals = ^reg2hw.alert_test; + + // Unused inputs + logic unused_idle; + assign unused_idle = reg2hw.status.idle.q; + + //////////////// + // Assertions // + //////////////// + + // Create a lint error to reduce the risk of accidentally disabling the masking. + `CALIPTRA_ASSERT_STATIC_LINT_ERROR(AesCoreSecMaskingNonDefault, SecMasking == 1) + + // Selectors must be known/valid + `CALIPTRA_ASSERT(AesModeValid, !ctrl_err_storage |-> aes_mode_q inside { + AES_ECB, + AES_CBC, + AES_CFB, + AES_OFB, + AES_CTR, + AES_GCM, + AES_NONE + }) + `CALIPTRA_ASSERT(AesOpValid, !ctrl_err_storage |-> aes_op_q inside { + AES_ENC, + AES_DEC + }) + + // Check parameters + `CALIPTRA_ASSERT_INIT(AesNumSlicesCtr, NumSlicesCtr == 8) + + // Signals used for assertions only. + logic [3:0][31:0] state_done_transposed, unused_state_done_transposed; + if (!SecMasking) begin : gen_state_done_transposed_unmasked + assign state_done_transposed = aes_transpose(state_done[0]); + end else begin : gen_state_done_transposed_masked + assign state_done_transposed = aes_transpose(state_done[0] ^ state_done[1]); + end + assign unused_state_done_transposed = state_done_transposed; + + // Ensure that upon local escalation of any of the FSMs, no intermediate state is released from + // the cipher core into the software readable output data or IV registers. + `CALIPTRA_ASSERT(AesSecCmDataRegLocalEscDataOut, $changed(data_out_q) && alert_fatal_o && + ($past(cipher_crypt, 2) == SP2V_HIGH || $past(cipher_crypt_busy, 2) == SP2V_HIGH) |=> + ($past(data_out_q) != $past(state_done_transposed, 2)) && + ($past(data_out_q) != $past(state_done_transposed, 2) ^ $past(iv_q, 2)) && + ($past(data_out_q) != $past(state_done_transposed, 2) ^ $past(data_in_prev_q, 2))) + + `CALIPTRA_ASSERT(AesSecCmDataRegLocalEscIv, $changed(iv_q) && alert_fatal_o && + ($past(cipher_crypt, 2) == SP2V_HIGH || $past(cipher_crypt_busy, 2) == SP2V_HIGH) |=> + ($past(iv_q) != $past(state_done_transposed, 2)) && + ($past(iv_q) != $past(state_done_transposed, 2) ^ $past(iv_q, 2)) && + ($past(iv_q) != $past(state_done_transposed, 2) ^ $past(data_in_prev_q, 2))) + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/aes_cov_bind.sv b/designs/Caliptra/src/caliptra-rtl/aes_cov_bind.sv new file mode 100644 index 0000000..c1b4ca7 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/aes_cov_bind.sv @@ -0,0 +1,25 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. + + +module aes_cov_bind; + `ifdef FCOV + bind aes_clp_wrapper aes_cov_if #( + .AHB_ADDR_WIDTH(`CALIPTRA_SLAVE_ADDR_WIDTH(`CALIPTRA_SLAVE_SEL_AES)), + .AHB_DATA_WIDTH(`CALIPTRA_AHB_HDATA_SIZE), + .CIF_DATA_WIDTH(32) // FIXME hardcoded value? + ) + i_aes_cov_if (.*); + `endif +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/aes_cov_if.sv b/designs/Caliptra/src/caliptra-rtl/aes_cov_if.sv new file mode 100644 index 0000000..7606496 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/aes_cov_if.sv @@ -0,0 +1,195 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. + + + +`ifndef VERILATOR + +interface aes_cov_if + import aes_pkg::*; + import kv_defines_pkg::*; + import aes_clp_reg_pkg::*; + #( + parameter AHB_DATA_WIDTH = 32, + parameter AHB_ADDR_WIDTH = 32, + parameter CIF_DATA_WIDTH = 32, + localparam CIF_DATA_NUM_BYTES = CIF_DATA_WIDTH / 8 + ) + ( + // Clock and reset. + input wire clk, + input wire reset_n, + input wire cptra_pwrgood, + + input logic [AHB_ADDR_WIDTH-1:0] haddr_i, + input logic [AHB_DATA_WIDTH-1:0] hwdata_i, + input logic hsel_i, + input logic hwrite_i, + input logic hready_i, + input logic [1:0] htrans_i, + input logic [2:0] hsize_i, + + input logic hresp_o, + input logic hreadyout_o, + input logic [AHB_DATA_WIDTH-1:0] hrdata_o, + + // OCP LOCK + input logic ocp_lock_in_progress, + input logic [15:0] key_release_key_size, + + // status signals + input logic input_ready_o, + input logic output_valid_o, + input logic status_idle_o, + + // DMA CIF + input logic dma_req_dv, + input logic dma_req_write, + input logic [AHB_ADDR_WIDTH-1 : 0] dma_req_addr, + input logic [CIF_DATA_WIDTH-1 : 0] dma_req_wdata, + input logic dma_req_hold, + input logic dma_req_error, + input logic [CIF_DATA_WIDTH-1 : 0] dma_req_rdata, + + // kv interface + input kv_read_t kv_read, + input kv_rd_resp_t kv_rd_resp, + input kv_write_t kv_write, + input kv_wr_resp_t kv_wr_resp, + + input logic busy_o, + + // Interrupt + input logic error_intr, + input logic notif_intr, + input logic debugUnlock_or_scan_mode_switch, + + // Internal signals in aes_clp_wrapper + input kv_write_ctrl_reg_t kv_write_ctrl_reg, + input logic [KV_ENTRY_ADDR_W-1:0] kv_key_present_slot, + input kv_write_filter_metrics_t kv_write_metrics, + input caliptra2aes_t caliptra2aes, + input aes2caliptra_t aes2caliptra + ); + + covergroup aes_clp_wrapper_cov_grp @(posedge clk); + reset_n_cp: coverpoint reset_n; + cptra_pwrgood_cp: coverpoint cptra_pwrgood; + + haddr_i_cp: coverpoint haddr_i; + hwdata_i_cp: coverpoint hwdata_i; + hsel_i_cp: coverpoint hsel_i; + hwrite_i_cp: coverpoint hwrite_i; + hready_i_cp: coverpoint hready_i; + htrans_i_cp: coverpoint htrans_i; + hsize_i_cp: coverpoint hsize_i; + + hresp_o_cp: coverpoint hresp_o; + hreadyout_o_cp: coverpoint hreadyout_o; + hrdata_o_cp: coverpoint hrdata_o; + + // OCP LOCK + ocp_lock_in_progress_cp: coverpoint ocp_lock_in_progress; + key_release_key_size_cp: coverpoint key_release_key_size { + bins zero = {0}; + bins lt_64bytes = {[1:63]}; + bins eq_64bytes = {64}; + bins gt_64bytes = {[65:65535]}; + } + + // status signals + input_ready_o_cp: coverpoint input_ready_o; + output_valid_o_cp: coverpoint output_valid_o; + status_idle_o_cp: coverpoint status_idle_o; + + // DMA CIF + dma_req_dv_cp: coverpoint dma_req_dv; + dma_req_write_cp: coverpoint dma_req_write; + dma_req_addr_cp: coverpoint dma_req_addr; + dma_req_wdata_cp: coverpoint dma_req_wdata; + dma_req_hold_cp: coverpoint dma_req_hold; + dma_req_error_cp: coverpoint dma_req_error; + dma_req_rdata_cp: coverpoint dma_req_rdata; + + // kv interface + kv_read_read_entry_cp: coverpoint kv_read.read_entry; + kv_read_read_offset_cp: coverpoint kv_read.read_offset; + kv_rd_resp_error_cp: coverpoint kv_rd_resp.error; + kv_rd_resp_last_cp: coverpoint kv_rd_resp.last; + kv_rd_resp_read_data_cp: coverpoint kv_rd_resp.read_data; + kv_write_write_en_cp: coverpoint kv_write.write_en; + kv_write_write_entry_cp: coverpoint kv_write.write_entry; + kv_write_write_offset_cp: coverpoint kv_write.write_offset; + kv_write_write_data_cp: coverpoint kv_write.write_data; + kv_write_write_dest_valid_cp: coverpoint kv_write.write_dest_valid; + kv_wr_resp_error_cp: coverpoint kv_wr_resp.error; + + busy_o_cp: coverpoint busy_o; + + // Interrupt + error_intr_cp: coverpoint error_intr; + notif_intr_cp: coverpoint notif_intr; + debugUnlock_or_scan_mode_switch_cp: coverpoint debugUnlock_or_scan_mode_switch; + endgroup + + + // KV read interface + // KV write interface + // OCP LOCK flows + // * MEK decryption + covergroup aes_ocp_lock_flow_grp @(posedge clk); + ocp_lock_in_progress_cp: coverpoint ocp_lock_in_progress; + key_is_kv_cp: coverpoint busy_o && aes_inst.hw2reg.ctrl_shadowed.sideload.d; + key_is_kv_rt_obf_key_cp: coverpoint busy_o && aes_inst.hw2reg.ctrl_shadowed.sideload.d && (kv_key_present_slot == OCP_LOCK_RT_OBF_KEY_KV_SLOT); + op_is_decrypt_cp: coverpoint busy_o && (aes_op_e'(aes_inst.hw2reg.ctrl_shadowed.operation.d) == AES_DEC); + mode_is_ecb_cp: coverpoint busy_o && (aes_mode_e'(aes_inst.hw2reg.ctrl_shadowed.mode.d) == AES_ECB); + output_is_kv_cp: coverpoint busy_o && caliptra2aes.kv_en; + output_is_kv_mek_slot_cp: coverpoint busy_o && caliptra2aes.kv_en && (kv_write_ctrl_reg.write_entry == OCP_LOCK_KEY_RELEASE_KV_SLOT); + + kv_read_entry_0_cp: coverpoint {kv_write_metrics.kv_data0_present, kv_write_metrics.kv_data0_entry} + iff (busy_o) { + bins fw = {[0:23]}; //{1'b0, [0:$]}; + bins lower_slots = {[32:47]}; //{1'b1, [0:15]}; + bins upper_slots = {[48:54]}; //{1'b1, [16:22]}; + bins slot_23 = {55}; //{1'b1, 23}; + } + + kv_write_entry_cp: coverpoint {kv_write_ctrl_reg.write_en, kv_write_metrics.kv_write_entry} + iff (busy_o) { + bins fw = {[0:23]}; //{1'b0, [0:$]}; + bins lower_slots = {[32:47]}; //{1'b1, [0:15]}; + bins upper_slots = {[48:54]}; //{1'b1, [16:22]}; + bins slot_23 = {55}; //{1'b1, 23}; + } + + // Crosses + ocp_lock_flow_mek_dec_X: cross ocp_lock_in_progress_cp, + key_is_kv_rt_obf_key_cp, + op_is_decrypt_cp, + mode_is_ecb_cp, + output_is_kv_mek_slot_cp; + ocp_lock_flow_kv_write_ctx_clear_X: cross aes2caliptra.kv_data_out_valid, caliptra2aes.clear_secrets, aes_inst.reg2hw_caliptra.trigger.data_out_clear.q; + ocp_lock_X_kv_entry: cross ocp_lock_in_progress_cp, kv_write_entry_cp, kv_read_entry_0_cp; + endgroup + + aes_clp_wrapper_cov_grp aes_clp_wrapper_cov_grp1 = new(); + aes_ocp_lock_flow_grp aes_ocp_lock_flow_grp1 = new(); + + + +endinterface + + +`endif + diff --git a/designs/Caliptra/src/caliptra-rtl/aes_ctr.sv b/designs/Caliptra/src/caliptra-rtl/aes_ctr.sv new file mode 100644 index 0000000..f07b55a --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/aes_ctr.sv @@ -0,0 +1,217 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// AES counter for CTR mode +// +// This module uses one counter with a width of SliceSizeCtr to iteratively increment the 128-bit +// counter value. + +module aes_ctr import aes_pkg::*; +( + input logic clk_i, + input logic rst_ni, + + input sp2v_e inc32_i, + input sp2v_e incr_i, + output sp2v_e ready_o, + output logic alert_o, + + input logic [NumSlicesCtr-1:0][SliceSizeCtr-1:0] ctr_i, + output logic [NumSlicesCtr-1:0][SliceSizeCtr-1:0] ctr_o, + output sp2v_e [NumSlicesCtr-1:0] ctr_we_o +); + + // Reverse byte order - unrelated to NumSlicesCtr and SliceSizeCtr + function automatic logic [15:0][7:0] aes_rev_order_byte(logic [15:0][7:0] in); + logic [15:0][7:0] out; + for (int i = 0; i < 16; i++) begin + out[i] = in[15-i]; + end + return out; + endfunction + + // Reverse sp2v order + function automatic sp2v_e [NumSlicesCtr-1:0] aes_rev_order_sp2v(sp2v_e [NumSlicesCtr-1:0] in); + sp2v_e [NumSlicesCtr-1:0] out; + for (int i = 0; i < NumSlicesCtr; i++) begin + out[i] = in[NumSlicesCtr - 1 - i]; + end + return out; + endfunction + + // Signals + logic [SliceIdxWidth-1:0] ctr_slice_idx; + + logic [NumSlicesCtr-1:0][SliceSizeCtr-1:0] ctr_i_rev; // 8 times 2 bytes + logic [NumSlicesCtr-1:0][SliceSizeCtr-1:0] ctr_o_rev; // 8 times 2 bytes + sp2v_e [NumSlicesCtr-1:0] ctr_we_o_rev; + sp2v_e ctr_we; + + logic [SliceSizeCtr-1:0] ctr_i_slice; + logic [SliceSizeCtr-1:0] ctr_o_slice; + + sp2v_e inc32; + logic inc32_err; + sp2v_e incr; + logic incr_err; + logic sp_enc_err; + logic mr_err; + + // Sparsified FSM signals. These are needed for connecting the individual bits of the Sp2V + // signals to the single-rail FSMs. + logic [Sp2VWidth-1:0] sp_inc32; + logic [Sp2VWidth-1:0] sp_incr; + logic [Sp2VWidth-1:0] sp_ready; + logic [Sp2VWidth-1:0] sp_ctr_we; + + // Multi-rail signals. These are outputs of the single-rail FSMs and need combining. + logic [Sp2VWidth-1:0] mr_alert; + logic [Sp2VWidth-1:0][SliceIdxWidth-1:0] mr_ctr_slice_idx; + logic [Sp2VWidth-1:0] [SliceSizeCtr-1:0] mr_ctr_o_slice; + + //////////// + // Inputs // + //////////// + + // Reverse byte order + assign ctr_i_rev = aes_rev_order_byte(ctr_i); + + // SEC_CM: CTRL.SPARSE + // Check sparsely encoded inc32 and incr signals. + logic [Sp2VWidth-1:0] inc32_raw; + aes_sel_buf_chk #( + .Num ( Sp2VNum ), + .Width ( Sp2VWidth ), + .EnSecBuf ( 1'b0 ) + ) u_aes_inc32_buf_chk ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .sel_i ( inc32_i ), + .sel_o ( inc32_raw ), + .err_o ( inc32_err ) + ); + assign inc32 = sp2v_e'(inc32_raw); + + logic [Sp2VWidth-1:0] incr_raw; + aes_sel_buf_chk #( + .Num ( Sp2VNum ), + .Width ( Sp2VWidth ), + .EnSecBuf ( 1'b0 ) + ) u_aes_incr_buf_chk ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .sel_i ( incr_i ), + .sel_o ( incr_raw ), + .err_o ( incr_err ) + ); + assign incr = sp2v_e'(incr_raw); + + // Collect encoding errors. + assign sp_enc_err = inc32_err | incr_err; + + ///////////// + // Counter // + ///////////// + + // We do SliceSizeCtr bits at a time. + assign ctr_i_slice = ctr_i_rev[ctr_slice_idx]; + + ///////// + // FSM // + ///////// + + // Convert sp2v_e signals to sparsified inputs. + assign sp_inc32 = {inc32}; + assign sp_incr = {incr}; + + // SEC_CM: CTR.FSM.REDUN + // For every bit in the Sp2V signals, one separate rail is instantiated. The inputs and outputs + // of every rail are buffered to prevent aggressive synthesis optimizations. + for (genvar i = 0; i < Sp2VWidth; i++) begin : gen_fsm + if (SP2V_LOGIC_HIGH[i] == 1'b1) begin : gen_fsm_p + aes_ctr_fsm_p u_aes_ctr_fsm_i ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + + .inc32_i ( sp_inc32[i] ), // Sparsified + .incr_i ( sp_incr[i] ), // Sparsified + .ready_o ( sp_ready[i] ), // Sparsified + .sp_enc_err_i ( sp_enc_err ), + .mr_err_i ( mr_err ), + .alert_o ( mr_alert[i] ), // OR-combine + + .ctr_slice_idx_o ( mr_ctr_slice_idx[i] ), // OR-combine + .ctr_slice_i ( ctr_i_slice ), + .ctr_slice_o ( mr_ctr_o_slice[i] ), // OR-combine + .ctr_we_o ( sp_ctr_we[i] ) // Sparsified + ); + end else begin : gen_fsm_n + aes_ctr_fsm_n u_aes_ctr_fsm_i ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + + .inc32_ni ( sp_inc32[i] ), // Sparsified + .incr_ni ( sp_incr[i] ), // Sparsified + .ready_no ( sp_ready[i] ), // Sparsified + .sp_enc_err_i ( sp_enc_err ), + .mr_err_i ( mr_err ), + .alert_o ( mr_alert[i] ), // OR-combine + + .ctr_slice_idx_o ( mr_ctr_slice_idx[i] ), // OR-combine + .ctr_slice_i ( ctr_i_slice ), + .ctr_slice_o ( mr_ctr_o_slice[i] ), // OR-combine + .ctr_we_no ( sp_ctr_we[i] ) // Sparsified + ); + end + end + + // Convert sparsified outputs to sp2v_e type. + assign ready_o = sp2v_e'(sp_ready); + assign ctr_we = sp2v_e'(sp_ctr_we); + + // Combine single-bit FSM outputs. + // OR: One bit is sufficient to drive the corresponding output bit high. + assign alert_o = |mr_alert; + + // Combine multi-bit FSM outputs. We simply OR them together and compare the values + // to detect errors. + always_comb begin : combine_sparse_signals + ctr_slice_idx = '0; + ctr_o_slice = '0; + mr_err = 1'b0; + + for (int i = 0; i < Sp2VWidth; i++) begin + ctr_slice_idx |= mr_ctr_slice_idx[i]; + ctr_o_slice |= mr_ctr_o_slice[i]; + end + + for (int i = 0; i < Sp2VWidth; i++) begin + if (ctr_slice_idx != mr_ctr_slice_idx[i] || + ctr_o_slice != mr_ctr_o_slice[i]) begin + mr_err = 1'b1; + end + end + end + + ///////////// + // Outputs // + ///////////// + + // Combine input and counter output. + always_comb begin + ctr_o_rev = ctr_i_rev; + ctr_o_rev[ctr_slice_idx] = ctr_o_slice; + end + + // Generate the sliced write enable. + always_comb begin + ctr_we_o_rev = {NumSlicesCtr{SP2V_LOW}}; + ctr_we_o_rev[ctr_slice_idx] = ctr_we; + end + + // Reverse byte and bit order. + assign ctr_o = aes_rev_order_byte(ctr_o_rev); + assign ctr_we_o = aes_rev_order_sp2v(ctr_we_o_rev); + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/aes_ctr_fsm.sv b/designs/Caliptra/src/caliptra-rtl/aes_ctr_fsm.sv new file mode 100644 index 0000000..e09644d --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/aes_ctr_fsm.sv @@ -0,0 +1,130 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// AES counter FSM for CTR mode + +`include "caliptra_prim_assert.sv" + +module aes_ctr_fsm import aes_pkg::*; +( + input logic clk_i, + input logic rst_ni, + + input logic inc32_i, // Sparsify using multi-rail. + input logic incr_i, // Sparsify using multi-rail. + output logic ready_o, // Sparsify using multi-rail. + input logic sp_enc_err_i, + input logic mr_err_i, + output logic alert_o, + + output logic [SliceIdxWidth-1:0] ctr_slice_idx_o, + input logic [SliceSizeCtr-1:0] ctr_slice_i, + output logic [SliceSizeCtr-1:0] ctr_slice_o, + output logic ctr_we_o // Sparsify using multi-rail. +); + + // Signals + aes_ctr_e aes_ctr_ns, aes_ctr_cs; + logic [SliceIdxWidth-1:0] ctr_slice_idx_d, ctr_slice_idx_q; + logic [SliceIdxWidth-1:0] ctr_slice_idx_max; + logic ctr_carry_d, ctr_carry_q; + + logic [SliceSizeCtr:0] ctr_value; + + ///////////// + // Counter // + ///////////// + + // We do SliceSizeCtr bits at a time. + assign ctr_value = ctr_slice_i + {{(SliceSizeCtr-1){1'b0}}, ctr_carry_q}; + assign ctr_slice_o = ctr_value[SliceSizeCtr-1:0]; + + // Perform either inc128() or inc32() for GCM. + assign ctr_slice_idx_max = inc32_i ? SliceIdxWidth'(SliceIdxMaxInc32) : {SliceIdxWidth{1'b1}}; + + ///////////// + // Control // + ///////////// + + // FSM + always_comb begin : aes_ctr_fsm_comb + + // Outputs + ready_o = 1'b0; + ctr_we_o = 1'b0; + alert_o = 1'b0; + + // FSM + aes_ctr_ns = aes_ctr_cs; + ctr_slice_idx_d = ctr_slice_idx_q; + ctr_carry_d = ctr_carry_q; + + unique case (aes_ctr_cs) + CTR_IDLE: begin + ready_o = 1'b1; + if (incr_i == 1'b1) begin + // Initialize slice index and carry bit. + ctr_slice_idx_d = '0; + ctr_carry_d = 1'b1; + aes_ctr_ns = CTR_INCR; + end + end + + CTR_INCR: begin + // Increment slice index. + ctr_slice_idx_d = ctr_slice_idx_q + SliceIdxWidth'(1); + ctr_carry_d = ctr_slice_idx_q >= ctr_slice_idx_max ? 1'b0 : ctr_value[SliceSizeCtr]; + ctr_we_o = 1'b1; + + if (ctr_slice_idx_q == {SliceIdxWidth{1'b1}}) begin + aes_ctr_ns = CTR_IDLE; + end + end + + CTR_ERROR: begin + // SEC_CM: CTR.FSM.LOCAL_ESC + // Terminal error state + alert_o = 1'b1; + end + + // We should never get here. If we do (e.g. via a malicious + // glitch), error out immediately. + default: begin + aes_ctr_ns = CTR_ERROR; + alert_o = 1'b1; + end + endcase + + // Unconditionally jump into the terminal error state in case an error is detected. + if (sp_enc_err_i || mr_err_i) begin + aes_ctr_ns = CTR_ERROR; + end + end + + // Registers + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + ctr_slice_idx_q <= '0; + ctr_carry_q <= '0; + end else begin + ctr_slice_idx_q <= ctr_slice_idx_d; + ctr_carry_q <= ctr_carry_d; + end + end + + // SEC_CM: CTR.FSM.SPARSE + `CALIPTRA_PRIM_FLOP_SPARSE_FSM(u_state_regs, aes_ctr_ns, aes_ctr_cs, aes_ctr_e, CTR_IDLE) + + // Forward slice index. + assign ctr_slice_idx_o = ctr_slice_idx_q; + + //////////////// + // Assertions // + //////////////// + `CALIPTRA_ASSERT(AesCtrStateValid, !alert_o |-> aes_ctr_cs inside { + CTR_IDLE, + CTR_INCR + }) + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/aes_ctr_fsm_n.sv b/designs/Caliptra/src/caliptra-rtl/aes_ctr_fsm_n.sv new file mode 100644 index 0000000..8df0ae7 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/aes_ctr_fsm_n.sv @@ -0,0 +1,146 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// AES counter FSM for CTR mode +// +// This module contains the AES counter FSM operating on and producing the negated values of +// important control signals. This is achieved by: +// - instantiating the regular AES counter FSM operating on and producing the positive values of +// these signals, and +// - inverting these signals between the regular FSM and the caliptra_prim_buf synthesis barriers. +// Synthesis tools will then push the inverters into the actual FSM. + +module aes_ctr_fsm_n import aes_pkg::*; +( + input logic clk_i, + input logic rst_ni, + + input logic inc32_ni, // Sparsify using multi-rail. + input logic incr_ni, // Sparsify using multi-rail. + output logic ready_no, // Sparsify using multi-rail. + input logic sp_enc_err_i, + input logic mr_err_i, + output logic alert_o, + + output logic [SliceIdxWidth-1:0] ctr_slice_idx_o, + input logic [SliceSizeCtr-1:0] ctr_slice_i, + output logic [SliceSizeCtr-1:0] ctr_slice_o, + output logic ctr_we_no // Sparsify using multi-rail. +); + + ///////////////////// + // Input Buffering // + ///////////////////// + + localparam int NumInBufBits = $bits({ + inc32_ni, + incr_ni, + sp_enc_err_i, + mr_err_i, + ctr_slice_i + }); + + logic [NumInBufBits-1:0] in, in_buf; + + assign in = { + inc32_ni, + incr_ni, + sp_enc_err_i, + mr_err_i, + ctr_slice_i + }; + + // This primitive is used to place a size-only constraint on the + // buffers to act as a synthesis optimization barrier. + caliptra_prim_buf #( + .Width(NumInBufBits) + ) u_caliptra_prim_buf_in ( + .in_i(in), + .out_o(in_buf) + ); + + logic inc32_n; + logic incr_n; + logic sp_enc_err; + logic mr_err; + logic [SliceSizeCtr-1:0] ctr_i_slice; + + assign {inc32_n, + incr_n, + sp_enc_err, + mr_err, + ctr_i_slice} = in_buf; + + // Intermediate output signals + logic ready; + logic alert; + logic [SliceIdxWidth-1:0] ctr_slice_idx; + logic [SliceSizeCtr-1:0] ctr_o_slice; + logic ctr_we; + + ///////////////// + // Regular FSM // + ///////////////// + + // The regular FSM operates on and produces the positive values of important control signals. + // Invert *_n input signals here to get the positive values for the regular FSM. To obtain the + // negated outputs, important output signals are inverted further below. Thanks to the caliptra_prim_buf + // synthesis optimization barriers, tools will push the inverters into the regular FSM. + aes_ctr_fsm u_aes_ctr_fsm ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + + .inc32_i ( ~inc32_n ), // Invert for regular FSM. + .incr_i ( ~incr_n ), // Invert for regular FSM. + .ready_o ( ready ), // Invert below for negated output. + .sp_enc_err_i ( sp_enc_err ), + .mr_err_i ( mr_err ), + .alert_o ( alert ), + + .ctr_slice_idx_o ( ctr_slice_idx ), + .ctr_slice_i ( ctr_i_slice ), + .ctr_slice_o ( ctr_o_slice ), + .ctr_we_o ( ctr_we ) // Invert below for negated output. + ); + + ////////////////////// + // Output Buffering // + ////////////////////// + + localparam int NumOutBufBits = $bits({ + ready_no, + alert_o, + ctr_slice_idx_o, + ctr_slice_o, + ctr_we_no + }); + + logic [NumOutBufBits-1:0] out, out_buf; + + // Important output control signals need to be inverted here. Synthesis tools will push the + // inverters back into the regular FSM. + assign out = { + ~ready, + alert, + ctr_slice_idx, + ctr_o_slice, + ~ctr_we + }; + + // This primitive is used to place a size-only constraint on the + // buffers to act as a synthesis optimization barrier. + caliptra_prim_buf #( + .Width(NumOutBufBits) + ) u_caliptra_prim_buf_out ( + .in_i(out), + .out_o(out_buf) + ); + + assign {ready_no, + alert_o, + ctr_slice_idx_o, + ctr_slice_o, + ctr_we_no} = out_buf; + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/aes_ctr_fsm_p.sv b/designs/Caliptra/src/caliptra-rtl/aes_ctr_fsm_p.sv new file mode 100644 index 0000000..cfa0f38 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/aes_ctr_fsm_p.sv @@ -0,0 +1,136 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// AES counter FSM for CTR mode +// +// This module contains the AES counter FSM operating on and producing the positive values of +// important control signals. + +module aes_ctr_fsm_p import aes_pkg::*; +( + input logic clk_i, + input logic rst_ni, + + input logic inc32_i, // Sparsify + input logic incr_i, // Sparsify + output logic ready_o, // Sparsify + input logic sp_enc_err_i, + input logic mr_err_i, + output logic alert_o, + + output logic [SliceIdxWidth-1:0] ctr_slice_idx_o, + input logic [SliceSizeCtr-1:0] ctr_slice_i, + output logic [SliceSizeCtr-1:0] ctr_slice_o, + output logic ctr_we_o // Sparsify +); + + ///////////////////// + // Input Buffering // + ///////////////////// + + localparam int NumInBufBits = $bits({ + inc32_i, + incr_i, + sp_enc_err_i, + mr_err_i, + ctr_slice_i + }); + + logic [NumInBufBits-1:0] in, in_buf; + + assign in = { + inc32_i, + incr_i, + sp_enc_err_i, + mr_err_i, + ctr_slice_i + }; + + // This primitive is used to place a size-only constraint on the + // buffers to act as a synthesis optimization barrier. + caliptra_prim_buf #( + .Width(NumInBufBits) + ) u_caliptra_prim_buf_in ( + .in_i(in), + .out_o(in_buf) + ); + + logic inc32; + logic incr; + logic sp_enc_err; + logic mr_err; + logic [SliceSizeCtr-1:0] ctr_i_slice; + + assign {inc32, + incr, + sp_enc_err, + mr_err, + ctr_i_slice} = in_buf; + + // Intermediate output signals + logic ready; + logic alert; + logic [SliceIdxWidth-1:0] ctr_slice_idx; + logic [SliceSizeCtr-1:0] ctr_o_slice; + logic ctr_we; + + ///////////////// + // Regular FSM // + ///////////////// + + aes_ctr_fsm u_aes_ctr_fsm ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + + .inc32_i ( inc32 ), + .incr_i ( incr ), + .ready_o ( ready ), + .sp_enc_err_i ( sp_enc_err ), + .mr_err_i ( mr_err ), + .alert_o ( alert ), + + .ctr_slice_idx_o ( ctr_slice_idx ), + .ctr_slice_i ( ctr_i_slice ), + .ctr_slice_o ( ctr_o_slice ), + .ctr_we_o ( ctr_we ) + ); + + ////////////////////// + // Output Buffering // + ////////////////////// + + localparam int NumOutBufBits = $bits({ + ready_o, + alert_o, + ctr_slice_idx_o, + ctr_slice_o, + ctr_we_o + }); + + logic [NumOutBufBits-1:0] out, out_buf; + + assign out = { + ready, + alert, + ctr_slice_idx, + ctr_o_slice, + ctr_we + }; + + // This primitive is used to place a size-only constraint on the + // buffers to act as a synthesis optimization barrier. + caliptra_prim_buf #( + .Width(NumOutBufBits) + ) u_caliptra_prim_buf_out ( + .in_i(out), + .out_o(out_buf) + ); + + assign {ready_o, + alert_o, + ctr_slice_idx_o, + ctr_slice_o, + ctr_we_o} = out_buf; + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/aes_ctrl_gcm_reg_shadowed.sv b/designs/Caliptra/src/caliptra-rtl/aes_ctrl_gcm_reg_shadowed.sv new file mode 100644 index 0000000..5764f27 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/aes_ctrl_gcm_reg_shadowed.sv @@ -0,0 +1,215 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// AES Galois/Counter Mode (GCM) shadowed control register +// +// This module implements the shadowed AES GCM control register. The main differences compared +// to implementing the register as part of the auto-generated aes_reg_top.sv are: +// +// 1. The hardware can block updates to the GCM control register from software. +// Whenever the module is busy, GCM control register writes are ignored. +// 2. Invalid values written by software are resolved to valid configurations. + +`include "caliptra_prim_assert.sv" + +module aes_ctrl_gcm_reg_shadowed + import aes_pkg::*; + import aes_reg_pkg::*; +#( + parameter bit AESGCMEnable = 1 +) ( + input logic clk_i, + input logic rst_ni, + input logic rst_shadowed_ni, + // Main control + output logic qe_o, // software wants to write + input logic we_i, // hardware grants software write + output logic phase_o, + input logic init_done_i, + input logic first_block_i, + output gcm_phase_e gcm_phase_o, + output logic [4:0] num_valid_bytes_o, + + // Alerts + output logic err_update_o, + output logic err_storage_o, + + // Bus interface + input aes_reg2hw_ctrl_gcm_shadowed_reg_t reg2hw_ctrl_gcm_i, + output aes_hw2reg_ctrl_gcm_shadowed_reg_t hw2reg_ctrl_gcm_o +); + + // Signals + logic phase_gcm_phase; + logic phase_num_valid_bytes; + logic err_update_gcm_phase; + logic err_update_num_valid_bytes; + logic err_storage_gcm_phase; + logic err_storage_num_valid_bytes; + + // Get and forward write enable. Writes are only allowed if the module is idle. + assign qe_o = reg2hw_ctrl_gcm_i.phase.qe & reg2hw_ctrl_gcm_i.num_valid_bytes.qe; + + if (AESGCMEnable) begin : gen_ctrl_gcm_reg_shadowed + ctrl_gcm_reg_t ctrl_gcm_wd; + gcm_phase_e gcm_phase_reg_if, gcm_phase; + logic [4:0] num_valid_bytes; + + // Get and resolve values from register interface. + assign gcm_phase_reg_if = gcm_phase_e'(reg2hw_ctrl_gcm_i.phase.q); + always_comb begin : gcm_phase_get + // Resolve unsupported input values. + unique case (gcm_phase_reg_if) + GCM_INIT: gcm_phase = GCM_INIT; + GCM_RESTORE: gcm_phase = GCM_RESTORE; + GCM_AAD: gcm_phase = GCM_AAD; + GCM_TEXT: gcm_phase = GCM_TEXT; + GCM_SAVE: gcm_phase = GCM_SAVE; + GCM_TAG: gcm_phase = GCM_TAG; + default: gcm_phase = GCM_INIT; // Unsupported values are mapped to GCM_INIT. + endcase + + // Only a subset of next phase transitions are allowed. + unique case (gcm_phase_o) + GCM_INIT: begin + gcm_phase = init_done_i && + (gcm_phase == GCM_RESTORE || + gcm_phase == GCM_AAD || + gcm_phase == GCM_TEXT || + gcm_phase == GCM_TAG) ? gcm_phase : gcm_phase_o; + end + + GCM_RESTORE: begin + gcm_phase = gcm_phase == GCM_INIT || + gcm_phase == GCM_AAD || + gcm_phase == GCM_TEXT ? gcm_phase : gcm_phase_o; + end + + GCM_AAD: begin + gcm_phase = gcm_phase == GCM_INIT || + gcm_phase == GCM_TEXT || + gcm_phase == GCM_SAVE && !first_block_i || + gcm_phase == GCM_TAG ? gcm_phase : gcm_phase_o; + end + + GCM_TEXT: begin + gcm_phase = gcm_phase == GCM_INIT || + gcm_phase == GCM_SAVE && !first_block_i || + gcm_phase == GCM_TAG ? gcm_phase : gcm_phase_o; + end + + GCM_SAVE: begin + gcm_phase = gcm_phase == GCM_INIT ? gcm_phase : gcm_phase_o; + end + + GCM_TAG: begin + gcm_phase = gcm_phase == GCM_INIT ? gcm_phase : gcm_phase_o; + end + + default: begin + gcm_phase = gcm_phase_o; // If we end up in an unspported value (which should never + // happen), keep it. + end + endcase + end + assign ctrl_gcm_wd.phase = gcm_phase; + + assign num_valid_bytes = reg2hw_ctrl_gcm_i.num_valid_bytes.q; + // Unsupported values are mapped to 16. + assign ctrl_gcm_wd.num_valid_bytes = + ((num_valid_bytes == 5'd0) || (num_valid_bytes > 5'd16)) ? 5'd16 : num_valid_bytes; + + // SEC_CM: GCM.CONFIG.SHADOW + // Instantiate one shadowed register primitive per field. An update error in a field should + // only prevent the update of the affected field. + caliptra_prim_subreg_shadow #( + .DW ($bits(gcm_phase_e)), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessWO), + .RESVAL (AES_CTRL_GCM_SHADOWED_PHASE_RESVAL) + ) u_ctrl_gcm_reg_shadowed_phase ( + .clk_i, + .rst_ni, + .rst_shadowed_ni, + .re (reg2hw_ctrl_gcm_i.phase.re), + .we (we_i), + .wd ({ctrl_gcm_wd.phase}), + .de (1'b0), + .d ('0), + .qe (), + .q (hw2reg_ctrl_gcm_o.phase.d), + .qs (), + .ds (), + .phase (phase_gcm_phase), + .err_update (err_update_gcm_phase), + .err_storage(err_storage_gcm_phase) + ); + + caliptra_prim_subreg_shadow #( + .DW (5), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessWO), + .RESVAL (AES_CTRL_GCM_SHADOWED_NUM_VALID_BYTES_RESVAL) + ) u_ctrl_gcm_reg_shadowed_num_valid_bytes ( + .clk_i, + .rst_ni, + .rst_shadowed_ni, + .re (reg2hw_ctrl_gcm_i.num_valid_bytes.re), + .we (we_i), + .wd ({ctrl_gcm_wd.num_valid_bytes}), + .de (1'b0), + .d ('0), + .qe (), + .q (hw2reg_ctrl_gcm_o.num_valid_bytes.d), + .qs (), + .ds (), + .phase (phase_num_valid_bytes), + .err_update (err_update_num_valid_bytes), + .err_storage(err_storage_num_valid_bytes) + ); + end else begin : gen_no_ctrl_gcm_reg_shadowed + // Tie off unused inputs. + logic unused_ctrl_gcm; + assign unused_ctrl_gcm = ^{reg2hw_ctrl_gcm_i.phase.re, + reg2hw_ctrl_gcm_i.phase.q, + reg2hw_ctrl_gcm_i.num_valid_bytes.re, + reg2hw_ctrl_gcm_i.num_valid_bytes.q}; + logic unused_we; + logic unused_init_done; + logic unused_first_block; + assign unused_we = we_i; + assign unused_init_done = init_done_i; + assign unused_first_block = first_block_i; + + logic unused_clk; + logic unused_rst; + logic unused_rst_shadowed; + assign unused_clk = clk_i; + assign unused_rst = rst_ni; + assign unused_rst_shadowed = rst_shadowed_ni; + + // Tie off control signals. + assign hw2reg_ctrl_gcm_o.phase.d = {GCM_INIT}; + assign hw2reg_ctrl_gcm_o.num_valid_bytes.d = 5'd16; + assign phase_gcm_phase = 1'b1; + assign phase_num_valid_bytes = 1'b1; + + // Tie off error signals. + assign err_update_gcm_phase = 1'b0; + assign err_update_num_valid_bytes = 1'b0; + assign err_storage_gcm_phase = 1'b0; + assign err_storage_num_valid_bytes = 1'b0; + end + + // Collect phase signals. + assign phase_o = phase_gcm_phase | phase_num_valid_bytes; + + // Collect alerts. + assign err_update_o = err_update_gcm_phase | err_update_num_valid_bytes; + assign err_storage_o = err_storage_gcm_phase | err_storage_num_valid_bytes; + + // Generate shorter references. + // Doing that here as opposed to in aes_core avoids several Verilator lint errors. + assign gcm_phase_o = gcm_phase_e'(hw2reg_ctrl_gcm_o.phase.d); + assign num_valid_bytes_o = hw2reg_ctrl_gcm_o.num_valid_bytes.d; + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/aes_ctrl_reg_shadowed.sv b/designs/Caliptra/src/caliptra-rtl/aes_ctrl_reg_shadowed.sv new file mode 100644 index 0000000..17f019a --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/aes_ctrl_reg_shadowed.sv @@ -0,0 +1,277 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// AES shadowed control register +// +// This module implements the AES shadowed control register. The main differences compared +// to implementing the register as part of the auto-generated aes_reg_top.sv are: +// +// 1. The hardware can block updates to the control register from software. +// Whenever the module is busy, control register writes are ignored. +// 2. Invalid values written by software are resolved to valid configurations. + +`include "caliptra_prim_assert.sv" + +module aes_ctrl_reg_shadowed + import aes_pkg::*; + import aes_reg_pkg::*; +#( + parameter bit AES192Enable = 1, + parameter bit AESGCMEnable = 1 +) ( + input logic clk_i, + input logic rst_ni, + input logic rst_shadowed_ni, + // Main control + output logic qe_o, // software wants to write + input logic we_i, // hardware grants software write + output logic phase_o, + output aes_op_e operation_o, + output aes_mode_e mode_o, + output key_len_e key_len_o, + output logic sideload_o, + output prs_rate_e prng_reseed_rate_o, + output logic manual_operation_o, + + // Alerts + output logic err_update_o, + output logic err_storage_o, + + // Bus interface + input aes_reg2hw_ctrl_shadowed_reg_t reg2hw_ctrl_i, + output aes_hw2reg_ctrl_shadowed_reg_t hw2reg_ctrl_o +); + + // Signals + ctrl_reg_t ctrl_wd; + aes_op_e op; + aes_mode_e mode; + key_len_e key_len; + prs_rate_e prng_reseed_rate; + logic phase_operation; + logic phase_mode; + logic phase_key_len; + logic phase_key_sideload; + logic phase_prng_reseed_rate; + logic phase_manual_operation; + logic err_update_operation; + logic err_update_mode; + logic err_update_key_len; + logic err_update_sideload; + logic err_update_prng_reseed_rate; + logic err_update_manual_operation; + logic err_storage_operation; + logic err_storage_mode; + logic err_storage_key_len; + logic err_storage_sideload; + logic err_storage_prng_reseed_rate; + logic err_storage_manual_operation; + + // Get and forward write enable. Writes are only allowed if the module is idle. + assign qe_o = reg2hw_ctrl_i.operation.qe & reg2hw_ctrl_i.mode.qe & + reg2hw_ctrl_i.key_len.qe & reg2hw_ctrl_i.sideload.qe & + reg2hw_ctrl_i.prng_reseed_rate.qe & reg2hw_ctrl_i.manual_operation.qe; + + // Get and resolve values from register interface. + assign op = aes_op_e'(reg2hw_ctrl_i.operation.q); + always_comb begin : operation_get + unique case (op) + AES_ENC: ctrl_wd.operation = AES_ENC; + AES_DEC: ctrl_wd.operation = AES_DEC; + default: ctrl_wd.operation = AES_ENC; // unsupported values are mapped to AES_ENC + endcase + end + + assign mode = aes_mode_e'(reg2hw_ctrl_i.mode.q); + always_comb begin : mode_get + unique case (mode) + AES_ECB: ctrl_wd.mode = AES_ECB; + AES_CBC: ctrl_wd.mode = AES_CBC; + AES_CFB: ctrl_wd.mode = AES_CFB; + AES_OFB: ctrl_wd.mode = AES_OFB; + AES_CTR: ctrl_wd.mode = AES_CTR; + AES_GCM: ctrl_wd.mode = AESGCMEnable ? AES_GCM : AES_NONE; + default: ctrl_wd.mode = AES_NONE; // unsupported values are mapped to AES_NONE + endcase + end + + assign key_len = key_len_e'(reg2hw_ctrl_i.key_len.q); + always_comb begin : key_len_get + unique case (key_len) + AES_128: ctrl_wd.key_len = AES_128; + AES_256: ctrl_wd.key_len = AES_256; + AES_192: ctrl_wd.key_len = AES192Enable ? AES_192 : AES_256; + default: ctrl_wd.key_len = AES_256; // unsupported values are mapped to AES_256 + endcase + end + + assign ctrl_wd.sideload = reg2hw_ctrl_i.sideload.q; + + assign prng_reseed_rate = prs_rate_e'(reg2hw_ctrl_i.prng_reseed_rate.q); + always_comb begin : prng_reseed_rate_get + unique case (prng_reseed_rate) + PER_1: ctrl_wd.prng_reseed_rate = PER_1; + PER_64: ctrl_wd.prng_reseed_rate = PER_64; + PER_8K: ctrl_wd.prng_reseed_rate = PER_8K; + default: ctrl_wd.prng_reseed_rate = PER_1; // unsupported values are mapped to PER_1. + endcase + end + + assign ctrl_wd.manual_operation = reg2hw_ctrl_i.manual_operation.q; + + // SEC_CM: MAIN.CONFIG.SHADOW + // Instantiate one shadowed register primitive per field. An update error in a field should + // only prevent the update of the affected field. + caliptra_prim_subreg_shadow #( + .DW ($bits(aes_op_e)), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessWO), + .RESVAL (AES_CTRL_SHADOWED_OPERATION_RESVAL) + ) u_ctrl_reg_shadowed_operation ( + .clk_i, + .rst_ni, + .rst_shadowed_ni, + .re (reg2hw_ctrl_i.operation.re), + .we (we_i), + .wd ({ctrl_wd.operation}), + .de (1'b0), + .d ('0), + .qe (), + .q (hw2reg_ctrl_o.operation.d), + .qs (), + .ds (), + .phase (phase_operation), + .err_update (err_update_operation), + .err_storage(err_storage_operation) + ); + + caliptra_prim_subreg_shadow #( + .DW ($bits(aes_mode_e)), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessWO), + .RESVAL (AES_CTRL_SHADOWED_MODE_RESVAL) + ) u_ctrl_reg_shadowed_mode ( + .clk_i, + .rst_ni, + .rst_shadowed_ni, + .re (reg2hw_ctrl_i.mode.re), + .we (we_i), + .wd ({ctrl_wd.mode}), + .de (1'b0), + .d ('0), + .qe (), + .q (hw2reg_ctrl_o.mode.d), + .qs (), + .ds (), + .phase (phase_mode), + .err_update (err_update_mode), + .err_storage(err_storage_mode) + ); + + caliptra_prim_subreg_shadow #( + .DW ($bits(key_len_e)), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessWO), + .RESVAL (AES_CTRL_SHADOWED_KEY_LEN_RESVAL) + ) u_ctrl_reg_shadowed_key_len ( + .clk_i, + .rst_ni, + .rst_shadowed_ni, + .re (reg2hw_ctrl_i.key_len.re), + .we (we_i), + .wd ({ctrl_wd.key_len}), + .de (1'b0), + .d ('0), + .qe (), + .q (hw2reg_ctrl_o.key_len.d), + .qs (), + .ds (), + .phase (phase_key_len), + .err_update (err_update_key_len), + .err_storage(err_storage_key_len) + ); + + caliptra_prim_subreg_shadow #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessWO), + .RESVAL (AES_CTRL_SHADOWED_SIDELOAD_RESVAL) + ) u_ctrl_reg_shadowed_sideload ( + .clk_i, + .rst_ni, + .rst_shadowed_ni, + .re (reg2hw_ctrl_i.sideload.re), + .we (we_i), + .wd (ctrl_wd.sideload), + .de (1'b0), + .d ('0), + .qe (), + .q (hw2reg_ctrl_o.sideload.d), + .qs (), + .ds (), + .phase (phase_key_sideload), + .err_update (err_update_sideload), + .err_storage(err_storage_sideload) + ); + + caliptra_prim_subreg_shadow #( + .DW ($bits(prs_rate_e)), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessWO), + .RESVAL (AES_CTRL_SHADOWED_PRNG_RESEED_RATE_RESVAL) + ) u_ctrl_reg_shadowed_prng_reseed_rate ( + .clk_i, + .rst_ni, + .rst_shadowed_ni, + .re (reg2hw_ctrl_i.prng_reseed_rate.re), + .we (we_i), + .wd ({ctrl_wd.prng_reseed_rate}), + .de (1'b0), + .d ('0), + .qe (), + .q (hw2reg_ctrl_o.prng_reseed_rate.d), + .qs (), + .ds (), + .phase (phase_prng_reseed_rate), + .err_update (err_update_prng_reseed_rate), + .err_storage(err_storage_prng_reseed_rate) + ); + + caliptra_prim_subreg_shadow #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessWO), + .RESVAL (AES_CTRL_SHADOWED_MANUAL_OPERATION_RESVAL) + ) u_ctrl_reg_shadowed_manual_operation ( + .clk_i, + .rst_ni, + .rst_shadowed_ni, + .re (reg2hw_ctrl_i.manual_operation.re), + .we (we_i), + .wd (ctrl_wd.manual_operation), + .de (1'b0), + .d ('0), + .qe (), + .q (hw2reg_ctrl_o.manual_operation.d), + .qs (), + .ds (), + .phase (phase_manual_operation), + .err_update (err_update_manual_operation), + .err_storage(err_storage_manual_operation) + ); + + // Collect phase signals. + assign phase_o = phase_operation | phase_mode | phase_key_len | phase_key_sideload | + phase_prng_reseed_rate | phase_manual_operation; + + // Collect alerts. + assign err_update_o = err_update_operation | err_update_mode | err_update_key_len | + err_update_sideload | err_update_prng_reseed_rate | err_update_manual_operation; + assign err_storage_o = err_storage_operation | err_storage_mode | err_storage_key_len | + err_storage_sideload | err_storage_prng_reseed_rate | err_storage_manual_operation; + + // Generate shorter references. + // Doing that here as opposed to in aes_core avoids several Verilator lint errors. + assign operation_o = aes_op_e'(hw2reg_ctrl_o.operation.d); + assign mode_o = aes_mode_e'(hw2reg_ctrl_o.mode.d); + assign key_len_o = key_len_e'(hw2reg_ctrl_o.key_len.d); + assign sideload_o = hw2reg_ctrl_o.sideload.d; + assign prng_reseed_rate_o = prs_rate_e'(hw2reg_ctrl_o.prng_reseed_rate.d); + assign manual_operation_o = hw2reg_ctrl_o.manual_operation.d; + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/aes_ghash.sv b/designs/Caliptra/src/caliptra-rtl/aes_ghash.sv new file mode 100644 index 0000000..1842898 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/aes_ghash.sv @@ -0,0 +1,1054 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// AES GHASH implementation for AES-GCM +// +// This module implements the GHASH core including hash state and hash key register required for +// AES-GCM. +// +// Details on the data formats +// --------------------------- +// +// The aes_core as well as the aes_cipher_core modules use 4-dimensional SystemVerilog arrays to +// represent AES states: +// +// logic [3:0][3:0][7:0] state_q [NumShares]; +// +// The fourth dimension (unpacked) corresponds to the different shares. The first element holds the +// (masked) data share whereas the other elements hold the masks (masked implementation only). +// The three packed dimensions correspond to the 128-bit state matrix per share. This +// implementation uses the same encoding as the Advanced Encryption Standard (AES) FIPS Publication +// 197 available at https://www.nist.gov/publications/advanced-encryption-standard-aes (see Section +// 3.4). An input sequence of 16 bytes (128-bit, left most byte is the first one) +// +// B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 B10 B11 B12 B13 B14 B15 +// +// is mapped to the state matrix as +// +// [ B0 B4 B8 B12 ] +// [ B1 B5 B9 B13 ] +// [ B2 B6 B10 B14 ] +// [ B3 B7 B11 B15 ] . +// +// In contrast, this implementation of the GHASH module uses 2-dimensional SystemVerilog arrays +// to represent bit strings: +// +// logic [127:0] hash_subkey_q [NumShares]; +// +// The second dimension (unpacked) corresponds to the different shares. The first element holds +// the (masked) data share whereas the other elements hold the masks (masked implementation only). +// The unpacked dimension corresponds to the 128-bit bit string per share. This implementation +// uses the same encoding as Recommendation for Block Cipher Modes of Operation: Galois/Counter +// Mode (GCM) and GMAC NIST Special Publication 800-38D available at +// https://csrc.nist.gov/pubs/sp/800/38/d/final (See Section 6.1) and as Advanced Encryption +// Standard (AES) FIPS Publication 197 available at +// https://www.nist.gov/publications/advanced-encryption-standard-aes (see Section 3.3). An input +// sequence of 128 bits (left most bit is the first one) +// +// b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 b10 b11 ... b125 b126 b127 +// +// is mapped to Bytes as follows +// +// B0 = {b0 b1 b2 b3 b4 b5 b6 b7 } +// B1 = {b8 b9 b10 b11 b12 b13 b14 b15 } +// . +// B15 = {b120 b121 b122 b123 b124 b125 b126 b127} . +// +// Internally, this is mapped to the 128-bit packed dimension of the SystemVerilog array as follows +// +// /-------- Byte 0 --------\ ... /-------- Byte 15 -------\ +// 128'b{ b0, b1, b2, ... b5, b6, b7, b8, b9, ..., b119, b120, ... b126, b127 } +// +// meaning the hexadecimal representations of these values can directly be compared with test vector +// data found in The Galois/Counter Mode of Operation (GCM) available at +// https://csrc.nist.rip/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-spec.pdf (See +// Appendix B). +// +// However, when interfacing the GF(2^128) multiplier, the bit order has to reversed to obtain +// packed 128-bit SystemVerilog arrays with the MSB left and the LSB right, i.e., +// +// 128'b{ b127, b126, ... b1, b0 } . +// +// The final authentication tag is put out via Data Out registers and uses again the above format +// +// MSB LSB +// - DATA_OUT_0 32'h{ B3 B2 B1 B0 } +// - DATA_OUT_1 32'h{ B7 B6 B5 B4 } +// - DATA_OUT_2 32'h{ B11 B10 B9 B8 } +// - DATA_OUT_3 32'h{ B15 B14 B13 B12 } +// +// Or in terms of bits +// MSB LSB +// - DATA_OUT_0 32'h = 32'h{ b24 b25 b26 b27 b28 b29 b30 b31 ... b0 b1 b2 b3 b4 b5 b6 b7 } +// - ... + +`include "caliptra_prim_assert.sv" + +module aes_ghash + import aes_pkg::*; + import aes_reg_pkg::*; +#( + parameter bit SecMasking = 1, + parameter int unsigned GFMultCycles = 32, + + localparam int NumShares = SecMasking ? 2 : 1 // derived parameter +) ( + input logic clk_i, + input logic rst_ni, + + // Input handshake signals + input sp2v_e in_valid_i, + output sp2v_e in_ready_o, + + // Output handshake signals + output sp2v_e out_valid_o, + input sp2v_e out_ready_i, + + // Control signals + input aes_op_e op_i, + input gcm_phase_e gcm_phase_i, + input logic [4:0] num_valid_bytes_i, + input sp2v_e load_hash_subkey_i, + input logic clear_i, + output logic first_block_o, + input logic alert_fatal_i, + output logic alert_o, + + // I/O data signals + input logic [GCMDegree-1:0] data_in_prev_i, // Ciphertext for decryption + // or AAD + input logic [NumRegsData-1:0][31:0] data_out_i, // Ciphertext for encryption + input logic [3:0][3:0][7:0] cipher_state_done_i [NumShares], // Masked cipher core output + output logic [NumRegsData-1:0][31:0] ghash_state_done_o +); + + // Parameters + localparam int GFMultStagesPerCycle = GCMDegree / GFMultCycles; + + // Signals + logic [GCMDegree-1:0] s_d; + logic [GCMDegree-1:0] s_q; + sp2v_e s_we; + logic [GCMDegree-1:0] corr_d [2]; + logic [GCMDegree-1:0] corr_q [2]; + sp2v_e corr_we; + logic corr0_en_d; + logic corr0_en_q; + logic [15:0][7:0] ghash_in; + logic [15:0][7:0] ghash_in_valid; + ghash_in_sel_e ghash_in_sel; + ghash_add_in_sel_e ghash_add_in_sel_d [2]; + ghash_add_in_sel_e ghash_add_in_sel_q [2]; + logic [1:0] ghash_add_in_sel_err; + logic [GCMDegree-1:0] ghash_state_d [NumShares]; + logic [GCMDegree-1:0] ghash_state_q [NumShares]; + logic [GCMDegree-1:0] add_s_in; + logic add_s_en_d; + logic add_s_en_q; + logic [GCMDegree-1:0] ghash_state_done; + logic [GCMDegree-1:0] ghash_state_add [NumShares]; + sp2v_e ghash_state_we [2]; + ghash_state_sel_e ghash_state_sel; + logic [GCMDegree-1:0] ghash_state_mult [NumShares]; + logic [GCMDegree-1:0] hash_subkey_d [NumShares]; + logic [GCMDegree-1:0] hash_subkey_q [NumShares]; + sp2v_e hash_subkey_we; + logic gf_mult0_en_d; + logic gf_mult0_en_q; + gf_mult_in_sel_e gf_mult1_in_sel_d; + gf_mult_in_sel_e gf_mult1_in_sel_q; + logic gf_mult1_in_sel_err; + logic [1:0] gf_mult_req; + logic [1:0] gf_mult_ack; + logic [1:0] gf_mult_ack_pre; + aes_ghash_e aes_ghash_ns, aes_ghash_cs; + logic first_block_d; + logic first_block_q; + logic final_add_d; + logic final_add_q; + logic advance; + + ////////////////////////////////// + // Input Data Format Conversion // + ////////////////////////////////// + // Covert the input data to the internal data format. + logic [GCMDegree-1:0] cipher_state_done [NumShares]; + logic [GCMDegree-1:0] data_in_prev; + logic [GCMDegree-1:0] data_out; + always_comb begin : data_in_conversion + for (int s = 0; s < NumShares; s++) begin + cipher_state_done[s] = aes_state_to_ghash_vec(cipher_state_done_i[s]); + end + data_in_prev = aes_state_to_ghash_vec(aes_transpose(data_in_prev_i)); + data_out = aes_state_to_ghash_vec(aes_transpose(data_out_i)); + end + + //////////////////// + // S = AES_K(J_0) // + //////////////////// + // The initial counter block J_0 encrypted using the encryption key K. For the unmasked + // implementation this is only used at the very end. + // + // For the masked implementaion, the shares of S are used multiple times in the form of + // correction terms throughout the entire computation (see separate section below for details). + // In addition, Share 1 of S only is again used at the very end. + // + // These registers can be cleared with pseudo-random data by loading the output of the cipher + // core after having cleared the internal state of the cipher core. + if (SecMasking) begin : gen_s1 + // Save Share 1 of S for later usage. + assign s_d = cipher_state_done[1]; + + end else begin : gen_s0 + // S comes in unmasked, simply save it. + assign s_d = cipher_state_done[0]; + end + + always_ff @(posedge clk_i or negedge rst_ni) begin : s_reg + if (!rst_ni) begin + s_q <= '0; + end else if (s_we == SP2V_HIGH) begin + s_q <= s_d; + end + end + + ////////////////////// + // Correction Terms // + ////////////////////// + // For the masked implementation, three correction terms based on the Shares of S as well as on + // the Shares of the sub hashkey need to be added to various intermediate results. Two of these + // correction terms are added repeatedly. These are thus stored in dedicated registers. A third + // correction term is used only once, it is computed on demand. The following terms are needed: + // + // 1. (S0 * H0) + S0 -- Used for every block, computed during the initialization phase. + // 2. S0 * H1 -- Used for every block except for the first one, computed during the + // initialization phase. + // 3. S1 * H1 -- Used only for the first block and computed on demand. + // + // where S0 or S1 is Share 0 or Share 1 of S, respectively. Similarly, H0 or H1 is Share 0 or + // Share 1 of the hash subkey, respectively. + // + // These registers can be cleared after pushing some pseudo-random data through the multipliers. + if (SecMasking) begin : gen_corr_terms + // Avoid glichtes on the enable signal controlling the blanking. + caliptra_prim_flop #( + .Width (1), + .ResetValue(1'b0) + ) u_caliptra_prim_flop_corr0_en ( + .clk_i (clk_i), + .rst_ni(rst_ni), + + .d_i(corr0_en_d), + .q_o(corr0_en_q) + ); + + // Only feed Share 0 of the GHASH state into the addition if we're actually updating the + // correction terms. This helps reducing undesirable SCA leakage due to combining intermediate + // results of the first mutliplier (when not computing correction terms) with the GHASH state. + logic [GCMDegree-1:0] ghash_state0_blanked; + caliptra_prim_blanker #( + .Width(GCMDegree) + ) u_caliptra_prim_blanker_corr0 ( + .in_i (ghash_state_q[0]), + .en_i (corr0_en_q), + .out_o(ghash_state0_blanked) + ); + + assign corr_d[0] = ghash_state_mult[0] ^ ghash_state0_blanked; + assign corr_d[1] = ghash_state_mult[1]; + + always_ff @(posedge clk_i or negedge rst_ni) begin : corr_reg + if (!rst_ni) begin + corr_q <= '{default: '0}; + end else if (corr_we == SP2V_HIGH) begin + corr_q <= corr_d; + end + end + end + + ///////////////// + // GHASH Input // + ///////////////// + // Select the ciphertext for encryption / decryption. + always_comb begin : ghash_in_mux + unique case (ghash_in_sel) + GHASH_IN_DATA_IN_PREV: ghash_in = data_in_prev; + GHASH_IN_DATA_OUT: ghash_in = data_out; + default: ghash_in = data_out; + endcase + end + + // Mask invalid bytes. The least significant byte is mapped to Position 15 internally. See + // the section "Details on the data formats" in the header for details. + always_comb begin + for (int unsigned i = 0; i < 16; i++) begin + ghash_in_valid[15-i] = num_valid_bytes_i > i[4:0] ? ghash_in[15-i] : 8'b0; + end + end + + ///////////////// + // GHASH State // + ///////////////// + // Add the GHASH input or correction terms (masked implementation only) to the current state. + if (SecMasking) begin : gen_masked_add + logic [GCMDegree-1:0] add_in [NumShares]; + + // Depending on the which phase we are in, we either add the GHASH input, or some correction + // term to the GHASH state. The selection may vary between the two shares. To reduce + // undesirable SCA leakage due to the multiplexing, caliptra_prim_onehot_mux instances are used. + logic [GHashAddInSelWidth-1:0] ghash_add_in_sel_q_raw [NumShares]; + logic [GCMDegree-1:0] ghash_add_in_mux_in [NumShares][GHashAddInSelWidth]; + + // The actual one-hot multiplexer forward any of the three inputs or zero if no input is + // selected (ghash_add_in_sel_q[i] == ADD_IN_ZERO). + assign ghash_add_in_mux_in[0][0] = ghash_in_valid; + assign ghash_add_in_mux_in[0][1] = corr_q[0]; + assign ghash_add_in_mux_in[0][2] = ghash_state_q[1]; + + assign ghash_add_in_mux_in[1][0] = ghash_in_valid; + assign ghash_add_in_mux_in[1][1] = corr_q[1]; + assign ghash_add_in_mux_in[1][2] = ghash_state_mult[1]; + + for (genvar s = 0; s < NumShares; s++) begin : gen_add_in_muxes + // Avoid glichtes on the selector signals. + caliptra_prim_flop #( + .Width (GHashAddInSelWidth), + .ResetValue({ADD_IN_GHASH_IN}) + ) u_caliptra_prim_flop_add_in_sel ( + .clk_i (clk_i), + .rst_ni(rst_ni), + + .d_i({ghash_add_in_sel_d[s]}), + .q_o(ghash_add_in_sel_q_raw[s]) + ); + assign ghash_add_in_sel_q[s] = ghash_add_in_sel_e'(ghash_add_in_sel_q_raw[s]); + + // Check that the selector signals are indeed one-hot encoded or zero. + caliptra_prim_onehot_check #( + .OneHotWidth(GHashAddInSelWidth), + .AddrCheck (1'b0), + .StrictCheck(1'b0) + ) u_caliptra_prim_onehot_check_add_in_sel ( + .clk_i (clk_i), + .rst_ni(rst_ni), + + .oh_i ({ghash_add_in_sel_q[s]}), + .addr_i('0), + .en_i (1'b1), + .err_o (ghash_add_in_sel_err[s]) + ); + + // The actual mux. + caliptra_prim_onehot_mux #( + .Width (GCMDegree), + .Inputs(GHashAddInSelWidth) + ) u_caliptra_prim_onehot_mux_add_in ( + .clk_i (clk_i), + .rst_ni(rst_ni), + + .in_i (ghash_add_in_mux_in[s]), + .sel_i(ghash_add_in_sel_q[s]), + .out_o(add_in[s]) + ); + end + + // Perform the addition on a per-share basis. + for (genvar s = 0; s < NumShares; s++) begin : gen_state_add + assign ghash_state_add[s] = ghash_state_q[s] ^ add_in[s]; + end + + end else begin : gen_unmasked_add + + // Simply add the GHASH input to the current state. + assign ghash_state_add[0] = ghash_state_q[0] ^ ghash_in_valid; + end + + // The GHASH state muxing differs in the number of inputs between the masked and the unmasked + // implementation. + if (SecMasking) begin : gen_ghash_state_mux_masked + + // We initialize the state with S. + // + // For restoring a GHASH state, we overwrite Share 0 of the initialized GHASH state with the + // previously saved value in unmasked form, i.e. GHASH state + S. Share 1 is left untouched. + // This is equal to subtracing Share 1 of S which will be added again at the very end. To save + // muxing resources, Share 1 of the state multiplexer below is identical to the default. + always_comb begin : ghash_state0_mux + unique case (ghash_state_sel) + GHASH_STATE_INIT: ghash_state_d[0] = cipher_state_done[0]; + GHASH_STATE_RESTORE: ghash_state_d[0] = data_in_prev; + GHASH_STATE_ADD: ghash_state_d[0] = ghash_state_add[0]; + GHASH_STATE_MULT: ghash_state_d[0] = ghash_state_mult[0]; + // GHASH_STATE_ADD_S unused. + default: ghash_state_d[0] = ghash_state_add[0]; + endcase + end + always_comb begin : ghash_state1_mux + unique case (ghash_state_sel) + GHASH_STATE_INIT: ghash_state_d[1] = cipher_state_done[1]; + GHASH_STATE_ADD: ghash_state_d[1] = ghash_state_add[1]; + GHASH_STATE_MULT: ghash_state_d[1] = ghash_state_mult[1]; + // GHASH_STATE_RESTORE and GHASH_STATE_ADD_S unused. + default: ghash_state_d[1] = ghash_state_add[1]; + endcase + end + + end else begin : gen_ghash_state_mux_unmasked + + // We initialize the state with S. In case of the unmasked implementation, S has to be + // substracted in a second step to reach the required zero state. Doing it this way allows + // saving one multiplexer input. + // + // For restoring a GHASH state in the unmasked implementation, the previously saved value, + // i.e., GHASH state + S, is added to the GHASH state initialized to 0. S is then substracted + // again seperately. Doing this allows saving one multiplexer input. + // + // The resulting multiplexer has 4 inputs. + always_comb begin : ghash_state_mux + unique case (ghash_state_sel) + GHASH_STATE_RESTORE: ghash_state_d[0] = ghash_state_add[0]; + GHASH_STATE_INIT: ghash_state_d[0] = cipher_state_done[0]; + GHASH_STATE_ADD: ghash_state_d[0] = ghash_state_add[0]; + GHASH_STATE_ADD_S: ghash_state_d[0] = ghash_state_done; + GHASH_STATE_MULT: ghash_state_d[0] = ghash_state_mult[0]; + // GHASH_STATE_RESTORE is equal to GHASH_STATE_ADD. + default: ghash_state_d[0] = ghash_state_add[0]; + endcase + end + end + + // This register can be cleared with pseudo-random data by adding the output of the cipher core + // to the current state after having cleared the internal state of the cipher core. + for (genvar s = 0; s < NumShares; s++) begin : gen_ghash_state_reg_shares + always_ff @(posedge clk_i or negedge rst_ni) begin : ghash_state_reg + if (!rst_ni) begin + ghash_state_q[s] <= '0; + end else if (ghash_state_we[s] == SP2V_HIGH) begin + ghash_state_q[s] <= ghash_state_d[s]; + end + end + end + + ///////////////// + // Hash Subkey // + ///////////////// + // This register can be cleared with pseudo-random data by loading the output of the cipher + // core after having cleared the internal state of the cipher core. + assign hash_subkey_d = cipher_state_done; + always_ff @(posedge clk_i or negedge rst_ni) begin : hash_subkey_reg + if (!rst_ni) begin + hash_subkey_q <= '{default: '0}; + end else if (hash_subkey_we == SP2V_HIGH) begin + hash_subkey_q <= hash_subkey_d; + end + end + + ////////////////////////// + // GF(2^128) Multiplier // + ////////////////////////// + logic [GCMDegree-1:0] gf_mult_op_b[NumShares]; + logic [GCMDegree-1:0] gf_mult_op_b_rev[NumShares]; + logic [GCMDegree-1:0] gf_mult_prod[NumShares]; + + // The first multiplier has no muxes on the operand inputs. For the masked implementation, + // a caliptra_prim_blanker instance helps to reduce undesirable SCA leakage. + if (SecMasking) begin : gen_gf_mult0_blanker + // Avoid glichtes on the enable signal controlling the blanking. + caliptra_prim_flop #( + .Width (1), + .ResetValue(1'b0) + ) u_caliptra_prim_flop_gf_mult0_en ( + .clk_i (clk_i), + .rst_ni(rst_ni), + + .d_i(gf_mult0_en_d), + .q_o(gf_mult0_en_q) + ); + + // Only present a non-zero input if we're actually performing a multiplication. + caliptra_prim_blanker #( + .Width(GCMDegree) + ) u_caliptra_prim_blanker_gf_mult0 ( + .in_i (ghash_state_q[0]), + .en_i (gf_mult0_en_q), + .out_o(gf_mult_op_b[0]) + ); + end else begin : gen_no_gf_mult0_blanker + assign gf_mult_op_b[0] = ghash_state_q[0]; + end + + // Reverse the bit order. + assign gf_mult_op_b_rev[0] = aes_ghash_reverse_bit_order(gf_mult_op_b[0]); + + if (SecMasking) begin : gen_gf_mult1_mux + // The second multiplier is used to multiply Share 1 of the hash subkey with Share 0, + // Share 1 (first block only) of the state, and also Share 1 of S. To reduce undesirable SCA + // leakage due to the multiplexing, a caliptra_prim_onehot_mux instance is used. + logic [GFMultInSelWidth-1:0] gf_mult1_in_sel_q_raw; + logic [GCMDegree-1:0] gf_mult1_op_b_mux_in [GFMultInSelWidth]; + + // Avoid glitches on the selector signal. + caliptra_prim_flop #( + .Width (GFMultInSelWidth), + .ResetValue({MULT_IN_ZERO}) + ) u_caliptra_prim_flop_gf_mult1_in_sel ( + .clk_i (clk_i), + .rst_ni(rst_ni), + + .d_i({gf_mult1_in_sel_d}), + .q_o(gf_mult1_in_sel_q_raw) + ); + assign gf_mult1_in_sel_q = gf_mult_in_sel_e'(gf_mult1_in_sel_q_raw); + + // Check that the selector signal is indeed one-hot encoded or zero. + caliptra_prim_onehot_check #( + .OneHotWidth(GFMultInSelWidth), + .AddrCheck (1'b0), + .StrictCheck(1'b0) + ) u_caliptra_prim_onehot_check_gf_mult1_in_sel ( + .clk_i (clk_i), + .rst_ni(rst_ni), + + .oh_i ({gf_mult1_in_sel_q}), + .addr_i('0), + .en_i (1'b1), + .err_o (gf_mult1_in_sel_err) + ); + + // The actual one-hot multiplexer forwards any of the three inputs or zero if no input is + // selected (gf_mult1_in_sel_q == MULT_IN_ZERO). + assign gf_mult1_op_b_mux_in[0] = ghash_state_q[0]; + assign gf_mult1_op_b_mux_in[1] = ghash_state_q[1]; + assign gf_mult1_op_b_mux_in[2] = s_q; + caliptra_prim_onehot_mux #( + .Width (GCMDegree), + .Inputs(GFMultInSelWidth) + ) u_caliptra_prim_onehot_mux_gf_mult1_op_b ( + .clk_i (clk_i), + .rst_ni(rst_ni), + + .in_i (gf_mult1_op_b_mux_in), + .sel_i(gf_mult1_in_sel_q), + .out_o(gf_mult_op_b[1]) + ); + + // Reverse the bit order. + logic [GCMDegree-1:0] gf_mult1_op_b_rev; + assign gf_mult1_op_b_rev = aes_ghash_reverse_bit_order(gf_mult_op_b[1]); + + // Register the last input slice of Operand B. This allows switching the one-hot multiplexer + // during the last clock cycle of the multiplication to effectively flush the multiplexer. This + // is beneficial from a SCA hardening viewpoint for two reasons: + // - Flushing the multiplexer before providing the next input avoids leakage between + // different multiplexer inputs and enables back-to-back multiplications. + // - Upon the last multiplication cycle, the GHASH state is updated. Even if the Operand B + // input of the multiplier is blanked in the next clock cycle, transient effects may cause + // the updated GHASH state to propagate into the multiplier and be combined with the secret + // hash subkey which can cause undesirable leakage. + logic [GFMultStagesPerCycle-1:0] gf_mult1_op_b_rev_slice_d; + logic [GFMultStagesPerCycle-1:0] gf_mult1_op_b_rev_slice_q; + assign gf_mult1_op_b_rev_slice_d = gf_mult1_op_b_rev[GCMDegree-1 -: GFMultStagesPerCycle]; + always_ff @(posedge clk_i or negedge rst_ni) begin : gf_mult1_op_b_slice_reg + if (!rst_ni) begin + gf_mult1_op_b_rev_slice_q <= '0; + end else begin + gf_mult1_op_b_rev_slice_q <= gf_mult1_op_b_rev_slice_d; + end + end + + assign gf_mult_op_b_rev[1] = + {gf_mult1_op_b_rev_slice_q, gf_mult1_op_b_rev[GCMDegree-GFMultStagesPerCycle-1:0]}; + end + + for (genvar s = 0; s < NumShares; s++) begin : gen_gf_mult + caliptra_prim_gf_mult #( + .Width (GCMDegree), + .StagesPerCycle (GFMultStagesPerCycle), + .IPoly (GCMIPoly), + .OutputZeroUntilAck(1'b1) + ) u_gf_mult ( + .clk_i (clk_i), + .rst_ni(rst_ni), + + .req_i(gf_mult_req[s]), + .ack_o(gf_mult_ack[s]), + + .ack_pre_o(gf_mult_ack_pre[s]), + + .operand_a_i(aes_ghash_reverse_bit_order(hash_subkey_q[s])), // The A input is not scanned. + .operand_b_i(gf_mult_op_b_rev[s]), // The B input is scanned. + + .prod_o(gf_mult_prod[s]) + ); + assign ghash_state_mult[s] = aes_ghash_reverse_bit_order(gf_mult_prod[s]); + end + + if (!SecMasking) begin : gen_tie_offs + // Tie-off datapath signals unused for the unmasked implementation. + logic [GCMDegree-1:0] unused_corr_q [2]; + sp2v_e unused_corr_we; + assign corr_d = '{default: '0}; + assign corr_q = corr_d; + assign unused_corr_q = corr_q; + assign unused_corr_we = corr_we; + + logic unused_corr0_en_q; + assign corr0_en_q = corr0_en_d; + assign unused_corr0_en_q = corr0_en_q; + + logic unused_ghash_add_in_sel_d; + assign unused_ghash_add_in_sel_d = ^{{ghash_add_in_sel_d[0]}, {ghash_add_in_sel_d[1]}}; + assign ghash_add_in_sel_q = '{default: ADD_IN_GHASH_IN}; + assign ghash_add_in_sel_err = 2'b00; + assign gf_mult1_in_sel_err = 1'b0; + + sp2v_e unused_ghash_state_we; + assign unused_ghash_state_we = ghash_state_we[1]; + + logic unused_gf_mult_req; + assign unused_gf_mult_req = gf_mult_req[1]; + assign gf_mult_ack[1] = 1'b1; + assign gf_mult_ack_pre[1] = 1'b1; + + logic unused_add_s_en_q; + assign add_s_en_q = add_s_en_d; + assign unused_add_s_en_q = add_s_en_q; + end + + ///////////////// + // Control FSM // + ///////////////// + + always_comb begin : aes_ghash_fsm + + // Handshake signals + in_ready_o = SP2V_LOW; + out_valid_o = SP2V_LOW; + + // Data path + s_we = SP2V_LOW; + corr_we = SP2V_LOW; + corr0_en_d = 1'b0; + + ghash_in_sel = GHASH_IN_DATA_OUT; + + ghash_add_in_sel_d = ghash_add_in_sel_q; + + ghash_state_sel = GHASH_STATE_ADD; + ghash_state_we[0] = SP2V_LOW; + ghash_state_we[1] = SP2V_LOW; + + hash_subkey_we = SP2V_LOW; + + gf_mult_req = '0; + gf_mult0_en_d = gf_mult0_en_q; + gf_mult1_in_sel_d = gf_mult1_in_sel_q; + + add_s_en_d = 1'b0; + + // FSM + aes_ghash_ns = aes_ghash_cs; + first_block_d = first_block_q; + final_add_d = final_add_q; + advance = 1'b0; + + // Alert + alert_o = 1'b0; + + unique case (aes_ghash_cs) + GHASH_IDLE: begin + in_ready_o = SP2V_HIGH; + if (in_valid_i == SP2V_HIGH) begin + if (clear_i) begin + // Clearing has highest priority. We clear the state using the unmasked cipher core + // output which is randomized at this point. + s_we = SP2V_HIGH; + ghash_state_sel = GHASH_STATE_ADD; + ghash_state_we[0] = SP2V_HIGH; + ghash_state_we[1] = SP2V_HIGH; + hash_subkey_we = SP2V_HIGH; + first_block_d = 1'b1; + final_add_d = 1'b0; + + // In case of the masked implementation, also the correction terms need to be cleared. + // This can be done by using the multipliers. + if (SecMasking) begin + gf_mult0_en_d = 1'b1; + gf_mult1_in_sel_d = MULT_IN_STATE1; + aes_ghash_ns = GHASH_MASKED_INIT; + end + + end else if (gcm_phase_i == GCM_INIT) begin + if (load_hash_subkey_i == SP2V_HIGH) begin + + // Load the hash subkey. + hash_subkey_we = SP2V_HIGH; + end else begin + + // Load S and initialize the state with S. + s_we = SP2V_HIGH; + ghash_state_sel = GHASH_STATE_INIT; + ghash_state_we[0] = SP2V_HIGH; + ghash_state_we[1] = SP2V_HIGH; + first_block_d = 1'b1; + + // We have now all pre-requisites to compute the correction terms for the masked + // implementation. For the unmasked implementation, we now have to subtract S again + // from the state. Doing it this way allows saving one multiplexer input. + if (SecMasking) begin + gf_mult0_en_d = 1'b1; + gf_mult1_in_sel_d = MULT_IN_STATE0; + aes_ghash_ns = GHASH_MASKED_INIT; + end else begin + aes_ghash_ns = GHASH_ADD_S; + end + end + + end else if (gcm_phase_i == GCM_RESTORE) begin + // Restore a previously loaded GHASH state. We overwrite the Share 0 of the GHASH + // state and leave Share 1 untouched. For the masked implementation, this is equal to + // subtracting Share 1 of S. It is only added at the very end (or when saving the GHASH + // state). + ghash_state_sel = GHASH_STATE_RESTORE; + ghash_state_we[0] = SP2V_HIGH; + first_block_d = 1'b0; + + // For the unmasked implementation, the previously saved value, i.e., GHASH state + S, + // is added to the GHASH state initialized to 0. S needs then to be substracted again + // seperately before continuing. + ghash_in_sel = !SecMasking ? GHASH_IN_DATA_IN_PREV : GHASH_IN_DATA_OUT; + aes_ghash_ns = !SecMasking ? GHASH_ADD_S : GHASH_IDLE; + + end else if (gcm_phase_i == GCM_AAD || + gcm_phase_i == GCM_TEXT || + gcm_phase_i == GCM_TAG) begin + // Select the proper input for the addition. + ghash_in_sel = + (gcm_phase_i == GCM_AAD) ? GHASH_IN_DATA_IN_PREV : + (gcm_phase_i == GCM_TEXT && op_i == AES_DEC) ? GHASH_IN_DATA_IN_PREV : + (gcm_phase_i == GCM_TEXT && op_i == AES_ENC) ? GHASH_IN_DATA_OUT : + (gcm_phase_i == GCM_TAG) ? GHASH_IN_DATA_IN_PREV : + GHASH_IN_DATA_OUT; + + // Add the current input to the GHASH state to start the multiplication afterwards. + // Only for the first block both shares of the GHASH state need to be updated. + ghash_state_we[0] = SP2V_HIGH; + ghash_state_we[1] = first_block_q ? SP2V_HIGH : SP2V_LOW; + + if (SecMasking && !first_block_q) begin + // In case masking is enabled and we've already done the first block, we have to do + // one more addition before starting the multiplication. + ghash_add_in_sel_d[0] = ADD_IN_CORR_B; + aes_ghash_ns = GHASH_MASKED_ADD_STATE_SHARES; + end else begin + + // Start the multiplication. For the masked implementation, the second multiplier + // takes Share 1 only for the very first block. + gf_mult0_en_d = 1'b1; + gf_mult1_in_sel_d = MULT_IN_STATE1; + aes_ghash_ns = GHASH_MULT; + end + + end else if (gcm_phase_i == GCM_SAVE) begin + // Get ready to output the current GHASH state. + + // For the masked implementation, first unmask the GHASH state and then add Share 1 of + // S. For the unmasked implementation, add S directly. + final_add_d = 1'b1; + if (SecMasking) begin + ghash_add_in_sel_d[0] = ADD_IN_CORR_B; + aes_ghash_ns = GHASH_MASKED_ADD_STATE_SHARES; + end else begin + add_s_en_d = 1'b1; + aes_ghash_ns = GHASH_OUT; + end + + end else begin + // Handshake without a valid command. We should never get here. If we do (e.g. via a + // malicious glitch), error out immediately. + aes_ghash_ns = GHASH_ERROR; + end + end + end + + GHASH_MASKED_INIT: begin + // Compute repeatedly used correction terms (masked implementation only). We need: + // + // 1. (S0 * H0) + S0 + // 2. S0 * H1 + // + // S0 and S1 have been loaded into the GHASH state registers previsously. + // + // This state is also used as part of the clearing sequence. Then, we multiply each state + // share by the corresponding share of the cleared hash subkey. + gf_mult_req = 2'b11; + if (gf_mult_ack_pre[0]) begin + corr0_en_d = 1'b1; + end + if (gf_mult_ack_pre[1]) begin + gf_mult1_in_sel_d = MULT_IN_ZERO; + end + if (&gf_mult_ack) begin + gf_mult0_en_d = 1'b0; + gf_mult1_in_sel_d = MULT_IN_ZERO; + corr_we = SP2V_HIGH; + aes_ghash_ns = GHASH_IDLE; + end + end + + GHASH_MASKED_ADD_STATE_SHARES: begin + // Add both shares of the GHASH state and store the result in Share 0. + ghash_state_sel = GHASH_STATE_ADD; + ghash_state_we[0] = SP2V_HIGH; + final_add_d = 1'b0; + + // Switch the add_in multiplexers back to the default position in the next clock cycle. + ghash_add_in_sel_d[0] = ADD_IN_GHASH_IN; + ghash_add_in_sel_d[1] = ADD_IN_GHASH_IN; + + if ((gcm_phase_i == GCM_SAVE) || ((gcm_phase_i == GCM_TAG) && final_add_q)) begin + // When saving the context or when producing the final authentication tag, we have to + // add Share 1 of S next and output the result. + add_s_en_d = 1'b1; + aes_ghash_ns = GHASH_OUT; + end else begin + + // Multiply Share 0 of the GHASH state with the hash subkey next. Share 1 of the GHASH + // state is only multiplied by Share 1 of the hash subkey for the very first block. + gf_mult0_en_d = 1'b1; + gf_mult1_in_sel_d = MULT_IN_STATE0; + aes_ghash_ns = GHASH_MULT; + end + end + + GHASH_MULT: begin + // Perform the multiplication and update the state. + gf_mult_req = 2'b11; + if (gf_mult_ack_pre[1]) begin + gf_mult1_in_sel_d = MULT_IN_ZERO; + end + if (&gf_mult_ack) begin + // Note: Once the multiplication finishes, Share 0 of the state depends on Share 0 of the + // hash subkey. Thus, we don't forward it to the second multiplier as this may lead to + // undesirable SCA leakage inside the multiplier. + // When doing the first block only, we have to start computing another correction term + // using the second multiplier in the next clock cycle, i.e., S1 * H1. + gf_mult0_en_d = 1'b0; + gf_mult1_in_sel_d = SecMasking && first_block_q ? MULT_IN_S1 : MULT_IN_ZERO; + + ghash_state_sel = GHASH_STATE_MULT; + ghash_state_we[0] = SP2V_HIGH; + ghash_state_we[1] = SP2V_HIGH; + if (SecMasking) begin + ghash_add_in_sel_d[0] = ADD_IN_CORR_A; + ghash_add_in_sel_d[1] = first_block_q ? ADD_IN_GHASH_IN : ADD_IN_CORR_A; + aes_ghash_ns = GHASH_MASKED_ADD_CORR; + end else begin + first_block_d = 1'b0; + aes_ghash_ns = (gcm_phase_i == GCM_TAG) ? GHASH_OUT : GHASH_IDLE; + end + end + end + + GHASH_MASKED_ADD_CORR: begin + // Add the proper correction terms to both state shares. + + if (first_block_q) begin + // When doing the first block only, we need to compute another correction term using the + // second multiplier only, i.e., S1 * H1. To reduce undesirable SCA leakage, we should + // not combine the previously computed correction term S0 * H1 with Share 1 of the GHASH + // state or potential intermediate results of the second multiplier (both may depend on + // S1). Only the final result of the second multiplier is forwarded to the addition. + gf_mult_req = 2'b10; + if (gf_mult_ack_pre[1]) begin + ghash_add_in_sel_d[1] = ADD_IN_CORR_B; + gf_mult1_in_sel_d = MULT_IN_ZERO; + end + if (gf_mult_ack[1]) begin + gf_mult1_in_sel_d = MULT_IN_ZERO; + ghash_state_we[0] = SP2V_HIGH; + ghash_state_we[1] = SP2V_HIGH; + first_block_d = 1'b0; + advance = 1'b1; + end + end else begin + // We don't have to do another multiplication. + advance = 1'b1; + + // Add the previously computed correction terms. + ghash_state_we[0] = SP2V_HIGH; + ghash_state_we[1] = SP2V_HIGH; + end + + if (advance) begin + if (gcm_phase_i == GCM_TAG) begin + // When producing the final authentication tag, we have to unmask the state next. + // + // But before doing that, we pause for one clock cycle to allow downstream wires of the + // GHASH state to fully settle to the corrected values. Otherwise, transient effects + // inside the addition for Share 0 of the GHASH state may cause undesirable SCA + // leakage. This is because before adding the correction terms, Share 0 and Share 1 + // of the GHASH state depends on H0 and H1, respectively. + aes_ghash_ns = GHASH_MASKED_SETTLE; + end else begin + ghash_add_in_sel_d[0] = ADD_IN_GHASH_IN; + ghash_add_in_sel_d[1] = ADD_IN_GHASH_IN; + aes_ghash_ns = GHASH_IDLE; + end + end + end + + GHASH_MASKED_SETTLE: begin + // After adding the correction terms the last time and before unmasking the state, we pause + // for one clock cycle. This allows downstream wires of the GHASH state to fully settle to + // the corrected values to reduce undesirable SCA leakage. + final_add_d = 1'b1; + ghash_add_in_sel_d[0] = ADD_IN_CORR_B; + ghash_add_in_sel_d[1] = ADD_IN_GHASH_IN; + aes_ghash_ns = GHASH_MASKED_ADD_STATE_SHARES; + end + + GHASH_ADD_S: begin + // Add S to the GHASH state and then return to the idle state. This state is used for the + // unmasked implementation only. The generatiion of the final authentication tag (also + // involves adding the GHASH state and S) is handled separately in the GHASH_OUT FSM state. + ghash_state_sel = GHASH_STATE_ADD_S; + ghash_state_we[0] = SP2V_HIGH; + aes_ghash_ns = GHASH_IDLE; + end + + GHASH_OUT: begin + // Add S to the GHASH state to output the final authentication tag. Upon performing the + // output handshake, clear all internal state with pseudo-random data. + add_s_en_d = 1'b1; + out_valid_o = SP2V_HIGH; + if (out_ready_i == SP2V_HIGH) begin + add_s_en_d = 1'b0; + s_we = SP2V_HIGH; + ghash_state_sel = GHASH_STATE_ADD; + ghash_state_we[0] = SP2V_HIGH; + ghash_state_we[1] = SP2V_HIGH; + hash_subkey_we = SP2V_HIGH; + + // In case of the masked implementation, also the correction terms need to be cleared. + // This can be done by using the multipliers. + if (SecMasking) begin + gf_mult0_en_d = 1'b1; + gf_mult1_in_sel_d = MULT_IN_STATE1; + aes_ghash_ns = GHASH_MASKED_INIT; + end else begin + aes_ghash_ns = GHASH_IDLE; + end + end + end + + GHASH_ERROR: begin + // Terminal error state + alert_o = 1'b1; + end + + // We should never get here. If we do (e.g. via a malicious glitch), error out immediately. + default: begin + aes_ghash_ns = GHASH_ERROR; + alert_o = 1'b1; + end + endcase + + // Unconditionally jump into the terminal error state in case a mux selector becomes invalid, + // or if a fatal alert has been triggered. + if (|ghash_add_in_sel_err || gf_mult1_in_sel_err || alert_fatal_i) begin + aes_ghash_ns = GHASH_ERROR; + end + end + + // SEC_CM: GHASH.FSM.SPARSE + `CALIPTRA_PRIM_FLOP_SPARSE_FSM(u_state_regs, aes_ghash_ns, + aes_ghash_cs, aes_ghash_e, GHASH_IDLE) + + always_ff @(posedge clk_i or negedge rst_ni) begin : fsm_reg + if (!rst_ni) begin + first_block_q <= 1'b0; + end else begin + first_block_q <= first_block_d; + end + end + + if (SecMasking) begin : gen_fsm_reg_masked + always_ff @(posedge clk_i or negedge rst_ni) begin : fsm_reg_masked + if (!rst_ni) begin + final_add_q <= 1'b0; + end else begin + final_add_q <= final_add_d; + end + end + + end else begin : gen_no_fsm_reg + // Tie-off unused FSM signals. + logic unused_final_add_d; + assign final_add_q = 1'b0; + assign unused_final_add_d = final_add_d; + + logic unused_gf_mult0_en_d; + assign gf_mult0_en_q = 1'b0; + assign unused_gf_mult0_en_d = gf_mult0_en_d; + + gf_mult_in_sel_e unused_gf_mult1_in_sel_d; + assign gf_mult1_in_sel_q = MULT_IN_ZERO; + assign unused_gf_mult1_in_sel_d = gf_mult1_in_sel_d; + + logic unused_advance; + assign unused_advance = advance; + end + + ///////////// + // Outputs // + ///////////// + + // Moving to GCM_SAVE is only allowed after having done the first block. + assign first_block_o = first_block_q; + + // Add S to the GHASH state for the generation of the final authentication tag. To reduce + // undesirable SCA leakage, the following measures are taken: + // 1. A blanker is used to only perform the addition at the very end. This avoids adding + // S to intermediate GHASH states. This is done for the masked implementation only. + // 2. The result of the addition is not written back into state regsiter but forwarded to + // the output directly. + if (SecMasking) begin : gen_add_s_in_masked + // Avoid glichtes on the enable signal controlling the blanking. + caliptra_prim_flop #( + .Width (1), + .ResetValue(1'b0) + ) u_caliptra_prim_flop_add_s_en ( + .clk_i (clk_i), + .rst_ni(rst_ni), + + .d_i(add_s_en_d), + .q_o(add_s_en_q) + ); + + // Only feed Share 0 of the GHASH state into the addition if we're actually generating and + // output. This helps reducing undesirable SCA leakage due to combining intermediate values of + // Share 0 of the GHASH state with Share 1 of S. + caliptra_prim_blanker #( + .Width(GCMDegree) + ) u_caliptra_prim_blanker_add_s_in ( + .in_i (ghash_state_q[0]), + .en_i (add_s_en_q), + .out_o(add_s_in) + ); + end else begin : gen_add_s_in_unmasked + + // Don't perform any blanking in the unmasked case. + assign add_s_in = ghash_state_q[0]; + end + + // Perform the actual addition. + assign ghash_state_done = s_q ^ add_s_in; + + // Covert the output data from the internal data format to the output format. + always_comb begin : data_out_conversion + ghash_state_done_o = aes_transpose(aes_state_to_ghash_vec(ghash_state_done)); + end + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/aes_key_expand.sv b/designs/Caliptra/src/caliptra-rtl/aes_key_expand.sv new file mode 100644 index 0000000..57692e3 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/aes_key_expand.sv @@ -0,0 +1,503 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// AES KeyExpand + +`include "caliptra_prim_assert.sv" + +module aes_key_expand import aes_pkg::*; +#( + parameter bit AES192Enable = 1, + parameter bit SecMasking = 0, + parameter sbox_impl_e SecSBoxImpl = SBoxImplLut, + + localparam int NumShares = SecMasking ? 2 : 1 // derived parameter +) ( + input logic clk_i, + input logic rst_ni, + input logic cfg_valid_i, + input ciph_op_e op_i, + input sp2v_e en_i, + input logic prd_we_i, + output sp2v_e out_req_o, + input sp2v_e out_ack_i, + input logic clear_i, + input logic [3:0] round_i, + input key_len_e key_len_i, + input logic [7:0][31:0] key_i [NumShares], + output logic [7:0][31:0] key_o [NumShares], + input logic [WidthPRDKey-1:0] prd_i, + output logic err_o +); + + sp2v_e en; + logic en_err; + sp2v_e out_ack; + logic out_ack_err; + + logic [7:0] rcon_d, rcon_q; + logic rcon_we; + logic use_rcon; + + logic [3:0] rnd; + logic [3:0] rnd_type; + + logic [31:0] spec_in_128 [NumShares]; + logic [31:0] spec_in_192 [NumShares]; + logic [31:0] rot_word_in [NumShares]; + logic [31:0] rot_word_out [NumShares]; + logic use_rot_word; + logic prd_we, prd_we_force, prd_we_inhibit; + logic [31:0] sub_word_in, sub_word_out; + logic [3:0] sub_word_out_req; + logic [31:0] sw_in_mask, sw_out_mask; + logic [7:0] rcon_add_in, rcon_add_out; + logic [31:0] rcon_added; + + logic [31:0] irregular [NumShares]; + logic [7:0][31:0] regular [NumShares]; + + // cfg_valid_i is used for gating assertions only. + logic unused_cfg_valid; + assign unused_cfg_valid = cfg_valid_i; + + // Get a shorter reference. + assign rnd = round_i; + + // For AES-192, there are four different types of rounds. + always_comb begin : get_rnd_type + if (AES192Enable) begin + rnd_type[0] = (rnd == 0); + rnd_type[1] = (rnd == 1 || rnd == 4 || rnd == 7 || rnd == 10); + rnd_type[2] = (rnd == 2 || rnd == 5 || rnd == 8 || rnd == 11); + rnd_type[3] = (rnd == 3 || rnd == 6 || rnd == 9 || rnd == 12); + end else begin + rnd_type = '0; + end + end + + ////////////////////////////////////////////////////// + // Irregular part involving Rcon, RotWord & SubWord // + ////////////////////////////////////////////////////// + + // Depending on key length and round, RotWord may not be used. + assign use_rot_word = (key_len_i == AES_256 && rnd[0] == 1'b0) ? 1'b0 : 1'b1; + + // Depending on operation, key length and round, Rcon may not be used thus must not be updated. + always_comb begin : rcon_usage + use_rcon = 1'b1; + + if (AES192Enable) begin + if (key_len_i == AES_192 && + ((op_i == CIPH_FWD && rnd_type[1]) || + (op_i == CIPH_INV && (rnd_type[0] || rnd_type[3])))) begin + use_rcon = 1'b0; + end + end + + if (key_len_i == AES_256 && rnd[0] == 1'b0) begin + use_rcon = 1'b0; + end + end + + // Generate Rcon + always_comb begin : rcon_update + rcon_d = rcon_q; + + if (clear_i) begin + rcon_d = (op_i == CIPH_FWD) ? 8'h01 : + ((op_i == CIPH_INV) && (key_len_i == AES_128)) ? 8'h36 : + ((op_i == CIPH_INV) && (key_len_i == AES_192)) ? 8'h80 : + ((op_i == CIPH_INV) && (key_len_i == AES_256)) ? 8'h40 : 8'h01; + end else begin + rcon_d = (op_i == CIPH_FWD) ? aes_mul2(rcon_q) : + (op_i == CIPH_INV) ? aes_div2(rcon_q) : 8'h01; + end + end + + // Advance. + assign rcon_we = clear_i | use_rcon & + (en == SP2V_HIGH) & (out_req_o == SP2V_HIGH) & (out_ack == SP2V_HIGH); + + // Rcon register + always_ff @(posedge clk_i or negedge rst_ni) begin : reg_rcon + if (!rst_ni) begin + rcon_q <= '0; + end else if (rcon_we) begin + rcon_q <= rcon_d; + end + end + + for (genvar s = 0; s < NumShares; s++) begin : gen_shares_rot_word_out + // Special input, equivalent to key_o[3] in the used cases + assign spec_in_128[s] = key_i[s][3] ^ key_i[s][2]; + assign spec_in_192[s] = AES192Enable ? key_i[s][5] ^ key_i[s][1] ^ key_i[s][0] : '0; + + // Select input + always_comb begin : rot_word_in_mux + unique case (key_len_i) + + ///////////// + // AES-128 // + ///////////// + AES_128: begin + unique case (op_i) + CIPH_FWD: rot_word_in[s] = key_i[s][3]; + CIPH_INV: rot_word_in[s] = spec_in_128[s]; + default: rot_word_in[s] = key_i[s][3]; + endcase + end + + ///////////// + // AES-192 // + ///////////// + AES_192: begin + if (AES192Enable) begin + unique case (op_i) + CIPH_FWD: begin + rot_word_in[s] = rnd_type[0] ? key_i[s][5] : + rnd_type[2] ? key_i[s][5] : + rnd_type[3] ? spec_in_192[s] : key_i[s][3]; + end + CIPH_INV: begin + rot_word_in[s] = rnd_type[1] ? key_i[s][3] : + rnd_type[2] ? key_i[s][1] : key_i[s][3]; + end + default: rot_word_in[s] = key_i[s][3]; + endcase + end else begin + rot_word_in[s] = key_i[s][3]; + end + end + + ///////////// + // AES-256 // + ///////////// + AES_256: begin + unique case (op_i) + CIPH_FWD: rot_word_in[s] = key_i[s][7]; + CIPH_INV: rot_word_in[s] = key_i[s][3]; + default: rot_word_in[s] = key_i[s][7]; + endcase + end + + default: rot_word_in[s] = key_i[s][3]; + endcase + end + + // RotWord: cyclic byte shift + assign rot_word_out[s] = aes_circ_byte_shift(rot_word_in[s], 2'h3); + end + + // Mux input for SubWord + assign sub_word_in = use_rot_word ? rot_word_out[0] : rot_word_in[0]; + + // Masking + if (!SecMasking) begin : gen_no_sw_in_mask + // The mask share is ignored anyway, it can be 0. + assign sw_in_mask = '0; + + // Tie-off unused signals. + logic [31:0] unused_sw_out_mask; + assign unused_sw_out_mask = sw_out_mask; + + end else begin : gen_sw_in_mask + // The input mask is the mask share of rot_word_in/out. + assign sw_in_mask = use_rot_word ? rot_word_out[1] : rot_word_in[1]; + end + + // Make sure that whenever the data/mask inputs of the S-Boxes update, the buffered PRD is + // updated in sync. There are two special cases we need to handle here: + // - For AES-256, the initial round is short (no round key computation). But the data/mask inputs + // are updated either way. Thus, we need to force a PRD update as well. + // - For AES-192 in FWD mode, the data/mask inputs aren't updated in Round 1, 4, 7 and 10. Thus, + // we need to inhibit PRD updates triggred at the end of Round 0, 3, 6 and 9. + assign prd_we_force = (key_len_i == AES_256) & (rnd == 0); + assign prd_we_inhibit = (key_len_i == AES_192) & (op_i == CIPH_FWD) & + (rnd == 0 || rnd == 3 || rnd == 6 || rnd == 9); + assign prd_we = (prd_we_i & ~prd_we_inhibit) | prd_we_force; + + // PRD buffering + logic [WidthPRDKey-1:0] prd_q; + + if (!SecMasking) begin : gen_no_prd_buffer + // The masks are ignored anyway. + assign prd_q = prd_i; + + // Tie-off unused signals. + logic unused_prd_we; + assign unused_prd_we = prd_we; + + end else begin : gen_prd_buffer + // PRD buffer stage to: + // 1. Make sure the S-Boxes get always presented new data/mask inputs together with fresh PRD + // for remasking. + // 2. Prevent glitches originating from inside the masking PRNG from propagating into the + // masked S-Boxes. + always_ff @(posedge clk_i or negedge rst_ni) begin : prd_reg + if (!rst_ni) begin + prd_q <= '0; + end else if (prd_we) begin + prd_q <= prd_i; + end + end + end + + // SubWord - individually substitute bytes. + // Every DOM S-Box instance consumes 28 bits of randomness but itself produces 20 bits for use in + // another S-Box instance. For other S-Box implementations, only the bits corresponding to prd_q + // are used. Other bits are ignored and tied to 0. + logic [3:0][WidthPRDSBox+19:0] in_prd; + logic [3:0] [19:0] out_prd; + + for (genvar i = 0; i < 4; i++) begin : gen_sbox + // Rotate the randomness produced by the S-Boxes. The LSBs are taken from the masking PRNG + // (prd_q) whereas the MSBs are produced by the other S-Box instances. + assign in_prd[i] = {out_prd[aes_rot_int(i,4)], prd_q[WidthPRDSBox*i +: WidthPRDSBox]}; + + aes_sbox #( + .SecSBoxImpl ( SecSBoxImpl ) + ) u_aes_sbox_i ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .en_i ( en == SP2V_HIGH ), + .out_req_o ( sub_word_out_req[i] ), + .out_ack_i ( out_ack == SP2V_HIGH ), + .op_i ( CIPH_FWD ), + .data_i ( sub_word_in[8*i +: 8] ), + .mask_i ( sw_in_mask[8*i +: 8] ), + .prd_i ( in_prd[i] ), + .data_o ( sub_word_out[8*i +: 8] ), + .mask_o ( sw_out_mask[8*i +: 8] ), + .prd_o ( out_prd[i] ) + ); + end + + // Add Rcon + assign rcon_add_in = sub_word_out[7:0]; + assign rcon_add_out = rcon_add_in ^ rcon_q; + assign rcon_added = {sub_word_out[31:8], rcon_add_out}; + + // Mux output coming from Rcon & SubWord + for (genvar s = 0; s < NumShares; s++) begin : gen_shares_irregular + if (s == 0) begin : gen_irregular_rcon + // The (masked) key share + assign irregular[s] = use_rcon ? rcon_added : sub_word_out; + end else begin : gen_irregular_no_rcon + // The mask share + assign irregular[s] = sw_out_mask; + end + end + + /////////////////////////// + // The more regular part // + /////////////////////////// + + // To reduce muxing resources, we re-use existing + // connections for unused words and default cases. + for (genvar s = 0; s < NumShares; s++) begin : gen_shares_regular + always_comb begin : drive_regular + unique case (key_len_i) + + ///////////// + // AES-128 // + ///////////// + AES_128: begin + // key_o[7:4] not used + regular[s][7:4] = key_i[s][3:0]; + + regular[s][0] = irregular[s] ^ key_i[s][0]; + unique case (op_i) + CIPH_FWD: begin + for (int i = 1; i < 4; i++) begin + regular[s][i] = regular[s][i-1] ^ key_i[s][i]; + end + end + + CIPH_INV: begin + for (int i = 1; i < 4; i++) begin + regular[s][i] = key_i[s][i-1] ^ key_i[s][i]; + end + end + + default: regular[s] = {key_i[s][3:0], key_i[s][7:4]}; + endcase + end + + ///////////// + // AES-192 // + ///////////// + AES_192: begin + // key_o[7:6] not used + regular[s][7:6] = key_i[s][3:2]; + + if (AES192Enable) begin + unique case (op_i) + CIPH_FWD: begin + if (rnd_type[0]) begin + // Shift down four upper most words + regular[s][3:0] = key_i[s][5:2]; + // Generate Words 6 and 7 + regular[s][4] = irregular[s] ^ key_i[s][0]; + regular[s][5] = regular[s][4] ^ key_i[s][1]; + end else begin + // Shift down two upper most words + regular[s][1:0] = key_i[s][5:4]; + // Generate new upper four words + for (int i = 0; i < 4; i++) begin + if ((i == 0 && rnd_type[2]) || + (i == 2 && rnd_type[3])) begin + regular[s][i+2] = irregular[s] ^ key_i[s][i]; + end else begin + regular[s][i+2] = regular[s][i+1] ^ key_i[s][i]; + end + end + end // rnd_type[0] + end + + CIPH_INV: begin + if (rnd_type[0]) begin + // Shift up four lowest words + regular[s][5:2] = key_i[s][3:0]; + // Generate Word 44 and 45 + for (int i = 0; i < 2; i++) begin + regular[s][i] = key_i[s][3+i] ^ key_i[s][3+i+1]; + end + end else begin + // Shift up two lowest words + regular[s][5:4] = key_i[s][1:0]; + // Generate new lower four words + for (int i = 0; i < 4; i++) begin + if ((i == 2 && rnd_type[1]) || + (i == 0 && rnd_type[2])) begin + regular[s][i] = irregular[s] ^ key_i[s][i+2]; + end else begin + regular[s][i] = key_i[s][i+1] ^ key_i[s][i+2]; + end + end + end // rnd_type[0] + end + + default: regular[s] = {key_i[s][3:0], key_i[s][7:4]}; + endcase + + end else begin + regular[s] = {key_i[s][3:0], key_i[s][7:4]}; + end // AES192Enable + end + + ///////////// + // AES-256 // + ///////////// + AES_256: begin + unique case (op_i) + CIPH_FWD: begin + if (rnd == 0) begin + // Round 0: Nothing to be done + // The Full Key registers are not updated + regular[s] = {key_i[s][3:0], key_i[s][7:4]}; + end else begin + // Shift down old upper half + regular[s][3:0] = key_i[s][7:4]; + // Generate new upper half + regular[s][4] = irregular[s] ^ key_i[s][0]; + for (int i = 1; i < 4; i++) begin + regular[s][i+4] = regular[s][i+4-1] ^ key_i[s][i]; + end + end // rnd == 0 + end + + CIPH_INV: begin + if (rnd == 0) begin + // Round 0: Nothing to be done + // The Full Key registers are not updated + regular[s] = {key_i[s][3:0], key_i[s][7:4]}; + end else begin + // Shift up old lower half + regular[s][7:4] = key_i[s][3:0]; + // Generate new lower half + regular[s][0] = irregular[s] ^ key_i[s][4]; + for (int i = 0; i < 3; i++) begin + regular[s][i+1] = key_i[s][4+i] ^ key_i[s][4+i+1]; + end + end // rnd == 0 + end + + default: regular[s] = {key_i[s][3:0], key_i[s][7:4]}; + endcase + end + + default: regular[s] = {key_i[s][3:0], key_i[s][7:4]}; + endcase // key_len_i + end // drive_regular + end // gen_shares_regular + + // Drive output + assign key_o = regular; + assign out_req_o = &sub_word_out_req ? SP2V_HIGH : SP2V_LOW; + + ////////////////////////////// + // Sparsely Encoded Signals // + ////////////////////////////// + + logic [Sp2VWidth-1:0] en_raw; + aes_sel_buf_chk #( + .Num ( Sp2VNum ), + .Width ( Sp2VWidth ), + .EnSecBuf ( 1'b1 ) + ) u_aes_key_expand_en_buf_chk ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .sel_i ( en_i ), + .sel_o ( en_raw ), + .err_o ( en_err ) + ); + assign en = sp2v_e'(en_raw); + + logic [Sp2VWidth-1:0] out_ack_raw; + aes_sel_buf_chk #( + .Num ( Sp2VNum ), + .Width ( Sp2VWidth ), + .EnSecBuf ( 1'b1 ) + ) u_aes_key_expand_out_ack_buf_chk ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .sel_i ( out_ack_i ), + .sel_o ( out_ack_raw ), + .err_o ( out_ack_err ) + ); + assign out_ack = sp2v_e'(out_ack_raw); + + // Collect encoding errors. + assign err_o = en_err | out_ack_err; + + //////////////// + // Assertions // + //////////////// + + // Create a lint error to reduce the risk of accidentally disabling the masking. + `CALIPTRA_ASSERT_STATIC_LINT_ERROR(AesKeyExpandSecMaskingNonDefault, SecMasking == 1) + + // Cipher core masking requires a masked SBox and vice versa. + `CALIPTRA_ASSERT_INIT(AesMaskedCoreAndSBox, + (SecMasking && + (SecSBoxImpl == SBoxImplCanrightMasked || + SecSBoxImpl == SBoxImplCanrightMaskedNoreuse || + SecSBoxImpl == SBoxImplDom)) || + (!SecMasking && + (SecSBoxImpl == SBoxImplLut || + SecSBoxImpl == SBoxImplCanright))) + + // Selectors must be known/valid + `CALIPTRA_ASSERT(AesCiphOpValid, cfg_valid_i |-> op_i inside { + CIPH_FWD, + CIPH_INV + }) + `CALIPTRA_ASSERT(AesKeyLenValid, cfg_valid_i |-> key_len_i inside { + AES_128, + AES_192, + AES_256 + }) + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/aes_mix_columns.sv b/designs/Caliptra/src/caliptra-rtl/aes_mix_columns.sv new file mode 100644 index 0000000..d2c5559 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/aes_mix_columns.sv @@ -0,0 +1,32 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// AES MixColumns + +module aes_mix_columns ( + input aes_pkg::ciph_op_e op_i, + input logic [3:0][3:0][7:0] data_i, + output logic [3:0][3:0][7:0] data_o +); + + import aes_pkg::*; + + // Transpose to operate on columns + logic [3:0][3:0][7:0] data_i_transposed; + logic [3:0][3:0][7:0] data_o_transposed; + + assign data_i_transposed = aes_transpose(data_i); + + // Individually mix columns + for (genvar i = 0; i < 4; i++) begin : gen_mix_column + aes_mix_single_column u_aes_mix_column_i ( + .op_i ( op_i ), + .data_i ( data_i_transposed[i] ), + .data_o ( data_o_transposed[i] ) + ); + end + + assign data_o = aes_transpose(data_o_transposed); + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/aes_mix_single_column.sv b/designs/Caliptra/src/caliptra-rtl/aes_mix_single_column.sv new file mode 100644 index 0000000..6b7cfd1 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/aes_mix_single_column.sv @@ -0,0 +1,70 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// AES MixColumns for one single column of the state matrix +// +// For details, see Equations 4-7 of: +// Satoh et al., "A Compact Rijndael Hardware Architecture with S-Box Optimization" + +module aes_mix_single_column ( + input aes_pkg::ciph_op_e op_i, + input logic [3:0][7:0] data_i, + output logic [3:0][7:0] data_o +); + + import aes_pkg::*; + + logic [3:0][7:0] x; + logic [1:0][7:0] y; + logic [1:0][7:0] z; + + logic [3:0][7:0] x_mul2; + logic [1:0][7:0] y_pre_mul4; + logic [7:0] y2, y2_pre_mul2; + + logic [1:0][7:0] z_muxed; + + // Drive x + assign x[0] = data_i[0] ^ data_i[3]; + assign x[1] = data_i[3] ^ data_i[2]; + assign x[2] = data_i[2] ^ data_i[1]; + assign x[3] = data_i[1] ^ data_i[0]; + + // Mul2(x) + for (genvar i = 0; i < 4; i++) begin : gen_x_mul2 + assign x_mul2[i] = aes_mul2(x[i]); + end + + // Drive y_pre_mul4 + assign y_pre_mul4[0] = data_i[3] ^ data_i[1]; + assign y_pre_mul4[1] = data_i[2] ^ data_i[0]; + + // Mul4(y_pre_mul4) + for (genvar i = 0; i < 2; i++) begin : gen_mul4 + assign y[i] = aes_mul4(y_pre_mul4[i]); + end + + // Drive y2_pre_mul2 + assign y2_pre_mul2 = y[0] ^ y[1]; + + // Mul2(y) + assign y2 = aes_mul2(y2_pre_mul2); + + // Drive z + assign z[0] = y2 ^ y[0]; + assign z[1] = y2 ^ y[1]; + + // Mux z + assign z_muxed[0] = (op_i == CIPH_FWD) ? 8'b0 : + (op_i == CIPH_INV) ? z[0] : 8'b0; + assign z_muxed[1] = (op_i == CIPH_FWD) ? 8'b0 : + (op_i == CIPH_INV) ? z[1] : 8'b0; + + // Drive outputs + assign data_o[0] = data_i[1] ^ x_mul2[3] ^ x[1] ^ z_muxed[1]; + assign data_o[1] = data_i[0] ^ x_mul2[2] ^ x[1] ^ z_muxed[0]; + assign data_o[2] = data_i[3] ^ x_mul2[1] ^ x[3] ^ z_muxed[1]; + assign data_o[3] = data_i[2] ^ x_mul2[0] ^ x[3] ^ z_muxed[0]; + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/aes_pkg.sv b/designs/Caliptra/src/caliptra-rtl/aes_pkg.sv new file mode 100644 index 0000000..f6d9f8e --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/aes_pkg.sv @@ -0,0 +1,768 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// AES package + +package aes_pkg; + +// If this parameter is set, fatal alerts clear all status and trigger bits to zero. By +// default, it's not set, i.e., no clearing is happening, in order to simplify debugging. +parameter bit ClearStatusOnFatalAlert = 1'b0; + +// The initial key is always provided in two shares, independently whether the cipher core is +// masked or not. +parameter int unsigned NumSharesKey = 2; + +// Software updates IV in chunks of 32 bits, the counter updates 16 bits at a time. +parameter int unsigned SliceSizeCtr = 16; +parameter int unsigned NumSlicesCtr = aes_reg_pkg::NumRegsIv * 32 / SliceSizeCtr; +parameter int unsigned SliceIdxWidth = caliptra_prim_util_pkg::vbits(NumSlicesCtr); + +// In GCM, the counter performs inc32() instead of inc128(), i.e., the counter wraps at 32 bits. +parameter int unsigned SliceIdxMaxInc32 = 32 / SliceSizeCtr - 1; + +// Widths of signals carrying pseudo-random data for clearing +parameter int unsigned WidthPRDClearing = 64; +parameter int unsigned NumChunksPRDClearing128 = 128/WidthPRDClearing; +parameter int unsigned NumChunksPRDClearing256 = 256/WidthPRDClearing; + +// Widths of signals carrying pseudo-random data for masking +parameter int unsigned WidthPRDSBox = 8; // Number PRD bits per S-Box. This includes the + // 8 bits for the output mask when using any of the + // masked Canright S-Box implementations. +parameter int unsigned WidthPRDData = 16*WidthPRDSBox; // 16 S-Boxes for the data path +parameter int unsigned WidthPRDKey = 4*WidthPRDSBox; // 4 S-Boxes for the key expand +parameter int unsigned WidthPRDMasking = WidthPRDData + WidthPRDKey; + +// Clearing PRNG default LFSR seed and permutation +// These LFSR parameters have been generated with +// $ util/design/gen-lfsr-seed.py --width 64 --seed 31468618 --prefix "Clearing" +parameter int ClearingLfsrWidth = 64; +typedef logic [ClearingLfsrWidth-1:0] clearing_lfsr_seed_t; +typedef logic [ClearingLfsrWidth-1:0][$clog2(ClearingLfsrWidth)-1:0] clearing_lfsr_perm_t; +parameter clearing_lfsr_seed_t RndCnstClearingLfsrSeedDefault = 64'hc32d580f74f1713a; +parameter clearing_lfsr_perm_t RndCnstClearingLfsrPermDefault = { + 128'hb33fdfc81deb6292c21f8a3102585067, + 256'h9c2f4be1bbe937b4b7c9d7f4e57568d99c8ae291a899143e0d8459d31b143223 +}; +// A second permutation is needed for the second share. +parameter clearing_lfsr_perm_t RndCnstClearingSharePermDefault = { + 128'hf66fd61b27847edc2286706fb3a2e900, + 256'h9736b95ac3f3b5205caf8dc536aad73605d393c8dd94476e830e97891d4828d0 +}; + +// Masking PRNG default state seed and output permutation +// The output width is 160 bits (WidthPRDMasking = WidthPRDSBox * (16 + 4)). +// These LFSR parameters have been generated with +// $ util/design/gen-lfsr-seed.py --width 160 --seed 31468618 --prefix "Masking" +parameter int MaskingLfsrWidth = 160; // = WidthPRDMasking = WidthPRDSBox * (16 + 4) +typedef logic [MaskingLfsrWidth-1:0][$clog2(MaskingLfsrWidth)-1:0] masking_lfsr_perm_t; +parameter masking_lfsr_perm_t RndCnstMaskingLfsrPermDefault = { + 256'h17261943423e4c5c03872194050c7e5f8497081d96666d406f4b606473303469, + 256'h8e7c721c8832471f59919e0b128f067b25622768462e554d8970815d490d7f44, + 256'h048c867d907a239b20220f6c79071a852d76485452189f14091b1e744e396737, + 256'h4f785b772b352f6550613c58130a8b104a3f28019c9a380233956b00563a512c, + 256'h808d419d63982a16995e0e3b57826a36718a9329452492533d83115a75316e15 +}; +// The state width is 177 bits (Bivium) but the primitive expects a 288-bit seed (Trivium). +// These LFSR parameters have been generated with +// $ util/design/gen-lfsr-seed.py --width 288 --seed 31468618 --prefix "Masking" +parameter int MaskingPrngStateWidth = 288; +typedef logic [MaskingPrngStateWidth-1:0] masking_lfsr_seed_t; +parameter masking_lfsr_seed_t RndCnstMaskingLfsrSeedDefault = { + 32'h758a4420, + 256'h31e1c461_6ea343ec_153282a3_0c132b57_23c5a4cf_4743b3c7_c32d580f_74f1713a +}; + +typedef enum logic [31:0] { + SBoxImplLut, // Unmasked LUT-based S-Box + SBoxImplCanright, // Unmasked Canright S-Box, see aes_sbox_canright.sv + SBoxImplCanrightMasked, // First-order masked Canright S-Box + // see aes_sbox_canright_masked.sv + SBoxImplCanrightMaskedNoreuse, // First-order masked Canright S-Box without mask reuse, + // see aes_sbox_canright_masked_noreuse.sv + SBoxImplDom // First-order masked S-Box using domain-oriented masking, + // see aes_sbox_canright_dom.sv +} sbox_impl_e; + +// GF(2^128) irreducible, field-generating polynomial for AES-GCM +// See Section "6.3 Multiplication Operation on Blocks" of +// https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf on Page 11: +// "Let R be the bit string 11100001 || 0^120." +// And further on Page 12: +// "The reduction modulus is the polynomial of degree 128 that corresponds to R || 1" +// Or in other words: x^128 + x^7 + x^2 + x + 1 +// The MSB gets clipped off below. +parameter int unsigned GCMDegree = 128; +parameter bit [GCMDegree-1:0] GCMIPoly = GCMDegree'(1'b1) << 7 | + GCMDegree'(1'b1) << 2 | + GCMDegree'(1'b1) << 1 | + GCMDegree'(1'b1) << 0; + +// Parameters used for controlgroups in the coverage +parameter int AES_OP_WIDTH = 2; +parameter int AES_MODE_WIDTH = 6; +parameter int AES_KEYLEN_WIDTH = 3; +parameter int AES_PRNGRESEEDRATE_WIDTH = 3; +parameter int AES_GCMPHASE_WIDTH = 6; + +// SEC_CM: MAIN.CONFIG.SPARSE +typedef enum logic [AES_OP_WIDTH-1:0] { + AES_ENC = 2'b01, + AES_DEC = 2'b10 +} aes_op_e; + +// SEC_CM: MAIN.CONFIG.SPARSE +typedef enum logic [AES_MODE_WIDTH-1:0] { + AES_ECB = 6'b00_0001, + AES_CBC = 6'b00_0010, + AES_CFB = 6'b00_0100, + AES_OFB = 6'b00_1000, + AES_CTR = 6'b01_0000, + AES_GCM = 6'b10_0000, + AES_NONE = 6'b11_1111 +} aes_mode_e; + +// SEC_CM: MAIN.CONFIG.SPARSE +typedef enum logic [AES_OP_WIDTH-1:0] { + CIPH_FWD = 2'b01, + CIPH_INV = 2'b10 +} ciph_op_e; + +// SEC_CM: MAIN.CONFIG.SPARSE +typedef enum logic [AES_KEYLEN_WIDTH-1:0] { + AES_128 = 3'b001, + AES_192 = 3'b010, + AES_256 = 3'b100 +} key_len_e; + +// SEC_CM: MAIN.CONFIG.SPARSE +typedef enum logic [AES_PRNGRESEEDRATE_WIDTH-1:0] { + PER_1 = 3'b001, + PER_64 = 3'b010, + PER_8K = 3'b100 +} prs_rate_e; +parameter int unsigned BlockCtrWidth = 13; + +// SEC_CM: GCM.CONFIG.SPARSE +typedef enum logic [AES_GCMPHASE_WIDTH-1:0] { + GCM_INIT = 6'b00_0001, + GCM_RESTORE = 6'b00_0010, + GCM_AAD = 6'b00_0100, + GCM_TEXT = 6'b00_1000, + GCM_SAVE = 6'b01_0000, + GCM_TAG = 6'b10_0000 +} gcm_phase_e; + +typedef struct packed { + logic [31:7] unused; + logic alert_fatal_fault; + logic alert_recov_ctrl_update_err; + logic input_ready; + logic output_valid; + logic output_lost; + logic stall; + logic idle; +} status_t; + +typedef struct packed { + logic recov_ctrl_update_err; + logic fatal_fault; +} alert_test_t; + + // Sparse state encodings + + // Encoding generated with: + // $ ./util/design/sparse-fsm-encode.py -d 3 -m 8 -n 6 \ + // -s 31468618 --language=sv + // + // Hamming distance histogram: + // + // 0: -- + // 1: -- + // 2: -- + // 3: |||||||||||||||||||| (57.14%) + // 4: ||||||||||||||| (42.86%) + // 5: -- + // 6: -- + // + // Minimum Hamming distance: 3 + // Maximum Hamming distance: 4 + // Minimum Hamming weight: 1 + // Maximum Hamming weight: 5 + // + localparam int CipherCtrlStateWidth = 6; + typedef enum logic [CipherCtrlStateWidth-1:0] { + CIPHER_CTRL_IDLE = 6'b001001, + CIPHER_CTRL_INIT = 6'b100011, + CIPHER_CTRL_ROUND = 6'b111101, + CIPHER_CTRL_FINISH = 6'b010000, + CIPHER_CTRL_PRNG_RESEED = 6'b100100, + CIPHER_CTRL_CLEAR_S = 6'b111010, + CIPHER_CTRL_CLEAR_KD = 6'b001110, + CIPHER_CTRL_ERROR = 6'b010111 + } aes_cipher_ctrl_e; + + // $ ./sparse-fsm-encode.py -d 3 -m 3 -n 5 \ + // -s 31468618 --language=sv + // + // Hamming distance histogram: + // + // 0: -- + // 1: -- + // 2: -- + // 3: |||||||||||||||||||| (66.67%) + // 4: |||||||||| (33.33%) + // 5: -- + // + // Minimum Hamming distance: 3 + // Maximum Hamming distance: 4 + // + localparam int CtrStateWidth = 5; + typedef enum logic [CtrStateWidth-1:0] { + CTR_IDLE = 5'b01110, + CTR_INCR = 5'b11000, + CTR_ERROR = 5'b00001 + } aes_ctr_e; + + // Encoding generated with: + // $ ./util/design/sparse-fsm-encode.py -d 3 -m 8 -n 6 \ + // -s 31468618 --language=sv + // + // Hamming distance histogram: + // + // 0: -- + // 1: -- + // 2: -- + // 3: |||||||||||||||||||| (57.14%) + // 4: ||||||||||||||| (42.86%) + // 5: -- + // 6: -- + // + // Minimum Hamming distance: 3 + // Maximum Hamming distance: 4 + // Minimum Hamming weight: 1 + // Maximum Hamming weight: 5 + // + localparam int CtrlStateWidth = 6; + typedef enum logic [CtrlStateWidth-1:0] { + CTRL_IDLE = 6'b001001, + CTRL_LOAD = 6'b100011, + CTRL_GHASH_READY = 6'b111101, + CTRL_PRNG_RESEED = 6'b010000, + CTRL_FINISH = 6'b100100, + CTRL_CLEAR_I = 6'b111010, + CTRL_CLEAR_CO = 6'b001110, + CTRL_ERROR = 6'b010111 + } aes_ctrl_e; + +// Encoding generated with: +// $ ./util/design/sparse-fsm-encode.py -d 3 -m 9 -n 7 \ +// -s 31468618 --language=sv +// +// Hamming distance histogram: +// +// 0: -- +// 1: -- +// 2: -- +// 3: |||||||||||||||||| (38.89%) +// 4: |||||||||||||||||||| (41.67%) +// 5: |||||||| (16.67%) +// 6: | (2.78%) +// 7: -- +// +// Minimum Hamming distance: 3 +// Maximum Hamming distance: 6 +// Minimum Hamming weight: 1 +// Maximum Hamming weight: 5 +// +localparam int GhashStateWidth = 7; +typedef enum logic [GhashStateWidth-1:0] { + GHASH_IDLE = 7'b1100001, + GHASH_MULT = 7'b0010001, + GHASH_ADD_S = 7'b0000110, + GHASH_OUT = 7'b0110111, + GHASH_ERROR = 7'b0111010, + GHASH_MASKED_INIT = 7'b1111100, + GHASH_MASKED_ADD_STATE_SHARES = 7'b0101101, + GHASH_MASKED_ADD_CORR = 7'b0001000, + GHASH_MASKED_SETTLE = 7'b1001111 +} aes_ghash_e; + +// Generic, sparse mux selector encodings + +// Encoding generated with: +// $ ./util/design/sparse-fsm-encode.py -d 3 -m 2 -n 3 \ +// -s 31468618 --language=sv +// +// Hamming distance histogram: +// +// 0: -- +// 1: -- +// 2: -- +// 3: |||||||||||||||||||| (100.00%) +// +// Minimum Hamming distance: 3 +// Maximum Hamming distance: 3 +// Minimum Hamming weight: 1 +// Maximum Hamming weight: 2 +// +parameter int Mux2SelWidth = 3; +typedef enum logic [Mux2SelWidth-1:0] { + MUX2_SEL_0 = 3'b011, + MUX2_SEL_1 = 3'b100 +} mux2_sel_e; + +// Encoding generated with: +// $ ./sparse-fsm-encode.py -d 3 -m 3 -n 5 \ +// -s 31468618 --language=sv +// +// Hamming distance histogram: +// +// 0: -- +// 1: -- +// 2: -- +// 3: |||||||||||||||||||| (66.67%) +// 4: |||||||||| (33.33%) +// 5: -- +// +// Minimum Hamming distance: 3 +// Maximum Hamming distance: 4 +// +parameter int Mux3SelWidth = 5; +typedef enum logic [Mux3SelWidth-1:0] { + MUX3_SEL_0 = 5'b01110, + MUX3_SEL_1 = 5'b11000, + MUX3_SEL_2 = 5'b00001 +} mux3_sel_e; + +// Encoding generated with: +// $ ./sparse-fsm-encode.py -d 3 -m 4 -n 5 \ +// -s 31468618 --language=sv +// +// Hamming distance histogram: +// +// 0: -- +// 1: -- +// 2: -- +// 3: |||||||||||||||||||| (66.67%) +// 4: |||||||||| (33.33%) +// 5: -- +// +// Minimum Hamming distance: 3 +// Maximum Hamming distance: 4 +// +parameter int Mux4SelWidth = 5; +typedef enum logic [Mux4SelWidth-1:0] { + MUX4_SEL_0 = 5'b01110, + MUX4_SEL_1 = 5'b11000, + MUX4_SEL_2 = 5'b00001, + MUX4_SEL_3 = 5'b10111 +} mux4_sel_e; + +// Encoding generated with: +// $ ./util/design/sparse-fsm-encode.py -d 3 -m 5 -n 6 \ +// -s 31468618 --language=sv +// +// Hamming distance histogram: +// +// 0: -- +// 1: -- +// 2: -- +// 3: |||||||||||||||||||| (50.00%) +// 4: |||||||||||||||| (40.00%) +// 5: |||| (10.00%) +// 6: -- +// +// Minimum Hamming distance: 3 +// Maximum Hamming distance: 5 +// Minimum Hamming weight: 1 +// Maximum Hamming weight: 5 +// +localparam int Mux5SelWidth = 6; +typedef enum logic [Mux5SelWidth-1:0] { + MUX5_SEL_0 = 6'b110000, + MUX5_SEL_1 = 6'b001000, + MUX5_SEL_2 = 6'b000011, + MUX5_SEL_3 = 6'b011101, + MUX5_SEL_4 = 6'b111110 +} mux5_sel_e; + + +// $ ./sparse-fsm-encode.py -d 3 -m 6 -n 6 \ +// -s 31468618 --language=sv +// +// Hamming distance histogram: +// +// 0: -- +// 1: -- +// 2: -- +// 3: |||||||||||||||||||| (53.33%) +// 4: ||||||||||||||| (40.00%) +// 5: || (6.67%) +// 6: -- +// +// Minimum Hamming distance: 3 +// Maximum Hamming distance: 5 +// +parameter int Mux6SelWidth = 6; +typedef enum logic [Mux6SelWidth-1:0] { + MUX6_SEL_0 = 6'b011101, + MUX6_SEL_1 = 6'b110000, + MUX6_SEL_2 = 6'b001000, + MUX6_SEL_3 = 6'b000011, + MUX6_SEL_4 = 6'b111110, + MUX6_SEL_5 = 6'b100101 +} mux6_sel_e; + +// Mux selector signal types. These use the generic types defined above. + +parameter int DIPSelNum = 2; +parameter int DIPSelWidth = Mux2SelWidth; +typedef enum logic [DIPSelWidth-1:0] { + DIP_DATA_IN = MUX2_SEL_0, + DIP_CLEAR = MUX2_SEL_1 +} dip_sel_e; + +parameter int SISelNum = 2; +parameter int SISelWidth = Mux2SelWidth; +typedef enum logic [SISelWidth-1:0] { + SI_ZERO = MUX2_SEL_0, + SI_DATA = MUX2_SEL_1 +} si_sel_e; + +parameter int AddSISelNum = 2; +parameter int AddSISelWidth = Mux2SelWidth; +typedef enum logic [AddSISelWidth-1:0] { + ADD_SI_ZERO = MUX2_SEL_0, + ADD_SI_IV = MUX2_SEL_1 +} add_si_sel_e; + +parameter int StateSelNum = 3; +parameter int StateSelWidth = Mux3SelWidth; +typedef enum logic [StateSelWidth-1:0] { + STATE_INIT = MUX3_SEL_0, + STATE_ROUND = MUX3_SEL_1, + STATE_CLEAR = MUX3_SEL_2 +} state_sel_e; + +parameter int AddRKSelNum = 3; +parameter int AddRKSelWidth = Mux3SelWidth; +typedef enum logic [AddRKSelWidth-1:0] { + ADD_RK_INIT = MUX3_SEL_0, + ADD_RK_ROUND = MUX3_SEL_1, + ADD_RK_FINAL = MUX3_SEL_2 +} add_rk_sel_e; + +parameter int KeyInitSelNum = 3; +parameter int KeyInitSelWidth = Mux3SelWidth; +typedef enum logic [KeyInitSelWidth-1:0] { + KEY_INIT_INPUT = MUX3_SEL_0, + KEY_INIT_KEYMGR = MUX3_SEL_1, + KEY_INIT_CLEAR = MUX3_SEL_2 +} key_init_sel_e; + +parameter int IVSelNum = 6; +parameter int IVSelWidth = Mux6SelWidth; +typedef enum logic [IVSelWidth-1:0] { + IV_INPUT = MUX6_SEL_0, + IV_DATA_OUT = MUX6_SEL_1, + IV_DATA_OUT_RAW = MUX6_SEL_2, + IV_DATA_IN_PREV = MUX6_SEL_3, + IV_CTR = MUX6_SEL_4, + IV_CLEAR = MUX6_SEL_5 +} iv_sel_e; + +parameter int KeyFullSelNum = 4; +parameter int KeyFullSelWidth = Mux4SelWidth; +typedef enum logic [KeyFullSelWidth-1:0] { + KEY_FULL_ENC_INIT = MUX4_SEL_0, + KEY_FULL_DEC_INIT = MUX4_SEL_1, + KEY_FULL_ROUND = MUX4_SEL_2, + KEY_FULL_CLEAR = MUX4_SEL_3 +} key_full_sel_e; + +parameter int KeyDecSelNum = 2; +parameter int KeyDecSelWidth = Mux2SelWidth; +typedef enum logic [KeyDecSelWidth-1:0] { + KEY_DEC_EXPAND = MUX2_SEL_0, + KEY_DEC_CLEAR = MUX2_SEL_1 +} key_dec_sel_e; + +parameter int KeyWordsSelNum = 4; +parameter int KeyWordsSelWidth = Mux4SelWidth; +typedef enum logic [KeyWordsSelWidth-1:0] { + KEY_WORDS_0123 = MUX4_SEL_0, + KEY_WORDS_2345 = MUX4_SEL_1, + KEY_WORDS_4567 = MUX4_SEL_2, + KEY_WORDS_ZERO = MUX4_SEL_3 +} key_words_sel_e; + +parameter int RoundKeySelNum = 2; +parameter int RoundKeySelWidth = Mux2SelWidth; +typedef enum logic [RoundKeySelWidth-1:0] { + ROUND_KEY_DIRECT = MUX2_SEL_0, + ROUND_KEY_MIXED = MUX2_SEL_1 +} round_key_sel_e; + +parameter int AddSOSelNum = 3; +parameter int AddSOSelWidth = Mux3SelWidth; +typedef enum logic [AddSOSelWidth-1:0] { + ADD_SO_ZERO = MUX3_SEL_0, + ADD_SO_IV = MUX3_SEL_1, + ADD_SO_DIP = MUX3_SEL_2 +} add_so_sel_e; + +parameter int GHashInSelNum = 2; +parameter int GHashInSelWidth = Mux2SelWidth; +typedef enum logic [GHashInSelWidth-1:0] { + GHASH_IN_DATA_IN_PREV = MUX2_SEL_0, + GHASH_IN_DATA_OUT = MUX2_SEL_1 +} ghash_in_sel_e; + +parameter int GHashAddInSelWidth = 3; +typedef enum logic [GHashAddInSelWidth-1:0] { + ADD_IN_GHASH_IN = 3'b001, + ADD_IN_CORR_A = 3'b010, + ADD_IN_CORR_B = 3'b100, + ADD_IN_ZERO = 3'b000 +} ghash_add_in_sel_e; + +parameter int GHashStateSelNum = 5; +parameter int GHashStateSelWidth = Mux5SelWidth; +typedef enum logic [GHashStateSelWidth-1:0] { + GHASH_STATE_RESTORE = MUX5_SEL_0, + GHASH_STATE_INIT = MUX5_SEL_1, + GHASH_STATE_ADD = MUX5_SEL_2, + GHASH_STATE_ADD_S = MUX5_SEL_3, + GHASH_STATE_MULT = MUX5_SEL_4 +} ghash_state_sel_e; + +parameter int GFMultInSelWidth = 3; +typedef enum logic [GFMultInSelWidth-1:0] { + MULT_IN_STATE0 = 3'b001, + MULT_IN_STATE1 = 3'b010, + MULT_IN_S1 = 3'b100, + MULT_IN_ZERO = 3'b000 +} gf_mult_in_sel_e; + +parameter int DataOutSelNum = 2; +parameter int DataOutSelWidth = Mux2SelWidth; +typedef enum logic [DataOutSelWidth-1:0] { + DATA_OUT_CIPHER = MUX2_SEL_0, + DATA_OUT_GHASH = MUX2_SEL_1 +} data_out_sel_e; + +// Sparse two-value signal type sp2v_e +parameter int Sp2VNum = 2; +parameter int Sp2VWidth = Mux2SelWidth; +typedef enum logic [Sp2VWidth-1:0] { + SP2V_HIGH = MUX2_SEL_0, + SP2V_LOW = MUX2_SEL_1 +} sp2v_e; + +typedef logic [Sp2VWidth-1:0] sp2v_logic_t; +parameter sp2v_logic_t SP2V_LOGIC_HIGH = {SP2V_HIGH}; + +// Control register type +typedef struct packed { + logic manual_operation; + prs_rate_e prng_reseed_rate; + logic sideload; + key_len_e key_len; + aes_mode_e mode; + aes_op_e operation; +} ctrl_reg_t; + +parameter ctrl_reg_t CTRL_RESET = '{ + manual_operation: aes_reg_pkg::AES_CTRL_SHADOWED_MANUAL_OPERATION_RESVAL, + prng_reseed_rate: prs_rate_e'(aes_reg_pkg::AES_CTRL_SHADOWED_PRNG_RESEED_RATE_RESVAL), + sideload: aes_reg_pkg::AES_CTRL_SHADOWED_SIDELOAD_RESVAL, + key_len: key_len_e'(aes_reg_pkg::AES_CTRL_SHADOWED_KEY_LEN_RESVAL), + mode: aes_mode_e'(aes_reg_pkg::AES_CTRL_SHADOWED_MODE_RESVAL), + operation: aes_op_e'(aes_reg_pkg::AES_CTRL_SHADOWED_OPERATION_RESVAL) +}; + +// GCM control register type +typedef struct packed { + logic [4:0] num_valid_bytes; + gcm_phase_e phase; +} ctrl_gcm_reg_t; + +// Multiplication by {02} (i.e. x) on GF(2^8) +// with field generating polynomial {01}{1b} (9'h11b) +// Sometimes also denoted by xtime(). +function automatic logic [7:0] aes_mul2(logic [7:0] in); + logic [7:0] out; + out[7] = in[6]; + out[6] = in[5]; + out[5] = in[4]; + out[4] = in[3] ^ in[7]; + out[3] = in[2] ^ in[7]; + out[2] = in[1]; + out[1] = in[0] ^ in[7]; + out[0] = in[7]; + return out; +endfunction + +// Multiplication by {04} (i.e. x^2) on GF(2^8) +// with field generating polynomial {01}{1b} (9'h11b) +function automatic logic [7:0] aes_mul4(logic [7:0] in); + return aes_mul2(aes_mul2(in)); +endfunction + +// Division by {02} (i.e. x) on GF(2^8) +// with field generating polynomial {01}{1b} (9'h11b) +// This is the inverse of aes_mul2() or xtime(). +function automatic logic [7:0] aes_div2(logic [7:0] in); + logic [7:0] out; + out[7] = in[0]; + out[6] = in[7]; + out[5] = in[6]; + out[4] = in[5]; + out[3] = in[4] ^ in[0]; + out[2] = in[3] ^ in[0]; + out[1] = in[2]; + out[0] = in[1] ^ in[0]; + return out; +endfunction + +// Circular byte shift to the left +function automatic logic [31:0] aes_circ_byte_shift(logic [31:0] in, logic [1:0] shift); + logic [31:0] out; + logic [31:0] s; + s = {30'b0,shift}; + out = {in[8*((7-s)%4) +: 8], in[8*((6-s)%4) +: 8], + in[8*((5-s)%4) +: 8], in[8*((4-s)%4) +: 8]}; + return out; +endfunction + +// Transpose state matrix +function automatic logic [3:0][3:0][7:0] aes_transpose(logic [3:0][3:0][7:0] in); + logic [3:0][3:0][7:0] transpose; + transpose = '0; + for (int j = 0; j < 4; j++) begin + for (int i = 0; i < 4; i++) begin + transpose[i][j] = in[j][i]; + end + end + return transpose; +endfunction + +// Convert AES byte state matrix to internal GHASH bit vector representation. +function automatic logic [127:0] aes_state_to_ghash_vec(logic [3:0][3:0][7:0] in); + logic [127:0] out; + logic [15:0][7:0] byte_vec; + for (int i = 0; i < 4; i++) begin + for (int j = 0; j < 4; j++) begin + byte_vec[15 - 4*i - j] = in[j][i]; + end + end + out = byte_vec; + return out; +endfunction + +// Convert internal GHASH bit vector representation to simple bit vector. +function automatic logic [127:0] aes_ghash_reverse_bit_order(logic [127:0] in); + logic [127:0] out; + for (int i = 0; i < 128; i++) begin + out[i] = in[127-i]; + end + return out; +endfunction + +// Extract single column from state matrix +function automatic logic [3:0][7:0] aes_col_get(logic [3:0][3:0][7:0] in, logic [1:0] idx); + logic [3:0][7:0] out; + for (int i = 0; i < 4; i++) begin + out[i] = in[i][idx]; + end + return out; +endfunction + +// Matrix-vector multiplication in GF(2^8): c = A * b +function automatic logic [7:0] aes_mvm( + logic [7:0] vec_b, + logic [7:0] mat_a [8] +); + logic [7:0] vec_c; + vec_c = '0; + for (int i = 0; i < 8; i++) begin + for (int j = 0; j < 8; j++) begin + vec_c[i] = vec_c[i] ^ (mat_a[j][i] & vec_b[7-j]); + end + end + return vec_c; +endfunction + +// Rotate integer indices +function automatic integer aes_rot_int(integer in, integer num); + integer out; + if (in == 0) begin + out = num - 1; + end else begin + out = in - 1; + end + return out; +endfunction + +// Function for extracting LSBs of the per-S-Box pseudo-random data (PRD) from the output of the +// masking PRNG. +// +// The masking PRNG is used for generating both the PRD for the S-Boxes/SubBytes operation as +// well as for the input data masks. When using any of the masked Canright S-Box implementations, +// it is important that the SubBytes input masks (generated by the PRNG in Round X-1) and the +// SubBytes output masks (generated by the PRNG in Round X) are independent. This can be achieved +// by using e.g. an unrolled Bivium stream cipher primitive inside the PRNG. Since the input data +// masks become the SubBytes input masks in the first round, we select the same 8 bit lanes for the +// input data masks which are also used to form the SubBytes output mask for the masked Canright +// S-Box implementations, i.e., the 8 LSBs of the per S-Box PRD. In particular, we have: +// +// prng_output = { prd_key_expand, ... , sb_prd[4], sb_out_mask[4], sb_prd[0], sb_out_mask[0] } +// +// Where sb_out_mask[x] contains the SubBytes output mask for byte x (when using a masked +// Canright S-Box implementation) and sb_prd[x] contains additional PRD consumed by SubBytes for +// byte x. +// +// When using a masked S-Box implementation other than Canright, we still select the 8 LSBs of +// the per-S-Box PRD to form the input data mask of the corresponding byte. We do this to +// distribute the input data masks over all output bits the masking PRNG. + +// For one row of the state matrix, extract the 8 LSBs of the per-S-Box PRD from the PRNG output. +// These bits are used as: +// - input data masks, and +// - SubBytes output mask when using a masked Canright S-Box implementation. +function automatic logic [3:0][7:0] aes_prd_get_lsbs( + logic [(4*WidthPRDSBox)-1:0] in +); + logic [3:0][7:0] prd_lsbs; + for (int i = 0; i < 4; i++) begin + prd_lsbs[i] = in[i*WidthPRDSBox +: 8]; + end + return prd_lsbs; +endfunction + +/* ------------------------- CALIPTRA definitions ------------------------- */ + +// AES writes to KeyVault have a max value of 512b +parameter CLP_AES_KV_WR_DW = 512; + +typedef struct packed { + logic kv_en; + logic kv_write_done; + logic block_reg_output; + logic clear_secrets; + logic [15:0] key_release_key_size; +} caliptra2aes_t; + +typedef struct packed { + logic [CLP_AES_KV_WR_DW-1:0] kv_data_out; + logic kv_data_out_valid; + logic kv_key_in_use; + logic aes_operation_is_ecb_decrypt; +} aes2caliptra_t; + +/* ---------------------- END CALIPTRA definitions ------------------------ */ + +endpackage diff --git a/designs/Caliptra/src/caliptra-rtl/aes_prng_clearing.sv b/designs/Caliptra/src/caliptra-rtl/aes_prng_clearing.sv new file mode 100644 index 0000000..c656312 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/aes_prng_clearing.sv @@ -0,0 +1,165 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// AES low-bandwidth pseudo-random number generator for register clearing +// +// This module uses an LFSR followed by an aligned permutation, a non-linear layer (PRINCE S-Boxes) +// and another permutation to generate pseudo-random data for the AES module for clearing +// registers (secure wipe). The LFSR can be reseeded using an external interface. + +`include "caliptra_prim_assert.sv" + +module aes_prng_clearing import aes_pkg::*; +#( + parameter int unsigned Width = 64, // At the moment we just support a width of 64. + parameter int unsigned EntropyWidth = edn_pkg::ENDPOINT_BUS_WIDTH, + parameter bit SecSkipPRNGReseeding = 0, // The current SCA setup doesn't provide + // sufficient resources to implement the + // infrastructure required for PRNG reseeding. + // To enable SCA resistance evaluations, we + // need to skip reseeding requests. + parameter clearing_lfsr_seed_t RndCnstLfsrSeed = RndCnstClearingLfsrSeedDefault, + parameter clearing_lfsr_perm_t RndCnstLfsrPerm = RndCnstClearingLfsrPermDefault, + parameter clearing_lfsr_perm_t RndCnstSharePerm = RndCnstClearingSharePermDefault +) ( + input logic clk_i, + input logic rst_ni, + + // Connections to AES internals, PRNG consumers + input logic data_update_i, + output logic [Width-1:0] data_o [NumSharesKey], + input logic reseed_req_i, + output logic reseed_ack_o, + + // Connections to outer world, LFSR re-seed + output logic entropy_req_o, + input logic entropy_ack_i, + input logic [EntropyWidth-1:0] entropy_i +); + + logic seed_valid; + logic seed_en; + logic [Width-1:0] seed; + logic lfsr_en; + logic [Width-1:0] lfsr_state; + + // The data requests are fed from an LFSR. Reseed requests take precedence internally to the + // LFSR. If there is an outstanding reseed request, the PRNG can keep updating and providing + // pseudo-random data (using the old seed). If the reseeding is taking place, the LFSR will + // provide fresh pseudo-random data (the new seed) in the next cycle anyway. This means the PRNG + // is always ready to provide new pseudo-random data. + + // In the current SCA setup, we don't have sufficient resources to implement the infrastructure + // required for PRNG reseeding (CSRNG, EDN, etc.). Therefore, we skip any reseeding requests if + // the SecSkipPRNGReseeding parameter is set. Performing the reseeding without proper entropy + // provided from CSRNG would result in quickly repeating, fully deterministic PRNG output, + // which prevents meaningful SCA resistance evaluations. + + // Create a lint error to reduce the risk of accidentally enabling this feature. + `CALIPTRA_ASSERT_STATIC_LINT_ERROR(AesSecSkipPRNGReseedingNonDefault, SecSkipPRNGReseeding == 0) + + // LFSR control + assign lfsr_en = data_update_i; + assign seed_en = SecSkipPRNGReseeding ? 1'b0 : seed_valid; + + // Width adaption for reseeding interface. We get EntropyWidth bits at a time. + if (Width/2 == EntropyWidth) begin : gen_buffer + // We buffer the first EntropyWidth bits. + logic [EntropyWidth-1:0] buffer_d, buffer_q; + logic buffer_valid_d, buffer_valid_q; + + // Stop requesting entropy once we have reseeded the LFSR. + assign entropy_req_o = SecSkipPRNGReseeding ? 1'b0 : reseed_req_i; + assign reseed_ack_o = SecSkipPRNGReseeding ? reseed_req_i : seed_valid; + + // Buffer + assign buffer_valid_d = entropy_req_o && entropy_ack_i ? ~buffer_valid_q : buffer_valid_q; + + // Only update the buffer upon receiving the first EntropyWidth bits. + assign buffer_d = entropy_req_o && entropy_ack_i && !buffer_valid_q ? entropy_i : buffer_q; + + always_ff @(posedge clk_i or negedge rst_ni) begin : reg_buffer + if (!rst_ni) begin + buffer_q <= '0; + buffer_valid_q <= 1'b0; + end else begin + buffer_q <= buffer_d; + buffer_valid_q <= buffer_valid_d; + end + end + + assign seed = {buffer_q, entropy_i}; + assign seed_valid = buffer_valid_q & entropy_req_o & entropy_ack_i; + + end else begin : gen_packer + // Upsizing of entropy input to correct width for LFSR reseeding. + + // Stop requesting entropy once the desired amount is available. + assign entropy_req_o = SecSkipPRNGReseeding ? 1'b0 : reseed_req_i & ~seed_valid; + assign reseed_ack_o = SecSkipPRNGReseeding ? reseed_req_i : seed_valid; + + caliptra_prim_packer_fifo #( + .InW ( EntropyWidth ), + .OutW ( Width ), + .ClearOnRead ( 1'b0 ) + ) u_caliptra_prim_packer_fifo ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .clr_i ( 1'b0 ), // Not needed. + .wvalid_i ( entropy_ack_i ), + .wdata_i ( entropy_i ), + .wready_o ( ), // Not needed, we're always ready to sink data at this point. + .rvalid_o ( seed_valid ), + .rdata_o ( seed ), + .rready_i ( 1'b1 ), // We're always ready to receive the packed output word. + .depth_o ( ) // Not needed. + ); + end + + // LFSR instance + caliptra_prim_lfsr #( + .LfsrType ( "GAL_XOR" ), + .LfsrDw ( Width ), + .StateOutDw ( Width ), + .DefaultSeed ( RndCnstLfsrSeed ), + .StatePermEn ( 1'b1 ), + .StatePerm ( RndCnstLfsrPerm ), + .NonLinearOut ( 1'b1 ) + ) u_lfsr ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .seed_en_i ( seed_en ), + .seed_i ( seed ), + .lfsr_en_i ( lfsr_en ), + .entropy_i ( '0 ), + .state_o ( lfsr_state ) + ); + assign data_o[0] = lfsr_state; + + // A seperate permutation is applied to obtain the pseudo-random data for clearing the second + // share of registers (e.g. key registers or state registers in case masking is enabled). + for (genvar i = 0; i < Width; i++) begin : gen_share_perm + assign data_o[1][i] = lfsr_state[RndCnstSharePerm[i]]; + end + + // Width must be 64. + `CALIPTRA_ASSERT_INIT(AesPrngWidth, Width == 64) + +// the code below is not meant to be synthesized, +// but it is intended to be used in simulation and FPV +`ifndef SYNTHESIS + // Check that the supplied permutation is valid. + logic [Width-1:0] share_perm_test, unused_share_perm_test; + initial begin : p_share_perm_check + share_perm_test = '0; + for (int k = 0; k < Width; k++) begin + share_perm_test[RndCnstSharePerm[k]] = 1'b1; + end + unused_share_perm_test = share_perm_test; + // All bit positions must be marked with 1. + `CALIPTRA_ASSERT_I(SharePermutationCheck_A, &share_perm_test) + end +`endif + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/aes_prng_masking.sv b/designs/Caliptra/src/caliptra-rtl/aes_prng_masking.sv new file mode 100644 index 0000000..6e15f45 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/aes_prng_masking.sv @@ -0,0 +1,150 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// AES high-bandwidth pseudo-random number generator for masking +// +// This module uses a stream cipher primitive followed by a linear permutation layer to generate +// pseudo-random data for masking the AES cipher core. The stream cipher primitive can be reseeded +// using an external interface. + +`include "caliptra_prim_assert.sv" + +module aes_prng_masking import aes_pkg::*; +#( + parameter int unsigned Width = WidthPRDMasking, + parameter int unsigned EntropyWidth = edn_pkg::ENDPOINT_BUS_WIDTH, + parameter bit SecAllowForcingMasks = 0, // Allow forcing masks to constant values using + // force_masks_i. Useful for SCA only. + parameter bit SecSkipPRNGReseeding = 0, // The current SCA setup doesn't provide + // sufficient resources to implement the + // infrastructure required for PRNG reseeding. + // To enable SCA resistance evaluations, we + // need to skip reseeding requests. + + parameter masking_lfsr_seed_t RndCnstLfsrSeed = RndCnstMaskingLfsrSeedDefault, + parameter masking_lfsr_perm_t RndCnstLfsrPerm = RndCnstMaskingLfsrPermDefault +) ( + input logic clk_i, + input logic rst_ni, + + input logic force_masks_i, + + // Connections to AES internals, PRNG consumers + input logic data_update_i, + output logic [Width-1:0] data_o, + input logic reseed_req_i, + output logic reseed_ack_o, + + // Connections to outer world, LFSR reseeding + output logic entropy_req_o, + input logic entropy_ack_i, + input logic [EntropyWidth-1:0] entropy_i +); + + logic prng_seed_en; + logic prng_seed_done; + logic [Width-1:0] prng_key; + logic prng_err; + + ///////////// + // Control // + ///////////// + + // The data requests are fed from a stream cipher primitive that is reseeded in chunks of + // EntropyWidth bits. Internally, the primitive generates the output based on the current state. + // If there is an outstanding reseed request, the PRNG can keep updating and providing + // pseudo-random data (using the current state of the primitive). When reseeding a chunk without + // requesting a PRNG update, the current output might change or not, depending on the Width and + // current chunk index. + + // In the current SCA setup, we don't have sufficient resources to implement the infrastructure + // required for PRNG reseeding (CSRNG, EDN, etc.). Therefore, we skip any reseeding requests if + // the SecSkipPRNGReseeding parameter is set. Performing the reseeding without proper entropy + // provided from CSRNG would result in quickly repeating, fully deterministic PRNG output, + // which prevents meaningful SCA resistance evaluations. + + // Create a lint error to reduce the risk of accidentally enabling this feature. + `CALIPTRA_ASSERT_STATIC_LINT_ERROR(AesSecAllowForcingMasksNonDefault, SecAllowForcingMasks == 0) + + if (SecAllowForcingMasks == 0) begin : gen_unused_force_masks + logic unused_force_masks; + assign unused_force_masks = force_masks_i; + end + + // Create a lint error to reduce the risk of accidentally enabling this feature. + `CALIPTRA_ASSERT_STATIC_LINT_ERROR(AesSecSkipPRNGReseedingNonDefault, SecSkipPRNGReseeding == 0) + + if (SecSkipPRNGReseeding == 1) begin : gen_unused_prng_seed_done + logic unused_prng_seed_done; + assign unused_prng_seed_done = prng_seed_done; + end + + // Reseed interface handling + assign prng_seed_en = SecSkipPRNGReseeding ? 1'b0 : reseed_req_i; + assign reseed_ack_o = SecSkipPRNGReseeding ? reseed_req_i : prng_seed_done; + + //////////////////////////////////// + // Bivium Stream Cipher Primitive // + //////////////////////////////////// + caliptra_prim_trivium #( + .BiviumVariant (1), + .OutputWidth (Width), + .StrictLockupProtection(!SecAllowForcingMasks), + .SeedType (caliptra_prim_trivium_pkg::SeedTypeStatePartial), + .PartialSeedWidth (EntropyWidth), + .RndCnstTriviumLfsrSeed(RndCnstLfsrSeed) + ) u_caliptra_prim_bivium ( + .clk_i (clk_i), + .rst_ni(rst_ni), + + .en_i (data_update_i), + .allow_lockup_i (SecAllowForcingMasks & force_masks_i), + .seed_en_i (prng_seed_en), + .seed_done_o (prng_seed_done), + .seed_req_o (entropy_req_o), + .seed_ack_i (entropy_ack_i), + .seed_key_i ('0), // Not used. + .seed_iv_i ('0), // Not used. + .seed_state_full_i ('0), // Not used. + .seed_state_partial_i(entropy_i), + + .key_o(prng_key), + .err_o(prng_err) + ); + + // Add a permutation layer to obfuscate the output of stream cipher primitive. + for (genvar b = 0; b < Width; b++) begin : gen_perm + assign data_o[b] = prng_key[RndCnstLfsrPerm[b]]; + end + + // At the moment, the PRNG error output is ignored. This signal is asserted only if the stream + // cipher primitive enters an all-zero state. Depending on the value of the SecAllowForcingMasks + // parameter, the primitive behaves differently: + // - If SecAllowForcingMasks == 0 or if SecAllowForcingMasks == 1 and force_masks_i == 0, the + // primitive is automatically reset to the default value defined by a secret netlist constant. + // - If SecAllowForcingMasks == 1 and force_masks_i == 1, the primitive keeps the all-zero value. + // This may be required to switch off the masking for evaluating the SCA resistance. + logic unused_prng_err; + assign unused_prng_err = prng_err; + + ///////////////// + // Asssertions // + ///////////////// + +// the code below is not meant to be synthesized, +// but it is intended to be used in simulation and FPV +`ifndef SYNTHESIS + // Check that the supplied permutation is valid. + logic [Width-1:0] perm_test; + initial begin : p_perm_check + perm_test = '0; + for (int k = 0; k < Width; k++) begin + perm_test[RndCnstLfsrPerm[k]] = 1'b1; + end + // All bit positions must be marked with 1. + `CALIPTRA_ASSERT_I(PermutationCheck_A, &perm_test) + end +`endif + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/aes_reduced_round.sv b/designs/Caliptra/src/caliptra-rtl/aes_reduced_round.sv new file mode 100644 index 0000000..c56cdf4 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/aes_reduced_round.sv @@ -0,0 +1,80 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// AES reduced round data path +// This module is useful for formal masking verification using e.g. Alma. +// For details, see hw/ip/aes/pre_sca/alma/README.md . + +module aes_reduced_round import aes_pkg::*; +#( + parameter sbox_impl_e SecSBoxImpl = SBoxImplDom +) ( + input logic clk_i, + input logic rst_ni, + input sp2v_e en_i, + output sp2v_e out_req_o, + input sp2v_e out_ack_i, + input ciph_op_e op_i, + input logic [3:0][3:0][7:0] data_i, + input logic [3:0][3:0][7:0] mask_i, + input logic [3:0][3:0][WidthPRDSBox-1:0] prd_i, + output logic [3:0][3:0][7:0] data_o, + output logic [3:0][3:0][7:0] mask_o, + output logic err_o +); + + localparam int NumShares = 2; + + // Signals + logic [3:0][3:0][7:0] sub_bytes_out; + logic [3:0][3:0][7:0] sb_out_mask; + logic [3:0][3:0][7:0] shift_rows_in [NumShares]; + logic [3:0][3:0][7:0] shift_rows_out [NumShares]; + logic [3:0][3:0][7:0] mix_columns_out [NumShares]; + + // A single reduced (no AddKey) round of the cipher data path + aes_sub_bytes #( + .SecSBoxImpl ( SecSBoxImpl ) + ) u_aes_sub_bytes ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .en_i ( en_i ), + .out_req_o ( out_req_o ), + .out_ack_i ( out_ack_i ), + .op_i ( op_i ), + .data_i ( data_i ), + .mask_i ( mask_i ), + .prd_i ( prd_i ), + .data_o ( sub_bytes_out ), + .mask_o ( sb_out_mask ), + .err_o ( err_o ) + ); + + for (genvar s = 0; s < NumShares; s++) begin : gen_shares_shift_mix + if (s == 0) begin : gen_shift_in_data + // The (masked) data share + assign shift_rows_in[s] = sub_bytes_out; + end else begin : gen_shift_in_mask + // The mask share + assign shift_rows_in[s] = sb_out_mask; + end + + aes_shift_rows u_aes_shift_rows ( + .op_i ( op_i ), + .data_i ( shift_rows_in[s] ), + .data_o ( shift_rows_out[s] ) + ); + + aes_mix_columns u_aes_mix_columns ( + .op_i ( op_i ), + .data_i ( shift_rows_out[s] ), + .data_o ( mix_columns_out[s] ) + ); + end + + // Outputs + assign data_o = mix_columns_out[0]; + assign mask_o = mix_columns_out[1]; + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/aes_reg_pkg.sv b/designs/Caliptra/src/caliptra-rtl/aes_reg_pkg.sv new file mode 100644 index 0000000..eb30c11 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/aes_reg_pkg.sv @@ -0,0 +1,444 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Register Package auto-generated by `reggen` containing data structure + +package aes_reg_pkg; + + // Param list + parameter int NumRegsKey = 8; + parameter int NumRegsIv = 4; + parameter int NumRegsData = 4; + parameter int NumAlerts = 2; + + // Address widths within the block + parameter int BlockAw = 8; + + //////////////////////////// + // Typedefs for registers // + //////////////////////////// + + typedef struct packed { + struct packed { + logic q; + logic qe; + } fatal_fault; + struct packed { + logic q; + logic qe; + } recov_ctrl_update_err; + } aes_reg2hw_alert_test_reg_t; + + typedef struct packed { + logic [31:0] q; + logic qe; + } aes_reg2hw_key_share0_mreg_t; + + typedef struct packed { + logic [31:0] q; + logic qe; + } aes_reg2hw_key_share1_mreg_t; + + typedef struct packed { + logic [31:0] q; + logic qe; + } aes_reg2hw_iv_mreg_t; + + typedef struct packed { + logic [31:0] q; + logic qe; + } aes_reg2hw_data_in_mreg_t; + + typedef struct packed { + logic [31:0] q; + logic re; + } aes_reg2hw_data_out_mreg_t; + + typedef struct packed { + struct packed { + logic q; + logic qe; + logic re; + } manual_operation; + struct packed { + logic [2:0] q; + logic qe; + logic re; + } prng_reseed_rate; + struct packed { + logic q; + logic qe; + logic re; + } sideload; + struct packed { + logic [2:0] q; + logic qe; + logic re; + } key_len; + struct packed { + logic [5:0] q; + logic qe; + logic re; + } mode; + struct packed { + logic [1:0] q; + logic qe; + logic re; + } operation; + } aes_reg2hw_ctrl_shadowed_reg_t; + + typedef struct packed { + struct packed { + logic q; + } force_masks; + struct packed { + logic q; + } key_touch_forces_reseed; + } aes_reg2hw_ctrl_aux_shadowed_reg_t; + + typedef struct packed { + struct packed { + logic q; + } prng_reseed; + struct packed { + logic q; + } data_out_clear; + struct packed { + logic q; + } key_iv_data_in_clear; + struct packed { + logic q; + } start; + } aes_reg2hw_trigger_reg_t; + + typedef struct packed { + struct packed { + logic q; + } output_lost; + struct packed { + logic q; + } idle; + } aes_reg2hw_status_reg_t; + + typedef struct packed { + struct packed { + logic [4:0] q; + logic qe; + logic re; + } num_valid_bytes; + struct packed { + logic [5:0] q; + logic qe; + logic re; + } phase; + } aes_reg2hw_ctrl_gcm_shadowed_reg_t; + + typedef struct packed { + logic [31:0] d; + } aes_hw2reg_key_share0_mreg_t; + + typedef struct packed { + logic [31:0] d; + } aes_hw2reg_key_share1_mreg_t; + + typedef struct packed { + logic [31:0] d; + } aes_hw2reg_iv_mreg_t; + + typedef struct packed { + logic [31:0] d; + logic de; + } aes_hw2reg_data_in_mreg_t; + + typedef struct packed { + logic [31:0] d; + } aes_hw2reg_data_out_mreg_t; + + typedef struct packed { + struct packed { + logic [1:0] d; + } operation; + struct packed { + logic [5:0] d; + } mode; + struct packed { + logic [2:0] d; + } key_len; + struct packed { + logic d; + } sideload; + struct packed { + logic [2:0] d; + } prng_reseed_rate; + struct packed { + logic d; + } manual_operation; + } aes_hw2reg_ctrl_shadowed_reg_t; + + typedef struct packed { + struct packed { + logic d; + logic de; + } start; + struct packed { + logic d; + logic de; + } key_iv_data_in_clear; + struct packed { + logic d; + logic de; + } data_out_clear; + struct packed { + logic d; + logic de; + } prng_reseed; + } aes_hw2reg_trigger_reg_t; + + typedef struct packed { + struct packed { + logic d; + logic de; + } idle; + struct packed { + logic d; + logic de; + } stall; + struct packed { + logic d; + logic de; + } output_lost; + struct packed { + logic d; + logic de; + } output_valid; + struct packed { + logic d; + logic de; + } input_ready; + struct packed { + logic d; + logic de; + } alert_recov_ctrl_update_err; + struct packed { + logic d; + logic de; + } alert_fatal_fault; + } aes_hw2reg_status_reg_t; + + typedef struct packed { + struct packed { + logic [5:0] d; + } phase; + struct packed { + logic [4:0] d; + } num_valid_bytes; + } aes_hw2reg_ctrl_gcm_shadowed_reg_t; + + // Register -> HW type + typedef struct packed { + aes_reg2hw_alert_test_reg_t alert_test; // [970:967] + aes_reg2hw_key_share0_mreg_t [7:0] key_share0; // [966:703] + aes_reg2hw_key_share1_mreg_t [7:0] key_share1; // [702:439] + aes_reg2hw_iv_mreg_t [3:0] iv; // [438:307] + aes_reg2hw_data_in_mreg_t [3:0] data_in; // [306:175] + aes_reg2hw_data_out_mreg_t [3:0] data_out; // [174:43] + aes_reg2hw_ctrl_shadowed_reg_t ctrl_shadowed; // [42:21] + aes_reg2hw_ctrl_aux_shadowed_reg_t ctrl_aux_shadowed; // [20:19] + aes_reg2hw_trigger_reg_t trigger; // [18:15] + aes_reg2hw_status_reg_t status; // [14:13] + aes_reg2hw_ctrl_gcm_shadowed_reg_t ctrl_gcm_shadowed; // [12:0] + } aes_reg2hw_t; + + // HW -> register type + typedef struct packed { + aes_hw2reg_key_share0_mreg_t [7:0] key_share0; // [948:693] + aes_hw2reg_key_share1_mreg_t [7:0] key_share1; // [692:437] + aes_hw2reg_iv_mreg_t [3:0] iv; // [436:309] + aes_hw2reg_data_in_mreg_t [3:0] data_in; // [308:177] + aes_hw2reg_data_out_mreg_t [3:0] data_out; // [176:49] + aes_hw2reg_ctrl_shadowed_reg_t ctrl_shadowed; // [48:33] + aes_hw2reg_trigger_reg_t trigger; // [32:25] + aes_hw2reg_status_reg_t status; // [24:11] + aes_hw2reg_ctrl_gcm_shadowed_reg_t ctrl_gcm_shadowed; // [10:0] + } aes_hw2reg_t; + + // Register offsets + parameter logic [BlockAw-1:0] AES_ALERT_TEST_OFFSET = 8'h 0; + parameter logic [BlockAw-1:0] AES_KEY_SHARE0_0_OFFSET = 8'h 4; + parameter logic [BlockAw-1:0] AES_KEY_SHARE0_1_OFFSET = 8'h 8; + parameter logic [BlockAw-1:0] AES_KEY_SHARE0_2_OFFSET = 8'h c; + parameter logic [BlockAw-1:0] AES_KEY_SHARE0_3_OFFSET = 8'h 10; + parameter logic [BlockAw-1:0] AES_KEY_SHARE0_4_OFFSET = 8'h 14; + parameter logic [BlockAw-1:0] AES_KEY_SHARE0_5_OFFSET = 8'h 18; + parameter logic [BlockAw-1:0] AES_KEY_SHARE0_6_OFFSET = 8'h 1c; + parameter logic [BlockAw-1:0] AES_KEY_SHARE0_7_OFFSET = 8'h 20; + parameter logic [BlockAw-1:0] AES_KEY_SHARE1_0_OFFSET = 8'h 24; + parameter logic [BlockAw-1:0] AES_KEY_SHARE1_1_OFFSET = 8'h 28; + parameter logic [BlockAw-1:0] AES_KEY_SHARE1_2_OFFSET = 8'h 2c; + parameter logic [BlockAw-1:0] AES_KEY_SHARE1_3_OFFSET = 8'h 30; + parameter logic [BlockAw-1:0] AES_KEY_SHARE1_4_OFFSET = 8'h 34; + parameter logic [BlockAw-1:0] AES_KEY_SHARE1_5_OFFSET = 8'h 38; + parameter logic [BlockAw-1:0] AES_KEY_SHARE1_6_OFFSET = 8'h 3c; + parameter logic [BlockAw-1:0] AES_KEY_SHARE1_7_OFFSET = 8'h 40; + parameter logic [BlockAw-1:0] AES_IV_0_OFFSET = 8'h 44; + parameter logic [BlockAw-1:0] AES_IV_1_OFFSET = 8'h 48; + parameter logic [BlockAw-1:0] AES_IV_2_OFFSET = 8'h 4c; + parameter logic [BlockAw-1:0] AES_IV_3_OFFSET = 8'h 50; + parameter logic [BlockAw-1:0] AES_DATA_IN_0_OFFSET = 8'h 54; + parameter logic [BlockAw-1:0] AES_DATA_IN_1_OFFSET = 8'h 58; + parameter logic [BlockAw-1:0] AES_DATA_IN_2_OFFSET = 8'h 5c; + parameter logic [BlockAw-1:0] AES_DATA_IN_3_OFFSET = 8'h 60; + parameter logic [BlockAw-1:0] AES_DATA_OUT_0_OFFSET = 8'h 64; + parameter logic [BlockAw-1:0] AES_DATA_OUT_1_OFFSET = 8'h 68; + parameter logic [BlockAw-1:0] AES_DATA_OUT_2_OFFSET = 8'h 6c; + parameter logic [BlockAw-1:0] AES_DATA_OUT_3_OFFSET = 8'h 70; + parameter logic [BlockAw-1:0] AES_CTRL_SHADOWED_OFFSET = 8'h 74; + parameter logic [BlockAw-1:0] AES_CTRL_AUX_SHADOWED_OFFSET = 8'h 78; + parameter logic [BlockAw-1:0] AES_CTRL_AUX_REGWEN_OFFSET = 8'h 7c; + parameter logic [BlockAw-1:0] AES_TRIGGER_OFFSET = 8'h 80; + parameter logic [BlockAw-1:0] AES_STATUS_OFFSET = 8'h 84; + parameter logic [BlockAw-1:0] AES_CTRL_GCM_SHADOWED_OFFSET = 8'h 88; + + // Reset values for hwext registers and their fields + parameter logic [1:0] AES_ALERT_TEST_RESVAL = 2'h 0; + parameter logic [0:0] AES_ALERT_TEST_RECOV_CTRL_UPDATE_ERR_RESVAL = 1'h 0; + parameter logic [0:0] AES_ALERT_TEST_FATAL_FAULT_RESVAL = 1'h 0; + parameter logic [31:0] AES_KEY_SHARE0_0_RESVAL = 32'h 0; + parameter logic [31:0] AES_KEY_SHARE0_0_KEY_SHARE0_0_RESVAL = 32'h 0; + parameter logic [31:0] AES_KEY_SHARE0_1_RESVAL = 32'h 0; + parameter logic [31:0] AES_KEY_SHARE0_1_KEY_SHARE0_1_RESVAL = 32'h 0; + parameter logic [31:0] AES_KEY_SHARE0_2_RESVAL = 32'h 0; + parameter logic [31:0] AES_KEY_SHARE0_2_KEY_SHARE0_2_RESVAL = 32'h 0; + parameter logic [31:0] AES_KEY_SHARE0_3_RESVAL = 32'h 0; + parameter logic [31:0] AES_KEY_SHARE0_3_KEY_SHARE0_3_RESVAL = 32'h 0; + parameter logic [31:0] AES_KEY_SHARE0_4_RESVAL = 32'h 0; + parameter logic [31:0] AES_KEY_SHARE0_4_KEY_SHARE0_4_RESVAL = 32'h 0; + parameter logic [31:0] AES_KEY_SHARE0_5_RESVAL = 32'h 0; + parameter logic [31:0] AES_KEY_SHARE0_5_KEY_SHARE0_5_RESVAL = 32'h 0; + parameter logic [31:0] AES_KEY_SHARE0_6_RESVAL = 32'h 0; + parameter logic [31:0] AES_KEY_SHARE0_6_KEY_SHARE0_6_RESVAL = 32'h 0; + parameter logic [31:0] AES_KEY_SHARE0_7_RESVAL = 32'h 0; + parameter logic [31:0] AES_KEY_SHARE0_7_KEY_SHARE0_7_RESVAL = 32'h 0; + parameter logic [31:0] AES_KEY_SHARE1_0_RESVAL = 32'h 0; + parameter logic [31:0] AES_KEY_SHARE1_0_KEY_SHARE1_0_RESVAL = 32'h 0; + parameter logic [31:0] AES_KEY_SHARE1_1_RESVAL = 32'h 0; + parameter logic [31:0] AES_KEY_SHARE1_1_KEY_SHARE1_1_RESVAL = 32'h 0; + parameter logic [31:0] AES_KEY_SHARE1_2_RESVAL = 32'h 0; + parameter logic [31:0] AES_KEY_SHARE1_2_KEY_SHARE1_2_RESVAL = 32'h 0; + parameter logic [31:0] AES_KEY_SHARE1_3_RESVAL = 32'h 0; + parameter logic [31:0] AES_KEY_SHARE1_3_KEY_SHARE1_3_RESVAL = 32'h 0; + parameter logic [31:0] AES_KEY_SHARE1_4_RESVAL = 32'h 0; + parameter logic [31:0] AES_KEY_SHARE1_4_KEY_SHARE1_4_RESVAL = 32'h 0; + parameter logic [31:0] AES_KEY_SHARE1_5_RESVAL = 32'h 0; + parameter logic [31:0] AES_KEY_SHARE1_5_KEY_SHARE1_5_RESVAL = 32'h 0; + parameter logic [31:0] AES_KEY_SHARE1_6_RESVAL = 32'h 0; + parameter logic [31:0] AES_KEY_SHARE1_6_KEY_SHARE1_6_RESVAL = 32'h 0; + parameter logic [31:0] AES_KEY_SHARE1_7_RESVAL = 32'h 0; + parameter logic [31:0] AES_KEY_SHARE1_7_KEY_SHARE1_7_RESVAL = 32'h 0; + parameter logic [31:0] AES_IV_0_RESVAL = 32'h 0; + parameter logic [31:0] AES_IV_0_IV_0_RESVAL = 32'h 0; + parameter logic [31:0] AES_IV_1_RESVAL = 32'h 0; + parameter logic [31:0] AES_IV_1_IV_1_RESVAL = 32'h 0; + parameter logic [31:0] AES_IV_2_RESVAL = 32'h 0; + parameter logic [31:0] AES_IV_2_IV_2_RESVAL = 32'h 0; + parameter logic [31:0] AES_IV_3_RESVAL = 32'h 0; + parameter logic [31:0] AES_IV_3_IV_3_RESVAL = 32'h 0; + parameter logic [31:0] AES_DATA_OUT_0_RESVAL = 32'h 0; + parameter logic [31:0] AES_DATA_OUT_0_DATA_OUT_0_RESVAL = 32'h 0; + parameter logic [31:0] AES_DATA_OUT_1_RESVAL = 32'h 0; + parameter logic [31:0] AES_DATA_OUT_1_DATA_OUT_1_RESVAL = 32'h 0; + parameter logic [31:0] AES_DATA_OUT_2_RESVAL = 32'h 0; + parameter logic [31:0] AES_DATA_OUT_2_DATA_OUT_2_RESVAL = 32'h 0; + parameter logic [31:0] AES_DATA_OUT_3_RESVAL = 32'h 0; + parameter logic [31:0] AES_DATA_OUT_3_DATA_OUT_3_RESVAL = 32'h 0; + parameter logic [15:0] AES_CTRL_SHADOWED_RESVAL = 16'h 11fd; + parameter logic [1:0] AES_CTRL_SHADOWED_OPERATION_RESVAL = 2'h 1; + parameter logic [5:0] AES_CTRL_SHADOWED_MODE_RESVAL = 6'h 3f; + parameter logic [2:0] AES_CTRL_SHADOWED_KEY_LEN_RESVAL = 3'h 1; + parameter logic [0:0] AES_CTRL_SHADOWED_SIDELOAD_RESVAL = 1'h 0; + parameter logic [2:0] AES_CTRL_SHADOWED_PRNG_RESEED_RATE_RESVAL = 3'h 1; + parameter logic [0:0] AES_CTRL_SHADOWED_MANUAL_OPERATION_RESVAL = 1'h 0; + parameter logic [10:0] AES_CTRL_GCM_SHADOWED_RESVAL = 11'h 401; + parameter logic [5:0] AES_CTRL_GCM_SHADOWED_PHASE_RESVAL = 6'h 1; + parameter logic [4:0] AES_CTRL_GCM_SHADOWED_NUM_VALID_BYTES_RESVAL = 5'h 10; + + // Register index + typedef enum logic [31:0] { + AES_ALERT_TEST, + AES_KEY_SHARE0_0, + AES_KEY_SHARE0_1, + AES_KEY_SHARE0_2, + AES_KEY_SHARE0_3, + AES_KEY_SHARE0_4, + AES_KEY_SHARE0_5, + AES_KEY_SHARE0_6, + AES_KEY_SHARE0_7, + AES_KEY_SHARE1_0, + AES_KEY_SHARE1_1, + AES_KEY_SHARE1_2, + AES_KEY_SHARE1_3, + AES_KEY_SHARE1_4, + AES_KEY_SHARE1_5, + AES_KEY_SHARE1_6, + AES_KEY_SHARE1_7, + AES_IV_0, + AES_IV_1, + AES_IV_2, + AES_IV_3, + AES_DATA_IN_0, + AES_DATA_IN_1, + AES_DATA_IN_2, + AES_DATA_IN_3, + AES_DATA_OUT_0, + AES_DATA_OUT_1, + AES_DATA_OUT_2, + AES_DATA_OUT_3, + AES_CTRL_SHADOWED, + AES_CTRL_AUX_SHADOWED, + AES_CTRL_AUX_REGWEN, + AES_TRIGGER, + AES_STATUS, + AES_CTRL_GCM_SHADOWED + } aes_id_e; + + // Register width information to check illegal writes + parameter logic [3:0] AES_PERMIT [35] = '{ + 4'b 0001, // index[ 0] AES_ALERT_TEST + 4'b 1111, // index[ 1] AES_KEY_SHARE0_0 + 4'b 1111, // index[ 2] AES_KEY_SHARE0_1 + 4'b 1111, // index[ 3] AES_KEY_SHARE0_2 + 4'b 1111, // index[ 4] AES_KEY_SHARE0_3 + 4'b 1111, // index[ 5] AES_KEY_SHARE0_4 + 4'b 1111, // index[ 6] AES_KEY_SHARE0_5 + 4'b 1111, // index[ 7] AES_KEY_SHARE0_6 + 4'b 1111, // index[ 8] AES_KEY_SHARE0_7 + 4'b 1111, // index[ 9] AES_KEY_SHARE1_0 + 4'b 1111, // index[10] AES_KEY_SHARE1_1 + 4'b 1111, // index[11] AES_KEY_SHARE1_2 + 4'b 1111, // index[12] AES_KEY_SHARE1_3 + 4'b 1111, // index[13] AES_KEY_SHARE1_4 + 4'b 1111, // index[14] AES_KEY_SHARE1_5 + 4'b 1111, // index[15] AES_KEY_SHARE1_6 + 4'b 1111, // index[16] AES_KEY_SHARE1_7 + 4'b 1111, // index[17] AES_IV_0 + 4'b 1111, // index[18] AES_IV_1 + 4'b 1111, // index[19] AES_IV_2 + 4'b 1111, // index[20] AES_IV_3 + 4'b 1111, // index[21] AES_DATA_IN_0 + 4'b 1111, // index[22] AES_DATA_IN_1 + 4'b 1111, // index[23] AES_DATA_IN_2 + 4'b 1111, // index[24] AES_DATA_IN_3 + 4'b 1111, // index[25] AES_DATA_OUT_0 + 4'b 1111, // index[26] AES_DATA_OUT_1 + 4'b 1111, // index[27] AES_DATA_OUT_2 + 4'b 1111, // index[28] AES_DATA_OUT_3 + 4'b 0011, // index[29] AES_CTRL_SHADOWED + 4'b 0001, // index[30] AES_CTRL_AUX_SHADOWED + 4'b 0001, // index[31] AES_CTRL_AUX_REGWEN + 4'b 0001, // index[32] AES_TRIGGER + 4'b 0001, // index[33] AES_STATUS + 4'b 0011 // index[34] AES_CTRL_GCM_SHADOWED + }; + +endpackage diff --git a/designs/Caliptra/src/caliptra-rtl/aes_reg_status.sv b/designs/Caliptra/src/caliptra-rtl/aes_reg_status.sv new file mode 100644 index 0000000..f608e84 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/aes_reg_status.sv @@ -0,0 +1,79 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// AES reg status +// +// This module tracks the collective status of multiple registers. + +module aes_reg_status #( + parameter int Width = 1 +) ( + input logic clk_i, + input logic rst_ni, + + input logic [Width-1:0] we_i, + input logic use_i, + input logic clear_i, + input logic arm_i, + output logic new_o, + output logic new_pulse_o, + output logic clean_o +); + + logic [Width-1:0] we_d, we_q; + logic armed_d, armed_q; + logic all_written; + logic none_written; + logic new_d, new_q; + logic clean_d, clean_q; + + // Collect write operations. Upon clear or use, we start over. If armed, the next write will + // restart the tracking. + assign we_d = (clear_i || use_i) ? '0 : + (armed_q && |we_i) ? we_i : (we_q | we_i); + assign armed_d = (clear_i || use_i) ? 1'b0 : + (armed_q && |we_i) ? 1'b0 : armed_q | arm_i; + + always_ff @(posedge clk_i or negedge rst_ni) begin : reg_ops + if (!rst_ni) begin + we_q <= '0; + armed_q <= 1'b0; + end else begin + we_q <= we_d; + armed_q <= armed_d; + end + end + + // Status tracking + assign all_written = &we_d; + assign none_written = ~|we_d; + + // We have a complete new value if all registers have been written at least once. + assign new_d = (clear_i || use_i) ? 1'b0 : all_written; + + // We have a clean value, if either: + // - all registers have been written at least once, or + // - no registers have been written but the value was clean previsously. + // A value is NOT clean, if either: + // - we get a clear or reset, or + // - some but not all registers have been written. + assign clean_d = clear_i ? 1'b0 : + all_written ? 1'b1 : + none_written ? clean_q : 1'b0; + + always_ff @(posedge clk_i or negedge rst_ni) begin : reg_status + if (!rst_ni) begin + new_q <= 1'b0; + clean_q <= 1'b0; + end else begin + new_q <= new_d; + clean_q <= clean_d; + end + end + + assign new_o = new_q; + assign new_pulse_o = new_d & ~new_q; + assign clean_o = clean_q; + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/aes_reg_top.sv b/designs/Caliptra/src/caliptra-rtl/aes_reg_top.sv new file mode 100644 index 0000000..fd82aae --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/aes_reg_top.sv @@ -0,0 +1,1950 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Register Top module auto-generated by `reggen` + +`include "caliptra_prim_assert.sv" + +module aes_reg_top ( + input clk_i, + input rst_ni, + input rst_shadowed_ni, + input caliptra_tlul_pkg::tl_h2d_t tl_i, + output caliptra_tlul_pkg::tl_d2h_t tl_o, + // To HW + output aes_reg_pkg::aes_reg2hw_t reg2hw, // Write + input aes_reg_pkg::aes_hw2reg_t hw2reg, // Read + + output logic input_ready_o, + output logic output_valid_o, + + output logic shadowed_storage_err_o, + output logic shadowed_update_err_o, + + // Integrity check errors + output logic intg_err_o +); + + import aes_reg_pkg::* ; + + localparam int AW = 8; + localparam int DW = 32; + localparam int DBW = DW/8; // Byte Width + + // register signals + logic reg_we; + logic reg_re; + logic [AW-1:0] reg_addr; + logic [DW-1:0] reg_wdata; + logic [DBW-1:0] reg_be; + logic [DW-1:0] reg_rdata; + logic reg_error; + + logic addrmiss, wr_err; + + logic [DW-1:0] reg_rdata_next; + logic reg_busy; + + caliptra_tlul_pkg::tl_h2d_t tl_reg_h2d; + caliptra_tlul_pkg::tl_d2h_t tl_reg_d2h; + + + // incoming payload check + logic intg_err; + caliptra_tlul_cmd_intg_chk u_chk ( + .tl_i(tl_i), + .err_o(intg_err) + ); + + // also check for spurious write enables + logic reg_we_err; + logic [34:0] reg_we_check; + caliptra_prim_reg_we_check #( + .OneHotWidth(35) + ) u_caliptra_prim_reg_we_check ( + .clk_i(clk_i), + .rst_ni(rst_ni), + .oh_i (reg_we_check), + .en_i (reg_we && !addrmiss), + .err_o (reg_we_err) + ); + + logic err_q; + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + err_q <= '0; + end else if (intg_err || reg_we_err) begin + err_q <= 1'b1; + end + end + + // integrity error output is permanent and should be used for alert generation + // register errors are transactional + assign intg_err_o = err_q | intg_err | reg_we_err; + + // outgoing integrity generation + caliptra_tlul_pkg::tl_d2h_t tl_o_pre; + caliptra_tlul_rsp_intg_gen #( + .EnableRspIntgGen(1), + .EnableDataIntgGen(1) + ) u_rsp_intg_gen ( + .tl_i(tl_o_pre), + .tl_o(tl_o) + ); + + assign tl_reg_h2d = tl_i; + assign tl_o_pre = tl_reg_d2h; + + caliptra_tlul_adapter_reg #( + .RegAw(AW), + .RegDw(DW), + .EnableDataIntgGen(0) + ) u_reg_if ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + .tl_i (tl_reg_h2d), + .tl_o (tl_reg_d2h), + + .en_ifetch_i(caliptra_prim_mubi_pkg::MuBi4False), + .intg_error_o(), + + .we_o (reg_we), + .re_o (reg_re), + .addr_o (reg_addr), + .wdata_o (reg_wdata), + .be_o (reg_be), + .busy_i (reg_busy), + .rdata_i (reg_rdata), + .error_i (reg_error) + ); + + // cdc oversampling signals + + assign reg_rdata = reg_rdata_next ; + assign reg_error = addrmiss | wr_err | intg_err; + + // Define SW related signals + // Format: __{wd|we|qs} + // or _{wd|we|qs} if field == 1 or 0 + logic alert_test_we; + logic alert_test_recov_ctrl_update_err_wd; + logic alert_test_fatal_fault_wd; + logic key_share0_0_we; + logic [31:0] key_share0_0_wd; + logic key_share0_1_we; + logic [31:0] key_share0_1_wd; + logic key_share0_2_we; + logic [31:0] key_share0_2_wd; + logic key_share0_3_we; + logic [31:0] key_share0_3_wd; + logic key_share0_4_we; + logic [31:0] key_share0_4_wd; + logic key_share0_5_we; + logic [31:0] key_share0_5_wd; + logic key_share0_6_we; + logic [31:0] key_share0_6_wd; + logic key_share0_7_we; + logic [31:0] key_share0_7_wd; + logic key_share1_0_we; + logic [31:0] key_share1_0_wd; + logic key_share1_1_we; + logic [31:0] key_share1_1_wd; + logic key_share1_2_we; + logic [31:0] key_share1_2_wd; + logic key_share1_3_we; + logic [31:0] key_share1_3_wd; + logic key_share1_4_we; + logic [31:0] key_share1_4_wd; + logic key_share1_5_we; + logic [31:0] key_share1_5_wd; + logic key_share1_6_we; + logic [31:0] key_share1_6_wd; + logic key_share1_7_we; + logic [31:0] key_share1_7_wd; + logic iv_0_re; + logic iv_0_we; + logic [31:0] iv_0_qs; + logic [31:0] iv_0_wd; + logic iv_1_re; + logic iv_1_we; + logic [31:0] iv_1_qs; + logic [31:0] iv_1_wd; + logic iv_2_re; + logic iv_2_we; + logic [31:0] iv_2_qs; + logic [31:0] iv_2_wd; + logic iv_3_re; + logic iv_3_we; + logic [31:0] iv_3_qs; + logic [31:0] iv_3_wd; + logic data_in_0_we; + logic [31:0] data_in_0_wd; + logic data_in_1_we; + logic [31:0] data_in_1_wd; + logic data_in_2_we; + logic [31:0] data_in_2_wd; + logic data_in_3_we; + logic [31:0] data_in_3_wd; + logic data_out_0_re; + logic [31:0] data_out_0_qs; + logic data_out_1_re; + logic [31:0] data_out_1_qs; + logic data_out_2_re; + logic [31:0] data_out_2_qs; + logic data_out_3_re; + logic [31:0] data_out_3_qs; + logic ctrl_shadowed_re; + logic ctrl_shadowed_we; + logic [1:0] ctrl_shadowed_operation_qs; + logic [1:0] ctrl_shadowed_operation_wd; + logic [5:0] ctrl_shadowed_mode_qs; + logic [5:0] ctrl_shadowed_mode_wd; + logic [2:0] ctrl_shadowed_key_len_qs; + logic [2:0] ctrl_shadowed_key_len_wd; + logic ctrl_shadowed_sideload_qs; + logic ctrl_shadowed_sideload_wd; + logic [2:0] ctrl_shadowed_prng_reseed_rate_qs; + logic [2:0] ctrl_shadowed_prng_reseed_rate_wd; + logic ctrl_shadowed_manual_operation_qs; + logic ctrl_shadowed_manual_operation_wd; + logic ctrl_aux_shadowed_re; + logic ctrl_aux_shadowed_we; + logic ctrl_aux_shadowed_key_touch_forces_reseed_qs; + logic ctrl_aux_shadowed_key_touch_forces_reseed_wd; + logic ctrl_aux_shadowed_key_touch_forces_reseed_storage_err; + logic ctrl_aux_shadowed_key_touch_forces_reseed_update_err; + logic ctrl_aux_shadowed_force_masks_qs; + logic ctrl_aux_shadowed_force_masks_wd; + logic ctrl_aux_shadowed_force_masks_storage_err; + logic ctrl_aux_shadowed_force_masks_update_err; + logic ctrl_aux_regwen_we; + logic ctrl_aux_regwen_qs; + logic ctrl_aux_regwen_wd; + logic trigger_we; + logic trigger_start_wd; + logic trigger_key_iv_data_in_clear_wd; + logic trigger_data_out_clear_wd; + logic trigger_prng_reseed_wd; + logic status_idle_qs; + logic status_stall_qs; + logic status_output_lost_qs; + logic status_output_valid_qs; + logic status_input_ready_qs; + logic status_alert_recov_ctrl_update_err_qs; + logic status_alert_fatal_fault_qs; + logic ctrl_gcm_shadowed_re; + logic ctrl_gcm_shadowed_we; + logic [5:0] ctrl_gcm_shadowed_phase_qs; + logic [5:0] ctrl_gcm_shadowed_phase_wd; + logic [4:0] ctrl_gcm_shadowed_num_valid_bytes_qs; + logic [4:0] ctrl_gcm_shadowed_num_valid_bytes_wd; + + // Register instances + // R[alert_test]: V(True) + logic alert_test_qe; + logic [1:0] alert_test_flds_we; + assign alert_test_qe = &alert_test_flds_we; + // F[recov_ctrl_update_err]: 0:0 + caliptra_prim_subreg_ext #( + .DW (1) + ) u_alert_test_recov_ctrl_update_err ( + .re (1'b0), + .we (alert_test_we), + .wd (alert_test_recov_ctrl_update_err_wd), + .d ('0), + .qre (), + .qe (alert_test_flds_we[0]), + .q (reg2hw.alert_test.recov_ctrl_update_err.q), + .ds (), + .qs () + ); + assign reg2hw.alert_test.recov_ctrl_update_err.qe = alert_test_qe; + + // F[fatal_fault]: 1:1 + caliptra_prim_subreg_ext #( + .DW (1) + ) u_alert_test_fatal_fault ( + .re (1'b0), + .we (alert_test_we), + .wd (alert_test_fatal_fault_wd), + .d ('0), + .qre (), + .qe (alert_test_flds_we[1]), + .q (reg2hw.alert_test.fatal_fault.q), + .ds (), + .qs () + ); + assign reg2hw.alert_test.fatal_fault.qe = alert_test_qe; + + + // Subregister 0 of Multireg key_share0 + // R[key_share0_0]: V(True) + logic key_share0_0_qe; + logic [0:0] key_share0_0_flds_we; + assign key_share0_0_qe = &key_share0_0_flds_we; + caliptra_prim_subreg_ext #( + .DW (32) + ) u_key_share0_0 ( + .re (1'b0), + .we (key_share0_0_we), + .wd (key_share0_0_wd), + .d (hw2reg.key_share0[0].d), + .qre (), + .qe (key_share0_0_flds_we[0]), + .q (reg2hw.key_share0[0].q), + .ds (), + .qs () + ); + assign reg2hw.key_share0[0].qe = key_share0_0_qe; + + + // Subregister 1 of Multireg key_share0 + // R[key_share0_1]: V(True) + logic key_share0_1_qe; + logic [0:0] key_share0_1_flds_we; + assign key_share0_1_qe = &key_share0_1_flds_we; + caliptra_prim_subreg_ext #( + .DW (32) + ) u_key_share0_1 ( + .re (1'b0), + .we (key_share0_1_we), + .wd (key_share0_1_wd), + .d (hw2reg.key_share0[1].d), + .qre (), + .qe (key_share0_1_flds_we[0]), + .q (reg2hw.key_share0[1].q), + .ds (), + .qs () + ); + assign reg2hw.key_share0[1].qe = key_share0_1_qe; + + + // Subregister 2 of Multireg key_share0 + // R[key_share0_2]: V(True) + logic key_share0_2_qe; + logic [0:0] key_share0_2_flds_we; + assign key_share0_2_qe = &key_share0_2_flds_we; + caliptra_prim_subreg_ext #( + .DW (32) + ) u_key_share0_2 ( + .re (1'b0), + .we (key_share0_2_we), + .wd (key_share0_2_wd), + .d (hw2reg.key_share0[2].d), + .qre (), + .qe (key_share0_2_flds_we[0]), + .q (reg2hw.key_share0[2].q), + .ds (), + .qs () + ); + assign reg2hw.key_share0[2].qe = key_share0_2_qe; + + + // Subregister 3 of Multireg key_share0 + // R[key_share0_3]: V(True) + logic key_share0_3_qe; + logic [0:0] key_share0_3_flds_we; + assign key_share0_3_qe = &key_share0_3_flds_we; + caliptra_prim_subreg_ext #( + .DW (32) + ) u_key_share0_3 ( + .re (1'b0), + .we (key_share0_3_we), + .wd (key_share0_3_wd), + .d (hw2reg.key_share0[3].d), + .qre (), + .qe (key_share0_3_flds_we[0]), + .q (reg2hw.key_share0[3].q), + .ds (), + .qs () + ); + assign reg2hw.key_share0[3].qe = key_share0_3_qe; + + + // Subregister 4 of Multireg key_share0 + // R[key_share0_4]: V(True) + logic key_share0_4_qe; + logic [0:0] key_share0_4_flds_we; + assign key_share0_4_qe = &key_share0_4_flds_we; + caliptra_prim_subreg_ext #( + .DW (32) + ) u_key_share0_4 ( + .re (1'b0), + .we (key_share0_4_we), + .wd (key_share0_4_wd), + .d (hw2reg.key_share0[4].d), + .qre (), + .qe (key_share0_4_flds_we[0]), + .q (reg2hw.key_share0[4].q), + .ds (), + .qs () + ); + assign reg2hw.key_share0[4].qe = key_share0_4_qe; + + + // Subregister 5 of Multireg key_share0 + // R[key_share0_5]: V(True) + logic key_share0_5_qe; + logic [0:0] key_share0_5_flds_we; + assign key_share0_5_qe = &key_share0_5_flds_we; + caliptra_prim_subreg_ext #( + .DW (32) + ) u_key_share0_5 ( + .re (1'b0), + .we (key_share0_5_we), + .wd (key_share0_5_wd), + .d (hw2reg.key_share0[5].d), + .qre (), + .qe (key_share0_5_flds_we[0]), + .q (reg2hw.key_share0[5].q), + .ds (), + .qs () + ); + assign reg2hw.key_share0[5].qe = key_share0_5_qe; + + + // Subregister 6 of Multireg key_share0 + // R[key_share0_6]: V(True) + logic key_share0_6_qe; + logic [0:0] key_share0_6_flds_we; + assign key_share0_6_qe = &key_share0_6_flds_we; + caliptra_prim_subreg_ext #( + .DW (32) + ) u_key_share0_6 ( + .re (1'b0), + .we (key_share0_6_we), + .wd (key_share0_6_wd), + .d (hw2reg.key_share0[6].d), + .qre (), + .qe (key_share0_6_flds_we[0]), + .q (reg2hw.key_share0[6].q), + .ds (), + .qs () + ); + assign reg2hw.key_share0[6].qe = key_share0_6_qe; + + + // Subregister 7 of Multireg key_share0 + // R[key_share0_7]: V(True) + logic key_share0_7_qe; + logic [0:0] key_share0_7_flds_we; + assign key_share0_7_qe = &key_share0_7_flds_we; + caliptra_prim_subreg_ext #( + .DW (32) + ) u_key_share0_7 ( + .re (1'b0), + .we (key_share0_7_we), + .wd (key_share0_7_wd), + .d (hw2reg.key_share0[7].d), + .qre (), + .qe (key_share0_7_flds_we[0]), + .q (reg2hw.key_share0[7].q), + .ds (), + .qs () + ); + assign reg2hw.key_share0[7].qe = key_share0_7_qe; + + + // Subregister 0 of Multireg key_share1 + // R[key_share1_0]: V(True) + logic key_share1_0_qe; + logic [0:0] key_share1_0_flds_we; + assign key_share1_0_qe = &key_share1_0_flds_we; + caliptra_prim_subreg_ext #( + .DW (32) + ) u_key_share1_0 ( + .re (1'b0), + .we (key_share1_0_we), + .wd (key_share1_0_wd), + .d (hw2reg.key_share1[0].d), + .qre (), + .qe (key_share1_0_flds_we[0]), + .q (reg2hw.key_share1[0].q), + .ds (), + .qs () + ); + assign reg2hw.key_share1[0].qe = key_share1_0_qe; + + + // Subregister 1 of Multireg key_share1 + // R[key_share1_1]: V(True) + logic key_share1_1_qe; + logic [0:0] key_share1_1_flds_we; + assign key_share1_1_qe = &key_share1_1_flds_we; + caliptra_prim_subreg_ext #( + .DW (32) + ) u_key_share1_1 ( + .re (1'b0), + .we (key_share1_1_we), + .wd (key_share1_1_wd), + .d (hw2reg.key_share1[1].d), + .qre (), + .qe (key_share1_1_flds_we[0]), + .q (reg2hw.key_share1[1].q), + .ds (), + .qs () + ); + assign reg2hw.key_share1[1].qe = key_share1_1_qe; + + + // Subregister 2 of Multireg key_share1 + // R[key_share1_2]: V(True) + logic key_share1_2_qe; + logic [0:0] key_share1_2_flds_we; + assign key_share1_2_qe = &key_share1_2_flds_we; + caliptra_prim_subreg_ext #( + .DW (32) + ) u_key_share1_2 ( + .re (1'b0), + .we (key_share1_2_we), + .wd (key_share1_2_wd), + .d (hw2reg.key_share1[2].d), + .qre (), + .qe (key_share1_2_flds_we[0]), + .q (reg2hw.key_share1[2].q), + .ds (), + .qs () + ); + assign reg2hw.key_share1[2].qe = key_share1_2_qe; + + + // Subregister 3 of Multireg key_share1 + // R[key_share1_3]: V(True) + logic key_share1_3_qe; + logic [0:0] key_share1_3_flds_we; + assign key_share1_3_qe = &key_share1_3_flds_we; + caliptra_prim_subreg_ext #( + .DW (32) + ) u_key_share1_3 ( + .re (1'b0), + .we (key_share1_3_we), + .wd (key_share1_3_wd), + .d (hw2reg.key_share1[3].d), + .qre (), + .qe (key_share1_3_flds_we[0]), + .q (reg2hw.key_share1[3].q), + .ds (), + .qs () + ); + assign reg2hw.key_share1[3].qe = key_share1_3_qe; + + + // Subregister 4 of Multireg key_share1 + // R[key_share1_4]: V(True) + logic key_share1_4_qe; + logic [0:0] key_share1_4_flds_we; + assign key_share1_4_qe = &key_share1_4_flds_we; + caliptra_prim_subreg_ext #( + .DW (32) + ) u_key_share1_4 ( + .re (1'b0), + .we (key_share1_4_we), + .wd (key_share1_4_wd), + .d (hw2reg.key_share1[4].d), + .qre (), + .qe (key_share1_4_flds_we[0]), + .q (reg2hw.key_share1[4].q), + .ds (), + .qs () + ); + assign reg2hw.key_share1[4].qe = key_share1_4_qe; + + + // Subregister 5 of Multireg key_share1 + // R[key_share1_5]: V(True) + logic key_share1_5_qe; + logic [0:0] key_share1_5_flds_we; + assign key_share1_5_qe = &key_share1_5_flds_we; + caliptra_prim_subreg_ext #( + .DW (32) + ) u_key_share1_5 ( + .re (1'b0), + .we (key_share1_5_we), + .wd (key_share1_5_wd), + .d (hw2reg.key_share1[5].d), + .qre (), + .qe (key_share1_5_flds_we[0]), + .q (reg2hw.key_share1[5].q), + .ds (), + .qs () + ); + assign reg2hw.key_share1[5].qe = key_share1_5_qe; + + + // Subregister 6 of Multireg key_share1 + // R[key_share1_6]: V(True) + logic key_share1_6_qe; + logic [0:0] key_share1_6_flds_we; + assign key_share1_6_qe = &key_share1_6_flds_we; + caliptra_prim_subreg_ext #( + .DW (32) + ) u_key_share1_6 ( + .re (1'b0), + .we (key_share1_6_we), + .wd (key_share1_6_wd), + .d (hw2reg.key_share1[6].d), + .qre (), + .qe (key_share1_6_flds_we[0]), + .q (reg2hw.key_share1[6].q), + .ds (), + .qs () + ); + assign reg2hw.key_share1[6].qe = key_share1_6_qe; + + + // Subregister 7 of Multireg key_share1 + // R[key_share1_7]: V(True) + logic key_share1_7_qe; + logic [0:0] key_share1_7_flds_we; + assign key_share1_7_qe = &key_share1_7_flds_we; + caliptra_prim_subreg_ext #( + .DW (32) + ) u_key_share1_7 ( + .re (1'b0), + .we (key_share1_7_we), + .wd (key_share1_7_wd), + .d (hw2reg.key_share1[7].d), + .qre (), + .qe (key_share1_7_flds_we[0]), + .q (reg2hw.key_share1[7].q), + .ds (), + .qs () + ); + assign reg2hw.key_share1[7].qe = key_share1_7_qe; + + + // Subregister 0 of Multireg iv + // R[iv_0]: V(True) + logic iv_0_qe; + logic [0:0] iv_0_flds_we; + assign iv_0_qe = &iv_0_flds_we; + caliptra_prim_subreg_ext #( + .DW (32) + ) u_iv_0 ( + .re (iv_0_re), + .we (iv_0_we), + .wd (iv_0_wd), + .d (hw2reg.iv[0].d), + .qre (), + .qe (iv_0_flds_we[0]), + .q (reg2hw.iv[0].q), + .ds (), + .qs (iv_0_qs) + ); + assign reg2hw.iv[0].qe = iv_0_qe; + + + // Subregister 1 of Multireg iv + // R[iv_1]: V(True) + logic iv_1_qe; + logic [0:0] iv_1_flds_we; + assign iv_1_qe = &iv_1_flds_we; + caliptra_prim_subreg_ext #( + .DW (32) + ) u_iv_1 ( + .re (iv_1_re), + .we (iv_1_we), + .wd (iv_1_wd), + .d (hw2reg.iv[1].d), + .qre (), + .qe (iv_1_flds_we[0]), + .q (reg2hw.iv[1].q), + .ds (), + .qs (iv_1_qs) + ); + assign reg2hw.iv[1].qe = iv_1_qe; + + + // Subregister 2 of Multireg iv + // R[iv_2]: V(True) + logic iv_2_qe; + logic [0:0] iv_2_flds_we; + assign iv_2_qe = &iv_2_flds_we; + caliptra_prim_subreg_ext #( + .DW (32) + ) u_iv_2 ( + .re (iv_2_re), + .we (iv_2_we), + .wd (iv_2_wd), + .d (hw2reg.iv[2].d), + .qre (), + .qe (iv_2_flds_we[0]), + .q (reg2hw.iv[2].q), + .ds (), + .qs (iv_2_qs) + ); + assign reg2hw.iv[2].qe = iv_2_qe; + + + // Subregister 3 of Multireg iv + // R[iv_3]: V(True) + logic iv_3_qe; + logic [0:0] iv_3_flds_we; + assign iv_3_qe = &iv_3_flds_we; + caliptra_prim_subreg_ext #( + .DW (32) + ) u_iv_3 ( + .re (iv_3_re), + .we (iv_3_we), + .wd (iv_3_wd), + .d (hw2reg.iv[3].d), + .qre (), + .qe (iv_3_flds_we[0]), + .q (reg2hw.iv[3].q), + .ds (), + .qs (iv_3_qs) + ); + assign reg2hw.iv[3].qe = iv_3_qe; + + + // Subregister 0 of Multireg data_in + // R[data_in_0]: V(False) + logic data_in_0_qe; + logic [0:0] data_in_0_flds_we; + caliptra_prim_flop #( + .Width(1), + .ResetValue(0) + ) u_data_in0_qe ( + .clk_i(clk_i), + .rst_ni(rst_ni), + .d_i(&data_in_0_flds_we), + .q_o(data_in_0_qe) + ); + caliptra_prim_subreg #( + .DW (32), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessWO), + .RESVAL (32'h0), + .Mubi (1'b0) + ) u_data_in_0 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (data_in_0_we), + .wd (data_in_0_wd), + + // from internal hardware + .de (hw2reg.data_in[0].de), + .d (hw2reg.data_in[0].d), + + // to internal hardware + .qe (data_in_0_flds_we[0]), + .q (reg2hw.data_in[0].q), + .ds (), + + // to register interface (read) + .qs () + ); + assign reg2hw.data_in[0].qe = data_in_0_qe; + + + // Subregister 1 of Multireg data_in + // R[data_in_1]: V(False) + logic data_in_1_qe; + logic [0:0] data_in_1_flds_we; + caliptra_prim_flop #( + .Width(1), + .ResetValue(0) + ) u_data_in1_qe ( + .clk_i(clk_i), + .rst_ni(rst_ni), + .d_i(&data_in_1_flds_we), + .q_o(data_in_1_qe) + ); + caliptra_prim_subreg #( + .DW (32), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessWO), + .RESVAL (32'h0), + .Mubi (1'b0) + ) u_data_in_1 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (data_in_1_we), + .wd (data_in_1_wd), + + // from internal hardware + .de (hw2reg.data_in[1].de), + .d (hw2reg.data_in[1].d), + + // to internal hardware + .qe (data_in_1_flds_we[0]), + .q (reg2hw.data_in[1].q), + .ds (), + + // to register interface (read) + .qs () + ); + assign reg2hw.data_in[1].qe = data_in_1_qe; + + + // Subregister 2 of Multireg data_in + // R[data_in_2]: V(False) + logic data_in_2_qe; + logic [0:0] data_in_2_flds_we; + caliptra_prim_flop #( + .Width(1), + .ResetValue(0) + ) u_data_in2_qe ( + .clk_i(clk_i), + .rst_ni(rst_ni), + .d_i(&data_in_2_flds_we), + .q_o(data_in_2_qe) + ); + caliptra_prim_subreg #( + .DW (32), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessWO), + .RESVAL (32'h0), + .Mubi (1'b0) + ) u_data_in_2 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (data_in_2_we), + .wd (data_in_2_wd), + + // from internal hardware + .de (hw2reg.data_in[2].de), + .d (hw2reg.data_in[2].d), + + // to internal hardware + .qe (data_in_2_flds_we[0]), + .q (reg2hw.data_in[2].q), + .ds (), + + // to register interface (read) + .qs () + ); + assign reg2hw.data_in[2].qe = data_in_2_qe; + + + // Subregister 3 of Multireg data_in + // R[data_in_3]: V(False) + logic data_in_3_qe; + logic [0:0] data_in_3_flds_we; + caliptra_prim_flop #( + .Width(1), + .ResetValue(0) + ) u_data_in3_qe ( + .clk_i(clk_i), + .rst_ni(rst_ni), + .d_i(&data_in_3_flds_we), + .q_o(data_in_3_qe) + ); + caliptra_prim_subreg #( + .DW (32), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessWO), + .RESVAL (32'h0), + .Mubi (1'b0) + ) u_data_in_3 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (data_in_3_we), + .wd (data_in_3_wd), + + // from internal hardware + .de (hw2reg.data_in[3].de), + .d (hw2reg.data_in[3].d), + + // to internal hardware + .qe (data_in_3_flds_we[0]), + .q (reg2hw.data_in[3].q), + .ds (), + + // to register interface (read) + .qs () + ); + assign reg2hw.data_in[3].qe = data_in_3_qe; + + + // Subregister 0 of Multireg data_out + // R[data_out_0]: V(True) + caliptra_prim_subreg_ext #( + .DW (32) + ) u_data_out_0 ( + .re (data_out_0_re), + .we (1'b0), + .wd ('0), + .d (hw2reg.data_out[0].d), + .qre (reg2hw.data_out[0].re), + .qe (), + .q (reg2hw.data_out[0].q), + .ds (), + .qs (data_out_0_qs) + ); + + + // Subregister 1 of Multireg data_out + // R[data_out_1]: V(True) + caliptra_prim_subreg_ext #( + .DW (32) + ) u_data_out_1 ( + .re (data_out_1_re), + .we (1'b0), + .wd ('0), + .d (hw2reg.data_out[1].d), + .qre (reg2hw.data_out[1].re), + .qe (), + .q (reg2hw.data_out[1].q), + .ds (), + .qs (data_out_1_qs) + ); + + + // Subregister 2 of Multireg data_out + // R[data_out_2]: V(True) + caliptra_prim_subreg_ext #( + .DW (32) + ) u_data_out_2 ( + .re (data_out_2_re), + .we (1'b0), + .wd ('0), + .d (hw2reg.data_out[2].d), + .qre (reg2hw.data_out[2].re), + .qe (), + .q (reg2hw.data_out[2].q), + .ds (), + .qs (data_out_2_qs) + ); + + + // Subregister 3 of Multireg data_out + // R[data_out_3]: V(True) + caliptra_prim_subreg_ext #( + .DW (32) + ) u_data_out_3 ( + .re (data_out_3_re), + .we (1'b0), + .wd ('0), + .d (hw2reg.data_out[3].d), + .qre (reg2hw.data_out[3].re), + .qe (), + .q (reg2hw.data_out[3].q), + .ds (), + .qs (data_out_3_qs) + ); + + + // R[ctrl_shadowed]: V(True) + logic ctrl_shadowed_qe; + logic [5:0] ctrl_shadowed_flds_we; + assign ctrl_shadowed_qe = &ctrl_shadowed_flds_we; + // F[operation]: 1:0 + caliptra_prim_subreg_ext #( + .DW (2) + ) u_ctrl_shadowed_operation ( + .re (ctrl_shadowed_re), + .we (ctrl_shadowed_we), + .wd (ctrl_shadowed_operation_wd), + .d (hw2reg.ctrl_shadowed.operation.d), + .qre (reg2hw.ctrl_shadowed.operation.re), + .qe (ctrl_shadowed_flds_we[0]), + .q (reg2hw.ctrl_shadowed.operation.q), + .ds (), + .qs (ctrl_shadowed_operation_qs) + ); + assign reg2hw.ctrl_shadowed.operation.qe = ctrl_shadowed_qe; + + // F[mode]: 7:2 + caliptra_prim_subreg_ext #( + .DW (6) + ) u_ctrl_shadowed_mode ( + .re (ctrl_shadowed_re), + .we (ctrl_shadowed_we), + .wd (ctrl_shadowed_mode_wd), + .d (hw2reg.ctrl_shadowed.mode.d), + .qre (reg2hw.ctrl_shadowed.mode.re), + .qe (ctrl_shadowed_flds_we[1]), + .q (reg2hw.ctrl_shadowed.mode.q), + .ds (), + .qs (ctrl_shadowed_mode_qs) + ); + assign reg2hw.ctrl_shadowed.mode.qe = ctrl_shadowed_qe; + + // F[key_len]: 10:8 + caliptra_prim_subreg_ext #( + .DW (3) + ) u_ctrl_shadowed_key_len ( + .re (ctrl_shadowed_re), + .we (ctrl_shadowed_we), + .wd (ctrl_shadowed_key_len_wd), + .d (hw2reg.ctrl_shadowed.key_len.d), + .qre (reg2hw.ctrl_shadowed.key_len.re), + .qe (ctrl_shadowed_flds_we[2]), + .q (reg2hw.ctrl_shadowed.key_len.q), + .ds (), + .qs (ctrl_shadowed_key_len_qs) + ); + assign reg2hw.ctrl_shadowed.key_len.qe = ctrl_shadowed_qe; + + // F[sideload]: 11:11 + caliptra_prim_subreg_ext #( + .DW (1) + ) u_ctrl_shadowed_sideload ( + .re (ctrl_shadowed_re), + .we (ctrl_shadowed_we), + .wd (ctrl_shadowed_sideload_wd), + .d (hw2reg.ctrl_shadowed.sideload.d), + .qre (reg2hw.ctrl_shadowed.sideload.re), + .qe (ctrl_shadowed_flds_we[3]), + .q (reg2hw.ctrl_shadowed.sideload.q), + .ds (), + .qs (ctrl_shadowed_sideload_qs) + ); + assign reg2hw.ctrl_shadowed.sideload.qe = ctrl_shadowed_qe; + + // F[prng_reseed_rate]: 14:12 + caliptra_prim_subreg_ext #( + .DW (3) + ) u_ctrl_shadowed_prng_reseed_rate ( + .re (ctrl_shadowed_re), + .we (ctrl_shadowed_we), + .wd (ctrl_shadowed_prng_reseed_rate_wd), + .d (hw2reg.ctrl_shadowed.prng_reseed_rate.d), + .qre (reg2hw.ctrl_shadowed.prng_reseed_rate.re), + .qe (ctrl_shadowed_flds_we[4]), + .q (reg2hw.ctrl_shadowed.prng_reseed_rate.q), + .ds (), + .qs (ctrl_shadowed_prng_reseed_rate_qs) + ); + assign reg2hw.ctrl_shadowed.prng_reseed_rate.qe = ctrl_shadowed_qe; + + // F[manual_operation]: 15:15 + caliptra_prim_subreg_ext #( + .DW (1) + ) u_ctrl_shadowed_manual_operation ( + .re (ctrl_shadowed_re), + .we (ctrl_shadowed_we), + .wd (ctrl_shadowed_manual_operation_wd), + .d (hw2reg.ctrl_shadowed.manual_operation.d), + .qre (reg2hw.ctrl_shadowed.manual_operation.re), + .qe (ctrl_shadowed_flds_we[5]), + .q (reg2hw.ctrl_shadowed.manual_operation.q), + .ds (), + .qs (ctrl_shadowed_manual_operation_qs) + ); + assign reg2hw.ctrl_shadowed.manual_operation.qe = ctrl_shadowed_qe; + + + // R[ctrl_aux_shadowed]: V(False) + // Create REGWEN-gated WE signal + logic ctrl_aux_shadowed_gated_we; + assign ctrl_aux_shadowed_gated_we = ctrl_aux_shadowed_we & ctrl_aux_regwen_qs; + // F[key_touch_forces_reseed]: 0:0 + caliptra_prim_subreg_shadow #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_ctrl_aux_shadowed_key_touch_forces_reseed ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .rst_shadowed_ni (rst_shadowed_ni), + + // from register interface + .re (ctrl_aux_shadowed_re), + .we (ctrl_aux_shadowed_gated_we), + .wd (ctrl_aux_shadowed_key_touch_forces_reseed_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.ctrl_aux_shadowed.key_touch_forces_reseed.q), + .ds (), + + // to register interface (read) + .qs (ctrl_aux_shadowed_key_touch_forces_reseed_qs), + + // Shadow register phase. Relevant for hwext only. + .phase (), + + // Shadow register error conditions + .err_update (ctrl_aux_shadowed_key_touch_forces_reseed_update_err), + .err_storage (ctrl_aux_shadowed_key_touch_forces_reseed_storage_err) + ); + + // F[force_masks]: 1:1 + caliptra_prim_subreg_shadow #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ctrl_aux_shadowed_force_masks ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .rst_shadowed_ni (rst_shadowed_ni), + + // from register interface + .re (ctrl_aux_shadowed_re), + .we (ctrl_aux_shadowed_gated_we), + .wd (ctrl_aux_shadowed_force_masks_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.ctrl_aux_shadowed.force_masks.q), + .ds (), + + // to register interface (read) + .qs (ctrl_aux_shadowed_force_masks_qs), + + // Shadow register phase. Relevant for hwext only. + .phase (), + + // Shadow register error conditions + .err_update (ctrl_aux_shadowed_force_masks_update_err), + .err_storage (ctrl_aux_shadowed_force_masks_storage_err) + ); + + + // R[ctrl_aux_regwen]: V(False) + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_ctrl_aux_regwen ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (ctrl_aux_regwen_we), + .wd (ctrl_aux_regwen_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (ctrl_aux_regwen_qs) + ); + + + // R[trigger]: V(False) + // F[start]: 0:0 + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessWO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_trigger_start ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (trigger_we), + .wd (trigger_start_wd), + + // from internal hardware + .de (hw2reg.trigger.start.de), + .d (hw2reg.trigger.start.d), + + // to internal hardware + .qe (), + .q (reg2hw.trigger.start.q), + .ds (), + + // to register interface (read) + .qs () + ); + + // F[key_iv_data_in_clear]: 1:1 + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessWO), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_trigger_key_iv_data_in_clear ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (trigger_we), + .wd (trigger_key_iv_data_in_clear_wd), + + // from internal hardware + .de (hw2reg.trigger.key_iv_data_in_clear.de), + .d (hw2reg.trigger.key_iv_data_in_clear.d), + + // to internal hardware + .qe (), + .q (reg2hw.trigger.key_iv_data_in_clear.q), + .ds (), + + // to register interface (read) + .qs () + ); + + // F[data_out_clear]: 2:2 + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessWO), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_trigger_data_out_clear ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (trigger_we), + .wd (trigger_data_out_clear_wd), + + // from internal hardware + .de (hw2reg.trigger.data_out_clear.de), + .d (hw2reg.trigger.data_out_clear.d), + + // to internal hardware + .qe (), + .q (reg2hw.trigger.data_out_clear.q), + .ds (), + + // to register interface (read) + .qs () + ); + + // F[prng_reseed]: 3:3 + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessWO), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_trigger_prng_reseed ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (trigger_we), + .wd (trigger_prng_reseed_wd), + + // from internal hardware + .de (hw2reg.trigger.prng_reseed.de), + .d (hw2reg.trigger.prng_reseed.d), + + // to internal hardware + .qe (), + .q (reg2hw.trigger.prng_reseed.q), + .ds (), + + // to register interface (read) + .qs () + ); + + + // R[status]: V(False) + // F[idle]: 0:0 + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_status_idle ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.status.idle.de), + .d (hw2reg.status.idle.d), + + // to internal hardware + .qe (), + .q (reg2hw.status.idle.q), + .ds (), + + // to register interface (read) + .qs (status_idle_qs) + ); + + // F[stall]: 1:1 + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_status_stall ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.status.stall.de), + .d (hw2reg.status.stall.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (status_stall_qs) + ); + + // F[output_lost]: 2:2 + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_status_output_lost ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.status.output_lost.de), + .d (hw2reg.status.output_lost.d), + + // to internal hardware + .qe (), + .q (reg2hw.status.output_lost.q), + .ds (), + + // to register interface (read) + .qs (status_output_lost_qs) + ); + + // F[output_valid]: 3:3 + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_status_output_valid ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.status.output_valid.de), + .d (hw2reg.status.output_valid.d), + + // to internal hardware + .qe (), + .q (output_valid_o), + .ds (), + + // to register interface (read) + .qs (status_output_valid_qs) + ); + + // F[input_ready]: 4:4 + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_status_input_ready ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.status.input_ready.de), + .d (hw2reg.status.input_ready.d), + + // to internal hardware + .qe (), + .q (input_ready_o), + .ds (), + + // to register interface (read) + .qs (status_input_ready_qs) + ); + + // F[alert_recov_ctrl_update_err]: 5:5 + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_status_alert_recov_ctrl_update_err ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.status.alert_recov_ctrl_update_err.de), + .d (hw2reg.status.alert_recov_ctrl_update_err.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (status_alert_recov_ctrl_update_err_qs) + ); + + // F[alert_fatal_fault]: 6:6 + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_status_alert_fatal_fault ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.status.alert_fatal_fault.de), + .d (hw2reg.status.alert_fatal_fault.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (status_alert_fatal_fault_qs) + ); + + + // R[ctrl_gcm_shadowed]: V(True) + logic ctrl_gcm_shadowed_qe; + logic [1:0] ctrl_gcm_shadowed_flds_we; + assign ctrl_gcm_shadowed_qe = &ctrl_gcm_shadowed_flds_we; + // F[phase]: 5:0 + caliptra_prim_subreg_ext #( + .DW (6) + ) u_ctrl_gcm_shadowed_phase ( + .re (ctrl_gcm_shadowed_re), + .we (ctrl_gcm_shadowed_we), + .wd (ctrl_gcm_shadowed_phase_wd), + .d (hw2reg.ctrl_gcm_shadowed.phase.d), + .qre (reg2hw.ctrl_gcm_shadowed.phase.re), + .qe (ctrl_gcm_shadowed_flds_we[0]), + .q (reg2hw.ctrl_gcm_shadowed.phase.q), + .ds (), + .qs (ctrl_gcm_shadowed_phase_qs) + ); + assign reg2hw.ctrl_gcm_shadowed.phase.qe = ctrl_gcm_shadowed_qe; + + // F[num_valid_bytes]: 10:6 + caliptra_prim_subreg_ext #( + .DW (5) + ) u_ctrl_gcm_shadowed_num_valid_bytes ( + .re (ctrl_gcm_shadowed_re), + .we (ctrl_gcm_shadowed_we), + .wd (ctrl_gcm_shadowed_num_valid_bytes_wd), + .d (hw2reg.ctrl_gcm_shadowed.num_valid_bytes.d), + .qre (reg2hw.ctrl_gcm_shadowed.num_valid_bytes.re), + .qe (ctrl_gcm_shadowed_flds_we[1]), + .q (reg2hw.ctrl_gcm_shadowed.num_valid_bytes.q), + .ds (), + .qs (ctrl_gcm_shadowed_num_valid_bytes_qs) + ); + assign reg2hw.ctrl_gcm_shadowed.num_valid_bytes.qe = ctrl_gcm_shadowed_qe; + + + + logic [34:0] addr_hit; + always_comb begin + addr_hit = '0; + addr_hit[ 0] = (reg_addr == AES_ALERT_TEST_OFFSET); + addr_hit[ 1] = (reg_addr == AES_KEY_SHARE0_0_OFFSET); + addr_hit[ 2] = (reg_addr == AES_KEY_SHARE0_1_OFFSET); + addr_hit[ 3] = (reg_addr == AES_KEY_SHARE0_2_OFFSET); + addr_hit[ 4] = (reg_addr == AES_KEY_SHARE0_3_OFFSET); + addr_hit[ 5] = (reg_addr == AES_KEY_SHARE0_4_OFFSET); + addr_hit[ 6] = (reg_addr == AES_KEY_SHARE0_5_OFFSET); + addr_hit[ 7] = (reg_addr == AES_KEY_SHARE0_6_OFFSET); + addr_hit[ 8] = (reg_addr == AES_KEY_SHARE0_7_OFFSET); + addr_hit[ 9] = (reg_addr == AES_KEY_SHARE1_0_OFFSET); + addr_hit[10] = (reg_addr == AES_KEY_SHARE1_1_OFFSET); + addr_hit[11] = (reg_addr == AES_KEY_SHARE1_2_OFFSET); + addr_hit[12] = (reg_addr == AES_KEY_SHARE1_3_OFFSET); + addr_hit[13] = (reg_addr == AES_KEY_SHARE1_4_OFFSET); + addr_hit[14] = (reg_addr == AES_KEY_SHARE1_5_OFFSET); + addr_hit[15] = (reg_addr == AES_KEY_SHARE1_6_OFFSET); + addr_hit[16] = (reg_addr == AES_KEY_SHARE1_7_OFFSET); + addr_hit[17] = (reg_addr == AES_IV_0_OFFSET); + addr_hit[18] = (reg_addr == AES_IV_1_OFFSET); + addr_hit[19] = (reg_addr == AES_IV_2_OFFSET); + addr_hit[20] = (reg_addr == AES_IV_3_OFFSET); + addr_hit[21] = (reg_addr == AES_DATA_IN_0_OFFSET); + addr_hit[22] = (reg_addr == AES_DATA_IN_1_OFFSET); + addr_hit[23] = (reg_addr == AES_DATA_IN_2_OFFSET); + addr_hit[24] = (reg_addr == AES_DATA_IN_3_OFFSET); + addr_hit[25] = (reg_addr == AES_DATA_OUT_0_OFFSET); + addr_hit[26] = (reg_addr == AES_DATA_OUT_1_OFFSET); + addr_hit[27] = (reg_addr == AES_DATA_OUT_2_OFFSET); + addr_hit[28] = (reg_addr == AES_DATA_OUT_3_OFFSET); + addr_hit[29] = (reg_addr == AES_CTRL_SHADOWED_OFFSET); + addr_hit[30] = (reg_addr == AES_CTRL_AUX_SHADOWED_OFFSET); + addr_hit[31] = (reg_addr == AES_CTRL_AUX_REGWEN_OFFSET); + addr_hit[32] = (reg_addr == AES_TRIGGER_OFFSET); + addr_hit[33] = (reg_addr == AES_STATUS_OFFSET); + addr_hit[34] = (reg_addr == AES_CTRL_GCM_SHADOWED_OFFSET); + end + + assign addrmiss = (reg_re || reg_we) ? ~|addr_hit : 1'b0 ; + + // Check sub-word write is permitted + always_comb begin + wr_err = (reg_we & + ((addr_hit[ 0] & (|(AES_PERMIT[ 0] & ~reg_be))) | + (addr_hit[ 1] & (|(AES_PERMIT[ 1] & ~reg_be))) | + (addr_hit[ 2] & (|(AES_PERMIT[ 2] & ~reg_be))) | + (addr_hit[ 3] & (|(AES_PERMIT[ 3] & ~reg_be))) | + (addr_hit[ 4] & (|(AES_PERMIT[ 4] & ~reg_be))) | + (addr_hit[ 5] & (|(AES_PERMIT[ 5] & ~reg_be))) | + (addr_hit[ 6] & (|(AES_PERMIT[ 6] & ~reg_be))) | + (addr_hit[ 7] & (|(AES_PERMIT[ 7] & ~reg_be))) | + (addr_hit[ 8] & (|(AES_PERMIT[ 8] & ~reg_be))) | + (addr_hit[ 9] & (|(AES_PERMIT[ 9] & ~reg_be))) | + (addr_hit[10] & (|(AES_PERMIT[10] & ~reg_be))) | + (addr_hit[11] & (|(AES_PERMIT[11] & ~reg_be))) | + (addr_hit[12] & (|(AES_PERMIT[12] & ~reg_be))) | + (addr_hit[13] & (|(AES_PERMIT[13] & ~reg_be))) | + (addr_hit[14] & (|(AES_PERMIT[14] & ~reg_be))) | + (addr_hit[15] & (|(AES_PERMIT[15] & ~reg_be))) | + (addr_hit[16] & (|(AES_PERMIT[16] & ~reg_be))) | + (addr_hit[17] & (|(AES_PERMIT[17] & ~reg_be))) | + (addr_hit[18] & (|(AES_PERMIT[18] & ~reg_be))) | + (addr_hit[19] & (|(AES_PERMIT[19] & ~reg_be))) | + (addr_hit[20] & (|(AES_PERMIT[20] & ~reg_be))) | + (addr_hit[21] & (|(AES_PERMIT[21] & ~reg_be))) | + (addr_hit[22] & (|(AES_PERMIT[22] & ~reg_be))) | + (addr_hit[23] & (|(AES_PERMIT[23] & ~reg_be))) | + (addr_hit[24] & (|(AES_PERMIT[24] & ~reg_be))) | + (addr_hit[25] & (|(AES_PERMIT[25] & ~reg_be))) | + (addr_hit[26] & (|(AES_PERMIT[26] & ~reg_be))) | + (addr_hit[27] & (|(AES_PERMIT[27] & ~reg_be))) | + (addr_hit[28] & (|(AES_PERMIT[28] & ~reg_be))) | + (addr_hit[29] & (|(AES_PERMIT[29] & ~reg_be))) | + (addr_hit[30] & (|(AES_PERMIT[30] & ~reg_be))) | + (addr_hit[31] & (|(AES_PERMIT[31] & ~reg_be))) | + (addr_hit[32] & (|(AES_PERMIT[32] & ~reg_be))) | + (addr_hit[33] & (|(AES_PERMIT[33] & ~reg_be))) | + (addr_hit[34] & (|(AES_PERMIT[34] & ~reg_be))))); + end + + // Generate write-enables + assign alert_test_we = addr_hit[0] & reg_we & !reg_error; + + assign alert_test_recov_ctrl_update_err_wd = reg_wdata[0]; + + assign alert_test_fatal_fault_wd = reg_wdata[1]; + assign key_share0_0_we = addr_hit[1] & reg_we & !reg_error; + + assign key_share0_0_wd = reg_wdata[31:0]; + assign key_share0_1_we = addr_hit[2] & reg_we & !reg_error; + + assign key_share0_1_wd = reg_wdata[31:0]; + assign key_share0_2_we = addr_hit[3] & reg_we & !reg_error; + + assign key_share0_2_wd = reg_wdata[31:0]; + assign key_share0_3_we = addr_hit[4] & reg_we & !reg_error; + + assign key_share0_3_wd = reg_wdata[31:0]; + assign key_share0_4_we = addr_hit[5] & reg_we & !reg_error; + + assign key_share0_4_wd = reg_wdata[31:0]; + assign key_share0_5_we = addr_hit[6] & reg_we & !reg_error; + + assign key_share0_5_wd = reg_wdata[31:0]; + assign key_share0_6_we = addr_hit[7] & reg_we & !reg_error; + + assign key_share0_6_wd = reg_wdata[31:0]; + assign key_share0_7_we = addr_hit[8] & reg_we & !reg_error; + + assign key_share0_7_wd = reg_wdata[31:0]; + assign key_share1_0_we = addr_hit[9] & reg_we & !reg_error; + + assign key_share1_0_wd = reg_wdata[31:0]; + assign key_share1_1_we = addr_hit[10] & reg_we & !reg_error; + + assign key_share1_1_wd = reg_wdata[31:0]; + assign key_share1_2_we = addr_hit[11] & reg_we & !reg_error; + + assign key_share1_2_wd = reg_wdata[31:0]; + assign key_share1_3_we = addr_hit[12] & reg_we & !reg_error; + + assign key_share1_3_wd = reg_wdata[31:0]; + assign key_share1_4_we = addr_hit[13] & reg_we & !reg_error; + + assign key_share1_4_wd = reg_wdata[31:0]; + assign key_share1_5_we = addr_hit[14] & reg_we & !reg_error; + + assign key_share1_5_wd = reg_wdata[31:0]; + assign key_share1_6_we = addr_hit[15] & reg_we & !reg_error; + + assign key_share1_6_wd = reg_wdata[31:0]; + assign key_share1_7_we = addr_hit[16] & reg_we & !reg_error; + + assign key_share1_7_wd = reg_wdata[31:0]; + assign iv_0_re = addr_hit[17] & reg_re & !reg_error; + assign iv_0_we = addr_hit[17] & reg_we & !reg_error; + + assign iv_0_wd = reg_wdata[31:0]; + assign iv_1_re = addr_hit[18] & reg_re & !reg_error; + assign iv_1_we = addr_hit[18] & reg_we & !reg_error; + + assign iv_1_wd = reg_wdata[31:0]; + assign iv_2_re = addr_hit[19] & reg_re & !reg_error; + assign iv_2_we = addr_hit[19] & reg_we & !reg_error; + + assign iv_2_wd = reg_wdata[31:0]; + assign iv_3_re = addr_hit[20] & reg_re & !reg_error; + assign iv_3_we = addr_hit[20] & reg_we & !reg_error; + + assign iv_3_wd = reg_wdata[31:0]; + assign data_in_0_we = addr_hit[21] & reg_we & !reg_error; + + assign data_in_0_wd = reg_wdata[31:0]; + assign data_in_1_we = addr_hit[22] & reg_we & !reg_error; + + assign data_in_1_wd = reg_wdata[31:0]; + assign data_in_2_we = addr_hit[23] & reg_we & !reg_error; + + assign data_in_2_wd = reg_wdata[31:0]; + assign data_in_3_we = addr_hit[24] & reg_we & !reg_error; + + assign data_in_3_wd = reg_wdata[31:0]; + assign data_out_0_re = addr_hit[25] & reg_re & !reg_error; + assign data_out_1_re = addr_hit[26] & reg_re & !reg_error; + assign data_out_2_re = addr_hit[27] & reg_re & !reg_error; + assign data_out_3_re = addr_hit[28] & reg_re & !reg_error; + assign ctrl_shadowed_re = addr_hit[29] & reg_re & !reg_error; + assign ctrl_shadowed_we = addr_hit[29] & reg_we & !reg_error; + + assign ctrl_shadowed_operation_wd = reg_wdata[1:0]; + + assign ctrl_shadowed_mode_wd = reg_wdata[7:2]; + + assign ctrl_shadowed_key_len_wd = reg_wdata[10:8]; + + assign ctrl_shadowed_sideload_wd = reg_wdata[11]; + + assign ctrl_shadowed_prng_reseed_rate_wd = reg_wdata[14:12]; + + assign ctrl_shadowed_manual_operation_wd = reg_wdata[15]; + assign ctrl_aux_shadowed_re = addr_hit[30] & reg_re & !reg_error; + assign ctrl_aux_shadowed_we = addr_hit[30] & reg_we & !reg_error; + + assign ctrl_aux_shadowed_key_touch_forces_reseed_wd = reg_wdata[0]; + + assign ctrl_aux_shadowed_force_masks_wd = reg_wdata[1]; + assign ctrl_aux_regwen_we = addr_hit[31] & reg_we & !reg_error; + + assign ctrl_aux_regwen_wd = reg_wdata[0]; + assign trigger_we = addr_hit[32] & reg_we & !reg_error; + + assign trigger_start_wd = reg_wdata[0]; + + assign trigger_key_iv_data_in_clear_wd = reg_wdata[1]; + + assign trigger_data_out_clear_wd = reg_wdata[2]; + + assign trigger_prng_reseed_wd = reg_wdata[3]; + assign ctrl_gcm_shadowed_re = addr_hit[34] & reg_re & !reg_error; + assign ctrl_gcm_shadowed_we = addr_hit[34] & reg_we & !reg_error; + + assign ctrl_gcm_shadowed_phase_wd = reg_wdata[5:0]; + + assign ctrl_gcm_shadowed_num_valid_bytes_wd = reg_wdata[10:6]; + + // Assign write-enables to checker logic vector. + always_comb begin + reg_we_check = '0; + reg_we_check[0] = alert_test_we; + reg_we_check[1] = key_share0_0_we; + reg_we_check[2] = key_share0_1_we; + reg_we_check[3] = key_share0_2_we; + reg_we_check[4] = key_share0_3_we; + reg_we_check[5] = key_share0_4_we; + reg_we_check[6] = key_share0_5_we; + reg_we_check[7] = key_share0_6_we; + reg_we_check[8] = key_share0_7_we; + reg_we_check[9] = key_share1_0_we; + reg_we_check[10] = key_share1_1_we; + reg_we_check[11] = key_share1_2_we; + reg_we_check[12] = key_share1_3_we; + reg_we_check[13] = key_share1_4_we; + reg_we_check[14] = key_share1_5_we; + reg_we_check[15] = key_share1_6_we; + reg_we_check[16] = key_share1_7_we; + reg_we_check[17] = iv_0_we; + reg_we_check[18] = iv_1_we; + reg_we_check[19] = iv_2_we; + reg_we_check[20] = iv_3_we; + reg_we_check[21] = data_in_0_we; + reg_we_check[22] = data_in_1_we; + reg_we_check[23] = data_in_2_we; + reg_we_check[24] = data_in_3_we; + reg_we_check[25] = 1'b0; + reg_we_check[26] = 1'b0; + reg_we_check[27] = 1'b0; + reg_we_check[28] = 1'b0; + reg_we_check[29] = ctrl_shadowed_we; + reg_we_check[30] = ctrl_aux_shadowed_gated_we; + reg_we_check[31] = ctrl_aux_regwen_we; + reg_we_check[32] = trigger_we; + reg_we_check[33] = 1'b0; + reg_we_check[34] = ctrl_gcm_shadowed_we; + end + + // Read data return + always_comb begin + reg_rdata_next = '0; + unique case (1'b1) + addr_hit[0]: begin + reg_rdata_next[0] = '0; + reg_rdata_next[1] = '0; + end + + addr_hit[1]: begin + reg_rdata_next[31:0] = '0; + end + + addr_hit[2]: begin + reg_rdata_next[31:0] = '0; + end + + addr_hit[3]: begin + reg_rdata_next[31:0] = '0; + end + + addr_hit[4]: begin + reg_rdata_next[31:0] = '0; + end + + addr_hit[5]: begin + reg_rdata_next[31:0] = '0; + end + + addr_hit[6]: begin + reg_rdata_next[31:0] = '0; + end + + addr_hit[7]: begin + reg_rdata_next[31:0] = '0; + end + + addr_hit[8]: begin + reg_rdata_next[31:0] = '0; + end + + addr_hit[9]: begin + reg_rdata_next[31:0] = '0; + end + + addr_hit[10]: begin + reg_rdata_next[31:0] = '0; + end + + addr_hit[11]: begin + reg_rdata_next[31:0] = '0; + end + + addr_hit[12]: begin + reg_rdata_next[31:0] = '0; + end + + addr_hit[13]: begin + reg_rdata_next[31:0] = '0; + end + + addr_hit[14]: begin + reg_rdata_next[31:0] = '0; + end + + addr_hit[15]: begin + reg_rdata_next[31:0] = '0; + end + + addr_hit[16]: begin + reg_rdata_next[31:0] = '0; + end + + addr_hit[17]: begin + reg_rdata_next[31:0] = iv_0_qs; + end + + addr_hit[18]: begin + reg_rdata_next[31:0] = iv_1_qs; + end + + addr_hit[19]: begin + reg_rdata_next[31:0] = iv_2_qs; + end + + addr_hit[20]: begin + reg_rdata_next[31:0] = iv_3_qs; + end + + addr_hit[21]: begin + reg_rdata_next[31:0] = '0; + end + + addr_hit[22]: begin + reg_rdata_next[31:0] = '0; + end + + addr_hit[23]: begin + reg_rdata_next[31:0] = '0; + end + + addr_hit[24]: begin + reg_rdata_next[31:0] = '0; + end + + addr_hit[25]: begin + reg_rdata_next[31:0] = data_out_0_qs; + end + + addr_hit[26]: begin + reg_rdata_next[31:0] = data_out_1_qs; + end + + addr_hit[27]: begin + reg_rdata_next[31:0] = data_out_2_qs; + end + + addr_hit[28]: begin + reg_rdata_next[31:0] = data_out_3_qs; + end + + addr_hit[29]: begin + reg_rdata_next[1:0] = ctrl_shadowed_operation_qs; + reg_rdata_next[7:2] = ctrl_shadowed_mode_qs; + reg_rdata_next[10:8] = ctrl_shadowed_key_len_qs; + reg_rdata_next[11] = ctrl_shadowed_sideload_qs; + reg_rdata_next[14:12] = ctrl_shadowed_prng_reseed_rate_qs; + reg_rdata_next[15] = ctrl_shadowed_manual_operation_qs; + end + + addr_hit[30]: begin + reg_rdata_next[0] = ctrl_aux_shadowed_key_touch_forces_reseed_qs; + reg_rdata_next[1] = ctrl_aux_shadowed_force_masks_qs; + end + + addr_hit[31]: begin + reg_rdata_next[0] = ctrl_aux_regwen_qs; + end + + addr_hit[32]: begin + reg_rdata_next[0] = '0; + reg_rdata_next[1] = '0; + reg_rdata_next[2] = '0; + reg_rdata_next[3] = '0; + end + + addr_hit[33]: begin + reg_rdata_next[0] = status_idle_qs; + reg_rdata_next[1] = status_stall_qs; + reg_rdata_next[2] = status_output_lost_qs; + reg_rdata_next[3] = status_output_valid_qs; + reg_rdata_next[4] = status_input_ready_qs; + reg_rdata_next[5] = status_alert_recov_ctrl_update_err_qs; + reg_rdata_next[6] = status_alert_fatal_fault_qs; + end + + addr_hit[34]: begin + reg_rdata_next[5:0] = ctrl_gcm_shadowed_phase_qs; + reg_rdata_next[10:6] = ctrl_gcm_shadowed_num_valid_bytes_qs; + end + + default: begin + reg_rdata_next = '1; + end + endcase + end + + // shadow busy + logic shadow_busy; + logic rst_done; + logic shadow_rst_done; + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + rst_done <= '0; + end else begin + rst_done <= 1'b1; + end + end + + always_ff @(posedge clk_i or negedge rst_shadowed_ni) begin + if (!rst_shadowed_ni) begin + shadow_rst_done <= '0; + end else begin + shadow_rst_done <= 1'b1; + end + end + + // both shadow and normal resets have been released + assign shadow_busy = ~(rst_done & shadow_rst_done); + + // Collect up storage and update errors + assign shadowed_storage_err_o = |{ + ctrl_aux_shadowed_key_touch_forces_reseed_storage_err, + ctrl_aux_shadowed_force_masks_storage_err + }; + assign shadowed_update_err_o = |{ + ctrl_aux_shadowed_key_touch_forces_reseed_update_err, + ctrl_aux_shadowed_force_masks_update_err + }; + + // register busy + assign reg_busy = shadow_busy; + + // Unused signal tieoff + + // wdata / byte enable are not always fully used + // add a blanket unused statement to handle lint waivers + logic unused_wdata; + logic unused_be; + assign unused_wdata = ^reg_wdata; + assign unused_be = ^reg_be; + + // Assertions for Register Interface + `CALIPTRA_ASSERT_PULSE(wePulse, reg_we, clk_i, !rst_ni) + `CALIPTRA_ASSERT_PULSE(rePulse, reg_re, clk_i, !rst_ni) + + `CALIPTRA_ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o_pre.d_valid, clk_i, !rst_ni) + + `CALIPTRA_ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit), clk_i, !rst_ni) + + // this is formulated as an assumption such that the FPV testbenches do disprove this + // property by mistake + //`ASSUME(reqParity, tl_reg_h2d.a_valid |-> tl_reg_h2d.a_user.chk_en == caliptra_tlul_pkg::CheckDis) + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/aes_sbox.sv b/designs/Caliptra/src/caliptra-rtl/aes_sbox.sv new file mode 100644 index 0000000..66be526 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/aes_sbox.sv @@ -0,0 +1,144 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// AES SBox + +`include "caliptra_prim_assert.sv" + +module aes_sbox import aes_pkg::*; +#( + parameter sbox_impl_e SecSBoxImpl = SBoxImplLut +) ( + input logic clk_i, + input logic rst_ni, + input logic en_i, + output logic out_req_o, + input logic out_ack_i, + input ciph_op_e op_i, + input logic [7:0] data_i, + input logic [7:0] mask_i, + input logic [WidthPRDSBox+19:0] prd_i, + output logic [7:0] data_o, + output logic [7:0] mask_o, + output logic [19:0] prd_o +); + + // Create a lint error to reduce the risk of accidentally using a less secure SBox + // implementation. + `CALIPTRA_ASSERT_STATIC_LINT_ERROR(AesSBoxSecSBoxImplNonDefault, SecSBoxImpl == SBoxImplDom) + + localparam bit SBoxMasked = (SecSBoxImpl == SBoxImplCanrightMasked || + SecSBoxImpl == SBoxImplCanrightMaskedNoreuse || + SecSBoxImpl == SBoxImplDom) ? 1'b1 : 1'b0; + + localparam bit SBoxSingleCycle = (SecSBoxImpl == SBoxImplDom) ? 1'b0 : 1'b1; + + if (!SBoxMasked) begin : gen_sbox_unmasked + // Tie off unused inputs. + logic unused_clk; + logic unused_rst; + logic [7:0] unused_mask; + logic [WidthPRDSBox+19:0] unused_prd; + assign unused_clk = clk_i; + assign unused_rst = rst_ni; + assign unused_mask = mask_i; + assign unused_prd = prd_i; + + if (SecSBoxImpl == SBoxImplCanright) begin : gen_sbox_canright + aes_sbox_canright u_aes_sbox ( + .op_i ( op_i ), + .data_i ( data_i ), + .data_o ( data_o ) + ); + + end else begin : gen_sbox_lut // SecSBoxImpl == SBoxImplLut + aes_sbox_lut u_aes_sbox ( + .op_i ( op_i ), + .data_i ( data_i ), + .data_o ( data_o ) + ); + end + + assign mask_o = '0; + assign prd_o = '0; + + end else begin : gen_sbox_masked + + // SEC_CM: KEY.MASKING + if (SecSBoxImpl == SBoxImplDom) begin : gen_sbox_dom + + aes_sbox_dom u_aes_sbox ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .en_i ( en_i ), + .out_req_o ( out_req_o ), + .out_ack_i ( out_ack_i ), + .op_i ( op_i ), + .data_i ( data_i ), + .mask_i ( mask_i ), + .prd_i ( prd_i[27:0] ), + .data_o ( data_o ), + .mask_o ( mask_o ), + .prd_o ( prd_o ) + ); + + `CALIPTRA_ASSERT_INIT(AesWidthPRDSBox, WidthPRDSBox == 8) + + end else if (SecSBoxImpl == SBoxImplCanrightMaskedNoreuse) begin : + gen_sbox_canright_masked_noreuse + // Tie off unused inputs. + logic unused_clk; + logic unused_rst; + logic [19:0] unused_prd; + assign unused_clk = clk_i; + assign unused_rst = rst_ni; + assign unused_prd = prd_i[WidthPRDSBox+19:WidthPRDSBox]; + + aes_sbox_canright_masked_noreuse u_aes_sbox ( + .op_i ( op_i ), + .data_i ( data_i ), + .mask_i ( mask_i ), + .prd_i ( prd_i[17:0] ), + .data_o ( data_o ), + .mask_o ( mask_o ) + ); + + assign prd_o = '0; + + `CALIPTRA_ASSERT_INIT(AesWidthPRDSBox, WidthPRDSBox == 18) + + end else begin : gen_sbox_canright_masked // SecSBoxImpl == SBoxImplCanrightMasked + // Tie off unused inputs. + logic unused_clk; + logic unused_rst; + logic [19:0] unused_prd; + assign unused_clk = clk_i; + assign unused_rst = rst_ni; + assign unused_prd = prd_i[WidthPRDSBox+19:WidthPRDSBox]; + + aes_sbox_canright_masked u_aes_sbox ( + .op_i ( op_i ), + .data_i ( data_i ), + .mask_i ( mask_i ), + .prd_i ( prd_i[7:0] ), + .data_o ( data_o ), + .mask_o ( mask_o ) + ); + + assign prd_o = '0; + + `CALIPTRA_ASSERT_INIT(AesWidthPRDSBox, WidthPRDSBox == 8) + end + end + + if (SBoxSingleCycle) begin : gen_req_singlecycle + // Tie off unused inputs. + logic unused_out_ack; + assign unused_out_ack = out_ack_i; + + // Signal that we have valid output right away. + assign out_req_o = en_i; + end + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/aes_sbox_canright.sv b/designs/Caliptra/src/caliptra-rtl/aes_sbox_canright.sv new file mode 100644 index 0000000..232a59f --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/aes_sbox_canright.sv @@ -0,0 +1,70 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// AES Canright SBox #4 +// +// For details, see the technical report: Canright, "A very compact Rijndael S-box" +// available at https://hdl.handle.net/10945/25608 + +module aes_sbox_canright ( + input aes_pkg::ciph_op_e op_i, + input logic [7:0] data_i, + output logic [7:0] data_o +); + + import aes_pkg::*; + import aes_sbox_canright_pkg::*; + + /////////////// + // Functions // + /////////////// + + // Inverse in GF(2^4), using normal basis [alpha^8, alpha^2] + // (see Figure 12 in the technical report) + function automatic logic [3:0] aes_inverse_gf2p4(logic [3:0] gamma); + logic [3:0] delta; + logic [1:0] a, b, c, d; + a = gamma[3:2] ^ gamma[1:0]; + b = aes_mul_gf2p2(gamma[3:2], gamma[1:0]); + c = aes_scale_omega2_gf2p2(aes_square_gf2p2(a)); + d = aes_square_gf2p2(c ^ b); + delta[3:2] = aes_mul_gf2p2(d, gamma[1:0]); + delta[1:0] = aes_mul_gf2p2(d, gamma[3:2]); + return delta; + endfunction + + // Inverse in GF(2^8), using normal basis [d^16, d] + // (see Figure 11 in the technical report) + function automatic logic [7:0] aes_inverse_gf2p8(logic [7:0] gamma); + logic [7:0] delta; + logic [3:0] a, b, c, d; + a = gamma[7:4] ^ gamma[3:0]; + b = aes_mul_gf2p4(gamma[7:4], gamma[3:0]); + c = aes_square_scale_gf2p4_gf2p2(a); + d = aes_inverse_gf2p4(c ^ b); + delta[7:4] = aes_mul_gf2p4(d, gamma[3:0]); + delta[3:0] = aes_mul_gf2p4(d, gamma[7:4]); + return delta; + endfunction + + /////////////////// + // Canright SBox // + /////////////////// + + logic [7:0] data_basis_x, data_inverse; + + // Convert to normal basis X. + assign data_basis_x = (op_i == CIPH_FWD) ? aes_mvm(data_i, A2X) : + (op_i == CIPH_INV) ? aes_mvm(data_i ^ 8'h63, S2X) : + aes_mvm(data_i, A2X); + + // Do the inversion in normal basis X. + assign data_inverse = aes_inverse_gf2p8(data_basis_x); + + // Convert to basis S or A. + assign data_o = (op_i == CIPH_FWD) ? aes_mvm(data_inverse, X2S) ^ 8'h63 : + (op_i == CIPH_INV) ? aes_mvm(data_inverse, X2A) : + aes_mvm(data_inverse, X2S) ^ 8'h63; + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/aes_sbox_canright_masked.sv b/designs/Caliptra/src/caliptra-rtl/aes_sbox_canright_masked.sv new file mode 100644 index 0000000..6bb9be5 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/aes_sbox_canright_masked.sv @@ -0,0 +1,486 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// AES Masked Canright SBox with Mask Re-Use +// +// For details, see the following paper: +// Canright, "A very compact 'perfectly masked' S-box for AES (corrected)" +// available at https://eprint.iacr.org/2009/011.pdf +// +// Note: This module implements the masked inversion algorithm with re-using masks. +// For details, see Section 2.3 of the paper. Re-using masks may make the implementation more +// vulnerable to higher-order differential side-channel analysis, but it remains secure against +// first-order attacks. This implementation is commonly referred to as THE Canright Masked SBox. +// +// A formal analysis using REBECCA (stable and transient mode) shows that this implementation is +// not secure. It's usage is thus discouraged. It's included here mainly for reference. +// +// For details on the REBECCA tool, see the following paper: +// Bloem, "Formal verification of masked hardware implementations in the presence of glitches" +// available at https://eprint.iacr.org/2017/897.pdf + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// IMPORTANT NOTE: // +// DO NOT USE THIS FOR SYNTHESIS BLINDLY! // +// // +// This implementation relies on primitive cells like caliptra_prim_buf/xor2 containing tool-specific // +// synthesis attributes to enforce the correct ordering of operations and avoid aggressive // +// optimization. Without the proper primitives, synthesis tools might heavily optimize the // +// design. The result is likely insecure. Use with care. // +/////////////////////////////////////////////////////////////////////////////////////////////////// + +// Masked inverse in GF(2^4), using normal basis [z^4, z] +// (see Formulas 6, 13, 14, 15, 21, 22, 23, 24 in the paper) +module aes_masked_inverse_gf2p4 ( + input logic [3:0] b, + input logic [3:0] q, + input logic [1:0] r, + input logic [3:0] m1, + output logic [3:0] b_inv +); + + import aes_pkg::*; + import aes_sbox_canright_pkg::*; + + logic [1:0] b1, b0, q1, q0, c_inv, r_sq, m11, m10; + assign b1 = b[3:2]; + assign b0 = b[1:0]; + assign q1 = q[3:2]; + assign q0 = q[1:0]; + assign m11 = m1[3:2]; + assign m10 = m1[1:0]; + + // Get re-usable intermediate results. + logic [1:0] mul_b0_q1, mul_b1_q0, mul_q1_q0; + assign mul_b0_q1 = aes_mul_gf2p2(b0, q1); + assign mul_b1_q0 = aes_mul_gf2p2(b1, q0); + assign mul_q1_q0 = aes_mul_gf2p2(q1, q0); + + // Avoid aggressive synthesis optimizations. + logic [1:0] mul_b0_q1_buf, mul_b1_q0_buf, mul_q1_q0_buf; + caliptra_prim_buf #( + .Width ( 6 ) + ) u_caliptra_prim_buf_mul_bq01 ( + .in_i ( {mul_b0_q1, mul_b1_q0, mul_q1_q0} ), + .out_o ( {mul_b0_q1_buf, mul_b1_q0_buf, mul_q1_q0_buf} ) + ); + + //////////////// + // Formula 13 // + //////////////// + // IMPORTANT: The following ops must be executed in order (left to right): + // c = r ^ aes_scale_omega2_gf2p2(aes_square_gf2p2(b1 ^ b0)) + // ^ aes_scale_omega2_gf2p2(aes_square_gf2p2(q1 ^ q0)) + // ^ aes_mul_gf2p2(b1, b0) + // ^ mul_b1_q0 ^ mul_b0_q1 ^ mul_q0_q1; + + // Get intermediate terms. + logic [1:0] scale_omega2_b, scale_omega2_q; + logic [1:0] mul_b1_b0; + assign scale_omega2_b = aes_scale_omega2_gf2p2(aes_square_gf2p2(b1 ^ b0)); + assign scale_omega2_q = aes_scale_omega2_gf2p2(aes_square_gf2p2(q1 ^ q0)); + assign mul_b1_b0 = aes_mul_gf2p2(b1, b0); + + // These terms are added to other terms that depend on the same inputs. + // Avoid aggressive synthesis optimizations. + logic [1:0] scale_omega2_b_buf, scale_omega2_q_buf; + caliptra_prim_buf #( + .Width ( 4 ) + ) u_caliptra_prim_buf_scale_omega2_bq ( + .in_i ( {scale_omega2_b, scale_omega2_q} ), + .out_o ( {scale_omega2_b_buf, scale_omega2_q_buf} ) + ); + logic [1:0] mul_b1_b0_buf; + caliptra_prim_buf #( + .Width ( 2 ) + ) u_caliptra_prim_buf_mul_b1_b0 ( + .in_i ( mul_b1_b0 ), + .out_o ( mul_b1_b0_buf ) + ); + + // Generate c step by step. + logic [1:0] c [6]; + logic [1:0] c_buf [6]; + assign c[0] = r ^ scale_omega2_b_buf; + assign c[1] = c_buf[0] ^ scale_omega2_q_buf; + assign c[2] = c_buf[1] ^ mul_b1_b0_buf; + assign c[3] = c_buf[2] ^ mul_b1_q0_buf; + assign c[4] = c_buf[3] ^ mul_b0_q1_buf; + assign c[5] = c_buf[4] ^ mul_q1_q0_buf; + + // Avoid aggressive synthesis optimizations. + for (genvar i = 0; i < 6; i++) begin : gen_c_buf + caliptra_prim_buf #( + .Width ( 2 ) + ) u_caliptra_prim_buf_c_i ( + .in_i ( c[i] ), + .out_o ( c_buf[i] ) + ); + end + + //////////////////////// + // Formulas 14 and 15 // + //////////////////////// + // Note: aes_square_gf2p2 contains no logic, it's just a bit swap. There is no need to insert + // additional buffers to stop aggressive synthesis optimizations here. + assign c_inv = aes_square_gf2p2(c_buf[5]); + assign r_sq = aes_square_gf2p2(r); + + //////////////////////// + // Formulas 21 and 23 // + //////////////////////// + // Re-masking c_inv + // IMPORTANT: First combine the masks (ops in parens) then apply to c_inv: + // c_inv = c_inv ^ (q1 ^ r_sq); + // c2_inv = c_inv ^ (q0 ^ q1); + + // Get intermediate terms. + logic [1:0] xor_q1_r_sq, xor_q0_q1, c1_inv, c2_inv; + caliptra_prim_xor2 #( + .Width ( 2 ) + ) u_caliptra_prim_xor_q1_r_sq ( + .in0_i ( q1 ), + .in1_i ( r_sq ), + .out_o ( xor_q1_r_sq ) + ); + caliptra_prim_xor2 #( + .Width ( 2 ) + ) u_caliptra_prim_xor_q0_q1 ( + .in0_i ( q0 ), + .in1_i ( q1 ), + .out_o ( xor_q0_q1 ) + ); + + // Generate c1_inv and c2_inv. + caliptra_prim_xor2 #( + .Width ( 2 ) + ) u_caliptra_prim_c1_inv ( + .in0_i ( xor_q1_r_sq ), + .in1_i ( c_inv ), + .out_o ( c1_inv ) + ); + caliptra_prim_xor2 #( + .Width ( 2 ) + ) u_caliptra_prim_c2_inv ( + .in0_i ( c1_inv ), + .in1_i ( xor_q0_q1 ), + .out_o ( c2_inv ) + ); + + //////////////////////// + // Formulas 22 and 24 // + //////////////////////// + // IMPORTANT: The following ops must be executed in order (left to right): + // b1_inv = m11 ^ aes_mul_gf2p2(b0, c1_inv) + // ^ mul_b0_q1 ^ aes_mul_gf2p2(q0, c1_inv) ^ mul_q0_q1; + // b0_inv = m10 ^ aes_mul_gf2p2(b1, c2_inv) + // ^ mul_b1_q0 ^ aes_mul_gf2p2(q1, c2_inv) ^ mul_q0_q1; + + // Get intermediate terms. + logic [1:0] mul_b0_c1_inv, mul_q0_c1_inv, mul_b1_c2_inv, mul_q1_c2_inv; + assign mul_b0_c1_inv = aes_mul_gf2p2(b0, c1_inv); + assign mul_q0_c1_inv = aes_mul_gf2p2(q0, c1_inv); + assign mul_b1_c2_inv = aes_mul_gf2p2(b1, c2_inv); + assign mul_q1_c2_inv = aes_mul_gf2p2(q1, c2_inv); + + // The multiplier outputs are added to terms that depend on the same inputs. + // Avoid aggressive synthesis optimizations. + logic [1:0] mul_b0_c1_inv_buf, mul_q0_c1_inv_buf, mul_b1_c2_inv_buf, mul_q1_c2_inv_buf; + caliptra_prim_buf #( + .Width ( 8 ) + ) u_caliptra_prim_buf_mul_bq01_c12_inv ( + .in_i ( {mul_b0_c1_inv, mul_q0_c1_inv, mul_b1_c2_inv, mul_q1_c2_inv} ), + .out_o ( {mul_b0_c1_inv_buf, mul_q0_c1_inv_buf, mul_b1_c2_inv_buf, mul_q1_c2_inv_buf} ) + ); + + // Generate b1_inv and b0_inv step by step. + logic [1:0] b1_inv [4]; + logic [1:0] b1_inv_buf [4]; + logic [1:0] b0_inv [4]; + logic [1:0] b0_inv_buf [4]; + assign b1_inv[0] = m11 ^ mul_b0_c1_inv_buf; + assign b1_inv[1] = b1_inv_buf[0] ^ mul_b0_q1_buf; + assign b1_inv[2] = b1_inv_buf[1] ^ mul_q0_c1_inv_buf; + assign b1_inv[3] = b1_inv_buf[2] ^ mul_q1_q0_buf; + assign b0_inv[0] = m10 ^ mul_b1_c2_inv_buf; + assign b0_inv[1] = b0_inv_buf[0] ^ mul_b1_q0_buf; + assign b0_inv[2] = b0_inv_buf[1] ^ mul_q1_c2_inv_buf; + assign b0_inv[3] = b0_inv_buf[2] ^ mul_q1_q0_buf; + + // Avoid aggressive synthesis optimizations. + for (genvar i = 0; i < 4; i++) begin : gen_a01_inv_buf + caliptra_prim_buf #( + .Width ( 2 ) + ) u_caliptra_prim_buf_b1_inv_i ( + .in_i ( b1_inv[i] ), + .out_o ( b1_inv_buf[i] ) + ); + caliptra_prim_buf #( + .Width ( 2 ) + ) u_caliptra_prim_buf_b0_inv_i ( + .in_i ( b0_inv[i] ), + .out_o ( b0_inv_buf[i] ) + ); + end + + // Note: b_inv is masked by m1, b was masked by q. + assign b_inv = {b1_inv_buf[3], b0_inv_buf[3]}; +endmodule + +// Masked inverse in GF(2^8), using normal basis [y^16, y] +// (see Formulas 3, 12, 25, 26 and 27 in the paper) +module aes_masked_inverse_gf2p8 ( + input logic [7:0] a, + input logic [7:0] m, + input logic [7:0] n, + output logic [7:0] a_inv +); + + import aes_pkg::*; + import aes_sbox_canright_pkg::*; + + logic [3:0] a1, a0, m1, m0, q, b_inv, s1, s0; + logic [1:0] r; + + assign a1 = a[7:4]; + assign a0 = a[3:0]; + assign m1 = m[7:4]; + assign m0 = m[3:0]; + + //////////////////// + // Notes on masks // + //////////////////// + // The paper states the following. + // - r must be independent of q. + // - q must be independent of m. + // - s is the specified output mask n. + assign r = m1[3:2]; + assign q = n[7:4]; + assign s1 = n[7:4]; + assign s0 = n[3:0]; + + // Get re-usable intermediate results. + logic [3:0] mul_a0_m1, mul_a1_m0, mul_m0_m1; + assign mul_a0_m1 = aes_mul_gf2p4(a0, m1); + assign mul_a1_m0 = aes_mul_gf2p4(a1, m0); + assign mul_m0_m1 = aes_mul_gf2p4(m0, m1); + + // Avoid aggressive synthesis optimizations. + logic [3:0] mul_a0_m1_buf, mul_a1_m0_buf, mul_m0_m1_buf; + caliptra_prim_buf #( + .Width ( 12 ) + ) u_caliptra_prim_buf_mul_bq01 ( + .in_i ( {mul_a0_m1, mul_a1_m0, mul_m0_m1} ), + .out_o ( {mul_a0_m1_buf, mul_a1_m0_buf, mul_m0_m1_buf} ) + ); + + //////////////// + // Formula 12 // + //////////////// + // IMPORTANT: The following ops must be executed in order (left to right): + // b = q ^ aes_square_scale_gf2p4_gf2p2(a1 ^ a0) + // ^ aes_square_scale_gf2p4_gf2p2(m1 ^ m0) + // ^ aes_mul_gf2p4(a1, a0) + // ^ mul_a1_m0 ^ mul_a0_m1 ^ mul_m0_m1; + + // Get intermediate terms. + logic [3:0] ss_a1_a0, ss_m1_m0; + assign ss_a1_a0 = aes_square_scale_gf2p4_gf2p2(a1 ^ a0); + assign ss_m1_m0 = aes_square_scale_gf2p4_gf2p2(m1 ^ m0); + + logic [3:0] mul_a1_a0; + assign mul_a1_a0 = aes_mul_gf2p4(a1, a0); + + // The multiplier output is added to terms that depend on the same inputs. + // Avoid aggressive synthesis optimizations. + logic [3:0] mul_a1_a0_buf; + caliptra_prim_buf #( + .Width ( 4 ) + ) u_caliptra_prim_buf_mul_am01 ( + .in_i ( mul_a1_a0 ), + .out_o ( mul_a1_a0_buf ) + ); + + // Generate b step by step. + logic [3:0] b [6]; + logic [3:0] b_buf [6]; + assign b[0] = q ^ ss_a1_a0; // q does not depend on a1, a0. + assign b[1] = b_buf[0] ^ ss_m1_m0; // b[0] does not depend on m1, m0. + assign b[2] = b_buf[1] ^ mul_a1_a0_buf; + assign b[3] = b_buf[2] ^ mul_a1_m0_buf; + assign b[4] = b_buf[3] ^ mul_a0_m1_buf; + assign b[5] = b_buf[4] ^ mul_m0_m1_buf; + + // Avoid aggressive synthesis optimizations. + for (genvar i = 0; i < 6; i++) begin : gen_b_buf + caliptra_prim_buf #( + .Width ( 4 ) + ) u_caliptra_prim_buf_b_i ( + .in_i ( b[i] ), + .out_o ( b_buf[i] ) + ); + end + + ////////////////////// + // GF(2^4) Inverter // + ////////////////////// + + // b is masked by q, b_inv is masked by m1. + aes_masked_inverse_gf2p4 u_aes_masked_inverse_gf2p4 ( + .b ( b_buf[5] ), + .q ( q ), + .r ( r ), + .m1 ( m1 ), + .b_inv ( b_inv ) + ); + + // The output of the inverse over GF(2^4) and signals derived from that are again recombined + // with inputs to the GF(2^4) inverter. Aggressive synthesis optimizations across the GF(2^4) + // inverter may result in SCA leakage and should be avoided. + logic [3:0] b_inv_buf; + caliptra_prim_buf #( + .Width ( 4 ) + ) u_caliptra_prim_buf_b_inv ( + .in_i ( b_inv ), + .out_o ( b_inv_buf ) + ); + + //////////////// + // Formula 26 // + //////////////// + // IMPORTANT: First combine the masks (ops in parens) then apply to b_inv: + // b2_inv = b_inv ^ (m1 ^ m0); + + // Generate b2_inv step by step. + logic [3:0] xor_m1_m0, b2_inv; + caliptra_prim_xor2 #( + .Width ( 4 ) + ) u_caliptra_prim_xor_m1_m0 ( + .in0_i ( m1 ), + .in1_i ( m0 ), + .out_o ( xor_m1_m0 ) + ); + caliptra_prim_xor2 #( + .Width ( 4 ) + ) u_caliptra_prim_xor_b2_inv ( + .in0_i ( b_inv_buf ), + .in1_i ( xor_m1_m0 ), + .out_o ( b2_inv ) + ); + + //////////////////////// + // Formulas 25 and 27 // + //////////////////////// + // IMPORTANT: The following ops must be executed in order (left to right): + // a1_inv = s1 ^ aes_mul_gf2p4(a0, b_inv) + // ^ mul_a0_m1 ^ aes_mul_gf2p4(m0, b_inv) ^ mul_m0_m1; + // a0_inv = s0 ^ aes_mul_gf2p4(a1, b2_inv) + // ^ mul_a1_m0 ^ aes_mul_gf2p4(m1, b2_inv) ^ mul_m0_m1; + + // Get intermediate terms. + logic [3:0] mul_a0_b_inv, mul_m0_b_inv, mul_a1_b2_inv, mul_m1_b2_inv; + assign mul_a0_b_inv = aes_mul_gf2p4(a0, b_inv_buf); + assign mul_m0_b_inv = aes_mul_gf2p4(m0, b_inv_buf); + assign mul_a1_b2_inv = aes_mul_gf2p4(a1, b2_inv); + assign mul_m1_b2_inv = aes_mul_gf2p4(m1, b2_inv); + + // The multiplier outputs are added to terms that depend on the same inputs. + // Avoid aggressive synthesis optimizations. + logic [3:0] mul_a0_b_inv_buf, mul_m0_b_inv_buf, mul_a1_b2_inv_buf, mul_m1_b2_inv_buf; + caliptra_prim_buf #( + .Width ( 16 ) + ) u_caliptra_prim_buf_mul_bq01_c12_inv ( + .in_i ( {mul_a0_b_inv, mul_m0_b_inv, mul_a1_b2_inv, mul_m1_b2_inv} ), + .out_o ( {mul_a0_b_inv_buf, mul_m0_b_inv_buf, mul_a1_b2_inv_buf, mul_m1_b2_inv_buf} ) + ); + + // Generate a1_inv and a0_inv step by step. + logic [3:0] a1_inv [4]; + logic [3:0] a1_inv_buf [4]; + logic [3:0] a0_inv [4]; + logic [3:0] a0_inv_buf [4]; + assign a1_inv[0] = s1 ^ mul_a0_b_inv_buf; + assign a1_inv[1] = a1_inv_buf[0] ^ mul_a0_m1_buf; + assign a1_inv[2] = a1_inv_buf[1] ^ mul_m0_b_inv_buf; + assign a1_inv[3] = a1_inv_buf[2] ^ mul_m0_m1_buf; + assign a0_inv[0] = s0 ^ mul_a1_b2_inv_buf; // s0 doesn't depend on a1, b2_inv. + assign a0_inv[1] = a0_inv_buf[0] ^ mul_a1_m0_buf; + assign a0_inv[2] = a0_inv_buf[1] ^ mul_m1_b2_inv_buf; + assign a0_inv[3] = a0_inv_buf[2] ^ mul_m0_m1_buf; + + // Avoid aggressive synthesis optimizations. + for (genvar i = 0; i < 4; i++) begin : gen_a01_inv_buf + caliptra_prim_buf #( + .Width ( 4 ) + ) u_caliptra_prim_buf_a1_inv_i ( + .in_i ( a1_inv[i] ), + .out_o ( a1_inv_buf[i] ) + ); + caliptra_prim_buf #( + .Width ( 4 ) + ) u_caliptra_prim_buf_a0_inv_i ( + .in_i ( a0_inv[i] ), + .out_o ( a0_inv_buf[i] ) + ); + end + + // Note: a_inv is masked by s (= n), a was masked by m. + assign a_inv = {a1_inv_buf[3], a0_inv_buf[3]}; + +endmodule + +// SEC_CM: KEY.MASKING +module aes_sbox_canright_masked ( + input aes_pkg::ciph_op_e op_i, + input logic [7:0] data_i, // masked, the actual input data is data_i ^ mask_i + input logic [7:0] mask_i, // input mask, independent from actual input data + input logic [7:0] prd_i, // pseudo-random data for remasking, independent of input mask + output logic [7:0] data_o, // masked, the actual output data is data_o ^ mask_o + output logic [7:0] mask_o // output mask +); + + import aes_pkg::*; + import aes_sbox_canright_pkg::*; + + ////////////////////////// + // Masked Canright SBox // + ////////////////////////// + + logic [7:0] in_data_basis_x, out_data_basis_x; + logic [7:0] in_mask_basis_x, out_mask_basis_x; + + // Convert data to normal basis X. + assign in_data_basis_x = (op_i == CIPH_FWD) ? aes_mvm(data_i, A2X) : + (op_i == CIPH_INV) ? aes_mvm(data_i ^ 8'h63, S2X) : + aes_mvm(data_i, A2X); + + // For the masked Canright SBox, the output mask directly corresponds to the pseduo-random data + // provided as input. + assign mask_o = prd_i; + + // Convert masks to normal basis X. + // The addition of constant 8'h63 following the affine transformation is skipped. + assign in_mask_basis_x = (op_i == CIPH_FWD) ? aes_mvm(mask_i, A2X) : + (op_i == CIPH_INV) ? aes_mvm(mask_i, S2X) : + aes_mvm(mask_i, A2X); + + // The output mask is converted in the opposite direction. + assign out_mask_basis_x = (op_i == CIPH_INV) ? aes_mvm(mask_o, A2X) : + (op_i == CIPH_FWD) ? aes_mvm(mask_o, S2X) : + aes_mvm(mask_o, S2X); + + // Do the inversion in normal basis X. + aes_masked_inverse_gf2p8 u_aes_masked_inverse_gf2p8 ( + .a ( in_data_basis_x ), // input + .m ( in_mask_basis_x ), // input + .n ( out_mask_basis_x ), // input + .a_inv ( out_data_basis_x ) // output + ); + + // Convert to basis S or A. + assign data_o = (op_i == CIPH_FWD) ? (aes_mvm(out_data_basis_x, X2S) ^ 8'h63) : + (op_i == CIPH_INV) ? (aes_mvm(out_data_basis_x, X2A)) : + (aes_mvm(out_data_basis_x, X2S) ^ 8'h63); + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/aes_sbox_canright_masked_noreuse.sv b/designs/Caliptra/src/caliptra-rtl/aes_sbox_canright_masked_noreuse.sv new file mode 100644 index 0000000..ba8184c --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/aes_sbox_canright_masked_noreuse.sv @@ -0,0 +1,450 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// AES Masked Canright SBox without Mask Re-Use +// +// For details, see the following paper: +// Canright, "A very compact 'perfectly masked' S-box for AES (corrected)" +// available at https://eprint.iacr.org/2009/011.pdf +// +// Note: This module implements the original masked inversion algorithm without re-using masks. +// For details, see Section 2.2 of the paper. In addition, a formal analysis using REBECCA (stable +// mode) shows that the intermediate masks cannot be created by re-using bits from the input and +// output masks. Instead, fresh random bits need to be used for these intermediate masks. Still, +// the implmentation cannot be made to pass formal analysis in transient mode. It's usage is thus +// discouraged. It's included here mainly for reference. +// +// For details on the REBECCA tool, see the following paper: +// Bloem, "Formal verification of masked hardware implementations in the presence of glitches" +// available at https://eprint.iacr.org/2017/897.pdf + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// IMPORTANT NOTE: // +// DO NOT USE THIS FOR SYNTHESIS BLINDLY! // +// // +// This implementation relies on primitive cells like caliptra_prim_buf containing tool-specific // +// synthesis attributes to enforce the correct ordering of operations and avoid aggressive // +// optimization. Without the proper primitives, synthesis tools might heavily optimize the // +// design. The result is likely insecure. Use with care. // +/////////////////////////////////////////////////////////////////////////////////////////////////// + +// Masked inverse in GF(2^4), using normal basis [z^4, z] +// (see Formulas 6, 13, 14, 15, 16, 17 in the paper) +module aes_masked_inverse_gf2p4_noreuse ( + input logic [3:0] b, + input logic [3:0] q, + input logic [1:0] r, + input logic [3:0] t, + output logic [3:0] b_inv +); + + import aes_pkg::*; + import aes_sbox_canright_pkg::*; + + logic [1:0] b1, b0, q1, q0, c_inv, r_sq, t1, t0; + assign b1 = b[3:2]; + assign b0 = b[1:0]; + assign q1 = q[3:2]; + assign q0 = q[1:0]; + assign t1 = t[3:2]; + assign t0 = t[1:0]; + + //////////////// + // Formula 13 // + //////////////// + // IMPORTANT: The following ops must be executed in order (left to right): + // c = r ^ aes_scale_omega2_gf2p2(aes_square_gf2p2(b1 ^ b0)) + // ^ aes_scale_omega2_gf2p2(aes_square_gf2p2(q1 ^ q0)) + // ^ aes_mul_gf2p2(b1, b0) + // ^ aes_mul_gf2p2(b1, q0) ^ aes_mul_gf2p2(b0, q1) ^ aes_mul_gf2p2(q1, q0); + + // Get intermediate terms. + logic [1:0] scale_omega2_b, scale_omega2_q; + logic [1:0] mul_b1_b0, mul_b1_q0, mul_b0_q1, mul_q1_q0; + assign scale_omega2_b = aes_scale_omega2_gf2p2(aes_square_gf2p2(b1 ^ b0)); + assign scale_omega2_q = aes_scale_omega2_gf2p2(aes_square_gf2p2(q1 ^ q0)); + assign mul_b1_b0 = aes_mul_gf2p2(b1, b0); + assign mul_b1_q0 = aes_mul_gf2p2(b1, q0); + assign mul_b0_q1 = aes_mul_gf2p2(b0, q1); + assign mul_q1_q0 = aes_mul_gf2p2(q1, q0); + + // These terms are added to other terms that depend on the same inputs. + // Avoid aggressive synthesis optimizations. + logic [1:0] scale_omega2_b_buf, scale_omega2_q_buf; + caliptra_prim_buf #( + .Width ( 4 ) + ) u_caliptra_prim_buf_scale_omega2_bq ( + .in_i ( {scale_omega2_b, scale_omega2_q} ), + .out_o ( {scale_omega2_b_buf, scale_omega2_q_buf} ) + ); + logic [1:0] mul_b1_b0_buf, mul_b1_q0_buf, mul_b0_q1_buf, mul_q1_q0_buf; + caliptra_prim_buf #( + .Width ( 8 ) + ) u_caliptra_prim_buf_mul_bq01 ( + .in_i ( {mul_b1_b0, mul_b1_q0, mul_b0_q1, mul_q1_q0} ), + .out_o ( {mul_b1_b0_buf, mul_b1_q0_buf, mul_b0_q1_buf, mul_q1_q0_buf} ) + ); + + // Generate c step by step. + logic [1:0] c [6]; + logic [1:0] c_buf [6]; + assign c[0] = r ^ scale_omega2_b_buf; + assign c[1] = c_buf[0] ^ scale_omega2_q_buf; + assign c[2] = c_buf[1] ^ mul_b1_b0_buf; + assign c[3] = c_buf[2] ^ mul_b1_q0_buf; + assign c[4] = c_buf[3] ^ mul_b0_q1_buf; + assign c[5] = c_buf[4] ^ mul_q1_q0_buf; + + // Avoid aggressive synthesis optimizations. + for (genvar i = 0; i < 6; i++) begin : gen_c_buf + caliptra_prim_buf #( + .Width ( 2 ) + ) u_caliptra_prim_buf_c_i ( + .in_i ( c[i] ), + .out_o ( c_buf[i] ) + ); + end + + //////////////////////// + // Formulas 14 and 15 // + //////////////////////// + // Note: aes_square_gf2p2 contains no logic, it's just a bit swap. There is no need to insert + // additional buffers to stop aggressive synthesis optimizations here. + assign c_inv = aes_square_gf2p2(c_buf[5]); + assign r_sq = aes_square_gf2p2(r); + + //////////////////////// + // Formulas 16 and 17 // + //////////////////////// + // IMPORTANT: The following ops must be executed in order (left to right): + // b1_inv = t1 ^ aes_mul_gf2p2(b0, c_inv) + // ^ aes_mul_gf2p2(b0, r_sq) ^ aes_mul_gf2p2(q0, c_inv) ^ aes_mul_gf2p2(q0, r_sq); + // b0_inv = t0 ^ aes_mul_gf2p2(b1, c_inv) + // ^ aes_mul_gf2p2(b1, r_sq) ^ aes_mul_gf2p2(q1, c_inv) ^ aes_mul_gf2p2(q1, r_sq); + + // Get intermediate terms. + logic [1:0] mul_b0_r_sq, mul_q0_c_inv, mul_q0_r_sq; + logic [1:0] mul_b1_r_sq, mul_q1_c_inv, mul_q1_r_sq; + assign mul_b0_r_sq = aes_mul_gf2p2(b0, r_sq); + assign mul_q0_c_inv = aes_mul_gf2p2(q0, c_inv); + assign mul_q0_r_sq = aes_mul_gf2p2(q0, r_sq); + assign mul_b1_r_sq = aes_mul_gf2p2(b1, r_sq); + assign mul_q1_c_inv = aes_mul_gf2p2(q1, c_inv); + assign mul_q1_r_sq = aes_mul_gf2p2(q1, r_sq); + + // The multiplier outputs are added to terms that depend on the same inputs. + // Avoid aggressive synthesis optimizations. + logic [1:0] mul_b0_r_sq_buf, mul_q0_c_inv_buf, mul_q0_r_sq_buf; + caliptra_prim_buf #( + .Width ( 6 ) + ) u_caliptra_prim_buf_mul_bq0 ( + .in_i ( {mul_b0_r_sq, mul_q0_c_inv, mul_q0_r_sq} ), + .out_o ( {mul_b0_r_sq_buf, mul_q0_c_inv_buf, mul_q0_r_sq_buf} ) + ); + logic [1:0] mul_b1_r_sq_buf, mul_q1_c_inv_buf, mul_q1_r_sq_buf; + caliptra_prim_buf #( + .Width ( 6 ) + ) u_caliptra_prim_buf_mul_bq1 ( + .in_i ( {mul_b1_r_sq, mul_q1_c_inv, mul_q1_r_sq} ), + .out_o ( {mul_b1_r_sq_buf, mul_q1_c_inv_buf, mul_q1_r_sq_buf} ) + ); + + // Generate b1_inv and b0_inv step by step. + logic [1:0] b1_inv [4]; + logic [1:0] b1_inv_buf [4]; + logic [1:0] b0_inv [4]; + logic [1:0] b0_inv_buf [4]; + assign b1_inv[0] = t1 ^ aes_mul_gf2p2(b0, c_inv); // t1 does not depend on b0, c_inv. + assign b1_inv[1] = b1_inv_buf[0] ^ mul_b0_r_sq_buf; + assign b1_inv[2] = b1_inv_buf[1] ^ mul_q0_c_inv_buf; + assign b1_inv[3] = b1_inv_buf[2] ^ mul_q0_r_sq_buf; + assign b0_inv[0] = t0 ^ aes_mul_gf2p2(b1, c_inv); // t0 does not depend on b1, c_inv. + assign b0_inv[1] = b0_inv_buf[0] ^ mul_b1_r_sq_buf; + assign b0_inv[2] = b0_inv_buf[1] ^ mul_q1_c_inv_buf; + assign b0_inv[3] = b0_inv_buf[2] ^ mul_q1_r_sq_buf; + + // Avoid aggressive synthesis optimizations. + for (genvar i = 0; i < 4; i++) begin : gen_a01_inv_buf + caliptra_prim_buf #( + .Width ( 2 ) + ) u_caliptra_prim_buf_b1_inv_i ( + .in_i ( b1_inv[i] ), + .out_o ( b1_inv_buf[i] ) + ); + caliptra_prim_buf #( + .Width ( 2 ) + ) u_caliptra_prim_buf_b0_inv_i ( + .in_i ( b0_inv[i] ), + .out_o ( b0_inv_buf[i] ) + ); + end + + // Note: b_inv is masked by t, b was masked by q. + assign b_inv = {b1_inv_buf[3], b0_inv_buf[3]}; + +endmodule + +// Masked inverse in GF(2^8), using normal basis [y^16, y] +// (see Formulas 3, 12, 18 and 19 in the paper) +module aes_masked_inverse_gf2p8_noreuse ( + input logic [7:0] a, // input data masked by m + input logic [7:0] m, // input mask + input logic [7:0] n, // output mask + input logic [9:0] prd, // pseudo-random data, e.g. for intermediate masks + output logic [7:0] a_inv // output data masked by n +); + + import aes_pkg::*; + import aes_sbox_canright_pkg::*; + + logic [3:0] a1, a0, m1, m0, q, b_inv, s1, s0, t; + logic [1:0] r; + + assign a1 = a[7:4]; + assign a0 = a[3:0]; + assign m1 = m[7:4]; + assign m0 = m[3:0]; + + //////////////////// + // Notes on masks // + //////////////////// + // The paper states the following. + // r: + // - must be independent of q, + // - it is suggested to re-use bits of m, + // - but further analysis shows that this is not sufficient (see below). + // + // q: + // - must be independent of m. + // + // t: + // - must be independent of r, + // - must be independent of m (for the final steps involving s), + // - t1 must be independent of q0, t0 must be independent of q1, + // - it is suggested to use t = q, + // - but further analysis shows that this is not sufficient (see below). + // + // s: + // - must be independent of t, + // - s1 must be independent of m0, s0 must be independent of m1, + // - it is suggested to use s = m, + // - but further analysis shows that this is not sufficient (see below). + // + // Formally analyzing the implementation with REBECCA reveals that: + // 1. Fresh random bits are required for r, q and t. Any re-use of other mask bits from m or n + // causes the static check to fail. + // 2. s can be the specified output mask n. + assign r = prd[1:0]; + assign q = prd[5:2]; + assign t = prd[9:6]; + assign s1 = n[7:4]; + assign s0 = n[3:0]; + + //////////////// + // Formula 12 // + //////////////// + // IMPORTANT: The following ops must be executed in order (left to right): + // b = q ^ aes_square_scale_gf2p4_gf2p2(a1 ^ a0) + // ^ aes_square_scale_gf2p4_gf2p2(m1 ^ m0) + // ^ aes_mul_gf2p4(a1, a0) + // ^ aes_mul_gf2p4(a1, m0) ^ aes_mul_gf2p4(a0, m1) ^ aes_mul_gf2p4(m0, m1); + + // Get intermediate terms. + logic [3:0] ss_a1_a0, ss_m1_m0; + assign ss_a1_a0 = aes_square_scale_gf2p4_gf2p2(a1 ^ a0); + assign ss_m1_m0 = aes_square_scale_gf2p4_gf2p2(m1 ^ m0); + + logic [3:0] mul_a1_a0, mul_a1_m0, mul_a0_m1, mul_m0_m1; + assign mul_a1_a0 = aes_mul_gf2p4(a1, a0); + assign mul_a1_m0 = aes_mul_gf2p4(a1, m0); + assign mul_a0_m1 = aes_mul_gf2p4(a0, m1); + assign mul_m0_m1 = aes_mul_gf2p4(m0, m1); + + // The multiplier outputs are added to terms that depend on the same inputs. + // Avoid aggressive synthesis optimizations. + logic [3:0] mul_a1_a0_buf, mul_a1_m0_buf, mul_a0_m1_buf, mul_m0_m1_buf; + caliptra_prim_buf #( + .Width ( 16 ) + ) u_caliptra_prim_buf_mul_am01 ( + .in_i ( {mul_a1_a0, mul_a1_m0, mul_a0_m1, mul_m0_m1} ), + .out_o ( {mul_a1_a0_buf, mul_a1_m0_buf, mul_a0_m1_buf, mul_m0_m1_buf} ) + ); + + // Generate b step by step. + logic [3:0] b [6]; + logic [3:0] b_buf [6]; + assign b[0] = q ^ ss_a1_a0; // q does not depend on a1, a0. + assign b[1] = b_buf[0] ^ ss_m1_m0; // b[0] does not depend on m1, m0. + assign b[2] = b_buf[1] ^ mul_a1_a0_buf; + assign b[3] = b_buf[2] ^ mul_a1_m0_buf; + assign b[4] = b_buf[3] ^ mul_a0_m1_buf; + assign b[5] = b_buf[4] ^ mul_m0_m1_buf; + + // Avoid aggressive synthesis optimizations. + for (genvar i = 0; i < 6; i++) begin : gen_b_buf + caliptra_prim_buf #( + .Width ( 4 ) + ) u_caliptra_prim_buf_b_i ( + .in_i ( b[i] ), + .out_o ( b_buf[i] ) + ); + end + + ////////////////////// + // GF(2^4) Inverter // + ////////////////////// + + // b is masked by q, b_inv is masked by t. + aes_masked_inverse_gf2p4_noreuse u_aes_masked_inverse_gf2p4 ( + .b ( b_buf[5] ), + .q ( q ), + .r ( r ), + .t ( t ), + .b_inv ( b_inv ) + ); + + // The output of the inverse over GF(2^4) and signals derived from that are again recombined + // with inputs to the GF(2^4) inverter. Aggressive synthesis optimizations across the GF(2^4) + // inverter may result in SCA leakage and should be avoided. + logic [3:0] b_inv_buf; + caliptra_prim_buf #( + .Width ( 4 ) + ) u_caliptra_prim_buf_b_inv ( + .in_i ( b_inv ), + .out_o ( b_inv_buf ) + ); + + //////////////////////// + // Formulas 18 and 19 // + //////////////////////// + // IMPORTANT: The following ops must be executed in order (left to right): + // a1_inv = s1 ^ aes_mul_gf2p4(a0, b_inv) + // ^ aes_mul_gf2p4(a0, t) ^ aes_mul_gf2p4(m0, b_inv) ^ aes_mul_gf2p4(m0, t); + // a0_inv = s0 ^ aes_mul_gf2p4(a1, b_inv) + // ^ aes_mul_gf2p4(a1, t) ^ aes_mul_gf2p4(m1, b_inv) ^ aes_mul_gf2p4(m1, t); + + // Get intermediate terms. + logic [3:0] mul_a0_b_inv, mul_a0_t, mul_m0_b_inv, mul_m0_t; + logic [3:0] mul_a1_b_inv, mul_a1_t, mul_m1_b_inv, mul_m1_t; + assign mul_a0_b_inv = aes_mul_gf2p4(a0, b_inv_buf); + assign mul_a0_t = aes_mul_gf2p4(a0, t); + assign mul_m0_b_inv = aes_mul_gf2p4(m0, b_inv_buf); + assign mul_m0_t = aes_mul_gf2p4(m0, t); + assign mul_a1_b_inv = aes_mul_gf2p4(a1, b_inv_buf); + assign mul_a1_t = aes_mul_gf2p4(a1, t); + assign mul_m1_b_inv = aes_mul_gf2p4(m1, b_inv_buf); + assign mul_m1_t = aes_mul_gf2p4(m1, t); + + // The multiplier outputs are added to terms that depend on the same inputs. + // Avoid aggressive synthesis optimizations. + logic [3:0] mul_a0_b_inv_buf, mul_a0_t_buf, mul_m0_b_inv_buf, mul_m0_t_buf; + caliptra_prim_buf #( + .Width ( 16 ) + ) u_caliptra_prim_buf_mul_am0 ( + .in_i ( {mul_a0_b_inv, mul_a0_t, mul_m0_b_inv, mul_m0_t} ), + .out_o ( {mul_a0_b_inv_buf, mul_a0_t_buf, mul_m0_b_inv_buf, mul_m0_t_buf} ) + ); + logic [3:0] mul_a1_b_inv_buf, mul_a1_t_buf, mul_m1_b_inv_buf, mul_m1_t_buf; + caliptra_prim_buf #( + .Width ( 16 ) + ) u_caliptra_prim_buf_mul_am1 ( + .in_i ( {mul_a1_b_inv, mul_a1_t, mul_m1_b_inv, mul_m1_t} ), + .out_o ( {mul_a1_b_inv_buf, mul_a1_t_buf, mul_m1_b_inv_buf, mul_m1_t_buf} ) + ); + + // Generate a1_inv and a0_inv step by step. + logic [3:0] a1_inv [4]; + logic [3:0] a1_inv_buf [4]; + logic [3:0] a0_inv [4]; + logic [3:0] a0_inv_buf [4]; + assign a1_inv[0] = s1 ^ mul_a0_b_inv_buf; + assign a1_inv[1] = a1_inv_buf[0] ^ mul_a0_t_buf; + assign a1_inv[2] = a1_inv_buf[1] ^ mul_m0_b_inv_buf; + assign a1_inv[3] = a1_inv_buf[2] ^ mul_m0_t_buf; + assign a0_inv[0] = s0 ^ mul_a1_b_inv_buf; + assign a0_inv[1] = a0_inv_buf[0] ^ mul_a1_t_buf; + assign a0_inv[2] = a0_inv_buf[1] ^ mul_m1_b_inv_buf; + assign a0_inv[3] = a0_inv_buf[2] ^ mul_m1_t_buf; + + // Avoid aggressive synthesis optimizations. + for (genvar i = 0; i < 4; i++) begin : gen_a01_inv_buf + caliptra_prim_buf #( + .Width ( 4 ) + ) u_caliptra_prim_buf_a1_inv_i ( + .in_i ( a1_inv[i] ), + .out_o ( a1_inv_buf[i] ) + ); + caliptra_prim_buf #( + .Width ( 4 ) + ) u_caliptra_prim_buf_a0_inv_i ( + .in_i ( a0_inv[i] ), + .out_o ( a0_inv_buf[i] ) + ); + end + + // Note: a_inv is masked by s (= n), a was masked by m. + assign a_inv = {a1_inv_buf[3], a0_inv_buf[3]}; + +endmodule + +// SEC_CM: KEY.MASKING +module aes_sbox_canright_masked_noreuse ( + input aes_pkg::ciph_op_e op_i, + input logic [7:0] data_i, // masked, the actual input data is data_i ^ mask_i + input logic [7:0] mask_i, // input mask, independent from actual input data + input logic [17:0] prd_i, // pseudo-random data, for remasking and for intermediate + // masks, must be independent of input mask + output logic [7:0] data_o, // masked, the actual output data is data_o ^ mask_o + output logic [7:0] mask_o // output mask +); + + import aes_pkg::*; + import aes_sbox_canright_pkg::*; + + ////////////////////////// + // Masked Canright SBox // + ////////////////////////// + + logic [7:0] in_data_basis_x, out_data_basis_x; + logic [7:0] in_mask_basis_x, out_mask_basis_x; + + // Convert data to normal basis X. + assign in_data_basis_x = (op_i == CIPH_FWD) ? aes_mvm(data_i, A2X) : + (op_i == CIPH_INV) ? aes_mvm(data_i ^ 8'h63, S2X) : + aes_mvm(data_i, A2X); + + // For the masked Canright SBox with no re-use, the output mask directly corresponds to the + // LSBs of the pseduo-random data provided as input. + assign mask_o = prd_i[7:0]; + + // The remaining bits are used for intermediate masks. + logic [9:0] prd_masking; + assign prd_masking = prd_i[17:8]; + + // Convert masks to normal basis X. + // The addition of constant 8'h63 following the affine transformation is skipped. + assign in_mask_basis_x = (op_i == CIPH_FWD) ? aes_mvm(mask_i, A2X) : + (op_i == CIPH_INV) ? aes_mvm(mask_i, S2X) : + aes_mvm(mask_i, A2X); + + // The output mask is converted in the opposite direction. + assign out_mask_basis_x = (op_i == CIPH_INV) ? aes_mvm(mask_o, A2X) : + (op_i == CIPH_FWD) ? aes_mvm(mask_o, S2X) : + aes_mvm(mask_o, S2X); + + // Do the inversion in normal basis X. + aes_masked_inverse_gf2p8_noreuse u_aes_masked_inverse_gf2p8 ( + .a ( in_data_basis_x ), // input + .m ( in_mask_basis_x ), // input + .n ( out_mask_basis_x ), // input + .prd ( prd_masking ), // input + .a_inv ( out_data_basis_x ) // output + ); + + // Convert to basis S or A. + assign data_o = (op_i == CIPH_FWD) ? (aes_mvm(out_data_basis_x, X2S) ^ 8'h63) : + (op_i == CIPH_INV) ? (aes_mvm(out_data_basis_x, X2A)) : + (aes_mvm(out_data_basis_x, X2S) ^ 8'h63); + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/aes_sbox_canright_pkg.sv b/designs/Caliptra/src/caliptra-rtl/aes_sbox_canright_pkg.sv new file mode 100644 index 0000000..d520fc9 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/aes_sbox_canright_pkg.sv @@ -0,0 +1,92 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// AES Canright SBox package +// +// For details, see the following documents: +// - Canright, "A very compact Rijndael S-box", technical report +// available at https://hdl.handle.net/10945/25608 +// - Canright, "A very compact 'perfectly masked' S-box for AES (corrected)", paper +// available at https://eprint.iacr.org/2009/011.pdf + +package aes_sbox_canright_pkg; + + // Multiplication in GF(2^2), using normal basis [Omega^2, Omega] + // (see Figure 14 in the technical report) + function automatic logic [1:0] aes_mul_gf2p2(logic [1:0] g, logic [1:0] d); + logic [1:0] f; + logic a, b, c; + a = g[1] & d[1]; + b = (^g) & (^d); + c = g[0] & d[0]; + f[1] = a ^ b; + f[0] = c ^ b; + return f; + endfunction + + // Scale by Omega^2 = N in GF(2^2), using normal basis [Omega^2, Omega] + // (see Figure 16 in the technical report) + function automatic logic [1:0] aes_scale_omega2_gf2p2(logic [1:0] g); + logic [1:0] d; + d[1] = g[0]; + d[0] = g[1] ^ g[0]; + return d; + endfunction + + // Scale by Omega = N^2 in GF(2^2), using normal basis [Omega^2, Omega] + // (see Figure 15 in the technical report) + function automatic logic [1:0] aes_scale_omega_gf2p2(logic [1:0] g); + logic [1:0] d; + d[1] = g[1] ^ g[0]; + d[0] = g[1]; + return d; + endfunction + + // Square in GF(2^2), using normal basis [Omega^2, Omega] + // (see Figures 8 and 10 in the technical report) + function automatic logic [1:0] aes_square_gf2p2(logic [1:0] g); + logic [1:0] d; + d[1] = g[0]; + d[0] = g[1]; + return d; + endfunction + + // Multiplication in GF(2^4), using normal basis [alpha^8, alpha^2] + // (see Figure 13 in the technical report) + function automatic logic [3:0] aes_mul_gf2p4(logic [3:0] gamma, logic [3:0] delta); + logic [3:0] theta; + logic [1:0] a, b, c; + a = aes_mul_gf2p2(gamma[3:2], delta[3:2]); + b = aes_mul_gf2p2(gamma[3:2] ^ gamma[1:0], delta[3:2] ^ delta[1:0]); + c = aes_mul_gf2p2(gamma[1:0], delta[1:0]); + theta[3:2] = a ^ aes_scale_omega2_gf2p2(b); + theta[1:0] = c ^ aes_scale_omega2_gf2p2(b); + return theta; + endfunction + + // Square and scale by nu in GF(2^4)/GF(2^2), using normal basis [alpha^8, alpha^2] + // (see Figure 19 as well as Appendix A of the technical report) + function automatic logic [3:0] aes_square_scale_gf2p4_gf2p2(logic [3:0] gamma); + logic [3:0] delta; + logic [1:0] a, b; + a = gamma[3:2] ^ gamma[1:0]; + b = aes_square_gf2p2(gamma[1:0]); + delta[3:2] = aes_square_gf2p2(a); + delta[1:0] = aes_scale_omega_gf2p2(b); + return delta; + endfunction + + // Basis conversion matrices to convert between polynomial basis A, normal basis X + // and basis S incorporating the bit matrix of the SBox. More specifically, + // multiplication by X2X performs the transformation from normal basis X into + // polynomial basis A, followed by the affine transformation (substep 2). Likewise, + // multiplication by S2X performs the inverse affine transformation followed by the + // transformation from polynomial basis A to normal basis X. + // (see Appendix A of the technical report) + parameter logic [7:0] A2X [8] = '{8'h98, 8'hf3, 8'hf2, 8'h48, 8'h09, 8'h81, 8'ha9, 8'hff}; + parameter logic [7:0] X2A [8] = '{8'h64, 8'h78, 8'h6e, 8'h8c, 8'h68, 8'h29, 8'hde, 8'h60}; + parameter logic [7:0] X2S [8] = '{8'h58, 8'h2d, 8'h9e, 8'h0b, 8'hdc, 8'h04, 8'h03, 8'h24}; + parameter logic [7:0] S2X [8] = '{8'h8c, 8'h79, 8'h05, 8'heb, 8'h12, 8'h04, 8'h51, 8'h53}; + +endpackage diff --git a/designs/Caliptra/src/caliptra-rtl/aes_sbox_dom.sv b/designs/Caliptra/src/caliptra-rtl/aes_sbox_dom.sv new file mode 100644 index 0000000..973d8b0 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/aes_sbox_dom.sv @@ -0,0 +1,1077 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// AES S-Box with First-Order Domain-Oriented Masking +// +// This is the unpipelined version using DOM-dep multipliers. It has a latency of 5 clock cycles +// and requires 28 bits of pseudo-random data per evaluation. Pipelining would only be beneficial +// when using +// - either a cipher core architecture with a data path smaller than 128 bit, i.e., where the +// individual S-Boxes are evaluated more than once per round, or +// - a fully unrolled cipher core architecture for maximum throughput. +// +// Note: The DOM AES S-Box is built on top of the Canright masked S-Box without mask re-use. +// +// For details, see the following papers and reports: +// [1] Gross, "Domain-Oriented Masking: Compact Masked Hardware Implementations with Arbitrary +// Protection Order" available at https://eprint.iacr.org/2016/486.pdf +// [2] Canright, "A very compact 'perfectly masked' S-box for AES (corrected)" available at +// https://eprint.iacr.org/2009/011.pdf +// [3] Canright, "A very compact Rijndael S-box" available at https://hdl.handle.net/10945/25608 +// +// Using the Coco-Alma tool in transient mode, this implementation has been formally verified to be +// secure against first-order side-channel analysis (SCA). For more information on the tool, +// refer to the following papers: +// [4] Gigerl, "COCO: Co-design and co-verification of masked software implementations on CPUs" +// available at https://eprint.iacr.org/2020/1294.pdf +// [5] Bloem, "Formal verification of masked hardware implementations in the presence of glitches" +// available at https://eprint.iacr.org/2017/897.pdf + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// IMPORTANT NOTE: // +// DO NOT USE THIS FOR SYNTHESIS BLINDLY! // +// // +// This implementation relies on primitive cells like caliptra_prim_buf/flop_en containing tool-specific // +// synthesis attributes to prevent the synthesis tool from optimizing away/re-ordering registers // +// and to enforce the correct ordering of operations. Without the proper primitives, synthesis // +// tools might heavily optimize the design. The result is likely insecure. Use with care. // +/////////////////////////////////////////////////////////////////////////////////////////////////// + +`include "caliptra_prim_assert.sv" + +// Packed struct for pseudo-random data (PRD) input. Stages 1, 3 and 4 require 8 bits each. Stage 2 +// requires just 4 bits. +typedef struct packed { + logic [7:0] prd_1; + logic [3:0] prd_2; + logic [7:0] prd_3; + logic [7:0] prd_4; +} aes_sbox_dom_prd_in_t; + +// Packed struct for pseudo-random data (PRD) output. Stages 2 and 3 produce 8 bits each. Stage 1 +// produces just 4 bits. +typedef struct packed { + logic [3:0] prd_1; + logic [7:0] prd_2; + logic [7:0] prd_3; +} aes_sbox_dom_prd_out_t; + +// DOM-indep GF(2^N) multiplier, first-order masked. +// Computes (a_q ^ b_q) = (a_x ^ b_x) * (a_y ^ b_y), i.e. q = x * y using first-order +// domain-oriented masking. The sharings of x and y are required to be uniformly random and +// independent from each other. +// See Fig. 2 in [1]. +module aes_dom_indep_mul_gf2pn #( + parameter int unsigned NPower = 4, + parameter bit Pipeline = 1'b0 +) ( + input logic clk_i, + input logic rst_ni, + input logic we_i, + input logic [NPower-1:0] a_x, // Share a of x + input logic [NPower-1:0] a_y, // Share a of y + input logic [NPower-1:0] b_x, // Share b of x + input logic [NPower-1:0] b_y, // Share b of y + input logic [NPower-1:0] z_0, // Randomness for resharing + output logic [NPower-1:0] a_q, // Share a of q + output logic [NPower-1:0] b_q // Share b of q +); + + import aes_sbox_canright_pkg::*; + + ///////////////// + // Calculation // + ///////////////// + // Inner-domain terms + logic [NPower-1:0] mul_ax_ay_d, mul_bx_by_d; + if (NPower == 4) begin : gen_inner_mul_gf2p4 + assign mul_ax_ay_d = aes_mul_gf2p4(a_x, a_y); + assign mul_bx_by_d = aes_mul_gf2p4(b_x, b_y); + + end else begin : gen_inner_mul_gf2p2 + assign mul_ax_ay_d = aes_mul_gf2p2(a_x, a_y); + assign mul_bx_by_d = aes_mul_gf2p2(b_x, b_y); + end + + // Cross-domain terms + logic [NPower-1:0] mul_ax_by, mul_ay_bx; + if (NPower == 4) begin : gen_cross_mul_gf2p4 + assign mul_ax_by = aes_mul_gf2p4(a_x, b_y); + assign mul_ay_bx = aes_mul_gf2p4(a_y, b_x); + + end else begin : gen_cross_mul_gf2p2 + assign mul_ax_by = aes_mul_gf2p2(a_x, b_y); + assign mul_ay_bx = aes_mul_gf2p2(a_y, b_x); + end + + /////////////// + // Resharing // + /////////////// + // Resharing of cross-domain terms + logic [NPower-1:0] aq_z0_d, bq_z0_d; + logic [NPower-1:0] aq_z0_q, bq_z0_q; + assign aq_z0_d = z_0 ^ mul_ax_by; + assign bq_z0_d = z_0 ^ mul_ay_bx; + + // Registers + caliptra_prim_flop_en #( + .Width ( 2*NPower ), + .ResetValue ( '0 ) + ) u_caliptra_prim_flop_abq_z0 ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .en_i ( we_i ), + .d_i ( {aq_z0_d, bq_z0_d} ), + .q_o ( {aq_z0_q, bq_z0_q} ) + ); + + ///////////////////////// + // Optional Pipelining // + ///////////////////////// + logic [NPower-1:0] mul_ax_ay, mul_bx_by; + + if (Pipeline == 1'b1) begin : gen_pipeline + // Add pipeline registers on inner-domain terms prior to integration. This allows accepting new + // input data every clock cycle and prevents SCA leakage occurring due to the integration of + // reshared cross-domain terms with inner-domain terms derived from different input data. + + logic [NPower-1:0] mul_ax_ay_q, mul_bx_by_q; + caliptra_prim_flop_en #( + .Width ( 2*NPower ), + .ResetValue ( '0 ) + ) u_caliptra_prim_flop_mul_abx_aby ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .en_i ( we_i ), + .d_i ( {mul_ax_ay_d, mul_bx_by_d} ), + .q_o ( {mul_ax_ay_q, mul_bx_by_q} ) + ); + + assign mul_ax_ay = mul_ax_ay_q; + assign mul_bx_by = mul_bx_by_q; + + end else begin : gen_no_pipeline + // Do not add the optional pipeline registers on the inner-domain terms. This allows to save + // some area in case the multiplier does not need to accept new data in every cycle. However, + // this can cause SCA leakage as during the clock cycle in which new data arrives, the new + // inner-domain terms are integrated with the previous, reshared cross-domain terms. + + // Avoid aggressive synthesis optimizations. + logic [NPower-1:0] mul_ax_ay_buf, mul_bx_by_buf; + caliptra_prim_buf #( + .Width ( 2*NPower ) + ) u_caliptra_prim_buf_mul_abx_aby ( + .in_i ( {mul_ax_ay_d, mul_bx_by_d} ), + .out_o ( {mul_ax_ay_buf, mul_bx_by_buf} ) + ); + + assign mul_ax_ay = mul_ax_ay_buf; + assign mul_bx_by = mul_bx_by_buf; + end + + ///////////////// + // Integration // + ///////////////// + assign a_q = mul_ax_ay ^ aq_z0_q; + assign b_q = mul_bx_by ^ bq_z0_q; + + // Only GF(2^4) and GF(2^2) is supported. + `CALIPTRA_ASSERT_INIT(AesDomIndepMulPower, NPower == 4 || NPower == 2) + +endmodule + +// DOM-dep GF(2^N) multiplier, first-order masked. +// Computes (a_q ^ b_q) = (a_x ^ b_x) * (a_y ^ b_y), i.e. q = x * y using first-order +// domain-oriented masking. The sharings of x and y are NOT required to be independent from each +// other. This is the un-optimized version consuming 3 times N bits of randomness for blinding and +// resharing. It is not used in the design but we keep it for reference. +// See Fig. 4 and Formulas 8 - 11 in [1]. +module aes_dom_dep_mul_gf2pn_unopt #( + parameter int unsigned NPower = 4, + parameter bit Pipeline = 1'b0 +) ( + input logic clk_i, + input logic rst_ni, + input logic we_i, + input logic [NPower-1:0] a_x, // Share a of x + input logic [NPower-1:0] a_y, // Share a of y + input logic [NPower-1:0] b_x, // Share b of x + input logic [NPower-1:0] b_y, // Share b of y + input logic [NPower-1:0] a_z, // Randomness for blinding + input logic [NPower-1:0] b_z, // Randomness for blinding + input logic [NPower-1:0] z_0, // Randomness for resharing + output logic [NPower-1:0] a_q, // Share a of q + output logic [NPower-1:0] b_q // Share b of q +); + + import aes_sbox_canright_pkg::*; + + ////////////// + // Blinding // + ////////////// + // Blinding of y by z. + logic [NPower-1:0] a_yz_d, b_yz_d; + logic [NPower-1:0] a_yz_q, b_yz_q; + assign a_yz_d = a_y ^ a_z; + assign b_yz_d = b_y ^ b_z; + + // Registers + caliptra_prim_flop_en #( + .Width ( 2*NPower ), + .ResetValue ( '0 ) + ) u_caliptra_prim_flop_ab_yz ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .en_i ( we_i ), + .d_i ( {a_yz_d, b_yz_d} ), + .q_o ( {a_yz_q, b_yz_q} ) + ); + + //////////////// + // Correction // + //////////////// + logic [NPower-1:0] a_mul_x_z, b_mul_x_z; + aes_dom_indep_mul_gf2pn #( + .NPower ( NPower ), + .Pipeline ( Pipeline ) + ) u_aes_dom_indep_mul_gf2pn ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .we_i ( we_i ), + .a_x ( a_x ), // Share a of x + .a_y ( a_z ), // Share a of z + .b_x ( b_x ), // Share b of x + .b_y ( b_z ), // Share b of z + .z_0 ( z_0 ), // Randomness for resharing + .a_q ( a_mul_x_z ), // Share a of x * z + .b_q ( b_mul_x_z ) // Share b of x * z + ); + + ///////////////////////// + // Optional Pipelining // + ///////////////////////// + logic [NPower-1:0] a_x_calc, b_x_calc; + + if (Pipeline == 1'b1) begin : gen_pipeline + // Add pipeline registers for input x. This allows accepting new input data every clock cycle + // and prevents SCA leakage occurring due to the multiplication of input x with b belonging to + // different clock cycles. + + logic [NPower-1:0] a_x_q, b_x_q; + caliptra_prim_flop_en #( + .Width ( 2*NPower ), + .ResetValue ( '0 ) + ) u_caliptra_prim_flop_ab_x ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .en_i ( we_i ), + .d_i ( {a_x, b_x} ), + .q_o ( {a_x_q, b_x_q} ) + ); + + assign a_x_calc = a_x_q; + assign b_x_calc = b_x_q; + + end else begin : gen_no_pipeline + // Do not add the optional pipeline registers for input x. This allows to save some area in + // case the multiplier does not need to accept new data in every cycle. However, this can cause + // SCA leakage as during the clock cycle in which new data arrives, the new x input is + // multiplied with the previous b. + + assign a_x_calc = a_x; + assign b_x_calc = b_x; + end + + ///////////////// + // Calculation // + ///////////////// + // Combine shares of blinded y to obtain b. + logic [NPower-1:0] b; + assign b = a_yz_q ^ b_yz_q; + + logic [NPower-1:0] a_mul_ax_b, b_mul_bx_b; + if (NPower == 4) begin : gen_mul_gf2p4 + assign a_mul_ax_b = aes_mul_gf2p4(a_x_calc, b); + assign b_mul_bx_b = aes_mul_gf2p4(b_x_calc, b); + + end else begin : gen_mul_gf2p2 + assign a_mul_ax_b = aes_mul_gf2p2(a_x_calc, b); + assign b_mul_bx_b = aes_mul_gf2p2(b_x_calc, b); + end + + ///////////////// + // Integration // + ///////////////// + assign a_q = a_mul_x_z ^ a_mul_ax_b; + assign b_q = b_mul_x_z ^ b_mul_bx_b; + + // Only GF(2^4) and GF(2^2) is supported. + `CALIPTRA_ASSERT_INIT(AesDomDepMulUnoptPower, NPower == 4 || NPower == 2) + +endmodule + +// DOM-dep GF(2^N) multiplier, first-order masked. +// Computes (a_q ^ b_q) = (a_x ^ b_x) * (a_y ^ b_y), i.e. q = x * y using first-order +// domain-oriented masking. The sharings of x and y are NOT required to be independent from each +// other. This is the optimized version consuming 2 instead of 3 times N bits of randomness for +// blinding and resharing. +// See Formula 12 in [1]. +module aes_dom_dep_mul_gf2pn #( + parameter int unsigned NPower = 4, + parameter bit Pipeline = 1'b0, + parameter bit PreDomIndep = 1'b0 // 1'b0: Not followed by an un-pipelined DOM-indep + // multiplier, this enables additional area + // optimizations + // 1'b1: Directly followed by an un-pipelined + // DOM-indep multiplier, this is the version + // discussed in [1]. +) ( + input logic clk_i, + input logic rst_ni, + input logic we_i, + input logic [NPower-1:0] a_x, // Share a of x + input logic [NPower-1:0] a_y, // Share a of y + input logic [NPower-1:0] b_x, // Share b of x + input logic [NPower-1:0] b_y, // Share b of y + input logic [NPower-1:0] a_x_q, // Share a of x, pipelined (for Pipeline=1 or PreDomIndep=1) + input logic [NPower-1:0] a_y_q, // Share a of y, pipelined (for Pipeline=1) + input logic [NPower-1:0] b_x_q, // Share b of x, pipelined (for Pipeline=1 or PreDomIndep=1) + input logic [NPower-1:0] b_y_q, // Share b of y, pipelined (for Pipeline=1) + input logic [NPower-1:0] z_0, // Randomness for blinding + input logic [NPower-1:0] z_1, // Randomness for resharing + output logic [NPower-1:0] a_q, // Share a of q + output logic [NPower-1:0] b_q, // Share b of q + output logic [2*NPower-1:0] prd_o // Randomness for use in another S-Box instance +); + + import aes_sbox_canright_pkg::*; + + ////////////// + // Blinding // + ////////////// + // Blinding of y by z_0. + logic [NPower-1:0] a_yz0_d, b_yz0_d; + logic [NPower-1:0] a_yz0_q, b_yz0_q; + assign a_yz0_d = a_y ^ z_0; + assign b_yz0_d = b_y ^ z_0; + + // Registers + caliptra_prim_flop_en #( + .Width ( 2*NPower ), + .ResetValue ( '0 ) + ) u_caliptra_prim_flop_ab_yz0 ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .en_i ( we_i ), + .d_i ( {a_yz0_d, b_yz0_d} ), + .q_o ( {a_yz0_q, b_yz0_q} ) + ); + + //////////////// + // Correction // + //////////////// + // Basically, this a DOM-indep multiplier with: + // - a_x = a_x, b_x = b_x, and + // - a_y = z_0, b_y = 0 (constant), + // which allows for further optimizations. + + // Calculation + logic [NPower-1:0] mul_ax_z0, mul_bx_z0; + if (NPower == 4) begin : gen_corr_mul_gf2p4 + assign mul_ax_z0 = aes_mul_gf2p4(a_x, z_0); + assign mul_bx_z0 = aes_mul_gf2p4(b_x, z_0); + + end else begin : gen_corr_mul_gf2p2 + assign mul_ax_z0 = aes_mul_gf2p2(a_x, z_0); + assign mul_bx_z0 = aes_mul_gf2p2(b_x, z_0); + end + + // Avoid aggressive synthesis optimizations. + logic [NPower-1:0] mul_ax_z0_buf, mul_bx_z0_buf; + caliptra_prim_buf #( + .Width ( 2*NPower ) + ) u_caliptra_prim_buf_mul_abx_z0 ( + .in_i ( {mul_ax_z0, mul_bx_z0} ), + .out_o ( {mul_ax_z0_buf, mul_bx_z0_buf} ) + ); + + // Resharing + logic [NPower-1:0] axz0_z1_d, bxz0_z1_d; + logic [NPower-1:0] axz0_z1_q, bxz0_z1_q; + assign axz0_z1_d = mul_ax_z0_buf ^ z_1; + assign bxz0_z1_d = mul_bx_z0_buf ^ z_1; + + // Registers + caliptra_prim_flop_en #( + .Width ( 2*NPower ), + .ResetValue ( '0 ) + ) u_caliptra_prim_flop_abxz0_z1 ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .en_i ( we_i ), + .d_i ( {axz0_z1_d, bxz0_z1_d} ), + .q_o ( {axz0_z1_q, bxz0_z1_q} ) + ); + + // Use intermediate results for generating PRD for another S-Box instance. + // Use one share only. Directly use output of flops updating with we_i. + // These intermediate results are obtained by remasking b_y and mul_bx_z0 with z_0 and z_1, + // respectively. Since z_0/1 are uniformly distributed and independent of b_y and mul_bx_z0, + // the intermediate results are also uniformly distributed and independent of b_y and mul_bx_z0. + // For details, see Lemma 1 in [2]. + assign prd_o = {b_yz0_q, bxz0_z1_q}; + + ///////////////////////// + // Optional Pipelining // + ///////////////////////// + logic [NPower-1:0] a_x_calc, b_x_calc, a_y_calc, b_y_calc; + + if (Pipeline == 1'b1 && PreDomIndep != 1'b1) begin : gen_pipeline_use + // Use pipelined inputs x and y. This allows accepting new input data every clock cycle and + // prevents SCA leakage occurring due to the multiplication of inputs x and y with d_b + // belonging to different clock cycles. + // + // The PreDomIndep variant uses the pipelined inputs directly. + + assign a_x_calc = a_x_q; + assign b_x_calc = b_x_q; + assign a_y_calc = a_y_q; + assign b_y_calc = b_y_q; + + end else begin : gen_no_pipeline_use + // Do not use pipelined inputs x and y. This allows to save some area in case the multiplier + // does not need to accept new data in every cycle. However, this can cause SCA leakage as + // during the clock cycle in which new data arrives, the new x and y inputs are multiplied + // with the previous d_b. + + assign a_x_calc = a_x; + assign b_x_calc = b_x; + assign a_y_calc = a_y; + assign b_y_calc = b_y; + + // Tie off unused signals. + if (PreDomIndep != 1'b1) begin : gen_ab_x_q + logic [NPower-1:0] unused_a_x_q, unused_b_x_q; + assign unused_a_x_q = a_x_q; + assign unused_b_x_q = b_x_q; + end + logic [NPower-1:0] unused_a_y_q, unused_b_y_q; + assign unused_a_y_q = a_y_q; + assign unused_b_y_q = b_y_q; + end + + /////////////////////////////// + // Calculation & Integration // + /////////////////////////////// + // Compute b. Note that unlike for the unoptimized implementation, we don't combine the blinded + // shares of y to obtain a single b value. Intstead, every domain d gets its own version of b: + // + // d_b = d_y ^ _D_y_z0 + // + // where _D_y_z0 corresponds to the sum of all domains of y except for domain d, each + // individually blinded by z0 (needs to happen before the register bank). This optimization + // is only suitable for first-order masking. + // See Formula 12 in [1]. + + if (PreDomIndep == 1'b1) begin : gen_pre_dom_indep + // This DOM-dep multiplier is directly followed by an un-pipelined DOM-indep multiplier. To + // prevent SCA leakage in the un-pipelined DOM-indep multiplier, the d_y and _D_y_z0 parts of + // d_b need to be individually multiplied with input x and then the results need to be + // integrated (summed up) on a per-domain basis. + + // d_y part: Inner-domain terms of x * y + logic [NPower-1:0] mul_ax_ay_d, mul_bx_by_d; + logic [NPower-1:0] mul_ax_ay_q, mul_bx_by_q; + if (NPower == 4) begin : gen_inner_mul_gf2p4 + assign mul_ax_ay_d = aes_mul_gf2p4(a_x_calc, a_y_calc); + assign mul_bx_by_d = aes_mul_gf2p4(b_x_calc, b_y_calc); + + end else begin : gen_inner_mul_gf2p2 + assign mul_ax_ay_d = aes_mul_gf2p2(a_x_calc, a_y_calc); + assign mul_bx_by_d = aes_mul_gf2p2(b_x_calc, b_y_calc); + end + + // Registers + caliptra_prim_flop_en #( + .Width ( 2*NPower ), + .ResetValue ( '0 ) + ) u_caliptra_prim_flop_mul_abx_aby ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .en_i ( we_i ), + .d_i ( {mul_ax_ay_d, mul_bx_by_d} ), + .q_o ( {mul_ax_ay_q, mul_bx_by_q} ) + ); + + // _D_y_z0 part: Cross-domain terms: d_x * _D_y_z0 + // Need to use registered version of input x. + logic [NPower-1:0] mul_ax_byz0, mul_bx_ayz0; + if (NPower == 4) begin : gen_cross_mul_gf2p4 + assign mul_ax_byz0 = aes_mul_gf2p4(a_x_q, b_yz0_q); + assign mul_bx_ayz0 = aes_mul_gf2p4(b_x_q, a_yz0_q); + + end else begin : gen_cross_mul_gf2p2 + assign mul_ax_byz0 = aes_mul_gf2p2(a_x_q, b_yz0_q); + assign mul_bx_ayz0 = aes_mul_gf2p2(b_x_q, a_yz0_q); + end + + // Avoid aggressive synthesis optimizations. + logic [NPower-1:0] mul_ax_byz0_buf, mul_bx_ayz0_buf; + caliptra_prim_buf #( + .Width ( 2*NPower ) + ) u_caliptra_prim_buf_mul_abx_bayz0 ( + .in_i ( {mul_ax_byz0, mul_bx_ayz0} ), + .out_o ( {mul_ax_byz0_buf, mul_bx_ayz0_buf} ) + ); + + // Integration + assign a_q = axz0_z1_q ^ mul_ax_ay_q ^ mul_ax_byz0_buf; + assign b_q = bxz0_z1_q ^ mul_bx_by_q ^ mul_bx_ayz0_buf; + + end else begin : gen_not_pre_dom_indep + // This DOM-dep multiplier is not directly followed by an un-pipelined DOM-indep multiplier. As + // a result, the d_y and _D_y_z0 parts of d_b can be summed up prior to the multiplication + // with input x which allows saving 2 GF multipliers. + + // Sum up d_y and _D_y_z0. + logic [NPower-1:0] a_b, b_b; + assign a_b = a_y_calc ^ b_yz0_q; + assign b_b = b_y_calc ^ a_yz0_q; + + // Avoid aggressive synthesis optimizations. + logic [NPower-1:0] a_b_buf, b_b_buf; + caliptra_prim_buf #( + .Width ( 2*NPower ) + ) u_caliptra_prim_buf_ab_b ( + .in_i ( {a_b, b_b} ), + .out_o ( {a_b_buf, b_b_buf} ) + ); + + // GF multiplications + logic [NPower-1:0] a_mul_ax_b, b_mul_bx_b; + if (NPower == 4) begin : gen_mul_gf2p4 + assign a_mul_ax_b = aes_mul_gf2p4(a_x_calc, a_b_buf); + assign b_mul_bx_b = aes_mul_gf2p4(b_x_calc, b_b_buf); + end else begin : gen_mul_gf2p2 + assign a_mul_ax_b = aes_mul_gf2p2(a_x_calc, a_b_buf); + assign b_mul_bx_b = aes_mul_gf2p2(b_x_calc, b_b_buf); + end + + // Avoid aggressive synthesis optimizations. + logic [NPower-1:0] a_mul_ax_b_buf, b_mul_bx_b_buf; + caliptra_prim_buf #( + .Width ( 2*NPower ) + ) u_caliptra_prim_buf_ab_mul_abx_b ( + .in_i ( {a_mul_ax_b, b_mul_bx_b} ), + .out_o ( {a_mul_ax_b_buf, b_mul_bx_b_buf} ) + ); + + // Integration + assign a_q = axz0_z1_q ^ a_mul_ax_b_buf; + assign b_q = bxz0_z1_q ^ b_mul_bx_b_buf; + end + + // Only GF(2^4) and GF(2^2) is supported. + `CALIPTRA_ASSERT_INIT(AesDomDepMulPower, NPower == 4 || NPower == 2) + +endmodule + +// Inverse in GF(2^4) using first-order domain-oriented masking and normal basis [z^4, z]. +// See Fig. 6 in [2] (grey block, Stages 2 and 3) and Formulas 6, 13, 14, 15, 16, 17 in [2]. +module aes_dom_inverse_gf2p4 #( + parameter bit PipelineMul = 1'b1 +) ( + input logic clk_i, + input logic rst_ni, + input logic [1:0] we_i, + input logic [3:0] a_gamma, + input logic [3:0] b_gamma, + input logic [3:0] prd_2_i, + input logic [7:0] prd_3_i, + output logic [3:0] a_gamma_inv, + output logic [3:0] b_gamma_inv, + output logic [7:0] prd_2_o, + output logic [7:0] prd_3_o +); + + import aes_sbox_canright_pkg::*; + + ///////////// + // Stage 2 // + ///////////// + // Formula 13 in [2]. + + logic [1:0] a_gamma1, a_gamma0, b_gamma1, b_gamma0, a_gamma1_gamma0, b_gamma1_gamma0; + assign a_gamma1 = a_gamma[3:2]; + assign a_gamma0 = a_gamma[1:0]; + assign b_gamma1 = b_gamma[3:2]; + assign b_gamma0 = b_gamma[1:0]; + + logic [1:0] a_gamma_ss_d, b_gamma_ss_d; + logic [1:0] a_gamma_ss_q, b_gamma_ss_q; + assign a_gamma_ss_d = aes_scale_omega2_gf2p2(aes_square_gf2p2(a_gamma1 ^ a_gamma0)); + assign b_gamma_ss_d = aes_scale_omega2_gf2p2(aes_square_gf2p2(b_gamma1 ^ b_gamma0)); + caliptra_prim_flop_en #( + .Width ( 4 ), + .ResetValue ( '0 ) + ) u_caliptra_prim_flop_ab_gamma_ss ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .en_i ( we_i[0] ), + .d_i ( {a_gamma_ss_d, b_gamma_ss_d} ), + .q_o ( {a_gamma_ss_q, b_gamma_ss_q} ) + ); + + logic [1:0] a_gamma1_q, a_gamma0_q, b_gamma1_q, b_gamma0_q; + caliptra_prim_flop_en #( + .Width ( 8 ), + .ResetValue ( '0 ) + ) u_caliptra_prim_flop_ab_gamma10 ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .en_i ( we_i[0] ), + .d_i ( {a_gamma1, a_gamma0, b_gamma1, b_gamma0} ), + .q_o ( {a_gamma1_q, a_gamma0_q, b_gamma1_q, b_gamma0_q} ) + ); + + logic [3:0] b_gamma10_prd2; + aes_dom_dep_mul_gf2pn #( + .NPower ( 2 ), + .Pipeline ( PipelineMul ), + .PreDomIndep ( 1'b0 ) + ) u_aes_dom_mul_gamma1_gamma0 ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .we_i ( we_i[0] ), + .a_x ( a_gamma1 ), // Share a of x + .a_y ( a_gamma0 ), // Share a of y + .b_x ( b_gamma1 ), // Share b of x + .b_y ( b_gamma0 ), // Share b of y + .a_x_q ( a_gamma1_q ), // Share a of x, pipelined (for Pipeline=1 or PreDomIndep=1) + .a_y_q ( a_gamma0_q ), // Share a of y, pipelined (for Pipeline=1) + .b_x_q ( b_gamma1_q ), // Share b of x, pipelined (for Pipeline=1 or PreDomIndep=1) + .b_y_q ( b_gamma0_q ), // Share b of y, pipelined (for Pipeline=1) + .z_0 ( prd_2_i[1:0] ), // Randomness for blinding + .z_1 ( prd_2_i[3:2] ), // Randomness for resharing + .a_q ( a_gamma1_gamma0 ), // Share a of q + .b_q ( b_gamma1_gamma0 ), // Share b of q + .prd_o ( b_gamma10_prd2 ) // Randomness for use in another S-Box instance + ); + + // Use intermediate results for generating PRD for Stage 3 of another S-Box instance. + // Use one share only. Directly use output of flops updating with we_i[0]. + // b_gamma10_prd2 is based on b_gamma1_q, b_gamma0_q but XORed with prd_2_i, thus uniformly + // distributed and independent of b_gamma1/0_q (See Lemma 1 in [2]). + // + // In Stage 3 of another S-Box instance, the MSBs and LSBs of the term below are used: + // 1. as randomness in the DOM-dep multipliers u_aes_dom_mul_omega_gamma1/0, and + // 2. to generate randomness for the DOM-indep multipliers u_aes_dom_mul_theta_y1/0 in Stage 4 of + // yet another S-Box instance, respectively. + // Without interleaving b_gamma1/0_q as well as the upper and lower halves of b_gamma10_prd2 here, + // a glitch on the write-enable signal on the input pipeline register of these DOM-indep + // multipliers may result in undesirable SCA leakage. + assign prd_2_o = {b_gamma1_q, b_gamma10_prd2[3:2], b_gamma0_q, b_gamma10_prd2[1:0]}; + + ///////////// + // Stage 3 // + ///////////// + + // Formulas 14 and 15 in [2]. + logic [1:0] a_omega, b_omega; + assign a_omega = aes_square_gf2p2(a_gamma1_gamma0 ^ a_gamma_ss_q); + assign b_omega = aes_square_gf2p2(b_gamma1_gamma0 ^ b_gamma_ss_q); + + // Avoid aggressive synthesis optimizations. + logic [1:0] a_omega_buf, b_omega_buf; + caliptra_prim_buf #( + .Width ( 4 ) + ) u_caliptra_prim_buf_ab_omega ( + .in_i ( {a_omega, b_omega} ), + .out_o ( {a_omega_buf, b_omega_buf} ) + ); + + // Pipeline registers + logic [1:0] a_gamma1_qq, a_gamma0_qq, b_gamma1_qq, b_gamma0_qq, a_omega_buf_q, b_omega_buf_q; + if (PipelineMul == 1'b1) begin: gen_caliptra_prim_flop_omega_gamma10 + // We instantiate the input pipeline registers for the DOM-dep multiplier outside of the + // multiplier to enable sharing of pipeline registers where applicable. + + caliptra_prim_flop_en #( + .Width ( 8 ), + .ResetValue ( '0 ) + ) u_caliptra_prim_flop_ab_gamma10_q ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .en_i ( we_i[1] ), + .d_i ( {a_gamma1_q, a_gamma0_q, b_gamma1_q, b_gamma0_q} ), + .q_o ( {a_gamma1_qq, a_gamma0_qq, b_gamma1_qq, b_gamma0_qq} ) + ); + + // These inputs are used by both DOM-dep multipliers below. + caliptra_prim_flop_en #( + .Width ( 4 ), + .ResetValue ( '0 ) + ) u_caliptra_prim_flop_ab_omega_buf ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .en_i ( we_i[1] ), + .d_i ( {a_omega_buf, b_omega_buf} ), + .q_o ( {a_omega_buf_q, b_omega_buf_q} ) + ); + + end else begin : gen_no_caliptra_prim_flop_ab_y10 + // When using un-pipelined multipliers, there is no need to insert additional registers. + // We drive the corresponding inputs to 0 to make sure the functionality isn't correct in case + // the pipeliend inputs are erroneously used. + + assign a_gamma1_qq = '0; + assign a_gamma0_qq = '0; + assign b_gamma1_qq = '0; + assign b_gamma0_qq = '0; + assign a_omega_buf_q = '0; + assign b_omega_buf_q = '0; + end + + // Formulas 16 and 17 in [2]. + logic [3:0] b_gamma1_omega_prd3; + aes_dom_dep_mul_gf2pn #( + .NPower ( 2 ), + .Pipeline ( PipelineMul ), + .PreDomIndep ( 1'b0 ) + ) u_aes_dom_mul_omega_gamma1 ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .we_i ( we_i[1] ), + .a_x ( a_gamma1_q ), // Share a of x + .a_y ( a_omega_buf ), // Share a of y + .b_x ( b_gamma1_q ), // Share b of x + .b_y ( b_omega_buf ), // Share b of y + .a_x_q ( a_gamma1_qq ), // Share a of x, pipelined (for Pipeline=1 or PreDomIndep=1) + .a_y_q ( a_omega_buf_q ), // Share a of y, pipelined (for Pipeline=1) + .b_x_q ( b_gamma1_qq ), // Share b of x, pipelined (for Pipeline=1 or PreDomIndep=1) + .b_y_q ( b_omega_buf_q ), // Share b of y, pipelined (for Pipeline=1) + .z_0 ( prd_3_i[5:4] ), // Randomness for blinding + .z_1 ( prd_3_i[7:6] ), // Randomness for resharing + .a_q ( a_gamma_inv[1:0] ), // Share a of q + .b_q ( b_gamma_inv[1:0] ), // Share b of q + .prd_o ( b_gamma1_omega_prd3 ) // Randomness for use in another S-Box instance + ); + + logic [3:0] b_gamma0_omega_prd3; + aes_dom_dep_mul_gf2pn #( + .NPower ( 2 ), + .Pipeline ( PipelineMul ), + .PreDomIndep ( 1'b0 ) + ) u_aes_dom_mul_omega_gamma0 ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .we_i ( we_i[1] ), + .a_x ( a_omega_buf ), // Share a of x + .a_y ( a_gamma0_q ), // Share a of y + .b_x ( b_omega_buf ), // Share b of x + .b_y ( b_gamma0_q ), // Share b of y + .a_x_q ( a_omega_buf_q ), // Share a of x, pipelined (for Pipeline=1 or PreDomIndep=1) + .a_y_q ( a_gamma0_qq ), // Share a of y, pipelined (for Pipeline=1) + .b_x_q ( b_omega_buf_q ), // Share b of x, pipelined (for Pipeline=1 or PreDomIndep=1) + .b_y_q ( b_gamma0_qq ), // Share b of y, pipelined (for Pipeline=1) + .z_0 ( prd_3_i[1:0] ), // Randomness for blinding + .z_1 ( prd_3_i[3:2] ), // Randomness for resharing + .a_q ( a_gamma_inv[3:2] ), // Share a of q + .b_q ( b_gamma_inv[3:2] ), // Share b of q + .prd_o ( b_gamma0_omega_prd3 ) // Randomness for use in another S-Box instance + ); + + // Use intermediate results for generating PRD for Stage 4 of another S-Box instance. + // Use one share only. Directly use output of flops updating with we_i[1]. + // b_gamma1/0_omega_prd3 are both based on b_omega but XORed with differend parts of prd_3_i, + // thus uniformly distributed and independent of b_omega (see Lemma 1 in [2]). + assign prd_3_o = {b_gamma1_omega_prd3, b_gamma0_omega_prd3}; + +endmodule + +// Inverse in GF(2^8) using first-order domain-oriented masking and normal basis [y^16, y]. +// See Fig. 6 in [1] and Formulas 3, 12, 18 and 19 in [2]. +module aes_dom_inverse_gf2p8 #( + parameter bit PipelineMul = 1'b1 +) ( + input logic clk_i, + input logic rst_ni, + input logic [3:0] we_i, + input logic [7:0] a_y, // input data masked by b_y + input logic [7:0] b_y, // input mask + input aes_sbox_dom_prd_in_t prd_i, // pseudo-random data, e.g. for intermediate masks + output logic [7:0] a_y_inv, // output data masked by b_y_inv + output logic [7:0] b_y_inv, // output mask + output aes_sbox_dom_prd_out_t prd_o // pseudo-random data, e.g. for use in another S-Box +); // instance + + import aes_sbox_canright_pkg::*; + + ///////////// + // Stage 1 // + ///////////// + // Formula 12 in [2]. + + logic [3:0] a_y1, a_y0, b_y1, b_y0, a_y1_y0, b_y1_y0; + assign a_y1 = a_y[7:4]; + assign a_y0 = a_y[3:0]; + assign b_y1 = b_y[7:4]; + assign b_y0 = b_y[3:0]; + + logic [3:0] a_y_ss_d, b_y_ss_d; + logic [3:0] a_y_ss_q, b_y_ss_q; + assign a_y_ss_d = aes_square_scale_gf2p4_gf2p2(a_y1 ^ a_y0); + assign b_y_ss_d = aes_square_scale_gf2p4_gf2p2(b_y1 ^ b_y0); + caliptra_prim_flop_en #( + .Width ( 8 ), + .ResetValue ( '0 ) + ) u_caliptra_prim_flop_ab_y_ss ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .en_i ( we_i[0] ), + .d_i ( {a_y_ss_d, b_y_ss_d} ), + .q_o ( {a_y_ss_q, b_y_ss_q} ) + ); + + logic [3:0] a_y1_q, a_y0_q, b_y1_q, b_y0_q; + if (PipelineMul == 1'b1) begin: gen_caliptra_prim_flop_ab_y10 + // We instantiate the input pipeline registers for the DOM-dep multiplier outside of the + // multiplier to enable sharing of pipeline registers where applicable. + + caliptra_prim_flop_en #( + .Width ( 16 ), + .ResetValue ( '0 ) + ) u_caliptra_prim_flop_ab_y10 ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .en_i ( we_i[0] ), + .d_i ( {a_y1, a_y0, b_y1, b_y0} ), + .q_o ( {a_y1_q, a_y0_q, b_y1_q, b_y0_q} ) + ); + + end else begin : gen_no_caliptra_prim_flop_ab_y10 + // When using un-pipelined multipliers, there is no need to insert additional registers. + // We drive the corresponding inputs to 0 to make sure the functionality isn't correct in case + // the pipeliend inputs are erroneously used. + + assign a_y1_q = '0; + assign a_y0_q = '0; + assign b_y1_q = '0; + assign b_y0_q = '0; + end + + logic [7:0] b_y10_prd1; + aes_dom_dep_mul_gf2pn #( + .NPower ( 4 ), + .Pipeline ( PipelineMul ), + .PreDomIndep ( 1'b0 ) + ) u_aes_dom_mul_y1_y0 ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .we_i ( we_i[0] ), + .a_x ( a_y1 ), // Share a of x + .a_y ( a_y0 ), // Share a of y + .b_x ( b_y1 ), // Share b of x + .b_y ( b_y0 ), // Share b of y + .a_x_q ( a_y1_q ), // Share a of x, pipelined (for Pipeline=1 or PreDomIndep=1) + .a_y_q ( a_y0_q ), // Share a of y, pipelined (for Pipeline=1) + .b_x_q ( b_y1_q ), // Share b of x, pipelined (for Pipeline=1 or PreDomIndep=1) + .b_y_q ( b_y0_q ), // Share b of y, pipelined (for Pipeline=1) + .z_0 ( prd_i.prd_1[3:0] ), // Randomness for blinding + .z_1 ( prd_i.prd_1[7:4] ), // Randomness for resharing + .a_q ( a_y1_y0 ), // Share a of q + .b_q ( b_y1_y0 ), // Share b of q + .prd_o ( b_y10_prd1 ) // Randomness for use in another S-Box instance + ); + + logic [3:0] a_gamma, b_gamma; + assign a_gamma = a_y_ss_q ^ a_y1_y0; + assign b_gamma = b_y_ss_q ^ b_y1_y0; + + // Avoid aggressive synthesis optimizations. + logic [3:0] a_gamma_buf, b_gamma_buf; + caliptra_prim_buf #( + .Width ( 8 ) + ) u_caliptra_prim_buf_ab_gamma ( + .in_i ( {a_gamma, b_gamma} ), + .out_o ( {a_gamma_buf, b_gamma_buf} ) + ); + + // Use intermediate results for generating PRD for Stage 2 of another S-Box instance. + // Use one share only. Directly use output of flops updating with we_i[0]. + // b_y10_prd1 is based on b_y and XORed with prd_1. We just use the lower part involving a + // non-linear element. + assign prd_o.prd_1 = b_y10_prd1[3:0]; + logic [3:0] unused_prd; + assign unused_prd = b_y10_prd1[7:4]; + + //////////////////// + // Stages 2 and 3 // + //////////////////// + + logic [3:0] a_theta, b_theta; + + // a_gamma is masked by b_gamma, a_gamma_inv is masked by b_gamma_inv. + aes_dom_inverse_gf2p4 #( + .PipelineMul ( PipelineMul ) + ) u_aes_dom_inverse_gf2p4 ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .we_i ( we_i[2:1] ), + .a_gamma ( a_gamma_buf ), + .b_gamma ( b_gamma_buf ), + .prd_2_i ( prd_i.prd_2 ), + .prd_3_i ( prd_i.prd_3 ), + .a_gamma_inv ( a_theta ), + .b_gamma_inv ( b_theta ), + .prd_2_o ( prd_o.prd_2 ), + .prd_3_o ( prd_o.prd_3 ) + ); + + ///////////// + // Stage 4 // + ///////////// + // Formulas 18 and 19 in [2]. + + logic [3:0] a_y1_qqq, a_y0_qqq, b_y1_qqq, b_y0_qqq; + caliptra_prim_flop_en #( + .Width ( 16 ), + .ResetValue ( '0 ) + ) u_caliptra_prim_flop_ab_y10_qqq ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .en_i ( we_i[2] ), + .d_i ( {a_y1, a_y0, b_y1, b_y0} ), + .q_o ( {a_y1_qqq, a_y0_qqq, b_y1_qqq, b_y0_qqq} ) + ); + + aes_dom_indep_mul_gf2pn #( + .NPower ( 4 ), + .Pipeline ( PipelineMul ) + ) u_aes_dom_mul_theta_y1 ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .we_i ( we_i[3] ), + .a_x ( a_y1_qqq ), // Share a of x + .a_y ( a_theta ), // Share a of y + .b_x ( b_y1_qqq ), // Share b of x + .b_y ( b_theta ), // Share b of y + .z_0 ( prd_i.prd_4[7:4] ), // Randomness for resharing + .a_q ( a_y_inv[3:0] ), // Share a of q + .b_q ( b_y_inv[3:0] ) // Share b of q + ); + + aes_dom_indep_mul_gf2pn #( + .NPower ( 4 ), + .Pipeline ( PipelineMul ) + ) u_aes_dom_mul_theta_y0 ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .we_i ( we_i[3] ), + .a_x ( a_theta ), // Share a of x + .a_y ( a_y0_qqq ), // Share a of y + .b_x ( b_theta ), // Share b of x + .b_y ( b_y0_qqq ), // Share b of y + .z_0 ( prd_i.prd_4[3:0] ), // Randomness for resharing + .a_q ( a_y_inv[7:4] ), // Share a of q + .b_q ( b_y_inv[7:4] ) // Share b of q + ); + +endmodule + +// SEC_CM: KEY.MASKING +module aes_sbox_dom +#( + parameter bit PipelineMul = 1'b1 +) ( + input logic clk_i, + input logic rst_ni, + input logic en_i, + output logic out_req_o, + input logic out_ack_i, + input aes_pkg::ciph_op_e op_i, + input logic [7:0] data_i, // masked, the actual input data is data_i ^ mask_i + input logic [7:0] mask_i, // input mask + input logic [27:0] prd_i, // pseudo-random data for remasking, in total we need 28 bits + // of PRD per evaluation, but at most 8 bits per cycle + output logic [7:0] data_o, // masked, the actual output data is data_o ^ mask_o + output logic [7:0] mask_o, // output mask + output logic [19:0] prd_o // PRD for usage in Stages 2 - 4 of other S-Box instances +); + + import aes_pkg::*; + import aes_sbox_canright_pkg::*; + + logic [7:0] in_data_basis_x, out_data_basis_x; + logic [7:0] in_mask_basis_x, out_mask_basis_x; + logic [3:0] we; + aes_sbox_dom_prd_in_t in_prd; + aes_sbox_dom_prd_out_t out_prd; + + // Convert data to normal basis X. + assign in_data_basis_x = (op_i == CIPH_FWD) ? aes_mvm(data_i, A2X) : + (op_i == CIPH_INV) ? aes_mvm(data_i ^ 8'h63, S2X) : + aes_mvm(data_i, A2X); + + // Convert mask to normal basis X. + // The addition of constant 8'h63 prior to the affine transformation is skipped. + assign in_mask_basis_x = (op_i == CIPH_FWD) ? aes_mvm(mask_i, A2X) : + (op_i == CIPH_INV) ? aes_mvm(mask_i, S2X) : + aes_mvm(mask_i, A2X); + + // Do the inversion in normal basis X. + aes_dom_inverse_gf2p8 #( + .PipelineMul ( PipelineMul ) + ) u_aes_dom_inverse_gf2p8 ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .we_i ( we ), + .a_y ( in_data_basis_x ), // input + .b_y ( in_mask_basis_x ), // input + .prd_i ( in_prd ), // input + .a_y_inv ( out_data_basis_x ), // output + .b_y_inv ( out_mask_basis_x ), // output + .prd_o ( out_prd ) // output + ); + + // Convert data to basis S or A. + assign data_o = (op_i == CIPH_FWD) ? (aes_mvm(out_data_basis_x, X2S) ^ 8'h63) : + (op_i == CIPH_INV) ? (aes_mvm(out_data_basis_x, X2A)) : + (aes_mvm(out_data_basis_x, X2S) ^ 8'h63); + + // Convert mask to basis S or A. + // The addition of constant 8'h63 following the affine transformation is skipped. + assign mask_o = (op_i == CIPH_FWD) ? aes_mvm(out_mask_basis_x, X2S) : + (op_i == CIPH_INV) ? aes_mvm(out_mask_basis_x, X2A) : + aes_mvm(out_mask_basis_x, X2S); + + // Counter register + logic [2:0] count_d, count_q; + assign count_d = (out_req_o && out_ack_i) ? '0 : + out_req_o ? count_q : + en_i ? count_q + 3'd1 : count_q; + always_ff @(posedge clk_i or negedge rst_ni) begin : reg_count + if (!rst_ni) begin + count_q <= '0; + end else begin + count_q <= count_d; + end + end + assign out_req_o = en_i & count_q == 3'd4; + + // Write enable signals for internal registers + assign we[0] = en_i & count_q == 3'd0; + assign we[1] = en_i & count_q == 3'd1; + assign we[2] = en_i & count_q == 3'd2; + assign we[3] = en_i & count_q == 3'd3; + + // PRD forwarding for the individual stages. We get 8 bits from the PRNG for usage in Stage 1. + // Stages 2, 3 and 4 are driven by other S-Box instances. + assign in_prd = '{prd_1: prd_i[7:0], + prd_2: prd_i[11:8], + prd_3: prd_i[19:12], + prd_4: prd_i[27:20]}; + assign prd_o = {out_prd.prd_3, out_prd.prd_2, out_prd.prd_1}; + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/aes_sbox_lut.sv b/designs/Caliptra/src/caliptra-rtl/aes_sbox_lut.sv new file mode 100644 index 0000000..94064a3 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/aes_sbox_lut.sv @@ -0,0 +1,120 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// AES LUT-based SBox + +module aes_sbox_lut ( + input aes_pkg::ciph_op_e op_i, + input logic [7:0] data_i, + output logic [7:0] data_o +); + + import aes_pkg::*; + + // Define the LUTs + localparam logic [7:0] SBOX_FWD [256] = '{ + 8'h63, 8'h7C, 8'h77, 8'h7B, 8'hF2, 8'h6B, 8'h6F, 8'hC5, + 8'h30, 8'h01, 8'h67, 8'h2B, 8'hFE, 8'hD7, 8'hAB, 8'h76, + + 8'hCA, 8'h82, 8'hC9, 8'h7D, 8'hFA, 8'h59, 8'h47, 8'hF0, + 8'hAD, 8'hD4, 8'hA2, 8'hAF, 8'h9C, 8'hA4, 8'h72, 8'hC0, + + 8'hB7, 8'hFD, 8'h93, 8'h26, 8'h36, 8'h3F, 8'hF7, 8'hCC, + 8'h34, 8'hA5, 8'hE5, 8'hF1, 8'h71, 8'hD8, 8'h31, 8'h15, + + 8'h04, 8'hC7, 8'h23, 8'hC3, 8'h18, 8'h96, 8'h05, 8'h9A, + 8'h07, 8'h12, 8'h80, 8'hE2, 8'hEB, 8'h27, 8'hB2, 8'h75, + + 8'h09, 8'h83, 8'h2C, 8'h1A, 8'h1B, 8'h6E, 8'h5A, 8'hA0, + 8'h52, 8'h3B, 8'hD6, 8'hB3, 8'h29, 8'hE3, 8'h2F, 8'h84, + + 8'h53, 8'hD1, 8'h00, 8'hED, 8'h20, 8'hFC, 8'hB1, 8'h5B, + 8'h6A, 8'hCB, 8'hBE, 8'h39, 8'h4A, 8'h4C, 8'h58, 8'hCF, + + 8'hD0, 8'hEF, 8'hAA, 8'hFB, 8'h43, 8'h4D, 8'h33, 8'h85, + 8'h45, 8'hF9, 8'h02, 8'h7F, 8'h50, 8'h3C, 8'h9F, 8'hA8, + + 8'h51, 8'hA3, 8'h40, 8'h8F, 8'h92, 8'h9D, 8'h38, 8'hF5, + 8'hBC, 8'hB6, 8'hDA, 8'h21, 8'h10, 8'hFF, 8'hF3, 8'hD2, + + 8'hCD, 8'h0C, 8'h13, 8'hEC, 8'h5F, 8'h97, 8'h44, 8'h17, + 8'hC4, 8'hA7, 8'h7E, 8'h3D, 8'h64, 8'h5D, 8'h19, 8'h73, + + 8'h60, 8'h81, 8'h4F, 8'hDC, 8'h22, 8'h2A, 8'h90, 8'h88, + 8'h46, 8'hEE, 8'hB8, 8'h14, 8'hDE, 8'h5E, 8'h0B, 8'hDB, + + 8'hE0, 8'h32, 8'h3A, 8'h0A, 8'h49, 8'h06, 8'h24, 8'h5C, + 8'hC2, 8'hD3, 8'hAC, 8'h62, 8'h91, 8'h95, 8'hE4, 8'h79, + + 8'hE7, 8'hC8, 8'h37, 8'h6D, 8'h8D, 8'hD5, 8'h4E, 8'hA9, + 8'h6C, 8'h56, 8'hF4, 8'hEA, 8'h65, 8'h7A, 8'hAE, 8'h08, + + 8'hBA, 8'h78, 8'h25, 8'h2E, 8'h1C, 8'hA6, 8'hB4, 8'hC6, + 8'hE8, 8'hDD, 8'h74, 8'h1F, 8'h4B, 8'hBD, 8'h8B, 8'h8A, + + 8'h70, 8'h3E, 8'hB5, 8'h66, 8'h48, 8'h03, 8'hF6, 8'h0E, + 8'h61, 8'h35, 8'h57, 8'hB9, 8'h86, 8'hC1, 8'h1D, 8'h9E, + + 8'hE1, 8'hF8, 8'h98, 8'h11, 8'h69, 8'hD9, 8'h8E, 8'h94, + 8'h9B, 8'h1E, 8'h87, 8'hE9, 8'hCE, 8'h55, 8'h28, 8'hDF, + + 8'h8C, 8'hA1, 8'h89, 8'h0D, 8'hBF, 8'hE6, 8'h42, 8'h68, + 8'h41, 8'h99, 8'h2D, 8'h0F, 8'hB0, 8'h54, 8'hBB, 8'h16 + }; + + localparam logic [7:0] SBOX_INV [256] = '{ + 8'h52, 8'h09, 8'h6a, 8'hd5, 8'h30, 8'h36, 8'ha5, 8'h38, + 8'hbf, 8'h40, 8'ha3, 8'h9e, 8'h81, 8'hf3, 8'hd7, 8'hfb, + + 8'h7c, 8'he3, 8'h39, 8'h82, 8'h9b, 8'h2f, 8'hff, 8'h87, + 8'h34, 8'h8e, 8'h43, 8'h44, 8'hc4, 8'hde, 8'he9, 8'hcb, + + 8'h54, 8'h7b, 8'h94, 8'h32, 8'ha6, 8'hc2, 8'h23, 8'h3d, + 8'hee, 8'h4c, 8'h95, 8'h0b, 8'h42, 8'hfa, 8'hc3, 8'h4e, + + 8'h08, 8'h2e, 8'ha1, 8'h66, 8'h28, 8'hd9, 8'h24, 8'hb2, + 8'h76, 8'h5b, 8'ha2, 8'h49, 8'h6d, 8'h8b, 8'hd1, 8'h25, + + 8'h72, 8'hf8, 8'hf6, 8'h64, 8'h86, 8'h68, 8'h98, 8'h16, + 8'hd4, 8'ha4, 8'h5c, 8'hcc, 8'h5d, 8'h65, 8'hb6, 8'h92, + + 8'h6c, 8'h70, 8'h48, 8'h50, 8'hfd, 8'hed, 8'hb9, 8'hda, + 8'h5e, 8'h15, 8'h46, 8'h57, 8'ha7, 8'h8d, 8'h9d, 8'h84, + + 8'h90, 8'hd8, 8'hab, 8'h00, 8'h8c, 8'hbc, 8'hd3, 8'h0a, + 8'hf7, 8'he4, 8'h58, 8'h05, 8'hb8, 8'hb3, 8'h45, 8'h06, + + 8'hd0, 8'h2c, 8'h1e, 8'h8f, 8'hca, 8'h3f, 8'h0f, 8'h02, + 8'hc1, 8'haf, 8'hbd, 8'h03, 8'h01, 8'h13, 8'h8a, 8'h6b, + + 8'h3a, 8'h91, 8'h11, 8'h41, 8'h4f, 8'h67, 8'hdc, 8'hea, + 8'h97, 8'hf2, 8'hcf, 8'hce, 8'hf0, 8'hb4, 8'he6, 8'h73, + + 8'h96, 8'hac, 8'h74, 8'h22, 8'he7, 8'had, 8'h35, 8'h85, + 8'he2, 8'hf9, 8'h37, 8'he8, 8'h1c, 8'h75, 8'hdf, 8'h6e, + + 8'h47, 8'hf1, 8'h1a, 8'h71, 8'h1d, 8'h29, 8'hc5, 8'h89, + 8'h6f, 8'hb7, 8'h62, 8'h0e, 8'haa, 8'h18, 8'hbe, 8'h1b, + + 8'hfc, 8'h56, 8'h3e, 8'h4b, 8'hc6, 8'hd2, 8'h79, 8'h20, + 8'h9a, 8'hdb, 8'hc0, 8'hfe, 8'h78, 8'hcd, 8'h5a, 8'hf4, + + 8'h1f, 8'hdd, 8'ha8, 8'h33, 8'h88, 8'h07, 8'hc7, 8'h31, + 8'hb1, 8'h12, 8'h10, 8'h59, 8'h27, 8'h80, 8'hec, 8'h5f, + + 8'h60, 8'h51, 8'h7f, 8'ha9, 8'h19, 8'hb5, 8'h4a, 8'h0d, + 8'h2d, 8'he5, 8'h7a, 8'h9f, 8'h93, 8'hc9, 8'h9c, 8'hef, + + 8'ha0, 8'he0, 8'h3b, 8'h4d, 8'hae, 8'h2a, 8'hf5, 8'hb0, + 8'hc8, 8'heb, 8'hbb, 8'h3c, 8'h83, 8'h53, 8'h99, 8'h61, + + 8'h17, 8'h2b, 8'h04, 8'h7e, 8'hba, 8'h77, 8'hd6, 8'h26, + 8'he1, 8'h69, 8'h14, 8'h63, 8'h55, 8'h21, 8'h0c, 8'h7d + }; + + // Drive output + assign data_o = (op_i == CIPH_FWD) ? SBOX_FWD[data_i] : + (op_i == CIPH_INV) ? SBOX_INV[data_i] : SBOX_FWD[data_i]; + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/aes_sel_buf_chk.sv b/designs/Caliptra/src/caliptra-rtl/aes_sel_buf_chk.sv new file mode 100644 index 0000000..335eeb6 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/aes_sel_buf_chk.sv @@ -0,0 +1,164 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// AES mux selector buffer and checker +// +// When using sparse encodings for mux selector signals, this module can be used to: +// 1. Prevent aggressive synthesis optimizations on the selector signal, and +// 2. to check that the selector signal is valid, i.e., doesn't take on invalid values. +// Whenever the selector signal takes on an invalid value, an error is signaled. + +`include "caliptra_prim_assert.sv" + +module aes_sel_buf_chk #( + parameter int Num = 2, + parameter int Width = 1, + parameter bit EnSecBuf = 1'b0 +) ( + input logic clk_i, // Used for assertions only. + input logic rst_ni, // Used for assertions only. + input logic [Width-1:0] sel_i, + output logic [Width-1:0] sel_o, + output logic err_o +); + + import aes_pkg::*; + + // Tie off unused inputs. + logic unused_clk; + logic unused_rst; + assign unused_clk = clk_i; + assign unused_rst = rst_ni; + + //////////// + // Buffer // + //////////// + + if (EnSecBuf) begin : gen_sec_buf + caliptra_prim_sec_anchor_buf #( + .Width ( Width ) + ) u_caliptra_prim_buf_sel_i ( + .in_i ( sel_i ), + .out_o ( sel_o ) + ); + end else begin : gen_buf + caliptra_prim_buf #( + .Width ( Width ) + ) u_caliptra_prim_buf_sel_i ( + .in_i ( sel_i ), + .out_o ( sel_o ) + ); + end + + ///////////// + // Checker // + ///////////// + + if (Num == 2) begin : gen_mux2_sel_chk + // Cast to generic type. + mux2_sel_e sel_chk; + assign sel_chk = mux2_sel_e'(sel_o); + + // Actual checker + always_comb begin : mux2_sel_chk + unique case (sel_chk) + MUX2_SEL_0, + MUX2_SEL_1: err_o = 1'b0; + default: err_o = 1'b1; + endcase + end + + // Assertion + `CALIPTRA_ASSERT(AesMux2SelValid, !err_o |-> sel_chk inside { + MUX2_SEL_0, + MUX2_SEL_1 + }) + + end else if (Num == 3) begin : gen_mux3_sel_chk + // Cast to generic type. + mux3_sel_e sel_chk; + assign sel_chk = mux3_sel_e'(sel_o); + + // Actual checker + always_comb begin : mux3_sel_chk + unique case (sel_chk) + MUX3_SEL_0, + MUX3_SEL_1, + MUX3_SEL_2: err_o = 1'b0; + default: err_o = 1'b1; + endcase + end + + // Assertion + `CALIPTRA_ASSERT(AesMux3SelValid, !err_o |-> sel_chk inside { + MUX3_SEL_0, + MUX3_SEL_1, + MUX3_SEL_2 + }) + + end else if (Num == 4) begin : gen_mux4_sel_chk + // Cast to generic type. + mux4_sel_e sel_chk; + assign sel_chk = mux4_sel_e'(sel_o); + + // Actual checker + always_comb begin : mux4_sel_chk + unique case (sel_chk) + MUX4_SEL_0, + MUX4_SEL_1, + MUX4_SEL_2, + MUX4_SEL_3: err_o = 1'b0; + default: err_o = 1'b1; + endcase + end + + // Assertion + `CALIPTRA_ASSERT(AesMux4SelValid, !err_o |-> sel_chk inside { + MUX4_SEL_0, + MUX4_SEL_1, + MUX4_SEL_2, + MUX4_SEL_3 + }) + + end else if (Num == 6) begin : gen_mux6_sel_chk + // Cast to generic type. + mux6_sel_e sel_chk; + assign sel_chk = mux6_sel_e'(sel_o); + + // Actual checker + always_comb begin : mux6_sel_chk + unique case (sel_chk) + MUX6_SEL_0, + MUX6_SEL_1, + MUX6_SEL_2, + MUX6_SEL_3, + MUX6_SEL_4, + MUX6_SEL_5: err_o = 1'b0; + default: err_o = 1'b1; + endcase + end + + // Assertion + `CALIPTRA_ASSERT(AesMux6SelValid, !err_o |-> sel_chk inside { + MUX6_SEL_0, + MUX6_SEL_1, + MUX6_SEL_2, + MUX6_SEL_3, + MUX6_SEL_4, + MUX6_SEL_5 + }) + + end else begin : gen_width_unsupported + // Selected width not supported, signal error. + assign err_o = 1'b1; + end + + //////////////// + // Assertions // + //////////////// + + // We only have generic sparse encodings defined for certain mux input numbers (see aes_pkg.sv). + `CALIPTRA_ASSERT_INIT(AesSelBufChkNum, Num inside {2, 3, 4, 6}) + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/aes_shift_rows.sv b/designs/Caliptra/src/caliptra-rtl/aes_shift_rows.sv new file mode 100644 index 0000000..e8df6f0 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/aes_shift_rows.sv @@ -0,0 +1,31 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// AES ShiftRows + +module aes_shift_rows ( + input aes_pkg::ciph_op_e op_i, + input logic [3:0][3:0][7:0] data_i, + output logic [3:0][3:0][7:0] data_o +); + + import aes_pkg::*; + + // Row 0 is left untouched + assign data_o[0] = data_i[0]; + + // Row 2 does not depend on op_i + assign data_o[2] = aes_circ_byte_shift(data_i[2], 2'h2); + + // Row 1 + assign data_o[1] = (op_i == CIPH_FWD) ? aes_circ_byte_shift(data_i[1], 2'h3) : + (op_i == CIPH_INV) ? aes_circ_byte_shift(data_i[1], 2'h1) : + aes_circ_byte_shift(data_i[1], 2'h3); + + // Row 3 + assign data_o[3] = (op_i == CIPH_FWD) ? aes_circ_byte_shift(data_i[3], 2'h1) : + (op_i == CIPH_INV) ? aes_circ_byte_shift(data_i[3], 2'h3) : + aes_circ_byte_shift(data_i[3], 2'h1); + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/aes_sub_bytes.sv b/designs/Caliptra/src/caliptra-rtl/aes_sub_bytes.sv new file mode 100644 index 0000000..11e7254 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/aes_sub_bytes.sv @@ -0,0 +1,101 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// AES SubBytes + +module aes_sub_bytes import aes_pkg::*; +#( + parameter sbox_impl_e SecSBoxImpl = SBoxImplDom +) ( + input logic clk_i, + input logic rst_ni, + input sp2v_e en_i, + output sp2v_e out_req_o, + input sp2v_e out_ack_i, + input ciph_op_e op_i, + input logic [3:0][3:0][7:0] data_i, + input logic [3:0][3:0][7:0] mask_i, + input logic [3:0][3:0][WidthPRDSBox-1:0] prd_i, + output logic [3:0][3:0][7:0] data_o, + output logic [3:0][3:0][7:0] mask_o, + output logic err_o +); + + sp2v_e en; + logic en_err; + logic [3:0][3:0] out_req; + sp2v_e out_ack; + logic out_ack_err; + + // Every DOM S-Box instance consumes 28 bits of randomness but itself produces 20 bits for use in + // another S-Box instance. For other S-Box implementations, only the bits corresponding to prd_i + // are used. Other bits are ignored and tied to 0. + logic [3:0][3:0][WidthPRDSBox+19:0] in_prd; + logic [3:0][3:0] [19:0] out_prd; + + // SEC_CM: CTRL.SPARSE + // Check sparsely encoded signals. + logic [Sp2VWidth-1:0] en_raw; + aes_sel_buf_chk #( + .Num ( Sp2VNum ), + .Width ( Sp2VWidth ), + .EnSecBuf ( 1'b1 ) + ) u_aes_sb_en_buf_chk ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .sel_i ( en_i ), + .sel_o ( en_raw ), + .err_o ( en_err ) + ); + assign en = sp2v_e'(en_raw); + + logic [Sp2VWidth-1:0] out_ack_raw; + aes_sel_buf_chk #( + .Num ( Sp2VNum ), + .Width ( Sp2VWidth ), + .EnSecBuf ( 1'b1 ) + ) u_aes_sb_out_ack_buf_chk ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .sel_i ( out_ack_i ), + .sel_o ( out_ack_raw ), + .err_o ( out_ack_err ) + ); + assign out_ack = sp2v_e'(out_ack_raw); + + // Individually substitute bytes. + for (genvar j = 0; j < 4; j++) begin : gen_sbox_j + for (genvar i = 0; i < 4; i++) begin : gen_sbox_i + + // Rotate the randomness produced by the S-Boxes over the columns but not across rows as + // MixColumns will operate across rows. The LSBs are taken from the masking PRNG (prd_i) + // whereas the MSBs are produced by the other S-Box instances. + assign in_prd[i][j] = {out_prd[i][aes_rot_int(j,4)], prd_i[i][j]}; + + aes_sbox #( + .SecSBoxImpl ( SecSBoxImpl ) + ) u_aes_sbox_ij ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .en_i ( en == SP2V_HIGH ), + .out_req_o ( out_req[i][j] ), + .out_ack_i ( out_ack == SP2V_HIGH ), + .op_i ( op_i ), + .data_i ( data_i[i][j] ), + .mask_i ( mask_i[i][j] ), + .prd_i ( in_prd[i][j] ), + .data_o ( data_o[i][j] ), + .mask_o ( mask_o[i][j] ), + .prd_o ( out_prd[i][j] ) + ); + end + end + + // Collect REQ signals. + assign out_req_o = &out_req ? SP2V_HIGH : SP2V_LOW; + + // Collect encoding errors. + assign err_o = en_err | out_ack_err; + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/ahb_defines_pkg.sv b/designs/Caliptra/src/caliptra-rtl/ahb_defines_pkg.sv new file mode 100644 index 0000000..0d91965 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/ahb_defines_pkg.sv @@ -0,0 +1,25 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +// +`ifndef CALIPTRA_AHB_DEFINES_PKG +`define CALIPTRA_AHB_DEFINES_PKG + +package ahb_defines_pkg; + +parameter H_OKAY=1'b0; +parameter H_ERROR=1'b1; + +endpackage + +`endif diff --git a/designs/Caliptra/src/caliptra-rtl/ahb_lite_2to1_mux.sv b/designs/Caliptra/src/caliptra-rtl/ahb_lite_2to1_mux.sv new file mode 100644 index 0000000..9024a0f --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/ahb_lite_2to1_mux.sv @@ -0,0 +1,242 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +// + +// ------------------------------------------------------------- +// AHB Lite 2:1 Mux +// ------------------------------------------------------------- + +`include "caliptra_sva.svh" + +module ahb_lite_2to1_mux #( + parameter AHB_LITE_ADDR_WIDTH = 32, + parameter AHB_LITE_DATA_WIDTH = 32, + parameter AHB_NO_OPT = 0 +) ( + // --------------------------------------- + // Global clock/reset + // --------------------------------------- + input logic hclk, + input logic hreset_n, + input logic force_bus_idle, + + // --------------------------------------- + // From Initiator 0 + // --------------------------------------- + input logic hsel_i_0, + input logic [AHB_LITE_ADDR_WIDTH-1:0] haddr_i_0, + input logic [AHB_LITE_DATA_WIDTH-1:0] hwdata_i_0, + input logic hwrite_i_0, + input logic [1:0] htrans_i_0, + input logic [2:0] hsize_i_0, + input logic hready_i_0, + + output logic hresp_o_0, + output logic hready_o_0, + output logic [AHB_LITE_DATA_WIDTH-1:0] hrdata_o_0, + + // --------------------------------------- + // From Initiator 1 + // --------------------------------------- + input logic hsel_i_1, + input logic [AHB_LITE_ADDR_WIDTH-1:0] haddr_i_1, + input logic [AHB_LITE_DATA_WIDTH-1:0] hwdata_i_1, + input logic hwrite_i_1, + input logic [1:0] htrans_i_1, + input logic [2:0] hsize_i_1, + input logic hready_i_1, + + output logic hresp_o_1, + output logic hready_o_1, + output logic [AHB_LITE_DATA_WIDTH-1:0] hrdata_o_1, + + // --------------------------------------- + // To Responder Interface Port + // --------------------------------------- + input logic hresp_i, + input logic [AHB_LITE_DATA_WIDTH-1:0] hrdata_i, + input logic hreadyout_i, + + output logic [AHB_LITE_ADDR_WIDTH-1:0] haddr_o, + output logic [AHB_LITE_DATA_WIDTH-1:0] hwdata_o, + output logic hsel_o, + output logic hwrite_o, + output logic hready_o, + output logic [1:0] htrans_o, + output logic [2:0] hsize_o + +); + +//This is a fixed priority 2:1 mux for AHB-Lite protocol +//Initiator 0 always takes priority + +logic initiator0_address_ph, initiator1_address_ph; +logic initiator0_data_ph_nq, initiator1_data_ph_nq; +logic initiator0_data_ph, initiator1_data_ph; +logic initiator0_pend_addr_ph_nq, initiator1_pend_addr_ph_nq; +logic initiator0_pend_addr_ph, initiator1_pend_addr_ph; +logic initiator0_gnt, initiator1_gnt; +logic [AHB_LITE_ADDR_WIDTH-1:0] initiator0_pend_haddr, initiator1_pend_haddr; +logic [AHB_LITE_ADDR_WIDTH-1:0] initiator0_haddr, initiator1_haddr; +logic [1:0] initiator0_pend_htrans, initiator1_pend_htrans; +logic [1:0] initiator0_htrans, initiator1_htrans; +logic [2:0] initiator0_pend_hsize, initiator1_pend_hsize; +logic [2:0] initiator0_hsize, initiator1_hsize; +logic initiator0_pend_hwrite, initiator1_pend_hwrite; +logic initiator0_hwrite, initiator1_hwrite; + +//Detect address phase +always_comb initiator0_address_ph = hsel_i_0 & hready_i_0 & htrans_i_0 inside {2'b10, 2'b11} & ~force_bus_idle; +always_comb initiator1_address_ph = hsel_i_1 & hready_i_1 & htrans_i_1 inside {2'b10, 2'b11} & ~force_bus_idle; + +always_ff @(posedge hclk or negedge hreset_n) begin + if (~hreset_n) begin + initiator0_pend_haddr <= '0; + initiator1_pend_haddr <= '0; + initiator0_pend_htrans <= '0; + initiator1_pend_htrans <= '0; + initiator0_pend_hsize <= '0; + initiator1_pend_hsize <= '0; + initiator0_pend_hwrite <= '0; + initiator1_pend_hwrite <= '0; + initiator0_pend_addr_ph_nq <= '0; + initiator1_pend_addr_ph_nq <= '0; + initiator0_data_ph_nq <= '0; + initiator1_data_ph_nq <= '0; + end + else begin + //Capture the address during the address phase for each initiator + initiator0_pend_haddr <= initiator0_address_ph & ~initiator0_pend_addr_ph ? haddr_i_0 : initiator0_pend_haddr; + initiator1_pend_haddr <= initiator1_address_ph & ~initiator1_pend_addr_ph ? haddr_i_1 : initiator1_pend_haddr; + initiator0_pend_htrans <= initiator0_address_ph & ~initiator0_pend_addr_ph ? htrans_i_0 : initiator0_pend_htrans; + initiator1_pend_htrans <= initiator1_address_ph & ~initiator1_pend_addr_ph ? htrans_i_1 : initiator1_pend_htrans; + initiator0_pend_hsize <= initiator0_address_ph & ~initiator0_pend_addr_ph ? hsize_i_0 : initiator0_pend_hsize; + initiator1_pend_hsize <= initiator1_address_ph & ~initiator1_pend_addr_ph ? hsize_i_1 : initiator1_pend_hsize; + initiator0_pend_hwrite <= initiator0_address_ph & ~initiator0_pend_addr_ph ? hwrite_i_0 : initiator0_pend_hwrite; + initiator1_pend_hwrite <= initiator1_address_ph & ~initiator1_pend_addr_ph ? hwrite_i_1 : initiator1_pend_hwrite; + + //Capture pending address phase when initiators collide + initiator0_pend_addr_ph_nq <= (initiator0_address_ph | initiator0_pend_addr_ph) & ~(hreadyout_i & initiator0_gnt); + initiator1_pend_addr_ph_nq <= (initiator1_address_ph | initiator1_pend_addr_ph) & ~(hreadyout_i & initiator1_gnt); + + //Transition to data phase when endpoint accepts address phase, hold when not ready + initiator0_data_ph_nq <= (initiator0_gnt) | (initiator0_data_ph & ~hreadyout_i); + initiator1_data_ph_nq <= (initiator1_gnt) | (initiator1_data_ph & ~hreadyout_i); + end +end + +always_comb initiator0_data_ph = initiator0_data_ph_nq & ~force_bus_idle; +always_comb initiator1_data_ph = initiator1_data_ph_nq & ~force_bus_idle; +always_comb initiator0_pend_addr_ph = initiator0_pend_addr_ph_nq & ~force_bus_idle; +always_comb initiator1_pend_addr_ph = initiator1_pend_addr_ph_nq & ~force_bus_idle; + +always_comb initiator0_haddr = initiator0_pend_addr_ph ? initiator0_pend_haddr : haddr_i_0; +always_comb initiator0_htrans = initiator0_pend_addr_ph ? initiator0_pend_htrans : htrans_i_0; +always_comb initiator0_hsize = initiator0_pend_addr_ph ? initiator0_pend_hsize : hsize_i_0; +always_comb initiator0_hwrite = initiator0_pend_addr_ph ? initiator0_pend_hwrite : hwrite_i_0; + +always_comb initiator1_haddr = initiator1_pend_addr_ph ? initiator1_pend_haddr : haddr_i_1; +always_comb initiator1_htrans = initiator1_pend_addr_ph ? initiator1_pend_htrans : htrans_i_1; +always_comb initiator1_hsize = initiator1_pend_addr_ph ? initiator1_pend_hsize : hsize_i_1; +always_comb initiator1_hwrite = initiator1_pend_addr_ph ? initiator1_pend_hwrite : hwrite_i_1; + +//Select the appropriate initiator +generate + if (AHB_NO_OPT) begin + //no optimization, data phase must complete before driving new address phase + //Initiator 0 gets priority + //Stall the grant only if initiator 1 is on its data phase + always_comb initiator0_gnt = (initiator0_address_ph | initiator0_pend_addr_ph) & ~initiator1_data_ph; + + //Initiator 1 gets through only if initiator 0 address phase isn't getting gnt, or in data phase + always_comb initiator1_gnt = (initiator1_address_ph | initiator1_pend_addr_ph) & ~initiator0_data_ph & ~initiator0_gnt; + end else begin + //optimized to allow addr phase to overlap data phase, assumes no stalls + //Initiator 0 gets priority + //Stall the grant if initiator 1 is processing a data phase and address phase b2b + always_comb initiator0_gnt = (initiator0_address_ph | initiator0_pend_addr_ph); + + //Initiator 1 gets through only if initiator 0 isn't getting granted + always_comb initiator1_gnt = (initiator1_address_ph | initiator1_pend_addr_ph) & ~initiator0_gnt; + + //optimized path doesn't look at stall + //only time this stalls is on error condition + `CALIPTRA_ASSERT_NEVER(ERR_2TO1MUX_STALL, ~hreadyout_i & (hresp_i == 1'b0), hclk, !hreset_n) + end +endgenerate + +//Mux the appropriate initiator and send out +//Keep driving initiator 1 controls on data phase if init0 isn't getting a grant in that cycle +always_comb haddr_o = initiator1_gnt | (initiator1_data_ph & ~initiator0_gnt) ? initiator1_haddr : initiator0_haddr; +always_comb htrans_o = initiator1_gnt | (initiator1_data_ph & ~initiator0_gnt) ? initiator1_htrans : initiator0_htrans; +always_comb hsize_o = initiator1_gnt | (initiator1_data_ph & ~initiator0_gnt) ? initiator1_hsize : initiator0_hsize; +always_comb hwrite_o = initiator1_gnt | (initiator1_data_ph & ~initiator0_gnt) ? initiator1_hwrite : initiator0_hwrite; +always_comb hsel_o = initiator1_gnt | (initiator1_data_ph & ~initiator0_gnt) ? hsel_i_1 : hsel_i_0; +always_comb hwdata_o = initiator1_gnt | (initiator1_data_ph & ~initiator0_gnt) ? hwdata_i_1 : hwdata_i_0; +always_comb hready_o = initiator1_gnt | (initiator1_data_ph & ~initiator0_gnt) ? (hready_i_1 | initiator1_pend_addr_ph) : (hready_i_0 | initiator0_pend_addr_ph); + +//Send response to the initiator +//Mask the ready when it's a pending address phase +//Send the data coming from responder when selected +always_comb hresp_o_0 = initiator0_data_ph ? hresp_i : '0; +always_comb hrdata_o_0 = initiator0_data_ph ? hrdata_i : '0; +always_comb hready_o_0 = initiator0_data_ph ? hreadyout_i : + initiator0_pend_addr_ph ? '0 : '1; + +always_comb hresp_o_1 = initiator1_data_ph? hresp_i: '0; +always_comb hrdata_o_1 = initiator1_data_ph ? hrdata_i: '0; +always_comb hready_o_1 = initiator1_data_ph ? hreadyout_i : + initiator1_pend_addr_ph ? '0 : '1; + +`CALIPTRA_ASSERT_MUTEX(ERR_2TO1MUX_MUTEX_DATA_PH, {initiator0_data_ph,initiator1_data_ph}, hclk, !hreset_n) +`CALIPTRA_ASSERT_NEVER(ERR_2TO1MUX_BAD_HTRANS, (htrans_o == 2'b01), hclk, !hreset_n) + +//Coverage +`ifndef VERILATOR +`ifdef FCOV + +covergroup ahb_lite_2to1_mux_cov_grp @(posedge hclk iff hreset_n); + option.per_instance = 1; + + init0_addr_cp: coverpoint initiator0_address_ph; + init0_pend_addr_cp: coverpoint initiator0_pend_addr_ph; + init0_data_cp: coverpoint initiator0_data_ph; + init0_gnt_cp : coverpoint initiator0_gnt; + + init1_addr_cp: coverpoint initiator1_address_ph; + init1_pend_addr_cp: coverpoint initiator1_pend_addr_ph; + init1_data_cp: coverpoint initiator1_data_ph; + init1_gnt_cp : coverpoint initiator1_gnt; + + init0_pend_addr_not_ready: coverpoint initiator0_pend_addr_ph & ~hreadyout_i; + init1_pend_addr_not_ready: coverpoint initiator1_pend_addr_ph & ~hreadyout_i; + + init0_data_not_ready: coverpoint initiator0_data_ph & ~hreadyout_i; + init1_data_not_ready: coverpoint initiator1_data_ph & ~hreadyout_i; + + init0_dataXinit1_gnt: cross init0_data_cp, init1_gnt_cp; + init1_dataXinit0_gnt: cross init1_data_cp, init0_gnt_cp; + + init0_addrXpend: cross init0_addr_cp, init0_pend_addr_cp; + init1_addrXpend: cross init1_addr_cp, init1_pend_addr_cp; + init0Xinit1_addr: cross init0_addr_cp, init1_addr_cp; + init0Xinit1_pend_addr: cross init0_pend_addr_cp, init1_pend_addr_cp; + +endgroup + + ahb_lite_2to1_mux_cov_grp ahb_lite_2to1_mux_cov_grp1 = new(); + +`endif +`endif +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/ahb_lite_address_decoder.sv b/designs/Caliptra/src/caliptra-rtl/ahb_lite_address_decoder.sv new file mode 100644 index 0000000..7f08755 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/ahb_lite_address_decoder.sv @@ -0,0 +1,232 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +// + +// ------------------------------------------------------------- +// AHB Lite Address Decoder +// ------------------------------------------------------------- + +module ahb_lite_address_decoder #( + parameter AHB_LITE_ADDR_WIDTH = 32, + parameter AHB_LITE_DATA_WIDTH = 32, + parameter NUM_RESPONDERS = 8 +) ( + // --------------------------------------- + // Global clock/reset + // --------------------------------------- + input logic hclk, + input logic hreset_n, + input logic force_bus_idle, + // --------------------------------------- + // From Initiator Interface Port + // --------------------------------------- + input logic [AHB_LITE_ADDR_WIDTH-1:0] haddr_i, + input logic [AHB_LITE_DATA_WIDTH-1:0] hwdata_i, + input logic hwrite_i, + input logic [1:0] htrans_i, + input logic [2:0] hsize_i, + + output logic hresp_o, + output logic hinitiatorready_o, + output logic [AHB_LITE_DATA_WIDTH-1:0] hrdata_o, + + // --------------------------------------- + // To Responder Interface Port + // --------------------------------------- + input logic [NUM_RESPONDERS-1:0] hresp_i, + input logic [NUM_RESPONDERS-1:0][AHB_LITE_DATA_WIDTH-1:0] hrdata_i, + input logic [NUM_RESPONDERS-1:0] hreadyout_i, + + output logic [NUM_RESPONDERS-1:0][AHB_LITE_ADDR_WIDTH-1:0] haddr_o, + output logic [NUM_RESPONDERS-1:0][AHB_LITE_DATA_WIDTH-1:0] hwdata_o, + output logic [NUM_RESPONDERS-1:0] hsel_o, + output logic [NUM_RESPONDERS-1:0] hwrite_o, + output logic [NUM_RESPONDERS-1:0] hresponderready_o, + output logic [NUM_RESPONDERS-1:0][1:0] htrans_o, + output logic [NUM_RESPONDERS-1:0][2:0] hsize_o, + + // ---------------------------------------------- + // Responder Disable + // ---------------------------------------------- + input logic [NUM_RESPONDERS-1:0] responder_disable_i, + output logic [NUM_RESPONDERS-1:0] access_blocked_o, + + // ----------------------------------------------- + // Responder Address Map (Start and End Addresses) + // ----------------------------------------------- + input logic [NUM_RESPONDERS-1:0][AHB_LITE_ADDR_WIDTH-1:0] responder_start_addr_i, + input logic [NUM_RESPONDERS-1:0][AHB_LITE_ADDR_WIDTH-1:0] responder_end_addr_i + +); + + localparam AHB_XFER_IDLE = 2'b00; + localparam AHB_XFER_BUSY = 2'b01; + localparam AHB_XFER_NONSEQ = 2'b10; + localparam AHB_XFER_SEQ = 2'b11; + + logic [NUM_RESPONDERS-1:0] pending_hsel; + logic hinitiator_ready_default; + logic hinitiator_ready_int; + logic hinitiator_ready_int_q; + logic [NUM_RESPONDERS-1:0] hsel_o_int_pre; + logic [NUM_RESPONDERS-1:0] hsel_blocked; + logic [NUM_RESPONDERS-1:0] hsel_o_int; + logic hresp_error; + logic hresp_error_r; + + logic [1:0] htrans_q; + + + always_comb htrans_q = force_bus_idle ? AHB_XFER_IDLE : htrans_i; + + // Decode the address to appropriate Responder HSEL + genvar resp_num; + generate + for (resp_num = 0; resp_num < NUM_RESPONDERS; resp_num++) begin: gen_responder_hsel + assign hsel_o_int_pre[resp_num] = ~force_bus_idle && (haddr_i >= responder_start_addr_i[resp_num]) && (haddr_i <= responder_end_addr_i[resp_num]); + assign hsel_blocked [resp_num] = hsel_o_int_pre[resp_num] && responder_disable_i[resp_num]; + assign hsel_o_int [resp_num] = hsel_o_int_pre[resp_num] && !responder_disable_i[resp_num]; + end + endgenerate + + // Pulse during address phase indicating an access was attempted to a disabled responder + always @(posedge hclk or negedge hreset_n) begin + if (!hreset_n) + access_blocked_o <= '0; + else if (|htrans_q && hinitiator_ready_int_q && |hsel_blocked) + access_blocked_o <= hsel_blocked; + else + access_blocked_o <= '0; + end + + always @(posedge hclk or negedge hreset_n) begin + if (!hreset_n) + pending_hsel <= '0; + else if (|htrans_q && hinitiator_ready_int_q) + pending_hsel <= hsel_o_int; + else if (hinitiator_ready_int_q) + pending_hsel <= '0; + end + + always_comb begin + // Only flag errors for NONSEQ or SEQ type transfers + // (BUSY transfers require OKAY response) + hresp_error = htrans_q inside {AHB_XFER_NONSEQ, AHB_XFER_SEQ} && hinitiator_ready_int_q && ~|hsel_o_int; + end + + always @(posedge hclk or negedge hreset_n) begin + if (!hreset_n) + hinitiator_ready_default <= 1'b1; + else + hinitiator_ready_default <= !hresp_error; + end + + always @(posedge hclk or negedge hreset_n) begin + if (!hreset_n) + hresp_error_r <= 1'b0; + else if (hresp_error) + hresp_error_r <= 1'b1; + else if (hinitiator_ready_int_q) + hresp_error_r <= 1'b0; + else + hresp_error_r <= hresp_error_r; + end + + // Drive the address phase of the AHB Lite Transaction + // For RDC force ready signal when we force the bus idle + always_comb begin + for (int rr = 0; rr < NUM_RESPONDERS; rr++) begin + hresponderready_o[rr] = hinitiator_ready_int_q; + hwrite_o[rr] = hwrite_i; + htrans_o[rr] = htrans_q; + hsize_o[rr] = hsize_i; + haddr_o[rr] = haddr_i; + hwdata_o[rr] = hwdata_i; + end + end + + // Use retimed select to drive response / data phase of the AHB Lite Transaction + // Default (for the case where an access does not hit any responder) is to + // return rdata = 0 and hresp = 1 + // This code will inject hresp = 1 for non-decoded addresses or blocked accesses + always_comb begin + hrdata_o = {AHB_LITE_DATA_WIDTH{1'b0}}; + hresp_o = hresp_error_r; + hinitiator_ready_int = hinitiator_ready_default; // Deassert for hresp = 1, first cycle + for (int rr = 0; rr < NUM_RESPONDERS; rr++) begin + if (hsel_o_int[rr] == 1'b1) begin + hinitiator_ready_int = hreadyout_i[rr]; + end + end + for (int rr = 0; rr < NUM_RESPONDERS; rr++) begin + if (pending_hsel[rr] == 1'b1) begin + hrdata_o = hrdata_i[rr]; + hresp_o = hresp_i[rr]; + hinitiator_ready_int = hreadyout_i[rr]; + end + end + hinitiator_ready_int_q = hinitiator_ready_int | force_bus_idle; + end + + assign hsel_o = hsel_o_int; + assign hinitiatorready_o = hinitiator_ready_int_q; + + // Assert that all AHB interfaces default to ready state, both out of + // reset and while idle. + // This demonstrates that there is no functional problem associated with the VeeR + // core bug that was reported and fixed in: + // https://github.com/chipsalliance/Cores-VeeR-EL2/pull/141 + generate + for (genvar rspr_ii=0; rspr_ii < NUM_RESPONDERS; rspr_ii++) begin: rspr_ready_loop + `ifdef CALIPTRA_INTERNAL_TRNG + localparam logic LOCAL_ASSERT_RSPR_RDY = 1'b1; + `else + // CSRNG/Entopy_src ahb interfaces are tied to 0 when not enabled + localparam logic LOCAL_ASSERT_RSPR_RDY = !(rspr_ii inside {`CALIPTRA_SLAVE_SEL_CSRNG, + `CALIPTRA_SLAVE_SEL_ENTROPY_SRC}); + `endif + if (LOCAL_ASSERT_RSPR_RDY) begin: rspr_ready_do_assert + `CALIPTRA_ASSERT(AHB_RSPR_RST_READY , $rose(hreset_n) |-> (hreadyout_i[rspr_ii] == 1'b1), hclk, !hreset_n) + // ICCM DMA and DCCM DMA are the same physical AHB endpoint, but with different offsets + // so hready deasserts simultaneously for both + if (rspr_ii inside {`CALIPTRA_SLAVE_SEL_DDMA,`CALIPTRA_SLAVE_SEL_IDMA}) begin: rspr_ready_rv_dma_merge + `CALIPTRA_ASSERT(AHB_RSPR_DFLT_READY, !pending_hsel[`CALIPTRA_SLAVE_SEL_DDMA] && !pending_hsel[`CALIPTRA_SLAVE_SEL_IDMA] |-> (hreadyout_i[rspr_ii] == 1'b1), hclk, !hreset_n) + end + else begin: rspr_ready_normal + `CALIPTRA_ASSERT(AHB_RSPR_DFLT_READY, !pending_hsel[rspr_ii] |-> (hreadyout_i[rspr_ii] == 1'b1), hclk, !hreset_n) + end + end + end + endgenerate + `CALIPTRA_ASSERT(AHB_INTR_RST_READY , $rose(hreset_n) |-> (hinitiatorready_o == 1'b1), hclk, !hreset_n) + `CALIPTRA_ASSERT(AHB_INTR_DFLT_READY, ~|pending_hsel && ~|access_blocked_o && ~|hresp_error_r |-> (hinitiatorready_o == 1'b1), hclk, !hreset_n) + +//Coverage +`ifndef VERILATOR +`ifdef FCOV + +covergroup ahb_lite_address_decode_cov_grp @(posedge hclk iff hreset_n); + option.per_instance = 1; + + access_blocked_cp: coverpoint |access_blocked_o {option.comment = "Received a transaction to a locked memory region";} + oob_access_cp: coverpoint |htrans_i && ~|hsel_o_int_pre {option.comment = "Received a transaction to an unmapped memory region";} + hresp_cp: coverpoint hresp_o {option.comment = "AHB Response - can be ERROR or OKAY";} +endgroup + + ahb_lite_address_decode_cov_grp ahb_lite_address_decode_cov_grp1 = new(); + +`endif +`endif + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/ahb_lite_bus.sv b/designs/Caliptra/src/caliptra-rtl/ahb_lite_bus.sv new file mode 100644 index 0000000..8e9124e --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/ahb_lite_bus.sv @@ -0,0 +1,148 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +// + +// ------------------------------------------------------------- +// AHB Lite Bus +// ------------------------------------------------------------- + +module ahb_lite_bus #( + parameter AHB_LITE_ADDR_WIDTH = 32, + parameter AHB_LITE_DATA_WIDTH = 32, + parameter NUM_RESPONDERS = 8 +) ( + // --------------------------------------- + // Global clock/reset + // --------------------------------------- + input logic hclk, + input logic hreset_n, + + // --------------------------------------- + // Initiator Interface Port + // --------------------------------------- + CALIPTRA_AHB_LITE_BUS_INF.Initiator_Interface_Ports ahb_lite_initiator, + + // -------------------------------------- + // Responder Interface Port + // -------------------------------------- + CALIPTRA_AHB_LITE_BUS_INF.Responder_Interface_Ports ahb_lite_responders[0:NUM_RESPONDERS-1], + + // ---------------------------------------------- + // Respnder Disable + // ---------------------------------------------- + input logic [NUM_RESPONDERS-1:0] ahb_lite_resp_disable_i, + output logic [NUM_RESPONDERS-1:0] ahb_lite_resp_access_blocked_o, + + // ---------------------------------------------- + // Responder Address Map (Start and End addresses) + // ---------------------------------------------- + input logic [NUM_RESPONDERS-1:0][AHB_LITE_ADDR_WIDTH-1:0] ahb_lite_start_addr_i, + input logic [NUM_RESPONDERS-1:0][AHB_LITE_ADDR_WIDTH-1:0] ahb_lite_end_addr_i, + + // ---------------------------------------------- + // Force bus idle during uc reset to prevent RDC violations + // ---------------------------------------------- + input logic force_bus_idle +); + + logic [NUM_RESPONDERS-1:0][AHB_LITE_ADDR_WIDTH-1:0] haddr; + logic [NUM_RESPONDERS-1:0][AHB_LITE_DATA_WIDTH-1:0] hwdata; + logic [NUM_RESPONDERS-1:0][AHB_LITE_DATA_WIDTH-1:0] hrdata; + logic [NUM_RESPONDERS-1:0] hsel; + logic [NUM_RESPONDERS-1:0] hwrite; + logic [NUM_RESPONDERS-1:0] hready; + logic [NUM_RESPONDERS-1:0][1:0] htrans; + logic [NUM_RESPONDERS-1:0][2:0] hsize; + logic [NUM_RESPONDERS-1:0] hresp; + logic [NUM_RESPONDERS-1:0] hreadyout; + + // Hook up the responder ports + + genvar ii; + generate + for (ii = 0; ii < NUM_RESPONDERS; ii++) begin: gen_responder_hook_up + assign ahb_lite_responders[ii].haddr = haddr[ii]; + assign ahb_lite_responders[ii].hwdata = hwdata[ii]; + assign ahb_lite_responders[ii].hsel = hsel[ii]; + assign ahb_lite_responders[ii].hwrite = hwrite[ii]; + assign ahb_lite_responders[ii].hready = hready[ii]; + assign ahb_lite_responders[ii].htrans = htrans[ii]; + assign ahb_lite_responders[ii].hsize = hsize[ii]; + + assign hrdata[ii] = ahb_lite_responders[ii].hrdata; + assign hresp[ii] = ahb_lite_responders[ii].hresp; + assign hreadyout[ii] = ahb_lite_responders[ii].hreadyout; + end + endgenerate + + // Instantiate AHB Lite Address Decoder + ahb_lite_address_decoder #( + .AHB_LITE_ADDR_WIDTH (AHB_LITE_ADDR_WIDTH), + .AHB_LITE_DATA_WIDTH (AHB_LITE_DATA_WIDTH), + .NUM_RESPONDERS (NUM_RESPONDERS) + ) u_ahb_lite_address_decoder ( + // ------------------------------------- + // Global clock/reset + // ------------------------------------- + .hclk (hclk), + .hreset_n (hreset_n), + + // -------------------------------------- + // From Initiator + // -------------------------------------- + + // Inputs + .haddr_i (ahb_lite_initiator.haddr), + .hwdata_i (ahb_lite_initiator.hwdata), + .hwrite_i (ahb_lite_initiator.hwrite), + .htrans_i (ahb_lite_initiator.htrans), + .hsize_i (ahb_lite_initiator.hsize), + // Outputs + .hresp_o (ahb_lite_initiator.hresp), + .hinitiatorready_o (ahb_lite_initiator.hreadyout), + .hrdata_o (ahb_lite_initiator.hrdata), + + // -------------------------------------- + // To Responder + // -------------------------------------- + + // Inputs + .hresp_i (hresp), + .hrdata_i (hrdata), + .hreadyout_i (hreadyout), + // Outputs + .haddr_o (haddr), + .hwdata_o (hwdata), + .hsel_o (hsel), + .hwrite_o (hwrite), + .hresponderready_o (hready), + .htrans_o (htrans), + .hsize_o (hsize), + + .force_bus_idle (force_bus_idle), + + // ---------------------------------------------- + // Responder Disable + // ---------------------------------------------- + .responder_disable_i (ahb_lite_resp_disable_i), + .access_blocked_o (ahb_lite_resp_access_blocked_o), + + // ----------------------------------------- + // Configuration Address Port + // ----------------------------------------- + .responder_start_addr_i (ahb_lite_start_addr_i), + .responder_end_addr_i (ahb_lite_end_addr_i) + + ); +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/ahb_lite_bus_inf.sv b/designs/Caliptra/src/caliptra-rtl/ahb_lite_bus_inf.sv new file mode 100644 index 0000000..d21c78b --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/ahb_lite_bus_inf.sv @@ -0,0 +1,61 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +// + +// ------------------------------------------------------------- +// AHB Lite Interface +// ------------------------------------------------------------- + +`ifndef CALIPTRA_AHB_LITE_BUS_INF +`define CALIPTRA_AHB_LITE_BUS_INF + +interface CALIPTRA_AHB_LITE_BUS_INF +#( + parameter AHB_LITE_ADDR_WIDTH = 32, + parameter AHB_LITE_DATA_WIDTH = 32 +); + + logic [AHB_LITE_ADDR_WIDTH-1:0] haddr; + logic [AHB_LITE_DATA_WIDTH-1:0] hwdata; + logic [AHB_LITE_DATA_WIDTH-1:0] hrdata; + logic hsel; + logic hwrite; + logic [2:0] hsize; + logic [1:0] htrans; + logic hready; + logic hreadyout; + logic hresp; + + // ---------------------------------- + // Initiator ports - single initiator + // ---------------------------------- + + modport Initiator_Interface_Ports ( + input haddr, hwdata, hwrite, hsize, htrans, // from AHB Initiator to AHB Responder + output hresp, hrdata, hreadyout // from AHB Responder to AHB Initiator + ); + + // ------------------------------------------- + // Responder Ports - go to multiple responders + // ------------------------------------------- + + modport Responder_Interface_Ports ( + input hresp, hrdata, hreadyout, // from AHB Responder to AHB Initiator + output haddr, hwdata, hsel, hwrite, hsize, htrans, hready // AHB Initiator to AHB Responder + ); + + +endinterface + +`endif //CALIPTRA_AHB_LITE_BUS_INF diff --git a/designs/Caliptra/src/caliptra-rtl/ahb_slv_sif.sv b/designs/Caliptra/src/caliptra-rtl/ahb_slv_sif.sv new file mode 100644 index 0000000..83a95e1 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/ahb_slv_sif.sv @@ -0,0 +1,174 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. + +module ahb_slv_sif + import ahb_defines_pkg::*; + #( + parameter AHB_DATA_WIDTH = 64 + ,parameter CLIENT_DATA_WIDTH = 32 + ,parameter AHB_ADDR_WIDTH = 32 + ,parameter CLIENT_ADDR_WIDTH = AHB_ADDR_WIDTH + + ) + ( + //AMBA AHB Lite INF + input logic hclk, + input logic hreset_n, + input logic [AHB_ADDR_WIDTH-1:0] haddr_i, + input logic [AHB_DATA_WIDTH-1:0] hwdata_i, + input logic hsel_i, + input logic hwrite_i, + + input logic hready_i, + input logic [1:0] htrans_i, + input logic [2:0] hsize_i, + + + output logic hresp_o, + output logic hreadyout_o, + output logic [AHB_DATA_WIDTH-1:0] hrdata_o, + + //COMPONENT INF + output logic dv, + input logic hld, + input logic err, + output logic write, + output logic [CLIENT_DATA_WIDTH-1:0] wdata, + output logic [CLIENT_ADDR_WIDTH-1:0] addr, + + input logic [CLIENT_DATA_WIDTH-1:0] rdata + ); + +logic err_f; +logic [2:0] size; + +localparam BITS_WDATA = $bits(wdata); + +//support bus widths: +//64b ahb, 32b client +//64b ahb, 64b client +generate + if ((AHB_DATA_WIDTH == 32) & (CLIENT_DATA_WIDTH == 32)) begin + always_comb begin + unique case (size) inside + 3'b000: //byte + //wdata = {{$bits(wdata)-8{1'b0}},hwdata_i[7:0]}; + wdata = {{BITS_WDATA-8{1'b0}},hwdata_i[7:0]}; + 3'b001: //halfword + //wdata = {{$bits(wdata)-16{1'b0}},hwdata_i[15:0]}; + wdata = {{BITS_WDATA-16{1'b0}},hwdata_i[15:0]}; + 3'b010: //word + wdata = hwdata_i[31:0]; + default: //word + wdata = hwdata_i[31:0]; + endcase + end + always_comb hrdata_o = rdata; + end else if ((AHB_DATA_WIDTH == 64) & (CLIENT_DATA_WIDTH == 32)) begin + always_comb begin + unique case (size) inside + 3'b000: //byte + //wdata = addr[2] ? {{$bits(wdata)-8{1'b0}},hwdata_i[39:32]} : {{$bits(wdata)-8{1'b0}},hwdata_i[7:0]}; + wdata = addr[2] ? {{BITS_WDATA-8{1'b0}},hwdata_i[39:32]} : {{BITS_WDATA-8{1'b0}},hwdata_i[7:0]}; + 3'b001: //halfword + //wdata = addr[2] ? {{$bits(wdata)-16{1'b0}},hwdata_i[47:32]} : {{$bits(wdata)-16{1'b0}},hwdata_i[15:0]}; + wdata = addr[2] ? {{BITS_WDATA-16{1'b0}},hwdata_i[47:32]} : {{BITS_WDATA-16{1'b0}},hwdata_i[15:0]}; + 3'b010: //word + wdata = addr[2] ? hwdata_i[63:32] : hwdata_i[31:0]; + default: //word + wdata = addr[2] ? hwdata_i[63:32] : hwdata_i[31:0]; + endcase + end + always_comb hrdata_o = addr[2] ? {rdata, 32'b0} : {32'b0, rdata}; + end else if ((AHB_DATA_WIDTH == 64) & (CLIENT_DATA_WIDTH == 64)) begin + always_comb begin + unique case (size) inside + 3'b000: //byte + //wdata = {{$bits(wdata)-8{1'b0}},hwdata_i[7:0]}; + wdata = {{BITS_WDATA-8{1'b0}},hwdata_i[7:0]}; + 3'b001: //halfword + //wdata = {{$bits(wdata)-16{1'b0}},hwdata_i[15:0]}; + wdata = {{BITS_WDATA-16{1'b0}},hwdata_i[15:0]}; + 3'b010: //word + wdata = addr[2]? hwdata_i[63:32] : hwdata_i[31:0]; + 3'b011: //dword + wdata = hwdata_i; + default: //dword + wdata = hwdata_i; + endcase + end + always_comb hrdata_o = rdata; + end + +endgenerate + + always_ff @(posedge hclk or negedge hreset_n) begin + if(!hreset_n) begin + dv <= 1'b0; + write <= 1'b0; + addr <= '0; + err_f <= '0; + size <= '0; + end + else begin + err_f <= err; + if (hready_i) begin + dv <= hsel_i & htrans_i inside {2'b10, 2'b11}; + end + // Clear dv as soon as the component responds + // (in case of error, hready_i will still be 0 due to hreadyout_o == 0) + else if (dv && !hld) begin + dv <= 1'b0; + end + if(hready_i & hsel_i) begin + addr <= haddr_i[CLIENT_ADDR_WIDTH-1:0]; + write <= hwrite_i & |htrans_i; + size <= hsize_i; + end + end + end + +always_comb begin : response_block + hreadyout_o = 1'b1; + hresp_o = H_OKAY; + //first err cycle, de-assert ready and drive err + if (err & ~err_f) begin + hreadyout_o = 1'b0; + hresp_o = H_ERROR; + end else if (dv & hld) begin + hreadyout_o = 1'b0; + hresp_o = H_OKAY; + end else if (err_f) begin + hreadyout_o = 1'b1; + hresp_o = H_ERROR; + end +end + +//Coverage +`ifndef VERILATOR +`ifdef FCOV + +covergroup ahb_slv_sif_cov_grp @(posedge hclk); + option.per_instance = 1; + + ahb_read_cp: coverpoint (dv & ~write) {option.comment = "AHB read transaction";} + ahb_write_cp: coverpoint (dv & write) {option.comment = "AHB write transaction";} +endgroup + +ahb_slv_sif_cov_grp ahb_slv_sif_cov_grp1 = new(); + +`endif +`endif + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/ahb_to_axi4.sv b/designs/Caliptra/src/caliptra-rtl/ahb_to_axi4.sv new file mode 100644 index 0000000..ebef0ca --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/ahb_to_axi4.sv @@ -0,0 +1,331 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2020 Western Digital Corporation or its affiliates. +// +// 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. +//******************************************************************************** +// $Id$ +// +// Owner: +// Function: AHB to AXI4 Bridge +// Comments: +// +//******************************************************************************** +module ahb_to_axi4 +import el2_pkg::*; +#( + TAG = 1, + CHECK_RANGES = 1, + `include "el2_param.vh" +) +( + input clk, + input rst_l, + /* pragma coverage off */ + input scan_mode, + /* pragma coverage on */ + input bus_clk_en, + input clk_override, + + // AXI signals + // AXI Write Channels + output logic axi_awvalid, + input logic axi_awready, + /* exclude signals that are tied to constant value in this file */ + /*pragma coverage off*/ + output logic [TAG-1:0] axi_awid, + /*pragma coverage on*/ + output logic [31:0] axi_awaddr, + output logic [2:0] axi_awsize, + /* exclude signals that are tied to constant value in this file */ + /*pragma coverage off*/ + output logic [2:0] axi_awprot, + output logic [7:0] axi_awlen, + output logic [1:0] axi_awburst, + /*pragma coverage on*/ + + output logic axi_wvalid, + input logic axi_wready, + output logic [63:0] axi_wdata, + output logic [7:0] axi_wstrb, + /* exclude signals that are tied to constant value in this file */ + /*pragma coverage off*/ + output logic axi_wlast, + /*pragma coverage on*/ + + input logic axi_bvalid, + /* exclude signals that are tied to constant value in this file */ + /*pragma coverage off*/ + output logic axi_bready, + /*pragma coverage on*/ + input logic [1:0] axi_bresp, + /* Exclude unused AXI rid since it has no equivalent in AHB */ + /*pragma coverage off*/ + input logic [TAG-1:0] axi_bid, + /*pragma coverage on*/ + + // AXI Read Channels + output logic axi_arvalid, + input logic axi_arready, + /* exclude signals that are tied to constant value in this file */ + /*pragma coverage off*/ + output logic [TAG-1:0] axi_arid, + /*pragma coverage on*/ + output logic [31:0] axi_araddr, + output logic [2:0] axi_arsize, + /* exclude signals that are tied to constant value in this file */ + /*pragma coverage off*/ + output logic [2:0] axi_arprot, + output logic [7:0] axi_arlen, + output logic [1:0] axi_arburst, + /*pragma coverage on*/ + + input logic axi_rvalid, + /* exclude signals that are tied to constant value in this file */ + /*pragma coverage off*/ + output logic axi_rready, + /*pragma coverage on*/ + /* Exclude unused AXI rid since it has no equivalent in AHB */ + /*pragma coverage off*/ + input logic [TAG-1:0] axi_rid, + /*pragma coverage on*/ + input logic [63:0] axi_rdata, + input logic [1:0] axi_rresp, + + // AHB-Lite signals + input logic [31:0] ahb_haddr, // ahb bus address + // Exclude input signals that are unused in this file (their AXI equivalents + // are tied to constants) + /*pragma coverage off*/ + input logic [2:0] ahb_hburst, // tied to 0 + input logic ahb_hmastlock, // tied to 0 + input logic [3:0] ahb_hprot, // tied to 4'b0011 + /*pragma coverage on*/ + input logic [2:0] ahb_hsize, // size of bus transaction (possible values 0,1,2,3) + input logic [1:0] ahb_htrans, // Transaction type (possible values 0,2 only right now) + input logic ahb_hwrite, // ahb bus write + input logic [63:0] ahb_hwdata, // ahb bus write data + input logic ahb_hsel, // this slave was selected + input logic ahb_hreadyin, // previous hready was accepted or not + + output logic [63:0] ahb_hrdata, // ahb bus read data + output logic ahb_hreadyout, // slave ready to accept transaction + output logic ahb_hresp // slave response (high indicates erro) + +); + + logic [7:0] master_wstrb; + + typedef enum logic [1:0] { IDLE = 2'b00, // Nothing in the buffer. No commands yet recieved + WR = 2'b01, // Write Command recieved + RD = 2'b10, // Read Command recieved + PEND = 2'b11 // Waiting on Read Data from core + } state_t; + state_t buf_state, buf_nxtstate; + logic buf_state_en; + + // Buffer signals (one entry buffer) + logic buf_read_error_in, buf_read_error; + logic [63:0] buf_rdata; + + logic ahb_hready; + logic ahb_hready_q; + logic [1:0] ahb_htrans_in, ahb_htrans_q; + logic [2:0] ahb_hsize_q; + logic ahb_hwrite_q; + logic [31:0] ahb_haddr_q; + logic ahb_hresp_q; + + // signals needed for the read data coming back from the core and to block any further commands as AHB is a blocking bus + logic buf_rdata_en; + + logic ahb_addr_clk_en, buf_rdata_clk_en; + logic bus_clk, ahb_addr_clk, buf_rdata_clk; + // Command buffer is the holding station where we convert to AXI and send to core + logic cmdbuf_wr_en, cmdbuf_rst; + logic cmdbuf_full; + logic cmdbuf_vld, cmdbuf_write; + logic [1:0] cmdbuf_size; + logic [7:0] cmdbuf_wstrb; + logic [31:0] cmdbuf_addr; + logic [63:0] cmdbuf_wdata; + +// FSM to control the bus states and when to block the hready and load the command buffer + always_comb begin + buf_nxtstate = IDLE; + buf_state_en = 1'b0; + buf_rdata_en = 1'b0; // signal to load the buffer when the core sends read data back + buf_read_error_in = 1'b0; // signal indicating that an error came back with the read from the core + cmdbuf_wr_en = 1'b0; // all clear from the gasket to load the buffer with the command for reads, command/dat for writes + case (buf_state) + IDLE: begin // No commands recieved + buf_nxtstate = ahb_hwrite ? WR : RD; + buf_state_en = ahb_hready & ahb_htrans[1] & ahb_hsel; // only transition on a valid hrtans + end + WR: begin // Write command recieved last cycle + buf_nxtstate = (ahb_hresp | (ahb_htrans[1:0] == 2'b0) | ~ahb_hsel) ? IDLE : ahb_hwrite ? WR : RD; + buf_state_en = (~cmdbuf_full | ahb_hresp) ; + cmdbuf_wr_en = ~cmdbuf_full & ~(ahb_hresp | ((ahb_htrans[1:0] == 2'b01) & ahb_hsel)); // Dont send command to the buffer in case of an error or when the master is not ready with the data now. + end + RD: begin // Read command recieved last cycle. + buf_nxtstate = ahb_hresp ? IDLE :PEND; // If error go to idle, else wait for read data + buf_state_en = (~cmdbuf_full | ahb_hresp); // only when command can go, or if its an error + cmdbuf_wr_en = ~ahb_hresp & ~cmdbuf_full; // send command only when no error + end + PEND: begin // Read Command has been sent. Waiting on Data. + buf_nxtstate = IDLE; // go back for next command and present data next cycle + buf_state_en = axi_rvalid & ~cmdbuf_write; // read data is back + buf_rdata_en = buf_state_en; // buffer the read data coming back from core + buf_read_error_in = buf_state_en & |axi_rresp[1:0]; // buffer error flag if return has Error ( ECC ) + end + endcase + end // always_comb begin + + rvdffs_fpga #($bits(state_t)) state_reg (.*, .din(buf_nxtstate), .dout({buf_state}), .en(buf_state_en), .clk(bus_clk), .clken(bus_clk_en), .rawclk(clk)); + + assign master_wstrb[7:0] = ({8{ahb_hsize_q[2:0] == 3'b0}} & (8'b1 << ahb_haddr_q[2:0])) | + ({8{ahb_hsize_q[2:0] == 3'b1}} & (8'b11 << ahb_haddr_q[2:0])) | + ({8{ahb_hsize_q[2:0] == 3'b10}} & (8'b1111 << ahb_haddr_q[2:0])) | + ({8{ahb_hsize_q[2:0] == 3'b11}} & 8'b1111_1111); + + // AHB signals + assign ahb_hreadyout = ahb_hresp ? (ahb_hresp_q & ~ahb_hready_q) : + ((~cmdbuf_full | (buf_state == IDLE)) & ~(buf_state == RD | buf_state == PEND) & ~buf_read_error); + + assign ahb_hready = ahb_hreadyout & ahb_hreadyin; + assign ahb_htrans_in[1:0] = {2{ahb_hsel}} & ahb_htrans[1:0]; + assign ahb_hrdata[63:0] = buf_rdata[63:0]; + + if (CHECK_RANGES) begin + // Miscellaneous signals + logic ahb_addr_in_dccm, ahb_addr_in_iccm, ahb_addr_in_pic; + logic ahb_addr_in_dccm_region_nc, ahb_addr_in_iccm_region_nc, ahb_addr_in_pic_region_nc; + + assign ahb_hresp = ((ahb_htrans_q[1:0] != 2'b0) & (buf_state != IDLE) & + ((~(ahb_addr_in_dccm | ahb_addr_in_iccm)) | // request not for ICCM or DCCM + ((ahb_addr_in_iccm | (ahb_addr_in_dccm & ahb_hwrite_q)) & ~((ahb_hsize_q[1:0] == 2'b10) | (ahb_hsize_q[1:0] == 2'b11))) | // ICCM Rd/Wr OR DCCM Wr not the right size + ((ahb_hsize_q[2:0] == 3'h1) & ahb_haddr_q[0]) | // HW size but unaligned + ((ahb_hsize_q[2:0] == 3'h2) & (|ahb_haddr_q[1:0])) | // W size but unaligned + ((ahb_hsize_q[2:0] == 3'h3) & (|ahb_haddr_q[2:0])))) | // DW size but unaligned + buf_read_error | // Read ECC error + (ahb_hresp_q & ~ahb_hready_q); + + // Address check dccm + rvrangecheck #(.CCM_SADR(pt.DCCM_SADR), + .CCM_SIZE(pt.DCCM_SIZE)) addr_dccm_rangecheck ( + .addr(ahb_haddr_q[31:0]), + .in_range(ahb_addr_in_dccm), + .in_region(ahb_addr_in_dccm_region_nc) + ); + + // Address check iccm + if (pt.ICCM_ENABLE == 1) begin: GenICCM + rvrangecheck #(.CCM_SADR(pt.ICCM_SADR), + .CCM_SIZE(pt.ICCM_SIZE)) addr_iccm_rangecheck ( + .addr(ahb_haddr_q[31:0]), + .in_range(ahb_addr_in_iccm), + .in_region(ahb_addr_in_iccm_region_nc) + ); + end else begin: GenNoICCM + assign ahb_addr_in_iccm = '0; + assign ahb_addr_in_iccm_region_nc = '0; + end + + // PIC memory address check + rvrangecheck #(.CCM_SADR(pt.PIC_BASE_ADDR), + .CCM_SIZE(pt.PIC_SIZE)) addr_pic_rangecheck ( + .addr(ahb_haddr_q[31:0]), + .in_range(ahb_addr_in_pic), + .in_region(ahb_addr_in_pic_region_nc) + ); + end else begin // !CHECK_RANGES + assign ahb_hresp = ((ahb_htrans_q[1:0] != 2'b0) & (buf_state != IDLE) & + (((ahb_hsize_q[2:0] == 3'h1) & ahb_haddr_q[0]) | // HW size but unaligned + ((ahb_hsize_q[2:0] == 3'h2) & (|ahb_haddr_q[1:0])) | // W size but unaligned + ((ahb_hsize_q[2:0] == 3'h3) & (|ahb_haddr_q[2:0])))) | // DW size but unaligned + buf_read_error | // Read ECC error + (ahb_hresp_q & ~ahb_hready_q); + end // CHECK_RANGES + + // Buffer signals - needed for the read data and ECC error response + rvdff_fpga #(.WIDTH(64)) buf_rdata_ff (.din(axi_rdata[63:0]), .dout(buf_rdata[63:0]), .clk(buf_rdata_clk), .clken(buf_rdata_clk_en), .rawclk(clk), .*); + rvdff_fpga #(.WIDTH(1)) buf_read_error_ff(.din(buf_read_error_in), .dout(buf_read_error), .clk(bus_clk), .clken(bus_clk_en), .rawclk(clk), .*); // buf_read_error will be high only one cycle + + // All the Master signals are captured before presenting it to the command buffer. We check for Hresp before sending it to the cmd buffer. + rvdff_fpga #(.WIDTH(1)) hresp_ff (.din(ahb_hresp), .dout(ahb_hresp_q), .clk(bus_clk), .clken(bus_clk_en), .rawclk(clk), .*); + rvdff_fpga #(.WIDTH(1)) hready_ff (.din(ahb_hready), .dout(ahb_hready_q), .clk(bus_clk), .clken(bus_clk_en), .rawclk(clk), .*); + rvdff_fpga #(.WIDTH(2)) htrans_ff (.din(ahb_htrans_in[1:0]), .dout(ahb_htrans_q[1:0]), .clk(bus_clk), .clken(bus_clk_en), .rawclk(clk), .*); + rvdff_fpga #(.WIDTH(3)) hsize_ff (.din(ahb_hsize[2:0]), .dout(ahb_hsize_q[2:0]), .clk(ahb_addr_clk), .clken(ahb_addr_clk_en), .rawclk(clk), .*); + rvdff_fpga #(.WIDTH(1)) hwrite_ff (.din(ahb_hwrite), .dout(ahb_hwrite_q), .clk(ahb_addr_clk), .clken(ahb_addr_clk_en), .rawclk(clk), .*); + rvdff_fpga #(.WIDTH(32)) haddr_ff (.din(ahb_haddr[31:0]), .dout(ahb_haddr_q[31:0]), .clk(ahb_addr_clk), .clken(ahb_addr_clk_en), .rawclk(clk), .*); + + // Command Buffer - Holding for the commands to be sent for the AXI. It will be converted to the AXI signals. + assign cmdbuf_rst = (((axi_awvalid & axi_awready) | (axi_arvalid & axi_arready)) & ~cmdbuf_wr_en) | (ahb_hresp & ~cmdbuf_write); + assign cmdbuf_full = (cmdbuf_vld & ~((axi_awvalid & axi_awready) | (axi_arvalid & axi_arready))); + + rvdffsc_fpga #(.WIDTH(1)) cmdbuf_vldff (.din(1'b1), .dout(cmdbuf_vld), .en(cmdbuf_wr_en), .clear(cmdbuf_rst), .clk(bus_clk), .clken(bus_clk_en), .rawclk(clk), .*); + rvdffs_fpga #(.WIDTH(1)) cmdbuf_writeff (.din(ahb_hwrite_q), .dout(cmdbuf_write), .en(cmdbuf_wr_en), .clk(bus_clk), .clken(bus_clk_en), .rawclk(clk), .*); + rvdffs_fpga #(.WIDTH(2)) cmdbuf_sizeff (.din(ahb_hsize_q[1:0]), .dout(cmdbuf_size[1:0]), .en(cmdbuf_wr_en), .clk(bus_clk), .clken(bus_clk_en), .rawclk(clk), .*); + rvdffs_fpga #(.WIDTH(8)) cmdbuf_wstrbff (.din(master_wstrb[7:0]), .dout(cmdbuf_wstrb[7:0]), .en(cmdbuf_wr_en), .clk(bus_clk), .clken(bus_clk_en), .rawclk(clk), .*); + rvdffe #(.WIDTH(32)) cmdbuf_addrff (.din(ahb_haddr_q[31:0]), .dout(cmdbuf_addr[31:0]), .en(cmdbuf_wr_en & bus_clk_en), .clk(clk), .*); + rvdffe #(.WIDTH(64)) cmdbuf_wdataff (.din(ahb_hwdata[63:0]), .dout(cmdbuf_wdata[63:0]), .en(cmdbuf_wr_en & bus_clk_en), .clk(clk), .*); + + // AXI Write Command Channel + assign axi_awvalid = cmdbuf_vld & cmdbuf_write; + assign axi_awid[TAG-1:0] = '0; + assign axi_awaddr[31:0] = cmdbuf_addr[31:0]; + assign axi_awsize[2:0] = {1'b0, cmdbuf_size[1:0]}; + assign axi_awprot[2:0] = 3'b0; + assign axi_awlen[7:0] = '0; + assign axi_awburst[1:0] = 2'b01; + // AXI Write Data Channel - This is tied to the command channel as we only write the command buffer once we have the data. + assign axi_wvalid = cmdbuf_vld & cmdbuf_write; + assign axi_wdata[63:0] = cmdbuf_wdata[63:0]; + assign axi_wstrb[7:0] = cmdbuf_wstrb[7:0]; + assign axi_wlast = 1'b1; + // AXI Write Response - Always ready. AHB does not require a write response. + assign axi_bready = 1'b1; + // AXI Read Channels + assign axi_arvalid = cmdbuf_vld & ~cmdbuf_write; + assign axi_arid[TAG-1:0] = '0; + assign axi_araddr[31:0] = cmdbuf_addr[31:0]; + assign axi_arsize[2:0] = {1'b0, cmdbuf_size[1:0]}; + assign axi_arprot = 3'b0; + assign axi_arlen[7:0] = '0; + assign axi_arburst[1:0] = 2'b01; + // AXI Read Response Channel - Always ready as AHB reads are blocking and the the buffer is available for the read coming back always. + assign axi_rready = 1'b1; + + // Clock header logic + assign ahb_addr_clk_en = bus_clk_en & (ahb_hready & ahb_htrans[1]); + assign buf_rdata_clk_en = bus_clk_en & buf_rdata_en; + +`ifdef RV_FPGA_OPTIMIZE + assign bus_clk = 1'b0; + assign ahb_addr_clk = 1'b0; + assign buf_rdata_clk = 1'b0; +`else + rvclkhdr bus_cgc (.en(bus_clk_en), .l1clk(bus_clk), .*); + rvclkhdr ahb_addr_cgc (.en(ahb_addr_clk_en), .l1clk(ahb_addr_clk), .*); + rvclkhdr buf_rdata_cgc (.en(buf_rdata_clk_en), .l1clk(buf_rdata_clk), .*); +`endif + +`ifdef RV_ASSERT_ON + property ahb_error_protocol; + @(posedge bus_clk) (ahb_hready & ahb_hresp) |-> (~$past(ahb_hready) & $past(ahb_hresp)); + endproperty + assert_ahb_error_protocol: assert property (ahb_error_protocol) else + $display("Bus Error with hReady isn't preceded with Bus Error without hready"); + +`endif + +endmodule // ahb_to_axi4 diff --git a/designs/Caliptra/src/caliptra-rtl/ahb_to_reg_adapter.sv b/designs/Caliptra/src/caliptra-rtl/ahb_to_reg_adapter.sv new file mode 100644 index 0000000..f395835 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/ahb_to_reg_adapter.sv @@ -0,0 +1,65 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +//====================================================================== +// +// ahb_to_reg_adapter.sv +// -------- +// This module converts the output of the ahb slave interface to a register +// interface. +// +//====================================================================== + + +module ahb_to_reg_adapter#( + parameter DATA_WIDTH = 32, + parameter DATA_BYTE_WIDTH = DATA_WIDTH / 8, + parameter ADDR_WIDTH = 32 + ) ( + input logic clk, + input logic rst_n, + // Signals from ahb slave interface + input logic ahb_reg_dv, + output logic ahb_reg_hld, + output logic ahb_reg_err, + input logic ahb_reg_write, + input logic [DATA_WIDTH-1:0] ahb_reg_wdata, + input logic [ADDR_WIDTH-1:0] ahb_reg_addr, + output logic [DATA_WIDTH-1:0] ahb_reg_rdata, + // register interface signals + output logic reg_we, + output logic reg_re, + output logic [ADDR_WIDTH-1:0] reg_addr, + output logic [DATA_WIDTH-1:0] reg_wdata, + output logic [DATA_BYTE_WIDTH-1:0] reg_be, + input logic [DATA_WIDTH-1:0] reg_rdata, + input logic reg_error, + input logic reg_busy + ); + + always_comb begin + // default + ahb_reg_rdata = reg_rdata; + ahb_reg_err = reg_error; + ahb_reg_hld = reg_busy; + reg_addr = ahb_reg_addr; + reg_wdata = ahb_reg_wdata; + reg_we = ahb_reg_dv && ahb_reg_write && !ahb_reg_hld; + end + + assign reg_re = ahb_reg_dv && !ahb_reg_write; + + // Write all bytes at any given time. The AHB interface module only accepts hsize_i + // when it is set to 'h2 = Word(32b) and 'h3 = Double Word(64b). + assign reg_be = {DATA_BYTE_WIDTH{1'b1}}; +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/axi4_to_ahb.sv b/designs/Caliptra/src/caliptra-rtl/axi4_to_ahb.sv new file mode 100644 index 0000000..86e5166 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/axi4_to_ahb.sv @@ -0,0 +1,505 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2020 Western Digital Corporation or its affiliates. +// +// 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. + +//******************************************************************************** +// $Id$ +// +// Owner: +// Function: AXI4 -> AHB Bridge +// Comments: +// +//******************************************************************************** +module axi4_to_ahb +import el2_pkg::*; +#( +`include "el2_param.vh" +,parameter TAG = 1) ( + + input clk, + input free_clk, + input rst_l, + // Excluding scan_mode from coverage as its usage is determined by the integrator of the VeeR core. + /*pragma coverage off*/ + input scan_mode, + /*pragma coverage on*/ + input bus_clk_en, + input clk_override, + input dec_tlu_force_halt, + + // AXI signals + // AXI Write Channels + input logic axi_awvalid, + output logic axi_awready, + input logic [TAG-1:0] axi_awid, + input logic [31:0] axi_awaddr, + input logic [2:0] axi_awsize, + input logic [2:0] axi_awprot, + + input logic axi_wvalid, + output logic axi_wready, + input logic [63:0] axi_wdata, + input logic [7:0] axi_wstrb, + input logic axi_wlast, + + output logic axi_bvalid, + input logic axi_bready, + output logic [1:0] axi_bresp, + output logic [TAG-1:0] axi_bid, + + // AXI Read Channels + input logic axi_arvalid, + output logic axi_arready, + input logic [TAG-1:0] axi_arid, + input logic [31:0] axi_araddr, + input logic [2:0] axi_arsize, + input logic [2:0] axi_arprot, + + output logic axi_rvalid, + input logic axi_rready, + output logic [TAG-1:0] axi_rid, + output logic [63:0] axi_rdata, + output logic [1:0] axi_rresp, + output logic axi_rlast, + + // AHB-Lite signals + output logic [31:0] ahb_haddr, // ahb bus address + /* exclude signals that are tied to constant value in this file */ + /*pragma coverage off*/ + output logic [2:0] ahb_hburst, // tied to 0 + output logic ahb_hmastlock, // tied to 0 + /*pragma coverage on*/ + output logic [3:0] ahb_hprot, // [3:1] are tied to 3'b001 + output logic [2:0] ahb_hsize, // size of bus transaction (possible values 0,1,2,3) + output logic [1:0] ahb_htrans, // Transaction type (possible values 0,2 only right now) + output logic ahb_hwrite, // ahb bus write + output logic [63:0] ahb_hwdata, // ahb bus write data + + input logic [63:0] ahb_hrdata, // ahb bus read data + input logic ahb_hready, // slave ready to accept transaction + input logic ahb_hresp // slave response (high indicates erro) + +); + + localparam ID = 1; + localparam PRTY = 1; + typedef enum logic [3:0] { + IDLE = 4'b0000, + CMD_RD = 4'b0001, + CMD_WR = 4'b1001, + DATA_RD = 4'b0010, + DATA_WR = 4'b1010, + DONE_RD = 4'b0011, + DONE_WR = 4'b1011, + STREAM_RD = 4'b0101, + STREAM_ERR_RD = 4'b0110 + } state_t; + + state_t buf_state, buf_nxtstate; + + logic slave_valid; + logic [TAG-1:0] slave_tag; + logic [63:0] slave_rdata; + logic [3:0] slave_opc; + + logic wrbuf_en, wrbuf_data_en; + logic wrbuf_cmd_sent, wrbuf_rst; + logic wrbuf_vld; + logic wrbuf_data_vld; + logic [TAG-1:0] wrbuf_tag; + logic [2:0] wrbuf_size; + logic [31:0] wrbuf_addr; + logic [63:0] wrbuf_data; + logic [7:0] wrbuf_byteen; + + logic master_valid; + logic master_ready; + logic [TAG-1:0] master_tag; + logic [31:0] master_addr; + logic [63:0] master_wdata; + logic [2:0] master_size; + logic [2:0] master_opc; + logic [7:0] master_byteen; + + // Buffer signals (one entry buffer) + logic [31:0] buf_addr; + logic [1:0] buf_size; + logic buf_write; + logic [7:0] buf_byteen; + logic buf_aligned; + logic [63:0] buf_data; + logic [TAG-1:0] buf_tag; + + //Miscellaneous signals + logic buf_rst; + logic [TAG-1:0] buf_tag_in; + logic [31:0] buf_addr_in; + logic [7:0] buf_byteen_in; + logic [63:0] buf_data_in; + logic buf_write_in; + logic buf_aligned_in; + logic [2:0] buf_size_in; + + logic buf_state_en; + logic buf_wr_en; + logic buf_data_wr_en; + logic slvbuf_error_en; + logic wr_cmd_vld; + + logic cmd_done_rst, cmd_done, cmd_doneQ; + logic trxn_done; + logic [2:0] buf_cmd_byte_ptr, buf_cmd_byte_ptrQ, buf_cmd_nxtbyte_ptr; + logic buf_cmd_byte_ptr_en; + logic found; + + logic slave_valid_pre; + logic ahb_hready_q; + logic ahb_hresp_q; + logic [1:0] ahb_htrans_q; + logic ahb_hwrite_q; + logic [63:0] ahb_hrdata_q; + + + logic slvbuf_write; + logic slvbuf_error; + logic [TAG-1:0] slvbuf_tag; + + logic slvbuf_error_in; + logic slvbuf_wr_en; + logic bypass_en; + logic rd_bypass_idle; + + logic last_addr_en; + logic [31:0] last_bus_addr; + + // Clocks + logic buf_clken; + logic ahbm_data_clken; + + logic buf_clk; + logic bus_clk; + logic ahbm_data_clk; + + logic dec_tlu_force_halt_bus, dec_tlu_force_halt_bus_ns, dec_tlu_force_halt_bus_q; + + // Function to get the length from byte enable + function automatic logic [1:0] get_write_size; + input logic [7:0] byteen; + + logic [1:0] size; + + size[1:0] = (2'b11 & {2{(byteen[7:0] == 8'hff)}}) | + (2'b10 & {2{((byteen[7:0] == 8'hf0) | (byteen[7:0] == 8'h0f))}}) | + (2'b01 & {2{((byteen[7:0] == 8'hc0) | (byteen[7:0] == 8'h30) | (byteen[7:0] == 8'h0c) | (byteen[7:0] == 8'h03))}}); + + return size[1:0]; + endfunction // get_write_size + + // Function to get the length from byte enable + function automatic logic [2:0] get_write_addr; + input logic [7:0] byteen; + + logic [2:0] addr; + + addr[2:0] = (3'h0 & {3{((byteen[7:0] == 8'hff) | (byteen[7:0] == 8'h0f) | (byteen[7:0] == 8'h03))}}) | + (3'h2 & {3{(byteen[7:0] == 8'h0c)}}) | + (3'h4 & {3{((byteen[7:0] == 8'hf0) | (byteen[7:0] == 8'h03))}}) | + (3'h6 & {3{(byteen[7:0] == 8'hc0)}}); + + return addr[2:0]; + endfunction // get_write_addr + + // Function to get the next byte pointer + function automatic logic [2:0] get_nxtbyte_ptr (logic [2:0] current_byte_ptr, logic [7:0] byteen, logic get_next); + logic [2:0] start_ptr; + logic found; + found = '0; + get_nxtbyte_ptr[2:0] = 3'd0; + start_ptr[2:0] = get_next ? (current_byte_ptr[2:0] + 3'b1) : current_byte_ptr[2:0]; + for (int j=0; j<8; j++) begin + if (~found) begin + get_nxtbyte_ptr[2:0] = 3'(j); + found |= (byteen[j] & (3'(j) >= start_ptr[2:0])) ; + end + end + endfunction // get_nextbyte_ptr + + // Create bus synchronized version of force halt + assign dec_tlu_force_halt_bus = dec_tlu_force_halt | dec_tlu_force_halt_bus_q; + assign dec_tlu_force_halt_bus_ns = ~bus_clk_en & dec_tlu_force_halt_bus; + rvdff #(.WIDTH(1)) force_halt_busff(.din(dec_tlu_force_halt_bus_ns), .dout(dec_tlu_force_halt_bus_q), .clk(free_clk), .*); + + // Write buffer + assign wrbuf_en = axi_awvalid & axi_awready & master_ready; + assign wrbuf_data_en = axi_wvalid & axi_wready & master_ready; + assign wrbuf_cmd_sent = master_valid & master_ready & (master_opc[2:1] == 2'b01); + assign wrbuf_rst = (wrbuf_cmd_sent & ~wrbuf_en) | dec_tlu_force_halt_bus; + + assign axi_awready = ~(wrbuf_vld & ~wrbuf_cmd_sent) & master_ready; + assign axi_wready = ~(wrbuf_data_vld & ~wrbuf_cmd_sent) & master_ready; + assign axi_arready = ~(wrbuf_vld & wrbuf_data_vld) & master_ready; + assign axi_rlast = 1'b1; + + assign wr_cmd_vld = (wrbuf_vld & wrbuf_data_vld); + assign master_valid = wr_cmd_vld | axi_arvalid; + assign master_tag[TAG-1:0] = wr_cmd_vld ? wrbuf_tag[TAG-1:0] : axi_arid[TAG-1:0]; + assign master_opc[2:0] = wr_cmd_vld ? 3'b011 : 3'b0; + assign master_addr[31:0] = wr_cmd_vld ? wrbuf_addr[31:0] : axi_araddr[31:0]; + assign master_size[2:0] = wr_cmd_vld ? wrbuf_size[2:0] : axi_arsize[2:0]; + assign master_byteen[7:0] = wrbuf_byteen[7:0]; + assign master_wdata[63:0] = wrbuf_data[63:0]; + + // AXI response channel signals + assign axi_bvalid = slave_valid & slave_opc[3]; + assign axi_bresp[1:0] = slave_opc[0] ? 2'b10 : (slave_opc[1] ? 2'b11 : 2'b0); + assign axi_bid[TAG-1:0] = slave_tag[TAG-1:0]; + + assign axi_rvalid = slave_valid & (slave_opc[3:2] == 2'b0); + assign axi_rresp[1:0] = slave_opc[0] ? 2'b10 : (slave_opc[1] ? 2'b11 : 2'b0); + assign axi_rid[TAG-1:0] = slave_tag[TAG-1:0]; + assign axi_rdata[63:0] = slave_rdata[63:0]; + + // FIFO state machine + always_comb begin + buf_nxtstate = IDLE; + buf_state_en = 1'b0; + buf_wr_en = 1'b0; + buf_data_wr_en = 1'b0; + slvbuf_error_in = 1'b0; + slvbuf_error_en = 1'b0; + buf_write_in = 1'b0; + cmd_done = 1'b0; + trxn_done = 1'b0; + buf_cmd_byte_ptr_en = 1'b0; + buf_cmd_byte_ptr[2:0] = '0; + slave_valid_pre = 1'b0; + master_ready = 1'b0; + ahb_htrans[1:0] = 2'b0; + slvbuf_wr_en = 1'b0; + bypass_en = 1'b0; + rd_bypass_idle = 1'b0; + + case (buf_state) + IDLE: begin + master_ready = 1'b1; + buf_write_in = (master_opc[2:1] == 2'b01); + buf_nxtstate = buf_write_in ? CMD_WR : CMD_RD; + buf_state_en = master_valid & master_ready; + buf_wr_en = buf_state_en; + buf_data_wr_en = buf_state_en & (buf_nxtstate == CMD_WR); + buf_cmd_byte_ptr_en = buf_state_en; + buf_cmd_byte_ptr[2:0] = buf_write_in ? get_nxtbyte_ptr(3'b0,buf_byteen_in[7:0],1'b0) : master_addr[2:0]; + bypass_en = buf_state_en; + rd_bypass_idle = bypass_en & (buf_nxtstate == CMD_RD); + ahb_htrans[1:0] = {2{bypass_en}} & 2'b10; + end + CMD_RD: begin + buf_nxtstate = (master_valid & (master_opc[2:0] == 3'b000))? STREAM_RD : DATA_RD; + buf_state_en = ahb_hready_q & (ahb_htrans_q[1:0] != 2'b0) & ~ahb_hwrite_q; + cmd_done = buf_state_en & ~master_valid; + slvbuf_wr_en = buf_state_en; + master_ready = buf_state_en & (buf_nxtstate == STREAM_RD); + buf_wr_en = master_ready; + bypass_en = master_ready & master_valid; + buf_cmd_byte_ptr[2:0] = bypass_en ? master_addr[2:0] : buf_addr[2:0]; + ahb_htrans[1:0] = 2'b10 & {2{~buf_state_en | bypass_en}}; + end + STREAM_RD: begin + master_ready = (ahb_hready_q & ~ahb_hresp_q) & ~(master_valid & master_opc[2:1] == 2'b01); + buf_wr_en = (master_valid & master_ready & (master_opc[2:0] == 3'b000)); // update the fifo if we are streaming the read commands + buf_nxtstate = ahb_hresp_q ? STREAM_ERR_RD : (buf_wr_en ? STREAM_RD : DATA_RD); // assuming that the master accpets the slave response right away. + buf_state_en = (ahb_hready_q | ahb_hresp_q); + buf_data_wr_en = buf_state_en; + slvbuf_error_in = ahb_hresp_q; + slvbuf_error_en = buf_state_en; + slave_valid_pre = buf_state_en & ~ahb_hresp_q; // send a response right away if we are not going through an error response. + cmd_done = buf_state_en & ~master_valid; // last one of the stream should not send a htrans + bypass_en = master_ready & master_valid & (buf_nxtstate == STREAM_RD) & buf_state_en; + buf_cmd_byte_ptr[2:0] = bypass_en ? master_addr[2:0] : buf_addr[2:0]; + ahb_htrans[1:0] = 2'b10 & {2{~((buf_nxtstate != STREAM_RD) & buf_state_en)}}; + slvbuf_wr_en = buf_wr_en; // shifting the contents from the buf to slv_buf for streaming cases + end // case: STREAM_RD + STREAM_ERR_RD: begin + buf_nxtstate = DATA_RD; + buf_state_en = ahb_hready_q & (ahb_htrans_q[1:0] != 2'b0) & ~ahb_hwrite_q; + slave_valid_pre = buf_state_en; + slvbuf_wr_en = buf_state_en; // Overwrite slvbuf with buffer + buf_cmd_byte_ptr[2:0] = buf_addr[2:0]; + ahb_htrans[1:0] = 2'b10 & {2{~buf_state_en}}; + end + DATA_RD: begin + buf_nxtstate = DONE_RD; + buf_state_en = (ahb_hready_q | ahb_hresp_q); + buf_data_wr_en = buf_state_en; + slvbuf_error_in= ahb_hresp_q; + slvbuf_error_en= buf_state_en; + slvbuf_wr_en = buf_state_en; + + end + CMD_WR: begin + buf_nxtstate = DATA_WR; + trxn_done = ahb_hready_q & ahb_hwrite_q & (ahb_htrans_q[1:0] != 2'b0); + buf_state_en = trxn_done; + buf_cmd_byte_ptr_en = buf_state_en; + slvbuf_wr_en = buf_state_en; + buf_cmd_byte_ptr = trxn_done ? get_nxtbyte_ptr(buf_cmd_byte_ptrQ[2:0],buf_byteen[7:0],1'b1) : buf_cmd_byte_ptrQ; + cmd_done = trxn_done & (buf_aligned | (buf_cmd_byte_ptrQ == 3'b111) | + (buf_byteen[get_nxtbyte_ptr(buf_cmd_byte_ptrQ[2:0],buf_byteen[7:0],1'b1)] == 1'b0)); + ahb_htrans[1:0] = {2{~(cmd_done | cmd_doneQ)}} & 2'b10; + end + DATA_WR: begin + buf_state_en = (cmd_doneQ & ahb_hready_q) | ahb_hresp_q; + master_ready = buf_state_en & ~ahb_hresp_q & axi_bready; // Ready to accept new command if current command done and no error + buf_nxtstate = (ahb_hresp_q | ~axi_bready) ? DONE_WR : + ((master_valid & master_ready) ? ((master_opc[2:1] == 2'b01) ? CMD_WR : CMD_RD) : IDLE); + slvbuf_error_in = ahb_hresp_q; + slvbuf_error_en = buf_state_en; + + buf_write_in = (master_opc[2:1] == 2'b01); + buf_wr_en = buf_state_en & ((buf_nxtstate == CMD_WR) | (buf_nxtstate == CMD_RD)); + buf_data_wr_en = buf_wr_en; + + cmd_done = (ahb_hresp_q | (ahb_hready_q & (ahb_htrans_q[1:0] != 2'b0) & + ((buf_cmd_byte_ptrQ == 3'b111) | (buf_byteen[get_nxtbyte_ptr(buf_cmd_byte_ptrQ[2:0],buf_byteen[7:0],1'b1)] == 1'b0)))); + bypass_en = buf_state_en & buf_write_in & (buf_nxtstate == CMD_WR); // Only bypass for writes for the time being + ahb_htrans[1:0] = {2{(~(cmd_done | cmd_doneQ) | bypass_en)}} & 2'b10; + slave_valid_pre = buf_state_en & (buf_nxtstate != DONE_WR); + + trxn_done = ahb_hready_q & ahb_hwrite_q & (ahb_htrans_q[1:0] != 2'b0); + buf_cmd_byte_ptr_en = trxn_done | bypass_en; + buf_cmd_byte_ptr = bypass_en ? get_nxtbyte_ptr(3'b0,buf_byteen_in[7:0],1'b0) : + trxn_done ? get_nxtbyte_ptr(buf_cmd_byte_ptrQ[2:0],buf_byteen[7:0],1'b1) : buf_cmd_byte_ptrQ; + end + DONE_WR: begin + buf_nxtstate = IDLE; + buf_state_en = axi_bvalid & axi_bready; + slvbuf_error_en = 1'b1; + slave_valid_pre = 1'b1; + end + DONE_RD: begin + buf_nxtstate = IDLE; + buf_state_en = axi_rvalid & axi_rready; // axi_rlast == 1 + slvbuf_error_en = 1'b1; + slave_valid_pre = 1'b1; + end + // `buf_state` is an enum and all the members are handled above, so the default case is excluded from coverge. + /*pragma coverage off*/ + default: begin + buf_nxtstate = IDLE; + buf_state_en = 1'b1; + end + /*pragma coverage on*/ + endcase + end + + assign buf_rst = dec_tlu_force_halt_bus; + assign cmd_done_rst = slave_valid_pre; + assign buf_addr_in[31:3] = master_addr[31:3]; + assign buf_addr_in[2:0] = (buf_aligned_in & (master_opc[2:1] == 2'b01)) ? get_write_addr(master_byteen[7:0]) : master_addr[2:0]; + assign buf_tag_in[TAG-1:0] = master_tag[TAG-1:0]; + assign buf_byteen_in[7:0] = wrbuf_byteen[7:0]; + assign buf_data_in[63:0] = (buf_state == DATA_RD) ? ahb_hrdata_q[63:0] : master_wdata[63:0]; + assign buf_size_in[1:0] = (buf_aligned_in & (master_size[1:0] == 2'b11) & (master_opc[2:1] == 2'b01)) ? get_write_size(master_byteen[7:0]) : master_size[1:0]; + assign buf_aligned_in = (master_opc[2:0] == 3'b0) | // reads are always aligned since they are either DW or sideeffects + (master_size[1:0] == 2'b0) | (master_size[1:0] == 2'b01) | (master_size[1:0] == 2'b10) | // Always aligned for Byte/HW/Word since they can be only for non-idempotent. IFU/SB are always aligned + ((master_size[1:0] == 2'b11) & + ((master_byteen[7:0] == 8'h3) | (master_byteen[7:0] == 8'hc) | (master_byteen[7:0] == 8'h30) | (master_byteen[7:0] == 8'hc0) | + (master_byteen[7:0] == 8'hf) | (master_byteen[7:0] == 8'hf0) | (master_byteen[7:0] == 8'hff))); + + // Generate the ahb signals + assign ahb_haddr[31:3] = bypass_en ? master_addr[31:3] : buf_addr[31:3]; + assign ahb_haddr[2:0] = {3{(ahb_htrans == 2'b10)}} & buf_cmd_byte_ptr[2:0]; // Trxn should be aligned during IDLE + assign ahb_hsize[2:0] = bypass_en ? {1'b0, ({2{buf_aligned_in}} & buf_size_in[1:0])} : + {1'b0, ({2{buf_aligned}} & buf_size[1:0])}; // Send the full size for aligned trxn + assign ahb_hburst[2:0] = 3'b0; + assign ahb_hmastlock = 1'b0; + assign ahb_hprot[3:0] = {3'b001,~axi_arprot[2]}; + assign ahb_hwrite = bypass_en ? (master_opc[2:1] == 2'b01) : buf_write; + assign ahb_hwdata[63:0] = buf_data[63:0]; + + assign slave_valid = slave_valid_pre;// & (~slvbuf_posted_write | slvbuf_error); + assign slave_opc[3:2] = slvbuf_write ? 2'b11 : 2'b00; + assign slave_opc[1:0] = {2{slvbuf_error}} & 2'b10; + assign slave_rdata[63:0] = slvbuf_error ? {2{last_bus_addr[31:0]}} : ((buf_state == DONE_RD) ? buf_data[63:0] : ahb_hrdata_q[63:0]); + assign slave_tag[TAG-1:0] = slvbuf_tag[TAG-1:0]; + + assign last_addr_en = (ahb_htrans[1:0] != 2'b0) & ahb_hready & ahb_hwrite ; + + + rvdffsc_fpga #(.WIDTH(1)) wrbuf_vldff (.din(1'b1), .dout(wrbuf_vld), .en(wrbuf_en), .clear(wrbuf_rst), .clk(bus_clk), .clken(bus_clk_en), .rawclk(clk), .*); + rvdffsc_fpga #(.WIDTH(1)) wrbuf_data_vldff(.din(1'b1), .dout(wrbuf_data_vld), .en(wrbuf_data_en), .clear(wrbuf_rst), .clk(bus_clk), .clken(bus_clk_en), .rawclk(clk), .*); + rvdffs_fpga #(.WIDTH(TAG)) wrbuf_tagff (.din(axi_awid[TAG-1:0]), .dout(wrbuf_tag[TAG-1:0]), .en(wrbuf_en), .clk(bus_clk), .clken(bus_clk_en), .rawclk(clk), .*); + rvdffs_fpga #(.WIDTH(3)) wrbuf_sizeff (.din(axi_awsize[2:0]), .dout(wrbuf_size[2:0]), .en(wrbuf_en), .clk(bus_clk), .clken(bus_clk_en), .rawclk(clk), .*); + rvdffe #(.WIDTH(32)) wrbuf_addrff (.din(axi_awaddr[31:0]), .dout(wrbuf_addr[31:0]), .en(wrbuf_en & bus_clk_en), .clk(clk), .*); + rvdffe #(.WIDTH(64)) wrbuf_dataff (.din(axi_wdata[63:0]), .dout(wrbuf_data[63:0]), .en(wrbuf_data_en & bus_clk_en), .clk(clk), .*); + rvdffs_fpga #(.WIDTH(8)) wrbuf_byteenff (.din(axi_wstrb[7:0]), .dout(wrbuf_byteen[7:0]), .en(wrbuf_data_en), .clk(bus_clk), .clken(bus_clk_en), .rawclk(clk), .*); + + rvdffs_fpga #(.WIDTH(32)) last_bus_addrff (.din(ahb_haddr[31:0]), .dout(last_bus_addr[31:0]), .en(last_addr_en), .clk(bus_clk), .clken(bus_clk_en), .rawclk(clk), .*); + + rvdffsc_fpga #(.WIDTH($bits(state_t))) buf_state_ff (.din(buf_nxtstate), .dout({buf_state}), .en(buf_state_en), .clear(buf_rst), .clk(bus_clk), .clken(bus_clk_en), .rawclk(clk), .*); + rvdffs_fpga #(.WIDTH(1)) buf_writeff (.din(buf_write_in), .dout(buf_write), .en(buf_wr_en), .clk(buf_clk), .clken(buf_clken), .rawclk(clk), .*); + rvdffs_fpga #(.WIDTH(TAG)) buf_tagff (.din(buf_tag_in[TAG-1:0]), .dout(buf_tag[TAG-1:0]), .en(buf_wr_en), .clk(buf_clk), .clken(buf_clken), .rawclk(clk), .*); + rvdffe #(.WIDTH(32)) buf_addrff (.din(buf_addr_in[31:0]), .dout(buf_addr[31:0]), .en(buf_wr_en & bus_clk_en), .clk(clk), .*); + rvdffs_fpga #(.WIDTH(2)) buf_sizeff (.din(buf_size_in[1:0]), .dout(buf_size[1:0]), .en(buf_wr_en), .clk(buf_clk), .clken(buf_clken), .rawclk(clk), .*); + rvdffs_fpga #(.WIDTH(1)) buf_alignedff (.din(buf_aligned_in), .dout(buf_aligned), .en(buf_wr_en), .clk(buf_clk), .clken(buf_clken), .rawclk(clk), .*); + rvdffs_fpga #(.WIDTH(8)) buf_byteenff (.din(buf_byteen_in[7:0]), .dout(buf_byteen[7:0]), .en(buf_wr_en), .clk(buf_clk), .clken(buf_clken), .rawclk(clk), .*); + rvdffe #(.WIDTH(64)) buf_dataff (.din(buf_data_in[63:0]), .dout(buf_data[63:0]), .en(buf_data_wr_en & bus_clk_en), .clk(clk), .*); + + + rvdffs_fpga #(.WIDTH(1)) slvbuf_writeff (.din(buf_write), .dout(slvbuf_write), .en(slvbuf_wr_en), .clk(buf_clk), .clken(buf_clken), .rawclk(clk), .*); + rvdffs_fpga #(.WIDTH(TAG)) slvbuf_tagff (.din(buf_tag[TAG-1:0]), .dout(slvbuf_tag[TAG-1:0]), .en(slvbuf_wr_en), .clk(buf_clk), .clken(buf_clken), .rawclk(clk), .*); + rvdffs_fpga #(.WIDTH(1)) slvbuf_errorff (.din(slvbuf_error_in), .dout(slvbuf_error), .en(slvbuf_error_en), .clk(bus_clk), .clken(bus_clk_en), .rawclk(clk), .*); + + rvdffsc_fpga #(.WIDTH(1)) buf_cmd_doneff (.din(1'b1), .dout(cmd_doneQ), .en(cmd_done), .clear(cmd_done_rst), .clk(bus_clk), .clken(bus_clk_en), .rawclk(clk), .*); + rvdffs_fpga #(.WIDTH(3)) buf_cmd_byte_ptrff (.din(buf_cmd_byte_ptr[2:0]), .dout(buf_cmd_byte_ptrQ[2:0]), .en(buf_cmd_byte_ptr_en), .clk(bus_clk), .clken(bus_clk_en), .rawclk(clk), .*); + + rvdff_fpga #(.WIDTH(1)) hready_ff (.din(ahb_hready), .dout(ahb_hready_q), .clk(bus_clk), .clken(bus_clk_en), .rawclk(clk), .*); + rvdff_fpga #(.WIDTH(2)) htrans_ff (.din(ahb_htrans[1:0]), .dout(ahb_htrans_q[1:0]), .clk(bus_clk), .clken(bus_clk_en), .rawclk(clk), .*); + rvdff_fpga #(.WIDTH(1)) hwrite_ff (.din(ahb_hwrite), .dout(ahb_hwrite_q), .clk(bus_clk), .clken(bus_clk_en), .rawclk(clk), .*); + rvdff_fpga #(.WIDTH(1)) hresp_ff (.din(ahb_hresp), .dout(ahb_hresp_q), .clk(bus_clk), .clken(bus_clk_en), .rawclk(clk), .*); + rvdff_fpga #(.WIDTH(64)) hrdata_ff (.din(ahb_hrdata[63:0]), .dout(ahb_hrdata_q[63:0]), .clk(ahbm_data_clk), .clken(ahbm_data_clken), .rawclk(clk), .*); + + // Clock headers + // clock enables for ahbm addr/data + assign buf_clken = bus_clk_en & (buf_wr_en | slvbuf_wr_en | clk_override); + assign ahbm_data_clken = bus_clk_en & ((buf_state != IDLE) | clk_override); + +`ifdef RV_FPGA_OPTIMIZE + assign bus_clk = 1'b0; + assign buf_clk = 1'b0; + assign ahbm_data_clk = 1'b0; +`else + rvclkhdr bus_cgc (.en(bus_clk_en), .l1clk(bus_clk), .*); + rvclkhdr buf_cgc (.en(buf_clken), .l1clk(buf_clk), .*); + rvclkhdr ahbm_data_cgc (.en(ahbm_data_clken), .l1clk(ahbm_data_clk), .*); +`endif + +`ifdef RV_ASSERT_ON + property ahb_trxn_aligned; + @(posedge bus_clk) ahb_htrans[1] |-> ((ahb_hsize[2:0] == 3'h0) | + ((ahb_hsize[2:0] == 3'h1) & (ahb_haddr[0] == 1'b0)) | + ((ahb_hsize[2:0] == 3'h2) & (ahb_haddr[1:0] == 2'b0)) | + ((ahb_hsize[2:0] == 3'h3) & (ahb_haddr[2:0] == 3'b0))); + endproperty + assert_ahb_trxn_aligned: assert property (ahb_trxn_aligned) else + $display("Assertion ahb_trxn_aligned failed: ahb_htrans=2'h%h, ahb_hsize=3'h%h, ahb_haddr=32'h%h",ahb_htrans[1:0], ahb_hsize[2:0], ahb_haddr[31:0]); + + property ahb_error_protocol; + @(posedge bus_clk) (ahb_hready & ahb_hresp) |-> (~$past(ahb_hready) & $past(ahb_hresp)); + endproperty + assert_ahb_error_protocol: assert property (ahb_error_protocol) else + $display("Bus Error with hReady isn't preceded with Bus Error without hready"); +`endif + +endmodule // axi4_to_ahb diff --git a/designs/Caliptra/src/caliptra-rtl/axi_addr.v b/designs/Caliptra/src/caliptra-rtl/axi_addr.v new file mode 100644 index 0000000..faa321c --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/axi_addr.v @@ -0,0 +1,239 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// Filename: axi_addr.v +// {{{ +// Project: WB2AXIPSP: bus bridges and other odds and ends +// +// Purpose: The AXI (full) standard has some rather complicated addressing +// modes, where the address can either be FIXED, INCRementing, or +// even where it can WRAP around some boundary. When in either INCR or +// WRAP modes, the next address must always be aligned. In WRAP mode, +// the next address calculation needs to wrap around a given value, and +// that value is dependent upon the burst size (i.e. bytes per beat) and +// length (total numbers of beats). Since this calculation can be +// non-trivial, and since it needs to be done multiple times, the logic +// below captures it for every time it might be needed. +// +// 20200918 - modified to accommodate (potential) AXI3 burst lengths +// +// Creator: Dan Gisselquist, Ph.D. +// Gisselquist Technology, LLC +// +// Caliptra Modifications: +// Revert the default_nettype assignment at file end +// +//////////////////////////////////////////////////////////////////////////////// +// }}} +// Copyright (C) 2019-2024, Gisselquist Technology, LLC +// {{{ +// This file is part of the WB2AXIP project. +// +// The WB2AXIP project contains free software and gateware, licensed under the +// Apache License, Version 2.0 (the "License"). You may not use this project, +// or 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. +// +//////////////////////////////////////////////////////////////////////////////// +// +// +`default_nettype none +// }}} +module axi_addr #( + // {{{ + parameter AW = 32, + DW = 32, + // parameter [0:0] OPT_AXI3 = 1'b0, + localparam LENB = 8 + // }}} + ) ( + // {{{ + input wire [AW-1:0] i_last_addr, + input wire [2:0] i_size, // 1b, 2b, 4b, 8b, etc + input wire [1:0] i_burst, // fixed, incr, wrap, reserved + input wire [LENB-1:0] i_len, + output wire [AW-1:0] o_next_addr + // }}} + ); + + // Parameter/register declarations + // {{{ + localparam DSZ = $clog2(DW)-3; + localparam [1:0] FIXED = 2'b00; + // localparam [1:0] INCREMENT = 2'b01; + // localparam [1:0] WRAP = 2'b10; + localparam IN_AW = (AW >= 12) ? 12 : AW; + localparam [IN_AW-1:0] ONE = 1; + + reg [IN_AW-1:0] wrap_mask, increment; + reg [IN_AW-1:0] crossblk_addr, aligned_addr, unaligned_addr; + // }}} + + // Address increment + // {{{ + always @(*) + if (DSZ == 0) + increment = 1; + else if (DSZ == 1) + increment = (i_size[0]) ? 2 : 1; + else if (DSZ == 2) + increment = (i_size[1]) ? 4 : ((i_size[0]) ? 2 : 1); + else if (DSZ == 3) + case(i_size[1:0]) + 2'b00: increment = 1; + 2'b01: increment = 2; + 2'b10: increment = 4; + 2'b11: increment = 8; + endcase + else + increment = (1<1) ? 1 : (AW-1):0]= 0; + 2'b11: aligned_addr[(AW-1>2) ? 2 : (AW-1):0]= 0; + endcase + // }}} + end else begin + // {{{ + // Align any subsequent address + case(i_size) + 3'b001: aligned_addr[ 0] = 0; + 3'b010: aligned_addr[(AW-1>1) ? 1 : (AW-1):0]=0; + 3'b011: aligned_addr[(AW-1>2) ? 2 : (AW-1):0]=0; + 3'b100: aligned_addr[(AW-1>3) ? 3 : (AW-1):0]=0; + 3'b101: aligned_addr[(AW-1>4) ? 4 : (AW-1):0]=0; + 3'b110: aligned_addr[(AW-1>5) ? 5 : (AW-1):0]=0; + 3'b111: aligned_addr[(AW-1>6) ? 6 : (AW-1):0]=0; + default: aligned_addr = unaligned_addr; + endcase + // }}} + end + // }}} + end else + aligned_addr = i_last_addr[IN_AW-1:0]; + // }}} + + // crossblk_addr from aligned_addr, for WRAP addressing + // {{{ + always @(*) + if (i_burst[1]) + begin + // WRAP! + crossblk_addr[IN_AW-1:0] = (i_last_addr[IN_AW-1:0] & ~wrap_mask) + | (aligned_addr & wrap_mask); + end else + crossblk_addr[IN_AW-1:0] = aligned_addr; + // }}} + + // o_next_addr: Guarantee only the bottom 12 bits change + // {{{ + // This is really a logic simplification. AXI bursts aren't allowed + // to cross 4kB boundaries. Given that's the case, we don't have to + // suffer from the propagation across all AW bits, and can limit any + // address propagation to just the lower 12 bits + generate if (AW > 12) + begin : WIDE_ADDRESS + assign o_next_addr = { i_last_addr[AW-1:12], + crossblk_addr[11:0] }; + end else begin : NARROW_ADDRESS + assign o_next_addr = crossblk_addr[AW-1:0]; + end endgenerate + // }}} + + // Make Verilator happy + // {{{ + // Verilator lint_off UNUSED + wire unused; + assign unused = (LENB <= 4) ? &{1'b0, i_len[0] } + : &{ 1'b0, i_len[LENB-1:4], i_len[0] }; + // Verilator lint_on UNUSED + // }}} +endmodule +`default_nettype wire diff --git a/designs/Caliptra/src/caliptra-rtl/axi_dma_ctrl.sv b/designs/Caliptra/src/caliptra-rtl/axi_dma_ctrl.sv new file mode 100644 index 0000000..677a9ae --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/axi_dma_ctrl.sv @@ -0,0 +1,1505 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +// +// Description: +// Control State Machine for Caliptra AXI Manager (DMA) block +// + +module axi_dma_ctrl +import axi_pkg::*; +import soc_ifc_pkg::*; +import kv_defines_pkg::*; +#( + parameter AW = 64, + parameter DW = 32, // Data Width + BC = DW/8, // Byte Count + BW = $clog2(BC) // Byte count Width +)( + input logic clk, + input logic cptra_pwrgood, + input logic rst_n, + + // Recovery INF Interrupt + // Should only assert when a full block_size of data is available at the + // recovery interface FIFO + input logic recovery_data_avail, + input logic recovery_image_activated, + + // Internal Signaling + input logic mbox_lock, + input logic sha_lock, + input logic debugUnlock_or_scan_mode_switch, + input logic ocp_lock_in_progress, + input logic [63:0] key_release_addr, + input logic [15:0] key_release_size, + + // Mailbox SRAM INF + output logic mb_dv, + input logic mb_hold, + input logic mb_error, + output var soc_ifc_req_t mb_data, + input logic [DW-1:0] mb_rdata, + + // AES Interface + input logic aes_input_ready, + input logic aes_output_valid, + input logic aes_status_idle, + output logic aes_req_dv, + input logic aes_req_hold, + output soc_ifc_req_t aes_req_data, + input logic [DW-1:0] aes_rdata, + input logic aes_err, + + // kv interface + output kv_read_t kv_read, + input kv_rd_resp_t kv_rd_resp, + + // AXI Manager Read INF + axi_dma_req_if.src r_req_if, + output logic r_ready_o, + input logic r_valid_i, + input logic [DW-1:0] r_data_i, + + // AXI Manager Write INF + axi_dma_req_if.src w_req_if, + input logic w_ready_i, + output logic w_valid_o, + output logic [DW-1:0] w_data_o, + + // Register INF + input logic dv, + input var soc_ifc_req_t req_data, + output logic hold, + output logic [SOC_IFC_DATA_W-1:0] rdata, + output logic error, + + // Interrupt + output logic notif_intr, + output logic error_intr + +); + + // --------------------------------------- // + // Imports // + // --------------------------------------- // + import axi_dma_reg_pkg::*; + `include "caliptra_prim_assert.sv" + + + // --------------------------------------- // + // Localparams/Typedefs // + // --------------------------------------- // + + `define MIN_OF(a,b) ((a < b) ? a : b) + `define MAX_OF(a,b) ((a > b) ? a : b) + + localparam FIFO_BC = 512; // depth in bytes + localparam FIFO_BW = caliptra_prim_util_pkg::vbits((FIFO_BC/BC)+1); // width of a signal that reports FIFO slot consumption + + localparam AES_FIFO_BC = 16; // depth in bytes + localparam AES_FIFO_BW = caliptra_prim_util_pkg::vbits((AES_FIFO_BC/BC)+1); // width of a signal that reports FIFO slot consumption + + // Smaller of + // a) 4096 (AXI max burst size) + // b) Configured data width X max supported AXI burst length value + localparam AXI_MAX_BLOCK_SIZE = `MIN_OF(AXI_LEN_MAX_BYTES,(AXI_LEN_MAX_VALUE * BC)); + // Smaller of + // a) Largest legal AXI block size + // b) Largest burst that can fit in the FIFO + localparam MAX_BLOCK_SIZE = `MIN_OF(AXI_MAX_BLOCK_SIZE,FIFO_BC/2); + // Smaller of + // a) MAX_BLOCK_SIZE + // b) Configured data width X max supported AXI burst length value for FIXED bursts + localparam AXI_MAX_FIXED_BLOCK_SIZE = `MIN_OF(AXI_LEN_MAX_BYTES,(AXI_FIXED_LEN_MAX_VALUE * BC)); + localparam MAX_FIXED_BLOCK_SIZE = `MIN_OF(AXI_MAX_FIXED_BLOCK_SIZE,MAX_BLOCK_SIZE); + localparam DMA_MAX_XFER_SIZE = 32'h10_0000; // 1MiB + + + // --------------------------------------- // + // Signals // + // --------------------------------------- // + + axi_dma_reg_pkg::axi_dma_reg__in_t hwif_in; + axi_dma_reg_pkg::axi_dma_reg__out_t hwif_out; + + enum logic [1:0] { + DMA_IDLE, + DMA_WAIT_DATA, + DMA_DONE, + DMA_ERROR + } ctrl_fsm_ns,ctrl_fsm_ps; + + + enum logic [3:0] { + AES_IDLE, + AES_WAIT_INPUT_READY, + AES_WAIT_IDLE, + AES_UPDATE_BYTE_COUNT, + AES_WRITE_BLOCK, + AES_WAIT_OUTPUT_VALID, + AES_READ_OUTPUT, + AES_DONE, + AES_ERROR + } aes_fsm_ns, aes_fsm_ps; + + logic start_aes_fsm; + logic aes_init_done; + logic aes_init_done_next; + logic [1:0] aes_cif_write_cnt, aes_cif_write_cnt_next; + logic aes_cif_write_cnt_reset; + logic aes_cif_write_block_done; + logic aes_cif_read_block_done; + logic aes_cif_update_byte_count_done; + logic aes_cif_write_cnt_incr; + logic aes_req_wait; + logic aes_req_wait_next; + logic aes_error; + logic aes_req_dv_q; + logic aes_to_axi_last_transfer; + logic aes_to_axi_last_transfer_next; + + logic [1:0] aes_cif_read_cnt; + logic [1:0] aes_cif_read_cnt_next; + logic aes_cif_read_cnt_incr; + + // AES Fifo Controls + logic aes_fifo_w_valid; + logic aes_fifo_w_ready; + logic [DW-1:0] aes_fifo_w_data ; + logic aes_fifo_r_valid; + logic aes_fifo_r_ready; + logic [DW-1:0] aes_fifo_r_data; + logic aes_fifo_full ; + logic [AES_FIFO_BW-1:0] aes_fifo_depth; + logic aes_fifo_empty; + + + logic [SOC_IFC_DATA_W-1:0] reg_biten; + logic reg_rd_err, reg_wr_err; + logic reg_rd_stall, reg_wr_stall; + logic reg_rd_ack_nc, reg_wr_ack_nc; + + // FIFO signals + logic fifo_w_ready; + logic fifo_w_valid; + logic [DW-1:0] fifo_w_data; + logic fifo_r_ready; + logic fifo_r_valid; + logic [DW-1:0] fifo_r_data; + logic [FIFO_BW-1:0] fifo_depth; + logic fifo_full, fifo_full_r; + logic fifo_empty, fifo_empty_r; + + // Read Route Signals + logic [DW-1:0] rd_route_data; + logic rd_route_valid; + logic rd_route_ready; + logic [DW-1:0] aes_fsm_rd_route_data; + logic aes_fsm_rd_route_valid; + logic aes_fsm_rd_route_ready; + + // Internal signals + axi_dma_reg__ctrl__rd_route__rd_route_e_e rd_route; + axi_dma_reg__ctrl__wr_route__wr_route_e_e wr_route; + + logic cmd_inv_rd_route; + logic cmd_inv_wr_route; + logic cmd_inv_route_combo; + logic cmd_inv_src_addr; + logic cmd_inv_dst_addr; + logic cmd_inv_byte_count; + logic cmd_inv_block_size; + logic cmd_inv_rd_fixed; + logic cmd_inv_wr_fixed; + logic cmd_inv_mbox_lock; + logic cmd_inv_sha_lock; + logic cmd_parse_error; + logic cmd_inv_aes_route_combo; + logic cmd_inv_aes_block_size; + logic cmd_inv_aes_fixed; + + logic rd_req_hshake, rd_req_hshake_bypass; + logic wr_req_hshake, wr_req_hshake_bypass; + // Count read requests that have been enqueued due to recovery_data_avail. + // Width of signal is sufficient to track 2x the maximum number of requests + // possible for any given "block" of data. + // The maximum number of requests for a given "block" is calculated as: + // max_block_size / min_size_per_request + // Where + // max_block_size = AXI_LEN_MAX_BYTES + // min_size_per_request = BC + // In payload_available edge-detection configuration, this allows the counter to schedule + // the next set of requests if recovery_data_avail pulse is observed + // while there are still requests that have not been issued from the prior pulse. + logic [AXI_LEN_BC_WIDTH-BW:0] rd_req_count_for_payload, rd_req_count_for_payload_next; + logic rd_req_stall; + `ifndef CALIPTRA_AXI_DMA_PAYLOAD_AVAILABLE_EDGE_DETECTION_MODE + logic rd_wait_to_ack_avail; // Used to enforce that requests go one at a time + `else + logic recovery_data_avail_d, recovery_data_avail_p; // Edge detection + `endif + logic [3:0] wr_resp_pending; // Counts up to 15 pending Write responses. + // Once this counter saturates, we stall new requests + // until further responses arrive. + // This is an artificially imposed limit, intended + // to allow a subordinate to have some delay in sending + // write responses without ever throttling this DMA. + + logic [DW-1:0] r_data_mask; + + logic [AW-1:0] src_addr, dst_addr; + logic [FIFO_BW-1:0] rd_credits; + logic [FIFO_BW-1:0] wr_credits; + logic wr_credits_fifo_w_valid; + logic wr_credits_fifo_w_ready; + logic [AXI_LEN_BC_WIDTH-1:0] block_size_mask; + // 1's based counters + logic [31:0] rd_bytes_requested; + logic rd_bytes_rem_thresh; // Number of read bytes remaining to be requested is lower than the threshold of MAX_BLOCK_SIZE + logic [31:0] wr_bytes_requested; + logic wr_bytes_rem_thresh; // Number of write bytes remaining to be requested is lower than the threshold of MAX_BLOCK_SIZE + logic [AXI_LEN_BC_WIDTH-1:0] rd_align_req_byte_count; // byte-count in a request until nearest AXI boundary + logic [AXI_LEN_BC_WIDTH-1:0] rd_final_req_byte_count; // byte-count in the final request, which may be smaller than a typical request + logic [AXI_LEN_BC_WIDTH-1:0] rd_req_byte_count; // byte-count calculated for the current read request + logic [AXI_LEN_BC_WIDTH-1:0] wr_align_req_byte_count; // byte-count in a request until nearest AXI boundary + logic [AXI_LEN_BC_WIDTH-1:0] wr_sel_req_byte_count; // byte-count select between AES and FIFO count + logic [AXI_LEN_BC_WIDTH-1:0] wr_aes_ceil_req_byte_count; // byte-count select between AES FIFO max size or number of bytes left + logic [AXI_LEN_BC_WIDTH-1:0] wr_final_req_byte_count; // byte-count in the final request, which may be smaller than a typical request + logic [AXI_LEN_BC_WIDTH-1:0] wr_req_byte_count; // byte-count calculated for the current read request + + logic [31:0] bytes_remaining; // Decrements with arrival of beat at DESTINATION. + logic [31:0] rd_fifo_bytes_remaining; // Decrements with arrival of data into FIFO + logic all_bytes_transferred; + logic axi_error; + logic mb_lock_dropped, mb_lock_error; + + // KeyVault signals + kv_read_ctrl_reg_t kv_read_ctrl_reg; + kv_read_filter_metrics_t kv_read_metrics; + logic kv_read_en; + logic kv_read_once; + logic kv_data_write_en; +// logic [$clog2(OCP_LOCK_MEK_NUM_DWORDS)-1:0] kv_data_write_offset; + logic [31:0] kv_data_write_data; + kv_error_code_e kv_data_error_code; + logic kv_data_kv_ready; + logic kv_data_read_done; + logic kv_read_error; // KV read operation error + logic kv_premature_done_error; // KV read done before expected key size read + logic kv_any_error; // Any KV read error + + + // --------------------------------------- // + // Control Register Block // + // --------------------------------------- // + genvar i; + generate + for (i=0;i (OCP_LOCK_MEK_NUM_DWORDS << 2)) && + (hwif_out.ctrl.wr_route.value == axi_dma_reg__ctrl__wr_route__wr_route_e__KEYVAULT)); + // power of 2 and word-aligned + cmd_inv_block_size = |(hwif_out.block_size.size.value & (hwif_out.block_size.size.value-1)) || + |hwif_out.block_size.size.value[BW-1:0]; + cmd_inv_rd_fixed = hwif_out.ctrl.rd_fixed.value && hwif_out.ctrl.rd_route.value == axi_dma_reg__ctrl__rd_route__rd_route_e__DISABLE; + cmd_inv_wr_fixed = hwif_out.ctrl.wr_fixed.value && hwif_out.ctrl.wr_route.value inside {axi_dma_reg__ctrl__wr_route__wr_route_e__DISABLE, + axi_dma_reg__ctrl__wr_route__wr_route_e__KEYVAULT}; + cmd_inv_mbox_lock = !mbox_lock && ((hwif_out.ctrl.rd_route.value == axi_dma_reg__ctrl__rd_route__rd_route_e__MBOX) || (hwif_out.ctrl.wr_route.value == axi_dma_reg__ctrl__wr_route__wr_route_e__MBOX)); + cmd_inv_sha_lock = !sha_lock && (1'b0/*addr decode? NOTE: Direct-access to sha accelerator not implemented. Disable this check.*/); + cmd_parse_error = cmd_inv_rd_route || + cmd_inv_wr_route || + cmd_inv_route_combo || + cmd_inv_aes_route_combo|| + cmd_inv_aes_block_size || + cmd_inv_aes_fixed || + cmd_inv_src_addr || + cmd_inv_dst_addr || + cmd_inv_byte_count || + cmd_inv_block_size || + cmd_inv_rd_fixed || + cmd_inv_wr_fixed || + cmd_inv_mbox_lock || + cmd_inv_sha_lock; + end + generate + // An address is invalid if: + // * improperly aligned + // * MSB bits are set (out of address range) + // * Mismatches key_release_addr for KEYVAULT wr_route + if (AW < 32) begin + always_comb begin + cmd_inv_src_addr = |src_addr[BW-1:0] || + |hwif_out.src_addr_l.addr_l.value[31:AW] || + |hwif_out.src_addr_h.addr_h.value; + cmd_inv_dst_addr = |dst_addr[BW-1:0] || + |hwif_out.dst_addr_l.addr_l.value[31:AW] || + |hwif_out.dst_addr_h.addr_h.value || + (|(64'(dst_addr) ^ key_release_addr) && (hwif_out.ctrl.wr_route.value == axi_dma_reg__ctrl__wr_route__wr_route_e__KEYVAULT)); + end + end + else if (AW < 64) begin + always_comb begin + cmd_inv_src_addr = |src_addr[BW-1:0] || + |hwif_out.src_addr_h.addr_h.value[31:AW-32]; + cmd_inv_dst_addr = |dst_addr[BW-1:0] || + |hwif_out.dst_addr_h.addr_h.value[31:AW-32] || + (|(64'(dst_addr) ^ key_release_addr) && (hwif_out.ctrl.wr_route.value == axi_dma_reg__ctrl__wr_route__wr_route_e__KEYVAULT)); + end + end + else begin + always_comb begin + cmd_inv_src_addr = |src_addr[BW-1:0]; + cmd_inv_dst_addr = |dst_addr[BW-1:0] || + (|(64'(dst_addr) ^ key_release_addr) && (hwif_out.ctrl.wr_route.value == axi_dma_reg__ctrl__wr_route__wr_route_e__KEYVAULT)); + end + end + endgenerate + + always_comb hwif_in.intr_block_rf.error_internal_intr_r.error_cmd_dec_sts .hwset = (ctrl_fsm_ps == DMA_IDLE) && hwif_out.ctrl.go.value && cmd_parse_error; + always_comb hwif_in.intr_block_rf.error_internal_intr_r.error_axi_rd_sts .hwset = r_req_if.resp_valid && r_req_if.resp inside {AXI_RESP_SLVERR,AXI_RESP_DECERR}; + always_comb hwif_in.intr_block_rf.error_internal_intr_r.error_axi_wr_sts .hwset = w_req_if.resp_valid && w_req_if.resp inside {AXI_RESP_SLVERR,AXI_RESP_DECERR}; + always_comb hwif_in.intr_block_rf.error_internal_intr_r.error_mbox_lock_sts .hwset = mb_lock_dropped && !mb_lock_error; // pulse to set + always_comb hwif_in.intr_block_rf.error_internal_intr_r.error_aes_cif_sts .hwset = aes_err && aes_req_dv; // Pulse to set + always_comb hwif_in.intr_block_rf.error_internal_intr_r.error_sha_lock_sts .hwset = 1'b0; // SHA accelerator direct-mode not enabled; sha locking should be checked by API user (i.e. FW) instead of in HW + always_comb hwif_in.intr_block_rf.error_internal_intr_r.error_fifo_oflow_sts .hwset = (hwif_out.ctrl.wr_route.value == axi_dma_reg__ctrl__wr_route__wr_route_e__AHB_FIFO) && fifo_w_valid && !fifo_w_ready; + always_comb hwif_in.intr_block_rf.error_internal_intr_r.error_fifo_uflow_sts .hwset = (hwif_out.ctrl.rd_route.value == axi_dma_reg__ctrl__rd_route__rd_route_e__AHB_FIFO) && !fifo_r_valid && fifo_r_ready; + always_comb hwif_in.intr_block_rf.error_internal_intr_r.error_kv_rd_sts .hwset = kv_read_error; + always_comb hwif_in.intr_block_rf.error_internal_intr_r.error_kv_rd_large_sts .hwset = kv_premature_done_error; + + always_comb hwif_in.intr_block_rf.notif_internal_intr_r.notif_txn_done_sts .hwset = ctrl_fsm_ps inside {DMA_DONE,DMA_ERROR}; + always_comb hwif_in.intr_block_rf.notif_internal_intr_r.notif_fifo_empty_sts .hwset = fifo_empty && !fifo_empty_r; + always_comb hwif_in.intr_block_rf.notif_internal_intr_r.notif_fifo_not_empty_sts.hwset = !fifo_empty && fifo_empty_r; + always_comb hwif_in.intr_block_rf.notif_internal_intr_r.notif_fifo_full_sts .hwset = fifo_full && !fifo_full_r; + always_comb hwif_in.intr_block_rf.notif_internal_intr_r.notif_fifo_not_full_sts .hwset = !fifo_full && fifo_full_r; + + assign notif_intr = hwif_out.intr_block_rf.notif_global_intr_r.intr; + assign error_intr = hwif_out.intr_block_rf.error_global_intr_r.intr; + + + // --------------------------------------- // + // Control Logic // + // --------------------------------------- // + + `ifndef CALIPTRA_AXI_DMA_PAYLOAD_AVAILABLE_EDGE_DETECTION_MODE + // Don't queue any more requests up in response to recovery_data_avail unless both: + // * the current request count is 0 + // * there is no data transfer pending + assign rd_wait_to_ack_avail = |rd_req_count_for_payload || (rd_credits < FIFO_BC/BC); + + // When block_size != 0, we are guaranteed to be interacting with the SS recovery interface + // which means transactions will also be of FIXED burst type. + // This guarantees that each read request will be sized according to the constraints of + // block_size and MAX_FIXED_BLOCK_SIZE, without regard for address alignment boundaries or + // other conditions. + // Treat recovery_data_avail as a level signal indicating there is some data in the FIFO + always_comb begin + case ({rd_wait_to_ack_avail,recovery_data_avail,rd_req_hshake}) inside + 3'b000: rd_req_count_for_payload_next = rd_req_count_for_payload; + 3'b001: rd_req_count_for_payload_next = rd_req_count_for_payload - 1; + 3'b010: rd_req_count_for_payload_next = rd_req_count_for_payload + `MAX_OF(hwif_out.block_size.size.value>>$clog2(MAX_FIXED_BLOCK_SIZE),1); + 3'b011: rd_req_count_for_payload_next = '0; // If block_size != 0, we would only expect to see rd_req_hshake when rd_wait_to_ack_avail is 1 + // If we see a rd_req_hshake in this case it would be erroneous, so reset the pending req count to 0 + // and watch for another indicator on recovery_data_avail. + // If block_size == 0, this case might occur. E.g., while Caliptra is reading registers from the + // recovery interface in response to the initial assertion of recovery_data_avail. + // rd_req_count_for_payload is only used when block_size != 0, so hold it at a 0 value. + 3'b100: rd_req_count_for_payload_next = rd_req_count_for_payload; + 3'b101: rd_req_count_for_payload_next = rd_req_count_for_payload - 1; + 3'b110: rd_req_count_for_payload_next = rd_req_count_for_payload; // Don't queue new requests when current requests are pending + 3'b111: rd_req_count_for_payload_next = rd_req_count_for_payload - 1; // Don't queue new requests when current requests are pending + endcase + end + + // Requirement: + // * never stall read requests if block_size == 0, i.e. not using recovery mode + // * upon observing recovery_data_avail, request block_size bytes of data + // * make AXI requests one at a time + // * after all requests are made, stall until all data is transferred + // * after all data is transferred, continue stalling until recovery_data_avail + // * Final burst size may be less than block_size - so 'rd_req_count_for_payload' may remain non-zero + // until it is cleared by returning to IDLE state, although this is not a bug + always_ff @(posedge clk or negedge rst_n) begin + if (!rst_n) begin + rd_req_count_for_payload <= '0; + rd_req_stall <= 1'b0; + end + else if (hwif_out.block_size.size.value == '0) begin + rd_req_count_for_payload <= '0; + rd_req_stall <= 1'b0; + end + else if (ctrl_fsm_ps == DMA_IDLE) begin + rd_req_count_for_payload <= '0; + rd_req_stall <= 1'b1; + end + else begin + rd_req_count_for_payload <= rd_req_count_for_payload_next; + rd_req_stall <= ~|rd_req_count_for_payload_next || rd_req_hshake || (rd_credits < FIFO_BC/BC); // Force requests for "block_size != 0" to go out one at a time + end + end + + `else + // Detect recovery_data_avail rising edge + assign recovery_data_avail_p = recovery_data_avail && !recovery_data_avail_d; + + // When block_size != 0, we are guaranteed to be interacting with the SS recovery interface + // which means transactions will also be of FIXED burst type. + // This guarantees that each read request will be sized according to the constraints of + // block_size and MAX_FIXED_BLOCK_SIZE, without regard for address alignment boundaries or + // other conditions. + always_comb begin + case ({recovery_data_avail_p,rd_req_hshake}) inside + 2'b00: rd_req_count_for_payload_next = rd_req_count_for_payload; + 2'b01: rd_req_count_for_payload_next = rd_req_count_for_payload - 1; + 2'b10: rd_req_count_for_payload_next = rd_req_count_for_payload + `MAX_OF(hwif_out.block_size.size.value>>$clog2(MAX_FIXED_BLOCK_SIZE),1); + 2'b11: rd_req_count_for_payload_next = rd_req_count_for_payload + `MAX_OF(hwif_out.block_size.size.value>>$clog2(MAX_FIXED_BLOCK_SIZE),1) - 1; + endcase + end + + // Requirement: + // * never stall read requests if block_size == 0, i.e. not using recovery mode + // * upon observing recovery_data_avail, request block_size bytes of data + // * after all requests are made, stall until another rising edge on recovery_data_avail + // * Final burst size may be less than block_size - so 'rd_req_count_for_payload' may remain non-zero + // until it is cleared by returning to IDLE state + always_ff @(posedge clk or negedge rst_n) begin + if (!rst_n) begin + recovery_data_avail_d <= 1'b0; + rd_req_count_for_payload <= '0; + rd_req_stall <= 1'b0; + end + else if (hwif_out.block_size.size.value == '0) begin + recovery_data_avail_d <= 1'b0; + rd_req_count_for_payload <= '0; + rd_req_stall <= 1'b0; + end + // Treat 'go' as the rising edge-detection if recovery_data_avail is already set before DMA is armed + else if (ctrl_fsm_ps == DMA_IDLE) begin + recovery_data_avail_d <= 1'b0; + rd_req_count_for_payload <= '0; + rd_req_stall <= 1'b1; + end + else begin + recovery_data_avail_d <= recovery_data_avail; + rd_req_count_for_payload <= rd_req_count_for_payload_next; + rd_req_stall <= ~|rd_req_count_for_payload_next; + end + end + + `endif + + always_ff @(posedge clk or negedge rst_n) begin + if (!rst_n) begin + wr_resp_pending <= '0; + end + else if (ctrl_fsm_ps == DMA_IDLE) begin + wr_resp_pending <= '0; + end + else begin + case ({w_req_if.resp_valid,wr_req_hshake}) inside + 2'b00: wr_resp_pending <= wr_resp_pending; + 2'b01: wr_resp_pending <= wr_resp_pending + 2'b01; + 2'b10: wr_resp_pending <= wr_resp_pending - 2'b01; + 2'b11: wr_resp_pending <= wr_resp_pending; + endcase + end + end + + always_comb block_size_mask = hwif_out.block_size.size.value - 1; + always_comb begin + rd_align_req_byte_count = (hwif_out.ctrl.rd_fixed.value && (~|hwif_out.block_size.size.value || (MAX_FIXED_BLOCK_SIZE < hwif_out.block_size.size.value))) ? AXI_LEN_BC_WIDTH'(MAX_FIXED_BLOCK_SIZE) : + (hwif_out.ctrl.rd_fixed.value) ? AXI_LEN_BC_WIDTH'(hwif_out.block_size.size.value) : + (~|hwif_out.block_size.size.value || (MAX_BLOCK_SIZE < hwif_out.block_size.size.value)) ? AXI_LEN_BC_WIDTH'(MAX_BLOCK_SIZE - r_req_if.addr[$clog2(MAX_BLOCK_SIZE)-1:0]) : + AXI_LEN_BC_WIDTH'(hwif_out.block_size.size.value - (AXI_LEN_BC_WIDTH'(r_req_if.addr[$clog2(MAX_BLOCK_SIZE)-1:0]) & block_size_mask)); + rd_final_req_byte_count = rd_bytes_rem_thresh ? AXI_LEN_BC_WIDTH'(hwif_out.byte_count.count.value - rd_bytes_requested) : + {AXI_LEN_BC_WIDTH{1'b1}}; + rd_req_byte_count = rd_final_req_byte_count < rd_align_req_byte_count ? rd_final_req_byte_count : + rd_align_req_byte_count; + wr_align_req_byte_count = (hwif_out.ctrl.wr_fixed.value && (~|hwif_out.block_size.size.value || (MAX_FIXED_BLOCK_SIZE < hwif_out.block_size.size.value))) ? AXI_LEN_BC_WIDTH'(MAX_FIXED_BLOCK_SIZE) : + (hwif_out.ctrl.wr_fixed.value) ? AXI_LEN_BC_WIDTH'(hwif_out.block_size.size.value) : + (~|hwif_out.block_size.size.value || (MAX_BLOCK_SIZE < hwif_out.block_size.size.value)) ? AXI_LEN_BC_WIDTH'(MAX_BLOCK_SIZE - w_req_if.addr[$clog2(MAX_BLOCK_SIZE)-1:0]) : + AXI_LEN_BC_WIDTH'(hwif_out.block_size.size.value - (AXI_LEN_BC_WIDTH'(w_req_if.addr[$clog2(MAX_BLOCK_SIZE)-1:0]) & block_size_mask)); + wr_final_req_byte_count = wr_bytes_rem_thresh ? AXI_LEN_BC_WIDTH'(hwif_out.byte_count.count.value - wr_bytes_requested) : + {AXI_LEN_BC_WIDTH{1'b1}}; + wr_aes_ceil_req_byte_count = hwif_out.byte_count.count.value - wr_bytes_requested > AES_FIFO_BC ? AES_FIFO_BC : + AXI_LEN_BC_WIDTH'(hwif_out.byte_count.count.value - wr_bytes_requested); + wr_sel_req_byte_count = hwif_out.ctrl.aes_mode_en.value ? wr_aes_ceil_req_byte_count : wr_final_req_byte_count; + wr_req_byte_count = wr_sel_req_byte_count < wr_align_req_byte_count ? wr_sel_req_byte_count : + wr_align_req_byte_count; + end + + always_comb begin + r_req_if.valid = (ctrl_fsm_ps == DMA_WAIT_DATA) && !rd_req_hshake_bypass && (rd_bytes_requested < hwif_out.byte_count.count.value) && ((AXI_LEN_BC_WIDTH-BW)'(rd_credits) >= rd_req_byte_count[AXI_LEN_BC_WIDTH-1:BW]) && !rd_req_stall; + r_req_if.addr = src_addr + (hwif_out.ctrl.rd_fixed.value ? 0 : rd_bytes_requested); + r_req_if.byte_len = rd_req_byte_count - AXI_LEN_BC_WIDTH'(BC); + r_req_if.fixed = hwif_out.ctrl.rd_fixed.value; + r_req_if.lock = 1'b0; + + w_req_if.valid = (ctrl_fsm_ps == DMA_WAIT_DATA) && !wr_req_hshake_bypass && (wr_bytes_requested < hwif_out.byte_count.count.value) && ((AXI_LEN_BC_WIDTH-BW)'(wr_credits) >= wr_req_byte_count[AXI_LEN_BC_WIDTH-1:BW]); + w_req_if.addr = dst_addr + (hwif_out.ctrl.wr_fixed.value ? 0 : wr_bytes_requested); + w_req_if.byte_len = wr_req_byte_count - AXI_LEN_BC_WIDTH'(BC); + w_req_if.fixed = hwif_out.ctrl.wr_fixed.value; + w_req_if.lock = 1'b0; + end + + always_comb begin + // rd_route_MBOX is tied to wr_bytes_requested because AXI Reads translate to Mailbox writes + // and vice-versa for wr_route_MBOX + mb_dv = ctrl_fsm_ps == DMA_WAIT_DATA && + ((hwif_out.ctrl.rd_route.value == axi_dma_reg__ctrl__rd_route__rd_route_e__MBOX && + (wr_bytes_requested < hwif_out.byte_count.count) && + rd_route_valid) || + (hwif_out.ctrl.wr_route.value == axi_dma_reg__ctrl__wr_route__wr_route_e__MBOX && + (rd_bytes_requested < hwif_out.byte_count.count) && + fifo_w_ready)); + mb_data.addr = hwif_out.ctrl.rd_route.value == axi_dma_reg__ctrl__rd_route__rd_route_e__MBOX ? SOC_IFC_ADDR_W'(w_req_if.addr) : + SOC_IFC_ADDR_W'(r_req_if.addr); + mb_data.wdata = rd_route_data; + mb_data.wstrb = '1; + mb_data.user = SOC_IFC_USER_W'(0); + mb_data.id = '1; + mb_data.write = hwif_out.ctrl.rd_route.value == axi_dma_reg__ctrl__rd_route__rd_route_e__MBOX; + mb_data.soc_req = 1'b0; + end + + always_ff @(posedge clk or negedge rst_n) begin + if (!rst_n) begin + kv_read_en <= 1'b0; + end + else if (!kv_read_once && + hwif_out.ctrl.go.value && + (hwif_out.ctrl.wr_route.value == axi_dma_reg__ctrl__wr_route__wr_route_e__KEYVAULT) && + (!cmd_parse_error)) begin + kv_read_en <= 1'b1; + end + else if (kv_data_read_done) begin + kv_read_en <= 1'b0; + end + end + + always_ff @(posedge clk or negedge rst_n) begin + if (!rst_n) begin + kv_read_once <= 1'b0; + end + else if (kv_read_en) begin + kv_read_once <= 1'b1; + end + else if (ctrl_fsm_ps == DMA_IDLE) begin + kv_read_once <= 1'b0; + end + end + + // KeyVault Error Detection - Separate Signals for Better Observability + always_comb begin + // KV read operation error (existing functionality) + kv_read_error = kv_read_en && (kv_data_error_code != KV_SUCCESS) && (ctrl_fsm_ps == DMA_WAIT_DATA); + + // KV premature completion error (new functionality) + kv_premature_done_error = kv_data_read_done && + (ctrl_fsm_ps == DMA_WAIT_DATA) && + (rd_fifo_bytes_remaining != 32'h0); + + // Combined error signal for FSM transitions + kv_any_error = kv_read_error || kv_premature_done_error; + end + + always_comb begin + kv_read_ctrl_reg.read_en = kv_read_en && kv_data_kv_ready; + kv_read_ctrl_reg.pcr_hash_extend = '0; + kv_read_ctrl_reg.read_entry = OCP_LOCK_KEY_RELEASE_KV_SLOT; + kv_read_ctrl_reg.rsvd = '0; + end + + always_comb begin + rd_req_hshake = r_req_if.valid && r_req_if.ready; + wr_req_hshake = w_req_if.valid && w_req_if.ready; + rd_req_hshake_bypass = hwif_out.ctrl.rd_route.value == axi_dma_reg__ctrl__rd_route__rd_route_e__DISABLE; + wr_req_hshake_bypass = hwif_out.ctrl.wr_route.value == axi_dma_reg__ctrl__wr_route__wr_route_e__DISABLE; + end + + always_ff @(posedge clk or negedge rst_n) begin + if (!rst_n) begin + rd_bytes_requested <= '0; + rd_bytes_rem_thresh <= 1'b0; + end + else if (rd_req_hshake) begin + rd_bytes_requested <= rd_bytes_requested + rd_req_byte_count; + rd_bytes_rem_thresh <= ~|((hwif_out.byte_count.count.value - (rd_bytes_requested + rd_req_byte_count)) >> AXI_LEN_BC_WIDTH); + end + else if (mb_dv && !mb_data.write && !mb_hold) begin + rd_bytes_requested <= rd_bytes_requested + BC; + rd_bytes_rem_thresh <= ~|((hwif_out.byte_count.count.value - (rd_bytes_requested + BC)) >> AXI_LEN_BC_WIDTH); + end + else if (ctrl_fsm_ps == DMA_IDLE) begin + rd_bytes_requested <= '0; + rd_bytes_rem_thresh <= ~|hwif_out.byte_count.count.value[31:AXI_LEN_BC_WIDTH]; + end + end + always_ff @(posedge clk or negedge rst_n) begin + if (!rst_n) begin + wr_bytes_requested <= '0; + wr_bytes_rem_thresh <= 1'b0; + end + else if (wr_req_hshake) begin + wr_bytes_requested <= wr_bytes_requested + wr_req_byte_count; + wr_bytes_rem_thresh <= ~|((hwif_out.byte_count.count.value - (wr_bytes_requested + wr_req_byte_count)) >> AXI_LEN_BC_WIDTH); + end + else if (mb_dv && mb_data.write && !mb_hold) begin + wr_bytes_requested <= wr_bytes_requested + BC; + wr_bytes_rem_thresh <= ~|((hwif_out.byte_count.count.value - (wr_bytes_requested + BC)) >> AXI_LEN_BC_WIDTH); + end + else if (hwif_out.ctrl.rd_route.value == axi_dma_reg__ctrl__rd_route__rd_route_e__AHB_FIFO && hwif_out.read_data.rdata.swacc) begin + wr_bytes_requested <= wr_bytes_requested + BC; + wr_bytes_rem_thresh <= ~|((hwif_out.byte_count.count.value - (wr_bytes_requested + BC)) >> AXI_LEN_BC_WIDTH); + end + else if (ctrl_fsm_ps == DMA_IDLE) begin + wr_bytes_requested <= '0; + wr_bytes_rem_thresh <= ~|hwif_out.byte_count.count.value[31:AXI_LEN_BC_WIDTH]; + end + end + + // Read credits logic + always_ff @(posedge clk or negedge rst_n) begin + if (!rst_n) begin + rd_credits <= FIFO_BC/BC; + end + else if ((ctrl_fsm_ps == DMA_IDLE) || (rd_req_hshake_bypass)) begin + rd_credits <= FIFO_BC/BC; + end + // Request byte count is restricted to not exceed the credit capacity + // Assertions (below) enforce a legal byte_count for sims + else if (rd_req_hshake && (fifo_r_valid && fifo_r_ready)) begin + rd_credits <= rd_credits + 1 - FIFO_BW'(rd_req_byte_count[AXI_LEN_BC_WIDTH-1:BW]); + end + else if (rd_req_hshake) begin + rd_credits <= rd_credits - FIFO_BW'(rd_req_byte_count[AXI_LEN_BC_WIDTH-1:BW]); + end + else if (fifo_r_valid && fifo_r_ready) begin + rd_credits <= rd_credits + 1; + end + end + + // Write credits logic + assign wr_credits_fifo_w_valid = hwif_out.ctrl.aes_mode_en.value ? aes_fifo_w_valid: fifo_w_valid; + assign wr_credits_fifo_w_ready = hwif_out.ctrl.aes_mode_en.value ? aes_fifo_w_ready: fifo_w_ready; + + + always_ff @(posedge clk or negedge rst_n) begin + if (!rst_n) begin + wr_credits <= 0; + end + else if ((ctrl_fsm_ps == DMA_IDLE) || (wr_req_hshake_bypass)) begin + wr_credits <= 0; + end + // Request byte count is restricted to not exceed the credit capacity + // Assertions (below) enforce a legal byte_count for sims + else if (wr_req_hshake && (wr_credits_fifo_w_valid && wr_credits_fifo_w_ready)) begin + wr_credits <= wr_credits + 1 - FIFO_BW'(wr_req_byte_count[AXI_LEN_BC_WIDTH-1:BW]); + end + else if (wr_req_hshake) begin + wr_credits <= wr_credits - FIFO_BW'(wr_req_byte_count[AXI_LEN_BC_WIDTH-1:BW]); + end + else if (wr_credits_fifo_w_valid && wr_credits_fifo_w_ready) begin + wr_credits <= wr_credits + 1; + end + end + + always_ff @(posedge clk or negedge rst_n) begin + if (!rst_n) begin + bytes_remaining <= '0; + end + else if (ctrl_fsm_ps == DMA_IDLE && hwif_out.ctrl.go.value) begin + bytes_remaining <= hwif_out.byte_count.count; + end + else if (fifo_r_valid && fifo_r_ready) begin + bytes_remaining <= bytes_remaining - BC; + end + end + + always_ff @(posedge clk or negedge rst_n) begin + if (!rst_n) begin + rd_fifo_bytes_remaining <= '0; + end + else if (ctrl_fsm_ps == DMA_IDLE && hwif_out.ctrl.go.value) begin + rd_fifo_bytes_remaining <= hwif_out.byte_count.count; + end + else if (fifo_w_valid && fifo_w_ready) begin + rd_fifo_bytes_remaining <= rd_fifo_bytes_remaining - BC; + end + end + + always_comb begin + if (hwif_out.ctrl.wr_route.value == axi_dma_reg__ctrl__wr_route__wr_route_e__AHB_FIFO) begin + fifo_w_data = req_data.wdata; + fifo_w_valid = hwif_out.write_data.wdata.swmod; + end + else if (hwif_out.ctrl.wr_route.value == axi_dma_reg__ctrl__wr_route__wr_route_e__MBOX) begin + fifo_w_data = mb_rdata; + fifo_w_valid = mb_dv && !mb_hold; + end + else if (hwif_out.ctrl.wr_route.value == axi_dma_reg__ctrl__wr_route__wr_route_e__KEYVAULT) begin + fifo_w_data = kv_data_write_data; + fifo_w_valid = kv_data_write_en && |(rd_fifo_bytes_remaining); // FIXME no backpressure on this signal, FIFO must accept every assertion + end + else begin + fifo_w_data = r_data_i; + fifo_w_valid = r_valid_i; + end + r_ready_o = fifo_w_ready; + end + + //////////////////////////////////////////////////// + // FIFO -> Read Route + //////////////////////////////////////////////////// + assign rd_route_data = hwif_out.ctrl.aes_mode_en.value ? aes_fsm_rd_route_data: fifo_r_data; + assign rd_route_valid = hwif_out.ctrl.aes_mode_en.value ? aes_fsm_rd_route_valid: fifo_r_valid; + + //////////////////////////////////////////////////// + // Read Route -> FIFO + //////////////////////////////////////////////////// + assign fifo_r_ready = hwif_out.ctrl.aes_mode_en.value ? aes_fsm_rd_route_ready: rd_route_ready; + + always_comb begin + + if (hwif_out.ctrl.rd_route.value == axi_dma_reg__ctrl__rd_route__rd_route_e__MBOX) begin + rd_route_ready = !mb_hold; + end + else if (hwif_out.ctrl.rd_route.value == axi_dma_reg__ctrl__rd_route__rd_route_e__AHB_FIFO) begin + rd_route_ready = hwif_out.read_data.rdata.swacc; + end + else begin + rd_route_ready = w_ready_i; + end + end + + //////////////////////////////////////////////////// + // Read Route -> AXI + //////////////////////////////////////////////////// + assign w_valid_o = rd_route_valid; + assign w_data_o = rd_route_data; + + //////////////////////////////////////////////////// + // Read Route -> AHB + //////////////////////////////////////////////////// + always_comb r_data_mask = {DW{hwif_out.ctrl.rd_route.value == axi_dma_reg__ctrl__rd_route__rd_route_e__AHB_FIFO}}; + always_comb hwif_in.read_data.rdata.next = rd_route_data & r_data_mask; + + + // Runtime Errors + always_ff @(posedge clk or negedge rst_n) begin + if (!rst_n) begin + axi_error <= 1'b0; + end + else if (ctrl_fsm_ps == DMA_IDLE || hwif_out.ctrl.flush.value) begin + axi_error <= 1'b0; + end + else if (r_req_if.resp_valid) begin + axi_error <= axi_error | (r_req_if.resp inside {AXI_RESP_SLVERR,AXI_RESP_DECERR}); + end + else if (w_req_if.resp_valid) begin + axi_error <= axi_error | (w_req_if.resp inside {AXI_RESP_SLVERR,AXI_RESP_DECERR}); + end + end + + always_comb mb_lock_dropped = ctrl_fsm_ps == DMA_WAIT_DATA && + ((hwif_out.ctrl.rd_route.value == axi_dma_reg__ctrl__rd_route__rd_route_e__MBOX) || + (hwif_out.ctrl.wr_route.value == axi_dma_reg__ctrl__wr_route__wr_route_e__MBOX)) && + !mbox_lock; + always_ff @(posedge clk or negedge rst_n) begin + if (!rst_n) begin + mb_lock_error <= 1'b0; + end + else if (ctrl_fsm_ps == DMA_IDLE || hwif_out.ctrl.flush.value) begin + mb_lock_error <= 1'b0; + end + else if (mb_lock_dropped) begin + mb_lock_error <= mb_lock_error | 1'b1; + end + end + + // --------------------------------------- // + // AES FSM // + // --------------------------------------- // + always_ff @(posedge clk or negedge rst_n) begin + if (!rst_n) begin + aes_fsm_ps <= AES_IDLE; + aes_init_done <= '0; + aes_to_axi_last_transfer <= '0; + end else begin + aes_fsm_ps <= aes_fsm_ns; + aes_init_done <= aes_init_done_next; + aes_to_axi_last_transfer <= aes_to_axi_last_transfer_next; + end + end + + // AES FSM next-state logic + always_comb begin + aes_fsm_ns = aes_fsm_ps; + aes_init_done_next = aes_init_done; + aes_to_axi_last_transfer_next = aes_to_axi_last_transfer; + case (aes_fsm_ps) + AES_IDLE: begin + // Start condition (add your own trigger) + if (start_aes_fsm) begin + aes_fsm_ns = AES_WAIT_INPUT_READY; + end + aes_init_done_next = 1'b0; + aes_to_axi_last_transfer_next = 1'b0; + end + AES_WAIT_INPUT_READY: begin + if (aes_input_ready) begin + if((!aes_init_done || bytes_remaining < 16) && hwif_out.ctrl.aes_gcm_mode.value) begin + aes_fsm_ns = AES_WAIT_IDLE; + end + else begin + aes_fsm_ns = AES_WRITE_BLOCK; + end + end + end + AES_WAIT_IDLE: begin + if(aes_status_idle) begin + aes_fsm_ns = AES_UPDATE_BYTE_COUNT; + end + end + AES_UPDATE_BYTE_COUNT: begin + // After writing CCM_SHAOWED register twice + if (aes_cif_update_byte_count_done) begin + aes_fsm_ns = AES_WRITE_BLOCK; + end + end + AES_WRITE_BLOCK: begin + // After writing 4 words + if (aes_cif_write_block_done) begin + aes_init_done_next = 1'b1; + // If transfer is > 4 DWORDs we need to push + // more content into AES before we start + // reading data out. + if (!aes_init_done && (bytes_remaining > 0)) begin + aes_fsm_ns = AES_WAIT_INPUT_READY; + end else begin + // If the transfer is =< 4DWORDs the "init" transfer + // is the last transfer and we need to indicate + // to AES_READ_OUTPUT this is the last transfer. + if(!aes_init_done && (bytes_remaining == 0)) begin + aes_to_axi_last_transfer_next = 1'b1; + end + aes_fsm_ns = AES_WAIT_OUTPUT_VALID; + end + end + end + AES_WAIT_OUTPUT_VALID: begin + if (aes_output_valid) begin + aes_fsm_ns = AES_READ_OUTPUT; + end + end + AES_READ_OUTPUT: begin + if (aes_cif_read_block_done) begin + // Final transfer and read out of AES is done so go into + // AES_ERROR or AES_DONE state + if (aes_to_axi_last_transfer) begin + if(aes_error) begin + aes_fsm_ns = AES_ERROR; + end else begin + aes_fsm_ns = AES_DONE; + end + end + // At this point we have transerted all data into + // AES but we still have one more block to read out of + // AES that we "buffered" into the AES on the first set of + // writes into AES. This allows us to read that last bit + // of data out of AES and the next time around we will + // transition into AES_ERROR or AES_DONE. This only + // happens when the size of the transfer is > 4 DWORDs + // anything smaller and there is not buffering of data + // since the payload is too small. + else if(bytes_remaining == '0) begin + aes_to_axi_last_transfer_next = 1'b1; + aes_fsm_ns = AES_WAIT_OUTPUT_VALID; + end + // When we are at the last block of data transfered into + // the AES we need to update the byte count in the AES if + // we are in GCM mode. + else if(bytes_remaining > 0 && bytes_remaining < 16 && hwif_out.ctrl.aes_gcm_mode.value) begin + aes_fsm_ns = AES_WAIT_IDLE; + end + // Typical transfer into AES is done and we are streaming + // another 4 DWORDs into the AES. + else begin + aes_fsm_ns = AES_WRITE_BLOCK; + end + end + end + AES_DONE: begin + aes_fsm_ns = AES_IDLE; + end + AES_ERROR: begin + if (hwif_out.ctrl.flush.value) begin + aes_fsm_ns = AES_IDLE; + end + end + default: aes_fsm_ns = AES_IDLE; + endcase + end + + // --------------------------------------- // + // AES Control Logic // + // --------------------------------------- // + + // AES CIF read counter and done logic + always_ff @(posedge clk or negedge rst_n) begin + if (!rst_n) begin + aes_cif_read_cnt <= '0; + end else begin + aes_cif_read_cnt <= aes_cif_read_cnt_next; + end + end + + // Count when detecting a CIF read + assign aes_cif_read_cnt_incr = !aes_req_hold && aes_req_dv & !aes_req_data.write; + + always_comb begin + aes_cif_read_cnt_next = aes_cif_read_cnt; + if (aes_cif_read_cnt_incr) begin + aes_cif_read_cnt_next = aes_cif_read_cnt + 1; + end + else if (aes_fsm_ps != AES_READ_OUTPUT) begin + aes_cif_read_cnt_next = '0; + end + end + + // Once we have read all 4 output rgisters indicate reading is done + // If not all 4 DWORDs contain data the data is blocked from going + // into the FIFO, but we always read 4 DWORDS from the AES + assign aes_cif_read_block_done = (aes_cif_read_cnt == 2'd3) && aes_cif_read_cnt_incr; + + + + // AES write block counter + assign aes_cif_write_cnt_incr = aes_req_dv & !aes_req_hold & aes_req_data.write; + + always_ff @(posedge clk or negedge rst_n) begin + if (!rst_n) begin + aes_cif_write_cnt <= '0; + end else begin + aes_cif_write_cnt <= aes_cif_write_cnt_next; + end + end + + + // When switching states reset or when we are not in a known writing state + // reset the write counter + assign aes_cif_write_cnt_reset = (aes_fsm_ps != aes_fsm_ns) || + ((aes_fsm_ps != AES_WRITE_BLOCK) && (aes_fsm_ps != AES_UPDATE_BYTE_COUNT)); + + always_comb begin + aes_cif_write_cnt_next = aes_cif_write_cnt; + if (aes_cif_write_cnt_reset) begin + aes_cif_write_cnt_next = '0; + end else if (aes_cif_write_cnt_incr) begin + aes_cif_write_cnt_next = aes_cif_write_cnt + 1'b1; + end + end + + // AES Byte update is just a single write. Once write is done we are done in this phase + assign aes_cif_update_byte_count_done = (aes_cif_write_cnt == 2'd1) && aes_cif_write_cnt_incr; + + // AES CIF write block done logic + assign aes_cif_write_block_done = (aes_cif_write_cnt == 2'd3) && aes_cif_write_cnt_incr; + + + // Latch AES request signals if aes_req_hold is asserted + always_ff @(posedge clk or negedge rst_n) begin + if (!rst_n) begin + aes_req_dv_q <= 1'b0; + end else begin + aes_req_dv_q <= aes_req_dv; + end + end + // AES CIF DV Control + always_comb begin + aes_req_dv = aes_req_dv_q; + if (aes_fsm_ps == AES_WRITE_BLOCK) begin + if (bytes_remaining > 0) begin + if(fifo_r_valid) begin + aes_req_dv = 1'b1; + end + else if (!fifo_r_valid && !aes_req_wait) begin + aes_req_dv = 1'b0; // No data available, do not assert request + end + end + else begin + aes_req_dv = 1'b1; + end + end else if(aes_fsm_ps == AES_UPDATE_BYTE_COUNT) begin + aes_req_dv = 1'b1; + end else if(aes_fsm_ps == AES_READ_OUTPUT && !aes_fifo_full) begin + aes_req_dv = 1'b1; + end + else begin + aes_req_dv = 1'b0; // Not in write block state, do not assert request + end + end + + // AES CIF Data Control + always_comb begin + aes_req_data = '0; // Default to zero + + // AES CIF same on read/write non-zero values + aes_req_data.id = '1; + + if (aes_fsm_ps == AES_WRITE_BLOCK) begin + // AES CIF Write Assignments + aes_req_data.addr = 19'((`AES_REG_DATA_IN_0 + (aes_cif_write_cnt * BC))) ; + aes_req_data.wstrb = '1; + aes_req_data.write = 1'b1; + aes_req_data.wdata = (bytes_remaining > 32'h0) ? fifo_r_data : '0; // Default to 0s + end else if(aes_fsm_ps == AES_UPDATE_BYTE_COUNT) begin + // AES CIF Update Byte Count Assignments + aes_req_data.addr = `AES_REG_CTRL_GCM_SHADOWED; + aes_req_data.wstrb = '1; + aes_req_data.write = 1'b1; + aes_req_data.wdata = (((bytes_remaining > 32'd16 ? 32'd16 : bytes_remaining ) << `AES_REG_CTRL_GCM_SHADOWED_NUM_VALID_BYTES_LOW) & `AES_REG_CTRL_GCM_SHADOWED_NUM_VALID_BYTES_MASK) | + ((6'h8 << `AES_REG_CTRL_GCM_SHADOWED_PHASE_LOW) & `AES_REG_CTRL_GCM_SHADOWED_PHASE_MASK); + end else if(aes_fsm_ps == AES_READ_OUTPUT) begin + // AES CIF Read Assignments + aes_req_data.addr = 19'((`AES_REG_DATA_OUT_0 + (aes_cif_read_cnt * BC))); + aes_req_data.write = 1'b0; + aes_req_data.wdata = '0; // Default to 0s + end + end + + + always_ff @(posedge clk or negedge rst_n) begin + if (!rst_n) begin + aes_req_wait <= 1'b0; + end else begin + aes_req_wait <= aes_req_wait_next; + end + end + always_comb begin + // Track if we are waiting for hold to clear + aes_req_wait_next = (aes_req_dv && aes_req_hold); + end + + // Pulling data off main fifo when we initiate the CIF transaction. + // Assumption is that AES has their aes_req_hold asserted when DMA asserts + // aes_req_dv first clock cycle of a transaction to AES + assign aes_fsm_rd_route_ready = (fifo_r_valid && aes_req_dv && !aes_req_wait && aes_fsm_ps == AES_WRITE_BLOCK); + + + assign start_aes_fsm = (ctrl_fsm_ps == DMA_IDLE) && (hwif_out.ctrl.go.value) && !cmd_parse_error && hwif_out.ctrl.aes_mode_en.value; + + + + + // AES error detect logic + always_ff @(posedge clk or negedge rst_n) begin + if (!rst_n) begin + aes_error <= 1'b0; + end + else if (ctrl_fsm_ps == DMA_IDLE || hwif_out.ctrl.flush.value) begin + aes_error <= 1'b0; + end + else if (aes_err && aes_req_dv) begin + aes_error <= 1'b1; + end + end + + // --------------------------------------- // + // KeyVault Read Client // + // --------------------------------------- // + always_comb begin + kv_read_metrics.ocp_lock_in_progress = ocp_lock_in_progress; + kv_read_metrics.kv_read_dest = KV_NUM_READ'(1< r_req_if.byte_len < MAX_BLOCK_SIZE, clk, !rst_n) + `CALIPTRA_ASSERT(AXI_DMA_VLD_WR_REQ_LEN, wr_req_hshake |-> w_req_if.byte_len < MAX_BLOCK_SIZE, clk, !rst_n) + `CALIPTRA_ASSERT(AXI_DMA_VLD_FIXED_RD_REQ_LEN, rd_req_hshake && r_req_if.fixed |-> r_req_if.byte_len < MAX_FIXED_BLOCK_SIZE, clk, !rst_n) + `CALIPTRA_ASSERT(AXI_DMA_VLD_FIXED_WR_REQ_LEN, wr_req_hshake && w_req_if.fixed |-> w_req_if.byte_len < MAX_FIXED_BLOCK_SIZE, clk, !rst_n) + // Requests must not cross AXI boundary (4KiB) + `CALIPTRA_ASSERT(AXI_DMA_VLD_RD_REQ_BND, rd_req_hshake && !r_req_if.fixed |-> r_req_if.addr[AW-1:AXI_LEN_BC_WIDTH] == ((r_req_if.addr + r_req_if.byte_len) >> AXI_LEN_BC_WIDTH), clk, !rst_n) + `CALIPTRA_ASSERT(AXI_DMA_VLD_WR_REQ_BND, wr_req_hshake && !w_req_if.fixed |-> w_req_if.addr[AW-1:AXI_LEN_BC_WIDTH] == ((w_req_if.addr + w_req_if.byte_len) >> AXI_LEN_BC_WIDTH), clk, !rst_n) + // Proper configuration + `CALIPTRA_ASSERT_INIT(AXI_DMA_DW_32, DW == 32) + `CALIPTRA_ASSERT_INIT(AXI_DMA_DW_EQ_MB, DW == CPTRA_MBOX_DATA_W) + // FIFO must have space for all requested data + `CALIPTRA_ASSERT(AXI_DMA_LIM_RD_CRED, rd_credits <= FIFO_BC/BC, clk, !rst_n) + `CALIPTRA_ASSERT(AXI_DMA_OFL_RD_CRED, rd_req_hshake |-> rd_req_byte_count <= FIFO_BC, clk, !rst_n) + `CALIPTRA_ASSERT(AXI_DMA_MIN_RD_CRED, !((rd_credits < 1) && rd_req_hshake), clk, !rst_n) + `CALIPTRA_ASSERT(AXI_DMA_RST_RD_CRED, (ctrl_fsm_ps == DMA_DONE) |-> (rd_credits == FIFO_BC/BC), clk, !rst_n) + `CALIPTRA_ASSERT(AXI_DMA_LIM_WR_CRED, wr_credits <= FIFO_BC/BC, clk, !rst_n) + `CALIPTRA_ASSERT(AXI_DMA_UFL_WR_CRED, wr_req_hshake |-> wr_credits >= wr_req_byte_count[AXI_LEN_BC_WIDTH-1:BW], clk, !rst_n) + `CALIPTRA_ASSERT(AXI_DMA_MIN_WR_CRED, !((wr_credits < 1) && wr_req_hshake), clk, !rst_n) + `CALIPTRA_ASSERT(AXI_DMA_RST_WR_CRED, (ctrl_fsm_ps == DMA_DONE) |-> (wr_credits == 0), clk, !rst_n) + // AES FSM sync with DMA FSM + `CALIPTRA_ASSERT(AXI_DMA_AES_FSM_DONE_SYNC, (ctrl_fsm_ps == DMA_DONE && hwif_out.ctrl.aes_mode_en.value) |-> (aes_fsm_ps == AES_DONE || aes_fsm_ps == AES_IDLE), clk, !rst_n) + `CALIPTRA_ASSERT(AXI_DMA_AES_FSM_ERR_SYNC, (ctrl_fsm_ps == DMA_ERROR && hwif_out.ctrl.aes_mode_en.value && !cmd_parse_error) |-> (aes_fsm_ps == AES_ERROR), clk, !rst_n) + `CALIPTRA_ASSERT(AXI_DMA_AES_FSM_IDLE_SYNC, (aes_fsm_ps != AES_IDLE) |-> (ctrl_fsm_ps != DMA_IDLE), clk, !rst_n) + // AES FIFO ensure no underflow/overflow + `CALIPTRA_ASSERT(AXI_DMA_AES_FIFO_WRITE_VALID, (aes_fifo_w_valid) |-> (aes_fifo_w_ready), clk, !rst_n) + `CALIPTRA_ASSERT(AXI_DMA_AES_FIFO_WRITE_NOT_FULL, (aes_fifo_w_valid) |-> (!aes_fifo_full), clk, !rst_n) + `CALIPTRA_ASSERT(AXI_DMA_AES_FIFO_READ_VALID, (aes_fifo_r_ready) |-> (aes_fifo_r_valid), clk, !rst_n) + + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/axi_dma_reg.sv b/designs/Caliptra/src/caliptra-rtl/axi_dma_reg.sv new file mode 100644 index 0000000..81b09a5 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/axi_dma_reg.sv @@ -0,0 +1,3747 @@ +// Generated by PeakRDL-regblock - A free and open-source SystemVerilog generator +// https://github.com/SystemRDL/PeakRDL-regblock + +module axi_dma_reg ( + input wire clk, + input wire rst, + + input wire s_cpuif_req, + input wire s_cpuif_req_is_wr, + input wire [11:0] s_cpuif_addr, + input wire [31:0] s_cpuif_wr_data, + input wire [31:0] s_cpuif_wr_biten, + output wire s_cpuif_req_stall_wr, + output wire s_cpuif_req_stall_rd, + output wire s_cpuif_rd_ack, + output wire s_cpuif_rd_err, + output wire [31:0] s_cpuif_rd_data, + output wire s_cpuif_wr_ack, + output wire s_cpuif_wr_err, + + input axi_dma_reg_pkg::axi_dma_reg__in_t hwif_in, + output axi_dma_reg_pkg::axi_dma_reg__out_t hwif_out + ); + + //-------------------------------------------------------------------------- + // CPU Bus interface logic + //-------------------------------------------------------------------------- + logic cpuif_req; + logic cpuif_req_is_wr; + logic [11:0] cpuif_addr; + logic [31:0] cpuif_wr_data; + logic [31:0] cpuif_wr_biten; + logic cpuif_req_stall_wr; + logic cpuif_req_stall_rd; + + logic cpuif_rd_ack; + logic cpuif_rd_err; + logic [31:0] cpuif_rd_data; + + logic cpuif_wr_ack; + logic cpuif_wr_err; + + assign cpuif_req = s_cpuif_req; + assign cpuif_req_is_wr = s_cpuif_req_is_wr; + assign cpuif_addr = s_cpuif_addr; + assign cpuif_wr_data = s_cpuif_wr_data; + assign cpuif_wr_biten = s_cpuif_wr_biten; + assign s_cpuif_req_stall_wr = cpuif_req_stall_wr; + assign s_cpuif_req_stall_rd = cpuif_req_stall_rd; + assign s_cpuif_rd_ack = cpuif_rd_ack; + assign s_cpuif_rd_err = cpuif_rd_err; + assign s_cpuif_rd_data = cpuif_rd_data; + assign s_cpuif_wr_ack = cpuif_wr_ack; + assign s_cpuif_wr_err = cpuif_wr_err; + + logic cpuif_req_masked; + + // Read & write latencies are balanced. Stalls not required + assign cpuif_req_stall_rd = '0; + assign cpuif_req_stall_wr = '0; + assign cpuif_req_masked = cpuif_req + & !(!cpuif_req_is_wr & cpuif_req_stall_rd) + & !(cpuif_req_is_wr & cpuif_req_stall_wr); + + //-------------------------------------------------------------------------- + // Address Decode + //-------------------------------------------------------------------------- + typedef struct packed{ + logic id; + logic cap; + logic ctrl; + logic status0; + logic status1; + logic src_addr_l; + logic src_addr_h; + logic dst_addr_l; + logic dst_addr_h; + logic byte_count; + logic block_size; + logic write_data; + logic read_data; + struct packed{ + logic global_intr_en_r; + logic error_intr_en_r; + logic notif_intr_en_r; + logic error_global_intr_r; + logic notif_global_intr_r; + logic error_internal_intr_r; + logic notif_internal_intr_r; + logic error_intr_trig_r; + logic notif_intr_trig_r; + logic error_cmd_dec_intr_count_r; + logic error_axi_rd_intr_count_r; + logic error_axi_wr_intr_count_r; + logic error_mbox_lock_intr_count_r; + logic error_sha_lock_intr_count_r; + logic error_fifo_oflow_intr_count_r; + logic error_fifo_uflow_intr_count_r; + logic error_aes_cif_intr_count_r; + logic error_kv_rd_intr_count_r; + logic error_kv_rd_large_intr_count_r; + logic notif_txn_done_intr_count_r; + logic notif_fifo_empty_intr_count_r; + logic notif_fifo_not_empty_intr_count_r; + logic notif_fifo_full_intr_count_r; + logic notif_fifo_not_full_intr_count_r; + logic error_cmd_dec_intr_count_incr_r; + logic error_axi_rd_intr_count_incr_r; + logic error_axi_wr_intr_count_incr_r; + logic error_mbox_lock_intr_count_incr_r; + logic error_sha_lock_intr_count_incr_r; + logic error_fifo_oflow_intr_count_incr_r; + logic error_fifo_uflow_intr_count_incr_r; + logic error_aes_cif_intr_count_incr_r; + logic error_kv_rd_intr_count_incr_r; + logic error_kv_rd_large_intr_count_incr_r; + logic notif_txn_done_intr_count_incr_r; + logic notif_fifo_empty_intr_count_incr_r; + logic notif_fifo_not_empty_intr_count_incr_r; + logic notif_fifo_full_intr_count_incr_r; + logic notif_fifo_not_full_intr_count_incr_r; + } intr_block_rf; + } decoded_reg_strb_t; + decoded_reg_strb_t decoded_reg_strb; + logic decoded_req; + logic decoded_req_is_wr; + logic [31:0] decoded_wr_data; + logic [31:0] decoded_wr_biten; + + always_comb begin + decoded_reg_strb.id = cpuif_req_masked & (cpuif_addr == 12'h0); + decoded_reg_strb.cap = cpuif_req_masked & (cpuif_addr == 12'h4); + decoded_reg_strb.ctrl = cpuif_req_masked & (cpuif_addr == 12'h8); + decoded_reg_strb.status0 = cpuif_req_masked & (cpuif_addr == 12'hc); + decoded_reg_strb.status1 = cpuif_req_masked & (cpuif_addr == 12'h10); + decoded_reg_strb.src_addr_l = cpuif_req_masked & (cpuif_addr == 12'h14); + decoded_reg_strb.src_addr_h = cpuif_req_masked & (cpuif_addr == 12'h18); + decoded_reg_strb.dst_addr_l = cpuif_req_masked & (cpuif_addr == 12'h1c); + decoded_reg_strb.dst_addr_h = cpuif_req_masked & (cpuif_addr == 12'h20); + decoded_reg_strb.byte_count = cpuif_req_masked & (cpuif_addr == 12'h24); + decoded_reg_strb.block_size = cpuif_req_masked & (cpuif_addr == 12'h28); + decoded_reg_strb.write_data = cpuif_req_masked & (cpuif_addr == 12'h2c); + decoded_reg_strb.read_data = cpuif_req_masked & (cpuif_addr == 12'h30); + decoded_reg_strb.intr_block_rf.global_intr_en_r = cpuif_req_masked & (cpuif_addr == 12'h800); + decoded_reg_strb.intr_block_rf.error_intr_en_r = cpuif_req_masked & (cpuif_addr == 12'h804); + decoded_reg_strb.intr_block_rf.notif_intr_en_r = cpuif_req_masked & (cpuif_addr == 12'h808); + decoded_reg_strb.intr_block_rf.error_global_intr_r = cpuif_req_masked & (cpuif_addr == 12'h80c); + decoded_reg_strb.intr_block_rf.notif_global_intr_r = cpuif_req_masked & (cpuif_addr == 12'h810); + decoded_reg_strb.intr_block_rf.error_internal_intr_r = cpuif_req_masked & (cpuif_addr == 12'h814); + decoded_reg_strb.intr_block_rf.notif_internal_intr_r = cpuif_req_masked & (cpuif_addr == 12'h818); + decoded_reg_strb.intr_block_rf.error_intr_trig_r = cpuif_req_masked & (cpuif_addr == 12'h81c); + decoded_reg_strb.intr_block_rf.notif_intr_trig_r = cpuif_req_masked & (cpuif_addr == 12'h820); + decoded_reg_strb.intr_block_rf.error_cmd_dec_intr_count_r = cpuif_req_masked & (cpuif_addr == 12'h900); + decoded_reg_strb.intr_block_rf.error_axi_rd_intr_count_r = cpuif_req_masked & (cpuif_addr == 12'h904); + decoded_reg_strb.intr_block_rf.error_axi_wr_intr_count_r = cpuif_req_masked & (cpuif_addr == 12'h908); + decoded_reg_strb.intr_block_rf.error_mbox_lock_intr_count_r = cpuif_req_masked & (cpuif_addr == 12'h90c); + decoded_reg_strb.intr_block_rf.error_sha_lock_intr_count_r = cpuif_req_masked & (cpuif_addr == 12'h910); + decoded_reg_strb.intr_block_rf.error_fifo_oflow_intr_count_r = cpuif_req_masked & (cpuif_addr == 12'h914); + decoded_reg_strb.intr_block_rf.error_fifo_uflow_intr_count_r = cpuif_req_masked & (cpuif_addr == 12'h918); + decoded_reg_strb.intr_block_rf.error_aes_cif_intr_count_r = cpuif_req_masked & (cpuif_addr == 12'h91c); + decoded_reg_strb.intr_block_rf.error_kv_rd_intr_count_r = cpuif_req_masked & (cpuif_addr == 12'h920); + decoded_reg_strb.intr_block_rf.error_kv_rd_large_intr_count_r = cpuif_req_masked & (cpuif_addr == 12'h924); + decoded_reg_strb.intr_block_rf.notif_txn_done_intr_count_r = cpuif_req_masked & (cpuif_addr == 12'h980); + decoded_reg_strb.intr_block_rf.notif_fifo_empty_intr_count_r = cpuif_req_masked & (cpuif_addr == 12'h984); + decoded_reg_strb.intr_block_rf.notif_fifo_not_empty_intr_count_r = cpuif_req_masked & (cpuif_addr == 12'h988); + decoded_reg_strb.intr_block_rf.notif_fifo_full_intr_count_r = cpuif_req_masked & (cpuif_addr == 12'h98c); + decoded_reg_strb.intr_block_rf.notif_fifo_not_full_intr_count_r = cpuif_req_masked & (cpuif_addr == 12'h990); + decoded_reg_strb.intr_block_rf.error_cmd_dec_intr_count_incr_r = cpuif_req_masked & (cpuif_addr == 12'ha00); + decoded_reg_strb.intr_block_rf.error_axi_rd_intr_count_incr_r = cpuif_req_masked & (cpuif_addr == 12'ha04); + decoded_reg_strb.intr_block_rf.error_axi_wr_intr_count_incr_r = cpuif_req_masked & (cpuif_addr == 12'ha08); + decoded_reg_strb.intr_block_rf.error_mbox_lock_intr_count_incr_r = cpuif_req_masked & (cpuif_addr == 12'ha0c); + decoded_reg_strb.intr_block_rf.error_sha_lock_intr_count_incr_r = cpuif_req_masked & (cpuif_addr == 12'ha10); + decoded_reg_strb.intr_block_rf.error_fifo_oflow_intr_count_incr_r = cpuif_req_masked & (cpuif_addr == 12'ha14); + decoded_reg_strb.intr_block_rf.error_fifo_uflow_intr_count_incr_r = cpuif_req_masked & (cpuif_addr == 12'ha18); + decoded_reg_strb.intr_block_rf.error_aes_cif_intr_count_incr_r = cpuif_req_masked & (cpuif_addr == 12'ha1c); + decoded_reg_strb.intr_block_rf.error_kv_rd_intr_count_incr_r = cpuif_req_masked & (cpuif_addr == 12'ha20); + decoded_reg_strb.intr_block_rf.error_kv_rd_large_intr_count_incr_r = cpuif_req_masked & (cpuif_addr == 12'ha24); + decoded_reg_strb.intr_block_rf.notif_txn_done_intr_count_incr_r = cpuif_req_masked & (cpuif_addr == 12'ha28); + decoded_reg_strb.intr_block_rf.notif_fifo_empty_intr_count_incr_r = cpuif_req_masked & (cpuif_addr == 12'ha2c); + decoded_reg_strb.intr_block_rf.notif_fifo_not_empty_intr_count_incr_r = cpuif_req_masked & (cpuif_addr == 12'ha30); + decoded_reg_strb.intr_block_rf.notif_fifo_full_intr_count_incr_r = cpuif_req_masked & (cpuif_addr == 12'ha34); + decoded_reg_strb.intr_block_rf.notif_fifo_not_full_intr_count_incr_r = cpuif_req_masked & (cpuif_addr == 12'ha38); + end + + // Pass down signals to next stage + assign decoded_req = cpuif_req_masked; + assign decoded_req_is_wr = cpuif_req_is_wr; + assign decoded_wr_data = cpuif_wr_data; + assign decoded_wr_biten = cpuif_wr_biten; + + //-------------------------------------------------------------------------- + // Field logic + //-------------------------------------------------------------------------- + typedef struct packed{ + struct packed{ + struct packed{ + logic next; + logic load_next; + } go; + struct packed{ + logic next; + logic load_next; + } flush; + struct packed{ + logic next; + logic load_next; + } aes_mode_en; + struct packed{ + logic next; + logic load_next; + } aes_gcm_mode; + struct packed{ + logic [1:0] next; + logic load_next; + } rd_route; + struct packed{ + logic next; + logic load_next; + } rd_fixed; + struct packed{ + logic [2:0] next; + logic load_next; + } wr_route; + struct packed{ + logic next; + logic load_next; + } wr_fixed; + } ctrl; + struct packed{ + struct packed{ + logic [1:0] next; + logic load_next; + } axi_dma_fsm_ps; + struct packed{ + logic [3:0] next; + logic load_next; + } axi_dma_aes_fsm_ps; + } status0; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } addr_l; + } src_addr_l; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } addr_h; + } src_addr_h; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } addr_l; + } dst_addr_l; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } addr_h; + } dst_addr_h; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } count; + } byte_count; + struct packed{ + struct packed{ + logic [11:0] next; + logic load_next; + } size; + } block_size; + struct packed{ + struct packed{ + struct packed{ + logic next; + logic load_next; + } error_en; + struct packed{ + logic next; + logic load_next; + } notif_en; + } global_intr_en_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + } error_cmd_dec_en; + struct packed{ + logic next; + logic load_next; + } error_axi_rd_en; + struct packed{ + logic next; + logic load_next; + } error_axi_wr_en; + struct packed{ + logic next; + logic load_next; + } error_mbox_lock_en; + struct packed{ + logic next; + logic load_next; + } error_sha_lock_en; + struct packed{ + logic next; + logic load_next; + } error_fifo_oflow_en; + struct packed{ + logic next; + logic load_next; + } error_fifo_uflow_en; + struct packed{ + logic next; + logic load_next; + } error_aes_cif_en; + struct packed{ + logic next; + logic load_next; + } error_kv_rd_en; + struct packed{ + logic next; + logic load_next; + } error_kv_rd_large_en; + } error_intr_en_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + } notif_txn_done_en; + struct packed{ + logic next; + logic load_next; + } notif_fifo_empty_en; + struct packed{ + logic next; + logic load_next; + } notif_fifo_not_empty_en; + struct packed{ + logic next; + logic load_next; + } notif_fifo_full_en; + struct packed{ + logic next; + logic load_next; + } notif_fifo_not_full_en; + } notif_intr_en_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + } agg_sts; + } error_global_intr_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + } agg_sts; + } notif_global_intr_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + } error_cmd_dec_sts; + struct packed{ + logic next; + logic load_next; + } error_axi_rd_sts; + struct packed{ + logic next; + logic load_next; + } error_axi_wr_sts; + struct packed{ + logic next; + logic load_next; + } error_mbox_lock_sts; + struct packed{ + logic next; + logic load_next; + } error_sha_lock_sts; + struct packed{ + logic next; + logic load_next; + } error_fifo_oflow_sts; + struct packed{ + logic next; + logic load_next; + } error_fifo_uflow_sts; + struct packed{ + logic next; + logic load_next; + } error_aes_cif_sts; + struct packed{ + logic next; + logic load_next; + } error_kv_rd_sts; + struct packed{ + logic next; + logic load_next; + } error_kv_rd_large_sts; + } error_internal_intr_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + } notif_txn_done_sts; + struct packed{ + logic next; + logic load_next; + } notif_fifo_empty_sts; + struct packed{ + logic next; + logic load_next; + } notif_fifo_not_empty_sts; + struct packed{ + logic next; + logic load_next; + } notif_fifo_full_sts; + struct packed{ + logic next; + logic load_next; + } notif_fifo_not_full_sts; + } notif_internal_intr_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + } error_cmd_dec_trig; + struct packed{ + logic next; + logic load_next; + } error_axi_rd_trig; + struct packed{ + logic next; + logic load_next; + } error_axi_wr_trig; + struct packed{ + logic next; + logic load_next; + } error_mbox_lock_trig; + struct packed{ + logic next; + logic load_next; + } error_sha_lock_trig; + struct packed{ + logic next; + logic load_next; + } error_fifo_oflow_trig; + struct packed{ + logic next; + logic load_next; + } error_fifo_uflow_trig; + struct packed{ + logic next; + logic load_next; + } error_aes_cif_trig; + struct packed{ + logic next; + logic load_next; + } error_kv_rd_trig; + struct packed{ + logic next; + logic load_next; + } error_kv_rd_large_trig; + } error_intr_trig_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + } notif_txn_done_trig; + struct packed{ + logic next; + logic load_next; + } notif_fifo_empty_trig; + struct packed{ + logic next; + logic load_next; + } notif_fifo_not_empty_trig; + struct packed{ + logic next; + logic load_next; + } notif_fifo_full_trig; + struct packed{ + logic next; + logic load_next; + } notif_fifo_not_full_trig; + } notif_intr_trig_r; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + logic incrthreshold; + logic incrsaturate; + } cnt; + } error_cmd_dec_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + logic incrthreshold; + logic incrsaturate; + } cnt; + } error_axi_rd_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + logic incrthreshold; + logic incrsaturate; + } cnt; + } error_axi_wr_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + logic incrthreshold; + logic incrsaturate; + } cnt; + } error_mbox_lock_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + logic incrthreshold; + logic incrsaturate; + } cnt; + } error_sha_lock_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + logic incrthreshold; + logic incrsaturate; + } cnt; + } error_fifo_oflow_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + logic incrthreshold; + logic incrsaturate; + } cnt; + } error_fifo_uflow_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + logic incrthreshold; + logic incrsaturate; + } cnt; + } error_aes_cif_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + logic incrthreshold; + logic incrsaturate; + } cnt; + } error_kv_rd_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + logic incrthreshold; + logic incrsaturate; + } cnt; + } error_kv_rd_large_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + logic incrthreshold; + logic incrsaturate; + } cnt; + } notif_txn_done_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + logic incrthreshold; + logic incrsaturate; + } cnt; + } notif_fifo_empty_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + logic incrthreshold; + logic incrsaturate; + } cnt; + } notif_fifo_not_empty_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + logic incrthreshold; + logic incrsaturate; + } cnt; + } notif_fifo_full_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + logic incrthreshold; + logic incrsaturate; + } cnt; + } notif_fifo_not_full_intr_count_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + logic decrthreshold; + logic underflow; + } pulse; + } error_cmd_dec_intr_count_incr_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + logic decrthreshold; + logic underflow; + } pulse; + } error_axi_rd_intr_count_incr_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + logic decrthreshold; + logic underflow; + } pulse; + } error_axi_wr_intr_count_incr_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + logic decrthreshold; + logic underflow; + } pulse; + } error_mbox_lock_intr_count_incr_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + logic decrthreshold; + logic underflow; + } pulse; + } error_sha_lock_intr_count_incr_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + logic decrthreshold; + logic underflow; + } pulse; + } error_fifo_oflow_intr_count_incr_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + logic decrthreshold; + logic underflow; + } pulse; + } error_fifo_uflow_intr_count_incr_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + logic decrthreshold; + logic underflow; + } pulse; + } error_aes_cif_intr_count_incr_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + logic decrthreshold; + logic underflow; + } pulse; + } error_kv_rd_intr_count_incr_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + logic decrthreshold; + logic underflow; + } pulse; + } error_kv_rd_large_intr_count_incr_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + logic decrthreshold; + logic underflow; + } pulse; + } notif_txn_done_intr_count_incr_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + logic decrthreshold; + logic underflow; + } pulse; + } notif_fifo_empty_intr_count_incr_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + logic decrthreshold; + logic underflow; + } pulse; + } notif_fifo_not_empty_intr_count_incr_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + logic decrthreshold; + logic underflow; + } pulse; + } notif_fifo_full_intr_count_incr_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + logic decrthreshold; + logic underflow; + } pulse; + } notif_fifo_not_full_intr_count_incr_r; + } intr_block_rf; + } field_combo_t; + field_combo_t field_combo; + + typedef struct packed{ + struct packed{ + struct packed{ + logic value; + } go; + struct packed{ + logic value; + } flush; + struct packed{ + logic value; + } aes_mode_en; + struct packed{ + logic value; + } aes_gcm_mode; + struct packed{ + logic [1:0] value; + } rd_route; + struct packed{ + logic value; + } rd_fixed; + struct packed{ + logic [2:0] value; + } wr_route; + struct packed{ + logic value; + } wr_fixed; + } ctrl; + struct packed{ + struct packed{ + logic [1:0] value; + } axi_dma_fsm_ps; + struct packed{ + logic [3:0] value; + } axi_dma_aes_fsm_ps; + } status0; + struct packed{ + struct packed{ + logic [31:0] value; + } addr_l; + } src_addr_l; + struct packed{ + struct packed{ + logic [31:0] value; + } addr_h; + } src_addr_h; + struct packed{ + struct packed{ + logic [31:0] value; + } addr_l; + } dst_addr_l; + struct packed{ + struct packed{ + logic [31:0] value; + } addr_h; + } dst_addr_h; + struct packed{ + struct packed{ + logic [31:0] value; + } count; + } byte_count; + struct packed{ + struct packed{ + logic [11:0] value; + } size; + } block_size; + struct packed{ + struct packed{ + struct packed{ + logic value; + } error_en; + struct packed{ + logic value; + } notif_en; + } global_intr_en_r; + struct packed{ + struct packed{ + logic value; + } error_cmd_dec_en; + struct packed{ + logic value; + } error_axi_rd_en; + struct packed{ + logic value; + } error_axi_wr_en; + struct packed{ + logic value; + } error_mbox_lock_en; + struct packed{ + logic value; + } error_sha_lock_en; + struct packed{ + logic value; + } error_fifo_oflow_en; + struct packed{ + logic value; + } error_fifo_uflow_en; + struct packed{ + logic value; + } error_aes_cif_en; + struct packed{ + logic value; + } error_kv_rd_en; + struct packed{ + logic value; + } error_kv_rd_large_en; + } error_intr_en_r; + struct packed{ + struct packed{ + logic value; + } notif_txn_done_en; + struct packed{ + logic value; + } notif_fifo_empty_en; + struct packed{ + logic value; + } notif_fifo_not_empty_en; + struct packed{ + logic value; + } notif_fifo_full_en; + struct packed{ + logic value; + } notif_fifo_not_full_en; + } notif_intr_en_r; + struct packed{ + struct packed{ + logic value; + } agg_sts; + } error_global_intr_r; + struct packed{ + struct packed{ + logic value; + } agg_sts; + } notif_global_intr_r; + struct packed{ + struct packed{ + logic value; + } error_cmd_dec_sts; + struct packed{ + logic value; + } error_axi_rd_sts; + struct packed{ + logic value; + } error_axi_wr_sts; + struct packed{ + logic value; + } error_mbox_lock_sts; + struct packed{ + logic value; + } error_sha_lock_sts; + struct packed{ + logic value; + } error_fifo_oflow_sts; + struct packed{ + logic value; + } error_fifo_uflow_sts; + struct packed{ + logic value; + } error_aes_cif_sts; + struct packed{ + logic value; + } error_kv_rd_sts; + struct packed{ + logic value; + } error_kv_rd_large_sts; + } error_internal_intr_r; + struct packed{ + struct packed{ + logic value; + } notif_txn_done_sts; + struct packed{ + logic value; + } notif_fifo_empty_sts; + struct packed{ + logic value; + } notif_fifo_not_empty_sts; + struct packed{ + logic value; + } notif_fifo_full_sts; + struct packed{ + logic value; + } notif_fifo_not_full_sts; + } notif_internal_intr_r; + struct packed{ + struct packed{ + logic value; + } error_cmd_dec_trig; + struct packed{ + logic value; + } error_axi_rd_trig; + struct packed{ + logic value; + } error_axi_wr_trig; + struct packed{ + logic value; + } error_mbox_lock_trig; + struct packed{ + logic value; + } error_sha_lock_trig; + struct packed{ + logic value; + } error_fifo_oflow_trig; + struct packed{ + logic value; + } error_fifo_uflow_trig; + struct packed{ + logic value; + } error_aes_cif_trig; + struct packed{ + logic value; + } error_kv_rd_trig; + struct packed{ + logic value; + } error_kv_rd_large_trig; + } error_intr_trig_r; + struct packed{ + struct packed{ + logic value; + } notif_txn_done_trig; + struct packed{ + logic value; + } notif_fifo_empty_trig; + struct packed{ + logic value; + } notif_fifo_not_empty_trig; + struct packed{ + logic value; + } notif_fifo_full_trig; + struct packed{ + logic value; + } notif_fifo_not_full_trig; + } notif_intr_trig_r; + struct packed{ + struct packed{ + logic [31:0] value; + } cnt; + } error_cmd_dec_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] value; + } cnt; + } error_axi_rd_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] value; + } cnt; + } error_axi_wr_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] value; + } cnt; + } error_mbox_lock_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] value; + } cnt; + } error_sha_lock_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] value; + } cnt; + } error_fifo_oflow_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] value; + } cnt; + } error_fifo_uflow_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] value; + } cnt; + } error_aes_cif_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] value; + } cnt; + } error_kv_rd_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] value; + } cnt; + } error_kv_rd_large_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] value; + } cnt; + } notif_txn_done_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] value; + } cnt; + } notif_fifo_empty_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] value; + } cnt; + } notif_fifo_not_empty_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] value; + } cnt; + } notif_fifo_full_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] value; + } cnt; + } notif_fifo_not_full_intr_count_r; + struct packed{ + struct packed{ + logic value; + } pulse; + } error_cmd_dec_intr_count_incr_r; + struct packed{ + struct packed{ + logic value; + } pulse; + } error_axi_rd_intr_count_incr_r; + struct packed{ + struct packed{ + logic value; + } pulse; + } error_axi_wr_intr_count_incr_r; + struct packed{ + struct packed{ + logic value; + } pulse; + } error_mbox_lock_intr_count_incr_r; + struct packed{ + struct packed{ + logic value; + } pulse; + } error_sha_lock_intr_count_incr_r; + struct packed{ + struct packed{ + logic value; + } pulse; + } error_fifo_oflow_intr_count_incr_r; + struct packed{ + struct packed{ + logic value; + } pulse; + } error_fifo_uflow_intr_count_incr_r; + struct packed{ + struct packed{ + logic value; + } pulse; + } error_aes_cif_intr_count_incr_r; + struct packed{ + struct packed{ + logic value; + } pulse; + } error_kv_rd_intr_count_incr_r; + struct packed{ + struct packed{ + logic value; + } pulse; + } error_kv_rd_large_intr_count_incr_r; + struct packed{ + struct packed{ + logic value; + } pulse; + } notif_txn_done_intr_count_incr_r; + struct packed{ + struct packed{ + logic value; + } pulse; + } notif_fifo_empty_intr_count_incr_r; + struct packed{ + struct packed{ + logic value; + } pulse; + } notif_fifo_not_empty_intr_count_incr_r; + struct packed{ + struct packed{ + logic value; + } pulse; + } notif_fifo_full_intr_count_incr_r; + struct packed{ + struct packed{ + logic value; + } pulse; + } notif_fifo_not_full_intr_count_incr_r; + } intr_block_rf; + } field_storage_t; + field_storage_t field_storage; + + // Field: axi_dma_reg.ctrl.go + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.ctrl.go.value; + load_next_c = '0; + if(decoded_reg_strb.ctrl && decoded_req_is_wr && !(hwif_in.dma_swwel)) begin // SW write 1 set + next_c = field_storage.ctrl.go.value | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end else if(hwif_in.ctrl.go.hwclr) begin // HW Clear + next_c = '0; + load_next_c = '1; + end + field_combo.ctrl.go.next = next_c; + field_combo.ctrl.go.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.ctrl.go.value <= 1'h0; + end else if(field_combo.ctrl.go.load_next) begin + field_storage.ctrl.go.value <= field_combo.ctrl.go.next; + end + end + assign hwif_out.ctrl.go.value = field_storage.ctrl.go.value; + assign hwif_out.ctrl.go.swmod = decoded_reg_strb.ctrl && decoded_req_is_wr; + // Field: axi_dma_reg.ctrl.flush + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.ctrl.flush.value; + load_next_c = '0; + if(decoded_reg_strb.ctrl && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write 1 set + next_c = field_storage.ctrl.flush.value | (decoded_wr_data[1:1] & decoded_wr_biten[1:1]); + load_next_c = '1; + end else if(hwif_in.ctrl.flush.hwclr) begin // HW Clear + next_c = '0; + load_next_c = '1; + end + field_combo.ctrl.flush.next = next_c; + field_combo.ctrl.flush.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.ctrl.flush.value <= 1'h0; + end else if(field_combo.ctrl.flush.load_next) begin + field_storage.ctrl.flush.value <= field_combo.ctrl.flush.next; + end + end + assign hwif_out.ctrl.flush.value = field_storage.ctrl.flush.value; + // Field: axi_dma_reg.ctrl.aes_mode_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.ctrl.aes_mode_en.value; + load_next_c = '0; + if(decoded_reg_strb.ctrl && decoded_req_is_wr && !(hwif_in.dma_swwel)) begin // SW write + next_c = (field_storage.ctrl.aes_mode_en.value & ~decoded_wr_biten[2:2]) | (decoded_wr_data[2:2] & decoded_wr_biten[2:2]); + load_next_c = '1; + end + field_combo.ctrl.aes_mode_en.next = next_c; + field_combo.ctrl.aes_mode_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.ctrl.aes_mode_en.value <= 1'h0; + end else if(field_combo.ctrl.aes_mode_en.load_next) begin + field_storage.ctrl.aes_mode_en.value <= field_combo.ctrl.aes_mode_en.next; + end + end + assign hwif_out.ctrl.aes_mode_en.value = field_storage.ctrl.aes_mode_en.value; + // Field: axi_dma_reg.ctrl.aes_gcm_mode + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.ctrl.aes_gcm_mode.value; + load_next_c = '0; + if(decoded_reg_strb.ctrl && decoded_req_is_wr && !(hwif_in.dma_swwel)) begin // SW write + next_c = (field_storage.ctrl.aes_gcm_mode.value & ~decoded_wr_biten[3:3]) | (decoded_wr_data[3:3] & decoded_wr_biten[3:3]); + load_next_c = '1; + end + field_combo.ctrl.aes_gcm_mode.next = next_c; + field_combo.ctrl.aes_gcm_mode.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.ctrl.aes_gcm_mode.value <= 1'h0; + end else if(field_combo.ctrl.aes_gcm_mode.load_next) begin + field_storage.ctrl.aes_gcm_mode.value <= field_combo.ctrl.aes_gcm_mode.next; + end + end + assign hwif_out.ctrl.aes_gcm_mode.value = field_storage.ctrl.aes_gcm_mode.value; + // Field: axi_dma_reg.ctrl.rd_route + always_comb begin + automatic logic [1:0] next_c; + automatic logic load_next_c; + next_c = field_storage.ctrl.rd_route.value; + load_next_c = '0; + if(decoded_reg_strb.ctrl && decoded_req_is_wr && !(hwif_in.dma_swwel)) begin // SW write + next_c = (field_storage.ctrl.rd_route.value & ~decoded_wr_biten[17:16]) | (decoded_wr_data[17:16] & decoded_wr_biten[17:16]); + load_next_c = '1; + end + field_combo.ctrl.rd_route.next = next_c; + field_combo.ctrl.rd_route.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.ctrl.rd_route.value <= 2'h0; + end else if(field_combo.ctrl.rd_route.load_next) begin + field_storage.ctrl.rd_route.value <= field_combo.ctrl.rd_route.next; + end + end + assign hwif_out.ctrl.rd_route.value = field_storage.ctrl.rd_route.value; + // Field: axi_dma_reg.ctrl.rd_fixed + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.ctrl.rd_fixed.value; + load_next_c = '0; + if(decoded_reg_strb.ctrl && decoded_req_is_wr && !(hwif_in.dma_swwel)) begin // SW write + next_c = (field_storage.ctrl.rd_fixed.value & ~decoded_wr_biten[20:20]) | (decoded_wr_data[20:20] & decoded_wr_biten[20:20]); + load_next_c = '1; + end + field_combo.ctrl.rd_fixed.next = next_c; + field_combo.ctrl.rd_fixed.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.ctrl.rd_fixed.value <= 1'h0; + end else if(field_combo.ctrl.rd_fixed.load_next) begin + field_storage.ctrl.rd_fixed.value <= field_combo.ctrl.rd_fixed.next; + end + end + assign hwif_out.ctrl.rd_fixed.value = field_storage.ctrl.rd_fixed.value; + // Field: axi_dma_reg.ctrl.wr_route + always_comb begin + automatic logic [2:0] next_c; + automatic logic load_next_c; + next_c = field_storage.ctrl.wr_route.value; + load_next_c = '0; + if(decoded_reg_strb.ctrl && decoded_req_is_wr && !(hwif_in.dma_swwel)) begin // SW write + next_c = (field_storage.ctrl.wr_route.value & ~decoded_wr_biten[26:24]) | (decoded_wr_data[26:24] & decoded_wr_biten[26:24]); + load_next_c = '1; + end + field_combo.ctrl.wr_route.next = next_c; + field_combo.ctrl.wr_route.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.ctrl.wr_route.value <= 3'h0; + end else if(field_combo.ctrl.wr_route.load_next) begin + field_storage.ctrl.wr_route.value <= field_combo.ctrl.wr_route.next; + end + end + assign hwif_out.ctrl.wr_route.value = field_storage.ctrl.wr_route.value; + // Field: axi_dma_reg.ctrl.wr_fixed + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.ctrl.wr_fixed.value; + load_next_c = '0; + if(decoded_reg_strb.ctrl && decoded_req_is_wr && !(hwif_in.dma_swwel)) begin // SW write + next_c = (field_storage.ctrl.wr_fixed.value & ~decoded_wr_biten[28:28]) | (decoded_wr_data[28:28] & decoded_wr_biten[28:28]); + load_next_c = '1; + end + field_combo.ctrl.wr_fixed.next = next_c; + field_combo.ctrl.wr_fixed.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.ctrl.wr_fixed.value <= 1'h0; + end else if(field_combo.ctrl.wr_fixed.load_next) begin + field_storage.ctrl.wr_fixed.value <= field_combo.ctrl.wr_fixed.next; + end + end + assign hwif_out.ctrl.wr_fixed.value = field_storage.ctrl.wr_fixed.value; + // Field: axi_dma_reg.status0.axi_dma_fsm_ps + always_comb begin + automatic logic [1:0] next_c; + automatic logic load_next_c; + next_c = field_storage.status0.axi_dma_fsm_ps.value; + load_next_c = '0; + + // HW Write + next_c = hwif_in.status0.axi_dma_fsm_ps.next; + load_next_c = '1; + field_combo.status0.axi_dma_fsm_ps.next = next_c; + field_combo.status0.axi_dma_fsm_ps.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.status0.axi_dma_fsm_ps.value <= 2'h0; + end else if(field_combo.status0.axi_dma_fsm_ps.load_next) begin + field_storage.status0.axi_dma_fsm_ps.value <= field_combo.status0.axi_dma_fsm_ps.next; + end + end + assign hwif_out.status0.axi_dma_fsm_ps.value = field_storage.status0.axi_dma_fsm_ps.value; + // Field: axi_dma_reg.status0.axi_dma_aes_fsm_ps + always_comb begin + automatic logic [3:0] next_c; + automatic logic load_next_c; + next_c = field_storage.status0.axi_dma_aes_fsm_ps.value; + load_next_c = '0; + + // HW Write + next_c = hwif_in.status0.axi_dma_aes_fsm_ps.next; + load_next_c = '1; + field_combo.status0.axi_dma_aes_fsm_ps.next = next_c; + field_combo.status0.axi_dma_aes_fsm_ps.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.status0.axi_dma_aes_fsm_ps.value <= 4'h0; + end else if(field_combo.status0.axi_dma_aes_fsm_ps.load_next) begin + field_storage.status0.axi_dma_aes_fsm_ps.value <= field_combo.status0.axi_dma_aes_fsm_ps.next; + end + end + assign hwif_out.status0.axi_dma_aes_fsm_ps.value = field_storage.status0.axi_dma_aes_fsm_ps.value; + // Field: axi_dma_reg.src_addr_l.addr_l + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.src_addr_l.addr_l.value; + load_next_c = '0; + if(decoded_reg_strb.src_addr_l && decoded_req_is_wr && !(hwif_in.dma_swwel)) begin // SW write + next_c = (field_storage.src_addr_l.addr_l.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + field_combo.src_addr_l.addr_l.next = next_c; + field_combo.src_addr_l.addr_l.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.src_addr_l.addr_l.value <= 32'h0; + end else if(field_combo.src_addr_l.addr_l.load_next) begin + field_storage.src_addr_l.addr_l.value <= field_combo.src_addr_l.addr_l.next; + end + end + assign hwif_out.src_addr_l.addr_l.value = field_storage.src_addr_l.addr_l.value; + // Field: axi_dma_reg.src_addr_h.addr_h + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.src_addr_h.addr_h.value; + load_next_c = '0; + if(decoded_reg_strb.src_addr_h && decoded_req_is_wr && !(hwif_in.dma_swwel)) begin // SW write + next_c = (field_storage.src_addr_h.addr_h.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + field_combo.src_addr_h.addr_h.next = next_c; + field_combo.src_addr_h.addr_h.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.src_addr_h.addr_h.value <= 32'h0; + end else if(field_combo.src_addr_h.addr_h.load_next) begin + field_storage.src_addr_h.addr_h.value <= field_combo.src_addr_h.addr_h.next; + end + end + assign hwif_out.src_addr_h.addr_h.value = field_storage.src_addr_h.addr_h.value; + // Field: axi_dma_reg.dst_addr_l.addr_l + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.dst_addr_l.addr_l.value; + load_next_c = '0; + if(decoded_reg_strb.dst_addr_l && decoded_req_is_wr && !(hwif_in.dma_swwel)) begin // SW write + next_c = (field_storage.dst_addr_l.addr_l.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + field_combo.dst_addr_l.addr_l.next = next_c; + field_combo.dst_addr_l.addr_l.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.dst_addr_l.addr_l.value <= 32'h0; + end else if(field_combo.dst_addr_l.addr_l.load_next) begin + field_storage.dst_addr_l.addr_l.value <= field_combo.dst_addr_l.addr_l.next; + end + end + assign hwif_out.dst_addr_l.addr_l.value = field_storage.dst_addr_l.addr_l.value; + // Field: axi_dma_reg.dst_addr_h.addr_h + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.dst_addr_h.addr_h.value; + load_next_c = '0; + if(decoded_reg_strb.dst_addr_h && decoded_req_is_wr && !(hwif_in.dma_swwel)) begin // SW write + next_c = (field_storage.dst_addr_h.addr_h.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + field_combo.dst_addr_h.addr_h.next = next_c; + field_combo.dst_addr_h.addr_h.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.dst_addr_h.addr_h.value <= 32'h0; + end else if(field_combo.dst_addr_h.addr_h.load_next) begin + field_storage.dst_addr_h.addr_h.value <= field_combo.dst_addr_h.addr_h.next; + end + end + assign hwif_out.dst_addr_h.addr_h.value = field_storage.dst_addr_h.addr_h.value; + // Field: axi_dma_reg.byte_count.count + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.byte_count.count.value; + load_next_c = '0; + if(decoded_reg_strb.byte_count && decoded_req_is_wr && !(hwif_in.dma_swwel)) begin // SW write + next_c = (field_storage.byte_count.count.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + field_combo.byte_count.count.next = next_c; + field_combo.byte_count.count.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.byte_count.count.value <= 32'h0; + end else if(field_combo.byte_count.count.load_next) begin + field_storage.byte_count.count.value <= field_combo.byte_count.count.next; + end + end + assign hwif_out.byte_count.count.value = field_storage.byte_count.count.value; + // Field: axi_dma_reg.block_size.size + always_comb begin + automatic logic [11:0] next_c; + automatic logic load_next_c; + next_c = field_storage.block_size.size.value; + load_next_c = '0; + if(decoded_reg_strb.block_size && decoded_req_is_wr && !(hwif_in.dma_swwel)) begin // SW write + next_c = (field_storage.block_size.size.value & ~decoded_wr_biten[11:0]) | (decoded_wr_data[11:0] & decoded_wr_biten[11:0]); + load_next_c = '1; + end + field_combo.block_size.size.next = next_c; + field_combo.block_size.size.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.block_size.size.value <= 12'h0; + end else if(field_combo.block_size.size.load_next) begin + field_storage.block_size.size.value <= field_combo.block_size.size.next; + end + end + assign hwif_out.block_size.size.value = field_storage.block_size.size.value; + assign hwif_out.write_data.wdata.swmod = decoded_reg_strb.write_data && decoded_req_is_wr; + assign hwif_out.read_data.rdata.swacc = decoded_reg_strb.read_data; + // Field: axi_dma_reg.intr_block_rf.global_intr_en_r.error_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.global_intr_en_r.error_en.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.global_intr_en_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.intr_block_rf.global_intr_en_r.error_en.value & ~decoded_wr_biten[0:0]) | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end + field_combo.intr_block_rf.global_intr_en_r.error_en.next = next_c; + field_combo.intr_block_rf.global_intr_en_r.error_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.global_intr_en_r.error_en.value <= 1'h0; + end else if(field_combo.intr_block_rf.global_intr_en_r.error_en.load_next) begin + field_storage.intr_block_rf.global_intr_en_r.error_en.value <= field_combo.intr_block_rf.global_intr_en_r.error_en.next; + end + end + // Field: axi_dma_reg.intr_block_rf.global_intr_en_r.notif_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.global_intr_en_r.notif_en.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.global_intr_en_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.intr_block_rf.global_intr_en_r.notif_en.value & ~decoded_wr_biten[1:1]) | (decoded_wr_data[1:1] & decoded_wr_biten[1:1]); + load_next_c = '1; + end + field_combo.intr_block_rf.global_intr_en_r.notif_en.next = next_c; + field_combo.intr_block_rf.global_intr_en_r.notif_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.global_intr_en_r.notif_en.value <= 1'h0; + end else if(field_combo.intr_block_rf.global_intr_en_r.notif_en.load_next) begin + field_storage.intr_block_rf.global_intr_en_r.notif_en.value <= field_combo.intr_block_rf.global_intr_en_r.notif_en.next; + end + end + // Field: axi_dma_reg.intr_block_rf.error_intr_en_r.error_cmd_dec_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_intr_en_r.error_cmd_dec_en.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_intr_en_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.intr_block_rf.error_intr_en_r.error_cmd_dec_en.value & ~decoded_wr_biten[0:0]) | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end + field_combo.intr_block_rf.error_intr_en_r.error_cmd_dec_en.next = next_c; + field_combo.intr_block_rf.error_intr_en_r.error_cmd_dec_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.error_intr_en_r.error_cmd_dec_en.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_intr_en_r.error_cmd_dec_en.load_next) begin + field_storage.intr_block_rf.error_intr_en_r.error_cmd_dec_en.value <= field_combo.intr_block_rf.error_intr_en_r.error_cmd_dec_en.next; + end + end + // Field: axi_dma_reg.intr_block_rf.error_intr_en_r.error_axi_rd_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_intr_en_r.error_axi_rd_en.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_intr_en_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.intr_block_rf.error_intr_en_r.error_axi_rd_en.value & ~decoded_wr_biten[1:1]) | (decoded_wr_data[1:1] & decoded_wr_biten[1:1]); + load_next_c = '1; + end + field_combo.intr_block_rf.error_intr_en_r.error_axi_rd_en.next = next_c; + field_combo.intr_block_rf.error_intr_en_r.error_axi_rd_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.error_intr_en_r.error_axi_rd_en.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_intr_en_r.error_axi_rd_en.load_next) begin + field_storage.intr_block_rf.error_intr_en_r.error_axi_rd_en.value <= field_combo.intr_block_rf.error_intr_en_r.error_axi_rd_en.next; + end + end + // Field: axi_dma_reg.intr_block_rf.error_intr_en_r.error_axi_wr_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_intr_en_r.error_axi_wr_en.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_intr_en_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.intr_block_rf.error_intr_en_r.error_axi_wr_en.value & ~decoded_wr_biten[2:2]) | (decoded_wr_data[2:2] & decoded_wr_biten[2:2]); + load_next_c = '1; + end + field_combo.intr_block_rf.error_intr_en_r.error_axi_wr_en.next = next_c; + field_combo.intr_block_rf.error_intr_en_r.error_axi_wr_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.error_intr_en_r.error_axi_wr_en.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_intr_en_r.error_axi_wr_en.load_next) begin + field_storage.intr_block_rf.error_intr_en_r.error_axi_wr_en.value <= field_combo.intr_block_rf.error_intr_en_r.error_axi_wr_en.next; + end + end + // Field: axi_dma_reg.intr_block_rf.error_intr_en_r.error_mbox_lock_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_intr_en_r.error_mbox_lock_en.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_intr_en_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.intr_block_rf.error_intr_en_r.error_mbox_lock_en.value & ~decoded_wr_biten[3:3]) | (decoded_wr_data[3:3] & decoded_wr_biten[3:3]); + load_next_c = '1; + end + field_combo.intr_block_rf.error_intr_en_r.error_mbox_lock_en.next = next_c; + field_combo.intr_block_rf.error_intr_en_r.error_mbox_lock_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.error_intr_en_r.error_mbox_lock_en.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_intr_en_r.error_mbox_lock_en.load_next) begin + field_storage.intr_block_rf.error_intr_en_r.error_mbox_lock_en.value <= field_combo.intr_block_rf.error_intr_en_r.error_mbox_lock_en.next; + end + end + // Field: axi_dma_reg.intr_block_rf.error_intr_en_r.error_sha_lock_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_intr_en_r.error_sha_lock_en.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_intr_en_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.intr_block_rf.error_intr_en_r.error_sha_lock_en.value & ~decoded_wr_biten[4:4]) | (decoded_wr_data[4:4] & decoded_wr_biten[4:4]); + load_next_c = '1; + end + field_combo.intr_block_rf.error_intr_en_r.error_sha_lock_en.next = next_c; + field_combo.intr_block_rf.error_intr_en_r.error_sha_lock_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.error_intr_en_r.error_sha_lock_en.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_intr_en_r.error_sha_lock_en.load_next) begin + field_storage.intr_block_rf.error_intr_en_r.error_sha_lock_en.value <= field_combo.intr_block_rf.error_intr_en_r.error_sha_lock_en.next; + end + end + // Field: axi_dma_reg.intr_block_rf.error_intr_en_r.error_fifo_oflow_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_intr_en_r.error_fifo_oflow_en.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_intr_en_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.intr_block_rf.error_intr_en_r.error_fifo_oflow_en.value & ~decoded_wr_biten[5:5]) | (decoded_wr_data[5:5] & decoded_wr_biten[5:5]); + load_next_c = '1; + end + field_combo.intr_block_rf.error_intr_en_r.error_fifo_oflow_en.next = next_c; + field_combo.intr_block_rf.error_intr_en_r.error_fifo_oflow_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.error_intr_en_r.error_fifo_oflow_en.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_intr_en_r.error_fifo_oflow_en.load_next) begin + field_storage.intr_block_rf.error_intr_en_r.error_fifo_oflow_en.value <= field_combo.intr_block_rf.error_intr_en_r.error_fifo_oflow_en.next; + end + end + // Field: axi_dma_reg.intr_block_rf.error_intr_en_r.error_fifo_uflow_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_intr_en_r.error_fifo_uflow_en.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_intr_en_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.intr_block_rf.error_intr_en_r.error_fifo_uflow_en.value & ~decoded_wr_biten[6:6]) | (decoded_wr_data[6:6] & decoded_wr_biten[6:6]); + load_next_c = '1; + end + field_combo.intr_block_rf.error_intr_en_r.error_fifo_uflow_en.next = next_c; + field_combo.intr_block_rf.error_intr_en_r.error_fifo_uflow_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.error_intr_en_r.error_fifo_uflow_en.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_intr_en_r.error_fifo_uflow_en.load_next) begin + field_storage.intr_block_rf.error_intr_en_r.error_fifo_uflow_en.value <= field_combo.intr_block_rf.error_intr_en_r.error_fifo_uflow_en.next; + end + end + // Field: axi_dma_reg.intr_block_rf.error_intr_en_r.error_aes_cif_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_intr_en_r.error_aes_cif_en.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_intr_en_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.intr_block_rf.error_intr_en_r.error_aes_cif_en.value & ~decoded_wr_biten[7:7]) | (decoded_wr_data[7:7] & decoded_wr_biten[7:7]); + load_next_c = '1; + end + field_combo.intr_block_rf.error_intr_en_r.error_aes_cif_en.next = next_c; + field_combo.intr_block_rf.error_intr_en_r.error_aes_cif_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.error_intr_en_r.error_aes_cif_en.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_intr_en_r.error_aes_cif_en.load_next) begin + field_storage.intr_block_rf.error_intr_en_r.error_aes_cif_en.value <= field_combo.intr_block_rf.error_intr_en_r.error_aes_cif_en.next; + end + end + // Field: axi_dma_reg.intr_block_rf.error_intr_en_r.error_kv_rd_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_intr_en_r.error_kv_rd_en.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_intr_en_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.intr_block_rf.error_intr_en_r.error_kv_rd_en.value & ~decoded_wr_biten[8:8]) | (decoded_wr_data[8:8] & decoded_wr_biten[8:8]); + load_next_c = '1; + end + field_combo.intr_block_rf.error_intr_en_r.error_kv_rd_en.next = next_c; + field_combo.intr_block_rf.error_intr_en_r.error_kv_rd_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.error_intr_en_r.error_kv_rd_en.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_intr_en_r.error_kv_rd_en.load_next) begin + field_storage.intr_block_rf.error_intr_en_r.error_kv_rd_en.value <= field_combo.intr_block_rf.error_intr_en_r.error_kv_rd_en.next; + end + end + // Field: axi_dma_reg.intr_block_rf.error_intr_en_r.error_kv_rd_large_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_intr_en_r.error_kv_rd_large_en.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_intr_en_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.intr_block_rf.error_intr_en_r.error_kv_rd_large_en.value & ~decoded_wr_biten[9:9]) | (decoded_wr_data[9:9] & decoded_wr_biten[9:9]); + load_next_c = '1; + end + field_combo.intr_block_rf.error_intr_en_r.error_kv_rd_large_en.next = next_c; + field_combo.intr_block_rf.error_intr_en_r.error_kv_rd_large_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.error_intr_en_r.error_kv_rd_large_en.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_intr_en_r.error_kv_rd_large_en.load_next) begin + field_storage.intr_block_rf.error_intr_en_r.error_kv_rd_large_en.value <= field_combo.intr_block_rf.error_intr_en_r.error_kv_rd_large_en.next; + end + end + // Field: axi_dma_reg.intr_block_rf.notif_intr_en_r.notif_txn_done_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_intr_en_r.notif_txn_done_en.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.notif_intr_en_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.intr_block_rf.notif_intr_en_r.notif_txn_done_en.value & ~decoded_wr_biten[0:0]) | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end + field_combo.intr_block_rf.notif_intr_en_r.notif_txn_done_en.next = next_c; + field_combo.intr_block_rf.notif_intr_en_r.notif_txn_done_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.notif_intr_en_r.notif_txn_done_en.value <= 1'h0; + end else if(field_combo.intr_block_rf.notif_intr_en_r.notif_txn_done_en.load_next) begin + field_storage.intr_block_rf.notif_intr_en_r.notif_txn_done_en.value <= field_combo.intr_block_rf.notif_intr_en_r.notif_txn_done_en.next; + end + end + // Field: axi_dma_reg.intr_block_rf.notif_intr_en_r.notif_fifo_empty_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_intr_en_r.notif_fifo_empty_en.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.notif_intr_en_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.intr_block_rf.notif_intr_en_r.notif_fifo_empty_en.value & ~decoded_wr_biten[1:1]) | (decoded_wr_data[1:1] & decoded_wr_biten[1:1]); + load_next_c = '1; + end + field_combo.intr_block_rf.notif_intr_en_r.notif_fifo_empty_en.next = next_c; + field_combo.intr_block_rf.notif_intr_en_r.notif_fifo_empty_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.notif_intr_en_r.notif_fifo_empty_en.value <= 1'h0; + end else if(field_combo.intr_block_rf.notif_intr_en_r.notif_fifo_empty_en.load_next) begin + field_storage.intr_block_rf.notif_intr_en_r.notif_fifo_empty_en.value <= field_combo.intr_block_rf.notif_intr_en_r.notif_fifo_empty_en.next; + end + end + // Field: axi_dma_reg.intr_block_rf.notif_intr_en_r.notif_fifo_not_empty_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_intr_en_r.notif_fifo_not_empty_en.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.notif_intr_en_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.intr_block_rf.notif_intr_en_r.notif_fifo_not_empty_en.value & ~decoded_wr_biten[2:2]) | (decoded_wr_data[2:2] & decoded_wr_biten[2:2]); + load_next_c = '1; + end + field_combo.intr_block_rf.notif_intr_en_r.notif_fifo_not_empty_en.next = next_c; + field_combo.intr_block_rf.notif_intr_en_r.notif_fifo_not_empty_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.notif_intr_en_r.notif_fifo_not_empty_en.value <= 1'h0; + end else if(field_combo.intr_block_rf.notif_intr_en_r.notif_fifo_not_empty_en.load_next) begin + field_storage.intr_block_rf.notif_intr_en_r.notif_fifo_not_empty_en.value <= field_combo.intr_block_rf.notif_intr_en_r.notif_fifo_not_empty_en.next; + end + end + // Field: axi_dma_reg.intr_block_rf.notif_intr_en_r.notif_fifo_full_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_intr_en_r.notif_fifo_full_en.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.notif_intr_en_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.intr_block_rf.notif_intr_en_r.notif_fifo_full_en.value & ~decoded_wr_biten[3:3]) | (decoded_wr_data[3:3] & decoded_wr_biten[3:3]); + load_next_c = '1; + end + field_combo.intr_block_rf.notif_intr_en_r.notif_fifo_full_en.next = next_c; + field_combo.intr_block_rf.notif_intr_en_r.notif_fifo_full_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.notif_intr_en_r.notif_fifo_full_en.value <= 1'h0; + end else if(field_combo.intr_block_rf.notif_intr_en_r.notif_fifo_full_en.load_next) begin + field_storage.intr_block_rf.notif_intr_en_r.notif_fifo_full_en.value <= field_combo.intr_block_rf.notif_intr_en_r.notif_fifo_full_en.next; + end + end + // Field: axi_dma_reg.intr_block_rf.notif_intr_en_r.notif_fifo_not_full_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_intr_en_r.notif_fifo_not_full_en.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.notif_intr_en_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.intr_block_rf.notif_intr_en_r.notif_fifo_not_full_en.value & ~decoded_wr_biten[4:4]) | (decoded_wr_data[4:4] & decoded_wr_biten[4:4]); + load_next_c = '1; + end + field_combo.intr_block_rf.notif_intr_en_r.notif_fifo_not_full_en.next = next_c; + field_combo.intr_block_rf.notif_intr_en_r.notif_fifo_not_full_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.notif_intr_en_r.notif_fifo_not_full_en.value <= 1'h0; + end else if(field_combo.intr_block_rf.notif_intr_en_r.notif_fifo_not_full_en.load_next) begin + field_storage.intr_block_rf.notif_intr_en_r.notif_fifo_not_full_en.value <= field_combo.intr_block_rf.notif_intr_en_r.notif_fifo_not_full_en.next; + end + end + // Field: axi_dma_reg.intr_block_rf.error_global_intr_r.agg_sts + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_global_intr_r.agg_sts.value; + load_next_c = '0; + + // HW Write + next_c = hwif_out.intr_block_rf.error_internal_intr_r.intr; + load_next_c = '1; + field_combo.intr_block_rf.error_global_intr_r.agg_sts.next = next_c; + field_combo.intr_block_rf.error_global_intr_r.agg_sts.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.error_global_intr_r.agg_sts.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_global_intr_r.agg_sts.load_next) begin + field_storage.intr_block_rf.error_global_intr_r.agg_sts.value <= field_combo.intr_block_rf.error_global_intr_r.agg_sts.next; + end + end + assign hwif_out.intr_block_rf.error_global_intr_r.intr = + |(field_storage.intr_block_rf.error_global_intr_r.agg_sts.value & field_storage.intr_block_rf.global_intr_en_r.error_en.value); + // Field: axi_dma_reg.intr_block_rf.notif_global_intr_r.agg_sts + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_global_intr_r.agg_sts.value; + load_next_c = '0; + + // HW Write + next_c = hwif_out.intr_block_rf.notif_internal_intr_r.intr; + load_next_c = '1; + field_combo.intr_block_rf.notif_global_intr_r.agg_sts.next = next_c; + field_combo.intr_block_rf.notif_global_intr_r.agg_sts.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.notif_global_intr_r.agg_sts.value <= 1'h0; + end else if(field_combo.intr_block_rf.notif_global_intr_r.agg_sts.load_next) begin + field_storage.intr_block_rf.notif_global_intr_r.agg_sts.value <= field_combo.intr_block_rf.notif_global_intr_r.agg_sts.next; + end + end + assign hwif_out.intr_block_rf.notif_global_intr_r.intr = + |(field_storage.intr_block_rf.notif_global_intr_r.agg_sts.value & field_storage.intr_block_rf.global_intr_en_r.notif_en.value); + // Field: axi_dma_reg.intr_block_rf.error_internal_intr_r.error_cmd_dec_sts + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_internal_intr_r.error_cmd_dec_sts.value; + load_next_c = '0; + if(field_storage.intr_block_rf.error_intr_trig_r.error_cmd_dec_trig.value != '0) begin // stickybit + next_c = field_storage.intr_block_rf.error_internal_intr_r.error_cmd_dec_sts.value | field_storage.intr_block_rf.error_intr_trig_r.error_cmd_dec_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.error_internal_intr_r.error_cmd_dec_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end else if(decoded_reg_strb.intr_block_rf.error_internal_intr_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write 1 clear + next_c = field_storage.intr_block_rf.error_internal_intr_r.error_cmd_dec_sts.value & ~(decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end + field_combo.intr_block_rf.error_internal_intr_r.error_cmd_dec_sts.next = next_c; + field_combo.intr_block_rf.error_internal_intr_r.error_cmd_dec_sts.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.intr_block_rf.error_internal_intr_r.error_cmd_dec_sts.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_internal_intr_r.error_cmd_dec_sts.load_next) begin + field_storage.intr_block_rf.error_internal_intr_r.error_cmd_dec_sts.value <= field_combo.intr_block_rf.error_internal_intr_r.error_cmd_dec_sts.next; + end + end + // Field: axi_dma_reg.intr_block_rf.error_internal_intr_r.error_axi_rd_sts + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_internal_intr_r.error_axi_rd_sts.value; + load_next_c = '0; + if(field_storage.intr_block_rf.error_intr_trig_r.error_axi_rd_trig.value != '0) begin // stickybit + next_c = field_storage.intr_block_rf.error_internal_intr_r.error_axi_rd_sts.value | field_storage.intr_block_rf.error_intr_trig_r.error_axi_rd_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.error_internal_intr_r.error_axi_rd_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end else if(decoded_reg_strb.intr_block_rf.error_internal_intr_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write 1 clear + next_c = field_storage.intr_block_rf.error_internal_intr_r.error_axi_rd_sts.value & ~(decoded_wr_data[1:1] & decoded_wr_biten[1:1]); + load_next_c = '1; + end + field_combo.intr_block_rf.error_internal_intr_r.error_axi_rd_sts.next = next_c; + field_combo.intr_block_rf.error_internal_intr_r.error_axi_rd_sts.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.intr_block_rf.error_internal_intr_r.error_axi_rd_sts.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_internal_intr_r.error_axi_rd_sts.load_next) begin + field_storage.intr_block_rf.error_internal_intr_r.error_axi_rd_sts.value <= field_combo.intr_block_rf.error_internal_intr_r.error_axi_rd_sts.next; + end + end + // Field: axi_dma_reg.intr_block_rf.error_internal_intr_r.error_axi_wr_sts + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_internal_intr_r.error_axi_wr_sts.value; + load_next_c = '0; + if(field_storage.intr_block_rf.error_intr_trig_r.error_axi_wr_trig.value != '0) begin // stickybit + next_c = field_storage.intr_block_rf.error_internal_intr_r.error_axi_wr_sts.value | field_storage.intr_block_rf.error_intr_trig_r.error_axi_wr_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.error_internal_intr_r.error_axi_wr_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end else if(decoded_reg_strb.intr_block_rf.error_internal_intr_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write 1 clear + next_c = field_storage.intr_block_rf.error_internal_intr_r.error_axi_wr_sts.value & ~(decoded_wr_data[2:2] & decoded_wr_biten[2:2]); + load_next_c = '1; + end + field_combo.intr_block_rf.error_internal_intr_r.error_axi_wr_sts.next = next_c; + field_combo.intr_block_rf.error_internal_intr_r.error_axi_wr_sts.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.intr_block_rf.error_internal_intr_r.error_axi_wr_sts.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_internal_intr_r.error_axi_wr_sts.load_next) begin + field_storage.intr_block_rf.error_internal_intr_r.error_axi_wr_sts.value <= field_combo.intr_block_rf.error_internal_intr_r.error_axi_wr_sts.next; + end + end + // Field: axi_dma_reg.intr_block_rf.error_internal_intr_r.error_mbox_lock_sts + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_internal_intr_r.error_mbox_lock_sts.value; + load_next_c = '0; + if(field_storage.intr_block_rf.error_intr_trig_r.error_mbox_lock_trig.value != '0) begin // stickybit + next_c = field_storage.intr_block_rf.error_internal_intr_r.error_mbox_lock_sts.value | field_storage.intr_block_rf.error_intr_trig_r.error_mbox_lock_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.error_internal_intr_r.error_mbox_lock_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end else if(decoded_reg_strb.intr_block_rf.error_internal_intr_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write 1 clear + next_c = field_storage.intr_block_rf.error_internal_intr_r.error_mbox_lock_sts.value & ~(decoded_wr_data[3:3] & decoded_wr_biten[3:3]); + load_next_c = '1; + end + field_combo.intr_block_rf.error_internal_intr_r.error_mbox_lock_sts.next = next_c; + field_combo.intr_block_rf.error_internal_intr_r.error_mbox_lock_sts.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.intr_block_rf.error_internal_intr_r.error_mbox_lock_sts.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_internal_intr_r.error_mbox_lock_sts.load_next) begin + field_storage.intr_block_rf.error_internal_intr_r.error_mbox_lock_sts.value <= field_combo.intr_block_rf.error_internal_intr_r.error_mbox_lock_sts.next; + end + end + // Field: axi_dma_reg.intr_block_rf.error_internal_intr_r.error_sha_lock_sts + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_internal_intr_r.error_sha_lock_sts.value; + load_next_c = '0; + if(field_storage.intr_block_rf.error_intr_trig_r.error_sha_lock_trig.value != '0) begin // stickybit + next_c = field_storage.intr_block_rf.error_internal_intr_r.error_sha_lock_sts.value | field_storage.intr_block_rf.error_intr_trig_r.error_sha_lock_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.error_internal_intr_r.error_sha_lock_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end else if(decoded_reg_strb.intr_block_rf.error_internal_intr_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write 1 clear + next_c = field_storage.intr_block_rf.error_internal_intr_r.error_sha_lock_sts.value & ~(decoded_wr_data[4:4] & decoded_wr_biten[4:4]); + load_next_c = '1; + end + field_combo.intr_block_rf.error_internal_intr_r.error_sha_lock_sts.next = next_c; + field_combo.intr_block_rf.error_internal_intr_r.error_sha_lock_sts.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.intr_block_rf.error_internal_intr_r.error_sha_lock_sts.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_internal_intr_r.error_sha_lock_sts.load_next) begin + field_storage.intr_block_rf.error_internal_intr_r.error_sha_lock_sts.value <= field_combo.intr_block_rf.error_internal_intr_r.error_sha_lock_sts.next; + end + end + // Field: axi_dma_reg.intr_block_rf.error_internal_intr_r.error_fifo_oflow_sts + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_internal_intr_r.error_fifo_oflow_sts.value; + load_next_c = '0; + if(field_storage.intr_block_rf.error_intr_trig_r.error_fifo_oflow_trig.value != '0) begin // stickybit + next_c = field_storage.intr_block_rf.error_internal_intr_r.error_fifo_oflow_sts.value | field_storage.intr_block_rf.error_intr_trig_r.error_fifo_oflow_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.error_internal_intr_r.error_fifo_oflow_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end else if(decoded_reg_strb.intr_block_rf.error_internal_intr_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write 1 clear + next_c = field_storage.intr_block_rf.error_internal_intr_r.error_fifo_oflow_sts.value & ~(decoded_wr_data[5:5] & decoded_wr_biten[5:5]); + load_next_c = '1; + end + field_combo.intr_block_rf.error_internal_intr_r.error_fifo_oflow_sts.next = next_c; + field_combo.intr_block_rf.error_internal_intr_r.error_fifo_oflow_sts.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.intr_block_rf.error_internal_intr_r.error_fifo_oflow_sts.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_internal_intr_r.error_fifo_oflow_sts.load_next) begin + field_storage.intr_block_rf.error_internal_intr_r.error_fifo_oflow_sts.value <= field_combo.intr_block_rf.error_internal_intr_r.error_fifo_oflow_sts.next; + end + end + // Field: axi_dma_reg.intr_block_rf.error_internal_intr_r.error_fifo_uflow_sts + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_internal_intr_r.error_fifo_uflow_sts.value; + load_next_c = '0; + if(field_storage.intr_block_rf.error_intr_trig_r.error_fifo_uflow_trig.value != '0) begin // stickybit + next_c = field_storage.intr_block_rf.error_internal_intr_r.error_fifo_uflow_sts.value | field_storage.intr_block_rf.error_intr_trig_r.error_fifo_uflow_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.error_internal_intr_r.error_fifo_uflow_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end else if(decoded_reg_strb.intr_block_rf.error_internal_intr_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write 1 clear + next_c = field_storage.intr_block_rf.error_internal_intr_r.error_fifo_uflow_sts.value & ~(decoded_wr_data[6:6] & decoded_wr_biten[6:6]); + load_next_c = '1; + end + field_combo.intr_block_rf.error_internal_intr_r.error_fifo_uflow_sts.next = next_c; + field_combo.intr_block_rf.error_internal_intr_r.error_fifo_uflow_sts.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.intr_block_rf.error_internal_intr_r.error_fifo_uflow_sts.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_internal_intr_r.error_fifo_uflow_sts.load_next) begin + field_storage.intr_block_rf.error_internal_intr_r.error_fifo_uflow_sts.value <= field_combo.intr_block_rf.error_internal_intr_r.error_fifo_uflow_sts.next; + end + end + // Field: axi_dma_reg.intr_block_rf.error_internal_intr_r.error_aes_cif_sts + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_internal_intr_r.error_aes_cif_sts.value; + load_next_c = '0; + if(field_storage.intr_block_rf.error_intr_trig_r.error_aes_cif_trig.value != '0) begin // stickybit + next_c = field_storage.intr_block_rf.error_internal_intr_r.error_aes_cif_sts.value | field_storage.intr_block_rf.error_intr_trig_r.error_aes_cif_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.error_internal_intr_r.error_aes_cif_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end else if(decoded_reg_strb.intr_block_rf.error_internal_intr_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write 1 clear + next_c = field_storage.intr_block_rf.error_internal_intr_r.error_aes_cif_sts.value & ~(decoded_wr_data[7:7] & decoded_wr_biten[7:7]); + load_next_c = '1; + end + field_combo.intr_block_rf.error_internal_intr_r.error_aes_cif_sts.next = next_c; + field_combo.intr_block_rf.error_internal_intr_r.error_aes_cif_sts.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.intr_block_rf.error_internal_intr_r.error_aes_cif_sts.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_internal_intr_r.error_aes_cif_sts.load_next) begin + field_storage.intr_block_rf.error_internal_intr_r.error_aes_cif_sts.value <= field_combo.intr_block_rf.error_internal_intr_r.error_aes_cif_sts.next; + end + end + // Field: axi_dma_reg.intr_block_rf.error_internal_intr_r.error_kv_rd_sts + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_internal_intr_r.error_kv_rd_sts.value; + load_next_c = '0; + if(field_storage.intr_block_rf.error_intr_trig_r.error_kv_rd_trig.value != '0) begin // stickybit + next_c = field_storage.intr_block_rf.error_internal_intr_r.error_kv_rd_sts.value | field_storage.intr_block_rf.error_intr_trig_r.error_kv_rd_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.error_internal_intr_r.error_kv_rd_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end else if(decoded_reg_strb.intr_block_rf.error_internal_intr_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write 1 clear + next_c = field_storage.intr_block_rf.error_internal_intr_r.error_kv_rd_sts.value & ~(decoded_wr_data[8:8] & decoded_wr_biten[8:8]); + load_next_c = '1; + end + field_combo.intr_block_rf.error_internal_intr_r.error_kv_rd_sts.next = next_c; + field_combo.intr_block_rf.error_internal_intr_r.error_kv_rd_sts.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.intr_block_rf.error_internal_intr_r.error_kv_rd_sts.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_internal_intr_r.error_kv_rd_sts.load_next) begin + field_storage.intr_block_rf.error_internal_intr_r.error_kv_rd_sts.value <= field_combo.intr_block_rf.error_internal_intr_r.error_kv_rd_sts.next; + end + end + // Field: axi_dma_reg.intr_block_rf.error_internal_intr_r.error_kv_rd_large_sts + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_internal_intr_r.error_kv_rd_large_sts.value; + load_next_c = '0; + if(field_storage.intr_block_rf.error_intr_trig_r.error_kv_rd_large_trig.value != '0) begin // stickybit + next_c = field_storage.intr_block_rf.error_internal_intr_r.error_kv_rd_large_sts.value | field_storage.intr_block_rf.error_intr_trig_r.error_kv_rd_large_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.error_internal_intr_r.error_kv_rd_large_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end else if(decoded_reg_strb.intr_block_rf.error_internal_intr_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write 1 clear + next_c = field_storage.intr_block_rf.error_internal_intr_r.error_kv_rd_large_sts.value & ~(decoded_wr_data[9:9] & decoded_wr_biten[9:9]); + load_next_c = '1; + end + field_combo.intr_block_rf.error_internal_intr_r.error_kv_rd_large_sts.next = next_c; + field_combo.intr_block_rf.error_internal_intr_r.error_kv_rd_large_sts.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.intr_block_rf.error_internal_intr_r.error_kv_rd_large_sts.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_internal_intr_r.error_kv_rd_large_sts.load_next) begin + field_storage.intr_block_rf.error_internal_intr_r.error_kv_rd_large_sts.value <= field_combo.intr_block_rf.error_internal_intr_r.error_kv_rd_large_sts.next; + end + end + assign hwif_out.intr_block_rf.error_internal_intr_r.intr = + |(field_storage.intr_block_rf.error_internal_intr_r.error_cmd_dec_sts.value & field_storage.intr_block_rf.error_intr_en_r.error_cmd_dec_en.value) + || |(field_storage.intr_block_rf.error_internal_intr_r.error_axi_rd_sts.value & field_storage.intr_block_rf.error_intr_en_r.error_axi_rd_en.value) + || |(field_storage.intr_block_rf.error_internal_intr_r.error_axi_wr_sts.value & field_storage.intr_block_rf.error_intr_en_r.error_axi_wr_en.value) + || |(field_storage.intr_block_rf.error_internal_intr_r.error_mbox_lock_sts.value & field_storage.intr_block_rf.error_intr_en_r.error_mbox_lock_en.value) + || |(field_storage.intr_block_rf.error_internal_intr_r.error_sha_lock_sts.value & field_storage.intr_block_rf.error_intr_en_r.error_sha_lock_en.value) + || |(field_storage.intr_block_rf.error_internal_intr_r.error_fifo_oflow_sts.value & field_storage.intr_block_rf.error_intr_en_r.error_fifo_oflow_en.value) + || |(field_storage.intr_block_rf.error_internal_intr_r.error_fifo_uflow_sts.value & field_storage.intr_block_rf.error_intr_en_r.error_fifo_uflow_en.value) + || |(field_storage.intr_block_rf.error_internal_intr_r.error_aes_cif_sts.value & field_storage.intr_block_rf.error_intr_en_r.error_aes_cif_en.value) + || |(field_storage.intr_block_rf.error_internal_intr_r.error_kv_rd_sts.value & field_storage.intr_block_rf.error_intr_en_r.error_kv_rd_en.value) + || |(field_storage.intr_block_rf.error_internal_intr_r.error_kv_rd_large_sts.value & field_storage.intr_block_rf.error_intr_en_r.error_kv_rd_large_en.value); + // Field: axi_dma_reg.intr_block_rf.notif_internal_intr_r.notif_txn_done_sts + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_internal_intr_r.notif_txn_done_sts.value; + load_next_c = '0; + if(field_storage.intr_block_rf.notif_intr_trig_r.notif_txn_done_trig.value != '0) begin // stickybit + next_c = field_storage.intr_block_rf.notif_internal_intr_r.notif_txn_done_sts.value | field_storage.intr_block_rf.notif_intr_trig_r.notif_txn_done_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.notif_internal_intr_r.notif_txn_done_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end else if(decoded_reg_strb.intr_block_rf.notif_internal_intr_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write 1 clear + next_c = field_storage.intr_block_rf.notif_internal_intr_r.notif_txn_done_sts.value & ~(decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end + field_combo.intr_block_rf.notif_internal_intr_r.notif_txn_done_sts.next = next_c; + field_combo.intr_block_rf.notif_internal_intr_r.notif_txn_done_sts.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.notif_internal_intr_r.notif_txn_done_sts.value <= 1'h0; + end else if(field_combo.intr_block_rf.notif_internal_intr_r.notif_txn_done_sts.load_next) begin + field_storage.intr_block_rf.notif_internal_intr_r.notif_txn_done_sts.value <= field_combo.intr_block_rf.notif_internal_intr_r.notif_txn_done_sts.next; + end + end + // Field: axi_dma_reg.intr_block_rf.notif_internal_intr_r.notif_fifo_empty_sts + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_internal_intr_r.notif_fifo_empty_sts.value; + load_next_c = '0; + if(field_storage.intr_block_rf.notif_intr_trig_r.notif_fifo_empty_trig.value != '0) begin // stickybit + next_c = field_storage.intr_block_rf.notif_internal_intr_r.notif_fifo_empty_sts.value | field_storage.intr_block_rf.notif_intr_trig_r.notif_fifo_empty_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.notif_internal_intr_r.notif_fifo_empty_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end else if(decoded_reg_strb.intr_block_rf.notif_internal_intr_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write 1 clear + next_c = field_storage.intr_block_rf.notif_internal_intr_r.notif_fifo_empty_sts.value & ~(decoded_wr_data[1:1] & decoded_wr_biten[1:1]); + load_next_c = '1; + end + field_combo.intr_block_rf.notif_internal_intr_r.notif_fifo_empty_sts.next = next_c; + field_combo.intr_block_rf.notif_internal_intr_r.notif_fifo_empty_sts.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.notif_internal_intr_r.notif_fifo_empty_sts.value <= 1'h0; + end else if(field_combo.intr_block_rf.notif_internal_intr_r.notif_fifo_empty_sts.load_next) begin + field_storage.intr_block_rf.notif_internal_intr_r.notif_fifo_empty_sts.value <= field_combo.intr_block_rf.notif_internal_intr_r.notif_fifo_empty_sts.next; + end + end + // Field: axi_dma_reg.intr_block_rf.notif_internal_intr_r.notif_fifo_not_empty_sts + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_internal_intr_r.notif_fifo_not_empty_sts.value; + load_next_c = '0; + if(field_storage.intr_block_rf.notif_intr_trig_r.notif_fifo_not_empty_trig.value != '0) begin // stickybit + next_c = field_storage.intr_block_rf.notif_internal_intr_r.notif_fifo_not_empty_sts.value | field_storage.intr_block_rf.notif_intr_trig_r.notif_fifo_not_empty_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.notif_internal_intr_r.notif_fifo_not_empty_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end else if(decoded_reg_strb.intr_block_rf.notif_internal_intr_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write 1 clear + next_c = field_storage.intr_block_rf.notif_internal_intr_r.notif_fifo_not_empty_sts.value & ~(decoded_wr_data[2:2] & decoded_wr_biten[2:2]); + load_next_c = '1; + end + field_combo.intr_block_rf.notif_internal_intr_r.notif_fifo_not_empty_sts.next = next_c; + field_combo.intr_block_rf.notif_internal_intr_r.notif_fifo_not_empty_sts.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.notif_internal_intr_r.notif_fifo_not_empty_sts.value <= 1'h0; + end else if(field_combo.intr_block_rf.notif_internal_intr_r.notif_fifo_not_empty_sts.load_next) begin + field_storage.intr_block_rf.notif_internal_intr_r.notif_fifo_not_empty_sts.value <= field_combo.intr_block_rf.notif_internal_intr_r.notif_fifo_not_empty_sts.next; + end + end + // Field: axi_dma_reg.intr_block_rf.notif_internal_intr_r.notif_fifo_full_sts + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_internal_intr_r.notif_fifo_full_sts.value; + load_next_c = '0; + if(field_storage.intr_block_rf.notif_intr_trig_r.notif_fifo_full_trig.value != '0) begin // stickybit + next_c = field_storage.intr_block_rf.notif_internal_intr_r.notif_fifo_full_sts.value | field_storage.intr_block_rf.notif_intr_trig_r.notif_fifo_full_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.notif_internal_intr_r.notif_fifo_full_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end else if(decoded_reg_strb.intr_block_rf.notif_internal_intr_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write 1 clear + next_c = field_storage.intr_block_rf.notif_internal_intr_r.notif_fifo_full_sts.value & ~(decoded_wr_data[3:3] & decoded_wr_biten[3:3]); + load_next_c = '1; + end + field_combo.intr_block_rf.notif_internal_intr_r.notif_fifo_full_sts.next = next_c; + field_combo.intr_block_rf.notif_internal_intr_r.notif_fifo_full_sts.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.notif_internal_intr_r.notif_fifo_full_sts.value <= 1'h0; + end else if(field_combo.intr_block_rf.notif_internal_intr_r.notif_fifo_full_sts.load_next) begin + field_storage.intr_block_rf.notif_internal_intr_r.notif_fifo_full_sts.value <= field_combo.intr_block_rf.notif_internal_intr_r.notif_fifo_full_sts.next; + end + end + // Field: axi_dma_reg.intr_block_rf.notif_internal_intr_r.notif_fifo_not_full_sts + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_internal_intr_r.notif_fifo_not_full_sts.value; + load_next_c = '0; + if(field_storage.intr_block_rf.notif_intr_trig_r.notif_fifo_not_full_trig.value != '0) begin // stickybit + next_c = field_storage.intr_block_rf.notif_internal_intr_r.notif_fifo_not_full_sts.value | field_storage.intr_block_rf.notif_intr_trig_r.notif_fifo_not_full_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.notif_internal_intr_r.notif_fifo_not_full_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end else if(decoded_reg_strb.intr_block_rf.notif_internal_intr_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write 1 clear + next_c = field_storage.intr_block_rf.notif_internal_intr_r.notif_fifo_not_full_sts.value & ~(decoded_wr_data[4:4] & decoded_wr_biten[4:4]); + load_next_c = '1; + end + field_combo.intr_block_rf.notif_internal_intr_r.notif_fifo_not_full_sts.next = next_c; + field_combo.intr_block_rf.notif_internal_intr_r.notif_fifo_not_full_sts.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.notif_internal_intr_r.notif_fifo_not_full_sts.value <= 1'h0; + end else if(field_combo.intr_block_rf.notif_internal_intr_r.notif_fifo_not_full_sts.load_next) begin + field_storage.intr_block_rf.notif_internal_intr_r.notif_fifo_not_full_sts.value <= field_combo.intr_block_rf.notif_internal_intr_r.notif_fifo_not_full_sts.next; + end + end + assign hwif_out.intr_block_rf.notif_internal_intr_r.intr = + |(field_storage.intr_block_rf.notif_internal_intr_r.notif_txn_done_sts.value & field_storage.intr_block_rf.notif_intr_en_r.notif_txn_done_en.value) + || |(field_storage.intr_block_rf.notif_internal_intr_r.notif_fifo_empty_sts.value & field_storage.intr_block_rf.notif_intr_en_r.notif_fifo_empty_en.value) + || |(field_storage.intr_block_rf.notif_internal_intr_r.notif_fifo_not_empty_sts.value & field_storage.intr_block_rf.notif_intr_en_r.notif_fifo_not_empty_en.value) + || |(field_storage.intr_block_rf.notif_internal_intr_r.notif_fifo_full_sts.value & field_storage.intr_block_rf.notif_intr_en_r.notif_fifo_full_en.value) + || |(field_storage.intr_block_rf.notif_internal_intr_r.notif_fifo_not_full_sts.value & field_storage.intr_block_rf.notif_intr_en_r.notif_fifo_not_full_en.value); + // Field: axi_dma_reg.intr_block_rf.error_intr_trig_r.error_cmd_dec_trig + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_intr_trig_r.error_cmd_dec_trig.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_intr_trig_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write 1 set + next_c = field_storage.intr_block_rf.error_intr_trig_r.error_cmd_dec_trig.value | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end else begin // singlepulse clears back to 0 + next_c = '0; + load_next_c = '1; + end + field_combo.intr_block_rf.error_intr_trig_r.error_cmd_dec_trig.next = next_c; + field_combo.intr_block_rf.error_intr_trig_r.error_cmd_dec_trig.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.error_intr_trig_r.error_cmd_dec_trig.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_intr_trig_r.error_cmd_dec_trig.load_next) begin + field_storage.intr_block_rf.error_intr_trig_r.error_cmd_dec_trig.value <= field_combo.intr_block_rf.error_intr_trig_r.error_cmd_dec_trig.next; + end + end + // Field: axi_dma_reg.intr_block_rf.error_intr_trig_r.error_axi_rd_trig + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_intr_trig_r.error_axi_rd_trig.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_intr_trig_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write 1 set + next_c = field_storage.intr_block_rf.error_intr_trig_r.error_axi_rd_trig.value | (decoded_wr_data[1:1] & decoded_wr_biten[1:1]); + load_next_c = '1; + end else begin // singlepulse clears back to 0 + next_c = '0; + load_next_c = '1; + end + field_combo.intr_block_rf.error_intr_trig_r.error_axi_rd_trig.next = next_c; + field_combo.intr_block_rf.error_intr_trig_r.error_axi_rd_trig.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.error_intr_trig_r.error_axi_rd_trig.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_intr_trig_r.error_axi_rd_trig.load_next) begin + field_storage.intr_block_rf.error_intr_trig_r.error_axi_rd_trig.value <= field_combo.intr_block_rf.error_intr_trig_r.error_axi_rd_trig.next; + end + end + // Field: axi_dma_reg.intr_block_rf.error_intr_trig_r.error_axi_wr_trig + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_intr_trig_r.error_axi_wr_trig.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_intr_trig_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write 1 set + next_c = field_storage.intr_block_rf.error_intr_trig_r.error_axi_wr_trig.value | (decoded_wr_data[2:2] & decoded_wr_biten[2:2]); + load_next_c = '1; + end else begin // singlepulse clears back to 0 + next_c = '0; + load_next_c = '1; + end + field_combo.intr_block_rf.error_intr_trig_r.error_axi_wr_trig.next = next_c; + field_combo.intr_block_rf.error_intr_trig_r.error_axi_wr_trig.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.error_intr_trig_r.error_axi_wr_trig.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_intr_trig_r.error_axi_wr_trig.load_next) begin + field_storage.intr_block_rf.error_intr_trig_r.error_axi_wr_trig.value <= field_combo.intr_block_rf.error_intr_trig_r.error_axi_wr_trig.next; + end + end + // Field: axi_dma_reg.intr_block_rf.error_intr_trig_r.error_mbox_lock_trig + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_intr_trig_r.error_mbox_lock_trig.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_intr_trig_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write 1 set + next_c = field_storage.intr_block_rf.error_intr_trig_r.error_mbox_lock_trig.value | (decoded_wr_data[3:3] & decoded_wr_biten[3:3]); + load_next_c = '1; + end else begin // singlepulse clears back to 0 + next_c = '0; + load_next_c = '1; + end + field_combo.intr_block_rf.error_intr_trig_r.error_mbox_lock_trig.next = next_c; + field_combo.intr_block_rf.error_intr_trig_r.error_mbox_lock_trig.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.error_intr_trig_r.error_mbox_lock_trig.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_intr_trig_r.error_mbox_lock_trig.load_next) begin + field_storage.intr_block_rf.error_intr_trig_r.error_mbox_lock_trig.value <= field_combo.intr_block_rf.error_intr_trig_r.error_mbox_lock_trig.next; + end + end + // Field: axi_dma_reg.intr_block_rf.error_intr_trig_r.error_sha_lock_trig + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_intr_trig_r.error_sha_lock_trig.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_intr_trig_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write 1 set + next_c = field_storage.intr_block_rf.error_intr_trig_r.error_sha_lock_trig.value | (decoded_wr_data[4:4] & decoded_wr_biten[4:4]); + load_next_c = '1; + end else begin // singlepulse clears back to 0 + next_c = '0; + load_next_c = '1; + end + field_combo.intr_block_rf.error_intr_trig_r.error_sha_lock_trig.next = next_c; + field_combo.intr_block_rf.error_intr_trig_r.error_sha_lock_trig.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.error_intr_trig_r.error_sha_lock_trig.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_intr_trig_r.error_sha_lock_trig.load_next) begin + field_storage.intr_block_rf.error_intr_trig_r.error_sha_lock_trig.value <= field_combo.intr_block_rf.error_intr_trig_r.error_sha_lock_trig.next; + end + end + // Field: axi_dma_reg.intr_block_rf.error_intr_trig_r.error_fifo_oflow_trig + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_intr_trig_r.error_fifo_oflow_trig.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_intr_trig_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write 1 set + next_c = field_storage.intr_block_rf.error_intr_trig_r.error_fifo_oflow_trig.value | (decoded_wr_data[5:5] & decoded_wr_biten[5:5]); + load_next_c = '1; + end else begin // singlepulse clears back to 0 + next_c = '0; + load_next_c = '1; + end + field_combo.intr_block_rf.error_intr_trig_r.error_fifo_oflow_trig.next = next_c; + field_combo.intr_block_rf.error_intr_trig_r.error_fifo_oflow_trig.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.error_intr_trig_r.error_fifo_oflow_trig.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_intr_trig_r.error_fifo_oflow_trig.load_next) begin + field_storage.intr_block_rf.error_intr_trig_r.error_fifo_oflow_trig.value <= field_combo.intr_block_rf.error_intr_trig_r.error_fifo_oflow_trig.next; + end + end + // Field: axi_dma_reg.intr_block_rf.error_intr_trig_r.error_fifo_uflow_trig + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_intr_trig_r.error_fifo_uflow_trig.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_intr_trig_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write 1 set + next_c = field_storage.intr_block_rf.error_intr_trig_r.error_fifo_uflow_trig.value | (decoded_wr_data[6:6] & decoded_wr_biten[6:6]); + load_next_c = '1; + end else begin // singlepulse clears back to 0 + next_c = '0; + load_next_c = '1; + end + field_combo.intr_block_rf.error_intr_trig_r.error_fifo_uflow_trig.next = next_c; + field_combo.intr_block_rf.error_intr_trig_r.error_fifo_uflow_trig.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.error_intr_trig_r.error_fifo_uflow_trig.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_intr_trig_r.error_fifo_uflow_trig.load_next) begin + field_storage.intr_block_rf.error_intr_trig_r.error_fifo_uflow_trig.value <= field_combo.intr_block_rf.error_intr_trig_r.error_fifo_uflow_trig.next; + end + end + // Field: axi_dma_reg.intr_block_rf.error_intr_trig_r.error_aes_cif_trig + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_intr_trig_r.error_aes_cif_trig.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_intr_trig_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write 1 set + next_c = field_storage.intr_block_rf.error_intr_trig_r.error_aes_cif_trig.value | (decoded_wr_data[7:7] & decoded_wr_biten[7:7]); + load_next_c = '1; + end else begin // singlepulse clears back to 0 + next_c = '0; + load_next_c = '1; + end + field_combo.intr_block_rf.error_intr_trig_r.error_aes_cif_trig.next = next_c; + field_combo.intr_block_rf.error_intr_trig_r.error_aes_cif_trig.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.error_intr_trig_r.error_aes_cif_trig.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_intr_trig_r.error_aes_cif_trig.load_next) begin + field_storage.intr_block_rf.error_intr_trig_r.error_aes_cif_trig.value <= field_combo.intr_block_rf.error_intr_trig_r.error_aes_cif_trig.next; + end + end + // Field: axi_dma_reg.intr_block_rf.error_intr_trig_r.error_kv_rd_trig + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_intr_trig_r.error_kv_rd_trig.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_intr_trig_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write 1 set + next_c = field_storage.intr_block_rf.error_intr_trig_r.error_kv_rd_trig.value | (decoded_wr_data[8:8] & decoded_wr_biten[8:8]); + load_next_c = '1; + end else begin // singlepulse clears back to 0 + next_c = '0; + load_next_c = '1; + end + field_combo.intr_block_rf.error_intr_trig_r.error_kv_rd_trig.next = next_c; + field_combo.intr_block_rf.error_intr_trig_r.error_kv_rd_trig.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.error_intr_trig_r.error_kv_rd_trig.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_intr_trig_r.error_kv_rd_trig.load_next) begin + field_storage.intr_block_rf.error_intr_trig_r.error_kv_rd_trig.value <= field_combo.intr_block_rf.error_intr_trig_r.error_kv_rd_trig.next; + end + end + // Field: axi_dma_reg.intr_block_rf.error_intr_trig_r.error_kv_rd_large_trig + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_intr_trig_r.error_kv_rd_large_trig.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_intr_trig_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write 1 set + next_c = field_storage.intr_block_rf.error_intr_trig_r.error_kv_rd_large_trig.value | (decoded_wr_data[9:9] & decoded_wr_biten[9:9]); + load_next_c = '1; + end else begin // singlepulse clears back to 0 + next_c = '0; + load_next_c = '1; + end + field_combo.intr_block_rf.error_intr_trig_r.error_kv_rd_large_trig.next = next_c; + field_combo.intr_block_rf.error_intr_trig_r.error_kv_rd_large_trig.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.error_intr_trig_r.error_kv_rd_large_trig.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_intr_trig_r.error_kv_rd_large_trig.load_next) begin + field_storage.intr_block_rf.error_intr_trig_r.error_kv_rd_large_trig.value <= field_combo.intr_block_rf.error_intr_trig_r.error_kv_rd_large_trig.next; + end + end + // Field: axi_dma_reg.intr_block_rf.notif_intr_trig_r.notif_txn_done_trig + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_intr_trig_r.notif_txn_done_trig.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.notif_intr_trig_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write 1 set + next_c = field_storage.intr_block_rf.notif_intr_trig_r.notif_txn_done_trig.value | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end else begin // singlepulse clears back to 0 + next_c = '0; + load_next_c = '1; + end + field_combo.intr_block_rf.notif_intr_trig_r.notif_txn_done_trig.next = next_c; + field_combo.intr_block_rf.notif_intr_trig_r.notif_txn_done_trig.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.notif_intr_trig_r.notif_txn_done_trig.value <= 1'h0; + end else if(field_combo.intr_block_rf.notif_intr_trig_r.notif_txn_done_trig.load_next) begin + field_storage.intr_block_rf.notif_intr_trig_r.notif_txn_done_trig.value <= field_combo.intr_block_rf.notif_intr_trig_r.notif_txn_done_trig.next; + end + end + // Field: axi_dma_reg.intr_block_rf.notif_intr_trig_r.notif_fifo_empty_trig + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_intr_trig_r.notif_fifo_empty_trig.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.notif_intr_trig_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write 1 set + next_c = field_storage.intr_block_rf.notif_intr_trig_r.notif_fifo_empty_trig.value | (decoded_wr_data[1:1] & decoded_wr_biten[1:1]); + load_next_c = '1; + end else begin // singlepulse clears back to 0 + next_c = '0; + load_next_c = '1; + end + field_combo.intr_block_rf.notif_intr_trig_r.notif_fifo_empty_trig.next = next_c; + field_combo.intr_block_rf.notif_intr_trig_r.notif_fifo_empty_trig.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.notif_intr_trig_r.notif_fifo_empty_trig.value <= 1'h0; + end else if(field_combo.intr_block_rf.notif_intr_trig_r.notif_fifo_empty_trig.load_next) begin + field_storage.intr_block_rf.notif_intr_trig_r.notif_fifo_empty_trig.value <= field_combo.intr_block_rf.notif_intr_trig_r.notif_fifo_empty_trig.next; + end + end + // Field: axi_dma_reg.intr_block_rf.notif_intr_trig_r.notif_fifo_not_empty_trig + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_intr_trig_r.notif_fifo_not_empty_trig.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.notif_intr_trig_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write 1 set + next_c = field_storage.intr_block_rf.notif_intr_trig_r.notif_fifo_not_empty_trig.value | (decoded_wr_data[2:2] & decoded_wr_biten[2:2]); + load_next_c = '1; + end else begin // singlepulse clears back to 0 + next_c = '0; + load_next_c = '1; + end + field_combo.intr_block_rf.notif_intr_trig_r.notif_fifo_not_empty_trig.next = next_c; + field_combo.intr_block_rf.notif_intr_trig_r.notif_fifo_not_empty_trig.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.notif_intr_trig_r.notif_fifo_not_empty_trig.value <= 1'h0; + end else if(field_combo.intr_block_rf.notif_intr_trig_r.notif_fifo_not_empty_trig.load_next) begin + field_storage.intr_block_rf.notif_intr_trig_r.notif_fifo_not_empty_trig.value <= field_combo.intr_block_rf.notif_intr_trig_r.notif_fifo_not_empty_trig.next; + end + end + // Field: axi_dma_reg.intr_block_rf.notif_intr_trig_r.notif_fifo_full_trig + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_intr_trig_r.notif_fifo_full_trig.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.notif_intr_trig_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write 1 set + next_c = field_storage.intr_block_rf.notif_intr_trig_r.notif_fifo_full_trig.value | (decoded_wr_data[3:3] & decoded_wr_biten[3:3]); + load_next_c = '1; + end else begin // singlepulse clears back to 0 + next_c = '0; + load_next_c = '1; + end + field_combo.intr_block_rf.notif_intr_trig_r.notif_fifo_full_trig.next = next_c; + field_combo.intr_block_rf.notif_intr_trig_r.notif_fifo_full_trig.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.notif_intr_trig_r.notif_fifo_full_trig.value <= 1'h0; + end else if(field_combo.intr_block_rf.notif_intr_trig_r.notif_fifo_full_trig.load_next) begin + field_storage.intr_block_rf.notif_intr_trig_r.notif_fifo_full_trig.value <= field_combo.intr_block_rf.notif_intr_trig_r.notif_fifo_full_trig.next; + end + end + // Field: axi_dma_reg.intr_block_rf.notif_intr_trig_r.notif_fifo_not_full_trig + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_intr_trig_r.notif_fifo_not_full_trig.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.notif_intr_trig_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write 1 set + next_c = field_storage.intr_block_rf.notif_intr_trig_r.notif_fifo_not_full_trig.value | (decoded_wr_data[4:4] & decoded_wr_biten[4:4]); + load_next_c = '1; + end else begin // singlepulse clears back to 0 + next_c = '0; + load_next_c = '1; + end + field_combo.intr_block_rf.notif_intr_trig_r.notif_fifo_not_full_trig.next = next_c; + field_combo.intr_block_rf.notif_intr_trig_r.notif_fifo_not_full_trig.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.notif_intr_trig_r.notif_fifo_not_full_trig.value <= 1'h0; + end else if(field_combo.intr_block_rf.notif_intr_trig_r.notif_fifo_not_full_trig.load_next) begin + field_storage.intr_block_rf.notif_intr_trig_r.notif_fifo_not_full_trig.value <= field_combo.intr_block_rf.notif_intr_trig_r.notif_fifo_not_full_trig.next; + end + end + // Field: axi_dma_reg.intr_block_rf.error_cmd_dec_intr_count_r.cnt + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_cmd_dec_intr_count_r.cnt.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_cmd_dec_intr_count_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.intr_block_rf.error_cmd_dec_intr_count_r.cnt.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + if(field_storage.intr_block_rf.error_cmd_dec_intr_count_incr_r.pulse.value) begin // increment + if(((33)'(next_c) + 32'h1) > 32'hffffffff) begin // up-counter saturated + next_c = 32'hffffffff; + end else begin + next_c = next_c + 32'h1; + end + load_next_c = '1; + end + field_combo.intr_block_rf.error_cmd_dec_intr_count_r.cnt.incrthreshold = (field_storage.intr_block_rf.error_cmd_dec_intr_count_r.cnt.value >= 32'hffffffff); + field_combo.intr_block_rf.error_cmd_dec_intr_count_r.cnt.incrsaturate = (field_storage.intr_block_rf.error_cmd_dec_intr_count_r.cnt.value >= 32'hffffffff); + if(next_c > 32'hffffffff) begin + next_c = 32'hffffffff; + load_next_c = '1; + end + field_combo.intr_block_rf.error_cmd_dec_intr_count_r.cnt.next = next_c; + field_combo.intr_block_rf.error_cmd_dec_intr_count_r.cnt.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.intr_block_rf.error_cmd_dec_intr_count_r.cnt.value <= 32'h0; + end else if(field_combo.intr_block_rf.error_cmd_dec_intr_count_r.cnt.load_next) begin + field_storage.intr_block_rf.error_cmd_dec_intr_count_r.cnt.value <= field_combo.intr_block_rf.error_cmd_dec_intr_count_r.cnt.next; + end + end + // Field: axi_dma_reg.intr_block_rf.error_axi_rd_intr_count_r.cnt + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_axi_rd_intr_count_r.cnt.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_axi_rd_intr_count_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.intr_block_rf.error_axi_rd_intr_count_r.cnt.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + if(field_storage.intr_block_rf.error_axi_rd_intr_count_incr_r.pulse.value) begin // increment + if(((33)'(next_c) + 32'h1) > 32'hffffffff) begin // up-counter saturated + next_c = 32'hffffffff; + end else begin + next_c = next_c + 32'h1; + end + load_next_c = '1; + end + field_combo.intr_block_rf.error_axi_rd_intr_count_r.cnt.incrthreshold = (field_storage.intr_block_rf.error_axi_rd_intr_count_r.cnt.value >= 32'hffffffff); + field_combo.intr_block_rf.error_axi_rd_intr_count_r.cnt.incrsaturate = (field_storage.intr_block_rf.error_axi_rd_intr_count_r.cnt.value >= 32'hffffffff); + if(next_c > 32'hffffffff) begin + next_c = 32'hffffffff; + load_next_c = '1; + end + field_combo.intr_block_rf.error_axi_rd_intr_count_r.cnt.next = next_c; + field_combo.intr_block_rf.error_axi_rd_intr_count_r.cnt.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.intr_block_rf.error_axi_rd_intr_count_r.cnt.value <= 32'h0; + end else if(field_combo.intr_block_rf.error_axi_rd_intr_count_r.cnt.load_next) begin + field_storage.intr_block_rf.error_axi_rd_intr_count_r.cnt.value <= field_combo.intr_block_rf.error_axi_rd_intr_count_r.cnt.next; + end + end + // Field: axi_dma_reg.intr_block_rf.error_axi_wr_intr_count_r.cnt + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_axi_wr_intr_count_r.cnt.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_axi_wr_intr_count_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.intr_block_rf.error_axi_wr_intr_count_r.cnt.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + if(field_storage.intr_block_rf.error_axi_wr_intr_count_incr_r.pulse.value) begin // increment + if(((33)'(next_c) + 32'h1) > 32'hffffffff) begin // up-counter saturated + next_c = 32'hffffffff; + end else begin + next_c = next_c + 32'h1; + end + load_next_c = '1; + end + field_combo.intr_block_rf.error_axi_wr_intr_count_r.cnt.incrthreshold = (field_storage.intr_block_rf.error_axi_wr_intr_count_r.cnt.value >= 32'hffffffff); + field_combo.intr_block_rf.error_axi_wr_intr_count_r.cnt.incrsaturate = (field_storage.intr_block_rf.error_axi_wr_intr_count_r.cnt.value >= 32'hffffffff); + if(next_c > 32'hffffffff) begin + next_c = 32'hffffffff; + load_next_c = '1; + end + field_combo.intr_block_rf.error_axi_wr_intr_count_r.cnt.next = next_c; + field_combo.intr_block_rf.error_axi_wr_intr_count_r.cnt.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.intr_block_rf.error_axi_wr_intr_count_r.cnt.value <= 32'h0; + end else if(field_combo.intr_block_rf.error_axi_wr_intr_count_r.cnt.load_next) begin + field_storage.intr_block_rf.error_axi_wr_intr_count_r.cnt.value <= field_combo.intr_block_rf.error_axi_wr_intr_count_r.cnt.next; + end + end + // Field: axi_dma_reg.intr_block_rf.error_mbox_lock_intr_count_r.cnt + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_mbox_lock_intr_count_r.cnt.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_mbox_lock_intr_count_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.intr_block_rf.error_mbox_lock_intr_count_r.cnt.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + if(field_storage.intr_block_rf.error_mbox_lock_intr_count_incr_r.pulse.value) begin // increment + if(((33)'(next_c) + 32'h1) > 32'hffffffff) begin // up-counter saturated + next_c = 32'hffffffff; + end else begin + next_c = next_c + 32'h1; + end + load_next_c = '1; + end + field_combo.intr_block_rf.error_mbox_lock_intr_count_r.cnt.incrthreshold = (field_storage.intr_block_rf.error_mbox_lock_intr_count_r.cnt.value >= 32'hffffffff); + field_combo.intr_block_rf.error_mbox_lock_intr_count_r.cnt.incrsaturate = (field_storage.intr_block_rf.error_mbox_lock_intr_count_r.cnt.value >= 32'hffffffff); + if(next_c > 32'hffffffff) begin + next_c = 32'hffffffff; + load_next_c = '1; + end + field_combo.intr_block_rf.error_mbox_lock_intr_count_r.cnt.next = next_c; + field_combo.intr_block_rf.error_mbox_lock_intr_count_r.cnt.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.intr_block_rf.error_mbox_lock_intr_count_r.cnt.value <= 32'h0; + end else if(field_combo.intr_block_rf.error_mbox_lock_intr_count_r.cnt.load_next) begin + field_storage.intr_block_rf.error_mbox_lock_intr_count_r.cnt.value <= field_combo.intr_block_rf.error_mbox_lock_intr_count_r.cnt.next; + end + end + // Field: axi_dma_reg.intr_block_rf.error_sha_lock_intr_count_r.cnt + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_sha_lock_intr_count_r.cnt.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_sha_lock_intr_count_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.intr_block_rf.error_sha_lock_intr_count_r.cnt.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + if(field_storage.intr_block_rf.error_sha_lock_intr_count_incr_r.pulse.value) begin // increment + if(((33)'(next_c) + 32'h1) > 32'hffffffff) begin // up-counter saturated + next_c = 32'hffffffff; + end else begin + next_c = next_c + 32'h1; + end + load_next_c = '1; + end + field_combo.intr_block_rf.error_sha_lock_intr_count_r.cnt.incrthreshold = (field_storage.intr_block_rf.error_sha_lock_intr_count_r.cnt.value >= 32'hffffffff); + field_combo.intr_block_rf.error_sha_lock_intr_count_r.cnt.incrsaturate = (field_storage.intr_block_rf.error_sha_lock_intr_count_r.cnt.value >= 32'hffffffff); + if(next_c > 32'hffffffff) begin + next_c = 32'hffffffff; + load_next_c = '1; + end + field_combo.intr_block_rf.error_sha_lock_intr_count_r.cnt.next = next_c; + field_combo.intr_block_rf.error_sha_lock_intr_count_r.cnt.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.intr_block_rf.error_sha_lock_intr_count_r.cnt.value <= 32'h0; + end else if(field_combo.intr_block_rf.error_sha_lock_intr_count_r.cnt.load_next) begin + field_storage.intr_block_rf.error_sha_lock_intr_count_r.cnt.value <= field_combo.intr_block_rf.error_sha_lock_intr_count_r.cnt.next; + end + end + // Field: axi_dma_reg.intr_block_rf.error_fifo_oflow_intr_count_r.cnt + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_fifo_oflow_intr_count_r.cnt.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_fifo_oflow_intr_count_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.intr_block_rf.error_fifo_oflow_intr_count_r.cnt.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + if(field_storage.intr_block_rf.error_fifo_oflow_intr_count_incr_r.pulse.value) begin // increment + if(((33)'(next_c) + 32'h1) > 32'hffffffff) begin // up-counter saturated + next_c = 32'hffffffff; + end else begin + next_c = next_c + 32'h1; + end + load_next_c = '1; + end + field_combo.intr_block_rf.error_fifo_oflow_intr_count_r.cnt.incrthreshold = (field_storage.intr_block_rf.error_fifo_oflow_intr_count_r.cnt.value >= 32'hffffffff); + field_combo.intr_block_rf.error_fifo_oflow_intr_count_r.cnt.incrsaturate = (field_storage.intr_block_rf.error_fifo_oflow_intr_count_r.cnt.value >= 32'hffffffff); + if(next_c > 32'hffffffff) begin + next_c = 32'hffffffff; + load_next_c = '1; + end + field_combo.intr_block_rf.error_fifo_oflow_intr_count_r.cnt.next = next_c; + field_combo.intr_block_rf.error_fifo_oflow_intr_count_r.cnt.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.intr_block_rf.error_fifo_oflow_intr_count_r.cnt.value <= 32'h0; + end else if(field_combo.intr_block_rf.error_fifo_oflow_intr_count_r.cnt.load_next) begin + field_storage.intr_block_rf.error_fifo_oflow_intr_count_r.cnt.value <= field_combo.intr_block_rf.error_fifo_oflow_intr_count_r.cnt.next; + end + end + // Field: axi_dma_reg.intr_block_rf.error_fifo_uflow_intr_count_r.cnt + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_fifo_uflow_intr_count_r.cnt.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_fifo_uflow_intr_count_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.intr_block_rf.error_fifo_uflow_intr_count_r.cnt.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + if(field_storage.intr_block_rf.error_fifo_uflow_intr_count_incr_r.pulse.value) begin // increment + if(((33)'(next_c) + 32'h1) > 32'hffffffff) begin // up-counter saturated + next_c = 32'hffffffff; + end else begin + next_c = next_c + 32'h1; + end + load_next_c = '1; + end + field_combo.intr_block_rf.error_fifo_uflow_intr_count_r.cnt.incrthreshold = (field_storage.intr_block_rf.error_fifo_uflow_intr_count_r.cnt.value >= 32'hffffffff); + field_combo.intr_block_rf.error_fifo_uflow_intr_count_r.cnt.incrsaturate = (field_storage.intr_block_rf.error_fifo_uflow_intr_count_r.cnt.value >= 32'hffffffff); + if(next_c > 32'hffffffff) begin + next_c = 32'hffffffff; + load_next_c = '1; + end + field_combo.intr_block_rf.error_fifo_uflow_intr_count_r.cnt.next = next_c; + field_combo.intr_block_rf.error_fifo_uflow_intr_count_r.cnt.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.intr_block_rf.error_fifo_uflow_intr_count_r.cnt.value <= 32'h0; + end else if(field_combo.intr_block_rf.error_fifo_uflow_intr_count_r.cnt.load_next) begin + field_storage.intr_block_rf.error_fifo_uflow_intr_count_r.cnt.value <= field_combo.intr_block_rf.error_fifo_uflow_intr_count_r.cnt.next; + end + end + // Field: axi_dma_reg.intr_block_rf.error_aes_cif_intr_count_r.cnt + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_aes_cif_intr_count_r.cnt.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_aes_cif_intr_count_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.intr_block_rf.error_aes_cif_intr_count_r.cnt.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + if(field_storage.intr_block_rf.error_aes_cif_intr_count_incr_r.pulse.value) begin // increment + if(((33)'(next_c) + 32'h1) > 32'hffffffff) begin // up-counter saturated + next_c = 32'hffffffff; + end else begin + next_c = next_c + 32'h1; + end + load_next_c = '1; + end + field_combo.intr_block_rf.error_aes_cif_intr_count_r.cnt.incrthreshold = (field_storage.intr_block_rf.error_aes_cif_intr_count_r.cnt.value >= 32'hffffffff); + field_combo.intr_block_rf.error_aes_cif_intr_count_r.cnt.incrsaturate = (field_storage.intr_block_rf.error_aes_cif_intr_count_r.cnt.value >= 32'hffffffff); + if(next_c > 32'hffffffff) begin + next_c = 32'hffffffff; + load_next_c = '1; + end + field_combo.intr_block_rf.error_aes_cif_intr_count_r.cnt.next = next_c; + field_combo.intr_block_rf.error_aes_cif_intr_count_r.cnt.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.intr_block_rf.error_aes_cif_intr_count_r.cnt.value <= 32'h0; + end else if(field_combo.intr_block_rf.error_aes_cif_intr_count_r.cnt.load_next) begin + field_storage.intr_block_rf.error_aes_cif_intr_count_r.cnt.value <= field_combo.intr_block_rf.error_aes_cif_intr_count_r.cnt.next; + end + end + // Field: axi_dma_reg.intr_block_rf.error_kv_rd_intr_count_r.cnt + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_kv_rd_intr_count_r.cnt.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_kv_rd_intr_count_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.intr_block_rf.error_kv_rd_intr_count_r.cnt.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + if(field_storage.intr_block_rf.error_kv_rd_intr_count_incr_r.pulse.value) begin // increment + if(((33)'(next_c) + 32'h1) > 32'hffffffff) begin // up-counter saturated + next_c = 32'hffffffff; + end else begin + next_c = next_c + 32'h1; + end + load_next_c = '1; + end + field_combo.intr_block_rf.error_kv_rd_intr_count_r.cnt.incrthreshold = (field_storage.intr_block_rf.error_kv_rd_intr_count_r.cnt.value >= 32'hffffffff); + field_combo.intr_block_rf.error_kv_rd_intr_count_r.cnt.incrsaturate = (field_storage.intr_block_rf.error_kv_rd_intr_count_r.cnt.value >= 32'hffffffff); + if(next_c > 32'hffffffff) begin + next_c = 32'hffffffff; + load_next_c = '1; + end + field_combo.intr_block_rf.error_kv_rd_intr_count_r.cnt.next = next_c; + field_combo.intr_block_rf.error_kv_rd_intr_count_r.cnt.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.intr_block_rf.error_kv_rd_intr_count_r.cnt.value <= 32'h0; + end else if(field_combo.intr_block_rf.error_kv_rd_intr_count_r.cnt.load_next) begin + field_storage.intr_block_rf.error_kv_rd_intr_count_r.cnt.value <= field_combo.intr_block_rf.error_kv_rd_intr_count_r.cnt.next; + end + end + // Field: axi_dma_reg.intr_block_rf.error_kv_rd_large_intr_count_r.cnt + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_kv_rd_large_intr_count_r.cnt.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_kv_rd_large_intr_count_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.intr_block_rf.error_kv_rd_large_intr_count_r.cnt.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + if(field_storage.intr_block_rf.error_kv_rd_large_intr_count_incr_r.pulse.value) begin // increment + if(((33)'(next_c) + 32'h1) > 32'hffffffff) begin // up-counter saturated + next_c = 32'hffffffff; + end else begin + next_c = next_c + 32'h1; + end + load_next_c = '1; + end + field_combo.intr_block_rf.error_kv_rd_large_intr_count_r.cnt.incrthreshold = (field_storage.intr_block_rf.error_kv_rd_large_intr_count_r.cnt.value >= 32'hffffffff); + field_combo.intr_block_rf.error_kv_rd_large_intr_count_r.cnt.incrsaturate = (field_storage.intr_block_rf.error_kv_rd_large_intr_count_r.cnt.value >= 32'hffffffff); + if(next_c > 32'hffffffff) begin + next_c = 32'hffffffff; + load_next_c = '1; + end + field_combo.intr_block_rf.error_kv_rd_large_intr_count_r.cnt.next = next_c; + field_combo.intr_block_rf.error_kv_rd_large_intr_count_r.cnt.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.intr_block_rf.error_kv_rd_large_intr_count_r.cnt.value <= 32'h0; + end else if(field_combo.intr_block_rf.error_kv_rd_large_intr_count_r.cnt.load_next) begin + field_storage.intr_block_rf.error_kv_rd_large_intr_count_r.cnt.value <= field_combo.intr_block_rf.error_kv_rd_large_intr_count_r.cnt.next; + end + end + // Field: axi_dma_reg.intr_block_rf.notif_txn_done_intr_count_r.cnt + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_txn_done_intr_count_r.cnt.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.notif_txn_done_intr_count_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.intr_block_rf.notif_txn_done_intr_count_r.cnt.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + if(field_storage.intr_block_rf.notif_txn_done_intr_count_incr_r.pulse.value) begin // increment + if(((33)'(next_c) + 32'h1) > 32'hffffffff) begin // up-counter saturated + next_c = 32'hffffffff; + end else begin + next_c = next_c + 32'h1; + end + load_next_c = '1; + end + field_combo.intr_block_rf.notif_txn_done_intr_count_r.cnt.incrthreshold = (field_storage.intr_block_rf.notif_txn_done_intr_count_r.cnt.value >= 32'hffffffff); + field_combo.intr_block_rf.notif_txn_done_intr_count_r.cnt.incrsaturate = (field_storage.intr_block_rf.notif_txn_done_intr_count_r.cnt.value >= 32'hffffffff); + if(next_c > 32'hffffffff) begin + next_c = 32'hffffffff; + load_next_c = '1; + end + field_combo.intr_block_rf.notif_txn_done_intr_count_r.cnt.next = next_c; + field_combo.intr_block_rf.notif_txn_done_intr_count_r.cnt.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.notif_txn_done_intr_count_r.cnt.value <= 32'h0; + end else if(field_combo.intr_block_rf.notif_txn_done_intr_count_r.cnt.load_next) begin + field_storage.intr_block_rf.notif_txn_done_intr_count_r.cnt.value <= field_combo.intr_block_rf.notif_txn_done_intr_count_r.cnt.next; + end + end + // Field: axi_dma_reg.intr_block_rf.notif_fifo_empty_intr_count_r.cnt + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_fifo_empty_intr_count_r.cnt.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.notif_fifo_empty_intr_count_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.intr_block_rf.notif_fifo_empty_intr_count_r.cnt.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + if(field_storage.intr_block_rf.notif_fifo_empty_intr_count_incr_r.pulse.value) begin // increment + if(((33)'(next_c) + 32'h1) > 32'hffffffff) begin // up-counter saturated + next_c = 32'hffffffff; + end else begin + next_c = next_c + 32'h1; + end + load_next_c = '1; + end + field_combo.intr_block_rf.notif_fifo_empty_intr_count_r.cnt.incrthreshold = (field_storage.intr_block_rf.notif_fifo_empty_intr_count_r.cnt.value >= 32'hffffffff); + field_combo.intr_block_rf.notif_fifo_empty_intr_count_r.cnt.incrsaturate = (field_storage.intr_block_rf.notif_fifo_empty_intr_count_r.cnt.value >= 32'hffffffff); + if(next_c > 32'hffffffff) begin + next_c = 32'hffffffff; + load_next_c = '1; + end + field_combo.intr_block_rf.notif_fifo_empty_intr_count_r.cnt.next = next_c; + field_combo.intr_block_rf.notif_fifo_empty_intr_count_r.cnt.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.notif_fifo_empty_intr_count_r.cnt.value <= 32'h0; + end else if(field_combo.intr_block_rf.notif_fifo_empty_intr_count_r.cnt.load_next) begin + field_storage.intr_block_rf.notif_fifo_empty_intr_count_r.cnt.value <= field_combo.intr_block_rf.notif_fifo_empty_intr_count_r.cnt.next; + end + end + // Field: axi_dma_reg.intr_block_rf.notif_fifo_not_empty_intr_count_r.cnt + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_fifo_not_empty_intr_count_r.cnt.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.notif_fifo_not_empty_intr_count_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.intr_block_rf.notif_fifo_not_empty_intr_count_r.cnt.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + if(field_storage.intr_block_rf.notif_fifo_not_empty_intr_count_incr_r.pulse.value) begin // increment + if(((33)'(next_c) + 32'h1) > 32'hffffffff) begin // up-counter saturated + next_c = 32'hffffffff; + end else begin + next_c = next_c + 32'h1; + end + load_next_c = '1; + end + field_combo.intr_block_rf.notif_fifo_not_empty_intr_count_r.cnt.incrthreshold = (field_storage.intr_block_rf.notif_fifo_not_empty_intr_count_r.cnt.value >= 32'hffffffff); + field_combo.intr_block_rf.notif_fifo_not_empty_intr_count_r.cnt.incrsaturate = (field_storage.intr_block_rf.notif_fifo_not_empty_intr_count_r.cnt.value >= 32'hffffffff); + if(next_c > 32'hffffffff) begin + next_c = 32'hffffffff; + load_next_c = '1; + end + field_combo.intr_block_rf.notif_fifo_not_empty_intr_count_r.cnt.next = next_c; + field_combo.intr_block_rf.notif_fifo_not_empty_intr_count_r.cnt.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.notif_fifo_not_empty_intr_count_r.cnt.value <= 32'h0; + end else if(field_combo.intr_block_rf.notif_fifo_not_empty_intr_count_r.cnt.load_next) begin + field_storage.intr_block_rf.notif_fifo_not_empty_intr_count_r.cnt.value <= field_combo.intr_block_rf.notif_fifo_not_empty_intr_count_r.cnt.next; + end + end + // Field: axi_dma_reg.intr_block_rf.notif_fifo_full_intr_count_r.cnt + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_fifo_full_intr_count_r.cnt.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.notif_fifo_full_intr_count_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.intr_block_rf.notif_fifo_full_intr_count_r.cnt.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + if(field_storage.intr_block_rf.notif_fifo_full_intr_count_incr_r.pulse.value) begin // increment + if(((33)'(next_c) + 32'h1) > 32'hffffffff) begin // up-counter saturated + next_c = 32'hffffffff; + end else begin + next_c = next_c + 32'h1; + end + load_next_c = '1; + end + field_combo.intr_block_rf.notif_fifo_full_intr_count_r.cnt.incrthreshold = (field_storage.intr_block_rf.notif_fifo_full_intr_count_r.cnt.value >= 32'hffffffff); + field_combo.intr_block_rf.notif_fifo_full_intr_count_r.cnt.incrsaturate = (field_storage.intr_block_rf.notif_fifo_full_intr_count_r.cnt.value >= 32'hffffffff); + if(next_c > 32'hffffffff) begin + next_c = 32'hffffffff; + load_next_c = '1; + end + field_combo.intr_block_rf.notif_fifo_full_intr_count_r.cnt.next = next_c; + field_combo.intr_block_rf.notif_fifo_full_intr_count_r.cnt.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.notif_fifo_full_intr_count_r.cnt.value <= 32'h0; + end else if(field_combo.intr_block_rf.notif_fifo_full_intr_count_r.cnt.load_next) begin + field_storage.intr_block_rf.notif_fifo_full_intr_count_r.cnt.value <= field_combo.intr_block_rf.notif_fifo_full_intr_count_r.cnt.next; + end + end + // Field: axi_dma_reg.intr_block_rf.notif_fifo_not_full_intr_count_r.cnt + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_fifo_not_full_intr_count_r.cnt.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.notif_fifo_not_full_intr_count_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.intr_block_rf.notif_fifo_not_full_intr_count_r.cnt.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + if(field_storage.intr_block_rf.notif_fifo_not_full_intr_count_incr_r.pulse.value) begin // increment + if(((33)'(next_c) + 32'h1) > 32'hffffffff) begin // up-counter saturated + next_c = 32'hffffffff; + end else begin + next_c = next_c + 32'h1; + end + load_next_c = '1; + end + field_combo.intr_block_rf.notif_fifo_not_full_intr_count_r.cnt.incrthreshold = (field_storage.intr_block_rf.notif_fifo_not_full_intr_count_r.cnt.value >= 32'hffffffff); + field_combo.intr_block_rf.notif_fifo_not_full_intr_count_r.cnt.incrsaturate = (field_storage.intr_block_rf.notif_fifo_not_full_intr_count_r.cnt.value >= 32'hffffffff); + if(next_c > 32'hffffffff) begin + next_c = 32'hffffffff; + load_next_c = '1; + end + field_combo.intr_block_rf.notif_fifo_not_full_intr_count_r.cnt.next = next_c; + field_combo.intr_block_rf.notif_fifo_not_full_intr_count_r.cnt.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.notif_fifo_not_full_intr_count_r.cnt.value <= 32'h0; + end else if(field_combo.intr_block_rf.notif_fifo_not_full_intr_count_r.cnt.load_next) begin + field_storage.intr_block_rf.notif_fifo_not_full_intr_count_r.cnt.value <= field_combo.intr_block_rf.notif_fifo_not_full_intr_count_r.cnt.next; + end + end + // Field: axi_dma_reg.intr_block_rf.error_cmd_dec_intr_count_incr_r.pulse + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_cmd_dec_intr_count_incr_r.pulse.value; + load_next_c = '0; + if(field_storage.intr_block_rf.error_intr_trig_r.error_cmd_dec_trig.value) begin // HW Write - we + next_c = field_storage.intr_block_rf.error_intr_trig_r.error_cmd_dec_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.error_internal_intr_r.error_cmd_dec_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end + if(field_storage.intr_block_rf.error_cmd_dec_intr_count_incr_r.pulse.value) begin // decrement + field_combo.intr_block_rf.error_cmd_dec_intr_count_incr_r.pulse.underflow = (next_c < (1'h1)); + next_c = next_c - 1'h1; + load_next_c = '1; + end else begin + field_combo.intr_block_rf.error_cmd_dec_intr_count_incr_r.pulse.underflow = '0; + end + field_combo.intr_block_rf.error_cmd_dec_intr_count_incr_r.pulse.decrthreshold = (field_storage.intr_block_rf.error_cmd_dec_intr_count_incr_r.pulse.value <= 1'd0); + field_combo.intr_block_rf.error_cmd_dec_intr_count_incr_r.pulse.next = next_c; + field_combo.intr_block_rf.error_cmd_dec_intr_count_incr_r.pulse.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.error_cmd_dec_intr_count_incr_r.pulse.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_cmd_dec_intr_count_incr_r.pulse.load_next) begin + field_storage.intr_block_rf.error_cmd_dec_intr_count_incr_r.pulse.value <= field_combo.intr_block_rf.error_cmd_dec_intr_count_incr_r.pulse.next; + end + end + // Field: axi_dma_reg.intr_block_rf.error_axi_rd_intr_count_incr_r.pulse + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_axi_rd_intr_count_incr_r.pulse.value; + load_next_c = '0; + if(field_storage.intr_block_rf.error_intr_trig_r.error_axi_rd_trig.value) begin // HW Write - we + next_c = field_storage.intr_block_rf.error_intr_trig_r.error_axi_rd_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.error_internal_intr_r.error_axi_rd_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end + if(field_storage.intr_block_rf.error_axi_rd_intr_count_incr_r.pulse.value) begin // decrement + field_combo.intr_block_rf.error_axi_rd_intr_count_incr_r.pulse.underflow = (next_c < (1'h1)); + next_c = next_c - 1'h1; + load_next_c = '1; + end else begin + field_combo.intr_block_rf.error_axi_rd_intr_count_incr_r.pulse.underflow = '0; + end + field_combo.intr_block_rf.error_axi_rd_intr_count_incr_r.pulse.decrthreshold = (field_storage.intr_block_rf.error_axi_rd_intr_count_incr_r.pulse.value <= 1'd0); + field_combo.intr_block_rf.error_axi_rd_intr_count_incr_r.pulse.next = next_c; + field_combo.intr_block_rf.error_axi_rd_intr_count_incr_r.pulse.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.error_axi_rd_intr_count_incr_r.pulse.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_axi_rd_intr_count_incr_r.pulse.load_next) begin + field_storage.intr_block_rf.error_axi_rd_intr_count_incr_r.pulse.value <= field_combo.intr_block_rf.error_axi_rd_intr_count_incr_r.pulse.next; + end + end + // Field: axi_dma_reg.intr_block_rf.error_axi_wr_intr_count_incr_r.pulse + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_axi_wr_intr_count_incr_r.pulse.value; + load_next_c = '0; + if(field_storage.intr_block_rf.error_intr_trig_r.error_axi_wr_trig.value) begin // HW Write - we + next_c = field_storage.intr_block_rf.error_intr_trig_r.error_axi_wr_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.error_internal_intr_r.error_axi_wr_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end + if(field_storage.intr_block_rf.error_axi_wr_intr_count_incr_r.pulse.value) begin // decrement + field_combo.intr_block_rf.error_axi_wr_intr_count_incr_r.pulse.underflow = (next_c < (1'h1)); + next_c = next_c - 1'h1; + load_next_c = '1; + end else begin + field_combo.intr_block_rf.error_axi_wr_intr_count_incr_r.pulse.underflow = '0; + end + field_combo.intr_block_rf.error_axi_wr_intr_count_incr_r.pulse.decrthreshold = (field_storage.intr_block_rf.error_axi_wr_intr_count_incr_r.pulse.value <= 1'd0); + field_combo.intr_block_rf.error_axi_wr_intr_count_incr_r.pulse.next = next_c; + field_combo.intr_block_rf.error_axi_wr_intr_count_incr_r.pulse.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.error_axi_wr_intr_count_incr_r.pulse.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_axi_wr_intr_count_incr_r.pulse.load_next) begin + field_storage.intr_block_rf.error_axi_wr_intr_count_incr_r.pulse.value <= field_combo.intr_block_rf.error_axi_wr_intr_count_incr_r.pulse.next; + end + end + // Field: axi_dma_reg.intr_block_rf.error_mbox_lock_intr_count_incr_r.pulse + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_mbox_lock_intr_count_incr_r.pulse.value; + load_next_c = '0; + if(field_storage.intr_block_rf.error_intr_trig_r.error_mbox_lock_trig.value) begin // HW Write - we + next_c = field_storage.intr_block_rf.error_intr_trig_r.error_mbox_lock_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.error_internal_intr_r.error_mbox_lock_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end + if(field_storage.intr_block_rf.error_mbox_lock_intr_count_incr_r.pulse.value) begin // decrement + field_combo.intr_block_rf.error_mbox_lock_intr_count_incr_r.pulse.underflow = (next_c < (1'h1)); + next_c = next_c - 1'h1; + load_next_c = '1; + end else begin + field_combo.intr_block_rf.error_mbox_lock_intr_count_incr_r.pulse.underflow = '0; + end + field_combo.intr_block_rf.error_mbox_lock_intr_count_incr_r.pulse.decrthreshold = (field_storage.intr_block_rf.error_mbox_lock_intr_count_incr_r.pulse.value <= 1'd0); + field_combo.intr_block_rf.error_mbox_lock_intr_count_incr_r.pulse.next = next_c; + field_combo.intr_block_rf.error_mbox_lock_intr_count_incr_r.pulse.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.error_mbox_lock_intr_count_incr_r.pulse.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_mbox_lock_intr_count_incr_r.pulse.load_next) begin + field_storage.intr_block_rf.error_mbox_lock_intr_count_incr_r.pulse.value <= field_combo.intr_block_rf.error_mbox_lock_intr_count_incr_r.pulse.next; + end + end + // Field: axi_dma_reg.intr_block_rf.error_sha_lock_intr_count_incr_r.pulse + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_sha_lock_intr_count_incr_r.pulse.value; + load_next_c = '0; + if(field_storage.intr_block_rf.error_intr_trig_r.error_sha_lock_trig.value) begin // HW Write - we + next_c = field_storage.intr_block_rf.error_intr_trig_r.error_sha_lock_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.error_internal_intr_r.error_sha_lock_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end + if(field_storage.intr_block_rf.error_sha_lock_intr_count_incr_r.pulse.value) begin // decrement + field_combo.intr_block_rf.error_sha_lock_intr_count_incr_r.pulse.underflow = (next_c < (1'h1)); + next_c = next_c - 1'h1; + load_next_c = '1; + end else begin + field_combo.intr_block_rf.error_sha_lock_intr_count_incr_r.pulse.underflow = '0; + end + field_combo.intr_block_rf.error_sha_lock_intr_count_incr_r.pulse.decrthreshold = (field_storage.intr_block_rf.error_sha_lock_intr_count_incr_r.pulse.value <= 1'd0); + field_combo.intr_block_rf.error_sha_lock_intr_count_incr_r.pulse.next = next_c; + field_combo.intr_block_rf.error_sha_lock_intr_count_incr_r.pulse.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.error_sha_lock_intr_count_incr_r.pulse.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_sha_lock_intr_count_incr_r.pulse.load_next) begin + field_storage.intr_block_rf.error_sha_lock_intr_count_incr_r.pulse.value <= field_combo.intr_block_rf.error_sha_lock_intr_count_incr_r.pulse.next; + end + end + // Field: axi_dma_reg.intr_block_rf.error_fifo_oflow_intr_count_incr_r.pulse + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_fifo_oflow_intr_count_incr_r.pulse.value; + load_next_c = '0; + if(field_storage.intr_block_rf.error_intr_trig_r.error_fifo_oflow_trig.value) begin // HW Write - we + next_c = field_storage.intr_block_rf.error_intr_trig_r.error_fifo_oflow_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.error_internal_intr_r.error_fifo_oflow_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end + if(field_storage.intr_block_rf.error_fifo_oflow_intr_count_incr_r.pulse.value) begin // decrement + field_combo.intr_block_rf.error_fifo_oflow_intr_count_incr_r.pulse.underflow = (next_c < (1'h1)); + next_c = next_c - 1'h1; + load_next_c = '1; + end else begin + field_combo.intr_block_rf.error_fifo_oflow_intr_count_incr_r.pulse.underflow = '0; + end + field_combo.intr_block_rf.error_fifo_oflow_intr_count_incr_r.pulse.decrthreshold = (field_storage.intr_block_rf.error_fifo_oflow_intr_count_incr_r.pulse.value <= 1'd0); + field_combo.intr_block_rf.error_fifo_oflow_intr_count_incr_r.pulse.next = next_c; + field_combo.intr_block_rf.error_fifo_oflow_intr_count_incr_r.pulse.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.error_fifo_oflow_intr_count_incr_r.pulse.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_fifo_oflow_intr_count_incr_r.pulse.load_next) begin + field_storage.intr_block_rf.error_fifo_oflow_intr_count_incr_r.pulse.value <= field_combo.intr_block_rf.error_fifo_oflow_intr_count_incr_r.pulse.next; + end + end + // Field: axi_dma_reg.intr_block_rf.error_fifo_uflow_intr_count_incr_r.pulse + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_fifo_uflow_intr_count_incr_r.pulse.value; + load_next_c = '0; + if(field_storage.intr_block_rf.error_intr_trig_r.error_fifo_uflow_trig.value) begin // HW Write - we + next_c = field_storage.intr_block_rf.error_intr_trig_r.error_fifo_uflow_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.error_internal_intr_r.error_fifo_uflow_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end + if(field_storage.intr_block_rf.error_fifo_uflow_intr_count_incr_r.pulse.value) begin // decrement + field_combo.intr_block_rf.error_fifo_uflow_intr_count_incr_r.pulse.underflow = (next_c < (1'h1)); + next_c = next_c - 1'h1; + load_next_c = '1; + end else begin + field_combo.intr_block_rf.error_fifo_uflow_intr_count_incr_r.pulse.underflow = '0; + end + field_combo.intr_block_rf.error_fifo_uflow_intr_count_incr_r.pulse.decrthreshold = (field_storage.intr_block_rf.error_fifo_uflow_intr_count_incr_r.pulse.value <= 1'd0); + field_combo.intr_block_rf.error_fifo_uflow_intr_count_incr_r.pulse.next = next_c; + field_combo.intr_block_rf.error_fifo_uflow_intr_count_incr_r.pulse.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.error_fifo_uflow_intr_count_incr_r.pulse.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_fifo_uflow_intr_count_incr_r.pulse.load_next) begin + field_storage.intr_block_rf.error_fifo_uflow_intr_count_incr_r.pulse.value <= field_combo.intr_block_rf.error_fifo_uflow_intr_count_incr_r.pulse.next; + end + end + // Field: axi_dma_reg.intr_block_rf.error_aes_cif_intr_count_incr_r.pulse + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_aes_cif_intr_count_incr_r.pulse.value; + load_next_c = '0; + if(field_storage.intr_block_rf.error_intr_trig_r.error_aes_cif_trig.value) begin // HW Write - we + next_c = field_storage.intr_block_rf.error_intr_trig_r.error_aes_cif_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.error_internal_intr_r.error_aes_cif_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end + if(field_storage.intr_block_rf.error_aes_cif_intr_count_incr_r.pulse.value) begin // decrement + field_combo.intr_block_rf.error_aes_cif_intr_count_incr_r.pulse.underflow = (next_c < (1'h1)); + next_c = next_c - 1'h1; + load_next_c = '1; + end else begin + field_combo.intr_block_rf.error_aes_cif_intr_count_incr_r.pulse.underflow = '0; + end + field_combo.intr_block_rf.error_aes_cif_intr_count_incr_r.pulse.decrthreshold = (field_storage.intr_block_rf.error_aes_cif_intr_count_incr_r.pulse.value <= 1'd0); + field_combo.intr_block_rf.error_aes_cif_intr_count_incr_r.pulse.next = next_c; + field_combo.intr_block_rf.error_aes_cif_intr_count_incr_r.pulse.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.error_aes_cif_intr_count_incr_r.pulse.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_aes_cif_intr_count_incr_r.pulse.load_next) begin + field_storage.intr_block_rf.error_aes_cif_intr_count_incr_r.pulse.value <= field_combo.intr_block_rf.error_aes_cif_intr_count_incr_r.pulse.next; + end + end + // Field: axi_dma_reg.intr_block_rf.error_kv_rd_intr_count_incr_r.pulse + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_kv_rd_intr_count_incr_r.pulse.value; + load_next_c = '0; + if(field_storage.intr_block_rf.error_intr_trig_r.error_kv_rd_trig.value) begin // HW Write - we + next_c = field_storage.intr_block_rf.error_intr_trig_r.error_kv_rd_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.error_internal_intr_r.error_kv_rd_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end + if(field_storage.intr_block_rf.error_kv_rd_intr_count_incr_r.pulse.value) begin // decrement + field_combo.intr_block_rf.error_kv_rd_intr_count_incr_r.pulse.underflow = (next_c < (1'h1)); + next_c = next_c - 1'h1; + load_next_c = '1; + end else begin + field_combo.intr_block_rf.error_kv_rd_intr_count_incr_r.pulse.underflow = '0; + end + field_combo.intr_block_rf.error_kv_rd_intr_count_incr_r.pulse.decrthreshold = (field_storage.intr_block_rf.error_kv_rd_intr_count_incr_r.pulse.value <= 1'd0); + field_combo.intr_block_rf.error_kv_rd_intr_count_incr_r.pulse.next = next_c; + field_combo.intr_block_rf.error_kv_rd_intr_count_incr_r.pulse.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.error_kv_rd_intr_count_incr_r.pulse.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_kv_rd_intr_count_incr_r.pulse.load_next) begin + field_storage.intr_block_rf.error_kv_rd_intr_count_incr_r.pulse.value <= field_combo.intr_block_rf.error_kv_rd_intr_count_incr_r.pulse.next; + end + end + // Field: axi_dma_reg.intr_block_rf.error_kv_rd_large_intr_count_incr_r.pulse + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_kv_rd_large_intr_count_incr_r.pulse.value; + load_next_c = '0; + if(field_storage.intr_block_rf.error_intr_trig_r.error_kv_rd_large_trig.value) begin // HW Write - we + next_c = field_storage.intr_block_rf.error_intr_trig_r.error_kv_rd_large_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.error_internal_intr_r.error_kv_rd_large_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end + if(field_storage.intr_block_rf.error_kv_rd_large_intr_count_incr_r.pulse.value) begin // decrement + field_combo.intr_block_rf.error_kv_rd_large_intr_count_incr_r.pulse.underflow = (next_c < (1'h1)); + next_c = next_c - 1'h1; + load_next_c = '1; + end else begin + field_combo.intr_block_rf.error_kv_rd_large_intr_count_incr_r.pulse.underflow = '0; + end + field_combo.intr_block_rf.error_kv_rd_large_intr_count_incr_r.pulse.decrthreshold = (field_storage.intr_block_rf.error_kv_rd_large_intr_count_incr_r.pulse.value <= 1'd0); + field_combo.intr_block_rf.error_kv_rd_large_intr_count_incr_r.pulse.next = next_c; + field_combo.intr_block_rf.error_kv_rd_large_intr_count_incr_r.pulse.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.error_kv_rd_large_intr_count_incr_r.pulse.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_kv_rd_large_intr_count_incr_r.pulse.load_next) begin + field_storage.intr_block_rf.error_kv_rd_large_intr_count_incr_r.pulse.value <= field_combo.intr_block_rf.error_kv_rd_large_intr_count_incr_r.pulse.next; + end + end + // Field: axi_dma_reg.intr_block_rf.notif_txn_done_intr_count_incr_r.pulse + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_txn_done_intr_count_incr_r.pulse.value; + load_next_c = '0; + if(field_storage.intr_block_rf.notif_intr_trig_r.notif_txn_done_trig.value) begin // HW Write - we + next_c = field_storage.intr_block_rf.notif_intr_trig_r.notif_txn_done_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.notif_internal_intr_r.notif_txn_done_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end + if(field_storage.intr_block_rf.notif_txn_done_intr_count_incr_r.pulse.value) begin // decrement + field_combo.intr_block_rf.notif_txn_done_intr_count_incr_r.pulse.underflow = (next_c < (1'h1)); + next_c = next_c - 1'h1; + load_next_c = '1; + end else begin + field_combo.intr_block_rf.notif_txn_done_intr_count_incr_r.pulse.underflow = '0; + end + field_combo.intr_block_rf.notif_txn_done_intr_count_incr_r.pulse.decrthreshold = (field_storage.intr_block_rf.notif_txn_done_intr_count_incr_r.pulse.value <= 1'd0); + field_combo.intr_block_rf.notif_txn_done_intr_count_incr_r.pulse.next = next_c; + field_combo.intr_block_rf.notif_txn_done_intr_count_incr_r.pulse.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.notif_txn_done_intr_count_incr_r.pulse.value <= 1'h0; + end else if(field_combo.intr_block_rf.notif_txn_done_intr_count_incr_r.pulse.load_next) begin + field_storage.intr_block_rf.notif_txn_done_intr_count_incr_r.pulse.value <= field_combo.intr_block_rf.notif_txn_done_intr_count_incr_r.pulse.next; + end + end + // Field: axi_dma_reg.intr_block_rf.notif_fifo_empty_intr_count_incr_r.pulse + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_fifo_empty_intr_count_incr_r.pulse.value; + load_next_c = '0; + if(field_storage.intr_block_rf.notif_intr_trig_r.notif_fifo_empty_trig.value) begin // HW Write - we + next_c = field_storage.intr_block_rf.notif_intr_trig_r.notif_fifo_empty_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.notif_internal_intr_r.notif_fifo_empty_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end + if(field_storage.intr_block_rf.notif_fifo_empty_intr_count_incr_r.pulse.value) begin // decrement + field_combo.intr_block_rf.notif_fifo_empty_intr_count_incr_r.pulse.underflow = (next_c < (1'h1)); + next_c = next_c - 1'h1; + load_next_c = '1; + end else begin + field_combo.intr_block_rf.notif_fifo_empty_intr_count_incr_r.pulse.underflow = '0; + end + field_combo.intr_block_rf.notif_fifo_empty_intr_count_incr_r.pulse.decrthreshold = (field_storage.intr_block_rf.notif_fifo_empty_intr_count_incr_r.pulse.value <= 1'd0); + field_combo.intr_block_rf.notif_fifo_empty_intr_count_incr_r.pulse.next = next_c; + field_combo.intr_block_rf.notif_fifo_empty_intr_count_incr_r.pulse.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.notif_fifo_empty_intr_count_incr_r.pulse.value <= 1'h0; + end else if(field_combo.intr_block_rf.notif_fifo_empty_intr_count_incr_r.pulse.load_next) begin + field_storage.intr_block_rf.notif_fifo_empty_intr_count_incr_r.pulse.value <= field_combo.intr_block_rf.notif_fifo_empty_intr_count_incr_r.pulse.next; + end + end + // Field: axi_dma_reg.intr_block_rf.notif_fifo_not_empty_intr_count_incr_r.pulse + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_fifo_not_empty_intr_count_incr_r.pulse.value; + load_next_c = '0; + if(field_storage.intr_block_rf.notif_intr_trig_r.notif_fifo_not_empty_trig.value) begin // HW Write - we + next_c = field_storage.intr_block_rf.notif_intr_trig_r.notif_fifo_not_empty_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.notif_internal_intr_r.notif_fifo_not_empty_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end + if(field_storage.intr_block_rf.notif_fifo_not_empty_intr_count_incr_r.pulse.value) begin // decrement + field_combo.intr_block_rf.notif_fifo_not_empty_intr_count_incr_r.pulse.underflow = (next_c < (1'h1)); + next_c = next_c - 1'h1; + load_next_c = '1; + end else begin + field_combo.intr_block_rf.notif_fifo_not_empty_intr_count_incr_r.pulse.underflow = '0; + end + field_combo.intr_block_rf.notif_fifo_not_empty_intr_count_incr_r.pulse.decrthreshold = (field_storage.intr_block_rf.notif_fifo_not_empty_intr_count_incr_r.pulse.value <= 1'd0); + field_combo.intr_block_rf.notif_fifo_not_empty_intr_count_incr_r.pulse.next = next_c; + field_combo.intr_block_rf.notif_fifo_not_empty_intr_count_incr_r.pulse.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.notif_fifo_not_empty_intr_count_incr_r.pulse.value <= 1'h0; + end else if(field_combo.intr_block_rf.notif_fifo_not_empty_intr_count_incr_r.pulse.load_next) begin + field_storage.intr_block_rf.notif_fifo_not_empty_intr_count_incr_r.pulse.value <= field_combo.intr_block_rf.notif_fifo_not_empty_intr_count_incr_r.pulse.next; + end + end + // Field: axi_dma_reg.intr_block_rf.notif_fifo_full_intr_count_incr_r.pulse + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_fifo_full_intr_count_incr_r.pulse.value; + load_next_c = '0; + if(field_storage.intr_block_rf.notif_intr_trig_r.notif_fifo_full_trig.value) begin // HW Write - we + next_c = field_storage.intr_block_rf.notif_intr_trig_r.notif_fifo_full_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.notif_internal_intr_r.notif_fifo_full_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end + if(field_storage.intr_block_rf.notif_fifo_full_intr_count_incr_r.pulse.value) begin // decrement + field_combo.intr_block_rf.notif_fifo_full_intr_count_incr_r.pulse.underflow = (next_c < (1'h1)); + next_c = next_c - 1'h1; + load_next_c = '1; + end else begin + field_combo.intr_block_rf.notif_fifo_full_intr_count_incr_r.pulse.underflow = '0; + end + field_combo.intr_block_rf.notif_fifo_full_intr_count_incr_r.pulse.decrthreshold = (field_storage.intr_block_rf.notif_fifo_full_intr_count_incr_r.pulse.value <= 1'd0); + field_combo.intr_block_rf.notif_fifo_full_intr_count_incr_r.pulse.next = next_c; + field_combo.intr_block_rf.notif_fifo_full_intr_count_incr_r.pulse.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.notif_fifo_full_intr_count_incr_r.pulse.value <= 1'h0; + end else if(field_combo.intr_block_rf.notif_fifo_full_intr_count_incr_r.pulse.load_next) begin + field_storage.intr_block_rf.notif_fifo_full_intr_count_incr_r.pulse.value <= field_combo.intr_block_rf.notif_fifo_full_intr_count_incr_r.pulse.next; + end + end + // Field: axi_dma_reg.intr_block_rf.notif_fifo_not_full_intr_count_incr_r.pulse + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_fifo_not_full_intr_count_incr_r.pulse.value; + load_next_c = '0; + if(field_storage.intr_block_rf.notif_intr_trig_r.notif_fifo_not_full_trig.value) begin // HW Write - we + next_c = field_storage.intr_block_rf.notif_intr_trig_r.notif_fifo_not_full_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.notif_internal_intr_r.notif_fifo_not_full_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end + if(field_storage.intr_block_rf.notif_fifo_not_full_intr_count_incr_r.pulse.value) begin // decrement + field_combo.intr_block_rf.notif_fifo_not_full_intr_count_incr_r.pulse.underflow = (next_c < (1'h1)); + next_c = next_c - 1'h1; + load_next_c = '1; + end else begin + field_combo.intr_block_rf.notif_fifo_not_full_intr_count_incr_r.pulse.underflow = '0; + end + field_combo.intr_block_rf.notif_fifo_not_full_intr_count_incr_r.pulse.decrthreshold = (field_storage.intr_block_rf.notif_fifo_not_full_intr_count_incr_r.pulse.value <= 1'd0); + field_combo.intr_block_rf.notif_fifo_not_full_intr_count_incr_r.pulse.next = next_c; + field_combo.intr_block_rf.notif_fifo_not_full_intr_count_incr_r.pulse.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.notif_fifo_not_full_intr_count_incr_r.pulse.value <= 1'h0; + end else if(field_combo.intr_block_rf.notif_fifo_not_full_intr_count_incr_r.pulse.load_next) begin + field_storage.intr_block_rf.notif_fifo_not_full_intr_count_incr_r.pulse.value <= field_combo.intr_block_rf.notif_fifo_not_full_intr_count_incr_r.pulse.next; + end + end + + //-------------------------------------------------------------------------- + // Write response + //-------------------------------------------------------------------------- + assign cpuif_wr_ack = decoded_req & decoded_req_is_wr; + // Writes are always granted with no error response + assign cpuif_wr_err = '0; + + //-------------------------------------------------------------------------- + // Readback + //-------------------------------------------------------------------------- + + logic readback_err; + logic readback_done; + logic [31:0] readback_data; + + // Assign readback values to a flattened array + logic [51-1:0][31:0] readback_array; + assign readback_array[0][31:0] = (decoded_reg_strb.id && !decoded_req_is_wr) ? 32'h67768068 : '0; + assign readback_array[1][11:0] = (decoded_reg_strb.cap && !decoded_req_is_wr) ? hwif_in.cap.fifo_max_depth.next : '0; + assign readback_array[1][31:12] = (decoded_reg_strb.cap && !decoded_req_is_wr) ? 20'h0 : '0; + assign readback_array[2][0:0] = (decoded_reg_strb.ctrl && !decoded_req_is_wr) ? field_storage.ctrl.go.value : '0; + assign readback_array[2][1:1] = (decoded_reg_strb.ctrl && !decoded_req_is_wr) ? field_storage.ctrl.flush.value : '0; + assign readback_array[2][2:2] = (decoded_reg_strb.ctrl && !decoded_req_is_wr) ? field_storage.ctrl.aes_mode_en.value : '0; + assign readback_array[2][3:3] = (decoded_reg_strb.ctrl && !decoded_req_is_wr) ? field_storage.ctrl.aes_gcm_mode.value : '0; + assign readback_array[2][15:4] = (decoded_reg_strb.ctrl && !decoded_req_is_wr) ? 12'h0 : '0; + assign readback_array[2][17:16] = (decoded_reg_strb.ctrl && !decoded_req_is_wr) ? field_storage.ctrl.rd_route.value : '0; + assign readback_array[2][19:18] = (decoded_reg_strb.ctrl && !decoded_req_is_wr) ? 2'h0 : '0; + assign readback_array[2][20:20] = (decoded_reg_strb.ctrl && !decoded_req_is_wr) ? field_storage.ctrl.rd_fixed.value : '0; + assign readback_array[2][23:21] = (decoded_reg_strb.ctrl && !decoded_req_is_wr) ? 3'h0 : '0; + assign readback_array[2][26:24] = (decoded_reg_strb.ctrl && !decoded_req_is_wr) ? field_storage.ctrl.wr_route.value : '0; + assign readback_array[2][27:27] = (decoded_reg_strb.ctrl && !decoded_req_is_wr) ? 1'h0 : '0; + assign readback_array[2][28:28] = (decoded_reg_strb.ctrl && !decoded_req_is_wr) ? field_storage.ctrl.wr_fixed.value : '0; + assign readback_array[2][31:29] = (decoded_reg_strb.ctrl && !decoded_req_is_wr) ? 3'h0 : '0; + assign readback_array[3][0:0] = (decoded_reg_strb.status0 && !decoded_req_is_wr) ? hwif_in.status0.busy.next : '0; + assign readback_array[3][1:1] = (decoded_reg_strb.status0 && !decoded_req_is_wr) ? hwif_in.status0.error.next : '0; + assign readback_array[3][3:2] = (decoded_reg_strb.status0 && !decoded_req_is_wr) ? 2'h0 : '0; + assign readback_array[3][15:4] = (decoded_reg_strb.status0 && !decoded_req_is_wr) ? hwif_in.status0.fifo_depth.next : '0; + assign readback_array[3][17:16] = (decoded_reg_strb.status0 && !decoded_req_is_wr) ? field_storage.status0.axi_dma_fsm_ps.value : '0; + assign readback_array[3][18:18] = (decoded_reg_strb.status0 && !decoded_req_is_wr) ? hwif_in.status0.payload_available.next : '0; + assign readback_array[3][19:19] = (decoded_reg_strb.status0 && !decoded_req_is_wr) ? hwif_in.status0.image_activated.next : '0; + assign readback_array[3][23:20] = (decoded_reg_strb.status0 && !decoded_req_is_wr) ? field_storage.status0.axi_dma_aes_fsm_ps.value : '0; + assign readback_array[3][31:24] = (decoded_reg_strb.status0 && !decoded_req_is_wr) ? 8'h0 : '0; + assign readback_array[4][31:0] = (decoded_reg_strb.status1 && !decoded_req_is_wr) ? hwif_in.status1.bytes_remaining.next : '0; + assign readback_array[5][31:0] = (decoded_reg_strb.src_addr_l && !decoded_req_is_wr) ? field_storage.src_addr_l.addr_l.value : '0; + assign readback_array[6][31:0] = (decoded_reg_strb.src_addr_h && !decoded_req_is_wr) ? field_storage.src_addr_h.addr_h.value : '0; + assign readback_array[7][31:0] = (decoded_reg_strb.dst_addr_l && !decoded_req_is_wr) ? field_storage.dst_addr_l.addr_l.value : '0; + assign readback_array[8][31:0] = (decoded_reg_strb.dst_addr_h && !decoded_req_is_wr) ? field_storage.dst_addr_h.addr_h.value : '0; + assign readback_array[9][31:0] = (decoded_reg_strb.byte_count && !decoded_req_is_wr) ? field_storage.byte_count.count.value : '0; + assign readback_array[10][11:0] = (decoded_reg_strb.block_size && !decoded_req_is_wr) ? field_storage.block_size.size.value : '0; + assign readback_array[10][31:12] = (decoded_reg_strb.block_size && !decoded_req_is_wr) ? 20'h0 : '0; + assign readback_array[11][31:0] = (decoded_reg_strb.read_data && !decoded_req_is_wr) ? hwif_in.read_data.rdata.next : '0; + assign readback_array[12][0:0] = (decoded_reg_strb.intr_block_rf.global_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.global_intr_en_r.error_en.value : '0; + assign readback_array[12][1:1] = (decoded_reg_strb.intr_block_rf.global_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.global_intr_en_r.notif_en.value : '0; + assign readback_array[12][31:2] = '0; + assign readback_array[13][0:0] = (decoded_reg_strb.intr_block_rf.error_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_en_r.error_cmd_dec_en.value : '0; + assign readback_array[13][1:1] = (decoded_reg_strb.intr_block_rf.error_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_en_r.error_axi_rd_en.value : '0; + assign readback_array[13][2:2] = (decoded_reg_strb.intr_block_rf.error_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_en_r.error_axi_wr_en.value : '0; + assign readback_array[13][3:3] = (decoded_reg_strb.intr_block_rf.error_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_en_r.error_mbox_lock_en.value : '0; + assign readback_array[13][4:4] = (decoded_reg_strb.intr_block_rf.error_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_en_r.error_sha_lock_en.value : '0; + assign readback_array[13][5:5] = (decoded_reg_strb.intr_block_rf.error_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_en_r.error_fifo_oflow_en.value : '0; + assign readback_array[13][6:6] = (decoded_reg_strb.intr_block_rf.error_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_en_r.error_fifo_uflow_en.value : '0; + assign readback_array[13][7:7] = (decoded_reg_strb.intr_block_rf.error_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_en_r.error_aes_cif_en.value : '0; + assign readback_array[13][8:8] = (decoded_reg_strb.intr_block_rf.error_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_en_r.error_kv_rd_en.value : '0; + assign readback_array[13][9:9] = (decoded_reg_strb.intr_block_rf.error_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_en_r.error_kv_rd_large_en.value : '0; + assign readback_array[13][31:10] = '0; + assign readback_array[14][0:0] = (decoded_reg_strb.intr_block_rf.notif_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_intr_en_r.notif_txn_done_en.value : '0; + assign readback_array[14][1:1] = (decoded_reg_strb.intr_block_rf.notif_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_intr_en_r.notif_fifo_empty_en.value : '0; + assign readback_array[14][2:2] = (decoded_reg_strb.intr_block_rf.notif_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_intr_en_r.notif_fifo_not_empty_en.value : '0; + assign readback_array[14][3:3] = (decoded_reg_strb.intr_block_rf.notif_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_intr_en_r.notif_fifo_full_en.value : '0; + assign readback_array[14][4:4] = (decoded_reg_strb.intr_block_rf.notif_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_intr_en_r.notif_fifo_not_full_en.value : '0; + assign readback_array[14][31:5] = '0; + assign readback_array[15][0:0] = (decoded_reg_strb.intr_block_rf.error_global_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_global_intr_r.agg_sts.value : '0; + assign readback_array[15][31:1] = '0; + assign readback_array[16][0:0] = (decoded_reg_strb.intr_block_rf.notif_global_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_global_intr_r.agg_sts.value : '0; + assign readback_array[16][31:1] = '0; + assign readback_array[17][0:0] = (decoded_reg_strb.intr_block_rf.error_internal_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_internal_intr_r.error_cmd_dec_sts.value : '0; + assign readback_array[17][1:1] = (decoded_reg_strb.intr_block_rf.error_internal_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_internal_intr_r.error_axi_rd_sts.value : '0; + assign readback_array[17][2:2] = (decoded_reg_strb.intr_block_rf.error_internal_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_internal_intr_r.error_axi_wr_sts.value : '0; + assign readback_array[17][3:3] = (decoded_reg_strb.intr_block_rf.error_internal_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_internal_intr_r.error_mbox_lock_sts.value : '0; + assign readback_array[17][4:4] = (decoded_reg_strb.intr_block_rf.error_internal_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_internal_intr_r.error_sha_lock_sts.value : '0; + assign readback_array[17][5:5] = (decoded_reg_strb.intr_block_rf.error_internal_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_internal_intr_r.error_fifo_oflow_sts.value : '0; + assign readback_array[17][6:6] = (decoded_reg_strb.intr_block_rf.error_internal_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_internal_intr_r.error_fifo_uflow_sts.value : '0; + assign readback_array[17][7:7] = (decoded_reg_strb.intr_block_rf.error_internal_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_internal_intr_r.error_aes_cif_sts.value : '0; + assign readback_array[17][8:8] = (decoded_reg_strb.intr_block_rf.error_internal_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_internal_intr_r.error_kv_rd_sts.value : '0; + assign readback_array[17][9:9] = (decoded_reg_strb.intr_block_rf.error_internal_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_internal_intr_r.error_kv_rd_large_sts.value : '0; + assign readback_array[17][31:10] = '0; + assign readback_array[18][0:0] = (decoded_reg_strb.intr_block_rf.notif_internal_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_internal_intr_r.notif_txn_done_sts.value : '0; + assign readback_array[18][1:1] = (decoded_reg_strb.intr_block_rf.notif_internal_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_internal_intr_r.notif_fifo_empty_sts.value : '0; + assign readback_array[18][2:2] = (decoded_reg_strb.intr_block_rf.notif_internal_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_internal_intr_r.notif_fifo_not_empty_sts.value : '0; + assign readback_array[18][3:3] = (decoded_reg_strb.intr_block_rf.notif_internal_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_internal_intr_r.notif_fifo_full_sts.value : '0; + assign readback_array[18][4:4] = (decoded_reg_strb.intr_block_rf.notif_internal_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_internal_intr_r.notif_fifo_not_full_sts.value : '0; + assign readback_array[18][31:5] = '0; + assign readback_array[19][0:0] = (decoded_reg_strb.intr_block_rf.error_intr_trig_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_trig_r.error_cmd_dec_trig.value : '0; + assign readback_array[19][1:1] = (decoded_reg_strb.intr_block_rf.error_intr_trig_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_trig_r.error_axi_rd_trig.value : '0; + assign readback_array[19][2:2] = (decoded_reg_strb.intr_block_rf.error_intr_trig_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_trig_r.error_axi_wr_trig.value : '0; + assign readback_array[19][3:3] = (decoded_reg_strb.intr_block_rf.error_intr_trig_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_trig_r.error_mbox_lock_trig.value : '0; + assign readback_array[19][4:4] = (decoded_reg_strb.intr_block_rf.error_intr_trig_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_trig_r.error_sha_lock_trig.value : '0; + assign readback_array[19][5:5] = (decoded_reg_strb.intr_block_rf.error_intr_trig_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_trig_r.error_fifo_oflow_trig.value : '0; + assign readback_array[19][6:6] = (decoded_reg_strb.intr_block_rf.error_intr_trig_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_trig_r.error_fifo_uflow_trig.value : '0; + assign readback_array[19][7:7] = (decoded_reg_strb.intr_block_rf.error_intr_trig_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_trig_r.error_aes_cif_trig.value : '0; + assign readback_array[19][8:8] = (decoded_reg_strb.intr_block_rf.error_intr_trig_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_trig_r.error_kv_rd_trig.value : '0; + assign readback_array[19][9:9] = (decoded_reg_strb.intr_block_rf.error_intr_trig_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_trig_r.error_kv_rd_large_trig.value : '0; + assign readback_array[19][31:10] = '0; + assign readback_array[20][0:0] = (decoded_reg_strb.intr_block_rf.notif_intr_trig_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_intr_trig_r.notif_txn_done_trig.value : '0; + assign readback_array[20][1:1] = (decoded_reg_strb.intr_block_rf.notif_intr_trig_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_intr_trig_r.notif_fifo_empty_trig.value : '0; + assign readback_array[20][2:2] = (decoded_reg_strb.intr_block_rf.notif_intr_trig_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_intr_trig_r.notif_fifo_not_empty_trig.value : '0; + assign readback_array[20][3:3] = (decoded_reg_strb.intr_block_rf.notif_intr_trig_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_intr_trig_r.notif_fifo_full_trig.value : '0; + assign readback_array[20][4:4] = (decoded_reg_strb.intr_block_rf.notif_intr_trig_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_intr_trig_r.notif_fifo_not_full_trig.value : '0; + assign readback_array[20][31:5] = '0; + assign readback_array[21][31:0] = (decoded_reg_strb.intr_block_rf.error_cmd_dec_intr_count_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_cmd_dec_intr_count_r.cnt.value : '0; + assign readback_array[22][31:0] = (decoded_reg_strb.intr_block_rf.error_axi_rd_intr_count_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_axi_rd_intr_count_r.cnt.value : '0; + assign readback_array[23][31:0] = (decoded_reg_strb.intr_block_rf.error_axi_wr_intr_count_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_axi_wr_intr_count_r.cnt.value : '0; + assign readback_array[24][31:0] = (decoded_reg_strb.intr_block_rf.error_mbox_lock_intr_count_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_mbox_lock_intr_count_r.cnt.value : '0; + assign readback_array[25][31:0] = (decoded_reg_strb.intr_block_rf.error_sha_lock_intr_count_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_sha_lock_intr_count_r.cnt.value : '0; + assign readback_array[26][31:0] = (decoded_reg_strb.intr_block_rf.error_fifo_oflow_intr_count_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_fifo_oflow_intr_count_r.cnt.value : '0; + assign readback_array[27][31:0] = (decoded_reg_strb.intr_block_rf.error_fifo_uflow_intr_count_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_fifo_uflow_intr_count_r.cnt.value : '0; + assign readback_array[28][31:0] = (decoded_reg_strb.intr_block_rf.error_aes_cif_intr_count_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_aes_cif_intr_count_r.cnt.value : '0; + assign readback_array[29][31:0] = (decoded_reg_strb.intr_block_rf.error_kv_rd_intr_count_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_kv_rd_intr_count_r.cnt.value : '0; + assign readback_array[30][31:0] = (decoded_reg_strb.intr_block_rf.error_kv_rd_large_intr_count_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_kv_rd_large_intr_count_r.cnt.value : '0; + assign readback_array[31][31:0] = (decoded_reg_strb.intr_block_rf.notif_txn_done_intr_count_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_txn_done_intr_count_r.cnt.value : '0; + assign readback_array[32][31:0] = (decoded_reg_strb.intr_block_rf.notif_fifo_empty_intr_count_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_fifo_empty_intr_count_r.cnt.value : '0; + assign readback_array[33][31:0] = (decoded_reg_strb.intr_block_rf.notif_fifo_not_empty_intr_count_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_fifo_not_empty_intr_count_r.cnt.value : '0; + assign readback_array[34][31:0] = (decoded_reg_strb.intr_block_rf.notif_fifo_full_intr_count_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_fifo_full_intr_count_r.cnt.value : '0; + assign readback_array[35][31:0] = (decoded_reg_strb.intr_block_rf.notif_fifo_not_full_intr_count_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_fifo_not_full_intr_count_r.cnt.value : '0; + assign readback_array[36][0:0] = (decoded_reg_strb.intr_block_rf.error_cmd_dec_intr_count_incr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_cmd_dec_intr_count_incr_r.pulse.value : '0; + assign readback_array[36][31:1] = '0; + assign readback_array[37][0:0] = (decoded_reg_strb.intr_block_rf.error_axi_rd_intr_count_incr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_axi_rd_intr_count_incr_r.pulse.value : '0; + assign readback_array[37][31:1] = '0; + assign readback_array[38][0:0] = (decoded_reg_strb.intr_block_rf.error_axi_wr_intr_count_incr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_axi_wr_intr_count_incr_r.pulse.value : '0; + assign readback_array[38][31:1] = '0; + assign readback_array[39][0:0] = (decoded_reg_strb.intr_block_rf.error_mbox_lock_intr_count_incr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_mbox_lock_intr_count_incr_r.pulse.value : '0; + assign readback_array[39][31:1] = '0; + assign readback_array[40][0:0] = (decoded_reg_strb.intr_block_rf.error_sha_lock_intr_count_incr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_sha_lock_intr_count_incr_r.pulse.value : '0; + assign readback_array[40][31:1] = '0; + assign readback_array[41][0:0] = (decoded_reg_strb.intr_block_rf.error_fifo_oflow_intr_count_incr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_fifo_oflow_intr_count_incr_r.pulse.value : '0; + assign readback_array[41][31:1] = '0; + assign readback_array[42][0:0] = (decoded_reg_strb.intr_block_rf.error_fifo_uflow_intr_count_incr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_fifo_uflow_intr_count_incr_r.pulse.value : '0; + assign readback_array[42][31:1] = '0; + assign readback_array[43][0:0] = (decoded_reg_strb.intr_block_rf.error_aes_cif_intr_count_incr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_aes_cif_intr_count_incr_r.pulse.value : '0; + assign readback_array[43][31:1] = '0; + assign readback_array[44][0:0] = (decoded_reg_strb.intr_block_rf.error_kv_rd_intr_count_incr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_kv_rd_intr_count_incr_r.pulse.value : '0; + assign readback_array[44][31:1] = '0; + assign readback_array[45][0:0] = (decoded_reg_strb.intr_block_rf.error_kv_rd_large_intr_count_incr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_kv_rd_large_intr_count_incr_r.pulse.value : '0; + assign readback_array[45][31:1] = '0; + assign readback_array[46][0:0] = (decoded_reg_strb.intr_block_rf.notif_txn_done_intr_count_incr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_txn_done_intr_count_incr_r.pulse.value : '0; + assign readback_array[46][31:1] = '0; + assign readback_array[47][0:0] = (decoded_reg_strb.intr_block_rf.notif_fifo_empty_intr_count_incr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_fifo_empty_intr_count_incr_r.pulse.value : '0; + assign readback_array[47][31:1] = '0; + assign readback_array[48][0:0] = (decoded_reg_strb.intr_block_rf.notif_fifo_not_empty_intr_count_incr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_fifo_not_empty_intr_count_incr_r.pulse.value : '0; + assign readback_array[48][31:1] = '0; + assign readback_array[49][0:0] = (decoded_reg_strb.intr_block_rf.notif_fifo_full_intr_count_incr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_fifo_full_intr_count_incr_r.pulse.value : '0; + assign readback_array[49][31:1] = '0; + assign readback_array[50][0:0] = (decoded_reg_strb.intr_block_rf.notif_fifo_not_full_intr_count_incr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_fifo_not_full_intr_count_incr_r.pulse.value : '0; + assign readback_array[50][31:1] = '0; + + // Reduce the array + always_comb begin + automatic logic [31:0] readback_data_var; + readback_done = decoded_req & ~decoded_req_is_wr; + readback_err = '0; + readback_data_var = '0; + for(int i=0; i<51; i++) readback_data_var |= readback_array[i]; + readback_data = readback_data_var; + end + + assign cpuif_rd_ack = readback_done; + assign cpuif_rd_data = readback_data; + assign cpuif_rd_err = readback_err; + +`CALIPTRA_ASSERT_KNOWN(ERR_HWIF_IN, hwif_in, clk, !hwif_in.cptra_pwrgood) + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/axi_dma_reg_pkg.sv b/designs/Caliptra/src/caliptra-rtl/axi_dma_reg_pkg.sv new file mode 100644 index 0000000..493ef5b --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/axi_dma_reg_pkg.sv @@ -0,0 +1,377 @@ +// Generated by PeakRDL-regblock - A free and open-source SystemVerilog generator +// https://github.com/SystemRDL/PeakRDL-regblock + +package axi_dma_reg_pkg; + + localparam AXI_DMA_REG_DATA_WIDTH = 32; + localparam AXI_DMA_REG_MIN_ADDR_WIDTH = 12; + + typedef struct packed{ + logic [11:0] next; + } axi_dma_reg__cap__fifo_max_depth__in_t; + + typedef struct packed{ + axi_dma_reg__cap__fifo_max_depth__in_t fifo_max_depth; + } axi_dma_reg__cap__in_t; + + typedef struct packed{ + logic hwclr; + } axi_dma_reg__ctrl__go__in_t; + + typedef struct packed{ + logic hwclr; + } axi_dma_reg__ctrl__flush__in_t; + + typedef struct packed{ + axi_dma_reg__ctrl__go__in_t go; + axi_dma_reg__ctrl__flush__in_t flush; + } axi_dma_reg__ctrl__in_t; + + typedef struct packed{ + logic next; + } axi_dma_reg__status0__busy__in_t; + + typedef struct packed{ + logic next; + } axi_dma_reg__status0__error__in_t; + + typedef struct packed{ + logic [11:0] next; + } axi_dma_reg__status0__fifo_depth__in_t; + + typedef struct packed{ + logic [1:0] next; + } axi_dma_reg__status0__axi_dma_fsm_ps__in_t; + + typedef struct packed{ + logic next; + } axi_dma_reg__status0__payload_available__in_t; + + typedef struct packed{ + logic next; + } axi_dma_reg__status0__image_activated__in_t; + + typedef struct packed{ + logic [3:0] next; + } axi_dma_reg__status0__axi_dma_aes_fsm_ps__in_t; + + typedef struct packed{ + axi_dma_reg__status0__busy__in_t busy; + axi_dma_reg__status0__error__in_t error; + axi_dma_reg__status0__fifo_depth__in_t fifo_depth; + axi_dma_reg__status0__axi_dma_fsm_ps__in_t axi_dma_fsm_ps; + axi_dma_reg__status0__payload_available__in_t payload_available; + axi_dma_reg__status0__image_activated__in_t image_activated; + axi_dma_reg__status0__axi_dma_aes_fsm_ps__in_t axi_dma_aes_fsm_ps; + } axi_dma_reg__status0__in_t; + + typedef struct packed{ + logic [31:0] next; + } axi_dma_reg__status1__bytes_remaining__in_t; + + typedef struct packed{ + axi_dma_reg__status1__bytes_remaining__in_t bytes_remaining; + } axi_dma_reg__status1__in_t; + + typedef struct packed{ + logic [31:0] next; + } axi_dma_reg__read_data__rdata__in_t; + + typedef struct packed{ + axi_dma_reg__read_data__rdata__in_t rdata; + } axi_dma_reg__read_data__in_t; + + typedef struct packed{ + logic hwset; + } axi_dma_reg__intr_block_t__error_intr_t_error_aes_cif_sts_63385a16_error_axi_rd_sts_927e49cd_error_axi_wr_sts_f84e5c07_error_cmd_dec_sts_46039d92_error_fifo_oflow_sts_71b29a77_error_fifo_uflow_sts_119d122a_error_kv_rd_large_sts_aa293a66_error_kv_rd_sts_df1ad5dd_error_mbox_lock_sts_9e18c395_error_sha_lock_sts_4c7993a0__error_cmd_dec_sts_enable_3fe3f38e_next_81a41b0f_resetsignal_f7aac87a__in_t; + + typedef struct packed{ + logic hwset; + } axi_dma_reg__intr_block_t__error_intr_t_error_aes_cif_sts_63385a16_error_axi_rd_sts_927e49cd_error_axi_wr_sts_f84e5c07_error_cmd_dec_sts_46039d92_error_fifo_oflow_sts_71b29a77_error_fifo_uflow_sts_119d122a_error_kv_rd_large_sts_aa293a66_error_kv_rd_sts_df1ad5dd_error_mbox_lock_sts_9e18c395_error_sha_lock_sts_4c7993a0__error_axi_rd_sts_enable_ade70b75_next_9749130e_resetsignal_f7aac87a__in_t; + + typedef struct packed{ + logic hwset; + } axi_dma_reg__intr_block_t__error_intr_t_error_aes_cif_sts_63385a16_error_axi_rd_sts_927e49cd_error_axi_wr_sts_f84e5c07_error_cmd_dec_sts_46039d92_error_fifo_oflow_sts_71b29a77_error_fifo_uflow_sts_119d122a_error_kv_rd_large_sts_aa293a66_error_kv_rd_sts_df1ad5dd_error_mbox_lock_sts_9e18c395_error_sha_lock_sts_4c7993a0__error_axi_wr_sts_enable_8302157e_next_d030e286_resetsignal_f7aac87a__in_t; + + typedef struct packed{ + logic hwset; + } axi_dma_reg__intr_block_t__error_intr_t_error_aes_cif_sts_63385a16_error_axi_rd_sts_927e49cd_error_axi_wr_sts_f84e5c07_error_cmd_dec_sts_46039d92_error_fifo_oflow_sts_71b29a77_error_fifo_uflow_sts_119d122a_error_kv_rd_large_sts_aa293a66_error_kv_rd_sts_df1ad5dd_error_mbox_lock_sts_9e18c395_error_sha_lock_sts_4c7993a0__error_mbox_lock_sts_enable_2200d685_next_dd20251c_resetsignal_f7aac87a__in_t; + + typedef struct packed{ + logic hwset; + } axi_dma_reg__intr_block_t__error_intr_t_error_aes_cif_sts_63385a16_error_axi_rd_sts_927e49cd_error_axi_wr_sts_f84e5c07_error_cmd_dec_sts_46039d92_error_fifo_oflow_sts_71b29a77_error_fifo_uflow_sts_119d122a_error_kv_rd_large_sts_aa293a66_error_kv_rd_sts_df1ad5dd_error_mbox_lock_sts_9e18c395_error_sha_lock_sts_4c7993a0__error_sha_lock_sts_enable_b89b863e_next_78f72dee_resetsignal_f7aac87a__in_t; + + typedef struct packed{ + logic hwset; + } axi_dma_reg__intr_block_t__error_intr_t_error_aes_cif_sts_63385a16_error_axi_rd_sts_927e49cd_error_axi_wr_sts_f84e5c07_error_cmd_dec_sts_46039d92_error_fifo_oflow_sts_71b29a77_error_fifo_uflow_sts_119d122a_error_kv_rd_large_sts_aa293a66_error_kv_rd_sts_df1ad5dd_error_mbox_lock_sts_9e18c395_error_sha_lock_sts_4c7993a0__error_fifo_oflow_sts_enable_db42b065_next_8d43e112_resetsignal_f7aac87a__in_t; + + typedef struct packed{ + logic hwset; + } axi_dma_reg__intr_block_t__error_intr_t_error_aes_cif_sts_63385a16_error_axi_rd_sts_927e49cd_error_axi_wr_sts_f84e5c07_error_cmd_dec_sts_46039d92_error_fifo_oflow_sts_71b29a77_error_fifo_uflow_sts_119d122a_error_kv_rd_large_sts_aa293a66_error_kv_rd_sts_df1ad5dd_error_mbox_lock_sts_9e18c395_error_sha_lock_sts_4c7993a0__error_fifo_uflow_sts_enable_fec90e1d_next_a25205a2_resetsignal_f7aac87a__in_t; + + typedef struct packed{ + logic hwset; + } axi_dma_reg__intr_block_t__error_intr_t_error_aes_cif_sts_63385a16_error_axi_rd_sts_927e49cd_error_axi_wr_sts_f84e5c07_error_cmd_dec_sts_46039d92_error_fifo_oflow_sts_71b29a77_error_fifo_uflow_sts_119d122a_error_kv_rd_large_sts_aa293a66_error_kv_rd_sts_df1ad5dd_error_mbox_lock_sts_9e18c395_error_sha_lock_sts_4c7993a0__error_aes_cif_sts_enable_427cc14a_next_cae765d7_resetsignal_f7aac87a__in_t; + + typedef struct packed{ + logic hwset; + } axi_dma_reg__intr_block_t__error_intr_t_error_aes_cif_sts_63385a16_error_axi_rd_sts_927e49cd_error_axi_wr_sts_f84e5c07_error_cmd_dec_sts_46039d92_error_fifo_oflow_sts_71b29a77_error_fifo_uflow_sts_119d122a_error_kv_rd_large_sts_aa293a66_error_kv_rd_sts_df1ad5dd_error_mbox_lock_sts_9e18c395_error_sha_lock_sts_4c7993a0__error_kv_rd_sts_enable_39217125_next_7a08f3e8_resetsignal_f7aac87a__in_t; + + typedef struct packed{ + logic hwset; + } axi_dma_reg__intr_block_t__error_intr_t_error_aes_cif_sts_63385a16_error_axi_rd_sts_927e49cd_error_axi_wr_sts_f84e5c07_error_cmd_dec_sts_46039d92_error_fifo_oflow_sts_71b29a77_error_fifo_uflow_sts_119d122a_error_kv_rd_large_sts_aa293a66_error_kv_rd_sts_df1ad5dd_error_mbox_lock_sts_9e18c395_error_sha_lock_sts_4c7993a0__error_kv_rd_large_sts_enable_e36bb929_next_5552524f_resetsignal_f7aac87a__in_t; + + typedef struct packed{ + axi_dma_reg__intr_block_t__error_intr_t_error_aes_cif_sts_63385a16_error_axi_rd_sts_927e49cd_error_axi_wr_sts_f84e5c07_error_cmd_dec_sts_46039d92_error_fifo_oflow_sts_71b29a77_error_fifo_uflow_sts_119d122a_error_kv_rd_large_sts_aa293a66_error_kv_rd_sts_df1ad5dd_error_mbox_lock_sts_9e18c395_error_sha_lock_sts_4c7993a0__error_cmd_dec_sts_enable_3fe3f38e_next_81a41b0f_resetsignal_f7aac87a__in_t error_cmd_dec_sts; + axi_dma_reg__intr_block_t__error_intr_t_error_aes_cif_sts_63385a16_error_axi_rd_sts_927e49cd_error_axi_wr_sts_f84e5c07_error_cmd_dec_sts_46039d92_error_fifo_oflow_sts_71b29a77_error_fifo_uflow_sts_119d122a_error_kv_rd_large_sts_aa293a66_error_kv_rd_sts_df1ad5dd_error_mbox_lock_sts_9e18c395_error_sha_lock_sts_4c7993a0__error_axi_rd_sts_enable_ade70b75_next_9749130e_resetsignal_f7aac87a__in_t error_axi_rd_sts; + axi_dma_reg__intr_block_t__error_intr_t_error_aes_cif_sts_63385a16_error_axi_rd_sts_927e49cd_error_axi_wr_sts_f84e5c07_error_cmd_dec_sts_46039d92_error_fifo_oflow_sts_71b29a77_error_fifo_uflow_sts_119d122a_error_kv_rd_large_sts_aa293a66_error_kv_rd_sts_df1ad5dd_error_mbox_lock_sts_9e18c395_error_sha_lock_sts_4c7993a0__error_axi_wr_sts_enable_8302157e_next_d030e286_resetsignal_f7aac87a__in_t error_axi_wr_sts; + axi_dma_reg__intr_block_t__error_intr_t_error_aes_cif_sts_63385a16_error_axi_rd_sts_927e49cd_error_axi_wr_sts_f84e5c07_error_cmd_dec_sts_46039d92_error_fifo_oflow_sts_71b29a77_error_fifo_uflow_sts_119d122a_error_kv_rd_large_sts_aa293a66_error_kv_rd_sts_df1ad5dd_error_mbox_lock_sts_9e18c395_error_sha_lock_sts_4c7993a0__error_mbox_lock_sts_enable_2200d685_next_dd20251c_resetsignal_f7aac87a__in_t error_mbox_lock_sts; + axi_dma_reg__intr_block_t__error_intr_t_error_aes_cif_sts_63385a16_error_axi_rd_sts_927e49cd_error_axi_wr_sts_f84e5c07_error_cmd_dec_sts_46039d92_error_fifo_oflow_sts_71b29a77_error_fifo_uflow_sts_119d122a_error_kv_rd_large_sts_aa293a66_error_kv_rd_sts_df1ad5dd_error_mbox_lock_sts_9e18c395_error_sha_lock_sts_4c7993a0__error_sha_lock_sts_enable_b89b863e_next_78f72dee_resetsignal_f7aac87a__in_t error_sha_lock_sts; + axi_dma_reg__intr_block_t__error_intr_t_error_aes_cif_sts_63385a16_error_axi_rd_sts_927e49cd_error_axi_wr_sts_f84e5c07_error_cmd_dec_sts_46039d92_error_fifo_oflow_sts_71b29a77_error_fifo_uflow_sts_119d122a_error_kv_rd_large_sts_aa293a66_error_kv_rd_sts_df1ad5dd_error_mbox_lock_sts_9e18c395_error_sha_lock_sts_4c7993a0__error_fifo_oflow_sts_enable_db42b065_next_8d43e112_resetsignal_f7aac87a__in_t error_fifo_oflow_sts; + axi_dma_reg__intr_block_t__error_intr_t_error_aes_cif_sts_63385a16_error_axi_rd_sts_927e49cd_error_axi_wr_sts_f84e5c07_error_cmd_dec_sts_46039d92_error_fifo_oflow_sts_71b29a77_error_fifo_uflow_sts_119d122a_error_kv_rd_large_sts_aa293a66_error_kv_rd_sts_df1ad5dd_error_mbox_lock_sts_9e18c395_error_sha_lock_sts_4c7993a0__error_fifo_uflow_sts_enable_fec90e1d_next_a25205a2_resetsignal_f7aac87a__in_t error_fifo_uflow_sts; + axi_dma_reg__intr_block_t__error_intr_t_error_aes_cif_sts_63385a16_error_axi_rd_sts_927e49cd_error_axi_wr_sts_f84e5c07_error_cmd_dec_sts_46039d92_error_fifo_oflow_sts_71b29a77_error_fifo_uflow_sts_119d122a_error_kv_rd_large_sts_aa293a66_error_kv_rd_sts_df1ad5dd_error_mbox_lock_sts_9e18c395_error_sha_lock_sts_4c7993a0__error_aes_cif_sts_enable_427cc14a_next_cae765d7_resetsignal_f7aac87a__in_t error_aes_cif_sts; + axi_dma_reg__intr_block_t__error_intr_t_error_aes_cif_sts_63385a16_error_axi_rd_sts_927e49cd_error_axi_wr_sts_f84e5c07_error_cmd_dec_sts_46039d92_error_fifo_oflow_sts_71b29a77_error_fifo_uflow_sts_119d122a_error_kv_rd_large_sts_aa293a66_error_kv_rd_sts_df1ad5dd_error_mbox_lock_sts_9e18c395_error_sha_lock_sts_4c7993a0__error_kv_rd_sts_enable_39217125_next_7a08f3e8_resetsignal_f7aac87a__in_t error_kv_rd_sts; + axi_dma_reg__intr_block_t__error_intr_t_error_aes_cif_sts_63385a16_error_axi_rd_sts_927e49cd_error_axi_wr_sts_f84e5c07_error_cmd_dec_sts_46039d92_error_fifo_oflow_sts_71b29a77_error_fifo_uflow_sts_119d122a_error_kv_rd_large_sts_aa293a66_error_kv_rd_sts_df1ad5dd_error_mbox_lock_sts_9e18c395_error_sha_lock_sts_4c7993a0__error_kv_rd_large_sts_enable_e36bb929_next_5552524f_resetsignal_f7aac87a__in_t error_kv_rd_large_sts; + } axi_dma_reg__intr_block_t__error_intr_t_error_aes_cif_sts_63385a16_error_axi_rd_sts_927e49cd_error_axi_wr_sts_f84e5c07_error_cmd_dec_sts_46039d92_error_fifo_oflow_sts_71b29a77_error_fifo_uflow_sts_119d122a_error_kv_rd_large_sts_aa293a66_error_kv_rd_sts_df1ad5dd_error_mbox_lock_sts_9e18c395_error_sha_lock_sts_4c7993a0__in_t; + + typedef struct packed{ + logic hwset; + } axi_dma_reg__intr_block_t__notif_intr_t_notif_fifo_empty_sts_d87d1786_notif_fifo_full_sts_64c66862_notif_fifo_not_empty_sts_1a0e2460_notif_fifo_not_full_sts_0266fe07_notif_txn_done_sts_0ee2f120__notif_txn_done_sts_enable_f3ace5c8_next_c04384c4__in_t; + + typedef struct packed{ + logic hwset; + } axi_dma_reg__intr_block_t__notif_intr_t_notif_fifo_empty_sts_d87d1786_notif_fifo_full_sts_64c66862_notif_fifo_not_empty_sts_1a0e2460_notif_fifo_not_full_sts_0266fe07_notif_txn_done_sts_0ee2f120__notif_fifo_empty_sts_enable_13fbeac1_next_3b1b70cb__in_t; + + typedef struct packed{ + logic hwset; + } axi_dma_reg__intr_block_t__notif_intr_t_notif_fifo_empty_sts_d87d1786_notif_fifo_full_sts_64c66862_notif_fifo_not_empty_sts_1a0e2460_notif_fifo_not_full_sts_0266fe07_notif_txn_done_sts_0ee2f120__notif_fifo_not_empty_sts_enable_fc6f2a07_next_53ecda05__in_t; + + typedef struct packed{ + logic hwset; + } axi_dma_reg__intr_block_t__notif_intr_t_notif_fifo_empty_sts_d87d1786_notif_fifo_full_sts_64c66862_notif_fifo_not_empty_sts_1a0e2460_notif_fifo_not_full_sts_0266fe07_notif_txn_done_sts_0ee2f120__notif_fifo_full_sts_enable_d59af270_next_5df4004b__in_t; + + typedef struct packed{ + logic hwset; + } axi_dma_reg__intr_block_t__notif_intr_t_notif_fifo_empty_sts_d87d1786_notif_fifo_full_sts_64c66862_notif_fifo_not_empty_sts_1a0e2460_notif_fifo_not_full_sts_0266fe07_notif_txn_done_sts_0ee2f120__notif_fifo_not_full_sts_enable_9ba0ed48_next_ed3f253d__in_t; + + typedef struct packed{ + axi_dma_reg__intr_block_t__notif_intr_t_notif_fifo_empty_sts_d87d1786_notif_fifo_full_sts_64c66862_notif_fifo_not_empty_sts_1a0e2460_notif_fifo_not_full_sts_0266fe07_notif_txn_done_sts_0ee2f120__notif_txn_done_sts_enable_f3ace5c8_next_c04384c4__in_t notif_txn_done_sts; + axi_dma_reg__intr_block_t__notif_intr_t_notif_fifo_empty_sts_d87d1786_notif_fifo_full_sts_64c66862_notif_fifo_not_empty_sts_1a0e2460_notif_fifo_not_full_sts_0266fe07_notif_txn_done_sts_0ee2f120__notif_fifo_empty_sts_enable_13fbeac1_next_3b1b70cb__in_t notif_fifo_empty_sts; + axi_dma_reg__intr_block_t__notif_intr_t_notif_fifo_empty_sts_d87d1786_notif_fifo_full_sts_64c66862_notif_fifo_not_empty_sts_1a0e2460_notif_fifo_not_full_sts_0266fe07_notif_txn_done_sts_0ee2f120__notif_fifo_not_empty_sts_enable_fc6f2a07_next_53ecda05__in_t notif_fifo_not_empty_sts; + axi_dma_reg__intr_block_t__notif_intr_t_notif_fifo_empty_sts_d87d1786_notif_fifo_full_sts_64c66862_notif_fifo_not_empty_sts_1a0e2460_notif_fifo_not_full_sts_0266fe07_notif_txn_done_sts_0ee2f120__notif_fifo_full_sts_enable_d59af270_next_5df4004b__in_t notif_fifo_full_sts; + axi_dma_reg__intr_block_t__notif_intr_t_notif_fifo_empty_sts_d87d1786_notif_fifo_full_sts_64c66862_notif_fifo_not_empty_sts_1a0e2460_notif_fifo_not_full_sts_0266fe07_notif_txn_done_sts_0ee2f120__notif_fifo_not_full_sts_enable_9ba0ed48_next_ed3f253d__in_t notif_fifo_not_full_sts; + } axi_dma_reg__intr_block_t__notif_intr_t_notif_fifo_empty_sts_d87d1786_notif_fifo_full_sts_64c66862_notif_fifo_not_empty_sts_1a0e2460_notif_fifo_not_full_sts_0266fe07_notif_txn_done_sts_0ee2f120__in_t; + + typedef struct packed{ + axi_dma_reg__intr_block_t__error_intr_t_error_aes_cif_sts_63385a16_error_axi_rd_sts_927e49cd_error_axi_wr_sts_f84e5c07_error_cmd_dec_sts_46039d92_error_fifo_oflow_sts_71b29a77_error_fifo_uflow_sts_119d122a_error_kv_rd_large_sts_aa293a66_error_kv_rd_sts_df1ad5dd_error_mbox_lock_sts_9e18c395_error_sha_lock_sts_4c7993a0__in_t error_internal_intr_r; + axi_dma_reg__intr_block_t__notif_intr_t_notif_fifo_empty_sts_d87d1786_notif_fifo_full_sts_64c66862_notif_fifo_not_empty_sts_1a0e2460_notif_fifo_not_full_sts_0266fe07_notif_txn_done_sts_0ee2f120__in_t notif_internal_intr_r; + } axi_dma_reg__intr_block_t__in_t; + + typedef struct packed{ + logic cptra_rst_b; + logic cptra_pwrgood; + logic soc_req; + logic dma_swwel; + axi_dma_reg__cap__in_t cap; + axi_dma_reg__ctrl__in_t ctrl; + axi_dma_reg__status0__in_t status0; + axi_dma_reg__status1__in_t status1; + axi_dma_reg__read_data__in_t read_data; + axi_dma_reg__intr_block_t__in_t intr_block_rf; + } axi_dma_reg__in_t; + + typedef struct packed{ + logic value; + logic swmod; + } axi_dma_reg__ctrl__go__out_t; + + typedef struct packed{ + logic value; + } axi_dma_reg__ctrl__flush__out_t; + + typedef struct packed{ + logic value; + } axi_dma_reg__ctrl__aes_mode_en__out_t; + + typedef struct packed{ + logic value; + } axi_dma_reg__ctrl__aes_gcm_mode__out_t; + + typedef struct packed{ + logic [1:0] value; + } axi_dma_reg__ctrl__rd_route__out_t; + + typedef struct packed{ + logic value; + } axi_dma_reg__ctrl__rd_fixed__out_t; + + typedef struct packed{ + logic [2:0] value; + } axi_dma_reg__ctrl__wr_route__out_t; + + typedef struct packed{ + logic value; + } axi_dma_reg__ctrl__wr_fixed__out_t; + + typedef struct packed{ + axi_dma_reg__ctrl__go__out_t go; + axi_dma_reg__ctrl__flush__out_t flush; + axi_dma_reg__ctrl__aes_mode_en__out_t aes_mode_en; + axi_dma_reg__ctrl__aes_gcm_mode__out_t aes_gcm_mode; + axi_dma_reg__ctrl__rd_route__out_t rd_route; + axi_dma_reg__ctrl__rd_fixed__out_t rd_fixed; + axi_dma_reg__ctrl__wr_route__out_t wr_route; + axi_dma_reg__ctrl__wr_fixed__out_t wr_fixed; + } axi_dma_reg__ctrl__out_t; + + typedef struct packed{ + logic [1:0] value; + } axi_dma_reg__status0__axi_dma_fsm_ps__out_t; + + typedef struct packed{ + logic [3:0] value; + } axi_dma_reg__status0__axi_dma_aes_fsm_ps__out_t; + + typedef struct packed{ + axi_dma_reg__status0__axi_dma_fsm_ps__out_t axi_dma_fsm_ps; + axi_dma_reg__status0__axi_dma_aes_fsm_ps__out_t axi_dma_aes_fsm_ps; + } axi_dma_reg__status0__out_t; + + typedef struct packed{ + logic [31:0] value; + } axi_dma_reg__src_addr_l__addr_l__out_t; + + typedef struct packed{ + axi_dma_reg__src_addr_l__addr_l__out_t addr_l; + } axi_dma_reg__src_addr_l__out_t; + + typedef struct packed{ + logic [31:0] value; + } axi_dma_reg__src_addr_h__addr_h__out_t; + + typedef struct packed{ + axi_dma_reg__src_addr_h__addr_h__out_t addr_h; + } axi_dma_reg__src_addr_h__out_t; + + typedef struct packed{ + logic [31:0] value; + } axi_dma_reg__dst_addr_l__addr_l__out_t; + + typedef struct packed{ + axi_dma_reg__dst_addr_l__addr_l__out_t addr_l; + } axi_dma_reg__dst_addr_l__out_t; + + typedef struct packed{ + logic [31:0] value; + } axi_dma_reg__dst_addr_h__addr_h__out_t; + + typedef struct packed{ + axi_dma_reg__dst_addr_h__addr_h__out_t addr_h; + } axi_dma_reg__dst_addr_h__out_t; + + typedef struct packed{ + logic [31:0] value; + } axi_dma_reg__byte_count__count__out_t; + + typedef struct packed{ + axi_dma_reg__byte_count__count__out_t count; + } axi_dma_reg__byte_count__out_t; + + typedef struct packed{ + logic [11:0] value; + } axi_dma_reg__block_size__size__out_t; + + typedef struct packed{ + axi_dma_reg__block_size__size__out_t size; + } axi_dma_reg__block_size__out_t; + + typedef struct packed{ + logic swmod; + } axi_dma_reg__write_data__wdata__out_t; + + typedef struct packed{ + axi_dma_reg__write_data__wdata__out_t wdata; + } axi_dma_reg__write_data__out_t; + + typedef struct packed{ + logic swacc; + } axi_dma_reg__read_data__rdata__out_t; + + typedef struct packed{ + axi_dma_reg__read_data__rdata__out_t rdata; + } axi_dma_reg__read_data__out_t; + + typedef struct packed{ + logic intr; + } axi_dma_reg__intr_block_t__global_intr_t_agg_sts_dd3dcf0a__out_t; + + typedef struct packed{ + logic intr; + } axi_dma_reg__intr_block_t__global_intr_t_agg_sts_e6399b4a__out_t; + + typedef struct packed{ + logic intr; + } axi_dma_reg__intr_block_t__error_intr_t_error_aes_cif_sts_63385a16_error_axi_rd_sts_927e49cd_error_axi_wr_sts_f84e5c07_error_cmd_dec_sts_46039d92_error_fifo_oflow_sts_71b29a77_error_fifo_uflow_sts_119d122a_error_kv_rd_large_sts_aa293a66_error_kv_rd_sts_df1ad5dd_error_mbox_lock_sts_9e18c395_error_sha_lock_sts_4c7993a0__out_t; + + typedef struct packed{ + logic intr; + } axi_dma_reg__intr_block_t__notif_intr_t_notif_fifo_empty_sts_d87d1786_notif_fifo_full_sts_64c66862_notif_fifo_not_empty_sts_1a0e2460_notif_fifo_not_full_sts_0266fe07_notif_txn_done_sts_0ee2f120__out_t; + + typedef struct packed{ + axi_dma_reg__intr_block_t__global_intr_t_agg_sts_dd3dcf0a__out_t error_global_intr_r; + axi_dma_reg__intr_block_t__global_intr_t_agg_sts_e6399b4a__out_t notif_global_intr_r; + axi_dma_reg__intr_block_t__error_intr_t_error_aes_cif_sts_63385a16_error_axi_rd_sts_927e49cd_error_axi_wr_sts_f84e5c07_error_cmd_dec_sts_46039d92_error_fifo_oflow_sts_71b29a77_error_fifo_uflow_sts_119d122a_error_kv_rd_large_sts_aa293a66_error_kv_rd_sts_df1ad5dd_error_mbox_lock_sts_9e18c395_error_sha_lock_sts_4c7993a0__out_t error_internal_intr_r; + axi_dma_reg__intr_block_t__notif_intr_t_notif_fifo_empty_sts_d87d1786_notif_fifo_full_sts_64c66862_notif_fifo_not_empty_sts_1a0e2460_notif_fifo_not_full_sts_0266fe07_notif_txn_done_sts_0ee2f120__out_t notif_internal_intr_r; + } axi_dma_reg__intr_block_t__out_t; + + typedef struct packed{ + axi_dma_reg__ctrl__out_t ctrl; + axi_dma_reg__status0__out_t status0; + axi_dma_reg__src_addr_l__out_t src_addr_l; + axi_dma_reg__src_addr_h__out_t src_addr_h; + axi_dma_reg__dst_addr_l__out_t dst_addr_l; + axi_dma_reg__dst_addr_h__out_t dst_addr_h; + axi_dma_reg__byte_count__out_t byte_count; + axi_dma_reg__block_size__out_t block_size; + axi_dma_reg__write_data__out_t write_data; + axi_dma_reg__read_data__out_t read_data; + axi_dma_reg__intr_block_t__out_t intr_block_rf; + } axi_dma_reg__out_t; + + typedef enum logic [31:0] { + axi_dma_reg__ctrl__rd_route__rd_route_e__DISABLE = 'h0, + axi_dma_reg__ctrl__rd_route__rd_route_e__MBOX = 'h1, + axi_dma_reg__ctrl__rd_route__rd_route_e__AHB_FIFO = 'h2, + axi_dma_reg__ctrl__rd_route__rd_route_e__AXI_WR = 'h3 + } axi_dma_reg__ctrl__rd_route__rd_route_e_e; + + typedef enum logic [31:0] { + axi_dma_reg__ctrl__wr_route__wr_route_e__DISABLE = 'h0, + axi_dma_reg__ctrl__wr_route__wr_route_e__MBOX = 'h1, + axi_dma_reg__ctrl__wr_route__wr_route_e__AHB_FIFO = 'h2, + axi_dma_reg__ctrl__wr_route__wr_route_e__AXI_RD = 'h3, + axi_dma_reg__ctrl__wr_route__wr_route_e__KEYVAULT = 'h4 + } axi_dma_reg__ctrl__wr_route__wr_route_e_e; + + typedef enum logic [31:0] { + axi_dma_reg__status0__axi_dma_fsm_ps__axi_dma_fsm_e__DMA_IDLE = 'h0, + axi_dma_reg__status0__axi_dma_fsm_ps__axi_dma_fsm_e__DMA_WAIT_DATA = 'h1, + axi_dma_reg__status0__axi_dma_fsm_ps__axi_dma_fsm_e__DMA_DONE = 'h2, + axi_dma_reg__status0__axi_dma_fsm_ps__axi_dma_fsm_e__DMA_ERROR = 'h3 + } axi_dma_reg__status0__axi_dma_fsm_ps__axi_dma_fsm_e_e; + + typedef enum logic [31:0] { + axi_dma_reg__status0__axi_dma_aes_fsm_ps__axi_dma_aes_fsm_e__AES_IDLE = 'h0, + axi_dma_reg__status0__axi_dma_aes_fsm_ps__axi_dma_aes_fsm_e__AES_WAIT_INPUT_READY = 'h1, + axi_dma_reg__status0__axi_dma_aes_fsm_ps__axi_dma_aes_fsm_e__AES_WAIT_IDLE = 'h2, + axi_dma_reg__status0__axi_dma_aes_fsm_ps__axi_dma_aes_fsm_e__AES_UPDATE_BYTE_COUNT = 'h3, + axi_dma_reg__status0__axi_dma_aes_fsm_ps__axi_dma_aes_fsm_e__AES_WRITE_BLOCK = 'h4, + axi_dma_reg__status0__axi_dma_aes_fsm_ps__axi_dma_aes_fsm_e__AES_WAIT_OUTPUT_VALID = 'h5, + axi_dma_reg__status0__axi_dma_aes_fsm_ps__axi_dma_aes_fsm_e__AES_READ_OUTPUT = 'h6, + axi_dma_reg__status0__axi_dma_aes_fsm_ps__axi_dma_aes_fsm_e__AES_DONE = 'h7, + axi_dma_reg__status0__axi_dma_aes_fsm_ps__axi_dma_aes_fsm_e__AES_ERROR = 'h8 + } axi_dma_reg__status0__axi_dma_aes_fsm_ps__axi_dma_aes_fsm_e_e; + + localparam AXI_DMA_REG_ADDR_WIDTH = 32'd12; + +endpackage \ No newline at end of file diff --git a/designs/Caliptra/src/caliptra-rtl/axi_dma_req_if.sv b/designs/Caliptra/src/caliptra-rtl/axi_dma_req_if.sv new file mode 100644 index 0000000..66f54fa --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/axi_dma_req_if.sv @@ -0,0 +1,57 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +// +// Description: +// Signals for internal transaction requests inside the Caliptra DMA +// hardware assist block +// Does not include any datapath signals (data, strb, wuser, ruser) +// as these flow separately through the FIFO. +// + +interface axi_dma_req_if #(parameter AW = 32) (input logic clk, input logic rst_n); + + import axi_pkg::*; + + logic valid; + logic ready; + logic [AW-1:0] addr; + logic [AXI_LEN_BC_WIDTH-1:0] byte_len; // Byte count, max value per AXI spec + logic fixed; + logic lock; + logic resp_valid; + logic [$bits(axi_resp_e)-1:0] resp; + + modport src ( + output valid, + input ready, + output addr, + output byte_len, + output fixed, + output lock, + input resp_valid, + input resp + ); + + modport snk ( + input valid, + output ready, + input addr, + input byte_len, + input fixed, + input lock, + output resp_valid, + output resp + ); + +endinterface diff --git a/designs/Caliptra/src/caliptra-rtl/axi_dma_top.sv b/designs/Caliptra/src/caliptra-rtl/axi_dma_top.sv new file mode 100644 index 0000000..46c9430 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/axi_dma_top.sv @@ -0,0 +1,244 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +// +// Description: +// Top wrapper on AXI4 Manager (DMA) block +// + +module axi_dma_top +import axi_pkg::*; +import soc_ifc_pkg::*; +import kv_defines_pkg::*; +#( + parameter AW = 64, + parameter DW = 32, // Data Width + BC = DW/8, // Byte Count + BW = $clog2(BC), // Byte count Width + parameter UW = 32, // User Width + parameter IW = 1, // ID Width + ID_NUM = 1 << IW // Don't override +)( + input logic clk, + input logic cptra_pwrgood, + input logic rst_n, + + // Recovery INF Interrupt + // Should only assert when a full block_size of data is available at the + // recovery interface FIFO + input logic recovery_data_avail, + input logic recovery_image_activated, + + // SOC_IFC Internal Signaling + input logic mbox_lock, + input logic sha_lock, + input logic debugUnlock_or_scan_mode_switch, + input logic ocp_lock_in_progress, + input logic [63:0] key_release_addr, + input logic [15:0] key_release_size, + + // AES Interface + input logic aes_input_ready, + input logic aes_output_valid, + input logic aes_status_idle, + output logic aes_req_dv, + input logic aes_req_hold, + output soc_ifc_req_t aes_req_data, + input logic [DW-1:0] aes_rdata, + input logic aes_err, + + // kv interface + output kv_read_t kv_read, + input kv_rd_resp_t kv_rd_resp, + + // Configuration for requests + input logic [UW-1:0] axuser, + + // AXI INF + axi_if.w_mgr m_axi_w_if, + axi_if.r_mgr m_axi_r_if, + + // Component INF + input logic dv, + input var soc_ifc_req_t req_data, + output logic hold, + output logic [SOC_IFC_DATA_W-1:0] rdata, + output logic error, + + // Mailbox SRAM INF + output logic mb_dv, + input logic mb_hold, + input logic mb_error, + output var soc_ifc_req_t mb_data, + input logic [DW-1:0] mb_rdata, + + // Interrupt + output logic notif_intr, + output logic error_intr + +); + + // --------------------------------------- // + // Imports // + // --------------------------------------- // + + // --------------------------------------- // + // Localparams/Typedefs // + // --------------------------------------- // + + // --------------------------------------- // + // Signals // + // --------------------------------------- // + // AXI Manager Read INF + axi_dma_req_if #(.AW(AW)) r_req_if (.clk(clk), .rst_n(rst_n)); + logic r_ready; + logic r_valid; + logic [DW-1:0] r_data; + + // AXI Manager Write INF + axi_dma_req_if #(.AW(AW)) w_req_if (.clk(clk), .rst_n(rst_n)); + logic w_ready; + logic w_valid; + logic [DW-1:0] w_data; + + + // --------------------------------------- // + // Control State Machine // + // --------------------------------------- // + axi_dma_ctrl #( + .AW(AW), + .DW(DW) + ) i_axi_dma_ctrl ( + .clk (clk ), + .cptra_pwrgood(cptra_pwrgood), + .rst_n (rst_n ), + + // Recovery INF Interrupt + // Should only assert when a full block_size of data is available at the + // recovery interface FIFO + .recovery_data_avail(recovery_data_avail), + .recovery_image_activated(recovery_image_activated), + + // Internal Signaling + .mbox_lock (mbox_lock ), + .sha_lock (sha_lock ), + .debugUnlock_or_scan_mode_switch(debugUnlock_or_scan_mode_switch), + .ocp_lock_in_progress(ocp_lock_in_progress), + .key_release_addr (key_release_addr ), + .key_release_size (key_release_size ), + + // AES Interface + .aes_input_ready, + .aes_output_valid, + .aes_status_idle, + .aes_req_dv, + .aes_req_hold, + .aes_req_data, + .aes_rdata, + .aes_err, + + // KV interface + .kv_read (kv_read ), + .kv_rd_resp(kv_rd_resp), + + // Mailbox SRAM INF + .mb_dv (mb_dv ), + .mb_hold (mb_hold ), + .mb_error(mb_error), + .mb_data (mb_data ), + .mb_rdata(mb_rdata), + + // AXI Manager Read INF + .r_req_if (r_req_if.src), + .r_ready_o(r_ready ), + .r_valid_i(r_valid ), + .r_data_i (r_data ), + + // AXI Manager Write INF + .w_req_if (w_req_if.src), + .w_ready_i(w_ready ), + .w_valid_o(w_valid ), + .w_data_o (w_data ), + + // Register INF + .dv (dv ), + .req_data(req_data), + .hold (hold ), + .rdata (rdata ), + .error (error ), + + // Interrupt + .notif_intr(notif_intr), + .error_intr(error_intr) + + ); + + // --------------------------------------- // + // AXI Manager Read Channel // + // --------------------------------------- // + axi_mgr_rd #( + .AW(AW), + .DW(DW), + .UW(UW), + .IW(IW) + ) i_axi_mgr_rd ( + .clk(clk), + .rst_n(rst_n), + + // AXI INF + .m_axi_if(m_axi_r_if), + + // REQ INF + .req_if(r_req_if.snk), + + // Static req USER value + .axuser(axuser), + + // FIFO INF + .ready_i(r_ready), + .valid_o(r_valid), + .data_o (r_data ) + ); + + // --------------------------------------- // + // AXI Manager Write Channel // + // --------------------------------------- // + axi_mgr_wr #( + .AW(AW), + .DW(DW), + .UW(UW), + .IW(IW) + ) i_axi_mgr_wr ( + .clk (clk ), + .rst_n(rst_n), + + // AXI INF + .m_axi_if(m_axi_w_if), + + // REQ INF + .req_if(w_req_if.snk), + + // Static req USER value + .axuser(axuser), + + // FIFO INF + .valid_i(w_valid), + .data_i (w_data ), + .ready_o(w_ready) + ); + + // --------------------------------------- // + // Assertions // + // --------------------------------------- // + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/axi_dma_top_cov_bind.sv b/designs/Caliptra/src/caliptra-rtl/axi_dma_top_cov_bind.sv new file mode 100644 index 0000000..9d14630 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/axi_dma_top_cov_bind.sv @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. + + +module axi_dma_top_cov_bind; + `ifdef FCOV + bind axi_dma_top axi_dma_top_cov_if i_axi_dma_top_cov_if(.*); + bind axi_dma_top axi_dma_top_cov_props i_axi_dma_top_cov_props(.*); + `endif +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/axi_dma_top_cov_if.sv b/designs/Caliptra/src/caliptra-rtl/axi_dma_top_cov_if.sv new file mode 100644 index 0000000..1eb2881 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/axi_dma_top_cov_if.sv @@ -0,0 +1,800 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. + +`ifndef VERILATOR + +interface axi_dma_top_cov_if + import soc_ifc_pkg::*; + import axi_dma_reg_pkg::*; + import kv_defines_pkg::*; + #( + parameter AW = 64, + parameter DW = 32, // Data Width + BC = DW/8, // Byte Count + BW = $clog2(BC), // Byte count Width + parameter UW = 32, // User Width + parameter IW = 1, // ID Width + ID_NUM = 1 << IW // Don't override + )( + input logic clk, + input logic cptra_pwrgood, + input logic rst_n, + + // AXI INF + axi_if.w_mgr m_axi_w_if, + axi_if.r_mgr m_axi_r_if, + + // Component INF + input logic dv, + input var soc_ifc_req_t req_data, + + // Key Vault INF + input logic ocp_lock_in_progress, + input logic [63:0] key_release_addr, + input logic [15:0] key_release_size, + input kv_read_t kv_read, + + // Mailbox SRAM INF + + input logic mb_hold, + input logic mb_error, + input logic [DW-1:0] mb_rdata + ); + + localparam DMA_IDLE = 2'h0; + localparam DMA_WAIT_DATA = 2'h1; + localparam DMA_DONE = 2'h2; + localparam DMA_ERROR = 2'h3; + localparam AES_ERROR = 4'h8; + localparam FIFO_BC = 512; + + // Additional signals for cmd_parse_error coverage + logic cmd_inv_rd_route; + logic cmd_inv_wr_route; + logic cmd_inv_route_combo; + logic cmd_inv_aes_route_combo; + logic cmd_inv_aes_block_size; + logic cmd_inv_aes_fixed; + logic cmd_inv_src_addr; + logic cmd_inv_dst_addr; + logic cmd_inv_byte_count; + logic cmd_inv_block_size; + logic cmd_inv_rd_fixed; + logic cmd_inv_wr_fixed; + logic cmd_inv_mbox_lock; + logic cmd_inv_sha_lock; + logic cmd_parse_error; + + // Key Vault signals for coverage + logic kv_read_en; + kv_error_code_e kv_data_error_code; + logic axi_error; + logic mb_lock_error; + logic aes_error; + logic all_bytes_transferred; + + logic w_valid; + logic [1:0] ctrl_fsm_ps; + logic [1:0] ctrl_fsm_ns; + logic ahb_rd; + logic mb_dv; + logic mb_wr; + logic [SOC_IFC_DATA_W-1:0] mb_wdata; + logic [1:0] rd_route; + logic [2:0] wr_route; + + logic awvalid_seen; + logic arvalid_seen; + + logic [SOC_IFC_DATA_W-1:0] rdata; + + logic [31:0] total_expected_byte_count; + logic [31:0] bytes_remaining; + + logic dma_xfer_start_pulse; + + logic [3:0] aes_fsm_ps; + + assign aes_fsm_ps = axi_dma_top.i_axi_dma_ctrl.aes_fsm_ps; + + + assign w_valid = axi_dma_top.w_valid; + assign ctrl_fsm_ps = axi_dma_top.i_axi_dma_ctrl.ctrl_fsm_ps; + assign ctrl_fsm_ns = axi_dma_top.i_axi_dma_ctrl.ctrl_fsm_ns; + assign ahb_rd = axi_dma_top.i_axi_dma_ctrl.hwif_out.read_data.rdata.swacc; + assign rdata = axi_dma_top.rdata; + assign mb_dv = axi_dma_top.mb_dv; + assign mb_wr = axi_dma_top.mb_data.write; + assign mb_wdata = axi_dma_top.mb_data.wdata; + assign rd_route = axi_dma_top.i_axi_dma_ctrl.hwif_out.ctrl.rd_route.value; + assign wr_route = axi_dma_top.i_axi_dma_ctrl.hwif_out.ctrl.wr_route.value; + assign bytes_remaining = axi_dma_top.i_axi_dma_ctrl.bytes_remaining; + assign cmd_inv_rd_route = axi_dma_top.i_axi_dma_ctrl.cmd_inv_rd_route; + assign cmd_inv_wr_route = axi_dma_top.i_axi_dma_ctrl.cmd_inv_wr_route; + assign cmd_inv_route_combo = axi_dma_top.i_axi_dma_ctrl.cmd_inv_route_combo; + assign cmd_inv_aes_route_combo = axi_dma_top.i_axi_dma_ctrl.cmd_inv_aes_route_combo; + assign cmd_inv_aes_block_size = axi_dma_top.i_axi_dma_ctrl.cmd_inv_aes_block_size; + assign cmd_inv_aes_fixed = axi_dma_top.i_axi_dma_ctrl.cmd_inv_aes_fixed; + assign cmd_inv_src_addr = axi_dma_top.i_axi_dma_ctrl.cmd_inv_src_addr; + assign cmd_inv_dst_addr = axi_dma_top.i_axi_dma_ctrl.cmd_inv_dst_addr; + assign cmd_inv_byte_count = axi_dma_top.i_axi_dma_ctrl.cmd_inv_byte_count; + assign cmd_inv_block_size = axi_dma_top.i_axi_dma_ctrl.cmd_inv_block_size; + assign cmd_inv_rd_fixed = axi_dma_top.i_axi_dma_ctrl.cmd_inv_rd_fixed; + assign cmd_inv_wr_fixed = axi_dma_top.i_axi_dma_ctrl.cmd_inv_wr_fixed; + assign cmd_inv_mbox_lock = axi_dma_top.i_axi_dma_ctrl.cmd_inv_mbox_lock; + assign cmd_inv_sha_lock = axi_dma_top.i_axi_dma_ctrl.cmd_inv_sha_lock; + assign cmd_parse_error = axi_dma_top.i_axi_dma_ctrl.cmd_parse_error; + + assign kv_read_en = axi_dma_top.i_axi_dma_ctrl.kv_read_en; + assign kv_data_error_code = kv_defines_pkg::kv_error_code_e'(axi_dma_top.i_axi_dma_ctrl.kv_data_error_code); + assign axi_error = axi_dma_top.i_axi_dma_ctrl.axi_error; + assign mb_lock_error = axi_dma_top.i_axi_dma_ctrl.mb_lock_error; + assign aes_error = axi_dma_top.i_axi_dma_ctrl.aes_error; + assign all_bytes_transferred = axi_dma_top.i_axi_dma_ctrl.all_bytes_transferred; + + // Pulse dma_xfer_start_pulse at beginning to DMA_WAIT_DATA state + always_ff @(posedge clk or negedge rst_n) begin + if (!rst_n) begin + dma_xfer_start_pulse <= 0; + end + else if (ctrl_fsm_ps == DMA_IDLE && ctrl_fsm_ns != DMA_IDLE) begin + dma_xfer_start_pulse <= 1; + end + else begin + dma_xfer_start_pulse <= 0; + end + end + + // Capture expected total byte count + always @(posedge clk or negedge rst_n) begin + if (!rst_n) begin + total_expected_byte_count <= 0; + end + else if (dma_xfer_start_pulse) begin + total_expected_byte_count <= bytes_remaining; + end + else if (bytes_remaining == 0) begin + total_expected_byte_count <= 0; + end + end + + + // AHB2AXI: Queue to store write data input Component INF + logic [SOC_IFC_DATA_W-1:0] ahb2axi_rdata_queue[$]; + + always_ff @(posedge clk or negedge rst_n) begin + if (!rst_n) begin + ahb2axi_rdata_queue = {}; + end + else if (rd_route == axi_dma_reg__ctrl__rd_route__rd_route_e__DISABLE && + wr_route == axi_dma_reg__ctrl__wr_route__wr_route_e__AHB_FIFO && + ctrl_fsm_ps == DMA_WAIT_DATA && dv && req_data.write) begin + ahb2axi_rdata_queue.push_back(req_data.wdata); + end + end + + // MBOX2AXI: Queue to store read data input from MBOX + logic [SOC_IFC_DATA_W-1:0] mbox2axi_rdata_queue[$]; + + always_ff @(posedge clk or negedge rst_n) begin + if (!rst_n) begin + mbox2axi_rdata_queue = {}; + end + else if (rd_route == axi_dma_reg__ctrl__rd_route__rd_route_e__DISABLE && + wr_route == axi_dma_reg__ctrl__wr_route__wr_route_e__MBOX && + ctrl_fsm_ps == DMA_WAIT_DATA && mb_dv && !mb_hold && !mb_wr) begin + mbox2axi_rdata_queue.push_back(mb_rdata); + end + end + + // AXI2AXI: Queue to store AXI read data + logic [SOC_IFC_DATA_W-1:0] axi2axi_rdata_queue[$]; + + always_ff @(posedge clk or negedge rst_n) begin + if (!rst_n) begin + axi2axi_rdata_queue = {}; + end + else if (rd_route == axi_dma_reg__ctrl__rd_route__rd_route_e__AXI_WR && + wr_route == axi_dma_reg__ctrl__wr_route__wr_route_e__AXI_RD && + ctrl_fsm_ps == DMA_WAIT_DATA && arvalid_seen && m_axi_r_if.rvalid) begin + axi2axi_rdata_queue.push_back(m_axi_r_if.rdata); + end + end + + // AXI2AHB: Queue to store AXI read data + logic [SOC_IFC_DATA_W-1:0] axi2ahb_rdata_queue[$]; + + always_ff @(posedge clk or negedge rst_n) begin + if (!rst_n) begin + axi2ahb_rdata_queue = {}; + end + else if (rd_route == axi_dma_reg__ctrl__rd_route__rd_route_e__AHB_FIFO && + wr_route == axi_dma_reg__ctrl__wr_route__wr_route_e__DISABLE && + ctrl_fsm_ps == DMA_WAIT_DATA && arvalid_seen && m_axi_r_if.rvalid) begin + axi2ahb_rdata_queue.push_back(m_axi_r_if.rdata); + end + end + + // AXI2MBOX: Queue to store AXI read data + logic [SOC_IFC_DATA_W-1:0] axi2mbox_rdata_queue[$]; + + always_ff @(posedge clk or negedge rst_n) begin + if (!rst_n) begin + axi2mbox_rdata_queue = {}; + end + else if (rd_route == axi_dma_reg__ctrl__rd_route__rd_route_e__MBOX && + wr_route == axi_dma_reg__ctrl__wr_route__wr_route_e__DISABLE && + ctrl_fsm_ps == DMA_WAIT_DATA && arvalid_seen && m_axi_r_if.rvalid && mb_wr) begin + axi2mbox_rdata_queue.push_back(m_axi_r_if.rdata); + end + end + + // AXI MGR write in progress + always_ff @(posedge clk or negedge rst_n) begin + if (!rst_n) begin + awvalid_seen <= 0; + end + else if (m_axi_w_if.awvalid && m_axi_w_if.awready && m_axi_w_if.awsize == 3'b010) begin + awvalid_seen <= 1; + end + else if (!m_axi_w_if.wvalid) begin + awvalid_seen <= 0; + end + end + + // AXI MGR Read in progress + always_ff @(posedge clk or negedge rst_n) begin + if (!rst_n) begin + arvalid_seen <= 0; + end + else if (m_axi_r_if.arvalid && m_axi_r_if.arready && m_axi_r_if.arsize == 3'b010) begin + arvalid_seen <= 1; + end + else if (!m_axi_r_if.rready) begin + arvalid_seen <= 0; + end + end + + // Capture expected write data for AHB2AXI transfer + logic [SOC_IFC_DATA_W-1:0] expected_wdata; + logic first_pop_done_req_data; + + always_ff @(posedge clk or negedge rst_n) begin + if (!rst_n) begin + expected_wdata <= 0; + first_pop_done_req_data <= 0; + end + else if (ahb2axi_rdata_queue.size() > 0) begin + if (!first_pop_done_req_data) begin + expected_wdata <= ahb2axi_rdata_queue.pop_front(); + first_pop_done_req_data <= 1; + end + else if (awvalid_seen && m_axi_w_if.wvalid && m_axi_w_if.wready) begin + expected_wdata <= ahb2axi_rdata_queue.pop_front(); + end + end + else if (awvalid_seen && ahb2axi_rdata_queue.size() == 0) begin + first_pop_done_req_data <= 0; + expected_wdata <= 0; + end + end + + // Capture expected mbox read data for MBOX2AXI transfer + logic [SOC_IFC_DATA_W-1:0] expected_mbox_rdata; + logic first_pop_done_mbox_rdata; + + always_ff @(posedge clk or negedge rst_n) begin + if (!rst_n) begin + expected_mbox_rdata <= 0; + first_pop_done_mbox_rdata <= 0; + end + else if (mbox2axi_rdata_queue.size() > 0) begin + if (!first_pop_done_mbox_rdata) begin + expected_mbox_rdata <= mbox2axi_rdata_queue.pop_front(); + first_pop_done_mbox_rdata <= 1; + end + else if (awvalid_seen && m_axi_w_if.wvalid && m_axi_w_if.wready) begin + expected_mbox_rdata <= mbox2axi_rdata_queue.pop_front(); + end + end + else if (awvalid_seen && mbox2axi_rdata_queue.size() == 0) begin + first_pop_done_mbox_rdata <= 0; + expected_mbox_rdata <= 0; + end + end + + + // Capture expected AXI Read Data for AXI2AXI transfer + logic [SOC_IFC_DATA_W-1:0] expected_axi_rdata; + logic first_pop_done_axi_rdata; + + always_ff @(posedge clk or negedge rst_n) begin + if (!rst_n) begin + expected_axi_rdata <= 0; + first_pop_done_axi_rdata <= 0; + end + else if (axi2axi_rdata_queue.size() > 0) begin + if (!first_pop_done_axi_rdata) begin + expected_axi_rdata <= axi2axi_rdata_queue.pop_front(); + first_pop_done_axi_rdata <= 1; + end + else if (awvalid_seen && m_axi_w_if.wvalid && m_axi_w_if.wready) begin + expected_axi_rdata <= axi2axi_rdata_queue.pop_front(); + end + end + else if (awvalid_seen && axi2axi_rdata_queue.size() == 0) begin + first_pop_done_axi_rdata <= 0; + expected_axi_rdata <= 0; + end + end + + // Capture expected AXI read data for AXI2AHB transfer + logic [SOC_IFC_DATA_W-1:0] expected_axi2ahb_rdata; + logic first_pop_done_axi2ahb_rdata; + + always_ff @(posedge clk or negedge rst_n) begin + if (!rst_n) begin + expected_axi2ahb_rdata <= 0; + first_pop_done_axi2ahb_rdata <= 0; + end + else if (axi2ahb_rdata_queue.size() > 0) begin + if (!first_pop_done_axi2ahb_rdata) begin + expected_axi2ahb_rdata <= axi2ahb_rdata_queue.pop_front(); + first_pop_done_axi2ahb_rdata <= 1; + end + else if (ahb_rd) begin + expected_axi2ahb_rdata <= axi2ahb_rdata_queue.pop_front(); + end + end + else if (ctrl_fsm_ps == DMA_DONE && axi2ahb_rdata_queue.size() == 0) begin + first_pop_done_axi2ahb_rdata <= 0; + expected_axi2ahb_rdata <= 0; + end + end + + // Capture expected AXI read data for AXi2MBOX transfer + logic [SOC_IFC_DATA_W-1:0] expected_axi2mbox_rdata; + logic first_pop_done_axi2mbox_rdata; + + always_ff @(posedge clk or negedge rst_n) begin + if (!rst_n) begin + expected_axi2mbox_rdata <= 0; + first_pop_done_axi2mbox_rdata <= 0; + end + else if (axi2mbox_rdata_queue.size() > 0) begin + if (!first_pop_done_axi2mbox_rdata) begin + expected_axi2mbox_rdata <= axi2mbox_rdata_queue.pop_front(); + first_pop_done_axi2mbox_rdata <= 1; + end + else if (mb_dv && mb_wr) begin + expected_axi2mbox_rdata <= axi2mbox_rdata_queue.pop_front(); + end + end + else if (axi2mbox_rdata_queue.size() == 0) begin + first_pop_done_axi2mbox_rdata <= 0; + expected_axi2mbox_rdata <= 0; + end + end + + covergroup axi_dma_top_cov_grp @(posedge clk); + option.per_instance = 1; + + //------------------------------------------------------------- + // Key Vault Read Error Coverpoint + // Covers entry into DMA_ERROR due to kv_read_en && kv_data_error_code != KV_SUCCESS + //------------------------------------------------------------- + + kv_read_error_only_causes_dma_error: coverpoint ( + (ctrl_fsm_ps == DMA_WAIT_DATA) && + (ctrl_fsm_ns == DMA_ERROR) && + kv_read_en && + (kv_data_error_code != KV_SUCCESS) && + !axi_error && // Ensure AXI error is NOT active + !mb_lock_error && // Ensure mailbox lock error is NOT active + !aes_error // Ensure AES error is NOT active + ) { + bins kv_read_error_isolated = {1}; + } + + //------------------------------------------------------------- + // CMD Parse Error Coverpoints - Individual Error Isolation + // Each coverpoint only hits when that specific cmd_inv signal is the ONLY one active + //------------------------------------------------------------- + + // Not included since tied to 0 in design + //cmd_inv_rd_route_in_error: coverpoint ( + // cmd_inv_rd_route && + // !cmd_inv_wr_route && !cmd_inv_route_combo && + // !cmd_inv_aes_route_combo && !cmd_inv_aes_block_size && !cmd_inv_aes_fixed && + // !cmd_inv_src_addr && !cmd_inv_dst_addr && !cmd_inv_byte_count && !cmd_inv_block_size && + // !cmd_inv_rd_fixed && !cmd_inv_wr_fixed && !cmd_inv_mbox_lock && !cmd_inv_sha_lock + //) iff (ctrl_fsm_ps == DMA_ERROR) { + // bins rd_route_error_only = {1}; + //} + + // Don't include cmd_inv_route_combo because this could be asserted as + // well. + cmd_inv_wr_route_in_error: coverpoint ( + cmd_inv_wr_route && + !cmd_inv_rd_route && + !cmd_inv_aes_route_combo && !cmd_inv_aes_block_size && !cmd_inv_aes_fixed && + !cmd_inv_src_addr && !cmd_inv_dst_addr && !cmd_inv_byte_count && !cmd_inv_block_size && + !cmd_inv_rd_fixed && !cmd_inv_wr_fixed && !cmd_inv_mbox_lock && !cmd_inv_sha_lock + ) iff (ctrl_fsm_ps == DMA_ERROR) { + bins wr_route_error_only = {1}; + } + + cmd_inv_route_combo_in_error: coverpoint ( + cmd_inv_route_combo && + !cmd_inv_rd_route && !cmd_inv_wr_route && + !cmd_inv_aes_route_combo && !cmd_inv_aes_block_size && !cmd_inv_aes_fixed && + !cmd_inv_src_addr && !cmd_inv_dst_addr && !cmd_inv_byte_count && !cmd_inv_block_size && + !cmd_inv_rd_fixed && !cmd_inv_wr_fixed && !cmd_inv_mbox_lock && !cmd_inv_sha_lock + ) iff (ctrl_fsm_ps == DMA_ERROR) { + bins route_combo_error_only = {1}; + } + + cmd_inv_aes_route_combo_in_error: coverpoint ( + cmd_inv_aes_route_combo && + !cmd_inv_rd_route && !cmd_inv_wr_route && !cmd_inv_route_combo && + !cmd_inv_aes_block_size && !cmd_inv_aes_fixed && + !cmd_inv_src_addr && !cmd_inv_dst_addr && !cmd_inv_byte_count && !cmd_inv_block_size && + !cmd_inv_rd_fixed && !cmd_inv_wr_fixed && !cmd_inv_mbox_lock && !cmd_inv_sha_lock + ) iff (ctrl_fsm_ps == DMA_ERROR) { + bins aes_route_combo_error_only = {1}; + } + + cmd_inv_aes_block_size_in_error: coverpoint ( + cmd_inv_aes_block_size && + !cmd_inv_rd_route && !cmd_inv_wr_route && !cmd_inv_route_combo && + !cmd_inv_aes_route_combo && !cmd_inv_aes_fixed && + !cmd_inv_src_addr && !cmd_inv_dst_addr && !cmd_inv_byte_count && !cmd_inv_block_size && + !cmd_inv_rd_fixed && !cmd_inv_wr_fixed && !cmd_inv_mbox_lock && !cmd_inv_sha_lock + ) iff (ctrl_fsm_ps == DMA_ERROR) { + bins aes_block_size_error_only = {1}; + } + + cmd_inv_aes_fixed_in_error: coverpoint ( + cmd_inv_aes_fixed && + !cmd_inv_rd_route && !cmd_inv_wr_route && !cmd_inv_route_combo && + !cmd_inv_aes_route_combo && !cmd_inv_aes_block_size && + !cmd_inv_src_addr && !cmd_inv_dst_addr && !cmd_inv_byte_count && !cmd_inv_block_size && + !cmd_inv_rd_fixed && !cmd_inv_wr_fixed && !cmd_inv_mbox_lock && !cmd_inv_sha_lock + ) iff (ctrl_fsm_ps == DMA_ERROR) { + bins aes_fixed_error_only = {1}; + } + + cmd_inv_src_addr_in_error: coverpoint ( + cmd_inv_src_addr && + !cmd_inv_rd_route && !cmd_inv_wr_route && !cmd_inv_route_combo && + !cmd_inv_aes_route_combo && !cmd_inv_aes_block_size && !cmd_inv_aes_fixed && + !cmd_inv_dst_addr && !cmd_inv_byte_count && !cmd_inv_block_size && + !cmd_inv_rd_fixed && !cmd_inv_wr_fixed && !cmd_inv_mbox_lock && !cmd_inv_sha_lock + ) iff (ctrl_fsm_ps == DMA_ERROR) { + bins src_addr_error_only = {1}; + } + + cmd_inv_dst_addr_in_error: coverpoint ( + cmd_inv_dst_addr && + !cmd_inv_rd_route && !cmd_inv_wr_route && !cmd_inv_route_combo && + !cmd_inv_aes_route_combo && !cmd_inv_aes_block_size && !cmd_inv_aes_fixed && + !cmd_inv_src_addr && !cmd_inv_byte_count && !cmd_inv_block_size && + !cmd_inv_rd_fixed && !cmd_inv_wr_fixed && !cmd_inv_mbox_lock && !cmd_inv_sha_lock + ) iff (ctrl_fsm_ps == DMA_ERROR) { + bins dst_addr_error_only = {1}; + } + + cmd_inv_byte_count_in_error: coverpoint ( + cmd_inv_byte_count && + !cmd_inv_rd_route && !cmd_inv_wr_route && !cmd_inv_route_combo && + !cmd_inv_aes_route_combo && !cmd_inv_aes_block_size && !cmd_inv_aes_fixed && + !cmd_inv_src_addr && !cmd_inv_dst_addr && !cmd_inv_block_size && + !cmd_inv_rd_fixed && !cmd_inv_wr_fixed && !cmd_inv_mbox_lock && !cmd_inv_sha_lock + ) iff (ctrl_fsm_ps == DMA_ERROR) { + bins byte_count_error_only = {1}; + } + + cmd_inv_block_size_in_error: coverpoint ( + cmd_inv_block_size && + !cmd_inv_rd_route && !cmd_inv_wr_route && !cmd_inv_route_combo && + !cmd_inv_aes_route_combo && !cmd_inv_aes_block_size && !cmd_inv_aes_fixed && + !cmd_inv_src_addr && !cmd_inv_dst_addr && !cmd_inv_byte_count && + !cmd_inv_rd_fixed && !cmd_inv_wr_fixed && !cmd_inv_mbox_lock && !cmd_inv_sha_lock + ) iff (ctrl_fsm_ps == DMA_ERROR) { + bins block_size_error_only = {1}; + } + + cmd_inv_rd_fixed_in_error: coverpoint ( + cmd_inv_rd_fixed && + !cmd_inv_rd_route && !cmd_inv_wr_route && !cmd_inv_route_combo && + !cmd_inv_aes_route_combo && !cmd_inv_aes_block_size && !cmd_inv_aes_fixed && + !cmd_inv_src_addr && !cmd_inv_dst_addr && !cmd_inv_byte_count && !cmd_inv_block_size && + !cmd_inv_wr_fixed && !cmd_inv_mbox_lock && !cmd_inv_sha_lock + ) iff (ctrl_fsm_ps == DMA_ERROR) { + bins rd_fixed_error_only = {1}; + } + + cmd_inv_wr_fixed_in_error: coverpoint ( + cmd_inv_wr_fixed && + !cmd_inv_rd_route && !cmd_inv_wr_route && !cmd_inv_route_combo && + !cmd_inv_aes_route_combo && !cmd_inv_aes_block_size && !cmd_inv_aes_fixed && + !cmd_inv_src_addr && !cmd_inv_dst_addr && !cmd_inv_byte_count && !cmd_inv_block_size && + !cmd_inv_rd_fixed && !cmd_inv_mbox_lock && !cmd_inv_sha_lock + ) iff (ctrl_fsm_ps == DMA_ERROR) { + bins wr_fixed_error_only = {1}; + } + + cmd_inv_mbox_lock_in_error: coverpoint ( + cmd_inv_mbox_lock && + !cmd_inv_rd_route && !cmd_inv_wr_route && !cmd_inv_route_combo && + !cmd_inv_aes_route_combo && !cmd_inv_aes_block_size && !cmd_inv_aes_fixed && + !cmd_inv_src_addr && !cmd_inv_dst_addr && !cmd_inv_byte_count && !cmd_inv_block_size && + !cmd_inv_rd_fixed && !cmd_inv_wr_fixed && !cmd_inv_sha_lock + ) iff (ctrl_fsm_ps == DMA_ERROR) { + bins mbox_lock_error_only = {1}; + } + + cmd_inv_sha_lock_in_error: coverpoint ( + cmd_inv_sha_lock && + !cmd_inv_rd_route && !cmd_inv_wr_route && !cmd_inv_route_combo && + !cmd_inv_aes_route_combo && !cmd_inv_aes_block_size && !cmd_inv_aes_fixed && + !cmd_inv_src_addr && !cmd_inv_dst_addr && !cmd_inv_byte_count && !cmd_inv_block_size && + !cmd_inv_rd_fixed && !cmd_inv_wr_fixed && !cmd_inv_mbox_lock + ) iff (ctrl_fsm_ps == DMA_ERROR) { + bins sha_lock_error_only = {1}; + } + + //------------------------------------------------------------- + // Key Release Address Mismatch - Requirement 2 + // DMA_ERROR due to key_release_addr mismatch, with KEYVAULT route, no other cmd_inv active + //------------------------------------------------------------- + + key_release_addr_mismatch_error: coverpoint ( + ctrl_fsm_ps == DMA_ERROR && + cmd_inv_dst_addr && + (wr_route == axi_dma_reg__ctrl__wr_route__wr_route_e__KEYVAULT) && + !cmd_inv_rd_route && !cmd_inv_wr_route && !cmd_inv_route_combo && + !cmd_inv_aes_route_combo && !cmd_inv_aes_block_size && !cmd_inv_aes_fixed && + !cmd_inv_src_addr && !cmd_inv_byte_count && !cmd_inv_block_size && + !cmd_inv_rd_fixed && !cmd_inv_wr_fixed && !cmd_inv_mbox_lock && !cmd_inv_sha_lock + ) { + bins key_addr_mismatch_only = {1}; + } + + //------------------------------------------------------------- + // OCP Lock Not In Progress - Requirement 4 + // DMA_ERROR due to !ocp_lock_in_progress with KEYVAULT route, no other cmd_inv active + //------------------------------------------------------------- + + ocp_lock_not_in_progress_error: coverpoint ( + ctrl_fsm_ps == DMA_ERROR && + cmd_inv_wr_route && + (wr_route == axi_dma_reg__ctrl__wr_route__wr_route_e__KEYVAULT) && + !ocp_lock_in_progress && + !cmd_inv_rd_route && !cmd_inv_route_combo && + !cmd_inv_aes_route_combo && !cmd_inv_aes_block_size && !cmd_inv_aes_fixed && + !cmd_inv_src_addr && !cmd_inv_dst_addr && !cmd_inv_byte_count && !cmd_inv_block_size && + !cmd_inv_rd_fixed && !cmd_inv_wr_fixed && !cmd_inv_mbox_lock && !cmd_inv_sha_lock + ) { + bins ocp_lock_not_active_only = {1}; + } + + //------------------------------------------------------------- + // Additional Interesting Coverpoints - Requirement 5 + //------------------------------------------------------------- + + // Key Vault operation start when OCP lock is active + keyvault_operation_with_ocp_lock: coverpoint ( + dma_xfer_start_pulse && + (wr_route == axi_dma_reg__ctrl__wr_route__wr_route_e__KEYVAULT) && + ocp_lock_in_progress + ) { + bins keyvault_with_lock = {1}; + } + + + // Key release address and size both match when starting KEYVAULT operation + keyvault_perfect_match: coverpoint ( + dma_xfer_start_pulse && + (wr_route == axi_dma_reg__ctrl__wr_route__wr_route_e__KEYVAULT) && + ocp_lock_in_progress && + (axi_dma_top.i_axi_dma_ctrl.dst_addr == key_release_addr) && + (axi_dma_top.i_axi_dma_ctrl.hwif_out.byte_count.count.value == 32'(key_release_size)) + ) { + bins perfect_keyvault_match = {1}; + } + + // OCP lock status during different DMA operations + ocp_lock_status_during_operations: coverpoint ocp_lock_in_progress iff (dma_xfer_start_pulse) { + bins lock_active = {1}; + bins lock_inactive = {0}; + } + + ocp_lock_in_progress_cp: coverpoint ocp_lock_in_progress; + + wr_route_cp: coverpoint wr_route { + bins disabled = {axi_dma_reg__ctrl__wr_route__wr_route_e__DISABLE}; + bins axi_rd = {axi_dma_reg__ctrl__wr_route__wr_route_e__AXI_RD}; + bins ahb_fifo = {axi_dma_reg__ctrl__wr_route__wr_route_e__AHB_FIFO}; + bins mbox = {axi_dma_reg__ctrl__wr_route__wr_route_e__MBOX}; + bins keyvault = {axi_dma_reg__ctrl__wr_route__wr_route_e__KEYVAULT}; + bins invalid_values = {[5:7]}; // Illegal bins, but still possible by error-injection test cases so mark these values as regular bins + } + + // Cross coverage: Route combination with OCP lock status + route_ocp_lock_cross: cross wr_route_cp, ocp_lock_in_progress_cp iff (dma_xfer_start_pulse) { + // Only interested in KEYVAULT route combinations + bins keyvault_with_lock = binsof(wr_route_cp) intersect {axi_dma_reg__ctrl__wr_route__wr_route_e__KEYVAULT} && + binsof(ocp_lock_in_progress_cp) intersect {1}; + bins keyvault_without_lock = binsof(wr_route_cp) intersect {axi_dma_reg__ctrl__wr_route__wr_route_e__KEYVAULT} && + binsof(ocp_lock_in_progress_cp) intersect {0}; + } + + kv_read_en_cp: coverpoint kv_read.read_entry iff (kv_read_en) { + bins kv_23 = {23}; + bins kv_not_23 = {23}; + } + + kv_read_X_ocp_lock: cross kv_read_en_cp, ocp_lock_in_progress_cp; + + //------------------------------------------------------------- + // Edge Function Coverpoints + //------------------------------------------------------------- + + //------------------------------------------- + // 1DW Transfers Data Check + // ------------------------------------------ + + // AHB2AXI_1DW Transfer with Data Comparison + ahb2axi_1dw_data_compare: coverpoint (awvalid_seen && m_axi_w_if.wvalid && m_axi_w_if.wdata == expected_wdata) { + bins single_4byte_ahb2axi_match = {1}; // Cover 4-byte write transfers with matching data + } + + // MBOX2AXI_1DW Transfer with Data Comparison + mbox2axi_1dw_data_compare: coverpoint (awvalid_seen && m_axi_w_if.wvalid && m_axi_w_if.wdata == expected_mbox_rdata) { + bins single_4byte_mbox2axi_match = {1}; // Cover 4-byte write transfer with matching data + } + + // AXI2AXI_1DW Transfer with Data Comparison + axi2axi_1dw_data_compare: coverpoint (awvalid_seen && m_axi_w_if.wvalid && m_axi_w_if.wready && m_axi_w_if.wdata == expected_axi_rdata) { + bins single_4byte_axi2axi_match = {1}; + } + + // AXI2AHB_1DW Transfer with Data Comparison + axi2ahb_1dw_data_compare: coverpoint (dv && ahb_rd && rdata == expected_axi2ahb_rdata) { + bins single_4byte_axi2ahb_match = {1}; + } + + // AXI2MBOX_1DW Transfer with Data Comparison + axi2mbox_1dw_data_compare: coverpoint (mb_dv && mb_wr && mb_wdata == expected_axi2mbox_rdata) { + bins single_4byte_axi2mbox_match = {1}; + } + + // ------------------------------------------------------------------- + // N-DW Transfers with total byte count check and transfer split check + // ------------------------------------------------------------------- + //ah2axi_ndw_byte_count: coverpoint () { + // bins total_byte_count_ahb2axi_match = {1}; + //} + + + + // 1. AES_ERROR and DMA_ERROR concurrent with aes_error only + aes_dma_concurrent_error: coverpoint (aes_fsm_ps == AES_ERROR && ctrl_fsm_ps == DMA_ERROR && + aes_error && !cmd_parse_error && !axi_error && !mb_lock_error) { + bins concurrent_aes_dma_error = {1}; + } + + // 2a-d. AES mode enabled with specific byte counts + aes_mode_byte_count_4: coverpoint (axi_dma_top.i_axi_dma_ctrl.hwif_out.ctrl.aes_mode_en.value && axi_dma_top.i_axi_dma_ctrl.hwif_out.ctrl.aes_gcm_mode.value && + axi_dma_top.i_axi_dma_ctrl.hwif_out.ctrl.go.value && axi_dma_top.i_axi_dma_ctrl.hwif_out.byte_count.count.value == 32'h4) { + bins aes_byte_count_4 = {1}; + } + + aes_mode_byte_count_12: coverpoint (axi_dma_top.i_axi_dma_ctrl.hwif_out.ctrl.aes_mode_en.value && axi_dma_top.i_axi_dma_ctrl.hwif_out.ctrl.aes_gcm_mode.value && + axi_dma_top.i_axi_dma_ctrl.hwif_out.ctrl.go.value && axi_dma_top.i_axi_dma_ctrl.hwif_out.byte_count.count.value == 32'd12) { + bins aes_byte_count_12 = {1}; + } + + aes_mode_byte_count_16: coverpoint (axi_dma_top.i_axi_dma_ctrl.hwif_out.ctrl.aes_mode_en.value && axi_dma_top.i_axi_dma_ctrl.hwif_out.ctrl.aes_gcm_mode.value && + axi_dma_top.i_axi_dma_ctrl.hwif_out.ctrl.go.value && axi_dma_top.i_axi_dma_ctrl.hwif_out.byte_count.count.value == 32'd16) { + bins aes_byte_count_16 = {1}; + } + + aes_mode_byte_count_gt_fifo: coverpoint (axi_dma_top.i_axi_dma_ctrl.hwif_out.ctrl.aes_mode_en.value && axi_dma_top.i_axi_dma_ctrl.hwif_out.ctrl.aes_gcm_mode.value && + axi_dma_top.i_axi_dma_ctrl.hwif_out.ctrl.go.value && axi_dma_top.i_axi_dma_ctrl.hwif_out.byte_count.count.value > FIFO_BC) { + bins aes_byte_count_gt_fifo = {1}; + } + + // 3. AXI error in DMA_WAIT_DATA with AES mode enabled + axi_error_dma_wait_aes: coverpoint (ctrl_fsm_ps == DMA_WAIT_DATA && axi_error && axi_dma_top.i_axi_dma_ctrl.hwif_out.ctrl.aes_mode_en.value) { + bins axi_error_wait_aes = {1}; + } + + // 4a. cmd_inv_aes_route_combo with rd_route != AXI_WR (but wr_route == AXI_RD) + aes_route_combo_rd_not_axi_wr: coverpoint (cmd_inv_aes_route_combo && + axi_dma_top.i_axi_dma_ctrl.hwif_out.ctrl.rd_route.value != 2'(axi_dma_reg__ctrl__rd_route__rd_route_e__AXI_WR)) + iff (axi_dma_top.i_axi_dma_ctrl.hwif_out.ctrl.wr_route.value == 2'(axi_dma_reg__ctrl__wr_route__wr_route_e__AXI_RD)) { + bins rd_route_not_axi_wr = {1}; + } + + // 4b. cmd_inv_aes_route_combo with wr_route != AXI_RD (but rd_route == AXI_WR) + aes_route_combo_wr_not_axi_rd: coverpoint (cmd_inv_aes_route_combo && + axi_dma_top.i_axi_dma_ctrl.hwif_out.ctrl.wr_route.value != 2'(axi_dma_reg__ctrl__wr_route__wr_route_e__AXI_RD)) + iff (axi_dma_top.i_axi_dma_ctrl.hwif_out.ctrl.rd_route.value == 2'(axi_dma_reg__ctrl__rd_route__rd_route_e__AXI_WR)) { + bins wr_route_not_axi_rd = {1}; + } + + // 5a. AES mode with GCM mode set + aes_gcm_mode_set: coverpoint (axi_dma_top.i_axi_dma_ctrl.hwif_out.ctrl.aes_mode_en.value && axi_dma_top.i_axi_dma_ctrl.hwif_out.ctrl.go.value && axi_dma_top.i_axi_dma_ctrl.hwif_out.ctrl.aes_gcm_mode.value) { + bins aes_gcm_set = {1}; + } + + // 5b. AES mode with GCM mode not set + aes_gcm_mode_not_set: coverpoint (axi_dma_top.i_axi_dma_ctrl.hwif_out.ctrl.aes_mode_en.value && axi_dma_top.i_axi_dma_ctrl.hwif_out.ctrl.go.value && !axi_dma_top.i_axi_dma_ctrl.hwif_out.ctrl.aes_gcm_mode.value) { + bins aes_gcm_not_set = {1}; + } + + // 6. cmd_inv_aes_block_size exclusive + cmd_inv_aes_block_size_only: coverpoint (cmd_inv_aes_block_size && + !cmd_inv_rd_route && !cmd_inv_wr_route && !cmd_inv_route_combo && + !cmd_inv_src_addr && !cmd_inv_dst_addr && !cmd_inv_byte_count && + !cmd_inv_block_size && !cmd_inv_rd_fixed && !cmd_inv_wr_fixed && + !cmd_inv_mbox_lock && !cmd_inv_sha_lock && !cmd_inv_aes_route_combo && + !cmd_inv_aes_fixed) { + bins aes_block_size_only = {1}; + } + + // 7. cmd_inv_aes_fixed exclusive + cmd_inv_aes_fixed_only: coverpoint (cmd_inv_aes_fixed && + !cmd_inv_rd_route && !cmd_inv_wr_route && !cmd_inv_route_combo && + !cmd_inv_src_addr && !cmd_inv_dst_addr && !cmd_inv_byte_count && + !cmd_inv_block_size && !cmd_inv_rd_fixed && !cmd_inv_wr_fixed && + !cmd_inv_mbox_lock && !cmd_inv_sha_lock && !cmd_inv_aes_route_combo && + !cmd_inv_aes_block_size) { + bins aes_fixed_only = {1}; + } + + // 8. cmd_inv_aes_fixed with rd_fixed and not wr_fixed + aes_fixed_rd_only: coverpoint (cmd_inv_aes_fixed && axi_dma_top.i_axi_dma_ctrl.hwif_out.ctrl.rd_fixed.value && !axi_dma_top.i_axi_dma_ctrl.hwif_out.ctrl.wr_fixed.value) { + bins aes_fixed_rd_not_wr = {1}; + } + + // 9. cmd_inv_aes_fixed with wr_fixed and not rd_fixed + aes_fixed_wr_only: coverpoint (cmd_inv_aes_fixed && !axi_dma_top.i_axi_dma_ctrl.hwif_out.ctrl.rd_fixed.value && axi_dma_top.i_axi_dma_ctrl.hwif_out.ctrl.wr_fixed.value) { + bins aes_fixed_wr_not_rd = {1}; + } + + // 10. cmd_inv_aes_route_combo exclusive + cmd_inv_aes_route_combo_only: coverpoint (cmd_inv_aes_route_combo && + !cmd_inv_rd_route && !cmd_inv_wr_route && !cmd_inv_route_combo && + !cmd_inv_src_addr && !cmd_inv_dst_addr && !cmd_inv_byte_count && + !cmd_inv_block_size && !cmd_inv_rd_fixed && !cmd_inv_wr_fixed && + !cmd_inv_mbox_lock && !cmd_inv_sha_lock && !cmd_inv_aes_block_size && + !cmd_inv_aes_fixed) { + bins aes_route_combo_only = {1}; + } + + // 11. wr_aes_ceil_req_byte_count in DMA_WAIT_DATA with AES mode + wr_aes_ceil_req_dma_wait: coverpoint (axi_dma_top.i_axi_dma_ctrl.wr_aes_ceil_req_byte_count < 16 && axi_dma_top.i_axi_dma_ctrl.w_req_if.valid && axi_dma_top.i_axi_dma_ctrl.wr_sel_req_byte_count < axi_dma_top.i_axi_dma_ctrl.wr_align_req_byte_count && axi_dma_top.i_axi_dma_ctrl.hwif_out.ctrl.aes_mode_en.value && + ctrl_fsm_ps == DMA_WAIT_DATA) { + bins wr_aes_ceil_dma_wait = {1}; + } + endgroup + + + axi_dma_top_cov_grp axi_dma_top_cov_grp1 = new(); +endinterface + +`endif diff --git a/designs/Caliptra/src/caliptra-rtl/axi_dma_top_cov_props.sv b/designs/Caliptra/src/caliptra-rtl/axi_dma_top_cov_props.sv new file mode 100644 index 0000000..a0fc56e --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/axi_dma_top_cov_props.sv @@ -0,0 +1,22 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2019 Western Digital Corporation or its affiliates. +// +// 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. +// + +// This file contains properties that define various sequences of events in AXI DMA + +module axi_dma_top_cov_props(); + `ifndef VERILATOR + `endif +endmodule \ No newline at end of file diff --git a/designs/Caliptra/src/caliptra-rtl/axi_if.sv b/designs/Caliptra/src/caliptra-rtl/axi_if.sv new file mode 100644 index 0000000..cfcaae4 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/axi_if.sv @@ -0,0 +1,406 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +// +// Description: +// Signals for a standard AXI4 compliant interface +// + +interface axi_if #(parameter integer AW = 32, parameter integer DW = 32, parameter integer IW = 8, parameter integer UW = 32) (input logic clk, input logic rst_n); + + import axi_pkg::*; + + // AXI AR + logic [AW-1:0] araddr; + logic [$bits(axi_burst_e)-1:0] arburst; + logic [2:0] arsize; + logic [7:0] arlen; + logic [UW-1:0] aruser; + logic [IW-1:0] arid; + logic arlock; + logic arvalid; + logic arready; + + // AXI R + logic [DW-1:0] rdata; + logic [$bits(axi_resp_e)-1:0] rresp; + logic [IW-1:0] rid; + logic [UW-1:0] ruser; + logic rlast; + logic rvalid; + logic rready; + + // AXI AW + logic [AW-1:0] awaddr; + logic [$bits(axi_burst_e)-1:0] awburst; + logic [2:0] awsize; + logic [7:0] awlen; + logic [UW-1:0] awuser; + logic [IW-1:0] awid; + logic awlock; + logic awvalid; + logic awready; + + // AXI W + logic [DW-1:0] wdata; + logic [DW/8-1:0] wstrb; + logic [UW-1:0] wuser; + logic wvalid; + logic wready; + logic wlast; + + // AXI B + logic [$bits(axi_resp_e)-1:0] bresp; + logic [IW-1:0] bid; + logic [UW-1:0] buser; + logic bvalid; + logic bready; + + // Modport for read manager + modport r_mgr ( + // AR + output araddr, + output arburst, + output arsize, + output arlen, + output aruser, + output arid, + output arlock, + output arvalid, + input arready, + // R + input rdata, + input rresp, + input rid, + input ruser, + input rlast, + input rvalid, + output rready + ); + + // Modport for write manager + modport w_mgr ( + // AW + output awaddr, + output awburst, + output awsize, + output awlen, + output awuser, + output awid, + output awlock, + output awvalid, + input awready, + // W + output wdata, + output wstrb, + output wuser, + output wvalid, + input wready, + output wlast, + // B + input bresp, + input bid, + input buser, + input bvalid, + output bready + ); + + // Modport for read subordinate + modport r_sub ( + // AR + input araddr, + input arburst, + input arsize, + input arlen, + input aruser, + input arid, + input arlock, + input arvalid, + output arready, + // R + output rdata, + output rresp, + output rid, + output ruser, + output rlast, + output rvalid, + input rready + ); + + // Modport for write subordinate + modport w_sub ( + // AW + input awaddr, + input awburst, + input awsize, + input awlen, + input awuser, + input awid, + input awlock, + input awvalid, + output awready, + // W + input wdata, + input wstrb, + input wuser, + input wvalid, + output wready, + input wlast, + // B + output bresp, + output bid, + output buser, + output bvalid, + input bready + ); + + // synopsys translate_off + + // Tasks + `ifdef VERILATOR + `define EQ__ = + `define TIME_ALGN #100ps + `else + `define EQ__ <= + `define TIME_ALGN + `endif + + `ifndef SYNTHESIS + `ifndef XCELIUM + task rst_mgr(); + araddr `EQ__ '0; + arburst `EQ__ AXI_BURST_FIXED; + arsize `EQ__ '0; + arlen `EQ__ '0; + aruser `EQ__ '0; + arid `EQ__ '0; + arlock `EQ__ '0; + arvalid `EQ__ '0; + + rready `EQ__ '0; + + awaddr `EQ__ '0; + awburst `EQ__ AXI_BURST_FIXED; + awsize `EQ__ '0; + awlen `EQ__ '0; + awuser `EQ__ '0; + awid `EQ__ '0; + awlock `EQ__ '0; + awvalid `EQ__ '0; + + wdata `EQ__ '0; + wstrb `EQ__ '0; + wuser `EQ__ '0; + wvalid `EQ__ '0; + wlast `EQ__ '0; + + bready `EQ__ '0; + endtask + + // TODO: handle IDs? + task get_read_beat(output logic [DW-1:0] data, + output logic [UW-1:0] user, + output axi_resp_e resp); + `TIME_ALGN + rready `EQ__ 1; + do + @(posedge clk); + while (!rvalid); + data `EQ__ rdata; + user `EQ__ ruser; + resp `EQ__ axi_resp_e'(rresp); + `TIME_ALGN + rready `EQ__ 0; + wait(!rready); + endtask + + // Read: default to single beat of native data width + task axi_read(input logic [AW-1:0] addr, + input axi_burst_e burst = AXI_BURST_INCR, + input logic [2:0] size = $clog2(DW/8), + input logic [7:0] len = 0, + input logic [UW-1:0] user = UW'(0), + input logic [IW-1:0] id = IW'(0), + input logic lock = 1'b0, + output logic [DW-1:0] data [], + output logic [UW-1:0] resp_user [], + output axi_resp_e resp []); + axi_resp_e beat_resp; + logic [UW-1:0] beat_user; + logic [DW-1:0] beat_data; + while(!rst_n) @(posedge clk); + do begin + `TIME_ALGN + araddr `EQ__ addr; + arburst `EQ__ burst; + arsize `EQ__ size; + arlen `EQ__ len; + aruser `EQ__ user; + arid `EQ__ id; + arlock `EQ__ lock; + arvalid `EQ__ 1; + @(posedge clk); + end while(!arready); + `TIME_ALGN + araddr `EQ__ '0; + arburst `EQ__ AXI_BURST_FIXED; + arsize `EQ__ '0; + arlen `EQ__ '0; + aruser `EQ__ '0; + arid `EQ__ '0; + arlock `EQ__ '0; + arvalid `EQ__ '0; + data = new[len+1]; + resp = new[len+1]; + for (int beat=0; beat <= len; beat++) begin + get_read_beat(beat_data, beat_user, beat_resp); + data[beat] = beat_data; + resp_user[beat] = beat_user; + resp[beat] = beat_resp; + end + endtask + + task axi_read_single(input logic [AW-1:0] addr, + input logic [UW-1:0] user = UW'(0), + input logic [IW-1:0] id = IW'(0), + input logic lock = 1'b0, + output logic [DW-1:0] data, + output logic [UW-1:0] resp_user, + output axi_resp_e resp); + automatic axi_resp_e burst_resp[]; + automatic logic [UW-1:0] burst_ruser[]; + automatic logic [DW-1:0] burst_data[]; + axi_read(.addr (addr ), + .user (user ), + .id (id ), + .lock (lock ), + .data (burst_data ), + .resp_user(burst_ruser), + .resp (burst_resp )); + data = burst_data[0]; + resp_user = burst_ruser[0]; + resp = burst_resp[0]; + endtask + + task send_write_beat(input logic last, + input logic [DW-1:0] data, + input logic [UW-1:0] user, + input logic [DW/8-1:0] strb); + `TIME_ALGN + wvalid `EQ__ 1; + wlast `EQ__ last; + wdata `EQ__ data; + wstrb `EQ__ strb; + wuser `EQ__ user; + do + @(posedge clk); + while (!wready); + `TIME_ALGN + wvalid `EQ__ '0; + wlast `EQ__ '0; + wdata `EQ__ '0; + wstrb `EQ__ '0; + wuser `EQ__ '0; + wait(!wvalid); + endtask + + // TODO handle ID + task get_write_resp(output axi_resp_e resp, + output logic [UW-1:0] user); + `TIME_ALGN + bready `EQ__ 1; + do + @(posedge clk); + while(!bvalid); + resp `EQ__ axi_resp_e'(bresp); + user `EQ__ buser; + `TIME_ALGN + bready `EQ__ 0; + wait(!bready); + endtask + + task axi_write(input logic [AW-1:0] addr, + input axi_burst_e burst = AXI_BURST_INCR, + input logic [2:0] size = $clog2(DW/8), + input logic [7:0] len = 0, + input logic [UW-1:0] user = UW'(0), + input logic [IW-1:0] id = IW'(0), + input logic lock = 1'b0, + input logic [DW-1:0] data [], + input logic use_strb = 0, + input logic [DW/8-1:0] strb [], + input logic use_write_user = 0, + input logic [UW-1:0] write_user [], + output axi_resp_e resp, + output logic [UW-1:0] resp_user); + while(!rst_n) @(posedge clk); + do begin + `TIME_ALGN + awaddr `EQ__ addr; + awburst `EQ__ burst; + awsize `EQ__ size; + awlen `EQ__ len; + awuser `EQ__ user; + awid `EQ__ id; + awlock `EQ__ lock; + awvalid `EQ__ 1; + @(posedge clk); + end while(!awready); + `TIME_ALGN + awaddr `EQ__ '0; + awburst `EQ__ AXI_BURST_FIXED; + awsize `EQ__ '0; + awlen `EQ__ '0; + awuser `EQ__ '0; + awid `EQ__ '0; + awlock `EQ__ '0; + awvalid `EQ__ '0; + fork + for (int beat=0; beat <= len; beat++) + send_write_beat(beat == len, data[beat], use_write_user ? write_user[beat] : UW'(0), use_strb ? strb[beat] : {DW/8{1'b1}}); + get_write_resp(resp, resp_user); + join + endtask + + task axi_write_single(input logic [AW-1:0] addr, + input logic [UW-1:0] user = UW'(0), + input logic [IW-1:0] id = IW'(0), + input logic lock = 1'b0, + input logic [DW-1:0] data, + input logic [UW-1:0] write_user = UW'(0), + output axi_resp_e resp, + output logic [UW-1:0] resp_user); + automatic logic [DW/8-1:0] burst_strb[] = new[1]('{{DW/8{1'b1}}}); + automatic logic [UW -1:0] burst_user[] = new[1]('{write_user}); + automatic logic [DW -1:0] burst_data[] = new[1]('{data}); + axi_write(.addr(addr), + .user(user), + .id (id ), + .lock(lock), + .data(burst_data), + .use_strb(0), + .strb(burst_strb), + .use_write_user(0), + .write_user(burst_user), + .resp(resp), + .resp_user(resp_user)); + endtask + `endif + `endif + + `undef EQ__ + `undef TIME_ALGN + + // synopsys translate_on + +endinterface diff --git a/designs/Caliptra/src/caliptra-rtl/axi_mgr_rd.sv b/designs/Caliptra/src/caliptra-rtl/axi_mgr_rd.sv new file mode 100644 index 0000000..1275bd2 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/axi_mgr_rd.sv @@ -0,0 +1,193 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +// +// Description: +// Generic AXI4 manager component for read channel. Accepts requests from +// FSM logic, converts the request to legal AXI4 handshake, and forwards +// return data via a FIFO interface. +// + +module axi_mgr_rd import axi_pkg::*; #( + parameter AW = 32, + parameter DW = 32, + BC = DW/8, // Byte Count + BW = $clog2(BC), // Byte count Width + parameter UW = 32, + parameter IW = 1, + ID_NUM = 1 << IW +) ( + input logic clk, + input logic rst_n, + + // AXI INF + axi_if.r_mgr m_axi_if, + + // REQ INF + axi_dma_req_if.snk req_if, + + // Static req USER value + input logic [UW-1:0] axuser, + + // FIFO INF + input logic ready_i, + output logic valid_o, + output logic [DW-1:0] data_o +); + + // --------------------------------------- // + // Imports // + // --------------------------------------- // + `include "caliptra_prim_assert.sv" + + + // --------------------------------------- // + // Localparams/Typedefs // + // --------------------------------------- // + // Transaction context + typedef struct packed { + logic [AW-1:0] addr; + logic fixed; + logic [AXI_LEN_WIDTH-1:0] len; + logic lock; + } req_ctx_t; + + + // --------------------------------------- // + // Signals // + // --------------------------------------- // + req_ctx_t req_ctx; + req_ctx_t axi_ctx; + logic axi_ctx_valid; + logic axi_ctx_ready; + logic axi_ctx_sent; + + logic txn_active; + logic txn_final_beat; + + + // --------------------------------------- // + // Request Context // + // --------------------------------------- // + + always_comb begin + req_ctx.addr = req_if.addr; + req_ctx.fixed = req_if.fixed; + req_ctx.len = req_if.byte_len[BW+:AXI_LEN_WIDTH]; + req_ctx.lock = req_if.lock; + end + + // Buffer the incoming request, but send it out over Address channel immediately + // to allow multiple in-flight transactions (reduce bubbles between bursts). + // The contents of the skidbuffer will inform the tracker for the next data + // burst once the address channel request is sent. + skidbuffer #( + .OPT_LOWPOWER (0 ), + .OPT_OUTREG (0 ), + // + .OPT_PASSTHROUGH(0 ), + .DW ($bits(req_ctx_t)) + ) i_ctx_skd ( + .i_clk (clk ), + .i_reset(rst_n ), + .i_valid(req_if.valid ), + .o_ready(req_if.ready ), + .i_data (req_ctx ), + .o_valid(axi_ctx_valid ), + .i_ready(axi_ctx_ready ), + .o_data (axi_ctx ) + ); + + always_ff@(posedge clk or negedge rst_n) begin + if (!rst_n) begin + axi_ctx_sent <= 1'b0; + end + else if (axi_ctx_valid && axi_ctx_ready) begin + axi_ctx_sent <= 1'b0; + end + else if (m_axi_if.arvalid && m_axi_if.arready) begin + axi_ctx_sent <= 1'b1; + end + end + + always_comb begin + m_axi_if.arvalid = axi_ctx_valid && !axi_ctx_sent; + m_axi_if.araddr = axi_ctx.addr; + m_axi_if.arburst = axi_ctx.fixed ? AXI_BURST_FIXED : AXI_BURST_INCR; + m_axi_if.arsize = BW; + m_axi_if.arlen = axi_ctx.len; + m_axi_if.aruser = axuser; + m_axi_if.arid = IW'(0); + m_axi_if.arlock = axi_ctx.lock; + end + + always_comb axi_ctx_ready = (!txn_active || txn_final_beat) && + (m_axi_if.arready || axi_ctx_sent); + + + // --------------------------------------- // + // Datapath // + // --------------------------------------- // + always_ff@(posedge clk or negedge rst_n) begin + if (!rst_n) begin + txn_active <= 1'b0; + end + else if (axi_ctx_valid && axi_ctx_ready) begin + txn_active <= 1'b1; + end + else if (txn_final_beat) begin + txn_active <= 1'b0; + end + end + + always_comb txn_final_beat = m_axi_if.rvalid && m_axi_if.rready && m_axi_if.rlast; + always_comb m_axi_if.rready = txn_active && ready_i; + + always_comb begin + valid_o = m_axi_if.rvalid && m_axi_if.rready; + data_o = m_axi_if.rdata; + end + + always_ff@(posedge clk or negedge rst_n) begin + if (!rst_n) begin + req_if.resp <= AXI_RESP_OKAY; + req_if.resp_valid <= 1'b0; + end + // Accumulate status codes... + // TODO what if ERROR is interleaved with EXOKAY? + // That would be a mistake by the slave, since we don't use Exclusive Access feature + else if (m_axi_if.rvalid && m_axi_if.rready) begin + req_if.resp <= req_if.resp | m_axi_if.rresp; + req_if.resp_valid <= m_axi_if.rlast; + end + else if (axi_ctx_valid && axi_ctx_ready) begin + req_if.resp <= AXI_RESP_OKAY; + req_if.resp_valid <= 1'b0; + end + else begin + req_if.resp <= req_if.resp; + req_if.resp_valid <= 1'b0; + end + end + + // --------------------------------------- // + // Assertions // + // --------------------------------------- // + `CALIPTRA_ASSERT(AXI_MGR_REQ_BND, req_if.valid && !req_if.fixed |-> ((req_if.addr[11:0] + req_if.byte_len) <= 4096), clk, !rst_n) + `CALIPTRA_ASSERT(AXI_MGR_LEGAL_LEN, req_if.valid |-> (req_if.byte_len[AXI_LEN_BC_WIDTH-1:BW]) < AXI_LEN_MAX_VALUE, clk, !rst_n) + `CALIPTRA_ASSERT(AXI_MGR_LEGAL_FIXED_LEN, req_if.valid && req_if.fixed |-> (req_if.byte_len[AXI_LEN_BC_WIDTH-1:BW]) < AXI_FIXED_LEN_MAX_VALUE, clk, !rst_n) + `CALIPTRA_ASSERT(AXI_MGR_DATA_WHILE_ACTIVE, valid_o |-> txn_active, clk, !rst_n) + `CALIPTRA_ASSERT_NEVER(AXI_MGR_OFLOW, m_axi_if.rready && !ready_i, clk, !rst_n) + + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/axi_mgr_wr.sv b/designs/Caliptra/src/caliptra-rtl/axi_mgr_wr.sv new file mode 100644 index 0000000..837d543 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/axi_mgr_wr.sv @@ -0,0 +1,194 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +// +// Description: +// Generic AXI4 manager component for write channel. Accepts requests from +// FSM logic, converts the request to legal AXI4 handshake, and moves data +// that is received via a FIFO interface. +// + +module axi_mgr_wr import axi_pkg::*; #( + parameter AW = 32, + parameter DW = 32, + BC = DW/8, // Byte Count + BW = $clog2(BC), // Byte count Width + parameter UW = 32, + parameter IW = 1, + ID_NUM = 1 << IW +) ( + input logic clk, + input logic rst_n, + + // AXI INF + axi_if.w_mgr m_axi_if, + + // REQ INF + axi_dma_req_if.snk req_if, + + // Static req USER value + input logic [UW-1:0] axuser, + + // FIFO INF + input logic valid_i, + input logic [DW-1:0] data_i, + output logic ready_o +); + + // --------------------------------------- // + // Imports // + // --------------------------------------- // + `include "caliptra_prim_assert.sv" + + + // --------------------------------------- // + // Localparams/Typedefs // + // --------------------------------------- // + // Transaction context + typedef struct packed { + logic [AW-1:0] addr; + logic fixed; + logic [AXI_LEN_WIDTH-1:0] len; + logic lock; + } req_ctx_t; + + + // --------------------------------------- // + // Signals // + // --------------------------------------- // + req_ctx_t req_ctx; + req_ctx_t axi_ctx; + logic axi_ctx_valid; + logic axi_ctx_ready; + logic axi_ctx_sent; + + logic txn_active; + logic [AXI_LEN_WIDTH-1:0] txn_down_cnt; + logic txn_final_beat; + + + // --------------------------------------- // + // Request Context // + // --------------------------------------- // + + always_comb begin + req_ctx.addr = req_if.addr; + req_ctx.fixed = req_if.fixed; + req_ctx.len = req_if.byte_len[BW+:8]; + req_ctx.lock = req_if.lock; + end + + // Buffer the incoming request, but send it out over Address channel immediately + // to allow multiple in-flight transactions (reduce bubbles between bursts). + // The contents of the skidbuffer will inform the tracker for the next data + // burst once the address channel request is sent. + skidbuffer #( + .OPT_LOWPOWER (0 ), + .OPT_OUTREG (0 ), + // + .OPT_PASSTHROUGH(0 ), + .DW ($bits(req_ctx_t)) + ) i_ctx_skd ( + .i_clk (clk ), + .i_reset(rst_n ), + .i_valid(req_if.valid ), + .o_ready(req_if.ready ), + .i_data (req_ctx ), + .o_valid(axi_ctx_valid ), + .i_ready(axi_ctx_ready ), + .o_data (axi_ctx ) + ); + + always_ff@(posedge clk or negedge rst_n) begin + if (!rst_n) begin + axi_ctx_sent <= 1'b0; + end + else if (axi_ctx_valid && axi_ctx_ready) begin + axi_ctx_sent <= 1'b0; + end + else if (m_axi_if.awvalid && m_axi_if.awready) begin + axi_ctx_sent <= 1'b1; + end + end + + always_comb begin + m_axi_if.awvalid = axi_ctx_valid && !axi_ctx_sent; + m_axi_if.awaddr = axi_ctx.addr; + m_axi_if.awburst = axi_ctx.fixed ? AXI_BURST_FIXED : AXI_BURST_INCR; + m_axi_if.awsize = BW; + m_axi_if.awlen = axi_ctx.len; + m_axi_if.awuser = axuser; + m_axi_if.awid = IW'(0); + m_axi_if.awlock = axi_ctx.lock; + end + + always_comb axi_ctx_ready = (!txn_active || txn_final_beat) && + (m_axi_if.awready || axi_ctx_sent); + + + // --------------------------------------- // + // Datapath // + // --------------------------------------- // + always_ff@(posedge clk or negedge rst_n) begin + if (!rst_n) begin + txn_active <= 1'b0; + end + else if (axi_ctx_valid && axi_ctx_ready) begin + txn_active <= 1'b1; + end + else if (txn_final_beat) begin + txn_active <= 1'b0; + end + end + + always_ff@(posedge clk or negedge rst_n) begin + if (!rst_n) begin + txn_down_cnt <= '1; + end + else if (axi_ctx_valid && axi_ctx_ready) begin + txn_down_cnt <= axi_ctx.len; + end + else if (m_axi_if.wvalid && m_axi_if.wready) begin + txn_down_cnt <= txn_down_cnt - 1; + end + end + + always_comb txn_final_beat = m_axi_if.wvalid && m_axi_if.wready && m_axi_if.wlast; + always_comb begin + m_axi_if.wvalid = txn_active && valid_i; + m_axi_if.wdata = data_i; + m_axi_if.wstrb = '1; // TODO support this? requires significant ctrl updates + m_axi_if.wuser = axuser; + m_axi_if.wlast = ~|txn_down_cnt; + end + + always_comb ready_o = txn_active && m_axi_if.wready; + + always_comb m_axi_if.bready = 1'b1; + + always_comb begin + req_if.resp = m_axi_if.bresp; + req_if.resp_valid = m_axi_if.bvalid; + end + + + // --------------------------------------- // + // Assertions // + // --------------------------------------- // + `CALIPTRA_ASSERT(AXI_MGR_REQ_BND, req_if.valid && !req_if.fixed |-> ((req_if.addr[11:0] + req_if.byte_len) <= 4096), clk, !rst_n) + `CALIPTRA_ASSERT(AXI_MGR_LEGAL_LEN, req_if.valid |-> (req_if.byte_len[AXI_LEN_BC_WIDTH-1:BW]) < AXI_LEN_MAX_VALUE, clk, !rst_n) + `CALIPTRA_ASSERT(AXI_MGR_LEGAL_FIXED_LEN, req_if.valid && req_if.fixed |-> (req_if.byte_len[AXI_LEN_BC_WIDTH-1:BW]) < AXI_FIXED_LEN_MAX_VALUE, clk, !rst_n) + `CALIPTRA_ASSERT(AXI_MGR_DATA_WHILE_ACTIVE, ready_o |-> txn_active, clk, !rst_n) + `CALIPTRA_ASSERT_NEVER(AXI_MGR_UFLOW, m_axi_if.wvalid && !valid_i, clk, !rst_n) + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/axi_pkg.sv b/designs/Caliptra/src/caliptra-rtl/axi_pkg.sv new file mode 100644 index 0000000..619af79 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/axi_pkg.sv @@ -0,0 +1,41 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +// + +package axi_pkg; + + localparam AXI_LEN_MAX_VALUE = 256; // 8-bit LEN signal = 256 beats max + localparam AXI_LEN_WIDTH = $clog2(AXI_LEN_MAX_VALUE); + localparam AXI_FIXED_LEN_MAX_VALUE = 16; // When AxBURST = FIXED, max length is 16 beats (AXI spec A3.4.1) + localparam AXI_FIXED_LEN_WIDTH = $clog2(AXI_FIXED_LEN_MAX_VALUE); + localparam AXI_LEN_MAX_BYTES = 4096; + localparam AXI_LEN_BC_WIDTH = $clog2(AXI_LEN_MAX_BYTES); + + // AXI Burst Enum + typedef enum logic [1:0] { + AXI_BURST_FIXED = 2'b00, + AXI_BURST_INCR = 2'b01, + AXI_BURST_WRAP = 2'b10, + AXI_BURST_RESERVED = 2'b11 + } axi_burst_e; + + // AXI Resp Enum + typedef enum logic [1:0] { + AXI_RESP_OKAY = 2'b00, + AXI_RESP_EXOKAY = 2'b01, + AXI_RESP_SLVERR = 2'b10, + AXI_RESP_DECERR = 2'b11 + } axi_resp_e; + +endpackage diff --git a/designs/Caliptra/src/caliptra-rtl/axi_sub.sv b/designs/Caliptra/src/caliptra-rtl/axi_sub.sv new file mode 100644 index 0000000..e4fffa2 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/axi_sub.sv @@ -0,0 +1,222 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +// +// +// ------------------------------------------------------------- +// AXI Subordinate +// ------------------------------------------------------------- +// Description: +// Subordinate to convert AXI protocol transactions into internal component accesses +// Includes an arbiter to squash duplex AXI transactions into simplex component operations +// May optionally include an Exclusive Access monitor (AxLOCK signal) +// +// Limitations: +// - When multiple ID tracking is enabled, write responses are returned in the +// same order they are received, regardless of ID. +// +// ------------------------------------------------------------- + +module axi_sub import axi_pkg::*; #( + parameter AW = 32, // Address Width + parameter DW = 32, // Data Width + BC = DW/8, // Byte Count + BW = $clog2(BC), // Byte count Width + parameter UW = 32, // User Width + parameter IW = 1, // ID Width + ID_NUM = 1 << IW, // Don't override + + parameter EX_EN = 0, // Enable exclusive access tracking w/ AxLOCK + parameter C_LAT = 0 // Component latency in clock cycles from (dv&&!hld) -> rdata + // Must be const per component + // For registers, typically 0 + // For SRAM, 1 or more +) ( + input clk, + input rst_n, + + // AXI INF + axi_if.w_sub s_axi_w_if, + axi_if.r_sub s_axi_r_if, + + //COMPONENT INF + output logic dv, + output logic [AW-1:0] addr, // Byte address + output logic write, + output logic [UW-1:0] user, + output logic [IW-1:0] id, + output logic [DW-1:0] wdata, // Requires: Component dwidth == AXI dwidth + output logic [BC-1:0] wstrb, // Requires: Component dwidth == AXI dwidth + output logic [2:0] size, + input logic [DW-1:0] rdata, // Requires: Component dwidth == AXI dwidth + output logic last, // Asserted with final 'dv' of a burst + input logic hld, + input logic rd_err, + input logic wr_err + +); + + // Exclusive Access Signals + `ifdef CALIPTRA_AXI_SUB_EX_EN + logic [ID_NUM-1:0] ex_clr; + logic [ID_NUM-1:0] ex_active; + struct packed { + logic [AW-1:0] addr; + logic [AW-1:0] addr_mask; + } [ID_NUM-1:0] ex_ctx; + `endif + + //Read Subordinate INF + logic r_dv; + logic [AW-1:0] r_addr; // Byte address + logic [UW-1:0] r_user; + logic [IW-1:0] r_id; + logic [2:0] r_size; + logic r_last; // Asserted with final 'dv' of a burst + logic r_hld; + logic r_err; + + logic [DW-1:0] r_rdata; // Requires: Component dwidth == AXI dwidth + + //Write Subordinate INF + logic w_dv; + logic [AW-1:0] w_addr; // Byte address + logic [UW-1:0] w_user; + logic [IW-1:0] w_id; + logic [DW-1:0] w_wdata; // Requires: Component dwidth == AXI dwidth + logic [BC-1:0] w_wstrb; // Requires: Component dwidth == AXI dwidth + logic [2:0] w_size; + logic w_last; // Asserted with final 'dv' of a burst + logic w_hld; + logic w_err; + + + axi_sub_wr #( + .AW (AW ), + .DW (DW ), + .UW (UW ), + .IW (IW ) + + ) i_axi_sub_wr ( + .clk (clk ), + .rst_n(rst_n), + + // AXI INF + .s_axi_if(s_axi_w_if), + + // Exclusive Access Signals + `ifdef CALIPTRA_AXI_SUB_EX_EN + .ex_clr (ex_clr ), + .ex_active(ex_active), + .ex_ctx (ex_ctx ), + `endif + + //COMPONENT INF + .dv (w_dv ), + .addr (w_addr ), + .user (w_user ), + .id (w_id ), + .wdata(w_wdata), + .wstrb(w_wstrb), + .wsize(w_size ), + .last (w_last ), + .hld (w_hld ), + .err (w_err ) + + ); + + axi_sub_rd #( + .AW(AW), + .DW(DW), + .UW(UW), + .IW(IW), + + .C_LAT(C_LAT) + ) i_axi_sub_rd ( + .clk (clk ), + .rst_n(rst_n), + + // AXI INF + .s_axi_if(s_axi_r_if), + + // Exclusive Access Signals + `ifdef CALIPTRA_AXI_SUB_EX_EN + .ex_clr (ex_clr ), + .ex_active(ex_active), + .ex_ctx (ex_ctx ), + `endif + + //COMPONENT INF + .dv (r_dv ), + .addr (r_addr ), + .user (r_user ), + .id (r_id ), + .size (r_size ), + .last (r_last ), + .hld (r_hld ), + .err (r_err ), + + .rdata(r_rdata) + ); + + axi_sub_arb #( + .AW(AW), + .DW(DW), + .UW(UW), + .IW(IW), + + .C_LAT(C_LAT) + ) i_axi_sub_arb ( + .clk (clk ), + .rst_n (rst_n ), + + //Read Subordinate INF + .r_dv (r_dv ), + .r_addr (r_addr ), + .r_user (r_user ), + .r_id (r_id ), + .r_last (r_last ), + .r_size (r_size ), + .r_hld (r_hld ), + .r_err (r_err ), + .r_rdata(r_rdata), + + //Write Subordinate INF + .w_dv (w_dv ), + .w_addr (w_addr ), + .w_user (w_user ), + .w_id (w_id ), + .w_wdata(w_wdata), + .w_wstrb(w_wstrb), + .w_size (w_size ), + .w_last (w_last ), + .w_hld (w_hld ), + .w_err (w_err ), + + //COMPONENT INF + .dv (dv ), + .addr (addr ), + .write (write ), + .user (user ), + .id (id ), + .wdata (wdata ), + .wstrb (wstrb ), + .size (size ), + .last (last ), + .hld (hld ), + .rd_err (rd_err ), + .wr_err (wr_err ), + .rdata (rdata ) + ); + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/axi_sub_arb.sv b/designs/Caliptra/src/caliptra-rtl/axi_sub_arb.sv new file mode 100644 index 0000000..66837d1 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/axi_sub_arb.sv @@ -0,0 +1,144 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +// + +// ------------------------------------------------------------- +// AXI Subordinate Arbiter +// ------------------------------------------------------------- +// Description: +// Arbitrate between Reads and Writes coming from AXI subordinate modules. +// Always give precedence to Writes. +// +// ------------------------------------------------------------- + +module axi_sub_arb import axi_pkg::*; #( + parameter AW = 32, // Address Width + parameter DW = 32, // Data Width + BC = DW/8, // Byte Count + BW = $clog2(BC), // Byte count Width + parameter UW = 32, // User Width + parameter IW = 1, // ID Width + ID_NUM = 1 << IW, // Don't override + + parameter C_LAT = 0 // Component latency in clock cycles from (dv&&!hld) -> rdata + // Must be const per component + // For registers, typically 0 + // For SRAM, 1 or more +) ( + input clk, + input rst_n, + + //Read Subordinate INF + input logic r_dv, + input logic [AW-1:0] r_addr, // Byte address + input logic [UW-1:0] r_user, + input logic [IW-1:0] r_id, + input logic [2:0] r_size, + input logic r_last, // Asserted with final 'dv' of a burst + output logic r_hld, + output logic r_err, + + output logic [DW-1:0] r_rdata, // Requires: Component dwidth == AXI dwidth + + //Write Subordinate INF + input logic w_dv, + input logic [AW-1:0] w_addr, // Byte address + input logic [UW-1:0] w_user, + input logic [IW-1:0] w_id, + input logic [DW-1:0] w_wdata, // Requires: Component dwidth == AXI dwidth + input logic [BC-1:0] w_wstrb, // Requires: Component dwidth == AXI dwidth + input logic [2:0] w_size, + input logic w_last, // Asserted with final 'dv' of a burst + output logic w_hld, + output logic w_err, + + //COMPONENT INF + output logic dv, + output logic [AW-1:0] addr, // Byte address + output logic write, + output logic [UW-1:0] user, + output logic [IW-1:0] id, + output logic [DW-1:0] wdata, // Requires: Component dwidth == AXI dwidth + output logic [BC-1:0] wstrb, // Requires: Component dwidth == AXI dwidth + output logic [2:0] size, + output logic last, // Asserted with final 'dv' of a burst + input logic hld, + input logic rd_err, // Asserts with rdata for reads (when C_LAT > 0) + input logic wr_err, // Asserts with dv for writes + + input logic [DW-1:0] rdata // Requires: Component dwidth == AXI dwidth +); + + `include "caliptra_prim_assert.sv" + + logic r_pri; // Priority to reads + logic r_win; + + // Switch priority to current arb winner so that priority persists + // in case + // a) it was granted during a hold + // b) it was granted at start of multi-beat burst + // Otherwise, always give priority to other channel at end of a burst + // to arbitrate fairly + always_ff@(posedge clk or negedge rst_n) begin + if (!rst_n) + r_pri <= 1'b0; + // Toggle priority at end of burst + else if (w_dv && !w_hld && w_last) + r_pri <= 1'b1; + else if (r_dv && !r_hld && r_last) + r_pri <= 1'b0; + // Keep priority when xfer is in progress + else if (w_dv && !r_win) + r_pri <= 1'b0; + else if (r_dv && r_win) + r_pri <= 1'b1; + end + + always_comb begin +// case ({r_pri,r_dv,w_dv}) inside +// 3'b000: r_win = 0; +// 3'b001: r_win = 0; +// 3'b010: r_win = 1; +// 3'b011: r_win = 0; +// 3'b100: r_win = 1; +// 3'b101: r_win = 0; +// 3'b110: r_win = 1; +// 3'b111: r_win = 1; +// endcase + if (r_pri) r_win = r_dv || !w_dv; + else r_win = r_dv && !w_dv; + end + + always_comb begin + dv = r_dv || w_dv; + addr = r_win ? r_addr : w_addr; + write = r_win ? 0 : 1; + user = r_win ? r_user : w_user; + id = r_win ? r_id : w_id ; + last = r_win ? r_last : w_last; + size = r_win ? r_size : w_size; + r_hld = hld || !r_win; + w_hld = hld || r_win; + r_err = rd_err; + w_err = wr_err; + wdata = w_wdata; + wstrb = w_wstrb; + r_rdata = rdata; + end + + `CALIPTRA_ASSERT_NEVER(AXI_SUB_ARB_CONFLICT, r_dv && !r_hld && w_dv && !w_hld, clk, !rst_n) + + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/axi_sub_rd.sv b/designs/Caliptra/src/caliptra-rtl/axi_sub_rd.sv new file mode 100644 index 0000000..a48c041 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/axi_sub_rd.sv @@ -0,0 +1,430 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +// + +// ------------------------------------------------------------- +// AXI Read Subordinate +// ------------------------------------------------------------- +// Description: +// Subordinate to convert AXI protocol reads into internal component accesses +// +// Limitations: +// - Drives RUSER to all 0's (i.e., RUSER is unimplemented) +// - When multiple ID tracking is enabled, read responses are returned in the +// same order they are received, regardless of ID. +// +// ------------------------------------------------------------- + +module axi_sub_rd import axi_pkg::*; #( + parameter AW = 32, // Address Width + parameter DW = 32, // Data Width + BC = DW/8, // Byte Count + BW = $clog2(BC), // Byte count Width + parameter UW = 32, // User Width + parameter IW = 1, // ID Width + ID_NUM = 1 << IW, // Don't override + + parameter C_LAT = 0 // Component latency in clock cycles from (dv&&!hld) -> rdata + // Must be const per component + // For registers, typically 0 + // For SRAM, 1 or more +) ( + input clk, + input rst_n, + + // AXI INF + axi_if.r_sub s_axi_if, + + // Exclusive Access Signals + // Enable exclusive access tracking w/ AxLOCK if EX_EN is set + `ifdef CALIPTRA_AXI_SUB_EX_EN + input logic [ID_NUM-1:0] ex_clr, + output logic [ID_NUM-1:0] ex_active, + output struct packed { + logic [AW-1:0] addr; + logic [AW-1:0] addr_mask; + } [ID_NUM-1:0] ex_ctx, + `endif + + //COMPONENT INF + output logic dv, + output logic [AW-1:0] addr, // Byte address + output logic [UW-1:0] user, + output logic [IW-1:0] id, + output logic [2:0] size, + output logic last, // Asserted with final 'dv' of a burst + input logic hld, + input logic err, + + input logic [DW-1:0] rdata // Requires: Component dwidth == AXI dwidth +); + + // --------------------------------------- // + // Imports // + // --------------------------------------- // + `include "caliptra_prim_assert.sv" + + // --------------------------------------- // + // Localparams/Typedefs // + // --------------------------------------- // + + // Transaction context + typedef struct packed { + logic [AW-1:0] addr; + axi_burst_e burst; + logic [2:0] size; + logic [7:0] len; + logic [UW-1:0] user; + logic [IW-1:0] id; + logic lock; + } axi_ctx_t; + + typedef struct packed { + logic [IW-1:0] id; + logic [UW-1:0] user; + axi_resp_e resp; + logic last; + } xfer_ctx_t; + + + // --------------------------------------- // + // Signals // + // --------------------------------------- // + + genvar cp; // Context pipeline + genvar dp; // Data pipeline + `ifdef CALIPTRA_AXI_SUB_EX_EN + genvar ex; // Exclusive contexts + `endif + + logic axi_out_of_rst; + + // Active transaction signals + // track requests as they are sent to component + axi_ctx_t txn_ctx; + logic [AW-1:0] txn_addr_nxt; + logic [ 7:0] txn_cnt; // Internal down-counter to track txn progress + logic txn_active; + logic txn_rvalid [C_LAT+1]; + xfer_ctx_t txn_xfer_ctx [C_LAT+1]; + logic txn_final_beat; + + // Data pipeline signals (skid buffer) + // track data after it is received from component + logic [C_LAT+1:0] [DW-1:0] dp_rdata; + xfer_ctx_t [C_LAT+1:0] dp_xfer_ctx; + logic [C_LAT+1:0] dp_rvalid; + logic [C_LAT+1:0] dp_rready; + + + // --------------------------------------- // + // Address Request I/F // + // --------------------------------------- // + + assign s_axi_if.arready = axi_out_of_rst && (!txn_active || txn_final_beat); + + always_ff@(posedge clk or negedge rst_n) begin + if (!rst_n) begin + axi_out_of_rst <= 1'b0; + end + else begin + axi_out_of_rst <= 1'b1; + end + end + + // Indicates there are still reqs to be issued towards component. + // This active signal deasserts after final dv to component, meaning data is + // still in flight from component->AXI for C_LAT clocks after deassertion + always_ff@(posedge clk or negedge rst_n) begin + if (!rst_n) begin + txn_active <= 1'b0; + end + else if (s_axi_if.arvalid && s_axi_if.arready) begin + txn_active <= 1'b1; + end + else if (txn_final_beat) begin + txn_active <= 1'b0; + end + else begin + txn_active <= txn_active; + end + end + + always_ff@(posedge clk or negedge rst_n) begin + if (!rst_n) begin + txn_ctx <= '{default:0, burst:AXI_BURST_FIXED}; + txn_cnt <= '0; + end + else if (s_axi_if.arvalid && s_axi_if.arready) begin + txn_ctx.addr <= s_axi_if.araddr[AW-1:0]; + txn_ctx.burst <= axi_burst_e'(s_axi_if.arburst); + txn_ctx.size <= s_axi_if.arsize; + txn_ctx.len <= s_axi_if.arlen ; + txn_ctx.user <= s_axi_if.aruser; + txn_ctx.id <= s_axi_if.arid ; + txn_ctx.lock <= s_axi_if.arlock; + txn_cnt <= s_axi_if.arlen ; + end + else if (txn_rvalid[0]) begin + txn_ctx.addr <= txn_addr_nxt; + txn_ctx.burst <= txn_ctx.burst; + txn_ctx.size <= txn_ctx.size; + txn_ctx.len <= txn_ctx.len ; + txn_ctx.user <= txn_ctx.user; + txn_ctx.id <= txn_ctx.id ; + txn_ctx.lock <= txn_ctx.lock; + txn_cnt <= |txn_cnt ? txn_cnt - 1 : txn_cnt; // Prevent underflow to 255 at end to reduce switching power. Extra logic cost worth it? + end + end + + // Only make the request to component if we have space in the pipeline to + // store the result (under worst-case AXI backpressure) + // To check this, look at the 'ready' output from all stages of the + // skidbuffer pipeline (but omit the C_LAT+1 index because that comes from + // axi rready) + assign dv = txn_active && &dp_rready[C_LAT:0]; + assign txn_rvalid[0] = dv && !hld; + + // Asserts on the final beat of the COMPONENT INF which means it lags the + // final AXI beat by at least C_LAT clocks (or more depending on backpressure) + assign txn_final_beat = txn_rvalid[0] && txn_xfer_ctx[0].last; + + + // --------------------------------------- // + // Address Calculations // + // --------------------------------------- // + // Force aligned address to component + assign addr = {txn_ctx.addr[AW-1:BW],BW'(0)}; + assign user = txn_ctx.user; + assign id = txn_ctx.id; + assign size = txn_ctx.size; + assign last = txn_cnt == 0; + + // Use full address to calculate next address (in case of arsize < data width) + axi_addr #( + .AW (AW), + .DW (DW) + ) i_axi_addr ( + .i_last_addr(txn_ctx.addr ), + .i_size (txn_ctx.size ), // 1b, 2b, 4b, 8b, etc + .i_burst (txn_ctx.burst), // fixed, incr, wrap, reserved + .i_len (txn_ctx.len ), + .o_next_addr(txn_addr_nxt ) + ); + + + // --------------------------------------- // + // Request Context Pipeline // + // --------------------------------------- // + assign txn_xfer_ctx[0].id = txn_ctx.id; + assign txn_xfer_ctx[0].user = txn_ctx.user; + assign txn_xfer_ctx[0].last = txn_cnt == 0; + assign txn_xfer_ctx[0].resp = + `ifdef CALIPTRA_AXI_SUB_EX_EN + txn_ctx.lock ? AXI_RESP_EXOKAY : + `endif + AXI_RESP_OKAY; + + // Shift Register to track requests made to component + generate + if (C_LAT > 0) begin: TXN_SR + // Context is maintained alongside request while waiting for + // component response to arrive + for (cp = 1; cp <= C_LAT; cp++) begin: CTX_PIPELINE + always_ff@(posedge clk or negedge rst_n) begin + if (!rst_n) begin + txn_rvalid[cp] <= 1'b0; + end + else begin + txn_rvalid[cp] <= txn_rvalid[cp-1]; + end + end + + // No reset needed on data path -- txn_rvalid (control path) is reset + always_ff@(posedge clk) begin + txn_xfer_ctx[cp] <= txn_xfer_ctx[cp-1]; + end + end: CTX_PIPELINE + + end: TXN_SR + endgenerate + + + // --------------------------------------- // + // Exclusive Access Tracking // + // --------------------------------------- // + `ifdef CALIPTRA_AXI_SUB_EX_EN + // Exclusive access requires transaction LENGTH to be a power of 2, + // so an address mask may be prepared by assuming the AxLEN value has + // all consecutive LSB set to 1, then all 0's in higher order bits. After + // shifting by the width of the transaction (AxSIZE), this mask can be applied + // to AxADDR to give the aligned address relative to an exclusive access. + // + logic [AW-1:0] addr_ex_algn_mask; + always_comb begin + case (BC) inside + 1: addr_ex_algn_mask = ~(AW'(txn_ctx.len)); + 2: addr_ex_algn_mask = (~(AW'(txn_ctx.len))) << txn_ctx.size[0]; + 4: addr_ex_algn_mask = (~(AW'(txn_ctx.len))) << txn_ctx.size[1:0]; + 8: addr_ex_algn_mask = (~(AW'(txn_ctx.len))) << txn_ctx.size[1:0]; + default: addr_ex_algn_mask = (~(AW'(txn_ctx.len))) << txn_ctx.size; + endcase + end + + always_ff@(posedge clk or negedge rst_n) begin + if (!rst_n) begin + ex_active <= '0; + end + // give 'set' precedence over 'clr' in case of same ID + else if ((txn_rvalid[0] && txn_ctx.lock) && |ex_clr) begin + ex_active <= (ex_active & ~ex_clr) | (1 << txn_ctx.id); + end + else if (txn_rvalid[0] && txn_ctx.lock) begin + ex_active <= ex_active | (1 << txn_ctx.id); + end + else if (|ex_clr) begin + ex_active <= ex_active & ~ex_clr; + end + else begin + ex_active <= ex_active; + end + end + + for (ex = 0; ex < ID_NUM; ex++) begin: EX_CTX_TRACKER + // TODO: reset? + always_ff@(posedge clk) begin + if (txn_rvalid[0] && txn_ctx.lock && (txn_ctx.id == ex)) begin + ex_ctx[ex].addr <= txn_ctx.addr; + ex_ctx[ex].addr_mask <= addr_ex_algn_mask; + end + // Ignore the clear case, as ex_active is the ctrl path + //else if (ex_clr[ex]) begin + //end + else begin + ex_ctx[ex] <= ex_ctx[ex]; + end + end + end + `endif + + + // --------------------------------------- // + // Data/Response // + // --------------------------------------- // + assign dp_rvalid[0] = txn_rvalid[C_LAT]; + assign dp_rdata[0] = rdata; + assign dp_xfer_ctx[0].id = txn_xfer_ctx[C_LAT].id; + assign dp_xfer_ctx[0].user = txn_xfer_ctx[C_LAT].user; // NOTE: Unused after it enters data pipeline + assign dp_xfer_ctx[0].resp = err ? AXI_RESP_SLVERR : + `ifdef CALIPTRA_AXI_SUB_EX_EN + txn_xfer_ctx[C_LAT].resp; + `else + AXI_RESP_OKAY; + `endif + assign dp_xfer_ctx[0].last = txn_xfer_ctx[C_LAT].last; + + generate + for (dp = 0; dp <= C_LAT; dp++) begin: DATA_PIPELINE + // skidbuffer instance to pipeline data payload + context to AXI, + // after response is received from component. + // This is necessary when there is latency from dv->rdata, + // because AXI R channel can be stalled by dropping rready, + // and we can't drop the data (which was requested N cycles ago) + skidbuffer #( + .OPT_LOWPOWER (0 ), + .OPT_OUTREG (0 ), + // + .OPT_PASSTHROUGH(0 ), + .DW (DW + $bits(xfer_ctx_t)) + ) i_dp_skd ( + .i_clk (clk ), + .i_reset(rst_n ), + .i_valid(dp_rvalid[dp] ), + .o_ready(dp_rready[dp] ), + .i_data ({dp_rdata[dp], + dp_xfer_ctx[dp]} ), + .o_valid(dp_rvalid[dp+1] ), + .i_ready(dp_rready[dp+1] ), + .o_data ({dp_rdata[dp+1], + dp_xfer_ctx[dp+1]}) + ); + + end: DATA_PIPELINE + endgenerate + + assign dp_rready[C_LAT+1] = s_axi_if.rready; + assign s_axi_if.rvalid = dp_rvalid[C_LAT+1]; + assign s_axi_if.rlast = dp_xfer_ctx[C_LAT+1].last; + assign s_axi_if.rdata = dp_rdata[C_LAT+1]; + assign s_axi_if.rid = dp_xfer_ctx[C_LAT+1].id; + assign s_axi_if.ruser = '0; + assign s_axi_if.rresp = dp_xfer_ctx[C_LAT+1].resp; + + + // --------------------------------------- // + // Formal Properties // + // --------------------------------------- // + `CALIPTRA_ASSERT_KNOWN(AXI_SUB_X_ARVALID, s_axi_if.arvalid, clk, !rst_n) + `CALIPTRA_ASSERT_KNOWN(AXI_SUB_X_ARREADY, s_axi_if.arready, clk, !rst_n) + `CALIPTRA_ASSERT_KNOWN(AXI_SUB_X_ARADDR , (s_axi_if.arvalid ? s_axi_if.araddr : '0), clk, !rst_n) + `CALIPTRA_ASSERT_KNOWN(AXI_SUB_X_ARBURST, (s_axi_if.arvalid ? s_axi_if.arburst : '0), clk, !rst_n) + `CALIPTRA_ASSERT_KNOWN(AXI_SUB_X_ARSIZE , (s_axi_if.arvalid ? s_axi_if.arsize : '0), clk, !rst_n) + `CALIPTRA_ASSERT_KNOWN(AXI_SUB_X_ARLEN , (s_axi_if.arvalid ? s_axi_if.arlen : '0), clk, !rst_n) + `CALIPTRA_ASSERT_KNOWN(AXI_SUB_X_ARUSER , (s_axi_if.arvalid ? s_axi_if.aruser : '0), clk, !rst_n) + `CALIPTRA_ASSERT_KNOWN(AXI_SUB_X_ARID , (s_axi_if.arvalid ? s_axi_if.arid : '0), clk, !rst_n) + `CALIPTRA_ASSERT_KNOWN(AXI_SUB_X_ARLOCK , (s_axi_if.arvalid ? s_axi_if.arlock : '0), clk, !rst_n) + `CALIPTRA_ASSERT_KNOWN(AXI_SUB_X_RVALID , s_axi_if.rvalid , clk, !rst_n) + `CALIPTRA_ASSERT_KNOWN(AXI_SUB_X_RREADY , s_axi_if.rready , clk, !rst_n) + `CALIPTRA_ASSERT_KNOWN(AXI_SUB_X_RDATA , (s_axi_if.rvalid ? s_axi_if.rdata : '0), clk, !rst_n) + `CALIPTRA_ASSERT_KNOWN(AXI_SUB_X_RRESP , (s_axi_if.rvalid ? s_axi_if.rresp : '0), clk, !rst_n) + `CALIPTRA_ASSERT_KNOWN(AXI_SUB_X_RID , (s_axi_if.rvalid ? s_axi_if.rid : '0), clk, !rst_n) + `CALIPTRA_ASSERT_KNOWN(AXI_SUB_X_RUSER , (s_axi_if.rvalid ? s_axi_if.ruser : '0), clk, !rst_n) + `CALIPTRA_ASSERT_KNOWN(AXI_SUB_X_RLAST , (s_axi_if.rvalid ? s_axi_if.rlast : '0), clk, !rst_n) + + // Handshake rules + // Once asserted, each channel's valid signal must remain high until ready is observed. + // This assertion assumes that if this rule is violated it is because of a system reset that + // may or may not have propagated into the axi_sub module yet. So we allow a short delay to + // occur before requiring the reset assertion be observed. + `CALIPTRA_ASSERT (AXI_SUB_AR_HSHAKE_ERR, ((s_axi_if.arvalid && !s_axi_if.arready) ##1 !s_axi_if.arvalid) |-> eventually [0:5] not(rst_n), clk, !rst_n) + `CALIPTRA_ASSERT (AXI_SUB_R_HSHAKE_ERR, ((s_axi_if.rvalid && !s_axi_if.rready ) ##1 !s_axi_if.rvalid ) |-> eventually [0:5] not(rst_n), clk, !rst_n) + + `CALIPTRA_ASSERT_NEVER(ERR_AXI_RD_DROP , dp_rvalid[0] && !dp_rready[0], clk, !rst_n) + `CALIPTRA_ASSERT_NEVER(ERR_AXI_RD_X , dp_rvalid[0] && $isunknown({dp_rdata[0],dp_xfer_ctx[0]}), clk, !rst_n) + // Exclusive access rules: + // - Must have an address that is aligned to burst byte count + // - Byte count must be power of 2 inside 1:128 + // - Max burst length = 16 + `CALIPTRA_ASSERT (ERR_AXI_EX_UNALGN , (s_axi_if.arvalid && s_axi_if.arlock) |-> ~|(s_axi_if.araddr & ((1 << $clog2((1< ((1< (s_axi_if.arlen < 16), clk, !rst_n) + + genvar sva_ii; + generate + if (C_LAT > 0) begin + for (sva_ii = 0; sva_ii < C_LAT-1; sva_ii++) begin + // Last stage should be first to fill and first to go empty + `CALIPTRA_ASSERT_NEVER(ERR_RD_SKD_BUF_FILL, $fell(dp_rready[sva_ii+1]) && !dp_rready[sva_ii], clk, !rst_n) + `CALIPTRA_ASSERT_NEVER(ERR_RD_SKD_BUF_DRAIN, $rose(dp_rready[sva_ii+1]) && dp_rready[sva_ii], clk, !rst_n) + end + end + endgenerate + + + // --------------------------------------- // + // Coverage // + // --------------------------------------- // + + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/axi_sub_wr.sv b/designs/Caliptra/src/caliptra-rtl/axi_sub_wr.sv new file mode 100644 index 0000000..3241225 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/axi_sub_wr.sv @@ -0,0 +1,414 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +// + +// ------------------------------------------------------------- +// AXI Write Subordinate +// ------------------------------------------------------------- +// Description: +// Subordinate to convert AXI protocol writes into internal component accesses +// +// Limitations: +// - Does not consume or store received WUSER, and drives BUSER to all 0's +// (i.e., BUSER is unimplemented) +// - When multiple ID tracking is enabled, write responses are returned in the +// same order they are received, regardless of ID. +// +// ------------------------------------------------------------- + +module axi_sub_wr import axi_pkg::*; #( + parameter AW = 32, // Address Width + parameter DW = 32, // Data Width + BC = DW/8, // Byte Count + BW = $clog2(BC), // Byte count Width + parameter UW = 32, // User Width + parameter IW = 1, // ID Width + ID_NUM = 1 << IW // Don't override + +) ( + input clk, + input rst_n, + + // AXI INF + axi_if.w_sub s_axi_if, + + // Exclusive Access Signals + // Enable exclusive access tracking w/ AxLOCK if EX_EN is set + `ifdef CALIPTRA_AXI_SUB_EX_EN + output logic [ID_NUM-1:0] ex_clr, + input logic [ID_NUM-1:0] ex_active, + input struct packed { + logic [AW-1:0] addr; + logic [AW-1:0] addr_mask; + } [ID_NUM-1:0] ex_ctx, + `endif + + //COMPONENT INF + output logic dv, + output logic [AW-1:0] addr, // Byte address + output logic [UW-1:0] user, + output logic [IW-1:0] id, + output logic [DW-1:0] wdata, // Requires: Component dwidth == AXI dwidth + output logic [BC-1:0] wstrb, // Requires: Component dwidth == AXI dwidth + output logic [2:0] wsize, + output logic last, // Asserted with final 'dv' of a burst + input logic hld, + input logic err + +); + + // --------------------------------------- // + // Imports // + // --------------------------------------- // + `include "caliptra_prim_assert.sv" + + // --------------------------------------- // + // Localparams/Typedefs // + // --------------------------------------- // + + // Transaction context + typedef struct packed { + logic [AW-1:0] addr; + axi_burst_e burst; + logic [2:0] size; + logic [7:0] len; + logic [UW-1:0] user; + logic [IW-1:0] id; + logic lock; + } axi_ctx_t; + + + // --------------------------------------- // + // Signals // + // --------------------------------------- // + + genvar ex; // Exclusive contexts + + logic axi_out_of_rst; + logic axi_awvalid_q; + logic axi_awready_q; + + logic dv_pre; + + // Active transaction signals + // track requests as they are sent to component + axi_ctx_t s_axi_if_ctx; + axi_ctx_t req_ctx; + logic req_valid; + logic req_ready; + `ifdef CALIPTRA_AXI_SUB_EX_EN + logic req_matches_ex; + `endif + axi_ctx_t txn_ctx; + logic [AW-1:0] txn_addr_nxt; + logic txn_active; + logic txn_wvalid; + logic txn_wready; + logic txn_allow; // If an exclusive-write with no match to tracked context, don't complete write to component + logic txn_err; + logic txn_final_beat; + `ifdef CALIPTRA_AXI_SUB_EX_EN + logic [ID_NUM-1:0] txn_ex_match; // Current access matches the flagged exclusive context + // Possible for multiple bits to be set -- match of multiple contexts + `endif + + // Response Pipeline signals + logic rp_valid; + logic rp_ready; + axi_resp_e rp_resp; + logic [IW-1:0] rp_id; + + + // --------------------------------------- // + // Address Request I/F // + // --------------------------------------- // + + always_ff@(posedge clk or negedge rst_n) begin + if (!rst_n) begin + axi_out_of_rst <= 1'b0; + end + else begin + axi_out_of_rst <= 1'b1; + end + end + assign axi_awvalid_q = s_axi_if.awvalid & axi_out_of_rst; + assign s_axi_if.awready = axi_awready_q & axi_out_of_rst; + + assign s_axi_if_ctx.addr = s_axi_if.awaddr[AW-1:0] ; + assign s_axi_if_ctx.burst = axi_burst_e'(s_axi_if.awburst); + assign s_axi_if_ctx.size = s_axi_if.awsize ; + assign s_axi_if_ctx.len = s_axi_if.awlen ; + assign s_axi_if_ctx.user = s_axi_if.awuser ; + assign s_axi_if_ctx.id = s_axi_if.awid ; + `ifdef CALIPTRA_AXI_SUB_EX_EN + assign s_axi_if_ctx.lock = s_axi_if.awlock; + `else + assign s_axi_if_ctx.lock = 1'b0; + `endif + + // skidbuffer instance to pipeline request context from AXI. + skidbuffer #( + .OPT_LOWPOWER (0 ), + .OPT_OUTREG (0 ), + // + .OPT_PASSTHROUGH(0 ), + .DW ($bits(axi_ctx_t)) + ) i_req_skd ( + .i_clk (clk ), + .i_reset(rst_n ), + .i_valid(axi_awvalid_q ), + .o_ready(axi_awready_q ), + .i_data (s_axi_if_ctx ), + .o_valid(req_valid ), + .i_ready(req_ready ), + .o_data (req_ctx ) + ); + + // Only accept request when we have a guaranteed slot in the response buffer + // to put the response + assign req_ready = (!txn_active || (txn_final_beat && !s_axi_if.bvalid)) && rp_ready; + + // Indicates there are still reqs to be issued towards component. + // This active signal deasserts after final dv to component + always_ff@(posedge clk or negedge rst_n) begin + if (!rst_n) begin + txn_active <= 1'b0; + end + else if (req_valid && req_ready) begin + txn_active <= 1'b1; + end + else if (txn_final_beat) begin + txn_active <= 1'b0; + end + else begin + txn_active <= txn_active; + end + end + + + `ifdef CALIPTRA_AXI_SUB_EX_EN + assign req_matches_ex = (req_ctx.addr & ex_ctx[req_ctx.id].addr_mask) == ex_ctx[req_ctx.id].addr; + `else + assign txn_allow = 1'b1; + `endif + + always_ff@(posedge clk or negedge rst_n) begin + if (!rst_n) begin + txn_ctx <= '{default:0, burst:AXI_BURST_FIXED}; + `ifdef CALIPTRA_AXI_SUB_EX_EN + txn_allow <= 0; + `endif + txn_err <= 1'b0; + end + else if (req_valid && req_ready) begin + txn_ctx.addr <= req_ctx.addr; + txn_ctx.burst <= req_ctx.burst; + txn_ctx.size <= req_ctx.size; + txn_ctx.len <= req_ctx.len ; + txn_ctx.user <= req_ctx.user; + txn_ctx.id <= req_ctx.id ; + txn_ctx.lock <= req_ctx.lock; + `ifdef CALIPTRA_AXI_SUB_EX_EN + txn_allow <= !req_ctx.lock || (ex_active[req_ctx.id] && req_matches_ex); + `endif + txn_err <= 1'b0; + end + else if (dv && !hld) begin + txn_ctx.addr <= txn_addr_nxt; + txn_ctx.burst <= txn_ctx.burst; + txn_ctx.size <= txn_ctx.size; + txn_ctx.len <= txn_ctx.len ; + txn_ctx.user <= txn_ctx.user; + txn_ctx.id <= txn_ctx.id ; + txn_ctx.lock <= txn_ctx.lock; + txn_err <= txn_err || err; + end + else begin + txn_ctx <= txn_ctx; + txn_err <= txn_err; + end + end + + // Asserts on the final COMPONENT INF beat, which means data does not + // arrive at endpoint until after C_LAT clocks + assign txn_final_beat = dv_pre && (!txn_allow || !hld) && last; + + + // --------------------------------------- // + // Address Calculations // + // --------------------------------------- // + // Force aligned address to component + assign addr = {txn_ctx.addr[AW-1:BW],BW'(0)}; + assign user = txn_ctx.user; + assign id = txn_ctx.id; + assign wsize = txn_ctx.size; + + // Use full address to calculate next address (in case of AxSIZE < data width) + axi_addr #( + .AW (AW), + .DW (DW) + ) i_axi_addr ( + .i_last_addr(txn_ctx.addr ), + .i_size (txn_ctx.size ), // 1b, 2b, 4b, 8b, etc + .i_burst (txn_ctx.burst), // fixed, incr, wrap, reserved + .i_len (txn_ctx.len ), + .o_next_addr(txn_addr_nxt ) + ); + + + // --------------------------------------- // + // Exclusive Access Tracking // + // --------------------------------------- // + + `ifdef CALIPTRA_AXI_SUB_EX_EN + generate + for (ex=0; ex < ID_NUM; ex++) begin: EX_AXS_TRACKER + logic [AW-1:0] addr_ex_algn; + + // Component address aligned to exclusive tracking context + // Don't use aligned 'addr' signal, because exclusive access alignment may + // be smaller than component inf (since single-byte exclusive access is legal) + assign addr_ex_algn = txn_ctx.addr & ex_ctx[ex].addr_mask; + + // Match on each beat in case a burst transaction only overlaps + // the exclusive context partially + assign txn_ex_match[ex] = (addr_ex_algn == ex_ctx[ex].addr); + + end: EX_AXS_TRACKER + endgenerate + + // Only clear the context when a write goes through to dest - meaining dv, not dv_pre + always_ff@(posedge clk or negedge rst_n) begin + if (!rst_n) + ex_clr <= ID_NUM'(0); + else if (dv && !hld) + ex_clr <= ex_active & txn_ex_match; // Could have multiple set bits + else + ex_clr <= ID_NUM'(0); + end + `endif + + + // --------------------------------------- // + // Data/Response // + // --------------------------------------- // + + assign txn_wvalid = s_axi_if.wvalid && txn_active; + assign s_axi_if.wready = txn_wready && txn_active; + + // skidbuffer instance to pipeline data payload from AXI. + skidbuffer #( + .OPT_LOWPOWER (0 ), + .OPT_OUTREG (0 ), + // + .OPT_PASSTHROUGH(0 ), + .DW (DW + BC + 1) + ) i_dp_skd ( + .i_clk (clk ), + .i_reset(rst_n ), + .i_valid(txn_wvalid ), + .o_ready(txn_wready ), + .i_data ({s_axi_if.wdata, + s_axi_if.wstrb, + s_axi_if.wlast}), + .o_valid(dv_pre ), + .i_ready(!hld ), + .o_data ({wdata, + wstrb, + last } ) + ); + + assign dv = dv_pre && txn_allow; + + // Registered skidbuffer to pipeline response signals. + // Skid buffer captures any response transfer if the + // register output is busy with a previous response and is + // stalled. + // There is guaranteed to be space in the skid buffer because new + // requests are stalled (AWREADY=0) until this buffer is ready. + assign rp_valid = txn_final_beat; + assign rp_resp = txn_allow && (txn_err || err) ? AXI_RESP_SLVERR : + txn_allow && txn_ctx.lock ? AXI_RESP_EXOKAY : + AXI_RESP_OKAY; + assign rp_id = txn_ctx.id; + + skidbuffer #( + .OPT_LOWPOWER (0 ), + .OPT_OUTREG (1 ), + // + .OPT_PASSTHROUGH(0 ), + .DW (IW + $bits(axi_resp_e)) + ) i_rsp_skd ( + .i_clk (clk ), + .i_reset(rst_n ), + .i_valid(rp_valid ), + .o_ready(rp_ready ), + .i_data ({rp_resp, + rp_id} ), + .o_valid(s_axi_if.bvalid ), + .i_ready(s_axi_if.bready ), + .o_data ({s_axi_if.bresp, + s_axi_if.bid} ) + ); + + assign s_axi_if.buser = '0; + + + // --------------------------------------- // + // Formal Properties // + // --------------------------------------- // + `CALIPTRA_ASSERT_KNOWN(AXI_SUB_X_AWVALID, s_axi_if.awvalid, clk, !rst_n) + `CALIPTRA_ASSERT_KNOWN(AXI_SUB_X_AWREADY, s_axi_if.awready, clk, !rst_n) + `CALIPTRA_ASSERT_KNOWN(AXI_SUB_X_AWADDR , (s_axi_if.awvalid ? s_axi_if.awaddr : '0), clk, !rst_n) + `CALIPTRA_ASSERT_KNOWN(AXI_SUB_X_AWBURST, (s_axi_if.awvalid ? s_axi_if.awburst : '0), clk, !rst_n) + `CALIPTRA_ASSERT_KNOWN(AXI_SUB_X_AWSIZE , (s_axi_if.awvalid ? s_axi_if.awsize : '0), clk, !rst_n) + `CALIPTRA_ASSERT_KNOWN(AXI_SUB_X_AWLEN , (s_axi_if.awvalid ? s_axi_if.awlen : '0), clk, !rst_n) + `CALIPTRA_ASSERT_KNOWN(AXI_SUB_X_AWUSER , (s_axi_if.awvalid ? s_axi_if.awuser : '0), clk, !rst_n) + `CALIPTRA_ASSERT_KNOWN(AXI_SUB_X_AWID , (s_axi_if.awvalid ? s_axi_if.awid : '0), clk, !rst_n) + `CALIPTRA_ASSERT_KNOWN(AXI_SUB_X_AWLOCK , (s_axi_if.awvalid ? s_axi_if.awlock : '0), clk, !rst_n) + `CALIPTRA_ASSERT_KNOWN(AXI_SUB_X_WVALID , s_axi_if.wvalid , clk, !rst_n) + `CALIPTRA_ASSERT_KNOWN(AXI_SUB_X_WREADY , s_axi_if.wready , clk, !rst_n) + `CALIPTRA_ASSERT_KNOWN(AXI_SUB_X_WDATA , (s_axi_if.wvalid ? s_axi_if.wdata : '0), clk, !rst_n) + `CALIPTRA_ASSERT_KNOWN(AXI_SUB_X_WSTRB , (s_axi_if.wvalid ? s_axi_if.wstrb : '0), clk, !rst_n) + `CALIPTRA_ASSERT_KNOWN(AXI_SUB_X_WUSER , (s_axi_if.wvalid ? s_axi_if.wuser : '0), clk, !rst_n) + `CALIPTRA_ASSERT_KNOWN(AXI_SUB_X_WLAST , (s_axi_if.wvalid ? s_axi_if.wlast : '0), clk, !rst_n) + `CALIPTRA_ASSERT_KNOWN(AXI_SUB_X_BVALID , s_axi_if.bvalid , clk, !rst_n) + `CALIPTRA_ASSERT_KNOWN(AXI_SUB_X_BREADY , s_axi_if.bready , clk, !rst_n) + `CALIPTRA_ASSERT_KNOWN(AXI_SUB_X_BRESP , (s_axi_if.bvalid ? s_axi_if.bresp : '0), clk, !rst_n) + `CALIPTRA_ASSERT_KNOWN(AXI_SUB_X_BID , (s_axi_if.bvalid ? s_axi_if.bid : '0), clk, !rst_n) + `CALIPTRA_ASSERT_KNOWN(AXI_SUB_X_BUSER , (s_axi_if.bvalid ? s_axi_if.buser : '0), clk, !rst_n) + + // Handshake rules + // Once asserted, each channel's valid signal must remain high until ready is observed. + // This assertion assumes that if this rule is violated it is because of a system reset that + // may or may not have propagated into the axi_sub module yet. So we allow a short delay to + // occur before requiring the reset assertion be observed. + `CALIPTRA_ASSERT (AXI_SUB_AW_HSHAKE_ERR, ((s_axi_if.awvalid && !s_axi_if.awready) ##1 !s_axi_if.awvalid) |-> eventually [0:5] not(rst_n), clk, !rst_n) + `CALIPTRA_ASSERT (AXI_SUB_W_HSHAKE_ERR, ((s_axi_if.wvalid && !s_axi_if.wready ) ##1 !s_axi_if.wvalid ) |-> eventually [0:5] not(rst_n), clk, !rst_n) + `CALIPTRA_ASSERT (AXI_SUB_B_HSHAKE_ERR, ((s_axi_if.bvalid && !s_axi_if.bready ) ##1 !s_axi_if.bvalid ) |-> eventually [0:5] not(rst_n), clk, !rst_n) + + // Exclusive access rules: + // - Must have an address that is aligned to burst byte count + // - Byte count must be power of 2 inside 1:128 + // - Max burst length = 16 + `CALIPTRA_ASSERT (ERR_AXI_EX_UNALGN , (s_axi_if.awvalid && s_axi_if.awlock) |-> ~|(s_axi_if.awaddr & ((1 << $clog2((1< ((1< (s_axi_if.awlen < 16), clk, !rst_n) + + + // --------------------------------------- // + // Coverage // + // --------------------------------------- // + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/beh_lib.sv b/designs/Caliptra/src/caliptra-rtl/beh_lib.sv new file mode 100644 index 0000000..689f557 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/beh_lib.sv @@ -0,0 +1,841 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2020 Western Digital Corporation or its affiliates. +// +// 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. + +// all flops call the rvdff flop + + +module rvdff #( parameter WIDTH=1, SHORT=0 ) + ( + input logic [WIDTH-1:0] din, + input logic clk, + input logic rst_l, + + output logic [WIDTH-1:0] dout + ); + +if (SHORT == 1) begin + assign dout = din; +end +else begin +`ifdef RV_CLOCKGATE + always @(posedge tb_top.clk) begin + #0 $strobe("CG: %0t %m din %x dout %x clk %b width %d",$time,din,dout,clk,WIDTH); + end +`endif + + always_ff @(posedge clk or negedge rst_l) begin + if (rst_l == 0) + dout[WIDTH-1:0] <= 0; + else + dout[WIDTH-1:0] <= din[WIDTH-1:0]; + end + +end +endmodule + +// rvdff with 2:1 input mux to flop din iff sel==1 +module rvdffs #( parameter WIDTH=1, SHORT=0 ) + ( + input logic [WIDTH-1:0] din, + input logic en, + input logic clk, + input logic rst_l, + output logic [WIDTH-1:0] dout + ); + +if (SHORT == 1) begin : genblock + assign dout = din; +end +else begin : genblock + rvdff #(WIDTH) dffs (.din((en) ? din[WIDTH-1:0] : dout[WIDTH-1:0]), .*); +end + +endmodule + +// rvdff with en and clear +module rvdffsc #( parameter WIDTH=1, SHORT=0 ) + ( + input logic [WIDTH-1:0] din, + input logic en, + input logic clear, + input logic clk, + input logic rst_l, + output logic [WIDTH-1:0] dout + ); + + logic [WIDTH-1:0] din_new; +if (SHORT == 1) begin : genblock + assign dout = din; +end +else begin : genblock + assign din_new = {WIDTH{~clear}} & (en ? din[WIDTH-1:0] : dout[WIDTH-1:0]); + rvdff #(WIDTH) dffsc (.din(din_new[WIDTH-1:0]), .*); +end +endmodule + +// _fpga versions +module rvdff_fpga #( parameter WIDTH=1, SHORT=0 ) + ( + input logic [WIDTH-1:0] din, + input logic clk, + input logic clken, + input logic rawclk, + input logic rst_l, + + output logic [WIDTH-1:0] dout + ); + +if (SHORT == 1) begin : genblock + assign dout = din; +end +else begin : genblock + `ifdef RV_FPGA_OPTIMIZE + rvdffs #(WIDTH) dffs (.clk(rawclk), .en(clken), .*); +`else + rvdff #(WIDTH) dff (.*); +`endif +end +endmodule + +// rvdff with 2:1 input mux to flop din iff sel==1 +module rvdffs_fpga #( parameter WIDTH=1, SHORT=0 ) + ( + input logic [WIDTH-1:0] din, + input logic en, + input logic clk, + input logic clken, + input logic rawclk, + input logic rst_l, + + output logic [WIDTH-1:0] dout + ); + +if (SHORT == 1) begin : genblock + assign dout = din; +end +else begin : genblock +`ifdef RV_FPGA_OPTIMIZE + rvdffs #(WIDTH) dffs (.clk(rawclk), .en(clken & en), .*); +`else + rvdffs #(WIDTH) dffs (.*); +`endif +end + +endmodule + +// rvdff with en and clear +module rvdffsc_fpga #( parameter WIDTH=1, SHORT=0 ) + ( + input logic [WIDTH-1:0] din, + input logic en, + input logic clear, + input logic clk, + input logic clken, + input logic rawclk, + input logic rst_l, + + output logic [WIDTH-1:0] dout + ); + + logic [WIDTH-1:0] din_new; +if (SHORT == 1) begin : genblock + assign dout = din; +end +else begin : genblock +`ifdef RV_FPGA_OPTIMIZE + rvdffs #(WIDTH) dffs (.clk(rawclk), .din(din[WIDTH-1:0] & {WIDTH{~clear}}),.en((en | clear) & clken), .*); +`else + rvdffsc #(WIDTH) dffsc (.*); +`endif +end +endmodule + + +module rvdffe #( parameter WIDTH=1, SHORT=0, OVERRIDE=0 ) + ( + input logic [WIDTH-1:0] din, + input logic en, + input logic clk, + input logic rst_l, + // Excluding scan_mode from coverage as its usage is determined by the integrator of the VeeR core. + /*pragma coverage off*/ + input logic scan_mode, + /*pragma coverage on*/ + output logic [WIDTH-1:0] dout + ); + + logic l1clk; + +if (SHORT == 1) begin : genblock + if (1) begin : genblock + assign dout = din; + end +end +else begin : genblock + +`ifndef RV_PHYSICAL + if (WIDTH >= 8 || OVERRIDE==1) begin: genblock +`endif + +`ifdef RV_FPGA_OPTIMIZE + rvdffs #(WIDTH) dff ( .* ); +`else + rvclkhdr clkhdr ( .* ); + rvdff #(WIDTH) dff (.*, .clk(l1clk)); +`endif + +`ifndef RV_PHYSICAL + end + else + $error("%m: rvdffe must be WIDTH >= 8"); +`endif +end // else: !if(SHORT == 1) + +endmodule // rvdffe + + +module rvdffpcie #( parameter WIDTH=31 ) + ( + input logic [WIDTH-1:0] din, + input logic clk, + input logic rst_l, + input logic en, + // Excluding scan_mode from coverage as its usage is determined by the integrator of the VeeR core. + /*pragma coverage off*/ + input logic scan_mode, + /*pragma coverage on*/ + output logic [WIDTH-1:0] dout + ); + + + +`ifndef RV_PHYSICAL + if (WIDTH == 31) begin: genblock +`endif + +`ifdef RV_FPGA_OPTIMIZE + rvdffs #(WIDTH) dff ( .* ); +`else + + rvdfflie #(.WIDTH(WIDTH), .LEFT(19)) dff (.*); + +`endif + +`ifndef RV_PHYSICAL + end + else + $error("%m: rvdffpcie width must be 31"); +`endif +endmodule + +// format: { LEFT, EXTRA } +// LEFT # of bits will be done with rvdffie, all else EXTRA with rvdffe +module rvdfflie #( parameter WIDTH=16, LEFT=8 ) + ( + input logic [WIDTH-1:0] din, + input logic clk, + input logic rst_l, + input logic en, + // Excluding scan_mode from coverage as its usage is determined by the integrator of the VeeR core. + /*pragma coverage off*/ + input logic scan_mode, + /*pragma coverage on*/ + output logic [WIDTH-1:0] dout + ); + + localparam EXTRA = WIDTH-LEFT; + + + + + + + + localparam LMSB = WIDTH-1; + localparam LLSB = LMSB-LEFT+1; + localparam XMSB = LLSB-1; + localparam XLSB = LLSB-EXTRA; + + +`ifndef RV_PHYSICAL + if (WIDTH >= 16 && LEFT >= 8 && EXTRA >= 8) begin: genblock +`endif + +`ifdef RV_FPGA_OPTIMIZE + rvdffs #(WIDTH) dff ( .* ); +`else + + rvdffiee #(LEFT) dff_left (.*, .din(din[LMSB:LLSB]), .dout(dout[LMSB:LLSB])); + + + rvdffe #(EXTRA) dff_extra (.*, .din(din[XMSB:XLSB]), .dout(dout[XMSB:XLSB])); + + + + +`endif + +`ifndef RV_PHYSICAL + end + else + $error("%m: rvdfflie musb be WIDTH >= 16 && LEFT >= 8 && EXTRA >= 8"); +`endif +endmodule + + + + +// special power flop for predict packet +// format: { LEFT, RIGHT==31 } +// LEFT # of bits will be done with rvdffe; RIGHT is enabled by LEFT[LSB] & en +module rvdffppe #( parameter integer WIDTH = 39 ) + ( + input logic [WIDTH-1:0] din, + input logic clk, + input logic rst_l, + input logic en, + // Excluding scan_mode from coverage as its usage is determined by the integrator of the VeeR core. + /*pragma coverage off*/ + input logic scan_mode, + /*pragma coverage on*/ + output logic [WIDTH-1:0] dout + ); + + localparam integer RIGHT = 31; + localparam integer LEFT = WIDTH - RIGHT; + + localparam integer LMSB = WIDTH-1; + localparam integer LLSB = LMSB-LEFT+1; + localparam integer RMSB = LLSB-1; + localparam integer RLSB = LLSB-RIGHT; + + +`ifndef RV_PHYSICAL + if (WIDTH>=32 && LEFT>=8 && RIGHT>=8) begin: genblock +`endif + +`ifdef RV_FPGA_OPTIMIZE + rvdffs #(WIDTH) dff ( .* ); +`else + rvdffe #(LEFT) dff_left (.*, .din(din[LMSB:LLSB]), .dout(dout[LMSB:LLSB])); + + rvdffe #(RIGHT) dff_right (.*, .din(din[RMSB:RLSB]), .dout(dout[RMSB:RLSB]), .en(en & din[LLSB])); // qualify with pret + + +`endif + +`ifndef RV_PHYSICAL + end + else + $error("%m: must be WIDTH>=32 && LEFT>=8 && RIGHT>=8"); +`endif +endmodule + + + + +module rvdffie #( parameter WIDTH=1, OVERRIDE=0 ) + ( + input logic [WIDTH-1:0] din, + + input logic clk, + input logic rst_l, + // Excluding scan_mode from coverage as its usage is determined by the integrator of the VeeR core. + /*pragma coverage off*/ + input logic scan_mode, + /*pragma coverage on*/ + output logic [WIDTH-1:0] dout + ); + + logic l1clk; + logic en; + + + + + + + + +`ifndef RV_PHYSICAL + if (WIDTH >= 8 || OVERRIDE==1) begin: genblock +`endif + + assign en = |(din ^ dout); + +`ifdef RV_FPGA_OPTIMIZE + rvdffs #(WIDTH) dff ( .* ); +`else + rvclkhdr clkhdr ( .* ); + rvdff #(WIDTH) dff (.*, .clk(l1clk)); +`endif + +`ifndef RV_PHYSICAL + end + else + $error("%m: rvdffie must be WIDTH >= 8"); +`endif + + +endmodule + +// ie flop but it has an .en input +module rvdffiee #( parameter WIDTH=1, OVERRIDE=0 ) + ( + input logic [WIDTH-1:0] din, + + input logic clk, + input logic rst_l, + // Excluding scan_mode from coverage as its usage is determined by the integrator of the VeeR core. + /*pragma coverage off*/ + input logic scan_mode, + /*pragma coverage on*/ + input logic en, + output logic [WIDTH-1:0] dout + ); + + logic l1clk; + logic final_en; + +`ifndef RV_PHYSICAL + if (WIDTH >= 8 || OVERRIDE==1) begin: genblock +`endif + + assign final_en = (|(din ^ dout)) & en; + +`ifdef RV_FPGA_OPTIMIZE + rvdffs #(WIDTH) dff ( .*, .en(final_en) ); +`else + rvdffe #(WIDTH) dff (.*, .en(final_en)); +`endif + +`ifndef RV_PHYSICAL + end + else + $error("%m: rvdffie width must be >= 8"); +`endif + +endmodule + + + +module rvsyncss #(parameter WIDTH = 251) + ( + input logic clk, + input logic rst_l, + input logic [WIDTH-1:0] din, + output logic [WIDTH-1:0] dout + ); + + logic [WIDTH-1:0] din_ff1; + + rvdff #(WIDTH) sync_ff1 (.*, .din (din[WIDTH-1:0]), .dout(din_ff1[WIDTH-1:0])); + rvdff #(WIDTH) sync_ff2 (.*, .din (din_ff1[WIDTH-1:0]), .dout(dout[WIDTH-1:0])); + +endmodule // rvsyncss + +module rvsyncss_fpga #(parameter WIDTH = 251) + ( + input logic gw_clk, + input logic rawclk, + input logic clken, + input logic rst_l, + input logic [WIDTH-1:0] din, + output logic [WIDTH-1:0] dout + ); + + logic [WIDTH-1:0] din_ff1; + + rvdff_fpga #(WIDTH) sync_ff1 (.*, .clk(gw_clk), .rawclk(rawclk), .clken(clken), .din (din[WIDTH-1:0]), .dout(din_ff1[WIDTH-1:0])); + rvdff_fpga #(WIDTH) sync_ff2 (.*, .clk(gw_clk), .rawclk(rawclk), .clken(clken), .din (din_ff1[WIDTH-1:0]), .dout(dout[WIDTH-1:0])); + +endmodule // rvsyncss + +module rvlsadder + ( + input logic [31:0] rs1, + input logic [11:0] offset, + + output logic [31:0] dout + ); + + logic cout; + logic sign; + + logic [31:12] rs1_inc; + logic [31:12] rs1_dec; + + assign {cout,dout[11:0]} = {1'b0,rs1[11:0]} + {1'b0,offset[11:0]}; + + assign rs1_inc[31:12] = rs1[31:12] + 1; + + assign rs1_dec[31:12] = rs1[31:12] - 1; + + assign sign = offset[11]; + + assign dout[31:12] = ({20{ sign ^~ cout}} & rs1[31:12]) | + ({20{ ~sign & cout}} & rs1_inc[31:12]) | + ({20{ sign & ~cout}} & rs1_dec[31:12]); + +endmodule // rvlsadder + +// assume we only maintain pc[31:1] in the pipe + +module rvbradder + ( + input [31:1] pc, + input [12:1] offset, + + output [31:1] dout + ); + + logic cout; + logic sign; + + logic [31:13] pc_inc; + logic [31:13] pc_dec; + + assign {cout,dout[12:1]} = {1'b0,pc[12:1]} + {1'b0,offset[12:1]}; + + assign pc_inc[31:13] = pc[31:13] + 1; + + assign pc_dec[31:13] = pc[31:13] - 1; + + assign sign = offset[12]; + + + assign dout[31:13] = ({19{ sign ^~ cout}} & pc[31:13]) | + ({19{ ~sign & cout}} & pc_inc[31:13]) | + ({19{ sign & ~cout}} & pc_dec[31:13]); + + +endmodule // rvbradder + + +// 2s complement circuit +module rvtwoscomp #( parameter WIDTH=32 ) + ( + input logic [WIDTH-1:0] din, + + output logic [WIDTH-1:0] dout + ); + + logic [WIDTH-1:1] dout_temp; // holding for all other bits except for the lsb. LSB is always din + + genvar i; + + for ( i = 1; i < WIDTH; i++ ) begin : flip_after_first_one + assign dout_temp[i] = (|din[i-1:0]) ? ~din[i] : din[i]; + end : flip_after_first_one + + assign dout[WIDTH-1:0] = { dout_temp[WIDTH-1:1], din[0] }; + +endmodule // 2'scomp + +// find first +module rvfindfirst1 #( parameter WIDTH=32, SHIFT=$clog2(WIDTH) ) + ( + input logic [WIDTH-1:0] din, + + output logic [SHIFT-1:0] dout + ); + logic done; + + always_comb begin + dout[SHIFT-1:0] = {SHIFT{1'b0}}; + done = 1'b0; + + for ( int i = WIDTH-1; i > 0; i-- ) begin : find_first_one + done |= din[i]; + dout[SHIFT-1:0] += done ? 1'b0 : 1'b1; + end : find_first_one + end +endmodule // rvfindfirst1 + +module rvfindfirst1hot #( parameter WIDTH=32 ) + ( + input logic [WIDTH-1:0] din, + + output logic [WIDTH-1:0] dout + ); + logic done; + + always_comb begin + dout[WIDTH-1:0] = {WIDTH{1'b0}}; + done = 1'b0; + for ( int i = 0; i < WIDTH; i++ ) begin : find_first_one + dout[i] = ~done & din[i]; + done |= din[i]; + end : find_first_one + end +endmodule // rvfindfirst1hot + +// mask and match function matches bits after finding the first 0 position +// find first starting from LSB. Skip that location and match the rest of the bits +module rvmaskandmatch #( parameter WIDTH=32 ) + ( + input logic [WIDTH-1:0] mask, // this will have the mask in the lower bit positions + input logic [WIDTH-1:0] data, // this is what needs to be matched on the upper bits with the mask's upper bits + input logic masken, // when 1 : do mask. 0 : full match + output logic match + ); + + logic [WIDTH-1:0] matchvec; + logic masken_or_fullmask; + + assign masken_or_fullmask = masken & ~(&mask[WIDTH-1:0]); + + assign matchvec[0] = masken_or_fullmask | (mask[0] == data[0]); + genvar i; + + for ( i = 1; i < WIDTH; i++ ) begin : match_after_first_zero + assign matchvec[i] = (&mask[i-1:0] & masken_or_fullmask) ? 1'b1 : (mask[i] == data[i]); + end : match_after_first_zero + + assign match = &matchvec[WIDTH-1:0]; // all bits either matched or were masked off + +endmodule // rvmaskandmatch + + + + +// Check if the S_ADDR <= addr < E_ADDR +module rvrangecheck #(CCM_SADR = 32'h0, + CCM_SIZE = 128) ( + input logic [31:0] addr, // Address to be checked for range + output logic in_range, // S_ADDR <= start_addr < E_ADDR + output logic in_region +); + + localparam REGION_BITS = 4; + localparam MASK_BITS = 10 + $clog2(CCM_SIZE); + + logic [31:0] start_addr; + logic [3:0] region; + + assign start_addr[31:0] = CCM_SADR; + assign region[REGION_BITS-1:0] = start_addr[31:(32-REGION_BITS)]; + + assign in_region = (addr[31:(32-REGION_BITS)] == region[REGION_BITS-1:0]); + if (CCM_SIZE == 48) + assign in_range = (addr[31:MASK_BITS] == start_addr[31:MASK_BITS]) & ~(&addr[MASK_BITS-1 : MASK_BITS-2]); + else + assign in_range = (addr[31:MASK_BITS] == start_addr[31:MASK_BITS]); + +endmodule // rvrangechecker + +// 16 bit even parity generator +module rveven_paritygen #(WIDTH = 16) ( + input logic [WIDTH-1:0] data_in, // Data + output logic parity_out // generated even parity + ); + + assign parity_out = ^(data_in[WIDTH-1:0]) ; + +endmodule // rveven_paritygen + +module rveven_paritycheck #(WIDTH = 16) ( + input logic [WIDTH-1:0] data_in, // Data + input logic parity_in, + output logic parity_err // Parity error + ); + + assign parity_err = ^(data_in[WIDTH-1:0]) ^ parity_in ; + +endmodule // rveven_paritycheck + +module rvecc_encode ( + input [31:0] din, + output [6:0] ecc_out + ); +logic [5:0] ecc_out_temp; + + assign ecc_out_temp[0] = din[0]^din[1]^din[3]^din[4]^din[6]^din[8]^din[10]^din[11]^din[13]^din[15]^din[17]^din[19]^din[21]^din[23]^din[25]^din[26]^din[28]^din[30]; + assign ecc_out_temp[1] = din[0]^din[2]^din[3]^din[5]^din[6]^din[9]^din[10]^din[12]^din[13]^din[16]^din[17]^din[20]^din[21]^din[24]^din[25]^din[27]^din[28]^din[31]; + assign ecc_out_temp[2] = din[1]^din[2]^din[3]^din[7]^din[8]^din[9]^din[10]^din[14]^din[15]^din[16]^din[17]^din[22]^din[23]^din[24]^din[25]^din[29]^din[30]^din[31]; + assign ecc_out_temp[3] = din[4]^din[5]^din[6]^din[7]^din[8]^din[9]^din[10]^din[18]^din[19]^din[20]^din[21]^din[22]^din[23]^din[24]^din[25]; + assign ecc_out_temp[4] = din[11]^din[12]^din[13]^din[14]^din[15]^din[16]^din[17]^din[18]^din[19]^din[20]^din[21]^din[22]^din[23]^din[24]^din[25]; + assign ecc_out_temp[5] = din[26]^din[27]^din[28]^din[29]^din[30]^din[31]; + + assign ecc_out[6:0] = {(^din[31:0])^(^ecc_out_temp[5:0]),ecc_out_temp[5:0]}; + +endmodule // rvecc_encode + +module rvecc_decode ( + input en, + input [31:0] din, + input [6:0] ecc_in, + input sed_ded, // only do detection and no correction. Used for the I$ + output [31:0] dout, + output [6:0] ecc_out, + output single_ecc_error, + output double_ecc_error + + ); + + logic [6:0] ecc_check; + logic [38:0] error_mask; + logic [38:0] din_plus_parity, dout_plus_parity; + + // Generate the ecc bits + assign ecc_check[0] = ecc_in[0]^din[0]^din[1]^din[3]^din[4]^din[6]^din[8]^din[10]^din[11]^din[13]^din[15]^din[17]^din[19]^din[21]^din[23]^din[25]^din[26]^din[28]^din[30]; + assign ecc_check[1] = ecc_in[1]^din[0]^din[2]^din[3]^din[5]^din[6]^din[9]^din[10]^din[12]^din[13]^din[16]^din[17]^din[20]^din[21]^din[24]^din[25]^din[27]^din[28]^din[31]; + assign ecc_check[2] = ecc_in[2]^din[1]^din[2]^din[3]^din[7]^din[8]^din[9]^din[10]^din[14]^din[15]^din[16]^din[17]^din[22]^din[23]^din[24]^din[25]^din[29]^din[30]^din[31]; + assign ecc_check[3] = ecc_in[3]^din[4]^din[5]^din[6]^din[7]^din[8]^din[9]^din[10]^din[18]^din[19]^din[20]^din[21]^din[22]^din[23]^din[24]^din[25]; + assign ecc_check[4] = ecc_in[4]^din[11]^din[12]^din[13]^din[14]^din[15]^din[16]^din[17]^din[18]^din[19]^din[20]^din[21]^din[22]^din[23]^din[24]^din[25]; + assign ecc_check[5] = ecc_in[5]^din[26]^din[27]^din[28]^din[29]^din[30]^din[31]; + + // This is the parity bit + assign ecc_check[6] = ((^din[31:0])^(^ecc_in[6:0])) & ~sed_ded; + + assign single_ecc_error = en & (ecc_check[6:0] != 0) & ecc_check[6]; // this will never be on for sed_ded + assign double_ecc_error = en & (ecc_check[6:0] != 0) & ~ecc_check[6]; // all errors in the sed_ded case will be recorded as DE + + // Generate the mask for error correctiong + for (genvar i=1; i<40; i++) begin + assign error_mask[i-1] = (ecc_check[5:0] == i); + end + + // Generate the corrected data + assign din_plus_parity[38:0] = {ecc_in[6], din[31:26], ecc_in[5], din[25:11], ecc_in[4], din[10:4], ecc_in[3], din[3:1], ecc_in[2], din[0], ecc_in[1:0]}; + + assign dout_plus_parity[38:0] = single_ecc_error ? (error_mask[38:0] ^ din_plus_parity[38:0]) : din_plus_parity[38:0]; + assign dout[31:0] = {dout_plus_parity[37:32], dout_plus_parity[30:16], dout_plus_parity[14:8], dout_plus_parity[6:4], dout_plus_parity[2]}; + assign ecc_out[6:0] = {(dout_plus_parity[38] ^ (ecc_check[6:0] == 7'b1000000)), dout_plus_parity[31], dout_plus_parity[15], dout_plus_parity[7], dout_plus_parity[3], dout_plus_parity[1:0]}; + +endmodule // rvecc_decode + +module rvecc_encode_64 ( + input [63:0] din, + output [6:0] ecc_out + ); + assign ecc_out[0] = din[0]^din[1]^din[3]^din[4]^din[6]^din[8]^din[10]^din[11]^din[13]^din[15]^din[17]^din[19]^din[21]^din[23]^din[25]^din[26]^din[28]^din[30]^din[32]^din[34]^din[36]^din[38]^din[40]^din[42]^din[44]^din[46]^din[48]^din[50]^din[52]^din[54]^din[56]^din[57]^din[59]^din[61]^din[63]; + + assign ecc_out[1] = din[0]^din[2]^din[3]^din[5]^din[6]^din[9]^din[10]^din[12]^din[13]^din[16]^din[17]^din[20]^din[21]^din[24]^din[25]^din[27]^din[28]^din[31]^din[32]^din[35]^din[36]^din[39]^din[40]^din[43]^din[44]^din[47]^din[48]^din[51]^din[52]^din[55]^din[56]^din[58]^din[59]^din[62]^din[63]; + + assign ecc_out[2] = din[1]^din[2]^din[3]^din[7]^din[8]^din[9]^din[10]^din[14]^din[15]^din[16]^din[17]^din[22]^din[23]^din[24]^din[25]^din[29]^din[30]^din[31]^din[32]^din[37]^din[38]^din[39]^din[40]^din[45]^din[46]^din[47]^din[48]^din[53]^din[54]^din[55]^din[56]^din[60]^din[61]^din[62]^din[63]; + + assign ecc_out[3] = din[4]^din[5]^din[6]^din[7]^din[8]^din[9]^din[10]^din[18]^din[19]^din[20]^din[21]^din[22]^din[23]^din[24]^din[25]^din[33]^din[34]^din[35]^din[36]^din[37]^din[38]^din[39]^din[40]^din[49]^din[50]^din[51]^din[52]^din[53]^din[54]^din[55]^din[56]; + + assign ecc_out[4] = din[11]^din[12]^din[13]^din[14]^din[15]^din[16]^din[17]^din[18]^din[19]^din[20]^din[21]^din[22]^din[23]^din[24]^din[25]^din[41]^din[42]^din[43]^din[44]^din[45]^din[46]^din[47]^din[48]^din[49]^din[50]^din[51]^din[52]^din[53]^din[54]^din[55]^din[56]; + + assign ecc_out[5] = din[26]^din[27]^din[28]^din[29]^din[30]^din[31]^din[32]^din[33]^din[34]^din[35]^din[36]^din[37]^din[38]^din[39]^din[40]^din[41]^din[42]^din[43]^din[44]^din[45]^din[46]^din[47]^din[48]^din[49]^din[50]^din[51]^din[52]^din[53]^din[54]^din[55]^din[56]; + + assign ecc_out[6] = din[57]^din[58]^din[59]^din[60]^din[61]^din[62]^din[63]; + +endmodule // rvecc_encode_64 + + +module rvecc_decode_64 ( + input en, + input [63:0] din, + input [6:0] ecc_in, + output ecc_error + ); + + logic [6:0] ecc_check; + + // Generate the ecc bits + assign ecc_check[0] = ecc_in[0]^din[0]^din[1]^din[3]^din[4]^din[6]^din[8]^din[10]^din[11]^din[13]^din[15]^din[17]^din[19]^din[21]^din[23]^din[25]^din[26]^din[28]^din[30]^din[32]^din[34]^din[36]^din[38]^din[40]^din[42]^din[44]^din[46]^din[48]^din[50]^din[52]^din[54]^din[56]^din[57]^din[59]^din[61]^din[63]; + + assign ecc_check[1] = ecc_in[1]^din[0]^din[2]^din[3]^din[5]^din[6]^din[9]^din[10]^din[12]^din[13]^din[16]^din[17]^din[20]^din[21]^din[24]^din[25]^din[27]^din[28]^din[31]^din[32]^din[35]^din[36]^din[39]^din[40]^din[43]^din[44]^din[47]^din[48]^din[51]^din[52]^din[55]^din[56]^din[58]^din[59]^din[62]^din[63]; + + assign ecc_check[2] = ecc_in[2]^din[1]^din[2]^din[3]^din[7]^din[8]^din[9]^din[10]^din[14]^din[15]^din[16]^din[17]^din[22]^din[23]^din[24]^din[25]^din[29]^din[30]^din[31]^din[32]^din[37]^din[38]^din[39]^din[40]^din[45]^din[46]^din[47]^din[48]^din[53]^din[54]^din[55]^din[56]^din[60]^din[61]^din[62]^din[63]; + + assign ecc_check[3] = ecc_in[3]^din[4]^din[5]^din[6]^din[7]^din[8]^din[9]^din[10]^din[18]^din[19]^din[20]^din[21]^din[22]^din[23]^din[24]^din[25]^din[33]^din[34]^din[35]^din[36]^din[37]^din[38]^din[39]^din[40]^din[49]^din[50]^din[51]^din[52]^din[53]^din[54]^din[55]^din[56]; + + assign ecc_check[4] = ecc_in[4]^din[11]^din[12]^din[13]^din[14]^din[15]^din[16]^din[17]^din[18]^din[19]^din[20]^din[21]^din[22]^din[23]^din[24]^din[25]^din[41]^din[42]^din[43]^din[44]^din[45]^din[46]^din[47]^din[48]^din[49]^din[50]^din[51]^din[52]^din[53]^din[54]^din[55]^din[56]; + + assign ecc_check[5] = ecc_in[5]^din[26]^din[27]^din[28]^din[29]^din[30]^din[31]^din[32]^din[33]^din[34]^din[35]^din[36]^din[37]^din[38]^din[39]^din[40]^din[41]^din[42]^din[43]^din[44]^din[45]^din[46]^din[47]^din[48]^din[49]^din[50]^din[51]^din[52]^din[53]^din[54]^din[55]^din[56]; + + assign ecc_check[6] = ecc_in[6]^din[57]^din[58]^din[59]^din[60]^din[61]^din[62]^din[63]; + + assign ecc_error = en & (ecc_check[6:0] != 0); // all errors in the sed_ded case will be recorded as DE + + endmodule // rvecc_decode_64 + +`ifndef TECH_SPECIFIC_EC_RV_ICG +module `TEC_RV_ICG + ( + input logic SE, EN, CK, + output Q + ); + + logic en_ff; + logic enable; + + assign enable = EN | SE; + + always @(CK, enable) begin + if(!CK) + en_ff = enable; + end + assign Q = CK & en_ff; + +endmodule +`endif + +`ifndef RV_FPGA_OPTIMIZE +module rvclkhdr + ( + input logic en, + input logic clk, + // Excluding scan_mode from coverage as its usage is determined by the integrator of the VeeR core. + /*pragma coverage off*/ + input logic scan_mode, + /*pragma coverage on*/ + output logic l1clk + ); + + logic SE; + assign SE = 0; + +`ifdef TECH_SPECIFIC_EC_RV_ICG + `USER_EC_RV_ICG clkhdr ( .*, .EN(en), .CK(clk), .Q(l1clk)); +`else + `TEC_RV_ICG clkhdr ( .*, .EN(en), .CK(clk), .Q(l1clk)); +`endif + +endmodule // rvclkhdr +`endif + +module rvoclkhdr + ( + input logic en, + input logic clk, + // Excluding scan_mode from coverage as its usage is determined by the integrator of the VeeR core. + /*pragma coverage off*/ + input logic scan_mode, + /*pragma coverage on*/ + output logic l1clk + ); + + logic SE; + assign SE = 0; + +`ifdef RV_FPGA_OPTIMIZE + assign l1clk = clk; +`else + `ifdef TECH_SPECIFIC_EC_RV_ICG + `USER_EC_RV_ICG clkhdr ( .*, .EN(en), .CK(clk), .Q(l1clk)); + `else + `TEC_RV_ICG clkhdr ( .*, .EN(en), .CK(clk), .Q(l1clk)); + `endif +`endif + +endmodule + + + diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_2ff_sync.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_2ff_sync.sv new file mode 100644 index 0000000..9124daa --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_2ff_sync.sv @@ -0,0 +1,39 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. + +module caliptra_2ff_sync #( parameter WIDTH=1, + parameter RST_VAL=0) + ( + input logic clk, + input logic rst_b, + input logic [WIDTH-1:0] din, + output logic [WIDTH-1:0] dout + +); + +logic din_ff; + +always_ff@(posedge clk or negedge rst_b) begin + if(!rst_b) begin + dout <= RST_VAL; + din_ff <= RST_VAL; + end + else begin + din_ff <= din; + dout <= din_ff; + end +end + + +endmodule \ No newline at end of file diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_ahb_srom.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_ahb_srom.sv new file mode 100644 index 0000000..f6a8d64 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_ahb_srom.sv @@ -0,0 +1,89 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. + + +module caliptra_ahb_srom + import ahb_defines_pkg::*; + #( + parameter AHB_DATA_WIDTH = 64, + parameter AHB_ADDR_WIDTH = 32, + parameter CLIENT_ADDR_WIDTH = 32 +)( + + //AMBA AHB Lite INF + input logic hclk, + input logic hreset_n, + input logic [AHB_ADDR_WIDTH-1:0] haddr_i, + input logic [AHB_DATA_WIDTH-1:0] hwdata_i, + input logic hsel_i, + input logic hwrite_i, + + input logic hready_i, + input logic [1:0] htrans_i, + input logic [2:0] hsize_i, + + + //response to uC + output logic hresp_o, + output logic hreadyout_o, + output logic [AHB_DATA_WIDTH-1:0] hrdata_o, + + //SROM Inf + output logic cs, + output logic [CLIENT_ADDR_WIDTH-1:0] addr, + input logic [AHB_DATA_WIDTH-1:0] rdata + +); + +//`define H_OKAY 1'b0; +//`define H_ERROR 1'b1; + +///////////////////////////////// +// Signals +logic sram_error, sram_error_data_ph, sram_error_data_ph_f; + +///////////////////////////////// +// Assignments/Shim logic +assign cs = hready_i & hsel_i & htrans_i inside {2'b10, 2'b11}; +assign addr = haddr_i >> $clog2(AHB_DATA_WIDTH/8); + +assign sram_error = cs & hwrite_i; // Error if trying to write to ROM + +assign hrdata_o = rdata; + +always_comb begin : response_block + hreadyout_o = 1'b1; + hresp_o = H_OKAY; + //first error cycle, de-assert ready and drive error + if (sram_error_data_ph & ~sram_error_data_ph_f) begin + hreadyout_o = 1'b0; + hresp_o = H_ERROR; + end else if (sram_error_data_ph_f) begin + hreadyout_o = 1'b1; + hresp_o = H_ERROR; + end +end + +//flop error to indicate second cycle of error +always_ff @(posedge hclk or negedge hreset_n) begin + if (~hreset_n) begin + sram_error_data_ph <= '0; + sram_error_data_ph_f <= '0; + end else begin + sram_error_data_ph <= sram_error; + sram_error_data_ph_f <= sram_error_data_ph; + end +end + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_axi_sram.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_axi_sram.sv new file mode 100644 index 0000000..7f83738 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_axi_sram.sv @@ -0,0 +1,95 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. + + +module caliptra_axi_sram #( + parameter AW = 32, + parameter DW = 64, + BC = DW/8, // Byte Count + BW = $clog2(BC), // Byte count Width + parameter UW = 32, // User Width + parameter IW = 1, // ID Width + ID_NUM = 1 << IW, // Don't override + + parameter EX_EN = 0 // Enable exclusive access tracking w/ AxLOCK +) +( + input clk, + input rst_n, + + // AXI INF + axi_if.w_sub s_axi_w_if, + axi_if.r_sub s_axi_r_if +); + +//COMPONENT INF +logic dv; +logic [AW-1:0] addr; // Byte address +logic write; +logic [DW-1:0] wdata; // Requires: Component dwidth == AXI dwidth +logic [DW-1:0] rdata; // Requires: Component dwidth == AXI dwidth +logic hold; +logic rd_error; +logic wr_error; + + +axi_sub #( + .AW (AW ), + .DW (DW ), + .UW (UW ), + .IW (IW ), + .EX_EN(EX_EN), + .C_LAT(1 ) +) i_axi_sub ( + .clk (clk ), + .rst_n(rst_n ), + + // AXI INF + .s_axi_w_if(s_axi_w_if), + .s_axi_r_if(s_axi_r_if), + + //COMPONENT INF + .dv (dv ), + .addr (addr ), // Byte address + .write (write ), + .user ( ), + .id ( ), + .wdata (wdata ), + .wstrb ( ), + .rdata (rdata ), + .last ( ), + .size ( ), + .hld (hold ), + .rd_err (rd_error), + .wr_err (wr_error) +); + +assign hold = 1'b0; +assign rd_error = 1'b0; +assign wr_error = 1'b0; + +caliptra_sram #( + .DEPTH (1 << (AW - BW)), // Depth in WORDS + .DATA_WIDTH(DW) +) i_sram ( + .clk_i (clk ), + + .cs_i (dv ), + .we_i (write), + .addr_i (addr[AW-1:BW]), + .wdata_i (wdata), + .rdata_o (rdata) +); + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_icg.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_icg.sv new file mode 100644 index 0000000..d40f8da --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_icg.sv @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +`include "config_defines.svh" + +`ifndef TECH_SPECIFIC_ICG + module `CALIPTRA_ICG ( + input logic clk, + input logic en, + output clk_cg + ); + logic en_lat; + + //Latch disable for both clk and soc_ifc clk + always_latch begin + if(!clk) begin + en_lat = en; + end + end + + //Gate clk + assign clk_cg = clk && en_lat; + + endmodule +`endif \ No newline at end of file diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_macros.svh b/designs/Caliptra/src/caliptra-rtl/caliptra_macros.svh new file mode 100644 index 0000000..709f7ae --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_macros.svh @@ -0,0 +1,32 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. + +`ifndef CALIPTRA_MACROS +`define CALIPTRA_MACROS + + //Debug values for obfuscated secrets when we unlock debug mode through security state + `define CLP_DEBUG_MODE_OBF_KEY {256{1'b1}} + `define CLP_DEBUG_MODE_UDS_SEED {512{1'b1}} + `define CLP_DEBUG_MODE_FIELD_ENTROPY {256{1'b1}} + `define CLP_DEBUG_MODE_CSR_HMAC_KEY {512{1'b1}} + //Dword values to write into all KV entries during debug mode + parameter CLP_DEBUG_MODE_KV_0 = 32'hAAAA_AAAA; + parameter CLP_DEBUG_MODE_KV_1 = 32'h5555_5555; + + `define CLP_OBF_KEY_DWORDS 8 + `define CLP_OBF_FE_DWORDS 8 + `define CLP_OBF_UDS_DWORDS 16 + `define CLP_CSR_HMAC_KEY_DWORDS 16 + +`endif diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_alert_pkg.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_alert_pkg.sv new file mode 100644 index 0000000..7604559 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_alert_pkg.sv @@ -0,0 +1,27 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +package caliptra_prim_alert_pkg; + + typedef struct packed { + logic alert_p; + logic alert_n; + } alert_tx_t; + + typedef struct packed { + logic ping_p; + logic ping_n; + logic ack_p; + logic ack_n; + } alert_rx_t; + + parameter alert_tx_t ALERT_TX_DEFAULT = '{alert_p: 1'b0, + alert_n: 1'b1}; + + parameter alert_rx_t ALERT_RX_DEFAULT = '{ping_p: 1'b0, + ping_n: 1'b1, + ack_p: 1'b0, + ack_n: 1'b1}; + +endpackage : caliptra_prim_alert_pkg diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_alert_receiver.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_alert_receiver.sv new file mode 100644 index 0000000..e9babc0 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_alert_receiver.sv @@ -0,0 +1,388 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// The alert receiver primitive decodes alerts that have been differentially +// encoded and transmitted via a handshake protocol on alert_p/n and +// ack_p/n. In case an alert handshake is initiated, the output alert_o will +// immediately be asserted (even before completion of the handshake). +// +// In case the differential input is not correctly encoded, this module will +// raise an error by asserting integ_fail_o. +// +// Further, the module supports ping testing of the alert diff pair. In order to +// initiate a ping test, ping_req_i shall be set to 1'b1 until ping_ok_o is +// asserted for one cycle. The signal may be de-asserted (e.g. after a long) +// timeout period. However note that all ping responses that come in after +// deasserting ping_req_i will be treated as native alerts. +// +// The protocol works in both asynchronous and synchronous cases. In the +// asynchronous case, the parameter AsyncOn must be set to 1'b1 in order to +// instantiate additional synchronization logic. Further, it must be ensured +// that the timing skew between all diff pairs is smaller than the shortest +// clock period of the involved clocks. +// +// Note that in case of synchronous operation, alerts on the diffpair are +// decoded combinationally and forwarded on alert_o within the same cycle. +// +// See also: caliptra_prim_alert_sender, caliptra_prim_diff_decode, alert_handler + +`include "caliptra_prim_assert.sv" + +module caliptra_prim_alert_receiver + import caliptra_prim_alert_pkg::*; + import caliptra_prim_mubi_pkg::mubi4_t; +#( + // enables additional synchronization logic + parameter bit AsyncOn = 1'b0 +) ( + input clk_i, + input rst_ni, + // if set to lc_ctrl_pkg::On, this triggers the in-band alert channel + // reset, which resets both the sender and receiver FSMs into IDLE. + input mubi4_t init_trig_i, + // this triggers a ping test. keep asserted + // until ping_ok_o is asserted. + input ping_req_i, + output logic ping_ok_o, + // asserted if signal integrity issue detected + output logic integ_fail_o, + // alert output (pulsed high) if a handshake is initiated + // on alert_p/n and no ping request is outstanding + output logic alert_o, + // ping input diff pair and ack diff pair + output alert_rx_t alert_rx_o, + // alert output diff pair + input alert_tx_t alert_tx_i +); + + import caliptra_prim_mubi_pkg::mubi4_test_true_strict; + + ///////////////////////////////// + // decode differential signals // + ///////////////////////////////// + logic alert_level, alert_sigint, alert_p, alert_n; + + // This prevents further tool optimizations of the differential signal. + caliptra_prim_sec_anchor_buf #( + .Width(2) + ) u_caliptra_prim_buf_in ( + .in_i({alert_tx_i.alert_n, + alert_tx_i.alert_p}), + .out_o({alert_n, + alert_p}) + ); + + caliptra_prim_diff_decode #( + .AsyncOn(AsyncOn) + ) u_decode_alert ( + .clk_i, + .rst_ni, + .diff_pi ( alert_p ), + .diff_ni ( alert_n ), + .level_o ( alert_level ), + .rise_o ( ), + .fall_o ( ), + .event_o ( ), + .sigint_o ( alert_sigint ) + ); + + ///////////////////////////////////////////////////// + // main protocol FSM that drives the diff outputs // + ///////////////////////////////////////////////////// + typedef enum logic [2:0] {Idle, HsAckWait, Pause0, Pause1, InitReq, InitAckWait} state_e; + state_e state_d, state_q; + logic ping_rise; + logic ping_tog_pd, ping_tog_pq, ping_tog_dn, ping_tog_nq; + logic ack_pd, ack_pq, ack_dn, ack_nq; + logic ping_req_d, ping_req_q; + logic ping_pending_d, ping_pending_q; + logic send_init; + logic send_ping; + + // signal ping request upon positive transition on ping_req_i + // signalling is performed by a level change event on the diff output + assign ping_req_d = ping_req_i; + assign ping_rise = ping_req_d && !ping_req_q; + assign ping_tog_pd = (send_init) ? 1'b0 : + (send_ping) ? ~ping_tog_pq : ping_tog_pq; + + // in-band reset is performed by sending out an integrity error on purpose. + assign ack_dn = (send_init) ? ack_pd : ~ack_pd; + assign ping_tog_dn = ~ping_tog_pd; + + // This prevents further tool optimizations of the differential signal. + caliptra_prim_sec_anchor_flop #( + .Width (2), + .ResetValue(2'b10) + ) u_caliptra_prim_generic_flop_ack ( + .clk_i, + .rst_ni, + .d_i({ack_dn, + ack_pd}), + .q_o({ack_nq, + ack_pq}) + ); + + caliptra_prim_sec_anchor_flop #( + .Width (2), + .ResetValue(2'b10) + ) u_caliptra_prim_generic_flop_ping ( + .clk_i, + .rst_ni, + .d_i({ping_tog_dn, + ping_tog_pd}), + .q_o({ping_tog_nq, + ping_tog_pq}) + ); + + // the ping pending signal is used in the FSM to distinguish whether the + // incoming handshake shall be treated as an alert or a ping response. + // it is important that this is only set on a rising ping_en level change, since + // otherwise the ping enable signal could be abused to "mask" all native alerts + // as ping responses by constantly tying it to 1. + assign ping_pending_d = ping_rise | ((~ping_ok_o) & ping_req_i & ping_pending_q); + + // diff pair outputs + assign alert_rx_o.ack_p = ack_pq; + assign alert_rx_o.ack_n = ack_nq; + + assign alert_rx_o.ping_p = ping_tog_pq; + assign alert_rx_o.ping_n = ping_tog_nq; + + // this FSM receives the four phase handshakes from the alert receiver + // note that the latency of the alert_p/n input diff pair is at least one + // cycle until it enters the receiver FSM. the same holds for the ack_* diff + // pair outputs. + always_comb begin : p_fsm + // default + state_d = state_q; + ack_pd = 1'b0; + ping_ok_o = 1'b0; + integ_fail_o = 1'b0; + alert_o = 1'b0; + send_init = 1'b0; + // by default, a ping request leads to a toogle on the differential ping pair + send_ping = ping_rise; + + unique case (state_q) + Idle: begin + // wait for handshake to be initiated + if (alert_level) begin + state_d = HsAckWait; + ack_pd = 1'b1; + // signal either an alert or ping received on the output + if (ping_pending_q) begin + ping_ok_o = 1'b1; + end else begin + alert_o = 1'b1; + end + end + end + // waiting for deassertion of alert to complete HS + HsAckWait: begin + if (!alert_level) begin + state_d = Pause0; + end else begin + ack_pd = 1'b1; + end + end + // pause cycles between back-to-back handshakes + Pause0: state_d = Pause1; + Pause1: state_d = Idle; + // this state is only reached if an in-band reset is + // requested via the low-power logic. + InitReq: begin + // we deliberately place a sigint error on the ack and ping lines in this case. + send_init = 1'b1; + // suppress any toggles on the ping line while we are in the init phase. + send_ping = 1'b0; + // As long as init req is asserted, we remain in this state and acknowledge all incoming + // ping requests. As soon as the init request is dropped however, ping requests are not + // acked anymore such that the ping mechanism can also flag alert channels that got stuck + // in the initialization sequence. + if (mubi4_test_true_strict(init_trig_i)) begin + ping_ok_o = ping_pending_q; + // the sender will respond to the sigint error above with a sigint error on the alert lines. + // hence we treat the alert_sigint like an acknowledgement in this case. + end else if (alert_sigint) begin + state_d = InitAckWait; + end + end + // We get here if the sender has responded with alert_sigint, and init_trig_i==lc_ctrl_pkg::On + // has been deasserted. At this point, we need to wait for the alert_sigint to drop again + // before resuming normal operation. + InitAckWait: begin + // suppress any toggles on the ping line while we are in the init phase. + send_ping = 1'b0; + if (!alert_sigint) begin + state_d = Pause0; + // If we get a ping request in this cycle, or if we realize that there is an unhandled + // ping request that came in during initialization (but after init_trig_i has been + // deasserted), we signal this to the alert sender by toggling the request line. + send_ping = ping_rise || ping_pending_q; + end + end + default: state_d = Idle; + endcase + + // once the initialization sequence has been triggered, + // overrides are not allowed anymore until the initialization has been completed. + if (!(state_q inside {InitReq, InitAckWait})) begin + // in this case, abort and jump into the initialization sequence + if (mubi4_test_true_strict(init_trig_i)) begin + state_d = InitReq; + ack_pd = 1'b0; + ping_ok_o = 1'b0; + integ_fail_o = 1'b0; + alert_o = 1'b0; + send_init = 1'b1; + // if we're not busy with an init request, we clamp down all outputs + // and indicate an integrity failure. + end else if (alert_sigint) begin + state_d = Idle; + ack_pd = 1'b0; + ping_ok_o = 1'b0; + integ_fail_o = 1'b1; + alert_o = 1'b0; + end + end + end + + always_ff @(posedge clk_i or negedge rst_ni) begin : p_reg + if (!rst_ni) begin + // Reset into the init request so that an alert handler reset implicitly + // triggers an in-band reset of all alert channels. + state_q <= InitReq; + ping_req_q <= 1'b0; + ping_pending_q <= 1'b0; + end else begin + state_q <= state_d; + ping_req_q <= ping_req_d; + ping_pending_q <= ping_pending_d; + end + end + + + //////////////// + // assertions // + //////////////// + +`ifdef CALIPTRA_INC_ASSERT + import caliptra_prim_mubi_pkg::mubi4_test_false_loose; +`endif + + // check whether all outputs have a good known state after reset + `CALIPTRA_ASSERT_KNOWN(PingOkKnownO_A, ping_ok_o) + `CALIPTRA_ASSERT_KNOWN(IntegFailKnownO_A, integ_fail_o) + `CALIPTRA_ASSERT_KNOWN(AlertKnownO_A, alert_o) + `CALIPTRA_ASSERT_KNOWN(PingPKnownO_A, alert_rx_o) + + // check encoding of outgoing diffpairs. note that during init, the outgoing diffpairs are + // supposed to be incorrectly encoded on purpose. + // shift sequence two cycles to the right to avoid reset effects. + `CALIPTRA_ASSERT(PingDiffOk_A, alert_rx_o.ping_p ^ alert_rx_o.ping_n) + `CALIPTRA_ASSERT(AckDiffOk_A, ##2 $past(send_init) ^ alert_rx_o.ack_p ^ alert_rx_o.ack_n) + `CALIPTRA_ASSERT(InitReq_A, mubi4_test_true_strict(init_trig_i) && + !(state_q inside {InitReq, InitAckWait}) |=> send_init) + + // If there is a ping request on the input then we should see an encoded ping request. This is + // squashed if we are in state InitReq or InitAckWait (because we are still initialising), or if + // we see the init_trig_i signal go high (because it will start an initialisation). + `CALIPTRA_ASSERT(PingRequest0_A, + $rose(ping_req_i) |=> $changed(alert_rx_o.ping_p), + clk_i, !rst_ni || init_trig_i || state_q inside {InitReq, InitAckWait}) + + // ping response implies it has been requested + `CALIPTRA_ASSERT(PingResponse0_A, ping_ok_o |-> ping_pending_q) + // correctly latch ping request + `CALIPTRA_ASSERT(PingPending_A, ##1 $rose(ping_req_i) |=> ping_pending_q) + + if (AsyncOn) begin : gen_async_assert + // signal integrity check propagation + `CALIPTRA_ASSERT(SigInt_A, + alert_tx_i.alert_p == alert_tx_i.alert_n [*2] ##2 + !(state_q inside {InitReq, InitAckWait}) && + mubi4_test_false_loose(init_trig_i) + |-> + ##[0:1] integ_fail_o) + `CALIPTRA_ASSERT(PingResponse1_A, + ##1 $rose(alert_tx_i.alert_p) && + (alert_tx_i.alert_p ^ alert_tx_i.alert_n) ##2 + state_q == Idle && ping_pending_q + |-> + ##[0:1] ping_ok_o, + clk_i, !rst_ni || integ_fail_o || mubi4_test_true_strict(init_trig_i)) + // alert + `CALIPTRA_ASSERT(Alert_A, + ##1 $rose(alert_tx_i.alert_p) && + (alert_tx_i.alert_p ^ alert_tx_i.alert_n) ##2 + state_q == Idle && + !ping_pending_q + |-> + ##[0:1] alert_o, + clk_i, !rst_ni || integ_fail_o || mubi4_test_true_strict(init_trig_i)) + end else begin : gen_sync_assert + // signal integrity check propagation + `CALIPTRA_ASSERT(SigInt_A, + alert_tx_i.alert_p == alert_tx_i.alert_n && + !(state_q inside {InitReq, InitAckWait}) && + mubi4_test_false_loose(init_trig_i) + |-> + integ_fail_o) + // ping response + `CALIPTRA_ASSERT(PingResponse1_A, + ##1 $rose(alert_tx_i.alert_p) && + state_q == Idle && + ping_pending_q + |-> + ping_ok_o, + clk_i, !rst_ni || integ_fail_o || mubi4_test_true_strict(init_trig_i)) + // alert + `CALIPTRA_ASSERT(Alert_A, + ##1 $rose(alert_tx_i.alert_p) && + state_q == Idle && + !ping_pending_q + |-> + alert_o, + clk_i, !rst_ni || integ_fail_o || mubi4_test_true_strict(init_trig_i)) + end + + // check in-band init request is always accepted + `CALIPTRA_ASSERT(InBandInitRequest_A, + mubi4_test_true_strict(init_trig_i) && + state_q != InitAckWait + |=> + state_q == InitReq) + // check in-band init sequence moves FSM into IDLE state + `CALIPTRA_ASSERT(InBandInitSequence_A, + (state_q == InitReq && + mubi4_test_true_strict(init_trig_i)) ##1 + (alert_sigint && + mubi4_test_false_loose(init_trig_i)) [*1:$] ##1 + (!alert_sigint && + mubi4_test_false_loose(init_trig_i)) [*3] + |=> + state_q == Idle) + // check there are no spurious alerts during init + `CALIPTRA_ASSERT(NoSpuriousAlertsDuringInit_A, + mubi4_test_true_strict(init_trig_i) || + (state_q inside {InitReq, InitAckWait}) + |-> + !alert_o) + // check that there are no spurious ping OKs + `CALIPTRA_ASSERT(NoSpuriousPingOksDuringInit_A, + (mubi4_test_true_strict(init_trig_i) || + (state_q inside {InitReq, InitAckWait})) && + !ping_pending_q + |-> + !ping_ok_o) + // check ping request is bypassed when in init state + `CALIPTRA_ASSERT(PingOkBypassDuringInit_A, + $rose(ping_req_i) ##1 + state_q == InitReq && + mubi4_test_true_strict(init_trig_i) + |-> + ping_ok_o) + +endmodule : caliptra_prim_alert_receiver diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_alert_sender.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_alert_sender.sv new file mode 100644 index 0000000..89819a9 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_alert_sender.sv @@ -0,0 +1,392 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// The alert sender primitive module differentially encodes and transmits an +// alert signal to the caliptra_prim_alert_receiver module. An alert will be signalled +// by a full handshake on alert_p/n and ack_p/n. The alert_req_i signal may +// be continuously asserted, in which case the alert signalling handshake +// will be repeatedly initiated. +// +// The alert_req_i signal may also be used as part of req/ack. The parent module +// can keep alert_req_i asserted until it has been ack'd (transferred to the alert +// receiver). The parent module is not required to use this. +// +// In case the alert sender parameter IsFatal is set to 1, an incoming alert +// alert_req_i is latched in a local register until the next reset, causing the +// alert sender to behave as if alert_req_i were continously asserted. +// The alert_state_o output reflects the state of this internal latching register. +// +// The alert sender also exposes an alert test input, which can be used to trigger +// single alert handshakes. This input behaves exactly the same way as the +// alert_req_i input with IsFatal set to 0. Test alerts do not cause alert_ack_o +// to be asserted, nor are they latched until reset (regardless of the value of the +// IsFatal parameter). +// +// Further, this module supports in-band ping testing, which means that a level +// change on the ping_p/n diff pair will result in a full-handshake response +// on alert_p/n and ack_p/n. +// +// The protocol works in both asynchronous and synchronous cases. In the +// asynchronous case, the parameter AsyncOn must be set to 1'b1 in order to +// instantiate additional synchronization logic. Further, it must be ensured +// that the timing skew between all diff pairs is smaller than the shortest +// clock period of the involved clocks. +// +// Incorrectly encoded diff inputs can be detected and will be signalled +// to the receiver by placing an inconsistent diff value on the differential +// output (and continuously toggling it). +// +// See also: caliptra_prim_alert_receiver, caliptra_prim_diff_decode, alert_handler + +`include "caliptra_prim_assert.sv" + +module caliptra_prim_alert_sender + import caliptra_prim_alert_pkg::*; +#( + // enables additional synchronization logic + parameter bit AsyncOn = 1'b1, + // alert sender will latch the incoming alert event permanently and + // keep on sending alert events until the next reset. + parameter bit IsFatal = 1'b0 +) ( + input clk_i, + input rst_ni, + // alert test trigger (this will never be latched, even if IsFatal == 1) + input alert_test_i, + // native alert from the peripheral + input alert_req_i, + output logic alert_ack_o, + // state of the alert latching register + output logic alert_state_o, + // ping input diff pair and ack diff pair + input alert_rx_t alert_rx_i, + // alert output diff pair + output alert_tx_t alert_tx_o +); + + + ///////////////////////////////// + // decode differential signals // + ///////////////////////////////// + logic ping_sigint, ping_event, ping_n, ping_p; + + // This prevents further tool optimizations of the differential signal. + caliptra_prim_sec_anchor_buf #( + .Width(2) + ) u_caliptra_prim_buf_ping ( + .in_i({alert_rx_i.ping_n, + alert_rx_i.ping_p}), + .out_o({ping_n, + ping_p}) + ); + + caliptra_prim_diff_decode #( + .AsyncOn(AsyncOn) + ) u_decode_ping ( + .clk_i, + .rst_ni, + .diff_pi ( ping_p ), + .diff_ni ( ping_n ), + .level_o ( ), + .rise_o ( ), + .fall_o ( ), + .event_o ( ping_event ), + .sigint_o ( ping_sigint ) + ); + + logic ack_sigint, ack_level, ack_n, ack_p; + + // This prevents further tool optimizations of the differential signal. + caliptra_prim_sec_anchor_buf #( + .Width(2) + ) u_caliptra_prim_buf_ack ( + .in_i({alert_rx_i.ack_n, + alert_rx_i.ack_p}), + .out_o({ack_n, + ack_p}) + ); + + caliptra_prim_diff_decode #( + .AsyncOn(AsyncOn) + ) u_decode_ack ( + .clk_i, + .rst_ni, + .diff_pi ( ack_p ), + .diff_ni ( ack_n ), + .level_o ( ack_level ), + .rise_o ( ), + .fall_o ( ), + .event_o ( ), + .sigint_o ( ack_sigint ) + ); + + + /////////////////////////////////////////////////// + // main protocol FSM that drives the diff output // + /////////////////////////////////////////////////// + typedef enum logic [2:0] { + Idle, + AlertHsPhase1, + AlertHsPhase2, + PingHsPhase1, + PingHsPhase2, + Pause0, + Pause1 + } state_e; + state_e state_d, state_q; + logic alert_pq, alert_nq, alert_pd, alert_nd; + logic sigint_detected; + + assign sigint_detected = ack_sigint | ping_sigint; + + + // diff pair output + assign alert_tx_o.alert_p = alert_pq; + assign alert_tx_o.alert_n = alert_nq; + + // alert and ping set regs + logic alert_set_d, alert_set_q, alert_clr; + logic alert_test_set_d, alert_test_set_q; + logic ping_set_d, ping_set_q, ping_clr; + logic alert_req_trigger, alert_test_trigger, ping_trigger; + + // if handshake is ongoing, capture additional alert requests. + logic alert_req; + caliptra_prim_sec_anchor_buf #( + .Width(1) + ) u_caliptra_prim_buf_in_req ( + .in_i(alert_req_i), + .out_o(alert_req) + ); + + assign alert_req_trigger = alert_req | alert_set_q; + if (IsFatal) begin : gen_fatal + assign alert_set_d = alert_req_trigger; + end else begin : gen_recov + assign alert_set_d = (alert_clr) ? 1'b0 : alert_req_trigger; + end + + // the alert test request is always cleared. + assign alert_test_trigger = alert_test_i | alert_test_set_q; + assign alert_test_set_d = (alert_clr) ? 1'b0 : alert_test_trigger; + + logic alert_trigger; + assign alert_trigger = alert_req_trigger | alert_test_trigger; + + assign ping_trigger = ping_set_q | ping_event; + assign ping_set_d = (ping_clr) ? 1'b0 : ping_trigger; + + + // alert event acknowledge and state (not affected by alert_test_i) + assign alert_ack_o = alert_clr & alert_set_q; + assign alert_state_o = alert_set_q; + + // this FSM performs a full four phase handshake upon a ping or alert trigger. + // note that the latency of the alert_p/n diff pair is at least one cycle + // until it enters the receiver FSM. the same holds for the ack_* diff pair + // input. in case a signal integrity issue is detected, the FSM bails out, + // sets the alert_p/n diff pair to the same value and toggles it in order to + // signal that condition over to the receiver. + always_comb begin : p_fsm + // default + state_d = state_q; + alert_pd = 1'b0; + alert_nd = 1'b1; + ping_clr = 1'b0; + alert_clr = 1'b0; + + unique case (state_q) + Idle: begin + // alert always takes precedence + if (alert_trigger || ping_trigger) begin + state_d = (alert_trigger) ? AlertHsPhase1 : PingHsPhase1; + alert_pd = 1'b1; + alert_nd = 1'b0; + end + end + // waiting for ack from receiver + AlertHsPhase1: begin + if (ack_level) begin + state_d = AlertHsPhase2; + end else begin + alert_pd = 1'b1; + alert_nd = 1'b0; + end + end + // wait for deassertion of ack + AlertHsPhase2: begin + if (!ack_level) begin + state_d = Pause0; + alert_clr = 1'b1; + end + end + // waiting for ack from receiver + PingHsPhase1: begin + if (ack_level) begin + state_d = PingHsPhase2; + end else begin + alert_pd = 1'b1; + alert_nd = 1'b0; + end + end + // wait for deassertion of ack + PingHsPhase2: begin + if (!ack_level) begin + ping_clr = 1'b1; + state_d = Pause0; + end + end + // pause cycles between back-to-back handshakes + Pause0: begin + state_d = Pause1; + end + // clear and ack alert request if it was set + Pause1: begin + state_d = Idle; + end + // catch parasitic states + default : state_d = Idle; + endcase + + // we have a signal integrity issue at one of the incoming diff pairs. this condition is + // signalled by setting the output diffpair to zero. If the sigint has disappeared, we clear + // the ping request state of this sender and go back to idle. + if (sigint_detected) begin + state_d = Idle; + alert_pd = 1'b0; + alert_nd = 1'b0; + ping_clr = 1'b1; + alert_clr = 1'b0; + end + end + + // This prevents further tool optimizations of the differential signal. + caliptra_prim_sec_anchor_flop #( + .Width (2), + .ResetValue(2'b10) + ) u_caliptra_prim_flop_alert ( + .clk_i, + .rst_ni, + .d_i({alert_nd, alert_pd}), + .q_o({alert_nq, alert_pq}) + ); + + always_ff @(posedge clk_i or negedge rst_ni) begin : p_reg + if (!rst_ni) begin + state_q <= Idle; + alert_set_q <= 1'b0; + alert_test_set_q <= 1'b0; + ping_set_q <= 1'b0; + end else begin + state_q <= state_d; + alert_set_q <= alert_set_d; + alert_test_set_q <= alert_test_set_d; + ping_set_q <= ping_set_d; + end + end + + + //////////////// + // assertions // + //////////////// + +// however, since we use sequence constructs below, we need to wrap the entire block again. +// typically, the CALIPTRA_ASSERT macros already contain this CALIPTRA_INC_ASSERT macro. +`ifdef CALIPTRA_INC_ASSERT + // check whether all outputs have a good known state after reset + `CALIPTRA_ASSERT_KNOWN(AlertPKnownO_A, alert_tx_o) + + if (AsyncOn) begin : gen_async_assert + sequence PingSigInt_S; + alert_rx_i.ping_p == alert_rx_i.ping_n [*2]; + endsequence + sequence AckSigInt_S; + alert_rx_i.ping_p == alert_rx_i.ping_n [*2]; + endsequence + + `ifndef FPV_ALERT_NO_SIGINT_ERR + // check propagation of sigint issues to output within three cycles, or four due to CDC + // shift sequence to the right to avoid reset effects. + `CALIPTRA_ASSERT(SigIntPing_A, ##1 PingSigInt_S |-> + ##[3:4] alert_tx_o.alert_p == alert_tx_o.alert_n) + `CALIPTRA_ASSERT(SigIntAck_A, ##1 AckSigInt_S |-> + ##[3:4] alert_tx_o.alert_p == alert_tx_o.alert_n) + `endif + + // Test in-band FSM reset request (via signal integrity error) + `CALIPTRA_ASSERT(InBandInitFsm_A, PingSigInt_S or AckSigInt_S |-> ##[3:4] state_q == Idle) + `CALIPTRA_ASSERT(InBandInitPing_A, PingSigInt_S or AckSigInt_S |-> ##[3:4] !ping_set_q) + // output must be driven diff unless sigint issue detected + `CALIPTRA_ASSERT(DiffEncoding_A, (alert_rx_i.ack_p ^ alert_rx_i.ack_n) && + (alert_rx_i.ping_p ^ alert_rx_i.ping_n) |-> + ##[3:5] alert_tx_o.alert_p ^ alert_tx_o.alert_n) + + // handshakes can take indefinite time if blocked due to sigint on outgoing + // lines (which is not visible here). thus, we only check whether the + // handshake is correctly initiated and defer the full handshake checking to the testbench. + `CALIPTRA_ASSERT(PingHs_A, ##1 $changed(alert_rx_i.ping_p) && + (alert_rx_i.ping_p ^ alert_rx_i.ping_n) ##2 state_q == Idle |=> + ##[0:1] $rose(alert_tx_o.alert_p), clk_i, + !rst_ni || (alert_tx_o.alert_p == alert_tx_o.alert_n)) + end else begin : gen_sync_assert + sequence PingSigInt_S; + alert_rx_i.ping_p == alert_rx_i.ping_n; + endsequence + sequence AckSigInt_S; + alert_rx_i.ping_p == alert_rx_i.ping_n; + endsequence + + `ifndef FPV_ALERT_NO_SIGINT_ERR + // check propagation of sigint issues to output within one cycle + `CALIPTRA_ASSERT(SigIntPing_A, PingSigInt_S |=> + alert_tx_o.alert_p == alert_tx_o.alert_n) + `CALIPTRA_ASSERT(SigIntAck_A, AckSigInt_S |=> + alert_tx_o.alert_p == alert_tx_o.alert_n) + `endif + + // Test in-band FSM reset request (via signal integrity error) + `CALIPTRA_ASSERT(InBandInitFsm_A, PingSigInt_S or AckSigInt_S |=> state_q == Idle) + `CALIPTRA_ASSERT(InBandInitPing_A, PingSigInt_S or AckSigInt_S |=> !ping_set_q) + // output must be driven diff unless sigint issue detected + `CALIPTRA_ASSERT(DiffEncoding_A, (alert_rx_i.ack_p ^ alert_rx_i.ack_n) && + (alert_rx_i.ping_p ^ alert_rx_i.ping_n) |=> alert_tx_o.alert_p ^ alert_tx_o.alert_n) + // handshakes can take indefinite time if blocked due to sigint on outgoing + // lines (which is not visible here). thus, we only check whether the handshake + // is correctly initiated and defer the full handshake checking to the testbench. + `CALIPTRA_ASSERT(PingHs_A, ##1 $changed(alert_rx_i.ping_p) && state_q == Idle |=> + $rose(alert_tx_o.alert_p), clk_i, !rst_ni || (alert_tx_o.alert_p == alert_tx_o.alert_n)) + end + + // Test the alert state output. + `CALIPTRA_ASSERT(AlertState0_A, alert_set_q === alert_state_o) + + if (IsFatal) begin : gen_fatal_assert + `CALIPTRA_ASSERT(AlertState1_A, alert_req_i |=> alert_state_o) + `CALIPTRA_ASSERT(AlertState2_A, alert_state_o |=> $stable(alert_state_o)) + `CALIPTRA_ASSERT(AlertState3_A, alert_ack_o |=> alert_state_o) + end else begin : gen_recov_assert + `CALIPTRA_ASSERT(AlertState1_A, alert_req_i && !alert_clr |=> alert_state_o) + `CALIPTRA_ASSERT(AlertState2_A, alert_req_i && alert_ack_o |=> !alert_state_o) + end + + // The alert test input should not set the alert state register. + `CALIPTRA_ASSERT(AlertTest1_A, alert_test_i && !alert_req_i && !alert_state_o |=> $stable(alert_state_o)) + + // if alert_req_i is true, handshakes should be continuously repeated + `CALIPTRA_ASSERT(AlertHs_A, alert_req_i && state_q == Idle |=> $rose(alert_tx_o.alert_p), + clk_i, !rst_ni || (alert_tx_o.alert_p == alert_tx_o.alert_n)) + + // if alert_test_i is true, handshakes should be continuously repeated + `CALIPTRA_ASSERT(AlertTestHs_A, alert_test_i && state_q == Idle |=> $rose(alert_tx_o.alert_p), + clk_i, !rst_ni || (alert_tx_o.alert_p == alert_tx_o.alert_n)) +`endif + +`ifdef FPV_ALERT_NO_SIGINT_ERR + // Assumptions for FPV security countermeasures to ensure the alert protocol functions collectly. + `CALIPTRA_ASSUME_FPV(AckPFollowsAlertP_S, alert_rx_i.ack_p == $past(alert_tx_o.alert_p)) + `CALIPTRA_ASSUME_FPV(AckNFollowsAlertN_S, alert_rx_i.ack_n == $past(alert_tx_o.alert_n)) + `CALIPTRA_ASSUME_FPV(TriggerAlertInit_S, $stable(rst_ni) == 0 |=> alert_rx_i.ping_p == alert_rx_i.ping_n) + `CALIPTRA_ASSUME_FPV(PingDiffPair_S, ##2 alert_rx_i.ping_p != alert_rx_i.ping_n) +`endif +endmodule : caliptra_prim_alert_sender diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_arbiter_fixed.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_arbiter_fixed.sv new file mode 100644 index 0000000..5b41cdf --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_arbiter_fixed.sv @@ -0,0 +1,170 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// N:1 fixed priority arbiter module (index 0 has highest prio) +// +// Verilog parameter +// N: Number of request ports +// DW: Data width +// DataPort: Set to 1 to enable the data port. Otherwise that port will be ignored. +// +// See also: prim_arbiter_ppc, prim_arbiter_tree + +`include "caliptra_prim_assert.sv" + +module caliptra_prim_arbiter_fixed #( + parameter int N = 8, + parameter int DW = 32, + + // Configurations + // EnDataPort: {0, 1}, if 0, input data will be ignored + parameter bit EnDataPort = 1, + + // Derived parameters + localparam int IdxW = $clog2(N) +) ( + // used for assertions only + input clk_i, + input rst_ni, + + input [ N-1:0] req_i, + input [DW-1:0] data_i [N], + output logic [ N-1:0] gnt_o, + output logic [IdxW-1:0] idx_o, + + output logic valid_o, + output logic [DW-1:0] data_o, + input ready_i +); + + `CALIPTRA_ASSERT_INIT(CheckNGreaterZero_A, N > 0) + + // this case is basically just a bypass + if (N == 1) begin : gen_degenerate_case + + assign valid_o = req_i[0]; + assign data_o = data_i[0]; + assign gnt_o[0] = valid_o & ready_i; + assign idx_o = '0; + + end else begin : gen_normal_case + + // align to powers of 2 for simplicity + // a full binary tree with N levels has 2**N + 2**N-1 nodes + logic [2**(IdxW+1)-2:0] req_tree; + logic [2**(IdxW+1)-2:0] gnt_tree; + logic [2**(IdxW+1)-2:0][IdxW-1:0] idx_tree; + logic [2**(IdxW+1)-2:0][DW-1:0] data_tree; + + for (genvar level = 0; level < IdxW+1; level++) begin : gen_tree + // + // level+1 C0 C1 <- "Base1" points to the first node on "level+1", + // \ / these nodes are the children of the nodes one level below + // level Pa <- "Base0", points to the first node on "level", + // these nodes are the parents of the nodes one level above + // + // hence we have the following indices for the Pa, C0, C1 nodes: + // Pa = 2**level - 1 + offset = Base0 + offset + // C0 = 2**(level+1) - 1 + 2*offset = Base1 + 2*offset + // C1 = 2**(level+1) - 1 + 2*offset + 1 = Base1 + 2*offset + 1 + // + localparam int Base0 = (2**level)-1; + localparam int Base1 = (2**(level+1))-1; + + for (genvar offset = 0; offset < 2**level; offset++) begin : gen_level + localparam int Pa = Base0 + offset; + localparam int C0 = Base1 + 2*offset; + localparam int C1 = Base1 + 2*offset + 1; + + // this assigns the gated interrupt source signals, their + // corresponding IDs and priorities to the tree leafs + if (level == IdxW) begin : gen_leafs + if (offset < N) begin : gen_assign + // forward path + assign req_tree[Pa] = req_i[offset]; + assign idx_tree[Pa] = offset; + assign data_tree[Pa] = data_i[offset]; + // backward (grant) path + assign gnt_o[offset] = gnt_tree[Pa]; + + end else begin : gen_tie_off + // forward path + assign req_tree[Pa] = '0; + assign idx_tree[Pa] = '0; + assign data_tree[Pa] = '0; + logic unused_sigs; + assign unused_sigs = gnt_tree[Pa]; + end + // this creates the node assignments + end else begin : gen_nodes + // forward path + logic sel; // local helper variable + always_comb begin : p_node + // this always gives priority to the left child + sel = ~req_tree[C0]; + // propagate requests + req_tree[Pa] = req_tree[C0] | req_tree[C1]; + // data and index muxes + idx_tree[Pa] = (sel) ? idx_tree[C1] : idx_tree[C0]; + data_tree[Pa] = (sel) ? data_tree[C1] : data_tree[C0]; + // propagate the grants back to the input + gnt_tree[C0] = gnt_tree[Pa] & ~sel; + gnt_tree[C1] = gnt_tree[Pa] & sel; + end + end + end : gen_level + end : gen_tree + + // the results can be found at the tree root + if (EnDataPort) begin : gen_data_port + assign data_o = data_tree[0]; + end else begin : gen_no_dataport + logic [DW-1:0] unused_data; + assign unused_data = data_tree[0]; + assign data_o = '1; + end + + assign idx_o = idx_tree[0]; + assign valid_o = req_tree[0]; + + // this propagates a grant back to the input + assign gnt_tree[0] = valid_o & ready_i; + end + + //////////////// + // assertions // + //////////////// + + // KNOWN assertions on outputs, except for data as that may be partially X in simulation + // e.g. when used on a BUS + `CALIPTRA_ASSERT_KNOWN(ValidKnown_A, valid_o) + `CALIPTRA_ASSERT_KNOWN(GrantKnown_A, gnt_o) + `CALIPTRA_ASSERT_KNOWN(IdxKnown_A, idx_o) + + // Make sure no higher prio req is asserted + `CALIPTRA_ASSERT(Priority_A, |req_i |-> req_i[idx_o] && (((N'(1'b1) << idx_o) - 1'b1) & req_i) == '0) + + // we can only grant one requestor at a time + `CALIPTRA_ASSERT(CheckHotOne_A, $onehot0(gnt_o)) + // A grant implies that the sink is ready + `CALIPTRA_ASSERT(GntImpliesReady_A, |gnt_o |-> ready_i) + // A grant implies that the arbiter asserts valid as well + `CALIPTRA_ASSERT(GntImpliesValid_A, |gnt_o |-> valid_o) + // A request and a sink that is ready imply a grant + `CALIPTRA_ASSERT(ReqAndReadyImplyGrant_A, |req_i && ready_i |-> |gnt_o) + // A request and a sink that is ready imply a grant + `CALIPTRA_ASSERT(ReqImpliesValid_A, |req_i |-> valid_o) + // Both conditions above combined and reversed + `CALIPTRA_ASSERT(ReadyAndValidImplyGrant_A, ready_i && valid_o |-> |gnt_o) + // Both conditions above combined and reversed + `CALIPTRA_ASSERT(NoReadyValidNoGrant_A, !(ready_i || valid_o) |-> gnt_o == 0) + // check index / grant correspond + `CALIPTRA_ASSERT(IndexIsCorrect_A, ready_i && valid_o |-> gnt_o[idx_o] && req_i[idx_o]) + +if (EnDataPort) begin: gen_data_port_assertion + // data flow + `CALIPTRA_ASSERT(DataFlow_A, ready_i && valid_o |-> data_o == data_i[idx_o]) +end + +endmodule : caliptra_prim_arbiter_fixed diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_arbiter_ppc.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_arbiter_ppc.sv new file mode 100644 index 0000000..dd90328 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_arbiter_ppc.sv @@ -0,0 +1,225 @@ +// Copyright lowRISC contributors. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// N:1 arbiter module +// +// Verilog parameter +// N: Number of request ports +// DW: Data width +// DataPort: Set to 1 to enable the data port. Otherwise that port will be ignored. +// +// This is the original implementation of the arbiter which relies on parallel prefix computing +// optimization to optimize the request / arbiter tree. Not all synthesis tools may support this. +// +// Note that the currently winning request is held if the data sink is not ready. This behavior is +// required by some interconnect protocols (AXI, TL). The module contains an assertion that checks +// this behavior. +// +// Also, this module contains a request stability assertion that checks that requests stay asserted +// until they have been served. This assertion can be gated by driving the req_chk_i low. This is +// a non-functional input and does not affect the designs behavior. +// +// See also: caliptra_prim_arbiter_tree + +`include "caliptra_prim_assert.sv" + +module caliptra_prim_arbiter_ppc #( + parameter int unsigned N = 8, + parameter int unsigned DW = 32, + + // Configurations + // EnDataPort: {0, 1}, if 0, input data will be ignored + parameter bit EnDataPort = 1, + + // Derived parameters + localparam int IdxW = $clog2(N) +) ( + input clk_i, + input rst_ni, + + input req_chk_i, // Used for gating assertions. Drive to 1 during normal + // operation. + input [ N-1:0] req_i, + input [DW-1:0] data_i [N], + output logic [ N-1:0] gnt_o, + output logic [IdxW-1:0] idx_o, + + output logic valid_o, + output logic [DW-1:0] data_o, + input ready_i +); + + // req_chk_i is used for gating assertions only. + logic unused_req_chk; + assign unused_req_chk = req_chk_i; + + `CALIPTRA_ASSERT_INIT(CheckNGreaterZero_A, N > 0) + + // this case is basically just a bypass + if (N == 1) begin : gen_degenerate_case + + assign valid_o = req_i[0]; + assign data_o = data_i[0]; + assign gnt_o[0] = valid_o & ready_i; + assign idx_o = '0; + + end else begin : gen_normal_case + + logic [N-1:0] masked_req; + logic [N-1:0] ppc_out; + logic [N-1:0] arb_req; + logic [N-1:0] mask, mask_next; + logic [N-1:0] winner; + + assign masked_req = mask & req_i; + assign arb_req = (|masked_req) ? masked_req : req_i; + + // PPC + // Even below code looks O(n) but DC optimizes it to O(log(N)) + // Using Parallel Prefix Computation + always_comb begin + ppc_out[0] = arb_req[0]; + for (int i = 1 ; i < N ; i++) begin + ppc_out[i] = ppc_out[i-1] | arb_req[i]; + end + end + + // Grant Generation: Leading-One detector + assign winner = ppc_out ^ {ppc_out[N-2:0], 1'b0}; + assign gnt_o = (ready_i) ? winner : '0; + + assign valid_o = |req_i; + // Mask Generation + assign mask_next = {ppc_out[N-2:0], 1'b0}; + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + mask <= '0; + end else if (valid_o && ready_i) begin + // Latch only when requests accepted + mask <= mask_next; + end else if (valid_o && !ready_i) begin + // Downstream isn't yet ready so, keep current request alive. (First come first serve) + mask <= ppc_out; + end + end + + if (EnDataPort == 1) begin: gen_datapath + always_comb begin + data_o = '0; + for (int i = 0 ; i < N ; i++) begin + if (winner[i]) begin + data_o = data_i[i]; + end + end + end + end else begin: gen_nodatapath + assign data_o = '1; + // The following signal is used to avoid possible lint errors. + logic [DW-1:0] unused_data [N]; + assign unused_data = data_i; + end + + always_comb begin + idx_o = '0; + for (int unsigned i = 0 ; i < N ; i++) begin + if (winner[i]) begin + idx_o = i[IdxW-1:0]; + end + end + end + end + + //////////////// + // assertions // + //////////////// + + // KNOWN assertions on outputs, except for data as that may be partially X in simulation + // e.g. when used on a BUS + `CALIPTRA_ASSERT_KNOWN(ValidKnown_A, valid_o) + `CALIPTRA_ASSERT_KNOWN(GrantKnown_A, gnt_o) + `CALIPTRA_ASSERT_KNOWN(IdxKnown_A, idx_o) + + // grant index shall be higher index than previous index, unless no higher requests exist. + `CALIPTRA_ASSERT(RoundRobin_A, + ##1 valid_o && ready_i && $past(ready_i) && $past(valid_o) && + |(req_i & ~((N'(1) << $past(idx_o)+1) - 1)) |-> + idx_o > $past(idx_o)) + // we can only grant one requestor at a time + `CALIPTRA_ASSERT(CheckHotOne_A, $onehot0(gnt_o)) + // A grant implies that the sink is ready + `CALIPTRA_ASSERT(GntImpliesReady_A, |gnt_o |-> ready_i) + // A grant implies that the arbiter asserts valid as well + `CALIPTRA_ASSERT(GntImpliesValid_A, |gnt_o |-> valid_o) + // A request and a sink that is ready imply a grant + `CALIPTRA_ASSERT(ReqAndReadyImplyGrant_A, |req_i && ready_i |-> |gnt_o) + // A request and a sink that is ready imply a grant + `CALIPTRA_ASSERT(ReqImpliesValid_A, |req_i |-> valid_o) + // Both conditions above combined and reversed + `CALIPTRA_ASSERT(ReadyAndValidImplyGrant_A, ready_i && valid_o |-> |gnt_o) + // Both conditions above combined and reversed + `CALIPTRA_ASSERT(NoReadyValidNoGrant_A, !(ready_i || valid_o) |-> gnt_o == 0) + // check index / grant correspond + `CALIPTRA_ASSERT(IndexIsCorrect_A, ready_i && valid_o |-> gnt_o[idx_o] && req_i[idx_o]) + +if (EnDataPort) begin: gen_data_port_assertion + // data flow + `CALIPTRA_ASSERT(DataFlow_A, ready_i && valid_o |-> data_o == data_i[idx_o]) +end + + // requests must stay asserted until they have been granted + `CALIPTRA_ASSUME(ReqStaysHighUntilGranted0_M, |req_i && !ready_i |=> + (req_i & $past(req_i)) == $past(req_i), clk_i, !rst_ni || !req_chk_i) + // check that the arbitration decision is held if the sink is not ready + `CALIPTRA_ASSERT(LockArbDecision_A, |req_i && !ready_i |=> idx_o == $past(idx_o), + clk_i, !rst_ni || !req_chk_i) + +// FPV-only assertions with symbolic variables +`ifdef FPV_ON + // symbolic variables + bit [IdxW-1:0] k; + bit ReadyIsStable; + bit ReqsAreStable; + + // constraints for symbolic variables + `CALIPTRA_ASSUME(KStable_M, ##1 $stable(k)) + `CALIPTRA_ASSUME(KRange_M, k < N) + // this is used enable checking for stable and unstable ready_i and req_i signals in the same run. + // the symbolic variables act like a switch that the solver can trun on and off. + `CALIPTRA_ASSUME(ReadyIsStable_M, ##1 $stable(ReadyIsStable)) + `CALIPTRA_ASSUME(ReqsAreStable_M, ##1 $stable(ReqsAreStable)) + `CALIPTRA_ASSUME(ReadyStable_M, ##1 !ReadyIsStable || $stable(ready_i)) + `CALIPTRA_ASSUME(ReqsStable_M, ##1 !ReqsAreStable || $stable(req_i)) + + // A grant implies a request + `CALIPTRA_ASSERT(GntImpliesReq_A, gnt_o[k] |-> req_i[k]) + + // if request and ready are constantly held at 1, we should eventually get a grant + `CALIPTRA_ASSERT(NoStarvation_A, + ReqsAreStable && ReadyIsStable && ready_i && req_i[k] |-> + strong(##[0:$] gnt_o[k])) + + // if N requests are constantly asserted and ready is constant 1, each request must + // be granted exactly once over a time window of N cycles for the arbiter to be fair. + for (genvar n = 1; n <= N; n++) begin : gen_fairness + integer gnt_cnt; + `CALIPTRA_ASSERT(Fairness_A, + ReqsAreStable && ReadyIsStable && ready_i && req_i[k] && + $countones(req_i) == n |-> + ##n gnt_cnt == $past(gnt_cnt, n) + 1) + + always_ff @(posedge clk_i or negedge rst_ni) begin : p_cnt + if (!rst_ni) begin + gnt_cnt <= 0; + end else begin + gnt_cnt <= gnt_cnt + gnt_o[k]; + end + end + end + + // requests must stay asserted until they have been granted + `CALIPTRA_ASSUME(ReqStaysHighUntilGranted1_M, req_i[k] && !gnt_o[k] |=> + req_i[k], clk_i, !rst_ni || !req_chk_i) +`endif + +endmodule : caliptra_prim_arbiter_ppc diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_arbiter_tree.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_arbiter_tree.sv new file mode 100644 index 0000000..012f19c --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_arbiter_tree.sv @@ -0,0 +1,291 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// N:1 arbiter module +// +// Verilog parameter +// N: Number of request ports +// DW: Data width +// DataPort: Set to 1 to enable the data port. Otherwise that port will be ignored. +// +// This is a tree implementation of a round robin arbiter. It has the same behavior as the PPC +// implementation in prim_arbiter_ppc, and also uses a prefix summing approach to determine the next +// request to be granted. The main difference with respect to the PPC arbiter is that the leading 1 +// detection and the prefix summation are performed with a binary tree instead of a sequential loop. +// Also, if the data port is enabled, the data is muxed based on the local arbitration decisions at +// each node of the arbiter tree. This means that the data can propagate through the tree +// simultaneously with the requests, instead of waiting for the arbitration to determine the winner +// index first. As a result, this design has a shorter critical path than other implementations, +// leading to better ovberall timing. +// +// Note that the currently winning request is held if the data sink is not ready. This behavior is +// required by some interconnect protocols (AXI, TL). The module contains an assertion that checks +// this behavior. +// +// Also, this module contains a request stability assertion that checks that requests stay asserted +// until they have been served. This assertion can be gated by driving the req_chk_i low. This is +// a non-functional input and does not affect the designs behavior. +// +// See also: prim_arbiter_ppc + +`include "caliptra_prim_assert.sv" + +module caliptra_prim_arbiter_tree #( + parameter int N = 8, + parameter int DW = 32, + + // Configurations + // EnDataPort: {0, 1}, if 0, input data will be ignored + parameter bit EnDataPort = 1, + + // Derived parameters + localparam int IdxW = $clog2(N) +) ( + input clk_i, + input rst_ni, + + input req_chk_i, // Used for gating assertions. Drive to 1 during normal + // operation. + input [ N-1:0] req_i, + input [DW-1:0] data_i [N], + output logic [ N-1:0] gnt_o, + output logic [IdxW-1:0] idx_o, + + output logic valid_o, + output logic [DW-1:0] data_o, + input ready_i +); + + // req_chk_i is used for gating assertions only. + logic unused_req_chk; + assign unused_req_chk = req_chk_i; + + `CALIPTRA_ASSERT_INIT(CheckNGreaterZero_A, N > 0) + + // this case is basically just a bypass + if (N == 1) begin : gen_degenerate_case + + assign valid_o = req_i[0]; + assign data_o = data_i[0]; + assign gnt_o[0] = valid_o & ready_i; + assign idx_o = '0; + + end else begin : gen_normal_case + + // align to powers of 2 for simplicity + // a full binary tree with N levels has 2**N + 2**N-1 nodes + logic [2**(IdxW+1)-2:0] req_tree; + logic [2**(IdxW+1)-2:0] prio_tree; + logic [2**(IdxW+1)-2:0] sel_tree; + logic [2**(IdxW+1)-2:0] mask_tree; + logic [2**(IdxW+1)-2:0][IdxW-1:0] idx_tree; + logic [2**(IdxW+1)-2:0][DW-1:0] data_tree; + logic [N-1:0] prio_mask_d, prio_mask_q; + + for (genvar level = 0; level < IdxW+1; level++) begin : gen_tree + // + // level+1 C0 C1 <- "Base1" points to the first node on "level+1", + // \ / these nodes are the children of the nodes one level below + // level Pa <- "Base0", points to the first node on "level", + // these nodes are the parents of the nodes one level above + // + // hence we have the following indices for the Pa, C0, C1 nodes: + // Pa = 2**level - 1 + offset = Base0 + offset + // C0 = 2**(level+1) - 1 + 2*offset = Base1 + 2*offset + // C1 = 2**(level+1) - 1 + 2*offset + 1 = Base1 + 2*offset + 1 + // + localparam int Base0 = (2**level)-1; + localparam int Base1 = (2**(level+1))-1; + + for (genvar offset = 0; offset < 2**level; offset++) begin : gen_level + localparam int Pa = Base0 + offset; + localparam int C0 = Base1 + 2*offset; + localparam int C1 = Base1 + 2*offset + 1; + + // this assigns the gated interrupt source signals, their + // corresponding IDs and priorities to the tree leafs + if (level == IdxW) begin : gen_leafs + if (offset < N) begin : gen_assign + // forward path (requests and data) + // all requests inputs are assigned to the request tree + assign req_tree[Pa] = req_i[offset]; + // we basically split the incoming request vector into two halves with the following + // priority assignment. the prio_mask_q register contains a prefix sum that has been + // computed using the last winning index, and hence masks out all requests at offsets + // lower or equal the previously granted index. hence, all higher indices are considered + // first in the arbitration tree nodes below, before considering the lower indices. + assign prio_tree[Pa] = req_i[offset] & prio_mask_q[offset]; + // input for the index muxes (used to compute the winner index) + assign idx_tree[Pa] = offset; + // input for the data muxes + assign data_tree[Pa] = data_i[offset]; + + // backward path (grants and prefix sum) + // grant if selected, ready and request asserted + assign gnt_o[offset] = req_i[offset] & sel_tree[Pa] & ready_i; + // only update mask if there is a valid request + assign prio_mask_d[offset] = (|req_i) ? + mask_tree[Pa] | sel_tree[Pa] & ~ready_i : + prio_mask_q[offset]; + end else begin : gen_tie_off + // forward path + assign req_tree[Pa] = '0; + assign prio_tree[Pa] = '0; + assign idx_tree[Pa] = '0; + assign data_tree[Pa] = '0; + logic unused_sigs; + assign unused_sigs = ^{mask_tree[Pa], + sel_tree[Pa]}; + end + // this creates the node assignments + end else begin : gen_nodes + // local helper variable + logic sel; + + // forward path (requests and data) + // each node looks at its two children, and selects the one with higher priority + assign sel = ~req_tree[C0] | ~prio_tree[C0] & prio_tree[C1]; + // propagate requests + assign req_tree[Pa] = req_tree[C0] | req_tree[C1]; + assign prio_tree[Pa] = prio_tree[C1] | prio_tree[C0]; + // data and index muxes + // Note: these ternaries have triggered a synthesis bug in Vivado versions older + // than 2020.2. If the problem resurfaces again, have a look at issue #1408. + assign idx_tree[Pa] = (sel) ? idx_tree[C1] : idx_tree[C0]; + assign data_tree[Pa] = (sel) ? data_tree[C1] : data_tree[C0]; + + // backward path (grants and prefix sum) + // this propagates the selction index back and computes a hot one mask + assign sel_tree[C0] = sel_tree[Pa] & ~sel; + assign sel_tree[C1] = sel_tree[Pa] & sel; + // this performs a prefix sum for masking the input requests in the next cycle + assign mask_tree[C0] = mask_tree[Pa]; + assign mask_tree[C1] = mask_tree[Pa] | sel_tree[C0]; + end + end : gen_level + end : gen_tree + + // the results can be found at the tree root + if (EnDataPort) begin : gen_data_port + assign data_o = data_tree[0]; + end else begin : gen_no_dataport + logic [DW-1:0] unused_data; + assign unused_data = data_tree[0]; + assign data_o = '1; + end + + // This index is unused. + logic unused_prio_tree; + assign unused_prio_tree = prio_tree[0]; + + assign idx_o = idx_tree[0]; + assign valid_o = req_tree[0]; + + // the select tree computes a hot one signal that indicates which request is currently selected + assign sel_tree[0] = 1'b1; + // the mask tree is basically a prefix sum of the hot one select signal computed above + assign mask_tree[0] = 1'b0; + + always_ff @(posedge clk_i or negedge rst_ni) begin : p_mask_reg + if (!rst_ni) begin + prio_mask_q <= '0; + end else begin + prio_mask_q <= prio_mask_d; + end + end + end + + //////////////// + // assertions // + //////////////// + + // KNOWN assertions on outputs, except for data as that may be partially X in simulation + // e.g. when used on a BUS + `CALIPTRA_ASSERT_KNOWN(ValidKnown_A, valid_o) + `CALIPTRA_ASSERT_KNOWN(GrantKnown_A, gnt_o) + `CALIPTRA_ASSERT_KNOWN(IdxKnown_A, idx_o) + + // grant index shall be higher index than previous index, unless no higher requests exist. + `CALIPTRA_ASSERT(RoundRobin_A, + ##1 valid_o && ready_i && $past(ready_i) && $past(valid_o) && + |(req_i & ~((N'(1) << $past(idx_o)+1) - 1)) |-> + idx_o > $past(idx_o)) + // we can only grant one requestor at a time + `CALIPTRA_ASSERT(CheckHotOne_A, $onehot0(gnt_o)) + // A grant implies that the sink is ready + `CALIPTRA_ASSERT(GntImpliesReady_A, |gnt_o |-> ready_i) + // A grant implies that the arbiter asserts valid as well + `CALIPTRA_ASSERT(GntImpliesValid_A, |gnt_o |-> valid_o) + // A request and a sink that is ready imply a grant + `CALIPTRA_ASSERT(ReqAndReadyImplyGrant_A, |req_i && ready_i |-> |gnt_o) + // A request and a sink that is ready imply a grant + `CALIPTRA_ASSERT(ReqImpliesValid_A, |req_i |-> valid_o) + // Both conditions above combined and reversed + `CALIPTRA_ASSERT(ReadyAndValidImplyGrant_A, ready_i && valid_o |-> |gnt_o) + // Both conditions above combined and reversed + `CALIPTRA_ASSERT(NoReadyValidNoGrant_A, !(ready_i || valid_o) |-> gnt_o == 0) + // check index / grant correspond + `CALIPTRA_ASSERT(IndexIsCorrect_A, ready_i && valid_o |-> gnt_o[idx_o] && req_i[idx_o]) + +if (EnDataPort) begin: gen_data_port_assertion + // data flow + `CALIPTRA_ASSERT(DataFlow_A, ready_i && valid_o |-> data_o == data_i[idx_o]) +end + + // requests must stay asserted until they have been granted + `CALIPTRA_ASSUME(ReqStaysHighUntilGranted0_M, |req_i && !ready_i |=> + (req_i & $past(req_i)) == $past(req_i), clk_i, !rst_ni || !req_chk_i) + // check that the arbitration decision is held if the sink is not ready + `CALIPTRA_ASSERT(LockArbDecision_A, |req_i && !ready_i |=> idx_o == $past(idx_o), + clk_i, !rst_ni || !req_chk_i) + +// FPV-only assertions with symbolic variables +`ifdef FPV_ON + // symbolic variables + int unsigned k; + bit ReadyIsStable; + bit ReqsAreStable; + + // constraints for symbolic variables + `CALIPTRA_ASSUME(KStable_M, ##1 $stable(k)) + `CALIPTRA_ASSUME(KRange_M, k < N) + // this is used enable checking for stable and unstable ready_i and req_i signals in the same run. + // the symbolic variables act like a switch that the solver can trun on and off. + `CALIPTRA_ASSUME(ReadyIsStable_M, ##1 $stable(ReadyIsStable)) + `CALIPTRA_ASSUME(ReqsAreStable_M, ##1 $stable(ReqsAreStable)) + `CALIPTRA_ASSUME(ReadyStable_M, ##1 !ReadyIsStable || $stable(ready_i)) + `CALIPTRA_ASSUME(ReqsStable_M, ##1 !ReqsAreStable || $stable(req_i)) + + // A grant implies a request + `CALIPTRA_ASSERT(GntImpliesReq_A, gnt_o[k] |-> req_i[k]) + + // if request and ready are constantly held at 1, we should eventually get a grant + `CALIPTRA_ASSERT(NoStarvation_A, + ReqsAreStable && ReadyIsStable && ready_i && req_i[k] |-> + strong(##[0:$] gnt_o[k])) + + // if N requests are constantly asserted and ready is constant 1, each request must + // be granted exactly once over a time window of N cycles for the arbiter to be fair. + for (genvar n = 1; n <= N; n++) begin : gen_fairness + integer gnt_cnt; + `CALIPTRA_ASSERT(Fairness_A, + ReqsAreStable && ReadyIsStable && ready_i && req_i[k] && + $countones(req_i) == n |-> + ##n gnt_cnt == $past(gnt_cnt, n) + 1) + + always_ff @(posedge clk_i or negedge rst_ni) begin : p_cnt + if (!rst_ni) begin + gnt_cnt <= 0; + end else begin + gnt_cnt <= gnt_cnt + gnt_o[k]; + end + end + end + + // requests must stay asserted until they have been granted + `CALIPTRA_ASSUME(ReqStaysHighUntilGranted1_M, req_i[k] && !gnt_o[k] |=> + req_i[k], clk_i, !rst_ni || !req_chk_i) +`endif + +endmodule : caliptra_prim_arbiter_tree diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_assert.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_assert.sv new file mode 100644 index 0000000..cf40b09 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_assert.sv @@ -0,0 +1,191 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// Macros and helper code for using assertions. +// - Provides default clk and rst options to simplify code +// - Provides boiler plate template for common assertions + +`ifndef CALIPTRA_PRIM_ASSERT_SV +`define CALIPTRA_PRIM_ASSERT_SV + +/////////////////// +// Helper macros // +/////////////////// + +`include "caliptra_sva.svh" +`ifndef CALIPTRA_SVA +// Default clk and reset signals used by assertion macros below. +`define CALIPTRA_ASSERT_DEFAULT_CLK clk_i +`define CALIPTRA_ASSERT_DEFAULT_RST !rst_ni +`endif + +// Converts an arbitrary block of code into a Verilog string +`define CALIPTRA_PRIM_STRINGIFY(__x) `"__x`" + +// CALIPTRA_ASSERT_ERROR logs an error message with either `uvm_error or with $error. +// +// This somewhat duplicates `DV_ERROR macro defined in hw/dv/sv/dv_utils/dv_macros.svh. The reason +// for redefining it here is to avoid creating a dependency. +`define CALIPTRA_ASSERT_ERROR(__name) \ +`ifdef UVM \ + uvm_pkg::uvm_report_error("CALIPTRA_ASSERT FAILED", `CALIPTRA_PRIM_STRINGIFY(__name), uvm_pkg::UVM_NONE, \ + `__FILE__, `__LINE__); \ +`else \ + $error("%0t: (%0s:%0d) [%m] [CALIPTRA_ASSERT FAILED] %0s", $time, `__FILE__, `__LINE__, \ + `CALIPTRA_PRIM_STRINGIFY(__name)); \ +`endif + +// This macro is suitable for conditionally triggering lint errors, e.g., if a Sec parameter takes +// on a non-default value. This may be required for pre-silicon/FPGA evaluation but we don't want +// to allow this for tapeout. +`define CALIPTRA_ASSERT_STATIC_LINT_ERROR(__name, __prop) \ + localparam int __name = (__prop) ? 1 : 2; \ + always_comb begin \ + logic unused_assert_static_lint_error; \ + unused_assert_static_lint_error = __name'(1'b1); \ + end + +// Static assertions for checks inside SV packages. If the conditions is not true, this will +// trigger an error during elaboration. +`define CALIPTRA_ASSERT_STATIC_IN_PACKAGE(__name, __prop) \ + function automatic logic assert_static_in_package_``__name(); \ + logic unused_sig [((__prop) ? 1 : -1)]; \ + unused_sig = '{default: 1'b0}; \ + return unused_sig[0]; \ + endfunction + +// The basic helper macros are actually defined in "implementation headers". The macros should do +// the same thing in each case (except for the dummy flavour), but in a way that the respective +// tools support. +// +// If the tool supports assertions in some form, we also define CALIPTRA_INC_ASSERT (which can be +// used to hide signal definitions that are only used for assertions). +// +// The list of basic macros supported is: +// +// CALIPTRA_ASSERT_I: Immediate assertion. Note that immediate assertions are sensitive to simulation +// glitches. +// +// CALIPTRA_ASSERT_INIT: Assertion in initial block. Can be used for things like parameter checking. +// +// CALIPTRA_ASSERT_INIT_NET: Assertion in initial block. Can be used for initial value of a net. +// +// CALIPTRA_ASSERT_FINAL: Assertion in final block. Can be used for things like queues being empty at end of +// sim, all credits returned at end of sim, state machines in idle at end of sim. +// +// CALIPTRA_ASSERT_AT_RESET: Assertion just before reset. Can be used to check sum-like properties that get +// cleared at reset. +// Note that unless your simulation ends with a reset, the property does not get +// checked at end of simulation; use CALIPTRA_ASSERT_AT_RESET_AND_FINAL if the property +// should also get checked at end of simulation. +// +// CALIPTRA_ASSERT_AT_RESET_AND_FINAL: Assertion just before reset and in final block. Can be used to check +// sum-like properties before every reset and at the end of simulation. +// +// CALIPTRA_ASSERT: Assert a concurrent property directly. It can be called as a module caliptra_(or +// interface) body item. +// +// Note: We use (__rst !== '0) in the disable iff statements instead of (__rst == +// '1). This properly disables the assertion in cases when reset is X at the +// beginning of a simulation. For that case, (reset == '1) does not disable the +// assertion. +// +// CALIPTRA_ASSERT_NEVER: Assert a concurrent property NEVER happens +// +// CALIPTRA_ASSERT_KNOWN: Assert that signal has a known value (each bit is either '0' or '1') after reset. +// It can be called as a module (or interface) body item. +// +// CALIPTRA_COVER: Cover a concurrent property +// +// CALIPTRA_ASSUME: Assume a concurrent property +// +// CALIPTRA_ASSUME_I: Assume an immediate property + +`ifdef VERILATOR + `include "caliptra_prim_assert_dummy_macros.svh" +`elsif SYNTHESIS + `include "caliptra_prim_assert_dummy_macros.svh" +`elsif YOSYS + `include "caliptra_prim_assert_yosys_macros.svh" + `define CALIPTRA_INC_ASSERT +`else + `include "caliptra_prim_assert_standard_macros.svh" + `define CALIPTRA_INC_ASSERT +`endif + +////////////////////////////// +// Complex assertion macros // +////////////////////////////// + +// Assert that signal is an active-high pulse with pulse length of 1 clock cycle +`define CALIPTRA_ASSERT_PULSE(__name, __sig, __clk = `CALIPTRA_ASSERT_DEFAULT_CLK, __rst = `CALIPTRA_ASSERT_DEFAULT_RST) \ + `CALIPTRA_ASSERT(__name, $rose(__sig) |=> !(__sig), __clk, __rst) + +// Assert that a property is true only when an enable signal is set. It can be called as a module +// (or interface) body item. +`define CALIPTRA_ASSERT_IF(__name, __prop, __enable, __clk = `CALIPTRA_ASSERT_DEFAULT_CLK, __rst = `CALIPTRA_ASSERT_DEFAULT_RST) \ + `CALIPTRA_ASSERT(__name, (__enable) |-> (__prop), __clk, __rst) + +// Assert that signal has a known value (each bit is either '0' or '1') after reset if enable is +// set. It can be called as a module (or interface) body item. +`define CALIPTRA_ASSERT_KNOWN_IF(__name, __sig, __enable, __clk = `CALIPTRA_ASSERT_DEFAULT_CLK, __rst = `CALIPTRA_ASSERT_DEFAULT_RST) \ + `CALIPTRA_ASSERT_KNOWN(__name``KnownEnable, __enable, __clk, __rst) \ + `CALIPTRA_ASSERT_IF(__name, !$isunknown(__sig), __enable, __clk, __rst) + +////////////////////////////////// +// For formal verification only // +////////////////////////////////// + +// Note that the existing set of CALIPTRA_ASSERT macros specified above shall be used for FPV, +// thereby ensuring that the assertions are evaluated during DV simulations as well. + +// CALIPTRA_ASSUME_FPV +// Assume a concurrent property during formal verification only. +`define CALIPTRA_ASSUME_FPV(__name, __prop, __clk = `CALIPTRA_ASSERT_DEFAULT_CLK, __rst = `CALIPTRA_ASSERT_DEFAULT_RST) \ +`ifdef FPV_ON \ + `CALIPTRA_ASSUME(__name, __prop, __clk, __rst) \ +`endif + +// CALIPTRA_ASSUME_I_FPV +// Assume a concurrent property during formal verification only. +`define CALIPTRA_ASSUME_I_FPV(__name, __prop) \ +`ifdef FPV_ON \ + `CALIPTRA_ASSUME_I(__name, __prop) \ +`endif + +// CALIPTRA_COVER_FPV +// Cover a concurrent property during formal verification +`define CALIPTRA_COVER_FPV(__name, __prop, __clk = `CALIPTRA_ASSERT_DEFAULT_CLK, __rst = `CALIPTRA_ASSERT_DEFAULT_RST) \ +`ifdef FPV_ON \ + `CALIPTRA_COVER(__name, __prop, __clk, __rst) \ +`endif + +// FPV assertion that proves that the FSM control flow is linear (no loops) +// The sequence triggers whenever the state changes and stores the current state as "initial_state". +// Then thereafter we must never see that state again until reset. +// It is possible for the reset to release ahead of the clock. +// Create a small "gray" window beyond the usual rst time to avoid +// checking. +`define CALIPTRA_ASSERT_FPV_LINEAR_FSM(__name, __state, __type, __clk = `CALIPTRA_ASSERT_DEFAULT_CLK, __rst = `CALIPTRA_ASSERT_DEFAULT_RST) \ + `ifdef CALIPTRA_INC_ASSERT \ + bit __name``_cond; \ + always_ff @(posedge __clk or posedge __rst) begin \ + if (__rst) begin \ + __name``_cond <= 0; \ + end else begin \ + __name``_cond <= 1; \ + end \ + end \ + property __name``_p; \ + __type initial_state; \ + (!$stable(__state) & __name``_cond, initial_state = $past(__state)) |-> \ + (__state != initial_state) until (__rst == 1'b1); \ + endproperty \ + `CALIPTRA_ASSERT(__name, __name``_p, __clk, __rst) \ + `endif + +`include "caliptra_prim_assert_sec_cm.svh" +`include "caliptra_prim_flop_macros.sv" + +`endif // CALIPTRA_PRIM_ASSERT_SV diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_assert_dummy_macros.svh b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_assert_dummy_macros.svh new file mode 100644 index 0000000..32803db --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_assert_dummy_macros.svh @@ -0,0 +1,22 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// Macro bodies included by caliptra_prim_assert.sv for tools that don't support assertions. See +// caliptra_prim_assert.sv for documentation for each of the macros. + +`define CALIPTRA_ASSERT_I(__name, __prop) +`define CALIPTRA_ASSERT_INIT(__name, __prop) +`define CALIPTRA_ASSERT_INIT_NET(__name, __prop) +`define CALIPTRA_ASSERT_FINAL(__name, __prop) +`define CALIPTRA_ASSERT_AT_RESET(__name, __prop, __rst = `CALIPTRA_ASSERT_DEFAULT_RST) +`define CALIPTRA_ASSERT_AT_RESET_AND_FINAL(__name, __prop, __rst = `CALIPTRA_ASSERT_DEFAULT_RST) +`define CALIPTRA_WITHIN_MARGIN(__actual, __expected, __allowed_less, __allowed_more) +`ifndef CALIPTRA_SVA +`define CALIPTRA_ASSERT(__name, __prop, __clk = `CALIPTRA_ASSERT_DEFAULT_CLK, __rst = `CALIPTRA_ASSERT_DEFAULT_RST) +`define CALIPTRA_ASSERT_NEVER(__name, __prop, __clk = `CALIPTRA_ASSERT_DEFAULT_CLK, __rst = `CALIPTRA_ASSERT_DEFAULT_RST) +`define CALIPTRA_ASSERT_KNOWN(__name, __sig, __clk = `CALIPTRA_ASSERT_DEFAULT_CLK, __rst = `CALIPTRA_ASSERT_DEFAULT_RST) +`endif +`define CALIPTRA_COVER(__name, __prop, __clk = `CALIPTRA_ASSERT_DEFAULT_CLK, __rst = `CALIPTRA_ASSERT_DEFAULT_RST) +`define CALIPTRA_ASSUME(__name, __prop, __clk = `CALIPTRA_ASSERT_DEFAULT_CLK, __rst = `CALIPTRA_ASSERT_DEFAULT_RST) +`define CALIPTRA_ASSUME_I(__name, __prop) diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_assert_sec_cm.svh b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_assert_sec_cm.svh new file mode 100644 index 0000000..3d642c5 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_assert_sec_cm.svh @@ -0,0 +1,86 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// // Macros and helper code for security countermeasures. + +`ifndef CALIPTRA_PRIM_ASSERT_SEC_CM_SVH +`define CALIPTRA_PRIM_ASSERT_SEC_CM_SVH + +`define _CALIPTRA_SEC_CM_ALERT_MAX_CYC 30 + +// When a named error signal rises, expect to see an associated error in at most MAX_CYCLES_ cycles. +// +// The NAME_ argument gets included in the name of the generated assertion, following an FpSecCm +// prefix. The error signal should be at HIER_.ERR_NAME_ and the posedge is ignored if GATE_ is +// true. +// +// This macro drives a magic "unused_assert_connected" signal, which is used for a static check to +// ensure the assertions are in place. +`define CALIPTRA_ASSERT_ERROR_TRIGGER_ERR(NAME_, HIER_, ERR_, GATE_, MAX_CYCLES_, ERR_NAME_, CLK_, RST_) \ + `CALIPTRA_ASSERT(FpvSecCm``NAME_``, \ + $rose(HIER_.ERR_NAME_) && !(GATE_) |-> ##[0:MAX_CYCLES_] (ERR_), \ + CLK_, RST_) \ + `ifdef CALIPTRA_INC_ASSERT \ + assign HIER_.unused_assert_connected = 1'b1; \ + `endif + +// When an error signal rises, expect to see the associated alert in at most MAX_CYCLE_ cycles. +// +// The NAME_, HIER_, GATE_, MAX_CYCLES_ and ERR_NAME_ arguments are the same as for +// `CALIPTRA_ASSERT_ERROR_TRIGGER_ERR. The ALERT_ argument is the name of the alert that we expect to be +// asserted. +// +// This macro adds an assumption that says the named error signal will stay low for the first 10 +// cycles after reset. +`define CALIPTRA_ASSERT_ERROR_TRIGGER_ALERT(NAME_, HIER_, ALERT_, GATE_, MAX_CYCLES_, ERR_NAME_) \ + `CALIPTRA_ASSERT_ERROR_TRIGGER_ERR(NAME_, HIER_, (ALERT_.alert_p), GATE_, MAX_CYCLES_, ERR_NAME_, \ + `CALIPTRA_ASSERT_DEFAULT_CLK, `CALIPTRA_ASSERT_DEFAULT_RST) \ + `CALIPTRA_ASSUME_FPV(``NAME_``TriggerAfterAlertInit_S, \ + $stable(rst_ni) == 0 |-> HIER_.ERR_NAME_ == 0 [*10]) + +//////////////////////////////////////////////////////////////////////////////// +// +// Assertions for CMs that trigger alerts +// +//////////////////////////////////////////////////////////////////////////////// + +`define CALIPTRA_ASSERT_PRIM_COUNT_ERROR_TRIGGER_ALERT(NAME_, HIER_, ALERT_, GATE_ = 0, MAX_CYCLES_ = `_CALIPTRA_SEC_CM_ALERT_MAX_CYC) \ + `CALIPTRA_ASSERT_ERROR_TRIGGER_ALERT(NAME_, HIER_, ALERT_, GATE_, MAX_CYCLES_, err_o) + +`define CALIPTRA_ASSERT_PRIM_DOUBLE_LFSR_ERROR_TRIGGER_ALERT(NAME_, HIER_, ALERT_, GATE_ = 0, MAX_CYCLES_ = `_CALIPTRA_SEC_CM_ALERT_MAX_CYC) \ + `CALIPTRA_ASSERT_ERROR_TRIGGER_ALERT(NAME_, HIER_, ALERT_, GATE_, MAX_CYCLES_, err_o) + +`define CALIPTRA_ASSERT_PRIM_FSM_ERROR_TRIGGER_ALERT(NAME_, HIER_, ALERT_, GATE_ = 0, MAX_CYCLES_ = `_CALIPTRA_SEC_CM_ALERT_MAX_CYC) \ + `CALIPTRA_ASSERT_ERROR_TRIGGER_ALERT(NAME_, HIER_, ALERT_, GATE_, MAX_CYCLES_, unused_err_o) + +`define CALIPTRA_ASSERT_PRIM_ONEHOT_ERROR_TRIGGER_ALERT(NAME_, HIER_, ALERT_, GATE_ = 0, MAX_CYCLES_ = `_CALIPTRA_SEC_CM_ALERT_MAX_CYC) \ + `CALIPTRA_ASSERT_ERROR_TRIGGER_ALERT(NAME_, HIER_, ALERT_, GATE_, MAX_CYCLES_, err_o) + +`define CALIPTRA_ASSERT_PRIM_REG_WE_ONEHOT_ERROR_TRIGGER_ALERT(NAME_, REG_TOP_HIER_, ALERT_, GATE_ = 0, MAX_CYCLES_ = `_CALIPTRA_SEC_CM_ALERT_MAX_CYC) \ + `CALIPTRA_ASSERT_PRIM_ONEHOT_ERROR_TRIGGER_ALERT(NAME_, \ + REG_TOP_HIER_.u_caliptra_prim_reg_we_check.u_caliptra_prim_onehot_check, ALERT_, GATE_, MAX_CYCLES_) + +//////////////////////////////////////////////////////////////////////////////// +// +// Assertions for CMs that trigger some other form of error +// +//////////////////////////////////////////////////////////////////////////////// + +`define CALIPTRA_ASSERT_PRIM_FSM_ERROR_TRIGGER_ERR(NAME_, HIER_, ERR_, GATE_ = 0, MAX_CYCLES_ = 2, CLK_ = clk_i, RST_ = !rst_ni) \ + `CALIPTRA_ASSERT_ERROR_TRIGGER_ERR(NAME_, HIER_, ERR_, GATE_, MAX_CYCLES_, unused_err_o, CLK_, RST_) + +`define CALIPTRA_ASSERT_PRIM_COUNT_ERROR_TRIGGER_ERR(NAME_, HIER_, ERR_, GATE_ = 0, MAX_CYCLES_ = 2, CLK_ = clk_i, RST_ = !rst_ni) \ + `CALIPTRA_ASSERT_ERROR_TRIGGER_ERR(NAME_, HIER_, ERR_, GATE_, MAX_CYCLES_, err_o, CLK_, RST_) + +`define CALIPTRA_ASSERT_PRIM_DOUBLE_LFSR_ERROR_TRIGGER_ERR(NAME_, HIER_, ERR_, GATE_ = 0, MAX_CYCLES_ = 2, CLK_ = clk_i, RST_ = !rst_ni) \ + `CALIPTRA_ASSERT_ERROR_TRIGGER_ERR(NAME_, HIER_, ERR_, GATE_, MAX_CYCLES_, err_o, CLK_, RST_) + +`define CALIPTRA_ASSERT_PRIM_ONEHOT_ERROR_TRIGGER_ERR(NAME_, HIER_, ERR_, GATE_ = 0, MAX_CYCLES_ = `_CALIPTRA_SEC_CM_ALERT_MAX_CYC, CLK_ = clk_i, RST_ = !rst_ni) \ + `CALIPTRA_ASSERT_ERROR_TRIGGER_ERR(NAME_, HIER_, ERR_, GATE_, MAX_CYCLES_, err_o, CLK_, RST_) + +`define CALIPTRA_ASSERT_PRIM_REG_WE_ONEHOT_ERROR_TRIGGER_ERR(NAME_, REG_TOP_HIER_, ERR_, GATE_ = 0, MAX_CYCLES_ = `_CALIPTRA_SEC_CM_ALERT_MAX_CYC, CLK_ = clk_i, RST_ = !rst_ni) \ + `CALIPTRA_ASSERT_PRIM_ONEHOT_ERROR_TRIGGER_ERR(NAME_, \ + REG_TOP_HIER_.u_prim_reg_we_check.u_prim_onehot_check, ERR_, GATE_, MAX_CYCLES_, CLK_, RST_) + +`endif // CALIPTRA_PRIM_ASSERT_SEC_CM_SVH diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_blanker.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_blanker.sv new file mode 100644 index 0000000..961ac7d --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_blanker.sv @@ -0,0 +1,22 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +`include "caliptra_prim_module_name_macros.svh" + +// Convenience module for wrapping caliptra_prim_and2 for use in blanking. +// When en_i == 1 the input is fed through to the output. +// When en_i == 0 the output is 0. +module caliptra_prim_blanker #( + parameter int Width = 1 +) ( + input logic [Width-1:0] in_i, + input logic en_i, + output logic [Width-1:0] out_o +); + `CALIPTRA_PRIM_MODULE_NAME(and2) #(.Width(Width)) u_blank_and ( + .in0_i(in_i), + .in1_i({Width{en_i}}), + .out_o + ); +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_buf.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_buf.sv new file mode 100755 index 0000000..6a23078 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_buf.sv @@ -0,0 +1,44 @@ +// Copyright lowRISC contributors. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// This file is auto-generated. +// Used parser: Verible + +`include "caliptra_prim_module_name_macros.svh" + +`ifndef CALIPTRA_PRIM_DEFAULT_IMPL + `define CALIPTRA_PRIM_DEFAULT_IMPL caliptra_prim_pkg::ImplGeneric +`endif + +// This is to prevent AscentLint warnings in the generated +// abstract prim wrapper. These warnings occur due to the .* +// use. TODO: we may want to move these inline waivers +// into a separate, generated waiver file for consistency. +//ri lint_check_off OUTPUT_NOT_DRIVEN INPUT_NOT_READ HIER_BRANCH_NOT_READ +module caliptra_prim_buf + +#( +parameter int Width = 1 +) ( + input [Width-1:0] in_i, + output logic [Width-1:0] out_o +); + parameter caliptra_prim_pkg::impl_e Impl = `CALIPTRA_PRIM_DEFAULT_IMPL; + +if (Impl == caliptra_prim_pkg::ImplXilinx) begin : gen_xilinx + caliptra_prim_xilinx_buf #( + .Width(Width) + ) u_impl_xilinx ( + .* + ); +end else begin : gen_generic + `CALIPTRA_PRIM_MODULE_NAME(buf) #( + .Width(Width) + ) u_impl_generic ( + .* + ); +end + +endmodule +//ri lint_check_on OUTPUT_NOT_DRIVEN INPUT_NOT_READ HIER_BRANCH_NOT_READ diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_cdc_rand_delay.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_cdc_rand_delay.sv new file mode 100644 index 0000000..1b3ca73 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_cdc_rand_delay.sv @@ -0,0 +1,67 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// This module should be instantiated within flops of CDC synchronization primitives, +// and allows DV to model real CDC delays within simulations, especially useful at the chip level +// or in IPs that communicate across clock domains. +// +// The instrumentation is very simple: when this is enabled the input into the first +// synchronizer flop has a mux where the select is randomly set. One of the mux inputs is the input +// of this module, and the other is the output of the first flop: selecting the latter models the +// effect of the first flop missing the input transition. +// +// Notice the delay should cause the input to be skipped by at most a single cycle. As a perhaps +// unnecessary precaution, the select will only be allowed to be random when the input changes. + +module caliptra_prim_cdc_rand_delay #( + parameter int DataWidth = 1, + parameter bit Enable = 1 +) ( + input logic clk_i, + input logic rst_ni, + input logic [DataWidth-1:0] prev_data_i, + input logic [DataWidth-1:0] src_data_i, + output logic [DataWidth-1:0] dst_data_o +); +`ifdef SIMULATION + if (Enable) begin : gen_enable + + // This controls dst_data_o: any bit with its data_sel set uses prev_data_i, others use + // src_data_i. + bit [DataWidth-1:0] data_sel; + bit cdc_instrumentation_enabled; + + function automatic bit [DataWidth-1:0] fast_randomize(); + bit [DataWidth-1:0] data; + if (DataWidth <= 32) begin + data = $urandom(); + end else begin + if (!std::randomize(data)) $fatal(1, "%t: [%m] Failed to randomize data", $time); + end + return data; + endfunction + + initial begin + void'($value$plusargs("cdc_instrumentation_enabled=%d", cdc_instrumentation_enabled)); + data_sel = '0; + end + + // Set data_sel at random combinationally when the input changes. + always @(src_data_i) begin + data_sel = cdc_instrumentation_enabled ? fast_randomize() : 0; + end + + // Clear data_del on any cycle start. + always @(posedge clk_i or negedge rst_ni) begin + data_sel <= 0; + end + + always_comb dst_data_o = (prev_data_i & data_sel) | (src_data_i & ~data_sel); + end else begin : gen_no_enable + assign dst_data_o = src_data_i; + end +`else // SIMULATION + assign dst_data_o = src_data_i; +`endif // SIMULATION +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_cipher_pkg.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_cipher_pkg.sv new file mode 100644 index 0000000..ce553f8 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_cipher_pkg.sv @@ -0,0 +1,397 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// This package holds common constants and functions for PRESENT- and +// PRINCE-based scrambling devices. +// +// See also: caliptra_prim_present, caliptra_prim_prince +// +// References: - https://en.wikipedia.org/wiki/PRESENT +// - https://en.wikipedia.org/wiki/Prince_(cipher) +// - http://www.lightweightcrypto.org/present/present_ches2007.pdf +// - https://eprint.iacr.org/2012/529.pdf +// - https://eprint.iacr.org/2015/372.pdf +// - https://eprint.iacr.org/2014/656.pdf + +package caliptra_prim_cipher_pkg; + + /////////////////// + // PRINCE Cipher // + /////////////////// + + parameter logic [15:0][3:0] PRINCE_SBOX4 = {4'h4, 4'hD, 4'h5, 4'hE, + 4'h0, 4'h8, 4'h7, 4'h6, + 4'h1, 4'h9, 4'hC, 4'hA, + 4'h2, 4'h3, 4'hF, 4'hB}; + + parameter logic [15:0][3:0] PRINCE_SBOX4_INV = {4'h1, 4'hC, 4'hE, 4'h5, + 4'h0, 4'h4, 4'h6, 4'hA, + 4'h9, 4'h8, 4'hD, 4'hF, + 4'h2, 4'h3, 4'h7, 4'hB}; + // nibble permutations + parameter logic [15:0][3:0] PRINCE_SHIFT_ROWS64 = '{4'hF, 4'hA, 4'h5, 4'h0, + 4'hB, 4'h6, 4'h1, 4'hC, + 4'h7, 4'h2, 4'hD, 4'h8, + 4'h3, 4'hE, 4'h9, 4'h4}; + + parameter logic [15:0][3:0] PRINCE_SHIFT_ROWS64_INV = '{4'hF, 4'h2, 4'h5, 4'h8, + 4'hB, 4'hE, 4'h1, 4'h4, + 4'h7, 4'hA, 4'hD, 4'h0, + 4'h3, 4'h6, 4'h9, 4'hC}; + + // these are the round constants + parameter logic [11:0][63:0] PRINCE_ROUND_CONST = {64'hC0AC29B7C97C50DD, + 64'hD3B5A399CA0C2399, + 64'h64A51195E0E3610D, + 64'hC882D32F25323C54, + 64'h85840851F1AC43AA, + 64'h7EF84F78FD955CB1, + 64'hBE5466CF34E90C6C, + 64'h452821E638D01377, + 64'h082EFA98EC4E6C89, + 64'hA4093822299F31D0, + 64'h13198A2E03707344, + 64'h0000000000000000}; + + // tweak constant for key modification between enc/dec modes + parameter logic [63:0] PRINCE_ALPHA_CONST = 64'hC0AC29B7C97C50DD; + + // masking constants for shift rows function below + parameter logic [15:0] PRINCE_SHIFT_ROWS_CONST0 = 16'h7BDE; + parameter logic [15:0] PRINCE_SHIFT_ROWS_CONST1 = 16'hBDE7; + parameter logic [15:0] PRINCE_SHIFT_ROWS_CONST2 = 16'hDE7B; + parameter logic [15:0] PRINCE_SHIFT_ROWS_CONST3 = 16'hE7BD; + + // nibble shifts + function automatic logic [31:0] prince_shiftrows_32bit(logic [31:0] state_in, + logic [15:0][3:0] shifts ); + logic [31:0] state_out; + // note that if simulation performance becomes an issue, this loop can be unrolled + for (int k = 0; k < 32/2; k++) begin + // operate on pairs of 2bit instead of nibbles + state_out[k*2 +: 2] = state_in[shifts[k]*2 +: 2]; + end + return state_out; + endfunction : prince_shiftrows_32bit + + function automatic logic [63:0] prince_shiftrows_64bit(logic [63:0] state_in, + logic [15:0][3:0] shifts ); + logic [63:0] state_out; + // note that if simulation performance becomes an issue, this loop can be unrolled + for (int k = 0; k < 64/4; k++) begin + state_out[k*4 +: 4] = state_in[shifts[k]*4 +: 4]; + end + return state_out; + endfunction : prince_shiftrows_64bit + + // XOR reduction of four nibbles in a 16bit subvector + function automatic logic [3:0] prince_nibble_red16(logic [15:0] vect); + return vect[0 +: 4] ^ vect[4 +: 4] ^ vect[8 +: 4] ^ vect[12 +: 4]; + endfunction : prince_nibble_red16 + + // M prime multiplication + function automatic logic [31:0] prince_mult_prime_32bit(logic [31:0] state_in); + logic [31:0] state_out; + // M0 + state_out[0 +: 4] = prince_nibble_red16(state_in[ 0 +: 16] & PRINCE_SHIFT_ROWS_CONST3); + state_out[4 +: 4] = prince_nibble_red16(state_in[ 0 +: 16] & PRINCE_SHIFT_ROWS_CONST2); + state_out[8 +: 4] = prince_nibble_red16(state_in[ 0 +: 16] & PRINCE_SHIFT_ROWS_CONST1); + state_out[12 +: 4] = prince_nibble_red16(state_in[ 0 +: 16] & PRINCE_SHIFT_ROWS_CONST0); + // M1 + state_out[16 +: 4] = prince_nibble_red16(state_in[16 +: 16] & PRINCE_SHIFT_ROWS_CONST0); + state_out[20 +: 4] = prince_nibble_red16(state_in[16 +: 16] & PRINCE_SHIFT_ROWS_CONST3); + state_out[24 +: 4] = prince_nibble_red16(state_in[16 +: 16] & PRINCE_SHIFT_ROWS_CONST2); + state_out[28 +: 4] = prince_nibble_red16(state_in[16 +: 16] & PRINCE_SHIFT_ROWS_CONST1); + return state_out; + endfunction : prince_mult_prime_32bit + + // M prime multiplication + function automatic logic [63:0] prince_mult_prime_64bit(logic [63:0] state_in); + logic [63:0] state_out; + // M0 + state_out[0 +: 4] = prince_nibble_red16(state_in[ 0 +: 16] & PRINCE_SHIFT_ROWS_CONST3); + state_out[4 +: 4] = prince_nibble_red16(state_in[ 0 +: 16] & PRINCE_SHIFT_ROWS_CONST2); + state_out[8 +: 4] = prince_nibble_red16(state_in[ 0 +: 16] & PRINCE_SHIFT_ROWS_CONST1); + state_out[12 +: 4] = prince_nibble_red16(state_in[ 0 +: 16] & PRINCE_SHIFT_ROWS_CONST0); + // M1 + state_out[16 +: 4] = prince_nibble_red16(state_in[16 +: 16] & PRINCE_SHIFT_ROWS_CONST0); + state_out[20 +: 4] = prince_nibble_red16(state_in[16 +: 16] & PRINCE_SHIFT_ROWS_CONST3); + state_out[24 +: 4] = prince_nibble_red16(state_in[16 +: 16] & PRINCE_SHIFT_ROWS_CONST2); + state_out[28 +: 4] = prince_nibble_red16(state_in[16 +: 16] & PRINCE_SHIFT_ROWS_CONST1); + // M1 + state_out[32 +: 4] = prince_nibble_red16(state_in[32 +: 16] & PRINCE_SHIFT_ROWS_CONST0); + state_out[36 +: 4] = prince_nibble_red16(state_in[32 +: 16] & PRINCE_SHIFT_ROWS_CONST3); + state_out[40 +: 4] = prince_nibble_red16(state_in[32 +: 16] & PRINCE_SHIFT_ROWS_CONST2); + state_out[44 +: 4] = prince_nibble_red16(state_in[32 +: 16] & PRINCE_SHIFT_ROWS_CONST1); + // M0 + state_out[48 +: 4] = prince_nibble_red16(state_in[48 +: 16] & PRINCE_SHIFT_ROWS_CONST3); + state_out[52 +: 4] = prince_nibble_red16(state_in[48 +: 16] & PRINCE_SHIFT_ROWS_CONST2); + state_out[56 +: 4] = prince_nibble_red16(state_in[48 +: 16] & PRINCE_SHIFT_ROWS_CONST1); + state_out[60 +: 4] = prince_nibble_red16(state_in[48 +: 16] & PRINCE_SHIFT_ROWS_CONST0); + return state_out; + endfunction : prince_mult_prime_64bit + + + //////////////////// + // PRESENT Cipher // + //////////////////// + + // this is the sbox from the present cipher + parameter logic [15:0][3:0] PRESENT_SBOX4 = {4'h2, 4'h1, 4'h7, 4'h4, + 4'h8, 4'hF, 4'hE, 4'h3, + 4'hD, 4'hA, 4'h0, 4'h9, + 4'hB, 4'h6, 4'h5, 4'hC}; + + parameter logic [15:0][3:0] PRESENT_SBOX4_INV = {4'hA, 4'h9, 4'h7, 4'h0, + 4'h3, 4'h6, 4'h4, 4'hB, + 4'hD, 4'h2, 4'h1, 4'hC, + 4'h8, 4'hF, 4'hE, 4'h5}; + + // these are modified permutation indices for a 32bit version that + // follow the same pattern as for the 64bit version + parameter logic [31:0][4:0] PRESENT_PERM32 = {5'd31, 5'd23, 5'd15, 5'd07, + 5'd30, 5'd22, 5'd14, 5'd06, + 5'd29, 5'd21, 5'd13, 5'd05, + 5'd28, 5'd20, 5'd12, 5'd04, + 5'd27, 5'd19, 5'd11, 5'd03, + 5'd26, 5'd18, 5'd10, 5'd02, + 5'd25, 5'd17, 5'd09, 5'd01, + 5'd24, 5'd16, 5'd08, 5'd00}; + + parameter logic [31:0][4:0] PRESENT_PERM32_INV = {5'd31, 5'd27, 5'd23, 5'd19, + 5'd15, 5'd11, 5'd07, 5'd03, + 5'd30, 5'd26, 5'd22, 5'd18, + 5'd14, 5'd10, 5'd06, 5'd02, + 5'd29, 5'd25, 5'd21, 5'd17, + 5'd13, 5'd09, 5'd05, 5'd01, + 5'd28, 5'd24, 5'd20, 5'd16, + 5'd12, 5'd08, 5'd04, 5'd00}; + + // these are the permutation indices of the present cipher + parameter logic [63:0][5:0] PRESENT_PERM64 = {6'd63, 6'd47, 6'd31, 6'd15, + 6'd62, 6'd46, 6'd30, 6'd14, + 6'd61, 6'd45, 6'd29, 6'd13, + 6'd60, 6'd44, 6'd28, 6'd12, + 6'd59, 6'd43, 6'd27, 6'd11, + 6'd58, 6'd42, 6'd26, 6'd10, + 6'd57, 6'd41, 6'd25, 6'd09, + 6'd56, 6'd40, 6'd24, 6'd08, + 6'd55, 6'd39, 6'd23, 6'd07, + 6'd54, 6'd38, 6'd22, 6'd06, + 6'd53, 6'd37, 6'd21, 6'd05, + 6'd52, 6'd36, 6'd20, 6'd04, + 6'd51, 6'd35, 6'd19, 6'd03, + 6'd50, 6'd34, 6'd18, 6'd02, + 6'd49, 6'd33, 6'd17, 6'd01, + 6'd48, 6'd32, 6'd16, 6'd00}; + + parameter logic [63:0][5:0] PRESENT_PERM64_INV = {6'd63, 6'd59, 6'd55, 6'd51, + 6'd47, 6'd43, 6'd39, 6'd35, + 6'd31, 6'd27, 6'd23, 6'd19, + 6'd15, 6'd11, 6'd07, 6'd03, + 6'd62, 6'd58, 6'd54, 6'd50, + 6'd46, 6'd42, 6'd38, 6'd34, + 6'd30, 6'd26, 6'd22, 6'd18, + 6'd14, 6'd10, 6'd06, 6'd02, + 6'd61, 6'd57, 6'd53, 6'd49, + 6'd45, 6'd41, 6'd37, 6'd33, + 6'd29, 6'd25, 6'd21, 6'd17, + 6'd13, 6'd09, 6'd05, 6'd01, + 6'd60, 6'd56, 6'd52, 6'd48, + 6'd44, 6'd40, 6'd36, 6'd32, + 6'd28, 6'd24, 6'd20, 6'd16, + 6'd12, 6'd08, 6'd04, 6'd00}; + + // forward key schedule + function automatic logic [63:0] present_update_key64(logic [63:0] key_in, + logic [4:0] round_idx); + logic [63:0] key_out; + // rotate by 61 to the left + key_out = {key_in[63-61:0], key_in[63:64-61]}; + // sbox on uppermost 4 bits + key_out[63 -: 4] = PRESENT_SBOX4[key_out[63 -: 4]]; + // xor in round counter on bits 19 to 15 + key_out[19:15] ^= round_idx; + return key_out; + endfunction : present_update_key64 + + function automatic logic [79:0] present_update_key80(logic [79:0] key_in, + logic [4:0] round_idx); + logic [79:0] key_out; + // rotate by 61 to the left + key_out = {key_in[79-61:0], key_in[79:80-61]}; + // sbox on uppermost 4 bits + key_out[79 -: 4] = PRESENT_SBOX4[key_out[79 -: 4]]; + // xor in round counter on bits 19 to 15 + key_out[19:15] ^= round_idx; + return key_out; + endfunction : present_update_key80 + + function automatic logic [127:0] present_update_key128(logic [127:0] key_in, + logic [4:0] round_idx); + logic [127:0] key_out; + // rotate by 61 to the left + key_out = {key_in[127-61:0], key_in[127:128-61]}; + // sbox on uppermost 4 bits + key_out[127 -: 4] = PRESENT_SBOX4[key_out[127 -: 4]]; + // sbox on second nibble from top + key_out[123 -: 4] = PRESENT_SBOX4[key_out[123 -: 4]]; + // xor in round counter on bits 66 to 62 + key_out[66:62] ^= round_idx; + return key_out; + endfunction : present_update_key128 + + + // inverse key schedule + function automatic logic [63:0] present_inv_update_key64(logic [63:0] key_in, + logic [4:0] round_idx); + logic [63:0] key_out = key_in; + // xor in round counter on bits 19 to 15 + key_out[19:15] ^= round_idx; + // sbox on uppermost 4 bits + key_out[63 -: 4] = PRESENT_SBOX4_INV[key_out[63 -: 4]]; + // rotate by 61 to the right + key_out = {key_out[60:0], key_out[63:61]}; + return key_out; + endfunction : present_inv_update_key64 + + function automatic logic [79:0] present_inv_update_key80(logic [79:0] key_in, + logic [4:0] round_idx); + logic [79:0] key_out = key_in; + // xor in round counter on bits 19 to 15 + key_out[19:15] ^= round_idx; + // sbox on uppermost 4 bits + key_out[79 -: 4] = PRESENT_SBOX4_INV[key_out[79 -: 4]]; + // rotate by 61 to the right + key_out = {key_out[60:0], key_out[79:61]}; + return key_out; + endfunction : present_inv_update_key80 + + function automatic logic [127:0] present_inv_update_key128(logic [127:0] key_in, + logic [4:0] round_idx); + logic [127:0] key_out = key_in; + // xor in round counter on bits 66 to 62 + key_out[66:62] ^= round_idx; + // sbox on second highest nibble + key_out[123 -: 4] = PRESENT_SBOX4_INV[key_out[123 -: 4]]; + // sbox on uppermost 4 bits + key_out[127 -: 4] = PRESENT_SBOX4_INV[key_out[127 -: 4]]; + // rotate by 61 to the right + key_out = {key_out[60:0], key_out[127:61]}; + return key_out; + endfunction : present_inv_update_key128 + + + // these functions can be used to derive the DEC key from the ENC key by + // stepping the key by the correct number of rounds using the keyschedule functions above. + function automatic logic [63:0] present_get_dec_key64(logic [63:0] key_in, + // total number of rounds employed + logic [4:0] round_cnt); + logic [63:0] key_out; + key_out = key_in; + for (int unsigned k = 0; k < round_cnt; k++) begin + key_out = present_update_key64(key_out, 5'(k + 1)); + end + return key_out; + endfunction : present_get_dec_key64 + + function automatic logic [79:0] present_get_dec_key80(logic [79:0] key_in, + // total number of rounds employed + logic [4:0] round_cnt); + logic [79:0] key_out; + key_out = key_in; + for (int unsigned k = 0; k < round_cnt; k++) begin + key_out = present_update_key80(key_out, 5'(k + 1)); + end + return key_out; + endfunction : present_get_dec_key80 + + function automatic logic [127:0] present_get_dec_key128(logic [127:0] key_in, + // total number of rounds employed + logic [4:0] round_cnt); + logic [127:0] key_out; + key_out = key_in; + for (int unsigned k = 0; k < round_cnt; k++) begin + key_out = present_update_key128(key_out, 5'(k + 1)); + end + return key_out; + endfunction : present_get_dec_key128 + + ///////////////////////// + // Common Subfunctions // + ///////////////////////// + + function automatic logic [7:0] sbox4_8bit(logic [7:0] state_in, logic [15:0][3:0] sbox4); + logic [7:0] state_out; + // note that if simulation performance becomes an issue, this loop can be unrolled + for (int k = 0; k < 8/4; k++) begin + state_out[k*4 +: 4] = sbox4[state_in[k*4 +: 4]]; + end + return state_out; + endfunction : sbox4_8bit + + function automatic logic [15:0] sbox4_16bit(logic [15:0] state_in, logic [15:0][3:0] sbox4); + logic [15:0] state_out; + // note that if simulation performance becomes an issue, this loop can be unrolled + for (int k = 0; k < 2; k++) begin + state_out[k*8 +: 8] = sbox4_8bit(state_in[k*8 +: 8], sbox4); + end + return state_out; + endfunction : sbox4_16bit + + function automatic logic [31:0] sbox4_32bit(logic [31:0] state_in, logic [15:0][3:0] sbox4); + logic [31:0] state_out; + // note that if simulation performance becomes an issue, this loop can be unrolled + for (int k = 0; k < 4; k++) begin + state_out[k*8 +: 8] = sbox4_8bit(state_in[k*8 +: 8], sbox4); + end + return state_out; + endfunction : sbox4_32bit + + function automatic logic [63:0] sbox4_64bit(logic [63:0] state_in, logic [15:0][3:0] sbox4); + logic [63:0] state_out; + // note that if simulation performance becomes an issue, this loop can be unrolled + for (int k = 0; k < 8; k++) begin + state_out[k*8 +: 8] = sbox4_8bit(state_in[k*8 +: 8], sbox4); + end + return state_out; + endfunction : sbox4_64bit + + function automatic logic [7:0] perm_8bit(logic [7:0] state_in, logic [7:0][2:0] perm); + logic [7:0] state_out; + // note that if simulation performance becomes an issue, this loop can be unrolled + for (int k = 0; k < 8; k++) begin + state_out[perm[k]] = state_in[k]; + end + return state_out; + endfunction : perm_8bit + + function automatic logic [15:0] perm_16bit(logic [15:0] state_in, logic [15:0][3:0] perm); + logic [15:0] state_out; + // note that if simulation performance becomes an issue, this loop can be unrolled + for (int k = 0; k < 16; k++) begin + state_out[perm[k]] = state_in[k]; + end + return state_out; + endfunction : perm_16bit + + function automatic logic [31:0] perm_32bit(logic [31:0] state_in, logic [31:0][4:0] perm); + logic [31:0] state_out; + // note that if simulation performance becomes an issue, this loop can be unrolled + for (int k = 0; k < 32; k++) begin + state_out[perm[k]] = state_in[k]; + end + return state_out; + endfunction : perm_32bit + + function automatic logic [63:0] perm_64bit(logic [63:0] state_in, logic [63:0][5:0] perm); + logic [63:0] state_out; + // note that if simulation performance becomes an issue, this loop can be unrolled + for (int k = 0; k < 64; k++) begin + state_out[perm[k]] = state_in[k]; + end + return state_out; + endfunction : perm_64bit + +endpackage : caliptra_prim_cipher_pkg diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_clock_mux2.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_clock_mux2.sv new file mode 100644 index 0000000..e129ad0 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_clock_mux2.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 + +// Abstract primitives wrapper. +// +// This file is a stop-gap until the DV file list is generated by FuseSoC. +// Its contents are taken from the file which would be generated by FuseSoC. +// https://github.com/lowRISC/ibex/issues/893 + +`include "caliptra_prim_module_name_macros.svh" + +module caliptra_prim_clock_mux2 #( + parameter bit NoFpgaBufG = 1'b0 +) ( + input clk0_i, + input clk1_i, + input sel_i, + output logic clk_o +); + +if (1) begin : gen_generic + `CALIPTRA_PRIM_MODULE_NAME(clock_mux2) #( + .NoFpgaBufG(NoFpgaBufG) + ) u_impl_generic ( + .* + ); +end + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_count.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_count.sv new file mode 100644 index 0000000..5a5baa3 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_count.sv @@ -0,0 +1,309 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Hardened counter primitive: +// +// This internally uses a cross counter scheme with primary and a secondary counter, where the +// secondary counter counts in reverse direction. The sum of both counters must remain constant and +// equal to 2**Width-1 or otherwise an err_o will be asserted. +// +// This counter supports a generic clear / set / increment / decrement interface: +// +// clr_i: This clears the primary counter to ResetValue and adjusts the secondary counter to match +// (i.e. 2**Width-1-ResetValue). Clear has priority over set, increment and decrement. +// set_i: This sets the primary counter to set_cnt_i and adjusts the secondary counter to match +// (i.e. 2**Width-1-set_cnt_i). Set has priority over increment and decrement. +// incr_en_i: Increments the primary counter by step_i, and decrements the secondary by step_i. +// decr_en_i: Decrements the primary counter by step_i, and increments the secondary by step_i. +// commit_i: Counter changes only take effect when `commit_i` is set. This does not effect the +// `cnt_after_commit_o` output which gives the next counter state if the change is +// committed. +// +// Note that if both incr_en_i and decr_en_i are asserted at the same time, the counter remains +// unchanged. The counter is also protected against under- and overflows. + +`include "caliptra_prim_assert.sv" + +module caliptra_prim_count + import caliptra_prim_count_pkg::*; +#( + parameter int Width = 2, + // Can be used to reset the counter to a different value than 0, for example when + // the counter is used as a down-counter. + parameter logic [Width-1:0] ResetValue = '0, + // This should only be disabled in special circumstances, for example + // in non-comportable IPs where an error does not trigger an alert. + parameter bit EnableAlertTriggerSVA = 1, + + // We have some assertions below with preconditions that depend on particular input actions + // (clear, set, incr, decr). If the design has instantiated prim_count with one of these actions + // tied to zero, the preconditions for the associated assertions will not be satisfiable. The + // result is an unreachable item, which we treat as a failed assertion in the report. + // + // To avoid this, we the instantiation to specify the actions which might happen. If this is not + // '1, we will have an assertion which assert the corresponding action is never triggered. We can + // then use this to avoid the unreachable assertions. + parameter action_mask_t PossibleActions = {$bits(action_mask_t){1'b1}} +) ( + input clk_i, + input rst_ni, + input clr_i, + input set_i, + input [Width-1:0] set_cnt_i, // Set value for the counter. + input incr_en_i, + input decr_en_i, + input [Width-1:0] step_i, // Increment/decrement step when enabled. + input commit_i, + output logic [Width-1:0] cnt_o, // Current counter state + output logic [Width-1:0] cnt_after_commit_o, // Next counter state if committed + output logic err_o +); + + /////////////////// + // Counter logic // + /////////////////// + + // Reset Values for primary and secondary counters. + localparam int NumCnt = 2; + localparam logic [NumCnt-1:0][Width-1:0] ResetValues = {{Width{1'b1}} - ResetValue, // secondary + ResetValue}; // primary + + logic [NumCnt-1:0][Width-1:0] cnt_d, cnt_d_committed, cnt_q; + + // The fpv_force signal can be used in FPV runs to make the internal counters (cnt_q) jump + // unexpectedly. We only want to use this mechanism when we're doing FPV on prim_count itself. In + // that situation, we will have the PrimCountFpv define and wish to leave fpv_force undriven so + // that it becomes a free variable in FPV. In any other situation, we drive the signal with zero. + logic [NumCnt-1:0][Width-1:0] fpv_force; +`ifndef PrimCountFpv + assign fpv_force = '0; +`endif + + for (genvar k = 0; k < NumCnt; k++) begin : gen_cnts + // Note that increments / decrements are reversed for the secondary counter. + logic incr_en, decr_en; + logic [Width-1:0] set_val; + if (k == 0) begin : gen_up_cnt + assign incr_en = incr_en_i; + assign decr_en = decr_en_i; + assign set_val = set_cnt_i; + end else begin : gen_dn_cnt + assign incr_en = decr_en_i; + assign decr_en = incr_en_i; + // The secondary value needs to be adjusted accordingly. + assign set_val = {Width{1'b1}} - set_cnt_i; + end + + // Main counter logic + logic [Width:0] ext_cnt; + assign ext_cnt = (decr_en) ? {1'b0, cnt_q[k]} - {1'b0, step_i} : + (incr_en) ? {1'b0, cnt_q[k]} + {1'b0, step_i} : {1'b0, cnt_q[k]}; + + // Saturation logic + logic uflow, oflow; + assign oflow = incr_en && ext_cnt[Width]; + assign uflow = decr_en && ext_cnt[Width]; + logic [Width-1:0] cnt_sat; + assign cnt_sat = (uflow) ? '0 : + (oflow) ? {Width{1'b1}} : ext_cnt[Width-1:0]; + + // Clock gate flops when in saturation, and do not + // count if both incr_en and decr_en are asserted. + logic cnt_en; + assign cnt_en = (incr_en ^ decr_en) && + ((incr_en && !(&cnt_q[k])) || + (decr_en && !(cnt_q[k] == '0))); + + // Counter muxes + assign cnt_d[k] = (clr_i) ? ResetValues[k] : + (set_i) ? set_val : + (cnt_en) ? cnt_sat : cnt_q[k]; + + assign cnt_d_committed[k] = commit_i ? cnt_d[k] : cnt_q[k]; + + logic [Width-1:0] cnt_unforced_q; + caliptra_prim_flop #( + .Width(Width), + .ResetValue(ResetValues[k]) + ) u_cnt_flop ( + .clk_i, + .rst_ni, + .d_i(cnt_d_committed[k]), + .q_o(cnt_unforced_q) + ); + + // fpv_force is only used during FPV. + assign cnt_q[k] = fpv_force[k] + cnt_unforced_q; + end + + // The sum of both counters must always equal the counter maximum. + logic [Width:0] sum; + assign sum = (cnt_q[0] + cnt_q[1]); + + // Register the error signal to avoid potential CDC issues downstream. + logic err_d, err_q; + assign err_d = (sum != {1'b0, {Width{1'b1}}}); + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + err_q <= 1'b0; + end else begin + err_q <= err_d; + end + end + assign err_o = err_q; + + // Output count values + assign cnt_o = cnt_q[0]; + assign cnt_after_commit_o = cnt_d[0]; + + //////////////// + // Assertions // + //////////////// +`ifdef CALIPTRA_INC_ASSERT + //VCS coverage off + // pragma coverage off + + // We need to disable most assertions in that case using a helper signal. + // We can't rely on err_o since some error patterns cannot be detected (e.g. all error + // patterns that still fullfill the sum constraint). + logic fpv_err_present; + assign fpv_err_present = |fpv_force; + + // Helper functions for assertions. + function automatic logic signed [Width+1:0] max(logic signed [Width+1:0] a, + logic signed [Width+1:0] b); + return (a > b) ? a : b; + endfunction + function automatic logic signed [Width+1:0] min(logic signed [Width+1:0] a, + logic signed [Width+1:0] b); + return (a < b) ? a : b; + endfunction + + //VCS coverage on + // pragma coverage on + + if (!(PossibleActions & Clr)) begin : g_check_no_clr + `CALIPTRA_ASSERT(ClrNeverTrue_A, clr_i !== 1'b1) + end + if (!(PossibleActions & Set)) begin : g_check_no_set + `CALIPTRA_ASSERT(SetNeverTrue_A, set_i !== 1'b1) + end + if (!(PossibleActions & Incr)) begin : g_check_no_incr + `CALIPTRA_ASSERT(IncrNeverTrue_A, incr_en_i !== 1'b1) + end + if (!(PossibleActions & Decr)) begin : g_check_no_decr + `CALIPTRA_ASSERT(DecrNeverTrue_A, decr_en_i !== 1'b1) + end + + // Cnt next + `CALIPTRA_ASSERT(CntNext_A, + rst_ni + |=> + $past(!commit_i) || (cnt_o == $past(cnt_after_commit_o)), + clk_i, err_d || fpv_err_present || !rst_ni) + + // Clear + if (PossibleActions & Clr) begin : g_check_clr_fwd_a + `CALIPTRA_ASSERT(ClrFwd_A, + rst_ni && commit_i && clr_i + |=> + (cnt_o == ResetValue) && + (cnt_q[1] == ({Width{1'b1}} - ResetValue)), + clk_i, err_d || fpv_err_present || !rst_ni) + end + + // Set + if (PossibleActions & Set) begin : g_check_set_fwd_a + `CALIPTRA_ASSERT(SetFwd_A, + rst_ni && commit_i && set_i && !clr_i + |=> + (cnt_o == $past(set_cnt_i)) && + (cnt_q[1] == ({Width{1'b1}} - $past(set_cnt_i))), + clk_i, err_d || fpv_err_present || !rst_ni) + end + + // Do not count if both increment and decrement are asserted. + if ((PossibleActions & Incr) && (PossibleActions & Decr)) begin : g_check_inc_and_dec + `CALIPTRA_ASSERT(IncrDecrUpDnCnt_A, + rst_ni && incr_en_i && decr_en_i && !(clr_i || set_i) + |=> + $stable(cnt_o) && $stable(cnt_q[1]), + clk_i, err_d || fpv_err_present || !rst_ni) + end + + // Increment + if ((PossibleActions & Incr)) begin : g_check_incr + `CALIPTRA_ASSERT(IncrUpCnt_A, + rst_ni && incr_en_i && !(clr_i || set_i || decr_en_i) && commit_i + |=> + cnt_o == min($past(cnt_o) + $past({2'b0, step_i}), {2'b0, {Width{1'b1}}}), + clk_i, err_d || fpv_err_present || !rst_ni) + `CALIPTRA_ASSERT(IncrDnCnt_A, + rst_ni && incr_en_i && !(clr_i || set_i || decr_en_i) && commit_i + |=> + cnt_q[1] == max($past(signed'({2'b0, cnt_q[1]})) - $past({2'b0, step_i}), '0), + clk_i, err_d || fpv_err_present || !rst_ni) + `CALIPTRA_ASSERT(UpCntIncrStable_A, + incr_en_i && !(clr_i || set_i || decr_en_i) && + cnt_o == {Width{1'b1}} + |=> + $stable(cnt_o), + clk_i, err_d || fpv_err_present || !rst_ni) + `CALIPTRA_ASSERT(DnCntIncrStable_A, + rst_ni && incr_en_i && !(clr_i || set_i || decr_en_i) && + cnt_q[1] == '0 + |=> + $stable(cnt_q[1]), + clk_i, err_d || fpv_err_present || !rst_ni) + end + + // Decrement + if ((PossibleActions & Decr)) begin : g_check_decr + `CALIPTRA_ASSERT(DecrUpCnt_A, + rst_ni && decr_en_i && !(clr_i || set_i || incr_en_i) && commit_i + |=> + cnt_o == max($past(signed'({2'b0, cnt_o})) - $past({2'b0, step_i}), '0), + clk_i, err_d || fpv_err_present || !rst_ni) + `CALIPTRA_ASSERT(DecrDnCnt_A, + rst_ni && decr_en_i && !(clr_i || set_i || incr_en_i) && commit_i + |=> + cnt_q[1] == min($past(cnt_q[1]) + $past({2'b0, step_i}), {2'b0, {Width{1'b1}}}), + clk_i, err_d || fpv_err_present || !rst_ni) + `CALIPTRA_ASSERT(UpCntDecrStable_A, + decr_en_i && !(clr_i || set_i || incr_en_i) && + cnt_o == '0 + |=> + $stable(cnt_o), + clk_i, err_d || fpv_err_present || !rst_ni) + `CALIPTRA_ASSERT(DnCntDecrStable_A, + rst_ni && decr_en_i && !(clr_i || set_i || incr_en_i) && + cnt_q[1] == {Width{1'b1}} + |=> + $stable(cnt_q[1]), + clk_i, err_d || fpv_err_present || !rst_ni) + end + + // A backwards check for count changes. This asserts that the count only changes if one of the + // inputs that should tell it to change (clear, set, increment, decrement) does so. + `CALIPTRA_ASSERT(ChangeBackward_A, + rst_ni ##1 $changed(cnt_o) && $changed(cnt_q[1]) + |-> + $past(clr_i || set_i || (commit_i && (incr_en_i || decr_en_i))), + clk_i, err_d || fpv_err_present || !rst_ni) + + // Check that count errors are reported properly in err_d + `CALIPTRA_ASSERT(CntErrReported_A, ((cnt_q[1] + cnt_q[0]) != {Width{1'b1}}) == err_d) + `ifdef PrimCountFpv + `CALIPTRA_COVER(CntErr_C, err_d) + `endif + + // This logic that will be assign to one, when user adds macro + // CALIPTRA_ASSERT_PRIM_COUNT_ERROR_TRIGGER_ALERT to check the error with alert, in case that prim_count + // is used in design without adding this assertion check. + logic unused_assert_connected; + + `CALIPTRA_ASSERT_INIT_NET(AssertConnected_A, unused_assert_connected === 1'b1 || !EnableAlertTriggerSVA) +`endif + +endmodule // caliptra_prim_count diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_count_pkg.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_count_pkg.sv new file mode 100644 index 0000000..bcc9931 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_count_pkg.sv @@ -0,0 +1,15 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +package caliptra_prim_count_pkg; + + // An enum that names the possible actions that the inputs might ask for. See the PossibleActions + // parameter in prim_count for how this is used. + typedef logic [3:0] action_mask_t; + typedef enum action_mask_t {Clr = 4'h1, + Set = 4'h2, + Incr = 4'h4, + Decr = 4'h8} action_e; + +endpackage : caliptra_prim_count_pkg diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_diff_decode.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_diff_decode.sv new file mode 100644 index 0000000..d8ca140 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_diff_decode.sv @@ -0,0 +1,294 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// This module decodes a differentially encoded signal and detects +// incorrectly encoded differential states. +// +// In case the differential pair crosses an asynchronous boundary, it has +// to be re-synchronized to the local clock. This can be achieved by +// setting the AsyncOn parameter to 1'b1. In that case, two additional +// input registers are added (to counteract metastability), and +// a pattern detector is instantiated that detects skewed level changes on +// the differential pair (i.e., when level changes on the diff pair are +// sampled one cycle apart due to a timing skew between the two wires). +// +// See also: caliptra_prim_alert_sender, caliptra_prim_alert_receiver, alert_handler + +`include "caliptra_prim_assert.sv" +`include "caliptra_prim_module_name_macros.svh" + +module caliptra_prim_diff_decode #( + // enables additional synchronization logic + parameter bit AsyncOn = 1'b0 +) ( + input clk_i, + input rst_ni, + // input diff pair + input diff_pi, + input diff_ni, + // logical level and + // detected edges + output logic level_o, + output logic rise_o, + output logic fall_o, + // either rise or fall + output logic event_o, + //signal integrity issue detected + output logic sigint_o +); + + logic level_d, level_q; + + /////////////////////////////////////////////////////////////// + // synchronization regs for incoming diff pair (if required) // + /////////////////////////////////////////////////////////////// + if (AsyncOn) begin : gen_async + + typedef enum logic [1:0] {IsStd, IsSkewed, SigInt} state_e; + state_e state_d, state_q; + logic diff_p_edge, diff_n_edge, diff_check_ok, level; + + // 2 sync regs, one reg for edge detection + logic diff_pq, diff_nq, diff_pd, diff_nd; + + caliptra_prim_flop_2sync #( + .Width(1), + .ResetValue('0) + ) i_sync_p ( + .clk_i, + .rst_ni, + .d_i(diff_pi), + .q_o(diff_pd) + ); + + caliptra_prim_flop_2sync #( + .Width(1), + .ResetValue(1'b1) + ) i_sync_n ( + .clk_i, + .rst_ni, + .d_i(diff_ni), + .q_o(diff_nd) + ); + + // detect level transitions + assign diff_p_edge = diff_pq ^ diff_pd; + assign diff_n_edge = diff_nq ^ diff_nd; + + // detect sigint issue + assign diff_check_ok = diff_pd ^ diff_nd; + + // this is the current logical level + assign level = diff_pd; + + // outputs + assign level_o = level_d; + assign event_o = rise_o | fall_o; + + // sigint detection is a bit more involved in async case since + // we might have skew on the diff pair, which can result in a + // one cycle sampling delay between the two wires + // so we need a simple pattern matcher + // the following waves are legal + // clk | | | | | | | | + // _______ _______ + // p _______/ ... \________ + // _______ ________ + // n \_______ ... _______/ + // ____ ___ + // p __________/ ... \________ + // _______ ________ + // n \_______ ... _______/ + // + // i.e., level changes may be off by one cycle - which is permissible + // as long as this condition is only one cycle long. + + + always_comb begin : p_diff_fsm + // default + state_d = state_q; + level_d = level_q; + rise_o = 1'b0; + fall_o = 1'b0; + sigint_o = 1'b0; + + unique case (state_q) + // we remain here as long as + // the diff pair is correctly encoded + IsStd: begin + if (diff_check_ok) begin + level_d = level; + if (diff_p_edge && diff_n_edge) begin + if (level) begin + rise_o = 1'b1; + end else begin + fall_o = 1'b1; + end + end + end else begin + if (diff_p_edge || diff_n_edge) begin + state_d = IsSkewed; + end else begin + state_d = SigInt; + sigint_o = 1'b1; + end + end + end + // diff pair must be correctly encoded, otherwise we got a sigint + IsSkewed: begin + if (diff_check_ok) begin + state_d = IsStd; + level_d = level; + if (level) rise_o = 1'b1; + else fall_o = 1'b1; + end else begin + state_d = SigInt; + sigint_o = 1'b1; + end + end + // Signal integrity issue detected, remain here + // until resolved + SigInt: begin + sigint_o = 1'b1; + if (diff_check_ok) begin + state_d = IsStd; + sigint_o = 1'b0; + end + end + default : ; + endcase + end + + always_ff @(posedge clk_i or negedge rst_ni) begin : p_sync_reg + if (!rst_ni) begin + state_q <= IsStd; + diff_pq <= 1'b0; + diff_nq <= 1'b1; + level_q <= 1'b0; + end else begin + state_q <= state_d; + diff_pq <= diff_pd; + diff_nq <= diff_nd; + level_q <= level_d; + end + end + + ////////////////////////////////////////////////////////// + // fully synchronous case, no skew present in this case // + ////////////////////////////////////////////////////////// + end else begin : gen_no_async + logic diff_pq, diff_pd; + + // one reg for edge detection + assign diff_pd = diff_pi; + + // Raise a signal integrity error when the differential signals have equal values. This is + // implemented with a `prim_xnor2` instead of behavioral code to prevent the synthesis tool from + // optimizing away combinational logic on the complementary differential signals. + `CALIPTRA_PRIM_MODULE_NAME(xnor2) #( + .Width (1) + ) u_xnor2_sigint ( + .in0_i (diff_pi), + .in1_i (diff_ni), + .out_o (sigint_o) + ); + + assign level_o = (sigint_o) ? level_q : diff_pi; + assign level_d = level_o; + + // detect level transitions + assign rise_o = (~diff_pq & diff_pi) & ~sigint_o; + assign fall_o = ( diff_pq & ~diff_pi) & ~sigint_o; + assign event_o = rise_o | fall_o; + + always_ff @(posedge clk_i or negedge rst_ni) begin : p_edge_reg + if (!rst_ni) begin + diff_pq <= 1'b0; + level_q <= 1'b0; + end else begin + diff_pq <= diff_pd; + level_q <= level_d; + end + end + end + + //////////////// + // assertions // + //////////////// + + // shared assertions + // sigint -> level stays the same during sigint + // $isunknown is needed to avoid false assertion in first clock cycle + `CALIPTRA_ASSERT(SigintLevelCheck_A, ##1 sigint_o |-> $stable(level_o)) + // sigint -> no additional events asserted at output + `CALIPTRA_ASSERT(SigintEventCheck_A, sigint_o |-> !event_o) + `CALIPTRA_ASSERT(SigintRiseCheck_A, sigint_o |-> !rise_o) + `CALIPTRA_ASSERT(SigintFallCheck_A, sigint_o |-> !fall_o) + + if (AsyncOn) begin : gen_async_assert + // assertions for asynchronous case +`ifdef CALIPTRA_INC_ASSERT + `ifndef FPV_ALERT_NO_SIGINT_ERR + // correctly detect sigint issue (only one transition cycle of permissible due to skew) + `CALIPTRA_ASSERT(SigintCheck0_A, gen_async.diff_pd == gen_async.diff_nd [*2] |-> sigint_o) + // the synchronizer adds 2 cycles of latency with respect to input signals. + `CALIPTRA_ASSERT(SigintCheck1_A, + ##1 (gen_async.diff_pd ^ gen_async.diff_nd) && + $stable(gen_async.diff_pd) && $stable(gen_async.diff_nd) ##1 + $rose(gen_async.diff_pd) && $stable(gen_async.diff_nd) ##1 + $stable(gen_async.diff_pd) && $fell(gen_async.diff_nd) + |-> rise_o) + `CALIPTRA_ASSERT(SigintCheck2_A, + ##1 (gen_async.diff_pd ^ gen_async.diff_nd) && + $stable(gen_async.diff_pd) && $stable(gen_async.diff_nd) ##1 + $fell(gen_async.diff_pd) && $stable(gen_async.diff_nd) ##1 + $stable(gen_async.diff_pd) && $rose(gen_async.diff_nd) + |-> fall_o) + `CALIPTRA_ASSERT(SigintCheck3_A, + ##1 (gen_async.diff_pd ^ gen_async.diff_nd) && + $stable(gen_async.diff_pd) && $stable(gen_async.diff_nd) ##1 + $rose(gen_async.diff_nd) && $stable(gen_async.diff_pd) ##1 + $stable(gen_async.diff_nd) && $fell(gen_async.diff_pd) + |-> fall_o) + `CALIPTRA_ASSERT(SigintCheck4_A, + ##1 (gen_async.diff_pd ^ gen_async.diff_nd) && + $stable(gen_async.diff_pd) && $stable(gen_async.diff_nd) ##1 + $fell(gen_async.diff_nd) && $stable(gen_async.diff_pd) ##1 + $stable(gen_async.diff_nd) && $rose(gen_async.diff_pd) + |-> rise_o) + `endif + + // correctly detect edges + `CALIPTRA_ASSERT(RiseCheck_A, + !sigint_o ##1 $rose(gen_async.diff_pd) && (gen_async.diff_pd ^ gen_async.diff_nd) |-> + ##[0:1] rise_o, clk_i, !rst_ni || sigint_o) + `CALIPTRA_ASSERT(FallCheck_A, + !sigint_o ##1 $fell(gen_async.diff_pd) && (gen_async.diff_pd ^ gen_async.diff_nd) |-> + ##[0:1] fall_o, clk_i, !rst_ni || sigint_o) + `CALIPTRA_ASSERT(EventCheck_A, + !sigint_o ##1 $changed(gen_async.diff_pd) && (gen_async.diff_pd ^ gen_async.diff_nd) |-> + ##[0:1] event_o, clk_i, !rst_ni || sigint_o) + // correctly detect level + `CALIPTRA_ASSERT(LevelCheck0_A, + !sigint_o && (gen_async.diff_pd ^ gen_async.diff_nd) [*2] |-> + gen_async.diff_pd == level_o, + clk_i, !rst_ni || sigint_o) +`endif + end else begin : gen_sync_assert + // assertions for synchronous case + + `ifndef FPV_ALERT_NO_SIGINT_ERR + // correctly detect sigint issue + `CALIPTRA_ASSERT(SigintCheck_A, diff_pi == diff_ni |-> sigint_o) + `endif + + // correctly detect edges + `CALIPTRA_ASSERT(RiseCheck_A, ##1 $rose(diff_pi) && (diff_pi ^ diff_ni) |-> rise_o) + `CALIPTRA_ASSERT(FallCheck_A, ##1 $fell(diff_pi) && (diff_pi ^ diff_ni) |-> fall_o) + `CALIPTRA_ASSERT(EventCheck_A, ##1 $changed(diff_pi) && (diff_pi ^ diff_ni) |-> event_o) + // correctly detect level + `CALIPTRA_ASSERT(LevelCheck_A, (diff_pi ^ diff_ni) |-> diff_pi == level_o) + end + +endmodule : caliptra_prim_diff_decode diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_dom_and_2share.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_dom_and_2share.sv new file mode 100644 index 0000000..6e6ae35 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_dom_and_2share.sv @@ -0,0 +1,174 @@ +// Copyright lowRISC contributors. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Domain-Oriented Masking GF(2) Multiplier with 2-shares +// ref: Higher-Order Side-Channel Protected Implementations of Keccak +// https://eprint.iacr.org/2017/395.pdf +// +// q0 = a0 & b0 + (a0 & b1 + z) +// q1 = a1 & b1 + (a1 & b0 + z) +// () ==> registered +// +// all input should be stable for two clocks +// as the output is valid after a clock +// For z, it can use other slice from the state +// as it is fairly random w.r.t the current inputs. + +// General formula of Q in the paper +// Qi = t{i,i} + Sig(j>i,d)(t{i,j}+Z{i+j*(j-1)/2}) + Sig(j0,1)(t{0,j}+Z{j(j-1)/2}) + Sig(j<0,d)(..) +// = a0&b0 + (a0&b1 + z0 + 0) +// Q1 = t{1,1} + sig(j>1,1)(...) + sig(j<1,1)(t{1,j} + Z{j}) +// = a1&b1 + (0 + a1&b0 + z0) + +`include "caliptra_prim_assert.sv" +`include "caliptra_prim_module_name_macros.svh" + +module caliptra_prim_dom_and_2share #( + parameter int DW = 64, // Input width + parameter bit Pipeline = 1'b0 // Enable full pipelining +) ( + input clk_i, + input rst_ni, + + input [DW-1:0] a0_i, // share0 of a + input [DW-1:0] a1_i, // share1 of a + input [DW-1:0] b0_i, // share0 of b + input [DW-1:0] b1_i, // share1 of b + input z_valid_i, // random number input validity + input [DW-1:0] z_i, // random number + + output logic [DW-1:0] q0_o, // share0 of q + output logic [DW-1:0] q1_o, // share1 of q + output logic [DW-1:0] prd_o // pseudo-random data for other instances +); + + logic [DW-1:0] t0_d, t0_q, t1_d, t1_q; + logic [DW-1:0] t_a0b0, t_a1b1; + logic [DW-1:0] t_a0b0_d, t_a1b1_d; + logic [DW-1:0] t_a0b1, t_a1b0; + + ///////////////// + // Calculation // + ///////////////// + // Inner-domain terms + assign t_a0b0_d = a0_i & b0_i; + assign t_a1b1_d = a1_i & b1_i; + + // Cross-domain terms + assign t_a0b1 = a0_i & b1_i; + assign t_a1b0 = a1_i & b0_i; + + /////////////// + // Resharing // + /////////////// + // Resharing of cross-domain terms + + // Preserve the logic sequence for XOR not to proceed cross-domain AND. + `CALIPTRA_PRIM_MODULE_NAME(xor2) #( + .Width ( DW*2 ) + ) u_caliptra_prim_xor_t01 ( + .in0_i ( {t_a0b1, t_a1b0} ), + .in1_i ( {z_i, z_i} ), + .out_o ( {t0_d, t1_d} ) + ); + + // Register stage + caliptra_prim_flop_en #( + .Width ( DW*2 ), + .ResetValue ( '0 ) + ) u_caliptra_prim_flop_t01 ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .en_i ( z_valid_i ), + .d_i ( {t0_d, t1_d} ), + .q_o ( {t0_q, t1_q} ) + ); + + ///////////////////////// + // Optional Pipelining // + ///////////////////////// + + if (Pipeline == 1'b1) begin : gen_inner_domain_regs + // Add pipeline registers on inner-domain terms prior to integration. This allows accepting new + // input data every clock cycle and prevents SCA leakage occurring due to the integration of + // reshared cross-domain terms with inner-domain terms derived from different input data. + + logic [DW-1:0] t_a0b0_q, t_a1b1_q; + caliptra_prim_flop_en #( + .Width ( DW*2 ), + .ResetValue ( '0 ) + ) u_caliptra_prim_flop_tab01 ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .en_i ( z_valid_i ), + .d_i ( {t_a0b0_d, t_a1b1_d} ), + .q_o ( {t_a0b0_q, t_a1b1_q} ) + ); + + assign t_a0b0 = t_a0b0_q; + assign t_a1b1 = t_a1b1_q; + + end else begin : gen_no_inner_domain_regs + // Do not add the optional pipeline registers on the inner-domain terms. This allows to save + // some area in case the multiplier does not need to accept new data in every cycle. However, + // this can cause SCA leakage as during the clock cycle in which new data arrives, the new + // inner-domain terms are integrated with the previous, reshared cross-domain terms. + + assign t_a0b0 = t_a0b0_d; + assign t_a1b1 = t_a1b1_d; + end + + ///////////////// + // Integration // + ///////////////// + + // Preserve the logic sequence for XOR not to proceed the inner-domain AND. + `CALIPTRA_PRIM_MODULE_NAME(xor2) #( + .Width ( DW*2 ) + ) u_caliptra_prim_xor_q01 ( + .in0_i ( {t_a0b0, t_a1b1} ), + .in1_i ( {t0_q, t1_q} ), + .out_o ( {q0_o, q1_o} ) + ); + + // Use intermediate results for remasking computations in another instance in the following + // clock cycle. Use one share only. Directly use output of flops updating with z_valid_i. + // t1_q is obtained by remasking t_a1b0 with z_i. Since z_i is uniformly distributed and + // independent of a1/b0_i, t1_q is also uniformly distributed and independent of a1/b0_i. + // For details, see Lemma 1 in Canright, "A very compact 'perfectly masked' S-box for AES + // (corrected)" available at https://eprint.iacr.org/2009/011.pdf + assign prd_o = t1_q; + + // DOM AND should be same as unmasked computation + // The correct test sequence will be: + // 1. inputs are changed + // 2. check if z_valid_i, + // 3. at the next cycle, inputs are still stable (assumption) - only in case Pipeline = 0 + // 4. and results Q == A & B (assertion) + + // To speed up the FPV process, random value is ready in less than or + // equal to two cycles. + `CALIPTRA_ASSUME_FPV(RandomReadyInShortTime_A, + $changed(a0_i) || $changed(a1_i) || $changed(b0_i) || $changed(b1_i) + |-> ##[0:2] z_valid_i, + clk_i, !rst_ni) + + if (Pipeline == 0) begin: g_assert_stable + // If Pipeline is not set, the computation takes two cycles without flop + // crossing the domain. In this case, the signal should be stable for at + // least two cycles. + `CALIPTRA_ASSUME(StableTwoCycles_M, + ($changed(a0_i) || $changed(a1_i) || $changed(b0_i) || $changed(b1_i)) + ##[0:$] z_valid_i |=> + $stable(a0_i) && $stable(a1_i) && $stable(b0_i) && $stable(b1_i)) + end + + `CALIPTRA_ASSERT(UnmaskedAndMatched_A, + z_valid_i |=> (q0_o ^ q1_o) == + (($past(a0_i) ^ $past(a1_i)) & ($past(b0_i) ^ $past(b1_i))), + clk_i, !rst_ni) + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_double_lfsr.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_double_lfsr.sv new file mode 100644 index 0000000..6b4339c --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_double_lfsr.sv @@ -0,0 +1,113 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Hardened LFSR module that instantiates two LFSRs of the same type. +// The state vector of both LFSRs is constantly checked and an error is asserted if the +// two states are inconsistent. + +module caliptra_prim_double_lfsr #( + // prim_lfsr parameters - refer to prim_lfsr for their meaning/ + parameter LfsrType = "GAL_XOR", + parameter int unsigned LfsrDw = 32, + localparam int unsigned LfsrIdxDw = $clog2(LfsrDw), + parameter int unsigned EntropyDw = 8, + parameter int unsigned StateOutDw = 8, + parameter logic [LfsrDw-1:0] DefaultSeed = LfsrDw'(1), + parameter logic [LfsrDw-1:0] CustomCoeffs = '0, + parameter bit StatePermEn = 1'b0, + parameter logic [LfsrDw-1:0][LfsrIdxDw-1:0] StatePerm = '0, + parameter bit MaxLenSVA = 1'b1, + parameter bit LockupSVA = 1'b1, + parameter bit ExtSeedSVA = 1'b1, + parameter bit NonLinearOut = 1'b0, + // This should only be disabled in special circumstances, for example + // in non-comportable IPs where an error does not trigger an alert. + parameter bit EnableAlertTriggerSVA = 1 +) ( + input clk_i, + input rst_ni, + input seed_en_i, + input [LfsrDw-1:0] seed_i, + input lfsr_en_i, + input [EntropyDw-1:0] entropy_i, + output logic [StateOutDw-1:0] state_o, + // Asserted if the parallel LFSR states are inconsistent. + output logic err_o +); + + + logic [1:0][LfsrDw-1:0] lfsr_state; + // We employ redundant LFSRs to guard against FI attacks. + for (genvar k = 0; k < 2; k++) begin : gen_double_lfsr + // Instantiate size_only buffers to prevent + // optimization / merging of redundant logic. + logic lfsr_en_buf, seed_en_buf; + logic [EntropyDw-1:0] entropy_buf; + logic [LfsrDw-1:0] seed_buf, lfsr_state_unbuf; + caliptra_prim_buf #( + .Width(EntropyDw + LfsrDw + 2) + ) u_prim_buf_input ( + .in_i({seed_en_i, seed_i, lfsr_en_i, entropy_i}), + .out_o({seed_en_buf, seed_buf, lfsr_en_buf, entropy_buf}) + ); + + caliptra_prim_lfsr #( + .LfsrType(LfsrType), + .LfsrDw(LfsrDw), + .EntropyDw(EntropyDw), + // output the full width so that the states can be cross checked. + .StateOutDw(LfsrDw), + .DefaultSeed(DefaultSeed), + .CustomCoeffs(CustomCoeffs), + .StatePermEn(StatePermEn), + .StatePerm(StatePerm), + .MaxLenSVA(MaxLenSVA), + .LockupSVA(LockupSVA), + .ExtSeedSVA(ExtSeedSVA), + .NonLinearOut(NonLinearOut) + ) u_prim_lfsr ( + .clk_i, + .rst_ni, + .seed_en_i ( seed_en_buf ), + .seed_i ( seed_buf ), + .lfsr_en_i ( lfsr_en_buf ), + .entropy_i ( entropy_buf ), + .state_o ( lfsr_state_unbuf ) + ); + + caliptra_prim_buf #( + .Width(LfsrDw) + ) u_prim_buf_output ( + .in_i(lfsr_state_unbuf), + .out_o(lfsr_state[k]) + ); + end + +`ifdef SIMULATION +`ifndef VERILATOR + // Ensure both LFSRs start off with the same default seed. if randomized in simulations. + initial begin : p_sync_lfsr_default_seed + wait (!$isunknown(gen_double_lfsr[0].u_prim_lfsr.DefaultSeedLocal)); + wait (!$isunknown(gen_double_lfsr[1].u_prim_lfsr.DefaultSeedLocal)); + gen_double_lfsr[1].u_prim_lfsr.DefaultSeedLocal = + gen_double_lfsr[0].u_prim_lfsr.DefaultSeedLocal; + $display("%m: Updated gen_double_lfsr[1].u_prim_lfsr.DefaultSeedLocal = 0x%0h", + gen_double_lfsr[1].u_prim_lfsr.DefaultSeedLocal); + end +`endif +`endif + + // Output the state from the first LFSR + assign state_o = lfsr_state[0][StateOutDw-1:0]; + assign err_o = lfsr_state[0] != lfsr_state[1]; + + // This logic that will be assign to one, when user adds macro + // CALIPTRA_ASSERT_PRIM_DOUBLE_LFSR_ERROR_TRIGGER_ALERT to check the error with alert, in case that + // prim_double_lfsr is used in design without adding this assertion check. + `ifdef CALIPTRA_INC_ASSERT + logic unused_assert_connected; + + `CALIPTRA_ASSERT_INIT_NET(AssertConnected_A, unused_assert_connected === 1'b1 || !EnableAlertTriggerSVA) + `endif +endmodule : caliptra_prim_double_lfsr diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_edge_detector.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_edge_detector.sv new file mode 100644 index 0000000..56eee82 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_edge_detector.sv @@ -0,0 +1,55 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Edge Detector + +module caliptra_prim_edge_detector #( + parameter int unsigned Width = 1, + + parameter logic [Width-1:0] ResetValue = '0, + + // EnSync + // + // Enable Synchronizer to the input signal. + // It is assumed that the input signal is glitch free (registered input). + parameter bit EnSync = 1'b 1 +) ( + input clk_i, + input rst_ni, + + input [Width-1:0] d_i, + output logic [Width-1:0] q_sync_o, + + output logic [Width-1:0] q_posedge_pulse_o, + output logic [Width-1:0] q_negedge_pulse_o +); + + logic [Width-1:0] q_sync_d, q_sync_q; + + if (EnSync) begin : g_sync + caliptra_prim_flop_2sync #( + .Width (Width), + .ResetValue (ResetValue) + ) u_sync ( + .clk_i, + .rst_ni, + .d_i, + .q_o (q_sync_d) + ); + end : g_sync + else begin : g_nosync + assign q_sync_d = d_i; + end : g_nosync + + assign q_sync_o = q_sync_d; + + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) q_sync_q <= ResetValue; + else q_sync_q <= q_sync_d; + end + + assign q_posedge_pulse_o = q_sync_d & ~q_sync_q; + assign q_negedge_pulse_o = ~q_sync_d & q_sync_q; + +endmodule : caliptra_prim_edge_detector diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_edn_req.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_edn_req.sv new file mode 100644 index 0000000..e5528d7 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_edn_req.sv @@ -0,0 +1,215 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// This module can be used as a "gadget" to adapt the native 32bit width of the EDN network +// locally to the width needed by the consuming logic. For example, if the local consumer +// needs 128bit, this module would request four 32 bit words from EDN and stack them accordingly. +// +// The module also uses a req/ack synchronizer to synchronize the EDN data over to the local +// clock domain. Note that this assumes that the EDN data bus remains stable between subsequent +// requests. +// + +`include "caliptra_prim_assert.sv" + +module caliptra_prim_edn_req + import caliptra_prim_alert_pkg::*; +#( + parameter int OutWidth = 32, + // Repetition check for incoming edn data + parameter bit RepCheck = 0, + // Disable reset-related assertion checks inside prim_sync_reqack primitives. + parameter bit EnRstChks = 0, + + // EDN Request latency checker + // + // Each consumer IP may have the maximum expected latency. MaxLatency + // parameter describes the expected latency in terms of the consumer clock + // cycles. If the edn request comes later than that, the assertion will be + // fired. + // + // The default value is 0, which disables the assertion. + parameter int unsigned MaxLatency = 0 +) ( + // Design side + input clk_i, + input rst_ni, + input req_chk_i, // Used for gating assertions. Drive to 1 during normal + // operation. + input req_i, + output logic ack_o, + output logic [OutWidth-1:0] data_o, + output logic fips_o, + output logic err_o, // current data_o failed repetition check + // EDN side + input clk_edn_i, + input rst_edn_ni, + output edn_pkg::edn_req_t edn_o, + input edn_pkg::edn_rsp_t edn_i +); + + // Stop requesting words from EDN once desired amount of data is available. + logic word_req, word_ack; + assign word_req = req_i & ~ack_o; + + logic [edn_pkg::ENDPOINT_BUS_WIDTH-1:0] word_data; + logic word_fips; + localparam int SyncWidth = $bits({edn_i.edn_fips, edn_i.edn_bus}); + caliptra_prim_sync_reqack_data #( + .Width(SyncWidth), + .EnRstChks(EnRstChks), + .DataSrc2Dst(1'b0), + .DataReg(1'b0) + ) u_prim_sync_reqack_data ( + .clk_src_i ( clk_i ), + .rst_src_ni ( rst_ni ), + .clk_dst_i ( clk_edn_i ), + .rst_dst_ni ( rst_edn_ni ), + .req_chk_i ( req_chk_i ), + .src_req_i ( word_req ), + .src_ack_o ( word_ack ), + .dst_req_o ( edn_o.edn_req ), + .dst_ack_i ( edn_i.edn_ack ), + .data_i ( {edn_i.edn_fips, edn_i.edn_bus} ), + .data_o ( {word_fips, word_data} ) + ); + + if (RepCheck) begin : gen_rep_chk + logic [edn_pkg::ENDPOINT_BUS_WIDTH-1:0] word_data_q; + always_ff @(posedge clk_i) begin + if (word_ack) begin + word_data_q <= word_data; + end + end + + // do not check until we have received at least the first entry + logic chk_rep; + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + chk_rep <= '0; + end else if (word_ack) begin + chk_rep <= 1'b1; + end + end + + // Need to track if any of the packed words has failed the repetition check, i.e., is identical + // to the last packed word. + logic err_d, err_q; + assign err_d = (req_i && ack_o) ? 1'b0 : // clear + (chk_rep && word_ack && word_data == word_data_q) ? 1'b1 : // set + err_q; // keep + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + err_q <= 1'b0; + end else begin + err_q <= err_d; + end + end + assign err_o = err_q; + + end else begin : gen_no_rep_chk // block: gen_rep_chk + assign err_o = '0; + end + + caliptra_prim_packer_fifo #( + .InW(edn_pkg::ENDPOINT_BUS_WIDTH), + .OutW(OutWidth), + .ClearOnRead(1'b0) + ) u_prim_packer_fifo ( + .clk_i, + .rst_ni, + .clr_i ( 1'b0 ), // not needed + .wvalid_i ( word_ack ), + .wdata_i ( word_data ), + // no need for backpressure since we're always ready to + // sink data at this point. + .wready_o ( ), + .rvalid_o ( ack_o ), + .rdata_o ( data_o ), + // we're always ready to receive the packed output word + // at this point. + .rready_i ( 1'b1 ), + .depth_o ( ) + ); + + // Need to track if any of the packed words has been generated with a pre-FIPS seed, i.e., has + // fips == 1'b0. + logic fips_d, fips_q; + assign fips_d = (req_i && ack_o) ? 1'b1 : // clear + (word_ack) ? fips_q & word_fips : // accumulate + fips_q; // keep + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + fips_q <= 1'b1; + end else begin + fips_q <= fips_d; + end + end + assign fips_o = fips_q; + + //////////////// + // Assertions // + //////////////// + + // Check EDN data is valid: Not all zeros, all ones, or not the same as previous data. +`ifdef CALIPTRA_INC_ASSERT + //VCS coverage off + // pragma coverage off + + logic [OutWidth-1:0] data_prev, data_curr; + + always_ff @(posedge ack_o or negedge rst_ni) begin + if (!rst_ni) begin + data_prev <= '0; + data_curr <= '0; + end else if (ack_o) begin + data_curr <= data_o; + data_prev <= data_curr; + end + end + //VCS coverage on + // pragma coverage on + + `CALIPTRA_ASSERT(DataOutputValid_A, ack_o |-> (data_o != 0) && (data_o != '1)) + `CALIPTRA_ASSERT(DataOutputDiffFromPrev_A, data_prev != 0 |-> data_prev != data_o) +`endif + + // EDN Max Latency Checker +`ifndef SYNTHESIS + if (MaxLatency != 0) begin: g_maxlatency_assertion + //VCS coverage off + // pragma coverage off + localparam int unsigned LatencyW = $clog2(MaxLatency+1); + logic [LatencyW-1:0] latency_counter; + logic reset_counter; + logic enable_counter; + + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) latency_counter <= '0; + else if (reset_counter) latency_counter <= '0; + else if (enable_counter) latency_counter <= latency_counter + 1'b1; + end + + assign reset_counter = ack_o; + assign enable_counter = req_i; + //VCS coverage on + // pragma coverage on + + `CALIPTRA_ASSERT(MaxLatency_A, latency_counter <= MaxLatency) + + // TODO: Is it worth to check req & ack pair? + // _________________________________ + // req __/ \______ + // ____ + // ack ____________________________________/ \_ + // + // | error + + end // g_maxlatency_assertion +`else // SYNTHESIS + logic unused_param_maxlatency; + assign unused_param_maxlatency = ^MaxLatency; +`endif // SYNTHESIS + +endmodule : caliptra_prim_edn_req diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_esc_pkg.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_esc_pkg.sv new file mode 100644 index 0000000..0fdb8ad --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_esc_pkg.sv @@ -0,0 +1,23 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +package caliptra_prim_esc_pkg; + + typedef struct packed { + logic esc_p; + logic esc_n; + } esc_tx_t; + + typedef struct packed { + logic resp_p; + logic resp_n; + } esc_rx_t; + + parameter esc_tx_t ESC_TX_DEFAULT = '{esc_p: 1'b0, + esc_n: 1'b1}; + + parameter esc_rx_t ESC_RX_DEFAULT = '{resp_p: 1'b0, + resp_n: 1'b1}; + +endpackage : caliptra_prim_esc_pkg diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_esc_receiver.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_esc_receiver.sv new file mode 100644 index 0000000..1da9628 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_esc_receiver.sv @@ -0,0 +1,290 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// This module decodes escalation enable pulses that have been encoded using +// the caliptra_prim_esc_sender module. +// +// The module supports in-band ping testing of the escalation +// wires. This is accomplished by the sender module that places a single-cycle, +// differentially encoded pulse on esc_p/n which will be interpreted as a ping +// request by the receiver module. The receiver module responds by sending back +// the response pattern "1010". +// +// Native escalation enable pulses are differentiated from ping +// requests by making sure that these pulses are always longer than 1 cycle. +// +// See also: caliptra_prim_esc_sender, caliptra_prim_diff_decode, alert_handler + +`include "caliptra_prim_assert.sv" + +module caliptra_prim_esc_receiver + import caliptra_prim_esc_pkg::*; +#( + // The number of escalation severities. Should be set to the Alert Handler's N_ESC_SEV when this + // primitive is instantiated. + parameter int N_ESC_SEV = 4, + + // The width of the Alert Handler's ping counter. Should be set to the Alert Handler's PING_CNT_DW + // when this primitive is instantiated. + parameter int PING_CNT_DW = 16, + + // This counter monitors incoming ping requests and auto-escalates if the alert handler + // ceases to send them regularly. The maximum number of cycles between subsequent ping requests + // is N_ESC_SEV x (2 x 2 x 2**PING_CNT_DW), see also implementation of the ping timer + // (alert_handler_ping_timer.sv). The timeout counter below uses a timeout that is 4x larger than + // that in order to incorporate some margin. + // + // Do NOT modify this counter value, when instantiating it in the design. It is only exposed to + // reduce the state space in the FPV testbench. + localparam int MarginFactor = 4, + localparam int NumWaitCounts = 2, + localparam int NumTimeoutCounts = 2, + parameter int TimeoutCntDw = $clog2(MarginFactor) + + $clog2(N_ESC_SEV) + + $clog2(NumWaitCounts) + + $clog2(NumTimeoutCounts) + + PING_CNT_DW +) ( + input clk_i, + input rst_ni, + // escalation enable + output logic esc_req_o, + // escalation / ping response + output esc_rx_t esc_rx_o, + // escalation output diff pair + input esc_tx_t esc_tx_i +); + + ///////////////////////////////// + // decode differential signals // + ///////////////////////////////// + + logic esc_level, esc_p, esc_n, sigint_detected; + + // This prevents further tool optimizations of the differential signal. + caliptra_prim_buf #( + .Width(2) + ) u_caliptra_prim_buf_esc ( + .in_i({esc_tx_i.esc_n, + esc_tx_i.esc_p}), + .out_o({esc_n, + esc_p}) + ); + + caliptra_prim_diff_decode #( + .AsyncOn(1'b0) + ) u_decode_esc ( + .clk_i, + .rst_ni, + .diff_pi ( esc_p ), + .diff_ni ( esc_n ), + .level_o ( esc_level ), + .rise_o ( ), + .fall_o ( ), + .event_o ( ), + .sigint_o ( sigint_detected ) + ); + + //////////////////////////////////////////// + // Ping Monitor Counter / Auto Escalation // + //////////////////////////////////////////// + + // The timeout counter is kicked off when the first ping occurs, and subsequent pings reset + // the counter to 1. The counter keeps on counting when it is nonzero, and saturates when it + // has reached its maximum (this state is terminal). + logic ping_en, timeout_cnt_error; + logic timeout_cnt_set, timeout_cnt_en; + logic [TimeoutCntDw-1:0] timeout_cnt; + assign timeout_cnt_set = (ping_en && !(&timeout_cnt)); + assign timeout_cnt_en = (timeout_cnt > '0); + + caliptra_prim_count #( + .Width(TimeoutCntDw), + // The escalation receiver behaves differently than other comportable IP. I.e., instead of + // sending out an alert signal, this condition is handled internally in the alert handler. + .EnableAlertTriggerSVA(0), + // Pass a parameter to disable coverage for some assertions that are unreachable because + // clr_i and decr_en_i are tied to zero. + .PossibleActions(caliptra_prim_count_pkg::Set | caliptra_prim_count_pkg::Incr) + ) u_caliptra_prim_count ( + .clk_i, + .rst_ni, + .clr_i(1'b0), + .set_i(timeout_cnt_set), + .set_cnt_i(TimeoutCntDw'(1)), + .incr_en_i(timeout_cnt_en), + .decr_en_i(1'b0), + .step_i(TimeoutCntDw'(1)), + .commit_i(1'b1), + .cnt_o(timeout_cnt), + .cnt_after_commit_o(), + .err_o(timeout_cnt_error) + ); + + // Escalation is asserted if + // - requested via the escalation sender/receiver path, + // - the ping monitor timeout is reached, + // - the two ping monitor counters are in an inconsistent state. + // Register the escalation request to avoid potential CDC issues downstream. + logic esc_req, esc_req_d, esc_req_q; + assign esc_req_d = esc_req || (&timeout_cnt) || timeout_cnt_error; + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + esc_req_q <= 1'b0; + end else begin + esc_req_q <= esc_req_d; + end + end + + caliptra_prim_sec_anchor_buf #( + .Width(1) + ) u_caliptra_prim_buf_esc_req ( + .in_i (esc_req_q), + .out_o(esc_req_o) + ); + + ///////////////// + // RX/TX Logic // + ///////////////// + + typedef enum logic [2:0] {Idle, Check, PingResp, EscResp, SigInt} state_e; + state_e state_d, state_q; + logic resp_pd, resp_pq; + logic resp_nd, resp_nq; + + // This prevents further tool optimizations of the differential signal. + caliptra_prim_sec_anchor_flop #( + .Width(2), + .ResetValue(2'b10) + ) u_caliptra_prim_flop_esc ( + .clk_i, + .rst_ni, + .d_i({resp_nd, resp_pd}), + .q_o({resp_nq, resp_pq}) + ); + + assign esc_rx_o.resp_p = resp_pq; + assign esc_rx_o.resp_n = resp_nq; + + always_comb begin : p_fsm + // default + state_d = state_q; + resp_pd = 1'b0; + resp_nd = 1'b1; + esc_req = 1'b0; + ping_en = 1'b0; + + unique case (state_q) + // wait for the esc_p/n diff pair + Idle: begin + if (esc_level) begin + state_d = Check; + resp_pd = ~resp_pq; + resp_nd = resp_pq; + end + end + // we decide here whether this is only a ping request or + // whether this is an escalation enable + Check: begin + state_d = PingResp; + resp_pd = ~resp_pq; + resp_nd = resp_pq; + if (esc_level) begin + state_d = EscResp; + esc_req = 1'b1; + end + end + // finish ping response. in case esc_level is again asserted, + // we got an escalation signal (pings cannot occur back to back) + PingResp: begin + state_d = Idle; + resp_pd = ~resp_pq; + resp_nd = resp_pq; + ping_en = 1'b1; + if (esc_level) begin + state_d = EscResp; + esc_req = 1'b1; + end + end + // we have got an escalation enable pulse, + // keep on toggling the outputs + EscResp: begin + state_d = Idle; + if (esc_level) begin + state_d = EscResp; + resp_pd = ~resp_pq; + resp_nd = resp_pq; + esc_req = 1'b1; + end + end + // we have a signal integrity issue at one of + // the incoming diff pairs. this condition is + // signalled to the sender by setting the resp + // diffpair to the same value and continuously + // toggling them. + SigInt: begin + state_d = Idle; + esc_req = 1'b1; + if (sigint_detected) begin + state_d = SigInt; + resp_pd = ~resp_pq; + resp_nd = ~resp_pq; + end + end + default: state_d = Idle; + endcase + + // bail out if a signal integrity issue has been detected + if (sigint_detected && (state_q != SigInt)) begin + state_d = SigInt; + resp_pd = 1'b0; + resp_nd = 1'b0; + end + end + + + /////////////// + // Registers // + /////////////// + + always_ff @(posedge clk_i or negedge rst_ni) begin : p_regs + if (!rst_ni) begin + state_q <= Idle; + end else begin + state_q <= state_d; + end + end + + //////////////// + // assertions // + //////////////// + + // check whether all outputs have a good known state after reset + `CALIPTRA_ASSERT_KNOWN(EscEnKnownO_A, esc_req_o) + `CALIPTRA_ASSERT_KNOWN(RespPKnownO_A, esc_rx_o) + + `CALIPTRA_ASSERT(SigIntCheck0_A, esc_tx_i.esc_p == esc_tx_i.esc_n |=> esc_rx_o.resp_p == esc_rx_o.resp_n) + `CALIPTRA_ASSERT(SigIntCheck1_A, esc_tx_i.esc_p == esc_tx_i.esc_n |=> state_q == SigInt) + // auto-escalate in case of signal integrity issue + `CALIPTRA_ASSERT(SigIntCheck2_A, esc_tx_i.esc_p == esc_tx_i.esc_n |=> esc_req_d) + // correct diff encoding + `CALIPTRA_ASSERT(DiffEncCheck_A, esc_tx_i.esc_p ^ esc_tx_i.esc_n |=> esc_rx_o.resp_p ^ esc_rx_o.resp_n) + // disable in case of signal integrity issue + `CALIPTRA_ASSERT(PingRespCheck_A, state_q == Idle ##1 $rose(esc_tx_i.esc_p) ##1 $fell(esc_tx_i.esc_p) |-> + $rose(esc_rx_o.resp_p) ##1 $fell(esc_rx_o.resp_p), + clk_i, !rst_ni || (esc_tx_i.esc_p == esc_tx_i.esc_n)) + // escalation response needs to continuously toggle + `CALIPTRA_ASSERT(EscRespCheck_A, ##1 esc_tx_i.esc_p && $past(esc_tx_i.esc_p) && + (esc_tx_i.esc_p ^ esc_tx_i.esc_n) && $past(esc_tx_i.esc_p ^ esc_tx_i.esc_n) + |=> esc_rx_o.resp_p != $past(esc_rx_o.resp_p)) + // detect escalation pulse + `CALIPTRA_ASSERT(EscEnCheck_A, + esc_tx_i.esc_p && (esc_tx_i.esc_p ^ esc_tx_i.esc_n) && state_q != SigInt + ##1 esc_tx_i.esc_p && (esc_tx_i.esc_p ^ esc_tx_i.esc_n) |-> esc_req_d) + // make sure the counter does not wrap around + `CALIPTRA_ASSERT(EscCntWrap_A, &timeout_cnt |=> timeout_cnt != 0) + // if the counter expires, escalation should be asserted + `CALIPTRA_ASSERT(EscCntEsc_A, &timeout_cnt |-> esc_req_d) + +endmodule : caliptra_prim_esc_receiver diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_fifo_async.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_fifo_async.sv new file mode 100644 index 0000000..80b57f7 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_fifo_async.sv @@ -0,0 +1,298 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Generic asynchronous fifo for use in a variety of devices. + +`include "caliptra_prim_assert.sv" + +module caliptra_prim_fifo_async #( + parameter int unsigned Width = 16, + parameter int unsigned Depth = 4, + parameter bit OutputZeroIfEmpty = 1'b0, // if == 1 always output 0 when FIFO is empty + parameter bit OutputZeroIfInvalid = 1'b0, // if == 1 always output 0 when rvalid_o is low + localparam int unsigned DepthW = $clog2(Depth+1) // derived parameter representing [0..Depth] +) ( + // write port + input logic clk_wr_i, + input logic rst_wr_ni, + input logic wvalid_i, + output logic wready_o, + input logic [Width-1:0] wdata_i, + output logic [DepthW-1:0] wdepth_o, + + // read port + input logic clk_rd_i, + input logic rst_rd_ni, + output logic rvalid_o, + input logic rready_i, + output logic [Width-1:0] rdata_o, + output logic [DepthW-1:0] rdepth_o +); + + // Depth must be a power of 2 for the gray code pointers to work + `CALIPTRA_ASSERT_INIT(ParamCheckDepth_A, (Depth == 2**$clog2(Depth))) + + localparam int unsigned PTRV_W = (Depth == 1) ? 1 : $clog2(Depth); + localparam int unsigned PTR_WIDTH = (Depth == 1) ? 1 : PTRV_W+1; + + logic [PTR_WIDTH-1:0] fifo_wptr_q, fifo_wptr_d; + logic [PTR_WIDTH-1:0] fifo_rptr_q, fifo_rptr_d; + logic [PTR_WIDTH-1:0] fifo_wptr_sync_combi, fifo_rptr_sync_combi; + logic [PTR_WIDTH-1:0] fifo_wptr_gray_sync, fifo_rptr_gray_sync, fifo_rptr_sync_q; + logic [PTR_WIDTH-1:0] fifo_wptr_gray_q, fifo_wptr_gray_d; + logic [PTR_WIDTH-1:0] fifo_rptr_gray_q, fifo_rptr_gray_d; + logic fifo_incr_wptr, fifo_incr_rptr; + logic full_wclk, full_rclk, empty_rclk; + logic [Width-1:0] storage [Depth]; + + /////////////////// + // Write Pointer // + /////////////////// + + assign fifo_incr_wptr = wvalid_i & wready_o; + + // decimal version + assign fifo_wptr_d = fifo_wptr_q + PTR_WIDTH'(1'b1); + + always_ff @(posedge clk_wr_i or negedge rst_wr_ni) begin + if (!rst_wr_ni) begin + fifo_wptr_q <= '0; + end else if (fifo_incr_wptr) begin + fifo_wptr_q <= fifo_wptr_d; + end + end + + // gray-coded version + always_ff @(posedge clk_wr_i or negedge rst_wr_ni) begin + if (!rst_wr_ni) begin + fifo_wptr_gray_q <= '0; + end else if (fifo_incr_wptr) begin + fifo_wptr_gray_q <= fifo_wptr_gray_d; + end + end + + // sync gray-coded pointer to read clk + caliptra_prim_flop_2sync #(.Width(PTR_WIDTH)) sync_wptr ( + .clk_i (clk_rd_i), + .rst_ni (rst_rd_ni), + .d_i (fifo_wptr_gray_q), + .q_o (fifo_wptr_gray_sync)); + + ////////////////// + // Read Pointer // + ////////////////// + + assign fifo_incr_rptr = rvalid_o & rready_i; + + // decimal version + assign fifo_rptr_d = fifo_rptr_q + PTR_WIDTH'(1'b1); + + always_ff @(posedge clk_rd_i or negedge rst_rd_ni) begin + if (!rst_rd_ni) begin + fifo_rptr_q <= '0; + end else if (fifo_incr_rptr) begin + fifo_rptr_q <= fifo_rptr_d; + end + end + + // gray-coded version + always_ff @(posedge clk_rd_i or negedge rst_rd_ni) begin + if (!rst_rd_ni) begin + fifo_rptr_gray_q <= '0; + end else if (fifo_incr_rptr) begin + fifo_rptr_gray_q <= fifo_rptr_gray_d; + end + end + + // sync gray-coded pointer to write clk + caliptra_prim_flop_2sync #(.Width(PTR_WIDTH)) sync_rptr ( + .clk_i (clk_wr_i), + .rst_ni (rst_wr_ni), + .d_i (fifo_rptr_gray_q), + .q_o (fifo_rptr_gray_sync)); + + // Registered version of synced read pointer + always_ff @(posedge clk_wr_i or negedge rst_wr_ni) begin + if (!rst_wr_ni) begin + fifo_rptr_sync_q <= '0; + end else begin + fifo_rptr_sync_q <= fifo_rptr_sync_combi; + end + end + + ////////////////// + // Empty / Full // + ////////////////// + + logic [PTR_WIDTH-1:0] xor_mask; + assign xor_mask = PTR_WIDTH'(1'b1) << (PTR_WIDTH-1); + assign full_wclk = (fifo_wptr_q == (fifo_rptr_sync_q ^ xor_mask)); + assign full_rclk = (fifo_wptr_sync_combi == (fifo_rptr_q ^ xor_mask)); + assign empty_rclk = (fifo_wptr_sync_combi == fifo_rptr_q); + + if (Depth > 1) begin : g_depth_calc + + // Current depth in the write clock side + logic wptr_msb; + logic rptr_sync_msb; + logic [PTRV_W-1:0] wptr_value; + logic [PTRV_W-1:0] rptr_sync_value; + + assign wptr_msb = fifo_wptr_q[PTR_WIDTH-1]; + assign rptr_sync_msb = fifo_rptr_sync_q[PTR_WIDTH-1]; + assign wptr_value = fifo_wptr_q[0+:PTRV_W]; + assign rptr_sync_value = fifo_rptr_sync_q[0+:PTRV_W]; + assign wdepth_o = (full_wclk) ? DepthW'(Depth) : + (wptr_msb == rptr_sync_msb) ? DepthW'(wptr_value) - DepthW'(rptr_sync_value) : + (DepthW'(Depth) - DepthW'(rptr_sync_value) + DepthW'(wptr_value)) ; + + // Current depth in the read clock side + logic rptr_msb; + logic wptr_sync_msb; + logic [PTRV_W-1:0] rptr_value; + logic [PTRV_W-1:0] wptr_sync_value; + + assign wptr_sync_msb = fifo_wptr_sync_combi[PTR_WIDTH-1]; + assign rptr_msb = fifo_rptr_q[PTR_WIDTH-1]; + assign wptr_sync_value = fifo_wptr_sync_combi[0+:PTRV_W]; + assign rptr_value = fifo_rptr_q[0+:PTRV_W]; + assign rdepth_o = (full_rclk) ? DepthW'(Depth) : + (wptr_sync_msb == rptr_msb) ? DepthW'(wptr_sync_value) - DepthW'(rptr_value) : + (DepthW'(Depth) - DepthW'(rptr_value) + DepthW'(wptr_sync_value)) ; + + end else begin : g_no_depth_calc + + assign rdepth_o = full_rclk; + assign wdepth_o = full_wclk; + + end + + assign wready_o = ~full_wclk; + assign rvalid_o = ~empty_rclk; + + ///////////// + // Storage // + ///////////// + + logic [Width-1:0] rdata_int; + if (Depth > 1) begin : g_storage_mux + + always_ff @(posedge clk_wr_i) begin + if (fifo_incr_wptr) begin + storage[fifo_wptr_q[PTRV_W-1:0]] <= wdata_i; + end + end + + assign rdata_int = storage[fifo_rptr_q[PTRV_W-1:0]]; + + end else begin : g_storage_simple + + always_ff @(posedge clk_wr_i) begin + if (fifo_incr_wptr) begin + storage[0] <= wdata_i; + end + end + + assign rdata_int = storage[0]; + + end + + // rdata_o is qualified with rvalid_o to avoid CDC error + if (OutputZeroIfEmpty == 1'b1) begin : gen_output_zero + if (OutputZeroIfInvalid == 1'b1) begin : gen_invalid_zero + assign rdata_o = empty_rclk ? '0 : (rvalid_o ? rdata_int : '0); + end + else begin : gen_invalid_non_zero + assign rdata_o = empty_rclk ? '0 : rdata_int; + end + end else begin : gen_no_output_zero + if (OutputZeroIfInvalid == 1'b1) begin : gen_invalid_zero + assign rdata_o = rvalid_o ? rdata_int : '0; + end + else begin : gen_invalid_non_zero + assign rdata_o = rdata_int; + end + end + + ////////////////////////////////////// + // Decimal <-> Gray-code Conversion // + ////////////////////////////////////// + + // This code is all in a generate context to avoid lint errors when Depth <= 2 + if (Depth > 2) begin : g_full_gray_conversion + + function automatic [PTR_WIDTH-1:0] dec2gray(input logic [PTR_WIDTH-1:0] decval); + logic [PTR_WIDTH-1:0] decval_sub; + logic [PTR_WIDTH-1:0] decval_in; + logic unused_decval_msb; + + decval_sub = (PTR_WIDTH)'(Depth) - {1'b0, decval[PTR_WIDTH-2:0]} - 1'b1; + + decval_in = decval[PTR_WIDTH-1] ? decval_sub : decval; + + // We do not care about the MSB, hence we mask it out + unused_decval_msb = decval_in[PTR_WIDTH-1]; + decval_in[PTR_WIDTH-1] = 1'b0; + + // Perform the XOR conversion + dec2gray = decval_in; + dec2gray ^= (decval_in >> 1); + + // Override the MSB + dec2gray[PTR_WIDTH-1] = decval[PTR_WIDTH-1]; + endfunction + + // Algorithm walks up from 0..N-1 then flips the upper bit and walks down from N-1 to 0. + function automatic [PTR_WIDTH-1:0] gray2dec(input logic [PTR_WIDTH-1:0] grayval); + logic [PTR_WIDTH-1:0] dec_tmp, dec_tmp_sub; + logic unused_decsub_msb; + + dec_tmp = '0; + for (int i = PTR_WIDTH-2; i >= 0; i--) begin + dec_tmp[i] = dec_tmp[i+1] ^ grayval[i]; + end + dec_tmp_sub = (PTR_WIDTH)'(Depth) - dec_tmp - 1'b1; + if (grayval[PTR_WIDTH-1]) begin + gray2dec = dec_tmp_sub; + // Override MSB + gray2dec[PTR_WIDTH-1] = 1'b1; + unused_decsub_msb = dec_tmp_sub[PTR_WIDTH-1]; + end else begin + gray2dec = dec_tmp; + end + endfunction + + // decimal version of read pointer in write domain + assign fifo_rptr_sync_combi = gray2dec(fifo_rptr_gray_sync); + // decimal version of write pointer in read domain + assign fifo_wptr_sync_combi = gray2dec(fifo_wptr_gray_sync); + + assign fifo_rptr_gray_d = dec2gray(fifo_rptr_d); + assign fifo_wptr_gray_d = dec2gray(fifo_wptr_d); + + end else if (Depth == 2) begin : g_simple_gray_conversion + + assign fifo_rptr_sync_combi = {fifo_rptr_gray_sync[PTR_WIDTH-1], ^fifo_rptr_gray_sync}; + assign fifo_wptr_sync_combi = {fifo_wptr_gray_sync[PTR_WIDTH-1], ^fifo_wptr_gray_sync}; + + assign fifo_rptr_gray_d = {fifo_rptr_d[PTR_WIDTH-1], ^fifo_rptr_d}; + assign fifo_wptr_gray_d = {fifo_wptr_d[PTR_WIDTH-1], ^fifo_wptr_d}; + + end else begin : g_no_gray_conversion + + assign fifo_rptr_sync_combi = fifo_rptr_gray_sync; + assign fifo_wptr_sync_combi = fifo_wptr_gray_sync; + + assign fifo_rptr_gray_d = fifo_rptr_d; + assign fifo_wptr_gray_d = fifo_wptr_d; + + end + + // TODO: assertions on full, empty + `CALIPTRA_ASSERT(GrayWptr_A, ##1 $countones(fifo_wptr_gray_q ^ $past(fifo_wptr_gray_q)) <= 1, + clk_wr_i, !rst_wr_ni) + `CALIPTRA_ASSERT(GrayRptr_A, ##1 $countones(fifo_rptr_gray_q ^ $past(fifo_rptr_gray_q)) <= 1, + clk_rd_i, !rst_rd_ni) + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_fifo_async_simple.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_fifo_async_simple.sv new file mode 100644 index 0000000..9a75e53 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_fifo_async_simple.sv @@ -0,0 +1,91 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// + +`include "caliptra_prim_assert.sv" + +module caliptra_prim_fifo_async_simple #( + parameter int unsigned Width = 16, + parameter bit EnRstChks = 1'b0, // Enable reset-related assertion checks, disabled by + // default. + parameter bit EnRzHs = 1'b0 // By Default, the faster NRZ handshake protocol + // (EnRzHs = 0) is used. Enable the RZ handshake protocol + // if the FSMs need to be partial-reset-safe. +) ( + // write port + input logic clk_wr_i, + input logic rst_wr_ni, + input logic wvalid_i, + output logic wready_o, + input logic [Width-1:0] wdata_i, + + // read port + input logic clk_rd_i, + input logic rst_rd_ni, + output logic rvalid_o, + input logic rready_i, + output logic [Width-1:0] rdata_o +); + + //////////////// + // FIFO logic // + //////////////// + + // Convert ready/valid to req/ack + logic wr_en; + logic src_req, src_ack; + logic pending_d, pending_q, not_in_reset_q; + assign wready_o = !pending_q && not_in_reset_q; + assign wr_en = wvalid_i && wready_o; + assign src_req = pending_q || wvalid_i; + + assign pending_d = (src_ack) ? 1'b0 : + (wr_en) ? 1'b1 : pending_q; + + logic dst_req, dst_ack; + assign rvalid_o = dst_req; + assign dst_ack = dst_req && rready_i; + + always_ff @(posedge clk_wr_i or negedge rst_wr_ni) begin + if (!rst_wr_ni) begin + pending_q <= 1'b0; + not_in_reset_q <= 1'b0; + end else begin + pending_q <= pending_d; + not_in_reset_q <= 1'b1; + end + end + + //////////////////////////////////// + // REQ/ACK synchronizer primitive // + //////////////////////////////////// + + caliptra_prim_sync_reqack #( + .EnRstChks(EnRstChks), + .EnRzHs(EnRzHs) + ) u_caliptra_prim_sync_reqack ( + .clk_src_i(clk_wr_i), + .rst_src_ni(rst_wr_ni), + .clk_dst_i(clk_rd_i), + .rst_dst_ni(rst_rd_ni), + .req_chk_i(1'b0), + .src_req_i(src_req), + .src_ack_o(src_ack), + .dst_req_o(dst_req), + .dst_ack_i(dst_ack) + ); + + ////////////////////// + // Data holding reg // + ////////////////////// + + logic [Width-1:0] data_q; + always_ff @(posedge clk_wr_i) begin + if (wr_en) begin + data_q <= wdata_i; + end + end + assign rdata_o = data_q; + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_fifo_sync.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_fifo_sync.sv new file mode 100644 index 0000000..ba68c6e --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_fifo_sync.sv @@ -0,0 +1,186 @@ +// Copyright lowRISC contributors. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Generic synchronous fifo for use in a variety of devices. + +`include "caliptra_prim_assert.sv" + +module caliptra_prim_fifo_sync #( + parameter int unsigned Width = 16, + parameter bit Pass = 1'b1, // if == 1 allow requests to pass through empty FIFO + parameter int unsigned Depth = 4, + parameter bit OutputZeroIfEmpty = 1'b1, // if == 1 always output 0 when FIFO is empty + parameter bit Secure = 1'b0, // use prim count for pointers + parameter int unsigned resetOnClear = 0, // if == 1, reset the FIFO on clear + // derived parameter + localparam int DepthW = caliptra_prim_util_pkg::vbits(Depth+1) +) ( + input clk_i, + input rst_ni, + // synchronous clear / flush port + input clr_i, + // write port + input wvalid_i, + output wready_o, + input [Width-1:0] wdata_i, + // read port + output rvalid_o, + input rready_i, + output [Width-1:0] rdata_o, + // occupancy + output full_o, + output [DepthW-1:0] depth_o, + output err_o +); + + + // FIFO is in complete passthrough mode + if (Depth == 0) begin : gen_passthru_fifo + `CALIPTRA_ASSERT_INIT(paramCheckPass, Pass == 1) + + assign depth_o = 1'b0; //output is meaningless + + // device facing + assign rvalid_o = wvalid_i; + assign rdata_o = wdata_i; + + // host facing + assign wready_o = rready_i; + assign full_o = rready_i; + + // this avoids lint warnings + logic unused_clr; + assign unused_clr = clr_i; + + // No error + assign err_o = 1'b 0; + + // Normal FIFO construction + end else begin : gen_normal_fifo + + localparam int unsigned PtrW = caliptra_prim_util_pkg::vbits(Depth); + + logic [PtrW-1:0] fifo_wptr, fifo_rptr; + logic fifo_incr_wptr, fifo_incr_rptr, fifo_empty; + + // module under reset flag + logic under_rst; + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + under_rst <= 1'b1; + end else if (under_rst) begin + under_rst <= ~under_rst; + end + end + + logic empty; + + // full and not ready for write are two different concepts. + // The latter can be '0' when under reset, while the former is an indication that no more + // entries can be written. + assign wready_o = ~full_o & ~under_rst; + assign rvalid_o = ~empty & ~under_rst; + + caliptra_prim_fifo_sync_cnt #( + .Depth(Depth), + .Secure(Secure) + ) u_fifo_cnt ( + .clk_i, + .rst_ni, + .clr_i, + .incr_wptr_i(fifo_incr_wptr), + .incr_rptr_i(fifo_incr_rptr), + .wptr_o(fifo_wptr), + .rptr_o(fifo_rptr), + .full_o, + .empty_o(fifo_empty), + .depth_o, + .err_o + ); + assign fifo_incr_wptr = wvalid_i & wready_o & ~under_rst; + assign fifo_incr_rptr = rvalid_o & rready_i & ~under_rst; + + // the generate blocks below are needed to avoid lint errors due to array indexing + // in the where the fifo only has one storage element + logic [Depth-1:0][Width-1:0] storage; + logic [Width-1:0] storage_rdata; + if (Depth == 1) begin : gen_depth_eq1 + assign storage_rdata = storage[0]; + + if (resetOnClear) begin : gen_depth_eq1_reset + + always_ff @(posedge clk_i) + if (clr_i) begin + storage[0] <= '0; + end + else if (fifo_incr_wptr) begin + storage[0] <= wdata_i; + end + + end else begin : gen_depth_eq1_no_reset + + always_ff @(posedge clk_i) + if (fifo_incr_wptr) begin + storage[0] <= wdata_i; + end + + end + + logic unused_ptrs; + assign unused_ptrs = ^{fifo_wptr, fifo_rptr}; + + // fifo with more than one storage element + end else begin : gen_depth_gt1 + assign storage_rdata = storage[fifo_rptr]; + + if (resetOnClear) begin : gen_depth_gt1_reset + + always_ff @(posedge clk_i) + if (clr_i) begin + storage <= '0; + end + else if (fifo_incr_wptr) begin + storage[fifo_wptr] <= wdata_i; + end + + end else begin : gen_depth_gt1_no_reset + + always_ff @(posedge clk_i) + if (fifo_incr_wptr) begin + storage[fifo_wptr] <= wdata_i; + end + + end + + end + + logic [Width-1:0] rdata_int; + if (Pass == 1'b1) begin : gen_pass + assign rdata_int = (fifo_empty && wvalid_i) ? wdata_i : storage_rdata; + assign empty = fifo_empty & ~wvalid_i; + end else begin : gen_nopass + assign rdata_int = storage_rdata; + assign empty = fifo_empty; + end + + if (OutputZeroIfEmpty == 1'b1) begin : gen_output_zero + assign rdata_o = empty ? Width'(0) : rdata_int; + end else begin : gen_no_output_zero + assign rdata_o = rdata_int; + end + + `CALIPTRA_ASSERT(depthShallNotExceedParamDepth, !empty |-> depth_o <= DepthW'(Depth)) + end // block: gen_normal_fifo + + + ////////////////////// + // Known Assertions // + ////////////////////// + + `CALIPTRA_ASSERT(DataKnown_A, rvalid_o |-> !$isunknown(rdata_o)) + `CALIPTRA_ASSERT_KNOWN(DepthKnown_A, depth_o) + `CALIPTRA_ASSERT_KNOWN(RvalidKnown_A, rvalid_o) + `CALIPTRA_ASSERT_KNOWN(WreadyKnown_A, wready_o) + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_fifo_sync_cnt.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_fifo_sync_cnt.sv new file mode 100644 index 0000000..d600567 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_fifo_sync_cnt.sv @@ -0,0 +1,139 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Read and write pointer logic for synchronous FIFOs + +`include "caliptra_prim_assert.sv" + +module caliptra_prim_fifo_sync_cnt #( + // Depth of the FIFO, i.e., maximum number of entries the FIFO can contain + parameter int unsigned Depth = 4, + // Whether to instantiate hardened counters + parameter bit Secure = 1'b0, + // Width of the read and write pointers for the FIFO + localparam int unsigned PtrW = caliptra_prim_util_pkg::vbits(Depth), + // Width of the 'current depth' output + localparam int unsigned DepthW = caliptra_prim_util_pkg::vbits(Depth+1) +) ( + input clk_i, + input rst_ni, + input clr_i, + input incr_wptr_i, + input incr_rptr_i, + // Write and read pointers. Value range: [0, Depth-1] + output logic [PtrW-1:0] wptr_o, + output logic [PtrW-1:0] rptr_o, + output logic full_o, + output logic empty_o, + // Current depth of the FIFO, i.e., number of entries the FIFO currently contains. + // Value range: [0, Depth] + output logic [DepthW-1:0] depth_o, + output logic err_o +); + + // Internal 'wrap' pointers that have an extra leading bit to account for wraparounds. + localparam int unsigned WrapPtrW = PtrW + 1; + logic [WrapPtrW-1:0] wptr_wrap_cnt_q, wptr_wrap_set_cnt, + rptr_wrap_cnt_q, rptr_wrap_set_cnt; + + // Derive real read and write pointers by truncating the internal 'wrap' pointers. + assign wptr_o = wptr_wrap_cnt_q[PtrW-1:0]; + assign rptr_o = rptr_wrap_cnt_q[PtrW-1:0]; + + // Extract the MSB of the 'wrap' pointers. + logic wptr_wrap_msb, rptr_wrap_msb; + assign wptr_wrap_msb = wptr_wrap_cnt_q[WrapPtrW-1]; + assign rptr_wrap_msb = rptr_wrap_cnt_q[WrapPtrW-1]; + + // Wrap pointers when they have reached the maximum value and are about to get incremented. + logic wptr_wrap_set, rptr_wrap_set; + assign wptr_wrap_set = incr_wptr_i & (wptr_o == PtrW'(Depth-1)); + assign rptr_wrap_set = incr_rptr_i & (rptr_o == PtrW'(Depth-1)); + + // When wrapping, invert the MSB and reset all lower bits to zero. + assign wptr_wrap_set_cnt = {~wptr_wrap_msb, {(WrapPtrW-1){1'b0}}}; + assign rptr_wrap_set_cnt = {~rptr_wrap_msb, {(WrapPtrW-1){1'b0}}}; + + // Full when both 'wrap' counters have a different MSB but all lower bits are equal. + assign full_o = wptr_wrap_cnt_q == (rptr_wrap_cnt_q ^ {1'b1, {(WrapPtrW-1){1'b0}}}); + // Empty when both 'wrap' counters are equal in all bits including the MSB. + assign empty_o = wptr_wrap_cnt_q == rptr_wrap_cnt_q; + + // The current depth is equal to: + // - when full: the maximum depth; + // - when both or none of the 'wrap' pointers are wrapped: the difference of the real pointers; + // - when only one of the two 'wrap' pointers is wrapped: the maximum depth minus the difference + // of the real pointers. + assign depth_o = full_o ? DepthW'(Depth) : + wptr_wrap_msb == rptr_wrap_msb ? DepthW'(wptr_o) - DepthW'(rptr_o) : + DepthW'(Depth) - DepthW'(rptr_o) + DepthW'(wptr_o); + + if (Secure) begin : gen_secure_ptrs + logic wptr_err; + caliptra_prim_count #( + .Width(WrapPtrW) + ) u_wptr ( + .clk_i, + .rst_ni, + .clr_i, + .set_i(wptr_wrap_set), + .set_cnt_i(wptr_wrap_set_cnt), + .incr_en_i(incr_wptr_i), + .decr_en_i(1'b0), + .step_i(WrapPtrW'(1'b1)), + .commit_i(1'b1), + .cnt_o(wptr_wrap_cnt_q), + .cnt_after_commit_o(), + .err_o(wptr_err) + ); + + logic rptr_err; + caliptra_prim_count #( + .Width(WrapPtrW) + ) u_rptr ( + .clk_i, + .rst_ni, + .clr_i, + .set_i(rptr_wrap_set), + .set_cnt_i(rptr_wrap_set_cnt), + .incr_en_i(incr_rptr_i), + .decr_en_i(1'b0), + .step_i(WrapPtrW'(1'b1)), + .commit_i(1'b1), + .cnt_o(rptr_wrap_cnt_q), + .cnt_after_commit_o(), + .err_o(rptr_err) + ); + + assign err_o = wptr_err | rptr_err; + + end else begin : gen_normal_ptrs + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + wptr_wrap_cnt_q <= {WrapPtrW{1'b0}}; + end else if (clr_i) begin + wptr_wrap_cnt_q <= {WrapPtrW{1'b0}}; + end else if (wptr_wrap_set) begin + wptr_wrap_cnt_q <= wptr_wrap_set_cnt; + end else if (incr_wptr_i) begin + wptr_wrap_cnt_q <= wptr_wrap_cnt_q + {{(WrapPtrW-1){1'b0}}, 1'b1}; + end + end + + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + rptr_wrap_cnt_q <= {WrapPtrW{1'b0}}; + end else if (clr_i) begin + rptr_wrap_cnt_q <= {WrapPtrW{1'b0}}; + end else if (rptr_wrap_set) begin + rptr_wrap_cnt_q <= rptr_wrap_set_cnt; + end else if (incr_rptr_i) begin + rptr_wrap_cnt_q <= rptr_wrap_cnt_q + {{(WrapPtrW-1){1'b0}}, 1'b1}; + end + end + + assign err_o = '0; + end + +endmodule // caliptra_prim_fifo_sync_cnt diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_flop.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_flop.sv new file mode 100755 index 0000000..7f71a6c --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_flop.sv @@ -0,0 +1,51 @@ +// Copyright lowRISC contributors. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// This file is auto-generated. +// Used parser: Fallback (regex) + +`include "caliptra_prim_module_name_macros.svh" + +`ifndef CALIPTRA_PRIM_DEFAULT_IMPL + `define CALIPTRA_PRIM_DEFAULT_IMPL caliptra_prim_pkg::ImplGeneric +`endif + +// This is to prevent AscentLint warnings in the generated +// abstract prim wrapper. These warnings occur due to the .* +// use. TODO: we may want to move these inline waivers +// into a separate, generated waiver file for consistency. +//ri lint_check_off OUTPUT_NOT_DRIVEN INPUT_NOT_READ HIER_BRANCH_NOT_READ +module caliptra_prim_flop + +#( + + parameter int Width = 1, + parameter logic [Width-1:0] ResetValue = 0 + +) ( + input clk_i, + input rst_ni, + input [Width-1:0] d_i, + output logic [Width-1:0] q_o +); + parameter caliptra_prim_pkg::impl_e Impl = `CALIPTRA_PRIM_DEFAULT_IMPL; + +if (Impl == caliptra_prim_pkg::ImplXilinx) begin : gen_xilinx + caliptra_prim_xilinx_flop #( + .ResetValue(ResetValue), + .Width(Width) + ) u_impl_xilinx ( + .* + ); +end else begin : gen_generic + `CALIPTRA_PRIM_MODULE_NAME(flop) #( + .ResetValue(ResetValue), + .Width(Width) + ) u_impl_generic ( + .* + ); +end + +endmodule +//ri lint_check_on OUTPUT_NOT_DRIVEN INPUT_NOT_READ HIER_BRANCH_NOT_READ diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_flop_2sync.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_flop_2sync.sv new file mode 100644 index 0000000..fff94f2 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_flop_2sync.sv @@ -0,0 +1,61 @@ +// Copyright lowRISC contributors. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Generic double-synchronizer flop +// This may need to be moved to caliptra_prim_generic if libraries have a specific cell +// for synchronization + +module caliptra_prim_flop_2sync #( + parameter int Width = 16, + parameter logic [Width-1:0] ResetValue = '0, + parameter bit EnablePrimCdcRand = 1 +) ( + input clk_i, + input rst_ni, + input [Width-1:0] d_i, + output logic [Width-1:0] q_o +); + + logic [Width-1:0] d_o; + logic [Width-1:0] intq; + +`ifdef SIMULATION + + caliptra_prim_cdc_rand_delay #( + .DataWidth(Width), + .Enable(EnablePrimCdcRand) + ) u_caliptra_prim_cdc_rand_delay ( + .clk_i, + .rst_ni, + .src_data_i(d_i), + .prev_data_i(intq), + .dst_data_o(d_o) + ); +`else // !`ifdef SIMULATION + logic unused_sig; + assign unused_sig = EnablePrimCdcRand; + always_comb d_o = d_i; +`endif // !`ifdef SIMULATION + + caliptra_prim_flop #( + .Width(Width), + .ResetValue(ResetValue) + ) u_sync_1 ( + .clk_i, + .rst_ni, + .d_i(d_o), + .q_o(intq) + ); + + caliptra_prim_flop #( + .Width(Width), + .ResetValue(ResetValue) + ) u_sync_2 ( + .clk_i, + .rst_ni, + .d_i(intq), + .q_o + ); + +endmodule : caliptra_prim_flop_2sync diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_flop_en.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_flop_en.sv new file mode 100644 index 0000000..0650131 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_flop_en.sv @@ -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 + +// This file is auto-generated. +// Used parser: Fallback (regex) + +`include "caliptra_prim_module_name_macros.svh" + +`ifndef CALIPTRA_PRIM_DEFAULT_IMPL + `define CALIPTRA_PRIM_DEFAULT_IMPL caliptra_prim_pkg::ImplGeneric +`endif + +// This is to prevent AscentLint warnings in the generated +// abstract prim wrapper. These warnings occur due to the .* +// use. TODO: we may want to move these inline waivers +// into a separate, generated waiver file for consistency. +//ri lint_check_off OUTPUT_NOT_DRIVEN INPUT_NOT_READ HIER_BRANCH_NOT_READ +module caliptra_prim_flop_en + +#( + + parameter int Width = 1, + parameter bit EnSecBuf = 0, + parameter logic [Width-1:0] ResetValue = 0 + +) ( + input clk_i, + input rst_ni, + input en_i, + input [Width-1:0] d_i, + output logic [Width-1:0] q_o +); + parameter caliptra_prim_pkg::impl_e Impl = `CALIPTRA_PRIM_DEFAULT_IMPL; + +if (Impl == caliptra_prim_pkg::ImplXilinx) begin : gen_xilinx + caliptra_prim_xilinx_flop_en #( + .EnSecBuf(EnSecBuf), + .ResetValue(ResetValue), + .Width(Width) + ) u_impl_xilinx ( + .* + ); +end else begin : gen_generic + `CALIPTRA_PRIM_MODULE_NAME(flop_en) #( + .EnSecBuf(EnSecBuf), + .ResetValue(ResetValue), + .Width(Width) + ) u_impl_generic ( + .* + ); +end + +endmodule +//ri lint_check_on OUTPUT_NOT_DRIVEN INPUT_NOT_READ HIER_BRANCH_NOT_READ diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_flop_macros.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_flop_macros.sv new file mode 100644 index 0000000..fa416b5 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_flop_macros.sv @@ -0,0 +1,74 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +`ifndef CALIPTRA_PRIM_FLOP_MACROS_SV +`define CALIPTRA_PRIM_FLOP_MACROS_SV + +///////////////////////////////////// +// Default Values for Macros below // +///////////////////////////////////// + +`define CALIPTRA_PRIM_FLOP_CLK clk_i +`define CALIPTRA_PRIM_FLOP_RST rst_ni +`define CALIPTRA_PRIM_FLOP_RESVAL '0 + +///////////////////// +// Register Macros // +///////////////////// + +// TODO: define other variations of register macros so that they can be used throughout all designs +// to make the code more concise. + +// Register with asynchronous reset. +`define CALIPTRA_PRIM_FLOP_A(__d, __q, __resval = `CALIPTRA_PRIM_FLOP_RESVAL, __clk = `CALIPTRA_PRIM_FLOP_CLK, __rst_n = `CALIPTRA_PRIM_FLOP_RST) \ + always_ff @(posedge __clk or negedge __rst_n) begin \ + if (!__rst_n) begin \ + __q <= __resval; \ + end else begin \ + __q <= __d; \ + end \ + end + +/////////////////////////// +// Macro for Sparse FSMs // +/////////////////////////// + +// Simulation tools typically infer FSMs and report coverage for these separately. However, tools +// like Xcelium and VCS seem to have problems inferring FSMs if the state register is not coded in +// a behavioral always_ff block in the same hierarchy. To that end, this uses a modified variant +// with a second behavioral register definition for RTL simulations so that FSMs can be inferred. +// Note that in this variant, the __q output is disconnected from caliptra_prim_sparse_fsm_flop and attached +// to the behavioral flop. An assertion is added to ensure equivalence between the +// caliptra_prim_sparse_fsm_flop output and the behavioral flop output in that case. +`define CALIPTRA_PRIM_FLOP_SPARSE_FSM(__name, __d, __q, __type, __resval = `CALIPTRA_PRIM_FLOP_RESVAL, __clk = `CALIPTRA_PRIM_FLOP_CLK, __rst_n = `CALIPTRA_PRIM_FLOP_RST, __alert_trigger_sva_en = 1) \ + `ifdef SIMULATION \ + caliptra_prim_sparse_fsm_flop #( \ + .StateEnumT(__type), \ + .Width($bits(__type)), \ + .ResetValue($bits(__type)'(__resval)), \ + .EnableAlertTriggerSVA(__alert_trigger_sva_en), \ + .CustomForceName(`CALIPTRA_PRIM_STRINGIFY(__q)) \ + ) __name ( \ + .clk_i ( __clk ), \ + .rst_ni ( __rst_n ), \ + .state_i ( __d ), \ + .state_o ( ) \ + ); \ + `CALIPTRA_PRIM_FLOP_A(__d, __q, __resval, __clk, __rst_n) \ + `CALIPTRA_ASSERT(``__name``_A, __q === ``__name``.state_o) \ + `else \ + caliptra_prim_sparse_fsm_flop #( \ + .StateEnumT(__type), \ + .Width($bits(__type)), \ + .ResetValue($bits(__type)'(__resval)), \ + .EnableAlertTriggerSVA(__alert_trigger_sva_en) \ + ) __name ( \ + .clk_i ( __clk ), \ + .rst_ni ( __rst_n ), \ + .state_i ( __d ), \ + .state_o ( __q ) \ + ); \ + `endif + +`endif // PRIM_FLOP_MACROS_SV diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_generic_and2.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_generic_and2.sv new file mode 100644 index 0000000..a692e7d --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_generic_and2.sv @@ -0,0 +1,17 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +`include "caliptra_prim_assert.sv" + +module caliptra_prim_generic_and2 #( + parameter int Width = 1 +) ( + input [Width-1:0] in0_i, + input [Width-1:0] in1_i, + output logic [Width-1:0] out_o +); + + assign out_o = in0_i & in1_i; + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_generic_buf.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_generic_buf.sv new file mode 100644 index 0000000..fef66a4 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_generic_buf.sv @@ -0,0 +1,18 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +`include "caliptra_prim_assert.sv" + +module caliptra_prim_generic_buf #( + parameter int Width = 1 +) ( + input [Width-1:0] in_i, + output logic [Width-1:0] out_o +); + + logic [Width-1:0] inv; + assign inv = ~in_i; + assign out_o = ~inv; + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_generic_clock_inv.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_generic_clock_inv.sv new file mode 100644 index 0000000..ddab9e3 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_generic_clock_inv.sv @@ -0,0 +1,34 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Clock inverter +// Varies on the process + +`include "caliptra_prim_module_name_macros.svh" + +module caliptra_prim_generic_clock_inv #( + parameter bit HasScanMode = 1'b1, + parameter bit NoFpgaBufG = 1'b0 // only used in FPGA case +) ( + input clk_i, + input scanmode_i, + output logic clk_no // Inverted +); + + if (HasScanMode) begin : gen_scan + `CALIPTRA_PRIM_MODULE_NAME(clock_mux2) #( + .NoFpgaBufG(NoFpgaBufG) + ) i_dft_tck_mux ( + .clk0_i ( ~clk_i ), + .clk1_i ( clk_i ), // bypass the inverted clock for testing + .sel_i ( scanmode_i ), + .clk_o ( clk_no ) + ); + end else begin : gen_noscan + logic unused_scanmode; + assign unused_scanmode = scanmode_i; + assign clk_no = ~clk_i; + end + +endmodule : caliptra_prim_generic_clock_inv diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_generic_clock_mux2.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_generic_clock_mux2.sv new file mode 100644 index 0000000..de4c162 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_generic_clock_mux2.sv @@ -0,0 +1,26 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +`include "caliptra_prim_assert.sv" +`include "caliptra_prim_module_name_macros.svh" + +module caliptra_prim_generic_clock_mux2 #( + parameter bit NoFpgaBufG = 1'b0 // this parameter serves no function in the generic model +) ( + input clk0_i, + input clk1_i, + input sel_i, + output logic clk_o +); + + // We model the mux with logic operations for GTECH runs. + assign clk_o = (sel_i & clk1_i) | (~sel_i & clk0_i); + + // make sure sel is never X (including during reset) + // need to use ##1 as this could break with inverted clocks that + // start with a rising edge at the beginning of the simulation. + `CALIPTRA_ASSERT(selKnown0, ##1 !$isunknown(sel_i), clk0_i, 0) + `CALIPTRA_ASSERT(selKnown1, ##1 !$isunknown(sel_i), clk1_i, 0) + +endmodule : caliptra_prim_generic_clock_mux2 diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_generic_flop.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_generic_flop.sv new file mode 100644 index 0000000..3bf1d9f --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_generic_flop.sv @@ -0,0 +1,25 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +`include "caliptra_prim_assert.sv" + +module caliptra_prim_generic_flop #( + parameter int Width = 1, + parameter logic [Width-1:0] ResetValue = 0 +) ( + input clk_i, + input rst_ni, + input [Width-1:0] d_i, + output logic [Width-1:0] q_o +); + + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + q_o <= ResetValue; + end else begin + q_o <= d_i; + end + end + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_generic_flop_en.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_generic_flop_en.sv new file mode 100644 index 0000000..2382f28 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_generic_flop_en.sv @@ -0,0 +1,39 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +`include "caliptra_prim_assert.sv" + +module caliptra_prim_generic_flop_en #( + parameter int Width = 1, + parameter bit EnSecBuf = 0, + parameter logic [Width-1:0] ResetValue = 0 +) ( + input clk_i, + input rst_ni, + input en_i, + input [Width-1:0] d_i, + output logic [Width-1:0] q_o +); + + logic en; + if (EnSecBuf) begin : gen_en_sec_buf + caliptra_prim_sec_anchor_buf #( + .Width(1) + ) u_en_buf ( + .in_i(en_i), + .out_o(en) + ); + end else begin : gen_en_no_sec_buf + assign en = en_i; + end + + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + q_o <= ResetValue; + end else if (en) begin + q_o <= d_i; + end + end + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_generic_ram_1p.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_generic_ram_1p.sv new file mode 100644 index 0000000..1c9698f --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_generic_ram_1p.sv @@ -0,0 +1,79 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Synchronous single-port SRAM model + +`include "caliptra_prim_assert.sv" + +module caliptra_prim_generic_ram_1p import caliptra_prim_ram_1p_pkg::*; #( + 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. + input ram_1p_cfg_t cfg_i +); + +// For certain synthesis experiments we compile the design with generic models to get an unmapped +// netlist (GTECH). In these synthesis experiments, we typically black-box the memory models since +// these are going to be simulated using plain RTL models in netlist simulations. This can be done +// by analyzing and elaborating the design, and then removing the memory submodules before writing +// out the verilog netlist. However, memory arrays can take a long time to elaborate, and in case +// of dual port rams they can even trigger elab errors due to multiple processes writing to the +// same memory variable concurrently. To this end, we exclude the entire logic in this module in +// these runs with the following macro. +`ifndef SYNTHESIS_MEMORY_BLACK_BOXING + + // Width must be fully divisible by DataBitsPerMask + `CALIPTRA_ASSERT_INIT(DataBitsPerMaskCheck_A, (Width % DataBitsPerMask) == 0) + + logic unused_cfg; + assign unused_cfg = ^cfg_i; + + // Width of internal write mask. Note wmask_i input into the module is always assumed + // to be the full bit mask + localparam int MaskWidth = Width / DataBitsPerMask; + + logic [Width-1:0] mem [Depth]; + logic [MaskWidth-1:0] wmask; + + for (genvar k = 0; k < MaskWidth; k++) begin : gen_wmask + assign wmask[k] = &wmask_i[k*DataBitsPerMask +: DataBitsPerMask]; + + // Ensure that all mask bits within a group have the same value for a write + `CALIPTRA_ASSERT(MaskCheck_A, req_i && write_i |-> + wmask_i[k*DataBitsPerMask +: DataBitsPerMask] inside {{DataBitsPerMask{1'b1}}, '0}, + clk_i, '0) + end + + // using always instead of always_ff to avoid 'ICPD - illegal combination of drivers' error + // thrown when using $readmemh system task to backdoor load an image + always @(posedge clk_i) begin + if (req_i) begin + if (write_i) begin + for (int i=0; i < MaskWidth; i = i + 1) begin + if (wmask[i]) begin + mem[addr_i][i*DataBitsPerMask +: DataBitsPerMask] <= + wdata_i[i*DataBitsPerMask +: DataBitsPerMask]; + end + end + end else begin + rdata_o <= mem[addr_i]; + end + end + end + + `include "caliptra_prim_util_memload.svh" +`endif +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_generic_xnor2.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_generic_xnor2.sv new file mode 100644 index 0000000..043f94f --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_generic_xnor2.sv @@ -0,0 +1,17 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +`include "caliptra_prim_assert.sv" + +module caliptra_prim_generic_xnor2 #( + parameter int Width = 1 +) ( + input [Width-1:0] in0_i, + input [Width-1:0] in1_i, + output logic [Width-1:0] out_o +); + + assign out_o = !(in0_i ^ in1_i); + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_generic_xor2.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_generic_xor2.sv new file mode 100644 index 0000000..593af3a --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_generic_xor2.sv @@ -0,0 +1,17 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +`include "caliptra_prim_assert.sv" + +module caliptra_prim_generic_xor2 #( + parameter int Width = 1 +) ( + input [Width-1:0] in0_i, + input [Width-1:0] in1_i, + output logic [Width-1:0] out_o +); + + assign out_o = in0_i ^ in1_i; + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_gf_mult.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_gf_mult.sv new file mode 100644 index 0000000..6b39a60 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_gf_mult.sv @@ -0,0 +1,184 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// This module performs a the multiplication of two operands in Galois field GF(2^Width) modulo the +// provided irreducible polynomial using a parallel Mastrovito multipler [3]. To cut long paths +// potentially occurring for large data widths, the implementation provides a parameter +// StagesPerCycle to decompose the multiplication into Width/StagesPerCycle iterative steps +// (Digit-Serial/Parallel Multiplier [4]). +// +// Note that this module is not pipelined and produces an output sample every Width/StagesPerCycle +// cycles. +// +// References: +// +// [1] Patel, "Parallel Multiplier Designs for the Galois/Counter Mode of Operation", +// https://pdfs.semanticscholar.org/1246/a9ad98dc0421ccfc945e6529c886f23e848d.pdf +// [2] Wagner, "The Laws of Cryptography: The Finite Field GF(2^8)", +// http://www.cs.utsa.edu/~wagner/laws/FFM.html +// +// [3]: Mastrovito, "VLSI Designs for Multiplication over Finite Fields GF(2^m)", +// https://link.springer.com/chapter/10.1007/3-540-51083-4_67 +// [4]: Song et al., "Efficient Finite Field Serial/Parallel Multiplication", +// https://ieeexplore.ieee.org/document/542803 + + +`include "caliptra_prim_assert.sv" + +module caliptra_prim_gf_mult #( + parameter int Width = 32, + parameter int StagesPerCycle = Width, + + // The field-generating, irreducible polynomial of degree Width. + // Can for example be a Conway polynomial, see + // http://www.math.rwth-aachen.de/~Frank.Luebeck/data/ConwayPol/CP2.html + // For Width = 33, the Conway polynomial has bits 32, 15, 9, 7, 4, 3, 0 set to one. + parameter logic[Width-1:0] IPoly = Width'(1'b1) << 15 | + Width'(1'b1) << 9 | + Width'(1'b1) << 7 | + Width'(1'b1) << 4 | + Width'(1'b1) << 3 | + Width'(1'b1) << 0, + parameter bit OutputZeroUntilAck = 1'b0 // By default, Operand A is forwarded to the output. +) ( + input clk_i, + input rst_ni, + input req_i, + input [Width-1:0] operand_a_i, + input [Width-1:0] operand_b_i, + output logic ack_pre_o, + output logic ack_o, + output logic [Width-1:0] prod_o +); + + `CALIPTRA_ASSERT_INIT(IntegerLoops_A, (Width % StagesPerCycle) == 0) + `CALIPTRA_ASSERT_INIT(StagePow2_A, $onehot(StagesPerCycle)) + + localparam int Loops = Width / StagesPerCycle; + localparam int CntWidth = (Loops == 1) ? 1 : $clog2(Loops); + + // reformat operand_b_i + logic [Loops-1:0][StagesPerCycle-1:0] reformat_data; + + // this slice of operand bits used during each loop + logic [StagesPerCycle-1:0] op_i_slice; + + // the matrix is made up of a series of GF(2^Width) * x + logic [StagesPerCycle-1:0][Width-1:0] matrix; + + // since the matrix generation is not done in one go, we must remember + // where it last left off + logic [Width-1:0] vector; + + // this variable tracks which loop we are currently operating + logic [CntWidth-1:0] cnt; + + // this variable tracks the first loop through the multiply + logic first; + + // intermediate prod held between loops + logic [Width-1:0] prod_q, prod_d; + + // intermediate output until the result becomes ready + logic [Width-1:0] out_int; + + // select current slice + assign reformat_data = operand_b_i; + assign op_i_slice = reformat_data[cnt]; + + assign first = cnt == 0; + + if (StagesPerCycle == Width) begin : gen_all_combo + + assign ack_o = 1'b1; + assign cnt = '0; + assign prod_q = '0; + assign vector = '0; + + end else begin : gen_decomposed + + // the next cycle is going to be the last one + assign ack_pre_o = int'(cnt) == (Loops - 2); + + // multiply is done + assign ack_o = int'(cnt) == (Loops - 1); + + // advance the stage count and also advance the bit position count + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + cnt <= '0; + end else if (req_i && ack_o) begin + cnt <= '0; + end else if (req_i && int'(cnt) < (Loops - 1)) begin + cnt <= cnt + 1'b1; + end + end + + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + prod_q <= '0; + vector <= '0; + end else if (ack_o) begin + prod_q <= '0; + vector <= '0; + end else if (req_i) begin + prod_q <= prod_d; + vector <= matrix[StagesPerCycle-1]; + end + end + end + + + assign matrix = first ? gen_matrix(operand_a_i, 1'b1) : gen_matrix(vector, 1'b0); + assign prod_d = prod_q ^ gf_mult(matrix, op_i_slice); + + // The output is not toggled until it is ready + if (OutputZeroUntilAck) begin : gen_out_int_zero + assign out_int = '0; + end else begin : gen_out_int_op_a + assign out_int = operand_a_i; + end + assign prod_o = ack_o ? prod_d : out_int; + + + // GF(2^Width) * x + function automatic logic [Width-1:0] gf_mult2( + logic [Width-1:0] operand + ); + logic [Width-1:0] mult_out; + mult_out = operand[Width-1] ? (operand << 1) ^ IPoly : (operand << 1); + return mult_out; + endfunction + + // Matrix generate step + function automatic logic [StagesPerCycle-1:0][Width-1:0] gen_matrix( + logic [Width-1:0] seed, + logic init + ); + logic [StagesPerCycle-1:0][Width-1:0] matrix_out; + + matrix_out[0] = init ? seed : gf_mult2(seed); + matrix_out[StagesPerCycle-1:1] = '0; + for (int i = 1; i < StagesPerCycle; i++) begin + matrix_out[i] = gf_mult2(matrix_out[i-1]); + end + return matrix_out; + endfunction + + // Galois multiply step + function automatic logic [Width-1:0] gf_mult( + logic [StagesPerCycle-1:0][Width-1:0] matrix_, + logic [StagesPerCycle-1:0] operand + ); + logic [Width-1:0] mult_out; + logic [Width-1:0] add_vector; + mult_out = '0; + for (int i = 0; i < StagesPerCycle; i++) begin + add_vector = operand[i] ? matrix_[i] : '0; + mult_out = mult_out ^ add_vector; + end + return mult_out; + endfunction // gf_mult + +endmodule // caliptra_prim_gf_mult diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_intr_hw.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_intr_hw.sv new file mode 100644 index 0000000..11546f9 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_intr_hw.sv @@ -0,0 +1,112 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Primitive block for generating CIP interrupts in peripherals. +// +// This block generates both the level-triggered wired interrupt signal intr_o and also updates +// the value of the INTR_STATE register. Together, the signal and register make up the two +// externally-visible indications of of the interrupt state. +// +// This assumes the existence of three external controller registers, which +// interface with this module caliptra_via the standard reggen reg2hw/hw2reg signals. The 3 registers are: +// - INTR_ENABLE : enables/masks the output of INTR_STATE as the intr_o signal +// - INTR_STATE : the current state of the interrupt (may be RO or W1C depending on "IntrT") +// - INTR_TEST : sw-access-only register which asserts the interrupt for testing purposes + +module caliptra_prim_intr_hw # ( + // This module can be instantiated once per interrupt field (Width == 1), or + // "bussified" with all fields of the interrupt vector (Width == $width(vec)). + parameter int unsigned Width = 1, + parameter bit FlopOutput = 1, + + // As the wired interrupt signal intr_o is a level-triggered interrupt, the upstream consumer sw + // has two options to make forward progress when this signal is asserted: + // - Mask the interrupt, by setting INTR_ENABLE = 1'b0 or masking/enabling at an upstream + // consumer. + // - Interact with the peripheral in some user-defined way that clears the signal. + // To make this user-defined interaction ergonomic from a SW-perspective, we have defined + // two common patterns for typical interrupt-triggering events, *Status* and *Event*. + // - *Event* is useful for capturing a momentary assertion of the input signal. + // - INTR_STATE/intr_o is set to '1 upon the event occurring. + // - INTR_STATE/intr_o remain set until software writes-1-to-clear to INTR_STATE. + // - *Status* captures a persistent conditional assertion that requires intervention to de-assert. + // - Until the root cause is alleviated, the interrupt output (while enabled) is continuously + // asserted. + // - INTR_STATE for *status* interrupts is RO (it simply presents the raw HW input signal). + // - If the root_cause is cleared, INTR_STATE/intr_o also clears automatically. + // More details about the interrupt type distinctions can be found in the comportability docs. + parameter IntrT = "Event" // Event or Status +) ( + // event + input clk_i, + input rst_ni, + input [Width-1:0] event_intr_i, + + // register interface + input [Width-1:0] reg2hw_intr_enable_q_i, + input [Width-1:0] reg2hw_intr_test_q_i, + input reg2hw_intr_test_qe_i, + input [Width-1:0] reg2hw_intr_state_q_i, + output hw2reg_intr_state_de_o, + output [Width-1:0] hw2reg_intr_state_d_o, + + // outgoing interrupt + output logic [Width-1:0] intr_o +); + + logic [Width-1:0] status; // incl. test + + if (IntrT == "Event") begin : g_intr_event + logic [Width-1:0] new_event; + assign new_event = + (({Width{reg2hw_intr_test_qe_i}} & reg2hw_intr_test_q_i) | event_intr_i); + assign hw2reg_intr_state_de_o = |new_event; + // for scalar interrupts, this resolves to '1' with new event + // for vector interrupts, new events are OR'd in to existing interrupt state + assign hw2reg_intr_state_d_o = new_event | reg2hw_intr_state_q_i; + + assign status = reg2hw_intr_state_q_i ; + end : g_intr_event + else if (IntrT == "Status") begin : g_intr_status + logic [Width-1:0] test_q; // Storing test. Cleared by SW + + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) test_q <= '0; + else if (reg2hw_intr_test_qe_i) test_q <= reg2hw_intr_test_q_i; + end + + // TODO: In Status type, INTR_STATE is better to be external type and RO. + assign hw2reg_intr_state_de_o = 1'b 1; // always represent the status + assign hw2reg_intr_state_d_o = event_intr_i | test_q; + + assign status = event_intr_i | test_q; + + // To make the timing same to event type, status signal does not use CSR.q, + // rather the input of the CSR. + logic unused_reg2hw; + assign unused_reg2hw = ^reg2hw_intr_state_q_i; + end : g_intr_status + + + if (FlopOutput == 1) begin : gen_flop_intr_output + // flop the interrupt output + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + intr_o <= '0; + end else begin + intr_o <= status & reg2hw_intr_enable_q_i; + end + end + + end else begin : gen_intr_passthrough_output + logic unused_clk; + logic unused_rst_n; + assign unused_clk = clk_i; + assign unused_rst_n = rst_ni; + assign intr_o = reg2hw_intr_state_q_i & reg2hw_intr_enable_q_i; + end + + `CALIPTRA_ASSERT_INIT(IntrTKind_A, IntrT inside {"Event", "Status"}) + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_lc_sender.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_lc_sender.sv new file mode 100644 index 0000000..c7552af --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_lc_sender.sv @@ -0,0 +1,68 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Multibit life cycle signal sender module. +// +// This module is instantiates a hand-picked flop cell +// for each bit in the life cycle control signal such that tools do not +// optimize the multibit encoding. + +`include "caliptra_prim_assert.sv" + +module caliptra_prim_lc_sender #( + // This flops the output if set to 1. + // In special cases where the sender is in the same clock domain as the receiver, + // this can be set to 0. However, it is recommended to leave this at 1. + parameter bit AsyncOn = 1, + // 0: reset value is lc_ctrl_pkg::Off + // 1: reset value is lc_ctrl_pkg::On + parameter bit ResetValueIsOn = 0 +) ( + input clk_i, + input rst_ni, + input lc_ctrl_pkg::lc_tx_t lc_en_i, + output lc_ctrl_pkg::lc_tx_t lc_en_o +); + + localparam lc_ctrl_pkg::lc_tx_t ResetValue = (ResetValueIsOn) ? lc_ctrl_pkg::On : + lc_ctrl_pkg::Off; + + logic [lc_ctrl_pkg::TxWidth-1:0] lc_en, lc_en_out; + assign lc_en = lc_ctrl_pkg::TxWidth'(lc_en_i); + + if (AsyncOn) begin : gen_flops + caliptra_prim_sec_anchor_flop #( + .Width(lc_ctrl_pkg::TxWidth), + .ResetValue(lc_ctrl_pkg::TxWidth'(ResetValue)) + ) u_prim_flop ( + .clk_i, + .rst_ni, + .d_i ( lc_en ), + .q_o ( lc_en_out ) + ); + end else begin : gen_no_flops + for (genvar k = 0; k < lc_ctrl_pkg::TxWidth; k++) begin : gen_bits + caliptra_prim_sec_anchor_buf u_prim_buf ( + .in_i(lc_en[k]), + .out_o(lc_en_out[k]) + ); + end + + // This unused companion logic helps remove lint errors + // for modules where clock and reset are used for assertions only + // or nothing at all. + // This logic will be removed for sythesis since it is unloaded. + lc_ctrl_pkg::lc_tx_t unused_logic; + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + unused_logic <= lc_ctrl_pkg::Off; + end else begin + unused_logic <= lc_en_i; + end + end + end + + assign lc_en_o = lc_ctrl_pkg::lc_tx_t'(lc_en_out); + +endmodule : caliptra_prim_lc_sender diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_lc_sync.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_lc_sync.sv new file mode 100644 index 0000000..d4f75f1 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_lc_sync.sv @@ -0,0 +1,116 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Double-synchronizer flop for life cycle control signals with additional +// output buffers and life-cycle specific assertions. +// +// Should be used exactly as recommended in the life cycle controller spec: +// https://docs.opentitan.org/hw/ip/lc_ctrl/doc/index.html#control-signal-propagation + +`include "caliptra_prim_assert.sv" + +module caliptra_prim_lc_sync #( + // Number of separately buffered output signals. + // The buffer cells have a don't touch constraint + // on them such that synthesis tools won't collapse + // all copies into one signal. + parameter int NumCopies = 1, + // This instantiates the synchronizer flops if set to 1. + // In special cases where the receiver is in the same clock domain as the sender, + // this can be set to 0. However, it is recommended to leave this at 1. + parameter bit AsyncOn = 1, + // 0: reset value is lc_ctrl_pkg::Off + // 1: reset value is lc_ctrl_pkg::On + parameter bit ResetValueIsOn = 0 +) ( + input clk_i, + input rst_ni, + input lc_ctrl_pkg::lc_tx_t lc_en_i, + output lc_ctrl_pkg::lc_tx_t [NumCopies-1:0] lc_en_o +); + + localparam lc_ctrl_pkg::lc_tx_t LcResetValue = (ResetValueIsOn) ? lc_ctrl_pkg::On : + lc_ctrl_pkg::Off; + + `CALIPTRA_ASSERT_INIT(NumCopiesMustBeGreaterZero_A, NumCopies > 0) + + logic [lc_ctrl_pkg::TxWidth-1:0] lc_en; + if (AsyncOn) begin : gen_flops + caliptra_prim_flop_2sync #( + .Width(lc_ctrl_pkg::TxWidth), + .ResetValue(lc_ctrl_pkg::TxWidth'(LcResetValue)) + ) u_caliptra_prim_flop_2sync ( + .clk_i, + .rst_ni, + .d_i(lc_en_i), + .q_o(lc_en) + ); + +// Note regarding SVA below: +// +// 1) Without the sampled rst_ni pre-condition, this may cause false assertion failures right after +// a reset release, since the "disable iff" condition with the rst_ni is sampled in the "observed" +// SV scheduler region after all assignments have been evaluated (see also LRM section 16.12, page +// 423). This is a simulation artifact due to reset synchronization in RTL, which releases rst_ni +// on the active clock edge. This causes the assertion to evaluate although the reset was actually +// 0 when entering this simulation cycle. +// +// 2) Similarly to 1) there can be sampling mismatches of the lc_en_i signal since that signal may +// originate from a different clock domain. I.e., in cases where the lc_en_i signal changes exactly +// at the same time that the clk_i signal rises, the SVA will not pick up that change in that clock +// cycle, whereas RTL will because SVAs sample values in the "preponed" region. To that end we make +// use of an RTL helper variable to sample the lc_en_i signal, hence ensuring that there are no +// sampling mismatches. +`ifdef CALIPTRA_INC_ASSERT + lc_ctrl_pkg::lc_tx_t lc_en_in_sva_q; + always_ff @(posedge clk_i) begin + lc_en_in_sva_q <= lc_en_i; + end + `CALIPTRA_ASSERT(OutputDelay_A, + rst_ni |-> ##3 lc_en_o == {NumCopies{$past(lc_en_in_sva_q, 2)}} || + ($past(lc_en_in_sva_q, 2) != $past(lc_en_in_sva_q, 1))) +`endif + end else begin : gen_no_flops + //VCS coverage off + // pragma coverage off + + // This unused companion logic helps remove lint errors + // for modules where clock and reset are used for assertions only + // or nothing at all. + // This logic will be removed for sythesis since it is unloaded. + lc_ctrl_pkg::lc_tx_t unused_logic; + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + unused_logic <= lc_ctrl_pkg::Off; + end else begin + unused_logic <= lc_en_i; + end + end + //VCS coverage on + // pragma coverage on + + assign lc_en = lc_en_i; + + `CALIPTRA_ASSERT(OutputDelay_A, lc_en_o == {NumCopies{lc_en_i}}) + end + + for (genvar j = 0; j < NumCopies; j++) begin : gen_buffs + logic [lc_ctrl_pkg::TxWidth-1:0] lc_en_out; + for (genvar k = 0; k < lc_ctrl_pkg::TxWidth; k++) begin : gen_bits + caliptra_prim_sec_anchor_buf u_caliptra_prim_buf ( + .in_i(lc_en[k]), + .out_o(lc_en_out[k]) + ); + end + assign lc_en_o[j] = lc_ctrl_pkg::lc_tx_t'(lc_en_out); + end + + //////////////// + // Assertions // + //////////////// + + // The outputs should be known at all times. + `CALIPTRA_ASSERT_KNOWN(OutputsKnown_A, lc_en_o) + +endmodule : caliptra_prim_lc_sync diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_lfsr.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_lfsr.sv new file mode 100644 index 0000000..ff34729 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_lfsr.sv @@ -0,0 +1,634 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// This module implements different LFSR types: +// +// 0) Galois XOR type LFSR ([1], internal XOR gates, very fast). +// Parameterizable width from 3 to 168 bits. +// Coefficients obtained from [3]. +// +// 1) Fibonacci XNOR type LFSR, parameterizable from 3 to 168 bits. +// Coefficients obtained from [3]. +// +// All flavors have an additional entropy input and lockup protection, which +// reseeds the state once it has accidentally fallen into the all-zero (XOR) or +// all-one (XNOR) state. Further, an external seed can be loaded into the LFSR +// state at runtime. If that seed is all-zero (XOR case) or all-one (XNOR case), +// the state will be reseeded in the next cycle using the lockup protection mechanism. +// Note that the external seed input takes precedence over internal state updates. +// +// All polynomials up to 34 bit in length have been verified in simulation. +// +// Refs: [1] https://en.wikipedia.org/wiki/Linear-feedback_shift_register +// [2] https://users.ece.cmu.edu/~koopman/lfsr/ +// [3] https://www.xilinx.com/support/documentation/application_notes/xapp052.pdf + +`include "caliptra_prim_assert.sv" + +module caliptra_prim_lfsr #( + // Lfsr Type, can be FIB_XNOR or GAL_XOR + parameter LfsrType = "GAL_XOR", + // Lfsr width + parameter int unsigned LfsrDw = 32, + // Derived parameter, do not override + localparam int unsigned LfsrIdxDw = $clog2(LfsrDw), + // Width of the entropy input to be XOR'd into state (lfsr_q[EntropyDw-1:0]) + parameter int unsigned EntropyDw = 8, + // Width of output tap (from lfsr_q[StateOutDw-1:0]) + parameter int unsigned StateOutDw = 8, + // Lfsr reset state, must be nonzero! + parameter logic [LfsrDw-1:0] DefaultSeed = LfsrDw'(1), + // Custom polynomial coeffs + parameter logic [LfsrDw-1:0] CustomCoeffs = '0, + // If StatePermEn is set to 1, the custom permutation specified via StatePerm is applied to the + // state output, in order to break linear shifting patterns of the LFSR. Note that this + // permutation represents a way of customizing the LFSR via a random netlist constant. This is + // different from the NonLinearOut feature below which just transforms the output non-linearly + // with a fixed function. In most cases, designers should consider enabling StatePermEn as it + // comes basically "for free" in terms of area and timing impact. NonLinearOut on the other hand + // has area and timing implications and designers should consider whether the use of that feature + // is justified. + parameter bit StatePermEn = 1'b0, + parameter logic [LfsrDw-1:0][LfsrIdxDw-1:0] StatePerm = '0, + // Enable this for DV, disable this for long LFSRs in FPV + parameter bit MaxLenSVA = 1'b1, + // Can be disabled in cases where seed and entropy + // inputs are unused in order to not distort coverage + // (the SVA will be unreachable in such cases) + parameter bit LockupSVA = 1'b1, + parameter bit ExtSeedSVA = 1'b1, + // Introduce non-linearity to lfsr output. Note, unlike StatePermEn, this feature is not "for + // free". Please double check that this feature is indeed required. Also note that this feature + // is only available for LFSRs that have a power-of-two width greater or equal 16bit. + parameter bit NonLinearOut = 1'b0 +) ( + input clk_i, + input rst_ni, + input seed_en_i, // load external seed into the state (takes precedence) + input [LfsrDw-1:0] seed_i, // external seed input + input lfsr_en_i, // enables the LFSR + input [EntropyDw-1:0] entropy_i, // additional entropy to be XOR'ed into the state + output logic [StateOutDw-1:0] state_o // (partial) LFSR state output +); + + // automatically generated with util/design/get-lfsr-coeffs.py script + localparam int unsigned LUT_OFF = 3; + localparam logic [167:0] LFSR_COEFFS [166] = + '{ 168'h6, + 168'hC, + 168'h14, + 168'h30, + 168'h60, + 168'hB8, + 168'h110, + 168'h240, + 168'h500, + 168'h829, + 168'h100D, + 168'h2015, + 168'h6000, + 168'hD008, + 168'h12000, + 168'h20400, + 168'h40023, + 168'h90000, + 168'h140000, + 168'h300000, + 168'h420000, + 168'hE10000, + 168'h1200000, + 168'h2000023, + 168'h4000013, + 168'h9000000, + 168'h14000000, + 168'h20000029, + 168'h48000000, + 168'h80200003, + 168'h100080000, + 168'h204000003, + 168'h500000000, + 168'h801000000, + 168'h100000001F, + 168'h2000000031, + 168'h4400000000, + 168'hA000140000, + 168'h12000000000, + 168'h300000C0000, + 168'h63000000000, + 168'hC0000030000, + 168'h1B0000000000, + 168'h300003000000, + 168'h420000000000, + 168'hC00000180000, + 168'h1008000000000, + 168'h3000000C00000, + 168'h6000C00000000, + 168'h9000000000000, + 168'h18003000000000, + 168'h30000000030000, + 168'h40000040000000, + 168'hC0000600000000, + 168'h102000000000000, + 168'h200004000000000, + 168'h600003000000000, + 168'hC00000000000000, + 168'h1800300000000000, + 168'h3000000000000030, + 168'h6000000000000000, + 168'hD800000000000000, + 168'h10000400000000000, + 168'h30180000000000000, + 168'h60300000000000000, + 168'h80400000000000000, + 168'h140000028000000000, + 168'h300060000000000000, + 168'h410000000000000000, + 168'h820000000001040000, + 168'h1000000800000000000, + 168'h3000600000000000000, + 168'h6018000000000000000, + 168'hC000000018000000000, + 168'h18000000600000000000, + 168'h30000600000000000000, + 168'h40200000000000000000, + 168'hC0000000060000000000, + 168'h110000000000000000000, + 168'h240000000480000000000, + 168'h600000000003000000000, + 168'h800400000000000000000, + 168'h1800000300000000000000, + 168'h3003000000000000000000, + 168'h4002000000000000000000, + 168'hC000000000000000018000, + 168'h10000000004000000000000, + 168'h30000C00000000000000000, + 168'h600000000000000000000C0, + 168'hC00C0000000000000000000, + 168'h140000000000000000000000, + 168'h200001000000000000000000, + 168'h400800000000000000000000, + 168'hA00000000001400000000000, + 168'h1040000000000000000000000, + 168'h2004000000000000000000000, + 168'h5000000000028000000000000, + 168'h8000000004000000000000000, + 168'h18600000000000000000000000, + 168'h30000000000000000C00000000, + 168'h40200000000000000000000000, + 168'hC0300000000000000000000000, + 168'h100010000000000000000000000, + 168'h200040000000000000000000000, + 168'h5000000000000000A0000000000, + 168'h800000010000000000000000000, + 168'h1860000000000000000000000000, + 168'h3003000000000000000000000000, + 168'h4010000000000000000000000000, + 168'hA000000000140000000000000000, + 168'h10080000000000000000000000000, + 168'h30000000000000000000180000000, + 168'h60018000000000000000000000000, + 168'hC0000000000000000300000000000, + 168'h140005000000000000000000000000, + 168'h200000001000000000000000000000, + 168'h404000000000000000000000000000, + 168'h810000000000000000000000000102, + 168'h1000040000000000000000000000000, + 168'h3000000000000006000000000000000, + 168'h5000000000000000000000000000000, + 168'h8000000004000000000000000000000, + 168'h18000000000000000000000000030000, + 168'h30000000030000000000000000000000, + 168'h60000000000000000000000000000000, + 168'hA0000014000000000000000000000000, + 168'h108000000000000000000000000000000, + 168'h240000000000000000000000000000000, + 168'h600000000000C00000000000000000000, + 168'h800000040000000000000000000000000, + 168'h1800000000000300000000000000000000, + 168'h2000000000000010000000000000000000, + 168'h4008000000000000000000000000000000, + 168'hC000000000000000000000000000000600, + 168'h10000080000000000000000000000000000, + 168'h30600000000000000000000000000000000, + 168'h4A400000000000000000000000000000000, + 168'h80000004000000000000000000000000000, + 168'h180000003000000000000000000000000000, + 168'h200001000000000000000000000000000000, + 168'h600006000000000000000000000000000000, + 168'hC00000000000000006000000000000000000, + 168'h1000000000000100000000000000000000000, + 168'h3000000000000006000000000000000000000, + 168'h6000000003000000000000000000000000000, + 168'h8000001000000000000000000000000000000, + 168'h1800000000000000000000000000C000000000, + 168'h20000000000001000000000000000000000000, + 168'h48000000000000000000000000000000000000, + 168'hC0000000000000006000000000000000000000, + 168'h180000000000000000000000000000000000000, + 168'h280000000000000000000000000000005000000, + 168'h60000000C000000000000000000000000000000, + 168'hC00000000000000000000000000018000000000, + 168'h1800000600000000000000000000000000000000, + 168'h3000000C00000000000000000000000000000000, + 168'h4000000080000000000000000000000000000000, + 168'hC000300000000000000000000000000000000000, + 168'h10000400000000000000000000000000000000000, + 168'h30000000000000000000006000000000000000000, + 168'h600000000000000C0000000000000000000000000, + 168'hC0060000000000000000000000000000000000000, + 168'h180000006000000000000000000000000000000000, + 168'h3000000000C0000000000000000000000000000000, + 168'h410000000000000000000000000000000000000000, + 168'hA00140000000000000000000000000000000000000 }; + + logic lockup; + logic [LfsrDw-1:0] lfsr_d, lfsr_q; + logic [LfsrDw-1:0] next_lfsr_state, coeffs; + + // Enable the randomization of DefaultSeed using DefaultSeedLocal in DV simulations. + `ifdef SIMULATION + `ifdef VERILATOR + localparam logic [LfsrDw-1:0] DefaultSeedLocal = DefaultSeed; + + `else + logic [LfsrDw-1:0] DefaultSeedLocal; + logic caliptra_prim_lfsr_use_default_seed; + + initial begin : p_randomize_default_seed + if (!$value$plusargs("caliptra_prim_lfsr_use_default_seed=%0d", caliptra_prim_lfsr_use_default_seed)) begin + // 30% of the time, use the DefaultSeed parameter; 70% of the time, randomize it. + `CALIPTRA_ASSERT_I(UseDefaultSeedRandomizeCheck_A, std::randomize(caliptra_prim_lfsr_use_default_seed) with { + caliptra_prim_lfsr_use_default_seed dist {0:/7, 1:/3};}) + end + if (caliptra_prim_lfsr_use_default_seed) begin + DefaultSeedLocal = DefaultSeed; + end else begin + // Randomize the DefaultSeedLocal ensuring its not all 0s or all 1s. + `CALIPTRA_ASSERT_I(DefaultSeedLocalRandomizeCheck_A, std::randomize(DefaultSeedLocal) with { + !(DefaultSeedLocal inside {'0, '1});}) + end + $display("%m: DefaultSeed = 0x%0h, DefaultSeedLocal = 0x%0h", DefaultSeed, DefaultSeedLocal); + end + `endif // ifdef VERILATOR + + `else + localparam logic [LfsrDw-1:0] DefaultSeedLocal = DefaultSeed; + + `endif // ifdef SIMULATION + + //////////////// + // Galois XOR // + //////////////// + if (64'(LfsrType) == 64'("GAL_XOR")) begin : gen_gal_xor + + // if custom polynomial is provided + if (CustomCoeffs > 0) begin : gen_custom + assign coeffs = CustomCoeffs[LfsrDw-1:0]; + end else begin : gen_lut + assign coeffs = LFSR_COEFFS[LfsrDw-LUT_OFF][LfsrDw-1:0]; + // check that the most significant bit of polynomial is 1 + `CALIPTRA_ASSERT_INIT(MinLfsrWidth_A, LfsrDw >= $low(LFSR_COEFFS)+LUT_OFF) + `CALIPTRA_ASSERT_INIT(MaxLfsrWidth_A, LfsrDw <= $high(LFSR_COEFFS)+LUT_OFF) + end + + // calculate next state using internal XOR feedback and entropy input + assign next_lfsr_state = LfsrDw'(entropy_i) ^ ({LfsrDw{lfsr_q[0]}} & coeffs) ^ (lfsr_q >> 1); + + // lockup condition is all-zero + assign lockup = ~(|lfsr_q); + + // check that seed is not all-zero + `CALIPTRA_ASSERT_INIT(DefaultSeedNzCheck_A, |DefaultSeedLocal) + + + //////////////////// + // Fibonacci XNOR // + //////////////////// + end else if (64'(LfsrType) == "FIB_XNOR") begin : gen_fib_xnor + + // if custom polynomial is provided + if (CustomCoeffs > 0) begin : gen_custom + assign coeffs = CustomCoeffs[LfsrDw-1:0]; + end else begin : gen_lut + assign coeffs = LFSR_COEFFS[LfsrDw-LUT_OFF][LfsrDw-1:0]; + // check that the most significant bit of polynomial is 1 + `CALIPTRA_ASSERT_INIT(MinLfsrWidth_A, LfsrDw >= $low(LFSR_COEFFS)+LUT_OFF) + `CALIPTRA_ASSERT_INIT(MaxLfsrWidth_A, LfsrDw <= $high(LFSR_COEFFS)+LUT_OFF) + end + + // calculate next state using external XNOR feedback and entropy input + assign next_lfsr_state = LfsrDw'(entropy_i) ^ {lfsr_q[LfsrDw-2:0], ~(^(lfsr_q & coeffs))}; + + // lockup condition is all-ones + assign lockup = &lfsr_q; + + // check that seed is not all-ones + `CALIPTRA_ASSERT_INIT(DefaultSeedNzCheck_A, !(&DefaultSeedLocal)) + + + ///////////// + // Unknown // + ///////////// + end else begin : gen_unknown_type + assign coeffs = '0; + assign next_lfsr_state = '0; + assign lockup = 1'b0; + `CALIPTRA_ASSERT_INIT(UnknownLfsrType_A, 0) + end + + + ////////////////// + // Shared logic // + ////////////////// + + assign lfsr_d = (seed_en_i) ? seed_i : + (lfsr_en_i && lockup) ? DefaultSeedLocal : + (lfsr_en_i) ? next_lfsr_state : + lfsr_q; + + logic [LfsrDw-1:0] sbox_out; + if (NonLinearOut) begin : gen_out_non_linear + // The "aligned" permutation ensures that adjacent bits do not go into the same SBox. It is + // different from the state permutation that can be specified via the StatePerm parameter. The + // permutation taps out 4 SBox input bits at regular stride intervals. E.g., for a 16bit + // vector, the input assignment looks as follows: + // + // SBox0: 0, 4, 8, 12 + // SBox1: 1, 5, 9, 13 + // SBox2: 2, 6, 10, 14 + // SBox3: 3, 7, 11, 15 + // + // Note that this permutation can be produced by filling the input vector into matrix columns + // and reading out the SBox inputs as matrix rows. + localparam int NumSboxes = LfsrDw / 4; + // Fill in the input vector in col-major order. + logic [3:0][NumSboxes-1:0][LfsrIdxDw-1:0] matrix_indices; + for (genvar j = 0; j < LfsrDw; j++) begin : gen_input_idx_map + assign matrix_indices[j / NumSboxes][j % NumSboxes] = j; + end + // Due to the LFSR shifting pattern, the above permutation has the property that the output of + // SBox(n) is going to be equal to SBox(n+1) in the subsequent cycle (unless the LFSR polynomial + // modifies some of the associated shifted bits via an XOR tap). + // We therefore tweak this permutation by rotating and reversing some of the assignment matrix + // columns. The rotation and reversion operations have been chosen such that this + // generalizes to all power of two widths supported by the LFSR primitive. For 16bit, this + // looks as follows: + // + // SBox0: 0, 6, 11, 14 + // SBox1: 1, 7, 10, 13 + // SBox2: 2, 4, 9, 12 + // SBox3: 3, 5, 8, 15 + // + // This can be achieved by: + // 1) down rotating the second column by NumSboxes/2 + // 2) reversing the third column + // 3) down rotating the fourth column by 1 and reversing it + // + logic [3:0][NumSboxes-1:0][LfsrIdxDw-1:0] matrix_rotrev_indices; + typedef logic [NumSboxes-1:0][LfsrIdxDw-1:0] matrix_col_t; + + // left-rotates a matrix column by the shift amount + function automatic matrix_col_t lrotcol(matrix_col_t col, integer shift); + matrix_col_t out; + for (int k = 0; k < NumSboxes; k++) begin + out[(k + shift) % NumSboxes] = col[k]; + end + return out; + endfunction : lrotcol + + // reverses a matrix column + function automatic matrix_col_t revcol(matrix_col_t col); + return {< StateOutDw) begin : gen_tieoff_unused + logic unused_sbox_out; + assign unused_sbox_out = ^sbox_out; + end + + end else begin : gen_no_state_perm + assign state_o = StateOutDw'(sbox_out); + end + + always_ff @(posedge clk_i or negedge rst_ni) begin : p_reg + if (!rst_ni) begin + lfsr_q <= DefaultSeedLocal; + end else begin + lfsr_q <= lfsr_d; + end + end + + + /////////////////////// + // shared assertions // + /////////////////////// + + `CALIPTRA_ASSERT_KNOWN(DataKnownO_A, state_o) + +// the code below is not meant to be synthesized, +// but it is intended to be used in simulation and FPV +`ifndef SYNTHESIS + function automatic logic [LfsrDw-1:0] compute_next_state(logic [LfsrDw-1:0] lfsrcoeffs, + logic [EntropyDw-1:0] entropy, + logic [LfsrDw-1:0] current_state); + logic state0; + logic [LfsrDw-1:0] next_state; + + next_state = current_state; + + // Galois XOR + if (64'(LfsrType) == 64'("GAL_XOR")) begin + if (next_state == 0) begin + next_state = DefaultSeedLocal; + end else begin + state0 = next_state[0]; + next_state = next_state >> 1; + if (state0) next_state ^= lfsrcoeffs; + next_state ^= LfsrDw'(entropy); + end + // Fibonacci XNOR + end else if (64'(LfsrType) == "FIB_XNOR") begin + if (&next_state) begin + next_state = DefaultSeedLocal; + end else begin + state0 = ~(^(next_state & lfsrcoeffs)); + next_state = next_state << 1; + next_state[0] = state0; + next_state ^= LfsrDw'(entropy); + end + end else begin + $error("unknown lfsr type"); + end + + return next_state; + endfunction : compute_next_state + + // check whether next state is computed correctly + // we shift the assertion by one clock cycle (##1) in order to avoid + // erroneous SVA triggers right after reset deassertion in cases where + // the precondition is true throughout the reset. + // this can happen since the disable_iff evaluates using unsampled values, + // meaning that the assertion may already read rst_ni == 1 on an active + // clock edge while the flops in the design have not yet changed state. + `CALIPTRA_ASSERT(NextStateCheck_A, ##1 lfsr_en_i && !seed_en_i |=> lfsr_q == + compute_next_state(coeffs, $past(entropy_i), $past(lfsr_q))) + + // Only check this if enabled. + if (StatePermEn) begin : gen_perm_check + // Check that the supplied permutation is valid. + logic [LfsrDw-1:0] lfsr_perm_test; + initial begin : p_perm_check + lfsr_perm_test = '0; + for (int k = 0; k < LfsrDw; k++) begin + lfsr_perm_test[StatePerm[k]] = 1'b1; + end + // All bit positions must be marked with 1. + `CALIPTRA_ASSERT_I(PermutationCheck_A, &lfsr_perm_test) + end + end + +`endif + + `CALIPTRA_ASSERT_INIT(InputWidth_A, LfsrDw >= EntropyDw) + `CALIPTRA_ASSERT_INIT(OutputWidth_A, LfsrDw >= StateOutDw) + + // MSB must be one in any case + `CALIPTRA_ASSERT(CoeffCheck_A, coeffs[LfsrDw-1]) + + // output check + `CALIPTRA_ASSERT_KNOWN(OutputKnown_A, state_o) + if (!StatePermEn && !NonLinearOut) begin : gen_output_sva + `CALIPTRA_ASSERT(OutputCheck_A, state_o == StateOutDw'(lfsr_q)) + end + // if no external input changes the lfsr state, a lockup must not occur (by design) + //`CALIPTRA_ASSERT(NoLockups_A, (!entropy_i) && (!seed_en_i) |=> !lockup, clk_i, !rst_ni) + `CALIPTRA_ASSERT(NoLockups_A, lfsr_en_i && !entropy_i && !seed_en_i |=> !lockup) + + // this can be disabled if unused in order to not distort coverage + if (ExtSeedSVA) begin : gen_ext_seed_sva + // check that external seed is correctly loaded into the state + // rst_ni is used directly as part of the pre-condition since the usage of rst_ni + // in disable_iff is unsampled. See #1985 for more details + `CALIPTRA_ASSERT(ExtDefaultSeedInputCheck_A, (seed_en_i && rst_ni) |=> lfsr_q == $past(seed_i)) + end + + // if the external seed mechanism is not used, + // there is theoretically no way we end up in a lockup condition + // in order to not distort coverage, this SVA can be disabled in such cases + if (LockupSVA) begin : gen_lockup_mechanism_sva + // check that a stuck LFSR is correctly reseeded + `CALIPTRA_ASSERT(LfsrLockupCheck_A, lfsr_en_i && lockup && !seed_en_i |=> !lockup) + end + + // If non-linear output requested, the LFSR width must be a power of 2 and greater than 16. + if(NonLinearOut) begin : gen_nonlinear_align_check_sva + `CALIPTRA_ASSERT_INIT(SboxByteAlign_A, 2**$clog2(LfsrDw) == LfsrDw && LfsrDw >= 16) + end + + if (MaxLenSVA) begin : gen_max_len_sva +`ifndef SYNTHESIS + // the code below is a workaround to enable long sequences to be checked. + // some simulators do not support SVA sequences longer than 2**32-1. + logic [LfsrDw-1:0] cnt_d, cnt_q; + logic perturbed_d, perturbed_q; + logic [LfsrDw-1:0] cmp_val; + + assign cmp_val = {{(LfsrDw-1){1'b1}}, 1'b0}; // 2**LfsrDw-2 + assign cnt_d = (lfsr_en_i && lockup) ? '0 : + (lfsr_en_i && (cnt_q == cmp_val)) ? '0 : + (lfsr_en_i) ? cnt_q + 1'b1 : + cnt_q; + + assign perturbed_d = perturbed_q | (|entropy_i) | seed_en_i; + + always_ff @(posedge clk_i or negedge rst_ni) begin : p_max_len + if (!rst_ni) begin + cnt_q <= '0; + perturbed_q <= 1'b0; + end else begin + cnt_q <= cnt_d; + perturbed_q <= perturbed_d; + end + end + + `CALIPTRA_ASSERT(MaximalLengthCheck0_A, cnt_q == 0 |-> lfsr_q == DefaultSeedLocal, + clk_i, !rst_ni || perturbed_q) + `CALIPTRA_ASSERT(MaximalLengthCheck1_A, cnt_q != 0 |-> lfsr_q != DefaultSeedLocal, + clk_i, !rst_ni || perturbed_q) +`endif + end + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_max_tree.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_max_tree.sv new file mode 100644 index 0000000..d63f043 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_max_tree.sv @@ -0,0 +1,152 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// The module implements a binary tree to find the maximal entry. the solution +// has O(N) area and O(log(N)) delay complexity, and thus scales well with +// many input sources. +// +// Note that only input values marked as "valid" are respected in the maximum computation. +// If there are multiple valid inputs with the same value, the tree will always select the input +// with the smallest index. +// +// If none of the input values are valid, the output index will be 0 and the output value will +// be equal to the input value at index 0. + + +`include "caliptra_prim_assert.sv" + +module caliptra_prim_max_tree #( + parameter int NumSrc = 32, + parameter int Width = 8, + // Derived parameters + localparam int SrcWidth = $clog2(NumSrc) +) ( + // The module is combinational - the clock and reset are only used for assertions. + input clk_i, + input rst_ni, + input [NumSrc-1:0][Width-1:0] values_i, // Input values + input [NumSrc-1:0] valid_i, // Input valid bits + output logic [Width-1:0] max_value_o, // Maximum value + output logic [SrcWidth-1:0] max_idx_o, // Index of the maximum value + output logic max_valid_o // Whether any of the inputs is valid +); + + /////////////////////// + // Binary tree logic // + /////////////////////// + + // This only works with 2 or more sources. + `CALIPTRA_ASSERT_INIT(NumSources_A, NumSrc >= 2) + + // Align to powers of 2 for simplicity. + // A full binary tree with N levels has 2**N + 2**N-1 nodes. + localparam int NumLevels = $clog2(NumSrc); + logic [2**(NumLevels+1)-2:0] vld_tree; + logic [2**(NumLevels+1)-2:0][SrcWidth-1:0] idx_tree; + logic [2**(NumLevels+1)-2:0][Width-1:0] max_tree; + + for (genvar level = 0; level < NumLevels+1; level++) begin : gen_tree + // + // level+1 C0 C1 <- "Base1" points to the first node on "level+1", + // \ / these nodes are the children of the nodes one level below + // level Pa <- "Base0", points to the first node on "level", + // these nodes are the parents of the nodes one level above + // + // hence we have the following indices for the paPa, C0, C1 nodes: + // Pa = 2**level - 1 + offset = Base0 + offset + // C0 = 2**(level+1) - 1 + 2*offset = Base1 + 2*offset + // C1 = 2**(level+1) - 1 + 2*offset + 1 = Base1 + 2*offset + 1 + // + localparam int Base0 = (2**level)-1; + localparam int Base1 = (2**(level+1))-1; + + for (genvar offset = 0; offset < 2**level; offset++) begin : gen_level + localparam int Pa = Base0 + offset; + localparam int C0 = Base1 + 2*offset; + localparam int C1 = Base1 + 2*offset + 1; + + // This assigns the input values, their corresponding IDs and valid signals to the tree leafs. + if (level == NumLevels) begin : gen_leafs + if (offset < NumSrc) begin : gen_assign + assign vld_tree[Pa] = valid_i[offset]; + assign idx_tree[Pa] = offset; + assign max_tree[Pa] = values_i[offset]; + end else begin : gen_tie_off + assign vld_tree[Pa] = '0; + assign idx_tree[Pa] = '0; + assign max_tree[Pa] = '0; + end + // This creates the node assignments. + end else begin : gen_nodes + logic sel; // Local helper variable + // In case only one of the parents is valid, forward that one + // In case both parents are valid, forward the one with higher value + assign sel = (~vld_tree[C0] & vld_tree[C1]) | + (vld_tree[C0] & vld_tree[C1] & logic'(max_tree[C1] > max_tree[C0])); + // Forwarding muxes + // Note: these ternaries have triggered a synthesis bug in Vivado versions older + // than 2020.2. If the problem resurfaces again, have a look at issue #1408. + assign vld_tree[Pa] = (sel) ? vld_tree[C1] : vld_tree[C0]; + assign idx_tree[Pa] = (sel) ? idx_tree[C1] : idx_tree[C0]; + assign max_tree[Pa] = (sel) ? max_tree[C1] : max_tree[C0]; + end + end : gen_level + end : gen_tree + + + // The results can be found at the tree root + assign max_valid_o = vld_tree[0]; + assign max_idx_o = idx_tree[0]; + assign max_value_o = max_tree[0]; + + //////////////// + // Assertions // + //////////////// + +`ifdef CALIPTRA_INC_ASSERT + //VCS coverage off + // pragma coverage off + + // Helper functions for assertions below. + function automatic logic [Width-1:0] max_value (input logic [NumSrc-1:0][Width-1:0] values_i, + input logic [NumSrc-1:0] valid_i); + logic [Width-1:0] value = '0; + for (int k = 0; k < NumSrc; k++) begin + if (valid_i[k] && values_i[k] > value) begin + value = values_i[k]; + end + end + return value; + endfunction : max_value + + function automatic logic [SrcWidth-1:0] max_idx (input logic [NumSrc-1:0][Width-1:0] values_i, + input logic [NumSrc-1:0] valid_i); + logic [Width-1:0] value = '0; + logic [SrcWidth-1:0] idx = '0; + for (int k = NumSrc-1; k >= 0; k--) begin + if (valid_i[k] && values_i[k] >= value) begin + value = values_i[k]; + idx = k; + end + end + return idx; + endfunction : max_idx + + logic [Width-1:0] max_value_exp; + logic [SrcWidth-1:0] max_idx_exp; + assign max_value_exp = max_value(values_i, valid_i); + assign max_idx_exp = max_idx(values_i, valid_i); + //VCS coverage on + // pragma coverage on + + // TODO(10588): Below syntax is not supported in xcelium, track xcelium cases #46591452. + // `CALIPTRA_ASSERT(ValidInImpliesValidOut_A, |valid_i <-> max_valid_o) + `CALIPTRA_ASSERT(ValidInImpliesValidOut_A, |valid_i === max_valid_o) + `CALIPTRA_ASSERT(MaxComputation_A, max_valid_o |-> max_value_o == max_value_exp) + `CALIPTRA_ASSERT(MaxComputationInvalid_A, !max_valid_o |-> max_value_o == values_i[0]) + `CALIPTRA_ASSERT(MaxIndexComputation_A, max_valid_o |-> max_idx_o == max_idx_exp) + `CALIPTRA_ASSERT(MaxIndexComputationInvalid_A, !max_valid_o |-> max_idx_o == '0) +`endif + +endmodule : caliptra_prim_max_tree diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_module_name_macros.svh b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_module_name_macros.svh new file mode 100644 index 0000000..47437c8 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_module_name_macros.svh @@ -0,0 +1,43 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +// + +// This file defines macros for generating module names in the caliptra_prim package. + +`ifndef caliptra_prim_module_name_macros_SVH +`define caliptra_prim_module_name_macros_SVH + +// Defines the default prefix for caliptra_prim generic modules. +// This can be overridden by defining CALIPTRA_PRIM_MODULE_PREFIX +// before including this file. If not defined, it defaults to +// 'caliptra_prim_generic'. The prim generic implementations can be found under +// ${CALIPTRA_ROOT}/src/caliptra_prim_generic/rtl +// +// For production use it is recommended to implement the technology-specific +// modules replacing the generic ones. Use the ${CALIPTRA_PRIM_ROOT} envar +// to point to the technology-specific implementation root directory. +`ifndef CALIPTRA_PRIM_MODULE_PREFIX +`define CALIPTRA_PRIM_MODULE_PREFIX caliptra_prim_generic +`endif // CALIPTRA_PRIM_MODULE_PREFIX + +// Macro to generate the full module name for caliptra_prim modules. +// Usage: `CALIPTRA_PRIM_MODULE_NAME(module_name) +// This will result in caliptra_prim_generic_module_name +// if CALIPTRA_PRIM_MODULE_PREFIX is not defined. +`define CALIPTRA_PRIM_MODULE_NAME_EXPAND(prefix, name) prefix``_``name + +`define CALIPTRA_PRIM_MODULE_NAME(__name) \ + `CALIPTRA_PRIM_MODULE_NAME_EXPAND(`CALIPTRA_PRIM_MODULE_PREFIX, __name) + +`endif // caliptra_prim_module_name_macros_SVH diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_mubi4_dec.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_mubi4_dec.sv new file mode 100644 index 0000000..bf7370d --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_mubi4_dec.sv @@ -0,0 +1,48 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// ------------------- W A R N I N G: A U T O - G E N E R A T E D C O D E !! -------------------// +// PLEASE DO NOT HAND-EDIT THIS FILE. IT HAS BEEN AUTO-GENERATED WITH THE FOLLOWING COMMAND: +// +// util/design/gen-mubi.py +// +// Decoder for multibit control signals with additional input buffers. + +`include "caliptra_prim_assert.sv" + +module caliptra_prim_mubi4_dec + import caliptra_prim_mubi_pkg::*; +#( + parameter bit TestTrue = 1, + parameter bit TestStrict = 1 +) ( + input mubi4_t mubi_i, + output logic mubi_dec_o +); + +logic [MuBi4Width-1:0] mubi, mubi_out; +assign mubi = MuBi4Width'(mubi_i); + +// The buffer cells have a don't touch constraint on them +// such that synthesis tools won't collapse them +for (genvar k = 0; k < MuBi4Width; k++) begin : gen_bits + caliptra_prim_buf u_caliptra_prim_buf ( + .in_i ( mubi[k] ), + .out_o ( mubi_out[k] ) + ); +end + +if (TestTrue && TestStrict) begin : gen_test_true_strict + assign mubi_dec_o = mubi4_test_true_strict(mubi4_t'(mubi_out)); +end else if (TestTrue && !TestStrict) begin : gen_test_true_loose + assign mubi_dec_o = mubi4_test_true_loose(mubi4_t'(mubi_out)); +end else if (!TestTrue && TestStrict) begin : gen_test_false_strict + assign mubi_dec_o = mubi4_test_false_strict(mubi4_t'(mubi_out)); +end else if (!TestTrue && !TestStrict) begin : gen_test_false_loose + assign mubi_dec_o = mubi4_test_false_loose(mubi4_t'(mubi_out)); +end else begin : gen_unknown_config + `CALIPTRA_ASSERT_INIT(UnknownConfig_A, 0) +end + +endmodule : caliptra_prim_mubi4_dec diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_mubi4_sender.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_mubi4_sender.sv new file mode 100644 index 0000000..4b383cc --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_mubi4_sender.sv @@ -0,0 +1,94 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// ------------------- W A R N I N G: A U T O - G E N E R A T E D C O D E !! -------------------// +// PLEASE DO NOT HAND-EDIT THIS FILE. IT HAS BEEN AUTO-GENERATED WITH THE FOLLOWING COMMAND: +// +// util/design/gen-mubi.py +// +// Multibit sender module. This module is instantiates a hand-picked flop cell for each bit in the +// multibit signal such that tools do not optimize the multibit encoding. + +`include "caliptra_prim_assert.sv" + +module caliptra_prim_mubi4_sender + import caliptra_prim_mubi_pkg::*; +#( + // This flops the output if set to 1. + // In special cases where the sender is in the same clock domain as the receiver, + // this can be set to 0. However, it is recommended to leave this at 1. + parameter bit AsyncOn = 1, + // Enable anchor buffer + parameter bit EnSecBuf = 0, + // Reset value for the sender flops + parameter mubi4_t ResetValue = MuBi4False +) ( + input clk_i, + input rst_ni, + input mubi4_t mubi_i, + output mubi4_t mubi_o +); + + logic [MuBi4Width-1:0] mubi, mubi_int, mubi_out; + assign mubi = MuBi4Width'(mubi_i); + + // first generation block decides whether a flop should be present + if (AsyncOn) begin : gen_flops + caliptra_prim_flop #( + .Width(MuBi4Width), + .ResetValue(MuBi4Width'(ResetValue)) + ) u_prim_flop ( + .clk_i, + .rst_ni, + .d_i ( mubi ), + .q_o ( mubi_int ) + ); + end else begin : gen_no_flops + assign mubi_int = mubi; + + // This unused companion logic helps remove lint errors + // for modules where clock and reset are used for assertions only + // This logic will be removed for sythesis since it is unloaded. + mubi4_t unused_logic; + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + unused_logic <= MuBi4False; + end else begin + unused_logic <= mubi_i; + end + end + end + + // second generation block determines output buffer type + // 1. If EnSecBuf -> always leads to a sec buffer regardless of first block + // 2. If not EnSecBuf and not AsyncOn -> use normal buffer + // 3. If not EnSecBuf and AsyncOn -> feed through + if (EnSecBuf) begin : gen_sec_buf + caliptra_prim_sec_anchor_buf #( + .Width(4) + ) u_prim_sec_buf ( + .in_i(mubi_int), + .out_o(mubi_out) + ); + end else if (!AsyncOn) begin : gen_prim_buf + caliptra_prim_buf #( + .Width(4) + ) u_prim_buf ( + .in_i(mubi_int), + .out_o(mubi_out) + ); + end else begin : gen_feedthru + assign mubi_out = mubi_int; + end + + assign mubi_o = mubi4_t'(mubi_out); + + //////////////// + // Assertions // + //////////////// + + // The outputs should be known at all times. + `CALIPTRA_ASSERT_KNOWN(OutputsKnown_A, mubi_o) + +endmodule : caliptra_prim_mubi4_sender diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_mubi4_sync.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_mubi4_sync.sv new file mode 100644 index 0000000..e32da64 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_mubi4_sync.sv @@ -0,0 +1,179 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// ------------------- W A R N I N G: A U T O - G E N E R A T E D C O D E !! -------------------// +// PLEASE DO NOT HAND-EDIT THIS FILE. IT HAS BEEN AUTO-GENERATED WITH THE FOLLOWING COMMAND: +// +// util/design/gen-mubi.py +// +// Double-synchronizer flop for multibit signals with additional output buffers. + +`include "caliptra_prim_assert.sv" +`include "caliptra_prim_module_name_macros.svh" + +module caliptra_prim_mubi4_sync + import caliptra_prim_mubi_pkg::*; +#( + // Number of separately buffered output signals. + // The buffer cells have a don't touch constraint + // on them such that synthesis tools won't collapse + // all copies into one signal. + parameter int NumCopies = 1, + // This instantiates the synchronizer flops if set to 1. + // In special cases where the receiver is in the same clock domain as the sender, + // this can be set to 0. However, it is recommended to leave this at 1. + parameter bit AsyncOn = 1, + // This controls whether the mubi module institutes stability checks when + // AsyncOn is set. If stability checks are on, a 3rd stage of storage is + // added after the synchronizers and the outputs only updated if the 3rd + // stage and sychronizer agree. If they do not agree, the ResetValue is + // output instead. + parameter bit StabilityCheck = 0, + // Reset value for the sync flops + parameter mubi4_t ResetValue = MuBi4False +) ( + input clk_i, + input rst_ni, + input mubi4_t mubi_i, + output mubi4_t [NumCopies-1:0] mubi_o +); + + `CALIPTRA_ASSERT_INIT(NumCopiesMustBeGreaterZero_A, NumCopies > 0) + + logic [MuBi4Width-1:0] mubi; + if (AsyncOn) begin : gen_flops + logic [MuBi4Width-1:0] mubi_sync; + caliptra_prim_flop_2sync #( + .Width(MuBi4Width), + .ResetValue(MuBi4Width'(ResetValue)) + ) u_caliptra_prim_flop_2sync ( + .clk_i, + .rst_ni, + .d_i(MuBi4Width'(mubi_i)), + .q_o(mubi_sync) + ); + + if (StabilityCheck) begin : gen_stable_chks + logic [MuBi4Width-1:0] mubi_q; + caliptra_prim_flop #( + .Width(MuBi4Width), + .ResetValue(MuBi4Width'(ResetValue)) + ) u_caliptra_prim_flop_3rd_stage ( + .clk_i, + .rst_ni, + .d_i(mubi_sync), + .q_o(mubi_q) + ); + + logic [MuBi4Width-1:0] sig_unstable; + `CALIPTRA_PRIM_MODULE_NAME(xor2) #( + .Width(MuBi4Width) + ) u_mubi_xor ( + .in0_i(mubi_sync), + .in1_i(mubi_q), + .out_o(sig_unstable) + ); + + logic [MuBi4Width-1:0] reset_value; + assign reset_value = ResetValue; + + for (genvar k = 0; k < MuBi4Width; k++) begin : gen_bufs_muxes + logic [MuBi4Width-1:0] sig_unstable_buf; + + // each mux gets its own buffered output, this ensures the OR-ing + // cannot be defeated in one place. + caliptra_prim_sec_anchor_buf #( + .Width(MuBi4Width) + ) u_sig_unstable_buf ( + .in_i(sig_unstable), + .out_o(sig_unstable_buf) + ); + + // if any xor indicates signal is unstable, output the reset + // value. note that the input and output signals of this mux + // are driven/read by constrained primitive cells (regs, buffers), + // hence this mux can be implemented behaviorally. + assign mubi[k] = (|sig_unstable_buf) ? reset_value[k] : mubi_q[k]; + end + +// Note regarding SVAs below: +// +// 1) Without the sampled rst_ni pre-condition, this may cause false assertion failures right after +// a reset release, since the "disable iff" condition with the rst_ni is sampled in the "observed" +// SV scheduler region after all assignments have been evaluated (see also LRM section 16.12, page +// 423). This is a simulation artifact due to reset synchronization in RTL, which releases rst_ni +// on the active clock edge. This causes the assertion to evaluate although the reset was actually +// 0 when entering this simulation cycle. +// +// 2) Similarly to 1) there can be sampling mismatches of the lc_en_i signal since that signal may +// originate from a different clock domain. I.e., in cases where the lc_en_i signal changes exactly +// at the same time that the clk_i signal rises, the SVA will not pick up that change in that clock +// cycle, whereas RTL will because SVAs sample values in the "preponed" region. To that end we make +// use of an RTL helper variable to sample the lc_en_i signal, hence ensuring that there are no +// sampling mismatches. +`ifdef CALIPTRA_INC_ASSERT + mubi4_t mubi_in_sva_q; + always_ff @(posedge clk_i) begin + mubi_in_sva_q <= mubi_i; + end + `CALIPTRA_ASSERT(OutputIfUnstable_A, sig_unstable |-> mubi_o == {NumCopies{reset_value}}) + `CALIPTRA_ASSERT(OutputDelay_A, + rst_ni |-> ##[3:4] sig_unstable || mubi_o == {NumCopies{$past(mubi_in_sva_q, 2)}}) +`endif + end else begin : gen_no_stable_chks + assign mubi = mubi_sync; +`ifdef CALIPTRA_INC_ASSERT + mubi4_t mubi_in_sva_q; + always_ff @(posedge clk_i) begin + mubi_in_sva_q <= mubi_i; + end + `CALIPTRA_ASSERT(OutputDelay_A, + rst_ni |-> ##3 (mubi_o == {NumCopies{$past(mubi_in_sva_q, 2)}} || + $past(mubi_in_sva_q, 2) != $past(mubi_in_sva_q, 1))) +`endif + end + end else begin : gen_no_flops + + //VCS coverage off + // pragma coverage off + + // This unused companion logic helps remove lint errors + // for modules where clock and reset are used for assertions only + // This logic will be removed for synthesis since it is unloaded. + mubi4_t unused_logic; + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + unused_logic <= MuBi4False; + end else begin + unused_logic <= mubi_i; + end + end + + //VCS coverage on + // pragma coverage on + + assign mubi = MuBi4Width'(mubi_i); + + `CALIPTRA_ASSERT(OutputDelay_A, mubi_o == {NumCopies{mubi_i}}) + end + + for (genvar j = 0; j < NumCopies; j++) begin : gen_buffs + logic [MuBi4Width-1:0] mubi_out; + for (genvar k = 0; k < MuBi4Width; k++) begin : gen_bits + caliptra_prim_buf u_caliptra_prim_buf ( + .in_i(mubi[k]), + .out_o(mubi_out[k]) + ); + end + assign mubi_o[j] = mubi4_t'(mubi_out); + end + + //////////////// + // Assertions // + //////////////// + + // The outputs should be known at all times. + `CALIPTRA_ASSERT_KNOWN(OutputsKnown_A, mubi_o) + +endmodule : caliptra_prim_mubi4_sync diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_mubi8_sender.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_mubi8_sender.sv new file mode 100644 index 0000000..28e9445 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_mubi8_sender.sv @@ -0,0 +1,94 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// ------------------- W A R N I N G: A U T O - G E N E R A T E D C O D E !! -------------------// +// PLEASE DO NOT HAND-EDIT THIS FILE. IT HAS BEEN AUTO-GENERATED WITH THE FOLLOWING COMMAND: +// +// util/design/gen-mubi.py +// +// Multibit sender module. This module is instantiates a hand-picked flop cell for each bit in the +// multibit signal such that tools do not optimize the multibit encoding. + +`include "caliptra_prim_assert.sv" + +module caliptra_prim_mubi8_sender + import caliptra_prim_mubi_pkg::*; +#( + // This flops the output if set to 1. + // In special cases where the sender is in the same clock domain as the receiver, + // this can be set to 0. However, it is recommended to leave this at 1. + parameter bit AsyncOn = 1, + // Enable anchor buffer + parameter bit EnSecBuf = 0, + // Reset value for the sender flops + parameter mubi8_t ResetValue = MuBi8False +) ( + input clk_i, + input rst_ni, + input mubi8_t mubi_i, + output mubi8_t mubi_o +); + + logic [MuBi8Width-1:0] mubi, mubi_int, mubi_out; + assign mubi = MuBi8Width'(mubi_i); + + // first generation block decides whether a flop should be present + if (AsyncOn) begin : gen_flops + caliptra_prim_flop #( + .Width(MuBi8Width), + .ResetValue(MuBi8Width'(ResetValue)) + ) u_prim_flop ( + .clk_i, + .rst_ni, + .d_i ( mubi ), + .q_o ( mubi_int ) + ); + end else begin : gen_no_flops + assign mubi_int = mubi; + + // This unused companion logic helps remove lint errors + // for modules where clock and reset are used for assertions only + // This logic will be removed for sythesis since it is unloaded. + mubi8_t unused_logic; + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + unused_logic <= MuBi8False; + end else begin + unused_logic <= mubi_i; + end + end + end + + // second generation block determines output buffer type + // 1. If EnSecBuf -> always leads to a sec buffer regardless of first block + // 2. If not EnSecBuf and not AsyncOn -> use normal buffer + // 3. If not EnSecBuf and AsyncOn -> feed through + if (EnSecBuf) begin : gen_sec_buf + caliptra_prim_sec_anchor_buf #( + .Width(8) + ) u_prim_sec_buf ( + .in_i(mubi_int), + .out_o(mubi_out) + ); + end else if (!AsyncOn) begin : gen_prim_buf + caliptra_prim_buf #( + .Width(8) + ) u_prim_buf ( + .in_i(mubi_int), + .out_o(mubi_out) + ); + end else begin : gen_feedthru + assign mubi_out = mubi_int; + end + + assign mubi_o = mubi8_t'(mubi_out); + + //////////////// + // Assertions // + //////////////// + + // The outputs should be known at all times. + `CALIPTRA_ASSERT_KNOWN(OutputsKnown_A, mubi_o) + +endmodule : caliptra_prim_mubi8_sender diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_mubi8_sync.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_mubi8_sync.sv new file mode 100644 index 0000000..442f539 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_mubi8_sync.sv @@ -0,0 +1,179 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// ------------------- W A R N I N G: A U T O - G E N E R A T E D C O D E !! -------------------// +// PLEASE DO NOT HAND-EDIT THIS FILE. IT HAS BEEN AUTO-GENERATED WITH THE FOLLOWING COMMAND: +// +// util/design/gen-mubi.py +// +// Double-synchronizer flop for multibit signals with additional output buffers. + +`include "caliptra_prim_assert.sv" +`include "caliptra_prim_module_name_macros.svh" + +module caliptra_prim_mubi8_sync + import caliptra_prim_mubi_pkg::*; +#( + // Number of separately buffered output signals. + // The buffer cells have a don't touch constraint + // on them such that synthesis tools won't collapse + // all copies into one signal. + parameter int NumCopies = 1, + // This instantiates the synchronizer flops if set to 1. + // In special cases where the receiver is in the same clock domain as the sender, + // this can be set to 0. However, it is recommended to leave this at 1. + parameter bit AsyncOn = 1, + // This controls whether the mubi module institutes stability checks when + // AsyncOn is set. If stability checks are on, a 3rd stage of storage is + // added after the synchronizers and the outputs only updated if the 3rd + // stage and sychronizer agree. If they do not agree, the ResetValue is + // output instead. + parameter bit StabilityCheck = 0, + // Reset value for the sync flops + parameter mubi8_t ResetValue = MuBi8False +) ( + input clk_i, + input rst_ni, + input mubi8_t mubi_i, + output mubi8_t [NumCopies-1:0] mubi_o +); + + `CALIPTRA_ASSERT_INIT(NumCopiesMustBeGreaterZero_A, NumCopies > 0) + + logic [MuBi8Width-1:0] mubi; + if (AsyncOn) begin : gen_flops + logic [MuBi8Width-1:0] mubi_sync; + caliptra_prim_flop_2sync #( + .Width(MuBi8Width), + .ResetValue(MuBi8Width'(ResetValue)) + ) u_caliptra_prim_flop_2sync ( + .clk_i, + .rst_ni, + .d_i(MuBi8Width'(mubi_i)), + .q_o(mubi_sync) + ); + + if (StabilityCheck) begin : gen_stable_chks + logic [MuBi8Width-1:0] mubi_q; + caliptra_prim_flop #( + .Width(MuBi8Width), + .ResetValue(MuBi8Width'(ResetValue)) + ) u_caliptra_prim_flop_3rd_stage ( + .clk_i, + .rst_ni, + .d_i(mubi_sync), + .q_o(mubi_q) + ); + + logic [MuBi8Width-1:0] sig_unstable; + `CALIPTRA_PRIM_MODULE_NAME(xor2) #( + .Width(MuBi8Width) + ) u_mubi_xor ( + .in0_i(mubi_sync), + .in1_i(mubi_q), + .out_o(sig_unstable) + ); + + logic [MuBi8Width-1:0] reset_value; + assign reset_value = ResetValue; + + for (genvar k = 0; k < MuBi8Width; k++) begin : gen_bufs_muxes + logic [MuBi8Width-1:0] sig_unstable_buf; + + // each mux gets its own buffered output, this ensures the OR-ing + // cannot be defeated in one place. + caliptra_prim_sec_anchor_buf #( + .Width(MuBi8Width) + ) u_sig_unstable_buf ( + .in_i(sig_unstable), + .out_o(sig_unstable_buf) + ); + + // if any xor indicates signal is unstable, output the reset + // value. note that the input and output signals of this mux + // are driven/read by constrained primitive cells (regs, buffers), + // hence this mux can be implemented behaviorally. + assign mubi[k] = (|sig_unstable_buf) ? reset_value[k] : mubi_q[k]; + end + +// Note regarding SVAs below: +// +// 1) Without the sampled rst_ni pre-condition, this may cause false assertion failures right after +// a reset release, since the "disable iff" condition with the rst_ni is sampled in the "observed" +// SV scheduler region after all assignments have been evaluated (see also LRM section 16.12, page +// 423). This is a simulation artifact due to reset synchronization in RTL, which releases rst_ni +// on the active clock edge. This causes the assertion to evaluate although the reset was actually +// 0 when entering this simulation cycle. +// +// 2) Similarly to 1) there can be sampling mismatches of the lc_en_i signal since that signal may +// originate from a different clock domain. I.e., in cases where the lc_en_i signal changes exactly +// at the same time that the clk_i signal rises, the SVA will not pick up that change in that clock +// cycle, whereas RTL will because SVAs sample values in the "preponed" region. To that end we make +// use of an RTL helper variable to sample the lc_en_i signal, hence ensuring that there are no +// sampling mismatches. +`ifdef CALIPTRA_INC_ASSERT + mubi8_t mubi_in_sva_q; + always_ff @(posedge clk_i) begin + mubi_in_sva_q <= mubi_i; + end + `CALIPTRA_ASSERT(OutputIfUnstable_A, sig_unstable |-> mubi_o == {NumCopies{reset_value}}) + `CALIPTRA_ASSERT(OutputDelay_A, + rst_ni |-> ##[3:4] sig_unstable || mubi_o == {NumCopies{$past(mubi_in_sva_q, 2)}}) +`endif + end else begin : gen_no_stable_chks + assign mubi = mubi_sync; +`ifdef CALIPTRA_INC_ASSERT + mubi8_t mubi_in_sva_q; + always_ff @(posedge clk_i) begin + mubi_in_sva_q <= mubi_i; + end + `CALIPTRA_ASSERT(OutputDelay_A, + rst_ni |-> ##3 (mubi_o == {NumCopies{$past(mubi_in_sva_q, 2)}} || + $past(mubi_in_sva_q, 2) != $past(mubi_in_sva_q, 1))) +`endif + end + end else begin : gen_no_flops + + //VCS coverage off + // pragma coverage off + + // This unused companion logic helps remove lint errors + // for modules where clock and reset are used for assertions only + // This logic will be removed for synthesis since it is unloaded. + mubi8_t unused_logic; + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + unused_logic <= MuBi8False; + end else begin + unused_logic <= mubi_i; + end + end + + //VCS coverage on + // pragma coverage on + + assign mubi = MuBi8Width'(mubi_i); + + `CALIPTRA_ASSERT(OutputDelay_A, mubi_o == {NumCopies{mubi_i}}) + end + + for (genvar j = 0; j < NumCopies; j++) begin : gen_buffs + logic [MuBi8Width-1:0] mubi_out; + for (genvar k = 0; k < MuBi8Width; k++) begin : gen_bits + caliptra_prim_buf u_caliptra_prim_buf ( + .in_i(mubi[k]), + .out_o(mubi_out[k]) + ); + end + assign mubi_o[j] = mubi8_t'(mubi_out); + end + + //////////////// + // Assertions // + //////////////// + + // The outputs should be known at all times. + `CALIPTRA_ASSERT_KNOWN(OutputsKnown_A, mubi_o) + +endmodule : caliptra_prim_mubi8_sync diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_mubi_pkg.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_mubi_pkg.sv new file mode 100644 index 0000000..988aa47 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_mubi_pkg.sv @@ -0,0 +1,550 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// ------------------- W A R N I N G: A U T O - G E N E R A T E D C O D E !! -------------------// +// PLEASE DO NOT HAND-EDIT THIS FILE. IT HAS BEEN AUTO-GENERATED WITH THE FOLLOWING COMMAND: +// +// util/design/gen-mubi.py +// +// This package defines common multibit signal types, active high and active low values and +// the corresponding functions to test whether the values are set or not. + +`include "caliptra_prim_assert.sv" + +package caliptra_prim_mubi_pkg; + + ////////////////////////////////////////////// + // 4 Bit Multibit Type and Functions // + ////////////////////////////////////////////// + + parameter int MuBi4Width = 4; + /* + typedef enum logic [MuBi4Width-1:0] { + MuBi4True = 4'h6, // enabled + MuBi4False = 4'h9 // disabled + } mubi4_t; + */ + typedef logic [MuBi4Width-1:0] mubi4_t; + localparam mubi4_t MuBi4True = 4'h6; + localparam mubi4_t MuBi4False = 4'h9; + + // This is a prerequisite for the multibit functions below to work. + `CALIPTRA_ASSERT_STATIC_IN_PACKAGE(CheckMuBi4ValsComplementary_A, MuBi4True == ~MuBi4False) + + // Test whether the multibit value is one of the valid enumerations + function automatic logic mubi4_test_invalid(mubi4_t val); + return ~(val inside {MuBi4True, MuBi4False}); + endfunction : mubi4_test_invalid + + // Convert a 1 input value to a mubi output + function automatic mubi4_t mubi4_bool_to_mubi(logic val); + return (val ? MuBi4True : MuBi4False); + endfunction : mubi4_bool_to_mubi + + // Test whether the multibit value signals an "enabled" condition. + // The strict version of this function requires + // the multibit value to equal True. + function automatic logic mubi4_test_true_strict(mubi4_t val); + return MuBi4True == val; + endfunction : mubi4_test_true_strict + + // Test whether the multibit value signals a "disabled" condition. + // The strict version of this function requires + // the multibit value to equal False. + function automatic logic mubi4_test_false_strict(mubi4_t val); + return MuBi4False == val; + endfunction : mubi4_test_false_strict + + // Test whether the multibit value signals an "enabled" condition. + // The loose version of this function interprets all + // values other than False as "enabled". + function automatic logic mubi4_test_true_loose(mubi4_t val); + return MuBi4False != val; + endfunction : mubi4_test_true_loose + + // Test whether the multibit value signals a "disabled" condition. + // The loose version of this function interprets all + // values other than True as "disabled". + function automatic logic mubi4_test_false_loose(mubi4_t val); + return MuBi4True != val; + endfunction : mubi4_test_false_loose + + + // Performs a logical OR operation between two multibit values. + // This treats "act" as logical 1, and all other values are + // treated as 0. Truth table: + // + // A | B | OUT + //------+------+----- + // !act | !act | !act + // act | !act | act + // !act | act | act + // act | act | act + // + function automatic mubi4_t mubi4_or(mubi4_t a, mubi4_t b, mubi4_t act); + logic [MuBi4Width-1:0] a_in, b_in, act_in, out; + a_in = a; + b_in = b; + act_in = act; + for (int k = 0; k < MuBi4Width; k++) begin + if (act_in[k]) begin + out[k] = a_in[k] || b_in[k]; + end else begin + out[k] = a_in[k] && b_in[k]; + end + end + return mubi4_t'(out); + endfunction : mubi4_or + + // Performs a logical AND operation between two multibit values. + // This treats "act" as logical 1, and all other values are + // treated as 0. Truth table: + // + // A | B | OUT + //------+------+----- + // !act | !act | !act + // act | !act | !act + // !act | act | !act + // act | act | act + // + function automatic mubi4_t mubi4_and(mubi4_t a, mubi4_t b, mubi4_t act); + logic [MuBi4Width-1:0] a_in, b_in, act_in, out; + a_in = a; + b_in = b; + act_in = act; + for (int k = 0; k < MuBi4Width; k++) begin + if (act_in[k]) begin + out[k] = a_in[k] && b_in[k]; + end else begin + out[k] = a_in[k] || b_in[k]; + end + end + return mubi4_t'(out); + endfunction : mubi4_and + + // Performs a logical OR operation between two multibit values. + // This treats "True" as logical 1, and all other values are + // treated as 0. + function automatic mubi4_t mubi4_or_hi(mubi4_t a, mubi4_t b); + return mubi4_or(a, b, MuBi4True); + endfunction : mubi4_or_hi + + // Performs a logical AND operation between two multibit values. + // This treats "True" as logical 1, and all other values are + // treated as 0. + function automatic mubi4_t mubi4_and_hi(mubi4_t a, mubi4_t b); + return mubi4_and(a, b, MuBi4True); + endfunction : mubi4_and_hi + + // Performs a logical OR operation between two multibit values. + // This treats "False" as logical 1, and all other values are + // treated as 0. + function automatic mubi4_t mubi4_or_lo(mubi4_t a, mubi4_t b); + return mubi4_or(a, b, MuBi4False); + endfunction : mubi4_or_lo + + // Performs a logical AND operation between two multibit values. + // This treats "False" as logical 1, and all other values are + // treated as 0. + function automatic mubi4_t mubi4_and_lo(mubi4_t a, mubi4_t b); + return mubi4_and(a, b, MuBi4False); + endfunction : mubi4_and_lo + + ////////////////////////////////////////////// + // 8 Bit Multibit Type and Functions // + ////////////////////////////////////////////// + + parameter int MuBi8Width = 8; + typedef enum logic [MuBi8Width-1:0] { + MuBi8True = 8'h96, // enabled + MuBi8False = 8'h69 // disabled + } mubi8_t; + + // This is a prerequisite for the multibit functions below to work. + `CALIPTRA_ASSERT_STATIC_IN_PACKAGE(CheckMuBi8ValsComplementary_A, MuBi8True == ~MuBi8False) + + // Test whether the multibit value is one of the valid enumerations + function automatic logic mubi8_test_invalid(mubi8_t val); + return ~(val inside {MuBi8True, MuBi8False}); + endfunction : mubi8_test_invalid + + // Convert a 1 input value to a mubi output + function automatic mubi8_t mubi8_bool_to_mubi(logic val); + return (val ? MuBi8True : MuBi8False); + endfunction : mubi8_bool_to_mubi + + // Test whether the multibit value signals an "enabled" condition. + // The strict version of this function requires + // the multibit value to equal True. + function automatic logic mubi8_test_true_strict(mubi8_t val); + return MuBi8True == val; + endfunction : mubi8_test_true_strict + + // Test whether the multibit value signals a "disabled" condition. + // The strict version of this function requires + // the multibit value to equal False. + function automatic logic mubi8_test_false_strict(mubi8_t val); + return MuBi8False == val; + endfunction : mubi8_test_false_strict + + // Test whether the multibit value signals an "enabled" condition. + // The loose version of this function interprets all + // values other than False as "enabled". + function automatic logic mubi8_test_true_loose(mubi8_t val); + return MuBi8False != val; + endfunction : mubi8_test_true_loose + + // Test whether the multibit value signals a "disabled" condition. + // The loose version of this function interprets all + // values other than True as "disabled". + function automatic logic mubi8_test_false_loose(mubi8_t val); + return MuBi8True != val; + endfunction : mubi8_test_false_loose + + + // Performs a logical OR operation between two multibit values. + // This treats "act" as logical 1, and all other values are + // treated as 0. Truth table: + // + // A | B | OUT + //------+------+----- + // !act | !act | !act + // act | !act | act + // !act | act | act + // act | act | act + // + function automatic mubi8_t mubi8_or(mubi8_t a, mubi8_t b, mubi8_t act); + logic [MuBi8Width-1:0] a_in, b_in, act_in, out; + a_in = a; + b_in = b; + act_in = act; + for (int k = 0; k < MuBi8Width; k++) begin + if (act_in[k]) begin + out[k] = a_in[k] || b_in[k]; + end else begin + out[k] = a_in[k] && b_in[k]; + end + end + return mubi8_t'(out); + endfunction : mubi8_or + + // Performs a logical AND operation between two multibit values. + // This treats "act" as logical 1, and all other values are + // treated as 0. Truth table: + // + // A | B | OUT + //------+------+----- + // !act | !act | !act + // act | !act | !act + // !act | act | !act + // act | act | act + // + function automatic mubi8_t mubi8_and(mubi8_t a, mubi8_t b, mubi8_t act); + logic [MuBi8Width-1:0] a_in, b_in, act_in, out; + a_in = a; + b_in = b; + act_in = act; + for (int k = 0; k < MuBi8Width; k++) begin + if (act_in[k]) begin + out[k] = a_in[k] && b_in[k]; + end else begin + out[k] = a_in[k] || b_in[k]; + end + end + return mubi8_t'(out); + endfunction : mubi8_and + + // Performs a logical OR operation between two multibit values. + // This treats "True" as logical 1, and all other values are + // treated as 0. + function automatic mubi8_t mubi8_or_hi(mubi8_t a, mubi8_t b); + return mubi8_or(a, b, MuBi8True); + endfunction : mubi8_or_hi + + // Performs a logical AND operation between two multibit values. + // This treats "True" as logical 1, and all other values are + // treated as 0. + function automatic mubi8_t mubi8_and_hi(mubi8_t a, mubi8_t b); + return mubi8_and(a, b, MuBi8True); + endfunction : mubi8_and_hi + + // Performs a logical OR operation between two multibit values. + // This treats "False" as logical 1, and all other values are + // treated as 0. + function automatic mubi8_t mubi8_or_lo(mubi8_t a, mubi8_t b); + return mubi8_or(a, b, MuBi8False); + endfunction : mubi8_or_lo + + // Performs a logical AND operation between two multibit values. + // This treats "False" as logical 1, and all other values are + // treated as 0. + function automatic mubi8_t mubi8_and_lo(mubi8_t a, mubi8_t b); + return mubi8_and(a, b, MuBi8False); + endfunction : mubi8_and_lo + + ////////////////////////////////////////////// + // 12 Bit Multibit Type and Functions // + ////////////////////////////////////////////// + + parameter int MuBi12Width = 12; + typedef enum logic [MuBi12Width-1:0] { + MuBi12True = 12'h696, // enabled + MuBi12False = 12'h969 // disabled + } mubi12_t; + + // This is a prerequisite for the multibit functions below to work. + `CALIPTRA_ASSERT_STATIC_IN_PACKAGE(CheckMuBi12ValsComplementary_A, MuBi12True == ~MuBi12False) + + // Test whether the multibit value is one of the valid enumerations + function automatic logic mubi12_test_invalid(mubi12_t val); + return ~(val inside {MuBi12True, MuBi12False}); + endfunction : mubi12_test_invalid + + // Convert a 1 input value to a mubi output + function automatic mubi12_t mubi12_bool_to_mubi(logic val); + return (val ? MuBi12True : MuBi12False); + endfunction : mubi12_bool_to_mubi + + // Test whether the multibit value signals an "enabled" condition. + // The strict version of this function requires + // the multibit value to equal True. + function automatic logic mubi12_test_true_strict(mubi12_t val); + return MuBi12True == val; + endfunction : mubi12_test_true_strict + + // Test whether the multibit value signals a "disabled" condition. + // The strict version of this function requires + // the multibit value to equal False. + function automatic logic mubi12_test_false_strict(mubi12_t val); + return MuBi12False == val; + endfunction : mubi12_test_false_strict + + // Test whether the multibit value signals an "enabled" condition. + // The loose version of this function interprets all + // values other than False as "enabled". + function automatic logic mubi12_test_true_loose(mubi12_t val); + return MuBi12False != val; + endfunction : mubi12_test_true_loose + + // Test whether the multibit value signals a "disabled" condition. + // The loose version of this function interprets all + // values other than True as "disabled". + function automatic logic mubi12_test_false_loose(mubi12_t val); + return MuBi12True != val; + endfunction : mubi12_test_false_loose + + + // Performs a logical OR operation between two multibit values. + // This treats "act" as logical 1, and all other values are + // treated as 0. Truth table: + // + // A | B | OUT + //------+------+----- + // !act | !act | !act + // act | !act | act + // !act | act | act + // act | act | act + // + function automatic mubi12_t mubi12_or(mubi12_t a, mubi12_t b, mubi12_t act); + logic [MuBi12Width-1:0] a_in, b_in, act_in, out; + a_in = a; + b_in = b; + act_in = act; + for (int k = 0; k < MuBi12Width; k++) begin + if (act_in[k]) begin + out[k] = a_in[k] || b_in[k]; + end else begin + out[k] = a_in[k] && b_in[k]; + end + end + return mubi12_t'(out); + endfunction : mubi12_or + + // Performs a logical AND operation between two multibit values. + // This treats "act" as logical 1, and all other values are + // treated as 0. Truth table: + // + // A | B | OUT + //------+------+----- + // !act | !act | !act + // act | !act | !act + // !act | act | !act + // act | act | act + // + function automatic mubi12_t mubi12_and(mubi12_t a, mubi12_t b, mubi12_t act); + logic [MuBi12Width-1:0] a_in, b_in, act_in, out; + a_in = a; + b_in = b; + act_in = act; + for (int k = 0; k < MuBi12Width; k++) begin + if (act_in[k]) begin + out[k] = a_in[k] && b_in[k]; + end else begin + out[k] = a_in[k] || b_in[k]; + end + end + return mubi12_t'(out); + endfunction : mubi12_and + + // Performs a logical OR operation between two multibit values. + // This treats "True" as logical 1, and all other values are + // treated as 0. + function automatic mubi12_t mubi12_or_hi(mubi12_t a, mubi12_t b); + return mubi12_or(a, b, MuBi12True); + endfunction : mubi12_or_hi + + // Performs a logical AND operation between two multibit values. + // This treats "True" as logical 1, and all other values are + // treated as 0. + function automatic mubi12_t mubi12_and_hi(mubi12_t a, mubi12_t b); + return mubi12_and(a, b, MuBi12True); + endfunction : mubi12_and_hi + + // Performs a logical OR operation between two multibit values. + // This treats "False" as logical 1, and all other values are + // treated as 0. + function automatic mubi12_t mubi12_or_lo(mubi12_t a, mubi12_t b); + return mubi12_or(a, b, MuBi12False); + endfunction : mubi12_or_lo + + // Performs a logical AND operation between two multibit values. + // This treats "False" as logical 1, and all other values are + // treated as 0. + function automatic mubi12_t mubi12_and_lo(mubi12_t a, mubi12_t b); + return mubi12_and(a, b, MuBi12False); + endfunction : mubi12_and_lo + + ////////////////////////////////////////////// + // 16 Bit Multibit Type and Functions // + ////////////////////////////////////////////// + + parameter int MuBi16Width = 16; + typedef enum logic [MuBi16Width-1:0] { + MuBi16True = 16'h9696, // enabled + MuBi16False = 16'h6969 // disabled + } mubi16_t; + + // This is a prerequisite for the multibit functions below to work. + `CALIPTRA_ASSERT_STATIC_IN_PACKAGE(CheckMuBi16ValsComplementary_A, MuBi16True == ~MuBi16False) + + // Test whether the multibit value is one of the valid enumerations + function automatic logic mubi16_test_invalid(mubi16_t val); + return ~(val inside {MuBi16True, MuBi16False}); + endfunction : mubi16_test_invalid + + // Convert a 1 input value to a mubi output + function automatic mubi16_t mubi16_bool_to_mubi(logic val); + return (val ? MuBi16True : MuBi16False); + endfunction : mubi16_bool_to_mubi + + // Test whether the multibit value signals an "enabled" condition. + // The strict version of this function requires + // the multibit value to equal True. + function automatic logic mubi16_test_true_strict(mubi16_t val); + return MuBi16True == val; + endfunction : mubi16_test_true_strict + + // Test whether the multibit value signals a "disabled" condition. + // The strict version of this function requires + // the multibit value to equal False. + function automatic logic mubi16_test_false_strict(mubi16_t val); + return MuBi16False == val; + endfunction : mubi16_test_false_strict + + // Test whether the multibit value signals an "enabled" condition. + // The loose version of this function interprets all + // values other than False as "enabled". + function automatic logic mubi16_test_true_loose(mubi16_t val); + return MuBi16False != val; + endfunction : mubi16_test_true_loose + + // Test whether the multibit value signals a "disabled" condition. + // The loose version of this function interprets all + // values other than True as "disabled". + function automatic logic mubi16_test_false_loose(mubi16_t val); + return MuBi16True != val; + endfunction : mubi16_test_false_loose + + + // Performs a logical OR operation between two multibit values. + // This treats "act" as logical 1, and all other values are + // treated as 0. Truth table: + // + // A | B | OUT + //------+------+----- + // !act | !act | !act + // act | !act | act + // !act | act | act + // act | act | act + // + function automatic mubi16_t mubi16_or(mubi16_t a, mubi16_t b, mubi16_t act); + logic [MuBi16Width-1:0] a_in, b_in, act_in, out; + a_in = a; + b_in = b; + act_in = act; + for (int k = 0; k < MuBi16Width; k++) begin + if (act_in[k]) begin + out[k] = a_in[k] || b_in[k]; + end else begin + out[k] = a_in[k] && b_in[k]; + end + end + return mubi16_t'(out); + endfunction : mubi16_or + + // Performs a logical AND operation between two multibit values. + // This treats "act" as logical 1, and all other values are + // treated as 0. Truth table: + // + // A | B | OUT + //------+------+----- + // !act | !act | !act + // act | !act | !act + // !act | act | !act + // act | act | act + // + function automatic mubi16_t mubi16_and(mubi16_t a, mubi16_t b, mubi16_t act); + logic [MuBi16Width-1:0] a_in, b_in, act_in, out; + a_in = a; + b_in = b; + act_in = act; + for (int k = 0; k < MuBi16Width; k++) begin + if (act_in[k]) begin + out[k] = a_in[k] && b_in[k]; + end else begin + out[k] = a_in[k] || b_in[k]; + end + end + return mubi16_t'(out); + endfunction : mubi16_and + + // Performs a logical OR operation between two multibit values. + // This treats "True" as logical 1, and all other values are + // treated as 0. + function automatic mubi16_t mubi16_or_hi(mubi16_t a, mubi16_t b); + return mubi16_or(a, b, MuBi16True); + endfunction : mubi16_or_hi + + // Performs a logical AND operation between two multibit values. + // This treats "True" as logical 1, and all other values are + // treated as 0. + function automatic mubi16_t mubi16_and_hi(mubi16_t a, mubi16_t b); + return mubi16_and(a, b, MuBi16True); + endfunction : mubi16_and_hi + + // Performs a logical OR operation between two multibit values. + // This treats "False" as logical 1, and all other values are + // treated as 0. + function automatic mubi16_t mubi16_or_lo(mubi16_t a, mubi16_t b); + return mubi16_or(a, b, MuBi16False); + endfunction : mubi16_or_lo + + // Performs a logical AND operation between two multibit values. + // This treats "False" as logical 1, and all other values are + // treated as 0. + function automatic mubi16_t mubi16_and_lo(mubi16_t a, mubi16_t b); + return mubi16_and(a, b, MuBi16False); + endfunction : mubi16_and_lo + +endpackage : caliptra_prim_mubi_pkg diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_onehot_check.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_onehot_check.sv new file mode 100644 index 0000000..837e8e1 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_onehot_check.sv @@ -0,0 +1,156 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// Onehot checker. +// +// This module checks whether the input vector oh_i is onehot0 and generates an error if not. +// +// Optionally, two additional checks can be activated: +// +// 1) EnableCheck: this check performs an OR reduction of the onehot vector, and compares +// the result with en_i. If there is a mismatch, an error is generated. +// 2) AddrCheck: this checks whether the onehot bit is in the correct position. +// It requires an additional address addr_i to be supplied to the module. +// +// All checks make use of an explicit binary tree implementation in order to minimize the delay. +// + +`include "caliptra_prim_assert.sv" + +module caliptra_prim_onehot_check #( + parameter int unsigned AddrWidth = 5, + // The onehot width can be <= 2**AddrWidth and does not have to be a power of two. + parameter int unsigned OneHotWidth = 2**AddrWidth, + // If set to 0, the addr_i input will not be used for the check and can be tied off. + parameter bit AddrCheck = 1, + // If set to 0, the en_i value will not be used for the check and can be tied off. + parameter bit EnableCheck = 1, + // If set to 1, the oh_i vector must always be one hot if en_i is set to 1. + // If set to 0, the oh_i vector may be 0 if en_i is set to 1 (useful when oh_i can be masked). + parameter bit StrictCheck = 1, + // This should only be disabled in special circumstances, for example + // in non-comportable IPs where an error does not trigger an alert. + parameter bit EnableAlertTriggerSVA = 1 +) ( + // The module is combinational - the clock and reset are only used for assertions. + input clk_i, + input rst_ni, + + input logic [OneHotWidth-1:0] oh_i, + input logic [AddrWidth-1:0] addr_i, + input logic en_i, + + output logic err_o +); + + /////////////////////// + // Binary tree logic // + /////////////////////// + + `CALIPTRA_ASSERT_INIT(NumSources_A, OneHotWidth >= 1) + `CALIPTRA_ASSERT_INIT(AddrWidth_A, AddrWidth >= 1) + `CALIPTRA_ASSERT_INIT(AddrRange_A, OneHotWidth <= 2**AddrWidth) + `CALIPTRA_ASSERT_INIT(AddrImpliesEnable_A, AddrCheck && EnableCheck || !AddrCheck) + + // Align to powers of 2 for simplicity. + // A full binary tree with N levels has 2**N + 2**N-1 nodes. + localparam int NumLevels = AddrWidth; + logic [2**(NumLevels+1)-2:0] or_tree; + logic [2**(NumLevels+1)-2:0] and_tree; // Used for the address check + logic [2**(NumLevels+1)-2:0] err_tree; // Used for the enable check + + for (genvar level = 0; level < NumLevels+1; level++) begin : gen_tree + // + // level+1 C0 C1 <- "Base1" points to the first node on "level+1", + // \ / these nodes are the children of the nodes one level below + // level Pa <- "Base0", points to the first node on "level", + // these nodes are the parents of the nodes one level above + // + // hence we have the following indices for the paPa, C0, C1 nodes: + // Pa = 2**level - 1 + offset = Base0 + offset + // C0 = 2**(level+1) - 1 + 2*offset = Base1 + 2*offset + // C1 = 2**(level+1) - 1 + 2*offset + 1 = Base1 + 2*offset + 1 + // + localparam int Base0 = (2**level)-1; + localparam int Base1 = (2**(level+1))-1; + + for (genvar offset = 0; offset < 2**level; offset++) begin : gen_level + localparam int Pa = Base0 + offset; + localparam int C0 = Base1 + 2*offset; + localparam int C1 = Base1 + 2*offset + 1; + + // This assigns the input values, their corresponding IDs and valid signals to the tree leafs. + if (level == NumLevels) begin : gen_leafs + if (offset < OneHotWidth) begin : gen_assign + assign or_tree[Pa] = oh_i[offset]; + assign and_tree[Pa] = oh_i[offset]; + end else begin : gen_tie_off + assign or_tree[Pa] = 1'b0; + assign and_tree[Pa] = 1'b0; + end + assign err_tree[Pa] = 1'b0; + // This creates the node assignments. + end else begin : gen_nodes + assign or_tree[Pa] = or_tree[C0] || or_tree[C1]; + assign and_tree[Pa] = (!addr_i[AddrWidth-1-level] && and_tree[C0]) || + (addr_i[AddrWidth-1-level] && and_tree[C1]); + assign err_tree[Pa] = (or_tree[C0] && or_tree[C1]) || err_tree[C0] || err_tree[C1]; + end + end : gen_level + end : gen_tree + + /////////////////// + // Onehot Checks // + /////////////////// + + logic enable_err, addr_err, oh0_err; + assign err_o = oh0_err || enable_err || addr_err; + + // Check that no more than 1 bit is set in the vector. + assign oh0_err = err_tree[0]; + `CALIPTRA_ASSERT(Onehot0Check_A, !$onehot0(oh_i) |-> err_o) + + // Check that en_i agrees with (|oh_i). + // Note: if StrictCheck 0, the oh_i vector may be all-zero if en_i == 1 (but not vice versa). + if (EnableCheck) begin : gen_enable_check + if (StrictCheck) begin : gen_strict + assign enable_err = or_tree[0] ^ en_i; + `CALIPTRA_ASSERT(EnableCheck_A, (|oh_i) != en_i |-> err_o) + end else begin : gen_not_strict + assign enable_err = !en_i && or_tree[0]; + `CALIPTRA_ASSERT(EnableCheck_A, !en_i && (|oh_i) |-> err_o) + end + end else begin : gen_no_enable_check + logic unused_or_tree; + assign unused_or_tree = ^or_tree; + assign enable_err = 1'b0; + end + + // Check that the set bit is actually in the correct position. + if (AddrCheck) begin : gen_addr_check_strict + assign addr_err = or_tree[0] ^ and_tree[0]; + `CALIPTRA_ASSERT(AddrCheck_A, oh_i[addr_i] != (|oh_i) |-> err_o) + end else begin : gen_no_addr_check_strict + logic unused_and_tree; + assign unused_and_tree = ^and_tree; + assign addr_err = 1'b0; + end + + // We want to know that a block that instantiates prim_onehot_check will raise an alert if we set + // our err_o output. + // + // For confidence that this is true, we use the scheme described in "Security Countermeasure + // Verification Framework". We expect a user of prim_onehot_check to use the + // CALIPTRA_ASSERT_PRIM_COUNT_ERROR_TRIGGER_ALERT macro to check that they will indeed raise an alert if we + // set err_o. + // + // That macro is also designed to drive our local unused_assert_connected variable to true. We add + // an assertion locally that checks (just after the start of time) that it is indeed true. This + // gives us confidence that the user has bound up the alert correctly. +`ifdef CALIPTRA_INC_ASSERT + logic unused_assert_connected; + `CALIPTRA_ASSERT_INIT_NET(AssertConnected_A, unused_assert_connected === 1'b1 || !EnableAlertTriggerSVA) +`endif + +endmodule : caliptra_prim_onehot_check diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_onehot_enc.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_onehot_enc.sv new file mode 100644 index 0000000..f8f2e24 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_onehot_enc.sv @@ -0,0 +1,21 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// One-hot encoder +// Outputs a one-hot encoded version of an integer input. + +module caliptra_prim_onehot_enc #( + parameter int unsigned OneHotWidth = 32, + localparam int unsigned InputWidth = $clog2(OneHotWidth) +) ( + input logic [InputWidth-1:0] in_i, + input logic en_i, // out_o == '0 when en_i == 0 + + output logic [OneHotWidth-1:0] out_o +); + + for (genvar i = 0; i < OneHotWidth; ++i) begin : g_out + assign out_o[i] = (in_i == i) & en_i; + end +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_onehot_mux.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_onehot_mux.sv new file mode 100644 index 0000000..74077c1 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_onehot_mux.sv @@ -0,0 +1,49 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// One-hot mux +// A AND/OR mux with a one-hot select input. + +`include "caliptra_prim_assert.sv" +`include "caliptra_prim_module_name_macros.svh" + +module caliptra_prim_onehot_mux #( + parameter int Width = 32, + parameter int Inputs = 8 +) ( + // Clock and reset only for assertions + input clk_i, + input rst_ni, + + input logic [Width-1:0] in_i [Inputs], + input logic [Inputs-1:0] sel_i, // Must be one-hot or zero + output logic [Width-1:0] out_o +); + logic [Inputs-1:0] in_mux [Width]; + + for (genvar b = 0; b < Width; ++b) begin : g_in_mux_outer + logic [Inputs-1:0] out_mux_bits; + + for (genvar i = 0; i < Inputs; ++i) begin : g_in_mux_inner + assign in_mux[b][i] = in_i[i][b]; + end + + `CALIPTRA_PRIM_MODULE_NAME(and2) #(.Width(Inputs)) u_mux_bit_and( + .in0_i(in_mux[b]), + .in1_i(sel_i), + .out_o(out_mux_bits) + ); + + assign out_o[b] = |out_mux_bits; + end + + logic unused_clk; + logic unused_rst_n; + + // clock and reset only needed for assertion + assign unused_clk = clk_i; + assign unused_rst_n = rst_ni; + + `CALIPTRA_ASSERT(SelIsOnehot_A, $onehot0(sel_i)) +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_otp_pkg.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_otp_pkg.sv new file mode 100644 index 0000000..ca056b9 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_otp_pkg.sv @@ -0,0 +1,50 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// Common interface definitions for OTP primitives. + +package caliptra_prim_otp_pkg; + + // The command is sparsely encoded to make it more difficult to tamper with. + parameter int CmdWidth = 7; + parameter int ErrWidth = 3; + + // Encoding generated with: + // $ ./util/design/sparse-fsm-encode.py -d 4 -m 5 -n 7 \ + // -s 696743973 --language=sv + // + // Hamming distance histogram: + // + // 0: -- + // 1: -- + // 2: -- + // 3: -- + // 4: |||||||||||||||||||| (100.00%) + // 5: -- + // 6: -- + // 7: -- + // + // Minimum Hamming distance: 4 + // Maximum Hamming distance: 4 + // Minimum Hamming weight: 3 + // Maximum Hamming weight: 5 + // + typedef enum logic [CmdWidth-1:0] { + Read = 7'b1000101, + Write = 7'b0110111, + // Raw commands ignore integrity + ReadRaw = 7'b1111001, + WriteRaw = 7'b1100010, + Init = 7'b0101100 + } cmd_e; + + typedef enum logic [ErrWidth-1:0] { + NoError = 3'h0, + MacroError = 3'h1, + MacroEccCorrError = 3'h2, + MacroEccUncorrError = 3'h3, + MacroWriteBlankError = 3'h4 + } err_e; + +endpackage : caliptra_prim_otp_pkg diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_packer.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_packer.sv new file mode 100644 index 0000000..559484c --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_packer.sv @@ -0,0 +1,371 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Combine InW data and write to OutW data if packed to full word or stop signal + +`include "caliptra_prim_assert.sv" + +// ICEBOX(#12958): Revise to send out the empty status. +module caliptra_prim_packer #( + parameter int unsigned InW = 32, + parameter int unsigned OutW = 32, + + // If 1, The input/output are byte granularity + parameter int HintByteData = 0, + + // Turn on protect against FI for the pos variable + parameter bit EnProtection = 1'b 0 +) ( + input clk_i , + input rst_ni, + + input valid_i, + input [InW-1:0] data_i, + input [InW-1:0] mask_i, + output ready_o, + + output logic valid_o, + output logic [OutW-1:0] data_o, + output logic [OutW-1:0] mask_o, + input ready_i, + + input flush_i, // If 1, send out remnant and clear state + output logic flush_done_o, + + // When EnProtection is set, err_o raises an error case (position variable + // mismatch) + output logic err_o +); + + localparam int unsigned Width = InW + OutW; // storage width + localparam int unsigned ConcatW = Width + InW; // Input concatenated width + localparam int unsigned PtrW = $clog2(ConcatW+1); + localparam int unsigned IdxW = caliptra_prim_util_pkg::vbits(InW); + localparam int unsigned OnesCntW = $clog2(InW+1); + + logic valid_next, ready_next; + logic [Width-1:0] stored_data, stored_mask; + logic [ConcatW-1:0] concat_data, concat_mask; + logic [ConcatW-1:0] shiftl_data, shiftl_mask; + logic [InW-1:0] shiftr_data, shiftr_mask; + + logic [PtrW-1:0] pos_q; // Current write position + logic [IdxW-1:0] lod_idx; // result of Leading One Detector + logic [OnesCntW-1:0] inmask_ones; // Counting Ones for mask_i + + logic ack_in, ack_out; + + logic flush_valid; // flush data out request + logic flush_done; + + // Computing next position ================================================== + always_comb begin + // counting mask_i ones + inmask_ones = '0; + for (int i = 0 ; i < InW ; i++) begin + inmask_ones = inmask_ones + OnesCntW'(mask_i[i]); + end + end + + logic [PtrW-1:0] pos_with_input; + assign pos_with_input = pos_q + PtrW'(inmask_ones); + + if (EnProtection == 1'b 0) begin : g_pos_nodup + logic [PtrW-1:0] pos_d; + + always_comb begin + pos_d = pos_q; + + unique case ({ack_in, ack_out}) + 2'b00: pos_d = pos_q; + 2'b01: pos_d = (int'(pos_q) <= OutW) ? '0 : pos_q - PtrW'(OutW); + 2'b10: pos_d = pos_with_input; + 2'b11: pos_d = (int'(pos_with_input) <= OutW) ? '0 : pos_with_input - PtrW'(OutW); + default: pos_d = pos_q; + endcase + end + + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + pos_q <= '0; + end else if (flush_done) begin + pos_q <= '0; + end else begin + pos_q <= pos_d; + end + end + + assign err_o = 1'b 0; // No checker logic + + end else begin : g_pos_dupcnt // EnProtection == 1'b 1 + // incr_en: Increase the pos by cnt_step. ack_in && !ack_out + // decr_en: Decrease the pos by cnt_step. !ack_in && ack_out + // set_en: Set to specific value in case of ack_in && ack_out. + // This case, the value could be increased or descreased based on + // the input size (inmask_ones) + logic cnt_incr_en, cnt_decr_en, cnt_set_en; + logic [PtrW-1:0] cnt_step, cnt_set; + + assign cnt_incr_en = ack_in && !ack_out; + assign cnt_decr_en = !ack_in && ack_out; + assign cnt_set_en = ack_in && ack_out; + + // counter has underflow protection. + assign cnt_step = (cnt_incr_en) ? PtrW'(inmask_ones) : PtrW'(OutW); + + always_comb begin : cnt_set_logic + + // default, consuming all data + cnt_set = '0; + + if (pos_with_input > PtrW'(OutW)) begin + // pos_q + inmask_ones is bigger than Output width. Still data remained. + cnt_set = pos_with_input - PtrW'(OutW); + end + end : cnt_set_logic + + + caliptra_prim_count #( + .Width (PtrW), + .ResetValue ('0 ) + ) u_pos ( + .clk_i, + .rst_ni, + + .clr_i (flush_done), + + .set_i (cnt_set_en), + .set_cnt_i (cnt_set ), + + .incr_en_i (cnt_incr_en), + .decr_en_i (cnt_decr_en), + .step_i (cnt_step ), + .commit_i (1'b1 ), + + .cnt_o (pos_q ), // Current counter state + .cnt_after_commit_o ( ), // Next counter state + + .err_o + ); + end // g_pos_dupcnt + + //--------------------------------------------------------------------------- + + // Leading one detector for mask_i + always_comb begin + lod_idx = 0; + for (int i = InW-1; i >= 0 ; i--) begin + if (mask_i[i] == 1'b1) begin + lod_idx = IdxW'(unsigned'(i)); + end + end + end + + assign ack_in = valid_i & ready_o; + assign ack_out = valid_o & ready_i; + + // Data process ============================================================= + // shiftr : Input data shifted right to put the leading one at bit zero + assign shiftr_data = (valid_i) ? data_i >> lod_idx : '0; + assign shiftr_mask = (valid_i) ? mask_i >> lod_idx : '0; + + // shiftl : Input data shifted into the current stored position + assign shiftl_data = ConcatW'(shiftr_data) << pos_q; + assign shiftl_mask = ConcatW'(shiftr_mask) << pos_q; + + // concat : Merging stored and shiftl + assign concat_data = {{(InW){1'b0}}, stored_data & stored_mask} | + (shiftl_data & shiftl_mask); + assign concat_mask = {{(InW){1'b0}}, stored_mask} | shiftl_mask; + + logic [Width-1:0] stored_data_next, stored_mask_next; + + always_comb begin + unique case ({ack_in, ack_out}) + 2'b 00: begin + stored_data_next = stored_data; + stored_mask_next = stored_mask; + end + 2'b 01: begin + // ack_out : shift the amount of OutW + stored_data_next = {{OutW{1'b0}}, stored_data[Width-1:OutW]}; + stored_mask_next = {{OutW{1'b0}}, stored_mask[Width-1:OutW]}; + end + 2'b 10: begin + // ack_in : Store concat data + stored_data_next = concat_data[0+:Width]; + stored_mask_next = concat_mask[0+:Width]; + end + 2'b 11: begin + // both : shift the concat_data + stored_data_next = concat_data[ConcatW-1:OutW]; + stored_mask_next = concat_mask[ConcatW-1:OutW]; + end + default: begin + stored_data_next = stored_data; + stored_mask_next = stored_mask; + end + endcase + end + + // Store the data temporary if it doesn't exceed OutW + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + stored_data <= '0; + stored_mask <= '0; + end else if (flush_done) begin + stored_data <= '0; + stored_mask <= '0; + end else begin + stored_data <= stored_data_next; + stored_mask <= stored_mask_next; + end + end + //--------------------------------------------------------------------------- + + // flush handling + typedef enum logic { + FlushIdle, + FlushSend + } flush_st_e; + flush_st_e flush_st, flush_st_next; + + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + flush_st <= FlushIdle; + end else begin + flush_st <= flush_st_next; + end + end + + always_comb begin + flush_st_next = FlushIdle; + + flush_valid = 1'b0; + flush_done = 1'b0; + + unique case (flush_st) + FlushIdle: begin + if (flush_i) begin + flush_st_next = FlushSend; + end else begin + flush_st_next = FlushIdle; + end + end + + FlushSend: begin + if (pos_q == '0) begin + flush_st_next = FlushIdle; + + flush_valid = 1'b 0; + flush_done = 1'b 1; + end else begin + flush_st_next = FlushSend; + + flush_valid = 1'b 1; + flush_done = 1'b 0; + end + end + default: begin + flush_st_next = FlushIdle; + + flush_valid = 1'b 0; + flush_done = 1'b 0; + end + endcase + end + + assign flush_done_o = flush_done; + + + // Output signals =========================================================== + assign valid_next = (int'(pos_q) >= OutW) ? 1'b 1 : flush_valid; + + // storage space is InW + OutW. So technically, ready_o can be asserted even + // if `pos_q` is greater than OutW. But in order to do that, the logic should + // use `inmask_ones` value whether pos_q+inmask_ones is less than (InW+OutW) + // with `valid_i`. It creates a path from `valid_i` --> `ready_o`. + // It may create a timing loop in some modules that use `ready_o` to + // `valid_i` (which is not a good practice though) + assign ready_next = int'(pos_q) <= OutW; + + // Output request + assign valid_o = valid_next; + assign data_o = stored_data[OutW-1:0]; + assign mask_o = stored_mask[OutW-1:0]; + + // ready_o + assign ready_o = ready_next; + //--------------------------------------------------------------------------- + + ////////////////////////////////////////////// + // Assertions, Assumptions, and Coverpoints // + ////////////////////////////////////////////// + // Assumption: mask_i should be contiguous ones + // e.g: 0011100 --> OK + // 0100011 --> Not OK + if (InW > 1) begin : gen_mask_assert + `CALIPTRA_ASSUME(ContiguousOnesMask_M, + valid_i |-> $countones(mask_i ^ {mask_i[InW-2:0],1'b0}) <= 2) + end + + // Flush and Write Enable cannot be asserted same time + `CALIPTRA_ASSUME(ExFlushValid_M, flush_i |-> !valid_i) + + // While in flush state, new request shouldn't come + `CALIPTRA_ASSUME(ValidIDeassertedOnFlush_M, + flush_st == FlushSend |-> $stable(valid_i)) + + // If not acked, input port keeps asserting valid and data + `CALIPTRA_ASSUME(DataIStable_M, + ##1 valid_i && $past(valid_i) && !$past(ready_o) + |-> $stable(data_i) && $stable(mask_i)) + + `CALIPTRA_ASSERT(FlushFollowedByDone_A, + ##1 $rose(flush_i) && !flush_done_o |-> !flush_done_o [*0:$] ##1 flush_done_o) + + // If not acked, valid_o should keep asserting + `CALIPTRA_ASSERT(ValidOPairedWidthReadyI_A, + valid_o && !ready_i |=> valid_o) + + // If stored data is greater than the output width, valid should be asserted + `CALIPTRA_ASSERT(ValidOAssertedForStoredDataGTEOutW_A, + ($countones(stored_mask) >= OutW) |-> valid_o) + + // If output port doesn't accept the data, the data should be stable + `CALIPTRA_ASSERT(DataOStableWhenPending_A, + ##1 valid_o && $past(valid_o) + && !$past(ready_i) |-> $stable(data_o)) + + // If input data & stored data are greater than OutW, remained should be stored + `CALIPTRA_ASSERT(ExcessiveDataStored_A, + ack_in && ack_out && (($countones(mask_i) + $countones(stored_mask)) > OutW) + |=> (($past(data_i) & $past(mask_i)) >> + ($past(lod_idx)+OutW-$countones($past(stored_mask)))) + == stored_data) + + `CALIPTRA_ASSERT(ExcessiveMaskStored_A, + ack_in && ack_out && (($countones(mask_i) + $countones(stored_mask)) > OutW) + |=> ($past(mask_i) >> + ($past(lod_idx)+OutW-$countones($past(stored_mask)))) + == stored_mask) + + // Assertions for byte hint enabled + if (HintByteData != 0) begin : g_byte_assert + `CALIPTRA_ASSERT_INIT(InputDividedBy8_A, InW % 8 == 0) + `CALIPTRA_ASSERT_INIT(OutputDividedBy8_A, OutW % 8 == 0) + + // Masking[8*i+:8] should be all zero or all one + for (genvar i = 0 ; i < InW/8 ; i++) begin : g_byte_input_masking + `CALIPTRA_ASSERT(InputMaskContiguous_A, + valid_i |-> (|mask_i[8*i+:8] == 1'b 0) + || (&mask_i[8*i+:8] == 1'b 1)) + end + for (genvar i = 0 ; i < OutW/8 ; i++) begin : g_byte_output_masking + `CALIPTRA_ASSERT(OutputMaskContiguous_A, + valid_o |-> (|mask_o[8*i+:8] == 1'b 0) + || (&mask_o[8*i+:8] == 1'b 1)) + end + end +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_packer_fifo.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_packer_fifo.sv new file mode 100644 index 0000000..d0f480b --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_packer_fifo.sv @@ -0,0 +1,181 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Supports packed and unpacked modes +// Uses FIFO timing on the control signals +// No masking or flush functions supported + +// Timings - case where InW < OutW +// clk_i __|~~|__~~|__|~~|__~~|__|~~|__~~|__|~~|__~~|__|~~|__~~|__|~~|__ +// wvalid_i _____|~~~~|_____|~~~~|_____|~~~~|_____|~~~~|___________________ +// wdata_i Val N |Val N+1 |Val N+2 |Val N+3 |------------------- +// wready_o ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~|__________|~~~~~~~~ +// rvalid_o ___________________________________________|~~~~~~~~~~|________ +// rdata_o -------------------------------------------|Val |-------- +// rready_i _________________________________________________|~~~~|________ +// depth_o 0000000000|1111111111|2222222222|3333333333|4444444444|00000000 + + +// Timings - case where InW > OutW +// clk_i __|~~|__~~|__|~~|__~~|__|~~|__~~|__|~~|__~~|__|~~|__~~|__|~~|__ +// wvalid_i _____|~~~~|____________________________________________________ +// wdata_i -----|Val |---------------------------------------------------- +// wready_o ~~~~~~~~~~|___________________________________________|~~~~~~~~ +// rvalid_o __________|~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~|________ +// rdata_o ----------|Val N |Val N+1 |Val N+2 |Val N+3 |-------- +// rready_i ________________|~~~~|_____|~~~~|_____|~~~~|_____|~~~~|________ +// depth_o 0000000000|4444444444|3333333333|2222222222|1111111111|00000000 + + +// Timings - case where InW = OutW +// clk_i __|~~|__~~|__|~~|__~~|__|~~|__~~|__|~~|__~~|__|~~|__~~|__|~~|__ +// wvalid_i _____|~~~~|____________________________________________________ +// wdata_i -----|Val |---------------------------------------------------- +// wready_o ~~~~~~~~~~|__________|~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// rvalid_o __________|~~~~~~~~~~|_________________________________________ +// rdata_o ----------|Val |----------------------------------------- +// rready_i ________________|~~~~|_________________________________________ +// depth_o 0000000000|1111111111|00000000000000000000000000000000000000000 + + +`include "caliptra_prim_assert.sv" + +module caliptra_prim_packer_fifo #( + parameter int InW = 32, + parameter int OutW = 8, + parameter bit ClearOnRead = 1'b1, // if == 1 always output 0 after read + // derived parameters + localparam int MaxW = (InW > OutW) ? InW : OutW, + localparam int MinW = (InW < OutW) ? InW : OutW, + localparam int DepthW = $clog2(MaxW/MinW) +) ( + input logic clk_i , + input logic rst_ni, + + input logic clr_i, + input logic wvalid_i, + input logic [InW-1:0] wdata_i, + output logic wready_o, + + output logic rvalid_o, + output logic [OutW-1:0] rdata_o, + input logic rready_i, + output logic [DepthW:0] depth_o +); + + localparam int unsigned WidthRatio = MaxW / MinW; + localparam bit [DepthW:0] FullDepth = WidthRatio[DepthW:0]; + localparam bit [DepthW:0] DepthOne = 1; + + // signals + logic load_data; + logic clear_data; + logic clear_status; + + // flops + logic [DepthW:0] depth_q, depth_d; + logic [MaxW-1:0] data_q, data_d; + logic clr_q, clr_d; + + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + depth_q <= '0; + data_q <= '0; + clr_q <= 1'b1; + end else begin + depth_q <= depth_d; + data_q <= data_d; + clr_q <= clr_d; + end + end + + // flop for handling reset case for clr + assign clr_d = clr_i; + + assign depth_o = depth_q; + + if (InW < OutW) begin : gen_pack_mode + logic [MaxW-1:0] wdata_shifted; + + assign wdata_shifted = {{OutW - InW{1'b0}}, wdata_i} << (depth_q*InW); + assign clear_status = (rready_i && rvalid_o) || clr_q; + assign clear_data = (ClearOnRead && clear_status) || clr_q; + assign load_data = wvalid_i && wready_o; + + assign depth_d = clear_status ? '0 : + load_data ? (depth_q + DepthOne): + depth_q; + + assign data_d = clear_data ? '0 : + load_data ? (wdata_shifted | (depth_q == 0 ? '0 : data_q)) : + data_q; + + // set outputs + assign wready_o = !(depth_q == FullDepth) && !clr_q; + assign rdata_o = data_q; + assign rvalid_o = (depth_q == FullDepth) && !clr_q; + + end else begin : gen_unpack_mode + logic [MaxW-1:0] rdata_shifted; + logic pull_data; + logic [DepthW:0] ptr_q, ptr_d; + logic [DepthW:0] lsb_is_one; + logic [DepthW:0] max_value; + + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + ptr_q <= '0; + end else begin + ptr_q <= ptr_d; + end + end + + assign lsb_is_one = {{DepthW{1'b0}},1'b1}; + assign max_value = FullDepth; + assign rdata_shifted = MaxW'(data_q >> ptr_q*OutW); + assign clear_status = (rready_i && (depth_q == lsb_is_one)) || clr_q; + assign clear_data = (ClearOnRead && clear_status) || clr_q; + assign load_data = wvalid_i && wready_o; + assign pull_data = rvalid_o && rready_i; + + assign depth_d = clear_status ? '0 : + load_data ? max_value : + pull_data ? (depth_q - DepthOne) : + depth_q; + + assign ptr_d = clear_status ? '0 : + pull_data ? (ptr_q + DepthOne) : + ptr_q; + + assign data_d = clear_data ? '0 : + load_data ? wdata_i : + data_q; + + // set outputs + assign wready_o = (depth_q == '0) && !clr_q; + assign rdata_o = rdata_shifted[OutW-1:0]; + assign rvalid_o = !(depth_q == '0) && !clr_q; + + // Avoid possible lint errors in case InW > OutW. + if (InW > OutW) begin : gen_unused + logic [MaxW-MinW-1:0] unused_rdata_shifted; + assign unused_rdata_shifted = rdata_shifted[MaxW-1:MinW]; + end + end + + + ////////////////////////////////////////////// + // Assertions, Assumptions, and Coverpoints // + ////////////////////////////////////////////// + + // If not acked, valid_o should keep asserting + `CALIPTRA_ASSERT(ValidOPairedWithReadyI_A, + rvalid_o && !rready_i && !clr_i |=> rvalid_o) + + // If output port doesn't accept the data, the data should be stable + `CALIPTRA_ASSERT(DataOStableWhenPending_A, + ##1 rvalid_o && $past(rvalid_o) + && !$past(rready_i) && !$past(clr_i) |-> $stable(rdata_o)) + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_pkg.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_pkg.sv new file mode 100755 index 0000000..2d69a31 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_pkg.sv @@ -0,0 +1,17 @@ +// Copyright lowRISC contributors. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Constants for use in primitives + +// This file is auto-generated. + +package caliptra_prim_pkg; + + // Implementation target specialization + typedef enum logic [31:0] { + ImplGeneric, + ImplXilinx, + ImplBadbit + } impl_e; +endpackage : caliptra_prim_pkg diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_present.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_present.sv new file mode 100644 index 0000000..884bd95 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_present.sv @@ -0,0 +1,158 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// This module is an implementation of the encryption pass of the 64bit PRESENT +// block cipher. It is a fully unrolled combinational implementation that +// supports both key sizes specified in the paper (80bit and 128bit). Further, +// the number of rounds is fully configurable, and the primitive supports a +// 32bit block cipher flavor which is not specified in the original paper. It +// should be noted, however, that the 32bit version is **not** secure and must +// not be used in a setting where cryptographic cipher strength is required. The +// 32bit variant is only intended to be used as a lightweight data scrambling +// device. +// +// See also: prim_prince, prim_cipher_pkg +// +// References: - https://en.wikipedia.org/wiki/PRESENT +// - https://en.wikipedia.org/wiki/Prince_(cipher) +// - http://www.lightweightcrypto.org/present/present_ches2007.pdf +// - https://eprint.iacr.org/2012/529.pdf +// - https://csrc.nist.gov/csrc/media/events/lightweight-cryptography-workshop-2015/ +// documents/papers/session7-maene-paper.pdf + +`include "caliptra_prim_assert.sv" +module caliptra_prim_present #( + parameter int DataWidth = 64, // {32, 64} + parameter int KeyWidth = 128, // {64, 80, 128} + // Number of rounds to perform in total (>0) + parameter int NumRounds = 31, + // Number of physically instantiated PRESENT rounds. + // This can be used to construct e.g. an iterative + // full-round implementation that only has one physical + // round instance by setting NumRounds = 31 and NumPhysRounds = 1. + // Note that NumPhysRounds needs to divide NumRounds. + parameter int NumPhysRounds = NumRounds, + // Note that the decryption pass needs a modified key, + // to be calculated by performing NumRounds key updates + parameter bit Decrypt = 0 // 0: encrypt, 1: decrypt +) ( + input [DataWidth-1:0] data_i, + input [KeyWidth-1:0] key_i, + // Starting round index for keyschedule [1 ... 31]. + // Set this to 5'd1 for a fully unrolled encryption, and 5'd31 for a fully unrolled decryption. + input [4:0] idx_i, + output logic [DataWidth-1:0] data_o, + output logic [KeyWidth-1:0] key_o, + // Next round index for keyschedule + // (Enc: idx_i + NumPhysRounds, Dec: idx_i - NumPhysRounds) + // Can be ignored for a fully unrolled implementation. + output logic [4:0] idx_o +); + + ////////////// + // datapath // + ////////////// + + logic [NumPhysRounds:0][DataWidth-1:0] data_state; + logic [NumPhysRounds:0][KeyWidth-1:0] round_key; + logic [NumPhysRounds:0][4:0] round_idx; + + // initialize + assign data_state[0] = data_i; + assign round_key[0] = key_i; + assign round_idx[0] = idx_i; + + for (genvar k = 0; k < NumPhysRounds; k++) begin : gen_round + logic [DataWidth-1:0] data_state_xor, data_state_sbox; + // cipher layers + assign data_state_xor = data_state[k] ^ round_key[k][KeyWidth-1 : KeyWidth-DataWidth]; + //////////////////////////////// + // decryption pass, performs inverse permutation, sbox and keyschedule + if (Decrypt) begin : gen_dec + // Decrement round count. + assign round_idx[k+1] = round_idx[k] - 1'b1; + // original 64bit variant + if (DataWidth == 64) begin : gen_d64 + assign data_state_sbox = caliptra_prim_cipher_pkg::perm_64bit(data_state_xor, + caliptra_prim_cipher_pkg::PRESENT_PERM64_INV); + assign data_state[k+1] = caliptra_prim_cipher_pkg::sbox4_64bit(data_state_sbox, + caliptra_prim_cipher_pkg::PRESENT_SBOX4_INV); + // reduced 32bit variant + end else begin : gen_d32 + assign data_state_sbox = caliptra_prim_cipher_pkg::perm_32bit(data_state_xor, + caliptra_prim_cipher_pkg::PRESENT_PERM32_INV); + assign data_state[k+1] = caliptra_prim_cipher_pkg::sbox4_32bit(data_state_sbox, + caliptra_prim_cipher_pkg::PRESENT_SBOX4_INV); + end + // update round key, count goes from 1 to 31 (max) + // original 128bit key variant + if (KeyWidth == 128) begin : gen_k128 + assign round_key[k+1] = caliptra_prim_cipher_pkg::present_inv_update_key128(round_key[k], + round_idx[k]); + // original 80bit key variant + end else if (KeyWidth == 80) begin : gen_k80 + assign round_key[k+1] = caliptra_prim_cipher_pkg::present_inv_update_key80(round_key[k], + round_idx[k]); + // reduced 64bit key variant + end else begin : gen_k64 + assign round_key[k+1] = caliptra_prim_cipher_pkg::present_inv_update_key64(round_key[k], + round_idx[k]); + end + //////////////////////////////// + // encryption pass + end else begin : gen_enc + // Increment round count. + assign round_idx[k+1] = round_idx[k] + 1'b1; + // original 64bit variant + if (DataWidth == 64) begin : gen_d64 + assign data_state_sbox = caliptra_prim_cipher_pkg::sbox4_64bit(data_state_xor, + caliptra_prim_cipher_pkg::PRESENT_SBOX4); + assign data_state[k+1] = caliptra_prim_cipher_pkg::perm_64bit(data_state_sbox, + caliptra_prim_cipher_pkg::PRESENT_PERM64); + // reduced 32bit variant + end else begin : gen_d32 + assign data_state_sbox = caliptra_prim_cipher_pkg::sbox4_32bit(data_state_xor, + caliptra_prim_cipher_pkg::PRESENT_SBOX4); + assign data_state[k+1] = caliptra_prim_cipher_pkg::perm_32bit(data_state_sbox, + caliptra_prim_cipher_pkg::PRESENT_PERM32); + end + // update round key, count goes from 1 to 31 (max) + // original 128bit key variant + if (KeyWidth == 128) begin : gen_k128 + assign round_key[k+1] = caliptra_prim_cipher_pkg::present_update_key128(round_key[k], round_idx[k]); + // original 80bit key variant + end else if (KeyWidth == 80) begin : gen_k80 + assign round_key[k+1] = caliptra_prim_cipher_pkg::present_update_key80(round_key[k], round_idx[k]); + // reduced 64bit key variant + end else begin : gen_k64 + assign round_key[k+1] = caliptra_prim_cipher_pkg::present_update_key64(round_key[k], round_idx[k]); + end + end // gen_enc + //////////////////////////////// + end // gen_round + + // This only needs to be applied after the last round. + // Note that for a full-round implementation the output index + // will be 0 for enc/dec for the last round (either due to wraparound or subtraction). + localparam int LastRoundIdx = (Decrypt != 0 || NumRounds == 31) ? 0 : NumRounds+1; + assign data_o = (int'(idx_o) == LastRoundIdx) ? + data_state[NumPhysRounds] ^ + round_key[NumPhysRounds][KeyWidth-1 : KeyWidth-DataWidth] : + data_state[NumPhysRounds]; + + assign key_o = round_key[NumPhysRounds]; + assign idx_o = round_idx[NumPhysRounds]; + + //////////////// + // assertions // + //////////////// + + `CALIPTRA_ASSERT_INIT(SupportedWidths_A, (DataWidth == 64 && KeyWidth inside {80, 128}) || + (DataWidth == 32 && KeyWidth == 64)) + `CALIPTRA_ASSERT_INIT(SupportedNumRounds_A, NumRounds > 0 && NumRounds <= 31) + `CALIPTRA_ASSERT_INIT(SupportedNumPhysRounds0_A, NumPhysRounds > 0 && NumPhysRounds <= NumRounds) + // Currently we do not support other arrangements + `CALIPTRA_ASSERT_INIT(SupportedNumPhysRounds1_A, (NumRounds % NumPhysRounds) == 0) + +endmodule : caliptra_prim_present diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_ram_1p_adv.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_ram_1p_adv.sv new file mode 100644 index 0000000..ff8899e --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_ram_1p_adv.sv @@ -0,0 +1,363 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Single-Port SRAM Wrapper +// +// Supported configurations: +// - ECC for 32b and 64b wide memories with no write mask +// (Width == 32 or Width == 64, DataBitsPerMask is ignored). +// - Byte parity if Width is a multiple of 8 bit and write masks have Byte +// granularity (DataBitsPerMask == 8). +// +// Note that the write mask needs to be per Byte if parity is enabled. If ECC is enabled, the write +// mask cannot be used and has to be tied to {Width{1'b1}}. + +`include "caliptra_prim_assert.sv" +`include "caliptra_prim_module_name_macros.svh" + +module caliptra_prim_ram_1p_adv import caliptra_prim_ram_1p_pkg::*; #( + parameter int Depth = 512, + parameter int Width = 32, + parameter int DataBitsPerMask = 1, // Number of data bits per bit of write mask + parameter MemInitFile = "", // VMEM file to initialize the memory with + + // Configurations + parameter bit EnableECC = 0, // Enables per-word ECC + parameter bit EnableParity = 0, // Enables per-Byte Parity + parameter bit EnableInputPipeline = 0, // Adds an input register (read latency +1) + parameter bit EnableOutputPipeline = 0, // Adds an output register (read latency +1) + + // This switch allows to switch to standard Hamming ECC instead of the HSIAO ECC. + // It is recommended to leave this parameter at its default setting (HSIAO), + // since this results in a more compact and faster implementation. + parameter bit HammingECC = 0, + + localparam int Aw = caliptra_prim_util_pkg::vbits(Depth) +) ( + input clk_i, + input rst_ni, + + input req_i, + input write_i, + input [Aw-1:0] addr_i, + input [Width-1:0] wdata_i, + input [Width-1:0] wmask_i, + output logic [Width-1:0] rdata_o, + output logic rvalid_o, // read response (rdata_o) is valid + output logic [1:0] rerror_o, // Bit1: Uncorrectable, Bit0: Correctable + + // config + input ram_1p_cfg_t cfg_i, + + // When detecting multi-bit encoding errors, raise alert. + output logic alert_o +); + + import caliptra_prim_mubi_pkg::mubi4_t; + import caliptra_prim_mubi_pkg::mubi4_and_hi; + import caliptra_prim_mubi_pkg::mubi4_bool_to_mubi; + import caliptra_prim_mubi_pkg::mubi4_test_invalid; + import caliptra_prim_mubi_pkg::mubi4_test_true_loose; + import caliptra_prim_mubi_pkg::MuBi4True; + import caliptra_prim_mubi_pkg::MuBi4False; + import caliptra_prim_mubi_pkg::MuBi4Width; + + `CALIPTRA_ASSERT_INIT(CannotHaveEccAndParity_A, !(EnableParity && EnableECC)) + + // Calculate ECC width + localparam int ParWidth = (EnableParity) ? Width/8 : + (!EnableECC) ? 0 : + (Width <= 4) ? 4 : + (Width <= 11) ? 5 : + (Width <= 26) ? 6 : + (Width <= 57) ? 7 : + (Width <= 120) ? 8 : 8 ; + localparam int TotalWidth = Width + ParWidth; + + // If byte parity is enabled, the write enable bits are used to write memory colums + // with 8 + 1 = 9 bit width (data plus corresponding parity bit). + // If ECC is enabled, the DataBitsPerMask is ignored. + localparam int LocalDataBitsPerMask = (EnableParity) ? 9 : + (EnableECC) ? TotalWidth : + DataBitsPerMask; + + //////////////////////////// + // RAM Primitive Instance // + //////////////////////////// + + mubi4_t req_q, req_d, req_buf_d ; + logic [MuBi4Width-1:0] req_buf_b_d; + logic req_q_b ; + mubi4_t write_q, write_d, write_buf_d ; + logic [MuBi4Width-1:0] write_buf_b_d; + logic write_q_b ; + logic [Aw-1:0] addr_q, addr_d ; + logic [TotalWidth-1:0] wdata_q, wdata_d ; + logic [TotalWidth-1:0] wmask_q, wmask_d ; + mubi4_t rvalid_q, rvalid_d, rvalid_sram_q, rvalid_sram_d ; + logic [Width-1:0] rdata_q, rdata_d ; + logic [TotalWidth-1:0] rdata_sram ; + logic [1:0] rerror_q, rerror_d ; + + assign req_q_b = mubi4_test_true_loose(req_q); + assign write_q_b = mubi4_test_true_loose(write_q); + + `CALIPTRA_PRIM_MODULE_NAME(ram_1p) #( + .MemInitFile (MemInitFile), + + .Width (TotalWidth), + .Depth (Depth), + .DataBitsPerMask (LocalDataBitsPerMask) + ) u_mem ( + .clk_i, + + .req_i (req_q_b), + .write_i (write_q_b), + .addr_i (addr_q), + .wdata_i (wdata_q), + .wmask_i (wmask_q), + .rdata_o (rdata_sram), + .cfg_i + ); + + assign rvalid_sram_d = mubi4_and_hi(req_q, mubi4_t'(~write_q)); + + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + rvalid_sram_q <= MuBi4False; + end else begin + rvalid_sram_q <= rvalid_sram_d; + end + end + + assign req_d = mubi4_bool_to_mubi(req_i); + assign write_d = mubi4_bool_to_mubi(write_i); + assign addr_d = addr_i; + assign rvalid_o = mubi4_test_true_loose(rvalid_q); + assign rdata_o = rdata_q; + assign rerror_o = rerror_q; + + caliptra_prim_buf #( + .Width(MuBi4Width) + ) u_req_d_buf ( + .in_i (req_d), + .out_o(req_buf_b_d) + ); + + assign req_buf_d = mubi4_t'(req_buf_b_d); + + caliptra_prim_buf #( + .Width(MuBi4Width) + ) u_write_d_buf ( + .in_i (write_d), + .out_o(write_buf_b_d) + ); + + assign write_buf_d = mubi4_t'(write_buf_b_d); + + ///////////////////////////// + // ECC / Parity Generation // + ///////////////////////////// + + if (EnableParity == 0 && EnableECC) begin : gen_secded + logic unused_wmask; + assign unused_wmask = ^wmask_i; + + // check supported widths + `CALIPTRA_ASSERT_INIT(SecDecWidth_A, Width inside {16, 32}) + + // the wmask is constantly set to 1 in this case + `CALIPTRA_ASSERT(OnlyWordWritePossibleWithEccPortA_A, req_i |-> + wmask_i == {Width{1'b1}}) + + assign wmask_d = {TotalWidth{1'b1}}; + + if (Width == 16) begin : gen_secded_22_16 + if (HammingECC) begin : gen_hamming + caliptra_prim_secded_inv_hamming_22_16_enc u_enc ( + .data_i(wdata_i), + .data_o(wdata_d) + ); + caliptra_prim_secded_inv_hamming_22_16_dec u_dec ( + .data_i (rdata_sram), + .data_o (rdata_d[0+:Width]), + .syndrome_o ( ), + .err_o (rerror_d) + ); + end else begin : gen_hsiao + caliptra_prim_secded_inv_22_16_enc u_enc ( + .data_i(wdata_i), + .data_o(wdata_d) + ); + caliptra_prim_secded_inv_22_16_dec u_dec ( + .data_i (rdata_sram), + .data_o (rdata_d[0+:Width]), + .syndrome_o ( ), + .err_o (rerror_d) + ); + end + end else if (Width == 32) begin : gen_secded_39_32 + if (HammingECC) begin : gen_hamming + caliptra_prim_secded_inv_hamming_39_32_enc u_enc ( + .data_i(wdata_i), + .data_o(wdata_d) + ); + caliptra_prim_secded_inv_hamming_39_32_dec u_dec ( + .data_i (rdata_sram), + .data_o (rdata_d[0+:Width]), + .syndrome_o ( ), + .err_o (rerror_d) + ); + end else begin : gen_hsiao + caliptra_prim_secded_inv_39_32_enc u_enc ( + .data_i(wdata_i), + .data_o(wdata_d) + ); + caliptra_prim_secded_inv_39_32_dec u_dec ( + .data_i (rdata_sram), + .data_o (rdata_d[0+:Width]), + .syndrome_o ( ), + .err_o (rerror_d) + ); + end + end + + end else if (EnableParity) begin : gen_byte_parity + + `CALIPTRA_ASSERT_INIT(WidthNeedsToBeByteAligned_A, Width % 8 == 0) + `CALIPTRA_ASSERT_INIT(ParityNeedsByteWriteMask_A, DataBitsPerMask == 8) + + always_comb begin : p_parity + rerror_d = '0; + for (int i = 0; i < Width/8; i ++) begin + // Data mapping. We have to make 8+1 = 9 bit groups + // that have the same write enable such that FPGA tools + // can map this correctly to BRAM resources. + wmask_d[i*9 +: 8] = wmask_i[i*8 +: 8]; + wdata_d[i*9 +: 8] = wdata_i[i*8 +: 8]; + rdata_d[i*8 +: 8] = rdata_sram[i*9 +: 8]; + + // parity generation (odd parity) + wdata_d[i*9 + 8] = ~(^wdata_i[i*8 +: 8]); + wmask_d[i*9 + 8] = &wmask_i[i*8 +: 8]; + // parity decoding (errors are always uncorrectable) + rerror_d[1] |= ~(^{rdata_sram[i*9 +: 8], rdata_sram[i*9 + 8]}); + end + end + end else begin : gen_nosecded_noparity + assign wmask_d = wmask_i; + assign wdata_d = wdata_i; + + assign rdata_d = rdata_sram[0+:Width]; + assign rerror_d = '0; + end + + assign rvalid_d = rvalid_sram_q; + + ///////////////////////////////////// + // Input/Output Pipeline Registers // + ///////////////////////////////////// + + if (EnableInputPipeline) begin : gen_regslice_input + // Put the register slices between ECC encoding to SRAM port + + // If no ECC or parity is used, do not use prim_flop to allow synthesis + // tool to optimize the registers. + if (EnableECC || EnableParity) begin : gen_prim_flop + prim_flop #( + .Width(MuBi4Width), + .ResetValue(MuBi4Width'(MuBi4False)) + ) u_write_flop ( + .clk_i, + .rst_ni, + .d_i(MuBi4Width'(write_buf_d)), + .q_o({write_q}) + ); + + prim_flop #( + .Width(MuBi4Width), + .ResetValue(MuBi4Width'(MuBi4False)) + ) u_req_flop ( + .clk_i, + .rst_ni, + .d_i(MuBi4Width'(req_buf_d)), + .q_o({req_q}) + ); + end else begin: gen_no_prim_flop + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + write_q <= MuBi4False; + req_q <= MuBi4False; + end else begin + write_q <= write_buf_d; + req_q <= req_buf_d; + end + end + end + + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + addr_q <= '0; + wdata_q <= '0; + wmask_q <= '0; + end else begin + addr_q <= addr_d; + wdata_q <= wdata_d; + wmask_q <= wmask_d; + end + end + end else begin : gen_dirconnect_input + assign req_q = req_buf_d; + assign write_q = write_buf_d; + assign addr_q = addr_d; + assign wdata_q = wdata_d; + assign wmask_q = wmask_d; + end + + if (EnableOutputPipeline) begin : gen_regslice_output + // Put the register slices between ECC decoding to output + + // If no ECC or parity is used, do not use prim_flop to allow synthesis + // tool to optimize the registers. + if (EnableECC || EnableParity) begin : gen_prim_rvalid_flop + prim_flop #( + .Width(MuBi4Width), + .ResetValue(MuBi4Width'(MuBi4False)) + ) u_rvalid_flop ( + .clk_i, + .rst_ni, + .d_i(MuBi4Width'(rvalid_d)), + .q_o({rvalid_q}) + ); + end else begin: gen_no_prim_rvalid_flop + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + rvalid_q <= MuBi4False; + end else begin + rvalid_q <= rvalid_d; + end + end + end + + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + rdata_q <= '0; + rerror_q <= '0; + end else begin + rdata_q <= rdata_d; + // tie to zero if the read data is not valid + rerror_q <= rerror_d & {2{mubi4_test_true_loose(rvalid_d)}}; + end + end + end else begin : gen_dirconnect_output + assign rvalid_q = rvalid_d; + assign rdata_q = rdata_d; + // tie to zero if the read data is not valid + assign rerror_q = rerror_d & {2{mubi4_test_true_loose(rvalid_d)}}; + end + + assign alert_o = mubi4_test_invalid(req_q) | mubi4_test_invalid(write_q) | + mubi4_test_invalid(rvalid_q) | mubi4_test_invalid(rvalid_sram_q); + +endmodule : caliptra_prim_ram_1p_adv diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_ram_1p_pkg.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_ram_1p_pkg.sv new file mode 100644 index 0000000..41b5e90 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_ram_1p_pkg.sv @@ -0,0 +1,21 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// + +package caliptra_prim_ram_1p_pkg; + + typedef struct packed { + logic test; + logic cfg_en; + logic [3:0] cfg; + } cfg_t; + + typedef struct packed { + cfg_t ram_cfg; // configuration for ram + cfg_t rf_cfg; // configuration for regfile + } ram_1p_cfg_t; + + parameter ram_1p_cfg_t RAM_1P_CFG_DEFAULT = '0; + +endpackage // caliptra_prim_ram_1p_pkg diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_reg_we_check.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_reg_we_check.sv new file mode 100644 index 0000000..45b0d94 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_reg_we_check.sv @@ -0,0 +1,54 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// Spurious write-enable checker for autogenerated CSR node. +// This module has additional simulation features for error injection testing. + +`include "caliptra_prim_assert.sv" + +module caliptra_prim_reg_we_check #( + parameter int unsigned OneHotWidth = 32 +) ( + // The module is combinational - the clock and reset are only used for assertions. + input clk_i, + input rst_ni, + + input logic [OneHotWidth-1:0] oh_i, + input logic en_i, + + output logic err_o +); + + // Prevent optimization of the onehot input buffer. + logic [OneHotWidth-1:0] oh_buf; + caliptra_prim_buf #( + .Width(OneHotWidth) + ) u_caliptra_prim_buf ( + .in_i(oh_i), + .out_o(oh_buf) + ); + + caliptra_prim_onehot_check #( + .OneHotWidth(OneHotWidth), + .AddrWidth (caliptra_prim_util_pkg::vbits(OneHotWidth)), + .EnableCheck(1), + // Since certain peripherals may have a very large address space + // (e.g. > 20bit), the inverse address decoding check (which is + // essentially an indexing operation) does not scale well and is + // hence omitted. + .AddrCheck(0), + // Due to REGWEN masking of write enable strobes, + // we do not perform strict checks. I.e., we allow cases + // where en_i is set to 1, but the oh_i vector is all-zeroes. + .StrictCheck(0) + ) u_caliptra_prim_onehot_check ( + .clk_i, + .rst_ni, + .oh_i(oh_buf), + .addr_i('0), + .en_i, + .err_o + ); + +endmodule : caliptra_prim_reg_we_check diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_sec_anchor_buf.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_sec_anchor_buf.sv new file mode 100644 index 0000000..1167308 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_sec_anchor_buf.sv @@ -0,0 +1,21 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +`include "caliptra_prim_assert.sv" + +module caliptra_prim_sec_anchor_buf #( + parameter int Width = 1 +) ( + input [Width-1:0] in_i, + output logic [Width-1:0] out_o +); + + caliptra_prim_buf #( + .Width(Width) + ) u_secure_anchor_buf ( + .in_i, + .out_o + ); + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_sec_anchor_flop.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_sec_anchor_flop.sv new file mode 100644 index 0000000..eb2a69d --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_sec_anchor_flop.sv @@ -0,0 +1,27 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +`include "caliptra_prim_assert.sv" + +module caliptra_prim_sec_anchor_flop #( + parameter int Width = 1, + parameter logic [Width-1:0] ResetValue = 0 +) ( + input clk_i, + input rst_ni, + input [Width-1:0] d_i, + output logic [Width-1:0] q_o +); + + caliptra_prim_flop #( + .Width(Width), + .ResetValue(ResetValue) + ) u_secure_anchor_flop ( + .clk_i, + .rst_ni, + .d_i, + .q_o + ); + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_22_16_dec.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_22_16_dec.sv new file mode 100644 index 0000000..3b01c69 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_22_16_dec.sv @@ -0,0 +1,45 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// SECDED decoder generated by util/design/secded_gen.py + +module caliptra_prim_secded_22_16_dec ( + input [21:0] data_i, + output logic [15:0] data_o, + output logic [5:0] syndrome_o, + output logic [1:0] err_o +); + + always_comb begin : p_encode + // Syndrome calculation + syndrome_o[0] = ^(data_i & 22'h01496E); + syndrome_o[1] = ^(data_i & 22'h02F20B); + syndrome_o[2] = ^(data_i & 22'h048ED8); + syndrome_o[3] = ^(data_i & 22'h087714); + syndrome_o[4] = ^(data_i & 22'h10ACA5); + syndrome_o[5] = ^(data_i & 22'h2011F3); + + // Corrected output calculation + data_o[0] = (syndrome_o == 6'h32) ^ data_i[0]; + data_o[1] = (syndrome_o == 6'h23) ^ data_i[1]; + data_o[2] = (syndrome_o == 6'h19) ^ data_i[2]; + data_o[3] = (syndrome_o == 6'h7) ^ data_i[3]; + data_o[4] = (syndrome_o == 6'h2c) ^ data_i[4]; + data_o[5] = (syndrome_o == 6'h31) ^ data_i[5]; + data_o[6] = (syndrome_o == 6'h25) ^ data_i[6]; + data_o[7] = (syndrome_o == 6'h34) ^ data_i[7]; + data_o[8] = (syndrome_o == 6'h29) ^ data_i[8]; + data_o[9] = (syndrome_o == 6'he) ^ data_i[9]; + data_o[10] = (syndrome_o == 6'h1c) ^ data_i[10]; + data_o[11] = (syndrome_o == 6'h15) ^ data_i[11]; + data_o[12] = (syndrome_o == 6'h2a) ^ data_i[12]; + data_o[13] = (syndrome_o == 6'h1a) ^ data_i[13]; + data_o[14] = (syndrome_o == 6'hb) ^ data_i[14]; + data_o[15] = (syndrome_o == 6'h16) ^ data_i[15]; + + // err_o calc. bit0: single error, bit1: double error + err_o[0] = ^syndrome_o; + err_o[1] = ~err_o[0] & (|syndrome_o); + end +endmodule : caliptra_prim_secded_22_16_dec diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_22_16_enc.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_22_16_enc.sv new file mode 100644 index 0000000..cd4dc1b --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_22_16_enc.sv @@ -0,0 +1,22 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// SECDED encoder generated by util/design/secded_gen.py + +module caliptra_prim_secded_22_16_enc ( + input [15:0] data_i, + output logic [21:0] data_o +); + + always_comb begin : p_encode + data_o = 22'(data_i); + data_o[16] = ^(data_o & 22'h00496E); + data_o[17] = ^(data_o & 22'h00F20B); + data_o[18] = ^(data_o & 22'h008ED8); + data_o[19] = ^(data_o & 22'h007714); + data_o[20] = ^(data_o & 22'h00ACA5); + data_o[21] = ^(data_o & 22'h0011F3); + end + +endmodule : caliptra_prim_secded_22_16_enc diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_28_22_dec.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_28_22_dec.sv new file mode 100644 index 0000000..e0a5b3e --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_28_22_dec.sv @@ -0,0 +1,51 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// SECDED decoder generated by util/design/secded_gen.py + +module caliptra_prim_secded_28_22_dec ( + input [27:0] data_i, + output logic [21:0] data_o, + output logic [5:0] syndrome_o, + output logic [1:0] err_o +); + + always_comb begin : p_encode + // Syndrome calculation + syndrome_o[0] = ^(data_i & 28'h07003FF); + syndrome_o[1] = ^(data_i & 28'h090FC0F); + syndrome_o[2] = ^(data_i & 28'h1271C71); + syndrome_o[3] = ^(data_i & 28'h23B6592); + syndrome_o[4] = ^(data_i & 28'h43DAAA4); + syndrome_o[5] = ^(data_i & 28'h83ED348); + + // Corrected output calculation + data_o[0] = (syndrome_o == 6'h7) ^ data_i[0]; + data_o[1] = (syndrome_o == 6'hb) ^ data_i[1]; + data_o[2] = (syndrome_o == 6'h13) ^ data_i[2]; + data_o[3] = (syndrome_o == 6'h23) ^ data_i[3]; + data_o[4] = (syndrome_o == 6'hd) ^ data_i[4]; + data_o[5] = (syndrome_o == 6'h15) ^ data_i[5]; + data_o[6] = (syndrome_o == 6'h25) ^ data_i[6]; + data_o[7] = (syndrome_o == 6'h19) ^ data_i[7]; + data_o[8] = (syndrome_o == 6'h29) ^ data_i[8]; + data_o[9] = (syndrome_o == 6'h31) ^ data_i[9]; + data_o[10] = (syndrome_o == 6'he) ^ data_i[10]; + data_o[11] = (syndrome_o == 6'h16) ^ data_i[11]; + data_o[12] = (syndrome_o == 6'h26) ^ data_i[12]; + data_o[13] = (syndrome_o == 6'h1a) ^ data_i[13]; + data_o[14] = (syndrome_o == 6'h2a) ^ data_i[14]; + data_o[15] = (syndrome_o == 6'h32) ^ data_i[15]; + data_o[16] = (syndrome_o == 6'h1c) ^ data_i[16]; + data_o[17] = (syndrome_o == 6'h2c) ^ data_i[17]; + data_o[18] = (syndrome_o == 6'h34) ^ data_i[18]; + data_o[19] = (syndrome_o == 6'h38) ^ data_i[19]; + data_o[20] = (syndrome_o == 6'h3b) ^ data_i[20]; + data_o[21] = (syndrome_o == 6'h3d) ^ data_i[21]; + + // err_o calc. bit0: single error, bit1: double error + err_o[0] = ^syndrome_o; + err_o[1] = ~err_o[0] & (|syndrome_o); + end +endmodule : caliptra_prim_secded_28_22_dec diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_28_22_enc.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_28_22_enc.sv new file mode 100644 index 0000000..c440a03 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_28_22_enc.sv @@ -0,0 +1,22 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// SECDED encoder generated by util/design/secded_gen.py + +module caliptra_prim_secded_28_22_enc ( + input [21:0] data_i, + output logic [27:0] data_o +); + + always_comb begin : p_encode + data_o = 28'(data_i); + data_o[22] = ^(data_o & 28'h03003FF); + data_o[23] = ^(data_o & 28'h010FC0F); + data_o[24] = ^(data_o & 28'h0271C71); + data_o[25] = ^(data_o & 28'h03B6592); + data_o[26] = ^(data_o & 28'h03DAAA4); + data_o[27] = ^(data_o & 28'h03ED348); + end + +endmodule : caliptra_prim_secded_28_22_enc diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_39_32_dec.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_39_32_dec.sv new file mode 100644 index 0000000..5fbf53e --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_39_32_dec.sv @@ -0,0 +1,62 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// SECDED decoder generated by util/design/secded_gen.py + +module caliptra_prim_secded_39_32_dec ( + input [38:0] data_i, + output logic [31:0] data_o, + output logic [6:0] syndrome_o, + output logic [1:0] err_o +); + + always_comb begin : p_encode + // Syndrome calculation + syndrome_o[0] = ^(data_i & 39'h012606BD25); + syndrome_o[1] = ^(data_i & 39'h02DEBA8050); + syndrome_o[2] = ^(data_i & 39'h04413D89AA); + syndrome_o[3] = ^(data_i & 39'h0831234ED1); + syndrome_o[4] = ^(data_i & 39'h10C2C1323B); + syndrome_o[5] = ^(data_i & 39'h202DCC624C); + syndrome_o[6] = ^(data_i & 39'h4098505586); + + // Corrected output calculation + data_o[0] = (syndrome_o == 7'h19) ^ data_i[0]; + data_o[1] = (syndrome_o == 7'h54) ^ data_i[1]; + data_o[2] = (syndrome_o == 7'h61) ^ data_i[2]; + data_o[3] = (syndrome_o == 7'h34) ^ data_i[3]; + data_o[4] = (syndrome_o == 7'h1a) ^ data_i[4]; + data_o[5] = (syndrome_o == 7'h15) ^ data_i[5]; + data_o[6] = (syndrome_o == 7'h2a) ^ data_i[6]; + data_o[7] = (syndrome_o == 7'h4c) ^ data_i[7]; + data_o[8] = (syndrome_o == 7'h45) ^ data_i[8]; + data_o[9] = (syndrome_o == 7'h38) ^ data_i[9]; + data_o[10] = (syndrome_o == 7'h49) ^ data_i[10]; + data_o[11] = (syndrome_o == 7'hd) ^ data_i[11]; + data_o[12] = (syndrome_o == 7'h51) ^ data_i[12]; + data_o[13] = (syndrome_o == 7'h31) ^ data_i[13]; + data_o[14] = (syndrome_o == 7'h68) ^ data_i[14]; + data_o[15] = (syndrome_o == 7'h7) ^ data_i[15]; + data_o[16] = (syndrome_o == 7'h1c) ^ data_i[16]; + data_o[17] = (syndrome_o == 7'hb) ^ data_i[17]; + data_o[18] = (syndrome_o == 7'h25) ^ data_i[18]; + data_o[19] = (syndrome_o == 7'h26) ^ data_i[19]; + data_o[20] = (syndrome_o == 7'h46) ^ data_i[20]; + data_o[21] = (syndrome_o == 7'he) ^ data_i[21]; + data_o[22] = (syndrome_o == 7'h70) ^ data_i[22]; + data_o[23] = (syndrome_o == 7'h32) ^ data_i[23]; + data_o[24] = (syndrome_o == 7'h2c) ^ data_i[24]; + data_o[25] = (syndrome_o == 7'h13) ^ data_i[25]; + data_o[26] = (syndrome_o == 7'h23) ^ data_i[26]; + data_o[27] = (syndrome_o == 7'h62) ^ data_i[27]; + data_o[28] = (syndrome_o == 7'h4a) ^ data_i[28]; + data_o[29] = (syndrome_o == 7'h29) ^ data_i[29]; + data_o[30] = (syndrome_o == 7'h16) ^ data_i[30]; + data_o[31] = (syndrome_o == 7'h52) ^ data_i[31]; + + // err_o calc. bit0: single error, bit1: double error + err_o[0] = ^syndrome_o; + err_o[1] = ~err_o[0] & (|syndrome_o); + end +endmodule : caliptra_prim_secded_39_32_dec diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_39_32_enc.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_39_32_enc.sv new file mode 100644 index 0000000..5221834 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_39_32_enc.sv @@ -0,0 +1,23 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// SECDED encoder generated by util/design/secded_gen.py + +module caliptra_prim_secded_39_32_enc ( + input [31:0] data_i, + output logic [38:0] data_o +); + + always_comb begin : p_encode + data_o = 39'(data_i); + data_o[32] = ^(data_o & 39'h002606BD25); + data_o[33] = ^(data_o & 39'h00DEBA8050); + data_o[34] = ^(data_o & 39'h00413D89AA); + data_o[35] = ^(data_o & 39'h0031234ED1); + data_o[36] = ^(data_o & 39'h00C2C1323B); + data_o[37] = ^(data_o & 39'h002DCC624C); + data_o[38] = ^(data_o & 39'h0098505586); + end + +endmodule : caliptra_prim_secded_39_32_enc diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_64_57_dec.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_64_57_dec.sv new file mode 100644 index 0000000..34f17d7 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_64_57_dec.sv @@ -0,0 +1,87 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// SECDED decoder generated by util/design/secded_gen.py + +module caliptra_prim_secded_64_57_dec ( + input [63:0] data_i, + output logic [56:0] data_o, + output logic [6:0] syndrome_o, + output logic [1:0] err_o +); + + always_comb begin : p_encode + // Syndrome calculation + syndrome_o[0] = ^(data_i & 64'h0303FFF800007FFF); + syndrome_o[1] = ^(data_i & 64'h057C1FF801FF801F); + syndrome_o[2] = ^(data_i & 64'h09BDE1F87E0781E1); + syndrome_o[3] = ^(data_i & 64'h11DEEE3B8E388E22); + syndrome_o[4] = ^(data_i & 64'h21EF76CDB2C93244); + syndrome_o[5] = ^(data_i & 64'h41F7BB56D5525488); + syndrome_o[6] = ^(data_i & 64'h81FBDDA769A46910); + + // Corrected output calculation + data_o[0] = (syndrome_o == 7'h7) ^ data_i[0]; + data_o[1] = (syndrome_o == 7'hb) ^ data_i[1]; + data_o[2] = (syndrome_o == 7'h13) ^ data_i[2]; + data_o[3] = (syndrome_o == 7'h23) ^ data_i[3]; + data_o[4] = (syndrome_o == 7'h43) ^ data_i[4]; + data_o[5] = (syndrome_o == 7'hd) ^ data_i[5]; + data_o[6] = (syndrome_o == 7'h15) ^ data_i[6]; + data_o[7] = (syndrome_o == 7'h25) ^ data_i[7]; + data_o[8] = (syndrome_o == 7'h45) ^ data_i[8]; + data_o[9] = (syndrome_o == 7'h19) ^ data_i[9]; + data_o[10] = (syndrome_o == 7'h29) ^ data_i[10]; + data_o[11] = (syndrome_o == 7'h49) ^ data_i[11]; + data_o[12] = (syndrome_o == 7'h31) ^ data_i[12]; + data_o[13] = (syndrome_o == 7'h51) ^ data_i[13]; + data_o[14] = (syndrome_o == 7'h61) ^ data_i[14]; + data_o[15] = (syndrome_o == 7'he) ^ data_i[15]; + data_o[16] = (syndrome_o == 7'h16) ^ data_i[16]; + data_o[17] = (syndrome_o == 7'h26) ^ data_i[17]; + data_o[18] = (syndrome_o == 7'h46) ^ data_i[18]; + data_o[19] = (syndrome_o == 7'h1a) ^ data_i[19]; + data_o[20] = (syndrome_o == 7'h2a) ^ data_i[20]; + data_o[21] = (syndrome_o == 7'h4a) ^ data_i[21]; + data_o[22] = (syndrome_o == 7'h32) ^ data_i[22]; + data_o[23] = (syndrome_o == 7'h52) ^ data_i[23]; + data_o[24] = (syndrome_o == 7'h62) ^ data_i[24]; + data_o[25] = (syndrome_o == 7'h1c) ^ data_i[25]; + data_o[26] = (syndrome_o == 7'h2c) ^ data_i[26]; + data_o[27] = (syndrome_o == 7'h4c) ^ data_i[27]; + data_o[28] = (syndrome_o == 7'h34) ^ data_i[28]; + data_o[29] = (syndrome_o == 7'h54) ^ data_i[29]; + data_o[30] = (syndrome_o == 7'h64) ^ data_i[30]; + data_o[31] = (syndrome_o == 7'h38) ^ data_i[31]; + data_o[32] = (syndrome_o == 7'h58) ^ data_i[32]; + data_o[33] = (syndrome_o == 7'h68) ^ data_i[33]; + data_o[34] = (syndrome_o == 7'h70) ^ data_i[34]; + data_o[35] = (syndrome_o == 7'h1f) ^ data_i[35]; + data_o[36] = (syndrome_o == 7'h2f) ^ data_i[36]; + data_o[37] = (syndrome_o == 7'h4f) ^ data_i[37]; + data_o[38] = (syndrome_o == 7'h37) ^ data_i[38]; + data_o[39] = (syndrome_o == 7'h57) ^ data_i[39]; + data_o[40] = (syndrome_o == 7'h67) ^ data_i[40]; + data_o[41] = (syndrome_o == 7'h3b) ^ data_i[41]; + data_o[42] = (syndrome_o == 7'h5b) ^ data_i[42]; + data_o[43] = (syndrome_o == 7'h6b) ^ data_i[43]; + data_o[44] = (syndrome_o == 7'h73) ^ data_i[44]; + data_o[45] = (syndrome_o == 7'h3d) ^ data_i[45]; + data_o[46] = (syndrome_o == 7'h5d) ^ data_i[46]; + data_o[47] = (syndrome_o == 7'h6d) ^ data_i[47]; + data_o[48] = (syndrome_o == 7'h75) ^ data_i[48]; + data_o[49] = (syndrome_o == 7'h79) ^ data_i[49]; + data_o[50] = (syndrome_o == 7'h3e) ^ data_i[50]; + data_o[51] = (syndrome_o == 7'h5e) ^ data_i[51]; + data_o[52] = (syndrome_o == 7'h6e) ^ data_i[52]; + data_o[53] = (syndrome_o == 7'h76) ^ data_i[53]; + data_o[54] = (syndrome_o == 7'h7a) ^ data_i[54]; + data_o[55] = (syndrome_o == 7'h7c) ^ data_i[55]; + data_o[56] = (syndrome_o == 7'h7f) ^ data_i[56]; + + // err_o calc. bit0: single error, bit1: double error + err_o[0] = ^syndrome_o; + err_o[1] = ~err_o[0] & (|syndrome_o); + end +endmodule : caliptra_prim_secded_64_57_dec diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_64_57_enc.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_64_57_enc.sv new file mode 100644 index 0000000..4d068b3 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_64_57_enc.sv @@ -0,0 +1,23 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// SECDED encoder generated by util/design/secded_gen.py + +module caliptra_prim_secded_64_57_enc ( + input [56:0] data_i, + output logic [63:0] data_o +); + + always_comb begin : p_encode + data_o = 64'(data_i); + data_o[57] = ^(data_o & 64'h0103FFF800007FFF); + data_o[58] = ^(data_o & 64'h017C1FF801FF801F); + data_o[59] = ^(data_o & 64'h01BDE1F87E0781E1); + data_o[60] = ^(data_o & 64'h01DEEE3B8E388E22); + data_o[61] = ^(data_o & 64'h01EF76CDB2C93244); + data_o[62] = ^(data_o & 64'h01F7BB56D5525488); + data_o[63] = ^(data_o & 64'h01FBDDA769A46910); + end + +endmodule : caliptra_prim_secded_64_57_enc diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_72_64_dec.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_72_64_dec.sv new file mode 100644 index 0000000..736a413 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_72_64_dec.sv @@ -0,0 +1,95 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// SECDED decoder generated by util/design/secded_gen.py + +module caliptra_prim_secded_72_64_dec ( + input [71:0] data_i, + output logic [63:0] data_o, + output logic [7:0] syndrome_o, + output logic [1:0] err_o +); + + always_comb begin : p_encode + // Syndrome calculation + syndrome_o[0] = ^(data_i & 72'h01B9000000001FFFFF); + syndrome_o[1] = ^(data_i & 72'h025E00000FFFE0003F); + syndrome_o[2] = ^(data_i & 72'h0467003FF003E007C1); + syndrome_o[3] = ^(data_i & 72'h08CD0FC0F03C207842); + syndrome_o[4] = ^(data_i & 72'h10B671C711C4438884); + syndrome_o[5] = ^(data_i & 72'h20B5B65926488C9108); + syndrome_o[6] = ^(data_i & 72'h40CBDAAA4A91152210); + syndrome_o[7] = ^(data_i & 72'h807AED348D221A4420); + + // Corrected output calculation + data_o[0] = (syndrome_o == 8'h7) ^ data_i[0]; + data_o[1] = (syndrome_o == 8'hb) ^ data_i[1]; + data_o[2] = (syndrome_o == 8'h13) ^ data_i[2]; + data_o[3] = (syndrome_o == 8'h23) ^ data_i[3]; + data_o[4] = (syndrome_o == 8'h43) ^ data_i[4]; + data_o[5] = (syndrome_o == 8'h83) ^ data_i[5]; + data_o[6] = (syndrome_o == 8'hd) ^ data_i[6]; + data_o[7] = (syndrome_o == 8'h15) ^ data_i[7]; + data_o[8] = (syndrome_o == 8'h25) ^ data_i[8]; + data_o[9] = (syndrome_o == 8'h45) ^ data_i[9]; + data_o[10] = (syndrome_o == 8'h85) ^ data_i[10]; + data_o[11] = (syndrome_o == 8'h19) ^ data_i[11]; + data_o[12] = (syndrome_o == 8'h29) ^ data_i[12]; + data_o[13] = (syndrome_o == 8'h49) ^ data_i[13]; + data_o[14] = (syndrome_o == 8'h89) ^ data_i[14]; + data_o[15] = (syndrome_o == 8'h31) ^ data_i[15]; + data_o[16] = (syndrome_o == 8'h51) ^ data_i[16]; + data_o[17] = (syndrome_o == 8'h91) ^ data_i[17]; + data_o[18] = (syndrome_o == 8'h61) ^ data_i[18]; + data_o[19] = (syndrome_o == 8'ha1) ^ data_i[19]; + data_o[20] = (syndrome_o == 8'hc1) ^ data_i[20]; + data_o[21] = (syndrome_o == 8'he) ^ data_i[21]; + data_o[22] = (syndrome_o == 8'h16) ^ data_i[22]; + data_o[23] = (syndrome_o == 8'h26) ^ data_i[23]; + data_o[24] = (syndrome_o == 8'h46) ^ data_i[24]; + data_o[25] = (syndrome_o == 8'h86) ^ data_i[25]; + data_o[26] = (syndrome_o == 8'h1a) ^ data_i[26]; + data_o[27] = (syndrome_o == 8'h2a) ^ data_i[27]; + data_o[28] = (syndrome_o == 8'h4a) ^ data_i[28]; + data_o[29] = (syndrome_o == 8'h8a) ^ data_i[29]; + data_o[30] = (syndrome_o == 8'h32) ^ data_i[30]; + data_o[31] = (syndrome_o == 8'h52) ^ data_i[31]; + data_o[32] = (syndrome_o == 8'h92) ^ data_i[32]; + data_o[33] = (syndrome_o == 8'h62) ^ data_i[33]; + data_o[34] = (syndrome_o == 8'ha2) ^ data_i[34]; + data_o[35] = (syndrome_o == 8'hc2) ^ data_i[35]; + data_o[36] = (syndrome_o == 8'h1c) ^ data_i[36]; + data_o[37] = (syndrome_o == 8'h2c) ^ data_i[37]; + data_o[38] = (syndrome_o == 8'h4c) ^ data_i[38]; + data_o[39] = (syndrome_o == 8'h8c) ^ data_i[39]; + data_o[40] = (syndrome_o == 8'h34) ^ data_i[40]; + data_o[41] = (syndrome_o == 8'h54) ^ data_i[41]; + data_o[42] = (syndrome_o == 8'h94) ^ data_i[42]; + data_o[43] = (syndrome_o == 8'h64) ^ data_i[43]; + data_o[44] = (syndrome_o == 8'ha4) ^ data_i[44]; + data_o[45] = (syndrome_o == 8'hc4) ^ data_i[45]; + data_o[46] = (syndrome_o == 8'h38) ^ data_i[46]; + data_o[47] = (syndrome_o == 8'h58) ^ data_i[47]; + data_o[48] = (syndrome_o == 8'h98) ^ data_i[48]; + data_o[49] = (syndrome_o == 8'h68) ^ data_i[49]; + data_o[50] = (syndrome_o == 8'ha8) ^ data_i[50]; + data_o[51] = (syndrome_o == 8'hc8) ^ data_i[51]; + data_o[52] = (syndrome_o == 8'h70) ^ data_i[52]; + data_o[53] = (syndrome_o == 8'hb0) ^ data_i[53]; + data_o[54] = (syndrome_o == 8'hd0) ^ data_i[54]; + data_o[55] = (syndrome_o == 8'he0) ^ data_i[55]; + data_o[56] = (syndrome_o == 8'h6d) ^ data_i[56]; + data_o[57] = (syndrome_o == 8'hd6) ^ data_i[57]; + data_o[58] = (syndrome_o == 8'h3e) ^ data_i[58]; + data_o[59] = (syndrome_o == 8'hcb) ^ data_i[59]; + data_o[60] = (syndrome_o == 8'hb3) ^ data_i[60]; + data_o[61] = (syndrome_o == 8'hb5) ^ data_i[61]; + data_o[62] = (syndrome_o == 8'hce) ^ data_i[62]; + data_o[63] = (syndrome_o == 8'h79) ^ data_i[63]; + + // err_o calc. bit0: single error, bit1: double error + err_o[0] = ^syndrome_o; + err_o[1] = ~err_o[0] & (|syndrome_o); + end +endmodule : caliptra_prim_secded_72_64_dec diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_72_64_enc.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_72_64_enc.sv new file mode 100644 index 0000000..8f0252e --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_72_64_enc.sv @@ -0,0 +1,24 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// SECDED encoder generated by util/design/secded_gen.py + +module caliptra_prim_secded_72_64_enc ( + input [63:0] data_i, + output logic [71:0] data_o +); + + always_comb begin : p_encode + data_o = 72'(data_i); + data_o[64] = ^(data_o & 72'h00B9000000001FFFFF); + data_o[65] = ^(data_o & 72'h005E00000FFFE0003F); + data_o[66] = ^(data_o & 72'h0067003FF003E007C1); + data_o[67] = ^(data_o & 72'h00CD0FC0F03C207842); + data_o[68] = ^(data_o & 72'h00B671C711C4438884); + data_o[69] = ^(data_o & 72'h00B5B65926488C9108); + data_o[70] = ^(data_o & 72'h00CBDAAA4A91152210); + data_o[71] = ^(data_o & 72'h007AED348D221A4420); + end + +endmodule : caliptra_prim_secded_72_64_enc diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_hamming_22_16_dec.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_hamming_22_16_dec.sv new file mode 100644 index 0000000..0203463 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_hamming_22_16_dec.sv @@ -0,0 +1,45 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// SECDED decoder generated by util/design/secded_gen.py + +module caliptra_prim_secded_hamming_22_16_dec ( + input [21:0] data_i, + output logic [15:0] data_o, + output logic [5:0] syndrome_o, + output logic [1:0] err_o +); + + always_comb begin : p_encode + // Syndrome calculation + syndrome_o[0] = ^(data_i & 22'h01AD5B); + syndrome_o[1] = ^(data_i & 22'h02366D); + syndrome_o[2] = ^(data_i & 22'h04C78E); + syndrome_o[3] = ^(data_i & 22'h0807F0); + syndrome_o[4] = ^(data_i & 22'h10F800); + syndrome_o[5] = ^(data_i & 22'h3FFFFF); + + // Corrected output calculation + data_o[0] = (syndrome_o == 6'h23) ^ data_i[0]; + data_o[1] = (syndrome_o == 6'h25) ^ data_i[1]; + data_o[2] = (syndrome_o == 6'h26) ^ data_i[2]; + data_o[3] = (syndrome_o == 6'h27) ^ data_i[3]; + data_o[4] = (syndrome_o == 6'h29) ^ data_i[4]; + data_o[5] = (syndrome_o == 6'h2a) ^ data_i[5]; + data_o[6] = (syndrome_o == 6'h2b) ^ data_i[6]; + data_o[7] = (syndrome_o == 6'h2c) ^ data_i[7]; + data_o[8] = (syndrome_o == 6'h2d) ^ data_i[8]; + data_o[9] = (syndrome_o == 6'h2e) ^ data_i[9]; + data_o[10] = (syndrome_o == 6'h2f) ^ data_i[10]; + data_o[11] = (syndrome_o == 6'h31) ^ data_i[11]; + data_o[12] = (syndrome_o == 6'h32) ^ data_i[12]; + data_o[13] = (syndrome_o == 6'h33) ^ data_i[13]; + data_o[14] = (syndrome_o == 6'h34) ^ data_i[14]; + data_o[15] = (syndrome_o == 6'h35) ^ data_i[15]; + + // err_o calc. bit0: single error, bit1: double error + err_o[0] = syndrome_o[5]; + err_o[1] = |syndrome_o[4:0] & ~syndrome_o[5]; + end +endmodule : caliptra_prim_secded_hamming_22_16_dec diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_hamming_22_16_enc.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_hamming_22_16_enc.sv new file mode 100644 index 0000000..cdb2e32 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_hamming_22_16_enc.sv @@ -0,0 +1,22 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// SECDED encoder generated by util/design/secded_gen.py + +module caliptra_prim_secded_hamming_22_16_enc ( + input [15:0] data_i, + output logic [21:0] data_o +); + + always_comb begin : p_encode + data_o = 22'(data_i); + data_o[16] = ^(data_o & 22'h00AD5B); + data_o[17] = ^(data_o & 22'h00366D); + data_o[18] = ^(data_o & 22'h00C78E); + data_o[19] = ^(data_o & 22'h0007F0); + data_o[20] = ^(data_o & 22'h00F800); + data_o[21] = ^(data_o & 22'h1FFFFF); + end + +endmodule : caliptra_prim_secded_hamming_22_16_enc diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_hamming_39_32_dec.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_hamming_39_32_dec.sv new file mode 100644 index 0000000..770ccd2 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_hamming_39_32_dec.sv @@ -0,0 +1,62 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// SECDED decoder generated by util/design/secded_gen.py + +module caliptra_prim_secded_hamming_39_32_dec ( + input [38:0] data_i, + output logic [31:0] data_o, + output logic [6:0] syndrome_o, + output logic [1:0] err_o +); + + always_comb begin : p_encode + // Syndrome calculation + syndrome_o[0] = ^(data_i & 39'h0156AAAD5B); + syndrome_o[1] = ^(data_i & 39'h029B33366D); + syndrome_o[2] = ^(data_i & 39'h04E3C3C78E); + syndrome_o[3] = ^(data_i & 39'h0803FC07F0); + syndrome_o[4] = ^(data_i & 39'h1003FFF800); + syndrome_o[5] = ^(data_i & 39'h20FC000000); + syndrome_o[6] = ^(data_i & 39'h7FFFFFFFFF); + + // Corrected output calculation + data_o[0] = (syndrome_o == 7'h43) ^ data_i[0]; + data_o[1] = (syndrome_o == 7'h45) ^ data_i[1]; + data_o[2] = (syndrome_o == 7'h46) ^ data_i[2]; + data_o[3] = (syndrome_o == 7'h47) ^ data_i[3]; + data_o[4] = (syndrome_o == 7'h49) ^ data_i[4]; + data_o[5] = (syndrome_o == 7'h4a) ^ data_i[5]; + data_o[6] = (syndrome_o == 7'h4b) ^ data_i[6]; + data_o[7] = (syndrome_o == 7'h4c) ^ data_i[7]; + data_o[8] = (syndrome_o == 7'h4d) ^ data_i[8]; + data_o[9] = (syndrome_o == 7'h4e) ^ data_i[9]; + data_o[10] = (syndrome_o == 7'h4f) ^ data_i[10]; + data_o[11] = (syndrome_o == 7'h51) ^ data_i[11]; + data_o[12] = (syndrome_o == 7'h52) ^ data_i[12]; + data_o[13] = (syndrome_o == 7'h53) ^ data_i[13]; + data_o[14] = (syndrome_o == 7'h54) ^ data_i[14]; + data_o[15] = (syndrome_o == 7'h55) ^ data_i[15]; + data_o[16] = (syndrome_o == 7'h56) ^ data_i[16]; + data_o[17] = (syndrome_o == 7'h57) ^ data_i[17]; + data_o[18] = (syndrome_o == 7'h58) ^ data_i[18]; + data_o[19] = (syndrome_o == 7'h59) ^ data_i[19]; + data_o[20] = (syndrome_o == 7'h5a) ^ data_i[20]; + data_o[21] = (syndrome_o == 7'h5b) ^ data_i[21]; + data_o[22] = (syndrome_o == 7'h5c) ^ data_i[22]; + data_o[23] = (syndrome_o == 7'h5d) ^ data_i[23]; + data_o[24] = (syndrome_o == 7'h5e) ^ data_i[24]; + data_o[25] = (syndrome_o == 7'h5f) ^ data_i[25]; + data_o[26] = (syndrome_o == 7'h61) ^ data_i[26]; + data_o[27] = (syndrome_o == 7'h62) ^ data_i[27]; + data_o[28] = (syndrome_o == 7'h63) ^ data_i[28]; + data_o[29] = (syndrome_o == 7'h64) ^ data_i[29]; + data_o[30] = (syndrome_o == 7'h65) ^ data_i[30]; + data_o[31] = (syndrome_o == 7'h66) ^ data_i[31]; + + // err_o calc. bit0: single error, bit1: double error + err_o[0] = syndrome_o[6]; + err_o[1] = |syndrome_o[5:0] & ~syndrome_o[6]; + end +endmodule : caliptra_prim_secded_hamming_39_32_dec diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_hamming_39_32_enc.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_hamming_39_32_enc.sv new file mode 100644 index 0000000..e80ccfb --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_hamming_39_32_enc.sv @@ -0,0 +1,23 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// SECDED encoder generated by util/design/secded_gen.py + +module caliptra_prim_secded_hamming_39_32_enc ( + input [31:0] data_i, + output logic [38:0] data_o +); + + always_comb begin : p_encode + data_o = 39'(data_i); + data_o[32] = ^(data_o & 39'h0056AAAD5B); + data_o[33] = ^(data_o & 39'h009B33366D); + data_o[34] = ^(data_o & 39'h00E3C3C78E); + data_o[35] = ^(data_o & 39'h0003FC07F0); + data_o[36] = ^(data_o & 39'h0003FFF800); + data_o[37] = ^(data_o & 39'h00FC000000); + data_o[38] = ^(data_o & 39'h3FFFFFFFFF); + end + +endmodule : caliptra_prim_secded_hamming_39_32_enc diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_hamming_72_64_dec.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_hamming_72_64_dec.sv new file mode 100644 index 0000000..5809cfc --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_hamming_72_64_dec.sv @@ -0,0 +1,95 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// SECDED decoder generated by util/design/secded_gen.py + +module caliptra_prim_secded_hamming_72_64_dec ( + input [71:0] data_i, + output logic [63:0] data_o, + output logic [7:0] syndrome_o, + output logic [1:0] err_o +); + + always_comb begin : p_encode + // Syndrome calculation + syndrome_o[0] = ^(data_i & 72'h01AB55555556AAAD5B); + syndrome_o[1] = ^(data_i & 72'h02CD9999999B33366D); + syndrome_o[2] = ^(data_i & 72'h04F1E1E1E1E3C3C78E); + syndrome_o[3] = ^(data_i & 72'h0801FE01FE03FC07F0); + syndrome_o[4] = ^(data_i & 72'h1001FFFE0003FFF800); + syndrome_o[5] = ^(data_i & 72'h2001FFFFFFFC000000); + syndrome_o[6] = ^(data_i & 72'h40FE00000000000000); + syndrome_o[7] = ^(data_i & 72'hFFFFFFFFFFFFFFFFFF); + + // Corrected output calculation + data_o[0] = (syndrome_o == 8'h83) ^ data_i[0]; + data_o[1] = (syndrome_o == 8'h85) ^ data_i[1]; + data_o[2] = (syndrome_o == 8'h86) ^ data_i[2]; + data_o[3] = (syndrome_o == 8'h87) ^ data_i[3]; + data_o[4] = (syndrome_o == 8'h89) ^ data_i[4]; + data_o[5] = (syndrome_o == 8'h8a) ^ data_i[5]; + data_o[6] = (syndrome_o == 8'h8b) ^ data_i[6]; + data_o[7] = (syndrome_o == 8'h8c) ^ data_i[7]; + data_o[8] = (syndrome_o == 8'h8d) ^ data_i[8]; + data_o[9] = (syndrome_o == 8'h8e) ^ data_i[9]; + data_o[10] = (syndrome_o == 8'h8f) ^ data_i[10]; + data_o[11] = (syndrome_o == 8'h91) ^ data_i[11]; + data_o[12] = (syndrome_o == 8'h92) ^ data_i[12]; + data_o[13] = (syndrome_o == 8'h93) ^ data_i[13]; + data_o[14] = (syndrome_o == 8'h94) ^ data_i[14]; + data_o[15] = (syndrome_o == 8'h95) ^ data_i[15]; + data_o[16] = (syndrome_o == 8'h96) ^ data_i[16]; + data_o[17] = (syndrome_o == 8'h97) ^ data_i[17]; + data_o[18] = (syndrome_o == 8'h98) ^ data_i[18]; + data_o[19] = (syndrome_o == 8'h99) ^ data_i[19]; + data_o[20] = (syndrome_o == 8'h9a) ^ data_i[20]; + data_o[21] = (syndrome_o == 8'h9b) ^ data_i[21]; + data_o[22] = (syndrome_o == 8'h9c) ^ data_i[22]; + data_o[23] = (syndrome_o == 8'h9d) ^ data_i[23]; + data_o[24] = (syndrome_o == 8'h9e) ^ data_i[24]; + data_o[25] = (syndrome_o == 8'h9f) ^ data_i[25]; + data_o[26] = (syndrome_o == 8'ha1) ^ data_i[26]; + data_o[27] = (syndrome_o == 8'ha2) ^ data_i[27]; + data_o[28] = (syndrome_o == 8'ha3) ^ data_i[28]; + data_o[29] = (syndrome_o == 8'ha4) ^ data_i[29]; + data_o[30] = (syndrome_o == 8'ha5) ^ data_i[30]; + data_o[31] = (syndrome_o == 8'ha6) ^ data_i[31]; + data_o[32] = (syndrome_o == 8'ha7) ^ data_i[32]; + data_o[33] = (syndrome_o == 8'ha8) ^ data_i[33]; + data_o[34] = (syndrome_o == 8'ha9) ^ data_i[34]; + data_o[35] = (syndrome_o == 8'haa) ^ data_i[35]; + data_o[36] = (syndrome_o == 8'hab) ^ data_i[36]; + data_o[37] = (syndrome_o == 8'hac) ^ data_i[37]; + data_o[38] = (syndrome_o == 8'had) ^ data_i[38]; + data_o[39] = (syndrome_o == 8'hae) ^ data_i[39]; + data_o[40] = (syndrome_o == 8'haf) ^ data_i[40]; + data_o[41] = (syndrome_o == 8'hb0) ^ data_i[41]; + data_o[42] = (syndrome_o == 8'hb1) ^ data_i[42]; + data_o[43] = (syndrome_o == 8'hb2) ^ data_i[43]; + data_o[44] = (syndrome_o == 8'hb3) ^ data_i[44]; + data_o[45] = (syndrome_o == 8'hb4) ^ data_i[45]; + data_o[46] = (syndrome_o == 8'hb5) ^ data_i[46]; + data_o[47] = (syndrome_o == 8'hb6) ^ data_i[47]; + data_o[48] = (syndrome_o == 8'hb7) ^ data_i[48]; + data_o[49] = (syndrome_o == 8'hb8) ^ data_i[49]; + data_o[50] = (syndrome_o == 8'hb9) ^ data_i[50]; + data_o[51] = (syndrome_o == 8'hba) ^ data_i[51]; + data_o[52] = (syndrome_o == 8'hbb) ^ data_i[52]; + data_o[53] = (syndrome_o == 8'hbc) ^ data_i[53]; + data_o[54] = (syndrome_o == 8'hbd) ^ data_i[54]; + data_o[55] = (syndrome_o == 8'hbe) ^ data_i[55]; + data_o[56] = (syndrome_o == 8'hbf) ^ data_i[56]; + data_o[57] = (syndrome_o == 8'hc1) ^ data_i[57]; + data_o[58] = (syndrome_o == 8'hc2) ^ data_i[58]; + data_o[59] = (syndrome_o == 8'hc3) ^ data_i[59]; + data_o[60] = (syndrome_o == 8'hc4) ^ data_i[60]; + data_o[61] = (syndrome_o == 8'hc5) ^ data_i[61]; + data_o[62] = (syndrome_o == 8'hc6) ^ data_i[62]; + data_o[63] = (syndrome_o == 8'hc7) ^ data_i[63]; + + // err_o calc. bit0: single error, bit1: double error + err_o[0] = syndrome_o[7]; + err_o[1] = |syndrome_o[6:0] & ~syndrome_o[7]; + end +endmodule : caliptra_prim_secded_hamming_72_64_dec diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_hamming_72_64_enc.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_hamming_72_64_enc.sv new file mode 100644 index 0000000..6289dd3 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_hamming_72_64_enc.sv @@ -0,0 +1,24 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// SECDED encoder generated by util/design/secded_gen.py + +module caliptra_prim_secded_hamming_72_64_enc ( + input [63:0] data_i, + output logic [71:0] data_o +); + + always_comb begin : p_encode + data_o = 72'(data_i); + data_o[64] = ^(data_o & 72'h00AB55555556AAAD5B); + data_o[65] = ^(data_o & 72'h00CD9999999B33366D); + data_o[66] = ^(data_o & 72'h00F1E1E1E1E3C3C78E); + data_o[67] = ^(data_o & 72'h0001FE01FE03FC07F0); + data_o[68] = ^(data_o & 72'h0001FFFE0003FFF800); + data_o[69] = ^(data_o & 72'h0001FFFFFFFC000000); + data_o[70] = ^(data_o & 72'h00FE00000000000000); + data_o[71] = ^(data_o & 72'h7FFFFFFFFFFFFFFFFF); + end + +endmodule : caliptra_prim_secded_hamming_72_64_enc diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_hamming_76_68_dec.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_hamming_76_68_dec.sv new file mode 100644 index 0000000..3178eed --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_hamming_76_68_dec.sv @@ -0,0 +1,99 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// SECDED decoder generated by util/design/secded_gen.py + +module caliptra_prim_secded_hamming_76_68_dec ( + input [75:0] data_i, + output logic [67:0] data_o, + output logic [7:0] syndrome_o, + output logic [1:0] err_o +); + + always_comb begin : p_encode + // Syndrome calculation + syndrome_o[0] = ^(data_i & 76'h01AAB55555556AAAD5B); + syndrome_o[1] = ^(data_i & 76'h02CCD9999999B33366D); + syndrome_o[2] = ^(data_i & 76'h040F1E1E1E1E3C3C78E); + syndrome_o[3] = ^(data_i & 76'h08F01FE01FE03FC07F0); + syndrome_o[4] = ^(data_i & 76'h10001FFFE0003FFF800); + syndrome_o[5] = ^(data_i & 76'h20001FFFFFFFC000000); + syndrome_o[6] = ^(data_i & 76'h40FFE00000000000000); + syndrome_o[7] = ^(data_i & 76'hFFFFFFFFFFFFFFFFFFF); + + // Corrected output calculation + data_o[0] = (syndrome_o == 8'h83) ^ data_i[0]; + data_o[1] = (syndrome_o == 8'h85) ^ data_i[1]; + data_o[2] = (syndrome_o == 8'h86) ^ data_i[2]; + data_o[3] = (syndrome_o == 8'h87) ^ data_i[3]; + data_o[4] = (syndrome_o == 8'h89) ^ data_i[4]; + data_o[5] = (syndrome_o == 8'h8a) ^ data_i[5]; + data_o[6] = (syndrome_o == 8'h8b) ^ data_i[6]; + data_o[7] = (syndrome_o == 8'h8c) ^ data_i[7]; + data_o[8] = (syndrome_o == 8'h8d) ^ data_i[8]; + data_o[9] = (syndrome_o == 8'h8e) ^ data_i[9]; + data_o[10] = (syndrome_o == 8'h8f) ^ data_i[10]; + data_o[11] = (syndrome_o == 8'h91) ^ data_i[11]; + data_o[12] = (syndrome_o == 8'h92) ^ data_i[12]; + data_o[13] = (syndrome_o == 8'h93) ^ data_i[13]; + data_o[14] = (syndrome_o == 8'h94) ^ data_i[14]; + data_o[15] = (syndrome_o == 8'h95) ^ data_i[15]; + data_o[16] = (syndrome_o == 8'h96) ^ data_i[16]; + data_o[17] = (syndrome_o == 8'h97) ^ data_i[17]; + data_o[18] = (syndrome_o == 8'h98) ^ data_i[18]; + data_o[19] = (syndrome_o == 8'h99) ^ data_i[19]; + data_o[20] = (syndrome_o == 8'h9a) ^ data_i[20]; + data_o[21] = (syndrome_o == 8'h9b) ^ data_i[21]; + data_o[22] = (syndrome_o == 8'h9c) ^ data_i[22]; + data_o[23] = (syndrome_o == 8'h9d) ^ data_i[23]; + data_o[24] = (syndrome_o == 8'h9e) ^ data_i[24]; + data_o[25] = (syndrome_o == 8'h9f) ^ data_i[25]; + data_o[26] = (syndrome_o == 8'ha1) ^ data_i[26]; + data_o[27] = (syndrome_o == 8'ha2) ^ data_i[27]; + data_o[28] = (syndrome_o == 8'ha3) ^ data_i[28]; + data_o[29] = (syndrome_o == 8'ha4) ^ data_i[29]; + data_o[30] = (syndrome_o == 8'ha5) ^ data_i[30]; + data_o[31] = (syndrome_o == 8'ha6) ^ data_i[31]; + data_o[32] = (syndrome_o == 8'ha7) ^ data_i[32]; + data_o[33] = (syndrome_o == 8'ha8) ^ data_i[33]; + data_o[34] = (syndrome_o == 8'ha9) ^ data_i[34]; + data_o[35] = (syndrome_o == 8'haa) ^ data_i[35]; + data_o[36] = (syndrome_o == 8'hab) ^ data_i[36]; + data_o[37] = (syndrome_o == 8'hac) ^ data_i[37]; + data_o[38] = (syndrome_o == 8'had) ^ data_i[38]; + data_o[39] = (syndrome_o == 8'hae) ^ data_i[39]; + data_o[40] = (syndrome_o == 8'haf) ^ data_i[40]; + data_o[41] = (syndrome_o == 8'hb0) ^ data_i[41]; + data_o[42] = (syndrome_o == 8'hb1) ^ data_i[42]; + data_o[43] = (syndrome_o == 8'hb2) ^ data_i[43]; + data_o[44] = (syndrome_o == 8'hb3) ^ data_i[44]; + data_o[45] = (syndrome_o == 8'hb4) ^ data_i[45]; + data_o[46] = (syndrome_o == 8'hb5) ^ data_i[46]; + data_o[47] = (syndrome_o == 8'hb6) ^ data_i[47]; + data_o[48] = (syndrome_o == 8'hb7) ^ data_i[48]; + data_o[49] = (syndrome_o == 8'hb8) ^ data_i[49]; + data_o[50] = (syndrome_o == 8'hb9) ^ data_i[50]; + data_o[51] = (syndrome_o == 8'hba) ^ data_i[51]; + data_o[52] = (syndrome_o == 8'hbb) ^ data_i[52]; + data_o[53] = (syndrome_o == 8'hbc) ^ data_i[53]; + data_o[54] = (syndrome_o == 8'hbd) ^ data_i[54]; + data_o[55] = (syndrome_o == 8'hbe) ^ data_i[55]; + data_o[56] = (syndrome_o == 8'hbf) ^ data_i[56]; + data_o[57] = (syndrome_o == 8'hc1) ^ data_i[57]; + data_o[58] = (syndrome_o == 8'hc2) ^ data_i[58]; + data_o[59] = (syndrome_o == 8'hc3) ^ data_i[59]; + data_o[60] = (syndrome_o == 8'hc4) ^ data_i[60]; + data_o[61] = (syndrome_o == 8'hc5) ^ data_i[61]; + data_o[62] = (syndrome_o == 8'hc6) ^ data_i[62]; + data_o[63] = (syndrome_o == 8'hc7) ^ data_i[63]; + data_o[64] = (syndrome_o == 8'hc8) ^ data_i[64]; + data_o[65] = (syndrome_o == 8'hc9) ^ data_i[65]; + data_o[66] = (syndrome_o == 8'hca) ^ data_i[66]; + data_o[67] = (syndrome_o == 8'hcb) ^ data_i[67]; + + // err_o calc. bit0: single error, bit1: double error + err_o[0] = syndrome_o[7]; + err_o[1] = |syndrome_o[6:0] & ~syndrome_o[7]; + end +endmodule : caliptra_prim_secded_hamming_76_68_dec diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_hamming_76_68_enc.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_hamming_76_68_enc.sv new file mode 100644 index 0000000..13643a4 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_hamming_76_68_enc.sv @@ -0,0 +1,24 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// SECDED encoder generated by util/design/secded_gen.py + +module caliptra_prim_secded_hamming_76_68_enc ( + input [67:0] data_i, + output logic [75:0] data_o +); + + always_comb begin : p_encode + data_o = 76'(data_i); + data_o[68] = ^(data_o & 76'h00AAB55555556AAAD5B); + data_o[69] = ^(data_o & 76'h00CCD9999999B33366D); + data_o[70] = ^(data_o & 76'h000F1E1E1E1E3C3C78E); + data_o[71] = ^(data_o & 76'h00F01FE01FE03FC07F0); + data_o[72] = ^(data_o & 76'h00001FFFE0003FFF800); + data_o[73] = ^(data_o & 76'h00001FFFFFFFC000000); + data_o[74] = ^(data_o & 76'h00FFE00000000000000); + data_o[75] = ^(data_o & 76'h7FFFFFFFFFFFFFFFFFF); + end + +endmodule : caliptra_prim_secded_hamming_76_68_enc diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_inv_22_16_dec.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_inv_22_16_dec.sv new file mode 100644 index 0000000..f89aa81 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_inv_22_16_dec.sv @@ -0,0 +1,45 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// SECDED decoder generated by util/design/secded_gen.py + +module caliptra_prim_secded_inv_22_16_dec ( + input [21:0] data_i, + output logic [15:0] data_o, + output logic [5:0] syndrome_o, + output logic [1:0] err_o +); + + always_comb begin : p_encode + // Syndrome calculation + syndrome_o[0] = ^((data_i ^ 22'h2A0000) & 22'h01496E); + syndrome_o[1] = ^((data_i ^ 22'h2A0000) & 22'h02F20B); + syndrome_o[2] = ^((data_i ^ 22'h2A0000) & 22'h048ED8); + syndrome_o[3] = ^((data_i ^ 22'h2A0000) & 22'h087714); + syndrome_o[4] = ^((data_i ^ 22'h2A0000) & 22'h10ACA5); + syndrome_o[5] = ^((data_i ^ 22'h2A0000) & 22'h2011F3); + + // Corrected output calculation + data_o[0] = (syndrome_o == 6'h32) ^ data_i[0]; + data_o[1] = (syndrome_o == 6'h23) ^ data_i[1]; + data_o[2] = (syndrome_o == 6'h19) ^ data_i[2]; + data_o[3] = (syndrome_o == 6'h7) ^ data_i[3]; + data_o[4] = (syndrome_o == 6'h2c) ^ data_i[4]; + data_o[5] = (syndrome_o == 6'h31) ^ data_i[5]; + data_o[6] = (syndrome_o == 6'h25) ^ data_i[6]; + data_o[7] = (syndrome_o == 6'h34) ^ data_i[7]; + data_o[8] = (syndrome_o == 6'h29) ^ data_i[8]; + data_o[9] = (syndrome_o == 6'he) ^ data_i[9]; + data_o[10] = (syndrome_o == 6'h1c) ^ data_i[10]; + data_o[11] = (syndrome_o == 6'h15) ^ data_i[11]; + data_o[12] = (syndrome_o == 6'h2a) ^ data_i[12]; + data_o[13] = (syndrome_o == 6'h1a) ^ data_i[13]; + data_o[14] = (syndrome_o == 6'hb) ^ data_i[14]; + data_o[15] = (syndrome_o == 6'h16) ^ data_i[15]; + + // err_o calc. bit0: single error, bit1: double error + err_o[0] = ^syndrome_o; + err_o[1] = ~err_o[0] & (|syndrome_o); + end +endmodule : caliptra_prim_secded_inv_22_16_dec diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_inv_22_16_enc.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_inv_22_16_enc.sv new file mode 100644 index 0000000..c8726f7 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_inv_22_16_enc.sv @@ -0,0 +1,23 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// SECDED encoder generated by util/design/secded_gen.py + +module caliptra_prim_secded_inv_22_16_enc ( + input [15:0] data_i, + output logic [21:0] data_o +); + + always_comb begin : p_encode + data_o = 22'(data_i); + data_o[16] = ^(data_o & 22'h00496E); + data_o[17] = ^(data_o & 22'h00F20B); + data_o[18] = ^(data_o & 22'h008ED8); + data_o[19] = ^(data_o & 22'h007714); + data_o[20] = ^(data_o & 22'h00ACA5); + data_o[21] = ^(data_o & 22'h0011F3); + data_o ^= 22'h2A0000; + end + +endmodule : caliptra_prim_secded_inv_22_16_enc diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_inv_28_22_dec.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_inv_28_22_dec.sv new file mode 100644 index 0000000..57b2c17 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_inv_28_22_dec.sv @@ -0,0 +1,51 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// SECDED decoder generated by util/design/secded_gen.py + +module caliptra_prim_secded_inv_28_22_dec ( + input [27:0] data_i, + output logic [21:0] data_o, + output logic [5:0] syndrome_o, + output logic [1:0] err_o +); + + always_comb begin : p_encode + // Syndrome calculation + syndrome_o[0] = ^((data_i ^ 28'hA800000) & 28'h07003FF); + syndrome_o[1] = ^((data_i ^ 28'hA800000) & 28'h090FC0F); + syndrome_o[2] = ^((data_i ^ 28'hA800000) & 28'h1271C71); + syndrome_o[3] = ^((data_i ^ 28'hA800000) & 28'h23B6592); + syndrome_o[4] = ^((data_i ^ 28'hA800000) & 28'h43DAAA4); + syndrome_o[5] = ^((data_i ^ 28'hA800000) & 28'h83ED348); + + // Corrected output calculation + data_o[0] = (syndrome_o == 6'h7) ^ data_i[0]; + data_o[1] = (syndrome_o == 6'hb) ^ data_i[1]; + data_o[2] = (syndrome_o == 6'h13) ^ data_i[2]; + data_o[3] = (syndrome_o == 6'h23) ^ data_i[3]; + data_o[4] = (syndrome_o == 6'hd) ^ data_i[4]; + data_o[5] = (syndrome_o == 6'h15) ^ data_i[5]; + data_o[6] = (syndrome_o == 6'h25) ^ data_i[6]; + data_o[7] = (syndrome_o == 6'h19) ^ data_i[7]; + data_o[8] = (syndrome_o == 6'h29) ^ data_i[8]; + data_o[9] = (syndrome_o == 6'h31) ^ data_i[9]; + data_o[10] = (syndrome_o == 6'he) ^ data_i[10]; + data_o[11] = (syndrome_o == 6'h16) ^ data_i[11]; + data_o[12] = (syndrome_o == 6'h26) ^ data_i[12]; + data_o[13] = (syndrome_o == 6'h1a) ^ data_i[13]; + data_o[14] = (syndrome_o == 6'h2a) ^ data_i[14]; + data_o[15] = (syndrome_o == 6'h32) ^ data_i[15]; + data_o[16] = (syndrome_o == 6'h1c) ^ data_i[16]; + data_o[17] = (syndrome_o == 6'h2c) ^ data_i[17]; + data_o[18] = (syndrome_o == 6'h34) ^ data_i[18]; + data_o[19] = (syndrome_o == 6'h38) ^ data_i[19]; + data_o[20] = (syndrome_o == 6'h3b) ^ data_i[20]; + data_o[21] = (syndrome_o == 6'h3d) ^ data_i[21]; + + // err_o calc. bit0: single error, bit1: double error + err_o[0] = ^syndrome_o; + err_o[1] = ~err_o[0] & (|syndrome_o); + end +endmodule : caliptra_prim_secded_inv_28_22_dec diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_inv_28_22_enc.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_inv_28_22_enc.sv new file mode 100644 index 0000000..a847398 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_inv_28_22_enc.sv @@ -0,0 +1,23 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// SECDED encoder generated by util/design/secded_gen.py + +module caliptra_prim_secded_inv_28_22_enc ( + input [21:0] data_i, + output logic [27:0] data_o +); + + always_comb begin : p_encode + data_o = 28'(data_i); + data_o[22] = ^(data_o & 28'h03003FF); + data_o[23] = ^(data_o & 28'h010FC0F); + data_o[24] = ^(data_o & 28'h0271C71); + data_o[25] = ^(data_o & 28'h03B6592); + data_o[26] = ^(data_o & 28'h03DAAA4); + data_o[27] = ^(data_o & 28'h03ED348); + data_o ^= 28'hA800000; + end + +endmodule : caliptra_prim_secded_inv_28_22_enc diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_inv_39_32_dec.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_inv_39_32_dec.sv new file mode 100644 index 0000000..677c174 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_inv_39_32_dec.sv @@ -0,0 +1,62 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// SECDED decoder generated by util/design/secded_gen.py + +module caliptra_prim_secded_inv_39_32_dec ( + input [38:0] data_i, + output logic [31:0] data_o, + output logic [6:0] syndrome_o, + output logic [1:0] err_o +); + + always_comb begin : p_encode + // Syndrome calculation + syndrome_o[0] = ^((data_i ^ 39'h2A00000000) & 39'h012606BD25); + syndrome_o[1] = ^((data_i ^ 39'h2A00000000) & 39'h02DEBA8050); + syndrome_o[2] = ^((data_i ^ 39'h2A00000000) & 39'h04413D89AA); + syndrome_o[3] = ^((data_i ^ 39'h2A00000000) & 39'h0831234ED1); + syndrome_o[4] = ^((data_i ^ 39'h2A00000000) & 39'h10C2C1323B); + syndrome_o[5] = ^((data_i ^ 39'h2A00000000) & 39'h202DCC624C); + syndrome_o[6] = ^((data_i ^ 39'h2A00000000) & 39'h4098505586); + + // Corrected output calculation + data_o[0] = (syndrome_o == 7'h19) ^ data_i[0]; + data_o[1] = (syndrome_o == 7'h54) ^ data_i[1]; + data_o[2] = (syndrome_o == 7'h61) ^ data_i[2]; + data_o[3] = (syndrome_o == 7'h34) ^ data_i[3]; + data_o[4] = (syndrome_o == 7'h1a) ^ data_i[4]; + data_o[5] = (syndrome_o == 7'h15) ^ data_i[5]; + data_o[6] = (syndrome_o == 7'h2a) ^ data_i[6]; + data_o[7] = (syndrome_o == 7'h4c) ^ data_i[7]; + data_o[8] = (syndrome_o == 7'h45) ^ data_i[8]; + data_o[9] = (syndrome_o == 7'h38) ^ data_i[9]; + data_o[10] = (syndrome_o == 7'h49) ^ data_i[10]; + data_o[11] = (syndrome_o == 7'hd) ^ data_i[11]; + data_o[12] = (syndrome_o == 7'h51) ^ data_i[12]; + data_o[13] = (syndrome_o == 7'h31) ^ data_i[13]; + data_o[14] = (syndrome_o == 7'h68) ^ data_i[14]; + data_o[15] = (syndrome_o == 7'h7) ^ data_i[15]; + data_o[16] = (syndrome_o == 7'h1c) ^ data_i[16]; + data_o[17] = (syndrome_o == 7'hb) ^ data_i[17]; + data_o[18] = (syndrome_o == 7'h25) ^ data_i[18]; + data_o[19] = (syndrome_o == 7'h26) ^ data_i[19]; + data_o[20] = (syndrome_o == 7'h46) ^ data_i[20]; + data_o[21] = (syndrome_o == 7'he) ^ data_i[21]; + data_o[22] = (syndrome_o == 7'h70) ^ data_i[22]; + data_o[23] = (syndrome_o == 7'h32) ^ data_i[23]; + data_o[24] = (syndrome_o == 7'h2c) ^ data_i[24]; + data_o[25] = (syndrome_o == 7'h13) ^ data_i[25]; + data_o[26] = (syndrome_o == 7'h23) ^ data_i[26]; + data_o[27] = (syndrome_o == 7'h62) ^ data_i[27]; + data_o[28] = (syndrome_o == 7'h4a) ^ data_i[28]; + data_o[29] = (syndrome_o == 7'h29) ^ data_i[29]; + data_o[30] = (syndrome_o == 7'h16) ^ data_i[30]; + data_o[31] = (syndrome_o == 7'h52) ^ data_i[31]; + + // err_o calc. bit0: single error, bit1: double error + err_o[0] = ^syndrome_o; + err_o[1] = ~err_o[0] & (|syndrome_o); + end +endmodule : caliptra_prim_secded_inv_39_32_dec diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_inv_39_32_enc.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_inv_39_32_enc.sv new file mode 100644 index 0000000..1cbd66a --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_inv_39_32_enc.sv @@ -0,0 +1,24 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// SECDED encoder generated by util/design/secded_gen.py + +module caliptra_prim_secded_inv_39_32_enc ( + input [31:0] data_i, + output logic [38:0] data_o +); + + always_comb begin : p_encode + data_o = 39'(data_i); + data_o[32] = ^(data_o & 39'h002606BD25); + data_o[33] = ^(data_o & 39'h00DEBA8050); + data_o[34] = ^(data_o & 39'h00413D89AA); + data_o[35] = ^(data_o & 39'h0031234ED1); + data_o[36] = ^(data_o & 39'h00C2C1323B); + data_o[37] = ^(data_o & 39'h002DCC624C); + data_o[38] = ^(data_o & 39'h0098505586); + data_o ^= 39'h2A00000000; + end + +endmodule : caliptra_prim_secded_inv_39_32_enc diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_inv_64_57_dec.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_inv_64_57_dec.sv new file mode 100644 index 0000000..28fad1d --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_inv_64_57_dec.sv @@ -0,0 +1,87 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// SECDED decoder generated by util/design/secded_gen.py + +module caliptra_prim_secded_inv_64_57_dec ( + input [63:0] data_i, + output logic [56:0] data_o, + output logic [6:0] syndrome_o, + output logic [1:0] err_o +); + + always_comb begin : p_encode + // Syndrome calculation + syndrome_o[0] = ^((data_i ^ 64'h5400000000000000) & 64'h0303FFF800007FFF); + syndrome_o[1] = ^((data_i ^ 64'h5400000000000000) & 64'h057C1FF801FF801F); + syndrome_o[2] = ^((data_i ^ 64'h5400000000000000) & 64'h09BDE1F87E0781E1); + syndrome_o[3] = ^((data_i ^ 64'h5400000000000000) & 64'h11DEEE3B8E388E22); + syndrome_o[4] = ^((data_i ^ 64'h5400000000000000) & 64'h21EF76CDB2C93244); + syndrome_o[5] = ^((data_i ^ 64'h5400000000000000) & 64'h41F7BB56D5525488); + syndrome_o[6] = ^((data_i ^ 64'h5400000000000000) & 64'h81FBDDA769A46910); + + // Corrected output calculation + data_o[0] = (syndrome_o == 7'h7) ^ data_i[0]; + data_o[1] = (syndrome_o == 7'hb) ^ data_i[1]; + data_o[2] = (syndrome_o == 7'h13) ^ data_i[2]; + data_o[3] = (syndrome_o == 7'h23) ^ data_i[3]; + data_o[4] = (syndrome_o == 7'h43) ^ data_i[4]; + data_o[5] = (syndrome_o == 7'hd) ^ data_i[5]; + data_o[6] = (syndrome_o == 7'h15) ^ data_i[6]; + data_o[7] = (syndrome_o == 7'h25) ^ data_i[7]; + data_o[8] = (syndrome_o == 7'h45) ^ data_i[8]; + data_o[9] = (syndrome_o == 7'h19) ^ data_i[9]; + data_o[10] = (syndrome_o == 7'h29) ^ data_i[10]; + data_o[11] = (syndrome_o == 7'h49) ^ data_i[11]; + data_o[12] = (syndrome_o == 7'h31) ^ data_i[12]; + data_o[13] = (syndrome_o == 7'h51) ^ data_i[13]; + data_o[14] = (syndrome_o == 7'h61) ^ data_i[14]; + data_o[15] = (syndrome_o == 7'he) ^ data_i[15]; + data_o[16] = (syndrome_o == 7'h16) ^ data_i[16]; + data_o[17] = (syndrome_o == 7'h26) ^ data_i[17]; + data_o[18] = (syndrome_o == 7'h46) ^ data_i[18]; + data_o[19] = (syndrome_o == 7'h1a) ^ data_i[19]; + data_o[20] = (syndrome_o == 7'h2a) ^ data_i[20]; + data_o[21] = (syndrome_o == 7'h4a) ^ data_i[21]; + data_o[22] = (syndrome_o == 7'h32) ^ data_i[22]; + data_o[23] = (syndrome_o == 7'h52) ^ data_i[23]; + data_o[24] = (syndrome_o == 7'h62) ^ data_i[24]; + data_o[25] = (syndrome_o == 7'h1c) ^ data_i[25]; + data_o[26] = (syndrome_o == 7'h2c) ^ data_i[26]; + data_o[27] = (syndrome_o == 7'h4c) ^ data_i[27]; + data_o[28] = (syndrome_o == 7'h34) ^ data_i[28]; + data_o[29] = (syndrome_o == 7'h54) ^ data_i[29]; + data_o[30] = (syndrome_o == 7'h64) ^ data_i[30]; + data_o[31] = (syndrome_o == 7'h38) ^ data_i[31]; + data_o[32] = (syndrome_o == 7'h58) ^ data_i[32]; + data_o[33] = (syndrome_o == 7'h68) ^ data_i[33]; + data_o[34] = (syndrome_o == 7'h70) ^ data_i[34]; + data_o[35] = (syndrome_o == 7'h1f) ^ data_i[35]; + data_o[36] = (syndrome_o == 7'h2f) ^ data_i[36]; + data_o[37] = (syndrome_o == 7'h4f) ^ data_i[37]; + data_o[38] = (syndrome_o == 7'h37) ^ data_i[38]; + data_o[39] = (syndrome_o == 7'h57) ^ data_i[39]; + data_o[40] = (syndrome_o == 7'h67) ^ data_i[40]; + data_o[41] = (syndrome_o == 7'h3b) ^ data_i[41]; + data_o[42] = (syndrome_o == 7'h5b) ^ data_i[42]; + data_o[43] = (syndrome_o == 7'h6b) ^ data_i[43]; + data_o[44] = (syndrome_o == 7'h73) ^ data_i[44]; + data_o[45] = (syndrome_o == 7'h3d) ^ data_i[45]; + data_o[46] = (syndrome_o == 7'h5d) ^ data_i[46]; + data_o[47] = (syndrome_o == 7'h6d) ^ data_i[47]; + data_o[48] = (syndrome_o == 7'h75) ^ data_i[48]; + data_o[49] = (syndrome_o == 7'h79) ^ data_i[49]; + data_o[50] = (syndrome_o == 7'h3e) ^ data_i[50]; + data_o[51] = (syndrome_o == 7'h5e) ^ data_i[51]; + data_o[52] = (syndrome_o == 7'h6e) ^ data_i[52]; + data_o[53] = (syndrome_o == 7'h76) ^ data_i[53]; + data_o[54] = (syndrome_o == 7'h7a) ^ data_i[54]; + data_o[55] = (syndrome_o == 7'h7c) ^ data_i[55]; + data_o[56] = (syndrome_o == 7'h7f) ^ data_i[56]; + + // err_o calc. bit0: single error, bit1: double error + err_o[0] = ^syndrome_o; + err_o[1] = ~err_o[0] & (|syndrome_o); + end +endmodule : caliptra_prim_secded_inv_64_57_dec diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_inv_64_57_enc.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_inv_64_57_enc.sv new file mode 100644 index 0000000..b491a42 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_inv_64_57_enc.sv @@ -0,0 +1,24 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// SECDED encoder generated by util/design/secded_gen.py + +module caliptra_prim_secded_inv_64_57_enc ( + input [56:0] data_i, + output logic [63:0] data_o +); + + always_comb begin : p_encode + data_o = 64'(data_i); + data_o[57] = ^(data_o & 64'h0103FFF800007FFF); + data_o[58] = ^(data_o & 64'h017C1FF801FF801F); + data_o[59] = ^(data_o & 64'h01BDE1F87E0781E1); + data_o[60] = ^(data_o & 64'h01DEEE3B8E388E22); + data_o[61] = ^(data_o & 64'h01EF76CDB2C93244); + data_o[62] = ^(data_o & 64'h01F7BB56D5525488); + data_o[63] = ^(data_o & 64'h01FBDDA769A46910); + data_o ^= 64'h5400000000000000; + end + +endmodule : caliptra_prim_secded_inv_64_57_enc diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_inv_72_64_dec.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_inv_72_64_dec.sv new file mode 100644 index 0000000..13fa06a --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_inv_72_64_dec.sv @@ -0,0 +1,95 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// SECDED decoder generated by util/design/secded_gen.py + +module caliptra_prim_secded_inv_72_64_dec ( + input [71:0] data_i, + output logic [63:0] data_o, + output logic [7:0] syndrome_o, + output logic [1:0] err_o +); + + always_comb begin : p_encode + // Syndrome calculation + syndrome_o[0] = ^((data_i ^ 72'hAA0000000000000000) & 72'h01B9000000001FFFFF); + syndrome_o[1] = ^((data_i ^ 72'hAA0000000000000000) & 72'h025E00000FFFE0003F); + syndrome_o[2] = ^((data_i ^ 72'hAA0000000000000000) & 72'h0467003FF003E007C1); + syndrome_o[3] = ^((data_i ^ 72'hAA0000000000000000) & 72'h08CD0FC0F03C207842); + syndrome_o[4] = ^((data_i ^ 72'hAA0000000000000000) & 72'h10B671C711C4438884); + syndrome_o[5] = ^((data_i ^ 72'hAA0000000000000000) & 72'h20B5B65926488C9108); + syndrome_o[6] = ^((data_i ^ 72'hAA0000000000000000) & 72'h40CBDAAA4A91152210); + syndrome_o[7] = ^((data_i ^ 72'hAA0000000000000000) & 72'h807AED348D221A4420); + + // Corrected output calculation + data_o[0] = (syndrome_o == 8'h7) ^ data_i[0]; + data_o[1] = (syndrome_o == 8'hb) ^ data_i[1]; + data_o[2] = (syndrome_o == 8'h13) ^ data_i[2]; + data_o[3] = (syndrome_o == 8'h23) ^ data_i[3]; + data_o[4] = (syndrome_o == 8'h43) ^ data_i[4]; + data_o[5] = (syndrome_o == 8'h83) ^ data_i[5]; + data_o[6] = (syndrome_o == 8'hd) ^ data_i[6]; + data_o[7] = (syndrome_o == 8'h15) ^ data_i[7]; + data_o[8] = (syndrome_o == 8'h25) ^ data_i[8]; + data_o[9] = (syndrome_o == 8'h45) ^ data_i[9]; + data_o[10] = (syndrome_o == 8'h85) ^ data_i[10]; + data_o[11] = (syndrome_o == 8'h19) ^ data_i[11]; + data_o[12] = (syndrome_o == 8'h29) ^ data_i[12]; + data_o[13] = (syndrome_o == 8'h49) ^ data_i[13]; + data_o[14] = (syndrome_o == 8'h89) ^ data_i[14]; + data_o[15] = (syndrome_o == 8'h31) ^ data_i[15]; + data_o[16] = (syndrome_o == 8'h51) ^ data_i[16]; + data_o[17] = (syndrome_o == 8'h91) ^ data_i[17]; + data_o[18] = (syndrome_o == 8'h61) ^ data_i[18]; + data_o[19] = (syndrome_o == 8'ha1) ^ data_i[19]; + data_o[20] = (syndrome_o == 8'hc1) ^ data_i[20]; + data_o[21] = (syndrome_o == 8'he) ^ data_i[21]; + data_o[22] = (syndrome_o == 8'h16) ^ data_i[22]; + data_o[23] = (syndrome_o == 8'h26) ^ data_i[23]; + data_o[24] = (syndrome_o == 8'h46) ^ data_i[24]; + data_o[25] = (syndrome_o == 8'h86) ^ data_i[25]; + data_o[26] = (syndrome_o == 8'h1a) ^ data_i[26]; + data_o[27] = (syndrome_o == 8'h2a) ^ data_i[27]; + data_o[28] = (syndrome_o == 8'h4a) ^ data_i[28]; + data_o[29] = (syndrome_o == 8'h8a) ^ data_i[29]; + data_o[30] = (syndrome_o == 8'h32) ^ data_i[30]; + data_o[31] = (syndrome_o == 8'h52) ^ data_i[31]; + data_o[32] = (syndrome_o == 8'h92) ^ data_i[32]; + data_o[33] = (syndrome_o == 8'h62) ^ data_i[33]; + data_o[34] = (syndrome_o == 8'ha2) ^ data_i[34]; + data_o[35] = (syndrome_o == 8'hc2) ^ data_i[35]; + data_o[36] = (syndrome_o == 8'h1c) ^ data_i[36]; + data_o[37] = (syndrome_o == 8'h2c) ^ data_i[37]; + data_o[38] = (syndrome_o == 8'h4c) ^ data_i[38]; + data_o[39] = (syndrome_o == 8'h8c) ^ data_i[39]; + data_o[40] = (syndrome_o == 8'h34) ^ data_i[40]; + data_o[41] = (syndrome_o == 8'h54) ^ data_i[41]; + data_o[42] = (syndrome_o == 8'h94) ^ data_i[42]; + data_o[43] = (syndrome_o == 8'h64) ^ data_i[43]; + data_o[44] = (syndrome_o == 8'ha4) ^ data_i[44]; + data_o[45] = (syndrome_o == 8'hc4) ^ data_i[45]; + data_o[46] = (syndrome_o == 8'h38) ^ data_i[46]; + data_o[47] = (syndrome_o == 8'h58) ^ data_i[47]; + data_o[48] = (syndrome_o == 8'h98) ^ data_i[48]; + data_o[49] = (syndrome_o == 8'h68) ^ data_i[49]; + data_o[50] = (syndrome_o == 8'ha8) ^ data_i[50]; + data_o[51] = (syndrome_o == 8'hc8) ^ data_i[51]; + data_o[52] = (syndrome_o == 8'h70) ^ data_i[52]; + data_o[53] = (syndrome_o == 8'hb0) ^ data_i[53]; + data_o[54] = (syndrome_o == 8'hd0) ^ data_i[54]; + data_o[55] = (syndrome_o == 8'he0) ^ data_i[55]; + data_o[56] = (syndrome_o == 8'h6d) ^ data_i[56]; + data_o[57] = (syndrome_o == 8'hd6) ^ data_i[57]; + data_o[58] = (syndrome_o == 8'h3e) ^ data_i[58]; + data_o[59] = (syndrome_o == 8'hcb) ^ data_i[59]; + data_o[60] = (syndrome_o == 8'hb3) ^ data_i[60]; + data_o[61] = (syndrome_o == 8'hb5) ^ data_i[61]; + data_o[62] = (syndrome_o == 8'hce) ^ data_i[62]; + data_o[63] = (syndrome_o == 8'h79) ^ data_i[63]; + + // err_o calc. bit0: single error, bit1: double error + err_o[0] = ^syndrome_o; + err_o[1] = ~err_o[0] & (|syndrome_o); + end +endmodule : caliptra_prim_secded_inv_72_64_dec diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_inv_72_64_enc.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_inv_72_64_enc.sv new file mode 100644 index 0000000..ba2d458 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_inv_72_64_enc.sv @@ -0,0 +1,25 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// SECDED encoder generated by util/design/secded_gen.py + +module caliptra_prim_secded_inv_72_64_enc ( + input [63:0] data_i, + output logic [71:0] data_o +); + + always_comb begin : p_encode + data_o = 72'(data_i); + data_o[64] = ^(data_o & 72'h00B9000000001FFFFF); + data_o[65] = ^(data_o & 72'h005E00000FFFE0003F); + data_o[66] = ^(data_o & 72'h0067003FF003E007C1); + data_o[67] = ^(data_o & 72'h00CD0FC0F03C207842); + data_o[68] = ^(data_o & 72'h00B671C711C4438884); + data_o[69] = ^(data_o & 72'h00B5B65926488C9108); + data_o[70] = ^(data_o & 72'h00CBDAAA4A91152210); + data_o[71] = ^(data_o & 72'h007AED348D221A4420); + data_o ^= 72'hAA0000000000000000; + end + +endmodule : caliptra_prim_secded_inv_72_64_enc diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_inv_hamming_22_16_dec.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_inv_hamming_22_16_dec.sv new file mode 100644 index 0000000..7a76ccc --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_inv_hamming_22_16_dec.sv @@ -0,0 +1,45 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// SECDED decoder generated by util/design/secded_gen.py + +module caliptra_prim_secded_inv_hamming_22_16_dec ( + input [21:0] data_i, + output logic [15:0] data_o, + output logic [5:0] syndrome_o, + output logic [1:0] err_o +); + + always_comb begin : p_encode + // Syndrome calculation + syndrome_o[0] = ^((data_i ^ 22'h2A0000) & 22'h01AD5B); + syndrome_o[1] = ^((data_i ^ 22'h2A0000) & 22'h02366D); + syndrome_o[2] = ^((data_i ^ 22'h2A0000) & 22'h04C78E); + syndrome_o[3] = ^((data_i ^ 22'h2A0000) & 22'h0807F0); + syndrome_o[4] = ^((data_i ^ 22'h2A0000) & 22'h10F800); + syndrome_o[5] = ^((data_i ^ 22'h2A0000) & 22'h3FFFFF); + + // Corrected output calculation + data_o[0] = (syndrome_o == 6'h23) ^ data_i[0]; + data_o[1] = (syndrome_o == 6'h25) ^ data_i[1]; + data_o[2] = (syndrome_o == 6'h26) ^ data_i[2]; + data_o[3] = (syndrome_o == 6'h27) ^ data_i[3]; + data_o[4] = (syndrome_o == 6'h29) ^ data_i[4]; + data_o[5] = (syndrome_o == 6'h2a) ^ data_i[5]; + data_o[6] = (syndrome_o == 6'h2b) ^ data_i[6]; + data_o[7] = (syndrome_o == 6'h2c) ^ data_i[7]; + data_o[8] = (syndrome_o == 6'h2d) ^ data_i[8]; + data_o[9] = (syndrome_o == 6'h2e) ^ data_i[9]; + data_o[10] = (syndrome_o == 6'h2f) ^ data_i[10]; + data_o[11] = (syndrome_o == 6'h31) ^ data_i[11]; + data_o[12] = (syndrome_o == 6'h32) ^ data_i[12]; + data_o[13] = (syndrome_o == 6'h33) ^ data_i[13]; + data_o[14] = (syndrome_o == 6'h34) ^ data_i[14]; + data_o[15] = (syndrome_o == 6'h35) ^ data_i[15]; + + // err_o calc. bit0: single error, bit1: double error + err_o[0] = syndrome_o[5]; + err_o[1] = |syndrome_o[4:0] & ~syndrome_o[5]; + end +endmodule : caliptra_prim_secded_inv_hamming_22_16_dec diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_inv_hamming_22_16_enc.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_inv_hamming_22_16_enc.sv new file mode 100644 index 0000000..2190d1a --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_inv_hamming_22_16_enc.sv @@ -0,0 +1,23 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// SECDED encoder generated by util/design/secded_gen.py + +module caliptra_prim_secded_inv_hamming_22_16_enc ( + input [15:0] data_i, + output logic [21:0] data_o +); + + always_comb begin : p_encode + data_o = 22'(data_i); + data_o[16] = ^(data_o & 22'h00AD5B); + data_o[17] = ^(data_o & 22'h00366D); + data_o[18] = ^(data_o & 22'h00C78E); + data_o[19] = ^(data_o & 22'h0007F0); + data_o[20] = ^(data_o & 22'h00F800); + data_o[21] = ^(data_o & 22'h1FFFFF); + data_o ^= 22'h2A0000; + end + +endmodule : caliptra_prim_secded_inv_hamming_22_16_enc diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_inv_hamming_39_32_dec.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_inv_hamming_39_32_dec.sv new file mode 100644 index 0000000..e63f577 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_inv_hamming_39_32_dec.sv @@ -0,0 +1,62 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// SECDED decoder generated by util/design/secded_gen.py + +module caliptra_prim_secded_inv_hamming_39_32_dec ( + input [38:0] data_i, + output logic [31:0] data_o, + output logic [6:0] syndrome_o, + output logic [1:0] err_o +); + + always_comb begin : p_encode + // Syndrome calculation + syndrome_o[0] = ^((data_i ^ 39'h2A00000000) & 39'h0156AAAD5B); + syndrome_o[1] = ^((data_i ^ 39'h2A00000000) & 39'h029B33366D); + syndrome_o[2] = ^((data_i ^ 39'h2A00000000) & 39'h04E3C3C78E); + syndrome_o[3] = ^((data_i ^ 39'h2A00000000) & 39'h0803FC07F0); + syndrome_o[4] = ^((data_i ^ 39'h2A00000000) & 39'h1003FFF800); + syndrome_o[5] = ^((data_i ^ 39'h2A00000000) & 39'h20FC000000); + syndrome_o[6] = ^((data_i ^ 39'h2A00000000) & 39'h7FFFFFFFFF); + + // Corrected output calculation + data_o[0] = (syndrome_o == 7'h43) ^ data_i[0]; + data_o[1] = (syndrome_o == 7'h45) ^ data_i[1]; + data_o[2] = (syndrome_o == 7'h46) ^ data_i[2]; + data_o[3] = (syndrome_o == 7'h47) ^ data_i[3]; + data_o[4] = (syndrome_o == 7'h49) ^ data_i[4]; + data_o[5] = (syndrome_o == 7'h4a) ^ data_i[5]; + data_o[6] = (syndrome_o == 7'h4b) ^ data_i[6]; + data_o[7] = (syndrome_o == 7'h4c) ^ data_i[7]; + data_o[8] = (syndrome_o == 7'h4d) ^ data_i[8]; + data_o[9] = (syndrome_o == 7'h4e) ^ data_i[9]; + data_o[10] = (syndrome_o == 7'h4f) ^ data_i[10]; + data_o[11] = (syndrome_o == 7'h51) ^ data_i[11]; + data_o[12] = (syndrome_o == 7'h52) ^ data_i[12]; + data_o[13] = (syndrome_o == 7'h53) ^ data_i[13]; + data_o[14] = (syndrome_o == 7'h54) ^ data_i[14]; + data_o[15] = (syndrome_o == 7'h55) ^ data_i[15]; + data_o[16] = (syndrome_o == 7'h56) ^ data_i[16]; + data_o[17] = (syndrome_o == 7'h57) ^ data_i[17]; + data_o[18] = (syndrome_o == 7'h58) ^ data_i[18]; + data_o[19] = (syndrome_o == 7'h59) ^ data_i[19]; + data_o[20] = (syndrome_o == 7'h5a) ^ data_i[20]; + data_o[21] = (syndrome_o == 7'h5b) ^ data_i[21]; + data_o[22] = (syndrome_o == 7'h5c) ^ data_i[22]; + data_o[23] = (syndrome_o == 7'h5d) ^ data_i[23]; + data_o[24] = (syndrome_o == 7'h5e) ^ data_i[24]; + data_o[25] = (syndrome_o == 7'h5f) ^ data_i[25]; + data_o[26] = (syndrome_o == 7'h61) ^ data_i[26]; + data_o[27] = (syndrome_o == 7'h62) ^ data_i[27]; + data_o[28] = (syndrome_o == 7'h63) ^ data_i[28]; + data_o[29] = (syndrome_o == 7'h64) ^ data_i[29]; + data_o[30] = (syndrome_o == 7'h65) ^ data_i[30]; + data_o[31] = (syndrome_o == 7'h66) ^ data_i[31]; + + // err_o calc. bit0: single error, bit1: double error + err_o[0] = syndrome_o[6]; + err_o[1] = |syndrome_o[5:0] & ~syndrome_o[6]; + end +endmodule : caliptra_prim_secded_inv_hamming_39_32_dec diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_inv_hamming_39_32_enc.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_inv_hamming_39_32_enc.sv new file mode 100644 index 0000000..5ca1580 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_inv_hamming_39_32_enc.sv @@ -0,0 +1,24 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// SECDED encoder generated by util/design/secded_gen.py + +module caliptra_prim_secded_inv_hamming_39_32_enc ( + input [31:0] data_i, + output logic [38:0] data_o +); + + always_comb begin : p_encode + data_o = 39'(data_i); + data_o[32] = ^(data_o & 39'h0056AAAD5B); + data_o[33] = ^(data_o & 39'h009B33366D); + data_o[34] = ^(data_o & 39'h00E3C3C78E); + data_o[35] = ^(data_o & 39'h0003FC07F0); + data_o[36] = ^(data_o & 39'h0003FFF800); + data_o[37] = ^(data_o & 39'h00FC000000); + data_o[38] = ^(data_o & 39'h3FFFFFFFFF); + data_o ^= 39'h2A00000000; + end + +endmodule : caliptra_prim_secded_inv_hamming_39_32_enc diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_inv_hamming_72_64_dec.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_inv_hamming_72_64_dec.sv new file mode 100644 index 0000000..d53e17c --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_inv_hamming_72_64_dec.sv @@ -0,0 +1,95 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// SECDED decoder generated by util/design/secded_gen.py + +module caliptra_prim_secded_inv_hamming_72_64_dec ( + input [71:0] data_i, + output logic [63:0] data_o, + output logic [7:0] syndrome_o, + output logic [1:0] err_o +); + + always_comb begin : p_encode + // Syndrome calculation + syndrome_o[0] = ^((data_i ^ 72'hAA0000000000000000) & 72'h01AB55555556AAAD5B); + syndrome_o[1] = ^((data_i ^ 72'hAA0000000000000000) & 72'h02CD9999999B33366D); + syndrome_o[2] = ^((data_i ^ 72'hAA0000000000000000) & 72'h04F1E1E1E1E3C3C78E); + syndrome_o[3] = ^((data_i ^ 72'hAA0000000000000000) & 72'h0801FE01FE03FC07F0); + syndrome_o[4] = ^((data_i ^ 72'hAA0000000000000000) & 72'h1001FFFE0003FFF800); + syndrome_o[5] = ^((data_i ^ 72'hAA0000000000000000) & 72'h2001FFFFFFFC000000); + syndrome_o[6] = ^((data_i ^ 72'hAA0000000000000000) & 72'h40FE00000000000000); + syndrome_o[7] = ^((data_i ^ 72'hAA0000000000000000) & 72'hFFFFFFFFFFFFFFFFFF); + + // Corrected output calculation + data_o[0] = (syndrome_o == 8'h83) ^ data_i[0]; + data_o[1] = (syndrome_o == 8'h85) ^ data_i[1]; + data_o[2] = (syndrome_o == 8'h86) ^ data_i[2]; + data_o[3] = (syndrome_o == 8'h87) ^ data_i[3]; + data_o[4] = (syndrome_o == 8'h89) ^ data_i[4]; + data_o[5] = (syndrome_o == 8'h8a) ^ data_i[5]; + data_o[6] = (syndrome_o == 8'h8b) ^ data_i[6]; + data_o[7] = (syndrome_o == 8'h8c) ^ data_i[7]; + data_o[8] = (syndrome_o == 8'h8d) ^ data_i[8]; + data_o[9] = (syndrome_o == 8'h8e) ^ data_i[9]; + data_o[10] = (syndrome_o == 8'h8f) ^ data_i[10]; + data_o[11] = (syndrome_o == 8'h91) ^ data_i[11]; + data_o[12] = (syndrome_o == 8'h92) ^ data_i[12]; + data_o[13] = (syndrome_o == 8'h93) ^ data_i[13]; + data_o[14] = (syndrome_o == 8'h94) ^ data_i[14]; + data_o[15] = (syndrome_o == 8'h95) ^ data_i[15]; + data_o[16] = (syndrome_o == 8'h96) ^ data_i[16]; + data_o[17] = (syndrome_o == 8'h97) ^ data_i[17]; + data_o[18] = (syndrome_o == 8'h98) ^ data_i[18]; + data_o[19] = (syndrome_o == 8'h99) ^ data_i[19]; + data_o[20] = (syndrome_o == 8'h9a) ^ data_i[20]; + data_o[21] = (syndrome_o == 8'h9b) ^ data_i[21]; + data_o[22] = (syndrome_o == 8'h9c) ^ data_i[22]; + data_o[23] = (syndrome_o == 8'h9d) ^ data_i[23]; + data_o[24] = (syndrome_o == 8'h9e) ^ data_i[24]; + data_o[25] = (syndrome_o == 8'h9f) ^ data_i[25]; + data_o[26] = (syndrome_o == 8'ha1) ^ data_i[26]; + data_o[27] = (syndrome_o == 8'ha2) ^ data_i[27]; + data_o[28] = (syndrome_o == 8'ha3) ^ data_i[28]; + data_o[29] = (syndrome_o == 8'ha4) ^ data_i[29]; + data_o[30] = (syndrome_o == 8'ha5) ^ data_i[30]; + data_o[31] = (syndrome_o == 8'ha6) ^ data_i[31]; + data_o[32] = (syndrome_o == 8'ha7) ^ data_i[32]; + data_o[33] = (syndrome_o == 8'ha8) ^ data_i[33]; + data_o[34] = (syndrome_o == 8'ha9) ^ data_i[34]; + data_o[35] = (syndrome_o == 8'haa) ^ data_i[35]; + data_o[36] = (syndrome_o == 8'hab) ^ data_i[36]; + data_o[37] = (syndrome_o == 8'hac) ^ data_i[37]; + data_o[38] = (syndrome_o == 8'had) ^ data_i[38]; + data_o[39] = (syndrome_o == 8'hae) ^ data_i[39]; + data_o[40] = (syndrome_o == 8'haf) ^ data_i[40]; + data_o[41] = (syndrome_o == 8'hb0) ^ data_i[41]; + data_o[42] = (syndrome_o == 8'hb1) ^ data_i[42]; + data_o[43] = (syndrome_o == 8'hb2) ^ data_i[43]; + data_o[44] = (syndrome_o == 8'hb3) ^ data_i[44]; + data_o[45] = (syndrome_o == 8'hb4) ^ data_i[45]; + data_o[46] = (syndrome_o == 8'hb5) ^ data_i[46]; + data_o[47] = (syndrome_o == 8'hb6) ^ data_i[47]; + data_o[48] = (syndrome_o == 8'hb7) ^ data_i[48]; + data_o[49] = (syndrome_o == 8'hb8) ^ data_i[49]; + data_o[50] = (syndrome_o == 8'hb9) ^ data_i[50]; + data_o[51] = (syndrome_o == 8'hba) ^ data_i[51]; + data_o[52] = (syndrome_o == 8'hbb) ^ data_i[52]; + data_o[53] = (syndrome_o == 8'hbc) ^ data_i[53]; + data_o[54] = (syndrome_o == 8'hbd) ^ data_i[54]; + data_o[55] = (syndrome_o == 8'hbe) ^ data_i[55]; + data_o[56] = (syndrome_o == 8'hbf) ^ data_i[56]; + data_o[57] = (syndrome_o == 8'hc1) ^ data_i[57]; + data_o[58] = (syndrome_o == 8'hc2) ^ data_i[58]; + data_o[59] = (syndrome_o == 8'hc3) ^ data_i[59]; + data_o[60] = (syndrome_o == 8'hc4) ^ data_i[60]; + data_o[61] = (syndrome_o == 8'hc5) ^ data_i[61]; + data_o[62] = (syndrome_o == 8'hc6) ^ data_i[62]; + data_o[63] = (syndrome_o == 8'hc7) ^ data_i[63]; + + // err_o calc. bit0: single error, bit1: double error + err_o[0] = syndrome_o[7]; + err_o[1] = |syndrome_o[6:0] & ~syndrome_o[7]; + end +endmodule : caliptra_prim_secded_inv_hamming_72_64_dec diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_inv_hamming_72_64_enc.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_inv_hamming_72_64_enc.sv new file mode 100644 index 0000000..933078e --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_inv_hamming_72_64_enc.sv @@ -0,0 +1,25 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// SECDED encoder generated by util/design/secded_gen.py + +module caliptra_prim_secded_inv_hamming_72_64_enc ( + input [63:0] data_i, + output logic [71:0] data_o +); + + always_comb begin : p_encode + data_o = 72'(data_i); + data_o[64] = ^(data_o & 72'h00AB55555556AAAD5B); + data_o[65] = ^(data_o & 72'h00CD9999999B33366D); + data_o[66] = ^(data_o & 72'h00F1E1E1E1E3C3C78E); + data_o[67] = ^(data_o & 72'h0001FE01FE03FC07F0); + data_o[68] = ^(data_o & 72'h0001FFFE0003FFF800); + data_o[69] = ^(data_o & 72'h0001FFFFFFFC000000); + data_o[70] = ^(data_o & 72'h00FE00000000000000); + data_o[71] = ^(data_o & 72'h7FFFFFFFFFFFFFFFFF); + data_o ^= 72'hAA0000000000000000; + end + +endmodule : caliptra_prim_secded_inv_hamming_72_64_enc diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_inv_hamming_76_68_dec.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_inv_hamming_76_68_dec.sv new file mode 100644 index 0000000..583848a --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_inv_hamming_76_68_dec.sv @@ -0,0 +1,99 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// SECDED decoder generated by util/design/secded_gen.py + +module caliptra_prim_secded_inv_hamming_76_68_dec ( + input [75:0] data_i, + output logic [67:0] data_o, + output logic [7:0] syndrome_o, + output logic [1:0] err_o +); + + always_comb begin : p_encode + // Syndrome calculation + syndrome_o[0] = ^((data_i ^ 76'hAA00000000000000000) & 76'h01AAB55555556AAAD5B); + syndrome_o[1] = ^((data_i ^ 76'hAA00000000000000000) & 76'h02CCD9999999B33366D); + syndrome_o[2] = ^((data_i ^ 76'hAA00000000000000000) & 76'h040F1E1E1E1E3C3C78E); + syndrome_o[3] = ^((data_i ^ 76'hAA00000000000000000) & 76'h08F01FE01FE03FC07F0); + syndrome_o[4] = ^((data_i ^ 76'hAA00000000000000000) & 76'h10001FFFE0003FFF800); + syndrome_o[5] = ^((data_i ^ 76'hAA00000000000000000) & 76'h20001FFFFFFFC000000); + syndrome_o[6] = ^((data_i ^ 76'hAA00000000000000000) & 76'h40FFE00000000000000); + syndrome_o[7] = ^((data_i ^ 76'hAA00000000000000000) & 76'hFFFFFFFFFFFFFFFFFFF); + + // Corrected output calculation + data_o[0] = (syndrome_o == 8'h83) ^ data_i[0]; + data_o[1] = (syndrome_o == 8'h85) ^ data_i[1]; + data_o[2] = (syndrome_o == 8'h86) ^ data_i[2]; + data_o[3] = (syndrome_o == 8'h87) ^ data_i[3]; + data_o[4] = (syndrome_o == 8'h89) ^ data_i[4]; + data_o[5] = (syndrome_o == 8'h8a) ^ data_i[5]; + data_o[6] = (syndrome_o == 8'h8b) ^ data_i[6]; + data_o[7] = (syndrome_o == 8'h8c) ^ data_i[7]; + data_o[8] = (syndrome_o == 8'h8d) ^ data_i[8]; + data_o[9] = (syndrome_o == 8'h8e) ^ data_i[9]; + data_o[10] = (syndrome_o == 8'h8f) ^ data_i[10]; + data_o[11] = (syndrome_o == 8'h91) ^ data_i[11]; + data_o[12] = (syndrome_o == 8'h92) ^ data_i[12]; + data_o[13] = (syndrome_o == 8'h93) ^ data_i[13]; + data_o[14] = (syndrome_o == 8'h94) ^ data_i[14]; + data_o[15] = (syndrome_o == 8'h95) ^ data_i[15]; + data_o[16] = (syndrome_o == 8'h96) ^ data_i[16]; + data_o[17] = (syndrome_o == 8'h97) ^ data_i[17]; + data_o[18] = (syndrome_o == 8'h98) ^ data_i[18]; + data_o[19] = (syndrome_o == 8'h99) ^ data_i[19]; + data_o[20] = (syndrome_o == 8'h9a) ^ data_i[20]; + data_o[21] = (syndrome_o == 8'h9b) ^ data_i[21]; + data_o[22] = (syndrome_o == 8'h9c) ^ data_i[22]; + data_o[23] = (syndrome_o == 8'h9d) ^ data_i[23]; + data_o[24] = (syndrome_o == 8'h9e) ^ data_i[24]; + data_o[25] = (syndrome_o == 8'h9f) ^ data_i[25]; + data_o[26] = (syndrome_o == 8'ha1) ^ data_i[26]; + data_o[27] = (syndrome_o == 8'ha2) ^ data_i[27]; + data_o[28] = (syndrome_o == 8'ha3) ^ data_i[28]; + data_o[29] = (syndrome_o == 8'ha4) ^ data_i[29]; + data_o[30] = (syndrome_o == 8'ha5) ^ data_i[30]; + data_o[31] = (syndrome_o == 8'ha6) ^ data_i[31]; + data_o[32] = (syndrome_o == 8'ha7) ^ data_i[32]; + data_o[33] = (syndrome_o == 8'ha8) ^ data_i[33]; + data_o[34] = (syndrome_o == 8'ha9) ^ data_i[34]; + data_o[35] = (syndrome_o == 8'haa) ^ data_i[35]; + data_o[36] = (syndrome_o == 8'hab) ^ data_i[36]; + data_o[37] = (syndrome_o == 8'hac) ^ data_i[37]; + data_o[38] = (syndrome_o == 8'had) ^ data_i[38]; + data_o[39] = (syndrome_o == 8'hae) ^ data_i[39]; + data_o[40] = (syndrome_o == 8'haf) ^ data_i[40]; + data_o[41] = (syndrome_o == 8'hb0) ^ data_i[41]; + data_o[42] = (syndrome_o == 8'hb1) ^ data_i[42]; + data_o[43] = (syndrome_o == 8'hb2) ^ data_i[43]; + data_o[44] = (syndrome_o == 8'hb3) ^ data_i[44]; + data_o[45] = (syndrome_o == 8'hb4) ^ data_i[45]; + data_o[46] = (syndrome_o == 8'hb5) ^ data_i[46]; + data_o[47] = (syndrome_o == 8'hb6) ^ data_i[47]; + data_o[48] = (syndrome_o == 8'hb7) ^ data_i[48]; + data_o[49] = (syndrome_o == 8'hb8) ^ data_i[49]; + data_o[50] = (syndrome_o == 8'hb9) ^ data_i[50]; + data_o[51] = (syndrome_o == 8'hba) ^ data_i[51]; + data_o[52] = (syndrome_o == 8'hbb) ^ data_i[52]; + data_o[53] = (syndrome_o == 8'hbc) ^ data_i[53]; + data_o[54] = (syndrome_o == 8'hbd) ^ data_i[54]; + data_o[55] = (syndrome_o == 8'hbe) ^ data_i[55]; + data_o[56] = (syndrome_o == 8'hbf) ^ data_i[56]; + data_o[57] = (syndrome_o == 8'hc1) ^ data_i[57]; + data_o[58] = (syndrome_o == 8'hc2) ^ data_i[58]; + data_o[59] = (syndrome_o == 8'hc3) ^ data_i[59]; + data_o[60] = (syndrome_o == 8'hc4) ^ data_i[60]; + data_o[61] = (syndrome_o == 8'hc5) ^ data_i[61]; + data_o[62] = (syndrome_o == 8'hc6) ^ data_i[62]; + data_o[63] = (syndrome_o == 8'hc7) ^ data_i[63]; + data_o[64] = (syndrome_o == 8'hc8) ^ data_i[64]; + data_o[65] = (syndrome_o == 8'hc9) ^ data_i[65]; + data_o[66] = (syndrome_o == 8'hca) ^ data_i[66]; + data_o[67] = (syndrome_o == 8'hcb) ^ data_i[67]; + + // err_o calc. bit0: single error, bit1: double error + err_o[0] = syndrome_o[7]; + err_o[1] = |syndrome_o[6:0] & ~syndrome_o[7]; + end +endmodule : caliptra_prim_secded_inv_hamming_76_68_dec diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_inv_hamming_76_68_enc.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_inv_hamming_76_68_enc.sv new file mode 100644 index 0000000..ebb89be --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_inv_hamming_76_68_enc.sv @@ -0,0 +1,25 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// SECDED encoder generated by util/design/secded_gen.py + +module caliptra_prim_secded_inv_hamming_76_68_enc ( + input [67:0] data_i, + output logic [75:0] data_o +); + + always_comb begin : p_encode + data_o = 76'(data_i); + data_o[68] = ^(data_o & 76'h00AAB55555556AAAD5B); + data_o[69] = ^(data_o & 76'h00CCD9999999B33366D); + data_o[70] = ^(data_o & 76'h000F1E1E1E1E3C3C78E); + data_o[71] = ^(data_o & 76'h00F01FE01FE03FC07F0); + data_o[72] = ^(data_o & 76'h00001FFFE0003FFF800); + data_o[73] = ^(data_o & 76'h00001FFFFFFFC000000); + data_o[74] = ^(data_o & 76'h00FFE00000000000000); + data_o[75] = ^(data_o & 76'h7FFFFFFFFFFFFFFFFFF); + data_o ^= 76'hAA00000000000000000; + end + +endmodule : caliptra_prim_secded_inv_hamming_76_68_enc diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_pkg.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_pkg.sv new file mode 100644 index 0000000..1f5bc25 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_secded_pkg.sv @@ -0,0 +1,1787 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// SECDED package generated by +// util/design/secded_gen.py from util/design/data/secded_cfg.hjson + +package caliptra_prim_secded_pkg; + + typedef enum logic [31:0] { + SecdedNone, + Secded_22_16, + Secded_28_22, + Secded_39_32, + Secded_64_57, + Secded_72_64, + SecdedHamming_22_16, + SecdedHamming_39_32, + SecdedHamming_72_64, + SecdedHamming_76_68, + SecdedInv_22_16, + SecdedInv_28_22, + SecdedInv_39_32, + SecdedInv_64_57, + SecdedInv_72_64, + SecdedInvHamming_22_16, + SecdedInvHamming_39_32, + SecdedInvHamming_72_64, + SecdedInvHamming_76_68 + } prim_secded_e; + + function automatic int get_ecc_data_width(prim_secded_e ecc_type); + case (ecc_type) + Secded_22_16: return 16; + Secded_28_22: return 22; + Secded_39_32: return 32; + Secded_64_57: return 57; + Secded_72_64: return 64; + SecdedHamming_22_16: return 16; + SecdedHamming_39_32: return 32; + SecdedHamming_72_64: return 64; + SecdedHamming_76_68: return 68; + SecdedInv_22_16: return 16; + SecdedInv_28_22: return 22; + SecdedInv_39_32: return 32; + SecdedInv_64_57: return 57; + SecdedInv_72_64: return 64; + SecdedInvHamming_22_16: return 16; + SecdedInvHamming_39_32: return 32; + SecdedInvHamming_72_64: return 64; + SecdedInvHamming_76_68: return 68; + // Return a non-zero width to avoid VCS compile issues + default: return 32; + endcase + endfunction + + function automatic int get_ecc_parity_width(prim_secded_e ecc_type); + case (ecc_type) + Secded_22_16: return 6; + Secded_28_22: return 6; + Secded_39_32: return 7; + Secded_64_57: return 7; + Secded_72_64: return 8; + SecdedHamming_22_16: return 6; + SecdedHamming_39_32: return 7; + SecdedHamming_72_64: return 8; + SecdedHamming_76_68: return 8; + SecdedInv_22_16: return 6; + SecdedInv_28_22: return 6; + SecdedInv_39_32: return 7; + SecdedInv_64_57: return 7; + SecdedInv_72_64: return 8; + SecdedInvHamming_22_16: return 6; + SecdedInvHamming_39_32: return 7; + SecdedInvHamming_72_64: return 8; + SecdedInvHamming_76_68: return 8; + default: return 0; + endcase + endfunction + + parameter logic [5:0] Secded2216ZeroEcc = 6'h0; + parameter logic [21:0] Secded2216ZeroWord = 22'h0; + + typedef struct packed { + logic [15:0] data; + logic [5:0] syndrome; + logic [1:0] err; + } secded_22_16_t; + + parameter logic [5:0] Secded2822ZeroEcc = 6'h0; + parameter logic [27:0] Secded2822ZeroWord = 28'h0; + + typedef struct packed { + logic [21:0] data; + logic [5:0] syndrome; + logic [1:0] err; + } secded_28_22_t; + + parameter logic [6:0] Secded3932ZeroEcc = 7'h0; + parameter logic [38:0] Secded3932ZeroWord = 39'h0; + + typedef struct packed { + logic [31:0] data; + logic [6:0] syndrome; + logic [1:0] err; + } secded_39_32_t; + + parameter logic [6:0] Secded6457ZeroEcc = 7'h0; + parameter logic [63:0] Secded6457ZeroWord = 64'h0; + + typedef struct packed { + logic [56:0] data; + logic [6:0] syndrome; + logic [1:0] err; + } secded_64_57_t; + + parameter logic [7:0] Secded7264ZeroEcc = 8'h0; + parameter logic [71:0] Secded7264ZeroWord = 72'h0; + + typedef struct packed { + logic [63:0] data; + logic [7:0] syndrome; + logic [1:0] err; + } secded_72_64_t; + + parameter logic [5:0] SecdedHamming2216ZeroEcc = 6'h0; + parameter logic [21:0] SecdedHamming2216ZeroWord = 22'h0; + + typedef struct packed { + logic [15:0] data; + logic [5:0] syndrome; + logic [1:0] err; + } secded_hamming_22_16_t; + + parameter logic [6:0] SecdedHamming3932ZeroEcc = 7'h0; + parameter logic [38:0] SecdedHamming3932ZeroWord = 39'h0; + + typedef struct packed { + logic [31:0] data; + logic [6:0] syndrome; + logic [1:0] err; + } secded_hamming_39_32_t; + + parameter logic [7:0] SecdedHamming7264ZeroEcc = 8'h0; + parameter logic [71:0] SecdedHamming7264ZeroWord = 72'h0; + + typedef struct packed { + logic [63:0] data; + logic [7:0] syndrome; + logic [1:0] err; + } secded_hamming_72_64_t; + + parameter logic [7:0] SecdedHamming7668ZeroEcc = 8'h0; + parameter logic [75:0] SecdedHamming7668ZeroWord = 76'h0; + + typedef struct packed { + logic [67:0] data; + logic [7:0] syndrome; + logic [1:0] err; + } secded_hamming_76_68_t; + + parameter logic [5:0] SecdedInv2216ZeroEcc = 6'h2A; + parameter logic [21:0] SecdedInv2216ZeroWord = 22'h2A0000; + + typedef struct packed { + logic [15:0] data; + logic [5:0] syndrome; + logic [1:0] err; + } secded_inv_22_16_t; + + parameter logic [5:0] SecdedInv2822ZeroEcc = 6'h2A; + parameter logic [27:0] SecdedInv2822ZeroWord = 28'hA800000; + + typedef struct packed { + logic [21:0] data; + logic [5:0] syndrome; + logic [1:0] err; + } secded_inv_28_22_t; + + parameter logic [6:0] SecdedInv3932ZeroEcc = 7'h2A; + parameter logic [38:0] SecdedInv3932ZeroWord = 39'h2A00000000; + + typedef struct packed { + logic [31:0] data; + logic [6:0] syndrome; + logic [1:0] err; + } secded_inv_39_32_t; + + parameter logic [6:0] SecdedInv6457ZeroEcc = 7'h2A; + parameter logic [63:0] SecdedInv6457ZeroWord = 64'h5400000000000000; + + typedef struct packed { + logic [56:0] data; + logic [6:0] syndrome; + logic [1:0] err; + } secded_inv_64_57_t; + + parameter logic [7:0] SecdedInv7264ZeroEcc = 8'hAA; + parameter logic [71:0] SecdedInv7264ZeroWord = 72'hAA0000000000000000; + + typedef struct packed { + logic [63:0] data; + logic [7:0] syndrome; + logic [1:0] err; + } secded_inv_72_64_t; + + parameter logic [5:0] SecdedInvHamming2216ZeroEcc = 6'h2A; + parameter logic [21:0] SecdedInvHamming2216ZeroWord = 22'h2A0000; + + typedef struct packed { + logic [15:0] data; + logic [5:0] syndrome; + logic [1:0] err; + } secded_inv_hamming_22_16_t; + + parameter logic [6:0] SecdedInvHamming3932ZeroEcc = 7'h2A; + parameter logic [38:0] SecdedInvHamming3932ZeroWord = 39'h2A00000000; + + typedef struct packed { + logic [31:0] data; + logic [6:0] syndrome; + logic [1:0] err; + } secded_inv_hamming_39_32_t; + + parameter logic [7:0] SecdedInvHamming7264ZeroEcc = 8'hAA; + parameter logic [71:0] SecdedInvHamming7264ZeroWord = 72'hAA0000000000000000; + + typedef struct packed { + logic [63:0] data; + logic [7:0] syndrome; + logic [1:0] err; + } secded_inv_hamming_72_64_t; + + parameter logic [7:0] SecdedInvHamming7668ZeroEcc = 8'hAA; + parameter logic [75:0] SecdedInvHamming7668ZeroWord = 76'hAA00000000000000000; + + typedef struct packed { + logic [67:0] data; + logic [7:0] syndrome; + logic [1:0] err; + } secded_inv_hamming_76_68_t; + + function automatic logic [21:0] + prim_secded_22_16_enc (logic [15:0] data_i); + logic [21:0] data_o; + data_o = 22'(data_i); + data_o[16] = ^(data_o & 22'h00496E); + data_o[17] = ^(data_o & 22'h00F20B); + data_o[18] = ^(data_o & 22'h008ED8); + data_o[19] = ^(data_o & 22'h007714); + data_o[20] = ^(data_o & 22'h00ACA5); + data_o[21] = ^(data_o & 22'h0011F3); + return data_o; + endfunction + + function automatic secded_22_16_t + prim_secded_22_16_dec (logic [21:0] data_i); + logic [15:0] data_o; + logic [5:0] syndrome_o; + logic [1:0] err_o; + + secded_22_16_t dec; + + // Syndrome calculation + syndrome_o[0] = ^(data_i & 22'h01496E); + syndrome_o[1] = ^(data_i & 22'h02F20B); + syndrome_o[2] = ^(data_i & 22'h048ED8); + syndrome_o[3] = ^(data_i & 22'h087714); + syndrome_o[4] = ^(data_i & 22'h10ACA5); + syndrome_o[5] = ^(data_i & 22'h2011F3); + + // Corrected output calculation + data_o[0] = (syndrome_o == 6'h32) ^ data_i[0]; + data_o[1] = (syndrome_o == 6'h23) ^ data_i[1]; + data_o[2] = (syndrome_o == 6'h19) ^ data_i[2]; + data_o[3] = (syndrome_o == 6'h7) ^ data_i[3]; + data_o[4] = (syndrome_o == 6'h2c) ^ data_i[4]; + data_o[5] = (syndrome_o == 6'h31) ^ data_i[5]; + data_o[6] = (syndrome_o == 6'h25) ^ data_i[6]; + data_o[7] = (syndrome_o == 6'h34) ^ data_i[7]; + data_o[8] = (syndrome_o == 6'h29) ^ data_i[8]; + data_o[9] = (syndrome_o == 6'he) ^ data_i[9]; + data_o[10] = (syndrome_o == 6'h1c) ^ data_i[10]; + data_o[11] = (syndrome_o == 6'h15) ^ data_i[11]; + data_o[12] = (syndrome_o == 6'h2a) ^ data_i[12]; + data_o[13] = (syndrome_o == 6'h1a) ^ data_i[13]; + data_o[14] = (syndrome_o == 6'hb) ^ data_i[14]; + data_o[15] = (syndrome_o == 6'h16) ^ data_i[15]; + + // err_o calc. bit0: single error, bit1: double error + err_o[0] = ^syndrome_o; + err_o[1] = ~err_o[0] & (|syndrome_o); + + dec.data = data_o; + dec.syndrome = syndrome_o; + dec.err = err_o; + return dec; + + endfunction + + function automatic logic [27:0] + prim_secded_28_22_enc (logic [21:0] data_i); + logic [27:0] data_o; + data_o = 28'(data_i); + data_o[22] = ^(data_o & 28'h03003FF); + data_o[23] = ^(data_o & 28'h010FC0F); + data_o[24] = ^(data_o & 28'h0271C71); + data_o[25] = ^(data_o & 28'h03B6592); + data_o[26] = ^(data_o & 28'h03DAAA4); + data_o[27] = ^(data_o & 28'h03ED348); + return data_o; + endfunction + + function automatic secded_28_22_t + prim_secded_28_22_dec (logic [27:0] data_i); + logic [21:0] data_o; + logic [5:0] syndrome_o; + logic [1:0] err_o; + + secded_28_22_t dec; + + // Syndrome calculation + syndrome_o[0] = ^(data_i & 28'h07003FF); + syndrome_o[1] = ^(data_i & 28'h090FC0F); + syndrome_o[2] = ^(data_i & 28'h1271C71); + syndrome_o[3] = ^(data_i & 28'h23B6592); + syndrome_o[4] = ^(data_i & 28'h43DAAA4); + syndrome_o[5] = ^(data_i & 28'h83ED348); + + // Corrected output calculation + data_o[0] = (syndrome_o == 6'h7) ^ data_i[0]; + data_o[1] = (syndrome_o == 6'hb) ^ data_i[1]; + data_o[2] = (syndrome_o == 6'h13) ^ data_i[2]; + data_o[3] = (syndrome_o == 6'h23) ^ data_i[3]; + data_o[4] = (syndrome_o == 6'hd) ^ data_i[4]; + data_o[5] = (syndrome_o == 6'h15) ^ data_i[5]; + data_o[6] = (syndrome_o == 6'h25) ^ data_i[6]; + data_o[7] = (syndrome_o == 6'h19) ^ data_i[7]; + data_o[8] = (syndrome_o == 6'h29) ^ data_i[8]; + data_o[9] = (syndrome_o == 6'h31) ^ data_i[9]; + data_o[10] = (syndrome_o == 6'he) ^ data_i[10]; + data_o[11] = (syndrome_o == 6'h16) ^ data_i[11]; + data_o[12] = (syndrome_o == 6'h26) ^ data_i[12]; + data_o[13] = (syndrome_o == 6'h1a) ^ data_i[13]; + data_o[14] = (syndrome_o == 6'h2a) ^ data_i[14]; + data_o[15] = (syndrome_o == 6'h32) ^ data_i[15]; + data_o[16] = (syndrome_o == 6'h1c) ^ data_i[16]; + data_o[17] = (syndrome_o == 6'h2c) ^ data_i[17]; + data_o[18] = (syndrome_o == 6'h34) ^ data_i[18]; + data_o[19] = (syndrome_o == 6'h38) ^ data_i[19]; + data_o[20] = (syndrome_o == 6'h3b) ^ data_i[20]; + data_o[21] = (syndrome_o == 6'h3d) ^ data_i[21]; + + // err_o calc. bit0: single error, bit1: double error + err_o[0] = ^syndrome_o; + err_o[1] = ~err_o[0] & (|syndrome_o); + + dec.data = data_o; + dec.syndrome = syndrome_o; + dec.err = err_o; + return dec; + + endfunction + + function automatic logic [38:0] + prim_secded_39_32_enc (logic [31:0] data_i); + logic [38:0] data_o; + data_o = 39'(data_i); + data_o[32] = ^(data_o & 39'h002606BD25); + data_o[33] = ^(data_o & 39'h00DEBA8050); + data_o[34] = ^(data_o & 39'h00413D89AA); + data_o[35] = ^(data_o & 39'h0031234ED1); + data_o[36] = ^(data_o & 39'h00C2C1323B); + data_o[37] = ^(data_o & 39'h002DCC624C); + data_o[38] = ^(data_o & 39'h0098505586); + return data_o; + endfunction + + function automatic secded_39_32_t + prim_secded_39_32_dec (logic [38:0] data_i); + logic [31:0] data_o; + logic [6:0] syndrome_o; + logic [1:0] err_o; + + secded_39_32_t dec; + + // Syndrome calculation + syndrome_o[0] = ^(data_i & 39'h012606BD25); + syndrome_o[1] = ^(data_i & 39'h02DEBA8050); + syndrome_o[2] = ^(data_i & 39'h04413D89AA); + syndrome_o[3] = ^(data_i & 39'h0831234ED1); + syndrome_o[4] = ^(data_i & 39'h10C2C1323B); + syndrome_o[5] = ^(data_i & 39'h202DCC624C); + syndrome_o[6] = ^(data_i & 39'h4098505586); + + // Corrected output calculation + data_o[0] = (syndrome_o == 7'h19) ^ data_i[0]; + data_o[1] = (syndrome_o == 7'h54) ^ data_i[1]; + data_o[2] = (syndrome_o == 7'h61) ^ data_i[2]; + data_o[3] = (syndrome_o == 7'h34) ^ data_i[3]; + data_o[4] = (syndrome_o == 7'h1a) ^ data_i[4]; + data_o[5] = (syndrome_o == 7'h15) ^ data_i[5]; + data_o[6] = (syndrome_o == 7'h2a) ^ data_i[6]; + data_o[7] = (syndrome_o == 7'h4c) ^ data_i[7]; + data_o[8] = (syndrome_o == 7'h45) ^ data_i[8]; + data_o[9] = (syndrome_o == 7'h38) ^ data_i[9]; + data_o[10] = (syndrome_o == 7'h49) ^ data_i[10]; + data_o[11] = (syndrome_o == 7'hd) ^ data_i[11]; + data_o[12] = (syndrome_o == 7'h51) ^ data_i[12]; + data_o[13] = (syndrome_o == 7'h31) ^ data_i[13]; + data_o[14] = (syndrome_o == 7'h68) ^ data_i[14]; + data_o[15] = (syndrome_o == 7'h7) ^ data_i[15]; + data_o[16] = (syndrome_o == 7'h1c) ^ data_i[16]; + data_o[17] = (syndrome_o == 7'hb) ^ data_i[17]; + data_o[18] = (syndrome_o == 7'h25) ^ data_i[18]; + data_o[19] = (syndrome_o == 7'h26) ^ data_i[19]; + data_o[20] = (syndrome_o == 7'h46) ^ data_i[20]; + data_o[21] = (syndrome_o == 7'he) ^ data_i[21]; + data_o[22] = (syndrome_o == 7'h70) ^ data_i[22]; + data_o[23] = (syndrome_o == 7'h32) ^ data_i[23]; + data_o[24] = (syndrome_o == 7'h2c) ^ data_i[24]; + data_o[25] = (syndrome_o == 7'h13) ^ data_i[25]; + data_o[26] = (syndrome_o == 7'h23) ^ data_i[26]; + data_o[27] = (syndrome_o == 7'h62) ^ data_i[27]; + data_o[28] = (syndrome_o == 7'h4a) ^ data_i[28]; + data_o[29] = (syndrome_o == 7'h29) ^ data_i[29]; + data_o[30] = (syndrome_o == 7'h16) ^ data_i[30]; + data_o[31] = (syndrome_o == 7'h52) ^ data_i[31]; + + // err_o calc. bit0: single error, bit1: double error + err_o[0] = ^syndrome_o; + err_o[1] = ~err_o[0] & (|syndrome_o); + + dec.data = data_o; + dec.syndrome = syndrome_o; + dec.err = err_o; + return dec; + + endfunction + + function automatic logic [63:0] + prim_secded_64_57_enc (logic [56:0] data_i); + logic [63:0] data_o; + data_o = 64'(data_i); + data_o[57] = ^(data_o & 64'h0103FFF800007FFF); + data_o[58] = ^(data_o & 64'h017C1FF801FF801F); + data_o[59] = ^(data_o & 64'h01BDE1F87E0781E1); + data_o[60] = ^(data_o & 64'h01DEEE3B8E388E22); + data_o[61] = ^(data_o & 64'h01EF76CDB2C93244); + data_o[62] = ^(data_o & 64'h01F7BB56D5525488); + data_o[63] = ^(data_o & 64'h01FBDDA769A46910); + return data_o; + endfunction + + function automatic secded_64_57_t + prim_secded_64_57_dec (logic [63:0] data_i); + logic [56:0] data_o; + logic [6:0] syndrome_o; + logic [1:0] err_o; + + secded_64_57_t dec; + + // Syndrome calculation + syndrome_o[0] = ^(data_i & 64'h0303FFF800007FFF); + syndrome_o[1] = ^(data_i & 64'h057C1FF801FF801F); + syndrome_o[2] = ^(data_i & 64'h09BDE1F87E0781E1); + syndrome_o[3] = ^(data_i & 64'h11DEEE3B8E388E22); + syndrome_o[4] = ^(data_i & 64'h21EF76CDB2C93244); + syndrome_o[5] = ^(data_i & 64'h41F7BB56D5525488); + syndrome_o[6] = ^(data_i & 64'h81FBDDA769A46910); + + // Corrected output calculation + data_o[0] = (syndrome_o == 7'h7) ^ data_i[0]; + data_o[1] = (syndrome_o == 7'hb) ^ data_i[1]; + data_o[2] = (syndrome_o == 7'h13) ^ data_i[2]; + data_o[3] = (syndrome_o == 7'h23) ^ data_i[3]; + data_o[4] = (syndrome_o == 7'h43) ^ data_i[4]; + data_o[5] = (syndrome_o == 7'hd) ^ data_i[5]; + data_o[6] = (syndrome_o == 7'h15) ^ data_i[6]; + data_o[7] = (syndrome_o == 7'h25) ^ data_i[7]; + data_o[8] = (syndrome_o == 7'h45) ^ data_i[8]; + data_o[9] = (syndrome_o == 7'h19) ^ data_i[9]; + data_o[10] = (syndrome_o == 7'h29) ^ data_i[10]; + data_o[11] = (syndrome_o == 7'h49) ^ data_i[11]; + data_o[12] = (syndrome_o == 7'h31) ^ data_i[12]; + data_o[13] = (syndrome_o == 7'h51) ^ data_i[13]; + data_o[14] = (syndrome_o == 7'h61) ^ data_i[14]; + data_o[15] = (syndrome_o == 7'he) ^ data_i[15]; + data_o[16] = (syndrome_o == 7'h16) ^ data_i[16]; + data_o[17] = (syndrome_o == 7'h26) ^ data_i[17]; + data_o[18] = (syndrome_o == 7'h46) ^ data_i[18]; + data_o[19] = (syndrome_o == 7'h1a) ^ data_i[19]; + data_o[20] = (syndrome_o == 7'h2a) ^ data_i[20]; + data_o[21] = (syndrome_o == 7'h4a) ^ data_i[21]; + data_o[22] = (syndrome_o == 7'h32) ^ data_i[22]; + data_o[23] = (syndrome_o == 7'h52) ^ data_i[23]; + data_o[24] = (syndrome_o == 7'h62) ^ data_i[24]; + data_o[25] = (syndrome_o == 7'h1c) ^ data_i[25]; + data_o[26] = (syndrome_o == 7'h2c) ^ data_i[26]; + data_o[27] = (syndrome_o == 7'h4c) ^ data_i[27]; + data_o[28] = (syndrome_o == 7'h34) ^ data_i[28]; + data_o[29] = (syndrome_o == 7'h54) ^ data_i[29]; + data_o[30] = (syndrome_o == 7'h64) ^ data_i[30]; + data_o[31] = (syndrome_o == 7'h38) ^ data_i[31]; + data_o[32] = (syndrome_o == 7'h58) ^ data_i[32]; + data_o[33] = (syndrome_o == 7'h68) ^ data_i[33]; + data_o[34] = (syndrome_o == 7'h70) ^ data_i[34]; + data_o[35] = (syndrome_o == 7'h1f) ^ data_i[35]; + data_o[36] = (syndrome_o == 7'h2f) ^ data_i[36]; + data_o[37] = (syndrome_o == 7'h4f) ^ data_i[37]; + data_o[38] = (syndrome_o == 7'h37) ^ data_i[38]; + data_o[39] = (syndrome_o == 7'h57) ^ data_i[39]; + data_o[40] = (syndrome_o == 7'h67) ^ data_i[40]; + data_o[41] = (syndrome_o == 7'h3b) ^ data_i[41]; + data_o[42] = (syndrome_o == 7'h5b) ^ data_i[42]; + data_o[43] = (syndrome_o == 7'h6b) ^ data_i[43]; + data_o[44] = (syndrome_o == 7'h73) ^ data_i[44]; + data_o[45] = (syndrome_o == 7'h3d) ^ data_i[45]; + data_o[46] = (syndrome_o == 7'h5d) ^ data_i[46]; + data_o[47] = (syndrome_o == 7'h6d) ^ data_i[47]; + data_o[48] = (syndrome_o == 7'h75) ^ data_i[48]; + data_o[49] = (syndrome_o == 7'h79) ^ data_i[49]; + data_o[50] = (syndrome_o == 7'h3e) ^ data_i[50]; + data_o[51] = (syndrome_o == 7'h5e) ^ data_i[51]; + data_o[52] = (syndrome_o == 7'h6e) ^ data_i[52]; + data_o[53] = (syndrome_o == 7'h76) ^ data_i[53]; + data_o[54] = (syndrome_o == 7'h7a) ^ data_i[54]; + data_o[55] = (syndrome_o == 7'h7c) ^ data_i[55]; + data_o[56] = (syndrome_o == 7'h7f) ^ data_i[56]; + + // err_o calc. bit0: single error, bit1: double error + err_o[0] = ^syndrome_o; + err_o[1] = ~err_o[0] & (|syndrome_o); + + dec.data = data_o; + dec.syndrome = syndrome_o; + dec.err = err_o; + return dec; + + endfunction + + function automatic logic [71:0] + prim_secded_72_64_enc (logic [63:0] data_i); + logic [71:0] data_o; + data_o = 72'(data_i); + data_o[64] = ^(data_o & 72'h00B9000000001FFFFF); + data_o[65] = ^(data_o & 72'h005E00000FFFE0003F); + data_o[66] = ^(data_o & 72'h0067003FF003E007C1); + data_o[67] = ^(data_o & 72'h00CD0FC0F03C207842); + data_o[68] = ^(data_o & 72'h00B671C711C4438884); + data_o[69] = ^(data_o & 72'h00B5B65926488C9108); + data_o[70] = ^(data_o & 72'h00CBDAAA4A91152210); + data_o[71] = ^(data_o & 72'h007AED348D221A4420); + return data_o; + endfunction + + function automatic secded_72_64_t + prim_secded_72_64_dec (logic [71:0] data_i); + logic [63:0] data_o; + logic [7:0] syndrome_o; + logic [1:0] err_o; + + secded_72_64_t dec; + + // Syndrome calculation + syndrome_o[0] = ^(data_i & 72'h01B9000000001FFFFF); + syndrome_o[1] = ^(data_i & 72'h025E00000FFFE0003F); + syndrome_o[2] = ^(data_i & 72'h0467003FF003E007C1); + syndrome_o[3] = ^(data_i & 72'h08CD0FC0F03C207842); + syndrome_o[4] = ^(data_i & 72'h10B671C711C4438884); + syndrome_o[5] = ^(data_i & 72'h20B5B65926488C9108); + syndrome_o[6] = ^(data_i & 72'h40CBDAAA4A91152210); + syndrome_o[7] = ^(data_i & 72'h807AED348D221A4420); + + // Corrected output calculation + data_o[0] = (syndrome_o == 8'h7) ^ data_i[0]; + data_o[1] = (syndrome_o == 8'hb) ^ data_i[1]; + data_o[2] = (syndrome_o == 8'h13) ^ data_i[2]; + data_o[3] = (syndrome_o == 8'h23) ^ data_i[3]; + data_o[4] = (syndrome_o == 8'h43) ^ data_i[4]; + data_o[5] = (syndrome_o == 8'h83) ^ data_i[5]; + data_o[6] = (syndrome_o == 8'hd) ^ data_i[6]; + data_o[7] = (syndrome_o == 8'h15) ^ data_i[7]; + data_o[8] = (syndrome_o == 8'h25) ^ data_i[8]; + data_o[9] = (syndrome_o == 8'h45) ^ data_i[9]; + data_o[10] = (syndrome_o == 8'h85) ^ data_i[10]; + data_o[11] = (syndrome_o == 8'h19) ^ data_i[11]; + data_o[12] = (syndrome_o == 8'h29) ^ data_i[12]; + data_o[13] = (syndrome_o == 8'h49) ^ data_i[13]; + data_o[14] = (syndrome_o == 8'h89) ^ data_i[14]; + data_o[15] = (syndrome_o == 8'h31) ^ data_i[15]; + data_o[16] = (syndrome_o == 8'h51) ^ data_i[16]; + data_o[17] = (syndrome_o == 8'h91) ^ data_i[17]; + data_o[18] = (syndrome_o == 8'h61) ^ data_i[18]; + data_o[19] = (syndrome_o == 8'ha1) ^ data_i[19]; + data_o[20] = (syndrome_o == 8'hc1) ^ data_i[20]; + data_o[21] = (syndrome_o == 8'he) ^ data_i[21]; + data_o[22] = (syndrome_o == 8'h16) ^ data_i[22]; + data_o[23] = (syndrome_o == 8'h26) ^ data_i[23]; + data_o[24] = (syndrome_o == 8'h46) ^ data_i[24]; + data_o[25] = (syndrome_o == 8'h86) ^ data_i[25]; + data_o[26] = (syndrome_o == 8'h1a) ^ data_i[26]; + data_o[27] = (syndrome_o == 8'h2a) ^ data_i[27]; + data_o[28] = (syndrome_o == 8'h4a) ^ data_i[28]; + data_o[29] = (syndrome_o == 8'h8a) ^ data_i[29]; + data_o[30] = (syndrome_o == 8'h32) ^ data_i[30]; + data_o[31] = (syndrome_o == 8'h52) ^ data_i[31]; + data_o[32] = (syndrome_o == 8'h92) ^ data_i[32]; + data_o[33] = (syndrome_o == 8'h62) ^ data_i[33]; + data_o[34] = (syndrome_o == 8'ha2) ^ data_i[34]; + data_o[35] = (syndrome_o == 8'hc2) ^ data_i[35]; + data_o[36] = (syndrome_o == 8'h1c) ^ data_i[36]; + data_o[37] = (syndrome_o == 8'h2c) ^ data_i[37]; + data_o[38] = (syndrome_o == 8'h4c) ^ data_i[38]; + data_o[39] = (syndrome_o == 8'h8c) ^ data_i[39]; + data_o[40] = (syndrome_o == 8'h34) ^ data_i[40]; + data_o[41] = (syndrome_o == 8'h54) ^ data_i[41]; + data_o[42] = (syndrome_o == 8'h94) ^ data_i[42]; + data_o[43] = (syndrome_o == 8'h64) ^ data_i[43]; + data_o[44] = (syndrome_o == 8'ha4) ^ data_i[44]; + data_o[45] = (syndrome_o == 8'hc4) ^ data_i[45]; + data_o[46] = (syndrome_o == 8'h38) ^ data_i[46]; + data_o[47] = (syndrome_o == 8'h58) ^ data_i[47]; + data_o[48] = (syndrome_o == 8'h98) ^ data_i[48]; + data_o[49] = (syndrome_o == 8'h68) ^ data_i[49]; + data_o[50] = (syndrome_o == 8'ha8) ^ data_i[50]; + data_o[51] = (syndrome_o == 8'hc8) ^ data_i[51]; + data_o[52] = (syndrome_o == 8'h70) ^ data_i[52]; + data_o[53] = (syndrome_o == 8'hb0) ^ data_i[53]; + data_o[54] = (syndrome_o == 8'hd0) ^ data_i[54]; + data_o[55] = (syndrome_o == 8'he0) ^ data_i[55]; + data_o[56] = (syndrome_o == 8'h6d) ^ data_i[56]; + data_o[57] = (syndrome_o == 8'hd6) ^ data_i[57]; + data_o[58] = (syndrome_o == 8'h3e) ^ data_i[58]; + data_o[59] = (syndrome_o == 8'hcb) ^ data_i[59]; + data_o[60] = (syndrome_o == 8'hb3) ^ data_i[60]; + data_o[61] = (syndrome_o == 8'hb5) ^ data_i[61]; + data_o[62] = (syndrome_o == 8'hce) ^ data_i[62]; + data_o[63] = (syndrome_o == 8'h79) ^ data_i[63]; + + // err_o calc. bit0: single error, bit1: double error + err_o[0] = ^syndrome_o; + err_o[1] = ~err_o[0] & (|syndrome_o); + + dec.data = data_o; + dec.syndrome = syndrome_o; + dec.err = err_o; + return dec; + + endfunction + + function automatic logic [21:0] + prim_secded_hamming_22_16_enc (logic [15:0] data_i); + logic [21:0] data_o; + data_o = 22'(data_i); + data_o[16] = ^(data_o & 22'h00AD5B); + data_o[17] = ^(data_o & 22'h00366D); + data_o[18] = ^(data_o & 22'h00C78E); + data_o[19] = ^(data_o & 22'h0007F0); + data_o[20] = ^(data_o & 22'h00F800); + data_o[21] = ^(data_o & 22'h1FFFFF); + return data_o; + endfunction + + function automatic secded_hamming_22_16_t + prim_secded_hamming_22_16_dec (logic [21:0] data_i); + logic [15:0] data_o; + logic [5:0] syndrome_o; + logic [1:0] err_o; + + secded_hamming_22_16_t dec; + + // Syndrome calculation + syndrome_o[0] = ^(data_i & 22'h01AD5B); + syndrome_o[1] = ^(data_i & 22'h02366D); + syndrome_o[2] = ^(data_i & 22'h04C78E); + syndrome_o[3] = ^(data_i & 22'h0807F0); + syndrome_o[4] = ^(data_i & 22'h10F800); + syndrome_o[5] = ^(data_i & 22'h3FFFFF); + + // Corrected output calculation + data_o[0] = (syndrome_o == 6'h23) ^ data_i[0]; + data_o[1] = (syndrome_o == 6'h25) ^ data_i[1]; + data_o[2] = (syndrome_o == 6'h26) ^ data_i[2]; + data_o[3] = (syndrome_o == 6'h27) ^ data_i[3]; + data_o[4] = (syndrome_o == 6'h29) ^ data_i[4]; + data_o[5] = (syndrome_o == 6'h2a) ^ data_i[5]; + data_o[6] = (syndrome_o == 6'h2b) ^ data_i[6]; + data_o[7] = (syndrome_o == 6'h2c) ^ data_i[7]; + data_o[8] = (syndrome_o == 6'h2d) ^ data_i[8]; + data_o[9] = (syndrome_o == 6'h2e) ^ data_i[9]; + data_o[10] = (syndrome_o == 6'h2f) ^ data_i[10]; + data_o[11] = (syndrome_o == 6'h31) ^ data_i[11]; + data_o[12] = (syndrome_o == 6'h32) ^ data_i[12]; + data_o[13] = (syndrome_o == 6'h33) ^ data_i[13]; + data_o[14] = (syndrome_o == 6'h34) ^ data_i[14]; + data_o[15] = (syndrome_o == 6'h35) ^ data_i[15]; + + // err_o calc. bit0: single error, bit1: double error + err_o[0] = syndrome_o[5]; + err_o[1] = |syndrome_o[4:0] & ~syndrome_o[5]; + + dec.data = data_o; + dec.syndrome = syndrome_o; + dec.err = err_o; + return dec; + + endfunction + + function automatic logic [38:0] + prim_secded_hamming_39_32_enc (logic [31:0] data_i); + logic [38:0] data_o; + data_o = 39'(data_i); + data_o[32] = ^(data_o & 39'h0056AAAD5B); + data_o[33] = ^(data_o & 39'h009B33366D); + data_o[34] = ^(data_o & 39'h00E3C3C78E); + data_o[35] = ^(data_o & 39'h0003FC07F0); + data_o[36] = ^(data_o & 39'h0003FFF800); + data_o[37] = ^(data_o & 39'h00FC000000); + data_o[38] = ^(data_o & 39'h3FFFFFFFFF); + return data_o; + endfunction + + function automatic secded_hamming_39_32_t + prim_secded_hamming_39_32_dec (logic [38:0] data_i); + logic [31:0] data_o; + logic [6:0] syndrome_o; + logic [1:0] err_o; + + secded_hamming_39_32_t dec; + + // Syndrome calculation + syndrome_o[0] = ^(data_i & 39'h0156AAAD5B); + syndrome_o[1] = ^(data_i & 39'h029B33366D); + syndrome_o[2] = ^(data_i & 39'h04E3C3C78E); + syndrome_o[3] = ^(data_i & 39'h0803FC07F0); + syndrome_o[4] = ^(data_i & 39'h1003FFF800); + syndrome_o[5] = ^(data_i & 39'h20FC000000); + syndrome_o[6] = ^(data_i & 39'h7FFFFFFFFF); + + // Corrected output calculation + data_o[0] = (syndrome_o == 7'h43) ^ data_i[0]; + data_o[1] = (syndrome_o == 7'h45) ^ data_i[1]; + data_o[2] = (syndrome_o == 7'h46) ^ data_i[2]; + data_o[3] = (syndrome_o == 7'h47) ^ data_i[3]; + data_o[4] = (syndrome_o == 7'h49) ^ data_i[4]; + data_o[5] = (syndrome_o == 7'h4a) ^ data_i[5]; + data_o[6] = (syndrome_o == 7'h4b) ^ data_i[6]; + data_o[7] = (syndrome_o == 7'h4c) ^ data_i[7]; + data_o[8] = (syndrome_o == 7'h4d) ^ data_i[8]; + data_o[9] = (syndrome_o == 7'h4e) ^ data_i[9]; + data_o[10] = (syndrome_o == 7'h4f) ^ data_i[10]; + data_o[11] = (syndrome_o == 7'h51) ^ data_i[11]; + data_o[12] = (syndrome_o == 7'h52) ^ data_i[12]; + data_o[13] = (syndrome_o == 7'h53) ^ data_i[13]; + data_o[14] = (syndrome_o == 7'h54) ^ data_i[14]; + data_o[15] = (syndrome_o == 7'h55) ^ data_i[15]; + data_o[16] = (syndrome_o == 7'h56) ^ data_i[16]; + data_o[17] = (syndrome_o == 7'h57) ^ data_i[17]; + data_o[18] = (syndrome_o == 7'h58) ^ data_i[18]; + data_o[19] = (syndrome_o == 7'h59) ^ data_i[19]; + data_o[20] = (syndrome_o == 7'h5a) ^ data_i[20]; + data_o[21] = (syndrome_o == 7'h5b) ^ data_i[21]; + data_o[22] = (syndrome_o == 7'h5c) ^ data_i[22]; + data_o[23] = (syndrome_o == 7'h5d) ^ data_i[23]; + data_o[24] = (syndrome_o == 7'h5e) ^ data_i[24]; + data_o[25] = (syndrome_o == 7'h5f) ^ data_i[25]; + data_o[26] = (syndrome_o == 7'h61) ^ data_i[26]; + data_o[27] = (syndrome_o == 7'h62) ^ data_i[27]; + data_o[28] = (syndrome_o == 7'h63) ^ data_i[28]; + data_o[29] = (syndrome_o == 7'h64) ^ data_i[29]; + data_o[30] = (syndrome_o == 7'h65) ^ data_i[30]; + data_o[31] = (syndrome_o == 7'h66) ^ data_i[31]; + + // err_o calc. bit0: single error, bit1: double error + err_o[0] = syndrome_o[6]; + err_o[1] = |syndrome_o[5:0] & ~syndrome_o[6]; + + dec.data = data_o; + dec.syndrome = syndrome_o; + dec.err = err_o; + return dec; + + endfunction + + function automatic logic [71:0] + prim_secded_hamming_72_64_enc (logic [63:0] data_i); + logic [71:0] data_o; + data_o = 72'(data_i); + data_o[64] = ^(data_o & 72'h00AB55555556AAAD5B); + data_o[65] = ^(data_o & 72'h00CD9999999B33366D); + data_o[66] = ^(data_o & 72'h00F1E1E1E1E3C3C78E); + data_o[67] = ^(data_o & 72'h0001FE01FE03FC07F0); + data_o[68] = ^(data_o & 72'h0001FFFE0003FFF800); + data_o[69] = ^(data_o & 72'h0001FFFFFFFC000000); + data_o[70] = ^(data_o & 72'h00FE00000000000000); + data_o[71] = ^(data_o & 72'h7FFFFFFFFFFFFFFFFF); + return data_o; + endfunction + + function automatic secded_hamming_72_64_t + prim_secded_hamming_72_64_dec (logic [71:0] data_i); + logic [63:0] data_o; + logic [7:0] syndrome_o; + logic [1:0] err_o; + + secded_hamming_72_64_t dec; + + // Syndrome calculation + syndrome_o[0] = ^(data_i & 72'h01AB55555556AAAD5B); + syndrome_o[1] = ^(data_i & 72'h02CD9999999B33366D); + syndrome_o[2] = ^(data_i & 72'h04F1E1E1E1E3C3C78E); + syndrome_o[3] = ^(data_i & 72'h0801FE01FE03FC07F0); + syndrome_o[4] = ^(data_i & 72'h1001FFFE0003FFF800); + syndrome_o[5] = ^(data_i & 72'h2001FFFFFFFC000000); + syndrome_o[6] = ^(data_i & 72'h40FE00000000000000); + syndrome_o[7] = ^(data_i & 72'hFFFFFFFFFFFFFFFFFF); + + // Corrected output calculation + data_o[0] = (syndrome_o == 8'h83) ^ data_i[0]; + data_o[1] = (syndrome_o == 8'h85) ^ data_i[1]; + data_o[2] = (syndrome_o == 8'h86) ^ data_i[2]; + data_o[3] = (syndrome_o == 8'h87) ^ data_i[3]; + data_o[4] = (syndrome_o == 8'h89) ^ data_i[4]; + data_o[5] = (syndrome_o == 8'h8a) ^ data_i[5]; + data_o[6] = (syndrome_o == 8'h8b) ^ data_i[6]; + data_o[7] = (syndrome_o == 8'h8c) ^ data_i[7]; + data_o[8] = (syndrome_o == 8'h8d) ^ data_i[8]; + data_o[9] = (syndrome_o == 8'h8e) ^ data_i[9]; + data_o[10] = (syndrome_o == 8'h8f) ^ data_i[10]; + data_o[11] = (syndrome_o == 8'h91) ^ data_i[11]; + data_o[12] = (syndrome_o == 8'h92) ^ data_i[12]; + data_o[13] = (syndrome_o == 8'h93) ^ data_i[13]; + data_o[14] = (syndrome_o == 8'h94) ^ data_i[14]; + data_o[15] = (syndrome_o == 8'h95) ^ data_i[15]; + data_o[16] = (syndrome_o == 8'h96) ^ data_i[16]; + data_o[17] = (syndrome_o == 8'h97) ^ data_i[17]; + data_o[18] = (syndrome_o == 8'h98) ^ data_i[18]; + data_o[19] = (syndrome_o == 8'h99) ^ data_i[19]; + data_o[20] = (syndrome_o == 8'h9a) ^ data_i[20]; + data_o[21] = (syndrome_o == 8'h9b) ^ data_i[21]; + data_o[22] = (syndrome_o == 8'h9c) ^ data_i[22]; + data_o[23] = (syndrome_o == 8'h9d) ^ data_i[23]; + data_o[24] = (syndrome_o == 8'h9e) ^ data_i[24]; + data_o[25] = (syndrome_o == 8'h9f) ^ data_i[25]; + data_o[26] = (syndrome_o == 8'ha1) ^ data_i[26]; + data_o[27] = (syndrome_o == 8'ha2) ^ data_i[27]; + data_o[28] = (syndrome_o == 8'ha3) ^ data_i[28]; + data_o[29] = (syndrome_o == 8'ha4) ^ data_i[29]; + data_o[30] = (syndrome_o == 8'ha5) ^ data_i[30]; + data_o[31] = (syndrome_o == 8'ha6) ^ data_i[31]; + data_o[32] = (syndrome_o == 8'ha7) ^ data_i[32]; + data_o[33] = (syndrome_o == 8'ha8) ^ data_i[33]; + data_o[34] = (syndrome_o == 8'ha9) ^ data_i[34]; + data_o[35] = (syndrome_o == 8'haa) ^ data_i[35]; + data_o[36] = (syndrome_o == 8'hab) ^ data_i[36]; + data_o[37] = (syndrome_o == 8'hac) ^ data_i[37]; + data_o[38] = (syndrome_o == 8'had) ^ data_i[38]; + data_o[39] = (syndrome_o == 8'hae) ^ data_i[39]; + data_o[40] = (syndrome_o == 8'haf) ^ data_i[40]; + data_o[41] = (syndrome_o == 8'hb0) ^ data_i[41]; + data_o[42] = (syndrome_o == 8'hb1) ^ data_i[42]; + data_o[43] = (syndrome_o == 8'hb2) ^ data_i[43]; + data_o[44] = (syndrome_o == 8'hb3) ^ data_i[44]; + data_o[45] = (syndrome_o == 8'hb4) ^ data_i[45]; + data_o[46] = (syndrome_o == 8'hb5) ^ data_i[46]; + data_o[47] = (syndrome_o == 8'hb6) ^ data_i[47]; + data_o[48] = (syndrome_o == 8'hb7) ^ data_i[48]; + data_o[49] = (syndrome_o == 8'hb8) ^ data_i[49]; + data_o[50] = (syndrome_o == 8'hb9) ^ data_i[50]; + data_o[51] = (syndrome_o == 8'hba) ^ data_i[51]; + data_o[52] = (syndrome_o == 8'hbb) ^ data_i[52]; + data_o[53] = (syndrome_o == 8'hbc) ^ data_i[53]; + data_o[54] = (syndrome_o == 8'hbd) ^ data_i[54]; + data_o[55] = (syndrome_o == 8'hbe) ^ data_i[55]; + data_o[56] = (syndrome_o == 8'hbf) ^ data_i[56]; + data_o[57] = (syndrome_o == 8'hc1) ^ data_i[57]; + data_o[58] = (syndrome_o == 8'hc2) ^ data_i[58]; + data_o[59] = (syndrome_o == 8'hc3) ^ data_i[59]; + data_o[60] = (syndrome_o == 8'hc4) ^ data_i[60]; + data_o[61] = (syndrome_o == 8'hc5) ^ data_i[61]; + data_o[62] = (syndrome_o == 8'hc6) ^ data_i[62]; + data_o[63] = (syndrome_o == 8'hc7) ^ data_i[63]; + + // err_o calc. bit0: single error, bit1: double error + err_o[0] = syndrome_o[7]; + err_o[1] = |syndrome_o[6:0] & ~syndrome_o[7]; + + dec.data = data_o; + dec.syndrome = syndrome_o; + dec.err = err_o; + return dec; + + endfunction + + function automatic logic [75:0] + prim_secded_hamming_76_68_enc (logic [67:0] data_i); + logic [75:0] data_o; + data_o = 76'(data_i); + data_o[68] = ^(data_o & 76'h00AAB55555556AAAD5B); + data_o[69] = ^(data_o & 76'h00CCD9999999B33366D); + data_o[70] = ^(data_o & 76'h000F1E1E1E1E3C3C78E); + data_o[71] = ^(data_o & 76'h00F01FE01FE03FC07F0); + data_o[72] = ^(data_o & 76'h00001FFFE0003FFF800); + data_o[73] = ^(data_o & 76'h00001FFFFFFFC000000); + data_o[74] = ^(data_o & 76'h00FFE00000000000000); + data_o[75] = ^(data_o & 76'h7FFFFFFFFFFFFFFFFFF); + return data_o; + endfunction + + function automatic secded_hamming_76_68_t + prim_secded_hamming_76_68_dec (logic [75:0] data_i); + logic [67:0] data_o; + logic [7:0] syndrome_o; + logic [1:0] err_o; + + secded_hamming_76_68_t dec; + + // Syndrome calculation + syndrome_o[0] = ^(data_i & 76'h01AAB55555556AAAD5B); + syndrome_o[1] = ^(data_i & 76'h02CCD9999999B33366D); + syndrome_o[2] = ^(data_i & 76'h040F1E1E1E1E3C3C78E); + syndrome_o[3] = ^(data_i & 76'h08F01FE01FE03FC07F0); + syndrome_o[4] = ^(data_i & 76'h10001FFFE0003FFF800); + syndrome_o[5] = ^(data_i & 76'h20001FFFFFFFC000000); + syndrome_o[6] = ^(data_i & 76'h40FFE00000000000000); + syndrome_o[7] = ^(data_i & 76'hFFFFFFFFFFFFFFFFFFF); + + // Corrected output calculation + data_o[0] = (syndrome_o == 8'h83) ^ data_i[0]; + data_o[1] = (syndrome_o == 8'h85) ^ data_i[1]; + data_o[2] = (syndrome_o == 8'h86) ^ data_i[2]; + data_o[3] = (syndrome_o == 8'h87) ^ data_i[3]; + data_o[4] = (syndrome_o == 8'h89) ^ data_i[4]; + data_o[5] = (syndrome_o == 8'h8a) ^ data_i[5]; + data_o[6] = (syndrome_o == 8'h8b) ^ data_i[6]; + data_o[7] = (syndrome_o == 8'h8c) ^ data_i[7]; + data_o[8] = (syndrome_o == 8'h8d) ^ data_i[8]; + data_o[9] = (syndrome_o == 8'h8e) ^ data_i[9]; + data_o[10] = (syndrome_o == 8'h8f) ^ data_i[10]; + data_o[11] = (syndrome_o == 8'h91) ^ data_i[11]; + data_o[12] = (syndrome_o == 8'h92) ^ data_i[12]; + data_o[13] = (syndrome_o == 8'h93) ^ data_i[13]; + data_o[14] = (syndrome_o == 8'h94) ^ data_i[14]; + data_o[15] = (syndrome_o == 8'h95) ^ data_i[15]; + data_o[16] = (syndrome_o == 8'h96) ^ data_i[16]; + data_o[17] = (syndrome_o == 8'h97) ^ data_i[17]; + data_o[18] = (syndrome_o == 8'h98) ^ data_i[18]; + data_o[19] = (syndrome_o == 8'h99) ^ data_i[19]; + data_o[20] = (syndrome_o == 8'h9a) ^ data_i[20]; + data_o[21] = (syndrome_o == 8'h9b) ^ data_i[21]; + data_o[22] = (syndrome_o == 8'h9c) ^ data_i[22]; + data_o[23] = (syndrome_o == 8'h9d) ^ data_i[23]; + data_o[24] = (syndrome_o == 8'h9e) ^ data_i[24]; + data_o[25] = (syndrome_o == 8'h9f) ^ data_i[25]; + data_o[26] = (syndrome_o == 8'ha1) ^ data_i[26]; + data_o[27] = (syndrome_o == 8'ha2) ^ data_i[27]; + data_o[28] = (syndrome_o == 8'ha3) ^ data_i[28]; + data_o[29] = (syndrome_o == 8'ha4) ^ data_i[29]; + data_o[30] = (syndrome_o == 8'ha5) ^ data_i[30]; + data_o[31] = (syndrome_o == 8'ha6) ^ data_i[31]; + data_o[32] = (syndrome_o == 8'ha7) ^ data_i[32]; + data_o[33] = (syndrome_o == 8'ha8) ^ data_i[33]; + data_o[34] = (syndrome_o == 8'ha9) ^ data_i[34]; + data_o[35] = (syndrome_o == 8'haa) ^ data_i[35]; + data_o[36] = (syndrome_o == 8'hab) ^ data_i[36]; + data_o[37] = (syndrome_o == 8'hac) ^ data_i[37]; + data_o[38] = (syndrome_o == 8'had) ^ data_i[38]; + data_o[39] = (syndrome_o == 8'hae) ^ data_i[39]; + data_o[40] = (syndrome_o == 8'haf) ^ data_i[40]; + data_o[41] = (syndrome_o == 8'hb0) ^ data_i[41]; + data_o[42] = (syndrome_o == 8'hb1) ^ data_i[42]; + data_o[43] = (syndrome_o == 8'hb2) ^ data_i[43]; + data_o[44] = (syndrome_o == 8'hb3) ^ data_i[44]; + data_o[45] = (syndrome_o == 8'hb4) ^ data_i[45]; + data_o[46] = (syndrome_o == 8'hb5) ^ data_i[46]; + data_o[47] = (syndrome_o == 8'hb6) ^ data_i[47]; + data_o[48] = (syndrome_o == 8'hb7) ^ data_i[48]; + data_o[49] = (syndrome_o == 8'hb8) ^ data_i[49]; + data_o[50] = (syndrome_o == 8'hb9) ^ data_i[50]; + data_o[51] = (syndrome_o == 8'hba) ^ data_i[51]; + data_o[52] = (syndrome_o == 8'hbb) ^ data_i[52]; + data_o[53] = (syndrome_o == 8'hbc) ^ data_i[53]; + data_o[54] = (syndrome_o == 8'hbd) ^ data_i[54]; + data_o[55] = (syndrome_o == 8'hbe) ^ data_i[55]; + data_o[56] = (syndrome_o == 8'hbf) ^ data_i[56]; + data_o[57] = (syndrome_o == 8'hc1) ^ data_i[57]; + data_o[58] = (syndrome_o == 8'hc2) ^ data_i[58]; + data_o[59] = (syndrome_o == 8'hc3) ^ data_i[59]; + data_o[60] = (syndrome_o == 8'hc4) ^ data_i[60]; + data_o[61] = (syndrome_o == 8'hc5) ^ data_i[61]; + data_o[62] = (syndrome_o == 8'hc6) ^ data_i[62]; + data_o[63] = (syndrome_o == 8'hc7) ^ data_i[63]; + data_o[64] = (syndrome_o == 8'hc8) ^ data_i[64]; + data_o[65] = (syndrome_o == 8'hc9) ^ data_i[65]; + data_o[66] = (syndrome_o == 8'hca) ^ data_i[66]; + data_o[67] = (syndrome_o == 8'hcb) ^ data_i[67]; + + // err_o calc. bit0: single error, bit1: double error + err_o[0] = syndrome_o[7]; + err_o[1] = |syndrome_o[6:0] & ~syndrome_o[7]; + + dec.data = data_o; + dec.syndrome = syndrome_o; + dec.err = err_o; + return dec; + + endfunction + + function automatic logic [21:0] + prim_secded_inv_22_16_enc (logic [15:0] data_i); + logic [21:0] data_o; + data_o = 22'(data_i); + data_o[16] = ^(data_o & 22'h00496E); + data_o[17] = ^(data_o & 22'h00F20B); + data_o[18] = ^(data_o & 22'h008ED8); + data_o[19] = ^(data_o & 22'h007714); + data_o[20] = ^(data_o & 22'h00ACA5); + data_o[21] = ^(data_o & 22'h0011F3); + data_o ^= 22'h2A0000; + return data_o; + endfunction + + function automatic secded_inv_22_16_t + prim_secded_inv_22_16_dec (logic [21:0] data_i); + logic [15:0] data_o; + logic [5:0] syndrome_o; + logic [1:0] err_o; + + secded_inv_22_16_t dec; + + // Syndrome calculation + syndrome_o[0] = ^((data_i ^ 22'h2A0000) & 22'h01496E); + syndrome_o[1] = ^((data_i ^ 22'h2A0000) & 22'h02F20B); + syndrome_o[2] = ^((data_i ^ 22'h2A0000) & 22'h048ED8); + syndrome_o[3] = ^((data_i ^ 22'h2A0000) & 22'h087714); + syndrome_o[4] = ^((data_i ^ 22'h2A0000) & 22'h10ACA5); + syndrome_o[5] = ^((data_i ^ 22'h2A0000) & 22'h2011F3); + + // Corrected output calculation + data_o[0] = (syndrome_o == 6'h32) ^ data_i[0]; + data_o[1] = (syndrome_o == 6'h23) ^ data_i[1]; + data_o[2] = (syndrome_o == 6'h19) ^ data_i[2]; + data_o[3] = (syndrome_o == 6'h7) ^ data_i[3]; + data_o[4] = (syndrome_o == 6'h2c) ^ data_i[4]; + data_o[5] = (syndrome_o == 6'h31) ^ data_i[5]; + data_o[6] = (syndrome_o == 6'h25) ^ data_i[6]; + data_o[7] = (syndrome_o == 6'h34) ^ data_i[7]; + data_o[8] = (syndrome_o == 6'h29) ^ data_i[8]; + data_o[9] = (syndrome_o == 6'he) ^ data_i[9]; + data_o[10] = (syndrome_o == 6'h1c) ^ data_i[10]; + data_o[11] = (syndrome_o == 6'h15) ^ data_i[11]; + data_o[12] = (syndrome_o == 6'h2a) ^ data_i[12]; + data_o[13] = (syndrome_o == 6'h1a) ^ data_i[13]; + data_o[14] = (syndrome_o == 6'hb) ^ data_i[14]; + data_o[15] = (syndrome_o == 6'h16) ^ data_i[15]; + + // err_o calc. bit0: single error, bit1: double error + err_o[0] = ^syndrome_o; + err_o[1] = ~err_o[0] & (|syndrome_o); + + dec.data = data_o; + dec.syndrome = syndrome_o; + dec.err = err_o; + return dec; + + endfunction + + function automatic logic [27:0] + prim_secded_inv_28_22_enc (logic [21:0] data_i); + logic [27:0] data_o; + data_o = 28'(data_i); + data_o[22] = ^(data_o & 28'h03003FF); + data_o[23] = ^(data_o & 28'h010FC0F); + data_o[24] = ^(data_o & 28'h0271C71); + data_o[25] = ^(data_o & 28'h03B6592); + data_o[26] = ^(data_o & 28'h03DAAA4); + data_o[27] = ^(data_o & 28'h03ED348); + data_o ^= 28'hA800000; + return data_o; + endfunction + + function automatic secded_inv_28_22_t + prim_secded_inv_28_22_dec (logic [27:0] data_i); + logic [21:0] data_o; + logic [5:0] syndrome_o; + logic [1:0] err_o; + + secded_inv_28_22_t dec; + + // Syndrome calculation + syndrome_o[0] = ^((data_i ^ 28'hA800000) & 28'h07003FF); + syndrome_o[1] = ^((data_i ^ 28'hA800000) & 28'h090FC0F); + syndrome_o[2] = ^((data_i ^ 28'hA800000) & 28'h1271C71); + syndrome_o[3] = ^((data_i ^ 28'hA800000) & 28'h23B6592); + syndrome_o[4] = ^((data_i ^ 28'hA800000) & 28'h43DAAA4); + syndrome_o[5] = ^((data_i ^ 28'hA800000) & 28'h83ED348); + + // Corrected output calculation + data_o[0] = (syndrome_o == 6'h7) ^ data_i[0]; + data_o[1] = (syndrome_o == 6'hb) ^ data_i[1]; + data_o[2] = (syndrome_o == 6'h13) ^ data_i[2]; + data_o[3] = (syndrome_o == 6'h23) ^ data_i[3]; + data_o[4] = (syndrome_o == 6'hd) ^ data_i[4]; + data_o[5] = (syndrome_o == 6'h15) ^ data_i[5]; + data_o[6] = (syndrome_o == 6'h25) ^ data_i[6]; + data_o[7] = (syndrome_o == 6'h19) ^ data_i[7]; + data_o[8] = (syndrome_o == 6'h29) ^ data_i[8]; + data_o[9] = (syndrome_o == 6'h31) ^ data_i[9]; + data_o[10] = (syndrome_o == 6'he) ^ data_i[10]; + data_o[11] = (syndrome_o == 6'h16) ^ data_i[11]; + data_o[12] = (syndrome_o == 6'h26) ^ data_i[12]; + data_o[13] = (syndrome_o == 6'h1a) ^ data_i[13]; + data_o[14] = (syndrome_o == 6'h2a) ^ data_i[14]; + data_o[15] = (syndrome_o == 6'h32) ^ data_i[15]; + data_o[16] = (syndrome_o == 6'h1c) ^ data_i[16]; + data_o[17] = (syndrome_o == 6'h2c) ^ data_i[17]; + data_o[18] = (syndrome_o == 6'h34) ^ data_i[18]; + data_o[19] = (syndrome_o == 6'h38) ^ data_i[19]; + data_o[20] = (syndrome_o == 6'h3b) ^ data_i[20]; + data_o[21] = (syndrome_o == 6'h3d) ^ data_i[21]; + + // err_o calc. bit0: single error, bit1: double error + err_o[0] = ^syndrome_o; + err_o[1] = ~err_o[0] & (|syndrome_o); + + dec.data = data_o; + dec.syndrome = syndrome_o; + dec.err = err_o; + return dec; + + endfunction + + function automatic logic [38:0] + caliptra_prim_secded_inv_39_32_enc (logic [31:0] data_i); + logic [38:0] data_o; + data_o = 39'(data_i); + data_o[32] = ^(data_o & 39'h002606BD25); + data_o[33] = ^(data_o & 39'h00DEBA8050); + data_o[34] = ^(data_o & 39'h00413D89AA); + data_o[35] = ^(data_o & 39'h0031234ED1); + data_o[36] = ^(data_o & 39'h00C2C1323B); + data_o[37] = ^(data_o & 39'h002DCC624C); + data_o[38] = ^(data_o & 39'h0098505586); + data_o ^= 39'h2A00000000; + return data_o; + endfunction + + function automatic secded_inv_39_32_t + caliptra_prim_secded_inv_39_32_dec (logic [38:0] data_i); + logic [31:0] data_o; + logic [6:0] syndrome_o; + logic [1:0] err_o; + + secded_inv_39_32_t dec; + + // Syndrome calculation + syndrome_o[0] = ^((data_i ^ 39'h2A00000000) & 39'h012606BD25); + syndrome_o[1] = ^((data_i ^ 39'h2A00000000) & 39'h02DEBA8050); + syndrome_o[2] = ^((data_i ^ 39'h2A00000000) & 39'h04413D89AA); + syndrome_o[3] = ^((data_i ^ 39'h2A00000000) & 39'h0831234ED1); + syndrome_o[4] = ^((data_i ^ 39'h2A00000000) & 39'h10C2C1323B); + syndrome_o[5] = ^((data_i ^ 39'h2A00000000) & 39'h202DCC624C); + syndrome_o[6] = ^((data_i ^ 39'h2A00000000) & 39'h4098505586); + + // Corrected output calculation + data_o[0] = (syndrome_o == 7'h19) ^ data_i[0]; + data_o[1] = (syndrome_o == 7'h54) ^ data_i[1]; + data_o[2] = (syndrome_o == 7'h61) ^ data_i[2]; + data_o[3] = (syndrome_o == 7'h34) ^ data_i[3]; + data_o[4] = (syndrome_o == 7'h1a) ^ data_i[4]; + data_o[5] = (syndrome_o == 7'h15) ^ data_i[5]; + data_o[6] = (syndrome_o == 7'h2a) ^ data_i[6]; + data_o[7] = (syndrome_o == 7'h4c) ^ data_i[7]; + data_o[8] = (syndrome_o == 7'h45) ^ data_i[8]; + data_o[9] = (syndrome_o == 7'h38) ^ data_i[9]; + data_o[10] = (syndrome_o == 7'h49) ^ data_i[10]; + data_o[11] = (syndrome_o == 7'hd) ^ data_i[11]; + data_o[12] = (syndrome_o == 7'h51) ^ data_i[12]; + data_o[13] = (syndrome_o == 7'h31) ^ data_i[13]; + data_o[14] = (syndrome_o == 7'h68) ^ data_i[14]; + data_o[15] = (syndrome_o == 7'h7) ^ data_i[15]; + data_o[16] = (syndrome_o == 7'h1c) ^ data_i[16]; + data_o[17] = (syndrome_o == 7'hb) ^ data_i[17]; + data_o[18] = (syndrome_o == 7'h25) ^ data_i[18]; + data_o[19] = (syndrome_o == 7'h26) ^ data_i[19]; + data_o[20] = (syndrome_o == 7'h46) ^ data_i[20]; + data_o[21] = (syndrome_o == 7'he) ^ data_i[21]; + data_o[22] = (syndrome_o == 7'h70) ^ data_i[22]; + data_o[23] = (syndrome_o == 7'h32) ^ data_i[23]; + data_o[24] = (syndrome_o == 7'h2c) ^ data_i[24]; + data_o[25] = (syndrome_o == 7'h13) ^ data_i[25]; + data_o[26] = (syndrome_o == 7'h23) ^ data_i[26]; + data_o[27] = (syndrome_o == 7'h62) ^ data_i[27]; + data_o[28] = (syndrome_o == 7'h4a) ^ data_i[28]; + data_o[29] = (syndrome_o == 7'h29) ^ data_i[29]; + data_o[30] = (syndrome_o == 7'h16) ^ data_i[30]; + data_o[31] = (syndrome_o == 7'h52) ^ data_i[31]; + + // err_o calc. bit0: single error, bit1: double error + err_o[0] = ^syndrome_o; + err_o[1] = ~err_o[0] & (|syndrome_o); + + dec.data = data_o; + dec.syndrome = syndrome_o; + dec.err = err_o; + return dec; + + endfunction + + function automatic logic [63:0] + caliptra_prim_secded_inv_64_57_enc (logic [56:0] data_i); + logic [63:0] data_o; + data_o = 64'(data_i); + data_o[57] = ^(data_o & 64'h0103FFF800007FFF); + data_o[58] = ^(data_o & 64'h017C1FF801FF801F); + data_o[59] = ^(data_o & 64'h01BDE1F87E0781E1); + data_o[60] = ^(data_o & 64'h01DEEE3B8E388E22); + data_o[61] = ^(data_o & 64'h01EF76CDB2C93244); + data_o[62] = ^(data_o & 64'h01F7BB56D5525488); + data_o[63] = ^(data_o & 64'h01FBDDA769A46910); + data_o ^= 64'h5400000000000000; + return data_o; + endfunction + + function automatic secded_inv_64_57_t + caliptra_prim_secded_inv_64_57_dec (logic [63:0] data_i); + logic [56:0] data_o; + logic [6:0] syndrome_o; + logic [1:0] err_o; + + secded_inv_64_57_t dec; + + // Syndrome calculation + syndrome_o[0] = ^((data_i ^ 64'h5400000000000000) & 64'h0303FFF800007FFF); + syndrome_o[1] = ^((data_i ^ 64'h5400000000000000) & 64'h057C1FF801FF801F); + syndrome_o[2] = ^((data_i ^ 64'h5400000000000000) & 64'h09BDE1F87E0781E1); + syndrome_o[3] = ^((data_i ^ 64'h5400000000000000) & 64'h11DEEE3B8E388E22); + syndrome_o[4] = ^((data_i ^ 64'h5400000000000000) & 64'h21EF76CDB2C93244); + syndrome_o[5] = ^((data_i ^ 64'h5400000000000000) & 64'h41F7BB56D5525488); + syndrome_o[6] = ^((data_i ^ 64'h5400000000000000) & 64'h81FBDDA769A46910); + + // Corrected output calculation + data_o[0] = (syndrome_o == 7'h7) ^ data_i[0]; + data_o[1] = (syndrome_o == 7'hb) ^ data_i[1]; + data_o[2] = (syndrome_o == 7'h13) ^ data_i[2]; + data_o[3] = (syndrome_o == 7'h23) ^ data_i[3]; + data_o[4] = (syndrome_o == 7'h43) ^ data_i[4]; + data_o[5] = (syndrome_o == 7'hd) ^ data_i[5]; + data_o[6] = (syndrome_o == 7'h15) ^ data_i[6]; + data_o[7] = (syndrome_o == 7'h25) ^ data_i[7]; + data_o[8] = (syndrome_o == 7'h45) ^ data_i[8]; + data_o[9] = (syndrome_o == 7'h19) ^ data_i[9]; + data_o[10] = (syndrome_o == 7'h29) ^ data_i[10]; + data_o[11] = (syndrome_o == 7'h49) ^ data_i[11]; + data_o[12] = (syndrome_o == 7'h31) ^ data_i[12]; + data_o[13] = (syndrome_o == 7'h51) ^ data_i[13]; + data_o[14] = (syndrome_o == 7'h61) ^ data_i[14]; + data_o[15] = (syndrome_o == 7'he) ^ data_i[15]; + data_o[16] = (syndrome_o == 7'h16) ^ data_i[16]; + data_o[17] = (syndrome_o == 7'h26) ^ data_i[17]; + data_o[18] = (syndrome_o == 7'h46) ^ data_i[18]; + data_o[19] = (syndrome_o == 7'h1a) ^ data_i[19]; + data_o[20] = (syndrome_o == 7'h2a) ^ data_i[20]; + data_o[21] = (syndrome_o == 7'h4a) ^ data_i[21]; + data_o[22] = (syndrome_o == 7'h32) ^ data_i[22]; + data_o[23] = (syndrome_o == 7'h52) ^ data_i[23]; + data_o[24] = (syndrome_o == 7'h62) ^ data_i[24]; + data_o[25] = (syndrome_o == 7'h1c) ^ data_i[25]; + data_o[26] = (syndrome_o == 7'h2c) ^ data_i[26]; + data_o[27] = (syndrome_o == 7'h4c) ^ data_i[27]; + data_o[28] = (syndrome_o == 7'h34) ^ data_i[28]; + data_o[29] = (syndrome_o == 7'h54) ^ data_i[29]; + data_o[30] = (syndrome_o == 7'h64) ^ data_i[30]; + data_o[31] = (syndrome_o == 7'h38) ^ data_i[31]; + data_o[32] = (syndrome_o == 7'h58) ^ data_i[32]; + data_o[33] = (syndrome_o == 7'h68) ^ data_i[33]; + data_o[34] = (syndrome_o == 7'h70) ^ data_i[34]; + data_o[35] = (syndrome_o == 7'h1f) ^ data_i[35]; + data_o[36] = (syndrome_o == 7'h2f) ^ data_i[36]; + data_o[37] = (syndrome_o == 7'h4f) ^ data_i[37]; + data_o[38] = (syndrome_o == 7'h37) ^ data_i[38]; + data_o[39] = (syndrome_o == 7'h57) ^ data_i[39]; + data_o[40] = (syndrome_o == 7'h67) ^ data_i[40]; + data_o[41] = (syndrome_o == 7'h3b) ^ data_i[41]; + data_o[42] = (syndrome_o == 7'h5b) ^ data_i[42]; + data_o[43] = (syndrome_o == 7'h6b) ^ data_i[43]; + data_o[44] = (syndrome_o == 7'h73) ^ data_i[44]; + data_o[45] = (syndrome_o == 7'h3d) ^ data_i[45]; + data_o[46] = (syndrome_o == 7'h5d) ^ data_i[46]; + data_o[47] = (syndrome_o == 7'h6d) ^ data_i[47]; + data_o[48] = (syndrome_o == 7'h75) ^ data_i[48]; + data_o[49] = (syndrome_o == 7'h79) ^ data_i[49]; + data_o[50] = (syndrome_o == 7'h3e) ^ data_i[50]; + data_o[51] = (syndrome_o == 7'h5e) ^ data_i[51]; + data_o[52] = (syndrome_o == 7'h6e) ^ data_i[52]; + data_o[53] = (syndrome_o == 7'h76) ^ data_i[53]; + data_o[54] = (syndrome_o == 7'h7a) ^ data_i[54]; + data_o[55] = (syndrome_o == 7'h7c) ^ data_i[55]; + data_o[56] = (syndrome_o == 7'h7f) ^ data_i[56]; + + // err_o calc. bit0: single error, bit1: double error + err_o[0] = ^syndrome_o; + err_o[1] = ~err_o[0] & (|syndrome_o); + + dec.data = data_o; + dec.syndrome = syndrome_o; + dec.err = err_o; + return dec; + + endfunction + + function automatic logic [71:0] + prim_secded_inv_72_64_enc (logic [63:0] data_i); + logic [71:0] data_o; + data_o = 72'(data_i); + data_o[64] = ^(data_o & 72'h00B9000000001FFFFF); + data_o[65] = ^(data_o & 72'h005E00000FFFE0003F); + data_o[66] = ^(data_o & 72'h0067003FF003E007C1); + data_o[67] = ^(data_o & 72'h00CD0FC0F03C207842); + data_o[68] = ^(data_o & 72'h00B671C711C4438884); + data_o[69] = ^(data_o & 72'h00B5B65926488C9108); + data_o[70] = ^(data_o & 72'h00CBDAAA4A91152210); + data_o[71] = ^(data_o & 72'h007AED348D221A4420); + data_o ^= 72'hAA0000000000000000; + return data_o; + endfunction + + function automatic secded_inv_72_64_t + prim_secded_inv_72_64_dec (logic [71:0] data_i); + logic [63:0] data_o; + logic [7:0] syndrome_o; + logic [1:0] err_o; + + secded_inv_72_64_t dec; + + // Syndrome calculation + syndrome_o[0] = ^((data_i ^ 72'hAA0000000000000000) & 72'h01B9000000001FFFFF); + syndrome_o[1] = ^((data_i ^ 72'hAA0000000000000000) & 72'h025E00000FFFE0003F); + syndrome_o[2] = ^((data_i ^ 72'hAA0000000000000000) & 72'h0467003FF003E007C1); + syndrome_o[3] = ^((data_i ^ 72'hAA0000000000000000) & 72'h08CD0FC0F03C207842); + syndrome_o[4] = ^((data_i ^ 72'hAA0000000000000000) & 72'h10B671C711C4438884); + syndrome_o[5] = ^((data_i ^ 72'hAA0000000000000000) & 72'h20B5B65926488C9108); + syndrome_o[6] = ^((data_i ^ 72'hAA0000000000000000) & 72'h40CBDAAA4A91152210); + syndrome_o[7] = ^((data_i ^ 72'hAA0000000000000000) & 72'h807AED348D221A4420); + + // Corrected output calculation + data_o[0] = (syndrome_o == 8'h7) ^ data_i[0]; + data_o[1] = (syndrome_o == 8'hb) ^ data_i[1]; + data_o[2] = (syndrome_o == 8'h13) ^ data_i[2]; + data_o[3] = (syndrome_o == 8'h23) ^ data_i[3]; + data_o[4] = (syndrome_o == 8'h43) ^ data_i[4]; + data_o[5] = (syndrome_o == 8'h83) ^ data_i[5]; + data_o[6] = (syndrome_o == 8'hd) ^ data_i[6]; + data_o[7] = (syndrome_o == 8'h15) ^ data_i[7]; + data_o[8] = (syndrome_o == 8'h25) ^ data_i[8]; + data_o[9] = (syndrome_o == 8'h45) ^ data_i[9]; + data_o[10] = (syndrome_o == 8'h85) ^ data_i[10]; + data_o[11] = (syndrome_o == 8'h19) ^ data_i[11]; + data_o[12] = (syndrome_o == 8'h29) ^ data_i[12]; + data_o[13] = (syndrome_o == 8'h49) ^ data_i[13]; + data_o[14] = (syndrome_o == 8'h89) ^ data_i[14]; + data_o[15] = (syndrome_o == 8'h31) ^ data_i[15]; + data_o[16] = (syndrome_o == 8'h51) ^ data_i[16]; + data_o[17] = (syndrome_o == 8'h91) ^ data_i[17]; + data_o[18] = (syndrome_o == 8'h61) ^ data_i[18]; + data_o[19] = (syndrome_o == 8'ha1) ^ data_i[19]; + data_o[20] = (syndrome_o == 8'hc1) ^ data_i[20]; + data_o[21] = (syndrome_o == 8'he) ^ data_i[21]; + data_o[22] = (syndrome_o == 8'h16) ^ data_i[22]; + data_o[23] = (syndrome_o == 8'h26) ^ data_i[23]; + data_o[24] = (syndrome_o == 8'h46) ^ data_i[24]; + data_o[25] = (syndrome_o == 8'h86) ^ data_i[25]; + data_o[26] = (syndrome_o == 8'h1a) ^ data_i[26]; + data_o[27] = (syndrome_o == 8'h2a) ^ data_i[27]; + data_o[28] = (syndrome_o == 8'h4a) ^ data_i[28]; + data_o[29] = (syndrome_o == 8'h8a) ^ data_i[29]; + data_o[30] = (syndrome_o == 8'h32) ^ data_i[30]; + data_o[31] = (syndrome_o == 8'h52) ^ data_i[31]; + data_o[32] = (syndrome_o == 8'h92) ^ data_i[32]; + data_o[33] = (syndrome_o == 8'h62) ^ data_i[33]; + data_o[34] = (syndrome_o == 8'ha2) ^ data_i[34]; + data_o[35] = (syndrome_o == 8'hc2) ^ data_i[35]; + data_o[36] = (syndrome_o == 8'h1c) ^ data_i[36]; + data_o[37] = (syndrome_o == 8'h2c) ^ data_i[37]; + data_o[38] = (syndrome_o == 8'h4c) ^ data_i[38]; + data_o[39] = (syndrome_o == 8'h8c) ^ data_i[39]; + data_o[40] = (syndrome_o == 8'h34) ^ data_i[40]; + data_o[41] = (syndrome_o == 8'h54) ^ data_i[41]; + data_o[42] = (syndrome_o == 8'h94) ^ data_i[42]; + data_o[43] = (syndrome_o == 8'h64) ^ data_i[43]; + data_o[44] = (syndrome_o == 8'ha4) ^ data_i[44]; + data_o[45] = (syndrome_o == 8'hc4) ^ data_i[45]; + data_o[46] = (syndrome_o == 8'h38) ^ data_i[46]; + data_o[47] = (syndrome_o == 8'h58) ^ data_i[47]; + data_o[48] = (syndrome_o == 8'h98) ^ data_i[48]; + data_o[49] = (syndrome_o == 8'h68) ^ data_i[49]; + data_o[50] = (syndrome_o == 8'ha8) ^ data_i[50]; + data_o[51] = (syndrome_o == 8'hc8) ^ data_i[51]; + data_o[52] = (syndrome_o == 8'h70) ^ data_i[52]; + data_o[53] = (syndrome_o == 8'hb0) ^ data_i[53]; + data_o[54] = (syndrome_o == 8'hd0) ^ data_i[54]; + data_o[55] = (syndrome_o == 8'he0) ^ data_i[55]; + data_o[56] = (syndrome_o == 8'h6d) ^ data_i[56]; + data_o[57] = (syndrome_o == 8'hd6) ^ data_i[57]; + data_o[58] = (syndrome_o == 8'h3e) ^ data_i[58]; + data_o[59] = (syndrome_o == 8'hcb) ^ data_i[59]; + data_o[60] = (syndrome_o == 8'hb3) ^ data_i[60]; + data_o[61] = (syndrome_o == 8'hb5) ^ data_i[61]; + data_o[62] = (syndrome_o == 8'hce) ^ data_i[62]; + data_o[63] = (syndrome_o == 8'h79) ^ data_i[63]; + + // err_o calc. bit0: single error, bit1: double error + err_o[0] = ^syndrome_o; + err_o[1] = ~err_o[0] & (|syndrome_o); + + dec.data = data_o; + dec.syndrome = syndrome_o; + dec.err = err_o; + return dec; + + endfunction + + function automatic logic [21:0] + prim_secded_inv_hamming_22_16_enc (logic [15:0] data_i); + logic [21:0] data_o; + data_o = 22'(data_i); + data_o[16] = ^(data_o & 22'h00AD5B); + data_o[17] = ^(data_o & 22'h00366D); + data_o[18] = ^(data_o & 22'h00C78E); + data_o[19] = ^(data_o & 22'h0007F0); + data_o[20] = ^(data_o & 22'h00F800); + data_o[21] = ^(data_o & 22'h1FFFFF); + data_o ^= 22'h2A0000; + return data_o; + endfunction + + function automatic secded_inv_hamming_22_16_t + prim_secded_inv_hamming_22_16_dec (logic [21:0] data_i); + logic [15:0] data_o; + logic [5:0] syndrome_o; + logic [1:0] err_o; + + secded_inv_hamming_22_16_t dec; + + // Syndrome calculation + syndrome_o[0] = ^((data_i ^ 22'h2A0000) & 22'h01AD5B); + syndrome_o[1] = ^((data_i ^ 22'h2A0000) & 22'h02366D); + syndrome_o[2] = ^((data_i ^ 22'h2A0000) & 22'h04C78E); + syndrome_o[3] = ^((data_i ^ 22'h2A0000) & 22'h0807F0); + syndrome_o[4] = ^((data_i ^ 22'h2A0000) & 22'h10F800); + syndrome_o[5] = ^((data_i ^ 22'h2A0000) & 22'h3FFFFF); + + // Corrected output calculation + data_o[0] = (syndrome_o == 6'h23) ^ data_i[0]; + data_o[1] = (syndrome_o == 6'h25) ^ data_i[1]; + data_o[2] = (syndrome_o == 6'h26) ^ data_i[2]; + data_o[3] = (syndrome_o == 6'h27) ^ data_i[3]; + data_o[4] = (syndrome_o == 6'h29) ^ data_i[4]; + data_o[5] = (syndrome_o == 6'h2a) ^ data_i[5]; + data_o[6] = (syndrome_o == 6'h2b) ^ data_i[6]; + data_o[7] = (syndrome_o == 6'h2c) ^ data_i[7]; + data_o[8] = (syndrome_o == 6'h2d) ^ data_i[8]; + data_o[9] = (syndrome_o == 6'h2e) ^ data_i[9]; + data_o[10] = (syndrome_o == 6'h2f) ^ data_i[10]; + data_o[11] = (syndrome_o == 6'h31) ^ data_i[11]; + data_o[12] = (syndrome_o == 6'h32) ^ data_i[12]; + data_o[13] = (syndrome_o == 6'h33) ^ data_i[13]; + data_o[14] = (syndrome_o == 6'h34) ^ data_i[14]; + data_o[15] = (syndrome_o == 6'h35) ^ data_i[15]; + + // err_o calc. bit0: single error, bit1: double error + err_o[0] = syndrome_o[5]; + err_o[1] = |syndrome_o[4:0] & ~syndrome_o[5]; + + dec.data = data_o; + dec.syndrome = syndrome_o; + dec.err = err_o; + return dec; + + endfunction + + function automatic logic [38:0] + prim_secded_inv_hamming_39_32_enc (logic [31:0] data_i); + logic [38:0] data_o; + data_o = 39'(data_i); + data_o[32] = ^(data_o & 39'h0056AAAD5B); + data_o[33] = ^(data_o & 39'h009B33366D); + data_o[34] = ^(data_o & 39'h00E3C3C78E); + data_o[35] = ^(data_o & 39'h0003FC07F0); + data_o[36] = ^(data_o & 39'h0003FFF800); + data_o[37] = ^(data_o & 39'h00FC000000); + data_o[38] = ^(data_o & 39'h3FFFFFFFFF); + data_o ^= 39'h2A00000000; + return data_o; + endfunction + + function automatic secded_inv_hamming_39_32_t + prim_secded_inv_hamming_39_32_dec (logic [38:0] data_i); + logic [31:0] data_o; + logic [6:0] syndrome_o; + logic [1:0] err_o; + + secded_inv_hamming_39_32_t dec; + + // Syndrome calculation + syndrome_o[0] = ^((data_i ^ 39'h2A00000000) & 39'h0156AAAD5B); + syndrome_o[1] = ^((data_i ^ 39'h2A00000000) & 39'h029B33366D); + syndrome_o[2] = ^((data_i ^ 39'h2A00000000) & 39'h04E3C3C78E); + syndrome_o[3] = ^((data_i ^ 39'h2A00000000) & 39'h0803FC07F0); + syndrome_o[4] = ^((data_i ^ 39'h2A00000000) & 39'h1003FFF800); + syndrome_o[5] = ^((data_i ^ 39'h2A00000000) & 39'h20FC000000); + syndrome_o[6] = ^((data_i ^ 39'h2A00000000) & 39'h7FFFFFFFFF); + + // Corrected output calculation + data_o[0] = (syndrome_o == 7'h43) ^ data_i[0]; + data_o[1] = (syndrome_o == 7'h45) ^ data_i[1]; + data_o[2] = (syndrome_o == 7'h46) ^ data_i[2]; + data_o[3] = (syndrome_o == 7'h47) ^ data_i[3]; + data_o[4] = (syndrome_o == 7'h49) ^ data_i[4]; + data_o[5] = (syndrome_o == 7'h4a) ^ data_i[5]; + data_o[6] = (syndrome_o == 7'h4b) ^ data_i[6]; + data_o[7] = (syndrome_o == 7'h4c) ^ data_i[7]; + data_o[8] = (syndrome_o == 7'h4d) ^ data_i[8]; + data_o[9] = (syndrome_o == 7'h4e) ^ data_i[9]; + data_o[10] = (syndrome_o == 7'h4f) ^ data_i[10]; + data_o[11] = (syndrome_o == 7'h51) ^ data_i[11]; + data_o[12] = (syndrome_o == 7'h52) ^ data_i[12]; + data_o[13] = (syndrome_o == 7'h53) ^ data_i[13]; + data_o[14] = (syndrome_o == 7'h54) ^ data_i[14]; + data_o[15] = (syndrome_o == 7'h55) ^ data_i[15]; + data_o[16] = (syndrome_o == 7'h56) ^ data_i[16]; + data_o[17] = (syndrome_o == 7'h57) ^ data_i[17]; + data_o[18] = (syndrome_o == 7'h58) ^ data_i[18]; + data_o[19] = (syndrome_o == 7'h59) ^ data_i[19]; + data_o[20] = (syndrome_o == 7'h5a) ^ data_i[20]; + data_o[21] = (syndrome_o == 7'h5b) ^ data_i[21]; + data_o[22] = (syndrome_o == 7'h5c) ^ data_i[22]; + data_o[23] = (syndrome_o == 7'h5d) ^ data_i[23]; + data_o[24] = (syndrome_o == 7'h5e) ^ data_i[24]; + data_o[25] = (syndrome_o == 7'h5f) ^ data_i[25]; + data_o[26] = (syndrome_o == 7'h61) ^ data_i[26]; + data_o[27] = (syndrome_o == 7'h62) ^ data_i[27]; + data_o[28] = (syndrome_o == 7'h63) ^ data_i[28]; + data_o[29] = (syndrome_o == 7'h64) ^ data_i[29]; + data_o[30] = (syndrome_o == 7'h65) ^ data_i[30]; + data_o[31] = (syndrome_o == 7'h66) ^ data_i[31]; + + // err_o calc. bit0: single error, bit1: double error + err_o[0] = syndrome_o[6]; + err_o[1] = |syndrome_o[5:0] & ~syndrome_o[6]; + + dec.data = data_o; + dec.syndrome = syndrome_o; + dec.err = err_o; + return dec; + + endfunction + + function automatic logic [71:0] + prim_secded_inv_hamming_72_64_enc (logic [63:0] data_i); + logic [71:0] data_o; + data_o = 72'(data_i); + data_o[64] = ^(data_o & 72'h00AB55555556AAAD5B); + data_o[65] = ^(data_o & 72'h00CD9999999B33366D); + data_o[66] = ^(data_o & 72'h00F1E1E1E1E3C3C78E); + data_o[67] = ^(data_o & 72'h0001FE01FE03FC07F0); + data_o[68] = ^(data_o & 72'h0001FFFE0003FFF800); + data_o[69] = ^(data_o & 72'h0001FFFFFFFC000000); + data_o[70] = ^(data_o & 72'h00FE00000000000000); + data_o[71] = ^(data_o & 72'h7FFFFFFFFFFFFFFFFF); + data_o ^= 72'hAA0000000000000000; + return data_o; + endfunction + + function automatic secded_inv_hamming_72_64_t + prim_secded_inv_hamming_72_64_dec (logic [71:0] data_i); + logic [63:0] data_o; + logic [7:0] syndrome_o; + logic [1:0] err_o; + + secded_inv_hamming_72_64_t dec; + + // Syndrome calculation + syndrome_o[0] = ^((data_i ^ 72'hAA0000000000000000) & 72'h01AB55555556AAAD5B); + syndrome_o[1] = ^((data_i ^ 72'hAA0000000000000000) & 72'h02CD9999999B33366D); + syndrome_o[2] = ^((data_i ^ 72'hAA0000000000000000) & 72'h04F1E1E1E1E3C3C78E); + syndrome_o[3] = ^((data_i ^ 72'hAA0000000000000000) & 72'h0801FE01FE03FC07F0); + syndrome_o[4] = ^((data_i ^ 72'hAA0000000000000000) & 72'h1001FFFE0003FFF800); + syndrome_o[5] = ^((data_i ^ 72'hAA0000000000000000) & 72'h2001FFFFFFFC000000); + syndrome_o[6] = ^((data_i ^ 72'hAA0000000000000000) & 72'h40FE00000000000000); + syndrome_o[7] = ^((data_i ^ 72'hAA0000000000000000) & 72'hFFFFFFFFFFFFFFFFFF); + + // Corrected output calculation + data_o[0] = (syndrome_o == 8'h83) ^ data_i[0]; + data_o[1] = (syndrome_o == 8'h85) ^ data_i[1]; + data_o[2] = (syndrome_o == 8'h86) ^ data_i[2]; + data_o[3] = (syndrome_o == 8'h87) ^ data_i[3]; + data_o[4] = (syndrome_o == 8'h89) ^ data_i[4]; + data_o[5] = (syndrome_o == 8'h8a) ^ data_i[5]; + data_o[6] = (syndrome_o == 8'h8b) ^ data_i[6]; + data_o[7] = (syndrome_o == 8'h8c) ^ data_i[7]; + data_o[8] = (syndrome_o == 8'h8d) ^ data_i[8]; + data_o[9] = (syndrome_o == 8'h8e) ^ data_i[9]; + data_o[10] = (syndrome_o == 8'h8f) ^ data_i[10]; + data_o[11] = (syndrome_o == 8'h91) ^ data_i[11]; + data_o[12] = (syndrome_o == 8'h92) ^ data_i[12]; + data_o[13] = (syndrome_o == 8'h93) ^ data_i[13]; + data_o[14] = (syndrome_o == 8'h94) ^ data_i[14]; + data_o[15] = (syndrome_o == 8'h95) ^ data_i[15]; + data_o[16] = (syndrome_o == 8'h96) ^ data_i[16]; + data_o[17] = (syndrome_o == 8'h97) ^ data_i[17]; + data_o[18] = (syndrome_o == 8'h98) ^ data_i[18]; + data_o[19] = (syndrome_o == 8'h99) ^ data_i[19]; + data_o[20] = (syndrome_o == 8'h9a) ^ data_i[20]; + data_o[21] = (syndrome_o == 8'h9b) ^ data_i[21]; + data_o[22] = (syndrome_o == 8'h9c) ^ data_i[22]; + data_o[23] = (syndrome_o == 8'h9d) ^ data_i[23]; + data_o[24] = (syndrome_o == 8'h9e) ^ data_i[24]; + data_o[25] = (syndrome_o == 8'h9f) ^ data_i[25]; + data_o[26] = (syndrome_o == 8'ha1) ^ data_i[26]; + data_o[27] = (syndrome_o == 8'ha2) ^ data_i[27]; + data_o[28] = (syndrome_o == 8'ha3) ^ data_i[28]; + data_o[29] = (syndrome_o == 8'ha4) ^ data_i[29]; + data_o[30] = (syndrome_o == 8'ha5) ^ data_i[30]; + data_o[31] = (syndrome_o == 8'ha6) ^ data_i[31]; + data_o[32] = (syndrome_o == 8'ha7) ^ data_i[32]; + data_o[33] = (syndrome_o == 8'ha8) ^ data_i[33]; + data_o[34] = (syndrome_o == 8'ha9) ^ data_i[34]; + data_o[35] = (syndrome_o == 8'haa) ^ data_i[35]; + data_o[36] = (syndrome_o == 8'hab) ^ data_i[36]; + data_o[37] = (syndrome_o == 8'hac) ^ data_i[37]; + data_o[38] = (syndrome_o == 8'had) ^ data_i[38]; + data_o[39] = (syndrome_o == 8'hae) ^ data_i[39]; + data_o[40] = (syndrome_o == 8'haf) ^ data_i[40]; + data_o[41] = (syndrome_o == 8'hb0) ^ data_i[41]; + data_o[42] = (syndrome_o == 8'hb1) ^ data_i[42]; + data_o[43] = (syndrome_o == 8'hb2) ^ data_i[43]; + data_o[44] = (syndrome_o == 8'hb3) ^ data_i[44]; + data_o[45] = (syndrome_o == 8'hb4) ^ data_i[45]; + data_o[46] = (syndrome_o == 8'hb5) ^ data_i[46]; + data_o[47] = (syndrome_o == 8'hb6) ^ data_i[47]; + data_o[48] = (syndrome_o == 8'hb7) ^ data_i[48]; + data_o[49] = (syndrome_o == 8'hb8) ^ data_i[49]; + data_o[50] = (syndrome_o == 8'hb9) ^ data_i[50]; + data_o[51] = (syndrome_o == 8'hba) ^ data_i[51]; + data_o[52] = (syndrome_o == 8'hbb) ^ data_i[52]; + data_o[53] = (syndrome_o == 8'hbc) ^ data_i[53]; + data_o[54] = (syndrome_o == 8'hbd) ^ data_i[54]; + data_o[55] = (syndrome_o == 8'hbe) ^ data_i[55]; + data_o[56] = (syndrome_o == 8'hbf) ^ data_i[56]; + data_o[57] = (syndrome_o == 8'hc1) ^ data_i[57]; + data_o[58] = (syndrome_o == 8'hc2) ^ data_i[58]; + data_o[59] = (syndrome_o == 8'hc3) ^ data_i[59]; + data_o[60] = (syndrome_o == 8'hc4) ^ data_i[60]; + data_o[61] = (syndrome_o == 8'hc5) ^ data_i[61]; + data_o[62] = (syndrome_o == 8'hc6) ^ data_i[62]; + data_o[63] = (syndrome_o == 8'hc7) ^ data_i[63]; + + // err_o calc. bit0: single error, bit1: double error + err_o[0] = syndrome_o[7]; + err_o[1] = |syndrome_o[6:0] & ~syndrome_o[7]; + + dec.data = data_o; + dec.syndrome = syndrome_o; + dec.err = err_o; + return dec; + + endfunction + + function automatic logic [75:0] + prim_secded_inv_hamming_76_68_enc (logic [67:0] data_i); + logic [75:0] data_o; + data_o = 76'(data_i); + data_o[68] = ^(data_o & 76'h00AAB55555556AAAD5B); + data_o[69] = ^(data_o & 76'h00CCD9999999B33366D); + data_o[70] = ^(data_o & 76'h000F1E1E1E1E3C3C78E); + data_o[71] = ^(data_o & 76'h00F01FE01FE03FC07F0); + data_o[72] = ^(data_o & 76'h00001FFFE0003FFF800); + data_o[73] = ^(data_o & 76'h00001FFFFFFFC000000); + data_o[74] = ^(data_o & 76'h00FFE00000000000000); + data_o[75] = ^(data_o & 76'h7FFFFFFFFFFFFFFFFFF); + data_o ^= 76'hAA00000000000000000; + return data_o; + endfunction + + function automatic secded_inv_hamming_76_68_t + prim_secded_inv_hamming_76_68_dec (logic [75:0] data_i); + logic [67:0] data_o; + logic [7:0] syndrome_o; + logic [1:0] err_o; + + secded_inv_hamming_76_68_t dec; + + // Syndrome calculation + syndrome_o[0] = ^((data_i ^ 76'hAA00000000000000000) & 76'h01AAB55555556AAAD5B); + syndrome_o[1] = ^((data_i ^ 76'hAA00000000000000000) & 76'h02CCD9999999B33366D); + syndrome_o[2] = ^((data_i ^ 76'hAA00000000000000000) & 76'h040F1E1E1E1E3C3C78E); + syndrome_o[3] = ^((data_i ^ 76'hAA00000000000000000) & 76'h08F01FE01FE03FC07F0); + syndrome_o[4] = ^((data_i ^ 76'hAA00000000000000000) & 76'h10001FFFE0003FFF800); + syndrome_o[5] = ^((data_i ^ 76'hAA00000000000000000) & 76'h20001FFFFFFFC000000); + syndrome_o[6] = ^((data_i ^ 76'hAA00000000000000000) & 76'h40FFE00000000000000); + syndrome_o[7] = ^((data_i ^ 76'hAA00000000000000000) & 76'hFFFFFFFFFFFFFFFFFFF); + + // Corrected output calculation + data_o[0] = (syndrome_o == 8'h83) ^ data_i[0]; + data_o[1] = (syndrome_o == 8'h85) ^ data_i[1]; + data_o[2] = (syndrome_o == 8'h86) ^ data_i[2]; + data_o[3] = (syndrome_o == 8'h87) ^ data_i[3]; + data_o[4] = (syndrome_o == 8'h89) ^ data_i[4]; + data_o[5] = (syndrome_o == 8'h8a) ^ data_i[5]; + data_o[6] = (syndrome_o == 8'h8b) ^ data_i[6]; + data_o[7] = (syndrome_o == 8'h8c) ^ data_i[7]; + data_o[8] = (syndrome_o == 8'h8d) ^ data_i[8]; + data_o[9] = (syndrome_o == 8'h8e) ^ data_i[9]; + data_o[10] = (syndrome_o == 8'h8f) ^ data_i[10]; + data_o[11] = (syndrome_o == 8'h91) ^ data_i[11]; + data_o[12] = (syndrome_o == 8'h92) ^ data_i[12]; + data_o[13] = (syndrome_o == 8'h93) ^ data_i[13]; + data_o[14] = (syndrome_o == 8'h94) ^ data_i[14]; + data_o[15] = (syndrome_o == 8'h95) ^ data_i[15]; + data_o[16] = (syndrome_o == 8'h96) ^ data_i[16]; + data_o[17] = (syndrome_o == 8'h97) ^ data_i[17]; + data_o[18] = (syndrome_o == 8'h98) ^ data_i[18]; + data_o[19] = (syndrome_o == 8'h99) ^ data_i[19]; + data_o[20] = (syndrome_o == 8'h9a) ^ data_i[20]; + data_o[21] = (syndrome_o == 8'h9b) ^ data_i[21]; + data_o[22] = (syndrome_o == 8'h9c) ^ data_i[22]; + data_o[23] = (syndrome_o == 8'h9d) ^ data_i[23]; + data_o[24] = (syndrome_o == 8'h9e) ^ data_i[24]; + data_o[25] = (syndrome_o == 8'h9f) ^ data_i[25]; + data_o[26] = (syndrome_o == 8'ha1) ^ data_i[26]; + data_o[27] = (syndrome_o == 8'ha2) ^ data_i[27]; + data_o[28] = (syndrome_o == 8'ha3) ^ data_i[28]; + data_o[29] = (syndrome_o == 8'ha4) ^ data_i[29]; + data_o[30] = (syndrome_o == 8'ha5) ^ data_i[30]; + data_o[31] = (syndrome_o == 8'ha6) ^ data_i[31]; + data_o[32] = (syndrome_o == 8'ha7) ^ data_i[32]; + data_o[33] = (syndrome_o == 8'ha8) ^ data_i[33]; + data_o[34] = (syndrome_o == 8'ha9) ^ data_i[34]; + data_o[35] = (syndrome_o == 8'haa) ^ data_i[35]; + data_o[36] = (syndrome_o == 8'hab) ^ data_i[36]; + data_o[37] = (syndrome_o == 8'hac) ^ data_i[37]; + data_o[38] = (syndrome_o == 8'had) ^ data_i[38]; + data_o[39] = (syndrome_o == 8'hae) ^ data_i[39]; + data_o[40] = (syndrome_o == 8'haf) ^ data_i[40]; + data_o[41] = (syndrome_o == 8'hb0) ^ data_i[41]; + data_o[42] = (syndrome_o == 8'hb1) ^ data_i[42]; + data_o[43] = (syndrome_o == 8'hb2) ^ data_i[43]; + data_o[44] = (syndrome_o == 8'hb3) ^ data_i[44]; + data_o[45] = (syndrome_o == 8'hb4) ^ data_i[45]; + data_o[46] = (syndrome_o == 8'hb5) ^ data_i[46]; + data_o[47] = (syndrome_o == 8'hb6) ^ data_i[47]; + data_o[48] = (syndrome_o == 8'hb7) ^ data_i[48]; + data_o[49] = (syndrome_o == 8'hb8) ^ data_i[49]; + data_o[50] = (syndrome_o == 8'hb9) ^ data_i[50]; + data_o[51] = (syndrome_o == 8'hba) ^ data_i[51]; + data_o[52] = (syndrome_o == 8'hbb) ^ data_i[52]; + data_o[53] = (syndrome_o == 8'hbc) ^ data_i[53]; + data_o[54] = (syndrome_o == 8'hbd) ^ data_i[54]; + data_o[55] = (syndrome_o == 8'hbe) ^ data_i[55]; + data_o[56] = (syndrome_o == 8'hbf) ^ data_i[56]; + data_o[57] = (syndrome_o == 8'hc1) ^ data_i[57]; + data_o[58] = (syndrome_o == 8'hc2) ^ data_i[58]; + data_o[59] = (syndrome_o == 8'hc3) ^ data_i[59]; + data_o[60] = (syndrome_o == 8'hc4) ^ data_i[60]; + data_o[61] = (syndrome_o == 8'hc5) ^ data_i[61]; + data_o[62] = (syndrome_o == 8'hc6) ^ data_i[62]; + data_o[63] = (syndrome_o == 8'hc7) ^ data_i[63]; + data_o[64] = (syndrome_o == 8'hc8) ^ data_i[64]; + data_o[65] = (syndrome_o == 8'hc9) ^ data_i[65]; + data_o[66] = (syndrome_o == 8'hca) ^ data_i[66]; + data_o[67] = (syndrome_o == 8'hcb) ^ data_i[67]; + + // err_o calc. bit0: single error, bit1: double error + err_o[0] = syndrome_o[7]; + err_o[1] = |syndrome_o[6:0] & ~syndrome_o[7]; + + dec.data = data_o; + dec.syndrome = syndrome_o; + dec.err = err_o; + return dec; + + endfunction + + +endpackage diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_slicer.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_slicer.sv new file mode 100644 index 0000000..89ca3da --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_slicer.sv @@ -0,0 +1,31 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Slicer chops the incoming bitstring into OutW granularity. +// It supports fractional InW/OutW which fills 0 at the end of message. + +`include "caliptra_prim_assert.sv" + +module caliptra_prim_slicer #( + parameter int InW = 64, + parameter int OutW = 8, + + parameter int IndexW = 4 +) ( + input [IndexW-1:0] sel_i, + input [InW-1:0] data_i, + output logic [OutW-1:0] data_o +); + + localparam int UnrollW = OutW*(2**IndexW); + + logic [UnrollW-1:0] unrolled_data; + + assign unrolled_data = UnrollW'(data_i); + + assign data_o = unrolled_data[sel_i*OutW+:OutW]; + + `CALIPTRA_ASSERT_INIT(ValidWidth_A, InW <= OutW*(2**IndexW)) + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_sparse_fsm_flop.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_sparse_fsm_flop.sv new file mode 100644 index 0000000..348aa3f --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_sparse_fsm_flop.sv @@ -0,0 +1,67 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +`include "caliptra_prim_assert.sv" + +module caliptra_prim_sparse_fsm_flop #( + parameter int Width = 1, + parameter type StateEnumT = logic [Width-1:0], + parameter logic [Width-1:0] ResetValue = '0, + // This should only be disabled in special circumstances, for example + // in non-comportable IPs where an error does not trigger an alert. + parameter bit EnableAlertTriggerSVA = 1 +`ifdef SIMULATION + , + // In case this parameter is set to a non-empty string, the + // caliptra_prim_sparse_fsm_flop_if will also force the signal with this name + // in the parent module that instantiates caliptra_prim_sparse_fsm_flop. + parameter string CustomForceName = "" +`endif +) ( + input clk_i, + input rst_ni, + input StateEnumT state_i, + output StateEnumT state_o +); + + logic unused_err_o; + + logic [Width-1:0] state_raw; + caliptra_prim_flop #( + .Width(Width), + .ResetValue(ResetValue) + ) u_state_flop ( + .clk_i, + .rst_ni, + .d_i(state_i), + .q_o(state_raw) + ); + assign state_o = StateEnumT'(state_raw); + + `ifdef CALIPTRA_INC_ASSERT + assign unused_err_o = is_undefined_state(state_o); + + function automatic logic is_undefined_state(StateEnumT sig); + // This is written with a vector in order to make it amenable to x-prop analysis. + logic is_defined = 1'b0; + for (int i = 0, StateEnumT t = t.first(); i < t.num(); i += 1, t = t.next()) begin + is_defined |= (sig === t); + end + return ~is_defined; + endfunction + + `else + assign unused_err_o = 1'b0; + `endif + + // If CALIPTRA_ASSERT_PRIM_FSM_ERROR_TRIGGER_ALERT is declared, the unused_assert_connected signal will + // be set to 1 and the below check will pass. + // If the assertion is not declared however, the statement below will fail. + `ifdef CALIPTRA_INC_ASSERT + logic unused_assert_connected; + + `CALIPTRA_ASSERT_INIT_NET(AssertConnected_A, unused_assert_connected === 1'b1 || !EnableAlertTriggerSVA) + `endif + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_sparse_fsm_pkg.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_sparse_fsm_pkg.sv new file mode 100644 index 0000000..5f0b716 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_sparse_fsm_pkg.sv @@ -0,0 +1,7 @@ +// Copyright lowRISC contributors. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +package caliptra_prim_sparse_fsm_pkg; + typedef enum logic {Idle, Done} state_t; +endpackage : caliptra_prim_sparse_fsm_pkg diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_subreg.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_subreg.sv new file mode 100644 index 0000000..c074c8b --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_subreg.sv @@ -0,0 +1,75 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Register slice conforming to Comportibility guide. + +module caliptra_prim_subreg + import caliptra_prim_subreg_pkg::*; +#( + parameter int DW = 32, + parameter sw_access_e SwAccess = SwAccessRW, + parameter logic [DW-1:0] RESVAL = '0, // reset value + parameter bit Mubi = 1'b0 +) ( + input clk_i, + input rst_ni, + + // From SW: valid for RW, WO, W1C, W1S, W0C, RC + // In case of RC, Top connects Read Pulse to we + input we, + input [DW-1:0] wd, + + // From HW: valid for HRW, HWO + input de, + input [DW-1:0] d, + + // output to HW and Reg Read + output logic qe, + output logic [DW-1:0] q, + + // ds and qs have slightly different timing. + // ds is the data that will be written into the flop, + // while qs is the current flop value exposed to software. + output logic [DW-1:0] ds, + output logic [DW-1:0] qs +); + + logic wr_en; + logic [DW-1:0] wr_data; + + caliptra_prim_subreg_arb #( + .DW ( DW ), + .SwAccess ( SwAccess ), + .Mubi ( Mubi ) + ) wr_en_data_arb ( + .we, + .wd, + .de, + .d, + .q, + .wr_en, + .wr_data + ); + + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + q <= RESVAL; + end else if (wr_en) begin + q <= wr_data; + end + end + + // feed back out for consolidation + assign ds = wr_en ? wr_data : qs; + assign qe = wr_en; + + if (SwAccess == SwAccessRC) begin : gen_rc + // In case of a SW RC colliding with a HW write, SW gets the value written by HW + // but the register is cleared to 0. See #5416 for a discussion. + assign qs = de && we ? d : q; + end else begin : gen_no_rc + assign qs = q; + end + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_subreg_arb.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_subreg_arb.sv new file mode 100644 index 0000000..0a8aaf1 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_subreg_arb.sv @@ -0,0 +1,187 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Write enable and data arbitration logic for register slice conforming to Comportibility guide. + +module caliptra_prim_subreg_arb + import caliptra_prim_subreg_pkg::*; +#( + parameter int DW = 32, + parameter sw_access_e SwAccess = SwAccessRW, + parameter bit Mubi = 1'b0 +) ( + // From SW: valid for RW, WO, W1C, W1S, W0C, RC. + // In case of RC, top connects read pulse to we. + input we, + input [DW-1:0] wd, + + // From HW: valid for HRW, HWO. + input de, + input [DW-1:0] d, + + // From register: actual reg value. + input [DW-1:0] q, + + // To register: actual write enable and write data. + output logic wr_en, + output logic [DW-1:0] wr_data +); + import caliptra_prim_mubi_pkg::*; + + if (SwAccess inside {SwAccessRW, SwAccessWO}) begin : gen_w + assign wr_en = we | de; + assign wr_data = (we == 1'b1) ? wd : d; // SW higher priority + // Unused q - Prevent lint errors. + logic [DW-1:0] unused_q; + //VCS coverage off + // pragma coverage off + assign unused_q = q; + //VCS coverage on + // pragma coverage on + end else if (SwAccess == SwAccessRO) begin : gen_ro + assign wr_en = de; + assign wr_data = d; + // Unused we, wd, q - Prevent lint errors. + logic unused_we; + logic [DW-1:0] unused_wd; + logic [DW-1:0] unused_q; + //VCS coverage off + // pragma coverage off + assign unused_we = we; + assign unused_wd = wd; + assign unused_q = q; + //VCS coverage on + // pragma coverage on + end else if (SwAccess == SwAccessW1S) begin : gen_w1s + // If SwAccess is W1S, then assume hw tries to clear. + // So, give a chance HW to clear when SW tries to set. + // If both try to set/clr at the same bit pos, SW wins. + assign wr_en = we | de; + if (Mubi) begin : gen_mubi + if (DW == 4) begin : gen_mubi4 + assign wr_data = caliptra_prim_mubi_pkg::mubi4_or_hi(caliptra_prim_mubi_pkg::mubi4_t'(de ? d : q), + (we ? caliptra_prim_mubi_pkg::mubi4_t'(wd) : + caliptra_prim_mubi_pkg::MuBi4False)); + end else if (DW == 8) begin : gen_mubi8 + assign wr_data = caliptra_prim_mubi_pkg::mubi8_or_hi(caliptra_prim_mubi_pkg::mubi8_t'(de ? d : q), + (we ? caliptra_prim_mubi_pkg::mubi8_t'(wd) : + caliptra_prim_mubi_pkg::MuBi8False)); + end else if (DW == 12) begin : gen_mubi12 + assign wr_data = caliptra_prim_mubi_pkg::mubi12_or_hi(caliptra_prim_mubi_pkg::mubi12_t'(de ? d : q), + (we ? caliptra_prim_mubi_pkg::mubi12_t'(wd) : + caliptra_prim_mubi_pkg::MuBi12False)); + end else if (DW == 16) begin : gen_mubi16 + assign wr_data = caliptra_prim_mubi_pkg::mubi16_or_hi(caliptra_prim_mubi_pkg::mubi16_t'(de ? d : q), + (we ? caliptra_prim_mubi_pkg::mubi16_t'(wd) : + caliptra_prim_mubi_pkg::MuBi16False)); + end else begin : gen_invalid_mubi + $error("%m: Invalid width for MuBi"); + end + end else begin : gen_non_mubi + assign wr_data = (de ? d : q) | (we ? wd : '0); + end + end else if (SwAccess == SwAccessW1C) begin : gen_w1c + // If SwAccess is W1C, then assume hw tries to set. + // So, give a chance HW to set when SW tries to clear. + // If both try to set/clr at the same bit pos, SW wins. + assign wr_en = we | de; + if (Mubi) begin : gen_mubi + if (DW == 4) begin : gen_mubi4 + assign wr_data = caliptra_prim_mubi_pkg::mubi4_and_hi(caliptra_prim_mubi_pkg::mubi4_t'(de ? d : q), + (we ? caliptra_prim_mubi_pkg::mubi4_t'(~wd) : + caliptra_prim_mubi_pkg::MuBi4True)); + end else if (DW == 8) begin : gen_mubi8 + assign wr_data = caliptra_prim_mubi_pkg::mubi8_and_hi(caliptra_prim_mubi_pkg::mubi8_t'(de ? d : q), + (we ? caliptra_prim_mubi_pkg::mubi8_t'(~wd) : + caliptra_prim_mubi_pkg::MuBi8True)); + end else if (DW == 12) begin : gen_mubi12 + assign wr_data = caliptra_prim_mubi_pkg::mubi12_and_hi(caliptra_prim_mubi_pkg::mubi12_t'(de ? d : q), + (we ? caliptra_prim_mubi_pkg::mubi12_t'(~wd) : + caliptra_prim_mubi_pkg::MuBi12True)); + end else if (DW == 16) begin : gen_mubi16 + assign wr_data = caliptra_prim_mubi_pkg::mubi16_and_hi(caliptra_prim_mubi_pkg::mubi16_t'(de ? d : q), + (we ? caliptra_prim_mubi_pkg::mubi16_t'(~wd) : + caliptra_prim_mubi_pkg::MuBi16True)); + end else begin : gen_invalid_mubi + $error("%m: Invalid width for MuBi"); + end + end else begin : gen_non_mubi + assign wr_data = (de ? d : q) & (we ? ~wd : '1); + end + end else if (SwAccess == SwAccessW0C) begin : gen_w0c + assign wr_en = we | de; + if (Mubi) begin : gen_mubi + if (DW == 4) begin : gen_mubi4 + assign wr_data = caliptra_prim_mubi_pkg::mubi4_and_hi(caliptra_prim_mubi_pkg::mubi4_t'(de ? d : q), + (we ? caliptra_prim_mubi_pkg::mubi4_t'(wd) : + caliptra_prim_mubi_pkg::MuBi4True)); + end else if (DW == 8) begin : gen_mubi8 + assign wr_data = caliptra_prim_mubi_pkg::mubi8_and_hi(caliptra_prim_mubi_pkg::mubi8_t'(de ? d : q), + (we ? caliptra_prim_mubi_pkg::mubi8_t'(wd) : + caliptra_prim_mubi_pkg::MuBi8True)); + end else if (DW == 12) begin : gen_mubi12 + assign wr_data = caliptra_prim_mubi_pkg::mubi12_and_hi(caliptra_prim_mubi_pkg::mubi12_t'(de ? d : q), + (we ? caliptra_prim_mubi_pkg::mubi12_t'(wd) : + caliptra_prim_mubi_pkg::MuBi12True)); + end else if (DW == 16) begin : gen_mubi16 + assign wr_data = caliptra_prim_mubi_pkg::mubi16_and_hi(caliptra_prim_mubi_pkg::mubi16_t'(de ? d : q), + (we ? caliptra_prim_mubi_pkg::mubi16_t'(wd) : + caliptra_prim_mubi_pkg::MuBi16True)); + end else begin : gen_invalid_mubi + $error("%m: Invalid width for MuBi"); + end + end else begin : gen_non_mubi + assign wr_data = (de ? d : q) & (we ? wd : '1); + end + end else if (SwAccess == SwAccessRC) begin : gen_rc + // This swtype is not recommended but exists for compatibility. + // WARN: we signal is actually read signal not write enable. + assign wr_en = we | de; + if (Mubi) begin : gen_mubi + if (DW == 4) begin : gen_mubi4 + assign wr_data = caliptra_prim_mubi_pkg::mubi4_and_hi(caliptra_prim_mubi_pkg::mubi4_t'(de ? d : q), + (we ? caliptra_prim_mubi_pkg::MuBi4False : + caliptra_prim_mubi_pkg::MuBi4True)); + end else if (DW == 8) begin : gen_mubi8 + assign wr_data = caliptra_prim_mubi_pkg::mubi8_and_hi(caliptra_prim_mubi_pkg::mubi8_t'(de ? d : q), + (we ? caliptra_prim_mubi_pkg::MuBi8False : + caliptra_prim_mubi_pkg::MuBi8True)); + end else if (DW == 12) begin : gen_mubi12 + assign wr_data = caliptra_prim_mubi_pkg::mubi12_and_hi(caliptra_prim_mubi_pkg::mubi12_t'(de ? d : q), + (we ? caliptra_prim_mubi_pkg::MuBi12False : + caliptra_prim_mubi_pkg::MuBi12True)); + end else if (DW == 16) begin : gen_mubi16 + assign wr_data = caliptra_prim_mubi_pkg::mubi16_and_hi(caliptra_prim_mubi_pkg::mubi16_t'(de ? d : q), + (we ? caliptra_prim_mubi_pkg::mubi16_t'(wd) : + caliptra_prim_mubi_pkg::MuBi16True)); + end else begin : gen_invalid_mubi + $error("%m: Invalid width for MuBi"); + end + end else begin : gen_non_mubi + assign wr_data = (de ? d : q) & (we ? '0 : '1); + end + // Unused wd - Prevent lint errors. + logic [DW-1:0] unused_wd; + //VCS coverage off + // pragma coverage off + assign unused_wd = wd; + //VCS coverage on + // pragma coverage on + end else begin : gen_hw + assign wr_en = de; + assign wr_data = d; + // Unused we, wd, q - Prevent lint errors. + logic unused_we; + logic [DW-1:0] unused_wd; + logic [DW-1:0] unused_q; + //VCS coverage off + // pragma coverage off + assign unused_we = we; + assign unused_wd = wd; + assign unused_q = q; + //VCS coverage on + // pragma coverage on + end + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_subreg_ext.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_subreg_ext.sv new file mode 100644 index 0000000..51c250c --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_subreg_ext.sv @@ -0,0 +1,32 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Register slice conforming to Comportibility guide. + +module caliptra_prim_subreg_ext #( + parameter int unsigned DW = 32 +) ( + input re, + input we, + input [DW-1:0] wd, + + input [DW-1:0] d, + + // output to HW and Reg Read + output logic qe, + output logic qre, + output logic [DW-1:0] q, + output logic [DW-1:0] ds, + output logic [DW-1:0] qs +); + + // for external registers, there is no difference + // between qs and ds + assign ds = d; + assign qs = d; + assign q = wd; + assign qe = we; + assign qre = re; + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_subreg_pkg.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_subreg_pkg.sv new file mode 100644 index 0000000..e732ee0 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_subreg_pkg.sv @@ -0,0 +1,17 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +package caliptra_prim_subreg_pkg; + + // Register access specifier + typedef enum logic [2:0] { + SwAccessRW = 3'd0, // Read-write + SwAccessRO = 3'd1, // Read-only + SwAccessWO = 3'd2, // Write-only + SwAccessW1C = 3'd3, // Write 1 to clear + SwAccessW1S = 3'd4, // Write 1 to set + SwAccessW0C = 3'd5, // Write 0 to clear + SwAccessRC = 3'd6 // Read to clear. Do not use, only exists for compatibility. + } sw_access_e; +endpackage diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_subreg_shadow.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_subreg_shadow.sv new file mode 100644 index 0000000..7ecce93 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_subreg_shadow.sv @@ -0,0 +1,196 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Shadowed register slice conforming to Comportibility guide. + +`include "caliptra_prim_assert.sv" + +module caliptra_prim_subreg_shadow + import caliptra_prim_subreg_pkg::*; +#( + parameter int DW = 32, + parameter sw_access_e SwAccess = SwAccessRW, + parameter logic [DW-1:0] RESVAL = '0, // reset value + parameter bit Mubi = 1'b0 +) ( + input clk_i, + input rst_ni, + input rst_shadowed_ni, + + // From SW: valid for RW, WO, W1C, W1S, W0C, RC. + // SW reads clear phase unless SwAccess is RO. + input re, + // In case of RC, top connects read pulse to we. + input we, + input [DW-1:0] wd, + + // From HW: valid for HRW, HWO. + input de, + input [DW-1:0] d, + + // Output to HW and Reg Read + output logic qe, + output logic [DW-1:0] q, + output logic [DW-1:0] ds, + output logic [DW-1:0] qs, + + // Phase output to HW + output logic phase, + + // Error conditions + output logic err_update, + output logic err_storage +); + + // Since the shadow register works with the 1's complement value, + // we need to invert the polarity of the SW access if it is either "W1S" or "W0C". + // W1C is forbidden since the W0S complement is not implemented. + `CALIPTRA_ASSERT_INIT(CheckSwAccessIsLegal_A, + SwAccess inside {SwAccessRW, SwAccessRO, SwAccessWO, SwAccessW1S, SwAccessW0C}) + localparam sw_access_e InvertedSwAccess = (SwAccess == SwAccessW1S) ? SwAccessW0C : + (SwAccess == SwAccessW0C) ? SwAccessW1S : SwAccess; + + // For the staging register, we set the SwAccess to RW in case of W1S and W0C in + // order to always capture the data value on the first write operation - no matter + // whether the data value will actually have an effect. That way, we can still capture + // inconsistent double writes which would otherwise be ignored due to the data value filtering + // effect that W1S and W0C can have. + localparam sw_access_e StagedSwAccess = (SwAccess == SwAccessW1S) ? SwAccessRW : + (SwAccess == SwAccessW0C) ? SwAccessRW : SwAccess; + + // Subreg control signals + logic phase_clear; + logic phase_q; + logic staged_we, shadow_we, committed_we; + logic staged_de, shadow_de, committed_de; + + // Subreg status and data signals + logic committed_qe; + logic [DW-1:0] staged_q, shadow_q, committed_q; + logic [DW-1:0] committed_qs; + + // Effective write enable and write data signals. + // These depend on we, de and wd, d, q as well as SwAccess. + logic wr_en; + logic [DW-1:0] wr_data; + + caliptra_prim_subreg_arb #( + .DW ( DW ), + .SwAccess ( SwAccess ) + ) wr_en_data_arb ( + .we ( we ), + .wd ( wd ), + .de ( de ), + .d ( d ), + .q ( q ), + .wr_en ( wr_en ), + .wr_data ( wr_data ) + ); + + // Phase clearing: + // - SW reads clear phase unless SwAccess is RO. + // - In case of RO, SW should not interfere with update process. + assign phase_clear = (SwAccess == SwAccessRO) ? 1'b0 : re; + + // Phase tracker: + // - Reads from SW clear the phase back to 0. + // - Writes have priority (can come from SW or HW). + always_ff @(posedge clk_i or negedge rst_ni) begin : phase_reg + if (!rst_ni) begin + phase_q <= 1'b0; + end else if (wr_en && !err_storage) begin + phase_q <= ~phase_q; + end else if (phase_clear || err_storage) begin + phase_q <= 1'b0; + end + end + + // The staged register: + // - Holds the 1's complement value. + // - Written in Phase 0. + // - Once storage error occurs, do not allow any further update until reset + assign staged_we = we & ~phase_q & ~err_storage; + assign staged_de = de & ~phase_q & ~err_storage; + caliptra_prim_subreg #( + .DW ( DW ), + .SwAccess ( StagedSwAccess ), + .RESVAL ( ~RESVAL ) + ) staged_reg ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .we ( staged_we ), + .wd ( ~wr_data ), + .de ( staged_de ), + .d ( ~d ), + .qe ( ), + .q ( staged_q ), + .ds ( ), + .qs ( ) + ); + + // The shadow register: + // - Holds the 1's complement value. + // - Written in Phase 1. + // - Writes are ignored in case of update errors. + // - Gets the value from the staged register. + // - Once storage error occurs, do not allow any further update until reset + assign shadow_we = we & phase_q & ~err_update & ~err_storage; + assign shadow_de = de & phase_q & ~err_update & ~err_storage; + caliptra_prim_subreg #( + .DW ( DW ), + .SwAccess ( InvertedSwAccess ), + .RESVAL ( ~RESVAL ) + ) shadow_reg ( + .clk_i ( clk_i ), + .rst_ni ( rst_shadowed_ni ), + .we ( shadow_we ), + .wd ( staged_q ), + .de ( shadow_de ), + .d ( staged_q ), + .qe ( ), + .q ( shadow_q ), + .ds ( ), + .qs ( ) + ); + + // The committed register: + // - Written in Phase 1. + // - Writes are ignored in case of update errors. + assign committed_we = shadow_we; + assign committed_de = shadow_de; + caliptra_prim_subreg #( + .DW ( DW ), + .SwAccess ( SwAccess ), + .RESVAL ( RESVAL ) + ) committed_reg ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .we ( committed_we ), + .wd ( wr_data ), + .de ( committed_de ), + .d ( d ), + .qe ( committed_qe ), + .q ( committed_q ), + .ds ( ds ), + .qs ( committed_qs ) + ); + + // Output phase for hwext. + assign phase = phase_q; + + // Error detection - all bits must match. + assign err_update = (~staged_q != wr_data) ? phase_q & wr_en : 1'b0; + assign err_storage = (~shadow_q != committed_q); + + // Remaining output assignments + assign qe = committed_qe; + assign q = committed_q; + assign qs = committed_qs; + + // prim_subreg_shadow does not support multi-bit software access yet + `CALIPTRA_ASSERT_NEVER(MubiIsNotYetSupported_A, Mubi) + logic unused_mubi; + assign unused_mubi = Mubi; + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_sum_tree.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_sum_tree.sv new file mode 100644 index 0000000..5c2ee41 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_sum_tree.sv @@ -0,0 +1,124 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Based on caliptra_prim_max_tree, this module implements an explicit binary tree to find the +// sum of this inputs. The solution has O(N) area and O(log(N)) delay complexity, and +// thus scales well with many input sources. +// +// Note that only input values marked as "valid" are respected in the maximum computation. +// Invalid values are treated as 0. +// + +`include "caliptra_prim_assert.sv" + +module caliptra_prim_sum_tree #( + parameter int NumSrc = 32, + parameter int Width = 8 +) ( + // The module is combinational - the clock and reset are only used for assertions. + input clk_i, + input rst_ni, + input [NumSrc-1:0][Width-1:0] values_i, // Input values + input [NumSrc-1:0] valid_i, // Input valid bits + output logic [Width-1:0] sum_value_o, // Summation result + output logic sum_valid_o // Whether any of the inputs is valid +); + + /////////////////////// + // Binary tree logic // + /////////////////////// + + // This only works with 2 or more sources. + `CALIPTRA_ASSERT_INIT(NumSources_A, NumSrc >= 2) + + // Align to powers of 2 for simplicity. + // A full binary tree with N levels has 2**N + 2**N-1 nodes. + localparam int NumLevels = $clog2(NumSrc); + logic [2**(NumLevels+1)-2:0] vld_tree; + logic [2**(NumLevels+1)-2:0][Width-1:0] sum_tree; + + for (genvar level = 0; level < NumLevels+1; level++) begin : gen_tree + // + // level+1 C0 C1 <- "Base1" points to the first node on "level+1", + // \ / these nodes are the children of the nodes one level below + // level Pa <- "Base0", points to the first node on "level", + // these nodes are the parents of the nodes one level above + // + // hence we have the following indices for the paPa, C0, C1 nodes: + // Pa = 2**level - 1 + offset = Base0 + offset + // C0 = 2**(level+1) - 1 + 2*offset = Base1 + 2*offset + // C1 = 2**(level+1) - 1 + 2*offset + 1 = Base1 + 2*offset + 1 + // + localparam int Base0 = (2**level)-1; + localparam int Base1 = (2**(level+1))-1; + + for (genvar offset = 0; offset < 2**level; offset++) begin : gen_level + localparam int Pa = Base0 + offset; + localparam int C0 = Base1 + 2*offset; + localparam int C1 = Base1 + 2*offset + 1; + + // This assigns the input values, their corresponding IDs and valid signals to the tree leafs. + if (level == NumLevels) begin : gen_leafs + if (offset < NumSrc) begin : gen_assign + assign vld_tree[Pa] = valid_i[offset]; + assign sum_tree[Pa] = values_i[offset]; + end else begin : gen_tie_off + assign vld_tree[Pa] = '0; + assign sum_tree[Pa] = '0; + end + // This creates the node assignments. + end else begin : gen_nodes + logic [Width-1:0] node_sum; // Local helper variable + // In case only one of the parents is valid, forward that one + // In case both parents are valid, forward the one with higher value + assign node_sum = (vld_tree[C0] & vld_tree[C1]) ? sum_tree[C1] + sum_tree[C0] : + (vld_tree[C0]) ? sum_tree[C0] : + (vld_tree[C1]) ? sum_tree[C1] : + {Width'(0)}; + + // Forwarding muxes + // Note: these ternaries have triggered a synthesis bug in Vivado versions older + // than 2020.2. If the problem resurfaces again, have a look at issue #1408. + assign vld_tree[Pa] = vld_tree[C1] | vld_tree[C0]; + assign sum_tree[Pa] = node_sum; + end + end : gen_level + end : gen_tree + + + // The results can be found at the tree root + assign sum_valid_o = vld_tree[0]; + assign sum_value_o = sum_tree[0]; + + //////////////// + // Assertions // + //////////////// + +`ifdef CALIPTRA_INC_ASSERT + //VCS coverage off + // pragma coverage off + + // Helper functions for assertions below. + function automatic logic [Width-1:0] sum_value (input logic [NumSrc-1:0][Width-1:0] values_i, + input logic [NumSrc-1:0] valid_i); + logic [Width-1:0] sum = '0; + for (int k = 0; k < NumSrc; k++) begin + if (valid_i[k]) begin + sum += values_i[k]; + end + end + return sum; + endfunction : sum_value + + logic [Width-1:0] sum_value_exp; + assign sum_value_exp = sum_value(values_i, valid_i); + //VCS coverage on + // pragma coverage on + + `CALIPTRA_ASSERT(ValidInImpliesValidOut_A, |valid_i === sum_valid_o) + `CALIPTRA_ASSERT(SumComputation_A, sum_valid_o |-> sum_value_o == sum_value_exp) + `CALIPTRA_ASSERT(SumComputationInvalid_A, !sum_valid_o |-> sum_value_o == '0) +`endif + +endmodule : caliptra_prim_sum_tree diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_sync_reqack.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_sync_reqack.sv new file mode 100644 index 0000000..d5958d6 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_sync_reqack.sv @@ -0,0 +1,404 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// REQ/ACK synchronizer +// +// This module synchronizes a REQ/ACK handshake across a clock domain crossing. +// Both domains will see a handshake with the duration of one clock cycle. +// +// Notes: +// - Once asserted, the source (SRC) domain is not allowed to de-assert REQ without ACK. +// - The destination (DST) domain is not allowed to send an ACK without a REQ. +// - When resetting one domain, also the other domain needs to be reset with both resets being +// active at the same time. +// - This module works both when syncing from a faster to a slower clock domain and vice versa. +// - Internally, this module uses a non-return-to-zero (NRZ), two-phase handshake protocol by +// default. Assuming the DST domain responds with an ACK immediately, the latency from asserting +// the REQ in the SRC domain is: +// - 1 source + 2 destination clock cycles until the handshake is performed in the DST domain, +// - 1 source + 2 destination + 1 destination + 2 source clock cycles until the handshake is +// performed in the SRC domain. +// - Optionally, the module can also use a return-to-zero (RZ), four-phase handshake protocol. +// That one has lower throughput, but it is safe to reset either domain in isolation, since the +// two FSMs cannot get out of sync due to persistent EVEN/ODD states. The handshake latencies +// are the same as for the NRZ protocol, but the throughput is half that of the NRZ protocol +// since the signals neet to return to zero first, causing two round-trips through the +// synchronizers instead of just one. +// +// For further information, see Section 8.2.4 in H. Kaeslin, "Top-Down Digital VLSI Design: From +// Architecture to Gate-Level Circuits and FPGAs", 2015. + +`include "caliptra_prim_assert.sv" + +module caliptra_prim_sync_reqack #( + parameter bit EnRstChks = 1'b0, // Enable reset-related assertion checks, disabled by default. + parameter bit EnRzHs = 1'b0 // By Default, the faster NRZ handshake protocol + // (EnRzHs = 0) is used. Enable the RZ handshake protocol + // if the FSMs need to be partial-reset-safe. +) ( + input clk_src_i, // REQ side, SRC domain + input rst_src_ni, // REQ side, SRC domain + input clk_dst_i, // ACK side, DST domain + input rst_dst_ni, // ACK side, DST domain + + input logic req_chk_i, // Used for gating assertions. Drive to 1 during normal operation. + + input logic src_req_i, // REQ side, SRC domain + output logic src_ack_o, // REQ side, SRC domain + output logic dst_req_o, // ACK side, DST domain + input logic dst_ack_i // ACK side, DST domain +); + + // req_chk_i is used for gating assertions only. + logic unused_req_chk; + assign unused_req_chk = req_chk_i; + + if (EnRzHs) begin : gen_rz_hs_protocol + ////////////////// + // RZ protocol // + ////////////////// + + // Types + typedef enum logic { + LoSt, HiSt + } rz_fsm_e; + + // Signals + rz_fsm_e src_fsm_d, src_fsm_q; + rz_fsm_e dst_fsm_d, dst_fsm_q; + logic src_ack, dst_ack; + logic src_req, dst_req; + + // REQ-side FSM (SRC domain) + always_comb begin : src_fsm + src_fsm_d = src_fsm_q; + src_ack_o = 1'b0; + src_req = 1'b0; + + unique case (src_fsm_q) + LoSt: begin + // Wait for the ack to go back to zero before starting + // a new transaction. + if (!src_ack && src_req_i) begin + src_fsm_d = HiSt; + end + end + HiSt: begin + src_req = 1'b1; + // Forward the acknowledgement. + src_ack_o = src_ack; + // If request drops out, we go back to LoSt. + // If DST side asserts ack, we also go back to LoSt. + if (!src_req_i || src_ack) begin + src_fsm_d = LoSt; + end + end + //VCS coverage off + // pragma coverage off + default: ; + //VCS coverage on + // pragma coverage on + endcase + end + + // Move ACK over to SRC domain. + caliptra_prim_flop_2sync #( + .Width(1) + ) ack_sync ( + .clk_i (clk_src_i), + .rst_ni (rst_src_ni), + .d_i (dst_ack), + .q_o (src_ack) + ); + + // Registers + always_ff @(posedge clk_src_i or negedge rst_src_ni) begin + if (!rst_src_ni) begin + src_fsm_q <= LoSt; + end else begin + src_fsm_q <= src_fsm_d; + end + end + + // ACK-side FSM (DST domain) + always_comb begin : dst_fsm + dst_fsm_d = dst_fsm_q; + dst_req_o = 1'b0; + dst_ack = 1'b0; + + unique case (dst_fsm_q) + LoSt: begin + if (dst_req) begin + // Forward the request. + dst_req_o = 1'b1; + // Wait for the request and acknowledge to be asserted + // before responding to the SRC side. + if (dst_ack_i) begin + dst_fsm_d = HiSt; + end + end + end + HiSt: begin + dst_ack = 1'b1; + // Wait for the request to drop back to zero. + if (!dst_req) begin + dst_fsm_d = LoSt; + end + end + //VCS coverage off + // pragma coverage off + default: ; + //VCS coverage on + // pragma coverage on + endcase + end + + // Move REQ over to DST domain. + caliptra_prim_flop_2sync #( + .Width(1) + ) req_sync ( + .clk_i (clk_dst_i), + .rst_ni (rst_dst_ni), + .d_i (src_req), + .q_o (dst_req) + ); + + // Registers + always_ff @(posedge clk_dst_i or negedge rst_dst_ni) begin + if (!rst_dst_ni) begin + dst_fsm_q <= LoSt; + end else begin + dst_fsm_q <= dst_fsm_d; + end + end + + end else begin : gen_nrz_hs_protocol + ////////////////// + // NRZ protocol // + ////////////////// + + // Types + typedef enum logic { + EVEN, ODD + } sync_reqack_fsm_e; + + // Signals + sync_reqack_fsm_e src_fsm_ns, src_fsm_cs; + sync_reqack_fsm_e dst_fsm_ns, dst_fsm_cs; + + logic src_req_d, src_req_q, src_ack; + logic dst_ack_d, dst_ack_q, dst_req; + logic src_handshake, dst_handshake; + + assign src_handshake = src_req_i & src_ack_o; + assign dst_handshake = dst_req_o & dst_ack_i; + + // Move REQ over to DST domain. + caliptra_prim_flop_2sync #( + .Width(1) + ) req_sync ( + .clk_i (clk_dst_i), + .rst_ni (rst_dst_ni), + .d_i (src_req_q), + .q_o (dst_req) + ); + + // Move ACK over to SRC domain. + caliptra_prim_flop_2sync #( + .Width(1) + ) ack_sync ( + .clk_i (clk_src_i), + .rst_ni (rst_src_ni), + .d_i (dst_ack_q), + .q_o (src_ack) + ); + + // REQ-side FSM (SRC domain) + always_comb begin : src_fsm + src_fsm_ns = src_fsm_cs; + + // By default, we keep the internal REQ value and don't ACK. + src_req_d = src_req_q; + src_ack_o = 1'b0; + + unique case (src_fsm_cs) + + EVEN: begin + // Simply forward REQ and ACK. + src_req_d = src_req_i; + src_ack_o = src_ack; + + // The handshake is done for exactly 1 clock cycle. + if (src_handshake) begin + src_fsm_ns = ODD; + end + end + + ODD: begin + // Internal REQ and ACK have inverted meaning now. If src_req_i is high again, this + // signals a new transaction. + src_req_d = ~src_req_i; + src_ack_o = ~src_ack; + + // The handshake is done for exactly 1 clock cycle. + if (src_handshake) begin + src_fsm_ns = EVEN; + end + end + + //VCS coverage off + // pragma coverage off + + default: ; + + //VCS coverage on + // pragma coverage on + + endcase + end + + // ACK-side FSM (DST domain) + always_comb begin : dst_fsm + dst_fsm_ns = dst_fsm_cs; + + // By default, we don't REQ and keep the internal ACK. + dst_req_o = 1'b0; + dst_ack_d = dst_ack_q; + + unique case (dst_fsm_cs) + + EVEN: begin + // Simply forward REQ and ACK. + dst_req_o = dst_req; + dst_ack_d = dst_ack_i; + + // The handshake is done for exactly 1 clock cycle. + if (dst_handshake) begin + dst_fsm_ns = ODD; + end + end + + ODD: begin + // Internal REQ and ACK have inverted meaning now. If dst_req goes low, this signals a new + // transaction. + dst_req_o = ~dst_req; + dst_ack_d = ~dst_ack_i; + + // The handshake is done for exactly 1 clock cycle. + if (dst_handshake) begin + dst_fsm_ns = EVEN; + end + end + + //VCS coverage off + // pragma coverage off + + default: ; + + //VCS coverage on + // pragma coverage on + + endcase + end + + // Registers + always_ff @(posedge clk_src_i or negedge rst_src_ni) begin + if (!rst_src_ni) begin + src_fsm_cs <= EVEN; + src_req_q <= 1'b0; + end else begin + src_fsm_cs <= src_fsm_ns; + src_req_q <= src_req_d; + end + end + always_ff @(posedge clk_dst_i or negedge rst_dst_ni) begin + if (!rst_dst_ni) begin + dst_fsm_cs <= EVEN; + dst_ack_q <= 1'b0; + end else begin + dst_fsm_cs <= dst_fsm_ns; + dst_ack_q <= dst_ack_d; + end + end + end + + //////////////// + // Assertions // + //////////////// + + `ifdef CALIPTRA_INC_ASSERT + //VCS coverage off + // pragma coverage off + + logic effective_rst_n; + assign effective_rst_n = rst_src_ni && rst_dst_ni; + + logic chk_flag; + always_ff @(posedge clk_src_i or negedge effective_rst_n) begin + if (!effective_rst_n) begin + chk_flag <= '0; + end else if (src_req_i && !chk_flag) begin + chk_flag <= 1'b1; + end + end + //VCS coverage on + // pragma coverage on + + // SRC domain can only de-assert REQ after receiving ACK. + `CALIPTRA_ASSERT(SyncReqAckHoldReq, $fell(src_req_i) && req_chk_i && chk_flag |-> + $fell(src_ack_o), clk_src_i, !rst_src_ni || !rst_dst_ni || !req_chk_i || !chk_flag) + `endif + + // DST domain cannot assert ACK without REQ. + `CALIPTRA_ASSERT(SyncReqAckAckNeedsReq, dst_ack_i |-> + dst_req_o, clk_dst_i, !rst_src_ni || !rst_dst_ni) + + if (EnRstChks) begin : gen_assert_en_rst_chks + `ifdef CALIPTRA_INC_ASSERT + + //VCS coverage off + // pragma coverage off + // This assertion is written very oddly because it is difficult to reliably catch + // when rst drops. + // The problem is that reset assertion in the design is often associated with clocks + // stopping, this means things like rise / fell don't work correctly since there are + // no clocks. + // As a result of this, we end up detecting way past the interest point (whenever + // clocks are restored) and falsely assert an error. + // The code below instead tries to use asynchronous flags to determine when and if + // the two domains are properly reset. + logic src_reset_flag; + always_ff @(posedge clk_src_i or negedge rst_src_ni) begin + if (!rst_src_ni) begin + src_reset_flag <= '0; + end else if(src_req_i) begin + src_reset_flag <= 1'b1; + end + end + + logic dst_reset_flag; + always_ff @(posedge clk_dst_i or negedge rst_dst_ni) begin + if (!rst_dst_ni) begin + dst_reset_flag <= '0; + end else if (dst_req_o) begin + dst_reset_flag <= 1'b1; + end + end + //VCS coverage on + // pragma coverage on + + // Always reset both domains. Both resets need to be active at the same time. + `CALIPTRA_ASSERT(SyncReqAckRstSrc, $fell(rst_src_ni) |-> + (!src_reset_flag throughout !dst_reset_flag[->1]), + clk_src_i, 0) + `CALIPTRA_ASSERT(SyncReqAckRstDst, $fell(rst_dst_ni) |-> + (!dst_reset_flag throughout !src_reset_flag[->1]), + clk_dst_i, 0) + + `endif + + + end + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_sync_reqack_data.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_sync_reqack_data.sv new file mode 100644 index 0000000..dc0a3f0 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_sync_reqack_data.sv @@ -0,0 +1,178 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// REQ/ACK synchronizer with associated data. +// +// This module synchronizes a REQ/ACK handshake with associated data across a clock domain +// crossing (CDC). Both domains will see a handshake with the duration of one clock cycle. By +// default, the data itself is not registered. The main purpose of feeding the data through this +// module to have an anchor point for waiving CDC violations. If the data is configured to flow +// from the destination (DST) to the source (SRC) domain, an additional register stage can be +// inserted for data buffering. +// +// Under the hood, this module uses a prim_sync_reqack primitive for synchronizing the +// REQ/ACK handshake. See prim_sync_reqack.sv for more details. + +`include "caliptra_prim_assert.sv" + +module caliptra_prim_sync_reqack_data #( + parameter int unsigned Width = 1, + parameter bit EnRstChks = 1'b0, // Enable reset-related assertion checks, disabled by + // default. + parameter bit DataSrc2Dst = 1'b1, // Direction of data flow: 1'b1 = SRC to DST, + // 1'b0 = DST to SRC + parameter bit DataReg = 1'b0, // Enable optional register stage for data, + // only usable with DataSrc2Dst == 1'b0. + parameter bit EnRzHs = 1'b0 // By Default, we the faster NRZ handshake protocol + // (EnRzHs = 0) is used. Enable the RZ handshake + // protocol if the FSMs need to be partial-reset-safe. +) ( + input clk_src_i, // REQ side, SRC domain + input rst_src_ni, // REQ side, SRC domain + input clk_dst_i, // ACK side, DST domain + input rst_dst_ni, // ACK side, DST domain + + input logic req_chk_i, // Used for gating assertions. Drive to 1 during normal operation. + + input logic src_req_i, // REQ side, SRC domain + output logic src_ack_o, // REQ side, SRC domain + output logic dst_req_o, // ACK side, DST domain + input logic dst_ack_i, // ACK side, DST domain + + input logic [Width-1:0] data_i, + output logic [Width-1:0] data_o +); + + //////////////////////////////////// + // REQ/ACK synchronizer primitive // + //////////////////////////////////// + caliptra_prim_sync_reqack #( + .EnRstChks(EnRstChks), + .EnRzHs(EnRzHs) + ) u_prim_sync_reqack ( + .clk_src_i, + .rst_src_ni, + .clk_dst_i, + .rst_dst_ni, + + .req_chk_i, + + .src_req_i, + .src_ack_o, + .dst_req_o, + .dst_ack_i + ); + + ///////////////////////// + // Data register stage // + ///////////////////////// + // Optional - Only relevant if the data flows from DST to SRC. In this case, it must be ensured + // that the data remains stable until the ACK becomes visible in the SRC domain. + // + // Note that for larger data widths, it is recommended to adjust the data sender to hold the data + // stable until the next REQ in order to save the cost of this register stage. + if (DataSrc2Dst == 1'b0 && DataReg == 1'b1) begin : gen_data_reg + logic data_we; + logic [Width-1:0] data_d, data_q; + + // Sample the data when seing the REQ/ACK handshake in the DST domain. + assign data_we = dst_req_o & dst_ack_i; + assign data_d = data_i; + always_ff @(posedge clk_dst_i or negedge rst_dst_ni) begin + if (!rst_dst_ni) begin + data_q <= '0; + end else if (data_we) begin + data_q <= data_d; + end + end + assign data_o = data_q; + + end else begin : gen_no_data_reg + // Just feed through the data. + assign data_o = data_i; + end + + //////////////// + // Assertions // + //////////////// + if (DataSrc2Dst == 1'b1) begin : gen_assert_data_src2dst +`ifdef CALIPTRA_INC_ASSERT + //VCS coverage off + // pragma coverage off + logic effective_rst_n; + assign effective_rst_n = rst_src_ni && rst_dst_ni; + + logic chk_flag_d, chk_flag_q; + assign chk_flag_d = src_req_i && !chk_flag_q ? 1'b1 : chk_flag_q; + + always_ff @(posedge clk_src_i or negedge effective_rst_n) begin + if (!effective_rst_n) begin + chk_flag_q <= '0; + end else begin + chk_flag_q <= chk_flag_d; + end + end + //VCS coverage on + // pragma coverage on + + // SRC domain cannot change data while waiting for ACK. + `CALIPTRA_ASSERT(SyncReqAckDataHoldSrc2Dst, !$stable(data_i) && chk_flag_q |-> + (!src_req_i || (src_req_i && src_ack_o)), + clk_src_i, !rst_src_ni || !rst_dst_ni || !chk_flag_q) + + // Register stage cannot be used. + `CALIPTRA_ASSERT_INIT(SyncReqAckDataReg, DataSrc2Dst && !DataReg) +`endif + end else if (DataSrc2Dst == 1'b0 && DataReg == 1'b0) begin : gen_assert_data_dst2src + // DST domain shall not change data while waiting for SRC domain to latch it (together with + // receiving ACK). It takes 2 SRC cycles for ACK to cross over from DST to SRC, and 1 SRC cycle + // for the next REQ to cross over from SRC to DST. + // + // Denote the src clock where REQ & ACK as time zero. The data flowing through the CDC could be + // corrupted if data_o was not stable over the previous 2 clock cycles (so we want to check time + // points -2, -1 and 0). Moreover, the DST domain cannot know that it is allowed to change value + // until at least one more SRC cycle (the time taken for REQ to cross back from SRC to DST). + // + // To make this assertion, we will sample at each of 4 time points (-2, -1, 0 and +1), asserting + // that data_o is equal at each of these times. Note this won't detect glitches at intermediate + // timepoints. + // + // The SVAs below are designed not to consume time, which means that they can be disabled with + // an $assertoff(..) and won't linger to fail later. This wouldn't work properly if we used + // something like |=> instead of the $past(...) function. That means that we have to trigger at + // the "end" of the window. To make sure we don't miss a situation where the value changed at + // time -1 (causing corruption), but reset was asserted between time 0 and 1, we split the + // assertion into two pieces. The first (SyncReqAckDataHoldDst2SrcA) checks that data doesn't + // change in a way that could cause data corruption. The second (SyncReqAckDataHoldDst2SrcB) + // checks that the DST side doesn't do anything that it shouldn't know is safe. +`ifdef CALIPTRA_INC_ASSERT + //VCS coverage off + // pragma coverage off + logic effective_rst_n; + assign effective_rst_n = rst_src_ni && rst_dst_ni; + + logic chk_flag_d, chk_flag_q; + assign chk_flag_d = src_req_i && !chk_flag_q ? 1'b1 : chk_flag_q; + + always_ff @(posedge clk_src_i or negedge effective_rst_n) begin + if (!effective_rst_n) begin + chk_flag_q <= '0; + end else begin + chk_flag_q <= chk_flag_d; + end + end + //VCS coverage on + // pragma coverage on + + `CALIPTRA_ASSERT(SyncReqAckDataHoldDst2SrcA, + chk_flag_q && src_req_i && src_ack_o |-> + $past(data_o, 2) == data_o && $past(data_o) == data_o, + clk_src_i, !rst_src_ni || !rst_dst_ni || !chk_flag_q) + `CALIPTRA_ASSERT(SyncReqAckDataHoldDst2SrcB, + chk_flag_q && $past(src_req_i && src_ack_o) |-> $past(data_o) == data_o, + clk_src_i, !rst_src_ni || !rst_dst_ni || !chk_flag_q) +`endif + end + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_trivium.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_trivium.sv new file mode 100644 index 0000000..c00cf88 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_trivium.sv @@ -0,0 +1,317 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// Trivium and Bivium stream cipher primitives +// +// This module implements the Trivium [1] and its reduced variant Bivium [2] (more precisely +// Bivium B) stream cipher primitives. Internally, they use 3 (Trivium) or 2 (Bivium) non-linear +// feedback shift registers (NFSRs). The number of output bits produced per update can flexibly +// be tuned using the OutputWidth parameter to match the needs of integrators. Up to an output +// width of 64 bits, the critical path stays unchanged. For output widths above 64 bits, the +// critical path starts to increase. The asymptotic area of the two primitives is 30 GE / output +// bit (Trivium) and 20 GE / output bit (Bivium). For a thorough analysis of the two primitives +// including security evaluation, as well as area and critical path figures, refer to [3]. +// +// As thoroughly analyzed in [3], these primitives are suitable to be used as pseudo-random +// number generators for masking countermeasures in hardware. +// +// This implementation supports three different reseeding interfaces which can be selected using +// the SeedType parameter: +// 1. SeedTypeKeyIv: 2 x 80 bits for key and IV need to be provided. Before the key stream becomes +// usable, the primitive needs to be updated 1152 / OutputWidth (Trivium) or +// 708 / OutputWidth (Bivium) times. These initial updates are performed automatically by the +// primitives. Once the reseeding and the following initialization are done, this is indicated +// with the seed_done_o output. +// 2. SeedTypeStateFull: The full 288-bit (Trivium) or 177-bit (Bivium) state is reseeded in one +// shot. +// 3. SeedTypeStatePartial: PartialSeedWidth bits at a time are injected into the state. The +// primitive latches the seed_en_i signal and keeps requesting entropy until every +// PartialSeedWidth-wide part of the state has been overwritten once. +// To enable updating the primitive and using the key stream during the reseed operation, the +// number of output bits produced per update (OutputWidth) should be greater than the width of +// the smallest NFSR in the primitve (MinNfsrWidth = 84). Thanks to the strong diffusion +// properties of the primitives, the majority of state and key stream bits change after +// reseeding the first state part and performing the first couple of updates if OutputWidth is +// chosen sufficiently large. For Bivium, a quick evaluation hints that for OutputWidth equal +// to 84, the key stream seems usable after 3 updates and most state bits seem to change after +// 5 updates. For OutputWidth equal to 160, the key stream seems usable after only 2 updates and +// most state bits seem to change after 3 updates. +// If the next PartialSeedWidth bits of entropy arrive after having done at least one update +// but the new entropy hasn't sufficiently diffused yet into the state, there is a risk that +// previously injected entropy bits are partially or completely overwritten. It is the job of +// the integrator to ensure sufficiently many updates are performed between reseeding state +// parts. In practice, this should be relatively simple as there is typically a minimal latency +// between receiving entropy bits, e.g., due to clock domain crossings in the system. +// Independently of the chosen OutputWidth parameter, it's always safe to reseed the primitive +// while it's completely idle. +// +// For details, see the following specifications and papers: +// [1] De Canniere, "Trivium Specifications" available at +// https://www.ecrypt.eu.org/stream/p3ciphers/trivium/trivium_p3.pdf +// [2] Raddum "Cryptanalytic Results on Trivium" available at +// https://www.ecrypt.eu.org/stream/papersdir/2006/039.ps +// [3] Cassiers, "Randomness Generation for Secure Hardware Masking - Unrolled Trivium to the +// Rescue" available at https://eprint.iacr.org/2023/1134 + +`include "caliptra_prim_assert.sv" + +module caliptra_prim_trivium import caliptra_prim_trivium_pkg::*; +#( + parameter bit BiviumVariant = 0, // 0: Trivium, 1: Bivium + parameter int unsigned OutputWidth = 64, // Number of output bits generated per update. + parameter bit StrictLockupProtection = 1, // Upon entering an all zero state, 1: always + // restore to the default seed, or 0: allow + // to keep the all zero state if requested by + // allow_lockup_i. + parameter seed_type_e SeedType = SeedTypeStateFull, // Reseeding inteface selection, see + // caliptra_prim_trivium_pkg.sv for possible values. + parameter int unsigned PartialSeedWidth = PartialSeedWidthDefault, + + // derived parameter + localparam int unsigned StateWidth = BiviumVariant ? BiviumStateWidth : TriviumStateWidth, + + parameter trivium_lfsr_seed_t RndCnstTriviumLfsrSeed = RndCnstTriviumLfsrSeedDefault, + + // derived parameter + localparam logic [StateWidth-1:0] StateSeed = RndCnstTriviumLfsrSeed[StateWidth-1:0] +) ( + input logic clk_i, + input logic rst_ni, + + input logic en_i, // Update the primitive. + input logic allow_lockup_i, // Allow locking up in all zero state. + // Only taken into account if + // LockupParameter = 0 + input logic seed_en_i, // Start reseeding (pulse or level). + output logic seed_done_o, // Reseeding is done (pulse). + output logic seed_req_o, // Seed REQ handshake signal + input logic seed_ack_i, // Seed ACK handshake signal + input logic [KeyIvWidth-1:0] seed_key_i, // Seed input for SeedTypeKeyIV + input logic [KeyIvWidth-1:0] seed_iv_i, // Seed input for SeedTypeKeyIV + input logic [StateWidth-1:0] seed_state_full_i, // Seed input for SeedTypeStateFull + input logic [PartialSeedWidth-1:0] seed_state_partial_i, // Seed input for SeedTypeStatePartial + + output logic [OutputWidth-1:0] key_o, // Key stream output + output logic err_o // The primitive entered an all zero state and may have + // locked up or entered the default state defined by + // RndCnstTriviumLfsrSeed depending on the + // StrictLockupProtection parameter and the allow_lockup_i + // signal. +); + + localparam int unsigned LastStatePartFractional = StateWidth % PartialSeedWidth != 0 ? 1 : 0; + localparam int unsigned NumStateParts = StateWidth / PartialSeedWidth + LastStatePartFractional; + localparam int unsigned NumBitsLastPart = StateWidth - (NumStateParts - 1) * PartialSeedWidth; + localparam int unsigned LastStatePart = NumStateParts - 1; + // Width of the variable determining which state part to overwrite with the next partial seed. + localparam int unsigned StateIdxWidth = caliptra_prim_util_pkg::vbits(NumStateParts); + + logic [StateWidth-1:0] state_d, state_q; + logic [StateWidth-1:0] state_update, state_seed; + logic seed_req_d, seed_req_q; + logic unused_seed; + logic update, update_init, wr_en_seed; + logic [StateIdxWidth-1:0] state_idx_d, state_idx_q; + logic last_state_part; + logic lockup, restore; + + assign update = en_i | update_init; + assign wr_en_seed = seed_req_o & seed_ack_i; + assign lockup = ~(|state_q); + assign err_o = lockup; + + ////////////////////////////////////////////////// + // Regular state updating and output generation // + ////////////////////////////////////////////////// + + // The current key stream depends on the current state only. + if (BiviumVariant) begin : gen_update_and_output_bivium + always_comb begin + state_update = state_q; + for (int unsigned i = 0; i < OutputWidth; i++) begin + key_o[i] = bivium_generate_key_stream(state_update); + state_update = bivium_update_state(state_update); + end + end + end else begin : gen_update_and_output_trivium + always_comb begin + state_update = state_q; + for (int unsigned i = 0; i < OutputWidth; i++) begin + key_o[i] = trivium_generate_key_stream(state_update); + state_update = trivium_update_state(state_update); + end + end + end + + /////////////// + // Reseeding // + /////////////// + + if (SeedType == SeedTypeKeyIv) begin : gen_seed_type_key_iv + if (BiviumVariant) begin : gen_seed_type_key_iv_bivium + assign state_seed = bivium_seed_key_iv(seed_key_i, seed_iv_i); + end else begin : gen_seed_type_key_iv_trivium + assign state_seed = trivium_seed_key_iv(seed_key_i, seed_iv_i); + end + + end else if (SeedType == SeedTypeStateFull) begin : gen_seed_type_state_full + assign state_seed = seed_state_full_i; + + end else begin : gen_seed_type_state_partial + // If the primitive is idle and an update is not currently being requested (update = 1'b0), the + // parts not currently being reseeded remain constant, i.e., the update function above doesn't + // modify the state. This is required to put the primitive into a known state e.g. for known + // answer testing. + // If the primitive is busy and an update is requested, the update function always modifies + // the state (but the part currently being reseeded is solely determined by the new seed). + // Otherwise the primitive could potentially produce the same key stream output twice in a row. + always_comb begin + state_seed = !update ? state_q : state_update; + // The last part may be shorter than PartialSeedWidth. + if (last_state_part) begin + state_seed[StateWidth - 1 -: NumBitsLastPart] = seed_state_partial_i[NumBitsLastPart-1:0]; + end else begin + state_seed[state_idx_q * PartialSeedWidth +: PartialSeedWidth] = seed_state_partial_i; + end + end + end + + ///////////////////////////////// + // State register and updating // + ///////////////////////////////// + + // The lockup protection can optionally be disabled at run time. This may be required to put the + // primitive into an all zero state, e.g., to switch off masking countermeasures for analysis if + // the primitive is used for generating masks. However, the err_o bit always signals this + // condition to the outside. + assign restore = lockup & (StrictLockupProtection | ~allow_lockup_i); + assign state_d = restore ? StateSeed : + wr_en_seed ? state_seed : + update ? state_update : state_q; + + always_ff @(posedge clk_i or negedge rst_ni) begin : state_reg + if (!rst_ni) begin + state_q <= StateSeed; + end else begin + state_q <= state_d; + end + end + + // Latch the seed enable signal and keep the request high until the last request is acknowledged. + assign seed_req_d = (seed_en_i | seed_req_q) & (~seed_ack_i | ~last_state_part); + always_ff @(posedge clk_i or negedge rst_ni) begin : seed_req_reg + if (!rst_ni) begin + seed_req_q <= 1'b0; + end else begin + seed_req_q <= seed_req_d; + end + end + assign seed_req_o = seed_en_i | seed_req_q; + + if (SeedType == SeedTypeKeyIv) begin : gen_key_iv_seed_handling + // After receiving key and IV, the entire state needs to be updated 4 times before the key + // stream becomes usable. Depending on OutputWidth, a different number of initial updates are + // required for this. [3] + localparam int unsigned NumInitUpdatesFractional = (StateWidth * 4) % OutputWidth != 0 ? 1 : 0; + localparam int unsigned NumInitUpdates = + (StateWidth * 4) / OutputWidth + NumInitUpdatesFractional; + localparam int unsigned LastInitUpdate = NumInitUpdates - 1; + localparam int unsigned InitUpdatesCtrWidth = caliptra_prim_util_pkg::vbits(NumInitUpdates); + + logic [InitUpdatesCtrWidth-1:0] init_update_ctr_d, init_update_ctr_q; + logic init_update_d, init_update_q; + logic last_init_update; + + // Count the number of initial updates done. + assign init_update_ctr_d = wr_en_seed ? '0 : + init_update_q ? init_update_ctr_q + 1'b1 : init_update_ctr_q; + always_ff @(posedge clk_i or negedge rst_ni) begin : init_update_ctr_reg + if (!rst_ni) begin + init_update_ctr_q <= '0; + end else begin + init_update_ctr_q <= init_update_ctr_d; + end + end + + // Track whether we're currently doing the initial updates. + assign last_init_update = init_update_ctr_q == LastInitUpdate[InitUpdatesCtrWidth-1:0]; + assign init_update_d = wr_en_seed ? 1'b1 : + last_init_update ? 1'b0 : init_update_q; + always_ff @(posedge clk_i or negedge rst_ni) begin : init_update_reg + if (!rst_ni) begin + init_update_q <= 1'b0; + end else begin + init_update_q <= init_update_d; + end + end + assign update_init = init_update_q; + + // We're done after performing the initial updates. + assign seed_done_o = init_update_q & last_init_update; + + // Tie off unused signals. + assign state_idx_d = '0; + assign state_idx_q = '0; + assign last_state_part = 1'b0; + assign unused_seed = ^{seed_state_full_i, + seed_state_partial_i, + state_idx_d, + state_idx_q, + last_state_part}; + + end else if (SeedType == SeedTypeStateFull) begin : gen_full_seed_handling + + // Only one handshake is required. + assign seed_done_o = seed_req_o & seed_ack_i; + + // Tie off unused signals. + assign update_init = 1'b0; + assign state_idx_d = '0; + assign state_idx_q = '0; + assign last_state_part = 1'b1; + assign unused_seed = ^{seed_key_i, + seed_iv_i, + seed_state_partial_i, + state_idx_d, + state_idx_q, + last_state_part}; + + end else begin : gen_partial_seed_handling + + // Seed PartialSeedWidth bits of the state at a time. Track the part idx using a counter. The + // counter is reset when seeding the last part. + assign last_state_part = state_idx_q == LastStatePart[StateIdxWidth-1:0]; + assign state_idx_d = wr_en_seed & last_state_part ? '0 : + wr_en_seed & ~last_state_part ? state_idx_q + 1'b1 : state_idx_q; + always_ff @(posedge clk_i or negedge rst_ni) begin : state_idx_reg + if (!rst_ni) begin + state_idx_q <= '0; + end else begin + state_idx_q <= state_idx_d; + end + end + + // We're done upon receiving the last state part. + assign seed_done_o = seed_req_o & seed_ack_i & last_state_part; + + // Tie off unused signals. + assign update_init = 1'b0; + assign unused_seed = ^{seed_key_i, + seed_iv_i, + seed_state_full_i}; + end + + ///////////////// + // Asssertions // + ///////////////// + + // While performing a partial reseed of the state, the primitive can be updated. However, this + // should only be done if the number of produced bits per update / shift amount per update is + // greater than the width of the smallest NFSR (= 84) inside the primitve. Otherwise, there is a + // risk of overwriting the previously provided partial seed which reduces the amount of fresh + // entropy injected per full reseed operation. + `CALIPTRA_ASSERT(PrimTriviumPartialStateSeedWhileUpdate_A, + (SeedType == SeedTypeStatePartial) && seed_req_o && en_i |-> OutputWidth >= MinNfsrWidth) + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_trivium_pkg.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_trivium_pkg.sv new file mode 100644 index 0000000..9ee8170 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_trivium_pkg.sv @@ -0,0 +1,159 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +package caliptra_prim_trivium_pkg; + + typedef enum logic [31:0] { + SeedTypeKeyIv, // 2 * 80 bits for key and IV, requires advancing the primitive + // 1152/OutputWidth (Trivium) or 708/OutputWidth (Bivium) times + // before the key stream becomes usable. + SeedTypeStateFull, // Seed the full state + SeedTypeStatePartial // Seed PartialSeedWidth bits of the state at a time. + } seed_type_e; + + parameter int unsigned KeyIvWidth = 80; + parameter int unsigned PartialSeedWidthDefault = 32; + parameter int unsigned MinNfsrWidth = 84; + + // These LFSR parameters have been generated with + // $ ./util/design/gen-lfsr-seed.py --width 288 --seed 31468618 --prefix "Trivium" + parameter int TriviumLfsrWidth = 288; + typedef logic [TriviumLfsrWidth-1:0] trivium_lfsr_seed_t; + parameter trivium_lfsr_seed_t RndCnstTriviumLfsrSeedDefault = { + 32'h758a4420, + 256'h31e1c461_6ea343ec_153282a3_0c132b57_23c5a4cf_4743b3c7_c32d580f_74f1713a + }; + + ///////////// + // Trivium // + ///////////// + + parameter int unsigned TriviumMaxNfsrWidth = 111; + parameter int TriviumStateWidth = TriviumLfsrWidth; + + function automatic logic [TriviumStateWidth-1:0] trivium_update_state( + logic [TriviumStateWidth-1:0] in + ); + logic [TriviumStateWidth-1:0] out; + logic mul_90_91, mul_174_175, mul_285_286; + logic add_65_92, add_161_176, add_242_287; + + // First state part intermediate results + mul_90_91 = in[90] & in[91]; + add_65_92 = in[65] ^ in[92]; + + // Second state part intermediate results + mul_174_175 = in[174] & in[175]; + add_161_176 = in[161] ^ in[176]; + + // Third state part intermediate results + mul_285_286 = in[285] & in[286]; + add_242_287 = in[242] ^ in[287]; + + // Updates - feedback part + out[0] = in[68] ^ (mul_285_286 ^ add_242_287); + out[93] = in[170] ^ (add_65_92 ^ mul_90_91); + out[177] = in[263] ^ (mul_174_175 ^ add_161_176); + + // Updates - shift part + out[92:1] = in[91:0]; + out[176:94] = in[175:93]; + out[287:178] = in[286:177]; + + return out; + endfunction + + function automatic logic trivium_generate_key_stream( + logic [TriviumStateWidth-1:0] state + ); + logic key; + logic add_65_92, add_161_176, add_242_287; + logic unused_state; + + add_65_92 = state[65] ^ state[92]; + add_161_176 = state[161] ^ state[176]; + add_242_287 = state[242] ^ state[287]; + key = add_161_176 ^ add_65_92 ^ add_242_287; + + unused_state = ^{state[286:243], + state[241:177], + state[175:162], + state[160:93], + state[91:66], + state[64:0]}; + return key; + endfunction + + function automatic logic [TriviumStateWidth-1:0] trivium_seed_key_iv( + logic [KeyIvWidth-1:0] key, + logic [KeyIvWidth-1:0] iv + ); + logic [TriviumStateWidth-1:0] state; + // [287:285] [284:173] [172:93] [92:80] [79:0] + state = {3'b111, 112'b0, iv, 13'b0, key}; + return state; + endfunction + + //////////// + // Bivium // + //////////// + + parameter int unsigned BiviumMaxNfsrWidth = 93; + parameter int BiviumStateWidth = 177; + + function automatic logic [BiviumStateWidth-1:0] bivium_update_state( + logic [BiviumStateWidth-1:0] in + ); + logic [BiviumStateWidth-1:0] out; + logic mul_90_91, mul_174_175; + logic add_65_92, add_161_176; + + // First state half intermediate results + mul_90_91 = in[90] & in[91]; + add_65_92 = in[65] ^ in[92]; + + // Second state half intermediate results + mul_174_175 = in[174] & in[175]; + add_161_176 = in[161] ^ in[176]; + + // Updates - feedback part + out[0] = in[68] ^ (mul_174_175 ^ add_161_176); + out[93] = in[170] ^ add_65_92 ^ mul_90_91; + + // Updates - shift part + out[92:1] = in[91:0]; + out[176:94] = in[175:93]; + + return out; + endfunction + + function automatic logic bivium_generate_key_stream( + logic [BiviumStateWidth-1:0] state + ); + logic key; + logic add_65_92, add_161_176; + logic unused_state; + + add_65_92 = state[65] ^ state[92]; + add_161_176 = state[161] ^ state[176]; + key = add_161_176 ^ add_65_92; + + unused_state = ^{state[175:162], + state[160:93], + state[91:66], + state[64:0]}; + return key; + endfunction + + function automatic logic [BiviumStateWidth-1:0] bivium_seed_key_iv( + logic [KeyIvWidth-1:0] key, + logic [KeyIvWidth-1:0] iv + ); + logic [BiviumStateWidth-1:0] state; + // [176:173] [172:93] [92:80] [79:0] + state = {4'b0, iv, 13'b0, key}; + return state; + endfunction + +endpackage diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_util_memload.svh b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_util_memload.svh new file mode 100644 index 0000000..81600a8 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_util_memload.svh @@ -0,0 +1,68 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +/** + * Memory loader for simulation + * + * Include this file in a memory primitive to load a memory array from + * simulation. + * + * Requirements: + * - A memory array named `mem`. + * - A parameter `Width` giving the memory width (word size) in bit. + * - A parameter `Depth` giving the memory depth in words. + * - A parameter `MemInitFile` with a file path of a VMEM file to be loaded into + * the memory if not empty. + * + * Note this works with memories up to a maximum width of 312 bits. Should this maximum width be + * increased all of the `simutil_set_mem` and `simutil_get_mem` call sites must be found (e.g. using + * git grep) and adjusted appropriately. + */ + +`ifndef SYNTHESIS + // Task for loading 'mem' with SystemVerilog system task $readmemh() + export "DPI-C" task simutil_memload; + + task simutil_memload; + input string file; + $readmemh(file, mem); + endtask + + // Function for setting a specific element in |mem| + // Returns 1 (true) for success, 0 (false) for errors. + export "DPI-C" function simutil_set_mem; + + function int simutil_set_mem(input int index, input bit [311:0] val); + int valid; + valid = Width > 312 || index >= Depth ? 0 : 1; + if (valid == 1) mem[index] = val[Width-1:0]; + return valid; + endfunction + + // Function for getting a specific element in |mem| + export "DPI-C" function simutil_get_mem; + + function int simutil_get_mem(input int index, output bit [311:0] val); + int valid; + valid = Width > 312 || index >= Depth ? 0 : 1; + if (valid == 1) begin + val = 0; + val[Width-1:0] = mem[index]; + end + return valid; + endfunction +`endif + +initial begin + logic show_mem_paths; + + // Print the hierarchical path to the memory to help make formal connectivity checks easy. + void'($value$plusargs("show_mem_paths=%0b", show_mem_paths)); + if (show_mem_paths) $display("%m"); + + if (MemInitFile != "") begin : gen_meminit + $display("Initializing memory %m from file '%s'.", MemInitFile); + $readmemh(MemInitFile, mem); + end +end diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_prim_util_pkg.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_util_pkg.sv new file mode 100644 index 0000000..c615e0b --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_prim_util_pkg.sv @@ -0,0 +1,56 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + + +/** + * Utility functions + */ +package caliptra_prim_util_pkg; + /** + * Math function: Number of bits needed to address |value| items. + * + * 0 for value == 0 + * vbits = 1 for value == 1 + * ceil(log2(value)) for value > 1 + * + * + * The primary use case for this function is the definition of registers/arrays + * which are wide enough to contain |value| items. + * + * This function identical to $clog2() for all input values except the value 1; + * it could be considered an "enhanced" $clog2() function. + * + * + * Example 1: + * parameter Items = 1; + * localparam ItemsWidth = vbits(Items); // 1 + * logic [ItemsWidth-1:0] item_register; // items_register is now [0:0] + * + * Example 2: + * parameter Items = 64; + * localparam ItemsWidth = vbits(Items); // 6 + * logic [ItemsWidth-1:0] item_register; // items_register is now [5:0] + * + * Note: If you want to store the number "value" inside a register, you need + * a register with size vbits(value + 1), since you also need to store + * the number 0. + * + * Example 3: + * logic [vbits(64)-1:0] store_64_logic_values; // width is [5:0] + * logic [vbits(64 + 1)-1:0] store_number_64; // width is [6:0] + */ + function automatic integer vbits(integer value); + return (value == 1) ? 1 : $clog2(value); + endfunction + +`ifdef CALIPTRA_INC_ASSERT + // Package-scoped variable to detect the end of simulation. + // + // Used only in DV simulations. The bit will be used by assertions in RTL to perform end-of-test + // cleanup. It is set to 1 in `dv_test_status_pkg::dv_test_status()`, which is invoked right + // before the simulation is terminated, to signal the status of the test. + bit end_of_simulation; +`endif + +endpackage diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_reg_defines.svh b/designs/Caliptra/src/caliptra-rtl/caliptra_reg_defines.svh new file mode 100644 index 0000000..8f0383e --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_reg_defines.svh @@ -0,0 +1,2453 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +// +`ifndef CALIPTRA_REG_DEFINES_HEADER +`define CALIPTRA_REG_DEFINES_HEADER + + +`define CLP_BASE_ADDR (32'h0) +`define CLP_DOE_REG_BASE_ADDR (32'h10000000) +`define CLP_DOE_REG_DOE_IV_0 (32'h10000000) +`define CLP_DOE_REG_DOE_IV_1 (32'h10000004) +`define CLP_DOE_REG_DOE_IV_2 (32'h10000008) +`define CLP_DOE_REG_DOE_IV_3 (32'h1000000c) +`define CLP_DOE_REG_DOE_CTRL (32'h10000010) +`define CLP_DOE_REG_DOE_STATUS (32'h10000014) +`define CLP_DOE_REG_INTR_BLOCK_RF_START (32'h10000800) +`define CLP_DOE_REG_INTR_BLOCK_RF_GLOBAL_INTR_EN_R (32'h10000800) +`define CLP_DOE_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R (32'h10000804) +`define CLP_DOE_REG_INTR_BLOCK_RF_NOTIF_INTR_EN_R (32'h10000808) +`define CLP_DOE_REG_INTR_BLOCK_RF_ERROR_GLOBAL_INTR_R (32'h1000080c) +`define CLP_DOE_REG_INTR_BLOCK_RF_NOTIF_GLOBAL_INTR_R (32'h10000810) +`define CLP_DOE_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R (32'h10000814) +`define CLP_DOE_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R (32'h10000818) +`define CLP_DOE_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R (32'h1000081c) +`define CLP_DOE_REG_INTR_BLOCK_RF_NOTIF_INTR_TRIG_R (32'h10000820) +`define CLP_DOE_REG_INTR_BLOCK_RF_ERROR0_INTR_COUNT_R (32'h10000900) +`define CLP_DOE_REG_INTR_BLOCK_RF_ERROR1_INTR_COUNT_R (32'h10000904) +`define CLP_DOE_REG_INTR_BLOCK_RF_ERROR2_INTR_COUNT_R (32'h10000908) +`define CLP_DOE_REG_INTR_BLOCK_RF_ERROR3_INTR_COUNT_R (32'h1000090c) +`define CLP_DOE_REG_INTR_BLOCK_RF_NOTIF_CMD_DONE_INTR_COUNT_R (32'h10000980) +`define CLP_DOE_REG_INTR_BLOCK_RF_ERROR0_INTR_COUNT_INCR_R (32'h10000a00) +`define CLP_DOE_REG_INTR_BLOCK_RF_ERROR1_INTR_COUNT_INCR_R (32'h10000a04) +`define CLP_DOE_REG_INTR_BLOCK_RF_ERROR2_INTR_COUNT_INCR_R (32'h10000a08) +`define CLP_DOE_REG_INTR_BLOCK_RF_ERROR3_INTR_COUNT_INCR_R (32'h10000a0c) +`define CLP_DOE_REG_INTR_BLOCK_RF_NOTIF_CMD_DONE_INTR_COUNT_INCR_R (32'h10000a10) +`define CLP_ECC_REG_BASE_ADDR (32'h10008000) +`define CLP_ECC_REG_ECC_NAME_0 (32'h10008000) +`define CLP_ECC_REG_ECC_NAME_1 (32'h10008004) +`define CLP_ECC_REG_ECC_VERSION_0 (32'h10008008) +`define CLP_ECC_REG_ECC_VERSION_1 (32'h1000800c) +`define CLP_ECC_REG_ECC_CTRL (32'h10008010) +`define CLP_ECC_REG_ECC_STATUS (32'h10008018) +`define CLP_ECC_REG_ECC_SEED_0 (32'h10008080) +`define CLP_ECC_REG_ECC_SEED_1 (32'h10008084) +`define CLP_ECC_REG_ECC_SEED_2 (32'h10008088) +`define CLP_ECC_REG_ECC_SEED_3 (32'h1000808c) +`define CLP_ECC_REG_ECC_SEED_4 (32'h10008090) +`define CLP_ECC_REG_ECC_SEED_5 (32'h10008094) +`define CLP_ECC_REG_ECC_SEED_6 (32'h10008098) +`define CLP_ECC_REG_ECC_SEED_7 (32'h1000809c) +`define CLP_ECC_REG_ECC_SEED_8 (32'h100080a0) +`define CLP_ECC_REG_ECC_SEED_9 (32'h100080a4) +`define CLP_ECC_REG_ECC_SEED_10 (32'h100080a8) +`define CLP_ECC_REG_ECC_SEED_11 (32'h100080ac) +`define CLP_ECC_REG_ECC_MSG_0 (32'h10008100) +`define CLP_ECC_REG_ECC_MSG_1 (32'h10008104) +`define CLP_ECC_REG_ECC_MSG_2 (32'h10008108) +`define CLP_ECC_REG_ECC_MSG_3 (32'h1000810c) +`define CLP_ECC_REG_ECC_MSG_4 (32'h10008110) +`define CLP_ECC_REG_ECC_MSG_5 (32'h10008114) +`define CLP_ECC_REG_ECC_MSG_6 (32'h10008118) +`define CLP_ECC_REG_ECC_MSG_7 (32'h1000811c) +`define CLP_ECC_REG_ECC_MSG_8 (32'h10008120) +`define CLP_ECC_REG_ECC_MSG_9 (32'h10008124) +`define CLP_ECC_REG_ECC_MSG_10 (32'h10008128) +`define CLP_ECC_REG_ECC_MSG_11 (32'h1000812c) +`define CLP_ECC_REG_ECC_PRIVKEY_OUT_0 (32'h10008180) +`define CLP_ECC_REG_ECC_PRIVKEY_OUT_1 (32'h10008184) +`define CLP_ECC_REG_ECC_PRIVKEY_OUT_2 (32'h10008188) +`define CLP_ECC_REG_ECC_PRIVKEY_OUT_3 (32'h1000818c) +`define CLP_ECC_REG_ECC_PRIVKEY_OUT_4 (32'h10008190) +`define CLP_ECC_REG_ECC_PRIVKEY_OUT_5 (32'h10008194) +`define CLP_ECC_REG_ECC_PRIVKEY_OUT_6 (32'h10008198) +`define CLP_ECC_REG_ECC_PRIVKEY_OUT_7 (32'h1000819c) +`define CLP_ECC_REG_ECC_PRIVKEY_OUT_8 (32'h100081a0) +`define CLP_ECC_REG_ECC_PRIVKEY_OUT_9 (32'h100081a4) +`define CLP_ECC_REG_ECC_PRIVKEY_OUT_10 (32'h100081a8) +`define CLP_ECC_REG_ECC_PRIVKEY_OUT_11 (32'h100081ac) +`define CLP_ECC_REG_ECC_PUBKEY_X_0 (32'h10008200) +`define CLP_ECC_REG_ECC_PUBKEY_X_1 (32'h10008204) +`define CLP_ECC_REG_ECC_PUBKEY_X_2 (32'h10008208) +`define CLP_ECC_REG_ECC_PUBKEY_X_3 (32'h1000820c) +`define CLP_ECC_REG_ECC_PUBKEY_X_4 (32'h10008210) +`define CLP_ECC_REG_ECC_PUBKEY_X_5 (32'h10008214) +`define CLP_ECC_REG_ECC_PUBKEY_X_6 (32'h10008218) +`define CLP_ECC_REG_ECC_PUBKEY_X_7 (32'h1000821c) +`define CLP_ECC_REG_ECC_PUBKEY_X_8 (32'h10008220) +`define CLP_ECC_REG_ECC_PUBKEY_X_9 (32'h10008224) +`define CLP_ECC_REG_ECC_PUBKEY_X_10 (32'h10008228) +`define CLP_ECC_REG_ECC_PUBKEY_X_11 (32'h1000822c) +`define CLP_ECC_REG_ECC_PUBKEY_Y_0 (32'h10008280) +`define CLP_ECC_REG_ECC_PUBKEY_Y_1 (32'h10008284) +`define CLP_ECC_REG_ECC_PUBKEY_Y_2 (32'h10008288) +`define CLP_ECC_REG_ECC_PUBKEY_Y_3 (32'h1000828c) +`define CLP_ECC_REG_ECC_PUBKEY_Y_4 (32'h10008290) +`define CLP_ECC_REG_ECC_PUBKEY_Y_5 (32'h10008294) +`define CLP_ECC_REG_ECC_PUBKEY_Y_6 (32'h10008298) +`define CLP_ECC_REG_ECC_PUBKEY_Y_7 (32'h1000829c) +`define CLP_ECC_REG_ECC_PUBKEY_Y_8 (32'h100082a0) +`define CLP_ECC_REG_ECC_PUBKEY_Y_9 (32'h100082a4) +`define CLP_ECC_REG_ECC_PUBKEY_Y_10 (32'h100082a8) +`define CLP_ECC_REG_ECC_PUBKEY_Y_11 (32'h100082ac) +`define CLP_ECC_REG_ECC_SIGN_R_0 (32'h10008300) +`define CLP_ECC_REG_ECC_SIGN_R_1 (32'h10008304) +`define CLP_ECC_REG_ECC_SIGN_R_2 (32'h10008308) +`define CLP_ECC_REG_ECC_SIGN_R_3 (32'h1000830c) +`define CLP_ECC_REG_ECC_SIGN_R_4 (32'h10008310) +`define CLP_ECC_REG_ECC_SIGN_R_5 (32'h10008314) +`define CLP_ECC_REG_ECC_SIGN_R_6 (32'h10008318) +`define CLP_ECC_REG_ECC_SIGN_R_7 (32'h1000831c) +`define CLP_ECC_REG_ECC_SIGN_R_8 (32'h10008320) +`define CLP_ECC_REG_ECC_SIGN_R_9 (32'h10008324) +`define CLP_ECC_REG_ECC_SIGN_R_10 (32'h10008328) +`define CLP_ECC_REG_ECC_SIGN_R_11 (32'h1000832c) +`define CLP_ECC_REG_ECC_SIGN_S_0 (32'h10008380) +`define CLP_ECC_REG_ECC_SIGN_S_1 (32'h10008384) +`define CLP_ECC_REG_ECC_SIGN_S_2 (32'h10008388) +`define CLP_ECC_REG_ECC_SIGN_S_3 (32'h1000838c) +`define CLP_ECC_REG_ECC_SIGN_S_4 (32'h10008390) +`define CLP_ECC_REG_ECC_SIGN_S_5 (32'h10008394) +`define CLP_ECC_REG_ECC_SIGN_S_6 (32'h10008398) +`define CLP_ECC_REG_ECC_SIGN_S_7 (32'h1000839c) +`define CLP_ECC_REG_ECC_SIGN_S_8 (32'h100083a0) +`define CLP_ECC_REG_ECC_SIGN_S_9 (32'h100083a4) +`define CLP_ECC_REG_ECC_SIGN_S_10 (32'h100083a8) +`define CLP_ECC_REG_ECC_SIGN_S_11 (32'h100083ac) +`define CLP_ECC_REG_ECC_VERIFY_R_0 (32'h10008400) +`define CLP_ECC_REG_ECC_VERIFY_R_1 (32'h10008404) +`define CLP_ECC_REG_ECC_VERIFY_R_2 (32'h10008408) +`define CLP_ECC_REG_ECC_VERIFY_R_3 (32'h1000840c) +`define CLP_ECC_REG_ECC_VERIFY_R_4 (32'h10008410) +`define CLP_ECC_REG_ECC_VERIFY_R_5 (32'h10008414) +`define CLP_ECC_REG_ECC_VERIFY_R_6 (32'h10008418) +`define CLP_ECC_REG_ECC_VERIFY_R_7 (32'h1000841c) +`define CLP_ECC_REG_ECC_VERIFY_R_8 (32'h10008420) +`define CLP_ECC_REG_ECC_VERIFY_R_9 (32'h10008424) +`define CLP_ECC_REG_ECC_VERIFY_R_10 (32'h10008428) +`define CLP_ECC_REG_ECC_VERIFY_R_11 (32'h1000842c) +`define CLP_ECC_REG_ECC_IV_0 (32'h10008480) +`define CLP_ECC_REG_ECC_IV_1 (32'h10008484) +`define CLP_ECC_REG_ECC_IV_2 (32'h10008488) +`define CLP_ECC_REG_ECC_IV_3 (32'h1000848c) +`define CLP_ECC_REG_ECC_IV_4 (32'h10008490) +`define CLP_ECC_REG_ECC_IV_5 (32'h10008494) +`define CLP_ECC_REG_ECC_IV_6 (32'h10008498) +`define CLP_ECC_REG_ECC_IV_7 (32'h1000849c) +`define CLP_ECC_REG_ECC_IV_8 (32'h100084a0) +`define CLP_ECC_REG_ECC_IV_9 (32'h100084a4) +`define CLP_ECC_REG_ECC_IV_10 (32'h100084a8) +`define CLP_ECC_REG_ECC_IV_11 (32'h100084ac) +`define CLP_ECC_REG_ECC_NONCE_0 (32'h10008500) +`define CLP_ECC_REG_ECC_NONCE_1 (32'h10008504) +`define CLP_ECC_REG_ECC_NONCE_2 (32'h10008508) +`define CLP_ECC_REG_ECC_NONCE_3 (32'h1000850c) +`define CLP_ECC_REG_ECC_NONCE_4 (32'h10008510) +`define CLP_ECC_REG_ECC_NONCE_5 (32'h10008514) +`define CLP_ECC_REG_ECC_NONCE_6 (32'h10008518) +`define CLP_ECC_REG_ECC_NONCE_7 (32'h1000851c) +`define CLP_ECC_REG_ECC_NONCE_8 (32'h10008520) +`define CLP_ECC_REG_ECC_NONCE_9 (32'h10008524) +`define CLP_ECC_REG_ECC_NONCE_10 (32'h10008528) +`define CLP_ECC_REG_ECC_NONCE_11 (32'h1000852c) +`define CLP_ECC_REG_ECC_PRIVKEY_IN_0 (32'h10008580) +`define CLP_ECC_REG_ECC_PRIVKEY_IN_1 (32'h10008584) +`define CLP_ECC_REG_ECC_PRIVKEY_IN_2 (32'h10008588) +`define CLP_ECC_REG_ECC_PRIVKEY_IN_3 (32'h1000858c) +`define CLP_ECC_REG_ECC_PRIVKEY_IN_4 (32'h10008590) +`define CLP_ECC_REG_ECC_PRIVKEY_IN_5 (32'h10008594) +`define CLP_ECC_REG_ECC_PRIVKEY_IN_6 (32'h10008598) +`define CLP_ECC_REG_ECC_PRIVKEY_IN_7 (32'h1000859c) +`define CLP_ECC_REG_ECC_PRIVKEY_IN_8 (32'h100085a0) +`define CLP_ECC_REG_ECC_PRIVKEY_IN_9 (32'h100085a4) +`define CLP_ECC_REG_ECC_PRIVKEY_IN_10 (32'h100085a8) +`define CLP_ECC_REG_ECC_PRIVKEY_IN_11 (32'h100085ac) +`define CLP_ECC_REG_ECC_DH_SHARED_KEY_0 (32'h100085c0) +`define CLP_ECC_REG_ECC_DH_SHARED_KEY_1 (32'h100085c4) +`define CLP_ECC_REG_ECC_DH_SHARED_KEY_2 (32'h100085c8) +`define CLP_ECC_REG_ECC_DH_SHARED_KEY_3 (32'h100085cc) +`define CLP_ECC_REG_ECC_DH_SHARED_KEY_4 (32'h100085d0) +`define CLP_ECC_REG_ECC_DH_SHARED_KEY_5 (32'h100085d4) +`define CLP_ECC_REG_ECC_DH_SHARED_KEY_6 (32'h100085d8) +`define CLP_ECC_REG_ECC_DH_SHARED_KEY_7 (32'h100085dc) +`define CLP_ECC_REG_ECC_DH_SHARED_KEY_8 (32'h100085e0) +`define CLP_ECC_REG_ECC_DH_SHARED_KEY_9 (32'h100085e4) +`define CLP_ECC_REG_ECC_DH_SHARED_KEY_10 (32'h100085e8) +`define CLP_ECC_REG_ECC_DH_SHARED_KEY_11 (32'h100085ec) +`define CLP_ECC_REG_ECC_KV_RD_PKEY_CTRL (32'h10008600) +`define CLP_ECC_REG_ECC_KV_RD_PKEY_STATUS (32'h10008604) +`define CLP_ECC_REG_ECC_KV_RD_SEED_CTRL (32'h10008608) +`define CLP_ECC_REG_ECC_KV_RD_SEED_STATUS (32'h1000860c) +`define CLP_ECC_REG_ECC_KV_WR_PKEY_CTRL (32'h10008610) +`define CLP_ECC_REG_ECC_KV_WR_PKEY_STATUS (32'h10008614) +`define CLP_ECC_REG_INTR_BLOCK_RF_START (32'h10008800) +`define CLP_ECC_REG_INTR_BLOCK_RF_GLOBAL_INTR_EN_R (32'h10008800) +`define CLP_ECC_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R (32'h10008804) +`define CLP_ECC_REG_INTR_BLOCK_RF_NOTIF_INTR_EN_R (32'h10008808) +`define CLP_ECC_REG_INTR_BLOCK_RF_ERROR_GLOBAL_INTR_R (32'h1000880c) +`define CLP_ECC_REG_INTR_BLOCK_RF_NOTIF_GLOBAL_INTR_R (32'h10008810) +`define CLP_ECC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R (32'h10008814) +`define CLP_ECC_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R (32'h10008818) +`define CLP_ECC_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R (32'h1000881c) +`define CLP_ECC_REG_INTR_BLOCK_RF_NOTIF_INTR_TRIG_R (32'h10008820) +`define CLP_ECC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_COUNT_R (32'h10008900) +`define CLP_ECC_REG_INTR_BLOCK_RF_NOTIF_CMD_DONE_INTR_COUNT_R (32'h10008980) +`define CLP_ECC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_COUNT_INCR_R (32'h10008a00) +`define CLP_ECC_REG_INTR_BLOCK_RF_NOTIF_CMD_DONE_INTR_COUNT_INCR_R (32'h10008a04) +`define CLP_HMAC_REG_BASE_ADDR (32'h10010000) +`define CLP_HMAC_REG_HMAC512_NAME_0 (32'h10010000) +`define CLP_HMAC_REG_HMAC512_NAME_1 (32'h10010004) +`define CLP_HMAC_REG_HMAC512_VERSION_0 (32'h10010008) +`define CLP_HMAC_REG_HMAC512_VERSION_1 (32'h1001000c) +`define CLP_HMAC_REG_HMAC512_CTRL (32'h10010010) +`define CLP_HMAC_REG_HMAC512_STATUS (32'h10010018) +`define CLP_HMAC_REG_HMAC512_KEY_0 (32'h10010040) +`define CLP_HMAC_REG_HMAC512_KEY_1 (32'h10010044) +`define CLP_HMAC_REG_HMAC512_KEY_2 (32'h10010048) +`define CLP_HMAC_REG_HMAC512_KEY_3 (32'h1001004c) +`define CLP_HMAC_REG_HMAC512_KEY_4 (32'h10010050) +`define CLP_HMAC_REG_HMAC512_KEY_5 (32'h10010054) +`define CLP_HMAC_REG_HMAC512_KEY_6 (32'h10010058) +`define CLP_HMAC_REG_HMAC512_KEY_7 (32'h1001005c) +`define CLP_HMAC_REG_HMAC512_KEY_8 (32'h10010060) +`define CLP_HMAC_REG_HMAC512_KEY_9 (32'h10010064) +`define CLP_HMAC_REG_HMAC512_KEY_10 (32'h10010068) +`define CLP_HMAC_REG_HMAC512_KEY_11 (32'h1001006c) +`define CLP_HMAC_REG_HMAC512_KEY_12 (32'h10010070) +`define CLP_HMAC_REG_HMAC512_KEY_13 (32'h10010074) +`define CLP_HMAC_REG_HMAC512_KEY_14 (32'h10010078) +`define CLP_HMAC_REG_HMAC512_KEY_15 (32'h1001007c) +`define CLP_HMAC_REG_HMAC512_BLOCK_0 (32'h10010080) +`define CLP_HMAC_REG_HMAC512_BLOCK_1 (32'h10010084) +`define CLP_HMAC_REG_HMAC512_BLOCK_2 (32'h10010088) +`define CLP_HMAC_REG_HMAC512_BLOCK_3 (32'h1001008c) +`define CLP_HMAC_REG_HMAC512_BLOCK_4 (32'h10010090) +`define CLP_HMAC_REG_HMAC512_BLOCK_5 (32'h10010094) +`define CLP_HMAC_REG_HMAC512_BLOCK_6 (32'h10010098) +`define CLP_HMAC_REG_HMAC512_BLOCK_7 (32'h1001009c) +`define CLP_HMAC_REG_HMAC512_BLOCK_8 (32'h100100a0) +`define CLP_HMAC_REG_HMAC512_BLOCK_9 (32'h100100a4) +`define CLP_HMAC_REG_HMAC512_BLOCK_10 (32'h100100a8) +`define CLP_HMAC_REG_HMAC512_BLOCK_11 (32'h100100ac) +`define CLP_HMAC_REG_HMAC512_BLOCK_12 (32'h100100b0) +`define CLP_HMAC_REG_HMAC512_BLOCK_13 (32'h100100b4) +`define CLP_HMAC_REG_HMAC512_BLOCK_14 (32'h100100b8) +`define CLP_HMAC_REG_HMAC512_BLOCK_15 (32'h100100bc) +`define CLP_HMAC_REG_HMAC512_BLOCK_16 (32'h100100c0) +`define CLP_HMAC_REG_HMAC512_BLOCK_17 (32'h100100c4) +`define CLP_HMAC_REG_HMAC512_BLOCK_18 (32'h100100c8) +`define CLP_HMAC_REG_HMAC512_BLOCK_19 (32'h100100cc) +`define CLP_HMAC_REG_HMAC512_BLOCK_20 (32'h100100d0) +`define CLP_HMAC_REG_HMAC512_BLOCK_21 (32'h100100d4) +`define CLP_HMAC_REG_HMAC512_BLOCK_22 (32'h100100d8) +`define CLP_HMAC_REG_HMAC512_BLOCK_23 (32'h100100dc) +`define CLP_HMAC_REG_HMAC512_BLOCK_24 (32'h100100e0) +`define CLP_HMAC_REG_HMAC512_BLOCK_25 (32'h100100e4) +`define CLP_HMAC_REG_HMAC512_BLOCK_26 (32'h100100e8) +`define CLP_HMAC_REG_HMAC512_BLOCK_27 (32'h100100ec) +`define CLP_HMAC_REG_HMAC512_BLOCK_28 (32'h100100f0) +`define CLP_HMAC_REG_HMAC512_BLOCK_29 (32'h100100f4) +`define CLP_HMAC_REG_HMAC512_BLOCK_30 (32'h100100f8) +`define CLP_HMAC_REG_HMAC512_BLOCK_31 (32'h100100fc) +`define CLP_HMAC_REG_HMAC512_TAG_0 (32'h10010100) +`define CLP_HMAC_REG_HMAC512_TAG_1 (32'h10010104) +`define CLP_HMAC_REG_HMAC512_TAG_2 (32'h10010108) +`define CLP_HMAC_REG_HMAC512_TAG_3 (32'h1001010c) +`define CLP_HMAC_REG_HMAC512_TAG_4 (32'h10010110) +`define CLP_HMAC_REG_HMAC512_TAG_5 (32'h10010114) +`define CLP_HMAC_REG_HMAC512_TAG_6 (32'h10010118) +`define CLP_HMAC_REG_HMAC512_TAG_7 (32'h1001011c) +`define CLP_HMAC_REG_HMAC512_TAG_8 (32'h10010120) +`define CLP_HMAC_REG_HMAC512_TAG_9 (32'h10010124) +`define CLP_HMAC_REG_HMAC512_TAG_10 (32'h10010128) +`define CLP_HMAC_REG_HMAC512_TAG_11 (32'h1001012c) +`define CLP_HMAC_REG_HMAC512_TAG_12 (32'h10010130) +`define CLP_HMAC_REG_HMAC512_TAG_13 (32'h10010134) +`define CLP_HMAC_REG_HMAC512_TAG_14 (32'h10010138) +`define CLP_HMAC_REG_HMAC512_TAG_15 (32'h1001013c) +`define CLP_HMAC_REG_HMAC512_LFSR_SEED_0 (32'h10010140) +`define CLP_HMAC_REG_HMAC512_LFSR_SEED_1 (32'h10010144) +`define CLP_HMAC_REG_HMAC512_LFSR_SEED_2 (32'h10010148) +`define CLP_HMAC_REG_HMAC512_LFSR_SEED_3 (32'h1001014c) +`define CLP_HMAC_REG_HMAC512_LFSR_SEED_4 (32'h10010150) +`define CLP_HMAC_REG_HMAC512_LFSR_SEED_5 (32'h10010154) +`define CLP_HMAC_REG_HMAC512_LFSR_SEED_6 (32'h10010158) +`define CLP_HMAC_REG_HMAC512_LFSR_SEED_7 (32'h1001015c) +`define CLP_HMAC_REG_HMAC512_LFSR_SEED_8 (32'h10010160) +`define CLP_HMAC_REG_HMAC512_LFSR_SEED_9 (32'h10010164) +`define CLP_HMAC_REG_HMAC512_LFSR_SEED_10 (32'h10010168) +`define CLP_HMAC_REG_HMAC512_LFSR_SEED_11 (32'h1001016c) +`define CLP_HMAC_REG_HMAC512_KV_RD_KEY_CTRL (32'h10010600) +`define CLP_HMAC_REG_HMAC512_KV_RD_KEY_STATUS (32'h10010604) +`define CLP_HMAC_REG_HMAC512_KV_RD_BLOCK_CTRL (32'h10010608) +`define CLP_HMAC_REG_HMAC512_KV_RD_BLOCK_STATUS (32'h1001060c) +`define CLP_HMAC_REG_HMAC512_KV_WR_CTRL (32'h10010610) +`define CLP_HMAC_REG_HMAC512_KV_WR_STATUS (32'h10010614) +`define CLP_HMAC_REG_INTR_BLOCK_RF_START (32'h10010800) +`define CLP_HMAC_REG_INTR_BLOCK_RF_GLOBAL_INTR_EN_R (32'h10010800) +`define CLP_HMAC_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R (32'h10010804) +`define CLP_HMAC_REG_INTR_BLOCK_RF_NOTIF_INTR_EN_R (32'h10010808) +`define CLP_HMAC_REG_INTR_BLOCK_RF_ERROR_GLOBAL_INTR_R (32'h1001080c) +`define CLP_HMAC_REG_INTR_BLOCK_RF_NOTIF_GLOBAL_INTR_R (32'h10010810) +`define CLP_HMAC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R (32'h10010814) +`define CLP_HMAC_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R (32'h10010818) +`define CLP_HMAC_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R (32'h1001081c) +`define CLP_HMAC_REG_INTR_BLOCK_RF_NOTIF_INTR_TRIG_R (32'h10010820) +`define CLP_HMAC_REG_INTR_BLOCK_RF_KEY_MODE_ERROR_INTR_COUNT_R (32'h10010900) +`define CLP_HMAC_REG_INTR_BLOCK_RF_KEY_ZERO_ERROR_INTR_COUNT_R (32'h10010904) +`define CLP_HMAC_REG_INTR_BLOCK_RF_ERROR2_INTR_COUNT_R (32'h10010908) +`define CLP_HMAC_REG_INTR_BLOCK_RF_ERROR3_INTR_COUNT_R (32'h1001090c) +`define CLP_HMAC_REG_INTR_BLOCK_RF_NOTIF_CMD_DONE_INTR_COUNT_R (32'h10010980) +`define CLP_HMAC_REG_INTR_BLOCK_RF_KEY_MODE_ERROR_INTR_COUNT_INCR_R (32'h10010a00) +`define CLP_HMAC_REG_INTR_BLOCK_RF_KEY_ZERO_ERROR_INTR_COUNT_INCR_R (32'h10010a04) +`define CLP_HMAC_REG_INTR_BLOCK_RF_ERROR2_INTR_COUNT_INCR_R (32'h10010a08) +`define CLP_HMAC_REG_INTR_BLOCK_RF_ERROR3_INTR_COUNT_INCR_R (32'h10010a0c) +`define CLP_HMAC_REG_INTR_BLOCK_RF_NOTIF_CMD_DONE_INTR_COUNT_INCR_R (32'h10010a10) +`define CLP_AES_REG_BASE_ADDR (32'h10011000) +`define CLP_AES_REG_KEY_SHARE0_0 (32'h10011004) +`define CLP_AES_REG_KEY_SHARE0_1 (32'h10011008) +`define CLP_AES_REG_KEY_SHARE0_2 (32'h1001100c) +`define CLP_AES_REG_KEY_SHARE0_3 (32'h10011010) +`define CLP_AES_REG_KEY_SHARE0_4 (32'h10011014) +`define CLP_AES_REG_KEY_SHARE0_5 (32'h10011018) +`define CLP_AES_REG_KEY_SHARE0_6 (32'h1001101c) +`define CLP_AES_REG_KEY_SHARE0_7 (32'h10011020) +`define CLP_AES_REG_KEY_SHARE1_0 (32'h10011024) +`define CLP_AES_REG_KEY_SHARE1_1 (32'h10011028) +`define CLP_AES_REG_KEY_SHARE1_2 (32'h1001102c) +`define CLP_AES_REG_KEY_SHARE1_3 (32'h10011030) +`define CLP_AES_REG_KEY_SHARE1_4 (32'h10011034) +`define CLP_AES_REG_KEY_SHARE1_5 (32'h10011038) +`define CLP_AES_REG_KEY_SHARE1_6 (32'h1001103c) +`define CLP_AES_REG_KEY_SHARE1_7 (32'h10011040) +`define CLP_AES_REG_IV_0 (32'h10011044) +`define CLP_AES_REG_IV_1 (32'h10011048) +`define CLP_AES_REG_IV_2 (32'h1001104c) +`define CLP_AES_REG_IV_3 (32'h10011050) +`define CLP_AES_REG_DATA_IN_0 (32'h10011054) +`define CLP_AES_REG_DATA_IN_1 (32'h10011058) +`define CLP_AES_REG_DATA_IN_2 (32'h1001105c) +`define CLP_AES_REG_DATA_IN_3 (32'h10011060) +`define CLP_AES_REG_DATA_OUT_0 (32'h10011064) +`define CLP_AES_REG_DATA_OUT_1 (32'h10011068) +`define CLP_AES_REG_DATA_OUT_2 (32'h1001106c) +`define CLP_AES_REG_DATA_OUT_3 (32'h10011070) +`define CLP_AES_REG_CTRL_SHADOWED (32'h10011074) +`define CLP_AES_REG_CTRL_AUX_SHADOWED (32'h10011078) +`define CLP_AES_REG_CTRL_AUX_REGWEN (32'h1001107c) +`define CLP_AES_REG_TRIGGER (32'h10011080) +`define CLP_AES_REG_STATUS (32'h10011084) +`define CLP_AES_REG_CTRL_GCM_SHADOWED (32'h10011088) +`define CLP_AES_CLP_REG_BASE_ADDR (32'h10011800) +`define CLP_AES_CLP_REG_AES_NAME_0 (32'h10011800) +`define CLP_AES_CLP_REG_AES_NAME_1 (32'h10011804) +`define CLP_AES_CLP_REG_AES_VERSION_0 (32'h10011808) +`define CLP_AES_CLP_REG_AES_VERSION_1 (32'h1001180c) +`define CLP_AES_CLP_REG_ENTROPY_IF_SEED_0 (32'h10011910) +`define CLP_AES_CLP_REG_ENTROPY_IF_SEED_1 (32'h10011914) +`define CLP_AES_CLP_REG_ENTROPY_IF_SEED_2 (32'h10011918) +`define CLP_AES_CLP_REG_ENTROPY_IF_SEED_3 (32'h1001191c) +`define CLP_AES_CLP_REG_ENTROPY_IF_SEED_4 (32'h10011920) +`define CLP_AES_CLP_REG_ENTROPY_IF_SEED_5 (32'h10011924) +`define CLP_AES_CLP_REG_ENTROPY_IF_SEED_6 (32'h10011928) +`define CLP_AES_CLP_REG_ENTROPY_IF_SEED_7 (32'h1001192c) +`define CLP_AES_CLP_REG_ENTROPY_IF_SEED_8 (32'h10011930) +`define CLP_AES_CLP_REG_CTRL0 (32'h10011934) +`define CLP_AES_CLP_REG_AES_KV_RD_KEY_CTRL (32'h10011a00) +`define CLP_AES_CLP_REG_AES_KV_RD_KEY_STATUS (32'h10011a04) +`define CLP_AES_CLP_REG_AES_KV_WR_CTRL (32'h10011a08) +`define CLP_AES_CLP_REG_AES_KV_WR_STATUS (32'h10011a0c) +`define CLP_AES_CLP_REG_INTR_BLOCK_RF_START (32'h10011c00) +`define CLP_AES_CLP_REG_INTR_BLOCK_RF_GLOBAL_INTR_EN_R (32'h10011c00) +`define CLP_AES_CLP_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R (32'h10011c04) +`define CLP_AES_CLP_REG_INTR_BLOCK_RF_NOTIF_INTR_EN_R (32'h10011c08) +`define CLP_AES_CLP_REG_INTR_BLOCK_RF_ERROR_GLOBAL_INTR_R (32'h10011c0c) +`define CLP_AES_CLP_REG_INTR_BLOCK_RF_NOTIF_GLOBAL_INTR_R (32'h10011c10) +`define CLP_AES_CLP_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R (32'h10011c14) +`define CLP_AES_CLP_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R (32'h10011c18) +`define CLP_AES_CLP_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R (32'h10011c1c) +`define CLP_AES_CLP_REG_INTR_BLOCK_RF_NOTIF_INTR_TRIG_R (32'h10011c20) +`define CLP_AES_CLP_REG_INTR_BLOCK_RF_ERROR0_INTR_COUNT_R (32'h10011d00) +`define CLP_AES_CLP_REG_INTR_BLOCK_RF_ERROR1_INTR_COUNT_R (32'h10011d04) +`define CLP_AES_CLP_REG_INTR_BLOCK_RF_ERROR2_INTR_COUNT_R (32'h10011d08) +`define CLP_AES_CLP_REG_INTR_BLOCK_RF_ERROR3_INTR_COUNT_R (32'h10011d0c) +`define CLP_AES_CLP_REG_INTR_BLOCK_RF_NOTIF_CMD_DONE_INTR_COUNT_R (32'h10011d80) +`define CLP_AES_CLP_REG_INTR_BLOCK_RF_ERROR0_INTR_COUNT_INCR_R (32'h10011e00) +`define CLP_AES_CLP_REG_INTR_BLOCK_RF_ERROR1_INTR_COUNT_INCR_R (32'h10011e04) +`define CLP_AES_CLP_REG_INTR_BLOCK_RF_ERROR2_INTR_COUNT_INCR_R (32'h10011e08) +`define CLP_AES_CLP_REG_INTR_BLOCK_RF_ERROR3_INTR_COUNT_INCR_R (32'h10011e0c) +`define CLP_AES_CLP_REG_INTR_BLOCK_RF_NOTIF_CMD_DONE_INTR_COUNT_INCR_R (32'h10011e10) +`define CLP_KV_REG_BASE_ADDR (32'h10018000) +`define CLP_KV_REG_KEY_CTRL_0 (32'h10018000) +`define CLP_KV_REG_KEY_CTRL_1 (32'h10018004) +`define CLP_KV_REG_KEY_CTRL_2 (32'h10018008) +`define CLP_KV_REG_KEY_CTRL_3 (32'h1001800c) +`define CLP_KV_REG_KEY_CTRL_4 (32'h10018010) +`define CLP_KV_REG_KEY_CTRL_5 (32'h10018014) +`define CLP_KV_REG_KEY_CTRL_6 (32'h10018018) +`define CLP_KV_REG_KEY_CTRL_7 (32'h1001801c) +`define CLP_KV_REG_KEY_CTRL_8 (32'h10018020) +`define CLP_KV_REG_KEY_CTRL_9 (32'h10018024) +`define CLP_KV_REG_KEY_CTRL_10 (32'h10018028) +`define CLP_KV_REG_KEY_CTRL_11 (32'h1001802c) +`define CLP_KV_REG_KEY_CTRL_12 (32'h10018030) +`define CLP_KV_REG_KEY_CTRL_13 (32'h10018034) +`define CLP_KV_REG_KEY_CTRL_14 (32'h10018038) +`define CLP_KV_REG_KEY_CTRL_15 (32'h1001803c) +`define CLP_KV_REG_KEY_CTRL_16 (32'h10018040) +`define CLP_KV_REG_KEY_CTRL_17 (32'h10018044) +`define CLP_KV_REG_KEY_CTRL_18 (32'h10018048) +`define CLP_KV_REG_KEY_CTRL_19 (32'h1001804c) +`define CLP_KV_REG_KEY_CTRL_20 (32'h10018050) +`define CLP_KV_REG_KEY_CTRL_21 (32'h10018054) +`define CLP_KV_REG_KEY_CTRL_22 (32'h10018058) +`define CLP_KV_REG_KEY_CTRL_23 (32'h1001805c) +`define CLP_KV_REG_KEY_ENTRY_0_0 (32'h10018600) +`define CLP_KV_REG_KEY_ENTRY_0_1 (32'h10018604) +`define CLP_KV_REG_KEY_ENTRY_0_2 (32'h10018608) +`define CLP_KV_REG_KEY_ENTRY_0_3 (32'h1001860c) +`define CLP_KV_REG_KEY_ENTRY_0_4 (32'h10018610) +`define CLP_KV_REG_KEY_ENTRY_0_5 (32'h10018614) +`define CLP_KV_REG_KEY_ENTRY_0_6 (32'h10018618) +`define CLP_KV_REG_KEY_ENTRY_0_7 (32'h1001861c) +`define CLP_KV_REG_KEY_ENTRY_0_8 (32'h10018620) +`define CLP_KV_REG_KEY_ENTRY_0_9 (32'h10018624) +`define CLP_KV_REG_KEY_ENTRY_0_10 (32'h10018628) +`define CLP_KV_REG_KEY_ENTRY_0_11 (32'h1001862c) +`define CLP_KV_REG_KEY_ENTRY_0_12 (32'h10018630) +`define CLP_KV_REG_KEY_ENTRY_0_13 (32'h10018634) +`define CLP_KV_REG_KEY_ENTRY_0_14 (32'h10018638) +`define CLP_KV_REG_KEY_ENTRY_0_15 (32'h1001863c) +`define CLP_KV_REG_KEY_ENTRY_1_0 (32'h10018640) +`define CLP_KV_REG_KEY_ENTRY_1_1 (32'h10018644) +`define CLP_KV_REG_KEY_ENTRY_1_2 (32'h10018648) +`define CLP_KV_REG_KEY_ENTRY_1_3 (32'h1001864c) +`define CLP_KV_REG_KEY_ENTRY_1_4 (32'h10018650) +`define CLP_KV_REG_KEY_ENTRY_1_5 (32'h10018654) +`define CLP_KV_REG_KEY_ENTRY_1_6 (32'h10018658) +`define CLP_KV_REG_KEY_ENTRY_1_7 (32'h1001865c) +`define CLP_KV_REG_KEY_ENTRY_1_8 (32'h10018660) +`define CLP_KV_REG_KEY_ENTRY_1_9 (32'h10018664) +`define CLP_KV_REG_KEY_ENTRY_1_10 (32'h10018668) +`define CLP_KV_REG_KEY_ENTRY_1_11 (32'h1001866c) +`define CLP_KV_REG_KEY_ENTRY_1_12 (32'h10018670) +`define CLP_KV_REG_KEY_ENTRY_1_13 (32'h10018674) +`define CLP_KV_REG_KEY_ENTRY_1_14 (32'h10018678) +`define CLP_KV_REG_KEY_ENTRY_1_15 (32'h1001867c) +`define CLP_KV_REG_KEY_ENTRY_2_0 (32'h10018680) +`define CLP_KV_REG_KEY_ENTRY_2_1 (32'h10018684) +`define CLP_KV_REG_KEY_ENTRY_2_2 (32'h10018688) +`define CLP_KV_REG_KEY_ENTRY_2_3 (32'h1001868c) +`define CLP_KV_REG_KEY_ENTRY_2_4 (32'h10018690) +`define CLP_KV_REG_KEY_ENTRY_2_5 (32'h10018694) +`define CLP_KV_REG_KEY_ENTRY_2_6 (32'h10018698) +`define CLP_KV_REG_KEY_ENTRY_2_7 (32'h1001869c) +`define CLP_KV_REG_KEY_ENTRY_2_8 (32'h100186a0) +`define CLP_KV_REG_KEY_ENTRY_2_9 (32'h100186a4) +`define CLP_KV_REG_KEY_ENTRY_2_10 (32'h100186a8) +`define CLP_KV_REG_KEY_ENTRY_2_11 (32'h100186ac) +`define CLP_KV_REG_KEY_ENTRY_2_12 (32'h100186b0) +`define CLP_KV_REG_KEY_ENTRY_2_13 (32'h100186b4) +`define CLP_KV_REG_KEY_ENTRY_2_14 (32'h100186b8) +`define CLP_KV_REG_KEY_ENTRY_2_15 (32'h100186bc) +`define CLP_KV_REG_KEY_ENTRY_3_0 (32'h100186c0) +`define CLP_KV_REG_KEY_ENTRY_3_1 (32'h100186c4) +`define CLP_KV_REG_KEY_ENTRY_3_2 (32'h100186c8) +`define CLP_KV_REG_KEY_ENTRY_3_3 (32'h100186cc) +`define CLP_KV_REG_KEY_ENTRY_3_4 (32'h100186d0) +`define CLP_KV_REG_KEY_ENTRY_3_5 (32'h100186d4) +`define CLP_KV_REG_KEY_ENTRY_3_6 (32'h100186d8) +`define CLP_KV_REG_KEY_ENTRY_3_7 (32'h100186dc) +`define CLP_KV_REG_KEY_ENTRY_3_8 (32'h100186e0) +`define CLP_KV_REG_KEY_ENTRY_3_9 (32'h100186e4) +`define CLP_KV_REG_KEY_ENTRY_3_10 (32'h100186e8) +`define CLP_KV_REG_KEY_ENTRY_3_11 (32'h100186ec) +`define CLP_KV_REG_KEY_ENTRY_3_12 (32'h100186f0) +`define CLP_KV_REG_KEY_ENTRY_3_13 (32'h100186f4) +`define CLP_KV_REG_KEY_ENTRY_3_14 (32'h100186f8) +`define CLP_KV_REG_KEY_ENTRY_3_15 (32'h100186fc) +`define CLP_KV_REG_KEY_ENTRY_4_0 (32'h10018700) +`define CLP_KV_REG_KEY_ENTRY_4_1 (32'h10018704) +`define CLP_KV_REG_KEY_ENTRY_4_2 (32'h10018708) +`define CLP_KV_REG_KEY_ENTRY_4_3 (32'h1001870c) +`define CLP_KV_REG_KEY_ENTRY_4_4 (32'h10018710) +`define CLP_KV_REG_KEY_ENTRY_4_5 (32'h10018714) +`define CLP_KV_REG_KEY_ENTRY_4_6 (32'h10018718) +`define CLP_KV_REG_KEY_ENTRY_4_7 (32'h1001871c) +`define CLP_KV_REG_KEY_ENTRY_4_8 (32'h10018720) +`define CLP_KV_REG_KEY_ENTRY_4_9 (32'h10018724) +`define CLP_KV_REG_KEY_ENTRY_4_10 (32'h10018728) +`define CLP_KV_REG_KEY_ENTRY_4_11 (32'h1001872c) +`define CLP_KV_REG_KEY_ENTRY_4_12 (32'h10018730) +`define CLP_KV_REG_KEY_ENTRY_4_13 (32'h10018734) +`define CLP_KV_REG_KEY_ENTRY_4_14 (32'h10018738) +`define CLP_KV_REG_KEY_ENTRY_4_15 (32'h1001873c) +`define CLP_KV_REG_KEY_ENTRY_5_0 (32'h10018740) +`define CLP_KV_REG_KEY_ENTRY_5_1 (32'h10018744) +`define CLP_KV_REG_KEY_ENTRY_5_2 (32'h10018748) +`define CLP_KV_REG_KEY_ENTRY_5_3 (32'h1001874c) +`define CLP_KV_REG_KEY_ENTRY_5_4 (32'h10018750) +`define CLP_KV_REG_KEY_ENTRY_5_5 (32'h10018754) +`define CLP_KV_REG_KEY_ENTRY_5_6 (32'h10018758) +`define CLP_KV_REG_KEY_ENTRY_5_7 (32'h1001875c) +`define CLP_KV_REG_KEY_ENTRY_5_8 (32'h10018760) +`define CLP_KV_REG_KEY_ENTRY_5_9 (32'h10018764) +`define CLP_KV_REG_KEY_ENTRY_5_10 (32'h10018768) +`define CLP_KV_REG_KEY_ENTRY_5_11 (32'h1001876c) +`define CLP_KV_REG_KEY_ENTRY_5_12 (32'h10018770) +`define CLP_KV_REG_KEY_ENTRY_5_13 (32'h10018774) +`define CLP_KV_REG_KEY_ENTRY_5_14 (32'h10018778) +`define CLP_KV_REG_KEY_ENTRY_5_15 (32'h1001877c) +`define CLP_KV_REG_KEY_ENTRY_6_0 (32'h10018780) +`define CLP_KV_REG_KEY_ENTRY_6_1 (32'h10018784) +`define CLP_KV_REG_KEY_ENTRY_6_2 (32'h10018788) +`define CLP_KV_REG_KEY_ENTRY_6_3 (32'h1001878c) +`define CLP_KV_REG_KEY_ENTRY_6_4 (32'h10018790) +`define CLP_KV_REG_KEY_ENTRY_6_5 (32'h10018794) +`define CLP_KV_REG_KEY_ENTRY_6_6 (32'h10018798) +`define CLP_KV_REG_KEY_ENTRY_6_7 (32'h1001879c) +`define CLP_KV_REG_KEY_ENTRY_6_8 (32'h100187a0) +`define CLP_KV_REG_KEY_ENTRY_6_9 (32'h100187a4) +`define CLP_KV_REG_KEY_ENTRY_6_10 (32'h100187a8) +`define CLP_KV_REG_KEY_ENTRY_6_11 (32'h100187ac) +`define CLP_KV_REG_KEY_ENTRY_6_12 (32'h100187b0) +`define CLP_KV_REG_KEY_ENTRY_6_13 (32'h100187b4) +`define CLP_KV_REG_KEY_ENTRY_6_14 (32'h100187b8) +`define CLP_KV_REG_KEY_ENTRY_6_15 (32'h100187bc) +`define CLP_KV_REG_KEY_ENTRY_7_0 (32'h100187c0) +`define CLP_KV_REG_KEY_ENTRY_7_1 (32'h100187c4) +`define CLP_KV_REG_KEY_ENTRY_7_2 (32'h100187c8) +`define CLP_KV_REG_KEY_ENTRY_7_3 (32'h100187cc) +`define CLP_KV_REG_KEY_ENTRY_7_4 (32'h100187d0) +`define CLP_KV_REG_KEY_ENTRY_7_5 (32'h100187d4) +`define CLP_KV_REG_KEY_ENTRY_7_6 (32'h100187d8) +`define CLP_KV_REG_KEY_ENTRY_7_7 (32'h100187dc) +`define CLP_KV_REG_KEY_ENTRY_7_8 (32'h100187e0) +`define CLP_KV_REG_KEY_ENTRY_7_9 (32'h100187e4) +`define CLP_KV_REG_KEY_ENTRY_7_10 (32'h100187e8) +`define CLP_KV_REG_KEY_ENTRY_7_11 (32'h100187ec) +`define CLP_KV_REG_KEY_ENTRY_7_12 (32'h100187f0) +`define CLP_KV_REG_KEY_ENTRY_7_13 (32'h100187f4) +`define CLP_KV_REG_KEY_ENTRY_7_14 (32'h100187f8) +`define CLP_KV_REG_KEY_ENTRY_7_15 (32'h100187fc) +`define CLP_KV_REG_KEY_ENTRY_8_0 (32'h10018800) +`define CLP_KV_REG_KEY_ENTRY_8_1 (32'h10018804) +`define CLP_KV_REG_KEY_ENTRY_8_2 (32'h10018808) +`define CLP_KV_REG_KEY_ENTRY_8_3 (32'h1001880c) +`define CLP_KV_REG_KEY_ENTRY_8_4 (32'h10018810) +`define CLP_KV_REG_KEY_ENTRY_8_5 (32'h10018814) +`define CLP_KV_REG_KEY_ENTRY_8_6 (32'h10018818) +`define CLP_KV_REG_KEY_ENTRY_8_7 (32'h1001881c) +`define CLP_KV_REG_KEY_ENTRY_8_8 (32'h10018820) +`define CLP_KV_REG_KEY_ENTRY_8_9 (32'h10018824) +`define CLP_KV_REG_KEY_ENTRY_8_10 (32'h10018828) +`define CLP_KV_REG_KEY_ENTRY_8_11 (32'h1001882c) +`define CLP_KV_REG_KEY_ENTRY_8_12 (32'h10018830) +`define CLP_KV_REG_KEY_ENTRY_8_13 (32'h10018834) +`define CLP_KV_REG_KEY_ENTRY_8_14 (32'h10018838) +`define CLP_KV_REG_KEY_ENTRY_8_15 (32'h1001883c) +`define CLP_KV_REG_KEY_ENTRY_9_0 (32'h10018840) +`define CLP_KV_REG_KEY_ENTRY_9_1 (32'h10018844) +`define CLP_KV_REG_KEY_ENTRY_9_2 (32'h10018848) +`define CLP_KV_REG_KEY_ENTRY_9_3 (32'h1001884c) +`define CLP_KV_REG_KEY_ENTRY_9_4 (32'h10018850) +`define CLP_KV_REG_KEY_ENTRY_9_5 (32'h10018854) +`define CLP_KV_REG_KEY_ENTRY_9_6 (32'h10018858) +`define CLP_KV_REG_KEY_ENTRY_9_7 (32'h1001885c) +`define CLP_KV_REG_KEY_ENTRY_9_8 (32'h10018860) +`define CLP_KV_REG_KEY_ENTRY_9_9 (32'h10018864) +`define CLP_KV_REG_KEY_ENTRY_9_10 (32'h10018868) +`define CLP_KV_REG_KEY_ENTRY_9_11 (32'h1001886c) +`define CLP_KV_REG_KEY_ENTRY_9_12 (32'h10018870) +`define CLP_KV_REG_KEY_ENTRY_9_13 (32'h10018874) +`define CLP_KV_REG_KEY_ENTRY_9_14 (32'h10018878) +`define CLP_KV_REG_KEY_ENTRY_9_15 (32'h1001887c) +`define CLP_KV_REG_KEY_ENTRY_10_0 (32'h10018880) +`define CLP_KV_REG_KEY_ENTRY_10_1 (32'h10018884) +`define CLP_KV_REG_KEY_ENTRY_10_2 (32'h10018888) +`define CLP_KV_REG_KEY_ENTRY_10_3 (32'h1001888c) +`define CLP_KV_REG_KEY_ENTRY_10_4 (32'h10018890) +`define CLP_KV_REG_KEY_ENTRY_10_5 (32'h10018894) +`define CLP_KV_REG_KEY_ENTRY_10_6 (32'h10018898) +`define CLP_KV_REG_KEY_ENTRY_10_7 (32'h1001889c) +`define CLP_KV_REG_KEY_ENTRY_10_8 (32'h100188a0) +`define CLP_KV_REG_KEY_ENTRY_10_9 (32'h100188a4) +`define CLP_KV_REG_KEY_ENTRY_10_10 (32'h100188a8) +`define CLP_KV_REG_KEY_ENTRY_10_11 (32'h100188ac) +`define CLP_KV_REG_KEY_ENTRY_10_12 (32'h100188b0) +`define CLP_KV_REG_KEY_ENTRY_10_13 (32'h100188b4) +`define CLP_KV_REG_KEY_ENTRY_10_14 (32'h100188b8) +`define CLP_KV_REG_KEY_ENTRY_10_15 (32'h100188bc) +`define CLP_KV_REG_KEY_ENTRY_11_0 (32'h100188c0) +`define CLP_KV_REG_KEY_ENTRY_11_1 (32'h100188c4) +`define CLP_KV_REG_KEY_ENTRY_11_2 (32'h100188c8) +`define CLP_KV_REG_KEY_ENTRY_11_3 (32'h100188cc) +`define CLP_KV_REG_KEY_ENTRY_11_4 (32'h100188d0) +`define CLP_KV_REG_KEY_ENTRY_11_5 (32'h100188d4) +`define CLP_KV_REG_KEY_ENTRY_11_6 (32'h100188d8) +`define CLP_KV_REG_KEY_ENTRY_11_7 (32'h100188dc) +`define CLP_KV_REG_KEY_ENTRY_11_8 (32'h100188e0) +`define CLP_KV_REG_KEY_ENTRY_11_9 (32'h100188e4) +`define CLP_KV_REG_KEY_ENTRY_11_10 (32'h100188e8) +`define CLP_KV_REG_KEY_ENTRY_11_11 (32'h100188ec) +`define CLP_KV_REG_KEY_ENTRY_11_12 (32'h100188f0) +`define CLP_KV_REG_KEY_ENTRY_11_13 (32'h100188f4) +`define CLP_KV_REG_KEY_ENTRY_11_14 (32'h100188f8) +`define CLP_KV_REG_KEY_ENTRY_11_15 (32'h100188fc) +`define CLP_KV_REG_KEY_ENTRY_12_0 (32'h10018900) +`define CLP_KV_REG_KEY_ENTRY_12_1 (32'h10018904) +`define CLP_KV_REG_KEY_ENTRY_12_2 (32'h10018908) +`define CLP_KV_REG_KEY_ENTRY_12_3 (32'h1001890c) +`define CLP_KV_REG_KEY_ENTRY_12_4 (32'h10018910) +`define CLP_KV_REG_KEY_ENTRY_12_5 (32'h10018914) +`define CLP_KV_REG_KEY_ENTRY_12_6 (32'h10018918) +`define CLP_KV_REG_KEY_ENTRY_12_7 (32'h1001891c) +`define CLP_KV_REG_KEY_ENTRY_12_8 (32'h10018920) +`define CLP_KV_REG_KEY_ENTRY_12_9 (32'h10018924) +`define CLP_KV_REG_KEY_ENTRY_12_10 (32'h10018928) +`define CLP_KV_REG_KEY_ENTRY_12_11 (32'h1001892c) +`define CLP_KV_REG_KEY_ENTRY_12_12 (32'h10018930) +`define CLP_KV_REG_KEY_ENTRY_12_13 (32'h10018934) +`define CLP_KV_REG_KEY_ENTRY_12_14 (32'h10018938) +`define CLP_KV_REG_KEY_ENTRY_12_15 (32'h1001893c) +`define CLP_KV_REG_KEY_ENTRY_13_0 (32'h10018940) +`define CLP_KV_REG_KEY_ENTRY_13_1 (32'h10018944) +`define CLP_KV_REG_KEY_ENTRY_13_2 (32'h10018948) +`define CLP_KV_REG_KEY_ENTRY_13_3 (32'h1001894c) +`define CLP_KV_REG_KEY_ENTRY_13_4 (32'h10018950) +`define CLP_KV_REG_KEY_ENTRY_13_5 (32'h10018954) +`define CLP_KV_REG_KEY_ENTRY_13_6 (32'h10018958) +`define CLP_KV_REG_KEY_ENTRY_13_7 (32'h1001895c) +`define CLP_KV_REG_KEY_ENTRY_13_8 (32'h10018960) +`define CLP_KV_REG_KEY_ENTRY_13_9 (32'h10018964) +`define CLP_KV_REG_KEY_ENTRY_13_10 (32'h10018968) +`define CLP_KV_REG_KEY_ENTRY_13_11 (32'h1001896c) +`define CLP_KV_REG_KEY_ENTRY_13_12 (32'h10018970) +`define CLP_KV_REG_KEY_ENTRY_13_13 (32'h10018974) +`define CLP_KV_REG_KEY_ENTRY_13_14 (32'h10018978) +`define CLP_KV_REG_KEY_ENTRY_13_15 (32'h1001897c) +`define CLP_KV_REG_KEY_ENTRY_14_0 (32'h10018980) +`define CLP_KV_REG_KEY_ENTRY_14_1 (32'h10018984) +`define CLP_KV_REG_KEY_ENTRY_14_2 (32'h10018988) +`define CLP_KV_REG_KEY_ENTRY_14_3 (32'h1001898c) +`define CLP_KV_REG_KEY_ENTRY_14_4 (32'h10018990) +`define CLP_KV_REG_KEY_ENTRY_14_5 (32'h10018994) +`define CLP_KV_REG_KEY_ENTRY_14_6 (32'h10018998) +`define CLP_KV_REG_KEY_ENTRY_14_7 (32'h1001899c) +`define CLP_KV_REG_KEY_ENTRY_14_8 (32'h100189a0) +`define CLP_KV_REG_KEY_ENTRY_14_9 (32'h100189a4) +`define CLP_KV_REG_KEY_ENTRY_14_10 (32'h100189a8) +`define CLP_KV_REG_KEY_ENTRY_14_11 (32'h100189ac) +`define CLP_KV_REG_KEY_ENTRY_14_12 (32'h100189b0) +`define CLP_KV_REG_KEY_ENTRY_14_13 (32'h100189b4) +`define CLP_KV_REG_KEY_ENTRY_14_14 (32'h100189b8) +`define CLP_KV_REG_KEY_ENTRY_14_15 (32'h100189bc) +`define CLP_KV_REG_KEY_ENTRY_15_0 (32'h100189c0) +`define CLP_KV_REG_KEY_ENTRY_15_1 (32'h100189c4) +`define CLP_KV_REG_KEY_ENTRY_15_2 (32'h100189c8) +`define CLP_KV_REG_KEY_ENTRY_15_3 (32'h100189cc) +`define CLP_KV_REG_KEY_ENTRY_15_4 (32'h100189d0) +`define CLP_KV_REG_KEY_ENTRY_15_5 (32'h100189d4) +`define CLP_KV_REG_KEY_ENTRY_15_6 (32'h100189d8) +`define CLP_KV_REG_KEY_ENTRY_15_7 (32'h100189dc) +`define CLP_KV_REG_KEY_ENTRY_15_8 (32'h100189e0) +`define CLP_KV_REG_KEY_ENTRY_15_9 (32'h100189e4) +`define CLP_KV_REG_KEY_ENTRY_15_10 (32'h100189e8) +`define CLP_KV_REG_KEY_ENTRY_15_11 (32'h100189ec) +`define CLP_KV_REG_KEY_ENTRY_15_12 (32'h100189f0) +`define CLP_KV_REG_KEY_ENTRY_15_13 (32'h100189f4) +`define CLP_KV_REG_KEY_ENTRY_15_14 (32'h100189f8) +`define CLP_KV_REG_KEY_ENTRY_15_15 (32'h100189fc) +`define CLP_KV_REG_KEY_ENTRY_16_0 (32'h10018a00) +`define CLP_KV_REG_KEY_ENTRY_16_1 (32'h10018a04) +`define CLP_KV_REG_KEY_ENTRY_16_2 (32'h10018a08) +`define CLP_KV_REG_KEY_ENTRY_16_3 (32'h10018a0c) +`define CLP_KV_REG_KEY_ENTRY_16_4 (32'h10018a10) +`define CLP_KV_REG_KEY_ENTRY_16_5 (32'h10018a14) +`define CLP_KV_REG_KEY_ENTRY_16_6 (32'h10018a18) +`define CLP_KV_REG_KEY_ENTRY_16_7 (32'h10018a1c) +`define CLP_KV_REG_KEY_ENTRY_16_8 (32'h10018a20) +`define CLP_KV_REG_KEY_ENTRY_16_9 (32'h10018a24) +`define CLP_KV_REG_KEY_ENTRY_16_10 (32'h10018a28) +`define CLP_KV_REG_KEY_ENTRY_16_11 (32'h10018a2c) +`define CLP_KV_REG_KEY_ENTRY_16_12 (32'h10018a30) +`define CLP_KV_REG_KEY_ENTRY_16_13 (32'h10018a34) +`define CLP_KV_REG_KEY_ENTRY_16_14 (32'h10018a38) +`define CLP_KV_REG_KEY_ENTRY_16_15 (32'h10018a3c) +`define CLP_KV_REG_KEY_ENTRY_17_0 (32'h10018a40) +`define CLP_KV_REG_KEY_ENTRY_17_1 (32'h10018a44) +`define CLP_KV_REG_KEY_ENTRY_17_2 (32'h10018a48) +`define CLP_KV_REG_KEY_ENTRY_17_3 (32'h10018a4c) +`define CLP_KV_REG_KEY_ENTRY_17_4 (32'h10018a50) +`define CLP_KV_REG_KEY_ENTRY_17_5 (32'h10018a54) +`define CLP_KV_REG_KEY_ENTRY_17_6 (32'h10018a58) +`define CLP_KV_REG_KEY_ENTRY_17_7 (32'h10018a5c) +`define CLP_KV_REG_KEY_ENTRY_17_8 (32'h10018a60) +`define CLP_KV_REG_KEY_ENTRY_17_9 (32'h10018a64) +`define CLP_KV_REG_KEY_ENTRY_17_10 (32'h10018a68) +`define CLP_KV_REG_KEY_ENTRY_17_11 (32'h10018a6c) +`define CLP_KV_REG_KEY_ENTRY_17_12 (32'h10018a70) +`define CLP_KV_REG_KEY_ENTRY_17_13 (32'h10018a74) +`define CLP_KV_REG_KEY_ENTRY_17_14 (32'h10018a78) +`define CLP_KV_REG_KEY_ENTRY_17_15 (32'h10018a7c) +`define CLP_KV_REG_KEY_ENTRY_18_0 (32'h10018a80) +`define CLP_KV_REG_KEY_ENTRY_18_1 (32'h10018a84) +`define CLP_KV_REG_KEY_ENTRY_18_2 (32'h10018a88) +`define CLP_KV_REG_KEY_ENTRY_18_3 (32'h10018a8c) +`define CLP_KV_REG_KEY_ENTRY_18_4 (32'h10018a90) +`define CLP_KV_REG_KEY_ENTRY_18_5 (32'h10018a94) +`define CLP_KV_REG_KEY_ENTRY_18_6 (32'h10018a98) +`define CLP_KV_REG_KEY_ENTRY_18_7 (32'h10018a9c) +`define CLP_KV_REG_KEY_ENTRY_18_8 (32'h10018aa0) +`define CLP_KV_REG_KEY_ENTRY_18_9 (32'h10018aa4) +`define CLP_KV_REG_KEY_ENTRY_18_10 (32'h10018aa8) +`define CLP_KV_REG_KEY_ENTRY_18_11 (32'h10018aac) +`define CLP_KV_REG_KEY_ENTRY_18_12 (32'h10018ab0) +`define CLP_KV_REG_KEY_ENTRY_18_13 (32'h10018ab4) +`define CLP_KV_REG_KEY_ENTRY_18_14 (32'h10018ab8) +`define CLP_KV_REG_KEY_ENTRY_18_15 (32'h10018abc) +`define CLP_KV_REG_KEY_ENTRY_19_0 (32'h10018ac0) +`define CLP_KV_REG_KEY_ENTRY_19_1 (32'h10018ac4) +`define CLP_KV_REG_KEY_ENTRY_19_2 (32'h10018ac8) +`define CLP_KV_REG_KEY_ENTRY_19_3 (32'h10018acc) +`define CLP_KV_REG_KEY_ENTRY_19_4 (32'h10018ad0) +`define CLP_KV_REG_KEY_ENTRY_19_5 (32'h10018ad4) +`define CLP_KV_REG_KEY_ENTRY_19_6 (32'h10018ad8) +`define CLP_KV_REG_KEY_ENTRY_19_7 (32'h10018adc) +`define CLP_KV_REG_KEY_ENTRY_19_8 (32'h10018ae0) +`define CLP_KV_REG_KEY_ENTRY_19_9 (32'h10018ae4) +`define CLP_KV_REG_KEY_ENTRY_19_10 (32'h10018ae8) +`define CLP_KV_REG_KEY_ENTRY_19_11 (32'h10018aec) +`define CLP_KV_REG_KEY_ENTRY_19_12 (32'h10018af0) +`define CLP_KV_REG_KEY_ENTRY_19_13 (32'h10018af4) +`define CLP_KV_REG_KEY_ENTRY_19_14 (32'h10018af8) +`define CLP_KV_REG_KEY_ENTRY_19_15 (32'h10018afc) +`define CLP_KV_REG_KEY_ENTRY_20_0 (32'h10018b00) +`define CLP_KV_REG_KEY_ENTRY_20_1 (32'h10018b04) +`define CLP_KV_REG_KEY_ENTRY_20_2 (32'h10018b08) +`define CLP_KV_REG_KEY_ENTRY_20_3 (32'h10018b0c) +`define CLP_KV_REG_KEY_ENTRY_20_4 (32'h10018b10) +`define CLP_KV_REG_KEY_ENTRY_20_5 (32'h10018b14) +`define CLP_KV_REG_KEY_ENTRY_20_6 (32'h10018b18) +`define CLP_KV_REG_KEY_ENTRY_20_7 (32'h10018b1c) +`define CLP_KV_REG_KEY_ENTRY_20_8 (32'h10018b20) +`define CLP_KV_REG_KEY_ENTRY_20_9 (32'h10018b24) +`define CLP_KV_REG_KEY_ENTRY_20_10 (32'h10018b28) +`define CLP_KV_REG_KEY_ENTRY_20_11 (32'h10018b2c) +`define CLP_KV_REG_KEY_ENTRY_20_12 (32'h10018b30) +`define CLP_KV_REG_KEY_ENTRY_20_13 (32'h10018b34) +`define CLP_KV_REG_KEY_ENTRY_20_14 (32'h10018b38) +`define CLP_KV_REG_KEY_ENTRY_20_15 (32'h10018b3c) +`define CLP_KV_REG_KEY_ENTRY_21_0 (32'h10018b40) +`define CLP_KV_REG_KEY_ENTRY_21_1 (32'h10018b44) +`define CLP_KV_REG_KEY_ENTRY_21_2 (32'h10018b48) +`define CLP_KV_REG_KEY_ENTRY_21_3 (32'h10018b4c) +`define CLP_KV_REG_KEY_ENTRY_21_4 (32'h10018b50) +`define CLP_KV_REG_KEY_ENTRY_21_5 (32'h10018b54) +`define CLP_KV_REG_KEY_ENTRY_21_6 (32'h10018b58) +`define CLP_KV_REG_KEY_ENTRY_21_7 (32'h10018b5c) +`define CLP_KV_REG_KEY_ENTRY_21_8 (32'h10018b60) +`define CLP_KV_REG_KEY_ENTRY_21_9 (32'h10018b64) +`define CLP_KV_REG_KEY_ENTRY_21_10 (32'h10018b68) +`define CLP_KV_REG_KEY_ENTRY_21_11 (32'h10018b6c) +`define CLP_KV_REG_KEY_ENTRY_21_12 (32'h10018b70) +`define CLP_KV_REG_KEY_ENTRY_21_13 (32'h10018b74) +`define CLP_KV_REG_KEY_ENTRY_21_14 (32'h10018b78) +`define CLP_KV_REG_KEY_ENTRY_21_15 (32'h10018b7c) +`define CLP_KV_REG_KEY_ENTRY_22_0 (32'h10018b80) +`define CLP_KV_REG_KEY_ENTRY_22_1 (32'h10018b84) +`define CLP_KV_REG_KEY_ENTRY_22_2 (32'h10018b88) +`define CLP_KV_REG_KEY_ENTRY_22_3 (32'h10018b8c) +`define CLP_KV_REG_KEY_ENTRY_22_4 (32'h10018b90) +`define CLP_KV_REG_KEY_ENTRY_22_5 (32'h10018b94) +`define CLP_KV_REG_KEY_ENTRY_22_6 (32'h10018b98) +`define CLP_KV_REG_KEY_ENTRY_22_7 (32'h10018b9c) +`define CLP_KV_REG_KEY_ENTRY_22_8 (32'h10018ba0) +`define CLP_KV_REG_KEY_ENTRY_22_9 (32'h10018ba4) +`define CLP_KV_REG_KEY_ENTRY_22_10 (32'h10018ba8) +`define CLP_KV_REG_KEY_ENTRY_22_11 (32'h10018bac) +`define CLP_KV_REG_KEY_ENTRY_22_12 (32'h10018bb0) +`define CLP_KV_REG_KEY_ENTRY_22_13 (32'h10018bb4) +`define CLP_KV_REG_KEY_ENTRY_22_14 (32'h10018bb8) +`define CLP_KV_REG_KEY_ENTRY_22_15 (32'h10018bbc) +`define CLP_KV_REG_KEY_ENTRY_23_0 (32'h10018bc0) +`define CLP_KV_REG_KEY_ENTRY_23_1 (32'h10018bc4) +`define CLP_KV_REG_KEY_ENTRY_23_2 (32'h10018bc8) +`define CLP_KV_REG_KEY_ENTRY_23_3 (32'h10018bcc) +`define CLP_KV_REG_KEY_ENTRY_23_4 (32'h10018bd0) +`define CLP_KV_REG_KEY_ENTRY_23_5 (32'h10018bd4) +`define CLP_KV_REG_KEY_ENTRY_23_6 (32'h10018bd8) +`define CLP_KV_REG_KEY_ENTRY_23_7 (32'h10018bdc) +`define CLP_KV_REG_KEY_ENTRY_23_8 (32'h10018be0) +`define CLP_KV_REG_KEY_ENTRY_23_9 (32'h10018be4) +`define CLP_KV_REG_KEY_ENTRY_23_10 (32'h10018be8) +`define CLP_KV_REG_KEY_ENTRY_23_11 (32'h10018bec) +`define CLP_KV_REG_KEY_ENTRY_23_12 (32'h10018bf0) +`define CLP_KV_REG_KEY_ENTRY_23_13 (32'h10018bf4) +`define CLP_KV_REG_KEY_ENTRY_23_14 (32'h10018bf8) +`define CLP_KV_REG_KEY_ENTRY_23_15 (32'h10018bfc) +`define CLP_KV_REG_CLEAR_SECRETS (32'h10018c00) +`define CLP_PV_REG_BASE_ADDR (32'h1001a000) +`define CLP_PV_REG_PCR_CTRL_0 (32'h1001a000) +`define CLP_PV_REG_PCR_CTRL_1 (32'h1001a004) +`define CLP_PV_REG_PCR_CTRL_2 (32'h1001a008) +`define CLP_PV_REG_PCR_CTRL_3 (32'h1001a00c) +`define CLP_PV_REG_PCR_CTRL_4 (32'h1001a010) +`define CLP_PV_REG_PCR_CTRL_5 (32'h1001a014) +`define CLP_PV_REG_PCR_CTRL_6 (32'h1001a018) +`define CLP_PV_REG_PCR_CTRL_7 (32'h1001a01c) +`define CLP_PV_REG_PCR_CTRL_8 (32'h1001a020) +`define CLP_PV_REG_PCR_CTRL_9 (32'h1001a024) +`define CLP_PV_REG_PCR_CTRL_10 (32'h1001a028) +`define CLP_PV_REG_PCR_CTRL_11 (32'h1001a02c) +`define CLP_PV_REG_PCR_CTRL_12 (32'h1001a030) +`define CLP_PV_REG_PCR_CTRL_13 (32'h1001a034) +`define CLP_PV_REG_PCR_CTRL_14 (32'h1001a038) +`define CLP_PV_REG_PCR_CTRL_15 (32'h1001a03c) +`define CLP_PV_REG_PCR_CTRL_16 (32'h1001a040) +`define CLP_PV_REG_PCR_CTRL_17 (32'h1001a044) +`define CLP_PV_REG_PCR_CTRL_18 (32'h1001a048) +`define CLP_PV_REG_PCR_CTRL_19 (32'h1001a04c) +`define CLP_PV_REG_PCR_CTRL_20 (32'h1001a050) +`define CLP_PV_REG_PCR_CTRL_21 (32'h1001a054) +`define CLP_PV_REG_PCR_CTRL_22 (32'h1001a058) +`define CLP_PV_REG_PCR_CTRL_23 (32'h1001a05c) +`define CLP_PV_REG_PCR_CTRL_24 (32'h1001a060) +`define CLP_PV_REG_PCR_CTRL_25 (32'h1001a064) +`define CLP_PV_REG_PCR_CTRL_26 (32'h1001a068) +`define CLP_PV_REG_PCR_CTRL_27 (32'h1001a06c) +`define CLP_PV_REG_PCR_CTRL_28 (32'h1001a070) +`define CLP_PV_REG_PCR_CTRL_29 (32'h1001a074) +`define CLP_PV_REG_PCR_CTRL_30 (32'h1001a078) +`define CLP_PV_REG_PCR_CTRL_31 (32'h1001a07c) +`define CLP_PV_REG_PCR_ENTRY_0_0 (32'h1001a600) +`define CLP_PV_REG_PCR_ENTRY_0_1 (32'h1001a604) +`define CLP_PV_REG_PCR_ENTRY_0_2 (32'h1001a608) +`define CLP_PV_REG_PCR_ENTRY_0_3 (32'h1001a60c) +`define CLP_PV_REG_PCR_ENTRY_0_4 (32'h1001a610) +`define CLP_PV_REG_PCR_ENTRY_0_5 (32'h1001a614) +`define CLP_PV_REG_PCR_ENTRY_0_6 (32'h1001a618) +`define CLP_PV_REG_PCR_ENTRY_0_7 (32'h1001a61c) +`define CLP_PV_REG_PCR_ENTRY_0_8 (32'h1001a620) +`define CLP_PV_REG_PCR_ENTRY_0_9 (32'h1001a624) +`define CLP_PV_REG_PCR_ENTRY_0_10 (32'h1001a628) +`define CLP_PV_REG_PCR_ENTRY_0_11 (32'h1001a62c) +`define CLP_PV_REG_PCR_ENTRY_1_0 (32'h1001a630) +`define CLP_PV_REG_PCR_ENTRY_1_1 (32'h1001a634) +`define CLP_PV_REG_PCR_ENTRY_1_2 (32'h1001a638) +`define CLP_PV_REG_PCR_ENTRY_1_3 (32'h1001a63c) +`define CLP_PV_REG_PCR_ENTRY_1_4 (32'h1001a640) +`define CLP_PV_REG_PCR_ENTRY_1_5 (32'h1001a644) +`define CLP_PV_REG_PCR_ENTRY_1_6 (32'h1001a648) +`define CLP_PV_REG_PCR_ENTRY_1_7 (32'h1001a64c) +`define CLP_PV_REG_PCR_ENTRY_1_8 (32'h1001a650) +`define CLP_PV_REG_PCR_ENTRY_1_9 (32'h1001a654) +`define CLP_PV_REG_PCR_ENTRY_1_10 (32'h1001a658) +`define CLP_PV_REG_PCR_ENTRY_1_11 (32'h1001a65c) +`define CLP_PV_REG_PCR_ENTRY_2_0 (32'h1001a660) +`define CLP_PV_REG_PCR_ENTRY_2_1 (32'h1001a664) +`define CLP_PV_REG_PCR_ENTRY_2_2 (32'h1001a668) +`define CLP_PV_REG_PCR_ENTRY_2_3 (32'h1001a66c) +`define CLP_PV_REG_PCR_ENTRY_2_4 (32'h1001a670) +`define CLP_PV_REG_PCR_ENTRY_2_5 (32'h1001a674) +`define CLP_PV_REG_PCR_ENTRY_2_6 (32'h1001a678) +`define CLP_PV_REG_PCR_ENTRY_2_7 (32'h1001a67c) +`define CLP_PV_REG_PCR_ENTRY_2_8 (32'h1001a680) +`define CLP_PV_REG_PCR_ENTRY_2_9 (32'h1001a684) +`define CLP_PV_REG_PCR_ENTRY_2_10 (32'h1001a688) +`define CLP_PV_REG_PCR_ENTRY_2_11 (32'h1001a68c) +`define CLP_PV_REG_PCR_ENTRY_3_0 (32'h1001a690) +`define CLP_PV_REG_PCR_ENTRY_3_1 (32'h1001a694) +`define CLP_PV_REG_PCR_ENTRY_3_2 (32'h1001a698) +`define CLP_PV_REG_PCR_ENTRY_3_3 (32'h1001a69c) +`define CLP_PV_REG_PCR_ENTRY_3_4 (32'h1001a6a0) +`define CLP_PV_REG_PCR_ENTRY_3_5 (32'h1001a6a4) +`define CLP_PV_REG_PCR_ENTRY_3_6 (32'h1001a6a8) +`define CLP_PV_REG_PCR_ENTRY_3_7 (32'h1001a6ac) +`define CLP_PV_REG_PCR_ENTRY_3_8 (32'h1001a6b0) +`define CLP_PV_REG_PCR_ENTRY_3_9 (32'h1001a6b4) +`define CLP_PV_REG_PCR_ENTRY_3_10 (32'h1001a6b8) +`define CLP_PV_REG_PCR_ENTRY_3_11 (32'h1001a6bc) +`define CLP_PV_REG_PCR_ENTRY_4_0 (32'h1001a6c0) +`define CLP_PV_REG_PCR_ENTRY_4_1 (32'h1001a6c4) +`define CLP_PV_REG_PCR_ENTRY_4_2 (32'h1001a6c8) +`define CLP_PV_REG_PCR_ENTRY_4_3 (32'h1001a6cc) +`define CLP_PV_REG_PCR_ENTRY_4_4 (32'h1001a6d0) +`define CLP_PV_REG_PCR_ENTRY_4_5 (32'h1001a6d4) +`define CLP_PV_REG_PCR_ENTRY_4_6 (32'h1001a6d8) +`define CLP_PV_REG_PCR_ENTRY_4_7 (32'h1001a6dc) +`define CLP_PV_REG_PCR_ENTRY_4_8 (32'h1001a6e0) +`define CLP_PV_REG_PCR_ENTRY_4_9 (32'h1001a6e4) +`define CLP_PV_REG_PCR_ENTRY_4_10 (32'h1001a6e8) +`define CLP_PV_REG_PCR_ENTRY_4_11 (32'h1001a6ec) +`define CLP_PV_REG_PCR_ENTRY_5_0 (32'h1001a6f0) +`define CLP_PV_REG_PCR_ENTRY_5_1 (32'h1001a6f4) +`define CLP_PV_REG_PCR_ENTRY_5_2 (32'h1001a6f8) +`define CLP_PV_REG_PCR_ENTRY_5_3 (32'h1001a6fc) +`define CLP_PV_REG_PCR_ENTRY_5_4 (32'h1001a700) +`define CLP_PV_REG_PCR_ENTRY_5_5 (32'h1001a704) +`define CLP_PV_REG_PCR_ENTRY_5_6 (32'h1001a708) +`define CLP_PV_REG_PCR_ENTRY_5_7 (32'h1001a70c) +`define CLP_PV_REG_PCR_ENTRY_5_8 (32'h1001a710) +`define CLP_PV_REG_PCR_ENTRY_5_9 (32'h1001a714) +`define CLP_PV_REG_PCR_ENTRY_5_10 (32'h1001a718) +`define CLP_PV_REG_PCR_ENTRY_5_11 (32'h1001a71c) +`define CLP_PV_REG_PCR_ENTRY_6_0 (32'h1001a720) +`define CLP_PV_REG_PCR_ENTRY_6_1 (32'h1001a724) +`define CLP_PV_REG_PCR_ENTRY_6_2 (32'h1001a728) +`define CLP_PV_REG_PCR_ENTRY_6_3 (32'h1001a72c) +`define CLP_PV_REG_PCR_ENTRY_6_4 (32'h1001a730) +`define CLP_PV_REG_PCR_ENTRY_6_5 (32'h1001a734) +`define CLP_PV_REG_PCR_ENTRY_6_6 (32'h1001a738) +`define CLP_PV_REG_PCR_ENTRY_6_7 (32'h1001a73c) +`define CLP_PV_REG_PCR_ENTRY_6_8 (32'h1001a740) +`define CLP_PV_REG_PCR_ENTRY_6_9 (32'h1001a744) +`define CLP_PV_REG_PCR_ENTRY_6_10 (32'h1001a748) +`define CLP_PV_REG_PCR_ENTRY_6_11 (32'h1001a74c) +`define CLP_PV_REG_PCR_ENTRY_7_0 (32'h1001a750) +`define CLP_PV_REG_PCR_ENTRY_7_1 (32'h1001a754) +`define CLP_PV_REG_PCR_ENTRY_7_2 (32'h1001a758) +`define CLP_PV_REG_PCR_ENTRY_7_3 (32'h1001a75c) +`define CLP_PV_REG_PCR_ENTRY_7_4 (32'h1001a760) +`define CLP_PV_REG_PCR_ENTRY_7_5 (32'h1001a764) +`define CLP_PV_REG_PCR_ENTRY_7_6 (32'h1001a768) +`define CLP_PV_REG_PCR_ENTRY_7_7 (32'h1001a76c) +`define CLP_PV_REG_PCR_ENTRY_7_8 (32'h1001a770) +`define CLP_PV_REG_PCR_ENTRY_7_9 (32'h1001a774) +`define CLP_PV_REG_PCR_ENTRY_7_10 (32'h1001a778) +`define CLP_PV_REG_PCR_ENTRY_7_11 (32'h1001a77c) +`define CLP_PV_REG_PCR_ENTRY_8_0 (32'h1001a780) +`define CLP_PV_REG_PCR_ENTRY_8_1 (32'h1001a784) +`define CLP_PV_REG_PCR_ENTRY_8_2 (32'h1001a788) +`define CLP_PV_REG_PCR_ENTRY_8_3 (32'h1001a78c) +`define CLP_PV_REG_PCR_ENTRY_8_4 (32'h1001a790) +`define CLP_PV_REG_PCR_ENTRY_8_5 (32'h1001a794) +`define CLP_PV_REG_PCR_ENTRY_8_6 (32'h1001a798) +`define CLP_PV_REG_PCR_ENTRY_8_7 (32'h1001a79c) +`define CLP_PV_REG_PCR_ENTRY_8_8 (32'h1001a7a0) +`define CLP_PV_REG_PCR_ENTRY_8_9 (32'h1001a7a4) +`define CLP_PV_REG_PCR_ENTRY_8_10 (32'h1001a7a8) +`define CLP_PV_REG_PCR_ENTRY_8_11 (32'h1001a7ac) +`define CLP_PV_REG_PCR_ENTRY_9_0 (32'h1001a7b0) +`define CLP_PV_REG_PCR_ENTRY_9_1 (32'h1001a7b4) +`define CLP_PV_REG_PCR_ENTRY_9_2 (32'h1001a7b8) +`define CLP_PV_REG_PCR_ENTRY_9_3 (32'h1001a7bc) +`define CLP_PV_REG_PCR_ENTRY_9_4 (32'h1001a7c0) +`define CLP_PV_REG_PCR_ENTRY_9_5 (32'h1001a7c4) +`define CLP_PV_REG_PCR_ENTRY_9_6 (32'h1001a7c8) +`define CLP_PV_REG_PCR_ENTRY_9_7 (32'h1001a7cc) +`define CLP_PV_REG_PCR_ENTRY_9_8 (32'h1001a7d0) +`define CLP_PV_REG_PCR_ENTRY_9_9 (32'h1001a7d4) +`define CLP_PV_REG_PCR_ENTRY_9_10 (32'h1001a7d8) +`define CLP_PV_REG_PCR_ENTRY_9_11 (32'h1001a7dc) +`define CLP_PV_REG_PCR_ENTRY_10_0 (32'h1001a7e0) +`define CLP_PV_REG_PCR_ENTRY_10_1 (32'h1001a7e4) +`define CLP_PV_REG_PCR_ENTRY_10_2 (32'h1001a7e8) +`define CLP_PV_REG_PCR_ENTRY_10_3 (32'h1001a7ec) +`define CLP_PV_REG_PCR_ENTRY_10_4 (32'h1001a7f0) +`define CLP_PV_REG_PCR_ENTRY_10_5 (32'h1001a7f4) +`define CLP_PV_REG_PCR_ENTRY_10_6 (32'h1001a7f8) +`define CLP_PV_REG_PCR_ENTRY_10_7 (32'h1001a7fc) +`define CLP_PV_REG_PCR_ENTRY_10_8 (32'h1001a800) +`define CLP_PV_REG_PCR_ENTRY_10_9 (32'h1001a804) +`define CLP_PV_REG_PCR_ENTRY_10_10 (32'h1001a808) +`define CLP_PV_REG_PCR_ENTRY_10_11 (32'h1001a80c) +`define CLP_PV_REG_PCR_ENTRY_11_0 (32'h1001a810) +`define CLP_PV_REG_PCR_ENTRY_11_1 (32'h1001a814) +`define CLP_PV_REG_PCR_ENTRY_11_2 (32'h1001a818) +`define CLP_PV_REG_PCR_ENTRY_11_3 (32'h1001a81c) +`define CLP_PV_REG_PCR_ENTRY_11_4 (32'h1001a820) +`define CLP_PV_REG_PCR_ENTRY_11_5 (32'h1001a824) +`define CLP_PV_REG_PCR_ENTRY_11_6 (32'h1001a828) +`define CLP_PV_REG_PCR_ENTRY_11_7 (32'h1001a82c) +`define CLP_PV_REG_PCR_ENTRY_11_8 (32'h1001a830) +`define CLP_PV_REG_PCR_ENTRY_11_9 (32'h1001a834) +`define CLP_PV_REG_PCR_ENTRY_11_10 (32'h1001a838) +`define CLP_PV_REG_PCR_ENTRY_11_11 (32'h1001a83c) +`define CLP_PV_REG_PCR_ENTRY_12_0 (32'h1001a840) +`define CLP_PV_REG_PCR_ENTRY_12_1 (32'h1001a844) +`define CLP_PV_REG_PCR_ENTRY_12_2 (32'h1001a848) +`define CLP_PV_REG_PCR_ENTRY_12_3 (32'h1001a84c) +`define CLP_PV_REG_PCR_ENTRY_12_4 (32'h1001a850) +`define CLP_PV_REG_PCR_ENTRY_12_5 (32'h1001a854) +`define CLP_PV_REG_PCR_ENTRY_12_6 (32'h1001a858) +`define CLP_PV_REG_PCR_ENTRY_12_7 (32'h1001a85c) +`define CLP_PV_REG_PCR_ENTRY_12_8 (32'h1001a860) +`define CLP_PV_REG_PCR_ENTRY_12_9 (32'h1001a864) +`define CLP_PV_REG_PCR_ENTRY_12_10 (32'h1001a868) +`define CLP_PV_REG_PCR_ENTRY_12_11 (32'h1001a86c) +`define CLP_PV_REG_PCR_ENTRY_13_0 (32'h1001a870) +`define CLP_PV_REG_PCR_ENTRY_13_1 (32'h1001a874) +`define CLP_PV_REG_PCR_ENTRY_13_2 (32'h1001a878) +`define CLP_PV_REG_PCR_ENTRY_13_3 (32'h1001a87c) +`define CLP_PV_REG_PCR_ENTRY_13_4 (32'h1001a880) +`define CLP_PV_REG_PCR_ENTRY_13_5 (32'h1001a884) +`define CLP_PV_REG_PCR_ENTRY_13_6 (32'h1001a888) +`define CLP_PV_REG_PCR_ENTRY_13_7 (32'h1001a88c) +`define CLP_PV_REG_PCR_ENTRY_13_8 (32'h1001a890) +`define CLP_PV_REG_PCR_ENTRY_13_9 (32'h1001a894) +`define CLP_PV_REG_PCR_ENTRY_13_10 (32'h1001a898) +`define CLP_PV_REG_PCR_ENTRY_13_11 (32'h1001a89c) +`define CLP_PV_REG_PCR_ENTRY_14_0 (32'h1001a8a0) +`define CLP_PV_REG_PCR_ENTRY_14_1 (32'h1001a8a4) +`define CLP_PV_REG_PCR_ENTRY_14_2 (32'h1001a8a8) +`define CLP_PV_REG_PCR_ENTRY_14_3 (32'h1001a8ac) +`define CLP_PV_REG_PCR_ENTRY_14_4 (32'h1001a8b0) +`define CLP_PV_REG_PCR_ENTRY_14_5 (32'h1001a8b4) +`define CLP_PV_REG_PCR_ENTRY_14_6 (32'h1001a8b8) +`define CLP_PV_REG_PCR_ENTRY_14_7 (32'h1001a8bc) +`define CLP_PV_REG_PCR_ENTRY_14_8 (32'h1001a8c0) +`define CLP_PV_REG_PCR_ENTRY_14_9 (32'h1001a8c4) +`define CLP_PV_REG_PCR_ENTRY_14_10 (32'h1001a8c8) +`define CLP_PV_REG_PCR_ENTRY_14_11 (32'h1001a8cc) +`define CLP_PV_REG_PCR_ENTRY_15_0 (32'h1001a8d0) +`define CLP_PV_REG_PCR_ENTRY_15_1 (32'h1001a8d4) +`define CLP_PV_REG_PCR_ENTRY_15_2 (32'h1001a8d8) +`define CLP_PV_REG_PCR_ENTRY_15_3 (32'h1001a8dc) +`define CLP_PV_REG_PCR_ENTRY_15_4 (32'h1001a8e0) +`define CLP_PV_REG_PCR_ENTRY_15_5 (32'h1001a8e4) +`define CLP_PV_REG_PCR_ENTRY_15_6 (32'h1001a8e8) +`define CLP_PV_REG_PCR_ENTRY_15_7 (32'h1001a8ec) +`define CLP_PV_REG_PCR_ENTRY_15_8 (32'h1001a8f0) +`define CLP_PV_REG_PCR_ENTRY_15_9 (32'h1001a8f4) +`define CLP_PV_REG_PCR_ENTRY_15_10 (32'h1001a8f8) +`define CLP_PV_REG_PCR_ENTRY_15_11 (32'h1001a8fc) +`define CLP_PV_REG_PCR_ENTRY_16_0 (32'h1001a900) +`define CLP_PV_REG_PCR_ENTRY_16_1 (32'h1001a904) +`define CLP_PV_REG_PCR_ENTRY_16_2 (32'h1001a908) +`define CLP_PV_REG_PCR_ENTRY_16_3 (32'h1001a90c) +`define CLP_PV_REG_PCR_ENTRY_16_4 (32'h1001a910) +`define CLP_PV_REG_PCR_ENTRY_16_5 (32'h1001a914) +`define CLP_PV_REG_PCR_ENTRY_16_6 (32'h1001a918) +`define CLP_PV_REG_PCR_ENTRY_16_7 (32'h1001a91c) +`define CLP_PV_REG_PCR_ENTRY_16_8 (32'h1001a920) +`define CLP_PV_REG_PCR_ENTRY_16_9 (32'h1001a924) +`define CLP_PV_REG_PCR_ENTRY_16_10 (32'h1001a928) +`define CLP_PV_REG_PCR_ENTRY_16_11 (32'h1001a92c) +`define CLP_PV_REG_PCR_ENTRY_17_0 (32'h1001a930) +`define CLP_PV_REG_PCR_ENTRY_17_1 (32'h1001a934) +`define CLP_PV_REG_PCR_ENTRY_17_2 (32'h1001a938) +`define CLP_PV_REG_PCR_ENTRY_17_3 (32'h1001a93c) +`define CLP_PV_REG_PCR_ENTRY_17_4 (32'h1001a940) +`define CLP_PV_REG_PCR_ENTRY_17_5 (32'h1001a944) +`define CLP_PV_REG_PCR_ENTRY_17_6 (32'h1001a948) +`define CLP_PV_REG_PCR_ENTRY_17_7 (32'h1001a94c) +`define CLP_PV_REG_PCR_ENTRY_17_8 (32'h1001a950) +`define CLP_PV_REG_PCR_ENTRY_17_9 (32'h1001a954) +`define CLP_PV_REG_PCR_ENTRY_17_10 (32'h1001a958) +`define CLP_PV_REG_PCR_ENTRY_17_11 (32'h1001a95c) +`define CLP_PV_REG_PCR_ENTRY_18_0 (32'h1001a960) +`define CLP_PV_REG_PCR_ENTRY_18_1 (32'h1001a964) +`define CLP_PV_REG_PCR_ENTRY_18_2 (32'h1001a968) +`define CLP_PV_REG_PCR_ENTRY_18_3 (32'h1001a96c) +`define CLP_PV_REG_PCR_ENTRY_18_4 (32'h1001a970) +`define CLP_PV_REG_PCR_ENTRY_18_5 (32'h1001a974) +`define CLP_PV_REG_PCR_ENTRY_18_6 (32'h1001a978) +`define CLP_PV_REG_PCR_ENTRY_18_7 (32'h1001a97c) +`define CLP_PV_REG_PCR_ENTRY_18_8 (32'h1001a980) +`define CLP_PV_REG_PCR_ENTRY_18_9 (32'h1001a984) +`define CLP_PV_REG_PCR_ENTRY_18_10 (32'h1001a988) +`define CLP_PV_REG_PCR_ENTRY_18_11 (32'h1001a98c) +`define CLP_PV_REG_PCR_ENTRY_19_0 (32'h1001a990) +`define CLP_PV_REG_PCR_ENTRY_19_1 (32'h1001a994) +`define CLP_PV_REG_PCR_ENTRY_19_2 (32'h1001a998) +`define CLP_PV_REG_PCR_ENTRY_19_3 (32'h1001a99c) +`define CLP_PV_REG_PCR_ENTRY_19_4 (32'h1001a9a0) +`define CLP_PV_REG_PCR_ENTRY_19_5 (32'h1001a9a4) +`define CLP_PV_REG_PCR_ENTRY_19_6 (32'h1001a9a8) +`define CLP_PV_REG_PCR_ENTRY_19_7 (32'h1001a9ac) +`define CLP_PV_REG_PCR_ENTRY_19_8 (32'h1001a9b0) +`define CLP_PV_REG_PCR_ENTRY_19_9 (32'h1001a9b4) +`define CLP_PV_REG_PCR_ENTRY_19_10 (32'h1001a9b8) +`define CLP_PV_REG_PCR_ENTRY_19_11 (32'h1001a9bc) +`define CLP_PV_REG_PCR_ENTRY_20_0 (32'h1001a9c0) +`define CLP_PV_REG_PCR_ENTRY_20_1 (32'h1001a9c4) +`define CLP_PV_REG_PCR_ENTRY_20_2 (32'h1001a9c8) +`define CLP_PV_REG_PCR_ENTRY_20_3 (32'h1001a9cc) +`define CLP_PV_REG_PCR_ENTRY_20_4 (32'h1001a9d0) +`define CLP_PV_REG_PCR_ENTRY_20_5 (32'h1001a9d4) +`define CLP_PV_REG_PCR_ENTRY_20_6 (32'h1001a9d8) +`define CLP_PV_REG_PCR_ENTRY_20_7 (32'h1001a9dc) +`define CLP_PV_REG_PCR_ENTRY_20_8 (32'h1001a9e0) +`define CLP_PV_REG_PCR_ENTRY_20_9 (32'h1001a9e4) +`define CLP_PV_REG_PCR_ENTRY_20_10 (32'h1001a9e8) +`define CLP_PV_REG_PCR_ENTRY_20_11 (32'h1001a9ec) +`define CLP_PV_REG_PCR_ENTRY_21_0 (32'h1001a9f0) +`define CLP_PV_REG_PCR_ENTRY_21_1 (32'h1001a9f4) +`define CLP_PV_REG_PCR_ENTRY_21_2 (32'h1001a9f8) +`define CLP_PV_REG_PCR_ENTRY_21_3 (32'h1001a9fc) +`define CLP_PV_REG_PCR_ENTRY_21_4 (32'h1001aa00) +`define CLP_PV_REG_PCR_ENTRY_21_5 (32'h1001aa04) +`define CLP_PV_REG_PCR_ENTRY_21_6 (32'h1001aa08) +`define CLP_PV_REG_PCR_ENTRY_21_7 (32'h1001aa0c) +`define CLP_PV_REG_PCR_ENTRY_21_8 (32'h1001aa10) +`define CLP_PV_REG_PCR_ENTRY_21_9 (32'h1001aa14) +`define CLP_PV_REG_PCR_ENTRY_21_10 (32'h1001aa18) +`define CLP_PV_REG_PCR_ENTRY_21_11 (32'h1001aa1c) +`define CLP_PV_REG_PCR_ENTRY_22_0 (32'h1001aa20) +`define CLP_PV_REG_PCR_ENTRY_22_1 (32'h1001aa24) +`define CLP_PV_REG_PCR_ENTRY_22_2 (32'h1001aa28) +`define CLP_PV_REG_PCR_ENTRY_22_3 (32'h1001aa2c) +`define CLP_PV_REG_PCR_ENTRY_22_4 (32'h1001aa30) +`define CLP_PV_REG_PCR_ENTRY_22_5 (32'h1001aa34) +`define CLP_PV_REG_PCR_ENTRY_22_6 (32'h1001aa38) +`define CLP_PV_REG_PCR_ENTRY_22_7 (32'h1001aa3c) +`define CLP_PV_REG_PCR_ENTRY_22_8 (32'h1001aa40) +`define CLP_PV_REG_PCR_ENTRY_22_9 (32'h1001aa44) +`define CLP_PV_REG_PCR_ENTRY_22_10 (32'h1001aa48) +`define CLP_PV_REG_PCR_ENTRY_22_11 (32'h1001aa4c) +`define CLP_PV_REG_PCR_ENTRY_23_0 (32'h1001aa50) +`define CLP_PV_REG_PCR_ENTRY_23_1 (32'h1001aa54) +`define CLP_PV_REG_PCR_ENTRY_23_2 (32'h1001aa58) +`define CLP_PV_REG_PCR_ENTRY_23_3 (32'h1001aa5c) +`define CLP_PV_REG_PCR_ENTRY_23_4 (32'h1001aa60) +`define CLP_PV_REG_PCR_ENTRY_23_5 (32'h1001aa64) +`define CLP_PV_REG_PCR_ENTRY_23_6 (32'h1001aa68) +`define CLP_PV_REG_PCR_ENTRY_23_7 (32'h1001aa6c) +`define CLP_PV_REG_PCR_ENTRY_23_8 (32'h1001aa70) +`define CLP_PV_REG_PCR_ENTRY_23_9 (32'h1001aa74) +`define CLP_PV_REG_PCR_ENTRY_23_10 (32'h1001aa78) +`define CLP_PV_REG_PCR_ENTRY_23_11 (32'h1001aa7c) +`define CLP_PV_REG_PCR_ENTRY_24_0 (32'h1001aa80) +`define CLP_PV_REG_PCR_ENTRY_24_1 (32'h1001aa84) +`define CLP_PV_REG_PCR_ENTRY_24_2 (32'h1001aa88) +`define CLP_PV_REG_PCR_ENTRY_24_3 (32'h1001aa8c) +`define CLP_PV_REG_PCR_ENTRY_24_4 (32'h1001aa90) +`define CLP_PV_REG_PCR_ENTRY_24_5 (32'h1001aa94) +`define CLP_PV_REG_PCR_ENTRY_24_6 (32'h1001aa98) +`define CLP_PV_REG_PCR_ENTRY_24_7 (32'h1001aa9c) +`define CLP_PV_REG_PCR_ENTRY_24_8 (32'h1001aaa0) +`define CLP_PV_REG_PCR_ENTRY_24_9 (32'h1001aaa4) +`define CLP_PV_REG_PCR_ENTRY_24_10 (32'h1001aaa8) +`define CLP_PV_REG_PCR_ENTRY_24_11 (32'h1001aaac) +`define CLP_PV_REG_PCR_ENTRY_25_0 (32'h1001aab0) +`define CLP_PV_REG_PCR_ENTRY_25_1 (32'h1001aab4) +`define CLP_PV_REG_PCR_ENTRY_25_2 (32'h1001aab8) +`define CLP_PV_REG_PCR_ENTRY_25_3 (32'h1001aabc) +`define CLP_PV_REG_PCR_ENTRY_25_4 (32'h1001aac0) +`define CLP_PV_REG_PCR_ENTRY_25_5 (32'h1001aac4) +`define CLP_PV_REG_PCR_ENTRY_25_6 (32'h1001aac8) +`define CLP_PV_REG_PCR_ENTRY_25_7 (32'h1001aacc) +`define CLP_PV_REG_PCR_ENTRY_25_8 (32'h1001aad0) +`define CLP_PV_REG_PCR_ENTRY_25_9 (32'h1001aad4) +`define CLP_PV_REG_PCR_ENTRY_25_10 (32'h1001aad8) +`define CLP_PV_REG_PCR_ENTRY_25_11 (32'h1001aadc) +`define CLP_PV_REG_PCR_ENTRY_26_0 (32'h1001aae0) +`define CLP_PV_REG_PCR_ENTRY_26_1 (32'h1001aae4) +`define CLP_PV_REG_PCR_ENTRY_26_2 (32'h1001aae8) +`define CLP_PV_REG_PCR_ENTRY_26_3 (32'h1001aaec) +`define CLP_PV_REG_PCR_ENTRY_26_4 (32'h1001aaf0) +`define CLP_PV_REG_PCR_ENTRY_26_5 (32'h1001aaf4) +`define CLP_PV_REG_PCR_ENTRY_26_6 (32'h1001aaf8) +`define CLP_PV_REG_PCR_ENTRY_26_7 (32'h1001aafc) +`define CLP_PV_REG_PCR_ENTRY_26_8 (32'h1001ab00) +`define CLP_PV_REG_PCR_ENTRY_26_9 (32'h1001ab04) +`define CLP_PV_REG_PCR_ENTRY_26_10 (32'h1001ab08) +`define CLP_PV_REG_PCR_ENTRY_26_11 (32'h1001ab0c) +`define CLP_PV_REG_PCR_ENTRY_27_0 (32'h1001ab10) +`define CLP_PV_REG_PCR_ENTRY_27_1 (32'h1001ab14) +`define CLP_PV_REG_PCR_ENTRY_27_2 (32'h1001ab18) +`define CLP_PV_REG_PCR_ENTRY_27_3 (32'h1001ab1c) +`define CLP_PV_REG_PCR_ENTRY_27_4 (32'h1001ab20) +`define CLP_PV_REG_PCR_ENTRY_27_5 (32'h1001ab24) +`define CLP_PV_REG_PCR_ENTRY_27_6 (32'h1001ab28) +`define CLP_PV_REG_PCR_ENTRY_27_7 (32'h1001ab2c) +`define CLP_PV_REG_PCR_ENTRY_27_8 (32'h1001ab30) +`define CLP_PV_REG_PCR_ENTRY_27_9 (32'h1001ab34) +`define CLP_PV_REG_PCR_ENTRY_27_10 (32'h1001ab38) +`define CLP_PV_REG_PCR_ENTRY_27_11 (32'h1001ab3c) +`define CLP_PV_REG_PCR_ENTRY_28_0 (32'h1001ab40) +`define CLP_PV_REG_PCR_ENTRY_28_1 (32'h1001ab44) +`define CLP_PV_REG_PCR_ENTRY_28_2 (32'h1001ab48) +`define CLP_PV_REG_PCR_ENTRY_28_3 (32'h1001ab4c) +`define CLP_PV_REG_PCR_ENTRY_28_4 (32'h1001ab50) +`define CLP_PV_REG_PCR_ENTRY_28_5 (32'h1001ab54) +`define CLP_PV_REG_PCR_ENTRY_28_6 (32'h1001ab58) +`define CLP_PV_REG_PCR_ENTRY_28_7 (32'h1001ab5c) +`define CLP_PV_REG_PCR_ENTRY_28_8 (32'h1001ab60) +`define CLP_PV_REG_PCR_ENTRY_28_9 (32'h1001ab64) +`define CLP_PV_REG_PCR_ENTRY_28_10 (32'h1001ab68) +`define CLP_PV_REG_PCR_ENTRY_28_11 (32'h1001ab6c) +`define CLP_PV_REG_PCR_ENTRY_29_0 (32'h1001ab70) +`define CLP_PV_REG_PCR_ENTRY_29_1 (32'h1001ab74) +`define CLP_PV_REG_PCR_ENTRY_29_2 (32'h1001ab78) +`define CLP_PV_REG_PCR_ENTRY_29_3 (32'h1001ab7c) +`define CLP_PV_REG_PCR_ENTRY_29_4 (32'h1001ab80) +`define CLP_PV_REG_PCR_ENTRY_29_5 (32'h1001ab84) +`define CLP_PV_REG_PCR_ENTRY_29_6 (32'h1001ab88) +`define CLP_PV_REG_PCR_ENTRY_29_7 (32'h1001ab8c) +`define CLP_PV_REG_PCR_ENTRY_29_8 (32'h1001ab90) +`define CLP_PV_REG_PCR_ENTRY_29_9 (32'h1001ab94) +`define CLP_PV_REG_PCR_ENTRY_29_10 (32'h1001ab98) +`define CLP_PV_REG_PCR_ENTRY_29_11 (32'h1001ab9c) +`define CLP_PV_REG_PCR_ENTRY_30_0 (32'h1001aba0) +`define CLP_PV_REG_PCR_ENTRY_30_1 (32'h1001aba4) +`define CLP_PV_REG_PCR_ENTRY_30_2 (32'h1001aba8) +`define CLP_PV_REG_PCR_ENTRY_30_3 (32'h1001abac) +`define CLP_PV_REG_PCR_ENTRY_30_4 (32'h1001abb0) +`define CLP_PV_REG_PCR_ENTRY_30_5 (32'h1001abb4) +`define CLP_PV_REG_PCR_ENTRY_30_6 (32'h1001abb8) +`define CLP_PV_REG_PCR_ENTRY_30_7 (32'h1001abbc) +`define CLP_PV_REG_PCR_ENTRY_30_8 (32'h1001abc0) +`define CLP_PV_REG_PCR_ENTRY_30_9 (32'h1001abc4) +`define CLP_PV_REG_PCR_ENTRY_30_10 (32'h1001abc8) +`define CLP_PV_REG_PCR_ENTRY_30_11 (32'h1001abcc) +`define CLP_PV_REG_PCR_ENTRY_31_0 (32'h1001abd0) +`define CLP_PV_REG_PCR_ENTRY_31_1 (32'h1001abd4) +`define CLP_PV_REG_PCR_ENTRY_31_2 (32'h1001abd8) +`define CLP_PV_REG_PCR_ENTRY_31_3 (32'h1001abdc) +`define CLP_PV_REG_PCR_ENTRY_31_4 (32'h1001abe0) +`define CLP_PV_REG_PCR_ENTRY_31_5 (32'h1001abe4) +`define CLP_PV_REG_PCR_ENTRY_31_6 (32'h1001abe8) +`define CLP_PV_REG_PCR_ENTRY_31_7 (32'h1001abec) +`define CLP_PV_REG_PCR_ENTRY_31_8 (32'h1001abf0) +`define CLP_PV_REG_PCR_ENTRY_31_9 (32'h1001abf4) +`define CLP_PV_REG_PCR_ENTRY_31_10 (32'h1001abf8) +`define CLP_PV_REG_PCR_ENTRY_31_11 (32'h1001abfc) +`define CLP_DV_REG_BASE_ADDR (32'h1001c000) +`define CLP_DV_REG_STICKYDATAVAULTCTRL_0 (32'h1001c000) +`define CLP_DV_REG_STICKYDATAVAULTCTRL_1 (32'h1001c004) +`define CLP_DV_REG_STICKYDATAVAULTCTRL_2 (32'h1001c008) +`define CLP_DV_REG_STICKYDATAVAULTCTRL_3 (32'h1001c00c) +`define CLP_DV_REG_STICKYDATAVAULTCTRL_4 (32'h1001c010) +`define CLP_DV_REG_STICKYDATAVAULTCTRL_5 (32'h1001c014) +`define CLP_DV_REG_STICKYDATAVAULTCTRL_6 (32'h1001c018) +`define CLP_DV_REG_STICKYDATAVAULTCTRL_7 (32'h1001c01c) +`define CLP_DV_REG_STICKYDATAVAULTCTRL_8 (32'h1001c020) +`define CLP_DV_REG_STICKYDATAVAULTCTRL_9 (32'h1001c024) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_0_0 (32'h1001c028) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_0_1 (32'h1001c02c) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_0_2 (32'h1001c030) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_0_3 (32'h1001c034) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_0_4 (32'h1001c038) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_0_5 (32'h1001c03c) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_0_6 (32'h1001c040) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_0_7 (32'h1001c044) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_0_8 (32'h1001c048) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_0_9 (32'h1001c04c) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_0_10 (32'h1001c050) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_0_11 (32'h1001c054) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_1_0 (32'h1001c058) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_1_1 (32'h1001c05c) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_1_2 (32'h1001c060) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_1_3 (32'h1001c064) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_1_4 (32'h1001c068) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_1_5 (32'h1001c06c) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_1_6 (32'h1001c070) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_1_7 (32'h1001c074) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_1_8 (32'h1001c078) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_1_9 (32'h1001c07c) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_1_10 (32'h1001c080) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_1_11 (32'h1001c084) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_2_0 (32'h1001c088) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_2_1 (32'h1001c08c) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_2_2 (32'h1001c090) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_2_3 (32'h1001c094) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_2_4 (32'h1001c098) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_2_5 (32'h1001c09c) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_2_6 (32'h1001c0a0) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_2_7 (32'h1001c0a4) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_2_8 (32'h1001c0a8) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_2_9 (32'h1001c0ac) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_2_10 (32'h1001c0b0) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_2_11 (32'h1001c0b4) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_3_0 (32'h1001c0b8) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_3_1 (32'h1001c0bc) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_3_2 (32'h1001c0c0) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_3_3 (32'h1001c0c4) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_3_4 (32'h1001c0c8) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_3_5 (32'h1001c0cc) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_3_6 (32'h1001c0d0) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_3_7 (32'h1001c0d4) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_3_8 (32'h1001c0d8) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_3_9 (32'h1001c0dc) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_3_10 (32'h1001c0e0) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_3_11 (32'h1001c0e4) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_4_0 (32'h1001c0e8) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_4_1 (32'h1001c0ec) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_4_2 (32'h1001c0f0) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_4_3 (32'h1001c0f4) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_4_4 (32'h1001c0f8) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_4_5 (32'h1001c0fc) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_4_6 (32'h1001c100) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_4_7 (32'h1001c104) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_4_8 (32'h1001c108) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_4_9 (32'h1001c10c) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_4_10 (32'h1001c110) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_4_11 (32'h1001c114) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_5_0 (32'h1001c118) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_5_1 (32'h1001c11c) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_5_2 (32'h1001c120) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_5_3 (32'h1001c124) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_5_4 (32'h1001c128) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_5_5 (32'h1001c12c) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_5_6 (32'h1001c130) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_5_7 (32'h1001c134) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_5_8 (32'h1001c138) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_5_9 (32'h1001c13c) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_5_10 (32'h1001c140) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_5_11 (32'h1001c144) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_6_0 (32'h1001c148) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_6_1 (32'h1001c14c) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_6_2 (32'h1001c150) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_6_3 (32'h1001c154) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_6_4 (32'h1001c158) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_6_5 (32'h1001c15c) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_6_6 (32'h1001c160) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_6_7 (32'h1001c164) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_6_8 (32'h1001c168) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_6_9 (32'h1001c16c) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_6_10 (32'h1001c170) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_6_11 (32'h1001c174) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_7_0 (32'h1001c178) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_7_1 (32'h1001c17c) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_7_2 (32'h1001c180) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_7_3 (32'h1001c184) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_7_4 (32'h1001c188) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_7_5 (32'h1001c18c) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_7_6 (32'h1001c190) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_7_7 (32'h1001c194) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_7_8 (32'h1001c198) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_7_9 (32'h1001c19c) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_7_10 (32'h1001c1a0) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_7_11 (32'h1001c1a4) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_8_0 (32'h1001c1a8) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_8_1 (32'h1001c1ac) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_8_2 (32'h1001c1b0) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_8_3 (32'h1001c1b4) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_8_4 (32'h1001c1b8) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_8_5 (32'h1001c1bc) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_8_6 (32'h1001c1c0) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_8_7 (32'h1001c1c4) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_8_8 (32'h1001c1c8) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_8_9 (32'h1001c1cc) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_8_10 (32'h1001c1d0) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_8_11 (32'h1001c1d4) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_9_0 (32'h1001c1d8) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_9_1 (32'h1001c1dc) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_9_2 (32'h1001c1e0) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_9_3 (32'h1001c1e4) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_9_4 (32'h1001c1e8) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_9_5 (32'h1001c1ec) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_9_6 (32'h1001c1f0) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_9_7 (32'h1001c1f4) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_9_8 (32'h1001c1f8) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_9_9 (32'h1001c1fc) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_9_10 (32'h1001c200) +`define CLP_DV_REG_STICKY_DATA_VAULT_ENTRY_9_11 (32'h1001c204) +`define CLP_DV_REG_DATAVAULTCTRL_0 (32'h1001c208) +`define CLP_DV_REG_DATAVAULTCTRL_1 (32'h1001c20c) +`define CLP_DV_REG_DATAVAULTCTRL_2 (32'h1001c210) +`define CLP_DV_REG_DATAVAULTCTRL_3 (32'h1001c214) +`define CLP_DV_REG_DATAVAULTCTRL_4 (32'h1001c218) +`define CLP_DV_REG_DATAVAULTCTRL_5 (32'h1001c21c) +`define CLP_DV_REG_DATAVAULTCTRL_6 (32'h1001c220) +`define CLP_DV_REG_DATAVAULTCTRL_7 (32'h1001c224) +`define CLP_DV_REG_DATAVAULTCTRL_8 (32'h1001c228) +`define CLP_DV_REG_DATAVAULTCTRL_9 (32'h1001c22c) +`define CLP_DV_REG_DATA_VAULT_ENTRY_0_0 (32'h1001c230) +`define CLP_DV_REG_DATA_VAULT_ENTRY_0_1 (32'h1001c234) +`define CLP_DV_REG_DATA_VAULT_ENTRY_0_2 (32'h1001c238) +`define CLP_DV_REG_DATA_VAULT_ENTRY_0_3 (32'h1001c23c) +`define CLP_DV_REG_DATA_VAULT_ENTRY_0_4 (32'h1001c240) +`define CLP_DV_REG_DATA_VAULT_ENTRY_0_5 (32'h1001c244) +`define CLP_DV_REG_DATA_VAULT_ENTRY_0_6 (32'h1001c248) +`define CLP_DV_REG_DATA_VAULT_ENTRY_0_7 (32'h1001c24c) +`define CLP_DV_REG_DATA_VAULT_ENTRY_0_8 (32'h1001c250) +`define CLP_DV_REG_DATA_VAULT_ENTRY_0_9 (32'h1001c254) +`define CLP_DV_REG_DATA_VAULT_ENTRY_0_10 (32'h1001c258) +`define CLP_DV_REG_DATA_VAULT_ENTRY_0_11 (32'h1001c25c) +`define CLP_DV_REG_DATA_VAULT_ENTRY_1_0 (32'h1001c260) +`define CLP_DV_REG_DATA_VAULT_ENTRY_1_1 (32'h1001c264) +`define CLP_DV_REG_DATA_VAULT_ENTRY_1_2 (32'h1001c268) +`define CLP_DV_REG_DATA_VAULT_ENTRY_1_3 (32'h1001c26c) +`define CLP_DV_REG_DATA_VAULT_ENTRY_1_4 (32'h1001c270) +`define CLP_DV_REG_DATA_VAULT_ENTRY_1_5 (32'h1001c274) +`define CLP_DV_REG_DATA_VAULT_ENTRY_1_6 (32'h1001c278) +`define CLP_DV_REG_DATA_VAULT_ENTRY_1_7 (32'h1001c27c) +`define CLP_DV_REG_DATA_VAULT_ENTRY_1_8 (32'h1001c280) +`define CLP_DV_REG_DATA_VAULT_ENTRY_1_9 (32'h1001c284) +`define CLP_DV_REG_DATA_VAULT_ENTRY_1_10 (32'h1001c288) +`define CLP_DV_REG_DATA_VAULT_ENTRY_1_11 (32'h1001c28c) +`define CLP_DV_REG_DATA_VAULT_ENTRY_2_0 (32'h1001c290) +`define CLP_DV_REG_DATA_VAULT_ENTRY_2_1 (32'h1001c294) +`define CLP_DV_REG_DATA_VAULT_ENTRY_2_2 (32'h1001c298) +`define CLP_DV_REG_DATA_VAULT_ENTRY_2_3 (32'h1001c29c) +`define CLP_DV_REG_DATA_VAULT_ENTRY_2_4 (32'h1001c2a0) +`define CLP_DV_REG_DATA_VAULT_ENTRY_2_5 (32'h1001c2a4) +`define CLP_DV_REG_DATA_VAULT_ENTRY_2_6 (32'h1001c2a8) +`define CLP_DV_REG_DATA_VAULT_ENTRY_2_7 (32'h1001c2ac) +`define CLP_DV_REG_DATA_VAULT_ENTRY_2_8 (32'h1001c2b0) +`define CLP_DV_REG_DATA_VAULT_ENTRY_2_9 (32'h1001c2b4) +`define CLP_DV_REG_DATA_VAULT_ENTRY_2_10 (32'h1001c2b8) +`define CLP_DV_REG_DATA_VAULT_ENTRY_2_11 (32'h1001c2bc) +`define CLP_DV_REG_DATA_VAULT_ENTRY_3_0 (32'h1001c2c0) +`define CLP_DV_REG_DATA_VAULT_ENTRY_3_1 (32'h1001c2c4) +`define CLP_DV_REG_DATA_VAULT_ENTRY_3_2 (32'h1001c2c8) +`define CLP_DV_REG_DATA_VAULT_ENTRY_3_3 (32'h1001c2cc) +`define CLP_DV_REG_DATA_VAULT_ENTRY_3_4 (32'h1001c2d0) +`define CLP_DV_REG_DATA_VAULT_ENTRY_3_5 (32'h1001c2d4) +`define CLP_DV_REG_DATA_VAULT_ENTRY_3_6 (32'h1001c2d8) +`define CLP_DV_REG_DATA_VAULT_ENTRY_3_7 (32'h1001c2dc) +`define CLP_DV_REG_DATA_VAULT_ENTRY_3_8 (32'h1001c2e0) +`define CLP_DV_REG_DATA_VAULT_ENTRY_3_9 (32'h1001c2e4) +`define CLP_DV_REG_DATA_VAULT_ENTRY_3_10 (32'h1001c2e8) +`define CLP_DV_REG_DATA_VAULT_ENTRY_3_11 (32'h1001c2ec) +`define CLP_DV_REG_DATA_VAULT_ENTRY_4_0 (32'h1001c2f0) +`define CLP_DV_REG_DATA_VAULT_ENTRY_4_1 (32'h1001c2f4) +`define CLP_DV_REG_DATA_VAULT_ENTRY_4_2 (32'h1001c2f8) +`define CLP_DV_REG_DATA_VAULT_ENTRY_4_3 (32'h1001c2fc) +`define CLP_DV_REG_DATA_VAULT_ENTRY_4_4 (32'h1001c300) +`define CLP_DV_REG_DATA_VAULT_ENTRY_4_5 (32'h1001c304) +`define CLP_DV_REG_DATA_VAULT_ENTRY_4_6 (32'h1001c308) +`define CLP_DV_REG_DATA_VAULT_ENTRY_4_7 (32'h1001c30c) +`define CLP_DV_REG_DATA_VAULT_ENTRY_4_8 (32'h1001c310) +`define CLP_DV_REG_DATA_VAULT_ENTRY_4_9 (32'h1001c314) +`define CLP_DV_REG_DATA_VAULT_ENTRY_4_10 (32'h1001c318) +`define CLP_DV_REG_DATA_VAULT_ENTRY_4_11 (32'h1001c31c) +`define CLP_DV_REG_DATA_VAULT_ENTRY_5_0 (32'h1001c320) +`define CLP_DV_REG_DATA_VAULT_ENTRY_5_1 (32'h1001c324) +`define CLP_DV_REG_DATA_VAULT_ENTRY_5_2 (32'h1001c328) +`define CLP_DV_REG_DATA_VAULT_ENTRY_5_3 (32'h1001c32c) +`define CLP_DV_REG_DATA_VAULT_ENTRY_5_4 (32'h1001c330) +`define CLP_DV_REG_DATA_VAULT_ENTRY_5_5 (32'h1001c334) +`define CLP_DV_REG_DATA_VAULT_ENTRY_5_6 (32'h1001c338) +`define CLP_DV_REG_DATA_VAULT_ENTRY_5_7 (32'h1001c33c) +`define CLP_DV_REG_DATA_VAULT_ENTRY_5_8 (32'h1001c340) +`define CLP_DV_REG_DATA_VAULT_ENTRY_5_9 (32'h1001c344) +`define CLP_DV_REG_DATA_VAULT_ENTRY_5_10 (32'h1001c348) +`define CLP_DV_REG_DATA_VAULT_ENTRY_5_11 (32'h1001c34c) +`define CLP_DV_REG_DATA_VAULT_ENTRY_6_0 (32'h1001c350) +`define CLP_DV_REG_DATA_VAULT_ENTRY_6_1 (32'h1001c354) +`define CLP_DV_REG_DATA_VAULT_ENTRY_6_2 (32'h1001c358) +`define CLP_DV_REG_DATA_VAULT_ENTRY_6_3 (32'h1001c35c) +`define CLP_DV_REG_DATA_VAULT_ENTRY_6_4 (32'h1001c360) +`define CLP_DV_REG_DATA_VAULT_ENTRY_6_5 (32'h1001c364) +`define CLP_DV_REG_DATA_VAULT_ENTRY_6_6 (32'h1001c368) +`define CLP_DV_REG_DATA_VAULT_ENTRY_6_7 (32'h1001c36c) +`define CLP_DV_REG_DATA_VAULT_ENTRY_6_8 (32'h1001c370) +`define CLP_DV_REG_DATA_VAULT_ENTRY_6_9 (32'h1001c374) +`define CLP_DV_REG_DATA_VAULT_ENTRY_6_10 (32'h1001c378) +`define CLP_DV_REG_DATA_VAULT_ENTRY_6_11 (32'h1001c37c) +`define CLP_DV_REG_DATA_VAULT_ENTRY_7_0 (32'h1001c380) +`define CLP_DV_REG_DATA_VAULT_ENTRY_7_1 (32'h1001c384) +`define CLP_DV_REG_DATA_VAULT_ENTRY_7_2 (32'h1001c388) +`define CLP_DV_REG_DATA_VAULT_ENTRY_7_3 (32'h1001c38c) +`define CLP_DV_REG_DATA_VAULT_ENTRY_7_4 (32'h1001c390) +`define CLP_DV_REG_DATA_VAULT_ENTRY_7_5 (32'h1001c394) +`define CLP_DV_REG_DATA_VAULT_ENTRY_7_6 (32'h1001c398) +`define CLP_DV_REG_DATA_VAULT_ENTRY_7_7 (32'h1001c39c) +`define CLP_DV_REG_DATA_VAULT_ENTRY_7_8 (32'h1001c3a0) +`define CLP_DV_REG_DATA_VAULT_ENTRY_7_9 (32'h1001c3a4) +`define CLP_DV_REG_DATA_VAULT_ENTRY_7_10 (32'h1001c3a8) +`define CLP_DV_REG_DATA_VAULT_ENTRY_7_11 (32'h1001c3ac) +`define CLP_DV_REG_DATA_VAULT_ENTRY_8_0 (32'h1001c3b0) +`define CLP_DV_REG_DATA_VAULT_ENTRY_8_1 (32'h1001c3b4) +`define CLP_DV_REG_DATA_VAULT_ENTRY_8_2 (32'h1001c3b8) +`define CLP_DV_REG_DATA_VAULT_ENTRY_8_3 (32'h1001c3bc) +`define CLP_DV_REG_DATA_VAULT_ENTRY_8_4 (32'h1001c3c0) +`define CLP_DV_REG_DATA_VAULT_ENTRY_8_5 (32'h1001c3c4) +`define CLP_DV_REG_DATA_VAULT_ENTRY_8_6 (32'h1001c3c8) +`define CLP_DV_REG_DATA_VAULT_ENTRY_8_7 (32'h1001c3cc) +`define CLP_DV_REG_DATA_VAULT_ENTRY_8_8 (32'h1001c3d0) +`define CLP_DV_REG_DATA_VAULT_ENTRY_8_9 (32'h1001c3d4) +`define CLP_DV_REG_DATA_VAULT_ENTRY_8_10 (32'h1001c3d8) +`define CLP_DV_REG_DATA_VAULT_ENTRY_8_11 (32'h1001c3dc) +`define CLP_DV_REG_DATA_VAULT_ENTRY_9_0 (32'h1001c3e0) +`define CLP_DV_REG_DATA_VAULT_ENTRY_9_1 (32'h1001c3e4) +`define CLP_DV_REG_DATA_VAULT_ENTRY_9_2 (32'h1001c3e8) +`define CLP_DV_REG_DATA_VAULT_ENTRY_9_3 (32'h1001c3ec) +`define CLP_DV_REG_DATA_VAULT_ENTRY_9_4 (32'h1001c3f0) +`define CLP_DV_REG_DATA_VAULT_ENTRY_9_5 (32'h1001c3f4) +`define CLP_DV_REG_DATA_VAULT_ENTRY_9_6 (32'h1001c3f8) +`define CLP_DV_REG_DATA_VAULT_ENTRY_9_7 (32'h1001c3fc) +`define CLP_DV_REG_DATA_VAULT_ENTRY_9_8 (32'h1001c400) +`define CLP_DV_REG_DATA_VAULT_ENTRY_9_9 (32'h1001c404) +`define CLP_DV_REG_DATA_VAULT_ENTRY_9_10 (32'h1001c408) +`define CLP_DV_REG_DATA_VAULT_ENTRY_9_11 (32'h1001c40c) +`define CLP_DV_REG_LOCKABLESCRATCHREGCTRL_0 (32'h1001c410) +`define CLP_DV_REG_LOCKABLESCRATCHREGCTRL_1 (32'h1001c414) +`define CLP_DV_REG_LOCKABLESCRATCHREGCTRL_2 (32'h1001c418) +`define CLP_DV_REG_LOCKABLESCRATCHREGCTRL_3 (32'h1001c41c) +`define CLP_DV_REG_LOCKABLESCRATCHREGCTRL_4 (32'h1001c420) +`define CLP_DV_REG_LOCKABLESCRATCHREGCTRL_5 (32'h1001c424) +`define CLP_DV_REG_LOCKABLESCRATCHREGCTRL_6 (32'h1001c428) +`define CLP_DV_REG_LOCKABLESCRATCHREGCTRL_7 (32'h1001c42c) +`define CLP_DV_REG_LOCKABLESCRATCHREGCTRL_8 (32'h1001c430) +`define CLP_DV_REG_LOCKABLESCRATCHREGCTRL_9 (32'h1001c434) +`define CLP_DV_REG_LOCKABLESCRATCHREG_0 (32'h1001c438) +`define CLP_DV_REG_LOCKABLESCRATCHREG_1 (32'h1001c43c) +`define CLP_DV_REG_LOCKABLESCRATCHREG_2 (32'h1001c440) +`define CLP_DV_REG_LOCKABLESCRATCHREG_3 (32'h1001c444) +`define CLP_DV_REG_LOCKABLESCRATCHREG_4 (32'h1001c448) +`define CLP_DV_REG_LOCKABLESCRATCHREG_5 (32'h1001c44c) +`define CLP_DV_REG_LOCKABLESCRATCHREG_6 (32'h1001c450) +`define CLP_DV_REG_LOCKABLESCRATCHREG_7 (32'h1001c454) +`define CLP_DV_REG_LOCKABLESCRATCHREG_8 (32'h1001c458) +`define CLP_DV_REG_LOCKABLESCRATCHREG_9 (32'h1001c45c) +`define CLP_DV_REG_NONSTICKYGENERICSCRATCHREG_0 (32'h1001c460) +`define CLP_DV_REG_NONSTICKYGENERICSCRATCHREG_1 (32'h1001c464) +`define CLP_DV_REG_NONSTICKYGENERICSCRATCHREG_2 (32'h1001c468) +`define CLP_DV_REG_NONSTICKYGENERICSCRATCHREG_3 (32'h1001c46c) +`define CLP_DV_REG_NONSTICKYGENERICSCRATCHREG_4 (32'h1001c470) +`define CLP_DV_REG_NONSTICKYGENERICSCRATCHREG_5 (32'h1001c474) +`define CLP_DV_REG_NONSTICKYGENERICSCRATCHREG_6 (32'h1001c478) +`define CLP_DV_REG_NONSTICKYGENERICSCRATCHREG_7 (32'h1001c47c) +`define CLP_DV_REG_STICKYLOCKABLESCRATCHREGCTRL_0 (32'h1001c480) +`define CLP_DV_REG_STICKYLOCKABLESCRATCHREGCTRL_1 (32'h1001c484) +`define CLP_DV_REG_STICKYLOCKABLESCRATCHREGCTRL_2 (32'h1001c488) +`define CLP_DV_REG_STICKYLOCKABLESCRATCHREGCTRL_3 (32'h1001c48c) +`define CLP_DV_REG_STICKYLOCKABLESCRATCHREGCTRL_4 (32'h1001c490) +`define CLP_DV_REG_STICKYLOCKABLESCRATCHREGCTRL_5 (32'h1001c494) +`define CLP_DV_REG_STICKYLOCKABLESCRATCHREGCTRL_6 (32'h1001c498) +`define CLP_DV_REG_STICKYLOCKABLESCRATCHREGCTRL_7 (32'h1001c49c) +`define CLP_DV_REG_STICKYLOCKABLESCRATCHREG_0 (32'h1001c4a0) +`define CLP_DV_REG_STICKYLOCKABLESCRATCHREG_1 (32'h1001c4a4) +`define CLP_DV_REG_STICKYLOCKABLESCRATCHREG_2 (32'h1001c4a8) +`define CLP_DV_REG_STICKYLOCKABLESCRATCHREG_3 (32'h1001c4ac) +`define CLP_DV_REG_STICKYLOCKABLESCRATCHREG_4 (32'h1001c4b0) +`define CLP_DV_REG_STICKYLOCKABLESCRATCHREG_5 (32'h1001c4b4) +`define CLP_DV_REG_STICKYLOCKABLESCRATCHREG_6 (32'h1001c4b8) +`define CLP_DV_REG_STICKYLOCKABLESCRATCHREG_7 (32'h1001c4bc) +`define CLP_SHA512_REG_BASE_ADDR (32'h10020000) +`define CLP_SHA512_REG_SHA512_NAME_0 (32'h10020000) +`define CLP_SHA512_REG_SHA512_NAME_1 (32'h10020004) +`define CLP_SHA512_REG_SHA512_VERSION_0 (32'h10020008) +`define CLP_SHA512_REG_SHA512_VERSION_1 (32'h1002000c) +`define CLP_SHA512_REG_SHA512_CTRL (32'h10020010) +`define CLP_SHA512_REG_SHA512_STATUS (32'h10020018) +`define CLP_SHA512_REG_SHA512_BLOCK_0 (32'h10020080) +`define CLP_SHA512_REG_SHA512_BLOCK_1 (32'h10020084) +`define CLP_SHA512_REG_SHA512_BLOCK_2 (32'h10020088) +`define CLP_SHA512_REG_SHA512_BLOCK_3 (32'h1002008c) +`define CLP_SHA512_REG_SHA512_BLOCK_4 (32'h10020090) +`define CLP_SHA512_REG_SHA512_BLOCK_5 (32'h10020094) +`define CLP_SHA512_REG_SHA512_BLOCK_6 (32'h10020098) +`define CLP_SHA512_REG_SHA512_BLOCK_7 (32'h1002009c) +`define CLP_SHA512_REG_SHA512_BLOCK_8 (32'h100200a0) +`define CLP_SHA512_REG_SHA512_BLOCK_9 (32'h100200a4) +`define CLP_SHA512_REG_SHA512_BLOCK_10 (32'h100200a8) +`define CLP_SHA512_REG_SHA512_BLOCK_11 (32'h100200ac) +`define CLP_SHA512_REG_SHA512_BLOCK_12 (32'h100200b0) +`define CLP_SHA512_REG_SHA512_BLOCK_13 (32'h100200b4) +`define CLP_SHA512_REG_SHA512_BLOCK_14 (32'h100200b8) +`define CLP_SHA512_REG_SHA512_BLOCK_15 (32'h100200bc) +`define CLP_SHA512_REG_SHA512_BLOCK_16 (32'h100200c0) +`define CLP_SHA512_REG_SHA512_BLOCK_17 (32'h100200c4) +`define CLP_SHA512_REG_SHA512_BLOCK_18 (32'h100200c8) +`define CLP_SHA512_REG_SHA512_BLOCK_19 (32'h100200cc) +`define CLP_SHA512_REG_SHA512_BLOCK_20 (32'h100200d0) +`define CLP_SHA512_REG_SHA512_BLOCK_21 (32'h100200d4) +`define CLP_SHA512_REG_SHA512_BLOCK_22 (32'h100200d8) +`define CLP_SHA512_REG_SHA512_BLOCK_23 (32'h100200dc) +`define CLP_SHA512_REG_SHA512_BLOCK_24 (32'h100200e0) +`define CLP_SHA512_REG_SHA512_BLOCK_25 (32'h100200e4) +`define CLP_SHA512_REG_SHA512_BLOCK_26 (32'h100200e8) +`define CLP_SHA512_REG_SHA512_BLOCK_27 (32'h100200ec) +`define CLP_SHA512_REG_SHA512_BLOCK_28 (32'h100200f0) +`define CLP_SHA512_REG_SHA512_BLOCK_29 (32'h100200f4) +`define CLP_SHA512_REG_SHA512_BLOCK_30 (32'h100200f8) +`define CLP_SHA512_REG_SHA512_BLOCK_31 (32'h100200fc) +`define CLP_SHA512_REG_SHA512_DIGEST_0 (32'h10020100) +`define CLP_SHA512_REG_SHA512_DIGEST_1 (32'h10020104) +`define CLP_SHA512_REG_SHA512_DIGEST_2 (32'h10020108) +`define CLP_SHA512_REG_SHA512_DIGEST_3 (32'h1002010c) +`define CLP_SHA512_REG_SHA512_DIGEST_4 (32'h10020110) +`define CLP_SHA512_REG_SHA512_DIGEST_5 (32'h10020114) +`define CLP_SHA512_REG_SHA512_DIGEST_6 (32'h10020118) +`define CLP_SHA512_REG_SHA512_DIGEST_7 (32'h1002011c) +`define CLP_SHA512_REG_SHA512_DIGEST_8 (32'h10020120) +`define CLP_SHA512_REG_SHA512_DIGEST_9 (32'h10020124) +`define CLP_SHA512_REG_SHA512_DIGEST_10 (32'h10020128) +`define CLP_SHA512_REG_SHA512_DIGEST_11 (32'h1002012c) +`define CLP_SHA512_REG_SHA512_DIGEST_12 (32'h10020130) +`define CLP_SHA512_REG_SHA512_DIGEST_13 (32'h10020134) +`define CLP_SHA512_REG_SHA512_DIGEST_14 (32'h10020138) +`define CLP_SHA512_REG_SHA512_DIGEST_15 (32'h1002013c) +`define CLP_SHA512_REG_SHA512_VAULT_RD_CTRL (32'h10020600) +`define CLP_SHA512_REG_SHA512_VAULT_RD_STATUS (32'h10020604) +`define CLP_SHA512_REG_SHA512_KV_WR_CTRL (32'h10020608) +`define CLP_SHA512_REG_SHA512_KV_WR_STATUS (32'h1002060c) +`define CLP_SHA512_REG_SHA512_GEN_PCR_HASH_NONCE_0 (32'h10020610) +`define CLP_SHA512_REG_SHA512_GEN_PCR_HASH_NONCE_1 (32'h10020614) +`define CLP_SHA512_REG_SHA512_GEN_PCR_HASH_NONCE_2 (32'h10020618) +`define CLP_SHA512_REG_SHA512_GEN_PCR_HASH_NONCE_3 (32'h1002061c) +`define CLP_SHA512_REG_SHA512_GEN_PCR_HASH_NONCE_4 (32'h10020620) +`define CLP_SHA512_REG_SHA512_GEN_PCR_HASH_NONCE_5 (32'h10020624) +`define CLP_SHA512_REG_SHA512_GEN_PCR_HASH_NONCE_6 (32'h10020628) +`define CLP_SHA512_REG_SHA512_GEN_PCR_HASH_NONCE_7 (32'h1002062c) +`define CLP_SHA512_REG_SHA512_GEN_PCR_HASH_CTRL (32'h10020630) +`define CLP_SHA512_REG_SHA512_GEN_PCR_HASH_STATUS (32'h10020634) +`define CLP_SHA512_REG_SHA512_GEN_PCR_HASH_DIGEST_0 (32'h10020638) +`define CLP_SHA512_REG_SHA512_GEN_PCR_HASH_DIGEST_1 (32'h1002063c) +`define CLP_SHA512_REG_SHA512_GEN_PCR_HASH_DIGEST_2 (32'h10020640) +`define CLP_SHA512_REG_SHA512_GEN_PCR_HASH_DIGEST_3 (32'h10020644) +`define CLP_SHA512_REG_SHA512_GEN_PCR_HASH_DIGEST_4 (32'h10020648) +`define CLP_SHA512_REG_SHA512_GEN_PCR_HASH_DIGEST_5 (32'h1002064c) +`define CLP_SHA512_REG_SHA512_GEN_PCR_HASH_DIGEST_6 (32'h10020650) +`define CLP_SHA512_REG_SHA512_GEN_PCR_HASH_DIGEST_7 (32'h10020654) +`define CLP_SHA512_REG_SHA512_GEN_PCR_HASH_DIGEST_8 (32'h10020658) +`define CLP_SHA512_REG_SHA512_GEN_PCR_HASH_DIGEST_9 (32'h1002065c) +`define CLP_SHA512_REG_SHA512_GEN_PCR_HASH_DIGEST_10 (32'h10020660) +`define CLP_SHA512_REG_SHA512_GEN_PCR_HASH_DIGEST_11 (32'h10020664) +`define CLP_SHA512_REG_SHA512_GEN_PCR_HASH_DIGEST_12 (32'h10020668) +`define CLP_SHA512_REG_SHA512_GEN_PCR_HASH_DIGEST_13 (32'h1002066c) +`define CLP_SHA512_REG_SHA512_GEN_PCR_HASH_DIGEST_14 (32'h10020670) +`define CLP_SHA512_REG_SHA512_GEN_PCR_HASH_DIGEST_15 (32'h10020674) +`define CLP_SHA512_REG_INTR_BLOCK_RF_START (32'h10020800) +`define CLP_SHA512_REG_INTR_BLOCK_RF_GLOBAL_INTR_EN_R (32'h10020800) +`define CLP_SHA512_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R (32'h10020804) +`define CLP_SHA512_REG_INTR_BLOCK_RF_NOTIF_INTR_EN_R (32'h10020808) +`define CLP_SHA512_REG_INTR_BLOCK_RF_ERROR_GLOBAL_INTR_R (32'h1002080c) +`define CLP_SHA512_REG_INTR_BLOCK_RF_NOTIF_GLOBAL_INTR_R (32'h10020810) +`define CLP_SHA512_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R (32'h10020814) +`define CLP_SHA512_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R (32'h10020818) +`define CLP_SHA512_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R (32'h1002081c) +`define CLP_SHA512_REG_INTR_BLOCK_RF_NOTIF_INTR_TRIG_R (32'h10020820) +`define CLP_SHA512_REG_INTR_BLOCK_RF_ERROR0_INTR_COUNT_R (32'h10020900) +`define CLP_SHA512_REG_INTR_BLOCK_RF_ERROR1_INTR_COUNT_R (32'h10020904) +`define CLP_SHA512_REG_INTR_BLOCK_RF_ERROR2_INTR_COUNT_R (32'h10020908) +`define CLP_SHA512_REG_INTR_BLOCK_RF_ERROR3_INTR_COUNT_R (32'h1002090c) +`define CLP_SHA512_REG_INTR_BLOCK_RF_NOTIF_CMD_DONE_INTR_COUNT_R (32'h10020980) +`define CLP_SHA512_REG_INTR_BLOCK_RF_ERROR0_INTR_COUNT_INCR_R (32'h10020a00) +`define CLP_SHA512_REG_INTR_BLOCK_RF_ERROR1_INTR_COUNT_INCR_R (32'h10020a04) +`define CLP_SHA512_REG_INTR_BLOCK_RF_ERROR2_INTR_COUNT_INCR_R (32'h10020a08) +`define CLP_SHA512_REG_INTR_BLOCK_RF_ERROR3_INTR_COUNT_INCR_R (32'h10020a0c) +`define CLP_SHA512_REG_INTR_BLOCK_RF_NOTIF_CMD_DONE_INTR_COUNT_INCR_R (32'h10020a10) +`define CLP_SHA256_REG_BASE_ADDR (32'h10028000) +`define CLP_SHA256_REG_SHA256_NAME_0 (32'h10028000) +`define CLP_SHA256_REG_SHA256_NAME_1 (32'h10028004) +`define CLP_SHA256_REG_SHA256_VERSION_0 (32'h10028008) +`define CLP_SHA256_REG_SHA256_VERSION_1 (32'h1002800c) +`define CLP_SHA256_REG_SHA256_CTRL (32'h10028010) +`define CLP_SHA256_REG_SHA256_STATUS (32'h10028018) +`define CLP_SHA256_REG_SHA256_BLOCK_0 (32'h10028080) +`define CLP_SHA256_REG_SHA256_BLOCK_1 (32'h10028084) +`define CLP_SHA256_REG_SHA256_BLOCK_2 (32'h10028088) +`define CLP_SHA256_REG_SHA256_BLOCK_3 (32'h1002808c) +`define CLP_SHA256_REG_SHA256_BLOCK_4 (32'h10028090) +`define CLP_SHA256_REG_SHA256_BLOCK_5 (32'h10028094) +`define CLP_SHA256_REG_SHA256_BLOCK_6 (32'h10028098) +`define CLP_SHA256_REG_SHA256_BLOCK_7 (32'h1002809c) +`define CLP_SHA256_REG_SHA256_BLOCK_8 (32'h100280a0) +`define CLP_SHA256_REG_SHA256_BLOCK_9 (32'h100280a4) +`define CLP_SHA256_REG_SHA256_BLOCK_10 (32'h100280a8) +`define CLP_SHA256_REG_SHA256_BLOCK_11 (32'h100280ac) +`define CLP_SHA256_REG_SHA256_BLOCK_12 (32'h100280b0) +`define CLP_SHA256_REG_SHA256_BLOCK_13 (32'h100280b4) +`define CLP_SHA256_REG_SHA256_BLOCK_14 (32'h100280b8) +`define CLP_SHA256_REG_SHA256_BLOCK_15 (32'h100280bc) +`define CLP_SHA256_REG_SHA256_DIGEST_0 (32'h10028100) +`define CLP_SHA256_REG_SHA256_DIGEST_1 (32'h10028104) +`define CLP_SHA256_REG_SHA256_DIGEST_2 (32'h10028108) +`define CLP_SHA256_REG_SHA256_DIGEST_3 (32'h1002810c) +`define CLP_SHA256_REG_SHA256_DIGEST_4 (32'h10028110) +`define CLP_SHA256_REG_SHA256_DIGEST_5 (32'h10028114) +`define CLP_SHA256_REG_SHA256_DIGEST_6 (32'h10028118) +`define CLP_SHA256_REG_SHA256_DIGEST_7 (32'h1002811c) +`define CLP_SHA256_REG_INTR_BLOCK_RF_START (32'h10028800) +`define CLP_SHA256_REG_INTR_BLOCK_RF_GLOBAL_INTR_EN_R (32'h10028800) +`define CLP_SHA256_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R (32'h10028804) +`define CLP_SHA256_REG_INTR_BLOCK_RF_NOTIF_INTR_EN_R (32'h10028808) +`define CLP_SHA256_REG_INTR_BLOCK_RF_ERROR_GLOBAL_INTR_R (32'h1002880c) +`define CLP_SHA256_REG_INTR_BLOCK_RF_NOTIF_GLOBAL_INTR_R (32'h10028810) +`define CLP_SHA256_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R (32'h10028814) +`define CLP_SHA256_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R (32'h10028818) +`define CLP_SHA256_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R (32'h1002881c) +`define CLP_SHA256_REG_INTR_BLOCK_RF_NOTIF_INTR_TRIG_R (32'h10028820) +`define CLP_SHA256_REG_INTR_BLOCK_RF_ERROR0_INTR_COUNT_R (32'h10028900) +`define CLP_SHA256_REG_INTR_BLOCK_RF_ERROR1_INTR_COUNT_R (32'h10028904) +`define CLP_SHA256_REG_INTR_BLOCK_RF_ERROR2_INTR_COUNT_R (32'h10028908) +`define CLP_SHA256_REG_INTR_BLOCK_RF_ERROR3_INTR_COUNT_R (32'h1002890c) +`define CLP_SHA256_REG_INTR_BLOCK_RF_NOTIF_CMD_DONE_INTR_COUNT_R (32'h10028980) +`define CLP_SHA256_REG_INTR_BLOCK_RF_ERROR0_INTR_COUNT_INCR_R (32'h10028a00) +`define CLP_SHA256_REG_INTR_BLOCK_RF_ERROR1_INTR_COUNT_INCR_R (32'h10028a04) +`define CLP_SHA256_REG_INTR_BLOCK_RF_ERROR2_INTR_COUNT_INCR_R (32'h10028a08) +`define CLP_SHA256_REG_INTR_BLOCK_RF_ERROR3_INTR_COUNT_INCR_R (32'h10028a0c) +`define CLP_SHA256_REG_INTR_BLOCK_RF_NOTIF_CMD_DONE_INTR_COUNT_INCR_R (32'h10028a10) +`define CLP_ABR_REG_BASE_ADDR (32'h10030000) +`define CLP_ABR_REG_MLDSA_NAME_0 (32'h10030000) +`define CLP_ABR_REG_MLDSA_NAME_1 (32'h10030004) +`define CLP_ABR_REG_MLDSA_VERSION_0 (32'h10030008) +`define CLP_ABR_REG_MLDSA_VERSION_1 (32'h1003000c) +`define CLP_ABR_REG_MLDSA_CTRL (32'h10030010) +`define CLP_ABR_REG_MLDSA_STATUS (32'h10030014) +`define CLP_ABR_REG_ABR_ENTROPY_0 (32'h10030018) +`define CLP_ABR_REG_ABR_ENTROPY_1 (32'h1003001c) +`define CLP_ABR_REG_ABR_ENTROPY_2 (32'h10030020) +`define CLP_ABR_REG_ABR_ENTROPY_3 (32'h10030024) +`define CLP_ABR_REG_ABR_ENTROPY_4 (32'h10030028) +`define CLP_ABR_REG_ABR_ENTROPY_5 (32'h1003002c) +`define CLP_ABR_REG_ABR_ENTROPY_6 (32'h10030030) +`define CLP_ABR_REG_ABR_ENTROPY_7 (32'h10030034) +`define CLP_ABR_REG_ABR_ENTROPY_8 (32'h10030038) +`define CLP_ABR_REG_ABR_ENTROPY_9 (32'h1003003c) +`define CLP_ABR_REG_ABR_ENTROPY_10 (32'h10030040) +`define CLP_ABR_REG_ABR_ENTROPY_11 (32'h10030044) +`define CLP_ABR_REG_ABR_ENTROPY_12 (32'h10030048) +`define CLP_ABR_REG_ABR_ENTROPY_13 (32'h1003004c) +`define CLP_ABR_REG_ABR_ENTROPY_14 (32'h10030050) +`define CLP_ABR_REG_ABR_ENTROPY_15 (32'h10030054) +`define CLP_ABR_REG_MLDSA_SEED_0 (32'h10030058) +`define CLP_ABR_REG_MLDSA_SEED_1 (32'h1003005c) +`define CLP_ABR_REG_MLDSA_SEED_2 (32'h10030060) +`define CLP_ABR_REG_MLDSA_SEED_3 (32'h10030064) +`define CLP_ABR_REG_MLDSA_SEED_4 (32'h10030068) +`define CLP_ABR_REG_MLDSA_SEED_5 (32'h1003006c) +`define CLP_ABR_REG_MLDSA_SEED_6 (32'h10030070) +`define CLP_ABR_REG_MLDSA_SEED_7 (32'h10030074) +`define CLP_ABR_REG_MLDSA_SIGN_RND_0 (32'h10030078) +`define CLP_ABR_REG_MLDSA_SIGN_RND_1 (32'h1003007c) +`define CLP_ABR_REG_MLDSA_SIGN_RND_2 (32'h10030080) +`define CLP_ABR_REG_MLDSA_SIGN_RND_3 (32'h10030084) +`define CLP_ABR_REG_MLDSA_SIGN_RND_4 (32'h10030088) +`define CLP_ABR_REG_MLDSA_SIGN_RND_5 (32'h1003008c) +`define CLP_ABR_REG_MLDSA_SIGN_RND_6 (32'h10030090) +`define CLP_ABR_REG_MLDSA_SIGN_RND_7 (32'h10030094) +`define CLP_ABR_REG_MLDSA_MSG_0 (32'h10030098) +`define CLP_ABR_REG_MLDSA_MSG_1 (32'h1003009c) +`define CLP_ABR_REG_MLDSA_MSG_2 (32'h100300a0) +`define CLP_ABR_REG_MLDSA_MSG_3 (32'h100300a4) +`define CLP_ABR_REG_MLDSA_MSG_4 (32'h100300a8) +`define CLP_ABR_REG_MLDSA_MSG_5 (32'h100300ac) +`define CLP_ABR_REG_MLDSA_MSG_6 (32'h100300b0) +`define CLP_ABR_REG_MLDSA_MSG_7 (32'h100300b4) +`define CLP_ABR_REG_MLDSA_MSG_8 (32'h100300b8) +`define CLP_ABR_REG_MLDSA_MSG_9 (32'h100300bc) +`define CLP_ABR_REG_MLDSA_MSG_10 (32'h100300c0) +`define CLP_ABR_REG_MLDSA_MSG_11 (32'h100300c4) +`define CLP_ABR_REG_MLDSA_MSG_12 (32'h100300c8) +`define CLP_ABR_REG_MLDSA_MSG_13 (32'h100300cc) +`define CLP_ABR_REG_MLDSA_MSG_14 (32'h100300d0) +`define CLP_ABR_REG_MLDSA_MSG_15 (32'h100300d4) +`define CLP_ABR_REG_MLDSA_VERIFY_RES_0 (32'h100300d8) +`define CLP_ABR_REG_MLDSA_VERIFY_RES_1 (32'h100300dc) +`define CLP_ABR_REG_MLDSA_VERIFY_RES_2 (32'h100300e0) +`define CLP_ABR_REG_MLDSA_VERIFY_RES_3 (32'h100300e4) +`define CLP_ABR_REG_MLDSA_VERIFY_RES_4 (32'h100300e8) +`define CLP_ABR_REG_MLDSA_VERIFY_RES_5 (32'h100300ec) +`define CLP_ABR_REG_MLDSA_VERIFY_RES_6 (32'h100300f0) +`define CLP_ABR_REG_MLDSA_VERIFY_RES_7 (32'h100300f4) +`define CLP_ABR_REG_MLDSA_VERIFY_RES_8 (32'h100300f8) +`define CLP_ABR_REG_MLDSA_VERIFY_RES_9 (32'h100300fc) +`define CLP_ABR_REG_MLDSA_VERIFY_RES_10 (32'h10030100) +`define CLP_ABR_REG_MLDSA_VERIFY_RES_11 (32'h10030104) +`define CLP_ABR_REG_MLDSA_VERIFY_RES_12 (32'h10030108) +`define CLP_ABR_REG_MLDSA_VERIFY_RES_13 (32'h1003010c) +`define CLP_ABR_REG_MLDSA_VERIFY_RES_14 (32'h10030110) +`define CLP_ABR_REG_MLDSA_VERIFY_RES_15 (32'h10030114) +`define CLP_ABR_REG_MLDSA_EXTERNAL_MU_0 (32'h10030118) +`define CLP_ABR_REG_MLDSA_EXTERNAL_MU_1 (32'h1003011c) +`define CLP_ABR_REG_MLDSA_EXTERNAL_MU_2 (32'h10030120) +`define CLP_ABR_REG_MLDSA_EXTERNAL_MU_3 (32'h10030124) +`define CLP_ABR_REG_MLDSA_EXTERNAL_MU_4 (32'h10030128) +`define CLP_ABR_REG_MLDSA_EXTERNAL_MU_5 (32'h1003012c) +`define CLP_ABR_REG_MLDSA_EXTERNAL_MU_6 (32'h10030130) +`define CLP_ABR_REG_MLDSA_EXTERNAL_MU_7 (32'h10030134) +`define CLP_ABR_REG_MLDSA_EXTERNAL_MU_8 (32'h10030138) +`define CLP_ABR_REG_MLDSA_EXTERNAL_MU_9 (32'h1003013c) +`define CLP_ABR_REG_MLDSA_EXTERNAL_MU_10 (32'h10030140) +`define CLP_ABR_REG_MLDSA_EXTERNAL_MU_11 (32'h10030144) +`define CLP_ABR_REG_MLDSA_EXTERNAL_MU_12 (32'h10030148) +`define CLP_ABR_REG_MLDSA_EXTERNAL_MU_13 (32'h1003014c) +`define CLP_ABR_REG_MLDSA_EXTERNAL_MU_14 (32'h10030150) +`define CLP_ABR_REG_MLDSA_EXTERNAL_MU_15 (32'h10030154) +`define CLP_ABR_REG_MLDSA_MSG_STROBE (32'h10030158) +`define CLP_ABR_REG_MLDSA_CTX_CONFIG (32'h1003015c) +`define CLP_ABR_REG_MLDSA_CTX_0 (32'h10030160) +`define CLP_ABR_REG_MLDSA_CTX_1 (32'h10030164) +`define CLP_ABR_REG_MLDSA_CTX_2 (32'h10030168) +`define CLP_ABR_REG_MLDSA_CTX_3 (32'h1003016c) +`define CLP_ABR_REG_MLDSA_CTX_4 (32'h10030170) +`define CLP_ABR_REG_MLDSA_CTX_5 (32'h10030174) +`define CLP_ABR_REG_MLDSA_CTX_6 (32'h10030178) +`define CLP_ABR_REG_MLDSA_CTX_7 (32'h1003017c) +`define CLP_ABR_REG_MLDSA_CTX_8 (32'h10030180) +`define CLP_ABR_REG_MLDSA_CTX_9 (32'h10030184) +`define CLP_ABR_REG_MLDSA_CTX_10 (32'h10030188) +`define CLP_ABR_REG_MLDSA_CTX_11 (32'h1003018c) +`define CLP_ABR_REG_MLDSA_CTX_12 (32'h10030190) +`define CLP_ABR_REG_MLDSA_CTX_13 (32'h10030194) +`define CLP_ABR_REG_MLDSA_CTX_14 (32'h10030198) +`define CLP_ABR_REG_MLDSA_CTX_15 (32'h1003019c) +`define CLP_ABR_REG_MLDSA_CTX_16 (32'h100301a0) +`define CLP_ABR_REG_MLDSA_CTX_17 (32'h100301a4) +`define CLP_ABR_REG_MLDSA_CTX_18 (32'h100301a8) +`define CLP_ABR_REG_MLDSA_CTX_19 (32'h100301ac) +`define CLP_ABR_REG_MLDSA_CTX_20 (32'h100301b0) +`define CLP_ABR_REG_MLDSA_CTX_21 (32'h100301b4) +`define CLP_ABR_REG_MLDSA_CTX_22 (32'h100301b8) +`define CLP_ABR_REG_MLDSA_CTX_23 (32'h100301bc) +`define CLP_ABR_REG_MLDSA_CTX_24 (32'h100301c0) +`define CLP_ABR_REG_MLDSA_CTX_25 (32'h100301c4) +`define CLP_ABR_REG_MLDSA_CTX_26 (32'h100301c8) +`define CLP_ABR_REG_MLDSA_CTX_27 (32'h100301cc) +`define CLP_ABR_REG_MLDSA_CTX_28 (32'h100301d0) +`define CLP_ABR_REG_MLDSA_CTX_29 (32'h100301d4) +`define CLP_ABR_REG_MLDSA_CTX_30 (32'h100301d8) +`define CLP_ABR_REG_MLDSA_CTX_31 (32'h100301dc) +`define CLP_ABR_REG_MLDSA_CTX_32 (32'h100301e0) +`define CLP_ABR_REG_MLDSA_CTX_33 (32'h100301e4) +`define CLP_ABR_REG_MLDSA_CTX_34 (32'h100301e8) +`define CLP_ABR_REG_MLDSA_CTX_35 (32'h100301ec) +`define CLP_ABR_REG_MLDSA_CTX_36 (32'h100301f0) +`define CLP_ABR_REG_MLDSA_CTX_37 (32'h100301f4) +`define CLP_ABR_REG_MLDSA_CTX_38 (32'h100301f8) +`define CLP_ABR_REG_MLDSA_CTX_39 (32'h100301fc) +`define CLP_ABR_REG_MLDSA_CTX_40 (32'h10030200) +`define CLP_ABR_REG_MLDSA_CTX_41 (32'h10030204) +`define CLP_ABR_REG_MLDSA_CTX_42 (32'h10030208) +`define CLP_ABR_REG_MLDSA_CTX_43 (32'h1003020c) +`define CLP_ABR_REG_MLDSA_CTX_44 (32'h10030210) +`define CLP_ABR_REG_MLDSA_CTX_45 (32'h10030214) +`define CLP_ABR_REG_MLDSA_CTX_46 (32'h10030218) +`define CLP_ABR_REG_MLDSA_CTX_47 (32'h1003021c) +`define CLP_ABR_REG_MLDSA_CTX_48 (32'h10030220) +`define CLP_ABR_REG_MLDSA_CTX_49 (32'h10030224) +`define CLP_ABR_REG_MLDSA_CTX_50 (32'h10030228) +`define CLP_ABR_REG_MLDSA_CTX_51 (32'h1003022c) +`define CLP_ABR_REG_MLDSA_CTX_52 (32'h10030230) +`define CLP_ABR_REG_MLDSA_CTX_53 (32'h10030234) +`define CLP_ABR_REG_MLDSA_CTX_54 (32'h10030238) +`define CLP_ABR_REG_MLDSA_CTX_55 (32'h1003023c) +`define CLP_ABR_REG_MLDSA_CTX_56 (32'h10030240) +`define CLP_ABR_REG_MLDSA_CTX_57 (32'h10030244) +`define CLP_ABR_REG_MLDSA_CTX_58 (32'h10030248) +`define CLP_ABR_REG_MLDSA_CTX_59 (32'h1003024c) +`define CLP_ABR_REG_MLDSA_CTX_60 (32'h10030250) +`define CLP_ABR_REG_MLDSA_CTX_61 (32'h10030254) +`define CLP_ABR_REG_MLDSA_CTX_62 (32'h10030258) +`define CLP_ABR_REG_MLDSA_CTX_63 (32'h1003025c) +`define CLP_ABR_REG_MLDSA_PUBKEY_BASE_ADDR (32'h10031000) +`define CLP_ABR_REG_MLDSA_PUBKEY_END_ADDR (32'h10031a1f) +`define CLP_ABR_REG_MLDSA_SIGNATURE_BASE_ADDR (32'h10032000) +`define CLP_ABR_REG_MLDSA_SIGNATURE_END_ADDR (32'h10033213) +`define CLP_ABR_REG_MLDSA_PRIVKEY_OUT_BASE_ADDR (32'h10034000) +`define CLP_ABR_REG_MLDSA_PRIVKEY_OUT_END_ADDR (32'h1003531f) +`define CLP_ABR_REG_MLDSA_PRIVKEY_IN_BASE_ADDR (32'h10036000) +`define CLP_ABR_REG_MLDSA_PRIVKEY_IN_END_ADDR (32'h1003731f) +`define CLP_ABR_REG_KV_MLDSA_SEED_RD_CTRL (32'h10038000) +`define CLP_ABR_REG_KV_MLDSA_SEED_RD_STATUS (32'h10038004) +`define CLP_ABR_REG_INTR_BLOCK_RF_START (32'h10038100) +`define CLP_ABR_REG_INTR_BLOCK_RF_GLOBAL_INTR_EN_R (32'h10038100) +`define CLP_ABR_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R (32'h10038104) +`define CLP_ABR_REG_INTR_BLOCK_RF_NOTIF_INTR_EN_R (32'h10038108) +`define CLP_ABR_REG_INTR_BLOCK_RF_ERROR_GLOBAL_INTR_R (32'h1003810c) +`define CLP_ABR_REG_INTR_BLOCK_RF_NOTIF_GLOBAL_INTR_R (32'h10038110) +`define CLP_ABR_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R (32'h10038114) +`define CLP_ABR_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R (32'h10038118) +`define CLP_ABR_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R (32'h1003811c) +`define CLP_ABR_REG_INTR_BLOCK_RF_NOTIF_INTR_TRIG_R (32'h10038120) +`define CLP_ABR_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_COUNT_R (32'h10038200) +`define CLP_ABR_REG_INTR_BLOCK_RF_NOTIF_CMD_DONE_INTR_COUNT_R (32'h10038280) +`define CLP_ABR_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_COUNT_INCR_R (32'h10038300) +`define CLP_ABR_REG_INTR_BLOCK_RF_NOTIF_CMD_DONE_INTR_COUNT_INCR_R (32'h10038304) +`define CLP_ABR_REG_MLKEM_NAME_0 (32'h10039000) +`define CLP_ABR_REG_MLKEM_NAME_1 (32'h10039004) +`define CLP_ABR_REG_MLKEM_VERSION_0 (32'h10039008) +`define CLP_ABR_REG_MLKEM_VERSION_1 (32'h1003900c) +`define CLP_ABR_REG_MLKEM_CTRL (32'h10039010) +`define CLP_ABR_REG_MLKEM_STATUS (32'h10039014) +`define CLP_ABR_REG_MLKEM_SEED_D_0 (32'h10039018) +`define CLP_ABR_REG_MLKEM_SEED_D_1 (32'h1003901c) +`define CLP_ABR_REG_MLKEM_SEED_D_2 (32'h10039020) +`define CLP_ABR_REG_MLKEM_SEED_D_3 (32'h10039024) +`define CLP_ABR_REG_MLKEM_SEED_D_4 (32'h10039028) +`define CLP_ABR_REG_MLKEM_SEED_D_5 (32'h1003902c) +`define CLP_ABR_REG_MLKEM_SEED_D_6 (32'h10039030) +`define CLP_ABR_REG_MLKEM_SEED_D_7 (32'h10039034) +`define CLP_ABR_REG_MLKEM_SEED_Z_0 (32'h10039038) +`define CLP_ABR_REG_MLKEM_SEED_Z_1 (32'h1003903c) +`define CLP_ABR_REG_MLKEM_SEED_Z_2 (32'h10039040) +`define CLP_ABR_REG_MLKEM_SEED_Z_3 (32'h10039044) +`define CLP_ABR_REG_MLKEM_SEED_Z_4 (32'h10039048) +`define CLP_ABR_REG_MLKEM_SEED_Z_5 (32'h1003904c) +`define CLP_ABR_REG_MLKEM_SEED_Z_6 (32'h10039050) +`define CLP_ABR_REG_MLKEM_SEED_Z_7 (32'h10039054) +`define CLP_ABR_REG_MLKEM_SHARED_KEY_0 (32'h10039058) +`define CLP_ABR_REG_MLKEM_SHARED_KEY_1 (32'h1003905c) +`define CLP_ABR_REG_MLKEM_SHARED_KEY_2 (32'h10039060) +`define CLP_ABR_REG_MLKEM_SHARED_KEY_3 (32'h10039064) +`define CLP_ABR_REG_MLKEM_SHARED_KEY_4 (32'h10039068) +`define CLP_ABR_REG_MLKEM_SHARED_KEY_5 (32'h1003906c) +`define CLP_ABR_REG_MLKEM_SHARED_KEY_6 (32'h10039070) +`define CLP_ABR_REG_MLKEM_SHARED_KEY_7 (32'h10039074) +`define CLP_ABR_REG_MLKEM_MSG_BASE_ADDR (32'h10039080) +`define CLP_ABR_REG_MLKEM_MSG_END_ADDR (32'h1003909f) +`define CLP_ABR_REG_MLKEM_DECAPS_KEY_BASE_ADDR (32'h1003a000) +`define CLP_ABR_REG_MLKEM_DECAPS_KEY_END_ADDR (32'h1003ac5f) +`define CLP_ABR_REG_MLKEM_ENCAPS_KEY_BASE_ADDR (32'h1003b000) +`define CLP_ABR_REG_MLKEM_ENCAPS_KEY_END_ADDR (32'h1003b61f) +`define CLP_ABR_REG_MLKEM_CIPHERTEXT_BASE_ADDR (32'h1003b800) +`define CLP_ABR_REG_MLKEM_CIPHERTEXT_END_ADDR (32'h1003be1f) +`define CLP_ABR_REG_KV_MLKEM_SEED_RD_CTRL (32'h1003c000) +`define CLP_ABR_REG_KV_MLKEM_SEED_RD_STATUS (32'h1003c004) +`define CLP_ABR_REG_KV_MLKEM_MSG_RD_CTRL (32'h1003c008) +`define CLP_ABR_REG_KV_MLKEM_MSG_RD_STATUS (32'h1003c00c) +`define CLP_ABR_REG_KV_MLKEM_SHAREDKEY_WR_CTRL (32'h1003c010) +`define CLP_ABR_REG_KV_MLKEM_SHAREDKEY_WR_STATUS (32'h1003c014) +`define CLP_KMAC_BASE_ADDR (32'h10040000) +`define CLP_KMAC_INTR_STATE (32'h10040000) +`define CLP_KMAC_INTR_ENABLE (32'h10040004) +`define CLP_KMAC_INTR_TEST (32'h10040008) +`define CLP_KMAC_ALERT_TEST (32'h1004000c) +`define CLP_KMAC_CFG_REGWEN (32'h10040010) +`define CLP_KMAC_CFG_SHADOWED (32'h10040014) +`define CLP_KMAC_CMD (32'h10040018) +`define CLP_KMAC_STATUS (32'h1004001c) +`define CLP_KMAC_PREFIX_0 (32'h10040020) +`define CLP_KMAC_PREFIX_1 (32'h10040024) +`define CLP_KMAC_PREFIX_2 (32'h10040028) +`define CLP_KMAC_PREFIX_3 (32'h1004002c) +`define CLP_KMAC_PREFIX_4 (32'h10040030) +`define CLP_KMAC_PREFIX_5 (32'h10040034) +`define CLP_KMAC_PREFIX_6 (32'h10040038) +`define CLP_KMAC_PREFIX_7 (32'h1004003c) +`define CLP_KMAC_PREFIX_8 (32'h10040040) +`define CLP_KMAC_PREFIX_9 (32'h10040044) +`define CLP_KMAC_PREFIX_10 (32'h10040048) +`define CLP_KMAC_ERR_CODE (32'h1004004c) +`define CLP_KMAC_STATE_BASE_ADDR (32'h10040400) +`define CLP_KMAC_STATE_END_ADDR (32'h100404ff) +`define CLP_KMAC_MSG_FIFO_BASE_ADDR (32'h10040800) +`define CLP_KMAC_MSG_FIFO_END_ADDR (32'h100408ff) +`define CLP_SHA3_BASE_ADDR (32'h10041000) +`define CLP_SHA3_SHA3_NAME_0 (32'h10041000) +`define CLP_SHA3_SHA3_NAME_1 (32'h10041004) +`define CLP_SHA3_SHA3_VERSION_0 (32'h10041008) +`define CLP_SHA3_SHA3_VERSION_1 (32'h1004100c) +`define CLP_SHA3_ALERT_TEST (32'h1004101c) +`define CLP_SHA3_CFG_REGWEN (32'h10041020) +`define CLP_SHA3_CFG_SHADOWED (32'h10041024) +`define CLP_SHA3_CMD (32'h10041028) +`define CLP_SHA3_STATUS (32'h1004102c) +`define CLP_SHA3_ERR_CODE (32'h100410d0) +`define CLP_SHA3_STATE_BASE_ADDR (32'h10041200) +`define CLP_SHA3_STATE_END_ADDR (32'h100412ff) +`define CLP_SHA3_INTR_BLOCK_RF_START (32'h10041400) +`define CLP_SHA3_INTR_BLOCK_RF_GLOBAL_INTR_EN_R (32'h10041400) +`define CLP_SHA3_INTR_BLOCK_RF_ERROR_INTR_EN_R (32'h10041404) +`define CLP_SHA3_INTR_BLOCK_RF_NOTIF_INTR_EN_R (32'h10041408) +`define CLP_SHA3_INTR_BLOCK_RF_ERROR_GLOBAL_INTR_R (32'h1004140c) +`define CLP_SHA3_INTR_BLOCK_RF_NOTIF_GLOBAL_INTR_R (32'h10041410) +`define CLP_SHA3_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R (32'h10041414) +`define CLP_SHA3_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R (32'h10041418) +`define CLP_SHA3_INTR_BLOCK_RF_ERROR_INTR_TRIG_R (32'h1004141c) +`define CLP_SHA3_INTR_BLOCK_RF_NOTIF_INTR_TRIG_R (32'h10041420) +`define CLP_SHA3_INTR_BLOCK_RF_SHA3_ERROR_INTR_COUNT_R (32'h10041500) +`define CLP_SHA3_INTR_BLOCK_RF_ERROR1_INTR_COUNT_R (32'h10041504) +`define CLP_SHA3_INTR_BLOCK_RF_ERROR2_INTR_COUNT_R (32'h10041508) +`define CLP_SHA3_INTR_BLOCK_RF_ERROR3_INTR_COUNT_R (32'h1004150c) +`define CLP_SHA3_INTR_BLOCK_RF_NOTIF_CMD_DONE_INTR_COUNT_R (32'h10041580) +`define CLP_SHA3_INTR_BLOCK_RF_SHA3_ERROR_INTR_COUNT_INCR_R (32'h10041600) +`define CLP_SHA3_INTR_BLOCK_RF_ERROR1_INTR_COUNT_INCR_R (32'h10041604) +`define CLP_SHA3_INTR_BLOCK_RF_ERROR2_INTR_COUNT_INCR_R (32'h10041608) +`define CLP_SHA3_INTR_BLOCK_RF_ERROR3_INTR_COUNT_INCR_R (32'h1004160c) +`define CLP_SHA3_INTR_BLOCK_RF_NOTIF_CMD_DONE_INTR_COUNT_INCR_R (32'h10041610) +`define CLP_SHA3_MSG_FIFO_BASE_ADDR (32'h10041c00) +`define CLP_SHA3_MSG_FIFO_END_ADDR (32'h10041cff) +`define CLP_CSRNG_REG_BASE_ADDR (32'h20002000) +`define CLP_CSRNG_REG_INTERRUPT_STATE (32'h20002000) +`define CLP_CSRNG_REG_INTERRUPT_ENABLE (32'h20002004) +`define CLP_CSRNG_REG_INTERRUPT_TEST (32'h20002008) +`define CLP_CSRNG_REG_ALERT_TEST (32'h2000200c) +`define CLP_CSRNG_REG_REGWEN (32'h20002010) +`define CLP_CSRNG_REG_CTRL (32'h20002014) +`define CLP_CSRNG_REG_CMD_REQ (32'h20002018) +`define CLP_CSRNG_REG_RESEED_INTERVAL (32'h2000201c) +`define CLP_CSRNG_REG_RESEED_COUNTER_0 (32'h20002020) +`define CLP_CSRNG_REG_RESEED_COUNTER_1 (32'h20002024) +`define CLP_CSRNG_REG_RESEED_COUNTER_2 (32'h20002028) +`define CLP_CSRNG_REG_SW_CMD_STS (32'h2000202c) +`define CLP_CSRNG_REG_GENBITS_VLD (32'h20002030) +`define CLP_CSRNG_REG_GENBITS (32'h20002034) +`define CLP_CSRNG_REG_INT_STATE_READ_ENABLE (32'h20002038) +`define CLP_CSRNG_REG_INT_STATE_READ_ENABLE_REGWEN (32'h2000203c) +`define CLP_CSRNG_REG_INT_STATE_NUM (32'h20002040) +`define CLP_CSRNG_REG_INT_STATE_VAL (32'h20002044) +`define CLP_CSRNG_REG_FIPS_FORCE (32'h20002048) +`define CLP_CSRNG_REG_HW_EXC_STS (32'h2000204c) +`define CLP_CSRNG_REG_RECOV_ALERT_STS (32'h20002050) +`define CLP_CSRNG_REG_ERR_CODE (32'h20002054) +`define CLP_CSRNG_REG_ERR_CODE_TEST (32'h20002058) +`define CLP_CSRNG_REG_MAIN_SM_STATE (32'h2000205c) +`define CLP_ENTROPY_SRC_REG_BASE_ADDR (32'h20003000) +`define CLP_ENTROPY_SRC_REG_INTERRUPT_STATE (32'h20003000) +`define CLP_ENTROPY_SRC_REG_INTERRUPT_ENABLE (32'h20003004) +`define CLP_ENTROPY_SRC_REG_INTERRUPT_TEST (32'h20003008) +`define CLP_ENTROPY_SRC_REG_ALERT_TEST (32'h2000300c) +`define CLP_ENTROPY_SRC_REG_ME_REGWEN (32'h20003010) +`define CLP_ENTROPY_SRC_REG_SW_REGUPD (32'h20003014) +`define CLP_ENTROPY_SRC_REG_REGWEN (32'h20003018) +`define CLP_ENTROPY_SRC_REG_REV (32'h2000301c) +`define CLP_ENTROPY_SRC_REG_MODULE_ENABLE (32'h20003020) +`define CLP_ENTROPY_SRC_REG_CONF (32'h20003024) +`define CLP_ENTROPY_SRC_REG_ENTROPY_CONTROL (32'h20003028) +`define CLP_ENTROPY_SRC_REG_ENTROPY_DATA (32'h2000302c) +`define CLP_ENTROPY_SRC_REG_HEALTH_TEST_WINDOWS (32'h20003030) +`define CLP_ENTROPY_SRC_REG_REPCNT_THRESHOLDS (32'h20003034) +`define CLP_ENTROPY_SRC_REG_REPCNTS_THRESHOLDS (32'h20003038) +`define CLP_ENTROPY_SRC_REG_ADAPTP_HI_THRESHOLDS (32'h2000303c) +`define CLP_ENTROPY_SRC_REG_ADAPTP_LO_THRESHOLDS (32'h20003040) +`define CLP_ENTROPY_SRC_REG_BUCKET_THRESHOLDS (32'h20003044) +`define CLP_ENTROPY_SRC_REG_MARKOV_HI_THRESHOLDS (32'h20003048) +`define CLP_ENTROPY_SRC_REG_MARKOV_LO_THRESHOLDS (32'h2000304c) +`define CLP_ENTROPY_SRC_REG_EXTHT_HI_THRESHOLDS (32'h20003050) +`define CLP_ENTROPY_SRC_REG_EXTHT_LO_THRESHOLDS (32'h20003054) +`define CLP_ENTROPY_SRC_REG_REPCNT_HI_WATERMARKS (32'h20003058) +`define CLP_ENTROPY_SRC_REG_REPCNTS_HI_WATERMARKS (32'h2000305c) +`define CLP_ENTROPY_SRC_REG_ADAPTP_HI_WATERMARKS (32'h20003060) +`define CLP_ENTROPY_SRC_REG_ADAPTP_LO_WATERMARKS (32'h20003064) +`define CLP_ENTROPY_SRC_REG_EXTHT_HI_WATERMARKS (32'h20003068) +`define CLP_ENTROPY_SRC_REG_EXTHT_LO_WATERMARKS (32'h2000306c) +`define CLP_ENTROPY_SRC_REG_BUCKET_HI_WATERMARKS (32'h20003070) +`define CLP_ENTROPY_SRC_REG_MARKOV_HI_WATERMARKS (32'h20003074) +`define CLP_ENTROPY_SRC_REG_MARKOV_LO_WATERMARKS (32'h20003078) +`define CLP_ENTROPY_SRC_REG_REPCNT_TOTAL_FAILS (32'h2000307c) +`define CLP_ENTROPY_SRC_REG_REPCNTS_TOTAL_FAILS (32'h20003080) +`define CLP_ENTROPY_SRC_REG_ADAPTP_HI_TOTAL_FAILS (32'h20003084) +`define CLP_ENTROPY_SRC_REG_ADAPTP_LO_TOTAL_FAILS (32'h20003088) +`define CLP_ENTROPY_SRC_REG_BUCKET_TOTAL_FAILS (32'h2000308c) +`define CLP_ENTROPY_SRC_REG_MARKOV_HI_TOTAL_FAILS (32'h20003090) +`define CLP_ENTROPY_SRC_REG_MARKOV_LO_TOTAL_FAILS (32'h20003094) +`define CLP_ENTROPY_SRC_REG_EXTHT_HI_TOTAL_FAILS (32'h20003098) +`define CLP_ENTROPY_SRC_REG_EXTHT_LO_TOTAL_FAILS (32'h2000309c) +`define CLP_ENTROPY_SRC_REG_ALERT_THRESHOLD (32'h200030a0) +`define CLP_ENTROPY_SRC_REG_ALERT_SUMMARY_FAIL_COUNTS (32'h200030a4) +`define CLP_ENTROPY_SRC_REG_ALERT_FAIL_COUNTS (32'h200030a8) +`define CLP_ENTROPY_SRC_REG_EXTHT_FAIL_COUNTS (32'h200030ac) +`define CLP_ENTROPY_SRC_REG_FW_OV_CONTROL (32'h200030b0) +`define CLP_ENTROPY_SRC_REG_FW_OV_SHA3_START (32'h200030b4) +`define CLP_ENTROPY_SRC_REG_FW_OV_WR_FIFO_FULL (32'h200030b8) +`define CLP_ENTROPY_SRC_REG_FW_OV_RD_FIFO_OVERFLOW (32'h200030bc) +`define CLP_ENTROPY_SRC_REG_FW_OV_RD_DATA (32'h200030c0) +`define CLP_ENTROPY_SRC_REG_FW_OV_WR_DATA (32'h200030c4) +`define CLP_ENTROPY_SRC_REG_OBSERVE_FIFO_THRESH (32'h200030c8) +`define CLP_ENTROPY_SRC_REG_OBSERVE_FIFO_DEPTH (32'h200030cc) +`define CLP_ENTROPY_SRC_REG_DEBUG_STATUS (32'h200030d0) +`define CLP_ENTROPY_SRC_REG_RECOV_ALERT_STS (32'h200030d4) +`define CLP_ENTROPY_SRC_REG_ERR_CODE (32'h200030d8) +`define CLP_ENTROPY_SRC_REG_ERR_CODE_TEST (32'h200030dc) +`define CLP_ENTROPY_SRC_REG_MAIN_SM_STATE (32'h200030e0) +`define CLP_MBOX_CSR_BASE_ADDR (32'h30020000) +`define CLP_MBOX_CSR_MBOX_LOCK (32'h30020000) +`define CLP_MBOX_CSR_MBOX_USER (32'h30020004) +`define CLP_MBOX_CSR_MBOX_CMD (32'h30020008) +`define CLP_MBOX_CSR_MBOX_DLEN (32'h3002000c) +`define CLP_MBOX_CSR_MBOX_DATAIN (32'h30020010) +`define CLP_MBOX_CSR_MBOX_DATAOUT (32'h30020014) +`define CLP_MBOX_CSR_MBOX_EXECUTE (32'h30020018) +`define CLP_MBOX_CSR_MBOX_STATUS (32'h3002001c) +`define CLP_MBOX_CSR_MBOX_UNLOCK (32'h30020020) +`define CLP_MBOX_CSR_TAP_MODE (32'h30020024) +`define CLP_SHA512_ACC_CSR_BASE_ADDR (32'h30021000) +`define CLP_SHA512_ACC_CSR_LOCK (32'h30021000) +`define CLP_SHA512_ACC_CSR_USER (32'h30021004) +`define CLP_SHA512_ACC_CSR_MODE (32'h30021008) +`define CLP_SHA512_ACC_CSR_START_ADDRESS (32'h3002100c) +`define CLP_SHA512_ACC_CSR_DLEN (32'h30021010) +`define CLP_SHA512_ACC_CSR_DATAIN (32'h30021014) +`define CLP_SHA512_ACC_CSR_EXECUTE (32'h30021018) +`define CLP_SHA512_ACC_CSR_STATUS (32'h3002101c) +`define CLP_SHA512_ACC_CSR_DIGEST_0 (32'h30021020) +`define CLP_SHA512_ACC_CSR_DIGEST_1 (32'h30021024) +`define CLP_SHA512_ACC_CSR_DIGEST_2 (32'h30021028) +`define CLP_SHA512_ACC_CSR_DIGEST_3 (32'h3002102c) +`define CLP_SHA512_ACC_CSR_DIGEST_4 (32'h30021030) +`define CLP_SHA512_ACC_CSR_DIGEST_5 (32'h30021034) +`define CLP_SHA512_ACC_CSR_DIGEST_6 (32'h30021038) +`define CLP_SHA512_ACC_CSR_DIGEST_7 (32'h3002103c) +`define CLP_SHA512_ACC_CSR_DIGEST_8 (32'h30021040) +`define CLP_SHA512_ACC_CSR_DIGEST_9 (32'h30021044) +`define CLP_SHA512_ACC_CSR_DIGEST_10 (32'h30021048) +`define CLP_SHA512_ACC_CSR_DIGEST_11 (32'h3002104c) +`define CLP_SHA512_ACC_CSR_DIGEST_12 (32'h30021050) +`define CLP_SHA512_ACC_CSR_DIGEST_13 (32'h30021054) +`define CLP_SHA512_ACC_CSR_DIGEST_14 (32'h30021058) +`define CLP_SHA512_ACC_CSR_DIGEST_15 (32'h3002105c) +`define CLP_SHA512_ACC_CSR_CONTROL (32'h30021060) +`define CLP_SHA512_ACC_CSR_INTR_BLOCK_RF_START (32'h30021800) +`define CLP_SHA512_ACC_CSR_INTR_BLOCK_RF_GLOBAL_INTR_EN_R (32'h30021800) +`define CLP_SHA512_ACC_CSR_INTR_BLOCK_RF_ERROR_INTR_EN_R (32'h30021804) +`define CLP_SHA512_ACC_CSR_INTR_BLOCK_RF_NOTIF_INTR_EN_R (32'h30021808) +`define CLP_SHA512_ACC_CSR_INTR_BLOCK_RF_ERROR_GLOBAL_INTR_R (32'h3002180c) +`define CLP_SHA512_ACC_CSR_INTR_BLOCK_RF_NOTIF_GLOBAL_INTR_R (32'h30021810) +`define CLP_SHA512_ACC_CSR_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R (32'h30021814) +`define CLP_SHA512_ACC_CSR_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R (32'h30021818) +`define CLP_SHA512_ACC_CSR_INTR_BLOCK_RF_ERROR_INTR_TRIG_R (32'h3002181c) +`define CLP_SHA512_ACC_CSR_INTR_BLOCK_RF_NOTIF_INTR_TRIG_R (32'h30021820) +`define CLP_SHA512_ACC_CSR_INTR_BLOCK_RF_ERROR0_INTR_COUNT_R (32'h30021900) +`define CLP_SHA512_ACC_CSR_INTR_BLOCK_RF_ERROR1_INTR_COUNT_R (32'h30021904) +`define CLP_SHA512_ACC_CSR_INTR_BLOCK_RF_ERROR2_INTR_COUNT_R (32'h30021908) +`define CLP_SHA512_ACC_CSR_INTR_BLOCK_RF_ERROR3_INTR_COUNT_R (32'h3002190c) +`define CLP_SHA512_ACC_CSR_INTR_BLOCK_RF_NOTIF_CMD_DONE_INTR_COUNT_R (32'h30021980) +`define CLP_SHA512_ACC_CSR_INTR_BLOCK_RF_ERROR0_INTR_COUNT_INCR_R (32'h30021a00) +`define CLP_SHA512_ACC_CSR_INTR_BLOCK_RF_ERROR1_INTR_COUNT_INCR_R (32'h30021a04) +`define CLP_SHA512_ACC_CSR_INTR_BLOCK_RF_ERROR2_INTR_COUNT_INCR_R (32'h30021a08) +`define CLP_SHA512_ACC_CSR_INTR_BLOCK_RF_ERROR3_INTR_COUNT_INCR_R (32'h30021a0c) +`define CLP_SHA512_ACC_CSR_INTR_BLOCK_RF_NOTIF_CMD_DONE_INTR_COUNT_INCR_R (32'h30021a10) +`define CLP_AXI_DMA_REG_BASE_ADDR (32'h30022000) +`define CLP_AXI_DMA_REG_ID (32'h30022000) +`define CLP_AXI_DMA_REG_CAP (32'h30022004) +`define CLP_AXI_DMA_REG_CTRL (32'h30022008) +`define CLP_AXI_DMA_REG_STATUS0 (32'h3002200c) +`define CLP_AXI_DMA_REG_STATUS1 (32'h30022010) +`define CLP_AXI_DMA_REG_SRC_ADDR_L (32'h30022014) +`define CLP_AXI_DMA_REG_SRC_ADDR_H (32'h30022018) +`define CLP_AXI_DMA_REG_DST_ADDR_L (32'h3002201c) +`define CLP_AXI_DMA_REG_DST_ADDR_H (32'h30022020) +`define CLP_AXI_DMA_REG_BYTE_COUNT (32'h30022024) +`define CLP_AXI_DMA_REG_BLOCK_SIZE (32'h30022028) +`define CLP_AXI_DMA_REG_WRITE_DATA (32'h3002202c) +`define CLP_AXI_DMA_REG_READ_DATA (32'h30022030) +`define CLP_AXI_DMA_REG_INTR_BLOCK_RF_START (32'h30022800) +`define CLP_AXI_DMA_REG_INTR_BLOCK_RF_GLOBAL_INTR_EN_R (32'h30022800) +`define CLP_AXI_DMA_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R (32'h30022804) +`define CLP_AXI_DMA_REG_INTR_BLOCK_RF_NOTIF_INTR_EN_R (32'h30022808) +`define CLP_AXI_DMA_REG_INTR_BLOCK_RF_ERROR_GLOBAL_INTR_R (32'h3002280c) +`define CLP_AXI_DMA_REG_INTR_BLOCK_RF_NOTIF_GLOBAL_INTR_R (32'h30022810) +`define CLP_AXI_DMA_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R (32'h30022814) +`define CLP_AXI_DMA_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R (32'h30022818) +`define CLP_AXI_DMA_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R (32'h3002281c) +`define CLP_AXI_DMA_REG_INTR_BLOCK_RF_NOTIF_INTR_TRIG_R (32'h30022820) +`define CLP_AXI_DMA_REG_INTR_BLOCK_RF_ERROR_CMD_DEC_INTR_COUNT_R (32'h30022900) +`define CLP_AXI_DMA_REG_INTR_BLOCK_RF_ERROR_AXI_RD_INTR_COUNT_R (32'h30022904) +`define CLP_AXI_DMA_REG_INTR_BLOCK_RF_ERROR_AXI_WR_INTR_COUNT_R (32'h30022908) +`define CLP_AXI_DMA_REG_INTR_BLOCK_RF_ERROR_MBOX_LOCK_INTR_COUNT_R (32'h3002290c) +`define CLP_AXI_DMA_REG_INTR_BLOCK_RF_ERROR_SHA_LOCK_INTR_COUNT_R (32'h30022910) +`define CLP_AXI_DMA_REG_INTR_BLOCK_RF_ERROR_FIFO_OFLOW_INTR_COUNT_R (32'h30022914) +`define CLP_AXI_DMA_REG_INTR_BLOCK_RF_ERROR_FIFO_UFLOW_INTR_COUNT_R (32'h30022918) +`define CLP_AXI_DMA_REG_INTR_BLOCK_RF_ERROR_AES_CIF_INTR_COUNT_R (32'h3002291c) +`define CLP_AXI_DMA_REG_INTR_BLOCK_RF_ERROR_KV_RD_INTR_COUNT_R (32'h30022920) +`define CLP_AXI_DMA_REG_INTR_BLOCK_RF_ERROR_KV_RD_LARGE_INTR_COUNT_R (32'h30022924) +`define CLP_AXI_DMA_REG_INTR_BLOCK_RF_NOTIF_TXN_DONE_INTR_COUNT_R (32'h30022980) +`define CLP_AXI_DMA_REG_INTR_BLOCK_RF_NOTIF_FIFO_EMPTY_INTR_COUNT_R (32'h30022984) +`define CLP_AXI_DMA_REG_INTR_BLOCK_RF_NOTIF_FIFO_NOT_EMPTY_INTR_COUNT_R (32'h30022988) +`define CLP_AXI_DMA_REG_INTR_BLOCK_RF_NOTIF_FIFO_FULL_INTR_COUNT_R (32'h3002298c) +`define CLP_AXI_DMA_REG_INTR_BLOCK_RF_NOTIF_FIFO_NOT_FULL_INTR_COUNT_R (32'h30022990) +`define CLP_AXI_DMA_REG_INTR_BLOCK_RF_ERROR_CMD_DEC_INTR_COUNT_INCR_R (32'h30022a00) +`define CLP_AXI_DMA_REG_INTR_BLOCK_RF_ERROR_AXI_RD_INTR_COUNT_INCR_R (32'h30022a04) +`define CLP_AXI_DMA_REG_INTR_BLOCK_RF_ERROR_AXI_WR_INTR_COUNT_INCR_R (32'h30022a08) +`define CLP_AXI_DMA_REG_INTR_BLOCK_RF_ERROR_MBOX_LOCK_INTR_COUNT_INCR_R (32'h30022a0c) +`define CLP_AXI_DMA_REG_INTR_BLOCK_RF_ERROR_SHA_LOCK_INTR_COUNT_INCR_R (32'h30022a10) +`define CLP_AXI_DMA_REG_INTR_BLOCK_RF_ERROR_FIFO_OFLOW_INTR_COUNT_INCR_R (32'h30022a14) +`define CLP_AXI_DMA_REG_INTR_BLOCK_RF_ERROR_FIFO_UFLOW_INTR_COUNT_INCR_R (32'h30022a18) +`define CLP_AXI_DMA_REG_INTR_BLOCK_RF_ERROR_AES_CIF_INTR_COUNT_INCR_R (32'h30022a1c) +`define CLP_AXI_DMA_REG_INTR_BLOCK_RF_ERROR_KV_RD_INTR_COUNT_INCR_R (32'h30022a20) +`define CLP_AXI_DMA_REG_INTR_BLOCK_RF_ERROR_KV_RD_LARGE_INTR_COUNT_INCR_R (32'h30022a24) +`define CLP_AXI_DMA_REG_INTR_BLOCK_RF_NOTIF_TXN_DONE_INTR_COUNT_INCR_R (32'h30022a28) +`define CLP_AXI_DMA_REG_INTR_BLOCK_RF_NOTIF_FIFO_EMPTY_INTR_COUNT_INCR_R (32'h30022a2c) +`define CLP_AXI_DMA_REG_INTR_BLOCK_RF_NOTIF_FIFO_NOT_EMPTY_INTR_COUNT_INCR_R (32'h30022a30) +`define CLP_AXI_DMA_REG_INTR_BLOCK_RF_NOTIF_FIFO_FULL_INTR_COUNT_INCR_R (32'h30022a34) +`define CLP_AXI_DMA_REG_INTR_BLOCK_RF_NOTIF_FIFO_NOT_FULL_INTR_COUNT_INCR_R (32'h30022a38) +`define CLP_SOC_IFC_REG_BASE_ADDR (32'h30030000) +`define CLP_SOC_IFC_REG_CPTRA_HW_ERROR_FATAL (32'h30030000) +`define CLP_SOC_IFC_REG_CPTRA_HW_ERROR_NON_FATAL (32'h30030004) +`define CLP_SOC_IFC_REG_CPTRA_FW_ERROR_FATAL (32'h30030008) +`define CLP_SOC_IFC_REG_CPTRA_FW_ERROR_NON_FATAL (32'h3003000c) +`define CLP_SOC_IFC_REG_CPTRA_HW_ERROR_ENC (32'h30030010) +`define CLP_SOC_IFC_REG_CPTRA_FW_ERROR_ENC (32'h30030014) +`define CLP_SOC_IFC_REG_CPTRA_FW_EXTENDED_ERROR_INFO_0 (32'h30030018) +`define CLP_SOC_IFC_REG_CPTRA_FW_EXTENDED_ERROR_INFO_1 (32'h3003001c) +`define CLP_SOC_IFC_REG_CPTRA_FW_EXTENDED_ERROR_INFO_2 (32'h30030020) +`define CLP_SOC_IFC_REG_CPTRA_FW_EXTENDED_ERROR_INFO_3 (32'h30030024) +`define CLP_SOC_IFC_REG_CPTRA_FW_EXTENDED_ERROR_INFO_4 (32'h30030028) +`define CLP_SOC_IFC_REG_CPTRA_FW_EXTENDED_ERROR_INFO_5 (32'h3003002c) +`define CLP_SOC_IFC_REG_CPTRA_FW_EXTENDED_ERROR_INFO_6 (32'h30030030) +`define CLP_SOC_IFC_REG_CPTRA_FW_EXTENDED_ERROR_INFO_7 (32'h30030034) +`define CLP_SOC_IFC_REG_CPTRA_BOOT_STATUS (32'h30030038) +`define CLP_SOC_IFC_REG_CPTRA_FLOW_STATUS (32'h3003003c) +`define CLP_SOC_IFC_REG_CPTRA_RESET_REASON (32'h30030040) +`define CLP_SOC_IFC_REG_CPTRA_SECURITY_STATE (32'h30030044) +`define CLP_SOC_IFC_REG_CPTRA_MBOX_VALID_AXI_USER_0 (32'h30030048) +`define CLP_SOC_IFC_REG_CPTRA_MBOX_VALID_AXI_USER_1 (32'h3003004c) +`define CLP_SOC_IFC_REG_CPTRA_MBOX_VALID_AXI_USER_2 (32'h30030050) +`define CLP_SOC_IFC_REG_CPTRA_MBOX_VALID_AXI_USER_3 (32'h30030054) +`define CLP_SOC_IFC_REG_CPTRA_MBOX_VALID_AXI_USER_4 (32'h30030058) +`define CLP_SOC_IFC_REG_CPTRA_MBOX_AXI_USER_LOCK_0 (32'h3003005c) +`define CLP_SOC_IFC_REG_CPTRA_MBOX_AXI_USER_LOCK_1 (32'h30030060) +`define CLP_SOC_IFC_REG_CPTRA_MBOX_AXI_USER_LOCK_2 (32'h30030064) +`define CLP_SOC_IFC_REG_CPTRA_MBOX_AXI_USER_LOCK_3 (32'h30030068) +`define CLP_SOC_IFC_REG_CPTRA_MBOX_AXI_USER_LOCK_4 (32'h3003006c) +`define CLP_SOC_IFC_REG_CPTRA_TRNG_VALID_AXI_USER (32'h30030070) +`define CLP_SOC_IFC_REG_CPTRA_TRNG_AXI_USER_LOCK (32'h30030074) +`define CLP_SOC_IFC_REG_CPTRA_TRNG_DATA_0 (32'h30030078) +`define CLP_SOC_IFC_REG_CPTRA_TRNG_DATA_1 (32'h3003007c) +`define CLP_SOC_IFC_REG_CPTRA_TRNG_DATA_2 (32'h30030080) +`define CLP_SOC_IFC_REG_CPTRA_TRNG_DATA_3 (32'h30030084) +`define CLP_SOC_IFC_REG_CPTRA_TRNG_DATA_4 (32'h30030088) +`define CLP_SOC_IFC_REG_CPTRA_TRNG_DATA_5 (32'h3003008c) +`define CLP_SOC_IFC_REG_CPTRA_TRNG_DATA_6 (32'h30030090) +`define CLP_SOC_IFC_REG_CPTRA_TRNG_DATA_7 (32'h30030094) +`define CLP_SOC_IFC_REG_CPTRA_TRNG_DATA_8 (32'h30030098) +`define CLP_SOC_IFC_REG_CPTRA_TRNG_DATA_9 (32'h3003009c) +`define CLP_SOC_IFC_REG_CPTRA_TRNG_DATA_10 (32'h300300a0) +`define CLP_SOC_IFC_REG_CPTRA_TRNG_DATA_11 (32'h300300a4) +`define CLP_SOC_IFC_REG_CPTRA_TRNG_CTRL (32'h300300a8) +`define CLP_SOC_IFC_REG_CPTRA_TRNG_STATUS (32'h300300ac) +`define CLP_SOC_IFC_REG_CPTRA_FUSE_WR_DONE (32'h300300b0) +`define CLP_SOC_IFC_REG_CPTRA_TIMER_CONFIG (32'h300300b4) +`define CLP_SOC_IFC_REG_CPTRA_BOOTFSM_GO (32'h300300b8) +`define CLP_SOC_IFC_REG_CPTRA_DBG_MANUF_SERVICE_REG (32'h300300bc) +`define CLP_SOC_IFC_REG_CPTRA_CLK_GATING_EN (32'h300300c0) +`define CLP_SOC_IFC_REG_CPTRA_GENERIC_INPUT_WIRES_0 (32'h300300c4) +`define CLP_SOC_IFC_REG_CPTRA_GENERIC_INPUT_WIRES_1 (32'h300300c8) +`define CLP_SOC_IFC_REG_CPTRA_GENERIC_OUTPUT_WIRES_0 (32'h300300cc) +`define CLP_SOC_IFC_REG_CPTRA_GENERIC_OUTPUT_WIRES_1 (32'h300300d0) +`define CLP_SOC_IFC_REG_CPTRA_HW_REV_ID (32'h300300d4) +`define CLP_SOC_IFC_REG_CPTRA_FW_REV_ID_0 (32'h300300d8) +`define CLP_SOC_IFC_REG_CPTRA_FW_REV_ID_1 (32'h300300dc) +`define CLP_SOC_IFC_REG_CPTRA_HW_CONFIG (32'h300300e0) +`define CLP_SOC_IFC_REG_CPTRA_WDT_TIMER1_EN (32'h300300e4) +`define CLP_SOC_IFC_REG_CPTRA_WDT_TIMER1_CTRL (32'h300300e8) +`define CLP_SOC_IFC_REG_CPTRA_WDT_TIMER1_TIMEOUT_PERIOD_0 (32'h300300ec) +`define CLP_SOC_IFC_REG_CPTRA_WDT_TIMER1_TIMEOUT_PERIOD_1 (32'h300300f0) +`define CLP_SOC_IFC_REG_CPTRA_WDT_TIMER2_EN (32'h300300f4) +`define CLP_SOC_IFC_REG_CPTRA_WDT_TIMER2_CTRL (32'h300300f8) +`define CLP_SOC_IFC_REG_CPTRA_WDT_TIMER2_TIMEOUT_PERIOD_0 (32'h300300fc) +`define CLP_SOC_IFC_REG_CPTRA_WDT_TIMER2_TIMEOUT_PERIOD_1 (32'h30030100) +`define CLP_SOC_IFC_REG_CPTRA_WDT_STATUS (32'h30030104) +`define CLP_SOC_IFC_REG_CPTRA_FUSE_VALID_AXI_USER (32'h30030108) +`define CLP_SOC_IFC_REG_CPTRA_FUSE_AXI_USER_LOCK (32'h3003010c) +`define CLP_SOC_IFC_REG_CPTRA_WDT_CFG_0 (32'h30030110) +`define CLP_SOC_IFC_REG_CPTRA_WDT_CFG_1 (32'h30030114) +`define CLP_SOC_IFC_REG_CPTRA_ITRNG_ENTROPY_CONFIG_0 (32'h30030118) +`define CLP_SOC_IFC_REG_CPTRA_ITRNG_ENTROPY_CONFIG_1 (32'h3003011c) +`define CLP_SOC_IFC_REG_CPTRA_RSVD_REG_0 (32'h30030120) +`define CLP_SOC_IFC_REG_CPTRA_RSVD_REG_1 (32'h30030124) +`define CLP_SOC_IFC_REG_CPTRA_HW_CAPABILITIES (32'h30030128) +`define CLP_SOC_IFC_REG_CPTRA_FW_CAPABILITIES (32'h3003012c) +`define CLP_SOC_IFC_REG_CPTRA_CAP_LOCK (32'h30030130) +`define CLP_SOC_IFC_REG_CPTRA_OWNER_PK_HASH_0 (32'h30030140) +`define CLP_SOC_IFC_REG_CPTRA_OWNER_PK_HASH_1 (32'h30030144) +`define CLP_SOC_IFC_REG_CPTRA_OWNER_PK_HASH_2 (32'h30030148) +`define CLP_SOC_IFC_REG_CPTRA_OWNER_PK_HASH_3 (32'h3003014c) +`define CLP_SOC_IFC_REG_CPTRA_OWNER_PK_HASH_4 (32'h30030150) +`define CLP_SOC_IFC_REG_CPTRA_OWNER_PK_HASH_5 (32'h30030154) +`define CLP_SOC_IFC_REG_CPTRA_OWNER_PK_HASH_6 (32'h30030158) +`define CLP_SOC_IFC_REG_CPTRA_OWNER_PK_HASH_7 (32'h3003015c) +`define CLP_SOC_IFC_REG_CPTRA_OWNER_PK_HASH_8 (32'h30030160) +`define CLP_SOC_IFC_REG_CPTRA_OWNER_PK_HASH_9 (32'h30030164) +`define CLP_SOC_IFC_REG_CPTRA_OWNER_PK_HASH_10 (32'h30030168) +`define CLP_SOC_IFC_REG_CPTRA_OWNER_PK_HASH_11 (32'h3003016c) +`define CLP_SOC_IFC_REG_CPTRA_OWNER_PK_HASH_LOCK (32'h30030170) +`define CLP_SOC_IFC_REG_FUSE_UDS_SEED_0 (32'h30030200) +`define CLP_SOC_IFC_REG_FUSE_UDS_SEED_1 (32'h30030204) +`define CLP_SOC_IFC_REG_FUSE_UDS_SEED_2 (32'h30030208) +`define CLP_SOC_IFC_REG_FUSE_UDS_SEED_3 (32'h3003020c) +`define CLP_SOC_IFC_REG_FUSE_UDS_SEED_4 (32'h30030210) +`define CLP_SOC_IFC_REG_FUSE_UDS_SEED_5 (32'h30030214) +`define CLP_SOC_IFC_REG_FUSE_UDS_SEED_6 (32'h30030218) +`define CLP_SOC_IFC_REG_FUSE_UDS_SEED_7 (32'h3003021c) +`define CLP_SOC_IFC_REG_FUSE_UDS_SEED_8 (32'h30030220) +`define CLP_SOC_IFC_REG_FUSE_UDS_SEED_9 (32'h30030224) +`define CLP_SOC_IFC_REG_FUSE_UDS_SEED_10 (32'h30030228) +`define CLP_SOC_IFC_REG_FUSE_UDS_SEED_11 (32'h3003022c) +`define CLP_SOC_IFC_REG_FUSE_UDS_SEED_12 (32'h30030230) +`define CLP_SOC_IFC_REG_FUSE_UDS_SEED_13 (32'h30030234) +`define CLP_SOC_IFC_REG_FUSE_UDS_SEED_14 (32'h30030238) +`define CLP_SOC_IFC_REG_FUSE_UDS_SEED_15 (32'h3003023c) +`define CLP_SOC_IFC_REG_FUSE_FIELD_ENTROPY_0 (32'h30030240) +`define CLP_SOC_IFC_REG_FUSE_FIELD_ENTROPY_1 (32'h30030244) +`define CLP_SOC_IFC_REG_FUSE_FIELD_ENTROPY_2 (32'h30030248) +`define CLP_SOC_IFC_REG_FUSE_FIELD_ENTROPY_3 (32'h3003024c) +`define CLP_SOC_IFC_REG_FUSE_FIELD_ENTROPY_4 (32'h30030250) +`define CLP_SOC_IFC_REG_FUSE_FIELD_ENTROPY_5 (32'h30030254) +`define CLP_SOC_IFC_REG_FUSE_FIELD_ENTROPY_6 (32'h30030258) +`define CLP_SOC_IFC_REG_FUSE_FIELD_ENTROPY_7 (32'h3003025c) +`define CLP_SOC_IFC_REG_FUSE_VENDOR_PK_HASH_0 (32'h30030260) +`define CLP_SOC_IFC_REG_FUSE_VENDOR_PK_HASH_1 (32'h30030264) +`define CLP_SOC_IFC_REG_FUSE_VENDOR_PK_HASH_2 (32'h30030268) +`define CLP_SOC_IFC_REG_FUSE_VENDOR_PK_HASH_3 (32'h3003026c) +`define CLP_SOC_IFC_REG_FUSE_VENDOR_PK_HASH_4 (32'h30030270) +`define CLP_SOC_IFC_REG_FUSE_VENDOR_PK_HASH_5 (32'h30030274) +`define CLP_SOC_IFC_REG_FUSE_VENDOR_PK_HASH_6 (32'h30030278) +`define CLP_SOC_IFC_REG_FUSE_VENDOR_PK_HASH_7 (32'h3003027c) +`define CLP_SOC_IFC_REG_FUSE_VENDOR_PK_HASH_8 (32'h30030280) +`define CLP_SOC_IFC_REG_FUSE_VENDOR_PK_HASH_9 (32'h30030284) +`define CLP_SOC_IFC_REG_FUSE_VENDOR_PK_HASH_10 (32'h30030288) +`define CLP_SOC_IFC_REG_FUSE_VENDOR_PK_HASH_11 (32'h3003028c) +`define CLP_SOC_IFC_REG_FUSE_ECC_REVOCATION (32'h30030290) +`define CLP_SOC_IFC_REG_FUSE_FMC_KEY_MANIFEST_SVN (32'h300302b4) +`define CLP_SOC_IFC_REG_FUSE_RUNTIME_SVN_0 (32'h300302b8) +`define CLP_SOC_IFC_REG_FUSE_RUNTIME_SVN_1 (32'h300302bc) +`define CLP_SOC_IFC_REG_FUSE_RUNTIME_SVN_2 (32'h300302c0) +`define CLP_SOC_IFC_REG_FUSE_RUNTIME_SVN_3 (32'h300302c4) +`define CLP_SOC_IFC_REG_FUSE_ANTI_ROLLBACK_DISABLE (32'h300302c8) +`define CLP_SOC_IFC_REG_FUSE_IDEVID_CERT_ATTR_0 (32'h300302cc) +`define CLP_SOC_IFC_REG_FUSE_IDEVID_CERT_ATTR_1 (32'h300302d0) +`define CLP_SOC_IFC_REG_FUSE_IDEVID_CERT_ATTR_2 (32'h300302d4) +`define CLP_SOC_IFC_REG_FUSE_IDEVID_CERT_ATTR_3 (32'h300302d8) +`define CLP_SOC_IFC_REG_FUSE_IDEVID_CERT_ATTR_4 (32'h300302dc) +`define CLP_SOC_IFC_REG_FUSE_IDEVID_CERT_ATTR_5 (32'h300302e0) +`define CLP_SOC_IFC_REG_FUSE_IDEVID_CERT_ATTR_6 (32'h300302e4) +`define CLP_SOC_IFC_REG_FUSE_IDEVID_CERT_ATTR_7 (32'h300302e8) +`define CLP_SOC_IFC_REG_FUSE_IDEVID_CERT_ATTR_8 (32'h300302ec) +`define CLP_SOC_IFC_REG_FUSE_IDEVID_CERT_ATTR_9 (32'h300302f0) +`define CLP_SOC_IFC_REG_FUSE_IDEVID_CERT_ATTR_10 (32'h300302f4) +`define CLP_SOC_IFC_REG_FUSE_IDEVID_CERT_ATTR_11 (32'h300302f8) +`define CLP_SOC_IFC_REG_FUSE_IDEVID_CERT_ATTR_12 (32'h300302fc) +`define CLP_SOC_IFC_REG_FUSE_IDEVID_CERT_ATTR_13 (32'h30030300) +`define CLP_SOC_IFC_REG_FUSE_IDEVID_CERT_ATTR_14 (32'h30030304) +`define CLP_SOC_IFC_REG_FUSE_IDEVID_CERT_ATTR_15 (32'h30030308) +`define CLP_SOC_IFC_REG_FUSE_IDEVID_CERT_ATTR_16 (32'h3003030c) +`define CLP_SOC_IFC_REG_FUSE_IDEVID_CERT_ATTR_17 (32'h30030310) +`define CLP_SOC_IFC_REG_FUSE_IDEVID_CERT_ATTR_18 (32'h30030314) +`define CLP_SOC_IFC_REG_FUSE_IDEVID_CERT_ATTR_19 (32'h30030318) +`define CLP_SOC_IFC_REG_FUSE_IDEVID_CERT_ATTR_20 (32'h3003031c) +`define CLP_SOC_IFC_REG_FUSE_IDEVID_CERT_ATTR_21 (32'h30030320) +`define CLP_SOC_IFC_REG_FUSE_IDEVID_CERT_ATTR_22 (32'h30030324) +`define CLP_SOC_IFC_REG_FUSE_IDEVID_CERT_ATTR_23 (32'h30030328) +`define CLP_SOC_IFC_REG_FUSE_IDEVID_MANUF_HSM_ID_0 (32'h3003032c) +`define CLP_SOC_IFC_REG_FUSE_IDEVID_MANUF_HSM_ID_1 (32'h30030330) +`define CLP_SOC_IFC_REG_FUSE_IDEVID_MANUF_HSM_ID_2 (32'h30030334) +`define CLP_SOC_IFC_REG_FUSE_IDEVID_MANUF_HSM_ID_3 (32'h30030338) +`define CLP_SOC_IFC_REG_FUSE_LMS_REVOCATION (32'h30030340) +`define CLP_SOC_IFC_REG_FUSE_MLDSA_REVOCATION (32'h30030344) +`define CLP_SOC_IFC_REG_FUSE_SOC_STEPPING_ID (32'h30030348) +`define CLP_SOC_IFC_REG_FUSE_MANUF_DBG_UNLOCK_TOKEN_0 (32'h3003034c) +`define CLP_SOC_IFC_REG_FUSE_MANUF_DBG_UNLOCK_TOKEN_1 (32'h30030350) +`define CLP_SOC_IFC_REG_FUSE_MANUF_DBG_UNLOCK_TOKEN_2 (32'h30030354) +`define CLP_SOC_IFC_REG_FUSE_MANUF_DBG_UNLOCK_TOKEN_3 (32'h30030358) +`define CLP_SOC_IFC_REG_FUSE_MANUF_DBG_UNLOCK_TOKEN_4 (32'h3003035c) +`define CLP_SOC_IFC_REG_FUSE_MANUF_DBG_UNLOCK_TOKEN_5 (32'h30030360) +`define CLP_SOC_IFC_REG_FUSE_MANUF_DBG_UNLOCK_TOKEN_6 (32'h30030364) +`define CLP_SOC_IFC_REG_FUSE_MANUF_DBG_UNLOCK_TOKEN_7 (32'h30030368) +`define CLP_SOC_IFC_REG_FUSE_MANUF_DBG_UNLOCK_TOKEN_8 (32'h3003036c) +`define CLP_SOC_IFC_REG_FUSE_MANUF_DBG_UNLOCK_TOKEN_9 (32'h30030370) +`define CLP_SOC_IFC_REG_FUSE_MANUF_DBG_UNLOCK_TOKEN_10 (32'h30030374) +`define CLP_SOC_IFC_REG_FUSE_MANUF_DBG_UNLOCK_TOKEN_11 (32'h30030378) +`define CLP_SOC_IFC_REG_FUSE_MANUF_DBG_UNLOCK_TOKEN_12 (32'h3003037c) +`define CLP_SOC_IFC_REG_FUSE_MANUF_DBG_UNLOCK_TOKEN_13 (32'h30030380) +`define CLP_SOC_IFC_REG_FUSE_MANUF_DBG_UNLOCK_TOKEN_14 (32'h30030384) +`define CLP_SOC_IFC_REG_FUSE_MANUF_DBG_UNLOCK_TOKEN_15 (32'h30030388) +`define CLP_SOC_IFC_REG_FUSE_PQC_KEY_TYPE (32'h3003038c) +`define CLP_SOC_IFC_REG_FUSE_SOC_MANIFEST_SVN_0 (32'h30030390) +`define CLP_SOC_IFC_REG_FUSE_SOC_MANIFEST_SVN_1 (32'h30030394) +`define CLP_SOC_IFC_REG_FUSE_SOC_MANIFEST_SVN_2 (32'h30030398) +`define CLP_SOC_IFC_REG_FUSE_SOC_MANIFEST_SVN_3 (32'h3003039c) +`define CLP_SOC_IFC_REG_FUSE_SOC_MANIFEST_MAX_SVN (32'h300303a0) +`define CLP_SOC_IFC_REG_FUSE_HEK_SEED_0 (32'h300303c0) +`define CLP_SOC_IFC_REG_FUSE_HEK_SEED_1 (32'h300303c4) +`define CLP_SOC_IFC_REG_FUSE_HEK_SEED_2 (32'h300303c8) +`define CLP_SOC_IFC_REG_FUSE_HEK_SEED_3 (32'h300303cc) +`define CLP_SOC_IFC_REG_FUSE_HEK_SEED_4 (32'h300303d0) +`define CLP_SOC_IFC_REG_FUSE_HEK_SEED_5 (32'h300303d4) +`define CLP_SOC_IFC_REG_FUSE_HEK_SEED_6 (32'h300303d8) +`define CLP_SOC_IFC_REG_FUSE_HEK_SEED_7 (32'h300303dc) +`define CLP_SOC_IFC_REG_SS_CALIPTRA_BASE_ADDR_L (32'h30030500) +`define CLP_SOC_IFC_REG_SS_CALIPTRA_BASE_ADDR_H (32'h30030504) +`define CLP_SOC_IFC_REG_SS_MCI_BASE_ADDR_L (32'h30030508) +`define CLP_SOC_IFC_REG_SS_MCI_BASE_ADDR_H (32'h3003050c) +`define CLP_SOC_IFC_REG_SS_RECOVERY_IFC_BASE_ADDR_L (32'h30030510) +`define CLP_SOC_IFC_REG_SS_RECOVERY_IFC_BASE_ADDR_H (32'h30030514) +`define CLP_SOC_IFC_REG_SS_OTP_FC_BASE_ADDR_L (32'h30030518) +`define CLP_SOC_IFC_REG_SS_OTP_FC_BASE_ADDR_H (32'h3003051c) +`define CLP_SOC_IFC_REG_SS_UDS_SEED_BASE_ADDR_L (32'h30030520) +`define CLP_SOC_IFC_REG_SS_UDS_SEED_BASE_ADDR_H (32'h30030524) +`define CLP_SOC_IFC_REG_SS_PROD_DEBUG_UNLOCK_AUTH_PK_HASH_REG_BANK_OFFSET (32'h30030528) +`define CLP_SOC_IFC_REG_SS_NUM_OF_PROD_DEBUG_UNLOCK_AUTH_PK_HASHES (32'h3003052c) +`define CLP_SOC_IFC_REG_SS_DEBUG_INTENT (32'h30030530) +`define CLP_SOC_IFC_REG_SS_CALIPTRA_DMA_AXI_USER (32'h30030534) +`define CLP_SOC_IFC_REG_SS_EXTERNAL_STAGING_AREA_BASE_ADDR_L (32'h30030538) +`define CLP_SOC_IFC_REG_SS_EXTERNAL_STAGING_AREA_BASE_ADDR_H (32'h3003053c) +`define CLP_SOC_IFC_REG_SS_KEY_RELEASE_BASE_ADDR_L (32'h30030540) +`define CLP_SOC_IFC_REG_SS_KEY_RELEASE_BASE_ADDR_H (32'h30030544) +`define CLP_SOC_IFC_REG_SS_KEY_RELEASE_SIZE (32'h30030548) +`define CLP_SOC_IFC_REG_SS_OCP_LOCK_CTRL (32'h3003054c) +`define CLP_SOC_IFC_REG_SS_STRAP_GENERIC_0 (32'h300305a0) +`define CLP_SOC_IFC_REG_SS_STRAP_GENERIC_1 (32'h300305a4) +`define CLP_SOC_IFC_REG_SS_STRAP_GENERIC_2 (32'h300305a8) +`define CLP_SOC_IFC_REG_SS_STRAP_GENERIC_3 (32'h300305ac) +`define CLP_SOC_IFC_REG_SS_DBG_SERVICE_REG_REQ (32'h300305c0) +`define CLP_SOC_IFC_REG_SS_DBG_SERVICE_REG_RSP (32'h300305c4) +`define CLP_SOC_IFC_REG_SS_SOC_DBG_UNLOCK_LEVEL_0 (32'h300305c8) +`define CLP_SOC_IFC_REG_SS_SOC_DBG_UNLOCK_LEVEL_1 (32'h300305cc) +`define CLP_SOC_IFC_REG_SS_GENERIC_FW_EXEC_CTRL_0 (32'h300305d0) +`define CLP_SOC_IFC_REG_SS_GENERIC_FW_EXEC_CTRL_1 (32'h300305d4) +`define CLP_SOC_IFC_REG_SS_GENERIC_FW_EXEC_CTRL_2 (32'h300305d8) +`define CLP_SOC_IFC_REG_SS_GENERIC_FW_EXEC_CTRL_3 (32'h300305dc) +`define CLP_SOC_IFC_REG_INTERNAL_OBF_KEY_0 (32'h30030600) +`define CLP_SOC_IFC_REG_INTERNAL_OBF_KEY_1 (32'h30030604) +`define CLP_SOC_IFC_REG_INTERNAL_OBF_KEY_2 (32'h30030608) +`define CLP_SOC_IFC_REG_INTERNAL_OBF_KEY_3 (32'h3003060c) +`define CLP_SOC_IFC_REG_INTERNAL_OBF_KEY_4 (32'h30030610) +`define CLP_SOC_IFC_REG_INTERNAL_OBF_KEY_5 (32'h30030614) +`define CLP_SOC_IFC_REG_INTERNAL_OBF_KEY_6 (32'h30030618) +`define CLP_SOC_IFC_REG_INTERNAL_OBF_KEY_7 (32'h3003061c) +`define CLP_SOC_IFC_REG_INTERNAL_ICCM_LOCK (32'h30030620) +`define CLP_SOC_IFC_REG_INTERNAL_FW_UPDATE_RESET (32'h30030624) +`define CLP_SOC_IFC_REG_INTERNAL_FW_UPDATE_RESET_WAIT_CYCLES (32'h30030628) +`define CLP_SOC_IFC_REG_INTERNAL_NMI_VECTOR (32'h3003062c) +`define CLP_SOC_IFC_REG_INTERNAL_HW_ERROR_FATAL_MASK (32'h30030630) +`define CLP_SOC_IFC_REG_INTERNAL_HW_ERROR_NON_FATAL_MASK (32'h30030634) +`define CLP_SOC_IFC_REG_INTERNAL_FW_ERROR_FATAL_MASK (32'h30030638) +`define CLP_SOC_IFC_REG_INTERNAL_FW_ERROR_NON_FATAL_MASK (32'h3003063c) +`define CLP_SOC_IFC_REG_INTERNAL_RV_MTIME_L (32'h30030640) +`define CLP_SOC_IFC_REG_INTERNAL_RV_MTIME_H (32'h30030644) +`define CLP_SOC_IFC_REG_INTERNAL_RV_MTIMECMP_L (32'h30030648) +`define CLP_SOC_IFC_REG_INTERNAL_RV_MTIMECMP_H (32'h3003064c) +`define CLP_SOC_IFC_REG_INTR_BLOCK_RF_START (32'h30030800) +`define CLP_SOC_IFC_REG_INTR_BLOCK_RF_GLOBAL_INTR_EN_R (32'h30030800) +`define CLP_SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R (32'h30030804) +`define CLP_SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_INTR_EN_R (32'h30030808) +`define CLP_SOC_IFC_REG_INTR_BLOCK_RF_ERROR_GLOBAL_INTR_R (32'h3003080c) +`define CLP_SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_GLOBAL_INTR_R (32'h30030810) +`define CLP_SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R (32'h30030814) +`define CLP_SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R (32'h30030818) +`define CLP_SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R (32'h3003081c) +`define CLP_SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_INTR_TRIG_R (32'h30030820) +`define CLP_SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_COUNT_R (32'h30030900) +`define CLP_SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INV_DEV_INTR_COUNT_R (32'h30030904) +`define CLP_SOC_IFC_REG_INTR_BLOCK_RF_ERROR_CMD_FAIL_INTR_COUNT_R (32'h30030908) +`define CLP_SOC_IFC_REG_INTR_BLOCK_RF_ERROR_BAD_FUSE_INTR_COUNT_R (32'h3003090c) +`define CLP_SOC_IFC_REG_INTR_BLOCK_RF_ERROR_ICCM_BLOCKED_INTR_COUNT_R (32'h30030910) +`define CLP_SOC_IFC_REG_INTR_BLOCK_RF_ERROR_MBOX_ECC_UNC_INTR_COUNT_R (32'h30030914) +`define CLP_SOC_IFC_REG_INTR_BLOCK_RF_ERROR_WDT_TIMER1_TIMEOUT_INTR_COUNT_R (32'h30030918) +`define CLP_SOC_IFC_REG_INTR_BLOCK_RF_ERROR_WDT_TIMER2_TIMEOUT_INTR_COUNT_R (32'h3003091c) +`define CLP_SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_CMD_AVAIL_INTR_COUNT_R (32'h30030980) +`define CLP_SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_MBOX_ECC_COR_INTR_COUNT_R (32'h30030984) +`define CLP_SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_DEBUG_LOCKED_INTR_COUNT_R (32'h30030988) +`define CLP_SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_SCAN_MODE_INTR_COUNT_R (32'h3003098c) +`define CLP_SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_SOC_REQ_LOCK_INTR_COUNT_R (32'h30030990) +`define CLP_SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_GEN_IN_TOGGLE_INTR_COUNT_R (32'h30030994) +`define CLP_SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_COUNT_INCR_R (32'h30030a00) +`define CLP_SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INV_DEV_INTR_COUNT_INCR_R (32'h30030a04) +`define CLP_SOC_IFC_REG_INTR_BLOCK_RF_ERROR_CMD_FAIL_INTR_COUNT_INCR_R (32'h30030a08) +`define CLP_SOC_IFC_REG_INTR_BLOCK_RF_ERROR_BAD_FUSE_INTR_COUNT_INCR_R (32'h30030a0c) +`define CLP_SOC_IFC_REG_INTR_BLOCK_RF_ERROR_ICCM_BLOCKED_INTR_COUNT_INCR_R (32'h30030a10) +`define CLP_SOC_IFC_REG_INTR_BLOCK_RF_ERROR_MBOX_ECC_UNC_INTR_COUNT_INCR_R (32'h30030a14) +`define CLP_SOC_IFC_REG_INTR_BLOCK_RF_ERROR_WDT_TIMER1_TIMEOUT_INTR_COUNT_INCR_R (32'h30030a18) +`define CLP_SOC_IFC_REG_INTR_BLOCK_RF_ERROR_WDT_TIMER2_TIMEOUT_INTR_COUNT_INCR_R (32'h30030a1c) +`define CLP_SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_CMD_AVAIL_INTR_COUNT_INCR_R (32'h30030a20) +`define CLP_SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_MBOX_ECC_COR_INTR_COUNT_INCR_R (32'h30030a24) +`define CLP_SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_DEBUG_LOCKED_INTR_COUNT_INCR_R (32'h30030a28) +`define CLP_SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_SCAN_MODE_INTR_COUNT_INCR_R (32'h30030a2c) +`define CLP_SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_SOC_REQ_LOCK_INTR_COUNT_INCR_R (32'h30030a30) +`define CLP_SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_GEN_IN_TOGGLE_INTR_COUNT_INCR_R (32'h30030a34) +`define CLP_MBOX_SRAM_BASE_ADDR (32'h30040000) +`define CLP_MBOX_SRAM_END_ADDR (32'h3007ffff) + + +`endif \ No newline at end of file diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_reg_field_defines.svh b/designs/Caliptra/src/caliptra-rtl/caliptra_reg_field_defines.svh new file mode 100644 index 0000000..7f215ae --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_reg_field_defines.svh @@ -0,0 +1,9646 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +// +`ifndef CALIPTRA_REG_FIELD_DEFINES_HEADER +`define CALIPTRA_REG_FIELD_DEFINES_HEADER + + +`ifndef DOE_REG_DOE_IV_0 +`define DOE_REG_DOE_IV_0 (32'h0) +`endif +`ifndef DOE_REG_DOE_IV_1 +`define DOE_REG_DOE_IV_1 (32'h4) +`endif +`ifndef DOE_REG_DOE_IV_2 +`define DOE_REG_DOE_IV_2 (32'h8) +`endif +`ifndef DOE_REG_DOE_IV_3 +`define DOE_REG_DOE_IV_3 (32'hc) +`endif +`ifndef DOE_REG_DOE_CTRL +`define DOE_REG_DOE_CTRL (32'h10) +`define DOE_REG_DOE_CTRL_CMD_LOW (0) +`define DOE_REG_DOE_CTRL_CMD_MASK (32'h3) +`define DOE_REG_DOE_CTRL_DEST_LOW (2) +`define DOE_REG_DOE_CTRL_DEST_MASK (32'h7c) +`define DOE_REG_DOE_CTRL_CMD_EXT_LOW (7) +`define DOE_REG_DOE_CTRL_CMD_EXT_MASK (32'h180) +`endif +`ifndef DOE_REG_DOE_STATUS +`define DOE_REG_DOE_STATUS (32'h14) +`define DOE_REG_DOE_STATUS_READY_LOW (0) +`define DOE_REG_DOE_STATUS_READY_MASK (32'h1) +`define DOE_REG_DOE_STATUS_VALID_LOW (1) +`define DOE_REG_DOE_STATUS_VALID_MASK (32'h2) +`define DOE_REG_DOE_STATUS_UDS_FLOW_DONE_LOW (2) +`define DOE_REG_DOE_STATUS_UDS_FLOW_DONE_MASK (32'h4) +`define DOE_REG_DOE_STATUS_FE_FLOW_DONE_LOW (3) +`define DOE_REG_DOE_STATUS_FE_FLOW_DONE_MASK (32'h8) +`define DOE_REG_DOE_STATUS_DEOBF_SECRETS_CLEARED_LOW (4) +`define DOE_REG_DOE_STATUS_DEOBF_SECRETS_CLEARED_MASK (32'h10) +`define DOE_REG_DOE_STATUS_HEK_FLOW_DONE_LOW (5) +`define DOE_REG_DOE_STATUS_HEK_FLOW_DONE_MASK (32'h20) +`define DOE_REG_DOE_STATUS_ERROR_LOW (8) +`define DOE_REG_DOE_STATUS_ERROR_MASK (32'h100) +`endif +`ifndef DOE_REG_INTR_BLOCK_RF_GLOBAL_INTR_EN_R +`define DOE_REG_INTR_BLOCK_RF_GLOBAL_INTR_EN_R (32'h800) +`define DOE_REG_INTR_BLOCK_RF_GLOBAL_INTR_EN_R_ERROR_EN_LOW (0) +`define DOE_REG_INTR_BLOCK_RF_GLOBAL_INTR_EN_R_ERROR_EN_MASK (32'h1) +`define DOE_REG_INTR_BLOCK_RF_GLOBAL_INTR_EN_R_NOTIF_EN_LOW (1) +`define DOE_REG_INTR_BLOCK_RF_GLOBAL_INTR_EN_R_NOTIF_EN_MASK (32'h2) +`endif +`ifndef DOE_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R +`define DOE_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R (32'h804) +`define DOE_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R_ERROR0_EN_LOW (0) +`define DOE_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R_ERROR0_EN_MASK (32'h1) +`define DOE_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R_ERROR1_EN_LOW (1) +`define DOE_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R_ERROR1_EN_MASK (32'h2) +`define DOE_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R_ERROR2_EN_LOW (2) +`define DOE_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R_ERROR2_EN_MASK (32'h4) +`define DOE_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R_ERROR3_EN_LOW (3) +`define DOE_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R_ERROR3_EN_MASK (32'h8) +`endif +`ifndef DOE_REG_INTR_BLOCK_RF_NOTIF_INTR_EN_R +`define DOE_REG_INTR_BLOCK_RF_NOTIF_INTR_EN_R (32'h808) +`define DOE_REG_INTR_BLOCK_RF_NOTIF_INTR_EN_R_NOTIF_CMD_DONE_EN_LOW (0) +`define DOE_REG_INTR_BLOCK_RF_NOTIF_INTR_EN_R_NOTIF_CMD_DONE_EN_MASK (32'h1) +`endif +`ifndef DOE_REG_INTR_BLOCK_RF_ERROR_GLOBAL_INTR_R +`define DOE_REG_INTR_BLOCK_RF_ERROR_GLOBAL_INTR_R (32'h80c) +`define DOE_REG_INTR_BLOCK_RF_ERROR_GLOBAL_INTR_R_AGG_STS_LOW (0) +`define DOE_REG_INTR_BLOCK_RF_ERROR_GLOBAL_INTR_R_AGG_STS_MASK (32'h1) +`endif +`ifndef DOE_REG_INTR_BLOCK_RF_NOTIF_GLOBAL_INTR_R +`define DOE_REG_INTR_BLOCK_RF_NOTIF_GLOBAL_INTR_R (32'h810) +`define DOE_REG_INTR_BLOCK_RF_NOTIF_GLOBAL_INTR_R_AGG_STS_LOW (0) +`define DOE_REG_INTR_BLOCK_RF_NOTIF_GLOBAL_INTR_R_AGG_STS_MASK (32'h1) +`endif +`ifndef DOE_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R +`define DOE_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R (32'h814) +`define DOE_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR0_STS_LOW (0) +`define DOE_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR0_STS_MASK (32'h1) +`define DOE_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR1_STS_LOW (1) +`define DOE_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR1_STS_MASK (32'h2) +`define DOE_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR2_STS_LOW (2) +`define DOE_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR2_STS_MASK (32'h4) +`define DOE_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR3_STS_LOW (3) +`define DOE_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR3_STS_MASK (32'h8) +`endif +`ifndef DOE_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R +`define DOE_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R (32'h818) +`define DOE_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_CMD_DONE_STS_LOW (0) +`define DOE_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_CMD_DONE_STS_MASK (32'h1) +`endif +`ifndef DOE_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R +`define DOE_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R (32'h81c) +`define DOE_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R_ERROR0_TRIG_LOW (0) +`define DOE_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R_ERROR0_TRIG_MASK (32'h1) +`define DOE_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R_ERROR1_TRIG_LOW (1) +`define DOE_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R_ERROR1_TRIG_MASK (32'h2) +`define DOE_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R_ERROR2_TRIG_LOW (2) +`define DOE_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R_ERROR2_TRIG_MASK (32'h4) +`define DOE_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R_ERROR3_TRIG_LOW (3) +`define DOE_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R_ERROR3_TRIG_MASK (32'h8) +`endif +`ifndef DOE_REG_INTR_BLOCK_RF_NOTIF_INTR_TRIG_R +`define DOE_REG_INTR_BLOCK_RF_NOTIF_INTR_TRIG_R (32'h820) +`define DOE_REG_INTR_BLOCK_RF_NOTIF_INTR_TRIG_R_NOTIF_CMD_DONE_TRIG_LOW (0) +`define DOE_REG_INTR_BLOCK_RF_NOTIF_INTR_TRIG_R_NOTIF_CMD_DONE_TRIG_MASK (32'h1) +`endif +`ifndef DOE_REG_INTR_BLOCK_RF_ERROR0_INTR_COUNT_R +`define DOE_REG_INTR_BLOCK_RF_ERROR0_INTR_COUNT_R (32'h900) +`endif +`ifndef DOE_REG_INTR_BLOCK_RF_ERROR1_INTR_COUNT_R +`define DOE_REG_INTR_BLOCK_RF_ERROR1_INTR_COUNT_R (32'h904) +`endif +`ifndef DOE_REG_INTR_BLOCK_RF_ERROR2_INTR_COUNT_R +`define DOE_REG_INTR_BLOCK_RF_ERROR2_INTR_COUNT_R (32'h908) +`endif +`ifndef DOE_REG_INTR_BLOCK_RF_ERROR3_INTR_COUNT_R +`define DOE_REG_INTR_BLOCK_RF_ERROR3_INTR_COUNT_R (32'h90c) +`endif +`ifndef DOE_REG_INTR_BLOCK_RF_NOTIF_CMD_DONE_INTR_COUNT_R +`define DOE_REG_INTR_BLOCK_RF_NOTIF_CMD_DONE_INTR_COUNT_R (32'h980) +`endif +`ifndef DOE_REG_INTR_BLOCK_RF_ERROR0_INTR_COUNT_INCR_R +`define DOE_REG_INTR_BLOCK_RF_ERROR0_INTR_COUNT_INCR_R (32'ha00) +`define DOE_REG_INTR_BLOCK_RF_ERROR0_INTR_COUNT_INCR_R_PULSE_LOW (0) +`define DOE_REG_INTR_BLOCK_RF_ERROR0_INTR_COUNT_INCR_R_PULSE_MASK (32'h1) +`endif +`ifndef DOE_REG_INTR_BLOCK_RF_ERROR1_INTR_COUNT_INCR_R +`define DOE_REG_INTR_BLOCK_RF_ERROR1_INTR_COUNT_INCR_R (32'ha04) +`define DOE_REG_INTR_BLOCK_RF_ERROR1_INTR_COUNT_INCR_R_PULSE_LOW (0) +`define DOE_REG_INTR_BLOCK_RF_ERROR1_INTR_COUNT_INCR_R_PULSE_MASK (32'h1) +`endif +`ifndef DOE_REG_INTR_BLOCK_RF_ERROR2_INTR_COUNT_INCR_R +`define DOE_REG_INTR_BLOCK_RF_ERROR2_INTR_COUNT_INCR_R (32'ha08) +`define DOE_REG_INTR_BLOCK_RF_ERROR2_INTR_COUNT_INCR_R_PULSE_LOW (0) +`define DOE_REG_INTR_BLOCK_RF_ERROR2_INTR_COUNT_INCR_R_PULSE_MASK (32'h1) +`endif +`ifndef DOE_REG_INTR_BLOCK_RF_ERROR3_INTR_COUNT_INCR_R +`define DOE_REG_INTR_BLOCK_RF_ERROR3_INTR_COUNT_INCR_R (32'ha0c) +`define DOE_REG_INTR_BLOCK_RF_ERROR3_INTR_COUNT_INCR_R_PULSE_LOW (0) +`define DOE_REG_INTR_BLOCK_RF_ERROR3_INTR_COUNT_INCR_R_PULSE_MASK (32'h1) +`endif +`ifndef DOE_REG_INTR_BLOCK_RF_NOTIF_CMD_DONE_INTR_COUNT_INCR_R +`define DOE_REG_INTR_BLOCK_RF_NOTIF_CMD_DONE_INTR_COUNT_INCR_R (32'ha10) +`define DOE_REG_INTR_BLOCK_RF_NOTIF_CMD_DONE_INTR_COUNT_INCR_R_PULSE_LOW (0) +`define DOE_REG_INTR_BLOCK_RF_NOTIF_CMD_DONE_INTR_COUNT_INCR_R_PULSE_MASK (32'h1) +`endif +`ifndef ECC_REG_ECC_NAME_0 +`define ECC_REG_ECC_NAME_0 (32'h0) +`endif +`ifndef ECC_REG_ECC_NAME_1 +`define ECC_REG_ECC_NAME_1 (32'h4) +`endif +`ifndef ECC_REG_ECC_VERSION_0 +`define ECC_REG_ECC_VERSION_0 (32'h8) +`endif +`ifndef ECC_REG_ECC_VERSION_1 +`define ECC_REG_ECC_VERSION_1 (32'hc) +`endif +`ifndef ECC_REG_ECC_CTRL +`define ECC_REG_ECC_CTRL (32'h10) +`define ECC_REG_ECC_CTRL_CTRL_LOW (0) +`define ECC_REG_ECC_CTRL_CTRL_MASK (32'h3) +`define ECC_REG_ECC_CTRL_ZEROIZE_LOW (2) +`define ECC_REG_ECC_CTRL_ZEROIZE_MASK (32'h4) +`define ECC_REG_ECC_CTRL_PCR_SIGN_LOW (3) +`define ECC_REG_ECC_CTRL_PCR_SIGN_MASK (32'h8) +`define ECC_REG_ECC_CTRL_DH_SHAREDKEY_LOW (4) +`define ECC_REG_ECC_CTRL_DH_SHAREDKEY_MASK (32'h10) +`endif +`ifndef ECC_REG_ECC_STATUS +`define ECC_REG_ECC_STATUS (32'h18) +`define ECC_REG_ECC_STATUS_READY_LOW (0) +`define ECC_REG_ECC_STATUS_READY_MASK (32'h1) +`define ECC_REG_ECC_STATUS_VALID_LOW (1) +`define ECC_REG_ECC_STATUS_VALID_MASK (32'h2) +`endif +`ifndef ECC_REG_ECC_SEED_0 +`define ECC_REG_ECC_SEED_0 (32'h80) +`endif +`ifndef ECC_REG_ECC_SEED_1 +`define ECC_REG_ECC_SEED_1 (32'h84) +`endif +`ifndef ECC_REG_ECC_SEED_2 +`define ECC_REG_ECC_SEED_2 (32'h88) +`endif +`ifndef ECC_REG_ECC_SEED_3 +`define ECC_REG_ECC_SEED_3 (32'h8c) +`endif +`ifndef ECC_REG_ECC_SEED_4 +`define ECC_REG_ECC_SEED_4 (32'h90) +`endif +`ifndef ECC_REG_ECC_SEED_5 +`define ECC_REG_ECC_SEED_5 (32'h94) +`endif +`ifndef ECC_REG_ECC_SEED_6 +`define ECC_REG_ECC_SEED_6 (32'h98) +`endif +`ifndef ECC_REG_ECC_SEED_7 +`define ECC_REG_ECC_SEED_7 (32'h9c) +`endif +`ifndef ECC_REG_ECC_SEED_8 +`define ECC_REG_ECC_SEED_8 (32'ha0) +`endif +`ifndef ECC_REG_ECC_SEED_9 +`define ECC_REG_ECC_SEED_9 (32'ha4) +`endif +`ifndef ECC_REG_ECC_SEED_10 +`define ECC_REG_ECC_SEED_10 (32'ha8) +`endif +`ifndef ECC_REG_ECC_SEED_11 +`define ECC_REG_ECC_SEED_11 (32'hac) +`endif +`ifndef ECC_REG_ECC_MSG_0 +`define ECC_REG_ECC_MSG_0 (32'h100) +`endif +`ifndef ECC_REG_ECC_MSG_1 +`define ECC_REG_ECC_MSG_1 (32'h104) +`endif +`ifndef ECC_REG_ECC_MSG_2 +`define ECC_REG_ECC_MSG_2 (32'h108) +`endif +`ifndef ECC_REG_ECC_MSG_3 +`define ECC_REG_ECC_MSG_3 (32'h10c) +`endif +`ifndef ECC_REG_ECC_MSG_4 +`define ECC_REG_ECC_MSG_4 (32'h110) +`endif +`ifndef ECC_REG_ECC_MSG_5 +`define ECC_REG_ECC_MSG_5 (32'h114) +`endif +`ifndef ECC_REG_ECC_MSG_6 +`define ECC_REG_ECC_MSG_6 (32'h118) +`endif +`ifndef ECC_REG_ECC_MSG_7 +`define ECC_REG_ECC_MSG_7 (32'h11c) +`endif +`ifndef ECC_REG_ECC_MSG_8 +`define ECC_REG_ECC_MSG_8 (32'h120) +`endif +`ifndef ECC_REG_ECC_MSG_9 +`define ECC_REG_ECC_MSG_9 (32'h124) +`endif +`ifndef ECC_REG_ECC_MSG_10 +`define ECC_REG_ECC_MSG_10 (32'h128) +`endif +`ifndef ECC_REG_ECC_MSG_11 +`define ECC_REG_ECC_MSG_11 (32'h12c) +`endif +`ifndef ECC_REG_ECC_PRIVKEY_OUT_0 +`define ECC_REG_ECC_PRIVKEY_OUT_0 (32'h180) +`endif +`ifndef ECC_REG_ECC_PRIVKEY_OUT_1 +`define ECC_REG_ECC_PRIVKEY_OUT_1 (32'h184) +`endif +`ifndef ECC_REG_ECC_PRIVKEY_OUT_2 +`define ECC_REG_ECC_PRIVKEY_OUT_2 (32'h188) +`endif +`ifndef ECC_REG_ECC_PRIVKEY_OUT_3 +`define ECC_REG_ECC_PRIVKEY_OUT_3 (32'h18c) +`endif +`ifndef ECC_REG_ECC_PRIVKEY_OUT_4 +`define ECC_REG_ECC_PRIVKEY_OUT_4 (32'h190) +`endif +`ifndef ECC_REG_ECC_PRIVKEY_OUT_5 +`define ECC_REG_ECC_PRIVKEY_OUT_5 (32'h194) +`endif +`ifndef ECC_REG_ECC_PRIVKEY_OUT_6 +`define ECC_REG_ECC_PRIVKEY_OUT_6 (32'h198) +`endif +`ifndef ECC_REG_ECC_PRIVKEY_OUT_7 +`define ECC_REG_ECC_PRIVKEY_OUT_7 (32'h19c) +`endif +`ifndef ECC_REG_ECC_PRIVKEY_OUT_8 +`define ECC_REG_ECC_PRIVKEY_OUT_8 (32'h1a0) +`endif +`ifndef ECC_REG_ECC_PRIVKEY_OUT_9 +`define ECC_REG_ECC_PRIVKEY_OUT_9 (32'h1a4) +`endif +`ifndef ECC_REG_ECC_PRIVKEY_OUT_10 +`define ECC_REG_ECC_PRIVKEY_OUT_10 (32'h1a8) +`endif +`ifndef ECC_REG_ECC_PRIVKEY_OUT_11 +`define ECC_REG_ECC_PRIVKEY_OUT_11 (32'h1ac) +`endif +`ifndef ECC_REG_ECC_PUBKEY_X_0 +`define ECC_REG_ECC_PUBKEY_X_0 (32'h200) +`endif +`ifndef ECC_REG_ECC_PUBKEY_X_1 +`define ECC_REG_ECC_PUBKEY_X_1 (32'h204) +`endif +`ifndef ECC_REG_ECC_PUBKEY_X_2 +`define ECC_REG_ECC_PUBKEY_X_2 (32'h208) +`endif +`ifndef ECC_REG_ECC_PUBKEY_X_3 +`define ECC_REG_ECC_PUBKEY_X_3 (32'h20c) +`endif +`ifndef ECC_REG_ECC_PUBKEY_X_4 +`define ECC_REG_ECC_PUBKEY_X_4 (32'h210) +`endif +`ifndef ECC_REG_ECC_PUBKEY_X_5 +`define ECC_REG_ECC_PUBKEY_X_5 (32'h214) +`endif +`ifndef ECC_REG_ECC_PUBKEY_X_6 +`define ECC_REG_ECC_PUBKEY_X_6 (32'h218) +`endif +`ifndef ECC_REG_ECC_PUBKEY_X_7 +`define ECC_REG_ECC_PUBKEY_X_7 (32'h21c) +`endif +`ifndef ECC_REG_ECC_PUBKEY_X_8 +`define ECC_REG_ECC_PUBKEY_X_8 (32'h220) +`endif +`ifndef ECC_REG_ECC_PUBKEY_X_9 +`define ECC_REG_ECC_PUBKEY_X_9 (32'h224) +`endif +`ifndef ECC_REG_ECC_PUBKEY_X_10 +`define ECC_REG_ECC_PUBKEY_X_10 (32'h228) +`endif +`ifndef ECC_REG_ECC_PUBKEY_X_11 +`define ECC_REG_ECC_PUBKEY_X_11 (32'h22c) +`endif +`ifndef ECC_REG_ECC_PUBKEY_Y_0 +`define ECC_REG_ECC_PUBKEY_Y_0 (32'h280) +`endif +`ifndef ECC_REG_ECC_PUBKEY_Y_1 +`define ECC_REG_ECC_PUBKEY_Y_1 (32'h284) +`endif +`ifndef ECC_REG_ECC_PUBKEY_Y_2 +`define ECC_REG_ECC_PUBKEY_Y_2 (32'h288) +`endif +`ifndef ECC_REG_ECC_PUBKEY_Y_3 +`define ECC_REG_ECC_PUBKEY_Y_3 (32'h28c) +`endif +`ifndef ECC_REG_ECC_PUBKEY_Y_4 +`define ECC_REG_ECC_PUBKEY_Y_4 (32'h290) +`endif +`ifndef ECC_REG_ECC_PUBKEY_Y_5 +`define ECC_REG_ECC_PUBKEY_Y_5 (32'h294) +`endif +`ifndef ECC_REG_ECC_PUBKEY_Y_6 +`define ECC_REG_ECC_PUBKEY_Y_6 (32'h298) +`endif +`ifndef ECC_REG_ECC_PUBKEY_Y_7 +`define ECC_REG_ECC_PUBKEY_Y_7 (32'h29c) +`endif +`ifndef ECC_REG_ECC_PUBKEY_Y_8 +`define ECC_REG_ECC_PUBKEY_Y_8 (32'h2a0) +`endif +`ifndef ECC_REG_ECC_PUBKEY_Y_9 +`define ECC_REG_ECC_PUBKEY_Y_9 (32'h2a4) +`endif +`ifndef ECC_REG_ECC_PUBKEY_Y_10 +`define ECC_REG_ECC_PUBKEY_Y_10 (32'h2a8) +`endif +`ifndef ECC_REG_ECC_PUBKEY_Y_11 +`define ECC_REG_ECC_PUBKEY_Y_11 (32'h2ac) +`endif +`ifndef ECC_REG_ECC_SIGN_R_0 +`define ECC_REG_ECC_SIGN_R_0 (32'h300) +`endif +`ifndef ECC_REG_ECC_SIGN_R_1 +`define ECC_REG_ECC_SIGN_R_1 (32'h304) +`endif +`ifndef ECC_REG_ECC_SIGN_R_2 +`define ECC_REG_ECC_SIGN_R_2 (32'h308) +`endif +`ifndef ECC_REG_ECC_SIGN_R_3 +`define ECC_REG_ECC_SIGN_R_3 (32'h30c) +`endif +`ifndef ECC_REG_ECC_SIGN_R_4 +`define ECC_REG_ECC_SIGN_R_4 (32'h310) +`endif +`ifndef ECC_REG_ECC_SIGN_R_5 +`define ECC_REG_ECC_SIGN_R_5 (32'h314) +`endif +`ifndef ECC_REG_ECC_SIGN_R_6 +`define ECC_REG_ECC_SIGN_R_6 (32'h318) +`endif +`ifndef ECC_REG_ECC_SIGN_R_7 +`define ECC_REG_ECC_SIGN_R_7 (32'h31c) +`endif +`ifndef ECC_REG_ECC_SIGN_R_8 +`define ECC_REG_ECC_SIGN_R_8 (32'h320) +`endif +`ifndef ECC_REG_ECC_SIGN_R_9 +`define ECC_REG_ECC_SIGN_R_9 (32'h324) +`endif +`ifndef ECC_REG_ECC_SIGN_R_10 +`define ECC_REG_ECC_SIGN_R_10 (32'h328) +`endif +`ifndef ECC_REG_ECC_SIGN_R_11 +`define ECC_REG_ECC_SIGN_R_11 (32'h32c) +`endif +`ifndef ECC_REG_ECC_SIGN_S_0 +`define ECC_REG_ECC_SIGN_S_0 (32'h380) +`endif +`ifndef ECC_REG_ECC_SIGN_S_1 +`define ECC_REG_ECC_SIGN_S_1 (32'h384) +`endif +`ifndef ECC_REG_ECC_SIGN_S_2 +`define ECC_REG_ECC_SIGN_S_2 (32'h388) +`endif +`ifndef ECC_REG_ECC_SIGN_S_3 +`define ECC_REG_ECC_SIGN_S_3 (32'h38c) +`endif +`ifndef ECC_REG_ECC_SIGN_S_4 +`define ECC_REG_ECC_SIGN_S_4 (32'h390) +`endif +`ifndef ECC_REG_ECC_SIGN_S_5 +`define ECC_REG_ECC_SIGN_S_5 (32'h394) +`endif +`ifndef ECC_REG_ECC_SIGN_S_6 +`define ECC_REG_ECC_SIGN_S_6 (32'h398) +`endif +`ifndef ECC_REG_ECC_SIGN_S_7 +`define ECC_REG_ECC_SIGN_S_7 (32'h39c) +`endif +`ifndef ECC_REG_ECC_SIGN_S_8 +`define ECC_REG_ECC_SIGN_S_8 (32'h3a0) +`endif +`ifndef ECC_REG_ECC_SIGN_S_9 +`define ECC_REG_ECC_SIGN_S_9 (32'h3a4) +`endif +`ifndef ECC_REG_ECC_SIGN_S_10 +`define ECC_REG_ECC_SIGN_S_10 (32'h3a8) +`endif +`ifndef ECC_REG_ECC_SIGN_S_11 +`define ECC_REG_ECC_SIGN_S_11 (32'h3ac) +`endif +`ifndef ECC_REG_ECC_VERIFY_R_0 +`define ECC_REG_ECC_VERIFY_R_0 (32'h400) +`endif +`ifndef ECC_REG_ECC_VERIFY_R_1 +`define ECC_REG_ECC_VERIFY_R_1 (32'h404) +`endif +`ifndef ECC_REG_ECC_VERIFY_R_2 +`define ECC_REG_ECC_VERIFY_R_2 (32'h408) +`endif +`ifndef ECC_REG_ECC_VERIFY_R_3 +`define ECC_REG_ECC_VERIFY_R_3 (32'h40c) +`endif +`ifndef ECC_REG_ECC_VERIFY_R_4 +`define ECC_REG_ECC_VERIFY_R_4 (32'h410) +`endif +`ifndef ECC_REG_ECC_VERIFY_R_5 +`define ECC_REG_ECC_VERIFY_R_5 (32'h414) +`endif +`ifndef ECC_REG_ECC_VERIFY_R_6 +`define ECC_REG_ECC_VERIFY_R_6 (32'h418) +`endif +`ifndef ECC_REG_ECC_VERIFY_R_7 +`define ECC_REG_ECC_VERIFY_R_7 (32'h41c) +`endif +`ifndef ECC_REG_ECC_VERIFY_R_8 +`define ECC_REG_ECC_VERIFY_R_8 (32'h420) +`endif +`ifndef ECC_REG_ECC_VERIFY_R_9 +`define ECC_REG_ECC_VERIFY_R_9 (32'h424) +`endif +`ifndef ECC_REG_ECC_VERIFY_R_10 +`define ECC_REG_ECC_VERIFY_R_10 (32'h428) +`endif +`ifndef ECC_REG_ECC_VERIFY_R_11 +`define ECC_REG_ECC_VERIFY_R_11 (32'h42c) +`endif +`ifndef ECC_REG_ECC_IV_0 +`define ECC_REG_ECC_IV_0 (32'h480) +`endif +`ifndef ECC_REG_ECC_IV_1 +`define ECC_REG_ECC_IV_1 (32'h484) +`endif +`ifndef ECC_REG_ECC_IV_2 +`define ECC_REG_ECC_IV_2 (32'h488) +`endif +`ifndef ECC_REG_ECC_IV_3 +`define ECC_REG_ECC_IV_3 (32'h48c) +`endif +`ifndef ECC_REG_ECC_IV_4 +`define ECC_REG_ECC_IV_4 (32'h490) +`endif +`ifndef ECC_REG_ECC_IV_5 +`define ECC_REG_ECC_IV_5 (32'h494) +`endif +`ifndef ECC_REG_ECC_IV_6 +`define ECC_REG_ECC_IV_6 (32'h498) +`endif +`ifndef ECC_REG_ECC_IV_7 +`define ECC_REG_ECC_IV_7 (32'h49c) +`endif +`ifndef ECC_REG_ECC_IV_8 +`define ECC_REG_ECC_IV_8 (32'h4a0) +`endif +`ifndef ECC_REG_ECC_IV_9 +`define ECC_REG_ECC_IV_9 (32'h4a4) +`endif +`ifndef ECC_REG_ECC_IV_10 +`define ECC_REG_ECC_IV_10 (32'h4a8) +`endif +`ifndef ECC_REG_ECC_IV_11 +`define ECC_REG_ECC_IV_11 (32'h4ac) +`endif +`ifndef ECC_REG_ECC_NONCE_0 +`define ECC_REG_ECC_NONCE_0 (32'h500) +`endif +`ifndef ECC_REG_ECC_NONCE_1 +`define ECC_REG_ECC_NONCE_1 (32'h504) +`endif +`ifndef ECC_REG_ECC_NONCE_2 +`define ECC_REG_ECC_NONCE_2 (32'h508) +`endif +`ifndef ECC_REG_ECC_NONCE_3 +`define ECC_REG_ECC_NONCE_3 (32'h50c) +`endif +`ifndef ECC_REG_ECC_NONCE_4 +`define ECC_REG_ECC_NONCE_4 (32'h510) +`endif +`ifndef ECC_REG_ECC_NONCE_5 +`define ECC_REG_ECC_NONCE_5 (32'h514) +`endif +`ifndef ECC_REG_ECC_NONCE_6 +`define ECC_REG_ECC_NONCE_6 (32'h518) +`endif +`ifndef ECC_REG_ECC_NONCE_7 +`define ECC_REG_ECC_NONCE_7 (32'h51c) +`endif +`ifndef ECC_REG_ECC_NONCE_8 +`define ECC_REG_ECC_NONCE_8 (32'h520) +`endif +`ifndef ECC_REG_ECC_NONCE_9 +`define ECC_REG_ECC_NONCE_9 (32'h524) +`endif +`ifndef ECC_REG_ECC_NONCE_10 +`define ECC_REG_ECC_NONCE_10 (32'h528) +`endif +`ifndef ECC_REG_ECC_NONCE_11 +`define ECC_REG_ECC_NONCE_11 (32'h52c) +`endif +`ifndef ECC_REG_ECC_PRIVKEY_IN_0 +`define ECC_REG_ECC_PRIVKEY_IN_0 (32'h580) +`endif +`ifndef ECC_REG_ECC_PRIVKEY_IN_1 +`define ECC_REG_ECC_PRIVKEY_IN_1 (32'h584) +`endif +`ifndef ECC_REG_ECC_PRIVKEY_IN_2 +`define ECC_REG_ECC_PRIVKEY_IN_2 (32'h588) +`endif +`ifndef ECC_REG_ECC_PRIVKEY_IN_3 +`define ECC_REG_ECC_PRIVKEY_IN_3 (32'h58c) +`endif +`ifndef ECC_REG_ECC_PRIVKEY_IN_4 +`define ECC_REG_ECC_PRIVKEY_IN_4 (32'h590) +`endif +`ifndef ECC_REG_ECC_PRIVKEY_IN_5 +`define ECC_REG_ECC_PRIVKEY_IN_5 (32'h594) +`endif +`ifndef ECC_REG_ECC_PRIVKEY_IN_6 +`define ECC_REG_ECC_PRIVKEY_IN_6 (32'h598) +`endif +`ifndef ECC_REG_ECC_PRIVKEY_IN_7 +`define ECC_REG_ECC_PRIVKEY_IN_7 (32'h59c) +`endif +`ifndef ECC_REG_ECC_PRIVKEY_IN_8 +`define ECC_REG_ECC_PRIVKEY_IN_8 (32'h5a0) +`endif +`ifndef ECC_REG_ECC_PRIVKEY_IN_9 +`define ECC_REG_ECC_PRIVKEY_IN_9 (32'h5a4) +`endif +`ifndef ECC_REG_ECC_PRIVKEY_IN_10 +`define ECC_REG_ECC_PRIVKEY_IN_10 (32'h5a8) +`endif +`ifndef ECC_REG_ECC_PRIVKEY_IN_11 +`define ECC_REG_ECC_PRIVKEY_IN_11 (32'h5ac) +`endif +`ifndef ECC_REG_ECC_DH_SHARED_KEY_0 +`define ECC_REG_ECC_DH_SHARED_KEY_0 (32'h5c0) +`endif +`ifndef ECC_REG_ECC_DH_SHARED_KEY_1 +`define ECC_REG_ECC_DH_SHARED_KEY_1 (32'h5c4) +`endif +`ifndef ECC_REG_ECC_DH_SHARED_KEY_2 +`define ECC_REG_ECC_DH_SHARED_KEY_2 (32'h5c8) +`endif +`ifndef ECC_REG_ECC_DH_SHARED_KEY_3 +`define ECC_REG_ECC_DH_SHARED_KEY_3 (32'h5cc) +`endif +`ifndef ECC_REG_ECC_DH_SHARED_KEY_4 +`define ECC_REG_ECC_DH_SHARED_KEY_4 (32'h5d0) +`endif +`ifndef ECC_REG_ECC_DH_SHARED_KEY_5 +`define ECC_REG_ECC_DH_SHARED_KEY_5 (32'h5d4) +`endif +`ifndef ECC_REG_ECC_DH_SHARED_KEY_6 +`define ECC_REG_ECC_DH_SHARED_KEY_6 (32'h5d8) +`endif +`ifndef ECC_REG_ECC_DH_SHARED_KEY_7 +`define ECC_REG_ECC_DH_SHARED_KEY_7 (32'h5dc) +`endif +`ifndef ECC_REG_ECC_DH_SHARED_KEY_8 +`define ECC_REG_ECC_DH_SHARED_KEY_8 (32'h5e0) +`endif +`ifndef ECC_REG_ECC_DH_SHARED_KEY_9 +`define ECC_REG_ECC_DH_SHARED_KEY_9 (32'h5e4) +`endif +`ifndef ECC_REG_ECC_DH_SHARED_KEY_10 +`define ECC_REG_ECC_DH_SHARED_KEY_10 (32'h5e8) +`endif +`ifndef ECC_REG_ECC_DH_SHARED_KEY_11 +`define ECC_REG_ECC_DH_SHARED_KEY_11 (32'h5ec) +`endif +`ifndef ECC_REG_ECC_KV_RD_PKEY_CTRL +`define ECC_REG_ECC_KV_RD_PKEY_CTRL (32'h600) +`define ECC_REG_ECC_KV_RD_PKEY_CTRL_READ_EN_LOW (0) +`define ECC_REG_ECC_KV_RD_PKEY_CTRL_READ_EN_MASK (32'h1) +`define ECC_REG_ECC_KV_RD_PKEY_CTRL_READ_ENTRY_LOW (1) +`define ECC_REG_ECC_KV_RD_PKEY_CTRL_READ_ENTRY_MASK (32'h3e) +`define ECC_REG_ECC_KV_RD_PKEY_CTRL_PCR_HASH_EXTEND_LOW (6) +`define ECC_REG_ECC_KV_RD_PKEY_CTRL_PCR_HASH_EXTEND_MASK (32'h40) +`define ECC_REG_ECC_KV_RD_PKEY_CTRL_RSVD_LOW (7) +`define ECC_REG_ECC_KV_RD_PKEY_CTRL_RSVD_MASK (32'hffffff80) +`endif +`ifndef ECC_REG_ECC_KV_RD_PKEY_STATUS +`define ECC_REG_ECC_KV_RD_PKEY_STATUS (32'h604) +`define ECC_REG_ECC_KV_RD_PKEY_STATUS_READY_LOW (0) +`define ECC_REG_ECC_KV_RD_PKEY_STATUS_READY_MASK (32'h1) +`define ECC_REG_ECC_KV_RD_PKEY_STATUS_VALID_LOW (1) +`define ECC_REG_ECC_KV_RD_PKEY_STATUS_VALID_MASK (32'h2) +`define ECC_REG_ECC_KV_RD_PKEY_STATUS_ERROR_LOW (2) +`define ECC_REG_ECC_KV_RD_PKEY_STATUS_ERROR_MASK (32'h3fc) +`endif +`ifndef ECC_REG_ECC_KV_RD_SEED_CTRL +`define ECC_REG_ECC_KV_RD_SEED_CTRL (32'h608) +`define ECC_REG_ECC_KV_RD_SEED_CTRL_READ_EN_LOW (0) +`define ECC_REG_ECC_KV_RD_SEED_CTRL_READ_EN_MASK (32'h1) +`define ECC_REG_ECC_KV_RD_SEED_CTRL_READ_ENTRY_LOW (1) +`define ECC_REG_ECC_KV_RD_SEED_CTRL_READ_ENTRY_MASK (32'h3e) +`define ECC_REG_ECC_KV_RD_SEED_CTRL_PCR_HASH_EXTEND_LOW (6) +`define ECC_REG_ECC_KV_RD_SEED_CTRL_PCR_HASH_EXTEND_MASK (32'h40) +`define ECC_REG_ECC_KV_RD_SEED_CTRL_RSVD_LOW (7) +`define ECC_REG_ECC_KV_RD_SEED_CTRL_RSVD_MASK (32'hffffff80) +`endif +`ifndef ECC_REG_ECC_KV_RD_SEED_STATUS +`define ECC_REG_ECC_KV_RD_SEED_STATUS (32'h60c) +`define ECC_REG_ECC_KV_RD_SEED_STATUS_READY_LOW (0) +`define ECC_REG_ECC_KV_RD_SEED_STATUS_READY_MASK (32'h1) +`define ECC_REG_ECC_KV_RD_SEED_STATUS_VALID_LOW (1) +`define ECC_REG_ECC_KV_RD_SEED_STATUS_VALID_MASK (32'h2) +`define ECC_REG_ECC_KV_RD_SEED_STATUS_ERROR_LOW (2) +`define ECC_REG_ECC_KV_RD_SEED_STATUS_ERROR_MASK (32'h3fc) +`endif +`ifndef ECC_REG_ECC_KV_WR_PKEY_CTRL +`define ECC_REG_ECC_KV_WR_PKEY_CTRL (32'h610) +`define ECC_REG_ECC_KV_WR_PKEY_CTRL_WRITE_EN_LOW (0) +`define ECC_REG_ECC_KV_WR_PKEY_CTRL_WRITE_EN_MASK (32'h1) +`define ECC_REG_ECC_KV_WR_PKEY_CTRL_WRITE_ENTRY_LOW (1) +`define ECC_REG_ECC_KV_WR_PKEY_CTRL_WRITE_ENTRY_MASK (32'h3e) +`define ECC_REG_ECC_KV_WR_PKEY_CTRL_HMAC_KEY_DEST_VALID_LOW (6) +`define ECC_REG_ECC_KV_WR_PKEY_CTRL_HMAC_KEY_DEST_VALID_MASK (32'h40) +`define ECC_REG_ECC_KV_WR_PKEY_CTRL_HMAC_BLOCK_DEST_VALID_LOW (7) +`define ECC_REG_ECC_KV_WR_PKEY_CTRL_HMAC_BLOCK_DEST_VALID_MASK (32'h80) +`define ECC_REG_ECC_KV_WR_PKEY_CTRL_MLDSA_SEED_DEST_VALID_LOW (8) +`define ECC_REG_ECC_KV_WR_PKEY_CTRL_MLDSA_SEED_DEST_VALID_MASK (32'h100) +`define ECC_REG_ECC_KV_WR_PKEY_CTRL_ECC_PKEY_DEST_VALID_LOW (9) +`define ECC_REG_ECC_KV_WR_PKEY_CTRL_ECC_PKEY_DEST_VALID_MASK (32'h200) +`define ECC_REG_ECC_KV_WR_PKEY_CTRL_ECC_SEED_DEST_VALID_LOW (10) +`define ECC_REG_ECC_KV_WR_PKEY_CTRL_ECC_SEED_DEST_VALID_MASK (32'h400) +`define ECC_REG_ECC_KV_WR_PKEY_CTRL_AES_KEY_DEST_VALID_LOW (11) +`define ECC_REG_ECC_KV_WR_PKEY_CTRL_AES_KEY_DEST_VALID_MASK (32'h800) +`define ECC_REG_ECC_KV_WR_PKEY_CTRL_MLKEM_SEED_DEST_VALID_LOW (12) +`define ECC_REG_ECC_KV_WR_PKEY_CTRL_MLKEM_SEED_DEST_VALID_MASK (32'h1000) +`define ECC_REG_ECC_KV_WR_PKEY_CTRL_MLKEM_MSG_DEST_VALID_LOW (13) +`define ECC_REG_ECC_KV_WR_PKEY_CTRL_MLKEM_MSG_DEST_VALID_MASK (32'h2000) +`define ECC_REG_ECC_KV_WR_PKEY_CTRL_DMA_DATA_DEST_VALID_LOW (14) +`define ECC_REG_ECC_KV_WR_PKEY_CTRL_DMA_DATA_DEST_VALID_MASK (32'h4000) +`define ECC_REG_ECC_KV_WR_PKEY_CTRL_RSVD_LOW (15) +`define ECC_REG_ECC_KV_WR_PKEY_CTRL_RSVD_MASK (32'hffff8000) +`endif +`ifndef ECC_REG_ECC_KV_WR_PKEY_STATUS +`define ECC_REG_ECC_KV_WR_PKEY_STATUS (32'h614) +`define ECC_REG_ECC_KV_WR_PKEY_STATUS_READY_LOW (0) +`define ECC_REG_ECC_KV_WR_PKEY_STATUS_READY_MASK (32'h1) +`define ECC_REG_ECC_KV_WR_PKEY_STATUS_VALID_LOW (1) +`define ECC_REG_ECC_KV_WR_PKEY_STATUS_VALID_MASK (32'h2) +`define ECC_REG_ECC_KV_WR_PKEY_STATUS_ERROR_LOW (2) +`define ECC_REG_ECC_KV_WR_PKEY_STATUS_ERROR_MASK (32'h3fc) +`endif +`ifndef ECC_REG_INTR_BLOCK_RF_GLOBAL_INTR_EN_R +`define ECC_REG_INTR_BLOCK_RF_GLOBAL_INTR_EN_R (32'h800) +`define ECC_REG_INTR_BLOCK_RF_GLOBAL_INTR_EN_R_ERROR_EN_LOW (0) +`define ECC_REG_INTR_BLOCK_RF_GLOBAL_INTR_EN_R_ERROR_EN_MASK (32'h1) +`define ECC_REG_INTR_BLOCK_RF_GLOBAL_INTR_EN_R_NOTIF_EN_LOW (1) +`define ECC_REG_INTR_BLOCK_RF_GLOBAL_INTR_EN_R_NOTIF_EN_MASK (32'h2) +`endif +`ifndef ECC_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R +`define ECC_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R (32'h804) +`define ECC_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R_ERROR_INTERNAL_EN_LOW (0) +`define ECC_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R_ERROR_INTERNAL_EN_MASK (32'h1) +`endif +`ifndef ECC_REG_INTR_BLOCK_RF_NOTIF_INTR_EN_R +`define ECC_REG_INTR_BLOCK_RF_NOTIF_INTR_EN_R (32'h808) +`define ECC_REG_INTR_BLOCK_RF_NOTIF_INTR_EN_R_NOTIF_CMD_DONE_EN_LOW (0) +`define ECC_REG_INTR_BLOCK_RF_NOTIF_INTR_EN_R_NOTIF_CMD_DONE_EN_MASK (32'h1) +`endif +`ifndef ECC_REG_INTR_BLOCK_RF_ERROR_GLOBAL_INTR_R +`define ECC_REG_INTR_BLOCK_RF_ERROR_GLOBAL_INTR_R (32'h80c) +`define ECC_REG_INTR_BLOCK_RF_ERROR_GLOBAL_INTR_R_AGG_STS_LOW (0) +`define ECC_REG_INTR_BLOCK_RF_ERROR_GLOBAL_INTR_R_AGG_STS_MASK (32'h1) +`endif +`ifndef ECC_REG_INTR_BLOCK_RF_NOTIF_GLOBAL_INTR_R +`define ECC_REG_INTR_BLOCK_RF_NOTIF_GLOBAL_INTR_R (32'h810) +`define ECC_REG_INTR_BLOCK_RF_NOTIF_GLOBAL_INTR_R_AGG_STS_LOW (0) +`define ECC_REG_INTR_BLOCK_RF_NOTIF_GLOBAL_INTR_R_AGG_STS_MASK (32'h1) +`endif +`ifndef ECC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R +`define ECC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R (32'h814) +`define ECC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_INTERNAL_STS_LOW (0) +`define ECC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_INTERNAL_STS_MASK (32'h1) +`endif +`ifndef ECC_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R +`define ECC_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R (32'h818) +`define ECC_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_CMD_DONE_STS_LOW (0) +`define ECC_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_CMD_DONE_STS_MASK (32'h1) +`endif +`ifndef ECC_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R +`define ECC_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R (32'h81c) +`define ECC_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R_ERROR_INTERNAL_TRIG_LOW (0) +`define ECC_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R_ERROR_INTERNAL_TRIG_MASK (32'h1) +`endif +`ifndef ECC_REG_INTR_BLOCK_RF_NOTIF_INTR_TRIG_R +`define ECC_REG_INTR_BLOCK_RF_NOTIF_INTR_TRIG_R (32'h820) +`define ECC_REG_INTR_BLOCK_RF_NOTIF_INTR_TRIG_R_NOTIF_CMD_DONE_TRIG_LOW (0) +`define ECC_REG_INTR_BLOCK_RF_NOTIF_INTR_TRIG_R_NOTIF_CMD_DONE_TRIG_MASK (32'h1) +`endif +`ifndef ECC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_COUNT_R +`define ECC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_COUNT_R (32'h900) +`endif +`ifndef ECC_REG_INTR_BLOCK_RF_NOTIF_CMD_DONE_INTR_COUNT_R +`define ECC_REG_INTR_BLOCK_RF_NOTIF_CMD_DONE_INTR_COUNT_R (32'h980) +`endif +`ifndef ECC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_COUNT_INCR_R +`define ECC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_COUNT_INCR_R (32'ha00) +`define ECC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_COUNT_INCR_R_PULSE_LOW (0) +`define ECC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_COUNT_INCR_R_PULSE_MASK (32'h1) +`endif +`ifndef ECC_REG_INTR_BLOCK_RF_NOTIF_CMD_DONE_INTR_COUNT_INCR_R +`define ECC_REG_INTR_BLOCK_RF_NOTIF_CMD_DONE_INTR_COUNT_INCR_R (32'ha04) +`define ECC_REG_INTR_BLOCK_RF_NOTIF_CMD_DONE_INTR_COUNT_INCR_R_PULSE_LOW (0) +`define ECC_REG_INTR_BLOCK_RF_NOTIF_CMD_DONE_INTR_COUNT_INCR_R_PULSE_MASK (32'h1) +`endif +`ifndef HMAC_REG_HMAC512_NAME_0 +`define HMAC_REG_HMAC512_NAME_0 (32'h0) +`endif +`ifndef HMAC_REG_HMAC512_NAME_1 +`define HMAC_REG_HMAC512_NAME_1 (32'h4) +`endif +`ifndef HMAC_REG_HMAC512_VERSION_0 +`define HMAC_REG_HMAC512_VERSION_0 (32'h8) +`endif +`ifndef HMAC_REG_HMAC512_VERSION_1 +`define HMAC_REG_HMAC512_VERSION_1 (32'hc) +`endif +`ifndef HMAC_REG_HMAC512_CTRL +`define HMAC_REG_HMAC512_CTRL (32'h10) +`define HMAC_REG_HMAC512_CTRL_INIT_LOW (0) +`define HMAC_REG_HMAC512_CTRL_INIT_MASK (32'h1) +`define HMAC_REG_HMAC512_CTRL_NEXT_LOW (1) +`define HMAC_REG_HMAC512_CTRL_NEXT_MASK (32'h2) +`define HMAC_REG_HMAC512_CTRL_ZEROIZE_LOW (2) +`define HMAC_REG_HMAC512_CTRL_ZEROIZE_MASK (32'h4) +`define HMAC_REG_HMAC512_CTRL_MODE_LOW (3) +`define HMAC_REG_HMAC512_CTRL_MODE_MASK (32'h8) +`define HMAC_REG_HMAC512_CTRL_CSR_MODE_LOW (4) +`define HMAC_REG_HMAC512_CTRL_CSR_MODE_MASK (32'h10) +`define HMAC_REG_HMAC512_CTRL_RESERVED_LOW (5) +`define HMAC_REG_HMAC512_CTRL_RESERVED_MASK (32'h20) +`endif +`ifndef HMAC_REG_HMAC512_STATUS +`define HMAC_REG_HMAC512_STATUS (32'h18) +`define HMAC_REG_HMAC512_STATUS_READY_LOW (0) +`define HMAC_REG_HMAC512_STATUS_READY_MASK (32'h1) +`define HMAC_REG_HMAC512_STATUS_VALID_LOW (1) +`define HMAC_REG_HMAC512_STATUS_VALID_MASK (32'h2) +`endif +`ifndef HMAC_REG_HMAC512_KEY_0 +`define HMAC_REG_HMAC512_KEY_0 (32'h40) +`endif +`ifndef HMAC_REG_HMAC512_KEY_1 +`define HMAC_REG_HMAC512_KEY_1 (32'h44) +`endif +`ifndef HMAC_REG_HMAC512_KEY_2 +`define HMAC_REG_HMAC512_KEY_2 (32'h48) +`endif +`ifndef HMAC_REG_HMAC512_KEY_3 +`define HMAC_REG_HMAC512_KEY_3 (32'h4c) +`endif +`ifndef HMAC_REG_HMAC512_KEY_4 +`define HMAC_REG_HMAC512_KEY_4 (32'h50) +`endif +`ifndef HMAC_REG_HMAC512_KEY_5 +`define HMAC_REG_HMAC512_KEY_5 (32'h54) +`endif +`ifndef HMAC_REG_HMAC512_KEY_6 +`define HMAC_REG_HMAC512_KEY_6 (32'h58) +`endif +`ifndef HMAC_REG_HMAC512_KEY_7 +`define HMAC_REG_HMAC512_KEY_7 (32'h5c) +`endif +`ifndef HMAC_REG_HMAC512_KEY_8 +`define HMAC_REG_HMAC512_KEY_8 (32'h60) +`endif +`ifndef HMAC_REG_HMAC512_KEY_9 +`define HMAC_REG_HMAC512_KEY_9 (32'h64) +`endif +`ifndef HMAC_REG_HMAC512_KEY_10 +`define HMAC_REG_HMAC512_KEY_10 (32'h68) +`endif +`ifndef HMAC_REG_HMAC512_KEY_11 +`define HMAC_REG_HMAC512_KEY_11 (32'h6c) +`endif +`ifndef HMAC_REG_HMAC512_KEY_12 +`define HMAC_REG_HMAC512_KEY_12 (32'h70) +`endif +`ifndef HMAC_REG_HMAC512_KEY_13 +`define HMAC_REG_HMAC512_KEY_13 (32'h74) +`endif +`ifndef HMAC_REG_HMAC512_KEY_14 +`define HMAC_REG_HMAC512_KEY_14 (32'h78) +`endif +`ifndef HMAC_REG_HMAC512_KEY_15 +`define HMAC_REG_HMAC512_KEY_15 (32'h7c) +`endif +`ifndef HMAC_REG_HMAC512_BLOCK_0 +`define HMAC_REG_HMAC512_BLOCK_0 (32'h80) +`endif +`ifndef HMAC_REG_HMAC512_BLOCK_1 +`define HMAC_REG_HMAC512_BLOCK_1 (32'h84) +`endif +`ifndef HMAC_REG_HMAC512_BLOCK_2 +`define HMAC_REG_HMAC512_BLOCK_2 (32'h88) +`endif +`ifndef HMAC_REG_HMAC512_BLOCK_3 +`define HMAC_REG_HMAC512_BLOCK_3 (32'h8c) +`endif +`ifndef HMAC_REG_HMAC512_BLOCK_4 +`define HMAC_REG_HMAC512_BLOCK_4 (32'h90) +`endif +`ifndef HMAC_REG_HMAC512_BLOCK_5 +`define HMAC_REG_HMAC512_BLOCK_5 (32'h94) +`endif +`ifndef HMAC_REG_HMAC512_BLOCK_6 +`define HMAC_REG_HMAC512_BLOCK_6 (32'h98) +`endif +`ifndef HMAC_REG_HMAC512_BLOCK_7 +`define HMAC_REG_HMAC512_BLOCK_7 (32'h9c) +`endif +`ifndef HMAC_REG_HMAC512_BLOCK_8 +`define HMAC_REG_HMAC512_BLOCK_8 (32'ha0) +`endif +`ifndef HMAC_REG_HMAC512_BLOCK_9 +`define HMAC_REG_HMAC512_BLOCK_9 (32'ha4) +`endif +`ifndef HMAC_REG_HMAC512_BLOCK_10 +`define HMAC_REG_HMAC512_BLOCK_10 (32'ha8) +`endif +`ifndef HMAC_REG_HMAC512_BLOCK_11 +`define HMAC_REG_HMAC512_BLOCK_11 (32'hac) +`endif +`ifndef HMAC_REG_HMAC512_BLOCK_12 +`define HMAC_REG_HMAC512_BLOCK_12 (32'hb0) +`endif +`ifndef HMAC_REG_HMAC512_BLOCK_13 +`define HMAC_REG_HMAC512_BLOCK_13 (32'hb4) +`endif +`ifndef HMAC_REG_HMAC512_BLOCK_14 +`define HMAC_REG_HMAC512_BLOCK_14 (32'hb8) +`endif +`ifndef HMAC_REG_HMAC512_BLOCK_15 +`define HMAC_REG_HMAC512_BLOCK_15 (32'hbc) +`endif +`ifndef HMAC_REG_HMAC512_BLOCK_16 +`define HMAC_REG_HMAC512_BLOCK_16 (32'hc0) +`endif +`ifndef HMAC_REG_HMAC512_BLOCK_17 +`define HMAC_REG_HMAC512_BLOCK_17 (32'hc4) +`endif +`ifndef HMAC_REG_HMAC512_BLOCK_18 +`define HMAC_REG_HMAC512_BLOCK_18 (32'hc8) +`endif +`ifndef HMAC_REG_HMAC512_BLOCK_19 +`define HMAC_REG_HMAC512_BLOCK_19 (32'hcc) +`endif +`ifndef HMAC_REG_HMAC512_BLOCK_20 +`define HMAC_REG_HMAC512_BLOCK_20 (32'hd0) +`endif +`ifndef HMAC_REG_HMAC512_BLOCK_21 +`define HMAC_REG_HMAC512_BLOCK_21 (32'hd4) +`endif +`ifndef HMAC_REG_HMAC512_BLOCK_22 +`define HMAC_REG_HMAC512_BLOCK_22 (32'hd8) +`endif +`ifndef HMAC_REG_HMAC512_BLOCK_23 +`define HMAC_REG_HMAC512_BLOCK_23 (32'hdc) +`endif +`ifndef HMAC_REG_HMAC512_BLOCK_24 +`define HMAC_REG_HMAC512_BLOCK_24 (32'he0) +`endif +`ifndef HMAC_REG_HMAC512_BLOCK_25 +`define HMAC_REG_HMAC512_BLOCK_25 (32'he4) +`endif +`ifndef HMAC_REG_HMAC512_BLOCK_26 +`define HMAC_REG_HMAC512_BLOCK_26 (32'he8) +`endif +`ifndef HMAC_REG_HMAC512_BLOCK_27 +`define HMAC_REG_HMAC512_BLOCK_27 (32'hec) +`endif +`ifndef HMAC_REG_HMAC512_BLOCK_28 +`define HMAC_REG_HMAC512_BLOCK_28 (32'hf0) +`endif +`ifndef HMAC_REG_HMAC512_BLOCK_29 +`define HMAC_REG_HMAC512_BLOCK_29 (32'hf4) +`endif +`ifndef HMAC_REG_HMAC512_BLOCK_30 +`define HMAC_REG_HMAC512_BLOCK_30 (32'hf8) +`endif +`ifndef HMAC_REG_HMAC512_BLOCK_31 +`define HMAC_REG_HMAC512_BLOCK_31 (32'hfc) +`endif +`ifndef HMAC_REG_HMAC512_TAG_0 +`define HMAC_REG_HMAC512_TAG_0 (32'h100) +`endif +`ifndef HMAC_REG_HMAC512_TAG_1 +`define HMAC_REG_HMAC512_TAG_1 (32'h104) +`endif +`ifndef HMAC_REG_HMAC512_TAG_2 +`define HMAC_REG_HMAC512_TAG_2 (32'h108) +`endif +`ifndef HMAC_REG_HMAC512_TAG_3 +`define HMAC_REG_HMAC512_TAG_3 (32'h10c) +`endif +`ifndef HMAC_REG_HMAC512_TAG_4 +`define HMAC_REG_HMAC512_TAG_4 (32'h110) +`endif +`ifndef HMAC_REG_HMAC512_TAG_5 +`define HMAC_REG_HMAC512_TAG_5 (32'h114) +`endif +`ifndef HMAC_REG_HMAC512_TAG_6 +`define HMAC_REG_HMAC512_TAG_6 (32'h118) +`endif +`ifndef HMAC_REG_HMAC512_TAG_7 +`define HMAC_REG_HMAC512_TAG_7 (32'h11c) +`endif +`ifndef HMAC_REG_HMAC512_TAG_8 +`define HMAC_REG_HMAC512_TAG_8 (32'h120) +`endif +`ifndef HMAC_REG_HMAC512_TAG_9 +`define HMAC_REG_HMAC512_TAG_9 (32'h124) +`endif +`ifndef HMAC_REG_HMAC512_TAG_10 +`define HMAC_REG_HMAC512_TAG_10 (32'h128) +`endif +`ifndef HMAC_REG_HMAC512_TAG_11 +`define HMAC_REG_HMAC512_TAG_11 (32'h12c) +`endif +`ifndef HMAC_REG_HMAC512_TAG_12 +`define HMAC_REG_HMAC512_TAG_12 (32'h130) +`endif +`ifndef HMAC_REG_HMAC512_TAG_13 +`define HMAC_REG_HMAC512_TAG_13 (32'h134) +`endif +`ifndef HMAC_REG_HMAC512_TAG_14 +`define HMAC_REG_HMAC512_TAG_14 (32'h138) +`endif +`ifndef HMAC_REG_HMAC512_TAG_15 +`define HMAC_REG_HMAC512_TAG_15 (32'h13c) +`endif +`ifndef HMAC_REG_HMAC512_LFSR_SEED_0 +`define HMAC_REG_HMAC512_LFSR_SEED_0 (32'h140) +`endif +`ifndef HMAC_REG_HMAC512_LFSR_SEED_1 +`define HMAC_REG_HMAC512_LFSR_SEED_1 (32'h144) +`endif +`ifndef HMAC_REG_HMAC512_LFSR_SEED_2 +`define HMAC_REG_HMAC512_LFSR_SEED_2 (32'h148) +`endif +`ifndef HMAC_REG_HMAC512_LFSR_SEED_3 +`define HMAC_REG_HMAC512_LFSR_SEED_3 (32'h14c) +`endif +`ifndef HMAC_REG_HMAC512_LFSR_SEED_4 +`define HMAC_REG_HMAC512_LFSR_SEED_4 (32'h150) +`endif +`ifndef HMAC_REG_HMAC512_LFSR_SEED_5 +`define HMAC_REG_HMAC512_LFSR_SEED_5 (32'h154) +`endif +`ifndef HMAC_REG_HMAC512_LFSR_SEED_6 +`define HMAC_REG_HMAC512_LFSR_SEED_6 (32'h158) +`endif +`ifndef HMAC_REG_HMAC512_LFSR_SEED_7 +`define HMAC_REG_HMAC512_LFSR_SEED_7 (32'h15c) +`endif +`ifndef HMAC_REG_HMAC512_LFSR_SEED_8 +`define HMAC_REG_HMAC512_LFSR_SEED_8 (32'h160) +`endif +`ifndef HMAC_REG_HMAC512_LFSR_SEED_9 +`define HMAC_REG_HMAC512_LFSR_SEED_9 (32'h164) +`endif +`ifndef HMAC_REG_HMAC512_LFSR_SEED_10 +`define HMAC_REG_HMAC512_LFSR_SEED_10 (32'h168) +`endif +`ifndef HMAC_REG_HMAC512_LFSR_SEED_11 +`define HMAC_REG_HMAC512_LFSR_SEED_11 (32'h16c) +`endif +`ifndef HMAC_REG_HMAC512_KV_RD_KEY_CTRL +`define HMAC_REG_HMAC512_KV_RD_KEY_CTRL (32'h600) +`define HMAC_REG_HMAC512_KV_RD_KEY_CTRL_READ_EN_LOW (0) +`define HMAC_REG_HMAC512_KV_RD_KEY_CTRL_READ_EN_MASK (32'h1) +`define HMAC_REG_HMAC512_KV_RD_KEY_CTRL_READ_ENTRY_LOW (1) +`define HMAC_REG_HMAC512_KV_RD_KEY_CTRL_READ_ENTRY_MASK (32'h3e) +`define HMAC_REG_HMAC512_KV_RD_KEY_CTRL_PCR_HASH_EXTEND_LOW (6) +`define HMAC_REG_HMAC512_KV_RD_KEY_CTRL_PCR_HASH_EXTEND_MASK (32'h40) +`define HMAC_REG_HMAC512_KV_RD_KEY_CTRL_RSVD_LOW (7) +`define HMAC_REG_HMAC512_KV_RD_KEY_CTRL_RSVD_MASK (32'hffffff80) +`endif +`ifndef HMAC_REG_HMAC512_KV_RD_KEY_STATUS +`define HMAC_REG_HMAC512_KV_RD_KEY_STATUS (32'h604) +`define HMAC_REG_HMAC512_KV_RD_KEY_STATUS_READY_LOW (0) +`define HMAC_REG_HMAC512_KV_RD_KEY_STATUS_READY_MASK (32'h1) +`define HMAC_REG_HMAC512_KV_RD_KEY_STATUS_VALID_LOW (1) +`define HMAC_REG_HMAC512_KV_RD_KEY_STATUS_VALID_MASK (32'h2) +`define HMAC_REG_HMAC512_KV_RD_KEY_STATUS_ERROR_LOW (2) +`define HMAC_REG_HMAC512_KV_RD_KEY_STATUS_ERROR_MASK (32'h3fc) +`endif +`ifndef HMAC_REG_HMAC512_KV_RD_BLOCK_CTRL +`define HMAC_REG_HMAC512_KV_RD_BLOCK_CTRL (32'h608) +`define HMAC_REG_HMAC512_KV_RD_BLOCK_CTRL_READ_EN_LOW (0) +`define HMAC_REG_HMAC512_KV_RD_BLOCK_CTRL_READ_EN_MASK (32'h1) +`define HMAC_REG_HMAC512_KV_RD_BLOCK_CTRL_READ_ENTRY_LOW (1) +`define HMAC_REG_HMAC512_KV_RD_BLOCK_CTRL_READ_ENTRY_MASK (32'h3e) +`define HMAC_REG_HMAC512_KV_RD_BLOCK_CTRL_PCR_HASH_EXTEND_LOW (6) +`define HMAC_REG_HMAC512_KV_RD_BLOCK_CTRL_PCR_HASH_EXTEND_MASK (32'h40) +`define HMAC_REG_HMAC512_KV_RD_BLOCK_CTRL_RSVD_LOW (7) +`define HMAC_REG_HMAC512_KV_RD_BLOCK_CTRL_RSVD_MASK (32'hffffff80) +`endif +`ifndef HMAC_REG_HMAC512_KV_RD_BLOCK_STATUS +`define HMAC_REG_HMAC512_KV_RD_BLOCK_STATUS (32'h60c) +`define HMAC_REG_HMAC512_KV_RD_BLOCK_STATUS_READY_LOW (0) +`define HMAC_REG_HMAC512_KV_RD_BLOCK_STATUS_READY_MASK (32'h1) +`define HMAC_REG_HMAC512_KV_RD_BLOCK_STATUS_VALID_LOW (1) +`define HMAC_REG_HMAC512_KV_RD_BLOCK_STATUS_VALID_MASK (32'h2) +`define HMAC_REG_HMAC512_KV_RD_BLOCK_STATUS_ERROR_LOW (2) +`define HMAC_REG_HMAC512_KV_RD_BLOCK_STATUS_ERROR_MASK (32'h3fc) +`endif +`ifndef HMAC_REG_HMAC512_KV_WR_CTRL +`define HMAC_REG_HMAC512_KV_WR_CTRL (32'h610) +`define HMAC_REG_HMAC512_KV_WR_CTRL_WRITE_EN_LOW (0) +`define HMAC_REG_HMAC512_KV_WR_CTRL_WRITE_EN_MASK (32'h1) +`define HMAC_REG_HMAC512_KV_WR_CTRL_WRITE_ENTRY_LOW (1) +`define HMAC_REG_HMAC512_KV_WR_CTRL_WRITE_ENTRY_MASK (32'h3e) +`define HMAC_REG_HMAC512_KV_WR_CTRL_HMAC_KEY_DEST_VALID_LOW (6) +`define HMAC_REG_HMAC512_KV_WR_CTRL_HMAC_KEY_DEST_VALID_MASK (32'h40) +`define HMAC_REG_HMAC512_KV_WR_CTRL_HMAC_BLOCK_DEST_VALID_LOW (7) +`define HMAC_REG_HMAC512_KV_WR_CTRL_HMAC_BLOCK_DEST_VALID_MASK (32'h80) +`define HMAC_REG_HMAC512_KV_WR_CTRL_MLDSA_SEED_DEST_VALID_LOW (8) +`define HMAC_REG_HMAC512_KV_WR_CTRL_MLDSA_SEED_DEST_VALID_MASK (32'h100) +`define HMAC_REG_HMAC512_KV_WR_CTRL_ECC_PKEY_DEST_VALID_LOW (9) +`define HMAC_REG_HMAC512_KV_WR_CTRL_ECC_PKEY_DEST_VALID_MASK (32'h200) +`define HMAC_REG_HMAC512_KV_WR_CTRL_ECC_SEED_DEST_VALID_LOW (10) +`define HMAC_REG_HMAC512_KV_WR_CTRL_ECC_SEED_DEST_VALID_MASK (32'h400) +`define HMAC_REG_HMAC512_KV_WR_CTRL_AES_KEY_DEST_VALID_LOW (11) +`define HMAC_REG_HMAC512_KV_WR_CTRL_AES_KEY_DEST_VALID_MASK (32'h800) +`define HMAC_REG_HMAC512_KV_WR_CTRL_MLKEM_SEED_DEST_VALID_LOW (12) +`define HMAC_REG_HMAC512_KV_WR_CTRL_MLKEM_SEED_DEST_VALID_MASK (32'h1000) +`define HMAC_REG_HMAC512_KV_WR_CTRL_MLKEM_MSG_DEST_VALID_LOW (13) +`define HMAC_REG_HMAC512_KV_WR_CTRL_MLKEM_MSG_DEST_VALID_MASK (32'h2000) +`define HMAC_REG_HMAC512_KV_WR_CTRL_DMA_DATA_DEST_VALID_LOW (14) +`define HMAC_REG_HMAC512_KV_WR_CTRL_DMA_DATA_DEST_VALID_MASK (32'h4000) +`define HMAC_REG_HMAC512_KV_WR_CTRL_RSVD_LOW (15) +`define HMAC_REG_HMAC512_KV_WR_CTRL_RSVD_MASK (32'hffff8000) +`endif +`ifndef HMAC_REG_HMAC512_KV_WR_STATUS +`define HMAC_REG_HMAC512_KV_WR_STATUS (32'h614) +`define HMAC_REG_HMAC512_KV_WR_STATUS_READY_LOW (0) +`define HMAC_REG_HMAC512_KV_WR_STATUS_READY_MASK (32'h1) +`define HMAC_REG_HMAC512_KV_WR_STATUS_VALID_LOW (1) +`define HMAC_REG_HMAC512_KV_WR_STATUS_VALID_MASK (32'h2) +`define HMAC_REG_HMAC512_KV_WR_STATUS_ERROR_LOW (2) +`define HMAC_REG_HMAC512_KV_WR_STATUS_ERROR_MASK (32'h3fc) +`endif +`ifndef HMAC_REG_INTR_BLOCK_RF_GLOBAL_INTR_EN_R +`define HMAC_REG_INTR_BLOCK_RF_GLOBAL_INTR_EN_R (32'h800) +`define HMAC_REG_INTR_BLOCK_RF_GLOBAL_INTR_EN_R_ERROR_EN_LOW (0) +`define HMAC_REG_INTR_BLOCK_RF_GLOBAL_INTR_EN_R_ERROR_EN_MASK (32'h1) +`define HMAC_REG_INTR_BLOCK_RF_GLOBAL_INTR_EN_R_NOTIF_EN_LOW (1) +`define HMAC_REG_INTR_BLOCK_RF_GLOBAL_INTR_EN_R_NOTIF_EN_MASK (32'h2) +`endif +`ifndef HMAC_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R +`define HMAC_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R (32'h804) +`define HMAC_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R_KEY_MODE_ERROR_EN_LOW (0) +`define HMAC_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R_KEY_MODE_ERROR_EN_MASK (32'h1) +`define HMAC_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R_KEY_ZERO_ERROR_EN_LOW (1) +`define HMAC_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R_KEY_ZERO_ERROR_EN_MASK (32'h2) +`define HMAC_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R_ERROR2_EN_LOW (2) +`define HMAC_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R_ERROR2_EN_MASK (32'h4) +`define HMAC_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R_ERROR3_EN_LOW (3) +`define HMAC_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R_ERROR3_EN_MASK (32'h8) +`endif +`ifndef HMAC_REG_INTR_BLOCK_RF_NOTIF_INTR_EN_R +`define HMAC_REG_INTR_BLOCK_RF_NOTIF_INTR_EN_R (32'h808) +`define HMAC_REG_INTR_BLOCK_RF_NOTIF_INTR_EN_R_NOTIF_CMD_DONE_EN_LOW (0) +`define HMAC_REG_INTR_BLOCK_RF_NOTIF_INTR_EN_R_NOTIF_CMD_DONE_EN_MASK (32'h1) +`endif +`ifndef HMAC_REG_INTR_BLOCK_RF_ERROR_GLOBAL_INTR_R +`define HMAC_REG_INTR_BLOCK_RF_ERROR_GLOBAL_INTR_R (32'h80c) +`define HMAC_REG_INTR_BLOCK_RF_ERROR_GLOBAL_INTR_R_AGG_STS_LOW (0) +`define HMAC_REG_INTR_BLOCK_RF_ERROR_GLOBAL_INTR_R_AGG_STS_MASK (32'h1) +`endif +`ifndef HMAC_REG_INTR_BLOCK_RF_NOTIF_GLOBAL_INTR_R +`define HMAC_REG_INTR_BLOCK_RF_NOTIF_GLOBAL_INTR_R (32'h810) +`define HMAC_REG_INTR_BLOCK_RF_NOTIF_GLOBAL_INTR_R_AGG_STS_LOW (0) +`define HMAC_REG_INTR_BLOCK_RF_NOTIF_GLOBAL_INTR_R_AGG_STS_MASK (32'h1) +`endif +`ifndef HMAC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R +`define HMAC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R (32'h814) +`define HMAC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_KEY_MODE_ERROR_STS_LOW (0) +`define HMAC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_KEY_MODE_ERROR_STS_MASK (32'h1) +`define HMAC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_KEY_ZERO_ERROR_STS_LOW (1) +`define HMAC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_KEY_ZERO_ERROR_STS_MASK (32'h2) +`define HMAC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR2_STS_LOW (2) +`define HMAC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR2_STS_MASK (32'h4) +`define HMAC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR3_STS_LOW (3) +`define HMAC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR3_STS_MASK (32'h8) +`endif +`ifndef HMAC_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R +`define HMAC_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R (32'h818) +`define HMAC_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_CMD_DONE_STS_LOW (0) +`define HMAC_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_CMD_DONE_STS_MASK (32'h1) +`endif +`ifndef HMAC_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R +`define HMAC_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R (32'h81c) +`define HMAC_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R_KEY_MODE_ERROR_TRIG_LOW (0) +`define HMAC_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R_KEY_MODE_ERROR_TRIG_MASK (32'h1) +`define HMAC_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R_KEY_ZERO_ERROR_TRIG_LOW (1) +`define HMAC_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R_KEY_ZERO_ERROR_TRIG_MASK (32'h2) +`define HMAC_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R_ERROR2_TRIG_LOW (2) +`define HMAC_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R_ERROR2_TRIG_MASK (32'h4) +`define HMAC_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R_ERROR3_TRIG_LOW (3) +`define HMAC_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R_ERROR3_TRIG_MASK (32'h8) +`endif +`ifndef HMAC_REG_INTR_BLOCK_RF_NOTIF_INTR_TRIG_R +`define HMAC_REG_INTR_BLOCK_RF_NOTIF_INTR_TRIG_R (32'h820) +`define HMAC_REG_INTR_BLOCK_RF_NOTIF_INTR_TRIG_R_NOTIF_CMD_DONE_TRIG_LOW (0) +`define HMAC_REG_INTR_BLOCK_RF_NOTIF_INTR_TRIG_R_NOTIF_CMD_DONE_TRIG_MASK (32'h1) +`endif +`ifndef HMAC_REG_INTR_BLOCK_RF_KEY_MODE_ERROR_INTR_COUNT_R +`define HMAC_REG_INTR_BLOCK_RF_KEY_MODE_ERROR_INTR_COUNT_R (32'h900) +`endif +`ifndef HMAC_REG_INTR_BLOCK_RF_KEY_ZERO_ERROR_INTR_COUNT_R +`define HMAC_REG_INTR_BLOCK_RF_KEY_ZERO_ERROR_INTR_COUNT_R (32'h904) +`endif +`ifndef HMAC_REG_INTR_BLOCK_RF_ERROR2_INTR_COUNT_R +`define HMAC_REG_INTR_BLOCK_RF_ERROR2_INTR_COUNT_R (32'h908) +`endif +`ifndef HMAC_REG_INTR_BLOCK_RF_ERROR3_INTR_COUNT_R +`define HMAC_REG_INTR_BLOCK_RF_ERROR3_INTR_COUNT_R (32'h90c) +`endif +`ifndef HMAC_REG_INTR_BLOCK_RF_NOTIF_CMD_DONE_INTR_COUNT_R +`define HMAC_REG_INTR_BLOCK_RF_NOTIF_CMD_DONE_INTR_COUNT_R (32'h980) +`endif +`ifndef HMAC_REG_INTR_BLOCK_RF_KEY_MODE_ERROR_INTR_COUNT_INCR_R +`define HMAC_REG_INTR_BLOCK_RF_KEY_MODE_ERROR_INTR_COUNT_INCR_R (32'ha00) +`define HMAC_REG_INTR_BLOCK_RF_KEY_MODE_ERROR_INTR_COUNT_INCR_R_PULSE_LOW (0) +`define HMAC_REG_INTR_BLOCK_RF_KEY_MODE_ERROR_INTR_COUNT_INCR_R_PULSE_MASK (32'h1) +`endif +`ifndef HMAC_REG_INTR_BLOCK_RF_KEY_ZERO_ERROR_INTR_COUNT_INCR_R +`define HMAC_REG_INTR_BLOCK_RF_KEY_ZERO_ERROR_INTR_COUNT_INCR_R (32'ha04) +`define HMAC_REG_INTR_BLOCK_RF_KEY_ZERO_ERROR_INTR_COUNT_INCR_R_PULSE_LOW (0) +`define HMAC_REG_INTR_BLOCK_RF_KEY_ZERO_ERROR_INTR_COUNT_INCR_R_PULSE_MASK (32'h1) +`endif +`ifndef HMAC_REG_INTR_BLOCK_RF_ERROR2_INTR_COUNT_INCR_R +`define HMAC_REG_INTR_BLOCK_RF_ERROR2_INTR_COUNT_INCR_R (32'ha08) +`define HMAC_REG_INTR_BLOCK_RF_ERROR2_INTR_COUNT_INCR_R_PULSE_LOW (0) +`define HMAC_REG_INTR_BLOCK_RF_ERROR2_INTR_COUNT_INCR_R_PULSE_MASK (32'h1) +`endif +`ifndef HMAC_REG_INTR_BLOCK_RF_ERROR3_INTR_COUNT_INCR_R +`define HMAC_REG_INTR_BLOCK_RF_ERROR3_INTR_COUNT_INCR_R (32'ha0c) +`define HMAC_REG_INTR_BLOCK_RF_ERROR3_INTR_COUNT_INCR_R_PULSE_LOW (0) +`define HMAC_REG_INTR_BLOCK_RF_ERROR3_INTR_COUNT_INCR_R_PULSE_MASK (32'h1) +`endif +`ifndef HMAC_REG_INTR_BLOCK_RF_NOTIF_CMD_DONE_INTR_COUNT_INCR_R +`define HMAC_REG_INTR_BLOCK_RF_NOTIF_CMD_DONE_INTR_COUNT_INCR_R (32'ha10) +`define HMAC_REG_INTR_BLOCK_RF_NOTIF_CMD_DONE_INTR_COUNT_INCR_R_PULSE_LOW (0) +`define HMAC_REG_INTR_BLOCK_RF_NOTIF_CMD_DONE_INTR_COUNT_INCR_R_PULSE_MASK (32'h1) +`endif +`ifndef AES_REG_KEY_SHARE0_0 +`define AES_REG_KEY_SHARE0_0 (32'h4) +`endif +`ifndef AES_REG_KEY_SHARE0_1 +`define AES_REG_KEY_SHARE0_1 (32'h8) +`endif +`ifndef AES_REG_KEY_SHARE0_2 +`define AES_REG_KEY_SHARE0_2 (32'hc) +`endif +`ifndef AES_REG_KEY_SHARE0_3 +`define AES_REG_KEY_SHARE0_3 (32'h10) +`endif +`ifndef AES_REG_KEY_SHARE0_4 +`define AES_REG_KEY_SHARE0_4 (32'h14) +`endif +`ifndef AES_REG_KEY_SHARE0_5 +`define AES_REG_KEY_SHARE0_5 (32'h18) +`endif +`ifndef AES_REG_KEY_SHARE0_6 +`define AES_REG_KEY_SHARE0_6 (32'h1c) +`endif +`ifndef AES_REG_KEY_SHARE0_7 +`define AES_REG_KEY_SHARE0_7 (32'h20) +`endif +`ifndef AES_REG_KEY_SHARE1_0 +`define AES_REG_KEY_SHARE1_0 (32'h24) +`endif +`ifndef AES_REG_KEY_SHARE1_1 +`define AES_REG_KEY_SHARE1_1 (32'h28) +`endif +`ifndef AES_REG_KEY_SHARE1_2 +`define AES_REG_KEY_SHARE1_2 (32'h2c) +`endif +`ifndef AES_REG_KEY_SHARE1_3 +`define AES_REG_KEY_SHARE1_3 (32'h30) +`endif +`ifndef AES_REG_KEY_SHARE1_4 +`define AES_REG_KEY_SHARE1_4 (32'h34) +`endif +`ifndef AES_REG_KEY_SHARE1_5 +`define AES_REG_KEY_SHARE1_5 (32'h38) +`endif +`ifndef AES_REG_KEY_SHARE1_6 +`define AES_REG_KEY_SHARE1_6 (32'h3c) +`endif +`ifndef AES_REG_KEY_SHARE1_7 +`define AES_REG_KEY_SHARE1_7 (32'h40) +`endif +`ifndef AES_REG_IV_0 +`define AES_REG_IV_0 (32'h44) +`endif +`ifndef AES_REG_IV_1 +`define AES_REG_IV_1 (32'h48) +`endif +`ifndef AES_REG_IV_2 +`define AES_REG_IV_2 (32'h4c) +`endif +`ifndef AES_REG_IV_3 +`define AES_REG_IV_3 (32'h50) +`endif +`ifndef AES_REG_DATA_IN_0 +`define AES_REG_DATA_IN_0 (32'h54) +`endif +`ifndef AES_REG_DATA_IN_1 +`define AES_REG_DATA_IN_1 (32'h58) +`endif +`ifndef AES_REG_DATA_IN_2 +`define AES_REG_DATA_IN_2 (32'h5c) +`endif +`ifndef AES_REG_DATA_IN_3 +`define AES_REG_DATA_IN_3 (32'h60) +`endif +`ifndef AES_REG_DATA_OUT_0 +`define AES_REG_DATA_OUT_0 (32'h64) +`endif +`ifndef AES_REG_DATA_OUT_1 +`define AES_REG_DATA_OUT_1 (32'h68) +`endif +`ifndef AES_REG_DATA_OUT_2 +`define AES_REG_DATA_OUT_2 (32'h6c) +`endif +`ifndef AES_REG_DATA_OUT_3 +`define AES_REG_DATA_OUT_3 (32'h70) +`endif +`ifndef AES_REG_CTRL_SHADOWED +`define AES_REG_CTRL_SHADOWED (32'h74) +`define AES_REG_CTRL_SHADOWED_OPERATION_LOW (0) +`define AES_REG_CTRL_SHADOWED_OPERATION_MASK (32'h3) +`define AES_REG_CTRL_SHADOWED_MODE_LOW (2) +`define AES_REG_CTRL_SHADOWED_MODE_MASK (32'hfc) +`define AES_REG_CTRL_SHADOWED_KEY_LEN_LOW (8) +`define AES_REG_CTRL_SHADOWED_KEY_LEN_MASK (32'h700) +`define AES_REG_CTRL_SHADOWED_SIDELOAD_LOW (11) +`define AES_REG_CTRL_SHADOWED_SIDELOAD_MASK (32'h800) +`define AES_REG_CTRL_SHADOWED_PRNG_RESEED_RATE_LOW (12) +`define AES_REG_CTRL_SHADOWED_PRNG_RESEED_RATE_MASK (32'h7000) +`define AES_REG_CTRL_SHADOWED_MANUAL_OPERATION_LOW (15) +`define AES_REG_CTRL_SHADOWED_MANUAL_OPERATION_MASK (32'h8000) +`endif +`ifndef AES_REG_CTRL_AUX_SHADOWED +`define AES_REG_CTRL_AUX_SHADOWED (32'h78) +`define AES_REG_CTRL_AUX_SHADOWED_KEY_TOUCH_FORCES_RESEED_LOW (0) +`define AES_REG_CTRL_AUX_SHADOWED_KEY_TOUCH_FORCES_RESEED_MASK (32'h1) +`define AES_REG_CTRL_AUX_SHADOWED_FORCE_MASKS_LOW (1) +`define AES_REG_CTRL_AUX_SHADOWED_FORCE_MASKS_MASK (32'h2) +`endif +`ifndef AES_REG_CTRL_AUX_REGWEN +`define AES_REG_CTRL_AUX_REGWEN (32'h7c) +`define AES_REG_CTRL_AUX_REGWEN_CTRL_AUX_REGWEN_LOW (0) +`define AES_REG_CTRL_AUX_REGWEN_CTRL_AUX_REGWEN_MASK (32'h1) +`endif +`ifndef AES_REG_TRIGGER +`define AES_REG_TRIGGER (32'h80) +`define AES_REG_TRIGGER_START_LOW (0) +`define AES_REG_TRIGGER_START_MASK (32'h1) +`define AES_REG_TRIGGER_KEY_IV_DATA_IN_CLEAR_LOW (1) +`define AES_REG_TRIGGER_KEY_IV_DATA_IN_CLEAR_MASK (32'h2) +`define AES_REG_TRIGGER_DATA_OUT_CLEAR_LOW (2) +`define AES_REG_TRIGGER_DATA_OUT_CLEAR_MASK (32'h4) +`define AES_REG_TRIGGER_PRNG_RESEED_LOW (3) +`define AES_REG_TRIGGER_PRNG_RESEED_MASK (32'h8) +`endif +`ifndef AES_REG_STATUS +`define AES_REG_STATUS (32'h84) +`define AES_REG_STATUS_IDLE_LOW (0) +`define AES_REG_STATUS_IDLE_MASK (32'h1) +`define AES_REG_STATUS_STALL_LOW (1) +`define AES_REG_STATUS_STALL_MASK (32'h2) +`define AES_REG_STATUS_OUTPUT_LOST_LOW (2) +`define AES_REG_STATUS_OUTPUT_LOST_MASK (32'h4) +`define AES_REG_STATUS_OUTPUT_VALID_LOW (3) +`define AES_REG_STATUS_OUTPUT_VALID_MASK (32'h8) +`define AES_REG_STATUS_INPUT_READY_LOW (4) +`define AES_REG_STATUS_INPUT_READY_MASK (32'h10) +`define AES_REG_STATUS_ALERT_RECOV_CTRL_UPDATE_ERR_LOW (5) +`define AES_REG_STATUS_ALERT_RECOV_CTRL_UPDATE_ERR_MASK (32'h20) +`define AES_REG_STATUS_ALERT_FATAL_FAULT_LOW (6) +`define AES_REG_STATUS_ALERT_FATAL_FAULT_MASK (32'h40) +`endif +`ifndef AES_REG_CTRL_GCM_SHADOWED +`define AES_REG_CTRL_GCM_SHADOWED (32'h88) +`define AES_REG_CTRL_GCM_SHADOWED_PHASE_LOW (0) +`define AES_REG_CTRL_GCM_SHADOWED_PHASE_MASK (32'h3f) +`define AES_REG_CTRL_GCM_SHADOWED_NUM_VALID_BYTES_LOW (6) +`define AES_REG_CTRL_GCM_SHADOWED_NUM_VALID_BYTES_MASK (32'h7c0) +`endif +`ifndef AES_CLP_REG_AES_NAME_0 +`define AES_CLP_REG_AES_NAME_0 (32'h0) +`endif +`ifndef AES_CLP_REG_AES_NAME_1 +`define AES_CLP_REG_AES_NAME_1 (32'h4) +`endif +`ifndef AES_CLP_REG_AES_VERSION_0 +`define AES_CLP_REG_AES_VERSION_0 (32'h8) +`endif +`ifndef AES_CLP_REG_AES_VERSION_1 +`define AES_CLP_REG_AES_VERSION_1 (32'hc) +`endif +`ifndef AES_CLP_REG_ENTROPY_IF_SEED_0 +`define AES_CLP_REG_ENTROPY_IF_SEED_0 (32'h110) +`endif +`ifndef AES_CLP_REG_ENTROPY_IF_SEED_1 +`define AES_CLP_REG_ENTROPY_IF_SEED_1 (32'h114) +`endif +`ifndef AES_CLP_REG_ENTROPY_IF_SEED_2 +`define AES_CLP_REG_ENTROPY_IF_SEED_2 (32'h118) +`endif +`ifndef AES_CLP_REG_ENTROPY_IF_SEED_3 +`define AES_CLP_REG_ENTROPY_IF_SEED_3 (32'h11c) +`endif +`ifndef AES_CLP_REG_ENTROPY_IF_SEED_4 +`define AES_CLP_REG_ENTROPY_IF_SEED_4 (32'h120) +`endif +`ifndef AES_CLP_REG_ENTROPY_IF_SEED_5 +`define AES_CLP_REG_ENTROPY_IF_SEED_5 (32'h124) +`endif +`ifndef AES_CLP_REG_ENTROPY_IF_SEED_6 +`define AES_CLP_REG_ENTROPY_IF_SEED_6 (32'h128) +`endif +`ifndef AES_CLP_REG_ENTROPY_IF_SEED_7 +`define AES_CLP_REG_ENTROPY_IF_SEED_7 (32'h12c) +`endif +`ifndef AES_CLP_REG_ENTROPY_IF_SEED_8 +`define AES_CLP_REG_ENTROPY_IF_SEED_8 (32'h130) +`endif +`ifndef AES_CLP_REG_CTRL0 +`define AES_CLP_REG_CTRL0 (32'h134) +`define AES_CLP_REG_CTRL0_ENDIAN_SWAP_LOW (0) +`define AES_CLP_REG_CTRL0_ENDIAN_SWAP_MASK (32'h1) +`endif +`ifndef AES_CLP_REG_AES_KV_RD_KEY_CTRL +`define AES_CLP_REG_AES_KV_RD_KEY_CTRL (32'h200) +`define AES_CLP_REG_AES_KV_RD_KEY_CTRL_READ_EN_LOW (0) +`define AES_CLP_REG_AES_KV_RD_KEY_CTRL_READ_EN_MASK (32'h1) +`define AES_CLP_REG_AES_KV_RD_KEY_CTRL_READ_ENTRY_LOW (1) +`define AES_CLP_REG_AES_KV_RD_KEY_CTRL_READ_ENTRY_MASK (32'h3e) +`define AES_CLP_REG_AES_KV_RD_KEY_CTRL_PCR_HASH_EXTEND_LOW (6) +`define AES_CLP_REG_AES_KV_RD_KEY_CTRL_PCR_HASH_EXTEND_MASK (32'h40) +`define AES_CLP_REG_AES_KV_RD_KEY_CTRL_RSVD_LOW (7) +`define AES_CLP_REG_AES_KV_RD_KEY_CTRL_RSVD_MASK (32'hffffff80) +`endif +`ifndef AES_CLP_REG_AES_KV_RD_KEY_STATUS +`define AES_CLP_REG_AES_KV_RD_KEY_STATUS (32'h204) +`define AES_CLP_REG_AES_KV_RD_KEY_STATUS_READY_LOW (0) +`define AES_CLP_REG_AES_KV_RD_KEY_STATUS_READY_MASK (32'h1) +`define AES_CLP_REG_AES_KV_RD_KEY_STATUS_VALID_LOW (1) +`define AES_CLP_REG_AES_KV_RD_KEY_STATUS_VALID_MASK (32'h2) +`define AES_CLP_REG_AES_KV_RD_KEY_STATUS_ERROR_LOW (2) +`define AES_CLP_REG_AES_KV_RD_KEY_STATUS_ERROR_MASK (32'h3fc) +`endif +`ifndef AES_CLP_REG_AES_KV_WR_CTRL +`define AES_CLP_REG_AES_KV_WR_CTRL (32'h208) +`define AES_CLP_REG_AES_KV_WR_CTRL_WRITE_EN_LOW (0) +`define AES_CLP_REG_AES_KV_WR_CTRL_WRITE_EN_MASK (32'h1) +`define AES_CLP_REG_AES_KV_WR_CTRL_WRITE_ENTRY_LOW (1) +`define AES_CLP_REG_AES_KV_WR_CTRL_WRITE_ENTRY_MASK (32'h3e) +`define AES_CLP_REG_AES_KV_WR_CTRL_HMAC_KEY_DEST_VALID_LOW (6) +`define AES_CLP_REG_AES_KV_WR_CTRL_HMAC_KEY_DEST_VALID_MASK (32'h40) +`define AES_CLP_REG_AES_KV_WR_CTRL_HMAC_BLOCK_DEST_VALID_LOW (7) +`define AES_CLP_REG_AES_KV_WR_CTRL_HMAC_BLOCK_DEST_VALID_MASK (32'h80) +`define AES_CLP_REG_AES_KV_WR_CTRL_MLDSA_SEED_DEST_VALID_LOW (8) +`define AES_CLP_REG_AES_KV_WR_CTRL_MLDSA_SEED_DEST_VALID_MASK (32'h100) +`define AES_CLP_REG_AES_KV_WR_CTRL_ECC_PKEY_DEST_VALID_LOW (9) +`define AES_CLP_REG_AES_KV_WR_CTRL_ECC_PKEY_DEST_VALID_MASK (32'h200) +`define AES_CLP_REG_AES_KV_WR_CTRL_ECC_SEED_DEST_VALID_LOW (10) +`define AES_CLP_REG_AES_KV_WR_CTRL_ECC_SEED_DEST_VALID_MASK (32'h400) +`define AES_CLP_REG_AES_KV_WR_CTRL_AES_KEY_DEST_VALID_LOW (11) +`define AES_CLP_REG_AES_KV_WR_CTRL_AES_KEY_DEST_VALID_MASK (32'h800) +`define AES_CLP_REG_AES_KV_WR_CTRL_MLKEM_SEED_DEST_VALID_LOW (12) +`define AES_CLP_REG_AES_KV_WR_CTRL_MLKEM_SEED_DEST_VALID_MASK (32'h1000) +`define AES_CLP_REG_AES_KV_WR_CTRL_MLKEM_MSG_DEST_VALID_LOW (13) +`define AES_CLP_REG_AES_KV_WR_CTRL_MLKEM_MSG_DEST_VALID_MASK (32'h2000) +`define AES_CLP_REG_AES_KV_WR_CTRL_DMA_DATA_DEST_VALID_LOW (14) +`define AES_CLP_REG_AES_KV_WR_CTRL_DMA_DATA_DEST_VALID_MASK (32'h4000) +`define AES_CLP_REG_AES_KV_WR_CTRL_RSVD_LOW (15) +`define AES_CLP_REG_AES_KV_WR_CTRL_RSVD_MASK (32'hffff8000) +`endif +`ifndef AES_CLP_REG_AES_KV_WR_STATUS +`define AES_CLP_REG_AES_KV_WR_STATUS (32'h20c) +`define AES_CLP_REG_AES_KV_WR_STATUS_READY_LOW (0) +`define AES_CLP_REG_AES_KV_WR_STATUS_READY_MASK (32'h1) +`define AES_CLP_REG_AES_KV_WR_STATUS_VALID_LOW (1) +`define AES_CLP_REG_AES_KV_WR_STATUS_VALID_MASK (32'h2) +`define AES_CLP_REG_AES_KV_WR_STATUS_ERROR_LOW (2) +`define AES_CLP_REG_AES_KV_WR_STATUS_ERROR_MASK (32'h3fc) +`endif +`ifndef AES_CLP_REG_INTR_BLOCK_RF_GLOBAL_INTR_EN_R +`define AES_CLP_REG_INTR_BLOCK_RF_GLOBAL_INTR_EN_R (32'h400) +`define AES_CLP_REG_INTR_BLOCK_RF_GLOBAL_INTR_EN_R_ERROR_EN_LOW (0) +`define AES_CLP_REG_INTR_BLOCK_RF_GLOBAL_INTR_EN_R_ERROR_EN_MASK (32'h1) +`define AES_CLP_REG_INTR_BLOCK_RF_GLOBAL_INTR_EN_R_NOTIF_EN_LOW (1) +`define AES_CLP_REG_INTR_BLOCK_RF_GLOBAL_INTR_EN_R_NOTIF_EN_MASK (32'h2) +`endif +`ifndef AES_CLP_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R +`define AES_CLP_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R (32'h404) +`define AES_CLP_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R_ERROR0_EN_LOW (0) +`define AES_CLP_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R_ERROR0_EN_MASK (32'h1) +`define AES_CLP_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R_ERROR1_EN_LOW (1) +`define AES_CLP_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R_ERROR1_EN_MASK (32'h2) +`define AES_CLP_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R_ERROR2_EN_LOW (2) +`define AES_CLP_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R_ERROR2_EN_MASK (32'h4) +`define AES_CLP_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R_ERROR3_EN_LOW (3) +`define AES_CLP_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R_ERROR3_EN_MASK (32'h8) +`endif +`ifndef AES_CLP_REG_INTR_BLOCK_RF_NOTIF_INTR_EN_R +`define AES_CLP_REG_INTR_BLOCK_RF_NOTIF_INTR_EN_R (32'h408) +`define AES_CLP_REG_INTR_BLOCK_RF_NOTIF_INTR_EN_R_NOTIF_CMD_DONE_EN_LOW (0) +`define AES_CLP_REG_INTR_BLOCK_RF_NOTIF_INTR_EN_R_NOTIF_CMD_DONE_EN_MASK (32'h1) +`endif +`ifndef AES_CLP_REG_INTR_BLOCK_RF_ERROR_GLOBAL_INTR_R +`define AES_CLP_REG_INTR_BLOCK_RF_ERROR_GLOBAL_INTR_R (32'h40c) +`define AES_CLP_REG_INTR_BLOCK_RF_ERROR_GLOBAL_INTR_R_AGG_STS_LOW (0) +`define AES_CLP_REG_INTR_BLOCK_RF_ERROR_GLOBAL_INTR_R_AGG_STS_MASK (32'h1) +`endif +`ifndef AES_CLP_REG_INTR_BLOCK_RF_NOTIF_GLOBAL_INTR_R +`define AES_CLP_REG_INTR_BLOCK_RF_NOTIF_GLOBAL_INTR_R (32'h410) +`define AES_CLP_REG_INTR_BLOCK_RF_NOTIF_GLOBAL_INTR_R_AGG_STS_LOW (0) +`define AES_CLP_REG_INTR_BLOCK_RF_NOTIF_GLOBAL_INTR_R_AGG_STS_MASK (32'h1) +`endif +`ifndef AES_CLP_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R +`define AES_CLP_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R (32'h414) +`define AES_CLP_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR0_STS_LOW (0) +`define AES_CLP_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR0_STS_MASK (32'h1) +`define AES_CLP_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR1_STS_LOW (1) +`define AES_CLP_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR1_STS_MASK (32'h2) +`define AES_CLP_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR2_STS_LOW (2) +`define AES_CLP_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR2_STS_MASK (32'h4) +`define AES_CLP_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR3_STS_LOW (3) +`define AES_CLP_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR3_STS_MASK (32'h8) +`endif +`ifndef AES_CLP_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R +`define AES_CLP_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R (32'h418) +`define AES_CLP_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_CMD_DONE_STS_LOW (0) +`define AES_CLP_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_CMD_DONE_STS_MASK (32'h1) +`endif +`ifndef AES_CLP_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R +`define AES_CLP_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R (32'h41c) +`define AES_CLP_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R_ERROR0_TRIG_LOW (0) +`define AES_CLP_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R_ERROR0_TRIG_MASK (32'h1) +`define AES_CLP_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R_ERROR1_TRIG_LOW (1) +`define AES_CLP_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R_ERROR1_TRIG_MASK (32'h2) +`define AES_CLP_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R_ERROR2_TRIG_LOW (2) +`define AES_CLP_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R_ERROR2_TRIG_MASK (32'h4) +`define AES_CLP_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R_ERROR3_TRIG_LOW (3) +`define AES_CLP_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R_ERROR3_TRIG_MASK (32'h8) +`endif +`ifndef AES_CLP_REG_INTR_BLOCK_RF_NOTIF_INTR_TRIG_R +`define AES_CLP_REG_INTR_BLOCK_RF_NOTIF_INTR_TRIG_R (32'h420) +`define AES_CLP_REG_INTR_BLOCK_RF_NOTIF_INTR_TRIG_R_NOTIF_CMD_DONE_TRIG_LOW (0) +`define AES_CLP_REG_INTR_BLOCK_RF_NOTIF_INTR_TRIG_R_NOTIF_CMD_DONE_TRIG_MASK (32'h1) +`endif +`ifndef AES_CLP_REG_INTR_BLOCK_RF_ERROR0_INTR_COUNT_R +`define AES_CLP_REG_INTR_BLOCK_RF_ERROR0_INTR_COUNT_R (32'h500) +`endif +`ifndef AES_CLP_REG_INTR_BLOCK_RF_ERROR1_INTR_COUNT_R +`define AES_CLP_REG_INTR_BLOCK_RF_ERROR1_INTR_COUNT_R (32'h504) +`endif +`ifndef AES_CLP_REG_INTR_BLOCK_RF_ERROR2_INTR_COUNT_R +`define AES_CLP_REG_INTR_BLOCK_RF_ERROR2_INTR_COUNT_R (32'h508) +`endif +`ifndef AES_CLP_REG_INTR_BLOCK_RF_ERROR3_INTR_COUNT_R +`define AES_CLP_REG_INTR_BLOCK_RF_ERROR3_INTR_COUNT_R (32'h50c) +`endif +`ifndef AES_CLP_REG_INTR_BLOCK_RF_NOTIF_CMD_DONE_INTR_COUNT_R +`define AES_CLP_REG_INTR_BLOCK_RF_NOTIF_CMD_DONE_INTR_COUNT_R (32'h580) +`endif +`ifndef AES_CLP_REG_INTR_BLOCK_RF_ERROR0_INTR_COUNT_INCR_R +`define AES_CLP_REG_INTR_BLOCK_RF_ERROR0_INTR_COUNT_INCR_R (32'h600) +`define AES_CLP_REG_INTR_BLOCK_RF_ERROR0_INTR_COUNT_INCR_R_PULSE_LOW (0) +`define AES_CLP_REG_INTR_BLOCK_RF_ERROR0_INTR_COUNT_INCR_R_PULSE_MASK (32'h1) +`endif +`ifndef AES_CLP_REG_INTR_BLOCK_RF_ERROR1_INTR_COUNT_INCR_R +`define AES_CLP_REG_INTR_BLOCK_RF_ERROR1_INTR_COUNT_INCR_R (32'h604) +`define AES_CLP_REG_INTR_BLOCK_RF_ERROR1_INTR_COUNT_INCR_R_PULSE_LOW (0) +`define AES_CLP_REG_INTR_BLOCK_RF_ERROR1_INTR_COUNT_INCR_R_PULSE_MASK (32'h1) +`endif +`ifndef AES_CLP_REG_INTR_BLOCK_RF_ERROR2_INTR_COUNT_INCR_R +`define AES_CLP_REG_INTR_BLOCK_RF_ERROR2_INTR_COUNT_INCR_R (32'h608) +`define AES_CLP_REG_INTR_BLOCK_RF_ERROR2_INTR_COUNT_INCR_R_PULSE_LOW (0) +`define AES_CLP_REG_INTR_BLOCK_RF_ERROR2_INTR_COUNT_INCR_R_PULSE_MASK (32'h1) +`endif +`ifndef AES_CLP_REG_INTR_BLOCK_RF_ERROR3_INTR_COUNT_INCR_R +`define AES_CLP_REG_INTR_BLOCK_RF_ERROR3_INTR_COUNT_INCR_R (32'h60c) +`define AES_CLP_REG_INTR_BLOCK_RF_ERROR3_INTR_COUNT_INCR_R_PULSE_LOW (0) +`define AES_CLP_REG_INTR_BLOCK_RF_ERROR3_INTR_COUNT_INCR_R_PULSE_MASK (32'h1) +`endif +`ifndef AES_CLP_REG_INTR_BLOCK_RF_NOTIF_CMD_DONE_INTR_COUNT_INCR_R +`define AES_CLP_REG_INTR_BLOCK_RF_NOTIF_CMD_DONE_INTR_COUNT_INCR_R (32'h610) +`define AES_CLP_REG_INTR_BLOCK_RF_NOTIF_CMD_DONE_INTR_COUNT_INCR_R_PULSE_LOW (0) +`define AES_CLP_REG_INTR_BLOCK_RF_NOTIF_CMD_DONE_INTR_COUNT_INCR_R_PULSE_MASK (32'h1) +`endif +`ifndef KV_REG_KEY_CTRL_0 +`define KV_REG_KEY_CTRL_0 (32'h0) +`define KV_REG_KEY_CTRL_0_LOCK_WR_LOW (0) +`define KV_REG_KEY_CTRL_0_LOCK_WR_MASK (32'h1) +`define KV_REG_KEY_CTRL_0_LOCK_USE_LOW (1) +`define KV_REG_KEY_CTRL_0_LOCK_USE_MASK (32'h2) +`define KV_REG_KEY_CTRL_0_CLEAR_LOW (2) +`define KV_REG_KEY_CTRL_0_CLEAR_MASK (32'h4) +`define KV_REG_KEY_CTRL_0_RSVD0_LOW (3) +`define KV_REG_KEY_CTRL_0_RSVD0_MASK (32'h8) +`define KV_REG_KEY_CTRL_0_RSVD1_LOW (4) +`define KV_REG_KEY_CTRL_0_RSVD1_MASK (32'h1f0) +`define KV_REG_KEY_CTRL_0_DEST_VALID_LOW (9) +`define KV_REG_KEY_CTRL_0_DEST_VALID_MASK (32'h3fe00) +`define KV_REG_KEY_CTRL_0_LAST_DWORD_LOW (18) +`define KV_REG_KEY_CTRL_0_LAST_DWORD_MASK (32'h3c0000) +`endif +`ifndef KV_REG_KEY_CTRL_1 +`define KV_REG_KEY_CTRL_1 (32'h4) +`define KV_REG_KEY_CTRL_1_LOCK_WR_LOW (0) +`define KV_REG_KEY_CTRL_1_LOCK_WR_MASK (32'h1) +`define KV_REG_KEY_CTRL_1_LOCK_USE_LOW (1) +`define KV_REG_KEY_CTRL_1_LOCK_USE_MASK (32'h2) +`define KV_REG_KEY_CTRL_1_CLEAR_LOW (2) +`define KV_REG_KEY_CTRL_1_CLEAR_MASK (32'h4) +`define KV_REG_KEY_CTRL_1_RSVD0_LOW (3) +`define KV_REG_KEY_CTRL_1_RSVD0_MASK (32'h8) +`define KV_REG_KEY_CTRL_1_RSVD1_LOW (4) +`define KV_REG_KEY_CTRL_1_RSVD1_MASK (32'h1f0) +`define KV_REG_KEY_CTRL_1_DEST_VALID_LOW (9) +`define KV_REG_KEY_CTRL_1_DEST_VALID_MASK (32'h3fe00) +`define KV_REG_KEY_CTRL_1_LAST_DWORD_LOW (18) +`define KV_REG_KEY_CTRL_1_LAST_DWORD_MASK (32'h3c0000) +`endif +`ifndef KV_REG_KEY_CTRL_2 +`define KV_REG_KEY_CTRL_2 (32'h8) +`define KV_REG_KEY_CTRL_2_LOCK_WR_LOW (0) +`define KV_REG_KEY_CTRL_2_LOCK_WR_MASK (32'h1) +`define KV_REG_KEY_CTRL_2_LOCK_USE_LOW (1) +`define KV_REG_KEY_CTRL_2_LOCK_USE_MASK (32'h2) +`define KV_REG_KEY_CTRL_2_CLEAR_LOW (2) +`define KV_REG_KEY_CTRL_2_CLEAR_MASK (32'h4) +`define KV_REG_KEY_CTRL_2_RSVD0_LOW (3) +`define KV_REG_KEY_CTRL_2_RSVD0_MASK (32'h8) +`define KV_REG_KEY_CTRL_2_RSVD1_LOW (4) +`define KV_REG_KEY_CTRL_2_RSVD1_MASK (32'h1f0) +`define KV_REG_KEY_CTRL_2_DEST_VALID_LOW (9) +`define KV_REG_KEY_CTRL_2_DEST_VALID_MASK (32'h3fe00) +`define KV_REG_KEY_CTRL_2_LAST_DWORD_LOW (18) +`define KV_REG_KEY_CTRL_2_LAST_DWORD_MASK (32'h3c0000) +`endif +`ifndef KV_REG_KEY_CTRL_3 +`define KV_REG_KEY_CTRL_3 (32'hc) +`define KV_REG_KEY_CTRL_3_LOCK_WR_LOW (0) +`define KV_REG_KEY_CTRL_3_LOCK_WR_MASK (32'h1) +`define KV_REG_KEY_CTRL_3_LOCK_USE_LOW (1) +`define KV_REG_KEY_CTRL_3_LOCK_USE_MASK (32'h2) +`define KV_REG_KEY_CTRL_3_CLEAR_LOW (2) +`define KV_REG_KEY_CTRL_3_CLEAR_MASK (32'h4) +`define KV_REG_KEY_CTRL_3_RSVD0_LOW (3) +`define KV_REG_KEY_CTRL_3_RSVD0_MASK (32'h8) +`define KV_REG_KEY_CTRL_3_RSVD1_LOW (4) +`define KV_REG_KEY_CTRL_3_RSVD1_MASK (32'h1f0) +`define KV_REG_KEY_CTRL_3_DEST_VALID_LOW (9) +`define KV_REG_KEY_CTRL_3_DEST_VALID_MASK (32'h3fe00) +`define KV_REG_KEY_CTRL_3_LAST_DWORD_LOW (18) +`define KV_REG_KEY_CTRL_3_LAST_DWORD_MASK (32'h3c0000) +`endif +`ifndef KV_REG_KEY_CTRL_4 +`define KV_REG_KEY_CTRL_4 (32'h10) +`define KV_REG_KEY_CTRL_4_LOCK_WR_LOW (0) +`define KV_REG_KEY_CTRL_4_LOCK_WR_MASK (32'h1) +`define KV_REG_KEY_CTRL_4_LOCK_USE_LOW (1) +`define KV_REG_KEY_CTRL_4_LOCK_USE_MASK (32'h2) +`define KV_REG_KEY_CTRL_4_CLEAR_LOW (2) +`define KV_REG_KEY_CTRL_4_CLEAR_MASK (32'h4) +`define KV_REG_KEY_CTRL_4_RSVD0_LOW (3) +`define KV_REG_KEY_CTRL_4_RSVD0_MASK (32'h8) +`define KV_REG_KEY_CTRL_4_RSVD1_LOW (4) +`define KV_REG_KEY_CTRL_4_RSVD1_MASK (32'h1f0) +`define KV_REG_KEY_CTRL_4_DEST_VALID_LOW (9) +`define KV_REG_KEY_CTRL_4_DEST_VALID_MASK (32'h3fe00) +`define KV_REG_KEY_CTRL_4_LAST_DWORD_LOW (18) +`define KV_REG_KEY_CTRL_4_LAST_DWORD_MASK (32'h3c0000) +`endif +`ifndef KV_REG_KEY_CTRL_5 +`define KV_REG_KEY_CTRL_5 (32'h14) +`define KV_REG_KEY_CTRL_5_LOCK_WR_LOW (0) +`define KV_REG_KEY_CTRL_5_LOCK_WR_MASK (32'h1) +`define KV_REG_KEY_CTRL_5_LOCK_USE_LOW (1) +`define KV_REG_KEY_CTRL_5_LOCK_USE_MASK (32'h2) +`define KV_REG_KEY_CTRL_5_CLEAR_LOW (2) +`define KV_REG_KEY_CTRL_5_CLEAR_MASK (32'h4) +`define KV_REG_KEY_CTRL_5_RSVD0_LOW (3) +`define KV_REG_KEY_CTRL_5_RSVD0_MASK (32'h8) +`define KV_REG_KEY_CTRL_5_RSVD1_LOW (4) +`define KV_REG_KEY_CTRL_5_RSVD1_MASK (32'h1f0) +`define KV_REG_KEY_CTRL_5_DEST_VALID_LOW (9) +`define KV_REG_KEY_CTRL_5_DEST_VALID_MASK (32'h3fe00) +`define KV_REG_KEY_CTRL_5_LAST_DWORD_LOW (18) +`define KV_REG_KEY_CTRL_5_LAST_DWORD_MASK (32'h3c0000) +`endif +`ifndef KV_REG_KEY_CTRL_6 +`define KV_REG_KEY_CTRL_6 (32'h18) +`define KV_REG_KEY_CTRL_6_LOCK_WR_LOW (0) +`define KV_REG_KEY_CTRL_6_LOCK_WR_MASK (32'h1) +`define KV_REG_KEY_CTRL_6_LOCK_USE_LOW (1) +`define KV_REG_KEY_CTRL_6_LOCK_USE_MASK (32'h2) +`define KV_REG_KEY_CTRL_6_CLEAR_LOW (2) +`define KV_REG_KEY_CTRL_6_CLEAR_MASK (32'h4) +`define KV_REG_KEY_CTRL_6_RSVD0_LOW (3) +`define KV_REG_KEY_CTRL_6_RSVD0_MASK (32'h8) +`define KV_REG_KEY_CTRL_6_RSVD1_LOW (4) +`define KV_REG_KEY_CTRL_6_RSVD1_MASK (32'h1f0) +`define KV_REG_KEY_CTRL_6_DEST_VALID_LOW (9) +`define KV_REG_KEY_CTRL_6_DEST_VALID_MASK (32'h3fe00) +`define KV_REG_KEY_CTRL_6_LAST_DWORD_LOW (18) +`define KV_REG_KEY_CTRL_6_LAST_DWORD_MASK (32'h3c0000) +`endif +`ifndef KV_REG_KEY_CTRL_7 +`define KV_REG_KEY_CTRL_7 (32'h1c) +`define KV_REG_KEY_CTRL_7_LOCK_WR_LOW (0) +`define KV_REG_KEY_CTRL_7_LOCK_WR_MASK (32'h1) +`define KV_REG_KEY_CTRL_7_LOCK_USE_LOW (1) +`define KV_REG_KEY_CTRL_7_LOCK_USE_MASK (32'h2) +`define KV_REG_KEY_CTRL_7_CLEAR_LOW (2) +`define KV_REG_KEY_CTRL_7_CLEAR_MASK (32'h4) +`define KV_REG_KEY_CTRL_7_RSVD0_LOW (3) +`define KV_REG_KEY_CTRL_7_RSVD0_MASK (32'h8) +`define KV_REG_KEY_CTRL_7_RSVD1_LOW (4) +`define KV_REG_KEY_CTRL_7_RSVD1_MASK (32'h1f0) +`define KV_REG_KEY_CTRL_7_DEST_VALID_LOW (9) +`define KV_REG_KEY_CTRL_7_DEST_VALID_MASK (32'h3fe00) +`define KV_REG_KEY_CTRL_7_LAST_DWORD_LOW (18) +`define KV_REG_KEY_CTRL_7_LAST_DWORD_MASK (32'h3c0000) +`endif +`ifndef KV_REG_KEY_CTRL_8 +`define KV_REG_KEY_CTRL_8 (32'h20) +`define KV_REG_KEY_CTRL_8_LOCK_WR_LOW (0) +`define KV_REG_KEY_CTRL_8_LOCK_WR_MASK (32'h1) +`define KV_REG_KEY_CTRL_8_LOCK_USE_LOW (1) +`define KV_REG_KEY_CTRL_8_LOCK_USE_MASK (32'h2) +`define KV_REG_KEY_CTRL_8_CLEAR_LOW (2) +`define KV_REG_KEY_CTRL_8_CLEAR_MASK (32'h4) +`define KV_REG_KEY_CTRL_8_RSVD0_LOW (3) +`define KV_REG_KEY_CTRL_8_RSVD0_MASK (32'h8) +`define KV_REG_KEY_CTRL_8_RSVD1_LOW (4) +`define KV_REG_KEY_CTRL_8_RSVD1_MASK (32'h1f0) +`define KV_REG_KEY_CTRL_8_DEST_VALID_LOW (9) +`define KV_REG_KEY_CTRL_8_DEST_VALID_MASK (32'h3fe00) +`define KV_REG_KEY_CTRL_8_LAST_DWORD_LOW (18) +`define KV_REG_KEY_CTRL_8_LAST_DWORD_MASK (32'h3c0000) +`endif +`ifndef KV_REG_KEY_CTRL_9 +`define KV_REG_KEY_CTRL_9 (32'h24) +`define KV_REG_KEY_CTRL_9_LOCK_WR_LOW (0) +`define KV_REG_KEY_CTRL_9_LOCK_WR_MASK (32'h1) +`define KV_REG_KEY_CTRL_9_LOCK_USE_LOW (1) +`define KV_REG_KEY_CTRL_9_LOCK_USE_MASK (32'h2) +`define KV_REG_KEY_CTRL_9_CLEAR_LOW (2) +`define KV_REG_KEY_CTRL_9_CLEAR_MASK (32'h4) +`define KV_REG_KEY_CTRL_9_RSVD0_LOW (3) +`define KV_REG_KEY_CTRL_9_RSVD0_MASK (32'h8) +`define KV_REG_KEY_CTRL_9_RSVD1_LOW (4) +`define KV_REG_KEY_CTRL_9_RSVD1_MASK (32'h1f0) +`define KV_REG_KEY_CTRL_9_DEST_VALID_LOW (9) +`define KV_REG_KEY_CTRL_9_DEST_VALID_MASK (32'h3fe00) +`define KV_REG_KEY_CTRL_9_LAST_DWORD_LOW (18) +`define KV_REG_KEY_CTRL_9_LAST_DWORD_MASK (32'h3c0000) +`endif +`ifndef KV_REG_KEY_CTRL_10 +`define KV_REG_KEY_CTRL_10 (32'h28) +`define KV_REG_KEY_CTRL_10_LOCK_WR_LOW (0) +`define KV_REG_KEY_CTRL_10_LOCK_WR_MASK (32'h1) +`define KV_REG_KEY_CTRL_10_LOCK_USE_LOW (1) +`define KV_REG_KEY_CTRL_10_LOCK_USE_MASK (32'h2) +`define KV_REG_KEY_CTRL_10_CLEAR_LOW (2) +`define KV_REG_KEY_CTRL_10_CLEAR_MASK (32'h4) +`define KV_REG_KEY_CTRL_10_RSVD0_LOW (3) +`define KV_REG_KEY_CTRL_10_RSVD0_MASK (32'h8) +`define KV_REG_KEY_CTRL_10_RSVD1_LOW (4) +`define KV_REG_KEY_CTRL_10_RSVD1_MASK (32'h1f0) +`define KV_REG_KEY_CTRL_10_DEST_VALID_LOW (9) +`define KV_REG_KEY_CTRL_10_DEST_VALID_MASK (32'h3fe00) +`define KV_REG_KEY_CTRL_10_LAST_DWORD_LOW (18) +`define KV_REG_KEY_CTRL_10_LAST_DWORD_MASK (32'h3c0000) +`endif +`ifndef KV_REG_KEY_CTRL_11 +`define KV_REG_KEY_CTRL_11 (32'h2c) +`define KV_REG_KEY_CTRL_11_LOCK_WR_LOW (0) +`define KV_REG_KEY_CTRL_11_LOCK_WR_MASK (32'h1) +`define KV_REG_KEY_CTRL_11_LOCK_USE_LOW (1) +`define KV_REG_KEY_CTRL_11_LOCK_USE_MASK (32'h2) +`define KV_REG_KEY_CTRL_11_CLEAR_LOW (2) +`define KV_REG_KEY_CTRL_11_CLEAR_MASK (32'h4) +`define KV_REG_KEY_CTRL_11_RSVD0_LOW (3) +`define KV_REG_KEY_CTRL_11_RSVD0_MASK (32'h8) +`define KV_REG_KEY_CTRL_11_RSVD1_LOW (4) +`define KV_REG_KEY_CTRL_11_RSVD1_MASK (32'h1f0) +`define KV_REG_KEY_CTRL_11_DEST_VALID_LOW (9) +`define KV_REG_KEY_CTRL_11_DEST_VALID_MASK (32'h3fe00) +`define KV_REG_KEY_CTRL_11_LAST_DWORD_LOW (18) +`define KV_REG_KEY_CTRL_11_LAST_DWORD_MASK (32'h3c0000) +`endif +`ifndef KV_REG_KEY_CTRL_12 +`define KV_REG_KEY_CTRL_12 (32'h30) +`define KV_REG_KEY_CTRL_12_LOCK_WR_LOW (0) +`define KV_REG_KEY_CTRL_12_LOCK_WR_MASK (32'h1) +`define KV_REG_KEY_CTRL_12_LOCK_USE_LOW (1) +`define KV_REG_KEY_CTRL_12_LOCK_USE_MASK (32'h2) +`define KV_REG_KEY_CTRL_12_CLEAR_LOW (2) +`define KV_REG_KEY_CTRL_12_CLEAR_MASK (32'h4) +`define KV_REG_KEY_CTRL_12_RSVD0_LOW (3) +`define KV_REG_KEY_CTRL_12_RSVD0_MASK (32'h8) +`define KV_REG_KEY_CTRL_12_RSVD1_LOW (4) +`define KV_REG_KEY_CTRL_12_RSVD1_MASK (32'h1f0) +`define KV_REG_KEY_CTRL_12_DEST_VALID_LOW (9) +`define KV_REG_KEY_CTRL_12_DEST_VALID_MASK (32'h3fe00) +`define KV_REG_KEY_CTRL_12_LAST_DWORD_LOW (18) +`define KV_REG_KEY_CTRL_12_LAST_DWORD_MASK (32'h3c0000) +`endif +`ifndef KV_REG_KEY_CTRL_13 +`define KV_REG_KEY_CTRL_13 (32'h34) +`define KV_REG_KEY_CTRL_13_LOCK_WR_LOW (0) +`define KV_REG_KEY_CTRL_13_LOCK_WR_MASK (32'h1) +`define KV_REG_KEY_CTRL_13_LOCK_USE_LOW (1) +`define KV_REG_KEY_CTRL_13_LOCK_USE_MASK (32'h2) +`define KV_REG_KEY_CTRL_13_CLEAR_LOW (2) +`define KV_REG_KEY_CTRL_13_CLEAR_MASK (32'h4) +`define KV_REG_KEY_CTRL_13_RSVD0_LOW (3) +`define KV_REG_KEY_CTRL_13_RSVD0_MASK (32'h8) +`define KV_REG_KEY_CTRL_13_RSVD1_LOW (4) +`define KV_REG_KEY_CTRL_13_RSVD1_MASK (32'h1f0) +`define KV_REG_KEY_CTRL_13_DEST_VALID_LOW (9) +`define KV_REG_KEY_CTRL_13_DEST_VALID_MASK (32'h3fe00) +`define KV_REG_KEY_CTRL_13_LAST_DWORD_LOW (18) +`define KV_REG_KEY_CTRL_13_LAST_DWORD_MASK (32'h3c0000) +`endif +`ifndef KV_REG_KEY_CTRL_14 +`define KV_REG_KEY_CTRL_14 (32'h38) +`define KV_REG_KEY_CTRL_14_LOCK_WR_LOW (0) +`define KV_REG_KEY_CTRL_14_LOCK_WR_MASK (32'h1) +`define KV_REG_KEY_CTRL_14_LOCK_USE_LOW (1) +`define KV_REG_KEY_CTRL_14_LOCK_USE_MASK (32'h2) +`define KV_REG_KEY_CTRL_14_CLEAR_LOW (2) +`define KV_REG_KEY_CTRL_14_CLEAR_MASK (32'h4) +`define KV_REG_KEY_CTRL_14_RSVD0_LOW (3) +`define KV_REG_KEY_CTRL_14_RSVD0_MASK (32'h8) +`define KV_REG_KEY_CTRL_14_RSVD1_LOW (4) +`define KV_REG_KEY_CTRL_14_RSVD1_MASK (32'h1f0) +`define KV_REG_KEY_CTRL_14_DEST_VALID_LOW (9) +`define KV_REG_KEY_CTRL_14_DEST_VALID_MASK (32'h3fe00) +`define KV_REG_KEY_CTRL_14_LAST_DWORD_LOW (18) +`define KV_REG_KEY_CTRL_14_LAST_DWORD_MASK (32'h3c0000) +`endif +`ifndef KV_REG_KEY_CTRL_15 +`define KV_REG_KEY_CTRL_15 (32'h3c) +`define KV_REG_KEY_CTRL_15_LOCK_WR_LOW (0) +`define KV_REG_KEY_CTRL_15_LOCK_WR_MASK (32'h1) +`define KV_REG_KEY_CTRL_15_LOCK_USE_LOW (1) +`define KV_REG_KEY_CTRL_15_LOCK_USE_MASK (32'h2) +`define KV_REG_KEY_CTRL_15_CLEAR_LOW (2) +`define KV_REG_KEY_CTRL_15_CLEAR_MASK (32'h4) +`define KV_REG_KEY_CTRL_15_RSVD0_LOW (3) +`define KV_REG_KEY_CTRL_15_RSVD0_MASK (32'h8) +`define KV_REG_KEY_CTRL_15_RSVD1_LOW (4) +`define KV_REG_KEY_CTRL_15_RSVD1_MASK (32'h1f0) +`define KV_REG_KEY_CTRL_15_DEST_VALID_LOW (9) +`define KV_REG_KEY_CTRL_15_DEST_VALID_MASK (32'h3fe00) +`define KV_REG_KEY_CTRL_15_LAST_DWORD_LOW (18) +`define KV_REG_KEY_CTRL_15_LAST_DWORD_MASK (32'h3c0000) +`endif +`ifndef KV_REG_KEY_CTRL_16 +`define KV_REG_KEY_CTRL_16 (32'h40) +`define KV_REG_KEY_CTRL_16_LOCK_WR_LOW (0) +`define KV_REG_KEY_CTRL_16_LOCK_WR_MASK (32'h1) +`define KV_REG_KEY_CTRL_16_LOCK_USE_LOW (1) +`define KV_REG_KEY_CTRL_16_LOCK_USE_MASK (32'h2) +`define KV_REG_KEY_CTRL_16_CLEAR_LOW (2) +`define KV_REG_KEY_CTRL_16_CLEAR_MASK (32'h4) +`define KV_REG_KEY_CTRL_16_RSVD0_LOW (3) +`define KV_REG_KEY_CTRL_16_RSVD0_MASK (32'h8) +`define KV_REG_KEY_CTRL_16_RSVD1_LOW (4) +`define KV_REG_KEY_CTRL_16_RSVD1_MASK (32'h1f0) +`define KV_REG_KEY_CTRL_16_DEST_VALID_LOW (9) +`define KV_REG_KEY_CTRL_16_DEST_VALID_MASK (32'h3fe00) +`define KV_REG_KEY_CTRL_16_LAST_DWORD_LOW (18) +`define KV_REG_KEY_CTRL_16_LAST_DWORD_MASK (32'h3c0000) +`endif +`ifndef KV_REG_KEY_CTRL_17 +`define KV_REG_KEY_CTRL_17 (32'h44) +`define KV_REG_KEY_CTRL_17_LOCK_WR_LOW (0) +`define KV_REG_KEY_CTRL_17_LOCK_WR_MASK (32'h1) +`define KV_REG_KEY_CTRL_17_LOCK_USE_LOW (1) +`define KV_REG_KEY_CTRL_17_LOCK_USE_MASK (32'h2) +`define KV_REG_KEY_CTRL_17_CLEAR_LOW (2) +`define KV_REG_KEY_CTRL_17_CLEAR_MASK (32'h4) +`define KV_REG_KEY_CTRL_17_RSVD0_LOW (3) +`define KV_REG_KEY_CTRL_17_RSVD0_MASK (32'h8) +`define KV_REG_KEY_CTRL_17_RSVD1_LOW (4) +`define KV_REG_KEY_CTRL_17_RSVD1_MASK (32'h1f0) +`define KV_REG_KEY_CTRL_17_DEST_VALID_LOW (9) +`define KV_REG_KEY_CTRL_17_DEST_VALID_MASK (32'h3fe00) +`define KV_REG_KEY_CTRL_17_LAST_DWORD_LOW (18) +`define KV_REG_KEY_CTRL_17_LAST_DWORD_MASK (32'h3c0000) +`endif +`ifndef KV_REG_KEY_CTRL_18 +`define KV_REG_KEY_CTRL_18 (32'h48) +`define KV_REG_KEY_CTRL_18_LOCK_WR_LOW (0) +`define KV_REG_KEY_CTRL_18_LOCK_WR_MASK (32'h1) +`define KV_REG_KEY_CTRL_18_LOCK_USE_LOW (1) +`define KV_REG_KEY_CTRL_18_LOCK_USE_MASK (32'h2) +`define KV_REG_KEY_CTRL_18_CLEAR_LOW (2) +`define KV_REG_KEY_CTRL_18_CLEAR_MASK (32'h4) +`define KV_REG_KEY_CTRL_18_RSVD0_LOW (3) +`define KV_REG_KEY_CTRL_18_RSVD0_MASK (32'h8) +`define KV_REG_KEY_CTRL_18_RSVD1_LOW (4) +`define KV_REG_KEY_CTRL_18_RSVD1_MASK (32'h1f0) +`define KV_REG_KEY_CTRL_18_DEST_VALID_LOW (9) +`define KV_REG_KEY_CTRL_18_DEST_VALID_MASK (32'h3fe00) +`define KV_REG_KEY_CTRL_18_LAST_DWORD_LOW (18) +`define KV_REG_KEY_CTRL_18_LAST_DWORD_MASK (32'h3c0000) +`endif +`ifndef KV_REG_KEY_CTRL_19 +`define KV_REG_KEY_CTRL_19 (32'h4c) +`define KV_REG_KEY_CTRL_19_LOCK_WR_LOW (0) +`define KV_REG_KEY_CTRL_19_LOCK_WR_MASK (32'h1) +`define KV_REG_KEY_CTRL_19_LOCK_USE_LOW (1) +`define KV_REG_KEY_CTRL_19_LOCK_USE_MASK (32'h2) +`define KV_REG_KEY_CTRL_19_CLEAR_LOW (2) +`define KV_REG_KEY_CTRL_19_CLEAR_MASK (32'h4) +`define KV_REG_KEY_CTRL_19_RSVD0_LOW (3) +`define KV_REG_KEY_CTRL_19_RSVD0_MASK (32'h8) +`define KV_REG_KEY_CTRL_19_RSVD1_LOW (4) +`define KV_REG_KEY_CTRL_19_RSVD1_MASK (32'h1f0) +`define KV_REG_KEY_CTRL_19_DEST_VALID_LOW (9) +`define KV_REG_KEY_CTRL_19_DEST_VALID_MASK (32'h3fe00) +`define KV_REG_KEY_CTRL_19_LAST_DWORD_LOW (18) +`define KV_REG_KEY_CTRL_19_LAST_DWORD_MASK (32'h3c0000) +`endif +`ifndef KV_REG_KEY_CTRL_20 +`define KV_REG_KEY_CTRL_20 (32'h50) +`define KV_REG_KEY_CTRL_20_LOCK_WR_LOW (0) +`define KV_REG_KEY_CTRL_20_LOCK_WR_MASK (32'h1) +`define KV_REG_KEY_CTRL_20_LOCK_USE_LOW (1) +`define KV_REG_KEY_CTRL_20_LOCK_USE_MASK (32'h2) +`define KV_REG_KEY_CTRL_20_CLEAR_LOW (2) +`define KV_REG_KEY_CTRL_20_CLEAR_MASK (32'h4) +`define KV_REG_KEY_CTRL_20_RSVD0_LOW (3) +`define KV_REG_KEY_CTRL_20_RSVD0_MASK (32'h8) +`define KV_REG_KEY_CTRL_20_RSVD1_LOW (4) +`define KV_REG_KEY_CTRL_20_RSVD1_MASK (32'h1f0) +`define KV_REG_KEY_CTRL_20_DEST_VALID_LOW (9) +`define KV_REG_KEY_CTRL_20_DEST_VALID_MASK (32'h3fe00) +`define KV_REG_KEY_CTRL_20_LAST_DWORD_LOW (18) +`define KV_REG_KEY_CTRL_20_LAST_DWORD_MASK (32'h3c0000) +`endif +`ifndef KV_REG_KEY_CTRL_21 +`define KV_REG_KEY_CTRL_21 (32'h54) +`define KV_REG_KEY_CTRL_21_LOCK_WR_LOW (0) +`define KV_REG_KEY_CTRL_21_LOCK_WR_MASK (32'h1) +`define KV_REG_KEY_CTRL_21_LOCK_USE_LOW (1) +`define KV_REG_KEY_CTRL_21_LOCK_USE_MASK (32'h2) +`define KV_REG_KEY_CTRL_21_CLEAR_LOW (2) +`define KV_REG_KEY_CTRL_21_CLEAR_MASK (32'h4) +`define KV_REG_KEY_CTRL_21_RSVD0_LOW (3) +`define KV_REG_KEY_CTRL_21_RSVD0_MASK (32'h8) +`define KV_REG_KEY_CTRL_21_RSVD1_LOW (4) +`define KV_REG_KEY_CTRL_21_RSVD1_MASK (32'h1f0) +`define KV_REG_KEY_CTRL_21_DEST_VALID_LOW (9) +`define KV_REG_KEY_CTRL_21_DEST_VALID_MASK (32'h3fe00) +`define KV_REG_KEY_CTRL_21_LAST_DWORD_LOW (18) +`define KV_REG_KEY_CTRL_21_LAST_DWORD_MASK (32'h3c0000) +`endif +`ifndef KV_REG_KEY_CTRL_22 +`define KV_REG_KEY_CTRL_22 (32'h58) +`define KV_REG_KEY_CTRL_22_LOCK_WR_LOW (0) +`define KV_REG_KEY_CTRL_22_LOCK_WR_MASK (32'h1) +`define KV_REG_KEY_CTRL_22_LOCK_USE_LOW (1) +`define KV_REG_KEY_CTRL_22_LOCK_USE_MASK (32'h2) +`define KV_REG_KEY_CTRL_22_CLEAR_LOW (2) +`define KV_REG_KEY_CTRL_22_CLEAR_MASK (32'h4) +`define KV_REG_KEY_CTRL_22_RSVD0_LOW (3) +`define KV_REG_KEY_CTRL_22_RSVD0_MASK (32'h8) +`define KV_REG_KEY_CTRL_22_RSVD1_LOW (4) +`define KV_REG_KEY_CTRL_22_RSVD1_MASK (32'h1f0) +`define KV_REG_KEY_CTRL_22_DEST_VALID_LOW (9) +`define KV_REG_KEY_CTRL_22_DEST_VALID_MASK (32'h3fe00) +`define KV_REG_KEY_CTRL_22_LAST_DWORD_LOW (18) +`define KV_REG_KEY_CTRL_22_LAST_DWORD_MASK (32'h3c0000) +`endif +`ifndef KV_REG_KEY_CTRL_23 +`define KV_REG_KEY_CTRL_23 (32'h5c) +`define KV_REG_KEY_CTRL_23_LOCK_WR_LOW (0) +`define KV_REG_KEY_CTRL_23_LOCK_WR_MASK (32'h1) +`define KV_REG_KEY_CTRL_23_LOCK_USE_LOW (1) +`define KV_REG_KEY_CTRL_23_LOCK_USE_MASK (32'h2) +`define KV_REG_KEY_CTRL_23_CLEAR_LOW (2) +`define KV_REG_KEY_CTRL_23_CLEAR_MASK (32'h4) +`define KV_REG_KEY_CTRL_23_RSVD0_LOW (3) +`define KV_REG_KEY_CTRL_23_RSVD0_MASK (32'h8) +`define KV_REG_KEY_CTRL_23_RSVD1_LOW (4) +`define KV_REG_KEY_CTRL_23_RSVD1_MASK (32'h1f0) +`define KV_REG_KEY_CTRL_23_DEST_VALID_LOW (9) +`define KV_REG_KEY_CTRL_23_DEST_VALID_MASK (32'h3fe00) +`define KV_REG_KEY_CTRL_23_LAST_DWORD_LOW (18) +`define KV_REG_KEY_CTRL_23_LAST_DWORD_MASK (32'h3c0000) +`endif +`ifndef KV_REG_KEY_ENTRY_0_0 +`define KV_REG_KEY_ENTRY_0_0 (32'h600) +`endif +`ifndef KV_REG_KEY_ENTRY_0_1 +`define KV_REG_KEY_ENTRY_0_1 (32'h604) +`endif +`ifndef KV_REG_KEY_ENTRY_0_2 +`define KV_REG_KEY_ENTRY_0_2 (32'h608) +`endif +`ifndef KV_REG_KEY_ENTRY_0_3 +`define KV_REG_KEY_ENTRY_0_3 (32'h60c) +`endif +`ifndef KV_REG_KEY_ENTRY_0_4 +`define KV_REG_KEY_ENTRY_0_4 (32'h610) +`endif +`ifndef KV_REG_KEY_ENTRY_0_5 +`define KV_REG_KEY_ENTRY_0_5 (32'h614) +`endif +`ifndef KV_REG_KEY_ENTRY_0_6 +`define KV_REG_KEY_ENTRY_0_6 (32'h618) +`endif +`ifndef KV_REG_KEY_ENTRY_0_7 +`define KV_REG_KEY_ENTRY_0_7 (32'h61c) +`endif +`ifndef KV_REG_KEY_ENTRY_0_8 +`define KV_REG_KEY_ENTRY_0_8 (32'h620) +`endif +`ifndef KV_REG_KEY_ENTRY_0_9 +`define KV_REG_KEY_ENTRY_0_9 (32'h624) +`endif +`ifndef KV_REG_KEY_ENTRY_0_10 +`define KV_REG_KEY_ENTRY_0_10 (32'h628) +`endif +`ifndef KV_REG_KEY_ENTRY_0_11 +`define KV_REG_KEY_ENTRY_0_11 (32'h62c) +`endif +`ifndef KV_REG_KEY_ENTRY_0_12 +`define KV_REG_KEY_ENTRY_0_12 (32'h630) +`endif +`ifndef KV_REG_KEY_ENTRY_0_13 +`define KV_REG_KEY_ENTRY_0_13 (32'h634) +`endif +`ifndef KV_REG_KEY_ENTRY_0_14 +`define KV_REG_KEY_ENTRY_0_14 (32'h638) +`endif +`ifndef KV_REG_KEY_ENTRY_0_15 +`define KV_REG_KEY_ENTRY_0_15 (32'h63c) +`endif +`ifndef KV_REG_KEY_ENTRY_1_0 +`define KV_REG_KEY_ENTRY_1_0 (32'h640) +`endif +`ifndef KV_REG_KEY_ENTRY_1_1 +`define KV_REG_KEY_ENTRY_1_1 (32'h644) +`endif +`ifndef KV_REG_KEY_ENTRY_1_2 +`define KV_REG_KEY_ENTRY_1_2 (32'h648) +`endif +`ifndef KV_REG_KEY_ENTRY_1_3 +`define KV_REG_KEY_ENTRY_1_3 (32'h64c) +`endif +`ifndef KV_REG_KEY_ENTRY_1_4 +`define KV_REG_KEY_ENTRY_1_4 (32'h650) +`endif +`ifndef KV_REG_KEY_ENTRY_1_5 +`define KV_REG_KEY_ENTRY_1_5 (32'h654) +`endif +`ifndef KV_REG_KEY_ENTRY_1_6 +`define KV_REG_KEY_ENTRY_1_6 (32'h658) +`endif +`ifndef KV_REG_KEY_ENTRY_1_7 +`define KV_REG_KEY_ENTRY_1_7 (32'h65c) +`endif +`ifndef KV_REG_KEY_ENTRY_1_8 +`define KV_REG_KEY_ENTRY_1_8 (32'h660) +`endif +`ifndef KV_REG_KEY_ENTRY_1_9 +`define KV_REG_KEY_ENTRY_1_9 (32'h664) +`endif +`ifndef KV_REG_KEY_ENTRY_1_10 +`define KV_REG_KEY_ENTRY_1_10 (32'h668) +`endif +`ifndef KV_REG_KEY_ENTRY_1_11 +`define KV_REG_KEY_ENTRY_1_11 (32'h66c) +`endif +`ifndef KV_REG_KEY_ENTRY_1_12 +`define KV_REG_KEY_ENTRY_1_12 (32'h670) +`endif +`ifndef KV_REG_KEY_ENTRY_1_13 +`define KV_REG_KEY_ENTRY_1_13 (32'h674) +`endif +`ifndef KV_REG_KEY_ENTRY_1_14 +`define KV_REG_KEY_ENTRY_1_14 (32'h678) +`endif +`ifndef KV_REG_KEY_ENTRY_1_15 +`define KV_REG_KEY_ENTRY_1_15 (32'h67c) +`endif +`ifndef KV_REG_KEY_ENTRY_2_0 +`define KV_REG_KEY_ENTRY_2_0 (32'h680) +`endif +`ifndef KV_REG_KEY_ENTRY_2_1 +`define KV_REG_KEY_ENTRY_2_1 (32'h684) +`endif +`ifndef KV_REG_KEY_ENTRY_2_2 +`define KV_REG_KEY_ENTRY_2_2 (32'h688) +`endif +`ifndef KV_REG_KEY_ENTRY_2_3 +`define KV_REG_KEY_ENTRY_2_3 (32'h68c) +`endif +`ifndef KV_REG_KEY_ENTRY_2_4 +`define KV_REG_KEY_ENTRY_2_4 (32'h690) +`endif +`ifndef KV_REG_KEY_ENTRY_2_5 +`define KV_REG_KEY_ENTRY_2_5 (32'h694) +`endif +`ifndef KV_REG_KEY_ENTRY_2_6 +`define KV_REG_KEY_ENTRY_2_6 (32'h698) +`endif +`ifndef KV_REG_KEY_ENTRY_2_7 +`define KV_REG_KEY_ENTRY_2_7 (32'h69c) +`endif +`ifndef KV_REG_KEY_ENTRY_2_8 +`define KV_REG_KEY_ENTRY_2_8 (32'h6a0) +`endif +`ifndef KV_REG_KEY_ENTRY_2_9 +`define KV_REG_KEY_ENTRY_2_9 (32'h6a4) +`endif +`ifndef KV_REG_KEY_ENTRY_2_10 +`define KV_REG_KEY_ENTRY_2_10 (32'h6a8) +`endif +`ifndef KV_REG_KEY_ENTRY_2_11 +`define KV_REG_KEY_ENTRY_2_11 (32'h6ac) +`endif +`ifndef KV_REG_KEY_ENTRY_2_12 +`define KV_REG_KEY_ENTRY_2_12 (32'h6b0) +`endif +`ifndef KV_REG_KEY_ENTRY_2_13 +`define KV_REG_KEY_ENTRY_2_13 (32'h6b4) +`endif +`ifndef KV_REG_KEY_ENTRY_2_14 +`define KV_REG_KEY_ENTRY_2_14 (32'h6b8) +`endif +`ifndef KV_REG_KEY_ENTRY_2_15 +`define KV_REG_KEY_ENTRY_2_15 (32'h6bc) +`endif +`ifndef KV_REG_KEY_ENTRY_3_0 +`define KV_REG_KEY_ENTRY_3_0 (32'h6c0) +`endif +`ifndef KV_REG_KEY_ENTRY_3_1 +`define KV_REG_KEY_ENTRY_3_1 (32'h6c4) +`endif +`ifndef KV_REG_KEY_ENTRY_3_2 +`define KV_REG_KEY_ENTRY_3_2 (32'h6c8) +`endif +`ifndef KV_REG_KEY_ENTRY_3_3 +`define KV_REG_KEY_ENTRY_3_3 (32'h6cc) +`endif +`ifndef KV_REG_KEY_ENTRY_3_4 +`define KV_REG_KEY_ENTRY_3_4 (32'h6d0) +`endif +`ifndef KV_REG_KEY_ENTRY_3_5 +`define KV_REG_KEY_ENTRY_3_5 (32'h6d4) +`endif +`ifndef KV_REG_KEY_ENTRY_3_6 +`define KV_REG_KEY_ENTRY_3_6 (32'h6d8) +`endif +`ifndef KV_REG_KEY_ENTRY_3_7 +`define KV_REG_KEY_ENTRY_3_7 (32'h6dc) +`endif +`ifndef KV_REG_KEY_ENTRY_3_8 +`define KV_REG_KEY_ENTRY_3_8 (32'h6e0) +`endif +`ifndef KV_REG_KEY_ENTRY_3_9 +`define KV_REG_KEY_ENTRY_3_9 (32'h6e4) +`endif +`ifndef KV_REG_KEY_ENTRY_3_10 +`define KV_REG_KEY_ENTRY_3_10 (32'h6e8) +`endif +`ifndef KV_REG_KEY_ENTRY_3_11 +`define KV_REG_KEY_ENTRY_3_11 (32'h6ec) +`endif +`ifndef KV_REG_KEY_ENTRY_3_12 +`define KV_REG_KEY_ENTRY_3_12 (32'h6f0) +`endif +`ifndef KV_REG_KEY_ENTRY_3_13 +`define KV_REG_KEY_ENTRY_3_13 (32'h6f4) +`endif +`ifndef KV_REG_KEY_ENTRY_3_14 +`define KV_REG_KEY_ENTRY_3_14 (32'h6f8) +`endif +`ifndef KV_REG_KEY_ENTRY_3_15 +`define KV_REG_KEY_ENTRY_3_15 (32'h6fc) +`endif +`ifndef KV_REG_KEY_ENTRY_4_0 +`define KV_REG_KEY_ENTRY_4_0 (32'h700) +`endif +`ifndef KV_REG_KEY_ENTRY_4_1 +`define KV_REG_KEY_ENTRY_4_1 (32'h704) +`endif +`ifndef KV_REG_KEY_ENTRY_4_2 +`define KV_REG_KEY_ENTRY_4_2 (32'h708) +`endif +`ifndef KV_REG_KEY_ENTRY_4_3 +`define KV_REG_KEY_ENTRY_4_3 (32'h70c) +`endif +`ifndef KV_REG_KEY_ENTRY_4_4 +`define KV_REG_KEY_ENTRY_4_4 (32'h710) +`endif +`ifndef KV_REG_KEY_ENTRY_4_5 +`define KV_REG_KEY_ENTRY_4_5 (32'h714) +`endif +`ifndef KV_REG_KEY_ENTRY_4_6 +`define KV_REG_KEY_ENTRY_4_6 (32'h718) +`endif +`ifndef KV_REG_KEY_ENTRY_4_7 +`define KV_REG_KEY_ENTRY_4_7 (32'h71c) +`endif +`ifndef KV_REG_KEY_ENTRY_4_8 +`define KV_REG_KEY_ENTRY_4_8 (32'h720) +`endif +`ifndef KV_REG_KEY_ENTRY_4_9 +`define KV_REG_KEY_ENTRY_4_9 (32'h724) +`endif +`ifndef KV_REG_KEY_ENTRY_4_10 +`define KV_REG_KEY_ENTRY_4_10 (32'h728) +`endif +`ifndef KV_REG_KEY_ENTRY_4_11 +`define KV_REG_KEY_ENTRY_4_11 (32'h72c) +`endif +`ifndef KV_REG_KEY_ENTRY_4_12 +`define KV_REG_KEY_ENTRY_4_12 (32'h730) +`endif +`ifndef KV_REG_KEY_ENTRY_4_13 +`define KV_REG_KEY_ENTRY_4_13 (32'h734) +`endif +`ifndef KV_REG_KEY_ENTRY_4_14 +`define KV_REG_KEY_ENTRY_4_14 (32'h738) +`endif +`ifndef KV_REG_KEY_ENTRY_4_15 +`define KV_REG_KEY_ENTRY_4_15 (32'h73c) +`endif +`ifndef KV_REG_KEY_ENTRY_5_0 +`define KV_REG_KEY_ENTRY_5_0 (32'h740) +`endif +`ifndef KV_REG_KEY_ENTRY_5_1 +`define KV_REG_KEY_ENTRY_5_1 (32'h744) +`endif +`ifndef KV_REG_KEY_ENTRY_5_2 +`define KV_REG_KEY_ENTRY_5_2 (32'h748) +`endif +`ifndef KV_REG_KEY_ENTRY_5_3 +`define KV_REG_KEY_ENTRY_5_3 (32'h74c) +`endif +`ifndef KV_REG_KEY_ENTRY_5_4 +`define KV_REG_KEY_ENTRY_5_4 (32'h750) +`endif +`ifndef KV_REG_KEY_ENTRY_5_5 +`define KV_REG_KEY_ENTRY_5_5 (32'h754) +`endif +`ifndef KV_REG_KEY_ENTRY_5_6 +`define KV_REG_KEY_ENTRY_5_6 (32'h758) +`endif +`ifndef KV_REG_KEY_ENTRY_5_7 +`define KV_REG_KEY_ENTRY_5_7 (32'h75c) +`endif +`ifndef KV_REG_KEY_ENTRY_5_8 +`define KV_REG_KEY_ENTRY_5_8 (32'h760) +`endif +`ifndef KV_REG_KEY_ENTRY_5_9 +`define KV_REG_KEY_ENTRY_5_9 (32'h764) +`endif +`ifndef KV_REG_KEY_ENTRY_5_10 +`define KV_REG_KEY_ENTRY_5_10 (32'h768) +`endif +`ifndef KV_REG_KEY_ENTRY_5_11 +`define KV_REG_KEY_ENTRY_5_11 (32'h76c) +`endif +`ifndef KV_REG_KEY_ENTRY_5_12 +`define KV_REG_KEY_ENTRY_5_12 (32'h770) +`endif +`ifndef KV_REG_KEY_ENTRY_5_13 +`define KV_REG_KEY_ENTRY_5_13 (32'h774) +`endif +`ifndef KV_REG_KEY_ENTRY_5_14 +`define KV_REG_KEY_ENTRY_5_14 (32'h778) +`endif +`ifndef KV_REG_KEY_ENTRY_5_15 +`define KV_REG_KEY_ENTRY_5_15 (32'h77c) +`endif +`ifndef KV_REG_KEY_ENTRY_6_0 +`define KV_REG_KEY_ENTRY_6_0 (32'h780) +`endif +`ifndef KV_REG_KEY_ENTRY_6_1 +`define KV_REG_KEY_ENTRY_6_1 (32'h784) +`endif +`ifndef KV_REG_KEY_ENTRY_6_2 +`define KV_REG_KEY_ENTRY_6_2 (32'h788) +`endif +`ifndef KV_REG_KEY_ENTRY_6_3 +`define KV_REG_KEY_ENTRY_6_3 (32'h78c) +`endif +`ifndef KV_REG_KEY_ENTRY_6_4 +`define KV_REG_KEY_ENTRY_6_4 (32'h790) +`endif +`ifndef KV_REG_KEY_ENTRY_6_5 +`define KV_REG_KEY_ENTRY_6_5 (32'h794) +`endif +`ifndef KV_REG_KEY_ENTRY_6_6 +`define KV_REG_KEY_ENTRY_6_6 (32'h798) +`endif +`ifndef KV_REG_KEY_ENTRY_6_7 +`define KV_REG_KEY_ENTRY_6_7 (32'h79c) +`endif +`ifndef KV_REG_KEY_ENTRY_6_8 +`define KV_REG_KEY_ENTRY_6_8 (32'h7a0) +`endif +`ifndef KV_REG_KEY_ENTRY_6_9 +`define KV_REG_KEY_ENTRY_6_9 (32'h7a4) +`endif +`ifndef KV_REG_KEY_ENTRY_6_10 +`define KV_REG_KEY_ENTRY_6_10 (32'h7a8) +`endif +`ifndef KV_REG_KEY_ENTRY_6_11 +`define KV_REG_KEY_ENTRY_6_11 (32'h7ac) +`endif +`ifndef KV_REG_KEY_ENTRY_6_12 +`define KV_REG_KEY_ENTRY_6_12 (32'h7b0) +`endif +`ifndef KV_REG_KEY_ENTRY_6_13 +`define KV_REG_KEY_ENTRY_6_13 (32'h7b4) +`endif +`ifndef KV_REG_KEY_ENTRY_6_14 +`define KV_REG_KEY_ENTRY_6_14 (32'h7b8) +`endif +`ifndef KV_REG_KEY_ENTRY_6_15 +`define KV_REG_KEY_ENTRY_6_15 (32'h7bc) +`endif +`ifndef KV_REG_KEY_ENTRY_7_0 +`define KV_REG_KEY_ENTRY_7_0 (32'h7c0) +`endif +`ifndef KV_REG_KEY_ENTRY_7_1 +`define KV_REG_KEY_ENTRY_7_1 (32'h7c4) +`endif +`ifndef KV_REG_KEY_ENTRY_7_2 +`define KV_REG_KEY_ENTRY_7_2 (32'h7c8) +`endif +`ifndef KV_REG_KEY_ENTRY_7_3 +`define KV_REG_KEY_ENTRY_7_3 (32'h7cc) +`endif +`ifndef KV_REG_KEY_ENTRY_7_4 +`define KV_REG_KEY_ENTRY_7_4 (32'h7d0) +`endif +`ifndef KV_REG_KEY_ENTRY_7_5 +`define KV_REG_KEY_ENTRY_7_5 (32'h7d4) +`endif +`ifndef KV_REG_KEY_ENTRY_7_6 +`define KV_REG_KEY_ENTRY_7_6 (32'h7d8) +`endif +`ifndef KV_REG_KEY_ENTRY_7_7 +`define KV_REG_KEY_ENTRY_7_7 (32'h7dc) +`endif +`ifndef KV_REG_KEY_ENTRY_7_8 +`define KV_REG_KEY_ENTRY_7_8 (32'h7e0) +`endif +`ifndef KV_REG_KEY_ENTRY_7_9 +`define KV_REG_KEY_ENTRY_7_9 (32'h7e4) +`endif +`ifndef KV_REG_KEY_ENTRY_7_10 +`define KV_REG_KEY_ENTRY_7_10 (32'h7e8) +`endif +`ifndef KV_REG_KEY_ENTRY_7_11 +`define KV_REG_KEY_ENTRY_7_11 (32'h7ec) +`endif +`ifndef KV_REG_KEY_ENTRY_7_12 +`define KV_REG_KEY_ENTRY_7_12 (32'h7f0) +`endif +`ifndef KV_REG_KEY_ENTRY_7_13 +`define KV_REG_KEY_ENTRY_7_13 (32'h7f4) +`endif +`ifndef KV_REG_KEY_ENTRY_7_14 +`define KV_REG_KEY_ENTRY_7_14 (32'h7f8) +`endif +`ifndef KV_REG_KEY_ENTRY_7_15 +`define KV_REG_KEY_ENTRY_7_15 (32'h7fc) +`endif +`ifndef KV_REG_KEY_ENTRY_8_0 +`define KV_REG_KEY_ENTRY_8_0 (32'h800) +`endif +`ifndef KV_REG_KEY_ENTRY_8_1 +`define KV_REG_KEY_ENTRY_8_1 (32'h804) +`endif +`ifndef KV_REG_KEY_ENTRY_8_2 +`define KV_REG_KEY_ENTRY_8_2 (32'h808) +`endif +`ifndef KV_REG_KEY_ENTRY_8_3 +`define KV_REG_KEY_ENTRY_8_3 (32'h80c) +`endif +`ifndef KV_REG_KEY_ENTRY_8_4 +`define KV_REG_KEY_ENTRY_8_4 (32'h810) +`endif +`ifndef KV_REG_KEY_ENTRY_8_5 +`define KV_REG_KEY_ENTRY_8_5 (32'h814) +`endif +`ifndef KV_REG_KEY_ENTRY_8_6 +`define KV_REG_KEY_ENTRY_8_6 (32'h818) +`endif +`ifndef KV_REG_KEY_ENTRY_8_7 +`define KV_REG_KEY_ENTRY_8_7 (32'h81c) +`endif +`ifndef KV_REG_KEY_ENTRY_8_8 +`define KV_REG_KEY_ENTRY_8_8 (32'h820) +`endif +`ifndef KV_REG_KEY_ENTRY_8_9 +`define KV_REG_KEY_ENTRY_8_9 (32'h824) +`endif +`ifndef KV_REG_KEY_ENTRY_8_10 +`define KV_REG_KEY_ENTRY_8_10 (32'h828) +`endif +`ifndef KV_REG_KEY_ENTRY_8_11 +`define KV_REG_KEY_ENTRY_8_11 (32'h82c) +`endif +`ifndef KV_REG_KEY_ENTRY_8_12 +`define KV_REG_KEY_ENTRY_8_12 (32'h830) +`endif +`ifndef KV_REG_KEY_ENTRY_8_13 +`define KV_REG_KEY_ENTRY_8_13 (32'h834) +`endif +`ifndef KV_REG_KEY_ENTRY_8_14 +`define KV_REG_KEY_ENTRY_8_14 (32'h838) +`endif +`ifndef KV_REG_KEY_ENTRY_8_15 +`define KV_REG_KEY_ENTRY_8_15 (32'h83c) +`endif +`ifndef KV_REG_KEY_ENTRY_9_0 +`define KV_REG_KEY_ENTRY_9_0 (32'h840) +`endif +`ifndef KV_REG_KEY_ENTRY_9_1 +`define KV_REG_KEY_ENTRY_9_1 (32'h844) +`endif +`ifndef KV_REG_KEY_ENTRY_9_2 +`define KV_REG_KEY_ENTRY_9_2 (32'h848) +`endif +`ifndef KV_REG_KEY_ENTRY_9_3 +`define KV_REG_KEY_ENTRY_9_3 (32'h84c) +`endif +`ifndef KV_REG_KEY_ENTRY_9_4 +`define KV_REG_KEY_ENTRY_9_4 (32'h850) +`endif +`ifndef KV_REG_KEY_ENTRY_9_5 +`define KV_REG_KEY_ENTRY_9_5 (32'h854) +`endif +`ifndef KV_REG_KEY_ENTRY_9_6 +`define KV_REG_KEY_ENTRY_9_6 (32'h858) +`endif +`ifndef KV_REG_KEY_ENTRY_9_7 +`define KV_REG_KEY_ENTRY_9_7 (32'h85c) +`endif +`ifndef KV_REG_KEY_ENTRY_9_8 +`define KV_REG_KEY_ENTRY_9_8 (32'h860) +`endif +`ifndef KV_REG_KEY_ENTRY_9_9 +`define KV_REG_KEY_ENTRY_9_9 (32'h864) +`endif +`ifndef KV_REG_KEY_ENTRY_9_10 +`define KV_REG_KEY_ENTRY_9_10 (32'h868) +`endif +`ifndef KV_REG_KEY_ENTRY_9_11 +`define KV_REG_KEY_ENTRY_9_11 (32'h86c) +`endif +`ifndef KV_REG_KEY_ENTRY_9_12 +`define KV_REG_KEY_ENTRY_9_12 (32'h870) +`endif +`ifndef KV_REG_KEY_ENTRY_9_13 +`define KV_REG_KEY_ENTRY_9_13 (32'h874) +`endif +`ifndef KV_REG_KEY_ENTRY_9_14 +`define KV_REG_KEY_ENTRY_9_14 (32'h878) +`endif +`ifndef KV_REG_KEY_ENTRY_9_15 +`define KV_REG_KEY_ENTRY_9_15 (32'h87c) +`endif +`ifndef KV_REG_KEY_ENTRY_10_0 +`define KV_REG_KEY_ENTRY_10_0 (32'h880) +`endif +`ifndef KV_REG_KEY_ENTRY_10_1 +`define KV_REG_KEY_ENTRY_10_1 (32'h884) +`endif +`ifndef KV_REG_KEY_ENTRY_10_2 +`define KV_REG_KEY_ENTRY_10_2 (32'h888) +`endif +`ifndef KV_REG_KEY_ENTRY_10_3 +`define KV_REG_KEY_ENTRY_10_3 (32'h88c) +`endif +`ifndef KV_REG_KEY_ENTRY_10_4 +`define KV_REG_KEY_ENTRY_10_4 (32'h890) +`endif +`ifndef KV_REG_KEY_ENTRY_10_5 +`define KV_REG_KEY_ENTRY_10_5 (32'h894) +`endif +`ifndef KV_REG_KEY_ENTRY_10_6 +`define KV_REG_KEY_ENTRY_10_6 (32'h898) +`endif +`ifndef KV_REG_KEY_ENTRY_10_7 +`define KV_REG_KEY_ENTRY_10_7 (32'h89c) +`endif +`ifndef KV_REG_KEY_ENTRY_10_8 +`define KV_REG_KEY_ENTRY_10_8 (32'h8a0) +`endif +`ifndef KV_REG_KEY_ENTRY_10_9 +`define KV_REG_KEY_ENTRY_10_9 (32'h8a4) +`endif +`ifndef KV_REG_KEY_ENTRY_10_10 +`define KV_REG_KEY_ENTRY_10_10 (32'h8a8) +`endif +`ifndef KV_REG_KEY_ENTRY_10_11 +`define KV_REG_KEY_ENTRY_10_11 (32'h8ac) +`endif +`ifndef KV_REG_KEY_ENTRY_10_12 +`define KV_REG_KEY_ENTRY_10_12 (32'h8b0) +`endif +`ifndef KV_REG_KEY_ENTRY_10_13 +`define KV_REG_KEY_ENTRY_10_13 (32'h8b4) +`endif +`ifndef KV_REG_KEY_ENTRY_10_14 +`define KV_REG_KEY_ENTRY_10_14 (32'h8b8) +`endif +`ifndef KV_REG_KEY_ENTRY_10_15 +`define KV_REG_KEY_ENTRY_10_15 (32'h8bc) +`endif +`ifndef KV_REG_KEY_ENTRY_11_0 +`define KV_REG_KEY_ENTRY_11_0 (32'h8c0) +`endif +`ifndef KV_REG_KEY_ENTRY_11_1 +`define KV_REG_KEY_ENTRY_11_1 (32'h8c4) +`endif +`ifndef KV_REG_KEY_ENTRY_11_2 +`define KV_REG_KEY_ENTRY_11_2 (32'h8c8) +`endif +`ifndef KV_REG_KEY_ENTRY_11_3 +`define KV_REG_KEY_ENTRY_11_3 (32'h8cc) +`endif +`ifndef KV_REG_KEY_ENTRY_11_4 +`define KV_REG_KEY_ENTRY_11_4 (32'h8d0) +`endif +`ifndef KV_REG_KEY_ENTRY_11_5 +`define KV_REG_KEY_ENTRY_11_5 (32'h8d4) +`endif +`ifndef KV_REG_KEY_ENTRY_11_6 +`define KV_REG_KEY_ENTRY_11_6 (32'h8d8) +`endif +`ifndef KV_REG_KEY_ENTRY_11_7 +`define KV_REG_KEY_ENTRY_11_7 (32'h8dc) +`endif +`ifndef KV_REG_KEY_ENTRY_11_8 +`define KV_REG_KEY_ENTRY_11_8 (32'h8e0) +`endif +`ifndef KV_REG_KEY_ENTRY_11_9 +`define KV_REG_KEY_ENTRY_11_9 (32'h8e4) +`endif +`ifndef KV_REG_KEY_ENTRY_11_10 +`define KV_REG_KEY_ENTRY_11_10 (32'h8e8) +`endif +`ifndef KV_REG_KEY_ENTRY_11_11 +`define KV_REG_KEY_ENTRY_11_11 (32'h8ec) +`endif +`ifndef KV_REG_KEY_ENTRY_11_12 +`define KV_REG_KEY_ENTRY_11_12 (32'h8f0) +`endif +`ifndef KV_REG_KEY_ENTRY_11_13 +`define KV_REG_KEY_ENTRY_11_13 (32'h8f4) +`endif +`ifndef KV_REG_KEY_ENTRY_11_14 +`define KV_REG_KEY_ENTRY_11_14 (32'h8f8) +`endif +`ifndef KV_REG_KEY_ENTRY_11_15 +`define KV_REG_KEY_ENTRY_11_15 (32'h8fc) +`endif +`ifndef KV_REG_KEY_ENTRY_12_0 +`define KV_REG_KEY_ENTRY_12_0 (32'h900) +`endif +`ifndef KV_REG_KEY_ENTRY_12_1 +`define KV_REG_KEY_ENTRY_12_1 (32'h904) +`endif +`ifndef KV_REG_KEY_ENTRY_12_2 +`define KV_REG_KEY_ENTRY_12_2 (32'h908) +`endif +`ifndef KV_REG_KEY_ENTRY_12_3 +`define KV_REG_KEY_ENTRY_12_3 (32'h90c) +`endif +`ifndef KV_REG_KEY_ENTRY_12_4 +`define KV_REG_KEY_ENTRY_12_4 (32'h910) +`endif +`ifndef KV_REG_KEY_ENTRY_12_5 +`define KV_REG_KEY_ENTRY_12_5 (32'h914) +`endif +`ifndef KV_REG_KEY_ENTRY_12_6 +`define KV_REG_KEY_ENTRY_12_6 (32'h918) +`endif +`ifndef KV_REG_KEY_ENTRY_12_7 +`define KV_REG_KEY_ENTRY_12_7 (32'h91c) +`endif +`ifndef KV_REG_KEY_ENTRY_12_8 +`define KV_REG_KEY_ENTRY_12_8 (32'h920) +`endif +`ifndef KV_REG_KEY_ENTRY_12_9 +`define KV_REG_KEY_ENTRY_12_9 (32'h924) +`endif +`ifndef KV_REG_KEY_ENTRY_12_10 +`define KV_REG_KEY_ENTRY_12_10 (32'h928) +`endif +`ifndef KV_REG_KEY_ENTRY_12_11 +`define KV_REG_KEY_ENTRY_12_11 (32'h92c) +`endif +`ifndef KV_REG_KEY_ENTRY_12_12 +`define KV_REG_KEY_ENTRY_12_12 (32'h930) +`endif +`ifndef KV_REG_KEY_ENTRY_12_13 +`define KV_REG_KEY_ENTRY_12_13 (32'h934) +`endif +`ifndef KV_REG_KEY_ENTRY_12_14 +`define KV_REG_KEY_ENTRY_12_14 (32'h938) +`endif +`ifndef KV_REG_KEY_ENTRY_12_15 +`define KV_REG_KEY_ENTRY_12_15 (32'h93c) +`endif +`ifndef KV_REG_KEY_ENTRY_13_0 +`define KV_REG_KEY_ENTRY_13_0 (32'h940) +`endif +`ifndef KV_REG_KEY_ENTRY_13_1 +`define KV_REG_KEY_ENTRY_13_1 (32'h944) +`endif +`ifndef KV_REG_KEY_ENTRY_13_2 +`define KV_REG_KEY_ENTRY_13_2 (32'h948) +`endif +`ifndef KV_REG_KEY_ENTRY_13_3 +`define KV_REG_KEY_ENTRY_13_3 (32'h94c) +`endif +`ifndef KV_REG_KEY_ENTRY_13_4 +`define KV_REG_KEY_ENTRY_13_4 (32'h950) +`endif +`ifndef KV_REG_KEY_ENTRY_13_5 +`define KV_REG_KEY_ENTRY_13_5 (32'h954) +`endif +`ifndef KV_REG_KEY_ENTRY_13_6 +`define KV_REG_KEY_ENTRY_13_6 (32'h958) +`endif +`ifndef KV_REG_KEY_ENTRY_13_7 +`define KV_REG_KEY_ENTRY_13_7 (32'h95c) +`endif +`ifndef KV_REG_KEY_ENTRY_13_8 +`define KV_REG_KEY_ENTRY_13_8 (32'h960) +`endif +`ifndef KV_REG_KEY_ENTRY_13_9 +`define KV_REG_KEY_ENTRY_13_9 (32'h964) +`endif +`ifndef KV_REG_KEY_ENTRY_13_10 +`define KV_REG_KEY_ENTRY_13_10 (32'h968) +`endif +`ifndef KV_REG_KEY_ENTRY_13_11 +`define KV_REG_KEY_ENTRY_13_11 (32'h96c) +`endif +`ifndef KV_REG_KEY_ENTRY_13_12 +`define KV_REG_KEY_ENTRY_13_12 (32'h970) +`endif +`ifndef KV_REG_KEY_ENTRY_13_13 +`define KV_REG_KEY_ENTRY_13_13 (32'h974) +`endif +`ifndef KV_REG_KEY_ENTRY_13_14 +`define KV_REG_KEY_ENTRY_13_14 (32'h978) +`endif +`ifndef KV_REG_KEY_ENTRY_13_15 +`define KV_REG_KEY_ENTRY_13_15 (32'h97c) +`endif +`ifndef KV_REG_KEY_ENTRY_14_0 +`define KV_REG_KEY_ENTRY_14_0 (32'h980) +`endif +`ifndef KV_REG_KEY_ENTRY_14_1 +`define KV_REG_KEY_ENTRY_14_1 (32'h984) +`endif +`ifndef KV_REG_KEY_ENTRY_14_2 +`define KV_REG_KEY_ENTRY_14_2 (32'h988) +`endif +`ifndef KV_REG_KEY_ENTRY_14_3 +`define KV_REG_KEY_ENTRY_14_3 (32'h98c) +`endif +`ifndef KV_REG_KEY_ENTRY_14_4 +`define KV_REG_KEY_ENTRY_14_4 (32'h990) +`endif +`ifndef KV_REG_KEY_ENTRY_14_5 +`define KV_REG_KEY_ENTRY_14_5 (32'h994) +`endif +`ifndef KV_REG_KEY_ENTRY_14_6 +`define KV_REG_KEY_ENTRY_14_6 (32'h998) +`endif +`ifndef KV_REG_KEY_ENTRY_14_7 +`define KV_REG_KEY_ENTRY_14_7 (32'h99c) +`endif +`ifndef KV_REG_KEY_ENTRY_14_8 +`define KV_REG_KEY_ENTRY_14_8 (32'h9a0) +`endif +`ifndef KV_REG_KEY_ENTRY_14_9 +`define KV_REG_KEY_ENTRY_14_9 (32'h9a4) +`endif +`ifndef KV_REG_KEY_ENTRY_14_10 +`define KV_REG_KEY_ENTRY_14_10 (32'h9a8) +`endif +`ifndef KV_REG_KEY_ENTRY_14_11 +`define KV_REG_KEY_ENTRY_14_11 (32'h9ac) +`endif +`ifndef KV_REG_KEY_ENTRY_14_12 +`define KV_REG_KEY_ENTRY_14_12 (32'h9b0) +`endif +`ifndef KV_REG_KEY_ENTRY_14_13 +`define KV_REG_KEY_ENTRY_14_13 (32'h9b4) +`endif +`ifndef KV_REG_KEY_ENTRY_14_14 +`define KV_REG_KEY_ENTRY_14_14 (32'h9b8) +`endif +`ifndef KV_REG_KEY_ENTRY_14_15 +`define KV_REG_KEY_ENTRY_14_15 (32'h9bc) +`endif +`ifndef KV_REG_KEY_ENTRY_15_0 +`define KV_REG_KEY_ENTRY_15_0 (32'h9c0) +`endif +`ifndef KV_REG_KEY_ENTRY_15_1 +`define KV_REG_KEY_ENTRY_15_1 (32'h9c4) +`endif +`ifndef KV_REG_KEY_ENTRY_15_2 +`define KV_REG_KEY_ENTRY_15_2 (32'h9c8) +`endif +`ifndef KV_REG_KEY_ENTRY_15_3 +`define KV_REG_KEY_ENTRY_15_3 (32'h9cc) +`endif +`ifndef KV_REG_KEY_ENTRY_15_4 +`define KV_REG_KEY_ENTRY_15_4 (32'h9d0) +`endif +`ifndef KV_REG_KEY_ENTRY_15_5 +`define KV_REG_KEY_ENTRY_15_5 (32'h9d4) +`endif +`ifndef KV_REG_KEY_ENTRY_15_6 +`define KV_REG_KEY_ENTRY_15_6 (32'h9d8) +`endif +`ifndef KV_REG_KEY_ENTRY_15_7 +`define KV_REG_KEY_ENTRY_15_7 (32'h9dc) +`endif +`ifndef KV_REG_KEY_ENTRY_15_8 +`define KV_REG_KEY_ENTRY_15_8 (32'h9e0) +`endif +`ifndef KV_REG_KEY_ENTRY_15_9 +`define KV_REG_KEY_ENTRY_15_9 (32'h9e4) +`endif +`ifndef KV_REG_KEY_ENTRY_15_10 +`define KV_REG_KEY_ENTRY_15_10 (32'h9e8) +`endif +`ifndef KV_REG_KEY_ENTRY_15_11 +`define KV_REG_KEY_ENTRY_15_11 (32'h9ec) +`endif +`ifndef KV_REG_KEY_ENTRY_15_12 +`define KV_REG_KEY_ENTRY_15_12 (32'h9f0) +`endif +`ifndef KV_REG_KEY_ENTRY_15_13 +`define KV_REG_KEY_ENTRY_15_13 (32'h9f4) +`endif +`ifndef KV_REG_KEY_ENTRY_15_14 +`define KV_REG_KEY_ENTRY_15_14 (32'h9f8) +`endif +`ifndef KV_REG_KEY_ENTRY_15_15 +`define KV_REG_KEY_ENTRY_15_15 (32'h9fc) +`endif +`ifndef KV_REG_KEY_ENTRY_16_0 +`define KV_REG_KEY_ENTRY_16_0 (32'ha00) +`endif +`ifndef KV_REG_KEY_ENTRY_16_1 +`define KV_REG_KEY_ENTRY_16_1 (32'ha04) +`endif +`ifndef KV_REG_KEY_ENTRY_16_2 +`define KV_REG_KEY_ENTRY_16_2 (32'ha08) +`endif +`ifndef KV_REG_KEY_ENTRY_16_3 +`define KV_REG_KEY_ENTRY_16_3 (32'ha0c) +`endif +`ifndef KV_REG_KEY_ENTRY_16_4 +`define KV_REG_KEY_ENTRY_16_4 (32'ha10) +`endif +`ifndef KV_REG_KEY_ENTRY_16_5 +`define KV_REG_KEY_ENTRY_16_5 (32'ha14) +`endif +`ifndef KV_REG_KEY_ENTRY_16_6 +`define KV_REG_KEY_ENTRY_16_6 (32'ha18) +`endif +`ifndef KV_REG_KEY_ENTRY_16_7 +`define KV_REG_KEY_ENTRY_16_7 (32'ha1c) +`endif +`ifndef KV_REG_KEY_ENTRY_16_8 +`define KV_REG_KEY_ENTRY_16_8 (32'ha20) +`endif +`ifndef KV_REG_KEY_ENTRY_16_9 +`define KV_REG_KEY_ENTRY_16_9 (32'ha24) +`endif +`ifndef KV_REG_KEY_ENTRY_16_10 +`define KV_REG_KEY_ENTRY_16_10 (32'ha28) +`endif +`ifndef KV_REG_KEY_ENTRY_16_11 +`define KV_REG_KEY_ENTRY_16_11 (32'ha2c) +`endif +`ifndef KV_REG_KEY_ENTRY_16_12 +`define KV_REG_KEY_ENTRY_16_12 (32'ha30) +`endif +`ifndef KV_REG_KEY_ENTRY_16_13 +`define KV_REG_KEY_ENTRY_16_13 (32'ha34) +`endif +`ifndef KV_REG_KEY_ENTRY_16_14 +`define KV_REG_KEY_ENTRY_16_14 (32'ha38) +`endif +`ifndef KV_REG_KEY_ENTRY_16_15 +`define KV_REG_KEY_ENTRY_16_15 (32'ha3c) +`endif +`ifndef KV_REG_KEY_ENTRY_17_0 +`define KV_REG_KEY_ENTRY_17_0 (32'ha40) +`endif +`ifndef KV_REG_KEY_ENTRY_17_1 +`define KV_REG_KEY_ENTRY_17_1 (32'ha44) +`endif +`ifndef KV_REG_KEY_ENTRY_17_2 +`define KV_REG_KEY_ENTRY_17_2 (32'ha48) +`endif +`ifndef KV_REG_KEY_ENTRY_17_3 +`define KV_REG_KEY_ENTRY_17_3 (32'ha4c) +`endif +`ifndef KV_REG_KEY_ENTRY_17_4 +`define KV_REG_KEY_ENTRY_17_4 (32'ha50) +`endif +`ifndef KV_REG_KEY_ENTRY_17_5 +`define KV_REG_KEY_ENTRY_17_5 (32'ha54) +`endif +`ifndef KV_REG_KEY_ENTRY_17_6 +`define KV_REG_KEY_ENTRY_17_6 (32'ha58) +`endif +`ifndef KV_REG_KEY_ENTRY_17_7 +`define KV_REG_KEY_ENTRY_17_7 (32'ha5c) +`endif +`ifndef KV_REG_KEY_ENTRY_17_8 +`define KV_REG_KEY_ENTRY_17_8 (32'ha60) +`endif +`ifndef KV_REG_KEY_ENTRY_17_9 +`define KV_REG_KEY_ENTRY_17_9 (32'ha64) +`endif +`ifndef KV_REG_KEY_ENTRY_17_10 +`define KV_REG_KEY_ENTRY_17_10 (32'ha68) +`endif +`ifndef KV_REG_KEY_ENTRY_17_11 +`define KV_REG_KEY_ENTRY_17_11 (32'ha6c) +`endif +`ifndef KV_REG_KEY_ENTRY_17_12 +`define KV_REG_KEY_ENTRY_17_12 (32'ha70) +`endif +`ifndef KV_REG_KEY_ENTRY_17_13 +`define KV_REG_KEY_ENTRY_17_13 (32'ha74) +`endif +`ifndef KV_REG_KEY_ENTRY_17_14 +`define KV_REG_KEY_ENTRY_17_14 (32'ha78) +`endif +`ifndef KV_REG_KEY_ENTRY_17_15 +`define KV_REG_KEY_ENTRY_17_15 (32'ha7c) +`endif +`ifndef KV_REG_KEY_ENTRY_18_0 +`define KV_REG_KEY_ENTRY_18_0 (32'ha80) +`endif +`ifndef KV_REG_KEY_ENTRY_18_1 +`define KV_REG_KEY_ENTRY_18_1 (32'ha84) +`endif +`ifndef KV_REG_KEY_ENTRY_18_2 +`define KV_REG_KEY_ENTRY_18_2 (32'ha88) +`endif +`ifndef KV_REG_KEY_ENTRY_18_3 +`define KV_REG_KEY_ENTRY_18_3 (32'ha8c) +`endif +`ifndef KV_REG_KEY_ENTRY_18_4 +`define KV_REG_KEY_ENTRY_18_4 (32'ha90) +`endif +`ifndef KV_REG_KEY_ENTRY_18_5 +`define KV_REG_KEY_ENTRY_18_5 (32'ha94) +`endif +`ifndef KV_REG_KEY_ENTRY_18_6 +`define KV_REG_KEY_ENTRY_18_6 (32'ha98) +`endif +`ifndef KV_REG_KEY_ENTRY_18_7 +`define KV_REG_KEY_ENTRY_18_7 (32'ha9c) +`endif +`ifndef KV_REG_KEY_ENTRY_18_8 +`define KV_REG_KEY_ENTRY_18_8 (32'haa0) +`endif +`ifndef KV_REG_KEY_ENTRY_18_9 +`define KV_REG_KEY_ENTRY_18_9 (32'haa4) +`endif +`ifndef KV_REG_KEY_ENTRY_18_10 +`define KV_REG_KEY_ENTRY_18_10 (32'haa8) +`endif +`ifndef KV_REG_KEY_ENTRY_18_11 +`define KV_REG_KEY_ENTRY_18_11 (32'haac) +`endif +`ifndef KV_REG_KEY_ENTRY_18_12 +`define KV_REG_KEY_ENTRY_18_12 (32'hab0) +`endif +`ifndef KV_REG_KEY_ENTRY_18_13 +`define KV_REG_KEY_ENTRY_18_13 (32'hab4) +`endif +`ifndef KV_REG_KEY_ENTRY_18_14 +`define KV_REG_KEY_ENTRY_18_14 (32'hab8) +`endif +`ifndef KV_REG_KEY_ENTRY_18_15 +`define KV_REG_KEY_ENTRY_18_15 (32'habc) +`endif +`ifndef KV_REG_KEY_ENTRY_19_0 +`define KV_REG_KEY_ENTRY_19_0 (32'hac0) +`endif +`ifndef KV_REG_KEY_ENTRY_19_1 +`define KV_REG_KEY_ENTRY_19_1 (32'hac4) +`endif +`ifndef KV_REG_KEY_ENTRY_19_2 +`define KV_REG_KEY_ENTRY_19_2 (32'hac8) +`endif +`ifndef KV_REG_KEY_ENTRY_19_3 +`define KV_REG_KEY_ENTRY_19_3 (32'hacc) +`endif +`ifndef KV_REG_KEY_ENTRY_19_4 +`define KV_REG_KEY_ENTRY_19_4 (32'had0) +`endif +`ifndef KV_REG_KEY_ENTRY_19_5 +`define KV_REG_KEY_ENTRY_19_5 (32'had4) +`endif +`ifndef KV_REG_KEY_ENTRY_19_6 +`define KV_REG_KEY_ENTRY_19_6 (32'had8) +`endif +`ifndef KV_REG_KEY_ENTRY_19_7 +`define KV_REG_KEY_ENTRY_19_7 (32'hadc) +`endif +`ifndef KV_REG_KEY_ENTRY_19_8 +`define KV_REG_KEY_ENTRY_19_8 (32'hae0) +`endif +`ifndef KV_REG_KEY_ENTRY_19_9 +`define KV_REG_KEY_ENTRY_19_9 (32'hae4) +`endif +`ifndef KV_REG_KEY_ENTRY_19_10 +`define KV_REG_KEY_ENTRY_19_10 (32'hae8) +`endif +`ifndef KV_REG_KEY_ENTRY_19_11 +`define KV_REG_KEY_ENTRY_19_11 (32'haec) +`endif +`ifndef KV_REG_KEY_ENTRY_19_12 +`define KV_REG_KEY_ENTRY_19_12 (32'haf0) +`endif +`ifndef KV_REG_KEY_ENTRY_19_13 +`define KV_REG_KEY_ENTRY_19_13 (32'haf4) +`endif +`ifndef KV_REG_KEY_ENTRY_19_14 +`define KV_REG_KEY_ENTRY_19_14 (32'haf8) +`endif +`ifndef KV_REG_KEY_ENTRY_19_15 +`define KV_REG_KEY_ENTRY_19_15 (32'hafc) +`endif +`ifndef KV_REG_KEY_ENTRY_20_0 +`define KV_REG_KEY_ENTRY_20_0 (32'hb00) +`endif +`ifndef KV_REG_KEY_ENTRY_20_1 +`define KV_REG_KEY_ENTRY_20_1 (32'hb04) +`endif +`ifndef KV_REG_KEY_ENTRY_20_2 +`define KV_REG_KEY_ENTRY_20_2 (32'hb08) +`endif +`ifndef KV_REG_KEY_ENTRY_20_3 +`define KV_REG_KEY_ENTRY_20_3 (32'hb0c) +`endif +`ifndef KV_REG_KEY_ENTRY_20_4 +`define KV_REG_KEY_ENTRY_20_4 (32'hb10) +`endif +`ifndef KV_REG_KEY_ENTRY_20_5 +`define KV_REG_KEY_ENTRY_20_5 (32'hb14) +`endif +`ifndef KV_REG_KEY_ENTRY_20_6 +`define KV_REG_KEY_ENTRY_20_6 (32'hb18) +`endif +`ifndef KV_REG_KEY_ENTRY_20_7 +`define KV_REG_KEY_ENTRY_20_7 (32'hb1c) +`endif +`ifndef KV_REG_KEY_ENTRY_20_8 +`define KV_REG_KEY_ENTRY_20_8 (32'hb20) +`endif +`ifndef KV_REG_KEY_ENTRY_20_9 +`define KV_REG_KEY_ENTRY_20_9 (32'hb24) +`endif +`ifndef KV_REG_KEY_ENTRY_20_10 +`define KV_REG_KEY_ENTRY_20_10 (32'hb28) +`endif +`ifndef KV_REG_KEY_ENTRY_20_11 +`define KV_REG_KEY_ENTRY_20_11 (32'hb2c) +`endif +`ifndef KV_REG_KEY_ENTRY_20_12 +`define KV_REG_KEY_ENTRY_20_12 (32'hb30) +`endif +`ifndef KV_REG_KEY_ENTRY_20_13 +`define KV_REG_KEY_ENTRY_20_13 (32'hb34) +`endif +`ifndef KV_REG_KEY_ENTRY_20_14 +`define KV_REG_KEY_ENTRY_20_14 (32'hb38) +`endif +`ifndef KV_REG_KEY_ENTRY_20_15 +`define KV_REG_KEY_ENTRY_20_15 (32'hb3c) +`endif +`ifndef KV_REG_KEY_ENTRY_21_0 +`define KV_REG_KEY_ENTRY_21_0 (32'hb40) +`endif +`ifndef KV_REG_KEY_ENTRY_21_1 +`define KV_REG_KEY_ENTRY_21_1 (32'hb44) +`endif +`ifndef KV_REG_KEY_ENTRY_21_2 +`define KV_REG_KEY_ENTRY_21_2 (32'hb48) +`endif +`ifndef KV_REG_KEY_ENTRY_21_3 +`define KV_REG_KEY_ENTRY_21_3 (32'hb4c) +`endif +`ifndef KV_REG_KEY_ENTRY_21_4 +`define KV_REG_KEY_ENTRY_21_4 (32'hb50) +`endif +`ifndef KV_REG_KEY_ENTRY_21_5 +`define KV_REG_KEY_ENTRY_21_5 (32'hb54) +`endif +`ifndef KV_REG_KEY_ENTRY_21_6 +`define KV_REG_KEY_ENTRY_21_6 (32'hb58) +`endif +`ifndef KV_REG_KEY_ENTRY_21_7 +`define KV_REG_KEY_ENTRY_21_7 (32'hb5c) +`endif +`ifndef KV_REG_KEY_ENTRY_21_8 +`define KV_REG_KEY_ENTRY_21_8 (32'hb60) +`endif +`ifndef KV_REG_KEY_ENTRY_21_9 +`define KV_REG_KEY_ENTRY_21_9 (32'hb64) +`endif +`ifndef KV_REG_KEY_ENTRY_21_10 +`define KV_REG_KEY_ENTRY_21_10 (32'hb68) +`endif +`ifndef KV_REG_KEY_ENTRY_21_11 +`define KV_REG_KEY_ENTRY_21_11 (32'hb6c) +`endif +`ifndef KV_REG_KEY_ENTRY_21_12 +`define KV_REG_KEY_ENTRY_21_12 (32'hb70) +`endif +`ifndef KV_REG_KEY_ENTRY_21_13 +`define KV_REG_KEY_ENTRY_21_13 (32'hb74) +`endif +`ifndef KV_REG_KEY_ENTRY_21_14 +`define KV_REG_KEY_ENTRY_21_14 (32'hb78) +`endif +`ifndef KV_REG_KEY_ENTRY_21_15 +`define KV_REG_KEY_ENTRY_21_15 (32'hb7c) +`endif +`ifndef KV_REG_KEY_ENTRY_22_0 +`define KV_REG_KEY_ENTRY_22_0 (32'hb80) +`endif +`ifndef KV_REG_KEY_ENTRY_22_1 +`define KV_REG_KEY_ENTRY_22_1 (32'hb84) +`endif +`ifndef KV_REG_KEY_ENTRY_22_2 +`define KV_REG_KEY_ENTRY_22_2 (32'hb88) +`endif +`ifndef KV_REG_KEY_ENTRY_22_3 +`define KV_REG_KEY_ENTRY_22_3 (32'hb8c) +`endif +`ifndef KV_REG_KEY_ENTRY_22_4 +`define KV_REG_KEY_ENTRY_22_4 (32'hb90) +`endif +`ifndef KV_REG_KEY_ENTRY_22_5 +`define KV_REG_KEY_ENTRY_22_5 (32'hb94) +`endif +`ifndef KV_REG_KEY_ENTRY_22_6 +`define KV_REG_KEY_ENTRY_22_6 (32'hb98) +`endif +`ifndef KV_REG_KEY_ENTRY_22_7 +`define KV_REG_KEY_ENTRY_22_7 (32'hb9c) +`endif +`ifndef KV_REG_KEY_ENTRY_22_8 +`define KV_REG_KEY_ENTRY_22_8 (32'hba0) +`endif +`ifndef KV_REG_KEY_ENTRY_22_9 +`define KV_REG_KEY_ENTRY_22_9 (32'hba4) +`endif +`ifndef KV_REG_KEY_ENTRY_22_10 +`define KV_REG_KEY_ENTRY_22_10 (32'hba8) +`endif +`ifndef KV_REG_KEY_ENTRY_22_11 +`define KV_REG_KEY_ENTRY_22_11 (32'hbac) +`endif +`ifndef KV_REG_KEY_ENTRY_22_12 +`define KV_REG_KEY_ENTRY_22_12 (32'hbb0) +`endif +`ifndef KV_REG_KEY_ENTRY_22_13 +`define KV_REG_KEY_ENTRY_22_13 (32'hbb4) +`endif +`ifndef KV_REG_KEY_ENTRY_22_14 +`define KV_REG_KEY_ENTRY_22_14 (32'hbb8) +`endif +`ifndef KV_REG_KEY_ENTRY_22_15 +`define KV_REG_KEY_ENTRY_22_15 (32'hbbc) +`endif +`ifndef KV_REG_KEY_ENTRY_23_0 +`define KV_REG_KEY_ENTRY_23_0 (32'hbc0) +`endif +`ifndef KV_REG_KEY_ENTRY_23_1 +`define KV_REG_KEY_ENTRY_23_1 (32'hbc4) +`endif +`ifndef KV_REG_KEY_ENTRY_23_2 +`define KV_REG_KEY_ENTRY_23_2 (32'hbc8) +`endif +`ifndef KV_REG_KEY_ENTRY_23_3 +`define KV_REG_KEY_ENTRY_23_3 (32'hbcc) +`endif +`ifndef KV_REG_KEY_ENTRY_23_4 +`define KV_REG_KEY_ENTRY_23_4 (32'hbd0) +`endif +`ifndef KV_REG_KEY_ENTRY_23_5 +`define KV_REG_KEY_ENTRY_23_5 (32'hbd4) +`endif +`ifndef KV_REG_KEY_ENTRY_23_6 +`define KV_REG_KEY_ENTRY_23_6 (32'hbd8) +`endif +`ifndef KV_REG_KEY_ENTRY_23_7 +`define KV_REG_KEY_ENTRY_23_7 (32'hbdc) +`endif +`ifndef KV_REG_KEY_ENTRY_23_8 +`define KV_REG_KEY_ENTRY_23_8 (32'hbe0) +`endif +`ifndef KV_REG_KEY_ENTRY_23_9 +`define KV_REG_KEY_ENTRY_23_9 (32'hbe4) +`endif +`ifndef KV_REG_KEY_ENTRY_23_10 +`define KV_REG_KEY_ENTRY_23_10 (32'hbe8) +`endif +`ifndef KV_REG_KEY_ENTRY_23_11 +`define KV_REG_KEY_ENTRY_23_11 (32'hbec) +`endif +`ifndef KV_REG_KEY_ENTRY_23_12 +`define KV_REG_KEY_ENTRY_23_12 (32'hbf0) +`endif +`ifndef KV_REG_KEY_ENTRY_23_13 +`define KV_REG_KEY_ENTRY_23_13 (32'hbf4) +`endif +`ifndef KV_REG_KEY_ENTRY_23_14 +`define KV_REG_KEY_ENTRY_23_14 (32'hbf8) +`endif +`ifndef KV_REG_KEY_ENTRY_23_15 +`define KV_REG_KEY_ENTRY_23_15 (32'hbfc) +`endif +`ifndef KV_REG_CLEAR_SECRETS +`define KV_REG_CLEAR_SECRETS (32'hc00) +`define KV_REG_CLEAR_SECRETS_WR_DEBUG_VALUES_LOW (0) +`define KV_REG_CLEAR_SECRETS_WR_DEBUG_VALUES_MASK (32'h1) +`define KV_REG_CLEAR_SECRETS_SEL_DEBUG_VALUE_LOW (1) +`define KV_REG_CLEAR_SECRETS_SEL_DEBUG_VALUE_MASK (32'h2) +`endif +`ifndef PV_REG_PCR_CTRL_0 +`define PV_REG_PCR_CTRL_0 (32'h0) +`define PV_REG_PCR_CTRL_0_LOCK_LOW (0) +`define PV_REG_PCR_CTRL_0_LOCK_MASK (32'h1) +`define PV_REG_PCR_CTRL_0_CLEAR_LOW (1) +`define PV_REG_PCR_CTRL_0_CLEAR_MASK (32'h2) +`define PV_REG_PCR_CTRL_0_RSVD0_LOW (2) +`define PV_REG_PCR_CTRL_0_RSVD0_MASK (32'h4) +`define PV_REG_PCR_CTRL_0_RSVD1_LOW (3) +`define PV_REG_PCR_CTRL_0_RSVD1_MASK (32'hf8) +`endif +`ifndef PV_REG_PCR_CTRL_1 +`define PV_REG_PCR_CTRL_1 (32'h4) +`define PV_REG_PCR_CTRL_1_LOCK_LOW (0) +`define PV_REG_PCR_CTRL_1_LOCK_MASK (32'h1) +`define PV_REG_PCR_CTRL_1_CLEAR_LOW (1) +`define PV_REG_PCR_CTRL_1_CLEAR_MASK (32'h2) +`define PV_REG_PCR_CTRL_1_RSVD0_LOW (2) +`define PV_REG_PCR_CTRL_1_RSVD0_MASK (32'h4) +`define PV_REG_PCR_CTRL_1_RSVD1_LOW (3) +`define PV_REG_PCR_CTRL_1_RSVD1_MASK (32'hf8) +`endif +`ifndef PV_REG_PCR_CTRL_2 +`define PV_REG_PCR_CTRL_2 (32'h8) +`define PV_REG_PCR_CTRL_2_LOCK_LOW (0) +`define PV_REG_PCR_CTRL_2_LOCK_MASK (32'h1) +`define PV_REG_PCR_CTRL_2_CLEAR_LOW (1) +`define PV_REG_PCR_CTRL_2_CLEAR_MASK (32'h2) +`define PV_REG_PCR_CTRL_2_RSVD0_LOW (2) +`define PV_REG_PCR_CTRL_2_RSVD0_MASK (32'h4) +`define PV_REG_PCR_CTRL_2_RSVD1_LOW (3) +`define PV_REG_PCR_CTRL_2_RSVD1_MASK (32'hf8) +`endif +`ifndef PV_REG_PCR_CTRL_3 +`define PV_REG_PCR_CTRL_3 (32'hc) +`define PV_REG_PCR_CTRL_3_LOCK_LOW (0) +`define PV_REG_PCR_CTRL_3_LOCK_MASK (32'h1) +`define PV_REG_PCR_CTRL_3_CLEAR_LOW (1) +`define PV_REG_PCR_CTRL_3_CLEAR_MASK (32'h2) +`define PV_REG_PCR_CTRL_3_RSVD0_LOW (2) +`define PV_REG_PCR_CTRL_3_RSVD0_MASK (32'h4) +`define PV_REG_PCR_CTRL_3_RSVD1_LOW (3) +`define PV_REG_PCR_CTRL_3_RSVD1_MASK (32'hf8) +`endif +`ifndef PV_REG_PCR_CTRL_4 +`define PV_REG_PCR_CTRL_4 (32'h10) +`define PV_REG_PCR_CTRL_4_LOCK_LOW (0) +`define PV_REG_PCR_CTRL_4_LOCK_MASK (32'h1) +`define PV_REG_PCR_CTRL_4_CLEAR_LOW (1) +`define PV_REG_PCR_CTRL_4_CLEAR_MASK (32'h2) +`define PV_REG_PCR_CTRL_4_RSVD0_LOW (2) +`define PV_REG_PCR_CTRL_4_RSVD0_MASK (32'h4) +`define PV_REG_PCR_CTRL_4_RSVD1_LOW (3) +`define PV_REG_PCR_CTRL_4_RSVD1_MASK (32'hf8) +`endif +`ifndef PV_REG_PCR_CTRL_5 +`define PV_REG_PCR_CTRL_5 (32'h14) +`define PV_REG_PCR_CTRL_5_LOCK_LOW (0) +`define PV_REG_PCR_CTRL_5_LOCK_MASK (32'h1) +`define PV_REG_PCR_CTRL_5_CLEAR_LOW (1) +`define PV_REG_PCR_CTRL_5_CLEAR_MASK (32'h2) +`define PV_REG_PCR_CTRL_5_RSVD0_LOW (2) +`define PV_REG_PCR_CTRL_5_RSVD0_MASK (32'h4) +`define PV_REG_PCR_CTRL_5_RSVD1_LOW (3) +`define PV_REG_PCR_CTRL_5_RSVD1_MASK (32'hf8) +`endif +`ifndef PV_REG_PCR_CTRL_6 +`define PV_REG_PCR_CTRL_6 (32'h18) +`define PV_REG_PCR_CTRL_6_LOCK_LOW (0) +`define PV_REG_PCR_CTRL_6_LOCK_MASK (32'h1) +`define PV_REG_PCR_CTRL_6_CLEAR_LOW (1) +`define PV_REG_PCR_CTRL_6_CLEAR_MASK (32'h2) +`define PV_REG_PCR_CTRL_6_RSVD0_LOW (2) +`define PV_REG_PCR_CTRL_6_RSVD0_MASK (32'h4) +`define PV_REG_PCR_CTRL_6_RSVD1_LOW (3) +`define PV_REG_PCR_CTRL_6_RSVD1_MASK (32'hf8) +`endif +`ifndef PV_REG_PCR_CTRL_7 +`define PV_REG_PCR_CTRL_7 (32'h1c) +`define PV_REG_PCR_CTRL_7_LOCK_LOW (0) +`define PV_REG_PCR_CTRL_7_LOCK_MASK (32'h1) +`define PV_REG_PCR_CTRL_7_CLEAR_LOW (1) +`define PV_REG_PCR_CTRL_7_CLEAR_MASK (32'h2) +`define PV_REG_PCR_CTRL_7_RSVD0_LOW (2) +`define PV_REG_PCR_CTRL_7_RSVD0_MASK (32'h4) +`define PV_REG_PCR_CTRL_7_RSVD1_LOW (3) +`define PV_REG_PCR_CTRL_7_RSVD1_MASK (32'hf8) +`endif +`ifndef PV_REG_PCR_CTRL_8 +`define PV_REG_PCR_CTRL_8 (32'h20) +`define PV_REG_PCR_CTRL_8_LOCK_LOW (0) +`define PV_REG_PCR_CTRL_8_LOCK_MASK (32'h1) +`define PV_REG_PCR_CTRL_8_CLEAR_LOW (1) +`define PV_REG_PCR_CTRL_8_CLEAR_MASK (32'h2) +`define PV_REG_PCR_CTRL_8_RSVD0_LOW (2) +`define PV_REG_PCR_CTRL_8_RSVD0_MASK (32'h4) +`define PV_REG_PCR_CTRL_8_RSVD1_LOW (3) +`define PV_REG_PCR_CTRL_8_RSVD1_MASK (32'hf8) +`endif +`ifndef PV_REG_PCR_CTRL_9 +`define PV_REG_PCR_CTRL_9 (32'h24) +`define PV_REG_PCR_CTRL_9_LOCK_LOW (0) +`define PV_REG_PCR_CTRL_9_LOCK_MASK (32'h1) +`define PV_REG_PCR_CTRL_9_CLEAR_LOW (1) +`define PV_REG_PCR_CTRL_9_CLEAR_MASK (32'h2) +`define PV_REG_PCR_CTRL_9_RSVD0_LOW (2) +`define PV_REG_PCR_CTRL_9_RSVD0_MASK (32'h4) +`define PV_REG_PCR_CTRL_9_RSVD1_LOW (3) +`define PV_REG_PCR_CTRL_9_RSVD1_MASK (32'hf8) +`endif +`ifndef PV_REG_PCR_CTRL_10 +`define PV_REG_PCR_CTRL_10 (32'h28) +`define PV_REG_PCR_CTRL_10_LOCK_LOW (0) +`define PV_REG_PCR_CTRL_10_LOCK_MASK (32'h1) +`define PV_REG_PCR_CTRL_10_CLEAR_LOW (1) +`define PV_REG_PCR_CTRL_10_CLEAR_MASK (32'h2) +`define PV_REG_PCR_CTRL_10_RSVD0_LOW (2) +`define PV_REG_PCR_CTRL_10_RSVD0_MASK (32'h4) +`define PV_REG_PCR_CTRL_10_RSVD1_LOW (3) +`define PV_REG_PCR_CTRL_10_RSVD1_MASK (32'hf8) +`endif +`ifndef PV_REG_PCR_CTRL_11 +`define PV_REG_PCR_CTRL_11 (32'h2c) +`define PV_REG_PCR_CTRL_11_LOCK_LOW (0) +`define PV_REG_PCR_CTRL_11_LOCK_MASK (32'h1) +`define PV_REG_PCR_CTRL_11_CLEAR_LOW (1) +`define PV_REG_PCR_CTRL_11_CLEAR_MASK (32'h2) +`define PV_REG_PCR_CTRL_11_RSVD0_LOW (2) +`define PV_REG_PCR_CTRL_11_RSVD0_MASK (32'h4) +`define PV_REG_PCR_CTRL_11_RSVD1_LOW (3) +`define PV_REG_PCR_CTRL_11_RSVD1_MASK (32'hf8) +`endif +`ifndef PV_REG_PCR_CTRL_12 +`define PV_REG_PCR_CTRL_12 (32'h30) +`define PV_REG_PCR_CTRL_12_LOCK_LOW (0) +`define PV_REG_PCR_CTRL_12_LOCK_MASK (32'h1) +`define PV_REG_PCR_CTRL_12_CLEAR_LOW (1) +`define PV_REG_PCR_CTRL_12_CLEAR_MASK (32'h2) +`define PV_REG_PCR_CTRL_12_RSVD0_LOW (2) +`define PV_REG_PCR_CTRL_12_RSVD0_MASK (32'h4) +`define PV_REG_PCR_CTRL_12_RSVD1_LOW (3) +`define PV_REG_PCR_CTRL_12_RSVD1_MASK (32'hf8) +`endif +`ifndef PV_REG_PCR_CTRL_13 +`define PV_REG_PCR_CTRL_13 (32'h34) +`define PV_REG_PCR_CTRL_13_LOCK_LOW (0) +`define PV_REG_PCR_CTRL_13_LOCK_MASK (32'h1) +`define PV_REG_PCR_CTRL_13_CLEAR_LOW (1) +`define PV_REG_PCR_CTRL_13_CLEAR_MASK (32'h2) +`define PV_REG_PCR_CTRL_13_RSVD0_LOW (2) +`define PV_REG_PCR_CTRL_13_RSVD0_MASK (32'h4) +`define PV_REG_PCR_CTRL_13_RSVD1_LOW (3) +`define PV_REG_PCR_CTRL_13_RSVD1_MASK (32'hf8) +`endif +`ifndef PV_REG_PCR_CTRL_14 +`define PV_REG_PCR_CTRL_14 (32'h38) +`define PV_REG_PCR_CTRL_14_LOCK_LOW (0) +`define PV_REG_PCR_CTRL_14_LOCK_MASK (32'h1) +`define PV_REG_PCR_CTRL_14_CLEAR_LOW (1) +`define PV_REG_PCR_CTRL_14_CLEAR_MASK (32'h2) +`define PV_REG_PCR_CTRL_14_RSVD0_LOW (2) +`define PV_REG_PCR_CTRL_14_RSVD0_MASK (32'h4) +`define PV_REG_PCR_CTRL_14_RSVD1_LOW (3) +`define PV_REG_PCR_CTRL_14_RSVD1_MASK (32'hf8) +`endif +`ifndef PV_REG_PCR_CTRL_15 +`define PV_REG_PCR_CTRL_15 (32'h3c) +`define PV_REG_PCR_CTRL_15_LOCK_LOW (0) +`define PV_REG_PCR_CTRL_15_LOCK_MASK (32'h1) +`define PV_REG_PCR_CTRL_15_CLEAR_LOW (1) +`define PV_REG_PCR_CTRL_15_CLEAR_MASK (32'h2) +`define PV_REG_PCR_CTRL_15_RSVD0_LOW (2) +`define PV_REG_PCR_CTRL_15_RSVD0_MASK (32'h4) +`define PV_REG_PCR_CTRL_15_RSVD1_LOW (3) +`define PV_REG_PCR_CTRL_15_RSVD1_MASK (32'hf8) +`endif +`ifndef PV_REG_PCR_CTRL_16 +`define PV_REG_PCR_CTRL_16 (32'h40) +`define PV_REG_PCR_CTRL_16_LOCK_LOW (0) +`define PV_REG_PCR_CTRL_16_LOCK_MASK (32'h1) +`define PV_REG_PCR_CTRL_16_CLEAR_LOW (1) +`define PV_REG_PCR_CTRL_16_CLEAR_MASK (32'h2) +`define PV_REG_PCR_CTRL_16_RSVD0_LOW (2) +`define PV_REG_PCR_CTRL_16_RSVD0_MASK (32'h4) +`define PV_REG_PCR_CTRL_16_RSVD1_LOW (3) +`define PV_REG_PCR_CTRL_16_RSVD1_MASK (32'hf8) +`endif +`ifndef PV_REG_PCR_CTRL_17 +`define PV_REG_PCR_CTRL_17 (32'h44) +`define PV_REG_PCR_CTRL_17_LOCK_LOW (0) +`define PV_REG_PCR_CTRL_17_LOCK_MASK (32'h1) +`define PV_REG_PCR_CTRL_17_CLEAR_LOW (1) +`define PV_REG_PCR_CTRL_17_CLEAR_MASK (32'h2) +`define PV_REG_PCR_CTRL_17_RSVD0_LOW (2) +`define PV_REG_PCR_CTRL_17_RSVD0_MASK (32'h4) +`define PV_REG_PCR_CTRL_17_RSVD1_LOW (3) +`define PV_REG_PCR_CTRL_17_RSVD1_MASK (32'hf8) +`endif +`ifndef PV_REG_PCR_CTRL_18 +`define PV_REG_PCR_CTRL_18 (32'h48) +`define PV_REG_PCR_CTRL_18_LOCK_LOW (0) +`define PV_REG_PCR_CTRL_18_LOCK_MASK (32'h1) +`define PV_REG_PCR_CTRL_18_CLEAR_LOW (1) +`define PV_REG_PCR_CTRL_18_CLEAR_MASK (32'h2) +`define PV_REG_PCR_CTRL_18_RSVD0_LOW (2) +`define PV_REG_PCR_CTRL_18_RSVD0_MASK (32'h4) +`define PV_REG_PCR_CTRL_18_RSVD1_LOW (3) +`define PV_REG_PCR_CTRL_18_RSVD1_MASK (32'hf8) +`endif +`ifndef PV_REG_PCR_CTRL_19 +`define PV_REG_PCR_CTRL_19 (32'h4c) +`define PV_REG_PCR_CTRL_19_LOCK_LOW (0) +`define PV_REG_PCR_CTRL_19_LOCK_MASK (32'h1) +`define PV_REG_PCR_CTRL_19_CLEAR_LOW (1) +`define PV_REG_PCR_CTRL_19_CLEAR_MASK (32'h2) +`define PV_REG_PCR_CTRL_19_RSVD0_LOW (2) +`define PV_REG_PCR_CTRL_19_RSVD0_MASK (32'h4) +`define PV_REG_PCR_CTRL_19_RSVD1_LOW (3) +`define PV_REG_PCR_CTRL_19_RSVD1_MASK (32'hf8) +`endif +`ifndef PV_REG_PCR_CTRL_20 +`define PV_REG_PCR_CTRL_20 (32'h50) +`define PV_REG_PCR_CTRL_20_LOCK_LOW (0) +`define PV_REG_PCR_CTRL_20_LOCK_MASK (32'h1) +`define PV_REG_PCR_CTRL_20_CLEAR_LOW (1) +`define PV_REG_PCR_CTRL_20_CLEAR_MASK (32'h2) +`define PV_REG_PCR_CTRL_20_RSVD0_LOW (2) +`define PV_REG_PCR_CTRL_20_RSVD0_MASK (32'h4) +`define PV_REG_PCR_CTRL_20_RSVD1_LOW (3) +`define PV_REG_PCR_CTRL_20_RSVD1_MASK (32'hf8) +`endif +`ifndef PV_REG_PCR_CTRL_21 +`define PV_REG_PCR_CTRL_21 (32'h54) +`define PV_REG_PCR_CTRL_21_LOCK_LOW (0) +`define PV_REG_PCR_CTRL_21_LOCK_MASK (32'h1) +`define PV_REG_PCR_CTRL_21_CLEAR_LOW (1) +`define PV_REG_PCR_CTRL_21_CLEAR_MASK (32'h2) +`define PV_REG_PCR_CTRL_21_RSVD0_LOW (2) +`define PV_REG_PCR_CTRL_21_RSVD0_MASK (32'h4) +`define PV_REG_PCR_CTRL_21_RSVD1_LOW (3) +`define PV_REG_PCR_CTRL_21_RSVD1_MASK (32'hf8) +`endif +`ifndef PV_REG_PCR_CTRL_22 +`define PV_REG_PCR_CTRL_22 (32'h58) +`define PV_REG_PCR_CTRL_22_LOCK_LOW (0) +`define PV_REG_PCR_CTRL_22_LOCK_MASK (32'h1) +`define PV_REG_PCR_CTRL_22_CLEAR_LOW (1) +`define PV_REG_PCR_CTRL_22_CLEAR_MASK (32'h2) +`define PV_REG_PCR_CTRL_22_RSVD0_LOW (2) +`define PV_REG_PCR_CTRL_22_RSVD0_MASK (32'h4) +`define PV_REG_PCR_CTRL_22_RSVD1_LOW (3) +`define PV_REG_PCR_CTRL_22_RSVD1_MASK (32'hf8) +`endif +`ifndef PV_REG_PCR_CTRL_23 +`define PV_REG_PCR_CTRL_23 (32'h5c) +`define PV_REG_PCR_CTRL_23_LOCK_LOW (0) +`define PV_REG_PCR_CTRL_23_LOCK_MASK (32'h1) +`define PV_REG_PCR_CTRL_23_CLEAR_LOW (1) +`define PV_REG_PCR_CTRL_23_CLEAR_MASK (32'h2) +`define PV_REG_PCR_CTRL_23_RSVD0_LOW (2) +`define PV_REG_PCR_CTRL_23_RSVD0_MASK (32'h4) +`define PV_REG_PCR_CTRL_23_RSVD1_LOW (3) +`define PV_REG_PCR_CTRL_23_RSVD1_MASK (32'hf8) +`endif +`ifndef PV_REG_PCR_CTRL_24 +`define PV_REG_PCR_CTRL_24 (32'h60) +`define PV_REG_PCR_CTRL_24_LOCK_LOW (0) +`define PV_REG_PCR_CTRL_24_LOCK_MASK (32'h1) +`define PV_REG_PCR_CTRL_24_CLEAR_LOW (1) +`define PV_REG_PCR_CTRL_24_CLEAR_MASK (32'h2) +`define PV_REG_PCR_CTRL_24_RSVD0_LOW (2) +`define PV_REG_PCR_CTRL_24_RSVD0_MASK (32'h4) +`define PV_REG_PCR_CTRL_24_RSVD1_LOW (3) +`define PV_REG_PCR_CTRL_24_RSVD1_MASK (32'hf8) +`endif +`ifndef PV_REG_PCR_CTRL_25 +`define PV_REG_PCR_CTRL_25 (32'h64) +`define PV_REG_PCR_CTRL_25_LOCK_LOW (0) +`define PV_REG_PCR_CTRL_25_LOCK_MASK (32'h1) +`define PV_REG_PCR_CTRL_25_CLEAR_LOW (1) +`define PV_REG_PCR_CTRL_25_CLEAR_MASK (32'h2) +`define PV_REG_PCR_CTRL_25_RSVD0_LOW (2) +`define PV_REG_PCR_CTRL_25_RSVD0_MASK (32'h4) +`define PV_REG_PCR_CTRL_25_RSVD1_LOW (3) +`define PV_REG_PCR_CTRL_25_RSVD1_MASK (32'hf8) +`endif +`ifndef PV_REG_PCR_CTRL_26 +`define PV_REG_PCR_CTRL_26 (32'h68) +`define PV_REG_PCR_CTRL_26_LOCK_LOW (0) +`define PV_REG_PCR_CTRL_26_LOCK_MASK (32'h1) +`define PV_REG_PCR_CTRL_26_CLEAR_LOW (1) +`define PV_REG_PCR_CTRL_26_CLEAR_MASK (32'h2) +`define PV_REG_PCR_CTRL_26_RSVD0_LOW (2) +`define PV_REG_PCR_CTRL_26_RSVD0_MASK (32'h4) +`define PV_REG_PCR_CTRL_26_RSVD1_LOW (3) +`define PV_REG_PCR_CTRL_26_RSVD1_MASK (32'hf8) +`endif +`ifndef PV_REG_PCR_CTRL_27 +`define PV_REG_PCR_CTRL_27 (32'h6c) +`define PV_REG_PCR_CTRL_27_LOCK_LOW (0) +`define PV_REG_PCR_CTRL_27_LOCK_MASK (32'h1) +`define PV_REG_PCR_CTRL_27_CLEAR_LOW (1) +`define PV_REG_PCR_CTRL_27_CLEAR_MASK (32'h2) +`define PV_REG_PCR_CTRL_27_RSVD0_LOW (2) +`define PV_REG_PCR_CTRL_27_RSVD0_MASK (32'h4) +`define PV_REG_PCR_CTRL_27_RSVD1_LOW (3) +`define PV_REG_PCR_CTRL_27_RSVD1_MASK (32'hf8) +`endif +`ifndef PV_REG_PCR_CTRL_28 +`define PV_REG_PCR_CTRL_28 (32'h70) +`define PV_REG_PCR_CTRL_28_LOCK_LOW (0) +`define PV_REG_PCR_CTRL_28_LOCK_MASK (32'h1) +`define PV_REG_PCR_CTRL_28_CLEAR_LOW (1) +`define PV_REG_PCR_CTRL_28_CLEAR_MASK (32'h2) +`define PV_REG_PCR_CTRL_28_RSVD0_LOW (2) +`define PV_REG_PCR_CTRL_28_RSVD0_MASK (32'h4) +`define PV_REG_PCR_CTRL_28_RSVD1_LOW (3) +`define PV_REG_PCR_CTRL_28_RSVD1_MASK (32'hf8) +`endif +`ifndef PV_REG_PCR_CTRL_29 +`define PV_REG_PCR_CTRL_29 (32'h74) +`define PV_REG_PCR_CTRL_29_LOCK_LOW (0) +`define PV_REG_PCR_CTRL_29_LOCK_MASK (32'h1) +`define PV_REG_PCR_CTRL_29_CLEAR_LOW (1) +`define PV_REG_PCR_CTRL_29_CLEAR_MASK (32'h2) +`define PV_REG_PCR_CTRL_29_RSVD0_LOW (2) +`define PV_REG_PCR_CTRL_29_RSVD0_MASK (32'h4) +`define PV_REG_PCR_CTRL_29_RSVD1_LOW (3) +`define PV_REG_PCR_CTRL_29_RSVD1_MASK (32'hf8) +`endif +`ifndef PV_REG_PCR_CTRL_30 +`define PV_REG_PCR_CTRL_30 (32'h78) +`define PV_REG_PCR_CTRL_30_LOCK_LOW (0) +`define PV_REG_PCR_CTRL_30_LOCK_MASK (32'h1) +`define PV_REG_PCR_CTRL_30_CLEAR_LOW (1) +`define PV_REG_PCR_CTRL_30_CLEAR_MASK (32'h2) +`define PV_REG_PCR_CTRL_30_RSVD0_LOW (2) +`define PV_REG_PCR_CTRL_30_RSVD0_MASK (32'h4) +`define PV_REG_PCR_CTRL_30_RSVD1_LOW (3) +`define PV_REG_PCR_CTRL_30_RSVD1_MASK (32'hf8) +`endif +`ifndef PV_REG_PCR_CTRL_31 +`define PV_REG_PCR_CTRL_31 (32'h7c) +`define PV_REG_PCR_CTRL_31_LOCK_LOW (0) +`define PV_REG_PCR_CTRL_31_LOCK_MASK (32'h1) +`define PV_REG_PCR_CTRL_31_CLEAR_LOW (1) +`define PV_REG_PCR_CTRL_31_CLEAR_MASK (32'h2) +`define PV_REG_PCR_CTRL_31_RSVD0_LOW (2) +`define PV_REG_PCR_CTRL_31_RSVD0_MASK (32'h4) +`define PV_REG_PCR_CTRL_31_RSVD1_LOW (3) +`define PV_REG_PCR_CTRL_31_RSVD1_MASK (32'hf8) +`endif +`ifndef PV_REG_PCR_ENTRY_0_0 +`define PV_REG_PCR_ENTRY_0_0 (32'h600) +`endif +`ifndef PV_REG_PCR_ENTRY_0_1 +`define PV_REG_PCR_ENTRY_0_1 (32'h604) +`endif +`ifndef PV_REG_PCR_ENTRY_0_2 +`define PV_REG_PCR_ENTRY_0_2 (32'h608) +`endif +`ifndef PV_REG_PCR_ENTRY_0_3 +`define PV_REG_PCR_ENTRY_0_3 (32'h60c) +`endif +`ifndef PV_REG_PCR_ENTRY_0_4 +`define PV_REG_PCR_ENTRY_0_4 (32'h610) +`endif +`ifndef PV_REG_PCR_ENTRY_0_5 +`define PV_REG_PCR_ENTRY_0_5 (32'h614) +`endif +`ifndef PV_REG_PCR_ENTRY_0_6 +`define PV_REG_PCR_ENTRY_0_6 (32'h618) +`endif +`ifndef PV_REG_PCR_ENTRY_0_7 +`define PV_REG_PCR_ENTRY_0_7 (32'h61c) +`endif +`ifndef PV_REG_PCR_ENTRY_0_8 +`define PV_REG_PCR_ENTRY_0_8 (32'h620) +`endif +`ifndef PV_REG_PCR_ENTRY_0_9 +`define PV_REG_PCR_ENTRY_0_9 (32'h624) +`endif +`ifndef PV_REG_PCR_ENTRY_0_10 +`define PV_REG_PCR_ENTRY_0_10 (32'h628) +`endif +`ifndef PV_REG_PCR_ENTRY_0_11 +`define PV_REG_PCR_ENTRY_0_11 (32'h62c) +`endif +`ifndef PV_REG_PCR_ENTRY_1_0 +`define PV_REG_PCR_ENTRY_1_0 (32'h630) +`endif +`ifndef PV_REG_PCR_ENTRY_1_1 +`define PV_REG_PCR_ENTRY_1_1 (32'h634) +`endif +`ifndef PV_REG_PCR_ENTRY_1_2 +`define PV_REG_PCR_ENTRY_1_2 (32'h638) +`endif +`ifndef PV_REG_PCR_ENTRY_1_3 +`define PV_REG_PCR_ENTRY_1_3 (32'h63c) +`endif +`ifndef PV_REG_PCR_ENTRY_1_4 +`define PV_REG_PCR_ENTRY_1_4 (32'h640) +`endif +`ifndef PV_REG_PCR_ENTRY_1_5 +`define PV_REG_PCR_ENTRY_1_5 (32'h644) +`endif +`ifndef PV_REG_PCR_ENTRY_1_6 +`define PV_REG_PCR_ENTRY_1_6 (32'h648) +`endif +`ifndef PV_REG_PCR_ENTRY_1_7 +`define PV_REG_PCR_ENTRY_1_7 (32'h64c) +`endif +`ifndef PV_REG_PCR_ENTRY_1_8 +`define PV_REG_PCR_ENTRY_1_8 (32'h650) +`endif +`ifndef PV_REG_PCR_ENTRY_1_9 +`define PV_REG_PCR_ENTRY_1_9 (32'h654) +`endif +`ifndef PV_REG_PCR_ENTRY_1_10 +`define PV_REG_PCR_ENTRY_1_10 (32'h658) +`endif +`ifndef PV_REG_PCR_ENTRY_1_11 +`define PV_REG_PCR_ENTRY_1_11 (32'h65c) +`endif +`ifndef PV_REG_PCR_ENTRY_2_0 +`define PV_REG_PCR_ENTRY_2_0 (32'h660) +`endif +`ifndef PV_REG_PCR_ENTRY_2_1 +`define PV_REG_PCR_ENTRY_2_1 (32'h664) +`endif +`ifndef PV_REG_PCR_ENTRY_2_2 +`define PV_REG_PCR_ENTRY_2_2 (32'h668) +`endif +`ifndef PV_REG_PCR_ENTRY_2_3 +`define PV_REG_PCR_ENTRY_2_3 (32'h66c) +`endif +`ifndef PV_REG_PCR_ENTRY_2_4 +`define PV_REG_PCR_ENTRY_2_4 (32'h670) +`endif +`ifndef PV_REG_PCR_ENTRY_2_5 +`define PV_REG_PCR_ENTRY_2_5 (32'h674) +`endif +`ifndef PV_REG_PCR_ENTRY_2_6 +`define PV_REG_PCR_ENTRY_2_6 (32'h678) +`endif +`ifndef PV_REG_PCR_ENTRY_2_7 +`define PV_REG_PCR_ENTRY_2_7 (32'h67c) +`endif +`ifndef PV_REG_PCR_ENTRY_2_8 +`define PV_REG_PCR_ENTRY_2_8 (32'h680) +`endif +`ifndef PV_REG_PCR_ENTRY_2_9 +`define PV_REG_PCR_ENTRY_2_9 (32'h684) +`endif +`ifndef PV_REG_PCR_ENTRY_2_10 +`define PV_REG_PCR_ENTRY_2_10 (32'h688) +`endif +`ifndef PV_REG_PCR_ENTRY_2_11 +`define PV_REG_PCR_ENTRY_2_11 (32'h68c) +`endif +`ifndef PV_REG_PCR_ENTRY_3_0 +`define PV_REG_PCR_ENTRY_3_0 (32'h690) +`endif +`ifndef PV_REG_PCR_ENTRY_3_1 +`define PV_REG_PCR_ENTRY_3_1 (32'h694) +`endif +`ifndef PV_REG_PCR_ENTRY_3_2 +`define PV_REG_PCR_ENTRY_3_2 (32'h698) +`endif +`ifndef PV_REG_PCR_ENTRY_3_3 +`define PV_REG_PCR_ENTRY_3_3 (32'h69c) +`endif +`ifndef PV_REG_PCR_ENTRY_3_4 +`define PV_REG_PCR_ENTRY_3_4 (32'h6a0) +`endif +`ifndef PV_REG_PCR_ENTRY_3_5 +`define PV_REG_PCR_ENTRY_3_5 (32'h6a4) +`endif +`ifndef PV_REG_PCR_ENTRY_3_6 +`define PV_REG_PCR_ENTRY_3_6 (32'h6a8) +`endif +`ifndef PV_REG_PCR_ENTRY_3_7 +`define PV_REG_PCR_ENTRY_3_7 (32'h6ac) +`endif +`ifndef PV_REG_PCR_ENTRY_3_8 +`define PV_REG_PCR_ENTRY_3_8 (32'h6b0) +`endif +`ifndef PV_REG_PCR_ENTRY_3_9 +`define PV_REG_PCR_ENTRY_3_9 (32'h6b4) +`endif +`ifndef PV_REG_PCR_ENTRY_3_10 +`define PV_REG_PCR_ENTRY_3_10 (32'h6b8) +`endif +`ifndef PV_REG_PCR_ENTRY_3_11 +`define PV_REG_PCR_ENTRY_3_11 (32'h6bc) +`endif +`ifndef PV_REG_PCR_ENTRY_4_0 +`define PV_REG_PCR_ENTRY_4_0 (32'h6c0) +`endif +`ifndef PV_REG_PCR_ENTRY_4_1 +`define PV_REG_PCR_ENTRY_4_1 (32'h6c4) +`endif +`ifndef PV_REG_PCR_ENTRY_4_2 +`define PV_REG_PCR_ENTRY_4_2 (32'h6c8) +`endif +`ifndef PV_REG_PCR_ENTRY_4_3 +`define PV_REG_PCR_ENTRY_4_3 (32'h6cc) +`endif +`ifndef PV_REG_PCR_ENTRY_4_4 +`define PV_REG_PCR_ENTRY_4_4 (32'h6d0) +`endif +`ifndef PV_REG_PCR_ENTRY_4_5 +`define PV_REG_PCR_ENTRY_4_5 (32'h6d4) +`endif +`ifndef PV_REG_PCR_ENTRY_4_6 +`define PV_REG_PCR_ENTRY_4_6 (32'h6d8) +`endif +`ifndef PV_REG_PCR_ENTRY_4_7 +`define PV_REG_PCR_ENTRY_4_7 (32'h6dc) +`endif +`ifndef PV_REG_PCR_ENTRY_4_8 +`define PV_REG_PCR_ENTRY_4_8 (32'h6e0) +`endif +`ifndef PV_REG_PCR_ENTRY_4_9 +`define PV_REG_PCR_ENTRY_4_9 (32'h6e4) +`endif +`ifndef PV_REG_PCR_ENTRY_4_10 +`define PV_REG_PCR_ENTRY_4_10 (32'h6e8) +`endif +`ifndef PV_REG_PCR_ENTRY_4_11 +`define PV_REG_PCR_ENTRY_4_11 (32'h6ec) +`endif +`ifndef PV_REG_PCR_ENTRY_5_0 +`define PV_REG_PCR_ENTRY_5_0 (32'h6f0) +`endif +`ifndef PV_REG_PCR_ENTRY_5_1 +`define PV_REG_PCR_ENTRY_5_1 (32'h6f4) +`endif +`ifndef PV_REG_PCR_ENTRY_5_2 +`define PV_REG_PCR_ENTRY_5_2 (32'h6f8) +`endif +`ifndef PV_REG_PCR_ENTRY_5_3 +`define PV_REG_PCR_ENTRY_5_3 (32'h6fc) +`endif +`ifndef PV_REG_PCR_ENTRY_5_4 +`define PV_REG_PCR_ENTRY_5_4 (32'h700) +`endif +`ifndef PV_REG_PCR_ENTRY_5_5 +`define PV_REG_PCR_ENTRY_5_5 (32'h704) +`endif +`ifndef PV_REG_PCR_ENTRY_5_6 +`define PV_REG_PCR_ENTRY_5_6 (32'h708) +`endif +`ifndef PV_REG_PCR_ENTRY_5_7 +`define PV_REG_PCR_ENTRY_5_7 (32'h70c) +`endif +`ifndef PV_REG_PCR_ENTRY_5_8 +`define PV_REG_PCR_ENTRY_5_8 (32'h710) +`endif +`ifndef PV_REG_PCR_ENTRY_5_9 +`define PV_REG_PCR_ENTRY_5_9 (32'h714) +`endif +`ifndef PV_REG_PCR_ENTRY_5_10 +`define PV_REG_PCR_ENTRY_5_10 (32'h718) +`endif +`ifndef PV_REG_PCR_ENTRY_5_11 +`define PV_REG_PCR_ENTRY_5_11 (32'h71c) +`endif +`ifndef PV_REG_PCR_ENTRY_6_0 +`define PV_REG_PCR_ENTRY_6_0 (32'h720) +`endif +`ifndef PV_REG_PCR_ENTRY_6_1 +`define PV_REG_PCR_ENTRY_6_1 (32'h724) +`endif +`ifndef PV_REG_PCR_ENTRY_6_2 +`define PV_REG_PCR_ENTRY_6_2 (32'h728) +`endif +`ifndef PV_REG_PCR_ENTRY_6_3 +`define PV_REG_PCR_ENTRY_6_3 (32'h72c) +`endif +`ifndef PV_REG_PCR_ENTRY_6_4 +`define PV_REG_PCR_ENTRY_6_4 (32'h730) +`endif +`ifndef PV_REG_PCR_ENTRY_6_5 +`define PV_REG_PCR_ENTRY_6_5 (32'h734) +`endif +`ifndef PV_REG_PCR_ENTRY_6_6 +`define PV_REG_PCR_ENTRY_6_6 (32'h738) +`endif +`ifndef PV_REG_PCR_ENTRY_6_7 +`define PV_REG_PCR_ENTRY_6_7 (32'h73c) +`endif +`ifndef PV_REG_PCR_ENTRY_6_8 +`define PV_REG_PCR_ENTRY_6_8 (32'h740) +`endif +`ifndef PV_REG_PCR_ENTRY_6_9 +`define PV_REG_PCR_ENTRY_6_9 (32'h744) +`endif +`ifndef PV_REG_PCR_ENTRY_6_10 +`define PV_REG_PCR_ENTRY_6_10 (32'h748) +`endif +`ifndef PV_REG_PCR_ENTRY_6_11 +`define PV_REG_PCR_ENTRY_6_11 (32'h74c) +`endif +`ifndef PV_REG_PCR_ENTRY_7_0 +`define PV_REG_PCR_ENTRY_7_0 (32'h750) +`endif +`ifndef PV_REG_PCR_ENTRY_7_1 +`define PV_REG_PCR_ENTRY_7_1 (32'h754) +`endif +`ifndef PV_REG_PCR_ENTRY_7_2 +`define PV_REG_PCR_ENTRY_7_2 (32'h758) +`endif +`ifndef PV_REG_PCR_ENTRY_7_3 +`define PV_REG_PCR_ENTRY_7_3 (32'h75c) +`endif +`ifndef PV_REG_PCR_ENTRY_7_4 +`define PV_REG_PCR_ENTRY_7_4 (32'h760) +`endif +`ifndef PV_REG_PCR_ENTRY_7_5 +`define PV_REG_PCR_ENTRY_7_5 (32'h764) +`endif +`ifndef PV_REG_PCR_ENTRY_7_6 +`define PV_REG_PCR_ENTRY_7_6 (32'h768) +`endif +`ifndef PV_REG_PCR_ENTRY_7_7 +`define PV_REG_PCR_ENTRY_7_7 (32'h76c) +`endif +`ifndef PV_REG_PCR_ENTRY_7_8 +`define PV_REG_PCR_ENTRY_7_8 (32'h770) +`endif +`ifndef PV_REG_PCR_ENTRY_7_9 +`define PV_REG_PCR_ENTRY_7_9 (32'h774) +`endif +`ifndef PV_REG_PCR_ENTRY_7_10 +`define PV_REG_PCR_ENTRY_7_10 (32'h778) +`endif +`ifndef PV_REG_PCR_ENTRY_7_11 +`define PV_REG_PCR_ENTRY_7_11 (32'h77c) +`endif +`ifndef PV_REG_PCR_ENTRY_8_0 +`define PV_REG_PCR_ENTRY_8_0 (32'h780) +`endif +`ifndef PV_REG_PCR_ENTRY_8_1 +`define PV_REG_PCR_ENTRY_8_1 (32'h784) +`endif +`ifndef PV_REG_PCR_ENTRY_8_2 +`define PV_REG_PCR_ENTRY_8_2 (32'h788) +`endif +`ifndef PV_REG_PCR_ENTRY_8_3 +`define PV_REG_PCR_ENTRY_8_3 (32'h78c) +`endif +`ifndef PV_REG_PCR_ENTRY_8_4 +`define PV_REG_PCR_ENTRY_8_4 (32'h790) +`endif +`ifndef PV_REG_PCR_ENTRY_8_5 +`define PV_REG_PCR_ENTRY_8_5 (32'h794) +`endif +`ifndef PV_REG_PCR_ENTRY_8_6 +`define PV_REG_PCR_ENTRY_8_6 (32'h798) +`endif +`ifndef PV_REG_PCR_ENTRY_8_7 +`define PV_REG_PCR_ENTRY_8_7 (32'h79c) +`endif +`ifndef PV_REG_PCR_ENTRY_8_8 +`define PV_REG_PCR_ENTRY_8_8 (32'h7a0) +`endif +`ifndef PV_REG_PCR_ENTRY_8_9 +`define PV_REG_PCR_ENTRY_8_9 (32'h7a4) +`endif +`ifndef PV_REG_PCR_ENTRY_8_10 +`define PV_REG_PCR_ENTRY_8_10 (32'h7a8) +`endif +`ifndef PV_REG_PCR_ENTRY_8_11 +`define PV_REG_PCR_ENTRY_8_11 (32'h7ac) +`endif +`ifndef PV_REG_PCR_ENTRY_9_0 +`define PV_REG_PCR_ENTRY_9_0 (32'h7b0) +`endif +`ifndef PV_REG_PCR_ENTRY_9_1 +`define PV_REG_PCR_ENTRY_9_1 (32'h7b4) +`endif +`ifndef PV_REG_PCR_ENTRY_9_2 +`define PV_REG_PCR_ENTRY_9_2 (32'h7b8) +`endif +`ifndef PV_REG_PCR_ENTRY_9_3 +`define PV_REG_PCR_ENTRY_9_3 (32'h7bc) +`endif +`ifndef PV_REG_PCR_ENTRY_9_4 +`define PV_REG_PCR_ENTRY_9_4 (32'h7c0) +`endif +`ifndef PV_REG_PCR_ENTRY_9_5 +`define PV_REG_PCR_ENTRY_9_5 (32'h7c4) +`endif +`ifndef PV_REG_PCR_ENTRY_9_6 +`define PV_REG_PCR_ENTRY_9_6 (32'h7c8) +`endif +`ifndef PV_REG_PCR_ENTRY_9_7 +`define PV_REG_PCR_ENTRY_9_7 (32'h7cc) +`endif +`ifndef PV_REG_PCR_ENTRY_9_8 +`define PV_REG_PCR_ENTRY_9_8 (32'h7d0) +`endif +`ifndef PV_REG_PCR_ENTRY_9_9 +`define PV_REG_PCR_ENTRY_9_9 (32'h7d4) +`endif +`ifndef PV_REG_PCR_ENTRY_9_10 +`define PV_REG_PCR_ENTRY_9_10 (32'h7d8) +`endif +`ifndef PV_REG_PCR_ENTRY_9_11 +`define PV_REG_PCR_ENTRY_9_11 (32'h7dc) +`endif +`ifndef PV_REG_PCR_ENTRY_10_0 +`define PV_REG_PCR_ENTRY_10_0 (32'h7e0) +`endif +`ifndef PV_REG_PCR_ENTRY_10_1 +`define PV_REG_PCR_ENTRY_10_1 (32'h7e4) +`endif +`ifndef PV_REG_PCR_ENTRY_10_2 +`define PV_REG_PCR_ENTRY_10_2 (32'h7e8) +`endif +`ifndef PV_REG_PCR_ENTRY_10_3 +`define PV_REG_PCR_ENTRY_10_3 (32'h7ec) +`endif +`ifndef PV_REG_PCR_ENTRY_10_4 +`define PV_REG_PCR_ENTRY_10_4 (32'h7f0) +`endif +`ifndef PV_REG_PCR_ENTRY_10_5 +`define PV_REG_PCR_ENTRY_10_5 (32'h7f4) +`endif +`ifndef PV_REG_PCR_ENTRY_10_6 +`define PV_REG_PCR_ENTRY_10_6 (32'h7f8) +`endif +`ifndef PV_REG_PCR_ENTRY_10_7 +`define PV_REG_PCR_ENTRY_10_7 (32'h7fc) +`endif +`ifndef PV_REG_PCR_ENTRY_10_8 +`define PV_REG_PCR_ENTRY_10_8 (32'h800) +`endif +`ifndef PV_REG_PCR_ENTRY_10_9 +`define PV_REG_PCR_ENTRY_10_9 (32'h804) +`endif +`ifndef PV_REG_PCR_ENTRY_10_10 +`define PV_REG_PCR_ENTRY_10_10 (32'h808) +`endif +`ifndef PV_REG_PCR_ENTRY_10_11 +`define PV_REG_PCR_ENTRY_10_11 (32'h80c) +`endif +`ifndef PV_REG_PCR_ENTRY_11_0 +`define PV_REG_PCR_ENTRY_11_0 (32'h810) +`endif +`ifndef PV_REG_PCR_ENTRY_11_1 +`define PV_REG_PCR_ENTRY_11_1 (32'h814) +`endif +`ifndef PV_REG_PCR_ENTRY_11_2 +`define PV_REG_PCR_ENTRY_11_2 (32'h818) +`endif +`ifndef PV_REG_PCR_ENTRY_11_3 +`define PV_REG_PCR_ENTRY_11_3 (32'h81c) +`endif +`ifndef PV_REG_PCR_ENTRY_11_4 +`define PV_REG_PCR_ENTRY_11_4 (32'h820) +`endif +`ifndef PV_REG_PCR_ENTRY_11_5 +`define PV_REG_PCR_ENTRY_11_5 (32'h824) +`endif +`ifndef PV_REG_PCR_ENTRY_11_6 +`define PV_REG_PCR_ENTRY_11_6 (32'h828) +`endif +`ifndef PV_REG_PCR_ENTRY_11_7 +`define PV_REG_PCR_ENTRY_11_7 (32'h82c) +`endif +`ifndef PV_REG_PCR_ENTRY_11_8 +`define PV_REG_PCR_ENTRY_11_8 (32'h830) +`endif +`ifndef PV_REG_PCR_ENTRY_11_9 +`define PV_REG_PCR_ENTRY_11_9 (32'h834) +`endif +`ifndef PV_REG_PCR_ENTRY_11_10 +`define PV_REG_PCR_ENTRY_11_10 (32'h838) +`endif +`ifndef PV_REG_PCR_ENTRY_11_11 +`define PV_REG_PCR_ENTRY_11_11 (32'h83c) +`endif +`ifndef PV_REG_PCR_ENTRY_12_0 +`define PV_REG_PCR_ENTRY_12_0 (32'h840) +`endif +`ifndef PV_REG_PCR_ENTRY_12_1 +`define PV_REG_PCR_ENTRY_12_1 (32'h844) +`endif +`ifndef PV_REG_PCR_ENTRY_12_2 +`define PV_REG_PCR_ENTRY_12_2 (32'h848) +`endif +`ifndef PV_REG_PCR_ENTRY_12_3 +`define PV_REG_PCR_ENTRY_12_3 (32'h84c) +`endif +`ifndef PV_REG_PCR_ENTRY_12_4 +`define PV_REG_PCR_ENTRY_12_4 (32'h850) +`endif +`ifndef PV_REG_PCR_ENTRY_12_5 +`define PV_REG_PCR_ENTRY_12_5 (32'h854) +`endif +`ifndef PV_REG_PCR_ENTRY_12_6 +`define PV_REG_PCR_ENTRY_12_6 (32'h858) +`endif +`ifndef PV_REG_PCR_ENTRY_12_7 +`define PV_REG_PCR_ENTRY_12_7 (32'h85c) +`endif +`ifndef PV_REG_PCR_ENTRY_12_8 +`define PV_REG_PCR_ENTRY_12_8 (32'h860) +`endif +`ifndef PV_REG_PCR_ENTRY_12_9 +`define PV_REG_PCR_ENTRY_12_9 (32'h864) +`endif +`ifndef PV_REG_PCR_ENTRY_12_10 +`define PV_REG_PCR_ENTRY_12_10 (32'h868) +`endif +`ifndef PV_REG_PCR_ENTRY_12_11 +`define PV_REG_PCR_ENTRY_12_11 (32'h86c) +`endif +`ifndef PV_REG_PCR_ENTRY_13_0 +`define PV_REG_PCR_ENTRY_13_0 (32'h870) +`endif +`ifndef PV_REG_PCR_ENTRY_13_1 +`define PV_REG_PCR_ENTRY_13_1 (32'h874) +`endif +`ifndef PV_REG_PCR_ENTRY_13_2 +`define PV_REG_PCR_ENTRY_13_2 (32'h878) +`endif +`ifndef PV_REG_PCR_ENTRY_13_3 +`define PV_REG_PCR_ENTRY_13_3 (32'h87c) +`endif +`ifndef PV_REG_PCR_ENTRY_13_4 +`define PV_REG_PCR_ENTRY_13_4 (32'h880) +`endif +`ifndef PV_REG_PCR_ENTRY_13_5 +`define PV_REG_PCR_ENTRY_13_5 (32'h884) +`endif +`ifndef PV_REG_PCR_ENTRY_13_6 +`define PV_REG_PCR_ENTRY_13_6 (32'h888) +`endif +`ifndef PV_REG_PCR_ENTRY_13_7 +`define PV_REG_PCR_ENTRY_13_7 (32'h88c) +`endif +`ifndef PV_REG_PCR_ENTRY_13_8 +`define PV_REG_PCR_ENTRY_13_8 (32'h890) +`endif +`ifndef PV_REG_PCR_ENTRY_13_9 +`define PV_REG_PCR_ENTRY_13_9 (32'h894) +`endif +`ifndef PV_REG_PCR_ENTRY_13_10 +`define PV_REG_PCR_ENTRY_13_10 (32'h898) +`endif +`ifndef PV_REG_PCR_ENTRY_13_11 +`define PV_REG_PCR_ENTRY_13_11 (32'h89c) +`endif +`ifndef PV_REG_PCR_ENTRY_14_0 +`define PV_REG_PCR_ENTRY_14_0 (32'h8a0) +`endif +`ifndef PV_REG_PCR_ENTRY_14_1 +`define PV_REG_PCR_ENTRY_14_1 (32'h8a4) +`endif +`ifndef PV_REG_PCR_ENTRY_14_2 +`define PV_REG_PCR_ENTRY_14_2 (32'h8a8) +`endif +`ifndef PV_REG_PCR_ENTRY_14_3 +`define PV_REG_PCR_ENTRY_14_3 (32'h8ac) +`endif +`ifndef PV_REG_PCR_ENTRY_14_4 +`define PV_REG_PCR_ENTRY_14_4 (32'h8b0) +`endif +`ifndef PV_REG_PCR_ENTRY_14_5 +`define PV_REG_PCR_ENTRY_14_5 (32'h8b4) +`endif +`ifndef PV_REG_PCR_ENTRY_14_6 +`define PV_REG_PCR_ENTRY_14_6 (32'h8b8) +`endif +`ifndef PV_REG_PCR_ENTRY_14_7 +`define PV_REG_PCR_ENTRY_14_7 (32'h8bc) +`endif +`ifndef PV_REG_PCR_ENTRY_14_8 +`define PV_REG_PCR_ENTRY_14_8 (32'h8c0) +`endif +`ifndef PV_REG_PCR_ENTRY_14_9 +`define PV_REG_PCR_ENTRY_14_9 (32'h8c4) +`endif +`ifndef PV_REG_PCR_ENTRY_14_10 +`define PV_REG_PCR_ENTRY_14_10 (32'h8c8) +`endif +`ifndef PV_REG_PCR_ENTRY_14_11 +`define PV_REG_PCR_ENTRY_14_11 (32'h8cc) +`endif +`ifndef PV_REG_PCR_ENTRY_15_0 +`define PV_REG_PCR_ENTRY_15_0 (32'h8d0) +`endif +`ifndef PV_REG_PCR_ENTRY_15_1 +`define PV_REG_PCR_ENTRY_15_1 (32'h8d4) +`endif +`ifndef PV_REG_PCR_ENTRY_15_2 +`define PV_REG_PCR_ENTRY_15_2 (32'h8d8) +`endif +`ifndef PV_REG_PCR_ENTRY_15_3 +`define PV_REG_PCR_ENTRY_15_3 (32'h8dc) +`endif +`ifndef PV_REG_PCR_ENTRY_15_4 +`define PV_REG_PCR_ENTRY_15_4 (32'h8e0) +`endif +`ifndef PV_REG_PCR_ENTRY_15_5 +`define PV_REG_PCR_ENTRY_15_5 (32'h8e4) +`endif +`ifndef PV_REG_PCR_ENTRY_15_6 +`define PV_REG_PCR_ENTRY_15_6 (32'h8e8) +`endif +`ifndef PV_REG_PCR_ENTRY_15_7 +`define PV_REG_PCR_ENTRY_15_7 (32'h8ec) +`endif +`ifndef PV_REG_PCR_ENTRY_15_8 +`define PV_REG_PCR_ENTRY_15_8 (32'h8f0) +`endif +`ifndef PV_REG_PCR_ENTRY_15_9 +`define PV_REG_PCR_ENTRY_15_9 (32'h8f4) +`endif +`ifndef PV_REG_PCR_ENTRY_15_10 +`define PV_REG_PCR_ENTRY_15_10 (32'h8f8) +`endif +`ifndef PV_REG_PCR_ENTRY_15_11 +`define PV_REG_PCR_ENTRY_15_11 (32'h8fc) +`endif +`ifndef PV_REG_PCR_ENTRY_16_0 +`define PV_REG_PCR_ENTRY_16_0 (32'h900) +`endif +`ifndef PV_REG_PCR_ENTRY_16_1 +`define PV_REG_PCR_ENTRY_16_1 (32'h904) +`endif +`ifndef PV_REG_PCR_ENTRY_16_2 +`define PV_REG_PCR_ENTRY_16_2 (32'h908) +`endif +`ifndef PV_REG_PCR_ENTRY_16_3 +`define PV_REG_PCR_ENTRY_16_3 (32'h90c) +`endif +`ifndef PV_REG_PCR_ENTRY_16_4 +`define PV_REG_PCR_ENTRY_16_4 (32'h910) +`endif +`ifndef PV_REG_PCR_ENTRY_16_5 +`define PV_REG_PCR_ENTRY_16_5 (32'h914) +`endif +`ifndef PV_REG_PCR_ENTRY_16_6 +`define PV_REG_PCR_ENTRY_16_6 (32'h918) +`endif +`ifndef PV_REG_PCR_ENTRY_16_7 +`define PV_REG_PCR_ENTRY_16_7 (32'h91c) +`endif +`ifndef PV_REG_PCR_ENTRY_16_8 +`define PV_REG_PCR_ENTRY_16_8 (32'h920) +`endif +`ifndef PV_REG_PCR_ENTRY_16_9 +`define PV_REG_PCR_ENTRY_16_9 (32'h924) +`endif +`ifndef PV_REG_PCR_ENTRY_16_10 +`define PV_REG_PCR_ENTRY_16_10 (32'h928) +`endif +`ifndef PV_REG_PCR_ENTRY_16_11 +`define PV_REG_PCR_ENTRY_16_11 (32'h92c) +`endif +`ifndef PV_REG_PCR_ENTRY_17_0 +`define PV_REG_PCR_ENTRY_17_0 (32'h930) +`endif +`ifndef PV_REG_PCR_ENTRY_17_1 +`define PV_REG_PCR_ENTRY_17_1 (32'h934) +`endif +`ifndef PV_REG_PCR_ENTRY_17_2 +`define PV_REG_PCR_ENTRY_17_2 (32'h938) +`endif +`ifndef PV_REG_PCR_ENTRY_17_3 +`define PV_REG_PCR_ENTRY_17_3 (32'h93c) +`endif +`ifndef PV_REG_PCR_ENTRY_17_4 +`define PV_REG_PCR_ENTRY_17_4 (32'h940) +`endif +`ifndef PV_REG_PCR_ENTRY_17_5 +`define PV_REG_PCR_ENTRY_17_5 (32'h944) +`endif +`ifndef PV_REG_PCR_ENTRY_17_6 +`define PV_REG_PCR_ENTRY_17_6 (32'h948) +`endif +`ifndef PV_REG_PCR_ENTRY_17_7 +`define PV_REG_PCR_ENTRY_17_7 (32'h94c) +`endif +`ifndef PV_REG_PCR_ENTRY_17_8 +`define PV_REG_PCR_ENTRY_17_8 (32'h950) +`endif +`ifndef PV_REG_PCR_ENTRY_17_9 +`define PV_REG_PCR_ENTRY_17_9 (32'h954) +`endif +`ifndef PV_REG_PCR_ENTRY_17_10 +`define PV_REG_PCR_ENTRY_17_10 (32'h958) +`endif +`ifndef PV_REG_PCR_ENTRY_17_11 +`define PV_REG_PCR_ENTRY_17_11 (32'h95c) +`endif +`ifndef PV_REG_PCR_ENTRY_18_0 +`define PV_REG_PCR_ENTRY_18_0 (32'h960) +`endif +`ifndef PV_REG_PCR_ENTRY_18_1 +`define PV_REG_PCR_ENTRY_18_1 (32'h964) +`endif +`ifndef PV_REG_PCR_ENTRY_18_2 +`define PV_REG_PCR_ENTRY_18_2 (32'h968) +`endif +`ifndef PV_REG_PCR_ENTRY_18_3 +`define PV_REG_PCR_ENTRY_18_3 (32'h96c) +`endif +`ifndef PV_REG_PCR_ENTRY_18_4 +`define PV_REG_PCR_ENTRY_18_4 (32'h970) +`endif +`ifndef PV_REG_PCR_ENTRY_18_5 +`define PV_REG_PCR_ENTRY_18_5 (32'h974) +`endif +`ifndef PV_REG_PCR_ENTRY_18_6 +`define PV_REG_PCR_ENTRY_18_6 (32'h978) +`endif +`ifndef PV_REG_PCR_ENTRY_18_7 +`define PV_REG_PCR_ENTRY_18_7 (32'h97c) +`endif +`ifndef PV_REG_PCR_ENTRY_18_8 +`define PV_REG_PCR_ENTRY_18_8 (32'h980) +`endif +`ifndef PV_REG_PCR_ENTRY_18_9 +`define PV_REG_PCR_ENTRY_18_9 (32'h984) +`endif +`ifndef PV_REG_PCR_ENTRY_18_10 +`define PV_REG_PCR_ENTRY_18_10 (32'h988) +`endif +`ifndef PV_REG_PCR_ENTRY_18_11 +`define PV_REG_PCR_ENTRY_18_11 (32'h98c) +`endif +`ifndef PV_REG_PCR_ENTRY_19_0 +`define PV_REG_PCR_ENTRY_19_0 (32'h990) +`endif +`ifndef PV_REG_PCR_ENTRY_19_1 +`define PV_REG_PCR_ENTRY_19_1 (32'h994) +`endif +`ifndef PV_REG_PCR_ENTRY_19_2 +`define PV_REG_PCR_ENTRY_19_2 (32'h998) +`endif +`ifndef PV_REG_PCR_ENTRY_19_3 +`define PV_REG_PCR_ENTRY_19_3 (32'h99c) +`endif +`ifndef PV_REG_PCR_ENTRY_19_4 +`define PV_REG_PCR_ENTRY_19_4 (32'h9a0) +`endif +`ifndef PV_REG_PCR_ENTRY_19_5 +`define PV_REG_PCR_ENTRY_19_5 (32'h9a4) +`endif +`ifndef PV_REG_PCR_ENTRY_19_6 +`define PV_REG_PCR_ENTRY_19_6 (32'h9a8) +`endif +`ifndef PV_REG_PCR_ENTRY_19_7 +`define PV_REG_PCR_ENTRY_19_7 (32'h9ac) +`endif +`ifndef PV_REG_PCR_ENTRY_19_8 +`define PV_REG_PCR_ENTRY_19_8 (32'h9b0) +`endif +`ifndef PV_REG_PCR_ENTRY_19_9 +`define PV_REG_PCR_ENTRY_19_9 (32'h9b4) +`endif +`ifndef PV_REG_PCR_ENTRY_19_10 +`define PV_REG_PCR_ENTRY_19_10 (32'h9b8) +`endif +`ifndef PV_REG_PCR_ENTRY_19_11 +`define PV_REG_PCR_ENTRY_19_11 (32'h9bc) +`endif +`ifndef PV_REG_PCR_ENTRY_20_0 +`define PV_REG_PCR_ENTRY_20_0 (32'h9c0) +`endif +`ifndef PV_REG_PCR_ENTRY_20_1 +`define PV_REG_PCR_ENTRY_20_1 (32'h9c4) +`endif +`ifndef PV_REG_PCR_ENTRY_20_2 +`define PV_REG_PCR_ENTRY_20_2 (32'h9c8) +`endif +`ifndef PV_REG_PCR_ENTRY_20_3 +`define PV_REG_PCR_ENTRY_20_3 (32'h9cc) +`endif +`ifndef PV_REG_PCR_ENTRY_20_4 +`define PV_REG_PCR_ENTRY_20_4 (32'h9d0) +`endif +`ifndef PV_REG_PCR_ENTRY_20_5 +`define PV_REG_PCR_ENTRY_20_5 (32'h9d4) +`endif +`ifndef PV_REG_PCR_ENTRY_20_6 +`define PV_REG_PCR_ENTRY_20_6 (32'h9d8) +`endif +`ifndef PV_REG_PCR_ENTRY_20_7 +`define PV_REG_PCR_ENTRY_20_7 (32'h9dc) +`endif +`ifndef PV_REG_PCR_ENTRY_20_8 +`define PV_REG_PCR_ENTRY_20_8 (32'h9e0) +`endif +`ifndef PV_REG_PCR_ENTRY_20_9 +`define PV_REG_PCR_ENTRY_20_9 (32'h9e4) +`endif +`ifndef PV_REG_PCR_ENTRY_20_10 +`define PV_REG_PCR_ENTRY_20_10 (32'h9e8) +`endif +`ifndef PV_REG_PCR_ENTRY_20_11 +`define PV_REG_PCR_ENTRY_20_11 (32'h9ec) +`endif +`ifndef PV_REG_PCR_ENTRY_21_0 +`define PV_REG_PCR_ENTRY_21_0 (32'h9f0) +`endif +`ifndef PV_REG_PCR_ENTRY_21_1 +`define PV_REG_PCR_ENTRY_21_1 (32'h9f4) +`endif +`ifndef PV_REG_PCR_ENTRY_21_2 +`define PV_REG_PCR_ENTRY_21_2 (32'h9f8) +`endif +`ifndef PV_REG_PCR_ENTRY_21_3 +`define PV_REG_PCR_ENTRY_21_3 (32'h9fc) +`endif +`ifndef PV_REG_PCR_ENTRY_21_4 +`define PV_REG_PCR_ENTRY_21_4 (32'ha00) +`endif +`ifndef PV_REG_PCR_ENTRY_21_5 +`define PV_REG_PCR_ENTRY_21_5 (32'ha04) +`endif +`ifndef PV_REG_PCR_ENTRY_21_6 +`define PV_REG_PCR_ENTRY_21_6 (32'ha08) +`endif +`ifndef PV_REG_PCR_ENTRY_21_7 +`define PV_REG_PCR_ENTRY_21_7 (32'ha0c) +`endif +`ifndef PV_REG_PCR_ENTRY_21_8 +`define PV_REG_PCR_ENTRY_21_8 (32'ha10) +`endif +`ifndef PV_REG_PCR_ENTRY_21_9 +`define PV_REG_PCR_ENTRY_21_9 (32'ha14) +`endif +`ifndef PV_REG_PCR_ENTRY_21_10 +`define PV_REG_PCR_ENTRY_21_10 (32'ha18) +`endif +`ifndef PV_REG_PCR_ENTRY_21_11 +`define PV_REG_PCR_ENTRY_21_11 (32'ha1c) +`endif +`ifndef PV_REG_PCR_ENTRY_22_0 +`define PV_REG_PCR_ENTRY_22_0 (32'ha20) +`endif +`ifndef PV_REG_PCR_ENTRY_22_1 +`define PV_REG_PCR_ENTRY_22_1 (32'ha24) +`endif +`ifndef PV_REG_PCR_ENTRY_22_2 +`define PV_REG_PCR_ENTRY_22_2 (32'ha28) +`endif +`ifndef PV_REG_PCR_ENTRY_22_3 +`define PV_REG_PCR_ENTRY_22_3 (32'ha2c) +`endif +`ifndef PV_REG_PCR_ENTRY_22_4 +`define PV_REG_PCR_ENTRY_22_4 (32'ha30) +`endif +`ifndef PV_REG_PCR_ENTRY_22_5 +`define PV_REG_PCR_ENTRY_22_5 (32'ha34) +`endif +`ifndef PV_REG_PCR_ENTRY_22_6 +`define PV_REG_PCR_ENTRY_22_6 (32'ha38) +`endif +`ifndef PV_REG_PCR_ENTRY_22_7 +`define PV_REG_PCR_ENTRY_22_7 (32'ha3c) +`endif +`ifndef PV_REG_PCR_ENTRY_22_8 +`define PV_REG_PCR_ENTRY_22_8 (32'ha40) +`endif +`ifndef PV_REG_PCR_ENTRY_22_9 +`define PV_REG_PCR_ENTRY_22_9 (32'ha44) +`endif +`ifndef PV_REG_PCR_ENTRY_22_10 +`define PV_REG_PCR_ENTRY_22_10 (32'ha48) +`endif +`ifndef PV_REG_PCR_ENTRY_22_11 +`define PV_REG_PCR_ENTRY_22_11 (32'ha4c) +`endif +`ifndef PV_REG_PCR_ENTRY_23_0 +`define PV_REG_PCR_ENTRY_23_0 (32'ha50) +`endif +`ifndef PV_REG_PCR_ENTRY_23_1 +`define PV_REG_PCR_ENTRY_23_1 (32'ha54) +`endif +`ifndef PV_REG_PCR_ENTRY_23_2 +`define PV_REG_PCR_ENTRY_23_2 (32'ha58) +`endif +`ifndef PV_REG_PCR_ENTRY_23_3 +`define PV_REG_PCR_ENTRY_23_3 (32'ha5c) +`endif +`ifndef PV_REG_PCR_ENTRY_23_4 +`define PV_REG_PCR_ENTRY_23_4 (32'ha60) +`endif +`ifndef PV_REG_PCR_ENTRY_23_5 +`define PV_REG_PCR_ENTRY_23_5 (32'ha64) +`endif +`ifndef PV_REG_PCR_ENTRY_23_6 +`define PV_REG_PCR_ENTRY_23_6 (32'ha68) +`endif +`ifndef PV_REG_PCR_ENTRY_23_7 +`define PV_REG_PCR_ENTRY_23_7 (32'ha6c) +`endif +`ifndef PV_REG_PCR_ENTRY_23_8 +`define PV_REG_PCR_ENTRY_23_8 (32'ha70) +`endif +`ifndef PV_REG_PCR_ENTRY_23_9 +`define PV_REG_PCR_ENTRY_23_9 (32'ha74) +`endif +`ifndef PV_REG_PCR_ENTRY_23_10 +`define PV_REG_PCR_ENTRY_23_10 (32'ha78) +`endif +`ifndef PV_REG_PCR_ENTRY_23_11 +`define PV_REG_PCR_ENTRY_23_11 (32'ha7c) +`endif +`ifndef PV_REG_PCR_ENTRY_24_0 +`define PV_REG_PCR_ENTRY_24_0 (32'ha80) +`endif +`ifndef PV_REG_PCR_ENTRY_24_1 +`define PV_REG_PCR_ENTRY_24_1 (32'ha84) +`endif +`ifndef PV_REG_PCR_ENTRY_24_2 +`define PV_REG_PCR_ENTRY_24_2 (32'ha88) +`endif +`ifndef PV_REG_PCR_ENTRY_24_3 +`define PV_REG_PCR_ENTRY_24_3 (32'ha8c) +`endif +`ifndef PV_REG_PCR_ENTRY_24_4 +`define PV_REG_PCR_ENTRY_24_4 (32'ha90) +`endif +`ifndef PV_REG_PCR_ENTRY_24_5 +`define PV_REG_PCR_ENTRY_24_5 (32'ha94) +`endif +`ifndef PV_REG_PCR_ENTRY_24_6 +`define PV_REG_PCR_ENTRY_24_6 (32'ha98) +`endif +`ifndef PV_REG_PCR_ENTRY_24_7 +`define PV_REG_PCR_ENTRY_24_7 (32'ha9c) +`endif +`ifndef PV_REG_PCR_ENTRY_24_8 +`define PV_REG_PCR_ENTRY_24_8 (32'haa0) +`endif +`ifndef PV_REG_PCR_ENTRY_24_9 +`define PV_REG_PCR_ENTRY_24_9 (32'haa4) +`endif +`ifndef PV_REG_PCR_ENTRY_24_10 +`define PV_REG_PCR_ENTRY_24_10 (32'haa8) +`endif +`ifndef PV_REG_PCR_ENTRY_24_11 +`define PV_REG_PCR_ENTRY_24_11 (32'haac) +`endif +`ifndef PV_REG_PCR_ENTRY_25_0 +`define PV_REG_PCR_ENTRY_25_0 (32'hab0) +`endif +`ifndef PV_REG_PCR_ENTRY_25_1 +`define PV_REG_PCR_ENTRY_25_1 (32'hab4) +`endif +`ifndef PV_REG_PCR_ENTRY_25_2 +`define PV_REG_PCR_ENTRY_25_2 (32'hab8) +`endif +`ifndef PV_REG_PCR_ENTRY_25_3 +`define PV_REG_PCR_ENTRY_25_3 (32'habc) +`endif +`ifndef PV_REG_PCR_ENTRY_25_4 +`define PV_REG_PCR_ENTRY_25_4 (32'hac0) +`endif +`ifndef PV_REG_PCR_ENTRY_25_5 +`define PV_REG_PCR_ENTRY_25_5 (32'hac4) +`endif +`ifndef PV_REG_PCR_ENTRY_25_6 +`define PV_REG_PCR_ENTRY_25_6 (32'hac8) +`endif +`ifndef PV_REG_PCR_ENTRY_25_7 +`define PV_REG_PCR_ENTRY_25_7 (32'hacc) +`endif +`ifndef PV_REG_PCR_ENTRY_25_8 +`define PV_REG_PCR_ENTRY_25_8 (32'had0) +`endif +`ifndef PV_REG_PCR_ENTRY_25_9 +`define PV_REG_PCR_ENTRY_25_9 (32'had4) +`endif +`ifndef PV_REG_PCR_ENTRY_25_10 +`define PV_REG_PCR_ENTRY_25_10 (32'had8) +`endif +`ifndef PV_REG_PCR_ENTRY_25_11 +`define PV_REG_PCR_ENTRY_25_11 (32'hadc) +`endif +`ifndef PV_REG_PCR_ENTRY_26_0 +`define PV_REG_PCR_ENTRY_26_0 (32'hae0) +`endif +`ifndef PV_REG_PCR_ENTRY_26_1 +`define PV_REG_PCR_ENTRY_26_1 (32'hae4) +`endif +`ifndef PV_REG_PCR_ENTRY_26_2 +`define PV_REG_PCR_ENTRY_26_2 (32'hae8) +`endif +`ifndef PV_REG_PCR_ENTRY_26_3 +`define PV_REG_PCR_ENTRY_26_3 (32'haec) +`endif +`ifndef PV_REG_PCR_ENTRY_26_4 +`define PV_REG_PCR_ENTRY_26_4 (32'haf0) +`endif +`ifndef PV_REG_PCR_ENTRY_26_5 +`define PV_REG_PCR_ENTRY_26_5 (32'haf4) +`endif +`ifndef PV_REG_PCR_ENTRY_26_6 +`define PV_REG_PCR_ENTRY_26_6 (32'haf8) +`endif +`ifndef PV_REG_PCR_ENTRY_26_7 +`define PV_REG_PCR_ENTRY_26_7 (32'hafc) +`endif +`ifndef PV_REG_PCR_ENTRY_26_8 +`define PV_REG_PCR_ENTRY_26_8 (32'hb00) +`endif +`ifndef PV_REG_PCR_ENTRY_26_9 +`define PV_REG_PCR_ENTRY_26_9 (32'hb04) +`endif +`ifndef PV_REG_PCR_ENTRY_26_10 +`define PV_REG_PCR_ENTRY_26_10 (32'hb08) +`endif +`ifndef PV_REG_PCR_ENTRY_26_11 +`define PV_REG_PCR_ENTRY_26_11 (32'hb0c) +`endif +`ifndef PV_REG_PCR_ENTRY_27_0 +`define PV_REG_PCR_ENTRY_27_0 (32'hb10) +`endif +`ifndef PV_REG_PCR_ENTRY_27_1 +`define PV_REG_PCR_ENTRY_27_1 (32'hb14) +`endif +`ifndef PV_REG_PCR_ENTRY_27_2 +`define PV_REG_PCR_ENTRY_27_2 (32'hb18) +`endif +`ifndef PV_REG_PCR_ENTRY_27_3 +`define PV_REG_PCR_ENTRY_27_3 (32'hb1c) +`endif +`ifndef PV_REG_PCR_ENTRY_27_4 +`define PV_REG_PCR_ENTRY_27_4 (32'hb20) +`endif +`ifndef PV_REG_PCR_ENTRY_27_5 +`define PV_REG_PCR_ENTRY_27_5 (32'hb24) +`endif +`ifndef PV_REG_PCR_ENTRY_27_6 +`define PV_REG_PCR_ENTRY_27_6 (32'hb28) +`endif +`ifndef PV_REG_PCR_ENTRY_27_7 +`define PV_REG_PCR_ENTRY_27_7 (32'hb2c) +`endif +`ifndef PV_REG_PCR_ENTRY_27_8 +`define PV_REG_PCR_ENTRY_27_8 (32'hb30) +`endif +`ifndef PV_REG_PCR_ENTRY_27_9 +`define PV_REG_PCR_ENTRY_27_9 (32'hb34) +`endif +`ifndef PV_REG_PCR_ENTRY_27_10 +`define PV_REG_PCR_ENTRY_27_10 (32'hb38) +`endif +`ifndef PV_REG_PCR_ENTRY_27_11 +`define PV_REG_PCR_ENTRY_27_11 (32'hb3c) +`endif +`ifndef PV_REG_PCR_ENTRY_28_0 +`define PV_REG_PCR_ENTRY_28_0 (32'hb40) +`endif +`ifndef PV_REG_PCR_ENTRY_28_1 +`define PV_REG_PCR_ENTRY_28_1 (32'hb44) +`endif +`ifndef PV_REG_PCR_ENTRY_28_2 +`define PV_REG_PCR_ENTRY_28_2 (32'hb48) +`endif +`ifndef PV_REG_PCR_ENTRY_28_3 +`define PV_REG_PCR_ENTRY_28_3 (32'hb4c) +`endif +`ifndef PV_REG_PCR_ENTRY_28_4 +`define PV_REG_PCR_ENTRY_28_4 (32'hb50) +`endif +`ifndef PV_REG_PCR_ENTRY_28_5 +`define PV_REG_PCR_ENTRY_28_5 (32'hb54) +`endif +`ifndef PV_REG_PCR_ENTRY_28_6 +`define PV_REG_PCR_ENTRY_28_6 (32'hb58) +`endif +`ifndef PV_REG_PCR_ENTRY_28_7 +`define PV_REG_PCR_ENTRY_28_7 (32'hb5c) +`endif +`ifndef PV_REG_PCR_ENTRY_28_8 +`define PV_REG_PCR_ENTRY_28_8 (32'hb60) +`endif +`ifndef PV_REG_PCR_ENTRY_28_9 +`define PV_REG_PCR_ENTRY_28_9 (32'hb64) +`endif +`ifndef PV_REG_PCR_ENTRY_28_10 +`define PV_REG_PCR_ENTRY_28_10 (32'hb68) +`endif +`ifndef PV_REG_PCR_ENTRY_28_11 +`define PV_REG_PCR_ENTRY_28_11 (32'hb6c) +`endif +`ifndef PV_REG_PCR_ENTRY_29_0 +`define PV_REG_PCR_ENTRY_29_0 (32'hb70) +`endif +`ifndef PV_REG_PCR_ENTRY_29_1 +`define PV_REG_PCR_ENTRY_29_1 (32'hb74) +`endif +`ifndef PV_REG_PCR_ENTRY_29_2 +`define PV_REG_PCR_ENTRY_29_2 (32'hb78) +`endif +`ifndef PV_REG_PCR_ENTRY_29_3 +`define PV_REG_PCR_ENTRY_29_3 (32'hb7c) +`endif +`ifndef PV_REG_PCR_ENTRY_29_4 +`define PV_REG_PCR_ENTRY_29_4 (32'hb80) +`endif +`ifndef PV_REG_PCR_ENTRY_29_5 +`define PV_REG_PCR_ENTRY_29_5 (32'hb84) +`endif +`ifndef PV_REG_PCR_ENTRY_29_6 +`define PV_REG_PCR_ENTRY_29_6 (32'hb88) +`endif +`ifndef PV_REG_PCR_ENTRY_29_7 +`define PV_REG_PCR_ENTRY_29_7 (32'hb8c) +`endif +`ifndef PV_REG_PCR_ENTRY_29_8 +`define PV_REG_PCR_ENTRY_29_8 (32'hb90) +`endif +`ifndef PV_REG_PCR_ENTRY_29_9 +`define PV_REG_PCR_ENTRY_29_9 (32'hb94) +`endif +`ifndef PV_REG_PCR_ENTRY_29_10 +`define PV_REG_PCR_ENTRY_29_10 (32'hb98) +`endif +`ifndef PV_REG_PCR_ENTRY_29_11 +`define PV_REG_PCR_ENTRY_29_11 (32'hb9c) +`endif +`ifndef PV_REG_PCR_ENTRY_30_0 +`define PV_REG_PCR_ENTRY_30_0 (32'hba0) +`endif +`ifndef PV_REG_PCR_ENTRY_30_1 +`define PV_REG_PCR_ENTRY_30_1 (32'hba4) +`endif +`ifndef PV_REG_PCR_ENTRY_30_2 +`define PV_REG_PCR_ENTRY_30_2 (32'hba8) +`endif +`ifndef PV_REG_PCR_ENTRY_30_3 +`define PV_REG_PCR_ENTRY_30_3 (32'hbac) +`endif +`ifndef PV_REG_PCR_ENTRY_30_4 +`define PV_REG_PCR_ENTRY_30_4 (32'hbb0) +`endif +`ifndef PV_REG_PCR_ENTRY_30_5 +`define PV_REG_PCR_ENTRY_30_5 (32'hbb4) +`endif +`ifndef PV_REG_PCR_ENTRY_30_6 +`define PV_REG_PCR_ENTRY_30_6 (32'hbb8) +`endif +`ifndef PV_REG_PCR_ENTRY_30_7 +`define PV_REG_PCR_ENTRY_30_7 (32'hbbc) +`endif +`ifndef PV_REG_PCR_ENTRY_30_8 +`define PV_REG_PCR_ENTRY_30_8 (32'hbc0) +`endif +`ifndef PV_REG_PCR_ENTRY_30_9 +`define PV_REG_PCR_ENTRY_30_9 (32'hbc4) +`endif +`ifndef PV_REG_PCR_ENTRY_30_10 +`define PV_REG_PCR_ENTRY_30_10 (32'hbc8) +`endif +`ifndef PV_REG_PCR_ENTRY_30_11 +`define PV_REG_PCR_ENTRY_30_11 (32'hbcc) +`endif +`ifndef PV_REG_PCR_ENTRY_31_0 +`define PV_REG_PCR_ENTRY_31_0 (32'hbd0) +`endif +`ifndef PV_REG_PCR_ENTRY_31_1 +`define PV_REG_PCR_ENTRY_31_1 (32'hbd4) +`endif +`ifndef PV_REG_PCR_ENTRY_31_2 +`define PV_REG_PCR_ENTRY_31_2 (32'hbd8) +`endif +`ifndef PV_REG_PCR_ENTRY_31_3 +`define PV_REG_PCR_ENTRY_31_3 (32'hbdc) +`endif +`ifndef PV_REG_PCR_ENTRY_31_4 +`define PV_REG_PCR_ENTRY_31_4 (32'hbe0) +`endif +`ifndef PV_REG_PCR_ENTRY_31_5 +`define PV_REG_PCR_ENTRY_31_5 (32'hbe4) +`endif +`ifndef PV_REG_PCR_ENTRY_31_6 +`define PV_REG_PCR_ENTRY_31_6 (32'hbe8) +`endif +`ifndef PV_REG_PCR_ENTRY_31_7 +`define PV_REG_PCR_ENTRY_31_7 (32'hbec) +`endif +`ifndef PV_REG_PCR_ENTRY_31_8 +`define PV_REG_PCR_ENTRY_31_8 (32'hbf0) +`endif +`ifndef PV_REG_PCR_ENTRY_31_9 +`define PV_REG_PCR_ENTRY_31_9 (32'hbf4) +`endif +`ifndef PV_REG_PCR_ENTRY_31_10 +`define PV_REG_PCR_ENTRY_31_10 (32'hbf8) +`endif +`ifndef PV_REG_PCR_ENTRY_31_11 +`define PV_REG_PCR_ENTRY_31_11 (32'hbfc) +`endif +`ifndef DV_REG_STICKYDATAVAULTCTRL_0 +`define DV_REG_STICKYDATAVAULTCTRL_0 (32'h0) +`define DV_REG_STICKYDATAVAULTCTRL_0_LOCK_ENTRY_LOW (0) +`define DV_REG_STICKYDATAVAULTCTRL_0_LOCK_ENTRY_MASK (32'h1) +`endif +`ifndef DV_REG_STICKYDATAVAULTCTRL_1 +`define DV_REG_STICKYDATAVAULTCTRL_1 (32'h4) +`define DV_REG_STICKYDATAVAULTCTRL_1_LOCK_ENTRY_LOW (0) +`define DV_REG_STICKYDATAVAULTCTRL_1_LOCK_ENTRY_MASK (32'h1) +`endif +`ifndef DV_REG_STICKYDATAVAULTCTRL_2 +`define DV_REG_STICKYDATAVAULTCTRL_2 (32'h8) +`define DV_REG_STICKYDATAVAULTCTRL_2_LOCK_ENTRY_LOW (0) +`define DV_REG_STICKYDATAVAULTCTRL_2_LOCK_ENTRY_MASK (32'h1) +`endif +`ifndef DV_REG_STICKYDATAVAULTCTRL_3 +`define DV_REG_STICKYDATAVAULTCTRL_3 (32'hc) +`define DV_REG_STICKYDATAVAULTCTRL_3_LOCK_ENTRY_LOW (0) +`define DV_REG_STICKYDATAVAULTCTRL_3_LOCK_ENTRY_MASK (32'h1) +`endif +`ifndef DV_REG_STICKYDATAVAULTCTRL_4 +`define DV_REG_STICKYDATAVAULTCTRL_4 (32'h10) +`define DV_REG_STICKYDATAVAULTCTRL_4_LOCK_ENTRY_LOW (0) +`define DV_REG_STICKYDATAVAULTCTRL_4_LOCK_ENTRY_MASK (32'h1) +`endif +`ifndef DV_REG_STICKYDATAVAULTCTRL_5 +`define DV_REG_STICKYDATAVAULTCTRL_5 (32'h14) +`define DV_REG_STICKYDATAVAULTCTRL_5_LOCK_ENTRY_LOW (0) +`define DV_REG_STICKYDATAVAULTCTRL_5_LOCK_ENTRY_MASK (32'h1) +`endif +`ifndef DV_REG_STICKYDATAVAULTCTRL_6 +`define DV_REG_STICKYDATAVAULTCTRL_6 (32'h18) +`define DV_REG_STICKYDATAVAULTCTRL_6_LOCK_ENTRY_LOW (0) +`define DV_REG_STICKYDATAVAULTCTRL_6_LOCK_ENTRY_MASK (32'h1) +`endif +`ifndef DV_REG_STICKYDATAVAULTCTRL_7 +`define DV_REG_STICKYDATAVAULTCTRL_7 (32'h1c) +`define DV_REG_STICKYDATAVAULTCTRL_7_LOCK_ENTRY_LOW (0) +`define DV_REG_STICKYDATAVAULTCTRL_7_LOCK_ENTRY_MASK (32'h1) +`endif +`ifndef DV_REG_STICKYDATAVAULTCTRL_8 +`define DV_REG_STICKYDATAVAULTCTRL_8 (32'h20) +`define DV_REG_STICKYDATAVAULTCTRL_8_LOCK_ENTRY_LOW (0) +`define DV_REG_STICKYDATAVAULTCTRL_8_LOCK_ENTRY_MASK (32'h1) +`endif +`ifndef DV_REG_STICKYDATAVAULTCTRL_9 +`define DV_REG_STICKYDATAVAULTCTRL_9 (32'h24) +`define DV_REG_STICKYDATAVAULTCTRL_9_LOCK_ENTRY_LOW (0) +`define DV_REG_STICKYDATAVAULTCTRL_9_LOCK_ENTRY_MASK (32'h1) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_0_0 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_0_0 (32'h28) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_0_1 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_0_1 (32'h2c) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_0_2 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_0_2 (32'h30) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_0_3 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_0_3 (32'h34) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_0_4 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_0_4 (32'h38) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_0_5 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_0_5 (32'h3c) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_0_6 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_0_6 (32'h40) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_0_7 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_0_7 (32'h44) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_0_8 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_0_8 (32'h48) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_0_9 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_0_9 (32'h4c) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_0_10 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_0_10 (32'h50) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_0_11 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_0_11 (32'h54) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_1_0 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_1_0 (32'h58) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_1_1 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_1_1 (32'h5c) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_1_2 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_1_2 (32'h60) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_1_3 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_1_3 (32'h64) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_1_4 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_1_4 (32'h68) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_1_5 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_1_5 (32'h6c) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_1_6 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_1_6 (32'h70) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_1_7 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_1_7 (32'h74) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_1_8 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_1_8 (32'h78) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_1_9 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_1_9 (32'h7c) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_1_10 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_1_10 (32'h80) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_1_11 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_1_11 (32'h84) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_2_0 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_2_0 (32'h88) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_2_1 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_2_1 (32'h8c) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_2_2 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_2_2 (32'h90) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_2_3 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_2_3 (32'h94) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_2_4 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_2_4 (32'h98) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_2_5 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_2_5 (32'h9c) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_2_6 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_2_6 (32'ha0) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_2_7 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_2_7 (32'ha4) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_2_8 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_2_8 (32'ha8) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_2_9 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_2_9 (32'hac) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_2_10 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_2_10 (32'hb0) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_2_11 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_2_11 (32'hb4) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_3_0 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_3_0 (32'hb8) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_3_1 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_3_1 (32'hbc) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_3_2 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_3_2 (32'hc0) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_3_3 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_3_3 (32'hc4) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_3_4 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_3_4 (32'hc8) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_3_5 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_3_5 (32'hcc) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_3_6 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_3_6 (32'hd0) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_3_7 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_3_7 (32'hd4) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_3_8 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_3_8 (32'hd8) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_3_9 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_3_9 (32'hdc) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_3_10 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_3_10 (32'he0) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_3_11 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_3_11 (32'he4) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_4_0 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_4_0 (32'he8) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_4_1 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_4_1 (32'hec) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_4_2 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_4_2 (32'hf0) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_4_3 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_4_3 (32'hf4) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_4_4 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_4_4 (32'hf8) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_4_5 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_4_5 (32'hfc) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_4_6 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_4_6 (32'h100) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_4_7 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_4_7 (32'h104) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_4_8 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_4_8 (32'h108) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_4_9 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_4_9 (32'h10c) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_4_10 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_4_10 (32'h110) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_4_11 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_4_11 (32'h114) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_5_0 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_5_0 (32'h118) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_5_1 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_5_1 (32'h11c) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_5_2 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_5_2 (32'h120) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_5_3 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_5_3 (32'h124) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_5_4 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_5_4 (32'h128) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_5_5 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_5_5 (32'h12c) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_5_6 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_5_6 (32'h130) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_5_7 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_5_7 (32'h134) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_5_8 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_5_8 (32'h138) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_5_9 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_5_9 (32'h13c) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_5_10 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_5_10 (32'h140) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_5_11 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_5_11 (32'h144) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_6_0 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_6_0 (32'h148) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_6_1 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_6_1 (32'h14c) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_6_2 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_6_2 (32'h150) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_6_3 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_6_3 (32'h154) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_6_4 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_6_4 (32'h158) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_6_5 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_6_5 (32'h15c) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_6_6 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_6_6 (32'h160) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_6_7 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_6_7 (32'h164) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_6_8 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_6_8 (32'h168) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_6_9 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_6_9 (32'h16c) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_6_10 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_6_10 (32'h170) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_6_11 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_6_11 (32'h174) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_7_0 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_7_0 (32'h178) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_7_1 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_7_1 (32'h17c) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_7_2 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_7_2 (32'h180) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_7_3 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_7_3 (32'h184) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_7_4 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_7_4 (32'h188) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_7_5 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_7_5 (32'h18c) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_7_6 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_7_6 (32'h190) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_7_7 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_7_7 (32'h194) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_7_8 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_7_8 (32'h198) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_7_9 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_7_9 (32'h19c) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_7_10 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_7_10 (32'h1a0) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_7_11 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_7_11 (32'h1a4) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_8_0 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_8_0 (32'h1a8) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_8_1 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_8_1 (32'h1ac) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_8_2 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_8_2 (32'h1b0) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_8_3 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_8_3 (32'h1b4) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_8_4 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_8_4 (32'h1b8) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_8_5 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_8_5 (32'h1bc) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_8_6 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_8_6 (32'h1c0) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_8_7 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_8_7 (32'h1c4) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_8_8 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_8_8 (32'h1c8) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_8_9 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_8_9 (32'h1cc) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_8_10 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_8_10 (32'h1d0) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_8_11 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_8_11 (32'h1d4) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_9_0 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_9_0 (32'h1d8) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_9_1 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_9_1 (32'h1dc) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_9_2 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_9_2 (32'h1e0) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_9_3 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_9_3 (32'h1e4) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_9_4 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_9_4 (32'h1e8) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_9_5 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_9_5 (32'h1ec) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_9_6 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_9_6 (32'h1f0) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_9_7 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_9_7 (32'h1f4) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_9_8 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_9_8 (32'h1f8) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_9_9 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_9_9 (32'h1fc) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_9_10 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_9_10 (32'h200) +`endif +`ifndef DV_REG_STICKY_DATA_VAULT_ENTRY_9_11 +`define DV_REG_STICKY_DATA_VAULT_ENTRY_9_11 (32'h204) +`endif +`ifndef DV_REG_DATAVAULTCTRL_0 +`define DV_REG_DATAVAULTCTRL_0 (32'h208) +`define DV_REG_DATAVAULTCTRL_0_LOCK_ENTRY_LOW (0) +`define DV_REG_DATAVAULTCTRL_0_LOCK_ENTRY_MASK (32'h1) +`endif +`ifndef DV_REG_DATAVAULTCTRL_1 +`define DV_REG_DATAVAULTCTRL_1 (32'h20c) +`define DV_REG_DATAVAULTCTRL_1_LOCK_ENTRY_LOW (0) +`define DV_REG_DATAVAULTCTRL_1_LOCK_ENTRY_MASK (32'h1) +`endif +`ifndef DV_REG_DATAVAULTCTRL_2 +`define DV_REG_DATAVAULTCTRL_2 (32'h210) +`define DV_REG_DATAVAULTCTRL_2_LOCK_ENTRY_LOW (0) +`define DV_REG_DATAVAULTCTRL_2_LOCK_ENTRY_MASK (32'h1) +`endif +`ifndef DV_REG_DATAVAULTCTRL_3 +`define DV_REG_DATAVAULTCTRL_3 (32'h214) +`define DV_REG_DATAVAULTCTRL_3_LOCK_ENTRY_LOW (0) +`define DV_REG_DATAVAULTCTRL_3_LOCK_ENTRY_MASK (32'h1) +`endif +`ifndef DV_REG_DATAVAULTCTRL_4 +`define DV_REG_DATAVAULTCTRL_4 (32'h218) +`define DV_REG_DATAVAULTCTRL_4_LOCK_ENTRY_LOW (0) +`define DV_REG_DATAVAULTCTRL_4_LOCK_ENTRY_MASK (32'h1) +`endif +`ifndef DV_REG_DATAVAULTCTRL_5 +`define DV_REG_DATAVAULTCTRL_5 (32'h21c) +`define DV_REG_DATAVAULTCTRL_5_LOCK_ENTRY_LOW (0) +`define DV_REG_DATAVAULTCTRL_5_LOCK_ENTRY_MASK (32'h1) +`endif +`ifndef DV_REG_DATAVAULTCTRL_6 +`define DV_REG_DATAVAULTCTRL_6 (32'h220) +`define DV_REG_DATAVAULTCTRL_6_LOCK_ENTRY_LOW (0) +`define DV_REG_DATAVAULTCTRL_6_LOCK_ENTRY_MASK (32'h1) +`endif +`ifndef DV_REG_DATAVAULTCTRL_7 +`define DV_REG_DATAVAULTCTRL_7 (32'h224) +`define DV_REG_DATAVAULTCTRL_7_LOCK_ENTRY_LOW (0) +`define DV_REG_DATAVAULTCTRL_7_LOCK_ENTRY_MASK (32'h1) +`endif +`ifndef DV_REG_DATAVAULTCTRL_8 +`define DV_REG_DATAVAULTCTRL_8 (32'h228) +`define DV_REG_DATAVAULTCTRL_8_LOCK_ENTRY_LOW (0) +`define DV_REG_DATAVAULTCTRL_8_LOCK_ENTRY_MASK (32'h1) +`endif +`ifndef DV_REG_DATAVAULTCTRL_9 +`define DV_REG_DATAVAULTCTRL_9 (32'h22c) +`define DV_REG_DATAVAULTCTRL_9_LOCK_ENTRY_LOW (0) +`define DV_REG_DATAVAULTCTRL_9_LOCK_ENTRY_MASK (32'h1) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_0_0 +`define DV_REG_DATA_VAULT_ENTRY_0_0 (32'h230) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_0_1 +`define DV_REG_DATA_VAULT_ENTRY_0_1 (32'h234) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_0_2 +`define DV_REG_DATA_VAULT_ENTRY_0_2 (32'h238) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_0_3 +`define DV_REG_DATA_VAULT_ENTRY_0_3 (32'h23c) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_0_4 +`define DV_REG_DATA_VAULT_ENTRY_0_4 (32'h240) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_0_5 +`define DV_REG_DATA_VAULT_ENTRY_0_5 (32'h244) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_0_6 +`define DV_REG_DATA_VAULT_ENTRY_0_6 (32'h248) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_0_7 +`define DV_REG_DATA_VAULT_ENTRY_0_7 (32'h24c) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_0_8 +`define DV_REG_DATA_VAULT_ENTRY_0_8 (32'h250) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_0_9 +`define DV_REG_DATA_VAULT_ENTRY_0_9 (32'h254) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_0_10 +`define DV_REG_DATA_VAULT_ENTRY_0_10 (32'h258) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_0_11 +`define DV_REG_DATA_VAULT_ENTRY_0_11 (32'h25c) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_1_0 +`define DV_REG_DATA_VAULT_ENTRY_1_0 (32'h260) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_1_1 +`define DV_REG_DATA_VAULT_ENTRY_1_1 (32'h264) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_1_2 +`define DV_REG_DATA_VAULT_ENTRY_1_2 (32'h268) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_1_3 +`define DV_REG_DATA_VAULT_ENTRY_1_3 (32'h26c) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_1_4 +`define DV_REG_DATA_VAULT_ENTRY_1_4 (32'h270) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_1_5 +`define DV_REG_DATA_VAULT_ENTRY_1_5 (32'h274) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_1_6 +`define DV_REG_DATA_VAULT_ENTRY_1_6 (32'h278) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_1_7 +`define DV_REG_DATA_VAULT_ENTRY_1_7 (32'h27c) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_1_8 +`define DV_REG_DATA_VAULT_ENTRY_1_8 (32'h280) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_1_9 +`define DV_REG_DATA_VAULT_ENTRY_1_9 (32'h284) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_1_10 +`define DV_REG_DATA_VAULT_ENTRY_1_10 (32'h288) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_1_11 +`define DV_REG_DATA_VAULT_ENTRY_1_11 (32'h28c) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_2_0 +`define DV_REG_DATA_VAULT_ENTRY_2_0 (32'h290) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_2_1 +`define DV_REG_DATA_VAULT_ENTRY_2_1 (32'h294) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_2_2 +`define DV_REG_DATA_VAULT_ENTRY_2_2 (32'h298) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_2_3 +`define DV_REG_DATA_VAULT_ENTRY_2_3 (32'h29c) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_2_4 +`define DV_REG_DATA_VAULT_ENTRY_2_4 (32'h2a0) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_2_5 +`define DV_REG_DATA_VAULT_ENTRY_2_5 (32'h2a4) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_2_6 +`define DV_REG_DATA_VAULT_ENTRY_2_6 (32'h2a8) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_2_7 +`define DV_REG_DATA_VAULT_ENTRY_2_7 (32'h2ac) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_2_8 +`define DV_REG_DATA_VAULT_ENTRY_2_8 (32'h2b0) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_2_9 +`define DV_REG_DATA_VAULT_ENTRY_2_9 (32'h2b4) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_2_10 +`define DV_REG_DATA_VAULT_ENTRY_2_10 (32'h2b8) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_2_11 +`define DV_REG_DATA_VAULT_ENTRY_2_11 (32'h2bc) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_3_0 +`define DV_REG_DATA_VAULT_ENTRY_3_0 (32'h2c0) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_3_1 +`define DV_REG_DATA_VAULT_ENTRY_3_1 (32'h2c4) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_3_2 +`define DV_REG_DATA_VAULT_ENTRY_3_2 (32'h2c8) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_3_3 +`define DV_REG_DATA_VAULT_ENTRY_3_3 (32'h2cc) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_3_4 +`define DV_REG_DATA_VAULT_ENTRY_3_4 (32'h2d0) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_3_5 +`define DV_REG_DATA_VAULT_ENTRY_3_5 (32'h2d4) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_3_6 +`define DV_REG_DATA_VAULT_ENTRY_3_6 (32'h2d8) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_3_7 +`define DV_REG_DATA_VAULT_ENTRY_3_7 (32'h2dc) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_3_8 +`define DV_REG_DATA_VAULT_ENTRY_3_8 (32'h2e0) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_3_9 +`define DV_REG_DATA_VAULT_ENTRY_3_9 (32'h2e4) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_3_10 +`define DV_REG_DATA_VAULT_ENTRY_3_10 (32'h2e8) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_3_11 +`define DV_REG_DATA_VAULT_ENTRY_3_11 (32'h2ec) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_4_0 +`define DV_REG_DATA_VAULT_ENTRY_4_0 (32'h2f0) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_4_1 +`define DV_REG_DATA_VAULT_ENTRY_4_1 (32'h2f4) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_4_2 +`define DV_REG_DATA_VAULT_ENTRY_4_2 (32'h2f8) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_4_3 +`define DV_REG_DATA_VAULT_ENTRY_4_3 (32'h2fc) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_4_4 +`define DV_REG_DATA_VAULT_ENTRY_4_4 (32'h300) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_4_5 +`define DV_REG_DATA_VAULT_ENTRY_4_5 (32'h304) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_4_6 +`define DV_REG_DATA_VAULT_ENTRY_4_6 (32'h308) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_4_7 +`define DV_REG_DATA_VAULT_ENTRY_4_7 (32'h30c) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_4_8 +`define DV_REG_DATA_VAULT_ENTRY_4_8 (32'h310) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_4_9 +`define DV_REG_DATA_VAULT_ENTRY_4_9 (32'h314) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_4_10 +`define DV_REG_DATA_VAULT_ENTRY_4_10 (32'h318) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_4_11 +`define DV_REG_DATA_VAULT_ENTRY_4_11 (32'h31c) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_5_0 +`define DV_REG_DATA_VAULT_ENTRY_5_0 (32'h320) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_5_1 +`define DV_REG_DATA_VAULT_ENTRY_5_1 (32'h324) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_5_2 +`define DV_REG_DATA_VAULT_ENTRY_5_2 (32'h328) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_5_3 +`define DV_REG_DATA_VAULT_ENTRY_5_3 (32'h32c) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_5_4 +`define DV_REG_DATA_VAULT_ENTRY_5_4 (32'h330) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_5_5 +`define DV_REG_DATA_VAULT_ENTRY_5_5 (32'h334) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_5_6 +`define DV_REG_DATA_VAULT_ENTRY_5_6 (32'h338) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_5_7 +`define DV_REG_DATA_VAULT_ENTRY_5_7 (32'h33c) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_5_8 +`define DV_REG_DATA_VAULT_ENTRY_5_8 (32'h340) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_5_9 +`define DV_REG_DATA_VAULT_ENTRY_5_9 (32'h344) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_5_10 +`define DV_REG_DATA_VAULT_ENTRY_5_10 (32'h348) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_5_11 +`define DV_REG_DATA_VAULT_ENTRY_5_11 (32'h34c) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_6_0 +`define DV_REG_DATA_VAULT_ENTRY_6_0 (32'h350) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_6_1 +`define DV_REG_DATA_VAULT_ENTRY_6_1 (32'h354) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_6_2 +`define DV_REG_DATA_VAULT_ENTRY_6_2 (32'h358) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_6_3 +`define DV_REG_DATA_VAULT_ENTRY_6_3 (32'h35c) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_6_4 +`define DV_REG_DATA_VAULT_ENTRY_6_4 (32'h360) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_6_5 +`define DV_REG_DATA_VAULT_ENTRY_6_5 (32'h364) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_6_6 +`define DV_REG_DATA_VAULT_ENTRY_6_6 (32'h368) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_6_7 +`define DV_REG_DATA_VAULT_ENTRY_6_7 (32'h36c) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_6_8 +`define DV_REG_DATA_VAULT_ENTRY_6_8 (32'h370) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_6_9 +`define DV_REG_DATA_VAULT_ENTRY_6_9 (32'h374) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_6_10 +`define DV_REG_DATA_VAULT_ENTRY_6_10 (32'h378) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_6_11 +`define DV_REG_DATA_VAULT_ENTRY_6_11 (32'h37c) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_7_0 +`define DV_REG_DATA_VAULT_ENTRY_7_0 (32'h380) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_7_1 +`define DV_REG_DATA_VAULT_ENTRY_7_1 (32'h384) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_7_2 +`define DV_REG_DATA_VAULT_ENTRY_7_2 (32'h388) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_7_3 +`define DV_REG_DATA_VAULT_ENTRY_7_3 (32'h38c) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_7_4 +`define DV_REG_DATA_VAULT_ENTRY_7_4 (32'h390) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_7_5 +`define DV_REG_DATA_VAULT_ENTRY_7_5 (32'h394) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_7_6 +`define DV_REG_DATA_VAULT_ENTRY_7_6 (32'h398) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_7_7 +`define DV_REG_DATA_VAULT_ENTRY_7_7 (32'h39c) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_7_8 +`define DV_REG_DATA_VAULT_ENTRY_7_8 (32'h3a0) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_7_9 +`define DV_REG_DATA_VAULT_ENTRY_7_9 (32'h3a4) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_7_10 +`define DV_REG_DATA_VAULT_ENTRY_7_10 (32'h3a8) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_7_11 +`define DV_REG_DATA_VAULT_ENTRY_7_11 (32'h3ac) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_8_0 +`define DV_REG_DATA_VAULT_ENTRY_8_0 (32'h3b0) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_8_1 +`define DV_REG_DATA_VAULT_ENTRY_8_1 (32'h3b4) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_8_2 +`define DV_REG_DATA_VAULT_ENTRY_8_2 (32'h3b8) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_8_3 +`define DV_REG_DATA_VAULT_ENTRY_8_3 (32'h3bc) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_8_4 +`define DV_REG_DATA_VAULT_ENTRY_8_4 (32'h3c0) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_8_5 +`define DV_REG_DATA_VAULT_ENTRY_8_5 (32'h3c4) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_8_6 +`define DV_REG_DATA_VAULT_ENTRY_8_6 (32'h3c8) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_8_7 +`define DV_REG_DATA_VAULT_ENTRY_8_7 (32'h3cc) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_8_8 +`define DV_REG_DATA_VAULT_ENTRY_8_8 (32'h3d0) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_8_9 +`define DV_REG_DATA_VAULT_ENTRY_8_9 (32'h3d4) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_8_10 +`define DV_REG_DATA_VAULT_ENTRY_8_10 (32'h3d8) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_8_11 +`define DV_REG_DATA_VAULT_ENTRY_8_11 (32'h3dc) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_9_0 +`define DV_REG_DATA_VAULT_ENTRY_9_0 (32'h3e0) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_9_1 +`define DV_REG_DATA_VAULT_ENTRY_9_1 (32'h3e4) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_9_2 +`define DV_REG_DATA_VAULT_ENTRY_9_2 (32'h3e8) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_9_3 +`define DV_REG_DATA_VAULT_ENTRY_9_3 (32'h3ec) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_9_4 +`define DV_REG_DATA_VAULT_ENTRY_9_4 (32'h3f0) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_9_5 +`define DV_REG_DATA_VAULT_ENTRY_9_5 (32'h3f4) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_9_6 +`define DV_REG_DATA_VAULT_ENTRY_9_6 (32'h3f8) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_9_7 +`define DV_REG_DATA_VAULT_ENTRY_9_7 (32'h3fc) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_9_8 +`define DV_REG_DATA_VAULT_ENTRY_9_8 (32'h400) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_9_9 +`define DV_REG_DATA_VAULT_ENTRY_9_9 (32'h404) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_9_10 +`define DV_REG_DATA_VAULT_ENTRY_9_10 (32'h408) +`endif +`ifndef DV_REG_DATA_VAULT_ENTRY_9_11 +`define DV_REG_DATA_VAULT_ENTRY_9_11 (32'h40c) +`endif +`ifndef DV_REG_LOCKABLESCRATCHREGCTRL_0 +`define DV_REG_LOCKABLESCRATCHREGCTRL_0 (32'h410) +`define DV_REG_LOCKABLESCRATCHREGCTRL_0_LOCK_ENTRY_LOW (0) +`define DV_REG_LOCKABLESCRATCHREGCTRL_0_LOCK_ENTRY_MASK (32'h1) +`endif +`ifndef DV_REG_LOCKABLESCRATCHREGCTRL_1 +`define DV_REG_LOCKABLESCRATCHREGCTRL_1 (32'h414) +`define DV_REG_LOCKABLESCRATCHREGCTRL_1_LOCK_ENTRY_LOW (0) +`define DV_REG_LOCKABLESCRATCHREGCTRL_1_LOCK_ENTRY_MASK (32'h1) +`endif +`ifndef DV_REG_LOCKABLESCRATCHREGCTRL_2 +`define DV_REG_LOCKABLESCRATCHREGCTRL_2 (32'h418) +`define DV_REG_LOCKABLESCRATCHREGCTRL_2_LOCK_ENTRY_LOW (0) +`define DV_REG_LOCKABLESCRATCHREGCTRL_2_LOCK_ENTRY_MASK (32'h1) +`endif +`ifndef DV_REG_LOCKABLESCRATCHREGCTRL_3 +`define DV_REG_LOCKABLESCRATCHREGCTRL_3 (32'h41c) +`define DV_REG_LOCKABLESCRATCHREGCTRL_3_LOCK_ENTRY_LOW (0) +`define DV_REG_LOCKABLESCRATCHREGCTRL_3_LOCK_ENTRY_MASK (32'h1) +`endif +`ifndef DV_REG_LOCKABLESCRATCHREGCTRL_4 +`define DV_REG_LOCKABLESCRATCHREGCTRL_4 (32'h420) +`define DV_REG_LOCKABLESCRATCHREGCTRL_4_LOCK_ENTRY_LOW (0) +`define DV_REG_LOCKABLESCRATCHREGCTRL_4_LOCK_ENTRY_MASK (32'h1) +`endif +`ifndef DV_REG_LOCKABLESCRATCHREGCTRL_5 +`define DV_REG_LOCKABLESCRATCHREGCTRL_5 (32'h424) +`define DV_REG_LOCKABLESCRATCHREGCTRL_5_LOCK_ENTRY_LOW (0) +`define DV_REG_LOCKABLESCRATCHREGCTRL_5_LOCK_ENTRY_MASK (32'h1) +`endif +`ifndef DV_REG_LOCKABLESCRATCHREGCTRL_6 +`define DV_REG_LOCKABLESCRATCHREGCTRL_6 (32'h428) +`define DV_REG_LOCKABLESCRATCHREGCTRL_6_LOCK_ENTRY_LOW (0) +`define DV_REG_LOCKABLESCRATCHREGCTRL_6_LOCK_ENTRY_MASK (32'h1) +`endif +`ifndef DV_REG_LOCKABLESCRATCHREGCTRL_7 +`define DV_REG_LOCKABLESCRATCHREGCTRL_7 (32'h42c) +`define DV_REG_LOCKABLESCRATCHREGCTRL_7_LOCK_ENTRY_LOW (0) +`define DV_REG_LOCKABLESCRATCHREGCTRL_7_LOCK_ENTRY_MASK (32'h1) +`endif +`ifndef DV_REG_LOCKABLESCRATCHREGCTRL_8 +`define DV_REG_LOCKABLESCRATCHREGCTRL_8 (32'h430) +`define DV_REG_LOCKABLESCRATCHREGCTRL_8_LOCK_ENTRY_LOW (0) +`define DV_REG_LOCKABLESCRATCHREGCTRL_8_LOCK_ENTRY_MASK (32'h1) +`endif +`ifndef DV_REG_LOCKABLESCRATCHREGCTRL_9 +`define DV_REG_LOCKABLESCRATCHREGCTRL_9 (32'h434) +`define DV_REG_LOCKABLESCRATCHREGCTRL_9_LOCK_ENTRY_LOW (0) +`define DV_REG_LOCKABLESCRATCHREGCTRL_9_LOCK_ENTRY_MASK (32'h1) +`endif +`ifndef DV_REG_LOCKABLESCRATCHREG_0 +`define DV_REG_LOCKABLESCRATCHREG_0 (32'h438) +`endif +`ifndef DV_REG_LOCKABLESCRATCHREG_1 +`define DV_REG_LOCKABLESCRATCHREG_1 (32'h43c) +`endif +`ifndef DV_REG_LOCKABLESCRATCHREG_2 +`define DV_REG_LOCKABLESCRATCHREG_2 (32'h440) +`endif +`ifndef DV_REG_LOCKABLESCRATCHREG_3 +`define DV_REG_LOCKABLESCRATCHREG_3 (32'h444) +`endif +`ifndef DV_REG_LOCKABLESCRATCHREG_4 +`define DV_REG_LOCKABLESCRATCHREG_4 (32'h448) +`endif +`ifndef DV_REG_LOCKABLESCRATCHREG_5 +`define DV_REG_LOCKABLESCRATCHREG_5 (32'h44c) +`endif +`ifndef DV_REG_LOCKABLESCRATCHREG_6 +`define DV_REG_LOCKABLESCRATCHREG_6 (32'h450) +`endif +`ifndef DV_REG_LOCKABLESCRATCHREG_7 +`define DV_REG_LOCKABLESCRATCHREG_7 (32'h454) +`endif +`ifndef DV_REG_LOCKABLESCRATCHREG_8 +`define DV_REG_LOCKABLESCRATCHREG_8 (32'h458) +`endif +`ifndef DV_REG_LOCKABLESCRATCHREG_9 +`define DV_REG_LOCKABLESCRATCHREG_9 (32'h45c) +`endif +`ifndef DV_REG_NONSTICKYGENERICSCRATCHREG_0 +`define DV_REG_NONSTICKYGENERICSCRATCHREG_0 (32'h460) +`endif +`ifndef DV_REG_NONSTICKYGENERICSCRATCHREG_1 +`define DV_REG_NONSTICKYGENERICSCRATCHREG_1 (32'h464) +`endif +`ifndef DV_REG_NONSTICKYGENERICSCRATCHREG_2 +`define DV_REG_NONSTICKYGENERICSCRATCHREG_2 (32'h468) +`endif +`ifndef DV_REG_NONSTICKYGENERICSCRATCHREG_3 +`define DV_REG_NONSTICKYGENERICSCRATCHREG_3 (32'h46c) +`endif +`ifndef DV_REG_NONSTICKYGENERICSCRATCHREG_4 +`define DV_REG_NONSTICKYGENERICSCRATCHREG_4 (32'h470) +`endif +`ifndef DV_REG_NONSTICKYGENERICSCRATCHREG_5 +`define DV_REG_NONSTICKYGENERICSCRATCHREG_5 (32'h474) +`endif +`ifndef DV_REG_NONSTICKYGENERICSCRATCHREG_6 +`define DV_REG_NONSTICKYGENERICSCRATCHREG_6 (32'h478) +`endif +`ifndef DV_REG_NONSTICKYGENERICSCRATCHREG_7 +`define DV_REG_NONSTICKYGENERICSCRATCHREG_7 (32'h47c) +`endif +`ifndef DV_REG_STICKYLOCKABLESCRATCHREGCTRL_0 +`define DV_REG_STICKYLOCKABLESCRATCHREGCTRL_0 (32'h480) +`define DV_REG_STICKYLOCKABLESCRATCHREGCTRL_0_LOCK_ENTRY_LOW (0) +`define DV_REG_STICKYLOCKABLESCRATCHREGCTRL_0_LOCK_ENTRY_MASK (32'h1) +`endif +`ifndef DV_REG_STICKYLOCKABLESCRATCHREGCTRL_1 +`define DV_REG_STICKYLOCKABLESCRATCHREGCTRL_1 (32'h484) +`define DV_REG_STICKYLOCKABLESCRATCHREGCTRL_1_LOCK_ENTRY_LOW (0) +`define DV_REG_STICKYLOCKABLESCRATCHREGCTRL_1_LOCK_ENTRY_MASK (32'h1) +`endif +`ifndef DV_REG_STICKYLOCKABLESCRATCHREGCTRL_2 +`define DV_REG_STICKYLOCKABLESCRATCHREGCTRL_2 (32'h488) +`define DV_REG_STICKYLOCKABLESCRATCHREGCTRL_2_LOCK_ENTRY_LOW (0) +`define DV_REG_STICKYLOCKABLESCRATCHREGCTRL_2_LOCK_ENTRY_MASK (32'h1) +`endif +`ifndef DV_REG_STICKYLOCKABLESCRATCHREGCTRL_3 +`define DV_REG_STICKYLOCKABLESCRATCHREGCTRL_3 (32'h48c) +`define DV_REG_STICKYLOCKABLESCRATCHREGCTRL_3_LOCK_ENTRY_LOW (0) +`define DV_REG_STICKYLOCKABLESCRATCHREGCTRL_3_LOCK_ENTRY_MASK (32'h1) +`endif +`ifndef DV_REG_STICKYLOCKABLESCRATCHREGCTRL_4 +`define DV_REG_STICKYLOCKABLESCRATCHREGCTRL_4 (32'h490) +`define DV_REG_STICKYLOCKABLESCRATCHREGCTRL_4_LOCK_ENTRY_LOW (0) +`define DV_REG_STICKYLOCKABLESCRATCHREGCTRL_4_LOCK_ENTRY_MASK (32'h1) +`endif +`ifndef DV_REG_STICKYLOCKABLESCRATCHREGCTRL_5 +`define DV_REG_STICKYLOCKABLESCRATCHREGCTRL_5 (32'h494) +`define DV_REG_STICKYLOCKABLESCRATCHREGCTRL_5_LOCK_ENTRY_LOW (0) +`define DV_REG_STICKYLOCKABLESCRATCHREGCTRL_5_LOCK_ENTRY_MASK (32'h1) +`endif +`ifndef DV_REG_STICKYLOCKABLESCRATCHREGCTRL_6 +`define DV_REG_STICKYLOCKABLESCRATCHREGCTRL_6 (32'h498) +`define DV_REG_STICKYLOCKABLESCRATCHREGCTRL_6_LOCK_ENTRY_LOW (0) +`define DV_REG_STICKYLOCKABLESCRATCHREGCTRL_6_LOCK_ENTRY_MASK (32'h1) +`endif +`ifndef DV_REG_STICKYLOCKABLESCRATCHREGCTRL_7 +`define DV_REG_STICKYLOCKABLESCRATCHREGCTRL_7 (32'h49c) +`define DV_REG_STICKYLOCKABLESCRATCHREGCTRL_7_LOCK_ENTRY_LOW (0) +`define DV_REG_STICKYLOCKABLESCRATCHREGCTRL_7_LOCK_ENTRY_MASK (32'h1) +`endif +`ifndef DV_REG_STICKYLOCKABLESCRATCHREG_0 +`define DV_REG_STICKYLOCKABLESCRATCHREG_0 (32'h4a0) +`endif +`ifndef DV_REG_STICKYLOCKABLESCRATCHREG_1 +`define DV_REG_STICKYLOCKABLESCRATCHREG_1 (32'h4a4) +`endif +`ifndef DV_REG_STICKYLOCKABLESCRATCHREG_2 +`define DV_REG_STICKYLOCKABLESCRATCHREG_2 (32'h4a8) +`endif +`ifndef DV_REG_STICKYLOCKABLESCRATCHREG_3 +`define DV_REG_STICKYLOCKABLESCRATCHREG_3 (32'h4ac) +`endif +`ifndef DV_REG_STICKYLOCKABLESCRATCHREG_4 +`define DV_REG_STICKYLOCKABLESCRATCHREG_4 (32'h4b0) +`endif +`ifndef DV_REG_STICKYLOCKABLESCRATCHREG_5 +`define DV_REG_STICKYLOCKABLESCRATCHREG_5 (32'h4b4) +`endif +`ifndef DV_REG_STICKYLOCKABLESCRATCHREG_6 +`define DV_REG_STICKYLOCKABLESCRATCHREG_6 (32'h4b8) +`endif +`ifndef DV_REG_STICKYLOCKABLESCRATCHREG_7 +`define DV_REG_STICKYLOCKABLESCRATCHREG_7 (32'h4bc) +`endif +`ifndef SHA512_REG_SHA512_NAME_0 +`define SHA512_REG_SHA512_NAME_0 (32'h0) +`endif +`ifndef SHA512_REG_SHA512_NAME_1 +`define SHA512_REG_SHA512_NAME_1 (32'h4) +`endif +`ifndef SHA512_REG_SHA512_VERSION_0 +`define SHA512_REG_SHA512_VERSION_0 (32'h8) +`endif +`ifndef SHA512_REG_SHA512_VERSION_1 +`define SHA512_REG_SHA512_VERSION_1 (32'hc) +`endif +`ifndef SHA512_REG_SHA512_CTRL +`define SHA512_REG_SHA512_CTRL (32'h10) +`define SHA512_REG_SHA512_CTRL_INIT_LOW (0) +`define SHA512_REG_SHA512_CTRL_INIT_MASK (32'h1) +`define SHA512_REG_SHA512_CTRL_NEXT_LOW (1) +`define SHA512_REG_SHA512_CTRL_NEXT_MASK (32'h2) +`define SHA512_REG_SHA512_CTRL_MODE_LOW (2) +`define SHA512_REG_SHA512_CTRL_MODE_MASK (32'hc) +`define SHA512_REG_SHA512_CTRL_ZEROIZE_LOW (4) +`define SHA512_REG_SHA512_CTRL_ZEROIZE_MASK (32'h10) +`define SHA512_REG_SHA512_CTRL_LAST_LOW (5) +`define SHA512_REG_SHA512_CTRL_LAST_MASK (32'h20) +`define SHA512_REG_SHA512_CTRL_RESTORE_LOW (6) +`define SHA512_REG_SHA512_CTRL_RESTORE_MASK (32'h40) +`endif +`ifndef SHA512_REG_SHA512_STATUS +`define SHA512_REG_SHA512_STATUS (32'h18) +`define SHA512_REG_SHA512_STATUS_READY_LOW (0) +`define SHA512_REG_SHA512_STATUS_READY_MASK (32'h1) +`define SHA512_REG_SHA512_STATUS_VALID_LOW (1) +`define SHA512_REG_SHA512_STATUS_VALID_MASK (32'h2) +`endif +`ifndef SHA512_REG_SHA512_BLOCK_0 +`define SHA512_REG_SHA512_BLOCK_0 (32'h80) +`endif +`ifndef SHA512_REG_SHA512_BLOCK_1 +`define SHA512_REG_SHA512_BLOCK_1 (32'h84) +`endif +`ifndef SHA512_REG_SHA512_BLOCK_2 +`define SHA512_REG_SHA512_BLOCK_2 (32'h88) +`endif +`ifndef SHA512_REG_SHA512_BLOCK_3 +`define SHA512_REG_SHA512_BLOCK_3 (32'h8c) +`endif +`ifndef SHA512_REG_SHA512_BLOCK_4 +`define SHA512_REG_SHA512_BLOCK_4 (32'h90) +`endif +`ifndef SHA512_REG_SHA512_BLOCK_5 +`define SHA512_REG_SHA512_BLOCK_5 (32'h94) +`endif +`ifndef SHA512_REG_SHA512_BLOCK_6 +`define SHA512_REG_SHA512_BLOCK_6 (32'h98) +`endif +`ifndef SHA512_REG_SHA512_BLOCK_7 +`define SHA512_REG_SHA512_BLOCK_7 (32'h9c) +`endif +`ifndef SHA512_REG_SHA512_BLOCK_8 +`define SHA512_REG_SHA512_BLOCK_8 (32'ha0) +`endif +`ifndef SHA512_REG_SHA512_BLOCK_9 +`define SHA512_REG_SHA512_BLOCK_9 (32'ha4) +`endif +`ifndef SHA512_REG_SHA512_BLOCK_10 +`define SHA512_REG_SHA512_BLOCK_10 (32'ha8) +`endif +`ifndef SHA512_REG_SHA512_BLOCK_11 +`define SHA512_REG_SHA512_BLOCK_11 (32'hac) +`endif +`ifndef SHA512_REG_SHA512_BLOCK_12 +`define SHA512_REG_SHA512_BLOCK_12 (32'hb0) +`endif +`ifndef SHA512_REG_SHA512_BLOCK_13 +`define SHA512_REG_SHA512_BLOCK_13 (32'hb4) +`endif +`ifndef SHA512_REG_SHA512_BLOCK_14 +`define SHA512_REG_SHA512_BLOCK_14 (32'hb8) +`endif +`ifndef SHA512_REG_SHA512_BLOCK_15 +`define SHA512_REG_SHA512_BLOCK_15 (32'hbc) +`endif +`ifndef SHA512_REG_SHA512_BLOCK_16 +`define SHA512_REG_SHA512_BLOCK_16 (32'hc0) +`endif +`ifndef SHA512_REG_SHA512_BLOCK_17 +`define SHA512_REG_SHA512_BLOCK_17 (32'hc4) +`endif +`ifndef SHA512_REG_SHA512_BLOCK_18 +`define SHA512_REG_SHA512_BLOCK_18 (32'hc8) +`endif +`ifndef SHA512_REG_SHA512_BLOCK_19 +`define SHA512_REG_SHA512_BLOCK_19 (32'hcc) +`endif +`ifndef SHA512_REG_SHA512_BLOCK_20 +`define SHA512_REG_SHA512_BLOCK_20 (32'hd0) +`endif +`ifndef SHA512_REG_SHA512_BLOCK_21 +`define SHA512_REG_SHA512_BLOCK_21 (32'hd4) +`endif +`ifndef SHA512_REG_SHA512_BLOCK_22 +`define SHA512_REG_SHA512_BLOCK_22 (32'hd8) +`endif +`ifndef SHA512_REG_SHA512_BLOCK_23 +`define SHA512_REG_SHA512_BLOCK_23 (32'hdc) +`endif +`ifndef SHA512_REG_SHA512_BLOCK_24 +`define SHA512_REG_SHA512_BLOCK_24 (32'he0) +`endif +`ifndef SHA512_REG_SHA512_BLOCK_25 +`define SHA512_REG_SHA512_BLOCK_25 (32'he4) +`endif +`ifndef SHA512_REG_SHA512_BLOCK_26 +`define SHA512_REG_SHA512_BLOCK_26 (32'he8) +`endif +`ifndef SHA512_REG_SHA512_BLOCK_27 +`define SHA512_REG_SHA512_BLOCK_27 (32'hec) +`endif +`ifndef SHA512_REG_SHA512_BLOCK_28 +`define SHA512_REG_SHA512_BLOCK_28 (32'hf0) +`endif +`ifndef SHA512_REG_SHA512_BLOCK_29 +`define SHA512_REG_SHA512_BLOCK_29 (32'hf4) +`endif +`ifndef SHA512_REG_SHA512_BLOCK_30 +`define SHA512_REG_SHA512_BLOCK_30 (32'hf8) +`endif +`ifndef SHA512_REG_SHA512_BLOCK_31 +`define SHA512_REG_SHA512_BLOCK_31 (32'hfc) +`endif +`ifndef SHA512_REG_SHA512_DIGEST_0 +`define SHA512_REG_SHA512_DIGEST_0 (32'h100) +`endif +`ifndef SHA512_REG_SHA512_DIGEST_1 +`define SHA512_REG_SHA512_DIGEST_1 (32'h104) +`endif +`ifndef SHA512_REG_SHA512_DIGEST_2 +`define SHA512_REG_SHA512_DIGEST_2 (32'h108) +`endif +`ifndef SHA512_REG_SHA512_DIGEST_3 +`define SHA512_REG_SHA512_DIGEST_3 (32'h10c) +`endif +`ifndef SHA512_REG_SHA512_DIGEST_4 +`define SHA512_REG_SHA512_DIGEST_4 (32'h110) +`endif +`ifndef SHA512_REG_SHA512_DIGEST_5 +`define SHA512_REG_SHA512_DIGEST_5 (32'h114) +`endif +`ifndef SHA512_REG_SHA512_DIGEST_6 +`define SHA512_REG_SHA512_DIGEST_6 (32'h118) +`endif +`ifndef SHA512_REG_SHA512_DIGEST_7 +`define SHA512_REG_SHA512_DIGEST_7 (32'h11c) +`endif +`ifndef SHA512_REG_SHA512_DIGEST_8 +`define SHA512_REG_SHA512_DIGEST_8 (32'h120) +`endif +`ifndef SHA512_REG_SHA512_DIGEST_9 +`define SHA512_REG_SHA512_DIGEST_9 (32'h124) +`endif +`ifndef SHA512_REG_SHA512_DIGEST_10 +`define SHA512_REG_SHA512_DIGEST_10 (32'h128) +`endif +`ifndef SHA512_REG_SHA512_DIGEST_11 +`define SHA512_REG_SHA512_DIGEST_11 (32'h12c) +`endif +`ifndef SHA512_REG_SHA512_DIGEST_12 +`define SHA512_REG_SHA512_DIGEST_12 (32'h130) +`endif +`ifndef SHA512_REG_SHA512_DIGEST_13 +`define SHA512_REG_SHA512_DIGEST_13 (32'h134) +`endif +`ifndef SHA512_REG_SHA512_DIGEST_14 +`define SHA512_REG_SHA512_DIGEST_14 (32'h138) +`endif +`ifndef SHA512_REG_SHA512_DIGEST_15 +`define SHA512_REG_SHA512_DIGEST_15 (32'h13c) +`endif +`ifndef SHA512_REG_SHA512_VAULT_RD_CTRL +`define SHA512_REG_SHA512_VAULT_RD_CTRL (32'h600) +`define SHA512_REG_SHA512_VAULT_RD_CTRL_READ_EN_LOW (0) +`define SHA512_REG_SHA512_VAULT_RD_CTRL_READ_EN_MASK (32'h1) +`define SHA512_REG_SHA512_VAULT_RD_CTRL_READ_ENTRY_LOW (1) +`define SHA512_REG_SHA512_VAULT_RD_CTRL_READ_ENTRY_MASK (32'h3e) +`define SHA512_REG_SHA512_VAULT_RD_CTRL_PCR_HASH_EXTEND_LOW (6) +`define SHA512_REG_SHA512_VAULT_RD_CTRL_PCR_HASH_EXTEND_MASK (32'h40) +`define SHA512_REG_SHA512_VAULT_RD_CTRL_RSVD_LOW (7) +`define SHA512_REG_SHA512_VAULT_RD_CTRL_RSVD_MASK (32'hffffff80) +`endif +`ifndef SHA512_REG_SHA512_VAULT_RD_STATUS +`define SHA512_REG_SHA512_VAULT_RD_STATUS (32'h604) +`define SHA512_REG_SHA512_VAULT_RD_STATUS_READY_LOW (0) +`define SHA512_REG_SHA512_VAULT_RD_STATUS_READY_MASK (32'h1) +`define SHA512_REG_SHA512_VAULT_RD_STATUS_VALID_LOW (1) +`define SHA512_REG_SHA512_VAULT_RD_STATUS_VALID_MASK (32'h2) +`define SHA512_REG_SHA512_VAULT_RD_STATUS_ERROR_LOW (2) +`define SHA512_REG_SHA512_VAULT_RD_STATUS_ERROR_MASK (32'h3fc) +`endif +`ifndef SHA512_REG_SHA512_KV_WR_CTRL +`define SHA512_REG_SHA512_KV_WR_CTRL (32'h608) +`define SHA512_REG_SHA512_KV_WR_CTRL_WRITE_EN_LOW (0) +`define SHA512_REG_SHA512_KV_WR_CTRL_WRITE_EN_MASK (32'h1) +`define SHA512_REG_SHA512_KV_WR_CTRL_WRITE_ENTRY_LOW (1) +`define SHA512_REG_SHA512_KV_WR_CTRL_WRITE_ENTRY_MASK (32'h3e) +`define SHA512_REG_SHA512_KV_WR_CTRL_HMAC_KEY_DEST_VALID_LOW (6) +`define SHA512_REG_SHA512_KV_WR_CTRL_HMAC_KEY_DEST_VALID_MASK (32'h40) +`define SHA512_REG_SHA512_KV_WR_CTRL_HMAC_BLOCK_DEST_VALID_LOW (7) +`define SHA512_REG_SHA512_KV_WR_CTRL_HMAC_BLOCK_DEST_VALID_MASK (32'h80) +`define SHA512_REG_SHA512_KV_WR_CTRL_MLDSA_SEED_DEST_VALID_LOW (8) +`define SHA512_REG_SHA512_KV_WR_CTRL_MLDSA_SEED_DEST_VALID_MASK (32'h100) +`define SHA512_REG_SHA512_KV_WR_CTRL_ECC_PKEY_DEST_VALID_LOW (9) +`define SHA512_REG_SHA512_KV_WR_CTRL_ECC_PKEY_DEST_VALID_MASK (32'h200) +`define SHA512_REG_SHA512_KV_WR_CTRL_ECC_SEED_DEST_VALID_LOW (10) +`define SHA512_REG_SHA512_KV_WR_CTRL_ECC_SEED_DEST_VALID_MASK (32'h400) +`define SHA512_REG_SHA512_KV_WR_CTRL_AES_KEY_DEST_VALID_LOW (11) +`define SHA512_REG_SHA512_KV_WR_CTRL_AES_KEY_DEST_VALID_MASK (32'h800) +`define SHA512_REG_SHA512_KV_WR_CTRL_MLKEM_SEED_DEST_VALID_LOW (12) +`define SHA512_REG_SHA512_KV_WR_CTRL_MLKEM_SEED_DEST_VALID_MASK (32'h1000) +`define SHA512_REG_SHA512_KV_WR_CTRL_MLKEM_MSG_DEST_VALID_LOW (13) +`define SHA512_REG_SHA512_KV_WR_CTRL_MLKEM_MSG_DEST_VALID_MASK (32'h2000) +`define SHA512_REG_SHA512_KV_WR_CTRL_DMA_DATA_DEST_VALID_LOW (14) +`define SHA512_REG_SHA512_KV_WR_CTRL_DMA_DATA_DEST_VALID_MASK (32'h4000) +`define SHA512_REG_SHA512_KV_WR_CTRL_RSVD_LOW (15) +`define SHA512_REG_SHA512_KV_WR_CTRL_RSVD_MASK (32'hffff8000) +`endif +`ifndef SHA512_REG_SHA512_KV_WR_STATUS +`define SHA512_REG_SHA512_KV_WR_STATUS (32'h60c) +`define SHA512_REG_SHA512_KV_WR_STATUS_READY_LOW (0) +`define SHA512_REG_SHA512_KV_WR_STATUS_READY_MASK (32'h1) +`define SHA512_REG_SHA512_KV_WR_STATUS_VALID_LOW (1) +`define SHA512_REG_SHA512_KV_WR_STATUS_VALID_MASK (32'h2) +`define SHA512_REG_SHA512_KV_WR_STATUS_ERROR_LOW (2) +`define SHA512_REG_SHA512_KV_WR_STATUS_ERROR_MASK (32'h3fc) +`endif +`ifndef SHA512_REG_SHA512_GEN_PCR_HASH_NONCE_0 +`define SHA512_REG_SHA512_GEN_PCR_HASH_NONCE_0 (32'h610) +`endif +`ifndef SHA512_REG_SHA512_GEN_PCR_HASH_NONCE_1 +`define SHA512_REG_SHA512_GEN_PCR_HASH_NONCE_1 (32'h614) +`endif +`ifndef SHA512_REG_SHA512_GEN_PCR_HASH_NONCE_2 +`define SHA512_REG_SHA512_GEN_PCR_HASH_NONCE_2 (32'h618) +`endif +`ifndef SHA512_REG_SHA512_GEN_PCR_HASH_NONCE_3 +`define SHA512_REG_SHA512_GEN_PCR_HASH_NONCE_3 (32'h61c) +`endif +`ifndef SHA512_REG_SHA512_GEN_PCR_HASH_NONCE_4 +`define SHA512_REG_SHA512_GEN_PCR_HASH_NONCE_4 (32'h620) +`endif +`ifndef SHA512_REG_SHA512_GEN_PCR_HASH_NONCE_5 +`define SHA512_REG_SHA512_GEN_PCR_HASH_NONCE_5 (32'h624) +`endif +`ifndef SHA512_REG_SHA512_GEN_PCR_HASH_NONCE_6 +`define SHA512_REG_SHA512_GEN_PCR_HASH_NONCE_6 (32'h628) +`endif +`ifndef SHA512_REG_SHA512_GEN_PCR_HASH_NONCE_7 +`define SHA512_REG_SHA512_GEN_PCR_HASH_NONCE_7 (32'h62c) +`endif +`ifndef SHA512_REG_SHA512_GEN_PCR_HASH_CTRL +`define SHA512_REG_SHA512_GEN_PCR_HASH_CTRL (32'h630) +`define SHA512_REG_SHA512_GEN_PCR_HASH_CTRL_START_LOW (0) +`define SHA512_REG_SHA512_GEN_PCR_HASH_CTRL_START_MASK (32'h1) +`endif +`ifndef SHA512_REG_SHA512_GEN_PCR_HASH_STATUS +`define SHA512_REG_SHA512_GEN_PCR_HASH_STATUS (32'h634) +`define SHA512_REG_SHA512_GEN_PCR_HASH_STATUS_READY_LOW (0) +`define SHA512_REG_SHA512_GEN_PCR_HASH_STATUS_READY_MASK (32'h1) +`define SHA512_REG_SHA512_GEN_PCR_HASH_STATUS_VALID_LOW (1) +`define SHA512_REG_SHA512_GEN_PCR_HASH_STATUS_VALID_MASK (32'h2) +`endif +`ifndef SHA512_REG_SHA512_GEN_PCR_HASH_DIGEST_0 +`define SHA512_REG_SHA512_GEN_PCR_HASH_DIGEST_0 (32'h638) +`endif +`ifndef SHA512_REG_SHA512_GEN_PCR_HASH_DIGEST_1 +`define SHA512_REG_SHA512_GEN_PCR_HASH_DIGEST_1 (32'h63c) +`endif +`ifndef SHA512_REG_SHA512_GEN_PCR_HASH_DIGEST_2 +`define SHA512_REG_SHA512_GEN_PCR_HASH_DIGEST_2 (32'h640) +`endif +`ifndef SHA512_REG_SHA512_GEN_PCR_HASH_DIGEST_3 +`define SHA512_REG_SHA512_GEN_PCR_HASH_DIGEST_3 (32'h644) +`endif +`ifndef SHA512_REG_SHA512_GEN_PCR_HASH_DIGEST_4 +`define SHA512_REG_SHA512_GEN_PCR_HASH_DIGEST_4 (32'h648) +`endif +`ifndef SHA512_REG_SHA512_GEN_PCR_HASH_DIGEST_5 +`define SHA512_REG_SHA512_GEN_PCR_HASH_DIGEST_5 (32'h64c) +`endif +`ifndef SHA512_REG_SHA512_GEN_PCR_HASH_DIGEST_6 +`define SHA512_REG_SHA512_GEN_PCR_HASH_DIGEST_6 (32'h650) +`endif +`ifndef SHA512_REG_SHA512_GEN_PCR_HASH_DIGEST_7 +`define SHA512_REG_SHA512_GEN_PCR_HASH_DIGEST_7 (32'h654) +`endif +`ifndef SHA512_REG_SHA512_GEN_PCR_HASH_DIGEST_8 +`define SHA512_REG_SHA512_GEN_PCR_HASH_DIGEST_8 (32'h658) +`endif +`ifndef SHA512_REG_SHA512_GEN_PCR_HASH_DIGEST_9 +`define SHA512_REG_SHA512_GEN_PCR_HASH_DIGEST_9 (32'h65c) +`endif +`ifndef SHA512_REG_SHA512_GEN_PCR_HASH_DIGEST_10 +`define SHA512_REG_SHA512_GEN_PCR_HASH_DIGEST_10 (32'h660) +`endif +`ifndef SHA512_REG_SHA512_GEN_PCR_HASH_DIGEST_11 +`define SHA512_REG_SHA512_GEN_PCR_HASH_DIGEST_11 (32'h664) +`endif +`ifndef SHA512_REG_SHA512_GEN_PCR_HASH_DIGEST_12 +`define SHA512_REG_SHA512_GEN_PCR_HASH_DIGEST_12 (32'h668) +`endif +`ifndef SHA512_REG_SHA512_GEN_PCR_HASH_DIGEST_13 +`define SHA512_REG_SHA512_GEN_PCR_HASH_DIGEST_13 (32'h66c) +`endif +`ifndef SHA512_REG_SHA512_GEN_PCR_HASH_DIGEST_14 +`define SHA512_REG_SHA512_GEN_PCR_HASH_DIGEST_14 (32'h670) +`endif +`ifndef SHA512_REG_SHA512_GEN_PCR_HASH_DIGEST_15 +`define SHA512_REG_SHA512_GEN_PCR_HASH_DIGEST_15 (32'h674) +`endif +`ifndef SHA512_REG_INTR_BLOCK_RF_GLOBAL_INTR_EN_R +`define SHA512_REG_INTR_BLOCK_RF_GLOBAL_INTR_EN_R (32'h800) +`define SHA512_REG_INTR_BLOCK_RF_GLOBAL_INTR_EN_R_ERROR_EN_LOW (0) +`define SHA512_REG_INTR_BLOCK_RF_GLOBAL_INTR_EN_R_ERROR_EN_MASK (32'h1) +`define SHA512_REG_INTR_BLOCK_RF_GLOBAL_INTR_EN_R_NOTIF_EN_LOW (1) +`define SHA512_REG_INTR_BLOCK_RF_GLOBAL_INTR_EN_R_NOTIF_EN_MASK (32'h2) +`endif +`ifndef SHA512_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R +`define SHA512_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R (32'h804) +`define SHA512_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R_ERROR0_EN_LOW (0) +`define SHA512_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R_ERROR0_EN_MASK (32'h1) +`define SHA512_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R_ERROR1_EN_LOW (1) +`define SHA512_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R_ERROR1_EN_MASK (32'h2) +`define SHA512_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R_ERROR2_EN_LOW (2) +`define SHA512_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R_ERROR2_EN_MASK (32'h4) +`define SHA512_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R_ERROR3_EN_LOW (3) +`define SHA512_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R_ERROR3_EN_MASK (32'h8) +`endif +`ifndef SHA512_REG_INTR_BLOCK_RF_NOTIF_INTR_EN_R +`define SHA512_REG_INTR_BLOCK_RF_NOTIF_INTR_EN_R (32'h808) +`define SHA512_REG_INTR_BLOCK_RF_NOTIF_INTR_EN_R_NOTIF_CMD_DONE_EN_LOW (0) +`define SHA512_REG_INTR_BLOCK_RF_NOTIF_INTR_EN_R_NOTIF_CMD_DONE_EN_MASK (32'h1) +`endif +`ifndef SHA512_REG_INTR_BLOCK_RF_ERROR_GLOBAL_INTR_R +`define SHA512_REG_INTR_BLOCK_RF_ERROR_GLOBAL_INTR_R (32'h80c) +`define SHA512_REG_INTR_BLOCK_RF_ERROR_GLOBAL_INTR_R_AGG_STS_LOW (0) +`define SHA512_REG_INTR_BLOCK_RF_ERROR_GLOBAL_INTR_R_AGG_STS_MASK (32'h1) +`endif +`ifndef SHA512_REG_INTR_BLOCK_RF_NOTIF_GLOBAL_INTR_R +`define SHA512_REG_INTR_BLOCK_RF_NOTIF_GLOBAL_INTR_R (32'h810) +`define SHA512_REG_INTR_BLOCK_RF_NOTIF_GLOBAL_INTR_R_AGG_STS_LOW (0) +`define SHA512_REG_INTR_BLOCK_RF_NOTIF_GLOBAL_INTR_R_AGG_STS_MASK (32'h1) +`endif +`ifndef SHA512_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R +`define SHA512_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R (32'h814) +`define SHA512_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR0_STS_LOW (0) +`define SHA512_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR0_STS_MASK (32'h1) +`define SHA512_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR1_STS_LOW (1) +`define SHA512_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR1_STS_MASK (32'h2) +`define SHA512_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR2_STS_LOW (2) +`define SHA512_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR2_STS_MASK (32'h4) +`define SHA512_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR3_STS_LOW (3) +`define SHA512_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR3_STS_MASK (32'h8) +`endif +`ifndef SHA512_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R +`define SHA512_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R (32'h818) +`define SHA512_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_CMD_DONE_STS_LOW (0) +`define SHA512_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_CMD_DONE_STS_MASK (32'h1) +`endif +`ifndef SHA512_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R +`define SHA512_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R (32'h81c) +`define SHA512_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R_ERROR0_TRIG_LOW (0) +`define SHA512_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R_ERROR0_TRIG_MASK (32'h1) +`define SHA512_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R_ERROR1_TRIG_LOW (1) +`define SHA512_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R_ERROR1_TRIG_MASK (32'h2) +`define SHA512_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R_ERROR2_TRIG_LOW (2) +`define SHA512_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R_ERROR2_TRIG_MASK (32'h4) +`define SHA512_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R_ERROR3_TRIG_LOW (3) +`define SHA512_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R_ERROR3_TRIG_MASK (32'h8) +`endif +`ifndef SHA512_REG_INTR_BLOCK_RF_NOTIF_INTR_TRIG_R +`define SHA512_REG_INTR_BLOCK_RF_NOTIF_INTR_TRIG_R (32'h820) +`define SHA512_REG_INTR_BLOCK_RF_NOTIF_INTR_TRIG_R_NOTIF_CMD_DONE_TRIG_LOW (0) +`define SHA512_REG_INTR_BLOCK_RF_NOTIF_INTR_TRIG_R_NOTIF_CMD_DONE_TRIG_MASK (32'h1) +`endif +`ifndef SHA512_REG_INTR_BLOCK_RF_ERROR0_INTR_COUNT_R +`define SHA512_REG_INTR_BLOCK_RF_ERROR0_INTR_COUNT_R (32'h900) +`endif +`ifndef SHA512_REG_INTR_BLOCK_RF_ERROR1_INTR_COUNT_R +`define SHA512_REG_INTR_BLOCK_RF_ERROR1_INTR_COUNT_R (32'h904) +`endif +`ifndef SHA512_REG_INTR_BLOCK_RF_ERROR2_INTR_COUNT_R +`define SHA512_REG_INTR_BLOCK_RF_ERROR2_INTR_COUNT_R (32'h908) +`endif +`ifndef SHA512_REG_INTR_BLOCK_RF_ERROR3_INTR_COUNT_R +`define SHA512_REG_INTR_BLOCK_RF_ERROR3_INTR_COUNT_R (32'h90c) +`endif +`ifndef SHA512_REG_INTR_BLOCK_RF_NOTIF_CMD_DONE_INTR_COUNT_R +`define SHA512_REG_INTR_BLOCK_RF_NOTIF_CMD_DONE_INTR_COUNT_R (32'h980) +`endif +`ifndef SHA512_REG_INTR_BLOCK_RF_ERROR0_INTR_COUNT_INCR_R +`define SHA512_REG_INTR_BLOCK_RF_ERROR0_INTR_COUNT_INCR_R (32'ha00) +`define SHA512_REG_INTR_BLOCK_RF_ERROR0_INTR_COUNT_INCR_R_PULSE_LOW (0) +`define SHA512_REG_INTR_BLOCK_RF_ERROR0_INTR_COUNT_INCR_R_PULSE_MASK (32'h1) +`endif +`ifndef SHA512_REG_INTR_BLOCK_RF_ERROR1_INTR_COUNT_INCR_R +`define SHA512_REG_INTR_BLOCK_RF_ERROR1_INTR_COUNT_INCR_R (32'ha04) +`define SHA512_REG_INTR_BLOCK_RF_ERROR1_INTR_COUNT_INCR_R_PULSE_LOW (0) +`define SHA512_REG_INTR_BLOCK_RF_ERROR1_INTR_COUNT_INCR_R_PULSE_MASK (32'h1) +`endif +`ifndef SHA512_REG_INTR_BLOCK_RF_ERROR2_INTR_COUNT_INCR_R +`define SHA512_REG_INTR_BLOCK_RF_ERROR2_INTR_COUNT_INCR_R (32'ha08) +`define SHA512_REG_INTR_BLOCK_RF_ERROR2_INTR_COUNT_INCR_R_PULSE_LOW (0) +`define SHA512_REG_INTR_BLOCK_RF_ERROR2_INTR_COUNT_INCR_R_PULSE_MASK (32'h1) +`endif +`ifndef SHA512_REG_INTR_BLOCK_RF_ERROR3_INTR_COUNT_INCR_R +`define SHA512_REG_INTR_BLOCK_RF_ERROR3_INTR_COUNT_INCR_R (32'ha0c) +`define SHA512_REG_INTR_BLOCK_RF_ERROR3_INTR_COUNT_INCR_R_PULSE_LOW (0) +`define SHA512_REG_INTR_BLOCK_RF_ERROR3_INTR_COUNT_INCR_R_PULSE_MASK (32'h1) +`endif +`ifndef SHA512_REG_INTR_BLOCK_RF_NOTIF_CMD_DONE_INTR_COUNT_INCR_R +`define SHA512_REG_INTR_BLOCK_RF_NOTIF_CMD_DONE_INTR_COUNT_INCR_R (32'ha10) +`define SHA512_REG_INTR_BLOCK_RF_NOTIF_CMD_DONE_INTR_COUNT_INCR_R_PULSE_LOW (0) +`define SHA512_REG_INTR_BLOCK_RF_NOTIF_CMD_DONE_INTR_COUNT_INCR_R_PULSE_MASK (32'h1) +`endif +`ifndef SHA256_REG_SHA256_NAME_0 +`define SHA256_REG_SHA256_NAME_0 (32'h0) +`endif +`ifndef SHA256_REG_SHA256_NAME_1 +`define SHA256_REG_SHA256_NAME_1 (32'h4) +`endif +`ifndef SHA256_REG_SHA256_VERSION_0 +`define SHA256_REG_SHA256_VERSION_0 (32'h8) +`endif +`ifndef SHA256_REG_SHA256_VERSION_1 +`define SHA256_REG_SHA256_VERSION_1 (32'hc) +`endif +`ifndef SHA256_REG_SHA256_CTRL +`define SHA256_REG_SHA256_CTRL (32'h10) +`define SHA256_REG_SHA256_CTRL_INIT_LOW (0) +`define SHA256_REG_SHA256_CTRL_INIT_MASK (32'h1) +`define SHA256_REG_SHA256_CTRL_NEXT_LOW (1) +`define SHA256_REG_SHA256_CTRL_NEXT_MASK (32'h2) +`define SHA256_REG_SHA256_CTRL_MODE_LOW (2) +`define SHA256_REG_SHA256_CTRL_MODE_MASK (32'h4) +`define SHA256_REG_SHA256_CTRL_ZEROIZE_LOW (3) +`define SHA256_REG_SHA256_CTRL_ZEROIZE_MASK (32'h8) +`define SHA256_REG_SHA256_CTRL_WNTZ_MODE_LOW (4) +`define SHA256_REG_SHA256_CTRL_WNTZ_MODE_MASK (32'h10) +`define SHA256_REG_SHA256_CTRL_WNTZ_W_LOW (5) +`define SHA256_REG_SHA256_CTRL_WNTZ_W_MASK (32'h1e0) +`define SHA256_REG_SHA256_CTRL_WNTZ_N_MODE_LOW (9) +`define SHA256_REG_SHA256_CTRL_WNTZ_N_MODE_MASK (32'h200) +`endif +`ifndef SHA256_REG_SHA256_STATUS +`define SHA256_REG_SHA256_STATUS (32'h18) +`define SHA256_REG_SHA256_STATUS_READY_LOW (0) +`define SHA256_REG_SHA256_STATUS_READY_MASK (32'h1) +`define SHA256_REG_SHA256_STATUS_VALID_LOW (1) +`define SHA256_REG_SHA256_STATUS_VALID_MASK (32'h2) +`define SHA256_REG_SHA256_STATUS_WNTZ_BUSY_LOW (2) +`define SHA256_REG_SHA256_STATUS_WNTZ_BUSY_MASK (32'h4) +`endif +`ifndef SHA256_REG_SHA256_BLOCK_0 +`define SHA256_REG_SHA256_BLOCK_0 (32'h80) +`endif +`ifndef SHA256_REG_SHA256_BLOCK_1 +`define SHA256_REG_SHA256_BLOCK_1 (32'h84) +`endif +`ifndef SHA256_REG_SHA256_BLOCK_2 +`define SHA256_REG_SHA256_BLOCK_2 (32'h88) +`endif +`ifndef SHA256_REG_SHA256_BLOCK_3 +`define SHA256_REG_SHA256_BLOCK_3 (32'h8c) +`endif +`ifndef SHA256_REG_SHA256_BLOCK_4 +`define SHA256_REG_SHA256_BLOCK_4 (32'h90) +`endif +`ifndef SHA256_REG_SHA256_BLOCK_5 +`define SHA256_REG_SHA256_BLOCK_5 (32'h94) +`endif +`ifndef SHA256_REG_SHA256_BLOCK_6 +`define SHA256_REG_SHA256_BLOCK_6 (32'h98) +`endif +`ifndef SHA256_REG_SHA256_BLOCK_7 +`define SHA256_REG_SHA256_BLOCK_7 (32'h9c) +`endif +`ifndef SHA256_REG_SHA256_BLOCK_8 +`define SHA256_REG_SHA256_BLOCK_8 (32'ha0) +`endif +`ifndef SHA256_REG_SHA256_BLOCK_9 +`define SHA256_REG_SHA256_BLOCK_9 (32'ha4) +`endif +`ifndef SHA256_REG_SHA256_BLOCK_10 +`define SHA256_REG_SHA256_BLOCK_10 (32'ha8) +`endif +`ifndef SHA256_REG_SHA256_BLOCK_11 +`define SHA256_REG_SHA256_BLOCK_11 (32'hac) +`endif +`ifndef SHA256_REG_SHA256_BLOCK_12 +`define SHA256_REG_SHA256_BLOCK_12 (32'hb0) +`endif +`ifndef SHA256_REG_SHA256_BLOCK_13 +`define SHA256_REG_SHA256_BLOCK_13 (32'hb4) +`endif +`ifndef SHA256_REG_SHA256_BLOCK_14 +`define SHA256_REG_SHA256_BLOCK_14 (32'hb8) +`endif +`ifndef SHA256_REG_SHA256_BLOCK_15 +`define SHA256_REG_SHA256_BLOCK_15 (32'hbc) +`endif +`ifndef SHA256_REG_SHA256_DIGEST_0 +`define SHA256_REG_SHA256_DIGEST_0 (32'h100) +`endif +`ifndef SHA256_REG_SHA256_DIGEST_1 +`define SHA256_REG_SHA256_DIGEST_1 (32'h104) +`endif +`ifndef SHA256_REG_SHA256_DIGEST_2 +`define SHA256_REG_SHA256_DIGEST_2 (32'h108) +`endif +`ifndef SHA256_REG_SHA256_DIGEST_3 +`define SHA256_REG_SHA256_DIGEST_3 (32'h10c) +`endif +`ifndef SHA256_REG_SHA256_DIGEST_4 +`define SHA256_REG_SHA256_DIGEST_4 (32'h110) +`endif +`ifndef SHA256_REG_SHA256_DIGEST_5 +`define SHA256_REG_SHA256_DIGEST_5 (32'h114) +`endif +`ifndef SHA256_REG_SHA256_DIGEST_6 +`define SHA256_REG_SHA256_DIGEST_6 (32'h118) +`endif +`ifndef SHA256_REG_SHA256_DIGEST_7 +`define SHA256_REG_SHA256_DIGEST_7 (32'h11c) +`endif +`ifndef SHA256_REG_INTR_BLOCK_RF_GLOBAL_INTR_EN_R +`define SHA256_REG_INTR_BLOCK_RF_GLOBAL_INTR_EN_R (32'h800) +`define SHA256_REG_INTR_BLOCK_RF_GLOBAL_INTR_EN_R_ERROR_EN_LOW (0) +`define SHA256_REG_INTR_BLOCK_RF_GLOBAL_INTR_EN_R_ERROR_EN_MASK (32'h1) +`define SHA256_REG_INTR_BLOCK_RF_GLOBAL_INTR_EN_R_NOTIF_EN_LOW (1) +`define SHA256_REG_INTR_BLOCK_RF_GLOBAL_INTR_EN_R_NOTIF_EN_MASK (32'h2) +`endif +`ifndef SHA256_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R +`define SHA256_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R (32'h804) +`define SHA256_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R_ERROR0_EN_LOW (0) +`define SHA256_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R_ERROR0_EN_MASK (32'h1) +`define SHA256_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R_ERROR1_EN_LOW (1) +`define SHA256_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R_ERROR1_EN_MASK (32'h2) +`define SHA256_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R_ERROR2_EN_LOW (2) +`define SHA256_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R_ERROR2_EN_MASK (32'h4) +`define SHA256_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R_ERROR3_EN_LOW (3) +`define SHA256_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R_ERROR3_EN_MASK (32'h8) +`endif +`ifndef SHA256_REG_INTR_BLOCK_RF_NOTIF_INTR_EN_R +`define SHA256_REG_INTR_BLOCK_RF_NOTIF_INTR_EN_R (32'h808) +`define SHA256_REG_INTR_BLOCK_RF_NOTIF_INTR_EN_R_NOTIF_CMD_DONE_EN_LOW (0) +`define SHA256_REG_INTR_BLOCK_RF_NOTIF_INTR_EN_R_NOTIF_CMD_DONE_EN_MASK (32'h1) +`endif +`ifndef SHA256_REG_INTR_BLOCK_RF_ERROR_GLOBAL_INTR_R +`define SHA256_REG_INTR_BLOCK_RF_ERROR_GLOBAL_INTR_R (32'h80c) +`define SHA256_REG_INTR_BLOCK_RF_ERROR_GLOBAL_INTR_R_AGG_STS_LOW (0) +`define SHA256_REG_INTR_BLOCK_RF_ERROR_GLOBAL_INTR_R_AGG_STS_MASK (32'h1) +`endif +`ifndef SHA256_REG_INTR_BLOCK_RF_NOTIF_GLOBAL_INTR_R +`define SHA256_REG_INTR_BLOCK_RF_NOTIF_GLOBAL_INTR_R (32'h810) +`define SHA256_REG_INTR_BLOCK_RF_NOTIF_GLOBAL_INTR_R_AGG_STS_LOW (0) +`define SHA256_REG_INTR_BLOCK_RF_NOTIF_GLOBAL_INTR_R_AGG_STS_MASK (32'h1) +`endif +`ifndef SHA256_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R +`define SHA256_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R (32'h814) +`define SHA256_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR0_STS_LOW (0) +`define SHA256_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR0_STS_MASK (32'h1) +`define SHA256_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR1_STS_LOW (1) +`define SHA256_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR1_STS_MASK (32'h2) +`define SHA256_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR2_STS_LOW (2) +`define SHA256_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR2_STS_MASK (32'h4) +`define SHA256_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR3_STS_LOW (3) +`define SHA256_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR3_STS_MASK (32'h8) +`endif +`ifndef SHA256_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R +`define SHA256_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R (32'h818) +`define SHA256_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_CMD_DONE_STS_LOW (0) +`define SHA256_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_CMD_DONE_STS_MASK (32'h1) +`endif +`ifndef SHA256_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R +`define SHA256_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R (32'h81c) +`define SHA256_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R_ERROR0_TRIG_LOW (0) +`define SHA256_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R_ERROR0_TRIG_MASK (32'h1) +`define SHA256_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R_ERROR1_TRIG_LOW (1) +`define SHA256_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R_ERROR1_TRIG_MASK (32'h2) +`define SHA256_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R_ERROR2_TRIG_LOW (2) +`define SHA256_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R_ERROR2_TRIG_MASK (32'h4) +`define SHA256_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R_ERROR3_TRIG_LOW (3) +`define SHA256_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R_ERROR3_TRIG_MASK (32'h8) +`endif +`ifndef SHA256_REG_INTR_BLOCK_RF_NOTIF_INTR_TRIG_R +`define SHA256_REG_INTR_BLOCK_RF_NOTIF_INTR_TRIG_R (32'h820) +`define SHA256_REG_INTR_BLOCK_RF_NOTIF_INTR_TRIG_R_NOTIF_CMD_DONE_TRIG_LOW (0) +`define SHA256_REG_INTR_BLOCK_RF_NOTIF_INTR_TRIG_R_NOTIF_CMD_DONE_TRIG_MASK (32'h1) +`endif +`ifndef SHA256_REG_INTR_BLOCK_RF_ERROR0_INTR_COUNT_R +`define SHA256_REG_INTR_BLOCK_RF_ERROR0_INTR_COUNT_R (32'h900) +`endif +`ifndef SHA256_REG_INTR_BLOCK_RF_ERROR1_INTR_COUNT_R +`define SHA256_REG_INTR_BLOCK_RF_ERROR1_INTR_COUNT_R (32'h904) +`endif +`ifndef SHA256_REG_INTR_BLOCK_RF_ERROR2_INTR_COUNT_R +`define SHA256_REG_INTR_BLOCK_RF_ERROR2_INTR_COUNT_R (32'h908) +`endif +`ifndef SHA256_REG_INTR_BLOCK_RF_ERROR3_INTR_COUNT_R +`define SHA256_REG_INTR_BLOCK_RF_ERROR3_INTR_COUNT_R (32'h90c) +`endif +`ifndef SHA256_REG_INTR_BLOCK_RF_NOTIF_CMD_DONE_INTR_COUNT_R +`define SHA256_REG_INTR_BLOCK_RF_NOTIF_CMD_DONE_INTR_COUNT_R (32'h980) +`endif +`ifndef SHA256_REG_INTR_BLOCK_RF_ERROR0_INTR_COUNT_INCR_R +`define SHA256_REG_INTR_BLOCK_RF_ERROR0_INTR_COUNT_INCR_R (32'ha00) +`define SHA256_REG_INTR_BLOCK_RF_ERROR0_INTR_COUNT_INCR_R_PULSE_LOW (0) +`define SHA256_REG_INTR_BLOCK_RF_ERROR0_INTR_COUNT_INCR_R_PULSE_MASK (32'h1) +`endif +`ifndef SHA256_REG_INTR_BLOCK_RF_ERROR1_INTR_COUNT_INCR_R +`define SHA256_REG_INTR_BLOCK_RF_ERROR1_INTR_COUNT_INCR_R (32'ha04) +`define SHA256_REG_INTR_BLOCK_RF_ERROR1_INTR_COUNT_INCR_R_PULSE_LOW (0) +`define SHA256_REG_INTR_BLOCK_RF_ERROR1_INTR_COUNT_INCR_R_PULSE_MASK (32'h1) +`endif +`ifndef SHA256_REG_INTR_BLOCK_RF_ERROR2_INTR_COUNT_INCR_R +`define SHA256_REG_INTR_BLOCK_RF_ERROR2_INTR_COUNT_INCR_R (32'ha08) +`define SHA256_REG_INTR_BLOCK_RF_ERROR2_INTR_COUNT_INCR_R_PULSE_LOW (0) +`define SHA256_REG_INTR_BLOCK_RF_ERROR2_INTR_COUNT_INCR_R_PULSE_MASK (32'h1) +`endif +`ifndef SHA256_REG_INTR_BLOCK_RF_ERROR3_INTR_COUNT_INCR_R +`define SHA256_REG_INTR_BLOCK_RF_ERROR3_INTR_COUNT_INCR_R (32'ha0c) +`define SHA256_REG_INTR_BLOCK_RF_ERROR3_INTR_COUNT_INCR_R_PULSE_LOW (0) +`define SHA256_REG_INTR_BLOCK_RF_ERROR3_INTR_COUNT_INCR_R_PULSE_MASK (32'h1) +`endif +`ifndef SHA256_REG_INTR_BLOCK_RF_NOTIF_CMD_DONE_INTR_COUNT_INCR_R +`define SHA256_REG_INTR_BLOCK_RF_NOTIF_CMD_DONE_INTR_COUNT_INCR_R (32'ha10) +`define SHA256_REG_INTR_BLOCK_RF_NOTIF_CMD_DONE_INTR_COUNT_INCR_R_PULSE_LOW (0) +`define SHA256_REG_INTR_BLOCK_RF_NOTIF_CMD_DONE_INTR_COUNT_INCR_R_PULSE_MASK (32'h1) +`endif +`ifndef ABR_REG_MLDSA_NAME_0 +`define ABR_REG_MLDSA_NAME_0 (32'h0) +`endif +`ifndef ABR_REG_MLDSA_NAME_1 +`define ABR_REG_MLDSA_NAME_1 (32'h4) +`endif +`ifndef ABR_REG_MLDSA_VERSION_0 +`define ABR_REG_MLDSA_VERSION_0 (32'h8) +`endif +`ifndef ABR_REG_MLDSA_VERSION_1 +`define ABR_REG_MLDSA_VERSION_1 (32'hc) +`endif +`ifndef ABR_REG_MLDSA_CTRL +`define ABR_REG_MLDSA_CTRL (32'h10) +`define ABR_REG_MLDSA_CTRL_CTRL_LOW (0) +`define ABR_REG_MLDSA_CTRL_CTRL_MASK (32'h7) +`define ABR_REG_MLDSA_CTRL_ZEROIZE_LOW (3) +`define ABR_REG_MLDSA_CTRL_ZEROIZE_MASK (32'h8) +`define ABR_REG_MLDSA_CTRL_PCR_SIGN_LOW (4) +`define ABR_REG_MLDSA_CTRL_PCR_SIGN_MASK (32'h10) +`define ABR_REG_MLDSA_CTRL_EXTERNAL_MU_LOW (5) +`define ABR_REG_MLDSA_CTRL_EXTERNAL_MU_MASK (32'h20) +`define ABR_REG_MLDSA_CTRL_STREAM_MSG_LOW (6) +`define ABR_REG_MLDSA_CTRL_STREAM_MSG_MASK (32'h40) +`endif +`ifndef ABR_REG_MLDSA_STATUS +`define ABR_REG_MLDSA_STATUS (32'h14) +`define ABR_REG_MLDSA_STATUS_READY_LOW (0) +`define ABR_REG_MLDSA_STATUS_READY_MASK (32'h1) +`define ABR_REG_MLDSA_STATUS_VALID_LOW (1) +`define ABR_REG_MLDSA_STATUS_VALID_MASK (32'h2) +`define ABR_REG_MLDSA_STATUS_MSG_STREAM_READY_LOW (2) +`define ABR_REG_MLDSA_STATUS_MSG_STREAM_READY_MASK (32'h4) +`define ABR_REG_MLDSA_STATUS_ERROR_LOW (3) +`define ABR_REG_MLDSA_STATUS_ERROR_MASK (32'h8) +`endif +`ifndef ABR_REG_ABR_ENTROPY_0 +`define ABR_REG_ABR_ENTROPY_0 (32'h18) +`endif +`ifndef ABR_REG_ABR_ENTROPY_1 +`define ABR_REG_ABR_ENTROPY_1 (32'h1c) +`endif +`ifndef ABR_REG_ABR_ENTROPY_2 +`define ABR_REG_ABR_ENTROPY_2 (32'h20) +`endif +`ifndef ABR_REG_ABR_ENTROPY_3 +`define ABR_REG_ABR_ENTROPY_3 (32'h24) +`endif +`ifndef ABR_REG_ABR_ENTROPY_4 +`define ABR_REG_ABR_ENTROPY_4 (32'h28) +`endif +`ifndef ABR_REG_ABR_ENTROPY_5 +`define ABR_REG_ABR_ENTROPY_5 (32'h2c) +`endif +`ifndef ABR_REG_ABR_ENTROPY_6 +`define ABR_REG_ABR_ENTROPY_6 (32'h30) +`endif +`ifndef ABR_REG_ABR_ENTROPY_7 +`define ABR_REG_ABR_ENTROPY_7 (32'h34) +`endif +`ifndef ABR_REG_ABR_ENTROPY_8 +`define ABR_REG_ABR_ENTROPY_8 (32'h38) +`endif +`ifndef ABR_REG_ABR_ENTROPY_9 +`define ABR_REG_ABR_ENTROPY_9 (32'h3c) +`endif +`ifndef ABR_REG_ABR_ENTROPY_10 +`define ABR_REG_ABR_ENTROPY_10 (32'h40) +`endif +`ifndef ABR_REG_ABR_ENTROPY_11 +`define ABR_REG_ABR_ENTROPY_11 (32'h44) +`endif +`ifndef ABR_REG_ABR_ENTROPY_12 +`define ABR_REG_ABR_ENTROPY_12 (32'h48) +`endif +`ifndef ABR_REG_ABR_ENTROPY_13 +`define ABR_REG_ABR_ENTROPY_13 (32'h4c) +`endif +`ifndef ABR_REG_ABR_ENTROPY_14 +`define ABR_REG_ABR_ENTROPY_14 (32'h50) +`endif +`ifndef ABR_REG_ABR_ENTROPY_15 +`define ABR_REG_ABR_ENTROPY_15 (32'h54) +`endif +`ifndef ABR_REG_MLDSA_SEED_0 +`define ABR_REG_MLDSA_SEED_0 (32'h58) +`endif +`ifndef ABR_REG_MLDSA_SEED_1 +`define ABR_REG_MLDSA_SEED_1 (32'h5c) +`endif +`ifndef ABR_REG_MLDSA_SEED_2 +`define ABR_REG_MLDSA_SEED_2 (32'h60) +`endif +`ifndef ABR_REG_MLDSA_SEED_3 +`define ABR_REG_MLDSA_SEED_3 (32'h64) +`endif +`ifndef ABR_REG_MLDSA_SEED_4 +`define ABR_REG_MLDSA_SEED_4 (32'h68) +`endif +`ifndef ABR_REG_MLDSA_SEED_5 +`define ABR_REG_MLDSA_SEED_5 (32'h6c) +`endif +`ifndef ABR_REG_MLDSA_SEED_6 +`define ABR_REG_MLDSA_SEED_6 (32'h70) +`endif +`ifndef ABR_REG_MLDSA_SEED_7 +`define ABR_REG_MLDSA_SEED_7 (32'h74) +`endif +`ifndef ABR_REG_MLDSA_SIGN_RND_0 +`define ABR_REG_MLDSA_SIGN_RND_0 (32'h78) +`endif +`ifndef ABR_REG_MLDSA_SIGN_RND_1 +`define ABR_REG_MLDSA_SIGN_RND_1 (32'h7c) +`endif +`ifndef ABR_REG_MLDSA_SIGN_RND_2 +`define ABR_REG_MLDSA_SIGN_RND_2 (32'h80) +`endif +`ifndef ABR_REG_MLDSA_SIGN_RND_3 +`define ABR_REG_MLDSA_SIGN_RND_3 (32'h84) +`endif +`ifndef ABR_REG_MLDSA_SIGN_RND_4 +`define ABR_REG_MLDSA_SIGN_RND_4 (32'h88) +`endif +`ifndef ABR_REG_MLDSA_SIGN_RND_5 +`define ABR_REG_MLDSA_SIGN_RND_5 (32'h8c) +`endif +`ifndef ABR_REG_MLDSA_SIGN_RND_6 +`define ABR_REG_MLDSA_SIGN_RND_6 (32'h90) +`endif +`ifndef ABR_REG_MLDSA_SIGN_RND_7 +`define ABR_REG_MLDSA_SIGN_RND_7 (32'h94) +`endif +`ifndef ABR_REG_MLDSA_MSG_0 +`define ABR_REG_MLDSA_MSG_0 (32'h98) +`endif +`ifndef ABR_REG_MLDSA_MSG_1 +`define ABR_REG_MLDSA_MSG_1 (32'h9c) +`endif +`ifndef ABR_REG_MLDSA_MSG_2 +`define ABR_REG_MLDSA_MSG_2 (32'ha0) +`endif +`ifndef ABR_REG_MLDSA_MSG_3 +`define ABR_REG_MLDSA_MSG_3 (32'ha4) +`endif +`ifndef ABR_REG_MLDSA_MSG_4 +`define ABR_REG_MLDSA_MSG_4 (32'ha8) +`endif +`ifndef ABR_REG_MLDSA_MSG_5 +`define ABR_REG_MLDSA_MSG_5 (32'hac) +`endif +`ifndef ABR_REG_MLDSA_MSG_6 +`define ABR_REG_MLDSA_MSG_6 (32'hb0) +`endif +`ifndef ABR_REG_MLDSA_MSG_7 +`define ABR_REG_MLDSA_MSG_7 (32'hb4) +`endif +`ifndef ABR_REG_MLDSA_MSG_8 +`define ABR_REG_MLDSA_MSG_8 (32'hb8) +`endif +`ifndef ABR_REG_MLDSA_MSG_9 +`define ABR_REG_MLDSA_MSG_9 (32'hbc) +`endif +`ifndef ABR_REG_MLDSA_MSG_10 +`define ABR_REG_MLDSA_MSG_10 (32'hc0) +`endif +`ifndef ABR_REG_MLDSA_MSG_11 +`define ABR_REG_MLDSA_MSG_11 (32'hc4) +`endif +`ifndef ABR_REG_MLDSA_MSG_12 +`define ABR_REG_MLDSA_MSG_12 (32'hc8) +`endif +`ifndef ABR_REG_MLDSA_MSG_13 +`define ABR_REG_MLDSA_MSG_13 (32'hcc) +`endif +`ifndef ABR_REG_MLDSA_MSG_14 +`define ABR_REG_MLDSA_MSG_14 (32'hd0) +`endif +`ifndef ABR_REG_MLDSA_MSG_15 +`define ABR_REG_MLDSA_MSG_15 (32'hd4) +`endif +`ifndef ABR_REG_MLDSA_VERIFY_RES_0 +`define ABR_REG_MLDSA_VERIFY_RES_0 (32'hd8) +`endif +`ifndef ABR_REG_MLDSA_VERIFY_RES_1 +`define ABR_REG_MLDSA_VERIFY_RES_1 (32'hdc) +`endif +`ifndef ABR_REG_MLDSA_VERIFY_RES_2 +`define ABR_REG_MLDSA_VERIFY_RES_2 (32'he0) +`endif +`ifndef ABR_REG_MLDSA_VERIFY_RES_3 +`define ABR_REG_MLDSA_VERIFY_RES_3 (32'he4) +`endif +`ifndef ABR_REG_MLDSA_VERIFY_RES_4 +`define ABR_REG_MLDSA_VERIFY_RES_4 (32'he8) +`endif +`ifndef ABR_REG_MLDSA_VERIFY_RES_5 +`define ABR_REG_MLDSA_VERIFY_RES_5 (32'hec) +`endif +`ifndef ABR_REG_MLDSA_VERIFY_RES_6 +`define ABR_REG_MLDSA_VERIFY_RES_6 (32'hf0) +`endif +`ifndef ABR_REG_MLDSA_VERIFY_RES_7 +`define ABR_REG_MLDSA_VERIFY_RES_7 (32'hf4) +`endif +`ifndef ABR_REG_MLDSA_VERIFY_RES_8 +`define ABR_REG_MLDSA_VERIFY_RES_8 (32'hf8) +`endif +`ifndef ABR_REG_MLDSA_VERIFY_RES_9 +`define ABR_REG_MLDSA_VERIFY_RES_9 (32'hfc) +`endif +`ifndef ABR_REG_MLDSA_VERIFY_RES_10 +`define ABR_REG_MLDSA_VERIFY_RES_10 (32'h100) +`endif +`ifndef ABR_REG_MLDSA_VERIFY_RES_11 +`define ABR_REG_MLDSA_VERIFY_RES_11 (32'h104) +`endif +`ifndef ABR_REG_MLDSA_VERIFY_RES_12 +`define ABR_REG_MLDSA_VERIFY_RES_12 (32'h108) +`endif +`ifndef ABR_REG_MLDSA_VERIFY_RES_13 +`define ABR_REG_MLDSA_VERIFY_RES_13 (32'h10c) +`endif +`ifndef ABR_REG_MLDSA_VERIFY_RES_14 +`define ABR_REG_MLDSA_VERIFY_RES_14 (32'h110) +`endif +`ifndef ABR_REG_MLDSA_VERIFY_RES_15 +`define ABR_REG_MLDSA_VERIFY_RES_15 (32'h114) +`endif +`ifndef ABR_REG_MLDSA_EXTERNAL_MU_0 +`define ABR_REG_MLDSA_EXTERNAL_MU_0 (32'h118) +`endif +`ifndef ABR_REG_MLDSA_EXTERNAL_MU_1 +`define ABR_REG_MLDSA_EXTERNAL_MU_1 (32'h11c) +`endif +`ifndef ABR_REG_MLDSA_EXTERNAL_MU_2 +`define ABR_REG_MLDSA_EXTERNAL_MU_2 (32'h120) +`endif +`ifndef ABR_REG_MLDSA_EXTERNAL_MU_3 +`define ABR_REG_MLDSA_EXTERNAL_MU_3 (32'h124) +`endif +`ifndef ABR_REG_MLDSA_EXTERNAL_MU_4 +`define ABR_REG_MLDSA_EXTERNAL_MU_4 (32'h128) +`endif +`ifndef ABR_REG_MLDSA_EXTERNAL_MU_5 +`define ABR_REG_MLDSA_EXTERNAL_MU_5 (32'h12c) +`endif +`ifndef ABR_REG_MLDSA_EXTERNAL_MU_6 +`define ABR_REG_MLDSA_EXTERNAL_MU_6 (32'h130) +`endif +`ifndef ABR_REG_MLDSA_EXTERNAL_MU_7 +`define ABR_REG_MLDSA_EXTERNAL_MU_7 (32'h134) +`endif +`ifndef ABR_REG_MLDSA_EXTERNAL_MU_8 +`define ABR_REG_MLDSA_EXTERNAL_MU_8 (32'h138) +`endif +`ifndef ABR_REG_MLDSA_EXTERNAL_MU_9 +`define ABR_REG_MLDSA_EXTERNAL_MU_9 (32'h13c) +`endif +`ifndef ABR_REG_MLDSA_EXTERNAL_MU_10 +`define ABR_REG_MLDSA_EXTERNAL_MU_10 (32'h140) +`endif +`ifndef ABR_REG_MLDSA_EXTERNAL_MU_11 +`define ABR_REG_MLDSA_EXTERNAL_MU_11 (32'h144) +`endif +`ifndef ABR_REG_MLDSA_EXTERNAL_MU_12 +`define ABR_REG_MLDSA_EXTERNAL_MU_12 (32'h148) +`endif +`ifndef ABR_REG_MLDSA_EXTERNAL_MU_13 +`define ABR_REG_MLDSA_EXTERNAL_MU_13 (32'h14c) +`endif +`ifndef ABR_REG_MLDSA_EXTERNAL_MU_14 +`define ABR_REG_MLDSA_EXTERNAL_MU_14 (32'h150) +`endif +`ifndef ABR_REG_MLDSA_EXTERNAL_MU_15 +`define ABR_REG_MLDSA_EXTERNAL_MU_15 (32'h154) +`endif +`ifndef ABR_REG_MLDSA_MSG_STROBE +`define ABR_REG_MLDSA_MSG_STROBE (32'h158) +`define ABR_REG_MLDSA_MSG_STROBE_STROBE_LOW (0) +`define ABR_REG_MLDSA_MSG_STROBE_STROBE_MASK (32'hf) +`endif +`ifndef ABR_REG_MLDSA_CTX_CONFIG +`define ABR_REG_MLDSA_CTX_CONFIG (32'h15c) +`define ABR_REG_MLDSA_CTX_CONFIG_CTX_SIZE_LOW (0) +`define ABR_REG_MLDSA_CTX_CONFIG_CTX_SIZE_MASK (32'hff) +`endif +`ifndef ABR_REG_MLDSA_CTX_0 +`define ABR_REG_MLDSA_CTX_0 (32'h160) +`endif +`ifndef ABR_REG_MLDSA_CTX_1 +`define ABR_REG_MLDSA_CTX_1 (32'h164) +`endif +`ifndef ABR_REG_MLDSA_CTX_2 +`define ABR_REG_MLDSA_CTX_2 (32'h168) +`endif +`ifndef ABR_REG_MLDSA_CTX_3 +`define ABR_REG_MLDSA_CTX_3 (32'h16c) +`endif +`ifndef ABR_REG_MLDSA_CTX_4 +`define ABR_REG_MLDSA_CTX_4 (32'h170) +`endif +`ifndef ABR_REG_MLDSA_CTX_5 +`define ABR_REG_MLDSA_CTX_5 (32'h174) +`endif +`ifndef ABR_REG_MLDSA_CTX_6 +`define ABR_REG_MLDSA_CTX_6 (32'h178) +`endif +`ifndef ABR_REG_MLDSA_CTX_7 +`define ABR_REG_MLDSA_CTX_7 (32'h17c) +`endif +`ifndef ABR_REG_MLDSA_CTX_8 +`define ABR_REG_MLDSA_CTX_8 (32'h180) +`endif +`ifndef ABR_REG_MLDSA_CTX_9 +`define ABR_REG_MLDSA_CTX_9 (32'h184) +`endif +`ifndef ABR_REG_MLDSA_CTX_10 +`define ABR_REG_MLDSA_CTX_10 (32'h188) +`endif +`ifndef ABR_REG_MLDSA_CTX_11 +`define ABR_REG_MLDSA_CTX_11 (32'h18c) +`endif +`ifndef ABR_REG_MLDSA_CTX_12 +`define ABR_REG_MLDSA_CTX_12 (32'h190) +`endif +`ifndef ABR_REG_MLDSA_CTX_13 +`define ABR_REG_MLDSA_CTX_13 (32'h194) +`endif +`ifndef ABR_REG_MLDSA_CTX_14 +`define ABR_REG_MLDSA_CTX_14 (32'h198) +`endif +`ifndef ABR_REG_MLDSA_CTX_15 +`define ABR_REG_MLDSA_CTX_15 (32'h19c) +`endif +`ifndef ABR_REG_MLDSA_CTX_16 +`define ABR_REG_MLDSA_CTX_16 (32'h1a0) +`endif +`ifndef ABR_REG_MLDSA_CTX_17 +`define ABR_REG_MLDSA_CTX_17 (32'h1a4) +`endif +`ifndef ABR_REG_MLDSA_CTX_18 +`define ABR_REG_MLDSA_CTX_18 (32'h1a8) +`endif +`ifndef ABR_REG_MLDSA_CTX_19 +`define ABR_REG_MLDSA_CTX_19 (32'h1ac) +`endif +`ifndef ABR_REG_MLDSA_CTX_20 +`define ABR_REG_MLDSA_CTX_20 (32'h1b0) +`endif +`ifndef ABR_REG_MLDSA_CTX_21 +`define ABR_REG_MLDSA_CTX_21 (32'h1b4) +`endif +`ifndef ABR_REG_MLDSA_CTX_22 +`define ABR_REG_MLDSA_CTX_22 (32'h1b8) +`endif +`ifndef ABR_REG_MLDSA_CTX_23 +`define ABR_REG_MLDSA_CTX_23 (32'h1bc) +`endif +`ifndef ABR_REG_MLDSA_CTX_24 +`define ABR_REG_MLDSA_CTX_24 (32'h1c0) +`endif +`ifndef ABR_REG_MLDSA_CTX_25 +`define ABR_REG_MLDSA_CTX_25 (32'h1c4) +`endif +`ifndef ABR_REG_MLDSA_CTX_26 +`define ABR_REG_MLDSA_CTX_26 (32'h1c8) +`endif +`ifndef ABR_REG_MLDSA_CTX_27 +`define ABR_REG_MLDSA_CTX_27 (32'h1cc) +`endif +`ifndef ABR_REG_MLDSA_CTX_28 +`define ABR_REG_MLDSA_CTX_28 (32'h1d0) +`endif +`ifndef ABR_REG_MLDSA_CTX_29 +`define ABR_REG_MLDSA_CTX_29 (32'h1d4) +`endif +`ifndef ABR_REG_MLDSA_CTX_30 +`define ABR_REG_MLDSA_CTX_30 (32'h1d8) +`endif +`ifndef ABR_REG_MLDSA_CTX_31 +`define ABR_REG_MLDSA_CTX_31 (32'h1dc) +`endif +`ifndef ABR_REG_MLDSA_CTX_32 +`define ABR_REG_MLDSA_CTX_32 (32'h1e0) +`endif +`ifndef ABR_REG_MLDSA_CTX_33 +`define ABR_REG_MLDSA_CTX_33 (32'h1e4) +`endif +`ifndef ABR_REG_MLDSA_CTX_34 +`define ABR_REG_MLDSA_CTX_34 (32'h1e8) +`endif +`ifndef ABR_REG_MLDSA_CTX_35 +`define ABR_REG_MLDSA_CTX_35 (32'h1ec) +`endif +`ifndef ABR_REG_MLDSA_CTX_36 +`define ABR_REG_MLDSA_CTX_36 (32'h1f0) +`endif +`ifndef ABR_REG_MLDSA_CTX_37 +`define ABR_REG_MLDSA_CTX_37 (32'h1f4) +`endif +`ifndef ABR_REG_MLDSA_CTX_38 +`define ABR_REG_MLDSA_CTX_38 (32'h1f8) +`endif +`ifndef ABR_REG_MLDSA_CTX_39 +`define ABR_REG_MLDSA_CTX_39 (32'h1fc) +`endif +`ifndef ABR_REG_MLDSA_CTX_40 +`define ABR_REG_MLDSA_CTX_40 (32'h200) +`endif +`ifndef ABR_REG_MLDSA_CTX_41 +`define ABR_REG_MLDSA_CTX_41 (32'h204) +`endif +`ifndef ABR_REG_MLDSA_CTX_42 +`define ABR_REG_MLDSA_CTX_42 (32'h208) +`endif +`ifndef ABR_REG_MLDSA_CTX_43 +`define ABR_REG_MLDSA_CTX_43 (32'h20c) +`endif +`ifndef ABR_REG_MLDSA_CTX_44 +`define ABR_REG_MLDSA_CTX_44 (32'h210) +`endif +`ifndef ABR_REG_MLDSA_CTX_45 +`define ABR_REG_MLDSA_CTX_45 (32'h214) +`endif +`ifndef ABR_REG_MLDSA_CTX_46 +`define ABR_REG_MLDSA_CTX_46 (32'h218) +`endif +`ifndef ABR_REG_MLDSA_CTX_47 +`define ABR_REG_MLDSA_CTX_47 (32'h21c) +`endif +`ifndef ABR_REG_MLDSA_CTX_48 +`define ABR_REG_MLDSA_CTX_48 (32'h220) +`endif +`ifndef ABR_REG_MLDSA_CTX_49 +`define ABR_REG_MLDSA_CTX_49 (32'h224) +`endif +`ifndef ABR_REG_MLDSA_CTX_50 +`define ABR_REG_MLDSA_CTX_50 (32'h228) +`endif +`ifndef ABR_REG_MLDSA_CTX_51 +`define ABR_REG_MLDSA_CTX_51 (32'h22c) +`endif +`ifndef ABR_REG_MLDSA_CTX_52 +`define ABR_REG_MLDSA_CTX_52 (32'h230) +`endif +`ifndef ABR_REG_MLDSA_CTX_53 +`define ABR_REG_MLDSA_CTX_53 (32'h234) +`endif +`ifndef ABR_REG_MLDSA_CTX_54 +`define ABR_REG_MLDSA_CTX_54 (32'h238) +`endif +`ifndef ABR_REG_MLDSA_CTX_55 +`define ABR_REG_MLDSA_CTX_55 (32'h23c) +`endif +`ifndef ABR_REG_MLDSA_CTX_56 +`define ABR_REG_MLDSA_CTX_56 (32'h240) +`endif +`ifndef ABR_REG_MLDSA_CTX_57 +`define ABR_REG_MLDSA_CTX_57 (32'h244) +`endif +`ifndef ABR_REG_MLDSA_CTX_58 +`define ABR_REG_MLDSA_CTX_58 (32'h248) +`endif +`ifndef ABR_REG_MLDSA_CTX_59 +`define ABR_REG_MLDSA_CTX_59 (32'h24c) +`endif +`ifndef ABR_REG_MLDSA_CTX_60 +`define ABR_REG_MLDSA_CTX_60 (32'h250) +`endif +`ifndef ABR_REG_MLDSA_CTX_61 +`define ABR_REG_MLDSA_CTX_61 (32'h254) +`endif +`ifndef ABR_REG_MLDSA_CTX_62 +`define ABR_REG_MLDSA_CTX_62 (32'h258) +`endif +`ifndef ABR_REG_MLDSA_CTX_63 +`define ABR_REG_MLDSA_CTX_63 (32'h25c) +`endif +`ifndef ABR_REG_KV_MLDSA_SEED_RD_CTRL +`define ABR_REG_KV_MLDSA_SEED_RD_CTRL (32'h8000) +`define ABR_REG_KV_MLDSA_SEED_RD_CTRL_READ_EN_LOW (0) +`define ABR_REG_KV_MLDSA_SEED_RD_CTRL_READ_EN_MASK (32'h1) +`define ABR_REG_KV_MLDSA_SEED_RD_CTRL_READ_ENTRY_LOW (1) +`define ABR_REG_KV_MLDSA_SEED_RD_CTRL_READ_ENTRY_MASK (32'h3e) +`define ABR_REG_KV_MLDSA_SEED_RD_CTRL_PCR_HASH_EXTEND_LOW (6) +`define ABR_REG_KV_MLDSA_SEED_RD_CTRL_PCR_HASH_EXTEND_MASK (32'h40) +`define ABR_REG_KV_MLDSA_SEED_RD_CTRL_RSVD_LOW (7) +`define ABR_REG_KV_MLDSA_SEED_RD_CTRL_RSVD_MASK (32'hffffff80) +`endif +`ifndef ABR_REG_KV_MLDSA_SEED_RD_STATUS +`define ABR_REG_KV_MLDSA_SEED_RD_STATUS (32'h8004) +`define ABR_REG_KV_MLDSA_SEED_RD_STATUS_READY_LOW (0) +`define ABR_REG_KV_MLDSA_SEED_RD_STATUS_READY_MASK (32'h1) +`define ABR_REG_KV_MLDSA_SEED_RD_STATUS_VALID_LOW (1) +`define ABR_REG_KV_MLDSA_SEED_RD_STATUS_VALID_MASK (32'h2) +`define ABR_REG_KV_MLDSA_SEED_RD_STATUS_ERROR_LOW (2) +`define ABR_REG_KV_MLDSA_SEED_RD_STATUS_ERROR_MASK (32'h3fc) +`endif +`ifndef ABR_REG_INTR_BLOCK_RF_GLOBAL_INTR_EN_R +`define ABR_REG_INTR_BLOCK_RF_GLOBAL_INTR_EN_R (32'h8100) +`define ABR_REG_INTR_BLOCK_RF_GLOBAL_INTR_EN_R_ERROR_EN_LOW (0) +`define ABR_REG_INTR_BLOCK_RF_GLOBAL_INTR_EN_R_ERROR_EN_MASK (32'h1) +`define ABR_REG_INTR_BLOCK_RF_GLOBAL_INTR_EN_R_NOTIF_EN_LOW (1) +`define ABR_REG_INTR_BLOCK_RF_GLOBAL_INTR_EN_R_NOTIF_EN_MASK (32'h2) +`endif +`ifndef ABR_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R +`define ABR_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R (32'h8104) +`define ABR_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R_ERROR_INTERNAL_EN_LOW (0) +`define ABR_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R_ERROR_INTERNAL_EN_MASK (32'h1) +`endif +`ifndef ABR_REG_INTR_BLOCK_RF_NOTIF_INTR_EN_R +`define ABR_REG_INTR_BLOCK_RF_NOTIF_INTR_EN_R (32'h8108) +`define ABR_REG_INTR_BLOCK_RF_NOTIF_INTR_EN_R_NOTIF_CMD_DONE_EN_LOW (0) +`define ABR_REG_INTR_BLOCK_RF_NOTIF_INTR_EN_R_NOTIF_CMD_DONE_EN_MASK (32'h1) +`endif +`ifndef ABR_REG_INTR_BLOCK_RF_ERROR_GLOBAL_INTR_R +`define ABR_REG_INTR_BLOCK_RF_ERROR_GLOBAL_INTR_R (32'h810c) +`define ABR_REG_INTR_BLOCK_RF_ERROR_GLOBAL_INTR_R_AGG_STS_LOW (0) +`define ABR_REG_INTR_BLOCK_RF_ERROR_GLOBAL_INTR_R_AGG_STS_MASK (32'h1) +`endif +`ifndef ABR_REG_INTR_BLOCK_RF_NOTIF_GLOBAL_INTR_R +`define ABR_REG_INTR_BLOCK_RF_NOTIF_GLOBAL_INTR_R (32'h8110) +`define ABR_REG_INTR_BLOCK_RF_NOTIF_GLOBAL_INTR_R_AGG_STS_LOW (0) +`define ABR_REG_INTR_BLOCK_RF_NOTIF_GLOBAL_INTR_R_AGG_STS_MASK (32'h1) +`endif +`ifndef ABR_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R +`define ABR_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R (32'h8114) +`define ABR_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_INTERNAL_STS_LOW (0) +`define ABR_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_INTERNAL_STS_MASK (32'h1) +`endif +`ifndef ABR_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R +`define ABR_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R (32'h8118) +`define ABR_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_CMD_DONE_STS_LOW (0) +`define ABR_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_CMD_DONE_STS_MASK (32'h1) +`endif +`ifndef ABR_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R +`define ABR_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R (32'h811c) +`define ABR_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R_ERROR_INTERNAL_TRIG_LOW (0) +`define ABR_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R_ERROR_INTERNAL_TRIG_MASK (32'h1) +`endif +`ifndef ABR_REG_INTR_BLOCK_RF_NOTIF_INTR_TRIG_R +`define ABR_REG_INTR_BLOCK_RF_NOTIF_INTR_TRIG_R (32'h8120) +`define ABR_REG_INTR_BLOCK_RF_NOTIF_INTR_TRIG_R_NOTIF_CMD_DONE_TRIG_LOW (0) +`define ABR_REG_INTR_BLOCK_RF_NOTIF_INTR_TRIG_R_NOTIF_CMD_DONE_TRIG_MASK (32'h1) +`endif +`ifndef ABR_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_COUNT_R +`define ABR_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_COUNT_R (32'h8200) +`endif +`ifndef ABR_REG_INTR_BLOCK_RF_NOTIF_CMD_DONE_INTR_COUNT_R +`define ABR_REG_INTR_BLOCK_RF_NOTIF_CMD_DONE_INTR_COUNT_R (32'h8280) +`endif +`ifndef ABR_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_COUNT_INCR_R +`define ABR_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_COUNT_INCR_R (32'h8300) +`define ABR_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_COUNT_INCR_R_PULSE_LOW (0) +`define ABR_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_COUNT_INCR_R_PULSE_MASK (32'h1) +`endif +`ifndef ABR_REG_INTR_BLOCK_RF_NOTIF_CMD_DONE_INTR_COUNT_INCR_R +`define ABR_REG_INTR_BLOCK_RF_NOTIF_CMD_DONE_INTR_COUNT_INCR_R (32'h8304) +`define ABR_REG_INTR_BLOCK_RF_NOTIF_CMD_DONE_INTR_COUNT_INCR_R_PULSE_LOW (0) +`define ABR_REG_INTR_BLOCK_RF_NOTIF_CMD_DONE_INTR_COUNT_INCR_R_PULSE_MASK (32'h1) +`endif +`ifndef ABR_REG_MLKEM_NAME_0 +`define ABR_REG_MLKEM_NAME_0 (32'h9000) +`endif +`ifndef ABR_REG_MLKEM_NAME_1 +`define ABR_REG_MLKEM_NAME_1 (32'h9004) +`endif +`ifndef ABR_REG_MLKEM_VERSION_0 +`define ABR_REG_MLKEM_VERSION_0 (32'h9008) +`endif +`ifndef ABR_REG_MLKEM_VERSION_1 +`define ABR_REG_MLKEM_VERSION_1 (32'h900c) +`endif +`ifndef ABR_REG_MLKEM_CTRL +`define ABR_REG_MLKEM_CTRL (32'h9010) +`define ABR_REG_MLKEM_CTRL_CTRL_LOW (0) +`define ABR_REG_MLKEM_CTRL_CTRL_MASK (32'h7) +`define ABR_REG_MLKEM_CTRL_ZEROIZE_LOW (3) +`define ABR_REG_MLKEM_CTRL_ZEROIZE_MASK (32'h8) +`endif +`ifndef ABR_REG_MLKEM_STATUS +`define ABR_REG_MLKEM_STATUS (32'h9014) +`define ABR_REG_MLKEM_STATUS_READY_LOW (0) +`define ABR_REG_MLKEM_STATUS_READY_MASK (32'h1) +`define ABR_REG_MLKEM_STATUS_VALID_LOW (1) +`define ABR_REG_MLKEM_STATUS_VALID_MASK (32'h2) +`define ABR_REG_MLKEM_STATUS_ERROR_LOW (2) +`define ABR_REG_MLKEM_STATUS_ERROR_MASK (32'h4) +`endif +`ifndef ABR_REG_MLKEM_SEED_D_0 +`define ABR_REG_MLKEM_SEED_D_0 (32'h9018) +`endif +`ifndef ABR_REG_MLKEM_SEED_D_1 +`define ABR_REG_MLKEM_SEED_D_1 (32'h901c) +`endif +`ifndef ABR_REG_MLKEM_SEED_D_2 +`define ABR_REG_MLKEM_SEED_D_2 (32'h9020) +`endif +`ifndef ABR_REG_MLKEM_SEED_D_3 +`define ABR_REG_MLKEM_SEED_D_3 (32'h9024) +`endif +`ifndef ABR_REG_MLKEM_SEED_D_4 +`define ABR_REG_MLKEM_SEED_D_4 (32'h9028) +`endif +`ifndef ABR_REG_MLKEM_SEED_D_5 +`define ABR_REG_MLKEM_SEED_D_5 (32'h902c) +`endif +`ifndef ABR_REG_MLKEM_SEED_D_6 +`define ABR_REG_MLKEM_SEED_D_6 (32'h9030) +`endif +`ifndef ABR_REG_MLKEM_SEED_D_7 +`define ABR_REG_MLKEM_SEED_D_7 (32'h9034) +`endif +`ifndef ABR_REG_MLKEM_SEED_Z_0 +`define ABR_REG_MLKEM_SEED_Z_0 (32'h9038) +`endif +`ifndef ABR_REG_MLKEM_SEED_Z_1 +`define ABR_REG_MLKEM_SEED_Z_1 (32'h903c) +`endif +`ifndef ABR_REG_MLKEM_SEED_Z_2 +`define ABR_REG_MLKEM_SEED_Z_2 (32'h9040) +`endif +`ifndef ABR_REG_MLKEM_SEED_Z_3 +`define ABR_REG_MLKEM_SEED_Z_3 (32'h9044) +`endif +`ifndef ABR_REG_MLKEM_SEED_Z_4 +`define ABR_REG_MLKEM_SEED_Z_4 (32'h9048) +`endif +`ifndef ABR_REG_MLKEM_SEED_Z_5 +`define ABR_REG_MLKEM_SEED_Z_5 (32'h904c) +`endif +`ifndef ABR_REG_MLKEM_SEED_Z_6 +`define ABR_REG_MLKEM_SEED_Z_6 (32'h9050) +`endif +`ifndef ABR_REG_MLKEM_SEED_Z_7 +`define ABR_REG_MLKEM_SEED_Z_7 (32'h9054) +`endif +`ifndef ABR_REG_MLKEM_SHARED_KEY_0 +`define ABR_REG_MLKEM_SHARED_KEY_0 (32'h9058) +`endif +`ifndef ABR_REG_MLKEM_SHARED_KEY_1 +`define ABR_REG_MLKEM_SHARED_KEY_1 (32'h905c) +`endif +`ifndef ABR_REG_MLKEM_SHARED_KEY_2 +`define ABR_REG_MLKEM_SHARED_KEY_2 (32'h9060) +`endif +`ifndef ABR_REG_MLKEM_SHARED_KEY_3 +`define ABR_REG_MLKEM_SHARED_KEY_3 (32'h9064) +`endif +`ifndef ABR_REG_MLKEM_SHARED_KEY_4 +`define ABR_REG_MLKEM_SHARED_KEY_4 (32'h9068) +`endif +`ifndef ABR_REG_MLKEM_SHARED_KEY_5 +`define ABR_REG_MLKEM_SHARED_KEY_5 (32'h906c) +`endif +`ifndef ABR_REG_MLKEM_SHARED_KEY_6 +`define ABR_REG_MLKEM_SHARED_KEY_6 (32'h9070) +`endif +`ifndef ABR_REG_MLKEM_SHARED_KEY_7 +`define ABR_REG_MLKEM_SHARED_KEY_7 (32'h9074) +`endif +`ifndef ABR_REG_KV_MLKEM_SEED_RD_CTRL +`define ABR_REG_KV_MLKEM_SEED_RD_CTRL (32'hc000) +`define ABR_REG_KV_MLKEM_SEED_RD_CTRL_READ_EN_LOW (0) +`define ABR_REG_KV_MLKEM_SEED_RD_CTRL_READ_EN_MASK (32'h1) +`define ABR_REG_KV_MLKEM_SEED_RD_CTRL_READ_ENTRY_LOW (1) +`define ABR_REG_KV_MLKEM_SEED_RD_CTRL_READ_ENTRY_MASK (32'h3e) +`define ABR_REG_KV_MLKEM_SEED_RD_CTRL_PCR_HASH_EXTEND_LOW (6) +`define ABR_REG_KV_MLKEM_SEED_RD_CTRL_PCR_HASH_EXTEND_MASK (32'h40) +`define ABR_REG_KV_MLKEM_SEED_RD_CTRL_RSVD_LOW (7) +`define ABR_REG_KV_MLKEM_SEED_RD_CTRL_RSVD_MASK (32'hffffff80) +`endif +`ifndef ABR_REG_KV_MLKEM_SEED_RD_STATUS +`define ABR_REG_KV_MLKEM_SEED_RD_STATUS (32'hc004) +`define ABR_REG_KV_MLKEM_SEED_RD_STATUS_READY_LOW (0) +`define ABR_REG_KV_MLKEM_SEED_RD_STATUS_READY_MASK (32'h1) +`define ABR_REG_KV_MLKEM_SEED_RD_STATUS_VALID_LOW (1) +`define ABR_REG_KV_MLKEM_SEED_RD_STATUS_VALID_MASK (32'h2) +`define ABR_REG_KV_MLKEM_SEED_RD_STATUS_ERROR_LOW (2) +`define ABR_REG_KV_MLKEM_SEED_RD_STATUS_ERROR_MASK (32'h3fc) +`endif +`ifndef ABR_REG_KV_MLKEM_MSG_RD_CTRL +`define ABR_REG_KV_MLKEM_MSG_RD_CTRL (32'hc008) +`define ABR_REG_KV_MLKEM_MSG_RD_CTRL_READ_EN_LOW (0) +`define ABR_REG_KV_MLKEM_MSG_RD_CTRL_READ_EN_MASK (32'h1) +`define ABR_REG_KV_MLKEM_MSG_RD_CTRL_READ_ENTRY_LOW (1) +`define ABR_REG_KV_MLKEM_MSG_RD_CTRL_READ_ENTRY_MASK (32'h3e) +`define ABR_REG_KV_MLKEM_MSG_RD_CTRL_PCR_HASH_EXTEND_LOW (6) +`define ABR_REG_KV_MLKEM_MSG_RD_CTRL_PCR_HASH_EXTEND_MASK (32'h40) +`define ABR_REG_KV_MLKEM_MSG_RD_CTRL_RSVD_LOW (7) +`define ABR_REG_KV_MLKEM_MSG_RD_CTRL_RSVD_MASK (32'hffffff80) +`endif +`ifndef ABR_REG_KV_MLKEM_MSG_RD_STATUS +`define ABR_REG_KV_MLKEM_MSG_RD_STATUS (32'hc00c) +`define ABR_REG_KV_MLKEM_MSG_RD_STATUS_READY_LOW (0) +`define ABR_REG_KV_MLKEM_MSG_RD_STATUS_READY_MASK (32'h1) +`define ABR_REG_KV_MLKEM_MSG_RD_STATUS_VALID_LOW (1) +`define ABR_REG_KV_MLKEM_MSG_RD_STATUS_VALID_MASK (32'h2) +`define ABR_REG_KV_MLKEM_MSG_RD_STATUS_ERROR_LOW (2) +`define ABR_REG_KV_MLKEM_MSG_RD_STATUS_ERROR_MASK (32'h3fc) +`endif +`ifndef ABR_REG_KV_MLKEM_SHAREDKEY_WR_CTRL +`define ABR_REG_KV_MLKEM_SHAREDKEY_WR_CTRL (32'hc010) +`define ABR_REG_KV_MLKEM_SHAREDKEY_WR_CTRL_WRITE_EN_LOW (0) +`define ABR_REG_KV_MLKEM_SHAREDKEY_WR_CTRL_WRITE_EN_MASK (32'h1) +`define ABR_REG_KV_MLKEM_SHAREDKEY_WR_CTRL_WRITE_ENTRY_LOW (1) +`define ABR_REG_KV_MLKEM_SHAREDKEY_WR_CTRL_WRITE_ENTRY_MASK (32'h3e) +`define ABR_REG_KV_MLKEM_SHAREDKEY_WR_CTRL_HMAC_KEY_DEST_VALID_LOW (6) +`define ABR_REG_KV_MLKEM_SHAREDKEY_WR_CTRL_HMAC_KEY_DEST_VALID_MASK (32'h40) +`define ABR_REG_KV_MLKEM_SHAREDKEY_WR_CTRL_HMAC_BLOCK_DEST_VALID_LOW (7) +`define ABR_REG_KV_MLKEM_SHAREDKEY_WR_CTRL_HMAC_BLOCK_DEST_VALID_MASK (32'h80) +`define ABR_REG_KV_MLKEM_SHAREDKEY_WR_CTRL_MLDSA_SEED_DEST_VALID_LOW (8) +`define ABR_REG_KV_MLKEM_SHAREDKEY_WR_CTRL_MLDSA_SEED_DEST_VALID_MASK (32'h100) +`define ABR_REG_KV_MLKEM_SHAREDKEY_WR_CTRL_ECC_PKEY_DEST_VALID_LOW (9) +`define ABR_REG_KV_MLKEM_SHAREDKEY_WR_CTRL_ECC_PKEY_DEST_VALID_MASK (32'h200) +`define ABR_REG_KV_MLKEM_SHAREDKEY_WR_CTRL_ECC_SEED_DEST_VALID_LOW (10) +`define ABR_REG_KV_MLKEM_SHAREDKEY_WR_CTRL_ECC_SEED_DEST_VALID_MASK (32'h400) +`define ABR_REG_KV_MLKEM_SHAREDKEY_WR_CTRL_AES_KEY_DEST_VALID_LOW (11) +`define ABR_REG_KV_MLKEM_SHAREDKEY_WR_CTRL_AES_KEY_DEST_VALID_MASK (32'h800) +`define ABR_REG_KV_MLKEM_SHAREDKEY_WR_CTRL_MLKEM_SEED_DEST_VALID_LOW (12) +`define ABR_REG_KV_MLKEM_SHAREDKEY_WR_CTRL_MLKEM_SEED_DEST_VALID_MASK (32'h1000) +`define ABR_REG_KV_MLKEM_SHAREDKEY_WR_CTRL_MLKEM_MSG_DEST_VALID_LOW (13) +`define ABR_REG_KV_MLKEM_SHAREDKEY_WR_CTRL_MLKEM_MSG_DEST_VALID_MASK (32'h2000) +`define ABR_REG_KV_MLKEM_SHAREDKEY_WR_CTRL_DMA_DATA_DEST_VALID_LOW (14) +`define ABR_REG_KV_MLKEM_SHAREDKEY_WR_CTRL_DMA_DATA_DEST_VALID_MASK (32'h4000) +`define ABR_REG_KV_MLKEM_SHAREDKEY_WR_CTRL_RSVD_LOW (15) +`define ABR_REG_KV_MLKEM_SHAREDKEY_WR_CTRL_RSVD_MASK (32'hffff8000) +`endif +`ifndef ABR_REG_KV_MLKEM_SHAREDKEY_WR_STATUS +`define ABR_REG_KV_MLKEM_SHAREDKEY_WR_STATUS (32'hc014) +`define ABR_REG_KV_MLKEM_SHAREDKEY_WR_STATUS_READY_LOW (0) +`define ABR_REG_KV_MLKEM_SHAREDKEY_WR_STATUS_READY_MASK (32'h1) +`define ABR_REG_KV_MLKEM_SHAREDKEY_WR_STATUS_VALID_LOW (1) +`define ABR_REG_KV_MLKEM_SHAREDKEY_WR_STATUS_VALID_MASK (32'h2) +`define ABR_REG_KV_MLKEM_SHAREDKEY_WR_STATUS_ERROR_LOW (2) +`define ABR_REG_KV_MLKEM_SHAREDKEY_WR_STATUS_ERROR_MASK (32'h3fc) +`endif +`ifndef KMAC_INTR_STATE +`define KMAC_INTR_STATE (32'h0) +`define KMAC_INTR_STATE_KMAC_DONE_LOW (0) +`define KMAC_INTR_STATE_KMAC_DONE_MASK (32'h1) +`define KMAC_INTR_STATE_FIFO_EMPTY_LOW (1) +`define KMAC_INTR_STATE_FIFO_EMPTY_MASK (32'h2) +`define KMAC_INTR_STATE_KMAC_ERR_LOW (2) +`define KMAC_INTR_STATE_KMAC_ERR_MASK (32'h4) +`endif +`ifndef KMAC_INTR_ENABLE +`define KMAC_INTR_ENABLE (32'h4) +`define KMAC_INTR_ENABLE_KMAC_DONE_LOW (0) +`define KMAC_INTR_ENABLE_KMAC_DONE_MASK (32'h1) +`define KMAC_INTR_ENABLE_FIFO_EMPTY_LOW (1) +`define KMAC_INTR_ENABLE_FIFO_EMPTY_MASK (32'h2) +`define KMAC_INTR_ENABLE_KMAC_ERR_LOW (2) +`define KMAC_INTR_ENABLE_KMAC_ERR_MASK (32'h4) +`endif +`ifndef KMAC_INTR_TEST +`define KMAC_INTR_TEST (32'h8) +`define KMAC_INTR_TEST_KMAC_DONE_LOW (0) +`define KMAC_INTR_TEST_KMAC_DONE_MASK (32'h1) +`define KMAC_INTR_TEST_FIFO_EMPTY_LOW (1) +`define KMAC_INTR_TEST_FIFO_EMPTY_MASK (32'h2) +`define KMAC_INTR_TEST_KMAC_ERR_LOW (2) +`define KMAC_INTR_TEST_KMAC_ERR_MASK (32'h4) +`endif +`ifndef KMAC_ALERT_TEST +`define KMAC_ALERT_TEST (32'hc) +`define KMAC_ALERT_TEST_RECOV_OPERATION_ERR_LOW (0) +`define KMAC_ALERT_TEST_RECOV_OPERATION_ERR_MASK (32'h1) +`define KMAC_ALERT_TEST_FATAL_FAULT_ERR_LOW (1) +`define KMAC_ALERT_TEST_FATAL_FAULT_ERR_MASK (32'h2) +`endif +`ifndef KMAC_CFG_REGWEN +`define KMAC_CFG_REGWEN (32'h10) +`define KMAC_CFG_REGWEN_EN_LOW (0) +`define KMAC_CFG_REGWEN_EN_MASK (32'h1) +`endif +`ifndef KMAC_CFG_SHADOWED +`define KMAC_CFG_SHADOWED (32'h14) +`define KMAC_CFG_SHADOWED_KSTRENGTH_LOW (1) +`define KMAC_CFG_SHADOWED_KSTRENGTH_MASK (32'he) +`define KMAC_CFG_SHADOWED_MODE_LOW (4) +`define KMAC_CFG_SHADOWED_MODE_MASK (32'h30) +`define KMAC_CFG_SHADOWED_MSG_ENDIANNESS_LOW (8) +`define KMAC_CFG_SHADOWED_MSG_ENDIANNESS_MASK (32'h100) +`define KMAC_CFG_SHADOWED_STATE_ENDIANNESS_LOW (9) +`define KMAC_CFG_SHADOWED_STATE_ENDIANNESS_MASK (32'h200) +`endif +`ifndef KMAC_CMD +`define KMAC_CMD (32'h18) +`define KMAC_CMD_CMD_LOW (0) +`define KMAC_CMD_CMD_MASK (32'h3f) +`define KMAC_CMD_ERR_PROCESSED_LOW (10) +`define KMAC_CMD_ERR_PROCESSED_MASK (32'h400) +`endif +`ifndef KMAC_STATUS +`define KMAC_STATUS (32'h1c) +`define KMAC_STATUS_SHA3_IDLE_LOW (0) +`define KMAC_STATUS_SHA3_IDLE_MASK (32'h1) +`define KMAC_STATUS_SHA3_ABSORB_LOW (1) +`define KMAC_STATUS_SHA3_ABSORB_MASK (32'h2) +`define KMAC_STATUS_SHA3_SQUEEZE_LOW (2) +`define KMAC_STATUS_SHA3_SQUEEZE_MASK (32'h4) +`define KMAC_STATUS_FIFO_DEPTH_LOW (8) +`define KMAC_STATUS_FIFO_DEPTH_MASK (32'h1f00) +`define KMAC_STATUS_FIFO_EMPTY_LOW (14) +`define KMAC_STATUS_FIFO_EMPTY_MASK (32'h4000) +`define KMAC_STATUS_FIFO_FULL_LOW (15) +`define KMAC_STATUS_FIFO_FULL_MASK (32'h8000) +`define KMAC_STATUS_ALERT_FATAL_FAULT_LOW (16) +`define KMAC_STATUS_ALERT_FATAL_FAULT_MASK (32'h10000) +`define KMAC_STATUS_ALERT_RECOV_CTRL_UPDATE_ERR_LOW (17) +`define KMAC_STATUS_ALERT_RECOV_CTRL_UPDATE_ERR_MASK (32'h20000) +`endif +`ifndef KMAC_PREFIX_0 +`define KMAC_PREFIX_0 (32'h20) +`endif +`ifndef KMAC_PREFIX_1 +`define KMAC_PREFIX_1 (32'h24) +`endif +`ifndef KMAC_PREFIX_2 +`define KMAC_PREFIX_2 (32'h28) +`endif +`ifndef KMAC_PREFIX_3 +`define KMAC_PREFIX_3 (32'h2c) +`endif +`ifndef KMAC_PREFIX_4 +`define KMAC_PREFIX_4 (32'h30) +`endif +`ifndef KMAC_PREFIX_5 +`define KMAC_PREFIX_5 (32'h34) +`endif +`ifndef KMAC_PREFIX_6 +`define KMAC_PREFIX_6 (32'h38) +`endif +`ifndef KMAC_PREFIX_7 +`define KMAC_PREFIX_7 (32'h3c) +`endif +`ifndef KMAC_PREFIX_8 +`define KMAC_PREFIX_8 (32'h40) +`endif +`ifndef KMAC_PREFIX_9 +`define KMAC_PREFIX_9 (32'h44) +`endif +`ifndef KMAC_PREFIX_10 +`define KMAC_PREFIX_10 (32'h48) +`endif +`ifndef KMAC_ERR_CODE +`define KMAC_ERR_CODE (32'h4c) +`endif +`ifndef SHA3_SHA3_NAME_0 +`define SHA3_SHA3_NAME_0 (32'h0) +`endif +`ifndef SHA3_SHA3_NAME_1 +`define SHA3_SHA3_NAME_1 (32'h4) +`endif +`ifndef SHA3_SHA3_VERSION_0 +`define SHA3_SHA3_VERSION_0 (32'h8) +`endif +`ifndef SHA3_SHA3_VERSION_1 +`define SHA3_SHA3_VERSION_1 (32'hc) +`endif +`ifndef SHA3_ALERT_TEST +`define SHA3_ALERT_TEST (32'h1c) +`define SHA3_ALERT_TEST_RECOV_OPERATION_ERR_LOW (0) +`define SHA3_ALERT_TEST_RECOV_OPERATION_ERR_MASK (32'h1) +`define SHA3_ALERT_TEST_FATAL_FAULT_ERR_LOW (1) +`define SHA3_ALERT_TEST_FATAL_FAULT_ERR_MASK (32'h2) +`endif +`ifndef SHA3_CFG_REGWEN +`define SHA3_CFG_REGWEN (32'h20) +`define SHA3_CFG_REGWEN_EN_LOW (0) +`define SHA3_CFG_REGWEN_EN_MASK (32'h1) +`endif +`ifndef SHA3_CFG_SHADOWED +`define SHA3_CFG_SHADOWED (32'h24) +`define SHA3_CFG_SHADOWED_KSTRENGTH_LOW (1) +`define SHA3_CFG_SHADOWED_KSTRENGTH_MASK (32'he) +`define SHA3_CFG_SHADOWED_MODE_LOW (4) +`define SHA3_CFG_SHADOWED_MODE_MASK (32'h30) +`define SHA3_CFG_SHADOWED_MSG_ENDIANNESS_LOW (8) +`define SHA3_CFG_SHADOWED_MSG_ENDIANNESS_MASK (32'h100) +`define SHA3_CFG_SHADOWED_STATE_ENDIANNESS_LOW (9) +`define SHA3_CFG_SHADOWED_STATE_ENDIANNESS_MASK (32'h200) +`endif +`ifndef SHA3_CMD +`define SHA3_CMD (32'h28) +`define SHA3_CMD_CMD_LOW (0) +`define SHA3_CMD_CMD_MASK (32'h3f) +`define SHA3_CMD_ERR_PROCESSED_LOW (10) +`define SHA3_CMD_ERR_PROCESSED_MASK (32'h400) +`endif +`ifndef SHA3_STATUS +`define SHA3_STATUS (32'h2c) +`define SHA3_STATUS_SHA3_IDLE_LOW (0) +`define SHA3_STATUS_SHA3_IDLE_MASK (32'h1) +`define SHA3_STATUS_SHA3_ABSORB_LOW (1) +`define SHA3_STATUS_SHA3_ABSORB_MASK (32'h2) +`define SHA3_STATUS_SHA3_SQUEEZE_LOW (2) +`define SHA3_STATUS_SHA3_SQUEEZE_MASK (32'h4) +`define SHA3_STATUS_FIFO_DEPTH_LOW (8) +`define SHA3_STATUS_FIFO_DEPTH_MASK (32'h1f00) +`define SHA3_STATUS_FIFO_EMPTY_LOW (14) +`define SHA3_STATUS_FIFO_EMPTY_MASK (32'h4000) +`define SHA3_STATUS_FIFO_FULL_LOW (15) +`define SHA3_STATUS_FIFO_FULL_MASK (32'h8000) +`define SHA3_STATUS_ALERT_FATAL_FAULT_LOW (16) +`define SHA3_STATUS_ALERT_FATAL_FAULT_MASK (32'h10000) +`define SHA3_STATUS_ALERT_RECOV_CTRL_UPDATE_ERR_LOW (17) +`define SHA3_STATUS_ALERT_RECOV_CTRL_UPDATE_ERR_MASK (32'h20000) +`endif +`ifndef SHA3_ERR_CODE +`define SHA3_ERR_CODE (32'hd0) +`endif +`ifndef SHA3_INTR_BLOCK_RF_GLOBAL_INTR_EN_R +`define SHA3_INTR_BLOCK_RF_GLOBAL_INTR_EN_R (32'h400) +`define SHA3_INTR_BLOCK_RF_GLOBAL_INTR_EN_R_ERROR_EN_LOW (0) +`define SHA3_INTR_BLOCK_RF_GLOBAL_INTR_EN_R_ERROR_EN_MASK (32'h1) +`define SHA3_INTR_BLOCK_RF_GLOBAL_INTR_EN_R_NOTIF_EN_LOW (1) +`define SHA3_INTR_BLOCK_RF_GLOBAL_INTR_EN_R_NOTIF_EN_MASK (32'h2) +`endif +`ifndef SHA3_INTR_BLOCK_RF_ERROR_INTR_EN_R +`define SHA3_INTR_BLOCK_RF_ERROR_INTR_EN_R (32'h404) +`define SHA3_INTR_BLOCK_RF_ERROR_INTR_EN_R_SHA3_ERROR_EN_LOW (0) +`define SHA3_INTR_BLOCK_RF_ERROR_INTR_EN_R_SHA3_ERROR_EN_MASK (32'h1) +`define SHA3_INTR_BLOCK_RF_ERROR_INTR_EN_R_ERROR1_EN_LOW (1) +`define SHA3_INTR_BLOCK_RF_ERROR_INTR_EN_R_ERROR1_EN_MASK (32'h2) +`define SHA3_INTR_BLOCK_RF_ERROR_INTR_EN_R_ERROR2_EN_LOW (2) +`define SHA3_INTR_BLOCK_RF_ERROR_INTR_EN_R_ERROR2_EN_MASK (32'h4) +`define SHA3_INTR_BLOCK_RF_ERROR_INTR_EN_R_ERROR3_EN_LOW (3) +`define SHA3_INTR_BLOCK_RF_ERROR_INTR_EN_R_ERROR3_EN_MASK (32'h8) +`endif +`ifndef SHA3_INTR_BLOCK_RF_NOTIF_INTR_EN_R +`define SHA3_INTR_BLOCK_RF_NOTIF_INTR_EN_R (32'h408) +`define SHA3_INTR_BLOCK_RF_NOTIF_INTR_EN_R_NOTIF_CMD_DONE_EN_LOW (0) +`define SHA3_INTR_BLOCK_RF_NOTIF_INTR_EN_R_NOTIF_CMD_DONE_EN_MASK (32'h1) +`define SHA3_INTR_BLOCK_RF_NOTIF_INTR_EN_R_NOTIF_MSG_FIFO_EMPTY_EN_LOW (1) +`define SHA3_INTR_BLOCK_RF_NOTIF_INTR_EN_R_NOTIF_MSG_FIFO_EMPTY_EN_MASK (32'h2) +`endif +`ifndef SHA3_INTR_BLOCK_RF_ERROR_GLOBAL_INTR_R +`define SHA3_INTR_BLOCK_RF_ERROR_GLOBAL_INTR_R (32'h40c) +`define SHA3_INTR_BLOCK_RF_ERROR_GLOBAL_INTR_R_AGG_STS_LOW (0) +`define SHA3_INTR_BLOCK_RF_ERROR_GLOBAL_INTR_R_AGG_STS_MASK (32'h1) +`endif +`ifndef SHA3_INTR_BLOCK_RF_NOTIF_GLOBAL_INTR_R +`define SHA3_INTR_BLOCK_RF_NOTIF_GLOBAL_INTR_R (32'h410) +`define SHA3_INTR_BLOCK_RF_NOTIF_GLOBAL_INTR_R_AGG_STS_LOW (0) +`define SHA3_INTR_BLOCK_RF_NOTIF_GLOBAL_INTR_R_AGG_STS_MASK (32'h1) +`endif +`ifndef SHA3_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R +`define SHA3_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R (32'h414) +`define SHA3_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_SHA3_ERROR_STS_LOW (0) +`define SHA3_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_SHA3_ERROR_STS_MASK (32'h1) +`define SHA3_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR1_STS_LOW (1) +`define SHA3_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR1_STS_MASK (32'h2) +`define SHA3_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR2_STS_LOW (2) +`define SHA3_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR2_STS_MASK (32'h4) +`define SHA3_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR3_STS_LOW (3) +`define SHA3_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR3_STS_MASK (32'h8) +`endif +`ifndef SHA3_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R +`define SHA3_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R (32'h418) +`define SHA3_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_CMD_DONE_STS_LOW (0) +`define SHA3_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_CMD_DONE_STS_MASK (32'h1) +`define SHA3_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_MSG_FIFO_EMPTY_STS_LOW (1) +`define SHA3_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_MSG_FIFO_EMPTY_STS_MASK (32'h2) +`endif +`ifndef SHA3_INTR_BLOCK_RF_ERROR_INTR_TRIG_R +`define SHA3_INTR_BLOCK_RF_ERROR_INTR_TRIG_R (32'h41c) +`define SHA3_INTR_BLOCK_RF_ERROR_INTR_TRIG_R_SHA3_ERROR_TRIG_LOW (0) +`define SHA3_INTR_BLOCK_RF_ERROR_INTR_TRIG_R_SHA3_ERROR_TRIG_MASK (32'h1) +`define SHA3_INTR_BLOCK_RF_ERROR_INTR_TRIG_R_ERROR1_TRIG_LOW (1) +`define SHA3_INTR_BLOCK_RF_ERROR_INTR_TRIG_R_ERROR1_TRIG_MASK (32'h2) +`define SHA3_INTR_BLOCK_RF_ERROR_INTR_TRIG_R_ERROR2_TRIG_LOW (2) +`define SHA3_INTR_BLOCK_RF_ERROR_INTR_TRIG_R_ERROR2_TRIG_MASK (32'h4) +`define SHA3_INTR_BLOCK_RF_ERROR_INTR_TRIG_R_ERROR3_TRIG_LOW (3) +`define SHA3_INTR_BLOCK_RF_ERROR_INTR_TRIG_R_ERROR3_TRIG_MASK (32'h8) +`endif +`ifndef SHA3_INTR_BLOCK_RF_NOTIF_INTR_TRIG_R +`define SHA3_INTR_BLOCK_RF_NOTIF_INTR_TRIG_R (32'h420) +`define SHA3_INTR_BLOCK_RF_NOTIF_INTR_TRIG_R_NOTIF_CMD_DONE_TRIG_LOW (0) +`define SHA3_INTR_BLOCK_RF_NOTIF_INTR_TRIG_R_NOTIF_CMD_DONE_TRIG_MASK (32'h1) +`define SHA3_INTR_BLOCK_RF_NOTIF_INTR_TRIG_R_NOTIF_MSG_FIFO_EMPTY_TRIG_LOW (1) +`define SHA3_INTR_BLOCK_RF_NOTIF_INTR_TRIG_R_NOTIF_MSG_FIFO_EMPTY_TRIG_MASK (32'h2) +`endif +`ifndef SHA3_INTR_BLOCK_RF_SHA3_ERROR_INTR_COUNT_R +`define SHA3_INTR_BLOCK_RF_SHA3_ERROR_INTR_COUNT_R (32'h500) +`endif +`ifndef SHA3_INTR_BLOCK_RF_ERROR1_INTR_COUNT_R +`define SHA3_INTR_BLOCK_RF_ERROR1_INTR_COUNT_R (32'h504) +`endif +`ifndef SHA3_INTR_BLOCK_RF_ERROR2_INTR_COUNT_R +`define SHA3_INTR_BLOCK_RF_ERROR2_INTR_COUNT_R (32'h508) +`endif +`ifndef SHA3_INTR_BLOCK_RF_ERROR3_INTR_COUNT_R +`define SHA3_INTR_BLOCK_RF_ERROR3_INTR_COUNT_R (32'h50c) +`endif +`ifndef SHA3_INTR_BLOCK_RF_NOTIF_CMD_DONE_INTR_COUNT_R +`define SHA3_INTR_BLOCK_RF_NOTIF_CMD_DONE_INTR_COUNT_R (32'h580) +`endif +`ifndef SHA3_INTR_BLOCK_RF_SHA3_ERROR_INTR_COUNT_INCR_R +`define SHA3_INTR_BLOCK_RF_SHA3_ERROR_INTR_COUNT_INCR_R (32'h600) +`define SHA3_INTR_BLOCK_RF_SHA3_ERROR_INTR_COUNT_INCR_R_PULSE_LOW (0) +`define SHA3_INTR_BLOCK_RF_SHA3_ERROR_INTR_COUNT_INCR_R_PULSE_MASK (32'h1) +`endif +`ifndef SHA3_INTR_BLOCK_RF_ERROR1_INTR_COUNT_INCR_R +`define SHA3_INTR_BLOCK_RF_ERROR1_INTR_COUNT_INCR_R (32'h604) +`define SHA3_INTR_BLOCK_RF_ERROR1_INTR_COUNT_INCR_R_PULSE_LOW (0) +`define SHA3_INTR_BLOCK_RF_ERROR1_INTR_COUNT_INCR_R_PULSE_MASK (32'h1) +`endif +`ifndef SHA3_INTR_BLOCK_RF_ERROR2_INTR_COUNT_INCR_R +`define SHA3_INTR_BLOCK_RF_ERROR2_INTR_COUNT_INCR_R (32'h608) +`define SHA3_INTR_BLOCK_RF_ERROR2_INTR_COUNT_INCR_R_PULSE_LOW (0) +`define SHA3_INTR_BLOCK_RF_ERROR2_INTR_COUNT_INCR_R_PULSE_MASK (32'h1) +`endif +`ifndef SHA3_INTR_BLOCK_RF_ERROR3_INTR_COUNT_INCR_R +`define SHA3_INTR_BLOCK_RF_ERROR3_INTR_COUNT_INCR_R (32'h60c) +`define SHA3_INTR_BLOCK_RF_ERROR3_INTR_COUNT_INCR_R_PULSE_LOW (0) +`define SHA3_INTR_BLOCK_RF_ERROR3_INTR_COUNT_INCR_R_PULSE_MASK (32'h1) +`endif +`ifndef SHA3_INTR_BLOCK_RF_NOTIF_CMD_DONE_INTR_COUNT_INCR_R +`define SHA3_INTR_BLOCK_RF_NOTIF_CMD_DONE_INTR_COUNT_INCR_R (32'h610) +`define SHA3_INTR_BLOCK_RF_NOTIF_CMD_DONE_INTR_COUNT_INCR_R_PULSE_LOW (0) +`define SHA3_INTR_BLOCK_RF_NOTIF_CMD_DONE_INTR_COUNT_INCR_R_PULSE_MASK (32'h1) +`endif +`ifndef CSRNG_REG_INTERRUPT_STATE +`define CSRNG_REG_INTERRUPT_STATE (32'h0) +`define CSRNG_REG_INTERRUPT_STATE_CS_CMD_REQ_DONE_LOW (0) +`define CSRNG_REG_INTERRUPT_STATE_CS_CMD_REQ_DONE_MASK (32'h1) +`define CSRNG_REG_INTERRUPT_STATE_CS_ENTROPY_REQ_LOW (1) +`define CSRNG_REG_INTERRUPT_STATE_CS_ENTROPY_REQ_MASK (32'h2) +`define CSRNG_REG_INTERRUPT_STATE_CS_HW_INST_EXC_LOW (2) +`define CSRNG_REG_INTERRUPT_STATE_CS_HW_INST_EXC_MASK (32'h4) +`define CSRNG_REG_INTERRUPT_STATE_CS_FATAL_ERR_LOW (3) +`define CSRNG_REG_INTERRUPT_STATE_CS_FATAL_ERR_MASK (32'h8) +`endif +`ifndef CSRNG_REG_INTERRUPT_ENABLE +`define CSRNG_REG_INTERRUPT_ENABLE (32'h4) +`define CSRNG_REG_INTERRUPT_ENABLE_CS_CMD_REQ_DONE_LOW (0) +`define CSRNG_REG_INTERRUPT_ENABLE_CS_CMD_REQ_DONE_MASK (32'h1) +`define CSRNG_REG_INTERRUPT_ENABLE_CS_ENTROPY_REQ_LOW (1) +`define CSRNG_REG_INTERRUPT_ENABLE_CS_ENTROPY_REQ_MASK (32'h2) +`define CSRNG_REG_INTERRUPT_ENABLE_CS_HW_INST_EXC_LOW (2) +`define CSRNG_REG_INTERRUPT_ENABLE_CS_HW_INST_EXC_MASK (32'h4) +`define CSRNG_REG_INTERRUPT_ENABLE_CS_FATAL_ERR_LOW (3) +`define CSRNG_REG_INTERRUPT_ENABLE_CS_FATAL_ERR_MASK (32'h8) +`endif +`ifndef CSRNG_REG_INTERRUPT_TEST +`define CSRNG_REG_INTERRUPT_TEST (32'h8) +`define CSRNG_REG_INTERRUPT_TEST_CS_CMD_REQ_DONE_LOW (0) +`define CSRNG_REG_INTERRUPT_TEST_CS_CMD_REQ_DONE_MASK (32'h1) +`define CSRNG_REG_INTERRUPT_TEST_CS_ENTROPY_REQ_LOW (1) +`define CSRNG_REG_INTERRUPT_TEST_CS_ENTROPY_REQ_MASK (32'h2) +`define CSRNG_REG_INTERRUPT_TEST_CS_HW_INST_EXC_LOW (2) +`define CSRNG_REG_INTERRUPT_TEST_CS_HW_INST_EXC_MASK (32'h4) +`define CSRNG_REG_INTERRUPT_TEST_CS_FATAL_ERR_LOW (3) +`define CSRNG_REG_INTERRUPT_TEST_CS_FATAL_ERR_MASK (32'h8) +`endif +`ifndef CSRNG_REG_ALERT_TEST +`define CSRNG_REG_ALERT_TEST (32'hc) +`define CSRNG_REG_ALERT_TEST_RECOV_ALERT_LOW (0) +`define CSRNG_REG_ALERT_TEST_RECOV_ALERT_MASK (32'h1) +`define CSRNG_REG_ALERT_TEST_FATAL_ALERT_LOW (1) +`define CSRNG_REG_ALERT_TEST_FATAL_ALERT_MASK (32'h2) +`endif +`ifndef CSRNG_REG_REGWEN +`define CSRNG_REG_REGWEN (32'h10) +`define CSRNG_REG_REGWEN_REGWEN_LOW (0) +`define CSRNG_REG_REGWEN_REGWEN_MASK (32'h1) +`endif +`ifndef CSRNG_REG_CTRL +`define CSRNG_REG_CTRL (32'h14) +`define CSRNG_REG_CTRL_ENABLE_LOW (0) +`define CSRNG_REG_CTRL_ENABLE_MASK (32'hf) +`define CSRNG_REG_CTRL_SW_APP_ENABLE_LOW (4) +`define CSRNG_REG_CTRL_SW_APP_ENABLE_MASK (32'hf0) +`define CSRNG_REG_CTRL_READ_INT_STATE_LOW (8) +`define CSRNG_REG_CTRL_READ_INT_STATE_MASK (32'hf00) +`define CSRNG_REG_CTRL_FIPS_FORCE_ENABLE_LOW (12) +`define CSRNG_REG_CTRL_FIPS_FORCE_ENABLE_MASK (32'hf000) +`endif +`ifndef CSRNG_REG_CMD_REQ +`define CSRNG_REG_CMD_REQ (32'h18) +`define CSRNG_REG_CMD_REQ_ACMD_LOW (0) +`define CSRNG_REG_CMD_REQ_ACMD_MASK (32'hf) +`define CSRNG_REG_CMD_REQ_CLEN_LOW (4) +`define CSRNG_REG_CMD_REQ_CLEN_MASK (32'hf0) +`define CSRNG_REG_CMD_REQ_FLAG0_LOW (8) +`define CSRNG_REG_CMD_REQ_FLAG0_MASK (32'hf00) +`define CSRNG_REG_CMD_REQ_GLEN_LOW (12) +`define CSRNG_REG_CMD_REQ_GLEN_MASK (32'h1fff000) +`endif +`ifndef CSRNG_REG_RESEED_INTERVAL +`define CSRNG_REG_RESEED_INTERVAL (32'h1c) +`endif +`ifndef CSRNG_REG_RESEED_COUNTER_0 +`define CSRNG_REG_RESEED_COUNTER_0 (32'h20) +`endif +`ifndef CSRNG_REG_RESEED_COUNTER_1 +`define CSRNG_REG_RESEED_COUNTER_1 (32'h24) +`endif +`ifndef CSRNG_REG_RESEED_COUNTER_2 +`define CSRNG_REG_RESEED_COUNTER_2 (32'h28) +`endif +`ifndef CSRNG_REG_SW_CMD_STS +`define CSRNG_REG_SW_CMD_STS (32'h2c) +`define CSRNG_REG_SW_CMD_STS_CMD_RDY_LOW (1) +`define CSRNG_REG_SW_CMD_STS_CMD_RDY_MASK (32'h2) +`define CSRNG_REG_SW_CMD_STS_CMD_ACK_LOW (2) +`define CSRNG_REG_SW_CMD_STS_CMD_ACK_MASK (32'h4) +`define CSRNG_REG_SW_CMD_STS_CMD_STS_LOW (3) +`define CSRNG_REG_SW_CMD_STS_CMD_STS_MASK (32'h38) +`endif +`ifndef CSRNG_REG_GENBITS_VLD +`define CSRNG_REG_GENBITS_VLD (32'h30) +`define CSRNG_REG_GENBITS_VLD_GENBITS_VLD_LOW (0) +`define CSRNG_REG_GENBITS_VLD_GENBITS_VLD_MASK (32'h1) +`define CSRNG_REG_GENBITS_VLD_GENBITS_FIPS_LOW (1) +`define CSRNG_REG_GENBITS_VLD_GENBITS_FIPS_MASK (32'h2) +`endif +`ifndef CSRNG_REG_GENBITS +`define CSRNG_REG_GENBITS (32'h34) +`endif +`ifndef CSRNG_REG_INT_STATE_READ_ENABLE +`define CSRNG_REG_INT_STATE_READ_ENABLE (32'h38) +`define CSRNG_REG_INT_STATE_READ_ENABLE_INT_STATE_READ_ENABLE_LOW (0) +`define CSRNG_REG_INT_STATE_READ_ENABLE_INT_STATE_READ_ENABLE_MASK (32'h7) +`endif +`ifndef CSRNG_REG_INT_STATE_READ_ENABLE_REGWEN +`define CSRNG_REG_INT_STATE_READ_ENABLE_REGWEN (32'h3c) +`define CSRNG_REG_INT_STATE_READ_ENABLE_REGWEN_INT_STATE_READ_ENABLE_REGWEN_LOW (0) +`define CSRNG_REG_INT_STATE_READ_ENABLE_REGWEN_INT_STATE_READ_ENABLE_REGWEN_MASK (32'h1) +`endif +`ifndef CSRNG_REG_INT_STATE_NUM +`define CSRNG_REG_INT_STATE_NUM (32'h40) +`define CSRNG_REG_INT_STATE_NUM_INT_STATE_NUM_LOW (0) +`define CSRNG_REG_INT_STATE_NUM_INT_STATE_NUM_MASK (32'hf) +`endif +`ifndef CSRNG_REG_INT_STATE_VAL +`define CSRNG_REG_INT_STATE_VAL (32'h44) +`endif +`ifndef CSRNG_REG_FIPS_FORCE +`define CSRNG_REG_FIPS_FORCE (32'h48) +`define CSRNG_REG_FIPS_FORCE_FIPS_FORCE_LOW (0) +`define CSRNG_REG_FIPS_FORCE_FIPS_FORCE_MASK (32'h7) +`endif +`ifndef CSRNG_REG_HW_EXC_STS +`define CSRNG_REG_HW_EXC_STS (32'h4c) +`define CSRNG_REG_HW_EXC_STS_HW_EXC_STS_LOW (0) +`define CSRNG_REG_HW_EXC_STS_HW_EXC_STS_MASK (32'hffff) +`endif +`ifndef CSRNG_REG_RECOV_ALERT_STS +`define CSRNG_REG_RECOV_ALERT_STS (32'h50) +`define CSRNG_REG_RECOV_ALERT_STS_ENABLE_FIELD_ALERT_LOW (0) +`define CSRNG_REG_RECOV_ALERT_STS_ENABLE_FIELD_ALERT_MASK (32'h1) +`define CSRNG_REG_RECOV_ALERT_STS_SW_APP_ENABLE_FIELD_ALERT_LOW (1) +`define CSRNG_REG_RECOV_ALERT_STS_SW_APP_ENABLE_FIELD_ALERT_MASK (32'h2) +`define CSRNG_REG_RECOV_ALERT_STS_READ_INT_STATE_FIELD_ALERT_LOW (2) +`define CSRNG_REG_RECOV_ALERT_STS_READ_INT_STATE_FIELD_ALERT_MASK (32'h4) +`define CSRNG_REG_RECOV_ALERT_STS_FIPS_FORCE_ENABLE_FIELD_ALERT_LOW (3) +`define CSRNG_REG_RECOV_ALERT_STS_FIPS_FORCE_ENABLE_FIELD_ALERT_MASK (32'h8) +`define CSRNG_REG_RECOV_ALERT_STS_ACMD_FLAG0_FIELD_ALERT_LOW (4) +`define CSRNG_REG_RECOV_ALERT_STS_ACMD_FLAG0_FIELD_ALERT_MASK (32'h10) +`define CSRNG_REG_RECOV_ALERT_STS_CS_BUS_CMP_ALERT_LOW (12) +`define CSRNG_REG_RECOV_ALERT_STS_CS_BUS_CMP_ALERT_MASK (32'h1000) +`define CSRNG_REG_RECOV_ALERT_STS_CMD_STAGE_INVALID_ACMD_ALERT_LOW (13) +`define CSRNG_REG_RECOV_ALERT_STS_CMD_STAGE_INVALID_ACMD_ALERT_MASK (32'h2000) +`define CSRNG_REG_RECOV_ALERT_STS_CMD_STAGE_INVALID_CMD_SEQ_ALERT_LOW (14) +`define CSRNG_REG_RECOV_ALERT_STS_CMD_STAGE_INVALID_CMD_SEQ_ALERT_MASK (32'h4000) +`define CSRNG_REG_RECOV_ALERT_STS_CMD_STAGE_RESEED_CNT_ALERT_LOW (15) +`define CSRNG_REG_RECOV_ALERT_STS_CMD_STAGE_RESEED_CNT_ALERT_MASK (32'h8000) +`endif +`ifndef CSRNG_REG_ERR_CODE +`define CSRNG_REG_ERR_CODE (32'h54) +`define CSRNG_REG_ERR_CODE_SFIFO_CMD_ERR_LOW (0) +`define CSRNG_REG_ERR_CODE_SFIFO_CMD_ERR_MASK (32'h1) +`define CSRNG_REG_ERR_CODE_SFIFO_GENBITS_ERR_LOW (1) +`define CSRNG_REG_ERR_CODE_SFIFO_GENBITS_ERR_MASK (32'h2) +`define CSRNG_REG_ERR_CODE_SFIFO_CMDREQ_ERR_LOW (2) +`define CSRNG_REG_ERR_CODE_SFIFO_CMDREQ_ERR_MASK (32'h4) +`define CSRNG_REG_ERR_CODE_SFIFO_RCSTAGE_ERR_LOW (3) +`define CSRNG_REG_ERR_CODE_SFIFO_RCSTAGE_ERR_MASK (32'h8) +`define CSRNG_REG_ERR_CODE_SFIFO_KEYVRC_ERR_LOW (4) +`define CSRNG_REG_ERR_CODE_SFIFO_KEYVRC_ERR_MASK (32'h10) +`define CSRNG_REG_ERR_CODE_SFIFO_UPDREQ_ERR_LOW (5) +`define CSRNG_REG_ERR_CODE_SFIFO_UPDREQ_ERR_MASK (32'h20) +`define CSRNG_REG_ERR_CODE_SFIFO_BENCREQ_ERR_LOW (6) +`define CSRNG_REG_ERR_CODE_SFIFO_BENCREQ_ERR_MASK (32'h40) +`define CSRNG_REG_ERR_CODE_SFIFO_BENCACK_ERR_LOW (7) +`define CSRNG_REG_ERR_CODE_SFIFO_BENCACK_ERR_MASK (32'h80) +`define CSRNG_REG_ERR_CODE_SFIFO_PDATA_ERR_LOW (8) +`define CSRNG_REG_ERR_CODE_SFIFO_PDATA_ERR_MASK (32'h100) +`define CSRNG_REG_ERR_CODE_SFIFO_FINAL_ERR_LOW (9) +`define CSRNG_REG_ERR_CODE_SFIFO_FINAL_ERR_MASK (32'h200) +`define CSRNG_REG_ERR_CODE_SFIFO_GBENCACK_ERR_LOW (10) +`define CSRNG_REG_ERR_CODE_SFIFO_GBENCACK_ERR_MASK (32'h400) +`define CSRNG_REG_ERR_CODE_SFIFO_GRCSTAGE_ERR_LOW (11) +`define CSRNG_REG_ERR_CODE_SFIFO_GRCSTAGE_ERR_MASK (32'h800) +`define CSRNG_REG_ERR_CODE_SFIFO_GGENREQ_ERR_LOW (12) +`define CSRNG_REG_ERR_CODE_SFIFO_GGENREQ_ERR_MASK (32'h1000) +`define CSRNG_REG_ERR_CODE_SFIFO_GADSTAGE_ERR_LOW (13) +`define CSRNG_REG_ERR_CODE_SFIFO_GADSTAGE_ERR_MASK (32'h2000) +`define CSRNG_REG_ERR_CODE_SFIFO_GGENBITS_ERR_LOW (14) +`define CSRNG_REG_ERR_CODE_SFIFO_GGENBITS_ERR_MASK (32'h4000) +`define CSRNG_REG_ERR_CODE_SFIFO_BLKENC_ERR_LOW (15) +`define CSRNG_REG_ERR_CODE_SFIFO_BLKENC_ERR_MASK (32'h8000) +`define CSRNG_REG_ERR_CODE_CMD_STAGE_SM_ERR_LOW (20) +`define CSRNG_REG_ERR_CODE_CMD_STAGE_SM_ERR_MASK (32'h100000) +`define CSRNG_REG_ERR_CODE_MAIN_SM_ERR_LOW (21) +`define CSRNG_REG_ERR_CODE_MAIN_SM_ERR_MASK (32'h200000) +`define CSRNG_REG_ERR_CODE_DRBG_GEN_SM_ERR_LOW (22) +`define CSRNG_REG_ERR_CODE_DRBG_GEN_SM_ERR_MASK (32'h400000) +`define CSRNG_REG_ERR_CODE_DRBG_UPDBE_SM_ERR_LOW (23) +`define CSRNG_REG_ERR_CODE_DRBG_UPDBE_SM_ERR_MASK (32'h800000) +`define CSRNG_REG_ERR_CODE_DRBG_UPDOB_SM_ERR_LOW (24) +`define CSRNG_REG_ERR_CODE_DRBG_UPDOB_SM_ERR_MASK (32'h1000000) +`define CSRNG_REG_ERR_CODE_AES_CIPHER_SM_ERR_LOW (25) +`define CSRNG_REG_ERR_CODE_AES_CIPHER_SM_ERR_MASK (32'h2000000) +`define CSRNG_REG_ERR_CODE_CMD_GEN_CNT_ERR_LOW (26) +`define CSRNG_REG_ERR_CODE_CMD_GEN_CNT_ERR_MASK (32'h4000000) +`define CSRNG_REG_ERR_CODE_FIFO_WRITE_ERR_LOW (28) +`define CSRNG_REG_ERR_CODE_FIFO_WRITE_ERR_MASK (32'h10000000) +`define CSRNG_REG_ERR_CODE_FIFO_READ_ERR_LOW (29) +`define CSRNG_REG_ERR_CODE_FIFO_READ_ERR_MASK (32'h20000000) +`define CSRNG_REG_ERR_CODE_FIFO_STATE_ERR_LOW (30) +`define CSRNG_REG_ERR_CODE_FIFO_STATE_ERR_MASK (32'h40000000) +`endif +`ifndef CSRNG_REG_ERR_CODE_TEST +`define CSRNG_REG_ERR_CODE_TEST (32'h58) +`define CSRNG_REG_ERR_CODE_TEST_ERR_CODE_TEST_LOW (0) +`define CSRNG_REG_ERR_CODE_TEST_ERR_CODE_TEST_MASK (32'h1f) +`endif +`ifndef CSRNG_REG_MAIN_SM_STATE +`define CSRNG_REG_MAIN_SM_STATE (32'h5c) +`define CSRNG_REG_MAIN_SM_STATE_MAIN_SM_STATE_LOW (0) +`define CSRNG_REG_MAIN_SM_STATE_MAIN_SM_STATE_MASK (32'hff) +`endif +`ifndef ENTROPY_SRC_REG_INTERRUPT_STATE +`define ENTROPY_SRC_REG_INTERRUPT_STATE (32'h0) +`define ENTROPY_SRC_REG_INTERRUPT_STATE_ES_ENTROPY_VALID_LOW (0) +`define ENTROPY_SRC_REG_INTERRUPT_STATE_ES_ENTROPY_VALID_MASK (32'h1) +`define ENTROPY_SRC_REG_INTERRUPT_STATE_ES_HEALTH_TEST_FAILED_LOW (1) +`define ENTROPY_SRC_REG_INTERRUPT_STATE_ES_HEALTH_TEST_FAILED_MASK (32'h2) +`define ENTROPY_SRC_REG_INTERRUPT_STATE_ES_OBSERVE_FIFO_READY_LOW (2) +`define ENTROPY_SRC_REG_INTERRUPT_STATE_ES_OBSERVE_FIFO_READY_MASK (32'h4) +`define ENTROPY_SRC_REG_INTERRUPT_STATE_ES_FATAL_ERR_LOW (3) +`define ENTROPY_SRC_REG_INTERRUPT_STATE_ES_FATAL_ERR_MASK (32'h8) +`endif +`ifndef ENTROPY_SRC_REG_INTERRUPT_ENABLE +`define ENTROPY_SRC_REG_INTERRUPT_ENABLE (32'h4) +`define ENTROPY_SRC_REG_INTERRUPT_ENABLE_ES_ENTROPY_VALID_LOW (0) +`define ENTROPY_SRC_REG_INTERRUPT_ENABLE_ES_ENTROPY_VALID_MASK (32'h1) +`define ENTROPY_SRC_REG_INTERRUPT_ENABLE_ES_HEALTH_TEST_FAILED_LOW (1) +`define ENTROPY_SRC_REG_INTERRUPT_ENABLE_ES_HEALTH_TEST_FAILED_MASK (32'h2) +`define ENTROPY_SRC_REG_INTERRUPT_ENABLE_ES_OBSERVE_FIFO_READY_LOW (2) +`define ENTROPY_SRC_REG_INTERRUPT_ENABLE_ES_OBSERVE_FIFO_READY_MASK (32'h4) +`define ENTROPY_SRC_REG_INTERRUPT_ENABLE_ES_FATAL_ERR_LOW (3) +`define ENTROPY_SRC_REG_INTERRUPT_ENABLE_ES_FATAL_ERR_MASK (32'h8) +`endif +`ifndef ENTROPY_SRC_REG_INTERRUPT_TEST +`define ENTROPY_SRC_REG_INTERRUPT_TEST (32'h8) +`define ENTROPY_SRC_REG_INTERRUPT_TEST_ES_ENTROPY_VALID_LOW (0) +`define ENTROPY_SRC_REG_INTERRUPT_TEST_ES_ENTROPY_VALID_MASK (32'h1) +`define ENTROPY_SRC_REG_INTERRUPT_TEST_ES_HEALTH_TEST_FAILED_LOW (1) +`define ENTROPY_SRC_REG_INTERRUPT_TEST_ES_HEALTH_TEST_FAILED_MASK (32'h2) +`define ENTROPY_SRC_REG_INTERRUPT_TEST_ES_OBSERVE_FIFO_READY_LOW (2) +`define ENTROPY_SRC_REG_INTERRUPT_TEST_ES_OBSERVE_FIFO_READY_MASK (32'h4) +`define ENTROPY_SRC_REG_INTERRUPT_TEST_ES_FATAL_ERR_LOW (3) +`define ENTROPY_SRC_REG_INTERRUPT_TEST_ES_FATAL_ERR_MASK (32'h8) +`endif +`ifndef ENTROPY_SRC_REG_ALERT_TEST +`define ENTROPY_SRC_REG_ALERT_TEST (32'hc) +`define ENTROPY_SRC_REG_ALERT_TEST_RECOV_ALERT_LOW (0) +`define ENTROPY_SRC_REG_ALERT_TEST_RECOV_ALERT_MASK (32'h1) +`define ENTROPY_SRC_REG_ALERT_TEST_FATAL_ALERT_LOW (1) +`define ENTROPY_SRC_REG_ALERT_TEST_FATAL_ALERT_MASK (32'h2) +`endif +`ifndef ENTROPY_SRC_REG_ME_REGWEN +`define ENTROPY_SRC_REG_ME_REGWEN (32'h10) +`define ENTROPY_SRC_REG_ME_REGWEN_ME_REGWEN_LOW (0) +`define ENTROPY_SRC_REG_ME_REGWEN_ME_REGWEN_MASK (32'h1) +`endif +`ifndef ENTROPY_SRC_REG_SW_REGUPD +`define ENTROPY_SRC_REG_SW_REGUPD (32'h14) +`define ENTROPY_SRC_REG_SW_REGUPD_SW_REGUPD_LOW (0) +`define ENTROPY_SRC_REG_SW_REGUPD_SW_REGUPD_MASK (32'h1) +`endif +`ifndef ENTROPY_SRC_REG_REGWEN +`define ENTROPY_SRC_REG_REGWEN (32'h18) +`define ENTROPY_SRC_REG_REGWEN_REGWEN_LOW (0) +`define ENTROPY_SRC_REG_REGWEN_REGWEN_MASK (32'h1) +`endif +`ifndef ENTROPY_SRC_REG_REV +`define ENTROPY_SRC_REG_REV (32'h1c) +`define ENTROPY_SRC_REG_REV_ABI_REVISION_LOW (0) +`define ENTROPY_SRC_REG_REV_ABI_REVISION_MASK (32'hff) +`define ENTROPY_SRC_REG_REV_HW_REVISION_LOW (8) +`define ENTROPY_SRC_REG_REV_HW_REVISION_MASK (32'hff00) +`define ENTROPY_SRC_REG_REV_CHIP_TYPE_LOW (16) +`define ENTROPY_SRC_REG_REV_CHIP_TYPE_MASK (32'hff0000) +`endif +`ifndef ENTROPY_SRC_REG_MODULE_ENABLE +`define ENTROPY_SRC_REG_MODULE_ENABLE (32'h20) +`define ENTROPY_SRC_REG_MODULE_ENABLE_MODULE_ENABLE_LOW (0) +`define ENTROPY_SRC_REG_MODULE_ENABLE_MODULE_ENABLE_MASK (32'hf) +`endif +`ifndef ENTROPY_SRC_REG_CONF +`define ENTROPY_SRC_REG_CONF (32'h24) +`define ENTROPY_SRC_REG_CONF_FIPS_ENABLE_LOW (0) +`define ENTROPY_SRC_REG_CONF_FIPS_ENABLE_MASK (32'hf) +`define ENTROPY_SRC_REG_CONF_FIPS_FLAG_LOW (4) +`define ENTROPY_SRC_REG_CONF_FIPS_FLAG_MASK (32'hf0) +`define ENTROPY_SRC_REG_CONF_RNG_FIPS_LOW (8) +`define ENTROPY_SRC_REG_CONF_RNG_FIPS_MASK (32'hf00) +`define ENTROPY_SRC_REG_CONF_RNG_BIT_ENABLE_LOW (12) +`define ENTROPY_SRC_REG_CONF_RNG_BIT_ENABLE_MASK (32'hf000) +`define ENTROPY_SRC_REG_CONF_RNG_BIT_SEL_LOW (16) +`define ENTROPY_SRC_REG_CONF_RNG_BIT_SEL_MASK (32'h30000) +`define ENTROPY_SRC_REG_CONF_THRESHOLD_SCOPE_LOW (18) +`define ENTROPY_SRC_REG_CONF_THRESHOLD_SCOPE_MASK (32'h3c0000) +`define ENTROPY_SRC_REG_CONF_ENTROPY_DATA_REG_ENABLE_LOW (22) +`define ENTROPY_SRC_REG_CONF_ENTROPY_DATA_REG_ENABLE_MASK (32'h3c00000) +`endif +`ifndef ENTROPY_SRC_REG_ENTROPY_CONTROL +`define ENTROPY_SRC_REG_ENTROPY_CONTROL (32'h28) +`define ENTROPY_SRC_REG_ENTROPY_CONTROL_ES_ROUTE_LOW (0) +`define ENTROPY_SRC_REG_ENTROPY_CONTROL_ES_ROUTE_MASK (32'hf) +`define ENTROPY_SRC_REG_ENTROPY_CONTROL_ES_TYPE_LOW (4) +`define ENTROPY_SRC_REG_ENTROPY_CONTROL_ES_TYPE_MASK (32'hf0) +`endif +`ifndef ENTROPY_SRC_REG_ENTROPY_DATA +`define ENTROPY_SRC_REG_ENTROPY_DATA (32'h2c) +`endif +`ifndef ENTROPY_SRC_REG_HEALTH_TEST_WINDOWS +`define ENTROPY_SRC_REG_HEALTH_TEST_WINDOWS (32'h30) +`define ENTROPY_SRC_REG_HEALTH_TEST_WINDOWS_FIPS_WINDOW_LOW (0) +`define ENTROPY_SRC_REG_HEALTH_TEST_WINDOWS_FIPS_WINDOW_MASK (32'hffff) +`define ENTROPY_SRC_REG_HEALTH_TEST_WINDOWS_BYPASS_WINDOW_LOW (16) +`define ENTROPY_SRC_REG_HEALTH_TEST_WINDOWS_BYPASS_WINDOW_MASK (32'hffff0000) +`endif +`ifndef ENTROPY_SRC_REG_REPCNT_THRESHOLDS +`define ENTROPY_SRC_REG_REPCNT_THRESHOLDS (32'h34) +`define ENTROPY_SRC_REG_REPCNT_THRESHOLDS_FIPS_THRESH_LOW (0) +`define ENTROPY_SRC_REG_REPCNT_THRESHOLDS_FIPS_THRESH_MASK (32'hffff) +`define ENTROPY_SRC_REG_REPCNT_THRESHOLDS_BYPASS_THRESH_LOW (16) +`define ENTROPY_SRC_REG_REPCNT_THRESHOLDS_BYPASS_THRESH_MASK (32'hffff0000) +`endif +`ifndef ENTROPY_SRC_REG_REPCNTS_THRESHOLDS +`define ENTROPY_SRC_REG_REPCNTS_THRESHOLDS (32'h38) +`define ENTROPY_SRC_REG_REPCNTS_THRESHOLDS_FIPS_THRESH_LOW (0) +`define ENTROPY_SRC_REG_REPCNTS_THRESHOLDS_FIPS_THRESH_MASK (32'hffff) +`define ENTROPY_SRC_REG_REPCNTS_THRESHOLDS_BYPASS_THRESH_LOW (16) +`define ENTROPY_SRC_REG_REPCNTS_THRESHOLDS_BYPASS_THRESH_MASK (32'hffff0000) +`endif +`ifndef ENTROPY_SRC_REG_ADAPTP_HI_THRESHOLDS +`define ENTROPY_SRC_REG_ADAPTP_HI_THRESHOLDS (32'h3c) +`define ENTROPY_SRC_REG_ADAPTP_HI_THRESHOLDS_FIPS_THRESH_LOW (0) +`define ENTROPY_SRC_REG_ADAPTP_HI_THRESHOLDS_FIPS_THRESH_MASK (32'hffff) +`define ENTROPY_SRC_REG_ADAPTP_HI_THRESHOLDS_BYPASS_THRESH_LOW (16) +`define ENTROPY_SRC_REG_ADAPTP_HI_THRESHOLDS_BYPASS_THRESH_MASK (32'hffff0000) +`endif +`ifndef ENTROPY_SRC_REG_ADAPTP_LO_THRESHOLDS +`define ENTROPY_SRC_REG_ADAPTP_LO_THRESHOLDS (32'h40) +`define ENTROPY_SRC_REG_ADAPTP_LO_THRESHOLDS_FIPS_THRESH_LOW (0) +`define ENTROPY_SRC_REG_ADAPTP_LO_THRESHOLDS_FIPS_THRESH_MASK (32'hffff) +`define ENTROPY_SRC_REG_ADAPTP_LO_THRESHOLDS_BYPASS_THRESH_LOW (16) +`define ENTROPY_SRC_REG_ADAPTP_LO_THRESHOLDS_BYPASS_THRESH_MASK (32'hffff0000) +`endif +`ifndef ENTROPY_SRC_REG_BUCKET_THRESHOLDS +`define ENTROPY_SRC_REG_BUCKET_THRESHOLDS (32'h44) +`define ENTROPY_SRC_REG_BUCKET_THRESHOLDS_FIPS_THRESH_LOW (0) +`define ENTROPY_SRC_REG_BUCKET_THRESHOLDS_FIPS_THRESH_MASK (32'hffff) +`define ENTROPY_SRC_REG_BUCKET_THRESHOLDS_BYPASS_THRESH_LOW (16) +`define ENTROPY_SRC_REG_BUCKET_THRESHOLDS_BYPASS_THRESH_MASK (32'hffff0000) +`endif +`ifndef ENTROPY_SRC_REG_MARKOV_HI_THRESHOLDS +`define ENTROPY_SRC_REG_MARKOV_HI_THRESHOLDS (32'h48) +`define ENTROPY_SRC_REG_MARKOV_HI_THRESHOLDS_FIPS_THRESH_LOW (0) +`define ENTROPY_SRC_REG_MARKOV_HI_THRESHOLDS_FIPS_THRESH_MASK (32'hffff) +`define ENTROPY_SRC_REG_MARKOV_HI_THRESHOLDS_BYPASS_THRESH_LOW (16) +`define ENTROPY_SRC_REG_MARKOV_HI_THRESHOLDS_BYPASS_THRESH_MASK (32'hffff0000) +`endif +`ifndef ENTROPY_SRC_REG_MARKOV_LO_THRESHOLDS +`define ENTROPY_SRC_REG_MARKOV_LO_THRESHOLDS (32'h4c) +`define ENTROPY_SRC_REG_MARKOV_LO_THRESHOLDS_FIPS_THRESH_LOW (0) +`define ENTROPY_SRC_REG_MARKOV_LO_THRESHOLDS_FIPS_THRESH_MASK (32'hffff) +`define ENTROPY_SRC_REG_MARKOV_LO_THRESHOLDS_BYPASS_THRESH_LOW (16) +`define ENTROPY_SRC_REG_MARKOV_LO_THRESHOLDS_BYPASS_THRESH_MASK (32'hffff0000) +`endif +`ifndef ENTROPY_SRC_REG_EXTHT_HI_THRESHOLDS +`define ENTROPY_SRC_REG_EXTHT_HI_THRESHOLDS (32'h50) +`define ENTROPY_SRC_REG_EXTHT_HI_THRESHOLDS_FIPS_THRESH_LOW (0) +`define ENTROPY_SRC_REG_EXTHT_HI_THRESHOLDS_FIPS_THRESH_MASK (32'hffff) +`define ENTROPY_SRC_REG_EXTHT_HI_THRESHOLDS_BYPASS_THRESH_LOW (16) +`define ENTROPY_SRC_REG_EXTHT_HI_THRESHOLDS_BYPASS_THRESH_MASK (32'hffff0000) +`endif +`ifndef ENTROPY_SRC_REG_EXTHT_LO_THRESHOLDS +`define ENTROPY_SRC_REG_EXTHT_LO_THRESHOLDS (32'h54) +`define ENTROPY_SRC_REG_EXTHT_LO_THRESHOLDS_FIPS_THRESH_LOW (0) +`define ENTROPY_SRC_REG_EXTHT_LO_THRESHOLDS_FIPS_THRESH_MASK (32'hffff) +`define ENTROPY_SRC_REG_EXTHT_LO_THRESHOLDS_BYPASS_THRESH_LOW (16) +`define ENTROPY_SRC_REG_EXTHT_LO_THRESHOLDS_BYPASS_THRESH_MASK (32'hffff0000) +`endif +`ifndef ENTROPY_SRC_REG_REPCNT_HI_WATERMARKS +`define ENTROPY_SRC_REG_REPCNT_HI_WATERMARKS (32'h58) +`define ENTROPY_SRC_REG_REPCNT_HI_WATERMARKS_FIPS_WATERMARK_LOW (0) +`define ENTROPY_SRC_REG_REPCNT_HI_WATERMARKS_FIPS_WATERMARK_MASK (32'hffff) +`define ENTROPY_SRC_REG_REPCNT_HI_WATERMARKS_BYPASS_WATERMARK_LOW (16) +`define ENTROPY_SRC_REG_REPCNT_HI_WATERMARKS_BYPASS_WATERMARK_MASK (32'hffff0000) +`endif +`ifndef ENTROPY_SRC_REG_REPCNTS_HI_WATERMARKS +`define ENTROPY_SRC_REG_REPCNTS_HI_WATERMARKS (32'h5c) +`define ENTROPY_SRC_REG_REPCNTS_HI_WATERMARKS_FIPS_WATERMARK_LOW (0) +`define ENTROPY_SRC_REG_REPCNTS_HI_WATERMARKS_FIPS_WATERMARK_MASK (32'hffff) +`define ENTROPY_SRC_REG_REPCNTS_HI_WATERMARKS_BYPASS_WATERMARK_LOW (16) +`define ENTROPY_SRC_REG_REPCNTS_HI_WATERMARKS_BYPASS_WATERMARK_MASK (32'hffff0000) +`endif +`ifndef ENTROPY_SRC_REG_ADAPTP_HI_WATERMARKS +`define ENTROPY_SRC_REG_ADAPTP_HI_WATERMARKS (32'h60) +`define ENTROPY_SRC_REG_ADAPTP_HI_WATERMARKS_FIPS_WATERMARK_LOW (0) +`define ENTROPY_SRC_REG_ADAPTP_HI_WATERMARKS_FIPS_WATERMARK_MASK (32'hffff) +`define ENTROPY_SRC_REG_ADAPTP_HI_WATERMARKS_BYPASS_WATERMARK_LOW (16) +`define ENTROPY_SRC_REG_ADAPTP_HI_WATERMARKS_BYPASS_WATERMARK_MASK (32'hffff0000) +`endif +`ifndef ENTROPY_SRC_REG_ADAPTP_LO_WATERMARKS +`define ENTROPY_SRC_REG_ADAPTP_LO_WATERMARKS (32'h64) +`define ENTROPY_SRC_REG_ADAPTP_LO_WATERMARKS_FIPS_WATERMARK_LOW (0) +`define ENTROPY_SRC_REG_ADAPTP_LO_WATERMARKS_FIPS_WATERMARK_MASK (32'hffff) +`define ENTROPY_SRC_REG_ADAPTP_LO_WATERMARKS_BYPASS_WATERMARK_LOW (16) +`define ENTROPY_SRC_REG_ADAPTP_LO_WATERMARKS_BYPASS_WATERMARK_MASK (32'hffff0000) +`endif +`ifndef ENTROPY_SRC_REG_EXTHT_HI_WATERMARKS +`define ENTROPY_SRC_REG_EXTHT_HI_WATERMARKS (32'h68) +`define ENTROPY_SRC_REG_EXTHT_HI_WATERMARKS_FIPS_WATERMARK_LOW (0) +`define ENTROPY_SRC_REG_EXTHT_HI_WATERMARKS_FIPS_WATERMARK_MASK (32'hffff) +`define ENTROPY_SRC_REG_EXTHT_HI_WATERMARKS_BYPASS_WATERMARK_LOW (16) +`define ENTROPY_SRC_REG_EXTHT_HI_WATERMARKS_BYPASS_WATERMARK_MASK (32'hffff0000) +`endif +`ifndef ENTROPY_SRC_REG_EXTHT_LO_WATERMARKS +`define ENTROPY_SRC_REG_EXTHT_LO_WATERMARKS (32'h6c) +`define ENTROPY_SRC_REG_EXTHT_LO_WATERMARKS_FIPS_WATERMARK_LOW (0) +`define ENTROPY_SRC_REG_EXTHT_LO_WATERMARKS_FIPS_WATERMARK_MASK (32'hffff) +`define ENTROPY_SRC_REG_EXTHT_LO_WATERMARKS_BYPASS_WATERMARK_LOW (16) +`define ENTROPY_SRC_REG_EXTHT_LO_WATERMARKS_BYPASS_WATERMARK_MASK (32'hffff0000) +`endif +`ifndef ENTROPY_SRC_REG_BUCKET_HI_WATERMARKS +`define ENTROPY_SRC_REG_BUCKET_HI_WATERMARKS (32'h70) +`define ENTROPY_SRC_REG_BUCKET_HI_WATERMARKS_FIPS_WATERMARK_LOW (0) +`define ENTROPY_SRC_REG_BUCKET_HI_WATERMARKS_FIPS_WATERMARK_MASK (32'hffff) +`define ENTROPY_SRC_REG_BUCKET_HI_WATERMARKS_BYPASS_WATERMARK_LOW (16) +`define ENTROPY_SRC_REG_BUCKET_HI_WATERMARKS_BYPASS_WATERMARK_MASK (32'hffff0000) +`endif +`ifndef ENTROPY_SRC_REG_MARKOV_HI_WATERMARKS +`define ENTROPY_SRC_REG_MARKOV_HI_WATERMARKS (32'h74) +`define ENTROPY_SRC_REG_MARKOV_HI_WATERMARKS_FIPS_WATERMARK_LOW (0) +`define ENTROPY_SRC_REG_MARKOV_HI_WATERMARKS_FIPS_WATERMARK_MASK (32'hffff) +`define ENTROPY_SRC_REG_MARKOV_HI_WATERMARKS_BYPASS_WATERMARK_LOW (16) +`define ENTROPY_SRC_REG_MARKOV_HI_WATERMARKS_BYPASS_WATERMARK_MASK (32'hffff0000) +`endif +`ifndef ENTROPY_SRC_REG_MARKOV_LO_WATERMARKS +`define ENTROPY_SRC_REG_MARKOV_LO_WATERMARKS (32'h78) +`define ENTROPY_SRC_REG_MARKOV_LO_WATERMARKS_FIPS_WATERMARK_LOW (0) +`define ENTROPY_SRC_REG_MARKOV_LO_WATERMARKS_FIPS_WATERMARK_MASK (32'hffff) +`define ENTROPY_SRC_REG_MARKOV_LO_WATERMARKS_BYPASS_WATERMARK_LOW (16) +`define ENTROPY_SRC_REG_MARKOV_LO_WATERMARKS_BYPASS_WATERMARK_MASK (32'hffff0000) +`endif +`ifndef ENTROPY_SRC_REG_REPCNT_TOTAL_FAILS +`define ENTROPY_SRC_REG_REPCNT_TOTAL_FAILS (32'h7c) +`endif +`ifndef ENTROPY_SRC_REG_REPCNTS_TOTAL_FAILS +`define ENTROPY_SRC_REG_REPCNTS_TOTAL_FAILS (32'h80) +`endif +`ifndef ENTROPY_SRC_REG_ADAPTP_HI_TOTAL_FAILS +`define ENTROPY_SRC_REG_ADAPTP_HI_TOTAL_FAILS (32'h84) +`endif +`ifndef ENTROPY_SRC_REG_ADAPTP_LO_TOTAL_FAILS +`define ENTROPY_SRC_REG_ADAPTP_LO_TOTAL_FAILS (32'h88) +`endif +`ifndef ENTROPY_SRC_REG_BUCKET_TOTAL_FAILS +`define ENTROPY_SRC_REG_BUCKET_TOTAL_FAILS (32'h8c) +`endif +`ifndef ENTROPY_SRC_REG_MARKOV_HI_TOTAL_FAILS +`define ENTROPY_SRC_REG_MARKOV_HI_TOTAL_FAILS (32'h90) +`endif +`ifndef ENTROPY_SRC_REG_MARKOV_LO_TOTAL_FAILS +`define ENTROPY_SRC_REG_MARKOV_LO_TOTAL_FAILS (32'h94) +`endif +`ifndef ENTROPY_SRC_REG_EXTHT_HI_TOTAL_FAILS +`define ENTROPY_SRC_REG_EXTHT_HI_TOTAL_FAILS (32'h98) +`endif +`ifndef ENTROPY_SRC_REG_EXTHT_LO_TOTAL_FAILS +`define ENTROPY_SRC_REG_EXTHT_LO_TOTAL_FAILS (32'h9c) +`endif +`ifndef ENTROPY_SRC_REG_ALERT_THRESHOLD +`define ENTROPY_SRC_REG_ALERT_THRESHOLD (32'ha0) +`define ENTROPY_SRC_REG_ALERT_THRESHOLD_ALERT_THRESHOLD_LOW (0) +`define ENTROPY_SRC_REG_ALERT_THRESHOLD_ALERT_THRESHOLD_MASK (32'hffff) +`define ENTROPY_SRC_REG_ALERT_THRESHOLD_ALERT_THRESHOLD_INV_LOW (16) +`define ENTROPY_SRC_REG_ALERT_THRESHOLD_ALERT_THRESHOLD_INV_MASK (32'hffff0000) +`endif +`ifndef ENTROPY_SRC_REG_ALERT_SUMMARY_FAIL_COUNTS +`define ENTROPY_SRC_REG_ALERT_SUMMARY_FAIL_COUNTS (32'ha4) +`define ENTROPY_SRC_REG_ALERT_SUMMARY_FAIL_COUNTS_ANY_FAIL_COUNT_LOW (0) +`define ENTROPY_SRC_REG_ALERT_SUMMARY_FAIL_COUNTS_ANY_FAIL_COUNT_MASK (32'hffff) +`endif +`ifndef ENTROPY_SRC_REG_ALERT_FAIL_COUNTS +`define ENTROPY_SRC_REG_ALERT_FAIL_COUNTS (32'ha8) +`define ENTROPY_SRC_REG_ALERT_FAIL_COUNTS_REPCNT_FAIL_COUNT_LOW (4) +`define ENTROPY_SRC_REG_ALERT_FAIL_COUNTS_REPCNT_FAIL_COUNT_MASK (32'hf0) +`define ENTROPY_SRC_REG_ALERT_FAIL_COUNTS_ADAPTP_HI_FAIL_COUNT_LOW (8) +`define ENTROPY_SRC_REG_ALERT_FAIL_COUNTS_ADAPTP_HI_FAIL_COUNT_MASK (32'hf00) +`define ENTROPY_SRC_REG_ALERT_FAIL_COUNTS_ADAPTP_LO_FAIL_COUNT_LOW (12) +`define ENTROPY_SRC_REG_ALERT_FAIL_COUNTS_ADAPTP_LO_FAIL_COUNT_MASK (32'hf000) +`define ENTROPY_SRC_REG_ALERT_FAIL_COUNTS_BUCKET_FAIL_COUNT_LOW (16) +`define ENTROPY_SRC_REG_ALERT_FAIL_COUNTS_BUCKET_FAIL_COUNT_MASK (32'hf0000) +`define ENTROPY_SRC_REG_ALERT_FAIL_COUNTS_MARKOV_HI_FAIL_COUNT_LOW (20) +`define ENTROPY_SRC_REG_ALERT_FAIL_COUNTS_MARKOV_HI_FAIL_COUNT_MASK (32'hf00000) +`define ENTROPY_SRC_REG_ALERT_FAIL_COUNTS_MARKOV_LO_FAIL_COUNT_LOW (24) +`define ENTROPY_SRC_REG_ALERT_FAIL_COUNTS_MARKOV_LO_FAIL_COUNT_MASK (32'hf000000) +`define ENTROPY_SRC_REG_ALERT_FAIL_COUNTS_REPCNTS_FAIL_COUNT_LOW (28) +`define ENTROPY_SRC_REG_ALERT_FAIL_COUNTS_REPCNTS_FAIL_COUNT_MASK (32'hf0000000) +`endif +`ifndef ENTROPY_SRC_REG_EXTHT_FAIL_COUNTS +`define ENTROPY_SRC_REG_EXTHT_FAIL_COUNTS (32'hac) +`define ENTROPY_SRC_REG_EXTHT_FAIL_COUNTS_EXTHT_HI_FAIL_COUNT_LOW (0) +`define ENTROPY_SRC_REG_EXTHT_FAIL_COUNTS_EXTHT_HI_FAIL_COUNT_MASK (32'hf) +`define ENTROPY_SRC_REG_EXTHT_FAIL_COUNTS_EXTHT_LO_FAIL_COUNT_LOW (4) +`define ENTROPY_SRC_REG_EXTHT_FAIL_COUNTS_EXTHT_LO_FAIL_COUNT_MASK (32'hf0) +`endif +`ifndef ENTROPY_SRC_REG_FW_OV_CONTROL +`define ENTROPY_SRC_REG_FW_OV_CONTROL (32'hb0) +`define ENTROPY_SRC_REG_FW_OV_CONTROL_FW_OV_MODE_LOW (0) +`define ENTROPY_SRC_REG_FW_OV_CONTROL_FW_OV_MODE_MASK (32'hf) +`define ENTROPY_SRC_REG_FW_OV_CONTROL_FW_OV_ENTROPY_INSERT_LOW (4) +`define ENTROPY_SRC_REG_FW_OV_CONTROL_FW_OV_ENTROPY_INSERT_MASK (32'hf0) +`endif +`ifndef ENTROPY_SRC_REG_FW_OV_SHA3_START +`define ENTROPY_SRC_REG_FW_OV_SHA3_START (32'hb4) +`define ENTROPY_SRC_REG_FW_OV_SHA3_START_FW_OV_INSERT_START_LOW (0) +`define ENTROPY_SRC_REG_FW_OV_SHA3_START_FW_OV_INSERT_START_MASK (32'hf) +`endif +`ifndef ENTROPY_SRC_REG_FW_OV_WR_FIFO_FULL +`define ENTROPY_SRC_REG_FW_OV_WR_FIFO_FULL (32'hb8) +`define ENTROPY_SRC_REG_FW_OV_WR_FIFO_FULL_FW_OV_WR_FIFO_FULL_LOW (0) +`define ENTROPY_SRC_REG_FW_OV_WR_FIFO_FULL_FW_OV_WR_FIFO_FULL_MASK (32'h1) +`endif +`ifndef ENTROPY_SRC_REG_FW_OV_RD_FIFO_OVERFLOW +`define ENTROPY_SRC_REG_FW_OV_RD_FIFO_OVERFLOW (32'hbc) +`define ENTROPY_SRC_REG_FW_OV_RD_FIFO_OVERFLOW_FW_OV_RD_FIFO_OVERFLOW_LOW (0) +`define ENTROPY_SRC_REG_FW_OV_RD_FIFO_OVERFLOW_FW_OV_RD_FIFO_OVERFLOW_MASK (32'h1) +`endif +`ifndef ENTROPY_SRC_REG_FW_OV_RD_DATA +`define ENTROPY_SRC_REG_FW_OV_RD_DATA (32'hc0) +`endif +`ifndef ENTROPY_SRC_REG_FW_OV_WR_DATA +`define ENTROPY_SRC_REG_FW_OV_WR_DATA (32'hc4) +`endif +`ifndef ENTROPY_SRC_REG_OBSERVE_FIFO_THRESH +`define ENTROPY_SRC_REG_OBSERVE_FIFO_THRESH (32'hc8) +`define ENTROPY_SRC_REG_OBSERVE_FIFO_THRESH_OBSERVE_FIFO_THRESH_LOW (0) +`define ENTROPY_SRC_REG_OBSERVE_FIFO_THRESH_OBSERVE_FIFO_THRESH_MASK (32'h3f) +`endif +`ifndef ENTROPY_SRC_REG_OBSERVE_FIFO_DEPTH +`define ENTROPY_SRC_REG_OBSERVE_FIFO_DEPTH (32'hcc) +`define ENTROPY_SRC_REG_OBSERVE_FIFO_DEPTH_OBSERVE_FIFO_DEPTH_LOW (0) +`define ENTROPY_SRC_REG_OBSERVE_FIFO_DEPTH_OBSERVE_FIFO_DEPTH_MASK (32'h3f) +`endif +`ifndef ENTROPY_SRC_REG_DEBUG_STATUS +`define ENTROPY_SRC_REG_DEBUG_STATUS (32'hd0) +`define ENTROPY_SRC_REG_DEBUG_STATUS_ENTROPY_FIFO_DEPTH_LOW (0) +`define ENTROPY_SRC_REG_DEBUG_STATUS_ENTROPY_FIFO_DEPTH_MASK (32'h3) +`define ENTROPY_SRC_REG_DEBUG_STATUS_SHA3_FSM_LOW (3) +`define ENTROPY_SRC_REG_DEBUG_STATUS_SHA3_FSM_MASK (32'h38) +`define ENTROPY_SRC_REG_DEBUG_STATUS_SHA3_BLOCK_PR_LOW (6) +`define ENTROPY_SRC_REG_DEBUG_STATUS_SHA3_BLOCK_PR_MASK (32'h40) +`define ENTROPY_SRC_REG_DEBUG_STATUS_SHA3_SQUEEZING_LOW (7) +`define ENTROPY_SRC_REG_DEBUG_STATUS_SHA3_SQUEEZING_MASK (32'h80) +`define ENTROPY_SRC_REG_DEBUG_STATUS_SHA3_ABSORBED_LOW (8) +`define ENTROPY_SRC_REG_DEBUG_STATUS_SHA3_ABSORBED_MASK (32'h100) +`define ENTROPY_SRC_REG_DEBUG_STATUS_SHA3_ERR_LOW (9) +`define ENTROPY_SRC_REG_DEBUG_STATUS_SHA3_ERR_MASK (32'h200) +`define ENTROPY_SRC_REG_DEBUG_STATUS_MAIN_SM_IDLE_LOW (16) +`define ENTROPY_SRC_REG_DEBUG_STATUS_MAIN_SM_IDLE_MASK (32'h10000) +`define ENTROPY_SRC_REG_DEBUG_STATUS_MAIN_SM_BOOT_DONE_LOW (17) +`define ENTROPY_SRC_REG_DEBUG_STATUS_MAIN_SM_BOOT_DONE_MASK (32'h20000) +`endif +`ifndef ENTROPY_SRC_REG_RECOV_ALERT_STS +`define ENTROPY_SRC_REG_RECOV_ALERT_STS (32'hd4) +`define ENTROPY_SRC_REG_RECOV_ALERT_STS_FIPS_ENABLE_FIELD_ALERT_LOW (0) +`define ENTROPY_SRC_REG_RECOV_ALERT_STS_FIPS_ENABLE_FIELD_ALERT_MASK (32'h1) +`define ENTROPY_SRC_REG_RECOV_ALERT_STS_ENTROPY_DATA_REG_EN_FIELD_ALERT_LOW (1) +`define ENTROPY_SRC_REG_RECOV_ALERT_STS_ENTROPY_DATA_REG_EN_FIELD_ALERT_MASK (32'h2) +`define ENTROPY_SRC_REG_RECOV_ALERT_STS_MODULE_ENABLE_FIELD_ALERT_LOW (2) +`define ENTROPY_SRC_REG_RECOV_ALERT_STS_MODULE_ENABLE_FIELD_ALERT_MASK (32'h4) +`define ENTROPY_SRC_REG_RECOV_ALERT_STS_THRESHOLD_SCOPE_FIELD_ALERT_LOW (3) +`define ENTROPY_SRC_REG_RECOV_ALERT_STS_THRESHOLD_SCOPE_FIELD_ALERT_MASK (32'h8) +`define ENTROPY_SRC_REG_RECOV_ALERT_STS_RNG_BIT_ENABLE_FIELD_ALERT_LOW (5) +`define ENTROPY_SRC_REG_RECOV_ALERT_STS_RNG_BIT_ENABLE_FIELD_ALERT_MASK (32'h20) +`define ENTROPY_SRC_REG_RECOV_ALERT_STS_FW_OV_SHA3_START_FIELD_ALERT_LOW (7) +`define ENTROPY_SRC_REG_RECOV_ALERT_STS_FW_OV_SHA3_START_FIELD_ALERT_MASK (32'h80) +`define ENTROPY_SRC_REG_RECOV_ALERT_STS_FW_OV_MODE_FIELD_ALERT_LOW (8) +`define ENTROPY_SRC_REG_RECOV_ALERT_STS_FW_OV_MODE_FIELD_ALERT_MASK (32'h100) +`define ENTROPY_SRC_REG_RECOV_ALERT_STS_FW_OV_ENTROPY_INSERT_FIELD_ALERT_LOW (9) +`define ENTROPY_SRC_REG_RECOV_ALERT_STS_FW_OV_ENTROPY_INSERT_FIELD_ALERT_MASK (32'h200) +`define ENTROPY_SRC_REG_RECOV_ALERT_STS_ES_ROUTE_FIELD_ALERT_LOW (10) +`define ENTROPY_SRC_REG_RECOV_ALERT_STS_ES_ROUTE_FIELD_ALERT_MASK (32'h400) +`define ENTROPY_SRC_REG_RECOV_ALERT_STS_ES_TYPE_FIELD_ALERT_LOW (11) +`define ENTROPY_SRC_REG_RECOV_ALERT_STS_ES_TYPE_FIELD_ALERT_MASK (32'h800) +`define ENTROPY_SRC_REG_RECOV_ALERT_STS_ES_MAIN_SM_ALERT_LOW (12) +`define ENTROPY_SRC_REG_RECOV_ALERT_STS_ES_MAIN_SM_ALERT_MASK (32'h1000) +`define ENTROPY_SRC_REG_RECOV_ALERT_STS_ES_BUS_CMP_ALERT_LOW (13) +`define ENTROPY_SRC_REG_RECOV_ALERT_STS_ES_BUS_CMP_ALERT_MASK (32'h2000) +`define ENTROPY_SRC_REG_RECOV_ALERT_STS_ES_THRESH_CFG_ALERT_LOW (14) +`define ENTROPY_SRC_REG_RECOV_ALERT_STS_ES_THRESH_CFG_ALERT_MASK (32'h4000) +`define ENTROPY_SRC_REG_RECOV_ALERT_STS_ES_FW_OV_WR_ALERT_LOW (15) +`define ENTROPY_SRC_REG_RECOV_ALERT_STS_ES_FW_OV_WR_ALERT_MASK (32'h8000) +`define ENTROPY_SRC_REG_RECOV_ALERT_STS_ES_FW_OV_DISABLE_ALERT_LOW (16) +`define ENTROPY_SRC_REG_RECOV_ALERT_STS_ES_FW_OV_DISABLE_ALERT_MASK (32'h10000) +`define ENTROPY_SRC_REG_RECOV_ALERT_STS_FIPS_FLAG_FIELD_ALERT_LOW (17) +`define ENTROPY_SRC_REG_RECOV_ALERT_STS_FIPS_FLAG_FIELD_ALERT_MASK (32'h20000) +`define ENTROPY_SRC_REG_RECOV_ALERT_STS_RNG_FIPS_FIELD_ALERT_LOW (18) +`define ENTROPY_SRC_REG_RECOV_ALERT_STS_RNG_FIPS_FIELD_ALERT_MASK (32'h40000) +`define ENTROPY_SRC_REG_RECOV_ALERT_STS_POSTHT_ENTROPY_DROP_ALERT_LOW (31) +`define ENTROPY_SRC_REG_RECOV_ALERT_STS_POSTHT_ENTROPY_DROP_ALERT_MASK (32'h80000000) +`endif +`ifndef ENTROPY_SRC_REG_ERR_CODE +`define ENTROPY_SRC_REG_ERR_CODE (32'hd8) +`define ENTROPY_SRC_REG_ERR_CODE_SFIFO_ESRNG_ERR_LOW (0) +`define ENTROPY_SRC_REG_ERR_CODE_SFIFO_ESRNG_ERR_MASK (32'h1) +`define ENTROPY_SRC_REG_ERR_CODE_SFIFO_DISTR_ERR_LOW (1) +`define ENTROPY_SRC_REG_ERR_CODE_SFIFO_DISTR_ERR_MASK (32'h2) +`define ENTROPY_SRC_REG_ERR_CODE_SFIFO_OBSERVE_ERR_LOW (2) +`define ENTROPY_SRC_REG_ERR_CODE_SFIFO_OBSERVE_ERR_MASK (32'h4) +`define ENTROPY_SRC_REG_ERR_CODE_SFIFO_ESFINAL_ERR_LOW (3) +`define ENTROPY_SRC_REG_ERR_CODE_SFIFO_ESFINAL_ERR_MASK (32'h8) +`define ENTROPY_SRC_REG_ERR_CODE_ES_ACK_SM_ERR_LOW (20) +`define ENTROPY_SRC_REG_ERR_CODE_ES_ACK_SM_ERR_MASK (32'h100000) +`define ENTROPY_SRC_REG_ERR_CODE_ES_MAIN_SM_ERR_LOW (21) +`define ENTROPY_SRC_REG_ERR_CODE_ES_MAIN_SM_ERR_MASK (32'h200000) +`define ENTROPY_SRC_REG_ERR_CODE_ES_CNTR_ERR_LOW (22) +`define ENTROPY_SRC_REG_ERR_CODE_ES_CNTR_ERR_MASK (32'h400000) +`define ENTROPY_SRC_REG_ERR_CODE_SHA3_STATE_ERR_LOW (23) +`define ENTROPY_SRC_REG_ERR_CODE_SHA3_STATE_ERR_MASK (32'h800000) +`define ENTROPY_SRC_REG_ERR_CODE_SHA3_RST_STORAGE_ERR_LOW (24) +`define ENTROPY_SRC_REG_ERR_CODE_SHA3_RST_STORAGE_ERR_MASK (32'h1000000) +`define ENTROPY_SRC_REG_ERR_CODE_FIFO_WRITE_ERR_LOW (28) +`define ENTROPY_SRC_REG_ERR_CODE_FIFO_WRITE_ERR_MASK (32'h10000000) +`define ENTROPY_SRC_REG_ERR_CODE_FIFO_READ_ERR_LOW (29) +`define ENTROPY_SRC_REG_ERR_CODE_FIFO_READ_ERR_MASK (32'h20000000) +`define ENTROPY_SRC_REG_ERR_CODE_FIFO_STATE_ERR_LOW (30) +`define ENTROPY_SRC_REG_ERR_CODE_FIFO_STATE_ERR_MASK (32'h40000000) +`endif +`ifndef ENTROPY_SRC_REG_ERR_CODE_TEST +`define ENTROPY_SRC_REG_ERR_CODE_TEST (32'hdc) +`define ENTROPY_SRC_REG_ERR_CODE_TEST_ERR_CODE_TEST_LOW (0) +`define ENTROPY_SRC_REG_ERR_CODE_TEST_ERR_CODE_TEST_MASK (32'h1f) +`endif +`ifndef ENTROPY_SRC_REG_MAIN_SM_STATE +`define ENTROPY_SRC_REG_MAIN_SM_STATE (32'he0) +`define ENTROPY_SRC_REG_MAIN_SM_STATE_MAIN_SM_STATE_LOW (0) +`define ENTROPY_SRC_REG_MAIN_SM_STATE_MAIN_SM_STATE_MASK (32'h1ff) +`endif +`ifndef MBOX_CSR_MBOX_LOCK +`define MBOX_CSR_MBOX_LOCK (32'h0) +`define MBOX_CSR_MBOX_LOCK_LOCK_LOW (0) +`define MBOX_CSR_MBOX_LOCK_LOCK_MASK (32'h1) +`endif +`ifndef MBOX_CSR_MBOX_USER +`define MBOX_CSR_MBOX_USER (32'h4) +`endif +`ifndef MBOX_CSR_MBOX_CMD +`define MBOX_CSR_MBOX_CMD (32'h8) +`endif +`ifndef MBOX_CSR_MBOX_DLEN +`define MBOX_CSR_MBOX_DLEN (32'hc) +`endif +`ifndef MBOX_CSR_MBOX_DATAIN +`define MBOX_CSR_MBOX_DATAIN (32'h10) +`endif +`ifndef MBOX_CSR_MBOX_DATAOUT +`define MBOX_CSR_MBOX_DATAOUT (32'h14) +`endif +`ifndef MBOX_CSR_MBOX_EXECUTE +`define MBOX_CSR_MBOX_EXECUTE (32'h18) +`define MBOX_CSR_MBOX_EXECUTE_EXECUTE_LOW (0) +`define MBOX_CSR_MBOX_EXECUTE_EXECUTE_MASK (32'h1) +`endif +`ifndef MBOX_CSR_MBOX_STATUS +`define MBOX_CSR_MBOX_STATUS (32'h1c) +`define MBOX_CSR_MBOX_STATUS_STATUS_LOW (0) +`define MBOX_CSR_MBOX_STATUS_STATUS_MASK (32'hf) +`define MBOX_CSR_MBOX_STATUS_ECC_SINGLE_ERROR_LOW (4) +`define MBOX_CSR_MBOX_STATUS_ECC_SINGLE_ERROR_MASK (32'h10) +`define MBOX_CSR_MBOX_STATUS_ECC_DOUBLE_ERROR_LOW (5) +`define MBOX_CSR_MBOX_STATUS_ECC_DOUBLE_ERROR_MASK (32'h20) +`define MBOX_CSR_MBOX_STATUS_MBOX_FSM_PS_LOW (6) +`define MBOX_CSR_MBOX_STATUS_MBOX_FSM_PS_MASK (32'h1c0) +`define MBOX_CSR_MBOX_STATUS_SOC_HAS_LOCK_LOW (9) +`define MBOX_CSR_MBOX_STATUS_SOC_HAS_LOCK_MASK (32'h200) +`define MBOX_CSR_MBOX_STATUS_MBOX_RDPTR_LOW (10) +`define MBOX_CSR_MBOX_STATUS_MBOX_RDPTR_MASK (32'h3fffc00) +`define MBOX_CSR_MBOX_STATUS_TAP_HAS_LOCK_LOW (26) +`define MBOX_CSR_MBOX_STATUS_TAP_HAS_LOCK_MASK (32'h4000000) +`endif +`ifndef MBOX_CSR_MBOX_UNLOCK +`define MBOX_CSR_MBOX_UNLOCK (32'h20) +`define MBOX_CSR_MBOX_UNLOCK_UNLOCK_LOW (0) +`define MBOX_CSR_MBOX_UNLOCK_UNLOCK_MASK (32'h1) +`endif +`ifndef MBOX_CSR_TAP_MODE +`define MBOX_CSR_TAP_MODE (32'h24) +`define MBOX_CSR_TAP_MODE_ENABLED_LOW (0) +`define MBOX_CSR_TAP_MODE_ENABLED_MASK (32'h1) +`endif +`ifndef SHA512_ACC_CSR_LOCK +`define SHA512_ACC_CSR_LOCK (32'h0) +`define SHA512_ACC_CSR_LOCK_LOCK_LOW (0) +`define SHA512_ACC_CSR_LOCK_LOCK_MASK (32'h1) +`endif +`ifndef SHA512_ACC_CSR_USER +`define SHA512_ACC_CSR_USER (32'h4) +`endif +`ifndef SHA512_ACC_CSR_MODE +`define SHA512_ACC_CSR_MODE (32'h8) +`define SHA512_ACC_CSR_MODE_MODE_LOW (0) +`define SHA512_ACC_CSR_MODE_MODE_MASK (32'h3) +`define SHA512_ACC_CSR_MODE_ENDIAN_TOGGLE_LOW (2) +`define SHA512_ACC_CSR_MODE_ENDIAN_TOGGLE_MASK (32'h4) +`endif +`ifndef SHA512_ACC_CSR_START_ADDRESS +`define SHA512_ACC_CSR_START_ADDRESS (32'hc) +`endif +`ifndef SHA512_ACC_CSR_DLEN +`define SHA512_ACC_CSR_DLEN (32'h10) +`endif +`ifndef SHA512_ACC_CSR_DATAIN +`define SHA512_ACC_CSR_DATAIN (32'h14) +`endif +`ifndef SHA512_ACC_CSR_EXECUTE +`define SHA512_ACC_CSR_EXECUTE (32'h18) +`define SHA512_ACC_CSR_EXECUTE_EXECUTE_LOW (0) +`define SHA512_ACC_CSR_EXECUTE_EXECUTE_MASK (32'h1) +`endif +`ifndef SHA512_ACC_CSR_STATUS +`define SHA512_ACC_CSR_STATUS (32'h1c) +`define SHA512_ACC_CSR_STATUS_VALID_LOW (0) +`define SHA512_ACC_CSR_STATUS_VALID_MASK (32'h1) +`define SHA512_ACC_CSR_STATUS_SOC_HAS_LOCK_LOW (1) +`define SHA512_ACC_CSR_STATUS_SOC_HAS_LOCK_MASK (32'h2) +`endif +`ifndef SHA512_ACC_CSR_DIGEST_0 +`define SHA512_ACC_CSR_DIGEST_0 (32'h20) +`endif +`ifndef SHA512_ACC_CSR_DIGEST_1 +`define SHA512_ACC_CSR_DIGEST_1 (32'h24) +`endif +`ifndef SHA512_ACC_CSR_DIGEST_2 +`define SHA512_ACC_CSR_DIGEST_2 (32'h28) +`endif +`ifndef SHA512_ACC_CSR_DIGEST_3 +`define SHA512_ACC_CSR_DIGEST_3 (32'h2c) +`endif +`ifndef SHA512_ACC_CSR_DIGEST_4 +`define SHA512_ACC_CSR_DIGEST_4 (32'h30) +`endif +`ifndef SHA512_ACC_CSR_DIGEST_5 +`define SHA512_ACC_CSR_DIGEST_5 (32'h34) +`endif +`ifndef SHA512_ACC_CSR_DIGEST_6 +`define SHA512_ACC_CSR_DIGEST_6 (32'h38) +`endif +`ifndef SHA512_ACC_CSR_DIGEST_7 +`define SHA512_ACC_CSR_DIGEST_7 (32'h3c) +`endif +`ifndef SHA512_ACC_CSR_DIGEST_8 +`define SHA512_ACC_CSR_DIGEST_8 (32'h40) +`endif +`ifndef SHA512_ACC_CSR_DIGEST_9 +`define SHA512_ACC_CSR_DIGEST_9 (32'h44) +`endif +`ifndef SHA512_ACC_CSR_DIGEST_10 +`define SHA512_ACC_CSR_DIGEST_10 (32'h48) +`endif +`ifndef SHA512_ACC_CSR_DIGEST_11 +`define SHA512_ACC_CSR_DIGEST_11 (32'h4c) +`endif +`ifndef SHA512_ACC_CSR_DIGEST_12 +`define SHA512_ACC_CSR_DIGEST_12 (32'h50) +`endif +`ifndef SHA512_ACC_CSR_DIGEST_13 +`define SHA512_ACC_CSR_DIGEST_13 (32'h54) +`endif +`ifndef SHA512_ACC_CSR_DIGEST_14 +`define SHA512_ACC_CSR_DIGEST_14 (32'h58) +`endif +`ifndef SHA512_ACC_CSR_DIGEST_15 +`define SHA512_ACC_CSR_DIGEST_15 (32'h5c) +`endif +`ifndef SHA512_ACC_CSR_CONTROL +`define SHA512_ACC_CSR_CONTROL (32'h60) +`define SHA512_ACC_CSR_CONTROL_ZEROIZE_LOW (0) +`define SHA512_ACC_CSR_CONTROL_ZEROIZE_MASK (32'h1) +`endif +`ifndef SHA512_ACC_CSR_INTR_BLOCK_RF_GLOBAL_INTR_EN_R +`define SHA512_ACC_CSR_INTR_BLOCK_RF_GLOBAL_INTR_EN_R (32'h800) +`define SHA512_ACC_CSR_INTR_BLOCK_RF_GLOBAL_INTR_EN_R_ERROR_EN_LOW (0) +`define SHA512_ACC_CSR_INTR_BLOCK_RF_GLOBAL_INTR_EN_R_ERROR_EN_MASK (32'h1) +`define SHA512_ACC_CSR_INTR_BLOCK_RF_GLOBAL_INTR_EN_R_NOTIF_EN_LOW (1) +`define SHA512_ACC_CSR_INTR_BLOCK_RF_GLOBAL_INTR_EN_R_NOTIF_EN_MASK (32'h2) +`endif +`ifndef SHA512_ACC_CSR_INTR_BLOCK_RF_ERROR_INTR_EN_R +`define SHA512_ACC_CSR_INTR_BLOCK_RF_ERROR_INTR_EN_R (32'h804) +`define SHA512_ACC_CSR_INTR_BLOCK_RF_ERROR_INTR_EN_R_ERROR0_EN_LOW (0) +`define SHA512_ACC_CSR_INTR_BLOCK_RF_ERROR_INTR_EN_R_ERROR0_EN_MASK (32'h1) +`define SHA512_ACC_CSR_INTR_BLOCK_RF_ERROR_INTR_EN_R_ERROR1_EN_LOW (1) +`define SHA512_ACC_CSR_INTR_BLOCK_RF_ERROR_INTR_EN_R_ERROR1_EN_MASK (32'h2) +`define SHA512_ACC_CSR_INTR_BLOCK_RF_ERROR_INTR_EN_R_ERROR2_EN_LOW (2) +`define SHA512_ACC_CSR_INTR_BLOCK_RF_ERROR_INTR_EN_R_ERROR2_EN_MASK (32'h4) +`define SHA512_ACC_CSR_INTR_BLOCK_RF_ERROR_INTR_EN_R_ERROR3_EN_LOW (3) +`define SHA512_ACC_CSR_INTR_BLOCK_RF_ERROR_INTR_EN_R_ERROR3_EN_MASK (32'h8) +`endif +`ifndef SHA512_ACC_CSR_INTR_BLOCK_RF_NOTIF_INTR_EN_R +`define SHA512_ACC_CSR_INTR_BLOCK_RF_NOTIF_INTR_EN_R (32'h808) +`define SHA512_ACC_CSR_INTR_BLOCK_RF_NOTIF_INTR_EN_R_NOTIF_CMD_DONE_EN_LOW (0) +`define SHA512_ACC_CSR_INTR_BLOCK_RF_NOTIF_INTR_EN_R_NOTIF_CMD_DONE_EN_MASK (32'h1) +`endif +`ifndef SHA512_ACC_CSR_INTR_BLOCK_RF_ERROR_GLOBAL_INTR_R +`define SHA512_ACC_CSR_INTR_BLOCK_RF_ERROR_GLOBAL_INTR_R (32'h80c) +`define SHA512_ACC_CSR_INTR_BLOCK_RF_ERROR_GLOBAL_INTR_R_AGG_STS_LOW (0) +`define SHA512_ACC_CSR_INTR_BLOCK_RF_ERROR_GLOBAL_INTR_R_AGG_STS_MASK (32'h1) +`endif +`ifndef SHA512_ACC_CSR_INTR_BLOCK_RF_NOTIF_GLOBAL_INTR_R +`define SHA512_ACC_CSR_INTR_BLOCK_RF_NOTIF_GLOBAL_INTR_R (32'h810) +`define SHA512_ACC_CSR_INTR_BLOCK_RF_NOTIF_GLOBAL_INTR_R_AGG_STS_LOW (0) +`define SHA512_ACC_CSR_INTR_BLOCK_RF_NOTIF_GLOBAL_INTR_R_AGG_STS_MASK (32'h1) +`endif +`ifndef SHA512_ACC_CSR_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R +`define SHA512_ACC_CSR_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R (32'h814) +`define SHA512_ACC_CSR_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR0_STS_LOW (0) +`define SHA512_ACC_CSR_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR0_STS_MASK (32'h1) +`define SHA512_ACC_CSR_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR1_STS_LOW (1) +`define SHA512_ACC_CSR_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR1_STS_MASK (32'h2) +`define SHA512_ACC_CSR_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR2_STS_LOW (2) +`define SHA512_ACC_CSR_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR2_STS_MASK (32'h4) +`define SHA512_ACC_CSR_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR3_STS_LOW (3) +`define SHA512_ACC_CSR_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR3_STS_MASK (32'h8) +`endif +`ifndef SHA512_ACC_CSR_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R +`define SHA512_ACC_CSR_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R (32'h818) +`define SHA512_ACC_CSR_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_CMD_DONE_STS_LOW (0) +`define SHA512_ACC_CSR_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_CMD_DONE_STS_MASK (32'h1) +`endif +`ifndef SHA512_ACC_CSR_INTR_BLOCK_RF_ERROR_INTR_TRIG_R +`define SHA512_ACC_CSR_INTR_BLOCK_RF_ERROR_INTR_TRIG_R (32'h81c) +`define SHA512_ACC_CSR_INTR_BLOCK_RF_ERROR_INTR_TRIG_R_ERROR0_TRIG_LOW (0) +`define SHA512_ACC_CSR_INTR_BLOCK_RF_ERROR_INTR_TRIG_R_ERROR0_TRIG_MASK (32'h1) +`define SHA512_ACC_CSR_INTR_BLOCK_RF_ERROR_INTR_TRIG_R_ERROR1_TRIG_LOW (1) +`define SHA512_ACC_CSR_INTR_BLOCK_RF_ERROR_INTR_TRIG_R_ERROR1_TRIG_MASK (32'h2) +`define SHA512_ACC_CSR_INTR_BLOCK_RF_ERROR_INTR_TRIG_R_ERROR2_TRIG_LOW (2) +`define SHA512_ACC_CSR_INTR_BLOCK_RF_ERROR_INTR_TRIG_R_ERROR2_TRIG_MASK (32'h4) +`define SHA512_ACC_CSR_INTR_BLOCK_RF_ERROR_INTR_TRIG_R_ERROR3_TRIG_LOW (3) +`define SHA512_ACC_CSR_INTR_BLOCK_RF_ERROR_INTR_TRIG_R_ERROR3_TRIG_MASK (32'h8) +`endif +`ifndef SHA512_ACC_CSR_INTR_BLOCK_RF_NOTIF_INTR_TRIG_R +`define SHA512_ACC_CSR_INTR_BLOCK_RF_NOTIF_INTR_TRIG_R (32'h820) +`define SHA512_ACC_CSR_INTR_BLOCK_RF_NOTIF_INTR_TRIG_R_NOTIF_CMD_DONE_TRIG_LOW (0) +`define SHA512_ACC_CSR_INTR_BLOCK_RF_NOTIF_INTR_TRIG_R_NOTIF_CMD_DONE_TRIG_MASK (32'h1) +`endif +`ifndef SHA512_ACC_CSR_INTR_BLOCK_RF_ERROR0_INTR_COUNT_R +`define SHA512_ACC_CSR_INTR_BLOCK_RF_ERROR0_INTR_COUNT_R (32'h900) +`endif +`ifndef SHA512_ACC_CSR_INTR_BLOCK_RF_ERROR1_INTR_COUNT_R +`define SHA512_ACC_CSR_INTR_BLOCK_RF_ERROR1_INTR_COUNT_R (32'h904) +`endif +`ifndef SHA512_ACC_CSR_INTR_BLOCK_RF_ERROR2_INTR_COUNT_R +`define SHA512_ACC_CSR_INTR_BLOCK_RF_ERROR2_INTR_COUNT_R (32'h908) +`endif +`ifndef SHA512_ACC_CSR_INTR_BLOCK_RF_ERROR3_INTR_COUNT_R +`define SHA512_ACC_CSR_INTR_BLOCK_RF_ERROR3_INTR_COUNT_R (32'h90c) +`endif +`ifndef SHA512_ACC_CSR_INTR_BLOCK_RF_NOTIF_CMD_DONE_INTR_COUNT_R +`define SHA512_ACC_CSR_INTR_BLOCK_RF_NOTIF_CMD_DONE_INTR_COUNT_R (32'h980) +`endif +`ifndef SHA512_ACC_CSR_INTR_BLOCK_RF_ERROR0_INTR_COUNT_INCR_R +`define SHA512_ACC_CSR_INTR_BLOCK_RF_ERROR0_INTR_COUNT_INCR_R (32'ha00) +`define SHA512_ACC_CSR_INTR_BLOCK_RF_ERROR0_INTR_COUNT_INCR_R_PULSE_LOW (0) +`define SHA512_ACC_CSR_INTR_BLOCK_RF_ERROR0_INTR_COUNT_INCR_R_PULSE_MASK (32'h1) +`endif +`ifndef SHA512_ACC_CSR_INTR_BLOCK_RF_ERROR1_INTR_COUNT_INCR_R +`define SHA512_ACC_CSR_INTR_BLOCK_RF_ERROR1_INTR_COUNT_INCR_R (32'ha04) +`define SHA512_ACC_CSR_INTR_BLOCK_RF_ERROR1_INTR_COUNT_INCR_R_PULSE_LOW (0) +`define SHA512_ACC_CSR_INTR_BLOCK_RF_ERROR1_INTR_COUNT_INCR_R_PULSE_MASK (32'h1) +`endif +`ifndef SHA512_ACC_CSR_INTR_BLOCK_RF_ERROR2_INTR_COUNT_INCR_R +`define SHA512_ACC_CSR_INTR_BLOCK_RF_ERROR2_INTR_COUNT_INCR_R (32'ha08) +`define SHA512_ACC_CSR_INTR_BLOCK_RF_ERROR2_INTR_COUNT_INCR_R_PULSE_LOW (0) +`define SHA512_ACC_CSR_INTR_BLOCK_RF_ERROR2_INTR_COUNT_INCR_R_PULSE_MASK (32'h1) +`endif +`ifndef SHA512_ACC_CSR_INTR_BLOCK_RF_ERROR3_INTR_COUNT_INCR_R +`define SHA512_ACC_CSR_INTR_BLOCK_RF_ERROR3_INTR_COUNT_INCR_R (32'ha0c) +`define SHA512_ACC_CSR_INTR_BLOCK_RF_ERROR3_INTR_COUNT_INCR_R_PULSE_LOW (0) +`define SHA512_ACC_CSR_INTR_BLOCK_RF_ERROR3_INTR_COUNT_INCR_R_PULSE_MASK (32'h1) +`endif +`ifndef SHA512_ACC_CSR_INTR_BLOCK_RF_NOTIF_CMD_DONE_INTR_COUNT_INCR_R +`define SHA512_ACC_CSR_INTR_BLOCK_RF_NOTIF_CMD_DONE_INTR_COUNT_INCR_R (32'ha10) +`define SHA512_ACC_CSR_INTR_BLOCK_RF_NOTIF_CMD_DONE_INTR_COUNT_INCR_R_PULSE_LOW (0) +`define SHA512_ACC_CSR_INTR_BLOCK_RF_NOTIF_CMD_DONE_INTR_COUNT_INCR_R_PULSE_MASK (32'h1) +`endif +`ifndef AXI_DMA_REG_ID +`define AXI_DMA_REG_ID (32'h0) +`endif +`ifndef AXI_DMA_REG_CAP +`define AXI_DMA_REG_CAP (32'h4) +`define AXI_DMA_REG_CAP_FIFO_MAX_DEPTH_LOW (0) +`define AXI_DMA_REG_CAP_FIFO_MAX_DEPTH_MASK (32'hfff) +`define AXI_DMA_REG_CAP_RSVD_LOW (12) +`define AXI_DMA_REG_CAP_RSVD_MASK (32'hfffff000) +`endif +`ifndef AXI_DMA_REG_CTRL +`define AXI_DMA_REG_CTRL (32'h8) +`define AXI_DMA_REG_CTRL_GO_LOW (0) +`define AXI_DMA_REG_CTRL_GO_MASK (32'h1) +`define AXI_DMA_REG_CTRL_FLUSH_LOW (1) +`define AXI_DMA_REG_CTRL_FLUSH_MASK (32'h2) +`define AXI_DMA_REG_CTRL_AES_MODE_EN_LOW (2) +`define AXI_DMA_REG_CTRL_AES_MODE_EN_MASK (32'h4) +`define AXI_DMA_REG_CTRL_AES_GCM_MODE_LOW (3) +`define AXI_DMA_REG_CTRL_AES_GCM_MODE_MASK (32'h8) +`define AXI_DMA_REG_CTRL_RSVD0_LOW (4) +`define AXI_DMA_REG_CTRL_RSVD0_MASK (32'hfff0) +`define AXI_DMA_REG_CTRL_RD_ROUTE_LOW (16) +`define AXI_DMA_REG_CTRL_RD_ROUTE_MASK (32'h30000) +`define AXI_DMA_REG_CTRL_RSVD1_LOW (18) +`define AXI_DMA_REG_CTRL_RSVD1_MASK (32'hc0000) +`define AXI_DMA_REG_CTRL_RD_FIXED_LOW (20) +`define AXI_DMA_REG_CTRL_RD_FIXED_MASK (32'h100000) +`define AXI_DMA_REG_CTRL_RSVD2_LOW (21) +`define AXI_DMA_REG_CTRL_RSVD2_MASK (32'he00000) +`define AXI_DMA_REG_CTRL_WR_ROUTE_LOW (24) +`define AXI_DMA_REG_CTRL_WR_ROUTE_MASK (32'h7000000) +`define AXI_DMA_REG_CTRL_RSVD3_LOW (27) +`define AXI_DMA_REG_CTRL_RSVD3_MASK (32'h8000000) +`define AXI_DMA_REG_CTRL_WR_FIXED_LOW (28) +`define AXI_DMA_REG_CTRL_WR_FIXED_MASK (32'h10000000) +`define AXI_DMA_REG_CTRL_RSVD4_LOW (29) +`define AXI_DMA_REG_CTRL_RSVD4_MASK (32'he0000000) +`endif +`ifndef AXI_DMA_REG_STATUS0 +`define AXI_DMA_REG_STATUS0 (32'hc) +`define AXI_DMA_REG_STATUS0_BUSY_LOW (0) +`define AXI_DMA_REG_STATUS0_BUSY_MASK (32'h1) +`define AXI_DMA_REG_STATUS0_ERROR_LOW (1) +`define AXI_DMA_REG_STATUS0_ERROR_MASK (32'h2) +`define AXI_DMA_REG_STATUS0_RSVD0_LOW (2) +`define AXI_DMA_REG_STATUS0_RSVD0_MASK (32'hc) +`define AXI_DMA_REG_STATUS0_FIFO_DEPTH_LOW (4) +`define AXI_DMA_REG_STATUS0_FIFO_DEPTH_MASK (32'hfff0) +`define AXI_DMA_REG_STATUS0_AXI_DMA_FSM_PS_LOW (16) +`define AXI_DMA_REG_STATUS0_AXI_DMA_FSM_PS_MASK (32'h30000) +`define AXI_DMA_REG_STATUS0_PAYLOAD_AVAILABLE_LOW (18) +`define AXI_DMA_REG_STATUS0_PAYLOAD_AVAILABLE_MASK (32'h40000) +`define AXI_DMA_REG_STATUS0_IMAGE_ACTIVATED_LOW (19) +`define AXI_DMA_REG_STATUS0_IMAGE_ACTIVATED_MASK (32'h80000) +`define AXI_DMA_REG_STATUS0_AXI_DMA_AES_FSM_PS_LOW (20) +`define AXI_DMA_REG_STATUS0_AXI_DMA_AES_FSM_PS_MASK (32'hf00000) +`define AXI_DMA_REG_STATUS0_RSVD1_LOW (24) +`define AXI_DMA_REG_STATUS0_RSVD1_MASK (32'hff000000) +`endif +`ifndef AXI_DMA_REG_STATUS1 +`define AXI_DMA_REG_STATUS1 (32'h10) +`endif +`ifndef AXI_DMA_REG_SRC_ADDR_L +`define AXI_DMA_REG_SRC_ADDR_L (32'h14) +`endif +`ifndef AXI_DMA_REG_SRC_ADDR_H +`define AXI_DMA_REG_SRC_ADDR_H (32'h18) +`endif +`ifndef AXI_DMA_REG_DST_ADDR_L +`define AXI_DMA_REG_DST_ADDR_L (32'h1c) +`endif +`ifndef AXI_DMA_REG_DST_ADDR_H +`define AXI_DMA_REG_DST_ADDR_H (32'h20) +`endif +`ifndef AXI_DMA_REG_BYTE_COUNT +`define AXI_DMA_REG_BYTE_COUNT (32'h24) +`endif +`ifndef AXI_DMA_REG_BLOCK_SIZE +`define AXI_DMA_REG_BLOCK_SIZE (32'h28) +`define AXI_DMA_REG_BLOCK_SIZE_SIZE_LOW (0) +`define AXI_DMA_REG_BLOCK_SIZE_SIZE_MASK (32'hfff) +`define AXI_DMA_REG_BLOCK_SIZE_RSVD_LOW (12) +`define AXI_DMA_REG_BLOCK_SIZE_RSVD_MASK (32'hfffff000) +`endif +`ifndef AXI_DMA_REG_WRITE_DATA +`define AXI_DMA_REG_WRITE_DATA (32'h2c) +`endif +`ifndef AXI_DMA_REG_READ_DATA +`define AXI_DMA_REG_READ_DATA (32'h30) +`endif +`ifndef AXI_DMA_REG_INTR_BLOCK_RF_GLOBAL_INTR_EN_R +`define AXI_DMA_REG_INTR_BLOCK_RF_GLOBAL_INTR_EN_R (32'h800) +`define AXI_DMA_REG_INTR_BLOCK_RF_GLOBAL_INTR_EN_R_ERROR_EN_LOW (0) +`define AXI_DMA_REG_INTR_BLOCK_RF_GLOBAL_INTR_EN_R_ERROR_EN_MASK (32'h1) +`define AXI_DMA_REG_INTR_BLOCK_RF_GLOBAL_INTR_EN_R_NOTIF_EN_LOW (1) +`define AXI_DMA_REG_INTR_BLOCK_RF_GLOBAL_INTR_EN_R_NOTIF_EN_MASK (32'h2) +`endif +`ifndef AXI_DMA_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R (32'h804) +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R_ERROR_CMD_DEC_EN_LOW (0) +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R_ERROR_CMD_DEC_EN_MASK (32'h1) +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R_ERROR_AXI_RD_EN_LOW (1) +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R_ERROR_AXI_RD_EN_MASK (32'h2) +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R_ERROR_AXI_WR_EN_LOW (2) +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R_ERROR_AXI_WR_EN_MASK (32'h4) +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R_ERROR_MBOX_LOCK_EN_LOW (3) +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R_ERROR_MBOX_LOCK_EN_MASK (32'h8) +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R_ERROR_SHA_LOCK_EN_LOW (4) +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R_ERROR_SHA_LOCK_EN_MASK (32'h10) +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R_ERROR_FIFO_OFLOW_EN_LOW (5) +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R_ERROR_FIFO_OFLOW_EN_MASK (32'h20) +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R_ERROR_FIFO_UFLOW_EN_LOW (6) +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R_ERROR_FIFO_UFLOW_EN_MASK (32'h40) +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R_ERROR_AES_CIF_EN_LOW (7) +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R_ERROR_AES_CIF_EN_MASK (32'h80) +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R_ERROR_KV_RD_EN_LOW (8) +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R_ERROR_KV_RD_EN_MASK (32'h100) +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R_ERROR_KV_RD_LARGE_EN_LOW (9) +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R_ERROR_KV_RD_LARGE_EN_MASK (32'h200) +`endif +`ifndef AXI_DMA_REG_INTR_BLOCK_RF_NOTIF_INTR_EN_R +`define AXI_DMA_REG_INTR_BLOCK_RF_NOTIF_INTR_EN_R (32'h808) +`define AXI_DMA_REG_INTR_BLOCK_RF_NOTIF_INTR_EN_R_NOTIF_TXN_DONE_EN_LOW (0) +`define AXI_DMA_REG_INTR_BLOCK_RF_NOTIF_INTR_EN_R_NOTIF_TXN_DONE_EN_MASK (32'h1) +`define AXI_DMA_REG_INTR_BLOCK_RF_NOTIF_INTR_EN_R_NOTIF_FIFO_EMPTY_EN_LOW (1) +`define AXI_DMA_REG_INTR_BLOCK_RF_NOTIF_INTR_EN_R_NOTIF_FIFO_EMPTY_EN_MASK (32'h2) +`define AXI_DMA_REG_INTR_BLOCK_RF_NOTIF_INTR_EN_R_NOTIF_FIFO_NOT_EMPTY_EN_LOW (2) +`define AXI_DMA_REG_INTR_BLOCK_RF_NOTIF_INTR_EN_R_NOTIF_FIFO_NOT_EMPTY_EN_MASK (32'h4) +`define AXI_DMA_REG_INTR_BLOCK_RF_NOTIF_INTR_EN_R_NOTIF_FIFO_FULL_EN_LOW (3) +`define AXI_DMA_REG_INTR_BLOCK_RF_NOTIF_INTR_EN_R_NOTIF_FIFO_FULL_EN_MASK (32'h8) +`define AXI_DMA_REG_INTR_BLOCK_RF_NOTIF_INTR_EN_R_NOTIF_FIFO_NOT_FULL_EN_LOW (4) +`define AXI_DMA_REG_INTR_BLOCK_RF_NOTIF_INTR_EN_R_NOTIF_FIFO_NOT_FULL_EN_MASK (32'h10) +`endif +`ifndef AXI_DMA_REG_INTR_BLOCK_RF_ERROR_GLOBAL_INTR_R +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_GLOBAL_INTR_R (32'h80c) +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_GLOBAL_INTR_R_AGG_STS_LOW (0) +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_GLOBAL_INTR_R_AGG_STS_MASK (32'h1) +`endif +`ifndef AXI_DMA_REG_INTR_BLOCK_RF_NOTIF_GLOBAL_INTR_R +`define AXI_DMA_REG_INTR_BLOCK_RF_NOTIF_GLOBAL_INTR_R (32'h810) +`define AXI_DMA_REG_INTR_BLOCK_RF_NOTIF_GLOBAL_INTR_R_AGG_STS_LOW (0) +`define AXI_DMA_REG_INTR_BLOCK_RF_NOTIF_GLOBAL_INTR_R_AGG_STS_MASK (32'h1) +`endif +`ifndef AXI_DMA_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R (32'h814) +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_CMD_DEC_STS_LOW (0) +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_CMD_DEC_STS_MASK (32'h1) +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_AXI_RD_STS_LOW (1) +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_AXI_RD_STS_MASK (32'h2) +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_AXI_WR_STS_LOW (2) +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_AXI_WR_STS_MASK (32'h4) +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_MBOX_LOCK_STS_LOW (3) +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_MBOX_LOCK_STS_MASK (32'h8) +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_SHA_LOCK_STS_LOW (4) +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_SHA_LOCK_STS_MASK (32'h10) +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_FIFO_OFLOW_STS_LOW (5) +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_FIFO_OFLOW_STS_MASK (32'h20) +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_FIFO_UFLOW_STS_LOW (6) +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_FIFO_UFLOW_STS_MASK (32'h40) +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_AES_CIF_STS_LOW (7) +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_AES_CIF_STS_MASK (32'h80) +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_KV_RD_STS_LOW (8) +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_KV_RD_STS_MASK (32'h100) +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_KV_RD_LARGE_STS_LOW (9) +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_KV_RD_LARGE_STS_MASK (32'h200) +`endif +`ifndef AXI_DMA_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R +`define AXI_DMA_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R (32'h818) +`define AXI_DMA_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_TXN_DONE_STS_LOW (0) +`define AXI_DMA_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_TXN_DONE_STS_MASK (32'h1) +`define AXI_DMA_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_FIFO_EMPTY_STS_LOW (1) +`define AXI_DMA_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_FIFO_EMPTY_STS_MASK (32'h2) +`define AXI_DMA_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_FIFO_NOT_EMPTY_STS_LOW (2) +`define AXI_DMA_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_FIFO_NOT_EMPTY_STS_MASK (32'h4) +`define AXI_DMA_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_FIFO_FULL_STS_LOW (3) +`define AXI_DMA_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_FIFO_FULL_STS_MASK (32'h8) +`define AXI_DMA_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_FIFO_NOT_FULL_STS_LOW (4) +`define AXI_DMA_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_FIFO_NOT_FULL_STS_MASK (32'h10) +`endif +`ifndef AXI_DMA_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R (32'h81c) +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R_ERROR_CMD_DEC_TRIG_LOW (0) +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R_ERROR_CMD_DEC_TRIG_MASK (32'h1) +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R_ERROR_AXI_RD_TRIG_LOW (1) +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R_ERROR_AXI_RD_TRIG_MASK (32'h2) +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R_ERROR_AXI_WR_TRIG_LOW (2) +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R_ERROR_AXI_WR_TRIG_MASK (32'h4) +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R_ERROR_MBOX_LOCK_TRIG_LOW (3) +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R_ERROR_MBOX_LOCK_TRIG_MASK (32'h8) +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R_ERROR_SHA_LOCK_TRIG_LOW (4) +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R_ERROR_SHA_LOCK_TRIG_MASK (32'h10) +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R_ERROR_FIFO_OFLOW_TRIG_LOW (5) +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R_ERROR_FIFO_OFLOW_TRIG_MASK (32'h20) +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R_ERROR_FIFO_UFLOW_TRIG_LOW (6) +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R_ERROR_FIFO_UFLOW_TRIG_MASK (32'h40) +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R_ERROR_AES_CIF_TRIG_LOW (7) +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R_ERROR_AES_CIF_TRIG_MASK (32'h80) +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R_ERROR_KV_RD_TRIG_LOW (8) +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R_ERROR_KV_RD_TRIG_MASK (32'h100) +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R_ERROR_KV_RD_LARGE_TRIG_LOW (9) +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R_ERROR_KV_RD_LARGE_TRIG_MASK (32'h200) +`endif +`ifndef AXI_DMA_REG_INTR_BLOCK_RF_NOTIF_INTR_TRIG_R +`define AXI_DMA_REG_INTR_BLOCK_RF_NOTIF_INTR_TRIG_R (32'h820) +`define AXI_DMA_REG_INTR_BLOCK_RF_NOTIF_INTR_TRIG_R_NOTIF_TXN_DONE_TRIG_LOW (0) +`define AXI_DMA_REG_INTR_BLOCK_RF_NOTIF_INTR_TRIG_R_NOTIF_TXN_DONE_TRIG_MASK (32'h1) +`define AXI_DMA_REG_INTR_BLOCK_RF_NOTIF_INTR_TRIG_R_NOTIF_FIFO_EMPTY_TRIG_LOW (1) +`define AXI_DMA_REG_INTR_BLOCK_RF_NOTIF_INTR_TRIG_R_NOTIF_FIFO_EMPTY_TRIG_MASK (32'h2) +`define AXI_DMA_REG_INTR_BLOCK_RF_NOTIF_INTR_TRIG_R_NOTIF_FIFO_NOT_EMPTY_TRIG_LOW (2) +`define AXI_DMA_REG_INTR_BLOCK_RF_NOTIF_INTR_TRIG_R_NOTIF_FIFO_NOT_EMPTY_TRIG_MASK (32'h4) +`define AXI_DMA_REG_INTR_BLOCK_RF_NOTIF_INTR_TRIG_R_NOTIF_FIFO_FULL_TRIG_LOW (3) +`define AXI_DMA_REG_INTR_BLOCK_RF_NOTIF_INTR_TRIG_R_NOTIF_FIFO_FULL_TRIG_MASK (32'h8) +`define AXI_DMA_REG_INTR_BLOCK_RF_NOTIF_INTR_TRIG_R_NOTIF_FIFO_NOT_FULL_TRIG_LOW (4) +`define AXI_DMA_REG_INTR_BLOCK_RF_NOTIF_INTR_TRIG_R_NOTIF_FIFO_NOT_FULL_TRIG_MASK (32'h10) +`endif +`ifndef AXI_DMA_REG_INTR_BLOCK_RF_ERROR_CMD_DEC_INTR_COUNT_R +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_CMD_DEC_INTR_COUNT_R (32'h900) +`endif +`ifndef AXI_DMA_REG_INTR_BLOCK_RF_ERROR_AXI_RD_INTR_COUNT_R +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_AXI_RD_INTR_COUNT_R (32'h904) +`endif +`ifndef AXI_DMA_REG_INTR_BLOCK_RF_ERROR_AXI_WR_INTR_COUNT_R +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_AXI_WR_INTR_COUNT_R (32'h908) +`endif +`ifndef AXI_DMA_REG_INTR_BLOCK_RF_ERROR_MBOX_LOCK_INTR_COUNT_R +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_MBOX_LOCK_INTR_COUNT_R (32'h90c) +`endif +`ifndef AXI_DMA_REG_INTR_BLOCK_RF_ERROR_SHA_LOCK_INTR_COUNT_R +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_SHA_LOCK_INTR_COUNT_R (32'h910) +`endif +`ifndef AXI_DMA_REG_INTR_BLOCK_RF_ERROR_FIFO_OFLOW_INTR_COUNT_R +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_FIFO_OFLOW_INTR_COUNT_R (32'h914) +`endif +`ifndef AXI_DMA_REG_INTR_BLOCK_RF_ERROR_FIFO_UFLOW_INTR_COUNT_R +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_FIFO_UFLOW_INTR_COUNT_R (32'h918) +`endif +`ifndef AXI_DMA_REG_INTR_BLOCK_RF_ERROR_AES_CIF_INTR_COUNT_R +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_AES_CIF_INTR_COUNT_R (32'h91c) +`endif +`ifndef AXI_DMA_REG_INTR_BLOCK_RF_ERROR_KV_RD_INTR_COUNT_R +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_KV_RD_INTR_COUNT_R (32'h920) +`endif +`ifndef AXI_DMA_REG_INTR_BLOCK_RF_ERROR_KV_RD_LARGE_INTR_COUNT_R +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_KV_RD_LARGE_INTR_COUNT_R (32'h924) +`endif +`ifndef AXI_DMA_REG_INTR_BLOCK_RF_NOTIF_TXN_DONE_INTR_COUNT_R +`define AXI_DMA_REG_INTR_BLOCK_RF_NOTIF_TXN_DONE_INTR_COUNT_R (32'h980) +`endif +`ifndef AXI_DMA_REG_INTR_BLOCK_RF_NOTIF_FIFO_EMPTY_INTR_COUNT_R +`define AXI_DMA_REG_INTR_BLOCK_RF_NOTIF_FIFO_EMPTY_INTR_COUNT_R (32'h984) +`endif +`ifndef AXI_DMA_REG_INTR_BLOCK_RF_NOTIF_FIFO_NOT_EMPTY_INTR_COUNT_R +`define AXI_DMA_REG_INTR_BLOCK_RF_NOTIF_FIFO_NOT_EMPTY_INTR_COUNT_R (32'h988) +`endif +`ifndef AXI_DMA_REG_INTR_BLOCK_RF_NOTIF_FIFO_FULL_INTR_COUNT_R +`define AXI_DMA_REG_INTR_BLOCK_RF_NOTIF_FIFO_FULL_INTR_COUNT_R (32'h98c) +`endif +`ifndef AXI_DMA_REG_INTR_BLOCK_RF_NOTIF_FIFO_NOT_FULL_INTR_COUNT_R +`define AXI_DMA_REG_INTR_BLOCK_RF_NOTIF_FIFO_NOT_FULL_INTR_COUNT_R (32'h990) +`endif +`ifndef AXI_DMA_REG_INTR_BLOCK_RF_ERROR_CMD_DEC_INTR_COUNT_INCR_R +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_CMD_DEC_INTR_COUNT_INCR_R (32'ha00) +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_CMD_DEC_INTR_COUNT_INCR_R_PULSE_LOW (0) +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_CMD_DEC_INTR_COUNT_INCR_R_PULSE_MASK (32'h1) +`endif +`ifndef AXI_DMA_REG_INTR_BLOCK_RF_ERROR_AXI_RD_INTR_COUNT_INCR_R +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_AXI_RD_INTR_COUNT_INCR_R (32'ha04) +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_AXI_RD_INTR_COUNT_INCR_R_PULSE_LOW (0) +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_AXI_RD_INTR_COUNT_INCR_R_PULSE_MASK (32'h1) +`endif +`ifndef AXI_DMA_REG_INTR_BLOCK_RF_ERROR_AXI_WR_INTR_COUNT_INCR_R +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_AXI_WR_INTR_COUNT_INCR_R (32'ha08) +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_AXI_WR_INTR_COUNT_INCR_R_PULSE_LOW (0) +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_AXI_WR_INTR_COUNT_INCR_R_PULSE_MASK (32'h1) +`endif +`ifndef AXI_DMA_REG_INTR_BLOCK_RF_ERROR_MBOX_LOCK_INTR_COUNT_INCR_R +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_MBOX_LOCK_INTR_COUNT_INCR_R (32'ha0c) +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_MBOX_LOCK_INTR_COUNT_INCR_R_PULSE_LOW (0) +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_MBOX_LOCK_INTR_COUNT_INCR_R_PULSE_MASK (32'h1) +`endif +`ifndef AXI_DMA_REG_INTR_BLOCK_RF_ERROR_SHA_LOCK_INTR_COUNT_INCR_R +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_SHA_LOCK_INTR_COUNT_INCR_R (32'ha10) +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_SHA_LOCK_INTR_COUNT_INCR_R_PULSE_LOW (0) +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_SHA_LOCK_INTR_COUNT_INCR_R_PULSE_MASK (32'h1) +`endif +`ifndef AXI_DMA_REG_INTR_BLOCK_RF_ERROR_FIFO_OFLOW_INTR_COUNT_INCR_R +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_FIFO_OFLOW_INTR_COUNT_INCR_R (32'ha14) +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_FIFO_OFLOW_INTR_COUNT_INCR_R_PULSE_LOW (0) +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_FIFO_OFLOW_INTR_COUNT_INCR_R_PULSE_MASK (32'h1) +`endif +`ifndef AXI_DMA_REG_INTR_BLOCK_RF_ERROR_FIFO_UFLOW_INTR_COUNT_INCR_R +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_FIFO_UFLOW_INTR_COUNT_INCR_R (32'ha18) +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_FIFO_UFLOW_INTR_COUNT_INCR_R_PULSE_LOW (0) +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_FIFO_UFLOW_INTR_COUNT_INCR_R_PULSE_MASK (32'h1) +`endif +`ifndef AXI_DMA_REG_INTR_BLOCK_RF_ERROR_AES_CIF_INTR_COUNT_INCR_R +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_AES_CIF_INTR_COUNT_INCR_R (32'ha1c) +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_AES_CIF_INTR_COUNT_INCR_R_PULSE_LOW (0) +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_AES_CIF_INTR_COUNT_INCR_R_PULSE_MASK (32'h1) +`endif +`ifndef AXI_DMA_REG_INTR_BLOCK_RF_ERROR_KV_RD_INTR_COUNT_INCR_R +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_KV_RD_INTR_COUNT_INCR_R (32'ha20) +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_KV_RD_INTR_COUNT_INCR_R_PULSE_LOW (0) +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_KV_RD_INTR_COUNT_INCR_R_PULSE_MASK (32'h1) +`endif +`ifndef AXI_DMA_REG_INTR_BLOCK_RF_ERROR_KV_RD_LARGE_INTR_COUNT_INCR_R +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_KV_RD_LARGE_INTR_COUNT_INCR_R (32'ha24) +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_KV_RD_LARGE_INTR_COUNT_INCR_R_PULSE_LOW (0) +`define AXI_DMA_REG_INTR_BLOCK_RF_ERROR_KV_RD_LARGE_INTR_COUNT_INCR_R_PULSE_MASK (32'h1) +`endif +`ifndef AXI_DMA_REG_INTR_BLOCK_RF_NOTIF_TXN_DONE_INTR_COUNT_INCR_R +`define AXI_DMA_REG_INTR_BLOCK_RF_NOTIF_TXN_DONE_INTR_COUNT_INCR_R (32'ha28) +`define AXI_DMA_REG_INTR_BLOCK_RF_NOTIF_TXN_DONE_INTR_COUNT_INCR_R_PULSE_LOW (0) +`define AXI_DMA_REG_INTR_BLOCK_RF_NOTIF_TXN_DONE_INTR_COUNT_INCR_R_PULSE_MASK (32'h1) +`endif +`ifndef AXI_DMA_REG_INTR_BLOCK_RF_NOTIF_FIFO_EMPTY_INTR_COUNT_INCR_R +`define AXI_DMA_REG_INTR_BLOCK_RF_NOTIF_FIFO_EMPTY_INTR_COUNT_INCR_R (32'ha2c) +`define AXI_DMA_REG_INTR_BLOCK_RF_NOTIF_FIFO_EMPTY_INTR_COUNT_INCR_R_PULSE_LOW (0) +`define AXI_DMA_REG_INTR_BLOCK_RF_NOTIF_FIFO_EMPTY_INTR_COUNT_INCR_R_PULSE_MASK (32'h1) +`endif +`ifndef AXI_DMA_REG_INTR_BLOCK_RF_NOTIF_FIFO_NOT_EMPTY_INTR_COUNT_INCR_R +`define AXI_DMA_REG_INTR_BLOCK_RF_NOTIF_FIFO_NOT_EMPTY_INTR_COUNT_INCR_R (32'ha30) +`define AXI_DMA_REG_INTR_BLOCK_RF_NOTIF_FIFO_NOT_EMPTY_INTR_COUNT_INCR_R_PULSE_LOW (0) +`define AXI_DMA_REG_INTR_BLOCK_RF_NOTIF_FIFO_NOT_EMPTY_INTR_COUNT_INCR_R_PULSE_MASK (32'h1) +`endif +`ifndef AXI_DMA_REG_INTR_BLOCK_RF_NOTIF_FIFO_FULL_INTR_COUNT_INCR_R +`define AXI_DMA_REG_INTR_BLOCK_RF_NOTIF_FIFO_FULL_INTR_COUNT_INCR_R (32'ha34) +`define AXI_DMA_REG_INTR_BLOCK_RF_NOTIF_FIFO_FULL_INTR_COUNT_INCR_R_PULSE_LOW (0) +`define AXI_DMA_REG_INTR_BLOCK_RF_NOTIF_FIFO_FULL_INTR_COUNT_INCR_R_PULSE_MASK (32'h1) +`endif +`ifndef AXI_DMA_REG_INTR_BLOCK_RF_NOTIF_FIFO_NOT_FULL_INTR_COUNT_INCR_R +`define AXI_DMA_REG_INTR_BLOCK_RF_NOTIF_FIFO_NOT_FULL_INTR_COUNT_INCR_R (32'ha38) +`define AXI_DMA_REG_INTR_BLOCK_RF_NOTIF_FIFO_NOT_FULL_INTR_COUNT_INCR_R_PULSE_LOW (0) +`define AXI_DMA_REG_INTR_BLOCK_RF_NOTIF_FIFO_NOT_FULL_INTR_COUNT_INCR_R_PULSE_MASK (32'h1) +`endif +`ifndef SOC_IFC_REG_CPTRA_HW_ERROR_FATAL +`define SOC_IFC_REG_CPTRA_HW_ERROR_FATAL (32'h0) +`define SOC_IFC_REG_CPTRA_HW_ERROR_FATAL_ICCM_ECC_UNC_LOW (0) +`define SOC_IFC_REG_CPTRA_HW_ERROR_FATAL_ICCM_ECC_UNC_MASK (32'h1) +`define SOC_IFC_REG_CPTRA_HW_ERROR_FATAL_DCCM_ECC_UNC_LOW (1) +`define SOC_IFC_REG_CPTRA_HW_ERROR_FATAL_DCCM_ECC_UNC_MASK (32'h2) +`define SOC_IFC_REG_CPTRA_HW_ERROR_FATAL_NMI_PIN_LOW (2) +`define SOC_IFC_REG_CPTRA_HW_ERROR_FATAL_NMI_PIN_MASK (32'h4) +`define SOC_IFC_REG_CPTRA_HW_ERROR_FATAL_CRYPTO_ERR_LOW (3) +`define SOC_IFC_REG_CPTRA_HW_ERROR_FATAL_CRYPTO_ERR_MASK (32'h8) +`define SOC_IFC_REG_CPTRA_HW_ERROR_FATAL_RSVD_LOW (4) +`define SOC_IFC_REG_CPTRA_HW_ERROR_FATAL_RSVD_MASK (32'hfffffff0) +`endif +`ifndef SOC_IFC_REG_CPTRA_HW_ERROR_NON_FATAL +`define SOC_IFC_REG_CPTRA_HW_ERROR_NON_FATAL (32'h4) +`define SOC_IFC_REG_CPTRA_HW_ERROR_NON_FATAL_MBOX_PROT_NO_LOCK_LOW (0) +`define SOC_IFC_REG_CPTRA_HW_ERROR_NON_FATAL_MBOX_PROT_NO_LOCK_MASK (32'h1) +`define SOC_IFC_REG_CPTRA_HW_ERROR_NON_FATAL_MBOX_PROT_OOO_LOW (1) +`define SOC_IFC_REG_CPTRA_HW_ERROR_NON_FATAL_MBOX_PROT_OOO_MASK (32'h2) +`define SOC_IFC_REG_CPTRA_HW_ERROR_NON_FATAL_MBOX_ECC_UNC_LOW (2) +`define SOC_IFC_REG_CPTRA_HW_ERROR_NON_FATAL_MBOX_ECC_UNC_MASK (32'h4) +`define SOC_IFC_REG_CPTRA_HW_ERROR_NON_FATAL_RSVD_LOW (3) +`define SOC_IFC_REG_CPTRA_HW_ERROR_NON_FATAL_RSVD_MASK (32'hfffffff8) +`endif +`ifndef SOC_IFC_REG_CPTRA_FW_ERROR_FATAL +`define SOC_IFC_REG_CPTRA_FW_ERROR_FATAL (32'h8) +`endif +`ifndef SOC_IFC_REG_CPTRA_FW_ERROR_NON_FATAL +`define SOC_IFC_REG_CPTRA_FW_ERROR_NON_FATAL (32'hc) +`endif +`ifndef SOC_IFC_REG_CPTRA_HW_ERROR_ENC +`define SOC_IFC_REG_CPTRA_HW_ERROR_ENC (32'h10) +`endif +`ifndef SOC_IFC_REG_CPTRA_FW_ERROR_ENC +`define SOC_IFC_REG_CPTRA_FW_ERROR_ENC (32'h14) +`endif +`ifndef SOC_IFC_REG_CPTRA_FW_EXTENDED_ERROR_INFO_0 +`define SOC_IFC_REG_CPTRA_FW_EXTENDED_ERROR_INFO_0 (32'h18) +`endif +`ifndef SOC_IFC_REG_CPTRA_FW_EXTENDED_ERROR_INFO_1 +`define SOC_IFC_REG_CPTRA_FW_EXTENDED_ERROR_INFO_1 (32'h1c) +`endif +`ifndef SOC_IFC_REG_CPTRA_FW_EXTENDED_ERROR_INFO_2 +`define SOC_IFC_REG_CPTRA_FW_EXTENDED_ERROR_INFO_2 (32'h20) +`endif +`ifndef SOC_IFC_REG_CPTRA_FW_EXTENDED_ERROR_INFO_3 +`define SOC_IFC_REG_CPTRA_FW_EXTENDED_ERROR_INFO_3 (32'h24) +`endif +`ifndef SOC_IFC_REG_CPTRA_FW_EXTENDED_ERROR_INFO_4 +`define SOC_IFC_REG_CPTRA_FW_EXTENDED_ERROR_INFO_4 (32'h28) +`endif +`ifndef SOC_IFC_REG_CPTRA_FW_EXTENDED_ERROR_INFO_5 +`define SOC_IFC_REG_CPTRA_FW_EXTENDED_ERROR_INFO_5 (32'h2c) +`endif +`ifndef SOC_IFC_REG_CPTRA_FW_EXTENDED_ERROR_INFO_6 +`define SOC_IFC_REG_CPTRA_FW_EXTENDED_ERROR_INFO_6 (32'h30) +`endif +`ifndef SOC_IFC_REG_CPTRA_FW_EXTENDED_ERROR_INFO_7 +`define SOC_IFC_REG_CPTRA_FW_EXTENDED_ERROR_INFO_7 (32'h34) +`endif +`ifndef SOC_IFC_REG_CPTRA_BOOT_STATUS +`define SOC_IFC_REG_CPTRA_BOOT_STATUS (32'h38) +`endif +`ifndef SOC_IFC_REG_CPTRA_FLOW_STATUS +`define SOC_IFC_REG_CPTRA_FLOW_STATUS (32'h3c) +`define SOC_IFC_REG_CPTRA_FLOW_STATUS_STATUS_LOW (0) +`define SOC_IFC_REG_CPTRA_FLOW_STATUS_STATUS_MASK (32'hffffff) +`define SOC_IFC_REG_CPTRA_FLOW_STATUS_IDEVID_CSR_READY_LOW (24) +`define SOC_IFC_REG_CPTRA_FLOW_STATUS_IDEVID_CSR_READY_MASK (32'h1000000) +`define SOC_IFC_REG_CPTRA_FLOW_STATUS_BOOT_FSM_PS_LOW (25) +`define SOC_IFC_REG_CPTRA_FLOW_STATUS_BOOT_FSM_PS_MASK (32'he000000) +`define SOC_IFC_REG_CPTRA_FLOW_STATUS_READY_FOR_MB_PROCESSING_LOW (28) +`define SOC_IFC_REG_CPTRA_FLOW_STATUS_READY_FOR_MB_PROCESSING_MASK (32'h10000000) +`define SOC_IFC_REG_CPTRA_FLOW_STATUS_READY_FOR_RUNTIME_LOW (29) +`define SOC_IFC_REG_CPTRA_FLOW_STATUS_READY_FOR_RUNTIME_MASK (32'h20000000) +`define SOC_IFC_REG_CPTRA_FLOW_STATUS_READY_FOR_FUSES_LOW (30) +`define SOC_IFC_REG_CPTRA_FLOW_STATUS_READY_FOR_FUSES_MASK (32'h40000000) +`define SOC_IFC_REG_CPTRA_FLOW_STATUS_MAILBOX_FLOW_DONE_LOW (31) +`define SOC_IFC_REG_CPTRA_FLOW_STATUS_MAILBOX_FLOW_DONE_MASK (32'h80000000) +`endif +`ifndef SOC_IFC_REG_CPTRA_RESET_REASON +`define SOC_IFC_REG_CPTRA_RESET_REASON (32'h40) +`define SOC_IFC_REG_CPTRA_RESET_REASON_FW_UPD_RESET_LOW (0) +`define SOC_IFC_REG_CPTRA_RESET_REASON_FW_UPD_RESET_MASK (32'h1) +`define SOC_IFC_REG_CPTRA_RESET_REASON_WARM_RESET_LOW (1) +`define SOC_IFC_REG_CPTRA_RESET_REASON_WARM_RESET_MASK (32'h2) +`endif +`ifndef SOC_IFC_REG_CPTRA_SECURITY_STATE +`define SOC_IFC_REG_CPTRA_SECURITY_STATE (32'h44) +`define SOC_IFC_REG_CPTRA_SECURITY_STATE_DEVICE_LIFECYCLE_LOW (0) +`define SOC_IFC_REG_CPTRA_SECURITY_STATE_DEVICE_LIFECYCLE_MASK (32'h3) +`define SOC_IFC_REG_CPTRA_SECURITY_STATE_DEBUG_LOCKED_LOW (2) +`define SOC_IFC_REG_CPTRA_SECURITY_STATE_DEBUG_LOCKED_MASK (32'h4) +`define SOC_IFC_REG_CPTRA_SECURITY_STATE_SCAN_MODE_LOW (3) +`define SOC_IFC_REG_CPTRA_SECURITY_STATE_SCAN_MODE_MASK (32'h8) +`define SOC_IFC_REG_CPTRA_SECURITY_STATE_RSVD_LOW (4) +`define SOC_IFC_REG_CPTRA_SECURITY_STATE_RSVD_MASK (32'hfffffff0) +`endif +`ifndef SOC_IFC_REG_CPTRA_MBOX_VALID_AXI_USER_0 +`define SOC_IFC_REG_CPTRA_MBOX_VALID_AXI_USER_0 (32'h48) +`endif +`ifndef SOC_IFC_REG_CPTRA_MBOX_VALID_AXI_USER_1 +`define SOC_IFC_REG_CPTRA_MBOX_VALID_AXI_USER_1 (32'h4c) +`endif +`ifndef SOC_IFC_REG_CPTRA_MBOX_VALID_AXI_USER_2 +`define SOC_IFC_REG_CPTRA_MBOX_VALID_AXI_USER_2 (32'h50) +`endif +`ifndef SOC_IFC_REG_CPTRA_MBOX_VALID_AXI_USER_3 +`define SOC_IFC_REG_CPTRA_MBOX_VALID_AXI_USER_3 (32'h54) +`endif +`ifndef SOC_IFC_REG_CPTRA_MBOX_VALID_AXI_USER_4 +`define SOC_IFC_REG_CPTRA_MBOX_VALID_AXI_USER_4 (32'h58) +`endif +`ifndef SOC_IFC_REG_CPTRA_MBOX_AXI_USER_LOCK_0 +`define SOC_IFC_REG_CPTRA_MBOX_AXI_USER_LOCK_0 (32'h5c) +`define SOC_IFC_REG_CPTRA_MBOX_AXI_USER_LOCK_0_LOCK_LOW (0) +`define SOC_IFC_REG_CPTRA_MBOX_AXI_USER_LOCK_0_LOCK_MASK (32'h1) +`endif +`ifndef SOC_IFC_REG_CPTRA_MBOX_AXI_USER_LOCK_1 +`define SOC_IFC_REG_CPTRA_MBOX_AXI_USER_LOCK_1 (32'h60) +`define SOC_IFC_REG_CPTRA_MBOX_AXI_USER_LOCK_1_LOCK_LOW (0) +`define SOC_IFC_REG_CPTRA_MBOX_AXI_USER_LOCK_1_LOCK_MASK (32'h1) +`endif +`ifndef SOC_IFC_REG_CPTRA_MBOX_AXI_USER_LOCK_2 +`define SOC_IFC_REG_CPTRA_MBOX_AXI_USER_LOCK_2 (32'h64) +`define SOC_IFC_REG_CPTRA_MBOX_AXI_USER_LOCK_2_LOCK_LOW (0) +`define SOC_IFC_REG_CPTRA_MBOX_AXI_USER_LOCK_2_LOCK_MASK (32'h1) +`endif +`ifndef SOC_IFC_REG_CPTRA_MBOX_AXI_USER_LOCK_3 +`define SOC_IFC_REG_CPTRA_MBOX_AXI_USER_LOCK_3 (32'h68) +`define SOC_IFC_REG_CPTRA_MBOX_AXI_USER_LOCK_3_LOCK_LOW (0) +`define SOC_IFC_REG_CPTRA_MBOX_AXI_USER_LOCK_3_LOCK_MASK (32'h1) +`endif +`ifndef SOC_IFC_REG_CPTRA_MBOX_AXI_USER_LOCK_4 +`define SOC_IFC_REG_CPTRA_MBOX_AXI_USER_LOCK_4 (32'h6c) +`define SOC_IFC_REG_CPTRA_MBOX_AXI_USER_LOCK_4_LOCK_LOW (0) +`define SOC_IFC_REG_CPTRA_MBOX_AXI_USER_LOCK_4_LOCK_MASK (32'h1) +`endif +`ifndef SOC_IFC_REG_CPTRA_TRNG_VALID_AXI_USER +`define SOC_IFC_REG_CPTRA_TRNG_VALID_AXI_USER (32'h70) +`endif +`ifndef SOC_IFC_REG_CPTRA_TRNG_AXI_USER_LOCK +`define SOC_IFC_REG_CPTRA_TRNG_AXI_USER_LOCK (32'h74) +`define SOC_IFC_REG_CPTRA_TRNG_AXI_USER_LOCK_LOCK_LOW (0) +`define SOC_IFC_REG_CPTRA_TRNG_AXI_USER_LOCK_LOCK_MASK (32'h1) +`endif +`ifndef SOC_IFC_REG_CPTRA_TRNG_DATA_0 +`define SOC_IFC_REG_CPTRA_TRNG_DATA_0 (32'h78) +`endif +`ifndef SOC_IFC_REG_CPTRA_TRNG_DATA_1 +`define SOC_IFC_REG_CPTRA_TRNG_DATA_1 (32'h7c) +`endif +`ifndef SOC_IFC_REG_CPTRA_TRNG_DATA_2 +`define SOC_IFC_REG_CPTRA_TRNG_DATA_2 (32'h80) +`endif +`ifndef SOC_IFC_REG_CPTRA_TRNG_DATA_3 +`define SOC_IFC_REG_CPTRA_TRNG_DATA_3 (32'h84) +`endif +`ifndef SOC_IFC_REG_CPTRA_TRNG_DATA_4 +`define SOC_IFC_REG_CPTRA_TRNG_DATA_4 (32'h88) +`endif +`ifndef SOC_IFC_REG_CPTRA_TRNG_DATA_5 +`define SOC_IFC_REG_CPTRA_TRNG_DATA_5 (32'h8c) +`endif +`ifndef SOC_IFC_REG_CPTRA_TRNG_DATA_6 +`define SOC_IFC_REG_CPTRA_TRNG_DATA_6 (32'h90) +`endif +`ifndef SOC_IFC_REG_CPTRA_TRNG_DATA_7 +`define SOC_IFC_REG_CPTRA_TRNG_DATA_7 (32'h94) +`endif +`ifndef SOC_IFC_REG_CPTRA_TRNG_DATA_8 +`define SOC_IFC_REG_CPTRA_TRNG_DATA_8 (32'h98) +`endif +`ifndef SOC_IFC_REG_CPTRA_TRNG_DATA_9 +`define SOC_IFC_REG_CPTRA_TRNG_DATA_9 (32'h9c) +`endif +`ifndef SOC_IFC_REG_CPTRA_TRNG_DATA_10 +`define SOC_IFC_REG_CPTRA_TRNG_DATA_10 (32'ha0) +`endif +`ifndef SOC_IFC_REG_CPTRA_TRNG_DATA_11 +`define SOC_IFC_REG_CPTRA_TRNG_DATA_11 (32'ha4) +`endif +`ifndef SOC_IFC_REG_CPTRA_TRNG_CTRL +`define SOC_IFC_REG_CPTRA_TRNG_CTRL (32'ha8) +`define SOC_IFC_REG_CPTRA_TRNG_CTRL_CLEAR_LOW (0) +`define SOC_IFC_REG_CPTRA_TRNG_CTRL_CLEAR_MASK (32'h1) +`endif +`ifndef SOC_IFC_REG_CPTRA_TRNG_STATUS +`define SOC_IFC_REG_CPTRA_TRNG_STATUS (32'hac) +`define SOC_IFC_REG_CPTRA_TRNG_STATUS_DATA_REQ_LOW (0) +`define SOC_IFC_REG_CPTRA_TRNG_STATUS_DATA_REQ_MASK (32'h1) +`define SOC_IFC_REG_CPTRA_TRNG_STATUS_DATA_WR_DONE_LOW (1) +`define SOC_IFC_REG_CPTRA_TRNG_STATUS_DATA_WR_DONE_MASK (32'h2) +`endif +`ifndef SOC_IFC_REG_CPTRA_FUSE_WR_DONE +`define SOC_IFC_REG_CPTRA_FUSE_WR_DONE (32'hb0) +`define SOC_IFC_REG_CPTRA_FUSE_WR_DONE_DONE_LOW (0) +`define SOC_IFC_REG_CPTRA_FUSE_WR_DONE_DONE_MASK (32'h1) +`endif +`ifndef SOC_IFC_REG_CPTRA_TIMER_CONFIG +`define SOC_IFC_REG_CPTRA_TIMER_CONFIG (32'hb4) +`endif +`ifndef SOC_IFC_REG_CPTRA_BOOTFSM_GO +`define SOC_IFC_REG_CPTRA_BOOTFSM_GO (32'hb8) +`define SOC_IFC_REG_CPTRA_BOOTFSM_GO_GO_LOW (0) +`define SOC_IFC_REG_CPTRA_BOOTFSM_GO_GO_MASK (32'h1) +`endif +`ifndef SOC_IFC_REG_CPTRA_DBG_MANUF_SERVICE_REG +`define SOC_IFC_REG_CPTRA_DBG_MANUF_SERVICE_REG (32'hbc) +`endif +`ifndef SOC_IFC_REG_CPTRA_CLK_GATING_EN +`define SOC_IFC_REG_CPTRA_CLK_GATING_EN (32'hc0) +`define SOC_IFC_REG_CPTRA_CLK_GATING_EN_CLK_GATING_EN_LOW (0) +`define SOC_IFC_REG_CPTRA_CLK_GATING_EN_CLK_GATING_EN_MASK (32'h1) +`endif +`ifndef SOC_IFC_REG_CPTRA_GENERIC_INPUT_WIRES_0 +`define SOC_IFC_REG_CPTRA_GENERIC_INPUT_WIRES_0 (32'hc4) +`endif +`ifndef SOC_IFC_REG_CPTRA_GENERIC_INPUT_WIRES_1 +`define SOC_IFC_REG_CPTRA_GENERIC_INPUT_WIRES_1 (32'hc8) +`endif +`ifndef SOC_IFC_REG_CPTRA_GENERIC_OUTPUT_WIRES_0 +`define SOC_IFC_REG_CPTRA_GENERIC_OUTPUT_WIRES_0 (32'hcc) +`endif +`ifndef SOC_IFC_REG_CPTRA_GENERIC_OUTPUT_WIRES_1 +`define SOC_IFC_REG_CPTRA_GENERIC_OUTPUT_WIRES_1 (32'hd0) +`endif +`ifndef SOC_IFC_REG_CPTRA_HW_REV_ID +`define SOC_IFC_REG_CPTRA_HW_REV_ID (32'hd4) +`define SOC_IFC_REG_CPTRA_HW_REV_ID_CPTRA_GENERATION_LOW (0) +`define SOC_IFC_REG_CPTRA_HW_REV_ID_CPTRA_GENERATION_MASK (32'hffff) +`define SOC_IFC_REG_CPTRA_HW_REV_ID_SOC_STEPPING_ID_LOW (16) +`define SOC_IFC_REG_CPTRA_HW_REV_ID_SOC_STEPPING_ID_MASK (32'hffff0000) +`endif +`ifndef SOC_IFC_REG_CPTRA_FW_REV_ID_0 +`define SOC_IFC_REG_CPTRA_FW_REV_ID_0 (32'hd8) +`endif +`ifndef SOC_IFC_REG_CPTRA_FW_REV_ID_1 +`define SOC_IFC_REG_CPTRA_FW_REV_ID_1 (32'hdc) +`endif +`ifndef SOC_IFC_REG_CPTRA_HW_CONFIG +`define SOC_IFC_REG_CPTRA_HW_CONFIG (32'he0) +`define SOC_IFC_REG_CPTRA_HW_CONFIG_ITRNG_EN_LOW (0) +`define SOC_IFC_REG_CPTRA_HW_CONFIG_ITRNG_EN_MASK (32'h1) +`define SOC_IFC_REG_CPTRA_HW_CONFIG_FUSE_GRANULARITY_LOW (1) +`define SOC_IFC_REG_CPTRA_HW_CONFIG_FUSE_GRANULARITY_MASK (32'h2) +`define SOC_IFC_REG_CPTRA_HW_CONFIG_RSVD_EN_LOW (2) +`define SOC_IFC_REG_CPTRA_HW_CONFIG_RSVD_EN_MASK (32'hc) +`define SOC_IFC_REG_CPTRA_HW_CONFIG_LMS_ACC_EN_LOW (4) +`define SOC_IFC_REG_CPTRA_HW_CONFIG_LMS_ACC_EN_MASK (32'h10) +`define SOC_IFC_REG_CPTRA_HW_CONFIG_SUBSYSTEM_MODE_EN_LOW (5) +`define SOC_IFC_REG_CPTRA_HW_CONFIG_SUBSYSTEM_MODE_EN_MASK (32'h20) +`define SOC_IFC_REG_CPTRA_HW_CONFIG_OCP_LOCK_MODE_EN_LOW (6) +`define SOC_IFC_REG_CPTRA_HW_CONFIG_OCP_LOCK_MODE_EN_MASK (32'h40) +`endif +`ifndef SOC_IFC_REG_CPTRA_WDT_TIMER1_EN +`define SOC_IFC_REG_CPTRA_WDT_TIMER1_EN (32'he4) +`define SOC_IFC_REG_CPTRA_WDT_TIMER1_EN_TIMER1_EN_LOW (0) +`define SOC_IFC_REG_CPTRA_WDT_TIMER1_EN_TIMER1_EN_MASK (32'h1) +`endif +`ifndef SOC_IFC_REG_CPTRA_WDT_TIMER1_CTRL +`define SOC_IFC_REG_CPTRA_WDT_TIMER1_CTRL (32'he8) +`define SOC_IFC_REG_CPTRA_WDT_TIMER1_CTRL_TIMER1_RESTART_LOW (0) +`define SOC_IFC_REG_CPTRA_WDT_TIMER1_CTRL_TIMER1_RESTART_MASK (32'h1) +`endif +`ifndef SOC_IFC_REG_CPTRA_WDT_TIMER1_TIMEOUT_PERIOD_0 +`define SOC_IFC_REG_CPTRA_WDT_TIMER1_TIMEOUT_PERIOD_0 (32'hec) +`endif +`ifndef SOC_IFC_REG_CPTRA_WDT_TIMER1_TIMEOUT_PERIOD_1 +`define SOC_IFC_REG_CPTRA_WDT_TIMER1_TIMEOUT_PERIOD_1 (32'hf0) +`endif +`ifndef SOC_IFC_REG_CPTRA_WDT_TIMER2_EN +`define SOC_IFC_REG_CPTRA_WDT_TIMER2_EN (32'hf4) +`define SOC_IFC_REG_CPTRA_WDT_TIMER2_EN_TIMER2_EN_LOW (0) +`define SOC_IFC_REG_CPTRA_WDT_TIMER2_EN_TIMER2_EN_MASK (32'h1) +`endif +`ifndef SOC_IFC_REG_CPTRA_WDT_TIMER2_CTRL +`define SOC_IFC_REG_CPTRA_WDT_TIMER2_CTRL (32'hf8) +`define SOC_IFC_REG_CPTRA_WDT_TIMER2_CTRL_TIMER2_RESTART_LOW (0) +`define SOC_IFC_REG_CPTRA_WDT_TIMER2_CTRL_TIMER2_RESTART_MASK (32'h1) +`endif +`ifndef SOC_IFC_REG_CPTRA_WDT_TIMER2_TIMEOUT_PERIOD_0 +`define SOC_IFC_REG_CPTRA_WDT_TIMER2_TIMEOUT_PERIOD_0 (32'hfc) +`endif +`ifndef SOC_IFC_REG_CPTRA_WDT_TIMER2_TIMEOUT_PERIOD_1 +`define SOC_IFC_REG_CPTRA_WDT_TIMER2_TIMEOUT_PERIOD_1 (32'h100) +`endif +`ifndef SOC_IFC_REG_CPTRA_WDT_STATUS +`define SOC_IFC_REG_CPTRA_WDT_STATUS (32'h104) +`define SOC_IFC_REG_CPTRA_WDT_STATUS_T1_TIMEOUT_LOW (0) +`define SOC_IFC_REG_CPTRA_WDT_STATUS_T1_TIMEOUT_MASK (32'h1) +`define SOC_IFC_REG_CPTRA_WDT_STATUS_T2_TIMEOUT_LOW (1) +`define SOC_IFC_REG_CPTRA_WDT_STATUS_T2_TIMEOUT_MASK (32'h2) +`endif +`ifndef SOC_IFC_REG_CPTRA_FUSE_VALID_AXI_USER +`define SOC_IFC_REG_CPTRA_FUSE_VALID_AXI_USER (32'h108) +`endif +`ifndef SOC_IFC_REG_CPTRA_FUSE_AXI_USER_LOCK +`define SOC_IFC_REG_CPTRA_FUSE_AXI_USER_LOCK (32'h10c) +`define SOC_IFC_REG_CPTRA_FUSE_AXI_USER_LOCK_LOCK_LOW (0) +`define SOC_IFC_REG_CPTRA_FUSE_AXI_USER_LOCK_LOCK_MASK (32'h1) +`endif +`ifndef SOC_IFC_REG_CPTRA_WDT_CFG_0 +`define SOC_IFC_REG_CPTRA_WDT_CFG_0 (32'h110) +`endif +`ifndef SOC_IFC_REG_CPTRA_WDT_CFG_1 +`define SOC_IFC_REG_CPTRA_WDT_CFG_1 (32'h114) +`endif +`ifndef SOC_IFC_REG_CPTRA_ITRNG_ENTROPY_CONFIG_0 +`define SOC_IFC_REG_CPTRA_ITRNG_ENTROPY_CONFIG_0 (32'h118) +`define SOC_IFC_REG_CPTRA_ITRNG_ENTROPY_CONFIG_0_LOW_THRESHOLD_LOW (0) +`define SOC_IFC_REG_CPTRA_ITRNG_ENTROPY_CONFIG_0_LOW_THRESHOLD_MASK (32'hffff) +`define SOC_IFC_REG_CPTRA_ITRNG_ENTROPY_CONFIG_0_HIGH_THRESHOLD_LOW (16) +`define SOC_IFC_REG_CPTRA_ITRNG_ENTROPY_CONFIG_0_HIGH_THRESHOLD_MASK (32'hffff0000) +`endif +`ifndef SOC_IFC_REG_CPTRA_ITRNG_ENTROPY_CONFIG_1 +`define SOC_IFC_REG_CPTRA_ITRNG_ENTROPY_CONFIG_1 (32'h11c) +`define SOC_IFC_REG_CPTRA_ITRNG_ENTROPY_CONFIG_1_REPETITION_COUNT_LOW (0) +`define SOC_IFC_REG_CPTRA_ITRNG_ENTROPY_CONFIG_1_REPETITION_COUNT_MASK (32'hffff) +`define SOC_IFC_REG_CPTRA_ITRNG_ENTROPY_CONFIG_1_RSVD_LOW (16) +`define SOC_IFC_REG_CPTRA_ITRNG_ENTROPY_CONFIG_1_RSVD_MASK (32'hffff0000) +`endif +`ifndef SOC_IFC_REG_CPTRA_RSVD_REG_0 +`define SOC_IFC_REG_CPTRA_RSVD_REG_0 (32'h120) +`endif +`ifndef SOC_IFC_REG_CPTRA_RSVD_REG_1 +`define SOC_IFC_REG_CPTRA_RSVD_REG_1 (32'h124) +`endif +`ifndef SOC_IFC_REG_CPTRA_HW_CAPABILITIES +`define SOC_IFC_REG_CPTRA_HW_CAPABILITIES (32'h128) +`endif +`ifndef SOC_IFC_REG_CPTRA_FW_CAPABILITIES +`define SOC_IFC_REG_CPTRA_FW_CAPABILITIES (32'h12c) +`endif +`ifndef SOC_IFC_REG_CPTRA_CAP_LOCK +`define SOC_IFC_REG_CPTRA_CAP_LOCK (32'h130) +`define SOC_IFC_REG_CPTRA_CAP_LOCK_LOCK_LOW (0) +`define SOC_IFC_REG_CPTRA_CAP_LOCK_LOCK_MASK (32'h1) +`endif +`ifndef SOC_IFC_REG_CPTRA_OWNER_PK_HASH_0 +`define SOC_IFC_REG_CPTRA_OWNER_PK_HASH_0 (32'h140) +`endif +`ifndef SOC_IFC_REG_CPTRA_OWNER_PK_HASH_1 +`define SOC_IFC_REG_CPTRA_OWNER_PK_HASH_1 (32'h144) +`endif +`ifndef SOC_IFC_REG_CPTRA_OWNER_PK_HASH_2 +`define SOC_IFC_REG_CPTRA_OWNER_PK_HASH_2 (32'h148) +`endif +`ifndef SOC_IFC_REG_CPTRA_OWNER_PK_HASH_3 +`define SOC_IFC_REG_CPTRA_OWNER_PK_HASH_3 (32'h14c) +`endif +`ifndef SOC_IFC_REG_CPTRA_OWNER_PK_HASH_4 +`define SOC_IFC_REG_CPTRA_OWNER_PK_HASH_4 (32'h150) +`endif +`ifndef SOC_IFC_REG_CPTRA_OWNER_PK_HASH_5 +`define SOC_IFC_REG_CPTRA_OWNER_PK_HASH_5 (32'h154) +`endif +`ifndef SOC_IFC_REG_CPTRA_OWNER_PK_HASH_6 +`define SOC_IFC_REG_CPTRA_OWNER_PK_HASH_6 (32'h158) +`endif +`ifndef SOC_IFC_REG_CPTRA_OWNER_PK_HASH_7 +`define SOC_IFC_REG_CPTRA_OWNER_PK_HASH_7 (32'h15c) +`endif +`ifndef SOC_IFC_REG_CPTRA_OWNER_PK_HASH_8 +`define SOC_IFC_REG_CPTRA_OWNER_PK_HASH_8 (32'h160) +`endif +`ifndef SOC_IFC_REG_CPTRA_OWNER_PK_HASH_9 +`define SOC_IFC_REG_CPTRA_OWNER_PK_HASH_9 (32'h164) +`endif +`ifndef SOC_IFC_REG_CPTRA_OWNER_PK_HASH_10 +`define SOC_IFC_REG_CPTRA_OWNER_PK_HASH_10 (32'h168) +`endif +`ifndef SOC_IFC_REG_CPTRA_OWNER_PK_HASH_11 +`define SOC_IFC_REG_CPTRA_OWNER_PK_HASH_11 (32'h16c) +`endif +`ifndef SOC_IFC_REG_CPTRA_OWNER_PK_HASH_LOCK +`define SOC_IFC_REG_CPTRA_OWNER_PK_HASH_LOCK (32'h170) +`define SOC_IFC_REG_CPTRA_OWNER_PK_HASH_LOCK_LOCK_LOW (0) +`define SOC_IFC_REG_CPTRA_OWNER_PK_HASH_LOCK_LOCK_MASK (32'h1) +`endif +`ifndef SOC_IFC_REG_FUSE_UDS_SEED_0 +`define SOC_IFC_REG_FUSE_UDS_SEED_0 (32'h200) +`endif +`ifndef SOC_IFC_REG_FUSE_UDS_SEED_1 +`define SOC_IFC_REG_FUSE_UDS_SEED_1 (32'h204) +`endif +`ifndef SOC_IFC_REG_FUSE_UDS_SEED_2 +`define SOC_IFC_REG_FUSE_UDS_SEED_2 (32'h208) +`endif +`ifndef SOC_IFC_REG_FUSE_UDS_SEED_3 +`define SOC_IFC_REG_FUSE_UDS_SEED_3 (32'h20c) +`endif +`ifndef SOC_IFC_REG_FUSE_UDS_SEED_4 +`define SOC_IFC_REG_FUSE_UDS_SEED_4 (32'h210) +`endif +`ifndef SOC_IFC_REG_FUSE_UDS_SEED_5 +`define SOC_IFC_REG_FUSE_UDS_SEED_5 (32'h214) +`endif +`ifndef SOC_IFC_REG_FUSE_UDS_SEED_6 +`define SOC_IFC_REG_FUSE_UDS_SEED_6 (32'h218) +`endif +`ifndef SOC_IFC_REG_FUSE_UDS_SEED_7 +`define SOC_IFC_REG_FUSE_UDS_SEED_7 (32'h21c) +`endif +`ifndef SOC_IFC_REG_FUSE_UDS_SEED_8 +`define SOC_IFC_REG_FUSE_UDS_SEED_8 (32'h220) +`endif +`ifndef SOC_IFC_REG_FUSE_UDS_SEED_9 +`define SOC_IFC_REG_FUSE_UDS_SEED_9 (32'h224) +`endif +`ifndef SOC_IFC_REG_FUSE_UDS_SEED_10 +`define SOC_IFC_REG_FUSE_UDS_SEED_10 (32'h228) +`endif +`ifndef SOC_IFC_REG_FUSE_UDS_SEED_11 +`define SOC_IFC_REG_FUSE_UDS_SEED_11 (32'h22c) +`endif +`ifndef SOC_IFC_REG_FUSE_UDS_SEED_12 +`define SOC_IFC_REG_FUSE_UDS_SEED_12 (32'h230) +`endif +`ifndef SOC_IFC_REG_FUSE_UDS_SEED_13 +`define SOC_IFC_REG_FUSE_UDS_SEED_13 (32'h234) +`endif +`ifndef SOC_IFC_REG_FUSE_UDS_SEED_14 +`define SOC_IFC_REG_FUSE_UDS_SEED_14 (32'h238) +`endif +`ifndef SOC_IFC_REG_FUSE_UDS_SEED_15 +`define SOC_IFC_REG_FUSE_UDS_SEED_15 (32'h23c) +`endif +`ifndef SOC_IFC_REG_FUSE_FIELD_ENTROPY_0 +`define SOC_IFC_REG_FUSE_FIELD_ENTROPY_0 (32'h240) +`endif +`ifndef SOC_IFC_REG_FUSE_FIELD_ENTROPY_1 +`define SOC_IFC_REG_FUSE_FIELD_ENTROPY_1 (32'h244) +`endif +`ifndef SOC_IFC_REG_FUSE_FIELD_ENTROPY_2 +`define SOC_IFC_REG_FUSE_FIELD_ENTROPY_2 (32'h248) +`endif +`ifndef SOC_IFC_REG_FUSE_FIELD_ENTROPY_3 +`define SOC_IFC_REG_FUSE_FIELD_ENTROPY_3 (32'h24c) +`endif +`ifndef SOC_IFC_REG_FUSE_FIELD_ENTROPY_4 +`define SOC_IFC_REG_FUSE_FIELD_ENTROPY_4 (32'h250) +`endif +`ifndef SOC_IFC_REG_FUSE_FIELD_ENTROPY_5 +`define SOC_IFC_REG_FUSE_FIELD_ENTROPY_5 (32'h254) +`endif +`ifndef SOC_IFC_REG_FUSE_FIELD_ENTROPY_6 +`define SOC_IFC_REG_FUSE_FIELD_ENTROPY_6 (32'h258) +`endif +`ifndef SOC_IFC_REG_FUSE_FIELD_ENTROPY_7 +`define SOC_IFC_REG_FUSE_FIELD_ENTROPY_7 (32'h25c) +`endif +`ifndef SOC_IFC_REG_FUSE_VENDOR_PK_HASH_0 +`define SOC_IFC_REG_FUSE_VENDOR_PK_HASH_0 (32'h260) +`endif +`ifndef SOC_IFC_REG_FUSE_VENDOR_PK_HASH_1 +`define SOC_IFC_REG_FUSE_VENDOR_PK_HASH_1 (32'h264) +`endif +`ifndef SOC_IFC_REG_FUSE_VENDOR_PK_HASH_2 +`define SOC_IFC_REG_FUSE_VENDOR_PK_HASH_2 (32'h268) +`endif +`ifndef SOC_IFC_REG_FUSE_VENDOR_PK_HASH_3 +`define SOC_IFC_REG_FUSE_VENDOR_PK_HASH_3 (32'h26c) +`endif +`ifndef SOC_IFC_REG_FUSE_VENDOR_PK_HASH_4 +`define SOC_IFC_REG_FUSE_VENDOR_PK_HASH_4 (32'h270) +`endif +`ifndef SOC_IFC_REG_FUSE_VENDOR_PK_HASH_5 +`define SOC_IFC_REG_FUSE_VENDOR_PK_HASH_5 (32'h274) +`endif +`ifndef SOC_IFC_REG_FUSE_VENDOR_PK_HASH_6 +`define SOC_IFC_REG_FUSE_VENDOR_PK_HASH_6 (32'h278) +`endif +`ifndef SOC_IFC_REG_FUSE_VENDOR_PK_HASH_7 +`define SOC_IFC_REG_FUSE_VENDOR_PK_HASH_7 (32'h27c) +`endif +`ifndef SOC_IFC_REG_FUSE_VENDOR_PK_HASH_8 +`define SOC_IFC_REG_FUSE_VENDOR_PK_HASH_8 (32'h280) +`endif +`ifndef SOC_IFC_REG_FUSE_VENDOR_PK_HASH_9 +`define SOC_IFC_REG_FUSE_VENDOR_PK_HASH_9 (32'h284) +`endif +`ifndef SOC_IFC_REG_FUSE_VENDOR_PK_HASH_10 +`define SOC_IFC_REG_FUSE_VENDOR_PK_HASH_10 (32'h288) +`endif +`ifndef SOC_IFC_REG_FUSE_VENDOR_PK_HASH_11 +`define SOC_IFC_REG_FUSE_VENDOR_PK_HASH_11 (32'h28c) +`endif +`ifndef SOC_IFC_REG_FUSE_ECC_REVOCATION +`define SOC_IFC_REG_FUSE_ECC_REVOCATION (32'h290) +`define SOC_IFC_REG_FUSE_ECC_REVOCATION_ECC_REVOCATION_LOW (0) +`define SOC_IFC_REG_FUSE_ECC_REVOCATION_ECC_REVOCATION_MASK (32'hf) +`endif +`ifndef SOC_IFC_REG_FUSE_FMC_KEY_MANIFEST_SVN +`define SOC_IFC_REG_FUSE_FMC_KEY_MANIFEST_SVN (32'h2b4) +`endif +`ifndef SOC_IFC_REG_FUSE_RUNTIME_SVN_0 +`define SOC_IFC_REG_FUSE_RUNTIME_SVN_0 (32'h2b8) +`endif +`ifndef SOC_IFC_REG_FUSE_RUNTIME_SVN_1 +`define SOC_IFC_REG_FUSE_RUNTIME_SVN_1 (32'h2bc) +`endif +`ifndef SOC_IFC_REG_FUSE_RUNTIME_SVN_2 +`define SOC_IFC_REG_FUSE_RUNTIME_SVN_2 (32'h2c0) +`endif +`ifndef SOC_IFC_REG_FUSE_RUNTIME_SVN_3 +`define SOC_IFC_REG_FUSE_RUNTIME_SVN_3 (32'h2c4) +`endif +`ifndef SOC_IFC_REG_FUSE_ANTI_ROLLBACK_DISABLE +`define SOC_IFC_REG_FUSE_ANTI_ROLLBACK_DISABLE (32'h2c8) +`define SOC_IFC_REG_FUSE_ANTI_ROLLBACK_DISABLE_DIS_LOW (0) +`define SOC_IFC_REG_FUSE_ANTI_ROLLBACK_DISABLE_DIS_MASK (32'h1) +`endif +`ifndef SOC_IFC_REG_FUSE_IDEVID_CERT_ATTR_0 +`define SOC_IFC_REG_FUSE_IDEVID_CERT_ATTR_0 (32'h2cc) +`endif +`ifndef SOC_IFC_REG_FUSE_IDEVID_CERT_ATTR_1 +`define SOC_IFC_REG_FUSE_IDEVID_CERT_ATTR_1 (32'h2d0) +`endif +`ifndef SOC_IFC_REG_FUSE_IDEVID_CERT_ATTR_2 +`define SOC_IFC_REG_FUSE_IDEVID_CERT_ATTR_2 (32'h2d4) +`endif +`ifndef SOC_IFC_REG_FUSE_IDEVID_CERT_ATTR_3 +`define SOC_IFC_REG_FUSE_IDEVID_CERT_ATTR_3 (32'h2d8) +`endif +`ifndef SOC_IFC_REG_FUSE_IDEVID_CERT_ATTR_4 +`define SOC_IFC_REG_FUSE_IDEVID_CERT_ATTR_4 (32'h2dc) +`endif +`ifndef SOC_IFC_REG_FUSE_IDEVID_CERT_ATTR_5 +`define SOC_IFC_REG_FUSE_IDEVID_CERT_ATTR_5 (32'h2e0) +`endif +`ifndef SOC_IFC_REG_FUSE_IDEVID_CERT_ATTR_6 +`define SOC_IFC_REG_FUSE_IDEVID_CERT_ATTR_6 (32'h2e4) +`endif +`ifndef SOC_IFC_REG_FUSE_IDEVID_CERT_ATTR_7 +`define SOC_IFC_REG_FUSE_IDEVID_CERT_ATTR_7 (32'h2e8) +`endif +`ifndef SOC_IFC_REG_FUSE_IDEVID_CERT_ATTR_8 +`define SOC_IFC_REG_FUSE_IDEVID_CERT_ATTR_8 (32'h2ec) +`endif +`ifndef SOC_IFC_REG_FUSE_IDEVID_CERT_ATTR_9 +`define SOC_IFC_REG_FUSE_IDEVID_CERT_ATTR_9 (32'h2f0) +`endif +`ifndef SOC_IFC_REG_FUSE_IDEVID_CERT_ATTR_10 +`define SOC_IFC_REG_FUSE_IDEVID_CERT_ATTR_10 (32'h2f4) +`endif +`ifndef SOC_IFC_REG_FUSE_IDEVID_CERT_ATTR_11 +`define SOC_IFC_REG_FUSE_IDEVID_CERT_ATTR_11 (32'h2f8) +`endif +`ifndef SOC_IFC_REG_FUSE_IDEVID_CERT_ATTR_12 +`define SOC_IFC_REG_FUSE_IDEVID_CERT_ATTR_12 (32'h2fc) +`endif +`ifndef SOC_IFC_REG_FUSE_IDEVID_CERT_ATTR_13 +`define SOC_IFC_REG_FUSE_IDEVID_CERT_ATTR_13 (32'h300) +`endif +`ifndef SOC_IFC_REG_FUSE_IDEVID_CERT_ATTR_14 +`define SOC_IFC_REG_FUSE_IDEVID_CERT_ATTR_14 (32'h304) +`endif +`ifndef SOC_IFC_REG_FUSE_IDEVID_CERT_ATTR_15 +`define SOC_IFC_REG_FUSE_IDEVID_CERT_ATTR_15 (32'h308) +`endif +`ifndef SOC_IFC_REG_FUSE_IDEVID_CERT_ATTR_16 +`define SOC_IFC_REG_FUSE_IDEVID_CERT_ATTR_16 (32'h30c) +`endif +`ifndef SOC_IFC_REG_FUSE_IDEVID_CERT_ATTR_17 +`define SOC_IFC_REG_FUSE_IDEVID_CERT_ATTR_17 (32'h310) +`endif +`ifndef SOC_IFC_REG_FUSE_IDEVID_CERT_ATTR_18 +`define SOC_IFC_REG_FUSE_IDEVID_CERT_ATTR_18 (32'h314) +`endif +`ifndef SOC_IFC_REG_FUSE_IDEVID_CERT_ATTR_19 +`define SOC_IFC_REG_FUSE_IDEVID_CERT_ATTR_19 (32'h318) +`endif +`ifndef SOC_IFC_REG_FUSE_IDEVID_CERT_ATTR_20 +`define SOC_IFC_REG_FUSE_IDEVID_CERT_ATTR_20 (32'h31c) +`endif +`ifndef SOC_IFC_REG_FUSE_IDEVID_CERT_ATTR_21 +`define SOC_IFC_REG_FUSE_IDEVID_CERT_ATTR_21 (32'h320) +`endif +`ifndef SOC_IFC_REG_FUSE_IDEVID_CERT_ATTR_22 +`define SOC_IFC_REG_FUSE_IDEVID_CERT_ATTR_22 (32'h324) +`endif +`ifndef SOC_IFC_REG_FUSE_IDEVID_CERT_ATTR_23 +`define SOC_IFC_REG_FUSE_IDEVID_CERT_ATTR_23 (32'h328) +`endif +`ifndef SOC_IFC_REG_FUSE_IDEVID_MANUF_HSM_ID_0 +`define SOC_IFC_REG_FUSE_IDEVID_MANUF_HSM_ID_0 (32'h32c) +`endif +`ifndef SOC_IFC_REG_FUSE_IDEVID_MANUF_HSM_ID_1 +`define SOC_IFC_REG_FUSE_IDEVID_MANUF_HSM_ID_1 (32'h330) +`endif +`ifndef SOC_IFC_REG_FUSE_IDEVID_MANUF_HSM_ID_2 +`define SOC_IFC_REG_FUSE_IDEVID_MANUF_HSM_ID_2 (32'h334) +`endif +`ifndef SOC_IFC_REG_FUSE_IDEVID_MANUF_HSM_ID_3 +`define SOC_IFC_REG_FUSE_IDEVID_MANUF_HSM_ID_3 (32'h338) +`endif +`ifndef SOC_IFC_REG_FUSE_LMS_REVOCATION +`define SOC_IFC_REG_FUSE_LMS_REVOCATION (32'h340) +`endif +`ifndef SOC_IFC_REG_FUSE_MLDSA_REVOCATION +`define SOC_IFC_REG_FUSE_MLDSA_REVOCATION (32'h344) +`define SOC_IFC_REG_FUSE_MLDSA_REVOCATION_MLDSA_REVOCATION_LOW (0) +`define SOC_IFC_REG_FUSE_MLDSA_REVOCATION_MLDSA_REVOCATION_MASK (32'hf) +`endif +`ifndef SOC_IFC_REG_FUSE_SOC_STEPPING_ID +`define SOC_IFC_REG_FUSE_SOC_STEPPING_ID (32'h348) +`define SOC_IFC_REG_FUSE_SOC_STEPPING_ID_SOC_STEPPING_ID_LOW (0) +`define SOC_IFC_REG_FUSE_SOC_STEPPING_ID_SOC_STEPPING_ID_MASK (32'hffff) +`endif +`ifndef SOC_IFC_REG_FUSE_MANUF_DBG_UNLOCK_TOKEN_0 +`define SOC_IFC_REG_FUSE_MANUF_DBG_UNLOCK_TOKEN_0 (32'h34c) +`endif +`ifndef SOC_IFC_REG_FUSE_MANUF_DBG_UNLOCK_TOKEN_1 +`define SOC_IFC_REG_FUSE_MANUF_DBG_UNLOCK_TOKEN_1 (32'h350) +`endif +`ifndef SOC_IFC_REG_FUSE_MANUF_DBG_UNLOCK_TOKEN_2 +`define SOC_IFC_REG_FUSE_MANUF_DBG_UNLOCK_TOKEN_2 (32'h354) +`endif +`ifndef SOC_IFC_REG_FUSE_MANUF_DBG_UNLOCK_TOKEN_3 +`define SOC_IFC_REG_FUSE_MANUF_DBG_UNLOCK_TOKEN_3 (32'h358) +`endif +`ifndef SOC_IFC_REG_FUSE_MANUF_DBG_UNLOCK_TOKEN_4 +`define SOC_IFC_REG_FUSE_MANUF_DBG_UNLOCK_TOKEN_4 (32'h35c) +`endif +`ifndef SOC_IFC_REG_FUSE_MANUF_DBG_UNLOCK_TOKEN_5 +`define SOC_IFC_REG_FUSE_MANUF_DBG_UNLOCK_TOKEN_5 (32'h360) +`endif +`ifndef SOC_IFC_REG_FUSE_MANUF_DBG_UNLOCK_TOKEN_6 +`define SOC_IFC_REG_FUSE_MANUF_DBG_UNLOCK_TOKEN_6 (32'h364) +`endif +`ifndef SOC_IFC_REG_FUSE_MANUF_DBG_UNLOCK_TOKEN_7 +`define SOC_IFC_REG_FUSE_MANUF_DBG_UNLOCK_TOKEN_7 (32'h368) +`endif +`ifndef SOC_IFC_REG_FUSE_MANUF_DBG_UNLOCK_TOKEN_8 +`define SOC_IFC_REG_FUSE_MANUF_DBG_UNLOCK_TOKEN_8 (32'h36c) +`endif +`ifndef SOC_IFC_REG_FUSE_MANUF_DBG_UNLOCK_TOKEN_9 +`define SOC_IFC_REG_FUSE_MANUF_DBG_UNLOCK_TOKEN_9 (32'h370) +`endif +`ifndef SOC_IFC_REG_FUSE_MANUF_DBG_UNLOCK_TOKEN_10 +`define SOC_IFC_REG_FUSE_MANUF_DBG_UNLOCK_TOKEN_10 (32'h374) +`endif +`ifndef SOC_IFC_REG_FUSE_MANUF_DBG_UNLOCK_TOKEN_11 +`define SOC_IFC_REG_FUSE_MANUF_DBG_UNLOCK_TOKEN_11 (32'h378) +`endif +`ifndef SOC_IFC_REG_FUSE_MANUF_DBG_UNLOCK_TOKEN_12 +`define SOC_IFC_REG_FUSE_MANUF_DBG_UNLOCK_TOKEN_12 (32'h37c) +`endif +`ifndef SOC_IFC_REG_FUSE_MANUF_DBG_UNLOCK_TOKEN_13 +`define SOC_IFC_REG_FUSE_MANUF_DBG_UNLOCK_TOKEN_13 (32'h380) +`endif +`ifndef SOC_IFC_REG_FUSE_MANUF_DBG_UNLOCK_TOKEN_14 +`define SOC_IFC_REG_FUSE_MANUF_DBG_UNLOCK_TOKEN_14 (32'h384) +`endif +`ifndef SOC_IFC_REG_FUSE_MANUF_DBG_UNLOCK_TOKEN_15 +`define SOC_IFC_REG_FUSE_MANUF_DBG_UNLOCK_TOKEN_15 (32'h388) +`endif +`ifndef SOC_IFC_REG_FUSE_PQC_KEY_TYPE +`define SOC_IFC_REG_FUSE_PQC_KEY_TYPE (32'h38c) +`define SOC_IFC_REG_FUSE_PQC_KEY_TYPE_KEY_TYPE_LOW (0) +`define SOC_IFC_REG_FUSE_PQC_KEY_TYPE_KEY_TYPE_MASK (32'h3) +`endif +`ifndef SOC_IFC_REG_FUSE_SOC_MANIFEST_SVN_0 +`define SOC_IFC_REG_FUSE_SOC_MANIFEST_SVN_0 (32'h390) +`endif +`ifndef SOC_IFC_REG_FUSE_SOC_MANIFEST_SVN_1 +`define SOC_IFC_REG_FUSE_SOC_MANIFEST_SVN_1 (32'h394) +`endif +`ifndef SOC_IFC_REG_FUSE_SOC_MANIFEST_SVN_2 +`define SOC_IFC_REG_FUSE_SOC_MANIFEST_SVN_2 (32'h398) +`endif +`ifndef SOC_IFC_REG_FUSE_SOC_MANIFEST_SVN_3 +`define SOC_IFC_REG_FUSE_SOC_MANIFEST_SVN_3 (32'h39c) +`endif +`ifndef SOC_IFC_REG_FUSE_SOC_MANIFEST_MAX_SVN +`define SOC_IFC_REG_FUSE_SOC_MANIFEST_MAX_SVN (32'h3a0) +`define SOC_IFC_REG_FUSE_SOC_MANIFEST_MAX_SVN_SVN_LOW (0) +`define SOC_IFC_REG_FUSE_SOC_MANIFEST_MAX_SVN_SVN_MASK (32'hff) +`endif +`ifndef SOC_IFC_REG_FUSE_HEK_SEED_0 +`define SOC_IFC_REG_FUSE_HEK_SEED_0 (32'h3c0) +`endif +`ifndef SOC_IFC_REG_FUSE_HEK_SEED_1 +`define SOC_IFC_REG_FUSE_HEK_SEED_1 (32'h3c4) +`endif +`ifndef SOC_IFC_REG_FUSE_HEK_SEED_2 +`define SOC_IFC_REG_FUSE_HEK_SEED_2 (32'h3c8) +`endif +`ifndef SOC_IFC_REG_FUSE_HEK_SEED_3 +`define SOC_IFC_REG_FUSE_HEK_SEED_3 (32'h3cc) +`endif +`ifndef SOC_IFC_REG_FUSE_HEK_SEED_4 +`define SOC_IFC_REG_FUSE_HEK_SEED_4 (32'h3d0) +`endif +`ifndef SOC_IFC_REG_FUSE_HEK_SEED_5 +`define SOC_IFC_REG_FUSE_HEK_SEED_5 (32'h3d4) +`endif +`ifndef SOC_IFC_REG_FUSE_HEK_SEED_6 +`define SOC_IFC_REG_FUSE_HEK_SEED_6 (32'h3d8) +`endif +`ifndef SOC_IFC_REG_FUSE_HEK_SEED_7 +`define SOC_IFC_REG_FUSE_HEK_SEED_7 (32'h3dc) +`endif +`ifndef SOC_IFC_REG_SS_CALIPTRA_BASE_ADDR_L +`define SOC_IFC_REG_SS_CALIPTRA_BASE_ADDR_L (32'h500) +`endif +`ifndef SOC_IFC_REG_SS_CALIPTRA_BASE_ADDR_H +`define SOC_IFC_REG_SS_CALIPTRA_BASE_ADDR_H (32'h504) +`endif +`ifndef SOC_IFC_REG_SS_MCI_BASE_ADDR_L +`define SOC_IFC_REG_SS_MCI_BASE_ADDR_L (32'h508) +`endif +`ifndef SOC_IFC_REG_SS_MCI_BASE_ADDR_H +`define SOC_IFC_REG_SS_MCI_BASE_ADDR_H (32'h50c) +`endif +`ifndef SOC_IFC_REG_SS_RECOVERY_IFC_BASE_ADDR_L +`define SOC_IFC_REG_SS_RECOVERY_IFC_BASE_ADDR_L (32'h510) +`endif +`ifndef SOC_IFC_REG_SS_RECOVERY_IFC_BASE_ADDR_H +`define SOC_IFC_REG_SS_RECOVERY_IFC_BASE_ADDR_H (32'h514) +`endif +`ifndef SOC_IFC_REG_SS_OTP_FC_BASE_ADDR_L +`define SOC_IFC_REG_SS_OTP_FC_BASE_ADDR_L (32'h518) +`endif +`ifndef SOC_IFC_REG_SS_OTP_FC_BASE_ADDR_H +`define SOC_IFC_REG_SS_OTP_FC_BASE_ADDR_H (32'h51c) +`endif +`ifndef SOC_IFC_REG_SS_UDS_SEED_BASE_ADDR_L +`define SOC_IFC_REG_SS_UDS_SEED_BASE_ADDR_L (32'h520) +`endif +`ifndef SOC_IFC_REG_SS_UDS_SEED_BASE_ADDR_H +`define SOC_IFC_REG_SS_UDS_SEED_BASE_ADDR_H (32'h524) +`endif +`ifndef SOC_IFC_REG_SS_PROD_DEBUG_UNLOCK_AUTH_PK_HASH_REG_BANK_OFFSET +`define SOC_IFC_REG_SS_PROD_DEBUG_UNLOCK_AUTH_PK_HASH_REG_BANK_OFFSET (32'h528) +`endif +`ifndef SOC_IFC_REG_SS_NUM_OF_PROD_DEBUG_UNLOCK_AUTH_PK_HASHES +`define SOC_IFC_REG_SS_NUM_OF_PROD_DEBUG_UNLOCK_AUTH_PK_HASHES (32'h52c) +`endif +`ifndef SOC_IFC_REG_SS_DEBUG_INTENT +`define SOC_IFC_REG_SS_DEBUG_INTENT (32'h530) +`define SOC_IFC_REG_SS_DEBUG_INTENT_DEBUG_INTENT_LOW (0) +`define SOC_IFC_REG_SS_DEBUG_INTENT_DEBUG_INTENT_MASK (32'h1) +`endif +`ifndef SOC_IFC_REG_SS_CALIPTRA_DMA_AXI_USER +`define SOC_IFC_REG_SS_CALIPTRA_DMA_AXI_USER (32'h534) +`endif +`ifndef SOC_IFC_REG_SS_EXTERNAL_STAGING_AREA_BASE_ADDR_L +`define SOC_IFC_REG_SS_EXTERNAL_STAGING_AREA_BASE_ADDR_L (32'h538) +`endif +`ifndef SOC_IFC_REG_SS_EXTERNAL_STAGING_AREA_BASE_ADDR_H +`define SOC_IFC_REG_SS_EXTERNAL_STAGING_AREA_BASE_ADDR_H (32'h53c) +`endif +`ifndef SOC_IFC_REG_SS_KEY_RELEASE_BASE_ADDR_L +`define SOC_IFC_REG_SS_KEY_RELEASE_BASE_ADDR_L (32'h540) +`endif +`ifndef SOC_IFC_REG_SS_KEY_RELEASE_BASE_ADDR_H +`define SOC_IFC_REG_SS_KEY_RELEASE_BASE_ADDR_H (32'h544) +`endif +`ifndef SOC_IFC_REG_SS_KEY_RELEASE_SIZE +`define SOC_IFC_REG_SS_KEY_RELEASE_SIZE (32'h548) +`define SOC_IFC_REG_SS_KEY_RELEASE_SIZE_SIZE_LOW (0) +`define SOC_IFC_REG_SS_KEY_RELEASE_SIZE_SIZE_MASK (32'hffff) +`endif +`ifndef SOC_IFC_REG_SS_OCP_LOCK_CTRL +`define SOC_IFC_REG_SS_OCP_LOCK_CTRL (32'h54c) +`define SOC_IFC_REG_SS_OCP_LOCK_CTRL_LOCK_IN_PROGRESS_LOW (0) +`define SOC_IFC_REG_SS_OCP_LOCK_CTRL_LOCK_IN_PROGRESS_MASK (32'h1) +`endif +`ifndef SOC_IFC_REG_SS_STRAP_GENERIC_0 +`define SOC_IFC_REG_SS_STRAP_GENERIC_0 (32'h5a0) +`endif +`ifndef SOC_IFC_REG_SS_STRAP_GENERIC_1 +`define SOC_IFC_REG_SS_STRAP_GENERIC_1 (32'h5a4) +`endif +`ifndef SOC_IFC_REG_SS_STRAP_GENERIC_2 +`define SOC_IFC_REG_SS_STRAP_GENERIC_2 (32'h5a8) +`endif +`ifndef SOC_IFC_REG_SS_STRAP_GENERIC_3 +`define SOC_IFC_REG_SS_STRAP_GENERIC_3 (32'h5ac) +`endif +`ifndef SOC_IFC_REG_SS_DBG_SERVICE_REG_REQ +`define SOC_IFC_REG_SS_DBG_SERVICE_REG_REQ (32'h5c0) +`define SOC_IFC_REG_SS_DBG_SERVICE_REG_REQ_MANUF_DBG_UNLOCK_REQ_LOW (0) +`define SOC_IFC_REG_SS_DBG_SERVICE_REG_REQ_MANUF_DBG_UNLOCK_REQ_MASK (32'h1) +`define SOC_IFC_REG_SS_DBG_SERVICE_REG_REQ_PROD_DBG_UNLOCK_REQ_LOW (1) +`define SOC_IFC_REG_SS_DBG_SERVICE_REG_REQ_PROD_DBG_UNLOCK_REQ_MASK (32'h2) +`define SOC_IFC_REG_SS_DBG_SERVICE_REG_REQ_UDS_PROGRAM_REQ_LOW (2) +`define SOC_IFC_REG_SS_DBG_SERVICE_REG_REQ_UDS_PROGRAM_REQ_MASK (32'h4) +`define SOC_IFC_REG_SS_DBG_SERVICE_REG_REQ_RSVD_LOW (3) +`define SOC_IFC_REG_SS_DBG_SERVICE_REG_REQ_RSVD_MASK (32'hfffffff8) +`endif +`ifndef SOC_IFC_REG_SS_DBG_SERVICE_REG_RSP +`define SOC_IFC_REG_SS_DBG_SERVICE_REG_RSP (32'h5c4) +`define SOC_IFC_REG_SS_DBG_SERVICE_REG_RSP_MANUF_DBG_UNLOCK_SUCCESS_LOW (0) +`define SOC_IFC_REG_SS_DBG_SERVICE_REG_RSP_MANUF_DBG_UNLOCK_SUCCESS_MASK (32'h1) +`define SOC_IFC_REG_SS_DBG_SERVICE_REG_RSP_MANUF_DBG_UNLOCK_FAIL_LOW (1) +`define SOC_IFC_REG_SS_DBG_SERVICE_REG_RSP_MANUF_DBG_UNLOCK_FAIL_MASK (32'h2) +`define SOC_IFC_REG_SS_DBG_SERVICE_REG_RSP_MANUF_DBG_UNLOCK_IN_PROGRESS_LOW (2) +`define SOC_IFC_REG_SS_DBG_SERVICE_REG_RSP_MANUF_DBG_UNLOCK_IN_PROGRESS_MASK (32'h4) +`define SOC_IFC_REG_SS_DBG_SERVICE_REG_RSP_PROD_DBG_UNLOCK_SUCCESS_LOW (3) +`define SOC_IFC_REG_SS_DBG_SERVICE_REG_RSP_PROD_DBG_UNLOCK_SUCCESS_MASK (32'h8) +`define SOC_IFC_REG_SS_DBG_SERVICE_REG_RSP_PROD_DBG_UNLOCK_FAIL_LOW (4) +`define SOC_IFC_REG_SS_DBG_SERVICE_REG_RSP_PROD_DBG_UNLOCK_FAIL_MASK (32'h10) +`define SOC_IFC_REG_SS_DBG_SERVICE_REG_RSP_PROD_DBG_UNLOCK_IN_PROGRESS_LOW (5) +`define SOC_IFC_REG_SS_DBG_SERVICE_REG_RSP_PROD_DBG_UNLOCK_IN_PROGRESS_MASK (32'h20) +`define SOC_IFC_REG_SS_DBG_SERVICE_REG_RSP_UDS_PROGRAM_SUCCESS_LOW (6) +`define SOC_IFC_REG_SS_DBG_SERVICE_REG_RSP_UDS_PROGRAM_SUCCESS_MASK (32'h40) +`define SOC_IFC_REG_SS_DBG_SERVICE_REG_RSP_UDS_PROGRAM_FAIL_LOW (7) +`define SOC_IFC_REG_SS_DBG_SERVICE_REG_RSP_UDS_PROGRAM_FAIL_MASK (32'h80) +`define SOC_IFC_REG_SS_DBG_SERVICE_REG_RSP_UDS_PROGRAM_IN_PROGRESS_LOW (8) +`define SOC_IFC_REG_SS_DBG_SERVICE_REG_RSP_UDS_PROGRAM_IN_PROGRESS_MASK (32'h100) +`define SOC_IFC_REG_SS_DBG_SERVICE_REG_RSP_TAP_MAILBOX_AVAILABLE_LOW (9) +`define SOC_IFC_REG_SS_DBG_SERVICE_REG_RSP_TAP_MAILBOX_AVAILABLE_MASK (32'h200) +`define SOC_IFC_REG_SS_DBG_SERVICE_REG_RSP_RSVD_LOW (10) +`define SOC_IFC_REG_SS_DBG_SERVICE_REG_RSP_RSVD_MASK (32'hfffffc00) +`endif +`ifndef SOC_IFC_REG_SS_SOC_DBG_UNLOCK_LEVEL_0 +`define SOC_IFC_REG_SS_SOC_DBG_UNLOCK_LEVEL_0 (32'h5c8) +`endif +`ifndef SOC_IFC_REG_SS_SOC_DBG_UNLOCK_LEVEL_1 +`define SOC_IFC_REG_SS_SOC_DBG_UNLOCK_LEVEL_1 (32'h5cc) +`endif +`ifndef SOC_IFC_REG_SS_GENERIC_FW_EXEC_CTRL_0 +`define SOC_IFC_REG_SS_GENERIC_FW_EXEC_CTRL_0 (32'h5d0) +`endif +`ifndef SOC_IFC_REG_SS_GENERIC_FW_EXEC_CTRL_1 +`define SOC_IFC_REG_SS_GENERIC_FW_EXEC_CTRL_1 (32'h5d4) +`endif +`ifndef SOC_IFC_REG_SS_GENERIC_FW_EXEC_CTRL_2 +`define SOC_IFC_REG_SS_GENERIC_FW_EXEC_CTRL_2 (32'h5d8) +`endif +`ifndef SOC_IFC_REG_SS_GENERIC_FW_EXEC_CTRL_3 +`define SOC_IFC_REG_SS_GENERIC_FW_EXEC_CTRL_3 (32'h5dc) +`endif +`ifndef SOC_IFC_REG_INTERNAL_OBF_KEY_0 +`define SOC_IFC_REG_INTERNAL_OBF_KEY_0 (32'h600) +`endif +`ifndef SOC_IFC_REG_INTERNAL_OBF_KEY_1 +`define SOC_IFC_REG_INTERNAL_OBF_KEY_1 (32'h604) +`endif +`ifndef SOC_IFC_REG_INTERNAL_OBF_KEY_2 +`define SOC_IFC_REG_INTERNAL_OBF_KEY_2 (32'h608) +`endif +`ifndef SOC_IFC_REG_INTERNAL_OBF_KEY_3 +`define SOC_IFC_REG_INTERNAL_OBF_KEY_3 (32'h60c) +`endif +`ifndef SOC_IFC_REG_INTERNAL_OBF_KEY_4 +`define SOC_IFC_REG_INTERNAL_OBF_KEY_4 (32'h610) +`endif +`ifndef SOC_IFC_REG_INTERNAL_OBF_KEY_5 +`define SOC_IFC_REG_INTERNAL_OBF_KEY_5 (32'h614) +`endif +`ifndef SOC_IFC_REG_INTERNAL_OBF_KEY_6 +`define SOC_IFC_REG_INTERNAL_OBF_KEY_6 (32'h618) +`endif +`ifndef SOC_IFC_REG_INTERNAL_OBF_KEY_7 +`define SOC_IFC_REG_INTERNAL_OBF_KEY_7 (32'h61c) +`endif +`ifndef SOC_IFC_REG_INTERNAL_ICCM_LOCK +`define SOC_IFC_REG_INTERNAL_ICCM_LOCK (32'h620) +`define SOC_IFC_REG_INTERNAL_ICCM_LOCK_LOCK_LOW (0) +`define SOC_IFC_REG_INTERNAL_ICCM_LOCK_LOCK_MASK (32'h1) +`endif +`ifndef SOC_IFC_REG_INTERNAL_FW_UPDATE_RESET +`define SOC_IFC_REG_INTERNAL_FW_UPDATE_RESET (32'h624) +`define SOC_IFC_REG_INTERNAL_FW_UPDATE_RESET_CORE_RST_LOW (0) +`define SOC_IFC_REG_INTERNAL_FW_UPDATE_RESET_CORE_RST_MASK (32'h1) +`endif +`ifndef SOC_IFC_REG_INTERNAL_FW_UPDATE_RESET_WAIT_CYCLES +`define SOC_IFC_REG_INTERNAL_FW_UPDATE_RESET_WAIT_CYCLES (32'h628) +`define SOC_IFC_REG_INTERNAL_FW_UPDATE_RESET_WAIT_CYCLES_WAIT_CYCLES_LOW (0) +`define SOC_IFC_REG_INTERNAL_FW_UPDATE_RESET_WAIT_CYCLES_WAIT_CYCLES_MASK (32'hff) +`endif +`ifndef SOC_IFC_REG_INTERNAL_NMI_VECTOR +`define SOC_IFC_REG_INTERNAL_NMI_VECTOR (32'h62c) +`endif +`ifndef SOC_IFC_REG_INTERNAL_HW_ERROR_FATAL_MASK +`define SOC_IFC_REG_INTERNAL_HW_ERROR_FATAL_MASK (32'h630) +`define SOC_IFC_REG_INTERNAL_HW_ERROR_FATAL_MASK_MASK_ICCM_ECC_UNC_LOW (0) +`define SOC_IFC_REG_INTERNAL_HW_ERROR_FATAL_MASK_MASK_ICCM_ECC_UNC_MASK (32'h1) +`define SOC_IFC_REG_INTERNAL_HW_ERROR_FATAL_MASK_MASK_DCCM_ECC_UNC_LOW (1) +`define SOC_IFC_REG_INTERNAL_HW_ERROR_FATAL_MASK_MASK_DCCM_ECC_UNC_MASK (32'h2) +`define SOC_IFC_REG_INTERNAL_HW_ERROR_FATAL_MASK_MASK_NMI_PIN_LOW (2) +`define SOC_IFC_REG_INTERNAL_HW_ERROR_FATAL_MASK_MASK_NMI_PIN_MASK (32'h4) +`define SOC_IFC_REG_INTERNAL_HW_ERROR_FATAL_MASK_MASK_CRYPTO_ERR_LOW (3) +`define SOC_IFC_REG_INTERNAL_HW_ERROR_FATAL_MASK_MASK_CRYPTO_ERR_MASK (32'h8) +`endif +`ifndef SOC_IFC_REG_INTERNAL_HW_ERROR_NON_FATAL_MASK +`define SOC_IFC_REG_INTERNAL_HW_ERROR_NON_FATAL_MASK (32'h634) +`define SOC_IFC_REG_INTERNAL_HW_ERROR_NON_FATAL_MASK_MASK_MBOX_PROT_NO_LOCK_LOW (0) +`define SOC_IFC_REG_INTERNAL_HW_ERROR_NON_FATAL_MASK_MASK_MBOX_PROT_NO_LOCK_MASK (32'h1) +`define SOC_IFC_REG_INTERNAL_HW_ERROR_NON_FATAL_MASK_MASK_MBOX_PROT_OOO_LOW (1) +`define SOC_IFC_REG_INTERNAL_HW_ERROR_NON_FATAL_MASK_MASK_MBOX_PROT_OOO_MASK (32'h2) +`define SOC_IFC_REG_INTERNAL_HW_ERROR_NON_FATAL_MASK_MASK_MBOX_ECC_UNC_LOW (2) +`define SOC_IFC_REG_INTERNAL_HW_ERROR_NON_FATAL_MASK_MASK_MBOX_ECC_UNC_MASK (32'h4) +`endif +`ifndef SOC_IFC_REG_INTERNAL_FW_ERROR_FATAL_MASK +`define SOC_IFC_REG_INTERNAL_FW_ERROR_FATAL_MASK (32'h638) +`endif +`ifndef SOC_IFC_REG_INTERNAL_FW_ERROR_NON_FATAL_MASK +`define SOC_IFC_REG_INTERNAL_FW_ERROR_NON_FATAL_MASK (32'h63c) +`endif +`ifndef SOC_IFC_REG_INTERNAL_RV_MTIME_L +`define SOC_IFC_REG_INTERNAL_RV_MTIME_L (32'h640) +`endif +`ifndef SOC_IFC_REG_INTERNAL_RV_MTIME_H +`define SOC_IFC_REG_INTERNAL_RV_MTIME_H (32'h644) +`endif +`ifndef SOC_IFC_REG_INTERNAL_RV_MTIMECMP_L +`define SOC_IFC_REG_INTERNAL_RV_MTIMECMP_L (32'h648) +`endif +`ifndef SOC_IFC_REG_INTERNAL_RV_MTIMECMP_H +`define SOC_IFC_REG_INTERNAL_RV_MTIMECMP_H (32'h64c) +`endif +`ifndef SOC_IFC_REG_INTR_BLOCK_RF_GLOBAL_INTR_EN_R +`define SOC_IFC_REG_INTR_BLOCK_RF_GLOBAL_INTR_EN_R (32'h800) +`define SOC_IFC_REG_INTR_BLOCK_RF_GLOBAL_INTR_EN_R_ERROR_EN_LOW (0) +`define SOC_IFC_REG_INTR_BLOCK_RF_GLOBAL_INTR_EN_R_ERROR_EN_MASK (32'h1) +`define SOC_IFC_REG_INTR_BLOCK_RF_GLOBAL_INTR_EN_R_NOTIF_EN_LOW (1) +`define SOC_IFC_REG_INTR_BLOCK_RF_GLOBAL_INTR_EN_R_NOTIF_EN_MASK (32'h2) +`endif +`ifndef SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R +`define SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R (32'h804) +`define SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R_ERROR_INTERNAL_EN_LOW (0) +`define SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R_ERROR_INTERNAL_EN_MASK (32'h1) +`define SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R_ERROR_INV_DEV_EN_LOW (1) +`define SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R_ERROR_INV_DEV_EN_MASK (32'h2) +`define SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R_ERROR_CMD_FAIL_EN_LOW (2) +`define SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R_ERROR_CMD_FAIL_EN_MASK (32'h4) +`define SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R_ERROR_BAD_FUSE_EN_LOW (3) +`define SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R_ERROR_BAD_FUSE_EN_MASK (32'h8) +`define SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R_ERROR_ICCM_BLOCKED_EN_LOW (4) +`define SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R_ERROR_ICCM_BLOCKED_EN_MASK (32'h10) +`define SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R_ERROR_MBOX_ECC_UNC_EN_LOW (5) +`define SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R_ERROR_MBOX_ECC_UNC_EN_MASK (32'h20) +`define SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R_ERROR_WDT_TIMER1_TIMEOUT_EN_LOW (6) +`define SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R_ERROR_WDT_TIMER1_TIMEOUT_EN_MASK (32'h40) +`define SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R_ERROR_WDT_TIMER2_TIMEOUT_EN_LOW (7) +`define SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R_ERROR_WDT_TIMER2_TIMEOUT_EN_MASK (32'h80) +`endif +`ifndef SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_INTR_EN_R +`define SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_INTR_EN_R (32'h808) +`define SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_INTR_EN_R_NOTIF_CMD_AVAIL_EN_LOW (0) +`define SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_INTR_EN_R_NOTIF_CMD_AVAIL_EN_MASK (32'h1) +`define SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_INTR_EN_R_NOTIF_MBOX_ECC_COR_EN_LOW (1) +`define SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_INTR_EN_R_NOTIF_MBOX_ECC_COR_EN_MASK (32'h2) +`define SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_INTR_EN_R_NOTIF_DEBUG_LOCKED_EN_LOW (2) +`define SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_INTR_EN_R_NOTIF_DEBUG_LOCKED_EN_MASK (32'h4) +`define SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_INTR_EN_R_NOTIF_SCAN_MODE_EN_LOW (3) +`define SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_INTR_EN_R_NOTIF_SCAN_MODE_EN_MASK (32'h8) +`define SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_INTR_EN_R_NOTIF_SOC_REQ_LOCK_EN_LOW (4) +`define SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_INTR_EN_R_NOTIF_SOC_REQ_LOCK_EN_MASK (32'h10) +`define SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_INTR_EN_R_NOTIF_GEN_IN_TOGGLE_EN_LOW (5) +`define SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_INTR_EN_R_NOTIF_GEN_IN_TOGGLE_EN_MASK (32'h20) +`endif +`ifndef SOC_IFC_REG_INTR_BLOCK_RF_ERROR_GLOBAL_INTR_R +`define SOC_IFC_REG_INTR_BLOCK_RF_ERROR_GLOBAL_INTR_R (32'h80c) +`define SOC_IFC_REG_INTR_BLOCK_RF_ERROR_GLOBAL_INTR_R_AGG_STS_LOW (0) +`define SOC_IFC_REG_INTR_BLOCK_RF_ERROR_GLOBAL_INTR_R_AGG_STS_MASK (32'h1) +`endif +`ifndef SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_GLOBAL_INTR_R +`define SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_GLOBAL_INTR_R (32'h810) +`define SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_GLOBAL_INTR_R_AGG_STS_LOW (0) +`define SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_GLOBAL_INTR_R_AGG_STS_MASK (32'h1) +`endif +`ifndef SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R +`define SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R (32'h814) +`define SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_INTERNAL_STS_LOW (0) +`define SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_INTERNAL_STS_MASK (32'h1) +`define SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_INV_DEV_STS_LOW (1) +`define SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_INV_DEV_STS_MASK (32'h2) +`define SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_CMD_FAIL_STS_LOW (2) +`define SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_CMD_FAIL_STS_MASK (32'h4) +`define SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_BAD_FUSE_STS_LOW (3) +`define SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_BAD_FUSE_STS_MASK (32'h8) +`define SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_ICCM_BLOCKED_STS_LOW (4) +`define SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_ICCM_BLOCKED_STS_MASK (32'h10) +`define SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_MBOX_ECC_UNC_STS_LOW (5) +`define SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_MBOX_ECC_UNC_STS_MASK (32'h20) +`define SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_WDT_TIMER1_TIMEOUT_STS_LOW (6) +`define SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_WDT_TIMER1_TIMEOUT_STS_MASK (32'h40) +`define SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_WDT_TIMER2_TIMEOUT_STS_LOW (7) +`define SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_WDT_TIMER2_TIMEOUT_STS_MASK (32'h80) +`endif +`ifndef SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R +`define SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R (32'h818) +`define SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_CMD_AVAIL_STS_LOW (0) +`define SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_CMD_AVAIL_STS_MASK (32'h1) +`define SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_MBOX_ECC_COR_STS_LOW (1) +`define SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_MBOX_ECC_COR_STS_MASK (32'h2) +`define SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_DEBUG_LOCKED_STS_LOW (2) +`define SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_DEBUG_LOCKED_STS_MASK (32'h4) +`define SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_SCAN_MODE_STS_LOW (3) +`define SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_SCAN_MODE_STS_MASK (32'h8) +`define SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_SOC_REQ_LOCK_STS_LOW (4) +`define SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_SOC_REQ_LOCK_STS_MASK (32'h10) +`define SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_GEN_IN_TOGGLE_STS_LOW (5) +`define SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_GEN_IN_TOGGLE_STS_MASK (32'h20) +`endif +`ifndef SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R +`define SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R (32'h81c) +`define SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R_ERROR_INTERNAL_TRIG_LOW (0) +`define SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R_ERROR_INTERNAL_TRIG_MASK (32'h1) +`define SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R_ERROR_INV_DEV_TRIG_LOW (1) +`define SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R_ERROR_INV_DEV_TRIG_MASK (32'h2) +`define SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R_ERROR_CMD_FAIL_TRIG_LOW (2) +`define SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R_ERROR_CMD_FAIL_TRIG_MASK (32'h4) +`define SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R_ERROR_BAD_FUSE_TRIG_LOW (3) +`define SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R_ERROR_BAD_FUSE_TRIG_MASK (32'h8) +`define SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R_ERROR_ICCM_BLOCKED_TRIG_LOW (4) +`define SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R_ERROR_ICCM_BLOCKED_TRIG_MASK (32'h10) +`define SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R_ERROR_MBOX_ECC_UNC_TRIG_LOW (5) +`define SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R_ERROR_MBOX_ECC_UNC_TRIG_MASK (32'h20) +`define SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R_ERROR_WDT_TIMER1_TIMEOUT_TRIG_LOW (6) +`define SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R_ERROR_WDT_TIMER1_TIMEOUT_TRIG_MASK (32'h40) +`define SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R_ERROR_WDT_TIMER2_TIMEOUT_TRIG_LOW (7) +`define SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R_ERROR_WDT_TIMER2_TIMEOUT_TRIG_MASK (32'h80) +`endif +`ifndef SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_INTR_TRIG_R +`define SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_INTR_TRIG_R (32'h820) +`define SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_INTR_TRIG_R_NOTIF_CMD_AVAIL_TRIG_LOW (0) +`define SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_INTR_TRIG_R_NOTIF_CMD_AVAIL_TRIG_MASK (32'h1) +`define SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_INTR_TRIG_R_NOTIF_MBOX_ECC_COR_TRIG_LOW (1) +`define SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_INTR_TRIG_R_NOTIF_MBOX_ECC_COR_TRIG_MASK (32'h2) +`define SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_INTR_TRIG_R_NOTIF_DEBUG_LOCKED_TRIG_LOW (2) +`define SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_INTR_TRIG_R_NOTIF_DEBUG_LOCKED_TRIG_MASK (32'h4) +`define SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_INTR_TRIG_R_NOTIF_SCAN_MODE_TRIG_LOW (3) +`define SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_INTR_TRIG_R_NOTIF_SCAN_MODE_TRIG_MASK (32'h8) +`define SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_INTR_TRIG_R_NOTIF_SOC_REQ_LOCK_TRIG_LOW (4) +`define SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_INTR_TRIG_R_NOTIF_SOC_REQ_LOCK_TRIG_MASK (32'h10) +`define SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_INTR_TRIG_R_NOTIF_GEN_IN_TOGGLE_TRIG_LOW (5) +`define SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_INTR_TRIG_R_NOTIF_GEN_IN_TOGGLE_TRIG_MASK (32'h20) +`endif +`ifndef SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_COUNT_R +`define SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_COUNT_R (32'h900) +`endif +`ifndef SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INV_DEV_INTR_COUNT_R +`define SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INV_DEV_INTR_COUNT_R (32'h904) +`endif +`ifndef SOC_IFC_REG_INTR_BLOCK_RF_ERROR_CMD_FAIL_INTR_COUNT_R +`define SOC_IFC_REG_INTR_BLOCK_RF_ERROR_CMD_FAIL_INTR_COUNT_R (32'h908) +`endif +`ifndef SOC_IFC_REG_INTR_BLOCK_RF_ERROR_BAD_FUSE_INTR_COUNT_R +`define SOC_IFC_REG_INTR_BLOCK_RF_ERROR_BAD_FUSE_INTR_COUNT_R (32'h90c) +`endif +`ifndef SOC_IFC_REG_INTR_BLOCK_RF_ERROR_ICCM_BLOCKED_INTR_COUNT_R +`define SOC_IFC_REG_INTR_BLOCK_RF_ERROR_ICCM_BLOCKED_INTR_COUNT_R (32'h910) +`endif +`ifndef SOC_IFC_REG_INTR_BLOCK_RF_ERROR_MBOX_ECC_UNC_INTR_COUNT_R +`define SOC_IFC_REG_INTR_BLOCK_RF_ERROR_MBOX_ECC_UNC_INTR_COUNT_R (32'h914) +`endif +`ifndef SOC_IFC_REG_INTR_BLOCK_RF_ERROR_WDT_TIMER1_TIMEOUT_INTR_COUNT_R +`define SOC_IFC_REG_INTR_BLOCK_RF_ERROR_WDT_TIMER1_TIMEOUT_INTR_COUNT_R (32'h918) +`endif +`ifndef SOC_IFC_REG_INTR_BLOCK_RF_ERROR_WDT_TIMER2_TIMEOUT_INTR_COUNT_R +`define SOC_IFC_REG_INTR_BLOCK_RF_ERROR_WDT_TIMER2_TIMEOUT_INTR_COUNT_R (32'h91c) +`endif +`ifndef SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_CMD_AVAIL_INTR_COUNT_R +`define SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_CMD_AVAIL_INTR_COUNT_R (32'h980) +`endif +`ifndef SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_MBOX_ECC_COR_INTR_COUNT_R +`define SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_MBOX_ECC_COR_INTR_COUNT_R (32'h984) +`endif +`ifndef SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_DEBUG_LOCKED_INTR_COUNT_R +`define SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_DEBUG_LOCKED_INTR_COUNT_R (32'h988) +`endif +`ifndef SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_SCAN_MODE_INTR_COUNT_R +`define SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_SCAN_MODE_INTR_COUNT_R (32'h98c) +`endif +`ifndef SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_SOC_REQ_LOCK_INTR_COUNT_R +`define SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_SOC_REQ_LOCK_INTR_COUNT_R (32'h990) +`endif +`ifndef SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_GEN_IN_TOGGLE_INTR_COUNT_R +`define SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_GEN_IN_TOGGLE_INTR_COUNT_R (32'h994) +`endif +`ifndef SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_COUNT_INCR_R +`define SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_COUNT_INCR_R (32'ha00) +`define SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_COUNT_INCR_R_PULSE_LOW (0) +`define SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_COUNT_INCR_R_PULSE_MASK (32'h1) +`endif +`ifndef SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INV_DEV_INTR_COUNT_INCR_R +`define SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INV_DEV_INTR_COUNT_INCR_R (32'ha04) +`define SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INV_DEV_INTR_COUNT_INCR_R_PULSE_LOW (0) +`define SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INV_DEV_INTR_COUNT_INCR_R_PULSE_MASK (32'h1) +`endif +`ifndef SOC_IFC_REG_INTR_BLOCK_RF_ERROR_CMD_FAIL_INTR_COUNT_INCR_R +`define SOC_IFC_REG_INTR_BLOCK_RF_ERROR_CMD_FAIL_INTR_COUNT_INCR_R (32'ha08) +`define SOC_IFC_REG_INTR_BLOCK_RF_ERROR_CMD_FAIL_INTR_COUNT_INCR_R_PULSE_LOW (0) +`define SOC_IFC_REG_INTR_BLOCK_RF_ERROR_CMD_FAIL_INTR_COUNT_INCR_R_PULSE_MASK (32'h1) +`endif +`ifndef SOC_IFC_REG_INTR_BLOCK_RF_ERROR_BAD_FUSE_INTR_COUNT_INCR_R +`define SOC_IFC_REG_INTR_BLOCK_RF_ERROR_BAD_FUSE_INTR_COUNT_INCR_R (32'ha0c) +`define SOC_IFC_REG_INTR_BLOCK_RF_ERROR_BAD_FUSE_INTR_COUNT_INCR_R_PULSE_LOW (0) +`define SOC_IFC_REG_INTR_BLOCK_RF_ERROR_BAD_FUSE_INTR_COUNT_INCR_R_PULSE_MASK (32'h1) +`endif +`ifndef SOC_IFC_REG_INTR_BLOCK_RF_ERROR_ICCM_BLOCKED_INTR_COUNT_INCR_R +`define SOC_IFC_REG_INTR_BLOCK_RF_ERROR_ICCM_BLOCKED_INTR_COUNT_INCR_R (32'ha10) +`define SOC_IFC_REG_INTR_BLOCK_RF_ERROR_ICCM_BLOCKED_INTR_COUNT_INCR_R_PULSE_LOW (0) +`define SOC_IFC_REG_INTR_BLOCK_RF_ERROR_ICCM_BLOCKED_INTR_COUNT_INCR_R_PULSE_MASK (32'h1) +`endif +`ifndef SOC_IFC_REG_INTR_BLOCK_RF_ERROR_MBOX_ECC_UNC_INTR_COUNT_INCR_R +`define SOC_IFC_REG_INTR_BLOCK_RF_ERROR_MBOX_ECC_UNC_INTR_COUNT_INCR_R (32'ha14) +`define SOC_IFC_REG_INTR_BLOCK_RF_ERROR_MBOX_ECC_UNC_INTR_COUNT_INCR_R_PULSE_LOW (0) +`define SOC_IFC_REG_INTR_BLOCK_RF_ERROR_MBOX_ECC_UNC_INTR_COUNT_INCR_R_PULSE_MASK (32'h1) +`endif +`ifndef SOC_IFC_REG_INTR_BLOCK_RF_ERROR_WDT_TIMER1_TIMEOUT_INTR_COUNT_INCR_R +`define SOC_IFC_REG_INTR_BLOCK_RF_ERROR_WDT_TIMER1_TIMEOUT_INTR_COUNT_INCR_R (32'ha18) +`define SOC_IFC_REG_INTR_BLOCK_RF_ERROR_WDT_TIMER1_TIMEOUT_INTR_COUNT_INCR_R_PULSE_LOW (0) +`define SOC_IFC_REG_INTR_BLOCK_RF_ERROR_WDT_TIMER1_TIMEOUT_INTR_COUNT_INCR_R_PULSE_MASK (32'h1) +`endif +`ifndef SOC_IFC_REG_INTR_BLOCK_RF_ERROR_WDT_TIMER2_TIMEOUT_INTR_COUNT_INCR_R +`define SOC_IFC_REG_INTR_BLOCK_RF_ERROR_WDT_TIMER2_TIMEOUT_INTR_COUNT_INCR_R (32'ha1c) +`define SOC_IFC_REG_INTR_BLOCK_RF_ERROR_WDT_TIMER2_TIMEOUT_INTR_COUNT_INCR_R_PULSE_LOW (0) +`define SOC_IFC_REG_INTR_BLOCK_RF_ERROR_WDT_TIMER2_TIMEOUT_INTR_COUNT_INCR_R_PULSE_MASK (32'h1) +`endif +`ifndef SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_CMD_AVAIL_INTR_COUNT_INCR_R +`define SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_CMD_AVAIL_INTR_COUNT_INCR_R (32'ha20) +`define SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_CMD_AVAIL_INTR_COUNT_INCR_R_PULSE_LOW (0) +`define SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_CMD_AVAIL_INTR_COUNT_INCR_R_PULSE_MASK (32'h1) +`endif +`ifndef SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_MBOX_ECC_COR_INTR_COUNT_INCR_R +`define SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_MBOX_ECC_COR_INTR_COUNT_INCR_R (32'ha24) +`define SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_MBOX_ECC_COR_INTR_COUNT_INCR_R_PULSE_LOW (0) +`define SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_MBOX_ECC_COR_INTR_COUNT_INCR_R_PULSE_MASK (32'h1) +`endif +`ifndef SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_DEBUG_LOCKED_INTR_COUNT_INCR_R +`define SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_DEBUG_LOCKED_INTR_COUNT_INCR_R (32'ha28) +`define SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_DEBUG_LOCKED_INTR_COUNT_INCR_R_PULSE_LOW (0) +`define SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_DEBUG_LOCKED_INTR_COUNT_INCR_R_PULSE_MASK (32'h1) +`endif +`ifndef SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_SCAN_MODE_INTR_COUNT_INCR_R +`define SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_SCAN_MODE_INTR_COUNT_INCR_R (32'ha2c) +`define SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_SCAN_MODE_INTR_COUNT_INCR_R_PULSE_LOW (0) +`define SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_SCAN_MODE_INTR_COUNT_INCR_R_PULSE_MASK (32'h1) +`endif +`ifndef SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_SOC_REQ_LOCK_INTR_COUNT_INCR_R +`define SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_SOC_REQ_LOCK_INTR_COUNT_INCR_R (32'ha30) +`define SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_SOC_REQ_LOCK_INTR_COUNT_INCR_R_PULSE_LOW (0) +`define SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_SOC_REQ_LOCK_INTR_COUNT_INCR_R_PULSE_MASK (32'h1) +`endif +`ifndef SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_GEN_IN_TOGGLE_INTR_COUNT_INCR_R +`define SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_GEN_IN_TOGGLE_INTR_COUNT_INCR_R (32'ha34) +`define SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_GEN_IN_TOGGLE_INTR_COUNT_INCR_R_PULSE_LOW (0) +`define SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_GEN_IN_TOGGLE_INTR_COUNT_INCR_R_PULSE_MASK (32'h1) +`endif + + +`endif \ No newline at end of file diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_sram.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_sram.sv new file mode 100644 index 0000000..b65f8e7 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_sram.sv @@ -0,0 +1,50 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. + +module caliptra_sram #( + parameter DEPTH = 64 + ,parameter DATA_WIDTH = 32 + ,parameter ADDR_WIDTH = $clog2(DEPTH) + + ) + ( + input logic clk_i, + + input logic cs_i, + input logic we_i, + input logic [ADDR_WIDTH-1:0] addr_i, + input logic [DATA_WIDTH-1:0] wdata_i, + output logic [DATA_WIDTH-1:0] rdata_o + ); + + localparam NUM_BYTES = DATA_WIDTH/8 + ((DATA_WIDTH % 8) ? 1 : 0); + + //storage element + logic [7:0] ram [DEPTH][NUM_BYTES-1:0]; + + initial rdata_o = '{default:0}; + always @(posedge clk_i) begin + if (cs_i & we_i) begin + for (int i = 0; i < NUM_BYTES; i++) begin + ram[addr_i][i] <= wdata_i[i*8 +: 8]; + end + end + if (cs_i & ~we_i) begin + for (int i = 0; i < NUM_BYTES; i++) begin + rdata_o[i*8 +: 8] <= ram[addr_i][i]; + end + end + end + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_sva.svh b/designs/Caliptra/src/caliptra-rtl/caliptra_sva.svh new file mode 100644 index 0000000..5f671e6 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_sva.svh @@ -0,0 +1,64 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. + +`ifndef CALIPTRA_SVA +`define CALIPTRA_SVA + +// Default clk and reset signals used by assertion macros below. +`define CALIPTRA_ASSERT_DEFAULT_CLK clk_i +`define CALIPTRA_ASSERT_DEFAULT_RST !rst_ni + +// Converts an arbitrary block of code into a Verilog string +`define STRINGIFY(__x) `"__x`" + +// CALIPTRA_ASSERT_RPT is available to change the reporting mechanism when an assert fails +`define CALIPTRA_ASSERT_RPT(name) \ +`ifdef UVM \ + uvm_pkg::uvm_report_error("CALIPTRA ASSERT FAILED", name, uvm_pkg::UVM_NONE, \ + `__FILE__, `__LINE__); \ +`else \ + $fatal(1, "[CALIPTRA_ASSERT FAILED] [%m] %s (%s:%0d)",name, `__FILE__, `__LINE__); \ +`endif + +// Assert a concurrent property directly. +`define CALIPTRA_ASSERT(assert_name, prop, clk = `CALIPTRA_ASSERT_DEFAULT_CLK, rst = `CALIPTRA_ASSERT_DEFAULT_RST) \ +`ifdef CLP_ASSERT_ON \ + assert_name: assert property (@(posedge clk) disable iff (rst !== 0) (prop)) \ + else begin \ + `CALIPTRA_ASSERT_RPT(`STRINGIFY(assert_name)) \ + end \ +`endif + +// Assert a concurrent property NEVER happens +`define CALIPTRA_ASSERT_NEVER(assert_name, prop, clk = `CALIPTRA_ASSERT_DEFAULT_CLK, rst = `CALIPTRA_ASSERT_DEFAULT_RST) \ +`ifdef CLP_ASSERT_ON \ + assert_name: assert property (@(posedge clk) disable iff (rst !== 0) not (prop)) \ + else begin \ + `CALIPTRA_ASSERT_RPT(`STRINGIFY(assert_name)) \ + end \ +`endif + +// Assert that signal is not x +`define CALIPTRA_ASSERT_KNOWN(assert_name, sig, clk = `CALIPTRA_ASSERT_DEFAULT_CLK, rst = `CALIPTRA_ASSERT_DEFAULT_RST) \ + `CALIPTRA_ASSERT(assert_name, !$isunknown(sig), clk, rst) + +// Assert that a vector of signals is mutually exclusive +`define CALIPTRA_ASSERT_MUTEX(assert_name, sig, clk = `CALIPTRA_ASSERT_DEFAULT_CLK, rst = `CALIPTRA_ASSERT_DEFAULT_RST) \ + `CALIPTRA_ASSERT(assert_name, $onehot0(sig), clk, rst) + +// Assert that a vector of signals is stable (does not change value) +`define CALIPTRA_ASSERT_STABLE(assert_name, sig, clk = `CALIPTRA_ASSERT_DEFAULT_CLK, rst = `CALIPTRA_ASSERT_DEFAULT_RST) \ + `CALIPTRA_ASSERT(assert_name, $stable(sig), clk, rst) + +`endif diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_tlul_adapter_reg.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_tlul_adapter_reg.sv new file mode 100644 index 0000000..fa01e42 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_tlul_adapter_reg.sv @@ -0,0 +1,231 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +`include "caliptra_prim_assert.sv" + +/** + * Tile-Link UL adapter for Register interface + * + * ICEBOX(#15822): Note that due to some modules with special needs (like + * the vendored-in RV_DM), this module has been extended so that it + * supports use cases outside of the generated reg_top module. This makes + * this adapter and its parameterization options a bit heavy. + * + * We should in the future come back to this and refactor / align the + * module and its parameterization needs. + */ + +module caliptra_tlul_adapter_reg + import caliptra_tlul_pkg::*; + import caliptra_prim_mubi_pkg::mubi4_t; +#( + parameter bit CmdIntgCheck = 0, // 1: Enable command integrity check + parameter bit EnableRspIntgGen = 0, // 1: Generate response integrity + parameter bit EnableDataIntgGen = 0, // 1: Generate response data integrity + parameter int RegAw = 8, // Width of register address + parameter int RegDw = 32, // Shall be matched with TL_DW + parameter int AccessLatency = 0, // 0: same cycle, 1: next cycle + localparam int RegBw = RegDw/8 +) ( + input clk_i, + input rst_ni, + + // TL-UL interface + input tl_h2d_t tl_i, + output tl_d2h_t tl_o, + + // control interface + input mubi4_t en_ifetch_i, + output logic intg_error_o, + + // Register interface + output logic re_o, + output logic we_o, + output logic [RegAw-1:0] addr_o, + output logic [RegDw-1:0] wdata_o, + output logic [RegBw-1:0] be_o, + input busy_i, + // The following two signals are expected + // to be returned in AccessLatency cycles. + input [RegDw-1:0] rdata_i, + // This can be a write or read error. + input error_i +); + + `CALIPTRA_ASSERT_INIT(AllowedLatency_A, AccessLatency inside {0, 1}) + + localparam int IW = $bits(tl_i.a_source); + localparam int SZW = $bits(tl_i.a_size); + + logic outstanding_q; // Indicates current request is pending + logic a_ack, d_ack; + + logic [RegDw-1:0] rdata, rdata_q; + logic error_q, error, err_internal, instr_error, intg_error; + + logic addr_align_err; // Size and alignment + logic tl_err; // Common TL-UL error checker + + logic [IW-1:0] reqid_q; + logic [SZW-1:0] reqsz_q; + tl_d_op_e rspop_q; + + logic rd_req, wr_req; + + assign a_ack = tl_i.a_valid & tl_o.a_ready; + assign d_ack = tl_o.d_valid & tl_i.d_ready; + // Request signal + assign wr_req = a_ack & ((tl_i.a_opcode == PutFullData) | (tl_i.a_opcode == PutPartialData)); + assign rd_req = a_ack & (tl_i.a_opcode == Get); + + assign we_o = wr_req & ~err_internal; + assign re_o = rd_req & ~err_internal; + assign wdata_o = tl_i.a_data; + assign be_o = tl_i.a_mask; + + if (RegAw <= 2) begin : gen_only_one_reg + assign addr_o = '0; + end else begin : gen_more_regs + assign addr_o = {tl_i.a_address[RegAw-1:2], 2'b00}; // generate always word-align + end + + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) outstanding_q <= 1'b0; + else if (a_ack) outstanding_q <= 1'b1; + else if (d_ack) outstanding_q <= 1'b0; + end + + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + reqid_q <= '0; + reqsz_q <= '0; + rspop_q <= AccessAck; + end else if (a_ack) begin + reqid_q <= tl_i.a_source; + reqsz_q <= tl_i.a_size; + // Return AccessAckData regardless of error + rspop_q <= (rd_req) ? AccessAckData : AccessAck ; + end + end + + if (AccessLatency == 1) begin : gen_access_latency1 + logic wr_req_q, rd_req_q; + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + rdata_q <= '0; + error_q <= 1'b0; + wr_req_q <= 1'b0; + rd_req_q <= 1'b0; + end else begin + rd_req_q <= rd_req; + wr_req_q <= wr_req; + // Addressing phase + if (a_ack) begin + error_q <= err_internal; + // Response phase + end else begin + error_q <= error; + rdata_q <= rdata; + end + end + end + assign rdata = (error_i || error_q || wr_req_q) ? '1 : + (rd_req_q) ? rdata_i : + rdata_q; // backpressure case + assign error = (rd_req_q || wr_req_q) ? (error_q || error_i) : + error_q; // backpressure case + end else begin : gen_access_latency0 + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + rdata_q <= '0; + error_q <= 1'b0; + end else if (a_ack) begin + rdata_q <= (error_i || err_internal || wr_req) ? '1 : rdata_i; + error_q <= error_i || err_internal; + end + end + assign rdata = rdata_q; + assign error = error_q; + end + + caliptra_tlul_pkg::tl_d2h_t tl_o_pre; + assign tl_o_pre = '{ + // busy is selected based on address + // thus if there is no valid transaction, we should ignore busy + a_ready: ~(outstanding_q | tl_i.a_valid & busy_i), + d_valid: outstanding_q, + d_opcode: rspop_q, + d_param: '0, + d_size: reqsz_q, + d_source: reqid_q, + d_sink: '0, + d_data: rdata, + d_user: '0, + d_error: error + }; + + // outgoing integrity generation + caliptra_tlul_rsp_intg_gen #( + .EnableRspIntgGen(EnableRspIntgGen), + .EnableDataIntgGen(EnableDataIntgGen) + ) u_rsp_intg_gen ( + .tl_i(tl_o_pre), + .tl_o(tl_o) + ); + + if (CmdIntgCheck) begin : gen_cmd_intg_check + logic intg_error_q; + caliptra_tlul_cmd_intg_chk u_cmd_intg_chk ( + .tl_i(tl_i), + .err_o(intg_error) + ); + // permanently latch integrity error until reset + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + intg_error_q <= 1'b0; + end else if (intg_error) begin + intg_error_q <= 1'b1; + end + end + assign intg_error_o = intg_error_q; + end else begin : gen_no_cmd_intg_check + assign intg_error = 1'b0; + assign intg_error_o = 1'b0; + end + + //////////////////// + // Error Handling // + //////////////////// + + // An instruction type transaction is only valid if en_ifetch is enabled + assign instr_error = caliptra_prim_mubi_pkg::mubi4_test_true_strict(tl_i.a_user.instr_type) & + caliptra_prim_mubi_pkg::mubi4_test_false_loose(en_ifetch_i); + + assign err_internal = addr_align_err | tl_err | instr_error | intg_error; + + // addr_align_err + // Raised if addr isn't aligned with the size + // Read size error is checked in tlul_assert.sv + // Here is it added due to the limitation of register interface. + always_comb begin + if (wr_req) begin + // Only word-align is accepted based on comportability spec + addr_align_err = |tl_i.a_address[1:0]; + end else begin + // No request + addr_align_err = 1'b0; + end + end + + // tl_err : separate checker + caliptra_tlul_err u_err ( + .clk_i, + .rst_ni, + .tl_i, + .err_o (tl_err) + ); + + `CALIPTRA_ASSERT_INIT(MatchedWidthAssert, RegDw == TL_DW) + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_tlul_adapter_sram.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_tlul_adapter_sram.sv new file mode 100644 index 0000000..3407b8d --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_tlul_adapter_sram.sv @@ -0,0 +1,683 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +`include "caliptra_prim_assert.sv" + +/** + * Tile-Link UL adapter for SRAM-like devices + * + * - Intentionally omitted BaseAddr in case of multiple memory maps are used in a SoC, + * it means that aliasing can happen if target device size in TL-UL crossbar is bigger + * than SRAM size + * - At most one of EnableDataIntgGen / EnableDataIntgPt can be enabled. However it + * possible for both to be disabled. + * A module can neither generate an integrity response nor pass through any pre-existing + * integrity. This might be the case for non-security critical memories where there is + * no stored integrity AND another entity upstream is already generating returning integrity. + * There is however no case where EnableDataIntgGen and EnableDataIntgPt are both true. + */ +module caliptra_tlul_adapter_sram + import caliptra_tlul_pkg::*; + import caliptra_prim_mubi_pkg::mubi4_t; +#( + parameter int SramAw = 12, + parameter int SramDw = 32, // Must be multiple of the TL width + parameter int Outstanding = 1, // Only one request is accepted + parameter int SramBusBankAW = 12, // SRAM bus address width of the SRAM bank. Only used + // when DataXorAddr=1. + parameter bit ByteAccess = 1, // 1: Enables sub-word write transactions. Note that this + // results in read-modify-write operations for integrity + // re-generation if EnableDataIntgPt is set to 1. + parameter bit ErrOnWrite = 0, // 1: Writes not allowed, automatically error + parameter bit ErrOnRead = 0, // 1: Reads not allowed, automatically error + parameter bit CmdIntgCheck = 0, // 1: Enable command integrity check + parameter bit EnableRspIntgGen = 0, // 1: Generate response integrity + parameter bit EnableDataIntgGen = 0, // 1: Generate response data integrity + parameter bit EnableDataIntgPt = 0, // 1: Passthrough command/response data integrity + parameter bit SecFifoPtr = 0, // 1: Duplicated fifo pointers + parameter bit EnableReadback = 0, // 1: Readback and check written/read data. + parameter bit DataXorAddr = 0, // 1: XOR data and address for address protection + localparam int WidthMult = SramDw / TL_DW, + localparam int IntgWidth = caliptra_tlul_pkg::DataIntgWidth * WidthMult, + localparam int DataOutW = EnableDataIntgPt ? SramDw + IntgWidth : SramDw +) ( + input clk_i, + input rst_ni, + + // TL-UL interface + input tl_h2d_t tl_i, + output tl_d2h_t tl_o, + + // control interface + input mubi4_t en_ifetch_i, + + // SRAM interface + output logic req_o, + output mubi4_t req_type_o, + input gnt_i, + output logic we_o, + output logic [SramAw-1:0] addr_o, + output logic [DataOutW-1:0] wdata_o, + output logic [DataOutW-1:0] wmask_o, + output logic intg_error_o, + input [DataOutW-1:0] rdata_i, + input rvalid_i, + input [1:0] rerror_i, // 2 bit error [1]: Uncorrectable, [0]: Correctable + output logic compound_txn_in_progress_o, + input mubi4_t readback_en_i, + output logic readback_error_o, + input logic wr_collision_i, + input logic write_pending_i +); + + localparam int SramByte = SramDw/8; + localparam int DataBitWidth = caliptra_prim_util_pkg::vbits(SramByte); + localparam int WoffsetWidth = (SramByte == TL_DBW) ? 1 : + DataBitWidth - caliptra_prim_util_pkg::vbits(TL_DBW); + + logic error_det; // Internal protocol error checker + logic error_internal; // Internal protocol error checker + logic wr_attr_error; + logic instr_error; + logic wr_vld_error; + logic rd_vld_error; + logic rsp_fifo_error; + logic sramreqfifo_error; + logic reqfifo_error; + logic intg_error; + logic tlul_error; + logic readback_error; + logic sram_byte_readback_error; + + // readback check + logic readback_error_q; + if (EnableReadback) begin : gen_cmd_readback_check + assign readback_error = sram_byte_readback_error; + // permanently latch readback error until reset + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + readback_error_q <= '0; + end else if (readback_error) begin + readback_error_q <= 1'b1; + end + end + end else begin : gen_no_readback_check + logic unused_sram_byte_readback_error; + assign unused_sram_byte_readback_error = sram_byte_readback_error; + assign readback_error = '0; + assign readback_error_q = '0; + end + + // readback error output is permanent and should be used for alert generation + // or other downstream effects + assign readback_error_o = readback_error | readback_error_q; + + // integrity check + if (CmdIntgCheck) begin : gen_cmd_intg_check + caliptra_tlul_cmd_intg_chk u_cmd_intg_chk ( + .tl_i(tl_i), + .err_o (intg_error) + ); + end else begin : gen_no_cmd_intg_check + assign intg_error = '0; + end + + // permanently latch integrity error until reset + logic intg_error_q; + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + intg_error_q <= '0; + end else if (intg_error || rsp_fifo_error || sramreqfifo_error || reqfifo_error) begin + intg_error_q <= 1'b1; + end + end + + // integrity error output is permanent and should be used for alert generation + // or other downstream effects + assign intg_error_o = intg_error | rsp_fifo_error | sramreqfifo_error | + reqfifo_error | intg_error_q; + + // wr_attr_error: Check if the request size, mask are permitted. + // Basic check of size, mask, addr align is done in tlul_err module. + // Here it checks any partial write if ByteAccess isn't allowed. + assign wr_attr_error = (tl_i.a_opcode == PutFullData || tl_i.a_opcode == PutPartialData) + ? ((ByteAccess == 0) ? + (tl_i.a_mask != '1 || tl_i.a_size != 2'h2) : 1'b0) + : 1'b0; + + // An instruction type transaction is only valid if en_ifetch is enabled + // If the instruction type is completely invalid, also considered an instruction error + assign instr_error = caliptra_prim_mubi_pkg::mubi4_test_invalid(tl_i.a_user.instr_type) | + (caliptra_prim_mubi_pkg::mubi4_test_true_strict(tl_i.a_user.instr_type) & + caliptra_prim_mubi_pkg::mubi4_test_false_loose(en_ifetch_i)); + + if (ErrOnWrite == 1) begin : gen_no_writes + assign wr_vld_error = tl_i.a_opcode != Get; + end else begin : gen_writes_allowed + assign wr_vld_error = 1'b0; + end + + if (ErrOnRead == 1) begin: gen_no_reads + assign rd_vld_error = tl_i.a_opcode == Get; + end else begin : gen_reads_allowed + assign rd_vld_error = 1'b0; + end + + // tlul protocol check + caliptra_tlul_err u_err ( + .clk_i, + .rst_ni, + .tl_i(tl_i), + .err_o (tlul_error) + ); + + // error return is transactional and thus does not used the "latched" intg_err signal + assign error_det = wr_attr_error | wr_vld_error | rd_vld_error | instr_error | + tlul_error | intg_error; + + // from sram_byte to adapter logic + tl_h2d_t tl_i_int; + // from adapter logic to sram_byte + tl_d2h_t tl_o_int; + // from sram_byte to rsp_gen + tl_d2h_t tl_out; + + // not all parts of tl_i_int are used + logic unused_tl_i_int; + assign unused_tl_i_int = ^tl_i_int; + + caliptra_tlul_rsp_intg_gen #( + .EnableRspIntgGen(EnableRspIntgGen), + .EnableDataIntgGen(EnableDataIntgGen) + ) u_rsp_gen ( + .tl_i(tl_out), + .tl_o + ); + + // byte handling for integrity + caliptra_tlul_sram_byte #( + .EnableIntg(ByteAccess & EnableDataIntgPt & !ErrOnWrite), + .Outstanding(Outstanding), + .EnableReadback(EnableReadback) + ) u_sram_byte ( + .clk_i, + .rst_ni, + .tl_i, + .tl_o(tl_out), + .tl_sram_o(tl_i_int), + .tl_sram_i(tl_o_int), + .error_i(error_det), + .error_o(error_internal), + .alert_o(sram_byte_readback_error), + .compound_txn_in_progress_o, + .readback_en_i, + .wr_collision_i, + .write_pending_i + ); + + typedef struct packed { + logic [TL_DBW-1:0] mask ; // Byte mask within the TL-UL word + logic [WoffsetWidth-1:0] woffset ; // Offset of the TL-UL word within the SRAM word + } sram_req_t ; + + typedef struct packed { + logic [SramBusBankAW-1:0] addr; // Address of the request going to the memory. + } sram_req_addr_t ; + + typedef enum logic [1:0] { + OpWrite, + OpRead, + OpUnknown + } req_op_e ; + + typedef struct packed { + req_op_e op ; + logic error ; + caliptra_prim_mubi_pkg::mubi4_t instr_type; + logic [TL_SZW-1:0] size ; + logic [TL_AIW-1:0] source ; + } req_t ; + + typedef struct packed { + logic [TL_DW-1:0] data ; + logic [DataIntgWidth-1:0] data_intg ; + logic error ; + } rsp_t ; + + localparam int SramReqFifoWidth = $bits(sram_req_t) ; + localparam int ReqFifoWidth = $bits(req_t) ; + localparam int RspFifoWidth = $bits(rsp_t) ; + + // FIFO signal in case OutStand is greater than 1 + // If request is latched, {write, source} is pushed to req fifo. + // Req fifo is popped when D channel is acknowledged (v & r) + // D channel valid is asserted if it is write request or rsp fifo not empty if read. + logic reqfifo_wvalid, reqfifo_wready; + logic reqfifo_rvalid, reqfifo_rready; + req_t reqfifo_wdata, reqfifo_rdata; + + logic sramreqfifo_wvalid, sramreqfifo_wready; + logic sramreqfifo_rready; + sram_req_t sramreqfifo_wdata, sramreqfifo_rdata; + + logic sramreqaddrfifo_wready; + logic [SramBusBankAW-1:0] sramreqaddrfifo_wdata, sramreqaddrfifo_rdata; + + logic rspfifo_wvalid, rspfifo_wready; + logic rspfifo_rvalid, rspfifo_rready; + rsp_t rspfifo_wdata, rspfifo_rdata; + + logic a_ack, d_ack, sram_ack; + assign a_ack = tl_i_int.a_valid & tl_o_int.a_ready ; + assign d_ack = tl_o_int.d_valid & tl_i_int.d_ready ; + assign sram_ack = req_o & gnt_i ; + + // Valid handling + logic d_valid, d_error; + always_comb begin + d_valid = 1'b0; + + if (reqfifo_rvalid) begin + if (reqfifo_rdata.error) begin + // Return error response. Assume no request went out to SRAM + d_valid = 1'b1; + end else if (reqfifo_rdata.op == OpRead) begin + d_valid = rspfifo_rvalid; + end else begin + // Write without error + d_valid = 1'b1; + end + end else begin + d_valid = 1'b0; + end + end + + + + always_comb begin + d_error = 1'b0; + + if (reqfifo_rvalid) begin + if (reqfifo_rdata.op == OpRead) begin + d_error = rspfifo_rdata.error | reqfifo_rdata.error; + end else begin + d_error = reqfifo_rdata.error; + end + end else begin + d_error = 1'b0; + end + end + + logic vld_rd_rsp; + assign vld_rd_rsp = d_valid & reqfifo_rvalid & rspfifo_rvalid & (reqfifo_rdata.op == OpRead); + // If the response data is not valid, we set it to an illegal blanking value which is determined + // by whether the current transaction is an instruction fetch or a regular read operation. + logic [TL_DW-1:0] error_blanking_data; + assign error_blanking_data = (caliptra_prim_mubi_pkg::mubi4_test_true_strict(reqfifo_rdata.instr_type)) ? + DataWhenInstrError : + DataWhenError; + + // Since DataWhenInstrError and DataWhenError can be arbitrary parameters + // we statically calculate the correct integrity values for these parameters here so that + // they do not have to be supplied externally. + logic [TL_DW-1:0] unused_instr, unused_data; + logic [DataIntgWidth-1:0] error_instr_integ, error_data_integ; + caliptra_tlul_data_integ_enc u_tlul_data_integ_enc_instr ( + .data_i(DataMaxWidth'(DataWhenInstrError)), + .data_intg_o({error_instr_integ, unused_instr}) + ); + caliptra_tlul_data_integ_enc u_tlul_data_integ_enc_data ( + .data_i(DataMaxWidth'(DataWhenError)), + .data_intg_o({error_data_integ, unused_data}) + ); + + logic [DataIntgWidth-1:0] error_blanking_integ; + assign error_blanking_integ = (caliptra_prim_mubi_pkg::mubi4_test_true_strict(reqfifo_rdata.instr_type)) ? + error_instr_integ : + error_data_integ; + + logic [TL_DW-1:0] d_data; + assign d_data = (vld_rd_rsp & ~d_error) ? rspfifo_rdata.data // valid read + : error_blanking_data; // write or TL-UL error + + // If this a write response with data fields set to 0, we have to set all ECC bits correctly + // since we are using an inverted Hsiao code. + logic [DataIntgWidth-1:0] data_intg; + assign data_intg = (vld_rd_rsp && reqfifo_rdata.error) ? error_blanking_integ : // TL-UL error + (vld_rd_rsp) ? rspfifo_rdata.data_intg : // valid read + caliptra_prim_secded_pkg::SecdedInv3932ZeroEcc; // valid write + + // When an error is seen on an incoming transaction it gets an immediate response without + // performing an SRAM request. It may be the transaction receives a ready the first cycle it is + // seen, but if not we force a ready the following cycle. This avoids factoring the error + // calculation into the outgoing ready preventing a feedthrough path from the incoming tilelink + // signals to the outgoing tilelink signals. + logic missed_err_gnt_d, missed_err_gnt_q; + + // Track whether we've seen an incoming transaction with an error that didn't get a ready + assign missed_err_gnt_d = error_internal & tl_i_int.a_valid & ~tl_o_int.a_ready; + + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + missed_err_gnt_q <= 1'b0; + end else begin + missed_err_gnt_q <= missed_err_gnt_d; + end + end + + assign tl_o_int = '{ + d_valid : d_valid , + d_opcode : (d_valid && reqfifo_rdata.op != OpRead) ? AccessAck : AccessAckData, + d_param : '0, + d_size : (d_valid) ? reqfifo_rdata.size : '0, + d_source : (d_valid) ? reqfifo_rdata.source : '0, + d_sink : 1'b0, + d_data : d_data, + d_user : '{default: '0, data_intg: data_intg}, + d_error : d_valid && d_error, + a_ready : (gnt_i | missed_err_gnt_q) & reqfifo_wready & sramreqfifo_wready & + sramreqaddrfifo_wready + }; + + // a_ready depends on the FIFO full condition and grant from SRAM (or SRAM arbiter) + // assemble response, including read response, write response, and error for unsupported stuff + + // Output to SRAM: + // Generate request only when no internal error occurs. If error occurs, the request should be + // dropped and returned error response to the host. So, error to be pushed to reqfifo. + // In this case, it is assumed the request is granted (may cause ordering issue later?) + assign req_o = tl_i_int.a_valid & reqfifo_wready & ~error_internal; + assign req_type_o = tl_i_int.a_user.instr_type; + assign we_o = tl_i_int.a_valid & (tl_i_int.a_opcode inside {PutFullData, PutPartialData}); + assign addr_o = (tl_i_int.a_valid) ? tl_i_int.a_address[DataBitWidth+:SramAw] : '0; + + // Support SRAMs wider than the TL-UL word width by mapping the parts of the + // TL-UL address which are more fine-granular than the SRAM width to the + // SRAM write mask. + logic [WoffsetWidth-1:0] woffset; + if (TL_DW != SramDw) begin : gen_wordwidthadapt + assign woffset = tl_i_int.a_address[DataBitWidth-1:caliptra_prim_util_pkg::vbits(TL_DBW)]; + end else begin : gen_no_wordwidthadapt + assign woffset = '0; + end + + // The size of the data/wmask depends on whether passthrough integrity is enabled. + // If passthrough integrity is enabled, the data is concatenated with the integrity passed through + // the user bits. Otherwise, it is the data only. + localparam int DataWidth = EnableDataIntgPt ? TL_DW + DataIntgWidth : TL_DW; + + // Final combined wmask / wdata + logic [WidthMult-1:0][DataWidth-1:0] wmask_combined; + logic [WidthMult-1:0][DataWidth-1:0] wdata_combined; + + // Original tlul portion + logic [WidthMult-1:0][TL_DW-1:0] wmask_int; + logic [WidthMult-1:0][TL_DW-1:0] wdata_int; + + // Integrity portion + logic [WidthMult-1:0][DataIntgWidth-1:0] wmask_intg; + logic [WidthMult-1:0][DataIntgWidth-1:0] wdata_intg; + + always_comb begin + wmask_int = '0; + wdata_int = '0; + + if (tl_i_int.a_valid) begin + for (int i = 0 ; i < TL_DW/8 ; i++) begin + wmask_int[woffset][8*i +: 8] = {8{tl_i_int.a_mask[i]}}; + wdata_int[woffset][8*i +: 8] = (tl_i_int.a_mask[i] && we_o) ? tl_i_int.a_data[8*i+:8] : '0; + end + end + end + + always_comb begin + wmask_intg = '0; + wdata_intg = '0; + + if (tl_i_int.a_valid) begin + wmask_intg[woffset] = {DataIntgWidth{1'b1}}; + wdata_intg[woffset] = tl_i_int.a_user.data_intg; + end + end + + for (genvar i = 0; i < WidthMult; i++) begin : gen_write_output + if (EnableDataIntgPt) begin : gen_combined_output + assign wmask_combined[i] = {wmask_intg[i], wmask_int[i]}; + assign wdata_combined[i] = {wdata_intg[i], wdata_int[i]}; + end else begin : gen_ft_output + logic unused_w; + assign wmask_combined[i] = wmask_int[i]; + assign wdata_combined[i] = wdata_int[i]; + assign unused_w = |wmask_intg & |wdata_intg; + end + end + + assign wmask_o = wmask_combined; + assign wdata_o = wdata_combined; + + assign reqfifo_wvalid = a_ack ; // Push to FIFO only when granted + assign reqfifo_wdata = '{ + op: (tl_i_int.a_opcode != Get) ? OpWrite : OpRead, // To return AccessAck for opcode error + error: error_internal, + instr_type: tl_i_int.a_user.instr_type, + size: tl_i_int.a_size, + source: tl_i_int.a_source + }; // Store the request only. Doesn't have to store data + assign reqfifo_rready = d_ack ; + + // push together with ReqFIFO, pop upon returning read + assign sramreqfifo_wdata = '{ + mask : tl_i_int.a_mask, + woffset : woffset + }; + assign sramreqfifo_wvalid = sram_ack & ~we_o; + assign sramreqfifo_rready = rspfifo_wvalid; + + assign rspfifo_wvalid = rvalid_i & reqfifo_rvalid; + + assign sramreqaddrfifo_wdata = tl_i_int.a_address[DataBitWidth+:SramBusBankAW]; + + // Make sure only requested bytes are forwarded + logic [WidthMult-1:0][DataWidth-1:0] rdata_reshaped; + logic [DataWidth-1:0] rdata_tlword; + + // This just changes the array format so that the correct word can be selected by indexing. + assign rdata_reshaped = rdata_i; + + if (EnableDataIntgPt) begin : gen_no_rmask + always_comb begin + // If the read mask is set to zero, all read data is zeroed out by the mask. + // We have to set the ECC bits accordingly since we are using an inverted Hsiao code. + rdata_tlword = caliptra_prim_secded_pkg::SecdedInv3932ZeroWord; + // Otherwise, if at least one mask bit is nonzero, we are passing through the integrity. + // In that case we need to feed back the entire word since otherwise the integrity + // will not calculate correctly. + if (|sramreqfifo_rdata.mask) begin + // Select correct word. + if (DataXorAddr) begin : gen_data_xor_addr + // When DataXorAddr is enabled, on a read, the address is XORed with the data fetched from + // the memory in the underlying memory controller (e.g., flash controller). At this point, + // the address is again removed. If the address in the read transaction has been modified, + // e.g., due to a fault, rdata now contains faulty data, which is detected by the + // integrity mechanism. + rdata_tlword = { + rdata_reshaped[sramreqfifo_rdata.woffset][DataWidth-1:TL_DW], + rdata_reshaped[sramreqfifo_rdata.woffset][TL_DW-1:0] ^ + {{(TL_DW-SramBusBankAW){1'b0}}, sramreqaddrfifo_rdata} + }; + end else begin: gen_no_data_xor_addr + rdata_tlword = rdata_reshaped[sramreqfifo_rdata.woffset]; + end + end + end + end else begin : gen_rmask + logic [DataWidth-1:0] rmask; + always_comb begin + rmask = '0; + for (int i = 0 ; i < TL_DW/8 ; i++) begin + rmask[8*i +: 8] = {8{sramreqfifo_rdata.mask[i]}}; + end + end + // Select correct word and mask it. + assign rdata_tlword = rdata_reshaped[sramreqfifo_rdata.woffset] & rmask; + end + + assign rspfifo_wdata = '{ + data : rdata_tlword[TL_DW-1:0], + data_intg : EnableDataIntgPt ? rdata_tlword[DataWidth-1 -: DataIntgWidth] : '0, + error : rerror_i[1] // Only care for Uncorrectable error + }; + assign rspfifo_rready = (reqfifo_rdata.op == OpRead & ~reqfifo_rdata.error) + ? reqfifo_rready : 1'b0 ; + + // This module only cares about uncorrectable errors. + logic unused_rerror; + assign unused_rerror = rerror_i[0]; + + // FIFO instance: REQ, RSP + + // ReqFIFO is to store the Access type to match to the Response data. + // For instance, SRAM accepts the write request but doesn't return the + // acknowledge. In this case, it may be hard to determine when the D + // response for the write data should send out if reads/writes are + // interleaved. So, to make it in-order (even TL-UL allows out-of-order + // responses), storing the request is necessary. And if the read entry + // is write op, it is safe to return the response right away. If it is + // read reqeust, then D response is waiting until read data arrives. + caliptra_prim_fifo_sync #( + .Width (ReqFifoWidth), + .Pass (1'b0), + .Depth (Outstanding), + .Secure (SecFifoPtr) + ) u_reqfifo ( + .clk_i, + .rst_ni, + .clr_i (1'b0), + .wvalid_i(reqfifo_wvalid), + .wready_o(reqfifo_wready), + .wdata_i (reqfifo_wdata), + .rvalid_o(reqfifo_rvalid), + .rready_i(reqfifo_rready), + .rdata_o (reqfifo_rdata), + .full_o (), + .depth_o (), + .err_o (reqfifo_error) + ); + + // sramreqfifo: + // While the ReqFIFO holds the request until it is sent back via TL-UL, the + // sramreqfifo only needs to hold the mask and word offset until the read + // data returns from memory. + caliptra_prim_fifo_sync #( + .Width (SramReqFifoWidth), + .Pass (1'b0), + .Depth (Outstanding), + .Secure (SecFifoPtr) + ) u_sramreqfifo ( + .clk_i, + .rst_ni, + .clr_i (1'b0), + .wvalid_i(sramreqfifo_wvalid), + .wready_o(sramreqfifo_wready), + .wdata_i (sramreqfifo_wdata), + .rvalid_o(), + .rready_i(sramreqfifo_rready), + .rdata_o (sramreqfifo_rdata), + .full_o (), + .depth_o (), + .err_o (sramreqfifo_error) + ); + + // sramreqaddrfifo: + // This fifo holds the address used for undoing the address XOR data infection. + if (DataXorAddr) begin : gen_data_xor_addr_fifo + prim_fifo_sync #( + .Width (SramBusBankAW), + .Pass (1'b0), + .Depth (Outstanding), + .OutputZeroIfEmpty (1) + ) u_sramreqaddrfifo ( + .clk_i, + .rst_ni, + .clr_i (1'b0), + .wvalid_i(sramreqfifo_wvalid), + .wready_o(sramreqaddrfifo_wready), + .wdata_i (sramreqaddrfifo_wdata), + .rvalid_o(), + .rready_i(sramreqfifo_rready), + .rdata_o (sramreqaddrfifo_rdata), + .full_o (), + .depth_o (), + .err_o () + ); + end else begin : gen_no_data_xor_addr_fifo + assign sramreqaddrfifo_wready = 1'b1; + assign sramreqaddrfifo_rdata = '0; + + // Tie-off unused signals + logic unused_sramreqaddrfifo; + assign unused_sramreqaddrfifo = ^{sramreqaddrfifo_wdata, sramreqaddrfifo_rdata}; + end + + // Rationale having #Outstanding depth in response FIFO. + // In normal case, if the host or the crossbar accepts the response data, + // response FIFO isn't needed. But if in any case it has a chance to be + // back pressured, the response FIFO should store the returned data not to + // lose the data from the SRAM interface. Remember, SRAM interface doesn't + // have back-pressure signal such as read_ready. + caliptra_prim_fifo_sync #( + .Width (RspFifoWidth), + .Pass (1'b1), + .Depth (Outstanding), + .Secure (SecFifoPtr) + ) u_rspfifo ( + .clk_i, + .rst_ni, + .clr_i (1'b0), + .wvalid_i(rspfifo_wvalid), + .wready_o(rspfifo_wready), + .wdata_i (rspfifo_wdata), + .rvalid_o(rspfifo_rvalid), + .rready_i(rspfifo_rready), + .rdata_o (rspfifo_rdata), + .full_o (), + .depth_o (), + .err_o (rsp_fifo_error) + ); + + // below assertion fails when SRAM rvalid is asserted even though ReqFifo is empty + `CALIPTRA_ASSERT(rvalidHighReqFifoEmpty, rvalid_i |-> reqfifo_rvalid) + + // below assertion fails when outstanding value is too small (SRAM rvalid is asserted + // even though the RspFifo is full) + `CALIPTRA_ASSERT(rvalidHighWhenRspFifoFull, rvalid_i |-> rspfifo_wready) + + // If both ErrOnWrite and ErrOnRead are set, this block is useless + `CALIPTRA_ASSERT_INIT(adapterNoReadOrWrite, (ErrOnWrite & ErrOnRead) == 0) + + `CALIPTRA_ASSERT_INIT(SramDwHasByteGranularity_A, SramDw % 8 == 0) + `CALIPTRA_ASSERT_INIT(SramDwIsMultipleOfTlulWidth_A, SramDw % TL_DW == 0) + + // These parameter options cannot both be true at the same time + `CALIPTRA_ASSERT_INIT(DataIntgOptions_A, ~(EnableDataIntgGen & EnableDataIntgPt)) + + // Make sure that outputs are defined (a special case for tl_o is explained separately below) + `CALIPTRA_ASSERT_KNOWN(ReqOutKnown_A, req_o ) + `CALIPTRA_ASSERT_KNOWN(WeOutKnown_A, we_o ) + `CALIPTRA_ASSERT_KNOWN(AddrOutKnown_A, addr_o ) + `CALIPTRA_ASSERT_KNOWN(WdataOutKnown_A, wdata_o) + `CALIPTRA_ASSERT_KNOWN(WmaskOutKnown_A, wmask_o) + + // We'd like to claim that the payload of the TL output is known, but this isn't necessarily true! + // This block is just an adapter that converts from an SRAM interface to a TL interface. To make + // the assertion true, we need to weaken it to say that that tl_o is only X if the SRAM supplied + // that X. + // + // This is a bit tricky to track because SRAM responses get stored in u_rspfifo. Assuming that the + // FIFO doesn't manufacture X's (an assertion in prim_fifo_sync), the only stage of the path + // needed in this file is the following: + `CALIPTRA_ASSERT_KNOWN(TlOutValidKnown_A, tl_o.d_valid) + `CALIPTRA_ASSERT(TlOutKnownIfFifoKnown_A, !$isunknown(rspfifo_rdata) -> !$isunknown(tl_o)) + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_tlul_adapter_vh.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_tlul_adapter_vh.sv new file mode 100644 index 0000000..a0bb465 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_tlul_adapter_vh.sv @@ -0,0 +1,149 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +`include "caliptra_prim_assert.sv" + +module caliptra_tlul_adapter_vh + import caliptra_tlul_pkg::*; + import caliptra_prim_mubi_pkg::mubi4_t; +#( + parameter int ADDR_WIDTH = TL_AW, + parameter int DATA_WIDTH = TL_DW, + parameter int MASK_WIDTH = DATA_WIDTH >> 3, + parameter int USER_WIDTH = 32, + parameter int ID_WIDTH = TL_AIW, + + parameter bit [ADDR_WIDTH-1:0] VH_REGISTER_ADDRESS_OFFSET = 32'h0000_0100, + + parameter bit EnableDataIntgGen = 1, + parameter bit EnableRspDataIntgCheck = 1 +) ( + input clk_i, + input rst_ni, + + output tl_h2d_t tl_o, + input tl_d2h_t tl_i, + + // Valid-Hold device interface (VH to TLUL). + input logic dv_i, + output logic hld_o, + input logic [ADDR_WIDTH-1:0] addr_i, + input logic write_i, + input logic [DATA_WIDTH-1:0] wdata_i, + input logic [MASK_WIDTH-1:0] wstrb_i, + input logic [2:0] size_i, + output logic [DATA_WIDTH-1:0] rdata_o, + output logic error_o, + input logic last_i, + input logic [USER_WIDTH-1:0] user_i, + input logic [ID_WIDTH-1:0] id_i, + + // Valid-Hold host interface (VH to internal registers). The signals from the VH device interface + // are routed to the VH host interface for every internal access, see the `internal_access` signal. + output logic int_dv_o, + input logic int_hld_i, + output logic [ADDR_WIDTH-1:0] int_addr_o, + output logic int_write_o, + output logic [DATA_WIDTH-1:0] int_wdata_o, + output logic [MASK_WIDTH-1:0] int_wstrb_o, + output logic [2:0] int_size_o, + input logic [DATA_WIDTH-1:0] int_rdata_i, + input logic int_error_i, + output logic int_last_o, + output logic [USER_WIDTH-1:0] int_user_o, + output logic [ID_WIDTH-1:0] int_id_o +); + + // The adapter distinguishes between two types of VH accesses: those going to an internal register + // file and those targeting OpenTitan registers, with the latter ones being translated into TLUL + // requests while the other requests are relayed to the internal register file. + logic internal_access; + assign internal_access = addr_i >= VH_REGISTER_ADDRESS_OFFSET; + + // Differentiate between two levels of acknowledgements: + // - `req_ack`: A host-to-device request is acknowledged by the device, meaning that the response + // is pending. + // - `resp_ack`: The device-to-host response is acknowledged. + logic pending_d, pending_q; + logic req_ack, resp_ack; + + assign req_ack = dv_i & tl_i.a_ready & tl_o.a_valid & ~internal_access; + assign resp_ack = dv_i & tl_o.d_ready & tl_i.d_valid & ~internal_access; + + always_comb begin + pending_d = pending_q; + if (req_ack) begin + pending_d = 1'b1; + end else if (resp_ack) begin + pending_d = 1'b0; + end + end + + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + pending_q <= 1'b0; + end else begin + pending_q <= pending_d; + end + end + + // Only make a new request (through `a_valid`) to the device when none are pending. If the + // integrity checks are enabled, the `a_user` fields will be set by the corresponding module (see + // `caliptra_tlul_cmd_intg_gen`). + caliptra_tlul_pkg::tl_h2d_t tl_o_pre; + assign tl_o_pre = '{ + a_valid: dv_i & ~pending_q & ~internal_access, + a_opcode: ~write_i ? Get : (&wstrb_i ? PutFullData : PutPartialData), + a_size: TL_SZW'(size_i), + a_mask: wstrb_i, + a_source: id_i, + a_address: addr_i, + a_data: wdata_i, + a_user: '{default: '0, instr_type: caliptra_prim_mubi_pkg::MuBi4False}, + d_ready: 1'b1, + // unused + a_param: 3'h0 + }; + + // Accesses to device registers are acknowledged with the TLUL d-channel handshake. + assign hld_o = !pending_q && internal_access && !int_hld_i ? 1'b0 : + pending_q && tl_o.d_ready && tl_i.d_valid ? 1'b0 : 1'b1; + + assign rdata_o = internal_access ? int_rdata_i : tl_i.d_data; + + // Route signals to the VH host interface. + assign int_dv_o = dv_i & internal_access; + assign int_addr_o = addr_i; + assign int_write_o = write_i; + assign int_wdata_o = wdata_i; + assign int_wstrb_o = wstrb_i; + assign int_size_o = size_i; + assign int_last_o = last_i; + assign int_user_o = user_i; + assign int_id_o = id_i; + + caliptra_tlul_cmd_intg_gen #( + .EnableDataIntgGen (EnableDataIntgGen) + ) u_cmd_intg_gen ( + .tl_i ( tl_o_pre ), + .tl_o ( tl_o ) + ); + + logic intg_err_chk; + caliptra_tlul_rsp_intg_chk #( + .EnableRspDataIntgCheck(EnableRspDataIntgCheck) + ) u_rsp_chk ( + .tl_i ( tl_i ), + .err_o ( intg_err_chk ) + ); + + assign error_o = tl_i.d_error | int_error_i | intg_err_chk; + + // Make sure the VH parameters are compatible with TLUL datapath widths. + `CALIPTRA_ASSERT_INIT(TlInvalidAddrWidth_A, ADDR_WIDTH == TL_AW) + `CALIPTRA_ASSERT_INIT(TlInvalidDataWidth_A, DATA_WIDTH == TL_DW) + `CALIPTRA_ASSERT_INIT(TlInvalidMaskWidth_A, MASK_WIDTH == TL_DBW) + `CALIPTRA_ASSERT_INIT(TlInvalidUserWidth_A, ID_WIDTH == TL_AIW) + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_tlul_cmd_intg_chk.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_tlul_cmd_intg_chk.sv new file mode 100644 index 0000000..df95c7e --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_tlul_cmd_intg_chk.sv @@ -0,0 +1,53 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +`include "caliptra_prim_assert.sv" + +/** + * Tile-Link UL command integrity check + */ + +module caliptra_tlul_cmd_intg_chk import caliptra_tlul_pkg::*; ( + // TL-UL interface + input tl_h2d_t tl_i, + + // error output + output logic err_o +); + + logic [1:0] err; + logic data_err; + tl_h2d_cmd_intg_t cmd; + assign cmd = extract_h2d_cmd_intg(tl_i); + + caliptra_prim_secded_inv_64_57_dec u_chk ( + .data_i({tl_i.a_user.cmd_intg, H2DCmdMaxWidth'(cmd)}), + .data_o(), + .syndrome_o(), + .err_o(err) + ); + + caliptra_tlul_data_integ_dec u_caliptra_tlul_data_integ_dec ( + .data_intg_i({tl_i.a_user.data_intg, DataMaxWidth'(tl_i.a_data)}), + .data_err_o(data_err) + ); + + // error output is transactional, it is up to the instantiating module + // to determine if a permanent latch is feasible + // [LOWRISC] err and data_err is unknown when a_valid is low, so we can't cover + // the condition coverage - (|err | (|data_err)) == 0/1, when a_valid = 0, which is + // fine as driving unknown is better. `err_o` is used as a condition in other places, + // which needs to be covered with 0 and 1, so it's OK to disable the entire coverage. + //VCS coverage off + // pragma coverage off + assign err_o = tl_i.a_valid & (|err | (|data_err)); + //VCS coverage on + // pragma coverage on + + logic unused_tl; + assign unused_tl = |tl_i; + + `CALIPTRA_ASSERT_INIT(PayLoadWidthCheck, $bits(tl_h2d_cmd_intg_t) <= H2DCmdMaxWidth) + +endmodule // caliptra_tlul_payload_chk diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_tlul_cmd_intg_gen.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_tlul_cmd_intg_gen.sv new file mode 100644 index 0000000..6cad6a1 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_tlul_cmd_intg_gen.sv @@ -0,0 +1,58 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +`include "caliptra_prim_assert.sv" + +/** + * Tile-Link UL command integrity generator + */ + +module caliptra_tlul_cmd_intg_gen import caliptra_tlul_pkg::*; #( + parameter bit EnableDataIntgGen = 1'b1 +) ( + // TL-UL interface + input tl_h2d_t tl_i, + output tl_h2d_t tl_o +); + + tl_h2d_cmd_intg_t cmd; + assign cmd = extract_h2d_cmd_intg(tl_i); + logic [H2DCmdMaxWidth-1:0] unused_cmd_payload; + + logic [H2DCmdIntgWidth-1:0] cmd_intg; + caliptra_prim_secded_inv_64_57_enc u_cmd_gen ( + .data_i(H2DCmdMaxWidth'(cmd)), + .data_o({cmd_intg, unused_cmd_payload}) + ); + + logic [TL_DW-1:0] data_final; + logic [DataIntgWidth-1:0] data_intg; + + if (EnableDataIntgGen) begin : gen_data_intg + assign data_final = tl_i.a_data; + + logic [DataMaxWidth-1:0] unused_data; + caliptra_prim_secded_inv_39_32_enc u_data_gen ( + .data_i(DataMaxWidth'(data_final)), + .data_o({data_intg, unused_data}) + ); + end else begin : gen_passthrough_data_intg + assign data_final = tl_i.a_data; + assign data_intg = tl_i.a_user.data_intg; + end + + always_comb begin + tl_o = tl_i; + tl_o.a_data = data_final; + tl_o.a_user.cmd_intg = cmd_intg; + tl_o.a_user.data_intg = data_intg; + end + + + logic unused_tl; + assign unused_tl = ^tl_i; + + `CALIPTRA_ASSERT_INIT(PayMaxWidthCheck_A, $bits(tl_h2d_cmd_intg_t) <= H2DCmdMaxWidth) + +endmodule : caliptra_tlul_cmd_intg_gen diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_tlul_data_integ_dec.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_tlul_data_integ_dec.sv new file mode 100644 index 0000000..76fb936 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_tlul_data_integ_dec.sv @@ -0,0 +1,27 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +`include "caliptra_prim_assert.sv" + +/** + * Data integrity decoder for bus integrity scheme + */ + +module caliptra_tlul_data_integ_dec import caliptra_tlul_pkg::*; ( + // TL-UL interface + input [DataMaxWidth+DataIntgWidth-1:0] data_intg_i, + output logic data_err_o +); + + logic [1:0] data_err; + caliptra_prim_secded_inv_39_32_dec u_data_chk ( + .data_i(data_intg_i), + .data_o(), + .syndrome_o(), + .err_o(data_err) + ); + + assign data_err_o = |data_err; + +endmodule : caliptra_tlul_data_integ_dec diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_tlul_data_integ_enc.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_tlul_data_integ_enc.sv new file mode 100644 index 0000000..de45bb5 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_tlul_data_integ_enc.sv @@ -0,0 +1,22 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +`include "caliptra_prim_assert.sv" + +/** + * Data integrity encoder for bus integrity scheme + */ + +module caliptra_tlul_data_integ_enc import caliptra_tlul_pkg::*; ( + // TL-UL interface + input [DataMaxWidth-1:0] data_i, + output logic [DataMaxWidth+DataIntgWidth-1:0] data_intg_o +); + + caliptra_prim_secded_inv_39_32_enc u_data_gen ( + .data_i, + .data_o(data_intg_o) + ); + +endmodule : caliptra_tlul_data_integ_enc diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_tlul_err.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_tlul_err.sv new file mode 100644 index 0000000..2c94ea4 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_tlul_err.sv @@ -0,0 +1,103 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + + +`include "caliptra_prim_assert.sv" + +module caliptra_tlul_err import caliptra_tlul_pkg::*; ( + input clk_i, + input rst_ni, + + input tl_h2d_t tl_i, + + output logic err_o +); + + localparam int IW = $bits(tl_i.a_source); + localparam int SZW = $bits(tl_i.a_size); + localparam int DW = $bits(tl_i.a_data); + localparam int MW = $bits(tl_i.a_mask); + localparam int SubAW = $clog2(DW/8); + + logic opcode_allowed, a_config_allowed; + + logic op_full, op_partial, op_get; + assign op_full = (tl_i.a_opcode == PutFullData); + assign op_partial = (tl_i.a_opcode == PutPartialData); + assign op_get = (tl_i.a_opcode == Get); + + // An instruction type transaction cannot be write + logic instr_wr_err; + assign instr_wr_err = caliptra_prim_mubi_pkg::mubi4_test_true_strict(tl_i.a_user.instr_type) & + (op_full | op_partial); + + logic instr_type_err; + assign instr_type_err = caliptra_prim_mubi_pkg::mubi4_test_invalid(tl_i.a_user.instr_type); + + // Anything that doesn't fall into the permitted category, it raises an error + assign err_o = ~(opcode_allowed & a_config_allowed) | instr_wr_err | instr_type_err; + + // opcode check + assign opcode_allowed = (tl_i.a_opcode == PutFullData) + | (tl_i.a_opcode == PutPartialData) + | (tl_i.a_opcode == Get); + + // a channel configuration check + logic addr_sz_chk; // address and size alignment check + logic mask_chk; // inactive lane a_mask check + logic fulldata_chk; // PutFullData should have size match to mask + + localparam bit [MW-1:0] MaskOne = 1; + logic [MW-1:0] mask; + + assign mask = MaskOne << tl_i.a_address[SubAW-1:0]; + + always_comb begin + addr_sz_chk = 1'b0; + mask_chk = 1'b0; + fulldata_chk = 1'b0; // Only valid when opcode is PutFullData + + if (tl_i.a_valid) begin + unique case (tl_i.a_size) + 'h0: begin // 1 Byte + addr_sz_chk = 1'b1; + mask_chk = ~|(tl_i.a_mask & ~mask); + fulldata_chk = |(tl_i.a_mask & mask); + end + + 'h1: begin // 2 Byte + addr_sz_chk = ~tl_i.a_address[0]; + // check inactive lanes if lower 2B, check a_mask[3:2], if uppwer 2B, a_mask[1:0] + mask_chk = (tl_i.a_address[1]) ? ~|(tl_i.a_mask & 4'b0011) + : ~|(tl_i.a_mask & 4'b1100); + fulldata_chk = (tl_i.a_address[1]) ? &tl_i.a_mask[3:2] : &tl_i.a_mask[1:0] ; + end + + 'h2: begin // 4 Byte + addr_sz_chk = ~|tl_i.a_address[SubAW-1:0]; + mask_chk = 1'b1; + fulldata_chk = &tl_i.a_mask[3:0]; + end + + default: begin // else + addr_sz_chk = 1'b0; + mask_chk = 1'b0; + fulldata_chk = 1'b0; + end + endcase + end else begin + addr_sz_chk = 1'b0; + mask_chk = 1'b0; + fulldata_chk = 1'b0; + end + end + + assign a_config_allowed = addr_sz_chk + & mask_chk + & (op_get | op_partial | fulldata_chk) ; + + // Only 32 bit data width for current caliptra_tlul_err + `CALIPTRA_ASSERT_INIT(dataWidthOnly32_A, DW == 32) + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_tlul_err_resp.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_tlul_err_resp.sv new file mode 100644 index 0000000..635f3cb --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_tlul_err_resp.sv @@ -0,0 +1,67 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// TL-UL error responder module, used by tlul_socket_1n to help response +// to requests to no correct address space. Responses are always one cycle +// after request with no stalling unless response is stuck on the way out. + +module caliptra_tlul_err_resp ( + input clk_i, + input rst_ni, + input caliptra_tlul_pkg::tl_h2d_t tl_h_i, + output caliptra_tlul_pkg::tl_d2h_t tl_h_o +); + import caliptra_tlul_pkg::*; + import caliptra_prim_mubi_pkg::*; + + tl_a_op_e err_opcode; + logic [$bits(tl_h_i.a_source)-1:0] err_source; + logic [$bits(tl_h_i.a_size)-1:0] err_size; + logic err_rsp_pending; + mubi4_t err_instr_type; + caliptra_tlul_pkg::tl_d2h_t tl_h_o_int; + + caliptra_tlul_rsp_intg_gen #( + .EnableRspIntgGen(1), + .EnableDataIntgGen(1) + ) u_intg_gen ( + .tl_i(tl_h_o_int), + .tl_o(tl_h_o) + ); + + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + err_rsp_pending <= 1'b0; + err_source <= {TL_AIW{1'b0}}; + err_opcode <= Get; + err_size <= '0; + err_instr_type <= MuBi4False; + end else if (err_rsp_pending && tl_h_i.d_ready) begin + err_rsp_pending <= 1'b0; + end else if (tl_h_i.a_valid && tl_h_o_int.a_ready) begin + err_rsp_pending <= 1'b1; + err_source <= tl_h_i.a_source; + err_opcode <= tl_h_i.a_opcode; + err_size <= tl_h_i.a_size; + err_instr_type <= tl_h_i.a_user.instr_type; + end + end + + assign tl_h_o_int.a_ready = ~err_rsp_pending; + assign tl_h_o_int.d_valid = err_rsp_pending; + assign tl_h_o_int.d_data = (mubi4_test_true_strict(err_instr_type)) ? DataWhenInstrError : + DataWhenError; + assign tl_h_o_int.d_source = err_source; + assign tl_h_o_int.d_sink = '0; + assign tl_h_o_int.d_param = '0; + assign tl_h_o_int.d_size = err_size; + assign tl_h_o_int.d_opcode = (err_opcode == Get) ? AccessAckData : AccessAck; + assign tl_h_o_int.d_user = '0; + assign tl_h_o_int.d_error = 1'b1; + + // Waive unused bits of tl_h_i + logic unused_tl_h; + assign unused_tl_h = ^tl_h_i; + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_tlul_fifo_sync.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_tlul_fifo_sync.sv new file mode 100644 index 0000000..54a4dc9 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_tlul_fifo_sync.sv @@ -0,0 +1,99 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// TL-UL fifo, used to add elasticity or an asynchronous clock crossing +// to an TL-UL bus. This instantiates two FIFOs, one for the request side, +// and one for the response side. + +module caliptra_tlul_fifo_sync + import caliptra_tlul_pkg::*; + #( + parameter bit ReqPass = 1'b1, + parameter bit RspPass = 1'b1, + parameter int unsigned ReqDepth = 2, + parameter int unsigned RspDepth = 2, + parameter int unsigned SpareReqW = 1, + parameter int unsigned SpareRspW = 1 +) ( + input clk_i, + input rst_ni, + input caliptra_tlul_pkg::tl_h2d_t tl_h_i, + output caliptra_tlul_pkg::tl_d2h_t tl_h_o, + output caliptra_tlul_pkg::tl_h2d_t tl_d_o, + input caliptra_tlul_pkg::tl_d2h_t tl_d_i, + input [SpareReqW-1:0] spare_req_i, + output [SpareReqW-1:0] spare_req_o, + input [SpareRspW-1:0] spare_rsp_i, + output [SpareRspW-1:0] spare_rsp_o +); + + // Put everything on the request side into one FIFO + localparam int unsigned REQFIFO_WIDTH = $bits(caliptra_tlul_pkg::tl_h2d_t) -2 + SpareReqW; + + caliptra_prim_fifo_sync #(.Width(REQFIFO_WIDTH), .Pass(ReqPass), .Depth(ReqDepth)) reqfifo ( + .clk_i, + .rst_ni, + .clr_i (1'b0 ), + .wvalid_i (tl_h_i.a_valid), + .wready_o (tl_h_o.a_ready), + .wdata_i ({tl_h_i.a_opcode , + tl_h_i.a_param , + tl_h_i.a_size , + tl_h_i.a_source , + tl_h_i.a_address, + tl_h_i.a_mask , + tl_h_i.a_data , + tl_h_i.a_user , + spare_req_i}), + .rvalid_o (tl_d_o.a_valid), + .rready_i (tl_d_i.a_ready), + .rdata_o ({tl_d_o.a_opcode , + tl_d_o.a_param , + tl_d_o.a_size , + tl_d_o.a_source , + tl_d_o.a_address, + tl_d_o.a_mask , + tl_d_o.a_data , + tl_d_o.a_user , + spare_req_o}), + .full_o (), + .depth_o (), + .err_o ()); + + // Put everything on the response side into the other FIFO + + localparam int unsigned RSPFIFO_WIDTH = $bits(caliptra_tlul_pkg::tl_d2h_t) -2 + SpareRspW; + + caliptra_prim_fifo_sync #(.Width(RSPFIFO_WIDTH), .Pass(RspPass), .Depth(RspDepth)) rspfifo ( + .clk_i, + .rst_ni, + .clr_i (1'b0 ), + .wvalid_i (tl_d_i.d_valid), + .wready_o (tl_d_o.d_ready), + .wdata_i ({tl_d_i.d_opcode, + tl_d_i.d_param , + tl_d_i.d_size , + tl_d_i.d_source, + tl_d_i.d_sink , + (tl_d_i.d_opcode == caliptra_tlul_pkg::AccessAckData) ? tl_d_i.d_data : + {TL_DW{1'b0}} , + tl_d_i.d_user , + tl_d_i.d_error , + spare_rsp_i}), + .rvalid_o (tl_h_o.d_valid), + .rready_i (tl_h_i.d_ready), + .rdata_o ({tl_h_o.d_opcode, + tl_h_o.d_param , + tl_h_o.d_size , + tl_h_o.d_source, + tl_h_o.d_sink , + tl_h_o.d_data , + tl_h_o.d_user , + tl_h_o.d_error , + spare_rsp_o}), + .full_o (), + .depth_o (), + .err_o ()); + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_tlul_pkg.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_tlul_pkg.sv new file mode 100644 index 0000000..d6ff392 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_tlul_pkg.sv @@ -0,0 +1,218 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// + +package caliptra_tlul_pkg; + + localparam int TL_AW=32; + localparam int TL_DW=32; // = TL_DBW * 8; TL_DBW must be a power-of-two + localparam int TL_AIW=8; // a_source, d_source + localparam int TL_DIW=1; // d_sink + localparam int TL_AUW=23; // a_user + localparam int TL_DUW=14; // d_user + localparam int TL_DBW=(TL_DW>>3); + localparam int TL_SZW=$clog2($clog2(TL_DBW)+1); + + // this can be either PPC or BINTREE + // there is no functional difference, but timing and area behavior is different + // between the two instances. PPC can result in smaller implementations when timing + // is not critical, whereas BINTREE is favorable when timing pressure is high (but this + // may also result in a larger implementation). on FPGA targets, BINTREE is favorable + // both in terms of area and timing. + parameter ArbiterImpl = "PPC"; + + typedef enum logic [2:0] { + PutFullData = 3'h 0, + PutPartialData = 3'h 1, + Get = 3'h 4 + } tl_a_op_e; + + typedef enum logic [2:0] { + AccessAck = 3'h 0, + AccessAckData = 3'h 1 + } tl_d_op_e; + + parameter int H2DCmdMaxWidth = 57; + parameter int H2DCmdIntgWidth = 7; + parameter int H2DCmdFullWidth = H2DCmdMaxWidth + H2DCmdIntgWidth; + parameter int D2HRspMaxWidth = 57; + parameter int D2HRspIntgWidth = 7; + parameter int D2HRspFullWidth = D2HRspMaxWidth + D2HRspIntgWidth; + parameter int DataMaxWidth = 32; + parameter int DataIntgWidth = 7; + parameter int DataFullWidth = DataMaxWidth + DataIntgWidth; + parameter int RsvdWidth = TL_AUW - caliptra_prim_mubi_pkg::MuBi4Width - + H2DCmdIntgWidth - DataIntgWidth; + + // Data that is returned upon an a TL-UL error belonging to an instruction fetch. + // Note that this data will be returned with the correct bus integrity value. + parameter logic [TL_DW-1:0] DataWhenInstrError = '0; + // Data that is returned upon an a TL-UL error not belonging to an instruction fetch. + // Note that this data will be returned with the correct bus integrity value. + parameter logic [TL_DW-1:0] DataWhenError = {TL_DW{1'b1}}; + + typedef struct packed { + logic [RsvdWidth-1:0] rsvd; + caliptra_prim_mubi_pkg::mubi4_t instr_type; + logic [H2DCmdIntgWidth-1:0] cmd_intg; + logic [DataIntgWidth-1:0] data_intg; + } tl_a_user_t; + + parameter tl_a_user_t TL_A_USER_DEFAULT = '{ + rsvd: '0, + instr_type: caliptra_prim_mubi_pkg::MuBi4False, + cmd_intg: {H2DCmdIntgWidth{1'b1}}, + data_intg: {DataIntgWidth{1'b1}} + }; + + typedef struct packed { + caliptra_prim_mubi_pkg::mubi4_t instr_type; + logic [TL_AW-1:0] addr; + tl_a_op_e opcode; + logic [TL_DBW-1:0] mask; + } tl_h2d_cmd_intg_t; + + typedef struct packed { + logic a_valid; + tl_a_op_e a_opcode; + logic [2:0] a_param; + logic [TL_SZW-1:0] a_size; + logic [TL_AIW-1:0] a_source; + logic [TL_AW-1:0] a_address; + logic [TL_DBW-1:0] a_mask; + logic [TL_DW-1:0] a_data; + tl_a_user_t a_user; + + logic d_ready; + } tl_h2d_t; + + // The choice of all 1's as the blanked value is deliberate. + // It is assumed that most security features of the design are opt-in instead + // of opt-out. + // Given the opt-in nature, if a 0 were to propagate, the feature would be turned + // off. Whereas if a 1 were to propagate, it would either stay on or be turned on. + // There is however no perfect value for this purpose. + localparam logic [TL_DW-1:0] BlankedAData = {TL_DW{1'b1}}; + + localparam tl_h2d_t TL_H2D_DEFAULT = '{ + d_ready: 1'b1, + a_opcode: tl_a_op_e'('0), + a_user: TL_A_USER_DEFAULT, + a_data: BlankedAData, + default: '0 + }; + + typedef struct packed { + logic [D2HRspIntgWidth-1:0] rsp_intg; + logic [DataIntgWidth-1:0] data_intg; + } tl_d_user_t; + + parameter tl_d_user_t TL_D_USER_DEFAULT = '{ + rsp_intg: {D2HRspIntgWidth{1'b1}}, + data_intg: {DataIntgWidth{1'b1}} + }; + + typedef struct packed { + logic d_valid; + tl_d_op_e d_opcode; + logic [2:0] d_param; + logic [TL_SZW-1:0] d_size; // Bouncing back a_size + logic [TL_AIW-1:0] d_source; + logic [TL_DIW-1:0] d_sink; + logic [TL_DW-1:0] d_data; + tl_d_user_t d_user; + logic d_error; + + logic a_ready; + + } tl_d2h_t; + + typedef struct packed { + tl_d_op_e opcode; + logic [TL_SZW-1:0] size; + // Temporarily removed because source changes throughout the fabric + // and thus cannot be used for end-to-end checking. + // A different PR will propose a work-around (a hoaky one) to see if + // it gets the job done. + //logic [TL_AIW-1:0] source; + logic error; + } tl_d2h_rsp_intg_t; + + localparam tl_d2h_t TL_D2H_DEFAULT = '{ + a_ready: 1'b1, + d_opcode: tl_d_op_e'('0), + d_user: TL_D_USER_DEFAULT, + default: '0 + }; + + // Check user for unsupported values + function automatic logic tl_a_user_chk(tl_a_user_t user); + logic malformed_err; + logic unused_user; + unused_user = |user; + malformed_err = caliptra_prim_mubi_pkg::mubi4_test_invalid(user.instr_type); + return malformed_err; + endfunction // tl_a_user_chk + + // extract variables used for command checking + function automatic tl_h2d_cmd_intg_t extract_h2d_cmd_intg(tl_h2d_t tl); + tl_h2d_cmd_intg_t payload; + logic unused_tlul; + unused_tlul = ^tl; + payload.addr = tl.a_address; + payload.opcode = tl.a_opcode; + payload.mask = tl.a_mask; + payload.instr_type = tl.a_user.instr_type; + return payload; + endfunction // extract_h2d_payload + + // extract variables used for response checking + function automatic tl_d2h_rsp_intg_t extract_d2h_rsp_intg(tl_d2h_t tl); + tl_d2h_rsp_intg_t payload; + logic unused_tlul; + unused_tlul = ^tl; + payload.opcode = tl.d_opcode; + payload.size = tl.d_size; + //payload.source = tl.d_source; + payload.error = tl.d_error; + return payload; + endfunction // extract_d2h_rsp_intg + + // calculate ecc for command checking + function automatic logic [H2DCmdIntgWidth-1:0] get_cmd_intg(tl_h2d_t tl); + logic [H2DCmdIntgWidth-1:0] cmd_intg; + logic [H2DCmdMaxWidth-1:0] unused_cmd_payload; + tl_h2d_cmd_intg_t cmd; + cmd = extract_h2d_cmd_intg(tl); + {cmd_intg, unused_cmd_payload} = + caliptra_prim_secded_pkg::caliptra_prim_secded_inv_64_57_enc(H2DCmdMaxWidth'(cmd)); + return cmd_intg; + endfunction // get_cmd_intg + + // calculate ecc for data checking + function automatic logic [DataIntgWidth-1:0] get_data_intg(logic [TL_DW-1:0] data); + logic [DataIntgWidth-1:0] data_intg; + logic [TL_DW-1:0] unused_data; + logic [DataIntgWidth + TL_DW - 1 : 0] enc_data; + enc_data = caliptra_prim_secded_pkg::caliptra_prim_secded_inv_39_32_enc(data); + data_intg = enc_data[DataIntgWidth + TL_DW - 1 : TL_DW]; + unused_data = enc_data[TL_DW - 1 : 0]; + return data_intg; + endfunction // get_data_intg + + // return inverted integrity for command payload + function automatic logic [H2DCmdIntgWidth-1:0] get_bad_cmd_intg(tl_h2d_t tl); + logic [H2DCmdIntgWidth-1:0] cmd_intg; + cmd_intg = get_cmd_intg(tl); + return ~cmd_intg; + endfunction // get_bad_cmd_intg + + // return inverted integrity for data payload + function automatic logic [H2DCmdIntgWidth-1:0] get_bad_data_intg(logic [TL_DW-1:0] data); + logic [H2DCmdIntgWidth-1:0] data_intg; + data_intg = get_data_intg(data); + return ~data_intg; + endfunction // get_bad_data_intg + +endpackage diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_tlul_rsp_intg_chk.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_tlul_rsp_intg_chk.sv new file mode 100644 index 0000000..ac7d9f6 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_tlul_rsp_intg_chk.sv @@ -0,0 +1,54 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +`include "caliptra_prim_assert.sv" + +/** + * Tile-Link UL response integrity check + */ + +module caliptra_tlul_rsp_intg_chk import caliptra_tlul_pkg::*; #( + parameter bit EnableRspDataIntgCheck = 0 +) ( + // TL-UL interface + input tl_d2h_t tl_i, + + // error output + output logic err_o +); + + logic [1:0] rsp_err; + tl_d2h_rsp_intg_t rsp; + assign rsp = extract_d2h_rsp_intg(tl_i); + + caliptra_prim_secded_inv_64_57_dec u_chk ( + .data_i({tl_i.d_user.rsp_intg, D2HRspMaxWidth'(rsp)}), + .data_o(), + .syndrome_o(), + .err_o(rsp_err) + ); + + logic rsp_data_err; + if (EnableRspDataIntgCheck) begin : gen_rsp_data_intg_check + caliptra_tlul_data_integ_dec u_caliptra_tlul_data_integ_dec ( + .data_intg_i({tl_i.d_user.data_intg, DataMaxWidth'(tl_i.d_data)}), + .data_err_o(rsp_data_err) + ); + end else begin : gen_no_rsp_data_intg_check + assign rsp_data_err = 1'b0; + end + + // error is not permanently latched as rsp_intg_chk is typically + // used near the host. + // if the error is permanent, it would imply the host could forever + // receive bus errors and lose all ability to debug. + // It should be up to the host to determine the permanence of this error. + assign err_o = tl_i.d_valid & (|rsp_err | rsp_data_err); + + logic unused_tl; + assign unused_tl = |tl_i; + + `CALIPTRA_ASSERT_INIT(PayLoadWidthCheck, $bits(tl_d2h_rsp_intg_t) <= D2HRspMaxWidth) + +endmodule // caliptra_tlul_rsp_intg_chk diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_tlul_rsp_intg_gen.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_tlul_rsp_intg_gen.sv new file mode 100644 index 0000000..40a3c29 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_tlul_rsp_intg_gen.sv @@ -0,0 +1,59 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +`include "caliptra_prim_assert.sv" + +/** + * Tile-Link UL response integrity generator + */ + +module caliptra_tlul_rsp_intg_gen import caliptra_tlul_pkg::*; #( + parameter bit EnableRspIntgGen = 1'b1, + parameter bit EnableDataIntgGen = 1'b1 +) ( + // TL-UL interface + input tl_d2h_t tl_i, + output tl_d2h_t tl_o +); + + logic [D2HRspIntgWidth-1:0] rsp_intg; + if (EnableRspIntgGen) begin : gen_rsp_intg + tl_d2h_rsp_intg_t rsp; + logic [D2HRspMaxWidth-1:0] unused_payload; + + assign rsp = extract_d2h_rsp_intg(tl_i); + + caliptra_prim_secded_inv_64_57_enc u_rsp_gen ( + .data_i(D2HRspMaxWidth'(rsp)), + .data_o({rsp_intg, unused_payload}) + ); + end else begin : gen_passthrough_rsp_intg + assign rsp_intg = tl_i.d_user.rsp_intg; + end + + logic [DataIntgWidth-1:0] data_intg; + if (EnableDataIntgGen) begin : gen_data_intg + logic [DataMaxWidth-1:0] unused_data; + caliptra_tlul_data_integ_enc u_caliptra_tlul_data_integ_enc ( + .data_i(DataMaxWidth'(tl_i.d_data)), + .data_intg_o({data_intg, unused_data}) + ); + end else begin : gen_passthrough_data_intg + assign data_intg = tl_i.d_user.data_intg; + end + + always_comb begin + tl_o = tl_i; + tl_o.d_user.rsp_intg = rsp_intg; + tl_o.d_user.data_intg = data_intg; + end + + logic unused_tl; + assign unused_tl = ^tl_i; + + + `CALIPTRA_ASSERT_INIT(PayLoadWidthCheck, $bits(tl_d2h_rsp_intg_t) <= D2HRspMaxWidth) + `CALIPTRA_ASSERT_INIT(DataWidthCheck_A, $bits(tl_i.d_data) <= DataMaxWidth) + +endmodule // tlul_rsp_intg_gen diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_tlul_socket_1n.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_tlul_socket_1n.sv new file mode 100644 index 0000000..6388ffd --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_tlul_socket_1n.sv @@ -0,0 +1,255 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// TL-UL socket 1:N module +// +// configuration settings +// device_count: 4 +// +// Verilog parameters +// HReqPass: if 1 then host requests can pass through on empty fifo, +// default 1 +// HRspPass: if 1 then host responses can pass through on empty fifo, +// default 1 +// DReqPass: (one per device_count) if 1 then device i requests can +// pass through on empty fifo, default 1 +// DRspPass: (one per device_count) if 1 then device i responses can +// pass through on empty fifo, default 1 +// HReqDepth: Depth of host request FIFO, default 2 +// HRspDepth: Depth of host response FIFO, default 2 +// DReqDepth: (one per device_count) Depth of device i request FIFO, +// default 2 +// DRspDepth: (one per device_count) Depth of device i response FIFO, +// default 2 +// ExplicitErrs: This module always returns a request error if dev_select_i +// is greater than N-1. If ExplicitErrs is set then the width +// of the dev_select_i signal will be chosen to make sure that +// this is possible. This only makes a difference if N is a +// power of 2. +// +// Requests must stall to one device until all responses from other devices +// have returned. Need to keep a counter of all outstanding requests and +// wait until that counter is zero before switching devices. +// +// This module will return a request error if the input value of 'dev_select_i' +// is not within the range 0..N-1. Thus the instantiator of the socket +// can indicate error by any illegal value of dev_select_i. 4'b1111 is +// recommended for visibility +// +// The maximum value of N is 15 + +`include "caliptra_prim_assert.sv" + +module caliptra_tlul_socket_1n #( + parameter int unsigned N = 4, + parameter bit HReqPass = 1'b1, + parameter bit HRspPass = 1'b1, + parameter bit [N-1:0] DReqPass = {N{1'b1}}, + parameter bit [N-1:0] DRspPass = {N{1'b1}}, + parameter bit [3:0] HReqDepth = 4'h1, + parameter bit [3:0] HRspDepth = 4'h1, + parameter bit [N*4-1:0] DReqDepth = {N{4'h1}}, + parameter bit [N*4-1:0] DRspDepth = {N{4'h1}}, + parameter bit ExplicitErrs = 1'b1, + + // The width of dev_select_i. We must be able to select any of the N devices + // (i.e. values 0..N-1). If ExplicitErrs is set, we also need to be able to + // represent N. + localparam int unsigned NWD = $clog2(ExplicitErrs ? N+1 : N) +) ( + input clk_i, + input rst_ni, + input caliptra_tlul_pkg::tl_h2d_t tl_h_i, + output caliptra_tlul_pkg::tl_d2h_t tl_h_o, + output caliptra_tlul_pkg::tl_h2d_t tl_d_o [N], + input caliptra_tlul_pkg::tl_d2h_t tl_d_i [N], + input [NWD-1:0] dev_select_i +); + + `CALIPTRA_ASSERT_INIT(maxN, N < 32) + + // Since our steering is done after potential FIFOing, we need to + // shove our device select bits into spare bits of reqfifo + + // instantiate the host fifo, create intermediate bus 't' + + // FIFO'd version of device select + logic [NWD-1:0] dev_select_t; + + caliptra_tlul_pkg::tl_h2d_t tl_t_o; + caliptra_tlul_pkg::tl_d2h_t tl_t_i; + + caliptra_tlul_fifo_sync #( + .ReqPass(HReqPass), + .RspPass(HRspPass), + .ReqDepth(HReqDepth), + .RspDepth(HRspDepth), + .SpareReqW(NWD) + ) fifo_h ( + .clk_i, + .rst_ni, + .tl_h_i, + .tl_h_o, + .tl_d_o (tl_t_o), + .tl_d_i (tl_t_i), + .spare_req_i (dev_select_i), + .spare_req_o (dev_select_t), + .spare_rsp_i (1'b0), + .spare_rsp_o ()); + + + // We need to keep track of how many requests are outstanding, + // and to which device. New requests are compared to this and + // stall until that number is zero. + localparam int MaxOutstanding = 2**caliptra_tlul_pkg::TL_AIW; // Up to 256 ounstanding + localparam int OutstandingW = $clog2(MaxOutstanding+1); + logic [OutstandingW-1:0] num_req_outstanding; + logic [NWD-1:0] dev_select_outstanding; + logic hold_all_requests; + logic accept_t_req, accept_t_rsp; + + assign accept_t_req = tl_t_o.a_valid & tl_t_i.a_ready; + assign accept_t_rsp = tl_t_i.d_valid & tl_t_o.d_ready; + + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + num_req_outstanding <= '0; + dev_select_outstanding <= '0; + end else if (accept_t_req) begin + if (!accept_t_rsp) begin + num_req_outstanding <= num_req_outstanding + 1'b1; + end + dev_select_outstanding <= dev_select_t; + end else if (accept_t_rsp) begin + num_req_outstanding <= num_req_outstanding - 1'b1; + end + end + + `CALIPTRA_ASSERT(NotOverflowed_A, + accept_t_req && !accept_t_rsp -> num_req_outstanding <= MaxOutstanding) + + assign hold_all_requests = + (num_req_outstanding != '0) & + (dev_select_t != dev_select_outstanding); + + // Make N copies of 't' request side with modified reqvalid, call + // them 'u[0]' .. 'u[n-1]'. + + caliptra_tlul_pkg::tl_h2d_t tl_u_o [N+1]; + caliptra_tlul_pkg::tl_d2h_t tl_u_i [N+1]; + + // ensure that when a device is not selected, both command + // data integrity can never match + caliptra_tlul_pkg::tl_a_user_t blanked_auser; + assign blanked_auser = '{ + rsvd: tl_t_o.a_user.rsvd, + instr_type: tl_t_o.a_user.instr_type, + cmd_intg: caliptra_tlul_pkg::get_bad_cmd_intg(tl_t_o), + data_intg: caliptra_tlul_pkg::get_bad_data_intg(caliptra_tlul_pkg::BlankedAData) + }; + + // if a host is not selected, or if requests are held off, blank the bus + for (genvar i = 0 ; i < N ; i++) begin : gen_u_o + logic dev_select; + assign dev_select = dev_select_t == NWD'(i) & ~hold_all_requests; + + assign tl_u_o[i].a_valid = tl_t_o.a_valid & dev_select; + assign tl_u_o[i].a_opcode = tl_t_o.a_opcode; + assign tl_u_o[i].a_param = tl_t_o.a_param; + assign tl_u_o[i].a_size = tl_t_o.a_size; + assign tl_u_o[i].a_source = tl_t_o.a_source; + assign tl_u_o[i].a_address = tl_t_o.a_address; + assign tl_u_o[i].a_mask = tl_t_o.a_mask; + assign tl_u_o[i].a_data = dev_select ? + tl_t_o.a_data : + caliptra_tlul_pkg::BlankedAData; + assign tl_u_o[i].a_user = dev_select ? + tl_t_o.a_user : + blanked_auser; + + assign tl_u_o[i].d_ready = tl_t_o.d_ready; + end + + + caliptra_tlul_pkg::tl_d2h_t tl_t_p ; + + // for the returning reqready, only look at the device we're addressing + logic hfifo_reqready; + always_comb begin + hfifo_reqready = tl_u_i[N].a_ready; // default to error + for (int idx = 0 ; idx < N ; idx++) begin + //if (dev_select_outstanding == NWD'(idx)) hfifo_reqready = tl_u_i[idx].a_ready; + if (dev_select_t == NWD'(idx)) hfifo_reqready = tl_u_i[idx].a_ready; + end + if (hold_all_requests) hfifo_reqready = 1'b0; + end + // Adding a_valid as a qualifier. This prevents the a_ready from having unknown value + // when the address is unknown and the Host TL-UL FIFO is bypass mode. + assign tl_t_i.a_ready = tl_t_o.a_valid & hfifo_reqready; + + always_comb begin + tl_t_p = tl_u_i[N]; + for (int idx = 0 ; idx < N ; idx++) begin + if (dev_select_outstanding == NWD'(idx)) tl_t_p = tl_u_i[idx]; + end + end + assign tl_t_i.d_valid = tl_t_p.d_valid ; + assign tl_t_i.d_opcode = tl_t_p.d_opcode; + assign tl_t_i.d_param = tl_t_p.d_param ; + assign tl_t_i.d_size = tl_t_p.d_size ; + assign tl_t_i.d_source = tl_t_p.d_source; + assign tl_t_i.d_sink = tl_t_p.d_sink ; + assign tl_t_i.d_data = tl_t_p.d_data ; + assign tl_t_i.d_user = tl_t_p.d_user ; + assign tl_t_i.d_error = tl_t_p.d_error ; + + // Instantiate all the device FIFOs + for (genvar i = 0 ; i < N ; i++) begin : gen_dfifo + caliptra_tlul_fifo_sync #( + .ReqPass(DReqPass[i]), + .RspPass(DRspPass[i]), + .ReqDepth(DReqDepth[i*4+:4]), + .RspDepth(DRspDepth[i*4+:4]) + ) fifo_d ( + .clk_i, + .rst_ni, + .tl_h_i (tl_u_o[i]), + .tl_h_o (tl_u_i[i]), + .tl_d_o (tl_d_o[i]), + .tl_d_i (tl_d_i[i]), + .spare_req_i (1'b0), + .spare_req_o (), + .spare_rsp_i (1'b0), + .spare_rsp_o ()); + end + + // Instantiate the error responder. It's only needed if a value greater than + // N-1 is actually representable in NWD bits. + if ($clog2(N+1) <= NWD) begin : gen_err_resp + assign tl_u_o[N].d_ready = tl_t_o.d_ready; + assign tl_u_o[N].a_valid = tl_t_o.a_valid & + (dev_select_t >= NWD'(N)) & + ~hold_all_requests; + assign tl_u_o[N].a_opcode = tl_t_o.a_opcode; + assign tl_u_o[N].a_param = tl_t_o.a_param; + assign tl_u_o[N].a_size = tl_t_o.a_size; + assign tl_u_o[N].a_source = tl_t_o.a_source; + assign tl_u_o[N].a_address = tl_t_o.a_address; + assign tl_u_o[N].a_mask = tl_t_o.a_mask; + assign tl_u_o[N].a_data = tl_t_o.a_data; + assign tl_u_o[N].a_user = tl_t_o.a_user; + caliptra_tlul_err_resp err_resp ( + .clk_i, + .rst_ni, + .tl_h_i (tl_u_o[N]), + .tl_h_o (tl_u_i[N]) + ); + end else begin : gen_no_err_resp // block: gen_err_resp + assign tl_u_o[N] = '0; + assign tl_u_i[N] = '0; + logic unused_sig; + assign unused_sig = ^tl_u_o[N]; + end + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_tlul_sram_byte.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_tlul_sram_byte.sv new file mode 100644 index 0000000..c690378 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_tlul_sram_byte.sv @@ -0,0 +1,723 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +`include "caliptra_prim_assert.sv" + +/** + * Tile-Link UL adapter for SRAM-like devices + * + * This module handles byte writes for tlul integrity. + * When a byte write is received, the downstream data is read first + * to correctly create the integrity constant. + * + * A tlul transaction goes through this module. If required, a + * tlul read transaction is generated out first. If not required, the + * incoming tlul transaction is directly muxed out. + */ +module caliptra_tlul_sram_byte import caliptra_tlul_pkg::*; #( + parameter bit EnableIntg = 0, // Enable integrity handling at byte level, + parameter int Outstanding = 1, + parameter bit EnableReadback = 0 // Enable readback checks on all transactions must have + // EnableIntg == 1 to enable +) ( + input clk_i, + input rst_ni, + + input tl_h2d_t tl_i, + output tl_d2h_t tl_o, + + output tl_h2d_t tl_sram_o, + input tl_d2h_t tl_sram_i, + + // if incoming transaction already has an error, do not + // attempt to handle the byte-write access. Instead treat as + // feedthrough and allow the system to directly error back. + // The error indication is also fed through + input error_i, + output logic error_o, + output logic alert_o, + + output logic compound_txn_in_progress_o, + + input caliptra_prim_mubi_pkg::mubi4_t readback_en_i, + + input logic wr_collision_i, + input logic write_pending_i +); + + import caliptra_prim_mubi_pkg::mubi4_t; + import caliptra_prim_mubi_pkg::mubi4_test_true_loose; + import caliptra_prim_mubi_pkg::mubi4_test_false_strict; + import caliptra_prim_mubi_pkg::MuBi4True; + import caliptra_prim_mubi_pkg::MuBi4False; + import caliptra_prim_mubi_pkg::MuBi4Width; + + // Encoding generated with: + // $ ./util/design/sparse-fsm-encode.py -d 3 -m 11 -n 8 \ + // -s 718546395 --language=sv + // + // Hamming distance histogram: + // + // 0: -- + // 1: -- + // 2: -- + // 3: |||||||||||||| (25.45%) + // 4: |||||||||||||||||||| (36.36%) + // 5: |||||||||||| (21.82%) + // 6: ||||||| (12.73%) + // 7: || (3.64%) + // 8: -- + // + // Minimum Hamming distance: 3 + // Maximum Hamming distance: 7 + // Minimum Hamming weight: 1 + // Maximum Hamming weight: 6 + // + localparam int StateWidth = 8; + typedef enum logic [StateWidth-1:0] { + StPassThru = 8'b01111110, + StWaitRd = 8'b00000010, + StWriteCmd = 8'b11110001, + StWrReadBackInit = 8'b10011001, + StWrReadBack = 8'b00001111, + StWrReadBackDWait = 8'b00110000, + StRdReadBack = 8'b10101100, + StRdReadBackDWait = 8'b11000000, + StByteWrReadBackInit = 8'b01010111, + StByteWrReadBack = 8'b11100111, + StByteWrReadBackDWait = 8'b11111111 + } state_e; + + if (EnableIntg) begin : gen_integ_handling + // state and selection + logic stall_host; + logic wait_phase; + logic rd_phase; + logic rd_wait; + logic wr_phase; + logic rdback_phase; + logic rdback_phase_wrreadback; + logic rdback_wait; + state_e state_d, state_q; + + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + state_q <= StPassThru; + end else begin + state_q <= state_d; + end + end + + // transaction qualifying signals + logic a_ack; // upstream a channel acknowledgement + logic d_ack; // upstream d channel acknowledgement + logic sram_a_ack; // downstream a channel acknowledgement + logic sram_d_ack; // downstream d channel acknowledgement + logic wr_txn; + logic byte_wr_txn; + logic byte_req_ack; + logic hold_tx_data; + + localparam int unsigned PendingTxnCntW = caliptra_prim_util_pkg::vbits(Outstanding+1); + logic [PendingTxnCntW-1:0] pending_txn_cnt; + + // prim fifo for capturing info + typedef struct packed { + logic [2:0] a_param; + logic [TL_SZW-1:0] a_size; + logic [TL_AIW-1:0] a_source; + logic [TL_AW-1:0] a_address; + logic [TL_DBW-1:0] a_mask; + logic [TL_DW-1:0] a_data; + tl_a_user_t a_user; + } tl_txn_data_t; + + tl_txn_data_t held_data; + + assign a_ack = tl_i.a_valid & tl_o.a_ready; + assign d_ack = tl_o.d_valid & tl_i.d_ready; + assign sram_a_ack = tl_sram_o.a_valid & tl_sram_i.a_ready; + assign sram_d_ack = tl_sram_i.d_valid & tl_sram_o.d_ready; + assign wr_txn = (tl_i.a_opcode == PutFullData) | (tl_i.a_opcode == PutPartialData); + + assign byte_req_ack = byte_wr_txn & a_ack & ~error_i; + assign byte_wr_txn = tl_i.a_valid & ~&tl_i.a_mask & wr_txn; + + logic rdback_chk_ok; + mubi4_t rdback_check_q, rdback_check_d; + mubi4_t rdback_en_q, rdback_en_d; + logic [31:0] rdback_data_exp_q, rdback_data_exp_d; + logic [DataIntgWidth-1:0] rdback_data_exp_intg_q, rdback_data_exp_intg_d; + + if (EnableReadback) begin : gen_readback_logic + logic rdback_chk_ok_unbuf; + + assign rdback_chk_ok_unbuf = (rdback_data_exp_q == tl_sram_i.d_data); + + caliptra_prim_sec_anchor_buf #( + .Width(1) + ) u_rdback_chk_ok_buf ( + .in_i (rdback_chk_ok_unbuf), + .out_o(rdback_chk_ok) + ); + + caliptra_prim_flop #( + .Width(MuBi4Width), + .ResetValue(MuBi4Width'(MuBi4False)) + ) u_rdback_check_flop ( + .clk_i, + .rst_ni, + + .d_i(MuBi4Width'(rdback_check_d)), + .q_o({rdback_check_q}) + ); + + caliptra_prim_flop #( + .Width(MuBi4Width), + .ResetValue(MuBi4Width'(MuBi4False)) + ) u_rdback_en_flop ( + .clk_i, + .rst_ni, + + .d_i(MuBi4Width'(rdback_en_d)), + .q_o({rdback_en_q}) + ); + + caliptra_prim_flop #( + .Width(32), + .ResetValue(0) + ) u_rdback_data_exp ( + .clk_i, + .rst_ni, + + .d_i(rdback_data_exp_d), + .q_o(rdback_data_exp_q) + ); + + caliptra_prim_flop #( + .Width(DataIntgWidth), + .ResetValue(0) + ) u_rdback_data_exp_intg ( + .clk_i, + .rst_ni, + + .d_i(rdback_data_exp_intg_d), + .q_o(rdback_data_exp_intg_q) + ); + + // If the readback feature is enabled and we are currently in the readback phase, + // no address collision should happen inside prim_ram_1p_scr. If this would be the + // case, we would read from the holding register inside prim_ram_1p_scr instead of + // actually performing the readback from the memory. + `CALIPTRA_ASSERT(WRCollisionDuringReadBack_A, (rdback_phase | rdback_phase_wrreadback) & + mubi4_test_true_loose(rdback_en_q) |-> !wr_collision_i) + + + // If the readback feature is enabled, we assume that the write phase takes one extra cycle + // due to the underyling scrambling mechanism. If this additional cycle is not needed anymore + // in the future (e.g. due to the removale of the scrambling mechanism), the readback does not + // need to be delayed by once cylce in the FSM below. + `CALIPTRA_ASSERT(NoPendingWriteAfterWrite_A, wr_phase & mubi4_test_true_loose(rdback_en_q) + |=> write_pending_i) + + + end else begin: gen_no_readback_logic + assign rdback_chk_ok = 1'b0; + assign rdback_check_q = MuBi4False; + assign rdback_en_q = MuBi4False; + assign rdback_data_exp_q = 1'b0; + assign rdback_data_exp_intg_q = 1'b0; + + logic unused_rdback; + + assign unused_rdback = ^{rdback_check_d, rdback_data_exp_d, rdback_data_exp_intg_d}; + end + + // state machine handling + always_comb begin + rd_wait = 1'b0; + wait_phase = 1'b0; + stall_host = 1'b0; + wr_phase = 1'b0; + rd_phase = 1'b0; + rdback_phase = 1'b0; + rdback_phase_wrreadback = 1'b0; + rdback_wait = 1'b0; + state_d = state_q; + hold_tx_data = 1'b0; + alert_o = 1'b0; + rdback_check_d = rdback_check_q; + rdback_en_d = rdback_en_q; + rdback_data_exp_d = rdback_data_exp_q; + rdback_data_exp_intg_d = rdback_data_exp_intg_q; + + unique case (state_q) + StPassThru: begin + if (mubi4_test_true_loose(rdback_en_q) && mubi4_test_true_loose(rdback_check_q)) begin + // When we're expecting a readback check that means we'll see a data response from the + // SRAM this cycle which we need to check against the readback registers. During this + // cycle the data response out (via tl_o) will be squashed to invalid but we can accept + // a new transaction (via tl_i). + rdback_wait = 1'b1; + rdback_check_d = MuBi4False; + + // Perform the readback check. Omit the check if the transaction contains an error. + if (!rdback_chk_ok && !error_i) begin + alert_o = 1'b1; + end + end + + if (byte_wr_txn) begin + rd_phase = 1'b1; + if (byte_req_ack) begin + state_d = StWaitRd; + end + end else if (a_ack && mubi4_test_true_loose(rdback_en_q) && !error_i) begin + // For reads and full word writes we'll first do the transaction and then do a readback + // check. Setting `hold_tx_data` here will preserve the transaction information in + // u_sync_fifo for doing the readback transaction. + hold_tx_data = 1'b1; + state_d = wr_txn ? StWrReadBackInit : StRdReadBack; + end + + if (!tl_sram_o.a_valid && !tl_o.d_valid && + mubi4_test_false_strict(rdback_check_q)) begin + // Store readback enable into register when bus is idle and no readback is processed. + rdback_en_d = readback_en_i; + end + end + + // Due to the way things are serialized, there is no way for the logic to tell which read + // belongs to the partial read unless it flushes all prior transactions. Hence, we wait + // here until exactly one outstanding transaction remains (that one is the partial read). + StWaitRd: begin + rd_phase = 1'b1; + stall_host = 1'b1; + if (pending_txn_cnt == PendingTxnCntW'(1)) begin + rd_wait = 1'b1; + if (sram_d_ack) begin + state_d = StWriteCmd; + end + end + end + + StWriteCmd: begin + stall_host = 1'b1; + wr_phase = 1'b1; + + if (sram_a_ack) begin + state_d = mubi4_test_true_loose(rdback_en_q) ? StByteWrReadBackInit : StPassThru; + rdback_check_d = mubi4_test_true_loose(rdback_en_q) ? MuBi4True : MuBi4False; + rdback_data_exp_d = tl_sram_o.a_data; + rdback_data_exp_intg_d = tl_sram_o.a_user.data_intg; + end + end + + StWrReadBackInit: begin + // Perform readback after full write. To avoid that we read the holding register + // in the readback, wait until the write was processed by the memory module. + if (EnableReadback == 0) begin : gen_inv_state_StWrReadBackInit + // If readback is disabled, we shouldn't be in this state. + alert_o = 1'b1; + end + + // Stall the host to perform the readback in the next cycle. + stall_host = 1'b1; + + // Need to ensure there's no other transactions in flight before we do the readback (the + // initial write we're doing the readback for should be the only one active). + if (pending_txn_cnt == PendingTxnCntW'(1)) begin + wait_phase = 1'b1; + // Data we're checking against the readback is captured from the write transaction that + // was sent. + rdback_check_d = mubi4_test_true_loose(rdback_en_q) ? MuBi4True : MuBi4False; + rdback_data_exp_d = held_data.a_data; + rdback_data_exp_intg_d = held_data.a_user.data_intg; + if (d_ack) begin + // Got an immediate TL-UL write response. Wait for one cycle until the holding + // register is flushed and then perform the readback. + state_d = StWrReadBack; + end else begin + // No response yet to the initial write. + state_d = StWrReadBackDWait; + end + end + end + + StWrReadBack: begin + // Perform readback and check response in StPassThru. + if (EnableReadback == 0) begin : gen_inv_state_StWrReadBack + // If readback is disabled, we shouldn't be in this state. + alert_o = 1'b1; + end + + stall_host = 1'b1; + + rdback_phase = 1'b1; + + state_d = StPassThru; + end + + StWrReadBackDWait: begin + // We have not received the d_valid response of the initial write. Wait + // for the valid signal. + if (EnableReadback == 0) begin : gen_inv_state_StWrReadBackDWait + // If readback is disabled, we shouldn't be in this state. + alert_o = 1'b1; + end + + // Wait until we get write response. + wait_phase = 1'b1; + + stall_host = 1'b1; + + if (d_ack) begin + // Got the TL-UL write response. Wait for one cycle until the holding + // register is flushed and then perform the readback. + state_d = StWrReadBack; + end + end + + StByteWrReadBackInit: begin + // Perform readback after partial write. To avoid that we read the holding register + // in the readback, do the actual readback check in the next FSM state. + if (EnableReadback == 0) begin : gen_inv_state_StByteWrReadBackInit + // If readback is disabled, we shouldn't be in this state. + alert_o = 1'b1; + end + + // Sends out a read to a readback check on a partial write. The host is stalled whilst + // this is happening. + stall_host = 1'b1; + + // Wait until there is a single ongoing transaction. + if (pending_txn_cnt == PendingTxnCntW'(1)) begin + // Wait for one cycle with sending readback request to SRAM to avoid reading from + // holding register. + wait_phase = 1'b1; + + if (d_ack) begin + // Got an immediate TL-UL write response. Wait for one cycle until the holding + // register is flushed and then perform the readback. + state_d = StByteWrReadBack; + end else begin + // No response received for initial write. We already can send the + // request for the readback in the next cycle but we need to wait + // for the response for the initial write before doing the readback + // check. + state_d = StByteWrReadBackDWait; + end + end + end + + StByteWrReadBack: begin + // Wait until the memory module has completed the partial write. + // Perform readback and check response in StPassThru. + if (EnableReadback == 0) begin : gen_inv_state_StByteWrReadBack + // If readback is disabled, we shouldn't be in this state. + alert_o = 1'b1; + end + + stall_host = 1'b1; + + rdback_phase_wrreadback = 1'b1; + + state_d = StPassThru; + end + + StByteWrReadBackDWait: begin + if (EnableReadback == 0) begin : gen_inv_state_StByteWrReadBackDWait + // If readback is disabled, we shouldn't be in this state. + alert_o = 1'b1; + end + + stall_host = 1'b1; + + // Wait for one cycle with sending readback request to SRAM. + wait_phase = 1'b1; + + if (d_ack) begin + // Got the TL-UL write response. Wait for one cycle until the holding + // register is flushed and then perform the readback. + state_d = StByteWrReadBack; + end + end + + StRdReadBack: begin + if (EnableReadback == 0) begin : gen_inv_state_StRdReadBack + // If readback is disabled, we shouldn't be in this state. + alert_o = 1'b1; + end + + // Sends out a read to a readback check on a read. The host is stalled whilst + // this is happening. + stall_host = 1'b1; + + // Need to ensure there's no other transactions in flight before we do the readback (the + // read we're doing the readback for should be the only one active). + if (pending_txn_cnt == PendingTxnCntW'(1)) begin + rdback_phase = 1'b1; + + if (d_ack) begin + state_d = StPassThru; + // Data for the readback check comes from the first read. + rdback_check_d = mubi4_test_true_loose(rdback_en_q) ? MuBi4True : MuBi4False; + rdback_data_exp_d = tl_o.d_data; + rdback_data_exp_intg_d = tl_o.d_user.data_intg; + end else begin + // No response yet to the initial read, so go wait for it. + state_d = StRdReadBackDWait; + end + end + end + + StRdReadBackDWait : begin + if (EnableReadback == 0) begin : gen_inv_state_StRdReadBackDWait + // If readback is disabled, we shouldn't be in this state. + alert_o = 1'b1; + end + + stall_host = 1'b1; + + if (d_ack) begin + // Response received for first read. Now need to await data for the readback check + // which is done in the `StPassThru` state. + state_d = StPassThru; + // Data for the readback check comes from the first read. + rdback_check_d = mubi4_test_true_loose(rdback_en_q) ? MuBi4True : MuBi4False; + rdback_data_exp_d = tl_o.d_data; + rdback_data_exp_intg_d = tl_o.d_user.data_intg; + end + end + + default: begin + alert_o = 1'b1; + end + endcase // unique case (state_q) + + end + + tl_txn_data_t txn_data; + logic fifo_rdy; + logic txn_data_wr; + localparam int TxnDataWidth = $bits(tl_txn_data_t); + + assign txn_data = '{ + a_param: tl_i.a_param, + a_size: tl_i.a_size, + a_source: tl_i.a_source, + a_address: tl_i.a_address, + a_mask: tl_i.a_mask, + a_data: tl_i.a_data, + a_user: tl_i.a_user + }; + + + assign txn_data_wr = hold_tx_data | byte_req_ack; + + caliptra_prim_fifo_sync #( + .Width(TxnDataWidth), + .Pass(1'b0), + .Depth(1), + .OutputZeroIfEmpty(1'b0) + ) u_sync_fifo ( + .clk_i, + .rst_ni, + .clr_i(1'b0), + .wvalid_i(txn_data_wr), + .wready_o(fifo_rdy), + .wdata_i(txn_data), + .rvalid_o(), + .rready_i(sram_a_ack), + .rdata_o(held_data), + .full_o(), + .depth_o(), + .err_o() + ); + + // captured read data + logic [caliptra_tlul_pkg::TL_DW-1:0] rsp_data; + always_ff @(posedge clk_i) begin + if (sram_d_ack && rd_wait) begin + rsp_data <= tl_sram_i.d_data; + end + end + + // while we could simply not assert a_ready to ensure the host keeps + // the request lines stable, there is no guarantee the hosts (if there are multiple) + // do not re-arbitrate on every cycle if its transactions are not accepted. + // As a result, it is better to capture the transaction attributes. + logic [caliptra_tlul_pkg::TL_DW-1:0] combined_data, unused_data; + always_comb begin + for (int i = 0; i < caliptra_tlul_pkg::TL_DBW; i++) begin + combined_data[i*8 +: 8] = held_data.a_mask[i] ? + held_data.a_data[i*8 +: 8] : + rsp_data[i*8 +: 8]; + end + end + + // Compute updated integrity bits for the data. + // Note that the CMD integrity does not have to be correct, since it is not consumed nor + // checked further downstream. + logic [caliptra_tlul_pkg::DataIntgWidth-1:0] data_intg; + + caliptra_tlul_data_integ_enc u_tlul_data_integ_enc ( + .data_i(combined_data), + .data_intg_o({data_intg, unused_data}) + ); + + tl_a_user_t combined_user; + always_comb begin + combined_user = held_data.a_user; + combined_user.data_intg = data_intg; + end + + localparam int unsigned AccessSize = $clog2(caliptra_tlul_pkg::TL_DBW); + always_comb begin + // Pass-through by default + tl_sram_o = tl_i; + // If we're waiting for an internal read for RMW, or a readback read, we force this to 1. + tl_sram_o.d_ready = tl_i.d_ready | rd_wait | rdback_wait; + + // We take over the TL-UL bus if there is a pending read or write for the RMW transaction. + // TL-UL signals are selectively muxed below to reduce complexity and remove long timing + // paths through the error_i signal. In particular, we avoid creating paths from error_i + // to the address and data output since these may feed into RAM scrambling logic further + // downstream. + + // Write transactions for RMW or reads when in readback mode. + if (wr_phase | rdback_phase | rdback_phase_wrreadback) begin + tl_sram_o.a_valid = 1'b1; + // During a read-modify write, always access the entire word. + tl_sram_o.a_opcode = wr_phase ? PutFullData : Get; + // In either read-modify write or SRAM readback mode, use the mask, size and address + // of the original request. + tl_sram_o.a_size = + (wr_phase | rdback_phase_wrreadback) ? TL_SZW'(AccessSize) : held_data.a_size; + tl_sram_o.a_mask = + (wr_phase | rdback_phase_wrreadback) ? '{default: '1} : held_data.a_mask; + // override with held / combined data. + // need to use word aligned addresses here. + tl_sram_o.a_address = held_data.a_address; + tl_sram_o.a_address[AccessSize-1:0] = + (wr_phase | rdback_phase_wrreadback) ? '0 : held_data.a_address[AccessSize-1:0]; + tl_sram_o.a_source = held_data.a_source; + tl_sram_o.a_param = held_data.a_param; + tl_sram_o.a_data = wr_phase ? combined_data : '0; + tl_sram_o.a_user = wr_phase ? combined_user : '0; + // Read transactions for RMW. + end else if (rd_phase) begin + // need to use word aligned addresses here. + tl_sram_o.a_address[AccessSize-1:0] = '0; + // Only override the control signals if there is no error at the input. + if (!error_i || stall_host) begin + // Since we are performing a read-modify-write operation, + // we always access the entire word. + tl_sram_o.a_size = caliptra_tlul_pkg::TL_SZW'(AccessSize); + tl_sram_o.a_mask = '{default: '1}; + // use incoming valid as long as we are not stalling the host + tl_sram_o.a_valid = tl_i.a_valid & ~stall_host; + tl_sram_o.a_opcode = Get; + end + end else if (wait_phase) begin + // Delay the readback request to avoid that we are reading the holding + // register. + tl_sram_o.a_valid = 1'b0; + end + end + + // This assert is necessary for the casting of AccessSize. + `CALIPTRA_ASSERT(TlulSramByteTlSize_A, caliptra_tlul_pkg::TL_SZW >= $clog2(AccessSize + 1)) + + assign error_o = error_i & ~stall_host; + + logic size_fifo_rdy; + logic [caliptra_tlul_pkg::TL_SZW-1:0] a_size; + caliptra_prim_fifo_sync #( + .Width(caliptra_tlul_pkg::TL_SZW), + .Pass(1'b0), + .Depth(Outstanding), + .OutputZeroIfEmpty(1'b1) + ) u_sync_fifo_a_size ( + .clk_i, + .rst_ni, + .clr_i(1'b0), + .wvalid_i(a_ack), + .wready_o(size_fifo_rdy), + .wdata_i(tl_i.a_size), + .rvalid_o(), + .rready_i(d_ack), + .rdata_o(a_size), + .full_o(), + .depth_o(pending_txn_cnt), + .err_o() + ); + + always_comb begin + tl_o = tl_sram_i; + + // pass a_ready through directly if we are not stalling + tl_o.a_ready = tl_sram_i.a_ready & ~stall_host & fifo_rdy & size_fifo_rdy; + + // when internal logic has taken over, do not show response to host during + // read phase. During write phase, allow the host to see the completion. + tl_o.d_valid = tl_sram_i.d_valid & ~rd_wait & ~rdback_wait; + + // the size returned by tl_sram_i does not always correspond to the actual + // transaction size in cases where a read modify write operation is + // performed. Hence, we always return the registered size here. + tl_o.d_size = a_size; + end // always_comb + + // unused info from tl_sram_i + // see explanation in above block + logic unused_tl; + assign unused_tl = |tl_sram_i.d_size; + + // when byte access detected, go to wait read + `CALIPTRA_ASSERT(ByteAccessStateChange_A, a_ack & wr_txn & ~&tl_i.a_mask & ~error_i |=> + state_q inside {StWaitRd}) + // when in wait for read, a successful response should move to write phase + `CALIPTRA_ASSERT(ReadCompleteStateChange_A, + (state_q == StWaitRd) && (pending_txn_cnt == 1) && sram_d_ack |=> state_q == StWriteCmd) + // The readback logic assumes that any request on the readback channel will be instantly granted + // (i.e. after the initial SRAM read or write request from the external requester has been + // granted). This helps simplify the logic. It is guaranteed when connected to an SRAM as it + // produces no back pressure. When connected to a scrambled SRAM the key going invalid will + // cause a_ready to drop. The `compound_txn_in_progress_o` output is provided for this scenario. + // When asserted SRAM should not drop `a_ready` even if there is an invalid scrambling key. + `CALIPTRA_ASSERT(ReadbackAccessAlwaysGranted_A, (rdback_phase | rdback_phase_wrreadback) && !error_i + |-> tl_sram_i.a_ready) + + // The readback logic assumes the result of a read transaction issues for the readback will get + // an immediate response. This can be guaranteed when connected to a SRAM, see above comment. + `CALIPTRA_ASSERT(ReadbackDataImmediatelyAvailable_A, (state_q == StPassThru) && + mubi4_test_true_loose(rdback_en_q) && mubi4_test_true_loose(rdback_check_q) && + !error_i|-> tl_sram_i.d_valid) + + assign compound_txn_in_progress_o = wr_phase | rdback_phase | rdback_phase_wrreadback; + end else begin : gen_no_integ_handling + // In this case we pass everything just through. + assign tl_sram_o = tl_i; + assign tl_o = tl_sram_i; + assign error_o = error_i; + assign alert_o = 1'b0; + assign compound_txn_in_progress_o = 1'b0; + + // Signal only used in readback mode. + mubi4_t unused_readback_en; + assign unused_readback_en = readback_en_i; + + end + + // Signals only used for SVA. + logic unused_write_pending, unused_wr_collision; + assign unused_write_pending = write_pending_i; + assign unused_wr_collision = wr_collision_i; + + // EnableReadback requires that EnableIntg is on. + // EnableIntg can be used without EnableReadback. + `CALIPTRA_ASSERT_INIT(SramReadbackAndIntg, + (EnableReadback && EnableIntg) || (!EnableReadback && (EnableIntg || !EnableIntg))) +endmodule // caliptra_tlul_adapter_sram diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_top.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_top.sv new file mode 100755 index 0000000..49ce79b --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_top.sv @@ -0,0 +1,1575 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +// + +`include "config_defines.svh" +`include "caliptra_macros.svh" +`include "caliptra_sva.svh" + +module caliptra_top + import kv_defines_pkg::*; + import pv_defines_pkg::*; + import soc_ifc_pkg::*; + import lc_ctrl_state_pkg::*; + import lc_ctrl_reg_pkg::*; + import lc_ctrl_pkg::*; +`ifdef CALIPTRA_INTERNAL_TRNG + import entropy_src_pkg::*; + import csrng_pkg::*; +`endif + ( + input logic clk, + + input logic cptra_pwrgood, + input logic cptra_rst_b, + + input logic [255:0] cptra_obf_key, + input logic [`CLP_CSR_HMAC_KEY_DWORDS-1:0][31:0] cptra_csr_hmac_key, + input logic cptra_obf_field_entropy_vld, + input logic [`CLP_OBF_FE_DWORDS-1 :0][31:0] cptra_obf_field_entropy, + input logic cptra_obf_uds_seed_vld, + input logic [`CLP_OBF_UDS_DWORDS-1:0][31:0] cptra_obf_uds_seed, + + + //JTAG Interface + input logic jtag_tck, // JTAG clk + input logic jtag_tms, // JTAG TMS + input logic jtag_tdi, // JTAG tdi + input logic jtag_trst_n, // JTAG Reset + output logic jtag_tdo, // JTAG TDO + output logic jtag_tdoEn, // JTAG TDO enable + + //SoC AXI Interface + axi_if.w_sub s_axi_w_if, + axi_if.r_sub s_axi_r_if, + + // AXI Manager INF + axi_if.w_mgr m_axi_w_if, + axi_if.r_mgr m_axi_r_if, + + // Caliptra Memory Export Interface + el2_mem_if.veer_sram_src el2_mem_export, + abr_mem_if.req abr_memory_export, + + //SRAM interface for mbox + output logic mbox_sram_cs, + output logic mbox_sram_we, + output logic [CPTRA_MBOX_ADDR_W-1:0] mbox_sram_addr, + output logic [CPTRA_MBOX_DATA_AND_ECC_W-1:0] mbox_sram_wdata, + input logic [CPTRA_MBOX_DATA_AND_ECC_W-1:0] mbox_sram_rdata, + + //SRAM interface for imem + output logic imem_cs, + output logic [`CALIPTRA_IMEM_ADDR_WIDTH-1:0] imem_addr, + input logic [`CALIPTRA_IMEM_DATA_WIDTH-1:0] imem_rdata, + + output logic ready_for_fuses, + output logic ready_for_mb_processing, + output logic ready_for_runtime, + + output logic mailbox_data_avail, + output logic mailbox_flow_done, + + input logic recovery_data_avail, + input logic recovery_image_activated, + + input logic BootFSM_BrkPoint, + + //SoC Interrupts + output logic cptra_error_fatal, + output logic cptra_error_non_fatal, + + // TRNG Interface + // External Request + output logic etrng_req, + // Physical Source for Internal TRNG + input logic [3:0] itrng_data, + input logic itrng_valid, + + // Subsystem mode straps + input logic [63:0] strap_ss_caliptra_base_addr, + input logic [63:0] strap_ss_mci_base_addr, + input logic [63:0] strap_ss_recovery_ifc_base_addr, + input logic [63:0] strap_ss_external_staging_area_base_addr, + input logic [63:0] strap_ss_otp_fc_base_addr, + input logic [63:0] strap_ss_uds_seed_base_addr, + input logic [63:0] strap_ss_key_release_base_addr, + input logic [15:0] strap_ss_key_release_key_size, + input logic [31:0] strap_ss_prod_debug_unlock_auth_pk_hash_reg_bank_offset, + input logic [31:0] strap_ss_num_of_prod_debug_unlock_auth_pk_hashes, + input logic [31:0] strap_ss_caliptra_dma_axi_user, + input logic [31:0] strap_ss_strap_generic_0, + input logic [31:0] strap_ss_strap_generic_1, + input logic [31:0] strap_ss_strap_generic_2, + input logic [31:0] strap_ss_strap_generic_3, + input logic ss_debug_intent, + + // Subsystem mode constant strap input indicating OCP LOCK configuration is enabled + input logic ss_ocp_lock_en, + + // Subsystem mode debug outputs + output logic ss_dbg_manuf_enable, + output logic [63:0] ss_soc_dbg_unlock_level, + + // Subsystem mode firmware execution control + output logic [127:0] ss_generic_fw_exec_ctrl, + + input logic [63:0] generic_input_wires, + output logic [63:0] generic_output_wires, + + // RISC-V Trace Ports + output logic [31:0] trace_rv_i_insn_ip, + output logic [31:0] trace_rv_i_address_ip, + output logic trace_rv_i_valid_ip, + output logic trace_rv_i_exception_ip, + output logic [4:0] trace_rv_i_ecause_ip, + output logic trace_rv_i_interrupt_ip, + output logic [31:0] trace_rv_i_tval_ip, + + input security_state_t security_state, + input logic scan_mode +); + + `include "common_defines.sv" + + localparam NUM_INTR = `RV_PIC_TOTAL_INT; // 31 + localparam TOTAL_OBF_KEY_BITS = `CLP_OBF_KEY_DWORDS * 32; + + //caliptra reset driven by boot fsm in mailbox + logic cptra_noncore_rst_b; + logic cptra_uc_rst_b; + + //clock gating signals + logic clk_gating_en ; + logic rdc_clk_dis ; + logic clk_cg ; + logic soc_ifc_clk_cg ; + logic rdc_clk_cg ; + logic uc_clk_cg ; + + logic [2:0] s_axi_active ; + + logic [31:0] ic_haddr ; + logic [2:0] ic_hburst ; + logic ic_hmastlock ; + logic [3:0] ic_hprot ; + logic [2:0] ic_hsize ; + logic [1:0] ic_htrans ; + logic ic_hwrite ; + logic [63:0] ic_hrdata ; + logic ic_hready ; + logic ic_hresp ; + + logic o_debug_mode_status; + + + logic o_cpu_halt_ack; + logic o_cpu_halt_status; + logic o_cpu_run_ack; + + logic mailbox_write; + logic [63:0] dma_hrdata ; + logic [63:0] dma_hwdata ; + logic dma_hready ; + logic dma_hresp ; + + logic mpc_debug_halt_req; + logic mpc_debug_run_req; + logic mpc_reset_run_req; + logic mpc_debug_halt_ack; + logic mpc_debug_run_ack; + logic debug_brkpt_status; + + integer cycleCnt; + logic mailbox_data_val; + + wire dma_hready_out; + integer commit_count; + + logic wb_valid; + logic [4:0] wb_dest; + logic [31:0] wb_data; + + logic [`CLP_OBF_KEY_DWORDS-1:0][31:0] cptra_obf_key_reg; + logic [`CLP_OBF_FE_DWORDS-1 :0][31:0] obf_field_entropy; + logic [`CLP_OBF_UDS_DWORDS-1:0][31:0] obf_uds_seed; + logic [OCP_LOCK_HEK_NUM_DWORDS-1:0][31:0] obf_hek_seed; + logic [`CLP_CSR_HMAC_KEY_DWORDS-1:0][31:0] cptra_csr_hmac_key_reg; + + //caliptra uncore jtag ports & pertinent logic + logic cptra_core_dmi_enable; + logic cptra_uncore_dmi_enable; + logic cptra_uncore_dmi_reg_en; + logic cptra_uncore_dmi_reg_wr_en; + logic [31:0] cptra_uncore_dmi_reg_rdata; + logic [6:0] cptra_uncore_dmi_reg_addr; + logic [31:0] cptra_uncore_dmi_reg_wdata; + logic unlock_caliptra_security_state; + security_state_t cptra_security_state_Latched; + security_state_t cptra_security_state_Latched_d; + security_state_t cptra_security_state_Latched_f; + logic cptra_dmi_reg_en_preQ; + + logic fw_update_rst_window; + + logic cptra_ss_debug_intent; //qualified debug intent + + // Caliptra ECC status signals + rv_ecc_sts_t rv_ecc_sts; + + el2_mem_if el2_icache_stub (); + + logic iccm_lock; + + // AES status signals + logic aes_input_ready; + logic aes_output_valid; + logic aes_status_idle; + + // AES CIF Signals + logic aes_cif_dma_req_dv; + logic aes_cif_dma_req_hold; + logic aes_cif_dma_req_error; + soc_ifc_req_t aes_cif_dma_req_data; + logic [CPTRA_AXI_DMA_DATA_WIDTH-1 : 0] aes_cif_dma_req_rdata; + + // Interrupt Signals + wire doe_error_intr; + wire doe_notif_intr; + wire ecc_error_intr; + wire ecc_notif_intr; + wire hmac_error_intr; + wire hmac_notif_intr; + wire kv_error_intr; + wire kv_notif_intr; + wire sha512_error_intr; + wire sha512_notif_intr; + wire sha256_error_intr; + wire sha256_notif_intr; + wire sha3_error_intr; + wire sha3_notif_intr; + wire abr_error_intr; + wire abr_notif_intr; + wire soc_ifc_error_intr; + wire soc_ifc_notif_intr; + wire sha_error_intr; + wire sha_notif_intr; + wire dma_error_intr; + wire dma_notif_intr; + logic [NUM_INTR-1:0] intr; + + kv_read_t [KV_NUM_READ-1:0] kv_read; + kv_write_t [KV_NUM_WRITE-1:0] kv_write; + kv_rd_resp_t [KV_NUM_READ-1:0] kv_rd_resp; + kv_wr_resp_t [KV_NUM_WRITE-1:0] kv_wr_resp; + + pv_read_t [PV_NUM_READ-1:0] pv_read; + pv_write_t [PV_NUM_WRITE-1:0] pv_write; + pv_rd_resp_t [PV_NUM_READ-1:0] pv_rd_resp; + pv_wr_resp_t [PV_NUM_WRITE-1:0] pv_wr_resp; + + pcr_signing_t pcr_signing_data; + + //mailbox sram gasket + cptra_mbox_sram_req_t mbox_sram_req; + cptra_mbox_sram_resp_t mbox_sram_resp; + + logic clear_obf_secrets; + logic scan_mode_switch; + logic debug_lock_switch; + logic device_lifecycle_switch; + logic debug_lock_or_scan_mode_switch, clear_obf_secrets_debugScanQ; + logic cptra_scan_mode_Latched, cptra_scan_mode_Latched_d, cptra_scan_mode_Latched_f; + + logic [`CLP_OBF_KEY_DWORDS-1:0][31:0] cptra_obf_key_dbg; + logic [`CLP_OBF_FE_DWORDS-1 :0][31:0] obf_field_entropy_dbg; + logic [`CLP_OBF_UDS_DWORDS-1:0][31:0] obf_uds_seed_dbg; + logic [`CLP_CSR_HMAC_KEY_DWORDS-1:0][31:0] cptra_csr_hmac_key_dbg; + logic cptra_in_debug_scan_mode; + + // Subsystem mode OCP LOCK status + logic ss_ocp_lock_in_progress; + // Key release size (used as input to AES operation) + logic [15:0] ss_key_release_key_size; + + logic [31:0] imem_haddr; + logic imem_hsel; + logic imem_hwrite; + logic imem_hready; + logic imem_hreadyout; + logic [1:0] imem_htrans; + logic [2:0] imem_hsize; + logic [63:0] imem_hrdata; + logic imem_hresp; + + logic lsu_addr_ph, lsu_data_ph, lsu_sel; + logic ic_addr_ph, ic_data_ph, ic_sel; + + logic hmac_busy, ecc_busy, doe_busy, aes_busy, abr_busy; + logic aes_busy_filtered, ecc_busy_filtered; + logic crypto_error; + + typedef enum logic [1:0] { + CRYPTO_IDLE, + CRYPTO_INITIAL, + CRYPTO_DONE + } crypto_state_t; + crypto_state_t aes_state, aes_next_state; + crypto_state_t ecc_state, ecc_next_state; + + always_ff @(posedge clk or negedge cptra_noncore_rst_b) begin + if (!cptra_noncore_rst_b) + aes_state <= CRYPTO_IDLE; + else + aes_state <= aes_next_state; + end + + always_comb begin + case (aes_state) + CRYPTO_IDLE: aes_next_state = aes_busy ? CRYPTO_INITIAL : CRYPTO_IDLE; + CRYPTO_INITIAL: aes_next_state = aes_busy ? CRYPTO_INITIAL : CRYPTO_DONE; + CRYPTO_DONE: aes_next_state = CRYPTO_DONE; + default: aes_next_state = CRYPTO_IDLE; + endcase + end + + always_comb aes_busy_filtered = (aes_state == CRYPTO_DONE) ? aes_busy : 1'b0; + + always_ff @(posedge clk or negedge cptra_noncore_rst_b) begin + if (!cptra_noncore_rst_b) + ecc_state <= CRYPTO_IDLE; + else + ecc_state <= ecc_next_state; + end + + always_comb begin + case (ecc_state) + CRYPTO_IDLE: ecc_next_state = ecc_busy ? CRYPTO_INITIAL : CRYPTO_IDLE; + CRYPTO_INITIAL: ecc_next_state = ecc_busy ? CRYPTO_INITIAL : CRYPTO_DONE; + CRYPTO_DONE: ecc_next_state = CRYPTO_DONE; + default: ecc_next_state = CRYPTO_IDLE; + endcase + end + + always_comb ecc_busy_filtered = (ecc_state == CRYPTO_DONE) ? ecc_busy : 1'b0; + + always_comb crypto_error = (hmac_busy & ecc_busy_filtered) | + (hmac_busy & abr_busy) | + (hmac_busy & doe_busy) | + (hmac_busy & aes_busy_filtered) | + (ecc_busy_filtered & doe_busy) | + (ecc_busy_filtered & abr_busy) | + (ecc_busy_filtered & aes_busy_filtered) | + (abr_busy & doe_busy) | + (abr_busy & aes_busy_filtered) | + (doe_busy & aes_busy_filtered) ; + + +always_comb begin + mbox_sram_cs = mbox_sram_req.cs; + mbox_sram_we = mbox_sram_req.we; + mbox_sram_addr = mbox_sram_req.addr; + mbox_sram_wdata = mbox_sram_req.wdata; // Contains data + ecc fields + mbox_sram_resp.rdata = mbox_sram_rdata; // Contains data + ecc fields +end + //======================================================================== + // AHB Slave ports. + // Slave 0: LMEM + // Slave 1: DMA Slave port + //======================================================================== + CALIPTRA_AHB_LITE_BUS_INF #( + .AHB_LITE_ADDR_WIDTH(`CALIPTRA_AHB_HADDR_SIZE), + .AHB_LITE_DATA_WIDTH(`CALIPTRA_AHB_HDATA_SIZE) + ) + responder_inst[0:`CALIPTRA_AHB_SLAVES_NUM-1](); + + //======================================================================== + // AHB Master ports + //======================================================================== + CALIPTRA_AHB_LITE_BUS_INF #( + .AHB_LITE_ADDR_WIDTH(`CALIPTRA_AHB_HADDR_SIZE), + .AHB_LITE_DATA_WIDTH(`CALIPTRA_AHB_HDATA_SIZE) + ) + sb_ahb(); + CALIPTRA_AHB_LITE_BUS_INF #( + .AHB_LITE_ADDR_WIDTH(`CALIPTRA_AHB_HADDR_SIZE), + .AHB_LITE_DATA_WIDTH(`CALIPTRA_AHB_HDATA_SIZE) + ) + lsu_ahb(); + + CALIPTRA_AHB_LITE_BUS_INF #( + .AHB_LITE_ADDR_WIDTH(`CALIPTRA_AHB_HADDR_SIZE), + .AHB_LITE_DATA_WIDTH(`CALIPTRA_AHB_HDATA_SIZE) + ) + initiator_inst(); + + //======================================================================== + // AHB Responder Disable + //======================================================================== + logic [`CALIPTRA_AHB_SLAVES_NUM-1:0] ahb_lite_resp_disable; + logic [`CALIPTRA_AHB_SLAVES_NUM-1:0] ahb_lite_resp_access_blocked; + + //======================================================================== + // AHB Lite Interface and decoder logic instance + //======================================================================== + ahb_lite_bus #( + .NUM_RESPONDERS (`CALIPTRA_AHB_SLAVES_NUM), + .AHB_LITE_ADDR_WIDTH (`CALIPTRA_AHB_HADDR_SIZE), + .AHB_LITE_DATA_WIDTH (`CALIPTRA_AHB_HDATA_SIZE) + ) + ahb_lite_bus_i ( + .hclk ( clk_cg ), + .hreset_n ( cptra_noncore_rst_b ), + .force_bus_idle ( fw_update_rst_window ), + .ahb_lite_responders ( responder_inst ), + .ahb_lite_initiator ( initiator_inst ), + .ahb_lite_resp_disable_i ( ahb_lite_resp_disable ), + .ahb_lite_resp_access_blocked_o( ahb_lite_resp_access_blocked), + .ahb_lite_start_addr_i ( `CALIPTRA_SLAVE_BASE_ADDR ), + .ahb_lite_end_addr_i ( `CALIPTRA_SLAVE_MASK_ADDR ) + ); + always_comb ahb_lite_resp_disable[`CALIPTRA_SLAVE_SEL_DOE] = 1'b0; + always_comb ahb_lite_resp_disable[`CALIPTRA_SLAVE_SEL_ECC] = 1'b0; + always_comb ahb_lite_resp_disable[`CALIPTRA_SLAVE_SEL_HMAC] = 1'b0; + always_comb ahb_lite_resp_disable[`CALIPTRA_SLAVE_SEL_KV] = 1'b0; + always_comb ahb_lite_resp_disable[`CALIPTRA_SLAVE_SEL_PV] = 1'b0; + always_comb ahb_lite_resp_disable[`CALIPTRA_SLAVE_SEL_DV] = 1'b0; + always_comb ahb_lite_resp_disable[`CALIPTRA_SLAVE_SEL_SHA512] = 1'b0; + always_comb ahb_lite_resp_disable[`CALIPTRA_SLAVE_SEL_SOC_IFC] = 1'b0; + always_comb ahb_lite_resp_disable[`CALIPTRA_SLAVE_SEL_DDMA] = 1'b0; + always_comb ahb_lite_resp_disable[`CALIPTRA_SLAVE_SEL_IDMA] = iccm_lock & responder_inst[`CALIPTRA_SLAVE_SEL_IDMA].hwrite; + always_comb ahb_lite_resp_disable[`CALIPTRA_SLAVE_SEL_SHA256] = 1'b0; + always_comb ahb_lite_resp_disable[`CALIPTRA_SLAVE_SEL_IMEM] = 1'b0; + always_comb ahb_lite_resp_disable[`CALIPTRA_SLAVE_SEL_CSRNG] = 1'b0; + always_comb ahb_lite_resp_disable[`CALIPTRA_SLAVE_SEL_ENTROPY_SRC] = 1'b0; + always_comb ahb_lite_resp_disable[`CALIPTRA_SLAVE_SEL_MLDSA] = 1'b0; + always_comb ahb_lite_resp_disable[`CALIPTRA_SLAVE_SEL_AES] = 1'b0; + always_comb ahb_lite_resp_disable[`CALIPTRA_SLAVE_SEL_SHA3] = 1'b0; + + //=========================================================================- + // RTL instance + //=========================================================================- +//FIXME TIE OFFS +logic [31:0] reset_vector; +logic [31:0] nmi_vector; +logic nmi_int; +logic soft_int; +logic timer_int; + +assign reset_vector = `RV_RESET_VEC; +assign soft_int = 1'b0; + +assign kv_error_intr = 1'b0; // TODO +assign kv_notif_intr = 1'b0; // TODO + +// Vector 0 usage is reserved by VeeR, so bit 0 of the intr wire +// drive Vector 1 +always_comb begin + intr[`VEER_INTR_VEC_DOE_ERROR -1] = doe_error_intr; + intr[`VEER_INTR_VEC_DOE_NOTIF -1] = doe_notif_intr; + intr[`VEER_INTR_VEC_ECC_ERROR -1] = ecc_error_intr; + intr[`VEER_INTR_VEC_ECC_NOTIF -1] = ecc_notif_intr; + intr[`VEER_INTR_VEC_HMAC_ERROR -1] = hmac_error_intr; + intr[`VEER_INTR_VEC_HMAC_NOTIF -1] = hmac_notif_intr; + intr[`VEER_INTR_VEC_KV_ERROR -1] = kv_error_intr; + intr[`VEER_INTR_VEC_KV_NOTIF -1] = kv_notif_intr; + intr[`VEER_INTR_VEC_SHA512_ERROR -1] = sha512_error_intr; + intr[`VEER_INTR_VEC_SHA512_NOTIF -1] = sha512_notif_intr; + intr[`VEER_INTR_VEC_SHA256_ERROR- 1] = sha256_error_intr; + intr[`VEER_INTR_VEC_SHA256_NOTIF -1] = sha256_notif_intr; + intr[`VEER_INTR_VEC_RSVD0_ERROR -1] = 1'b0; + intr[`VEER_INTR_VEC_RSVD0_NOTIF -1] = 1'b0; + intr[`VEER_INTR_VEC_RSVD1_ERROR -1] = 1'b0; + intr[`VEER_INTR_VEC_RSVD1_NOTIF -1] = 1'b0; + intr[`VEER_INTR_VEC_SHA3_ERROR -1] = sha3_error_intr; + intr[`VEER_INTR_VEC_SHA3_NOTIF -1] = sha3_notif_intr; + intr[`VEER_INTR_VEC_SOC_IFC_ERROR-1] = soc_ifc_error_intr; + intr[`VEER_INTR_VEC_SOC_IFC_NOTIF-1] = soc_ifc_notif_intr; + intr[`VEER_INTR_VEC_SHA_ERROR -1] = sha_error_intr; + intr[`VEER_INTR_VEC_SHA_NOTIF -1] = sha_notif_intr; + intr[`VEER_INTR_VEC_ABR_ERROR -1] = abr_error_intr; + intr[`VEER_INTR_VEC_ABR_NOTIF -1] = abr_notif_intr; + intr[`VEER_INTR_VEC_AXI_DMA_ERROR-1] = dma_error_intr; + intr[`VEER_INTR_VEC_AXI_DMA_NOTIF-1] = dma_notif_intr; + intr[NUM_INTR-1:`VEER_INTR_VEC_MAX_ASSIGNED] = '0; +end + +//Open Core TAP only for debug unlocked +always_comb cptra_core_dmi_enable = ~(cptra_security_state_Latched.debug_locked); +//Open Uncore TAP for debug unlocked, or DEVICE_MANUFACTURING, or debug intent set +always_comb cptra_uncore_dmi_enable = ~(cptra_security_state_Latched.debug_locked) | + (cptra_security_state_Latched.device_lifecycle == DEVICE_MANUFACTURING) | + cptra_ss_debug_intent; + +// I-Cache is disabled, leave pins connected to 0/unloaded +always_comb begin + el2_icache_stub.wb_packeddout_pre = '0; + el2_icache_stub.wb_dout_pre_up = '0; + el2_icache_stub.ic_tag_data_raw_packed_pre = '0; + el2_icache_stub.ic_tag_data_raw_pre = '0; +end + +el2_veer_wrapper rvtop ( +`ifdef CALIPTRA_FORCE_CPU_RESET + .rst_l ( 1'b0 ), +`else + .rst_l ( cptra_uc_rst_b), +`endif + .dbg_rst_l ( cptra_pwrgood), + .clk ( uc_clk_cg ), + .rst_vec ( reset_vector[31:1]), + .nmi_int ( nmi_int ), + .nmi_vec ( nmi_vector[31:1]), + + .haddr ( ic_haddr ), + .hburst ( ic_hburst ), + .hmastlock ( ic_hmastlock ), + .hprot ( ic_hprot ), + .hsize ( ic_hsize ), + .htrans ( ic_htrans ), + .hwrite ( ic_hwrite ), + + .hrdata ( ic_hrdata[63:0]), + .hready ( ic_hready ), + .hresp ( ic_hresp ), + + //--------------------------------------------------------------- + // Debug AHB Master + //--------------------------------------------------------------- + .sb_haddr ( sb_ahb.haddr ), + .sb_hburst ( ), + .sb_hmastlock ( ), + .sb_hprot ( ), + .sb_hsize ( sb_ahb.hsize ), + .sb_htrans ( sb_ahb.htrans ), + .sb_hwrite ( sb_ahb.hwrite ), + .sb_hwdata ( sb_ahb.hwdata ), + + .sb_hrdata ( sb_ahb.hrdata ), + .sb_hready ( sb_ahb.hready ), + .sb_hresp ( sb_ahb.hresp ), + + //--------------------------------------------------------------- + // LSU AHB Master + //--------------------------------------------------------------- + .lsu_haddr ( lsu_ahb.haddr ), + .lsu_hburst ( ), + .lsu_hmastlock ( ), + .lsu_hprot ( ), + .lsu_hsize ( lsu_ahb.hsize ), + .lsu_htrans ( lsu_ahb.htrans ), + .lsu_hwrite ( lsu_ahb.hwrite ), + .lsu_hwdata ( lsu_ahb.hwdata ), + + .lsu_hrdata ( lsu_ahb.hrdata ), + .lsu_hready ( lsu_ahb.hready ), + .lsu_hresp ( lsu_ahb.hresp ), + + //--------------------------------------------------------------- + // DMA Slave + //--------------------------------------------------------------- + .dma_haddr ( responder_inst[`CALIPTRA_SLAVE_SEL_IDMA].hsel ? responder_inst[`CALIPTRA_SLAVE_SEL_IDMA].haddr : responder_inst[`CALIPTRA_SLAVE_SEL_DDMA].haddr ), + .dma_hburst ( '0 ), + .dma_hmastlock ( '0 ), + .dma_hprot ( 4'd3 ), + .dma_hsize ( responder_inst[`CALIPTRA_SLAVE_SEL_IDMA].hsel ? responder_inst[`CALIPTRA_SLAVE_SEL_IDMA].hsize : responder_inst[`CALIPTRA_SLAVE_SEL_DDMA].hsize ), + .dma_htrans ( responder_inst[`CALIPTRA_SLAVE_SEL_IDMA].hsel ? responder_inst[`CALIPTRA_SLAVE_SEL_IDMA].htrans : responder_inst[`CALIPTRA_SLAVE_SEL_DDMA].htrans ), + .dma_hwrite ( responder_inst[`CALIPTRA_SLAVE_SEL_IDMA].hsel ? responder_inst[`CALIPTRA_SLAVE_SEL_IDMA].hwrite : responder_inst[`CALIPTRA_SLAVE_SEL_DDMA].hwrite ), + .dma_hwdata ( responder_inst[`CALIPTRA_SLAVE_SEL_IDMA].hsel ? responder_inst[`CALIPTRA_SLAVE_SEL_IDMA].hwdata : responder_inst[`CALIPTRA_SLAVE_SEL_DDMA].hwdata ), + + .dma_hrdata ( responder_inst[`CALIPTRA_SLAVE_SEL_DDMA].hrdata ), + .dma_hresp ( responder_inst[`CALIPTRA_SLAVE_SEL_DDMA].hresp ), + .dma_hsel ( responder_inst[`CALIPTRA_SLAVE_SEL_IDMA].hsel | responder_inst[`CALIPTRA_SLAVE_SEL_DDMA].hsel), + .dma_hreadyin ( responder_inst[`CALIPTRA_SLAVE_SEL_IDMA].hsel ? responder_inst[`CALIPTRA_SLAVE_SEL_IDMA].hready : responder_inst[`CALIPTRA_SLAVE_SEL_DDMA].hready ), + .dma_hreadyout ( responder_inst[`CALIPTRA_SLAVE_SEL_DDMA].hreadyout ), + + .timer_int ( timer_int), + .soft_int ( soft_int ), + .extintsrc_req ( intr ), + + .lsu_bus_clk_en ( 1'b1 ),// Clock ratio b/w cpu core clk & AHB master interface + .ifu_bus_clk_en ( 1'b1 ),// Clock ratio b/w cpu core clk & AHB master interface + .dbg_bus_clk_en ( 1'b1 ),// Clock ratio b/w cpu core clk & AHB Debug master interface + .dma_bus_clk_en ( 1'b1 ),// Clock ratio b/w cpu core clk & AHB slave interface + + // ICCM/DCCM ECC status + .iccm_ecc_single_error (rv_ecc_sts.cptra_iccm_ecc_single_error), + .iccm_ecc_double_error (rv_ecc_sts.cptra_iccm_ecc_double_error), + .dccm_ecc_single_error (rv_ecc_sts.cptra_dccm_ecc_single_error), + .dccm_ecc_double_error (rv_ecc_sts.cptra_dccm_ecc_double_error), + + .el2_icache_export (el2_icache_stub.veer_icache_src), + + .trace_rv_i_insn_ip (trace_rv_i_insn_ip), + .trace_rv_i_address_ip (trace_rv_i_address_ip), + .trace_rv_i_valid_ip (trace_rv_i_valid_ip), + .trace_rv_i_exception_ip(trace_rv_i_exception_ip), + .trace_rv_i_ecause_ip (trace_rv_i_ecause_ip), + .trace_rv_i_interrupt_ip(trace_rv_i_interrupt_ip), + .trace_rv_i_tval_ip (trace_rv_i_tval_ip), + + .jtag_tck ( jtag_tck ), + .jtag_tms ( jtag_tms ), + .jtag_tdi ( jtag_tdi ), + .jtag_trst_n ( jtag_trst_n ), + .jtag_tdo ( jtag_tdo ), + .jtag_tdoEn ( jtag_tdoEn ), + + .dmi_core_enable ( cptra_core_dmi_enable ), + // DMI port for uncore + .dmi_uncore_enable( cptra_uncore_dmi_enable ), + .dmi_uncore_en ( cptra_uncore_dmi_reg_en ), + .dmi_uncore_wr_en ( cptra_uncore_dmi_reg_wr_en ), + .dmi_uncore_addr ( cptra_uncore_dmi_reg_addr ), + .dmi_uncore_wdata ( cptra_uncore_dmi_reg_wdata ), + .dmi_uncore_rdata ( cptra_uncore_dmi_reg_rdata ), + .dmi_active ( cptra_dmi_reg_en_preQ ), + + .mpc_debug_halt_ack ( mpc_debug_halt_ack), + .mpc_debug_halt_req ( 1'b0), + .mpc_debug_run_ack ( mpc_debug_run_ack), + .mpc_debug_run_req ( 1'b1), + .mpc_reset_run_req ( 1'b1), // Start running after reset + .debug_brkpt_status (debug_brkpt_status), + + .i_cpu_halt_req ( 1'b0 ), // Async halt req to CPU + .o_cpu_halt_ack ( o_cpu_halt_ack ), // core response to halt + .o_cpu_halt_status ( o_cpu_halt_status ), // 1'b1 indicates core is halted + .i_cpu_run_req ( 1'b0 ), // Async restart req to CPU + .o_debug_mode_status (o_debug_mode_status), + .o_cpu_run_ack ( o_cpu_run_ack ), // Core response to run req + + .dec_tlu_perfcnt0 (), + .dec_tlu_perfcnt1 (), + .dec_tlu_perfcnt2 (), + .dec_tlu_perfcnt3 (), + + // Caliptra Memory Export Interface + .el2_mem_export (el2_mem_export), + + .core_id ('0), + .scan_mode ( scan_mode ), // To enable scan mode + .mbist_mode ( 1'b0 ) // to enable mbist + +); + // Duplicate ICCM/DCCM accesses, using only hsel to differentiate + always_comb responder_inst[`CALIPTRA_SLAVE_SEL_IDMA].hrdata = responder_inst[`CALIPTRA_SLAVE_SEL_DDMA].hrdata; + always_comb responder_inst[`CALIPTRA_SLAVE_SEL_IDMA].hresp = responder_inst[`CALIPTRA_SLAVE_SEL_DDMA].hresp; + always_comb responder_inst[`CALIPTRA_SLAVE_SEL_IDMA].hreadyout = responder_inst[`CALIPTRA_SLAVE_SEL_DDMA].hreadyout; + + // SB and LSU AHB master mux + ahb_lite_2to1_mux #( + .AHB_LITE_ADDR_WIDTH (`CALIPTRA_AHB_HADDR_SIZE), + .AHB_LITE_DATA_WIDTH (`CALIPTRA_AHB_HDATA_SIZE), + .AHB_NO_OPT(1) //Prevent address and data phase overlap between initiators + ) u_sb_lsu_ahb_mux ( + .hclk (clk_cg), + .hreset_n (cptra_noncore_rst_b), + .force_bus_idle (fw_update_rst_window), + // Initiator 0 + .hsel_i_0 (1'b1 ), + .haddr_i_0 (lsu_ahb.haddr ), + .hwdata_i_0 (lsu_ahb.hwdata), + .hwrite_i_0 (lsu_ahb.hwrite), + .htrans_i_0 (lsu_ahb.htrans), + .hsize_i_0 (lsu_ahb.hsize ), + .hready_i_0 (1'b1 ), + .hresp_o_0 (lsu_ahb.hresp ), + .hready_o_0 (lsu_ahb.hready), + .hrdata_o_0 (lsu_ahb.hrdata), + + // Initiator 1 + .hsel_i_1 (1'b1 ), + .haddr_i_1 (sb_ahb.haddr ), + .hwdata_i_1 (sb_ahb.hwdata ), + .hwrite_i_1 (sb_ahb.hwrite ), + .htrans_i_1 (sb_ahb.htrans ), + .hsize_i_1 (sb_ahb.hsize ), + .hready_i_1 (1'b1 ), + .hresp_o_1 (sb_ahb.hresp ), + .hready_o_1 (sb_ahb.hready ), + .hrdata_o_1 (sb_ahb.hrdata ), + + // Responder + .hsel_o (initiator_inst.hsel ), + .haddr_o (initiator_inst.haddr ), + .hwdata_o (initiator_inst.hwdata), + .hwrite_o (initiator_inst.hwrite), + .htrans_o (initiator_inst.htrans), + .hsize_o (initiator_inst.hsize ), + .hready_o (initiator_inst.hready), + .hresp_i (initiator_inst.hresp ), + .hreadyout_i (initiator_inst.hreadyout), + .hrdata_i (initiator_inst.hrdata) + ); + + // Security State value captured on a Caliptra reset deassertion + // Security State can be unlocked by setting ss_dbg_manuf_enable or ss_soc_dbg_unlock_level[0] + always_ff @(posedge clk or negedge cptra_noncore_rst_b) begin + if (~cptra_noncore_rst_b) begin + unlock_caliptra_security_state <= 1; + end + else begin + unlock_caliptra_security_state <= ss_dbg_manuf_enable || ss_soc_dbg_unlock_level[0]; + end + end + + always_ff @(posedge clk or negedge cptra_noncore_rst_b) begin + if (~cptra_noncore_rst_b) begin //Setting the default value to be debug locked and in production mode + cptra_security_state_Latched_d <= '{device_lifecycle: DEVICE_PRODUCTION, debug_locked: 1'b1}; + cptra_security_state_Latched_f <= '{device_lifecycle: DEVICE_PRODUCTION, debug_locked: 1'b1}; + end + else if (unlock_caliptra_security_state) begin //capture the new value at reset or when unlocked + cptra_security_state_Latched_d <= security_state; + cptra_security_state_Latched_f <= cptra_security_state_Latched_d; + end else begin //hold the previous value when locked + cptra_security_state_Latched_d <= cptra_security_state_Latched_d; + cptra_security_state_Latched_f <= cptra_security_state_Latched_d; + end + end + + always_ff @(posedge clk or negedge cptra_pwrgood) begin + if (~cptra_pwrgood) begin + cptra_scan_mode_Latched_d <= '0; + cptra_scan_mode_Latched_f <= '0; + end + else begin + cptra_scan_mode_Latched_d <= scan_mode; + cptra_scan_mode_Latched_f <= cptra_scan_mode_Latched_d; + end + end + + //Lock debug unless both flops are unlocked + always_comb cptra_security_state_Latched.debug_locked = cptra_security_state_Latched_d.debug_locked | cptra_security_state_Latched_f.debug_locked; + //Pass on the latched value of device lifecycle + always_comb cptra_security_state_Latched.device_lifecycle = cptra_security_state_Latched_f.device_lifecycle; + //Only assert scan mode once both flops have set + always_comb cptra_scan_mode_Latched = cptra_scan_mode_Latched_d & cptra_scan_mode_Latched_f; + + // When scan mode goes from 0->1, generate a pulse to clear the assets + // Note that when scan goes to '1, Caliptra state as well as SOC state + // gets messed up. So switch to scan is destructive (obvious! Duh!) + always_comb scan_mode_switch = cptra_scan_mode_Latched_d & ~cptra_scan_mode_Latched_f; + // Detect transition of debug mode + always_comb debug_lock_switch = cptra_security_state_Latched_d.debug_locked ^ cptra_security_state_Latched_f.debug_locked; + // Detect transition from valid lifecycle state to invalid + always_comb device_lifecycle_switch = (cptra_security_state_Latched_f.device_lifecycle inside {DEVICE_MANUFACTURING, DEVICE_PRODUCTION}) & + ~(cptra_security_state_Latched_d.device_lifecycle inside {DEVICE_MANUFACTURING, DEVICE_PRODUCTION}); + + assign debug_lock_or_scan_mode_switch = debug_lock_switch | scan_mode_switch | device_lifecycle_switch | cptra_error_fatal; + + assign clear_obf_secrets_debugScanQ = clear_obf_secrets | cptra_in_debug_scan_mode | cptra_error_fatal; + + + //capture incoming CSR HMAC key + always_ff @(posedge clk or negedge cptra_noncore_rst_b) begin + if (~cptra_noncore_rst_b) begin + cptra_csr_hmac_key_reg <= '0; + end + //Only latch the value during device manufacturing + else if (cptra_security_state_Latched.device_lifecycle == DEVICE_MANUFACTURING) begin + cptra_csr_hmac_key_reg <= cptra_csr_hmac_key; + end + else begin + cptra_csr_hmac_key_reg <= '0; + end + end + +//=========================================================================- +// Clock gating instance +//=========================================================================- +always_ff@(posedge clk or negedge cptra_rst_b) begin + if (!cptra_rst_b) begin + s_axi_active <= '0; + end + else begin + case ({s_axi_r_if.rvalid && s_axi_r_if.rready && s_axi_r_if.rlast, + s_axi_r_if.arvalid && s_axi_r_if.arready, + s_axi_w_if.bvalid && s_axi_w_if.bready, + s_axi_w_if.awvalid && s_axi_w_if.awready}) inside + 4'b0000: s_axi_active <= s_axi_active ; + 4'b0001: s_axi_active <= s_axi_active + 3'd1; + 4'b0010: s_axi_active <= s_axi_active - 3'd1; + 4'b0011: s_axi_active <= s_axi_active ; + 4'b0100: s_axi_active <= s_axi_active + 3'd1; + 4'b0101: s_axi_active <= s_axi_active + 3'd2; + 4'b0110: s_axi_active <= s_axi_active ; + 4'b0111: s_axi_active <= s_axi_active + 3'd1; + 4'b1000: s_axi_active <= s_axi_active - 3'd1; + 4'b1001: s_axi_active <= s_axi_active ; + 4'b1010: s_axi_active <= s_axi_active - 3'd2; + 4'b1011: s_axi_active <= s_axi_active - 3'd1; + 4'b1100: s_axi_active <= s_axi_active ; + 4'b1101: s_axi_active <= s_axi_active + 3'd1; + 4'b1110: s_axi_active <= s_axi_active - 3'd1; + 4'b1111: s_axi_active <= s_axi_active ; + endcase + end +end + +clk_gate cg ( + .clk(clk), + .cptra_rst_b(cptra_noncore_rst_b), + .psel(|s_axi_active || s_axi_r_if.arvalid || s_axi_w_if.awvalid), + .clk_gate_en(clk_gating_en), + .cpu_halt_status(o_cpu_halt_status), + .rdc_clk_dis(rdc_clk_dis), + .rdc_clk_dis_uc (fw_update_rst_window), + .clk_cg (clk_cg), + .soc_ifc_clk_cg (soc_ifc_clk_cg), + .rdc_clk_cg (rdc_clk_cg), + .uc_clk_cg (uc_clk_cg), + .generic_input_wires(generic_input_wires), + .cptra_error_fatal(cptra_error_fatal), + .cptra_in_debug_scan_mode(cptra_in_debug_scan_mode), + .cptra_dmi_reg_en_preQ(cptra_dmi_reg_en_preQ) +); +//=========================================================================- +// AHB I$ instance +//=========================================================================- + + // Instantiate AHB Lite Address Decoder +ahb_lite_2to1_mux #( + .AHB_LITE_ADDR_WIDTH(`CALIPTRA_IMEM_BYTE_ADDR_W), + .AHB_LITE_DATA_WIDTH(`CALIPTRA_IMEM_DATA_WIDTH) +) u_ahb_lite_2to1_mux ( + .hclk (clk_cg), + .hreset_n (cptra_uc_rst_b), + .force_bus_idle (fw_update_rst_window), + // From Initiator 0 + // Inputs + .hsel_i_0 (responder_inst[`CALIPTRA_SLAVE_SEL_IMEM].hsel), + .haddr_i_0 (responder_inst[`CALIPTRA_SLAVE_SEL_IMEM].haddr[`CALIPTRA_IMEM_BYTE_ADDR_W-1:0]), + .hwdata_i_0 ('0), + .hwrite_i_0 (responder_inst[`CALIPTRA_SLAVE_SEL_IMEM].hwrite), + .htrans_i_0 (responder_inst[`CALIPTRA_SLAVE_SEL_IMEM].htrans), + .hsize_i_0 (responder_inst[`CALIPTRA_SLAVE_SEL_IMEM].hsize), + .hready_i_0 (responder_inst[`CALIPTRA_SLAVE_SEL_IMEM].hready), + // Outputs + .hresp_o_0 (responder_inst[`CALIPTRA_SLAVE_SEL_IMEM].hresp), + .hready_o_0 (responder_inst[`CALIPTRA_SLAVE_SEL_IMEM].hreadyout), + .hrdata_o_0 (responder_inst[`CALIPTRA_SLAVE_SEL_IMEM].hrdata), + // From Initiator 1 + // Inputs + .hsel_i_1 (1'b1), + .haddr_i_1 (ic_haddr[`CALIPTRA_IMEM_BYTE_ADDR_W-1:0]), + .hwdata_i_1 ('0), + .hwrite_i_1 (ic_hwrite), + .htrans_i_1 (ic_htrans), + .hsize_i_1 (ic_hsize), + .hready_i_1 (1'b1), + // Outputs + .hresp_o_1 (ic_hresp), + .hready_o_1 (ic_hready), + .hrdata_o_1 (ic_hrdata), + // To Responder + // Inputs + .hresp_i (imem_hresp), + .hrdata_i (imem_hrdata), + .hreadyout_i (imem_hreadyout), + // Outputs + .haddr_o (imem_haddr[`CALIPTRA_IMEM_BYTE_ADDR_W-1:0]), + .hwdata_o ( ), + .hsel_o (imem_hsel), + .hwrite_o (imem_hwrite), + .hready_o (imem_hready), + .htrans_o (imem_htrans), + .hsize_o (imem_hsize) +); + +caliptra_ahb_srom #( + .AHB_DATA_WIDTH(`CALIPTRA_IMEM_DATA_WIDTH), + .AHB_ADDR_WIDTH(`CALIPTRA_IMEM_BYTE_ADDR_W), + .CLIENT_ADDR_WIDTH(`CALIPTRA_IMEM_ADDR_WIDTH) +) imem ( + + //AMBA AHB Lite INF + .hclk (clk_cg), + .hreset_n (cptra_uc_rst_b), + .haddr_i (imem_haddr[`CALIPTRA_IMEM_BYTE_ADDR_W-1:0]), + .hwdata_i (`CALIPTRA_IMEM_DATA_WIDTH'(0) ), + .hsel_i (imem_hsel), + .hwrite_i (imem_hwrite), + + .hready_i (imem_hready), + .htrans_i (imem_htrans), + .hsize_i (imem_hsize), + + + .hresp_o (imem_hresp), + .hreadyout_o(imem_hreadyout), + .hrdata_o (imem_hrdata), + + .cs (imem_cs), + .addr (imem_addr), + .rdata (imem_rdata) + +); + +sha512_ctrl #( + .AHB_DATA_WIDTH (`CALIPTRA_AHB_HDATA_SIZE), + .AHB_ADDR_WIDTH (`CALIPTRA_SLAVE_ADDR_WIDTH(`CALIPTRA_SLAVE_SEL_SHA512)) +) sha512 ( + .clk (clk_cg), + .reset_n (cptra_noncore_rst_b), + .cptra_pwrgood (cptra_pwrgood), + .haddr_i (responder_inst[`CALIPTRA_SLAVE_SEL_SHA512].haddr[`CALIPTRA_SLAVE_ADDR_WIDTH(`CALIPTRA_SLAVE_SEL_SHA512)-1:0]), + .hwdata_i (responder_inst[`CALIPTRA_SLAVE_SEL_SHA512].hwdata), + .hsel_i (responder_inst[`CALIPTRA_SLAVE_SEL_SHA512].hsel), + .hwrite_i (responder_inst[`CALIPTRA_SLAVE_SEL_SHA512].hwrite), + .hready_i (responder_inst[`CALIPTRA_SLAVE_SEL_SHA512].hready), + .htrans_i (responder_inst[`CALIPTRA_SLAVE_SEL_SHA512].htrans), + .hsize_i (responder_inst[`CALIPTRA_SLAVE_SEL_SHA512].hsize), + .hresp_o (responder_inst[`CALIPTRA_SLAVE_SEL_SHA512].hresp), + .hreadyout_o (responder_inst[`CALIPTRA_SLAVE_SEL_SHA512].hreadyout), + .hrdata_o (responder_inst[`CALIPTRA_SLAVE_SEL_SHA512].hrdata), + .pv_read (pv_read), + .pv_write (pv_write), + .pv_rd_resp (pv_rd_resp), + .pv_wr_resp (pv_wr_resp), + .pcr_signing_hash(pcr_signing_data.pcr_hash), + + .error_intr(sha512_error_intr), + .notif_intr(sha512_notif_intr), + .debugUnlock_or_scan_mode_switch(debug_lock_or_scan_mode_switch) +); + +sha256_ctrl #( + .AHB_DATA_WIDTH (`CALIPTRA_AHB_HDATA_SIZE), + .AHB_ADDR_WIDTH (`CALIPTRA_SLAVE_ADDR_WIDTH(`CALIPTRA_SLAVE_SEL_SHA256)) +) sha256 ( + .clk (clk_cg), + .reset_n (cptra_noncore_rst_b), + .cptra_pwrgood (cptra_pwrgood), + .haddr_i (responder_inst[`CALIPTRA_SLAVE_SEL_SHA256].haddr[`CALIPTRA_SLAVE_ADDR_WIDTH(`CALIPTRA_SLAVE_SEL_SHA256)-1:0]), + .hwdata_i (responder_inst[`CALIPTRA_SLAVE_SEL_SHA256].hwdata), + .hsel_i (responder_inst[`CALIPTRA_SLAVE_SEL_SHA256].hsel), + .hwrite_i (responder_inst[`CALIPTRA_SLAVE_SEL_SHA256].hwrite), + .hready_i (responder_inst[`CALIPTRA_SLAVE_SEL_SHA256].hready), + .htrans_i (responder_inst[`CALIPTRA_SLAVE_SEL_SHA256].htrans), + .hsize_i (responder_inst[`CALIPTRA_SLAVE_SEL_SHA256].hsize), + .hresp_o (responder_inst[`CALIPTRA_SLAVE_SEL_SHA256].hresp), + .hreadyout_o (responder_inst[`CALIPTRA_SLAVE_SEL_SHA256].hreadyout), + .hrdata_o (responder_inst[`CALIPTRA_SLAVE_SEL_SHA256].hrdata), + + .error_intr(sha256_error_intr), + .notif_intr(sha256_notif_intr), + .debugUnlock_or_scan_mode_switch(debug_lock_or_scan_mode_switch) +); + +sha3_ctrl #( + .AHB_DATA_WIDTH (`CALIPTRA_AHB_HDATA_SIZE), + .AHB_ADDR_WIDTH (`CALIPTRA_SLAVE_ADDR_WIDTH(`CALIPTRA_SLAVE_SEL_SHA3)) +) sha3 ( + .clk (clk_cg), + .reset_n (cptra_noncore_rst_b), + .cptra_pwrgood (cptra_pwrgood), + .haddr_i (responder_inst[`CALIPTRA_SLAVE_SEL_SHA3].haddr[`CALIPTRA_SLAVE_ADDR_WIDTH(`CALIPTRA_SLAVE_SEL_SHA3)-1:0]), + .hwdata_i (responder_inst[`CALIPTRA_SLAVE_SEL_SHA3].hwdata), + .hsel_i (responder_inst[`CALIPTRA_SLAVE_SEL_SHA3].hsel), + .hwrite_i (responder_inst[`CALIPTRA_SLAVE_SEL_SHA3].hwrite), + .hready_i (responder_inst[`CALIPTRA_SLAVE_SEL_SHA3].hready), + .htrans_i (responder_inst[`CALIPTRA_SLAVE_SEL_SHA3].htrans), + .hsize_i (responder_inst[`CALIPTRA_SLAVE_SEL_SHA3].hsize), + .hresp_o (responder_inst[`CALIPTRA_SLAVE_SEL_SHA3].hresp), + .hreadyout_o (responder_inst[`CALIPTRA_SLAVE_SEL_SHA3].hreadyout), + .hrdata_o (responder_inst[`CALIPTRA_SLAVE_SEL_SHA3].hrdata), + .busy_o ( ), + + .error_intr(sha3_error_intr), + .notif_intr(sha3_notif_intr), + + .debugUnlock_or_scan_mode_switch(debug_lock_or_scan_mode_switch) +); + +//override device secrets with debug values in Debug, Debug Intent, or Scan Mode or any device lifecycle other than PROD and MANUF +always_comb cptra_in_debug_scan_mode = ~cptra_security_state_Latched.debug_locked | cptra_scan_mode_Latched | cptra_ss_debug_intent | + ~(cptra_security_state_Latched.device_lifecycle inside {DEVICE_PRODUCTION, DEVICE_MANUFACTURING}); +always_comb cptra_obf_key_dbg = cptra_in_debug_scan_mode ? `CLP_DEBUG_MODE_OBF_KEY : cptra_obf_key_reg; +always_comb obf_uds_seed_dbg = cptra_in_debug_scan_mode ? `CLP_DEBUG_MODE_UDS_SEED : obf_uds_seed; +always_comb obf_field_entropy_dbg = cptra_in_debug_scan_mode ? `CLP_DEBUG_MODE_FIELD_ENTROPY : obf_field_entropy; +always_comb cptra_csr_hmac_key_dbg = cptra_in_debug_scan_mode ? `CLP_DEBUG_MODE_CSR_HMAC_KEY : cptra_csr_hmac_key_reg; + +doe_ctrl #( + .AHB_DATA_WIDTH (`CALIPTRA_AHB_HDATA_SIZE), + .AHB_ADDR_WIDTH (`CALIPTRA_SLAVE_ADDR_WIDTH(`CALIPTRA_SLAVE_SEL_DOE)) +) doe ( + .clk (clk_cg), + .reset_n (cptra_noncore_rst_b), + .cptra_pwrgood (cptra_pwrgood), + .cptra_obf_key (cptra_obf_key_dbg), + .obf_uds_seed (obf_uds_seed_dbg), + .obf_field_entropy (obf_field_entropy_dbg), + .obf_hek_seed (obf_hek_seed), + .haddr_i (responder_inst[`CALIPTRA_SLAVE_SEL_DOE].haddr[`CALIPTRA_SLAVE_ADDR_WIDTH(`CALIPTRA_SLAVE_SEL_DOE)-1:0]), + .hwdata_i (responder_inst[`CALIPTRA_SLAVE_SEL_DOE].hwdata), + .hsel_i (responder_inst[`CALIPTRA_SLAVE_SEL_DOE].hsel), + .hwrite_i (responder_inst[`CALIPTRA_SLAVE_SEL_DOE].hwrite), + .hready_i (responder_inst[`CALIPTRA_SLAVE_SEL_DOE].hready), + .htrans_i (responder_inst[`CALIPTRA_SLAVE_SEL_DOE].htrans), + .hsize_i (responder_inst[`CALIPTRA_SLAVE_SEL_DOE].hsize), + .hresp_o (responder_inst[`CALIPTRA_SLAVE_SEL_DOE].hresp), + .hreadyout_o (responder_inst[`CALIPTRA_SLAVE_SEL_DOE].hreadyout), + .hrdata_o (responder_inst[`CALIPTRA_SLAVE_SEL_DOE].hrdata), + + .error_intr(doe_error_intr), + .notif_intr(doe_notif_intr), + .clear_obf_secrets(clear_obf_secrets), //Output + .busy_o(doe_busy), + .kv_write (kv_write[KV_WRITE_IDX_DOE]), + .kv_wr_resp (kv_wr_resp[KV_WRITE_IDX_DOE]), + .ocp_lock_en(ss_ocp_lock_en), + .debugUnlock_or_scan_mode_switch(debug_lock_or_scan_mode_switch) + +); + +ecc_top #( + .AHB_ADDR_WIDTH(`CALIPTRA_SLAVE_ADDR_WIDTH(`CALIPTRA_SLAVE_SEL_ECC)), + .AHB_DATA_WIDTH(`CALIPTRA_AHB_HDATA_SIZE) +) +ecc_top1 +( + .clk (clk_cg), + .reset_n (cptra_noncore_rst_b), + .cptra_pwrgood (cptra_pwrgood), + .haddr_i (responder_inst[`CALIPTRA_SLAVE_SEL_ECC].haddr[`CALIPTRA_SLAVE_ADDR_WIDTH(`CALIPTRA_SLAVE_SEL_ECC)-1:0]), + .hwdata_i (responder_inst[`CALIPTRA_SLAVE_SEL_ECC].hwdata), + .hsel_i (responder_inst[`CALIPTRA_SLAVE_SEL_ECC].hsel), + .hwrite_i (responder_inst[`CALIPTRA_SLAVE_SEL_ECC].hwrite), + .hready_i (responder_inst[`CALIPTRA_SLAVE_SEL_ECC].hready), + .htrans_i (responder_inst[`CALIPTRA_SLAVE_SEL_ECC].htrans), + .hsize_i (responder_inst[`CALIPTRA_SLAVE_SEL_ECC].hsize), + .hresp_o (responder_inst[`CALIPTRA_SLAVE_SEL_ECC].hresp), + .hreadyout_o (responder_inst[`CALIPTRA_SLAVE_SEL_ECC].hreadyout), + .hrdata_o (responder_inst[`CALIPTRA_SLAVE_SEL_ECC].hrdata), + + .kv_read (kv_read[4:3]), + .kv_rd_resp (kv_rd_resp[4:3]), + .kv_write (kv_write[KV_WRITE_IDX_ECC]), + .kv_wr_resp (kv_wr_resp[KV_WRITE_IDX_ECC]), + .pcr_signing_data(pcr_signing_data), + .ocp_lock_in_progress(ss_ocp_lock_in_progress), + .busy_o (ecc_busy), + .error_intr (ecc_error_intr), + .notif_intr (ecc_notif_intr), + .debugUnlock_or_scan_mode_switch(debug_lock_or_scan_mode_switch) +); + +hmac_ctrl #( + .AHB_DATA_WIDTH(`CALIPTRA_AHB_HDATA_SIZE), + .AHB_ADDR_WIDTH(`CALIPTRA_SLAVE_ADDR_WIDTH(`CALIPTRA_SLAVE_SEL_HMAC)) +)hmac ( + .clk(clk_cg), + .reset_n (cptra_noncore_rst_b), + .cptra_pwrgood (cptra_pwrgood), + .cptra_csr_hmac_key(cptra_csr_hmac_key_dbg), + .haddr_i (responder_inst[`CALIPTRA_SLAVE_SEL_HMAC].haddr[`CALIPTRA_SLAVE_ADDR_WIDTH(`CALIPTRA_SLAVE_SEL_HMAC)-1:0]), + .hwdata_i (responder_inst[`CALIPTRA_SLAVE_SEL_HMAC].hwdata), + .hsel_i (responder_inst[`CALIPTRA_SLAVE_SEL_HMAC].hsel), + .hwrite_i (responder_inst[`CALIPTRA_SLAVE_SEL_HMAC].hwrite), + .hready_i (responder_inst[`CALIPTRA_SLAVE_SEL_HMAC].hready), + .htrans_i (responder_inst[`CALIPTRA_SLAVE_SEL_HMAC].htrans), + .hsize_i (responder_inst[`CALIPTRA_SLAVE_SEL_HMAC].hsize), + .hresp_o (responder_inst[`CALIPTRA_SLAVE_SEL_HMAC].hresp), + .hreadyout_o (responder_inst[`CALIPTRA_SLAVE_SEL_HMAC].hreadyout), + .hrdata_o (responder_inst[`CALIPTRA_SLAVE_SEL_HMAC].hrdata), + .kv_read (kv_read[1:0]), + .kv_write (kv_write[KV_WRITE_IDX_HMAC]), + .kv_rd_resp (kv_rd_resp[1:0]), + .kv_wr_resp (kv_wr_resp[KV_WRITE_IDX_HMAC]), + .busy_o (hmac_busy), + .error_intr(hmac_error_intr), + .notif_intr(hmac_notif_intr), + .ocp_lock_in_progress(ss_ocp_lock_in_progress), + .debugUnlock_or_scan_mode_switch(debug_lock_or_scan_mode_switch) + +); + +abr_top #( + .AHB_DATA_WIDTH(`CALIPTRA_AHB_HDATA_SIZE), + .AHB_ADDR_WIDTH(`CALIPTRA_SLAVE_ADDR_WIDTH(`CALIPTRA_SLAVE_SEL_MLDSA)) +) abr_inst ( + .clk (clk_cg), + .rst_b (cptra_noncore_rst_b), + //TODO: pwrgood + .haddr_i (responder_inst[`CALIPTRA_SLAVE_SEL_MLDSA].haddr[`CALIPTRA_SLAVE_ADDR_WIDTH(`CALIPTRA_SLAVE_SEL_MLDSA)-1:0]), + .hwdata_i (responder_inst[`CALIPTRA_SLAVE_SEL_MLDSA].hwdata), + .hsel_i (responder_inst[`CALIPTRA_SLAVE_SEL_MLDSA].hsel), + .hwrite_i (responder_inst[`CALIPTRA_SLAVE_SEL_MLDSA].hwrite), + .hready_i (responder_inst[`CALIPTRA_SLAVE_SEL_MLDSA].hready), + .htrans_i (responder_inst[`CALIPTRA_SLAVE_SEL_MLDSA].htrans), + .hsize_i (responder_inst[`CALIPTRA_SLAVE_SEL_MLDSA].hsize), + .hresp_o (responder_inst[`CALIPTRA_SLAVE_SEL_MLDSA].hresp), + .hreadyout_o (responder_inst[`CALIPTRA_SLAVE_SEL_MLDSA].hreadyout), + .hrdata_o (responder_inst[`CALIPTRA_SLAVE_SEL_MLDSA].hrdata), + .kv_read ({kv_read[7:6],kv_read[2]}), + .kv_rd_resp ({kv_rd_resp[7:6],kv_rd_resp[2]}), + .kv_write (kv_write[1]), + .kv_wr_resp (kv_wr_resp[1]), + .pcr_signing_data (pcr_signing_data), + .busy_o (abr_busy), + .error_intr (abr_error_intr), + .notif_intr (abr_notif_intr), + .ocp_lock_in_progress(ss_ocp_lock_in_progress), + .debugUnlock_or_scan_mode_switch(debug_lock_or_scan_mode_switch), + .abr_memory_export (abr_memory_export) +); + + + + +aes_clp_wrapper #( + .CIF_DATA_WIDTH(CPTRA_AXI_DMA_DATA_WIDTH), + .AHB_DATA_WIDTH(`CALIPTRA_AHB_HDATA_SIZE), + .AHB_ADDR_WIDTH(`CALIPTRA_SLAVE_ADDR_WIDTH(`CALIPTRA_SLAVE_SEL_AES)) +) aes_inst ( + .clk(clk_cg), + .reset_n(cptra_noncore_rst_b), + .cptra_pwrgood(cptra_pwrgood), + + .haddr_i (responder_inst[`CALIPTRA_SLAVE_SEL_AES].haddr[`CALIPTRA_SLAVE_ADDR_WIDTH(`CALIPTRA_SLAVE_SEL_AES)-1:0]), + .hwdata_i (responder_inst[`CALIPTRA_SLAVE_SEL_AES].hwdata), + .hsel_i (responder_inst[`CALIPTRA_SLAVE_SEL_AES].hsel), + .hwrite_i (responder_inst[`CALIPTRA_SLAVE_SEL_AES].hwrite), + .hready_i (responder_inst[`CALIPTRA_SLAVE_SEL_AES].hready), + .htrans_i (responder_inst[`CALIPTRA_SLAVE_SEL_AES].htrans), + .hsize_i (responder_inst[`CALIPTRA_SLAVE_SEL_AES].hsize), + .hresp_o (responder_inst[`CALIPTRA_SLAVE_SEL_AES].hresp), + .hreadyout_o (responder_inst[`CALIPTRA_SLAVE_SEL_AES].hreadyout), + .hrdata_o (responder_inst[`CALIPTRA_SLAVE_SEL_AES].hrdata), + + + // OCP LOCK + .ocp_lock_in_progress(ss_ocp_lock_in_progress), + .key_release_key_size(ss_key_release_key_size), + // status signals + .input_ready_o(aes_input_ready), + .output_valid_o(aes_output_valid), + .status_idle_o(aes_status_idle), + + // DMA CIF IF + .dma_req_dv(aes_cif_dma_req_dv), + .dma_req_write(aes_cif_dma_req_data.write), + .dma_req_addr(aes_cif_dma_req_data.addr[`CALIPTRA_SLAVE_ADDR_WIDTH(`CALIPTRA_SLAVE_SEL_AES)-1:0]), + .dma_req_wdata(aes_cif_dma_req_data.wdata), + .dma_req_hold(aes_cif_dma_req_hold), + .dma_req_error(aes_cif_dma_req_error), + .dma_req_rdata(aes_cif_dma_req_rdata), + + + // kv interface + .kv_read (kv_read [KV_DEST_IDX_AES_KEY]), + .kv_rd_resp(kv_rd_resp[KV_DEST_IDX_AES_KEY]), + .kv_write (kv_write [KV_WRITE_IDX_AES] ), + .kv_wr_resp(kv_wr_resp[KV_WRITE_IDX_AES] ), + + .busy_o(aes_busy), + + // Interrupt + .error_intr(), + .notif_intr(), + .debugUnlock_or_scan_mode_switch(debug_lock_or_scan_mode_switch) +); + +kv #( + .AHB_ADDR_WIDTH(`CALIPTRA_SLAVE_ADDR_WIDTH(`CALIPTRA_SLAVE_SEL_KV)), + .AHB_DATA_WIDTH(`CALIPTRA_AHB_HDATA_SIZE) +) +key_vault1 +( + .clk (clk_cg), + .rst_b (cptra_noncore_rst_b), + .core_only_rst_b (cptra_uc_rst_b), + .cptra_pwrgood (cptra_pwrgood), + .fw_update_rst_window (fw_update_rst_window), + .haddr_i (responder_inst[`CALIPTRA_SLAVE_SEL_KV].haddr[`CALIPTRA_SLAVE_ADDR_WIDTH(`CALIPTRA_SLAVE_SEL_KV)-1:0]), + .hwdata_i (responder_inst[`CALIPTRA_SLAVE_SEL_KV].hwdata), + .hsel_i (responder_inst[`CALIPTRA_SLAVE_SEL_KV].hsel), + .hwrite_i (responder_inst[`CALIPTRA_SLAVE_SEL_KV].hwrite), + .hready_i (responder_inst[`CALIPTRA_SLAVE_SEL_KV].hready), + .htrans_i (responder_inst[`CALIPTRA_SLAVE_SEL_KV].htrans), + .hsize_i (responder_inst[`CALIPTRA_SLAVE_SEL_KV].hsize), + .hresp_o (responder_inst[`CALIPTRA_SLAVE_SEL_KV].hresp), + .hreadyout_o (responder_inst[`CALIPTRA_SLAVE_SEL_KV].hreadyout), + .hrdata_o (responder_inst[`CALIPTRA_SLAVE_SEL_KV].hrdata), + + .cptra_in_debug_scan_mode(cptra_in_debug_scan_mode), + .debugUnlock_or_scan_mode_switch (debug_lock_or_scan_mode_switch), + + .kv_read (kv_read), + .kv_write (kv_write), + .kv_rd_resp (kv_rd_resp), + .kv_wr_resp (kv_wr_resp), + .pcr_ecc_signing_key (pcr_signing_data.pcr_ecc_signing_privkey), + .pcr_mldsa_signing_key (pcr_signing_data.pcr_mldsa_signing_seed) +); + +pv #( + .AHB_ADDR_WIDTH(`CALIPTRA_SLAVE_ADDR_WIDTH(`CALIPTRA_SLAVE_SEL_PV)), + .AHB_DATA_WIDTH(`CALIPTRA_AHB_HDATA_SIZE) +) +pcr_vault1 +( + .clk (clk_cg), + .rst_b (cptra_noncore_rst_b), + .core_only_rst_b (cptra_uc_rst_b), + .cptra_pwrgood (cptra_pwrgood), + .fw_update_rst_window (fw_update_rst_window), + .haddr_i (responder_inst[`CALIPTRA_SLAVE_SEL_PV].haddr[`CALIPTRA_SLAVE_ADDR_WIDTH(`CALIPTRA_SLAVE_SEL_PV)-1:0]), + .hwdata_i (responder_inst[`CALIPTRA_SLAVE_SEL_PV].hwdata), + .hsel_i (responder_inst[`CALIPTRA_SLAVE_SEL_PV].hsel), + .hwrite_i (responder_inst[`CALIPTRA_SLAVE_SEL_PV].hwrite), + .hready_i (responder_inst[`CALIPTRA_SLAVE_SEL_PV].hready), + .htrans_i (responder_inst[`CALIPTRA_SLAVE_SEL_PV].htrans), + .hsize_i (responder_inst[`CALIPTRA_SLAVE_SEL_PV].hsize), + .hresp_o (responder_inst[`CALIPTRA_SLAVE_SEL_PV].hresp), + .hreadyout_o (responder_inst[`CALIPTRA_SLAVE_SEL_PV].hreadyout), + .hrdata_o (responder_inst[`CALIPTRA_SLAVE_SEL_PV].hrdata), + + .pv_read (pv_read), + .pv_write (pv_write), + .pv_rd_resp (pv_rd_resp), + .pv_wr_resp (pv_wr_resp) +); + +dv #( + .AHB_ADDR_WIDTH(`CALIPTRA_SLAVE_ADDR_WIDTH(`CALIPTRA_SLAVE_SEL_DV)), + .AHB_DATA_WIDTH(`CALIPTRA_AHB_HDATA_SIZE) +) +data_vault1 +( + .clk (clk_cg), + .rst_b (cptra_noncore_rst_b), + .core_only_rst_b (cptra_uc_rst_b), + .cptra_pwrgood (cptra_pwrgood), + .haddr_i (responder_inst[`CALIPTRA_SLAVE_SEL_DV].haddr[`CALIPTRA_SLAVE_ADDR_WIDTH(`CALIPTRA_SLAVE_SEL_DV)-1:0]), + .hwdata_i (responder_inst[`CALIPTRA_SLAVE_SEL_DV].hwdata), + .hsel_i (responder_inst[`CALIPTRA_SLAVE_SEL_DV].hsel), + .hwrite_i (responder_inst[`CALIPTRA_SLAVE_SEL_DV].hwrite), + .hready_i (responder_inst[`CALIPTRA_SLAVE_SEL_DV].hready), + .htrans_i (responder_inst[`CALIPTRA_SLAVE_SEL_DV].htrans), + .hsize_i (responder_inst[`CALIPTRA_SLAVE_SEL_DV].hsize), + .hresp_o (responder_inst[`CALIPTRA_SLAVE_SEL_DV].hresp), + .hreadyout_o (responder_inst[`CALIPTRA_SLAVE_SEL_DV].hreadyout), + .hrdata_o (responder_inst[`CALIPTRA_SLAVE_SEL_DV].hrdata) +); + +`ifdef CALIPTRA_INTERNAL_TRNG +entropy_src_hw_if_req_t entropy_src_hw_if_req; +entropy_src_hw_if_rsp_t entropy_src_hw_if_rsp; +cs_aes_halt_req_t csrng_cs_aes_halt_req; +cs_aes_halt_rsp_t csrng_cs_aes_halt_rsp; +entropy_src_rng_req_t entropy_src_rng_req; +entropy_src_rng_rsp_t entropy_src_rng_rsp; + +assign etrng_req = entropy_src_rng_req.rng_enable; +assign entropy_src_rng_rsp.rng_valid = itrng_valid; +assign entropy_src_rng_rsp.rng_b = itrng_data; + +// TODO: Revisit ports and verify connectivity + +csrng #( + .AHBDataWidth(`CALIPTRA_AHB_HDATA_SIZE), + .AHBAddrWidth(`CALIPTRA_SLAVE_ADDR_WIDTH(`CALIPTRA_SLAVE_SEL_CSRNG)) +) csrng ( + // Clock and reset connections + .clk_i (clk_cg), + .rst_ni (cptra_noncore_rst_b), + // AMBA AHB Lite Interface + .haddr_i (responder_inst[`CALIPTRA_SLAVE_SEL_CSRNG].haddr[`CALIPTRA_SLAVE_ADDR_WIDTH(`CALIPTRA_SLAVE_SEL_CSRNG)-1:0]), + .hwdata_i (responder_inst[`CALIPTRA_SLAVE_SEL_CSRNG].hwdata), + .hsel_i (responder_inst[`CALIPTRA_SLAVE_SEL_CSRNG].hsel), + .hwrite_i (responder_inst[`CALIPTRA_SLAVE_SEL_CSRNG].hwrite), + .hready_i (responder_inst[`CALIPTRA_SLAVE_SEL_CSRNG].hready), + .htrans_i (responder_inst[`CALIPTRA_SLAVE_SEL_CSRNG].htrans), + .hsize_i (responder_inst[`CALIPTRA_SLAVE_SEL_CSRNG].hsize), + .hresp_o (responder_inst[`CALIPTRA_SLAVE_SEL_CSRNG].hresp), + .hreadyout_o (responder_inst[`CALIPTRA_SLAVE_SEL_CSRNG].hreadyout), + .hrdata_o (responder_inst[`CALIPTRA_SLAVE_SEL_CSRNG].hrdata), + // OTP Interface + .otp_en_csrng_sw_app_read_i(caliptra_prim_mubi_pkg::MuBi8True), + // Lifecycle broadcast inputs + .lc_hw_debug_en_i (lc_ctrl_pkg::On), + // Entropy Interface + .entropy_src_hw_if_o (entropy_src_hw_if_req), + .entropy_src_hw_if_i (entropy_src_hw_if_rsp), + .cs_aes_halt_i (csrng_cs_aes_halt_req), + .cs_aes_halt_o (csrng_cs_aes_halt_rsp), + // Application Interfaces + .csrng_cmd_i ('0), + .csrng_cmd_o (), + // Alerts + .alert_tx_o (), + .alert_rx_i ({caliptra_prim_alert_pkg::ALERT_RX_DEFAULT, caliptra_prim_alert_pkg::ALERT_RX_DEFAULT}), + // Interrupt + .intr_cs_cmd_req_done_o (), + .intr_cs_entropy_req_o (), + .intr_cs_hw_inst_exc_o (), + .intr_cs_fatal_err_o () + ); + +entropy_src #( + .AHBDataWidth(`CALIPTRA_AHB_HDATA_SIZE), + .AHBAddrWidth(`CALIPTRA_SLAVE_ADDR_WIDTH(`CALIPTRA_SLAVE_SEL_ENTROPY_SRC)) +) entropy_src ( + .clk_i (clk_cg), + .rst_ni (cptra_noncore_rst_b), + // AMBA AHB Lite Interface + .haddr_i (responder_inst[`CALIPTRA_SLAVE_SEL_ENTROPY_SRC].haddr[`CALIPTRA_SLAVE_ADDR_WIDTH(`CALIPTRA_SLAVE_SEL_ENTROPY_SRC)-1:0]), + .hwdata_i (responder_inst[`CALIPTRA_SLAVE_SEL_ENTROPY_SRC].hwdata), + .hsel_i (responder_inst[`CALIPTRA_SLAVE_SEL_ENTROPY_SRC].hsel), + .hwrite_i (responder_inst[`CALIPTRA_SLAVE_SEL_ENTROPY_SRC].hwrite), + .hready_i (responder_inst[`CALIPTRA_SLAVE_SEL_ENTROPY_SRC].hready), + .htrans_i (responder_inst[`CALIPTRA_SLAVE_SEL_ENTROPY_SRC].htrans), + .hsize_i (responder_inst[`CALIPTRA_SLAVE_SEL_ENTROPY_SRC].hsize), + .hresp_o (responder_inst[`CALIPTRA_SLAVE_SEL_ENTROPY_SRC].hresp), + .hreadyout_o (responder_inst[`CALIPTRA_SLAVE_SEL_ENTROPY_SRC].hreadyout), + .hrdata_o (responder_inst[`CALIPTRA_SLAVE_SEL_ENTROPY_SRC].hrdata), + // OTP Interface + .otp_en_entropy_src_fw_read_i(caliptra_prim_mubi_pkg::MuBi8True), + .otp_en_entropy_src_fw_over_i(caliptra_prim_mubi_pkg::MuBi8True), + // RNG Interface + .rng_fips_o (), + // Entropy Interface + .entropy_src_hw_if_i (entropy_src_hw_if_req), + .entropy_src_hw_if_o (entropy_src_hw_if_rsp), + // RNG Interface + .entropy_src_rng_o (entropy_src_rng_req), + .entropy_src_rng_i (entropy_src_rng_rsp), + // CSRNG Interface + .cs_aes_halt_o (csrng_cs_aes_halt_req), + .cs_aes_halt_i (csrng_cs_aes_halt_rsp), + // External Health Test Interface + .entropy_src_xht_o (), + .entropy_src_xht_i (entropy_src_xht_rsp_t'('0)), + // Alerts + .alert_rx_i ({caliptra_prim_alert_pkg::ALERT_RX_DEFAULT, caliptra_prim_alert_pkg::ALERT_RX_DEFAULT}), + .alert_tx_o (), + // Interrupts + .intr_es_entropy_valid_o (), + .intr_es_health_test_failed_o (), + .intr_es_observe_fifo_ready_o (), + .intr_es_fatal_err_o () + ); + +`endif + +soc_ifc_top #( + .AHB_ADDR_WIDTH(`CALIPTRA_SLAVE_ADDR_WIDTH(`CALIPTRA_SLAVE_SEL_SOC_IFC)), + .AHB_DATA_WIDTH(`CALIPTRA_AHB_HDATA_SIZE), + .AXI_ADDR_WIDTH(`CALIPTRA_SLAVE_ADDR_WIDTH(`CALIPTRA_SLAVE_SEL_SOC_IFC)), + .AXI_DATA_WIDTH(`CALIPTRA_AXI_DATA_WIDTH), + .AXI_ID_WIDTH (`CALIPTRA_AXI_ID_WIDTH ), + .AXI_USER_WIDTH(`CALIPTRA_AXI_USER_WIDTH), + .AXIM_ADDR_WIDTH(`CALIPTRA_AXI_DMA_ADDR_WIDTH), + .AXIM_DATA_WIDTH(CPTRA_AXI_DMA_DATA_WIDTH), + .AXIM_ID_WIDTH (CPTRA_AXI_DMA_ID_WIDTH), + .AXIM_USER_WIDTH(CPTRA_AXI_DMA_USER_WIDTH) + ) +soc_ifc_top1 + ( + .clk (clk ), + .clk_cg (clk_cg ), + .soc_ifc_clk_cg(soc_ifc_clk_cg), + .rdc_clk_cg (rdc_clk_cg ), + + .cptra_pwrgood(cptra_pwrgood), + .cptra_rst_b (cptra_rst_b ), + + .ready_for_fuses(ready_for_fuses), + .ready_for_mb_processing(ready_for_mb_processing), + .ready_for_runtime(ready_for_runtime), + .mailbox_data_avail(mailbox_data_avail), + .mailbox_flow_done(mailbox_flow_done), + + .aes_input_ready, + .aes_output_valid, + .aes_status_idle, + + .aes_req_dv(aes_cif_dma_req_dv), + .aes_req_hold(aes_cif_dma_req_hold), + .aes_req_data(aes_cif_dma_req_data), + .aes_rdata(aes_cif_dma_req_rdata), + .aes_error(aes_cif_dma_req_error), + + + + .recovery_data_avail (recovery_data_avail ), + .recovery_image_activated(recovery_image_activated), + + .security_state(cptra_security_state_Latched), + + .BootFSM_BrkPoint (BootFSM_BrkPoint), + + .generic_input_wires(generic_input_wires), + .generic_output_wires(generic_output_wires), + + //SRAM interface + .mbox_sram_req(mbox_sram_req), + .mbox_sram_resp(mbox_sram_resp), + + // RV ECC Status Interface + .rv_ecc_sts(rv_ecc_sts), + + //SoC AXI Interface + .s_axi_w_if(s_axi_w_if), + .s_axi_r_if(s_axi_r_if), + + //AHB Interface with uC + .haddr_i (responder_inst[`CALIPTRA_SLAVE_SEL_SOC_IFC].haddr[`CALIPTRA_SLAVE_ADDR_WIDTH(`CALIPTRA_SLAVE_SEL_SOC_IFC)-1:0]), + .hwdata_i (responder_inst[`CALIPTRA_SLAVE_SEL_SOC_IFC].hwdata), + .hsel_i (responder_inst[`CALIPTRA_SLAVE_SEL_SOC_IFC].hsel), + .hwrite_i (responder_inst[`CALIPTRA_SLAVE_SEL_SOC_IFC].hwrite), + .hready_i (responder_inst[`CALIPTRA_SLAVE_SEL_SOC_IFC].hready), + .htrans_i (responder_inst[`CALIPTRA_SLAVE_SEL_SOC_IFC].htrans), + .hsize_i (responder_inst[`CALIPTRA_SLAVE_SEL_SOC_IFC].hsize), + .hresp_o (responder_inst[`CALIPTRA_SLAVE_SEL_SOC_IFC].hresp), + .hreadyout_o(responder_inst[`CALIPTRA_SLAVE_SEL_SOC_IFC].hreadyout), + .hrdata_o (responder_inst[`CALIPTRA_SLAVE_SEL_SOC_IFC].hrdata), + + // AXI Manager INF + .m_axi_w_if(m_axi_w_if), + .m_axi_r_if(m_axi_r_if), + + //SoC Interrupts + .cptra_error_fatal (cptra_error_fatal), + .cptra_error_non_fatal(cptra_error_non_fatal), +`ifdef CALIPTRA_INTERNAL_TRNG + .trng_req (), +`else + .trng_req (etrng_req), +`endif + // uC Interrupts + .soc_ifc_error_intr(soc_ifc_error_intr), + .soc_ifc_notif_intr(soc_ifc_notif_intr), + .sha_error_intr(sha_error_intr), + .sha_notif_intr(sha_notif_intr), + .dma_error_intr(dma_error_intr), + .dma_notif_intr(dma_notif_intr), + .timer_intr(timer_int), + + //Clear KeyVault secrets + .debugUnlock_or_scan_mode_switch(debug_lock_or_scan_mode_switch), + + //Obfuscated UDS and FE + .clear_obf_secrets(clear_obf_secrets_debugScanQ), //input - includes debug & scan modes to do the register clearing + .scan_mode(scan_mode), + .cptra_obf_key(cptra_obf_key), + .cptra_obf_key_reg(cptra_obf_key_reg), + .cptra_obf_field_entropy_vld(cptra_obf_field_entropy_vld), + .cptra_obf_field_entropy(cptra_obf_field_entropy), + .obf_field_entropy(obf_field_entropy), + .cptra_obf_uds_seed_vld(cptra_obf_uds_seed_vld), + .cptra_obf_uds_seed(cptra_obf_uds_seed), + .obf_uds_seed(obf_uds_seed), + .obf_hek_seed(obf_hek_seed), + + // kv interface + .kv_read (kv_read [KV_DEST_IDX_DMA_DATA]), + .kv_rd_resp(kv_rd_resp[KV_DEST_IDX_DMA_DATA]), + + // Subsystem mode straps + .strap_ss_caliptra_base_addr (strap_ss_caliptra_base_addr ), + .strap_ss_mci_base_addr (strap_ss_mci_base_addr ), + .strap_ss_recovery_ifc_base_addr (strap_ss_recovery_ifc_base_addr ), + .strap_ss_external_staging_area_base_addr (strap_ss_external_staging_area_base_addr ), + .strap_ss_otp_fc_base_addr (strap_ss_otp_fc_base_addr ), + .strap_ss_uds_seed_base_addr (strap_ss_uds_seed_base_addr ), + .strap_ss_key_release_base_addr (strap_ss_key_release_base_addr ), + .strap_ss_key_release_key_size (strap_ss_key_release_key_size ), + .strap_ss_prod_debug_unlock_auth_pk_hash_reg_bank_offset(strap_ss_prod_debug_unlock_auth_pk_hash_reg_bank_offset), + .strap_ss_num_of_prod_debug_unlock_auth_pk_hashes (strap_ss_num_of_prod_debug_unlock_auth_pk_hashes ), + .strap_ss_caliptra_dma_axi_user (strap_ss_caliptra_dma_axi_user ), + .strap_ss_strap_generic_0 (strap_ss_strap_generic_0 ), + .strap_ss_strap_generic_1 (strap_ss_strap_generic_1 ), + .strap_ss_strap_generic_2 (strap_ss_strap_generic_2 ), + .strap_ss_strap_generic_3 (strap_ss_strap_generic_3 ), + .ss_debug_intent (ss_debug_intent ), + .cptra_ss_debug_intent (cptra_ss_debug_intent ), + // Subsystem mode debug outputs + .ss_dbg_manuf_enable (ss_dbg_manuf_enable ), + .ss_soc_dbg_unlock_level(ss_soc_dbg_unlock_level), + + // Subsystem mode firmware execution control + .ss_generic_fw_exec_ctrl(ss_generic_fw_exec_ctrl), + + // Subsystem mode OCP LOCK status + .ss_ocp_lock_en(ss_ocp_lock_en), + .ss_ocp_lock_in_progress(ss_ocp_lock_in_progress), + .ss_key_release_key_size(ss_key_release_key_size), + + // NMI Vector + .nmi_vector(nmi_vector), + .nmi_intr(nmi_int), + // ICCM Lock + .iccm_lock (iccm_lock ), + .iccm_axs_blocked(ahb_lite_resp_access_blocked[`CALIPTRA_SLAVE_SEL_IDMA]), + //uC reset + .cptra_noncore_rst_b (cptra_noncore_rst_b), + .cptra_uc_rst_b (cptra_uc_rst_b), + //Clock gating en + .clk_gating_en(clk_gating_en), + .rdc_clk_dis(rdc_clk_dis), + .fw_update_rst_window(fw_update_rst_window), + //multiple cryptos operating at once, assert fatal error + .crypto_error(crypto_error), + //caliptra uncore jtag ports + .cptra_uncore_dmi_reg_en( cptra_uncore_dmi_reg_en ), + .cptra_uncore_dmi_reg_wr_en( cptra_uncore_dmi_reg_wr_en ), + .cptra_uncore_dmi_reg_rdata( cptra_uncore_dmi_reg_rdata ), + .cptra_uncore_dmi_reg_addr ( cptra_uncore_dmi_reg_addr ), + .cptra_uncore_dmi_reg_wdata( cptra_uncore_dmi_reg_wdata ) +); + +//TIE OFF slaves +always_comb begin: tie_off_slaves + +`ifndef CALIPTRA_INTERNAL_TRNG + responder_inst[`CALIPTRA_SLAVE_SEL_CSRNG].hresp = '0; + responder_inst[`CALIPTRA_SLAVE_SEL_CSRNG].hreadyout = '0; + responder_inst[`CALIPTRA_SLAVE_SEL_CSRNG].hrdata = '0; + responder_inst[`CALIPTRA_SLAVE_SEL_ENTROPY_SRC].hresp = '0; + responder_inst[`CALIPTRA_SLAVE_SEL_ENTROPY_SRC].hreadyout = '0; + responder_inst[`CALIPTRA_SLAVE_SEL_ENTROPY_SRC].hrdata = '0; +`endif +end + +genvar sva_i; +generate + for(sva_i= 0; sva_i<`CALIPTRA_AHB_SLAVES_NUM; sva_i=sva_i+1) + begin: gen_caliptra_asserts + `CALIPTRA_ASSERT_KNOWN(AHB_SLAVE_HADDR_X, responder_inst[sva_i].haddr, clk, !cptra_noncore_rst_b) + `CALIPTRA_ASSERT_KNOWN(AHB_SLAVE_HWDATA_X, responder_inst[sva_i].hwdata, clk, !cptra_noncore_rst_b) + `CALIPTRA_ASSERT_KNOWN(AHB_SLAVE_HSEL_X, responder_inst[sva_i].hsel, clk, !cptra_noncore_rst_b) + `CALIPTRA_ASSERT_KNOWN(AHB_SLAVE_HWRITE_X, responder_inst[sva_i].hwrite, clk, !cptra_noncore_rst_b) + `CALIPTRA_ASSERT_KNOWN(AHB_SLAVE_HREADY_X, responder_inst[sva_i].hready, clk, !cptra_noncore_rst_b) + `CALIPTRA_ASSERT_KNOWN(AHB_SLAVE_HTRANS_X, responder_inst[sva_i].htrans, clk, !cptra_noncore_rst_b) + `CALIPTRA_ASSERT_KNOWN(AHB_SLAVE_HSIZE_X, responder_inst[sva_i].hsize, clk, !cptra_noncore_rst_b) + `CALIPTRA_ASSERT_KNOWN(AHB_SLAVE_HRESP_X, responder_inst[sva_i].hresp, clk, !cptra_noncore_rst_b) + `CALIPTRA_ASSERT_KNOWN(AHB_SLAVE_HREADYOUT_X, responder_inst[sva_i].hreadyout, clk, !cptra_noncore_rst_b) + `CALIPTRA_ASSERT_KNOWN(AHB_SLAVE_HRDATA_X, responder_inst[sva_i].hreadyout ? responder_inst[sva_i].hrdata : '0, clk, !cptra_noncore_rst_b) + end +endgenerate + +`CALIPTRA_ASSERT_KNOWN(AHB_MASTER_HADDR_X, initiator_inst.haddr, clk, !cptra_noncore_rst_b) +`CALIPTRA_ASSERT_KNOWN(AHB_MASTER_HWDATA_X, initiator_inst.hwdata, clk, !cptra_noncore_rst_b) +`CALIPTRA_ASSERT_KNOWN(AHB_MASTER_HWRITE_X, initiator_inst.hwrite, clk, !cptra_noncore_rst_b) +`CALIPTRA_ASSERT_KNOWN(AHB_MASTER_HREADY_X, initiator_inst.hready, clk, !cptra_noncore_rst_b) +`CALIPTRA_ASSERT_KNOWN(AHB_MASTER_HTRANS_X, initiator_inst.htrans, clk, !cptra_noncore_rst_b) +`CALIPTRA_ASSERT_KNOWN(AHB_MASTER_HSIZE_X, initiator_inst.hsize, clk, !cptra_noncore_rst_b) +`CALIPTRA_ASSERT_KNOWN(AHB_MASTER_HRESP_X, initiator_inst.hresp, clk, !cptra_noncore_rst_b) +`CALIPTRA_ASSERT_KNOWN(AHB_MASTER_HRDATA_X, initiator_inst.hready ? initiator_inst.hrdata : '0, clk, !cptra_noncore_rst_b) +`CALIPTRA_ASSERT_NEVER(AHB_MASTER_HTRANS_BUSY, initiator_inst.htrans == 2'b01, clk, !cptra_noncore_rst_b) + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_top_cov_bind.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_top_cov_bind.sv new file mode 100644 index 0000000..fad91e0 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_top_cov_bind.sv @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. + + +module caliptra_top_cov_bind; + `ifdef FCOV + bind caliptra_top caliptra_top_cov_if i_caliptra_top_cov_if(.*); + bind caliptra_top caliptra_top_cov_props i_caliptra_top_cov_props(.*); + `endif +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_top_cov_if.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_top_cov_if.sv new file mode 100644 index 0000000..0f3f329 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_top_cov_if.sv @@ -0,0 +1,145 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. + +`ifndef VERILATOR + +interface caliptra_top_cov_if + import soc_ifc_pkg::*; + ( + input logic clk, + //SoC AXI Interface + axi_if.w_sub s_axi_w_if, + axi_if.r_sub s_axi_r_if, + input logic [63:0] generic_input_wires, + input logic cptra_rst_b, + input logic cptra_pwrgood, + input logic scan_mode, + input security_state_t security_state, + input logic cptra_error_fatal +); + + logic clk_gating_en; + logic cpu_halt_status; + logic wdt_timer1_en; + logic wdt_timer2_en; + logic nmi_int; + + assign clk_gating_en = caliptra_top.cg.clk_gate_en; + assign cpu_halt_status = caliptra_top.cg.cpu_halt_status; + assign wdt_timer1_en = caliptra_top.soc_ifc_top1.i_wdt.timer1_en; + assign wdt_timer2_en = caliptra_top.soc_ifc_top1.i_wdt.timer2_en; + assign nmi_int = caliptra_top.nmi_int; + + + covergroup caliptra_top_cov_grp @(posedge clk); + option.per_instance = 1; + + //----------------------------------------- + //WDT coverpoints + //----------------------------------------- + wdt_t1: coverpoint wdt_timer1_en; + wdt_t2: coverpoint wdt_timer2_en; + wdt_t1Xt2: cross wdt_t1, wdt_t2; + // wdt_t1t2Xwarmrst: cross wdt_t1Xt2, cptra_rst_b; + // wdt_t1t2Xcoldrst: cross wdt_t1Xt2, cptra_pwrgood; + + //----------------------------------------- + //CLK GATING coverpoints + //----------------------------------------- + axi_rd_txn: coverpoint s_axi_r_if.arvalid && s_axi_r_if.arready { + bins single_axi_rd_txn = (0 => 1 => 0); + bins b2b_axi_rd_txn = (1 [*5]); //5 rd txns in a row + } + axi_rd_rsp: coverpoint s_axi_r_if.rvalid && s_axi_r_if.rready { + bins axi_rd_hshake = {1'b1}; + bins single_axi_rd_rsp = (0 => 1 => 0); + } + axi_wr_txn: coverpoint s_axi_w_if.awvalid && s_axi_w_if.awready { + bins single_axi_wr_txn = (0 => 1 => 0); + bins b2b_axi_wr_txn = (1 [*5]); //5 wr txns in a row + } + axi_wr_rsp: coverpoint s_axi_w_if.bvalid && s_axi_w_if.bready { + bins axi_wr_hshake = {1'b1}; + bins single_axi_wr_rsp = (0 => 1 => 0); + } + axi_any_txn: coverpoint (s_axi_r_if.arvalid && s_axi_r_if.arready) || (s_axi_w_if.awvalid && s_axi_w_if.awready) { + bins single_axi_txn = (0 => 1 => 0); + bins b2b_axi_txn = (1 [*5]); //5 txns in a row + } + cg_en: coverpoint clk_gating_en; + core_asleep_value: coverpoint cpu_halt_status; + core_asleep_trans: coverpoint cpu_halt_status { + bins bin01 = (0 => 1); + bins bin10 = (1 => 0); + } + warm_rst: coverpoint cptra_rst_b; + + scan: coverpoint scan_mode; + debug: coverpoint security_state.debug_locked; + fatal_error: coverpoint cptra_error_fatal; + nmi: coverpoint nmi_int; + generic: coverpoint generic_input_wires { + bins byte0_active = generic with (|(item & (64'hFF << 0))); + bins byte1_active = generic with (|(item & (64'hFF << 8))); + bins byte2_active = generic with (|(item & (64'hFF << 16))); + bins byte3_active = generic with (|(item & (64'hFF << 24))); + bins byte4_active = generic with (|(item & (64'hFF << 32))); + bins byte5_active = generic with (|(item & (64'hFF << 40))); + bins byte6_active = generic with (|(item & (64'hFF << 48))); + bins byte7_active = generic with (|(item & (64'hFF << 56))); + } + + enXcore_asleep: cross cg_en, core_asleep_value { + ignore_bins b0 = enXcore_asleep with ((cg_en == 0) && (core_asleep_value == 1)); + } + enXcore_asleepXwarm_rst: cross enXcore_asleep, warm_rst; + enXcore_asleepXcold_rst: cross enXcore_asleep, cptra_pwrgood; + // { + // ignore_bins b0 = enXcore_asleepXwarm_rst with ((cg_en == 1) && (core_asleep_value == 1) && (warm_rst == 0)); + // } + enXcore_asleepXwdt1: cross enXcore_asleep, wdt_t1; + enXcore_asleepXwdt2: cross enXcore_asleep, wdt_t2; + + enXcore_asleepXscan: cross enXcore_asleep, scan; + enXcore_asleepXdebug: cross enXcore_asleep, debug; + enXcore_asleepXfatalerr: cross enXcore_asleep, fatal_error; + enXcore_asleepXnmi: cross enXcore_asleep, nmi; + enXcore_asleepXaxi: cross enXcore_asleep, axi_any_txn; + enXcore_asleepXgeneric: cross enXcore_asleep, generic; + endgroup + + covergroup generic_input_wires_cg(input int index) @(posedge clk); + option.per_instance = 1; + value: coverpoint generic_input_wires[index]; + transition: coverpoint generic_input_wires[index] { + bins bin01 = (0 => 1); + bins bin10 = (1 => 0); + } + endgroup + + // CLK_GATING_cov_grp CLK_GATING_cov_grp1 = new(); + // WDT_cov_grp WDT_cov_grp1 = new(); + caliptra_top_cov_grp caliptra_top_cov_grp1 = new(); + +// generic_input_wires_cg giw_cg[64]; + //foreach(giw_cg[i]) giw_cg[i] = new(generic_input_wires[i]); + generate + for(genvar i = 0; i < 64; i++) begin: GIW_LOOP + generic_input_wires_cg giw_cg = new(i); + end + endgenerate + +endinterface + +`endif diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_top_cov_props.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_top_cov_props.sv new file mode 100644 index 0000000..99cb33f --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_top_cov_props.sv @@ -0,0 +1,55 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2019 Western Digital Corporation or its affiliates. +// +// 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. +// + +// This file contains properties that define various sequences of events in KV + +module caliptra_top_cov_props(); + + `ifndef VERILATOR + + //------------------------------------------------------------------------------ + //Check that WDT was enabled before issuing warm reset + //------------------------------------------------------------------------------ + property cover_prop_wdt_t1_warmrst; + @(posedge soc_ifc_top1.i_wdt.clk) + ($rose(soc_ifc_top1.i_wdt.timer1_en) |-> ##[0:$] !soc_ifc_top1.i_wdt.cptra_rst_b); + endproperty + covprop_wdt_t1_warmrst: cover property(cover_prop_wdt_t1_warmrst); + + property cover_prop_wdt_t2_warmrst; + @(posedge soc_ifc_top1.i_wdt.clk) + ($rose(soc_ifc_top1.i_wdt.timer2_en) |-> ##[0:$] !soc_ifc_top1.i_wdt.cptra_rst_b); + endproperty + covprop_wdt_t2_warmrst: cover property(cover_prop_wdt_t2_warmrst); + + //------------------------------------------------------------------------------ + //Check that locks/clear were set before issuing cold reset + //------------------------------------------------------------------------------ + property cover_prop_wdt_t1_coldrst; + @(posedge soc_ifc_top1.clk) + ($rose(soc_ifc_top1.i_wdt.timer1_en) |=> ##[0:$] !soc_ifc_top1.cptra_pwrgood); + endproperty + covprop_wdt_t1_coldrst: cover property(cover_prop_wdt_t1_coldrst); + + property cover_prop_wdt_t2_coldrst; + @(posedge soc_ifc_top1.clk) + ($rose(soc_ifc_top1.i_wdt.timer2_en) |=> ##[0:$] !soc_ifc_top1.cptra_pwrgood); + endproperty + covprop_wdt_t2_coldrst: cover property(cover_prop_wdt_t2_coldrst); + + `endif + +endmodule \ No newline at end of file diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_top_sva.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_top_sva.sv new file mode 100644 index 0000000..78ac463 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_top_sva.sv @@ -0,0 +1,1361 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2019 Western Digital Corporation or its affiliates. +// +// 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. +// + + +`include "caliptra_macros.svh" +`include "config_defines.svh" +//`include "kv_defines_pkg.sv" +//`include "doe_defines_pkg.sv" +`ifndef CPTRA_TB_TOP_NAME + `ifdef UVMF_CALIPTRA_TOP + `define CPTRA_TB_TOP_NAME hdl_top + `else + `define CPTRA_TB_TOP_NAME caliptra_top_tb + `endif +`endif +`ifndef CPTRA_TOP_PATH + `define CPTRA_TOP_PATH `CPTRA_TB_TOP_NAME.caliptra_top_dut +`endif +`define KEYVAULT_PATH `CPTRA_TOP_PATH.key_vault1 +`define KEYVAULT_REG_PATH `KEYVAULT_PATH.kv_reg1 +`define PCRVAULT_PATH `CPTRA_TOP_PATH.pcr_vault1 +`define PCRVAULT_REG_PATH `PCRVAULT_PATH.pv_reg1 +`define DATA_VAULT_PATH `CPTRA_TOP_PATH.data_vault1 +`define DATA_VAULT_REG_PATH `DATA_VAULT_PATH.dv_reg1 +`define DOE_INST_PATH `CPTRA_TOP_PATH.doe.doe_inst +`define DOE_PATH `DOE_INST_PATH.doe_fsm1 +`define DOE_REG_PATH `DOE_INST_PATH.i_doe_reg +`define SERVICES_PATH `CPTRA_TB_TOP_NAME.tb_services_i +`define SHA512_PATH `CPTRA_TOP_PATH.sha512.sha512_inst +`define ABR_PATH `CPTRA_TOP_PATH.abr_inst.abr_ctrl_inst +`define ABR_REG_PATH `CPTRA_TOP_PATH.abr_inst.abr_reg_inst +`define HMAC_PATH `CPTRA_TOP_PATH.hmac.hmac_inst +`define HMAC_REG_PATH `HMAC_PATH.i_hmac_reg +`define ECC_PATH `CPTRA_TOP_PATH.ecc_top1.ecc_dsa_ctrl_i +`define ECC_REG_PATH `CPTRA_TOP_PATH.ecc_top1.ecc_reg1 +`define HMAC_DRBG_PATH `CPTRA_TOP_PATH.ecc_top1.ecc_dsa_ctrl_i.ecc_hmac_drbg_interface_i.hmac_drbg_i +`define SHA256_PATH `CPTRA_TOP_PATH.sha256.sha256_inst +`define SHA512_MASKED_PATH `CPTRA_TOP_PATH.ecc_top1.ecc_dsa_ctrl_i.ecc_hmac_drbg_interface_i.hmac_drbg_i.HMAC_K.u_sha512_core_h1 +`define SOC_IFC_TOP_PATH `CPTRA_TOP_PATH.soc_ifc_top1 +`define AXI_DMA_CTRL_PATH `SOC_IFC_TOP_PATH.i_axi_dma.i_axi_dma_ctrl +`define WDT_PATH `SOC_IFC_TOP_PATH.i_wdt +`define ABR_RAMS_PATH `SERVICES_PATH.abr_mem_top_inst +`define ABR_TOP_PATH `CPTRA_TOP_PATH.abr_inst +// the name 'aes_inst' is used for the top 2 layers of AES core hierarchy :/ +`define AES_CLP_PATH `CPTRA_TOP_PATH.aes_inst +`define AES_PATH `AES_CLP_PATH.aes_inst + +`define SVA_RDC_CLK `CPTRA_TOP_PATH.rdc_clk_cg +`define CPTRA_FW_UPD_RST_WINDOW `SOC_IFC_TOP_PATH.i_soc_ifc_boot_fsm.fw_update_rst_window +`ifdef UVMF_CALIPTRA_TOP + `define SVA_CLK `CPTRA_TB_TOP_NAME.clk + `define SVA_RST `CPTRA_TB_TOP_NAME.soc_ifc_subenv_soc_ifc_ctrl_agent_bus.cptra_rst_b +`else + `define SVA_CLK `CPTRA_TB_TOP_NAME.core_clk + `define SVA_RST `CPTRA_TB_TOP_NAME.cptra_rst_b +`endif +`define MLDSA_ZEROIZATION `CPTRA_TOP_PATH.abr_inst.abr_ctrl_inst.abr_reg_hwif_out.MLDSA_CTRL.ZEROIZE.value +`define MLKEM_ZEROIZATION `CPTRA_TOP_PATH.abr_inst.abr_ctrl_inst.abr_reg_hwif_out.MLKEM_CTRL.ZEROIZE.value +`define ABR_SCAN_DEBUG `CPTRA_TOP_PATH.abr_inst.debugUnlock_or_scan_mode_switch + +module caliptra_top_sva + import doe_defines_pkg::*; + import kv_defines_pkg::*; + import axi_dma_reg_pkg::*; + import keymgr_pkg::*; + (); + + //TODO: pass these parameters from their architecture into here + localparam SHA512_DIG_NUM_DWORDS = 16; //`SHA512_PATH.DIG_NUM_DWORDS; + localparam SHA512_BLOCK_NUM_DWORDS = 32; //`SHA512_PATH.BLOCK_NUM_DWORDS; + localparam MLDSA_SEED_NUM_DWORDS = 8; //`ABR_PATH.SEED_NUM_DWORDS; + localparam MLKEM_SHAREDKEY_NUM_DWORDS = 8; + localparam HMAC_KEY_NUM_DWORDS = 12; //`HMAC_PATH.KEY_NUM_DWORDS + localparam HMAC_TAG_NUM_DWORDS = 12; //`HMAC_PATH.TAG_NUM_DWORDS + localparam HMAC_BLOCK_NUM_DWORDS = 32; //`HMAC_PATH.BLOCK_NUM_DWORDS + localparam ECC_REG_NUM_DWORDS = 12; //'ECC_PATH.REG_NUM_DWORDS + localparam ECC_MEM_ADDR = 2**6; //'ECC_PATH.ecc_arith_unit_i.ram_tdp_file_i.mem.ADDR_LENGTH + localparam SHA256_DIG_NUM_DWORDS = 8; //`SHA256_PATH.DIG_NUM_DWORDS; + localparam SHA256_BLOCK_NUM_DWORDS = 16; //`SHA256_PATH.BLOCK_NUM_DWORDS; + localparam DOE_256_NUM_ROUNDS = 14; //`DOE_INST_PATH.i_doe_core_cbc.keymem.DOE_256_NUM_ROUNDS + localparam SEED_NUM_DWORDS = 8; + localparam MSG_NUM_DWORDS = 16; + localparam PRIVKEY_NUM_DWORDS = 1224; + localparam PRIVKEY_REG_NUM_DWORDS = 32; + localparam PRIVKEY_REG_RHO_NUM_DWORDS = 8; + localparam SIGNATURE_H_NUM_DWORDS = 21; + localparam VERIFY_RES_NUM_DWORDS = 16; + localparam PRIVKEY_MEM_NUM_DWORDS = PRIVKEY_NUM_DWORDS - PRIVKEY_REG_NUM_DWORDS; + localparam SIGNATURE_C_NUM_DWORDS = 16; + localparam SIGNATURE_Z_NUM_DWORDS = 1120; + localparam SIGNATURE_NUM_DWORDS = SIGNATURE_H_NUM_DWORDS + SIGNATURE_Z_NUM_DWORDS + SIGNATURE_C_NUM_DWORDS; + + localparam MLDSA_REG_RHO_P_NUM_DWORDS = PRIVKEY_REG_RHO_NUM_DWORDS; + localparam ABR_SCRATCH_REG_NUM_DWORDS = 48; + localparam MLDSA_ENTROPY_NUM_DWORDS = 16; + localparam MLDSA_SIGN_RND_NUM_DWORDS = 8; + + + //Create a flopped version of hmac kv_data_present to be used to disable tag write OCP SVAs in case result is not expected to go to KV + logic hmac_kv_data_present_f; + + always_ff @(posedge `SVA_RDC_CLK or negedge `SVA_RST) begin + if (!`SVA_RST) begin + hmac_kv_data_present_f <= 0; + end + else begin + if (`HMAC_PATH.kv_data_present) + hmac_kv_data_present_f <= 1; + else if (`HMAC_PATH.kv_write_done) + hmac_kv_data_present_f <= 0; + end + end + + //TODO: add disable condition based on doe cmd reg + DOE_lock_uds_set: assert property ( + @(posedge `SVA_RDC_CLK) + disable iff (~`SVA_RST) + $rose(`DOE_PATH.flow_done) && $past(doe_cmd_reg_t'(`DOE_PATH.doe_cmd_reg.cmd) == DOE_UDS) |=> `DOE_PATH.lock_uds_flow + ) + else $display("SVA ERROR: lock_uds_flow was not set after UDS flow"); + + //Note: lock + reset checks will use ungated clock. Using RDC clk throws the SVA off in the very first cycle where lock was 0 + //but there's no $past value to compare against. This problem doesn't exist when using ungated clk because in the first cycle, + //pwrgood is also 0, so SVA is disabled. + DOE_lock_uds_cold_reset: assert property ( + @(posedge `SVA_CLK) + ~`DOE_PATH.hard_rst_b |-> (`DOE_PATH.lock_uds_flow == 0) + ) + else $display("SVA ERROR: lock_uds_flow was not reset on hard reset"); + + DOE_lock_uds_warm_reset: assert property ( + @(posedge `SVA_CLK) + disable iff (~`DOE_PATH.rst_b && ~`DOE_PATH.hard_rst_b) + ~`DOE_PATH.rst_b |-> $past(`DOE_PATH.lock_uds_flow) == `DOE_PATH.lock_uds_flow + ) + else $display("SVA ERROR: lock_uds_flow toggled after warm reset"); + DOE_lock_fe_set: assert property ( + @(posedge `SVA_RDC_CLK) + disable iff (~`SVA_RST) + $rose(`DOE_PATH.flow_done) && $past(doe_cmd_reg_t'(`DOE_PATH.doe_cmd_reg.cmd) == DOE_FE) |=> `DOE_PATH.lock_fe_flow + ) + else $display("SVA ERROR: lock_fe_flow was not set after FE flow"); + + DOE_lock_fe_cold_reset: assert property ( + @(posedge `SVA_CLK) + ~`DOE_PATH.hard_rst_b |-> (`DOE_PATH.lock_fe_flow == 0) + ) + else $display("SVA ERROR: lock_fe_flow was not reset on hard reset"); + + DOE_lock_fe_warm_reset: assert property ( + @(posedge `SVA_CLK) + disable iff (~`DOE_PATH.rst_b && ~`DOE_PATH.hard_rst_b) + ~`DOE_PATH.rst_b |-> $past(`DOE_PATH.lock_fe_flow) == `DOE_PATH.lock_fe_flow + ) + else $display("SVA ERROR: lock_fe_flow toggled after warm reset"); + + DOE_lock_hek_set: assert property ( + @(posedge `SVA_RDC_CLK) + disable iff (~`SVA_RST) + $rose(`DOE_PATH.flow_done) && $past(doe_cmd_reg_t'(`DOE_PATH.doe_cmd_reg.cmd) == DOE_HEK) |=> `DOE_PATH.lock_hek_flow + ) + else $display("SVA ERROR: lock_hek_flow was not set after HEK flow"); + + DOE_lock_hek_cold_reset: assert property ( + @(posedge `SVA_CLK) + ~`DOE_PATH.hard_rst_b |-> (`DOE_PATH.lock_hek_flow == 0) + ) + else $display("SVA ERROR: lock_hek_flow was not reset to expected value on hard reset"); + + DOE_lock_hek_warm_reset: assert property ( + @(posedge `SVA_CLK) + disable iff (~`DOE_PATH.rst_b && ~`DOE_PATH.hard_rst_b) + ~`DOE_PATH.rst_b |-> $past(`DOE_PATH.lock_hek_flow) == `DOE_PATH.lock_hek_flow + ) + else $display("SVA ERROR: lock_hek_flow toggled after warm reset"); + + //Corner case: when clear_obf_secrets and reset events happen in the same cycle, reset deassertion will cause SVA to start checking + //But if clear_obf_secrets was already 1 (not a pulse), it expects to see status valid in the next clk, but in design, it takes an extra + //cycle to update status. Adding a 1 cycle delay to avoid this case by starting the check when reset is deasserted + DOE_clear_obf_status_valid: assert property ( + @(posedge `SVA_RDC_CLK) + disable iff (~`DOE_PATH.rst_b) + `CPTRA_TOP_PATH.clear_obf_secrets && `DOE_PATH.rst_b |=> (`DOE_REG_PATH.field_storage.DOE_STATUS.VALID.value && `DOE_REG_PATH.field_storage.DOE_STATUS.DEOBF_SECRETS_CLEARED.value) + ) + else $display("SVA ERROR: DOE STATUS valid bit not set after clear obf secrets cmd"); + + KV_haddr_valid: assert property ( + @(posedge `SVA_RDC_CLK) + disable iff (~`KEYVAULT_PATH.hsel_i) + `KEYVAULT_PATH.hsel_i |-> !$isunknown(`KEYVAULT_PATH.haddr_i) + ) + else $display("SVA ERROR: AHB address not valid in keyvault"); + + // Single comprehensive function that handles both debug modes + function automatic logic check_all_kv_debug_values(); + logic sel_value = `KEYVAULT_PATH.kv_reg_hwif_out.CLEAR_SECRETS.sel_debug_value.value; + logic [31:0] expected_value = sel_value ? CLP_DEBUG_MODE_KV_1 : CLP_DEBUG_MODE_KV_0; + + for (int entry = 0; entry < KV_NUM_KEYS; entry++) begin + for (int dword = 0; dword < KV_NUM_DWORDS; dword++) begin + if (`KEYVAULT_PATH.kv_reg1.hwif_out.KEY_ENTRY[entry][dword].data.value != expected_value) begin + //$display("SVA ERROR: KV[%0d][%0d] debug flush failed. Expected: %h, Got: %h, SelValue: %0d", + // entry, dword, expected_value, + // `KEYVAULT_PATH.kv_reg1.hwif_out.KEY_ENTRY[entry][dword].data.value, sel_value); + return 1'b0; + end + end + end + return 1'b1; + endfunction + + // Single assertion covering both debug modes + KV_debug_comprehensive: assert property ( + @(posedge `SVA_RDC_CLK) + disable iff(!`KEYVAULT_PATH.cptra_pwrgood) + + ($rose(~`CPTRA_TOP_PATH.cptra_security_state_Latched.debug_locked || + `SOC_IFC_TOP_PATH.cptra_error_fatal || + `CPTRA_TOP_PATH.cptra_scan_mode_Latched) && + `KEYVAULT_PATH.cptra_pwrgood) |=> + check_all_kv_debug_values() + ) + else $display("SVA ERROR: KV debug flush comprehensive check failed"); + + generate + for (genvar dword = 0; dword < KV_NUM_DWORDS; dword++) begin + //mlkem shared key write + if (dword < MLKEM_SHAREDKEY_NUM_DWORDS) begin + kv_mlkem_sharedkey_w_flow: assert property ( + @(posedge `SVA_RDC_CLK) + (`ABR_PATH.kv_mlkem_sharedkey_done & ~`SOC_IFC_TOP_PATH.ss_ocp_lock_in_progress) |-> (`KEYVAULT_PATH.kv_reg1.hwif_out.KEY_ENTRY[`ABR_PATH.kv_mlkem_sharedkey_write_ctrl_reg.write_entry][dword].data.value == `ABR_PATH.mlkem_sharedkey_data[dword]) + ) + else $display("SVA ERROR: MLKEM sharedkey mismatch!, 0x%04x, 0x%04x", `KEYVAULT_PATH.kv_reg1.hwif_out.KEY_ENTRY[`ABR_PATH.kv_mlkem_sharedkey_write_ctrl_reg.write_entry][dword].data.value, `ABR_PATH.mlkem_sharedkey_data[dword]); + + kv_mlkem_sharedkey_w_std_to_std_flow: assert property ( + @(posedge `SVA_RDC_CLK) + (`ABR_PATH.kv_mlkem_sharedkey_done & `SOC_IFC_TOP_PATH.ss_ocp_lock_in_progress) & + ((`ABR_PATH.kv_mlkem_sharedkey_write_metrics.kv_data0_present & `ABR_PATH.kv_mlkem_sharedkey_write_metrics.kv_data0_entry <= KV_STANDARD_SLOT_HI) | + (`ABR_PATH.kv_mlkem_sharedkey_write_metrics.kv_data1_present & `ABR_PATH.kv_mlkem_sharedkey_write_metrics.kv_data1_entry <= KV_STANDARD_SLOT_HI)) & + (`ABR_PATH.kv_mlkem_sharedkey_write_ctrl_reg.write_entry <= KV_STANDARD_SLOT_HI) |-> + `ABR_PATH.kv_mlkem_sharedkey_write_inst.kv_write_rules.write_allow & + (`KEYVAULT_PATH.kv_reg1.hwif_out.KEY_ENTRY[`ABR_PATH.kv_mlkem_sharedkey_write_ctrl_reg.write_entry][dword].data.value == `ABR_PATH.mlkem_sharedkey_data[dword]) + ) + else $display("SVA ERROR: MLKEM sharedkey mismatch for STD to STD flow in OCP LOCK mode!, 0x%04x, 0x%04x", `KEYVAULT_PATH.kv_reg1.hwif_out.KEY_ENTRY[`ABR_PATH.kv_mlkem_sharedkey_write_ctrl_reg.write_entry][dword].data.value, `ABR_PATH.mlkem_sharedkey_data[dword]); + + kv_mlkem_sharedkey_lock_to_lock_nonkv23_flow: assert property ( + @(posedge `SVA_RDC_CLK) + (`ABR_PATH.kv_mlkem_sharedkey_done & `SOC_IFC_TOP_PATH.ss_ocp_lock_in_progress) & + ((`ABR_PATH.kv_mlkem_sharedkey_write_metrics.kv_data0_present & `ABR_PATH.kv_mlkem_sharedkey_write_metrics.kv_data0_entry >= KV_OCP_LOCK_SLOT_LOW) | + (`ABR_PATH.kv_mlkem_sharedkey_write_metrics.kv_data1_present & `ABR_PATH.kv_mlkem_sharedkey_write_metrics.kv_data1_entry >= KV_OCP_LOCK_SLOT_LOW)) & + ((`ABR_PATH.kv_mlkem_sharedkey_write_ctrl_reg.write_entry >= KV_OCP_LOCK_SLOT_LOW) & + (`ABR_PATH.kv_mlkem_sharedkey_write_ctrl_reg.write_entry != OCP_LOCK_KEY_RELEASE_KV_SLOT)) |-> + `ABR_PATH.kv_mlkem_sharedkey_write_inst.kv_write_rules.write_allow & + (`KEYVAULT_PATH.kv_reg1.hwif_out.KEY_ENTRY[`ABR_PATH.kv_mlkem_sharedkey_write_ctrl_reg.write_entry][dword].data.value == `ABR_PATH.mlkem_sharedkey_data[dword]) + ) + else $display("SVA ERROR: MLKEM sharedkey mismatch for LOCK to LOCK flow in OCP LOCK mode!, 0x%04x, 0x%04x", `KEYVAULT_PATH.kv_reg1.hwif_out.KEY_ENTRY[`ABR_PATH.kv_mlkem_sharedkey_write_ctrl_reg.write_entry][dword].data.value, `ABR_PATH.mlkem_sharedkey_data[dword]); +`ifndef VERILATOR + kv_mlkem_sharedkey_kv23_flow: assert property ( + @(posedge `SVA_RDC_CLK) + (`ABR_PATH.kv_mlkem_sharedkey_done & `SOC_IFC_TOP_PATH.ss_ocp_lock_in_progress) & + ((`ABR_PATH.kv_mlkem_sharedkey_write_ctrl_reg.write_entry == OCP_LOCK_KEY_RELEASE_KV_SLOT)) |-> + ~`ABR_PATH.kv_mlkem_sharedkey_write_inst.kv_write_rules.write_allow & + $stable($past(`KEYVAULT_PATH.kv_reg1.hwif_out.KEY_ENTRY[`ABR_PATH.kv_mlkem_sharedkey_write_ctrl_reg.write_entry][dword].data.value,16)) + ) + else $display("SVA ERROR: MLKEM sharedkey mismatch for LOCK to LOCK flow in OCP LOCK mode!, 0x%04x, 0x%04x", `KEYVAULT_PATH.kv_reg1.hwif_out.KEY_ENTRY[`ABR_PATH.kv_mlkem_sharedkey_write_ctrl_reg.write_entry][dword].data.value, `ABR_PATH.mlkem_sharedkey_data[dword]); + + kv_mlkem_sharedkey_w_lock_to_std_illegal_flow: assert property ( + @(posedge `SVA_RDC_CLK) + (`ABR_PATH.kv_mlkem_sharedkey_done & `SOC_IFC_TOP_PATH.ss_ocp_lock_in_progress) & + ((`ABR_PATH.kv_mlkem_sharedkey_write_metrics.kv_data0_present & `ABR_PATH.kv_mlkem_sharedkey_write_metrics.kv_data0_entry >= KV_OCP_LOCK_SLOT_LOW) | + (`ABR_PATH.kv_mlkem_sharedkey_write_metrics.kv_data1_present & `ABR_PATH.kv_mlkem_sharedkey_write_metrics.kv_data1_entry >= KV_OCP_LOCK_SLOT_LOW)) & + (`ABR_PATH.kv_mlkem_sharedkey_write_ctrl_reg.write_entry <= KV_STANDARD_SLOT_HI) |-> + ~`ABR_PATH.kv_mlkem_sharedkey_write_inst.kv_write_rules.write_allow & + $stable($past(`KEYVAULT_PATH.kv_reg1.hwif_out.KEY_ENTRY[`ABR_PATH.kv_mlkem_sharedkey_write_ctrl_reg.write_entry][dword].data.value, 16)) + ) + else $display("SVA ERROR: Unexpected MLKEM sharedkey write to illegal slot in LOCK to STD flow in OCP LOCK mode!"); + + kv_mlkem_sharedkey_w_std_to_lock_illegal_flow: assert property ( + @(posedge `SVA_RDC_CLK) + (`ABR_PATH.kv_mlkem_sharedkey_done & `SOC_IFC_TOP_PATH.ss_ocp_lock_in_progress) & + ((`ABR_PATH.kv_mlkem_sharedkey_write_metrics.kv_data0_present & `ABR_PATH.kv_mlkem_sharedkey_write_metrics.kv_data0_entry <= KV_STANDARD_SLOT_HI) | + (`ABR_PATH.kv_mlkem_sharedkey_write_metrics.kv_data1_present & `ABR_PATH.kv_mlkem_sharedkey_write_metrics.kv_data1_entry <= KV_STANDARD_SLOT_HI)) & + (`ABR_PATH.kv_mlkem_sharedkey_write_ctrl_reg.write_entry >= KV_OCP_LOCK_SLOT_LOW) |-> + ~`ABR_PATH.kv_mlkem_sharedkey_write_inst.kv_write_rules.write_allow & + $stable($past(`KEYVAULT_PATH.kv_reg1.hwif_out.KEY_ENTRY[`ABR_PATH.kv_mlkem_sharedkey_write_ctrl_reg.write_entry][dword].data.value, 16)) + ) + else $display("SVA ERROR: Unexpected MLKEM sharedkey write to illegal slot in STD to LOCK flow in OCP LOCK mode!"); + +`endif + end + end + endgenerate + + generate + for(genvar dword = 0; dword < KV_NUM_DWORDS; dword++) begin + if (dword < MLDSA_SEED_NUM_DWORDS) begin + //mldsa seed read + kv_mldsa_seed_r_flow: assert property ( + @(posedge `SVA_RDC_CLK) + $rose(`ABR_PATH.kv_mldsa_seed_done) && (`ABR_PATH.kv_mldsa_seed_error == 0) && (dword < (`KEYVAULT_PATH.kv_reg1.hwif_out.KEY_CTRL[`ABR_PATH.kv_read[0].read_entry].last_dword.value + 1)) |-> (`SOC_IFC_TOP_PATH.ss_ocp_lock_in_progress & (`ABR_PATH.kv_read[0].read_entry == 23)) ? (`ABR_PATH.mldsa_seed_reg[dword] == '0) : (`KEYVAULT_PATH.kv_reg1.hwif_out.KEY_ENTRY[`ABR_PATH.kv_read[0].read_entry][dword].data.value == `ABR_PATH.mldsa_seed_reg[(MLDSA_SEED_NUM_DWORDS-1) - dword]) + ) + else $display("SVA ERROR: MLDSA seed mismatch!, 0x%04x, 0x%04x", `KEYVAULT_PATH.kv_reg1.hwif_out.KEY_ENTRY[`ABR_PATH.kv_read[0].read_entry][dword].data.value, `ABR_PATH.mldsa_seed_reg[(MLDSA_SEED_NUM_DWORDS-1) - dword]); + end + + //hmac block read + //If ocp_lock_in_progress = 1 && kv_read_entry == 23, block is not read + //If ocp_lock_in_progress = 0, block is read from any slot + kv_hmac_block_r_flow: assert property ( + @(posedge `SVA_RDC_CLK) + $rose(`HMAC_PATH.kv_block_done) && (`HMAC_PATH.kv_block_error == 0) && (dword < (`KEYVAULT_PATH.kv_reg1.hwif_out.KEY_CTRL[`HMAC_PATH.kv_read[1].read_entry].last_dword.value + 1)) |-> (`SOC_IFC_TOP_PATH.ss_ocp_lock_in_progress & (`HMAC_PATH.kv_read[1].read_entry == OCP_LOCK_KEY_RELEASE_KV_SLOT)) ? (`HMAC_PATH.block_reg[dword] == '0) : (`KEYVAULT_PATH.kv_reg1.hwif_out.KEY_ENTRY[`HMAC_PATH.kv_read[1].read_entry][dword].data.value == `HMAC_PATH.block_reg[dword]) + ) + else $display("SVA ERROR: HMAC384 block mismatch!, 0x%04x, 0x%04x", `KEYVAULT_PATH.kv_reg1.hwif_out.KEY_ENTRY[`HMAC_PATH.kv_read[1].read_entry][dword].data.value, `HMAC_PATH.block_reg[dword]); + + //hmac key read + //If ocp_lock_in_progress = 1 && kv_read_entry == 23, key is not read + //If ocp_lock_in_progress = 0, key is read from any slot + if (dword < HMAC_KEY_NUM_DWORDS) begin + kv_hmac_key_r_flow: assert property ( + @(posedge `SVA_RDC_CLK) + $rose(`HMAC_PATH.kv_key_done) && (`HMAC_PATH.kv_key_error == 0) && (dword < (`KEYVAULT_PATH.kv_reg1.hwif_out.KEY_CTRL[`HMAC_PATH.kv_read[0].read_entry].last_dword.value + 1))|-> (`SOC_IFC_TOP_PATH.ss_ocp_lock_in_progress & (`HMAC_PATH.kv_read[0].read_entry == OCP_LOCK_KEY_RELEASE_KV_SLOT)) ? (`HMAC_PATH.key_reg[dword] == '0) : (`KEYVAULT_PATH.kv_reg1.hwif_out.KEY_ENTRY[`HMAC_PATH.kv_read[0].read_entry][dword].data.value == `HMAC_PATH.key_reg[dword]) + ) + else $display("SVA ERROR: HMAC384 key mismatch!, 0x%04x, 0x%04x", `KEYVAULT_PATH.kv_reg1.hwif_out.KEY_ENTRY[`HMAC_PATH.kv_read[0].read_entry][dword].data.value, `HMAC_PATH.key_reg[dword]); + end + + //hmac tag write + //If KV entry != 23 && hmac reads key/block/lfsr seed from non-23 KV slot, tag is written (std_to_std or lock_to_lock) + //If KV entry != 23 && hmac reads key/block/lfsr seed from KV23 && ocp_lock_in_progress = 1, tag is not written + //If KV entry == 23 && ocp_lock_in_progress = 0, tag is written + //If KV entry == 23 && ocp_lock_in_progress = 1, tag is not written + /* + If ocp_lock_in_progress = 1: + Key read (input) Block read (input) Tag write (output) Allowed? + ------------------------------------------------------------------------------------------------------------- + STD STD STD Yes + LOCK LOCK LOCK (!= KV23) Yes + LOCK LOCK LOCK (== KV23) No + STD LOCK STD No + LOCK STD LOCK No + STD STD LOCK No + LOCK LOCK STD No + + If ocp_lock_in_progress = 0: + hmac key/block can be read from any KV entry, tag is written to any KV entry + */ + if (dword < HMAC_TAG_NUM_DWORDS) begin + kv_hmac_tag_w_flow: assert property ( + @(posedge `SVA_RDC_CLK) + (`HMAC_PATH.kv_write_done & ~`SOC_IFC_TOP_PATH.ss_ocp_lock_in_progress) |-> (`KEYVAULT_PATH.kv_reg1.hwif_out.KEY_ENTRY[`HMAC_PATH.kv_write_ctrl_reg.write_entry][dword].data.value == `HMAC_PATH.kv_reg[(`HMAC_PATH.TAG_NUM_DWORDS-1) - dword]) + ) + else $display("SVA ERROR: HMAC384 tag mismatch!, 0x%04x, 0x%04x", `KEYVAULT_PATH.kv_reg1.hwif_out.KEY_ENTRY[`HMAC_PATH.kv_write_ctrl_reg.write_entry][dword].data.value, `HMAC_PATH.kv_reg[(`HMAC_PATH.TAG_NUM_DWORDS-1) - dword]); + + kv_hmac_tag_w_std_to_std_flow: assert property ( + @(posedge `SVA_RDC_CLK) + disable iff (!hmac_kv_data_present_f) + (`HMAC_PATH.kv_write_done & `SOC_IFC_TOP_PATH.ss_ocp_lock_in_progress) & (`HMAC_PATH.kv_read[0].read_entry <= KV_STANDARD_SLOT_HI) & (`HMAC_PATH.kv_read[1].read_entry <= KV_STANDARD_SLOT_HI) & (`HMAC_PATH.kv_write_ctrl_reg.write_entry <= KV_STANDARD_SLOT_HI) |-> `HMAC_PATH.hmac_result_kv_write.kv_write_rules.write_allow & (`KEYVAULT_PATH.kv_reg1.hwif_out.KEY_ENTRY[`HMAC_PATH.kv_write_ctrl_reg.write_entry][dword].data.value == `HMAC_PATH.kv_reg[(`HMAC_PATH.TAG_NUM_DWORDS-1) - dword]) + ) + else $display("SVA ERROR: HMAC384 tag mismatch for STD to STD flow in OCP LOCK mode!, 0x%04x, 0x%04x", `KEYVAULT_PATH.kv_reg1.hwif_out.KEY_ENTRY[`HMAC_PATH.kv_write_ctrl_reg.write_entry][dword].data.value, `HMAC_PATH.kv_reg[(`HMAC_PATH.TAG_NUM_DWORDS-1) - dword]); + kv_hmac_tag_w_lock_to_lock_nonkv23_flow: assert property ( + @(posedge `SVA_RDC_CLK) + disable iff (!hmac_kv_data_present_f) + (`HMAC_PATH.kv_write_done & `SOC_IFC_TOP_PATH.ss_ocp_lock_in_progress) & (`HMAC_PATH.kv_read[0].read_entry >= KV_OCP_LOCK_SLOT_LOW) & (`HMAC_PATH.kv_read[1].read_entry >= KV_OCP_LOCK_SLOT_LOW) & ((`HMAC_PATH.kv_write_ctrl_reg.write_entry >= KV_OCP_LOCK_SLOT_LOW) & (`HMAC_PATH.kv_write_ctrl_reg.write_entry != OCP_LOCK_KEY_RELEASE_KV_SLOT)) |-> `HMAC_PATH.hmac_result_kv_write.kv_write_rules.write_allow & (`KEYVAULT_PATH.kv_reg1.hwif_out.KEY_ENTRY[`HMAC_PATH.kv_write_ctrl_reg.write_entry][dword].data.value == `HMAC_PATH.kv_reg[(`HMAC_PATH.TAG_NUM_DWORDS-1) - dword]) + ) + else $display("SVA ERROR: HMAC384 tag mismatch for LOCK to LOCK flow in OCP LOCK mode!, 0x%04x, 0x%04x", `KEYVAULT_PATH.kv_reg1.hwif_out.KEY_ENTRY[`HMAC_PATH.kv_write_ctrl_reg.write_entry][dword].data.value, `HMAC_PATH.kv_reg[(`HMAC_PATH.TAG_NUM_DWORDS-1) - dword]); +`ifndef VERILATOR + kv_hmac_tag_w_lock_to_lock_kv23_flow: assert property ( + @(posedge `SVA_RDC_CLK) + disable iff (!hmac_kv_data_present_f) + (`HMAC_PATH.kv_write_done & `SOC_IFC_TOP_PATH.ss_ocp_lock_in_progress) & (`HMAC_PATH.kv_read[0].read_entry >= KV_OCP_LOCK_SLOT_LOW) & (`HMAC_PATH.kv_read[1].read_entry >= KV_OCP_LOCK_SLOT_LOW) & (`HMAC_PATH.kv_write_ctrl_reg.write_entry == OCP_LOCK_KEY_RELEASE_KV_SLOT) |-> ~`HMAC_PATH.hmac_result_kv_write.kv_write_rules.write_allow & $stable($past(`KEYVAULT_PATH.kv_reg1.hwif_out.KEY_ENTRY[`HMAC_PATH.kv_write_ctrl_reg.write_entry][dword].data.value,16)) + ) + else $display("SVA ERROR: Unexpected HMAC384 tag write to KV23 in LOCK to LOCK flow in OCP LOCK mode!"); + + kv_hmac_tag_w_std_to_lock_illegal_flow: assert property ( + @(posedge `SVA_RDC_CLK) + disable iff (!hmac_kv_data_present_f) + (`HMAC_PATH.kv_write_done & `SOC_IFC_TOP_PATH.ss_ocp_lock_in_progress) & (`HMAC_PATH.kv_read[0].read_entry <= KV_STANDARD_SLOT_HI) & (`HMAC_PATH.kv_read[1].read_entry <= KV_STANDARD_SLOT_HI) & (`HMAC_PATH.kv_write_ctrl_reg.write_entry >= KV_OCP_LOCK_SLOT_LOW) |-> ~`HMAC_PATH.hmac_result_kv_write.kv_write_rules.write_allow & $stable($past(`KEYVAULT_PATH.kv_reg1.hwif_out.KEY_ENTRY[`HMAC_PATH.kv_write_ctrl_reg.write_entry][dword].data.value,16)) + ) + else $display("SVA ERROR: Unexpected HMAC384 tag write to illegal slot in STD to LOCK flow in OCP LOCK mode!"); + + kv_hmac_tag_w_lock_to_std_illegal_flow: assert property ( + @(posedge `SVA_RDC_CLK) + disable iff (!hmac_kv_data_present_f) + (`HMAC_PATH.kv_write_done & `SOC_IFC_TOP_PATH.ss_ocp_lock_in_progress) & (`HMAC_PATH.kv_read[0].read_entry >= KV_OCP_LOCK_SLOT_LOW) & (`HMAC_PATH.kv_read[1].read_entry >= KV_OCP_LOCK_SLOT_LOW) & (`HMAC_PATH.kv_write_ctrl_reg.write_entry <= KV_STANDARD_SLOT_HI) |-> ~`HMAC_PATH.hmac_result_kv_write.kv_write_rules.write_allow & $stable($past(`KEYVAULT_PATH.kv_reg1.hwif_out.KEY_ENTRY[`HMAC_PATH.kv_write_ctrl_reg.write_entry][dword].data.value,16)) + ) + else $display("SVA ERROR: Unexpected HMAC384 tag write to illegal slot in LOCK to STD flow in OCP LOCK mode!"); + + +`endif + end + + // ECC + if (dword < ECC_REG_NUM_DWORDS) begin + //ecc privkey read + kv_ecc_privkey_r_flow: assert property ( + @(posedge `SVA_RDC_CLK) + $fell(`ECC_PATH.kv_privkey_write_en) && (`ECC_PATH.kv_privkey_error == 0) |-> (`SOC_IFC_TOP_PATH.ss_ocp_lock_in_progress & (`ECC_PATH.kv_read[0].read_entry == OCP_LOCK_KEY_RELEASE_KV_SLOT)) ? (`ECC_PATH.privkey_reg[dword] == '0) : (`KEYVAULT_PATH.kv_reg1.hwif_out.KEY_ENTRY[`ECC_PATH.kv_read[0].read_entry][dword].data.value == `ECC_PATH.privkey_reg[(`ECC_PATH.REG_NUM_DWORDS-1) - dword]) + ) + else $display("SVA ERROR: ECC privkey read mismatch!, 0x%04x, 0x%04x", `KEYVAULT_PATH.kv_reg1.hwif_out.KEY_ENTRY[`ECC_PATH.kv_read[0].read_entry][dword].data.value, `ECC_PATH.privkey_reg[(`ECC_PATH.REG_NUM_DWORDS-1) - dword]); + kv_ecc_seed_r_flow: assert property ( + @(posedge `SVA_RDC_CLK) + $fell(`ECC_PATH.kv_seed_write_en) && (`ECC_PATH.kv_seed_error == 0) |-> (`SOC_IFC_TOP_PATH.ss_ocp_lock_in_progress & (`ECC_PATH.kv_read[1].read_entry == OCP_LOCK_KEY_RELEASE_KV_SLOT)) ? (`ECC_PATH.seed_reg[dword] == '0) : (`KEYVAULT_PATH.kv_reg1.hwif_out.KEY_ENTRY[`ECC_PATH.kv_read[1].read_entry][dword].data.value == `ECC_PATH.seed_reg[(`ECC_PATH.REG_NUM_DWORDS-1) - dword]) + ) + else $display("SVA ERROR: ECC seed mismatch!, 0x%04x, 0x%04x", `KEYVAULT_PATH.kv_reg1.hwif_out.KEY_ENTRY[`ECC_PATH.kv_read[1].read_entry][dword].data.value, `ECC_PATH.seed_reg[(`ECC_PATH.REG_NUM_DWORDS-1) - dword]); + //ecc privkey write + kv_ecc_privkey_w_flow: assert property ( + @(posedge `SVA_RDC_CLK) + (`ECC_PATH.kv_write_done && (`ECC_PATH.kv_write_error == 0) & ~`SOC_IFC_TOP_PATH.ss_ocp_lock_in_progress) |-> (`KEYVAULT_PATH.kv_reg1.hwif_out.KEY_ENTRY[`ECC_PATH.kv_write_ctrl_reg.write_entry][dword].data.value == `ECC_PATH.kv_reg[(`ECC_PATH.REG_NUM_DWORDS-1) - dword]) + ) + else $display("SVA ERROR: ECC privkey write mismatch!, 0x%04x, 0x%04x", `KEYVAULT_PATH.kv_reg1.hwif_out.KEY_ENTRY[`ECC_PATH.kv_write_ctrl_reg.write_entry][dword].data.value, `ECC_PATH.kv_reg[(`ECC_PATH.REG_NUM_DWORDS-1) - dword]); + + kv_ecc_privkey_w_std_to_std_flow: assert property ( + @(posedge `SVA_RDC_CLK) + (`ECC_PATH.kv_write_done & `SOC_IFC_TOP_PATH.ss_ocp_lock_in_progress) & (`ECC_PATH.kv_read[1].read_entry <= KV_STANDARD_SLOT_HI) & (`ECC_PATH.kv_write_ctrl_reg.write_entry <= KV_STANDARD_SLOT_HI) |-> `ECC_PATH.ecc_privkey_kv_write.kv_write_rules.write_allow & (`KEYVAULT_PATH.kv_reg1.hwif_out.KEY_ENTRY[`ECC_PATH.kv_write_ctrl_reg.write_entry][dword].data.value == `ECC_PATH.kv_reg[(`ECC_PATH.REG_NUM_DWORDS-1) - dword]) + ) + else $display("SVA ERROR: ECC privkey mismatch for STD to STD flow in OCP LOCK mode!, 0x%04x, 0x%04x", `KEYVAULT_PATH.kv_reg1.hwif_out.KEY_ENTRY[`ECC_PATH.kv_write_ctrl_reg.write_entry][dword].data.value, `ECC_PATH.kv_reg[(`ECC_PATH.REG_NUM_DWORDS-1) - dword]); + + kv_ecc_privkey_w_lock_to_lock_nonkv23_flow: assert property ( + @(posedge `SVA_RDC_CLK) + (`ECC_PATH.kv_write_done & `SOC_IFC_TOP_PATH.ss_ocp_lock_in_progress) & (`ECC_PATH.kv_read[1].read_entry >= KV_OCP_LOCK_SLOT_LOW) & (`ECC_PATH.kv_write_ctrl_reg.write_entry >= KV_OCP_LOCK_SLOT_LOW) & (`ECC_PATH.kv_write_ctrl_reg.write_entry != OCP_LOCK_KEY_RELEASE_KV_SLOT) |-> `ECC_PATH.ecc_privkey_kv_write.kv_write_rules.write_allow & (`KEYVAULT_PATH.kv_reg1.hwif_out.KEY_ENTRY[`ECC_PATH.kv_write_ctrl_reg.write_entry][dword].data.value == `ECC_PATH.kv_reg[(`ECC_PATH.REG_NUM_DWORDS-1) - dword]) + ) + else $display("SVA ERROR: ECC privkey mismatch for LOCK to LOCK flow in OCP LOCK mode!, 0x%04x, 0x%04x", `KEYVAULT_PATH.kv_reg1.hwif_out.KEY_ENTRY[`ECC_PATH.kv_write_ctrl_reg.write_entry][dword].data.value, `ECC_PATH.kv_reg[(`ECC_PATH.REG_NUM_DWORDS-1) - dword]); +`ifndef VERILATOR + kv_ecc_privkey_w_lock_to_lock_kv23_flow: assert property ( + @(posedge `SVA_RDC_CLK) + (`ECC_PATH.kv_write_done & `SOC_IFC_TOP_PATH.ss_ocp_lock_in_progress) & (`ECC_PATH.kv_read[1].read_entry >= KV_OCP_LOCK_SLOT_LOW) & (`ECC_PATH.kv_write_ctrl_reg.write_entry >= KV_OCP_LOCK_SLOT_LOW) & (`ECC_PATH.kv_write_ctrl_reg.write_entry == OCP_LOCK_KEY_RELEASE_KV_SLOT) |-> ~`ECC_PATH.ecc_privkey_kv_write.kv_write_rules.write_allow & $stable($past(`KEYVAULT_PATH.kv_reg1.hwif_out.KEY_ENTRY[`ECC_PATH.kv_write_ctrl_reg.write_entry][dword].data.value, 16)) + ) + else $display("SVA ERROR: Unexpected ECC privkey write to KV23 in LOCK to LOCK flow in OCP LOCK mode!"); + + kv_ecc_privkey_w_std_to_lock_illegal_flow: assert property ( + @(posedge `SVA_RDC_CLK) + (`ECC_PATH.kv_write_done & `SOC_IFC_TOP_PATH.ss_ocp_lock_in_progress) & (`ECC_PATH.kv_read[1].read_entry <= KV_STANDARD_SLOT_HI) & (`ECC_PATH.kv_write_ctrl_reg.write_entry >= KV_OCP_LOCK_SLOT_LOW) |-> ~`ECC_PATH.ecc_privkey_kv_write.kv_write_rules.write_allow & $stable($past(`KEYVAULT_PATH.kv_reg1.hwif_out.KEY_ENTRY[`ECC_PATH.kv_write_ctrl_reg.write_entry][dword].data.value, 16)) + ) + else $display("SVA ERROR: Unexpected ECC privkey write to illegal slot in STD to LOCK flow in OCP LOCK mode!"); + + kv_ecc_privkey_w_lock_to_std_illegal_flow: assert property ( + @(posedge `SVA_RDC_CLK) + (`ECC_PATH.kv_write_done & `SOC_IFC_TOP_PATH.ss_ocp_lock_in_progress) & (`ECC_PATH.kv_read[1].read_entry >= KV_OCP_LOCK_SLOT_LOW) & (`ECC_PATH.kv_write_ctrl_reg.write_entry <= KV_STANDARD_SLOT_HI) |-> ~`ECC_PATH.ecc_privkey_kv_write.kv_write_rules.write_allow & $stable($past(`KEYVAULT_PATH.kv_reg1.hwif_out.KEY_ENTRY[`ECC_PATH.kv_write_ctrl_reg.write_entry][dword].data.value, 16)) + ) + else $display("SVA ERROR: Unexpected ECC privkey write to illegal slot in LOCK to STD flow in OCP LOCK mode!"); + +`endif + + + //ecc sign r + pcr_ecc_sign_r: assert property ( + @(posedge `SVA_RDC_CLK) + `SERVICES_PATH.check_pcr_ecc_signing |-> (`SERVICES_PATH.ecc_test_vector.R[dword] == `ECC_PATH.hwif_out.ECC_SIGN_R[dword].SIGN_R.value) + ) + else $display("SVA ERROR: PCR SIGNING SIGN_R mismatch!, 0x%04x, 0x%04x", `SERVICES_PATH.ecc_test_vector.R[dword], `ECC_PATH.hwif_out.ECC_SIGN_R[dword].SIGN_R.value); + + //ecc sign s + pcr_ecc_sign_s: assert property ( + @(posedge `SVA_RDC_CLK) + `SERVICES_PATH.check_pcr_ecc_signing |-> (`SERVICES_PATH.ecc_test_vector.S[dword] == `ECC_PATH.hwif_out.ECC_SIGN_S[dword].SIGN_S.value) + ) + else $display("SVA ERROR: PCR SIGNING SIGN_S mismatch!, 0x%04x, 0x%04x", `SERVICES_PATH.ecc_test_vector.S[dword], `ECC_PATH.hwif_out.ECC_SIGN_S[dword].SIGN_S.value); + end + end + endgenerate + + + //////////////////////// + // AES + + `ifndef VERILATOR + // Helper function to compare new key with old key + function automatic logic dw_all_different_or_all_same (input logic [(keymgr_pkg::KeyWidth/32)-1:0][3:0][7:0] op0, + input logic [(keymgr_pkg::KeyWidth/32)-1:0][3:0][7:0] op1); + logic same_flag = 1'b0; + logic diff_flag = 1'b0; + foreach (op0[dw]) + if (op0[dw] == op1[dw]) begin + same_flag = 1'b1; +// $display("[%t] [%m] SAME op0[%d]=0x%x op1[%d]=0x%x", $time, dw, op0[dw], dw, op1[dw]); + end + foreach (op0[dw]) + if (op0[dw] != op1[dw]) begin + diff_flag = 1'b1; +// $display("[%t] [%m] DIFF op0[%d]=0x%x op1[%d]=0x%x", $time, dw, op0[dw], dw, op1[dw]); + end + return same_flag ^ diff_flag; + endfunction + + // Enforce that every time AES reads new key from KV it either matches the old key in entirety or + // differs from old key in entirety + property aes_new_key_fully_overwrites_old_key; + logic [(keymgr_pkg::KeyWidth/32)-1:0][3:0][7:0] keymgr_key_prev; + @(posedge `SVA_RDC_CLK) disable iff (~`SVA_RST) + ($past(`AES_CLP_PATH.keymgr_key.valid) && !`AES_CLP_PATH.keymgr_key.valid, keymgr_key_prev = $past(`AES_CLP_PATH.keymgr_key.key[0])) ##0 + (!`AES_CLP_PATH.keymgr_key.valid)[*0:$] ##1 + `AES_CLP_PATH.keymgr_key.valid + |-> + (dw_all_different_or_all_same(keymgr_key_prev, `AES_CLP_PATH.keymgr_key.key[0]) == 1); + endproperty + AES_KV_rd_full_key: assert property (aes_new_key_fully_overwrites_old_key) + else $display("SVA ERROR: AES core partially read new key into keyvault and kept partial old key!"); + + // AES core contains a local reg that buffers the key when reading from KeyVault. + // Enforce that this reg is cleared to 0 when reading in a new key. + AES_KV_rd_reg_clr: assert property ( + @(posedge `SVA_RDC_CLK) + (`AES_CLP_PATH.aes_key_kv_read.write_en && `AES_CLP_PATH.aes_key_kv_read.write_offset == 0) + |=> + // dword 0 is written with new value + // Check that dwords 1:MAX are cleared to 0 + (~|`AES_CLP_PATH.kv_key_reg[(keymgr_pkg::KeyWidth/32)-1:1]) + ) + else $display("SVA ERROR: AES local reg stage for KeyVault not cleared"); + `endif + + +`ifdef CALIPTRA_MODE_SUBSYSTEM + + // Helper function to check if any key data from KEY_ENTRY[23] exists in DMA FIFO + function automatic logic key_data_exists_in_fifo(); + logic match_found; + logic [31:0] key_word; + logic [31:0] fifo_entry; + + match_found = 1'b0; + + // Check each of the 16 x 32-bit words in KEY_ENTRY[23] + for (int key_word_idx = 0; key_word_idx < 16; key_word_idx++) begin + key_word = `KEYVAULT_PATH.kv_reg_hwif_out.KEY_ENTRY[23][key_word_idx]; + + // Skip if key word is all zeros (not sensitive data) + if (key_word != '0) begin + // Search through all 128 FIFO entries + for (int fifo_idx = 0; fifo_idx < 128; fifo_idx++) begin + fifo_entry = `AXI_DMA_CTRL_PATH.i_fifo.gen_normal_fifo.storage[fifo_idx]; + + // Check if this key word matches the FIFO entry + if (fifo_entry == key_word) begin + $display("[%t] SVA ERROR: AXI DMA KV Assertion: Found key in DMA FIFO: KEY_ENTRY[23][%0d] = %h FIFO entry[%0d] = %h", $time, fifo_idx, fifo_entry, key_word_idx, key_word); + match_found = 1'b1; + break; + end + end + if (match_found) break; + end + end + + return match_found; + endfunction + + // Main assertion + property p_axi_dma_kv_data_isolation; + @(posedge `SVA_RDC_CLK) disable iff (~`SVA_RST) + + // Trigger condition: DMA FSM transitions to IDLE with KEYVAULT write route + ($rose(int'(`AXI_DMA_CTRL_PATH.ctrl_fsm_ps) == int'(axi_dma_reg__status0__axi_dma_fsm_ps__axi_dma_fsm_e__DMA_IDLE)) && + (int'(`AXI_DMA_CTRL_PATH.wr_route) == int'(axi_dma_reg__ctrl__wr_route__wr_route_e__KEYVAULT))) + + |-> + + // Check condition: No key data should exist in DMA FIFO + (!key_data_exists_in_fifo()); + + endproperty + + // Assertion instantiation + assert_axi_dma_kv_data_isolation: assert property (p_axi_dma_kv_data_isolation) + else begin + $display("SVA ERROR: AXI DMA Key Vault Data Isolation Violation: KEY_ENTRY[23] data detected in DMA FIFO after KEYVAULT operation completion"); + end + +`endif + + + `ifndef VERILATOR + generate + begin: SHA256_WNTZ_data_check + for(genvar dword = 0; dword < 8; dword++) begin + SHA256_WNTZ_data_check: assert property ( + @(posedge `SVA_RDC_CLK) + //disable iff (`CPTRA_TOP_PATH.) + (`SERVICES_PATH.WriteData == 'hdd && `SERVICES_PATH.mailbox_write) |=> ##[1:$] $rose(`SHA256_PATH.digest_valid_reg) |=> (`SHA256_PATH.digest_reg[dword] == `SERVICES_PATH.sha256_wntz_test_vector.sha256_wntz_digest[dword]) + ) + else $display("SVA ERROR: SHA256 wntz digest %h does not match expected digest %h!", `SHA256_PATH.digest_reg[dword], `SERVICES_PATH.sha256_wntz_test_vector.sha256_wntz_digest[dword]); + end //for + end //data check + endgenerate + + generate + begin: UDS_data_check + for(genvar dword = 0; dword < `CLP_OBF_UDS_DWORDS; dword++) begin + DOE_UDS_data_check: assert property ( + @(posedge `SVA_RDC_CLK) + disable iff (`CPTRA_TOP_PATH.scan_mode || !`CPTRA_TOP_PATH.security_state.debug_locked) + (`SERVICES_PATH.WriteData == 'hEC && `SERVICES_PATH.mailbox_write) |=> ##[1:$] $rose(`DOE_PATH.lock_uds_flow) |=> (`KEYVAULT_PATH.kv_reg1.hwif_out.KEY_ENTRY[`DOE_REG_PATH.hwif_out.DOE_CTRL.DEST.value][dword].data.value == `SERVICES_PATH.doe_test_vector.uds_plaintext[dword]) + + ) + else $display("SVA ERROR: DOE UDS output %h does not match plaintext %h!", `KEYVAULT_PATH.kv_reg1.hwif_out.KEY_ENTRY[`DOE_REG_PATH.hwif_out.DOE_CTRL.DEST.value][dword].data.value, `SERVICES_PATH.doe_test_vector.uds_plaintext[dword]); + end + end + endgenerate + generate + begin: FE_data_check + for(genvar dword = 0; dword < `CLP_OBF_FE_DWORDS; dword++) begin + + DOE_FE_data_check: assert property ( + @(posedge `SVA_RDC_CLK) + disable iff (`CPTRA_TOP_PATH.scan_mode || !`CPTRA_TOP_PATH.security_state.debug_locked) + (`SERVICES_PATH.WriteData == 'hED && `SERVICES_PATH.mailbox_write) |=> ##[1:$] $rose(`DOE_PATH.lock_fe_flow) |=> (`KEYVAULT_PATH.kv_reg1.hwif_out.KEY_ENTRY[`DOE_REG_PATH.hwif_out.DOE_CTRL.DEST.value][dword].data.value == `SERVICES_PATH.doe_test_vector.fe_plaintext[dword]) + ) + else $display("SVA ERROR: DOE FE output %h does not match plaintext %h!", `KEYVAULT_PATH.kv_reg1.hwif_out.KEY_ENTRY[`DOE_REG_PATH.hwif_out.DOE_CTRL.DEST.value][dword].data.value, `SERVICES_PATH.doe_test_vector.fe_plaintext[dword]); + + end + end + endgenerate + generate + begin: HEK_data_check + for(genvar dword = 0; dword < kv_defines_pkg::OCP_LOCK_HEK_NUM_DWORDS; dword++) begin + + DOE_HEK_data_check: assert property ( + @(posedge `SVA_RDC_CLK) + disable iff (`CPTRA_TOP_PATH.scan_mode || !`CPTRA_TOP_PATH.security_state.debug_locked) + (`SERVICES_PATH.WriteData == 'hD5 && `SERVICES_PATH.mailbox_write) |=> ##[1:$] $rose(`DOE_PATH.lock_hek_flow) |=> (`KEYVAULT_PATH.kv_reg1.hwif_out.KEY_ENTRY[`DOE_REG_PATH.hwif_out.DOE_CTRL.DEST.value][dword].data.value == `SERVICES_PATH.doe_test_vector.hek_plaintext[dword]) + ) + else $display("SVA ERROR: DOE HEK output %h does not match plaintext %h!", `KEYVAULT_PATH.kv_reg1.hwif_out.KEY_ENTRY[`DOE_REG_PATH.hwif_out.DOE_CTRL.DEST.value][dword].data.value, `SERVICES_PATH.doe_test_vector.hek_plaintext[dword]); + + end + end + endgenerate + `endif + + `ifndef VERILATOR + // MLDSA Checks + + // Helper function for byte swapping + function automatic logic [31:0] byte_swap(logic [31:0] data); + return {data[7:0], data[15:8], data[23:16], data[31:24]}; + endfunction + + // Function to check all private key data (registers + memory banks) + function automatic logic check_mldsa_privkey(); + // Check scratch registers (0 to PRIVKEY_REG_NUM_DWORDS-1) + for (int dword = 0; dword < PRIVKEY_REG_NUM_DWORDS; dword++) begin + logic [31:0] expected = byte_swap(`SERVICES_PATH.mldsa_test_vector.privkey[dword]); + if (`ABR_PATH.abr_scratch_reg.raw[dword] != expected) begin + $display("SVA ERROR: [MLDSA keygen] SK register %h does not match expected %h at index %h", + `ABR_PATH.abr_scratch_reg.raw[dword], expected, dword); + return 1'b0; + end + end + + // Check even memory bank (bank0) + for (int dword = 0; dword < PRIVKEY_MEM_NUM_DWORDS/2; dword++) begin + int idx = PRIVKEY_REG_NUM_DWORDS + (2*dword); + logic [31:0] expected = byte_swap(`SERVICES_PATH.mldsa_test_vector.privkey[idx]); + if (`ABR_RAMS_PATH.abr_sk_mem_bank0_inst.ram[dword] != expected) begin + $display("SVA ERROR: [MLDSA keygen] SK bank0 %h does not match expected %h at index %h", + `ABR_RAMS_PATH.abr_sk_mem_bank0_inst.ram[dword], expected, idx); + return 1'b0; + end + end + + // Check odd memory bank (bank1) + for (int dword = 0; dword < PRIVKEY_MEM_NUM_DWORDS/2; dword++) begin + int idx = PRIVKEY_REG_NUM_DWORDS + 1 + (2*dword); + logic [31:0] expected = byte_swap(`SERVICES_PATH.mldsa_test_vector.privkey[idx]); + if (`ABR_RAMS_PATH.abr_sk_mem_bank1_inst.ram[dword] != expected) begin + $display("SVA ERROR: [MLDSA keygen] SK bank1 %h does not match expected %h at index %h", + `ABR_RAMS_PATH.abr_sk_mem_bank1_inst.ram[dword], expected, idx); + return 1'b0; + end + end + + return 1'b1; + endfunction + + // Function to check all public key data (registers + memory) + function automatic logic check_mldsa_pubkey(); + // Check first 8 dwords in scratch registers + for (int dword = 0; dword < 8; dword++) begin + logic [31:0] expected = byte_swap(`SERVICES_PATH.mldsa_test_vector.pubkey[dword]); + if (`ABR_PATH.abr_scratch_reg.raw[dword] != expected) begin + $display("SVA ERROR: [MLDSA keygen] PK register %h does not match expected %h at index %h", + `ABR_PATH.abr_scratch_reg.raw[dword], expected, dword); + return 1'b0; + end + end + + // Check public key memory (64x10 array) + for (int i = 0; i < 64; i++) begin + for (int j = 0; j < 10; j++) begin + int idx = i*10 + 8 + j; + logic [31:0] expected = byte_swap(`SERVICES_PATH.mldsa_test_vector.pubkey[idx]); + logic [31:0] actual = {`ABR_RAMS_PATH.abr_pk_mem_inst.ram[i][(j*4)+3], + `ABR_RAMS_PATH.abr_pk_mem_inst.ram[i][(j*4)+2], + `ABR_RAMS_PATH.abr_pk_mem_inst.ram[i][(j*4)+1], + `ABR_RAMS_PATH.abr_pk_mem_inst.ram[i][(j*4)+0]}; + if (actual != expected) begin + $display("SVA ERROR: [MLDSA keygen] PK memory %h does not match expected %h at index %0d %0d", + actual, expected, i, j); + return 1'b0; + end + end + end + + return 1'b1; + endfunction + + // Function to check signature data + function automatic logic check_mldsa_signature(); + // Check signature C portion (0 to SIGNATURE_C_NUM_DWORDS-1) + for (int dword = 0; dword < SIGNATURE_C_NUM_DWORDS; dword++) begin + logic [31:0] expected = byte_swap(`SERVICES_PATH.mldsa_test_vector.signature[dword]); + if (`ABR_PATH.signature_reg.raw[dword] != expected) begin + $display("SVA ERROR: [MLDSA signing] Signature C %h does not match expected %h at index %h", + `ABR_PATH.signature_reg.raw[dword], expected, dword); + return 1'b0; + end + end + + // Check signature H portion (SIGNATURE_C_NUM_DWORDS to SIGNATURE_C_NUM_DWORDS+SIGNATURE_H_NUM_DWORDS-1) + for (int dword = 0; dword < SIGNATURE_H_NUM_DWORDS; dword++) begin + int sig_idx = (SIGNATURE_NUM_DWORDS-1) - ((SIGNATURE_H_NUM_DWORDS-1) - dword); + logic [31:0] expected = byte_swap(`SERVICES_PATH.mldsa_test_vector.signature[sig_idx]); + if (`ABR_PATH.signature_reg.raw[SIGNATURE_C_NUM_DWORDS + dword] != expected) begin + $display("SVA ERROR: [MLDSA signing] Signature H %h does not match expected %h at index %h", + `ABR_PATH.signature_reg.raw[SIGNATURE_C_NUM_DWORDS + dword], expected, SIGNATURE_C_NUM_DWORDS + dword); + return 1'b0; + end + end + + // Check signature Z portion in memory (224x5 array) + for (int i = 0; i < 224; i++) begin + for (int j = 0; j < 5; j++) begin + int sig_idx = i*5+16+j; + logic [31:0] expected = byte_swap(`SERVICES_PATH.mldsa_test_vector.signature[sig_idx]); + logic [31:0] actual = {`ABR_RAMS_PATH.abr_sig_z_mem_inst.ram[i][(j*4)+3], + `ABR_RAMS_PATH.abr_sig_z_mem_inst.ram[i][(j*4)+2], + `ABR_RAMS_PATH.abr_sig_z_mem_inst.ram[i][(j*4)+1], + `ABR_RAMS_PATH.abr_sig_z_mem_inst.ram[i][(j*4)+0]}; + + if (actual != expected) begin + $display("SVA ERROR: [MLDSA signing] Sig output %h does not match expected sig %h at index %0d %0d", + actual, expected, i, j); + return 1'b0; + end + end + end + + return 1'b1; + endfunction + + // Function to check all MLDSA verify results at once + function automatic logic check_mldsa_verify_results(); + for (int dword = 0; dword < VERIFY_RES_NUM_DWORDS; dword++) begin + logic [31:0] expected = byte_swap(`SERVICES_PATH.mldsa_test_vector.verify_res[dword]); + + if (`ABR_REG_PATH.hwif_out.MLDSA_VERIFY_RES[dword] != expected) begin + $display("SVA ERROR: [MLDSA verify] Verify output %h does not match expected verify res %h at index %h", + `ABR_REG_PATH.hwif_out.MLDSA_VERIFY_RES[dword], expected, dword); + return 1'b0; + end + end + return 1'b1; + endfunction + + // Consolidated assertions + MLDSA_keygen_privkey_comprehensive: assert property ( + @(posedge `SVA_RDC_CLK) + disable iff (`CPTRA_TOP_PATH.scan_mode || !`CPTRA_TOP_PATH.security_state.debug_locked) + (((`SERVICES_PATH.mldsa_keygen || `SERVICES_PATH.mldsa_keygen_signing) && `ABR_PATH.abr_status_done) |=> + check_mldsa_privkey()) + ) + else $display("SVA ERROR: [MLDSA keygen] Private key verification failed"); + + MLDSA_keygen_pubkey_comprehensive: assert property ( + @(posedge `SVA_RDC_CLK) + disable iff (`CPTRA_TOP_PATH.scan_mode || !`CPTRA_TOP_PATH.security_state.debug_locked) + (((`SERVICES_PATH.mldsa_keygen || `SERVICES_PATH.mldsa_keygen_signing) && `ABR_PATH.abr_status_done) |=> + check_mldsa_pubkey()) + ) + else $display("SVA ERROR: [MLDSA keygen] Public key verification failed"); + + MLDSA_signature_comprehensive: assert property ( + @(posedge `SVA_RDC_CLK) + disable iff (`CPTRA_TOP_PATH.scan_mode || !`CPTRA_TOP_PATH.security_state.debug_locked || `SERVICES_PATH.disable_mldsa_sva) + (((`SERVICES_PATH.mldsa_signing || `SERVICES_PATH.mldsa_keygen_signing || `SERVICES_PATH.check_pcr_mldsa_signing) && `ABR_PATH.abr_status_done) |=> + check_mldsa_signature()) + ) + else $display("SVA ERROR: [MLDSA signing] Signature verification failed"); + + MLDSA_verify_comprehensive: assert property ( + @(posedge `SVA_RDC_CLK iff (`SERVICES_PATH.mldsa_verify || `ABR_PATH.abr_status_done)) + disable iff (`CPTRA_TOP_PATH.scan_mode || !`CPTRA_TOP_PATH.security_state.debug_locked) + ((`SERVICES_PATH.mldsa_verify && `ABR_PATH.abr_status_done) |=> + check_mldsa_verify_results()) + ) + else $display("SVA ERROR: [MLDSA verify] Verification result check failed"); + + + // MLDSA Scan, Debug and Zeroization Assertions + generate + // Check abr_scratch_reg (accessed via its raw field) word-by-word using MLDSA_PRIVKEY_REG_NUM_DWORDS + for (genvar i = 0; i < ABR_SCRATCH_REG_NUM_DWORDS; i++) begin: privkey_check + ZERO_MLDSA_K_scratch_reg_check: assert property ( + @(posedge `SVA_RDC_CLK) + ((`MLDSA_ZEROIZATION || `MLKEM_ZEROIZATION || `ABR_SCAN_DEBUG) |-> ##10 (`ABR_PATH.abr_scratch_reg.raw[i] == 0)) + ) + else $display("SVA ERROR: ABR_PATH.abr_scratch_reg.raw[%0d] is not zero", i); + end + + ZERO_MLDSA_priv_key_rd_port: assert property ( + @(posedge `SVA_RDC_CLK) + ((`MLDSA_ZEROIZATION || `MLKEM_ZEROIZATION || `ABR_SCAN_DEBUG) |-> ##10 (`ABR_PATH.api_reg_rdata == 0)) + ) + else $display("SVA ERROR: ABR_PATH.api_reg_rdata is not zero"); + + // Check seed_reg word-by-word using MLDSA_SEED_NUM_DWORDS + for (genvar i = 0; i < MLDSA_SEED_NUM_DWORDS; i++) begin: seed_check + ZERO_MLDSA_seed_reg: assert property ( + @(posedge `SVA_RDC_CLK) + ((`MLDSA_ZEROIZATION || `MLKEM_ZEROIZATION || `ABR_SCAN_DEBUG) |-> ##10 (`ABR_PATH.mldsa_seed_reg[i] == 0)) + ) + else $display("SVA ERROR: ABR_PATH.mldsa_seed_reg[%0d] is not zero", i); + end + + // Check entropy_reg word-by-word using MLDSA_ENTROPY_NUM_DWORDS + for (genvar i = 0; i < MLDSA_ENTROPY_NUM_DWORDS; i++) begin: entropy_check + ZERO_MLDSA_entropy_reg: assert property ( + @(posedge `SVA_RDC_CLK) + ((`MLDSA_ZEROIZATION || `MLKEM_ZEROIZATION || `ABR_SCAN_DEBUG) |-> ##10 (`ABR_PATH.entropy_reg[i] == 0)) + ) + else $display("SVA ERROR: ABR_PATH.entropy_reg[%0d] is not zero", i); + end + + // Check sign_rnd_reg word-by-word using MLDSA_SIGN_RND_NUM_DWORDS + for (genvar i = 0; i < MLDSA_SIGN_RND_NUM_DWORDS; i++) begin: sign_rnd_check + ZERO_MLDSA_sign_rnd_reg: assert property ( + @(posedge `SVA_RDC_CLK) + ((`MLDSA_ZEROIZATION || `MLKEM_ZEROIZATION || `ABR_SCAN_DEBUG) |-> ##10 (`ABR_PATH.sign_rnd_reg[i] == 0)) + ) + else $display("SVA ERROR: ABR_PATH.sign_rnd_reg[%0d] is not zero", i); + end + + endgenerate + // ABR_TOP_PATH Memory Interface Zeroization Assertions + generate + // skencode_mem_rd_data: 2-element array of MLDSA_MEM_DATA_WIDTH bits each. + for (genvar i = 0; i < 2; i++) begin: skencode_mem_rd_data_check + ZERO_MLDSA_skencode_mem_rd_data: assert property ( + @(posedge `SVA_RDC_CLK) + ((`MLDSA_ZEROIZATION || `MLKEM_ZEROIZATION || `ABR_SCAN_DEBUG) |-> ##10 (`ABR_TOP_PATH.skencode_mem_rd_data[i] == 0)) + ) + else $display("SVA ERROR: ABR_TOP_PATH.skencode_mem_rd_data[%0d] is not zero", i); + end + // skencode_wr_data: Single vector of DATA_WIDTH bits. + ZERO_MLDSA_skencode_wr_data: assert property ( + @(posedge `SVA_RDC_CLK) + ((`MLDSA_ZEROIZATION || `MLKEM_ZEROIZATION || `ABR_SCAN_DEBUG) |-> ##10 (`ABR_TOP_PATH.skencode_wr_data == 0)) + ) + else $display("SVA ERROR: ABR_TOP_PATH.skencode_wr_data is not zero"); + + // skdecode_mem_wr_data: 2-element array of MLDSA_MEM_DATA_WIDTH bits each. + for (genvar i = 0; i < 2; i++) begin: skdecode_mem_wr_data_check + ZERO_MLDSA_skdecode_mem_wr_data: assert property ( + @(posedge `SVA_RDC_CLK) + ((`MLDSA_ZEROIZATION || `MLKEM_ZEROIZATION || `ABR_SCAN_DEBUG) |-> ##10 (`ABR_TOP_PATH.skdecode_mem_wr_data[i] == 0)) + ) + else $display("SVA ERROR: ABR_TOP_PATH.skdecode_mem_wr_data[%0d] is not zero", i); + end + + // skdecode_rd_data: 2-element array of DATA_WIDTH bits each. + for (genvar i = 0; i < 2; i++) begin: skdecode_rd_data_check + ZERO_MLDSA_skdecode_rd_data: assert property ( + @(posedge `SVA_RDC_CLK) + ((`MLDSA_ZEROIZATION || `MLKEM_ZEROIZATION || `ABR_SCAN_DEBUG) |-> ##10 (`ABR_TOP_PATH.skdecode_rd_data[i] == 0)) + ) + else $display("SVA ERROR: ABR_TOP_PATH.skdecode_rd_data[%0d] is not zero", i); + end + + // abr_mem_rdata0_bank: 2-element array of MLDSA_MEM_DATA_WIDTH bits. + for (genvar i = 0; i < 2; i++) begin: abr_mem_rdata0_bank_check + ZERO_MLDSA_abr_mem_rdata0_bank: assert property ( + @(posedge `SVA_RDC_CLK) + ((`MLDSA_ZEROIZATION || `MLKEM_ZEROIZATION || `ABR_SCAN_DEBUG) |-> ##10 (`ABR_TOP_PATH.abr_mem_rdata0_bank[i] == 0)) + ) + else $display("SVA ERROR: ABR_TOP_PATH.abr_mem_rdata0_bank[%0d] is not zero", i); + end + + // abr_mem_wdata: Array indexed from 1 to 3, each element is MLDSA_MEM_DATA_WIDTH bits. + for (genvar i = 1; i < 3; i++) begin: abr_mem_wdata_check + ZERO_MLDSA_abr_mem_wdata: assert property ( + @(posedge `SVA_RDC_CLK) + ((`MLDSA_ZEROIZATION || `MLKEM_ZEROIZATION || `ABR_SCAN_DEBUG) |-> ##10 (`ABR_TOP_PATH.abr_mem_wdata[i] == 0)) + ) + else $display("SVA ERROR: ABR_TOP_PATH.abr_mem_wdata[%0d] is not zero", i); + end + + // abr_mem_wdata: Array indexed from 1 to 3, each element is MLDSA_MEM_DATA_WIDTH bits. + for (genvar i = 3; i <= 3; i++) begin: abr_mem_masked_wdata_check + ZERO_MLDSA_abr_mem_wdata: assert property ( + @(posedge `SVA_RDC_CLK) + ((`MLDSA_ZEROIZATION || `MLKEM_ZEROIZATION || `ABR_SCAN_DEBUG) |-> ##10 (`ABR_TOP_PATH.abr_mem_masked_wdata[i] == 0)) + ) + else $display("SVA ERROR: ABR_TOP_PATH.abr_mem_wdata[%0d] is not zero", i); + end + + // abr_mem_wdata0_bank: 2-element array of MLDSA_MEM_DATA_WIDTH bits. + for (genvar i = 0; i < 2; i++) begin: abr_mem_wdata0_bank_check + ZERO_MLDSA_abr_mem_wdata0_bank: assert property ( + @(posedge `SVA_RDC_CLK) + ((`MLDSA_ZEROIZATION || `MLKEM_ZEROIZATION || `ABR_SCAN_DEBUG) |-> ##10 (`ABR_TOP_PATH.abr_mem_wdata0_bank[i] == 0)) + ) + else $display("SVA ERROR: ABR_TOP_PATH.abr_mem_wdata0_bank[%0d] is not zero", i); + end + endgenerate + + // Function to check all SK memory banks are zero + function automatic logic check_mldsa_sk_memory_zero(); + // Check bank0 memory (even addresses) + for (int dword = 0; dword < PRIVKEY_MEM_NUM_DWORDS/2; dword++) begin + if (`ABR_RAMS_PATH.abr_sk_mem_bank0_inst.ram[dword] != 0) begin + $display("SVA ERROR: [MLDSA zeroize] SK bank0 at index %0d is not zero: %h", + dword, `ABR_RAMS_PATH.abr_sk_mem_bank0_inst.ram[dword]); + return 1'b0; + end + end + + // Check bank1 memory (odd addresses) + for (int dword = 0; dword < PRIVKEY_MEM_NUM_DWORDS/2; dword++) begin + if (`ABR_RAMS_PATH.abr_sk_mem_bank1_inst.ram[dword] != 0) begin + $display("SVA ERROR: [MLDSA zeroize] SK bank1 at index %0d is not zero: %h", + dword, `ABR_RAMS_PATH.abr_sk_mem_bank1_inst.ram[dword]); + return 1'b0; + end + end + + return 1'b1; + endfunction + + // Consolidated zeroization assertions + MLDSA_sk_memory_zero_comprehensive: assert property ( + @(posedge `SVA_RDC_CLK) + $rose(`ABR_PATH.zeroize_mem_done) |-> check_mldsa_sk_memory_zero() + ) + else $display("SVA ERROR: [MLDSA zeroize] SK memory zeroization verification failed"); + + // Assertion to check that `ABR_PATH.zeroize_mem_done` transitions from low to high + // when (`MLDSA_ZEROIZATION || `MLKEM_ZEROIZATION || `ABR_SCAN_DEBUG) is active + ZEROIZE_MEM_DONE_TRANSITION: assert property ( + @(posedge `SVA_RDC_CLK) + $rose(`MLDSA_ZEROIZATION || `MLKEM_ZEROIZATION || `ABR_SCAN_DEBUG) |=> + ( !`ABR_PATH.zeroize_mem_done )[*0:$] ##1 + $rose(`ABR_PATH.zeroize_mem_done) + ) + else $display("SVA ERROR: [MLDSA zeroize] zeroize_mem_done did not rise when expected"); + + + + + + `endif + //Generate disable signal for fuse_wr_check sva when hwclr is asserted. The disable needs to be for 3 clks in order to ignore the fuses being cleared + logic clear_obf_secrets_f; + logic clear_obf_secrets_ff; + logic clear_obf_secrets_int; + + logic cptra_in_debug_scan_mode_f; + logic cptra_in_debug_scan_mode_fall_trans; + logic cptra_in_debug_scan_mode_fall_trans_f; + logic cptra_in_debug_scan_mode_int; + + always@(posedge `SVA_RDC_CLK or negedge `CPTRA_TOP_PATH.cptra_rst_b) begin + if(!`CPTRA_TOP_PATH.cptra_rst_b) begin + clear_obf_secrets_f <= 'b0; + clear_obf_secrets_ff <= 'b0; + end + else begin + clear_obf_secrets_f <= `SOC_IFC_TOP_PATH.clear_obf_secrets; + clear_obf_secrets_ff <= clear_obf_secrets_f; + end + end + + always@(posedge `SVA_RDC_CLK or negedge `CPTRA_TOP_PATH.cptra_rst_b) begin + if(!`CPTRA_TOP_PATH.cptra_rst_b) begin + cptra_in_debug_scan_mode_f <= 'b0; + cptra_in_debug_scan_mode_fall_trans_f <= 'b0; + end + else begin + cptra_in_debug_scan_mode_f <= `CPTRA_TOP_PATH.cptra_in_debug_scan_mode; + cptra_in_debug_scan_mode_fall_trans_f <= cptra_in_debug_scan_mode_fall_trans; + end + end + + assign clear_obf_secrets_int = `SOC_IFC_TOP_PATH.clear_obf_secrets | clear_obf_secrets_f | clear_obf_secrets_ff; + assign cptra_in_debug_scan_mode_fall_trans = !`CPTRA_TOP_PATH.cptra_in_debug_scan_mode && cptra_in_debug_scan_mode_f; + assign cptra_in_debug_scan_mode_int = cptra_in_debug_scan_mode_fall_trans | cptra_in_debug_scan_mode_fall_trans_f; + + UDS_fuse_wr_check: assert property ( + @(posedge `SVA_RDC_CLK) + disable iff(`CPTRA_TOP_PATH.cptra_in_debug_scan_mode || clear_obf_secrets_int || cptra_in_debug_scan_mode_int) + (`SOC_IFC_TOP_PATH.soc_ifc_reg_hwif_out.CPTRA_FUSE_WR_DONE.done.value) |-> `CPTRA_TOP_PATH.obf_uds_seed == $past(`CPTRA_TOP_PATH.obf_uds_seed) + ) + else $display("SVA ERROR: Unexpected write to obf uds seed!"); + + FE_fuse_wr_check: assert property ( + @(posedge `SVA_RDC_CLK) + disable iff(`CPTRA_TOP_PATH.cptra_in_debug_scan_mode || clear_obf_secrets_int || cptra_in_debug_scan_mode_int) + (`SOC_IFC_TOP_PATH.soc_ifc_reg_hwif_out.CPTRA_FUSE_WR_DONE.done.value) |-> `CPTRA_TOP_PATH.obf_field_entropy == $past(`CPTRA_TOP_PATH.obf_field_entropy) + ) + else $display("SVA ERROR: Unexpected write to obf field entropy!"); + + //ZEROIZE SVA + generate + for(genvar dword = 0; dword < SHA256_BLOCK_NUM_DWORDS; dword++) begin + sha256_block_zeroize: assert property ( + @(posedge `SVA_RDC_CLK) + `SHA256_PATH.hwif_out.SHA256_CTRL.ZEROIZE.value |=> (`SHA256_PATH.hwif_out.SHA256_BLOCK[dword].BLOCK.value == 0) + ) + else $display("SVA ERROR: SHA256 block zeroize mismatch!"); + end + + for(genvar dword = 0; dword < SHA256_DIG_NUM_DWORDS; dword++) begin + sha256_digest_zeroize: assert property ( + @(posedge `SVA_RDC_CLK) + `SHA256_PATH.hwif_out.SHA256_CTRL.ZEROIZE.value |=> (`SHA256_PATH.digest_reg[dword] == 0) & (`SHA256_PATH.i_sha256_reg.field_storage.SHA256_DIGEST[dword].DIGEST.value == 0) + ) + else $display("SVA ERROR: SHA256 digest zeroize mismatch!"); + end + + for(genvar dword = 0; dword < SHA512_BLOCK_NUM_DWORDS; dword++) begin + sha512_block_zeroize: assert property ( + @(posedge `SVA_RDC_CLK) + `SHA512_PATH.hwif_out.SHA512_CTRL.ZEROIZE.value |=> (`SHA512_PATH.hwif_out.SHA512_BLOCK[dword].BLOCK.value == 0) + ) + else $display("SVA ERROR: SHA512 block zeroize mismatch!"); + end + + for(genvar dword = 0; dword < SHA512_DIG_NUM_DWORDS; dword++) begin + sha512_digest_zeroize: assert property ( + @(posedge `SVA_RDC_CLK) + `SHA512_PATH.hwif_out.SHA512_CTRL.ZEROIZE.value |=> (`SHA512_PATH.digest_reg[dword] == 0) & (`SHA512_PATH.i_sha512_reg.field_storage.SHA512_DIGEST[dword].DIGEST.value == 0) + ) + else $display("SVA ERROR: SHA512 digest zeroize mismatch!"); + end + + for(genvar dword = 0; dword < HMAC_KEY_NUM_DWORDS; dword++) begin + hmac_key_zeroize: assert property ( + @(posedge `SVA_RDC_CLK) + `HMAC_PATH.hwif_out.HMAC512_CTRL.ZEROIZE.value |=> (`HMAC_PATH.hwif_out.HMAC512_KEY[dword].KEY.value == 0) + ) + else $display("SVA ERROR: HMAC384 key zeroize mismatch!"); + end + + for(genvar dword = 0; dword < HMAC_BLOCK_NUM_DWORDS; dword++) begin + hmac_block_zeroize: assert property ( + @(posedge `SVA_RDC_CLK) + `HMAC_PATH.hwif_out.HMAC512_CTRL.ZEROIZE.value |=> (`HMAC_PATH.hwif_out.HMAC512_BLOCK[dword].BLOCK.value == 0) + ) + else $display("SVA ERROR: HMAC384 block zeroize mismatch!"); + end + + for(genvar dword = 0; dword < HMAC_TAG_NUM_DWORDS; dword++) begin + hmac_tag_zeroize: assert property ( + @(posedge `SVA_RDC_CLK) + `HMAC_PATH.hwif_out.HMAC512_CTRL.ZEROIZE.value |=> (`HMAC_PATH.tag_reg[dword] == 0) & (`HMAC_PATH.i_hmac_reg.field_storage.HMAC512_TAG[dword].TAG.value == 0) + ) + else $display("SVA ERROR: HMAC384 tag zeroize mismatch!"); + end + + + for(genvar dword = 0; dword < ECC_REG_NUM_DWORDS; dword++) begin + ecc_reg_zeroize: assert property ( + @(posedge `SVA_RDC_CLK) + `ECC_PATH.hwif_out.ECC_CTRL.ZEROIZE.value |=> (`ECC_PATH.hwif_out.ECC_SEED[dword].SEED.value == 0) & (`ECC_PATH.hwif_out.ECC_NONCE[dword].NONCE.value == 0) & (`ECC_PATH.hwif_out.ECC_PRIVKEY_IN[dword].PRIVKEY_IN.value == 0) & + (`ECC_PATH.hwif_out.ECC_MSG[dword].MSG.value == 0) & (`ECC_PATH.hwif_out.ECC_PUBKEY_X[dword].PUBKEY_X.value == 0) & (`ECC_PATH.hwif_out.ECC_PUBKEY_Y[dword].PUBKEY_Y.value == 0) & + (`ECC_PATH.hwif_out.ECC_SIGN_R[dword].SIGN_R.value == 0) & (`ECC_PATH.hwif_out.ECC_SIGN_S[dword].SIGN_S.value == 0) & (`ECC_PATH.hwif_out.ECC_VERIFY_R[dword].VERIFY_R.value == 0) & (`ECC_PATH.hwif_out.ECC_IV[dword].IV.value == 0) & + (`ECC_REG_PATH.field_storage.ECC_PRIVKEY_OUT[dword].PRIVKEY_OUT.value == 0) + ) + else $display("SVA ERROR: ECC reg zeroize mismatch!"); + end + + for(genvar addr = 0; addr < ECC_MEM_ADDR; addr++) begin + ecc_mem_zeroize: assert property ( + @(posedge `SVA_RDC_CLK) + `ECC_PATH.hwif_out.ECC_CTRL.ZEROIZE.value |=> (`ECC_PATH.ecc_arith_unit_i.ram_tdp_file_i.mem[addr] == 0) + ) + else $display("SVA ERROR: ECC mem zeroize mismatch!"); + end + + for(genvar addr = 0; addr < DOE_256_NUM_ROUNDS; addr++) begin + doe_mem_zeroize: assert property ( + @(posedge `DOE_INST_PATH.clk) + `DOE_INST_PATH.zeroize |=> (`DOE_INST_PATH.i_doe_core_cbc.keymem.key_mem[addr] == 0) + ) + else $display("SVA ERROR: DOE mem zeroize mismatch!"); + end + endgenerate + + sha512_masked_core_digest_zeroize: assert property ( + @(posedge `SVA_RDC_CLK) + `ECC_PATH.hwif_out.ECC_CTRL.ZEROIZE.value |=> (`SHA512_MASKED_PATH.digest == 0) & (`SHA512_MASKED_PATH.a_reg == 0) & (`SHA512_MASKED_PATH.b_reg == 0) & (`SHA512_MASKED_PATH.c_reg == 0) & (`SHA512_MASKED_PATH.d_reg == 0) & (`SHA512_MASKED_PATH.e_reg == 0) & (`SHA512_MASKED_PATH.f_reg == 0) & (`SHA512_MASKED_PATH.g_reg == 0) & (`SHA512_MASKED_PATH.h_reg == 0) + ) + else $display("SVA ERROR: SHA512_masked_core digest zeroize mismatch!"); + + doe_block_zeroize: assert property ( + @(posedge `DOE_INST_PATH.clk) + `DOE_INST_PATH.zeroize |=> (`DOE_INST_PATH.i_doe_core_cbc.enc_block.new_block == 0) & (`DOE_INST_PATH.i_doe_core_cbc.dec_block.new_block == 0) + ) + else $display("SVA ERROR: DOE block zeroize mismatch!"); + + doe_block_reg_zeroize: assert property ( + @(posedge `DOE_INST_PATH.clk) + `DOE_INST_PATH.zeroize |=> (`DOE_INST_PATH.core_block == 0) + ) + else $display("SVA ERROR: DOE block reg zeroize mismatch!"); + + doe_iv_reg_zeroize: assert property ( + @(posedge `DOE_INST_PATH.clk) + $rose(`DOE_INST_PATH.zeroize) |=> (`DOE_INST_PATH.core_IV == 0) + ) + else $display("SVA ERROR: DOE iv reg zeroize mismatch!"); + + doe_key_clear: assert property ( + @(posedge `DOE_INST_PATH.clk) + disable iff(`CPTRA_TOP_PATH.cptra_in_debug_scan_mode) + `DOE_INST_PATH.zeroize |=> (`DOE_INST_PATH.core_key == 0) + ) + else $display("SVA ERROR: DOE key clear mismatch!"); + + genvar client; + generate + for(client = 0; client < KV_NUM_WRITE; client++) begin + KV_client_wrdata_not_unknown: assert property ( + @(posedge `SVA_RDC_CLK) + disable iff (!`KEYVAULT_PATH.kv_write[client].write_en || !`KEYVAULT_PATH.rst_b) + `KEYVAULT_PATH.kv_write[client].write_en |-> !$isunknown(`KEYVAULT_PATH.kv_write[client].write_data) + ) + else $display("SVA ERROR: KV client %0d data is unknown", client); + end + + for(client = 0; client < KV_NUM_READ; client++) begin + KV_client_rddata_not_unknown: assert property ( + @(posedge `SVA_RDC_CLK) + disable iff (!`KEYVAULT_PATH.rst_b) + !$isunknown(`KEYVAULT_PATH.kv_rd_resp[client].read_data) + ) + else $display("SVA ERROR: KV client %0d data is unknown", client); + end + endgenerate + + //KV read error check + //If ocp_lock_in_progress = 1, kv23 read is not allowed. Other slots can be read + //If ocp_lock_in_progress = 0, kv23 read is allowed + // localparam KV_SUCCESS = 0; //TODO: resolve pkg warning during build + // localparam KV_READ_FAIL = 1; + // localparam KV_WRITE_FAIL = 2; + + hmac_key_kv23_read_error_check: assert property ( + @(posedge `SVA_RDC_CLK) + ($fell(`HMAC_PATH.kv_key_write_en) & `SOC_IFC_TOP_PATH.ss_ocp_lock_in_progress & `KEYVAULT_PATH.kv_read[0].read_entry == 23) |-> /*(`KEYVAULT_PATH.kv_rd_resp[0].error == 1'b1)*/ (`HMAC_PATH.hmac_key_kv_read.error_code == 1) + ) + else $display("SVA ERROR: KV read error not set for KV23 read when ocp_lock_in_progress = 1"); + + hmac_key_kv_others_read_error_check: assert property ( + @(posedge `SVA_RDC_CLK) + ($fell(`HMAC_PATH.kv_key_write_en) & `SOC_IFC_TOP_PATH.ss_ocp_lock_in_progress & (`KEYVAULT_PATH.kv_read[0].read_entry != 23) & (`KEYVAULT_PATH.kv_reg1.hwif_out.KEY_CTRL[`HMAC_PATH.kv_read[0].read_entry].dest_valid.value[0])) |-> /*(`KEYVAULT_PATH.kv_rd_resp[0].error == 1'b0)*/ (`HMAC_PATH.hmac_key_kv_read.error_code == 0) + ) + else $display("SVA ERROR: KV read error set when ocp_lock_in_progress = 1 for non-KV23 read"); + + hmac_block_kv23_read_error_check: assert property ( + @(posedge `SVA_RDC_CLK) + ($rose(`HMAC_PATH.kv_block_done) & `SOC_IFC_TOP_PATH.ss_ocp_lock_in_progress & `KEYVAULT_PATH.kv_read[1].read_entry == 23) |-> /*(`KEYVAULT_PATH.kv_rd_resp[0].error == 1'b1)*/ (`HMAC_PATH.hmac_block_kv_read.error_code == 1) + ) + else $display("SVA ERROR: KV read error not set for KV23 read when ocp_lock_in_progress = 1"); + + hmac_block_kv_others_read_error_check: assert property ( + @(posedge `SVA_RDC_CLK) + ($rose(`HMAC_PATH.kv_block_done) &`SOC_IFC_TOP_PATH.ss_ocp_lock_in_progress & `KEYVAULT_PATH.kv_read[1].read_entry != 23 & (`KEYVAULT_PATH.kv_reg1.hwif_out.KEY_CTRL[`HMAC_PATH.kv_read[1].read_entry].dest_valid.value[1])) |-> /*(`KEYVAULT_PATH.kv_rd_resp[1].error == 1'b0)*/ (`HMAC_PATH.hmac_block_kv_read.error_code == 0) + ) + else $display("SVA ERROR: KV read error set when ocp_lock_in_progress = 1 for non-KV23 read"); + + + + //WDT checks: + cascade_wdt_t1_pet: assert property ( + @(posedge `SVA_RDC_CLK) + (`WDT_PATH.timer1_restart && `WDT_PATH.timer1_en && !`WDT_PATH.timer2_en && !`WDT_PATH.t1_timeout) |=> (`WDT_PATH.timer1_count == 'h0) + ) + else $display("SVA ERROR: [Cascade] WDT Timer1 did not restart on pet"); + + cascade_wdt_t2_pet: assert property ( + @(posedge `SVA_RDC_CLK) + (`WDT_PATH.timer2_restart && !`WDT_PATH.timer2_en && !`WDT_PATH.t2_timeout) |=> (`WDT_PATH.timer2_count == 'h0) + ) + else $display("SVA ERROR: [Cascade] WDT Timer2 did not restart on pet"); + + cascade_wdt_t1_service: assert property ( + @(posedge `SVA_RDC_CLK) + (`WDT_PATH.wdt_timer1_timeout_serviced_qual && `WDT_PATH.timer1_en && !`WDT_PATH.timer2_en && !`WDT_PATH.t2_timeout) |=> (`WDT_PATH.timer1_count == 'h0) + ) + else $display("SVA ERROR: [Cascade] WDT Timer1 did not restart after interrupt service"); + + cascade_wdt_t2_service: assert property ( + @(posedge `SVA_RDC_CLK) + (`WDT_PATH.wdt_timer2_timeout_serviced_qual && !`WDT_PATH.timer2_en) |=> (`WDT_PATH.timer2_count == 'h0) + ) + else $display("SVA ERROR: [Cascade] WDT Timer2 did not restart after interrupt service"); + + independent_wdt_t1_pet: assert property ( + @(posedge `SVA_RDC_CLK) + (`WDT_PATH.timer1_restart && `WDT_PATH.timer1_en && `WDT_PATH.timer2_en) |=> (`WDT_PATH.timer1_count == 'h0) + ) + else $display("SVA ERROR: [Independent] WDT Timer1 did not restart on pet"); + + independent_wdt_t2_pet: assert property ( + @(posedge `SVA_RDC_CLK) + (`WDT_PATH.timer2_restart && `WDT_PATH.timer2_en) |=> (`WDT_PATH.timer2_count == 'h0) + ) + else $display("SVA ERROR: [Independent] WDT Timer2 did not restart on pet"); + + independent_wdt_t1_service: assert property ( + @(posedge `SVA_RDC_CLK) + (`WDT_PATH.wdt_timer1_timeout_serviced_qual && `WDT_PATH.timer1_en && `WDT_PATH.timer2_en && !`WDT_PATH.t2_timeout) |=> (`WDT_PATH.timer1_count == 'h0) + ) + else $display("SVA ERROR: [Independent] WDT Timer1 did not restart after interrupt service"); + + independent_wdt_t2_service: assert property ( + @(posedge `SVA_RDC_CLK) + (`WDT_PATH.wdt_timer2_timeout_serviced_qual && `WDT_PATH.timer2_en) |=> (`WDT_PATH.timer2_count == 'h0) + ) + else $display("SVA ERROR: [Independent] WDT Timer2 did not restart after interrupt service"); + + wdt_status_t1_check: assert property ( + @(posedge `SVA_RDC_CLK) + disable iff (~`SVA_RST) + $rose(`WDT_PATH.t1_timeout) |=> $rose(`SOC_IFC_TOP_PATH.soc_ifc_reg_hwif_out.CPTRA_WDT_STATUS.t1_timeout.value) + ) + else $display("SVA ERROR: WDT Status bit not set on t1 expiry!"); + + wdt_status_t2_check: assert property ( + @(posedge `SVA_RDC_CLK) + disable iff (~`SVA_RST) + $rose(`WDT_PATH.t2_timeout) |=> $rose(`SOC_IFC_TOP_PATH.soc_ifc_reg_hwif_out.CPTRA_WDT_STATUS.t2_timeout.value) + ) + else $display("SVA ERROR: WDT Status bit not set on t2 expiry!"); + + + + //VALID flag SVA + sha512_valid_flag: assert property ( + @(posedge `SVA_RDC_CLK) + `SHA512_PATH.digest_valid_reg |-> `SHA512_PATH.ready_reg + ) + else $display("SVA ERROR: SHA512 VALID flag mismatch!"); + + sha256_valid_flag: assert property ( + @(posedge `SVA_RDC_CLK) + `SHA256_PATH.digest_valid_reg |-> `SHA256_PATH.ready_reg + ) + else $display("SVA ERROR: SHA256 VALID flag mismatch!"); + + HMAC_valid_flag: assert property ( + @(posedge `SVA_RDC_CLK) + `HMAC_PATH.tag_valid_reg |-> `HMAC_PATH.ready_reg + ) + else $display("SVA ERROR: HMAC VALID flag mismatch!"); + + ECC_valid_flag: assert property ( + @(posedge `SVA_RDC_CLK) + `ECC_PATH.ecc_valid_reg |-> `ECC_PATH.ecc_ready_reg + ) + else $display("SVA ERROR: ECC VALID flag mismatch!"); + + //MLDSA_valid_flag: assert property ( + // @(posedge `SVA_RDC_CLK) + // disable iff (`SERVICES_PATH.disable_mldsa_sva) + // `ABR_PATH.mldsa_valid_reg |-> `ABR_PATH.abr_ready + // ) + // else $display("SVA ERROR: MLDSA VALID flag mismatch!"); + + //SVA for SHA512 restore + sha512_restore_cmd: assert property ( + @(posedge `SVA_RDC_CLK) + `SHA512_PATH.restore_reg |-> (`SHA512_PATH.next_reg && !`SHA512_PATH.init_reg) + ) + else $display("SVA ERROR: SHA512 restore is not valid!"); + + //SVA for modular operations + ecc_opa_input: assert property ( + @(posedge `SVA_RDC_CLK) + (`ECC_PATH.ecc_arith_unit_i.ecc_fau_i.add_en_i | `ECC_PATH.ecc_arith_unit_i.ecc_fau_i.mult_en_i) |-> (`ECC_PATH.ecc_arith_unit_i.ecc_fau_i.opa_i < `ECC_PATH.ecc_arith_unit_i.ecc_fau_i.prime_i) + ) + else $display("SVA ERROR: ECC opa input is not valid!"); + + ecc_opb_input: assert property ( + @(posedge `SVA_RDC_CLK) + (`ECC_PATH.ecc_arith_unit_i.ecc_fau_i.add_en_i | `ECC_PATH.ecc_arith_unit_i.ecc_fau_i.mult_en_i) |-> (`ECC_PATH.ecc_arith_unit_i.ecc_fau_i.opb_i < `ECC_PATH.ecc_arith_unit_i.ecc_fau_i.prime_i) + ) + else $display("SVA ERROR: ECC opb input is not valid!"); + + ecc_add_result: assert property ( + @(posedge `SVA_RDC_CLK) + `ECC_PATH.ecc_arith_unit_i.ecc_instr_s.opcode.add_we |-> (`ECC_PATH.ecc_arith_unit_i.add_res_s < `ECC_PATH.ecc_arith_unit_i.adder_prime) + ) + else $display("SVA ERROR: ECC adder result is not valid!"); + + ecc_mult_result: assert property ( + @(posedge `SVA_RDC_CLK) + `ECC_PATH.ecc_arith_unit_i.ecc_instr_s.opcode.mult_we |-> (`ECC_PATH.ecc_arith_unit_i.mult_res_s < `ECC_PATH.ecc_arith_unit_i.adder_prime) + ) + else $display("SVA ERROR: ECC multiplier result is not valid!"); + + // SVA for LMS WNTZ accelerator + wntz_mode: assert property ( + @(posedge `SVA_RDC_CLK) + `SHA256_PATH.init_reg |-> !`SHA256_PATH.next_reg + ) + else $display("SVA ERROR: SHA256 operation is not valid with INIT and NEXT asserted in the same cycle!"); + + // Bus IDLE on Firmware Update Reset + fw_upd_rst_doe_idle: assert property (@(posedge `SVA_RDC_CLK) `CPTRA_FW_UPD_RST_WINDOW |-> !`DOE_REG_PATH.s_cpuif_req) + else $display("SVA ERROR: DOE bus not idle after Firmware Update Reset!"); + fw_upd_rst_ecc_idle: assert property (@(posedge `SVA_RDC_CLK) `CPTRA_FW_UPD_RST_WINDOW |-> !`ECC_REG_PATH.s_cpuif_req) + else $display("SVA ERROR: ECC bus not idle after Firmware Update Reset!"); + fw_upd_rst_hmac_idle: assert property (@(posedge `SVA_RDC_CLK) `CPTRA_FW_UPD_RST_WINDOW |-> !`HMAC_REG_PATH.s_cpuif_req) + else $display("SVA ERROR: HMAC bus not idle after Firmware Update Reset!"); + fw_upd_rst_kv_idle: assert property (@(posedge `SVA_RDC_CLK) `CPTRA_FW_UPD_RST_WINDOW |-> !`KEYVAULT_REG_PATH.s_cpuif_req) + else $display("SVA ERROR: Key Vault bus not idle after Firmware Update Reset!"); + fw_upd_rst_pv_idle: assert property (@(posedge `SVA_RDC_CLK) `CPTRA_FW_UPD_RST_WINDOW |-> !`PCRVAULT_REG_PATH.s_cpuif_req) + else $display("SVA ERROR: PCR Vault bus not idle after Firmware Update Reset!"); + fw_upd_rst_dv_idle: assert property (@(posedge `SVA_RDC_CLK) `CPTRA_FW_UPD_RST_WINDOW |-> !`DATA_VAULT_REG_PATH.s_cpuif_req) + else $display("SVA ERROR: Data Vault bus not idle after Firmware Update Reset!"); + fw_upd_rst_sha256_idle: assert property (@(posedge `SVA_RDC_CLK) `CPTRA_FW_UPD_RST_WINDOW |-> !`SHA256_PATH.i_sha256_reg.s_cpuif_req) + else $display("SVA ERROR: SHA256 bus not idle after Firmware Update Reset!"); + fw_upd_rst_sha512_idle: assert property (@(posedge `SVA_RDC_CLK) `CPTRA_FW_UPD_RST_WINDOW |-> !`SHA512_PATH.i_sha512_reg.s_cpuif_req) + else $display("SVA ERROR: SHA512 bus not idle after Firmware Update Reset!"); + fw_upd_rst_soc_ifc_idle: assert property (@(posedge `SVA_RDC_CLK) `CPTRA_FW_UPD_RST_WINDOW |-> !`SOC_IFC_TOP_PATH.i_ahb_slv_sif_soc_ifc.dv) + else $display("SVA ERROR: SOC_IFC bus not idle after Firmware Update Reset!"); + + + hmac_drbg_zero_result: assert property ( + @(posedge `SVA_RDC_CLK) + `HMAC_DRBG_PATH.valid |-> (`HMAC_DRBG_PATH.drbg != 384'h0 ) + ) + else $display("SVA ERROR: drbg is zero when valid is high"); + + hmac_drbg_illegal_above_prime: assert property ( + @(posedge `SVA_RDC_CLK) + `HMAC_DRBG_PATH.valid |-> (`HMAC_DRBG_PATH.drbg < `HMAC_DRBG_PATH.HMAC_DRBG_PRIME) + ) + else $display("SVA ERROR: drbg >= HMAC_DRBG_PRIME when valid is high"); + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_top_tb.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_top_tb.sv new file mode 100755 index 0000000..82d49a6 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_top_tb.sv @@ -0,0 +1,373 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +// +`default_nettype none + +`include "common_defines.sv" +`include "config_defines.svh" +`include "caliptra_reg_defines.svh" +`include "caliptra_reg_field_defines.svh" +`include "caliptra_macros.svh" + +module caliptra_top_tb; + + import axi_pkg::*; + import kv_defines_pkg::*; + import soc_ifc_pkg::*; + import caliptra_top_tb_pkg::*; + + bit core_clk; + + int cycleCnt; + + + logic [15:0] strap_ss_key_release_key_size; + logic [63:0] strap_ss_key_release_base_addr; + + logic cptra_pwrgood; + logic cptra_rst_b; + logic BootFSM_BrkPoint; + logic scan_mode; + + logic recovery_data_avail; + + logic [`CLP_OBF_KEY_DWORDS-1:0][31:0] cptra_obf_key; + + logic [`CLP_CSR_HMAC_KEY_DWORDS-1:0][31:0] cptra_csr_hmac_key; + + logic [0:`CLP_OBF_UDS_DWORDS-1][31:0] cptra_uds_rand; + logic [0:`CLP_OBF_FE_DWORDS-1][31:0] cptra_fe_rand; + logic [0:OCP_LOCK_HEK_NUM_DWORDS-1][31:0] cptra_hek_rand; + logic [0:`CLP_OBF_KEY_DWORDS-1][31:0] cptra_obf_key_tb; + + //jtag interface + logic jtag_tck; // JTAG clk + logic jtag_tms; // JTAG TMS + logic jtag_tdi; // JTAG tdi + logic jtag_trst_n; // JTAG Reset + logic jtag_tdo; // JTAG TDO + logic jtag_tdoEn; // JTAG TDO enable + + logic axi_error_inj_en; + + // AXI Interface + axi_if #( + .AW(`CALIPTRA_SLAVE_ADDR_WIDTH(`CALIPTRA_SLAVE_SEL_SOC_IFC)), + .DW(`CALIPTRA_AXI_DATA_WIDTH), + .IW(`CALIPTRA_AXI_ID_WIDTH), + .UW(`CALIPTRA_AXI_USER_WIDTH) + ) m_axi_bfm_if (.clk(core_clk), .rst_n(cptra_rst_b)); + axi_if #( + .AW(`CALIPTRA_AXI_DMA_ADDR_WIDTH), + .DW(CPTRA_AXI_DMA_DATA_WIDTH), + .IW(CPTRA_AXI_DMA_ID_WIDTH), + .UW(CPTRA_AXI_DMA_USER_WIDTH) + ) m_axi_if (.clk(core_clk), .rst_n(cptra_rst_b)); + + logic ready_for_fuses; + logic ready_for_mb_processing; + logic mailbox_data_avail; + logic mbox_sram_cs; + logic mbox_sram_we; + logic [CPTRA_MBOX_ADDR_W-1:0] mbox_sram_addr; + logic [CPTRA_MBOX_DATA_AND_ECC_W-1:0] mbox_sram_wdata; + logic [CPTRA_MBOX_DATA_AND_ECC_W-1:0] mbox_sram_rdata; + + logic imem_cs; + logic [`CALIPTRA_IMEM_ADDR_WIDTH-1:0] imem_addr; + logic [`CALIPTRA_IMEM_DATA_WIDTH-1:0] imem_rdata; + + //device lifecycle + security_state_t security_state; + + logic ss_ocp_lock_en; + + ras_test_ctrl_t ras_test_ctrl; + axi_complex_ctrl_t axi_complex_ctrl; + logic [63:0] generic_input_wires; + logic etrng_req; + logic [3:0] itrng_data; + logic itrng_valid; + + logic cptra_error_fatal; + logic cptra_error_non_fatal; + + //Interrupt flags + logic int_flag; + logic cycleCnt_smpl_en; + + //Reset flags + logic assert_hard_rst_flag; + logic deassert_hard_rst_flag; + logic assert_rst_flag_from_service; + logic deassert_rst_flag_from_service; + + el2_mem_if el2_mem_export (); + abr_mem_if abr_memory_export(); + + always + begin : clk_gen + core_clk = #5ns ~core_clk; + end // clk_gen + + +caliptra_top_tb_soc_bfm soc_bfm_inst ( + .core_clk (core_clk ), + + .cptra_pwrgood (cptra_pwrgood ), + .cptra_rst_b (cptra_rst_b ), + + .BootFSM_BrkPoint(BootFSM_BrkPoint), + .cycleCnt (cycleCnt ), + + .cptra_obf_key (cptra_obf_key ), + .cptra_csr_hmac_key (cptra_csr_hmac_key), + + .strap_ss_key_release_key_size, + .strap_ss_key_release_base_addr, + .ss_ocp_lock_en, + + .cptra_uds_rand (cptra_uds_rand ), + .cptra_fe_rand (cptra_fe_rand ), + .cptra_hek_rand (cptra_hek_rand ), + .cptra_obf_key_tb(cptra_obf_key_tb), + + .m_axi_bfm_if(m_axi_bfm_if), + + .ready_for_fuses (ready_for_fuses ), + .ready_for_mb_processing (ready_for_mb_processing ), + .mailbox_data_avail(mailbox_data_avail), + + .ras_test_ctrl(ras_test_ctrl), + + .generic_input_wires(generic_input_wires), + + .cptra_error_fatal(cptra_error_fatal), + .cptra_error_non_fatal(cptra_error_non_fatal), + + //Interrupt flags + .int_flag(int_flag), + .cycleCnt_smpl_en(cycleCnt_smpl_en), + + .assert_hard_rst_flag(assert_hard_rst_flag), + .deassert_hard_rst_flag(deassert_hard_rst_flag), + .assert_rst_flag_from_service(assert_rst_flag_from_service), + .deassert_rst_flag_from_service(deassert_rst_flag_from_service) + +); + + assign jtag_tck = 1'b0; + assign jtag_tms = 1'b0; + assign jtag_tdi = 1'b0; + assign jtag_trst_n = 1'b0; + + //=========================================================================- + // DUT instance + //=========================================================================- +caliptra_top caliptra_top_dut ( + .cptra_pwrgood (cptra_pwrgood), + .cptra_rst_b (cptra_rst_b), + .clk (core_clk), + + .cptra_obf_key (cptra_obf_key), + .cptra_obf_uds_seed_vld ('0), //validated at caliptra-ss + .cptra_obf_uds_seed ('0), //validated at caliptra-ss + .cptra_obf_field_entropy_vld('0), //validated at caliptra-ss + .cptra_obf_field_entropy ('0), //validated at caliptra-ss + .cptra_csr_hmac_key (cptra_csr_hmac_key), + + .jtag_tck(jtag_tck), + .jtag_tdi(jtag_tdi), + .jtag_tms(jtag_tms), + .jtag_trst_n(jtag_trst_n), + .jtag_tdo(jtag_tdo), + .jtag_tdoEn(jtag_tdoEn), + + //SoC AXI Interface + .s_axi_w_if(m_axi_bfm_if.w_sub), + .s_axi_r_if(m_axi_bfm_if.r_sub), + + //AXI DMA Interface + .m_axi_w_if(m_axi_if.w_mgr), + .m_axi_r_if(m_axi_if.r_mgr), + + .el2_mem_export(el2_mem_export.veer_sram_src), + .abr_memory_export(abr_memory_export.req), + + .ready_for_fuses(ready_for_fuses), + .ready_for_mb_processing(ready_for_mb_processing), + .ready_for_runtime(), + + .mbox_sram_cs(mbox_sram_cs), + .mbox_sram_we(mbox_sram_we), + .mbox_sram_addr(mbox_sram_addr), + .mbox_sram_wdata(mbox_sram_wdata), + .mbox_sram_rdata(mbox_sram_rdata), + + .imem_cs(imem_cs), + .imem_addr(imem_addr), + .imem_rdata(imem_rdata), + + .mailbox_data_avail(mailbox_data_avail), + .mailbox_flow_done(), + .BootFSM_BrkPoint(BootFSM_BrkPoint), + + .recovery_data_avail(recovery_data_avail), + .recovery_image_activated(1'b0), + + //SoC Interrupts + .cptra_error_fatal (cptra_error_fatal ), + .cptra_error_non_fatal(cptra_error_non_fatal), + +`ifdef CALIPTRA_INTERNAL_TRNG + .etrng_req (etrng_req), + .itrng_data (itrng_data), + .itrng_valid (itrng_valid), +`else + .etrng_req (), + .itrng_data (4'b0), + .itrng_valid (1'b0), +`endif + + // Subsystem mode straps, tested in subsystem bench + .strap_ss_caliptra_base_addr (64'hba5e_ba11), + .strap_ss_mci_base_addr (64'h0), + .strap_ss_recovery_ifc_base_addr (64'h0), + .strap_ss_external_staging_area_base_addr (64'h0), + .strap_ss_otp_fc_base_addr (64'h0), + .strap_ss_uds_seed_base_addr (64'h0), + .strap_ss_key_release_base_addr , + .strap_ss_key_release_key_size , + .strap_ss_prod_debug_unlock_auth_pk_hash_reg_bank_offset(32'h0), + .strap_ss_num_of_prod_debug_unlock_auth_pk_hashes (32'h0), + .strap_ss_caliptra_dma_axi_user (32'h0), + .strap_ss_strap_generic_0 (32'h0), + .strap_ss_strap_generic_1 (32'h0), + .strap_ss_strap_generic_2 (32'h0), + .strap_ss_strap_generic_3 (32'h0), + .ss_debug_intent ( 1'b0), + + // Subsystem mode constant strap input indicating OCP LOCK configuration is enabled + .ss_ocp_lock_en (ss_ocp_lock_en), + + // Subsystem mode debug outputs + .ss_dbg_manuf_enable (), + .ss_soc_dbg_unlock_level(), + + // Subsystem mode firmware execution control + .ss_generic_fw_exec_ctrl(), + + .generic_input_wires (generic_input_wires ), + .generic_output_wires( ), + + // RISC-V Trace Ports + .trace_rv_i_insn_ip (), + .trace_rv_i_address_ip (), + .trace_rv_i_valid_ip (), + .trace_rv_i_exception_ip(), + .trace_rv_i_ecause_ip (), + .trace_rv_i_interrupt_ip(), + .trace_rv_i_tval_ip (), + + .security_state(security_state), + .scan_mode (scan_mode) +); + + +`ifdef CALIPTRA_INTERNAL_TRNG + //=========================================================================- + // Physical RNG used for Internal TRNG + //=========================================================================- +physical_rng physical_rng ( + .clk (core_clk), + .enable (etrng_req), + .data (itrng_data), + .valid (itrng_valid) +); +`endif + + //=========================================================================- + // Services for SRAM exports, STDOUT, etc + //=========================================================================- +caliptra_top_tb_services #( + .UVM_TB(0) +) tb_services_i ( + .clk(core_clk), + + .cptra_rst_b(cptra_rst_b), + + // Caliptra Memory Export Interface + .el2_mem_export (el2_mem_export.veer_sram_sink), + .abr_memory_export (abr_memory_export.resp), + + //SRAM interface for mbox + .mbox_sram_cs (mbox_sram_cs ), + .mbox_sram_we (mbox_sram_we ), + .mbox_sram_addr (mbox_sram_addr ), + .mbox_sram_wdata(mbox_sram_wdata), + .mbox_sram_rdata(mbox_sram_rdata), + + //SRAM interface for imem + .imem_cs (imem_cs ), + .imem_addr (imem_addr ), + .imem_rdata(imem_rdata), + + // Security State + .security_state(security_state), + + //Scan mode + .scan_mode(scan_mode), + + // TB Controls + .ras_test_ctrl(ras_test_ctrl), + .cycleCnt(cycleCnt), + .axi_complex_ctrl(axi_complex_ctrl), + + //Interrupt flags + .int_flag(int_flag), + .cycleCnt_smpl_en(cycleCnt_smpl_en), + + //Reset flags + .assert_hard_rst_flag(assert_hard_rst_flag), + .deassert_hard_rst_flag(deassert_hard_rst_flag), + + .assert_rst_flag(assert_rst_flag_from_service), + .deassert_rst_flag(deassert_rst_flag_from_service), + + .cptra_uds_tb(cptra_uds_rand), + .cptra_fe_tb(cptra_fe_rand), + .cptra_obf_key_tb(cptra_obf_key_tb), + .cptra_hek_tb(cptra_hek_rand), + + .axi_error_inj_en(axi_error_inj_en) + +); + +caliptra_top_tb_axi_complex tb_axi_complex_i ( + .core_clk (core_clk ), + .cptra_rst_b (cptra_rst_b ), + .m_axi_if (m_axi_if ), + .recovery_data_avail(recovery_data_avail), + .ctrl (axi_complex_ctrl ), + .axi_error_inj_en (axi_error_inj_en) +); + +//=========================================================================- +// SVA +//=========================================================================- +caliptra_top_sva sva(); + +`include "__rtlmeter_top_include.vh" + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_top_tb_axi_complex.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_top_tb_axi_complex.sv new file mode 100644 index 0000000..74fe8b0 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_top_tb_axi_complex.sv @@ -0,0 +1,667 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +// +`default_nettype none + +module caliptra_top_tb_axi_complex import caliptra_top_tb_pkg::*; ( + input logic core_clk, + input logic cptra_rst_b, + axi_if m_axi_if, + output logic recovery_data_avail, + input var axi_complex_ctrl_t ctrl, + input logic axi_error_inj_en +); + + import axi_pkg::*; + import soc_ifc_pkg::*; + + //=========================================================================- + // Error Response Injection Parameters + //=========================================================================- + logic [`CALIPTRA_AXI_DMA_ADDR_WIDTH-1:0] err_resp_start_addr; + logic [`CALIPTRA_AXI_DMA_ADDR_WIDTH-1:0] err_resp_end_addr; + logic err_resp_enable; + logic cmdline_err_resp_enable; + + // Command line parameter parsing + initial begin + // string err_start_str, err_end_str; + string err_resp_enable_str; + cmdline_err_resp_enable = 1'b0; + err_resp_start_addr = '0; + err_resp_end_addr = '0; + + if ($value$plusargs("ERR_RESP_START_ADDR=%x", err_resp_start_addr)) begin + if ($value$plusargs("ERR_RESP_END_ADDR=%x", err_resp_end_addr)) begin + cmdline_err_resp_enable = 1'b1; + $display("[%0t] TB: Err response injection enabled for address range 0x%09h to 0x%09h", $time, err_resp_start_addr, err_resp_end_addr); + end else begin + $error("TB: ERR_RESP_START_ADDR specified but ERR_RESP_END_ADDR missing. Err injection disabled."); + end + end + end + + assign err_resp_enable = cmdline_err_resp_enable && axi_error_inj_en; + + // Function to check if address is in error injection range + function automatic logic addr_in_err_range(logic [`CALIPTRA_AXI_DMA_ADDR_WIDTH-1:0] addr); + return err_resp_enable && (addr >= err_resp_start_addr) && (addr <= err_resp_end_addr);; + endfunction + + //=========================================================================- + // Local i/fs + //=========================================================================- + axi_if #( + .AW(AXI_SRAM_ADDR_WIDTH), + .DW(CPTRA_AXI_DMA_DATA_WIDTH), + .IW(CPTRA_AXI_DMA_ID_WIDTH), + .UW(CPTRA_AXI_DMA_USER_WIDTH) + ) axi_sram_if (.clk(core_clk), .rst_n(cptra_rst_b)); + logic axi_sram_if_bvalid_force; // Intermediary signal that can be 'forced' without impacting axi_sub logic + axi_if #( + .AW(AXI_FIFO_ADDR_WIDTH), + .DW(CPTRA_AXI_DMA_DATA_WIDTH), + .IW(CPTRA_AXI_DMA_ID_WIDTH), + .UW(CPTRA_AXI_DMA_USER_WIDTH) + ) axi_fifo_if (.clk(core_clk), .rst_n(cptra_rst_b)); + logic axi_fifo_if_bvalid_force; // Intermediary signal that can be 'forced' without impacting axi_sub logic + + + //=========================================================================- + // AXI Protocol Checker + //=========================================================================- + `ifdef AXI4PC + Axi4PC #( + .DATA_WIDTH (CPTRA_AXI_DMA_DATA_WIDTH ), + .WID_WIDTH (CPTRA_AXI_DMA_ID_WIDTH ), + .RID_WIDTH (CPTRA_AXI_DMA_ID_WIDTH ), + .ADDR_WIDTH (`CALIPTRA_AXI_DMA_ADDR_WIDTH), + .AWUSER_WIDTH(CPTRA_AXI_DMA_USER_WIDTH ), + .WUSER_WIDTH (CPTRA_AXI_DMA_USER_WIDTH ), + .BUSER_WIDTH (CPTRA_AXI_DMA_USER_WIDTH ), + .ARUSER_WIDTH(CPTRA_AXI_DMA_USER_WIDTH ), + .RUSER_WIDTH (CPTRA_AXI_DMA_USER_WIDTH ), +// .MAXWAITS (256 ), + .RecMaxWaitOn(0 ) + ) axi4_pc_inst ( + // Global Signals + .ACLK (core_clk ), + .ARESETn(cptra_rst_b), + + // Write Address Channel + .AWID (m_axi_if.awid), + .AWADDR (m_axi_if.awaddr), + .AWLEN (m_axi_if.awlen), + .AWSIZE (m_axi_if.awsize), + .AWBURST (m_axi_if.awburst), + .AWLOCK (m_axi_if.awlock), + .AWCACHE (4'h0), + .AWPROT (3'h0), + .AWQOS (4'h0), + .AWREGION(4'h0), + .AWUSER (m_axi_if.awuser), + .AWVALID (m_axi_if.awvalid), + .AWREADY (m_axi_if.awready), + + // Write Channel + .WLAST (m_axi_if.wlast), + .WDATA (m_axi_if.wdata), + .WSTRB (m_axi_if.wstrb), + .WUSER (m_axi_if.wuser), + .WVALID (m_axi_if.wvalid), + .WREADY (m_axi_if.wready), + + // Write Response Channel + .BID (m_axi_if.bid), + .BRESP (m_axi_if.bresp), + .BUSER (m_axi_if.buser), + .BVALID (m_axi_if.bvalid), + .BREADY (m_axi_if.bready), + + // Read Address Channel + .ARID (m_axi_if.arid), + .ARADDR (m_axi_if.araddr), + .ARLEN (m_axi_if.arlen), + .ARSIZE (m_axi_if.arsize), + .ARBURST (m_axi_if.arburst), + .ARLOCK (m_axi_if.arlock), + .ARCACHE (4'h0), + .ARPROT (3'h0), + .ARQOS (4'h0), + .ARREGION(4'h0), + .ARUSER (m_axi_if.aruser), + .ARVALID (m_axi_if.arvalid), + .ARREADY (m_axi_if.arready), + + // Read Channel + .RID (m_axi_if.rid), + .RLAST (m_axi_if.rlast), + .RDATA (m_axi_if.rdata), + .RRESP (m_axi_if.rresp), + .RUSER (m_axi_if.ruser), + .RVALID (m_axi_if.rvalid), + .RREADY (m_axi_if.rready), + + // Low power interface + .CACTIVE (1'b0), + .CSYSREQ (1'b0), + .CSYSACK (1'b0) + ); + `endif + + + //=========================================================================- + // Delay Injection + //=========================================================================- + `define GENERIC_2SIG_DLY_TEMPLATE(GEN_NAME, cnt_var, rdy_sig_path, vld_sig_path) \ + logic [11:0] cnt_var; \ + bit GEN_NAME``_past_shake_stall; \ + always@(posedge core_clk) \ + GEN_NAME``_past_shake_stall <= vld_sig_path && !rdy_sig_path; \ + initial begin: GEN_NAME \ + `ifndef VERILATOR \ + if (!std::randomize(cnt_var) with {cnt_var dist {[0:1] :/ 500, [2:7] :/ 75, [8:31] :/ 3, [32:255] :/ 1}; }) \ + $fatal("Randomize %s failed", `"cnt_var`"); \ + `else \ + cnt_var = $urandom_range(7,0); \ + `endif \ + forever begin \ + @(negedge core_clk) \ + if (ctrl.rand_delays) begin \ + if (|cnt_var && !GEN_NAME``_past_shake_stall) begin \ + cnt_var = cnt_var - 1; \ + force rdy_sig_path = 1'b0; \ + force vld_sig_path = 1'b0; \ + end \ + `ifndef VERILATOR \ + else if (!std::randomize(cnt_var) with {cnt_var dist {[0:1] :/ 500, [2:7] :/ 75, [8:31] :/ 3, [32:255] :/ 1}; }) begin \ + $fatal("Randomize %s failed", `"cnt_var`"); \ + end \ + `endif \ + else begin \ + `ifdef VERILATOR \ + cnt_var = $urandom_range(7,0); \ + `endif \ + release rdy_sig_path; \ + release vld_sig_path; \ + end \ + end \ + else begin \ + release rdy_sig_path; \ + release vld_sig_path; \ + end \ + end \ + end: GEN_NAME \ + + // --------------------- SRAM --------------------- + `GENERIC_2SIG_DLY_TEMPLATE (AXI_SRAM_AR_DLY, i_axi_sram_ar_dly_cnt, axi_sram_if.arready , axi_sram_if.arvalid ) + `GENERIC_2SIG_DLY_TEMPLATE (AXI_SRAM_R_DLY , i_axi_sram_r_dly_cnt, axi_sram_if.rready , axi_sram_if.rvalid ) + `GENERIC_2SIG_DLY_TEMPLATE (AXI_SRAM_AW_DLY, i_axi_sram_aw_dly_cnt, i_axi_sram.i_axi_sub.i_axi_sub_wr.axi_awready_q , i_axi_sram.i_axi_sub.i_axi_sub_wr.axi_awvalid_q ) + `GENERIC_2SIG_DLY_TEMPLATE (AXI_SRAM_W_DLY , i_axi_sram_w_dly_cnt, i_axi_sram.i_axi_sub.i_axi_sub_wr.txn_wready , i_axi_sram.i_axi_sub.i_axi_sub_wr.txn_wvalid ) + `GENERIC_2SIG_DLY_TEMPLATE (AXI_SRAM_B_DLY , i_axi_sram_b_dly_cnt, axi_sram_if.bready , axi_sram_if_bvalid_force ) + // --------------------- FIFO --------------------- + `GENERIC_2SIG_DLY_TEMPLATE (AXI_FIFO_AR_DLY, i_axi_fifo_ar_dly_cnt, axi_fifo_if.arready , axi_fifo_if.arvalid ) + `GENERIC_2SIG_DLY_TEMPLATE (AXI_FIFO_R_DLY , i_axi_fifo_r_dly_cnt, axi_fifo_if.rready , axi_fifo_if.rvalid ) + `GENERIC_2SIG_DLY_TEMPLATE (AXI_FIFO_AW_DLY, i_axi_fifo_aw_dly_cnt, i_axi_fifo.i_axi_sub.i_axi_sub_wr.axi_awready_q , i_axi_fifo.i_axi_sub.i_axi_sub_wr.axi_awvalid_q ) + `GENERIC_2SIG_DLY_TEMPLATE (AXI_FIFO_W_DLY , i_axi_fifo_w_dly_cnt, i_axi_fifo.i_axi_sub.i_axi_sub_wr.txn_wready , i_axi_fifo.i_axi_sub.i_axi_sub_wr.txn_wvalid ) + `GENERIC_2SIG_DLY_TEMPLATE (AXI_FIFO_B_DLY , i_axi_fifo_b_dly_cnt, axi_fifo_if.bready , axi_fifo_if_bvalid_force ) + + + //=========================================================================- + // Dummy interconnect + //=========================================================================- + // Error injection signals + logic inject_read_err; + logic inject_write_err; + logic inject_write_err_pending; // Set when AW is received, cleared when wlast+bresp is sent + logic [`CALIPTRA_AXI_DMA_ADDR_WIDTH-1:0] read_addr_reg; + logic [`CALIPTRA_AXI_DMA_ADDR_WIDTH-1:0] write_addr_reg; + + logic err_addr_detected; + logic err_addr_detected_1d; + + assign err_addr_detected = inject_read_err || inject_write_err ? 1'b1 : err_addr_detected_1d; + + // Register read and write addresses for error injection + always_ff@(posedge core_clk or negedge cptra_rst_b) begin + if (!cptra_rst_b) begin + read_addr_reg <= '0; + write_addr_reg <= '0; + inject_read_err <= 1'b0; + inject_write_err <= 1'b0; + inject_write_err_pending <= 1'b0; + err_addr_detected_1d <= 1'b0; + end else begin + + err_addr_detected_1d <= err_addr_detected; + // Capture read address and check for error injection + if (m_axi_if.arvalid && m_axi_if.arready) begin + read_addr_reg <= m_axi_if.araddr; + inject_read_err <= (addr_in_err_range(m_axi_if.araddr) && (err_addr_detected_1d == 0)); + if (addr_in_err_range(m_axi_if.araddr) && (err_addr_detected_1d == 0)) begin + $display("[%0t] TB: Injecting read err for address 0x%08h",$time, m_axi_if.araddr); + end + end + + // Capture write address and check for error injection + if (m_axi_if.awvalid && m_axi_if.awready) begin + write_addr_reg <= m_axi_if.awaddr; + inject_write_err_pending <= (addr_in_err_range(m_axi_if.awaddr) && (err_addr_detected_1d == 0)); + if (addr_in_err_range(m_axi_if.awaddr) && (err_addr_detected_1d == 0)) begin + $display("[%0t] TB: Injecting write err for address 0x%08h",$time, m_axi_if.awaddr); + end + end + + // Assert write error response only after receiving wlast + if (inject_write_err_pending && m_axi_if.wvalid && m_axi_if.wready && m_axi_if.wlast) begin + inject_write_err <= 1'b1; + inject_write_err_pending <= 1'b0; + $display("[%0t] TB: Write err response ready after wlast for address 0x%08h",$time, write_addr_reg); + end + + // Clear error injection flags when responses are sent + if (m_axi_if.rvalid && m_axi_if.rready && m_axi_if.rlast) begin + inject_read_err <= 1'b0; + end + if (m_axi_if.bvalid && m_axi_if.bready) begin + inject_write_err <= 1'b0; + end + end + end + + // --------------------- Endpoint mux --------------------- + logic [1:0] sram_r_active; + logic sram_ar_hshake; + logic sram_rlast_hshake; + + logic [2:0] sram_w_active; + logic sram_aw_hshake; + logic sram_b_hshake; + + logic [1:0] fifo_r_active; + logic fifo_ar_hshake; + logic fifo_rlast_hshake; + + logic [2:0] fifo_w_active; + logic fifo_aw_hshake; + logic fifo_b_hshake; + + always_comb begin + // AXI AR - Block ready when injecting errors + m_axi_if.arready = (addr_in_err_range(m_axi_if.araddr) && (err_addr_detected_1d == 0))? 1'b1 : + (m_axi_if.araddr[`CALIPTRA_AXI_DMA_ADDR_WIDTH-1:AXI_SRAM_ADDR_WIDTH] == + AXI_SRAM_BASE_ADDR[`CALIPTRA_AXI_DMA_ADDR_WIDTH-1:AXI_SRAM_ADDR_WIDTH]) ? + axi_sram_if.arready : + (m_axi_if.araddr[`CALIPTRA_AXI_DMA_ADDR_WIDTH-1:AXI_FIFO_ADDR_WIDTH] == + AXI_FIFO_BASE_ADDR[`CALIPTRA_AXI_DMA_ADDR_WIDTH-1:AXI_FIFO_ADDR_WIDTH]) ? + axi_fifo_if.arready : 1'b0; + + // AXI R - Inject error responses when needed + m_axi_if.rdata = sram_r_active ? axi_sram_if.rdata : + fifo_r_active ? axi_fifo_if.rdata : + '0; + m_axi_if.rresp = inject_read_err ? axi_pkg::AXI_RESP_SLVERR: + sram_r_active ? axi_sram_if.rresp : + fifo_r_active ? axi_fifo_if.rresp : + axi_pkg::AXI_RESP_OKAY; + + m_axi_if.rid = sram_r_active ? axi_sram_if.rid : + fifo_r_active ? axi_fifo_if.rid : + '0; + + m_axi_if.ruser = sram_r_active ? axi_sram_if.ruser : + fifo_r_active ? axi_fifo_if.ruser : + '0; + m_axi_if.rlast = sram_r_active ? axi_sram_if.rlast : + fifo_r_active ? axi_fifo_if.rlast : + '0; + + m_axi_if.rvalid = sram_r_active ? axi_sram_if.rvalid : + fifo_r_active ? axi_fifo_if.rvalid : + '0; + + // AXI AW - Block ready when injecting errors + m_axi_if.awready = (addr_in_err_range(m_axi_if.awaddr) && (err_addr_detected_1d == 0)) ? 1'b1 : + (m_axi_if.awaddr[`CALIPTRA_AXI_DMA_ADDR_WIDTH-1:AXI_SRAM_ADDR_WIDTH] == + AXI_SRAM_BASE_ADDR[`CALIPTRA_AXI_DMA_ADDR_WIDTH-1:AXI_SRAM_ADDR_WIDTH]) ? + axi_sram_if.awready : + (m_axi_if.awaddr[`CALIPTRA_AXI_DMA_ADDR_WIDTH-1:AXI_FIFO_ADDR_WIDTH] == + AXI_FIFO_BASE_ADDR[`CALIPTRA_AXI_DMA_ADDR_WIDTH-1:AXI_FIFO_ADDR_WIDTH]) ? + axi_fifo_if.awready : 1'b0; + + // AXI W - Accept data when injecting errors, but don't forward + m_axi_if.wready = (inject_write_err || inject_write_err_pending) ? 1'b1 : + sram_w_active ? axi_sram_if.wready : + fifo_w_active ? axi_fifo_if.wready : + 1'b0; + + // AXI B - Inject error responses when needed + m_axi_if.bresp = inject_write_err ? axi_pkg::AXI_RESP_SLVERR : + sram_w_active ? axi_sram_if.bresp : + fifo_w_active ? axi_fifo_if.bresp : + axi_pkg::AXI_RESP_OKAY; + + m_axi_if.bid = sram_w_active ? axi_sram_if.bid : + fifo_w_active ? axi_fifo_if.bid : + '0; + m_axi_if.buser = sram_w_active ? axi_sram_if.buser : + fifo_w_active ? axi_fifo_if.buser : + '0; + m_axi_if.bvalid = inject_write_err ? 1'b1 : + sram_w_active ? axi_sram_if_bvalid_force : + fifo_w_active ? axi_fifo_if_bvalid_force : + '0; + end + `CALIPTRA_ASSERT(AXI_COMPLEX_RD_DECODE, m_axi_if.arvalid |-> (m_axi_if.araddr[`CALIPTRA_AXI_DMA_ADDR_WIDTH-1:AXI_SRAM_ADDR_WIDTH] == AXI_SRAM_BASE_ADDR[`CALIPTRA_AXI_DMA_ADDR_WIDTH-1:AXI_SRAM_ADDR_WIDTH]) || (m_axi_if.araddr[`CALIPTRA_AXI_DMA_ADDR_WIDTH-1:AXI_FIFO_ADDR_WIDTH] == AXI_FIFO_BASE_ADDR[`CALIPTRA_AXI_DMA_ADDR_WIDTH-1:AXI_FIFO_ADDR_WIDTH]), core_clk, !cptra_rst_b) + `CALIPTRA_ASSERT(AXI_COMPLEX_WR_DECODE, m_axi_if.awvalid |-> (m_axi_if.awaddr[`CALIPTRA_AXI_DMA_ADDR_WIDTH-1:AXI_SRAM_ADDR_WIDTH] == AXI_SRAM_BASE_ADDR[`CALIPTRA_AXI_DMA_ADDR_WIDTH-1:AXI_SRAM_ADDR_WIDTH]) || (m_axi_if.awaddr[`CALIPTRA_AXI_DMA_ADDR_WIDTH-1:AXI_FIFO_ADDR_WIDTH] == AXI_FIFO_BASE_ADDR[`CALIPTRA_AXI_DMA_ADDR_WIDTH-1:AXI_FIFO_ADDR_WIDTH]), core_clk, !cptra_rst_b) + + // --------------------- SRAM Endpoint --------------------- + always_comb begin + sram_ar_hshake = axi_sram_if.arvalid && axi_sram_if.arready; + sram_rlast_hshake = axi_sram_if.rvalid && axi_sram_if.rready && axi_sram_if.rlast; + end + always_ff@(posedge core_clk or negedge cptra_rst_b) begin + if (!cptra_rst_b) begin + sram_r_active <= 2'b0;; + end + else begin + case ({sram_ar_hshake,sram_rlast_hshake}) inside + 2'b00: + sram_r_active <= sram_r_active; + 2'b01: + if (sram_r_active) + sram_r_active <= sram_r_active - 2'b1; + else + $fatal("Read data with last, but no reads outstanding!"); + 2'b10: + sram_r_active <= sram_r_active + 2'b1; + 2'b11: + sram_r_active <= sram_r_active; + endcase + end + end + `CALIPTRA_ASSERT_NEVER(SRAM_GT2_RD_PENDING, sram_r_active > 2, core_clk, !cptra_rst_b) + always_comb begin + sram_aw_hshake = axi_sram_if.awvalid && axi_sram_if.awready; + sram_b_hshake = axi_sram_if_bvalid_force && axi_sram_if.bready; + end + always_ff@(posedge core_clk or negedge cptra_rst_b) begin + if (!cptra_rst_b) begin + sram_w_active <= 3'b0; + end + else begin + case ({sram_aw_hshake,sram_b_hshake}) inside + 2'b00: + sram_w_active <= sram_w_active; + 2'b01: + if (sram_w_active) + sram_w_active <= sram_w_active - 3'b1; + else + $fatal("Write response, but no writes outstanding!"); + 2'b10: + sram_w_active <= sram_w_active + 3'b1; + 2'b11: + sram_w_active <= sram_w_active; + endcase + end + end + // In rare cases, small write requests while generating backpressure on Write response channel can cause + // 1 write response pending on output reg + // 1 write response pending in response buffer + // 1 write request active + // 1 write request accepted and pending + `CALIPTRA_ASSERT_NEVER(SRAM_GT4_WR_PENDING, (sram_w_active == 4) && sram_aw_hshake && !sram_b_hshake, core_clk, !cptra_rst_b) + + // AXI AR - Don't forward requests when injecting errors + assign axi_sram_if.arvalid = m_axi_if.arvalid + && (m_axi_if.araddr[`CALIPTRA_AXI_DMA_ADDR_WIDTH-1:AXI_SRAM_ADDR_WIDTH] + == AXI_SRAM_BASE_ADDR[`CALIPTRA_AXI_DMA_ADDR_WIDTH-1:AXI_SRAM_ADDR_WIDTH]) ; + assign axi_sram_if.araddr = m_axi_if.araddr[AXI_SRAM_ADDR_WIDTH-1:0]; + assign axi_sram_if.arburst = m_axi_if.arburst; + assign axi_sram_if.arsize = m_axi_if.arsize ; + assign axi_sram_if.arlen = m_axi_if.arlen ; + assign axi_sram_if.aruser = m_axi_if.aruser ; + assign axi_sram_if.arid = m_axi_if.arid ; + assign axi_sram_if.arlock = m_axi_if.arlock ; + + // AXI R + assign axi_sram_if.rready = sram_r_active ? m_axi_if.rready : '0; + + // AXI AW - Don't forward requests when injecting errors + assign axi_sram_if.awvalid = m_axi_if.awvalid && + !(addr_in_err_range(m_axi_if.awaddr) && (err_addr_detected_1d == 0))&& + m_axi_if.awaddr[`CALIPTRA_AXI_DMA_ADDR_WIDTH-1:AXI_SRAM_ADDR_WIDTH] == + AXI_SRAM_BASE_ADDR[`CALIPTRA_AXI_DMA_ADDR_WIDTH-1:AXI_SRAM_ADDR_WIDTH]; + assign axi_sram_if.awaddr = m_axi_if.awaddr[AXI_SRAM_ADDR_WIDTH-1:0]; + assign axi_sram_if.awburst = m_axi_if.awburst; + assign axi_sram_if.awsize = m_axi_if.awsize ; + assign axi_sram_if.awlen = m_axi_if.awlen ; + assign axi_sram_if.awuser = m_axi_if.awuser ; + assign axi_sram_if.awid = m_axi_if.awid ; + assign axi_sram_if.awlock = m_axi_if.awlock ; + + // AXI W - Don't forward data when injecting errors + logic sram_w_blocked; + assign sram_w_blocked = inject_write_err || inject_write_err_pending; + assign axi_sram_if.wvalid = (sram_w_active && !sram_w_blocked) ? m_axi_if.wvalid : '0; + assign axi_sram_if.wdata = (sram_w_active && !sram_w_blocked) ? m_axi_if.wdata : '0; + assign axi_sram_if.wstrb = (sram_w_active && !sram_w_blocked) ? m_axi_if.wstrb : '0; + assign axi_sram_if.wuser = (sram_w_active && !sram_w_blocked) ? m_axi_if.wuser : '0; + assign axi_sram_if.wlast = (sram_w_active && !sram_w_blocked) ? m_axi_if.wlast : '0; + + // AXI B + assign axi_sram_if.bready = sram_w_active ? m_axi_if.bready : '0; + assign axi_sram_if_bvalid_force = axi_sram_if.bvalid; + + // Fake "MCU" SRAM block + caliptra_axi_sram #( + .AW (AXI_SRAM_ADDR_WIDTH ), + .DW (CPTRA_AXI_DMA_DATA_WIDTH), + .UW (CPTRA_AXI_DMA_USER_WIDTH), + .IW (CPTRA_AXI_DMA_ID_WIDTH ), + .EX_EN(0 ) + ) i_axi_sram ( + .clk(core_clk), + .rst_n(cptra_rst_b), + + // AXI INF + .s_axi_w_if(axi_sram_if.w_sub), + .s_axi_r_if(axi_sram_if.r_sub) + ); + `ifdef VERILATOR + initial i_axi_sram.i_sram.ram = '{default:'{default:8'h00}}; + `else + initial i_axi_sram.i_sram.ram = '{default:8'h00}; + `endif + + // --------------------- FIFO Endpoint --------------------- + always_comb begin + fifo_ar_hshake = axi_fifo_if.arvalid && axi_fifo_if.arready; + fifo_rlast_hshake = axi_fifo_if.rvalid && axi_fifo_if.rready && axi_fifo_if.rlast; + end + always_ff@(posedge core_clk or negedge cptra_rst_b) begin + if (!cptra_rst_b) begin + fifo_r_active <= 2'b0;; + end + else begin + case ({fifo_ar_hshake,fifo_rlast_hshake}) inside + 2'b00: + fifo_r_active <= fifo_r_active; + 2'b01: + if (fifo_r_active) + fifo_r_active <= fifo_r_active - 2'b1; + else + $fatal("Read data with last, but no reads outstanding!"); + 2'b10: + fifo_r_active <= fifo_r_active + 2'b1; + 2'b11: + fifo_r_active <= fifo_r_active; + endcase + end + end + `CALIPTRA_ASSERT_NEVER(FIFO_GT2_RD_PENDING, fifo_r_active > 2, core_clk, !cptra_rst_b) + always_comb begin + fifo_aw_hshake = axi_fifo_if.awvalid && axi_fifo_if.awready; + fifo_b_hshake = axi_fifo_if_bvalid_force && axi_fifo_if.bready; + end + always_ff@(posedge core_clk or negedge cptra_rst_b) begin + if (!cptra_rst_b) begin + fifo_w_active <= 3'b0; + end + else begin + case ({fifo_aw_hshake,fifo_b_hshake}) inside + 2'b00: + fifo_w_active <= fifo_w_active; + 2'b01: + if (fifo_w_active) + fifo_w_active <= fifo_w_active - 3'b1; + else + $fatal("Write response, but no writes outstanding!"); + 2'b10: + fifo_w_active <= fifo_w_active + 3'b1; + 2'b11: + fifo_w_active <= fifo_w_active; + endcase + end + end + // In rare cases, small write requests while generating backpressure on Write response channel can cause + // 1 write response pending on output reg + // 1 write response pending in response buffer + // 1 write request active + // 1 write request accepted and pending + `CALIPTRA_ASSERT_NEVER(FIFO_GT4_WR_PENDING, (fifo_w_active == 4) && fifo_aw_hshake && !fifo_b_hshake, core_clk, !cptra_rst_b) + + logic [31:0] fifo_aw_hshake_count, fifo_b_hshake_count; + logic [31:0] fifo_b_hshake_count_expected; + logic [11:0] awlen_active; + logic awlen_busy; + int awlen_active_q [$]; + + initial begin + forever begin + @(posedge core_clk); + if (!cptra_rst_b) begin + awlen_active = '0; + awlen_busy = '0; + awlen_active_q.delete(); + fifo_b_hshake_count_expected = 0; + end + if (fifo_aw_hshake && awlen_busy) begin + awlen_active_q.push_front(axi_fifo_if.awlen); + end + else if (fifo_aw_hshake) begin + awlen_active = axi_fifo_if.awlen; + awlen_busy = 1; + end + if (axi_fifo_if.wvalid && axi_fifo_if.wready && (awlen_busy == 0)) begin + $fatal("TB: Write data to AXI Complex FIFO while awlen_busy == 0; check TB for logic error."); + end + else if (axi_fifo_if.wvalid && axi_fifo_if.wready && (awlen_active == 0)) begin + awlen_busy = 0; + fifo_b_hshake_count_expected += 1; + end + else if (axi_fifo_if.wvalid && axi_fifo_if.wready) begin + awlen_active -= 1; + end + if (!awlen_busy && (awlen_active_q.size() != 0)) begin + awlen_busy = 1; + awlen_active = awlen_active_q.pop_back(); + end + end + end + + always@(posedge core_clk or negedge cptra_rst_b) begin + if (!cptra_rst_b) begin + fifo_aw_hshake_count <= '0; + fifo_b_hshake_count <= '0; + end + else begin + fifo_aw_hshake_count <= fifo_aw_hshake_count + (fifo_aw_hshake ? 32'h1 : 32'h0); + fifo_b_hshake_count <= fifo_b_hshake_count + (fifo_b_hshake ? 32'h1 : 32'h0); + end + end + + // AXI AR + assign axi_fifo_if.arvalid = m_axi_if.arvalid && m_axi_if.araddr[`CALIPTRA_AXI_DMA_ADDR_WIDTH-1:AXI_FIFO_ADDR_WIDTH] == AXI_FIFO_BASE_ADDR[`CALIPTRA_AXI_DMA_ADDR_WIDTH-1:AXI_FIFO_ADDR_WIDTH]; + assign axi_fifo_if.araddr = m_axi_if.araddr[AXI_FIFO_ADDR_WIDTH-1:0]; + assign axi_fifo_if.arburst = m_axi_if.arburst; + assign axi_fifo_if.arsize = m_axi_if.arsize ; + assign axi_fifo_if.arlen = m_axi_if.arlen ; + assign axi_fifo_if.aruser = m_axi_if.aruser ; + assign axi_fifo_if.arid = m_axi_if.arid ; + assign axi_fifo_if.arlock = m_axi_if.arlock ; + + // AXI R + assign axi_fifo_if.rready = fifo_r_active ? m_axi_if.rready : '0; + + // AXI AW - Don't forward requests when injecting errors + assign axi_fifo_if.awvalid = m_axi_if.awvalid && + !(addr_in_err_range(m_axi_if.awaddr) && (err_addr_detected_1d == 0)) && + m_axi_if.awaddr[`CALIPTRA_AXI_DMA_ADDR_WIDTH-1:AXI_FIFO_ADDR_WIDTH] == + AXI_FIFO_BASE_ADDR[`CALIPTRA_AXI_DMA_ADDR_WIDTH-1:AXI_FIFO_ADDR_WIDTH]; + assign axi_fifo_if.awaddr = m_axi_if.awaddr[AXI_FIFO_ADDR_WIDTH-1:0]; + assign axi_fifo_if.awburst = m_axi_if.awburst; + assign axi_fifo_if.awsize = m_axi_if.awsize ; + assign axi_fifo_if.awlen = m_axi_if.awlen ; + assign axi_fifo_if.awuser = m_axi_if.awuser ; + assign axi_fifo_if.awid = m_axi_if.awid ; + assign axi_fifo_if.awlock = m_axi_if.awlock ; + + // AXI W - Don't forward data when injecting errors + logic fifo_w_blocked; + assign fifo_w_blocked = inject_write_err || inject_write_err_pending; + assign axi_fifo_if.wvalid = (fifo_w_active && !fifo_w_blocked) ? m_axi_if.wvalid : '0; + assign axi_fifo_if.wdata = (fifo_w_active && !fifo_w_blocked) ? m_axi_if.wdata : '0; + assign axi_fifo_if.wstrb = (fifo_w_active && !fifo_w_blocked) ? m_axi_if.wstrb : '0; + assign axi_fifo_if.wuser = (fifo_w_active && !fifo_w_blocked) ? m_axi_if.wuser : '0; + assign axi_fifo_if.wlast = (fifo_w_active && !fifo_w_blocked) ? m_axi_if.wlast : '0; + + // AXI B + assign axi_fifo_if.bready = fifo_w_active ? m_axi_if.bready : '0; + assign axi_fifo_if_bvalid_force = axi_fifo_if.bvalid; + + `CALIPTRA_ASSERT_NEVER(FIFO_RD_NOT_FIXED, fifo_ar_hshake && (axi_fifo_if.arburst != AXI_BURST_FIXED), core_clk, !cptra_rst_b) + `CALIPTRA_ASSERT_NEVER(FIFO_WR_NOT_FIXED, fifo_aw_hshake && (axi_fifo_if.awburst != AXI_BURST_FIXED), core_clk, !cptra_rst_b) + `CALIPTRA_ASSERT_NEVER(FIFO_1RD_FOR_RCVY_EMU, (fifo_r_active > 1) && ctrl.en_recovery_emulation, core_clk, !cptra_rst_b) + + caliptra_top_tb_axi_fifo #( + .AW(AXI_FIFO_ADDR_WIDTH ), + .DW(CPTRA_AXI_DMA_DATA_WIDTH), + .UW(CPTRA_AXI_DMA_USER_WIDTH), // User Width + .IW(CPTRA_AXI_DMA_ID_WIDTH ), // ID Width + .DEPTH(AXI_FIFO_SIZE_BYTES ) + ) i_axi_fifo ( + .clk (core_clk ), + .rst_n(cptra_rst_b), + + // AXI INF + .s_axi_w_if(axi_fifo_if.w_sub), + .s_axi_r_if(axi_fifo_if.r_sub), + + // Control + .auto_push (ctrl.fifo_auto_push ), + .auto_pop (ctrl.fifo_auto_pop ), + .fifo_clear (ctrl.fifo_clear ), + .en_recovery_emulation(ctrl.en_recovery_emulation), + .recovery_data_avail (recovery_data_avail ), + .dma_gen_done (ctrl.dma_gen_done ), + .dma_gen_block_size (ctrl.dma_gen_block_size ) + ); + + // --------------------- REG Endpoint TODO --------------------- + + `CALIPTRA_ASSERT_MUTEX(DMA_NO_SIMULT_RD, {|sram_r_active,|fifo_r_active/*TODO*/}, core_clk, !cptra_rst_b) + `CALIPTRA_ASSERT_MUTEX(DMA_NO_SIMULT_WR, {|sram_w_active,|fifo_w_active/*TODO*/}, core_clk, !cptra_rst_b) + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_top_tb_axi_fifo.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_top_tb_axi_fifo.sv new file mode 100644 index 0000000..bb940bd --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_top_tb_axi_fifo.sv @@ -0,0 +1,351 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. + + +module caliptra_top_tb_axi_fifo #( + parameter AW = 32, + parameter DW = 64, + BC = DW/8, // Byte Count + BW = $clog2(BC), // Byte count Width + parameter UW = 32, // User Width + parameter IW = 1, // ID Width + ID_NUM = 1 << IW,// Don't override + parameter DEPTH = 16 +) +( + input clk, + input rst_n, + + // AXI INF + axi_if.w_sub s_axi_w_if, + axi_if.r_sub s_axi_r_if, + + // Control + input logic auto_push, + input logic auto_pop, + input logic fifo_clear, + input logic en_recovery_emulation, + output logic recovery_data_avail, + input logic dma_gen_done, + input logic [99:0] [11:0] dma_gen_block_size +); + + // --------------------------------------- // + // Localparams/Typedefs // + // --------------------------------------- // + + import axi_pkg::*; + + localparam FIFO_BC = DEPTH; // depth in bytes + localparam FIFO_BW = caliptra_prim_util_pkg::vbits((FIFO_BC/BC)+1); // width of a signal that reports FIFO slot consumption + + int RECOVERY_BURST_TEST_SIZE; + + //COMPONENT INF + logic dv; + logic [AW-1:0] addr; // Byte address + logic write; + logic [DW-1:0] wdata; // Requires: Component dwidth == AXI dwidth + logic [DW-1:0] rdata; // Requires: Component dwidth == AXI dwidth + logic hold; + logic rd_error; + logic wr_error; + + // FIFO signals + logic fifo_w_ready; + logic fifo_w_valid; + logic [DW-1:0] fifo_w_data; + logic fifo_r_ready; + logic fifo_r_valid; + logic [DW-1:0] fifo_r_data; + logic [FIFO_BW-1:0] fifo_depth; + logic fifo_full, fifo_full_r; + logic fifo_empty, fifo_empty_r; + + // Random stimulus generators + logic [11:0] stall_down_count; + logic [31:0] rand_w_data; + logic rand_w_valid; + logic rand_r_ready; + + + axi_sub #( + .AW (AW), + .DW (DW), + .UW (UW), + .IW (IW), + .EX_EN(0 ), + .C_LAT(0 ) + ) i_axi_sub ( + .clk (clk ), + .rst_n(rst_n ), + + // AXI INF + .s_axi_w_if(s_axi_w_if), + .s_axi_r_if(s_axi_r_if), + + //COMPONENT INF + .dv (dv ), + .addr (addr ), // Byte address + .write (write ), + .user ( ), + .id ( ), + .wdata (wdata ), + .wstrb ( ), + .rdata (rdata ), + .last ( ), + .size ( ), + .hld (hold ), + .rd_err (rd_error), + .wr_err (wr_error) + ); + `CALIPTRA_ASSERT(AXI_FIFO_WR_FIXED_ONLY, s_axi_w_if.awvalid && s_axi_w_if.awready |-> s_axi_w_if.awburst == AXI_BURST_FIXED, clk, !rst_n) + `CALIPTRA_ASSERT(AXI_FIFO_RD_FIXED_ONLY, s_axi_r_if.arvalid && s_axi_r_if.arready |-> s_axi_r_if.arburst == AXI_BURST_FIXED, clk, !rst_n) + + assign rd_error = 1'b0; + assign wr_error = 1'b0; + + // --------------------------------------- // + // Data FIFO // + // --------------------------------------- // + caliptra_prim_fifo_sync #( + .Width (DW ), + .Pass (1'b0), // if == 1 allow requests to pass through empty FIFO + .Depth (FIFO_BC/BC), + .OutputZeroIfEmpty(1'b1), // if == 1 always output 0 when FIFO is empty + .Secure (1'b0) // use prim count for pointers TODO review if this is needed + ) i_fifo ( + .clk_i (clk ), + .rst_ni (rst_n ), + // synchronous clear / flush port + .clr_i (fifo_clear), + // write port + .wvalid_i(fifo_w_valid ), + .wready_o(fifo_w_ready ), + .wdata_i (fifo_w_data ), + // read port + .rvalid_o(fifo_r_valid), + .rready_i(fifo_r_ready), + .rdata_o (fifo_r_data ), + // occupancy + .full_o (fifo_full ), + .depth_o (fifo_depth), + .err_o ( ) + ); + + always_comb fifo_empty = fifo_depth == 0; + always_ff @(posedge clk or negedge rst_n) begin + if (!rst_n) begin + fifo_full_r <= 1'b0; + fifo_empty_r <= 1'b1; + end + else begin + fifo_full_r <= fifo_full; + fifo_empty_r <= fifo_empty; + end + end + + always_comb begin + fifo_w_valid = (dv && write) || rand_w_valid; + fifo_r_ready = (dv && !write) || rand_r_ready; + hold = write ? !fifo_w_ready : !fifo_r_valid; + rdata = fifo_r_data; + fifo_w_data = rand_w_valid ? rand_w_data : wdata; + end + + // --------------------------------------- // + // Random Stimulus // + // --------------------------------------- // + initial begin + `ifndef VERILATOR + if (!std::randomize(stall_down_count) with {stall_down_count dist {[0:1] :/ 75, [2:7] :/ 20, [8:31] :/ 3, [32:255] :/ 1}; }) + $fatal("Randomize failed"); + `else + stall_down_count = $urandom_range(7,0); + `endif + end + always@(posedge clk) begin + if (auto_pop || auto_push) begin + if (|stall_down_count) + stall_down_count <= stall_down_count - 1; + `ifndef VERILATOR + else if (!std::randomize(stall_down_count) with {stall_down_count dist {[0:1] :/ 75, [2:7] :/ 20, [8:31] :/ 3, [32:255] :/ 1}; }) + $fatal("Randomize failed"); + if (!std::randomize(rand_w_data)) + $fatal("Randomize failed"); + `else + else + stall_down_count <= $urandom_range(7,0); + rand_w_data <= $urandom; + `endif + end + rand_w_valid <= !fifo_clear && rst_n && ((auto_push && (stall_down_count == 0)) || (rand_w_valid && !fifo_w_ready)); // Hold valid until data is accepted + rand_r_ready <= rst_n && (auto_pop && (stall_down_count == 0)) && fifo_r_valid; + end + + //=========================================================================- + // Recovery Interface Model + //=========================================================================- + + bit recovery_data_avail_in_not_empty; + bit recovery_data_avail_in_thresh; + bit recovery_data_avail_in_pulse; + bit mode_not_empty; + bit mode_thresh; + bit mode_pulse; + int thresh; + + logic en_recovery_emulation_d, en_recovery_emulation_p; + logic recovery_data_avail_d, recovery_data_avail_p; + logic [FIFO_BW-1:0] fifo_writes_since_avail; + int fifo_writes_since_recovery_emu_start; + int fifo_reads_since_recovery_emu_start; + int recovery_data_avail_deassert_at_fifo_read_count; + + initial begin + if ($test$plusargs("CLP_DMA_TB_MODE_NOT_EMPTY")) begin + mode_not_empty = 1; + end + else if ($test$plusargs("CLP_DMA_TB_MODE_THRESH")) begin + mode_thresh = 1; + end + else if ($test$plusargs("CLP_DMA_TB_MODE_PULSE")) begin + mode_pulse = 1; + end + `ifndef VERILATOR + else if (!std::randomize(mode_pulse,mode_thresh,mode_not_empty) with { $onehot({mode_pulse,mode_thresh,mode_not_empty}); }) begin + $fatal("Failed to randomize recovery_data_avail behavior model!"); + end + `else + else begin + mode_not_empty = 1; + end + `endif + $display("Randomized mode to %s", mode_pulse ? "mode_pulse" : mode_thresh ? "mode_thresh" : mode_not_empty ? "mode_not_empty" : "null"); + `ifndef VERILATOR + if ($test$plusargs("CPTRA_RAND_TEST_DMA")) begin + int block_size_idx = 0; + RECOVERY_BURST_TEST_SIZE = 4; // dummy init value + wait(dma_gen_done); + @(posedge en_recovery_emulation); + forever begin + if (dma_gen_block_size[block_size_idx] != 0) begin + RECOVERY_BURST_TEST_SIZE = dma_gen_block_size[block_size_idx]; + thresh = $urandom_range(RECOVERY_BURST_TEST_SIZE/BC,1); + $display("TB is modelling a block_size of %d from array index %d for recovery_data_avail", RECOVERY_BURST_TEST_SIZE, block_size_idx); + // Hold the value until the next FALLING edge on en_recovery_emulation + // indicating that current testcase using the value is completed + // and we should grab the next value... + @(negedge en_recovery_emulation); + end + // If a reset caused en_recovery_emulation to deassert, test will continue with the same + // test scenario and block_size value after the reset. + // Otherwise, advance to the next testcase and emulate the next block_size value + if (rst_n) begin + block_size_idx++; + if (block_size_idx >= 100) begin + $display("TB Reached end of block_size array, exiting watch loop"); + break; + end + end + end + end + else + `endif + begin + RECOVERY_BURST_TEST_SIZE = 256; // Used for smoke_test_dma, etc. + end + end + + assign recovery_data_avail = recovery_data_avail_in_not_empty | recovery_data_avail_in_thresh | recovery_data_avail_in_pulse; + assign recovery_data_avail_in_not_empty = !fifo_empty & mode_not_empty; + assign recovery_data_avail_in_thresh = (fifo_depth >= thresh) & mode_thresh; + + assign en_recovery_emulation_p = en_recovery_emulation && !en_recovery_emulation_d; + assign recovery_data_avail_p = recovery_data_avail && !recovery_data_avail_d; + + always_ff@(posedge clk or negedge rst_n) begin + if (!rst_n) begin + fifo_writes_since_recovery_emu_start <= '0; + fifo_reads_since_recovery_emu_start <= '0; + recovery_data_avail_deassert_at_fifo_read_count <= '0; + end + else if (!en_recovery_emulation) begin + fifo_writes_since_recovery_emu_start <= '0; + fifo_reads_since_recovery_emu_start <= '0; + recovery_data_avail_deassert_at_fifo_read_count <= '0; + end + else begin + fifo_writes_since_recovery_emu_start <= fifo_writes_since_recovery_emu_start + 32'(fifo_w_valid && fifo_w_ready); + fifo_reads_since_recovery_emu_start <= fifo_reads_since_recovery_emu_start + 32'(fifo_r_valid && fifo_r_ready); + recovery_data_avail_deassert_at_fifo_read_count <= recovery_data_avail_p && ~|recovery_data_avail_deassert_at_fifo_read_count ? 1 : + recovery_data_avail_p ? (recovery_data_avail_deassert_at_fifo_read_count + RECOVERY_BURST_TEST_SIZE/BC) : + recovery_data_avail_deassert_at_fifo_read_count; + end + end + always_ff@(posedge clk or negedge rst_n) begin + if (!rst_n) begin + en_recovery_emulation_d <= 1'b0; + recovery_data_avail_d <= 1'b0; + end + else begin + en_recovery_emulation_d <= en_recovery_emulation; + recovery_data_avail_d <= recovery_data_avail_in_pulse && en_recovery_emulation; + end + end + // TODO ASSERT on first dword to FIFO + // assert once RECOVERY_BURST_TEST_SIZE bytes are pushed to FIFO + // TODO deassert after full FIFO payload is read + // deassert once 1 entry is ready from FIFO, unless another RECOVERY_BURST_TEST_SIZE bytes have already + // been pushed since it first asserted + always_ff@(posedge clk or negedge rst_n) begin + if (!rst_n) begin + recovery_data_avail_in_pulse <= 1'b0; + end + else if (!en_recovery_emulation || !mode_pulse) begin + recovery_data_avail_in_pulse <= 1'b0; + end + else if (fifo_writes_since_avail >= RECOVERY_BURST_TEST_SIZE/BC) begin + recovery_data_avail_in_pulse <= 1'b1; + if (recovery_data_avail_in_pulse == 1'b0) + $display("SoC [%t]: Set recovery_data_avail_in_pulse", $time); + end + else if (fifo_r_valid && fifo_r_ready && (fifo_reads_since_recovery_emu_start == (recovery_data_avail_deassert_at_fifo_read_count - 1))) begin + recovery_data_avail_in_pulse <= 1'b0; + end + end + // start counting when recovery emulation enabled + // decrement on the edge of recovery_data_avail_in_pulse + always_ff@(posedge clk or negedge rst_n) begin + if (!rst_n) begin + fifo_writes_since_avail <= '0; + end + else if (!en_recovery_emulation) + fifo_writes_since_avail <= '0; + else begin + case ({(fifo_w_valid && fifo_w_ready),recovery_data_avail_p}) inside + 2'b00: fifo_writes_since_avail <= fifo_writes_since_avail; + 2'b01: fifo_writes_since_avail <= fifo_writes_since_avail - RECOVERY_BURST_TEST_SIZE/BC; + 2'b10: fifo_writes_since_avail <= fifo_writes_since_avail + 1; + 2'b11: fifo_writes_since_avail <= fifo_writes_since_avail - RECOVERY_BURST_TEST_SIZE/BC + 1; + endcase + end + end + + `CALIPTRA_ASSERT(RCVY_TEST_BYTE_SIZE_POW2, $onehot(RECOVERY_BURST_TEST_SIZE), clk, !rst_n) /* power of 2 requirement */ + `CALIPTRA_ASSERT(RCVY_TEST_BYTE_SIZE_GT_BC, RECOVERY_BURST_TEST_SIZE >= BC, clk, !rst_n) + `CALIPTRA_ASSERT(AXI_COMPLEX_EMPTY_ON_RCVY, en_recovery_emulation_p |-> fifo_depth == 0, clk, !rst_n) + + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_top_tb_pkg.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_top_tb_pkg.sv new file mode 100644 index 0000000..2ec7773 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_top_tb_pkg.sv @@ -0,0 +1,120 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +// + +package caliptra_top_tb_pkg; +import soc_ifc_pkg::*; +import axi_pkg::*; + +`ifndef VERILATOR +class bitflip_mask_generator #(int CPTRA_MBOX_DATA_AND_ECC_W = 39); + + rand logic [CPTRA_MBOX_DATA_AND_ECC_W-1:0] rand_sram_bitflip_mask; + logic do_double_bitflip; + constraint bitflip_c { + if (do_double_bitflip) { + $countones(rand_sram_bitflip_mask) == 2; + } else { + $countones(rand_sram_bitflip_mask) == 1; + } + } + + function new; + this.rand_sram_bitflip_mask = '0; + this.do_double_bitflip = 1'b0; + endfunction + + function logic [CPTRA_MBOX_DATA_AND_ECC_W-1:0] get_mask(bit do_double_bit = 1'b0); + this.do_double_bitflip = do_double_bit; + this.randomize(); + return this.rand_sram_bitflip_mask; + endfunction + +endclass +`else +function static logic [soc_ifc_pkg::CPTRA_MBOX_DATA_AND_ECC_W-1:0] get_bitflip_mask(bit do_double_bit = 1'b0); + return 2<<($urandom%(soc_ifc_pkg::CPTRA_MBOX_DATA_AND_ECC_W-2)) | soc_ifc_pkg::CPTRA_MBOX_DATA_AND_ECC_W'(do_double_bit); +endfunction +`endif + +typedef struct packed { + // [3] - Double bit, DCCM Error Injection + // [2] - Single bit, DCCM Error Injection + // [1] - Double bit, ICCM Error Injection + // [0] - Single bit, ICCM Error Injection + logic dccm_double_bit_error; + logic dccm_single_bit_error; + logic iccm_double_bit_error; + logic iccm_single_bit_error; +} veer_sram_error_injection_mode_t; + +typedef struct packed { + logic [31:0] addr; + logic [19:0] count; + logic start; +} rv_ccm_read_burst_pkt; +typedef struct packed { + rv_ccm_read_burst_pkt dccm_read_burst; + rv_ccm_read_burst_pkt iccm_read_burst; + logic error_injection_seen; + logic reset_generic_input_wires; + logic do_no_lock_access; + logic do_ooo_access; +} ras_test_ctrl_t; + +typedef struct packed { + logic fifo_auto_push; + logic fifo_auto_pop; + logic fifo_clear; + logic rand_delays; + logic en_recovery_emulation; + logic dma_gen_done; + logic [99:0] [11:0] dma_gen_block_size; +} axi_complex_ctrl_t; + +// Transfer types enum +typedef enum logic [2:0] { + AHB2AXI, + MBOX2AXI, + AXI2AXI, + AXI2MBOX, + AXI2AHB +} dma_transfer_type_e; + +// Values to drive onto GENERIC INPUT WIRES in response to RAS testing +localparam MBOX_NON_FATAL_OBSERVED = 32'h600dab1e; +localparam PROT_NO_LOCK_NON_FATAL_OBSERVED = 32'h600dbabe; +localparam PROT_OOO_NON_FATAL_OBSERVED = 32'h600dcafe; +localparam ICCM_FATAL_OBSERVED = 32'hdeadaca1; +localparam DCCM_FATAL_OBSERVED = 32'hdeadbeef; +localparam NMI_FATAL_OBSERVED = 32'hdeadc0a7; +localparam CRYPTO_ERROR_OBSERVED = 32'hdeadface; +localparam DMA_ERROR_OBSERVED = 32'hfadebadd; +localparam ERROR_NONE_SET = 32'hba5eba11; /* default value for a test with no activity observed by TB */ + +// AXI SRAM config +localparam AXI_SRAM_SIZE_BYTES = 262144; +localparam AXI_SRAM_ADDR_WIDTH = $clog2(AXI_SRAM_SIZE_BYTES); +localparam AXI_SRAM_DEPTH = AXI_SRAM_SIZE_BYTES / (CPTRA_AXI_DMA_DATA_WIDTH/8); +localparam logic [`CALIPTRA_AXI_DMA_ADDR_WIDTH-1:0] AXI_SRAM_BASE_ADDR = `CALIPTRA_AXI_DMA_ADDR_WIDTH'h0001_2344_0000; + +// AXI FIFO config +localparam AXI_FIFO_SIZE_BYTES = 65536; +localparam AXI_FIFO_ADDR_WIDTH = $clog2(AXI_SRAM_SIZE_BYTES); +localparam AXI_FIFO_DEPTH = AXI_SRAM_SIZE_BYTES / (CPTRA_AXI_DMA_DATA_WIDTH/8); +localparam logic [`CALIPTRA_AXI_DMA_ADDR_WIDTH-1:0] AXI_FIFO_BASE_ADDR = `CALIPTRA_AXI_DMA_ADDR_WIDTH'h0000_fa57_0000; + +`include "dma_transfer_randomizer.sv" + +endpackage diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_top_tb_services.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_top_tb_services.sv new file mode 100644 index 0000000..39a8718 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_top_tb_services.sv @@ -0,0 +1,3261 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2019 Western Digital Corporation or its affiliates. +// +// 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. +// + +// =================== DESCRIPTION =================== +// This module provides supporting functionality that is shared between the standalone +// and UVM benches for caliptra_top. +// This includes the following: +// - Contains all SRAM exports +// - Mem init functions (from .hex files, with ECC functionality as applicable) +// - RV Firmware STDOUT behavior (ASCII dump + sim kill + Error injection + interrupt + security_state) +// - RV and internal AHB interface monitoring to activity dumps +// The purpose of this module is to centralize identical code that is shared to +// improve maintainability. +// =================================================== + +`default_nettype none + +`include "common_defines.sv" +`include "config_defines.svh" +`include "caliptra_reg_defines.svh" +`include "caliptra_reg_field_defines.svh" + + +module caliptra_top_tb_services + import soc_ifc_pkg::*; + import kv_defines_pkg::*; + import caliptra_top_tb_pkg::*; +#( + parameter UVM_TB = 0 +) ( + input wire logic clk, + + input wire logic cptra_rst_b, + + // Caliptra Memory Export Interface + el2_mem_if.veer_sram_sink el2_mem_export, + abr_mem_if.resp abr_memory_export, + + //SRAM interface for mbox + input wire logic mbox_sram_cs, + input wire logic mbox_sram_we, + input wire logic [CPTRA_MBOX_ADDR_W-1:0] mbox_sram_addr, + input wire logic [CPTRA_MBOX_DATA_AND_ECC_W-1:0] mbox_sram_wdata, + output wire logic [CPTRA_MBOX_DATA_AND_ECC_W-1:0] mbox_sram_rdata, + + //SRAM interface for imem + input wire logic imem_cs, + input wire logic [`CALIPTRA_IMEM_ADDR_WIDTH-1:0] imem_addr, + output logic [`CALIPTRA_IMEM_DATA_WIDTH-1:0] imem_rdata, + + // Security State + output var security_state_t security_state, + + //Scan mode + output logic scan_mode, + + // TB Controls + output var ras_test_ctrl_t ras_test_ctrl, + output int cycleCnt, + output var axi_complex_ctrl_t axi_complex_ctrl, + + //Interrupt flags + output logic int_flag, + output logic cycleCnt_smpl_en, + + //Reset flags + output logic assert_hard_rst_flag, + output logic assert_rst_flag, + output logic deassert_hard_rst_flag, + output logic deassert_rst_flag, + + output logic [0:`CLP_OBF_UDS_DWORDS-1][31:0] cptra_uds_tb, + output logic [0:`CLP_OBF_FE_DWORDS-1] [31:0] cptra_fe_tb, + output logic [0:`CLP_OBF_KEY_DWORDS-1][31:0] cptra_obf_key_tb, + output logic [0:OCP_LOCK_HEK_NUM_DWORDS-1] [31:0] cptra_hek_tb, + + output logic axi_error_inj_en + +); + + //=========================================================================- + // Imports + //=========================================================================- + + //=========================================================================- + // Parameters + //=========================================================================- + localparam SEED_NUM_DWORDS = 8; + localparam MSG_NUM_DWORDS = 16; + localparam PRIVKEY_NUM_DWORDS = 1224; + localparam PRIVKEY_REG_NUM_DWORDS = 32; + localparam PRIVKEY_REG_RHO_NUM_DWORDS = 8; + localparam PUBKEY_NUM_DWORDS = 648; + localparam SIGNATURE_H_NUM_DWORDS = 21; + localparam VERIFY_RES_NUM_DWORDS = 16; + + + `ifndef VERILATOR + int MAX_CYCLES; + initial begin + // To use this from the command line, add "+CLP_MAX_CYCLES=" + // to override the sim timeout + if ($value$plusargs("CLP_MAX_CYCLES=%d", MAX_CYCLES)) begin + $info("Received argument +CLP_MAX_CYCLES, with value %d", MAX_CYCLES); + end + else begin + MAX_CYCLES = 20_000_000; + $info("No argument provided for CLP_MAX_CYCLES, defaulting to %d", MAX_CYCLES); + end + end + `else + parameter MAX_CYCLES = 20_000_000; + `endif + + parameter MEMTYPE_LMEM = 3'h1; + parameter MEMTYPE_DCCM = 3'h2; + parameter MEMTYPE_ICCM = 3'h3; + parameter DATA_WIDTH = 32; + localparam IV_NO = 128 / DATA_WIDTH; + + localparam ICCM_BYTE_SIZE = `RV_ICCM_SIZE*1024; // 256KiB + localparam ICCM_PRELOADER_WIDTH = 64; + localparam ICCM_PRELOADER_BYTE_WIDTH = ICCM_PRELOADER_WIDTH/8; + localparam ICCM_PRELOADER_DEPTH = ICCM_BYTE_SIZE / ICCM_PRELOADER_BYTE_WIDTH; + localparam ICCM_PRELOADER_ADDR_WIDTH = $clog2(ICCM_PRELOADER_DEPTH); + localparam DCCM_BYTE_SIZE = `RV_DCCM_SIZE*1024; // 256KiB + localparam DCCM_PRELOADER_WIDTH = 64; + localparam DCCM_PRELOADER_BYTE_WIDTH = DCCM_PRELOADER_WIDTH/8; + localparam DCCM_PRELOADER_DEPTH = DCCM_BYTE_SIZE / DCCM_PRELOADER_BYTE_WIDTH; + localparam DCCM_PRELOADER_ADDR_WIDTH = $clog2(DCCM_PRELOADER_DEPTH); + + //=========================================================================- + // Signals + //=========================================================================- + logic mailbox_write; + wire [31:0] WriteData; + logic [31:0] prev_mailbox_data; + logic mailbox_data_val; + int commit_count; + + logic wb_valid; + logic [4:0] wb_dest; + logic [31:0] wb_data; + + int hex_file_is_empty; + bit flip_bit; + + string abi_reg[32]; // ABI register names + + logic [CPTRA_MBOX_DATA_AND_ECC_W-1:0] mbox_sram_wdata_bitflip; + int cycleCntKillReq; + + int cycleCnt_ff; + int rst_cyclecnt = 0; + int wait_time_to_rst; + + logic cold_rst; + logic warm_rst; + logic timed_warm_rst; + logic prandom_warm_rst; + logic cold_rst_done; + + logic inject_hmac_key; + logic inject_hmac_block; + logic inject_ecc_seed; + logic inject_ecc_privkey; + logic inject_mldsa_seed; + logic inject_mlkem_kv; + logic inject_aes_seed; + logic inject_kv_error_check = 0; + logic inject_kv16_zero_key; + logic inject_kv23_small_rand_key; + logic inject_kv23_rand_length_key; + logic inject_random_data; + logic release_kv_inject_flags; + logic check_pcr_ecc_signing; + logic check_pcr_mldsa_signing; + logic inject_single_msg_for_ecc_mldsa; + logic [4:0] mlkem_kv_write_slot; + logic unlock_security_state; + + // Decode: + // [0] - Single bit, ICCM Error Injection + // [1] - Double bit, ICCM Error Injection + // [2] - Single bit, DCCM Error Injection + // [3] - Double bit, DCCM Error Injection + veer_sram_error_injection_mode_t sram_error_injection_mode; + // Decode: + // [0] - Single bit, Mailbox Error Injection + // [1] - Double bit, Mailbox Error Injection + logic [1:0] inject_mbox_sram_error = 2'b0; + + logic set_wdt_timer1_period; + logic set_wdt_timer2_period; + logic reset_wdt_timer_period; + + logic inject_zero_sign_r; + logic inject_zero_sign_r_needs_release; + logic inject_zero_sign_s; + logic inject_zero_sign_s_needs_release; + logic inject_invalid_privkey; + logic inject_invalid_privkey_needs_release; + logic inject_invalid_dhkey; + logic inject_invalid_dhkey_needs_release; + logic inject_invalid_pubkeyx; + logic inject_invalid_pubkeyx_needs_release; + logic inject_invalid_pubkeyy; + logic inject_invalid_pubkeyy_needs_release; + + logic en_jtag_access; + logic disable_mldsa_sva; + + typedef bit [0:11][31:0] operand_t; + + typedef struct packed { + operand_t x; + operand_t y; + } affn_point_t; + + typedef struct packed { + operand_t X; + operand_t Y; + operand_t Z; + } proj_point_t; + + typedef struct packed { + operand_t hashed_msg; + operand_t privkey; + affn_point_t pubkey; + operand_t R; + operand_t S; + operand_t seed; + operand_t nonce; + operand_t IV; + operand_t privkeyB; + operand_t dh_sharedkey; + } ecc_test_vector_t; + + ecc_test_vector_t ecc_test_vector; + + typedef struct packed { + logic [0:`CLP_OBF_KEY_DWORDS-1][31:0] obf_key_uds; + logic [0:IV_NO-1][31:0] iv_uds; + logic [0:`CLP_OBF_UDS_DWORDS-1][31:0] uds_plaintext; + logic [0:`CLP_OBF_UDS_DWORDS-1][31:0] uds_ciphertext; + + logic [0:`CLP_OBF_KEY_DWORDS-1][31:0] obf_key_fe; + logic [0:IV_NO-1][31:0] iv_fe; + logic [0:`CLP_OBF_FE_DWORDS-1] [31:0] fe_plaintext; + logic [0:`CLP_OBF_FE_DWORDS-1] [31:0] fe_ciphertext; + + logic [0:OCP_LOCK_HEK_NUM_DWORDS-1][31:0] obf_key_hek; + logic [0:IV_NO-1][31:0] iv_hek; + logic [0:OCP_LOCK_HEK_NUM_DWORDS-1] [31:0] hek_plaintext; + logic [0:OCP_LOCK_HEK_NUM_DWORDS-1] [31:0] hek_ciphertext; + } doe_test_vector_t; + + doe_test_vector_t doe_test_vector; + + typedef struct packed { + //logic [511:0] sha256_wntz_block_tb; + logic [15:0][31:0] sha256_wntz_block_tb; + logic [0:7][31:0] sha256_wntz_digest; + logic wntz_n; + logic [3:0] wntz_w; + } sha256_wntz_test_vector_t; + + sha256_wntz_test_vector_t sha256_wntz_test_vector; + + typedef struct packed { + logic [0:SEED_NUM_DWORDS-1][31:0] seed; + logic [0:PUBKEY_NUM_DWORDS-1][31:0] pubkey; + logic [0:PRIVKEY_NUM_DWORDS-1][31:0] privkey; + logic [0:MSG_NUM_DWORDS-1][31:0] msg; + logic [0:1156][31:0] signature; + logic [0:VERIFY_RES_NUM_DWORDS-1][31:0] verify_res; + logic [0:7][31:0] sign_rnd; + } mldsa_test_vector_t; + + mldsa_test_vector_t mldsa_test_vector; + + typedef struct packed { + logic [7:0][31:0] seed_d; + logic [7:0][31:0] seed_z; + logic [391:0][31:0] ek; + logic [791:0][31:0] dk; + logic [7:0][31:0] msg; + logic [391:0][31:0] ciphertext; + logic [7:0][31:0] sharedkey; + } mlkem_test_vector_t; + + mlkem_test_vector_t mlkem_test_vector; + + logic inject_makehint_failure, inject_normcheck_failure; + logic reset_mldsa_failure; + logic [1:0] normcheck_mode_random; + logic inject_mldsa_timeout; + logic random_mldsa_failure_injection; + function automatic logic [511:0] change_endian(input logic [511:0] data); + logic [511:0] result; + for (int i = 0; i < 512; i = i + 8) begin + result[i +: 8] = data[511 - i -: 8]; + end + return result; + endfunction + +// Upwards name referencing per 23.8 of IEEE 1800-2017 +`define DEC `CPTRA_TOP_PATH.rvtop.veer.dec + +`define LMEM mbox_ram1.ram + + //=========================================================================- + // STDOUT and Trace Logic + //=========================================================================- + // NOTE: This aperture into the mailbox is heavily overloaded right now by + // various firmware "STDOUT" use-cases. + // Functionality currently implemented at this offset is as follows + // (relative to the WriteData used to trigger that function): + // 8'h0 - Do nothing + // 8'h1 - Kill the simulation with a Failed status + // 8'h2 : 8'h5 - Do nothing + // 8'h6 : 8'h7E - WriteData is an ASCII character - dump to console.log + // 8'h7F - Switch to MANUF device lifecycle state + // 8'h80: 8'h87 - Inject ECC_SEED to kv_key register + // 8'h88 - Toggle recovery interface emulation in AXI complex + // 8'h89 - Use same msg in SHA512 digest for ECC/MLDSA PCR signing (used where both cryptos are running in parallel) + // 8'h8a - Enable FIFO in caliptra_top_tb_axi_complex to auto-read data + // 8'h8b - Enable FIFO in caliptra_top_tb_axi_complex to auto-write data + // 8'h8c - Disable FIFO in caliptra_top_tb_axi_complex to auto-read data + // 8'h8d - Disable FIFO in caliptra_top_tb_axi_complex to auto-write data + // 8'h8e - Flush the FIFO in caliptra_top_tb_axi_complex + // 8'h8f - Toggle random delays in AXI complex (FIFO and SRAM endpoints) + // 8'h90 - Issue PCR signing with fixed vector + // 8'h91 - Issue PCR ECC signing with randomized vector + // 8'h92 - Check PCR ECC signing with randomized vector + // 8'h93 - Issue PCR MLDSA signing with randomized vector + // 8'h94 - Check PCR MLDSA signing with randomized vector + // 8'h97 - Inject invalid dh_key into ECC + // 8'h98 - Inject invalid zero sign_r into ECC + // 8'h99 - Inject zeroize into HMAC + // 8'h9a - Inject invalid zero sign_s into ECC + // 8'h9b - Inject zeroize during keyvault read + // 8'h9c - Inject invalid privkey/dh_key into ECC + // 8'h9d - Inject invalid pubkey_x into ECC + // 8'h9e - Inject invalid pubkey_y into ECC + // 8'h9f - Inject AES key into KV + // 8'ha0 - Inject HMAC384_KEY to kv_key register + // 8'ha1: 8'ha7 - Unused + // 8'ha8 - Inject zero as HMAC_KEY to kv_key register + // 8'ha9 - Inject HMAC512_KEY to kv_key register + // 8'haa - Inject HMAC512_BLOCK to kv_key16 register + // 8'hab - Inject MLDSA SEED to kv_key22/23 register + // 8'hac - Inject ECC seed to kv_key22/23 register + // 8'had - Inject ECC_PRIVKEY to kv_key register + // 8'hae: 8'haf - Unused + // 8'hb0 - Inject HMAC512_BLOCK to kv_key register + // 8'hb1 - Inject MLKEM SEED to keyvault + // 8'hb2 - Inject MLKEM MSG to keyvault + // 8'hb3 - Check MLKEM KV result against shared key test vector + // 8'hb4 - Inject MLKEM zeroize during KV access + // 8'hb5 - Turn on Assertion using $asserton + // 8'hb6 - Turn off Assertion using $assertoff + // 8'hb7 - AXI Error Injection Enabled + // 8'hb8 - AXI Error Injection Disabled + // 8'hb9 - Enable scan mode and run DOE back to back + // 8'hba - Enable scan mode with KV write + // 8'hbb:bf - Unused + // 8'hc0: - Inject MLDSA_SEED to kv_key register + // 8'hc1: 8'hc7 - Unused + // 8'hc8 - Inject key 0x0 into slot 16 for AES + // 8'hc9 - Inject key smaller than key_release_size into KV23 + // 8'hca - Inject key larger than key_release_size into KV23 + // 8'hcb - Inject key 0x0 into all slots for AES + // 8'hcc - Inject key into slot 16 for AES + // 8'hcd - KV Error checking + // 8'hce: 8'hcf - Unused + // 8'hd0 - SHA3 public key injection + // 8'hd1 - SHA3 message injection + // 8'hd2 - MLDSA keygen+signing without injecting message + // 8'hd3 - MLDSA verification without injecting message + // 8'hd5 - Inject randomized HEK test vector + // 8'hd6 - Inject mldsa timeout + // 8'hd7 - Inject normcheck or makehint failure during mldsa signing 1st loop. Failure type is selected randomly + // 8'hd8 - Clear MLDSA checking + // 8'hd9 - Perform mldsa keygen + // 8'hda - Perform mldsa signing + // 8'hdb - Perform mldsa verify + // 8'hdc - Perform mldsa keygen+signing + // 8'hdd - Inject random block input to SHA256 WNTZ module + // 8'hde - ICCM SRAM force loop read (requires read params written to other bytes of generic wires) + // 8'hdf - DCCM SRAM force loop read (requires read params written to other bytes of generic wires) + // 8'he0 - Set random ICCM SRAM single bit error injection + // 8'he1 - Set random ICCM SRAM double bit error injection + // 8'he2 - Set random DCCM SRAM single bit error injection + // 8'he3 - Set random DCCM SRAM double bit error injection + // 8'he4 - Disable all SRAM error injection (Mailbox, ICCM, DCCM) + // 8'he5 - Request TB to initiate Mailbox flow without lock (violation) + // 8'he6 - Request TB to initiate Mailbox flow with out-of-order accesses (violation) + // 8'he7 - Reset mailbox out-of-order flag when non-fatal error is masked (allows the test to continue) [Deprecated] + // 8'he8 - Enable scan mode when DOE fsm transitions to done state + // 8'he9 - Force dmi_reg_en input to clk gate to emulate JTAG accesses + // 8'hea - Set random values to WDT timer1 and timer2 + // 8'heb - Inject fatal error + // 8'hec - Inject randomized UDS test vector + // 8'hed - Inject randomized FE test vector + // 8'hee - Issue random warm reset + // 8'hef - Enable scan mode + // 8'hf0 - Disable scan mode + // 8'hf1 - Release WDT timer periods so they can be set by the test + // 8'hf2 - Force clk_gating_en (to use in smoke_test only) + // 8'hf3 - Init PCR slot 31 + // 8'hf4 - Write random data to KV entry0 + // 8'hf5 - Issue cold reset + // 8'hf6 - Issue warm reset + // 8'hf7 - Issue warm reset when DOE FSM is done + // 8'hf8 - Assert interrupt flags at fixed intervals to wake up halted core + // 8'hf9 - Lock debug in security state + // 8'hfa - Unlock debug in security state + // 8'hfb - Set the isr_active bit + // 8'hfc - Clear the isr_active bit + // 8'hfd - Set random Mailbox SRAM single bit error injection + // 8'hfe - Set random Mailbox SRAM double bit error injection + // 8'hff - End the simulation with a Success status + assign mailbox_write = `CPTRA_TOP_PATH.soc_ifc_top1.i_soc_ifc_reg.field_combo.CPTRA_GENERIC_OUTPUT_WIRES[0].generic_wires.load_next; + assign WriteData = `CPTRA_TOP_PATH.soc_ifc_top1.i_soc_ifc_reg.field_combo.CPTRA_GENERIC_OUTPUT_WIRES[0].generic_wires.next; + assign mailbox_data_val = WriteData[7:0] > 8'h5 && WriteData[7:0] < 8'h7f; + + integer fd, tp, el, sm, i; + integer ifu_p, lsu_p, sl_p[`CALIPTRA_AHB_SLAVES_NUM]; + + integer j; + string slaveLog_fileName[`CALIPTRA_AHB_SLAVES_NUM]; + + logic [7:0] isr_active = 8'h0; + always @(negedge clk) begin + if ((WriteData[7:0] == 8'hfc) && mailbox_write) begin + isr_active--; + end + else if ((WriteData[7:0] == 8'hfb) && mailbox_write) begin + isr_active++; + end + end + always @(negedge clk or negedge cptra_rst_b) begin + if (!cptra_rst_b) inject_mbox_sram_error <= 2'b00; + else if ((WriteData[7:0] == 8'hfd) && mailbox_write) inject_mbox_sram_error <= 2'b01; + else if ((WriteData[7:0] == 8'hfe) && mailbox_write) inject_mbox_sram_error <= 2'b10; + else if ((WriteData[7:0] == 8'he4) && mailbox_write) inject_mbox_sram_error <= 2'b00; + end + always @(negedge clk or negedge cptra_rst_b) begin + if (!cptra_rst_b) sram_error_injection_mode <= '{default: 1'b0}; + else if ((WriteData[7:0] == 8'he0) && mailbox_write) sram_error_injection_mode.iccm_single_bit_error <= 1'b1; + else if ((WriteData[7:0] == 8'he1) && mailbox_write) sram_error_injection_mode.iccm_double_bit_error <= 1'b1; + else if ((WriteData[7:0] == 8'he2) && mailbox_write) sram_error_injection_mode.dccm_single_bit_error <= 1'b1; + else if ((WriteData[7:0] == 8'he3) && mailbox_write) sram_error_injection_mode.dccm_double_bit_error <= 1'b1; + else if ((WriteData[7:0] == 8'he4) && mailbox_write) sram_error_injection_mode <= '{default: 1'b0}; + end + + always @(negedge clk or negedge cptra_rst_b) begin + if (!cptra_rst_b) begin + ras_test_ctrl.do_no_lock_access <= 1'b0; + ras_test_ctrl.do_ooo_access <= 1'b0; + end + else if((WriteData[7:0] == 8'he5) && mailbox_write) begin + ras_test_ctrl.do_no_lock_access <= 1'b1; + ras_test_ctrl.do_ooo_access <= 1'b0; + end + else if((WriteData[7:0] == 8'he6) && mailbox_write) begin + ras_test_ctrl.do_no_lock_access <= 1'b0; + ras_test_ctrl.do_ooo_access <= 1'b1; + end + else if ((WriteData[7:0] == 8'he7) && mailbox_write) begin + ras_test_ctrl.do_no_lock_access <= 1'b0; + ras_test_ctrl.do_ooo_access <= 1'b0; + end + else begin + ras_test_ctrl.do_no_lock_access <= 1'b0; + ras_test_ctrl.do_ooo_access <= 1'b0; + end + end + + always @(negedge clk or negedge cptra_rst_b) begin + if (!cptra_rst_b) begin + ras_test_ctrl.iccm_read_burst.start <= 1'b0; + ras_test_ctrl.iccm_read_burst.count <= '0; + ras_test_ctrl.iccm_read_burst.addr <= '0; + ras_test_ctrl.dccm_read_burst.start <= 1'b0; + ras_test_ctrl.dccm_read_burst.count <= '0; + ras_test_ctrl.dccm_read_burst.addr <= '0; + end + else if((WriteData[7:0] == 8'hde) && mailbox_write) begin + ras_test_ctrl.iccm_read_burst.start <= 1'b1; + ras_test_ctrl.iccm_read_burst.count <= WriteData[31:12]; + ras_test_ctrl.iccm_read_burst.addr <= `CPTRA_TOP_PATH.soc_ifc_top1.i_soc_ifc_reg.field_storage.CPTRA_GENERIC_OUTPUT_WIRES[1].generic_wires.value; + ras_test_ctrl.dccm_read_burst.start <= 1'b0; + ras_test_ctrl.dccm_read_burst.count <= '0; + ras_test_ctrl.dccm_read_burst.addr <= '0; + end + else if((WriteData[7:0] == 8'hdf) && mailbox_write) begin + ras_test_ctrl.iccm_read_burst.start <= 1'b0; + ras_test_ctrl.iccm_read_burst.count <= '0; + ras_test_ctrl.iccm_read_burst.addr <= '0; + ras_test_ctrl.dccm_read_burst.start <= 1'b1; + ras_test_ctrl.dccm_read_burst.count <= WriteData[31:12]; + ras_test_ctrl.dccm_read_burst.addr <= `CPTRA_TOP_PATH.soc_ifc_top1.i_soc_ifc_reg.field_storage.CPTRA_GENERIC_OUTPUT_WIRES[1].generic_wires.value; + end + else begin + ras_test_ctrl.iccm_read_burst.start <= 1'b0; + ras_test_ctrl.iccm_read_burst.count <= '0; + ras_test_ctrl.iccm_read_burst.addr <= '0; + ras_test_ctrl.dccm_read_burst.start <= 1'b0; + ras_test_ctrl.dccm_read_burst.count <= '0; + ras_test_ctrl.dccm_read_burst.addr <= '0; + end + end + + initial ras_test_ctrl.error_injection_seen = 1'b0; + always @(negedge clk) begin + if (mailbox_write && WriteData[7:0] == 8'hfd) begin + ras_test_ctrl.error_injection_seen <= 1'b1; + end + end + // When starting a new error injection test, reset generic_input wires to the idle value. + // New values will be loaded to reflect the result of the RAS test. + initial ras_test_ctrl.reset_generic_input_wires = 1'b0; + always@(negedge clk) begin + ras_test_ctrl.reset_generic_input_wires <= mailbox_write && (WriteData[7:0] inside {8'he0, 8'he1, 8'he2, 8'he3, 8'hfd, 8'hfe}); + end + + // AXI Complex Control + always @(negedge clk or negedge cptra_rst_b) begin + if (!cptra_rst_b) begin + axi_complex_ctrl.fifo_auto_push <= 1'b0; + axi_complex_ctrl.fifo_auto_pop <= 1'b0; + axi_complex_ctrl.fifo_clear <= 1'b0; + axi_complex_ctrl.rand_delays <= 1'b0; + axi_complex_ctrl.en_recovery_emulation <= 1'b0; + end + else if((WriteData[7:0] == 8'h88) && mailbox_write) begin + axi_complex_ctrl.en_recovery_emulation <= ~axi_complex_ctrl.en_recovery_emulation; // Toggle option + end + else if((WriteData[7:0] == 8'h8a) && mailbox_write) begin + axi_complex_ctrl.fifo_auto_pop <= 1'b1; + end + else if((WriteData[7:0] == 8'h8b) && mailbox_write) begin + axi_complex_ctrl.fifo_auto_push <= 1'b1; + end + else if((WriteData[7:0] == 8'h8c) && mailbox_write) begin + axi_complex_ctrl.fifo_auto_pop <= 1'b0; + end + else if((WriteData[7:0] == 8'h8d) && mailbox_write) begin + axi_complex_ctrl.fifo_auto_push <= 1'b0; + end + else if((WriteData[7:0] == 8'h8e) && mailbox_write) begin + axi_complex_ctrl.fifo_clear <= 1'b1; + end + else if((WriteData[7:0] == 8'h8f) && mailbox_write) begin + axi_complex_ctrl.rand_delays <= ~axi_complex_ctrl.rand_delays; // Toggle option + end + else begin + axi_complex_ctrl.fifo_clear <= 1'b0; + end + end + + //keyvault injection hooks + //Inject data to KV key reg + logic [0:15][31:0] ecc_seed_tb = 512'h_8FA8541C82A392CA74F23ED1DBFD73541C5966391B97EA73D744B0E34B9DF59ED0158063E39C09A5A055371EDF7A5441_00000000000000000000000000000000; + logic [0:15][31:0] ecc_privkey_tb = 512'h_F274F69D163B0C9F1FC3EBF4292AD1C4EB3CEC1C5A7DDE6F80C14292934C2055E087748D0A169C772483ADEE5EE70E17_00000000000000000000000000000000; + logic [0:15][31:0] hmac384_key_tb = 512'h_0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b_00000000000000000000000000000000; + logic [0:15][31:0] hmac512_key_tb = 512'h0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b; + logic [0:15][31:0] hmac512_block_tb = 512'h_e7f1293c6f23a53289143df1399e784cb71180e3830c3869fd725fe78f0b6480559d6344edc1aaf64b7d0701e78672d2_55555555555555555555555555555555; + logic [0:15][31:0] mldsa_seed_tb = 512'h_2d5cf89c46768a850768f0d4a243fe283fcee4d537071d12675fd1279340000a_55555555555555555555555555555555_00000000000000000000000000000000; //fixme padded with junk + logic [0:15][31:0] aes256_key_tb = 512'hbc623095823dafe190998314fedbac4258395063234564532123adfcefda2344_0000000000000000000000000000000000000000000000000000000000000000; + logic [0:15][31:0] ecc_privkey_random; + logic [0:15][31:0] mldsa_seed_random; + logic [15:0][31:0] mlkem_seed_random; + logic [15:0][31:0] mlkem_msg_random; + logic [15:0] key_release_size_val = `CPTRA_TOP_PATH.soc_ifc_top1.i_axi_dma.key_release_size; + logic [7:0] min_dwords ; + logic [7:0] max_dwords ; + logic [3:0] random_key_size ; + + always_comb ecc_privkey_random = {ecc_test_vector.privkey, 128'h_00000000000000000000000000000000}; + always_comb mldsa_seed_random = change_endian({256'h0, mldsa_test_vector.seed}); + always_comb mlkem_seed_random = {mlkem_test_vector.seed_z,mlkem_test_vector.seed_d}; + always_comb mlkem_msg_random = {256'h0,mlkem_test_vector.msg}; + + genvar dword_i, slot_id; + generate + for (slot_id=0; slot_id < 24; slot_id++) begin : inject_slot_loop + for (dword_i=0; dword_i < 16; dword_i++) begin : inject_dword_loop + always @(negedge clk) begin + //inject valid seed dest and seed value to key reg + if(((WriteData[7:0] & 8'hf8) == 8'h80) && mailbox_write) begin + release_kv_inject_flags <= '0; + //$system("/home/mojtabab/workspace_aha_poc/ws1/Caliptra/src/ecc/tb/ecdsa_secp384r1.exe"); + inject_ecc_seed <= 1'b1; + if (WriteData[12:8] == slot_id) begin + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[slot_id].dest_valid.we = 1'b1; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[slot_id].dest_valid.next = 8'b10000; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[slot_id].last_dword.we = 1'b1; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[slot_id].last_dword.next = 'd11; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_ENTRY[slot_id][dword_i].data.we = 1'b1; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_ENTRY[slot_id][dword_i].data.next = ecc_seed_tb[dword_i][31 : 0]; + end + end + //inject privkey value to key reg + else if((WriteData[7:0] == 8'h90) && mailbox_write) begin + release_kv_inject_flags <= '0; + inject_ecc_privkey <= 1'b1; + if (slot_id == KV_ENTRY_FOR_ECC_SIGNING) begin + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[slot_id].dest_valid.we = 1'b1; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[slot_id].dest_valid.next = 8'b1000; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[slot_id].last_dword.we = 1'b1; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[slot_id].last_dword.next = 'd11; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_ENTRY[slot_id][dword_i].data.we = 1'b1; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_ENTRY[slot_id][dword_i].data.next = ecc_privkey_tb[dword_i][31 : 0]; + end + inject_mldsa_seed <= 1'b1; + if (slot_id == KV_ENTRY_FOR_MLDSA_SIGNING) begin + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[slot_id].dest_valid.we = 1'b1; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[slot_id].dest_valid.next = 8'b100; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[slot_id].last_dword.we = 1'b1; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[slot_id].last_dword.next = 'd7; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_ENTRY[slot_id][dword_i].data.we = 1'b1; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_ENTRY[slot_id][dword_i].data.next = mldsa_seed_tb[dword_i][31 : 0]; + end + end + else if((WriteData[7:0] == 8'h91) && mailbox_write) begin + inject_ecc_privkey <= 1'b1; + release_kv_inject_flags <= '0; + if (slot_id == KV_ENTRY_FOR_ECC_SIGNING) begin + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[slot_id].dest_valid.we = 1'b1; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[slot_id].dest_valid.next = 8'b1000; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[slot_id].last_dword.we = 1'b1; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[slot_id].last_dword.next = 'd11; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_ENTRY[slot_id][dword_i].data.we = 1'b1; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_ENTRY[slot_id][dword_i].data.next = ecc_privkey_random[dword_i][31 : 0]; + end + end + else if((WriteData[7:0] == 8'had) && mailbox_write) begin + inject_ecc_privkey <= 1'b1; + release_kv_inject_flags <= '0; + if (WriteData[12:8] == slot_id) begin + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[slot_id].dest_valid.we = 1'b1; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[slot_id].dest_valid.next = 8'b1000; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[slot_id].last_dword.we = 1'b1; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[slot_id].last_dword.next = 'd11; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_ENTRY[slot_id][dword_i].data.we = 1'b1; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_ENTRY[slot_id][dword_i].data.next = ecc_privkey_tb[dword_i][31 : 0]; + end + end + else if((WriteData[7:0] == 8'h93) && mailbox_write) begin + inject_mldsa_seed <= 1'b1; + release_kv_inject_flags <= '0; + if (slot_id == KV_ENTRY_FOR_MLDSA_SIGNING) begin + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[slot_id].dest_valid.we = 1'b1; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[slot_id].dest_valid.next = 8'b100; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[slot_id].last_dword.we = 1'b1; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[slot_id].last_dword.next = 'd7; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_ENTRY[slot_id][dword_i].data.we = 1'b1; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_ENTRY[slot_id][dword_i].data.next = mldsa_seed_random[dword_i][31 : 0]; + end + end + //inject valid hmac_key dest and zero hmac_key value to key reg + else if(((WriteData[7:0]) == 8'ha8) && mailbox_write) begin + inject_hmac_key <= 1'b1; + release_kv_inject_flags <= '0; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[slot_id].dest_valid.we = 1'b1; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[slot_id].dest_valid.next = 8'b1; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[slot_id].last_dword.we = 1'b1; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[slot_id].last_dword.next = 'd15; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_ENTRY[slot_id][dword_i].data.we = 1'b1; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_ENTRY[slot_id][dword_i].data.next = '0; + end + //inject valid hmac_key dest and hmac384_key value to key reg + else if((WriteData[7:0] == 8'ha0) && mailbox_write) begin + inject_hmac_key <= 1'b1; + release_kv_inject_flags <= '0; + if (WriteData[12:8] == slot_id) begin + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[slot_id].dest_valid.we = 1'b1; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[slot_id].dest_valid.next = 8'b1; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[slot_id].last_dword.we = 1'b1; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[slot_id].last_dword.next = 'd11; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_ENTRY[slot_id][dword_i].data.we = 1'b1; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_ENTRY[slot_id][dword_i].data.next = hmac384_key_tb[dword_i][31 : 0]; + end + end + //inject valid hmac_key dest and hmac512_key value to key reg + else if((WriteData[7:0] == 8'ha9) && mailbox_write) begin + inject_hmac_key <= 1'b1; + release_kv_inject_flags <= '0; + if (WriteData[12:8] == slot_id) begin + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[slot_id].dest_valid.we = 1'b1; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[slot_id].dest_valid.next = 8'b1; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[slot_id].last_dword.we = 1'b1; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[slot_id].last_dword.next = 'd15; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_ENTRY[slot_id][dword_i].data.we = 1'b1; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_ENTRY[slot_id][dword_i].data.next = hmac512_key_tb[dword_i][31 : 0]; + end + end + else if ((WriteData[7:0] == 8'haa) && mailbox_write) begin + inject_hmac_block <= 1'b1; + release_kv_inject_flags <= '0; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[16].dest_valid.we = 1'b1; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[16].dest_valid.next = 6'h2; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[16].last_dword.we = 1'b1; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[16].last_dword.next = 'd15; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_ENTRY[16][dword_i].data.we = 1'b1; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_ENTRY[16][dword_i].data.next = hmac512_block_tb[dword_i][31 : 0]; + end + // inject key 0x0 into slot 16 for AES + else if((WriteData[7:0] == 8'hc8) && mailbox_write) begin + inject_kv16_zero_key <= '1; + release_kv_inject_flags <= '0; + if (slot_id == 16) begin + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[slot_id].dest_valid.we = 1'b1; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[slot_id].dest_valid.next = 9'b000100000; // AES access + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[slot_id].last_dword.we = 1'b1; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[slot_id].last_dword.next = 'd15; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_ENTRY[slot_id][dword_i].data.we = 1'b1; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_ENTRY[slot_id][dword_i].data.next = 32'h0; + end + + end + // inject key size 8 in KV 23 + else if((WriteData[7:0] == 8'hc9) && mailbox_write) begin + // Generate random key size with bounds checking + max_dwords = (key_release_size_val >> 2); // Convert bytes to dwords + random_key_size = (max_dwords > 0) ? (($urandom() % max_dwords) + 1) : 1; + inject_kv23_small_rand_key <= '1; + release_kv_inject_flags <= '0; + if (slot_id == 23 && dword_i < random_key_size) begin + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[slot_id].dest_valid.we = 1'b1; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[slot_id].dest_valid.next = 9'b100000000; // DMA + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[slot_id].last_dword.we = 1'b1; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[slot_id].last_dword.next = random_key_size - 1; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_ENTRY[slot_id][dword_i].data.we = 1'b1; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_ENTRY[slot_id][dword_i].data.next = $urandom(); + end + end + // inject key size 8 in KV 23 + else if((WriteData[7:0] == 8'hca) && mailbox_write) begin + // Generate random key size with bounds checking + min_dwords = (key_release_size_val >> 2); // Convert bytes to dwords + max_dwords = 8'h40; + random_key_size = min_dwords + ($urandom() % (max_dwords - min_dwords + 1)); + inject_kv23_rand_length_key <= '1; + release_kv_inject_flags <= '0; + if (slot_id == 23 && dword_i < random_key_size) begin + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[slot_id].dest_valid.we = 1'b1; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[slot_id].dest_valid.next = 9'b100000000; // DMA + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[slot_id].last_dword.we = 1'b1; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[slot_id].last_dword.next = random_key_size - 1; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_ENTRY[slot_id][dword_i].data.we = 1'b1; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_ENTRY[slot_id][dword_i].data.next = $urandom(); + end + end + // inject key for AES into all key slots + else if((WriteData[7:0] == 8'hcb) && mailbox_write) begin + release_kv_inject_flags <= '0; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[slot_id].dest_valid.we = 1'b1; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[slot_id].dest_valid.next = 9'b000100000; // AES access + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[slot_id].last_dword.we = 1'b1; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[slot_id].last_dword.next = 'd7; + if(dword_i < 8) begin + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_ENTRY[slot_id][dword_i].data.we = 1'b1; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_ENTRY[slot_id][dword_i].data.next = 32'h0; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_ENTRY[slot_id][dword_i].data.next = aes256_key_tb[dword_i][31 : 0]; + end + else begin + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_ENTRY[slot_id][dword_i].data.we = 1'b1; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_ENTRY[slot_id][dword_i].data.next = 32'h0; + end + end + // inject key for AES into slot 16 key slots + else if((WriteData[7:0] == 8'hcc) && mailbox_write) begin + release_kv_inject_flags <= '0; + if (slot_id == 16) begin + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[slot_id].dest_valid.we = 1'b1; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[slot_id].dest_valid.next = 9'b000100000; // AES access + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[slot_id].last_dword.we = 1'b1; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[slot_id].last_dword.next = 'd7; + if(dword_i < 8) begin + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_ENTRY[slot_id][dword_i].data.we = 1'b1; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_ENTRY[slot_id][dword_i].data.next = 32'h0; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_ENTRY[slot_id][dword_i].data.next = aes256_key_tb[dword_i][31 : 0]; + end + else begin + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_ENTRY[slot_id][dword_i].data.we = 1'b1; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_ENTRY[slot_id][dword_i].data.next = 32'h0; + end + end + end + //inject valid hmac_block dest and hmac512_block value to key reg + else if((WriteData[7:0] == 8'hb0) && mailbox_write) begin + release_kv_inject_flags <= '0; + inject_hmac_block <= 1'b1; + if (WriteData[12:8] == slot_id) begin + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[slot_id].dest_valid.we = 1'b1; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[slot_id].dest_valid.next = 8'h3; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[slot_id].last_dword.we = 1'b1; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[slot_id].last_dword.next = 'd15; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_ENTRY[slot_id][dword_i].data.we = 1'b1; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_ENTRY[slot_id][dword_i].data.next = hmac512_block_tb[dword_i][31 : 0]; + end + end + else if((WriteData[7:0] == 8'hf4) && mailbox_write) begin + inject_random_data <= '1; + release_kv_inject_flags <= '0; + if (slot_id == 0) begin + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[slot_id].dest_valid.we = 'b1; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[slot_id].dest_valid.next = (32'b10000 << `KV_REG_KEY_CTRL_0_DEST_VALID_LOW); + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[slot_id].last_dword.we = 1'b1; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[slot_id].last_dword.next = 'd11; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_ENTRY[slot_id][dword_i].data.we = 1'b1; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_ENTRY[slot_id][dword_i].data.next = $urandom(); + end + end + //inject valid mldsa seed dest and mldsa_seed value to key reg + else if((WriteData[7:0] == 8'hc0) && mailbox_write) begin + inject_mldsa_seed <= 1'b1; + release_kv_inject_flags <= '0; + if (WriteData[12:8] == slot_id) begin + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[slot_id].dest_valid.we = 1'b1; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[slot_id].dest_valid.next = 8'b0000_0100; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[slot_id].last_dword.we = 1'b1; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[slot_id].last_dword.next = 'd7; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_ENTRY[slot_id][dword_i].data.we = 1'b1; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_ENTRY[slot_id][dword_i].data.next = mldsa_seed_tb[dword_i][31 : 0]; + end + end + //Inject mldsa seed to 22 and 23 + else if(((WriteData[7:0] == 8'hab)) && mailbox_write) begin + inject_mldsa_seed <= 1'b1; + release_kv_inject_flags <= '0; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[22].dest_valid.we = 1'b1; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[22].dest_valid.next = 9'b0_0000_0100; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[22].last_dword.we = 1'b1; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[22].last_dword.next = 7; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_ENTRY[22][dword_i].data.we = 1'b1; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_ENTRY[22][dword_i].data.next = mldsa_seed_tb[dword_i][31 : 0]; + + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[23].dest_valid.we = 1'b1; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[23].dest_valid.next = 9'b0_0000_0100; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[23].last_dword.we = 1'b1; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[23].last_dword.next = 7; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_ENTRY[23][dword_i].data.we = 1'b1; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_ENTRY[23][dword_i].data.next = mldsa_seed_tb[dword_i][31 : 0]; + end + //Inject ecc seed to 22 and 23 + else if(((WriteData[7:0] == 8'hac)) && mailbox_write) begin + inject_ecc_seed <= 1'b1; + release_kv_inject_flags <= '0; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[22].dest_valid.we = 1'b1; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[22].dest_valid.next = 9'b0_0001_1000; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[22].last_dword.we = 1'b1; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[22].last_dword.next = 15; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_ENTRY[22][dword_i].data.we = 1'b1; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_ENTRY[22][dword_i].data.next = ecc_seed_tb[dword_i][31 : 0]; + + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[23].dest_valid.we = 1'b1; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[23].dest_valid.next = 9'b0_0001_1000; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[23].last_dword.we = 1'b1; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[23].last_dword.next = 15; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_ENTRY[23][dword_i].data.we = 1'b1; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_ENTRY[23][dword_i].data.next = ecc_seed_tb[dword_i][31 : 0]; + end + //inject mlkem seed + else if((WriteData[7:0] == 8'hb1) && mailbox_write) begin + inject_mlkem_kv <= 1'b1; + release_kv_inject_flags <= '0; + if ((WriteData[12:8] == slot_id)) begin + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[slot_id].dest_valid.we = 1'b1; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[slot_id].dest_valid.next = 8'b0100_0000; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[slot_id].last_dword.we = 1'b1; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[slot_id].last_dword.next = 'd15; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_ENTRY[slot_id][dword_i].data.we = 1'b1; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_ENTRY[slot_id][dword_i].data.next = mlkem_seed_random[dword_i][31 : 0]; + end + end + else if((WriteData[7:0] == 8'hb2) && mailbox_write) begin + inject_mlkem_kv <= 1'b1; + release_kv_inject_flags <= '0; + if ((WriteData[12:8] == slot_id)) begin + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[slot_id].dest_valid.we = 1'b1; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[slot_id].dest_valid.next = 8'b1000_0000; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[slot_id].last_dword.we = 1'b1; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[slot_id].last_dword.next = 'd7; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_ENTRY[slot_id][dword_i].data.we = 1'b1; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_ENTRY[slot_id][dword_i].data.next = mlkem_msg_random[dword_i][31 : 0]; + end + end + else if((WriteData[7:0] == 8'h9f) && mailbox_write) begin + inject_aes_seed <= 1'b1; + release_kv_inject_flags <= '0; + if ((WriteData[12:8] == slot_id)) begin + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[slot_id].dest_valid.we = 1'b1; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[slot_id].dest_valid.next = 8'b0010_0000; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[slot_id].last_dword.we = 1'b1; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[slot_id].last_dword.next = 'd7; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_ENTRY[slot_id][dword_i].data.we = 1'b1; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_ENTRY[slot_id][dword_i].data.next = 32'hAAAA_5555; + end + end + else if ((WriteData[7:0] == 8'hcd) && mailbox_write && ~inject_kv_error_check) begin + inject_kv_error_check <= 1'b1; + release_kv_inject_flags <= '0; + //write to every entry with dest valid 0's + //reads will result in errors + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[slot_id].dest_valid.we = 1'b1; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[slot_id].dest_valid.next = 'd0; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[slot_id].last_dword.we = 1'b1; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[slot_id].last_dword.next = 'd15; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_ENTRY[slot_id][dword_i].data.we = 1'b1; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_ENTRY[slot_id][dword_i].data.next = '1; + end + else if ((WriteData[7:0] == 8'hcd) && mailbox_write && inject_kv_error_check) begin + inject_kv_error_check <= 1'b0; + release_kv_inject_flags <= '0; + end + else begin + inject_ecc_seed <= '0; + inject_ecc_privkey <= '0; + inject_hmac_key <= '0; + inject_mldsa_seed <= '0; + inject_random_data <= '0; + inject_hmac_block <= '0; + inject_mlkem_kv <= 1'b0; + inject_aes_seed <= '0; + inject_kv16_zero_key <= '0; + inject_kv23_small_rand_key <= '0; + inject_kv23_rand_length_key <= '0; + if (release_kv_inject_flags) begin + release `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[slot_id].dest_valid.we; + release `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[slot_id].dest_valid.next; + release `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[slot_id].last_dword.we; + release `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[slot_id].last_dword.next; + release `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_ENTRY[slot_id][dword_i].data.we; + release `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_ENTRY[slot_id][dword_i].data.next; + end + else begin + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[slot_id].dest_valid.we = 1'b0; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[slot_id].dest_valid.next = '0; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[slot_id].last_dword.we = 1'b0; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[slot_id].last_dword.next = '0; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_ENTRY[slot_id][dword_i].data.we = 1'b0; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_ENTRY[slot_id][dword_i].data.next = '0; + end + release_kv_inject_flags <= '1; + end + end + end // inject_dword_loop + end // inject_slot_loop + endgenerate + + //Keyvault check for MLKEM + logic mlkem_kv_check_dis; + logic [4:0] kv_entry_id; + logic [7:0][31:0] kv_entry_data; + always_comb kv_entry_id = WriteData[12:8]; + genvar g_dword,g_byte; + + generate + for (g_dword = 0; g_dword < 8; g_dword++) begin + assign kv_entry_data[g_dword] = `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_out.KEY_ENTRY[kv_entry_id][g_dword].data.value; + for (g_byte = 0; g_byte < 4; g_byte++) begin + //KeyVault is stored big endian, so we need to reverse the order of bytes in the test vector + `CALIPTRA_ASSERT(KV_MLKEM_CHECK0, kv_entry_data[g_dword][g_byte*8 +: 8] == mlkem_test_vector.sharedkey[g_dword][31-(g_byte*8) -: 8], clk, mlkem_kv_check_dis); + end + end + endgenerate + + always@(posedge clk or negedge cptra_rst_b) begin + if (~cptra_rst_b) begin + mlkem_kv_check_dis <= 1'b1; + end + else begin + mlkem_kv_check_dis <= ~((WriteData[7:0] == 8'hb3) && mailbox_write); + end + end + + + always@(posedge clk or negedge cptra_rst_b) begin + if (~cptra_rst_b) begin + inject_zero_sign_r <= 1'b0; + inject_zero_sign_r_needs_release <= 1'b0; + inject_zero_sign_s <= 1'b0; + inject_zero_sign_s_needs_release <= 1'b0; + inject_invalid_privkey <= 1'b0; + inject_invalid_privkey_needs_release <= 1'b0; + inject_invalid_dhkey <= 1'b0; + inject_invalid_dhkey_needs_release <= 1'b0; + inject_invalid_pubkeyx <= 1'b0; + inject_invalid_pubkeyx_needs_release <= 1'b0; + inject_invalid_pubkeyy <= 1'b0; + inject_invalid_pubkeyy_needs_release <= 1'b0; + end + else if((WriteData[7:0] == 8'h98) && mailbox_write) begin + inject_zero_sign_r <= 1'b1; + end + else if((WriteData[7:0] == 8'h9a) && mailbox_write) begin + inject_zero_sign_s <= 1'b1; + end + else if((WriteData[7:0] == 8'h9c) && mailbox_write) begin + inject_invalid_privkey <= 1'b1; + end + else if((WriteData[7:0] == 8'h97) && mailbox_write) begin + inject_invalid_dhkey <= 1'b1; + end + else if((WriteData[7:0] == 8'h9d) && mailbox_write) begin + inject_invalid_pubkeyx <= 1'b1; + end + else if((WriteData[7:0] == 8'h9e) && mailbox_write) begin + inject_invalid_pubkeyy <= 1'b1; + end + else if(inject_zero_sign_r) begin + if (`CPTRA_TOP_PATH.ecc_top1.ecc_dsa_ctrl_i.prog_instr.reg_id == 6'd21) begin //R_ID + force `CPTRA_TOP_PATH.ecc_top1.ecc_dsa_ctrl_i.ecc_arith_unit_i.d_o = '0; + inject_zero_sign_r_needs_release <= 1'b1; + end + else if (inject_zero_sign_r_needs_release) begin + inject_zero_sign_r <= 1'b0; + end + end + else if(inject_zero_sign_s) begin + if (`CPTRA_TOP_PATH.ecc_top1.ecc_dsa_ctrl_i.prog_instr.reg_id == 6'd22) begin //S_ID + force `CPTRA_TOP_PATH.ecc_top1.ecc_dsa_ctrl_i.ecc_arith_unit_i.d_o = '0; + inject_zero_sign_s_needs_release <= 1'b1; + end + else if (inject_zero_sign_s_needs_release) begin + inject_zero_sign_s <= 1'b0; + end + end + else if(inject_invalid_privkey) begin + if (`CPTRA_TOP_PATH.ecc_top1.ecc_dsa_ctrl_i.prog_instr.reg_id == 6'd18) begin //PRIVKEY_ID + force `CPTRA_TOP_PATH.ecc_top1.ecc_dsa_ctrl_i.ecc_arith_unit_i.d_o = '1; + inject_invalid_privkey_needs_release <= 1'b1; + end + else if (inject_invalid_privkey_needs_release) begin + inject_invalid_privkey <= 1'b0; + end + end + else if(inject_invalid_dhkey) begin + if (`CPTRA_TOP_PATH.ecc_top1.ecc_dsa_ctrl_i.prog_instr.reg_id == 6'd30) begin //DH_SHAREDKEY_ID + force `CPTRA_TOP_PATH.ecc_top1.ecc_dsa_ctrl_i.ecc_arith_unit_i.d_o = '1; + inject_invalid_dhkey_needs_release <= 1'b1; + end + else if (inject_invalid_dhkey_needs_release) begin + inject_invalid_dhkey <= 1'b0; + end + end + else if(inject_invalid_pubkeyx) begin + if (`CPTRA_TOP_PATH.ecc_top1.ecc_dsa_ctrl_i.prog_instr.reg_id == 6'd19) begin //PUBKEYX_ID + force `CPTRA_TOP_PATH.ecc_top1.ecc_dsa_ctrl_i.ecc_arith_unit_i.d_o = '1; + inject_invalid_pubkeyx_needs_release <= 1'b1; + end + else if (inject_invalid_pubkeyx_needs_release) begin + inject_invalid_pubkeyx <= 1'b0; + end + end + else if(inject_invalid_pubkeyy) begin + if (`CPTRA_TOP_PATH.ecc_top1.ecc_dsa_ctrl_i.prog_instr.reg_id == 6'd20) begin //PUBKEYY_ID + force `CPTRA_TOP_PATH.ecc_top1.ecc_dsa_ctrl_i.ecc_arith_unit_i.d_o = '1; + inject_invalid_pubkeyy_needs_release <= 1'b1; + end + else if (inject_invalid_pubkeyy_needs_release) begin + inject_invalid_pubkeyy <= 1'b0; + end + end + else begin + release `CPTRA_TOP_PATH.ecc_top1.ecc_dsa_ctrl_i.ecc_arith_unit_i.d_o; + end + end + + //TIE-OFF device lifecycle + logic assert_ss_tran; +`ifdef CALIPTRA_DEBUG_UNLOCKED + initial security_state = '{device_lifecycle: DEVICE_PRODUCTION, debug_locked: 1'b0}; // DebugUnlocked & Production +`else + initial begin + if ($test$plusargs("CALIPTRA_DEBUG_UNLOCKED")) + security_state = '{device_lifecycle: DEVICE_PRODUCTION, debug_locked: 1'b0}; // DebugUnlocked & Production + else + security_state = '{device_lifecycle: DEVICE_PRODUCTION, debug_locked: 1'b1}; // DebugLocked & Production + + unlock_security_state = 1'b0; // Default to not unlocking security state + end +`endif + always @(negedge clk) begin + //lock debug mode + if ((WriteData[7:0] == 8'hf9) && mailbox_write) begin + security_state.debug_locked <= 1'b1; + if (UVM_TB) $warning("WARNING! Detected FW write to manually set security_state.debug_locked, but Firmware can't do this in UVM. Use a sequence in the soc_ifc_ctrl_agent to modify this field."); + end + //unlock debug mode + else if ((WriteData[7:0] == 8'hfa) && mailbox_write) begin + cycleCnt_ff <= cycleCnt; + assert_ss_tran <= 'b1; + //security_state.debug_locked <= 1'b0; + if (UVM_TB) $warning("WARNING! Detected FW write to manually clear security_state.debug_locked, but Firmware can't do this in UVM. Use a sequence in the soc_ifc_ctrl_agent to modify this field."); + end + else if(assert_ss_tran && (cycleCnt == cycleCnt_ff + 'd100)) begin + security_state.debug_locked <= 1'b0; + assert_ss_tran <= 'b0; + end + + if ((WriteData[7:0] == 8'h7F) && mailbox_write) begin + security_state.device_lifecycle <= DEVICE_MANUFACTURING; + unlock_security_state <= 1'b1; // Force unlock security state + force `CPTRA_TOP_PATH.unlock_caliptra_security_state = 1'b1; // Force unlock security state + end + else if (unlock_security_state) begin + unlock_security_state <= 1'b0; // Reset unlock security state + release `CPTRA_TOP_PATH.unlock_caliptra_security_state; // Release force unlock security state + end + end + + always_ff @(negedge clk or negedge cptra_rst_b) begin + if (!cptra_rst_b) + inject_single_msg_for_ecc_mldsa <= 'b0; + else if ((WriteData[7:0] == 8'h89) && mailbox_write && !inject_single_msg_for_ecc_mldsa) + inject_single_msg_for_ecc_mldsa <= 'b1; //set + else if ((WriteData[7:0] == 8'h89) && mailbox_write && inject_single_msg_for_ecc_mldsa) + inject_single_msg_for_ecc_mldsa <= 'b0; //reset + end + + + + always_ff @(negedge clk or negedge cptra_rst_b) begin + if (!cptra_rst_b) begin + inject_makehint_failure <= 1'b0; + inject_normcheck_failure <= 1'b0; + inject_mldsa_timeout <= 1'b0; + reset_mldsa_failure <= 1'b0; + random_mldsa_failure_injection <= $urandom(); + normcheck_mode_random <= $urandom_range(0,2); + disable_mldsa_sva <= 1'b0; + end + else if (((WriteData[7:0] == 8'hd7) && mailbox_write)) begin + if (`CPTRA_TOP_PATH.abr_inst.abr_ctrl_inst.mldsa_verifying_process) begin + inject_normcheck_failure <= 1'b1; + normcheck_mode_random <= 'h0; + inject_makehint_failure <= 1'b0; + disable_mldsa_sva <= 1'b1; + $display("Verify: Injecting normcheck failure with mode = %h\n", normcheck_mode_random); + end + else if (random_mldsa_failure_injection) begin + inject_makehint_failure <= 1'b1; + inject_normcheck_failure <= 1'b0; + disable_mldsa_sva <= 1'b1; + $display("Injecting makehint failure\n"); + end + else begin + inject_makehint_failure <= 1'b0; + inject_normcheck_failure <= 1'b1; + disable_mldsa_sva <= 1'b1; + $display("Injecting normcheck failure with mode = %h\n", normcheck_mode_random); + end + end + else if (((WriteData[7:0] == 8'hd6) && mailbox_write)) begin + inject_mldsa_timeout <= 1'b1; + end + else if (`CPTRA_TOP_PATH.abr_inst.abr_ctrl_inst.clear_verify_valid) begin //clear flags if end of signing loop or verify failed + inject_normcheck_failure <= 1'b0; + end + else if (inject_normcheck_failure && `CPTRA_TOP_PATH.abr_inst.abr_ctrl_inst.clear_signature_valid && (`CPTRA_TOP_PATH.abr_inst.norm_check_inst.mode == normcheck_mode_random)) begin //clear flags if end of signing loop or verify failed + inject_normcheck_failure <= 1'b0; + end + else if (inject_makehint_failure && `CPTRA_TOP_PATH.abr_inst.abr_ctrl_inst.clear_signature_valid && `CPTRA_TOP_PATH.abr_inst.abr_ctrl_inst.makehint_invalid_i) begin //clear flags if end of signing loop or verify failed + inject_makehint_failure <= 1'b0; + end + end + + always @(negedge clk) begin + // Hintsum: force if makehint failure (with enable) OR mldsa timeout + if ((inject_makehint_failure && `CPTRA_TOP_PATH.abr_inst.makehint_inst.hintgen_enable) || inject_mldsa_timeout) + force `CPTRA_TOP_PATH.abr_inst.makehint_inst.hintsum = 'd80; + else if (!inject_makehint_failure && !inject_mldsa_timeout) // Only release when both are clear + release `CPTRA_TOP_PATH.abr_inst.makehint_inst.hintsum; + + // Invalid: force only for normcheck with specific conditions + if (inject_normcheck_failure && + `CPTRA_TOP_PATH.abr_inst.norm_check_inst.norm_check_ctrl_inst.check_enable && + (`CPTRA_TOP_PATH.abr_inst.norm_check_inst.mode == normcheck_mode_random)) + force `CPTRA_TOP_PATH.abr_inst.norm_check_inst.invalid = 1'b1; + else if (!inject_normcheck_failure) + release `CPTRA_TOP_PATH.abr_inst.norm_check_inst.invalid; + end + + `ifndef VERILATOR + logic mldsa_keygen, mldsa_signing, mldsa_verify, mldsa_keygen_signing; + logic sha3_pubkey, sha3_message, mldsa_keygen_signing_nomsg, mldsa_verify_nomsg; + + always @(negedge clk or negedge cptra_rst_b) begin + if (!cptra_rst_b) begin + mldsa_keygen <= 'b0; + mldsa_signing <= 'b0; + mldsa_verify <= 'b0; + mldsa_keygen_signing <= 'b0; + sha3_pubkey <= 'b0; + sha3_message <= 'b0; + mldsa_keygen_signing_nomsg <= 'b0; + mldsa_verify_nomsg <= 'b0; + end + else if ((WriteData[7:0] == 8'hd0) && mailbox_write) begin + mldsa_keygen <= 'b0; + mldsa_signing <= 'b0; + mldsa_verify <= 'b0; + mldsa_keygen_signing <= 'b0; + sha3_pubkey <= 'b1; + sha3_message <= 'b0; + mldsa_keygen_signing_nomsg <= 'b0; + mldsa_verify_nomsg <= 'b0; + end + else if ((WriteData[7:0] == 8'hd1) && mailbox_write) begin + mldsa_keygen <= 'b0; + mldsa_signing <= 'b0; + mldsa_verify <= 'b0; + mldsa_keygen_signing <= 'b0; + sha3_pubkey <= 'b0; + sha3_message <= 'b1; + mldsa_keygen_signing_nomsg <= 'b0; + mldsa_verify_nomsg <= 'b0; + end + else if ((WriteData[7:0] == 8'hd2) && mailbox_write) begin + mldsa_keygen <= 'b0; + mldsa_signing <= 'b0; + mldsa_verify <= 'b0; + mldsa_keygen_signing <= 'b0; + sha3_pubkey <= 'b0; + sha3_message <= 'b0; + mldsa_keygen_signing_nomsg <= 'b1; + mldsa_verify_nomsg <= 'b0; + end + else if ((WriteData[7:0] == 8'hd3) && mailbox_write) begin + mldsa_keygen <= 'b0; + mldsa_signing <= 'b0; + mldsa_verify <= 'b0; + mldsa_keygen_signing <= 'b0; + sha3_pubkey <= 'b0; + sha3_message <= 'b0; + mldsa_keygen_signing_nomsg <= 'b0; + mldsa_verify_nomsg <= 'b1; + end + else if ((WriteData[7:0] == 8'hd8) && mailbox_write) begin + mldsa_keygen <= 'b0; + mldsa_signing <= 'b0; + mldsa_verify <= 'b0; + mldsa_keygen_signing <= 'b0; + sha3_pubkey <= 'b0; + sha3_message <= 'b0; + mldsa_keygen_signing_nomsg <= 'b0; + mldsa_verify_nomsg <= 'b0; + end + else if ((WriteData[7:0] == 8'hd9) && mailbox_write) begin + mldsa_keygen <= 'b1; + mldsa_signing <= 'b0; + mldsa_verify <= 'b0; + mldsa_keygen_signing <= 'b0; + sha3_pubkey <= 'b0; + sha3_message <= 'b0; + mldsa_keygen_signing_nomsg <= 'b0; + mldsa_verify_nomsg <= 'b0; + end + //unlock debug mode + else if ((WriteData[7:0] == 8'hda) && mailbox_write) begin + mldsa_keygen <= 'b0; + mldsa_signing <= 'b1; + mldsa_verify <= 'b0; + mldsa_keygen_signing <= 'b0; + sha3_pubkey <= 'b0; + sha3_message <= 'b0; + mldsa_keygen_signing_nomsg <= 'b0; + mldsa_verify_nomsg <= 'b0; + end + else if((WriteData[7:0] == 8'hdb) && mailbox_write) begin + mldsa_keygen <= 'b0; + mldsa_signing <= 'b0; + mldsa_verify <= 'b1; + mldsa_keygen_signing <= 'b0; + sha3_pubkey <= 'b0; + sha3_message <= 'b0; + mldsa_keygen_signing_nomsg <= 'b0; + mldsa_verify_nomsg <= 'b0; + end + else if((WriteData[7:0] == 8'hdc) && mailbox_write) begin + mldsa_keygen <= 'b0; + mldsa_signing <= 'b0; + mldsa_verify <= 'b0; + mldsa_keygen_signing <= 'b1; + sha3_pubkey <= 'b0; + sha3_message <= 'b0; + mldsa_keygen_signing_nomsg <= 'b0; + mldsa_verify_nomsg <= 'b0; + end + end + + logic [31:0] sha3_input_counter; + logic [63:0] sha3_input_data; + + logic sha3_input_ready; + always @(posedge clk) begin + sha3_input_ready <= `CPTRA_TOP_PATH.sha3.u_sha_inst.mux2fifo_ready; + end + + + always @(negedge clk) begin + if (sha3_pubkey) begin + if (sha3_input_ready) begin + if (sha3_input_counter < (PUBKEY_NUM_DWORDS/2)) begin + force `CPTRA_TOP_PATH.sha3.u_sha_inst.mux2fifo_valid = 1'b1; + sha3_input_data = { + mldsa_test_vector.pubkey[(sha3_input_counter*2)+1][ 7: 0], + mldsa_test_vector.pubkey[(sha3_input_counter*2)+1][15: 8], + mldsa_test_vector.pubkey[(sha3_input_counter*2)+1][23:16], + mldsa_test_vector.pubkey[(sha3_input_counter*2)+1][31:24], + mldsa_test_vector.pubkey[(sha3_input_counter*2) ][ 7: 0], + mldsa_test_vector.pubkey[(sha3_input_counter*2) ][15: 8], + mldsa_test_vector.pubkey[(sha3_input_counter*2) ][23:16], + mldsa_test_vector.pubkey[(sha3_input_counter*2) ][31:24] + }; + force `CPTRA_TOP_PATH.sha3.u_sha_inst.mux2fifo_data = sha3_input_data; + force `CPTRA_TOP_PATH.sha3.u_sha_inst.mux2fifo_mask = 64'hFFFF_FFFF_FFFF_FFFF; + sha3_input_counter <= sha3_input_counter + 1; + end else begin + release `CPTRA_TOP_PATH.sha3.u_sha_inst.mux2fifo_valid; + release `CPTRA_TOP_PATH.sha3.u_sha_inst.mux2fifo_data; + release `CPTRA_TOP_PATH.sha3.u_sha_inst.mux2fifo_mask; + end + end + end else if (sha3_message) begin + if (sha3_input_ready) begin + if (sha3_input_counter < (MSG_NUM_DWORDS/2)) begin + force `CPTRA_TOP_PATH.sha3.u_sha_inst.mux2fifo_valid = 1'b1; + sha3_input_data = { + mldsa_test_vector.msg[(sha3_input_counter*2)+1][ 7: 0], + mldsa_test_vector.msg[(sha3_input_counter*2)+1][15: 8], + mldsa_test_vector.msg[(sha3_input_counter*2)+1][23:16], + mldsa_test_vector.msg[(sha3_input_counter*2)+1][31:24], + mldsa_test_vector.msg[(sha3_input_counter*2) ][ 7: 0], + mldsa_test_vector.msg[(sha3_input_counter*2) ][15: 8], + mldsa_test_vector.msg[(sha3_input_counter*2) ][23:16], + mldsa_test_vector.msg[(sha3_input_counter*2) ][31:24] + }; + force `CPTRA_TOP_PATH.sha3.u_sha_inst.mux2fifo_data = sha3_input_data; + force `CPTRA_TOP_PATH.sha3.u_sha_inst.mux2fifo_mask = 64'hFFFF_FFFF_FFFF_FFFF; + sha3_input_counter <= sha3_input_counter + 1; + end else begin + release `CPTRA_TOP_PATH.sha3.u_sha_inst.mux2fifo_valid; + release `CPTRA_TOP_PATH.sha3.u_sha_inst.mux2fifo_data; + release `CPTRA_TOP_PATH.sha3.u_sha_inst.mux2fifo_mask; + end + end + end else begin + sha3_input_counter <= 'b0; + release `CPTRA_TOP_PATH.sha3.u_sha_inst.mux2fifo_valid; + release `CPTRA_TOP_PATH.sha3.u_sha_inst.mux2fifo_data; + release `CPTRA_TOP_PATH.sha3.u_sha_inst.mux2fifo_mask; + end + end + + genvar mldsa_dword; + generate + //MLDSA keygen - inject seed + for (mldsa_dword = 0; mldsa_dword < SEED_NUM_DWORDS; mldsa_dword++) begin + always @(negedge clk) begin + if (mldsa_keygen | mldsa_keygen_signing | mldsa_keygen_signing_nomsg) begin + force `CPTRA_TOP_PATH.abr_inst.abr_reg_inst.hwif_in.MLDSA_SEED[mldsa_dword].SEED.we = 'b1; + force `CPTRA_TOP_PATH.abr_inst.abr_reg_inst.hwif_in.MLDSA_SEED[mldsa_dword].SEED.next = {mldsa_test_vector.seed[mldsa_dword][7:0], mldsa_test_vector.seed[mldsa_dword][15:8], mldsa_test_vector.seed[mldsa_dword][23:16], mldsa_test_vector.seed[mldsa_dword][31:24]}; + end + else begin + release `CPTRA_TOP_PATH.abr_inst.abr_reg_inst.hwif_in.MLDSA_SEED[mldsa_dword].SEED.we; + release `CPTRA_TOP_PATH.abr_inst.abr_reg_inst.hwif_in.MLDSA_SEED[mldsa_dword].SEED.next; + end + end + end + + //MLDSA signing or MLDSA verify - inject msg + for (mldsa_dword = 0; mldsa_dword < MSG_NUM_DWORDS; mldsa_dword++) begin + always @(negedge clk) begin + if (mldsa_signing | mldsa_verify | mldsa_keygen_signing) begin + force `CPTRA_TOP_PATH.abr_inst.abr_reg_inst.hwif_in.MLDSA_MSG[mldsa_dword].MSG.we = 'b1; + force `CPTRA_TOP_PATH.abr_inst.abr_reg_inst.hwif_in.MLDSA_MSG[mldsa_dword].MSG.next = {mldsa_test_vector.msg[mldsa_dword][7:0], mldsa_test_vector.msg[mldsa_dword][15:8], mldsa_test_vector.msg[mldsa_dword][23:16], mldsa_test_vector.msg[mldsa_dword][31:24]}; + end + else begin + release `CPTRA_TOP_PATH.abr_inst.abr_reg_inst.hwif_in.MLDSA_MSG[mldsa_dword].MSG.we; + release `CPTRA_TOP_PATH.abr_inst.abr_reg_inst.hwif_in.MLDSA_MSG[mldsa_dword].MSG.next; + end + end + end + + //MLDSA signing - inject sk + for (mldsa_dword = 0; mldsa_dword < PRIVKEY_REG_RHO_NUM_DWORDS/2; mldsa_dword++) begin + always @(negedge clk) begin + if (mldsa_signing) begin + force `CPTRA_TOP_PATH.abr_inst.abr_ctrl_inst.abr_scratch_reg.mldsa_enc.rho[mldsa_dword] = {mldsa_test_vector.privkey[((mldsa_dword*2)+1)][7:0], mldsa_test_vector.privkey[((mldsa_dword*2)+1)][15:8], mldsa_test_vector.privkey[((mldsa_dword*2)+1)][23:16], mldsa_test_vector.privkey[((mldsa_dword*2)+1)][31:24], + mldsa_test_vector.privkey[(mldsa_dword*2)][7:0], mldsa_test_vector.privkey[(mldsa_dword*2)][15:8], mldsa_test_vector.privkey[(mldsa_dword*2)][23:16], mldsa_test_vector.privkey[(mldsa_dword*2)][31:24]}; + force `CPTRA_TOP_PATH.abr_inst.abr_ctrl_inst.abr_scratch_reg.mldsa_enc.K[mldsa_dword] = {mldsa_test_vector.privkey[((mldsa_dword*2)+1+8)][7:0], mldsa_test_vector.privkey[((mldsa_dword*2)+1+8)][15:8], mldsa_test_vector.privkey[((mldsa_dword*2)+1+8)][23:16], mldsa_test_vector.privkey[((mldsa_dword*2)+1+8)][31:24], + mldsa_test_vector.privkey[((mldsa_dword*2)+8)][7:0], mldsa_test_vector.privkey[((mldsa_dword*2)+8)][15:8], mldsa_test_vector.privkey[((mldsa_dword*2)+8)][23:16], mldsa_test_vector.privkey[((mldsa_dword*2)+8)][31:24]}; + end + else begin + release `CPTRA_TOP_PATH.abr_inst.abr_ctrl_inst.abr_scratch_reg.mldsa_enc.rho[mldsa_dword]; + release `CPTRA_TOP_PATH.abr_inst.abr_ctrl_inst.abr_scratch_reg.mldsa_enc.K[mldsa_dword]; + end + end + end + + for (mldsa_dword = 0; mldsa_dword < 8; mldsa_dword++) begin + always @(negedge clk) begin + if (mldsa_signing) begin + force `CPTRA_TOP_PATH.abr_inst.abr_ctrl_inst.abr_scratch_reg.mldsa_enc.tr[mldsa_dword] = {mldsa_test_vector.privkey[((mldsa_dword*2)+1+16)][7:0], mldsa_test_vector.privkey[((mldsa_dword*2)+1+16)][15:8], mldsa_test_vector.privkey[((mldsa_dword*2)+1+16)][23:16], mldsa_test_vector.privkey[((mldsa_dword*2)+1+16)][31:24], + mldsa_test_vector.privkey[((mldsa_dword*2)+16)][7:0], mldsa_test_vector.privkey[((mldsa_dword*2)+16)][15:8], mldsa_test_vector.privkey[((mldsa_dword*2)+16)][23:16], mldsa_test_vector.privkey[((mldsa_dword*2)+16)][31:24]}; + end + else begin + release `CPTRA_TOP_PATH.abr_inst.abr_ctrl_inst.abr_scratch_reg.mldsa_enc.tr[mldsa_dword]; + end + end + end + + for (mldsa_dword = PRIVKEY_REG_NUM_DWORDS; mldsa_dword < PRIVKEY_NUM_DWORDS; mldsa_dword++) begin + always @(negedge clk) begin + if (mldsa_signing) begin + if ((mldsa_dword % 2) == 0) begin + force abr_mem_top_inst.abr_sk_mem_bank0_inst.ram[(mldsa_dword-32)/2] = {mldsa_test_vector.privkey[mldsa_dword][7:0], mldsa_test_vector.privkey[mldsa_dword][15:8], mldsa_test_vector.privkey[mldsa_dword][23:16], mldsa_test_vector.privkey[mldsa_dword][31:24]}; + end + else begin + force abr_mem_top_inst.abr_sk_mem_bank1_inst.ram[(mldsa_dword-33)/2] = {mldsa_test_vector.privkey[mldsa_dword][7:0], mldsa_test_vector.privkey[mldsa_dword][15:8], mldsa_test_vector.privkey[mldsa_dword][23:16], mldsa_test_vector.privkey[mldsa_dword][31:24]}; + end + end + else begin + release abr_mem_top_inst.abr_sk_mem_bank0_inst.ram[(mldsa_dword-32)/2]; + release abr_mem_top_inst.abr_sk_mem_bank1_inst.ram[(mldsa_dword-33)/2]; + end + end + end + + //MLDSA verify - inject pk + for (mldsa_dword = 0; mldsa_dword < 4; mldsa_dword++) begin + always @(negedge clk) begin + if (mldsa_verify | mldsa_verify_nomsg) begin + force `CPTRA_TOP_PATH.abr_inst.abr_ctrl_inst.abr_scratch_reg.mldsa_enc.rho[mldsa_dword] = {mldsa_test_vector.pubkey[((mldsa_dword*2)+1)][7:0], mldsa_test_vector.pubkey[((mldsa_dword*2)+1)][15:8], mldsa_test_vector.pubkey[((mldsa_dword*2)+1)][23:16], mldsa_test_vector.pubkey[((mldsa_dword*2)+1)][31:24], + mldsa_test_vector.pubkey[(mldsa_dword*2)][7:0], mldsa_test_vector.pubkey[(mldsa_dword*2)][15:8], mldsa_test_vector.pubkey[(mldsa_dword*2)][23:16], mldsa_test_vector.pubkey[(mldsa_dword*2)][31:24]}; + + end + else begin + release `CPTRA_TOP_PATH.abr_inst.abr_ctrl_inst.abr_scratch_reg.mldsa_enc.rho[mldsa_dword]; + end + end + end + for (genvar a = 0; a < 64; a++) begin + for (genvar b = 0; b < 10; b++) begin + always @(negedge clk) begin + if (mldsa_verify | mldsa_verify_nomsg) begin + force abr_mem_top_inst.abr_pk_mem_inst.ram[a][b*4+3:b*4] = {mldsa_test_vector.pubkey[a*10+8+b][7:0], mldsa_test_vector.pubkey[a*10+8+b][15:8], mldsa_test_vector.pubkey[a*10+8+b][23:16], mldsa_test_vector.pubkey[a*10+8+b][31:24]}; + end + else begin + release abr_mem_top_inst.abr_pk_mem_inst.ram[a][b*4+3:b*4]; + end + end + end + end + + //MLDSA verify - inject signature + for (mldsa_dword = 0; mldsa_dword < VERIFY_RES_NUM_DWORDS; mldsa_dword++) begin + always @(negedge clk) begin + if (mldsa_verify | mldsa_verify_nomsg) begin + force `CPTRA_TOP_PATH.abr_inst.abr_ctrl_inst.signature_reg.enc.c[mldsa_dword] = {mldsa_test_vector.signature[mldsa_dword][7:0], mldsa_test_vector.signature[mldsa_dword][15:8], mldsa_test_vector.signature[mldsa_dword][23:16], mldsa_test_vector.signature[mldsa_dword][31:24]}; + end + else begin + release `CPTRA_TOP_PATH.abr_inst.abr_ctrl_inst.signature_reg.enc.c[mldsa_dword]; + end + end + end + for (mldsa_dword = 0; mldsa_dword < SIGNATURE_H_NUM_DWORDS; mldsa_dword++) begin + always @(negedge clk) begin + if (mldsa_verify | mldsa_verify_nomsg) begin + force `CPTRA_TOP_PATH.abr_inst.abr_ctrl_inst.signature_reg.enc.h[mldsa_dword] = {mldsa_test_vector.signature[1136+mldsa_dword][7:0], mldsa_test_vector.signature[1136+mldsa_dword][15:8], mldsa_test_vector.signature[1136+mldsa_dword][23:16], mldsa_test_vector.signature[1136+mldsa_dword][31:24]}; + end + else begin + release `CPTRA_TOP_PATH.abr_inst.abr_ctrl_inst.signature_reg.enc.h[mldsa_dword]; + end + end + end + for (genvar a = 0; a < 224; a++) begin + for (genvar b = 0; b < 5; b++) begin + always @(negedge clk) begin + if (mldsa_verify | mldsa_verify_nomsg) begin + force abr_mem_top_inst.abr_sig_z_mem_inst.ram[a][b*4+3:b*4] = {mldsa_test_vector.signature[a*5+16+b][7:0], mldsa_test_vector.signature[a*5+16+b][15:8], mldsa_test_vector.signature[a*5+16+b][23:16], mldsa_test_vector.signature[a*5+16+b][31:24]}; + end + else begin + release abr_mem_top_inst.abr_sig_z_mem_inst.ram[a][b*4+3:b*4]; + end + end + end + end + endgenerate + `endif + + //Randomized wntz + generate + for (genvar dword = 15; dword >= 0; dword--) begin + always@(negedge clk) begin + if ((WriteData[7:0] == 8'hdd) && mailbox_write) begin + force `CPTRA_TOP_PATH.sha256.sha256_inst.hwif_out.SHA256_BLOCK[dword].BLOCK.value = sha256_wntz_test_vector.sha256_wntz_block_tb[15-dword]; + force `CPTRA_TOP_PATH.sha256.sha256_inst.wntz_mode = 1'b1; //single pulse + force `CPTRA_TOP_PATH.sha256.sha256_inst.wntz_n_mode = sha256_wntz_test_vector.wntz_n; + force `CPTRA_TOP_PATH.sha256.sha256_inst.wntz_w = sha256_wntz_test_vector.wntz_w; + force `CPTRA_TOP_PATH.sha256.sha256_inst.init_reg = 1'b1; + force `CPTRA_TOP_PATH.sha256.sha256_inst.mode_reg = 1'b1; + end //if 'hdd + else if (`CPTRA_TOP_PATH.sha256.sha256_inst.hwif_out.SHA256_CTRL.ZEROIZE.value) begin + release `CPTRA_TOP_PATH.sha256.sha256_inst.hwif_out.SHA256_BLOCK[dword].BLOCK.value; + end + else begin + // release `CPTRA_TOP_PATH.sha256.sha256_inst.hwif_out.SHA256_BLOCK[dword].BLOCK.value; + release `CPTRA_TOP_PATH.sha256.sha256_inst.wntz_mode; + release `CPTRA_TOP_PATH.sha256.sha256_inst.init_reg; + end //else + end //always + end //for + endgenerate + + generate + for(genvar dword = 0; dword < IV_NO; dword++) begin + always@(negedge clk) begin + if ((WriteData[7:0] == 8'hec) && mailbox_write) begin + force `CPTRA_TOP_PATH.doe.doe_inst.hwif_out.DOE_IV[dword].IV.swmod = 'b1; + force `CPTRA_TOP_PATH.doe.doe_inst.i_doe_reg.field_storage.DOE_IV[dword].IV.value = doe_test_vector.iv_uds[dword]; + end + else if ((WriteData[7:0] == 8'hed) && mailbox_write) begin + force `CPTRA_TOP_PATH.doe.doe_inst.hwif_out.DOE_IV[dword].IV.swmod = 'b1; + force `CPTRA_TOP_PATH.doe.doe_inst.i_doe_reg.field_storage.DOE_IV[dword].IV.value = doe_test_vector.iv_fe[dword]; + end + else if ((WriteData[7:0] == 8'hd5) && mailbox_write) begin + force `CPTRA_TOP_PATH.doe.doe_inst.hwif_out.DOE_IV[dword].IV.swmod = 'b1; + force `CPTRA_TOP_PATH.doe.doe_inst.i_doe_reg.field_storage.DOE_IV[dword].IV.value = doe_test_vector.iv_hek[dword]; + end + else begin + release `CPTRA_TOP_PATH.doe.doe_inst.hwif_out.DOE_IV[dword].IV.swmod; + release `CPTRA_TOP_PATH.doe.doe_inst.i_doe_reg.field_storage.DOE_IV[dword].IV.value; + end + end +end //for +endgenerate //IV_NO + + logic assert_scan_mode; + logic assert_scan_mode_doe_done; + logic assert_scan_mode_kv_write; + always @(negedge clk) begin + //Enable scan mode + if ((WriteData[7:0] == 8'hef) && mailbox_write) begin + cycleCnt_ff <= cycleCnt; + assert_scan_mode <= 'b1; + //scan_mode <= 1'b1; + end + else if ((WriteData[7:0] == 8'he8) && mailbox_write) begin + cycleCnt_ff <= cycleCnt; + assert_scan_mode_doe_done <= 'b1; + end + else if(assert_scan_mode && (cycleCnt == cycleCnt_ff + 'd100)) begin + scan_mode <= 1'b1; + assert_scan_mode <= 'b0; + end + else if ((WriteData[7:0] == 8'hb9) && mailbox_write) begin + scan_mode <= 1'b1; + assert_scan_mode <= 'b0; + end + else if ((WriteData[7:0] == 8'hba) && mailbox_write) begin + assert_scan_mode_kv_write <= 1'b1; + end + else if (assert_scan_mode_kv_write) begin + for (int client = 0; client < KV_NUM_WRITE; client++)begin + if (`CPTRA_TOP_PATH.key_vault1.kv_write[client].write_en) begin + scan_mode <= 1'b1; + assert_scan_mode <= 'b0; + assert_scan_mode_kv_write <= 'b0; + end + end + end + else if (assert_scan_mode_doe_done && (`CPTRA_TOP_PATH.doe.doe_inst.doe_fsm1.kv_doe_fsm_ps == 'h5)) begin + scan_mode <= 1'b1; + assert_scan_mode <= 'b0; + end + //Disable scan mode + else if ((WriteData[7:0] == 8'hf0) && mailbox_write) begin + scan_mode <= 1'b0; + end + end + + always@(negedge clk) begin + if ((WriteData[7:0] == 8'hb9) && mailbox_write) begin + force `CPTRA_TOP_PATH.doe.doe_inst.i_doe_reg.field_storage.DOE_CTRL.CMD.value = 2'b1; + cycleCnt_ff <= cycleCnt; + end + else if(cycleCnt == cycleCnt_ff + 'd5) begin + release `CPTRA_TOP_PATH.doe.doe_inst.i_doe_reg.field_storage.DOE_CTRL.CMD.value; + end + end + + always@(negedge clk) begin + if((WriteData[7:0] == 8'hf2) && mailbox_write) begin + force `CPTRA_TOP_PATH.soc_ifc_top1.clk_gating_en = 1; + end + end + + always@(negedge clk) begin + if ((WriteData[7:0] == 8'he9) && mailbox_write) begin + cycleCnt_ff <= cycleCnt; + en_jtag_access <= 'b1; + end + else if(en_jtag_access && (cycleCnt == (cycleCnt_ff + 'd100))) begin + force `CPTRA_TOP_PATH.cptra_dmi_reg_en_preQ = 1; + end + else if(en_jtag_access && (cycleCnt == (cycleCnt_ff + 'd150))) begin + release `CPTRA_TOP_PATH.cptra_dmi_reg_en_preQ; + en_jtag_access <= 'b0; + end + end + + logic inject_zeroize_to_hmac; + logic inject_zeroize_to_hmac_cmd; + logic [3 : 0] inject_zeroize_to_hmac_cnt; + always@(posedge clk or negedge cptra_rst_b) begin + if (~cptra_rst_b) begin + inject_zeroize_to_hmac_cmd <= 1'b0; + inject_zeroize_to_hmac <= 1'b0; + inject_zeroize_to_hmac_cnt <= '0; + end + else if((WriteData[7:0] == 8'h99) && mailbox_write) begin + inject_zeroize_to_hmac_cmd <= 1'b1; + end + else if (inject_zeroize_to_hmac_cmd) begin + if (`CPTRA_TOP_PATH.hmac.hmac_inst.core_tag_we) begin + inject_zeroize_to_hmac <= 1'b1; + end + if (inject_zeroize_to_hmac) begin + if (inject_zeroize_to_hmac_cnt < 4'hf) begin + inject_zeroize_to_hmac_cnt <= inject_zeroize_to_hmac_cnt + 1'b1; + end + end + end + end + always@(negedge clk) begin + if (inject_zeroize_to_hmac) begin + if (inject_zeroize_to_hmac_cnt == 4'h5) begin + force `CPTRA_TOP_PATH.hmac.hmac_inst.i_hmac_reg.field_storage.HMAC512_CTRL.ZEROIZE.value = 1'b1; + end + else begin + release `CPTRA_TOP_PATH.hmac.hmac_inst.i_hmac_reg.field_storage.HMAC512_CTRL.ZEROIZE.value; + end + end + end + + logic inject_zeroize_kv_read; + logic inject_zeroize_to_mldsa; + always@(posedge clk or negedge cptra_rst_b) begin + if (~cptra_rst_b) begin + inject_zeroize_kv_read <= 1'b0; + inject_zeroize_to_mldsa <= 1'b0; + end + else if((WriteData[7:0] == 8'h9b) && mailbox_write) begin + inject_zeroize_kv_read <= 1'b1; + end + else if (inject_zeroize_kv_read) begin + if (`CPTRA_TOP_PATH.abr_inst.abr_ctrl_inst.kv_mldsa_seed_write_en & + (`CPTRA_TOP_PATH.abr_inst.abr_ctrl_inst.kv_mldsa_seed_write_offset == 3)) begin + inject_zeroize_to_mldsa <= 1'b1; + end + if (inject_zeroize_to_mldsa) begin + inject_zeroize_to_mldsa <= 1'b0; + inject_zeroize_kv_read <= 1'b0; + end + end + end + always@(negedge clk) begin + if (inject_zeroize_to_mldsa) begin + force `CPTRA_TOP_PATH.abr_inst.abr_ctrl_inst.abr_reg_hwif_out.MLDSA_CTRL.ZEROIZE.value = 1'b1; + end else begin + release `CPTRA_TOP_PATH.abr_inst.abr_ctrl_inst.abr_reg_hwif_out.MLDSA_CTRL.ZEROIZE.value; + end + end + + genvar g_client, g_entry; + generate + for (g_client = 0; g_client < KV_NUM_READ; g_client++) begin : gen_kv_client_loop + for (g_entry = 0; g_entry < KV_NUM_KEYS; g_entry++) begin : gen_kv_entry_loop + logic dest_valid_release_local; + always@(posedge clk) begin + if (inject_kv_error_check) begin + // If we see a key being read, set the dest valid bit + if ((`CPTRA_TOP_PATH.key_vault1.kv_read[g_client].read_offset == 'd1) && + (`CPTRA_TOP_PATH.key_vault1.kv_read[g_client].read_entry == g_entry)) begin + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[g_entry].dest_valid.we = 1'b1; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[g_entry].dest_valid.next[g_client] = 1'b1; + dest_valid_release_local <= 1'b0; + end + // If dest valid bit is set and we are done reading, clear it + else if (`CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_out.KEY_CTRL[g_entry].dest_valid[g_client] && + ((`CPTRA_TOP_PATH.key_vault1.kv_read[g_client].read_offset == '0) || + (`CPTRA_TOP_PATH.key_vault1.kv_read[g_client].read_entry != g_entry))) begin + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[g_entry].dest_valid.we = 1'b1; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[g_entry].dest_valid.next[g_client] = 1'b0; + dest_valid_release_local <= 1'b0; + // Otherwise, release the forces + end else begin + if (dest_valid_release_local) begin + release `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[g_entry].dest_valid.we; + release `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[g_entry].dest_valid.next[g_client]; + end + else begin + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[g_entry].dest_valid.we = 1'b0; + force `CPTRA_TOP_PATH.key_vault1.kv_reg_hwif_in.KEY_CTRL[g_entry].dest_valid.next[g_client] = 1'b0; + end + dest_valid_release_local <= 1'b1; + end + end + else begin + dest_valid_release_local <= 1'b1; + end + end + end + end + endgenerate + + always@(posedge clk) begin + if((WriteData[7:0] == 8'hb5) && mailbox_write) begin + `ifdef CLP_ASSERT_ON + `ifndef VERILATOR + $display("Turning ON assertions using $asserton"); + $asserton; + `endif + `endif + end + else if((WriteData[7:0] == 8'hb6) && mailbox_write) begin + `ifdef CLP_ASSERT_ON + `ifndef VERILATOR + $display("Turning OFF assertion using $assertoff"); + $assertoff; + `endif + `endif + end + end + + always@(posedge clk or negedge cptra_rst_b) begin + if(!cptra_rst_b) begin + axi_error_inj_en <= 1'b0; + end else if((WriteData[7:0] == 8'hb7) && mailbox_write) begin + $display("AXI Err Injection Enabled"); + axi_error_inj_en <= 1'b1; + end else if((WriteData[7:0] == 8'hb8) && mailbox_write) begin + $display("AXI Err Injection Disabled"); + axi_error_inj_en <= 1'b0; + end + end + + logic inject_mlkem_zeroize_kv_read; + logic inject_zeroize_to_mlkem; + always@(posedge clk or negedge cptra_rst_b) begin + if (~cptra_rst_b) begin + inject_mlkem_zeroize_kv_read <= 1'b0; + inject_zeroize_to_mlkem <= 1'b0; + end + else if((WriteData[7:0] == 8'hb4) && mailbox_write) begin + inject_mlkem_zeroize_kv_read <= 1'b1; + end + else if (inject_mlkem_zeroize_kv_read) begin + if (`CPTRA_TOP_PATH.abr_inst.abr_ctrl_inst.kv_mlkem_seed_write_en & + (`CPTRA_TOP_PATH.abr_inst.abr_ctrl_inst.kv_mlkem_seed_write_offset == 3)) begin + inject_zeroize_to_mlkem <= 1'b1; + end + else if (`CPTRA_TOP_PATH.abr_inst.abr_ctrl_inst.kv_mlkem_msg_write_en & + (`CPTRA_TOP_PATH.abr_inst.abr_ctrl_inst.kv_mlkem_msg_write_offset == 3)) begin + inject_zeroize_to_mlkem <= 1'b1; + end + if (inject_zeroize_to_mlkem) begin + inject_zeroize_to_mlkem <= 1'b0; + inject_mlkem_zeroize_kv_read <= 1'b0; + end + end + end + always@(negedge clk) begin + if (inject_zeroize_to_mlkem) begin + force `CPTRA_TOP_PATH.abr_inst.abr_ctrl_inst.abr_reg_hwif_out.MLKEM_CTRL.ZEROIZE.value = 1'b1; + end else begin + release `CPTRA_TOP_PATH.abr_inst.abr_ctrl_inst.abr_reg_hwif_out.MLKEM_CTRL.ZEROIZE.value; + end + end + + //Inject fatal error after a delay + logic inject_fatal_error; + always@(negedge clk) begin + if((WriteData[7:0] == 8'heb) && mailbox_write) begin + cycleCnt_ff <= cycleCnt; + inject_fatal_error <= 'b1; + end + else if(inject_fatal_error && (cycleCnt == cycleCnt_ff + 'd100)) begin + force `CPTRA_TOP_PATH.cptra_error_fatal = 'b1; + end + else if(inject_fatal_error && (cycleCnt == cycleCnt_ff + 'd200)) begin + release `CPTRA_TOP_PATH.cptra_error_fatal; + inject_fatal_error <= 'b0; + end + end + + logic [0:11][31:0] pv_hash_value = {32'h11143121, + 32'hbeb365e6, + 32'h3826e7de, + 32'h89f9c76a, + 32'he1100411, + 32'hfb9643d1, + 32'h98e730b7, + 32'h603a83a4, + 32'h977c76ee, + 32'he6ddf74f, + 32'ha0b43fbf, + 32'h49897978}; + + logic pcr_vault_needs_release; + + generate + for (genvar dword = 0; dword < 12; dword++) begin + always@(posedge clk or negedge cptra_rst_b) begin + if (~cptra_rst_b) begin + pcr_vault_needs_release <= 1'b0; + end + else if((WriteData[7:0] == 8'hf3) && mailbox_write) begin + pcr_vault_needs_release <= 1'b1; + force `CPTRA_TOP_PATH.pcr_vault1.pv_reg_hwif_in.PCR_ENTRY[31][dword].data.we = 1'b1; + force `CPTRA_TOP_PATH.pcr_vault1.pv_reg_hwif_in.PCR_ENTRY[31][dword].data.next = pv_hash_value[dword]; + end + else if (pcr_vault_needs_release) begin + pcr_vault_needs_release <= 1'b0; + release `CPTRA_TOP_PATH.pcr_vault1.pv_reg_hwif_in.PCR_ENTRY[31][dword].data.we; + release `CPTRA_TOP_PATH.pcr_vault1.pv_reg_hwif_in.PCR_ENTRY[31][dword].data.next; + end + end + end + endgenerate + + task sha256_wntz_testvector_generator(); + string file_name; + int fd_r; + string line_read; + int w_ln, w, n; + + w_ln = $urandom_range(3, 0); + w = 2**w_ln; + n = $urandom_range(0, 1); + + $system($sformatf("python sha256_wntz_test_gen.py %d %d", w, n)); + file_name = "sha256_wntz_test_vector.txt"; + + if (!UVM_TB) begin + fd_r = $fopen(file_name, "r"); + if (fd_r == 0) $error("Cannot open file %s for reading", file_name); + + //Get values from file + void'($fgets(line_read, fd_r)); + void'($sscanf(line_read, "%h", sha256_wntz_test_vector.sha256_wntz_block_tb)); + void'($fgets(line_read, fd_r)); + void'($sscanf(line_read, "%h", sha256_wntz_test_vector.sha256_wntz_digest)); + sha256_wntz_test_vector.wntz_n = n; + sha256_wntz_test_vector.wntz_w = w; + $fclose(fd_r); + end + endtask + + task doe_testvector_generator(); + string file_name; + int fd_r; + string line_read; + + $system("python doe_test_gen.py"); + file_name = "doe_test_vector.txt"; + if(!UVM_TB) begin + fd_r = $fopen(file_name, "r"); + if(fd_r == 0) $error("Cannot open file %s for reading", file_name); + + //Get values from file + void'($fgets(line_read, fd_r)); + void'($sscanf(line_read, "%h", doe_test_vector.obf_key_uds)); + void'($fgets(line_read, fd_r)); + void'($sscanf(line_read, "%h", doe_test_vector.iv_uds)); + void'($fgets(line_read, fd_r)); + void'($sscanf(line_read, "%h", doe_test_vector.uds_plaintext)); + void'($fgets(line_read, fd_r)); + void'($sscanf(line_read, "%h", doe_test_vector.uds_ciphertext)); + + void'($fgets(line_read, fd_r)); + void'($sscanf(line_read, "%h", doe_test_vector.obf_key_fe)); + void'($fgets(line_read, fd_r)); + void'($sscanf(line_read, "%h", doe_test_vector.iv_fe)); + void'($fgets(line_read, fd_r)); + void'($sscanf(line_read, "%h", doe_test_vector.fe_plaintext)); + void'($fgets(line_read, fd_r)); + void'($sscanf(line_read, "%h", doe_test_vector.fe_ciphertext)); + + void'($fgets(line_read, fd_r)); + void'($sscanf(line_read, "%h", doe_test_vector.obf_key_hek)); + void'($fgets(line_read, fd_r)); + void'($sscanf(line_read, "%h", doe_test_vector.iv_hek)); + void'($fgets(line_read, fd_r)); + void'($sscanf(line_read, "%h", doe_test_vector.hek_plaintext)); + void'($fgets(line_read, fd_r)); + void'($sscanf(line_read, "%h", doe_test_vector.hek_ciphertext)); + + $fclose(fd_r); + end + + endtask + + task mlkem_testvector_generator(); + int fd; + string input_fname, output_fname, cmd, line; + bit [31:0] seed_d[]; + bit [31:0] seed_z[]; + bit [31:0] ek[]; + bit [31:0] dk[]; + bit [31:0] msg[]; + bit [31:0] ciphertext[]; + bit [31:0] sharedkey[]; + + seed_d = new[8]; + seed_z = new[8]; + msg = new[8]; + ek = new[392]; + dk = new[792]; + ciphertext = new[392]; + sharedkey = new[8]; + + //randomize the inputs + for (int i = 0; i < 8; i++) begin + seed_d[i] = $urandom(); + seed_z[i] = $urandom(); + msg[i] = $urandom(); + end + //Generate EK and DK + input_fname = "ml-kem/tv/keygen_ext_input.txt"; + fd = $fopen(input_fname, "w"); + if (fd == 0) $error("Cannot open %s for writing", input_fname); + // line1: operation code + $fwrite(fd, "1\n"); + // line2-3: z, d as hex strings + write_file(fd, 8, seed_z); + write_file(fd, 8, seed_d); + $fclose(fd); + // 3) invoke the python generator + cmd = $sformatf("python3.9 ml-kem/random_test_ml_kem.py 1 -i %s -o ml-kem/tv/keygen_ext_output.txt",input_fname); + $display("## Running: %s", cmd); + if ($system(cmd) != 0) $error("External Python script failed"); + // 4) read back ek and dk from the output file + output_fname = "ml-kem/tv/keygen_ext_output.txt"; + fd = $fopen(output_fname, "r"); + if (fd == 0) $error("Cannot open %s for reading", output_fname); + // skip lines 1–3 (op, z, d) + void'($fgets(line, fd)); + void'($fgets(line, fd)); + void'($fgets(line, fd)); + read_line(fd, 392, ek); + read_line(fd, 792, dk); + $fclose(fd); + // 2) write the python‐readable input file + input_fname = "ml-kem/tv/encap_ext_input.txt"; + fd = $fopen(input_fname, "w"); + if (fd == 0) $error("Cannot open %s for writing", input_fname); + // line1: operation code + $fwrite(fd, "2\n"); + // line2-3: z, d as hex strings + write_file(fd, 8, msg); + write_file(fd, 392, ek); + $fclose(fd); + // 3) invoke the python generator + cmd = $sformatf("python3.9 ml-kem/random_test_ml_kem.py 2 -i %s -o ml-kem/tv/encap_ext_output.txt", input_fname); + $display("## Running: %s", cmd); + if ($system(cmd) != 0) $error("External Python script failed"); + // 4) read back ek and dk from the output file + output_fname = "ml-kem/tv/encap_ext_output.txt"; + fd = $fopen(output_fname, "r"); + if (fd == 0) $error("Cannot open %s for reading", output_fname); + // skip lines 1–3 (op, m, ek) + void'($fgets(line, fd)); + void'($fgets(line, fd)); + void'($fgets(line, fd)); + read_line(fd, 8, sharedkey); + read_line(fd, 392, ciphertext); + $fclose(fd); + + //Assign to test vector struct + for (int i = 0; i < 8; i++) begin + mlkem_test_vector.seed_d[i] = seed_d[i]; + mlkem_test_vector.seed_z[i] = seed_z[i]; + mlkem_test_vector.msg[i] = msg[i]; + mlkem_test_vector.sharedkey[i] = sharedkey[i]; + end + for (int i = 0; i < 392; i++) begin + mlkem_test_vector.ek[i] = ek[i]; + mlkem_test_vector.ciphertext[i] = ciphertext[i]; + end + for (int i = 0; i < 792; i++) begin + mlkem_test_vector.dk[i] = dk[i]; + end + endtask + + task mldsa_input_hex_gen(); //mode = CTRL.value-1 + int fd_r; + logic [7:0][31:0] seed; + logic [15:0][31:0] msg; + string keygen_outfile, sign_outfile, verify_outfile; + string keygen_infile, sign_infile, verify_infile; + string line_read; + keygen_outfile = "keygen_input.hex"; + keygen_infile = "keygen_output.hex"; + sign_outfile = "sign_input.hex"; + sign_infile = "sign_output.hex"; + verify_outfile = "verify_input.hex"; + verify_infile = "verify_output.hex"; + + //--------------------------- + //Keygen + //--------------------------- + fd_r = $fopen(keygen_outfile, "w"); + for (int i = 0; i < 8; i++) begin + seed[i] = $urandom(); + end + mldsa_test_vector.seed = seed; + $fwrite(fd_r, "%02X\n", 0); //write cmd (keygen) as a 2 digit number + $fwrite(fd_r, "%h", seed); //write random seed 8*4 bytes + $fclose(fd_r); + $system("./test_dilithium5 keygen_input.hex keygen_output.hex"); + + fd_r = $fopen(keygen_infile, "r"); + if (fd_r == 0) + $error("Can't open file %s", keygen_infile); + + void'($fgets(line_read, fd_r)); //skip cmd + void'($fgets(line_read, fd_r)); + void'($sscanf(line_read, "%h", mldsa_test_vector.pubkey)); + void'($fgets(line_read, fd_r)); + void'($sscanf(line_read, "%h", mldsa_test_vector.privkey)); + + //--------------------------- + //Sign + //--------------------------- + fd_r = $fopen(sign_outfile, "w"); + for (int i = 0; i < 16; i++) begin + msg[i] = $urandom(); + end + mldsa_test_vector.msg = msg; + $fwrite(fd_r, "%02X\n", 1); + $fwrite(fd_r, "%h\n", msg); + $fwrite(fd_r, "%h", mldsa_test_vector.privkey); + $fclose(fd_r); + $system("./test_dilithium5 sign_input.hex sign_output.hex"); + + fd_r = $fopen(sign_infile, "r"); + if (fd_r == 0) + $error("Can't open file %s", sign_infile); + + void'($fgets(line_read, fd_r)); //skip cmd + void'($fgets(line_read, fd_r)); //skip sig length + void'($fgets(line_read, fd_r)); + void'($sscanf(line_read, "%h", mldsa_test_vector.signature)); + mldsa_test_vector.signature = {mldsa_test_vector.signature[0:1156], 8'h00}; + + mldsa_test_vector.sign_rnd = 'h0; + + //--------------------------- + //Verify + //--------------------------- + fd_r = $fopen(verify_outfile, "w"); + $fwrite(fd_r, "%02X\n", 2); + $fwrite(fd_r, "%h\n", {mldsa_test_vector.signature[0:1155], mldsa_test_vector.signature[1156][31:8]}); //[0:1156][31:0] signature + $fwrite(fd_r, "%h\n", mldsa_test_vector.msg); + $fwrite(fd_r, "%h", mldsa_test_vector.pubkey); + $fclose(fd_r); + $system("./test_dilithium5 verify_input.hex verify_output.hex"); + + fd_r = $fopen(verify_infile, "r"); + if (fd_r == 0) + $error("Can't open file %s", verify_infile); + + void'($fgets(line_read, fd_r)); //skip cmd + void'($fgets(line_read, fd_r)); //skip 2nd line + void'($fgets(line_read, fd_r)); + void'($sscanf(line_read, "%h", mldsa_test_vector.verify_res)); + endtask + + task ecc_testvector_generator (); + string file_name; + begin + + $system("./ecc_secp384r1.exe"); + + file_name = "secp384_testvector.hex"; + if (!UVM_TB) ecc_read_test_vectors(file_name); + end + endtask // ecc_test + + task static ecc_read_test_vectors (input string fname); + integer values_per_test_vector; + int fd_r; + string line_read; + begin + + // ATTN: Must match the number of fields generated by gen_mm_test_vectors.py script + values_per_test_vector = 11; + + fd_r = $fopen(fname, "r"); + if (fd_r == 0) + $error("Can't open file %s", fname); + + + // Get hashed message, private key, public key x, public key y, k and R + void'($fgets(line_read, fd_r)); + void'($sscanf(line_read, "%h", ecc_test_vector.hashed_msg)); + void'($fgets(line_read, fd_r)); + void'($sscanf(line_read, "%h", ecc_test_vector.privkey)); + void'($fgets(line_read, fd_r)); + void'($sscanf(line_read, "%h", ecc_test_vector.pubkey.x)); + void'($fgets(line_read, fd_r)); + void'($sscanf(line_read, "%h", ecc_test_vector.pubkey.y)); + void'($fgets(line_read, fd_r)); + void'($sscanf(line_read, "%h", ecc_test_vector.seed)); + void'($fgets(line_read, fd_r)); + void'($sscanf(line_read, "%h", ecc_test_vector.nonce)); + void'($fgets(line_read, fd_r)); + void'($sscanf(line_read, "%h", ecc_test_vector.R)); + void'($fgets(line_read, fd_r)); + void'($sscanf(line_read, "%h", ecc_test_vector.S)); + void'($fgets(line_read, fd_r)); + void'($sscanf(line_read, "%h", ecc_test_vector.IV)); + void'($fgets(line_read, fd_r)); + void'($sscanf(line_read, "%h", ecc_test_vector.privkeyB)); + void'($fgets(line_read, fd_r)); + void'($sscanf(line_read, "%h", ecc_test_vector.dh_sharedkey)); + + $fclose(fd_r); + + end + endtask + + logic [0:15][31:0] pcr_to_be_signed = 512'h_C8F518D4F3AA1BD46ED56C1C3C9E16FB800AF504DB98843548C5F623EE115F73D4C62ABC06D303B5D90D9A175087290D_16e6009644e2a5f2c41fed22e703fb78; + logic [0:15][31:0] ecc_random_msg; + logic [0:15][31:0] mldsa_random_msg; + always_comb ecc_random_msg = {ecc_test_vector.hashed_msg, 128'h00000000000000000000000000000000}; + always_comb mldsa_random_msg = change_endian(mldsa_test_vector.msg); //swap the endian + + generate + for (genvar dword = 0; dword < 16; dword++) begin + always@(posedge clk) begin + if((WriteData[7:0] == 8'h90) && mailbox_write) begin + force `CPTRA_TOP_PATH.sha512.sha512_inst.pcr_sign_we = 1'b1; + force `CPTRA_TOP_PATH.sha512.sha512_inst.pcr_sign[dword] = pcr_to_be_signed[15-dword][31 : 0]; + end + else if((WriteData[7:0] == 8'h91) && mailbox_write) begin + force `CPTRA_TOP_PATH.sha512.sha512_inst.pcr_sign_we = 1'b1; + force `CPTRA_TOP_PATH.sha512.sha512_inst.pcr_sign[dword] = ecc_random_msg[15-dword][31 : 0]; + end + else if((WriteData[7:0] == 8'h93) && mailbox_write && !inject_single_msg_for_ecc_mldsa) begin //TODO: what if mldsa is trig'd first and then ecc? + force `CPTRA_TOP_PATH.sha512.sha512_inst.pcr_sign_we = 1'b1; + force `CPTRA_TOP_PATH.sha512.sha512_inst.pcr_sign[dword] = mldsa_random_msg[15-dword][31 : 0]; + end + else begin + release `CPTRA_TOP_PATH.sha512.sha512_inst.pcr_sign_we; + release `CPTRA_TOP_PATH.sha512.sha512_inst.pcr_sign[dword]; + end + end + end + endgenerate + + always @(negedge clk) begin + if((WriteData[7:0] == 8'h92) && mailbox_write) + check_pcr_ecc_signing <= 1'b1; + else if((WriteData[7:0] == 8'h94) && mailbox_write) + check_pcr_mldsa_signing <= 1'b1; + else begin + check_pcr_ecc_signing <= 1'b0; + check_pcr_mldsa_signing <= 1'b0; + end + end + + + always@(negedge clk) begin + + if((WriteData[7:0] == 8'hf5) && mailbox_write) begin + cold_rst <= 'b1; + rst_cyclecnt <= cycleCnt; + end + else if((WriteData[7:0] == 8'hf6) && mailbox_write) begin + warm_rst <= 'b1; + rst_cyclecnt <= cycleCnt; + end + else if((WriteData[7:0] == 8'hf7) && mailbox_write) begin + timed_warm_rst <= 'b1; + end + else if((WriteData[7:0] == 8'hee) && mailbox_write) begin + `ifndef VERILATOR + std::randomize(wait_time_to_rst) with {wait_time_to_rst dist {[5:24] :/ 3, [25:99] :/ 5, [100:255] :/ 8, [256:511] :/ 5, [512:1023] :/ 1};}; + `else + wait_time_to_rst = $urandom_range(5,150); + `endif + prandom_warm_rst <= 'b1; + rst_cyclecnt <= cycleCnt; + end + + + if (cold_rst) begin + assert_hard_rst_flag <= cold_rst_done ? 'b0 : 'b1; + deassert_hard_rst_flag <= 'b0; + deassert_rst_flag <= 'b0; + + + if(cycleCnt == rst_cyclecnt + 'd10) begin + assert_hard_rst_flag <= 'b0; + deassert_hard_rst_flag <= 'b1; + cold_rst_done <= 'b1; + end + else if(cycleCnt == rst_cyclecnt + 'd20) begin + deassert_rst_flag <= 'b1; + cold_rst <= 'b0; + cold_rst_done <= 'b0; + end + else begin + deassert_hard_rst_flag <= 'b0; + deassert_rst_flag <= 'b0; + end + end + else if(warm_rst) begin + assert_rst_flag <= 'b1; + deassert_rst_flag <= 'b0; + + + if(cycleCnt == rst_cyclecnt + 'd10) begin + assert_rst_flag <= 'b0; + deassert_rst_flag <= 'b1; + warm_rst <= 'b0; + end + end + else if(timed_warm_rst) begin + if((`CPTRA_TOP_PATH.doe.doe_inst.doe_fsm1.kv_doe_fsm_ns == 'h5)) begin + assert_rst_flag <= 'b1; + deassert_rst_flag <= 'b0; + rst_cyclecnt <= cycleCnt; + end + else if(assert_rst_flag && (cycleCnt == rst_cyclecnt + 'd5)) begin + assert_rst_flag <= 0; + deassert_rst_flag <= 1; + timed_warm_rst <= 'b0; + end + end + else if(prandom_warm_rst) begin + if(cycleCnt == rst_cyclecnt + wait_time_to_rst) begin + assert_rst_flag <= 'b1; + deassert_rst_flag <= 'b0; + end + else if(assert_rst_flag && (cycleCnt >= (rst_cyclecnt + wait_time_to_rst + 10))) begin //prandom rst was already issued, so deassert rst now + assert_rst_flag <= 'b0; + deassert_rst_flag <= 'b1; + prandom_warm_rst <= 'b0; + end + end + else begin + deassert_hard_rst_flag <= 'b0; + deassert_rst_flag <= 'b0; + end + end + + always @(negedge clk or negedge cptra_rst_b) begin + if (!cptra_rst_b) begin + int_flag <= 'b0; + cycleCnt_smpl_en <= 'b0; + end + else if((WriteData[7:0] == 8'hf8) && mailbox_write) begin + int_flag <= 1'b1; + cycleCnt_smpl_en <= 'b1; + end + else cycleCnt_smpl_en <= 'b0; + end + + //WDT assist logic + always @(negedge clk or negedge cptra_rst_b) begin + if (!cptra_rst_b) begin + reset_wdt_timer_period <= 'b0; + end + else if((WriteData[7:0] == 8'hf1) && mailbox_write) begin + reset_wdt_timer_period <= 'b1; + end + end + + always @(negedge clk or negedge cptra_rst_b) begin + if(!cptra_rst_b) begin + set_wdt_timer1_period <= 'b0; + set_wdt_timer2_period <= 'b0; + end + else begin + if (!UVM_TB) begin + if(`CPTRA_TOP_PATH.soc_ifc_top1.i_wdt.wdt_timer1_timeout_serviced_qual) begin + set_wdt_timer1_period <= 'b1; + end + if(`CPTRA_TOP_PATH.soc_ifc_top1.i_wdt.wdt_timer2_timeout_serviced_qual) begin + set_wdt_timer2_period <= 'b1; + end + end + if(reset_wdt_timer_period) begin + set_wdt_timer1_period <= 'b0; + set_wdt_timer2_period <= 'b0; + end + end + end + + always @(negedge clk) begin + if(set_wdt_timer1_period) begin + force `CPTRA_TOP_PATH.soc_ifc_top1.timer1_timeout_period = 64'hFFFFFFFF_FFFFFFFF; + end + else if(reset_wdt_timer_period) begin + release `CPTRA_TOP_PATH.soc_ifc_top1.timer1_timeout_period; + end + + if(set_wdt_timer2_period) begin + force `CPTRA_TOP_PATH.soc_ifc_top1.timer2_timeout_period = 64'hFFFFFFFF_FFFFFFFF; + end + else if(reset_wdt_timer_period) begin + release `CPTRA_TOP_PATH.soc_ifc_top1.timer2_timeout_period; + end + + end + + always @(negedge clk) begin + if((WriteData[7:0] == 8'hea) && mailbox_write) begin + force `CPTRA_TOP_PATH.soc_ifc_top1.timer1_timeout_period = {32'h0000_0000, $urandom_range(32'h0000_0001,32'h0000_0FFF)}; + force `CPTRA_TOP_PATH.soc_ifc_top1.timer2_timeout_period = {32'h0000_0000, $urandom_range(32'h0000_0001,32'h0000_0FFF)}; + end + //Use 'hF1 code to reset these values in the test + end + + + `ifndef VERILATOR + initial begin + automatic bitflip_mask_generator #(CPTRA_MBOX_DATA_AND_ECC_W) bitflip_gen = new(); + forever begin + @(posedge clk) + if (~|inject_mbox_sram_error) begin + mbox_sram_wdata_bitflip <= '0; + end + else if (mbox_sram_cs & mbox_sram_we) begin + // Corrupt 10% of the writes + flip_bit = $urandom_range(0,99) < 10; + mbox_sram_wdata_bitflip <= flip_bit ? bitflip_gen.get_mask(inject_mbox_sram_error[1]) : '0; +// if (flip_bit) $display("%t Injecting bit flips", $realtime); +// else $display("%t No bit flips injected", $realtime); + end + end + end + `else + always @(posedge clk) begin + if (~|inject_mbox_sram_error) begin + flip_bit <= 0; + mbox_sram_wdata_bitflip <= '0; + end + else if (mbox_sram_cs & mbox_sram_we) begin + // Corrupt 10% of the writes + flip_bit <= ($urandom % 100) < 10; + mbox_sram_wdata_bitflip <= flip_bit ? get_bitflip_mask(inject_mbox_sram_error[1]) : '0; + end + end + `endif + + always @(negedge clk or negedge cptra_rst_b) begin + if(!cptra_rst_b) begin + prev_mailbox_data <= 'hA; // Initialize with newline character so timestamp is printed to console for the first line + end + else if(mailbox_data_val & mailbox_write) begin + prev_mailbox_data <= WriteData; + end + end + + initial cycleCnt = 0; + initial cycleCntKillReq = 0; + always @(negedge clk) begin + cycleCnt <= cycleCnt+1; + // Test timeout monitor + if(cycleCnt == MAX_CYCLES && !UVM_TB) begin + $error("Hit max cycle count (%0d) .. stopping",cycleCnt); + dump_memory_contents(MEMTYPE_LMEM, 32'h8000_0110, 32'h8000_0180); + dump_memory_contents(MEMTYPE_DCCM, `RV_DCCM_SADR, `RV_DCCM_EADR); + dump_memory_contents(MEMTYPE_ICCM, `RV_ICCM_SADR, `RV_ICCM_EADR); + $finish; + end + // console Monitor + if( mailbox_data_val & mailbox_write) begin + if (prev_mailbox_data[7:0] inside {8'h0A,8'h0D}) begin + $fwrite(fd,"%0t - ", $time); + if (!UVM_TB) $write("%0t - ", $time); + end + $fwrite(fd,"%c", WriteData[7:0]); + // Prints get lost in sim.log amidst a flurry of UVM_INFO + // messages.... best to just omit and send to console.log + if (!UVM_TB) begin + $write("%c", WriteData[7:0]); + end + if (WriteData[7:0] inside {8'h0A,8'h0D}) begin // CR/LF + $fflush(fd); + end + end + // Disable this for UVM simulations since control is delegated to + // uvm tests/sequences + // End Of test monitor + if(mailbox_write && WriteData[7:0] == 8'hff) begin + if (UVM_TB) $info("INFO: Detected FW write to manually end the test with SUCCESS; ignoring since the UVM environment will handle this."); + else if (|cycleCntKillReq) begin + $error("ERROR! FW attempted to end the simulation with SUCCESS after previously requesting to end the sim with FAILURE!"); + end + else begin + $display("* TESTCASE PASSED"); + $display("\nFinished : minstret = %0d, mcycle = %0d", `DEC.tlu.minstretl[31:0],`DEC.tlu.mcyclel[31:0]); + $display("See \"exec.log\" for execution trace with register updates..\n"); + dump_memory_contents(MEMTYPE_LMEM, MBOX_DIR_START_ADDR, MBOX_DIR_END_ADDR); + dump_memory_contents(MEMTYPE_DCCM, `RV_DCCM_SADR, `RV_DCCM_EADR); + dump_memory_contents(MEMTYPE_ICCM, `RV_ICCM_SADR, `RV_ICCM_EADR); + $finish; + end + end + else if(mailbox_write && WriteData[7:0] == 8'h1) begin + if (UVM_TB) $info("INFO: Detected FW write to manually end the test with FAIL; ignoring since the UVM environment will handle this."); + else begin + cycleCntKillReq <= cycleCnt; + $error("* TESTCASE FAILED"); + $display(" -- Extending simulation for 100 clock cycles to capture ending waveform"); + end + end + if (|cycleCntKillReq && (cycleCnt == (cycleCntKillReq + 100))) begin + $error("Dumping memory contents at simulation end due to FAILURE"); + dump_memory_contents(MEMTYPE_LMEM, MBOX_DIR_START_ADDR, MBOX_DIR_END_ADDR); + dump_memory_contents(MEMTYPE_DCCM, `RV_DCCM_SADR, `RV_DCCM_EADR); + dump_memory_contents(MEMTYPE_ICCM, `RV_ICCM_SADR, `RV_ICCM_EADR); + $finish; + end + end + + + // trace monitor + always @(posedge clk) begin + wb_valid <= `DEC.dec_i0_wen_r; + wb_dest <= `DEC.dec_i0_waddr_r; + wb_data <= `DEC.dec_i0_wdata_r; + if (`CPTRA_TOP_PATH.trace_rv_i_valid_ip && $test$plusargs("CLP_BUS_LOGS")) begin + + $fwrite(tp,"%b,%h,%h,%0h,%0h,3,%b,%h,%h,%b\n", `CPTRA_TOP_PATH.trace_rv_i_valid_ip, 0, `CPTRA_TOP_PATH.trace_rv_i_address_ip, + 0, `CPTRA_TOP_PATH.trace_rv_i_insn_ip,`CPTRA_TOP_PATH.trace_rv_i_exception_ip,`CPTRA_TOP_PATH.trace_rv_i_ecause_ip, + `CPTRA_TOP_PATH.trace_rv_i_tval_ip,`CPTRA_TOP_PATH.trace_rv_i_interrupt_ip); + // Basic trace - no exception register updates + // #1 0 ee000000 b0201073 c 0b02 00000000 + commit_count++; + $fwrite (el, "%10d : %8s 0 %h %h%13s ; %s\n", cycleCnt, $sformatf("#%0d",commit_count), + `CPTRA_TOP_PATH.trace_rv_i_address_ip, `CPTRA_TOP_PATH.trace_rv_i_insn_ip, + (wb_dest !=0 && wb_valid)? $sformatf("%s=%h", abi_reg[wb_dest], wb_data) : " ", + dasm(`CPTRA_TOP_PATH.trace_rv_i_insn_ip, `CPTRA_TOP_PATH.trace_rv_i_address_ip, wb_dest & {5{wb_valid}}, wb_data) + ); + end + if(`DEC.dec_nonblock_load_wen) begin + if ($test$plusargs("CLP_BUS_LOGS")) $fwrite (el, "%10d : %32s=%h ; nbL\n", cycleCnt, abi_reg[`DEC.dec_nonblock_load_waddr], `DEC.lsu_nonblock_load_data); + caliptra_top_tb_services.gpr[0][`DEC.dec_nonblock_load_waddr] = `DEC.lsu_nonblock_load_data; + end + if(`DEC.exu_div_wren) begin + if ($test$plusargs("CLP_BUS_LOGS")) $fwrite (el, "%10d : %32s=%h ; nbD\n", cycleCnt, abi_reg[`DEC.div_waddr_wb], `DEC.exu_div_result); + caliptra_top_tb_services.gpr[0][`DEC.div_waddr_wb] = `DEC.exu_div_result; + end + end + + // IFU Initiator monitor + always @(posedge clk) begin + if ($test$plusargs("CLP_BUS_LOGS")) + $fstrobe(ifu_p, "%10d : 0x%0h %h %b %h %h %h %b 0x%08h_%08h %b %b\n", cycleCnt, + `CPTRA_TOP_PATH.ic_haddr, `CPTRA_TOP_PATH.ic_hburst, `CPTRA_TOP_PATH.ic_hmastlock, + `CPTRA_TOP_PATH.ic_hprot, `CPTRA_TOP_PATH.ic_hsize, `CPTRA_TOP_PATH.ic_htrans, + `CPTRA_TOP_PATH.ic_hwrite, `CPTRA_TOP_PATH.ic_hrdata[63:32], `CPTRA_TOP_PATH.ic_hrdata[31:0], + `CPTRA_TOP_PATH.ic_hready, `CPTRA_TOP_PATH.ic_hresp); + end + + // LSU Initiator monitor + always @(posedge clk) begin + if ($test$plusargs("CLP_BUS_LOGS")) + $fstrobe(lsu_p, "%10d : 0x%0h %h %h %b 0x%08h_%08h 0x%08h_%08h %b %b\n", cycleCnt, + `CPTRA_TOP_PATH.initiator_inst.haddr, `CPTRA_TOP_PATH.initiator_inst.hsize, `CPTRA_TOP_PATH.initiator_inst.htrans, + `CPTRA_TOP_PATH.initiator_inst.hwrite, `CPTRA_TOP_PATH.initiator_inst.hrdata[63:32], `CPTRA_TOP_PATH.initiator_inst.hrdata[31:0], + `CPTRA_TOP_PATH.initiator_inst.hwdata[63:32], `CPTRA_TOP_PATH.initiator_inst.hwdata[31:0], + `CPTRA_TOP_PATH.initiator_inst.hready, `CPTRA_TOP_PATH.initiator_inst.hresp); + end + + // AHB responder interfaces monitor + genvar sl_i; + generate + for (sl_i = 0; sl_i < `CALIPTRA_AHB_SLAVES_NUM; sl_i = sl_i + 1) begin: gen_responder_inf_monitor + always @(posedge clk) begin + if ($test$plusargs("CLP_BUS_LOGS")) + $fstrobe(sl_p[sl_i], "%10d : 0x%0h %h %h %b 0x%08h_%08h 0x%08h_%08h %b %b %b %b\n", cycleCnt, + `CPTRA_TOP_PATH.responder_inst[sl_i].haddr, `CPTRA_TOP_PATH.responder_inst[sl_i].hsize, `CPTRA_TOP_PATH.responder_inst[sl_i].htrans, + `CPTRA_TOP_PATH.responder_inst[sl_i].hwrite, `CPTRA_TOP_PATH.responder_inst[sl_i].hrdata[63:32], `CPTRA_TOP_PATH.responder_inst[sl_i].hrdata[31:0], + `CPTRA_TOP_PATH.responder_inst[sl_i].hwdata[63:32], `CPTRA_TOP_PATH.responder_inst[sl_i].hwdata[31:0], + `CPTRA_TOP_PATH.responder_inst[sl_i].hready, `CPTRA_TOP_PATH.responder_inst[sl_i].hreadyout, `CPTRA_TOP_PATH.responder_inst[sl_i].hresp, `CPTRA_TOP_PATH.responder_inst[sl_i].hsel); + end + end + endgenerate + + logic preload_dccm_done; + + initial begin + abi_reg[0] = "zero"; + abi_reg[1] = "ra"; + abi_reg[2] = "sp"; + abi_reg[3] = "gp"; + abi_reg[4] = "tp"; + abi_reg[5] = "t0"; + abi_reg[6] = "t1"; + abi_reg[7] = "t2"; + abi_reg[8] = "s0"; + abi_reg[9] = "s1"; + abi_reg[10] = "a0"; + abi_reg[11] = "a1"; + abi_reg[12] = "a2"; + abi_reg[13] = "a3"; + abi_reg[14] = "a4"; + abi_reg[15] = "a5"; + abi_reg[16] = "a6"; + abi_reg[17] = "a7"; + abi_reg[18] = "s2"; + abi_reg[19] = "s3"; + abi_reg[20] = "s4"; + abi_reg[21] = "s5"; + abi_reg[22] = "s6"; + abi_reg[23] = "s7"; + abi_reg[24] = "s8"; + abi_reg[25] = "s9"; + abi_reg[26] = "s10"; + abi_reg[27] = "s11"; + abi_reg[28] = "t3"; + abi_reg[29] = "t4"; + abi_reg[30] = "t5"; + abi_reg[31] = "t6"; + + //generate_memory_hex_file(AXI_SRAM_BASE_ADDR, 65536, getenv("PLAYBOOK_RANDOM_SEED")); + + `ifndef VERILATOR + imem_inst1.ram = '{default:8'h0}; + dummy_mbox_preloader.ram = '{default:8'h0}; + dummy_iccm_preloader.ram = '{default:8'h0}; + dummy_dccm_preloader.ram = '{default:8'h0}; + `endif + hex_file_is_empty = $system("test -s program.hex"); + if (!hex_file_is_empty) $readmemh("program.hex", imem_inst1.ram,0,`CALIPTRA_IMEM_BYTE_SIZE-1); + hex_file_is_empty = $system("test -s mailbox.hex"); + if (!hex_file_is_empty) $readmemh("mailbox.hex", dummy_mbox_preloader.ram,0,MBOX_DIR_MEM_SIZE-1); + hex_file_is_empty = $system("test -s dccm.hex"); + if (!hex_file_is_empty) $readmemh("dccm.hex", dummy_dccm_preloader.ram,0,`RV_DCCM_EADR - `RV_DCCM_SADR); + hex_file_is_empty = $system("test -s iccm.hex"); + if (!hex_file_is_empty) $readmemh("iccm.hex", dummy_iccm_preloader.ram,0,`RV_ICCM_EADR - `RV_ICCM_SADR); + + begin + int unsigned iterations; + if ($value$plusargs("iterations=%d", iterations)) begin + $display("Iterations: %0d", iterations); + { + dummy_dccm_preloader.ram['h30000 >> 3][3], + dummy_dccm_preloader.ram['h30000 >> 3][2], + dummy_dccm_preloader.ram['h30000 >> 3][1], + dummy_dccm_preloader.ram['h30000 >> 3][0] + } = iterations; + end + end + + `ifdef CALIPTRA_TOP_TB + $display("Initializing AXI SRAM with random data"); + if ($test$plusargs("CPTRA_RAND_TEST_DMA")) begin + initialize_caliptra_axi_sram(); + end + `endif + + if ($test$plusargs("CLP_BUS_LOGS")) begin + tp = $fopen("trace_port.csv","w"); + el = $fopen("exec.log","w"); + ifu_p = $fopen("ifu_master_ahb_trace.log", "w"); + lsu_p = $fopen("lsu_master_ahb_trace.log", "w"); + end + if ($test$plusargs("CLP_BUS_LOGS")) begin + $fwrite (el, "// Cycle : #inst 0 pc opcode reg=value ; mnemonic\n"); + $fwrite(ifu_p, "// Cycle: ic_haddr ic_hburst ic_hmastlock ic_hprot ic_hsize ic_htrans ic_hwrite ic_hrdata ic_hwdata ic_hready ic_hresp\n"); + $fwrite(lsu_p, "// Cycle: lsu_haddr lsu_hsize lsu_htrans lsu_hwrite lsu_hrdata lsu_hwdata lsu_hready lsu_hresp\n"); + + for (j = 0; j < `CALIPTRA_AHB_SLAVES_NUM; j = j + 1) begin + slaveLog_fileName[j] = {$sformatf("slave%0d_ahb_trace.log", j)}; + sl_p[j] = $fopen(slaveLog_fileName[j], "w"); + $fwrite(sl_p[j], "// Cycle: haddr hsize htrans hwrite hrdata hwdata hready hreadyout hresp\n"); + end + end + + fd = $fopen("console.log","w"); + commit_count = 0; + preload_dccm(); + preload_iccm(); + preload_mbox(); + + assert_hard_rst_flag = 0; + deassert_hard_rst_flag = 0; + assert_rst_flag = 0; + deassert_rst_flag = 0; + + cold_rst = 0; + warm_rst = 0; + timed_warm_rst = 0; + cold_rst_done = 0; + prandom_warm_rst = 0; + + scan_mode = 0; + wait_time_to_rst = 0; + + set_wdt_timer1_period = 0; + assert_ss_tran = 0; + en_jtag_access = 0; + + `ifndef VERILATOR + if (!UVM_TB) begin + ecc_testvector_generator(); + doe_testvector_generator(); + sha256_wntz_testvector_generator(); + mldsa_input_hex_gen(); + mlkem_testvector_generator(); + + //Note: Both obf_key_uds and obf_key_fe are the same + //for(int dword = 0; dword < `CLP_OBF_KEY_DWORDS; dword++) begin + // cptra_obf_key_tb[dword] = doe_test_vector.obf_key_uds[(`CLP_OBF_KEY_DWORDS-1)-dword]; + //end + cptra_obf_key_tb = doe_test_vector.obf_key_uds; + for(int dword = 0; dword < `CLP_OBF_UDS_DWORDS; dword++) begin + cptra_uds_tb[dword] = doe_test_vector.uds_ciphertext[dword]; + end + for(int dword = 0; dword < `CLP_OBF_FE_DWORDS; dword++) begin + cptra_fe_tb[dword] = doe_test_vector.fe_ciphertext[dword]; + end + for(int dword = 0; dword < OCP_LOCK_HEK_NUM_DWORDS; dword++) begin + cptra_hek_tb[dword] = doe_test_vector.hek_ciphertext[dword]; + end + end + `endif + end + + //=========================================================================- + // SRAM instances + //=========================================================================- + // SRAM module +abr_mem_top abr_mem_top_inst ( + .clk_i(clk), + .abr_memory_export +); + +caliptra_veer_sram_export veer_sram_export_inst ( + .sram_error_injection_mode(sram_error_injection_mode), + .el2_mem_export(el2_mem_export) +); + +//SRAM for mbox (preload raw data here) +caliptra_sram +#( + .DATA_WIDTH(CPTRA_MBOX_DATA_W), + .DEPTH (CPTRA_MBOX_DEPTH ) +) +dummy_mbox_preloader +( + .clk_i(clk), + + .cs_i (), + .we_i (), + .addr_i (), + .wdata_i(), + .rdata_o() +); +// Actual Mailbox RAM -- preloaded with data from +// dummy_mbox_preloader with ECC bits appended +caliptra_sram +#( + .DATA_WIDTH(CPTRA_MBOX_DATA_AND_ECC_W), + .DEPTH (CPTRA_MBOX_DEPTH ) +) +mbox_ram1 +( + .clk_i(clk), + + .cs_i(mbox_sram_cs), + .we_i(mbox_sram_we), + .addr_i(mbox_sram_addr), + .wdata_i(mbox_sram_wdata ^ mbox_sram_wdata_bitflip), + + .rdata_o(mbox_sram_rdata) +); + +//SRAM for imem +caliptra_sram #( + .DEPTH (`CALIPTRA_IMEM_DEPTH ), // Depth in WORDS + .DATA_WIDTH(`CALIPTRA_IMEM_DATA_WIDTH), + .ADDR_WIDTH(`CALIPTRA_IMEM_ADDR_WIDTH) +) imem_inst1 ( + .clk_i (clk ), + + .cs_i (imem_cs), + .we_i (1'b0/*sram_write && sram_dv*/ ), + .addr_i (imem_addr ), + .wdata_i (`CALIPTRA_IMEM_DATA_WIDTH'(0)/*sram_wdata */), + .rdata_o (imem_rdata ) +); + +// This is used to load the generated ICCM hexfile prior to +// running slam_iccm_ram +caliptra_sram #( + .DEPTH (ICCM_PRELOADER_DEPTH ), + .DATA_WIDTH(ICCM_PRELOADER_WIDTH ), + .ADDR_WIDTH(ICCM_PRELOADER_ADDR_WIDTH) + +) dummy_iccm_preloader ( + .clk_i (clk), + + .cs_i ( ), + .we_i ( ), + .addr_i ( ), + .wdata_i ( ), + .rdata_o ( ) +); + + +// This is used to load the generated DCCM hexfile prior to +// running slam_dccm_ram +caliptra_sram #( + .DEPTH (DCCM_PRELOADER_DEPTH ), + .DATA_WIDTH(DCCM_PRELOADER_WIDTH ), + .ADDR_WIDTH(DCCM_PRELOADER_ADDR_WIDTH) + +) dummy_dccm_preloader ( + .clk_i (clk), + + .cs_i ( ), + .we_i ( ), + .addr_i ( ), + .wdata_i ( ), + .rdata_o ( ) +); + +// DMA Test case generator +// Interface instance +//dma_transfer_if dma_xfer_if; + +`ifndef VERILATOR +// Testcase generator instance +dma_transfer_randomizer dma_xfers[]; + +dma_testcase_generator i_dma_gen ( + .preload_dccm_done (preload_dccm_done ), + .dma_gen_done (axi_complex_ctrl.dma_gen_done ), + .dma_gen_block_size(axi_complex_ctrl.dma_gen_block_size) + ); +/* +initial begin + // Wait for the test cases to be generated + wait (dma_gen_done); + + // Retrieve the generated test cases + i_dma_gen.get_dma_xfers(dma_xfers); +end +*/ +`else + always@(posedge clk) axi_complex_ctrl.dma_gen_done <= 1'b0; + always@(posedge clk) axi_complex_ctrl.dma_gen_block_size <= '0; +`endif + + //=========================================================================- + // SRAM preload services + //=========================================================================- +task static preload_mbox; + // Variables + cptra_mbox_sram_data_t ecc_data; + bit [CPTRA_MBOX_ADDR_W:0] addr; + int byt; + localparam NUM_BYTES = CPTRA_MBOX_DATA_AND_ECC_W / 8 + ((CPTRA_MBOX_DATA_AND_ECC_W%8) ? 1 : 0); + + // Init + `ifndef VERILATOR + mbox_ram1.ram = '{default:8'h0}; + `endif + + // Slam + $display("MBOX pre-load from %h to %h", 0, CPTRA_MBOX_DEPTH); + + for (addr = 0; addr < CPTRA_MBOX_DEPTH; addr++) begin + ecc_data.data = {dummy_mbox_preloader.ram[addr][3], + dummy_mbox_preloader.ram[addr][2], + dummy_mbox_preloader.ram[addr][1], + dummy_mbox_preloader.ram[addr][0]}; + ecc_data.ecc = |ecc_data.data ? riscv_ecc32(ecc_data.data) : 0; + for (byt = 0; byt < NUM_BYTES; byt++) begin + mbox_ram1.ram[addr][byt] = ecc_data[byt*8+:8]; + end + end + $display("MBOX pre-load completed"); +endtask + +task static preload_iccm; + bit[31:0] data; + bit[31:0] addr, eaddr, saddr; + + `ifndef VERILATOR + init_iccm(); + `endif + saddr = `RV_ICCM_SADR; + if ( (saddr < `RV_ICCM_SADR) || (saddr > `RV_ICCM_EADR)) return; + `ifndef RV_ICCM_ENABLE + $display("********************************************************"); + $display("ICCM preload: there is no ICCM in VeeR, terminating !!!"); + $display("********************************************************"); + $finish; + `endif + eaddr = `RV_ICCM_EADR; + $display("ICCM pre-load from %h to %h", saddr, eaddr); + + for(addr= saddr; addr <= eaddr; addr+=4) begin + // FIXME hardcoded address indices? + data = {dummy_iccm_preloader.ram [addr[`RV_ICCM_BITS-1:3]] [{addr[2],2'h3}], + dummy_iccm_preloader.ram [addr[`RV_ICCM_BITS-1:3]] [{addr[2],2'h2}], + dummy_iccm_preloader.ram [addr[`RV_ICCM_BITS-1:3]] [{addr[2],2'h1}], + dummy_iccm_preloader.ram [addr[`RV_ICCM_BITS-1:3]] [{addr[2],2'h0}]}; + //data = {`CPTRA_TOP_PATH.imem.mem[addr+3],`CPTRA_TOP_PATH.imem.mem[addr+2],`CPTRA_TOP_PATH.imem.mem[addr+1],`CPTRA_TOP_PATH.imem.mem[addr]}; + slam_iccm_ram(addr, data == 0 ? 0 : {riscv_ecc32(data),data}); + end + $display("ICCM pre-load completed"); + +endtask + + +task static preload_dccm (); + bit[31:0] data; + bit[31:0] addr, saddr, eaddr; + + `ifndef VERILATOR + init_dccm(); + `endif + saddr = `RV_DCCM_SADR; + if (saddr < `RV_DCCM_SADR || saddr > `RV_DCCM_EADR) return; + `ifndef RV_DCCM_ENABLE + $display("********************************************************"); + $display("DCCM preload: there is no DCCM in VeeR, terminating !!!"); + $display("********************************************************"); + $finish; + `endif + eaddr = `RV_DCCM_EADR; + $display("DCCM pre-load from %h to %h", saddr, eaddr); + + for(addr=saddr; addr <= eaddr; addr+=4) begin + // FIXME hardcoded address indices? + data = {dummy_dccm_preloader.ram [addr[`RV_DCCM_BITS:3]] [{addr[2],2'h3}], + dummy_dccm_preloader.ram [addr[`RV_DCCM_BITS:3]] [{addr[2],2'h2}], + dummy_dccm_preloader.ram [addr[`RV_DCCM_BITS:3]] [{addr[2],2'h1}], + dummy_dccm_preloader.ram [addr[`RV_DCCM_BITS:3]] [{addr[2],2'h0}]}; + slam_dccm_ram(addr, data == 0 ? 0 : {riscv_ecc32(data),data}); + end + $display("DCCM pre-load completed"); + preload_dccm_done = 1; + +endtask + + + +`define ICCM_PATH veer_sram_export_inst.Gen_iccm_enable +`ifdef VERILATOR +`define DRAM(bk) veer_sram_export_inst.Gen_dccm_enable.dccm_loop[bk].ram.ram_core +`define IRAM(bk) `ICCM_PATH.iccm_loop[bk].iccm_bank.ram_core +`else +`define DRAM(bk) veer_sram_export_inst.Gen_dccm_enable.dccm_loop[bk].dccm.dccm_bank.ram_core +`define IRAM(bk) `ICCM_PATH.iccm_loop[bk].iccm.iccm_bank.ram_core +`endif + + +task static slam_dccm_ram(input [31:0] addr, input[38:0] data); + int bank, indx; + bank = get_dccm_bank(addr, indx); + `ifdef RV_DCCM_ENABLE + case(bank) + 0: `DRAM(0)[indx] = data; + 1: `DRAM(1)[indx] = data; + `ifdef RV_DCCM_NUM_BANKS_4 + 2: `DRAM(2)[indx] = data; + 3: `DRAM(3)[indx] = data; + `endif + `ifdef RV_DCCM_NUM_BANKS_8 + 2: `DRAM(2)[indx] = data; + 3: `DRAM(3)[indx] = data; + 4: `DRAM(4)[indx] = data; + 5: `DRAM(5)[indx] = data; + 6: `DRAM(6)[indx] = data; + 7: `DRAM(7)[indx] = data; + `endif + endcase + `endif + //$display("Writing bank %0d indx=%0d A=%h, D=%h",bank, indx, addr, data); +endtask + + +task static slam_iccm_ram( input[31:0] addr, input[38:0] data); + int bank, idx; + + bank = get_iccm_bank(addr, idx); + `ifdef RV_ICCM_ENABLE + case(bank) // { + 0: `IRAM(0)[idx] = data; + 1: `IRAM(1)[idx] = data; + `ifdef RV_ICCM_NUM_BANKS_4 + 2: `IRAM(2)[idx] = data; + 3: `IRAM(3)[idx] = data; + `endif + `ifdef RV_ICCM_NUM_BANKS_8 + 2: `IRAM(2)[idx] = data; + 3: `IRAM(3)[idx] = data; + 4: `IRAM(4)[idx] = data; + 5: `IRAM(5)[idx] = data; + 6: `IRAM(6)[idx] = data; + 7: `IRAM(7)[idx] = data; + `endif + + `ifdef RV_ICCM_NUM_BANKS_16 + 2: `IRAM(2)[idx] = data; + 3: `IRAM(3)[idx] = data; + 4: `IRAM(4)[idx] = data; + 5: `IRAM(5)[idx] = data; + 6: `IRAM(6)[idx] = data; + 7: `IRAM(7)[idx] = data; + 8: `IRAM(8)[idx] = data; + 9: `IRAM(9)[idx] = data; + 10: `IRAM(10)[idx] = data; + 11: `IRAM(11)[idx] = data; + 12: `IRAM(12)[idx] = data; + 13: `IRAM(13)[idx] = data; + 14: `IRAM(14)[idx] = data; + 15: `IRAM(15)[idx] = data; + `endif + endcase // } + `endif +endtask + +task static init_iccm; + `ifdef RV_ICCM_ENABLE + `IRAM(0) = '{default:39'h0}; + `IRAM(1) = '{default:39'h0}; + `ifdef RV_ICCM_NUM_BANKS_4 + `IRAM(2) = '{default:39'h0}; + `IRAM(3) = '{default:39'h0}; + `endif + `ifdef RV_ICCM_NUM_BANKS_8 + `IRAM(4) = '{default:39'h0}; + `IRAM(5) = '{default:39'h0}; + `IRAM(6) = '{default:39'h0}; + `IRAM(7) = '{default:39'h0}; + `endif + + `ifdef RV_ICCM_NUM_BANKS_16 + `IRAM(4) = '{default:39'h0}; + `IRAM(5) = '{default:39'h0}; + `IRAM(6) = '{default:39'h0}; + `IRAM(7) = '{default:39'h0}; + `IRAM(8) = '{default:39'h0}; + `IRAM(9) = '{default:39'h0}; + `IRAM(10) = '{default:39'h0}; + `IRAM(11) = '{default:39'h0}; + `IRAM(12) = '{default:39'h0}; + `IRAM(13) = '{default:39'h0}; + `IRAM(14) = '{default:39'h0}; + `IRAM(15) = '{default:39'h0}; + `endif + `endif +endtask + +task static init_dccm; + `ifdef RV_DCCM_ENABLE + `DRAM(0) = '{default:39'h0}; + `DRAM(1) = '{default:39'h0}; + `ifdef RV_DCCM_NUM_BANKS_4 + `DRAM(2) = '{default:39'h0}; + `DRAM(3) = '{default:39'h0}; + `endif + `ifdef RV_DCCM_NUM_BANKS_8 + `DRAM(4) = '{default:39'h0}; + `DRAM(5) = '{default:39'h0}; + `DRAM(6) = '{default:39'h0}; + `DRAM(7) = '{default:39'h0}; + `endif + `endif +endtask + +task static dump_memory_contents; + input [2:0] mem_type; + input [31:0] start_addr; + input [31:0] end_addr; + + bit [31:0] addr; + bit [38:0] ecc_data; + bit [7:0] data; + string outfile; + + int bank, indx; + + int of; + + //$display(`DRAM); + + case (mem_type) + MEMTYPE_LMEM: outfile = "lmem_data_dump.hex"; + MEMTYPE_DCCM: outfile = "dccm_data_dump.hex"; + MEMTYPE_ICCM: outfile = "iccm_data_dump.hex"; + default: outfile = ""; + endcase + + of = $fopen(outfile, "w"); + for (addr = start_addr; addr <= start_addr + 112; addr = addr + 1) begin + case (mem_type) + MEMTYPE_LMEM: data = `LMEM[addr[31:2]][addr[1:0]]; + MEMTYPE_DCCM: begin + bank = get_dccm_bank(addr, indx); + `ifdef RV_DCCM_ENABLE + case(bank) + 0: ecc_data = `DRAM(0)[indx]; + 1: ecc_data = `DRAM(1)[indx]; + `ifdef RV_DCCM_NUM_BANKS_4 + 2: ecc_data = `DRAM(2)[indx]; + 3: ecc_data = `DRAM(3)[indx]; + `endif + `ifdef RV_DCCM_NUM_BANKS_8 + 2: ecc_data = `DRAM(2)[indx]; + 3: ecc_data = `DRAM(3)[indx]; + 4: ecc_data = `DRAM(4)[indx]; + 5: ecc_data = `DRAM(5)[indx]; + 6: ecc_data = `DRAM(6)[indx]; + 7: ecc_data = `DRAM(7)[indx]; + `endif + endcase + `endif + end + MEMTYPE_ICCM: begin + bank = get_iccm_bank(addr, indx); + `ifdef RV_ICCM_ENABLE + case(bank) // { + 0: ecc_data = `IRAM(0)[indx]; + 1: ecc_data = `IRAM(1)[indx]; + `ifdef RV_ICCM_NUM_BANKS_4 + 2: ecc_data = `IRAM(2)[indx]; + 3: ecc_data = `IRAM(3)[indx]; + `endif + `ifdef RV_ICCM_NUM_BANKS_8 + 2: ecc_data = `IRAM(2)[indx]; + 3: ecc_data = `IRAM(3)[indx]; + 4: ecc_data = `IRAM(4)[indx]; + 5: ecc_data = `IRAM(5)[indx]; + 6: ecc_data = `IRAM(6)[indx]; + 7: ecc_data = `IRAM(7)[indx]; + `endif + `ifdef RV_ICCM_NUM_BANKS_16 + 2: ecc_data = `IRAM(2)[indx]; + 3: ecc_data = `IRAM(3)[indx]; + 4: ecc_data = `IRAM(4)[indx]; + 5: ecc_data = `IRAM(5)[indx]; + 6: ecc_data = `IRAM(6)[indx]; + 7: ecc_data = `IRAM(7)[indx]; + 8: ecc_data = `IRAM(8)[indx]; + 9: ecc_data = `IRAM(9)[indx]; + 10: ecc_data = `IRAM(10)[indx]; + 11: ecc_data = `IRAM(11)[indx]; + 12: ecc_data = `IRAM(12)[indx]; + 13: ecc_data = `IRAM(13)[indx]; + 14: ecc_data = `IRAM(14)[indx]; + 15: ecc_data = `IRAM(15)[indx]; + `endif + endcase // } + `endif + end + default: begin + data = 0; + bank = 0; + ecc_data = 0; + end + endcase + + case (mem_type) + MEMTYPE_LMEM: begin + if ((addr & 'hF) == 0) begin + $fwrite(of, "%0x:\t%x ", addr, data); + end + else if ((addr & 'hF) == 'hF) begin + $fwrite(of, "%x\n", data); + end + else begin + $fwrite(of, "%x ", data); + end + end + MEMTYPE_DCCM, + MEMTYPE_ICCM: begin + if ((addr & 'hF) == 0) begin + $fwrite(of, "%0x:\t%x ", addr, ecc_data); + end + else if ((addr & 'hF) == 'hC) begin + $fwrite(of, "%x\n", ecc_data); + end + else if (((addr & 'hF) == 'h4)|| ((addr & 'hF) == 'h8)) begin + $fwrite(of, "%x ", ecc_data); + end + end + default: begin end + endcase + end +endtask + +`ifdef CALIPTRA_TOP_TB +// Initialize AXI SRAM with random data +task initialize_caliptra_axi_sram; + + integer addr, byte_idx; + reg [7:0] random_byte; + + begin + + if (!UVM_TB) begin + + $display("Starting Caliptra SRAM initialization with random data (64K addresses, 4 bytes per address)..."); + + // Loop through all addresses (64K) and all bytes per address (4 for 32-bit data) + for (addr = 0; addr < AXI_SRAM_DEPTH; addr = addr + 1) begin + // For each address, initialize all bytes + for (byte_idx = 0; byte_idx < 4; byte_idx = byte_idx + 1) begin + random_byte = $random & 8'hFF; // Generate random byte (8 bits) + + // Direct assignment + `CALIPTRA_TOP.tb_axi_complex_i.i_axi_sram.i_sram.ram[addr][byte_idx] = random_byte; + end + + // Progress reporting every 12.5% (8192 addresses) + if (addr % (AXI_SRAM_DEPTH/8) == 0) begin + $display(" SRAM initialization progress: %0d%% (addr: 0x%x)", (addr * 100) / AXI_SRAM_DEPTH, addr); + end + end + + $display("Caliptra SRAM initialization complete!"); + end + end +endtask +`endif + + +function[6:0] riscv_ecc32(input[31:0] data); + reg[6:0] synd; + synd[0] = ^(data & 32'h56aa_ad5b); + synd[1] = ^(data & 32'h9b33_366d); + synd[2] = ^(data & 32'he3c3_c78e); + synd[3] = ^(data & 32'h03fc_07f0); + synd[3] = ^(data & 32'h03fc_07f0); + synd[4] = ^(data & 32'h03ff_f800); + synd[5] = ^(data & 32'hfc00_0000); + synd[6] = ^{data, synd[5:0]}; + return synd; +endfunction + +function int get_dccm_bank(input[31:0] addr, output int bank_idx); + `ifdef RV_DCCM_NUM_BANKS_2 + bank_idx = int'(addr[`RV_DCCM_BITS-1:3]); + return int'( addr[2]); + `elsif RV_DCCM_NUM_BANKS_4 + bank_idx = int'(addr[`RV_DCCM_BITS-1:4]); + return int'(addr[3:2]); + `elsif RV_DCCM_NUM_BANKS_8 + bank_idx = int'(addr[`RV_DCCM_BITS-1:5]); + return int'( addr[4:2]); + `endif +endfunction + +function int get_iccm_bank(input[31:0] addr, output int bank_idx); + `ifdef RV_DCCM_NUM_BANKS_2 + bank_idx = int'(addr[`RV_DCCM_BITS-1:3]); + return int'( addr[2]); + `elsif RV_ICCM_NUM_BANKS_4 + bank_idx = int'(addr[`RV_ICCM_BITS-1:4]); + return int'(addr[3:2]); + `elsif RV_ICCM_NUM_BANKS_8 + bank_idx = int'(addr[`RV_ICCM_BITS-1:5]); + return int'( addr[4:2]); + `elsif RV_ICCM_NUM_BANKS_16 + bank_idx = int'(addr[`RV_ICCM_BITS-1:6]); + return int'( addr[5:2]); + `endif +endfunction + +function void write_file(int fd, int bit_length_words, bit [31:0] array []); +int i; +int words_to_write; + +// Write the data from the array to the file +words_to_write = bit_length_words; +for (i = 0; i < words_to_write; i++) begin + $fwrite(fd, "%02X%02X%02X%02X", array[i][7:0], array[i][15:8], + array[i][23:16],array[i][31:24]); +end +$fwrite(fd, "\n"); + +endfunction + +function void read_line(int fd, int bit_length_words, ref bit [31:0] array []); +string line; +int words_read; +bit [31:0] word; +bit [31:0] reversed_word; + +// Read the data from the file line by line +words_read = 0; +while (!$feof(fd) && words_read < bit_length_words) begin + line = ""; + void'($fgets(line, fd)); // Read a line from the file + while ($sscanf(line, "%08x", word) == 1) begin + reversed_word = {word[7:0], word[15:8], word[23:16], word[31:24]}; + array[words_read] = reversed_word; + words_read++; + // Remove the parsed part from the line + line = line.substr(8, line.len() - 1); + end +end +endfunction + +`ifndef VERILATOR +soc_ifc_cov_bind i_soc_ifc_cov_bind(); +caliptra_top_cov_bind i_caliptra_top_cov_bind(); +sha512_ctrl_cov_bind i_sha512_ctrl_cov_bind(); +sha256_ctrl_cov_bind i_sha256_ctrl_cov_bind(); +hmac_ctrl_cov_bind i_hmac_ctrl_cov_bind(); +hmac_drbg_cov_bind i_hmac_drbg_cov_bind(); +ecc_top_cov_bind i_ecc_top_cov_bind(); +clp_abr_top_cov_bind i_clp_abr_top_cov_bind(); +keyvault_cov_bind i_keyvault_cov_bind(); +pcrvault_cov_bind i_pcrvault_cov_bind(); +axi_dma_top_cov_bind i_axi_dma_top_cov_bind(); +aes_cov_bind i_aes_cov_bind(); +doe_cov_bind i_doe_cov_bind(); +`endif + +/* verilator lint_off CASEINCOMPLETE */ +`include "dasm.svi" +/* verilator lint_on CASEINCOMPLETE */ + + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_top_tb_soc_bfm.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_top_tb_soc_bfm.sv new file mode 100644 index 0000000..7962c76 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_top_tb_soc_bfm.sv @@ -0,0 +1,700 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +// + +`include "common_defines.sv" +`include "config_defines.svh" +`include "caliptra_reg_defines.svh" +`include "caliptra_reg_field_defines.svh" +`include "caliptra_macros.svh" + +module caliptra_top_tb_soc_bfm +import axi_pkg::*; +import soc_ifc_pkg::*; +import mbox_pkg::*; +import kv_defines_pkg::*; +import caliptra_top_tb_pkg::*; #( + parameter SKIP_BRINGUP = 0 +) ( + input logic core_clk, + output logic cptra_pwrgood, + output logic cptra_rst_b, + output logic BootFSM_BrkPoint, + input int cycleCnt, + + output logic [`CLP_OBF_KEY_DWORDS-1:0][31:0] cptra_obf_key, + output logic [`CLP_CSR_HMAC_KEY_DWORDS-1:0][31:0] cptra_csr_hmac_key, + + input logic [0:`CLP_OBF_UDS_DWORDS-1][31:0] cptra_uds_rand, + input logic [0:`CLP_OBF_FE_DWORDS-1] [31:0] cptra_fe_rand, + input logic [0:OCP_LOCK_HEK_NUM_DWORDS-1] [31:0] cptra_hek_rand, + input logic [0:`CLP_OBF_KEY_DWORDS-1][31:0] cptra_obf_key_tb, + + axi_if m_axi_bfm_if, + + output logic [15:0] strap_ss_key_release_key_size, + output logic [63:0] strap_ss_key_release_base_addr, + + output logic ss_ocp_lock_en, + + input logic ready_for_fuses, + input logic ready_for_mb_processing, + input logic mailbox_data_avail, + + input var ras_test_ctrl_t ras_test_ctrl, + + output logic [63:0] generic_input_wires, + + input logic cptra_error_fatal, + input logic cptra_error_non_fatal, + + //Interrupt flags + input logic int_flag, + input logic cycleCnt_smpl_en, + + input logic assert_hard_rst_flag, + input logic deassert_hard_rst_flag, + input logic assert_rst_flag_from_service, + input logic deassert_rst_flag_from_service + +); + localparam FW_NUM_DWORDS = 256; + + int poll_count; + + logic [0:`CLP_OBF_KEY_DWORDS-1][31:0] cptra_obfkey_tb; + + logic [0:`CLP_OBF_UDS_DWORDS-1][31:0] cptra_uds_tb; + logic [0:`CLP_OBF_FE_DWORDS-1][31:0] cptra_fe_tb; + logic [0:OCP_LOCK_HEK_NUM_DWORDS-1] [31:0] cptra_hek_tb; + + // AXI request signals + axi_resp_e wresp, rresp; + logic [`CALIPTRA_AXI_DATA_WIDTH -1:0] wdata, rdata; + logic [`CALIPTRA_AXI_DATA_WIDTH/8-1:0] wstrb_array[]; + logic [`CALIPTRA_AXI_USER_WIDTH -1:0] wuser_array[]; + logic [`CALIPTRA_AXI_USER_WIDTH -1:0] buser; + logic [`CALIPTRA_AXI_DATA_WIDTH -1:0] rdata_array[]; + logic [`CALIPTRA_AXI_USER_WIDTH -1:0] ruser_array[]; + axi_resp_e rresp_array[]; + + int byte_count; + int dw_count; + + logic [15:0] cptra_error_fatal_counter; + logic [15:0] cptra_error_non_fatal_counter; + logic cptra_error_fatal_dly_p; + logic cptra_error_non_fatal_dly_p; + + logic rv_dma_resp_error; + + logic [`CALIPTRA_AXI_DATA_WIDTH-1:0] soc_ifc_hw_error_wdata; + + process boot_and_cmd_flow; + + logic assert_rst_flag_from_fatal; + logic assert_rst_flag; + int count_deassert_rst_flag_from_fatal; + logic deassert_rst_flag_from_fatal; + logic deassert_rst_flag; + + logic [31:0] fw_blob []; + + always@(negedge core_clk or negedge cptra_rst_b) begin + if (!cptra_rst_b) begin + cptra_error_fatal_counter <= 16'h0; + cptra_error_non_fatal_counter <= 16'h0; + end + else begin + cptra_error_fatal_counter <= cptra_error_fatal ? (cptra_error_fatal_counter + 16'h1) : 16'h0; + cptra_error_non_fatal_counter <= cptra_error_non_fatal ? (cptra_error_non_fatal_counter + 16'h1) : 16'h0; + end + end + // Pulse fires about 640ns after the original error interrupt occurs + always_comb cptra_error_fatal_dly_p = cptra_error_fatal_counter == 16'h0040; + always_comb cptra_error_non_fatal_dly_p = cptra_error_non_fatal_counter == 16'h0040; + + always@(negedge core_clk) begin + if (!cptra_pwrgood) begin + count_deassert_rst_flag_from_fatal <= 0; + end + // Start counting after the fatal flag asserts reset, and continue + // counting until the reset is deasserted + else if (assert_rst_flag_from_fatal || (!cptra_rst_b && |count_deassert_rst_flag_from_fatal)) begin + count_deassert_rst_flag_from_fatal <= count_deassert_rst_flag_from_fatal + 1; + end + else begin + count_deassert_rst_flag_from_fatal <= 0; + end + end + // Leave reset asserted for 32 clock cycles + always_comb deassert_rst_flag_from_fatal = count_deassert_rst_flag_from_fatal == 31; + + initial begin + // Initialize strap_ss_key_release_key_size based on plusargs + if ($test$plusargs("STRAP_SS_KEY_RELEASE_KEY_SIZE_MANUAL")) begin + if (!$value$plusargs("STRAP_SS_KEY_RELEASE_KEY_SIZE_MANUAL=%h", strap_ss_key_release_key_size)) begin + $error("Failed to get value for +STRAP_SS_KEY_RELEASE_KEY_SIZE_MANUAL"); + end + $display("STRAP_SS_KEY_RELEASE_KEY_SIZE set manually to 0x%04x", strap_ss_key_release_key_size); + end + else if ($test$plusargs("STRAP_SS_KEY_RELEASE_KEY_SIZE_RAND_LOW")) begin + // Randomize from 4 to 64 bytes, ensure DWORD alignment + strap_ss_key_release_key_size = $urandom_range(16'h4, 16'h40); + strap_ss_key_release_key_size = strap_ss_key_release_key_size & ~16'h3; + $display("STRAP_SS_KEY_RELEASE_KEY_SIZE randomized (0x4-0x40, DWORD aligned) to 0x%04x", strap_ss_key_release_key_size); + end + else if ($test$plusargs("STRAP_SS_KEY_RELEASE_KEY_SIZE_RAND_HIGH")) begin +`ifdef CLP_ASSERT_ON + `ifndef VERILATOR + $assertoff(0, `CPTRA_TOP_PATH.soc_ifc_top1.SS_STRAP_KEY_SIZE_LTE_64); + `endif // VERILATOR +`endif // CLP_ASSERT_ON + strap_ss_key_release_key_size = $urandom_range(16'h44, 16'hFFFF); + // Ensure DWORD alignment by clearing lower 2 bits + strap_ss_key_release_key_size = strap_ss_key_release_key_size & ~16'h3; + $display("STRAP_SS_KEY_RELEASE_KEY_SIZE randomized (>0x40, DWORD aligned) to 0x%04x", strap_ss_key_release_key_size); + end + else if ($test$plusargs("STRAP_SS_KEY_RELEASE_KEY_SIZE_RAND_ANY")) begin + strap_ss_key_release_key_size = $urandom(); + // Ensure DWORD alignment by clearing lower 2 bits + strap_ss_key_release_key_size = strap_ss_key_release_key_size & ~16'h3; + $display("STRAP_SS_KEY_RELEASE_KEY_SIZE randomized (any value, DWORD aligned) to 0x%04x", strap_ss_key_release_key_size); + end + else begin + // Default value (already DWORD aligned) + strap_ss_key_release_key_size = 16'h40; + $display("STRAP_SS_KEY_RELEASE_KEY_SIZE set to default value 0x%04x", strap_ss_key_release_key_size); + end + + if ($test$plusargs("CLP_OCP_LOCK_EN")) begin + ss_ocp_lock_en = 1'b1; + end + else if ($test$plusargs("CLP_OCP_LOCK_DIS")) begin + ss_ocp_lock_en = 1'b0; + end + else begin + // Randomize when neither plusarg is set + ss_ocp_lock_en = $urandom(); + end + + // Initialize strap_ss_key_release_base_addr based on plusargs + if ($test$plusargs("STRAP_SS_KEY_RELEASE_BASE_ADDR_RAND_SRAM")) begin + logic [63:0] random_offset; + // Ensure address is at least 64 bytes (512 bits) before end of SRAM + random_offset = $urandom_range(64'h0, AXI_SRAM_SIZE_BYTES - 64 - 1); + random_offset = random_offset & ~64'h3; + strap_ss_key_release_base_addr = AXI_SRAM_BASE_ADDR + random_offset; + $display("STRAP_SS_KEY_RELEASE_BASE_ADDR randomized within AXI SRAM to 0x%016x", strap_ss_key_release_base_addr); + end + else begin + // Default value + strap_ss_key_release_base_addr = AXI_SRAM_BASE_ADDR; + $display("STRAP_SS_KEY_RELEASE_BASE_ADDR set to default value 0x%016x", strap_ss_key_release_base_addr); + end + end + + + initial begin + cptra_pwrgood = 1'b0; + BootFSM_BrkPoint = $urandom_range(1,0); //Set before anything starts (drive like a const strap) + cptra_rst_b = 1'b0; + assert_rst_flag_from_fatal = 1'b0; + m_axi_bfm_if.rst_mgr(); + +`ifndef VERILATOR + if($test$plusargs("dumpon")) $dumpvars; +`endif + + if($test$plusargs("RAND_DOE_VALUES")) begin + //cptra_obf_key = cptra_obf_key_tb; + for (int dword = 0; dword < $bits(cptra_obf_key)/32; dword++) begin + `ifndef VERILATOR + wait(cptra_obf_key_tb[dword] !== 32'hXXXXXXXX); + `endif + cptra_obf_key[dword] = cptra_obf_key_tb[dword]; + end + + cptra_uds_tb = cptra_uds_rand; + cptra_fe_tb = cptra_fe_rand; + cptra_hek_tb = cptra_hek_rand; + end + else begin + if ($test$plusargs("SECOND_DOE_KAT")) begin + //Key for DOE + cptra_obfkey_tb = 256'he1dd72419beccddff77c722d992cdcc87e9c7486f56ab406ea608d8c6aeb060c; + cptra_uds_tb = 512'h32cd8a75b5e515bd7b0fe37a6de144696aeedb1f5e03225a71fc690f5b004ff593794db7a99ced97c376385149c4ecafd3afd70cb657a6f6434bfd911983f4ff; + cptra_fe_tb = 256'h7dca6154c2510ae1c87b1b422b02b621bb06cac280023894fcff3406af08ee9b; + cptra_hek_tb = 256'h7dca6154c2510ae1c87b1b422b02b621bb06cac280023894fcff3406af08ee9b; // FIXME unique value? + /*256'h7dca6154c2510ae1c87b1b422b02b621bb06cac280023894fcff3406af08ee9b, + 256'he1dd72419beccddff77c722d992cdcc87e9c7486f56ab406ea608d8c6aeb060c, + 256'h64cf2785ad1a159147567e39e303370da445247526d95942bf4d7e88057178b0};*/ + end + else begin + cptra_obfkey_tb = 256'h31358e8af34d6ac31c958bbd5c8fb33c334714bffb41700d28b07f11cfe891e7; + cptra_uds_tb = 512'he4046d05385ab789c6a72866e08350f93f583e2a005ca0faecc32b5cfc323d461c76c107307654db5566a5bd693e227c144516246a752c329056d884daf3c89d; + cptra_fe_tb = 256'hb32e2b171b63827034ebb0d1909f7ef1d51c5f82c1bb9bc26bc4ac4dccdee835; + cptra_hek_tb = 256'hb32e2b171b63827034ebb0d1909f7ef1d51c5f82c1bb9bc26bc4ac4dccdee835; // FIXME + end + //swizzle the key so it matches the endianness of AES block + //used for visual inspection of uds/fe/hek flow, manually switching keys and checking both + for (int dword = 0; dword < $bits(cptra_obf_key)/32; dword++) begin + cptra_obf_key[dword] = cptra_obfkey_tb[dword]; + end + end + + for (int dword = 0; dword < `CLP_CSR_HMAC_KEY_DWORDS; dword++) begin + cptra_csr_hmac_key[dword] = 32'h0b0b0b0b; + end + + // Run the test stimulus + + soc_ifc_hw_error_wdata = 'h0; + generic_input_wires = 'h0; + $display ("\n\n\n\n\n\n"); + repeat(15) @(posedge core_clk); + $display("CLP: Waiting for cptra_rst_b deassertion\n"); + + forever begin + fork + begin: BOOT_AND_CMD_FLOW + boot_and_cmd_flow = process::self(); + + // Repeat this flow after every warm reset + @(posedge cptra_rst_b) + $display("CLP: Observed cptra_rst_b deassertion\n"); + + if (!SKIP_BRINGUP) begin: DO_BOOT_AND_CMD_FLOW + + // Fuse download sequence + wait(ready_for_fuses == 1); + $display ("CLP: Ready for fuse download\n"); + + for (int rpt=0; rpt < 5; rpt++) @(posedge core_clk); + + $display ("SoC: Writing obfuscated UDS to fuse bank\n"); + for (int dw=0; dw < `CLP_OBF_UDS_DWORDS; dw++) begin + m_axi_bfm_if.axi_write_single(.addr(`CLP_SOC_IFC_REG_FUSE_UDS_SEED_0 + 4 * dw), .data(cptra_uds_tb[dw]), .resp(wresp), .resp_user(buser)); + end + + $display ("SoC: Writing obfuscated Field Entropy to fuse bank\n"); + for (int dw=0; dw < `CLP_OBF_FE_DWORDS; dw++) begin + m_axi_bfm_if.axi_write_single(.addr(`CLP_SOC_IFC_REG_FUSE_FIELD_ENTROPY_0 + 4 * dw), .data(cptra_fe_tb[dw]), .resp(wresp), .resp_user(buser)); + end + + $display ("SoC: Writing obfuscated HEK seed to fuse bank\n"); + for (int dw=0; dw < OCP_LOCK_HEK_NUM_DWORDS; dw++) begin + m_axi_bfm_if.axi_write_single(.addr(`CLP_SOC_IFC_REG_FUSE_HEK_SEED_0 + 4 * dw), .data(cptra_hek_tb[dw]), .resp(wresp), .resp_user(buser)); + end + + $display ("SoC: Writing SOC Stepping ID to fuse bank\n"); + m_axi_bfm_if.axi_write_single(.addr(`CLP_SOC_IFC_REG_FUSE_SOC_STEPPING_ID), .data($urandom()), .resp(wresp), .resp_user(buser)); + + $display ("SoC: Writing fuse done register\n"); + m_axi_bfm_if.axi_write_single(.addr(`CLP_SOC_IFC_REG_CPTRA_FUSE_WR_DONE), .data(32'h00000001), .resp(wresp), .resp_user(buser)); + + assert (!cptra_error_non_fatal) else begin + $error("cptra_error_non_fatal observed during boot up"); + $finish; + end + assert (!cptra_error_fatal) else begin + $error("cptra_error_fatal observed during boot up"); + $finish; + end + + if (BootFSM_BrkPoint) begin + $write ("SoC: Polling Flow Status..."); + poll_count = 0; + do begin + m_axi_bfm_if.axi_read_single(.addr(`CLP_SOC_IFC_REG_CPTRA_FLOW_STATUS), .data(rdata), .resp(rresp), .resp_user(buser)); + poll_count++; + end while(rdata[`SOC_IFC_REG_CPTRA_FLOW_STATUS_READY_FOR_FUSES_LOW] == 1); + $display("\n >>> SoC: Ready for Fuses deasserted after polling %d times\n", poll_count); + $display ("SoC: Writing BootGo register\n"); + m_axi_bfm_if.axi_write_single(.addr(`CLP_SOC_IFC_REG_CPTRA_BOOTFSM_GO), .data(32'h00000001), .resp(wresp), .resp_user(buser)); + end + else begin + $display("SoC: Breakpoint not set; skipping BOOTFSM_GO step\n"); + end + + $display ("CLP: ROM Flow in progress...\n"); + + // Test sequence (Mailbox or error handling) + wait(ready_for_mb_processing || ras_test_ctrl.error_injection_seen); + + // Mailbox flow + if (ready_for_mb_processing) begin + for (int rpt=0; rpt<5; rpt++) @(posedge core_clk); + + $display ("CLP: Ready for firmware push\n"); + $write ("SoC: Requesting mailbox lock..."); + poll_count = 0; + do begin + m_axi_bfm_if.axi_read_single(.addr(`CLP_MBOX_CSR_MBOX_LOCK), .user(32'hFFFF_FFFF), .data(rdata), .resp(rresp), .resp_user(buser)); + poll_count++; + end while (rdata[`MBOX_CSR_MBOX_LOCK_LOCK_LOW] == 1); + $display ("\n >>> SoC: Lock granted after polling %d times\n", poll_count); + + $display ("SoC: Writing the Command Register\n"); + m_axi_bfm_if.axi_write_single(.addr(`CLP_MBOX_CSR_MBOX_CMD), .user(32'hFFFF_FFFF), .data(32'hBA5EBA11), .resp(wresp), .resp_user(buser)); + + $display ("SoC: Writing the Data Length Register\n"); + m_axi_bfm_if.axi_write_single(.addr(`CLP_MBOX_CSR_MBOX_DLEN), .user(32'hFFFF_FFFF), .data(FW_NUM_DWORDS*4), .resp(wresp), .resp_user(buser)); + + $display ("SoC: Writing the Firmware into Data-in Register\n"); + fw_blob = new[FW_NUM_DWORDS]; + wstrb_array = new[FW_NUM_DWORDS]('{default: {`CALIPTRA_AXI_DATA_WIDTH/8{1'b1}}}); + for (int dw=0; dw < FW_NUM_DWORDS; dw++) + fw_blob[dw] = $urandom(); + m_axi_bfm_if.axi_write(.addr (`CLP_MBOX_CSR_MBOX_DATAIN), + .burst (AXI_BURST_FIXED), + .len (FW_NUM_DWORDS-1), + .user (32'hFFFF_FFFF ), + .data (fw_blob ), + .strb (wstrb_array ), + .write_user(wuser_array ), + .resp (wresp ), + .resp_user (buser )); + + $display ("SoC: Setting the Execute Register\n"); + m_axi_bfm_if.axi_write_single(.addr(`CLP_MBOX_CSR_MBOX_EXECUTE), .user(32'hFFFF_FFFF), .data(32'h00000001), .resp(wresp), .resp_user(buser)); + + $display("SoC: Waiting for Response Data availability\n"); + wait(mailbox_data_avail); + + $display("SoC: Reading the Status Register...\n"); + m_axi_bfm_if.axi_read_single(.addr(`CLP_MBOX_CSR_MBOX_STATUS), .user(32'hFFFF_FFFF), .data(rdata), .resp(rresp), .resp_user(buser)); + + if (((rdata & `MBOX_CSR_MBOX_STATUS_STATUS_MASK) >> `MBOX_CSR_MBOX_STATUS_STATUS_LOW) == DATA_READY) begin: READ_RESP_DATA + $display("SoC: Reading the Data Length Register...\n"); + m_axi_bfm_if.axi_read_single(.addr(`CLP_MBOX_CSR_MBOX_DLEN), .user(32'hFFFF_FFFF), .data(rdata), .resp(rresp), .resp_user(buser)); + + $display("SoC: Reading the Data Out Register\n"); + for (int xfer4k = 0; xfer4k < rdata; xfer4k += 4096) begin + byte_count = (rdata - xfer4k) > 4096 ? 4096 : (rdata - xfer4k); + dw_count = byte_count/(`CALIPTRA_AXI_DATA_WIDTH/8) + |byte_count[$clog2(`CALIPTRA_AXI_DATA_WIDTH/8)-1:0]; + rdata_array = new[dw_count]; + rresp_array = new[dw_count]; + ruser_array = new[dw_count]; + m_axi_bfm_if.axi_read(.addr (`CLP_MBOX_CSR_MBOX_DATAOUT), + .burst (AXI_BURST_FIXED), + .len (dw_count-1 ), + .user (32'hFFFF_FFFF ), + .data (rdata_array ), + .resp (rresp_array ), + .resp_user(ruser_array )); + end + end: READ_RESP_DATA + + $display("SoC: Resetting the Execute Register\n"); + m_axi_bfm_if.axi_write_single(.addr(`CLP_MBOX_CSR_MBOX_EXECUTE), .user(32'hFFFF_FFFF), .data(32'h0), .resp(wresp), .resp_user(buser)); + + //Wait for Mailbox flow to be done before toggling generic_input_wires + @(negedge core_clk); + generic_input_wires = {$urandom, $urandom}; //Toggle wires + end + + if (ras_test_ctrl.error_injection_seen) begin + $display("SoC: Waiting to see cptra_error_fatal/non_fatal\n"); + rv_dma_resp_error = 1'b0; + end + + // Mailbox response flow and RAS functionality + forever begin + if (cptra_error_fatal_dly_p) begin + $display("SoC: Observed cptra_error_fatal; reading Caliptra register\n"); + m_axi_bfm_if.axi_read_single(.addr(`CLP_SOC_IFC_REG_CPTRA_HW_ERROR_FATAL), .data(rdata), .resp(rresp), .resp_user(buser)); + if (rdata[`SOC_IFC_REG_CPTRA_HW_ERROR_FATAL_ICCM_ECC_UNC_LOW]) begin + generic_input_wires = {32'h0, ICCM_FATAL_OBSERVED}; + end + else if (rdata[`SOC_IFC_REG_CPTRA_HW_ERROR_FATAL_DCCM_ECC_UNC_LOW]) begin + generic_input_wires = {32'h0, DCCM_FATAL_OBSERVED}; + end + else if (rdata[`SOC_IFC_REG_CPTRA_HW_ERROR_FATAL_NMI_PIN_LOW]) begin + generic_input_wires = {32'h0, NMI_FATAL_OBSERVED}; + end + else if (rdata[`SOC_IFC_REG_CPTRA_HW_ERROR_FATAL_CRYPTO_ERR_LOW]) begin + generic_input_wires = {32'h0, CRYPTO_ERROR_OBSERVED}; + end + else begin + generic_input_wires = {32'h0, ERROR_NONE_SET}; + end + // HW ERROR registers are W1C, capture the set bits + soc_ifc_hw_error_wdata = rdata; + //wait for reset stuff + assert_rst_flag_from_fatal = 1; + wait(cptra_rst_b == 0); + end + else if (cptra_error_non_fatal_dly_p) begin + $display("SoC: Observed cptra_error_non_fatal; reading Caliptra register\n"); + m_axi_bfm_if.axi_read_single(.addr(`CLP_SOC_IFC_REG_CPTRA_HW_ERROR_NON_FATAL), .data(rdata), .resp(rresp), .resp_user(buser)); + if (rdata[`SOC_IFC_REG_CPTRA_HW_ERROR_NON_FATAL_MBOX_PROT_NO_LOCK_LOW]) begin + generic_input_wires = {32'h0, PROT_NO_LOCK_NON_FATAL_OBSERVED}; + end + else if (rdata[`SOC_IFC_REG_CPTRA_HW_ERROR_NON_FATAL_MBOX_PROT_OOO_LOW]) begin + generic_input_wires = {32'h0, PROT_OOO_NON_FATAL_OBSERVED}; + end + else if (rdata[`SOC_IFC_REG_CPTRA_HW_ERROR_NON_FATAL_MBOX_ECC_UNC_LOW]) begin + generic_input_wires = {32'h0, MBOX_NON_FATAL_OBSERVED}; + end + else begin + generic_input_wires = {32'h0, ERROR_NONE_SET}; + end + $display("SoC: Observed cptra_error_non_fatal; writing to clear Caliptra register\n"); + m_axi_bfm_if.axi_write_single(.addr(`CLP_SOC_IFC_REG_CPTRA_HW_ERROR_NON_FATAL), .data(rdata), .resp(wresp), .resp_user(buser)); + end + else if (soc_ifc_hw_error_wdata) begin + $display("SoC: Observed cptra_error_fatal; writing to clear Caliptra register\n"); + m_axi_bfm_if.axi_write_single(.addr(`CLP_SOC_IFC_REG_CPTRA_HW_ERROR_FATAL), .data(soc_ifc_hw_error_wdata), .resp(wresp), .resp_user(buser)); + soc_ifc_hw_error_wdata = '0; + end + else if (ras_test_ctrl.do_no_lock_access) begin + fork + begin + $display("SoC: Reading the Data Out Register without lock\n"); + dw_count = 1; + rdata_array = new[dw_count]; + rresp_array = new[dw_count]; + ruser_array = new[dw_count]; + m_axi_bfm_if.axi_read(.addr (`CLP_MBOX_CSR_MBOX_DATAOUT), + .burst (AXI_BURST_FIXED), + .len (dw_count-1 ), + .user (32'hFFFF_FFFF ), + .data (rdata_array ), + .resp (rresp_array ), + .resp_user(ruser_array )); + end + join + end + else if (ras_test_ctrl.do_ooo_access) begin + fork + begin + $write ("SoC: Requesting mailbox lock..."); + poll_count = 0; + do begin + m_axi_bfm_if.axi_read_single(.addr(`CLP_MBOX_CSR_MBOX_LOCK), .user(32'hFFFF_FFFF), .data(rdata), .resp(rresp), .resp_user(buser)); + poll_count++; + end while (rdata[`MBOX_CSR_MBOX_LOCK_LOCK_LOW] == 1); + $display ("\n >>> SoC: Lock granted after polling %d times\n", poll_count); + + $display("SoC: Reading the Data Length Register...\n"); + m_axi_bfm_if.axi_read_single(.addr(`CLP_MBOX_CSR_MBOX_DLEN), .user(32'hFFFF_FFFF), .data(rdata), .resp(rresp), .resp_user(buser)); + + $display("SoC: Reading the Data Out Register\n"); + dw_count = 1; + rdata_array = new[dw_count]; + rresp_array = new[dw_count]; + ruser_array = new[dw_count]; + m_axi_bfm_if.axi_read(.addr (`CLP_MBOX_CSR_MBOX_DATAOUT), + .burst (AXI_BURST_FIXED), + .len (dw_count-1 ), + .user (32'hFFFF_FFFF ), + .data (rdata_array ), + .resp (rresp_array ), + .resp_user(ruser_array )); + end + join + end + else if (ras_test_ctrl.reset_generic_input_wires) begin + `ifdef VERILATOR + generic_input_wires = {32'h72746C76, ERROR_NONE_SET}; /* 32'h72746c76 is the big-endian ASCII representation of 'vltr' (r t l v) */ + `else + generic_input_wires = {32'h0, ERROR_NONE_SET}; + `endif + end + else if (rv_dma_resp_error) begin + generic_input_wires = {32'h0, DMA_ERROR_OBSERVED}; + rv_dma_resp_error = 1'b0; + end + else if (mailbox_data_avail) begin + $display("SoC: Reading the Data Length Register\n"); + m_axi_bfm_if.axi_read_single(.addr(`CLP_MBOX_CSR_MBOX_DLEN), .user(32'hFFFF_FFFF), .data(rdata), .resp(rresp), .resp_user(buser)); + + $display("SoC: Reading the Data Out Register\n"); + for (int xfer4k = 0; xfer4k < rdata; xfer4k += 4096) begin + byte_count = (rdata - xfer4k) > 4096 ? 4096 : (rdata - xfer4k); + dw_count = byte_count/(`CALIPTRA_AXI_DATA_WIDTH/8) + |byte_count[$clog2(`CALIPTRA_AXI_DATA_WIDTH/8)-1:0]; + rdata_array = new[dw_count]; + rresp_array = new[dw_count]; + ruser_array = new[dw_count]; + m_axi_bfm_if.axi_read(.addr (`CLP_MBOX_CSR_MBOX_DATAOUT), + .burst (AXI_BURST_FIXED ), + .len (dw_count-1 ), + .user (32'hFFFF_FFFF ), + .data (rdata_array ), + .resp (rresp_array ), + .resp_user(ruser_array )); + end + + $display ("SoC: Writing the Mbox Status Register\n"); + m_axi_bfm_if.axi_write_single(.addr(`CLP_MBOX_CSR_MBOX_STATUS), .user(32'hFFFF_FFFF), .data(32'h1), .resp(wresp), .resp_user(buser)); + end + @(posedge core_clk); + end + end: DO_BOOT_AND_CMD_FLOW + else begin: SKIP_BOOT_AND_CMD_FLOW + forever @(posedge core_clk); + end: SKIP_BOOT_AND_CMD_FLOW + end: BOOT_AND_CMD_FLOW + begin: CLK_GATE_FLOW + wait(cycleCnt_smpl_en); + for (int rpt=0; rpt<2000; rpt++) @(negedge core_clk); + + if (int_flag) begin + $display("SoC (clk_gate_flow): Forcing soft_int = 1. cycleCnt [%d]\n", cycleCnt); + force `CPTRA_TOP_PATH.soft_int = 1'b1; + for (int rpt=0; rpt<2; rpt++) @(negedge core_clk); + $display("SoC (clk_gate_flow): Releasing soft_int = 1. cycleCnt [%d]\n", cycleCnt); + release `CPTRA_TOP_PATH.soft_int; + end + + for (int rpt=0; rpt<5000; rpt++) @(negedge core_clk); + + if (int_flag) begin + $display("SoC (clk_gate_flow): Forcing timer_int = 1. cycleCnt [%d]\n", cycleCnt); + force `CPTRA_TOP_PATH.timer_int = 1'b1; + for (int rpt=0; rpt<2; rpt++) @(negedge core_clk); + $display("SoC (clk_gate_flow): Releasing timer_int = 1. cycleCnt [%d]\n", cycleCnt); + release `CPTRA_TOP_PATH.timer_int; + end + + for (int rpt=0; rpt<8000; rpt++) @(negedge core_clk); + + if (int_flag) begin + $display("SoC (clk_gate_flow): Forcing soft_int = 1. cycleCnt [%d]\n", cycleCnt); + force `CPTRA_TOP_PATH.soft_int = 1'b1; + for (int rpt=0; rpt<2; rpt++) @(negedge core_clk); + $display("SoC (clk_gate_flow): Releasing soft_int = 1. cycleCnt [%d]\n", cycleCnt); + release `CPTRA_TOP_PATH.soft_int; + end + + wait(cptra_rst_b == 0); + end: CLK_GATE_FLOW + begin: RESET_FLOW + @(negedge cptra_rst_b); + $display("CLP: Observed cptra_rst_b assertion\n"); +// disable BOOT_AND_CMD_FLOW; + if (boot_and_cmd_flow != null) boot_and_cmd_flow.kill(); + assert_rst_flag_from_fatal = 1'b0; + m_axi_bfm_if.rst_mgr(); + end: RESET_FLOW + join_any + end + end + + assign assert_rst_flag = assert_rst_flag_from_service || assert_rst_flag_from_fatal; + assign deassert_rst_flag = deassert_rst_flag_from_service || deassert_rst_flag_from_fatal; + always @(posedge core_clk) begin + //Reset/pwrgood assertion during runtime + if (cycleCnt == 15 || deassert_hard_rst_flag) begin + $display ("SoC: Asserting cptra_pwrgood and breakpoint. cycleCnt [%d] deassert_hard_rst_flag[%d]\n", cycleCnt, deassert_hard_rst_flag); + //assert power good + cptra_pwrgood <= 1'b1; + end + else if (cycleCnt == 20 || deassert_rst_flag) begin + $display ("SoC: De-Asserting cptra_rst_b. cycleCnt [%d] deassert_rst_flag[%d]\n", cycleCnt, deassert_rst_flag); + //de-assert reset + cptra_rst_b <= 1'b1; + end + else if (assert_hard_rst_flag) begin + cptra_pwrgood <= 'b0; + cptra_rst_b <= 'b0; + end + else if (assert_rst_flag) begin + cptra_rst_b <= 'b0; + end + end + +`define RV_INST `CPTRA_TOP_PATH.rvtop +`define RV_IDMA_RESP_INST `CPTRA_TOP_PATH.responder_inst[`CALIPTRA_SLAVE_SEL_IDMA] +`define RV_DDMA_RESP_INST `CPTRA_TOP_PATH.responder_inst[`CALIPTRA_SLAVE_SEL_DDMA] +task force_ahb_dma_read(input logic [31:0] address); + while(`RV_INST.dma_hsel) @(posedge core_clk); + + // Disable DMA-related hreadyout assertions before forcing signals +`ifdef CLP_ASSERT_ON + `ifndef VERILATOR + $assertoff(0, `CPTRA_TOP_PATH.ahb_lite_bus_i.u_ahb_lite_address_decoder.rspr_ready_loop[`CALIPTRA_SLAVE_SEL_DDMA].rspr_ready_do_assert.rspr_ready_rv_dma_merge.AHB_RSPR_DFLT_READY); + $assertoff(0, `CPTRA_TOP_PATH.ahb_lite_bus_i.u_ahb_lite_address_decoder.rspr_ready_loop[`CALIPTRA_SLAVE_SEL_IDMA].rspr_ready_do_assert.rspr_ready_rv_dma_merge.AHB_RSPR_DFLT_READY); + `endif // VERILATOR +`endif // CLP_ASSERT_ON + + force `RV_IDMA_RESP_INST.hreadyout = 1'b0; + force `RV_DDMA_RESP_INST.hreadyout = 1'b0; + + force `RV_INST.dma_haddr = address; + force `RV_INST.dma_hsize = 3'b010; // 4-bytes + force `RV_INST.dma_hwrite = 1'b0; + force `RV_INST.dma_hwdata = '0; + force `RV_INST.dma_hreadyin = 1'b1; + force `RV_INST.dma_hsel = 1'b1; + force `RV_INST.dma_htrans = 2'b10; + + // Wait for command to be accepted + do @(posedge core_clk); while(!`RV_INST.dma_hreadyout); + force `RV_INST.dma_htrans = 2'b00; + // Wait for response to be provided + do @(posedge core_clk); while(!`RV_INST.dma_hreadyout); + $display("[%t] AHB DMA FORCE READ: Address 0x%x Data 0x%x Resp 0x%x", $time, address, `RV_INST.dma_hrdata, `RV_INST.dma_hresp); + if (`RV_INST.dma_hresp) + rv_dma_resp_error = 1'b1; + + force `RV_INST.dma_hsel = 1'b0; // Reset to the expected value before releasing force + force `RV_IDMA_RESP_INST.hreadyout = `RV_INST.dma_hreadyout; // Reset to the expected value before releasing force + force `RV_DDMA_RESP_INST.hreadyout = `RV_INST.dma_hreadyout; // Reset to the expected value before releasing force + + release `RV_IDMA_RESP_INST.hreadyout; + release `RV_DDMA_RESP_INST.hreadyout; + + release `RV_INST.dma_htrans; + release `RV_INST.dma_haddr; + release `RV_INST.dma_hsize; + release `RV_INST.dma_hwrite; + release `RV_INST.dma_hwdata; + release `RV_INST.dma_hsel; + release `RV_INST.dma_hreadyin; + + #1ps; + + // Re-enable DMA-related hreadyout assertions after releasing signals +`ifdef CLP_ASSERT_ON + `ifndef VERILATOR + $asserton(0, `CPTRA_TOP_PATH.ahb_lite_bus_i.u_ahb_lite_address_decoder.rspr_ready_loop[`CALIPTRA_SLAVE_SEL_DDMA].rspr_ready_do_assert.rspr_ready_rv_dma_merge.AHB_RSPR_DFLT_READY); + $asserton(0, `CPTRA_TOP_PATH.ahb_lite_bus_i.u_ahb_lite_address_decoder.rspr_ready_loop[`CALIPTRA_SLAVE_SEL_IDMA].rspr_ready_do_assert.rspr_ready_rv_dma_merge.AHB_RSPR_DFLT_READY); + `endif // VERILATOR +`endif // CLP_ASSERT_ON +endtask + +task force_ahb_dma_loop_read(input logic [31:0] start_addr, input logic [19:0] count); + automatic logic [31:0] addr; + addr = start_addr; + $display("[%t] AHB DMA FORCE LOOP READ: Start Address 0x%x Count 0x%x", $time, addr, count); + if ($isunknown(start_addr) || $isunknown(addr)) + $error("[%t] Unknown signal found: start_addr 0x%x addr 0x%x", $time, start_addr, addr); + repeat(count) begin + force_ahb_dma_read(addr); + addr += 4; + end +endtask + +initial begin + forever @(posedge core_clk) begin + if (ras_test_ctrl.dccm_read_burst.start) + force_ahb_dma_loop_read(ras_test_ctrl.dccm_read_burst.addr, ras_test_ctrl.dccm_read_burst.count); + if (ras_test_ctrl.iccm_read_burst.start) + force_ahb_dma_loop_read(ras_test_ctrl.iccm_read_burst.addr, ras_test_ctrl.iccm_read_burst.count); + end +end + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/caliptra_veer_sram_export.sv b/designs/Caliptra/src/caliptra-rtl/caliptra_veer_sram_export.sv new file mode 100644 index 0000000..0dd47e7 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/caliptra_veer_sram_export.sv @@ -0,0 +1,547 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +// + +import el2_pkg::*; +module caliptra_veer_sram_export import caliptra_top_tb_pkg::*; #( + `include "el2_param.vh" +) ( + // Decode: + // [0] - Single bit, ICCM Error Injection + // [1] - Double bit, ICCM Error Injection + // [2] - Single bit, DCCM Error Injection + // [3] - Double bit, DCCM Error Injection + input veer_sram_error_injection_mode_t sram_error_injection_mode, + el2_mem_if.veer_sram_sink el2_mem_export +); + +////////////////////////////////////////////////////// +// Sim-only Error Injection for ICCM/DCCM +// + bit [pt.ICCM_NUM_BANKS-1:0] iccm_flip_bit; + bit [pt.DCCM_NUM_BANKS-1:0] dccm_flip_bit; + logic [pt.ICCM_NUM_BANKS-1:0] [39-1:0] iccm_sram_wdata_bitflip; + logic [pt.DCCM_NUM_BANKS-1:0] [39-1:0] dccm_sram_wdata_bitflip; + int ii,jj,kk,ll; + + `ifndef VERILATOR + initial begin + bitflip_mask_generator #(39) iccm_bitflip_gen = new(); + bitflip_mask_generator #(39) dccm_bitflip_gen = new(); + forever begin + @(posedge el2_mem_export.clk) + if (~sram_error_injection_mode.iccm_single_bit_error && ~sram_error_injection_mode.iccm_double_bit_error) begin + iccm_sram_wdata_bitflip <= '{default:0}; + end + else if (el2_mem_export.iccm_clken & el2_mem_export.iccm_wren_bank) begin + // Corrupt 50% of the writes + for (ii = 0; ii < pt.ICCM_NUM_BANKS; ii++) begin + iccm_flip_bit[ii] = 1'($urandom_range(0,99) < 50); + iccm_sram_wdata_bitflip[ii] <= iccm_flip_bit[ii] ? iccm_bitflip_gen.get_mask(sram_error_injection_mode.iccm_double_bit_error) : '0; + end + end + if (~sram_error_injection_mode.dccm_single_bit_error && ~sram_error_injection_mode.dccm_double_bit_error) begin + dccm_sram_wdata_bitflip <= '{default:0}; + end + else if (el2_mem_export.dccm_clken & el2_mem_export.dccm_wren_bank) begin + // Corrupt 50% of the writes + for (jj = 0; jj < pt.DCCM_NUM_BANKS; jj++) begin + dccm_flip_bit[jj] = 1'($urandom_range(0,99) < 50); + dccm_sram_wdata_bitflip[jj] <= dccm_flip_bit[jj] ? dccm_bitflip_gen.get_mask(sram_error_injection_mode.dccm_double_bit_error) : '0; + end + end + end + end + `else + always @(posedge el2_mem_export.clk) begin + // Corrupt 50% of the writes + if ((~sram_error_injection_mode.iccm_single_bit_error && ~sram_error_injection_mode.iccm_double_bit_error)) begin + iccm_sram_wdata_bitflip <= '{default:0}; + end + else if (el2_mem_export.iccm_clken & el2_mem_export.iccm_wren_bank) begin + for (kk = 0; kk < pt.ICCM_NUM_BANKS; kk++) begin + iccm_flip_bit[kk] <= ($urandom % 100) < 50; + iccm_sram_wdata_bitflip[kk] <= iccm_flip_bit[kk] ? get_bitflip_mask(sram_error_injection_mode.iccm_double_bit_error) : '0; + end + end + // Corrupt 50% of the writes + if ((~sram_error_injection_mode.dccm_single_bit_error && ~sram_error_injection_mode.dccm_double_bit_error)) begin + dccm_sram_wdata_bitflip <= '{default:0}; + end + else if (el2_mem_export.dccm_clken & el2_mem_export.dccm_wren_bank) begin + for (ll = 0; ll < pt.DCCM_NUM_BANKS; ll++) begin + dccm_flip_bit[ll] <= ($urandom % 100) < 50; + dccm_sram_wdata_bitflip[ll] <= dccm_flip_bit[ll] ? get_bitflip_mask(sram_error_injection_mode.dccm_double_bit_error) : '0; + end + end + end + `endif + +////////////////////////////////////////////////////// +// DCCM +// +if (pt.DCCM_ENABLE == 1) begin: Gen_dccm_enable +`define EL2_LOCAL_DCCM_RAM_TEST_PORTS .TEST1 (1'b0 ), \ + .RME (1'b0 ), \ + .RM (4'b0000), \ + .LS (1'b0 ), \ + .DS (1'b0 ), \ + .SD (1'b0 ), \ + .TEST_RNM(1'b0 ), \ + .BC1 (1'b0 ), \ + .BC2 (1'b0 ), \ + +localparam DCCM_INDEX_DEPTH = ((pt.DCCM_SIZE)*1024)/((pt.DCCM_BYTE_WIDTH)*(pt.DCCM_NUM_BANKS)); // Depth of memory bank +// 8 Banks, 16KB each (2048 x 72) +for (genvar i=0; i MLDSA_GAMMA1_RANGE); + + // For the lower instance + assign eq_flags[sig_enc_i*2+1] = (abr_top.sigencode_z_inst.enc_unit[sig_enc_i].lower_encode.data_i == MLDSA_GAMMA1_RANGE); + assign less_flags[sig_enc_i*2+1] = (abr_top.sigencode_z_inst.enc_unit[sig_enc_i].lower_encode.data_i < MLDSA_GAMMA1_RANGE); + assign greater_flags[sig_enc_i*2+1] = (abr_top.sigencode_z_inst.enc_unit[sig_enc_i].lower_encode.data_i > MLDSA_GAMMA1_RANGE); + end + endgenerate + + // OR-reduce the flags: if any instance meets the condition, the corresponding signal is 1. + assign enc_unit_equal = (|eq_flags) & (abr_top.sigencode_z_inst.state != abr_top.sigencode_z_inst.IDLE); + assign enc_unit_less = (|less_flags) & (abr_top.sigencode_z_inst.state != abr_top.sigencode_z_inst.IDLE); + assign enc_unit_greater = (|greater_flags) & (abr_top.sigencode_z_inst.state != abr_top.sigencode_z_inst.IDLE); + // Sign_z to cover the aggregated conditions + covergroup clp_mldsa_sign_z_enc_agg_cg @(posedge clk); + coverpoint enc_unit_equal { + bins hit = {1'b1}; + } + coverpoint enc_unit_less { + bins hit = {1'b1}; + } + coverpoint enc_unit_greater { + bins hit = {1'b1}; + } + endgroup + + // The FSM cases are: 'h0, 'h1, 'h2, MLDSA_Q-1, MLDSA_Q-2, and default. + logic [(NUM_ENC*2)-1:0] skenc_state0_flags; + logic [(NUM_ENC*2)-1:0] skenc_state1_flags; + logic [(NUM_ENC*2)-1:0] skenc_state2_flags; + logic [(NUM_ENC*2)-1:0] skenc_state_mq1_flags; + logic [(NUM_ENC*2)-1:0] skenc_state_mq2_flags; + logic skenc_state0_agg, skenc_state1_agg, skenc_state2_agg, skenc_state_mq1_agg, skenc_state_mq2_agg; + + genvar sk_enc_i; + generate + for (sk_enc_i = 0; sk_enc_i < NUM_ENC; sk_enc_i++) begin : sk_enc_loop + // For mem_a_rd_data element + assign skenc_state0_flags[sk_enc_i*2] = (abr_top.skencode_inst.mem_a_rd_data[sk_enc_i] == 'h0); + assign skenc_state1_flags[sk_enc_i*2] = (abr_top.skencode_inst.mem_a_rd_data[sk_enc_i] == 'h1); + assign skenc_state2_flags[sk_enc_i*2] = (abr_top.skencode_inst.mem_a_rd_data[sk_enc_i] == 'h2); + assign skenc_state_mq1_flags[sk_enc_i*2] = (abr_top.skencode_inst.mem_a_rd_data[sk_enc_i] == MLDSA_Q - 1); + assign skenc_state_mq2_flags[sk_enc_i*2] = (abr_top.skencode_inst.mem_a_rd_data[sk_enc_i] == MLDSA_Q - 2); + // For mem_b_rd_data element + assign skenc_state0_flags[sk_enc_i*2+1] = (abr_top.skencode_inst.mem_b_rd_data[sk_enc_i] == 'h0); + assign skenc_state1_flags[sk_enc_i*2+1] = (abr_top.skencode_inst.mem_b_rd_data[sk_enc_i] == 'h1); + assign skenc_state2_flags[sk_enc_i*2+1] = (abr_top.skencode_inst.mem_b_rd_data[sk_enc_i] == 'h2); + assign skenc_state_mq1_flags[sk_enc_i*2+1] = (abr_top.skencode_inst.mem_b_rd_data[sk_enc_i] == MLDSA_Q - 1); + assign skenc_state_mq2_flags[sk_enc_i*2+1] = (abr_top.skencode_inst.mem_b_rd_data[sk_enc_i] == MLDSA_Q - 2); + end + endgenerate + + // OR-reduce each set of flags and ensure the FSM is not in IDLE. + // (Assuming abr_top.skencode_inst.state and its IDLE constant are accessible.) + assign skenc_state0_agg = (|skenc_state0_flags) & (abr_top.skencode_inst.main_state != abr_top.skencode_inst.IDLE); + assign skenc_state1_agg = (|skenc_state1_flags) & (abr_top.skencode_inst.main_state != abr_top.skencode_inst.IDLE); + assign skenc_state2_agg = (|skenc_state2_flags) & (abr_top.skencode_inst.main_state != abr_top.skencode_inst.IDLE); + assign skenc_state_mq1_agg = (|skenc_state_mq1_flags) & (abr_top.skencode_inst.main_state != abr_top.skencode_inst.IDLE); + assign skenc_state_mq2_agg = (|skenc_state_mq2_flags) & (abr_top.skencode_inst.main_state != abr_top.skencode_inst.IDLE); + + // Now create a covergroup that samples these aggregated flags. + covergroup clp_mldsa_skencode_agg_cg @(posedge clk); + coverpoint skenc_state0_agg { bins hit = {1'b1}; } + coverpoint skenc_state1_agg { bins hit = {1'b1}; } + coverpoint skenc_state2_agg { bins hit = {1'b1}; } + coverpoint skenc_state_mq1_agg { bins hit = {1'b1}; } + coverpoint skenc_state_mq2_agg { bins hit = {1'b1}; } + endgroup + + covergroup clp_abr_ocp_lock_cov_grp @(posedge clk); + + ocp_lock_in_progress_cp: coverpoint ocp_lock_in_progress; + + kv_read_entry_mldsa_cp: coverpoint {kv_mldsa_seed_data_present, kv_read_ctrl_reg.read_entry } + iff (mldsa_cmd inside {MLDSA_KEYGEN, MLDSA_KEYGEN_SIGN}) { + bins fw = {[0:23]}; //{1'b0, [0:$]}; + bins lower_slots = {[32:47]}; //{1'b1, [0:15]}; + bins upper_slots = {[48:54]}; //{1'b1, [16:22]}; + bins slot_23 = {55}; //{1'b1, 23}; + } + + kv_read_entry_0_cp: coverpoint {kv_write_metrics.kv_data0_present, kv_write_metrics.kv_data0_entry} + iff (mlkem_cmd inside {MLKEM_KEYGEN_DEC}) { + bins fw = {[0:23]}; //{1'b0, [0:$]}; + bins lower_slots = {[32:47]}; //{1'b1, [0:15]}; + bins upper_slots = {[48:54]}; //{1'b1, [16:22]}; + bins slot_23 = {55}; //{1'b1, 23}; + } + + kv_read_entry_1_cp: coverpoint {kv_write_metrics.kv_data1_present, kv_write_metrics.kv_data1_entry} + iff (mlkem_cmd inside {MLKEM_ENCAPS}) { + bins fw = {[0:23]}; //{1'b0, [0:$]}; + bins lower_slots = {[32:47]}; //{1'b1, [0:15]}; + bins upper_slots = {[48:54]}; //{1'b1, [16:22]}; + bins slot_23 = {55}; //{1'b1, 23}; + } + + kv_write_entry_decaps_cp: coverpoint {kv_write_ctrl_reg.write_en, kv_write_metrics.kv_write_entry} + iff (mlkem_cmd inside {MLKEM_KEYGEN_DEC}) { + bins fw = {[0:23]}; //{1'b0, [0:$]}; + bins lower_slots = {[32:47]}; //{1'b1, [0:15]}; + bins upper_slots = {[48:54]}; //{1'b1, [16:22]}; + bins slot_23 = {55}; //{1'b1, 23}; + } + + kv_write_entry_encaps_cp: coverpoint {kv_write_ctrl_reg.write_en, kv_write_metrics.kv_write_entry} + iff (mlkem_cmd inside {MLKEM_ENCAPS}) { + bins fw = {[0:23]}; //{1'b0, [0:$]}; + bins lower_slots = {[32:47]}; //{1'b1, [0:15]}; + bins upper_slots = {[48:54]}; //{1'b1, [16:22]}; + bins slot_23 = {55}; //{1'b1, 23}; + } + + ocp_lock_X_kv_read_entry0: cross ocp_lock_in_progress_cp, kv_write_entry_decaps_cp, kv_read_entry_0_cp; + ocp_lock_X_kv_read_entry1: cross ocp_lock_in_progress_cp, kv_write_entry_encaps_cp, kv_read_entry_1_cp; + ocp_lock_X_kv_read_entry_mldsa: cross ocp_lock_in_progress_cp, kv_read_entry_mldsa_cp; + endgroup + + // Instantiate the covergroup + clp_mldsa_skencode_agg_cg clp_mldsa_skencode_agg_cov = new(); + clp_mldsa_sign_z_enc_agg_cg clp_mldsa_sign_z_enc_agg_cov_grp1 = new(); + + clp_abr_ocp_lock_cov_grp clp_abr_ocp_lock_cov_grp1 = new(); + + clp_abr_top_cov_grp clp_abr_top_cov_grp1 = new(); + +endinterface + +`endif diff --git a/designs/Caliptra/src/caliptra-rtl/common_defines.sv b/designs/Caliptra/src/caliptra-rtl/common_defines.sv new file mode 100644 index 0000000..bb8ca16 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/common_defines.sv @@ -0,0 +1,270 @@ +//******************************************************************************** +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +//******************************************************************************** + + +// NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE +// This is an automatically generated file by cwhitehead on Wed Oct 8 18:26:01 PDT 2025 +// +// cmd: veer -target=default_ahb -set=ret_stack_size=8 -set=btb_enable=1 -set=btb_fullya=0 -set=btb_size=512 -set=bht_size=512 -set=div_bit=4 -set=div_new=1 -set=dccm_enable=1 -set=dccm_num_banks=4 -set=dccm_region=0x5 -set=dccm_offset=0x00000 -set=dccm_size=256 -set=dma_buf_depth=5 -set=fast_interrupt_redirect=1 -set=icache_enable=0 -set=icache_waypack=1 -set=icache_ecc=1 -set=icache_size=16 -set=icache_2banks=1 -set=icache_num_ways=2 -set=icache_bypass_enable=1 -set=icache_num_bypass=2 -set=icache_num_tag_bypass=2 -set=icache_tag_bypass_enable=1 -set=iccm_enable=1 -set=iccm_num_banks=4 -set=iccm_region=0x4 -set=iccm_offset=0x0 -set=iccm_size=256 -set=lsu_stbuf_depth=4 -set=lsu_num_nbload=4 -set=load_to_use_plus1=0 -set=pic_2cycle=0 -set=pic_region=0x6 -set=pic_offset=0 -set=pic_size=32 -set=pic_total_int=31 -set=dma_buf_depth=5 -set=timer_legal_en=1 -set=bitmanip_zba=1 -set=bitmanip_zbb=1 -set=bitmanip_zbc=1 -set=bitmanip_zbe=0 -set=bitmanip_zbf=0 -set=bitmanip_zbp=0 -set=bitmanip_zbr=0 -set=bitmanip_zbs=1 -set=pmp_entries=64 -set=reset_vec=0x00000000 -fpga_optimize=0 -snapshot=Cores-VeeR-EL2 +// +`ifndef RV_COMMON_DEFINES +`define RV_COMMON_DEFINES + +`define RV_ROOT "" +`define RV_BHT_ADDR_HI 9 +`define RV_BHT_ADDR_LO 2 +`define RV_BHT_ARRAY_DEPTH 256 +`define RV_BHT_GHR_HASH_1 +`define RV_BHT_GHR_RANGE 7:0 +`define RV_BHT_GHR_SIZE 8 +`define RV_BHT_HASH_STRING {hashin[8+1:2]^ghr[8-1:0]}// cf2 +`define RV_BHT_SIZE 512 +`define RV_BTB_ADDR_HI 9 +`define RV_BTB_ADDR_LO 2 +`define RV_BTB_ARRAY_DEPTH 256 +`define RV_BTB_BTAG_FOLD 0 +`define RV_BTB_BTAG_SIZE 5 +`define RV_BTB_ENABLE 1 +`define RV_BTB_FOLD2_INDEX_HASH 0 +`define RV_BTB_INDEX1_HI 9 +`define RV_BTB_INDEX1_LO 2 +`define RV_BTB_INDEX2_HI 17 +`define RV_BTB_INDEX2_LO 10 +`define RV_BTB_INDEX3_HI 25 +`define RV_BTB_INDEX3_LO 18 +`define RV_BTB_SIZE 512 +`define RV_BTB_TOFFSET_SIZE 12 +`define RV_BUS_PRTY_DEFAULT 2'h3 +`define RV_DMA_BUS_ID 1 +`define RV_DMA_BUS_PRTY 2 +`define RV_DMA_BUS_TAG 1 +`define RV_IFU_BUS_ID 1 +`define RV_IFU_BUS_PRTY 2 +`define RV_IFU_BUS_TAG 3 +`define RV_LSU_BUS_ID 1 +`define RV_LSU_BUS_PRTY 2 +`define RV_LSU_BUS_TAG 3 +`define RV_SB_BUS_ID 1 +`define RV_SB_BUS_PRTY 2 +`define RV_SB_BUS_TAG 1 +`define RV_CONFIG_KEY 32'hdeadbeef +`define RV_BITMANIP_ZBA 1 +`define RV_BITMANIP_ZBB 1 +`define RV_BITMANIP_ZBC 1 +`define RV_BITMANIP_ZBE 0 +`define RV_BITMANIP_ZBF 0 +`define RV_BITMANIP_ZBP 0 +`define RV_BITMANIP_ZBR 0 +`define RV_BITMANIP_ZBS 1 +`define RV_DIV_BIT 4 +`define RV_DIV_NEW 1 +`define RV_DMA_BUF_DEPTH 5 +`define RV_FAST_INTERRUPT_REDIRECT 1 +`define RV_ICCM_ONLY 1 +`define RV_LSU2DMA 0 +`define RV_LSU_NUM_NBLOAD 4 +`define RV_LSU_NUM_NBLOAD_WIDTH 2 +`define RV_LSU_STBUF_DEPTH 4 +`define RV_TIMER_LEGAL_EN 1 +`define RV_DCCM_BANK_BITS 2 +`define RV_DCCM_BITS 18 +`define RV_DCCM_BYTE_WIDTH 4 +`define RV_DCCM_DATA_CELL ram_16384x39 +`define RV_DCCM_DATA_WIDTH 32 +`define RV_DCCM_EADR 32'h5003ffff +`define RV_DCCM_ECC_WIDTH 7 +`define RV_DCCM_ENABLE 1 +`define RV_DCCM_FDATA_WIDTH 39 +`define RV_DCCM_INDEX_BITS 14 +`define RV_DCCM_NUM_BANKS 4 +`define RV_DCCM_NUM_BANKS_4 +`define RV_DCCM_OFFSET 28'h00000 +`define RV_DCCM_REGION 4'h5 +`define RV_DCCM_RESERVED 'h1400 +`define RV_DCCM_ROWS 16384 +`define RV_DCCM_SADR 32'h50000000 +`define RV_DCCM_SIZE 256 +`define RV_DCCM_SIZE_256 +`define RV_DCCM_WIDTH_BITS 2 +`define RV_LSU_SB_BITS 18 +`define RV_ICACHE_2BANKS 1 +`define RV_ICACHE_BANK_BITS 1 +`define RV_ICACHE_BANK_HI 3 +`define RV_ICACHE_BANK_LO 3 +`define RV_ICACHE_BANK_WIDTH 8 +`define RV_ICACHE_BANKS_WAY 2 +`define RV_ICACHE_BEAT_ADDR_HI 5 +`define RV_ICACHE_BEAT_BITS 3 +`define RV_ICACHE_BYPASS_ENABLE 1 +`define RV_ICACHE_DATA_CELL ram_512x71 +`define RV_ICACHE_DATA_DEPTH 512 +`define RV_ICACHE_DATA_INDEX_LO 4 +`define RV_ICACHE_DATA_WIDTH 64 +`define RV_ICACHE_ECC 1 +`define RV_ICACHE_FDATA_WIDTH 71 +`define RV_ICACHE_INDEX_HI 12 +`define RV_ICACHE_LN_SZ 64 +`define RV_ICACHE_NUM_BEATS 8 +`define RV_ICACHE_NUM_BYPASS 2 +`define RV_ICACHE_NUM_BYPASS_WIDTH 2 +`define RV_ICACHE_NUM_LINES 256 +`define RV_ICACHE_NUM_LINES_BANK 64 +`define RV_ICACHE_NUM_LINES_WAY 128 +`define RV_ICACHE_NUM_WAYS 2 +`define RV_ICACHE_SCND_LAST 6 +`define RV_ICACHE_SIZE 16 +`define RV_ICACHE_STATUS_BITS 1 +`define RV_ICACHE_TAG_BYPASS_ENABLE 1 +`define RV_ICACHE_TAG_CELL ram_128x25 +`define RV_ICACHE_TAG_DEPTH 128 +`define RV_ICACHE_TAG_INDEX_LO 6 +`define RV_ICACHE_TAG_LO 13 +`define RV_ICACHE_TAG_NUM_BYPASS 2 +`define RV_ICACHE_TAG_NUM_BYPASS_WIDTH 2 +`define RV_ICACHE_WAYPACK 1 +`define RV_ICCM_BANK_BITS 2 +`define RV_ICCM_BANK_HI 3 +`define RV_ICCM_BANK_INDEX_LO 4 +`define RV_ICCM_BITS 18 +`define RV_ICCM_DATA_CELL ram_16384x39 +`define RV_ICCM_EADR 32'h4003ffff +`define RV_ICCM_ECC_WIDTH 7 +`define RV_ICCM_ENABLE 1 +`define RV_ICCM_INDEX_BITS 14 +`define RV_ICCM_NUM_BANKS 4 +`define RV_ICCM_NUM_BANKS_4 +`define RV_ICCM_OFFSET 10'h0 +`define RV_ICCM_REGION 4'h4 +`define RV_ICCM_RESERVED 'h1000 +`define RV_ICCM_ROWS 16384 +`define RV_ICCM_SADR 32'h40000000 +`define RV_ICCM_SIZE 256 +`define RV_ICCM_SIZE_256 +`define RV_DEBUG_SB_MEM 'hc0580000 +`define RV_EXTERNAL_DATA 'he0580000 +`define RV_EXTERNAL_DATA_1 'hd0000000 +`define RV_SERIALIO 'hf0580000 +`define RV_UNUSED_REGION0 'hb0000000 +`define RV_UNUSED_REGION1 'ha0000000 +`define RV_UNUSED_REGION2 'h90000000 +`define RV_UNUSED_REGION3 'h80000000 +`define RV_UNUSED_REGION4 'h70000000 +`define RV_UNUSED_REGION5 'h30000000 +`define RV_UNUSED_REGION6 'h20000000 +`define RV_UNUSED_REGION7 'h10000000 +`define RV_NMI_VEC 'h11110000 +`define RV_NUMIREGS 32 +`define RV_PIC_BASE_ADDR 32'h60000000 +`define RV_PIC_BITS 15 +`define RV_PIC_INT_WORDS 1 +`define RV_PIC_MEIE_COUNT 31 +`define RV_PIC_MEIE_MASK 'h1 +`define RV_PIC_MEIE_OFFSET 'h2000 +`define RV_PIC_MEIGWCLR_COUNT 31 +`define RV_PIC_MEIGWCLR_MASK 'h0 +`define RV_PIC_MEIGWCLR_OFFSET 'h5000 +`define RV_PIC_MEIGWCTRL_COUNT 31 +`define RV_PIC_MEIGWCTRL_MASK 'h3 +`define RV_PIC_MEIGWCTRL_OFFSET 'h4000 +`define RV_PIC_MEIP_COUNT 1 +`define RV_PIC_MEIP_MASK 'h0 +`define RV_PIC_MEIP_OFFSET 'h1000 +`define RV_PIC_MEIPL_COUNT 31 +`define RV_PIC_MEIPL_MASK 'hf +`define RV_PIC_MEIPL_OFFSET 'h0000 +`define RV_PIC_MEIPT_COUNT 31 +`define RV_PIC_MEIPT_MASK 'h0 +`define RV_PIC_MEIPT_OFFSET 'h3004 +`define RV_PIC_MPICCFG_COUNT 1 +`define RV_PIC_MPICCFG_MASK 'h1 +`define RV_PIC_MPICCFG_OFFSET 'h3000 +`define RV_PIC_OFFSET 10'h0 +`define RV_PIC_REGION 4'h6 +`define RV_PIC_SIZE 32 +`define RV_PIC_TOTAL_INT 31 +`define RV_PIC_TOTAL_INT_PLUS1 32 +`define RV_DATA_ACCESS_ADDR0 'h00000000 +`define RV_DATA_ACCESS_ADDR1 'h00000000 +`define RV_DATA_ACCESS_ADDR2 'h00000000 +`define RV_DATA_ACCESS_ADDR3 'h00000000 +`define RV_DATA_ACCESS_ADDR4 'h00000000 +`define RV_DATA_ACCESS_ADDR5 'h00000000 +`define RV_DATA_ACCESS_ADDR6 'h00000000 +`define RV_DATA_ACCESS_ADDR7 'h00000000 +`define RV_DATA_ACCESS_ENABLE0 1'h0 +`define RV_DATA_ACCESS_ENABLE1 1'h0 +`define RV_DATA_ACCESS_ENABLE2 1'h0 +`define RV_DATA_ACCESS_ENABLE3 1'h0 +`define RV_DATA_ACCESS_ENABLE4 1'h0 +`define RV_DATA_ACCESS_ENABLE5 1'h0 +`define RV_DATA_ACCESS_ENABLE6 1'h0 +`define RV_DATA_ACCESS_ENABLE7 1'h0 +`define RV_DATA_ACCESS_MASK0 'hffffffff +`define RV_DATA_ACCESS_MASK1 'hffffffff +`define RV_DATA_ACCESS_MASK2 'hffffffff +`define RV_DATA_ACCESS_MASK3 'hffffffff +`define RV_DATA_ACCESS_MASK4 'hffffffff +`define RV_DATA_ACCESS_MASK5 'hffffffff +`define RV_DATA_ACCESS_MASK6 'hffffffff +`define RV_DATA_ACCESS_MASK7 'hffffffff +`define RV_INST_ACCESS_ADDR0 'h00000000 +`define RV_INST_ACCESS_ADDR1 'h00000000 +`define RV_INST_ACCESS_ADDR2 'h00000000 +`define RV_INST_ACCESS_ADDR3 'h00000000 +`define RV_INST_ACCESS_ADDR4 'h00000000 +`define RV_INST_ACCESS_ADDR5 'h00000000 +`define RV_INST_ACCESS_ADDR6 'h00000000 +`define RV_INST_ACCESS_ADDR7 'h00000000 +`define RV_INST_ACCESS_ENABLE0 1'h0 +`define RV_INST_ACCESS_ENABLE1 1'h0 +`define RV_INST_ACCESS_ENABLE2 1'h0 +`define RV_INST_ACCESS_ENABLE3 1'h0 +`define RV_INST_ACCESS_ENABLE4 1'h0 +`define RV_INST_ACCESS_ENABLE5 1'h0 +`define RV_INST_ACCESS_ENABLE6 1'h0 +`define RV_INST_ACCESS_ENABLE7 1'h0 +`define RV_INST_ACCESS_MASK0 'hffffffff +`define RV_INST_ACCESS_MASK1 'hffffffff +`define RV_INST_ACCESS_MASK2 'hffffffff +`define RV_INST_ACCESS_MASK3 'hffffffff +`define RV_INST_ACCESS_MASK4 'hffffffff +`define RV_INST_ACCESS_MASK5 'hffffffff +`define RV_INST_ACCESS_MASK6 'hffffffff +`define RV_INST_ACCESS_MASK7 'hffffffff +`define RV_PMP_ENTRIES 64 +`define REGWIDTH 32 +`define RV_RESET_VEC 'h00000000 +`define RV_RET_STACK_SIZE 8 +`define RV_TARGET default_ahb +`define TEC_RV_ICG clockhdr +`define CPU_TOP `RV_TOP.veer +//`define RV_TOP `TOP.rvtop +`define SDVT_AHB 1 +//`define TOP tb_top +`define RV_BUILD_AHB_LITE 1 +`define CLOCK_PERIOD 100 +`define RV_EXT_ADDRWIDTH 32 +`define RV_EXT_DATAWIDTH 64 +`define RV_LDERR_ROLLBACK 1 +`define RV_STERR_ROLLBACK 0 +`define RV_XLEN 32 +`ifndef SYNTHESIS +`ifndef VERILATOR + `define RV_ASSERT_ON +`endif +`endif + +`endif // RV_COMMON_DEFINES diff --git a/designs/Caliptra/src/caliptra-rtl/config_defines.svh b/designs/Caliptra/src/caliptra-rtl/config_defines.svh new file mode 100755 index 0000000..34e7a1a --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/config_defines.svh @@ -0,0 +1,111 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +// +`ifndef CALIPTRA_CFG_SV +`define CALIPTRA_CFG_SV + + `define CALIPTRA + +// Uncomment to enable Caliptra Internal TRNG +//`define CALIPTRA_INTERNAL_TRNG + +// Uncomment if fuse granularity 32 bits. +//`define CALIPTRA_FUSE_GRANULARITY_32 + + `define CALIPTRA_AHB_SLAVES_NUM 5'd17 // Number of slaves AHB + `define CALIPTRA_AHB_MASTERS_NUM 4'd1 // Number of masters AHB + `define CALIPTRA_AHB_HADDR_SIZE 32 // bit-width AHB address haddr + `define CALIPTRA_AHB_HDATA_SIZE 64 // bit-width AHB data + `define CALIPTRA_AXI_DATA_WIDTH 32 // bit-width AXI data + `define CALIPTRA_AXI_USER_WIDTH 32 // bit-width AXI USER field + `define CALIPTRA_AXI_ID_WIDTH 8 // bit-width AXI ID field + // Overrideable for lint checks + `ifndef CALIPTRA_AXI_DMA_ADDR_WIDTH + `define CALIPTRA_AXI_DMA_ADDR_WIDTH 48 + `endif + `define CALIPTRA_SOC_SEC_STATE_WIDTH 3 + + // AHB Address Map + `define CALIPTRA_SLAVE_NAMES {"SHA3" , "AES" , "MLDSA" , "ENTROPY_SRC", "CSRNG" , "IMEM" , "SHA256" , "VEER_ICCM_DMA", "VEER_DCCM_DMA", "SOC_IFC" , "SHA512" , "DATAVAULT" , "PCRVAULT" , "KEYVAULT" , "HMAC" , "ECC" , "DOE_CTRL" } /* Array of names for peripherals */ + `define CALIPTRA_SLAVE_BASE_ADDR {32'h1004_0000, 32'h1001_1000, 32'h1003_0000, 32'h2000_3000, 32'h2000_2000, 32'h0000_0000, 32'h1002_8000, 32'h4000_0000 , 32'h5000_0000 , 32'h3000_0000, 32'h1002_0000, 32'h1001_C000, 32'h1001_A000, 32'h1001_8000, 32'h1001_0000, 32'h1000_8000, 32'h1000_0000} /* Array with slave base address */ + `define CALIPTRA_SLAVE_MASK_ADDR {32'h1004_1FFF, 32'h1001_1FFF, 32'h1003_FFFF, 32'h2000_3FFF, 32'h2000_2FFF, 32'h0001_7FFF, 32'h1002_FFFF, 32'h4003_FFFF , 32'h5003_FFFF , 32'h3007_FFFF, 32'h1002_7FFF, 32'h1001_DFFF, 32'h1001_BFFF, 32'h1001_9FFF, 32'h1001_0FFF, 32'h1000_FFFF, 32'h1000_7FFF} /* Array with slave offset address */ + `define CALIPTRA_SLAVE_ADDR_MASK (`CALIPTRA_SLAVE_BASE_ADDR ^ `CALIPTRA_SLAVE_MASK_ADDR) /* Array indicating meaningful address bits for each slave */ + `define CALIPTRA_SLAVE_ADDR_WIDTH(n) $clog2((`CALIPTRA_SLAVE_ADDR_MASK >> (`CALIPTRA_AHB_HADDR_SIZE*n)) & {`CALIPTRA_AHB_HADDR_SIZE{1'b1}}) /* Decode address width for each slave from assigned BASE/MASK address */ + `define CALIPTRA_SLAVE_SEL_DOE 0 + `define CALIPTRA_SLAVE_SEL_ECC 1 + `define CALIPTRA_SLAVE_SEL_HMAC 2 + `define CALIPTRA_SLAVE_SEL_KV 3 + `define CALIPTRA_SLAVE_SEL_PV 4 + `define CALIPTRA_SLAVE_SEL_DV 5 + `define CALIPTRA_SLAVE_SEL_SHA512 6 + `define CALIPTRA_SLAVE_SEL_SOC_IFC 7 + `define CALIPTRA_SLAVE_SEL_DDMA 8 + `define CALIPTRA_SLAVE_SEL_IDMA 9 + `define CALIPTRA_SLAVE_SEL_SHA256 10 + `define CALIPTRA_SLAVE_SEL_IMEM 11 + `define CALIPTRA_SLAVE_SEL_CSRNG 12 + `define CALIPTRA_SLAVE_SEL_ENTROPY_SRC 13 + `define CALIPTRA_SLAVE_SEL_MLDSA 14 + `define CALIPTRA_SLAVE_SEL_AES 15 + `define CALIPTRA_SLAVE_SEL_SHA3 16 + + // Interrupt Assignments + // NOTE Vector 0 is reserved by VeeR + `define VEER_INTR_VEC_DOE_ERROR 1 + `define VEER_INTR_VEC_DOE_NOTIF 2 + `define VEER_INTR_VEC_ECC_ERROR 3 + `define VEER_INTR_VEC_ECC_NOTIF 4 + `define VEER_INTR_VEC_HMAC_ERROR 5 + `define VEER_INTR_VEC_HMAC_NOTIF 6 + `define VEER_INTR_VEC_KV_ERROR 7 + `define VEER_INTR_VEC_KV_NOTIF 8 + `define VEER_INTR_VEC_SHA512_ERROR 9 + `define VEER_INTR_VEC_SHA512_NOTIF 10 + `define VEER_INTR_VEC_SHA256_ERROR 11 + `define VEER_INTR_VEC_SHA256_NOTIF 12 + `define VEER_INTR_VEC_RSVD0_ERROR 13 + `define VEER_INTR_VEC_RSVD0_NOTIF 14 + `define VEER_INTR_VEC_RSVD1_ERROR 15 + `define VEER_INTR_VEC_RSVD1_NOTIF 16 + `define VEER_INTR_VEC_SHA3_ERROR 17 + `define VEER_INTR_VEC_SHA3_NOTIF 18 + `define VEER_INTR_VEC_SOC_IFC_ERROR 19 + `define VEER_INTR_VEC_SOC_IFC_NOTIF 20 + `define VEER_INTR_VEC_SHA_ERROR 21 + `define VEER_INTR_VEC_SHA_NOTIF 22 + `define VEER_INTR_VEC_ABR_ERROR 23 + `define VEER_INTR_VEC_ABR_NOTIF 24 + `define VEER_INTR_VEC_AXI_DMA_ERROR 25 + `define VEER_INTR_VEC_AXI_DMA_NOTIF 26 + // Used to tie-off unused upper intr bits + `define VEER_INTR_VEC_MAX_ASSIGNED `VEER_INTR_VEC_AXI_DMA_NOTIF + + //`define CALIPTRA_KV_NUM_READ 6 + //`define CALIPTRA_KV_NUM_WRITE 4 + + `define CALIPTRA_IMEM_BYTE_SIZE 98304 + `define CALIPTRA_IMEM_DATA_WIDTH 64 + `define CALIPTRA_IMEM_DEPTH `CALIPTRA_IMEM_BYTE_SIZE / (`CALIPTRA_IMEM_DATA_WIDTH/8) + `define CALIPTRA_IMEM_BYTE_ADDR_W $clog2(`CALIPTRA_IMEM_BYTE_SIZE) + `define CALIPTRA_IMEM_ADDR_WIDTH $clog2(`CALIPTRA_IMEM_DEPTH) + + `define CALIPTRA_TOP caliptra_top_tb + `define CALIPTRA_RV_TOP `CALIPTRA_TOP.caliptra_top_dut + + `define RV_TOP `CALIPTRA_RV_TOP.rvtop + + `define CALIPTRA_ICG cptra_clk_gate + +`endif + diff --git a/designs/Caliptra/src/caliptra-rtl/csrng.sv b/designs/Caliptra/src/caliptra-rtl/csrng.sv new file mode 100644 index 0000000..16d8f0f --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/csrng.sv @@ -0,0 +1,241 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Description: csrng top level wrapper file + +`include "caliptra_prim_assert.sv" + +module csrng + import csrng_pkg::*; + import csrng_reg_pkg::*; + import lc_ctrl_state_pkg::*; + import lc_ctrl_reg_pkg::*; + import lc_ctrl_pkg::*; +#( + parameter aes_pkg::sbox_impl_e SBoxImpl = aes_pkg::SBoxImplCanright, + parameter logic [csrng_reg_pkg::NumAlerts-1:0] AlertAsyncOn = {csrng_reg_pkg::NumAlerts{1'b1}}, + parameter logic [31:0] NHwApps = 2, + parameter cs_keymgr_div_t RndCnstCsKeymgrDivNonProduction = CsKeymgrDivWidth'(0), + parameter cs_keymgr_div_t RndCnstCsKeymgrDivProduction = CsKeymgrDivWidth'(0), + parameter AHBDataWidth = 64, + parameter AHBAddrWidth = 32 +) ( + input logic clk_i, + input logic rst_ni, + + // AMBA AHB Lite Interface + input logic [AHBAddrWidth-1:0] haddr_i, + input logic [AHBDataWidth-1:0] hwdata_i, + input logic hsel_i, + input logic hwrite_i, + input logic hready_i, + input logic [1:0] htrans_i, + input logic [2:0] hsize_i, + + output logic hresp_o, + output logic hreadyout_o, + output logic [AHBDataWidth-1:0] hrdata_o, + + + + // OTP Interface + // SEC_CM: INTERSIG.MUBI + input caliptra_prim_mubi_pkg::mubi8_t otp_en_csrng_sw_app_read_i, + + // Lifecycle broadcast inputs + input lc_ctrl_pkg::lc_tx_t lc_hw_debug_en_i, + + // Entropy Interface + output entropy_src_pkg::entropy_src_hw_if_req_t entropy_src_hw_if_o, + input entropy_src_pkg::entropy_src_hw_if_rsp_t entropy_src_hw_if_i, + + // Entropy Interface + input entropy_src_pkg::cs_aes_halt_req_t cs_aes_halt_i, + output entropy_src_pkg::cs_aes_halt_rsp_t cs_aes_halt_o, + + // Application Interfaces + input csrng_req_t [NHwApps-1:0] csrng_cmd_i, + output csrng_rsp_t [NHwApps-1:0] csrng_cmd_o, + + // Alerts + input caliptra_prim_alert_pkg::alert_rx_t [csrng_reg_pkg::NumAlerts-1:0] alert_rx_i, + output caliptra_prim_alert_pkg::alert_tx_t [csrng_reg_pkg::NumAlerts-1:0] alert_tx_o, + + // Interrupts + output logic intr_cs_cmd_req_done_o, + output logic intr_cs_entropy_req_o, + output logic intr_cs_hw_inst_exc_o, + output logic intr_cs_fatal_err_o +); + + csrng_reg2hw_t reg2hw; + csrng_hw2reg_t hw2reg; + + logic [csrng_reg_pkg::NumAlerts-1:0] alert_test; + logic [csrng_reg_pkg::NumAlerts-1:0] alert; + + logic [csrng_reg_pkg::NumAlerts-1:0] intg_err_alert; + assign intg_err_alert[0] = 1'b0; + + // SEC_CM: CONFIG.REGWEN + // SEC_CM: TILE_LINK.BUS.INTEGRITY + + csrng_reg_top #( + .AHBDataWidth(AHBDataWidth), + .AHBAddrWidth(AHBAddrWidth) + ) u_reg ( + .clk_i, + .rst_ni, + .haddr_i, + .hwdata_i, + .hsel_i, + .hwrite_i, + .hready_i, + .htrans_i, + .hsize_i, + .hresp_o, + .hreadyout_o, + .hrdata_o, + .reg2hw, + .hw2reg, + .intg_err_o(intg_err_alert[1]) + ); + + csrng_core #( + .SBoxImpl(SBoxImpl), + .NHwApps(NHwApps), + .RndCnstCsKeymgrDivNonProduction(RndCnstCsKeymgrDivNonProduction), + .RndCnstCsKeymgrDivProduction(RndCnstCsKeymgrDivProduction) + ) u_csrng_core ( + .clk_i, + .rst_ni, + .reg2hw, + .hw2reg, + + // misc inputs + .otp_en_csrng_sw_app_read_i(otp_en_csrng_sw_app_read_i), + .lc_hw_debug_en_i, + + // Entropy Interface + .entropy_src_hw_if_o, + .entropy_src_hw_if_i, + + // Entropy Interface + .cs_aes_halt_i, + .cs_aes_halt_o, + + // Application Interfaces + .csrng_cmd_i, + .csrng_cmd_o, + + // Alerts + .recov_alert_test_o(alert_test[0]), + .fatal_alert_test_o(alert_test[1]), + .recov_alert_o(alert[0]), + .fatal_alert_o(alert[1]), + + .intr_cs_cmd_req_done_o, + .intr_cs_entropy_req_o, + .intr_cs_hw_inst_exc_o, + .intr_cs_fatal_err_o + ); + + + /////////////////////////// + // Alert generation + /////////////////////////// + for (genvar i = 0; i < csrng_reg_pkg::NumAlerts; i++) begin : gen_alert_tx + caliptra_prim_alert_sender #( + .AsyncOn(AlertAsyncOn[i]), + .IsFatal(i) + ) u_caliptra_prim_alert_sender ( + .clk_i, + .rst_ni, + .alert_test_i (alert_test[i] ), + .alert_req_i (alert[i] || intg_err_alert[i] ), + .alert_ack_o (), + .alert_state_o (), + .alert_rx_i (alert_rx_i[i] ), + .alert_tx_o (alert_tx_o[i] ) + ); + end + + + // Assertions + + `CALIPTRA_ASSERT_KNOWN(AHBRespKnownO_A, hresp_o) + `CALIPTRA_ASSERT_KNOWN(AHBReadyKnownO_A, hreadyout_o) + `CALIPTRA_ASSERT_KNOWN(EsReqKnownO_A, entropy_src_hw_if_o.es_req) + + // Application Interface Asserts + for (genvar i = 0; i < NHwApps; i = i+1) begin : gen_app_if_asserts + `CALIPTRA_ASSERT_KNOWN(CsrngReqReadyKnownO_A, csrng_cmd_o[i].csrng_req_ready) + `CALIPTRA_ASSERT_KNOWN(CsrngRspAckKnownO_A, csrng_cmd_o[i].csrng_rsp_ack) + `CALIPTRA_ASSERT_KNOWN(CsrngRspStsKnownO_A, csrng_cmd_o[i].csrng_rsp_sts) + `CALIPTRA_ASSERT_KNOWN(CsrngGenbitsValidKnownO_A, csrng_cmd_o[i].genbits_valid) + `CALIPTRA_ASSERT_KNOWN_IF(CsrngGenbitsFipsKnownO_A, csrng_cmd_o[i].genbits_fips, + csrng_cmd_o[i].genbits_valid) + `CALIPTRA_ASSERT_KNOWN_IF(CsrngGenbitsBusKnownO_A, csrng_cmd_o[i].genbits_bus, + csrng_cmd_o[i].genbits_valid) + end : gen_app_if_asserts + + // Alerts + `CALIPTRA_ASSERT_KNOWN(AlertTxKnownO_A, alert_tx_o) + + `CALIPTRA_ASSERT_KNOWN(IntrCsCmdReqDoneKnownO_A, intr_cs_cmd_req_done_o) + `CALIPTRA_ASSERT_KNOWN(IntrCsEntropyReqKnownO_A, intr_cs_entropy_req_o) + `CALIPTRA_ASSERT_KNOWN(IntrCsHwInstExcKnownO_A, intr_cs_hw_inst_exc_o) + `CALIPTRA_ASSERT_KNOWN(IntrCsFatalErrKnownO_A, intr_cs_fatal_err_o) + + `CALIPTRA_ASSERT_PRIM_COUNT_ERROR_TRIGGER_ALERT(CtrDrbgUpdAlertCheck_A, + u_csrng_core.u_csrng_ctr_drbg_upd.u_caliptra_prim_count_ctr_drbg, + alert_tx_o[1]) + + `CALIPTRA_ASSERT_PRIM_COUNT_ERROR_TRIGGER_ALERT(CtrDrbgGenAlertCheck_A, + u_csrng_core.u_csrng_ctr_drbg_gen.u_caliptra_prim_count_ctr_drbg, + alert_tx_o[1]) + + for (genvar i = 0; i < NHwApps + 1; i++) begin : gen_cnt_asserts + `CALIPTRA_ASSERT_PRIM_COUNT_ERROR_TRIGGER_ALERT(CntAlertCheck_A, + u_csrng_core.gen_cmd_stage[i].u_csrng_cmd_stage.u_caliptra_prim_count_cmd_gen_cntr, + alert_tx_o[1]) + + `CALIPTRA_ASSERT_PRIM_FSM_ERROR_TRIGGER_ALERT(DrbgCmdFsmCheck_A, + u_csrng_core.gen_cmd_stage[i].u_csrng_cmd_stage.u_state_regs, + alert_tx_o[1]) + end + + `CALIPTRA_ASSERT_PRIM_FSM_ERROR_TRIGGER_ALERT(CtrlMainFsmCheck_A, + u_csrng_core.u_csrng_main_sm.u_state_regs, + alert_tx_o[1]) + + `CALIPTRA_ASSERT_PRIM_FSM_ERROR_TRIGGER_ALERT(DrbgGenFsmCheck_A, + u_csrng_core.u_csrng_ctr_drbg_gen.u_state_regs, + alert_tx_o[1]) + + `CALIPTRA_ASSERT_PRIM_FSM_ERROR_TRIGGER_ALERT(DrbgUpdBlkEncFsmCheck_A, + u_csrng_core.u_csrng_ctr_drbg_upd.u_blk_enc_state_regs, + alert_tx_o[1]) + + `CALIPTRA_ASSERT_PRIM_FSM_ERROR_TRIGGER_ALERT(DrbgUpdOutBlkFsmCheck_A, + u_csrng_core.u_csrng_ctr_drbg_upd.u_outblk_state_regs, + alert_tx_o[1]) + + for (genvar i = 0; i < aes_pkg::Sp2VWidth; i++) begin : gen_aes_cipher_control_fsm_svas + if (aes_pkg::SP2V_LOGIC_HIGH[i] == 1'b1) begin : gen_aes_cipher_control_fsm_svas_p + `CALIPTRA_ASSERT_PRIM_FSM_ERROR_TRIGGER_ALERT(AesCipherControlFsmCheck_A, + u_csrng_core.u_csrng_block_encrypt.u_aes_cipher_core.u_aes_cipher_control.gen_fsm[i]. + gen_fsm_p.u_aes_cipher_control_fsm_i.u_aes_cipher_control_fsm.u_state_regs, + alert_tx_o[1]) + end else begin : gen_aes_cipher_control_fsm_svas_n + `CALIPTRA_ASSERT_PRIM_FSM_ERROR_TRIGGER_ALERT(AesCipherControlFsmCheck_A, + u_csrng_core.u_csrng_block_encrypt.u_aes_cipher_core.u_aes_cipher_control.gen_fsm[i]. + gen_fsm_n.u_aes_cipher_control_fsm_i.u_aes_cipher_control_fsm.u_state_regs, + alert_tx_o[1]) + end + end + + // Alert assertions for reg_we onehot check + `CALIPTRA_ASSERT_PRIM_REG_WE_ONEHOT_ERROR_TRIGGER_ALERT(RegWeOnehotCheck_A, u_reg, alert_tx_o[1]) +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/csrng_block_encrypt.sv b/designs/Caliptra/src/caliptra-rtl/csrng_block_encrypt.sv new file mode 100644 index 0000000..c20664b --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/csrng_block_encrypt.sv @@ -0,0 +1,191 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Description: csrng block encrypt module +// + +module csrng_block_encrypt import csrng_pkg::*; #( + parameter aes_pkg::sbox_impl_e SBoxImpl = aes_pkg::SBoxImplLut, + parameter logic [31:0] Cmd = 3, + parameter logic [31:0] StateId = 4, + parameter logic [31:0] BlkLen = 128, + parameter logic [31:0] KeyLen = 256 +) ( + input logic clk_i, + input logic rst_ni, + + // update interface + input logic block_encrypt_enable_i, + input logic block_encrypt_req_i, + output logic block_encrypt_rdy_o, + input logic [KeyLen-1:0] block_encrypt_key_i, + input logic [BlkLen-1:0] block_encrypt_v_i, + input logic [Cmd-1:0] block_encrypt_cmd_i, + input logic [StateId-1:0] block_encrypt_id_i, + output logic block_encrypt_ack_o, + input logic block_encrypt_rdy_i, + output logic [Cmd-1:0] block_encrypt_cmd_o, + output logic [StateId-1:0] block_encrypt_id_o, + output logic [BlkLen-1:0] block_encrypt_v_o, + output logic block_encrypt_quiet_o, + output logic block_encrypt_aes_cipher_sm_err_o, + output logic [2:0] block_encrypt_sfifo_blkenc_err_o +); + + localparam logic[31:0] BlkEncFifoDepth = 1; + localparam logic[31:0] BlkEncFifoWidth = StateId+Cmd; + localparam logic[31:0] NumShares = 1; + + // signals + // blk_encrypt_in fifo + logic [BlkEncFifoWidth-1:0] sfifo_blkenc_rdata; + logic sfifo_blkenc_push; + logic [BlkEncFifoWidth-1:0] sfifo_blkenc_wdata; + logic sfifo_blkenc_pop; + logic sfifo_blkenc_full; + logic sfifo_blkenc_not_empty; + // breakout + logic [Cmd-1:0] sfifo_blkenc_cmd; + logic [StateId-1:0] sfifo_blkenc_id; + + aes_pkg::sp2v_e cipher_in_valid; + aes_pkg::sp2v_e cipher_in_ready; + aes_pkg::sp2v_e cipher_out_valid; + aes_pkg::sp2v_e cipher_out_ready; + aes_pkg::sp2v_e cipher_crypt_busy; + logic [BlkLen-1:0] cipher_data_out; + logic aes_cipher_core_enable; + + logic [3:0][3:0][7:0] state_init[NumShares]; + + logic [7:0][31:0] key_init[NumShares]; + logic [3:0][3:0][7:0] state_done[NumShares]; + logic [3:0][3:0][7:0] state_out; + + assign state_init[0] = aes_pkg::aes_transpose({<<8{block_encrypt_v_i}}); + + assign key_init[0] = {<<8{block_encrypt_key_i}}; + assign state_out = aes_pkg::aes_transpose(state_done[0]); + assign cipher_data_out = {<<8{state_out}}; + + + //-------------------------------------------- + // aes cipher core lifecycle enable + //-------------------------------------------- + + assign aes_cipher_core_enable = block_encrypt_enable_i; + + //-------------------------------------------- + // aes cipher core + //-------------------------------------------- + assign cipher_in_valid = (aes_cipher_core_enable && block_encrypt_req_i) ? + aes_pkg::SP2V_HIGH : aes_pkg::SP2V_LOW; + + // SEC_CM: AES_CIPHER.FSM.SPARSE + // SEC_CM: AES_CIPHER.FSM.REDUN + // SEC_CM: AES_CIPHER.CTRL.SPARSE + // SEC_CM: AES_CIPHER.FSM.LOCAL_ESC + // SEC_CM: AES_CIPHER.CTR.REDUN + // SEC_CM: AES_CIPHER.DATA_REG.LOCAL_ESC + + aes_cipher_core #( + .AES192Enable ( 1'b0 ), // AES192Enable disabled + .CiphOpFwdOnly ( 1'b1 ), // Forward operation only + .SecMasking ( 1'b0 ), // Masking disable + .SecSBoxImpl ( SBoxImpl ) + ) u_aes_cipher_core ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + .cfg_valid_i ( 1'b1 ), + .in_valid_i ( cipher_in_valid ), + .in_ready_o ( cipher_in_ready ), + .out_valid_o ( cipher_out_valid ), + .out_ready_i ( cipher_out_ready ), + .op_i ( aes_pkg::CIPH_FWD ), + .key_len_i ( aes_pkg::AES_256 ), + .crypt_i ( aes_pkg::SP2V_HIGH ), // Enable + .crypt_o ( cipher_crypt_busy ), + .alert_fatal_i ( 1'b0 ), + .alert_o ( block_encrypt_aes_cipher_sm_err_o), + .dec_key_gen_i ( aes_pkg::SP2V_LOW ), // Disable + .dec_key_gen_o ( ), + .prng_reseed_i ( 1'b0 ), // Disable + .prng_reseed_o ( ), + .key_clear_i ( 1'b0 ), // Disable + .key_clear_o ( ), + .data_out_clear_i ( 1'b0 ), // Disable + .data_out_clear_o ( ), + .prd_clearing_state_i ( state_init ), // Providing this value allows synthesis + // to perform optimizations. We don't + // care about SCA leakage in this context. + .prd_clearing_key_i ( key_init ), // This input is not used. Providing this + // value allows synthesis to perform + // optimizations. + .force_masks_i ( 1'b0 ), + .data_in_mask_o ( ), + .entropy_req_o ( ), + .entropy_ack_i ( 1'b0 ), + .entropy_i ( '0 ), + + .state_init_i ( state_init ), + .key_init_i ( key_init ), + .state_o ( state_done ) + ); + + + //-------------------------------------------- + // cmd / id tracking fifo + //-------------------------------------------- + + caliptra_prim_fifo_sync #( + .Width(BlkEncFifoWidth), + .Pass(0), + .Depth(BlkEncFifoDepth) + ) u_caliptra_prim_fifo_sync_blkenc ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .clr_i (!block_encrypt_enable_i), + .wvalid_i (sfifo_blkenc_push), + .wready_o (), + .wdata_i (sfifo_blkenc_wdata), + .rvalid_o (sfifo_blkenc_not_empty), + .rready_i (sfifo_blkenc_pop), + .rdata_o (sfifo_blkenc_rdata), + .full_o (sfifo_blkenc_full), + .depth_o (), + .err_o () + ); + + assign sfifo_blkenc_push = block_encrypt_req_i && !sfifo_blkenc_full; + assign sfifo_blkenc_wdata = {block_encrypt_id_i,block_encrypt_cmd_i}; + + assign block_encrypt_rdy_o = (cipher_in_ready == aes_pkg::SP2V_HIGH); + + assign sfifo_blkenc_pop = block_encrypt_ack_o; + assign {sfifo_blkenc_id,sfifo_blkenc_cmd} = sfifo_blkenc_rdata; + + assign block_encrypt_ack_o = block_encrypt_rdy_i && (cipher_out_valid == aes_pkg::SP2V_HIGH); + + assign block_encrypt_cmd_o = sfifo_blkenc_cmd; + assign block_encrypt_id_o = sfifo_blkenc_id; + assign block_encrypt_v_o = cipher_data_out; + + assign cipher_out_ready = block_encrypt_rdy_i ? aes_pkg::SP2V_HIGH : aes_pkg::SP2V_LOW; + + assign block_encrypt_sfifo_blkenc_err_o = + {(sfifo_blkenc_push && sfifo_blkenc_full), + (sfifo_blkenc_pop && !sfifo_blkenc_not_empty), + (sfifo_blkenc_full && !sfifo_blkenc_not_empty)}; + + //-------------------------------------------- + // idle detection + //-------------------------------------------- + + // simple aes cipher activity detector + assign block_encrypt_quiet_o = + ((cipher_in_valid == aes_pkg::SP2V_LOW) || (cipher_in_ready == aes_pkg::SP2V_LOW)) && + (cipher_crypt_busy == aes_pkg::SP2V_LOW); + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/csrng_cmd_stage.sv b/designs/Caliptra/src/caliptra-rtl/csrng_cmd_stage.sv new file mode 100644 index 0000000..8e16a5f --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/csrng_cmd_stage.sv @@ -0,0 +1,551 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Description: CSRNG command staging module. +// + +module csrng_cmd_stage import csrng_pkg::*; #( + parameter logic [31:0] CmdFifoWidth = 32, + parameter logic [31:0] CmdFifoDepth = 16, + parameter logic [31:0] StateId = 4 +) ( + input logic clk_i, + input logic rst_ni, + // Command input. + input logic cs_enable_i, + input logic cmd_stage_vld_i, + input logic [StateId-1:0] cmd_stage_shid_i, + input logic [CmdFifoWidth-1:0] cmd_stage_bus_i, + output logic cmd_stage_rdy_o, + // Command checking interface. + input logic reseed_cnt_reached_i, + output logic reseed_cnt_alert_o, + output logic invalid_cmd_seq_alert_o, + output logic invalid_acmd_alert_o, + // Command to arbiter. + output logic cmd_arb_req_o, + output logic cmd_arb_sop_o, + output logic cmd_arb_mop_o, + output logic cmd_arb_eop_o, + input logic cmd_arb_gnt_i, + output logic [CmdFifoWidth-1:0] cmd_arb_bus_o, + // Ack from core. + input logic cmd_ack_i, + input csrng_cmd_sts_e cmd_ack_sts_i, + // Ack to app i/f. + output logic cmd_stage_ack_o, + output csrng_cmd_sts_e cmd_stage_ack_sts_o, + // Genbits from core. + input logic genbits_vld_i, + input logic [127:0] genbits_bus_i, + input logic genbits_fips_i, + // Genbits to app i/f. + output logic genbits_vld_o, + input logic genbits_rdy_i, + output logic [127:0] genbits_bus_o, + output logic genbits_fips_o, + // Error indication. + output logic [2:0] cmd_stage_sfifo_cmd_err_o, + output logic [2:0] cmd_stage_sfifo_genbits_err_o, + output logic cmd_gen_cnt_err_o, + output logic cmd_stage_sm_err_o +); + + // Genbits parameters. + localparam logic[31:0] GenBitsFifoWidth = 1+128; + localparam logic[31:0] GenBitsFifoDepth = 1; + localparam logic[31:0] GenBitsCntrWidth = 12; + + // Command FIFO. + logic [CmdFifoWidth-1:0] sfifo_cmd_rdata; + logic [$clog2(CmdFifoDepth):0] sfifo_cmd_depth; + logic sfifo_cmd_push; + logic [CmdFifoWidth-1:0] sfifo_cmd_wdata; + logic sfifo_cmd_pop; + logic [2:0] sfifo_cmd_err; + logic sfifo_cmd_full; + logic sfifo_cmd_not_empty; + + // Genbits FIFO. + logic [GenBitsFifoWidth-1:0] sfifo_genbits_rdata; + logic sfifo_genbits_push; + logic [GenBitsFifoWidth-1:0] sfifo_genbits_wdata; + logic sfifo_genbits_pop; + logic [2:0] sfifo_genbits_err; + logic sfifo_genbits_full; + logic sfifo_genbits_not_empty; + + // Command signals. + logic [3:0] cmd_len; + logic cmd_fifo_zero; + logic cmd_fifo_pop; + logic cmd_len_dec; + logic cmd_gen_cnt_dec; + logic cmd_gen_1st_req; + logic cmd_gen_inc_req; + logic cmd_gen_cnt_last; + logic cmd_final_ack; + logic cmd_err_ack; + logic [GenBitsCntrWidth-1:0] cmd_gen_cnt; + csrng_cmd_sts_e err_sts; + logic reseed_cnt_exceeded; + logic invalid_cmd_seq; + logic invalid_acmd; + logic [2:0] acmd; + + // Flops. + logic cmd_ack_q, cmd_ack_d; + csrng_cmd_sts_e cmd_ack_sts_q, cmd_ack_sts_d; + logic [3:0] cmd_len_q, cmd_len_d; + logic cmd_gen_flag_q, cmd_gen_flag_d; + logic [11:0] cmd_gen_cmd_q, cmd_gen_cmd_d; + logic instantiated_d, instantiated_q; + + logic local_escalate; + + + always_ff @(posedge clk_i or negedge rst_ni) + if (!rst_ni) begin + cmd_ack_q <= '0; + cmd_ack_sts_q <= CMD_STS_SUCCESS; + cmd_len_q <= '0; + cmd_gen_flag_q <= '0; + cmd_gen_cmd_q <= '0; + instantiated_q <= '0; + end else begin + cmd_ack_q <= cmd_ack_d; + cmd_ack_sts_q <= cmd_ack_sts_d; + cmd_len_q <= cmd_len_d; + cmd_gen_flag_q <= cmd_gen_flag_d; + cmd_gen_cmd_q <= cmd_gen_cmd_d; + instantiated_q <= instantiated_d; + end + + assign cmd_stage_sfifo_cmd_err_o = sfifo_cmd_err; + assign cmd_stage_sfifo_genbits_err_o = sfifo_genbits_err; + + //--------------------------------------------------------- + // Capture the transfer length of data behind the command. + //--------------------------------------------------------- + + caliptra_prim_fifo_sync #( + .Width(CmdFifoWidth), + .Pass(0), + .Depth(CmdFifoDepth), + .OutputZeroIfEmpty(1'b0) + ) u_caliptra_prim_fifo_cmd ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .clr_i (!cs_enable_i), + .wvalid_i (sfifo_cmd_push), + .wready_o (), + .wdata_i (sfifo_cmd_wdata), + .rvalid_o (sfifo_cmd_not_empty), + .rready_i (sfifo_cmd_pop), + .rdata_o (sfifo_cmd_rdata), + .full_o (sfifo_cmd_full), + .depth_o (sfifo_cmd_depth), + .err_o () + ); + + assign sfifo_cmd_wdata = cmd_stage_bus_i; + + assign sfifo_cmd_push = cs_enable_i && cmd_stage_rdy_o && cmd_stage_vld_i; + + assign sfifo_cmd_pop = cs_enable_i && cmd_fifo_pop; + + assign cmd_arb_bus_o = + cmd_gen_inc_req ? {15'b0,cmd_gen_cnt_last,cmd_stage_shid_i,cmd_gen_cmd_q} : + // pad,glast,id,f,clen,cmd + cmd_gen_1st_req ? {15'b0,cmd_gen_cnt_last,cmd_stage_shid_i,sfifo_cmd_rdata[11:0]} : + cmd_arb_mop_o ? sfifo_cmd_rdata : + '0; + + assign cmd_stage_rdy_o = !sfifo_cmd_full; + + assign sfifo_cmd_err = + {(sfifo_cmd_push && sfifo_cmd_full), + (sfifo_cmd_pop && !sfifo_cmd_not_empty), + (sfifo_cmd_full && !sfifo_cmd_not_empty)}; + + + // State machine controls. + assign cmd_fifo_zero = (sfifo_cmd_depth == '0); + assign cmd_len = sfifo_cmd_rdata[7:4]; + + // Capture the length of csrng command. + assign cmd_len_d = + (!cs_enable_i) ? '0 : + cmd_arb_sop_o ? cmd_len : + cmd_len_dec ? (cmd_len_q-1) : + cmd_len_q; + + // Capture the application command type. + assign acmd = sfifo_cmd_rdata[2:0]; + + // For gen commands, capture information from the orignal command for use later. + assign cmd_gen_flag_d = + (!cs_enable_i) ? '0 : + cmd_gen_1st_req ? (acmd == GEN) : + cmd_gen_flag_q; + + assign cmd_gen_cmd_d = + (!cs_enable_i) ? '0 : + cmd_gen_1st_req ? {sfifo_cmd_rdata[11:0]} : + cmd_gen_cmd_q; + + // SEC_CM: GEN_CMD.CTR.REDUN + caliptra_prim_count #( + .Width(GenBitsCntrWidth), + .ResetValue({GenBitsCntrWidth{1'b1}}) + ) u_caliptra_prim_count_cmd_gen_cntr ( + .clk_i, + .rst_ni, + .clr_i(!cs_enable_i), + .set_i(cmd_gen_1st_req), + .set_cnt_i(sfifo_cmd_rdata[12+:GenBitsCntrWidth]), + .incr_en_i(1'b0), + .decr_en_i(cmd_gen_cnt_dec), // Count down. + .step_i(GenBitsCntrWidth'(unsigned'(1))), + .commit_i(1'b1), + .cnt_o(cmd_gen_cnt), + .cnt_after_commit_o(), + .err_o(cmd_gen_cnt_err_o) + ); + + // For naming consistency. + assign local_escalate = cmd_gen_cnt_err_o; + + //--------------------------------------------------------- + // state machine to process command + //--------------------------------------------------------- + // Encoding generated with: + // $ ./util/design/sparse-fsm-encode.py -d 3 -m 11 -n 8 \ + // -s 170131814 --language=sv + // + // Hamming distance histogram: + // + // 0: -- + // 1: -- + // 2: -- + // 3: |||||||||||| (21.82%) + // 4: |||||||||||||||||||| (36.36%) + // 5: ||||||||||||||||| (30.91%) + // 6: ||||| (9.09%) + // 7: | (1.82%) + // 8: -- + // + // Minimum Hamming distance: 3 + // Maximum Hamming distance: 7 + // Minimum Hamming weight: 1 + // Maximum Hamming weight: 6 + // + localparam logic[31:0] StateWidth = 8; + typedef enum logic [StateWidth-1:0] { + Idle = 8'b11110101, // idle + Flush = 8'b01011011, // flush command FIFO and start over + ArbGnt = 8'b00011100, // general arbiter request + SendSOP = 8'b00000001, // send sop (start of packet) + SendMOP = 8'b01010110, // send mop (middle of packet) + GenCmdChk = 8'b10001101, // gen cmd check + CmdAck = 8'b11000000, // wait for command ack + GenReq = 8'b10010011, // process gen requests + GenArbGnt = 8'b11101110, // generate subsequent arb request + GenSOP = 8'b10111010, // generate subsequent request + Error = 8'b01100111 // illegal state reached and hang + } state_e; + + state_e state_d, state_q; + `CALIPTRA_PRIM_FLOP_SPARSE_FSM(u_state_regs, state_d, state_q, state_e, Idle) + + always_comb begin + state_d = state_q; + cmd_fifo_pop = 1'b0; + cmd_len_dec = 1'b0; + cmd_gen_cnt_dec = 1'b0; + cmd_gen_1st_req = 1'b0; + cmd_gen_inc_req = 1'b0; + cmd_gen_cnt_last = 1'b0; + cmd_final_ack = 1'b0; + cmd_arb_req_o = 1'b0; + cmd_arb_sop_o = 1'b0; + cmd_arb_mop_o = 1'b0; + cmd_arb_eop_o = 1'b0; + cmd_stage_sm_err_o = 1'b0; + cmd_err_ack = 1'b0; + reseed_cnt_exceeded = 1'b0; + invalid_cmd_seq = 1'b0; + invalid_acmd = 1'b0; + instantiated_d = instantiated_q; + + if (state_q == Error) begin + // In case we are in the Error state we must ignore the local escalate and enable signals. + cmd_stage_sm_err_o = 1'b1; + end else if (local_escalate) begin + // In case local escalate is high we must transition to the error state. + state_d = Error; + end else if (!cs_enable_i && state_q inside {Idle, Flush, ArbGnt, SendSOP, SendMOP, GenCmdChk, + CmdAck, GenReq, GenArbGnt, GenSOP}) begin + // In case the module is disabled and we are in a legal state we must go into idle state. + state_d = Idle; + instantiated_d = 1'b0; + end else begin + // Otherwise do the state machine as normal. + unique case (state_q) + Idle: begin + // Because of the if statement above we won't leave idle if enable is low. + if (!cmd_fifo_zero) begin + if (acmd == INS) begin + if (!instantiated_q) begin + state_d = ArbGnt; + instantiated_d = 1'b1; + end + if (instantiated_q) begin + cmd_err_ack = 1'b1; + invalid_cmd_seq = 1'b1; + state_d = Idle; + end + end else if (acmd == RES) begin + if (instantiated_q) begin + state_d = ArbGnt; + end + if (!instantiated_q) begin + cmd_err_ack = 1'b1; + invalid_cmd_seq = 1'b1; + state_d = Idle; + end + end else if (acmd == GEN) begin + if (instantiated_q) begin + // If the issued command is GEN and the reseed count has already been reached, + // send an ack with an error status response. + if ((acmd == GEN) && reseed_cnt_reached_i) begin + cmd_err_ack = 1'b1; + reseed_cnt_exceeded = 1'b1; + state_d = Idle; + end else begin + state_d = ArbGnt; + end + end + if (!instantiated_q) begin + cmd_err_ack = 1'b1; + invalid_cmd_seq = 1'b1; + state_d = Idle; + end + end else if (acmd == UPD) begin + if (instantiated_q) begin + state_d = ArbGnt; + end + if (!instantiated_q) begin + cmd_err_ack = 1'b1; + invalid_cmd_seq = 1'b1; + state_d = Idle; + end + end else if (acmd == UNI) begin + // Set the instantiation to zero. + instantiated_d = 1'b0; + state_d = ArbGnt; + end else begin + // Command was not supported. + cmd_err_ack = 1'b1; + invalid_acmd = 1'b1; + state_d = Idle; + end + // If we received an invalid command, pop it from the FIFO. Afterwards, absorb any + // additional data belonging to the same invalid command and empty the FIFO. + if (cmd_err_ack) begin + cmd_fifo_pop = 1'b1; + state_d = Flush; + end + end + end + Flush: begin + // Keep popping the FIFO until it's empty and we're not getting new command input. + // The decision whether a command is invalid is taken based on the command header but + // EDN might continue and send additional data belonging to the same command. We have + // to absorb the full invalid command before we can continue. + cmd_fifo_pop = sfifo_cmd_not_empty; + if (!sfifo_cmd_not_empty && !cmd_stage_vld_i) begin + state_d = Idle; + end + end + ArbGnt: begin + cmd_arb_req_o = 1'b1; + if (cmd_arb_gnt_i) begin + state_d = SendSOP; + end + end + SendSOP: begin + cmd_gen_1st_req = 1'b1; + cmd_arb_sop_o = 1'b1; + cmd_fifo_pop = 1'b1; + if (sfifo_cmd_rdata[12+:GenBitsCntrWidth] == GenBitsCntrWidth'(unsigned'(1))) begin + cmd_gen_cnt_last = 1'b1; + end + if (cmd_len == '0) begin + cmd_arb_eop_o = 1'b1; + state_d = GenCmdChk; + end else begin + state_d = SendMOP; + end + end + SendMOP: begin + if (!cmd_fifo_zero) begin + cmd_fifo_pop = 1'b1; + cmd_len_dec = 1'b1; + if (cmd_len_q == 4'h1) begin + cmd_arb_mop_o = 1'b1; + cmd_arb_eop_o = 1'b1; + state_d = GenCmdChk; + end else begin + cmd_arb_mop_o = 1'b1; + end + end + end + GenCmdChk: begin + if (cmd_gen_flag_q) begin + cmd_gen_cnt_dec = 1'b1; + end + state_d = CmdAck; + end + CmdAck: begin + if (cmd_ack_i) begin + // The state database has successfully been updated. + // In case of Generate commands, we get the generated bits one clock cycle before + // receiving the ACK from the state database (from csrng_ctr_drbg_gen). + state_d = GenReq; + end + end + GenReq: begin + // Flag set if a gen request. + if (cmd_gen_flag_q) begin + // Must stall if genbits fifo is not clear. + if (!sfifo_genbits_full) begin + if (cmd_gen_cnt == '0) begin + cmd_final_ack = 1'b1; + state_d = Idle; + end else begin + // Issue a subsequent gen request. + state_d = GenArbGnt; + end + end + end else begin + // Ack for the non-gen request case. + cmd_final_ack = 1'b1; + state_d = Idle; + end + end + GenArbGnt: begin + cmd_arb_req_o = 1'b1; + if (cmd_arb_gnt_i) begin + state_d = GenSOP; + end + end + GenSOP: begin + cmd_arb_sop_o = 1'b1; + cmd_arb_eop_o = 1'b1; + cmd_gen_inc_req = 1'b1; + state_d = GenCmdChk; + // Check for final genbits beat. + if (cmd_gen_cnt == GenBitsCntrWidth'(unsigned'(1))) begin + cmd_gen_cnt_last = 1'b1; + end + end + // Error: The error state is now covered by the if statement above. + default: begin + state_d = Error; + cmd_stage_sm_err_o = 1'b1; + end + endcase // unique case (state_q) + end + end + + //--------------------------------------------------------- + // Genbits FIFO. + //--------------------------------------------------------- + + caliptra_prim_fifo_sync #( + .Width(GenBitsFifoWidth), + .Pass(0), + .Depth(GenBitsFifoDepth), + .OutputZeroIfEmpty(0) // Set to 0, and let last data drive out. + ) u_caliptra_prim_fifo_genbits ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .clr_i (!cs_enable_i), + .wvalid_i (sfifo_genbits_push), + .wready_o (), + .wdata_i (sfifo_genbits_wdata), + .rvalid_o (sfifo_genbits_not_empty), + .rready_i (sfifo_genbits_pop), + .rdata_o (sfifo_genbits_rdata), + .full_o (sfifo_genbits_full), + .depth_o (), // sfifo_genbits_depth) + .err_o () + ); + + assign sfifo_genbits_wdata = {genbits_fips_i,genbits_bus_i}; + + // The caliptra_prim_fifo_sync primitive is constructed to only accept pushes if there is indeed space + // available. Backpressure would actually need to be handled at the sender (csrng_ctr_drbg_gen). + // In this particular case, it is safe to unconditionally push the genbits FIFO because + // the GenSOP FSM state which triggers csrng_ctr_drbg_gen to generate bits can only be reached + // after checking that the genbits FIFO isn't full already. This condition is checked using an + // SVA below. + // + // If the genbits FIFO got pushed without having space, this either means the output of a genbits + // request is routed to the wrong application interface (which would be a critical design bug) + // or that some fault injection attack is going on. Thus, we track such cases both with an SVA + // and with a fatal alert (identifiable via the ERR_CODE register). + assign sfifo_genbits_push = cs_enable_i && genbits_vld_i; + + assign sfifo_genbits_pop = genbits_vld_o && genbits_rdy_i; + + assign genbits_vld_o = cs_enable_i && sfifo_genbits_not_empty; + assign {genbits_fips_o, genbits_bus_o} = sfifo_genbits_rdata; + + assign sfifo_genbits_err = + {(sfifo_genbits_push && sfifo_genbits_full), + (sfifo_genbits_pop && !sfifo_genbits_not_empty), + (sfifo_genbits_full && !sfifo_genbits_not_empty)}; + + // We're only allowed to request more bits if the genbits FIFO has indeed space. + `CALIPTRA_ASSERT(CsrngCmdStageGenbitsFifoFull_A, state_q == GenSOP |-> !sfifo_genbits_full) + + // Pushes to the genbits FIFO outside of the GenCmdChk and CmdAck states or while handling a + // command other than Generate are not allowed. + `CALIPTRA_ASSERT(CsrngCmdStageGenbitsFifoPushExpected_A, + sfifo_genbits_push |-> state_q inside {GenCmdChk, CmdAck} && cmd_gen_flag_q) + + //--------------------------------------------------------- + // Ack logic. + //--------------------------------------------------------- + + assign cmd_ack_d = + (!cs_enable_i) ? '0 : + cmd_final_ack || cmd_err_ack; + + assign cmd_stage_ack_o = cmd_ack_q; + + assign err_sts = reseed_cnt_exceeded ? CMD_STS_RESEED_CNT_EXCEEDED : + invalid_cmd_seq ? CMD_STS_INVALID_CMD_SEQ : + invalid_acmd ? CMD_STS_INVALID_ACMD : CMD_STS_INVALID_ACMD; + + assign cmd_ack_sts_d = + (!cs_enable_i) ? CMD_STS_SUCCESS : + cmd_err_ack ? err_sts : + cmd_final_ack ? cmd_ack_sts_i : + cmd_ack_sts_q; + + assign cmd_stage_ack_sts_o = cmd_ack_sts_q; + + assign reseed_cnt_alert_o = reseed_cnt_exceeded; + assign invalid_cmd_seq_alert_o = invalid_cmd_seq; + assign invalid_acmd_alert_o = invalid_acmd; + + // Make sure that the state machine has a stable error state. This means that after the error + // state is entered it will not exit it unless a reset signal is received. + `CALIPTRA_ASSERT(CsrngCmdStageErrorStStable_A, state_q == Error |=> $stable(state_q)) + // If in error state, the error output must be high. + `CALIPTRA_ASSERT(CsrngCmdStageErrorOutput_A, state_q == Error |-> cmd_stage_sm_err_o) +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/csrng_core.sv b/designs/Caliptra/src/caliptra-rtl/csrng_core.sv new file mode 100644 index 0000000..8dad2fd --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/csrng_core.sv @@ -0,0 +1,1787 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Description: csrng core module +// + + +module csrng_core + import csrng_pkg::*; + import lc_ctrl_state_pkg::*; + import lc_ctrl_reg_pkg::*; + import lc_ctrl_pkg::*; +#( + parameter aes_pkg::sbox_impl_e SBoxImpl = aes_pkg::SBoxImplLut, + parameter logic [31:0] NHwApps = 2, + parameter cs_keymgr_div_t RndCnstCsKeymgrDivNonProduction = CsKeymgrDivWidth'(0), + parameter cs_keymgr_div_t RndCnstCsKeymgrDivProduction = CsKeymgrDivWidth'(0) +) ( + input logic clk_i, + input logic rst_ni, + + input csrng_reg_pkg::csrng_reg2hw_t reg2hw, + output csrng_reg_pkg::csrng_hw2reg_t hw2reg, + + // Efuse Interface + input caliptra_prim_mubi_pkg::mubi8_t otp_en_csrng_sw_app_read_i, + + // Lifecycle broadcast inputs + input lc_ctrl_pkg::lc_tx_t lc_hw_debug_en_i, + + // Entropy Interface + output entropy_src_pkg::entropy_src_hw_if_req_t entropy_src_hw_if_o, + input entropy_src_pkg::entropy_src_hw_if_rsp_t entropy_src_hw_if_i, + + // Entropy Interface + input entropy_src_pkg::cs_aes_halt_req_t cs_aes_halt_i, + output entropy_src_pkg::cs_aes_halt_rsp_t cs_aes_halt_o, + + // Application Interfaces + input csrng_req_t [NHwApps-1:0] csrng_cmd_i, + output csrng_rsp_t [NHwApps-1:0] csrng_cmd_o, + + // Alerts + + output logic recov_alert_test_o, + output logic fatal_alert_test_o, + output logic recov_alert_o, + output logic fatal_alert_o, + + output logic intr_cs_cmd_req_done_o, + output logic intr_cs_entropy_req_o, + output logic intr_cs_hw_inst_exc_o, + output logic intr_cs_fatal_err_o +); + + import csrng_reg_pkg::*; + + import caliptra_prim_mubi_pkg::mubi4_t; + import caliptra_prim_mubi_pkg::mubi4_test_true_strict; + import caliptra_prim_mubi_pkg::mubi4_test_invalid; + + localparam logic [31:0] NApps = NHwApps + 1; + localparam logic [31:0] NAppsLog = $clog2(NApps); + localparam logic [31:0] AppCmdWidth = 32; + localparam logic [31:0] AppCmdFifoDepth = 2; + localparam logic [31:0] GenBitsWidth = 128; + localparam logic [31:0] Cmd = 3; + localparam logic [31:0] StateId = 4; + localparam logic [31:0] KeyLen = 256; + localparam logic [31:0] BlkLen = 128; + localparam logic [31:0] SeedLen = 384; + localparam logic [31:0] CtrLen = 32; + localparam logic [31:0] NBlkEncArbReqs = 2; + localparam logic [31:0] BlkEncArbWidth = KeyLen+BlkLen+StateId+Cmd; + localparam logic [31:0] NUpdateArbReqs = 2; + localparam logic [31:0] UpdateArbWidth = KeyLen+BlkLen+SeedLen+StateId+Cmd; + localparam logic [31:0] MaxClen = 12; + localparam logic [31:0] ADataDepthWidth = SeedLen/AppCmdWidth; + localparam logic [31:0] ADataDepthClog = $clog2(ADataDepthWidth)+1; + localparam logic [31:0] CsEnableCopies = 51; + localparam logic [31:0] LcHwDebugCopies = 1; + localparam logic [31:0] Flag0Copies = 3; + + // signals + // interrupt signals + logic event_cs_cmd_req_done; + logic event_cs_entropy_req; + logic event_cs_hw_inst_exc; + logic event_cs_fatal_err; + logic [CsEnableCopies-1:1] cs_enable_fo; + logic [Flag0Copies-1:0] flag0_fo; + logic acmd_flag0_pfa; + logic cs_enable_pfa; + logic sw_app_enable; + logic sw_app_enable_pfe; + logic sw_app_enable_pfa; + logic read_int_state; + logic read_int_state_pfe; + logic read_int_state_pfa; + logic fips_force_enable; + logic fips_force_enable_pfe; + logic fips_force_enable_pfa; + logic recov_alert_event; + logic acmd_avail; + logic acmd_sop; + logic acmd_mop; + logic acmd_eop; + + logic cmd_blk_select; + logic gen_blk_select; + logic state_db_wr_req_rdy; + logic state_db_wr_req; + logic [StateId-1:0] state_db_wr_inst_id; + logic [KeyLen-1:0] state_db_wr_key; + logic [BlkLen-1:0] state_db_wr_v; + logic [CtrLen-1:0] state_db_wr_rc; + csrng_cmd_sts_e state_db_wr_sts; + logic state_db_wr_fips; + logic [Cmd-1:0] state_db_wr_ccmd; + + logic [AppCmdWidth-1:0] acmd_bus; + + logic [SeedLen-1:0] packer_adata; + logic [ADataDepthClog-1:0] packer_adata_depth; + logic packer_adata_pop; + logic packer_adata_clr; + logic [SeedLen-1:0] seed_diversification; + + logic cmd_entropy_req; + logic cmd_entropy_avail; + logic cmd_entropy_fips; + logic [SeedLen-1:0] cmd_entropy; + + logic cmd_result_wr_req; + logic cmd_result_ack; + csrng_cmd_sts_e cmd_result_ack_sts; + logic [Cmd-1:0] cmd_result_ccmd; + logic cmd_result_ack_rdy; + logic [StateId-1:0] cmd_result_inst_id; + logic cmd_result_glast; + logic cmd_result_fips; + logic [SeedLen-1:0] cmd_result_adata; + logic [KeyLen-1:0] cmd_result_key; + logic [BlkLen-1:0] cmd_result_v; + logic [CtrLen-1:0] cmd_result_rc; + + logic state_db_sts_ack; + csrng_cmd_sts_e state_db_sts_sts; + logic [StateId-1:0] state_db_sts_id; + + logic gen_result_wr_req; + csrng_cmd_sts_e gen_result_ack_sts; + logic gen_result_ack_rdy; + logic [Cmd-1:0] gen_result_ccmd; + logic [StateId-1:0] gen_result_inst_id; + logic gen_result_fips; + logic [KeyLen-1:0] gen_result_key; + logic [BlkLen-1:0] gen_result_v; + logic [CtrLen-1:0] gen_result_rc; + logic [BlkLen-1:0] gen_result_bits; + + logic acmd_accept; + logic instant_req; + logic reseed_req; + logic generate_req; + logic update_req; + logic uninstant_req; + logic clr_adata_packer; + logic [Cmd-1:0] ctr_drbg_cmd_ccmd; + logic ctr_drbg_cmd_req; + logic ctr_drbg_gen_req; + logic ctr_drbg_gen_req_rdy; + logic ctr_drbg_cmd_req_rdy; + logic ctr_drbg_cmd_sfifo_cmdreq_err_sum; + logic [2:0] ctr_drbg_cmd_sfifo_cmdreq_err; + logic ctr_drbg_cmd_sfifo_rcstage_err_sum; + logic [2:0] ctr_drbg_cmd_sfifo_rcstage_err; + logic ctr_drbg_cmd_sfifo_keyvrc_err_sum; + logic [2:0] ctr_drbg_cmd_sfifo_keyvrc_err; + logic ctr_drbg_upd_sfifo_updreq_err_sum; + logic [2:0] ctr_drbg_upd_sfifo_updreq_err; + logic ctr_drbg_upd_sfifo_bencreq_err_sum; + logic [2:0] ctr_drbg_upd_sfifo_bencreq_err; + logic ctr_drbg_upd_sfifo_bencack_err_sum; + logic [2:0] ctr_drbg_upd_sfifo_bencack_err; + logic ctr_drbg_upd_sfifo_pdata_err_sum; + logic [2:0] ctr_drbg_upd_sfifo_pdata_err; + logic ctr_drbg_upd_sfifo_final_err_sum; + logic [2:0] ctr_drbg_upd_sfifo_final_err; + logic ctr_drbg_gen_sfifo_gbencack_err_sum; + logic [2:0] ctr_drbg_gen_sfifo_gbencack_err; + logic ctr_drbg_gen_sfifo_grcstage_err_sum; + logic [2:0] ctr_drbg_gen_sfifo_grcstage_err; + logic ctr_drbg_gen_sfifo_ggenreq_err_sum; + logic [2:0] ctr_drbg_gen_sfifo_ggenreq_err; + logic ctr_drbg_gen_sfifo_gadstage_err_sum; + logic [2:0] ctr_drbg_gen_sfifo_gadstage_err; + logic ctr_drbg_gen_sfifo_ggenbits_err_sum; + logic [2:0] ctr_drbg_gen_sfifo_ggenbits_err; + logic block_encrypt_sfifo_blkenc_err_sum; + logic [2:0] block_encrypt_sfifo_blkenc_err; + logic cmd_gen_cnt_err_sum; + logic cmd_stage_sm_err_sum; + logic main_sm_err_sum; + logic cs_main_sm_err; + logic [MainSmStateWidth-1:0] cs_main_sm_state; + logic drbg_gen_sm_err_sum; + logic drbg_gen_sm_err; + logic drbg_updbe_sm_err_sum; + logic drbg_updbe_sm_err; + logic drbg_updob_sm_err_sum; + logic drbg_updob_sm_err; + logic aes_cipher_sm_err_sum; + logic aes_cipher_sm_err; + logic fifo_write_err_sum; + logic fifo_read_err_sum; + logic fifo_status_err_sum; + + logic [KeyLen-1:0] state_db_rd_key; + logic [BlkLen-1:0] state_db_rd_v; + logic [CtrLen-1:0] state_db_rd_rc; + logic state_db_rd_fips; + logic [2:0] acmd_hold; + logic [3:0] shid; + logic gen_last; + mubi4_t flag0; + + // blk encrypt arbiter + logic [Cmd-1:0] updblk_benblk_cmd_arb_din; + logic [StateId-1:0] updblk_benblk_id_arb_din; + logic [BlkLen-1:0] updblk_benblk_v_arb_din; + logic [KeyLen-1:0] updblk_benblk_key_arb_din; + logic updblk_benblk_arb_req; + logic updblk_benblk_arb_req_rdy; + logic benblk_updblk_ack; + logic updblk_benblk_ack_rdy; + + logic [Cmd-1:0] genblk_benblk_cmd_arb_din; + logic [StateId-1:0] genblk_benblk_id_arb_din; + logic [BlkLen-1:0] genblk_benblk_v_arb_din; + logic [KeyLen-1:0] genblk_benblk_key_arb_din; + logic genblk_benblk_arb_req; + logic genblk_benblk_arb_req_rdy; + logic benblk_genblk_ack; + logic genblk_benblk_ack_rdy; + + logic [BlkEncArbWidth-1:0] benblk_arb_din [2]; + logic [BlkEncArbWidth-1:0] benblk_arb_data; + logic [KeyLen-1:0] benblk_arb_key; + logic [BlkLen-1:0] benblk_arb_v; + logic [StateId-1:0] benblk_arb_inst_id; + logic [Cmd-1:0] benblk_arb_cmd; + logic benblk_arb_vld; + logic benblk_ack; + logic benblk_ack_rdy; + logic benblk_arb_rdy; + logic [Cmd-1:0] benblk_cmd; + logic [StateId-1:0] benblk_inst_id; + logic [BlkLen-1:0] benblk_v; + + // update arbiter + logic [Cmd-1:0] cmdblk_updblk_ccmd_arb_din; + logic [StateId-1:0] cmdblk_updblk_id_arb_din; + logic [BlkLen-1:0] cmdblk_updblk_v_arb_din; + logic [KeyLen-1:0] cmdblk_updblk_key_arb_din; + logic [SeedLen-1:0] cmdblk_updblk_pdata_arb_din; + logic cmdblk_updblk_arb_req; + logic updblk_cmdblk_arb_req_rdy; + logic updblk_cmdblk_ack; + logic cmdblk_updblk_ack_rdy; + + logic [Cmd-1:0] genblk_updblk_ccmd_arb_din; + logic [StateId-1:0] genblk_updblk_id_arb_din; + logic [BlkLen-1:0] genblk_updblk_v_arb_din; + logic [KeyLen-1:0] genblk_updblk_key_arb_din; + logic [SeedLen-1:0] genblk_updblk_pdata_arb_din; + logic genblk_updblk_arb_req; + logic updblk_genblk_arb_req_rdy; + logic updblk_genblk_ack; + logic genblk_updblk_ack_rdy; + + logic [UpdateArbWidth-1:0] updblk_arb_din [2]; + logic [UpdateArbWidth-1:0] updblk_arb_data; + logic [KeyLen-1:0] updblk_arb_key; + logic [BlkLen-1:0] updblk_arb_v; + logic [SeedLen-1:0] updblk_arb_pdata; + logic [StateId-1:0] updblk_arb_inst_id; + logic [Cmd-1:0] updblk_arb_ccmd; + logic updblk_arb_vld; + logic updblk_ack; + logic updblk_ack_rdy; + logic updblk_arb_rdy; + logic [Cmd-1:0] updblk_ccmd; + logic [StateId-1:0] updblk_inst_id; + logic [KeyLen-1:0] updblk_key; + logic [BlkLen-1:0] updblk_v; + + logic [2:0] cmd_stage_sfifo_cmd_err[NApps]; + logic [NApps-1:0] cmd_stage_sfifo_cmd_err_sum; + logic [NApps-1:0] cmd_stage_sfifo_cmd_err_wr; + logic [NApps-1:0] cmd_stage_sfifo_cmd_err_rd; + logic [NApps-1:0] cmd_stage_sfifo_cmd_err_st; + logic [2:0] cmd_stage_sfifo_genbits_err[NApps]; + logic [NApps-1:0] cmd_stage_sfifo_genbits_err_sum; + logic [NApps-1:0] cmd_stage_sfifo_genbits_err_wr; + logic [NApps-1:0] cmd_stage_sfifo_genbits_err_rd; + logic [NApps-1:0] cmd_stage_sfifo_genbits_err_st; + logic [NApps-1:0] cmd_gen_cnt_err; + logic [NApps-1:0] cmd_stage_sm_err; + logic ctr_drbg_upd_v_ctr_err; + logic ctr_drbg_gen_v_ctr_err; + + logic [NApps-1:0] cmd_stage_vld; + logic [StateId-1:0] cmd_stage_shid[NApps]; + logic [AppCmdWidth-1:0] cmd_stage_bus[NApps]; + logic [NApps-1:0] cmd_stage_rdy; + logic [NApps-1:0] cmd_arb_req; + logic [0:0] cmd_arb_di [NApps]; + logic [NApps-1:0] cmd_arb_gnt; + logic [$clog2(NApps)-1:0] cmd_arb_idx; + logic [NApps-1:0] cmd_arb_sop; + logic [NApps-1:0] cmd_arb_mop; + logic [NApps-1:0] cmd_arb_eop; + logic [AppCmdWidth-1:0] cmd_arb_bus[NApps]; + logic [NApps-1:0] cmd_core_ack; + csrng_cmd_sts_e [NApps-1:0] cmd_core_ack_sts; + logic [NApps-1:0] cmd_stage_ack; + csrng_cmd_sts_e [NApps-1:0] cmd_stage_ack_sts; + logic [NApps-1:0] genbits_core_vld; + logic [GenBitsWidth-1:0] genbits_core_bus[NApps]; + logic [NApps-1:0] genbits_core_fips; + logic [NApps-1:0] genbits_stage_vld; + logic [NApps-1:0] genbits_stage_fips; + logic [GenBitsWidth-1:0] genbits_stage_bus[NApps]; + logic [NApps-1:0] genbits_stage_rdy; + logic genbits_stage_vldo_sw; + logic genbits_stage_bus_rd_sw; + logic [31:0] genbits_stage_bus_sw; + logic genbits_stage_fips_sw; + + logic [15:0] hw_exception_sts; + logic [LcHwDebugCopies-1:0] lc_hw_debug_on_fo; + logic state_db_is_dump_en; + logic state_db_reg_rd_sel; + logic state_db_reg_rd_id_pulse; + logic [StateId-1:0] state_db_reg_rd_id; + logic [31:0] state_db_reg_rd_val; + logic [NApps-1:0] int_state_read_enable; + + logic [30:0] err_code_test_bit; + logic ctr_drbg_upd_es_ack; + logic ctr_drbg_gen_es_ack; + logic block_encrypt_quiet; + + logic cs_rdata_capt_vld; + logic cs_bus_cmp_alert; + logic cmd_rdy; + logic [NApps-1:0] invalid_cmd_seq_alert; + logic [NApps-1:0] invalid_acmd_alert; + logic [NApps-1:0] reseed_cnt_alert; + logic sw_sts_ack; + logic [1:0] efuse_sw_app_enable; + + logic [NApps-1:0][31:0] reseed_counter; + + logic unused_err_code_test_bit; + logic unused_reg2hw_genbits; + logic unused_int_state_val; + logic unused_reseed_interval; + + caliptra_prim_mubi_pkg::mubi8_t [1:0] en_csrng_sw_app_read; + caliptra_prim_mubi_pkg::mubi4_t [CsEnableCopies-1:0] mubi_cs_enable_fanout; + caliptra_prim_mubi_pkg::mubi4_t [Flag0Copies-1:0] mubi_flag0_fanout; + + // flops + logic [2:0] acmd_q, acmd_d; + logic [3:0] shid_q, shid_d; + logic gen_last_q, gen_last_d; + mubi4_t flag0_q, flag0_d; + logic [$clog2(NApps)-1:0] cmd_arb_idx_q, cmd_arb_idx_d; + logic statedb_wr_select_q, statedb_wr_select_d; + logic genbits_stage_fips_sw_q, genbits_stage_fips_sw_d; + logic cmd_req_dly_q, cmd_req_dly_d; + logic [Cmd-1:0] cmd_req_ccmd_dly_q, cmd_req_ccmd_dly_d; + logic cs_aes_halt_q, cs_aes_halt_d; + logic [SeedLen-1:0] entropy_src_seed_q, entropy_src_seed_d; + logic entropy_src_fips_q, entropy_src_fips_d; + logic [63:0] cs_rdata_capt_q, cs_rdata_capt_d; + logic cs_rdata_capt_vld_q, cs_rdata_capt_vld_d; + logic sw_rdy_sts_q, sw_rdy_sts_d; + logic sw_sts_ack_q, sw_sts_ack_d; + logic [NApps-1:0] reseed_cnt_reached_q, reseed_cnt_reached_d; + + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + acmd_q <= '0; + shid_q <= '0; + gen_last_q <= '0; + flag0_q <= caliptra_prim_mubi_pkg::MuBi4False; + cmd_arb_idx_q <= '0; + statedb_wr_select_q <= '0; + genbits_stage_fips_sw_q <= '0; + cmd_req_dly_q <= '0; + cmd_req_ccmd_dly_q <= '0; + cs_aes_halt_q <= '0; + entropy_src_seed_q <= '0; + entropy_src_fips_q <= '0; + cs_rdata_capt_q <= '0; + cs_rdata_capt_vld_q <= '0; + sw_rdy_sts_q <= '0; + sw_sts_ack_q <= '0; + reseed_cnt_reached_q <= '0; + end else begin + acmd_q <= acmd_d; + shid_q <= shid_d; + gen_last_q <= gen_last_d; + flag0_q <= flag0_d; + cmd_arb_idx_q <= cmd_arb_idx_d; + statedb_wr_select_q <= statedb_wr_select_d; + genbits_stage_fips_sw_q <= genbits_stage_fips_sw_d; + cmd_req_dly_q <= cmd_req_dly_d; + cmd_req_ccmd_dly_q <= cmd_req_ccmd_dly_d; + cs_aes_halt_q <= cs_aes_halt_d; + entropy_src_seed_q <= entropy_src_seed_d; + entropy_src_fips_q <= entropy_src_fips_d; + cs_rdata_capt_q <= cs_rdata_capt_d; + cs_rdata_capt_vld_q <= cs_rdata_capt_vld_d; + sw_rdy_sts_q <= sw_rdy_sts_d; + sw_sts_ack_q <= sw_sts_ack_d; + reseed_cnt_reached_q <= reseed_cnt_reached_d; + end + end + + //-------------------------------------------- + // instantiate interrupt hardware primitives + //-------------------------------------------- + // All TLUL interrupts are collect in the section. + + caliptra_prim_intr_hw #( + .Width(1) + ) u_intr_hw_cs_cmd_req_done ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .event_intr_i (event_cs_cmd_req_done), + .reg2hw_intr_enable_q_i (reg2hw.intr_enable.cs_cmd_req_done.q), + .reg2hw_intr_test_q_i (reg2hw.intr_test.cs_cmd_req_done.q), + .reg2hw_intr_test_qe_i (reg2hw.intr_test.cs_cmd_req_done.qe), + .reg2hw_intr_state_q_i (reg2hw.intr_state.cs_cmd_req_done.q), + .hw2reg_intr_state_de_o (hw2reg.intr_state.cs_cmd_req_done.de), + .hw2reg_intr_state_d_o (hw2reg.intr_state.cs_cmd_req_done.d), + .intr_o (intr_cs_cmd_req_done_o) + ); + + caliptra_prim_intr_hw #( + .Width(1) + ) u_intr_hw_cs_entropy_req ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .event_intr_i (event_cs_entropy_req), + .reg2hw_intr_enable_q_i (reg2hw.intr_enable.cs_entropy_req.q), + .reg2hw_intr_test_q_i (reg2hw.intr_test.cs_entropy_req.q), + .reg2hw_intr_test_qe_i (reg2hw.intr_test.cs_entropy_req.qe), + .reg2hw_intr_state_q_i (reg2hw.intr_state.cs_entropy_req.q), + .hw2reg_intr_state_de_o (hw2reg.intr_state.cs_entropy_req.de), + .hw2reg_intr_state_d_o (hw2reg.intr_state.cs_entropy_req.d), + .intr_o (intr_cs_entropy_req_o) + ); + + + caliptra_prim_intr_hw #( + .Width(1) + ) u_intr_hw_cs_hw_inst_exc ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .event_intr_i (event_cs_hw_inst_exc), + .reg2hw_intr_enable_q_i (reg2hw.intr_enable.cs_hw_inst_exc.q), + .reg2hw_intr_test_q_i (reg2hw.intr_test.cs_hw_inst_exc.q), + .reg2hw_intr_test_qe_i (reg2hw.intr_test.cs_hw_inst_exc.qe), + .reg2hw_intr_state_q_i (reg2hw.intr_state.cs_hw_inst_exc.q), + .hw2reg_intr_state_de_o (hw2reg.intr_state.cs_hw_inst_exc.de), + .hw2reg_intr_state_d_o (hw2reg.intr_state.cs_hw_inst_exc.d), + .intr_o (intr_cs_hw_inst_exc_o) + ); + + + caliptra_prim_intr_hw #( + .Width(1) + ) u_intr_hw_cs_fatal_err ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .event_intr_i (event_cs_fatal_err), + .reg2hw_intr_enable_q_i (reg2hw.intr_enable.cs_fatal_err.q), + .reg2hw_intr_test_q_i (reg2hw.intr_test.cs_fatal_err.q), + .reg2hw_intr_test_qe_i (reg2hw.intr_test.cs_fatal_err.qe), + .reg2hw_intr_state_q_i (reg2hw.intr_state.cs_fatal_err.q), + .hw2reg_intr_state_de_o (hw2reg.intr_state.cs_fatal_err.de), + .hw2reg_intr_state_d_o (hw2reg.intr_state.cs_fatal_err.d), + .intr_o (intr_cs_fatal_err_o) + ); + + // Counter and FSM errors are structural errors and are always active regardless of the + // functional state. main_sm_err_sum is not included here to prevent some tools from + // inferring combo loops. However, to include the state machine error for testing, + // we use the error code test bit (index 21) directly. + logic fatal_loc_events; + assign fatal_loc_events = cmd_gen_cnt_err_sum || + cmd_stage_sm_err_sum || + drbg_gen_sm_err_sum || + drbg_updbe_sm_err_sum || + drbg_updob_sm_err_sum || + aes_cipher_sm_err_sum || + err_code_test_bit[21]; + + // set the interrupt sources + assign event_cs_fatal_err = (cs_enable_fo[1] && ( + (|cmd_stage_sfifo_cmd_err_sum) || + (|cmd_stage_sfifo_genbits_err_sum) || + ctr_drbg_cmd_sfifo_cmdreq_err_sum || + ctr_drbg_cmd_sfifo_rcstage_err_sum || + ctr_drbg_cmd_sfifo_keyvrc_err_sum || + ctr_drbg_upd_sfifo_updreq_err_sum || + ctr_drbg_upd_sfifo_bencreq_err_sum || + ctr_drbg_upd_sfifo_bencack_err_sum || + ctr_drbg_upd_sfifo_pdata_err_sum || + ctr_drbg_upd_sfifo_final_err_sum || + ctr_drbg_gen_sfifo_gbencack_err_sum || + ctr_drbg_gen_sfifo_grcstage_err_sum || + ctr_drbg_gen_sfifo_ggenreq_err_sum || + ctr_drbg_gen_sfifo_gadstage_err_sum || + ctr_drbg_gen_sfifo_ggenbits_err_sum || + block_encrypt_sfifo_blkenc_err_sum || + fifo_write_err_sum || + fifo_read_err_sum || + fifo_status_err_sum)) || + // errs not gated by cs_enable + main_sm_err_sum || + fatal_loc_events; + + // set fifo errors that are single instances of source + assign ctr_drbg_cmd_sfifo_cmdreq_err_sum = (|ctr_drbg_cmd_sfifo_cmdreq_err) || + err_code_test_bit[2]; + assign ctr_drbg_cmd_sfifo_rcstage_err_sum = (|ctr_drbg_cmd_sfifo_rcstage_err) || + err_code_test_bit[3]; + assign ctr_drbg_cmd_sfifo_keyvrc_err_sum = (|ctr_drbg_cmd_sfifo_keyvrc_err) || + err_code_test_bit[4]; + assign ctr_drbg_upd_sfifo_updreq_err_sum = (|ctr_drbg_upd_sfifo_updreq_err) || + err_code_test_bit[5]; + assign ctr_drbg_upd_sfifo_bencreq_err_sum = (|ctr_drbg_upd_sfifo_bencreq_err) || + err_code_test_bit[6]; + assign ctr_drbg_upd_sfifo_bencack_err_sum = (|ctr_drbg_upd_sfifo_bencack_err) || + err_code_test_bit[7]; + assign ctr_drbg_upd_sfifo_pdata_err_sum = (|ctr_drbg_upd_sfifo_pdata_err) || + err_code_test_bit[8]; + assign ctr_drbg_upd_sfifo_final_err_sum = (|ctr_drbg_upd_sfifo_final_err) || + err_code_test_bit[9]; + assign ctr_drbg_gen_sfifo_gbencack_err_sum = (|ctr_drbg_gen_sfifo_gbencack_err) || + err_code_test_bit[10]; + assign ctr_drbg_gen_sfifo_grcstage_err_sum = (|ctr_drbg_gen_sfifo_grcstage_err) || + err_code_test_bit[11]; + assign ctr_drbg_gen_sfifo_ggenreq_err_sum = (|ctr_drbg_gen_sfifo_ggenreq_err) || + err_code_test_bit[12]; + assign ctr_drbg_gen_sfifo_gadstage_err_sum = (|ctr_drbg_gen_sfifo_gadstage_err) || + err_code_test_bit[13]; + assign ctr_drbg_gen_sfifo_ggenbits_err_sum = (|ctr_drbg_gen_sfifo_ggenbits_err) || + err_code_test_bit[14]; + assign block_encrypt_sfifo_blkenc_err_sum = (|block_encrypt_sfifo_blkenc_err) || + err_code_test_bit[15]; + assign cmd_stage_sm_err_sum = (|cmd_stage_sm_err) || + err_code_test_bit[20]; + assign main_sm_err_sum = cs_main_sm_err || + err_code_test_bit[21]; + assign drbg_gen_sm_err_sum = drbg_gen_sm_err || + err_code_test_bit[22]; + assign drbg_updbe_sm_err_sum = drbg_updbe_sm_err || + err_code_test_bit[23]; + assign drbg_updob_sm_err_sum = drbg_updob_sm_err || + err_code_test_bit[24]; + assign aes_cipher_sm_err_sum = aes_cipher_sm_err || + err_code_test_bit[25]; + assign cmd_gen_cnt_err_sum = (|cmd_gen_cnt_err) || ctr_drbg_gen_v_ctr_err || + ctr_drbg_upd_v_ctr_err || err_code_test_bit[26]; + assign fifo_write_err_sum = + block_encrypt_sfifo_blkenc_err[2] || + ctr_drbg_gen_sfifo_ggenbits_err[2] || + ctr_drbg_gen_sfifo_gadstage_err[2] || + ctr_drbg_gen_sfifo_ggenreq_err[2] || + ctr_drbg_gen_sfifo_grcstage_err[2] || + ctr_drbg_gen_sfifo_gbencack_err[2] || + ctr_drbg_upd_sfifo_final_err[2] || + ctr_drbg_upd_sfifo_pdata_err[2] || + ctr_drbg_upd_sfifo_bencack_err[2] || + ctr_drbg_upd_sfifo_bencreq_err[2] || + ctr_drbg_upd_sfifo_updreq_err[2] || + ctr_drbg_cmd_sfifo_keyvrc_err[2] || + ctr_drbg_cmd_sfifo_rcstage_err[2] || + ctr_drbg_cmd_sfifo_cmdreq_err[2] || + (|cmd_stage_sfifo_genbits_err_wr) || + (|cmd_stage_sfifo_cmd_err_wr) || + err_code_test_bit[28]; + assign fifo_read_err_sum = + block_encrypt_sfifo_blkenc_err[1] || + ctr_drbg_gen_sfifo_ggenbits_err[1] || + ctr_drbg_gen_sfifo_gadstage_err[1] || + ctr_drbg_gen_sfifo_ggenreq_err[1] || + ctr_drbg_gen_sfifo_grcstage_err[1] || + ctr_drbg_gen_sfifo_gbencack_err[1] || + ctr_drbg_upd_sfifo_final_err[1] || + ctr_drbg_upd_sfifo_pdata_err[1] || + ctr_drbg_upd_sfifo_bencack_err[1] || + ctr_drbg_upd_sfifo_bencreq_err[1] || + ctr_drbg_upd_sfifo_updreq_err[1] || + ctr_drbg_cmd_sfifo_keyvrc_err[1] || + ctr_drbg_cmd_sfifo_rcstage_err[1] || + ctr_drbg_cmd_sfifo_cmdreq_err[1] || + (|cmd_stage_sfifo_genbits_err_rd) || + (|cmd_stage_sfifo_cmd_err_rd) || + err_code_test_bit[29]; + assign fifo_status_err_sum = + block_encrypt_sfifo_blkenc_err[0] || + ctr_drbg_gen_sfifo_ggenbits_err[0] || + ctr_drbg_gen_sfifo_gadstage_err[0] || + ctr_drbg_gen_sfifo_ggenreq_err[0] || + ctr_drbg_gen_sfifo_grcstage_err[0] || + ctr_drbg_gen_sfifo_gbencack_err[0] || + ctr_drbg_upd_sfifo_final_err[0] || + ctr_drbg_upd_sfifo_pdata_err[0] || + ctr_drbg_upd_sfifo_bencack_err[0] || + ctr_drbg_upd_sfifo_bencreq_err[0] || + ctr_drbg_upd_sfifo_updreq_err[0] || + ctr_drbg_cmd_sfifo_keyvrc_err[0] || + ctr_drbg_cmd_sfifo_rcstage_err[0] || + ctr_drbg_cmd_sfifo_cmdreq_err[0] || + (|cmd_stage_sfifo_genbits_err_st) || + (|cmd_stage_sfifo_cmd_err_st) || + err_code_test_bit[30]; + + // set the err code source bits + assign hw2reg.err_code.sfifo_cmd_err.d = 1'b1; + assign hw2reg.err_code.sfifo_cmd_err.de = cs_enable_fo[2] && + (|cmd_stage_sfifo_cmd_err_sum); + + assign hw2reg.err_code.sfifo_genbits_err.d = 1'b1; + assign hw2reg.err_code.sfifo_genbits_err.de = cs_enable_fo[3] && + (|cmd_stage_sfifo_genbits_err_sum); + + assign hw2reg.err_code.sfifo_cmdreq_err.d = 1'b1; + assign hw2reg.err_code.sfifo_cmdreq_err.de = cs_enable_fo[4] && + ctr_drbg_cmd_sfifo_cmdreq_err_sum; + + assign hw2reg.err_code.sfifo_rcstage_err.d = 1'b1; + assign hw2reg.err_code.sfifo_rcstage_err.de = cs_enable_fo[5] && + ctr_drbg_cmd_sfifo_rcstage_err_sum; + + assign hw2reg.err_code.sfifo_keyvrc_err.d = 1'b1; + assign hw2reg.err_code.sfifo_keyvrc_err.de = cs_enable_fo[6] && + ctr_drbg_cmd_sfifo_keyvrc_err_sum; + + assign hw2reg.err_code.sfifo_updreq_err.d = 1'b1; + assign hw2reg.err_code.sfifo_updreq_err.de = cs_enable_fo[7] && + ctr_drbg_upd_sfifo_updreq_err_sum; + + assign hw2reg.err_code.sfifo_bencreq_err.d = 1'b1; + assign hw2reg.err_code.sfifo_bencreq_err.de = cs_enable_fo[8] && + ctr_drbg_upd_sfifo_bencreq_err_sum; + + assign hw2reg.err_code.sfifo_bencack_err.d = 1'b1; + assign hw2reg.err_code.sfifo_bencack_err.de = cs_enable_fo[9] && + ctr_drbg_upd_sfifo_bencack_err_sum; + + assign hw2reg.err_code.sfifo_pdata_err.d = 1'b1; + assign hw2reg.err_code.sfifo_pdata_err.de = cs_enable_fo[10] && + ctr_drbg_upd_sfifo_pdata_err_sum; + + assign hw2reg.err_code.sfifo_final_err.d = 1'b1; + assign hw2reg.err_code.sfifo_final_err.de = cs_enable_fo[11] && + ctr_drbg_upd_sfifo_final_err_sum; + + assign hw2reg.err_code.sfifo_gbencack_err.d = 1'b1; + assign hw2reg.err_code.sfifo_gbencack_err.de = cs_enable_fo[12] && + ctr_drbg_gen_sfifo_gbencack_err_sum; + + assign hw2reg.err_code.sfifo_grcstage_err.d = 1'b1; + assign hw2reg.err_code.sfifo_grcstage_err.de = cs_enable_fo[13] && + ctr_drbg_gen_sfifo_grcstage_err_sum; + + assign hw2reg.err_code.sfifo_ggenreq_err.d = 1'b1; + assign hw2reg.err_code.sfifo_ggenreq_err.de = cs_enable_fo[14] && + ctr_drbg_gen_sfifo_ggenreq_err_sum; + + assign hw2reg.err_code.sfifo_gadstage_err.d = 1'b1; + assign hw2reg.err_code.sfifo_gadstage_err.de = cs_enable_fo[15] && + ctr_drbg_gen_sfifo_gadstage_err_sum; + + assign hw2reg.err_code.sfifo_ggenbits_err.d = 1'b1; + assign hw2reg.err_code.sfifo_ggenbits_err.de = cs_enable_fo[16] && + ctr_drbg_gen_sfifo_ggenbits_err_sum; + + assign hw2reg.err_code.sfifo_blkenc_err.d = 1'b1; + assign hw2reg.err_code.sfifo_blkenc_err.de = cs_enable_fo[17] && + block_encrypt_sfifo_blkenc_err_sum; + + assign hw2reg.err_code.cmd_stage_sm_err.d = 1'b1; + assign hw2reg.err_code.cmd_stage_sm_err.de = cs_enable_fo[18] && + cmd_stage_sm_err_sum; + + assign hw2reg.err_code.main_sm_err.d = 1'b1; + assign hw2reg.err_code.main_sm_err.de = cs_enable_fo[19] && + main_sm_err_sum; + + assign hw2reg.err_code.drbg_gen_sm_err.d = 1'b1; + assign hw2reg.err_code.drbg_gen_sm_err.de = cs_enable_fo[20] && + drbg_gen_sm_err_sum; + + assign hw2reg.err_code.drbg_updbe_sm_err.d = 1'b1; + assign hw2reg.err_code.drbg_updbe_sm_err.de = cs_enable_fo[21] && + drbg_updbe_sm_err_sum; + + assign hw2reg.err_code.drbg_updob_sm_err.d = 1'b1; + assign hw2reg.err_code.drbg_updob_sm_err.de = cs_enable_fo[22] && + drbg_updob_sm_err_sum; + + assign hw2reg.err_code.aes_cipher_sm_err.d = 1'b1; + assign hw2reg.err_code.aes_cipher_sm_err.de = cs_enable_fo[23] && + aes_cipher_sm_err_sum; + + assign hw2reg.err_code.cmd_gen_cnt_err.d = 1'b1; + assign hw2reg.err_code.cmd_gen_cnt_err.de = cmd_gen_cnt_err_sum; + + + // set the err code type bits + assign hw2reg.err_code.fifo_write_err.d = 1'b1; + assign hw2reg.err_code.fifo_write_err.de = cs_enable_fo[24] && fifo_write_err_sum; + + assign hw2reg.err_code.fifo_read_err.d = 1'b1; + assign hw2reg.err_code.fifo_read_err.de = cs_enable_fo[25] && fifo_read_err_sum; + + assign hw2reg.err_code.fifo_state_err.d = 1'b1; + assign hw2reg.err_code.fifo_state_err.de = cs_enable_fo[26] && fifo_status_err_sum; + + // Error forcing + for (genvar i = 0; i < 31; i = i+1) begin : gen_err_code_test_bit + assign err_code_test_bit[i] = (reg2hw.err_code_test.q == i) && reg2hw.err_code_test.qe; + end : gen_err_code_test_bit + + // alert - send all interrupt sources to the alert for the fatal case + assign fatal_alert_o = event_cs_fatal_err; + + // alert test + assign recov_alert_test_o = { + reg2hw.alert_test.recov_alert.q && + reg2hw.alert_test.recov_alert.qe + }; + assign fatal_alert_test_o = { + reg2hw.alert_test.fatal_alert.q && + reg2hw.alert_test.fatal_alert.qe + }; + + + assign recov_alert_event = cs_enable_pfa || + sw_app_enable_pfa || + read_int_state_pfa || + acmd_flag0_pfa || + |reseed_cnt_alert || + |invalid_cmd_seq_alert || + |invalid_acmd_alert || + cs_bus_cmp_alert; + + + caliptra_prim_edge_detector #( + .Width(1), + .ResetValue(0), + .EnSync(0) + ) u_caliptra_prim_edge_detector_recov_alert ( + .clk_i, + .rst_ni, + .d_i(recov_alert_event), + .q_sync_o(), + .q_posedge_pulse_o(recov_alert_o), + .q_negedge_pulse_o() + ); + + + // check for illegal enable field states, and set alert if detected + + // SEC_CM: CONFIG.MUBI + mubi4_t mubi_cs_enable; + assign mubi_cs_enable = mubi4_t'(reg2hw.ctrl.enable.q); + assign cs_enable_pfa = mubi4_test_invalid(mubi_cs_enable_fanout[0]); + assign hw2reg.recov_alert_sts.enable_field_alert.de = cs_enable_pfa; + assign hw2reg.recov_alert_sts.enable_field_alert.d = cs_enable_pfa; + + for (genvar i = 1; i < CsEnableCopies; i = i+1) begin : gen_mubi_en_copies + assign cs_enable_fo[i] = mubi4_test_true_strict(mubi_cs_enable_fanout[i]); + end : gen_mubi_en_copies + + caliptra_prim_mubi4_sync #( + .NumCopies(CsEnableCopies), + .AsyncOn(0) + ) u_caliptra_prim_mubi4_sync_cs_enable ( + .clk_i, + .rst_ni, + .mubi_i(mubi_cs_enable), + .mubi_o(mubi_cs_enable_fanout) + ); + + // SEC_CM: CONFIG.MUBI + mubi4_t mubi_sw_app_enable; + mubi4_t [1:0] mubi_sw_app_enable_fanout; + assign mubi_sw_app_enable = mubi4_t'(reg2hw.ctrl.sw_app_enable.q); + assign sw_app_enable_pfe = mubi4_test_true_strict(mubi_sw_app_enable_fanout[0]); + assign sw_app_enable_pfa = mubi4_test_invalid(mubi_sw_app_enable_fanout[1]); + assign hw2reg.recov_alert_sts.sw_app_enable_field_alert.de = sw_app_enable_pfa; + assign hw2reg.recov_alert_sts.sw_app_enable_field_alert.d = sw_app_enable_pfa; + + caliptra_prim_mubi4_sync #( + .NumCopies(2), + .AsyncOn(0) + ) u_caliptra_prim_mubi4_sync_sw_app_enable ( + .clk_i, + .rst_ni, + .mubi_i(mubi_sw_app_enable), + .mubi_o(mubi_sw_app_enable_fanout) + ); + + // SEC_CM: CONFIG.MUBI + mubi4_t mubi_read_int_state; + mubi4_t [1:0] mubi_read_int_state_fanout; + assign mubi_read_int_state = mubi4_t'(reg2hw.ctrl.read_int_state.q); + assign read_int_state_pfe = mubi4_test_true_strict(mubi_read_int_state_fanout[0]); + assign read_int_state_pfa = mubi4_test_invalid(mubi_read_int_state_fanout[1]); + assign hw2reg.recov_alert_sts.read_int_state_field_alert.de = read_int_state_pfa; + assign hw2reg.recov_alert_sts.read_int_state_field_alert.d = read_int_state_pfa; + + caliptra_prim_mubi4_sync #( + .NumCopies(2), + .AsyncOn(0) + ) u_caliptra_prim_mubi4_sync_read_int_state ( + .clk_i, + .rst_ni, + .mubi_i(mubi_read_int_state), + .mubi_o(mubi_read_int_state_fanout) + ); + + // SEC_CM: CONFIG.MUBI + mubi4_t mubi_fips_force_enable; + mubi4_t [1:0] mubi_fips_force_enable_fanout; + assign mubi_fips_force_enable = mubi4_t'(reg2hw.ctrl.fips_force_enable.q); + assign fips_force_enable_pfe = mubi4_test_true_strict(mubi_fips_force_enable_fanout[0]); + assign fips_force_enable_pfa = mubi4_test_invalid(mubi_fips_force_enable_fanout[1]); + assign hw2reg.recov_alert_sts.fips_force_enable_field_alert.de = fips_force_enable_pfa; + assign hw2reg.recov_alert_sts.fips_force_enable_field_alert.d = fips_force_enable_pfa; + + caliptra_prim_mubi4_sync #( + .NumCopies(2), + .AsyncOn(0) + ) u_caliptra_prim_mubi4_sync_fips_force_enable ( + .clk_i, + .rst_ni, + .mubi_i(mubi_fips_force_enable), + .mubi_o(mubi_fips_force_enable_fanout) + ); + + // master module enable + assign sw_app_enable = sw_app_enable_pfe; + assign read_int_state = read_int_state_pfe; + assign fips_force_enable = fips_force_enable_pfe; + + //------------------------------------------ + // application interface + //------------------------------------------ + // Each application port has its own + // csrng_cmd_stage block to recieve the + // command, track the state of its completion, + // and return any genbits if the command + // is a generate command. + + for (genvar ai = 0; ai < NApps; ai = ai+1) begin : gen_cmd_stage + + csrng_cmd_stage #( + .CmdFifoWidth(AppCmdWidth), + .CmdFifoDepth(AppCmdFifoDepth), + .StateId(StateId) + ) u_csrng_cmd_stage ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .cs_enable_i (cs_enable_fo[27]), + .cmd_stage_vld_i (cmd_stage_vld[ai]), + .cmd_stage_shid_i (cmd_stage_shid[ai]), + .cmd_stage_bus_i (cmd_stage_bus[ai]), + .cmd_stage_rdy_o (cmd_stage_rdy[ai]), + .reseed_cnt_reached_i (reseed_cnt_reached_q[ai]), + .reseed_cnt_alert_o (reseed_cnt_alert[ai]), + .invalid_cmd_seq_alert_o (invalid_cmd_seq_alert[ai]), + .invalid_acmd_alert_o (invalid_acmd_alert[ai]), + .cmd_arb_req_o (cmd_arb_req[ai]), + .cmd_arb_sop_o (cmd_arb_sop[ai]), + .cmd_arb_mop_o (cmd_arb_mop[ai]), + .cmd_arb_eop_o (cmd_arb_eop[ai]), + .cmd_arb_gnt_i (cmd_arb_gnt[ai]), + .cmd_arb_bus_o (cmd_arb_bus[ai]), + .cmd_ack_i (cmd_core_ack[ai]), + .cmd_ack_sts_i (cmd_core_ack_sts[ai]), + .cmd_stage_ack_o (cmd_stage_ack[ai]), + .cmd_stage_ack_sts_o (cmd_stage_ack_sts[ai]), + .genbits_vld_i (genbits_core_vld[ai]), + .genbits_bus_i (genbits_core_bus[ai]), + .genbits_fips_i (genbits_core_fips[ai]), + .genbits_vld_o (genbits_stage_vld[ai]), + .genbits_rdy_i (genbits_stage_rdy[ai]), + .genbits_bus_o (genbits_stage_bus[ai]), + .genbits_fips_o (genbits_stage_fips[ai]), + .cmd_stage_sfifo_cmd_err_o (cmd_stage_sfifo_cmd_err[ai]), + .cmd_stage_sfifo_genbits_err_o(cmd_stage_sfifo_genbits_err[ai]), + .cmd_gen_cnt_err_o (cmd_gen_cnt_err[ai]), + .cmd_stage_sm_err_o (cmd_stage_sm_err[ai]) + ); + + // Set reseed_cnt_reached_d to true if the max number of generate requests between reseeds + // has been reached for the respective counter. + assign reseed_cnt_reached_d[ai] = + state_db_wr_req && state_db_wr_req_rdy && (state_db_wr_inst_id == ai) ? + (state_db_wr_rc >= reg2hw.reseed_interval.q) : + reseed_cnt_reached_q[ai]; + + end : gen_cmd_stage + + // SW interface connection (only 1, and must be present) + // cmd req + assign cmd_stage_vld[NApps-1] = reg2hw.cmd_req.qe; + assign cmd_stage_shid[NApps-1] = StateId'(NApps-1); + assign cmd_stage_bus[NApps-1] = reg2hw.cmd_req.q; + assign hw2reg.sw_cmd_sts.cmd_rdy.de = 1'b1; + assign hw2reg.sw_cmd_sts.cmd_rdy.d = cmd_rdy; + assign cmd_rdy = !cmd_stage_vld[NApps-1] && sw_rdy_sts_q; + assign sw_rdy_sts_d = + !cs_enable_fo[28] ? 1'b0 : + cmd_stage_vld[NApps-1] ? 1'b0 : + cmd_stage_rdy[NApps-1] ? 1'b1 : + sw_rdy_sts_q; + // cmd sts ack + assign hw2reg.sw_cmd_sts.cmd_ack.de = 1'b1; + assign hw2reg.sw_cmd_sts.cmd_ack.d = sw_sts_ack_d; + assign sw_sts_ack = cmd_stage_ack[NApps-1]; + assign sw_sts_ack_d = + !cs_enable_fo[28] ? 1'b0 : + cmd_stage_vld[NApps-1] ? 1'b0 : + cmd_stage_ack[NApps-1] ? 1'b1 : + sw_sts_ack_q; + // cmd ack sts + assign hw2reg.sw_cmd_sts.cmd_sts.de = cmd_stage_ack[NApps-1]; + assign hw2reg.sw_cmd_sts.cmd_sts.d = cmd_stage_ack_sts[NApps-1]; + // genbits + assign hw2reg.genbits_vld.genbits_vld.d = genbits_stage_vldo_sw; + assign hw2reg.genbits_vld.genbits_fips.d = genbits_stage_fips_sw; + assign hw2reg.genbits.d = (sw_app_enable && efuse_sw_app_enable[0]) ? genbits_stage_bus_sw : '0; + assign genbits_stage_bus_rd_sw = reg2hw.genbits.re; + + assign efuse_sw_app_enable[0] = caliptra_prim_mubi_pkg::mubi8_test_true_strict(en_csrng_sw_app_read[0]); + assign efuse_sw_app_enable[1] = caliptra_prim_mubi_pkg::mubi8_test_true_strict(en_csrng_sw_app_read[1]); + + caliptra_prim_mubi8_sync #( + .NumCopies(2), + .AsyncOn(1) + ) u_caliptra_prim_mubi8_sync_sw_app_read ( + .clk_i, + .rst_ni, + .mubi_i(otp_en_csrng_sw_app_read_i), + .mubi_o(en_csrng_sw_app_read) + ); + + // pack the gen bits into a 32 bit register sized word + + caliptra_prim_packer_fifo #( + .InW(BlkLen), + .OutW(32), + .ClearOnRead(1'b0) + ) u_caliptra_prim_packer_fifo_sw_genbits ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .clr_i (!cs_enable_fo[29]), + .wvalid_i (genbits_stage_vld[NApps-1]), + .wdata_i (genbits_stage_bus[NApps-1]), + .wready_o (genbits_stage_rdy[NApps-1]), + .rvalid_o (genbits_stage_vldo_sw), + .rdata_o (genbits_stage_bus_sw), + .rready_i (genbits_stage_bus_rd_sw), + .depth_o () + ); + + // flops for SW fips status + assign genbits_stage_fips_sw_d = + (!cs_enable_fo[30]) ? 1'b0 : + (genbits_stage_rdy[NApps-1] && genbits_stage_vld[NApps-1]) ? genbits_stage_fips[NApps-1] : + genbits_stage_fips_sw_q; + + assign genbits_stage_fips_sw = genbits_stage_fips_sw_q; + + + //-------------------------------------------- + // data path integrity check + // - a countermeasure to detect entropy bus tampering attempts + // - checks to make sure repeated data sets off + // an alert for sw to handle + //-------------------------------------------- + + // SEC_CM: SW_GENBITS.BUS.CONSISTENCY + + // capture a copy of the genbits data + assign cs_rdata_capt_vld = (genbits_stage_vld[NApps-1] && genbits_stage_rdy[NApps-1]); + + assign cs_rdata_capt_d = cs_rdata_capt_vld ? genbits_stage_bus[NApps-1][63:0] : cs_rdata_capt_q; + + assign cs_rdata_capt_vld_d = + !cs_enable_fo[31] ? 1'b0 : + cs_rdata_capt_vld ? 1'b1 : + cs_rdata_capt_vld_q; + + // continuous compare of the entropy data for sw port + assign cs_bus_cmp_alert = cs_rdata_capt_vld && cs_rdata_capt_vld_q && + (cs_rdata_capt_q == genbits_stage_bus[NApps-1][63:0]); // only look at 64 bits + + assign hw2reg.recov_alert_sts.cs_bus_cmp_alert.de = cs_bus_cmp_alert; + assign hw2reg.recov_alert_sts.cs_bus_cmp_alert.d = cs_bus_cmp_alert; + + assign hw2reg.recov_alert_sts.cmd_stage_invalid_acmd_alert.de = |invalid_acmd_alert; + assign hw2reg.recov_alert_sts.cmd_stage_invalid_acmd_alert.d = |invalid_acmd_alert; + + assign hw2reg.recov_alert_sts.cmd_stage_invalid_cmd_seq_alert.de = |invalid_cmd_seq_alert; + assign hw2reg.recov_alert_sts.cmd_stage_invalid_cmd_seq_alert.d = |invalid_cmd_seq_alert; + + assign hw2reg.recov_alert_sts.cmd_stage_reseed_cnt_alert.de = |reseed_cnt_alert; + assign hw2reg.recov_alert_sts.cmd_stage_reseed_cnt_alert.d = |reseed_cnt_alert; + + // HW interface connections (up to 16, numbered 0-14) + for (genvar hai = 0; hai < (NApps-1); hai = hai+1) begin : gen_app_if + // cmd req + assign cmd_stage_vld[hai] = csrng_cmd_i[hai].csrng_req_valid; + assign cmd_stage_shid[hai] = hai; + assign cmd_stage_bus[hai] = csrng_cmd_i[hai].csrng_req_bus; + assign csrng_cmd_o[hai].csrng_req_ready = cmd_stage_rdy[hai]; + // cmd ack + assign csrng_cmd_o[hai].csrng_rsp_ack = cmd_stage_ack[hai]; + assign csrng_cmd_o[hai].csrng_rsp_sts = cmd_stage_ack_sts[hai]; + // genbits + assign csrng_cmd_o[hai].genbits_valid = genbits_stage_vld[hai]; + assign csrng_cmd_o[hai].genbits_fips = genbits_stage_fips[hai]; + assign csrng_cmd_o[hai].genbits_bus = genbits_stage_bus[hai]; + assign genbits_stage_rdy[hai] = csrng_cmd_i[hai].genbits_ready; + end : gen_app_if + + // set ack status for configured instances + for (genvar i = 0; i < NHwApps; i = i+1) begin : gen_app_if_sts + assign hw_exception_sts[i] = cmd_stage_ack[i] && (cmd_stage_ack_sts[i] != CMD_STS_SUCCESS); + end : gen_app_if_sts + + // set ack status to zero for un-configured instances + for (genvar i = NHwApps; i < 16; i = i+1) begin : gen_app_if_zero_sts + assign hw_exception_sts[i] = 1'b0; + end : gen_app_if_zero_sts + + // set fifo err status bits + for (genvar i = 0; i < NApps; i = i+1) begin : gen_fifo_sts + assign cmd_stage_sfifo_cmd_err_sum[i] = (|cmd_stage_sfifo_cmd_err[i] || + err_code_test_bit[0]); + assign cmd_stage_sfifo_cmd_err_wr[i] = cmd_stage_sfifo_cmd_err[i][2]; + assign cmd_stage_sfifo_cmd_err_rd[i] = cmd_stage_sfifo_cmd_err[i][1]; + assign cmd_stage_sfifo_cmd_err_st[i] = cmd_stage_sfifo_cmd_err[i][0]; + assign cmd_stage_sfifo_genbits_err_sum[i] = (|cmd_stage_sfifo_genbits_err[i] || + err_code_test_bit[1]); + assign cmd_stage_sfifo_genbits_err_wr[i] = cmd_stage_sfifo_genbits_err[i][2]; + assign cmd_stage_sfifo_genbits_err_rd[i] = cmd_stage_sfifo_genbits_err[i][1]; + assign cmd_stage_sfifo_genbits_err_st[i] = cmd_stage_sfifo_genbits_err[i][0]; + end : gen_fifo_sts + + //------------------------------------------ + // app command arbiter and state machine + //------------------------------------------ + // All commands that arrive from the + // application ports are arbitrated for + // and processed by the main state machine + // logic block. + + assign cmd_arb_idx_d = (acmd_avail && acmd_accept) ? cmd_arb_idx : cmd_arb_idx_q; + + assign acmd_sop = cmd_arb_sop[cmd_arb_idx_q]; + assign acmd_mop = cmd_arb_mop[cmd_arb_idx_q]; + assign acmd_eop = cmd_arb_eop[cmd_arb_idx_q]; + assign acmd_bus = cmd_arb_bus[cmd_arb_idx_q]; + + // Can't be fed directly to port-list per Synthesis failure + assign cmd_arb_di = '{1'b0, 1'b0, 1'b0}; + + caliptra_prim_arbiter_ppc #( + .EnDataPort(0), // Ignore data port + .N(NApps), // Number of request ports + .DW(1) // Data width + ) u_caliptra_prim_arbiter_ppc_acmd ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .req_chk_i(cs_enable_fo[1]), + .req_i (cmd_arb_req), + .data_i (cmd_arb_di), + .gnt_o (cmd_arb_gnt), + .idx_o (cmd_arb_idx), + .valid_o (acmd_avail), // 1 req + .data_o (), //NC + .ready_i (acmd_accept) // 1 fsm rdy + ); + + mubi4_t mubi_acmd_flag0; + assign mubi_acmd_flag0 = mubi4_t'(acmd_bus[11:8]); + assign acmd_flag0_pfa = mubi4_test_invalid(flag0_q); + assign hw2reg.recov_alert_sts.acmd_flag0_field_alert.de = acmd_flag0_pfa; + assign hw2reg.recov_alert_sts.acmd_flag0_field_alert.d = acmd_flag0_pfa; + + // parse the command bus + assign acmd_hold = acmd_sop ? acmd_bus[2:0] : acmd_q; + assign flag0 = mubi_acmd_flag0; + assign shid = acmd_bus[15:12]; + assign gen_last = acmd_bus[16]; + + assign acmd_d = + (!cs_enable_fo[32]) ? '0 : + acmd_sop ? acmd_bus[2:0] : + acmd_q; + + assign shid_d = + (!cs_enable_fo[33]) ? '0 : + acmd_sop ? shid : + shid_q; + + assign gen_last_d = + (!cs_enable_fo[34]) ? '0 : + acmd_sop ? gen_last : + gen_last_q; + + assign flag0_d = + (!cs_enable_fo[35]) ? caliptra_prim_mubi_pkg::MuBi4False : + (acmd_sop && ((acmd_bus[2:0] == INS) || (acmd_bus[2:0] == RES))) ? flag0 : + flag0_q; + + // SEC_CM: CTRL.MUBI + mubi4_t mubi_flag0; + assign mubi_flag0 = flag0_q; + + for (genvar i = 0; i < Flag0Copies; i = i+1) begin : gen_mubi_flag0_copies + assign flag0_fo[i] = mubi4_test_true_strict(mubi_flag0_fanout[i]); + end : gen_mubi_flag0_copies + + caliptra_prim_mubi4_sync #( + .NumCopies(Flag0Copies), + .AsyncOn(0) + ) u_caliptra_prim_mubi4_sync_flag0 ( + .clk_i, + .rst_ni, + .mubi_i(mubi_flag0), + .mubi_o(mubi_flag0_fanout) + ); + + // sm to process all instantiation requests + // SEC_CM: MAIN_SM.CTR.LOCAL_ESC + // SEC_CM: MAIN_SM.FSM.SPARSE + csrng_main_sm u_csrng_main_sm ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .enable_i (cs_enable_fo[36]), + .acmd_avail_i (acmd_avail), + .acmd_accept_o (acmd_accept), + .acmd_i (acmd_hold), + .acmd_eop_i (acmd_eop), + .ctr_drbg_cmd_req_rdy_i (ctr_drbg_cmd_req_rdy), + .flag0_i (flag0_fo[0]), + .cmd_entropy_req_o (cmd_entropy_req), + .cmd_entropy_avail_i (cmd_entropy_avail), + .instant_req_o (instant_req), + .reseed_req_o (reseed_req), + .generate_req_o (generate_req), + .update_req_o (update_req), + .uninstant_req_o (uninstant_req), + .clr_adata_packer_o (clr_adata_packer), + .cmd_complete_i (state_db_wr_req), + .local_escalate_i (fatal_loc_events), + .main_sm_state_o (cs_main_sm_state), + .main_sm_err_o (cs_main_sm_err) + ); + + // interrupt for sw app interface only + assign event_cs_cmd_req_done = sw_sts_ack; + + // interrupt for entropy request + assign event_cs_entropy_req = entropy_src_hw_if_o.es_req; + + // interrupt for app interface exception + assign event_cs_hw_inst_exc = |hw_exception_sts; + + // entropy available + assign cmd_entropy_avail = entropy_src_hw_if_i.es_ack; + + for (genvar csi = 0; csi < NApps; csi = csi+1) begin : gen_cmd_ack + assign cmd_core_ack[csi] = state_db_sts_ack && (state_db_sts_id == csi); + assign cmd_core_ack_sts[csi] = state_db_sts_sts; + assign genbits_core_vld[csi] = gen_result_wr_req && (gen_result_inst_id == csi); + assign genbits_core_bus[csi] = gen_result_bits; + assign genbits_core_fips[csi] = gen_result_fips; + end : gen_cmd_ack + + + caliptra_prim_packer_fifo #( + .InW(32), + .OutW(SeedLen), + .ClearOnRead(1'b1) + ) u_caliptra_prim_packer_fifo_adata ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .clr_i (!cs_enable_fo[37] || packer_adata_clr), + .wvalid_i (acmd_mop), + .wdata_i (acmd_bus), + .wready_o (), + .rvalid_o (), + .rdata_o (packer_adata), + .rready_i (packer_adata_pop), + .depth_o (packer_adata_depth) + ); + + assign packer_adata_pop = cs_enable_fo[38] && + clr_adata_packer && (packer_adata_depth == ADataDepthClog'(MaxClen)); + + assign packer_adata_clr = cs_enable_fo[39] && + clr_adata_packer && (packer_adata_depth < ADataDepthClog'(MaxClen)); + + //------------------------------------- + // csrng_state_db nstantiation + //------------------------------------- + // This block holds the internal state + // of each csrng instance. The state + // is updated after each command. + + assign cmd_result_wr_req = cmd_result_ack && (cmd_result_ccmd != GEN); + + // register read access + assign state_db_reg_rd_sel = reg2hw.int_state_val.re; + assign state_db_reg_rd_id = reg2hw.int_state_num.q; + assign state_db_reg_rd_id_pulse = reg2hw.int_state_num.qe; + assign hw2reg.int_state_val.d = state_db_reg_rd_val; + assign state_db_is_dump_en = cs_enable_fo[40] && read_int_state && efuse_sw_app_enable[1]; + assign int_state_read_enable = reg2hw.int_state_read_enable.q; + + csrng_state_db #( + .NApps(NApps), + .StateId(StateId), + .BlkLen(BlkLen), + .KeyLen(KeyLen), + .CtrLen(CtrLen), + .Cmd(Cmd) + ) u_csrng_state_db ( + .clk_i(clk_i), + .rst_ni(rst_ni), + .state_db_enable_i(cs_enable_fo[41]), + .state_db_rd_inst_id_i(shid_q), + .state_db_rd_key_o(state_db_rd_key), + .state_db_rd_v_o(state_db_rd_v), + .state_db_rd_res_ctr_o(state_db_rd_rc), + .state_db_rd_inst_st_o(), // NC + .state_db_rd_fips_o(state_db_rd_fips), + + .state_db_wr_req_i(state_db_wr_req), + .state_db_wr_req_rdy_o(state_db_wr_req_rdy), + .state_db_wr_inst_id_i(state_db_wr_inst_id), + .state_db_wr_fips_i(state_db_wr_fips), + .state_db_wr_ccmd_i(state_db_wr_ccmd), + .state_db_wr_key_i(state_db_wr_key), + .state_db_wr_v_i(state_db_wr_v), + .state_db_wr_res_ctr_i(state_db_wr_rc), + .state_db_wr_sts_i(state_db_wr_sts), + + .state_db_is_dump_en_i(state_db_is_dump_en), + .state_db_reg_rd_sel_i(state_db_reg_rd_sel), + .state_db_reg_rd_id_pulse_i(state_db_reg_rd_id_pulse), + .state_db_reg_rd_id_i(state_db_reg_rd_id), + .state_db_reg_rd_val_o(state_db_reg_rd_val), + .state_db_sts_ack_o(state_db_sts_ack), + .state_db_sts_sts_o(state_db_sts_sts), + .state_db_sts_id_o(state_db_sts_id), + .int_state_read_enable_i(int_state_read_enable), + + .reseed_counter_o(reseed_counter) + ); + + assign statedb_wr_select_d = + (!cs_enable_fo[42]) ? '0 : + !statedb_wr_select_q; + + assign cmd_blk_select = !statedb_wr_select_q; + assign gen_blk_select = statedb_wr_select_q; + + // return to requesting block + assign cmd_result_ack_rdy = (cmd_blk_select && state_db_wr_req_rdy) && ctr_drbg_gen_req_rdy; + assign gen_result_ack_rdy = gen_blk_select && state_db_wr_req_rdy; + + // muxes for statedb block inputs + assign state_db_wr_req = gen_blk_select ? gen_result_wr_req : cmd_result_wr_req; + assign state_db_wr_inst_id = gen_blk_select ? gen_result_inst_id : cmd_result_inst_id; + assign state_db_wr_fips = gen_blk_select ? gen_result_fips : cmd_result_fips; + assign state_db_wr_ccmd = gen_blk_select ? gen_result_ccmd : cmd_result_ccmd; + assign state_db_wr_key = gen_blk_select ? gen_result_key : cmd_result_key; + assign state_db_wr_v = gen_blk_select ? gen_result_v : cmd_result_v; + assign state_db_wr_rc = gen_blk_select ? gen_result_rc : cmd_result_rc; + assign state_db_wr_sts = gen_blk_select ? gen_result_ack_sts : cmd_result_ack_sts; + + // Forward the reseed counter values to the register interface. + always_comb begin : reseed_counter_assign + for (int i = 0; i < NApps; i++) begin + hw2reg.reseed_counter[i].d = reseed_counter[i]; + end + end + + //-------------------------------------------- + // entropy interface + //-------------------------------------------- + // Basic interface logic with the entropy_src block + + assign entropy_src_hw_if_o.es_req = cs_enable_fo[43] && + cmd_entropy_req; + + + // SEC_CM: CONSTANTS.LC_GATED + assign seed_diversification = lc_hw_debug_on_fo[0] ? RndCnstCsKeymgrDivNonProduction : + RndCnstCsKeymgrDivProduction; + + // Capture entropy from entropy_src + assign entropy_src_seed_d = + flag0_fo[1] ? '0 : // special case where zero is used + cmd_entropy_req && cmd_entropy_avail ? + (entropy_src_hw_if_i.es_bits ^ seed_diversification) : + entropy_src_seed_q; + assign entropy_src_fips_d = + // Use shid_d here such that u_csrng_ctr_drbg_cmd gets the shid_q and the proper + // entropy_src_fips_q in the next clock cycle. + fips_force_enable && reg2hw.fips_force.q[shid_d[NAppsLog-1:0]] ? 1'b1 : + flag0_fo[2] ? '0 : // special case where zero is used + cmd_entropy_req && cmd_entropy_avail ? entropy_src_hw_if_i.es_fips : + entropy_src_fips_q; + + assign cmd_entropy = entropy_src_seed_q; + + assign cmd_entropy_fips = entropy_src_fips_q; + + //------------------------------------- + // csrng_ctr_drbg_cmd instantiation + //------------------------------------- + // commands and input parameters + // ins -> send to csrng_state_db + // inputs: 384b entropy, 384b adata + // outputs: 416b K,V,RC + // + // res -> send to csrng_state_db + // inputs: 416b K,V,RC, 384b entropy, 384b adata + // outputs: 416b K,V,RC + // + // gen -> send to csrng_ctr_drbg_gen block + // inputs: 416b K,V,RC, 384b adata + // outputs: 416b K,V,RC, 384b adata + // + // gen blk -> send to csrng_state_db + // inputs: 416b K,V,RC, 384b adata + // outputs: 416b K,V,RC, 128b genbits + // + // upd -> send to csrng_state_db + // inputs: 416b K,V,RC, 384b adata + // outputs: 416b K,V,RC + + + + assign cmd_req_ccmd_dly_d = + (!cs_enable_fo[44]) ? '0 : + acmd_hold; + + assign ctr_drbg_cmd_ccmd = cmd_req_ccmd_dly_q; + + + assign cmd_req_dly_d = + (!cs_enable_fo[45]) ? '0 : + (instant_req || reseed_req || generate_req || update_req || uninstant_req); + + assign ctr_drbg_cmd_req = cmd_req_dly_q; + + csrng_ctr_drbg_cmd #( + .Cmd(Cmd), + .StateId(StateId), + .BlkLen(BlkLen), + .KeyLen(KeyLen), + .SeedLen(SeedLen), + .CtrLen(CtrLen) + ) u_csrng_ctr_drbg_cmd ( + .clk_i(clk_i), + .rst_ni(rst_ni), + .ctr_drbg_cmd_enable_i(cs_enable_fo[46]), + .ctr_drbg_cmd_req_i(ctr_drbg_cmd_req), + .ctr_drbg_cmd_rdy_o(ctr_drbg_cmd_req_rdy), + .ctr_drbg_cmd_ccmd_i(ctr_drbg_cmd_ccmd), + .ctr_drbg_cmd_inst_id_i(shid_q), + .ctr_drbg_cmd_glast_i(gen_last_q), + .ctr_drbg_cmd_entropy_i(cmd_entropy), + .ctr_drbg_cmd_entropy_fips_i(cmd_entropy_fips), // send to state_db + .ctr_drbg_cmd_adata_i(packer_adata), + .ctr_drbg_cmd_key_i(state_db_rd_key), + .ctr_drbg_cmd_v_i(state_db_rd_v), + .ctr_drbg_cmd_rc_i(state_db_rd_rc), + .ctr_drbg_cmd_fips_i(state_db_rd_fips), // send to genbits user + + .ctr_drbg_cmd_ack_o(cmd_result_ack), + .ctr_drbg_cmd_sts_o(cmd_result_ack_sts), + .ctr_drbg_cmd_rdy_i(cmd_result_ack_rdy), + .ctr_drbg_cmd_ccmd_o(cmd_result_ccmd), + .ctr_drbg_cmd_inst_id_o(cmd_result_inst_id), + .ctr_drbg_cmd_glast_o(cmd_result_glast), + .ctr_drbg_cmd_fips_o(cmd_result_fips), + .ctr_drbg_cmd_adata_o(cmd_result_adata), + .ctr_drbg_cmd_key_o(cmd_result_key), + .ctr_drbg_cmd_v_o(cmd_result_v), + .ctr_drbg_cmd_rc_o(cmd_result_rc), + + // interface to updblk from cmdblk + .cmd_upd_req_o(cmdblk_updblk_arb_req), + .upd_cmd_rdy_i(updblk_cmdblk_arb_req_rdy), + .cmd_upd_ccmd_o(cmdblk_updblk_ccmd_arb_din), + .cmd_upd_inst_id_o(cmdblk_updblk_id_arb_din), + .cmd_upd_pdata_o(cmdblk_updblk_pdata_arb_din), + .cmd_upd_key_o(cmdblk_updblk_key_arb_din), + .cmd_upd_v_o(cmdblk_updblk_v_arb_din), + + .upd_cmd_ack_i(updblk_cmdblk_ack), + .cmd_upd_rdy_o(cmdblk_updblk_ack_rdy), + .upd_cmd_ccmd_i(updblk_ccmd), + .upd_cmd_inst_id_i(updblk_inst_id), + .upd_cmd_key_i(updblk_key), + .upd_cmd_v_i(updblk_v), + + .ctr_drbg_cmd_sfifo_cmdreq_err_o(ctr_drbg_cmd_sfifo_cmdreq_err), + .ctr_drbg_cmd_sfifo_rcstage_err_o(ctr_drbg_cmd_sfifo_rcstage_err), + .ctr_drbg_cmd_sfifo_keyvrc_err_o(ctr_drbg_cmd_sfifo_keyvrc_err) + ); + + + //------------------------------------- + // csrng_ctr_drbg_upd instantiation + //------------------------------------- + // The csrng_ctr_drbg_upd is shared + // between the csrng_ctr_drbg_cmd block + // and the csrng_ctr_drbg_gen block. + // The arbiter in this section will + // route requests and responses between + // these two blocks. + + + csrng_ctr_drbg_upd #( + .Cmd(Cmd), + .StateId(StateId), + .BlkLen(BlkLen), + .KeyLen(KeyLen), + .SeedLen(SeedLen), + .CtrLen(CtrLen) + ) u_csrng_ctr_drbg_upd ( + .clk_i(clk_i), + .rst_ni(rst_ni), + .ctr_drbg_upd_enable_i(cs_enable_fo[47]), + .ctr_drbg_upd_req_i(updblk_arb_vld), + .ctr_drbg_upd_rdy_o(updblk_arb_rdy), + .ctr_drbg_upd_ack_o(updblk_ack), + .ctr_drbg_upd_rdy_i(updblk_ack_rdy), + .ctr_drbg_upd_ccmd_i(updblk_arb_ccmd), + .ctr_drbg_upd_inst_id_i(updblk_arb_inst_id), + .ctr_drbg_upd_pdata_i(updblk_arb_pdata), + .ctr_drbg_upd_key_i(updblk_arb_key), + .ctr_drbg_upd_v_i(updblk_arb_v), + .ctr_drbg_upd_ccmd_o(updblk_ccmd), + .ctr_drbg_upd_inst_id_o(updblk_inst_id), + .ctr_drbg_upd_key_o(updblk_key), + .ctr_drbg_upd_v_o(updblk_v), + + // es halt interface + .ctr_drbg_upd_es_req_i(cs_aes_halt_i.cs_aes_halt_req), + .ctr_drbg_upd_es_ack_o(ctr_drbg_upd_es_ack), + + .block_encrypt_req_o(updblk_benblk_arb_req), + .block_encrypt_rdy_i(updblk_benblk_arb_req_rdy), + .block_encrypt_ccmd_o(updblk_benblk_cmd_arb_din), + .block_encrypt_inst_id_o(updblk_benblk_id_arb_din), + .block_encrypt_key_o(updblk_benblk_key_arb_din), + .block_encrypt_v_o(updblk_benblk_v_arb_din), + .block_encrypt_ack_i(benblk_updblk_ack), + .block_encrypt_rdy_o(updblk_benblk_ack_rdy), + .block_encrypt_ccmd_i(benblk_cmd), + .block_encrypt_inst_id_i(benblk_inst_id), + .block_encrypt_v_i(benblk_v), + .ctr_drbg_upd_v_ctr_err_o(ctr_drbg_upd_v_ctr_err), + .ctr_drbg_upd_sfifo_updreq_err_o(ctr_drbg_upd_sfifo_updreq_err), + .ctr_drbg_upd_sfifo_bencreq_err_o(ctr_drbg_upd_sfifo_bencreq_err), + .ctr_drbg_upd_sfifo_bencack_err_o(ctr_drbg_upd_sfifo_bencack_err), + .ctr_drbg_upd_sfifo_pdata_err_o(ctr_drbg_upd_sfifo_pdata_err), + .ctr_drbg_upd_sfifo_final_err_o(ctr_drbg_upd_sfifo_final_err), + .ctr_drbg_updbe_sm_err_o(drbg_updbe_sm_err), + .ctr_drbg_updob_sm_err_o(drbg_updob_sm_err) + ); + + // update block arbiter + + caliptra_prim_arbiter_ppc #( + .N(NUpdateArbReqs), // (cmd req and gen req) + .DW(UpdateArbWidth) // Data width + ) u_caliptra_prim_arbiter_ppc_updblk_arb ( + .clk_i(clk_i), + .rst_ni(rst_ni), + .req_chk_i(cs_enable_fo[1]), + .req_i({genblk_updblk_arb_req,cmdblk_updblk_arb_req}), + .data_i(updblk_arb_din), + .gnt_o({updblk_genblk_arb_req_rdy,updblk_cmdblk_arb_req_rdy}), + .idx_o(), + .valid_o(updblk_arb_vld), + .data_o(updblk_arb_data), + .ready_i(updblk_arb_rdy) + ); + + assign updblk_arb_din[0] = {cmdblk_updblk_key_arb_din,cmdblk_updblk_v_arb_din, + cmdblk_updblk_pdata_arb_din, + cmdblk_updblk_id_arb_din,cmdblk_updblk_ccmd_arb_din}; + + assign updblk_arb_din[1] = {genblk_updblk_key_arb_din,genblk_updblk_v_arb_din, + genblk_updblk_pdata_arb_din, + genblk_updblk_id_arb_din,genblk_updblk_ccmd_arb_din}; + + assign {updblk_arb_key,updblk_arb_v,updblk_arb_pdata, + updblk_arb_inst_id,updblk_arb_ccmd} = updblk_arb_data; + + assign updblk_cmdblk_ack = (updblk_ack && (updblk_ccmd != GENU)); + assign updblk_genblk_ack = (updblk_ack && (updblk_ccmd == GENU)); + + assign updblk_ack_rdy = (updblk_ccmd == GENU) ? genblk_updblk_ack_rdy : cmdblk_updblk_ack_rdy; + + + //------------------------------------- + // life cycle logic + //------------------------------------- + // The chip level life cycle control + // provide control logic to determine + // how certain debug features are controlled. + + lc_ctrl_pkg::lc_tx_t [LcHwDebugCopies-1:0] lc_hw_debug_en_out; + + caliptra_prim_lc_sync #( + .NumCopies(LcHwDebugCopies) + ) u_caliptra_prim_lc_sync ( + .clk_i, + .rst_ni, + .lc_en_i(lc_hw_debug_en_i), + .lc_en_o({lc_hw_debug_en_out}) + ); + + for (genvar i = 0; i < LcHwDebugCopies; i = i+1) begin : gen_lc_dbg_copies + assign lc_hw_debug_on_fo[i] = lc_ctrl_pkg::lc_tx_test_true_strict(lc_hw_debug_en_out[i]); + end : gen_lc_dbg_copies + + + //------------------------------------- + // csrng_block_encrypt instantiation + //------------------------------------- + // The csrng_block_encrypt is shared + // between the csrng_ctr_drbg_cmd block + // and the csrng_ctr_drbg_gen block. + // The arbiter in this section will + // route requests and responses between + // these two blocks. + + csrng_block_encrypt #( + .SBoxImpl(SBoxImpl), + .Cmd(Cmd), + .StateId(StateId), + .BlkLen(BlkLen), + .KeyLen(KeyLen) + ) u_csrng_block_encrypt ( + .clk_i(clk_i), + .rst_ni(rst_ni), + .block_encrypt_enable_i(cs_enable_fo[48]), + .block_encrypt_req_i(benblk_arb_vld), + .block_encrypt_rdy_o(benblk_arb_rdy), + .block_encrypt_key_i(benblk_arb_key), + .block_encrypt_v_i(benblk_arb_v), + .block_encrypt_cmd_i(benblk_arb_cmd), + .block_encrypt_id_i(benblk_arb_inst_id), + .block_encrypt_ack_o(benblk_ack), + .block_encrypt_rdy_i(benblk_ack_rdy), + .block_encrypt_cmd_o(benblk_cmd), + .block_encrypt_id_o(benblk_inst_id), + .block_encrypt_v_o(benblk_v), + .block_encrypt_quiet_o(block_encrypt_quiet), + .block_encrypt_aes_cipher_sm_err_o(aes_cipher_sm_err), + .block_encrypt_sfifo_blkenc_err_o(block_encrypt_sfifo_blkenc_err) + ); + + + caliptra_prim_arbiter_ppc #( + .N(NBlkEncArbReqs), // (upd req and gen req) + .DW(BlkEncArbWidth) // Data width + ) u_caliptra_prim_arbiter_ppc_benblk_arb ( + .clk_i(clk_i), + .rst_ni(rst_ni), + .req_chk_i(cs_enable_fo[1]), + .req_i({genblk_benblk_arb_req,updblk_benblk_arb_req}), + .data_i(benblk_arb_din), + .gnt_o({genblk_benblk_arb_req_rdy,updblk_benblk_arb_req_rdy}), + .idx_o(), + .valid_o(benblk_arb_vld), + .data_o(benblk_arb_data), + .ready_i(benblk_arb_rdy) + ); + + assign benblk_arb_din[0] = {updblk_benblk_key_arb_din,updblk_benblk_v_arb_din, + updblk_benblk_id_arb_din,updblk_benblk_cmd_arb_din}; + assign benblk_arb_din[1] = {genblk_benblk_key_arb_din,genblk_benblk_v_arb_din, + genblk_benblk_id_arb_din,genblk_benblk_cmd_arb_din}; + + assign benblk_updblk_ack = (benblk_ack && (benblk_cmd != GENB)); + assign benblk_genblk_ack = (benblk_ack && (benblk_cmd == GENB)); + + assign benblk_ack_rdy = (benblk_cmd == GENB) ? genblk_benblk_ack_rdy : updblk_benblk_ack_rdy; + + assign {benblk_arb_key,benblk_arb_v,benblk_arb_inst_id,benblk_arb_cmd} = benblk_arb_data; + + + //------------------------------------- + // csrng_ctr_drbg_gen instantiation + //------------------------------------- + // this block performs the second sequence + // of the generate command. The first part + // of the sequence is done by the + // csrng_ctr_drbg_cmd block. + + assign ctr_drbg_gen_req = cmd_result_ack && (cmd_result_ccmd == GEN); + + + csrng_ctr_drbg_gen #( + .NApps(NApps), + .Cmd(Cmd), + .StateId(StateId), + .BlkLen(BlkLen), + .KeyLen(KeyLen), + .SeedLen(SeedLen), + .CtrLen(CtrLen) + ) u_csrng_ctr_drbg_gen ( + .clk_i(clk_i), + .rst_ni(rst_ni), + .ctr_drbg_gen_enable_i(cs_enable_fo[49]), + .ctr_drbg_gen_req_i(ctr_drbg_gen_req), + .ctr_drbg_gen_rdy_o(ctr_drbg_gen_req_rdy), + .ctr_drbg_gen_ccmd_i(cmd_result_ccmd), + .ctr_drbg_gen_inst_id_i(cmd_result_inst_id), + .ctr_drbg_gen_glast_i(cmd_result_glast), + .ctr_drbg_gen_fips_i(cmd_result_fips), + .ctr_drbg_gen_adata_i(cmd_result_adata), + .ctr_drbg_gen_key_i(cmd_result_key), + .ctr_drbg_gen_v_i(cmd_result_v), + .ctr_drbg_gen_rc_i(cmd_result_rc), + + .ctr_drbg_gen_ack_o(gen_result_wr_req), + .ctr_drbg_gen_sts_o(gen_result_ack_sts), + .ctr_drbg_gen_rdy_i(gen_result_ack_rdy), + .ctr_drbg_gen_ccmd_o(gen_result_ccmd), + .ctr_drbg_gen_inst_id_o(gen_result_inst_id), + .ctr_drbg_gen_fips_o(gen_result_fips), + .ctr_drbg_gen_key_o(gen_result_key), + .ctr_drbg_gen_v_o(gen_result_v), + .ctr_drbg_gen_rc_o(gen_result_rc), + .ctr_drbg_gen_bits_o(gen_result_bits), + + // es halt interface + .ctr_drbg_gen_es_req_i(cs_aes_halt_i.cs_aes_halt_req), + .ctr_drbg_gen_es_ack_o(ctr_drbg_gen_es_ack), + + // interface to updblk from genblk + .gen_upd_req_o(genblk_updblk_arb_req), + .upd_gen_rdy_i(updblk_genblk_arb_req_rdy), + .gen_upd_ccmd_o(genblk_updblk_ccmd_arb_din), + .gen_upd_inst_id_o(genblk_updblk_id_arb_din), + .gen_upd_pdata_o(genblk_updblk_pdata_arb_din), + .gen_upd_key_o(genblk_updblk_key_arb_din), + .gen_upd_v_o(genblk_updblk_v_arb_din), + + .upd_gen_ack_i(updblk_genblk_ack), + .gen_upd_rdy_o(genblk_updblk_ack_rdy), + .upd_gen_ccmd_i(updblk_ccmd), + .upd_gen_inst_id_i(updblk_inst_id), + .upd_gen_key_i(updblk_key), + .upd_gen_v_i(updblk_v), + + .block_encrypt_req_o(genblk_benblk_arb_req), + .block_encrypt_rdy_i(genblk_benblk_arb_req_rdy), + .block_encrypt_ccmd_o(genblk_benblk_cmd_arb_din), + .block_encrypt_inst_id_o(genblk_benblk_id_arb_din), + .block_encrypt_key_o(genblk_benblk_key_arb_din), + .block_encrypt_v_o(genblk_benblk_v_arb_din), + .block_encrypt_ack_i(benblk_genblk_ack), + .block_encrypt_rdy_o(genblk_benblk_ack_rdy), + .block_encrypt_ccmd_i(benblk_cmd), + .block_encrypt_inst_id_i(benblk_inst_id), + .block_encrypt_v_i(benblk_v), + + .ctr_drbg_gen_v_ctr_err_o(ctr_drbg_gen_v_ctr_err), + .ctr_drbg_gen_sfifo_gbencack_err_o(ctr_drbg_gen_sfifo_gbencack_err), + .ctr_drbg_gen_sfifo_grcstage_err_o(ctr_drbg_gen_sfifo_grcstage_err), + .ctr_drbg_gen_sfifo_ggenreq_err_o(ctr_drbg_gen_sfifo_ggenreq_err), + .ctr_drbg_gen_sfifo_gadstage_err_o(ctr_drbg_gen_sfifo_gadstage_err), + .ctr_drbg_gen_sfifo_ggenbits_err_o(ctr_drbg_gen_sfifo_ggenbits_err), + .ctr_drbg_gen_sm_err_o(drbg_gen_sm_err) + ); + + + // es to cs halt request to reduce power spikes + assign cs_aes_halt_d = + (ctr_drbg_upd_es_ack && ctr_drbg_gen_es_ack && block_encrypt_quiet && + cs_aes_halt_i.cs_aes_halt_req); + + assign cs_aes_halt_o.cs_aes_halt_ack = cs_aes_halt_q; + + //-------------------------------------------- + // observe state machine + //-------------------------------------------- + + assign hw2reg.main_sm_state.de = 1'b1; + assign hw2reg.main_sm_state.d = cs_main_sm_state; + + //-------------------------------------------- + // report csrng request summary + //-------------------------------------------- + // Misc status + + assign hw2reg.hw_exc_sts.de = cs_enable_fo[50]; + assign hw2reg.hw_exc_sts.d = hw_exception_sts; + + // unused signals + assign unused_err_code_test_bit = (|err_code_test_bit[19:16]) || (|err_code_test_bit[27:26]); + assign unused_reg2hw_genbits = (|reg2hw.genbits.q); + assign unused_int_state_val = (|reg2hw.int_state_val.q); + assign unused_reseed_interval = reg2hw.reseed_interval.qe; + + //-------------------------------------------- + // Assertions + //-------------------------------------------- +`ifdef CALIPTRA_INC_ASSERT + // Track activity of AES. + logic aes_active_d, aes_active_q; + assign aes_active_d = + (u_csrng_block_encrypt.u_aes_cipher_core.in_valid_i == aes_pkg::SP2V_HIGH && + u_csrng_block_encrypt.u_aes_cipher_core.in_ready_o == aes_pkg::SP2V_HIGH) ? 1'b1 : // set + (u_csrng_block_encrypt.u_aes_cipher_core.out_valid_o == aes_pkg::SP2V_HIGH && + u_csrng_block_encrypt.u_aes_cipher_core.out_ready_i == aes_pkg::SP2V_HIGH) ? 1'b0 : // clear + aes_active_q; // keep + + // Track state of AES Halt req/ack with entropy_src. + logic cs_aes_halt_active; + assign cs_aes_halt_active = cs_aes_halt_i.cs_aes_halt_req & cs_aes_halt_o.cs_aes_halt_ack; + + // Assert that when AES Halt is active, AES is not active. + `CALIPTRA_ASSERT(AesNotActiveWhileCsAesHaltActive_A, cs_aes_halt_active |-> !aes_active_d) + + always_ff @(posedge clk_i, negedge rst_ni) begin + if (!rst_ni) begin + aes_active_q <= '0; + end else begin + aes_active_q <= aes_active_d; + end + end + + logic state_db_zeroize; + assign state_db_zeroize = state_db_wr_req && (state_db_wr_ccmd == UNI); + `CALIPTRA_ASSERT(CsrngUniZeroizeFips_A, state_db_zeroize -> (state_db_wr_fips == '0)) + `CALIPTRA_ASSERT(CsrngUniZeroizeKey_A, state_db_zeroize -> (state_db_wr_key == '0)) + `CALIPTRA_ASSERT(CsrngUniZeroizeV_A, state_db_zeroize -> (state_db_wr_v == '0)) + `CALIPTRA_ASSERT(CsrngUniZeroizeRc_A, state_db_zeroize -> (state_db_wr_rc == '0)) + `CALIPTRA_ASSERT(CsrngUniZeroizeSts_A, state_db_zeroize -> (state_db_wr_sts == '0)) + + // The number of application interfaces defined in the hjson must match the number of + // application interfaces derived from the top-level parameter NHwApps. + `CALIPTRA_ASSERT_INIT(CsrngNumAppsMatch_A, NumApps == NApps) +`endif + +endmodule // csrng_core diff --git a/designs/Caliptra/src/caliptra-rtl/csrng_ctr_drbg_cmd.sv b/designs/Caliptra/src/caliptra-rtl/csrng_ctr_drbg_cmd.sv new file mode 100644 index 0000000..df0d231 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/csrng_ctr_drbg_cmd.sv @@ -0,0 +1,324 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Description: csrng ctr_drbg commands module +// +// Accepts all csrng commands + +`include "caliptra_prim_assert.sv" + +module csrng_ctr_drbg_cmd import csrng_pkg::*; #( + parameter logic [31:0] Cmd = 3, + parameter logic [31:0] StateId = 4, + parameter logic [31:0] BlkLen = 128, + parameter logic [31:0] KeyLen = 256, + parameter logic [31:0] SeedLen = 384, + parameter logic [31:0] CtrLen = 32 +) ( + input logic clk_i, + input logic rst_ni, + + // command interface + input logic ctr_drbg_cmd_enable_i, + input logic ctr_drbg_cmd_req_i, + output logic ctr_drbg_cmd_rdy_o, // ready to process the req above + input logic [Cmd-1:0] ctr_drbg_cmd_ccmd_i, // current command + input logic [StateId-1:0] ctr_drbg_cmd_inst_id_i, // instantance id + input logic ctr_drbg_cmd_glast_i, // gen cmd last beat + input logic [SeedLen-1:0] ctr_drbg_cmd_entropy_i, // es entropy + input logic ctr_drbg_cmd_entropy_fips_i, // es entropy)fips + input logic [SeedLen-1:0] ctr_drbg_cmd_adata_i, // additional data + input logic [KeyLen-1:0] ctr_drbg_cmd_key_i, + input logic [BlkLen-1:0] ctr_drbg_cmd_v_i, + input logic [CtrLen-1:0] ctr_drbg_cmd_rc_i, + input logic ctr_drbg_cmd_fips_i, + + output logic ctr_drbg_cmd_ack_o, // final ack when update process has been completed + output csrng_cmd_sts_e ctr_drbg_cmd_sts_o, // final ack status + input logic ctr_drbg_cmd_rdy_i, // ready to process the ack above + output logic [Cmd-1:0] ctr_drbg_cmd_ccmd_o, + output logic [StateId-1:0] ctr_drbg_cmd_inst_id_o, + output logic ctr_drbg_cmd_glast_o, + output logic ctr_drbg_cmd_fips_o, + output logic [SeedLen-1:0] ctr_drbg_cmd_adata_o, + output logic [KeyLen-1:0] ctr_drbg_cmd_key_o, + output logic [BlkLen-1:0] ctr_drbg_cmd_v_o, + output logic [CtrLen-1:0] ctr_drbg_cmd_rc_o, + + // update interface + output logic cmd_upd_req_o, + input logic upd_cmd_rdy_i, + output logic [Cmd-1:0] cmd_upd_ccmd_o, + output logic [StateId-1:0] cmd_upd_inst_id_o, + output logic [SeedLen-1:0] cmd_upd_pdata_o, + output logic [KeyLen-1:0] cmd_upd_key_o, + output logic [BlkLen-1:0] cmd_upd_v_o, + + input logic upd_cmd_ack_i, + output logic cmd_upd_rdy_o, + input logic [Cmd-1:0] upd_cmd_ccmd_i, + input logic [StateId-1:0] upd_cmd_inst_id_i, + input logic [KeyLen-1:0] upd_cmd_key_i, + input logic [BlkLen-1:0] upd_cmd_v_i, + // misc + output logic [2:0] ctr_drbg_cmd_sfifo_cmdreq_err_o, + output logic [2:0] ctr_drbg_cmd_sfifo_rcstage_err_o, + output logic [2:0] ctr_drbg_cmd_sfifo_keyvrc_err_o +); + + localparam logic[31:0] CmdreqFifoDepth = 1; + localparam logic[31:0] CmdreqFifoWidth = KeyLen+BlkLen+CtrLen+1+2*SeedLen+1+StateId+Cmd; + localparam logic[31:0] RCStageFifoDepth = 1; + localparam logic[31:0] RCStageFifoWidth = KeyLen+BlkLen+StateId+CtrLen+1+SeedLen+1+Cmd; + localparam logic[31:0] KeyVRCFifoDepth = 1; + localparam logic[31:0] KeyVRCFifoWidth = KeyLen+BlkLen+CtrLen+1+SeedLen+1+StateId+Cmd; + + + // signals + logic [Cmd-1:0] cmdreq_ccmd; + logic [StateId-1:0] cmdreq_id; + logic cmdreq_glast; + logic [SeedLen-1:0] cmdreq_entropy; + logic cmdreq_entropy_fips; + logic [SeedLen-1:0] cmdreq_adata; + logic [KeyLen-1:0] cmdreq_key; + logic [BlkLen-1:0] cmdreq_v; + logic [CtrLen-1:0] cmdreq_rc; + + logic [SeedLen-1:0] prep_seed_material; + logic [KeyLen-1:0] prep_key; + logic [BlkLen-1:0] prep_v; + logic [CtrLen-1:0] prep_rc; + logic prep_gen_adata_null; + logic [KeyLen-1:0] rcstage_key; + logic [BlkLen-1:0] rcstage_v; + logic [StateId-1:0] rcstage_id; + logic [CtrLen-1:0] rcstage_rc; + logic [Cmd-1:0] rcstage_ccmd; + logic rcstage_glast; + logic [SeedLen-1:0] rcstage_adata; + logic rcstage_fips; + logic fips_modified; + + // cmdreq fifo + logic [CmdreqFifoWidth-1:0] sfifo_cmdreq_rdata; + logic sfifo_cmdreq_push; + logic [CmdreqFifoWidth-1:0] sfifo_cmdreq_wdata; + logic sfifo_cmdreq_pop; + logic sfifo_cmdreq_full; + logic sfifo_cmdreq_not_empty; + + // rcstage fifo + logic [RCStageFifoWidth-1:0] sfifo_rcstage_rdata; + logic sfifo_rcstage_push; + logic [RCStageFifoWidth-1:0] sfifo_rcstage_wdata; + logic sfifo_rcstage_pop; + logic sfifo_rcstage_full; + logic sfifo_rcstage_not_empty; + + // keyvrc fifo + logic [KeyVRCFifoWidth-1:0] sfifo_keyvrc_rdata; + logic sfifo_keyvrc_push; + logic [KeyVRCFifoWidth-1:0] sfifo_keyvrc_wdata; + logic sfifo_keyvrc_pop; + logic sfifo_keyvrc_full; + logic sfifo_keyvrc_not_empty; + + // flops + logic gen_adata_null_q, gen_adata_null_d; + + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + gen_adata_null_q <= '0; + end else begin + gen_adata_null_q <= gen_adata_null_d; + end + end + + //-------------------------------------------- + // input request fifo for staging cmd request + //-------------------------------------------- + + caliptra_prim_fifo_sync #( + .Width(CmdreqFifoWidth), + .Pass(0), + .Depth(CmdreqFifoDepth), + .OutputZeroIfEmpty(1'b0) + ) u_caliptra_prim_fifo_sync_cmdreq ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .clr_i (!ctr_drbg_cmd_enable_i), + .wvalid_i (sfifo_cmdreq_push), + .wready_o (), + .wdata_i (sfifo_cmdreq_wdata), + .rvalid_o (sfifo_cmdreq_not_empty), + .rready_i (sfifo_cmdreq_pop), + .rdata_o (sfifo_cmdreq_rdata), + .full_o (sfifo_cmdreq_full), + .depth_o (), + .err_o () + ); + + assign fips_modified = ((ctr_drbg_cmd_ccmd_i == INS) || + (ctr_drbg_cmd_ccmd_i == RES)) ? ctr_drbg_cmd_entropy_fips_i : + ctr_drbg_cmd_fips_i; + + assign sfifo_cmdreq_wdata = {ctr_drbg_cmd_key_i,ctr_drbg_cmd_v_i, + ctr_drbg_cmd_rc_i,fips_modified, + ctr_drbg_cmd_entropy_i,ctr_drbg_cmd_adata_i, + ctr_drbg_cmd_glast_i, + ctr_drbg_cmd_inst_id_i,ctr_drbg_cmd_ccmd_i}; + + assign sfifo_cmdreq_push = ctr_drbg_cmd_enable_i && ctr_drbg_cmd_req_i; + + assign sfifo_cmdreq_pop = ctr_drbg_cmd_enable_i && + (upd_cmd_rdy_i || gen_adata_null_q) && sfifo_cmdreq_not_empty; + + assign {cmdreq_key,cmdreq_v,cmdreq_rc, + cmdreq_entropy_fips,cmdreq_entropy,cmdreq_adata, + cmdreq_glast,cmdreq_id,cmdreq_ccmd} = sfifo_cmdreq_rdata; + + assign ctr_drbg_cmd_rdy_o = !sfifo_cmdreq_full; + + assign ctr_drbg_cmd_sfifo_cmdreq_err_o = + {(sfifo_cmdreq_push && sfifo_cmdreq_full), + (sfifo_cmdreq_pop && !sfifo_cmdreq_not_empty), + (sfifo_cmdreq_full && !sfifo_cmdreq_not_empty)}; + + + //-------------------------------------------- + // prepare values for update step + //-------------------------------------------- + + assign prep_seed_material = + (cmdreq_ccmd == INS) ? (cmdreq_entropy ^ cmdreq_adata) : + (cmdreq_ccmd == RES) ? (cmdreq_entropy ^ cmdreq_adata) : + (cmdreq_ccmd == GEN) ? cmdreq_adata : + (cmdreq_ccmd == UPD) ? cmdreq_adata : + '0; + + assign prep_key = + (cmdreq_ccmd == INS) ? {KeyLen{1'b0}} : + (cmdreq_ccmd == RES) ? cmdreq_key : + (cmdreq_ccmd == GEN) ? cmdreq_key : + (cmdreq_ccmd == UPD) ? cmdreq_key : + '0; + + assign prep_v = + (cmdreq_ccmd == INS) ? {BlkLen{1'b0}} : + (cmdreq_ccmd == RES) ? cmdreq_v : + (cmdreq_ccmd == GEN) ? cmdreq_v : + (cmdreq_ccmd == UPD) ? cmdreq_v : + '0; + + assign prep_rc = + (cmdreq_ccmd == INS) ? {{(CtrLen-1){1'b0}},1'b0} : + (cmdreq_ccmd == RES) ? {{(CtrLen-1){1'b0}},1'b0} : + (cmdreq_ccmd == GEN) ? cmdreq_rc : + (cmdreq_ccmd == UPD) ? cmdreq_rc : + '0; + + assign prep_gen_adata_null = (cmdreq_ccmd == GEN) && (cmdreq_adata == '0); + + assign gen_adata_null_d = ~ctr_drbg_cmd_enable_i ? '0 : prep_gen_adata_null; + + // send to the update block + assign cmd_upd_req_o = sfifo_cmdreq_not_empty && !prep_gen_adata_null; + assign cmd_upd_ccmd_o = cmdreq_ccmd; + assign cmd_upd_inst_id_o = cmdreq_id; + assign cmd_upd_pdata_o = prep_seed_material; + assign cmd_upd_key_o = prep_key; + assign cmd_upd_v_o = prep_v; + + + + //-------------------------------------------- + // fifo to stage rc and command, waiting for update block to ack + //-------------------------------------------- + + caliptra_prim_fifo_sync #( + .Width(RCStageFifoWidth), + .Pass(0), + .Depth(RCStageFifoDepth), + .OutputZeroIfEmpty(1'b0) + ) u_caliptra_prim_fifo_sync_rcstage ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .clr_i (!ctr_drbg_cmd_enable_i), + .wvalid_i (sfifo_rcstage_push), + .wready_o (), + .wdata_i (sfifo_rcstage_wdata), + .rvalid_o (sfifo_rcstage_not_empty), + .rready_i (sfifo_rcstage_pop), + .rdata_o (sfifo_rcstage_rdata), + .full_o (sfifo_rcstage_full), + .depth_o (), + .err_o () + ); + + assign sfifo_rcstage_push = sfifo_cmdreq_pop; + assign sfifo_rcstage_wdata = {prep_key,prep_v,cmdreq_id,prep_rc,cmdreq_entropy_fips, + cmdreq_adata,cmdreq_glast,cmdreq_ccmd}; + assign sfifo_rcstage_pop = sfifo_rcstage_not_empty && (upd_cmd_ack_i || gen_adata_null_q); + assign {rcstage_key,rcstage_v,rcstage_id,rcstage_rc,rcstage_fips, + rcstage_adata,rcstage_glast,rcstage_ccmd} = sfifo_rcstage_rdata; + + + assign ctr_drbg_cmd_sfifo_rcstage_err_o = + {(sfifo_rcstage_push && sfifo_rcstage_full), + (sfifo_rcstage_pop && !sfifo_rcstage_not_empty), + (sfifo_rcstage_full && !sfifo_rcstage_not_empty)}; + + assign cmd_upd_rdy_o = sfifo_rcstage_not_empty && !sfifo_keyvrc_full; + + //-------------------------------------------- + // final cmd block processing + //-------------------------------------------- + + caliptra_prim_fifo_sync #( + .Width(KeyVRCFifoWidth), + .Pass(0), + .Depth(KeyVRCFifoDepth), + .OutputZeroIfEmpty(1'b0) + ) u_caliptra_prim_fifo_sync_keyvrc ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .clr_i (!ctr_drbg_cmd_enable_i), + .wvalid_i (sfifo_keyvrc_push), + .wready_o (), + .wdata_i (sfifo_keyvrc_wdata), + .rvalid_o (sfifo_keyvrc_not_empty), + .rready_i (sfifo_keyvrc_pop), + .rdata_o (sfifo_keyvrc_rdata), + .full_o (sfifo_keyvrc_full), + .depth_o (), + .err_o () + ); + + assign sfifo_keyvrc_push = sfifo_rcstage_pop; + + // if a UNI command, reset the state values + assign sfifo_keyvrc_wdata = (rcstage_ccmd == UNI) ? + {{(KeyLen+BlkLen+CtrLen+1+SeedLen){1'b0}},rcstage_glast,upd_cmd_inst_id_i,upd_cmd_ccmd_i} : + gen_adata_null_q ? + {rcstage_key,rcstage_v,rcstage_rc,rcstage_fips, + rcstage_adata,rcstage_glast,rcstage_id,rcstage_ccmd} : + {upd_cmd_key_i,upd_cmd_v_i,rcstage_rc,rcstage_fips, + rcstage_adata,rcstage_glast,upd_cmd_inst_id_i,upd_cmd_ccmd_i}; + + assign sfifo_keyvrc_pop = ctr_drbg_cmd_rdy_i && sfifo_keyvrc_not_empty; + assign {ctr_drbg_cmd_key_o,ctr_drbg_cmd_v_o,ctr_drbg_cmd_rc_o, + ctr_drbg_cmd_fips_o,ctr_drbg_cmd_adata_o,ctr_drbg_cmd_glast_o, + ctr_drbg_cmd_inst_id_o,ctr_drbg_cmd_ccmd_o} = sfifo_keyvrc_rdata; + + assign ctr_drbg_cmd_sfifo_keyvrc_err_o = + {(sfifo_keyvrc_push && sfifo_keyvrc_full), + (sfifo_keyvrc_pop && !sfifo_keyvrc_not_empty), + (sfifo_keyvrc_full && !sfifo_keyvrc_not_empty)}; + + // block ack + assign ctr_drbg_cmd_ack_o = sfifo_keyvrc_pop; + assign ctr_drbg_cmd_sts_o = CMD_STS_SUCCESS; + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/csrng_ctr_drbg_gen.sv b/designs/Caliptra/src/caliptra-rtl/csrng_ctr_drbg_gen.sv new file mode 100644 index 0000000..f38d141 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/csrng_ctr_drbg_gen.sv @@ -0,0 +1,606 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Description: csrng ctr_drbg generate module +// +// This module will process the second half of the generate function. +// It takes in the key, v, and reseed counter values processed by the +// ctr_drbg cmd module. + +module csrng_ctr_drbg_gen import csrng_pkg::*; #( + parameter logic [31:0] NApps = 4, + parameter logic [31:0] Cmd = 3, + parameter logic [31:0] StateId = 4, + parameter logic [31:0] BlkLen = 128, + parameter logic [31:0] KeyLen = 256, + parameter logic [31:0] SeedLen = 384, + parameter logic [31:0] CtrLen = 32 +) ( + input logic clk_i, + input logic rst_ni, + + // command interface + input logic ctr_drbg_gen_enable_i, + input logic ctr_drbg_gen_req_i, + output logic ctr_drbg_gen_rdy_o, // ready to process the req above + input logic [Cmd-1:0] ctr_drbg_gen_ccmd_i, // current command + input logic [StateId-1:0] ctr_drbg_gen_inst_id_i, // instantance id + input logic ctr_drbg_gen_glast_i, // gen cmd last beat + input logic ctr_drbg_gen_fips_i, // fips + input logic [SeedLen-1:0] ctr_drbg_gen_adata_i, // additional data + input logic [KeyLen-1:0] ctr_drbg_gen_key_i, + input logic [BlkLen-1:0] ctr_drbg_gen_v_i, + input logic [CtrLen-1:0] ctr_drbg_gen_rc_i, + + output logic ctr_drbg_gen_ack_o, // final ack when update process has been completed + output csrng_cmd_sts_e ctr_drbg_gen_sts_o, // final ack status + input logic ctr_drbg_gen_rdy_i, // ready to process the ack above + output logic [Cmd-1:0] ctr_drbg_gen_ccmd_o, + output logic [StateId-1:0] ctr_drbg_gen_inst_id_o, + output logic [KeyLen-1:0] ctr_drbg_gen_key_o, + output logic [BlkLen-1:0] ctr_drbg_gen_v_o, + output logic [CtrLen-1:0] ctr_drbg_gen_rc_o, + output logic [BlkLen-1:0] ctr_drbg_gen_bits_o, + output logic ctr_drbg_gen_fips_o, + + // es_req/ack + input logic ctr_drbg_gen_es_req_i, + output logic ctr_drbg_gen_es_ack_o, + + // update interface + output logic gen_upd_req_o, + input logic upd_gen_rdy_i, + output logic [Cmd-1:0] gen_upd_ccmd_o, + output logic [StateId-1:0] gen_upd_inst_id_o, + output logic [SeedLen-1:0] gen_upd_pdata_o, + output logic [KeyLen-1:0] gen_upd_key_o, + output logic [BlkLen-1:0] gen_upd_v_o, + + input logic upd_gen_ack_i, + output logic gen_upd_rdy_o, + input logic [Cmd-1:0] upd_gen_ccmd_i, + input logic [StateId-1:0] upd_gen_inst_id_i, + input logic [KeyLen-1:0] upd_gen_key_i, + input logic [BlkLen-1:0] upd_gen_v_i, + // block encrypt interface + output logic block_encrypt_req_o, + input logic block_encrypt_rdy_i, + output logic [Cmd-1:0] block_encrypt_ccmd_o, + output logic [StateId-1:0] block_encrypt_inst_id_o, + output logic [KeyLen-1:0] block_encrypt_key_o, + output logic [BlkLen-1:0] block_encrypt_v_o, + input logic block_encrypt_ack_i, + output logic block_encrypt_rdy_o, + input logic [Cmd-1:0] block_encrypt_ccmd_i, + input logic [StateId-1:0] block_encrypt_inst_id_i, + input logic [BlkLen-1:0] block_encrypt_v_i, + // misc + output logic ctr_drbg_gen_v_ctr_err_o, + output logic [2:0] ctr_drbg_gen_sfifo_gbencack_err_o, + output logic [2:0] ctr_drbg_gen_sfifo_grcstage_err_o, + output logic [2:0] ctr_drbg_gen_sfifo_ggenreq_err_o, + output logic [2:0] ctr_drbg_gen_sfifo_gadstage_err_o, + output logic [2:0] ctr_drbg_gen_sfifo_ggenbits_err_o, + output logic ctr_drbg_gen_sm_err_o +); + + localparam logic[31:0] GenreqFifoDepth = 1; + localparam logic[31:0] GenreqFifoWidth = KeyLen+BlkLen+CtrLen+1+SeedLen+1+StateId+Cmd; + localparam logic[31:0] BlkEncAckFifoDepth = 1; + localparam logic[31:0] BlkEncAckFifoWidth = BlkLen+StateId+Cmd; + localparam logic[31:0] AdstageFifoDepth = 1; + localparam logic[31:0] AdstageFifoWidth = KeyLen+BlkLen+CtrLen+1+1; + localparam logic[31:0] RCStageFifoDepth = 1; + localparam logic[31:0] RCStageFifoWidth = KeyLen+BlkLen+BlkLen+CtrLen+1+1+StateId+Cmd; + localparam logic[31:0] GenbitsFifoDepth = 1; + localparam logic[31:0] GenbitsFifoWidth = 1+BlkLen+KeyLen+BlkLen+CtrLen+StateId+Cmd; + + // signals + logic [Cmd-1:0] genreq_ccmd; + logic [StateId-1:0] genreq_id; + logic genreq_glast; + logic [SeedLen-1:0] genreq_adata; + logic genreq_fips; + logic [KeyLen-1:0] genreq_key; + logic [BlkLen-1:0] genreq_v; + logic [CtrLen-1:0] genreq_rc; + + logic [KeyLen-1:0] adstage_key; + logic [BlkLen-1:0] adstage_v; + logic [CtrLen-1:0] adstage_rc; + logic adstage_fips; + logic adstage_glast; + logic [SeedLen-1:0] adstage_adata; + + logic [KeyLen-1:0] rcstage_key; + logic [BlkLen-1:0] rcstage_v; + logic [BlkLen-1:0] rcstage_bits; + logic [CtrLen-1:0] rcstage_rc; + logic rcstage_glast; + logic rcstage_fips; + logic [CtrLen-1:0] rcstage_rc_plus1; + logic [Cmd-1:0] rcstage_ccmd; + logic [StateId-1:0] rcstage_inst_id; + + logic [Cmd-1:0] genreq_ccmd_modified; + logic [Cmd-1:0] bencack_ccmd_modified; + + // cmdreq fifo + // logic [$clog2(CmdreqFifoDepth):0] sfifo_cmdreq_depth; + logic [GenreqFifoWidth-1:0] sfifo_genreq_rdata; + logic sfifo_genreq_push; + logic [GenreqFifoWidth-1:0] sfifo_genreq_wdata; + logic sfifo_genreq_pop; + logic sfifo_genreq_full; + logic sfifo_genreq_not_empty; + + // adstage fifo + logic [AdstageFifoWidth-1:0] sfifo_adstage_rdata; + logic sfifo_adstage_push; + logic [AdstageFifoWidth-1:0] sfifo_adstage_wdata; + logic sfifo_adstage_pop; + logic sfifo_adstage_full; + logic sfifo_adstage_not_empty; + // blk_encrypt_ack fifo + logic [BlkEncAckFifoWidth-1:0] sfifo_bencack_rdata; + logic sfifo_bencack_push; + logic [BlkEncAckFifoWidth-1:0] sfifo_bencack_wdata; + logic sfifo_bencack_pop; + logic sfifo_bencack_full; + logic sfifo_bencack_not_empty; + // breakout + logic [Cmd-1:0] sfifo_bencack_ccmd; + logic [StateId-1:0] sfifo_bencack_inst_id; + logic [BlkLen-1:0] sfifo_bencack_bits; + + // rcstage fifo + logic [RCStageFifoWidth-1:0] sfifo_rcstage_rdata; + logic sfifo_rcstage_push; + logic [RCStageFifoWidth-1:0] sfifo_rcstage_wdata; + logic sfifo_rcstage_pop; + logic sfifo_rcstage_full; + logic sfifo_rcstage_not_empty; + + // genbits fifo + logic [GenbitsFifoWidth-1:0] sfifo_genbits_rdata; + logic sfifo_genbits_push; + logic [GenbitsFifoWidth-1:0] sfifo_genbits_wdata; + logic sfifo_genbits_pop; + logic sfifo_genbits_full; + logic sfifo_genbits_not_empty; + + logic [CtrLen-1:0] v_inc; + logic [BlkLen-1:0] v_first; + logic [BlkLen-1:0] v_sized; + logic v_ctr_load; + logic v_ctr_inc; + logic interate_ctr_done; + logic interate_ctr_inc; + logic [NApps-1:0] capt_adata; + logic [SeedLen-1:0] update_adata[NApps]; + logic [CtrLen-1:0] v_ctr; + + // status error signals + logic ctr_drbg_gen_sts_err; + + // flops + logic [1:0] interate_ctr_q, interate_ctr_d; + logic [SeedLen-1:0] update_adata_q[NApps], update_adata_d[NApps]; + logic [NApps-1:0] update_adata_vld_q, update_adata_vld_d; + +// Encoding generated with: +// $ ./util/design/sparse-fsm-encode.py -d 3 -m 4 -n 5 \ +// -s 2651202796 --language=sv +// +// Hamming distance histogram: +// +// 0: -- +// 1: -- +// 2: -- +// 3: |||||||||||||||||||| (66.67%) +// 4: |||||||||| (33.33%) +// 5: -- +// +// Minimum Hamming distance: 3 +// Maximum Hamming distance: 4 +// Minimum Hamming weight: 2 +// Maximum Hamming weight: 3 +// + + localparam logic[31:0] StateWidth = 5; + typedef enum logic [StateWidth-1:0] { + ReqIdle = 5'b01101, + ReqSend = 5'b00011, + ESHalt = 5'b11000, + ReqError = 5'b10110 +} state_e; + + state_e state_d, state_q; + + // SEC_CM: UPDATE.FSM.SPARSE + `CALIPTRA_PRIM_FLOP_SPARSE_FSM(u_state_regs, state_d, state_q, state_e, ReqIdle) + + always_ff @(posedge clk_i or negedge rst_ni) + if (!rst_ni) begin + interate_ctr_q <= '0; + update_adata_q <= '{default:0}; + update_adata_vld_q <= '{default:0}; + end else begin + interate_ctr_q <= interate_ctr_d; + update_adata_q <= update_adata_d; + update_adata_vld_q <= update_adata_vld_d; + end + + + + //-------------------------------------------- + // input request fifo for staging gen request + //-------------------------------------------- + + caliptra_prim_fifo_sync #( + .Width(GenreqFifoWidth), + .Pass(0), + .Depth(GenreqFifoDepth), + .OutputZeroIfEmpty(1'b0) + ) u_caliptra_prim_fifo_sync_genreq ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .clr_i (!ctr_drbg_gen_enable_i), + .wvalid_i (sfifo_genreq_push), + .wready_o (), + .wdata_i (sfifo_genreq_wdata), + .rvalid_o (sfifo_genreq_not_empty), + .rready_i (sfifo_genreq_pop), + .rdata_o (sfifo_genreq_rdata), + .full_o (sfifo_genreq_full), + .depth_o (), + .err_o () + ); + + assign genreq_ccmd_modified = (ctr_drbg_gen_ccmd_i == GEN) ? GENB : INV; + + assign sfifo_genreq_wdata = {ctr_drbg_gen_key_i,ctr_drbg_gen_v_i,ctr_drbg_gen_rc_i, + ctr_drbg_gen_fips_i,ctr_drbg_gen_adata_i,ctr_drbg_gen_glast_i, + ctr_drbg_gen_inst_id_i,genreq_ccmd_modified}; + + assign sfifo_genreq_push = ctr_drbg_gen_enable_i && ctr_drbg_gen_req_i; + + assign {genreq_key,genreq_v,genreq_rc, + genreq_fips,genreq_adata,genreq_glast, + genreq_id,genreq_ccmd} = sfifo_genreq_rdata; + + assign ctr_drbg_gen_rdy_o = !sfifo_genreq_full; + + assign ctr_drbg_gen_sfifo_ggenreq_err_o = + {(sfifo_genreq_push && sfifo_genreq_full), + (sfifo_genreq_pop && !sfifo_genreq_not_empty), + (sfifo_genreq_full && !sfifo_genreq_not_empty)}; + + + + //-------------------------------------------- + // prepare value for block_encrypt step + //-------------------------------------------- + + if (CtrLen < BlkLen) begin : gen_ctrlen_sm + // for ctr_len < blocklen + assign v_inc = genreq_v[CtrLen-1:0] + 1; + assign v_first = {genreq_v[BlkLen-1:CtrLen],v_inc}; + end else begin : g_ctrlen_lg + assign v_first = genreq_v + 1; + end + + // SEC_CM: DRBG_GEN.CTR.REDUN + caliptra_prim_count #( + .Width(CtrLen) + ) u_caliptra_prim_count_ctr_drbg ( + .clk_i, + .rst_ni, + .clr_i(!ctr_drbg_gen_enable_i), + .set_i(v_ctr_load), + .set_cnt_i(v_first[CtrLen-1:0]), + .incr_en_i(v_ctr_inc), // count up + .decr_en_i(1'b0), + .step_i(CtrLen'(1)), + .commit_i(1'b1), + .cnt_o(v_ctr), + .cnt_after_commit_o(), + .err_o(ctr_drbg_gen_v_ctr_err_o) + ); + + assign v_sized = {v_first[BlkLen-1:CtrLen],v_ctr}; + + // interation counter + assign interate_ctr_d = + (!ctr_drbg_gen_enable_i) ? '0 : + interate_ctr_done ? '0 : + interate_ctr_inc ? (interate_ctr_q + 1) : + interate_ctr_q; + + // Supporting only 128b requests + assign interate_ctr_done = (interate_ctr_q >= 2'(BlkLen/BlkLen)); + + //-------------------------------------------- + // state machine to send values to block_encrypt + //-------------------------------------------- + + assign block_encrypt_ccmd_o = genreq_ccmd; + assign block_encrypt_inst_id_o = genreq_id; + assign block_encrypt_key_o = genreq_key; + assign block_encrypt_v_o = v_sized; + + always_comb begin + state_d = state_q; + v_ctr_load = 1'b0; + v_ctr_inc = 1'b0; + interate_ctr_inc = 1'b0; + sfifo_adstage_push = 1'b0; + block_encrypt_req_o = 1'b0; + sfifo_genreq_pop = 1'b0; + ctr_drbg_gen_sm_err_o = 1'b0; + ctr_drbg_gen_es_ack_o = 1'b0; + unique case (state_q) + // ReqIdle: increment v this cycle, push in next + ReqIdle: begin + // Prioritize halt requests from entropy_src over disable, as CSRNG would otherwise starve + // those requests while it is idle. + if (ctr_drbg_gen_es_req_i) begin + state_d = ESHalt; + end else if (!ctr_drbg_gen_enable_i) begin + state_d = ReqIdle; + end else if (sfifo_genreq_not_empty && !sfifo_adstage_full) begin + v_ctr_load = 1'b1; + state_d = ReqSend; + end + end + ReqSend: begin + if (!ctr_drbg_gen_enable_i) begin + state_d = ReqIdle; + end else if (!interate_ctr_done) begin + block_encrypt_req_o = 1'b1; + sfifo_adstage_push = 1'b1; + if (block_encrypt_rdy_i) begin + v_ctr_inc = 1'b1; + interate_ctr_inc = 1'b1; + end + end else begin + sfifo_genreq_pop = 1'b1; + state_d = ReqIdle; + end + end + ESHalt: begin + ctr_drbg_gen_es_ack_o = 1'b1; + if (!ctr_drbg_gen_es_req_i) begin + state_d = ReqIdle; + end + end + ReqError: begin + ctr_drbg_gen_sm_err_o = 1'b1; + end + default: begin + state_d = ReqError; + ctr_drbg_gen_sm_err_o = 1'b1; + end + endcase + end + + + //-------------------------------------------- + // fifo to stage key, v, rc, and adata, waiting for update block to ack + //-------------------------------------------- + + caliptra_prim_fifo_sync #( + .Width(AdstageFifoWidth), + .Pass(0), + .Depth(AdstageFifoDepth), + .OutputZeroIfEmpty(1'b0) + ) u_caliptra_prim_fifo_sync_adstage ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .clr_i (!ctr_drbg_gen_enable_i), + .wvalid_i (sfifo_adstage_push), + .wready_o (), + .wdata_i (sfifo_adstage_wdata), + .rvalid_o (sfifo_adstage_not_empty), + .rready_i (sfifo_adstage_pop), + .rdata_o (sfifo_adstage_rdata), + .full_o (sfifo_adstage_full), + .depth_o (), + .err_o () + ); + + assign sfifo_adstage_wdata = {genreq_key,v_sized,genreq_rc,genreq_fips,genreq_glast}; + assign sfifo_adstage_pop = sfifo_adstage_not_empty && sfifo_bencack_pop; + assign {adstage_key,adstage_v,adstage_rc,adstage_fips,adstage_glast} = sfifo_adstage_rdata; + + assign ctr_drbg_gen_sfifo_gadstage_err_o = + {(sfifo_adstage_push && sfifo_adstage_full), + (sfifo_adstage_pop && !sfifo_adstage_not_empty), + (sfifo_adstage_full && !sfifo_adstage_not_empty)}; + + + // array to hold each channel's adata + for (genvar i = 0; i < NApps; i = i+1) begin : gen_adata + assign capt_adata[i] = (sfifo_adstage_push && (genreq_id == i)); + + assign update_adata_vld_d[i] = ~ctr_drbg_gen_enable_i ? 1'b0 : + capt_adata[i] && !update_adata_vld_q[i] ? 1'b1 : + (gen_upd_req_o && upd_gen_rdy_i && (sfifo_bencack_inst_id == i)) ? 1'b0 : + update_adata_vld_q[i]; + + assign update_adata_d[i] = ~ctr_drbg_gen_enable_i ? '0 : + (capt_adata[i] && !update_adata_vld_q[i]) ? genreq_adata : + update_adata_q[i]; + assign update_adata[i] = update_adata_q[i] & {SeedLen{update_adata_vld_q[i] && + (genreq_id == i)}}; + end + + always_comb begin + adstage_adata = '0; + for (int i = 0; i < NApps; i = i+1) begin + // since only one bus is active at a time based on the instant id, + // an "or" of all the buses can be done below + adstage_adata |= update_adata[i]; + end + end + + + //-------------------------------------------- + // block_encrypt response fifo from block encrypt + //-------------------------------------------- + + caliptra_prim_fifo_sync #( + .Width(BlkEncAckFifoWidth), + .Pass(0), + .Depth(BlkEncAckFifoDepth), + .OutputZeroIfEmpty(1'b0) + ) u_caliptra_prim_fifo_sync_bencack ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .clr_i (!ctr_drbg_gen_enable_i), + .wvalid_i (sfifo_bencack_push), + .wready_o (), + .wdata_i (sfifo_bencack_wdata), + .rvalid_o (sfifo_bencack_not_empty), + .rready_i (sfifo_bencack_pop), + .rdata_o (sfifo_bencack_rdata), + .full_o (sfifo_bencack_full), + .depth_o (), + .err_o () + ); + + assign bencack_ccmd_modified = (block_encrypt_ccmd_i == GENB) ? GENU : INV; + + assign sfifo_bencack_push = !sfifo_bencack_full && block_encrypt_ack_i; + assign sfifo_bencack_wdata = {block_encrypt_v_i,block_encrypt_inst_id_i,bencack_ccmd_modified}; + assign block_encrypt_rdy_o = !sfifo_bencack_full; + + assign sfifo_bencack_pop = !sfifo_rcstage_full && sfifo_bencack_not_empty && + (upd_gen_rdy_i || !adstage_glast); + + assign {sfifo_bencack_bits,sfifo_bencack_inst_id,sfifo_bencack_ccmd} = sfifo_bencack_rdata; + + assign ctr_drbg_gen_sfifo_gbencack_err_o = + {(sfifo_bencack_push && sfifo_bencack_full), + (sfifo_bencack_pop && !sfifo_bencack_not_empty), + (sfifo_bencack_full && !sfifo_bencack_not_empty)}; + + + //-------------------------------------------- + // prepare values for update step + //-------------------------------------------- + + // send to the update block + assign gen_upd_req_o = sfifo_bencack_not_empty && adstage_glast; + assign gen_upd_ccmd_o = sfifo_bencack_ccmd; + assign gen_upd_inst_id_o = sfifo_bencack_inst_id; + assign gen_upd_pdata_o = adstage_adata; + assign gen_upd_key_o = adstage_key; + assign gen_upd_v_o = adstage_v; + + + + //-------------------------------------------- + // fifo to stage rc, waiting for update block to ack + //-------------------------------------------- + + caliptra_prim_fifo_sync #( + .Width(RCStageFifoWidth), + .Pass(0), + .Depth(RCStageFifoDepth), + .OutputZeroIfEmpty(1'b0) + ) u_caliptra_prim_fifo_sync_rcstage ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .clr_i (!ctr_drbg_gen_enable_i), + .wvalid_i (sfifo_rcstage_push), + .wready_o (), + .wdata_i (sfifo_rcstage_wdata), + .rvalid_o (sfifo_rcstage_not_empty), + .rready_i (sfifo_rcstage_pop), + .rdata_o (sfifo_rcstage_rdata), + .full_o (sfifo_rcstage_full), + .depth_o (), + .err_o () + ); + + assign sfifo_rcstage_push = sfifo_adstage_pop; + assign sfifo_rcstage_wdata = {adstage_key,adstage_v,sfifo_bencack_bits, + adstage_rc,adstage_fips,adstage_glast, + sfifo_bencack_inst_id,sfifo_bencack_ccmd}; + + assign sfifo_rcstage_pop = sfifo_rcstage_not_empty && (upd_gen_ack_i || !rcstage_glast); + + assign {rcstage_key,rcstage_v,rcstage_bits,rcstage_rc,rcstage_fips,rcstage_glast, + rcstage_inst_id,rcstage_ccmd} = sfifo_rcstage_rdata; + + + assign ctr_drbg_gen_sfifo_grcstage_err_o = + {(sfifo_rcstage_push && sfifo_rcstage_full), + (sfifo_rcstage_pop && !sfifo_rcstage_not_empty), + (sfifo_rcstage_full && !sfifo_rcstage_not_empty)}; + + assign gen_upd_rdy_o = sfifo_rcstage_not_empty && !sfifo_genbits_full; + + + //-------------------------------------------- + // final cmd block processing + //-------------------------------------------- + + caliptra_prim_fifo_sync #( + .Width(GenbitsFifoWidth), + .Pass(0), + .Depth(GenbitsFifoDepth), + .OutputZeroIfEmpty(1'b0) + ) u_caliptra_prim_fifo_sync_genbits ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .clr_i (!ctr_drbg_gen_enable_i), + .wvalid_i (sfifo_genbits_push), + .wready_o (), + .wdata_i (sfifo_genbits_wdata), + .rvalid_o (sfifo_genbits_not_empty), + .rready_i (sfifo_genbits_pop), + .rdata_o (sfifo_genbits_rdata), + .full_o (sfifo_genbits_full), + .depth_o (), + .err_o () + ); + + assign sfifo_genbits_push = sfifo_rcstage_pop; + + assign rcstage_rc_plus1 = (rcstage_rc+1); + + assign sfifo_genbits_wdata = rcstage_glast ? + {rcstage_fips,rcstage_bits,upd_gen_key_i,upd_gen_v_i, + rcstage_rc_plus1,upd_gen_inst_id_i,upd_gen_ccmd_i} : + {rcstage_fips,rcstage_bits,rcstage_key,rcstage_v, + rcstage_rc,rcstage_inst_id,rcstage_ccmd}; + + assign sfifo_genbits_pop = ctr_drbg_gen_rdy_i && sfifo_genbits_not_empty; + assign {ctr_drbg_gen_fips_o,ctr_drbg_gen_bits_o, + ctr_drbg_gen_key_o,ctr_drbg_gen_v_o,ctr_drbg_gen_rc_o, + ctr_drbg_gen_inst_id_o,ctr_drbg_gen_ccmd_o} = sfifo_genbits_rdata; + + assign ctr_drbg_gen_sfifo_ggenbits_err_o = + {(sfifo_genbits_push && sfifo_genbits_full), + (sfifo_genbits_pop && !sfifo_genbits_not_empty), + (sfifo_genbits_full && !sfifo_genbits_not_empty)}; + + // block ack + assign ctr_drbg_gen_ack_o = sfifo_genbits_pop; + + // Return a status error when the genbits FIFO is popped while ctr_drbg_gen_ccmd_o is not + // equal to GEN. + assign ctr_drbg_gen_sts_err = sfifo_genbits_pop && (ctr_drbg_gen_ccmd_o != GENU); + + assign ctr_drbg_gen_sts_o = ctr_drbg_gen_sts_err ? CMD_STS_INVALID_GEN_CMD : CMD_STS_SUCCESS; + + // Make sure that the state machine has a stable error state. This means that after the error + // state is entered it will not exit it unless a reset signal is received. + `CALIPTRA_ASSERT(CsrngDrbgGenErrorStStable_A, state_q == ReqError |=> $stable(state_q)) + // If in error state, the error output must be high. + `CALIPTRA_ASSERT(CsrngDrbgGenErrorOutput_A, + !(state_q inside {ReqIdle, ReqSend, ESHalt}) |-> ctr_drbg_gen_sm_err_o) +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/csrng_ctr_drbg_upd.sv b/designs/Caliptra/src/caliptra-rtl/csrng_ctr_drbg_upd.sv new file mode 100644 index 0000000..6dbe2db --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/csrng_ctr_drbg_upd.sv @@ -0,0 +1,628 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Description: csrng ctr_drbg_update module +// +// implementation using security_strength = 256 + +module csrng_ctr_drbg_upd #( + parameter logic [31:0] Cmd = 3, + parameter logic [31:0] StateId = 4, + parameter logic [31:0] BlkLen = 128, + parameter logic [31:0] KeyLen = 256, + parameter logic [31:0] SeedLen = 384, + parameter logic [31:0] CtrLen = 32 +) ( + input logic clk_i, + input logic rst_ni, + + // update interface + input logic ctr_drbg_upd_enable_i, + input logic ctr_drbg_upd_req_i, + output logic ctr_drbg_upd_rdy_o, // ready to process the req above + input logic [Cmd-1:0] ctr_drbg_upd_ccmd_i, + input logic [StateId-1:0] ctr_drbg_upd_inst_id_i, // instantance id + input logic [SeedLen-1:0] ctr_drbg_upd_pdata_i, // provided_data + input logic [KeyLen-1:0] ctr_drbg_upd_key_i, + input logic [BlkLen-1:0] ctr_drbg_upd_v_i, + output logic [Cmd-1:0] ctr_drbg_upd_ccmd_o, + output logic [StateId-1:0] ctr_drbg_upd_inst_id_o, + output logic [KeyLen-1:0] ctr_drbg_upd_key_o, + output logic [BlkLen-1:0] ctr_drbg_upd_v_o, + output logic ctr_drbg_upd_ack_o, // final ack when update process has been completed + input logic ctr_drbg_upd_rdy_i, // readu to process the ack above + + // es_req/ack + input logic ctr_drbg_upd_es_req_i, + output logic ctr_drbg_upd_es_ack_o, + + // block encrypt interface + output logic block_encrypt_req_o, + input logic block_encrypt_rdy_i, + output logic [Cmd-1:0] block_encrypt_ccmd_o, + output logic [StateId-1:0] block_encrypt_inst_id_o, + output logic [KeyLen-1:0] block_encrypt_key_o, + output logic [BlkLen-1:0] block_encrypt_v_o, + input logic block_encrypt_ack_i, + output logic block_encrypt_rdy_o, + input logic [Cmd-1:0] block_encrypt_ccmd_i, + input logic [StateId-1:0] block_encrypt_inst_id_i, + input logic [BlkLen-1:0] block_encrypt_v_i, + output logic ctr_drbg_upd_v_ctr_err_o, + output logic [2:0] ctr_drbg_upd_sfifo_updreq_err_o, + output logic [2:0] ctr_drbg_upd_sfifo_bencreq_err_o, + output logic [2:0] ctr_drbg_upd_sfifo_bencack_err_o, + output logic [2:0] ctr_drbg_upd_sfifo_pdata_err_o, + output logic [2:0] ctr_drbg_upd_sfifo_final_err_o, + output logic ctr_drbg_updbe_sm_err_o, + output logic ctr_drbg_updob_sm_err_o +); + + localparam logic[31:0] UpdReqFifoDepth = 1; + localparam logic[31:0] UpdReqFifoWidth = KeyLen+BlkLen+SeedLen+StateId+Cmd; + localparam logic[31:0] BlkEncReqFifoDepth = 1; + localparam logic[31:0] BlkEncReqFifoWidth = KeyLen+BlkLen+StateId+Cmd; + localparam logic[31:0] BlkEncAckFifoDepth = 1; + localparam logic[31:0] BlkEncAckFifoWidth = BlkLen+StateId+Cmd; + localparam logic[31:0] PDataFifoDepth = 1; + localparam logic[31:0] PDataFifoWidth = SeedLen; + localparam logic[31:0] FinalFifoDepth = 1; + localparam logic[31:0] FinalFifoWidth = KeyLen+BlkLen+StateId+Cmd; + + // signals + logic [SeedLen-1:0] updated_key_and_v; + logic [CtrLen-1:0] v_inc; + logic [BlkLen-1:0] v_first; + logic [BlkLen-1:0] v_sized; + + // upd_req fifo + logic [UpdReqFifoWidth-1:0] sfifo_updreq_rdata; + logic sfifo_updreq_push; + logic [UpdReqFifoWidth-1:0] sfifo_updreq_wdata; + logic sfifo_updreq_pop; + logic sfifo_updreq_full; + logic sfifo_updreq_not_empty; + // breakout + logic [Cmd-1:0] sfifo_updreq_ccmd; + logic [StateId-1:0] sfifo_updreq_inst_id; + logic [SeedLen-1:0] sfifo_updreq_pdata; + logic [KeyLen-1:0] sfifo_updreq_key; + logic [BlkLen-1:0] sfifo_updreq_v; + + // blk_encrypt_req fifo + logic [BlkEncReqFifoWidth-1:0] sfifo_bencreq_rdata; + logic sfifo_bencreq_push; + logic [BlkEncReqFifoWidth-1:0] sfifo_bencreq_wdata; + logic sfifo_bencreq_pop; + logic sfifo_bencreq_full; + logic sfifo_bencreq_not_empty; + // breakout + logic [Cmd-1:0] sfifo_bencreq_ccmd; + logic [StateId-1:0] sfifo_bencreq_inst_id; + logic [KeyLen-1:0] sfifo_bencreq_key; + logic [BlkLen-1:0] sfifo_bencreq_v; + + // blk_encrypt_ack fifo + logic [BlkEncAckFifoWidth-1:0] sfifo_bencack_rdata; + logic sfifo_bencack_push; + logic [BlkEncAckFifoWidth-1:0] sfifo_bencack_wdata; + logic sfifo_bencack_pop; + logic sfifo_bencack_full; + logic sfifo_bencack_not_empty; + // breakout + logic [Cmd-1:0] sfifo_bencack_ccmd; + logic [StateId-1:0] sfifo_bencack_inst_id; + logic [BlkLen-1:0] sfifo_bencack_v; + + // pdata_stage fifo + logic [PDataFifoWidth-1:0] sfifo_pdata_rdata; + logic sfifo_pdata_push; + logic [PDataFifoWidth-1:0] sfifo_pdata_wdata; + logic sfifo_pdata_pop; + logic sfifo_pdata_full; + logic sfifo_pdata_not_empty; + logic [SeedLen-1:0] sfifo_pdata_v; + + // key_v fifo + logic [FinalFifoWidth-1:0] sfifo_final_rdata; + logic sfifo_final_push; + logic [FinalFifoWidth-1:0] sfifo_final_wdata; + logic sfifo_final_pop; + logic sfifo_final_full; + logic sfifo_final_not_empty; + // breakout + logic [Cmd-1:0] sfifo_final_ccmd; + logic [StateId-1:0] sfifo_final_inst_id; + logic [KeyLen-1:0] sfifo_final_key; + logic [BlkLen-1:0] sfifo_final_v; + + logic v_ctr_load; + logic v_ctr_inc; + logic interate_ctr_done; + logic interate_ctr_inc; + logic concat_outblk_shift; + logic concat_ctr_done; + logic concat_ctr_inc; + logic [SeedLen+BlkLen-1:0] concat_outblk_shifted_value; + logic [CtrLen-1:0] v_ctr; + + // flops + logic [1:0] interate_ctr_q, interate_ctr_d; + logic [1:0] concat_ctr_q, concat_ctr_d; + logic [SeedLen-1:0] concat_outblk_q, concat_outblk_d; + logic [Cmd-1:0] concat_ccmd_q, concat_ccmd_d; + logic [StateId-1:0] concat_inst_id_q, concat_inst_id_d; + +// Encoding generated with: +// $ ./util/design/sparse-fsm-encode.py -d 3 -m 4 -n 5 \ +// -s 47328894 --language=sv +// +// Hamming distance histogram: +// +// 0: -- +// 1: -- +// 2: -- +// 3: |||||||||||||||||||| (66.67%) +// 4: |||||||||| (33.33%) +// 5: -- +// +// Minimum Hamming distance: 3 +// Maximum Hamming distance: 4 +// Minimum Hamming weight: 2 +// Maximum Hamming weight: 3 +// + + localparam logic[31:0] BlkEncStateWidth = 5; + typedef enum logic [BlkEncStateWidth-1:0] { + ReqIdle = 5'b11000, + ReqSend = 5'b10011, + ESHalt = 5'b01110, + BEError = 5'b00101 + } blk_enc_state_e; + + blk_enc_state_e blk_enc_state_d, blk_enc_state_q; + + // SEC_CM: BLK_ENC.FSM.SPARSE + `CALIPTRA_PRIM_FLOP_SPARSE_FSM(u_blk_enc_state_regs, blk_enc_state_d, + blk_enc_state_q, blk_enc_state_e, ReqIdle) + +// Encoding generated with: +// $ ./util/design/sparse-fsm-encode.py -d 3 -m 4 -n 6 \ +// -s 400877681 --language=sv +// +// Hamming distance histogram: +// +// 0: -- +// 1: -- +// 2: -- +// 3: |||||||||||||||||||| (66.67%) +// 4: ||||| (16.67%) +// 5: -- +// 6: ||||| (16.67%) +// +// Minimum Hamming distance: 3 +// Maximum Hamming distance: 6 +// Minimum Hamming weight: 2 +// Maximum Hamming weight: 4 +// + + localparam logic[31:0] OutBlkStateWidth = 6; + typedef enum logic [OutBlkStateWidth-1:0] { + AckIdle = 6'b110110, + Load = 6'b110001, + Shift = 6'b001001, + OBError = 6'b011100 + } outblk_state_e; + + outblk_state_e outblk_state_d, outblk_state_q; + + // SEC_CM: OUTBLK.FSM.SPARSE + `CALIPTRA_PRIM_FLOP_SPARSE_FSM(u_outblk_state_regs, outblk_state_d, + outblk_state_q, outblk_state_e, AckIdle) + + always_ff @(posedge clk_i or negedge rst_ni) + if (!rst_ni) begin + interate_ctr_q <= '0; + concat_ctr_q <= '0; + concat_outblk_q <= '0; + concat_ccmd_q <= '0; + concat_inst_id_q <= '0; + end else begin + interate_ctr_q <= interate_ctr_d; + concat_ctr_q <= concat_ctr_d; + concat_outblk_q <= concat_outblk_d; + concat_ccmd_q <= concat_ccmd_d; + concat_inst_id_q <= concat_inst_id_d; + end // else: !if(!rst_ni) + + + //-------------------------------------------- + // input request fifo for staging update requests + //-------------------------------------------- + + caliptra_prim_fifo_sync #( + .Width(UpdReqFifoWidth), + .Pass(0), + .Depth(UpdReqFifoDepth), + .OutputZeroIfEmpty(1'b0) + ) u_caliptra_prim_fifo_sync_updreq ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .clr_i (!ctr_drbg_upd_enable_i), + .wvalid_i (sfifo_updreq_push), + .wready_o (), + .wdata_i (sfifo_updreq_wdata), + .rvalid_o (sfifo_updreq_not_empty), + .rready_i (sfifo_updreq_pop), + .rdata_o (sfifo_updreq_rdata), + .full_o (sfifo_updreq_full), + .depth_o (), + .err_o () + ); + + assign sfifo_updreq_push = !sfifo_updreq_full && ctr_drbg_upd_req_i; + assign sfifo_updreq_wdata = {ctr_drbg_upd_key_i,ctr_drbg_upd_v_i,ctr_drbg_upd_pdata_i, + ctr_drbg_upd_inst_id_i,ctr_drbg_upd_ccmd_i}; + assign ctr_drbg_upd_rdy_o = !sfifo_updreq_full; + + assign {sfifo_updreq_key,sfifo_updreq_v,sfifo_updreq_pdata, + sfifo_updreq_inst_id,sfifo_updreq_ccmd} = sfifo_updreq_rdata; + + assign ctr_drbg_upd_sfifo_updreq_err_o = + {(sfifo_updreq_push && sfifo_updreq_full), + (sfifo_updreq_pop && !sfifo_updreq_not_empty), + (sfifo_updreq_full && !sfifo_updreq_not_empty)}; + + //-------------------------------------------- + // prepare value for block_encrypt step + //-------------------------------------------- + + if (CtrLen < BlkLen) begin : g_ctrlen_sm + // for ctr_len < blocklen + assign v_inc = sfifo_updreq_v[CtrLen-1:0] + 1; + assign v_first = {sfifo_updreq_v[BlkLen-1:CtrLen],v_inc}; + end else begin : g_ctrlen_lg + assign v_first = sfifo_updreq_v + 1; + end + + // SEC_CM: DRBG_UPD.CTR.REDUN + caliptra_prim_count #( + .Width(CtrLen) + ) u_caliptra_prim_count_ctr_drbg ( + .clk_i, + .rst_ni, + .clr_i(!ctr_drbg_upd_enable_i), + .set_i(v_ctr_load), + .set_cnt_i(v_first[CtrLen-1:0]), + .incr_en_i(v_ctr_inc), // count up + .decr_en_i(1'b0), + .step_i(CtrLen'(1)), + .commit_i(1'b1), + .cnt_o(v_ctr), + .cnt_after_commit_o(), + .err_o(ctr_drbg_upd_v_ctr_err_o) + ); + + assign v_sized = {v_first[BlkLen-1:CtrLen],v_ctr}; + + // interation counter + assign interate_ctr_d = + (!ctr_drbg_upd_enable_i) ? '0 : + interate_ctr_done ? '0 : + interate_ctr_inc ? (interate_ctr_q + 1) : + interate_ctr_q; + + assign interate_ctr_done = (32'(interate_ctr_q) >= SeedLen/BlkLen); + + //-------------------------------------------- + // state machine to send values to block_encrypt + //-------------------------------------------- + + always_comb begin + blk_enc_state_d = blk_enc_state_q; + v_ctr_load = 1'b0; + v_ctr_inc = 1'b0; + interate_ctr_inc = 1'b0; + sfifo_pdata_push = 1'b0; + sfifo_bencreq_push = 1'b0; + sfifo_updreq_pop = 1'b0; + ctr_drbg_updbe_sm_err_o = 1'b0; + ctr_drbg_upd_es_ack_o = 1'b0; + unique case (blk_enc_state_q) + // ReqIdle: increment v this cycle, push in next + ReqIdle: begin + // Prioritize halt requests from entropy_src over disable, as CSRNG would otherwise starve + // those requests while it is idle. + if (ctr_drbg_upd_es_req_i) begin + blk_enc_state_d = ESHalt; + end else if (!ctr_drbg_upd_enable_i) begin + blk_enc_state_d = ReqIdle; + end else if (sfifo_updreq_not_empty && !sfifo_bencreq_full && !sfifo_pdata_full) begin + v_ctr_load = 1'b1; + sfifo_pdata_push = 1'b1; + blk_enc_state_d = ReqSend; + end + end + ReqSend: begin + if (!ctr_drbg_upd_enable_i) begin + blk_enc_state_d = ReqIdle; + end else if (!interate_ctr_done) begin + if (!sfifo_bencreq_full) begin + v_ctr_inc = 1'b1; + interate_ctr_inc = 1'b1; + sfifo_bencreq_push = 1'b1; + end + end else begin + sfifo_updreq_pop = 1'b1; + blk_enc_state_d = ReqIdle; + end + end + ESHalt: begin + ctr_drbg_upd_es_ack_o = 1'b1; + if (!ctr_drbg_upd_es_req_i) begin + blk_enc_state_d = ReqIdle; + end + end + BEError: begin + ctr_drbg_updbe_sm_err_o = 1'b1; + end + default: begin + blk_enc_state_d = BEError; + ctr_drbg_updbe_sm_err_o = 1'b1; + end + endcase // case (blk_enc_state_q) + end + + //-------------------------------------------- + // block_encrypt request fifo for staging aes requests + //-------------------------------------------- + + caliptra_prim_fifo_sync #( + .Width(BlkEncReqFifoWidth), + .Pass(0), + .Depth(BlkEncReqFifoDepth), + .OutputZeroIfEmpty(1'b0) + ) u_caliptra_prim_fifo_sync_bencreq ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .clr_i (!ctr_drbg_upd_enable_i), + .wvalid_i (sfifo_bencreq_push), + .wready_o (), + .wdata_i (sfifo_bencreq_wdata), + .rvalid_o (sfifo_bencreq_not_empty), + .rready_i (sfifo_bencreq_pop), + .rdata_o (sfifo_bencreq_rdata), + .full_o (sfifo_bencreq_full), + .depth_o (), + .err_o () + ); + + assign sfifo_bencreq_pop = block_encrypt_req_o && block_encrypt_rdy_i; + assign block_encrypt_req_o = sfifo_bencreq_not_empty; + + assign sfifo_bencreq_wdata = {sfifo_updreq_key,v_sized,sfifo_updreq_inst_id,sfifo_updreq_ccmd}; + + assign {sfifo_bencreq_key,sfifo_bencreq_v,sfifo_bencreq_inst_id, + sfifo_bencreq_ccmd} = sfifo_bencreq_rdata; + + // set outputs + assign block_encrypt_key_o = sfifo_bencreq_key; + assign block_encrypt_v_o = sfifo_bencreq_v; + assign block_encrypt_inst_id_o = sfifo_bencreq_inst_id; + assign block_encrypt_ccmd_o = sfifo_bencreq_ccmd; + + assign ctr_drbg_upd_sfifo_bencreq_err_o = + {(sfifo_bencreq_push && sfifo_bencreq_full), + (sfifo_bencreq_pop && !sfifo_bencreq_not_empty), + (sfifo_bencreq_full && !sfifo_bencreq_not_empty)}; + + //-------------------------------------------- + // block_encrypt response fifo from block encrypt + //-------------------------------------------- + + caliptra_prim_fifo_sync #( + .Width(BlkEncAckFifoWidth), + .Pass(0), + .Depth(BlkEncAckFifoDepth), + .OutputZeroIfEmpty(1'b0) + ) u_caliptra_prim_fifo_sync_bencack ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .clr_i (!ctr_drbg_upd_enable_i), + .wvalid_i (sfifo_bencack_push), + .wready_o (), + .wdata_i (sfifo_bencack_wdata), + .rvalid_o (sfifo_bencack_not_empty), + .rready_i (sfifo_bencack_pop), + .rdata_o (sfifo_bencack_rdata), + .full_o (sfifo_bencack_full), + .depth_o (), + .err_o () + ); + + assign sfifo_bencack_push = !sfifo_bencack_full && block_encrypt_ack_i; + assign sfifo_bencack_wdata = {block_encrypt_v_i,block_encrypt_inst_id_i,block_encrypt_ccmd_i}; + assign block_encrypt_rdy_o = !sfifo_bencack_full; + + assign {sfifo_bencack_v,sfifo_bencack_inst_id,sfifo_bencack_ccmd} = sfifo_bencack_rdata; + + assign ctr_drbg_upd_sfifo_bencack_err_o = + {(sfifo_bencack_push && sfifo_bencack_full), + (sfifo_bencack_pop && !sfifo_bencack_not_empty), + (sfifo_bencack_full && !sfifo_bencack_not_empty)}; + + //-------------------------------------------- + // fifo to stage provided_data, waiting for blk_encrypt to ack + //-------------------------------------------- + + caliptra_prim_fifo_sync #( + .Width(PDataFifoWidth), + .Pass(0), + .Depth(PDataFifoDepth), + .OutputZeroIfEmpty(1'b0) + ) u_caliptra_prim_fifo_sync_pdata ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .clr_i (!ctr_drbg_upd_enable_i), + .wvalid_i (sfifo_pdata_push), + .wready_o (), + .wdata_i (sfifo_pdata_wdata), + .rvalid_o (sfifo_pdata_not_empty), + .rready_i (sfifo_pdata_pop), + .rdata_o (sfifo_pdata_rdata), + .full_o (sfifo_pdata_full), + .depth_o (), + .err_o () + ); + + assign sfifo_pdata_wdata = sfifo_updreq_pdata; + + assign sfifo_pdata_v = sfifo_pdata_rdata; + + assign ctr_drbg_upd_sfifo_pdata_err_o = + {(sfifo_pdata_push && sfifo_pdata_full), + (sfifo_pdata_pop && !sfifo_pdata_not_empty), + (sfifo_pdata_full && !sfifo_pdata_not_empty)}; + + //-------------------------------------------- + // shifting logic to receive values from block_encrypt + //-------------------------------------------- + + assign concat_outblk_shifted_value = {concat_outblk_q, {BlkLen{1'b0}}}; + + assign concat_outblk_d = + (!ctr_drbg_upd_enable_i) ? '0 : + sfifo_bencack_pop ? {concat_outblk_q[SeedLen-1:BlkLen],sfifo_bencack_v} : + concat_outblk_shift ? concat_outblk_shifted_value[SeedLen-1:0] : + concat_outblk_q; + + // The following signal is used to avoid possible lint errors. + logic [BlkLen-1:0] unused_concat_outblk_shifted_value; + assign unused_concat_outblk_shifted_value = concat_outblk_shifted_value[SeedLen+BlkLen-1:SeedLen]; + + // concatination counter + assign concat_ctr_d = + (!ctr_drbg_upd_enable_i) ? '0 : + concat_ctr_done ? '0 : + concat_ctr_inc ? (concat_ctr_q + 1) : + concat_ctr_q; + + assign concat_ctr_done = (32'(concat_ctr_q) >= (SeedLen/BlkLen)); + + assign concat_inst_id_d = + (!ctr_drbg_upd_enable_i) ? '0 : + sfifo_bencack_pop ? sfifo_bencack_inst_id : + concat_inst_id_q; + + assign concat_ccmd_d = + (!ctr_drbg_upd_enable_i) ? '0 : + sfifo_bencack_pop ? sfifo_bencack_ccmd : + concat_ccmd_q; + + //-------------------------------------------- + // state machine to receive values from block_encrypt + //-------------------------------------------- + + always_comb begin + outblk_state_d = outblk_state_q; + concat_ctr_inc = 1'b0; + concat_outblk_shift = 1'b0; + sfifo_pdata_pop = 1'b0; + sfifo_bencack_pop = 1'b0; + sfifo_final_push = 1'b0; + ctr_drbg_updob_sm_err_o = 1'b0; + unique case (outblk_state_q) + // AckIdle: increment v this cycle, push in next + AckIdle: begin + if (!ctr_drbg_upd_enable_i) begin + outblk_state_d = AckIdle; + end else if (sfifo_bencack_not_empty && sfifo_pdata_not_empty && !sfifo_final_full) begin + outblk_state_d = Load; + end + end + Load: begin + if (!ctr_drbg_upd_enable_i) begin + outblk_state_d = AckIdle; + end else if (sfifo_bencack_not_empty) begin + concat_ctr_inc = 1'b1; + sfifo_bencack_pop = 1'b1; + outblk_state_d = Shift; + end + end + Shift: begin + if (!ctr_drbg_upd_enable_i) begin + outblk_state_d = AckIdle; + end else if (concat_ctr_done) begin + sfifo_pdata_pop = 1'b1; + sfifo_final_push = 1'b1; + outblk_state_d = AckIdle; + end else begin + concat_outblk_shift = 1'b1; + outblk_state_d = Load; + end + end + OBError: begin + ctr_drbg_updob_sm_err_o = 1'b1; + end + default: begin + outblk_state_d = OBError; + ctr_drbg_updob_sm_err_o = 1'b1; + end + endcase + end + + + //-------------------------------------------- + // final update processing + //-------------------------------------------- + + // XOR the additional data with the new key and value from block encryption + assign updated_key_and_v = concat_outblk_q ^ sfifo_pdata_v; + + caliptra_prim_fifo_sync #( + .Width(FinalFifoWidth), + .Pass(0), + .Depth(FinalFifoDepth), + .OutputZeroIfEmpty(1'b0) + ) u_caliptra_prim_fifo_sync_final ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .clr_i (!ctr_drbg_upd_enable_i), + .wvalid_i (sfifo_final_push), + .wready_o (), + .wdata_i (sfifo_final_wdata), + .rvalid_o (sfifo_final_not_empty), + .rready_i (sfifo_final_pop), + .rdata_o (sfifo_final_rdata), + .full_o (sfifo_final_full), + .depth_o (), + .err_o () + ); + + assign sfifo_final_wdata = {updated_key_and_v,concat_inst_id_q,concat_ccmd_q}; + + assign {sfifo_final_key,sfifo_final_v,sfifo_final_inst_id,sfifo_final_ccmd} = sfifo_final_rdata; + + assign sfifo_final_pop = ctr_drbg_upd_rdy_i && sfifo_final_not_empty; + assign ctr_drbg_upd_ack_o = sfifo_final_pop; + assign ctr_drbg_upd_ccmd_o = sfifo_final_ccmd; + assign ctr_drbg_upd_inst_id_o = sfifo_final_inst_id; + assign ctr_drbg_upd_key_o = sfifo_final_key; + assign ctr_drbg_upd_v_o = sfifo_final_v; + + assign ctr_drbg_upd_sfifo_final_err_o = + {(sfifo_final_push && sfifo_final_full), + (sfifo_final_pop && !sfifo_final_not_empty), + (sfifo_final_full && !sfifo_final_not_empty)}; + + // Make sure that the two state machines have a stable error state. This means that after the + // error state is entered it will not exit it unless a reset signal is received. + `CALIPTRA_ASSERT(CsrngDrbgUpdBlkEncErrorStStable_A, + blk_enc_state_q == BEError |=> $stable(blk_enc_state_q)) + `CALIPTRA_ASSERT(CsrngDrbgUpdOutBlkErrorStStable_A, + outblk_state_q == OBError |=> $stable(outblk_state_q)) + // If in error state, the error output must be high. + `CALIPTRA_ASSERT(CsrngDrbgUpdBlkEncErrorOutput_A, blk_enc_state_q == BEError |-> ctr_drbg_updbe_sm_err_o) + `CALIPTRA_ASSERT(CsrngDrbgUpdOutBlkErrorOutput_A, outblk_state_q == OBError |-> ctr_drbg_updob_sm_err_o) +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/csrng_main_sm.sv b/designs/Caliptra/src/caliptra-rtl/csrng_main_sm.sv new file mode 100644 index 0000000..87fedb5 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/csrng_main_sm.sv @@ -0,0 +1,175 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Description: csrng app cmd request state machine module +// +// - handles all app cmd requests from all requesting interfaces + +module csrng_main_sm import csrng_pkg::*; ( + input logic clk_i, + input logic rst_ni, + + input logic enable_i, + input logic acmd_avail_i, + output logic acmd_accept_o, + input logic [2:0] acmd_i, + input logic acmd_eop_i, + input logic ctr_drbg_cmd_req_rdy_i, + input logic flag0_i, + output logic cmd_entropy_req_o, + input logic cmd_entropy_avail_i, + output logic instant_req_o, + output logic reseed_req_o, + output logic generate_req_o, + output logic update_req_o, + output logic uninstant_req_o, + output logic clr_adata_packer_o, + input logic cmd_complete_i, + input logic local_escalate_i, + output logic [MainSmStateWidth-1:0] main_sm_state_o, + output logic main_sm_err_o +); + + main_sm_state_e state_d, state_q; + `CALIPTRA_PRIM_FLOP_SPARSE_FSM(u_state_regs, state_d, state_q, main_sm_state_e, MainSmIdle) + + assign main_sm_state_o = {state_q}; + + always_comb begin + state_d = state_q; + acmd_accept_o = 1'b0; + cmd_entropy_req_o = 1'b0; + instant_req_o = 1'b0; + reseed_req_o = 1'b0; + generate_req_o = 1'b0; + update_req_o = 1'b0; + uninstant_req_o = 1'b0; + clr_adata_packer_o = 1'b0; + main_sm_err_o = 1'b0; + + if (state_q == MainSmError) begin + // In case we are in the Error state we must ignore the local escalate and enable signals. + main_sm_err_o = 1'b1; + end else if (local_escalate_i) begin + // In case local escalate is high we must transition to the error state. + state_d = MainSmError; + end else if (!enable_i && state_q inside {MainSmIdle, MainSmParseCmd, MainSmInstantPrep, + MainSmInstantReq, MainSmReseedPrep, MainSmReseedReq, + MainSmGeneratePrep, MainSmGenerateReq, + MainSmUpdatePrep, MainSmUpdateReq, + MainSmUninstantPrep, MainSmUninstantReq, + MainSmClrAData, MainSmCmdCompWait}) begin + // In case the module is disabled and we are in a legal state we must go into idle state. + state_d = MainSmIdle; + end else begin + // Otherwise do the state machine as normal. + unique case (state_q) + MainSmIdle: begin + // Because of the if statement above we won't leave idle if enable is low. + if (ctr_drbg_cmd_req_rdy_i) begin + // Signal the arbiter to grant this request. + if (acmd_avail_i) begin + acmd_accept_o = 1'b1; + state_d = MainSmParseCmd; + end + end + end + MainSmParseCmd: begin + if (ctr_drbg_cmd_req_rdy_i && acmd_eop_i) begin + if (acmd_i == INS) begin + state_d = MainSmInstantPrep; + end else if (acmd_i == RES) begin + state_d = MainSmReseedPrep; + end else if (acmd_i == GEN) begin + state_d = MainSmGeneratePrep; + end else if (acmd_i == UPD) begin + state_d = MainSmUpdatePrep; + end else if (acmd_i == UNI) begin + state_d = MainSmUninstantPrep; + end else begin + // Command was not supported. + state_d = MainSmIdle; + end + end + end + MainSmInstantPrep: begin + if (flag0_i) begin + // Assumes all adata is present now. + state_d = MainSmInstantReq; + end else begin + // Delay one clock to fix timing issue. + cmd_entropy_req_o = 1'b1; + if (cmd_entropy_avail_i) begin + state_d = MainSmInstantReq; + end + end + end + MainSmInstantReq: begin + instant_req_o = 1'b1; + state_d = MainSmClrAData; + end + MainSmReseedPrep: begin + if (flag0_i) begin + // Assumes all adata is present now. + state_d = MainSmReseedReq; + end else begin + // Delay one clock to fix timing issue. + cmd_entropy_req_o = 1'b1; + if (cmd_entropy_avail_i) begin + state_d = MainSmReseedReq; + end + end + end + MainSmReseedReq: begin + reseed_req_o = 1'b1; + state_d = MainSmClrAData; + end + MainSmGeneratePrep: begin + // Assumes all adata is present now. + state_d = MainSmGenerateReq; + end + MainSmGenerateReq: begin + generate_req_o = 1'b1; + state_d = MainSmClrAData; + end + MainSmUpdatePrep: begin + // Assumes all adata is present now. + state_d = MainSmUpdateReq; + end + MainSmUpdateReq: begin + update_req_o = 1'b1; + state_d = MainSmClrAData; + end + MainSmUninstantPrep: begin + // Assumes all adata is present now. + state_d = MainSmUninstantReq; + end + MainSmUninstantReq: begin + uninstant_req_o = 1'b1; + state_d = MainSmClrAData; + end + MainSmClrAData: begin + clr_adata_packer_o = 1'b1; + state_d = MainSmCmdCompWait; + end + MainSmCmdCompWait: begin + if (cmd_complete_i) begin + state_d = MainSmIdle; + end + end + // Error: The error state is now covered by the if statement above. + default: begin + state_d = MainSmError; + main_sm_err_o = 1'b1; + end + endcase + end + end + + // Make sure that the state machine has a stable error state. This means that after the error + // state is entered it will not exit it unless a reset signal is received. + `CALIPTRA_ASSERT(CsrngMainErrorStStable_A, state_q == MainSmError |=> $stable(state_q)) + // If in error state, the error output must be high. + `CALIPTRA_ASSERT(CsrngMainErrorOutput_A, state_q == MainSmError |-> main_sm_err_o) +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/csrng_pkg.sv b/designs/Caliptra/src/caliptra-rtl/csrng_pkg.sv new file mode 100644 index 0000000..abc3a6d --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/csrng_pkg.sv @@ -0,0 +1,110 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// + +package csrng_pkg; + + //------------------------- + // Application Interfaces + //------------------------- + + parameter logic [31:0] GENBITS_BUS_WIDTH = 128; + parameter logic [31:0] CSRNG_CMD_WIDTH = 32; + parameter logic [31:0] FIPS_GENBITS_BUS_WIDTH = entropy_src_pkg::FIPS_BUS_WIDTH + + GENBITS_BUS_WIDTH; + parameter logic [31:0] MainSmStateWidth = 8; + parameter logic [31:0] CSRNG_CMD_STS_WIDTH = 3; + + // instantiation interface + typedef struct packed { + logic csrng_req_valid; + logic [CSRNG_CMD_WIDTH-1:0] csrng_req_bus; + logic genbits_ready; + } csrng_req_t; + + typedef enum logic [CSRNG_CMD_STS_WIDTH-1:0] { + CMD_STS_SUCCESS = 'h0, + CMD_STS_INVALID_ACMD = 'h1, + CMD_STS_INVALID_GEN_CMD = 'h2, + CMD_STS_INVALID_CMD_SEQ = 'h3, + CMD_STS_RESEED_CNT_EXCEEDED = 'h4, + CMD_STS_UNDRIVEN = 'z + } csrng_cmd_sts_e; + + typedef struct packed { + logic csrng_req_ready; + logic csrng_rsp_ack; + csrng_cmd_sts_e csrng_rsp_sts; + logic genbits_valid; + logic genbits_fips; + logic [GENBITS_BUS_WIDTH-1:0] genbits_bus; + } csrng_rsp_t; + + parameter csrng_req_t CSRNG_REQ_DEFAULT = '{default: '0}; + parameter csrng_rsp_t CSRNG_RSP_DEFAULT = '0; + + typedef enum logic [2:0] { + INV = 3'h0, + INS = 3'h1, + RES = 3'h2, + GEN = 3'h3, + UPD = 3'h4, + UNI = 3'h5, + GENB = 3'h6, + GENU = 3'h7 + } acmd_e; + + typedef struct packed { + logic [7:0] resv; + logic [11:0] glen; + logic [3:0] flag0; + logic [3:0] clen; + logic gap; // acmd is defined as 4 bits wide but only 3 are used + acmd_e acmd; + } csrng_cmd_t; + + + // Encoding generated with: + // $ ./util/design/sparse-fsm-encode.py -d 3 -m 15 -n 8 \ + // -s 1300573258 --language=sv + // + // Hamming distance histogram: + // + // 0: -- + // 1: -- + // 2: -- + // 3: |||||||||||||||||| (32.38%) + // 4: |||||||||||||||||||| (35.24%) + // 5: |||||||| (15.24%) + // 6: |||||| (11.43%) + // 7: ||| (5.71%) + // 8: -- + // + // Minimum Hamming distance: 3 + // Maximum Hamming distance: 7 + // Minimum Hamming weight: 1 + // Maximum Hamming weight: 7 + // + typedef enum logic [MainSmStateWidth-1:0] { + MainSmIdle = 8'b01001110, // idle + MainSmParseCmd = 8'b10111011, // parse the cmd + MainSmInstantPrep = 8'b11000001, // instantiate prep + MainSmInstantReq = 8'b01010100, // instantiate request (takes adata or entropy) + MainSmReseedPrep = 8'b11011101, // reseed prep + MainSmReseedReq = 8'b01011011, // reseed request (takes adata and entropy and Key,V,RC) + MainSmGeneratePrep = 8'b11101111, // generate request (takes adata? and Key,V,RC) + MainSmGenerateReq = 8'b00100100, // generate request (takes adata? and Key,V,RC) + MainSmUpdatePrep = 8'b00110001, // update prep + MainSmUpdateReq = 8'b10010000, // update request (takes adata and Key,V,RC) + MainSmUninstantPrep = 8'b11110110, // uninstantiate prep + MainSmUninstantReq = 8'b01100011, // uninstantiate request + MainSmClrAData = 8'b00000010, // clear out the additional data packer fifo + MainSmCmdCompWait = 8'b10111100, // wait for command to complete + MainSmError = 8'b01111000 // error state, results in fatal alert + } main_sm_state_e; + + parameter logic [31:0] CsKeymgrDivWidth = 384; + typedef logic [CsKeymgrDivWidth-1:0] cs_keymgr_div_t; + +endpackage : csrng_pkg diff --git a/designs/Caliptra/src/caliptra-rtl/csrng_reg_pkg.sv b/designs/Caliptra/src/caliptra-rtl/csrng_reg_pkg.sv new file mode 100644 index 0000000..6fcad8b --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/csrng_reg_pkg.sv @@ -0,0 +1,476 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Register Package auto-generated by `reggen` containing data structure + +package csrng_reg_pkg; + + // Param list + parameter logic [31:0] NumApps = 3; + parameter logic [31:0] NumAlerts = 2; + + // Address widths within the block + parameter logic [31:0] BlockAw = 7; + + //////////////////////////// + // Typedefs for registers // + //////////////////////////// + + typedef struct packed { + struct packed { + logic q; + } cs_fatal_err; + struct packed { + logic q; + } cs_hw_inst_exc; + struct packed { + logic q; + } cs_entropy_req; + struct packed { + logic q; + } cs_cmd_req_done; + } csrng_reg2hw_intr_state_reg_t; + + typedef struct packed { + struct packed { + logic q; + } cs_fatal_err; + struct packed { + logic q; + } cs_hw_inst_exc; + struct packed { + logic q; + } cs_entropy_req; + struct packed { + logic q; + } cs_cmd_req_done; + } csrng_reg2hw_intr_enable_reg_t; + + typedef struct packed { + struct packed { + logic q; + logic qe; + } cs_fatal_err; + struct packed { + logic q; + logic qe; + } cs_hw_inst_exc; + struct packed { + logic q; + logic qe; + } cs_entropy_req; + struct packed { + logic q; + logic qe; + } cs_cmd_req_done; + } csrng_reg2hw_intr_test_reg_t; + + typedef struct packed { + struct packed { + logic q; + logic qe; + } fatal_alert; + struct packed { + logic q; + logic qe; + } recov_alert; + } csrng_reg2hw_alert_test_reg_t; + + typedef struct packed { + struct packed { + logic [3:0] q; + } fips_force_enable; + struct packed { + logic [3:0] q; + } read_int_state; + struct packed { + logic [3:0] q; + } sw_app_enable; + struct packed { + logic [3:0] q; + } enable; + } csrng_reg2hw_ctrl_reg_t; + + typedef struct packed { + logic [31:0] q; + logic qe; + } csrng_reg2hw_cmd_req_reg_t; + + typedef struct packed { + logic [31:0] q; + logic qe; + } csrng_reg2hw_reseed_interval_reg_t; + + typedef struct packed { + logic [31:0] q; + logic re; + } csrng_reg2hw_genbits_reg_t; + + typedef struct packed { + logic [2:0] q; + } csrng_reg2hw_int_state_read_enable_reg_t; + + typedef struct packed { + logic [3:0] q; + logic qe; + } csrng_reg2hw_int_state_num_reg_t; + + typedef struct packed { + logic [31:0] q; + logic re; + } csrng_reg2hw_int_state_val_reg_t; + + typedef struct packed { + logic [2:0] q; + } csrng_reg2hw_fips_force_reg_t; + + typedef struct packed { + logic [4:0] q; + logic qe; + } csrng_reg2hw_err_code_test_reg_t; + + typedef struct packed { + struct packed { + logic d; + logic de; + } cs_cmd_req_done; + struct packed { + logic d; + logic de; + } cs_entropy_req; + struct packed { + logic d; + logic de; + } cs_hw_inst_exc; + struct packed { + logic d; + logic de; + } cs_fatal_err; + } csrng_hw2reg_intr_state_reg_t; + + typedef struct packed { + logic [31:0] d; + } csrng_hw2reg_reseed_counter_mreg_t; + + typedef struct packed { + struct packed { + logic d; + logic de; + } cmd_rdy; + struct packed { + logic d; + logic de; + } cmd_ack; + struct packed { + logic [2:0] d; + logic de; + } cmd_sts; + } csrng_hw2reg_sw_cmd_sts_reg_t; + + typedef struct packed { + struct packed { + logic d; + } genbits_vld; + struct packed { + logic d; + } genbits_fips; + } csrng_hw2reg_genbits_vld_reg_t; + + typedef struct packed { + logic [31:0] d; + } csrng_hw2reg_genbits_reg_t; + + typedef struct packed { + logic [31:0] d; + } csrng_hw2reg_int_state_val_reg_t; + + typedef struct packed { + logic [15:0] d; + logic de; + } csrng_hw2reg_hw_exc_sts_reg_t; + + typedef struct packed { + struct packed { + logic d; + logic de; + } enable_field_alert; + struct packed { + logic d; + logic de; + } sw_app_enable_field_alert; + struct packed { + logic d; + logic de; + } read_int_state_field_alert; + struct packed { + logic d; + logic de; + } fips_force_enable_field_alert; + struct packed { + logic d; + logic de; + } acmd_flag0_field_alert; + struct packed { + logic d; + logic de; + } cs_bus_cmp_alert; + struct packed { + logic d; + logic de; + } cmd_stage_invalid_acmd_alert; + struct packed { + logic d; + logic de; + } cmd_stage_invalid_cmd_seq_alert; + struct packed { + logic d; + logic de; + } cmd_stage_reseed_cnt_alert; + } csrng_hw2reg_recov_alert_sts_reg_t; + + typedef struct packed { + struct packed { + logic d; + logic de; + } sfifo_cmd_err; + struct packed { + logic d; + logic de; + } sfifo_genbits_err; + struct packed { + logic d; + logic de; + } sfifo_cmdreq_err; + struct packed { + logic d; + logic de; + } sfifo_rcstage_err; + struct packed { + logic d; + logic de; + } sfifo_keyvrc_err; + struct packed { + logic d; + logic de; + } sfifo_updreq_err; + struct packed { + logic d; + logic de; + } sfifo_bencreq_err; + struct packed { + logic d; + logic de; + } sfifo_bencack_err; + struct packed { + logic d; + logic de; + } sfifo_pdata_err; + struct packed { + logic d; + logic de; + } sfifo_final_err; + struct packed { + logic d; + logic de; + } sfifo_gbencack_err; + struct packed { + logic d; + logic de; + } sfifo_grcstage_err; + struct packed { + logic d; + logic de; + } sfifo_ggenreq_err; + struct packed { + logic d; + logic de; + } sfifo_gadstage_err; + struct packed { + logic d; + logic de; + } sfifo_ggenbits_err; + struct packed { + logic d; + logic de; + } sfifo_blkenc_err; + struct packed { + logic d; + logic de; + } cmd_stage_sm_err; + struct packed { + logic d; + logic de; + } main_sm_err; + struct packed { + logic d; + logic de; + } drbg_gen_sm_err; + struct packed { + logic d; + logic de; + } drbg_updbe_sm_err; + struct packed { + logic d; + logic de; + } drbg_updob_sm_err; + struct packed { + logic d; + logic de; + } aes_cipher_sm_err; + struct packed { + logic d; + logic de; + } cmd_gen_cnt_err; + struct packed { + logic d; + logic de; + } fifo_write_err; + struct packed { + logic d; + logic de; + } fifo_read_err; + struct packed { + logic d; + logic de; + } fifo_state_err; + } csrng_hw2reg_err_code_reg_t; + + typedef struct packed { + logic [7:0] d; + logic de; + } csrng_hw2reg_main_sm_state_reg_t; + + // Register -> HW type + typedef struct packed { + csrng_reg2hw_intr_state_reg_t intr_state; // [184:181] + csrng_reg2hw_intr_enable_reg_t intr_enable; // [180:177] + csrng_reg2hw_intr_test_reg_t intr_test; // [176:169] + csrng_reg2hw_alert_test_reg_t alert_test; // [168:165] + csrng_reg2hw_ctrl_reg_t ctrl; // [164:149] + csrng_reg2hw_cmd_req_reg_t cmd_req; // [148:116] + csrng_reg2hw_reseed_interval_reg_t reseed_interval; // [115:83] + csrng_reg2hw_genbits_reg_t genbits; // [82:50] + csrng_reg2hw_int_state_read_enable_reg_t int_state_read_enable; // [49:47] + csrng_reg2hw_int_state_num_reg_t int_state_num; // [46:42] + csrng_reg2hw_int_state_val_reg_t int_state_val; // [41:9] + csrng_reg2hw_fips_force_reg_t fips_force; // [8:6] + csrng_reg2hw_err_code_test_reg_t err_code_test; // [5:0] + } csrng_reg2hw_t; + + // HW -> register type + typedef struct packed { + csrng_hw2reg_intr_state_reg_t intr_state; // [273:266] + csrng_hw2reg_reseed_counter_mreg_t [2:0] reseed_counter; // [265:170] + csrng_hw2reg_sw_cmd_sts_reg_t sw_cmd_sts; // [169:162] + csrng_hw2reg_genbits_vld_reg_t genbits_vld; // [161:160] + csrng_hw2reg_genbits_reg_t genbits; // [159:128] + csrng_hw2reg_int_state_val_reg_t int_state_val; // [127:96] + csrng_hw2reg_hw_exc_sts_reg_t hw_exc_sts; // [95:79] + csrng_hw2reg_recov_alert_sts_reg_t recov_alert_sts; // [78:61] + csrng_hw2reg_err_code_reg_t err_code; // [60:9] + csrng_hw2reg_main_sm_state_reg_t main_sm_state; // [8:0] + } csrng_hw2reg_t; + + // Register offsets + parameter logic [BlockAw-1:0] CSRNG_INTR_STATE_OFFSET = 7'h 0; + parameter logic [BlockAw-1:0] CSRNG_INTR_ENABLE_OFFSET = 7'h 4; + parameter logic [BlockAw-1:0] CSRNG_INTR_TEST_OFFSET = 7'h 8; + parameter logic [BlockAw-1:0] CSRNG_ALERT_TEST_OFFSET = 7'h c; + parameter logic [BlockAw-1:0] CSRNG_REGWEN_OFFSET = 7'h 10; + parameter logic [BlockAw-1:0] CSRNG_CTRL_OFFSET = 7'h 14; + parameter logic [BlockAw-1:0] CSRNG_CMD_REQ_OFFSET = 7'h 18; + parameter logic [BlockAw-1:0] CSRNG_RESEED_INTERVAL_OFFSET = 7'h 1c; + parameter logic [BlockAw-1:0] CSRNG_RESEED_COUNTER_0_OFFSET = 7'h 20; + parameter logic [BlockAw-1:0] CSRNG_RESEED_COUNTER_1_OFFSET = 7'h 24; + parameter logic [BlockAw-1:0] CSRNG_RESEED_COUNTER_2_OFFSET = 7'h 28; + parameter logic [BlockAw-1:0] CSRNG_SW_CMD_STS_OFFSET = 7'h 2c; + parameter logic [BlockAw-1:0] CSRNG_GENBITS_VLD_OFFSET = 7'h 30; + parameter logic [BlockAw-1:0] CSRNG_GENBITS_OFFSET = 7'h 34; + parameter logic [BlockAw-1:0] CSRNG_INT_STATE_READ_ENABLE_OFFSET = 7'h 38; + parameter logic [BlockAw-1:0] CSRNG_INT_STATE_READ_ENABLE_REGWEN_OFFSET = 7'h 3c; + parameter logic [BlockAw-1:0] CSRNG_INT_STATE_NUM_OFFSET = 7'h 40; + parameter logic [BlockAw-1:0] CSRNG_INT_STATE_VAL_OFFSET = 7'h 44; + parameter logic [BlockAw-1:0] CSRNG_FIPS_FORCE_OFFSET = 7'h 48; + parameter logic [BlockAw-1:0] CSRNG_HW_EXC_STS_OFFSET = 7'h 4c; + parameter logic [BlockAw-1:0] CSRNG_RECOV_ALERT_STS_OFFSET = 7'h 50; + parameter logic [BlockAw-1:0] CSRNG_ERR_CODE_OFFSET = 7'h 54; + parameter logic [BlockAw-1:0] CSRNG_ERR_CODE_TEST_OFFSET = 7'h 58; + parameter logic [BlockAw-1:0] CSRNG_MAIN_SM_STATE_OFFSET = 7'h 5c; + + // Reset values for hwext registers and their fields + parameter logic [3:0] CSRNG_INTR_TEST_RESVAL = 4'h 0; + parameter logic [0:0] CSRNG_INTR_TEST_CS_CMD_REQ_DONE_RESVAL = 1'h 0; + parameter logic [0:0] CSRNG_INTR_TEST_CS_ENTROPY_REQ_RESVAL = 1'h 0; + parameter logic [0:0] CSRNG_INTR_TEST_CS_HW_INST_EXC_RESVAL = 1'h 0; + parameter logic [0:0] CSRNG_INTR_TEST_CS_FATAL_ERR_RESVAL = 1'h 0; + parameter logic [1:0] CSRNG_ALERT_TEST_RESVAL = 2'h 0; + parameter logic [0:0] CSRNG_ALERT_TEST_RECOV_ALERT_RESVAL = 1'h 0; + parameter logic [0:0] CSRNG_ALERT_TEST_FATAL_ALERT_RESVAL = 1'h 0; + parameter logic [31:0] CSRNG_RESEED_COUNTER_0_RESVAL = 32'h 0; + parameter logic [31:0] CSRNG_RESEED_COUNTER_0_RESEED_COUNTER_0_RESVAL = 32'h 0; + parameter logic [31:0] CSRNG_RESEED_COUNTER_1_RESVAL = 32'h 0; + parameter logic [31:0] CSRNG_RESEED_COUNTER_1_RESEED_COUNTER_1_RESVAL = 32'h 0; + parameter logic [31:0] CSRNG_RESEED_COUNTER_2_RESVAL = 32'h 0; + parameter logic [31:0] CSRNG_RESEED_COUNTER_2_RESEED_COUNTER_2_RESVAL = 32'h 0; + parameter logic [1:0] CSRNG_GENBITS_VLD_RESVAL = 2'h 0; + parameter logic [31:0] CSRNG_GENBITS_RESVAL = 32'h 0; + parameter logic [31:0] CSRNG_INT_STATE_VAL_RESVAL = 32'h 0; + + // Register index + typedef enum logic [31:0] { + CSRNG_INTR_STATE, + CSRNG_INTR_ENABLE, + CSRNG_INTR_TEST, + CSRNG_ALERT_TEST, + CSRNG_REGWEN, + CSRNG_CTRL, + CSRNG_CMD_REQ, + CSRNG_RESEED_INTERVAL, + CSRNG_RESEED_COUNTER_0, + CSRNG_RESEED_COUNTER_1, + CSRNG_RESEED_COUNTER_2, + CSRNG_SW_CMD_STS, + CSRNG_GENBITS_VLD, + CSRNG_GENBITS, + CSRNG_INT_STATE_READ_ENABLE, + CSRNG_INT_STATE_READ_ENABLE_REGWEN, + CSRNG_INT_STATE_NUM, + CSRNG_INT_STATE_VAL, + CSRNG_FIPS_FORCE, + CSRNG_HW_EXC_STS, + CSRNG_RECOV_ALERT_STS, + CSRNG_ERR_CODE, + CSRNG_ERR_CODE_TEST, + CSRNG_MAIN_SM_STATE + } csrng_id_e; + + // Register width information to check illegal writes + parameter logic [3:0] CSRNG_PERMIT [24] = '{ + 4'b 0001, // index[ 0] CSRNG_INTR_STATE + 4'b 0001, // index[ 1] CSRNG_INTR_ENABLE + 4'b 0001, // index[ 2] CSRNG_INTR_TEST + 4'b 0001, // index[ 3] CSRNG_ALERT_TEST + 4'b 0001, // index[ 4] CSRNG_REGWEN + 4'b 0011, // index[ 5] CSRNG_CTRL + 4'b 1111, // index[ 6] CSRNG_CMD_REQ + 4'b 1111, // index[ 7] CSRNG_RESEED_INTERVAL + 4'b 1111, // index[ 8] CSRNG_RESEED_COUNTER_0 + 4'b 1111, // index[ 9] CSRNG_RESEED_COUNTER_1 + 4'b 1111, // index[10] CSRNG_RESEED_COUNTER_2 + 4'b 0001, // index[11] CSRNG_SW_CMD_STS + 4'b 0001, // index[12] CSRNG_GENBITS_VLD + 4'b 1111, // index[13] CSRNG_GENBITS + 4'b 0001, // index[14] CSRNG_INT_STATE_READ_ENABLE + 4'b 0001, // index[15] CSRNG_INT_STATE_READ_ENABLE_REGWEN + 4'b 0001, // index[16] CSRNG_INT_STATE_NUM + 4'b 1111, // index[17] CSRNG_INT_STATE_VAL + 4'b 0001, // index[18] CSRNG_FIPS_FORCE + 4'b 0011, // index[19] CSRNG_HW_EXC_STS + 4'b 0011, // index[20] CSRNG_RECOV_ALERT_STS + 4'b 1111, // index[21] CSRNG_ERR_CODE + 4'b 0001, // index[22] CSRNG_ERR_CODE_TEST + 4'b 0001 // index[23] CSRNG_MAIN_SM_STATE + }; + +endpackage diff --git a/designs/Caliptra/src/caliptra-rtl/csrng_reg_top.sv b/designs/Caliptra/src/caliptra-rtl/csrng_reg_top.sv new file mode 100644 index 0000000..346cd21 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/csrng_reg_top.sv @@ -0,0 +1,2562 @@ +// Copyright lowRISC contributors (OpenTitan project) (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Register Top module auto-generated by `reggen` + +`include "caliptra_prim_assert.sv" + +module csrng_reg_top #( + parameter AHBDataWidth = 64, + parameter AHBAddrWidth = 32 + ) ( + input clk_i, + input rst_ni, + // AMBA AHB Lite Interface + input logic [AHBAddrWidth-1:0] haddr_i, + input logic [AHBDataWidth-1:0] hwdata_i, + input logic hsel_i, + input logic hwrite_i, + input logic hready_i, + input logic [1:0] htrans_i, + input logic [2:0] hsize_i, + + output logic hresp_o, + output logic hreadyout_o, + output logic [AHBDataWidth-1:0] hrdata_o, + + // To HW + output csrng_reg_pkg::csrng_reg2hw_t reg2hw, // Write + input csrng_reg_pkg::csrng_hw2reg_t hw2reg, // Read + + // Integrity check errors + output logic intg_err_o +); + + import csrng_reg_pkg::*; + + localparam logic[31:0] AW = 7; + localparam logic[31:0] DW = 32; + localparam logic[31:0] DBW = DW/8; // Byte Width + + // ahb interface register signals + logic ahb_reg_dv; + logic ahb_reg_hld; + logic ahb_reg_err; + logic ahb_reg_write; + logic [DW-1:0] ahb_reg_wdata; + logic [AW-1:0] ahb_reg_addr; + logic [DW-1:0] ahb_reg_rdata; + // register signals + logic reg_we; + logic reg_re; + logic [AW-1:0] reg_addr; + logic [DW-1:0] reg_wdata; + logic [DBW-1:0] reg_be; + logic [DW-1:0] reg_rdata; + logic reg_error; + + logic addrmiss, wr_err; + + logic [DW-1:0] reg_rdata_next; + logic reg_busy; + + // also check for spurious write enables + logic reg_we_err; + logic [23:0] reg_we_check; + caliptra_prim_reg_we_check #( + .OneHotWidth(24) + ) u_caliptra_prim_reg_we_check ( + .clk_i(clk_i), + .rst_ni(rst_ni), + .oh_i (reg_we_check), + .en_i (reg_we && !addrmiss), + .err_o (reg_we_err) + ); + + logic err_q; + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + err_q <= '0; + end else if (reg_we_err) begin + err_q <= 1'b1; + end + end + + // integrity error output is permanent and should be used for alert generation + // register errors are transactional + assign intg_err_o = err_q | reg_we_err; + + ahb_slv_sif #( + .AHB_DATA_WIDTH (AHBDataWidth), + .AHB_ADDR_WIDTH (AHBAddrWidth), + .CLIENT_DATA_WIDTH (DW), + .CLIENT_ADDR_WIDTH (AW) + ) u_ahb_slv_sif ( + .hclk (clk_i), + .hreset_n (rst_ni), + .haddr_i (haddr_i), + .hwdata_i (hwdata_i), + .hsel_i (hsel_i), + .hwrite_i (hwrite_i), + .hready_i (hready_i), + .htrans_i (htrans_i), + .hsize_i (hsize_i), + .hresp_o (hresp_o), + .hreadyout_o (hreadyout_o), + .hrdata_o (hrdata_o), + //component inf + .dv (ahb_reg_dv), + .hld (ahb_reg_hld), + .err (ahb_reg_err), + .write (ahb_reg_write), + .wdata (ahb_reg_wdata), + .addr (ahb_reg_addr), + .rdata (ahb_reg_rdata) + ); + + ahb_to_reg_adapter #( + .DATA_WIDTH (DW), + .ADDR_WIDTH (AW) + ) u_ahb_to_reg_adapter ( + .clk (clk_i), + .rst_n (rst_ni), + .ahb_reg_dv (ahb_reg_dv), + .ahb_reg_hld (ahb_reg_hld), + .ahb_reg_err (ahb_reg_err), + .ahb_reg_write (ahb_reg_write), + .ahb_reg_wdata (ahb_reg_wdata), + .ahb_reg_addr (ahb_reg_addr), + .ahb_reg_rdata (ahb_reg_rdata), + .reg_we (reg_we), + .reg_re (reg_re), + .reg_addr (reg_addr), + .reg_wdata (reg_wdata), + .reg_be (reg_be), + .reg_rdata (reg_rdata), + .reg_error (reg_error), + .reg_busy (reg_busy) + ); + + // cdc oversampling signals + + assign reg_rdata = reg_rdata_next; + assign reg_error = addrmiss | wr_err; + + // Define SW related signals + // Format: __{wd|we|qs} + // or _{wd|we|qs} if field == 1 or 0 + logic intr_state_we; + logic intr_state_cs_cmd_req_done_qs; + logic intr_state_cs_cmd_req_done_wd; + logic intr_state_cs_entropy_req_qs; + logic intr_state_cs_entropy_req_wd; + logic intr_state_cs_hw_inst_exc_qs; + logic intr_state_cs_hw_inst_exc_wd; + logic intr_state_cs_fatal_err_qs; + logic intr_state_cs_fatal_err_wd; + logic intr_enable_we; + logic intr_enable_cs_cmd_req_done_qs; + logic intr_enable_cs_cmd_req_done_wd; + logic intr_enable_cs_entropy_req_qs; + logic intr_enable_cs_entropy_req_wd; + logic intr_enable_cs_hw_inst_exc_qs; + logic intr_enable_cs_hw_inst_exc_wd; + logic intr_enable_cs_fatal_err_qs; + logic intr_enable_cs_fatal_err_wd; + logic intr_test_we; + logic intr_test_cs_cmd_req_done_wd; + logic intr_test_cs_entropy_req_wd; + logic intr_test_cs_hw_inst_exc_wd; + logic intr_test_cs_fatal_err_wd; + logic alert_test_we; + logic alert_test_recov_alert_wd; + logic alert_test_fatal_alert_wd; + logic regwen_we; + logic regwen_qs; + logic regwen_wd; + logic ctrl_we; + logic [3:0] ctrl_enable_qs; + logic [3:0] ctrl_enable_wd; + logic [3:0] ctrl_sw_app_enable_qs; + logic [3:0] ctrl_sw_app_enable_wd; + logic [3:0] ctrl_read_int_state_qs; + logic [3:0] ctrl_read_int_state_wd; + logic [3:0] ctrl_fips_force_enable_qs; + logic [3:0] ctrl_fips_force_enable_wd; + logic cmd_req_we; + logic [31:0] cmd_req_wd; + logic reseed_interval_we; + logic [31:0] reseed_interval_qs; + logic [31:0] reseed_interval_wd; + logic reseed_counter_0_re; + logic [31:0] reseed_counter_0_qs; + logic reseed_counter_1_re; + logic [31:0] reseed_counter_1_qs; + logic reseed_counter_2_re; + logic [31:0] reseed_counter_2_qs; + logic sw_cmd_sts_cmd_rdy_qs; + logic sw_cmd_sts_cmd_ack_qs; + logic [2:0] sw_cmd_sts_cmd_sts_qs; + logic genbits_vld_re; + logic genbits_vld_genbits_vld_qs; + logic genbits_vld_genbits_fips_qs; + logic genbits_re; + logic [31:0] genbits_qs; + logic int_state_read_enable_we; + logic [2:0] int_state_read_enable_qs; + logic [2:0] int_state_read_enable_wd; + logic int_state_read_enable_regwen_we; + logic int_state_read_enable_regwen_qs; + logic int_state_read_enable_regwen_wd; + logic int_state_num_we; + logic [3:0] int_state_num_qs; + logic [3:0] int_state_num_wd; + logic int_state_val_re; + logic [31:0] int_state_val_qs; + logic fips_force_we; + logic [2:0] fips_force_qs; + logic [2:0] fips_force_wd; + logic hw_exc_sts_we; + logic [15:0] hw_exc_sts_qs; + logic [15:0] hw_exc_sts_wd; + logic recov_alert_sts_we; + logic recov_alert_sts_enable_field_alert_qs; + logic recov_alert_sts_enable_field_alert_wd; + logic recov_alert_sts_sw_app_enable_field_alert_qs; + logic recov_alert_sts_sw_app_enable_field_alert_wd; + logic recov_alert_sts_read_int_state_field_alert_qs; + logic recov_alert_sts_read_int_state_field_alert_wd; + logic recov_alert_sts_fips_force_enable_field_alert_qs; + logic recov_alert_sts_fips_force_enable_field_alert_wd; + logic recov_alert_sts_acmd_flag0_field_alert_qs; + logic recov_alert_sts_acmd_flag0_field_alert_wd; + logic recov_alert_sts_cs_bus_cmp_alert_qs; + logic recov_alert_sts_cs_bus_cmp_alert_wd; + logic recov_alert_sts_cmd_stage_invalid_acmd_alert_qs; + logic recov_alert_sts_cmd_stage_invalid_acmd_alert_wd; + logic recov_alert_sts_cmd_stage_invalid_cmd_seq_alert_qs; + logic recov_alert_sts_cmd_stage_invalid_cmd_seq_alert_wd; + logic recov_alert_sts_cmd_stage_reseed_cnt_alert_qs; + logic recov_alert_sts_cmd_stage_reseed_cnt_alert_wd; + logic err_code_sfifo_cmd_err_qs; + logic err_code_sfifo_genbits_err_qs; + logic err_code_sfifo_cmdreq_err_qs; + logic err_code_sfifo_rcstage_err_qs; + logic err_code_sfifo_keyvrc_err_qs; + logic err_code_sfifo_updreq_err_qs; + logic err_code_sfifo_bencreq_err_qs; + logic err_code_sfifo_bencack_err_qs; + logic err_code_sfifo_pdata_err_qs; + logic err_code_sfifo_final_err_qs; + logic err_code_sfifo_gbencack_err_qs; + logic err_code_sfifo_grcstage_err_qs; + logic err_code_sfifo_ggenreq_err_qs; + logic err_code_sfifo_gadstage_err_qs; + logic err_code_sfifo_ggenbits_err_qs; + logic err_code_sfifo_blkenc_err_qs; + logic err_code_cmd_stage_sm_err_qs; + logic err_code_main_sm_err_qs; + logic err_code_drbg_gen_sm_err_qs; + logic err_code_drbg_updbe_sm_err_qs; + logic err_code_drbg_updob_sm_err_qs; + logic err_code_aes_cipher_sm_err_qs; + logic err_code_cmd_gen_cnt_err_qs; + logic err_code_fifo_write_err_qs; + logic err_code_fifo_read_err_qs; + logic err_code_fifo_state_err_qs; + logic err_code_test_we; + logic [4:0] err_code_test_qs; + logic [4:0] err_code_test_wd; + logic [7:0] main_sm_state_qs; + + // Register instances + // R[intr_state]: V(False) + // F[cs_cmd_req_done]: 0:0 + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessW1C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_intr_state_cs_cmd_req_done ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (intr_state_we), + .wd (intr_state_cs_cmd_req_done_wd), + + // from internal hardware + .de (hw2reg.intr_state.cs_cmd_req_done.de), + .d (hw2reg.intr_state.cs_cmd_req_done.d), + + // to internal hardware + .qe (), + .q (reg2hw.intr_state.cs_cmd_req_done.q), + .ds (), + + // to register interface (read) + .qs (intr_state_cs_cmd_req_done_qs) + ); + + // F[cs_entropy_req]: 1:1 + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessW1C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_intr_state_cs_entropy_req ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (intr_state_we), + .wd (intr_state_cs_entropy_req_wd), + + // from internal hardware + .de (hw2reg.intr_state.cs_entropy_req.de), + .d (hw2reg.intr_state.cs_entropy_req.d), + + // to internal hardware + .qe (), + .q (reg2hw.intr_state.cs_entropy_req.q), + .ds (), + + // to register interface (read) + .qs (intr_state_cs_entropy_req_qs) + ); + + // F[cs_hw_inst_exc]: 2:2 + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessW1C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_intr_state_cs_hw_inst_exc ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (intr_state_we), + .wd (intr_state_cs_hw_inst_exc_wd), + + // from internal hardware + .de (hw2reg.intr_state.cs_hw_inst_exc.de), + .d (hw2reg.intr_state.cs_hw_inst_exc.d), + + // to internal hardware + .qe (), + .q (reg2hw.intr_state.cs_hw_inst_exc.q), + .ds (), + + // to register interface (read) + .qs (intr_state_cs_hw_inst_exc_qs) + ); + + // F[cs_fatal_err]: 3:3 + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessW1C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_intr_state_cs_fatal_err ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (intr_state_we), + .wd (intr_state_cs_fatal_err_wd), + + // from internal hardware + .de (hw2reg.intr_state.cs_fatal_err.de), + .d (hw2reg.intr_state.cs_fatal_err.d), + + // to internal hardware + .qe (), + .q (reg2hw.intr_state.cs_fatal_err.q), + .ds (), + + // to register interface (read) + .qs (intr_state_cs_fatal_err_qs) + ); + + + // R[intr_enable]: V(False) + // F[cs_cmd_req_done]: 0:0 + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_intr_enable_cs_cmd_req_done ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (intr_enable_we), + .wd (intr_enable_cs_cmd_req_done_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.intr_enable.cs_cmd_req_done.q), + .ds (), + + // to register interface (read) + .qs (intr_enable_cs_cmd_req_done_qs) + ); + + // F[cs_entropy_req]: 1:1 + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_intr_enable_cs_entropy_req ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (intr_enable_we), + .wd (intr_enable_cs_entropy_req_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.intr_enable.cs_entropy_req.q), + .ds (), + + // to register interface (read) + .qs (intr_enable_cs_entropy_req_qs) + ); + + // F[cs_hw_inst_exc]: 2:2 + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_intr_enable_cs_hw_inst_exc ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (intr_enable_we), + .wd (intr_enable_cs_hw_inst_exc_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.intr_enable.cs_hw_inst_exc.q), + .ds (), + + // to register interface (read) + .qs (intr_enable_cs_hw_inst_exc_qs) + ); + + // F[cs_fatal_err]: 3:3 + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_intr_enable_cs_fatal_err ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (intr_enable_we), + .wd (intr_enable_cs_fatal_err_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.intr_enable.cs_fatal_err.q), + .ds (), + + // to register interface (read) + .qs (intr_enable_cs_fatal_err_qs) + ); + + + // R[intr_test]: V(True) + logic intr_test_qe; + logic [3:0] intr_test_flds_we; + assign intr_test_qe = &intr_test_flds_we; + // F[cs_cmd_req_done]: 0:0 + caliptra_prim_subreg_ext #( + .DW (1) + ) u_intr_test_cs_cmd_req_done ( + .re (1'b0), + .we (intr_test_we), + .wd (intr_test_cs_cmd_req_done_wd), + .d ('0), + .qre (), + .qe (intr_test_flds_we[0]), + .q (reg2hw.intr_test.cs_cmd_req_done.q), + .ds (), + .qs () + ); + assign reg2hw.intr_test.cs_cmd_req_done.qe = intr_test_qe; + + // F[cs_entropy_req]: 1:1 + caliptra_prim_subreg_ext #( + .DW (1) + ) u_intr_test_cs_entropy_req ( + .re (1'b0), + .we (intr_test_we), + .wd (intr_test_cs_entropy_req_wd), + .d ('0), + .qre (), + .qe (intr_test_flds_we[1]), + .q (reg2hw.intr_test.cs_entropy_req.q), + .ds (), + .qs () + ); + assign reg2hw.intr_test.cs_entropy_req.qe = intr_test_qe; + + // F[cs_hw_inst_exc]: 2:2 + caliptra_prim_subreg_ext #( + .DW (1) + ) u_intr_test_cs_hw_inst_exc ( + .re (1'b0), + .we (intr_test_we), + .wd (intr_test_cs_hw_inst_exc_wd), + .d ('0), + .qre (), + .qe (intr_test_flds_we[2]), + .q (reg2hw.intr_test.cs_hw_inst_exc.q), + .ds (), + .qs () + ); + assign reg2hw.intr_test.cs_hw_inst_exc.qe = intr_test_qe; + + // F[cs_fatal_err]: 3:3 + caliptra_prim_subreg_ext #( + .DW (1) + ) u_intr_test_cs_fatal_err ( + .re (1'b0), + .we (intr_test_we), + .wd (intr_test_cs_fatal_err_wd), + .d ('0), + .qre (), + .qe (intr_test_flds_we[3]), + .q (reg2hw.intr_test.cs_fatal_err.q), + .ds (), + .qs () + ); + assign reg2hw.intr_test.cs_fatal_err.qe = intr_test_qe; + + + // R[alert_test]: V(True) + logic alert_test_qe; + logic [1:0] alert_test_flds_we; + assign alert_test_qe = &alert_test_flds_we; + // F[recov_alert]: 0:0 + caliptra_prim_subreg_ext #( + .DW (1) + ) u_alert_test_recov_alert ( + .re (1'b0), + .we (alert_test_we), + .wd (alert_test_recov_alert_wd), + .d ('0), + .qre (), + .qe (alert_test_flds_we[0]), + .q (reg2hw.alert_test.recov_alert.q), + .ds (), + .qs () + ); + assign reg2hw.alert_test.recov_alert.qe = alert_test_qe; + + // F[fatal_alert]: 1:1 + caliptra_prim_subreg_ext #( + .DW (1) + ) u_alert_test_fatal_alert ( + .re (1'b0), + .we (alert_test_we), + .wd (alert_test_fatal_alert_wd), + .d ('0), + .qre (), + .qe (alert_test_flds_we[1]), + .q (reg2hw.alert_test.fatal_alert.q), + .ds (), + .qs () + ); + assign reg2hw.alert_test.fatal_alert.qe = alert_test_qe; + + + // R[regwen]: V(False) + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_regwen ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (regwen_we), + .wd (regwen_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (regwen_qs) + ); + + + // R[ctrl]: V(False) + // Create REGWEN-gated WE signal + logic ctrl_gated_we; + assign ctrl_gated_we = ctrl_we & regwen_qs; + // F[enable]: 3:0 + caliptra_prim_subreg #( + .DW (4), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_ctrl_enable ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (ctrl_gated_we), + .wd (ctrl_enable_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.ctrl.enable.q), + .ds (), + + // to register interface (read) + .qs (ctrl_enable_qs) + ); + + // F[sw_app_enable]: 7:4 + caliptra_prim_subreg #( + .DW (4), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_ctrl_sw_app_enable ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (ctrl_gated_we), + .wd (ctrl_sw_app_enable_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.ctrl.sw_app_enable.q), + .ds (), + + // to register interface (read) + .qs (ctrl_sw_app_enable_qs) + ); + + // F[read_int_state]: 11:8 + caliptra_prim_subreg #( + .DW (4), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_ctrl_read_int_state ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (ctrl_gated_we), + .wd (ctrl_read_int_state_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.ctrl.read_int_state.q), + .ds (), + + // to register interface (read) + .qs (ctrl_read_int_state_qs) + ); + + // F[fips_force_enable]: 15:12 + caliptra_prim_subreg #( + .DW (4), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_ctrl_fips_force_enable ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (ctrl_gated_we), + .wd (ctrl_fips_force_enable_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.ctrl.fips_force_enable.q), + .ds (), + + // to register interface (read) + .qs (ctrl_fips_force_enable_qs) + ); + + + // R[cmd_req]: V(False) + logic cmd_req_qe; + logic [0:0] cmd_req_flds_we; + caliptra_prim_flop #( + .Width(1), + .ResetValue(0) + ) u_cmd_req0_qe ( + .clk_i(clk_i), + .rst_ni(rst_ni), + .d_i(&cmd_req_flds_we), + .q_o(cmd_req_qe) + ); + caliptra_prim_subreg #( + .DW (32), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessWO), + .RESVAL (32'h0), + .Mubi (1'b0) + ) u_cmd_req ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (cmd_req_we), + .wd (cmd_req_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (cmd_req_flds_we[0]), + .q (reg2hw.cmd_req.q), + .ds (), + + // to register interface (read) + .qs () + ); + assign reg2hw.cmd_req.qe = cmd_req_qe; + + + // R[reseed_interval]: V(False) + logic reseed_interval_qe; + logic [0:0] reseed_interval_flds_we; + caliptra_prim_flop #( + .Width(1), + .ResetValue(0) + ) u_reseed_interval0_qe ( + .clk_i(clk_i), + .rst_ni(rst_ni), + .d_i(&reseed_interval_flds_we), + .q_o(reseed_interval_qe) + ); + caliptra_prim_subreg #( + .DW (32), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRW), + .RESVAL (32'hffffffff), + .Mubi (1'b0) + ) u_reseed_interval ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (reseed_interval_we), + .wd (reseed_interval_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (reseed_interval_flds_we[0]), + .q (reg2hw.reseed_interval.q), + .ds (), + + // to register interface (read) + .qs (reseed_interval_qs) + ); + assign reg2hw.reseed_interval.qe = reseed_interval_qe; + + + // Subregister 0 of Multireg reseed_counter + // R[reseed_counter_0]: V(True) + caliptra_prim_subreg_ext #( + .DW (32) + ) u_reseed_counter_0 ( + .re (reseed_counter_0_re), + .we (1'b0), + .wd ('0), + .d (hw2reg.reseed_counter[0].d), + .qre (), + .qe (), + .q (), + .ds (), + .qs (reseed_counter_0_qs) + ); + + + // Subregister 1 of Multireg reseed_counter + // R[reseed_counter_1]: V(True) + caliptra_prim_subreg_ext #( + .DW (32) + ) u_reseed_counter_1 ( + .re (reseed_counter_1_re), + .we (1'b0), + .wd ('0), + .d (hw2reg.reseed_counter[1].d), + .qre (), + .qe (), + .q (), + .ds (), + .qs (reseed_counter_1_qs) + ); + + + // Subregister 2 of Multireg reseed_counter + // R[reseed_counter_2]: V(True) + caliptra_prim_subreg_ext #( + .DW (32) + ) u_reseed_counter_2 ( + .re (reseed_counter_2_re), + .we (1'b0), + .wd ('0), + .d (hw2reg.reseed_counter[2].d), + .qre (), + .qe (), + .q (), + .ds (), + .qs (reseed_counter_2_qs) + ); + + + // R[sw_cmd_sts]: V(False) + // F[cmd_rdy]: 1:1 + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_sw_cmd_sts_cmd_rdy ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.sw_cmd_sts.cmd_rdy.de), + .d (hw2reg.sw_cmd_sts.cmd_rdy.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (sw_cmd_sts_cmd_rdy_qs) + ); + + // F[cmd_ack]: 2:2 + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_sw_cmd_sts_cmd_ack ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.sw_cmd_sts.cmd_ack.de), + .d (hw2reg.sw_cmd_sts.cmd_ack.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (sw_cmd_sts_cmd_ack_qs) + ); + + // F[cmd_sts]: 5:3 + caliptra_prim_subreg #( + .DW (3), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRO), + .RESVAL (3'h0), + .Mubi (1'b0) + ) u_sw_cmd_sts_cmd_sts ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.sw_cmd_sts.cmd_sts.de), + .d (hw2reg.sw_cmd_sts.cmd_sts.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (sw_cmd_sts_cmd_sts_qs) + ); + + + // R[genbits_vld]: V(True) + // F[genbits_vld]: 0:0 + caliptra_prim_subreg_ext #( + .DW (1) + ) u_genbits_vld_genbits_vld ( + .re (genbits_vld_re), + .we (1'b0), + .wd ('0), + .d (hw2reg.genbits_vld.genbits_vld.d), + .qre (), + .qe (), + .q (), + .ds (), + .qs (genbits_vld_genbits_vld_qs) + ); + + // F[genbits_fips]: 1:1 + caliptra_prim_subreg_ext #( + .DW (1) + ) u_genbits_vld_genbits_fips ( + .re (genbits_vld_re), + .we (1'b0), + .wd ('0), + .d (hw2reg.genbits_vld.genbits_fips.d), + .qre (), + .qe (), + .q (), + .ds (), + .qs (genbits_vld_genbits_fips_qs) + ); + + + // R[genbits]: V(True) + caliptra_prim_subreg_ext #( + .DW (32) + ) u_genbits ( + .re (genbits_re), + .we (1'b0), + .wd ('0), + .d (hw2reg.genbits.d), + .qre (reg2hw.genbits.re), + .qe (), + .q (reg2hw.genbits.q), + .ds (), + .qs (genbits_qs) + ); + + + // R[int_state_read_enable]: V(False) + // Create REGWEN-gated WE signal + logic int_state_read_enable_gated_we; + assign int_state_read_enable_gated_we = + int_state_read_enable_we & int_state_read_enable_regwen_qs; + caliptra_prim_subreg #( + .DW (3), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRW), + .RESVAL (3'h7), + .Mubi (1'b0) + ) u_int_state_read_enable ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (int_state_read_enable_gated_we), + .wd (int_state_read_enable_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.int_state_read_enable.q), + .ds (), + + // to register interface (read) + .qs (int_state_read_enable_qs) + ); + + + // R[int_state_read_enable_regwen]: V(False) + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_int_state_read_enable_regwen ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (int_state_read_enable_regwen_we), + .wd (int_state_read_enable_regwen_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (int_state_read_enable_regwen_qs) + ); + + + // R[int_state_num]: V(False) + logic int_state_num_qe; + logic [0:0] int_state_num_flds_we; + caliptra_prim_flop #( + .Width(1), + .ResetValue(0) + ) u_int_state_num0_qe ( + .clk_i(clk_i), + .rst_ni(rst_ni), + .d_i(&int_state_num_flds_we), + .q_o(int_state_num_qe) + ); + caliptra_prim_subreg #( + .DW (4), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h0), + .Mubi (1'b0) + ) u_int_state_num ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (int_state_num_we), + .wd (int_state_num_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (int_state_num_flds_we[0]), + .q (reg2hw.int_state_num.q), + .ds (), + + // to register interface (read) + .qs (int_state_num_qs) + ); + assign reg2hw.int_state_num.qe = int_state_num_qe; + + + // R[int_state_val]: V(True) + caliptra_prim_subreg_ext #( + .DW (32) + ) u_int_state_val ( + .re (int_state_val_re), + .we (1'b0), + .wd ('0), + .d (hw2reg.int_state_val.d), + .qre (reg2hw.int_state_val.re), + .qe (), + .q (reg2hw.int_state_val.q), + .ds (), + .qs (int_state_val_qs) + ); + + + // R[fips_force]: V(False) + // Create REGWEN-gated WE signal + logic fips_force_gated_we; + assign fips_force_gated_we = fips_force_we & regwen_qs; + caliptra_prim_subreg #( + .DW (3), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRW), + .RESVAL (3'h0), + .Mubi (1'b0) + ) u_fips_force ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (fips_force_gated_we), + .wd (fips_force_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.fips_force.q), + .ds (), + + // to register interface (read) + .qs (fips_force_qs) + ); + + + // R[hw_exc_sts]: V(False) + caliptra_prim_subreg #( + .DW (16), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessW0C), + .RESVAL (16'h0), + .Mubi (1'b0) + ) u_hw_exc_sts ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (hw_exc_sts_we), + .wd (hw_exc_sts_wd), + + // from internal hardware + .de (hw2reg.hw_exc_sts.de), + .d (hw2reg.hw_exc_sts.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (hw_exc_sts_qs) + ); + + + // R[recov_alert_sts]: V(False) + // F[enable_field_alert]: 0:0 + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_recov_alert_sts_enable_field_alert ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (recov_alert_sts_we), + .wd (recov_alert_sts_enable_field_alert_wd), + + // from internal hardware + .de (hw2reg.recov_alert_sts.enable_field_alert.de), + .d (hw2reg.recov_alert_sts.enable_field_alert.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (recov_alert_sts_enable_field_alert_qs) + ); + + // F[sw_app_enable_field_alert]: 1:1 + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_recov_alert_sts_sw_app_enable_field_alert ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (recov_alert_sts_we), + .wd (recov_alert_sts_sw_app_enable_field_alert_wd), + + // from internal hardware + .de (hw2reg.recov_alert_sts.sw_app_enable_field_alert.de), + .d (hw2reg.recov_alert_sts.sw_app_enable_field_alert.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (recov_alert_sts_sw_app_enable_field_alert_qs) + ); + + // F[read_int_state_field_alert]: 2:2 + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_recov_alert_sts_read_int_state_field_alert ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (recov_alert_sts_we), + .wd (recov_alert_sts_read_int_state_field_alert_wd), + + // from internal hardware + .de (hw2reg.recov_alert_sts.read_int_state_field_alert.de), + .d (hw2reg.recov_alert_sts.read_int_state_field_alert.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (recov_alert_sts_read_int_state_field_alert_qs) + ); + + // F[fips_force_enable_field_alert]: 3:3 + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_recov_alert_sts_fips_force_enable_field_alert ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (recov_alert_sts_we), + .wd (recov_alert_sts_fips_force_enable_field_alert_wd), + + // from internal hardware + .de (hw2reg.recov_alert_sts.fips_force_enable_field_alert.de), + .d (hw2reg.recov_alert_sts.fips_force_enable_field_alert.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (recov_alert_sts_fips_force_enable_field_alert_qs) + ); + + // F[acmd_flag0_field_alert]: 4:4 + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_recov_alert_sts_acmd_flag0_field_alert ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (recov_alert_sts_we), + .wd (recov_alert_sts_acmd_flag0_field_alert_wd), + + // from internal hardware + .de (hw2reg.recov_alert_sts.acmd_flag0_field_alert.de), + .d (hw2reg.recov_alert_sts.acmd_flag0_field_alert.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (recov_alert_sts_acmd_flag0_field_alert_qs) + ); + + // F[cs_bus_cmp_alert]: 12:12 + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_recov_alert_sts_cs_bus_cmp_alert ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (recov_alert_sts_we), + .wd (recov_alert_sts_cs_bus_cmp_alert_wd), + + // from internal hardware + .de (hw2reg.recov_alert_sts.cs_bus_cmp_alert.de), + .d (hw2reg.recov_alert_sts.cs_bus_cmp_alert.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (recov_alert_sts_cs_bus_cmp_alert_qs) + ); + + // F[cmd_stage_invalid_acmd_alert]: 13:13 + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_recov_alert_sts_cmd_stage_invalid_acmd_alert ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (recov_alert_sts_we), + .wd (recov_alert_sts_cmd_stage_invalid_acmd_alert_wd), + + // from internal hardware + .de (hw2reg.recov_alert_sts.cmd_stage_invalid_acmd_alert.de), + .d (hw2reg.recov_alert_sts.cmd_stage_invalid_acmd_alert.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (recov_alert_sts_cmd_stage_invalid_acmd_alert_qs) + ); + + // F[cmd_stage_invalid_cmd_seq_alert]: 14:14 + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_recov_alert_sts_cmd_stage_invalid_cmd_seq_alert ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (recov_alert_sts_we), + .wd (recov_alert_sts_cmd_stage_invalid_cmd_seq_alert_wd), + + // from internal hardware + .de (hw2reg.recov_alert_sts.cmd_stage_invalid_cmd_seq_alert.de), + .d (hw2reg.recov_alert_sts.cmd_stage_invalid_cmd_seq_alert.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (recov_alert_sts_cmd_stage_invalid_cmd_seq_alert_qs) + ); + + // F[cmd_stage_reseed_cnt_alert]: 15:15 + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_recov_alert_sts_cmd_stage_reseed_cnt_alert ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (recov_alert_sts_we), + .wd (recov_alert_sts_cmd_stage_reseed_cnt_alert_wd), + + // from internal hardware + .de (hw2reg.recov_alert_sts.cmd_stage_reseed_cnt_alert.de), + .d (hw2reg.recov_alert_sts.cmd_stage_reseed_cnt_alert.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (recov_alert_sts_cmd_stage_reseed_cnt_alert_qs) + ); + + + // R[err_code]: V(False) + // F[sfifo_cmd_err]: 0:0 + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_err_code_sfifo_cmd_err ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.err_code.sfifo_cmd_err.de), + .d (hw2reg.err_code.sfifo_cmd_err.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (err_code_sfifo_cmd_err_qs) + ); + + // F[sfifo_genbits_err]: 1:1 + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_err_code_sfifo_genbits_err ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.err_code.sfifo_genbits_err.de), + .d (hw2reg.err_code.sfifo_genbits_err.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (err_code_sfifo_genbits_err_qs) + ); + + // F[sfifo_cmdreq_err]: 2:2 + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_err_code_sfifo_cmdreq_err ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.err_code.sfifo_cmdreq_err.de), + .d (hw2reg.err_code.sfifo_cmdreq_err.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (err_code_sfifo_cmdreq_err_qs) + ); + + // F[sfifo_rcstage_err]: 3:3 + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_err_code_sfifo_rcstage_err ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.err_code.sfifo_rcstage_err.de), + .d (hw2reg.err_code.sfifo_rcstage_err.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (err_code_sfifo_rcstage_err_qs) + ); + + // F[sfifo_keyvrc_err]: 4:4 + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_err_code_sfifo_keyvrc_err ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.err_code.sfifo_keyvrc_err.de), + .d (hw2reg.err_code.sfifo_keyvrc_err.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (err_code_sfifo_keyvrc_err_qs) + ); + + // F[sfifo_updreq_err]: 5:5 + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_err_code_sfifo_updreq_err ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.err_code.sfifo_updreq_err.de), + .d (hw2reg.err_code.sfifo_updreq_err.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (err_code_sfifo_updreq_err_qs) + ); + + // F[sfifo_bencreq_err]: 6:6 + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_err_code_sfifo_bencreq_err ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.err_code.sfifo_bencreq_err.de), + .d (hw2reg.err_code.sfifo_bencreq_err.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (err_code_sfifo_bencreq_err_qs) + ); + + // F[sfifo_bencack_err]: 7:7 + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_err_code_sfifo_bencack_err ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.err_code.sfifo_bencack_err.de), + .d (hw2reg.err_code.sfifo_bencack_err.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (err_code_sfifo_bencack_err_qs) + ); + + // F[sfifo_pdata_err]: 8:8 + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_err_code_sfifo_pdata_err ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.err_code.sfifo_pdata_err.de), + .d (hw2reg.err_code.sfifo_pdata_err.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (err_code_sfifo_pdata_err_qs) + ); + + // F[sfifo_final_err]: 9:9 + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_err_code_sfifo_final_err ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.err_code.sfifo_final_err.de), + .d (hw2reg.err_code.sfifo_final_err.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (err_code_sfifo_final_err_qs) + ); + + // F[sfifo_gbencack_err]: 10:10 + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_err_code_sfifo_gbencack_err ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.err_code.sfifo_gbencack_err.de), + .d (hw2reg.err_code.sfifo_gbencack_err.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (err_code_sfifo_gbencack_err_qs) + ); + + // F[sfifo_grcstage_err]: 11:11 + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_err_code_sfifo_grcstage_err ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.err_code.sfifo_grcstage_err.de), + .d (hw2reg.err_code.sfifo_grcstage_err.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (err_code_sfifo_grcstage_err_qs) + ); + + // F[sfifo_ggenreq_err]: 12:12 + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_err_code_sfifo_ggenreq_err ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.err_code.sfifo_ggenreq_err.de), + .d (hw2reg.err_code.sfifo_ggenreq_err.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (err_code_sfifo_ggenreq_err_qs) + ); + + // F[sfifo_gadstage_err]: 13:13 + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_err_code_sfifo_gadstage_err ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.err_code.sfifo_gadstage_err.de), + .d (hw2reg.err_code.sfifo_gadstage_err.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (err_code_sfifo_gadstage_err_qs) + ); + + // F[sfifo_ggenbits_err]: 14:14 + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_err_code_sfifo_ggenbits_err ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.err_code.sfifo_ggenbits_err.de), + .d (hw2reg.err_code.sfifo_ggenbits_err.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (err_code_sfifo_ggenbits_err_qs) + ); + + // F[sfifo_blkenc_err]: 15:15 + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_err_code_sfifo_blkenc_err ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.err_code.sfifo_blkenc_err.de), + .d (hw2reg.err_code.sfifo_blkenc_err.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (err_code_sfifo_blkenc_err_qs) + ); + + // F[cmd_stage_sm_err]: 20:20 + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_err_code_cmd_stage_sm_err ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.err_code.cmd_stage_sm_err.de), + .d (hw2reg.err_code.cmd_stage_sm_err.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (err_code_cmd_stage_sm_err_qs) + ); + + // F[main_sm_err]: 21:21 + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_err_code_main_sm_err ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.err_code.main_sm_err.de), + .d (hw2reg.err_code.main_sm_err.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (err_code_main_sm_err_qs) + ); + + // F[drbg_gen_sm_err]: 22:22 + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_err_code_drbg_gen_sm_err ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.err_code.drbg_gen_sm_err.de), + .d (hw2reg.err_code.drbg_gen_sm_err.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (err_code_drbg_gen_sm_err_qs) + ); + + // F[drbg_updbe_sm_err]: 23:23 + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_err_code_drbg_updbe_sm_err ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.err_code.drbg_updbe_sm_err.de), + .d (hw2reg.err_code.drbg_updbe_sm_err.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (err_code_drbg_updbe_sm_err_qs) + ); + + // F[drbg_updob_sm_err]: 24:24 + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_err_code_drbg_updob_sm_err ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.err_code.drbg_updob_sm_err.de), + .d (hw2reg.err_code.drbg_updob_sm_err.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (err_code_drbg_updob_sm_err_qs) + ); + + // F[aes_cipher_sm_err]: 25:25 + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_err_code_aes_cipher_sm_err ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.err_code.aes_cipher_sm_err.de), + .d (hw2reg.err_code.aes_cipher_sm_err.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (err_code_aes_cipher_sm_err_qs) + ); + + // F[cmd_gen_cnt_err]: 26:26 + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_err_code_cmd_gen_cnt_err ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.err_code.cmd_gen_cnt_err.de), + .d (hw2reg.err_code.cmd_gen_cnt_err.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (err_code_cmd_gen_cnt_err_qs) + ); + + // F[fifo_write_err]: 28:28 + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_err_code_fifo_write_err ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.err_code.fifo_write_err.de), + .d (hw2reg.err_code.fifo_write_err.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (err_code_fifo_write_err_qs) + ); + + // F[fifo_read_err]: 29:29 + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_err_code_fifo_read_err ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.err_code.fifo_read_err.de), + .d (hw2reg.err_code.fifo_read_err.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (err_code_fifo_read_err_qs) + ); + + // F[fifo_state_err]: 30:30 + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_err_code_fifo_state_err ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.err_code.fifo_state_err.de), + .d (hw2reg.err_code.fifo_state_err.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (err_code_fifo_state_err_qs) + ); + + + // R[err_code_test]: V(False) + logic err_code_test_qe; + logic [0:0] err_code_test_flds_we; + caliptra_prim_flop #( + .Width(1), + .ResetValue(0) + ) u_err_code_test0_qe ( + .clk_i(clk_i), + .rst_ni(rst_ni), + .d_i(&err_code_test_flds_we), + .q_o(err_code_test_qe) + ); + // Create REGWEN-gated WE signal + logic err_code_test_gated_we; + assign err_code_test_gated_we = err_code_test_we & regwen_qs; + caliptra_prim_subreg #( + .DW (5), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRW), + .RESVAL (5'h0), + .Mubi (1'b0) + ) u_err_code_test ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (err_code_test_gated_we), + .wd (err_code_test_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (err_code_test_flds_we[0]), + .q (reg2hw.err_code_test.q), + .ds (), + + // to register interface (read) + .qs (err_code_test_qs) + ); + assign reg2hw.err_code_test.qe = err_code_test_qe; + + + // R[main_sm_state]: V(False) + caliptra_prim_subreg #( + .DW (8), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRO), + .RESVAL (8'h4e), + .Mubi (1'b0) + ) u_main_sm_state ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.main_sm_state.de), + .d (hw2reg.main_sm_state.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (main_sm_state_qs) + ); + + + + logic [23:0] addr_hit; + always_comb begin + addr_hit = '0; + addr_hit[ 0] = (reg_addr == CSRNG_INTR_STATE_OFFSET); + addr_hit[ 1] = (reg_addr == CSRNG_INTR_ENABLE_OFFSET); + addr_hit[ 2] = (reg_addr == CSRNG_INTR_TEST_OFFSET); + addr_hit[ 3] = (reg_addr == CSRNG_ALERT_TEST_OFFSET); + addr_hit[ 4] = (reg_addr == CSRNG_REGWEN_OFFSET); + addr_hit[ 5] = (reg_addr == CSRNG_CTRL_OFFSET); + addr_hit[ 6] = (reg_addr == CSRNG_CMD_REQ_OFFSET); + addr_hit[ 7] = (reg_addr == CSRNG_RESEED_INTERVAL_OFFSET); + addr_hit[ 8] = (reg_addr == CSRNG_RESEED_COUNTER_0_OFFSET); + addr_hit[ 9] = (reg_addr == CSRNG_RESEED_COUNTER_1_OFFSET); + addr_hit[10] = (reg_addr == CSRNG_RESEED_COUNTER_2_OFFSET); + addr_hit[11] = (reg_addr == CSRNG_SW_CMD_STS_OFFSET); + addr_hit[12] = (reg_addr == CSRNG_GENBITS_VLD_OFFSET); + addr_hit[13] = (reg_addr == CSRNG_GENBITS_OFFSET); + addr_hit[14] = (reg_addr == CSRNG_INT_STATE_READ_ENABLE_OFFSET); + addr_hit[15] = (reg_addr == CSRNG_INT_STATE_READ_ENABLE_REGWEN_OFFSET); + addr_hit[16] = (reg_addr == CSRNG_INT_STATE_NUM_OFFSET); + addr_hit[17] = (reg_addr == CSRNG_INT_STATE_VAL_OFFSET); + addr_hit[18] = (reg_addr == CSRNG_FIPS_FORCE_OFFSET); + addr_hit[19] = (reg_addr == CSRNG_HW_EXC_STS_OFFSET); + addr_hit[20] = (reg_addr == CSRNG_RECOV_ALERT_STS_OFFSET); + addr_hit[21] = (reg_addr == CSRNG_ERR_CODE_OFFSET); + addr_hit[22] = (reg_addr == CSRNG_ERR_CODE_TEST_OFFSET); + addr_hit[23] = (reg_addr == CSRNG_MAIN_SM_STATE_OFFSET); + end + + assign addrmiss = (reg_re || reg_we) ? ~|addr_hit : 1'b0; + + // Check sub-word write is permitted + always_comb begin + wr_err = (reg_we & + ((addr_hit[ 0] & (|(CSRNG_PERMIT[ 0] & ~reg_be))) | + (addr_hit[ 1] & (|(CSRNG_PERMIT[ 1] & ~reg_be))) | + (addr_hit[ 2] & (|(CSRNG_PERMIT[ 2] & ~reg_be))) | + (addr_hit[ 3] & (|(CSRNG_PERMIT[ 3] & ~reg_be))) | + (addr_hit[ 4] & (|(CSRNG_PERMIT[ 4] & ~reg_be))) | + (addr_hit[ 5] & (|(CSRNG_PERMIT[ 5] & ~reg_be))) | + (addr_hit[ 6] & (|(CSRNG_PERMIT[ 6] & ~reg_be))) | + (addr_hit[ 7] & (|(CSRNG_PERMIT[ 7] & ~reg_be))) | + (addr_hit[ 8] & (|(CSRNG_PERMIT[ 8] & ~reg_be))) | + (addr_hit[ 9] & (|(CSRNG_PERMIT[ 9] & ~reg_be))) | + (addr_hit[10] & (|(CSRNG_PERMIT[10] & ~reg_be))) | + (addr_hit[11] & (|(CSRNG_PERMIT[11] & ~reg_be))) | + (addr_hit[12] & (|(CSRNG_PERMIT[12] & ~reg_be))) | + (addr_hit[13] & (|(CSRNG_PERMIT[13] & ~reg_be))) | + (addr_hit[14] & (|(CSRNG_PERMIT[14] & ~reg_be))) | + (addr_hit[15] & (|(CSRNG_PERMIT[15] & ~reg_be))) | + (addr_hit[16] & (|(CSRNG_PERMIT[16] & ~reg_be))) | + (addr_hit[17] & (|(CSRNG_PERMIT[17] & ~reg_be))) | + (addr_hit[18] & (|(CSRNG_PERMIT[18] & ~reg_be))) | + (addr_hit[19] & (|(CSRNG_PERMIT[19] & ~reg_be))) | + (addr_hit[20] & (|(CSRNG_PERMIT[20] & ~reg_be))) | + (addr_hit[21] & (|(CSRNG_PERMIT[21] & ~reg_be))) | + (addr_hit[22] & (|(CSRNG_PERMIT[22] & ~reg_be))) | + (addr_hit[23] & (|(CSRNG_PERMIT[23] & ~reg_be))))); + end + + // Generate write-enables + assign intr_state_we = addr_hit[0] & reg_we & !reg_error; + + assign intr_state_cs_cmd_req_done_wd = reg_wdata[0]; + + assign intr_state_cs_entropy_req_wd = reg_wdata[1]; + + assign intr_state_cs_hw_inst_exc_wd = reg_wdata[2]; + + assign intr_state_cs_fatal_err_wd = reg_wdata[3]; + assign intr_enable_we = addr_hit[1] & reg_we & !reg_error; + + assign intr_enable_cs_cmd_req_done_wd = reg_wdata[0]; + + assign intr_enable_cs_entropy_req_wd = reg_wdata[1]; + + assign intr_enable_cs_hw_inst_exc_wd = reg_wdata[2]; + + assign intr_enable_cs_fatal_err_wd = reg_wdata[3]; + assign intr_test_we = addr_hit[2] & reg_we & !reg_error; + + assign intr_test_cs_cmd_req_done_wd = reg_wdata[0]; + + assign intr_test_cs_entropy_req_wd = reg_wdata[1]; + + assign intr_test_cs_hw_inst_exc_wd = reg_wdata[2]; + + assign intr_test_cs_fatal_err_wd = reg_wdata[3]; + assign alert_test_we = addr_hit[3] & reg_we & !reg_error; + + assign alert_test_recov_alert_wd = reg_wdata[0]; + + assign alert_test_fatal_alert_wd = reg_wdata[1]; + assign regwen_we = addr_hit[4] & reg_we & !reg_error; + + assign regwen_wd = reg_wdata[0]; + assign ctrl_we = addr_hit[5] & reg_we & !reg_error; + + assign ctrl_enable_wd = reg_wdata[3:0]; + + assign ctrl_sw_app_enable_wd = reg_wdata[7:4]; + + assign ctrl_read_int_state_wd = reg_wdata[11:8]; + + assign ctrl_fips_force_enable_wd = reg_wdata[15:12]; + assign cmd_req_we = addr_hit[6] & reg_we & !reg_error; + + assign cmd_req_wd = reg_wdata[31:0]; + assign reseed_interval_we = addr_hit[7] & reg_we & !reg_error; + + assign reseed_interval_wd = reg_wdata[31:0]; + assign reseed_counter_0_re = addr_hit[8] & reg_re & !reg_error; + assign reseed_counter_1_re = addr_hit[9] & reg_re & !reg_error; + assign reseed_counter_2_re = addr_hit[10] & reg_re & !reg_error; + assign genbits_vld_re = addr_hit[12] & reg_re & !reg_error; + assign genbits_re = addr_hit[13] & reg_re & !reg_error; + assign int_state_read_enable_we = addr_hit[14] & reg_we & !reg_error; + + assign int_state_read_enable_wd = reg_wdata[2:0]; + assign int_state_read_enable_regwen_we = addr_hit[15] & reg_we & !reg_error; + + assign int_state_read_enable_regwen_wd = reg_wdata[0]; + assign int_state_num_we = addr_hit[16] & reg_we & !reg_error; + + assign int_state_num_wd = reg_wdata[3:0]; + assign int_state_val_re = addr_hit[17] & reg_re & !reg_error; + assign fips_force_we = addr_hit[18] & reg_we & !reg_error; + + assign fips_force_wd = reg_wdata[2:0]; + assign hw_exc_sts_we = addr_hit[19] & reg_we & !reg_error; + + assign hw_exc_sts_wd = reg_wdata[15:0]; + assign recov_alert_sts_we = addr_hit[20] & reg_we & !reg_error; + + assign recov_alert_sts_enable_field_alert_wd = reg_wdata[0]; + + assign recov_alert_sts_sw_app_enable_field_alert_wd = reg_wdata[1]; + + assign recov_alert_sts_read_int_state_field_alert_wd = reg_wdata[2]; + + assign recov_alert_sts_fips_force_enable_field_alert_wd = reg_wdata[3]; + + assign recov_alert_sts_acmd_flag0_field_alert_wd = reg_wdata[4]; + + assign recov_alert_sts_cs_bus_cmp_alert_wd = reg_wdata[12]; + + assign recov_alert_sts_cmd_stage_invalid_acmd_alert_wd = reg_wdata[13]; + + assign recov_alert_sts_cmd_stage_invalid_cmd_seq_alert_wd = reg_wdata[14]; + + assign recov_alert_sts_cmd_stage_reseed_cnt_alert_wd = reg_wdata[15]; + assign err_code_test_we = addr_hit[22] & reg_we & !reg_error; + + assign err_code_test_wd = reg_wdata[4:0]; + + // Assign write-enables to checker logic vector. + always_comb begin + reg_we_check = '0; + reg_we_check[0] = intr_state_we; + reg_we_check[1] = intr_enable_we; + reg_we_check[2] = intr_test_we; + reg_we_check[3] = alert_test_we; + reg_we_check[4] = regwen_we; + reg_we_check[5] = ctrl_gated_we; + reg_we_check[6] = cmd_req_we; + reg_we_check[7] = reseed_interval_we; + reg_we_check[8] = 1'b0; + reg_we_check[9] = 1'b0; + reg_we_check[10] = 1'b0; + reg_we_check[11] = 1'b0; + reg_we_check[12] = 1'b0; + reg_we_check[13] = 1'b0; + reg_we_check[14] = int_state_read_enable_gated_we; + reg_we_check[15] = int_state_read_enable_regwen_we; + reg_we_check[16] = int_state_num_we; + reg_we_check[17] = 1'b0; + reg_we_check[18] = fips_force_gated_we; + reg_we_check[19] = hw_exc_sts_we; + reg_we_check[20] = recov_alert_sts_we; + reg_we_check[21] = 1'b0; + reg_we_check[22] = err_code_test_gated_we; + reg_we_check[23] = 1'b0; + end + + // Read data return + always_comb begin + reg_rdata_next = '0; + unique case (addr_hit) + 24'h000001: begin + reg_rdata_next[0] = intr_state_cs_cmd_req_done_qs; + reg_rdata_next[1] = intr_state_cs_entropy_req_qs; + reg_rdata_next[2] = intr_state_cs_hw_inst_exc_qs; + reg_rdata_next[3] = intr_state_cs_fatal_err_qs; + end + + 24'h000002: begin + reg_rdata_next[0] = intr_enable_cs_cmd_req_done_qs; + reg_rdata_next[1] = intr_enable_cs_entropy_req_qs; + reg_rdata_next[2] = intr_enable_cs_hw_inst_exc_qs; + reg_rdata_next[3] = intr_enable_cs_fatal_err_qs; + end + + 24'h000004: begin + reg_rdata_next[0] = '0; + reg_rdata_next[1] = '0; + reg_rdata_next[2] = '0; + reg_rdata_next[3] = '0; + end + + 24'h000008: begin + reg_rdata_next[0] = '0; + reg_rdata_next[1] = '0; + end + + 24'h000010: begin + reg_rdata_next[0] = regwen_qs; + end + + 24'h000020: begin + reg_rdata_next[3:0] = ctrl_enable_qs; + reg_rdata_next[7:4] = ctrl_sw_app_enable_qs; + reg_rdata_next[11:8] = ctrl_read_int_state_qs; + reg_rdata_next[15:12] = ctrl_fips_force_enable_qs; + end + + 24'h000040: begin + reg_rdata_next[31:0] = '0; + end + + 24'h000080: begin + reg_rdata_next[31:0] = reseed_interval_qs; + end + + 24'h000100: begin + reg_rdata_next[31:0] = reseed_counter_0_qs; + end + + 24'h000200: begin + reg_rdata_next[31:0] = reseed_counter_1_qs; + end + + 24'h000400: begin + reg_rdata_next[31:0] = reseed_counter_2_qs; + end + + 24'h000800: begin + reg_rdata_next[1] = sw_cmd_sts_cmd_rdy_qs; + reg_rdata_next[2] = sw_cmd_sts_cmd_ack_qs; + reg_rdata_next[5:3] = sw_cmd_sts_cmd_sts_qs; + end + + 24'h001000: begin + reg_rdata_next[0] = genbits_vld_genbits_vld_qs; + reg_rdata_next[1] = genbits_vld_genbits_fips_qs; + end + + 24'h002000: begin + reg_rdata_next[31:0] = genbits_qs; + end + + 24'h004000: begin + reg_rdata_next[2:0] = int_state_read_enable_qs; + end + + 24'h008000: begin + reg_rdata_next[0] = int_state_read_enable_regwen_qs; + end + + 24'h010000: begin + reg_rdata_next[3:0] = int_state_num_qs; + end + + 24'h020000: begin + reg_rdata_next[31:0] = int_state_val_qs; + end + + 24'h040000: begin + reg_rdata_next[2:0] = fips_force_qs; + end + + 24'h080000: begin + reg_rdata_next[15:0] = hw_exc_sts_qs; + end + + 24'h100000: begin + reg_rdata_next[0] = recov_alert_sts_enable_field_alert_qs; + reg_rdata_next[1] = recov_alert_sts_sw_app_enable_field_alert_qs; + reg_rdata_next[2] = recov_alert_sts_read_int_state_field_alert_qs; + reg_rdata_next[3] = recov_alert_sts_fips_force_enable_field_alert_qs; + reg_rdata_next[4] = recov_alert_sts_acmd_flag0_field_alert_qs; + reg_rdata_next[12] = recov_alert_sts_cs_bus_cmp_alert_qs; + reg_rdata_next[13] = recov_alert_sts_cmd_stage_invalid_acmd_alert_qs; + reg_rdata_next[14] = recov_alert_sts_cmd_stage_invalid_cmd_seq_alert_qs; + reg_rdata_next[15] = recov_alert_sts_cmd_stage_reseed_cnt_alert_qs; + end + + 24'h200000: begin + reg_rdata_next[0] = err_code_sfifo_cmd_err_qs; + reg_rdata_next[1] = err_code_sfifo_genbits_err_qs; + reg_rdata_next[2] = err_code_sfifo_cmdreq_err_qs; + reg_rdata_next[3] = err_code_sfifo_rcstage_err_qs; + reg_rdata_next[4] = err_code_sfifo_keyvrc_err_qs; + reg_rdata_next[5] = err_code_sfifo_updreq_err_qs; + reg_rdata_next[6] = err_code_sfifo_bencreq_err_qs; + reg_rdata_next[7] = err_code_sfifo_bencack_err_qs; + reg_rdata_next[8] = err_code_sfifo_pdata_err_qs; + reg_rdata_next[9] = err_code_sfifo_final_err_qs; + reg_rdata_next[10] = err_code_sfifo_gbencack_err_qs; + reg_rdata_next[11] = err_code_sfifo_grcstage_err_qs; + reg_rdata_next[12] = err_code_sfifo_ggenreq_err_qs; + reg_rdata_next[13] = err_code_sfifo_gadstage_err_qs; + reg_rdata_next[14] = err_code_sfifo_ggenbits_err_qs; + reg_rdata_next[15] = err_code_sfifo_blkenc_err_qs; + reg_rdata_next[20] = err_code_cmd_stage_sm_err_qs; + reg_rdata_next[21] = err_code_main_sm_err_qs; + reg_rdata_next[22] = err_code_drbg_gen_sm_err_qs; + reg_rdata_next[23] = err_code_drbg_updbe_sm_err_qs; + reg_rdata_next[24] = err_code_drbg_updob_sm_err_qs; + reg_rdata_next[25] = err_code_aes_cipher_sm_err_qs; + reg_rdata_next[26] = err_code_cmd_gen_cnt_err_qs; + reg_rdata_next[28] = err_code_fifo_write_err_qs; + reg_rdata_next[29] = err_code_fifo_read_err_qs; + reg_rdata_next[30] = err_code_fifo_state_err_qs; + end + + 24'h400000: begin + reg_rdata_next[4:0] = err_code_test_qs; + end + + 24'h800000: begin + reg_rdata_next[7:0] = main_sm_state_qs; + end + endcase + end + + // shadow busy + logic shadow_busy; + assign shadow_busy = 1'b0; + + // register busy + assign reg_busy = shadow_busy; + + // Unused signal tieoff + + // wdata / byte enable are not always fully used + // add a blanket unused statement to handle lint waivers + logic unused_wdata; + logic unused_be; + assign unused_wdata = ^reg_wdata; + assign unused_be = ^reg_be; + + // Assertions for Register Interface + `CALIPTRA_ASSERT_PULSE(wePulse, reg_we, clk_i, !rst_ni) + `CALIPTRA_ASSERT_PULSE(rePulse, reg_re, clk_i, !rst_ni) + + `CALIPTRA_ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> hreadyout_o, clk_i, !rst_ni) + + `CALIPTRA_ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit), clk_i, !rst_ni) + + // this is formulated as an assumption such that the FPV testbenches do disprove this + // property by mistake + //`CALIPTRA_ASSUME(reqParity, tl_reg_h2d.a_valid |-> tl_reg_h2d.a_user.chk_en == tlul_pkg::CheckDis) + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/csrng_state_db.sv b/designs/Caliptra/src/caliptra-rtl/csrng_state_db.sv new file mode 100644 index 0000000..b5e5273 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/csrng_state_db.sv @@ -0,0 +1,229 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Description: csrng state data base module +// +// This is the container for accessing the current +// working state for a given drbg instance. + +`include "caliptra_prim_assert.sv" + +module csrng_state_db import csrng_pkg::*; #( + parameter logic [31:0] NApps = 4, + parameter logic [31:0] StateId = 4, + parameter logic [31:0] BlkLen = 128, + parameter logic [31:0] KeyLen = 256, + parameter logic [31:0] CtrLen = 32, + parameter logic [31:0] Cmd = 3 +) ( + input logic clk_i, + input logic rst_ni, + + // read interface + input logic state_db_enable_i, + input logic [StateId-1:0] state_db_rd_inst_id_i, + output logic [KeyLen-1:0] state_db_rd_key_o, + output logic [BlkLen-1:0] state_db_rd_v_o, + output logic [CtrLen-1:0] state_db_rd_res_ctr_o, + output logic state_db_rd_inst_st_o, + output logic state_db_rd_fips_o, + // write interface + input logic state_db_wr_req_i, + output logic state_db_wr_req_rdy_o, + input logic [StateId-1:0] state_db_wr_inst_id_i, + input logic state_db_wr_fips_i, + input logic [Cmd-1:0] state_db_wr_ccmd_i, + input logic [KeyLen-1:0] state_db_wr_key_i, + input logic [BlkLen-1:0] state_db_wr_v_i, + input logic [CtrLen-1:0] state_db_wr_res_ctr_i, + input csrng_cmd_sts_e state_db_wr_sts_i, + // status interface + input logic state_db_is_dump_en_i, + input logic state_db_reg_rd_sel_i, + input logic state_db_reg_rd_id_pulse_i, + input logic [StateId-1:0] state_db_reg_rd_id_i, + output logic [31:0] state_db_reg_rd_val_o, + output logic state_db_sts_ack_o, + output csrng_cmd_sts_e state_db_sts_sts_o, + output logic [StateId-1:0] state_db_sts_id_o, + input logic [NApps-1:0] int_state_read_enable_i, + + // The reseed counters are always readable via register interface. + output logic [NApps-1:0][31:0] reseed_counter_o +); + + localparam logic[31:0] InternalStateWidth = 2+KeyLen+BlkLen+CtrLen; + localparam logic[31:0] RegInternalStateWidth = 30+InternalStateWidth; + localparam logic[31:0] RegW = 32; + localparam logic[31:0] StateWidth = 1+1+KeyLen+BlkLen+CtrLen+StateId+CSRNG_CMD_STS_WIDTH; + + logic [StateId-1:0] state_db_id; + logic [KeyLen-1:0] state_db_key; + logic [BlkLen-1:0] state_db_v; + logic [CtrLen-1:0] state_db_rc; + logic state_db_fips; + logic state_db_inst_st; + csrng_cmd_sts_e state_db_sts; + logic state_db_write; + logic instance_status; + logic [NApps-1:0] int_st_out_sel; + logic [NApps-1:0] int_st_dump_sel; + logic [InternalStateWidth-1:0] internal_states_out[NApps]; + logic [InternalStateWidth-1:0] internal_states_dump[NApps]; + logic [InternalStateWidth-1:0] internal_state_pl; + logic [InternalStateWidth-1:0] internal_state_pl_dump; + logic [RegInternalStateWidth-1:0] internal_state_diag; + logic reg_rd_ptr_inc; + + // flops + logic state_db_sts_ack_q, state_db_sts_ack_d; + csrng_cmd_sts_e state_db_sts_sts_q, state_db_sts_sts_d; + logic [StateId-1:0] state_db_sts_id_q, state_db_sts_id_d; + logic [StateId-1:0] reg_rd_ptr_q, reg_rd_ptr_d; + logic [StateId-1:0] int_st_dump_id_q, int_st_dump_id_d; + + always_ff @(posedge clk_i or negedge rst_ni) + if (!rst_ni) begin + state_db_sts_ack_q <= '0; + state_db_sts_sts_q <= CMD_STS_SUCCESS; + state_db_sts_id_q <= '0; + reg_rd_ptr_q <= '0; + int_st_dump_id_q <= '0; + end else begin + state_db_sts_ack_q <= state_db_sts_ack_d; + state_db_sts_sts_q <= state_db_sts_sts_d; + state_db_sts_id_q <= state_db_sts_id_d; + reg_rd_ptr_q <= reg_rd_ptr_d; + int_st_dump_id_q <= int_st_dump_id_d; + end + + // flops - no reset + logic [InternalStateWidth-1:0] internal_states_q[NApps], internal_states_d[NApps]; + + // no reset on state + always_ff @(posedge clk_i) + begin + internal_states_q <= internal_states_d; + end + + + //-------------------------------------------- + // internal state read logic + //-------------------------------------------- + for (genvar rd = 0; rd < NApps; rd = rd+1) begin : gen_state_rd + assign int_st_out_sel[rd] = (state_db_rd_inst_id_i == rd); + assign int_st_dump_sel[rd] = (int_st_dump_id_q == rd); + assign internal_states_out[rd] = int_st_out_sel[rd] ? internal_states_q[rd] : '0; + assign internal_states_dump[rd] = + int_st_dump_sel[rd] && int_state_read_enable_i[rd] ? internal_states_q[rd] : '0; + end + + // since only one of the internal states is active at a time, a + // logical "or" is made of all of the buses into one + always_comb begin + internal_state_pl = '0; + internal_state_pl_dump = '0; + for (int i = 0; i < NApps; i = i+1) begin + internal_state_pl |= internal_states_out[i]; + internal_state_pl_dump |= internal_states_dump[i]; + end + end + + assign {state_db_rd_fips_o,state_db_rd_inst_st_o, + state_db_rd_key_o,state_db_rd_v_o, + state_db_rd_res_ctr_o} = internal_state_pl; + + + assign internal_state_diag = {30'b0,internal_state_pl_dump}; + + + // Register access of internal state + assign state_db_reg_rd_val_o = + (reg_rd_ptr_q == 4'h0) ? internal_state_diag[RegW-1:0] : + (reg_rd_ptr_q == 4'h1) ? internal_state_diag[2*RegW-1:RegW] : + (reg_rd_ptr_q == 4'h2) ? internal_state_diag[3*RegW-1:2*RegW] : + (reg_rd_ptr_q == 4'h3) ? internal_state_diag[4*RegW-1:3*RegW] : + (reg_rd_ptr_q == 4'h4) ? internal_state_diag[5*RegW-1:4*RegW] : + (reg_rd_ptr_q == 4'h5) ? internal_state_diag[6*RegW-1:5*RegW] : + (reg_rd_ptr_q == 4'h6) ? internal_state_diag[7*RegW-1:6*RegW] : + (reg_rd_ptr_q == 4'h7) ? internal_state_diag[8*RegW-1:7*RegW] : + (reg_rd_ptr_q == 4'h8) ? internal_state_diag[9*RegW-1:8*RegW] : + (reg_rd_ptr_q == 4'h9) ? internal_state_diag[10*RegW-1:9*RegW] : + (reg_rd_ptr_q == 4'ha) ? internal_state_diag[11*RegW-1:10*RegW] : + (reg_rd_ptr_q == 4'hb) ? internal_state_diag[12*RegW-1:11*RegW] : + (reg_rd_ptr_q == 4'hc) ? internal_state_diag[13*RegW-1:12*RegW] : + (reg_rd_ptr_q == 4'hd) ? internal_state_diag[14*RegW-1:13*RegW] : + '0; + + // selects 32b fields from the internal state to be read out for diagnostics + assign reg_rd_ptr_inc = state_db_reg_rd_sel_i; + + assign reg_rd_ptr_d = + (!state_db_enable_i) ? 4'hf : + (!state_db_is_dump_en_i) ? 4'hf : + (reg_rd_ptr_q == 4'he) ? '0 : + state_db_reg_rd_id_pulse_i ? '0 : + reg_rd_ptr_inc ? (reg_rd_ptr_q+1) : + reg_rd_ptr_q; + + + assign int_st_dump_id_d = + (!state_db_enable_i) ? '0 : + state_db_reg_rd_id_pulse_i ? state_db_reg_rd_id_i : + int_st_dump_id_q; + + // The reseed counters are always readable via register interface. + for (genvar i = 0; i < NApps; i++) begin : gen_reseed_counter + assign reseed_counter_o[i] = internal_states_q[i][31:0]; + end + + //-------------------------------------------- + // write state logic + //-------------------------------------------- + + for (genvar wr = 0; wr < NApps; wr = wr+1) begin : gen_state_wr + + assign internal_states_d[wr] = !state_db_enable_i ? '0 : // better timing + (state_db_write && (state_db_id == wr)) ? + {state_db_fips,state_db_inst_st,state_db_key, + state_db_v,state_db_rc} : internal_states_q[wr]; + end : gen_state_wr + + + assign {state_db_fips,state_db_inst_st, + state_db_key, + state_db_v,state_db_rc, + state_db_id,state_db_sts} = {StateWidth{state_db_enable_i}} & + {state_db_wr_fips_i,instance_status, + state_db_wr_key_i, + state_db_wr_v_i,state_db_wr_res_ctr_i, + state_db_wr_inst_id_i,state_db_wr_sts_i}; + + assign instance_status = + (state_db_wr_ccmd_i == INS) || + (state_db_wr_ccmd_i == RES) || + (state_db_wr_ccmd_i == GENU) || + (state_db_wr_ccmd_i == UPD); + + + assign state_db_write = state_db_enable_i && state_db_wr_req_i; + + assign state_db_sts_ack_d = + state_db_write; + + assign state_db_sts_sts_d = + state_db_sts; + + assign state_db_sts_id_d = + state_db_id; + + assign state_db_sts_ack_o = state_db_sts_ack_q; + assign state_db_sts_sts_o = state_db_sts_sts_q; + assign state_db_sts_id_o = state_db_sts_id_q; + assign state_db_wr_req_rdy_o = 1'b1; + + // Assertions + `CALIPTRA_ASSERT_KNOWN(IntStOutSelOneHot_A, $onehot(int_st_out_sel)) + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/dasm.svi b/designs/Caliptra/src/caliptra-rtl/dasm.svi new file mode 100755 index 0000000..f5e0d77 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/dasm.svi @@ -0,0 +1,395 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2019 Western Digital Corporation or its affiliates. +// +// 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. +// + +// Run time disassembler functions +// supports RISCV extentions I, C, M, A +`ifndef RV_NUM_THREADS +`define RV_NUM_THREADS 1 +`endif + +bit[31:0] [31:0] gpr[`RV_NUM_THREADS]; + +// main DASM function +function static string dasm(input[31:0] opcode, input[31:0] pc, input[4:0] regn, input[31:0] regv, input tid=0); + dasm = (opcode[1:0] == 2'b11) ? dasm32(opcode, pc, tid) : dasm16(opcode, pc, tid); + if(regn) gpr[tid][regn] = regv; +endfunction + + +///////////////// 16 bits instructions /////////////////////// + +function static string dasm16( input[31:0] opcode, input[31:0] pc, input tid=0); + case(opcode[1:0]) + 0: return dasm16_0(opcode, tid); + 1: return dasm16_1(opcode, pc); + 2: return dasm16_2(opcode); + endcase + return $sformatf(".short 0x%h", opcode[15:0]); +endfunction + +function static string dasm16_0( input[31:0] opcode, tid); + case(opcode[15:13]) + 3'b000: return dasm16_ciw(opcode); + 3'b001: return {"c.fld ", dasm16_cl(opcode, tid)}; + 3'b010: return {"c.lw ", dasm16_cl(opcode, tid)}; + 3'b011: return {"c.flw ", dasm16_cl(opcode, tid)}; + 3'b101: return {"c.fsd ", dasm16_cl(opcode, tid)}; + 3'b110: return {"c.sw ", dasm16_cl(opcode, tid)}; + 3'b111: return {"c.fsw ", dasm16_cl(opcode, tid)}; + endcase + return $sformatf(".short 0x%h", opcode[15:0]); +endfunction + +function static string dasm16_ciw( input[31:0] opcode); +int imm; + imm=0; + if(opcode[15:0] == 0) return ".short 0"; + {imm[5:4],imm[9:6],imm[2],imm[3]} = opcode[12:5]; + return $sformatf("c.addi4spn %s,0x%0h", abi_reg[opcode[4:2]+8], imm); +endfunction + +function static string dasm16_cl( input[31:0] opcode, input tid=0); +int imm; + imm=0; + imm[5:3] = opcode[12:10]; + imm[7:6] = opcode[6:5]; + + return $sformatf(" %s,%0d(%s) [%h]", abi_reg[opcode[4:2]+8], imm, abi_reg[opcode[9:7]+8], gpr[tid][opcode[9:7]+8]+imm); +endfunction + +function static string dasm16_1( input[31:0] opcode, input[31:0] pc); + case(opcode[15:13]) + 3'b000: return opcode[11:7]==0 ? "c.nop" : {"c.addi ",dasm16_ci(opcode)}; + 3'b001: return {"c.jal ", dasm16_cj(opcode, pc)}; + 3'b010: return {"c.li ", dasm16_ci(opcode)}; + 3'b011: return dasm16_1_3(opcode); + 3'b100: return dasm16_cr(opcode); + 3'b101: return {"c.j ", dasm16_cj(opcode, pc)}; + 3'b110: return {"c.beqz ", dasm16_cb(opcode, pc)}; + 3'b111: return {"c.bnez ", dasm16_cb(opcode, pc)}; + endcase +endfunction + +function static string dasm16_ci( input[31:0] opcode); +int imm; + imm=0; + imm[4:0] = opcode[6:2]; + if(opcode[12]) imm [31:5] = '1; + return $sformatf("%s,%0d", abi_reg[opcode[11:7]], imm); +endfunction + +function static string dasm16_cj( input[31:0] opcode, input[31:0] pc); +bit[31:0] imm; + imm=0; + {imm[11],imm[4],imm[9:8],imm[10],imm[6], imm[7],imm[3:1], imm[5]} = opcode[12:2]; + if(opcode[12]) imm [31:12] = '1; + return $sformatf("0x%0h", imm+pc); +endfunction + +function static string dasm16_cb( input[31:0] opcode, input[31:0] pc); +bit[31:0] imm; + imm=0; + {imm[8],imm[4:3]} = opcode[12:10]; + {imm[7:6],imm[2:1], imm[5]} = opcode[6:2]; + if(opcode[12]) imm [31:9] = '1; + return $sformatf("%s,0x%0h",abi_reg[opcode[9:7]+8], imm+pc); +endfunction + +function static string dasm16_cr( input[31:0] opcode); +bit[31:0] imm; + + imm = 0; + imm[4:0] = opcode[6:2]; + if(opcode[5]) imm [31:5] = '1; + case(opcode[11:10]) + 0: return $sformatf("c.srli %s,%0d", abi_reg[opcode[9:7]+8], imm[5:0]); + 1: return $sformatf("c.srai %s,%0d", abi_reg[opcode[9:7]+8], imm[5:0]); + 2: return $sformatf("c.andi %s,0x%0h", abi_reg[opcode[9:7]+8], imm); + endcase + + case(opcode[6:5]) + 0: return $sformatf("c.sub %s,%s", abi_reg[opcode[9:7]+8], abi_reg[opcode[4:2]+8]); + 1: return $sformatf("c.xor %s,%s", abi_reg[opcode[9:7]+8], abi_reg[opcode[4:2]+8]); + 2: return $sformatf("c.or %s,%s", abi_reg[opcode[9:7]+8], abi_reg[opcode[4:2]+8]); + 3: return $sformatf("c.and %s,%s", abi_reg[opcode[9:7]+8], abi_reg[opcode[4:2]+8]); + endcase +endfunction + +function static string dasm16_1_3( input[31:0] opcode); +int imm; + + imm=0; + if(opcode[11:7] == 2) begin + {imm[4], imm[6],imm[8:7], imm[5]} = opcode[6:2]; + if(opcode[12]) imm [31:9] = '1; + return $sformatf("c.addi16sp %0d", imm); + end + else begin + imm[16:12] = opcode[6:2]; + if(opcode[12]) imm [31:17] = '1; + return $sformatf("c.lui %s,0x%0h", abi_reg[opcode[11:7]], imm); + + end +endfunction + +function static string dasm16_2( input[31:0] opcode, input tid=0); + case(opcode[15:13]) + 3'b000: return {"c.slli ", dasm16_ci(opcode)}; + 3'b001: return {"c.fldsp ", dasm16_cls(opcode,1,tid)}; + 3'b010: return {"c.lwsp ", dasm16_cls(opcode,0,tid)}; + 3'b011: return {"c.flwsp ", dasm16_cls(opcode,0,tid)}; + 3'b101: return {"c.fsdsp ", dasm16_css(opcode,1,tid)}; + 3'b110: return {"c.swsp ", dasm16_css(opcode,0,tid)}; + 3'b111: return {"c.fswsp ", dasm16_css(opcode,0,tid)}; + endcase + if(opcode[12]) begin + if(opcode[12:2] == 0) return "c.ebreak"; + else if(opcode[6:2] == 0) return $sformatf("c.jalr %s", abi_reg[opcode[11:7]]); + else return $sformatf("c.add %s,%s", abi_reg[opcode[11:7]], abi_reg[opcode[6:2]]); + end + else begin + if(opcode[6:2] == 0) return $sformatf("c.jr %s", abi_reg[opcode[11:7]]); + else return $sformatf("c.mv %s,%s", abi_reg[opcode[11:7]], abi_reg[opcode[6:2]]); + end +endfunction + + +function static string dasm16_cls( input[31:0] opcode, input sh1=0, tid=0); +bit[31:0] imm; + imm=0; + if(sh1) {imm[4:3],imm[8:6]} = opcode[6:2]; + else {imm[4:2],imm[7:6]} = opcode[6:2]; + imm[5] = opcode[12]; + return $sformatf("%s,0x%0h [%h]", abi_reg[opcode[11:7]], imm, gpr[tid][2]+imm); +endfunction + +function static string dasm16_css( input[31:0] opcode, input sh1=0, tid=0); +bit[31:0] imm; + imm=0; + if(sh1) {imm[5:3],imm[8:6]} = opcode[12:7]; + else {imm[5:2],imm[7:6]} = opcode[12:7]; + return $sformatf("%s,0x%0h [%h]", abi_reg[opcode[6:2]], imm, gpr[tid][2]+imm); +endfunction + +///////////////// 32 bit instructions /////////////////////// + +function static string dasm32( input[31:0] opcode, input[31:0] pc, input tid=0); + case(opcode[6:0]) + 7'b0110111: return {"lui ", dasm32_u(opcode)}; + 7'b0010111: return {"auipc ", dasm32_u(opcode)}; + 7'b1101111: return {"jal ", dasm32_j(opcode,pc)}; + 7'b1100111: return {"jalr ", dasm32_jr(opcode,pc)}; + 7'b1100011: return dasm32_b(opcode,pc); + 7'b0000011: return dasm32_l(opcode,tid); + 7'b0100011: return dasm32_s(opcode,tid); + 7'b0010011: return dasm32_ai(opcode); + 7'b0110011: return dasm32_ar(opcode); + 7'b0001111: return {"fence", dasm32_fence(opcode)}; + 7'b1110011: return dasm32_e(opcode); + 7'b0101111: return dasm32_a(opcode,tid); + + endcase + return $sformatf(".long 0x%h", opcode); +endfunction + +function static string dasm32_u( input[31:0] opcode); +bit[31:0] imm; + imm=0; + imm[31:12] = opcode[31:12]; + return $sformatf("%s,0x%0h", abi_reg[opcode[11:7]], imm); +endfunction + +function static string dasm32_j( input[31:0] opcode, input[31:0] pc); +int imm; + imm=0; + {imm[20], imm[10:1], imm[11], imm[19:12]} = opcode[31:12]; + if(opcode[31]) imm[31:20] = '1; + return $sformatf("%s,0x%0h",abi_reg[opcode[11:7]], imm+pc); +endfunction + +function static string dasm32_jr( input[31:0] opcode, input[31:0] pc); +int imm; + imm=0; + imm[11:1] = opcode[31:19]; + if(opcode[31]) imm[31:12] = '1; + return $sformatf("%s,%s,0x%0h",abi_reg[opcode[11:7]], abi_reg[opcode[19:15]], imm+pc); +endfunction + +function static string dasm32_b( input[31:0] opcode, input[31:0] pc); +int imm; +string mn; + imm=0; + {imm[12],imm[10:5]} = opcode[31:25]; + {imm[4:1],imm[11]} = opcode[11:7]; + if(opcode[31]) imm[31:12] = '1; + case(opcode[14:12]) + 0: mn = "beq "; + 1: mn = "bne "; + 2,3 : return $sformatf(".long 0x%h", opcode); + 4: mn = "blt "; + 5: mn = "bge "; + 6: mn = "bltu "; + 7: mn = "bgeu "; + endcase + return $sformatf("%s%s,%s,0x%0h", mn, abi_reg[opcode[19:15]], abi_reg[opcode[24:20]], imm+pc); +endfunction + +function static string dasm32_l( input[31:0] opcode, input tid=0); +int imm; +string mn; + imm=0; + imm[11:0] = opcode[31:20]; + if(opcode[31]) imm[31:12] = '1; + case(opcode[14:12]) + 0: mn = "lb "; + 1: mn = "lh "; + 2: mn = "lw "; + 4: mn = "lbu "; + 5: mn = "lhu "; + default : return $sformatf(".long 0x%h", opcode); + endcase + return $sformatf("%s%s,%0d(%s) [%h]", mn, abi_reg[opcode[11:7]], imm, abi_reg[opcode[19:15]], imm+gpr[tid][opcode[19:15]]); +endfunction + +function static string dasm32_s( input[31:0] opcode, input tid=0); +int imm; +string mn; + imm=0; + imm[11:5] = opcode[31:25]; + imm[4:0] = opcode[11:7]; + if(opcode[31]) imm[31:12] = '1; + case(opcode[14:12]) + 0: mn = "sb "; + 1: mn = "sh "; + 2: mn = "sw "; + default : return $sformatf(".long 0x%h", opcode); + endcase + return $sformatf("%s%s,%0d(%s) [%h]", mn, abi_reg[opcode[24:20]], imm, abi_reg[opcode[19:15]], imm+gpr[tid][opcode[19:15]]); +endfunction + +function static string dasm32_ai( input[31:0] opcode); +int imm; +string mn; + imm=0; + imm[11:0] = opcode[31:20]; + if(opcode[31]) imm[31:12] = '1; + case(opcode[14:12]) + 0: mn = "addi "; + 2: mn = "slti "; + 3: mn = "sltiu "; + 4: mn = "xori "; + 6: mn = "ori "; + 7: mn = "andi "; + default: return dasm32_si(opcode); +endcase + +return $sformatf("%s%s,%s,%0d", mn, abi_reg[opcode[11:7]], abi_reg[opcode[19:15]], imm); +endfunction + +function static string dasm32_si( input[31:0] opcode); +int imm; +string mn; + imm = opcode[24:20]; + case(opcode[14:12]) + 1: mn = "slli"; + 5: mn = opcode[30] ? "srli": "srai"; + endcase + + return $sformatf("%s %s,%s,%0d", mn, abi_reg[opcode[11:7]], abi_reg[opcode[19:15]], imm); +endfunction + + + +function static string dasm32_ar( input[31:0] opcode); +string mn; + if(opcode[25]) + case(opcode[14:12]) + 0: mn = "mul "; + 1: mn = "mulh "; + 2: mn = "mulhsu "; + 3: mn = "mulhu "; + 4: mn = "div "; + 5: mn = "divu "; + 6: mn = "rem "; + 7: mn = "remu "; + endcase + else + case(opcode[14:12]) + 0: mn = opcode[30]? "sub ":"add "; + 1: mn = "sll "; + 2: mn = "slt "; + 3: mn = "sltu "; + 4: mn = "xor "; + 5: mn = opcode[30]? "sra ":"srl "; + 6: mn = "or "; + 7: mn = "and "; + endcase + return $sformatf("%s%s,%s,%s", mn, abi_reg[opcode[11:7]], abi_reg[opcode[19:15]], abi_reg[opcode[24:20]]); +endfunction + +function static string dasm32_fence( input[31:0] opcode); + return opcode[12] ? ".i" : ""; +endfunction + +function static string dasm32_e(input[31:0] opcode); + if(opcode[31:7] == 0) return "ecall"; + else if({opcode[31:21],opcode [19:7]} == 0) return "ebreak"; + else + case(opcode[14:12]) + 1: return {"csrrw ", dasm32_csr(opcode)}; + 2: return {"csrrs ", dasm32_csr(opcode)}; + 3: return {"csrrc ", dasm32_csr(opcode)}; + 5: return {"csrrwi ", dasm32_csr(opcode, 1)}; + 6: return {"csrrsi ", dasm32_csr(opcode, 1)}; + 7: return {"csrrci ", dasm32_csr(opcode, 1)}; + endcase + +endfunction + + +function static string dasm32_csr(input[31:0] opcode, input im=0); +bit[11:0] csr; + csr = opcode[31:20]; + if(im) begin + return $sformatf("%s,csr_%0h,0x%h", abi_reg[opcode[11:7]], csr, opcode[19:15]); + end + else begin + return $sformatf("%s,csr_%0h,%s", abi_reg[opcode[11:7]], csr, abi_reg[opcode[19:15]]); + end + +endfunction + +//atomics +function static string dasm32_a(input[31:0] opcode, input tid=0); + case(opcode[31:27]) + 'b00010: return $sformatf("lr.w %s,(%s) [%h]", abi_reg[opcode[11:7]], abi_reg[opcode[19:15]], gpr[tid][opcode[19:15]]); + 'b00011: return $sformatf("sc.w %s,%s,(%s) [%h]", abi_reg[opcode[11:7]], abi_reg[opcode[24:20]], abi_reg[opcode[19:15]], gpr[tid][opcode[19:15]]); + 'b00001: return {"amoswap.w", dasm32_amo(opcode, tid)}; + 'b00000: return {"amoadd.w", dasm32_amo(opcode, tid)}; + 'b00100: return {"amoxor.w", dasm32_amo(opcode, tid)}; + 'b01100: return {"amoand.w", dasm32_amo(opcode, tid)}; + 'b01000: return {"amoor.w", dasm32_amo(opcode, tid)}; + 'b10000: return {"amomin.w", dasm32_amo(opcode, tid)}; + 'b10100: return {"amomax.w", dasm32_amo(opcode, tid)}; + 'b11000: return {"amominu.w", dasm32_amo(opcode, tid)}; + 'b11100: return {"amomaxu.w", dasm32_amo(opcode, tid)}; + endcase + return $sformatf(".long 0x%h", opcode); +endfunction + +function static string dasm32_amo( input[31:0] opcode, input tid=0); + return $sformatf(" %s,%s,(%s) [%h]", abi_reg[opcode[11:7]], abi_reg[opcode[24:20]], abi_reg[opcode[19:15]], gpr[tid][opcode[19:15]]); +endfunction diff --git a/designs/Caliptra/src/caliptra-rtl/dma_testcase_generator.sv b/designs/Caliptra/src/caliptra-rtl/dma_testcase_generator.sv new file mode 100644 index 0000000..ebe048f --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/dma_testcase_generator.sv @@ -0,0 +1,205 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +// + +module dma_testcase_generator ( + input logic preload_dccm_done, + output logic dma_gen_done, + output logic [99:0] [11:0] dma_gen_block_size +); + import caliptra_top_tb_pkg::*; // provides dma_transfer_randomizer, etc... + + localparam MAX_SIZE_TO_CHECK = 16384; // dwords + + `ifdef VERILATOR + assign dma_gen_done = 1'b0; + assign dma_gen_block_size = '0; + `else + + // Dynamic array to store test cases + dma_transfer_randomizer#(MAX_SIZE_TO_CHECK) dma_xfers[]; + + //---------------------------------------------------------------- + // main + // + // The main test functionality. + //---------------------------------------------------------------- + + initial begin : main + // 0: no prints + // 1: reduced prints + // 2: all prints + int verbosity; + if (!$value$plusargs("CPTRA_VERBOSITY=%d", verbosity)) begin + verbosity = 1; + end + if ($test$plusargs("CPTRA_RAND_TEST_DMA")) begin + int num_iterations; + int end_addr = `RV_DCCM_EADR; // Base address for DCCM + int tc_start_addr; + int dccm_addr; + int total_testcase_bytes_to_check = 32'h18000; // Initialize with the value indicating how many DCCM bytes can be used for TC stuffing + // Compiled rand_test_dma is about 0x1b170 bytes + // 0x1b170 + 0x18000 = 0x33170, which leaves a fair margin until the DCCM size of 0x40000 + struct packed { + bit [11:0] block_size; + bit src_is_fifo; + bit dst_is_fifo; + bit use_rd_fixed; + bit use_wr_fixed; + bit inject_rand_delays; + bit inject_rst; + bit test_block_size; // Requires accessing the axi_fifo with recovery_data_avail emulation + dma_transfer_type_e dma_xfer_type; // Randomized transfer type + } type_dword; + logic [31:0] data; // Assuming a 39-bit data format + + if (!$value$plusargs("NUM_ITERATIONS=%d", num_iterations)) begin + num_iterations = 25; // Default + end + if (num_iterations > 100) begin + $fatal("num_iterations cannot exceed 100 due to width of dma_gen_block_size output signal..."); + end + + dma_gen_block_size = '0; + + // Wait for caliptra_top_tb to complete preload_dccm before running slam_dccm_ram + wait(preload_dccm_done); + + // Test cases cases are stored in DCCM starting from the end address and filling backwards + // 0x5003_FFFC: num_iterations + // 0x5003_FFF8: tc #1 xfer_type + // 0x5003_FFF4: tc #1 xfer_size + // 0x5003_FFF0: tc #1 payload data #0 + // ... + // 0x5003_xxxx: tc #1 payload data #(xfer_size-1) + // 0x5000_xxxx - 4: tc #2 xfer_type + // ... + slam_dccm_ram(end_addr - 3, {riscv_ecc32(num_iterations), num_iterations}); + total_testcase_bytes_to_check = total_testcase_bytes_to_check - 4; // 4-bytes for "num_iterations" + total_testcase_bytes_to_check = total_testcase_bytes_to_check - 16; // 16-bytes for 4-dwords of xfer_type, xfer_size, src_addr, dst_addr for first xfer + + tc_start_addr = end_addr - 7; + dccm_addr = tc_start_addr; + + // Resize the dynamic array + dma_xfers = new[num_iterations]; + + $display(" ======================================================"); + $display(" Running %d iterations of rand_test_dma", num_iterations); + $display(" ======================================================"); + + // Generate and store test cases + for (int i = 0; i < num_iterations; i++) begin: gen_dma_tc + dma_transfer_randomizer#(MAX_SIZE_TO_CHECK) dma_gen = new(total_testcase_bytes_to_check/4, verbosity); + if (!dma_gen.randomize()) begin + $error("Randomization failed for dma_transfer_generator %d", i); + end + else begin + dma_xfers[i] = dma_gen; + + //dccm_addr = tc_start_addr - (i * ((2 + dma_gen.xfer_size) * 4)); // 1dw = xfer_type, 1dw = xfer_size, xfer_size dws = payload data + + // Write DMA transfer_type tp DCCM + type_dword.block_size = dma_gen.block_size ; + type_dword.src_is_fifo = dma_gen.src_is_fifo ; + type_dword.dst_is_fifo = dma_gen.dst_is_fifo ; + type_dword.use_rd_fixed = dma_gen.use_rd_fixed ; + type_dword.use_wr_fixed = dma_gen.use_wr_fixed ; + type_dword.inject_rand_delays = dma_gen.inject_rand_delays; + type_dword.inject_rst = dma_gen.inject_rst ; + type_dword.test_block_size = dma_gen.test_block_size ; + type_dword.dma_xfer_type = dma_gen.dma_xfer_type ; + data = 32'(type_dword); + if (verbosity >= 1) begin + $display("dccm_addr = 0x%0x, xfer_type = 0x%0x", dccm_addr, data); + end + slam_dccm_ram(dccm_addr, data == 0 ? 0 : {riscv_ecc32(data),data}); + + // Write DMA transfer size to DCCM + dccm_addr = dccm_addr - 4; + data = dma_gen.xfer_size; + if (verbosity >= 1) begin + $display("dccm_addr = 0x%0x, xfer_size = 0x%0x", dccm_addr, data); + end + slam_dccm_ram(dccm_addr, data == 0 ? 0 : {riscv_ecc32(data),data}); + + // Write DMA src offset to DCCM + dccm_addr = dccm_addr - 4; + data = dma_gen.src_offset; + if (verbosity >= 1) begin + $display("dccm_addr = 0x%0x, src_offset = 0x%0x", dccm_addr, data); + end + slam_dccm_ram(dccm_addr, data == 0 ? 0 : {riscv_ecc32(data),data}); + + // Write DMA dst offset to DCCM + dccm_addr = dccm_addr - 4; + data = dma_gen.dst_offset; + if (verbosity >= 1) begin + $display("dccm_addr = 0x%0x, dst_offset = 0x%0x", dccm_addr, data); + end + slam_dccm_ram(dccm_addr, data == 0 ? 0 : {riscv_ecc32(data),data}); + + // Write payload data to DCCM + if (dma_gen.xfer_size <= MAX_SIZE_TO_CHECK) begin + for (int j = 0; j < dma_gen.xfer_size; j++) begin + dccm_addr = dccm_addr - 4; + data = dma_gen.payload_data[j]; + if ((verbosity >= 2) || ((verbosity >= 1) && (j == dma_gen.xfer_size-1))) begin + $display("dccm_addr = 0x%0x, data = 0x%0x", dccm_addr, data); + end + slam_dccm_ram(dccm_addr, data == 0 ? 0 : {riscv_ecc32(data), data}); + end + end + else if (verbosity >= 1) begin + $display("payload skipped"); + end + dma_gen.display(i, verbosity); + if (verbosity >= 1) begin + $display("-------------------------------"); + end + + // Drive out the block_size on the array to caliptra_top_tb_axi_fifo + dma_gen_block_size[i] = dma_gen.block_size; + + // After writing the entire transfer, move to a new address for the next transfer + // Move to the next 4-byte boundary for the next transfer + dccm_addr = dccm_addr - 4; + end + if (total_testcase_bytes_to_check <= ((4*MAX_SIZE_TO_CHECK > 4*dma_gen.xfer_size) ? 4*dma_gen.xfer_size + 16 : 16)) begin + total_testcase_bytes_to_check = 0; + num_iterations = i+1; + break; + end + else begin + total_testcase_bytes_to_check = total_testcase_bytes_to_check - ((4*MAX_SIZE_TO_CHECK > 4*dma_gen.xfer_size) ? 4*dma_gen.xfer_size + 16 : 16); + end + end + + $display(" ======================================================"); + $display(" Writing random generated test cases to DCCM completed."); + slam_dccm_ram(end_addr - 3, {riscv_ecc32(num_iterations), num_iterations}); // Rewrite in case we had to truncate the num_iterations + $display(" * Final iteration count of rand_test_dma: %d", num_iterations); + $display(" ======================================================"); + end + dma_gen_done = 1; + end + + // Task to provide the test cases + function void get_dma_xfers(dma_transfer_randomizer#(MAX_SIZE_TO_CHECK) t[]); + t = dma_xfers; + endfunction + + `endif // VERILATOR +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/dma_transfer_randomizer.sv b/designs/Caliptra/src/caliptra-rtl/dma_transfer_randomizer.sv new file mode 100644 index 0000000..a071768 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/dma_transfer_randomizer.sv @@ -0,0 +1,242 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +// + +class dma_transfer_randomizer #(parameter MAX_SIZE_TO_CHECK = 16384); + + // ============================================= + // Class properties + // ============================================= + int verbosity; + + rand dma_transfer_type_e dma_xfer_type; // Randomized transfer type + int unsigned max_checked_xfer_size = 0; // From the TB, based on space in DCCM + rand int unsigned xfer_size; // Randomized transfer size in dwords + rand int unsigned payload_data[]; // Randomized payload data array + rand int unsigned src_offset; + rand int unsigned dst_offset; + rand bit src_is_fifo; + rand bit dst_is_fifo; + rand bit use_rd_fixed; + rand bit use_wr_fixed; + rand bit inject_rand_delays; + rand bit inject_rst; + rand bit test_block_size; // Requires accessing the axi_fifo with recovery_data_avail emulation + rand bit [11:0] block_size; + + `ifndef VERILATOR + // ============================================= + // Constraints + // ============================================= + // Transfer type constrained to enum values + constraint valid_transfer_type { + dma_xfer_type inside {[0:4]}; + + // Weight distribution to ensure each type is chosen at least once + dma_xfer_type dist { + 0 := 20, // AHB2AXI + 1 := 20, // MBOX2AXI + 2 := 20, // AXI2AXI + 3 := 20, // AXI2MBOX + 4 := 20 // AXI2AHB + }; + } + + // sizes + constraint transfer_size_c { + xfer_size dist { + [1:4] :/ 500 + ,[5:64] :/ 1000 + ,[65:256] :/ 500 + ,[257:2048] :/ 200 + ,[2049:4096] :/ 20 + ,[4097:16384] :/ 5 + ,[16385:65536] :/ 2 + }; +// Disable large transfer sizes since Subsystem mode defines a smaller mbox, per +// - CPTRA_MBOX_SIZE_BYTES +// - CLP_MBOX_SRAM_END_ADDR (from caliptra_reg_defines.svh) +// - MBOX_DIR_END_ADDR +// - MBOX_DIR_MEM_SIZE +`ifdef CALIPTRA_MODE_SUBSYSTEM + dma_xfer_type inside {MBOX2AXI,AXI2MBOX} -> xfer_size <= MBOX_DIR_MEM_SIZE; +`endif + (xfer_size <= max_checked_xfer_size) || (xfer_size > MAX_SIZE_TO_CHECK); + solve dma_xfer_type before xfer_size; + } + constraint payload_data_size_c { + if (xfer_size > MAX_SIZE_TO_CHECK) + payload_data.size == 1; // Actual payload will be generated by FIFO auto-mode in the system + else + payload_data.size == xfer_size; + solve xfer_size before payload_data.size; + } + + // access properties + constraint test_blk_size_c { + test_block_size dist { 0 := 2, 1 := 1 }; + test_block_size -> src_is_fifo; + test_block_size -> dma_xfer_type inside {AXI2AXI,AXI2AHB,AXI2MBOX}; + solve dma_xfer_type before test_block_size; + }; + + constraint blk_size_c { + !test_block_size -> block_size == 0; + test_block_size -> $onehot(block_size); + test_block_size -> block_size inside {[4:2048]}; + solve test_block_size before block_size; + }; + + constraint blk_size_with_axi2axi_restriction_c { + test_block_size && (dma_xfer_type == AXI2AXI) -> block_size <= AXI_FIXED_LEN_MAX_VALUE*CPTRA_AXI_DMA_DATA_WIDTH; // 64 is the maximum burst size for AXI FIXED bursts assuming a 32-bit data width + test_block_size && (dma_xfer_type == AXI2AXI) -> dst_offset & (block_size - 1) == 0; // Force destination address to be aligned to the block_size + }; + + constraint fifo_access_c { + !(src_is_fifo && dst_is_fifo); + dma_xfer_type inside {AHB2AXI,MBOX2AXI} -> !src_is_fifo; + dma_xfer_type inside {AXI2AHB,AXI2MBOX} -> !dst_is_fifo; + src_is_fifo -> use_rd_fixed; + dst_is_fifo -> use_wr_fixed; + solve test_block_size before src_is_fifo; + solve test_block_size before dst_is_fifo; + solve test_block_size before use_rd_fixed; + solve test_block_size before use_wr_fixed; + }; + + constraint fixed_access_c { + dma_xfer_type inside {AHB2AXI,MBOX2AXI} -> !use_rd_fixed; + dma_xfer_type inside {AXI2AHB,AXI2MBOX} -> !use_wr_fixed; + use_rd_fixed dist { 0 := 1, 1 := 1 }; + use_wr_fixed dist { 0 := 1, 1 := 1 }; + solve dma_xfer_type before use_rd_fixed; + solve dma_xfer_type before use_wr_fixed; + solve src_is_fifo before use_rd_fixed; + solve dst_is_fifo before use_wr_fixed; + }; + + // addresses + // src unused for AHB2AXI, still calculate it... + constraint src_addr_c { + dma_xfer_type == MBOX2AXI -> src_offset inside {[0:MBOX_DIR_END_ADDR]}; + dma_xfer_type == MBOX2AXI -> (src_offset + xfer_size*4) <= MBOX_DIR_MEM_SIZE; + dma_xfer_type != MBOX2AXI && src_is_fifo -> src_offset inside {[0:AXI_FIFO_SIZE_BYTES-1]}; + dma_xfer_type != MBOX2AXI && !src_is_fifo -> src_offset inside {[0:AXI_SRAM_SIZE_BYTES-1]}; + dma_xfer_type != MBOX2AXI && !src_is_fifo -> (src_offset + xfer_size*4) <= AXI_SRAM_SIZE_BYTES; + src_offset[1:0] == 2'b0; + solve dma_xfer_type before src_offset; + }; + + // dst unused for AXI2AHB, still calculate it... + constraint dst_addr_c { + dma_xfer_type == AXI2MBOX -> dst_offset inside {[0:MBOX_DIR_END_ADDR]}; + dma_xfer_type == AXI2MBOX -> (dst_offset + xfer_size*4) <= MBOX_DIR_MEM_SIZE; + dma_xfer_type != AXI2MBOX && dst_is_fifo -> dst_offset inside {[0:AXI_FIFO_SIZE_BYTES-1]}; + dma_xfer_type != AXI2MBOX && !dst_is_fifo -> dst_offset inside {[0:AXI_SRAM_SIZE_BYTES-1]}; + dma_xfer_type != AXI2MBOX && !dst_is_fifo -> (dst_offset + xfer_size*4) <= AXI_SRAM_SIZE_BYTES; + dst_offset[1:0] == 2'b0; + solve dma_xfer_type before dst_offset; + solve block_size before dst_offset; + }; + + // TB stimulus injection + constraint inject_c { + inject_rand_delays dist { 0 := 5, 1 := 1 }; + inject_rst dist { 0 := 75, 1 := 25 }; + }; + `endif + + // ============================================= + // Constructor + // ============================================= + function new(int max_checked_size, int verbosity); + this.max_checked_xfer_size = max_checked_size; + this.verbosity = verbosity; + endfunction + + `ifndef VERILATOR + // ============================================= + // Pre-randomize function + // ============================================= + function void pre_randomize(); + // Onus is on TB not to request a transfer with size == 0! + if (max_checked_xfer_size == 0) + $fatal("max_checked_xfer_size must be provided and non-zero!"); + endfunction + + // ============================================= + // Post-randomize function + // ============================================= + function void post_randomize(); + //Verify post_randomize() is being called + if (this.verbosity >= 1) begin + $display("post_randomize called with xfer_size = %0d", xfer_size); + end + + // Report payload_data array size + if (this.verbosity >= 1) begin + if (xfer_size <= MAX_SIZE_TO_CHECK) begin + $display("payload_data initialized with size: %d", payload_data.size()); + end + else begin + $display("payload_data will not be initialized or checked for very large transfer test. Size: %d", payload_data.size()); + end + end + + // Ensure array is porperly sized + if ((xfer_size <= MAX_SIZE_TO_CHECK) && (payload_data.size() != xfer_size)) begin + $error("For xfer_size %d, payload_data.size %d is incorrect!", xfer_size, payload_data.size()); + end + + foreach (payload_data[i]) if (payload_data[i] == 0) $warning("payload_data[%d] is 0!", i); +// // Populate payload_data array with non-zero random values +// foreach (payload_data[i]) begin +// do begin +// payload_data[i] = $urandom(); +// end while (payload_data[i] == 0); // Ensure non-zero values +// $display(" Setting payload_data[%0d] = 0x%0x", i, payload_data[i]); +// end + endfunction + `endif + + // ============================================= + // Display method + // ============================================= + function void display(int index = -1, int local_verbosity = 1); + if (local_verbosity >= 1) begin + if (index != -1) begin + $display("Transfer %0d:", index); + end + $display(" Type: %s", dma_xfer_type.name()); + $display(" Size: %0d dwords", xfer_size); + if (local_verbosity >= 2) begin + $display(" Payload Data:"); + foreach (payload_data[i]) begin + $display(" %0d: %h", i, payload_data[i]); + end + end + $display(" src_is_fifo : 0x%x", src_is_fifo ); + $display(" dst_is_fifo : 0x%x", dst_is_fifo ); + $display(" src_offset : 0x%x", src_offset ); + $display(" dst_offset : 0x%x", dst_offset ); + $display(" use_rd_fixed : 0x%x", use_rd_fixed ); + $display(" use_wr_fixed : 0x%x", use_wr_fixed ); + $display(" inject_rand_delays: 0x%x", inject_rand_delays); + $display(" inject_rst : 0x%x", inject_rst ); + $display(" test_block_size : 0x%x", test_block_size ); + $display(" block_size : 0x%x", block_size ); + end + endfunction + +endclass diff --git a/designs/Caliptra/src/caliptra-rtl/dmi_jtag_to_core_sync.v b/designs/Caliptra/src/caliptra-rtl/dmi_jtag_to_core_sync.v new file mode 100644 index 0000000..dc0a0bb --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/dmi_jtag_to_core_sync.v @@ -0,0 +1,64 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2018 Western Digital Corporation or it's affiliates. +// +// 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. +//------------------------------------------------------------------------------------ +// +// Copyright Western Digital, 2019 +// Owner : Alex Grobman +// Description: +// This module Synchronizes the signals between JTAG (TCK) and +// processor (Core_clk) +// +//------------------------------------------------------------------------------------- + +module dmi_jtag_to_core_sync ( +// JTAG signals +input rd_en, // 1 bit Read Enable from JTAG +input wr_en, // 1 bit Write enable from JTAG + +// Processor Signals +input rst_n, // Core reset +input clk, // Core clock + +output reg_en, // 1 bit Write interface bit to Processor +output reg_wr_en // 1 bit Write enable to Processor +); + +wire c_rd_en; +wire c_wr_en; +reg [2:0] rden, wren; + + +// Outputs +assign reg_en = c_wr_en | c_rd_en; +assign reg_wr_en = c_wr_en; + + +// synchronizers +always @ ( posedge clk or negedge rst_n) begin + if(!rst_n) begin + rden <= '0; + wren <= '0; + end + else begin + rden <= {rden[1:0], rd_en}; + wren <= {wren[1:0], wr_en}; + end +end + +assign c_rd_en = rden[1] & ~rden[2]; +assign c_wr_en = wren[1] & ~wren[2]; + + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/dmi_mux.v b/designs/Caliptra/src/caliptra-rtl/dmi_mux.v new file mode 100644 index 0000000..105ec70 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/dmi_mux.v @@ -0,0 +1,67 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright (c) 2023 Antmicro +// +// 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. + +// DMI core aperture ranges from 0x00 to 0x4F. Addresses starting from 0x50 +// and above are considered uncore. + +module dmi_mux ( + + // Core access enable + input wire core_enable, + // Uncore access enable + input wire uncore_enable, + + // DMI upstream + input wire dmi_en, + input wire dmi_wr_en, + input wire [ 6:0] dmi_addr, + input wire [31:0] dmi_wdata, + output wire [31:0] dmi_rdata, + + // DMI downstream for core + output wire dmi_core_en, + output wire dmi_core_wr_en, + output wire [ 6:0] dmi_core_addr, + output wire [31:0] dmi_core_wdata, + input wire [31:0] dmi_core_rdata, + + // DMI downstream for uncore + output wire dmi_uncore_en, + output wire dmi_uncore_wr_en, + output wire [ 6:0] dmi_uncore_addr, + output wire [31:0] dmi_uncore_wdata, + input wire [31:0] dmi_uncore_rdata +); + logic is_uncore_aperture; + + // Uncore address decoder + assign is_uncore_aperture = (dmi_addr[6] & (dmi_addr[5] | dmi_addr[4])); + + // Core signals + assign dmi_core_en = dmi_en & ~is_uncore_aperture & core_enable; + assign dmi_core_wr_en = dmi_wr_en & ~is_uncore_aperture & core_enable; + assign dmi_core_addr = dmi_addr; + assign dmi_core_wdata = dmi_wdata; + + // Uncore signals + assign dmi_uncore_en = dmi_en & is_uncore_aperture & uncore_enable; + assign dmi_uncore_wr_en = dmi_wr_en & is_uncore_aperture & uncore_enable; + assign dmi_uncore_addr = dmi_addr; + assign dmi_uncore_wdata = dmi_wdata; + + // Read mux + assign dmi_rdata = is_uncore_aperture ? dmi_uncore_rdata : dmi_core_rdata; + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/dmi_wrapper.v b/designs/Caliptra/src/caliptra-rtl/dmi_wrapper.v new file mode 100644 index 0000000..9fc09e7 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/dmi_wrapper.v @@ -0,0 +1,88 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2018 Western Digital Corporation or it's affiliates. +// +// 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. +//------------------------------------------------------------------------------------ +// +// Copyright Western Digital, 2018 +// Owner : Anusha Narayanamoorthy +// Description: +// Wrapper module for JTAG_TAP and DMI synchronizer +// +//------------------------------------------------------------------------------------- + +module dmi_wrapper( + + // JTAG signals + input trst_n, // JTAG reset + input tck, // JTAG clock + input tms, // Test mode select + input tdi, // Test Data Input + output tdo, // Test Data Output + output tdoEnable, // Test Data Output enable + + // Processor Signals + input core_rst_n, // Core reset + input core_clk, // Core clock + input [31:0] rd_data, // 32 bit Read data from Processor + output [31:0] reg_wr_data, // 32 bit Write data to Processor + output [6:0] reg_wr_addr, // 7 bit reg address to Processor + output reg_en, // 1 bit Read enable to Processor + output reg_wr_en, // 1 bit Write enable to Processor + output dmi_hard_reset +); + + + + + + //Wire Declaration + wire rd_en; + wire wr_en; + wire dmireset; + + + //jtag_tap instantiation + rvjtag_tap i_jtag_tap( + .trst(trst_n), // dedicated JTAG TRST (active low) pad signal or asynchronous active low power on reset + .tck(tck), // dedicated JTAG TCK pad signal + .tms(tms), // dedicated JTAG TMS pad signal + .tdi(tdi), // dedicated JTAG TDI pad signal + .tdo(tdo), // dedicated JTAG TDO pad signal + .tdoEnable(tdoEnable), // enable for TDO pad + .wr_data(reg_wr_data), // 32 bit Write data + .wr_addr(reg_wr_addr), // 7 bit Write address + .rd_en(rd_en), // 1 bit read enable + .wr_en(wr_en), // 1 bit Write enable + .rd_data(rd_data), // 32 bit Read data + .rd_status(2'b0), + .idle(3'h0), // no need to wait to sample data + .dmi_stat(2'b0), // no need to wait or error possible + .version(4'h1), // debug spec 0.13 compliant + .dmi_hard_reset(dmi_hard_reset), + .dmi_reset(dmireset) +); + + + // dmi_jtag_to_core_sync instantiation + dmi_jtag_to_core_sync i_dmi_jtag_to_core_sync( + .wr_en(wr_en), // 1 bit Write enable + .rd_en(rd_en), // 1 bit Read enable + + .rst_n(core_rst_n), + .clk(core_clk), + .reg_en(reg_en), // 1 bit Write interface bit + .reg_wr_en(reg_wr_en) // 1 bit Write enable + ); + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/doe_cbc.sv b/designs/Caliptra/src/caliptra-rtl/doe_cbc.sv new file mode 100644 index 0000000..a9e9e5b --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/doe_cbc.sv @@ -0,0 +1,311 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +// +//============================================================================== +// +// doe_cbc.v +// -------- +// The module supports DOE_CBC and it is the modified version of doe.v file. +// In the hierarcy, one level up module is the doe_ctrl_32.sv or doe_ctrl_64.sv +// This module receives the data from AHB just before decoding it into block, +// key, and IV. +// +// The "IV XOR Plaintext" operation is just added into the DOE first Key XOR path. +// The combinational logical path is ((IV XOR Plaintext) XOR Key). The lower +// hierarcy, doe core, has not been changed. Instead, doe_core_cbc was created. +// The created design differs from the original one only with an XOR operation. +// +// DOE CBC mode is tested with doe_cbc_tb.sv +// +// +//============================================================================== + +module doe_cbc + import doe_defines_pkg::*; + import kv_defines_pkg::*; + import doe_reg_pkg::*; + #( + parameter ADDR_WIDTH = 32, + parameter DATA_WIDTH = 32 + ) + ( + // Clock and reset. + input wire clk, + input wire reset_n, + input wire cptra_pwrgood, + + input wire [`CLP_OBF_KEY_DWORDS-1:0][31:0] cptra_obf_key, + + //Obfuscated UDS and FE + input wire [`CLP_OBF_FE_DWORDS-1 :0][31:0] obf_field_entropy, + input wire [`CLP_OBF_UDS_DWORDS-1:0][31:0] obf_uds_seed, + input wire [OCP_LOCK_HEK_NUM_DWORDS-1:0][31:0] obf_hek_seed, + + // Control. + input wire cs, + input wire we, + + // Data ports. + input wire [ADDR_WIDTH-1 : 0] address, + input wire [DATA_WIDTH-1 : 0] write_data, + output wire [DATA_WIDTH-1 : 0] read_data, + + // Interrupt Outputs + output logic error_intr, + output logic notif_intr, + + output logic clear_obf_secrets, + + output logic busy_o, + + //interface with kv + output kv_write_t kv_write, + input logic ocp_lock_en, // Synth-time constant strap input instead of ocp_lock_in_progress + input logic debugUnlock_or_scan_mode_switch + ); + + //---------------------------------------------------------------- + // Registers including update variables and write enable. + //---------------------------------------------------------------- + localparam BLOCK_NO = 128 / DATA_WIDTH; + localparam IV_NO = 128 / DATA_WIDTH; + + logic [BLOCK_NO-1:0][DATA_WIDTH-1:0] block_reg; + logic [IV_NO-1:0][DATA_WIDTH-1:0] IV_reg; + reg [127 : 0] kv_result_reg; + reg ready_reg; + + //---------------------------------------------------------------- + // Wires. + //---------------------------------------------------------------- + wire core_encdec; + wire core_init; + wire core_next; + wire core_ready; + wire [255 : 0] core_key; + wire core_keylen; + wire [127 : 0] core_block; + wire [127 : 0] core_IV; + wire [127 : 0] core_result; + wire core_valid; + + //client control register + doe_cmd_reg_t doe_cmd_reg; + + logic IV_updated; + + //interface with client + logic doe_block_write_en; + logic [127:0] doe_block_write_data; + + logic doe_init; + logic doe_next; + logic zeroize; + + logic flow_done; + logic flow_error; + logic flow_in_progress, lock_fe_flow, lock_uds_flow, lock_hek_flow; + + doe_reg__in_t hwif_in; + doe_reg__out_t hwif_out; + + + //---------------------------------------------------------------- + // Concurrent connectivity for ports etc. + //---------------------------------------------------------------- + assign core_key = {cptra_obf_key[0], cptra_obf_key[1], cptra_obf_key[2], cptra_obf_key[3], cptra_obf_key[4], cptra_obf_key[5], cptra_obf_key[6], cptra_obf_key[7]}; + assign core_block = {block_reg[0], block_reg[1], block_reg[2], block_reg[3]}; + assign core_IV = {IV_reg[0], IV_reg[1], IV_reg[2], IV_reg[3]}; + + assign core_init = doe_init; + assign core_next = doe_next; + assign core_encdec = '0; //force decypher for DOE + assign core_keylen = '1; //force 256b KEY for DOE + + + //---------------------------------------------------------------- + // core instantiation. + //---------------------------------------------------------------- + doe_core_cbc i_doe_core_cbc( + .clk(clk), + .reset_n(reset_n), + .zeroize(zeroize), + + .encdec(core_encdec), + .init_cmd(core_init), + .next_cmd(core_next), + .ready(core_ready), + + .key(core_key), + .keylen(core_keylen), + + .IV(core_IV), + .IV_updated(IV_updated), + + .block_msg(core_block), + .result(core_result), + .result_valid(core_valid) + ); + + + //---------------------------------------------------------------- + // reg_update + // Update functionality for all registers in the core. + // All registers are positive edge triggered with asynchronous + // active low reset. + //---------------------------------------------------------------- + always @ (posedge clk or negedge reset_n) begin : reg_update + if (!reset_n) begin + block_reg <= '0; + ready_reg <= '0; + kv_result_reg <= '0; + end + else if (zeroize) begin + block_reg <= '0; + ready_reg <= '0; + kv_result_reg <= '0; + end + else begin + ready_reg <= core_ready; + kv_result_reg <= core_result; + block_reg <= doe_block_write_en ? doe_block_write_data : block_reg; + end + end// reg_update + +//DOE Register Hardware Interface + + +// Lock the UDS_FLOW_DONE & FE_FLOW_DONE status once the flow is done. Bit is reset only on cold reset on '1. FIXME: add an assertion +assign hwif_in.DOE_STATUS.UDS_FLOW_DONE.next = lock_uds_flow; +assign hwif_in.DOE_STATUS.FE_FLOW_DONE.next = lock_fe_flow; +assign hwif_in.DOE_STATUS.HEK_FLOW_DONE.next = lock_hek_flow; + +assign hwif_in.DOE_STATUS.DEOBF_SECRETS_CLEARED.hwset = clear_obf_secrets; + +assign hwif_in.DOE_STATUS.READY.hwset = ready_reg & ~(flow_in_progress); +assign hwif_in.DOE_STATUS.READY.hwclr = ~ready_reg; +assign hwif_in.DOE_STATUS.VALID.hwset = flow_done | clear_obf_secrets; +assign hwif_in.DOE_STATUS.VALID.hwclr = hwif_out.DOE_CTRL.CMD.swmod || hwif_out.DOE_CTRL.CMD_EXT.swmod; +assign hwif_in.DOE_STATUS.ERROR.hwset = flow_error; +assign hwif_in.DOE_STATUS.ERROR.hwclr = clear_obf_secrets || hwif_out.DOE_CTRL.CMD.swmod || hwif_out.DOE_CTRL.CMD_EXT.swmod; + +assign hwif_in.DOE_CTRL.CMD.hwclr = flow_done | clear_obf_secrets; +assign hwif_in.DOE_CTRL.CMD_EXT.hwclr = flow_done | clear_obf_secrets; + +assign doe_cmd_reg.cmd = doe_cmd_e'({hwif_out.DOE_CTRL.CMD_EXT.value,hwif_out.DOE_CTRL.CMD.value}); +// OCP LOCK flow for HEK deobf requires output be stored in a predetermined slot. +// ROM is responsible for configuring this properly. +assign doe_cmd_reg.dest_sel = hwif_out.DOE_CTRL.DEST.value; + +//FW can do this to clear the obfuscation related secrets +//the Obfuscated UDS, FE, and OBF KEY +always_comb clear_obf_secrets = (doe_cmd_reg.cmd == DOE_CLEAR) || debugUnlock_or_scan_mode_switch; +always_comb zeroize = clear_obf_secrets; + +always_comb begin + IV_updated = '0; + for (int dword = 0; dword < IV_NO; dword++) begin + IV_reg[dword] = hwif_out.DOE_IV[dword].IV.value; + IV_updated |= hwif_out.DOE_IV[dword].IV.swmod; + end +end + +//TODO: flow_done also? +always_comb begin + for (int dword = 0; dword < IV_NO; dword++) begin + hwif_in.DOE_IV[dword].IV.hwclr = zeroize; + end +end + +doe_fsm +doe_fsm1 +( + .clk(clk), + .rst_b(reset_n), + .hard_rst_b(cptra_pwrgood), + //Obfuscated UDS and FE + .obf_field_entropy(obf_field_entropy), + .obf_uds_seed(obf_uds_seed), + .obf_hek_seed(obf_hek_seed), + + //client control register + .doe_cmd_reg(doe_cmd_reg), + .ocp_lock_en(ocp_lock_en), + + //interface with kv + .kv_write(kv_write), + + //interface with client + .src_write_en(doe_block_write_en), + .src_write_data(doe_block_write_data), + + .doe_init(doe_init), + .doe_next(doe_next), + + .init_done(core_ready), + .dest_data_avail(core_valid), + .dest_data(kv_result_reg), + + .flow_done(flow_done), + .flow_error(flow_error), + .flow_in_progress(flow_in_progress), + .lock_uds_flow(lock_uds_flow), + .lock_fe_flow (lock_fe_flow ), + .lock_hek_flow(lock_hek_flow), + .zeroize(zeroize) + +); + +always_comb hwif_in.reset_b = reset_n; +always_comb hwif_in.cptra_pwrgood = cptra_pwrgood; + +// Pulse input to intr_regs to set the interrupt status bit and generate interrupt output (if enabled) +always_comb hwif_in.intr_block_rf.error_internal_intr_r.error0_sts.hwset = 1'b0; // TODO please assign +always_comb hwif_in.intr_block_rf.error_internal_intr_r.error1_sts.hwset = 1'b0; // TODO please assign +always_comb hwif_in.intr_block_rf.error_internal_intr_r.error2_sts.hwset = 1'b0; // TODO please assign +always_comb hwif_in.intr_block_rf.error_internal_intr_r.error3_sts.hwset = 1'b0; // TODO please assign +always_comb hwif_in.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.hwset = flow_done; + +doe_reg i_doe_reg ( + .clk(clk), + .rst(reset_n), + + .s_cpuif_req (cs), + .s_cpuif_req_is_wr (we), + .s_cpuif_addr (address[DOE_REG_ADDR_WIDTH-1:0]), + .s_cpuif_wr_data (write_data[31:0]), + .s_cpuif_wr_biten ('1), + + .s_cpuif_req_stall_wr(), + .s_cpuif_req_stall_rd(), + .s_cpuif_rd_ack (), + .s_cpuif_rd_err (/*TODO*/), + .s_cpuif_rd_data (read_data ), + .s_cpuif_wr_ack (), + .s_cpuif_wr_err (/*TODO*/), + + .hwif_in (hwif_in ), + .hwif_out (hwif_out) + ); + +assign error_intr = hwif_out.intr_block_rf.error_global_intr_r.intr; +assign notif_intr = hwif_out.intr_block_rf.notif_global_intr_r.intr; + +always_comb busy_o = flow_in_progress | ~core_ready; + +endmodule // doe + +//====================================================================== +// EOF doe.v +//====================================================================== diff --git a/designs/Caliptra/src/caliptra-rtl/doe_core_cbc.sv b/designs/Caliptra/src/caliptra-rtl/doe_core_cbc.sv new file mode 100644 index 0000000..087e7a0 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/doe_core_cbc.sv @@ -0,0 +1,495 @@ +//====================================================================== +// +// Updated by Caliptra team to work in CBC mode: +// Line 57 IV was added in the port list. +// Line 139 IV was XORed with plaintext. +// Line 193-245 has an always block to store IV values for +// the next encry/decry due to the chain requirement +// Line 261 IV was XORed with decrypted ciphertext. +// doe_core_cbc.sv +// ---------- +// The DOE core. This core supports key size of 128, and 256 bits. +// Most of the functionality is within the submodules. +// +// +// Author: Joachim Strombergson +// Copyright (c) 2013, 2014, Secworks Sweden AB +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or +// without modification, are permitted provided that the following +// conditions are met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in +// the documentation and/or other materials provided with the +// distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +//====================================================================== + +module doe_core_cbc( + // Clock and reset. + input wire clk, + input wire reset_n, + input wire zeroize, + + // Control. + input wire encdec, + input wire init_cmd, + input wire next_cmd, + output wire ready, + + //Data. + input wire [255 : 0] key, + input wire keylen, + input wire [127 : 0] IV, + input wire IV_updated, + input wire [127 : 0] block_msg, + output wire [127 : 0] result, + output wire result_valid + ); + + + + + //---------------------------------------------------------------- + // Internal constant and parameter definitions. + //---------------------------------------------------------------- + localparam CTRL_IDLE = 2'h0; + localparam CTRL_INIT = 2'h1; + localparam CTRL_NEXT = 2'h2; + + + //---------------------------------------------------------------- + // Registers including update variables and write enable. + //---------------------------------------------------------------- + reg [1 : 0] doe_core_ctrl_reg; + reg [1 : 0] doe_core_ctrl_new; + reg doe_core_ctrl_we; + + reg result_valid_reg; + reg result_valid_new; + reg result_valid_we; + + reg ready_reg; + reg ready_new; + reg ready_we; + + + //---------------------------------------------------------------- + // Wires. + //---------------------------------------------------------------- + reg init_state; + + wire [127 : 0] round_key; + wire key_ready; + + reg enc_next; + wire [3 : 0] enc_round_nr; + wire [127 : 0] enc_new_block; + wire enc_ready; + wire [31 : 0] enc_sboxw; + + reg dec_next; + wire [3 : 0] dec_round_nr; + wire [127 : 0] dec_new_block; + wire dec_ready; + + reg [127 : 0] muxed_new_block; + reg [3 : 0] muxed_round_nr; + reg muxed_ready; + + wire [31 : 0] keymem_sboxw; + +/* verilator lint_off UNOPTFLAT */ + reg [31 : 0] muxed_sboxw; + wire [31 : 0] new_sboxw; +/* verilator lint_on UNOPTFLAT */ + +/* IV registers for chain based encryption */ + reg [127 : 0] IV_encry; + reg [127 : 0] IV_decry; + reg [127 : 0] IV_decry_next; + reg IV_updated_delayed; + + reg [1:0] IV_enc_state; + reg [1:0] IV_dec_state; + + reg [127:0] block_msg_encr; + + localparam st_IV_engine_idle = 2'h0, + st_IV_engine_stars = 2'h1, + st_IV_1st_decrypt = 2'h2; + + assign block_msg_encr = block_msg ^ IV_encry; + //---------------------------------------------------------------- + // Instantiations. + //---------------------------------------------------------------- + doe_encipher_block enc_block( + .clk(clk), + .reset_n(reset_n), + .zeroize(zeroize), + + .next_cmd(enc_next), + + .keylen(keylen), + .round(enc_round_nr), + .round_key(round_key), + + .sboxw(enc_sboxw), + .new_sboxw(new_sboxw), + + .block_msg(block_msg_encr), + .new_block(enc_new_block), + .ready(enc_ready) + ); + + + doe_decipher_block dec_block( + .clk(clk), + .reset_n(reset_n), + .zeroize(zeroize), + + .next_cmd(dec_next), + + .keylen(keylen), + .round(dec_round_nr), + .round_key(round_key), + + .block_msg(block_msg), + .new_block(dec_new_block), + .ready(dec_ready) + ); + + + doe_key_mem keymem( + .clk(clk), + .reset_n(reset_n), + .zeroize(zeroize), + + .key(key), + .keylen(keylen), + .init_cmd(init_cmd), + + .round(muxed_round_nr), + .round_key(round_key), + .ready(key_ready), + + .sboxw(keymem_sboxw), + .new_sboxw(new_sboxw) + ); + + + doe_sbox sbox_inst(.sboxw(muxed_sboxw), .new_sboxw(new_sboxw)); + + //---------------------------------------------------------------- + // IV Storage for Encryption and Decryption + // FSM design for IV value storage + // + // Since the IV is used to encry/decry next block, the IV should + // be preserved and updated after each encry/decry. The following + // FSM provides this functionality + //---------------------------------------------------------------- + + + always @ (posedge clk or negedge reset_n) + begin:IV_storage_management + if (!reset_n) + begin + IV_encry <= 128'h0; + IV_decry <= 128'h0; + IV_decry_next <= 128'h0; + IV_enc_state <= st_IV_engine_idle; + IV_dec_state <= st_IV_engine_idle; + IV_updated_delayed <= 1'b0; + end + else if (zeroize) + begin + IV_encry <= 128'h0; + IV_decry <= 128'h0; + IV_decry_next <= 128'h0; + IV_enc_state <= st_IV_engine_idle; + IV_dec_state <= st_IV_engine_idle; + IV_updated_delayed <= 1'b0; + end + else + begin + + // ENCRYPTION IV CONTROLLER + if(IV_updated_delayed) + IV_encry <= IV; + else if ((IV_enc_state == st_IV_engine_stars) && enc_ready) + IV_encry <= enc_new_block; + else + IV_encry <= IV_encry; + + case (IV_enc_state) + st_IV_engine_idle: + begin + if(enc_ready & enc_next) + IV_enc_state <= st_IV_engine_stars; + else + IV_enc_state <= st_IV_engine_idle; + end + st_IV_engine_stars: + begin + if (IV_updated_delayed) + IV_enc_state <= st_IV_engine_idle; + else + IV_enc_state <= st_IV_engine_stars; + end + default: + begin + IV_enc_state <= st_IV_engine_idle; + end + endcase //IV_enc_state + + // DECRYPTION IV CONTROLLER + case (IV_dec_state) + st_IV_engine_idle: + begin + IV_decry_next <= block_msg; + IV_decry <= IV; + if(dec_ready & dec_next) + IV_dec_state <= st_IV_1st_decrypt; + else + IV_dec_state <= st_IV_engine_idle; + end + st_IV_1st_decrypt: + begin + if(IV_updated_delayed) + begin + IV_decry_next <= IV; + IV_decry <= IV; + IV_dec_state <= st_IV_engine_idle; + end + else if(dec_ready & dec_next) + begin + IV_dec_state <= st_IV_engine_stars; + IV_decry_next <= block_msg; + IV_decry <= IV_decry_next; + end + else + begin + IV_dec_state <= st_IV_1st_decrypt; + IV_decry_next <= IV_decry_next; + IV_decry <= IV_decry; + end + end + st_IV_engine_stars: + begin + IV_dec_state <= st_IV_1st_decrypt; + IV_decry_next <= IV_decry_next; + IV_decry <= IV_decry; + end + default: + begin + IV_dec_state <= st_IV_engine_idle; + IV_decry_next <= IV; + IV_decry <= IV; + end + endcase //IV_dec_state + + IV_updated_delayed <= IV_updated; + end + end //IV_storage_management + + + + + //---------------------------------------------------------------- + // Concurrent connectivity for ports etc. + //---------------------------------------------------------------- + assign ready = ready_reg; + assign result = muxed_new_block; + assign result_valid = result_valid_reg; + + + //---------------------------------------------------------------- + // reg_update + // + // Update functionality for all registers in the core. + // All registers are positive edge triggered with asynchronous + // active low reset. All registers have write enable. + //---------------------------------------------------------------- + always @ (posedge clk or negedge reset_n) + begin: reg_update + if (!reset_n) + begin + result_valid_reg <= 1'b0; + ready_reg <= 1'b1; + doe_core_ctrl_reg <= CTRL_IDLE; + end + else if (zeroize) + begin + result_valid_reg <= 1'b0; + ready_reg <= 1'b1; + doe_core_ctrl_reg <= CTRL_IDLE; + end + else + begin + if (result_valid_we) + result_valid_reg <= result_valid_new; + + if (ready_we) + ready_reg <= ready_new; + + if (doe_core_ctrl_we) + doe_core_ctrl_reg <= doe_core_ctrl_new; + end + end // reg_update + + + //---------------------------------------------------------------- + // sbox_mux + // + // Controls which of the encipher datapath or the key memory + // that gets access to the sbox. + //---------------------------------------------------------------- + always @* + begin : sbox_mux + if (init_state) + begin + muxed_sboxw = keymem_sboxw; + end + else + begin + muxed_sboxw = enc_sboxw; + end + end // sbox_mux + + + //---------------------------------------------------------------- + // encdex_mux + // + // Controls which of the datapaths that get the next signal, have + // access to the memory as well as the block processing result. + //---------------------------------------------------------------- + always @* + begin : encdec_mux + enc_next = 1'b0; + dec_next = 1'b0; + + if (encdec) + begin + // Encipher operations + enc_next = next_cmd; + muxed_round_nr = enc_round_nr; + muxed_new_block = enc_new_block; + muxed_ready = enc_ready; + end + else + begin + // Decipher operations + dec_next = next_cmd; + muxed_round_nr = dec_round_nr; + muxed_new_block = dec_new_block^IV_decry; + muxed_ready = dec_ready; + end + end // encdec_mux + + + //---------------------------------------------------------------- + // doe_core_ctrl + // + // Control FSM for doe core. Basically tracks if we are in + // key init, encipher or decipher modes and connects the + // different submodules to shared resources and interface ports. + //---------------------------------------------------------------- + always @* + begin : doe_core_ctrl + init_state = 1'b0; + ready_new = 1'b0; + ready_we = 1'b0; + result_valid_new = 1'b0; + result_valid_we = 1'b0; + doe_core_ctrl_new = CTRL_IDLE; + doe_core_ctrl_we = 1'b0; + + case (doe_core_ctrl_reg) + CTRL_IDLE: + begin + if (init_cmd) + begin + init_state = 1'b1; + ready_new = 1'b0; + ready_we = 1'b1; + result_valid_new = 1'b0; + result_valid_we = 1'b1; + doe_core_ctrl_new = CTRL_INIT; + doe_core_ctrl_we = 1'b1; + end + else if (next_cmd) + begin + init_state = 1'b0; + ready_new = 1'b0; + ready_we = 1'b1; + result_valid_new = 1'b0; + result_valid_we = 1'b1; + doe_core_ctrl_new = CTRL_NEXT; + doe_core_ctrl_we = 1'b1; + end + end + + CTRL_INIT: + begin + init_state = 1'b1; + + if (key_ready) + begin + ready_new = 1'b1; + ready_we = 1'b1; + doe_core_ctrl_new = CTRL_IDLE; + doe_core_ctrl_we = 1'b1; + end + end + + CTRL_NEXT: + begin + init_state = 1'b0; + + if (muxed_ready) + begin + ready_new = 1'b1; + ready_we = 1'b1; + result_valid_new = 1'b1; + result_valid_we = 1'b1; + doe_core_ctrl_new = CTRL_IDLE; + doe_core_ctrl_we = 1'b1; + end + end + + default: + begin + init_state = 1'b0; + ready_new = 1'b0; + ready_we = 1'b0; + result_valid_new = 1'b0; + result_valid_we = 1'b0; + doe_core_ctrl_new = CTRL_IDLE; + doe_core_ctrl_we = 1'b0; + end + endcase // case (doe_core_ctrl_reg) + + end // doe_core_ctrl +endmodule // doe_core + +//====================================================================== +// EOF doe_core.v +//====================================================================== diff --git a/designs/Caliptra/src/caliptra-rtl/doe_cov_bind.sv b/designs/Caliptra/src/caliptra-rtl/doe_cov_bind.sv new file mode 100644 index 0000000..f991d2b --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/doe_cov_bind.sv @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. + + +module doe_cov_bind; + `ifdef FCOV + bind doe_ctrl doe_cov_if i_doe_cov_if(.*); + `endif +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/doe_cov_if.sv b/designs/Caliptra/src/caliptra-rtl/doe_cov_if.sv new file mode 100644 index 0000000..07fe6cf --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/doe_cov_if.sv @@ -0,0 +1,57 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. + +`ifndef VERILATOR + +interface doe_cov_if + import kv_defines_pkg::*; + import doe_defines_pkg::*; + ( + input logic clk, + input logic reset_n, + input logic cptra_pwrgood, + input logic ocp_lock_en, + input kv_write_t kv_write + ); + + logic running_uds, running_fe, running_hek; + doe_cmd_e doe_cmd; + + assign running_uds = doe_ctrl.doe_inst.doe_fsm1.running_uds; + assign running_fe = doe_ctrl.doe_inst.doe_fsm1.running_fe; + assign running_hek = doe_ctrl.doe_inst.doe_fsm1.running_hek; + assign doe_cmd = doe_cmd_e'(doe_ctrl.doe_inst.doe_cmd_reg.cmd); + + covergroup doe_cov_grp @(posedge clk); + running_uds_cp: coverpoint running_uds; + running_fe_cp: coverpoint running_fe; + running_hek_cp: coverpoint running_hek; + + ocp_lock_en_cp: coverpoint ocp_lock_en; + + dest_addr_cp: coverpoint kv_write.write_entry iff (doe_cmd inside {DOE_UDS, DOE_FE, DOE_HEK}) { + bins lower_slots = {[0:15]}; + bins upper_slots = {[16:22]}; + bins slot_23 = {23}; + } + + dest_addr_X_ocp_lock_en: cross dest_addr_cp, ocp_lock_en_cp; + + endgroup + + doe_cov_grp doe_cov_grp1 = new(); + +endinterface + +`endif \ No newline at end of file diff --git a/designs/Caliptra/src/caliptra-rtl/doe_ctrl.sv b/designs/Caliptra/src/caliptra-rtl/doe_ctrl.sv new file mode 100644 index 0000000..d3c62cb --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/doe_ctrl.sv @@ -0,0 +1,141 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +// +//====================================================================== +// +// doe_ctrl.sv +// -------- +// DOE controller for the AHb_lite interface. +// DOE is the de-obfuscation engine, used to de-obfuscate the device secrets +// +//====================================================================== +`include "caliptra_macros.svh" + +module doe_ctrl + import doe_defines_pkg::*; + import kv_defines_pkg::*; + #( + parameter AHB_DATA_WIDTH = 32, + parameter AHB_ADDR_WIDTH = 32, + localparam TOTAL_OBF_KEY_BITS = `CLP_OBF_KEY_DWORDS * 32 +) +( + // Clock and reset. + input wire clk, + input wire reset_n, + input wire cptra_pwrgood, + + input logic [TOTAL_OBF_KEY_BITS-1:0] cptra_obf_key, + + //Obfuscated UDS and FE + input logic [`CLP_OBF_FE_DWORDS-1 :0][31:0] obf_field_entropy, + input logic [`CLP_OBF_UDS_DWORDS-1:0][31:0] obf_uds_seed, + input logic [OCP_LOCK_HEK_NUM_DWORDS-1:0][31:0] obf_hek_seed, + + // from SLAVES PORT + input logic [AHB_ADDR_WIDTH-1:0] haddr_i, + input logic [AHB_DATA_WIDTH-1:0] hwdata_i, + input logic hsel_i, + input logic hwrite_i, + input logic hready_i, + input logic [1:0] htrans_i, + input logic [2:0] hsize_i, + + output logic hresp_o, + output logic hreadyout_o, + output logic [AHB_DATA_WIDTH-1:0] hrdata_o, + output kv_write_t kv_write, + input kv_wr_resp_t kv_wr_resp, + + output logic clear_obf_secrets, + + output logic busy_o, + + // Interrupt + output logic error_intr, + output logic notif_intr, + input logic ocp_lock_en, // Synth-time constant strap input instead of ocp_lock_in_progress + input logic debugUnlock_or_scan_mode_switch +); + + //---------------------------------------------------------------- + // doe + //---------------------------------------------------------------- + logic doe_cs; + logic doe_we; + logic [AHB_ADDR_WIDTH-1:0] doe_address; + logic [AHB_DATA_WIDTH-1:0] doe_write_data; + logic [AHB_DATA_WIDTH-1:0] doe_read_data; + + doe_cbc #( + .ADDR_WIDTH(AHB_ADDR_WIDTH), + .DATA_WIDTH(32) + ) doe_inst( + .clk(clk), + .reset_n(reset_n), + .cptra_pwrgood(cptra_pwrgood), + .cptra_obf_key(cptra_obf_key), + .obf_uds_seed(obf_uds_seed), + .obf_field_entropy(obf_field_entropy), + .obf_hek_seed(obf_hek_seed), + .cs(doe_cs), + .we(doe_we), + .address(doe_address), + .write_data(doe_write_data[31:0]), + .read_data(doe_read_data[31:0]), + .error_intr(error_intr), + .notif_intr(notif_intr), + .busy_o(busy_o), + .clear_obf_secrets(clear_obf_secrets), + .kv_write(kv_write), + .ocp_lock_en(ocp_lock_en), // Synth-time constant strap input instead of ocp_lock_in_progress + .debugUnlock_or_scan_mode_switch(debugUnlock_or_scan_mode_switch) + ); + + + //instantiate ahb lite module + ahb_slv_sif #( + .AHB_ADDR_WIDTH(AHB_ADDR_WIDTH), + .AHB_DATA_WIDTH(AHB_DATA_WIDTH), + .CLIENT_DATA_WIDTH(32) + ) ahb_slv_sif_uut + ( + //AMBA AHB Lite INF + .hclk(clk), + .hreset_n(reset_n), + .haddr_i(haddr_i), + .hwdata_i(hwdata_i), + .hsel_i(hsel_i), + .hwrite_i(hwrite_i), + .hready_i(hready_i), + .htrans_i(htrans_i), + .hsize_i(hsize_i), + + .hresp_o(hresp_o), + .hreadyout_o(hreadyout_o), + .hrdata_o(hrdata_o), + + + //COMPONENT INF + .dv(doe_cs), + .hld(1'b0), //no holds from doe + .err(1'b0), //no errors from doe + .write(doe_we), + .wdata(doe_write_data[31:0]), + .addr(doe_address), + + .rdata(doe_read_data[31:0]) + ); + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/doe_decipher_block.sv b/designs/Caliptra/src/caliptra-rtl/doe_decipher_block.sv new file mode 100644 index 0000000..3fef11a --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/doe_decipher_block.sv @@ -0,0 +1,556 @@ +//====================================================================== +// +// doe_decipher_block.v +// -------------------- +// The DOE decipher round. A pure combinational module that implements +// the initial round, main round and final round logic for +// decciper operations. +// +// +// Author: Joachim Strombergson +// Copyright (c) 2013, 2014, Secworks Sweden AB +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or +// without modification, are permitted provided that the following +// conditions are met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in +// the documentation and/or other materials provided with the +// distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +//====================================================================== + +module doe_decipher_block( + //Clock and reset. + input wire clk, + input wire reset_n, + input wire zeroize, + + //Control + input wire next_cmd, + + //Data + input wire keylen, + output wire [3 : 0] round, + input wire [127 : 0] round_key, + input wire [127 : 0] block_msg, + output wire [127 : 0] new_block, + output wire ready + ); + + + //---------------------------------------------------------------- + // Internal constant and parameter definitions. + //---------------------------------------------------------------- + //localparam DOE_128_BIT_KEY = 1'h0; + localparam DOE_256_BIT_KEY = 1'h1; + + localparam DOE128_ROUNDS = 4'ha; + localparam DOE256_ROUNDS = 4'he; + + localparam NO_UPDATE = 3'h0; + localparam INIT_UPDATE = 3'h1; + localparam SBOX_UPDATE = 3'h2; + localparam MAIN_UPDATE = 3'h3; + localparam FINAL_UPDATE = 3'h4; + + localparam CTRL_IDLE = 2'h0; + localparam CTRL_INIT = 2'h1; + localparam CTRL_SBOX = 2'h2; + localparam CTRL_MAIN = 2'h3; + + + //---------------------------------------------------------------- + // Gaolis multiplication functions for Inverse MixColumn. + //---------------------------------------------------------------- + function automatic [7 : 0] gm2(input [7 : 0] op); + begin + gm2 = {op[6 : 0], 1'b0} ^ (8'h1b & {8{op[7]}}); + end + endfunction // gm2 + + function automatic [7 : 0] gm3(input [7 : 0] op); + begin + gm3 = gm2(op) ^ op; + end + endfunction // gm3 + + function automatic [7 : 0] gm4(input [7 : 0] op); + begin + gm4 = gm2(gm2(op)); + end + endfunction // gm4 + + function automatic [7 : 0] gm8(input [7 : 0] op); + begin + gm8 = gm2(gm4(op)); + end + endfunction // gm8 + + function automatic [7 : 0] gm09(input [7 : 0] op); + begin + gm09 = gm8(op) ^ op; + end + endfunction // gm09 + + function automatic [7 : 0] gm11(input [7 : 0] op); + begin + gm11 = gm8(op) ^ gm2(op) ^ op; + end + endfunction // gm11 + + function automatic [7 : 0] gm13(input [7 : 0] op); + begin + gm13 = gm8(op) ^ gm4(op) ^ op; + end + endfunction // gm13 + + function automatic [7 : 0] gm14(input [7 : 0] op); + begin + gm14 = gm8(op) ^ gm4(op) ^ gm2(op); + end + endfunction // gm14 + + function automatic [31 : 0] inv_mixw(input [31 : 0] w_val); + reg [7 : 0] b0, b1, b2, b3; + reg [7 : 0] mb0, mb1, mb2, mb3; + begin + b0 = w_val[31 : 24]; + b1 = w_val[23 : 16]; + b2 = w_val[15 : 08]; + b3 = w_val[07 : 00]; + + mb0 = gm14(b0) ^ gm11(b1) ^ gm13(b2) ^ gm09(b3); + mb1 = gm09(b0) ^ gm14(b1) ^ gm11(b2) ^ gm13(b3); + mb2 = gm13(b0) ^ gm09(b1) ^ gm14(b2) ^ gm11(b3); + mb3 = gm11(b0) ^ gm13(b1) ^ gm09(b2) ^ gm14(b3); + + inv_mixw = {mb0, mb1, mb2, mb3}; + end + endfunction // mixw + + function automatic [127 : 0] inv_mixcolumns(input [127 : 0] data); + reg [31 : 0] w0, w1, w2, w3; + reg [31 : 0] ws0, ws1, ws2, ws3; + begin + w0 = data[127 : 096]; + w1 = data[095 : 064]; + w2 = data[063 : 032]; + w3 = data[031 : 000]; + + ws0 = inv_mixw(w0); + ws1 = inv_mixw(w1); + ws2 = inv_mixw(w2); + ws3 = inv_mixw(w3); + + inv_mixcolumns = {ws0, ws1, ws2, ws3}; + end + endfunction // inv_mixcolumns + + function automatic [127 : 0] inv_shiftrows(input [127 : 0] data); + reg [31 : 0] w0, w1, w2, w3; + reg [31 : 0] ws0, ws1, ws2, ws3; + begin + w0 = data[127 : 096]; + w1 = data[095 : 064]; + w2 = data[063 : 032]; + w3 = data[031 : 000]; + + ws0 = {w0[31 : 24], w3[23 : 16], w2[15 : 08], w1[07 : 00]}; + ws1 = {w1[31 : 24], w0[23 : 16], w3[15 : 08], w2[07 : 00]}; + ws2 = {w2[31 : 24], w1[23 : 16], w0[15 : 08], w3[07 : 00]}; + ws3 = {w3[31 : 24], w2[23 : 16], w1[15 : 08], w0[07 : 00]}; + + inv_shiftrows = {ws0, ws1, ws2, ws3}; + end + endfunction // inv_shiftrows + + function automatic [127 : 0] addroundkey(input [127 : 0] data, input [127 : 0] rkey); + begin + addroundkey = data ^ rkey; + end + endfunction // addroundkey + + + //---------------------------------------------------------------- + // Registers including update variables and write enable. + //---------------------------------------------------------------- + reg [1 : 0] sword_ctr_reg; + reg [1 : 0] sword_ctr_new; + reg sword_ctr_we; + reg sword_ctr_inc; + reg sword_ctr_rst; + + reg [3 : 0] round_ctr_reg; + reg [3 : 0] round_ctr_new; + reg round_ctr_we; + reg round_ctr_set; + reg round_ctr_dec; + + reg [127 : 0] block_new; + reg [31 : 0] block_w0_reg; + reg [31 : 0] block_w1_reg; + reg [31 : 0] block_w2_reg; + reg [31 : 0] block_w3_reg; + reg block_w0_we; + reg block_w1_we; + reg block_w2_we; + reg block_w3_we; + + reg ready_reg; + reg ready_new; + reg ready_we; + + reg [1 : 0] dec_ctrl_reg; + reg [1 : 0] dec_ctrl_new; + reg dec_ctrl_we; + + + //---------------------------------------------------------------- + // Wires. + //---------------------------------------------------------------- + reg [31 : 0] tmp_sboxw; + wire [31 : 0] new_sboxw; + reg [2 : 0] update_type; + + + //---------------------------------------------------------------- + // Instantiations. + //---------------------------------------------------------------- + doe_inv_sbox inv_sbox_inst(.sboxw(tmp_sboxw), .new_sboxw(new_sboxw)); + + + //---------------------------------------------------------------- + // Concurrent connectivity for ports etc. + //---------------------------------------------------------------- + assign round = round_ctr_reg; + assign new_block = {block_w0_reg, block_w1_reg, block_w2_reg, block_w3_reg}; + assign ready = ready_reg; + + + //---------------------------------------------------------------- + // reg_update + // + // Update functionality for all registers in the core. + // All registers are positive edge triggered with synchronous + // active low reset. All registers have write enable. + //---------------------------------------------------------------- + always @ (posedge clk or negedge reset_n) + begin: reg_update + if (!reset_n) + begin + block_w0_reg <= 32'h0; + block_w1_reg <= 32'h0; + block_w2_reg <= 32'h0; + block_w3_reg <= 32'h0; + sword_ctr_reg <= 2'h0; + round_ctr_reg <= 4'h0; + ready_reg <= 1'b1; + dec_ctrl_reg <= CTRL_IDLE; + end + else if (zeroize) + begin + block_w0_reg <= 32'h0; + block_w1_reg <= 32'h0; + block_w2_reg <= 32'h0; + block_w3_reg <= 32'h0; + sword_ctr_reg <= 2'h0; + round_ctr_reg <= 4'h0; + ready_reg <= 1'b1; + dec_ctrl_reg <= CTRL_IDLE; + end + else + begin + if (block_w0_we) + block_w0_reg <= block_new[127 : 096]; + + if (block_w1_we) + block_w1_reg <= block_new[095 : 064]; + + if (block_w2_we) + block_w2_reg <= block_new[063 : 032]; + + if (block_w3_we) + block_w3_reg <= block_new[031 : 000]; + + if (sword_ctr_we) + sword_ctr_reg <= sword_ctr_new; + + if (round_ctr_we) + round_ctr_reg <= round_ctr_new; + + if (ready_we) + ready_reg <= ready_new; + + if (dec_ctrl_we) + dec_ctrl_reg <= dec_ctrl_new; + end + end // reg_update + + + //---------------------------------------------------------------- + // round_logic + // + // The logic needed to implement init, main and final rounds. + //---------------------------------------------------------------- + always @* + begin : round_logic + reg [127 : 0] old_block, inv_shiftrows_block, inv_mixcolumns_block; + reg [127 : 0] addkey_block; + + inv_shiftrows_block = 128'h0; + inv_mixcolumns_block = 128'h0; + addkey_block = 128'h0; + block_new = 128'h0; + tmp_sboxw = 32'h0; + block_w0_we = 1'b0; + block_w1_we = 1'b0; + block_w2_we = 1'b0; + block_w3_we = 1'b0; + + old_block = {block_w0_reg, block_w1_reg, block_w2_reg, block_w3_reg}; + + // Update based on update type. + case (update_type) + // InitRound + INIT_UPDATE: + begin + old_block = block_msg; + addkey_block = addroundkey(old_block, round_key); + inv_shiftrows_block = inv_shiftrows(addkey_block); + block_new = inv_shiftrows_block; + block_w0_we = 1'b1; + block_w1_we = 1'b1; + block_w2_we = 1'b1; + block_w3_we = 1'b1; + end + + SBOX_UPDATE: + begin + block_new = {new_sboxw, new_sboxw, new_sboxw, new_sboxw}; + + case (sword_ctr_reg) + 2'h0: + begin + tmp_sboxw = block_w0_reg; + block_w0_we = 1'b1; + end + + 2'h1: + begin + tmp_sboxw = block_w1_reg; + block_w1_we = 1'b1; + end + + 2'h2: + begin + tmp_sboxw = block_w2_reg; + block_w2_we = 1'b1; + end + + 2'h3: + begin + tmp_sboxw = block_w3_reg; + block_w3_we = 1'b1; + end + endcase // case (sbox_mux_ctrl_reg) + end + + MAIN_UPDATE: + begin + addkey_block = addroundkey(old_block, round_key); + inv_mixcolumns_block = inv_mixcolumns(addkey_block); + inv_shiftrows_block = inv_shiftrows(inv_mixcolumns_block); + block_new = inv_shiftrows_block; + block_w0_we = 1'b1; + block_w1_we = 1'b1; + block_w2_we = 1'b1; + block_w3_we = 1'b1; + end + + FINAL_UPDATE: + begin + block_new = addroundkey(old_block, round_key); + block_w0_we = 1'b1; + block_w1_we = 1'b1; + block_w2_we = 1'b1; + block_w3_we = 1'b1; + end + + default: + begin + inv_shiftrows_block = 128'h0; + inv_mixcolumns_block = 128'h0; + addkey_block = 128'h0; + block_new = 128'h0; + tmp_sboxw = 32'h0; + block_w0_we = 1'b0; + block_w1_we = 1'b0; + block_w2_we = 1'b0; + block_w3_we = 1'b0; + end + endcase // case (update_type) + end // round_logic + + + //---------------------------------------------------------------- + // sword_ctr + // + // The subbytes word counter with reset and increase logic. + //---------------------------------------------------------------- + always @* + begin : sword_ctr + sword_ctr_new = 2'h0; + sword_ctr_we = 1'b0; + + if (sword_ctr_rst) + begin + sword_ctr_new = 2'h0; + sword_ctr_we = 1'b1; + end + else if (sword_ctr_inc) + begin + sword_ctr_new = sword_ctr_reg + 1'b1; + sword_ctr_we = 1'b1; + end + end // sword_ctr + + + //---------------------------------------------------------------- + // round_ctr + // + // The round counter with reset and increase logic. + //---------------------------------------------------------------- + always @* + begin : round_ctr + round_ctr_new = 4'h0; + round_ctr_we = 1'b0; + + if (round_ctr_set) + begin + if (keylen == DOE_256_BIT_KEY) + begin + round_ctr_new = DOE256_ROUNDS; + end + else // keylen == DOE_128_BIT_KEY + begin + round_ctr_new = DOE128_ROUNDS; + end + round_ctr_we = 1'b1; + end + else if (round_ctr_dec) + begin + round_ctr_new = round_ctr_reg - 1'b1; + round_ctr_we = 1'b1; + end + end // round_ctr + + + //---------------------------------------------------------------- + // decipher_ctrl + // + // The FSM that controls the decipher operations. + //---------------------------------------------------------------- + always @* + begin: decipher_ctrl + sword_ctr_inc = 1'b0; + sword_ctr_rst = 1'b0; + round_ctr_dec = 1'b0; + round_ctr_set = 1'b0; + ready_new = 1'b0; + ready_we = 1'b0; + update_type = NO_UPDATE; + dec_ctrl_new = CTRL_IDLE; + dec_ctrl_we = 1'b0; + + case (dec_ctrl_reg) + CTRL_IDLE: + begin + if (next_cmd) + begin + round_ctr_set = 1'b1; + ready_new = 1'b0; + ready_we = 1'b1; + dec_ctrl_new = CTRL_INIT; + dec_ctrl_we = 1'b1; + end + end + + CTRL_INIT: + begin + sword_ctr_rst = 1'b1; + update_type = INIT_UPDATE; + dec_ctrl_new = CTRL_SBOX; + dec_ctrl_we = 1'b1; + end + + CTRL_SBOX: + begin + sword_ctr_inc = 1'b1; + update_type = SBOX_UPDATE; + if (sword_ctr_reg == 2'h3) + begin + round_ctr_dec = 1'b1; + dec_ctrl_new = CTRL_MAIN; + dec_ctrl_we = 1'b1; + end + end + + CTRL_MAIN: + begin + sword_ctr_rst = 1'b1; + if (round_ctr_reg > 0) + begin + update_type = MAIN_UPDATE; + dec_ctrl_new = CTRL_SBOX; + dec_ctrl_we = 1'b1; + end + else + begin + update_type = FINAL_UPDATE; + ready_new = 1'b1; + ready_we = 1'b1; + dec_ctrl_new = CTRL_IDLE; + dec_ctrl_we = 1'b1; + end + end + + default: + begin + sword_ctr_inc = 1'b0; + sword_ctr_rst = 1'b0; + round_ctr_dec = 1'b0; + round_ctr_set = 1'b0; + ready_new = 1'b0; + ready_we = 1'b0; + update_type = NO_UPDATE; + dec_ctrl_new = CTRL_IDLE; + dec_ctrl_we = 1'b0; + // Empty. Just here to make the synthesis tool happy. + end + endcase // case (dec_ctrl_reg) + end // decipher_ctrl + +endmodule // doe_decipher_block + +//====================================================================== +// EOF doe_decipher_block.v +//====================================================================== diff --git a/designs/Caliptra/src/caliptra-rtl/doe_defines_pkg.sv b/designs/Caliptra/src/caliptra-rtl/doe_defines_pkg.sv new file mode 100644 index 0000000..3fa527f --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/doe_defines_pkg.sv @@ -0,0 +1,55 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +// + +`ifndef DOE_DEFINES_PKG +`define DOE_DEFINES_PKG + +package doe_defines_pkg; + import kv_defines_pkg::*; + + //---------------------------------------------------------------- + // Internal constant and parameter definitions. + //---------------------------------------------------------------- + + localparam DOE_CORE_NAME = 64'h20202020_73206165; // "doe " + localparam DOE_CORE_VERSION = 64'h00000000_3630302e; // "0.60" + +typedef enum logic [3:0] { + DOE_NOP = 4'b0000, + DOE_UDS = 4'b0001, + DOE_FE = 4'b0010, + DOE_CLEAR = 4'b0011, + DOE_HEK = 4'b0100, + DOE_INV0 = 4'b0101, // INVALID + DOE_INV1 = 4'b0110, // INVALID + DOE_INV2 = 4'b0111, // INVALID + DOE_RSVD0 = 4'b1000, // RESERVED + DOE_INV3 = 4'b1001, // INVALID + DOE_INV4 = 4'b1010, // INVALID + DOE_INV5 = 4'b1011, // INVALID + DOE_RSVD1 = 4'b1100, // RESERVED + DOE_INV6 = 4'b1101, // INVALID + DOE_INV7 = 4'b1110, // INVALID + DOE_INV8 = 4'b1111 // INVALID +} doe_cmd_e; + +typedef struct packed { + logic [KV_ENTRY_ADDR_W-1:0] dest_sel; + doe_cmd_e cmd; +} doe_cmd_reg_t; + +endpackage + +`endif diff --git a/designs/Caliptra/src/caliptra-rtl/doe_encipher_block.sv b/designs/Caliptra/src/caliptra-rtl/doe_encipher_block.sv new file mode 100644 index 0000000..faf9347 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/doe_encipher_block.sv @@ -0,0 +1,512 @@ +//====================================================================== +// +// doe_encipher_block.v +// -------------------- +// The DOE encipher round. A pure combinational module that implements +// the initial round, main round and final round logic for +// enciper operations. +// +// +// Author: Joachim Strombergson +// Copyright (c) 2013, 2014, Secworks Sweden AB +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or +// without modification, are permitted provided that the following +// conditions are met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in +// the documentation and/or other materials provided with the +// distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +//====================================================================== + +module doe_encipher_block( + input wire clk, + input wire reset_n, + input wire zeroize, + + input wire next_cmd, + + input wire keylen, + output wire [3 : 0] round, + input wire [127 : 0] round_key, + + output wire [31 : 0] sboxw, + input wire [31 : 0] new_sboxw, + + input wire [127 : 0] block_msg, + output wire [127 : 0] new_block, + output wire ready + ); + + + //---------------------------------------------------------------- + // Internal constant and parameter definitions. + //---------------------------------------------------------------- + //localparam DOE_128_BIT_KEY = 1'h0; + localparam DOE_256_BIT_KEY = 1'h1; + + localparam DOE128_ROUNDS = 4'ha; + localparam DOE256_ROUNDS = 4'he; + + localparam NO_UPDATE = 3'h0; + localparam INIT_UPDATE = 3'h1; + localparam SBOX_UPDATE = 3'h2; + localparam MAIN_UPDATE = 3'h3; + localparam FINAL_UPDATE = 3'h4; + + localparam CTRL_IDLE = 2'h0; + localparam CTRL_INIT = 2'h1; + localparam CTRL_SBOX = 2'h2; + localparam CTRL_MAIN = 2'h3; + + + //---------------------------------------------------------------- + // Round functions with sub functions. + //---------------------------------------------------------------- + function automatic [7 : 0] gm2(input [7 : 0] op); + begin + gm2 = {op[6 : 0], 1'b0} ^ (8'h1b & {8{op[7]}}); + end + endfunction // gm2 + + function automatic [7 : 0] gm3(input [7 : 0] op); + begin + gm3 = gm2(op) ^ op; + end + endfunction // gm3 + + function automatic [31 : 0] mixw(input [31 : 0] w_val); + reg [7 : 0] b0, b1, b2, b3; + reg [7 : 0] mb0, mb1, mb2, mb3; + begin + b0 = w_val[31 : 24]; + b1 = w_val[23 : 16]; + b2 = w_val[15 : 08]; + b3 = w_val[07 : 00]; + + mb0 = gm2(b0) ^ gm3(b1) ^ b2 ^ b3; + mb1 = b0 ^ gm2(b1) ^ gm3(b2) ^ b3; + mb2 = b0 ^ b1 ^ gm2(b2) ^ gm3(b3); + mb3 = gm3(b0) ^ b1 ^ b2 ^ gm2(b3); + + mixw = {mb0, mb1, mb2, mb3}; + end + endfunction // mixw + + function automatic [127 : 0] mixcolumns(input [127 : 0] data); + reg [31 : 0] w0, w1, w2, w3; + reg [31 : 0] ws0, ws1, ws2, ws3; + begin + w0 = data[127 : 096]; + w1 = data[095 : 064]; + w2 = data[063 : 032]; + w3 = data[031 : 000]; + + ws0 = mixw(w0); + ws1 = mixw(w1); + ws2 = mixw(w2); + ws3 = mixw(w3); + + mixcolumns = {ws0, ws1, ws2, ws3}; + end + endfunction // mixcolumns + + function automatic [127 : 0] shiftrows(input [127 : 0] data); + reg [31 : 0] w0, w1, w2, w3; + reg [31 : 0] ws0, ws1, ws2, ws3; + begin + w0 = data[127 : 096]; + w1 = data[095 : 064]; + w2 = data[063 : 032]; + w3 = data[031 : 000]; + + ws0 = {w0[31 : 24], w1[23 : 16], w2[15 : 08], w3[07 : 00]}; + ws1 = {w1[31 : 24], w2[23 : 16], w3[15 : 08], w0[07 : 00]}; + ws2 = {w2[31 : 24], w3[23 : 16], w0[15 : 08], w1[07 : 00]}; + ws3 = {w3[31 : 24], w0[23 : 16], w1[15 : 08], w2[07 : 00]}; + + shiftrows = {ws0, ws1, ws2, ws3}; + end + endfunction // shiftrows + + function automatic [127 : 0] addroundkey(input [127 : 0] data, input [127 : 0] rkey); + begin + addroundkey = data ^ rkey; + end + endfunction // addroundkey + + + //---------------------------------------------------------------- + // Registers including update variables and write enable. + //---------------------------------------------------------------- + reg [1 : 0] sword_ctr_reg; + reg [1 : 0] sword_ctr_new; + reg sword_ctr_we; + reg sword_ctr_inc; + reg sword_ctr_rst; + + reg [3 : 0] round_ctr_reg; + reg [3 : 0] round_ctr_new; + reg round_ctr_we; + reg round_ctr_rst; + reg round_ctr_inc; + + reg [127 : 0] block_new; + reg [31 : 0] block_w0_reg; + reg [31 : 0] block_w1_reg; + reg [31 : 0] block_w2_reg; + reg [31 : 0] block_w3_reg; + reg block_w0_we; + reg block_w1_we; + reg block_w2_we; + reg block_w3_we; + + reg ready_reg; + reg ready_new; + reg ready_we; + + reg [1 : 0] enc_ctrl_reg; + reg [1 : 0] enc_ctrl_new; + reg enc_ctrl_we; + + + //---------------------------------------------------------------- + // Wires. + //---------------------------------------------------------------- + reg [2 : 0] update_type; + reg [31 : 0] muxed_sboxw; + + + //---------------------------------------------------------------- + // Concurrent connectivity for ports etc. + //---------------------------------------------------------------- + assign round = round_ctr_reg; + assign sboxw = muxed_sboxw; + assign new_block = {block_w0_reg, block_w1_reg, block_w2_reg, block_w3_reg}; + assign ready = ready_reg; + + + //---------------------------------------------------------------- + // reg_update + // + // Update functionality for all registers in the core. + // All registers are positive edge triggered with asynchronous + // active low reset. All registers have write enable. + //---------------------------------------------------------------- + always @ (posedge clk or negedge reset_n) + begin: reg_update + if (!reset_n) + begin + block_w0_reg <= 32'h0; + block_w1_reg <= 32'h0; + block_w2_reg <= 32'h0; + block_w3_reg <= 32'h0; + sword_ctr_reg <= 2'h0; + round_ctr_reg <= 4'h0; + ready_reg <= 1'b1; + enc_ctrl_reg <= CTRL_IDLE; + end + else if (zeroize) + begin + block_w0_reg <= 32'h0; + block_w1_reg <= 32'h0; + block_w2_reg <= 32'h0; + block_w3_reg <= 32'h0; + sword_ctr_reg <= 2'h0; + round_ctr_reg <= 4'h0; + ready_reg <= 1'b1; + enc_ctrl_reg <= CTRL_IDLE; + end + else + begin + if (block_w0_we) + block_w0_reg <= block_new[127 : 096]; + + if (block_w1_we) + block_w1_reg <= block_new[095 : 064]; + + if (block_w2_we) + block_w2_reg <= block_new[063 : 032]; + + if (block_w3_we) + block_w3_reg <= block_new[031 : 000]; + + if (sword_ctr_we) + sword_ctr_reg <= sword_ctr_new; + + if (round_ctr_we) + round_ctr_reg <= round_ctr_new; + + if (ready_we) + ready_reg <= ready_new; + + if (enc_ctrl_we) + enc_ctrl_reg <= enc_ctrl_new; + end + end // reg_update + + + //---------------------------------------------------------------- + // round_logic + // + // The logic needed to implement init, main and final rounds. + //---------------------------------------------------------------- + always @* + begin : round_logic + reg [127 : 0] old_block, shiftrows_block, mixcolumns_block; + reg [127 : 0] addkey_init_block, addkey_main_block, addkey_final_block; + + block_new = 128'h0; + muxed_sboxw = 32'h0; + block_w0_we = 1'b0; + block_w1_we = 1'b0; + block_w2_we = 1'b0; + block_w3_we = 1'b0; + + old_block = {block_w0_reg, block_w1_reg, block_w2_reg, block_w3_reg}; + shiftrows_block = shiftrows(old_block); + mixcolumns_block = mixcolumns(shiftrows_block); + addkey_init_block = addroundkey(block_msg, round_key); + addkey_main_block = addroundkey(mixcolumns_block, round_key); + addkey_final_block = addroundkey(shiftrows_block, round_key); + + case (update_type) + INIT_UPDATE: + begin + block_new = addkey_init_block; + block_w0_we = 1'b1; + block_w1_we = 1'b1; + block_w2_we = 1'b1; + block_w3_we = 1'b1; + end + + SBOX_UPDATE: + begin + block_new = {new_sboxw, new_sboxw, new_sboxw, new_sboxw}; + + case (sword_ctr_reg) + 2'h0: + begin + muxed_sboxw = block_w0_reg; + block_w0_we = 1'b1; + end + + 2'h1: + begin + muxed_sboxw = block_w1_reg; + block_w1_we = 1'b1; + end + + 2'h2: + begin + muxed_sboxw = block_w2_reg; + block_w2_we = 1'b1; + end + + 2'h3: + begin + muxed_sboxw = block_w3_reg; + block_w3_we = 1'b1; + end + endcase // case (sbox_mux_ctrl_reg) + end + + MAIN_UPDATE: + begin + block_new = addkey_main_block; + block_w0_we = 1'b1; + block_w1_we = 1'b1; + block_w2_we = 1'b1; + block_w3_we = 1'b1; + end + + FINAL_UPDATE: + begin + block_new = addkey_final_block; + block_w0_we = 1'b1; + block_w1_we = 1'b1; + block_w2_we = 1'b1; + block_w3_we = 1'b1; + end + + default: + begin + block_new = 128'h0; + muxed_sboxw = 32'h0; + block_w0_we = 1'b0; + block_w1_we = 1'b0; + block_w2_we = 1'b0; + block_w3_we = 1'b0; + end + endcase // case (update_type) + end // round_logic + + + //---------------------------------------------------------------- + // sword_ctr + //Not all cases are covered in case statement: default case may be used + // The subbytes word counter with reset and increase logic. + //---------------------------------------------------------------- + always @* + begin : sword_ctr + sword_ctr_new = 2'h0; + sword_ctr_we = 1'b0; + + if (sword_ctr_rst) + begin + sword_ctr_new = 2'h0; + sword_ctr_we = 1'b1; + end + else if (sword_ctr_inc) + begin + sword_ctr_new = sword_ctr_reg + 1'b1; + sword_ctr_we = 1'b1; + end + end // sword_ctr + + + //---------------------------------------------------------------- + // round_ctr + // + // The round counter with reset and increase logic. + //---------------------------------------------------------------- + always @* + begin : round_ctr + round_ctr_new = 4'h0; + round_ctr_we = 1'b0; + + if (round_ctr_rst) + begin + round_ctr_new = 4'h0; + round_ctr_we = 1'b1; + end + else if (round_ctr_inc) + begin + round_ctr_new = round_ctr_reg + 1'b1; + round_ctr_we = 1'b1; + end + end // round_ctr + + + //---------------------------------------------------------------- + // encipher_ctrl + // + // The FSM that controls the encipher operations. + //---------------------------------------------------------------- + always @* + begin: encipher_ctrl + reg [3 : 0] num_rounds; + + // Default assignments. + sword_ctr_inc = 1'b0; + sword_ctr_rst = 1'b0; + round_ctr_inc = 1'b0; + round_ctr_rst = 1'b0; + ready_new = 1'b0; + ready_we = 1'b0; + update_type = NO_UPDATE; + enc_ctrl_new = CTRL_IDLE; + enc_ctrl_we = 1'b0; + + if (keylen == DOE_256_BIT_KEY) + begin + num_rounds = DOE256_ROUNDS; + end + else // keylen == DOE_128_BIT_KEY + begin + num_rounds = DOE128_ROUNDS; + end + + case (enc_ctrl_reg) + CTRL_IDLE: + begin + if (next_cmd) + begin + round_ctr_rst = 1'b1; + ready_new = 1'b0; + ready_we = 1'b1; + enc_ctrl_new = CTRL_INIT; + enc_ctrl_we = 1'b1; + end + end + + CTRL_INIT: + begin + round_ctr_inc = 1'b1; + sword_ctr_rst = 1'b1; + update_type = INIT_UPDATE; + enc_ctrl_new = CTRL_SBOX; + enc_ctrl_we = 1'b1; + end + + CTRL_SBOX: + begin + sword_ctr_inc = 1'b1; + update_type = SBOX_UPDATE; + if (sword_ctr_reg == 2'h3) + begin + enc_ctrl_new = CTRL_MAIN; + enc_ctrl_we = 1'b1; + end + end + + CTRL_MAIN: + begin + sword_ctr_rst = 1'b1; + round_ctr_inc = 1'b1; + if (round_ctr_reg < num_rounds) + begin + update_type = MAIN_UPDATE; + enc_ctrl_new = CTRL_SBOX; + enc_ctrl_we = 1'b1; + end + else + begin + update_type = FINAL_UPDATE; + ready_new = 1'b1; + ready_we = 1'b1; + enc_ctrl_new = CTRL_IDLE; + enc_ctrl_we = 1'b1; + end + end + + default: + begin + sword_ctr_inc = 1'b0; + sword_ctr_rst = 1'b0; + round_ctr_inc = 1'b0; + round_ctr_rst = 1'b0; + ready_new = 1'b0; + ready_we = 1'b0; + update_type = NO_UPDATE; + enc_ctrl_new = CTRL_IDLE; + enc_ctrl_we = 1'b0; + // Empty. Just here to make the synthesis tool happy. + end + endcase // case (enc_ctrl_reg) + end // encipher_ctrl + +endmodule // doe_encipher_block + +//====================================================================== +// EOF doe_encipher_block.v +//====================================================================== diff --git a/designs/Caliptra/src/caliptra-rtl/doe_fsm.sv b/designs/Caliptra/src/caliptra-rtl/doe_fsm.sv new file mode 100644 index 0000000..5cd8f23 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/doe_fsm.sv @@ -0,0 +1,314 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +// +//`include "kv_defines.svh" + +module doe_fsm + import doe_defines_pkg::*; + import kv_defines_pkg::*; + #( + parameter SRC_WIDTH = 128 + ,parameter DEST_WIDTH = 128 + //derived params don't change + ,localparam DEST_OFFSET_W = $clog2(DEST_WIDTH/32) + ,localparam DEST_NUM_DWORDS = (DEST_WIDTH/32) + ,localparam TOTAL_OBF_FE_BITS = `CLP_OBF_FE_DWORDS * 32 + ,localparam TOTAL_OBF_UDS_BITS = `CLP_OBF_UDS_DWORDS * 32 + ,localparam TOTAL_OBF_HEK_BITS = OCP_LOCK_HEK_NUM_DWORDS * 32 + ,localparam FE_NUM_BLOCKS = TOTAL_OBF_FE_BITS/SRC_WIDTH + ,localparam UDS_NUM_BLOCKS = TOTAL_OBF_UDS_BITS/SRC_WIDTH + ,localparam HEK_NUM_BLOCKS = TOTAL_OBF_HEK_BITS/SRC_WIDTH +) +( + input logic clk, + input logic rst_b, + input logic hard_rst_b, + + //Obfuscated UDS and FE + input logic [FE_NUM_BLOCKS-1:0][SRC_WIDTH-1:0] obf_field_entropy, + input logic [UDS_NUM_BLOCKS-1:0][SRC_WIDTH-1:0] obf_uds_seed, + input logic [HEK_NUM_BLOCKS-1:0][SRC_WIDTH-1:0] obf_hek_seed, + + //client control register + input doe_cmd_reg_t doe_cmd_reg, + input logic ocp_lock_en, + + //interface with kv + output kv_write_t kv_write, + + //interface with client + output logic src_write_en, + output logic [SRC_WIDTH-1:0] src_write_data, + + output logic doe_init, + output logic doe_next, + + input logic init_done, + input logic dest_data_avail, + input logic [DEST_NUM_DWORDS-1:0][31:0] dest_data, + + output logic flow_done, + output logic flow_error, + output logic flow_in_progress, + output logic lock_uds_flow, + output logic lock_fe_flow, + output logic lock_hek_flow, + input logic zeroize +); + +`define CLP_MAX_OF(a,b) ((a > b) ? a : b) + +localparam UDS_BLOCK_OFFSET_W = $clog2(UDS_NUM_BLOCKS); +localparam FE_BLOCK_OFFSET_W = $clog2(FE_NUM_BLOCKS); +localparam HEK_BLOCK_OFFSET_W = $clog2(HEK_NUM_BLOCKS); +localparam BLOCK_OFFSET_W = `CLP_MAX_OF(HEK_BLOCK_OFFSET_W, `CLP_MAX_OF(FE_BLOCK_OFFSET_W, UDS_BLOCK_OFFSET_W)); +localparam DEST_WR_OFFSET_W = $clog2(512/32); + +//declare fsm state variables +typedef enum logic [2:0] { + DOE_IDLE = 3'b000, + DOE_INIT = 3'b001, + DOE_BLOCK = 3'b011, + DOE_NEXT = 3'b010, + DOE_WAIT = 3'b110, + DOE_WRITE = 3'b100, + DOE_DONE = 3'b101 +} kv_doe_fsm_state_e; + +logic running_uds, running_fe, running_hek; + +//access filtering rule metrics +//NOTE: must be stabilized 1 clock cycle prior to dest_data_avail +kv_write_filter_metrics_t kv_write_metrics; +logic kv_write_allow; + +logic [KV_ENTRY_ADDR_W-1:0] dest_addr, dest_addr_nxt; +logic dest_addr_en; +logic [DEST_WR_OFFSET_W-1:0] dest_write_offset, dest_write_offset_nxt; +logic dest_write_offset_en; +logic dest_write_en; +logic dest_write_done; + +logic [BLOCK_OFFSET_W-1:0] block_offset, block_offset_nxt; +logic block_offset_en; +logic block_done; +logic zeroize_reg; + +kv_doe_fsm_state_e kv_doe_fsm_ps, kv_doe_fsm_ns; +logic arc_DOE_IDLE_DOE_INIT; +logic arc_DOE_WAIT_DOE_BLOCK; +logic arc_DOE_WAIT_DOE_WRITE; +logic arc_DOE_WRITE_DOE_BLOCK; +logic arc_DOE_WRITE_DOE_DONE; + +//zeroize input is a single pulse. However, when we detect zeroize, we'd like the fsm +//to remain in IDLE until next DOE_CMD is issued. To avoid other arcs moving the fsm +//to other states, extending zeroize to a level so we can keep the fsm in IDLE. When the +//next command is issued, this extended signal is reset and fsm advances. +always_ff @(posedge clk or negedge rst_b) begin + if (~rst_b) begin + zeroize_reg <= 0; + end + else if (zeroize) begin + zeroize_reg <= 1; + end + else if (running_uds || running_fe || running_hek) begin + zeroize_reg <= 0; + end +end + +always_comb running_uds = (doe_cmd_reg.cmd == DOE_UDS); +always_comb running_fe = (doe_cmd_reg.cmd == DOE_FE ); +always_comb running_hek = (doe_cmd_reg.cmd == DOE_HEK); +always_comb block_done = running_uds ? (block_offset == (UDS_NUM_BLOCKS-1)) : + running_hek ? (block_offset == (HEK_NUM_BLOCKS-1)) : + (block_offset == (FE_NUM_BLOCKS -1)) ; + +always_comb flow_in_progress = running_uds | running_fe | running_hek; +always_comb dest_write_done = (dest_write_offset[DEST_OFFSET_W-1:0] == (DEST_NUM_DWORDS-1)); + +//assign arc equations +//move to init state when command is set and that command isn't locked +always_comb arc_DOE_IDLE_DOE_INIT = (running_uds & ~lock_uds_flow) | + (running_fe & ~lock_fe_flow ) | + (running_hek & ~lock_hek_flow); +//wait to write when init is done and we have data to write +always_comb arc_DOE_WAIT_DOE_WRITE = init_done & dest_data_avail; +//wait to block when init is done and no data +always_comb arc_DOE_WAIT_DOE_BLOCK = init_done & ~dest_data_avail; +//done with this phase, but not done with the whole block +always_comb arc_DOE_WRITE_DOE_BLOCK = dest_write_done & ~block_done; +//done with this phase and the block is complete +always_comb arc_DOE_WRITE_DOE_DONE = dest_write_done & block_done; + +//state combo block +always_comb begin : kv_doe_fsm + kv_doe_fsm_ns = kv_doe_fsm_ps; + src_write_en = '0; + block_offset_nxt = block_offset; + block_offset_en = '0; + doe_init = '0; + doe_next = '0; + dest_write_en = '0; + dest_write_offset_en ='0; + dest_write_offset_nxt = dest_write_offset; + flow_done = '0; + flow_error = '0; + + unique case (kv_doe_fsm_ps) + DOE_IDLE: begin + if (arc_DOE_IDLE_DOE_INIT) kv_doe_fsm_ns = DOE_INIT; + //assert flow done if a locked flow is attempted + flow_done = (running_uds & lock_uds_flow) | (running_fe & lock_fe_flow) | (running_hek & lock_hek_flow); + end + DOE_INIT: begin + kv_doe_fsm_ns = DOE_WAIT; + doe_init = '1; + end + DOE_BLOCK: begin + kv_doe_fsm_ns = DOE_NEXT; + src_write_en = '1; + end + DOE_NEXT: begin + kv_doe_fsm_ns = DOE_WAIT; + doe_next = '1; + end + DOE_WAIT: begin + if (arc_DOE_WAIT_DOE_WRITE) kv_doe_fsm_ns = DOE_WRITE; + else if (arc_DOE_WAIT_DOE_BLOCK) kv_doe_fsm_ns = DOE_BLOCK; + end + DOE_WRITE: begin + dest_write_en = kv_write_allow; // If rule-check fails, no data is written to KV and FSM hangs in this state + //increment dest offset each clock, clear when done + dest_write_offset_en = kv_write_allow; + dest_write_offset_nxt = dest_write_offset + 'd1; + flow_error = !kv_write_allow; + + //go back to idle if dest done, and done with blocks + if (arc_DOE_WRITE_DOE_DONE) kv_doe_fsm_ns = DOE_DONE; + //go back to block stage for next block if not done with blocks + else if (arc_DOE_WRITE_DOE_BLOCK) begin + kv_doe_fsm_ns = DOE_BLOCK; + //increment the block offset each time we write a block + block_offset_en = '1; + block_offset_nxt = block_offset + 'd1; + end + end + DOE_DONE: begin + kv_doe_fsm_ns = DOE_IDLE; + flow_done = '1; + //clear block and write offsets when we go back to idle + block_offset_en = '1; + block_offset_nxt = '0; + dest_write_offset_en = '1; + dest_write_offset_nxt = '0; + end + default: begin + kv_doe_fsm_ns = kv_doe_fsm_ps; + src_write_en = '0; + block_offset_nxt = block_offset; + block_offset_en = '0; + doe_init = '0; + doe_next = '0; + dest_write_en = '0; + dest_write_offset_en ='0; + dest_write_offset_nxt = dest_write_offset; + flow_done = '0; + flow_error = '0; + end + endcase +end + +//latch the dest addr when starting, and when we roll over dest offset +always_comb dest_addr_en = ((kv_doe_fsm_ps == DOE_IDLE) & arc_DOE_IDLE_DOE_INIT); +always_comb dest_addr_nxt = doe_cmd_reg.dest_sel; + +// check KV filtering rules +// Use the strap ocp_lock_en instead of the register ocp_lock_in_progress because DOE +// is a ROM flow and occurs prior to setting the register +always_comb begin + `ifdef CALIPTRA_MODE_SUBSYSTEM + kv_write_metrics.ocp_lock_in_progress = ocp_lock_en; + `else + kv_write_metrics.ocp_lock_in_progress = 1'b0; + `endif + kv_write_metrics.kv_data0_present = 1'b0; + kv_write_metrics.kv_data0_entry = '0; + kv_write_metrics.kv_data1_present = 1'b0; + kv_write_metrics.kv_data1_entry = '0; + kv_write_metrics.kv_write_src = KV_NUM_WRITE'(1 << KV_WRITE_IDX_DOE); + kv_write_metrics.kv_write_entry = dest_addr; + kv_write_metrics.aes_decrypt_ecb_op = 1'b0; +end + +// Output kv_write_allow will stabilize by first entry to DOE_WAIT +kv_write_rule_check kv_write_rules +( + .clk (clk ), + .rst_b(rst_b), + + .write_metrics(kv_write_metrics), + .write_allow (kv_write_allow ) +); + +//drive outputs to kv +always_comb kv_write.write_en = dest_write_en; +always_comb kv_write.write_offset = dest_write_offset; +always_comb kv_write.write_dest_valid = running_hek ? OCP_LOCK_HEK_SEED_DEST_VALID : 'd3; //FIXME tie off dest valid, or let FW program? +always_comb kv_write.write_entry = dest_addr; +//swizzle big endian result to little endian storage +always_comb kv_write.write_data = dest_write_en ? dest_data[(DEST_NUM_DWORDS-1) - dest_write_offset[DEST_OFFSET_W-1:0]] : '0; + +//pick among uds, fe, hek based on command +always_comb src_write_data = running_uds ? obf_uds_seed[block_offset[UDS_BLOCK_OFFSET_W-1:0]] : + running_fe ? obf_field_entropy[block_offset[FE_BLOCK_OFFSET_W-1:0]] : + running_hek ? obf_hek_seed[block_offset[HEK_BLOCK_OFFSET_W-1:0]] : '0; + +//state flops +always_ff @(posedge clk or negedge rst_b) begin + if (~rst_b) begin + kv_doe_fsm_ps <= DOE_IDLE; + dest_write_offset <= '0; + block_offset <= '0; + dest_addr <= '0; + end + else if (zeroize_reg) begin + kv_doe_fsm_ps <= DOE_IDLE; + dest_write_offset <= '0; + block_offset <= '0; + dest_addr <= '0; + end + else begin + kv_doe_fsm_ps <= kv_doe_fsm_ns; + dest_write_offset <= dest_write_offset_en ? dest_write_offset_nxt : dest_write_offset; + block_offset <= block_offset_en ? block_offset_nxt : block_offset; + dest_addr <= dest_addr_en ? dest_addr_nxt : dest_addr; + end +end + +//sticky flops for locking UDS/FE/HEK flow after execution +always_ff @(posedge clk or negedge hard_rst_b) begin + if (~hard_rst_b) begin + lock_uds_flow <= '0; + lock_fe_flow <= '0; + lock_hek_flow <= '0; + end + else begin + lock_uds_flow <= running_uds & flow_done ? '1 : lock_uds_flow; + lock_fe_flow <= running_fe & flow_done ? '1 : lock_fe_flow; + lock_hek_flow <= running_hek & flow_done ? '1 : lock_hek_flow; + end +end + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/doe_inv_sbox.sv b/designs/Caliptra/src/caliptra-rtl/doe_inv_sbox.sv new file mode 100644 index 0000000..46e197e --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/doe_inv_sbox.sv @@ -0,0 +1,323 @@ +//====================================================================== +// +// doe_inv_sbox.v +// -------------- +// The inverse DOE S-box. Basically a 256 Byte ROM. +// +// +// Copyright (c) 2013 Secworks Sweden AB +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or +// without modification, are permitted provided that the following +// conditions are met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in +// the documentation and/or other materials provided with the +// distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +//====================================================================== + +module doe_inv_sbox( + input wire [31 : 0] sboxw, + output wire [31 : 0] new_sboxw + ); + + + //---------------------------------------------------------------- + // The inverse sbox array. + //---------------------------------------------------------------- + wire [7 : 0] inv_sbox [255 : 0]; + + + //---------------------------------------------------------------- + // Four parallel muxes. + //---------------------------------------------------------------- + assign new_sboxw[31 : 24] = inv_sbox[sboxw[31 : 24]]; + assign new_sboxw[23 : 16] = inv_sbox[sboxw[23 : 16]]; + assign new_sboxw[15 : 08] = inv_sbox[sboxw[15 : 08]]; + assign new_sboxw[07 : 00] = inv_sbox[sboxw[07 : 00]]; + + + //---------------------------------------------------------------- + // Creating the contents of the array. + //---------------------------------------------------------------- + assign inv_sbox[8'h00] = 8'h52; + assign inv_sbox[8'h01] = 8'h09; + assign inv_sbox[8'h02] = 8'h6a; + assign inv_sbox[8'h03] = 8'hd5; + assign inv_sbox[8'h04] = 8'h30; + assign inv_sbox[8'h05] = 8'h36; + assign inv_sbox[8'h06] = 8'ha5; + assign inv_sbox[8'h07] = 8'h38; + assign inv_sbox[8'h08] = 8'hbf; + assign inv_sbox[8'h09] = 8'h40; + assign inv_sbox[8'h0a] = 8'ha3; + assign inv_sbox[8'h0b] = 8'h9e; + assign inv_sbox[8'h0c] = 8'h81; + assign inv_sbox[8'h0d] = 8'hf3; + assign inv_sbox[8'h0e] = 8'hd7; + assign inv_sbox[8'h0f] = 8'hfb; + assign inv_sbox[8'h10] = 8'h7c; + assign inv_sbox[8'h11] = 8'he3; + assign inv_sbox[8'h12] = 8'h39; + assign inv_sbox[8'h13] = 8'h82; + assign inv_sbox[8'h14] = 8'h9b; + assign inv_sbox[8'h15] = 8'h2f; + assign inv_sbox[8'h16] = 8'hff; + assign inv_sbox[8'h17] = 8'h87; + assign inv_sbox[8'h18] = 8'h34; + assign inv_sbox[8'h19] = 8'h8e; + assign inv_sbox[8'h1a] = 8'h43; + assign inv_sbox[8'h1b] = 8'h44; + assign inv_sbox[8'h1c] = 8'hc4; + assign inv_sbox[8'h1d] = 8'hde; + assign inv_sbox[8'h1e] = 8'he9; + assign inv_sbox[8'h1f] = 8'hcb; + assign inv_sbox[8'h20] = 8'h54; + assign inv_sbox[8'h21] = 8'h7b; + assign inv_sbox[8'h22] = 8'h94; + assign inv_sbox[8'h23] = 8'h32; + assign inv_sbox[8'h24] = 8'ha6; + assign inv_sbox[8'h25] = 8'hc2; + assign inv_sbox[8'h26] = 8'h23; + assign inv_sbox[8'h27] = 8'h3d; + assign inv_sbox[8'h28] = 8'hee; + assign inv_sbox[8'h29] = 8'h4c; + assign inv_sbox[8'h2a] = 8'h95; + assign inv_sbox[8'h2b] = 8'h0b; + assign inv_sbox[8'h2c] = 8'h42; + assign inv_sbox[8'h2d] = 8'hfa; + assign inv_sbox[8'h2e] = 8'hc3; + assign inv_sbox[8'h2f] = 8'h4e; + assign inv_sbox[8'h30] = 8'h08; + assign inv_sbox[8'h31] = 8'h2e; + assign inv_sbox[8'h32] = 8'ha1; + assign inv_sbox[8'h33] = 8'h66; + assign inv_sbox[8'h34] = 8'h28; + assign inv_sbox[8'h35] = 8'hd9; + assign inv_sbox[8'h36] = 8'h24; + assign inv_sbox[8'h37] = 8'hb2; + assign inv_sbox[8'h38] = 8'h76; + assign inv_sbox[8'h39] = 8'h5b; + assign inv_sbox[8'h3a] = 8'ha2; + assign inv_sbox[8'h3b] = 8'h49; + assign inv_sbox[8'h3c] = 8'h6d; + assign inv_sbox[8'h3d] = 8'h8b; + assign inv_sbox[8'h3e] = 8'hd1; + assign inv_sbox[8'h3f] = 8'h25; + assign inv_sbox[8'h40] = 8'h72; + assign inv_sbox[8'h41] = 8'hf8; + assign inv_sbox[8'h42] = 8'hf6; + assign inv_sbox[8'h43] = 8'h64; + assign inv_sbox[8'h44] = 8'h86; + assign inv_sbox[8'h45] = 8'h68; + assign inv_sbox[8'h46] = 8'h98; + assign inv_sbox[8'h47] = 8'h16; + assign inv_sbox[8'h48] = 8'hd4; + assign inv_sbox[8'h49] = 8'ha4; + assign inv_sbox[8'h4a] = 8'h5c; + assign inv_sbox[8'h4b] = 8'hcc; + assign inv_sbox[8'h4c] = 8'h5d; + assign inv_sbox[8'h4d] = 8'h65; + assign inv_sbox[8'h4e] = 8'hb6; + assign inv_sbox[8'h4f] = 8'h92; + assign inv_sbox[8'h50] = 8'h6c; + assign inv_sbox[8'h51] = 8'h70; + assign inv_sbox[8'h52] = 8'h48; + assign inv_sbox[8'h53] = 8'h50; + assign inv_sbox[8'h54] = 8'hfd; + assign inv_sbox[8'h55] = 8'hed; + assign inv_sbox[8'h56] = 8'hb9; + assign inv_sbox[8'h57] = 8'hda; + assign inv_sbox[8'h58] = 8'h5e; + assign inv_sbox[8'h59] = 8'h15; + assign inv_sbox[8'h5a] = 8'h46; + assign inv_sbox[8'h5b] = 8'h57; + assign inv_sbox[8'h5c] = 8'ha7; + assign inv_sbox[8'h5d] = 8'h8d; + assign inv_sbox[8'h5e] = 8'h9d; + assign inv_sbox[8'h5f] = 8'h84; + assign inv_sbox[8'h60] = 8'h90; + assign inv_sbox[8'h61] = 8'hd8; + assign inv_sbox[8'h62] = 8'hab; + assign inv_sbox[8'h63] = 8'h00; + assign inv_sbox[8'h64] = 8'h8c; + assign inv_sbox[8'h65] = 8'hbc; + assign inv_sbox[8'h66] = 8'hd3; + assign inv_sbox[8'h67] = 8'h0a; + assign inv_sbox[8'h68] = 8'hf7; + assign inv_sbox[8'h69] = 8'he4; + assign inv_sbox[8'h6a] = 8'h58; + assign inv_sbox[8'h6b] = 8'h05; + assign inv_sbox[8'h6c] = 8'hb8; + assign inv_sbox[8'h6d] = 8'hb3; + assign inv_sbox[8'h6e] = 8'h45; + assign inv_sbox[8'h6f] = 8'h06; + assign inv_sbox[8'h70] = 8'hd0; + assign inv_sbox[8'h71] = 8'h2c; + assign inv_sbox[8'h72] = 8'h1e; + assign inv_sbox[8'h73] = 8'h8f; + assign inv_sbox[8'h74] = 8'hca; + assign inv_sbox[8'h75] = 8'h3f; + assign inv_sbox[8'h76] = 8'h0f; + assign inv_sbox[8'h77] = 8'h02; + assign inv_sbox[8'h78] = 8'hc1; + assign inv_sbox[8'h79] = 8'haf; + assign inv_sbox[8'h7a] = 8'hbd; + assign inv_sbox[8'h7b] = 8'h03; + assign inv_sbox[8'h7c] = 8'h01; + assign inv_sbox[8'h7d] = 8'h13; + assign inv_sbox[8'h7e] = 8'h8a; + assign inv_sbox[8'h7f] = 8'h6b; + assign inv_sbox[8'h80] = 8'h3a; + assign inv_sbox[8'h81] = 8'h91; + assign inv_sbox[8'h82] = 8'h11; + assign inv_sbox[8'h83] = 8'h41; + assign inv_sbox[8'h84] = 8'h4f; + assign inv_sbox[8'h85] = 8'h67; + assign inv_sbox[8'h86] = 8'hdc; + assign inv_sbox[8'h87] = 8'hea; + assign inv_sbox[8'h88] = 8'h97; + assign inv_sbox[8'h89] = 8'hf2; + assign inv_sbox[8'h8a] = 8'hcf; + assign inv_sbox[8'h8b] = 8'hce; + assign inv_sbox[8'h8c] = 8'hf0; + assign inv_sbox[8'h8d] = 8'hb4; + assign inv_sbox[8'h8e] = 8'he6; + assign inv_sbox[8'h8f] = 8'h73; + assign inv_sbox[8'h90] = 8'h96; + assign inv_sbox[8'h91] = 8'hac; + assign inv_sbox[8'h92] = 8'h74; + assign inv_sbox[8'h93] = 8'h22; + assign inv_sbox[8'h94] = 8'he7; + assign inv_sbox[8'h95] = 8'had; + assign inv_sbox[8'h96] = 8'h35; + assign inv_sbox[8'h97] = 8'h85; + assign inv_sbox[8'h98] = 8'he2; + assign inv_sbox[8'h99] = 8'hf9; + assign inv_sbox[8'h9a] = 8'h37; + assign inv_sbox[8'h9b] = 8'he8; + assign inv_sbox[8'h9c] = 8'h1c; + assign inv_sbox[8'h9d] = 8'h75; + assign inv_sbox[8'h9e] = 8'hdf; + assign inv_sbox[8'h9f] = 8'h6e; + assign inv_sbox[8'ha0] = 8'h47; + assign inv_sbox[8'ha1] = 8'hf1; + assign inv_sbox[8'ha2] = 8'h1a; + assign inv_sbox[8'ha3] = 8'h71; + assign inv_sbox[8'ha4] = 8'h1d; + assign inv_sbox[8'ha5] = 8'h29; + assign inv_sbox[8'ha6] = 8'hc5; + assign inv_sbox[8'ha7] = 8'h89; + assign inv_sbox[8'ha8] = 8'h6f; + assign inv_sbox[8'ha9] = 8'hb7; + assign inv_sbox[8'haa] = 8'h62; + assign inv_sbox[8'hab] = 8'h0e; + assign inv_sbox[8'hac] = 8'haa; + assign inv_sbox[8'had] = 8'h18; + assign inv_sbox[8'hae] = 8'hbe; + assign inv_sbox[8'haf] = 8'h1b; + assign inv_sbox[8'hb0] = 8'hfc; + assign inv_sbox[8'hb1] = 8'h56; + assign inv_sbox[8'hb2] = 8'h3e; + assign inv_sbox[8'hb3] = 8'h4b; + assign inv_sbox[8'hb4] = 8'hc6; + assign inv_sbox[8'hb5] = 8'hd2; + assign inv_sbox[8'hb6] = 8'h79; + assign inv_sbox[8'hb7] = 8'h20; + assign inv_sbox[8'hb8] = 8'h9a; + assign inv_sbox[8'hb9] = 8'hdb; + assign inv_sbox[8'hba] = 8'hc0; + assign inv_sbox[8'hbb] = 8'hfe; + assign inv_sbox[8'hbc] = 8'h78; + assign inv_sbox[8'hbd] = 8'hcd; + assign inv_sbox[8'hbe] = 8'h5a; + assign inv_sbox[8'hbf] = 8'hf4; + assign inv_sbox[8'hc0] = 8'h1f; + assign inv_sbox[8'hc1] = 8'hdd; + assign inv_sbox[8'hc2] = 8'ha8; + assign inv_sbox[8'hc3] = 8'h33; + assign inv_sbox[8'hc4] = 8'h88; + assign inv_sbox[8'hc5] = 8'h07; + assign inv_sbox[8'hc6] = 8'hc7; + assign inv_sbox[8'hc7] = 8'h31; + assign inv_sbox[8'hc8] = 8'hb1; + assign inv_sbox[8'hc9] = 8'h12; + assign inv_sbox[8'hca] = 8'h10; + assign inv_sbox[8'hcb] = 8'h59; + assign inv_sbox[8'hcc] = 8'h27; + assign inv_sbox[8'hcd] = 8'h80; + assign inv_sbox[8'hce] = 8'hec; + assign inv_sbox[8'hcf] = 8'h5f; + assign inv_sbox[8'hd0] = 8'h60; + assign inv_sbox[8'hd1] = 8'h51; + assign inv_sbox[8'hd2] = 8'h7f; + assign inv_sbox[8'hd3] = 8'ha9; + assign inv_sbox[8'hd4] = 8'h19; + assign inv_sbox[8'hd5] = 8'hb5; + assign inv_sbox[8'hd6] = 8'h4a; + assign inv_sbox[8'hd7] = 8'h0d; + assign inv_sbox[8'hd8] = 8'h2d; + assign inv_sbox[8'hd9] = 8'he5; + assign inv_sbox[8'hda] = 8'h7a; + assign inv_sbox[8'hdb] = 8'h9f; + assign inv_sbox[8'hdc] = 8'h93; + assign inv_sbox[8'hdd] = 8'hc9; + assign inv_sbox[8'hde] = 8'h9c; + assign inv_sbox[8'hdf] = 8'hef; + assign inv_sbox[8'he0] = 8'ha0; + assign inv_sbox[8'he1] = 8'he0; + assign inv_sbox[8'he2] = 8'h3b; + assign inv_sbox[8'he3] = 8'h4d; + assign inv_sbox[8'he4] = 8'hae; + assign inv_sbox[8'he5] = 8'h2a; + assign inv_sbox[8'he6] = 8'hf5; + assign inv_sbox[8'he7] = 8'hb0; + assign inv_sbox[8'he8] = 8'hc8; + assign inv_sbox[8'he9] = 8'heb; + assign inv_sbox[8'hea] = 8'hbb; + assign inv_sbox[8'heb] = 8'h3c; + assign inv_sbox[8'hec] = 8'h83; + assign inv_sbox[8'hed] = 8'h53; + assign inv_sbox[8'hee] = 8'h99; + assign inv_sbox[8'hef] = 8'h61; + assign inv_sbox[8'hf0] = 8'h17; + assign inv_sbox[8'hf1] = 8'h2b; + assign inv_sbox[8'hf2] = 8'h04; + assign inv_sbox[8'hf3] = 8'h7e; + assign inv_sbox[8'hf4] = 8'hba; + assign inv_sbox[8'hf5] = 8'h77; + assign inv_sbox[8'hf6] = 8'hd6; + assign inv_sbox[8'hf7] = 8'h26; + assign inv_sbox[8'hf8] = 8'he1; + assign inv_sbox[8'hf9] = 8'h69; + assign inv_sbox[8'hfa] = 8'h14; + assign inv_sbox[8'hfb] = 8'h63; + assign inv_sbox[8'hfc] = 8'h55; + assign inv_sbox[8'hfd] = 8'h21; + assign inv_sbox[8'hfe] = 8'h0c; + assign inv_sbox[8'hff] = 8'h7d; + +endmodule // doe_inv_sbox + +//====================================================================== +// EOF doe_inv_sbox.v +//====================================================================== diff --git a/designs/Caliptra/src/caliptra-rtl/doe_key_mem.sv b/designs/Caliptra/src/caliptra-rtl/doe_key_mem.sv new file mode 100644 index 0000000..7b2100e --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/doe_key_mem.sv @@ -0,0 +1,465 @@ +//====================================================================== +// +// doe_key_mem.v +// ------------- +// The DOE key memory including round key generator. +// +// +// Author: Joachim Strombergson +// Copyright (c) 2013 Secworks Sweden AB +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or +// without modification, are permitted provided that the following +// conditions are met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in +// the documentation and/or other materials provided with the +// distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +//====================================================================== + +module doe_key_mem( + input wire clk, + input wire reset_n, + input wire zeroize, + + input wire [255 : 0] key, + input wire keylen, + input wire init_cmd, + + input wire [3 : 0] round, + output wire [127 : 0] round_key, + output wire ready, + + + output wire [31 : 0] sboxw, + input wire [31 : 0] new_sboxw + ); + + + //---------------------------------------------------------------- + // Parameters. + //---------------------------------------------------------------- + localparam DOE_128_BIT_KEY = 1'h0; + localparam DOE_256_BIT_KEY = 1'h1; + + localparam DOE_128_NUM_ROUNDS = 10; + localparam DOE_256_NUM_ROUNDS = 14; + + localparam CTRL_IDLE = 3'h0; + localparam CTRL_INIT = 3'h1; + localparam CTRL_GENERATE = 3'h2; + localparam CTRL_DONE = 3'h3; + + + //---------------------------------------------------------------- + // Registers. + //---------------------------------------------------------------- + reg [127 : 0] key_mem [14 : 0]; + reg [127 : 0] key_mem_new; + reg key_mem_we; + + reg [127 : 0] prev_key0_reg; + reg [127 : 0] prev_key0_new; + reg prev_key0_we; + + reg [127 : 0] prev_key1_reg; + reg [127 : 0] prev_key1_new; + reg prev_key1_we; + + reg [3 : 0] round_ctr_reg; + reg [3 : 0] round_ctr_new; + reg round_ctr_rst; + reg round_ctr_inc; + reg round_ctr_we; + + reg [2 : 0] key_mem_ctrl_reg; + reg [2 : 0] key_mem_ctrl_new; + reg key_mem_ctrl_we; + + reg ready_reg; + reg ready_new; + reg ready_we; + + reg [7 : 0] rcon_reg; + reg [7 : 0] rcon_new; + reg rcon_we; + reg rcon_set; + reg rcon_next; + + + //---------------------------------------------------------------- + // Wires. + //---------------------------------------------------------------- + reg [31 : 0] tmp_sboxw; + reg round_key_update; + reg [127 : 0] tmp_round_key; + + + //---------------------------------------------------------------- + // Concurrent assignments for ports. + //---------------------------------------------------------------- + assign round_key = tmp_round_key; + assign ready = ready_reg; + assign sboxw = tmp_sboxw; + + + //---------------------------------------------------------------- + // reg_update + // + // Update functionality for all registers in the core. + // All registers are positive edge triggered with asynchronous + // active low reset. All registers have write enable. + //---------------------------------------------------------------- + always @ (posedge clk or negedge reset_n) + begin: reg_update + integer ii; + + if (!reset_n) + begin + for (ii = 0 ; ii <= DOE_256_NUM_ROUNDS ; ii = ii + 1) + key_mem [ii] <= 128'h0; + + ready_reg <= 1'b0; + rcon_reg <= 8'h0; + round_ctr_reg <= 4'h0; + prev_key0_reg <= 128'h0; + prev_key1_reg <= 128'h0; + key_mem_ctrl_reg <= CTRL_IDLE; + end + else if (zeroize) + begin + for (ii = 0 ; ii <= DOE_256_NUM_ROUNDS ; ii = ii + 1) + key_mem [ii] <= 128'h0; + + ready_reg <= 1'b0; + rcon_reg <= 8'h0; + round_ctr_reg <= 4'h0; + prev_key0_reg <= 128'h0; + prev_key1_reg <= 128'h0; + key_mem_ctrl_reg <= CTRL_IDLE; + end + else + begin + if (ready_we) + ready_reg <= ready_new; + + if (rcon_we) + rcon_reg <= rcon_new; + + if (key_mem_we) + key_mem[round_ctr_reg] <= key_mem_new; + + if (round_ctr_we) + round_ctr_reg <= round_ctr_new; + + if (prev_key0_we) + prev_key0_reg <= prev_key0_new; + + if (prev_key1_we) + prev_key1_reg <= prev_key1_new; + + if (key_mem_ctrl_we) + key_mem_ctrl_reg <= key_mem_ctrl_new; + end + end // reg_update + + + //---------------------------------------------------------------- + // key_mem_read + // + // Combinational read port for the key memory. + //---------------------------------------------------------------- + always @* + begin : key_mem_read + tmp_round_key = key_mem[round]; + end // key_mem_read + + + //---------------------------------------------------------------- + // round_key_gen + // + // The round key generator logic for DOE-128 and DOE-256. + //---------------------------------------------------------------- + always @* + begin: round_key_gen + reg [31 : 0] w0, w1, w2, w3, w4, w5, w6, w7; + reg [31 : 0] k0, k1, k2, k3; + reg [31 : 0] rconw, rotstw, tw, trw; + + // Default assignments. + key_mem_new = 128'h0; + key_mem_we = 1'b0; + prev_key0_new = 128'h0; + prev_key0_we = 1'b0; + prev_key1_new = 128'h0; + prev_key1_we = 1'b0; + + k0 = 32'h0; + k1 = 32'h0; + k2 = 32'h0; + k3 = 32'h0; + + rcon_set = 1'b1; + rcon_next = 1'b0; + + // Extract words and calculate intermediate values. + // Perform rotation of sbox word etc. + w0 = prev_key0_reg[127 : 096]; + w1 = prev_key0_reg[095 : 064]; + w2 = prev_key0_reg[063 : 032]; + w3 = prev_key0_reg[031 : 000]; + + w4 = prev_key1_reg[127 : 096]; + w5 = prev_key1_reg[095 : 064]; + w6 = prev_key1_reg[063 : 032]; + w7 = prev_key1_reg[031 : 000]; + + rconw = {rcon_reg, 24'h0}; + tmp_sboxw = w7; + rotstw = {new_sboxw[23 : 00], new_sboxw[31 : 24]}; + trw = rotstw ^ rconw; + tw = new_sboxw; + + // Generate the specific round keys. + if (round_key_update) + begin + rcon_set = 1'b0; + key_mem_we = 1'b1; + case (keylen) + DOE_128_BIT_KEY: + begin + if (round_ctr_reg == 0) + begin + key_mem_new = key[255 : 128]; + prev_key1_new = key[255 : 128]; + prev_key1_we = 1'b1; + rcon_next = 1'b1; + end + else + begin + k0 = w4 ^ trw; + k1 = w5 ^ w4 ^ trw; + k2 = w6 ^ w5 ^ w4 ^ trw; + k3 = w7 ^ w6 ^ w5 ^ w4 ^ trw; + + key_mem_new = {k0, k1, k2, k3}; + prev_key1_new = {k0, k1, k2, k3}; + prev_key1_we = 1'b1; + rcon_next = 1'b1; + end + end + + DOE_256_BIT_KEY: + begin + if (round_ctr_reg == 0) + begin + key_mem_new = key[255 : 128]; + prev_key0_new = key[255 : 128]; + prev_key0_we = 1'b1; + end + else if (round_ctr_reg == 1) + begin + key_mem_new = key[127 : 0]; + prev_key1_new = key[127 : 0]; + prev_key1_we = 1'b1; + rcon_next = 1'b1; + end + else + begin + if (round_ctr_reg[0] == 0) + begin + k0 = w0 ^ trw; + k1 = w1 ^ w0 ^ trw; + k2 = w2 ^ w1 ^ w0 ^ trw; + k3 = w3 ^ w2 ^ w1 ^ w0 ^ trw; + end + else + begin + k0 = w0 ^ tw; + k1 = w1 ^ w0 ^ tw; + k2 = w2 ^ w1 ^ w0 ^ tw; + k3 = w3 ^ w2 ^ w1 ^ w0 ^ tw; + rcon_next = 1'b1; + end + + // Store the generated round keys. + key_mem_new = {k0, k1, k2, k3}; + prev_key1_new = {k0, k1, k2, k3}; + prev_key1_we = 1'b1; + prev_key0_new = prev_key1_reg; + prev_key0_we = 1'b1; + end + end + + default: + begin + key_mem_new = 128'h0; + key_mem_we = 1'b0; + prev_key0_new = 128'h0; + prev_key0_we = 1'b0; + prev_key1_new = 128'h0; + prev_key1_we = 1'b0; + + k0 = 32'h0; + k1 = 32'h0; + k2 = 32'h0; + k3 = 32'h0; + + rcon_set = 1'b1; + rcon_next = 1'b0; + end + endcase // case (keylen) + end + end // round_key_gen + + + //---------------------------------------------------------------- + // rcon_logic + // + // Caclulates the rcon value for the different key expansion + // iterations. + //---------------------------------------------------------------- + always @* + begin : rcon_logic + reg [7 : 0] tmp_rcon; + rcon_new = 8'h00; + rcon_we = 1'b0; + + tmp_rcon = {rcon_reg[6 : 0], 1'b0} ^ (8'h1b & {8{rcon_reg[7]}}); + + if (rcon_set) + begin + rcon_new = 8'h8d; + rcon_we = 1'b1; + end + else if (rcon_next) + begin + rcon_new = tmp_rcon; + rcon_we = 1'b1; + end + end + + + //---------------------------------------------------------------- + // round_ctr + // + // The round counter logic with increase and reset. + //---------------------------------------------------------------- + always @* + begin : round_ctr + round_ctr_new = 4'h0; + round_ctr_we = 1'b0; + + if (round_ctr_rst) + begin + round_ctr_new = 4'h0; + round_ctr_we = 1'b1; + end + + else if (round_ctr_inc) + begin + round_ctr_new = round_ctr_reg + 1'b1; + round_ctr_we = 1'b1; + end + end + + + //---------------------------------------------------------------- + // key_mem_ctrl + // + // + // The FSM that controls the round key generation. + //---------------------------------------------------------------- + always @* + begin: key_mem_ctrl + reg [3 : 0] num_rounds; + + // Default assignments. + ready_new = 1'b0; + ready_we = 1'b0; + round_key_update = 1'b0; + round_ctr_rst = 1'b0; + round_ctr_inc = 1'b0; + key_mem_ctrl_new = CTRL_IDLE; + key_mem_ctrl_we = 1'b0; + + if (keylen == DOE_128_BIT_KEY) + num_rounds = DOE_128_NUM_ROUNDS; + else + num_rounds = DOE_256_NUM_ROUNDS; + + case (key_mem_ctrl_reg) + CTRL_IDLE: + begin + if (init_cmd) + begin + ready_new = 1'b0; + ready_we = 1'b1; + key_mem_ctrl_new = CTRL_INIT; + key_mem_ctrl_we = 1'b1; + end + end + + CTRL_INIT: + begin + round_ctr_rst = 1'b1; + key_mem_ctrl_new = CTRL_GENERATE; + key_mem_ctrl_we = 1'b1; + end + + CTRL_GENERATE: + begin + round_ctr_inc = 1'b1; + round_key_update = 1'b1; + if (round_ctr_reg == num_rounds) + begin + key_mem_ctrl_new = CTRL_DONE; + key_mem_ctrl_we = 1'b1; + end + end + + CTRL_DONE: + begin + ready_new = 1'b1; + ready_we = 1'b1; + key_mem_ctrl_new = CTRL_IDLE; + key_mem_ctrl_we = 1'b1; + end + + default: + begin + ready_new = 1'b0; + ready_we = 1'b0; + round_key_update = 1'b0; + round_ctr_rst = 1'b0; + round_ctr_inc = 1'b0; + key_mem_ctrl_new = CTRL_IDLE; + key_mem_ctrl_we = 1'b0; + end + endcase // case (key_mem_ctrl_reg) + + end // key_mem_ctrl +endmodule // doe_key_mem + +//====================================================================== +// EOF doe_key_mem.v +//====================================================================== diff --git a/designs/Caliptra/src/caliptra-rtl/doe_reg.sv b/designs/Caliptra/src/caliptra-rtl/doe_reg.sv new file mode 100644 index 0000000..8304eea --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/doe_reg.sv @@ -0,0 +1,1557 @@ +// Generated by PeakRDL-regblock - A free and open-source SystemVerilog generator +// https://github.com/SystemRDL/PeakRDL-regblock + +module doe_reg ( + input wire clk, + input wire rst, + + input wire s_cpuif_req, + input wire s_cpuif_req_is_wr, + input wire [11:0] s_cpuif_addr, + input wire [31:0] s_cpuif_wr_data, + input wire [31:0] s_cpuif_wr_biten, + output wire s_cpuif_req_stall_wr, + output wire s_cpuif_req_stall_rd, + output wire s_cpuif_rd_ack, + output wire s_cpuif_rd_err, + output wire [31:0] s_cpuif_rd_data, + output wire s_cpuif_wr_ack, + output wire s_cpuif_wr_err, + + input doe_reg_pkg::doe_reg__in_t hwif_in, + output doe_reg_pkg::doe_reg__out_t hwif_out + ); + + //-------------------------------------------------------------------------- + // CPU Bus interface logic + //-------------------------------------------------------------------------- + logic cpuif_req; + logic cpuif_req_is_wr; + logic [11:0] cpuif_addr; + logic [31:0] cpuif_wr_data; + logic [31:0] cpuif_wr_biten; + logic cpuif_req_stall_wr; + logic cpuif_req_stall_rd; + + logic cpuif_rd_ack; + logic cpuif_rd_err; + logic [31:0] cpuif_rd_data; + + logic cpuif_wr_ack; + logic cpuif_wr_err; + + assign cpuif_req = s_cpuif_req; + assign cpuif_req_is_wr = s_cpuif_req_is_wr; + assign cpuif_addr = s_cpuif_addr; + assign cpuif_wr_data = s_cpuif_wr_data; + assign cpuif_wr_biten = s_cpuif_wr_biten; + assign s_cpuif_req_stall_wr = cpuif_req_stall_wr; + assign s_cpuif_req_stall_rd = cpuif_req_stall_rd; + assign s_cpuif_rd_ack = cpuif_rd_ack; + assign s_cpuif_rd_err = cpuif_rd_err; + assign s_cpuif_rd_data = cpuif_rd_data; + assign s_cpuif_wr_ack = cpuif_wr_ack; + assign s_cpuif_wr_err = cpuif_wr_err; + + logic cpuif_req_masked; + + // Read & write latencies are balanced. Stalls not required + assign cpuif_req_stall_rd = '0; + assign cpuif_req_stall_wr = '0; + assign cpuif_req_masked = cpuif_req + & !(!cpuif_req_is_wr & cpuif_req_stall_rd) + & !(cpuif_req_is_wr & cpuif_req_stall_wr); + + //-------------------------------------------------------------------------- + // Address Decode + //-------------------------------------------------------------------------- + typedef struct packed{ + logic [4-1:0]DOE_IV; + logic DOE_CTRL; + logic DOE_STATUS; + struct packed{ + logic global_intr_en_r; + logic error_intr_en_r; + logic notif_intr_en_r; + logic error_global_intr_r; + logic notif_global_intr_r; + logic error_internal_intr_r; + logic notif_internal_intr_r; + logic error_intr_trig_r; + logic notif_intr_trig_r; + logic error0_intr_count_r; + logic error1_intr_count_r; + logic error2_intr_count_r; + logic error3_intr_count_r; + logic notif_cmd_done_intr_count_r; + logic error0_intr_count_incr_r; + logic error1_intr_count_incr_r; + logic error2_intr_count_incr_r; + logic error3_intr_count_incr_r; + logic notif_cmd_done_intr_count_incr_r; + } intr_block_rf; + } decoded_reg_strb_t; + decoded_reg_strb_t decoded_reg_strb; + logic decoded_req; + logic decoded_req_is_wr; + logic [31:0] decoded_wr_data; + logic [31:0] decoded_wr_biten; + + always_comb begin + for(int i0=0; i0<4; i0++) begin + decoded_reg_strb.DOE_IV[i0] = cpuif_req_masked & (cpuif_addr == 12'h0 + i0*12'h4); + end + decoded_reg_strb.DOE_CTRL = cpuif_req_masked & (cpuif_addr == 12'h10); + decoded_reg_strb.DOE_STATUS = cpuif_req_masked & (cpuif_addr == 12'h14); + decoded_reg_strb.intr_block_rf.global_intr_en_r = cpuif_req_masked & (cpuif_addr == 12'h800); + decoded_reg_strb.intr_block_rf.error_intr_en_r = cpuif_req_masked & (cpuif_addr == 12'h804); + decoded_reg_strb.intr_block_rf.notif_intr_en_r = cpuif_req_masked & (cpuif_addr == 12'h808); + decoded_reg_strb.intr_block_rf.error_global_intr_r = cpuif_req_masked & (cpuif_addr == 12'h80c); + decoded_reg_strb.intr_block_rf.notif_global_intr_r = cpuif_req_masked & (cpuif_addr == 12'h810); + decoded_reg_strb.intr_block_rf.error_internal_intr_r = cpuif_req_masked & (cpuif_addr == 12'h814); + decoded_reg_strb.intr_block_rf.notif_internal_intr_r = cpuif_req_masked & (cpuif_addr == 12'h818); + decoded_reg_strb.intr_block_rf.error_intr_trig_r = cpuif_req_masked & (cpuif_addr == 12'h81c); + decoded_reg_strb.intr_block_rf.notif_intr_trig_r = cpuif_req_masked & (cpuif_addr == 12'h820); + decoded_reg_strb.intr_block_rf.error0_intr_count_r = cpuif_req_masked & (cpuif_addr == 12'h900); + decoded_reg_strb.intr_block_rf.error1_intr_count_r = cpuif_req_masked & (cpuif_addr == 12'h904); + decoded_reg_strb.intr_block_rf.error2_intr_count_r = cpuif_req_masked & (cpuif_addr == 12'h908); + decoded_reg_strb.intr_block_rf.error3_intr_count_r = cpuif_req_masked & (cpuif_addr == 12'h90c); + decoded_reg_strb.intr_block_rf.notif_cmd_done_intr_count_r = cpuif_req_masked & (cpuif_addr == 12'h980); + decoded_reg_strb.intr_block_rf.error0_intr_count_incr_r = cpuif_req_masked & (cpuif_addr == 12'ha00); + decoded_reg_strb.intr_block_rf.error1_intr_count_incr_r = cpuif_req_masked & (cpuif_addr == 12'ha04); + decoded_reg_strb.intr_block_rf.error2_intr_count_incr_r = cpuif_req_masked & (cpuif_addr == 12'ha08); + decoded_reg_strb.intr_block_rf.error3_intr_count_incr_r = cpuif_req_masked & (cpuif_addr == 12'ha0c); + decoded_reg_strb.intr_block_rf.notif_cmd_done_intr_count_incr_r = cpuif_req_masked & (cpuif_addr == 12'ha10); + end + + // Pass down signals to next stage + assign decoded_req = cpuif_req_masked; + assign decoded_req_is_wr = cpuif_req_is_wr; + assign decoded_wr_data = cpuif_wr_data; + assign decoded_wr_biten = cpuif_wr_biten; + + //-------------------------------------------------------------------------- + // Field logic + //-------------------------------------------------------------------------- + typedef struct packed{ + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } IV; + } [4-1:0]DOE_IV; + struct packed{ + struct packed{ + logic [1:0] next; + logic load_next; + } CMD; + struct packed{ + logic [4:0] next; + logic load_next; + } DEST; + struct packed{ + logic [1:0] next; + logic load_next; + } CMD_EXT; + } DOE_CTRL; + struct packed{ + struct packed{ + logic next; + logic load_next; + } READY; + struct packed{ + logic next; + logic load_next; + } VALID; + struct packed{ + logic next; + logic load_next; + } DEOBF_SECRETS_CLEARED; + struct packed{ + logic next; + logic load_next; + } ERROR; + } DOE_STATUS; + struct packed{ + struct packed{ + struct packed{ + logic next; + logic load_next; + } error_en; + struct packed{ + logic next; + logic load_next; + } notif_en; + } global_intr_en_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + } error0_en; + struct packed{ + logic next; + logic load_next; + } error1_en; + struct packed{ + logic next; + logic load_next; + } error2_en; + struct packed{ + logic next; + logic load_next; + } error3_en; + } error_intr_en_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + } notif_cmd_done_en; + } notif_intr_en_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + } agg_sts; + } error_global_intr_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + } agg_sts; + } notif_global_intr_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + } error0_sts; + struct packed{ + logic next; + logic load_next; + } error1_sts; + struct packed{ + logic next; + logic load_next; + } error2_sts; + struct packed{ + logic next; + logic load_next; + } error3_sts; + } error_internal_intr_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + } notif_cmd_done_sts; + } notif_internal_intr_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + } error0_trig; + struct packed{ + logic next; + logic load_next; + } error1_trig; + struct packed{ + logic next; + logic load_next; + } error2_trig; + struct packed{ + logic next; + logic load_next; + } error3_trig; + } error_intr_trig_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + } notif_cmd_done_trig; + } notif_intr_trig_r; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + logic incrthreshold; + logic incrsaturate; + } cnt; + } error0_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + logic incrthreshold; + logic incrsaturate; + } cnt; + } error1_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + logic incrthreshold; + logic incrsaturate; + } cnt; + } error2_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + logic incrthreshold; + logic incrsaturate; + } cnt; + } error3_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + logic incrthreshold; + logic incrsaturate; + } cnt; + } notif_cmd_done_intr_count_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + logic decrthreshold; + logic underflow; + } pulse; + } error0_intr_count_incr_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + logic decrthreshold; + logic underflow; + } pulse; + } error1_intr_count_incr_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + logic decrthreshold; + logic underflow; + } pulse; + } error2_intr_count_incr_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + logic decrthreshold; + logic underflow; + } pulse; + } error3_intr_count_incr_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + logic decrthreshold; + logic underflow; + } pulse; + } notif_cmd_done_intr_count_incr_r; + } intr_block_rf; + } field_combo_t; + field_combo_t field_combo; + + typedef struct packed{ + struct packed{ + struct packed{ + logic [31:0] value; + } IV; + } [4-1:0]DOE_IV; + struct packed{ + struct packed{ + logic [1:0] value; + } CMD; + struct packed{ + logic [4:0] value; + } DEST; + struct packed{ + logic [1:0] value; + } CMD_EXT; + } DOE_CTRL; + struct packed{ + struct packed{ + logic value; + } READY; + struct packed{ + logic value; + } VALID; + struct packed{ + logic value; + } DEOBF_SECRETS_CLEARED; + struct packed{ + logic value; + } ERROR; + } DOE_STATUS; + struct packed{ + struct packed{ + struct packed{ + logic value; + } error_en; + struct packed{ + logic value; + } notif_en; + } global_intr_en_r; + struct packed{ + struct packed{ + logic value; + } error0_en; + struct packed{ + logic value; + } error1_en; + struct packed{ + logic value; + } error2_en; + struct packed{ + logic value; + } error3_en; + } error_intr_en_r; + struct packed{ + struct packed{ + logic value; + } notif_cmd_done_en; + } notif_intr_en_r; + struct packed{ + struct packed{ + logic value; + } agg_sts; + } error_global_intr_r; + struct packed{ + struct packed{ + logic value; + } agg_sts; + } notif_global_intr_r; + struct packed{ + struct packed{ + logic value; + } error0_sts; + struct packed{ + logic value; + } error1_sts; + struct packed{ + logic value; + } error2_sts; + struct packed{ + logic value; + } error3_sts; + } error_internal_intr_r; + struct packed{ + struct packed{ + logic value; + } notif_cmd_done_sts; + } notif_internal_intr_r; + struct packed{ + struct packed{ + logic value; + } error0_trig; + struct packed{ + logic value; + } error1_trig; + struct packed{ + logic value; + } error2_trig; + struct packed{ + logic value; + } error3_trig; + } error_intr_trig_r; + struct packed{ + struct packed{ + logic value; + } notif_cmd_done_trig; + } notif_intr_trig_r; + struct packed{ + struct packed{ + logic [31:0] value; + } cnt; + } error0_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] value; + } cnt; + } error1_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] value; + } cnt; + } error2_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] value; + } cnt; + } error3_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] value; + } cnt; + } notif_cmd_done_intr_count_r; + struct packed{ + struct packed{ + logic value; + } pulse; + } error0_intr_count_incr_r; + struct packed{ + struct packed{ + logic value; + } pulse; + } error1_intr_count_incr_r; + struct packed{ + struct packed{ + logic value; + } pulse; + } error2_intr_count_incr_r; + struct packed{ + struct packed{ + logic value; + } pulse; + } error3_intr_count_incr_r; + struct packed{ + struct packed{ + logic value; + } pulse; + } notif_cmd_done_intr_count_incr_r; + } intr_block_rf; + } field_storage_t; + field_storage_t field_storage; + + for(genvar i0=0; i0<4; i0++) begin + // Field: doe_reg.DOE_IV[].IV + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.DOE_IV[i0].IV.value; + load_next_c = '0; + if(decoded_reg_strb.DOE_IV[i0] && decoded_req_is_wr) begin // SW write + next_c = (field_storage.DOE_IV[i0].IV.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end else if(hwif_in.DOE_IV[i0].IV.hwclr) begin // HW Clear + next_c = '0; + load_next_c = '1; + end + field_combo.DOE_IV[i0].IV.next = next_c; + field_combo.DOE_IV[i0].IV.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.DOE_IV[i0].IV.value <= 32'h0; + end else if(field_combo.DOE_IV[i0].IV.load_next) begin + field_storage.DOE_IV[i0].IV.value <= field_combo.DOE_IV[i0].IV.next; + end + end + assign hwif_out.DOE_IV[i0].IV.value = field_storage.DOE_IV[i0].IV.value; + assign hwif_out.DOE_IV[i0].IV.swmod = decoded_reg_strb.DOE_IV[i0] && decoded_req_is_wr; + end + // Field: doe_reg.DOE_CTRL.CMD + always_comb begin + automatic logic [1:0] next_c; + automatic logic load_next_c; + next_c = field_storage.DOE_CTRL.CMD.value; + load_next_c = '0; + if(decoded_reg_strb.DOE_CTRL && decoded_req_is_wr) begin // SW write + next_c = (field_storage.DOE_CTRL.CMD.value & ~decoded_wr_biten[1:0]) | (decoded_wr_data[1:0] & decoded_wr_biten[1:0]); + load_next_c = '1; + end else if(hwif_in.DOE_CTRL.CMD.hwclr) begin // HW Clear + next_c = '0; + load_next_c = '1; + end + field_combo.DOE_CTRL.CMD.next = next_c; + field_combo.DOE_CTRL.CMD.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.DOE_CTRL.CMD.value <= 2'h0; + end else if(field_combo.DOE_CTRL.CMD.load_next) begin + field_storage.DOE_CTRL.CMD.value <= field_combo.DOE_CTRL.CMD.next; + end + end + assign hwif_out.DOE_CTRL.CMD.value = field_storage.DOE_CTRL.CMD.value; + assign hwif_out.DOE_CTRL.CMD.swmod = decoded_reg_strb.DOE_CTRL && decoded_req_is_wr; + // Field: doe_reg.DOE_CTRL.DEST + always_comb begin + automatic logic [4:0] next_c; + automatic logic load_next_c; + next_c = field_storage.DOE_CTRL.DEST.value; + load_next_c = '0; + if(decoded_reg_strb.DOE_CTRL && decoded_req_is_wr) begin // SW write + next_c = (field_storage.DOE_CTRL.DEST.value & ~decoded_wr_biten[6:2]) | (decoded_wr_data[6:2] & decoded_wr_biten[6:2]); + load_next_c = '1; + end + field_combo.DOE_CTRL.DEST.next = next_c; + field_combo.DOE_CTRL.DEST.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.DOE_CTRL.DEST.value <= 5'h0; + end else if(field_combo.DOE_CTRL.DEST.load_next) begin + field_storage.DOE_CTRL.DEST.value <= field_combo.DOE_CTRL.DEST.next; + end + end + assign hwif_out.DOE_CTRL.DEST.value = field_storage.DOE_CTRL.DEST.value; + // Field: doe_reg.DOE_CTRL.CMD_EXT + always_comb begin + automatic logic [1:0] next_c; + automatic logic load_next_c; + next_c = field_storage.DOE_CTRL.CMD_EXT.value; + load_next_c = '0; + if(decoded_reg_strb.DOE_CTRL && decoded_req_is_wr) begin // SW write + next_c = (field_storage.DOE_CTRL.CMD_EXT.value & ~decoded_wr_biten[8:7]) | (decoded_wr_data[8:7] & decoded_wr_biten[8:7]); + load_next_c = '1; + end else if(hwif_in.DOE_CTRL.CMD_EXT.hwclr) begin // HW Clear + next_c = '0; + load_next_c = '1; + end + field_combo.DOE_CTRL.CMD_EXT.next = next_c; + field_combo.DOE_CTRL.CMD_EXT.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.DOE_CTRL.CMD_EXT.value <= 2'h0; + end else if(field_combo.DOE_CTRL.CMD_EXT.load_next) begin + field_storage.DOE_CTRL.CMD_EXT.value <= field_combo.DOE_CTRL.CMD_EXT.next; + end + end + assign hwif_out.DOE_CTRL.CMD_EXT.value = field_storage.DOE_CTRL.CMD_EXT.value; + assign hwif_out.DOE_CTRL.CMD_EXT.swmod = decoded_reg_strb.DOE_CTRL && decoded_req_is_wr; + // Field: doe_reg.DOE_STATUS.READY + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.DOE_STATUS.READY.value; + load_next_c = '0; + if(hwif_in.DOE_STATUS.READY.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end else if(hwif_in.DOE_STATUS.READY.hwclr) begin // HW Clear + next_c = '0; + load_next_c = '1; + end + field_combo.DOE_STATUS.READY.next = next_c; + field_combo.DOE_STATUS.READY.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.DOE_STATUS.READY.value <= 1'h0; + end else if(field_combo.DOE_STATUS.READY.load_next) begin + field_storage.DOE_STATUS.READY.value <= field_combo.DOE_STATUS.READY.next; + end + end + // Field: doe_reg.DOE_STATUS.VALID + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.DOE_STATUS.VALID.value; + load_next_c = '0; + if(hwif_in.DOE_STATUS.VALID.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end else if(hwif_in.DOE_STATUS.VALID.hwclr) begin // HW Clear + next_c = '0; + load_next_c = '1; + end + field_combo.DOE_STATUS.VALID.next = next_c; + field_combo.DOE_STATUS.VALID.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.DOE_STATUS.VALID.value <= 1'h0; + end else if(field_combo.DOE_STATUS.VALID.load_next) begin + field_storage.DOE_STATUS.VALID.value <= field_combo.DOE_STATUS.VALID.next; + end + end + // Field: doe_reg.DOE_STATUS.DEOBF_SECRETS_CLEARED + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.DOE_STATUS.DEOBF_SECRETS_CLEARED.value; + load_next_c = '0; + if(hwif_in.DOE_STATUS.DEOBF_SECRETS_CLEARED.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end + field_combo.DOE_STATUS.DEOBF_SECRETS_CLEARED.next = next_c; + field_combo.DOE_STATUS.DEOBF_SECRETS_CLEARED.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.DOE_STATUS.DEOBF_SECRETS_CLEARED.value <= 1'h0; + end else if(field_combo.DOE_STATUS.DEOBF_SECRETS_CLEARED.load_next) begin + field_storage.DOE_STATUS.DEOBF_SECRETS_CLEARED.value <= field_combo.DOE_STATUS.DEOBF_SECRETS_CLEARED.next; + end + end + // Field: doe_reg.DOE_STATUS.ERROR + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.DOE_STATUS.ERROR.value; + load_next_c = '0; + if(hwif_in.DOE_STATUS.ERROR.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end else if(hwif_in.DOE_STATUS.ERROR.hwclr) begin // HW Clear + next_c = '0; + load_next_c = '1; + end + field_combo.DOE_STATUS.ERROR.next = next_c; + field_combo.DOE_STATUS.ERROR.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.DOE_STATUS.ERROR.value <= 1'h0; + end else if(field_combo.DOE_STATUS.ERROR.load_next) begin + field_storage.DOE_STATUS.ERROR.value <= field_combo.DOE_STATUS.ERROR.next; + end + end + // Field: doe_reg.intr_block_rf.global_intr_en_r.error_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.global_intr_en_r.error_en.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.global_intr_en_r && decoded_req_is_wr) begin // SW write + next_c = (field_storage.intr_block_rf.global_intr_en_r.error_en.value & ~decoded_wr_biten[0:0]) | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end + field_combo.intr_block_rf.global_intr_en_r.error_en.next = next_c; + field_combo.intr_block_rf.global_intr_en_r.error_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.global_intr_en_r.error_en.value <= 1'h0; + end else if(field_combo.intr_block_rf.global_intr_en_r.error_en.load_next) begin + field_storage.intr_block_rf.global_intr_en_r.error_en.value <= field_combo.intr_block_rf.global_intr_en_r.error_en.next; + end + end + // Field: doe_reg.intr_block_rf.global_intr_en_r.notif_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.global_intr_en_r.notif_en.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.global_intr_en_r && decoded_req_is_wr) begin // SW write + next_c = (field_storage.intr_block_rf.global_intr_en_r.notif_en.value & ~decoded_wr_biten[1:1]) | (decoded_wr_data[1:1] & decoded_wr_biten[1:1]); + load_next_c = '1; + end + field_combo.intr_block_rf.global_intr_en_r.notif_en.next = next_c; + field_combo.intr_block_rf.global_intr_en_r.notif_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.global_intr_en_r.notif_en.value <= 1'h0; + end else if(field_combo.intr_block_rf.global_intr_en_r.notif_en.load_next) begin + field_storage.intr_block_rf.global_intr_en_r.notif_en.value <= field_combo.intr_block_rf.global_intr_en_r.notif_en.next; + end + end + // Field: doe_reg.intr_block_rf.error_intr_en_r.error0_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_intr_en_r.error0_en.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_intr_en_r && decoded_req_is_wr) begin // SW write + next_c = (field_storage.intr_block_rf.error_intr_en_r.error0_en.value & ~decoded_wr_biten[0:0]) | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end + field_combo.intr_block_rf.error_intr_en_r.error0_en.next = next_c; + field_combo.intr_block_rf.error_intr_en_r.error0_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.error_intr_en_r.error0_en.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_intr_en_r.error0_en.load_next) begin + field_storage.intr_block_rf.error_intr_en_r.error0_en.value <= field_combo.intr_block_rf.error_intr_en_r.error0_en.next; + end + end + // Field: doe_reg.intr_block_rf.error_intr_en_r.error1_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_intr_en_r.error1_en.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_intr_en_r && decoded_req_is_wr) begin // SW write + next_c = (field_storage.intr_block_rf.error_intr_en_r.error1_en.value & ~decoded_wr_biten[1:1]) | (decoded_wr_data[1:1] & decoded_wr_biten[1:1]); + load_next_c = '1; + end + field_combo.intr_block_rf.error_intr_en_r.error1_en.next = next_c; + field_combo.intr_block_rf.error_intr_en_r.error1_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.error_intr_en_r.error1_en.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_intr_en_r.error1_en.load_next) begin + field_storage.intr_block_rf.error_intr_en_r.error1_en.value <= field_combo.intr_block_rf.error_intr_en_r.error1_en.next; + end + end + // Field: doe_reg.intr_block_rf.error_intr_en_r.error2_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_intr_en_r.error2_en.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_intr_en_r && decoded_req_is_wr) begin // SW write + next_c = (field_storage.intr_block_rf.error_intr_en_r.error2_en.value & ~decoded_wr_biten[2:2]) | (decoded_wr_data[2:2] & decoded_wr_biten[2:2]); + load_next_c = '1; + end + field_combo.intr_block_rf.error_intr_en_r.error2_en.next = next_c; + field_combo.intr_block_rf.error_intr_en_r.error2_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.error_intr_en_r.error2_en.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_intr_en_r.error2_en.load_next) begin + field_storage.intr_block_rf.error_intr_en_r.error2_en.value <= field_combo.intr_block_rf.error_intr_en_r.error2_en.next; + end + end + // Field: doe_reg.intr_block_rf.error_intr_en_r.error3_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_intr_en_r.error3_en.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_intr_en_r && decoded_req_is_wr) begin // SW write + next_c = (field_storage.intr_block_rf.error_intr_en_r.error3_en.value & ~decoded_wr_biten[3:3]) | (decoded_wr_data[3:3] & decoded_wr_biten[3:3]); + load_next_c = '1; + end + field_combo.intr_block_rf.error_intr_en_r.error3_en.next = next_c; + field_combo.intr_block_rf.error_intr_en_r.error3_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.error_intr_en_r.error3_en.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_intr_en_r.error3_en.load_next) begin + field_storage.intr_block_rf.error_intr_en_r.error3_en.value <= field_combo.intr_block_rf.error_intr_en_r.error3_en.next; + end + end + // Field: doe_reg.intr_block_rf.notif_intr_en_r.notif_cmd_done_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_intr_en_r.notif_cmd_done_en.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.notif_intr_en_r && decoded_req_is_wr) begin // SW write + next_c = (field_storage.intr_block_rf.notif_intr_en_r.notif_cmd_done_en.value & ~decoded_wr_biten[0:0]) | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end + field_combo.intr_block_rf.notif_intr_en_r.notif_cmd_done_en.next = next_c; + field_combo.intr_block_rf.notif_intr_en_r.notif_cmd_done_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.notif_intr_en_r.notif_cmd_done_en.value <= 1'h0; + end else if(field_combo.intr_block_rf.notif_intr_en_r.notif_cmd_done_en.load_next) begin + field_storage.intr_block_rf.notif_intr_en_r.notif_cmd_done_en.value <= field_combo.intr_block_rf.notif_intr_en_r.notif_cmd_done_en.next; + end + end + // Field: doe_reg.intr_block_rf.error_global_intr_r.agg_sts + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_global_intr_r.agg_sts.value; + load_next_c = '0; + + // HW Write + next_c = hwif_out.intr_block_rf.error_internal_intr_r.intr; + load_next_c = '1; + field_combo.intr_block_rf.error_global_intr_r.agg_sts.next = next_c; + field_combo.intr_block_rf.error_global_intr_r.agg_sts.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.error_global_intr_r.agg_sts.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_global_intr_r.agg_sts.load_next) begin + field_storage.intr_block_rf.error_global_intr_r.agg_sts.value <= field_combo.intr_block_rf.error_global_intr_r.agg_sts.next; + end + end + assign hwif_out.intr_block_rf.error_global_intr_r.intr = + |(field_storage.intr_block_rf.error_global_intr_r.agg_sts.value & field_storage.intr_block_rf.global_intr_en_r.error_en.value); + // Field: doe_reg.intr_block_rf.notif_global_intr_r.agg_sts + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_global_intr_r.agg_sts.value; + load_next_c = '0; + + // HW Write + next_c = hwif_out.intr_block_rf.notif_internal_intr_r.intr; + load_next_c = '1; + field_combo.intr_block_rf.notif_global_intr_r.agg_sts.next = next_c; + field_combo.intr_block_rf.notif_global_intr_r.agg_sts.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.notif_global_intr_r.agg_sts.value <= 1'h0; + end else if(field_combo.intr_block_rf.notif_global_intr_r.agg_sts.load_next) begin + field_storage.intr_block_rf.notif_global_intr_r.agg_sts.value <= field_combo.intr_block_rf.notif_global_intr_r.agg_sts.next; + end + end + assign hwif_out.intr_block_rf.notif_global_intr_r.intr = + |(field_storage.intr_block_rf.notif_global_intr_r.agg_sts.value & field_storage.intr_block_rf.global_intr_en_r.notif_en.value); + // Field: doe_reg.intr_block_rf.error_internal_intr_r.error0_sts + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_internal_intr_r.error0_sts.value; + load_next_c = '0; + if(field_storage.intr_block_rf.error_intr_trig_r.error0_trig.value != '0) begin // stickybit + next_c = field_storage.intr_block_rf.error_internal_intr_r.error0_sts.value | field_storage.intr_block_rf.error_intr_trig_r.error0_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.error_internal_intr_r.error0_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end else if(decoded_reg_strb.intr_block_rf.error_internal_intr_r && decoded_req_is_wr) begin // SW write 1 clear + next_c = field_storage.intr_block_rf.error_internal_intr_r.error0_sts.value & ~(decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end + field_combo.intr_block_rf.error_internal_intr_r.error0_sts.next = next_c; + field_combo.intr_block_rf.error_internal_intr_r.error0_sts.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.intr_block_rf.error_internal_intr_r.error0_sts.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_internal_intr_r.error0_sts.load_next) begin + field_storage.intr_block_rf.error_internal_intr_r.error0_sts.value <= field_combo.intr_block_rf.error_internal_intr_r.error0_sts.next; + end + end + // Field: doe_reg.intr_block_rf.error_internal_intr_r.error1_sts + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_internal_intr_r.error1_sts.value; + load_next_c = '0; + if(field_storage.intr_block_rf.error_intr_trig_r.error1_trig.value != '0) begin // stickybit + next_c = field_storage.intr_block_rf.error_internal_intr_r.error1_sts.value | field_storage.intr_block_rf.error_intr_trig_r.error1_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.error_internal_intr_r.error1_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end else if(decoded_reg_strb.intr_block_rf.error_internal_intr_r && decoded_req_is_wr) begin // SW write 1 clear + next_c = field_storage.intr_block_rf.error_internal_intr_r.error1_sts.value & ~(decoded_wr_data[1:1] & decoded_wr_biten[1:1]); + load_next_c = '1; + end + field_combo.intr_block_rf.error_internal_intr_r.error1_sts.next = next_c; + field_combo.intr_block_rf.error_internal_intr_r.error1_sts.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.intr_block_rf.error_internal_intr_r.error1_sts.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_internal_intr_r.error1_sts.load_next) begin + field_storage.intr_block_rf.error_internal_intr_r.error1_sts.value <= field_combo.intr_block_rf.error_internal_intr_r.error1_sts.next; + end + end + // Field: doe_reg.intr_block_rf.error_internal_intr_r.error2_sts + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_internal_intr_r.error2_sts.value; + load_next_c = '0; + if(field_storage.intr_block_rf.error_intr_trig_r.error2_trig.value != '0) begin // stickybit + next_c = field_storage.intr_block_rf.error_internal_intr_r.error2_sts.value | field_storage.intr_block_rf.error_intr_trig_r.error2_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.error_internal_intr_r.error2_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end else if(decoded_reg_strb.intr_block_rf.error_internal_intr_r && decoded_req_is_wr) begin // SW write 1 clear + next_c = field_storage.intr_block_rf.error_internal_intr_r.error2_sts.value & ~(decoded_wr_data[2:2] & decoded_wr_biten[2:2]); + load_next_c = '1; + end + field_combo.intr_block_rf.error_internal_intr_r.error2_sts.next = next_c; + field_combo.intr_block_rf.error_internal_intr_r.error2_sts.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.intr_block_rf.error_internal_intr_r.error2_sts.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_internal_intr_r.error2_sts.load_next) begin + field_storage.intr_block_rf.error_internal_intr_r.error2_sts.value <= field_combo.intr_block_rf.error_internal_intr_r.error2_sts.next; + end + end + // Field: doe_reg.intr_block_rf.error_internal_intr_r.error3_sts + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_internal_intr_r.error3_sts.value; + load_next_c = '0; + if(field_storage.intr_block_rf.error_intr_trig_r.error3_trig.value != '0) begin // stickybit + next_c = field_storage.intr_block_rf.error_internal_intr_r.error3_sts.value | field_storage.intr_block_rf.error_intr_trig_r.error3_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.error_internal_intr_r.error3_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end else if(decoded_reg_strb.intr_block_rf.error_internal_intr_r && decoded_req_is_wr) begin // SW write 1 clear + next_c = field_storage.intr_block_rf.error_internal_intr_r.error3_sts.value & ~(decoded_wr_data[3:3] & decoded_wr_biten[3:3]); + load_next_c = '1; + end + field_combo.intr_block_rf.error_internal_intr_r.error3_sts.next = next_c; + field_combo.intr_block_rf.error_internal_intr_r.error3_sts.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.intr_block_rf.error_internal_intr_r.error3_sts.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_internal_intr_r.error3_sts.load_next) begin + field_storage.intr_block_rf.error_internal_intr_r.error3_sts.value <= field_combo.intr_block_rf.error_internal_intr_r.error3_sts.next; + end + end + assign hwif_out.intr_block_rf.error_internal_intr_r.intr = + |(field_storage.intr_block_rf.error_internal_intr_r.error0_sts.value & field_storage.intr_block_rf.error_intr_en_r.error0_en.value) + || |(field_storage.intr_block_rf.error_internal_intr_r.error1_sts.value & field_storage.intr_block_rf.error_intr_en_r.error1_en.value) + || |(field_storage.intr_block_rf.error_internal_intr_r.error2_sts.value & field_storage.intr_block_rf.error_intr_en_r.error2_en.value) + || |(field_storage.intr_block_rf.error_internal_intr_r.error3_sts.value & field_storage.intr_block_rf.error_intr_en_r.error3_en.value); + // Field: doe_reg.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.value; + load_next_c = '0; + if(field_storage.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.value != '0) begin // stickybit + next_c = field_storage.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.value | field_storage.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end else if(decoded_reg_strb.intr_block_rf.notif_internal_intr_r && decoded_req_is_wr) begin // SW write 1 clear + next_c = field_storage.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.value & ~(decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end + field_combo.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.next = next_c; + field_combo.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.value <= 1'h0; + end else if(field_combo.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.load_next) begin + field_storage.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.value <= field_combo.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.next; + end + end + assign hwif_out.intr_block_rf.notif_internal_intr_r.intr = + |(field_storage.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.value & field_storage.intr_block_rf.notif_intr_en_r.notif_cmd_done_en.value); + // Field: doe_reg.intr_block_rf.error_intr_trig_r.error0_trig + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_intr_trig_r.error0_trig.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_intr_trig_r && decoded_req_is_wr) begin // SW write 1 set + next_c = field_storage.intr_block_rf.error_intr_trig_r.error0_trig.value | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end else begin // singlepulse clears back to 0 + next_c = '0; + load_next_c = '1; + end + field_combo.intr_block_rf.error_intr_trig_r.error0_trig.next = next_c; + field_combo.intr_block_rf.error_intr_trig_r.error0_trig.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.error_intr_trig_r.error0_trig.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_intr_trig_r.error0_trig.load_next) begin + field_storage.intr_block_rf.error_intr_trig_r.error0_trig.value <= field_combo.intr_block_rf.error_intr_trig_r.error0_trig.next; + end + end + // Field: doe_reg.intr_block_rf.error_intr_trig_r.error1_trig + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_intr_trig_r.error1_trig.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_intr_trig_r && decoded_req_is_wr) begin // SW write 1 set + next_c = field_storage.intr_block_rf.error_intr_trig_r.error1_trig.value | (decoded_wr_data[1:1] & decoded_wr_biten[1:1]); + load_next_c = '1; + end else begin // singlepulse clears back to 0 + next_c = '0; + load_next_c = '1; + end + field_combo.intr_block_rf.error_intr_trig_r.error1_trig.next = next_c; + field_combo.intr_block_rf.error_intr_trig_r.error1_trig.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.error_intr_trig_r.error1_trig.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_intr_trig_r.error1_trig.load_next) begin + field_storage.intr_block_rf.error_intr_trig_r.error1_trig.value <= field_combo.intr_block_rf.error_intr_trig_r.error1_trig.next; + end + end + // Field: doe_reg.intr_block_rf.error_intr_trig_r.error2_trig + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_intr_trig_r.error2_trig.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_intr_trig_r && decoded_req_is_wr) begin // SW write 1 set + next_c = field_storage.intr_block_rf.error_intr_trig_r.error2_trig.value | (decoded_wr_data[2:2] & decoded_wr_biten[2:2]); + load_next_c = '1; + end else begin // singlepulse clears back to 0 + next_c = '0; + load_next_c = '1; + end + field_combo.intr_block_rf.error_intr_trig_r.error2_trig.next = next_c; + field_combo.intr_block_rf.error_intr_trig_r.error2_trig.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.error_intr_trig_r.error2_trig.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_intr_trig_r.error2_trig.load_next) begin + field_storage.intr_block_rf.error_intr_trig_r.error2_trig.value <= field_combo.intr_block_rf.error_intr_trig_r.error2_trig.next; + end + end + // Field: doe_reg.intr_block_rf.error_intr_trig_r.error3_trig + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_intr_trig_r.error3_trig.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_intr_trig_r && decoded_req_is_wr) begin // SW write 1 set + next_c = field_storage.intr_block_rf.error_intr_trig_r.error3_trig.value | (decoded_wr_data[3:3] & decoded_wr_biten[3:3]); + load_next_c = '1; + end else begin // singlepulse clears back to 0 + next_c = '0; + load_next_c = '1; + end + field_combo.intr_block_rf.error_intr_trig_r.error3_trig.next = next_c; + field_combo.intr_block_rf.error_intr_trig_r.error3_trig.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.error_intr_trig_r.error3_trig.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_intr_trig_r.error3_trig.load_next) begin + field_storage.intr_block_rf.error_intr_trig_r.error3_trig.value <= field_combo.intr_block_rf.error_intr_trig_r.error3_trig.next; + end + end + // Field: doe_reg.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.notif_intr_trig_r && decoded_req_is_wr) begin // SW write 1 set + next_c = field_storage.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.value | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end else begin // singlepulse clears back to 0 + next_c = '0; + load_next_c = '1; + end + field_combo.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.next = next_c; + field_combo.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.value <= 1'h0; + end else if(field_combo.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.load_next) begin + field_storage.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.value <= field_combo.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.next; + end + end + // Field: doe_reg.intr_block_rf.error0_intr_count_r.cnt + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error0_intr_count_r.cnt.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error0_intr_count_r && decoded_req_is_wr) begin // SW write + next_c = (field_storage.intr_block_rf.error0_intr_count_r.cnt.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + if(field_storage.intr_block_rf.error0_intr_count_incr_r.pulse.value) begin // increment + if(((33)'(next_c) + 32'h1) > 32'hffffffff) begin // up-counter saturated + next_c = 32'hffffffff; + end else begin + next_c = next_c + 32'h1; + end + load_next_c = '1; + end + field_combo.intr_block_rf.error0_intr_count_r.cnt.incrthreshold = (field_storage.intr_block_rf.error0_intr_count_r.cnt.value >= 32'hffffffff); + field_combo.intr_block_rf.error0_intr_count_r.cnt.incrsaturate = (field_storage.intr_block_rf.error0_intr_count_r.cnt.value >= 32'hffffffff); + if(next_c > 32'hffffffff) begin + next_c = 32'hffffffff; + load_next_c = '1; + end + field_combo.intr_block_rf.error0_intr_count_r.cnt.next = next_c; + field_combo.intr_block_rf.error0_intr_count_r.cnt.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.intr_block_rf.error0_intr_count_r.cnt.value <= 32'h0; + end else if(field_combo.intr_block_rf.error0_intr_count_r.cnt.load_next) begin + field_storage.intr_block_rf.error0_intr_count_r.cnt.value <= field_combo.intr_block_rf.error0_intr_count_r.cnt.next; + end + end + // Field: doe_reg.intr_block_rf.error1_intr_count_r.cnt + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error1_intr_count_r.cnt.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error1_intr_count_r && decoded_req_is_wr) begin // SW write + next_c = (field_storage.intr_block_rf.error1_intr_count_r.cnt.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + if(field_storage.intr_block_rf.error1_intr_count_incr_r.pulse.value) begin // increment + if(((33)'(next_c) + 32'h1) > 32'hffffffff) begin // up-counter saturated + next_c = 32'hffffffff; + end else begin + next_c = next_c + 32'h1; + end + load_next_c = '1; + end + field_combo.intr_block_rf.error1_intr_count_r.cnt.incrthreshold = (field_storage.intr_block_rf.error1_intr_count_r.cnt.value >= 32'hffffffff); + field_combo.intr_block_rf.error1_intr_count_r.cnt.incrsaturate = (field_storage.intr_block_rf.error1_intr_count_r.cnt.value >= 32'hffffffff); + if(next_c > 32'hffffffff) begin + next_c = 32'hffffffff; + load_next_c = '1; + end + field_combo.intr_block_rf.error1_intr_count_r.cnt.next = next_c; + field_combo.intr_block_rf.error1_intr_count_r.cnt.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.intr_block_rf.error1_intr_count_r.cnt.value <= 32'h0; + end else if(field_combo.intr_block_rf.error1_intr_count_r.cnt.load_next) begin + field_storage.intr_block_rf.error1_intr_count_r.cnt.value <= field_combo.intr_block_rf.error1_intr_count_r.cnt.next; + end + end + // Field: doe_reg.intr_block_rf.error2_intr_count_r.cnt + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error2_intr_count_r.cnt.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error2_intr_count_r && decoded_req_is_wr) begin // SW write + next_c = (field_storage.intr_block_rf.error2_intr_count_r.cnt.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + if(field_storage.intr_block_rf.error2_intr_count_incr_r.pulse.value) begin // increment + if(((33)'(next_c) + 32'h1) > 32'hffffffff) begin // up-counter saturated + next_c = 32'hffffffff; + end else begin + next_c = next_c + 32'h1; + end + load_next_c = '1; + end + field_combo.intr_block_rf.error2_intr_count_r.cnt.incrthreshold = (field_storage.intr_block_rf.error2_intr_count_r.cnt.value >= 32'hffffffff); + field_combo.intr_block_rf.error2_intr_count_r.cnt.incrsaturate = (field_storage.intr_block_rf.error2_intr_count_r.cnt.value >= 32'hffffffff); + if(next_c > 32'hffffffff) begin + next_c = 32'hffffffff; + load_next_c = '1; + end + field_combo.intr_block_rf.error2_intr_count_r.cnt.next = next_c; + field_combo.intr_block_rf.error2_intr_count_r.cnt.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.intr_block_rf.error2_intr_count_r.cnt.value <= 32'h0; + end else if(field_combo.intr_block_rf.error2_intr_count_r.cnt.load_next) begin + field_storage.intr_block_rf.error2_intr_count_r.cnt.value <= field_combo.intr_block_rf.error2_intr_count_r.cnt.next; + end + end + // Field: doe_reg.intr_block_rf.error3_intr_count_r.cnt + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error3_intr_count_r.cnt.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error3_intr_count_r && decoded_req_is_wr) begin // SW write + next_c = (field_storage.intr_block_rf.error3_intr_count_r.cnt.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + if(field_storage.intr_block_rf.error3_intr_count_incr_r.pulse.value) begin // increment + if(((33)'(next_c) + 32'h1) > 32'hffffffff) begin // up-counter saturated + next_c = 32'hffffffff; + end else begin + next_c = next_c + 32'h1; + end + load_next_c = '1; + end + field_combo.intr_block_rf.error3_intr_count_r.cnt.incrthreshold = (field_storage.intr_block_rf.error3_intr_count_r.cnt.value >= 32'hffffffff); + field_combo.intr_block_rf.error3_intr_count_r.cnt.incrsaturate = (field_storage.intr_block_rf.error3_intr_count_r.cnt.value >= 32'hffffffff); + if(next_c > 32'hffffffff) begin + next_c = 32'hffffffff; + load_next_c = '1; + end + field_combo.intr_block_rf.error3_intr_count_r.cnt.next = next_c; + field_combo.intr_block_rf.error3_intr_count_r.cnt.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.intr_block_rf.error3_intr_count_r.cnt.value <= 32'h0; + end else if(field_combo.intr_block_rf.error3_intr_count_r.cnt.load_next) begin + field_storage.intr_block_rf.error3_intr_count_r.cnt.value <= field_combo.intr_block_rf.error3_intr_count_r.cnt.next; + end + end + // Field: doe_reg.intr_block_rf.notif_cmd_done_intr_count_r.cnt + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_cmd_done_intr_count_r.cnt.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.notif_cmd_done_intr_count_r && decoded_req_is_wr) begin // SW write + next_c = (field_storage.intr_block_rf.notif_cmd_done_intr_count_r.cnt.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + if(field_storage.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.value) begin // increment + if(((33)'(next_c) + 32'h1) > 32'hffffffff) begin // up-counter saturated + next_c = 32'hffffffff; + end else begin + next_c = next_c + 32'h1; + end + load_next_c = '1; + end + field_combo.intr_block_rf.notif_cmd_done_intr_count_r.cnt.incrthreshold = (field_storage.intr_block_rf.notif_cmd_done_intr_count_r.cnt.value >= 32'hffffffff); + field_combo.intr_block_rf.notif_cmd_done_intr_count_r.cnt.incrsaturate = (field_storage.intr_block_rf.notif_cmd_done_intr_count_r.cnt.value >= 32'hffffffff); + if(next_c > 32'hffffffff) begin + next_c = 32'hffffffff; + load_next_c = '1; + end + field_combo.intr_block_rf.notif_cmd_done_intr_count_r.cnt.next = next_c; + field_combo.intr_block_rf.notif_cmd_done_intr_count_r.cnt.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.notif_cmd_done_intr_count_r.cnt.value <= 32'h0; + end else if(field_combo.intr_block_rf.notif_cmd_done_intr_count_r.cnt.load_next) begin + field_storage.intr_block_rf.notif_cmd_done_intr_count_r.cnt.value <= field_combo.intr_block_rf.notif_cmd_done_intr_count_r.cnt.next; + end + end + // Field: doe_reg.intr_block_rf.error0_intr_count_incr_r.pulse + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error0_intr_count_incr_r.pulse.value; + load_next_c = '0; + if(field_storage.intr_block_rf.error_intr_trig_r.error0_trig.value) begin // HW Write - we + next_c = field_storage.intr_block_rf.error_intr_trig_r.error0_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.error_internal_intr_r.error0_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end + if(field_storage.intr_block_rf.error0_intr_count_incr_r.pulse.value) begin // decrement + field_combo.intr_block_rf.error0_intr_count_incr_r.pulse.underflow = (next_c < (1'h1)); + next_c = next_c - 1'h1; + load_next_c = '1; + end else begin + field_combo.intr_block_rf.error0_intr_count_incr_r.pulse.underflow = '0; + end + field_combo.intr_block_rf.error0_intr_count_incr_r.pulse.decrthreshold = (field_storage.intr_block_rf.error0_intr_count_incr_r.pulse.value <= 1'd0); + field_combo.intr_block_rf.error0_intr_count_incr_r.pulse.next = next_c; + field_combo.intr_block_rf.error0_intr_count_incr_r.pulse.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.error0_intr_count_incr_r.pulse.value <= 1'h0; + end else if(field_combo.intr_block_rf.error0_intr_count_incr_r.pulse.load_next) begin + field_storage.intr_block_rf.error0_intr_count_incr_r.pulse.value <= field_combo.intr_block_rf.error0_intr_count_incr_r.pulse.next; + end + end + // Field: doe_reg.intr_block_rf.error1_intr_count_incr_r.pulse + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error1_intr_count_incr_r.pulse.value; + load_next_c = '0; + if(field_storage.intr_block_rf.error_intr_trig_r.error1_trig.value) begin // HW Write - we + next_c = field_storage.intr_block_rf.error_intr_trig_r.error1_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.error_internal_intr_r.error1_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end + if(field_storage.intr_block_rf.error1_intr_count_incr_r.pulse.value) begin // decrement + field_combo.intr_block_rf.error1_intr_count_incr_r.pulse.underflow = (next_c < (1'h1)); + next_c = next_c - 1'h1; + load_next_c = '1; + end else begin + field_combo.intr_block_rf.error1_intr_count_incr_r.pulse.underflow = '0; + end + field_combo.intr_block_rf.error1_intr_count_incr_r.pulse.decrthreshold = (field_storage.intr_block_rf.error1_intr_count_incr_r.pulse.value <= 1'd0); + field_combo.intr_block_rf.error1_intr_count_incr_r.pulse.next = next_c; + field_combo.intr_block_rf.error1_intr_count_incr_r.pulse.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.error1_intr_count_incr_r.pulse.value <= 1'h0; + end else if(field_combo.intr_block_rf.error1_intr_count_incr_r.pulse.load_next) begin + field_storage.intr_block_rf.error1_intr_count_incr_r.pulse.value <= field_combo.intr_block_rf.error1_intr_count_incr_r.pulse.next; + end + end + // Field: doe_reg.intr_block_rf.error2_intr_count_incr_r.pulse + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error2_intr_count_incr_r.pulse.value; + load_next_c = '0; + if(field_storage.intr_block_rf.error_intr_trig_r.error2_trig.value) begin // HW Write - we + next_c = field_storage.intr_block_rf.error_intr_trig_r.error2_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.error_internal_intr_r.error2_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end + if(field_storage.intr_block_rf.error2_intr_count_incr_r.pulse.value) begin // decrement + field_combo.intr_block_rf.error2_intr_count_incr_r.pulse.underflow = (next_c < (1'h1)); + next_c = next_c - 1'h1; + load_next_c = '1; + end else begin + field_combo.intr_block_rf.error2_intr_count_incr_r.pulse.underflow = '0; + end + field_combo.intr_block_rf.error2_intr_count_incr_r.pulse.decrthreshold = (field_storage.intr_block_rf.error2_intr_count_incr_r.pulse.value <= 1'd0); + field_combo.intr_block_rf.error2_intr_count_incr_r.pulse.next = next_c; + field_combo.intr_block_rf.error2_intr_count_incr_r.pulse.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.error2_intr_count_incr_r.pulse.value <= 1'h0; + end else if(field_combo.intr_block_rf.error2_intr_count_incr_r.pulse.load_next) begin + field_storage.intr_block_rf.error2_intr_count_incr_r.pulse.value <= field_combo.intr_block_rf.error2_intr_count_incr_r.pulse.next; + end + end + // Field: doe_reg.intr_block_rf.error3_intr_count_incr_r.pulse + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error3_intr_count_incr_r.pulse.value; + load_next_c = '0; + if(field_storage.intr_block_rf.error_intr_trig_r.error3_trig.value) begin // HW Write - we + next_c = field_storage.intr_block_rf.error_intr_trig_r.error3_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.error_internal_intr_r.error3_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end + if(field_storage.intr_block_rf.error3_intr_count_incr_r.pulse.value) begin // decrement + field_combo.intr_block_rf.error3_intr_count_incr_r.pulse.underflow = (next_c < (1'h1)); + next_c = next_c - 1'h1; + load_next_c = '1; + end else begin + field_combo.intr_block_rf.error3_intr_count_incr_r.pulse.underflow = '0; + end + field_combo.intr_block_rf.error3_intr_count_incr_r.pulse.decrthreshold = (field_storage.intr_block_rf.error3_intr_count_incr_r.pulse.value <= 1'd0); + field_combo.intr_block_rf.error3_intr_count_incr_r.pulse.next = next_c; + field_combo.intr_block_rf.error3_intr_count_incr_r.pulse.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.error3_intr_count_incr_r.pulse.value <= 1'h0; + end else if(field_combo.intr_block_rf.error3_intr_count_incr_r.pulse.load_next) begin + field_storage.intr_block_rf.error3_intr_count_incr_r.pulse.value <= field_combo.intr_block_rf.error3_intr_count_incr_r.pulse.next; + end + end + // Field: doe_reg.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.value; + load_next_c = '0; + if(field_storage.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.value) begin // HW Write - we + next_c = field_storage.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end + if(field_storage.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.value) begin // decrement + field_combo.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.underflow = (next_c < (1'h1)); + next_c = next_c - 1'h1; + load_next_c = '1; + end else begin + field_combo.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.underflow = '0; + end + field_combo.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.decrthreshold = (field_storage.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.value <= 1'd0); + field_combo.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.next = next_c; + field_combo.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.value <= 1'h0; + end else if(field_combo.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.load_next) begin + field_storage.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.value <= field_combo.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.next; + end + end + + //-------------------------------------------------------------------------- + // Write response + //-------------------------------------------------------------------------- + assign cpuif_wr_ack = decoded_req & decoded_req_is_wr; + // Writes are always granted with no error response + assign cpuif_wr_err = '0; + + //-------------------------------------------------------------------------- + // Readback + //-------------------------------------------------------------------------- + + logic readback_err; + logic readback_done; + logic [31:0] readback_data; + + // Assign readback values to a flattened array + logic [25-1:0][31:0] readback_array; + for(genvar i0=0; i0<4; i0++) begin + assign readback_array[i0*1 + 0][31:0] = (decoded_reg_strb.DOE_IV[i0] && !decoded_req_is_wr) ? field_storage.DOE_IV[i0].IV.value : '0; + end + assign readback_array[4][1:0] = (decoded_reg_strb.DOE_CTRL && !decoded_req_is_wr) ? field_storage.DOE_CTRL.CMD.value : '0; + assign readback_array[4][6:2] = (decoded_reg_strb.DOE_CTRL && !decoded_req_is_wr) ? field_storage.DOE_CTRL.DEST.value : '0; + assign readback_array[4][8:7] = (decoded_reg_strb.DOE_CTRL && !decoded_req_is_wr) ? field_storage.DOE_CTRL.CMD_EXT.value : '0; + assign readback_array[4][31:9] = '0; + assign readback_array[5][0:0] = (decoded_reg_strb.DOE_STATUS && !decoded_req_is_wr) ? field_storage.DOE_STATUS.READY.value : '0; + assign readback_array[5][1:1] = (decoded_reg_strb.DOE_STATUS && !decoded_req_is_wr) ? field_storage.DOE_STATUS.VALID.value : '0; + assign readback_array[5][2:2] = (decoded_reg_strb.DOE_STATUS && !decoded_req_is_wr) ? hwif_in.DOE_STATUS.UDS_FLOW_DONE.next : '0; + assign readback_array[5][3:3] = (decoded_reg_strb.DOE_STATUS && !decoded_req_is_wr) ? hwif_in.DOE_STATUS.FE_FLOW_DONE.next : '0; + assign readback_array[5][4:4] = (decoded_reg_strb.DOE_STATUS && !decoded_req_is_wr) ? field_storage.DOE_STATUS.DEOBF_SECRETS_CLEARED.value : '0; + assign readback_array[5][5:5] = (decoded_reg_strb.DOE_STATUS && !decoded_req_is_wr) ? hwif_in.DOE_STATUS.HEK_FLOW_DONE.next : '0; + assign readback_array[5][7:6] = '0; + assign readback_array[5][8:8] = (decoded_reg_strb.DOE_STATUS && !decoded_req_is_wr) ? field_storage.DOE_STATUS.ERROR.value : '0; + assign readback_array[5][31:9] = '0; + assign readback_array[6][0:0] = (decoded_reg_strb.intr_block_rf.global_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.global_intr_en_r.error_en.value : '0; + assign readback_array[6][1:1] = (decoded_reg_strb.intr_block_rf.global_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.global_intr_en_r.notif_en.value : '0; + assign readback_array[6][31:2] = '0; + assign readback_array[7][0:0] = (decoded_reg_strb.intr_block_rf.error_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_en_r.error0_en.value : '0; + assign readback_array[7][1:1] = (decoded_reg_strb.intr_block_rf.error_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_en_r.error1_en.value : '0; + assign readback_array[7][2:2] = (decoded_reg_strb.intr_block_rf.error_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_en_r.error2_en.value : '0; + assign readback_array[7][3:3] = (decoded_reg_strb.intr_block_rf.error_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_en_r.error3_en.value : '0; + assign readback_array[7][31:4] = '0; + assign readback_array[8][0:0] = (decoded_reg_strb.intr_block_rf.notif_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_intr_en_r.notif_cmd_done_en.value : '0; + assign readback_array[8][31:1] = '0; + assign readback_array[9][0:0] = (decoded_reg_strb.intr_block_rf.error_global_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_global_intr_r.agg_sts.value : '0; + assign readback_array[9][31:1] = '0; + assign readback_array[10][0:0] = (decoded_reg_strb.intr_block_rf.notif_global_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_global_intr_r.agg_sts.value : '0; + assign readback_array[10][31:1] = '0; + assign readback_array[11][0:0] = (decoded_reg_strb.intr_block_rf.error_internal_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_internal_intr_r.error0_sts.value : '0; + assign readback_array[11][1:1] = (decoded_reg_strb.intr_block_rf.error_internal_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_internal_intr_r.error1_sts.value : '0; + assign readback_array[11][2:2] = (decoded_reg_strb.intr_block_rf.error_internal_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_internal_intr_r.error2_sts.value : '0; + assign readback_array[11][3:3] = (decoded_reg_strb.intr_block_rf.error_internal_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_internal_intr_r.error3_sts.value : '0; + assign readback_array[11][31:4] = '0; + assign readback_array[12][0:0] = (decoded_reg_strb.intr_block_rf.notif_internal_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.value : '0; + assign readback_array[12][31:1] = '0; + assign readback_array[13][0:0] = (decoded_reg_strb.intr_block_rf.error_intr_trig_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_trig_r.error0_trig.value : '0; + assign readback_array[13][1:1] = (decoded_reg_strb.intr_block_rf.error_intr_trig_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_trig_r.error1_trig.value : '0; + assign readback_array[13][2:2] = (decoded_reg_strb.intr_block_rf.error_intr_trig_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_trig_r.error2_trig.value : '0; + assign readback_array[13][3:3] = (decoded_reg_strb.intr_block_rf.error_intr_trig_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_trig_r.error3_trig.value : '0; + assign readback_array[13][31:4] = '0; + assign readback_array[14][0:0] = (decoded_reg_strb.intr_block_rf.notif_intr_trig_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.value : '0; + assign readback_array[14][31:1] = '0; + assign readback_array[15][31:0] = (decoded_reg_strb.intr_block_rf.error0_intr_count_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error0_intr_count_r.cnt.value : '0; + assign readback_array[16][31:0] = (decoded_reg_strb.intr_block_rf.error1_intr_count_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error1_intr_count_r.cnt.value : '0; + assign readback_array[17][31:0] = (decoded_reg_strb.intr_block_rf.error2_intr_count_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error2_intr_count_r.cnt.value : '0; + assign readback_array[18][31:0] = (decoded_reg_strb.intr_block_rf.error3_intr_count_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error3_intr_count_r.cnt.value : '0; + assign readback_array[19][31:0] = (decoded_reg_strb.intr_block_rf.notif_cmd_done_intr_count_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_cmd_done_intr_count_r.cnt.value : '0; + assign readback_array[20][0:0] = (decoded_reg_strb.intr_block_rf.error0_intr_count_incr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error0_intr_count_incr_r.pulse.value : '0; + assign readback_array[20][31:1] = '0; + assign readback_array[21][0:0] = (decoded_reg_strb.intr_block_rf.error1_intr_count_incr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error1_intr_count_incr_r.pulse.value : '0; + assign readback_array[21][31:1] = '0; + assign readback_array[22][0:0] = (decoded_reg_strb.intr_block_rf.error2_intr_count_incr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error2_intr_count_incr_r.pulse.value : '0; + assign readback_array[22][31:1] = '0; + assign readback_array[23][0:0] = (decoded_reg_strb.intr_block_rf.error3_intr_count_incr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error3_intr_count_incr_r.pulse.value : '0; + assign readback_array[23][31:1] = '0; + assign readback_array[24][0:0] = (decoded_reg_strb.intr_block_rf.notif_cmd_done_intr_count_incr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.value : '0; + assign readback_array[24][31:1] = '0; + + // Reduce the array + always_comb begin + automatic logic [31:0] readback_data_var; + readback_done = decoded_req & ~decoded_req_is_wr; + readback_err = '0; + readback_data_var = '0; + for(int i=0; i<25; i++) readback_data_var |= readback_array[i]; + readback_data = readback_data_var; + end + + assign cpuif_rd_ack = readback_done; + assign cpuif_rd_data = readback_data; + assign cpuif_rd_err = readback_err; + +`CALIPTRA_ASSERT_KNOWN(ERR_HWIF_IN, hwif_in, clk, !hwif_in.cptra_pwrgood) + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/doe_reg_pkg.sv b/designs/Caliptra/src/caliptra-rtl/doe_reg_pkg.sv new file mode 100644 index 0000000..22064b5 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/doe_reg_pkg.sv @@ -0,0 +1,190 @@ +// Generated by PeakRDL-regblock - A free and open-source SystemVerilog generator +// https://github.com/SystemRDL/PeakRDL-regblock + +package doe_reg_pkg; + + localparam DOE_REG_DATA_WIDTH = 32; + localparam DOE_REG_MIN_ADDR_WIDTH = 12; + + typedef struct packed{ + logic hwclr; + } doe_reg__DOE_IV__IV__in_t; + + typedef struct packed{ + doe_reg__DOE_IV__IV__in_t IV; + } doe_reg__DOE_IV__in_t; + + typedef struct packed{ + logic hwclr; + } doe_reg__DOE_CTRL__CMD__in_t; + + typedef struct packed{ + logic hwclr; + } doe_reg__DOE_CTRL__CMD_EXT__in_t; + + typedef struct packed{ + doe_reg__DOE_CTRL__CMD__in_t CMD; + doe_reg__DOE_CTRL__CMD_EXT__in_t CMD_EXT; + } doe_reg__DOE_CTRL__in_t; + + typedef struct packed{ + logic hwclr; + logic hwset; + } doe_reg__DOE_STATUS__READY__in_t; + + typedef struct packed{ + logic hwclr; + logic hwset; + } doe_reg__DOE_STATUS__VALID__in_t; + + typedef struct packed{ + logic next; + } doe_reg__DOE_STATUS__UDS_FLOW_DONE__in_t; + + typedef struct packed{ + logic next; + } doe_reg__DOE_STATUS__FE_FLOW_DONE__in_t; + + typedef struct packed{ + logic hwset; + } doe_reg__DOE_STATUS__DEOBF_SECRETS_CLEARED__in_t; + + typedef struct packed{ + logic next; + } doe_reg__DOE_STATUS__HEK_FLOW_DONE__in_t; + + typedef struct packed{ + logic hwclr; + logic hwset; + } doe_reg__DOE_STATUS__ERROR__in_t; + + typedef struct packed{ + doe_reg__DOE_STATUS__READY__in_t READY; + doe_reg__DOE_STATUS__VALID__in_t VALID; + doe_reg__DOE_STATUS__UDS_FLOW_DONE__in_t UDS_FLOW_DONE; + doe_reg__DOE_STATUS__FE_FLOW_DONE__in_t FE_FLOW_DONE; + doe_reg__DOE_STATUS__DEOBF_SECRETS_CLEARED__in_t DEOBF_SECRETS_CLEARED; + doe_reg__DOE_STATUS__HEK_FLOW_DONE__in_t HEK_FLOW_DONE; + doe_reg__DOE_STATUS__ERROR__in_t ERROR; + } doe_reg__DOE_STATUS__in_t; + + typedef struct packed{ + logic hwset; + } doe_reg__error_intr_t_error0_sts_5ee134bf_error1_sts_aad9583f_error2_sts_6cad4575_error3_sts_735bbeba__error0_sts_enable_528ccada_next_b1018582_resetsignal_f7aac87a__in_t; + + typedef struct packed{ + logic hwset; + } doe_reg__error_intr_t_error0_sts_5ee134bf_error1_sts_aad9583f_error2_sts_6cad4575_error3_sts_735bbeba__error1_sts_enable_938cafef_next_f460eb81_resetsignal_f7aac87a__in_t; + + typedef struct packed{ + logic hwset; + } doe_reg__error_intr_t_error0_sts_5ee134bf_error1_sts_aad9583f_error2_sts_6cad4575_error3_sts_735bbeba__error2_sts_enable_0dacf7a6_next_4b5b9e74_resetsignal_f7aac87a__in_t; + + typedef struct packed{ + logic hwset; + } doe_reg__error_intr_t_error0_sts_5ee134bf_error1_sts_aad9583f_error2_sts_6cad4575_error3_sts_735bbeba__error3_sts_enable_fc3af94b_next_c3125d40_resetsignal_f7aac87a__in_t; + + typedef struct packed{ + doe_reg__error_intr_t_error0_sts_5ee134bf_error1_sts_aad9583f_error2_sts_6cad4575_error3_sts_735bbeba__error0_sts_enable_528ccada_next_b1018582_resetsignal_f7aac87a__in_t error0_sts; + doe_reg__error_intr_t_error0_sts_5ee134bf_error1_sts_aad9583f_error2_sts_6cad4575_error3_sts_735bbeba__error1_sts_enable_938cafef_next_f460eb81_resetsignal_f7aac87a__in_t error1_sts; + doe_reg__error_intr_t_error0_sts_5ee134bf_error1_sts_aad9583f_error2_sts_6cad4575_error3_sts_735bbeba__error2_sts_enable_0dacf7a6_next_4b5b9e74_resetsignal_f7aac87a__in_t error2_sts; + doe_reg__error_intr_t_error0_sts_5ee134bf_error1_sts_aad9583f_error2_sts_6cad4575_error3_sts_735bbeba__error3_sts_enable_fc3af94b_next_c3125d40_resetsignal_f7aac87a__in_t error3_sts; + } doe_reg__error_intr_t_error0_sts_5ee134bf_error1_sts_aad9583f_error2_sts_6cad4575_error3_sts_735bbeba__in_t; + + typedef struct packed{ + logic hwset; + } doe_reg__notif_intr_t_notif_cmd_done_sts_1c68637e__notif_cmd_done_sts_enable_dabe0b8b_next_540fa3b7__in_t; + + typedef struct packed{ + doe_reg__notif_intr_t_notif_cmd_done_sts_1c68637e__notif_cmd_done_sts_enable_dabe0b8b_next_540fa3b7__in_t notif_cmd_done_sts; + } doe_reg__notif_intr_t_notif_cmd_done_sts_1c68637e__in_t; + + typedef struct packed{ + doe_reg__error_intr_t_error0_sts_5ee134bf_error1_sts_aad9583f_error2_sts_6cad4575_error3_sts_735bbeba__in_t error_internal_intr_r; + doe_reg__notif_intr_t_notif_cmd_done_sts_1c68637e__in_t notif_internal_intr_r; + } doe_reg__intr_block_t__in_t; + + typedef struct packed{ + logic reset_b; + logic cptra_pwrgood; + doe_reg__DOE_IV__in_t [4-1:0]DOE_IV; + doe_reg__DOE_CTRL__in_t DOE_CTRL; + doe_reg__DOE_STATUS__in_t DOE_STATUS; + doe_reg__intr_block_t__in_t intr_block_rf; + } doe_reg__in_t; + + typedef struct packed{ + logic [31:0] value; + logic swmod; + } doe_reg__DOE_IV__IV__out_t; + + typedef struct packed{ + doe_reg__DOE_IV__IV__out_t IV; + } doe_reg__DOE_IV__out_t; + + typedef struct packed{ + logic [1:0] value; + logic swmod; + } doe_reg__DOE_CTRL__CMD__out_t; + + typedef struct packed{ + logic [4:0] value; + } doe_reg__DOE_CTRL__DEST__out_t; + + typedef struct packed{ + logic [1:0] value; + logic swmod; + } doe_reg__DOE_CTRL__CMD_EXT__out_t; + + typedef struct packed{ + doe_reg__DOE_CTRL__CMD__out_t CMD; + doe_reg__DOE_CTRL__DEST__out_t DEST; + doe_reg__DOE_CTRL__CMD_EXT__out_t CMD_EXT; + } doe_reg__DOE_CTRL__out_t; + + typedef struct packed{ + logic intr; + } doe_reg__global_intr_t_agg_sts_dd3dcf0a__out_t; + + typedef struct packed{ + logic intr; + } doe_reg__global_intr_t_agg_sts_e6399b4a__out_t; + + typedef struct packed{ + logic intr; + } doe_reg__error_intr_t_error0_sts_5ee134bf_error1_sts_aad9583f_error2_sts_6cad4575_error3_sts_735bbeba__out_t; + + typedef struct packed{ + logic intr; + } doe_reg__notif_intr_t_notif_cmd_done_sts_1c68637e__out_t; + + typedef struct packed{ + doe_reg__global_intr_t_agg_sts_dd3dcf0a__out_t error_global_intr_r; + doe_reg__global_intr_t_agg_sts_e6399b4a__out_t notif_global_intr_r; + doe_reg__error_intr_t_error0_sts_5ee134bf_error1_sts_aad9583f_error2_sts_6cad4575_error3_sts_735bbeba__out_t error_internal_intr_r; + doe_reg__notif_intr_t_notif_cmd_done_sts_1c68637e__out_t notif_internal_intr_r; + } doe_reg__intr_block_t__out_t; + + typedef struct packed{ + doe_reg__DOE_IV__out_t [4-1:0]DOE_IV; + doe_reg__DOE_CTRL__out_t DOE_CTRL; + doe_reg__intr_block_t__out_t intr_block_rf; + } doe_reg__out_t; + + typedef enum logic [31:0] { + doe_reg__DOE_CTRL__CMD__doe_cmd_e__DOE_IDLE = 'h0, + doe_reg__DOE_CTRL__CMD__doe_cmd_e__DOE_UDS = 'h1, + doe_reg__DOE_CTRL__CMD__doe_cmd_e__DOE_FE = 'h2, + doe_reg__DOE_CTRL__CMD__doe_cmd_e__DOE_CLEAR_OBF_SECRETS = 'h3 + } doe_reg__DOE_CTRL__CMD__doe_cmd_e_e; + + typedef enum logic [31:0] { + doe_reg__DOE_CTRL__CMD_EXT__doe_cmd_ext_e__DOE_STD = 'h0, + doe_reg__DOE_CTRL__CMD_EXT__doe_cmd_ext_e__DOE_HEK = 'h1, + doe_reg__DOE_CTRL__CMD_EXT__doe_cmd_ext_e__DOE_RSVD0 = 'h2, + doe_reg__DOE_CTRL__CMD_EXT__doe_cmd_ext_e__DOE_RSVD1 = 'h3 + } doe_reg__DOE_CTRL__CMD_EXT__doe_cmd_ext_e_e; + + localparam DOE_REG_ADDR_WIDTH = 32'd12; + +endpackage \ No newline at end of file diff --git a/designs/Caliptra/src/caliptra-rtl/doe_sbox.sv b/designs/Caliptra/src/caliptra-rtl/doe_sbox.sv new file mode 100644 index 0000000..4e7825e --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/doe_sbox.sv @@ -0,0 +1,325 @@ +//====================================================================== +// +// doe_sbox.v +// ---------- +// The DOE S-box. Basically a 256 Byte ROM. This implementation +// contains four parallel S-boxes to handle a 32 bit word. +// +// +// Author: Joachim Strombergson +// Copyright (c) 2014, Secworks Sweden AB +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or +// without modification, are permitted provided that the following +// conditions are met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in +// the documentation and/or other materials provided with the +// distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +//====================================================================== + +module doe_sbox( + input wire [31 : 0] sboxw, + output wire [31 : 0] new_sboxw + ); + + + //---------------------------------------------------------------- + // The sbox array. + //---------------------------------------------------------------- + wire [7 : 0] sbox [255 : 0]; + + + //---------------------------------------------------------------- + // Four parallel muxes. + //---------------------------------------------------------------- + assign new_sboxw[31 : 24] = sbox[sboxw[31 : 24]]; + assign new_sboxw[23 : 16] = sbox[sboxw[23 : 16]]; + assign new_sboxw[15 : 08] = sbox[sboxw[15 : 08]]; + assign new_sboxw[07 : 00] = sbox[sboxw[07 : 00]]; + + + //---------------------------------------------------------------- + // Creating the sbox array contents. + //---------------------------------------------------------------- + assign sbox[8'h00] = 8'h63; + assign sbox[8'h01] = 8'h7c; + assign sbox[8'h02] = 8'h77; + assign sbox[8'h03] = 8'h7b; + assign sbox[8'h04] = 8'hf2; + assign sbox[8'h05] = 8'h6b; + assign sbox[8'h06] = 8'h6f; + assign sbox[8'h07] = 8'hc5; + assign sbox[8'h08] = 8'h30; + assign sbox[8'h09] = 8'h01; + assign sbox[8'h0a] = 8'h67; + assign sbox[8'h0b] = 8'h2b; + assign sbox[8'h0c] = 8'hfe; + assign sbox[8'h0d] = 8'hd7; + assign sbox[8'h0e] = 8'hab; + assign sbox[8'h0f] = 8'h76; + assign sbox[8'h10] = 8'hca; + assign sbox[8'h11] = 8'h82; + assign sbox[8'h12] = 8'hc9; + assign sbox[8'h13] = 8'h7d; + assign sbox[8'h14] = 8'hfa; + assign sbox[8'h15] = 8'h59; + assign sbox[8'h16] = 8'h47; + assign sbox[8'h17] = 8'hf0; + assign sbox[8'h18] = 8'had; + assign sbox[8'h19] = 8'hd4; + assign sbox[8'h1a] = 8'ha2; + assign sbox[8'h1b] = 8'haf; + assign sbox[8'h1c] = 8'h9c; + assign sbox[8'h1d] = 8'ha4; + assign sbox[8'h1e] = 8'h72; + assign sbox[8'h1f] = 8'hc0; + assign sbox[8'h20] = 8'hb7; + assign sbox[8'h21] = 8'hfd; + assign sbox[8'h22] = 8'h93; + assign sbox[8'h23] = 8'h26; + assign sbox[8'h24] = 8'h36; + assign sbox[8'h25] = 8'h3f; + assign sbox[8'h26] = 8'hf7; + assign sbox[8'h27] = 8'hcc; + assign sbox[8'h28] = 8'h34; + assign sbox[8'h29] = 8'ha5; + assign sbox[8'h2a] = 8'he5; + assign sbox[8'h2b] = 8'hf1; + assign sbox[8'h2c] = 8'h71; + assign sbox[8'h2d] = 8'hd8; + assign sbox[8'h2e] = 8'h31; + assign sbox[8'h2f] = 8'h15; + assign sbox[8'h30] = 8'h04; + assign sbox[8'h31] = 8'hc7; + assign sbox[8'h32] = 8'h23; + assign sbox[8'h33] = 8'hc3; + assign sbox[8'h34] = 8'h18; + assign sbox[8'h35] = 8'h96; + assign sbox[8'h36] = 8'h05; + assign sbox[8'h37] = 8'h9a; + assign sbox[8'h38] = 8'h07; + assign sbox[8'h39] = 8'h12; + assign sbox[8'h3a] = 8'h80; + assign sbox[8'h3b] = 8'he2; + assign sbox[8'h3c] = 8'heb; + assign sbox[8'h3d] = 8'h27; + assign sbox[8'h3e] = 8'hb2; + assign sbox[8'h3f] = 8'h75; + assign sbox[8'h40] = 8'h09; + assign sbox[8'h41] = 8'h83; + assign sbox[8'h42] = 8'h2c; + assign sbox[8'h43] = 8'h1a; + assign sbox[8'h44] = 8'h1b; + assign sbox[8'h45] = 8'h6e; + assign sbox[8'h46] = 8'h5a; + assign sbox[8'h47] = 8'ha0; + assign sbox[8'h48] = 8'h52; + assign sbox[8'h49] = 8'h3b; + assign sbox[8'h4a] = 8'hd6; + assign sbox[8'h4b] = 8'hb3; + assign sbox[8'h4c] = 8'h29; + assign sbox[8'h4d] = 8'he3; + assign sbox[8'h4e] = 8'h2f; + assign sbox[8'h4f] = 8'h84; + assign sbox[8'h50] = 8'h53; + assign sbox[8'h51] = 8'hd1; + assign sbox[8'h52] = 8'h00; + assign sbox[8'h53] = 8'hed; + assign sbox[8'h54] = 8'h20; + assign sbox[8'h55] = 8'hfc; + assign sbox[8'h56] = 8'hb1; + assign sbox[8'h57] = 8'h5b; + assign sbox[8'h58] = 8'h6a; + assign sbox[8'h59] = 8'hcb; + assign sbox[8'h5a] = 8'hbe; + assign sbox[8'h5b] = 8'h39; + assign sbox[8'h5c] = 8'h4a; + assign sbox[8'h5d] = 8'h4c; + assign sbox[8'h5e] = 8'h58; + assign sbox[8'h5f] = 8'hcf; + assign sbox[8'h60] = 8'hd0; + assign sbox[8'h61] = 8'hef; + assign sbox[8'h62] = 8'haa; + assign sbox[8'h63] = 8'hfb; + assign sbox[8'h64] = 8'h43; + assign sbox[8'h65] = 8'h4d; + assign sbox[8'h66] = 8'h33; + assign sbox[8'h67] = 8'h85; + assign sbox[8'h68] = 8'h45; + assign sbox[8'h69] = 8'hf9; + assign sbox[8'h6a] = 8'h02; + assign sbox[8'h6b] = 8'h7f; + assign sbox[8'h6c] = 8'h50; + assign sbox[8'h6d] = 8'h3c; + assign sbox[8'h6e] = 8'h9f; + assign sbox[8'h6f] = 8'ha8; + assign sbox[8'h70] = 8'h51; + assign sbox[8'h71] = 8'ha3; + assign sbox[8'h72] = 8'h40; + assign sbox[8'h73] = 8'h8f; + assign sbox[8'h74] = 8'h92; + assign sbox[8'h75] = 8'h9d; + assign sbox[8'h76] = 8'h38; + assign sbox[8'h77] = 8'hf5; + assign sbox[8'h78] = 8'hbc; + assign sbox[8'h79] = 8'hb6; + assign sbox[8'h7a] = 8'hda; + assign sbox[8'h7b] = 8'h21; + assign sbox[8'h7c] = 8'h10; + assign sbox[8'h7d] = 8'hff; + assign sbox[8'h7e] = 8'hf3; + assign sbox[8'h7f] = 8'hd2; + assign sbox[8'h80] = 8'hcd; + assign sbox[8'h81] = 8'h0c; + assign sbox[8'h82] = 8'h13; + assign sbox[8'h83] = 8'hec; + assign sbox[8'h84] = 8'h5f; + assign sbox[8'h85] = 8'h97; + assign sbox[8'h86] = 8'h44; + assign sbox[8'h87] = 8'h17; + assign sbox[8'h88] = 8'hc4; + assign sbox[8'h89] = 8'ha7; + assign sbox[8'h8a] = 8'h7e; + assign sbox[8'h8b] = 8'h3d; + assign sbox[8'h8c] = 8'h64; + assign sbox[8'h8d] = 8'h5d; + assign sbox[8'h8e] = 8'h19; + assign sbox[8'h8f] = 8'h73; + assign sbox[8'h90] = 8'h60; + assign sbox[8'h91] = 8'h81; + assign sbox[8'h92] = 8'h4f; + assign sbox[8'h93] = 8'hdc; + assign sbox[8'h94] = 8'h22; + assign sbox[8'h95] = 8'h2a; + assign sbox[8'h96] = 8'h90; + assign sbox[8'h97] = 8'h88; + assign sbox[8'h98] = 8'h46; + assign sbox[8'h99] = 8'hee; + assign sbox[8'h9a] = 8'hb8; + assign sbox[8'h9b] = 8'h14; + assign sbox[8'h9c] = 8'hde; + assign sbox[8'h9d] = 8'h5e; + assign sbox[8'h9e] = 8'h0b; + assign sbox[8'h9f] = 8'hdb; + assign sbox[8'ha0] = 8'he0; + assign sbox[8'ha1] = 8'h32; + assign sbox[8'ha2] = 8'h3a; + assign sbox[8'ha3] = 8'h0a; + assign sbox[8'ha4] = 8'h49; + assign sbox[8'ha5] = 8'h06; + assign sbox[8'ha6] = 8'h24; + assign sbox[8'ha7] = 8'h5c; + assign sbox[8'ha8] = 8'hc2; + assign sbox[8'ha9] = 8'hd3; + assign sbox[8'haa] = 8'hac; + assign sbox[8'hab] = 8'h62; + assign sbox[8'hac] = 8'h91; + assign sbox[8'had] = 8'h95; + assign sbox[8'hae] = 8'he4; + assign sbox[8'haf] = 8'h79; + assign sbox[8'hb0] = 8'he7; + assign sbox[8'hb1] = 8'hc8; + assign sbox[8'hb2] = 8'h37; + assign sbox[8'hb3] = 8'h6d; + assign sbox[8'hb4] = 8'h8d; + assign sbox[8'hb5] = 8'hd5; + assign sbox[8'hb6] = 8'h4e; + assign sbox[8'hb7] = 8'ha9; + assign sbox[8'hb8] = 8'h6c; + assign sbox[8'hb9] = 8'h56; + assign sbox[8'hba] = 8'hf4; + assign sbox[8'hbb] = 8'hea; + assign sbox[8'hbc] = 8'h65; + assign sbox[8'hbd] = 8'h7a; + assign sbox[8'hbe] = 8'hae; + assign sbox[8'hbf] = 8'h08; + assign sbox[8'hc0] = 8'hba; + assign sbox[8'hc1] = 8'h78; + assign sbox[8'hc2] = 8'h25; + assign sbox[8'hc3] = 8'h2e; + assign sbox[8'hc4] = 8'h1c; + assign sbox[8'hc5] = 8'ha6; + assign sbox[8'hc6] = 8'hb4; + assign sbox[8'hc7] = 8'hc6; + assign sbox[8'hc8] = 8'he8; + assign sbox[8'hc9] = 8'hdd; + assign sbox[8'hca] = 8'h74; + assign sbox[8'hcb] = 8'h1f; + assign sbox[8'hcc] = 8'h4b; + assign sbox[8'hcd] = 8'hbd; + assign sbox[8'hce] = 8'h8b; + assign sbox[8'hcf] = 8'h8a; + assign sbox[8'hd0] = 8'h70; + assign sbox[8'hd1] = 8'h3e; + assign sbox[8'hd2] = 8'hb5; + assign sbox[8'hd3] = 8'h66; + assign sbox[8'hd4] = 8'h48; + assign sbox[8'hd5] = 8'h03; + assign sbox[8'hd6] = 8'hf6; + assign sbox[8'hd7] = 8'h0e; + assign sbox[8'hd8] = 8'h61; + assign sbox[8'hd9] = 8'h35; + assign sbox[8'hda] = 8'h57; + assign sbox[8'hdb] = 8'hb9; + assign sbox[8'hdc] = 8'h86; + assign sbox[8'hdd] = 8'hc1; + assign sbox[8'hde] = 8'h1d; + assign sbox[8'hdf] = 8'h9e; + assign sbox[8'he0] = 8'he1; + assign sbox[8'he1] = 8'hf8; + assign sbox[8'he2] = 8'h98; + assign sbox[8'he3] = 8'h11; + assign sbox[8'he4] = 8'h69; + assign sbox[8'he5] = 8'hd9; + assign sbox[8'he6] = 8'h8e; + assign sbox[8'he7] = 8'h94; + assign sbox[8'he8] = 8'h9b; + assign sbox[8'he9] = 8'h1e; + assign sbox[8'hea] = 8'h87; + assign sbox[8'heb] = 8'he9; + assign sbox[8'hec] = 8'hce; + assign sbox[8'hed] = 8'h55; + assign sbox[8'hee] = 8'h28; + assign sbox[8'hef] = 8'hdf; + assign sbox[8'hf0] = 8'h8c; + assign sbox[8'hf1] = 8'ha1; + assign sbox[8'hf2] = 8'h89; + assign sbox[8'hf3] = 8'h0d; + assign sbox[8'hf4] = 8'hbf; + assign sbox[8'hf5] = 8'he6; + assign sbox[8'hf6] = 8'h42; + assign sbox[8'hf7] = 8'h68; + assign sbox[8'hf8] = 8'h41; + assign sbox[8'hf9] = 8'h99; + assign sbox[8'hfa] = 8'h2d; + assign sbox[8'hfb] = 8'h0f; + assign sbox[8'hfc] = 8'hb0; + assign sbox[8'hfd] = 8'h54; + assign sbox[8'hfe] = 8'hbb; + assign sbox[8'hff] = 8'h16; + +endmodule // doe_sbox + +//====================================================================== +// EOF doe_sbox.v +//====================================================================== diff --git a/designs/Caliptra/src/caliptra-rtl/dv.sv b/designs/Caliptra/src/caliptra-rtl/dv.sv new file mode 100644 index 0000000..a4f2e45 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/dv.sv @@ -0,0 +1,153 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +// + + +`include "caliptra_macros.svh" + +module dv + import dv_defines_pkg::*; + import dv_reg_pkg::*; + + #( + parameter AHB_ADDR_WIDTH = DV_ADDR_W + ,parameter AHB_DATA_WIDTH = 32 + ) + ( + input logic clk, + input logic rst_b, + input logic core_only_rst_b, + input logic cptra_pwrgood, + + + //uC AHB Lite Interface + //from SLAVES PORT + input logic [AHB_ADDR_WIDTH-1:0] haddr_i, + input logic [AHB_DATA_WIDTH-1:0] hwdata_i, + input logic hsel_i, + input logic hwrite_i, + input logic hready_i, + input logic [1:0] htrans_i, + input logic [2:0] hsize_i, + + output logic hresp_o, + output logic hreadyout_o, + output logic [AHB_DATA_WIDTH-1:0] hrdata_o + +); + +logic uc_req_dv, uc_req_hold; +logic uc_req_error; +logic [31:0] uc_req_rdata; +logic dv_reg_read_error, dv_reg_write_error; +dv_uc_req_t uc_req; + +dv_reg__in_t dv_reg_hwif_in; +dv_reg__out_t dv_reg_hwif_out; + +ahb_slv_sif #( + .AHB_ADDR_WIDTH(AHB_ADDR_WIDTH), + .AHB_DATA_WIDTH(AHB_DATA_WIDTH), + .CLIENT_DATA_WIDTH(32) +) +dv_ahb_slv1 ( + //AMBA AHB Lite INF + .hclk(clk), + .hreset_n(rst_b), + .haddr_i(haddr_i), + .hwdata_i(hwdata_i), + .hsel_i(hsel_i), + .hwrite_i(hwrite_i), + .hready_i(hready_i), + .htrans_i(htrans_i), + .hsize_i(hsize_i), + + .hresp_o(hresp_o), + .hreadyout_o(hreadyout_o), + .hrdata_o(hrdata_o), + + + //COMPONENT INF + .dv(uc_req_dv), + .hld(uc_req_hold), + .err(uc_req_error), + .write(uc_req.write), + .wdata(uc_req.wdata), + .addr(uc_req.addr), + + .rdata(uc_req_rdata) +); + +always_comb uc_req_error = dv_reg_read_error | dv_reg_write_error; +always_comb uc_req_hold = '0; + +// Sticky (when lock is set, locked until cold reset) & Non-sticky (when lock is set, locked until warm reset) Generic DataVault registers. +always_comb begin: datavault + + //Sticky Data Vault Regs & Controls + for (int entry = 0; entry < STICKY_DV_NUM_ENTRIES; entry++) begin + dv_reg_hwif_in.StickyDataVaultCtrl[entry].lock_entry.swwel = dv_reg_hwif_out.StickyDataVaultCtrl[entry].lock_entry.value; + for (int dword = 0; dword < DV_NUM_DWORDS; dword++) begin + dv_reg_hwif_in.STICKY_DATA_VAULT_ENTRY[entry][dword].data.swwel = dv_reg_hwif_out.StickyDataVaultCtrl[entry].lock_entry.value; + end + end + + //Non-Sticky Data Vault Regs & Controls + for (int entry = 0; entry < DV_NUM_ENTRIES; entry++) begin + dv_reg_hwif_in.DataVaultCtrl[entry].lock_entry.swwel = dv_reg_hwif_out.DataVaultCtrl[entry].lock_entry.value; + for (int dword = 0; dword < DV_NUM_DWORDS; dword++) begin + dv_reg_hwif_in.DATA_VAULT_ENTRY[entry][dword].data.swwel = dv_reg_hwif_out.DataVaultCtrl[entry].lock_entry.value; + end + end + + //Non-Sticky Generic Lockable Registers in the Data Vault + for (int entry = 0; entry < LOCK_SCRATCH_NUM_ENTRIES; entry++) begin + dv_reg_hwif_in.LockableScratchRegCtrl[entry].lock_entry.swwel = dv_reg_hwif_out.LockableScratchRegCtrl[entry].lock_entry.value; + dv_reg_hwif_in.LockableScratchReg[entry].data.swwel = dv_reg_hwif_out.LockableScratchRegCtrl[entry].lock_entry.value; + end + + //Sticky Generic Lockable Registers in the Data Vault + for (int entry = 0; entry < STICKY_LOCK_SCRATCH_NUM_ENTRIES; entry++) begin + dv_reg_hwif_in.StickyLockableScratchRegCtrl[entry].lock_entry.swwel = dv_reg_hwif_out.StickyLockableScratchRegCtrl[entry].lock_entry.value; + dv_reg_hwif_in.StickyLockableScratchReg[entry].data.swwel = dv_reg_hwif_out.StickyLockableScratchRegCtrl[entry].lock_entry.value; + end + +end + +always_comb dv_reg_hwif_in.hard_reset_b = cptra_pwrgood; +always_comb dv_reg_hwif_in.reset_b = rst_b; +always_comb dv_reg_hwif_in.core_only_rst_b = core_only_rst_b; //Note that this signal will also reset when rst_b is asserted + +dv_reg dv_reg1 ( + .clk(clk), + .rst('0), + //qualify request so no addresses alias + .s_cpuif_req(uc_req_dv & (uc_req.addr[DV_ADDR_W-1:DV_REG_ADDR_WIDTH] == '0)), + .s_cpuif_req_is_wr(uc_req.write), + .s_cpuif_addr(uc_req.addr[DV_REG_ADDR_WIDTH-1:0]), + .s_cpuif_wr_data(uc_req.wdata), + .s_cpuif_wr_biten('1), + .s_cpuif_req_stall_wr(), + .s_cpuif_req_stall_rd(), + .s_cpuif_rd_ack(), + .s_cpuif_rd_err(dv_reg_read_error), + .s_cpuif_rd_data(uc_req_rdata), + .s_cpuif_wr_ack(), + .s_cpuif_wr_err(dv_reg_write_error), + + .hwif_in(dv_reg_hwif_in), + .hwif_out(dv_reg_hwif_out) +); + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/dv_defines_pkg.sv b/designs/Caliptra/src/caliptra-rtl/dv_defines_pkg.sv new file mode 100644 index 0000000..7ff199f --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/dv_defines_pkg.sv @@ -0,0 +1,40 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +// +`ifndef DV_DEFINES_PKG +`define DV_DEFINES_PKG + +package dv_defines_pkg; + + parameter DV_ADDR_W = 13; + parameter DV_DATA_W = 32; + + parameter STICKY_DV_NUM_ENTRIES = 10; + parameter DV_NUM_ENTRIES = 10; + parameter LOCK_SCRATCH_NUM_ENTRIES = 10; + parameter STICKY_LOCK_SCRATCH_NUM_ENTRIES = 8; + parameter NONSTICKY_SCRATCH_NUM_ENTRIES = 8; + parameter DV_NUM_DWORDS = 12; + +typedef struct packed { + logic [DV_ADDR_W-1:0] addr; + logic [DV_DATA_W-1:0] wdata; + logic write; +} dv_uc_req_t; + +endpackage + +`endif + + diff --git a/designs/Caliptra/src/caliptra-rtl/dv_reg.sv b/designs/Caliptra/src/caliptra-rtl/dv_reg.sv new file mode 100644 index 0000000..3cf9a61 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/dv_reg.sv @@ -0,0 +1,511 @@ +// Generated by PeakRDL-regblock - A free and open-source SystemVerilog generator +// https://github.com/SystemRDL/PeakRDL-regblock + +module dv_reg ( + input wire clk, + input wire rst, + + input wire s_cpuif_req, + input wire s_cpuif_req_is_wr, + input wire [10:0] s_cpuif_addr, + input wire [31:0] s_cpuif_wr_data, + input wire [31:0] s_cpuif_wr_biten, + output wire s_cpuif_req_stall_wr, + output wire s_cpuif_req_stall_rd, + output wire s_cpuif_rd_ack, + output wire s_cpuif_rd_err, + output wire [31:0] s_cpuif_rd_data, + output wire s_cpuif_wr_ack, + output wire s_cpuif_wr_err, + + input dv_reg_pkg::dv_reg__in_t hwif_in, + output dv_reg_pkg::dv_reg__out_t hwif_out + ); + + //-------------------------------------------------------------------------- + // CPU Bus interface logic + //-------------------------------------------------------------------------- + logic cpuif_req; + logic cpuif_req_is_wr; + logic [10:0] cpuif_addr; + logic [31:0] cpuif_wr_data; + logic [31:0] cpuif_wr_biten; + logic cpuif_req_stall_wr; + logic cpuif_req_stall_rd; + + logic cpuif_rd_ack; + logic cpuif_rd_err; + logic [31:0] cpuif_rd_data; + + logic cpuif_wr_ack; + logic cpuif_wr_err; + + assign cpuif_req = s_cpuif_req; + assign cpuif_req_is_wr = s_cpuif_req_is_wr; + assign cpuif_addr = s_cpuif_addr; + assign cpuif_wr_data = s_cpuif_wr_data; + assign cpuif_wr_biten = s_cpuif_wr_biten; + assign s_cpuif_req_stall_wr = cpuif_req_stall_wr; + assign s_cpuif_req_stall_rd = cpuif_req_stall_rd; + assign s_cpuif_rd_ack = cpuif_rd_ack; + assign s_cpuif_rd_err = cpuif_rd_err; + assign s_cpuif_rd_data = cpuif_rd_data; + assign s_cpuif_wr_ack = cpuif_wr_ack; + assign s_cpuif_wr_err = cpuif_wr_err; + + logic cpuif_req_masked; + + // Read & write latencies are balanced. Stalls not required + assign cpuif_req_stall_rd = '0; + assign cpuif_req_stall_wr = '0; + assign cpuif_req_masked = cpuif_req + & !(!cpuif_req_is_wr & cpuif_req_stall_rd) + & !(cpuif_req_is_wr & cpuif_req_stall_wr); + + //-------------------------------------------------------------------------- + // Address Decode + //-------------------------------------------------------------------------- + typedef struct packed{ + logic [10-1:0]StickyDataVaultCtrl; + logic [10-1:0][12-1:0]STICKY_DATA_VAULT_ENTRY; + logic [10-1:0]DataVaultCtrl; + logic [10-1:0][12-1:0]DATA_VAULT_ENTRY; + logic [10-1:0]LockableScratchRegCtrl; + logic [10-1:0]LockableScratchReg; + logic [8-1:0]NonStickyGenericScratchReg; + logic [8-1:0]StickyLockableScratchRegCtrl; + logic [8-1:0]StickyLockableScratchReg; + } decoded_reg_strb_t; + decoded_reg_strb_t decoded_reg_strb; + logic decoded_req; + logic decoded_req_is_wr; + logic [31:0] decoded_wr_data; + logic [31:0] decoded_wr_biten; + + always_comb begin + for(int i0=0; i0<10; i0++) begin + decoded_reg_strb.StickyDataVaultCtrl[i0] = cpuif_req_masked & (cpuif_addr == 11'h0 + i0*11'h4); + end + for(int i0=0; i0<10; i0++) begin + for(int i1=0; i1<12; i1++) begin + decoded_reg_strb.STICKY_DATA_VAULT_ENTRY[i0][i1] = cpuif_req_masked & (cpuif_addr == 11'h28 + i0*11'h30 + i1*11'h4); + end + end + for(int i0=0; i0<10; i0++) begin + decoded_reg_strb.DataVaultCtrl[i0] = cpuif_req_masked & (cpuif_addr == 11'h208 + i0*11'h4); + end + for(int i0=0; i0<10; i0++) begin + for(int i1=0; i1<12; i1++) begin + decoded_reg_strb.DATA_VAULT_ENTRY[i0][i1] = cpuif_req_masked & (cpuif_addr == 11'h230 + i0*11'h30 + i1*11'h4); + end + end + for(int i0=0; i0<10; i0++) begin + decoded_reg_strb.LockableScratchRegCtrl[i0] = cpuif_req_masked & (cpuif_addr == 11'h410 + i0*11'h4); + end + for(int i0=0; i0<10; i0++) begin + decoded_reg_strb.LockableScratchReg[i0] = cpuif_req_masked & (cpuif_addr == 11'h438 + i0*11'h4); + end + for(int i0=0; i0<8; i0++) begin + decoded_reg_strb.NonStickyGenericScratchReg[i0] = cpuif_req_masked & (cpuif_addr == 11'h460 + i0*11'h4); + end + for(int i0=0; i0<8; i0++) begin + decoded_reg_strb.StickyLockableScratchRegCtrl[i0] = cpuif_req_masked & (cpuif_addr == 11'h480 + i0*11'h4); + end + for(int i0=0; i0<8; i0++) begin + decoded_reg_strb.StickyLockableScratchReg[i0] = cpuif_req_masked & (cpuif_addr == 11'h4a0 + i0*11'h4); + end + end + + // Pass down signals to next stage + assign decoded_req = cpuif_req_masked; + assign decoded_req_is_wr = cpuif_req_is_wr; + assign decoded_wr_data = cpuif_wr_data; + assign decoded_wr_biten = cpuif_wr_biten; + + //-------------------------------------------------------------------------- + // Field logic + //-------------------------------------------------------------------------- + typedef struct packed{ + struct packed{ + struct packed{ + logic next; + logic load_next; + } lock_entry; + } [10-1:0]StickyDataVaultCtrl; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } data; + } [10-1:0][12-1:0]STICKY_DATA_VAULT_ENTRY; + struct packed{ + struct packed{ + logic next; + logic load_next; + } lock_entry; + } [10-1:0]DataVaultCtrl; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } data; + } [10-1:0][12-1:0]DATA_VAULT_ENTRY; + struct packed{ + struct packed{ + logic next; + logic load_next; + } lock_entry; + } [10-1:0]LockableScratchRegCtrl; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } data; + } [10-1:0]LockableScratchReg; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } data; + } [8-1:0]NonStickyGenericScratchReg; + struct packed{ + struct packed{ + logic next; + logic load_next; + } lock_entry; + } [8-1:0]StickyLockableScratchRegCtrl; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } data; + } [8-1:0]StickyLockableScratchReg; + } field_combo_t; + field_combo_t field_combo; + + typedef struct packed{ + struct packed{ + struct packed{ + logic value; + } lock_entry; + } [10-1:0]StickyDataVaultCtrl; + struct packed{ + struct packed{ + logic [31:0] value; + } data; + } [10-1:0][12-1:0]STICKY_DATA_VAULT_ENTRY; + struct packed{ + struct packed{ + logic value; + } lock_entry; + } [10-1:0]DataVaultCtrl; + struct packed{ + struct packed{ + logic [31:0] value; + } data; + } [10-1:0][12-1:0]DATA_VAULT_ENTRY; + struct packed{ + struct packed{ + logic value; + } lock_entry; + } [10-1:0]LockableScratchRegCtrl; + struct packed{ + struct packed{ + logic [31:0] value; + } data; + } [10-1:0]LockableScratchReg; + struct packed{ + struct packed{ + logic [31:0] value; + } data; + } [8-1:0]NonStickyGenericScratchReg; + struct packed{ + struct packed{ + logic value; + } lock_entry; + } [8-1:0]StickyLockableScratchRegCtrl; + struct packed{ + struct packed{ + logic [31:0] value; + } data; + } [8-1:0]StickyLockableScratchReg; + } field_storage_t; + field_storage_t field_storage; + + for(genvar i0=0; i0<10; i0++) begin + // Field: dv_reg.StickyDataVaultCtrl[].lock_entry + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.StickyDataVaultCtrl[i0].lock_entry.value; + load_next_c = '0; + if(decoded_reg_strb.StickyDataVaultCtrl[i0] && decoded_req_is_wr && !(hwif_in.StickyDataVaultCtrl[i0].lock_entry.swwel)) begin // SW write + next_c = (field_storage.StickyDataVaultCtrl[i0].lock_entry.value & ~decoded_wr_biten[0:0]) | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end + field_combo.StickyDataVaultCtrl[i0].lock_entry.next = next_c; + field_combo.StickyDataVaultCtrl[i0].lock_entry.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.hard_reset_b) begin + if(~hwif_in.hard_reset_b) begin + field_storage.StickyDataVaultCtrl[i0].lock_entry.value <= 1'h0; + end else if(field_combo.StickyDataVaultCtrl[i0].lock_entry.load_next) begin + field_storage.StickyDataVaultCtrl[i0].lock_entry.value <= field_combo.StickyDataVaultCtrl[i0].lock_entry.next; + end + end + assign hwif_out.StickyDataVaultCtrl[i0].lock_entry.value = field_storage.StickyDataVaultCtrl[i0].lock_entry.value; + end + for(genvar i0=0; i0<10; i0++) begin + for(genvar i1=0; i1<12; i1++) begin + // Field: dv_reg.STICKY_DATA_VAULT_ENTRY[][].data + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.STICKY_DATA_VAULT_ENTRY[i0][i1].data.value; + load_next_c = '0; + if(decoded_reg_strb.STICKY_DATA_VAULT_ENTRY[i0][i1] && decoded_req_is_wr && !(hwif_in.STICKY_DATA_VAULT_ENTRY[i0][i1].data.swwel)) begin // SW write + next_c = (field_storage.STICKY_DATA_VAULT_ENTRY[i0][i1].data.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + field_combo.STICKY_DATA_VAULT_ENTRY[i0][i1].data.next = next_c; + field_combo.STICKY_DATA_VAULT_ENTRY[i0][i1].data.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.hard_reset_b) begin + if(~hwif_in.hard_reset_b) begin + field_storage.STICKY_DATA_VAULT_ENTRY[i0][i1].data.value <= 32'h0; + end else if(field_combo.STICKY_DATA_VAULT_ENTRY[i0][i1].data.load_next) begin + field_storage.STICKY_DATA_VAULT_ENTRY[i0][i1].data.value <= field_combo.STICKY_DATA_VAULT_ENTRY[i0][i1].data.next; + end + end + end + end + for(genvar i0=0; i0<10; i0++) begin + // Field: dv_reg.DataVaultCtrl[].lock_entry + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.DataVaultCtrl[i0].lock_entry.value; + load_next_c = '0; + if(decoded_reg_strb.DataVaultCtrl[i0] && decoded_req_is_wr && !(hwif_in.DataVaultCtrl[i0].lock_entry.swwel)) begin // SW write + next_c = (field_storage.DataVaultCtrl[i0].lock_entry.value & ~decoded_wr_biten[0:0]) | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end + field_combo.DataVaultCtrl[i0].lock_entry.next = next_c; + field_combo.DataVaultCtrl[i0].lock_entry.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.core_only_rst_b) begin + if(~hwif_in.core_only_rst_b) begin + field_storage.DataVaultCtrl[i0].lock_entry.value <= 1'h0; + end else if(field_combo.DataVaultCtrl[i0].lock_entry.load_next) begin + field_storage.DataVaultCtrl[i0].lock_entry.value <= field_combo.DataVaultCtrl[i0].lock_entry.next; + end + end + assign hwif_out.DataVaultCtrl[i0].lock_entry.value = field_storage.DataVaultCtrl[i0].lock_entry.value; + end + for(genvar i0=0; i0<10; i0++) begin + for(genvar i1=0; i1<12; i1++) begin + // Field: dv_reg.DATA_VAULT_ENTRY[][].data + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.DATA_VAULT_ENTRY[i0][i1].data.value; + load_next_c = '0; + if(decoded_reg_strb.DATA_VAULT_ENTRY[i0][i1] && decoded_req_is_wr && !(hwif_in.DATA_VAULT_ENTRY[i0][i1].data.swwel)) begin // SW write + next_c = (field_storage.DATA_VAULT_ENTRY[i0][i1].data.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + field_combo.DATA_VAULT_ENTRY[i0][i1].data.next = next_c; + field_combo.DATA_VAULT_ENTRY[i0][i1].data.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.hard_reset_b) begin + if(~hwif_in.hard_reset_b) begin + field_storage.DATA_VAULT_ENTRY[i0][i1].data.value <= 32'h0; + end else if(field_combo.DATA_VAULT_ENTRY[i0][i1].data.load_next) begin + field_storage.DATA_VAULT_ENTRY[i0][i1].data.value <= field_combo.DATA_VAULT_ENTRY[i0][i1].data.next; + end + end + end + end + for(genvar i0=0; i0<10; i0++) begin + // Field: dv_reg.LockableScratchRegCtrl[].lock_entry + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.LockableScratchRegCtrl[i0].lock_entry.value; + load_next_c = '0; + if(decoded_reg_strb.LockableScratchRegCtrl[i0] && decoded_req_is_wr && !(hwif_in.LockableScratchRegCtrl[i0].lock_entry.swwel)) begin // SW write + next_c = (field_storage.LockableScratchRegCtrl[i0].lock_entry.value & ~decoded_wr_biten[0:0]) | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end + field_combo.LockableScratchRegCtrl[i0].lock_entry.next = next_c; + field_combo.LockableScratchRegCtrl[i0].lock_entry.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.core_only_rst_b) begin + if(~hwif_in.core_only_rst_b) begin + field_storage.LockableScratchRegCtrl[i0].lock_entry.value <= 1'h0; + end else if(field_combo.LockableScratchRegCtrl[i0].lock_entry.load_next) begin + field_storage.LockableScratchRegCtrl[i0].lock_entry.value <= field_combo.LockableScratchRegCtrl[i0].lock_entry.next; + end + end + assign hwif_out.LockableScratchRegCtrl[i0].lock_entry.value = field_storage.LockableScratchRegCtrl[i0].lock_entry.value; + end + for(genvar i0=0; i0<10; i0++) begin + // Field: dv_reg.LockableScratchReg[].data + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.LockableScratchReg[i0].data.value; + load_next_c = '0; + if(decoded_reg_strb.LockableScratchReg[i0] && decoded_req_is_wr && !(hwif_in.LockableScratchReg[i0].data.swwel)) begin // SW write + next_c = (field_storage.LockableScratchReg[i0].data.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + field_combo.LockableScratchReg[i0].data.next = next_c; + field_combo.LockableScratchReg[i0].data.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.hard_reset_b) begin + if(~hwif_in.hard_reset_b) begin + field_storage.LockableScratchReg[i0].data.value <= 32'h0; + end else if(field_combo.LockableScratchReg[i0].data.load_next) begin + field_storage.LockableScratchReg[i0].data.value <= field_combo.LockableScratchReg[i0].data.next; + end + end + end + for(genvar i0=0; i0<8; i0++) begin + // Field: dv_reg.NonStickyGenericScratchReg[].data + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.NonStickyGenericScratchReg[i0].data.value; + load_next_c = '0; + if(decoded_reg_strb.NonStickyGenericScratchReg[i0] && decoded_req_is_wr) begin // SW write + next_c = (field_storage.NonStickyGenericScratchReg[i0].data.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + field_combo.NonStickyGenericScratchReg[i0].data.next = next_c; + field_combo.NonStickyGenericScratchReg[i0].data.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.NonStickyGenericScratchReg[i0].data.value <= 32'h0; + end else if(field_combo.NonStickyGenericScratchReg[i0].data.load_next) begin + field_storage.NonStickyGenericScratchReg[i0].data.value <= field_combo.NonStickyGenericScratchReg[i0].data.next; + end + end + end + for(genvar i0=0; i0<8; i0++) begin + // Field: dv_reg.StickyLockableScratchRegCtrl[].lock_entry + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.StickyLockableScratchRegCtrl[i0].lock_entry.value; + load_next_c = '0; + if(decoded_reg_strb.StickyLockableScratchRegCtrl[i0] && decoded_req_is_wr && !(hwif_in.StickyLockableScratchRegCtrl[i0].lock_entry.swwel)) begin // SW write + next_c = (field_storage.StickyLockableScratchRegCtrl[i0].lock_entry.value & ~decoded_wr_biten[0:0]) | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end + field_combo.StickyLockableScratchRegCtrl[i0].lock_entry.next = next_c; + field_combo.StickyLockableScratchRegCtrl[i0].lock_entry.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.hard_reset_b) begin + if(~hwif_in.hard_reset_b) begin + field_storage.StickyLockableScratchRegCtrl[i0].lock_entry.value <= 1'h0; + end else if(field_combo.StickyLockableScratchRegCtrl[i0].lock_entry.load_next) begin + field_storage.StickyLockableScratchRegCtrl[i0].lock_entry.value <= field_combo.StickyLockableScratchRegCtrl[i0].lock_entry.next; + end + end + assign hwif_out.StickyLockableScratchRegCtrl[i0].lock_entry.value = field_storage.StickyLockableScratchRegCtrl[i0].lock_entry.value; + end + for(genvar i0=0; i0<8; i0++) begin + // Field: dv_reg.StickyLockableScratchReg[].data + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.StickyLockableScratchReg[i0].data.value; + load_next_c = '0; + if(decoded_reg_strb.StickyLockableScratchReg[i0] && decoded_req_is_wr && !(hwif_in.StickyLockableScratchReg[i0].data.swwel)) begin // SW write + next_c = (field_storage.StickyLockableScratchReg[i0].data.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + field_combo.StickyLockableScratchReg[i0].data.next = next_c; + field_combo.StickyLockableScratchReg[i0].data.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.hard_reset_b) begin + if(~hwif_in.hard_reset_b) begin + field_storage.StickyLockableScratchReg[i0].data.value <= 32'h0; + end else if(field_combo.StickyLockableScratchReg[i0].data.load_next) begin + field_storage.StickyLockableScratchReg[i0].data.value <= field_combo.StickyLockableScratchReg[i0].data.next; + end + end + end + + //-------------------------------------------------------------------------- + // Write response + //-------------------------------------------------------------------------- + assign cpuif_wr_ack = decoded_req & decoded_req_is_wr; + // Writes are always granted with no error response + assign cpuif_wr_err = '0; + + //-------------------------------------------------------------------------- + // Readback + //-------------------------------------------------------------------------- + + logic readback_err; + logic readback_done; + logic [31:0] readback_data; + + // Assign readback values to a flattened array + logic [304-1:0][31:0] readback_array; + for(genvar i0=0; i0<10; i0++) begin + assign readback_array[i0*1 + 0][0:0] = (decoded_reg_strb.StickyDataVaultCtrl[i0] && !decoded_req_is_wr) ? field_storage.StickyDataVaultCtrl[i0].lock_entry.value : '0; + assign readback_array[i0*1 + 0][31:1] = '0; + end + for(genvar i0=0; i0<10; i0++) begin + for(genvar i1=0; i1<12; i1++) begin + assign readback_array[i0*12 + i1*1 + 10][31:0] = (decoded_reg_strb.STICKY_DATA_VAULT_ENTRY[i0][i1] && !decoded_req_is_wr) ? field_storage.STICKY_DATA_VAULT_ENTRY[i0][i1].data.value : '0; + end + end + for(genvar i0=0; i0<10; i0++) begin + assign readback_array[i0*1 + 130][0:0] = (decoded_reg_strb.DataVaultCtrl[i0] && !decoded_req_is_wr) ? field_storage.DataVaultCtrl[i0].lock_entry.value : '0; + assign readback_array[i0*1 + 130][31:1] = '0; + end + for(genvar i0=0; i0<10; i0++) begin + for(genvar i1=0; i1<12; i1++) begin + assign readback_array[i0*12 + i1*1 + 140][31:0] = (decoded_reg_strb.DATA_VAULT_ENTRY[i0][i1] && !decoded_req_is_wr) ? field_storage.DATA_VAULT_ENTRY[i0][i1].data.value : '0; + end + end + for(genvar i0=0; i0<10; i0++) begin + assign readback_array[i0*1 + 260][0:0] = (decoded_reg_strb.LockableScratchRegCtrl[i0] && !decoded_req_is_wr) ? field_storage.LockableScratchRegCtrl[i0].lock_entry.value : '0; + assign readback_array[i0*1 + 260][31:1] = '0; + end + for(genvar i0=0; i0<10; i0++) begin + assign readback_array[i0*1 + 270][31:0] = (decoded_reg_strb.LockableScratchReg[i0] && !decoded_req_is_wr) ? field_storage.LockableScratchReg[i0].data.value : '0; + end + for(genvar i0=0; i0<8; i0++) begin + assign readback_array[i0*1 + 280][31:0] = (decoded_reg_strb.NonStickyGenericScratchReg[i0] && !decoded_req_is_wr) ? field_storage.NonStickyGenericScratchReg[i0].data.value : '0; + end + for(genvar i0=0; i0<8; i0++) begin + assign readback_array[i0*1 + 288][0:0] = (decoded_reg_strb.StickyLockableScratchRegCtrl[i0] && !decoded_req_is_wr) ? field_storage.StickyLockableScratchRegCtrl[i0].lock_entry.value : '0; + assign readback_array[i0*1 + 288][31:1] = '0; + end + for(genvar i0=0; i0<8; i0++) begin + assign readback_array[i0*1 + 296][31:0] = (decoded_reg_strb.StickyLockableScratchReg[i0] && !decoded_req_is_wr) ? field_storage.StickyLockableScratchReg[i0].data.value : '0; + end + + // Reduce the array + always_comb begin + automatic logic [31:0] readback_data_var; + readback_done = decoded_req & ~decoded_req_is_wr; + readback_err = '0; + readback_data_var = '0; + for(int i=0; i<304; i++) readback_data_var |= readback_array[i]; + readback_data = readback_data_var; + end + + assign cpuif_rd_ack = readback_done; + assign cpuif_rd_data = readback_data; + assign cpuif_rd_err = readback_err; + +`CALIPTRA_ASSERT_KNOWN(ERR_HWIF_IN, hwif_in, clk, !hwif_in.hard_reset_b) + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/dv_reg_pkg.sv b/designs/Caliptra/src/caliptra-rtl/dv_reg_pkg.sv new file mode 100644 index 0000000..10a491e --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/dv_reg_pkg.sv @@ -0,0 +1,128 @@ +// Generated by PeakRDL-regblock - A free and open-source SystemVerilog generator +// https://github.com/SystemRDL/PeakRDL-regblock + +package dv_reg_pkg; + + localparam DV_REG_DATA_WIDTH = 32; + localparam DV_REG_MIN_ADDR_WIDTH = 11; + + typedef struct packed{ + logic swwel; + } dv_reg__StickyDataVaultCtrl__lock_entry__in_t; + + typedef struct packed{ + dv_reg__StickyDataVaultCtrl__lock_entry__in_t lock_entry; + } dv_reg__StickyDataVaultCtrl__in_t; + + typedef struct packed{ + logic swwel; + } dv_reg__StickyDataVaultEntry_w32__in_t; + + typedef struct packed{ + dv_reg__StickyDataVaultEntry_w32__in_t data; + } dv_reg__StickyDataVaultReg__in_t; + + typedef struct packed{ + logic swwel; + } dv_reg__DataVaultCtrl__lock_entry__in_t; + + typedef struct packed{ + dv_reg__DataVaultCtrl__lock_entry__in_t lock_entry; + } dv_reg__DataVaultCtrl__in_t; + + typedef struct packed{ + logic swwel; + } dv_reg__DataVaultEntry_w32__in_t; + + typedef struct packed{ + dv_reg__DataVaultEntry_w32__in_t data; + } dv_reg__DataVaultReg__in_t; + + typedef struct packed{ + logic swwel; + } dv_reg__LockableScratchRegCtrl__lock_entry__in_t; + + typedef struct packed{ + dv_reg__LockableScratchRegCtrl__lock_entry__in_t lock_entry; + } dv_reg__LockableScratchRegCtrl__in_t; + + typedef struct packed{ + logic swwel; + } dv_reg__LockableScratchReg__data__in_t; + + typedef struct packed{ + dv_reg__LockableScratchReg__data__in_t data; + } dv_reg__LockableScratchReg__in_t; + + typedef struct packed{ + logic swwel; + } dv_reg__StickyLockableScratchRegCtrl__lock_entry__in_t; + + typedef struct packed{ + dv_reg__StickyLockableScratchRegCtrl__lock_entry__in_t lock_entry; + } dv_reg__StickyLockableScratchRegCtrl__in_t; + + typedef struct packed{ + logic swwel; + } dv_reg__StickyLockableScratchReg__data__in_t; + + typedef struct packed{ + dv_reg__StickyLockableScratchReg__data__in_t data; + } dv_reg__StickyLockableScratchReg__in_t; + + typedef struct packed{ + logic reset_b; + logic core_only_rst_b; + logic hard_reset_b; + dv_reg__StickyDataVaultCtrl__in_t [10-1:0]StickyDataVaultCtrl; + dv_reg__StickyDataVaultReg__in_t [10-1:0][12-1:0]STICKY_DATA_VAULT_ENTRY; + dv_reg__DataVaultCtrl__in_t [10-1:0]DataVaultCtrl; + dv_reg__DataVaultReg__in_t [10-1:0][12-1:0]DATA_VAULT_ENTRY; + dv_reg__LockableScratchRegCtrl__in_t [10-1:0]LockableScratchRegCtrl; + dv_reg__LockableScratchReg__in_t [10-1:0]LockableScratchReg; + dv_reg__StickyLockableScratchRegCtrl__in_t [8-1:0]StickyLockableScratchRegCtrl; + dv_reg__StickyLockableScratchReg__in_t [8-1:0]StickyLockableScratchReg; + } dv_reg__in_t; + + typedef struct packed{ + logic value; + } dv_reg__StickyDataVaultCtrl__lock_entry__out_t; + + typedef struct packed{ + dv_reg__StickyDataVaultCtrl__lock_entry__out_t lock_entry; + } dv_reg__StickyDataVaultCtrl__out_t; + + typedef struct packed{ + logic value; + } dv_reg__DataVaultCtrl__lock_entry__out_t; + + typedef struct packed{ + dv_reg__DataVaultCtrl__lock_entry__out_t lock_entry; + } dv_reg__DataVaultCtrl__out_t; + + typedef struct packed{ + logic value; + } dv_reg__LockableScratchRegCtrl__lock_entry__out_t; + + typedef struct packed{ + dv_reg__LockableScratchRegCtrl__lock_entry__out_t lock_entry; + } dv_reg__LockableScratchRegCtrl__out_t; + + typedef struct packed{ + logic value; + } dv_reg__StickyLockableScratchRegCtrl__lock_entry__out_t; + + typedef struct packed{ + dv_reg__StickyLockableScratchRegCtrl__lock_entry__out_t lock_entry; + } dv_reg__StickyLockableScratchRegCtrl__out_t; + + typedef struct packed{ + dv_reg__StickyDataVaultCtrl__out_t [10-1:0]StickyDataVaultCtrl; + dv_reg__DataVaultCtrl__out_t [10-1:0]DataVaultCtrl; + dv_reg__LockableScratchRegCtrl__out_t [10-1:0]LockableScratchRegCtrl; + dv_reg__StickyLockableScratchRegCtrl__out_t [8-1:0]StickyLockableScratchRegCtrl; + } dv_reg__out_t; + + localparam DV_REG_ADDR_WIDTH = 32'd11; + +endpackage \ No newline at end of file diff --git a/designs/Caliptra/src/caliptra-rtl/ecc_add_sub_mod_alter.sv b/designs/Caliptra/src/caliptra-rtl/ecc_add_sub_mod_alter.sv new file mode 100644 index 0000000..4118caa --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/ecc_add_sub_mod_alter.sv @@ -0,0 +1,122 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +// +//====================================================================== +// +// ecc_add_sub_mod_alter.sv +// -------- +// modular addtion/subtraction module to compute opa+-opb % prime +// +// +//====================================================================== + +module ecc_add_sub_mod_alter #( + parameter REG_SIZE = 384 + ) + ( + // Clock and reset. + input wire clk, + input wire reset_n, + input wire zeroize, + + // DATA PORT + input wire add_en_i, + input wire sub_i, + input wire [REG_SIZE-1:0] opa_i, + input wire [REG_SIZE-1:0] opb_i, + input wire [REG_SIZE-1:0] prime_i, + output logic [REG_SIZE-1:0] res_o, + output logic ready_o +); + + logic [REG_SIZE-1 : 0] opb0; + logic [REG_SIZE-1 : 0] opb1; + logic [REG_SIZE-1 : 0] r0; + logic [REG_SIZE-1 : 0] r1; + logic carry0; + + logic sub_n; + logic [REG_SIZE-1 : 0] r0_reg; + logic carry0_reg; + + logic carry1; + logic [1 : 0] push_result_reg; + + ecc_adder #( + .RADIX(REG_SIZE) + ) + adder_inst_0( + .a_i(opa_i), + .b_i(opb0), + .cin_i(sub_i), + .s_o(r0), + .cout_o(carry0) + ); + + ecc_adder #( + .RADIX(REG_SIZE) + ) + adder_inst_1( + .a_i(r0_reg), + .b_i(opb1), + .cin_i(sub_n), + .s_o(r1), + .cout_o(carry1) + ); + + + assign opb0 = sub_i ? ~opb_i : opb_i; + + always_ff @(posedge clk or negedge reset_n) + begin + if(!reset_n) begin + r0_reg <= '0; + carry0_reg <= '0; + sub_n <= '0; + opb1 <= '0; + end + else if (zeroize) begin + r0_reg <= '0; + carry0_reg <= '0; + sub_n <= '0; + opb1 <= '0; + end + else if (add_en_i) begin + r0_reg <= r0; + carry0_reg <= carry0; + sub_n <= !sub_i; + if (sub_i) + opb1 <= prime_i; + else + opb1 <= ~prime_i; + end + end + + // Determines when results are ready + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) + push_result_reg <= 2'b0; + else if (zeroize) + push_result_reg <= 2'b0; + else if (add_en_i) + push_result_reg <= 2'b10; + else // one shift to right + push_result_reg <= 2'(push_result_reg >> 1); + end + + assign ready_o = push_result_reg[0]; + + assign res_o = sub_n ? (carry0_reg ^ carry1)? r1 : r0_reg : (carry0_reg) ? r0_reg : r1; + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/ecc_adder.sv b/designs/Caliptra/src/caliptra-rtl/ecc_adder.sv new file mode 100644 index 0000000..13facfa --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/ecc_adder.sv @@ -0,0 +1,46 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +// +//====================================================================== +// +// ecc_adder.sv +// -------- +// Full adder module to compute a + b in RADIX bits and output add result +// with carry +// +// +//====================================================================== + +module ecc_adder #( + parameter RADIX = 8 +) +( + // DATA PORT + input wire [RADIX-1:0] a_i, + input wire [RADIX-1:0] b_i, + input wire cin_i, + output wire [RADIX-1:0] s_o, + output wire cout_o +); + + logic [RADIX : 0] s_full; + + always_comb begin + s_full = a_i + b_i + cin_i; + end + + assign s_o = s_full[RADIX-1 : 0]; + assign cout_o = s_full[RADIX]; + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/ecc_arith_unit.sv b/designs/Caliptra/src/caliptra-rtl/ecc_arith_unit.sv new file mode 100644 index 0000000..9357aa4 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/ecc_arith_unit.sv @@ -0,0 +1,224 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +// +//====================================================================== +// +// ecc_arith_unit.sv +// -------- +// ECC arithmetic unit to perform point multiplication including +// data memory, point mult (pm) controller, and field arithmeric +// - The module controlol memory acces from outside and pm controller +// - Secret key is stored in this madule's register instead of data memory, +// and this module shifts and feeds one bit of secret key to pm controller +// in each iteration corresponding with pm controller request (req_digit) +// +// +//====================================================================== + +module ecc_arith_unit + import ecc_pm_uop_pkg::*; + #( + parameter REG_SIZE = 384, + parameter RND_SIZE = 192, + parameter RADIX = 32, + parameter ADDR_WIDTH = 6, + parameter [REG_SIZE-1 : 0] p_prime = 384'hfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000ffffffff, + parameter [RADIX-1 : 0] p_mu = 32'h00000001, + parameter [REG_SIZE-1 : 0] q_grouporder = 384'hffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52973, + parameter [RADIX-1 : 0] q_mu = 32'he88fdc45 + ) + ( + // Clock and reset. + input wire clk, + input wire reset_n, + input wire zeroize, + + // DATA PORT + input wire [3 : 0] ecc_cmd_i, + input wire [ADDR_WIDTH-1 : 0] addr_i, + input wire wr_op_sel_i, + input wire wr_en_i, + input wire rd_reg_i, + input wire [(REG_SIZE+RND_SIZE)-1 : 0] data_i, + output wire [REG_SIZE-1: 0] data_o, + output wire busy_o + ); + + //---------------------------------------------------------------- + // Registers including update variables and write enable. + //---------------------------------------------------------------- + + logic [REG_SIZE-1 : 0] opa_s; + logic [REG_SIZE-1 : 0] opb_s; + logic [REG_SIZE-1 : 0] add_res_s; + logic [REG_SIZE-1 : 0] mult_res_s; + + reg digit_in; + logic req_digit; + logic ecc_busy_s; + + pm_instr_struct_t ecc_instr_s; + logic [REG_SIZE-1 : 0] reg_dinb_r; + logic [REG_SIZE-1 : 0] dinb_mux_s; + logic [OPR_ADDR_WIDTH-1 : 0] reg_addr_r; + logic [OPR_ADDR_WIDTH-1 : 0] addrb_mux_s; + logic reg_web_r; + logic web_mux_s; + + logic [REG_SIZE-1 : 0] d_o; + + logic mod_p_q; + logic [REG_SIZE-1 : 0] adder_prime; + logic [RADIX-1 : 0] mult_mu; + + reg [(REG_SIZE+RND_SIZE)-1 : 0] secret_key; + + //---------------------------------------------------------------- + // + // ECC Control Logic + // + //---------------------------------------------------------------- + + ecc_pm_ctrl #( + .REG_SIZE(REG_SIZE), + .RND_SIZE(RND_SIZE), + .INSTR_SIZE(INSTRUCTION_LENGTH) + ) + ecc_pm_ctrl_i( + .clk(clk), + .reset_n(reset_n), + .zeroize(zeroize), + .ecc_cmd_i(ecc_cmd_i), + .digit_i(digit_in), + .instr_o(ecc_instr_s), + .req_digit_o(req_digit), + .busy_o(ecc_busy_s) + ); + + //---------------------------------------------------------------- + // + // Memory interface + // + //---------------------------------------------------------------- + ecc_ram_tdp_file #( + .ADDR_WIDTH(OPR_ADDR_WIDTH), + .DATA_WIDTH(REG_SIZE) + ) + ram_tdp_file_i( + .clk(clk), + .reset_n(reset_n), + .zeroize(zeroize), + .ena(1'b1), + .wea(ecc_instr_s.opcode.add_we), + .addra(ecc_instr_s.opa_addr), + .dina(add_res_s), + .douta(opa_s), + .enb(1'b1), + .web(web_mux_s), + .addrb(addrb_mux_s), + .dinb(dinb_mux_s), + .doutb(opb_s) + ); + + //---------------------------------------------------------------- + // + // fau interface + // + //---------------------------------------------------------------- + + assign mod_p_q = ecc_instr_s.opcode.mod_q_sel; //performing mod_p if (mod_p_q = 0), else mod_q + assign adder_prime = (mod_p_q)? q_grouporder : p_prime; + assign mult_mu = (mod_p_q)? q_mu : p_mu; + + ecc_fau #( + .REG_SIZE(REG_SIZE), + .RADIX(RADIX) + ) + ecc_fau_i + ( + // Clock and reset. + .clk(clk), + .reset_n(reset_n), + .zeroize(zeroize), + + // DATA PORT + .add_en_i(ecc_instr_s.opcode.add_en), + .sub_i(ecc_instr_s.opcode.sub_sel), + .mult_en_i(ecc_instr_s.opcode.mult_en), + .prime_i(adder_prime), + .mult_mu_i(mult_mu), + .opa_i(opa_s), + .opb_i(opb_s), + .add_res_o(add_res_s), + .mult_res_o(mult_res_s) + ); + + + //---------------------------------------------------------------- + // + // Register updates + // + //---------------------------------------------------------------- + always_ff @(posedge clk or negedge reset_n) + begin :reg_update + if (!reset_n) begin + reg_dinb_r <= '0; + reg_addr_r <= '0; + reg_web_r <= 0; + secret_key <= '0; + d_o <= '0; + end + else if (zeroize) begin + reg_dinb_r <= '0; + reg_addr_r <= '0; + reg_web_r <= 0; + secret_key <= '0; + d_o <= '0; + end + else begin + if (wr_en_i) begin + if (wr_op_sel_i == 1'b0) // Write new register + reg_dinb_r <= data_i[REG_SIZE-1 : 0]; + else // Write new key + secret_key <= data_i; + end + else if (req_digit) begin + //Shift secret_key to the left + secret_key <= {secret_key[(REG_SIZE+RND_SIZE)-2 : 0], secret_key[(REG_SIZE+RND_SIZE)-1]}; + end + + reg_addr_r <= addr_i; + if (wr_op_sel_i == 1'b0) + reg_web_r <= wr_en_i; + else + reg_web_r <= '0; + + // Read multiplexer + if (rd_reg_i) + d_o <= opb_s; + else + d_o <= '0; + end + end // reg_update + + //Push key bit to ecc pm control + assign digit_in = secret_key[0]; + + assign addrb_mux_s = ecc_busy_s ? ecc_instr_s.opb_addr : reg_addr_r; + assign web_mux_s = ecc_busy_s ? ecc_instr_s.opcode.mult_we : reg_web_r; + assign dinb_mux_s = ecc_busy_s ? mult_res_s : reg_dinb_r; + assign busy_o = ecc_busy_s; + assign data_o = d_o; + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/ecc_defines_pkg.sv b/designs/Caliptra/src/caliptra-rtl/ecc_defines_pkg.sv new file mode 100644 index 0000000..be799e5 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/ecc_defines_pkg.sv @@ -0,0 +1,40 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +//====================================================================== +// +// ecc_defines_pkg.sv +// -------- +// ECC interface parameters for the digital signature algorithm (DSA). +// +// +//====================================================================== + +`ifndef CALIPTRA_ECC_DEFINES +`define CALIPTRA_ECC_DEFINES + +package ecc_defines_pkg; + +localparam ECC_ADDR_W = 32; +localparam ECC_DATA_W = 32; + +//ECC REQ +typedef struct packed { + logic [ECC_ADDR_W-1:0] addr; + logic [ECC_DATA_W-1:0] wdata; + logic write; +} ecc_req_t; + +endpackage + +`endif diff --git a/designs/Caliptra/src/caliptra-rtl/ecc_dsa_ctrl.sv b/designs/Caliptra/src/caliptra-rtl/ecc_dsa_ctrl.sv new file mode 100644 index 0000000..7528301 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/ecc_dsa_ctrl.sv @@ -0,0 +1,1017 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +// +//====================================================================== +// +// ecc_dsa_ctrl.sv +// -------- +// Elliptic Curve Cryptography (ECC) digital signature algorithm (DSA) +// controller to support deterministic ECDSA based on RFC 6979. +// The dsa architecture includes several countermeasuress to be protected +// against a subset of side-channel analysis (SCA) attacks. +// +// The architecture includes: +// 1) ecc_dsa_sequencer: including the required sequence to perform +// keygen, signing, and verifying. +// 2) ecc_arith_unit: the arithmetic unit to perform point multiplication +// and other required operations +// 3) hmac_drbg: the hmac384 drbg component to support RFC 6979 +// 4) ecc_scalar_blinding: the SCA countermeasure to randomized scalar +// to avoid information leakage. +// +// The embedded countermeasures are: +// - point randomization: +// Randomized Projective Coordinates countermeasure based on section 5.3 +// "Resistance against Differential Power Analysis for Elliptic Curve +// Cryptosystems" in CHES 1999 by Coron, J. +// This countermesure uses a random value "lambda" in point multiplication +// (Q = k * P) in keygen/signing to randomiza base point P = (X, Y, 1) +// as follows: +// P = (X * Lambda, Y * lambda, Lambda) +// - scalar blinding: +// Scalar blinding countermeasure based on section 5.1 +// "Resistance against Differential Power Analysis for Elliptic Curve +// Cryptosystems" in CHES 1999 by Coron, J. +// This countermeasure uses a random value "r" in the point multiplication +// (Q = k * P) in keygen/signing to randomiza scalar k as follows: +// k = k + r*group_order +// - masking signature: +// Masking sign countermeasure uses a random value "d" in the signing +// operation to generate signature proof s = (privkey * r + h)*k_inv +// as follows: +// s = [((privkey - d) * r + (h - d)) * k_inv] + [(d * r + d) * k_inv +//====================================================================== + +`include "kv_macros.svh" + +module ecc_dsa_ctrl + import ecc_params_pkg::*; + import ecc_dsa_uop_pkg::*; + import ecc_reg_pkg::*; + import kv_defines_pkg::*; + ( + // Clock and reset. + input wire clk, + input wire reset_n, + input wire cptra_pwrgood, + + // Reg ports. + input ecc_reg__out_t hwif_out, + output ecc_reg__in_t hwif_in, + + // KV interface + output kv_read_t [1:0] kv_read, + output kv_write_t kv_write, + input kv_rd_resp_t [1:0] kv_rd_resp, + input kv_wr_resp_t kv_wr_resp, + + //PCR Signing + input pcr_signing_t pcr_signing_data, + + input logic ocp_lock_in_progress, + output logic busy_o, + + // Interrupts (from ecc_reg) + output logic error_intr, + output logic notif_intr, + input logic debugUnlock_or_scan_mode_switch + ); + + //---------------------------------------------------------------- + // Internal constant and parameter definitions. + //---------------------------------------------------------------- + + localparam [RND_SIZE-1 : 0] zero_pad = '0; + localparam REG_NUM_DWORDS = REG_SIZE / DATA_WIDTH; + //---------------------------------------------------------------- + // Registers including update variables and write enable. + //---------------------------------------------------------------- + logic [DSA_PROG_ADDR_W-1 : 0] prog_cntr; + + logic [REG_NUM_DWORDS-1 : 0][DATA_WIDTH-1:0] read_reg; + logic [(REG_SIZE+RND_SIZE)-1 : 0] write_reg; + logic [1 : 0] cycle_cnt; + + logic zeroize_reg; + + logic dsa_busy; + logic subcomponent_busy; + logic pm_busy_o; + + logic hw_privkey_we; + logic privkey_we_reg; + logic sharedkey_we_reg; + logic secretkey_we; + logic hw_pubkeyx_we; + logic hw_pubkeyy_we; + logic hw_r_we; + logic hw_s_we; + logic hw_scalar_G_we; + logic hw_scalar_PK_we; + logic hw_verify_r_we; + logic hw_pk_chk_we; + logic hw_sharedkey_we; + logic scalar_G_sel; + + logic ecc_valid_reg; + logic ecc_ready_reg; + + logic ecc_status_done_d; + logic ecc_status_done_p; + + logic [2 : 0] cmd_reg; + logic [3 : 0] pm_cmd_reg; + logic [REG_NUM_DWORDS-1 : 0][DATA_WIDTH-1:0] msg_reg; + logic [REG_NUM_DWORDS-1 : 0][DATA_WIDTH-1:0] msg_reduced_reg; + logic [REG_NUM_DWORDS-1 : 0][DATA_WIDTH-1:0] privkey_reg; + logic [REG_NUM_DWORDS-1 : 0][DATA_WIDTH-1:0] kv_reg; + logic [REG_NUM_DWORDS-1 : 0][DATA_WIDTH-1:0] pubkeyx_reg; + logic [REG_NUM_DWORDS-1 : 0][DATA_WIDTH-1:0] pubkeyy_reg; + logic [REG_NUM_DWORDS-1 : 0][DATA_WIDTH-1:0] seed_reg; + logic [REG_NUM_DWORDS-1 : 0][DATA_WIDTH-1:0] nonce_reg; + logic [REG_NUM_DWORDS-1 : 0][DATA_WIDTH-1:0] r_reg; + logic [REG_NUM_DWORDS-1 : 0][DATA_WIDTH-1:0] s_reg; + logic [REG_NUM_DWORDS-1 : 0][DATA_WIDTH-1:0] IV_reg; + logic [REG_SIZE-1 : 0] lambda_reg; + logic [REG_SIZE-1 : 0] masking_rnd_reg; + logic [REG_SIZE-1 : 0] pk_chk_reg; + + logic [REG_SIZE-1 : 0] scalar_G_reg; + logic [REG_SIZE-1 : 0] scalar_PK_reg; + + logic [REG_SIZE-1 : 0] scalar_in_reg; + logic [REG_SIZE-1 : 0] scalar_rnd_reg; + logic [(REG_SIZE+RND_SIZE)-1 : 0] scalar_out_reg; + logic scalar_sca_en; + logic scalar_sca_busy_o; + + logic [1 : 0] hmac_mode; + logic hmac_init; + logic hmac_ready; + logic [REG_SIZE-1 : 0] hmac_drbg_result; + logic hmac_busy; + + //interface with kv client + logic kv_privkey_write_en; + logic [REG_OFFSET_W-1:0] kv_privkey_write_offset; + logic [31:0] kv_privkey_write_data; + logic kv_seed_write_en; + logic [REG_OFFSET_W-1:0] kv_seed_write_offset; + logic [31:0] kv_seed_write_data; + + logic dest_keyvault; + kv_error_code_e kv_privkey_error, kv_seed_error, kv_nonce_error, kv_write_error; + logic kv_privkey_ready, kv_privkey_done; + logic kv_seed_ready, kv_seed_done ; + logic kv_write_ready, kv_write_done; + //KV Seed Data Present + logic kv_seed_data_present; + logic kv_seed_data_present_set, kv_seed_data_present_reset; + //KV Key Data Present + logic kv_key_data_present; + logic kv_key_data_present_set, kv_key_data_present_reset; + + kv_read_ctrl_reg_t kv_privkey_read_ctrl_reg; + kv_read_ctrl_reg_t kv_seed_read_ctrl_reg; + kv_write_ctrl_reg_t kv_write_ctrl_reg; + kv_read_filter_metrics_t kv_privkey_read_metrics; + kv_read_filter_metrics_t kv_seed_read_metrics; + kv_write_filter_metrics_t kv_write_metrics; + + logic pcr_sign_mode; + + instr_struct_t prog_instr; + + // ERROR + logic keygen_process; + logic signing_process; + logic verifying_process; + logic sharedkey_process; + + logic privkey_input_outofrange; + logic r_output_outofrange; + logic s_output_outofrange; + logic r_input_outofrange; + logic s_input_outofrange; + logic pubkeyx_input_outofrange; + logic pubkeyy_input_outofrange; + logic pubkey_input_invalid; + logic pcr_sign_input_invalid; + logic privkey_output_outofrange, pubkeyx_output_outofrange, pubkeyy_output_outofrange; + logic sharedkey_outofrange; + + logic error_flag; + logic error_flag_reg; + logic error_flag_edge; + + //---------------------------------------------------------------- + // Module instantiantions. + //---------------------------------------------------------------- + ecc_dsa_sequencer #( + .ADDR_WIDTH(DSA_PROG_ADDR_W), + .DATA_WIDTH(DSA_INSTRUCTION_LENGTH) + ) + ecc_dsa_sequencer_i( + .clka(clk), + .reset_n(reset_n), + .zeroize(zeroize_reg), + .ena(1'b1), + .addra(prog_cntr), + .douta(prog_instr) + ); + + ecc_arith_unit #( + .REG_SIZE(REG_SIZE), + .RND_SIZE(RND_SIZE), + .RADIX(MULT_RADIX), + .ADDR_WIDTH(DSA_OPR_ADDR_WIDTH), + .p_prime(PRIME), + .p_mu(PRIME_mu), + .q_grouporder(GROUP_ORDER), + .q_mu(GROUP_ORDER_mu) + ) + ecc_arith_unit_i ( + .clk(clk), + .reset_n(reset_n), + .zeroize(zeroize_reg), + .ecc_cmd_i(pm_cmd_reg), + .addr_i(prog_instr.mem_addr), + .wr_op_sel_i(prog_instr.opcode.op_sel), + + .wr_en_i(prog_instr.opcode.wr_en), + .rd_reg_i(prog_instr.opcode.rd_en), + .data_i(write_reg), + .data_o(read_reg), + .busy_o(pm_busy_o) + ); + + ecc_hmac_drbg_interface #( + .REG_SIZE(REG_SIZE), + .GROUP_ORDER(GROUP_ORDER) + ) + ecc_hmac_drbg_interface_i ( + .clk(clk), + .reset_n(reset_n), + .zeroize(zeroize_reg), + .hmac_mode(hmac_mode), + .en(hmac_init), + .ready(hmac_ready), + .keygen_seed(seed_reg), + .keygen_nonce(nonce_reg), + .privKey(privkey_reg), + .hashed_msg(msg_reduced_reg), + .IV(IV_reg), + .lambda(lambda_reg), + .scalar_rnd(scalar_rnd_reg), + .masking_rnd(masking_rnd_reg), + .drbg(hmac_drbg_result) + ); + + ecc_scalar_blinding #( + .REG_SIZE(REG_SIZE), + .RND_SIZE(RND_SIZE), + .RADIX(SCALAR_BLIND_RADIX), + .GROUP_ORDER(GROUP_ORDER) + ) + ecc_scalar_blinding_i( + .clk(clk), + .reset_n(reset_n), + .zeroize(zeroize_reg), + .en_i(scalar_sca_en), + .data_i(scalar_in_reg), + .rnd_i(scalar_rnd_reg[RND_SIZE-1 : 0]), + .data_o(scalar_out_reg), + .busy_o(scalar_sca_busy_o) + ); + + + //---------------------------------------------------------------- + // ecc_reg_update + // Update functionality for all interface registers in the core. + //---------------------------------------------------------------- + + // read the registers written by sw + always_comb begin + //Mask the command if KV clients are not idle + cmd_reg = {hwif_out.ECC_CTRL.DH_SHAREDKEY.value, hwif_out.ECC_CTRL.CTRL.value} & {3{kv_seed_ready}} & {3{kv_privkey_ready}}; + zeroize_reg = hwif_out.ECC_CTRL.ZEROIZE.value || debugUnlock_or_scan_mode_switch; + end + + //there is a clk cycle memory read delay between hw_privkey_we and read_reg + always_ff @(posedge clk or negedge reset_n) + begin : ecc_kv_reg + if (!reset_n) begin + privkey_we_reg <= '0; + sharedkey_we_reg <= '0; + kv_reg <= '0; + kv_seed_data_present <= '0; + kv_key_data_present <= '0; + end + else if (zeroize_reg) begin + privkey_we_reg <= '0; + sharedkey_we_reg <= '0; + kv_reg <= '0; + kv_seed_data_present <= '0; + kv_key_data_present <= '0; + end + //Store private key here before pushing to keyvault + else begin + privkey_we_reg <= hw_privkey_we; + sharedkey_we_reg <= hw_sharedkey_we; + if (secretkey_we & (dest_keyvault | kv_seed_data_present)) + kv_reg <= read_reg; + + kv_seed_data_present <= kv_seed_data_present_set ? '1 : + kv_seed_data_present_reset ? '0 : kv_seed_data_present; + kv_key_data_present <= kv_key_data_present_set ? '1 : + kv_key_data_present_reset ? '0 : kv_key_data_present; + end + end + + always_comb secretkey_we = (privkey_we_reg | sharedkey_we_reg); + + assign error_intr = hwif_out.intr_block_rf.error_global_intr_r.intr; + assign notif_intr = hwif_out.intr_block_rf.notif_global_intr_r.intr; + + // write the registers by hw + always_comb hwif_in.reset_b = reset_n; + always_comb hwif_in.hard_reset_b = cptra_pwrgood; + always_comb hwif_in.ecc_ready = ecc_ready_reg; + always_comb hwif_in.ECC_NAME[0].NAME.next = ECC_CORE_NAME[31 : 0]; + always_comb hwif_in.ECC_NAME[1].NAME.next = ECC_CORE_NAME[63 : 32]; + always_comb hwif_in.ECC_VERSION[0].VERSION.next = ECC_CORE_VERSION[31 : 0]; + always_comb hwif_in.ECC_VERSION[1].VERSION.next = ECC_CORE_VERSION[63 : 32]; + + always_comb hwif_in.ECC_STATUS.READY.next = ecc_ready_reg; + always_comb hwif_in.ECC_STATUS.VALID.next = ecc_valid_reg; + + + always_comb begin // ecc_reg_writing + for (int dword=0; dword < 12; dword++)begin + //Key Vault has priority if enabled to drive these registers + //don't store the private key generated in sw accessible register if it's going to keyvault + privkey_reg[dword] = hwif_out.ECC_PRIVKEY_IN[11-dword].PRIVKEY_IN.value; + hwif_in.ECC_PRIVKEY_IN[dword].PRIVKEY_IN.we = (pcr_sign_mode | (kv_privkey_write_en & (kv_privkey_write_offset == dword))) & !zeroize_reg; + hwif_in.ECC_PRIVKEY_IN[dword].PRIVKEY_IN.next = pcr_sign_mode ? pcr_signing_data.pcr_ecc_signing_privkey[dword] : + kv_privkey_write_en ? kv_privkey_write_data : + read_reg[11-dword]; + hwif_in.ECC_PRIVKEY_IN[dword].PRIVKEY_IN.hwclr = zeroize_reg | kv_key_data_present_reset | (kv_privkey_error == KV_READ_FAIL); + hwif_in.ECC_PRIVKEY_IN[dword].PRIVKEY_IN.swwe = ecc_ready_reg & ~kv_key_data_present; + end + + for (int dword=0; dword < 12; dword++)begin + //If keyvault is not enabled, grab the sw value as usual + hwif_in.ECC_PRIVKEY_OUT[dword].PRIVKEY_OUT.we = (privkey_we_reg & ~(dest_keyvault | kv_seed_data_present)) & !zeroize_reg; + hwif_in.ECC_PRIVKEY_OUT[dword].PRIVKEY_OUT.next = read_reg[11-dword]; + hwif_in.ECC_PRIVKEY_OUT[dword].PRIVKEY_OUT.hwclr = zeroize_reg; + end + + for (int dword=0; dword < 12; dword++)begin + seed_reg[dword] = hwif_out.ECC_SEED[11-dword].SEED.value; + hwif_in.ECC_SEED[dword].SEED.we = (kv_seed_write_en & (kv_seed_write_offset == dword)) & !zeroize_reg; + hwif_in.ECC_SEED[dword].SEED.next = kv_seed_write_data; + hwif_in.ECC_SEED[dword].SEED.hwclr = zeroize_reg | kv_seed_data_present_reset | (kv_seed_error == KV_READ_FAIL); + hwif_in.ECC_SEED[dword].SEED.swwe = ecc_ready_reg & ~kv_seed_data_present; + end + + for (int dword=0; dword < 12; dword++)begin + nonce_reg[dword] = hwif_out.ECC_NONCE[11-dword].NONCE.value; + hwif_in.ECC_NONCE[dword].NONCE.hwclr = zeroize_reg; + end + + for (int dword=0; dword < 12; dword++)begin + msg_reg[dword] = hwif_out.ECC_MSG[11-dword].MSG.value; + hwif_in.ECC_MSG[dword].MSG.we = pcr_sign_mode & !zeroize_reg; + hwif_in.ECC_MSG[dword].MSG.next = pcr_signing_data.pcr_hash[dword]; + hwif_in.ECC_MSG[dword].MSG.hwclr = zeroize_reg; + end + + for (int dword=0; dword < 12; dword++)begin + pubkeyx_reg[dword] = hwif_out.ECC_PUBKEY_X[11-dword].PUBKEY_X.value; + hwif_in.ECC_PUBKEY_X[dword].PUBKEY_X.we = hw_pubkeyx_we & !zeroize_reg; + hwif_in.ECC_PUBKEY_X[dword].PUBKEY_X.next = read_reg[11-dword]; + hwif_in.ECC_PUBKEY_X[dword].PUBKEY_X.hwclr = zeroize_reg; + end + + for (int dword=0; dword < 12; dword++)begin + pubkeyy_reg[dword] = hwif_out.ECC_PUBKEY_Y[11-dword].PUBKEY_Y.value; + hwif_in.ECC_PUBKEY_Y[dword].PUBKEY_Y.we = hw_pubkeyy_we & !zeroize_reg; + hwif_in.ECC_PUBKEY_Y[dword].PUBKEY_Y.next = read_reg[11-dword]; + hwif_in.ECC_PUBKEY_Y[dword].PUBKEY_Y.hwclr = zeroize_reg; + end + + for (int dword=0; dword < 12; dword++)begin + r_reg[dword] = hwif_out.ECC_SIGN_R[11-dword].SIGN_R.value; + hwif_in.ECC_SIGN_R[dword].SIGN_R.we = hw_r_we & !zeroize_reg; + hwif_in.ECC_SIGN_R[dword].SIGN_R.next = read_reg[11-dword]; + hwif_in.ECC_SIGN_R[dword].SIGN_R.hwclr = zeroize_reg; + end + + for (int dword=0; dword < 12; dword++)begin + s_reg[dword] = hwif_out.ECC_SIGN_S[11-dword].SIGN_S.value; + hwif_in.ECC_SIGN_S[dword].SIGN_S.we = hw_s_we & !zeroize_reg; + hwif_in.ECC_SIGN_S[dword].SIGN_S.next = read_reg[11-dword]; + hwif_in.ECC_SIGN_S[dword].SIGN_S.hwclr = zeroize_reg; + end + + for (int dword=0; dword < 12; dword++)begin + hwif_in.ECC_VERIFY_R[dword].VERIFY_R.we = hw_verify_r_we & !zeroize_reg; + hwif_in.ECC_VERIFY_R[dword].VERIFY_R.next = read_reg[11-dword]; + hwif_in.ECC_VERIFY_R[dword].VERIFY_R.hwclr = zeroize_reg; + end + + for (int dword=0; dword < 12; dword++)begin + IV_reg[dword] = hwif_out.ECC_IV[11-dword].IV.value; + hwif_in.ECC_IV[dword].IV.hwclr = zeroize_reg; + end + + for (int dword=0; dword < 12; dword++)begin + hwif_in.ECC_DH_SHARED_KEY[dword].DH_SHARED_KEY.we = (sharedkey_we_reg & ~(dest_keyvault | kv_key_data_present)) & !zeroize_reg; + hwif_in.ECC_DH_SHARED_KEY[dword].DH_SHARED_KEY.next = read_reg[11-dword]; + hwif_in.ECC_DH_SHARED_KEY[dword].DH_SHARED_KEY.hwclr = zeroize_reg; + end + end + + //transformed msg into modulo q + always_ff @(posedge clk or negedge reset_n) + begin : reduced_msg + if (!reset_n) + msg_reduced_reg <= '0; + else if (zeroize_reg) + msg_reduced_reg <= '0; + else begin + if (msg_reg >= GROUP_ORDER) + msg_reduced_reg <= msg_reg - GROUP_ORDER; + else + msg_reduced_reg <= msg_reg; + end + end + + + always_comb hwif_in.ECC_CTRL.CTRL.hwclr = |cmd_reg; + always_comb hwif_in.ECC_CTRL.DH_SHAREDKEY.hwclr = |cmd_reg; + always_comb hwif_in.ECC_CTRL.PCR_SIGN.hwclr = hwif_out.ECC_CTRL.PCR_SIGN.value; + + // TODO add other interrupt hwset signals (errors) + always_comb hwif_in.intr_block_rf.error_internal_intr_r.error_internal_sts.hwset = error_flag_edge; + always_comb hwif_in.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.hwset = ecc_status_done_p; + + + always_comb begin: ecc_kv_ctrl_reg + //ready when fsm is not busy + hwif_in.ecc_kv_rd_pkey_status.ERROR.next = kv_privkey_error; + hwif_in.ecc_kv_rd_seed_status.ERROR.next = kv_seed_error; + hwif_in.ecc_kv_wr_pkey_status.ERROR.next = kv_write_error; + //ready when fsm is not busy + hwif_in.ecc_kv_rd_pkey_status.READY.next = kv_privkey_ready; + hwif_in.ecc_kv_rd_seed_status.READY.next = kv_seed_ready; + hwif_in.ecc_kv_wr_pkey_status.READY.next = kv_write_ready; + //set valid when fsm is done + hwif_in.ecc_kv_rd_pkey_status.VALID.hwset = kv_privkey_done; + hwif_in.ecc_kv_rd_seed_status.VALID.hwset = kv_seed_done; + hwif_in.ecc_kv_wr_pkey_status.VALID.hwset = kv_write_done; + //clear valid when new request is made + hwif_in.ecc_kv_rd_pkey_status.VALID.hwclr = kv_privkey_read_ctrl_reg.read_en; + hwif_in.ecc_kv_rd_seed_status.VALID.hwclr = kv_seed_read_ctrl_reg.read_en; + hwif_in.ecc_kv_wr_pkey_status.VALID.hwclr = kv_write_ctrl_reg.write_en; + //clear enable when busy + hwif_in.ecc_kv_rd_pkey_ctrl.read_en.hwclr = ~kv_privkey_ready; + hwif_in.ecc_kv_rd_seed_ctrl.read_en.hwclr = ~kv_seed_ready; + hwif_in.ecc_kv_wr_pkey_ctrl.write_en.hwclr = ~kv_write_ready; + end + + // Software write-enables to prevent KV reg manipulation mid-operation + always_comb hwif_in.ecc_kv_rd_pkey_ctrl.read_en.swwe = !kv_key_data_present && ecc_ready_reg; + always_comb hwif_in.ecc_kv_rd_pkey_ctrl.read_entry.swwe = !kv_key_data_present && ecc_ready_reg; + always_comb hwif_in.ecc_kv_rd_pkey_ctrl.pcr_hash_extend.swwe = !kv_key_data_present && ecc_ready_reg; + always_comb hwif_in.ecc_kv_rd_pkey_ctrl.rsvd.swwe = !kv_key_data_present && ecc_ready_reg; + + always_comb hwif_in.ecc_kv_rd_seed_ctrl.read_en.swwe = !kv_seed_data_present && ecc_ready_reg; + always_comb hwif_in.ecc_kv_rd_seed_ctrl.read_entry.swwe = !kv_seed_data_present && ecc_ready_reg; + always_comb hwif_in.ecc_kv_rd_seed_ctrl.pcr_hash_extend.swwe = !kv_seed_data_present && ecc_ready_reg; + always_comb hwif_in.ecc_kv_rd_seed_ctrl.rsvd.swwe = !kv_seed_data_present && ecc_ready_reg; + + // KV write control must be written before ECC core operation begins, even though + // output isn't written to KV until the end of the operation. + // Prevent partial-key attacks by blocking register modifications during core execution. + always_comb hwif_in.ecc_kv_wr_pkey_ctrl.write_en.swwe = ecc_ready_reg; + always_comb hwif_in.ecc_kv_wr_pkey_ctrl.write_entry.swwe = ecc_ready_reg; + always_comb hwif_in.ecc_kv_wr_pkey_ctrl.hmac_key_dest_valid.swwe = ecc_ready_reg; + always_comb hwif_in.ecc_kv_wr_pkey_ctrl.hmac_block_dest_valid.swwe = ecc_ready_reg; + always_comb hwif_in.ecc_kv_wr_pkey_ctrl.mldsa_seed_dest_valid.swwe = ecc_ready_reg; + always_comb hwif_in.ecc_kv_wr_pkey_ctrl.ecc_pkey_dest_valid.swwe = ecc_ready_reg; + always_comb hwif_in.ecc_kv_wr_pkey_ctrl.ecc_seed_dest_valid.swwe = ecc_ready_reg; + always_comb hwif_in.ecc_kv_wr_pkey_ctrl.aes_key_dest_valid.swwe = ecc_ready_reg; + always_comb hwif_in.ecc_kv_wr_pkey_ctrl.mlkem_seed_dest_valid.swwe = ecc_ready_reg; + always_comb hwif_in.ecc_kv_wr_pkey_ctrl.mlkem_msg_dest_valid.swwe = ecc_ready_reg; + always_comb hwif_in.ecc_kv_wr_pkey_ctrl.dma_data_dest_valid.swwe = ecc_ready_reg; + always_comb hwif_in.ecc_kv_wr_pkey_ctrl.rsvd.swwe = ecc_ready_reg; + + //keyvault control reg macros for assigning to struct + `CALIPTRA_KV_READ_CTRL_REG2STRUCT(kv_privkey_read_ctrl_reg, ecc_kv_rd_pkey_ctrl) + `CALIPTRA_KV_READ_CTRL_REG2STRUCT(kv_seed_read_ctrl_reg, ecc_kv_rd_seed_ctrl) + `CALIPTRA_KV_WRITE_CTRL_REG2STRUCT(kv_write_ctrl_reg, ecc_kv_wr_pkey_ctrl) + + //Detect keyvault data coming in to lock api registers and protect outputs + always_comb kv_seed_data_present_set = kv_seed_read_ctrl_reg.read_en; + always_comb kv_seed_data_present_reset = kv_seed_data_present & ecc_status_done_p; + + always_comb kv_key_data_present_set = kv_privkey_read_ctrl_reg.read_en; + always_comb kv_key_data_present_reset = kv_key_data_present & ecc_status_done_p; + + always_comb pcr_sign_mode = hwif_out.ECC_CTRL.PCR_SIGN.value; + + //---------------------------------------------------------------- + // register updates + // + // update the internal registers and their wr_en + //---------------------------------------------------------------- + always_ff @(posedge clk or negedge reset_n) + begin : SCALAR_REG + if(!reset_n) begin + scalar_G_reg <= '0; + scalar_PK_reg <= '0; + end + else if(zeroize_reg) begin + scalar_G_reg <= '0; + scalar_PK_reg <= '0; + end + else begin + if (!scalar_G_sel) + scalar_G_reg <= hmac_drbg_result; + else if (hw_scalar_G_we) + scalar_G_reg <= read_reg; + + if (hw_scalar_PK_we) + scalar_PK_reg <= read_reg; + end + end + + // Set the write enable flag for different register based on sequencer output of "DSA_UOP_RD_CORE" + // to read them from data memory inside ecc_arith_unit + always_comb + begin : wr_en_signals + hw_privkey_we = 0; + hw_pubkeyx_we = 0; + hw_pubkeyy_we = 0; + hw_r_we = 0; + hw_s_we = 0; + hw_scalar_G_we = 0; + hw_scalar_PK_we = 0; + hw_verify_r_we = 0; + hw_pk_chk_we = 0; + hw_sharedkey_we = 0; + if ((prog_instr.opcode == DSA_UOP_RD_CORE) & (cycle_cnt == 0)) begin + unique case (prog_instr.reg_id) + PRIVKEY_ID : hw_privkey_we = 1; + PUBKEYX_ID : hw_pubkeyx_we = 1; + PUBKEYY_ID : hw_pubkeyy_we = 1; + R_ID : hw_r_we = 1; + S_ID : hw_s_we = 1; + SCALAR_G_ID : hw_scalar_G_we = 1; + SCALAR_PK_ID : hw_scalar_PK_we = 1; + VERIFY_R_ID : hw_verify_r_we = 1; + PK_VALID_ID : hw_pk_chk_we = 1; + DH_SHAREDKEY_ID : hw_sharedkey_we = 1; + default : + begin + hw_privkey_we = 0; + hw_pubkeyx_we = 0; + hw_pubkeyy_we = 0; + hw_r_we = 0; + hw_s_we = 0; + hw_scalar_G_we = 0; + hw_scalar_PK_we = 0; + hw_verify_r_we = 0; + hw_pk_chk_we = 0; + hw_sharedkey_we = 0; + end + endcase + end + end // wr_en_signals + + + // set the write register value based on sequencer output of "DSA_UOP_WR_CORE" + // to write into data memory inside ecc_arith_unit + always_comb + begin : write_to_pm_core + write_reg = '0; + if (prog_instr.opcode == DSA_UOP_WR_CORE) begin + unique case (prog_instr.reg_id) + CONST_ZERO_ID : write_reg = {zero_pad, ZERO_CONST}; + CONST_ONE_ID : write_reg = {zero_pad, ONE_CONST}; + CONST_E_a_MONT_ID : write_reg = {zero_pad, E_a_MONT}; + CONST_E_b_MONT_ID : write_reg = {zero_pad, E_b_MONT}; + CONST_E_3b_MONT_ID : write_reg = {zero_pad, E_3b_MONT}; + CONST_ONE_p_MONT_ID : write_reg = {zero_pad, ONE_p_MONT}; + CONST_R2_p_MONT_ID : write_reg = {zero_pad, R2_p_MONT}; + CONST_G_X_MONT_ID : write_reg = {zero_pad, G_X_MONT}; + CONST_G_Y_MONT_ID : write_reg = {zero_pad, G_Y_MONT}; + CONST_R2_q_MONT_ID : write_reg = {zero_pad, R2_q_MONT}; + CONST_ONE_q_MONT_ID : write_reg = {zero_pad, ONE_q_MONT}; + MSG_ID : write_reg = {zero_pad, msg_reduced_reg}; + PRIVKEY_ID : write_reg = {zero_pad, privkey_reg}; + PUBKEYX_ID : write_reg = {zero_pad, pubkeyx_reg}; + PUBKEYY_ID : write_reg = {zero_pad, pubkeyy_reg}; + R_ID : write_reg = {zero_pad, r_reg}; + S_ID : write_reg = {zero_pad, s_reg}; + SCALAR_G_ID : write_reg = {zero_pad, scalar_G_reg}; + LAMBDA_ID : write_reg = {zero_pad, lambda_reg}; + MASKING_ID : write_reg = {zero_pad, masking_rnd_reg}; + default : write_reg = '0; + endcase + end + else if (prog_instr.opcode == DSA_UOP_WR_SCALAR) begin + unique case (prog_instr.reg_id) + SCALAR_PK_ID : write_reg = (REG_SIZE+RND_SIZE)'(scalar_PK_reg << RND_SIZE); + SCALAR_G_ID : write_reg = (REG_SIZE+RND_SIZE)'(scalar_G_reg << RND_SIZE); + SCALAR_ID : write_reg = scalar_out_reg; // SCA + default : write_reg = '0; + endcase + end + end // write_to_pm_core + + // Set the input scalar for scalar_blinding module + always_ff @(posedge clk or negedge reset_n) + begin : scalar_sca_ctrl + if(!reset_n) begin + scalar_in_reg <= '0; + end + else if(zeroize_reg) begin + scalar_in_reg <= '0; + end + else begin + if (prog_instr.opcode == DSA_UOP_SCALAR_SCA) begin + scalar_in_reg <= scalar_G_reg; + end + end + end // scalar_sca_ctrl + + assign hmac_busy = ~hmac_ready; + assign subcomponent_busy = pm_busy_o | hmac_busy | scalar_sca_busy_o; + + + //---------------------------------------------------------------- + // ERROR detection + // + // bound check for different input/output registers. + //---------------------------------------------------------------- + always_ff @(posedge clk or negedge reset_n) + begin : pk_chk + if(!reset_n) begin + pk_chk_reg <= '0; + end + else if(zeroize_reg) begin + pk_chk_reg <= '0; + end + else begin + if (hw_pk_chk_we) begin + pk_chk_reg <= read_reg; + end + end + end // pk_chk + + always_ff @(posedge clk or negedge reset_n) + begin : error_detection + if(!reset_n) + error_flag_reg <= 1'b0; + else if(zeroize_reg) + error_flag_reg <= 1'b0; + else if (error_flag) + error_flag_reg <= 1'b1; + end // error_detection + + assign error_flag_edge = error_flag & (!error_flag_reg); + + assign privkey_input_outofrange = signing_process & ((privkey_reg == 0) | (privkey_reg >= GROUP_ORDER)); + assign r_output_outofrange = signing_process & (hw_r_we & ((read_reg == 0) | (read_reg >= GROUP_ORDER))); + assign s_output_outofrange = signing_process & (hw_s_we & ((read_reg == 0) | (read_reg >= GROUP_ORDER))); + + assign r_input_outofrange = verifying_process & ((r_reg == 0) | (r_reg >= GROUP_ORDER)); + assign s_input_outofrange = verifying_process & ((s_reg == 0) | (s_reg >= GROUP_ORDER)); + assign pubkeyx_input_outofrange = (verifying_process | sharedkey_process) & (pubkeyx_reg >= PRIME); + assign pubkeyy_input_outofrange = (verifying_process | sharedkey_process) & (pubkeyy_reg >= PRIME); + assign pubkey_input_invalid = (verifying_process | sharedkey_process) & (pk_chk_reg != 0); + + assign pcr_sign_input_invalid = ((cmd_reg == KEYGEN) | (cmd_reg == VERIFY) | (cmd_reg == SHARED_KEY)) & pcr_sign_mode; + + assign privkey_output_outofrange = keygen_process & (hw_privkey_we & ((read_reg == 0) | (read_reg >= GROUP_ORDER))); + assign pubkeyx_output_outofrange = keygen_process & (hw_pubkeyx_we & (read_reg >= PRIME)); + assign pubkeyy_output_outofrange = keygen_process & (hw_pubkeyy_we & (read_reg >= PRIME)); + + assign sharedkey_outofrange = sharedkey_process & (hw_sharedkey_we & (read_reg >= PRIME)); + + assign error_flag = privkey_input_outofrange | r_output_outofrange | s_output_outofrange | + r_input_outofrange | s_input_outofrange | pubkeyx_input_outofrange | pubkeyy_input_outofrange | + pubkey_input_invalid | pcr_sign_input_invalid | + privkey_output_outofrange | pubkeyx_output_outofrange | pubkeyy_output_outofrange | + sharedkey_outofrange; + + //---------------------------------------------------------------- + // ECDSA_FSM_flow + // + // This FSM starts with the keyfen/signing/verifying command to + // perform different operations. + // Active low and async reset. + //---------------------------------------------------------------- + always_ff @(posedge clk or negedge reset_n) + begin : ECDSA_FSM + if(!reset_n) begin + prog_cntr <= ECC_RESET; + cycle_cnt <= '0; + pm_cmd_reg <= '0; + ecc_valid_reg <= 0; + scalar_G_sel <= 0; + hmac_mode <= '0; + hmac_init <= 0; + scalar_sca_en <= 0; + keygen_process <= 0; + signing_process <= 0; + verifying_process <= 0; + sharedkey_process <= 0; + end + else if(zeroize_reg) begin + prog_cntr <= ECC_RESET; + cycle_cnt <= '0; + pm_cmd_reg <= '0; + ecc_valid_reg <= 0; + scalar_G_sel <= 0; + hmac_mode <= '0; + hmac_init <= 0; + scalar_sca_en <= 0; + keygen_process <= 0; + signing_process <= 0; + verifying_process <= 0; + sharedkey_process <= 0; + end + else if (error_flag | error_flag_reg) begin + prog_cntr <= ECC_NOP; + cycle_cnt <= '0; + pm_cmd_reg <= '0; + ecc_valid_reg <= 0; + scalar_G_sel <= 0; + hmac_mode <= '0; + hmac_init <= 0; + scalar_sca_en <= 0; + keygen_process <= 0; + signing_process <= 0; + verifying_process <= 0; + sharedkey_process <= 0; + end + else begin + if (subcomponent_busy) begin //Stalled until sub-component is done + prog_cntr <= prog_cntr; + cycle_cnt <= 2'd3; + pm_cmd_reg <= '0; + scalar_sca_en <= 0; + hmac_init <= 0; + end + else if (dsa_busy & (cycle_cnt != 2'd3)) begin + cycle_cnt <= cycle_cnt + 1; + end + else begin + cycle_cnt <= '0; + unique case (prog_cntr) + ECC_NOP : begin + keygen_process <= 0; + signing_process <= 0; + verifying_process <= 0; + sharedkey_process <= 0; + // Waiting for new valid command + unique case (cmd_reg) + KEYGEN : begin // keygen + prog_cntr <= DSA_KG_S; + ecc_valid_reg <= 0; + scalar_G_sel <= 0; + hmac_mode <= 2'b00; + keygen_process <= 1; + end + + SIGN : begin // signing + prog_cntr <= DSA_SGN_S; + ecc_valid_reg <= 0; + scalar_G_sel <= 0; + hmac_mode <= 2'b01; + signing_process <= 1; + end + + VERIFY : begin // verifying + prog_cntr <= DSA_VER_S; + ecc_valid_reg <= 0; + scalar_G_sel <= 1; + verifying_process <= 1; + end + + SHARED_KEY : begin // DH shared_key + prog_cntr <= DH_SHARED_S; + ecc_valid_reg <= 0; + scalar_G_sel <= 1; + hmac_mode <= 2'b10; + sharedkey_process <= 1; + end + + default : begin + prog_cntr <= ECC_NOP; + scalar_G_sel <= 0; + end + endcase + pm_cmd_reg <= '0; + hmac_init <= 0; + end + + DSA_KG_E : begin // end of keygen + prog_cntr <= ECC_NOP; + ecc_valid_reg <= 1; + end + + DSA_SGN_E : begin // end of signing + prog_cntr <= ECC_NOP; + ecc_valid_reg <= 1; + end + + DSA_VER_E : begin // end of verifying + prog_cntr <= ECC_NOP; + ecc_valid_reg <= 1; + end + + DH_SHARED_E: begin // end of DH shared key + prog_cntr <= ECC_NOP; + ecc_valid_reg <= 1; + end + + ECC_RESET, + DSA_KG_S, + DSA_SGN_S, + DSA_VER_S, + DH_SHARED_S : begin + prog_cntr <= prog_cntr + 1; + pm_cmd_reg <= prog_instr.opcode.pm_cmd; + hmac_init <= prog_instr.opcode.hmac_drbg_en; + scalar_sca_en <= prog_instr.opcode.sca_en; + end + + default : begin + prog_cntr <= prog_cntr + 1; + pm_cmd_reg <= prog_instr.opcode.pm_cmd; + hmac_init <= prog_instr.opcode.hmac_drbg_en; + scalar_sca_en <= prog_instr.opcode.sca_en; + end + endcase + end + end + end // ECDSA_FSM + + // Generate a pulse to trig the interupt after finishing the operation + always_ff @(posedge clk or negedge reset_n) + if (!reset_n) + ecc_status_done_d <= 1'b0; + else if (zeroize_reg) + ecc_status_done_d <= 1'b0; + else + ecc_status_done_d <= hwif_in.ECC_STATUS.VALID.next; + always_comb ecc_status_done_p = hwif_in.ECC_STATUS.VALID.next && !ecc_status_done_d; + + // Set the ready/busy flag of ECC + assign dsa_busy = (prog_cntr == ECC_NOP)? 1'b0 : 1'b1; + always_comb ecc_ready_reg = !(dsa_busy | pm_busy_o); + + //Key Vault Control Modules + always_comb begin + kv_privkey_read_metrics.ocp_lock_in_progress = ocp_lock_in_progress; + kv_privkey_read_metrics.kv_read_dest = KV_NUM_READ'(1<= prime, it is rejected and a new random value +// is generated by calling HMAC_DRBG_Generate_algorithm. +// There is NO RESEED process. +// - NEXT: it calls HMAC_DRBG_Generate_algorithm (additional input string is empty) +// to generate a 384-bit random value while it's in (0, prime) range. +// if the random value is zero or >= prime, it is rejected and a new random value +// is generated by calling HMAC_DRBG_Generate_algorithm. +// There is NO RESEED process. +// +//====================================================================== + +module ecc_hmac_drbg_interface#( + parameter REG_SIZE = 384, + parameter [REG_SIZE-1 : 0] GROUP_ORDER = 384'hffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52973 + ) + ( + // Clock and reset. + input wire clk, + input wire reset_n, + input wire zeroize, + input wire [1 : 0] hmac_mode, + input wire en, + output wire ready, + + //Data + input wire [REG_SIZE-1 : 0] keygen_seed, + input wire [REG_SIZE-1 : 0] keygen_nonce, + input wire [REG_SIZE-1 : 0] privKey, + input wire [REG_SIZE-1 : 0] hashed_msg, + input wire [REG_SIZE-1 : 0] IV, + + output wire [REG_SIZE-1 : 0] lambda, + output wire [REG_SIZE-1 : 0] scalar_rnd, + output wire [REG_SIZE-1 : 0] masking_rnd, + output wire [REG_SIZE-1 : 0] drbg + ); + + //---------------------------------------------------------------- + // Registers including update variables and write enable. + //---------------------------------------------------------------- + logic [REG_SIZE-1 : 0] lfsr_seed_reg; + logic [REG_SIZE-1 : 0] hmac_lfsr_seed; + + logic hmac_drbg_init; + logic hmac_drbg_next; + logic hmac_drbg_ready; + logic hmac_drbg_valid; + logic [REG_SIZE-1 : 0] hmac_drbg_entropy; + logic [REG_SIZE-1 : 0] hmac_drbg_nonce; + logic [REG_SIZE-1 : 0] hmac_drbg_result; + + logic first_round; + logic [REG_SIZE-1 : 0] lambda_reg; + logic [REG_SIZE-1 : 0] scalar_rnd_reg; + logic [REG_SIZE-1 : 0] masking_rnd_reg; + logic [REG_SIZE-1 : 0] drbg_reg; + logic hmac_drbg_valid_last; + logic hmac_done_edge; + + logic [63 : 0] counter_reg; + logic [REG_SIZE-1 : 0] counter_nonce; + logic [REG_SIZE-1 : 0] counter_nonce_reg; + logic [REG_SIZE-1 : 0] sca_entropy, sca_entropy_reg; + + localparam [1 : 0] KEYGEN_CMD = 2'b00; + localparam [1 : 0] SIGN_CMD = 2'b01; + localparam [1 : 0] DH_SHARED_CMD = 2'b10; + + /*State register*/ + reg [3 : 0] state_reg; + reg [3 : 0] state_next; + reg [3 : 0] state_reg_last; + + /*STATES*/ + localparam [3 : 0] IDLE_ST = 4'd0; + localparam [3 : 0] LFSR_ST = 4'd1; + localparam [3 : 0] LAMBDA_ST = 4'd2; + localparam [3 : 0] SCALAR_RND_ST = 4'd3; + localparam [3 : 0] RND_DONE_ST = 4'd4; + localparam [3 : 0] MASKING_RND_ST = 4'd5; + localparam [3 : 0] KEYGEN_ST = 4'd6; + localparam [3 : 0] SIGN_ST = 4'd7; + localparam [3 : 0] DONE_ST = 4'd8; + + //---------------------------------------------------------------- + // Module instantiantions. + //---------------------------------------------------------------- + + hmac_drbg #( + .REG_SIZE(REG_SIZE), + .HMAC_DRBG_PRIME(GROUP_ORDER) + ) + hmac_drbg_i ( + .clk(clk), + .reset_n(reset_n), + .zeroize(zeroize), + .init_cmd(hmac_drbg_init), + .next_cmd(hmac_drbg_next), + .ready(hmac_drbg_ready), + .valid(hmac_drbg_valid), + .lfsr_seed(hmac_lfsr_seed), + .entropy(hmac_drbg_entropy), + .nonce(hmac_drbg_nonce), + .drbg(hmac_drbg_result) + ); + + genvar i; + generate + for (i=0; i < 12; i++) begin : gen_lfsr + caliptra_prim_lfsr + #( + .LfsrType("FIB_XNOR"), + .LfsrDw(32), + .StateOutDw(32) + ) caliptra_prim_lfsr_inst_i + ( + .clk_i(clk), + .rst_ni(reset_n), + .seed_en_i(hmac_drbg_init), + .seed_i(sca_entropy[i*32 +: 32]), + .lfsr_en_i(1'b1), + .entropy_i('0), + .state_o(hmac_lfsr_seed[i*32 +: 32]) + ); + end + endgenerate + + //---------------------------------------------------------------- + // hmac_drbg_interface_logic + // + // The logic needed to init as well as update the hmac_drbg commands. + //---------------------------------------------------------------- + always_comb first_round = (state_reg == state_reg_last)? 1'b0 : 1'b1; + always_comb hmac_done_edge = hmac_drbg_valid & (!hmac_drbg_valid_last); + + always_comb + begin : hmac_drbg_entropy_input + unique case (state_reg) + LFSR_ST: hmac_drbg_entropy = sca_entropy_reg; + LAMBDA_ST: hmac_drbg_entropy = sca_entropy_reg; + SCALAR_RND_ST: hmac_drbg_entropy = sca_entropy_reg; + MASKING_RND_ST: hmac_drbg_entropy = sca_entropy_reg; + KEYGEN_ST: hmac_drbg_entropy = keygen_seed; + SIGN_ST: hmac_drbg_entropy = privKey; + default: hmac_drbg_entropy = sca_entropy_reg; + endcase + end // hmac_drbg_entropy_input + + always_comb + begin : hmac_drbg_nonce_input + unique case (state_reg) + LFSR_ST: hmac_drbg_nonce = counter_nonce_reg; + LAMBDA_ST: hmac_drbg_nonce = counter_nonce_reg; + SCALAR_RND_ST: hmac_drbg_nonce = counter_nonce_reg; + MASKING_RND_ST: hmac_drbg_nonce = counter_nonce_reg; + KEYGEN_ST: hmac_drbg_nonce = keygen_nonce; + SIGN_ST: hmac_drbg_nonce = hashed_msg; + default: hmac_drbg_nonce = counter_nonce_reg; + endcase + end // hmac_drbg_nonce_input + + + always_comb + begin :hmac_trigger + hmac_drbg_init = 0; + hmac_drbg_next = 0; + if (first_round) begin + unique case (state_reg) + LFSR_ST: hmac_drbg_init = 1; + LAMBDA_ST: hmac_drbg_next = 1; + SCALAR_RND_ST: hmac_drbg_next = 1; + MASKING_RND_ST: hmac_drbg_next = 1; + KEYGEN_ST: hmac_drbg_init = 1; + SIGN_ST: hmac_drbg_init = 1; + default: begin + hmac_drbg_init = 0; + hmac_drbg_next = 0; + end + endcase + end + end //hmac_trigger + + //---------------------------------------------------------------- + // register updates + // + // update the internal registers + //---------------------------------------------------------------- + always_ff @(posedge clk or negedge reset_n) + begin //reg_update + if (!reset_n) begin + lambda_reg <= '0; + scalar_rnd_reg <= '0; + masking_rnd_reg <= '0; + drbg_reg <= '0; + lfsr_seed_reg <= '0; + end + else if (zeroize) begin + lambda_reg <= '0; + scalar_rnd_reg <= '0; + masking_rnd_reg <= '0; + drbg_reg <= '0; + //lfsr_seed_reg <= '0; // without zeroize to make it more complex + end + else + if (hmac_done_edge) begin + unique case (state_reg) inside + LFSR_ST: lfsr_seed_reg <= hmac_drbg_result; + LAMBDA_ST: lambda_reg <= hmac_drbg_result; + SCALAR_RND_ST: scalar_rnd_reg <= hmac_drbg_result; + MASKING_RND_ST: masking_rnd_reg <= hmac_drbg_result; + KEYGEN_ST: drbg_reg <= hmac_drbg_result; + SIGN_ST: drbg_reg <= hmac_drbg_result; + default: begin + lambda_reg <= '0; + scalar_rnd_reg <= '0; + masking_rnd_reg <= '0; + drbg_reg <= '0; + end + endcase + end + end //reg_update + + always_ff @(posedge clk or negedge reset_n) + begin : state_reg_update + if (!reset_n) + state_reg <= IDLE_ST; + else if (zeroize) + state_reg <= IDLE_ST; + else + state_reg <= state_next; + end // state_reg_update + + always_ff @(posedge clk or negedge reset_n) + begin : ff_state_reg + if (!reset_n) + state_reg_last <= IDLE_ST; + else if (zeroize) + state_reg_last <= IDLE_ST; + else + state_reg_last <= state_reg; + end // ff_state_reg + + always_ff @(posedge clk or negedge reset_n) + begin : ff_hamc_valid + if (!reset_n) + hmac_drbg_valid_last <= '0; + else if (zeroize) + hmac_drbg_valid_last <= '0; + else + hmac_drbg_valid_last <= hmac_drbg_valid; + end //ff_hamc_valid + + // without zeroize to make it more complex + always_ff @(posedge clk or negedge reset_n) + begin : counter_reg_update + if (!reset_n) + counter_reg <= '0; + else + counter_reg <= counter_reg + 1; + end // counter_reg_update + + // without zeroize to make it more complex + always_ff @(posedge clk or negedge reset_n) + begin + if (!reset_n) begin + counter_nonce_reg <= '0; + sca_entropy_reg <= '0; + end else if (en && (state_reg == IDLE_ST)) begin + counter_nonce_reg <= counter_nonce; + sca_entropy_reg <= sca_entropy; + end + end + + always_comb counter_nonce = {counter_reg, counter_reg, counter_reg, counter_reg, counter_reg, counter_reg}; + always_comb sca_entropy = IV ^ lfsr_seed_reg ^ counter_nonce; + //---------------------------------------------------------------- + // FSM_flow + // + // This FSM starts with the en command to perfrom HMAC-DRBG. + // Active low and async reset. + //---------------------------------------------------------------- + always_comb + begin : interface_fsm + state_next = IDLE_ST; + unique case(state_reg) + IDLE_ST: state_next = (en & hmac_drbg_ready)? LFSR_ST : IDLE_ST; + LFSR_ST: state_next = (hmac_done_edge)? LAMBDA_ST : LFSR_ST; + LAMBDA_ST: state_next = (hmac_done_edge)? SCALAR_RND_ST : LAMBDA_ST; + SCALAR_RND_ST: state_next = (hmac_done_edge)? RND_DONE_ST : SCALAR_RND_ST; + RND_DONE_ST: state_next = (hmac_mode == SIGN_CMD)? MASKING_RND_ST : (hmac_mode == KEYGEN_CMD)? KEYGEN_ST : DONE_ST; + MASKING_RND_ST: state_next = (hmac_done_edge)? SIGN_ST : MASKING_RND_ST; + KEYGEN_ST: state_next = (hmac_done_edge)? DONE_ST : KEYGEN_ST; + SIGN_ST: state_next = (hmac_done_edge)? DONE_ST: SIGN_ST; + DONE_ST: state_next = IDLE_ST; + default: state_next = IDLE_ST; + endcase + end // interface_fsm + + //---------------------------------------------------------------- + // Concurrent connectivity for ports etc. + //---------------------------------------------------------------- + assign lambda = lambda_reg; + assign scalar_rnd = scalar_rnd_reg; + assign masking_rnd = masking_rnd_reg; + assign drbg = drbg_reg; + assign ready = (state_reg == IDLE_ST); + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/ecc_montgomerymultiplier.sv b/designs/Caliptra/src/caliptra-rtl/ecc_montgomerymultiplier.sv new file mode 100644 index 0000000..db767af --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/ecc_montgomerymultiplier.sv @@ -0,0 +1,375 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +// +//====================================================================== +// Module: +// ecc_montgomerymultiplier.sv +// +// Montgomery Multiplier based on +// Optimized Algorithms and Architectures for Montgomery Multiplication +// for Post-quantum Cryptography by Rami Elkhatib et. al. +// +// Description: +// The module produces a Montgomery product of input operands with the following contraints: +// Input operands must be less than n_i, i.e. opa_i < n_i and opb_i < n_i. +// RADIX > 2 +// R = 2^((ceil($bits(n_i) / RADIX) + 1) * RADIX) +// R > n_i. +// (1) T = opa_i * opb_i < n_i * n_i = n_i^2 +// (2) p_internal = (T + (T*n_prime mod R) * n_i) / R +// (3) p_subtracted_internal = p_internal - n_i +// (4) p_o = (p_internal >= ni)? p_subtracted_internal : p_internal +// From (1) and (2) given R > n_i, and opa_i, opb_i < n_i: +// p_internal < (n_i^2 + R * n_i) / R = n_i + n_i^2 / R < n_i + n_i^2 / n_i = n_i + n_i = 2*n_i +// From (3) and (4): +// p_subtracted_internal < 2*n_i - n_i = n_i +// p_o < n_i +//====================================================================== + +module ecc_montgomerymultiplier #( + parameter REG_SIZE = 384, + parameter RADIX = 32 +) +( + // Clock and reset. + input wire clk, + input wire reset_n, + input wire zeroize, + + // DATA PORT + input wire start_i, + input wire [REG_SIZE-1:0] opa_i, + input wire [REG_SIZE-1:0] opb_i, + input wire [REG_SIZE-1:0] n_i, + input wire [RADIX-1:0] n_prime_i, // only need the last few bits + output logic [REG_SIZE-1:0] p_o, + output logic ready_o +); + //---------------------------------------------------------------- + // Local Parameters + //---------------------------------------------------------------- + + // Equivalent to $ceil(real'(REG_SIZE) / RADIX) + 1; + localparam int unsigned S_NUM = ((REG_SIZE + RADIX - 1) / RADIX) + 1; + localparam int unsigned FULL_REG_SIZE = S_NUM * RADIX; + // Each PE performs two iterations out of S_NUM - 1 + // See section 4.2 of Elkhatib_2019 paper. + // PE_UNITS does not include the last PE. + // The last PE is instantiated separately. + localparam PE_UNITS = ((S_NUM - 1) / 2) - 1; + localparam [(FULL_REG_SIZE-REG_SIZE)-1 : 0] zero_pad = '0; + + //---------------------------------------------------------------- + // Registers + //---------------------------------------------------------------- + logic [RADIX-1 : 0] a_array[0:PE_UNITS+1]; + logic [RADIX-1 : 0] b_array[0:PE_UNITS+1]; + logic [RADIX-1 : 0] p_array[0:PE_UNITS+1]; + logic [RADIX-1 : 0] m_array[0:PE_UNITS]; + logic [RADIX : 0] c_array[0:PE_UNITS+1]; + logic [RADIX-1 : 0] s_array[0:PE_UNITS+1]; + + logic [RADIX-1 : 0] p_neg_array[0:2*(PE_UNITS+1)]; + logic [RADIX-1 : 0] t_reg[0:2*(PE_UNITS+1)]; + logic [RADIX-1 : 0] t_subtracted_reg[0:2*(PE_UNITS+1)]; + logic [RADIX : 0] sub_res[0:2*(PE_UNITS+1)]; + + logic sub_b_i[0:2*(PE_UNITS+1)]; + logic sub_b_o[0:2*(PE_UNITS+1)]; + + logic [FULL_REG_SIZE-1 : 0] a_reg; //extended with zero + logic [FULL_REG_SIZE-1 : 0] b_reg; //extended with zero + logic [FULL_REG_SIZE-1 : 0] p_reg; //extended with zero + logic [FULL_REG_SIZE-1 : 0] p_neg_reg; //extended with one + logic [RADIX-1:0] n_prime_reg; + logic [(3*S_NUM)-1 : 0] push_reg; + logic push_reg_eq_zero; + logic push_reg_eq_zero_ff; + logic odd; + logic [RADIX-1 : 0] last_s_reg; + logic [FULL_REG_SIZE-1:0] p_internal; + logic [FULL_REG_SIZE-1:0] p_subtracted_internal; + logic last_reduction; + + //---------------------------------------------------------------- + // Processing elements (PEs) + //---------------------------------------------------------------- + ecc_pe_first #( + .RADIX(RADIX) + ) + first_box + ( + .clk(clk), + .reset_n(reset_n), + .zeroize(zeroize), + .start_in(start_i), + .a_in(a_array[0]), + .b_in(b_array[0]), + .p_in(p_array[0]), + .s_in(s_array[0]), + .n_prime_in(n_prime_reg), + .odd(odd), + + .a_out(a_array[1]), + .m_out(m_array[0]), + .c_out(c_array[0]) + ); + + genvar i0; + generate + for (i0=0; i0 < PE_UNITS; i0++) begin : gen_PE //PE general boxes + ecc_pe #( + .RADIX(RADIX) + ) + box_i + ( + .clk(clk), + .reset_n(reset_n), + .zeroize(zeroize), + .start_in(start_i), + .a_in(a_array[i0+1]), + .b_in(b_array[i0+1]), + .p_in(p_array[i0+1]), + .m_in(m_array[i0]), + .s_in(s_array[i0+1]), + .c_in(c_array[i0]), + .odd(odd), + + .a_out(a_array[i0+2]), + .m_out(m_array[i0+1]), + .s_out(s_array[i0]), + .c_out(c_array[i0+1]) + ); + end + endgenerate + + ecc_pe_final #( + .RADIX(RADIX) + ) + final_box + ( + .clk(clk), + .reset_n(reset_n), + .zeroize(zeroize), + .start_in(start_i), + .a_in(a_array[PE_UNITS+1]), + .b_in(b_array[PE_UNITS+1]), + .p_in(p_array[PE_UNITS+1]), + .m_in(m_array[PE_UNITS]), + .s_in(s_array[PE_UNITS+1]), + .c_in(c_array[PE_UNITS]), + .odd(odd), + + .s_out(s_array[PE_UNITS]), + .c_out(c_array[PE_UNITS+1]) + ); + + // Determines the input s for the final PE + assign s_array[PE_UNITS+1] = last_s_reg; + always_ff @(posedge clk or negedge reset_n) + begin + if (~reset_n) + last_s_reg <= 'b0; + else if (zeroize) + last_s_reg <= 'b0; + else if (start_i) + last_s_reg <= 'b0; + else + last_s_reg <= c_array[PE_UNITS+1][RADIX-1:0]; + end + + // Set odd flag + always_ff @(posedge clk or negedge reset_n) + begin + if (~reset_n) + odd <= 0; + else if (zeroize) + odd <= 0; + else if (start_i) + odd <= 1'b1; + else + odd <= ~odd; + end + + always_ff @(posedge clk or negedge reset_n) + begin : input_reg + if (~reset_n) begin + a_reg <= 'b0; + b_reg <= 'b0; + p_reg <= 'b0; + n_prime_reg <= 'b0; + end + else if (zeroize) begin + a_reg <= 'b0; + b_reg <= 'b0; + p_reg <= 'b0; + n_prime_reg <= 'b0; + end + else if (start_i) begin + a_reg <= {zero_pad, opa_i}; + b_reg <= {zero_pad, opb_i}; + p_reg <= {zero_pad, n_i}; + n_prime_reg <= n_prime_i; + end else begin + if (odd) begin + a_reg[(FULL_REG_SIZE-RADIX)-1 : 0] <= a_reg[FULL_REG_SIZE-1 : RADIX]; + a_reg[FULL_REG_SIZE-1 : FULL_REG_SIZE-RADIX] <= 'b0; //Shift + end + end + end // input_reg + + assign a_array[0] = a_reg[RADIX-1 : 0]; + + // Determines which b and p is pushed through the system + assign b_array[0] = b_reg[RADIX-1 : 0]; + assign p_array[0] = p_reg[RADIX-1 : 0]; + genvar j0; + generate + for (j0=1; j0 < (PE_UNITS+2); j0++) begin : gen_b_p_array + assign b_array[j0] = odd ? b_reg[(((2*j0)+1)*RADIX)-1 : (2*j0)*RADIX] : b_reg[((2*j0)*RADIX)-1 : ((2*j0)-1)*RADIX]; + assign p_array[j0] = odd ? p_reg[(((2*j0)+1)*RADIX)-1 : (2*j0)*RADIX] : p_reg[((2*j0)*RADIX)-1 : ((2*j0)-1)*RADIX]; + end + endgenerate + + + assign p_neg_reg = ~p_reg; + + genvar i1; + generate + for (i1=0; i1 < ((2*(PE_UNITS+1))+1); i1++) begin : gen_n_neg_array + assign p_neg_array[i1] = p_neg_reg[i1*RADIX +: RADIX]; + end + endgenerate + + // Storing the partial results from the system + genvar t0; + generate + for (t0=0; t0 < ((2*(PE_UNITS+1))+1); t0++) begin : gen_t_reg + if ((t0 == 0) | (t0 == 1)) begin + always_ff @(posedge clk or negedge reset_n) begin + if (~reset_n) + t_reg[t0] <= '0; + else if (zeroize) + t_reg[t0] <= '0; + else if (push_reg[(2*(PE_UNITS+1)) - t0]) + t_reg[t0] <= s_array[0]; + else + t_reg[t0] <= t_reg[t0]; + end + end + else begin + localparam int t0_WIDTH = $clog2((2*(PE_UNITS+1))+1); + localparam bit [t0_WIDTH-1:0] t0_unsigned = t0[t0_WIDTH-1:0]; + always_ff @(posedge clk or negedge reset_n) begin + if (~reset_n) + t_reg[t0] <= '0; + else if (zeroize) + t_reg[t0] <= '0; + else if (push_reg[(2*(PE_UNITS+1)) - t0]) + t_reg[t0] <= s_array[t0_unsigned >> 1]; + else + t_reg[t0] <= t_reg[t0]; + end + end + end // gen_t_reg + endgenerate + + genvar t1; + generate + for (t1=0; t1 < ((2*(PE_UNITS+1))+1); t1++) begin : gen_sub_t + if (t1 == 0) + always_comb sub_b_i[t1] = 1; + else + always_comb sub_b_i[t1] = sub_b_o[t1 - 1]; + + always_ff @(posedge clk or negedge reset_n) begin + if (~reset_n) + sub_b_o[t1] <= '0; + else if (zeroize) + sub_b_o[t1] <= '0; + else + sub_b_o[t1] <= sub_res[t1][RADIX]; + end + end + endgenerate + + genvar t2; + generate + for (t2=0; t2 < ((2*(PE_UNITS+1))+1); t2++) + begin : gen_sub_res_t + //if (~reset_n) + // sub_res[t2] = 0; + //else if (push_reg[2*(PE_UNITS+1) - t2]) + localparam int t2_WIDTH = $clog2((2*(PE_UNITS+1))+1); + localparam bit [t2_WIDTH-1:0] t2_unsigned = t2[t2_WIDTH-1:0]; + if ((t2 == 0) | (t2 == 1)) + always_comb sub_res[t2] = s_array[0] + p_neg_array[t2] + sub_b_i[t2]; + else + always_comb sub_res[t2] = s_array[t2_unsigned >> 1] + p_neg_array[t2] + sub_b_i[t2]; + end // gen_sub_res_t + endgenerate + + genvar t3; + generate + for (t3=0; t3 < ((2*(PE_UNITS+1))+1); t3++) begin : gen_t_sub_reg + always_ff @(posedge clk or negedge reset_n) begin + if (~reset_n) + t_subtracted_reg[t3] <= '0; + else if (zeroize) + t_subtracted_reg[t3] <= '0; + else if (push_reg[(2*(PE_UNITS+1)) - t3]) + t_subtracted_reg[t3] <= sub_res[t3][RADIX-1 : 0]; + else + t_subtracted_reg[t3] <= t_subtracted_reg[t3]; + end + end // gen_t_sub_reg + endgenerate + + // Storing the final results from the system + genvar k0; + generate + for (k0=0; k0 < ((2*(PE_UNITS+1))+1); k0++) begin : gen_p_o + assign p_internal[k0*RADIX +: RADIX] = t_reg[k0]; + assign p_subtracted_internal[k0*RADIX +: RADIX] = t_subtracted_reg[k0]; + end + endgenerate + + always_comb last_reduction = (sub_b_o[2*(PE_UNITS+1)]); + assign p_o = (last_reduction)? p_subtracted_internal[REG_SIZE-1:0] : p_internal[REG_SIZE-1:0]; + + // Determines when results are ready based on S_NUM + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) + push_reg <= 'b0; + else if (zeroize) + push_reg <= 'b0; + else if (start_i) + push_reg[(3*S_NUM)-1] <= 1'b1; + else // one shift to right + push_reg <= {1'b0, push_reg[(3*S_NUM)-1 : 1]}; + end + + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) + push_reg_eq_zero_ff <= '0; + else if (zeroize) + push_reg_eq_zero_ff <= '0; + else + push_reg_eq_zero_ff <= push_reg_eq_zero; + end + + assign push_reg_eq_zero = push_reg == 'b0; + assign ready_o = push_reg_eq_zero & ~push_reg_eq_zero_ff; + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/ecc_mult_dsp.sv b/designs/Caliptra/src/caliptra-rtl/ecc_mult_dsp.sv new file mode 100644 index 0000000..1cd01ff --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/ecc_mult_dsp.sv @@ -0,0 +1,39 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +// +//====================================================================== +// +// ecc_mult_dsp.sv +// -------- +// General multiplier to perfrom P = A*B. +// +// +//====================================================================== + +module ecc_mult_dsp #( + parameter RADIX = 32 +) +( + // DATA PORT + input wire [RADIX-1 : 0] A_i, + input wire [RADIX-1 : 0] B_i, + + output logic [(2*RADIX)-1 : 0] P_o +); + + always_comb begin + P_o = A_i * B_i; + end + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/ecc_params_pkg.sv b/designs/Caliptra/src/caliptra-rtl/ecc_params_pkg.sv new file mode 100644 index 0000000..b22c483 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/ecc_params_pkg.sv @@ -0,0 +1,77 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +// +//====================================================================== +// +// ecc_params_pkg.sv +// -------- +// required parameters and register address for ECC Secp384r1. +// +//====================================================================== + +`ifndef CALIPTRA_ECC_PARAMS_PKG +`define CALIPTRA_ECC_PARAMS_PKG + +package ecc_params_pkg; + + //---------------------------------------------------------------- + // Internal constant and parameter definitions. + //---------------------------------------------------------------- + parameter KEYGEN = 3'b001; + parameter SIGN = 3'b010; + parameter VERIFY = 3'b011; + parameter SHARED_KEY = 3'b100; + + parameter [63 : 0] ECC_CORE_NAME = 64'h38342D33_63707365; // "secp-384" + parameter [63 : 0] ECC_CORE_VERSION = 64'h00000000_3030312e; // "1.00" + + // Implementation parameters for field arithmetic + parameter [9 : 0] REG_SIZE = 10'd384; + parameter [9 : 0] RND_SIZE = 10'd192; // half of REG_SIZE based on Schindler W, Wiemers A (2015) Efficient side-channel attacks on + // scalar blinding on elliptic curves with special structure. In: NIST Workshop on ECC standards + parameter DATA_WIDTH = 32; + parameter REG_NUM_DWORDS = REG_SIZE/DATA_WIDTH; + parameter REG_OFFSET_W = $clog2(REG_NUM_DWORDS); + parameter MULT_RADIX = 48; + parameter SCALAR_BLIND_RADIX = 32; + parameter ADD_NUM_ADDS = 1; + parameter ADD_BASE_SZ = 384; + + // prime parameters in Montgomery domain + parameter [REG_SIZE-1 : 0] PRIME = 384'hfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000ffffffff; + parameter [REG_SIZE-1 : 0] GROUP_ORDER = 384'hffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52973; + + // prime parameters in Montgomery domain + parameter [REG_SIZE-1 : 0] ZERO_CONST = 384'h0; + parameter [REG_SIZE-1 : 0] ONE_CONST = 384'h1; + parameter [REG_SIZE-1 : 0] E_a_MONT = 384'hfffffffffffffffffffffffffffffffffffffffffffffffffffcfffffffcfffeffffffff0002fffffffd0000ffffffff; + parameter [REG_SIZE-1 : 0] E_b_MONT = 384'hbff9b62b21f41f022094e3374bee94938ae277f2209b1920022fc431bf24a7a3443768608870d0391c816cb9114b604f; + parameter [REG_SIZE-1 : 0] E_3b_MONT = 384'h3fed228165dc5d0661bea9a5e3cbbdbaa0a767d661d14b60068f4c953d6df6ebcca63923995270ab5584462933e220ef; + parameter [REG_SIZE-1 : 0] ONE_p_MONT = 384'h100000000ffffffffffffffff00000001000000000000; + parameter [REG_SIZE-1 : 0] R2_p_MONT = 384'h10000000200000000fffffffe000000000000000200000000fffffffe00000001000000000000000000000000; + parameter [REG_SIZE-1 : 0] G_X_MONT = 384'h1513812ff723614ede2b6454868459a30eff879c3afc541b4d6e6e1e26a517af7bfa676e7565fc860766239cadc2299e; + parameter [REG_SIZE-1 : 0] G_Y_MONT = 384'hc5e9dd8002263969a840c6c3521968f4ffd98bade7562e83b050cd3854820142556e7d193dad1f8af93bd163abc25a15; + parameter [MULT_RADIX-1 : 0] PRIME_mu = 64'h100000001; + + // group order parameters in Montgomery domain + parameter [REG_SIZE-1 : 0] R2_q_MONT = 384'h28266895d40d49174aab1cc5bf030606de609f43cc9601f9ebbfed4b3ffe90bfead8c2590449c1c55daf7abd883e5e32; + parameter [REG_SIZE-1 : 0] ONE_q_MONT = 384'h389cb27e0bc8d220a7e5f24db74f58851313e695333ad68d000000000000; + parameter [MULT_RADIX-1 : 0] GROUP_ORDER_mu = 64'h6089e88fdc45; + +endpackage + +`endif +//====================================================================== +// EOF ecc_params.sv +//====================================================================== diff --git a/designs/Caliptra/src/caliptra-rtl/ecc_pe.sv b/designs/Caliptra/src/caliptra-rtl/ecc_pe.sv new file mode 100644 index 0000000..921c223 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/ecc_pe.sv @@ -0,0 +1,162 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +// +//====================================================================== +// +// ecc_pe.sv +// -------- +// processing element for Montgomery Multiplier based on +// Optimized Algorithms and Architectures for Montgomery Multiplication +// for Post-quantum Cryptography by Rami Elkhatib et. al. +// +//====================================================================== + +module ecc_pe #( + parameter RADIX = 32 +) +( + // Clock and reset. + input wire clk, + input wire reset_n, + input wire zeroize, + + input wire start_in, + // DATA PORT + input wire [RADIX-1:0] a_in, + input wire [RADIX-1:0] b_in, + input wire [RADIX-1:0] p_in, + input wire [RADIX-1:0] m_in, + input wire [RADIX-1:0] s_in, + input wire [RADIX :0] c_in, + input wire odd, + + output logic [RADIX-1:0] a_out, + output logic [RADIX-1:0] m_out, + output logic [RADIX-1:0] s_out, + output logic [RADIX :0] c_out +); + + + //---------------------------------------------------------------- + // ecc_pe + //---------------------------------------------------------------- + logic [(2*RADIX)-1 : 0] mult0_out; + logic [(2*RADIX)-1 : 0] mult1_out; + + logic [RADIX : 0] c_mux; + logic [RADIX-1 : 0] s_mux; + + logic [2*RADIX : 0] res; + logic [RADIX-1 : 0] res_LSW; + logic [RADIX : 0] res_MSW; + + logic carry_garbage_bit; + + //---------------------------------------------------------------- + // Module instantiantions. + //---------------------------------------------------------------- + ecc_mult_dsp #( + .RADIX(RADIX) + ) MULT1 ( + .A_i(a_in), + .B_i(b_in), + .P_o(mult0_out) + ); + + ecc_mult_dsp #( + .RADIX(RADIX) + ) MULT2 ( + .A_i(p_in), + .B_i(m_in), + .P_o(mult1_out) + ); + + //---------------------------------------------------------------- + // pe_logic + // + // The logic needed to update the multiplier inputs. + //---------------------------------------------------------------- + assign c_mux = odd ? c_out : c_in; + assign s_mux = odd ? s_in : s_out; + + assign res_MSW = res[2*RADIX : RADIX]; + assign res_LSW = res[RADIX-1 : 0]; + + always_comb {carry_garbage_bit, res} = mult0_out + mult1_out + c_mux + s_mux; + + //---------------------------------------------------------------- + // register updates + // + //---------------------------------------------------------------- + always_ff @(posedge clk or negedge reset_n) begin + if (~reset_n) begin + c_out <= 'b0; + end + else if (zeroize) begin + c_out <= 'b0; + end + else if (start_in) begin + c_out <= 'b0; + end else begin + c_out <= res_MSW; + end + end + + always_ff @(posedge clk or negedge reset_n) begin + if (~reset_n) begin + s_out <= 'b0; + end + else if (zeroize) begin + s_out <= 'b0; + end + else if (start_in) begin + s_out <= 'b0; + end else begin + s_out <= res_LSW; + end + end + + always_ff @(posedge clk or negedge reset_n) begin + if (~reset_n) begin + a_out <= 'b0; + end + else if (zeroize) begin + a_out <= 'b0; + end + else if (start_in) begin + a_out <= 'b0; + end else begin + if (odd) begin + a_out <= a_in; + end + end + end + + always_ff @(posedge clk or negedge reset_n) begin + if (~reset_n) begin + m_out <= 'b0; + end + else if (zeroize) begin + m_out <= 'b0; + end + else if (start_in) begin + m_out <= 'b0; + end else begin + if (odd) begin + m_out <= m_in; + end + end + end + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/ecc_pe_final.sv b/designs/Caliptra/src/caliptra-rtl/ecc_pe_final.sv new file mode 100644 index 0000000..79a6b66 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/ecc_pe_final.sv @@ -0,0 +1,128 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +// +//====================================================================== +// +// ecc_pe_final.sv +// -------- +// final processing element for Montgomery Multiplier based on +// Optimized Algorithms and Architectures for Montgomery Multiplication +// for Post-quantum Cryptography by Rami Elkhatib et. al. +// +//====================================================================== + +module ecc_pe_final #( + parameter RADIX = 32 +) +( + // Clock and reset. + input wire clk, + input wire reset_n, + input wire zeroize, + + input wire start_in, + // DATA PORT + input wire [RADIX-1:0] a_in, + input wire [RADIX-1:0] b_in, + input wire [RADIX-1:0] p_in, + input wire [RADIX-1:0] m_in, + input wire [RADIX-1:0] s_in, + input wire [RADIX :0] c_in, + input wire odd, + + output logic [RADIX-1:0] s_out, + output logic [RADIX :0] c_out +); + + + //---------------------------------------------------------------- + // ecc_pe + //---------------------------------------------------------------- + logic [(2*RADIX)-1 : 0] mult0_out; + logic [(2*RADIX)-1 : 0] mult1_out; + + logic [RADIX : 0] c_mux; + logic [RADIX-1 : 0] s_mux; + + logic [2*RADIX : 0] res; + logic [RADIX-1 : 0] res_LSW; + logic [RADIX : 0] res_MSW; + + logic carry_garbage_bit; + + //---------------------------------------------------------------- + // Module instantiantions. + //---------------------------------------------------------------- + ecc_mult_dsp #( + .RADIX(RADIX) + ) MULT1 ( + .A_i(a_in), + .B_i(b_in), + .P_o(mult0_out) + ); + + ecc_mult_dsp #( + .RADIX(RADIX) + ) MULT2 ( + .A_i(p_in), + .B_i(m_in), + .P_o(mult1_out) + ); + + //---------------------------------------------------------------- + // pe_logic + // + // The logic needed to update the multiplier inputs. + //---------------------------------------------------------------- + assign c_mux = odd ? c_out : c_in; + assign s_mux = odd ? s_in : s_out; + + assign res_MSW = res[2*RADIX : RADIX]; + assign res_LSW = res[RADIX-1 : 0]; + + always_comb {carry_garbage_bit, res} = mult0_out + mult1_out + c_mux + s_mux; + + //---------------------------------------------------------------- + // register updates + // + //---------------------------------------------------------------- + always_ff @(posedge clk or negedge reset_n) begin + if (~reset_n) begin + c_out <= 'b0; + end + else if (zeroize) begin + c_out <= 'b0; + end + else if (start_in) begin + c_out <= 'b0; + end else begin + c_out <= res_MSW; + end + end + + always_ff @(posedge clk or negedge reset_n) begin + if (~reset_n) begin + s_out <= 'b0; + end + else if (zeroize) begin + s_out <= 'b0; + end + else if (start_in) begin + s_out <= 'b0; + end else begin + s_out <= res_LSW; + end + end + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/ecc_pe_first.sv b/designs/Caliptra/src/caliptra-rtl/ecc_pe_first.sv new file mode 100644 index 0000000..98926d1 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/ecc_pe_first.sv @@ -0,0 +1,204 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +// +//====================================================================== +// +// ecc_pe_first.sv +// -------- +// first processing element for Montgomery Multiplier based on +// Optimized Algorithms and Architectures for Montgomery Multiplication +// for Post-quantum Cryptography by Rami Elkhatib et. al. +// +//====================================================================== + +module ecc_pe_first #( + parameter RADIX = 32 +) +( + // Clock and reset. + input wire clk, + input wire reset_n, + input wire zeroize, + + input wire start_in, + // DATA PORT + input wire [RADIX-1:0] a_in, + input wire [RADIX-1:0] b_in, + input wire [RADIX-1:0] p_in, + input wire [RADIX-1:0] s_in, + input wire [RADIX-1:0] n_prime_in, + input wire odd, + + output logic [RADIX-1:0] a_out, + output logic [RADIX-1:0] m_out, + output logic [RADIX :0] c_out +); + + + //---------------------------------------------------------------- + // ecc_pe_first + //---------------------------------------------------------------- + logic [RADIX-1:0] s_reg; + logic [RADIX-1:0] s_val; + logic [RADIX-1:0] a_reg; + logic [RADIX-1:0] a_val; + + logic [(2*RADIX)-1 : 0] mult_out_0; + logic [RADIX-1 : 0] mult_out_0_MSW; + logic [RADIX-1 : 0] mult_out_0_LSW; + + logic [RADIX : 0] res_0; + logic [RADIX-1 : 0] sum_0; + logic carry_0; + logic [RADIX-1 : 0] sum_0_reg; + + logic [RADIX : 0] res_1; + logic carry_1; + + logic [RADIX : 0] c_0; + logic [RADIX : 0] c_0_reg; + logic [RADIX : 0] c_1; + + logic [(2*RADIX)-1 : 0] mult_out_1; + logic [RADIX-1 : 0] m_temp; + logic [RADIX-1 : 0] m_temp_reg; + + logic [(2*RADIX)-1 : 0] mult_out_2; + logic [RADIX-1 : 0] mult_out_2_MSW; + logic [RADIX-1 : 0] mult_out_2_LSW; + + logic carry_garbage_bit; + + //---------------------------------------------------------------- + // Module instantiantions. + //---------------------------------------------------------------- + ecc_mult_dsp #( + .RADIX(RADIX) + ) MULT0 ( + .A_i(a_val), + .B_i(b_in), + .P_o(mult_out_0) + ); + + ecc_mult_dsp #( + .RADIX(RADIX) + ) MULT1 ( + .A_i(n_prime_in), + .B_i(sum_0), + .P_o(mult_out_1) + ); + + ecc_mult_dsp #( + .RADIX(RADIX) + ) MULT2 ( + .A_i(m_temp_reg), + .B_i(p_in), + .P_o(mult_out_2) + ); + + //---------------------------------------------------------------- + // pe_logic + // + // The logic needed to update the multiplier inputs. + //---------------------------------------------------------------- + assign m_temp = mult_out_1[RADIX-1:0]; + + assign mult_out_0_MSW = mult_out_0[(2*RADIX)-1 : RADIX]; + assign mult_out_0_LSW = mult_out_0[RADIX-1 : 0]; + assign mult_out_2_MSW = mult_out_2[(2*RADIX)-1 : RADIX]; + assign mult_out_2_LSW = mult_out_2[RADIX-1 : 0]; + + assign s_val = odd ? s_in : s_reg; + assign a_val = odd ? a_in : a_reg; + + always_comb begin + res_0 = s_val + mult_out_0_LSW; + sum_0 = res_0[RADIX-1 : 0]; + carry_0 = res_0[RADIX]; + end + + always_comb begin + res_1 = sum_0_reg + mult_out_2_LSW; + carry_1 = res_1[RADIX]; + end + + always_comb c_0 = mult_out_0_MSW + carry_0; + + always_comb c_1 = mult_out_2_MSW + carry_1; + + assign {carry_garbage_bit, c_out} = c_0_reg + c_1; + + //---------------------------------------------------------------- + // register updates + // + //---------------------------------------------------------------- + always_ff @(posedge clk or negedge reset_n) begin + if(~reset_n) begin + c_0_reg <= 'b0; + sum_0_reg <= 'b0; + m_temp_reg <= 'b0; + s_reg <= 'b0; + a_reg <= 'b0; + end + else if (zeroize) begin + c_0_reg <= 'b0; + sum_0_reg <= 'b0; + m_temp_reg <= 'b0; + s_reg <= 'b0; + a_reg <= 'b0; + end + else if (start_in) begin + c_0_reg <= 'b0; + sum_0_reg <= 'b0; + m_temp_reg <= 'b0; + s_reg <= 'b0; + a_reg <= 'b0; + end else begin + s_reg <= s_in; + a_reg <= a_in; + m_temp_reg <= m_temp; + c_0_reg <= c_0; + sum_0_reg <= sum_0; + end + end + + always_ff @(posedge clk or negedge reset_n) begin + if (~reset_n) begin + a_out <= 'b0; + end + else if (zeroize) begin + a_out <= 'b0; + end + else if (start_in) begin + a_out <= 'b0; + end else begin + a_out <= a_val; + end + end + + always_ff @(posedge clk or negedge reset_n) begin + if (~reset_n) begin + m_out <= 'b0; + end + else if (zeroize) begin + m_out <= 'b0; + end + else if (start_in) begin + m_out <= 'b0; + end else begin + m_out <= m_temp; + end + end + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/ecc_pm_ctrl.sv b/designs/Caliptra/src/caliptra-rtl/ecc_pm_ctrl.sv new file mode 100644 index 0000000..c161e47 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/ecc_pm_ctrl.sv @@ -0,0 +1,404 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +// +//====================================================================== +// +// ecc_pm_ctrl.sv +// -------- +// ECC point multiplication controller for the Secp384. +// +// The architecture includes ecc_pm_sequencer including the required +// sequence to perform: +// - point multiplication (pm) based on Montgomery ladder and Fermat's little +// theorem (FLT) inversion +// - Montgomery ladder initilization with base point G or public key PK in +// keygen, signing, or verifying operations. +// - Montgomery ladder steps: including the iterative point addition (PA) +// and point doubling (PD) operations in Montgomery domain using projective +// coordinates. The number of iteration is equal to REG_SIZE of scalar in +// unprotected point multiplication, and REG_SIZE+RND_SIZE of scalar in the +// SCA protected operation. +// - Modular Inversion (mod p, mod q) is based on Fermat's little theorem (FLT) +// inversion. +// - Conversion from projective coordinates in Montgomery domain (X,Y,Z) to +// affine coordinates in the normal domain (x,y). +// - Modular arithmetic operations such as (h + r*privKey) in signing +// or (h*s_inv) and (r*s_inv) in verifying +// +// +//====================================================================== + +module ecc_pm_ctrl + import ecc_pm_uop_pkg::*; + #( + parameter REG_SIZE = 384, + parameter RND_SIZE = 192, + parameter INSTR_SIZE = 24 + ) + ( + // Clock and reset. + input wire clk, + input wire reset_n, + input wire zeroize, + + // from arith_unit + input wire [3 : 0] ecc_cmd_i, + input wire digit_i, + output pm_instr_struct_t instr_o, + output logic req_digit_o, + output wire busy_o +); + + + //---------------------------------------------------------------- + // Internal constant and parameter definitions. + //---------------------------------------------------------------- + localparam [7 : 0] MULT_DELAY = 8'd27; //28 -1; + localparam [7 : 0] ADD_DELAY = 8'd1; // 2 -1; + + localparam [9 : 0] Secp384_SCA_MONT_COUNT = REG_SIZE[9 : 0] + RND_SIZE[9 : 0]; + localparam [9 : 0] Secp384_MONT_COUNT = REG_SIZE[9 : 0]; + + //---------------------------------------------------------------- + // Registers + //---------------------------------------------------------------- + + logic [PROG_ADDR_W-1 : 0] prog_cntr; + logic [9 : 0] mont_cntr; + logic [7 : 0] stall_cntr; + + // Program pipeline signals + logic [PROG_ADDR_W-1 : 0] prog_addr; + pm_instr_struct_t prog_instr; + pm_instr_struct_t prog_instr_pipe1; + pm_instr_struct_t prog_instr_pipe2; + + logic [3 : 0] ecc_cmd_reg; + + logic stalled, stalled_pipe1; + logic stall_flag; + logic mont_ladder; + //---------------------------------------------------------------- + // pm sequencer fsm + //---------------------------------------------------------------- + assign prog_addr = prog_cntr; + + ecc_pm_sequencer #( + .ADDR_WIDTH(PROG_ADDR_W), + .DATA_WIDTH(INSTRUCTION_LENGTH) + ) + i_ecc_pm_sequencer( + .clka(clk), + .reset_n(reset_n), + .zeroize(zeroize), + .ena(1'b1), + .addra(prog_addr), + .douta(prog_instr) + ); + + always_ff @(posedge clk or negedge reset_n) + begin : ff_stalled_reg + if(!reset_n) + stalled_pipe1 <= '0; + else if (zeroize) + stalled_pipe1 <= '0; + else + stalled_pipe1 <= stalled; + end // ff_stalled_reg + + //---------------------------------------------------------------- + // Point_multiplication_FSM_flow + // + // This FSM starts with the keyfen/signing/verifying command to + // perform different operations. + // Active low and async reset. + //---------------------------------------------------------------- + always_ff @(posedge clk or negedge reset_n) + begin : pm_fsm + if(!reset_n) begin + prog_cntr <= '0; + mont_cntr <= '0; + stall_cntr <= '0; + stalled <= '0; + req_digit_o <= '0; + mont_ladder <= '0; + ecc_cmd_reg <= '0; + end + else if (zeroize) begin + prog_cntr <= '0; + mont_cntr <= '0; + stall_cntr <= '0; + stalled <= '0; + req_digit_o <= '0; + mont_ladder <= '0; + ecc_cmd_reg <= '0; + end + else begin + if (stalled & (stall_cntr > 0)) begin + stall_cntr <= stall_cntr - 1; + end + else if (stall_flag & (!stalled) & (!stalled_pipe1)) begin + unique case (prog_instr.opcode) + UOP_DO_ADD_p : begin stalled <= 1'b1; stall_cntr <= ADD_DELAY; end // ADD + UOP_DO_SUB_p : begin stalled <= 1'b1; stall_cntr <= ADD_DELAY; end // SUB + UOP_DO_MUL_p : begin stalled <= 1'b1; stall_cntr <= MULT_DELAY; end // MULT + UOP_DO_ADD_q : begin stalled <= 1'b1; stall_cntr <= ADD_DELAY; end // ADD + UOP_DO_SUB_q : begin stalled <= 1'b1; stall_cntr <= ADD_DELAY; end // SUB + UOP_DO_MUL_q : begin stalled <= 1'b1; stall_cntr <= MULT_DELAY; end // MULT + default : begin stalled <= 1'b0; stall_cntr <= '0; end + endcase + end + else begin + stalled <= 0; + unique case (prog_cntr) + NOP : begin // Waiting for new valid command + ecc_cmd_reg <= ecc_cmd_i; + unique case (ecc_cmd_i) + KEYGEN_CMD : begin // keygen + mont_cntr <= Secp384_SCA_MONT_COUNT; + prog_cntr <= PM_INIT_G_S; + end + + SIGN_CMD : begin // signing + mont_cntr <= Secp384_SCA_MONT_COUNT; + prog_cntr <= PM_INIT_G_S; + end + + VER_PART0_CMD : begin // verifying part0 + prog_cntr <= VER0_P0_S; + end + + VER_PART1_CMD : begin // verifying part1 + mont_cntr <= Secp384_MONT_COUNT; + prog_cntr <= PM_INIT_G_S; + end + + VER_PART2_CMD : begin // verifying part2 + prog_cntr <= VER1_ST_S; + end + + CHK_PK_CMD : begin + prog_cntr <= CHK_PK_S; + end + + DH_SHARED_CMD : begin // DH shared key + mont_cntr <= Secp384_SCA_MONT_COUNT; + prog_cntr <= PM_INIT_DH_S; + end + + default : + prog_cntr <= NOP; + endcase + req_digit_o <= 0; + end + + VER1_ST_E : begin // Storing the VER1 MONT results before starting VER2 + mont_cntr <= Secp384_MONT_COUNT; + prog_cntr <= PM_INIT_PK_S; + end + + // Montgoemry Ladder + PM_INIT_G_E : begin //End of initilize R0 = Randomized G + prog_cntr <= PM_INIT_S; + end + + PM_INIT_PK_E : begin //End of initilize R0 = PK + prog_cntr <= PM_INIT_S; + end + + PM_INIT_DH_E : begin //End of initilize R0 = Randomized PK + prog_cntr <= PM_INIT_S; + end + + PM_INIT_E : begin // End of initilaze R1 = 0 + mont_cntr <= mont_cntr - 1; + req_digit_o <= 1; + prog_cntr <= PA_S; + mont_ladder <= 1; + end + + PA_S : begin //Start of point addtion + req_digit_o <= 0; + prog_cntr <= prog_cntr + 1; + end + + PA_E : begin //End of point addtion + prog_cntr <= PD_S; + end + + PD_E : begin //End of point doubling + if (mont_cntr == 0) begin // Montgomery ladder is done + unique case (ecc_cmd_reg) + VER_PART1_CMD : prog_cntr <= NOP; + VER_PART2_CMD : prog_cntr <= VER2_PA_S; + default : prog_cntr <= INV_S; + endcase + mont_ladder <= 0; + req_digit_o <= 0; + end + else begin + mont_cntr <= mont_cntr - 1; + req_digit_o <= 1; + prog_cntr <= PA_S; + end + end + + INV_E : begin // End of inversion mod p + prog_cntr <= CONV_S; + end + + CONV_E : begin // End of conversion from projective Mont (X,Y,Z) to affine normanl (x,y) + unique case (ecc_cmd_reg) + SIGN_CMD : prog_cntr <= SIGN0_S; + default : prog_cntr <= NOP; + endcase + end + + SIGN0_E : begin // End of signing part 0 to to convert inputs to Mont domain & compute (h + r*privKey) + prog_cntr <= INVq_S; + end + + INVq_E : begin // End of inversion mod q + unique case (ecc_cmd_reg) + SIGN_CMD : prog_cntr <= SIGN1_S; + VER_PART0_CMD : prog_cntr <= VER0_P1_S; + default : prog_cntr <= NOP; + endcase + end + + SIGN1_E : begin // End of signing part 1 to compute s + prog_cntr <= NOP; + end + + CHK_PK_E: begin // End of public key validation before verifying process + prog_cntr <= NOP; + end + + VER0_P0_E : begin // End of verfying part 0 to convert inputs to Mont domain + prog_cntr <= INVq_S; + end + + VER0_P1_E : begin // End of verfying part 1 to compute (h*s_inv) and (r*s_inv) + prog_cntr <= NOP; + end + + VER2_PA_E : begin // End of point addition of PA((h*s_inv)*G, (r*s_inv)*PK) + prog_cntr <= INV_S; + end + + PM_INIT_G_S, + PM_INIT_PK_S, + PM_INIT_S, + PD_S, + INV_S, + INVq_S, + CONV_S, + SIGN0_S, + SIGN1_S, + VER0_P0_S, + VER0_P1_S, + VER1_ST_S, + VER2_PA_S, + PM_INIT_DH_S: begin + prog_cntr <= prog_cntr + 1; + end + + default : begin + prog_cntr <= prog_cntr + 1; + end + endcase + end + end + end // pm_fsm + + always_ff @(posedge clk or negedge reset_n) + begin : sequencer_pipeline1 + if (!reset_n) + prog_instr_pipe1 <= '{UOP_NOP, '0, '0}; + else if (zeroize) + prog_instr_pipe1 <= '{UOP_NOP, '0, '0}; + else begin + if (stalled_pipe1) + prog_instr_pipe1 <= prog_instr_pipe1; + else + prog_instr_pipe1 <= prog_instr; + end + end // sequencer_pipeline1 + + always_ff @(posedge clk or negedge reset_n) + begin : sequencer_pipeline2 + if (!reset_n) + prog_instr_pipe2 <= '{UOP_NOP, '0, '0}; + else if (zeroize) + prog_instr_pipe2 <= '{UOP_NOP, '0, '0}; + else begin + if (stalled_pipe1) + prog_instr_pipe2 <= prog_instr_pipe2; + else + prog_instr_pipe2 <= prog_instr_pipe1; + end + end // sequencer_pipeline2 + + /* + always_comb + begin : delay_flag + unique case (prog_instr.opcode) + UOP_DO_ADD_p : stall_flag = 1; + UOP_DO_SUB_p : stall_flag = 1; + UOP_DO_MUL_p : stall_flag = 1; + UOP_DO_ADD_q : stall_flag = 1; + UOP_DO_SUB_q : stall_flag = 1; + UOP_DO_MUL_q : stall_flag = 1; + default : stall_flag = 0; + endcase + end // delay_flag + */ + + always_comb stall_flag = (prog_instr.opcode.add_en || prog_instr.opcode.mult_en); + + + //Instruction out to arithmetic units and memory + always_ff @(posedge clk or negedge reset_n) + begin : instruction_out + if (!reset_n) + instr_o <= '{UOP_NOP, '0, '0}; + else if (zeroize) + instr_o <= '{UOP_NOP, '0, '0}; + else begin + instr_o.opcode <= prog_instr_pipe2.opcode; + + if (mont_ladder) begin + // constant-time conditional swaps depending on the value of the currently processed bit of secret key + + //Addr A for ADD/SUB result + if (prog_instr_pipe2.opa_addr[3 +: OPR_ADDR_WIDTH-3] == 3'b001) + instr_o.opa_addr <= {prog_instr_pipe2.opa_addr[3 +: OPR_ADDR_WIDTH-3], digit_i ^ prog_instr_pipe2.opa_addr[2], prog_instr_pipe2.opa_addr[1 : 0]}; + else + instr_o.opa_addr <= prog_instr_pipe2.opa_addr; + //Addr B for MULT result + if (prog_instr_pipe2.opb_addr[3 +: OPR_ADDR_WIDTH-3] == 3'b001) + instr_o.opb_addr <= {prog_instr_pipe2.opb_addr[3 +: OPR_ADDR_WIDTH-3], digit_i ^ prog_instr_pipe2.opb_addr[2], prog_instr_pipe2.opb_addr[1 : 0]}; + else + instr_o.opb_addr <= prog_instr_pipe2.opb_addr; + end + else begin + instr_o.opa_addr <= prog_instr_pipe2.opa_addr; //Addr A for ADD/SUB result + instr_o.opb_addr <= prog_instr_pipe2.opb_addr; //Addr B for MULT result + end + end + end // instruction_out + + assign busy_o = ~(prog_cntr == NOP); + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/ecc_pm_sequencer.sv b/designs/Caliptra/src/caliptra-rtl/ecc_pm_sequencer.sv new file mode 100644 index 0000000..c897376 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/ecc_pm_sequencer.sv @@ -0,0 +1,2569 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +// +//====================================================================== +// +// ecc_pm_sequencer.sv +// -------- +// ECC point multiplication sequencer for the Secp384. +// 1) Point Addition (PA) and Point Doubling (PD) are based on +// "Complete Addition Formulas for Prime Order Elliptic Curves" +// by Renes et. al. (Algorithm 1) +// 2) Modular Inversion (mod p, mod q) is based on "Fermat's little +// theorem (FLT)" implemented by exponentiation by squaring methos +// with window size of 3 bits. +// 3) All modular operations are performed in Montgomery domain. +// mod p are modular operation respect to PRIME of SECP384 curve. +// mod q are modular operation respect to GROUP ORDER of SECP384 curve. +// 4) To validate the given public key, we compare YY = Y^2 with +// RHS = X^3 + A X + B. +// +//====================================================================== + +module ecc_pm_sequencer + import ecc_pm_uop_pkg::*; + #( + parameter ADDR_WIDTH = 10, + parameter DATA_WIDTH = 32 + ) + ( + input wire clka, + input wire reset_n, + input wire zeroize, + input wire ena, + input wire [ADDR_WIDTH-1 : 0] addra, + output logic [DATA_WIDTH-1 : 0] douta + ); + + //---------------------------------------------------------------- + // ROM content + //---------------------------------------------------------------- + + always_ff @(posedge clka or negedge reset_n) + begin : prog_rom + if (!reset_n) begin + douta <= '0; + end + else if (zeroize) begin + douta <= '0; + end + else begin + if (ena) begin + unique case(addra) + NOP : douta <= '0; + 1 : douta <= '0; + + //R1 INIT with Randomized G + PM_INIT_G_S : douta <= {UOP_DO_MUL_p, UOP_OPR_LAMBDA, UOP_OPR_CONST_R2_p}; // R1_Z = mm(Lambda, R2) + PM_INIT_G_S+ 1 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_R1_Z}; + PM_INIT_G_S+ 2 : douta <= {UOP_DO_MUL_p, UOP_OPR_CONST_GX_MONT, UOP_OPR_R1_Z}; // R1_X = mm(GX_MONT, R0_Z) + PM_INIT_G_S+ 3 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_R1_X}; + PM_INIT_G_S+ 4 : douta <= {UOP_DO_MUL_p, UOP_OPR_CONST_GY_MONT, UOP_OPR_R1_Z}; // R1_Y = mm(GY_MONT, R0_Z) + PM_INIT_G_S+ 5 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_R1_Y}; + + //R0 INIT with O + PM_INIT_S : douta <= {UOP_DO_ADD_p, UOP_OPR_CONST_ZERO, UOP_OPR_CONST_ZERO}; // R0_X = 0 + PM_INIT_S+ 1 : douta <= {UOP_ST_ADD_p, UOP_OPR_R0_X, UOP_OPR_DONTCARE}; + PM_INIT_S+ 2 : douta <= {UOP_DO_ADD_p, UOP_OPR_CONST_ONE_MONT, UOP_OPR_CONST_ZERO}; // R0_Y = fp_mult(1, R2, p) + PM_INIT_S+ 3 : douta <= {UOP_ST_ADD_p, UOP_OPR_R0_Y, UOP_OPR_DONTCARE}; + PM_INIT_S+ 4 : douta <= {UOP_DO_ADD_p, UOP_OPR_CONST_ZERO, UOP_OPR_CONST_ZERO}; // R0_Z = 0 + PM_INIT_S+ 5 : douta <= {UOP_ST_ADD_p, UOP_OPR_R0_Z, UOP_OPR_DONTCARE}; + PM_INIT_S+ 6 : douta <= {UOP_NOP, UOP_OPR_DONTCARE, UOP_OPR_DONTCARE}; + PM_INIT_S+ 7 : douta <= {UOP_NOP, UOP_OPR_DONTCARE, UOP_OPR_DONTCARE}; + PM_INIT_S+ 8 : douta <= {UOP_NOP, UOP_OPR_DONTCARE, UOP_OPR_DONTCARE}; + PM_INIT_S+ 9 : douta <= {UOP_NOP, UOP_OPR_DONTCARE, UOP_OPR_DONTCARE}; + + // PA : R1 = PA(R0, R1) + PA_S : douta <= {UOP_DO_MUL_p, UOP_OPR_R0_X, UOP_OPR_R1_X}; // A = fp_mult(P0.X, P1.X, p) + PA_S+ 1 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A}; + PA_S+ 2 : douta <= {UOP_DO_MUL_p, UOP_OPR_R0_Y, UOP_OPR_R1_Y}; // B = fp_mult(P0.Y, P1.Y, p) + PA_S+ 3 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_B}; + PA_S+ 4 : douta <= {UOP_DO_MUL_p, UOP_OPR_R0_Z, UOP_OPR_R1_Z}; // C = fp_mult(P0.Z, P1.Z, p) + PA_S+ 5 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_C}; + PA_S+ 6 : douta <= {UOP_DO_ADD_p, UOP_OPR_R0_X, UOP_OPR_R0_Y}; // D = (P0.X + P0.Y) % p + PA_S+ 7 : douta <= {UOP_ST_ADD_p, UOP_OPR_D, UOP_OPR_DONTCARE}; + PA_S+ 8 : douta <= {UOP_DO_ADD_p, UOP_OPR_R1_X, UOP_OPR_R1_Y}; // E = (P1.X + P1.Y) % p + PA_S+ 9 : douta <= {UOP_ST_ADD_p, UOP_OPR_E, UOP_OPR_DONTCARE}; + PA_S+ 10 : douta <= {UOP_DO_MUL_p, UOP_OPR_D, UOP_OPR_E}; // D = fp_mult(D, E, p) + PA_S+ 11 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_D}; + PA_S+ 12 : douta <= {UOP_DO_ADD_p, UOP_OPR_A, UOP_OPR_B}; // E = (A + B) % p + PA_S+ 13 : douta <= {UOP_ST_ADD_p, UOP_OPR_E, UOP_OPR_DONTCARE}; + PA_S+ 14 : douta <= {UOP_DO_SUB_p, UOP_OPR_D, UOP_OPR_E}; // D = (D - E) % p + PA_S+ 15 : douta <= {UOP_ST_ADD_p, UOP_OPR_D, UOP_OPR_DONTCARE}; + PA_S+ 16 : douta <= {UOP_DO_ADD_p, UOP_OPR_R0_X, UOP_OPR_R0_Z}; // E = (P0.X + P0.Z) % p + PA_S+ 17 : douta <= {UOP_ST_ADD_p, UOP_OPR_E, UOP_OPR_DONTCARE}; + PA_S+ 18 : douta <= {UOP_DO_ADD_p, UOP_OPR_R1_X, UOP_OPR_R1_Z}; // F = (P1.X + P1.Z) % p + PA_S+ 19 : douta <= {UOP_ST_ADD_p, UOP_OPR_F, UOP_OPR_DONTCARE}; + PA_S+ 20 : douta <= {UOP_DO_MUL_p, UOP_OPR_E, UOP_OPR_F}; // E = fp_mult(E, F, p) + PA_S+ 21 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_E}; + PA_S+ 22 : douta <= {UOP_DO_ADD_p, UOP_OPR_A, UOP_OPR_C}; // F = (A + C) % p + PA_S+ 23 : douta <= {UOP_ST_ADD_p, UOP_OPR_F, UOP_OPR_DONTCARE}; + PA_S+ 24 : douta <= {UOP_DO_SUB_p, UOP_OPR_E, UOP_OPR_F}; // E = (E - F) % p + PA_S+ 25 : douta <= {UOP_ST_ADD_p, UOP_OPR_E, UOP_OPR_DONTCARE}; + PA_S+ 26 : douta <= {UOP_DO_ADD_p, UOP_OPR_R0_Y, UOP_OPR_R0_Z}; // F = (P0.Y + P0.Z) % p + PA_S+ 27 : douta <= {UOP_ST_ADD_p, UOP_OPR_F, UOP_OPR_DONTCARE}; + PA_S+ 28 : douta <= {UOP_DO_ADD_p, UOP_OPR_R1_Y, UOP_OPR_R1_Z}; // X3 = (P1.Y + P1.Z) % p + PA_S+ 29 : douta <= {UOP_ST_ADD_p, UOP_OPR_R1_X, UOP_OPR_DONTCARE}; + PA_S+ 30 : douta <= {UOP_DO_MUL_p, UOP_OPR_F, UOP_OPR_R1_X}; // F = fp_mult(F, X3, p) + PA_S+ 31 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_F}; + PA_S+ 32 : douta <= {UOP_DO_ADD_p, UOP_OPR_B, UOP_OPR_C}; // X3 = (B + C) % p + PA_S+ 33 : douta <= {UOP_ST_ADD_p, UOP_OPR_R1_X, UOP_OPR_DONTCARE}; + PA_S+ 34 : douta <= {UOP_DO_SUB_p, UOP_OPR_F, UOP_OPR_R1_X}; // F = (F - X3) % p + PA_S+ 35 : douta <= {UOP_ST_ADD_p, UOP_OPR_F, UOP_OPR_DONTCARE}; + PA_S+ 36 : douta <= {UOP_DO_MUL_p, UOP_OPR_CONST_E_a, UOP_OPR_E}; // Z3 = fp_mult(ECC.a, E, p) + PA_S+ 37 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_R1_Z}; + PA_S+ 38 : douta <= {UOP_DO_MUL_p, UOP_OPR_CONST_E_3b, UOP_OPR_C}; // X3 = fp_mult(ECC.3b, C, p) + PA_S+ 39 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_R1_X}; + PA_S+ 40 : douta <= {UOP_DO_ADD_p, UOP_OPR_R1_X, UOP_OPR_R1_Z}; // Z3 = (X3 + Z3) % p + PA_S+ 41 : douta <= {UOP_ST_ADD_p, UOP_OPR_R1_Z, UOP_OPR_DONTCARE}; + PA_S+ 42 : douta <= {UOP_DO_SUB_p, UOP_OPR_B, UOP_OPR_R1_Z}; // X3 = (B - Z3) % p + PA_S+ 43 : douta <= {UOP_ST_ADD_p, UOP_OPR_R1_X, UOP_OPR_DONTCARE}; + PA_S+ 44 : douta <= {UOP_DO_ADD_p, UOP_OPR_B, UOP_OPR_R1_Z}; // Z3 = (B + Z3) % p + PA_S+ 45 : douta <= {UOP_ST_ADD_p, UOP_OPR_R1_Z, UOP_OPR_DONTCARE}; + PA_S+ 46 : douta <= {UOP_DO_MUL_p, UOP_OPR_R1_X, UOP_OPR_R1_Z}; // Y3 = fp_mult(X3, Z3, p) + PA_S+ 47 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_R1_Y}; + PA_S+ 48 : douta <= {UOP_DO_ADD_p, UOP_OPR_A, UOP_OPR_A}; // B = (A + A) % p + PA_S+ 49 : douta <= {UOP_ST_ADD_p, UOP_OPR_B, UOP_OPR_DONTCARE}; + PA_S+ 50 : douta <= {UOP_DO_ADD_p, UOP_OPR_B, UOP_OPR_A}; // B = (B + A) % p + PA_S+ 51 : douta <= {UOP_ST_ADD_p, UOP_OPR_B, UOP_OPR_DONTCARE}; + PA_S+ 52 : douta <= {UOP_DO_MUL_p, UOP_OPR_CONST_E_a, UOP_OPR_C}; // C = fp_mult(ECC.a, C, p) + PA_S+ 53 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_C}; + PA_S+ 54 : douta <= {UOP_DO_MUL_p, UOP_OPR_CONST_E_3b, UOP_OPR_E}; // E = fp_mult(ECC.3b, E, p) + PA_S+ 55 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_E}; + PA_S+ 56 : douta <= {UOP_DO_ADD_p, UOP_OPR_B, UOP_OPR_C}; // B = (B + C) % p + PA_S+ 57 : douta <= {UOP_ST_ADD_p, UOP_OPR_B, UOP_OPR_DONTCARE}; + PA_S+ 58 : douta <= {UOP_DO_SUB_p, UOP_OPR_A, UOP_OPR_C}; // C = (A - C) % p + PA_S+ 59 : douta <= {UOP_ST_ADD_p, UOP_OPR_C, UOP_OPR_DONTCARE}; + PA_S+ 60 : douta <= {UOP_DO_MUL_p, UOP_OPR_CONST_E_a, UOP_OPR_C}; // C = fp_mult(ECC.a, C, p) + PA_S+ 61 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_C}; + PA_S+ 62 : douta <= {UOP_DO_ADD_p, UOP_OPR_E, UOP_OPR_C}; // E = (E + C) % p + PA_S+ 63 : douta <= {UOP_ST_ADD_p, UOP_OPR_E, UOP_OPR_DONTCARE}; + PA_S+ 64 : douta <= {UOP_DO_MUL_p, UOP_OPR_B, UOP_OPR_E}; // A = fp_mult(B, E, p) + PA_S+ 65 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A}; + PA_S+ 66 : douta <= {UOP_DO_ADD_p, UOP_OPR_R1_Y, UOP_OPR_A}; // Y3 = (Y3 + A) % p + PA_S+ 67 : douta <= {UOP_ST_ADD_p, UOP_OPR_R1_Y, UOP_OPR_DONTCARE}; + PA_S+ 68 : douta <= {UOP_DO_MUL_p, UOP_OPR_F, UOP_OPR_E}; // A = fp_mult(F, E, p) + PA_S+ 69 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A}; + PA_S+ 70 : douta <= {UOP_DO_MUL_p, UOP_OPR_D, UOP_OPR_R1_X}; // X3 = fp_mult(D, X3, p) + PA_S+ 71 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_R1_X}; + PA_S+ 72 : douta <= {UOP_DO_SUB_p, UOP_OPR_R1_X, UOP_OPR_A}; // X3 = (X3 - A) % p + PA_S+ 73 : douta <= {UOP_ST_ADD_p, UOP_OPR_R1_X, UOP_OPR_DONTCARE}; + PA_S+ 74 : douta <= {UOP_DO_MUL_p, UOP_OPR_D, UOP_OPR_B}; // A = fp_mult(D, B, p) + PA_S+ 75 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A}; + PA_S+ 76 : douta <= {UOP_DO_MUL_p, UOP_OPR_F, UOP_OPR_R1_Z}; // Z3 = fp_mult(F, Z3, p) + PA_S+ 77 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_R1_Z}; + PA_S+ 78 : douta <= {UOP_DO_ADD_p, UOP_OPR_R1_Z, UOP_OPR_A}; // Z3 = (Z3 + A) % p + PA_S+ 79 : douta <= {UOP_ST_ADD_p, UOP_OPR_R1_Z, UOP_OPR_DONTCARE}; + + //PD : R0 = PD(R0) + PD_S : douta <= {UOP_DO_MUL_p, UOP_OPR_R0_X, UOP_OPR_R0_X}; // A = fp_mult(P0.X, P0.X, p) + PD_S+ 1 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A}; + PD_S+ 2 : douta <= {UOP_DO_MUL_p, UOP_OPR_R0_Y, UOP_OPR_R0_Y}; // B = fp_mult(P0.Y, P0.Y, p) + PD_S+ 3 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_B}; + PD_S+ 4 : douta <= {UOP_DO_MUL_p, UOP_OPR_R0_Z, UOP_OPR_R0_Z}; // C = fp_mult(P0.Z, P0.Z, p) + PD_S+ 5 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_C}; + PD_S+ 6 : douta <= {UOP_DO_ADD_p, UOP_OPR_R0_X, UOP_OPR_R0_Y}; // D = (P0.X + P0.Y) % p + PD_S+ 7 : douta <= {UOP_ST_ADD_p, UOP_OPR_D, UOP_OPR_DONTCARE}; + PD_S+ 8 : douta <= {UOP_DO_ADD_p, UOP_OPR_R0_X, UOP_OPR_R0_Y}; // E = (P0.X + P0.Y) % p + PD_S+ 9 : douta <= {UOP_ST_ADD_p, UOP_OPR_E, UOP_OPR_DONTCARE}; + PD_S+ 10 : douta <= {UOP_DO_MUL_p, UOP_OPR_D, UOP_OPR_E}; // D = fp_mult(D, E, p) + PD_S+ 11 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_D}; + PD_S+ 12 : douta <= {UOP_DO_ADD_p, UOP_OPR_A, UOP_OPR_B}; // E = (A + B) % p + PD_S+ 13 : douta <= {UOP_ST_ADD_p, UOP_OPR_E, UOP_OPR_DONTCARE}; + PD_S+ 14 : douta <= {UOP_DO_SUB_p, UOP_OPR_D, UOP_OPR_E}; // D = (D - E) % p + PD_S+ 15 : douta <= {UOP_ST_ADD_p, UOP_OPR_D, UOP_OPR_DONTCARE}; + PD_S+ 16 : douta <= {UOP_DO_ADD_p, UOP_OPR_R0_X, UOP_OPR_R0_Z}; // E = (P0.X + P0.Z) % p + PD_S+ 17 : douta <= {UOP_ST_ADD_p, UOP_OPR_E, UOP_OPR_DONTCARE}; + PD_S+ 18 : douta <= {UOP_DO_ADD_p, UOP_OPR_R0_X, UOP_OPR_R0_Z}; // F = (P0.X + P0.Z) % p + PD_S+ 19 : douta <= {UOP_ST_ADD_p, UOP_OPR_F, UOP_OPR_DONTCARE}; + PD_S+ 20 : douta <= {UOP_DO_MUL_p, UOP_OPR_E, UOP_OPR_F}; // E = fp_mult(E, F, p) + PD_S+ 21 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_E}; + PD_S+ 22 : douta <= {UOP_DO_ADD_p, UOP_OPR_A, UOP_OPR_C}; // F = (A + C) % p + PD_S+ 23 : douta <= {UOP_ST_ADD_p, UOP_OPR_F, UOP_OPR_DONTCARE}; + PD_S+ 24 : douta <= {UOP_DO_SUB_p, UOP_OPR_E, UOP_OPR_F}; // E = (E - F) % p + PD_S+ 25 : douta <= {UOP_ST_ADD_p, UOP_OPR_E, UOP_OPR_DONTCARE}; + PD_S+ 26 : douta <= {UOP_DO_ADD_p, UOP_OPR_R0_Y, UOP_OPR_R0_Z}; // F = (P0.Y + P0.Z) % p + PD_S+ 27 : douta <= {UOP_ST_ADD_p, UOP_OPR_F, UOP_OPR_DONTCARE}; + PD_S+ 28 : douta <= {UOP_DO_ADD_p, UOP_OPR_R0_Y, UOP_OPR_R0_Z}; // X3 = (P0.Y + P0.Z) % p + PD_S+ 29 : douta <= {UOP_ST_ADD_p, UOP_OPR_R0_X, UOP_OPR_DONTCARE}; + PD_S+ 30 : douta <= {UOP_DO_MUL_p, UOP_OPR_F, UOP_OPR_R0_X}; // F = fp_mult(F, X3, p) + PD_S+ 31 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_F}; + PD_S+ 32 : douta <= {UOP_DO_ADD_p, UOP_OPR_B, UOP_OPR_C}; // X3 = (B + C) % p + PD_S+ 33 : douta <= {UOP_ST_ADD_p, UOP_OPR_R0_X, UOP_OPR_DONTCARE}; + PD_S+ 34 : douta <= {UOP_DO_SUB_p, UOP_OPR_F, UOP_OPR_R0_X}; // F = (F - X3) % p + PD_S+ 35 : douta <= {UOP_ST_ADD_p, UOP_OPR_F, UOP_OPR_DONTCARE}; + PD_S+ 36 : douta <= {UOP_DO_MUL_p, UOP_OPR_CONST_E_a, UOP_OPR_E}; // Z3 = fp_mult(ECC.a, E, p) + PD_S+ 37 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_R0_Z}; + PD_S+ 38 : douta <= {UOP_DO_MUL_p, UOP_OPR_CONST_E_3b, UOP_OPR_C}; // X3 = fp_mult(ECC.3b, C, p) + PD_S+ 39 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_R0_X}; + PD_S+ 40 : douta <= {UOP_DO_ADD_p, UOP_OPR_R0_X, UOP_OPR_R0_Z}; // Z3 = (X3 + Z3) % p + PD_S+ 41 : douta <= {UOP_ST_ADD_p, UOP_OPR_R0_Z, UOP_OPR_DONTCARE}; + PD_S+ 42 : douta <= {UOP_DO_SUB_p, UOP_OPR_B, UOP_OPR_R0_Z}; // X3 = (B - Z3) % p + PD_S+ 43 : douta <= {UOP_ST_ADD_p, UOP_OPR_R0_X, UOP_OPR_DONTCARE}; + PD_S+ 44 : douta <= {UOP_DO_ADD_p, UOP_OPR_B, UOP_OPR_R0_Z}; // Z3 = (B + Z3) % p + PD_S+ 45 : douta <= {UOP_ST_ADD_p, UOP_OPR_R0_Z, UOP_OPR_DONTCARE}; + PD_S+ 46 : douta <= {UOP_DO_MUL_p, UOP_OPR_R0_X, UOP_OPR_R0_Z}; // Y3 = fp_mult(X3, Z3, p) + PD_S+ 47 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_R0_Y}; + PD_S+ 48 : douta <= {UOP_DO_ADD_p, UOP_OPR_A, UOP_OPR_A}; // B = (A + A) % p + PD_S+ 49 : douta <= {UOP_ST_ADD_p, UOP_OPR_B, UOP_OPR_DONTCARE}; + PD_S+ 50 : douta <= {UOP_DO_ADD_p, UOP_OPR_B, UOP_OPR_A}; // B = (B + A) % p + PD_S+ 51 : douta <= {UOP_ST_ADD_p, UOP_OPR_B, UOP_OPR_DONTCARE}; + PD_S+ 52 : douta <= {UOP_DO_MUL_p, UOP_OPR_CONST_E_a, UOP_OPR_C}; // C = fp_mult(ECC.a, C, p) + PD_S+ 53 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_C}; + PD_S+ 54 : douta <= {UOP_DO_MUL_p, UOP_OPR_CONST_E_3b, UOP_OPR_E}; // E = fp_mult(ECC.3b, E, p) + PD_S+ 55 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_E}; + PD_S+ 56 : douta <= {UOP_DO_ADD_p, UOP_OPR_B, UOP_OPR_C}; // B = (B + C) % p + PD_S+ 57 : douta <= {UOP_ST_ADD_p, UOP_OPR_B, UOP_OPR_DONTCARE}; + PD_S+ 58 : douta <= {UOP_DO_SUB_p, UOP_OPR_A, UOP_OPR_C}; // C = (A - C) % p + PD_S+ 59 : douta <= {UOP_ST_ADD_p, UOP_OPR_C, UOP_OPR_DONTCARE}; + PD_S+ 60 : douta <= {UOP_DO_MUL_p, UOP_OPR_CONST_E_a, UOP_OPR_C}; // C = fp_mult(ECC.a, C, p) + PD_S+ 61 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_C}; + PD_S+ 62 : douta <= {UOP_DO_ADD_p, UOP_OPR_E, UOP_OPR_C}; // E = (E + C) % p + PD_S+ 63 : douta <= {UOP_ST_ADD_p, UOP_OPR_E, UOP_OPR_DONTCARE}; + PD_S+ 64 : douta <= {UOP_DO_MUL_p, UOP_OPR_B, UOP_OPR_E}; // A = fp_mult(B, E, p) + PD_S+ 65 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A}; + PD_S+ 66 : douta <= {UOP_DO_ADD_p, UOP_OPR_R0_Y, UOP_OPR_A}; // Y3 = (Y3 + A) % p + PD_S+ 67 : douta <= {UOP_ST_ADD_p, UOP_OPR_R0_Y, UOP_OPR_DONTCARE}; + PD_S+ 68 : douta <= {UOP_DO_MUL_p, UOP_OPR_F, UOP_OPR_E}; // A = fp_mult(F, E, p) + PD_S+ 69 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A}; + PD_S+ 70 : douta <= {UOP_DO_MUL_p, UOP_OPR_D, UOP_OPR_R0_X}; // X3 = fp_mult(D, X3, p) + PD_S+ 71 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_R0_X}; + PD_S+ 72 : douta <= {UOP_DO_SUB_p, UOP_OPR_R0_X, UOP_OPR_A}; // X3 = (X3 - A) % p + PD_S+ 73 : douta <= {UOP_ST_ADD_p, UOP_OPR_R0_X, UOP_OPR_DONTCARE}; + PD_S+ 74 : douta <= {UOP_DO_MUL_p, UOP_OPR_D, UOP_OPR_B}; // A = fp_mult(D, B, p) + PD_S+ 75 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A}; + PD_S+ 76 : douta <= {UOP_DO_MUL_p, UOP_OPR_F, UOP_OPR_R0_Z}; // Z3 = fp_mult(F, Z3, p) + PD_S+ 77 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_R0_Z}; + PD_S+ 78 : douta <= {UOP_DO_ADD_p, UOP_OPR_R0_Z, UOP_OPR_A}; // Z3 = (Z3 + A) % p + PD_S+ 79 : douta <= {UOP_ST_ADD_p, UOP_OPR_R0_Z, UOP_OPR_DONTCARE}; + PD_S+ 80 : douta <= {UOP_NOP, UOP_OPR_DONTCARE, UOP_OPR_DONTCARE}; + PD_S+ 81 : douta <= {UOP_NOP, UOP_OPR_DONTCARE, UOP_OPR_DONTCARE}; + PD_S+ 82 : douta <= {UOP_NOP, UOP_OPR_DONTCARE, UOP_OPR_DONTCARE}; + PD_S+ 83 : douta <= {UOP_NOP, UOP_OPR_DONTCARE, UOP_OPR_DONTCARE}; + + //INV mod p + INV_S : douta <= {UOP_DO_ADD_p, UOP_OPR_CONST_ZERO, UOP_OPR_CONST_ONE_MONT}; // precompute[0] = UOP_OPR_CONST_ONE_MONT % p + INV_S+ 1 : douta <= {UOP_ST_ADD_p, UOP_OPR_INV_PRE0, UOP_OPR_DONTCARE}; + INV_S+ 2 : douta <= {UOP_DO_MUL_p, UOP_OPR_INV_IN, UOP_OPR_INV_PRE0}; // precompute[1] = fp_mult(Z, precompute[0], p) + INV_S+ 3 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_INV_PRE1}; + INV_S+ 4 : douta <= {UOP_DO_MUL_p, UOP_OPR_INV_IN, UOP_OPR_INV_PRE1}; // precompute[2] = fp_mult(Z, precompute[1], p) + INV_S+ 5 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_INV_PRE2}; + INV_S+ 6 : douta <= {UOP_DO_MUL_p, UOP_OPR_INV_IN, UOP_OPR_INV_PRE2}; // precompute[3] = fp_mult(Z, precompute[2], p) + INV_S+ 7 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_INV_PRE3}; + INV_S+ 8 : douta <= {UOP_DO_MUL_p, UOP_OPR_INV_IN, UOP_OPR_INV_PRE3}; // precompute[4] = fp_mult(Z, precompute[3], p) + INV_S+ 9 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_INV_PRE4}; + INV_S+ 10 : douta <= {UOP_DO_MUL_p, UOP_OPR_INV_IN, UOP_OPR_INV_PRE4}; // precompute[5] = fp_mult(Z, precompute[4], p) + INV_S+ 11 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_INV_PRE5}; + INV_S+ 12 : douta <= {UOP_DO_MUL_p, UOP_OPR_INV_IN, UOP_OPR_INV_PRE5}; // precompute[6] = fp_mult(Z, precompute[5], p) + INV_S+ 13 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_INV_PRE6}; + INV_S+ 14 : douta <= {UOP_DO_MUL_p, UOP_OPR_INV_IN, UOP_OPR_INV_PRE6}; // precompute[7] = fp_mult(Z, precompute[6], p) + INV_S+ 15 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_INV_PRE7}; + INV_S+ 16 : douta <= {UOP_DO_MUL_p, UOP_OPR_INV_PRE0, UOP_OPR_INV_PRE0}; // a_inv = fp_mult(precompute[0], precompute[0], p) + INV_S+ 17 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 18 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 19 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 20 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 21 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 22 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 23 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 24 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 25 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 26 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 27 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 28 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 29 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 30 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 31 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 32 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 33 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 34 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 35 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 36 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 37 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 38 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 39 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 40 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 41 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 42 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 43 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 44 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 45 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 46 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 47 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 48 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 49 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 50 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 51 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 52 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 53 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 54 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 55 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 56 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 57 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 58 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 59 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 60 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 61 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 62 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 63 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 64 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 65 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 66 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 67 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 68 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 69 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 70 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 71 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 72 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 73 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 74 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 75 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 76 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 77 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 78 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 79 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 80 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 81 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 82 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 83 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 84 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 85 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 86 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 87 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 88 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 89 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 90 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 91 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 92 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 93 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 94 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 95 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 96 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 97 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 98 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 99 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 100 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 101 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 102 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 103 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 104 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 105 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 106 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 107 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 108 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 109 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 110 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 111 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 112 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 113 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 114 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 115 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 116 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 117 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 118 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 119 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 120 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 121 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 122 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 123 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 124 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 125 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 126 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 127 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 128 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 129 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 130 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 131 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 132 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 133 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 134 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 135 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 136 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 137 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 138 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 139 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 140 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 141 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 142 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 143 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 144 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 145 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 146 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 147 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 148 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 149 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 150 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 151 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 152 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 153 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 154 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 155 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 156 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 157 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 158 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 159 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 160 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 161 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 162 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 163 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 164 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 165 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 166 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 167 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 168 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 169 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 170 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 171 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 172 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 173 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 174 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 175 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 176 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 177 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 178 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 179 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 180 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 181 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 182 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 183 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 184 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 185 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 186 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 187 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 188 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 189 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 190 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 191 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 192 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 193 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 194 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 195 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 196 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 197 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 198 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 199 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 200 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 201 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 202 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 203 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 204 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 205 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 206 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 207 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 208 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 209 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 210 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 211 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 212 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 213 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 214 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 215 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 216 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 217 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 218 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 219 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 220 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 221 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 222 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 223 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 224 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 225 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 226 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 227 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 228 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 229 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 230 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 231 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 232 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 233 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 234 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 235 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 236 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 237 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 238 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 239 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 240 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 241 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 242 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 243 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 244 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 245 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 246 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 247 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 248 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 249 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 250 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 251 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 252 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 253 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 254 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 255 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 256 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 257 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 258 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 259 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 260 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 261 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 262 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 263 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 264 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 265 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 266 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 267 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 268 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 269 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 270 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 271 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 272 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 273 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 274 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 275 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 276 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 277 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 278 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 279 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 280 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 281 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 282 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 283 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 284 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 285 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 286 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 287 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 288 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 289 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 290 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 291 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 292 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 293 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 294 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 295 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 296 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 297 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 298 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 299 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 300 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 301 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 302 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 303 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 304 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 305 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 306 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 307 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 308 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 309 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 310 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 311 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 312 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 313 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 314 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 315 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 316 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 317 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 318 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 319 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 320 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 321 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 322 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 323 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 324 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 325 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 326 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 327 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 328 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 329 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 330 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 331 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 332 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 333 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 334 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 335 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 336 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 337 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 338 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 339 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 340 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 341 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 342 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 343 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 344 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 345 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 346 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 347 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 348 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 349 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 350 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 351 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 352 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 353 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 354 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 355 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 356 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 357 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 358 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 359 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 360 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 361 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 362 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 363 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 364 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 365 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 366 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 367 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 368 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 369 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 370 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 371 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 372 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 373 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 374 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 375 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 376 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 377 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 378 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 379 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 380 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 381 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 382 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 383 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 384 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 385 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 386 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 387 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 388 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 389 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 390 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 391 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 392 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 393 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 394 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 395 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 396 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 397 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 398 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 399 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 400 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 401 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 402 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 403 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 404 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 405 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 406 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 407 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 408 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 409 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 410 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 411 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 412 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 413 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 414 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 415 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 416 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 417 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 418 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 419 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 420 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 421 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 422 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 423 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 424 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 425 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 426 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 427 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 428 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 429 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 430 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 431 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 432 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 433 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 434 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 435 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 436 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 437 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 438 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 439 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 440 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 441 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 442 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 443 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 444 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 445 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 446 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 447 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 448 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 449 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 450 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 451 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 452 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 453 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 454 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 455 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 456 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 457 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 458 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 459 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 460 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 461 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 462 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 463 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 464 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 465 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 466 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 467 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 468 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 469 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 470 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 471 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 472 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 473 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 474 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 475 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 476 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 477 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 478 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 479 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 480 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 481 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 482 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 483 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 484 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 485 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 486 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 487 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 488 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 489 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 490 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 491 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 492 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 493 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 494 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 495 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 496 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 497 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 498 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 499 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 500 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 501 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 502 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 503 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 504 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 505 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 506 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 507 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 508 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 509 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 510 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 511 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 512 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 513 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 514 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 515 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 516 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 517 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 518 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 519 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 520 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 521 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 522 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 523 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 524 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 525 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 526 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 527 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 528 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 529 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 530 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 531 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 532 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 533 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 534 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 535 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 536 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 537 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 538 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 539 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 540 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 541 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 542 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 543 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 544 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 545 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 546 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 547 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 548 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 549 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 550 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 551 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 552 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 553 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 554 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 555 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 556 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 557 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 558 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 559 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 560 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 561 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 562 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 563 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 564 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 565 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 566 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 567 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 568 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 569 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 570 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 571 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 572 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 573 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 574 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 575 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 576 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 577 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 578 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 579 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 580 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 581 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 582 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 583 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 584 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 585 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 586 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 587 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 588 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 589 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 590 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 591 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 592 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 593 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 594 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 595 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 596 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 597 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 598 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 599 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 600 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 601 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 602 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 603 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 604 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 605 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 606 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 607 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 608 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 609 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 610 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 611 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 612 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 613 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 614 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 615 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 616 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 617 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 618 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 619 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 620 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 621 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 622 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 623 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 624 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 625 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 626 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 627 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 628 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 629 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 630 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 631 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 632 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 633 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 634 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 635 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 636 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 637 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 638 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 639 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 640 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 641 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 642 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 643 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 644 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 645 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 646 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 647 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 648 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 649 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 650 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 651 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 652 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 653 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 654 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 655 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 656 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 657 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 658 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 659 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 660 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 661 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 662 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 663 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 664 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 665 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 666 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 667 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 668 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 669 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 670 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 671 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 672 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 673 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 674 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 675 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 676 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 677 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 678 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 679 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 680 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 681 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 682 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 683 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 684 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 685 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 686 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 687 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 688 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 689 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 690 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 691 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 692 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 693 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 694 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 695 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 696 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 697 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 698 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 699 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 700 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 701 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 702 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE3}; // a_inv = fp_mult(a_inv, precompute[3], p) + INV_S+ 703 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 704 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 705 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 706 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 707 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 708 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 709 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 710 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 711 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 712 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 713 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 714 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 715 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 716 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 717 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 718 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 719 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 720 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 721 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 722 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 723 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 724 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 725 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 726 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 727 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 728 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 729 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 730 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 731 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 732 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 733 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 734 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 735 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 736 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 737 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 738 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 739 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 740 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 741 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 742 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 743 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 744 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 745 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 746 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 747 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 748 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 749 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 750 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 751 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 752 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 753 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 754 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 755 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 756 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 757 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 758 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 759 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 760 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 761 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 762 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 763 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 764 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 765 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 766 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 767 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 768 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 769 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 770 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 771 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 772 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 773 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 774 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 775 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 776 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 777 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 778 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 779 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 780 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 781 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 782 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 783 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 784 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 785 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 786 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 787 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 788 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 789 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 790 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE0}; // a_inv = fp_mult(a_inv, precompute[0], p) + INV_S+ 791 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 792 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 793 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 794 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 795 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 796 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 797 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 798 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE0}; // a_inv = fp_mult(a_inv, precompute[0], p) + INV_S+ 799 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 800 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 801 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 802 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 803 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 804 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 805 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 806 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE0}; // a_inv = fp_mult(a_inv, precompute[0], p) + INV_S+ 807 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 808 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 809 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 810 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 811 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 812 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 813 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 814 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE0}; // a_inv = fp_mult(a_inv, precompute[0], p) + INV_S+ 815 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 816 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 817 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 818 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 819 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 820 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 821 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 822 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE0}; // a_inv = fp_mult(a_inv, precompute[0], p) + INV_S+ 823 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 824 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 825 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 826 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 827 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 828 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 829 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 830 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE0}; // a_inv = fp_mult(a_inv, precompute[0], p) + INV_S+ 831 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 832 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 833 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 834 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 835 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 836 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 837 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 838 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE0}; // a_inv = fp_mult(a_inv, precompute[0], p) + INV_S+ 839 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 840 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 841 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 842 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 843 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 844 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 845 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 846 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE0}; // a_inv = fp_mult(a_inv, precompute[0], p) + INV_S+ 847 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 848 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 849 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 850 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 851 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 852 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 853 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 854 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE0}; // a_inv = fp_mult(a_inv, precompute[0], p) + INV_S+ 855 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 856 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 857 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 858 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 859 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 860 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 861 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 862 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE0}; // a_inv = fp_mult(a_inv, precompute[0], p) + INV_S+ 863 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 864 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 865 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 866 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 867 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 868 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 869 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 870 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE0}; // a_inv = fp_mult(a_inv, precompute[0], p) + INV_S+ 871 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 872 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 873 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 874 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 875 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 876 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 877 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 878 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE0}; // a_inv = fp_mult(a_inv, precompute[0], p) + INV_S+ 879 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 880 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 881 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 882 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 883 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 884 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 885 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 886 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE0}; // a_inv = fp_mult(a_inv, precompute[0], p) + INV_S+ 887 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 888 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 889 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 890 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 891 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 892 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 893 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 894 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE0}; // a_inv = fp_mult(a_inv, precompute[0], p) + INV_S+ 895 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 896 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 897 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 898 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 899 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 900 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 901 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 902 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE0}; // a_inv = fp_mult(a_inv, precompute[0], p) + INV_S+ 903 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 904 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 905 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 906 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 907 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 908 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 909 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 910 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE0}; // a_inv = fp_mult(a_inv, precompute[0], p) + INV_S+ 911 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 912 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 913 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 914 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 915 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 916 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 917 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 918 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE0}; // a_inv = fp_mult(a_inv, precompute[0], p) + INV_S+ 919 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 920 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 921 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 922 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 923 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 924 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 925 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 926 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE0}; // a_inv = fp_mult(a_inv, precompute[0], p) + INV_S+ 927 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 928 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 929 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 930 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 931 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 932 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 933 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 934 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE0}; // a_inv = fp_mult(a_inv, precompute[0], p) + INV_S+ 935 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 936 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 937 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 938 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 939 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 940 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 941 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 942 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE0}; // a_inv = fp_mult(a_inv, precompute[0], p) + INV_S+ 943 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 944 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 945 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 946 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 947 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 948 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 949 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 950 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE0}; // a_inv = fp_mult(a_inv, precompute[0], p) + INV_S+ 951 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 952 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 953 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 954 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 955 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 956 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 957 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 958 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE3}; // a_inv = fp_mult(a_inv, precompute[3], p) + INV_S+ 959 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 960 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 961 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 962 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 963 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 964 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 965 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 966 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 967 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 968 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 969 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 970 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 971 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 972 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 973 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 974 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 975 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 976 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 977 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 978 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 979 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 980 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 981 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 982 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 983 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 984 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 985 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 986 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 987 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 988 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 989 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 990 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 991 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 992 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 993 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 994 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 995 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 996 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 997 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 998 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 999 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 1000 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 1001 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 1002 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 1003 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 1004 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 1005 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 1006 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 1007 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 1008 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 1009 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 1010 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 1011 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 1012 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 1013 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 1014 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 1015 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 1016 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 1017 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 1018 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 1019 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 1020 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 1021 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 1022 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 1023 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 1024 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 1025 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 1026 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 1027 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 1028 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 1029 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 1030 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], p) + INV_S+ 1031 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 1032 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 1033 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 1034 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 1035 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 1036 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, p) + INV_S+ 1037 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INV_S+ 1038 : douta <= {UOP_DO_MUL_p, UOP_OPR_A_INV, UOP_OPR_INV_PRE5}; // INV_OUT = fp_mult(a_inv, precompute[5], p) + INV_S+ 1039 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_INV_OUT}; + + //Conversion from projective Mont (X,Y,Z) to affine normanl (x,y) + CONV_S : douta <= {UOP_DO_MUL_p, UOP_OPR_INV_OUT, UOP_OPR_R0_Y}; // y_MONT = fp_mult(Z_inv, Y_MONT, p) + CONV_S+ 1 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_Qy_MONT}; + CONV_S+ 2 : douta <= {UOP_DO_MUL_p, UOP_OPR_INV_OUT, UOP_OPR_R0_X}; // x_MONT = fp_mult(Z_inv, X_MONT, p) + CONV_S+ 3 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_Qx_MONT}; + CONV_S+ 4 : douta <= {UOP_DO_MUL_p, UOP_OPR_CONST_ONE, UOP_OPR_Qy_MONT}; // y_affine = fp_mult(y_MONT, 1, p) + CONV_S+ 5 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_Qy_AFFN}; + CONV_S+ 6 : douta <= {UOP_DO_MUL_p, UOP_OPR_CONST_ONE, UOP_OPR_Qx_MONT}; // y_affine = fp_mult(y_MONT, 1, p) + CONV_S+ 7 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_Qx_AFFN}; + CONV_S+ 8 : douta <= {UOP_NOP, UOP_OPR_DONTCARE, UOP_OPR_DONTCARE}; + CONV_S+ 9 : douta <= {UOP_NOP, UOP_OPR_DONTCARE, UOP_OPR_DONTCARE}; + CONV_S+ 10 : douta <= {UOP_NOP, UOP_OPR_DONTCARE, UOP_OPR_DONTCARE}; + CONV_S+ 11 : douta <= {UOP_NOP, UOP_OPR_DONTCARE, UOP_OPR_DONTCARE}; + + // SIGNATURE R + SIGN0_S : douta <= {UOP_DO_ADD_q, UOP_OPR_CONST_ZERO, UOP_OPR_Qx_AFFN}; // R = Qx_AFFN + SIGN0_S+ 1 : douta <= {UOP_ST_ADD_q, UOP_OPR_SIGN_R, UOP_OPR_DONTCARE}; + SIGN0_S+ 2 : douta <= {UOP_DO_MUL_q, UOP_OPR_SIGN_R, UOP_OPR_CONST_R2_q}; // E = mm(R, R2) % q + SIGN0_S+ 3 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_E}; + SIGN0_S+ 4 : douta <= {UOP_DO_MUL_q, UOP_OPR_SCALAR_G, UOP_OPR_CONST_R2_q}; // k_MONT = mm(k, R2) % q + SIGN0_S+ 5 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_INV_IN}; + SIGN0_S+ 6 : douta <= {UOP_DO_MUL_q, UOP_OPR_PRIVKEY, UOP_OPR_CONST_R2_q}; // A = mm(privKey, R2) % q + SIGN0_S+ 7 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A}; + SIGN0_S+ 8 : douta <= {UOP_DO_MUL_q, UOP_OPR_HASH_MSG, UOP_OPR_CONST_R2_q}; // B = mm(h, R2) % q + SIGN0_S+ 9 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_B}; + SIGN0_S+ 10 : douta <= {UOP_DO_MUL_q, UOP_OPR_MASKING, UOP_OPR_CONST_R2_q}; // D = mm(masking_d, R2) % q + SIGN0_S+ 11 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_D}; + SIGN0_S+ 12 : douta <= {UOP_DO_SUB_q, UOP_OPR_A, UOP_OPR_D}; // A = (A - D) % q + SIGN0_S+ 13 : douta <= {UOP_ST_ADD_q, UOP_OPR_A, UOP_OPR_DONTCARE}; + SIGN0_S+ 14 : douta <= {UOP_DO_SUB_q, UOP_OPR_B, UOP_OPR_D}; // B = (B - D) % q + SIGN0_S+ 15 : douta <= {UOP_ST_ADD_q, UOP_OPR_B, UOP_OPR_DONTCARE}; + SIGN0_S+ 16 : douta <= {UOP_DO_MUL_q, UOP_OPR_A, UOP_OPR_E}; // C = mm(A, E) % q + SIGN0_S+ 17 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_C}; + SIGN0_S+ 18 : douta <= {UOP_DO_MUL_q, UOP_OPR_D, UOP_OPR_E}; // F = mm(D, E) % q + SIGN0_S+ 19 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_F}; + SIGN0_S+ 20 : douta <= {UOP_DO_ADD_q, UOP_OPR_D, UOP_OPR_C}; // C = (C + D) % q + SIGN0_S+ 21 : douta <= {UOP_ST_ADD_q, UOP_OPR_C, UOP_OPR_DONTCARE}; + SIGN0_S+ 22 : douta <= {UOP_DO_ADD_q, UOP_OPR_B, UOP_OPR_F}; // D = (B + F) % q + SIGN0_S+ 23 : douta <= {UOP_ST_ADD_q, UOP_OPR_D, UOP_OPR_DONTCARE}; + SIGN0_S+ 24 : douta <= {UOP_NOP, UOP_OPR_DONTCARE, UOP_OPR_DONTCARE}; + SIGN0_S+ 25 : douta <= {UOP_NOP, UOP_OPR_DONTCARE, UOP_OPR_DONTCARE}; + SIGN0_S+ 26 : douta <= {UOP_NOP, UOP_OPR_DONTCARE, UOP_OPR_DONTCARE}; + SIGN0_S+ 27 : douta <= {UOP_NOP, UOP_OPR_DONTCARE, UOP_OPR_DONTCARE}; + + //INV MOD q + INVq_S : douta <= {UOP_DO_ADD_q, UOP_OPR_CONST_ZERO, UOP_OPR_CONST_ONE_q_MONT}; // precompute[0] = UOP_OPR_CONST_ONE_q_MONT % q + INVq_S+ 1 : douta <= {UOP_ST_ADD_q, UOP_OPR_INV_PRE0, UOP_OPR_DONTCARE}; + INVq_S+ 2 : douta <= {UOP_DO_MUL_q, UOP_OPR_INV_IN, UOP_OPR_INV_PRE0}; // precompute[1] = fp_mult(Z, precompute[0], q) + INVq_S+ 3 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_INV_PRE1}; + INVq_S+ 4 : douta <= {UOP_DO_MUL_q, UOP_OPR_INV_IN, UOP_OPR_INV_PRE1}; // precompute[2] = fp_mult(Z, precompute[1], q) + INVq_S+ 5 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_INV_PRE2}; + INVq_S+ 6 : douta <= {UOP_DO_MUL_q, UOP_OPR_INV_IN, UOP_OPR_INV_PRE2}; // precompute[3] = fp_mult(Z, precompute[2], q) + INVq_S+ 7 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_INV_PRE3}; + INVq_S+ 8 : douta <= {UOP_DO_MUL_q, UOP_OPR_INV_IN, UOP_OPR_INV_PRE3}; // precompute[4] = fp_mult(Z, precompute[3], q) + INVq_S+ 9 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_INV_PRE4}; + INVq_S+ 10 : douta <= {UOP_DO_MUL_q, UOP_OPR_INV_IN, UOP_OPR_INV_PRE4}; // precompute[5] = fp_mult(Z, precompute[4], q) + INVq_S+ 11 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_INV_PRE5}; + INVq_S+ 12 : douta <= {UOP_DO_MUL_q, UOP_OPR_INV_IN, UOP_OPR_INV_PRE5}; // precompute[6] = fp_mult(Z, precompute[5], q) + INVq_S+ 13 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_INV_PRE6}; + INVq_S+ 14 : douta <= {UOP_DO_MUL_q, UOP_OPR_INV_IN, UOP_OPR_INV_PRE6}; // precompute[7] = fp_mult(Z, precompute[6], q) + INVq_S+ 15 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_INV_PRE7}; + INVq_S+ 16 : douta <= {UOP_DO_MUL_q, UOP_OPR_INV_PRE0, UOP_OPR_INV_PRE0}; // a_inv = fp_mult(precompute[0], precompute[0], q) + INVq_S+ 17 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 18 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 19 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 20 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 21 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 22 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], q) + INVq_S+ 23 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 24 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 25 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 26 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 27 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 28 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 29 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 30 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], q) + INVq_S+ 31 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 32 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 33 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 34 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 35 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 36 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 37 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 38 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], q) + INVq_S+ 39 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 40 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 41 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 42 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 43 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 44 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 45 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 46 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], q) + INVq_S+ 47 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 48 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 49 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 50 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 51 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 52 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 53 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 54 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], q) + INVq_S+ 55 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 56 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 57 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 58 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 59 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 60 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 61 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 62 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], q) + INVq_S+ 63 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 64 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 65 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 66 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 67 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 68 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 69 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 70 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], q) + INVq_S+ 71 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 72 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 73 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 74 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 75 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 76 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 77 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 78 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], q) + INVq_S+ 79 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 80 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 81 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 82 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 83 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 84 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 85 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 86 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], q) + INVq_S+ 87 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 88 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 89 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 90 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 91 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 92 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 93 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 94 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], q) + INVq_S+ 95 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 96 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 97 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 98 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 99 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 100 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 101 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 102 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], q) + INVq_S+ 103 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 104 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 105 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 106 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 107 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 108 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 109 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 110 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], q) + INVq_S+ 111 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 112 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 113 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 114 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 115 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 116 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 117 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 118 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], q) + INVq_S+ 119 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 120 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 121 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 122 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 123 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 124 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 125 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 126 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], q) + INVq_S+ 127 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 128 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 129 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 130 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 131 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 132 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 133 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 134 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], q) + INVq_S+ 135 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 136 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 137 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 138 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 139 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 140 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 141 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 142 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], q) + INVq_S+ 143 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 144 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 145 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 146 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 147 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 148 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 149 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 150 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], q) + INVq_S+ 151 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 152 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 153 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 154 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 155 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 156 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 157 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 158 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], q) + INVq_S+ 159 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 160 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 161 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 162 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 163 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 164 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 165 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 166 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], q) + INVq_S+ 167 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 168 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 169 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 170 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 171 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 172 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 173 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 174 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], q) + INVq_S+ 175 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 176 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 177 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 178 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 179 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 180 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 181 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 182 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], q) + INVq_S+ 183 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 184 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 185 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 186 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 187 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 188 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 189 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 190 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], q) + INVq_S+ 191 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 192 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 193 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 194 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 195 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 196 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 197 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 198 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], q) + INVq_S+ 199 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 200 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 201 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 202 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 203 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 204 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 205 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 206 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], q) + INVq_S+ 207 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 208 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 209 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 210 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 211 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 212 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 213 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 214 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], q) + INVq_S+ 215 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 216 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 217 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 218 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 219 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 220 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 221 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 222 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], q) + INVq_S+ 223 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 224 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 225 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 226 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 227 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 228 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 229 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 230 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], q) + INVq_S+ 231 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 232 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 233 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 234 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 235 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 236 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 237 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 238 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], q) + INVq_S+ 239 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 240 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 241 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 242 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 243 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 244 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 245 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 246 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], q) + INVq_S+ 247 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 248 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 249 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 250 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 251 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 252 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 253 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 254 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], q) + INVq_S+ 255 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 256 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 257 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 258 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 259 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 260 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 261 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 262 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], q) + INVq_S+ 263 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 264 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 265 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 266 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 267 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 268 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 269 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 270 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], q) + INVq_S+ 271 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 272 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 273 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 274 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 275 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 276 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 277 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 278 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], q) + INVq_S+ 279 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 280 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 281 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 282 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 283 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 284 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 285 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 286 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], q) + INVq_S+ 287 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 288 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 289 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 290 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 291 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 292 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 293 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 294 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], q) + INVq_S+ 295 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 296 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 297 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 298 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 299 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 300 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 301 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 302 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], q) + INVq_S+ 303 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 304 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 305 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 306 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 307 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 308 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 309 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 310 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], q) + INVq_S+ 311 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 312 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 313 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 314 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 315 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 316 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 317 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 318 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], q) + INVq_S+ 319 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 320 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 321 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 322 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 323 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 324 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 325 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 326 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], q) + INVq_S+ 327 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 328 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 329 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 330 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 331 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 332 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 333 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 334 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], q) + INVq_S+ 335 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 336 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 337 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 338 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 339 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 340 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 341 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 342 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], q) + INVq_S+ 343 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 344 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 345 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 346 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 347 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 348 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 349 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 350 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], q) + INVq_S+ 351 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 352 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 353 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 354 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 355 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 356 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 357 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 358 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], q) + INVq_S+ 359 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 360 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 361 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 362 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 363 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 364 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 365 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 366 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], q) + INVq_S+ 367 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 368 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 369 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 370 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 371 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 372 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 373 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 374 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], q) + INVq_S+ 375 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 376 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 377 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 378 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 379 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 380 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 381 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 382 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], q) + INVq_S+ 383 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 384 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 385 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 386 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 387 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 388 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 389 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 390 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], q) + INVq_S+ 391 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 392 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 393 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 394 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 395 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 396 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 397 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 398 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], q) + INVq_S+ 399 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 400 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 401 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 402 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 403 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 404 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 405 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 406 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], q) + INVq_S+ 407 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 408 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 409 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 410 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 411 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 412 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 413 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 414 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], q) + INVq_S+ 415 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 416 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 417 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 418 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 419 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 420 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 421 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 422 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], q) + INVq_S+ 423 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 424 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 425 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 426 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 427 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 428 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 429 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 430 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], q) + INVq_S+ 431 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 432 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 433 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 434 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 435 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 436 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 437 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 438 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], q) + INVq_S+ 439 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 440 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 441 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 442 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 443 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 444 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 445 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 446 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], q) + INVq_S+ 447 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 448 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 449 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 450 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 451 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 452 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 453 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 454 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], q) + INVq_S+ 455 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 456 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 457 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 458 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 459 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 460 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 461 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 462 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], q) + INVq_S+ 463 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 464 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 465 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 466 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 467 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 468 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 469 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 470 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], q) + INVq_S+ 471 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 472 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 473 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 474 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 475 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 476 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 477 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 478 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], q) + INVq_S+ 479 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 480 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 481 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 482 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 483 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 484 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 485 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 486 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], q) + INVq_S+ 487 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 488 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 489 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 490 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 491 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 492 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 493 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 494 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], q) + INVq_S+ 495 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 496 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 497 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 498 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 499 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 500 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 501 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 502 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], q) + INVq_S+ 503 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 504 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 505 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 506 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 507 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 508 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 509 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 510 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], q) + INVq_S+ 511 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 512 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 513 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 514 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 515 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 516 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 517 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 518 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], q) + INVq_S+ 519 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 520 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 521 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 522 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 523 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 524 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 525 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 526 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], q) + INVq_S+ 527 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 528 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 529 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 530 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 531 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 532 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 533 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 534 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE6}; // a_inv = fp_mult(a_inv, precompute[6], q) + INVq_S+ 535 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 536 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 537 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 538 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 539 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 540 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 541 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 542 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE1}; // a_inv = fp_mult(a_inv, precompute[1], q) + INVq_S+ 543 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 544 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 545 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 546 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 547 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 548 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 549 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 550 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE6}; // a_inv = fp_mult(a_inv, precompute[6], q) + INVq_S+ 551 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 552 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 553 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 554 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 555 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 556 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 557 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 558 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE6}; // a_inv = fp_mult(a_inv, precompute[6], q) + INVq_S+ 559 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 560 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 561 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 562 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 563 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 564 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 565 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 566 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE1}; // a_inv = fp_mult(a_inv, precompute[1], q) + INVq_S+ 567 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 568 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 569 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 570 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 571 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 572 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 573 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 574 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE5}; // a_inv = fp_mult(a_inv, precompute[5], q) + INVq_S+ 575 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 576 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 577 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 578 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 579 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 580 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 581 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 582 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE1}; // a_inv = fp_mult(a_inv, precompute[1], q) + INVq_S+ 583 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 584 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 585 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 586 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 587 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 588 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 589 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 590 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE5}; // a_inv = fp_mult(a_inv, precompute[5], q) + INVq_S+ 591 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 592 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 593 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 594 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 595 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 596 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 597 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 598 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE4}; // a_inv = fp_mult(a_inv, precompute[4], q) + INVq_S+ 599 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 600 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 601 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 602 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 603 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 604 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 605 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 606 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE0}; // a_inv = fp_mult(a_inv, precompute[0], q) + INVq_S+ 607 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 608 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 609 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 610 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 611 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 612 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 613 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 614 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE3}; // a_inv = fp_mult(a_inv, precompute[3], q) + INVq_S+ 615 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 616 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 617 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 618 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 619 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 620 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 621 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 622 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], q) + INVq_S+ 623 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 624 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 625 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 626 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 627 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 628 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 629 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 630 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE2}; // a_inv = fp_mult(a_inv, precompute[2], q) + INVq_S+ 631 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 632 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 633 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 634 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 635 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 636 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 637 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 638 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE0}; // a_inv = fp_mult(a_inv, precompute[0], q) + INVq_S+ 639 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 640 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 641 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 642 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 643 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 644 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 645 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 646 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE6}; // a_inv = fp_mult(a_inv, precompute[6], q) + INVq_S+ 647 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 648 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 649 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 650 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 651 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 652 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 653 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 654 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], q) + INVq_S+ 655 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 656 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 657 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 658 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 659 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 660 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 661 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 662 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE1}; // a_inv = fp_mult(a_inv, precompute[1], q) + INVq_S+ 663 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 664 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 665 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 666 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 667 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 668 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 669 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 670 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE3}; // a_inv = fp_mult(a_inv, precompute[3], q) + INVq_S+ 671 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 672 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 673 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 674 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 675 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 676 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 677 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 678 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE3}; // a_inv = fp_mult(a_inv, precompute[3], q) + INVq_S+ 679 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 680 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 681 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 682 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 683 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 684 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 685 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 686 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE5}; // a_inv = fp_mult(a_inv, precompute[5], q) + INVq_S+ 687 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 688 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 689 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 690 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 691 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 692 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 693 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 694 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], q) + INVq_S+ 695 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 696 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 697 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 698 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 699 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 700 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 701 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 702 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE5}; // a_inv = fp_mult(a_inv, precompute[5], q) + INVq_S+ 703 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 704 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 705 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 706 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 707 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 708 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 709 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 710 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE3}; // a_inv = fp_mult(a_inv, precompute[3], q) + INVq_S+ 711 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 712 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 713 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 714 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 715 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 716 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 717 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 718 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE0}; // a_inv = fp_mult(a_inv, precompute[0], q) + INVq_S+ 719 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 720 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 721 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 722 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 723 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 724 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 725 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 726 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE0}; // a_inv = fp_mult(a_inv, precompute[0], q) + INVq_S+ 727 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 728 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 729 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 730 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 731 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 732 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 733 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 734 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE6}; // a_inv = fp_mult(a_inv, precompute[6], q) + INVq_S+ 735 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 736 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 737 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 738 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 739 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 740 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 741 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 742 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE4}; // a_inv = fp_mult(a_inv, precompute[4], q) + INVq_S+ 743 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 744 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 745 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 746 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 747 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 748 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 749 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 750 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE0}; // a_inv = fp_mult(a_inv, precompute[0], q) + INVq_S+ 751 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 752 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 753 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 754 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 755 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 756 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 757 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 758 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE6}; // a_inv = fp_mult(a_inv, precompute[6], q) + INVq_S+ 759 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 760 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 761 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 762 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 763 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 764 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 765 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 766 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE6}; // a_inv = fp_mult(a_inv, precompute[6], q) + INVq_S+ 767 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 768 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 769 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 770 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 771 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 772 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 773 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 774 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE6}; // a_inv = fp_mult(a_inv, precompute[6], q) + INVq_S+ 775 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 776 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 777 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 778 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 779 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 780 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 781 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 782 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE2}; // a_inv = fp_mult(a_inv, precompute[2], q) + INVq_S+ 783 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 784 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 785 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 786 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 787 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 788 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 789 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 790 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE2}; // a_inv = fp_mult(a_inv, precompute[2], q) + INVq_S+ 791 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 792 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 793 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 794 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 795 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 796 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 797 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 798 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE2}; // a_inv = fp_mult(a_inv, precompute[2], q) + INVq_S+ 799 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 800 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 801 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 802 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 803 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 804 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 805 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 806 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE1}; // a_inv = fp_mult(a_inv, precompute[1], q) + INVq_S+ 807 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 808 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 809 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 810 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 811 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 812 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 813 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 814 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE3}; // a_inv = fp_mult(a_inv, precompute[3], q) + INVq_S+ 815 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 816 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 817 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 818 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 819 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 820 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 821 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 822 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE0}; // a_inv = fp_mult(a_inv, precompute[0], q) + INVq_S+ 823 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 824 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 825 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 826 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 827 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 828 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 829 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 830 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE2}; // a_inv = fp_mult(a_inv, precompute[2], q) + INVq_S+ 831 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 832 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 833 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 834 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 835 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 836 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 837 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 838 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE4}; // a_inv = fp_mult(a_inv, precompute[4], q) + INVq_S+ 839 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 840 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 841 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 842 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 843 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 844 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 845 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 846 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE7}; // a_inv = fp_mult(a_inv, precompute[7], q) + INVq_S+ 847 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 848 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 849 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 850 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 851 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 852 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 853 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 854 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE3}; // a_inv = fp_mult(a_inv, precompute[3], q) + INVq_S+ 855 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 856 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 857 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 858 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 859 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 860 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 861 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 862 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE6}; // a_inv = fp_mult(a_inv, precompute[6], q) + INVq_S+ 863 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 864 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 865 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 866 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 867 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 868 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 869 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 870 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE5}; // a_inv = fp_mult(a_inv, precompute[5], q) + INVq_S+ 871 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 872 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 873 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 874 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 875 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 876 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 877 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 878 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE6}; // a_inv = fp_mult(a_inv, precompute[6], q) + INVq_S+ 879 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 880 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 881 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 882 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 883 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 884 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 885 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 886 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE6}; // a_inv = fp_mult(a_inv, precompute[6], q) + INVq_S+ 887 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 888 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 889 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 890 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 891 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 892 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 893 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 894 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE3}; // a_inv = fp_mult(a_inv, precompute[3], q) + INVq_S+ 895 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 896 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 897 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 898 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 899 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 900 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 901 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 902 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE5}; // a_inv = fp_mult(a_inv, precompute[5], q) + INVq_S+ 903 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 904 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 905 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 906 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 907 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 908 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 909 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 910 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE4}; // a_inv = fp_mult(a_inv, precompute[4], q) + INVq_S+ 911 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 912 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 913 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 914 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 915 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 916 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 917 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 918 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE0}; // a_inv = fp_mult(a_inv, precompute[0], q) + INVq_S+ 919 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 920 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 921 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 922 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 923 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 924 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 925 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 926 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE6}; // a_inv = fp_mult(a_inv, precompute[6], q) + INVq_S+ 927 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 928 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 929 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 930 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 931 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 932 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 933 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 934 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE2}; // a_inv = fp_mult(a_inv, precompute[2], q) + INVq_S+ 935 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 936 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 937 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 938 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 939 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 940 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 941 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 942 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE6}; // a_inv = fp_mult(a_inv, precompute[6], q) + INVq_S+ 943 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 944 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 945 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 946 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 947 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 948 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 949 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 950 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE5}; // a_inv = fp_mult(a_inv, precompute[5], q) + INVq_S+ 951 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 952 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 953 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 954 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 955 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 956 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 957 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 958 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE3}; // a_inv = fp_mult(a_inv, precompute[3], q) + INVq_S+ 959 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 960 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 961 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 962 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 963 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 964 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 965 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 966 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE1}; // a_inv = fp_mult(a_inv, precompute[1], q) + INVq_S+ 967 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 968 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 969 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 970 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 971 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 972 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 973 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 974 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE4}; // a_inv = fp_mult(a_inv, precompute[4], q) + INVq_S+ 975 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 976 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 977 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 978 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 979 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 980 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 981 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 982 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE6}; // a_inv = fp_mult(a_inv, precompute[6], q) + INVq_S+ 983 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 984 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 985 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 986 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 987 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 988 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 989 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 990 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE1}; // a_inv = fp_mult(a_inv, precompute[1], q) + INVq_S+ 991 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 992 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 993 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 994 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 995 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 996 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 997 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 998 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE2}; // a_inv = fp_mult(a_inv, precompute[2], q) + INVq_S+ 999 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 1000 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 1001 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 1002 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 1003 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 1004 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 1005 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 1006 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE2}; // a_inv = fp_mult(a_inv, precompute[2], q) + INVq_S+ 1007 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 1008 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 1009 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 1010 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 1011 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 1012 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 1013 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 1014 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE4}; // a_inv = fp_mult(a_inv, precompute[4], q) + INVq_S+ 1015 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 1016 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 1017 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 1018 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 1019 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 1020 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 1021 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 1022 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE5}; // a_inv = fp_mult(a_inv, precompute[5], q) + INVq_S+ 1023 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 1024 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 1025 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 1026 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 1027 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 1028 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 1029 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 1030 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE6}; // a_inv = fp_mult(a_inv, precompute[6], q) + INVq_S+ 1031 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 1032 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 1033 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 1034 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 1035 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 1036 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_A_INV}; // a_inv = fp_mult(a_inv, a_inv, q) + INVq_S+ 1037 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A_INV}; + INVq_S+ 1038 : douta <= {UOP_DO_MUL_q, UOP_OPR_A_INV, UOP_OPR_INV_PRE1}; // INV_OUT = fp_mult(a_inv, precompute[1], q) + INVq_S+ 1039 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_INV_OUT}; + INVq_S+ 1040 : douta <= {UOP_NOP, UOP_OPR_DONTCARE, UOP_OPR_DONTCARE}; + INVq_S+ 1041 : douta <= {UOP_NOP, UOP_OPR_DONTCARE, UOP_OPR_DONTCARE}; + INVq_S+ 1042 : douta <= {UOP_NOP, UOP_OPR_DONTCARE, UOP_OPR_DONTCARE}; + INVq_S+ 1043 : douta <= {UOP_NOP, UOP_OPR_DONTCARE, UOP_OPR_DONTCARE}; + + //SIGNING part1 + SIGN1_S : douta <= {UOP_DO_MUL_q, UOP_OPR_INV_OUT, UOP_OPR_C}; // C = fp_mult(C, k_inv, q) + SIGN1_S+ 1 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_C}; + SIGN1_S+ 2 : douta <= {UOP_DO_MUL_q, UOP_OPR_INV_OUT, UOP_OPR_D}; // D = fp_mult(D, k_inv, q) + SIGN1_S+ 3 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_D}; + SIGN1_S+ 4 : douta <= {UOP_DO_ADD_q, UOP_OPR_C, UOP_OPR_D}; // B = C + D % q + SIGN1_S+ 5 : douta <= {UOP_ST_ADD_q, UOP_OPR_B, UOP_OPR_DONTCARE}; + SIGN1_S+ 6 : douta <= {UOP_DO_MUL_q, UOP_OPR_CONST_ONE, UOP_OPR_B}; // B = fp_mult(B, 1, q) + SIGN1_S+ 7 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_SIGN_S}; + SIGN1_S+ 8 : douta <= {UOP_NOP, UOP_OPR_DONTCARE, UOP_OPR_DONTCARE}; + SIGN1_S+ 9 : douta <= {UOP_NOP, UOP_OPR_DONTCARE, UOP_OPR_DONTCARE}; + SIGN1_S+ 10 : douta <= {UOP_NOP, UOP_OPR_DONTCARE, UOP_OPR_DONTCARE}; + SIGN1_S+ 11 : douta <= {UOP_NOP, UOP_OPR_DONTCARE, UOP_OPR_DONTCARE}; + + // check the given public key is a valid curve point + CHK_PK_S : douta <= {UOP_DO_MUL_p, UOP_OPR_Qy_AFFN, UOP_OPR_CONST_R2_p}; // A = mm(Qy, R2) % q + CHK_PK_S+ 1 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A}; + CHK_PK_S+ 2 : douta <= {UOP_DO_MUL_p, UOP_OPR_A, UOP_OPR_A}; // A = A*A % q + CHK_PK_S+ 3 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A}; + CHK_PK_S+ 4 : douta <= {UOP_DO_MUL_p, UOP_OPR_Qx_AFFN, UOP_OPR_CONST_R2_p}; // B = mm(Qx, R2) % q + CHK_PK_S+ 5 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_B}; + CHK_PK_S+ 6 : douta <= {UOP_DO_MUL_p, UOP_OPR_B, UOP_OPR_B}; // C = B*B % q + CHK_PK_S+ 7 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_C}; + CHK_PK_S+ 8 : douta <= {UOP_DO_MUL_p, UOP_OPR_C, UOP_OPR_B}; // C = C*B % q + CHK_PK_S+ 9 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_C}; + CHK_PK_S+ 10 : douta <= {UOP_DO_MUL_p, UOP_OPR_CONST_E_a, UOP_OPR_B}; // D = ECC.a*B % q + CHK_PK_S+ 11 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_D}; + CHK_PK_S+ 12 : douta <= {UOP_DO_ADD_p, UOP_OPR_C, UOP_OPR_D}; // C = C + D % q + CHK_PK_S+ 13 : douta <= {UOP_ST_ADD_p, UOP_OPR_C, UOP_OPR_DONTCARE}; + CHK_PK_S+ 14 : douta <= {UOP_DO_ADD_p, UOP_OPR_C, UOP_OPR_CONST_E_b}; // C = C + ECC.b % q + CHK_PK_S+ 15 : douta <= {UOP_ST_ADD_p, UOP_OPR_C, UOP_OPR_DONTCARE}; + CHK_PK_S+ 16 : douta <= {UOP_DO_SUB_p, UOP_OPR_A, UOP_OPR_C}; // C = C + ECC.b % q + CHK_PK_S+ 17 : douta <= {UOP_ST_ADD_p, UOP_OPR_PK_VALID, UOP_OPR_DONTCARE}; + CHK_PK_S+ 18 : douta <= {UOP_NOP, UOP_OPR_DONTCARE, UOP_OPR_DONTCARE}; + CHK_PK_S+ 19 : douta <= {UOP_NOP, UOP_OPR_DONTCARE, UOP_OPR_DONTCARE}; + CHK_PK_S+ 20 : douta <= {UOP_NOP, UOP_OPR_DONTCARE, UOP_OPR_DONTCARE}; + CHK_PK_S+ 21 : douta <= {UOP_NOP, UOP_OPR_DONTCARE, UOP_OPR_DONTCARE}; + + // VERIFY0 SCALAR part0 to convert inputs to Mont domain + VER0_P0_S : douta <= {UOP_DO_MUL_q, UOP_OPR_HASH_MSG, UOP_OPR_CONST_R2_q}; // A = mm(h, R2) % q + VER0_P0_S+ 1 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A}; + VER0_P0_S+ 2 : douta <= {UOP_DO_MUL_q, UOP_OPR_SIGN_R, UOP_OPR_CONST_R2_q}; // B = mm(R, R2) % q + VER0_P0_S+ 3 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_B}; + VER0_P0_S+ 4 : douta <= {UOP_DO_MUL_q, UOP_OPR_SIGN_S, UOP_OPR_CONST_R2_q}; // INV_IN = mm(S, R2) % q + VER0_P0_S+ 5 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_INV_IN}; + VER0_P0_S+ 6 : douta <= {UOP_NOP, UOP_OPR_DONTCARE, UOP_OPR_DONTCARE}; + VER0_P0_S+ 7 : douta <= {UOP_NOP, UOP_OPR_DONTCARE, UOP_OPR_DONTCARE}; + VER0_P0_S+ 8 : douta <= {UOP_NOP, UOP_OPR_DONTCARE, UOP_OPR_DONTCARE}; + VER0_P0_S+ 9 : douta <= {UOP_NOP, UOP_OPR_DONTCARE, UOP_OPR_DONTCARE}; + + // VERIFY0 SCALAR part1 to compute (h*s_inv) and (r*s_inv) + VER0_P1_S : douta <= {UOP_DO_MUL_q, UOP_OPR_INV_OUT, UOP_OPR_A}; // A = mm(h, S_INV) % q + VER0_P1_S+ 1 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_A}; + VER0_P1_S+ 2 : douta <= {UOP_DO_MUL_q, UOP_OPR_CONST_ONE, UOP_OPR_A}; // hs1 = mm(A, 1) % q + VER0_P1_S+ 3 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_SCALAR_G}; + VER0_P1_S+ 4 : douta <= {UOP_DO_MUL_q, UOP_OPR_INV_OUT, UOP_OPR_B}; // B = mm(r, S_INV) % q + VER0_P1_S+ 5 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_B}; + VER0_P1_S+ 6 : douta <= {UOP_DO_MUL_q, UOP_OPR_CONST_ONE, UOP_OPR_B}; // rs1 = mm(B, 1) % q + VER0_P1_S+ 7 : douta <= {UOP_ST_MUL_q, UOP_OPR_DONTCARE, UOP_OPR_SCALAR_PK}; + VER0_P1_S+ 8 : douta <= {UOP_NOP, UOP_OPR_DONTCARE, UOP_OPR_DONTCARE}; + VER0_P1_S+ 9 : douta <= {UOP_NOP, UOP_OPR_DONTCARE, UOP_OPR_DONTCARE}; + VER0_P1_S+ 10 : douta <= {UOP_NOP, UOP_OPR_DONTCARE, UOP_OPR_DONTCARE}; + VER0_P1_S+ 11 : douta <= {UOP_NOP, UOP_OPR_DONTCARE, UOP_OPR_DONTCARE}; + + //STORE VER1 result (h*s_inv)*G + VER1_ST_S : douta <= {UOP_DO_ADD_p, UOP_OPR_R0_X, UOP_OPR_CONST_ZERO}; + VER1_ST_S+ 1 : douta <= {UOP_ST_ADD_p, UOP_OPR_P1_X_MONT, UOP_OPR_DONTCARE}; + VER1_ST_S+ 2 : douta <= {UOP_DO_ADD_p, UOP_OPR_R0_Y, UOP_OPR_CONST_ZERO}; + VER1_ST_S+ 3 : douta <= {UOP_ST_ADD_p, UOP_OPR_P1_Y_MONT, UOP_OPR_DONTCARE}; + VER1_ST_S+ 4 : douta <= {UOP_DO_ADD_p, UOP_OPR_R0_Z, UOP_OPR_CONST_ZERO}; + VER1_ST_S+ 5 : douta <= {UOP_ST_ADD_p, UOP_OPR_P1_Z_MONT, UOP_OPR_DONTCARE}; + + //VER2 R1 INIT with PK + PM_INIT_PK_S : douta <= {UOP_DO_MUL_p, UOP_OPR_Qx_AFFN, UOP_OPR_CONST_R2_p}; + PM_INIT_PK_S+ 1 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_R1_X}; + PM_INIT_PK_S+ 2 : douta <= {UOP_DO_MUL_p, UOP_OPR_Qy_AFFN, UOP_OPR_CONST_R2_p}; + PM_INIT_PK_S+ 3 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_R1_Y}; + PM_INIT_PK_S+ 4 : douta <= {UOP_DO_ADD_p, UOP_OPR_CONST_ONE_MONT, UOP_OPR_CONST_ZERO}; + PM_INIT_PK_S+ 5 : douta <= {UOP_ST_ADD_p, UOP_OPR_R1_Z, UOP_OPR_DONTCARE}; + + //VER2 point addtion of PA((h*s_inv)*G, (r*s_inv)*PK) + VER2_PA_S : douta <= {UOP_DO_MUL_p, UOP_OPR_R0_X, UOP_OPR_P1_X_MONT}; // A = fp_mult(P0.X, P1.X, p) + VER2_PA_S+ 1 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A}; + VER2_PA_S+ 2 : douta <= {UOP_DO_MUL_p, UOP_OPR_R0_Y, UOP_OPR_P1_Y_MONT}; // B = fp_mult(P0.Y, P1.Y, p) + VER2_PA_S+ 3 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_B}; + VER2_PA_S+ 4 : douta <= {UOP_DO_MUL_p, UOP_OPR_R0_Z, UOP_OPR_P1_Z_MONT}; // C = fp_mult(P0.Z, P1.Z, p) + VER2_PA_S+ 5 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_C}; + VER2_PA_S+ 6 : douta <= {UOP_DO_ADD_p, UOP_OPR_R0_X, UOP_OPR_R0_Y}; // D = (P0.X + P0.Y) % p + VER2_PA_S+ 7 : douta <= {UOP_ST_ADD_p, UOP_OPR_D, UOP_OPR_DONTCARE}; + VER2_PA_S+ 8 : douta <= {UOP_DO_ADD_p, UOP_OPR_P1_X_MONT, UOP_OPR_P1_Y_MONT}; // E = (P1.X + P1.Y) % p + VER2_PA_S+ 9 : douta <= {UOP_ST_ADD_p, UOP_OPR_E, UOP_OPR_DONTCARE}; + VER2_PA_S+ 10 : douta <= {UOP_DO_MUL_p, UOP_OPR_D, UOP_OPR_E}; // D = fp_mult(D, E, p) + VER2_PA_S+ 11 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_D}; + VER2_PA_S+ 12 : douta <= {UOP_DO_ADD_p, UOP_OPR_A, UOP_OPR_B}; // E = (A + B) % p + VER2_PA_S+ 13 : douta <= {UOP_ST_ADD_p, UOP_OPR_E, UOP_OPR_DONTCARE}; + VER2_PA_S+ 14 : douta <= {UOP_DO_SUB_p, UOP_OPR_D, UOP_OPR_E}; // D = (D - E) % p + VER2_PA_S+ 15 : douta <= {UOP_ST_ADD_p, UOP_OPR_D, UOP_OPR_DONTCARE}; + VER2_PA_S+ 16 : douta <= {UOP_DO_ADD_p, UOP_OPR_R0_X, UOP_OPR_R0_Z}; // E = (P0.X + P0.Z) % p + VER2_PA_S+ 17 : douta <= {UOP_ST_ADD_p, UOP_OPR_E, UOP_OPR_DONTCARE}; + VER2_PA_S+ 18 : douta <= {UOP_DO_ADD_p, UOP_OPR_P1_X_MONT, UOP_OPR_P1_Z_MONT}; // F = (P1.X + P1.Z) % p + VER2_PA_S+ 19 : douta <= {UOP_ST_ADD_p, UOP_OPR_F, UOP_OPR_DONTCARE}; + VER2_PA_S+ 20 : douta <= {UOP_DO_MUL_p, UOP_OPR_E, UOP_OPR_F}; // E = fp_mult(E, F, p) + VER2_PA_S+ 21 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_E}; + VER2_PA_S+ 22 : douta <= {UOP_DO_ADD_p, UOP_OPR_A, UOP_OPR_C}; // F = (A + C) % p + VER2_PA_S+ 23 : douta <= {UOP_ST_ADD_p, UOP_OPR_F, UOP_OPR_DONTCARE}; + VER2_PA_S+ 24 : douta <= {UOP_DO_SUB_p, UOP_OPR_E, UOP_OPR_F}; // E = (E - F) % p + VER2_PA_S+ 25 : douta <= {UOP_ST_ADD_p, UOP_OPR_E, UOP_OPR_DONTCARE}; + VER2_PA_S+ 26 : douta <= {UOP_DO_ADD_p, UOP_OPR_R0_Y, UOP_OPR_R0_Z}; // F = (P0.Y + P0.Z) % p + VER2_PA_S+ 27 : douta <= {UOP_ST_ADD_p, UOP_OPR_F, UOP_OPR_DONTCARE}; + VER2_PA_S+ 28 : douta <= {UOP_DO_ADD_p, UOP_OPR_P1_Y_MONT, UOP_OPR_P1_Z_MONT}; // X3 = (P1.Y + P1.Z) % p + VER2_PA_S+ 29 : douta <= {UOP_ST_ADD_p, UOP_OPR_R0_X, UOP_OPR_DONTCARE}; + VER2_PA_S+ 30 : douta <= {UOP_DO_MUL_p, UOP_OPR_F, UOP_OPR_R0_X}; // F = fp_mult(F, X3, p) + VER2_PA_S+ 31 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_F}; + VER2_PA_S+ 32 : douta <= {UOP_DO_ADD_p, UOP_OPR_B, UOP_OPR_C}; // X3 = (B + C) % p + VER2_PA_S+ 33 : douta <= {UOP_ST_ADD_p, UOP_OPR_R0_X, UOP_OPR_DONTCARE}; + VER2_PA_S+ 34 : douta <= {UOP_DO_SUB_p, UOP_OPR_F, UOP_OPR_R0_X}; // F = (F - X3) % p + VER2_PA_S+ 35 : douta <= {UOP_ST_ADD_p, UOP_OPR_F, UOP_OPR_DONTCARE}; + VER2_PA_S+ 36 : douta <= {UOP_DO_MUL_p, UOP_OPR_CONST_E_a, UOP_OPR_E}; // Z3 = fp_mult(ECC.a, E, p) + VER2_PA_S+ 37 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_R0_Z}; + VER2_PA_S+ 38 : douta <= {UOP_DO_MUL_p, UOP_OPR_CONST_E_3b, UOP_OPR_C}; // X3 = fp_mult(ECC.3b, C, p) + VER2_PA_S+ 39 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_R0_X}; + VER2_PA_S+ 40 : douta <= {UOP_DO_ADD_p, UOP_OPR_R0_X, UOP_OPR_R0_Z}; // Z3 = (X3 + Z3) % p + VER2_PA_S+ 41 : douta <= {UOP_ST_ADD_p, UOP_OPR_R0_Z, UOP_OPR_DONTCARE}; + VER2_PA_S+ 42 : douta <= {UOP_DO_SUB_p, UOP_OPR_B, UOP_OPR_R0_Z}; // X3 = (B - Z3) % p + VER2_PA_S+ 43 : douta <= {UOP_ST_ADD_p, UOP_OPR_R0_X, UOP_OPR_DONTCARE}; + VER2_PA_S+ 44 : douta <= {UOP_DO_ADD_p, UOP_OPR_B, UOP_OPR_R0_Z}; // Z3 = (B + Z3) % p + VER2_PA_S+ 45 : douta <= {UOP_ST_ADD_p, UOP_OPR_R0_Z, UOP_OPR_DONTCARE}; + VER2_PA_S+ 46 : douta <= {UOP_DO_MUL_p, UOP_OPR_R0_X, UOP_OPR_R0_Z}; // Y3 = fp_mult(X3, Z3, p) + VER2_PA_S+ 47 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_R0_Y}; + VER2_PA_S+ 48 : douta <= {UOP_DO_ADD_p, UOP_OPR_A, UOP_OPR_A}; // B = (A + A) % p + VER2_PA_S+ 49 : douta <= {UOP_ST_ADD_p, UOP_OPR_B, UOP_OPR_DONTCARE}; + VER2_PA_S+ 50 : douta <= {UOP_DO_ADD_p, UOP_OPR_B, UOP_OPR_A}; // B = (B + A) % p + VER2_PA_S+ 51 : douta <= {UOP_ST_ADD_p, UOP_OPR_B, UOP_OPR_DONTCARE}; + VER2_PA_S+ 52 : douta <= {UOP_DO_MUL_p, UOP_OPR_CONST_E_a, UOP_OPR_C}; // C = fp_mult(ECC.a, C, p) + VER2_PA_S+ 53 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_C}; + VER2_PA_S+ 54 : douta <= {UOP_DO_MUL_p, UOP_OPR_CONST_E_3b, UOP_OPR_E}; // E = fp_mult(ECC.3b, E, p) + VER2_PA_S+ 55 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_E}; + VER2_PA_S+ 56 : douta <= {UOP_DO_ADD_p, UOP_OPR_B, UOP_OPR_C}; // B = (B + C) % p + VER2_PA_S+ 57 : douta <= {UOP_ST_ADD_p, UOP_OPR_B, UOP_OPR_DONTCARE}; + VER2_PA_S+ 58 : douta <= {UOP_DO_SUB_p, UOP_OPR_A, UOP_OPR_C}; // C = (A - C) % p + VER2_PA_S+ 59 : douta <= {UOP_ST_ADD_p, UOP_OPR_C, UOP_OPR_DONTCARE}; + VER2_PA_S+ 60 : douta <= {UOP_DO_MUL_p, UOP_OPR_CONST_E_a, UOP_OPR_C}; // C = fp_mult(ECC.a, C, p) + VER2_PA_S+ 61 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_C}; + VER2_PA_S+ 62 : douta <= {UOP_DO_ADD_p, UOP_OPR_E, UOP_OPR_C}; // E = (E + C) % p + VER2_PA_S+ 63 : douta <= {UOP_ST_ADD_p, UOP_OPR_E, UOP_OPR_DONTCARE}; + VER2_PA_S+ 64 : douta <= {UOP_DO_MUL_p, UOP_OPR_B, UOP_OPR_E}; // A = fp_mult(B, E, p) + VER2_PA_S+ 65 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A}; + VER2_PA_S+ 66 : douta <= {UOP_DO_ADD_p, UOP_OPR_R0_Y, UOP_OPR_A}; // Y3 = (Y3 + A) % p + VER2_PA_S+ 67 : douta <= {UOP_ST_ADD_p, UOP_OPR_R0_Y, UOP_OPR_DONTCARE}; + VER2_PA_S+ 68 : douta <= {UOP_DO_MUL_p, UOP_OPR_F, UOP_OPR_E}; // A = fp_mult(F, E, p) + VER2_PA_S+ 69 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A}; + VER2_PA_S+ 70 : douta <= {UOP_DO_MUL_p, UOP_OPR_D, UOP_OPR_R0_X}; // X3 = fp_mult(D, X3, p) + VER2_PA_S+ 71 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_R0_X}; + VER2_PA_S+ 72 : douta <= {UOP_DO_SUB_p, UOP_OPR_R0_X, UOP_OPR_A}; // X3 = (X3 - A) % p + VER2_PA_S+ 73 : douta <= {UOP_ST_ADD_p, UOP_OPR_R0_X, UOP_OPR_DONTCARE}; + VER2_PA_S+ 74 : douta <= {UOP_DO_MUL_p, UOP_OPR_D, UOP_OPR_B}; // A = fp_mult(D, B, p) + VER2_PA_S+ 75 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_A}; + VER2_PA_S+ 76 : douta <= {UOP_DO_MUL_p, UOP_OPR_F, UOP_OPR_R0_Z}; // Z3 = fp_mult(F, Z3, p) + VER2_PA_S+ 77 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_R0_Z}; + VER2_PA_S+ 78 : douta <= {UOP_DO_ADD_p, UOP_OPR_R0_Z, UOP_OPR_A}; // Z3 = (Z3 + A) % p + VER2_PA_S+ 79 : douta <= {UOP_ST_ADD_p, UOP_OPR_R0_Z, UOP_OPR_DONTCARE}; + VER2_PA_S+ 80 : douta <= {UOP_DO_ADD_p, UOP_OPR_R0_Z, UOP_OPR_CONST_ZERO}; // Zinv_IN = P1_Z + VER2_PA_S+ 81 : douta <= {UOP_ST_ADD_p, UOP_OPR_INV_IN, UOP_OPR_DONTCARE}; + + //DH SHARED KEY R1 INIT with PK + PM_INIT_DH_S : douta <= {UOP_DO_MUL_p, UOP_OPR_LAMBDA, UOP_OPR_CONST_R2_p}; // R1_Z = mm(Lambda, R2) + PM_INIT_DH_S+ 1 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_R1_Z}; + PM_INIT_DH_S+ 2 : douta <= {UOP_DO_MUL_p, UOP_OPR_Qx_AFFN, UOP_OPR_CONST_R2_p}; // R1_X = mm(PK_X, R2) + PM_INIT_DH_S+ 3 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_R1_X}; + PM_INIT_DH_S+ 4 : douta <= {UOP_DO_MUL_p, UOP_OPR_R1_X, UOP_OPR_R1_Z}; // R1_X = mm(PKX_MONT, R0_Z) + PM_INIT_DH_S+ 5 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_R1_X}; + PM_INIT_DH_S+ 6 : douta <= {UOP_DO_MUL_p, UOP_OPR_Qy_AFFN, UOP_OPR_CONST_R2_p}; // R1_Y = mm(PK_Y, R2) + PM_INIT_DH_S+ 7 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_R1_Y}; + PM_INIT_DH_S+ 8 : douta <= {UOP_DO_MUL_p, UOP_OPR_R1_Y, UOP_OPR_R1_Z}; // R1_Y = mm(PKY_MONT, R0_Z) + PM_INIT_DH_S+ 9 : douta <= {UOP_ST_MUL_p, UOP_OPR_DONTCARE, UOP_OPR_R1_Y}; + + default : douta <= {UOP_NOP, UOP_OPR_DONTCARE, UOP_OPR_DONTCARE}; + endcase + end + end + end // prog_rom + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/ecc_pm_uop_pkg.sv b/designs/Caliptra/src/caliptra-rtl/ecc_pm_uop_pkg.sv new file mode 100644 index 0000000..a5e93f4 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/ecc_pm_uop_pkg.sv @@ -0,0 +1,184 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +// +//====================================================================== +// +// ecc_pm_uop_pkg.sv +// -------- +// ECC instructin for the point multiplication (PM). +// +// +//====================================================================== + + +`ifndef CALIPTRA_ECC_PM_UOP_PKG +`define CALIPTRA_ECC_PM_UOP_PKG + +package ecc_pm_uop_pkg; + +localparam integer UOP_ADDR_WIDTH = 6; +localparam integer OPR_ADDR_WIDTH = 6; + +localparam PROG_ADDR_W = 12; //$clog2(VER2_PA_E+2); +localparam INSTRUCTION_LENGTH = UOP_ADDR_WIDTH + (2*OPR_ADDR_WIDTH); // opcode + 2 * operand + +typedef struct packed +{ + logic mult_we; + logic add_we; + logic sub_sel; + logic add_en; + logic mult_en; + logic mod_q_sel; +} pm_opcode_t; + +typedef struct packed +{ + pm_opcode_t opcode; + logic [OPR_ADDR_WIDTH-1 : 0] opa_addr; + logic [OPR_ADDR_WIDTH-1 : 0] opb_addr; +} pm_instr_struct_t; + +localparam pm_opcode_t UOP_NOP = '{mult_we:1'b0, add_we:1'b0, sub_sel:1'b0, add_en:1'b0, mult_en:1'b0, mod_q_sel:1'b0}; // = 6'b00_0000; +localparam pm_opcode_t UOP_DO_MUL_p = '{mult_we:1'b0, add_we:1'b0, sub_sel:1'b0, add_en:1'b0, mult_en:1'b1, mod_q_sel:1'b0}; // = 6'b01_0000; +localparam pm_opcode_t UOP_ST_MUL_p = '{mult_we:1'b1, add_we:1'b0, sub_sel:1'b0, add_en:1'b0, mult_en:1'b0, mod_q_sel:1'b0}; // = 6'b00_0001; +localparam pm_opcode_t UOP_DO_ADD_p = '{mult_we:1'b0, add_we:1'b0, sub_sel:1'b0, add_en:1'b1, mult_en:1'b0, mod_q_sel:1'b0}; // = 6'b00_1000; +localparam pm_opcode_t UOP_DO_SUB_p = '{mult_we:1'b0, add_we:1'b0, sub_sel:1'b1, add_en:1'b1, mult_en:1'b0, mod_q_sel:1'b0}; // = 6'b00_1100; +localparam pm_opcode_t UOP_ST_ADD_p = '{mult_we:1'b0, add_we:1'b1, sub_sel:1'b0, add_en:1'b0, mult_en:1'b0, mod_q_sel:1'b0}; // = 6'b00_0010; + +localparam pm_opcode_t UOP_DO_MUL_q = '{mult_we:1'b0, add_we:1'b0, sub_sel:1'b0, add_en:1'b0, mult_en:1'b1, mod_q_sel:1'b1}; // = 6'b11_0000; +localparam pm_opcode_t UOP_ST_MUL_q = '{mult_we:1'b1, add_we:1'b0, sub_sel:1'b0, add_en:1'b0, mult_en:1'b0, mod_q_sel:1'b1}; // = 6'b10_0001; +localparam pm_opcode_t UOP_DO_ADD_q = '{mult_we:1'b0, add_we:1'b0, sub_sel:1'b0, add_en:1'b1, mult_en:1'b0, mod_q_sel:1'b1}; // = 6'b10_1000; +localparam pm_opcode_t UOP_DO_SUB_q = '{mult_we:1'b0, add_we:1'b0, sub_sel:1'b1, add_en:1'b1, mult_en:1'b0, mod_q_sel:1'b1}; // = 6'b10_1100; +localparam pm_opcode_t UOP_ST_ADD_q = '{mult_we:1'b0, add_we:1'b1, sub_sel:1'b0, add_en:1'b0, mult_en:1'b0, mod_q_sel:1'b1}; // = 6'b10_0010; + +localparam [OPR_ADDR_WIDTH-1 : 0] UOP_OPR_DONTCARE = 6'd0; + +localparam [OPR_ADDR_WIDTH-1 : 0] UOP_OPR_CONST_ZERO = 6'd0; +localparam [OPR_ADDR_WIDTH-1 : 0] UOP_OPR_CONST_ONE = 6'd1; +localparam [OPR_ADDR_WIDTH-1 : 0] UOP_OPR_CONST_E_a = 6'd2; +localparam [OPR_ADDR_WIDTH-1 : 0] UOP_OPR_CONST_E_3b = 6'd3; +localparam [OPR_ADDR_WIDTH-1 : 0] UOP_OPR_CONST_ONE_MONT = 6'd4; // Mont_mult(1, R2) % p +localparam [OPR_ADDR_WIDTH-1 : 0] UOP_OPR_CONST_R2_p = 6'd5; + +localparam [OPR_ADDR_WIDTH-1 : 0] UOP_OPR_CONST_GX_MONT = 6'd6; +localparam [OPR_ADDR_WIDTH-1 : 0] UOP_OPR_CONST_GY_MONT = 6'd7; + +localparam [OPR_ADDR_WIDTH-1 : 0] UOP_OPR_R0_X = 6'd8; // 8'b0000_1000; +localparam [OPR_ADDR_WIDTH-1 : 0] UOP_OPR_R0_Y = 6'd9; // 8'b0000_1001; +localparam [OPR_ADDR_WIDTH-1 : 0] UOP_OPR_R0_Z = 6'd10; // 8'b0000_1010; + +localparam [OPR_ADDR_WIDTH-1 : 0] UOP_OPR_R1_X = 6'd12; // 8'b0000_1100; +localparam [OPR_ADDR_WIDTH-1 : 0] UOP_OPR_R1_Y = 6'd13; // 8'b0000_1101; +localparam [OPR_ADDR_WIDTH-1 : 0] UOP_OPR_R1_Z = 6'd14; // 8'b0000_1110; + +localparam [OPR_ADDR_WIDTH-1 : 0] UOP_OPR_Qx_AFFN = 6'd16; +localparam [OPR_ADDR_WIDTH-1 : 0] UOP_OPR_Qy_AFFN = 6'd17; + +localparam [OPR_ADDR_WIDTH-1 : 0] UOP_OPR_SIGN_R = 6'd18; +localparam [OPR_ADDR_WIDTH-1 : 0] UOP_OPR_SIGN_S = 6'd19; + +localparam [OPR_ADDR_WIDTH-1 : 0] UOP_OPR_PRIVKEY = 6'd20; +localparam [OPR_ADDR_WIDTH-1 : 0] UOP_OPR_HASH_MSG = 6'd21; +localparam [OPR_ADDR_WIDTH-1 : 0] UOP_OPR_SCALAR_G = 6'd22; +localparam [OPR_ADDR_WIDTH-1 : 0] UOP_OPR_SCALAR_PK = 6'd23; + +localparam [OPR_ADDR_WIDTH-1 : 0] UOP_OPR_LAMBDA = 6'd24; +localparam [OPR_ADDR_WIDTH-1 : 0] UOP_OPR_MASKING = 6'd25; + +localparam [OPR_ADDR_WIDTH-1 : 0] UOP_OPR_CONST_ONE_q_MONT = 6'd28; // Mont_mult(1, R2) % q +localparam [OPR_ADDR_WIDTH-1 : 0] UOP_OPR_CONST_R2_q = 6'd29; + +localparam [OPR_ADDR_WIDTH-1 : 0] UOP_OPR_A = 6'd32; +localparam [OPR_ADDR_WIDTH-1 : 0] UOP_OPR_B = 6'd33; +localparam [OPR_ADDR_WIDTH-1 : 0] UOP_OPR_C = 6'd34; +localparam [OPR_ADDR_WIDTH-1 : 0] UOP_OPR_D = 6'd35; +localparam [OPR_ADDR_WIDTH-1 : 0] UOP_OPR_E = 6'd36; +localparam [OPR_ADDR_WIDTH-1 : 0] UOP_OPR_F = 6'd37; +localparam [OPR_ADDR_WIDTH-1 : 0] UOP_OPR_G = 6'd38; +localparam [OPR_ADDR_WIDTH-1 : 0] UOP_OPR_H = 6'd39; +localparam [OPR_ADDR_WIDTH-1 : 0] UOP_OPR_J = 6'd40; + +localparam [OPR_ADDR_WIDTH-1 : 0] UOP_OPR_INV_IN = UOP_OPR_R0_Z; // operand to be inverted +localparam [OPR_ADDR_WIDTH-1 : 0] UOP_OPR_INV_PRE0 = 6'd41; // precomputed value based on UOP_OPR_Z_INV +localparam [OPR_ADDR_WIDTH-1 : 0] UOP_OPR_INV_PRE1 = 6'd42; +localparam [OPR_ADDR_WIDTH-1 : 0] UOP_OPR_INV_PRE2 = 6'd43; +localparam [OPR_ADDR_WIDTH-1 : 0] UOP_OPR_INV_PRE3 = 6'd44; +localparam [OPR_ADDR_WIDTH-1 : 0] UOP_OPR_INV_PRE4 = 6'd45; +localparam [OPR_ADDR_WIDTH-1 : 0] UOP_OPR_INV_PRE5 = 6'd46; +localparam [OPR_ADDR_WIDTH-1 : 0] UOP_OPR_INV_PRE6 = 6'd47; +localparam [OPR_ADDR_WIDTH-1 : 0] UOP_OPR_INV_PRE7 = 6'd48; +localparam [OPR_ADDR_WIDTH-1 : 0] UOP_OPR_A_INV = 6'd49; // intermediate results during inversion +localparam [OPR_ADDR_WIDTH-1 : 0] UOP_OPR_INV_OUT = 6'd50; + +localparam [OPR_ADDR_WIDTH-1 : 0] UOP_OPR_Qx_MONT = 6'd51; +localparam [OPR_ADDR_WIDTH-1 : 0] UOP_OPR_Qy_MONT = 6'd52; + +localparam [OPR_ADDR_WIDTH-1 : 0] UOP_OPR_P1_X_MONT = 6'd53; +localparam [OPR_ADDR_WIDTH-1 : 0] UOP_OPR_P1_Y_MONT = 6'd54; +localparam [OPR_ADDR_WIDTH-1 : 0] UOP_OPR_P1_Z_MONT = 6'd55; + +localparam [OPR_ADDR_WIDTH-1 : 0] UOP_OPR_CONST_E_b = 6'd56; +localparam [OPR_ADDR_WIDTH-1 : 0] UOP_OPR_PK_VALID = 6'd57; + +//PM command listing +localparam [3 : 0] KEYGEN_CMD = 4'b0001; +localparam [3 : 0] SIGN_CMD = 4'b0010; +localparam [3 : 0] VER_PART0_CMD = 4'b0100; +localparam [3 : 0] VER_PART1_CMD = 4'b0101; +localparam [3 : 0] VER_PART2_CMD = 4'b0110; +localparam [3 : 0] CHK_PK_CMD = 4'b0111; +localparam [3 : 0] DH_SHARED_CMD = 4'b1000; + +//PM Subroutine listing +localparam [PROG_ADDR_W-1 : 0] NOP = 12'd0; +localparam [PROG_ADDR_W-1 : 0] PM_INIT_G_S = 12'd2; // R1 INIT with G +localparam [PROG_ADDR_W-1 : 0] PM_INIT_G_E = PM_INIT_G_S + 5; +localparam [PROG_ADDR_W-1 : 0] PM_INIT_S = PM_INIT_G_E + 2; // R0 INIT with O +localparam [PROG_ADDR_W-1 : 0] PM_INIT_E = PM_INIT_S + 9; +localparam [PROG_ADDR_W-1 : 0] PA_S = PM_INIT_E + 2; // Point Addition +localparam [PROG_ADDR_W-1 : 0] PA_E = PA_S + 79; +localparam [PROG_ADDR_W-1 : 0] PD_S = PA_E + 2; // Point Doubling +localparam [PROG_ADDR_W-1 : 0] PD_E = PD_S + 83; +localparam [PROG_ADDR_W-1 : 0] INV_S = PD_E + 2; // Inversion mod p +localparam [PROG_ADDR_W-1 : 0] INV_E = INV_S + 1039; +localparam [PROG_ADDR_W-1 : 0] CONV_S = INV_E + 2; // PM result conversion from projective Mont (X,Y,Z) to affine normanl (x,y) +localparam [PROG_ADDR_W-1 : 0] CONV_E = CONV_S + 11; + +localparam [PROG_ADDR_W-1 : 0] SIGN0_S = CONV_E + 2; // signing proof r part0 +localparam [PROG_ADDR_W-1 : 0] SIGN0_E = SIGN0_S + 27; +localparam [PROG_ADDR_W-1 : 0] INVq_S = SIGN0_E + 2; // Inversion mod q +localparam [PROG_ADDR_W-1 : 0] INVq_E = INVq_S + 1043; +localparam [PROG_ADDR_W-1 : 0] SIGN1_S = INVq_E + 2; // signing proof r part1 +localparam [PROG_ADDR_W-1 : 0] SIGN1_E = SIGN1_S + 11; + +localparam [PROG_ADDR_W-1 : 0] CHK_PK_S = SIGN1_E + 2; // check the given public key is a valid curve point +localparam [PROG_ADDR_W-1 : 0] CHK_PK_E = CHK_PK_S + 21; +localparam [PROG_ADDR_W-1 : 0] VER0_P0_S = CHK_PK_E + 2; // verifying0 part0 to convert inputs to Mont domain +localparam [PROG_ADDR_W-1 : 0] VER0_P0_E = VER0_P0_S + 9; +localparam [PROG_ADDR_W-1 : 0] VER0_P1_S = VER0_P0_E + 2; // verifying0 part1 to compute (h*s_inv) and (r*s_inv) +localparam [PROG_ADDR_W-1 : 0] VER0_P1_E = VER0_P1_S + 11; +localparam [PROG_ADDR_W-1 : 0] VER1_ST_S = VER0_P1_E + 2; // verifying1 store ver1 result (h*s_inv)*G +localparam [PROG_ADDR_W-1 : 0] VER1_ST_E = VER1_ST_S + 5; +localparam [PROG_ADDR_W-1 : 0] PM_INIT_PK_S = VER1_ST_E + 2; // verifying2 R1 INIT with PK +localparam [PROG_ADDR_W-1 : 0] PM_INIT_PK_E = PM_INIT_PK_S + 5; +localparam [PROG_ADDR_W-1 : 0] VER2_PA_S = PM_INIT_PK_E + 2; // verifying2 point addtion of PA((h*s_inv)*G, (r*s_inv)*PK) +localparam [PROG_ADDR_W-1 : 0] VER2_PA_E = VER2_PA_S + 81; + +localparam [PROG_ADDR_W-1 : 0] PM_INIT_DH_S = VER2_PA_E + 2; // Deffie-Helman Shared Key R1 INIT with PK +localparam [PROG_ADDR_W-1 : 0] PM_INIT_DH_E = PM_INIT_DH_S + 9; + +endpackage + +`endif diff --git a/designs/Caliptra/src/caliptra-rtl/ecc_ram_tdp_file.sv b/designs/Caliptra/src/caliptra-rtl/ecc_ram_tdp_file.sv new file mode 100644 index 0000000..01131bb --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/ecc_ram_tdp_file.sv @@ -0,0 +1,88 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +// +//====================================================================== +// +// ecc_ram_tdp_file.sv +// -------- +// ECC Data Memory to store intermediate results from point multiplication. +// +// +//====================================================================== + +module ecc_ram_tdp_file #( + parameter ADDR_WIDTH = 10, + parameter DATA_WIDTH = 32 + ) + ( + input wire clk, + input wire reset_n, + input wire zeroize, + + input wire ena, + input wire wea, + input wire [ADDR_WIDTH-1 : 0] addra, + input wire [DATA_WIDTH-1 : 0] dina, + output logic [DATA_WIDTH-1 : 0] douta, + + input wire enb, + input wire web, + input wire [ADDR_WIDTH-1 : 0] addrb, + input wire [DATA_WIDTH-1 : 0] dinb, + output logic [DATA_WIDTH-1 : 0] doutb + ); + + // Declare the RAM variable + localparam ADDR_LENGTH = 2**ADDR_WIDTH; + reg [DATA_WIDTH-1:0] mem[ADDR_LENGTH-1:0]; + + always_ff @ (posedge clk or negedge reset_n) + begin : reading_memory + if (!reset_n) begin + douta <= '0; + doutb <= '0; + end + else if (zeroize) begin + douta <= '0; + doutb <= '0; + end + else begin + if (ena) + douta <= mem[addra]; + + if (enb) + doutb <= mem[addrb]; + end + end // reading_memory + + always_ff @ (posedge clk or negedge reset_n) + begin : writing_memory + if (!reset_n) begin + for (int i0 = 0; i0 < ADDR_LENGTH; i0++) + mem[i0] <= '0; + end + else if (zeroize) begin + for (int i0 = 0; i0 < ADDR_LENGTH; i0++) + mem[i0] <= '0; + end + else begin + if (ena & wea) + mem[addra] <= dina; + + if (enb & web) + mem[addrb] <= dinb; + end + end // writing_memory + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/ecc_reg.sv b/designs/Caliptra/src/caliptra-rtl/ecc_reg.sv new file mode 100644 index 0000000..e92a2fd --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/ecc_reg.sv @@ -0,0 +1,2110 @@ +// Generated by PeakRDL-regblock - A free and open-source SystemVerilog generator +// https://github.com/SystemRDL/PeakRDL-regblock + +module ecc_reg ( + input wire clk, + input wire rst, + + input wire s_cpuif_req, + input wire s_cpuif_req_is_wr, + input wire [11:0] s_cpuif_addr, + input wire [31:0] s_cpuif_wr_data, + input wire [31:0] s_cpuif_wr_biten, + output wire s_cpuif_req_stall_wr, + output wire s_cpuif_req_stall_rd, + output wire s_cpuif_rd_ack, + output wire s_cpuif_rd_err, + output wire [31:0] s_cpuif_rd_data, + output wire s_cpuif_wr_ack, + output wire s_cpuif_wr_err, + + input ecc_reg_pkg::ecc_reg__in_t hwif_in, + output ecc_reg_pkg::ecc_reg__out_t hwif_out + ); + + //-------------------------------------------------------------------------- + // CPU Bus interface logic + //-------------------------------------------------------------------------- + logic cpuif_req; + logic cpuif_req_is_wr; + logic [11:0] cpuif_addr; + logic [31:0] cpuif_wr_data; + logic [31:0] cpuif_wr_biten; + logic cpuif_req_stall_wr; + logic cpuif_req_stall_rd; + + logic cpuif_rd_ack; + logic cpuif_rd_err; + logic [31:0] cpuif_rd_data; + + logic cpuif_wr_ack; + logic cpuif_wr_err; + + assign cpuif_req = s_cpuif_req; + assign cpuif_req_is_wr = s_cpuif_req_is_wr; + assign cpuif_addr = s_cpuif_addr; + assign cpuif_wr_data = s_cpuif_wr_data; + assign cpuif_wr_biten = s_cpuif_wr_biten; + assign s_cpuif_req_stall_wr = cpuif_req_stall_wr; + assign s_cpuif_req_stall_rd = cpuif_req_stall_rd; + assign s_cpuif_rd_ack = cpuif_rd_ack; + assign s_cpuif_rd_err = cpuif_rd_err; + assign s_cpuif_rd_data = cpuif_rd_data; + assign s_cpuif_wr_ack = cpuif_wr_ack; + assign s_cpuif_wr_err = cpuif_wr_err; + + logic cpuif_req_masked; + + // Read & write latencies are balanced. Stalls not required + assign cpuif_req_stall_rd = '0; + assign cpuif_req_stall_wr = '0; + assign cpuif_req_masked = cpuif_req + & !(!cpuif_req_is_wr & cpuif_req_stall_rd) + & !(cpuif_req_is_wr & cpuif_req_stall_wr); + + //-------------------------------------------------------------------------- + // Address Decode + //-------------------------------------------------------------------------- + typedef struct packed{ + logic [2-1:0]ECC_NAME; + logic [2-1:0]ECC_VERSION; + logic ECC_CTRL; + logic ECC_STATUS; + logic [12-1:0]ECC_SEED; + logic [12-1:0]ECC_MSG; + logic [12-1:0]ECC_PRIVKEY_OUT; + logic [12-1:0]ECC_PUBKEY_X; + logic [12-1:0]ECC_PUBKEY_Y; + logic [12-1:0]ECC_SIGN_R; + logic [12-1:0]ECC_SIGN_S; + logic [12-1:0]ECC_VERIFY_R; + logic [12-1:0]ECC_IV; + logic [12-1:0]ECC_NONCE; + logic [12-1:0]ECC_PRIVKEY_IN; + logic [12-1:0]ECC_DH_SHARED_KEY; + logic ecc_kv_rd_pkey_ctrl; + logic ecc_kv_rd_pkey_status; + logic ecc_kv_rd_seed_ctrl; + logic ecc_kv_rd_seed_status; + logic ecc_kv_wr_pkey_ctrl; + logic ecc_kv_wr_pkey_status; + struct packed{ + logic global_intr_en_r; + logic error_intr_en_r; + logic notif_intr_en_r; + logic error_global_intr_r; + logic notif_global_intr_r; + logic error_internal_intr_r; + logic notif_internal_intr_r; + logic error_intr_trig_r; + logic notif_intr_trig_r; + logic error_internal_intr_count_r; + logic notif_cmd_done_intr_count_r; + logic error_internal_intr_count_incr_r; + logic notif_cmd_done_intr_count_incr_r; + } intr_block_rf; + } decoded_reg_strb_t; + decoded_reg_strb_t decoded_reg_strb; + logic decoded_req; + logic decoded_req_is_wr; + logic [31:0] decoded_wr_data; + logic [31:0] decoded_wr_biten; + + always_comb begin + for(int i0=0; i0<2; i0++) begin + decoded_reg_strb.ECC_NAME[i0] = cpuif_req_masked & (cpuif_addr == 12'h0 + i0*12'h4); + end + for(int i0=0; i0<2; i0++) begin + decoded_reg_strb.ECC_VERSION[i0] = cpuif_req_masked & (cpuif_addr == 12'h8 + i0*12'h4); + end + decoded_reg_strb.ECC_CTRL = cpuif_req_masked & (cpuif_addr == 12'h10); + decoded_reg_strb.ECC_STATUS = cpuif_req_masked & (cpuif_addr == 12'h18); + for(int i0=0; i0<12; i0++) begin + decoded_reg_strb.ECC_SEED[i0] = cpuif_req_masked & (cpuif_addr == 12'h80 + i0*12'h4); + end + for(int i0=0; i0<12; i0++) begin + decoded_reg_strb.ECC_MSG[i0] = cpuif_req_masked & (cpuif_addr == 12'h100 + i0*12'h4); + end + for(int i0=0; i0<12; i0++) begin + decoded_reg_strb.ECC_PRIVKEY_OUT[i0] = cpuif_req_masked & (cpuif_addr == 12'h180 + i0*12'h4); + end + for(int i0=0; i0<12; i0++) begin + decoded_reg_strb.ECC_PUBKEY_X[i0] = cpuif_req_masked & (cpuif_addr == 12'h200 + i0*12'h4); + end + for(int i0=0; i0<12; i0++) begin + decoded_reg_strb.ECC_PUBKEY_Y[i0] = cpuif_req_masked & (cpuif_addr == 12'h280 + i0*12'h4); + end + for(int i0=0; i0<12; i0++) begin + decoded_reg_strb.ECC_SIGN_R[i0] = cpuif_req_masked & (cpuif_addr == 12'h300 + i0*12'h4); + end + for(int i0=0; i0<12; i0++) begin + decoded_reg_strb.ECC_SIGN_S[i0] = cpuif_req_masked & (cpuif_addr == 12'h380 + i0*12'h4); + end + for(int i0=0; i0<12; i0++) begin + decoded_reg_strb.ECC_VERIFY_R[i0] = cpuif_req_masked & (cpuif_addr == 12'h400 + i0*12'h4); + end + for(int i0=0; i0<12; i0++) begin + decoded_reg_strb.ECC_IV[i0] = cpuif_req_masked & (cpuif_addr == 12'h480 + i0*12'h4); + end + for(int i0=0; i0<12; i0++) begin + decoded_reg_strb.ECC_NONCE[i0] = cpuif_req_masked & (cpuif_addr == 12'h500 + i0*12'h4); + end + for(int i0=0; i0<12; i0++) begin + decoded_reg_strb.ECC_PRIVKEY_IN[i0] = cpuif_req_masked & (cpuif_addr == 12'h580 + i0*12'h4); + end + for(int i0=0; i0<12; i0++) begin + decoded_reg_strb.ECC_DH_SHARED_KEY[i0] = cpuif_req_masked & (cpuif_addr == 12'h5c0 + i0*12'h4); + end + decoded_reg_strb.ecc_kv_rd_pkey_ctrl = cpuif_req_masked & (cpuif_addr == 12'h600); + decoded_reg_strb.ecc_kv_rd_pkey_status = cpuif_req_masked & (cpuif_addr == 12'h604); + decoded_reg_strb.ecc_kv_rd_seed_ctrl = cpuif_req_masked & (cpuif_addr == 12'h608); + decoded_reg_strb.ecc_kv_rd_seed_status = cpuif_req_masked & (cpuif_addr == 12'h60c); + decoded_reg_strb.ecc_kv_wr_pkey_ctrl = cpuif_req_masked & (cpuif_addr == 12'h610); + decoded_reg_strb.ecc_kv_wr_pkey_status = cpuif_req_masked & (cpuif_addr == 12'h614); + decoded_reg_strb.intr_block_rf.global_intr_en_r = cpuif_req_masked & (cpuif_addr == 12'h800); + decoded_reg_strb.intr_block_rf.error_intr_en_r = cpuif_req_masked & (cpuif_addr == 12'h804); + decoded_reg_strb.intr_block_rf.notif_intr_en_r = cpuif_req_masked & (cpuif_addr == 12'h808); + decoded_reg_strb.intr_block_rf.error_global_intr_r = cpuif_req_masked & (cpuif_addr == 12'h80c); + decoded_reg_strb.intr_block_rf.notif_global_intr_r = cpuif_req_masked & (cpuif_addr == 12'h810); + decoded_reg_strb.intr_block_rf.error_internal_intr_r = cpuif_req_masked & (cpuif_addr == 12'h814); + decoded_reg_strb.intr_block_rf.notif_internal_intr_r = cpuif_req_masked & (cpuif_addr == 12'h818); + decoded_reg_strb.intr_block_rf.error_intr_trig_r = cpuif_req_masked & (cpuif_addr == 12'h81c); + decoded_reg_strb.intr_block_rf.notif_intr_trig_r = cpuif_req_masked & (cpuif_addr == 12'h820); + decoded_reg_strb.intr_block_rf.error_internal_intr_count_r = cpuif_req_masked & (cpuif_addr == 12'h900); + decoded_reg_strb.intr_block_rf.notif_cmd_done_intr_count_r = cpuif_req_masked & (cpuif_addr == 12'h980); + decoded_reg_strb.intr_block_rf.error_internal_intr_count_incr_r = cpuif_req_masked & (cpuif_addr == 12'ha00); + decoded_reg_strb.intr_block_rf.notif_cmd_done_intr_count_incr_r = cpuif_req_masked & (cpuif_addr == 12'ha04); + end + + // Pass down signals to next stage + assign decoded_req = cpuif_req_masked; + assign decoded_req_is_wr = cpuif_req_is_wr; + assign decoded_wr_data = cpuif_wr_data; + assign decoded_wr_biten = cpuif_wr_biten; + + //-------------------------------------------------------------------------- + // Field logic + //-------------------------------------------------------------------------- + typedef struct packed{ + struct packed{ + struct packed{ + logic [1:0] next; + logic load_next; + } CTRL; + struct packed{ + logic next; + logic load_next; + } ZEROIZE; + struct packed{ + logic next; + logic load_next; + } PCR_SIGN; + struct packed{ + logic next; + logic load_next; + } DH_SHAREDKEY; + } ECC_CTRL; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } SEED; + } [12-1:0]ECC_SEED; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } MSG; + } [12-1:0]ECC_MSG; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } PRIVKEY_OUT; + } [12-1:0]ECC_PRIVKEY_OUT; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } PUBKEY_X; + } [12-1:0]ECC_PUBKEY_X; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } PUBKEY_Y; + } [12-1:0]ECC_PUBKEY_Y; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } SIGN_R; + } [12-1:0]ECC_SIGN_R; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } SIGN_S; + } [12-1:0]ECC_SIGN_S; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } VERIFY_R; + } [12-1:0]ECC_VERIFY_R; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } IV; + } [12-1:0]ECC_IV; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } NONCE; + } [12-1:0]ECC_NONCE; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } PRIVKEY_IN; + } [12-1:0]ECC_PRIVKEY_IN; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } DH_SHARED_KEY; + } [12-1:0]ECC_DH_SHARED_KEY; + struct packed{ + struct packed{ + logic next; + logic load_next; + } read_en; + struct packed{ + logic [4:0] next; + logic load_next; + } read_entry; + struct packed{ + logic next; + logic load_next; + } pcr_hash_extend; + struct packed{ + logic [24:0] next; + logic load_next; + } rsvd; + } ecc_kv_rd_pkey_ctrl; + struct packed{ + struct packed{ + logic next; + logic load_next; + } VALID; + } ecc_kv_rd_pkey_status; + struct packed{ + struct packed{ + logic next; + logic load_next; + } read_en; + struct packed{ + logic [4:0] next; + logic load_next; + } read_entry; + struct packed{ + logic next; + logic load_next; + } pcr_hash_extend; + struct packed{ + logic [24:0] next; + logic load_next; + } rsvd; + } ecc_kv_rd_seed_ctrl; + struct packed{ + struct packed{ + logic next; + logic load_next; + } VALID; + } ecc_kv_rd_seed_status; + struct packed{ + struct packed{ + logic next; + logic load_next; + } write_en; + struct packed{ + logic [4:0] next; + logic load_next; + } write_entry; + struct packed{ + logic next; + logic load_next; + } hmac_key_dest_valid; + struct packed{ + logic next; + logic load_next; + } hmac_block_dest_valid; + struct packed{ + logic next; + logic load_next; + } mldsa_seed_dest_valid; + struct packed{ + logic next; + logic load_next; + } ecc_pkey_dest_valid; + struct packed{ + logic next; + logic load_next; + } ecc_seed_dest_valid; + struct packed{ + logic next; + logic load_next; + } aes_key_dest_valid; + struct packed{ + logic next; + logic load_next; + } mlkem_seed_dest_valid; + struct packed{ + logic next; + logic load_next; + } mlkem_msg_dest_valid; + struct packed{ + logic next; + logic load_next; + } dma_data_dest_valid; + struct packed{ + logic [16:0] next; + logic load_next; + } rsvd; + } ecc_kv_wr_pkey_ctrl; + struct packed{ + struct packed{ + logic next; + logic load_next; + } VALID; + } ecc_kv_wr_pkey_status; + struct packed{ + struct packed{ + struct packed{ + logic next; + logic load_next; + } error_en; + struct packed{ + logic next; + logic load_next; + } notif_en; + } global_intr_en_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + } error_internal_en; + } error_intr_en_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + } notif_cmd_done_en; + } notif_intr_en_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + } agg_sts; + } error_global_intr_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + } agg_sts; + } notif_global_intr_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + } error_internal_sts; + } error_internal_intr_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + } notif_cmd_done_sts; + } notif_internal_intr_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + } error_internal_trig; + } error_intr_trig_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + } notif_cmd_done_trig; + } notif_intr_trig_r; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + logic incrthreshold; + logic incrsaturate; + } cnt; + } error_internal_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + logic incrthreshold; + logic incrsaturate; + } cnt; + } notif_cmd_done_intr_count_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + logic decrthreshold; + logic underflow; + } pulse; + } error_internal_intr_count_incr_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + logic decrthreshold; + logic underflow; + } pulse; + } notif_cmd_done_intr_count_incr_r; + } intr_block_rf; + } field_combo_t; + field_combo_t field_combo; + + typedef struct packed{ + struct packed{ + struct packed{ + logic [1:0] value; + } CTRL; + struct packed{ + logic value; + } ZEROIZE; + struct packed{ + logic value; + } PCR_SIGN; + struct packed{ + logic value; + } DH_SHAREDKEY; + } ECC_CTRL; + struct packed{ + struct packed{ + logic [31:0] value; + } SEED; + } [12-1:0]ECC_SEED; + struct packed{ + struct packed{ + logic [31:0] value; + } MSG; + } [12-1:0]ECC_MSG; + struct packed{ + struct packed{ + logic [31:0] value; + } PRIVKEY_OUT; + } [12-1:0]ECC_PRIVKEY_OUT; + struct packed{ + struct packed{ + logic [31:0] value; + } PUBKEY_X; + } [12-1:0]ECC_PUBKEY_X; + struct packed{ + struct packed{ + logic [31:0] value; + } PUBKEY_Y; + } [12-1:0]ECC_PUBKEY_Y; + struct packed{ + struct packed{ + logic [31:0] value; + } SIGN_R; + } [12-1:0]ECC_SIGN_R; + struct packed{ + struct packed{ + logic [31:0] value; + } SIGN_S; + } [12-1:0]ECC_SIGN_S; + struct packed{ + struct packed{ + logic [31:0] value; + } VERIFY_R; + } [12-1:0]ECC_VERIFY_R; + struct packed{ + struct packed{ + logic [31:0] value; + } IV; + } [12-1:0]ECC_IV; + struct packed{ + struct packed{ + logic [31:0] value; + } NONCE; + } [12-1:0]ECC_NONCE; + struct packed{ + struct packed{ + logic [31:0] value; + } PRIVKEY_IN; + } [12-1:0]ECC_PRIVKEY_IN; + struct packed{ + struct packed{ + logic [31:0] value; + } DH_SHARED_KEY; + } [12-1:0]ECC_DH_SHARED_KEY; + struct packed{ + struct packed{ + logic value; + } read_en; + struct packed{ + logic [4:0] value; + } read_entry; + struct packed{ + logic value; + } pcr_hash_extend; + struct packed{ + logic [24:0] value; + } rsvd; + } ecc_kv_rd_pkey_ctrl; + struct packed{ + struct packed{ + logic value; + } VALID; + } ecc_kv_rd_pkey_status; + struct packed{ + struct packed{ + logic value; + } read_en; + struct packed{ + logic [4:0] value; + } read_entry; + struct packed{ + logic value; + } pcr_hash_extend; + struct packed{ + logic [24:0] value; + } rsvd; + } ecc_kv_rd_seed_ctrl; + struct packed{ + struct packed{ + logic value; + } VALID; + } ecc_kv_rd_seed_status; + struct packed{ + struct packed{ + logic value; + } write_en; + struct packed{ + logic [4:0] value; + } write_entry; + struct packed{ + logic value; + } hmac_key_dest_valid; + struct packed{ + logic value; + } hmac_block_dest_valid; + struct packed{ + logic value; + } mldsa_seed_dest_valid; + struct packed{ + logic value; + } ecc_pkey_dest_valid; + struct packed{ + logic value; + } ecc_seed_dest_valid; + struct packed{ + logic value; + } aes_key_dest_valid; + struct packed{ + logic value; + } mlkem_seed_dest_valid; + struct packed{ + logic value; + } mlkem_msg_dest_valid; + struct packed{ + logic value; + } dma_data_dest_valid; + struct packed{ + logic [16:0] value; + } rsvd; + } ecc_kv_wr_pkey_ctrl; + struct packed{ + struct packed{ + logic value; + } VALID; + } ecc_kv_wr_pkey_status; + struct packed{ + struct packed{ + struct packed{ + logic value; + } error_en; + struct packed{ + logic value; + } notif_en; + } global_intr_en_r; + struct packed{ + struct packed{ + logic value; + } error_internal_en; + } error_intr_en_r; + struct packed{ + struct packed{ + logic value; + } notif_cmd_done_en; + } notif_intr_en_r; + struct packed{ + struct packed{ + logic value; + } agg_sts; + } error_global_intr_r; + struct packed{ + struct packed{ + logic value; + } agg_sts; + } notif_global_intr_r; + struct packed{ + struct packed{ + logic value; + } error_internal_sts; + } error_internal_intr_r; + struct packed{ + struct packed{ + logic value; + } notif_cmd_done_sts; + } notif_internal_intr_r; + struct packed{ + struct packed{ + logic value; + } error_internal_trig; + } error_intr_trig_r; + struct packed{ + struct packed{ + logic value; + } notif_cmd_done_trig; + } notif_intr_trig_r; + struct packed{ + struct packed{ + logic [31:0] value; + } cnt; + } error_internal_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] value; + } cnt; + } notif_cmd_done_intr_count_r; + struct packed{ + struct packed{ + logic value; + } pulse; + } error_internal_intr_count_incr_r; + struct packed{ + struct packed{ + logic value; + } pulse; + } notif_cmd_done_intr_count_incr_r; + } intr_block_rf; + } field_storage_t; + field_storage_t field_storage; + + // Field: ecc_reg.ECC_CTRL.CTRL + always_comb begin + automatic logic [1:0] next_c; + automatic logic load_next_c; + next_c = field_storage.ECC_CTRL.CTRL.value; + load_next_c = '0; + if(decoded_reg_strb.ECC_CTRL && decoded_req_is_wr && hwif_in.ecc_ready) begin // SW write + next_c = (field_storage.ECC_CTRL.CTRL.value & ~decoded_wr_biten[1:0]) | (decoded_wr_data[1:0] & decoded_wr_biten[1:0]); + load_next_c = '1; + end else if(hwif_in.ECC_CTRL.CTRL.hwclr) begin // HW Clear + next_c = '0; + load_next_c = '1; + end + field_combo.ECC_CTRL.CTRL.next = next_c; + field_combo.ECC_CTRL.CTRL.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.ECC_CTRL.CTRL.value <= 2'h0; + end else if(field_combo.ECC_CTRL.CTRL.load_next) begin + field_storage.ECC_CTRL.CTRL.value <= field_combo.ECC_CTRL.CTRL.next; + end + end + assign hwif_out.ECC_CTRL.CTRL.value = field_storage.ECC_CTRL.CTRL.value; + // Field: ecc_reg.ECC_CTRL.ZEROIZE + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.ECC_CTRL.ZEROIZE.value; + load_next_c = '0; + if(decoded_reg_strb.ECC_CTRL && decoded_req_is_wr) begin // SW write + next_c = (field_storage.ECC_CTRL.ZEROIZE.value & ~decoded_wr_biten[2:2]) | (decoded_wr_data[2:2] & decoded_wr_biten[2:2]); + load_next_c = '1; + end else begin // singlepulse clears back to 0 + next_c = '0; + load_next_c = '1; + end + field_combo.ECC_CTRL.ZEROIZE.next = next_c; + field_combo.ECC_CTRL.ZEROIZE.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.ECC_CTRL.ZEROIZE.value <= 1'h0; + end else if(field_combo.ECC_CTRL.ZEROIZE.load_next) begin + field_storage.ECC_CTRL.ZEROIZE.value <= field_combo.ECC_CTRL.ZEROIZE.next; + end + end + assign hwif_out.ECC_CTRL.ZEROIZE.value = field_storage.ECC_CTRL.ZEROIZE.value; + // Field: ecc_reg.ECC_CTRL.PCR_SIGN + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.ECC_CTRL.PCR_SIGN.value; + load_next_c = '0; + if(decoded_reg_strb.ECC_CTRL && decoded_req_is_wr && hwif_in.ecc_ready) begin // SW write + next_c = (field_storage.ECC_CTRL.PCR_SIGN.value & ~decoded_wr_biten[3:3]) | (decoded_wr_data[3:3] & decoded_wr_biten[3:3]); + load_next_c = '1; + end else if(hwif_in.ECC_CTRL.PCR_SIGN.hwclr) begin // HW Clear + next_c = '0; + load_next_c = '1; + end + field_combo.ECC_CTRL.PCR_SIGN.next = next_c; + field_combo.ECC_CTRL.PCR_SIGN.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.ECC_CTRL.PCR_SIGN.value <= 1'h0; + end else if(field_combo.ECC_CTRL.PCR_SIGN.load_next) begin + field_storage.ECC_CTRL.PCR_SIGN.value <= field_combo.ECC_CTRL.PCR_SIGN.next; + end + end + assign hwif_out.ECC_CTRL.PCR_SIGN.value = field_storage.ECC_CTRL.PCR_SIGN.value; + // Field: ecc_reg.ECC_CTRL.DH_SHAREDKEY + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.ECC_CTRL.DH_SHAREDKEY.value; + load_next_c = '0; + if(decoded_reg_strb.ECC_CTRL && decoded_req_is_wr && hwif_in.ecc_ready) begin // SW write + next_c = (field_storage.ECC_CTRL.DH_SHAREDKEY.value & ~decoded_wr_biten[4:4]) | (decoded_wr_data[4:4] & decoded_wr_biten[4:4]); + load_next_c = '1; + end else if(hwif_in.ECC_CTRL.DH_SHAREDKEY.hwclr) begin // HW Clear + next_c = '0; + load_next_c = '1; + end + field_combo.ECC_CTRL.DH_SHAREDKEY.next = next_c; + field_combo.ECC_CTRL.DH_SHAREDKEY.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.ECC_CTRL.DH_SHAREDKEY.value <= 1'h0; + end else if(field_combo.ECC_CTRL.DH_SHAREDKEY.load_next) begin + field_storage.ECC_CTRL.DH_SHAREDKEY.value <= field_combo.ECC_CTRL.DH_SHAREDKEY.next; + end + end + assign hwif_out.ECC_CTRL.DH_SHAREDKEY.value = field_storage.ECC_CTRL.DH_SHAREDKEY.value; + for(genvar i0=0; i0<12; i0++) begin + // Field: ecc_reg.ECC_SEED[].SEED + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.ECC_SEED[i0].SEED.value; + load_next_c = '0; + if(decoded_reg_strb.ECC_SEED[i0] && decoded_req_is_wr && hwif_in.ECC_SEED[i0].SEED.swwe) begin // SW write + next_c = (field_storage.ECC_SEED[i0].SEED.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end else if(hwif_in.ECC_SEED[i0].SEED.we) begin // HW Write - we + next_c = hwif_in.ECC_SEED[i0].SEED.next; + load_next_c = '1; + end else if(hwif_in.ECC_SEED[i0].SEED.hwclr) begin // HW Clear + next_c = '0; + load_next_c = '1; + end + field_combo.ECC_SEED[i0].SEED.next = next_c; + field_combo.ECC_SEED[i0].SEED.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.ECC_SEED[i0].SEED.value <= 32'h0; + end else if(field_combo.ECC_SEED[i0].SEED.load_next) begin + field_storage.ECC_SEED[i0].SEED.value <= field_combo.ECC_SEED[i0].SEED.next; + end + end + assign hwif_out.ECC_SEED[i0].SEED.value = field_storage.ECC_SEED[i0].SEED.value; + end + for(genvar i0=0; i0<12; i0++) begin + // Field: ecc_reg.ECC_MSG[].MSG + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.ECC_MSG[i0].MSG.value; + load_next_c = '0; + if(decoded_reg_strb.ECC_MSG[i0] && decoded_req_is_wr && hwif_in.ecc_ready) begin // SW write + next_c = (field_storage.ECC_MSG[i0].MSG.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end else if(hwif_in.ECC_MSG[i0].MSG.we) begin // HW Write - we + next_c = hwif_in.ECC_MSG[i0].MSG.next; + load_next_c = '1; + end else if(hwif_in.ECC_MSG[i0].MSG.hwclr) begin // HW Clear + next_c = '0; + load_next_c = '1; + end + field_combo.ECC_MSG[i0].MSG.next = next_c; + field_combo.ECC_MSG[i0].MSG.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.ECC_MSG[i0].MSG.value <= 32'h0; + end else if(field_combo.ECC_MSG[i0].MSG.load_next) begin + field_storage.ECC_MSG[i0].MSG.value <= field_combo.ECC_MSG[i0].MSG.next; + end + end + assign hwif_out.ECC_MSG[i0].MSG.value = field_storage.ECC_MSG[i0].MSG.value; + end + for(genvar i0=0; i0<12; i0++) begin + // Field: ecc_reg.ECC_PRIVKEY_OUT[].PRIVKEY_OUT + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.ECC_PRIVKEY_OUT[i0].PRIVKEY_OUT.value; + load_next_c = '0; + if(hwif_in.ECC_PRIVKEY_OUT[i0].PRIVKEY_OUT.we) begin // HW Write - we + next_c = hwif_in.ECC_PRIVKEY_OUT[i0].PRIVKEY_OUT.next; + load_next_c = '1; + end else if(hwif_in.ECC_PRIVKEY_OUT[i0].PRIVKEY_OUT.hwclr) begin // HW Clear + next_c = '0; + load_next_c = '1; + end + field_combo.ECC_PRIVKEY_OUT[i0].PRIVKEY_OUT.next = next_c; + field_combo.ECC_PRIVKEY_OUT[i0].PRIVKEY_OUT.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.ECC_PRIVKEY_OUT[i0].PRIVKEY_OUT.value <= 32'h0; + end else if(field_combo.ECC_PRIVKEY_OUT[i0].PRIVKEY_OUT.load_next) begin + field_storage.ECC_PRIVKEY_OUT[i0].PRIVKEY_OUT.value <= field_combo.ECC_PRIVKEY_OUT[i0].PRIVKEY_OUT.next; + end + end + end + for(genvar i0=0; i0<12; i0++) begin + // Field: ecc_reg.ECC_PUBKEY_X[].PUBKEY_X + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.ECC_PUBKEY_X[i0].PUBKEY_X.value; + load_next_c = '0; + if(decoded_reg_strb.ECC_PUBKEY_X[i0] && decoded_req_is_wr && hwif_in.ecc_ready) begin // SW write + next_c = (field_storage.ECC_PUBKEY_X[i0].PUBKEY_X.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end else if(hwif_in.ECC_PUBKEY_X[i0].PUBKEY_X.we) begin // HW Write - we + next_c = hwif_in.ECC_PUBKEY_X[i0].PUBKEY_X.next; + load_next_c = '1; + end else if(hwif_in.ECC_PUBKEY_X[i0].PUBKEY_X.hwclr) begin // HW Clear + next_c = '0; + load_next_c = '1; + end + field_combo.ECC_PUBKEY_X[i0].PUBKEY_X.next = next_c; + field_combo.ECC_PUBKEY_X[i0].PUBKEY_X.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.ECC_PUBKEY_X[i0].PUBKEY_X.value <= 32'h0; + end else if(field_combo.ECC_PUBKEY_X[i0].PUBKEY_X.load_next) begin + field_storage.ECC_PUBKEY_X[i0].PUBKEY_X.value <= field_combo.ECC_PUBKEY_X[i0].PUBKEY_X.next; + end + end + assign hwif_out.ECC_PUBKEY_X[i0].PUBKEY_X.value = field_storage.ECC_PUBKEY_X[i0].PUBKEY_X.value; + end + for(genvar i0=0; i0<12; i0++) begin + // Field: ecc_reg.ECC_PUBKEY_Y[].PUBKEY_Y + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.ECC_PUBKEY_Y[i0].PUBKEY_Y.value; + load_next_c = '0; + if(decoded_reg_strb.ECC_PUBKEY_Y[i0] && decoded_req_is_wr && hwif_in.ecc_ready) begin // SW write + next_c = (field_storage.ECC_PUBKEY_Y[i0].PUBKEY_Y.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end else if(hwif_in.ECC_PUBKEY_Y[i0].PUBKEY_Y.we) begin // HW Write - we + next_c = hwif_in.ECC_PUBKEY_Y[i0].PUBKEY_Y.next; + load_next_c = '1; + end else if(hwif_in.ECC_PUBKEY_Y[i0].PUBKEY_Y.hwclr) begin // HW Clear + next_c = '0; + load_next_c = '1; + end + field_combo.ECC_PUBKEY_Y[i0].PUBKEY_Y.next = next_c; + field_combo.ECC_PUBKEY_Y[i0].PUBKEY_Y.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.ECC_PUBKEY_Y[i0].PUBKEY_Y.value <= 32'h0; + end else if(field_combo.ECC_PUBKEY_Y[i0].PUBKEY_Y.load_next) begin + field_storage.ECC_PUBKEY_Y[i0].PUBKEY_Y.value <= field_combo.ECC_PUBKEY_Y[i0].PUBKEY_Y.next; + end + end + assign hwif_out.ECC_PUBKEY_Y[i0].PUBKEY_Y.value = field_storage.ECC_PUBKEY_Y[i0].PUBKEY_Y.value; + end + for(genvar i0=0; i0<12; i0++) begin + // Field: ecc_reg.ECC_SIGN_R[].SIGN_R + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.ECC_SIGN_R[i0].SIGN_R.value; + load_next_c = '0; + if(decoded_reg_strb.ECC_SIGN_R[i0] && decoded_req_is_wr && hwif_in.ecc_ready) begin // SW write + next_c = (field_storage.ECC_SIGN_R[i0].SIGN_R.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end else if(hwif_in.ECC_SIGN_R[i0].SIGN_R.we) begin // HW Write - we + next_c = hwif_in.ECC_SIGN_R[i0].SIGN_R.next; + load_next_c = '1; + end else if(hwif_in.ECC_SIGN_R[i0].SIGN_R.hwclr) begin // HW Clear + next_c = '0; + load_next_c = '1; + end + field_combo.ECC_SIGN_R[i0].SIGN_R.next = next_c; + field_combo.ECC_SIGN_R[i0].SIGN_R.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.ECC_SIGN_R[i0].SIGN_R.value <= 32'h0; + end else if(field_combo.ECC_SIGN_R[i0].SIGN_R.load_next) begin + field_storage.ECC_SIGN_R[i0].SIGN_R.value <= field_combo.ECC_SIGN_R[i0].SIGN_R.next; + end + end + assign hwif_out.ECC_SIGN_R[i0].SIGN_R.value = field_storage.ECC_SIGN_R[i0].SIGN_R.value; + end + for(genvar i0=0; i0<12; i0++) begin + // Field: ecc_reg.ECC_SIGN_S[].SIGN_S + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.ECC_SIGN_S[i0].SIGN_S.value; + load_next_c = '0; + if(decoded_reg_strb.ECC_SIGN_S[i0] && decoded_req_is_wr && hwif_in.ecc_ready) begin // SW write + next_c = (field_storage.ECC_SIGN_S[i0].SIGN_S.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end else if(hwif_in.ECC_SIGN_S[i0].SIGN_S.we) begin // HW Write - we + next_c = hwif_in.ECC_SIGN_S[i0].SIGN_S.next; + load_next_c = '1; + end else if(hwif_in.ECC_SIGN_S[i0].SIGN_S.hwclr) begin // HW Clear + next_c = '0; + load_next_c = '1; + end + field_combo.ECC_SIGN_S[i0].SIGN_S.next = next_c; + field_combo.ECC_SIGN_S[i0].SIGN_S.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.ECC_SIGN_S[i0].SIGN_S.value <= 32'h0; + end else if(field_combo.ECC_SIGN_S[i0].SIGN_S.load_next) begin + field_storage.ECC_SIGN_S[i0].SIGN_S.value <= field_combo.ECC_SIGN_S[i0].SIGN_S.next; + end + end + assign hwif_out.ECC_SIGN_S[i0].SIGN_S.value = field_storage.ECC_SIGN_S[i0].SIGN_S.value; + end + for(genvar i0=0; i0<12; i0++) begin + // Field: ecc_reg.ECC_VERIFY_R[].VERIFY_R + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.ECC_VERIFY_R[i0].VERIFY_R.value; + load_next_c = '0; + if(hwif_in.ECC_VERIFY_R[i0].VERIFY_R.we) begin // HW Write - we + next_c = hwif_in.ECC_VERIFY_R[i0].VERIFY_R.next; + load_next_c = '1; + end else if(hwif_in.ECC_VERIFY_R[i0].VERIFY_R.hwclr) begin // HW Clear + next_c = '0; + load_next_c = '1; + end + field_combo.ECC_VERIFY_R[i0].VERIFY_R.next = next_c; + field_combo.ECC_VERIFY_R[i0].VERIFY_R.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.ECC_VERIFY_R[i0].VERIFY_R.value <= 32'h0; + end else if(field_combo.ECC_VERIFY_R[i0].VERIFY_R.load_next) begin + field_storage.ECC_VERIFY_R[i0].VERIFY_R.value <= field_combo.ECC_VERIFY_R[i0].VERIFY_R.next; + end + end + assign hwif_out.ECC_VERIFY_R[i0].VERIFY_R.value = field_storage.ECC_VERIFY_R[i0].VERIFY_R.value; + end + for(genvar i0=0; i0<12; i0++) begin + // Field: ecc_reg.ECC_IV[].IV + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.ECC_IV[i0].IV.value; + load_next_c = '0; + if(decoded_reg_strb.ECC_IV[i0] && decoded_req_is_wr && hwif_in.ecc_ready) begin // SW write + next_c = (field_storage.ECC_IV[i0].IV.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end else if(hwif_in.ECC_IV[i0].IV.hwclr) begin // HW Clear + next_c = '0; + load_next_c = '1; + end + field_combo.ECC_IV[i0].IV.next = next_c; + field_combo.ECC_IV[i0].IV.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.ECC_IV[i0].IV.value <= 32'h0; + end else if(field_combo.ECC_IV[i0].IV.load_next) begin + field_storage.ECC_IV[i0].IV.value <= field_combo.ECC_IV[i0].IV.next; + end + end + assign hwif_out.ECC_IV[i0].IV.value = field_storage.ECC_IV[i0].IV.value; + end + for(genvar i0=0; i0<12; i0++) begin + // Field: ecc_reg.ECC_NONCE[].NONCE + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.ECC_NONCE[i0].NONCE.value; + load_next_c = '0; + if(decoded_reg_strb.ECC_NONCE[i0] && decoded_req_is_wr && hwif_in.ecc_ready) begin // SW write + next_c = (field_storage.ECC_NONCE[i0].NONCE.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end else if(hwif_in.ECC_NONCE[i0].NONCE.hwclr) begin // HW Clear + next_c = '0; + load_next_c = '1; + end + field_combo.ECC_NONCE[i0].NONCE.next = next_c; + field_combo.ECC_NONCE[i0].NONCE.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.ECC_NONCE[i0].NONCE.value <= 32'h0; + end else if(field_combo.ECC_NONCE[i0].NONCE.load_next) begin + field_storage.ECC_NONCE[i0].NONCE.value <= field_combo.ECC_NONCE[i0].NONCE.next; + end + end + assign hwif_out.ECC_NONCE[i0].NONCE.value = field_storage.ECC_NONCE[i0].NONCE.value; + end + for(genvar i0=0; i0<12; i0++) begin + // Field: ecc_reg.ECC_PRIVKEY_IN[].PRIVKEY_IN + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.ECC_PRIVKEY_IN[i0].PRIVKEY_IN.value; + load_next_c = '0; + if(decoded_reg_strb.ECC_PRIVKEY_IN[i0] && decoded_req_is_wr && hwif_in.ECC_PRIVKEY_IN[i0].PRIVKEY_IN.swwe) begin // SW write + next_c = (field_storage.ECC_PRIVKEY_IN[i0].PRIVKEY_IN.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end else if(hwif_in.ECC_PRIVKEY_IN[i0].PRIVKEY_IN.we) begin // HW Write - we + next_c = hwif_in.ECC_PRIVKEY_IN[i0].PRIVKEY_IN.next; + load_next_c = '1; + end else if(hwif_in.ECC_PRIVKEY_IN[i0].PRIVKEY_IN.hwclr) begin // HW Clear + next_c = '0; + load_next_c = '1; + end + field_combo.ECC_PRIVKEY_IN[i0].PRIVKEY_IN.next = next_c; + field_combo.ECC_PRIVKEY_IN[i0].PRIVKEY_IN.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.ECC_PRIVKEY_IN[i0].PRIVKEY_IN.value <= 32'h0; + end else if(field_combo.ECC_PRIVKEY_IN[i0].PRIVKEY_IN.load_next) begin + field_storage.ECC_PRIVKEY_IN[i0].PRIVKEY_IN.value <= field_combo.ECC_PRIVKEY_IN[i0].PRIVKEY_IN.next; + end + end + assign hwif_out.ECC_PRIVKEY_IN[i0].PRIVKEY_IN.value = field_storage.ECC_PRIVKEY_IN[i0].PRIVKEY_IN.value; + end + for(genvar i0=0; i0<12; i0++) begin + // Field: ecc_reg.ECC_DH_SHARED_KEY[].DH_SHARED_KEY + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.ECC_DH_SHARED_KEY[i0].DH_SHARED_KEY.value; + load_next_c = '0; + if(hwif_in.ECC_DH_SHARED_KEY[i0].DH_SHARED_KEY.we) begin // HW Write - we + next_c = hwif_in.ECC_DH_SHARED_KEY[i0].DH_SHARED_KEY.next; + load_next_c = '1; + end else if(hwif_in.ECC_DH_SHARED_KEY[i0].DH_SHARED_KEY.hwclr) begin // HW Clear + next_c = '0; + load_next_c = '1; + end + field_combo.ECC_DH_SHARED_KEY[i0].DH_SHARED_KEY.next = next_c; + field_combo.ECC_DH_SHARED_KEY[i0].DH_SHARED_KEY.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.ECC_DH_SHARED_KEY[i0].DH_SHARED_KEY.value <= 32'h0; + end else if(field_combo.ECC_DH_SHARED_KEY[i0].DH_SHARED_KEY.load_next) begin + field_storage.ECC_DH_SHARED_KEY[i0].DH_SHARED_KEY.value <= field_combo.ECC_DH_SHARED_KEY[i0].DH_SHARED_KEY.next; + end + end + end + // Field: ecc_reg.ecc_kv_rd_pkey_ctrl.read_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.ecc_kv_rd_pkey_ctrl.read_en.value; + load_next_c = '0; + if(decoded_reg_strb.ecc_kv_rd_pkey_ctrl && decoded_req_is_wr && hwif_in.ecc_kv_rd_pkey_ctrl.read_en.swwe) begin // SW write + next_c = (field_storage.ecc_kv_rd_pkey_ctrl.read_en.value & ~decoded_wr_biten[0:0]) | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end else if(hwif_in.ecc_kv_rd_pkey_ctrl.read_en.hwclr) begin // HW Clear + next_c = '0; + load_next_c = '1; + end + field_combo.ecc_kv_rd_pkey_ctrl.read_en.next = next_c; + field_combo.ecc_kv_rd_pkey_ctrl.read_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.ecc_kv_rd_pkey_ctrl.read_en.value <= 1'h0; + end else if(field_combo.ecc_kv_rd_pkey_ctrl.read_en.load_next) begin + field_storage.ecc_kv_rd_pkey_ctrl.read_en.value <= field_combo.ecc_kv_rd_pkey_ctrl.read_en.next; + end + end + assign hwif_out.ecc_kv_rd_pkey_ctrl.read_en.value = field_storage.ecc_kv_rd_pkey_ctrl.read_en.value; + // Field: ecc_reg.ecc_kv_rd_pkey_ctrl.read_entry + always_comb begin + automatic logic [4:0] next_c; + automatic logic load_next_c; + next_c = field_storage.ecc_kv_rd_pkey_ctrl.read_entry.value; + load_next_c = '0; + if(decoded_reg_strb.ecc_kv_rd_pkey_ctrl && decoded_req_is_wr && hwif_in.ecc_kv_rd_pkey_ctrl.read_entry.swwe) begin // SW write + next_c = (field_storage.ecc_kv_rd_pkey_ctrl.read_entry.value & ~decoded_wr_biten[5:1]) | (decoded_wr_data[5:1] & decoded_wr_biten[5:1]); + load_next_c = '1; + end + field_combo.ecc_kv_rd_pkey_ctrl.read_entry.next = next_c; + field_combo.ecc_kv_rd_pkey_ctrl.read_entry.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.ecc_kv_rd_pkey_ctrl.read_entry.value <= 5'h0; + end else if(field_combo.ecc_kv_rd_pkey_ctrl.read_entry.load_next) begin + field_storage.ecc_kv_rd_pkey_ctrl.read_entry.value <= field_combo.ecc_kv_rd_pkey_ctrl.read_entry.next; + end + end + assign hwif_out.ecc_kv_rd_pkey_ctrl.read_entry.value = field_storage.ecc_kv_rd_pkey_ctrl.read_entry.value; + // Field: ecc_reg.ecc_kv_rd_pkey_ctrl.pcr_hash_extend + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.ecc_kv_rd_pkey_ctrl.pcr_hash_extend.value; + load_next_c = '0; + if(decoded_reg_strb.ecc_kv_rd_pkey_ctrl && decoded_req_is_wr && hwif_in.ecc_kv_rd_pkey_ctrl.pcr_hash_extend.swwe) begin // SW write + next_c = (field_storage.ecc_kv_rd_pkey_ctrl.pcr_hash_extend.value & ~decoded_wr_biten[6:6]) | (decoded_wr_data[6:6] & decoded_wr_biten[6:6]); + load_next_c = '1; + end + field_combo.ecc_kv_rd_pkey_ctrl.pcr_hash_extend.next = next_c; + field_combo.ecc_kv_rd_pkey_ctrl.pcr_hash_extend.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.ecc_kv_rd_pkey_ctrl.pcr_hash_extend.value <= 1'h0; + end else if(field_combo.ecc_kv_rd_pkey_ctrl.pcr_hash_extend.load_next) begin + field_storage.ecc_kv_rd_pkey_ctrl.pcr_hash_extend.value <= field_combo.ecc_kv_rd_pkey_ctrl.pcr_hash_extend.next; + end + end + assign hwif_out.ecc_kv_rd_pkey_ctrl.pcr_hash_extend.value = field_storage.ecc_kv_rd_pkey_ctrl.pcr_hash_extend.value; + // Field: ecc_reg.ecc_kv_rd_pkey_ctrl.rsvd + always_comb begin + automatic logic [24:0] next_c; + automatic logic load_next_c; + next_c = field_storage.ecc_kv_rd_pkey_ctrl.rsvd.value; + load_next_c = '0; + if(decoded_reg_strb.ecc_kv_rd_pkey_ctrl && decoded_req_is_wr && hwif_in.ecc_kv_rd_pkey_ctrl.rsvd.swwe) begin // SW write + next_c = (field_storage.ecc_kv_rd_pkey_ctrl.rsvd.value & ~decoded_wr_biten[31:7]) | (decoded_wr_data[31:7] & decoded_wr_biten[31:7]); + load_next_c = '1; + end + field_combo.ecc_kv_rd_pkey_ctrl.rsvd.next = next_c; + field_combo.ecc_kv_rd_pkey_ctrl.rsvd.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.ecc_kv_rd_pkey_ctrl.rsvd.value <= 25'h0; + end else if(field_combo.ecc_kv_rd_pkey_ctrl.rsvd.load_next) begin + field_storage.ecc_kv_rd_pkey_ctrl.rsvd.value <= field_combo.ecc_kv_rd_pkey_ctrl.rsvd.next; + end + end + assign hwif_out.ecc_kv_rd_pkey_ctrl.rsvd.value = field_storage.ecc_kv_rd_pkey_ctrl.rsvd.value; + // Field: ecc_reg.ecc_kv_rd_pkey_status.VALID + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.ecc_kv_rd_pkey_status.VALID.value; + load_next_c = '0; + if(hwif_in.ecc_kv_rd_pkey_status.VALID.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end else if(hwif_in.ecc_kv_rd_pkey_status.VALID.hwclr) begin // HW Clear + next_c = '0; + load_next_c = '1; + end + field_combo.ecc_kv_rd_pkey_status.VALID.next = next_c; + field_combo.ecc_kv_rd_pkey_status.VALID.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.ecc_kv_rd_pkey_status.VALID.value <= 1'h0; + end else if(field_combo.ecc_kv_rd_pkey_status.VALID.load_next) begin + field_storage.ecc_kv_rd_pkey_status.VALID.value <= field_combo.ecc_kv_rd_pkey_status.VALID.next; + end + end + // Field: ecc_reg.ecc_kv_rd_seed_ctrl.read_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.ecc_kv_rd_seed_ctrl.read_en.value; + load_next_c = '0; + if(decoded_reg_strb.ecc_kv_rd_seed_ctrl && decoded_req_is_wr && hwif_in.ecc_kv_rd_seed_ctrl.read_en.swwe) begin // SW write + next_c = (field_storage.ecc_kv_rd_seed_ctrl.read_en.value & ~decoded_wr_biten[0:0]) | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end else if(hwif_in.ecc_kv_rd_seed_ctrl.read_en.hwclr) begin // HW Clear + next_c = '0; + load_next_c = '1; + end + field_combo.ecc_kv_rd_seed_ctrl.read_en.next = next_c; + field_combo.ecc_kv_rd_seed_ctrl.read_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.ecc_kv_rd_seed_ctrl.read_en.value <= 1'h0; + end else if(field_combo.ecc_kv_rd_seed_ctrl.read_en.load_next) begin + field_storage.ecc_kv_rd_seed_ctrl.read_en.value <= field_combo.ecc_kv_rd_seed_ctrl.read_en.next; + end + end + assign hwif_out.ecc_kv_rd_seed_ctrl.read_en.value = field_storage.ecc_kv_rd_seed_ctrl.read_en.value; + // Field: ecc_reg.ecc_kv_rd_seed_ctrl.read_entry + always_comb begin + automatic logic [4:0] next_c; + automatic logic load_next_c; + next_c = field_storage.ecc_kv_rd_seed_ctrl.read_entry.value; + load_next_c = '0; + if(decoded_reg_strb.ecc_kv_rd_seed_ctrl && decoded_req_is_wr && hwif_in.ecc_kv_rd_seed_ctrl.read_entry.swwe) begin // SW write + next_c = (field_storage.ecc_kv_rd_seed_ctrl.read_entry.value & ~decoded_wr_biten[5:1]) | (decoded_wr_data[5:1] & decoded_wr_biten[5:1]); + load_next_c = '1; + end + field_combo.ecc_kv_rd_seed_ctrl.read_entry.next = next_c; + field_combo.ecc_kv_rd_seed_ctrl.read_entry.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.ecc_kv_rd_seed_ctrl.read_entry.value <= 5'h0; + end else if(field_combo.ecc_kv_rd_seed_ctrl.read_entry.load_next) begin + field_storage.ecc_kv_rd_seed_ctrl.read_entry.value <= field_combo.ecc_kv_rd_seed_ctrl.read_entry.next; + end + end + assign hwif_out.ecc_kv_rd_seed_ctrl.read_entry.value = field_storage.ecc_kv_rd_seed_ctrl.read_entry.value; + // Field: ecc_reg.ecc_kv_rd_seed_ctrl.pcr_hash_extend + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.ecc_kv_rd_seed_ctrl.pcr_hash_extend.value; + load_next_c = '0; + if(decoded_reg_strb.ecc_kv_rd_seed_ctrl && decoded_req_is_wr && hwif_in.ecc_kv_rd_seed_ctrl.pcr_hash_extend.swwe) begin // SW write + next_c = (field_storage.ecc_kv_rd_seed_ctrl.pcr_hash_extend.value & ~decoded_wr_biten[6:6]) | (decoded_wr_data[6:6] & decoded_wr_biten[6:6]); + load_next_c = '1; + end + field_combo.ecc_kv_rd_seed_ctrl.pcr_hash_extend.next = next_c; + field_combo.ecc_kv_rd_seed_ctrl.pcr_hash_extend.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.ecc_kv_rd_seed_ctrl.pcr_hash_extend.value <= 1'h0; + end else if(field_combo.ecc_kv_rd_seed_ctrl.pcr_hash_extend.load_next) begin + field_storage.ecc_kv_rd_seed_ctrl.pcr_hash_extend.value <= field_combo.ecc_kv_rd_seed_ctrl.pcr_hash_extend.next; + end + end + assign hwif_out.ecc_kv_rd_seed_ctrl.pcr_hash_extend.value = field_storage.ecc_kv_rd_seed_ctrl.pcr_hash_extend.value; + // Field: ecc_reg.ecc_kv_rd_seed_ctrl.rsvd + always_comb begin + automatic logic [24:0] next_c; + automatic logic load_next_c; + next_c = field_storage.ecc_kv_rd_seed_ctrl.rsvd.value; + load_next_c = '0; + if(decoded_reg_strb.ecc_kv_rd_seed_ctrl && decoded_req_is_wr && hwif_in.ecc_kv_rd_seed_ctrl.rsvd.swwe) begin // SW write + next_c = (field_storage.ecc_kv_rd_seed_ctrl.rsvd.value & ~decoded_wr_biten[31:7]) | (decoded_wr_data[31:7] & decoded_wr_biten[31:7]); + load_next_c = '1; + end + field_combo.ecc_kv_rd_seed_ctrl.rsvd.next = next_c; + field_combo.ecc_kv_rd_seed_ctrl.rsvd.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.ecc_kv_rd_seed_ctrl.rsvd.value <= 25'h0; + end else if(field_combo.ecc_kv_rd_seed_ctrl.rsvd.load_next) begin + field_storage.ecc_kv_rd_seed_ctrl.rsvd.value <= field_combo.ecc_kv_rd_seed_ctrl.rsvd.next; + end + end + assign hwif_out.ecc_kv_rd_seed_ctrl.rsvd.value = field_storage.ecc_kv_rd_seed_ctrl.rsvd.value; + // Field: ecc_reg.ecc_kv_rd_seed_status.VALID + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.ecc_kv_rd_seed_status.VALID.value; + load_next_c = '0; + if(hwif_in.ecc_kv_rd_seed_status.VALID.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end else if(hwif_in.ecc_kv_rd_seed_status.VALID.hwclr) begin // HW Clear + next_c = '0; + load_next_c = '1; + end + field_combo.ecc_kv_rd_seed_status.VALID.next = next_c; + field_combo.ecc_kv_rd_seed_status.VALID.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.ecc_kv_rd_seed_status.VALID.value <= 1'h0; + end else if(field_combo.ecc_kv_rd_seed_status.VALID.load_next) begin + field_storage.ecc_kv_rd_seed_status.VALID.value <= field_combo.ecc_kv_rd_seed_status.VALID.next; + end + end + // Field: ecc_reg.ecc_kv_wr_pkey_ctrl.write_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.ecc_kv_wr_pkey_ctrl.write_en.value; + load_next_c = '0; + if(decoded_reg_strb.ecc_kv_wr_pkey_ctrl && decoded_req_is_wr && hwif_in.ecc_kv_wr_pkey_ctrl.write_en.swwe) begin // SW write + next_c = (field_storage.ecc_kv_wr_pkey_ctrl.write_en.value & ~decoded_wr_biten[0:0]) | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end else if(hwif_in.ecc_kv_wr_pkey_ctrl.write_en.hwclr) begin // HW Clear + next_c = '0; + load_next_c = '1; + end + field_combo.ecc_kv_wr_pkey_ctrl.write_en.next = next_c; + field_combo.ecc_kv_wr_pkey_ctrl.write_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.ecc_kv_wr_pkey_ctrl.write_en.value <= 1'h0; + end else if(field_combo.ecc_kv_wr_pkey_ctrl.write_en.load_next) begin + field_storage.ecc_kv_wr_pkey_ctrl.write_en.value <= field_combo.ecc_kv_wr_pkey_ctrl.write_en.next; + end + end + assign hwif_out.ecc_kv_wr_pkey_ctrl.write_en.value = field_storage.ecc_kv_wr_pkey_ctrl.write_en.value; + // Field: ecc_reg.ecc_kv_wr_pkey_ctrl.write_entry + always_comb begin + automatic logic [4:0] next_c; + automatic logic load_next_c; + next_c = field_storage.ecc_kv_wr_pkey_ctrl.write_entry.value; + load_next_c = '0; + if(decoded_reg_strb.ecc_kv_wr_pkey_ctrl && decoded_req_is_wr && hwif_in.ecc_kv_wr_pkey_ctrl.write_entry.swwe) begin // SW write + next_c = (field_storage.ecc_kv_wr_pkey_ctrl.write_entry.value & ~decoded_wr_biten[5:1]) | (decoded_wr_data[5:1] & decoded_wr_biten[5:1]); + load_next_c = '1; + end + field_combo.ecc_kv_wr_pkey_ctrl.write_entry.next = next_c; + field_combo.ecc_kv_wr_pkey_ctrl.write_entry.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.ecc_kv_wr_pkey_ctrl.write_entry.value <= 5'h0; + end else if(field_combo.ecc_kv_wr_pkey_ctrl.write_entry.load_next) begin + field_storage.ecc_kv_wr_pkey_ctrl.write_entry.value <= field_combo.ecc_kv_wr_pkey_ctrl.write_entry.next; + end + end + assign hwif_out.ecc_kv_wr_pkey_ctrl.write_entry.value = field_storage.ecc_kv_wr_pkey_ctrl.write_entry.value; + // Field: ecc_reg.ecc_kv_wr_pkey_ctrl.hmac_key_dest_valid + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.ecc_kv_wr_pkey_ctrl.hmac_key_dest_valid.value; + load_next_c = '0; + if(decoded_reg_strb.ecc_kv_wr_pkey_ctrl && decoded_req_is_wr && hwif_in.ecc_kv_wr_pkey_ctrl.hmac_key_dest_valid.swwe) begin // SW write + next_c = (field_storage.ecc_kv_wr_pkey_ctrl.hmac_key_dest_valid.value & ~decoded_wr_biten[6:6]) | (decoded_wr_data[6:6] & decoded_wr_biten[6:6]); + load_next_c = '1; + end + field_combo.ecc_kv_wr_pkey_ctrl.hmac_key_dest_valid.next = next_c; + field_combo.ecc_kv_wr_pkey_ctrl.hmac_key_dest_valid.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.ecc_kv_wr_pkey_ctrl.hmac_key_dest_valid.value <= 1'h0; + end else if(field_combo.ecc_kv_wr_pkey_ctrl.hmac_key_dest_valid.load_next) begin + field_storage.ecc_kv_wr_pkey_ctrl.hmac_key_dest_valid.value <= field_combo.ecc_kv_wr_pkey_ctrl.hmac_key_dest_valid.next; + end + end + assign hwif_out.ecc_kv_wr_pkey_ctrl.hmac_key_dest_valid.value = field_storage.ecc_kv_wr_pkey_ctrl.hmac_key_dest_valid.value; + // Field: ecc_reg.ecc_kv_wr_pkey_ctrl.hmac_block_dest_valid + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.ecc_kv_wr_pkey_ctrl.hmac_block_dest_valid.value; + load_next_c = '0; + if(decoded_reg_strb.ecc_kv_wr_pkey_ctrl && decoded_req_is_wr && hwif_in.ecc_kv_wr_pkey_ctrl.hmac_block_dest_valid.swwe) begin // SW write + next_c = (field_storage.ecc_kv_wr_pkey_ctrl.hmac_block_dest_valid.value & ~decoded_wr_biten[7:7]) | (decoded_wr_data[7:7] & decoded_wr_biten[7:7]); + load_next_c = '1; + end + field_combo.ecc_kv_wr_pkey_ctrl.hmac_block_dest_valid.next = next_c; + field_combo.ecc_kv_wr_pkey_ctrl.hmac_block_dest_valid.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.ecc_kv_wr_pkey_ctrl.hmac_block_dest_valid.value <= 1'h0; + end else if(field_combo.ecc_kv_wr_pkey_ctrl.hmac_block_dest_valid.load_next) begin + field_storage.ecc_kv_wr_pkey_ctrl.hmac_block_dest_valid.value <= field_combo.ecc_kv_wr_pkey_ctrl.hmac_block_dest_valid.next; + end + end + assign hwif_out.ecc_kv_wr_pkey_ctrl.hmac_block_dest_valid.value = field_storage.ecc_kv_wr_pkey_ctrl.hmac_block_dest_valid.value; + // Field: ecc_reg.ecc_kv_wr_pkey_ctrl.mldsa_seed_dest_valid + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.ecc_kv_wr_pkey_ctrl.mldsa_seed_dest_valid.value; + load_next_c = '0; + if(decoded_reg_strb.ecc_kv_wr_pkey_ctrl && decoded_req_is_wr && hwif_in.ecc_kv_wr_pkey_ctrl.mldsa_seed_dest_valid.swwe) begin // SW write + next_c = (field_storage.ecc_kv_wr_pkey_ctrl.mldsa_seed_dest_valid.value & ~decoded_wr_biten[8:8]) | (decoded_wr_data[8:8] & decoded_wr_biten[8:8]); + load_next_c = '1; + end + field_combo.ecc_kv_wr_pkey_ctrl.mldsa_seed_dest_valid.next = next_c; + field_combo.ecc_kv_wr_pkey_ctrl.mldsa_seed_dest_valid.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.ecc_kv_wr_pkey_ctrl.mldsa_seed_dest_valid.value <= 1'h0; + end else if(field_combo.ecc_kv_wr_pkey_ctrl.mldsa_seed_dest_valid.load_next) begin + field_storage.ecc_kv_wr_pkey_ctrl.mldsa_seed_dest_valid.value <= field_combo.ecc_kv_wr_pkey_ctrl.mldsa_seed_dest_valid.next; + end + end + assign hwif_out.ecc_kv_wr_pkey_ctrl.mldsa_seed_dest_valid.value = field_storage.ecc_kv_wr_pkey_ctrl.mldsa_seed_dest_valid.value; + // Field: ecc_reg.ecc_kv_wr_pkey_ctrl.ecc_pkey_dest_valid + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.ecc_kv_wr_pkey_ctrl.ecc_pkey_dest_valid.value; + load_next_c = '0; + if(decoded_reg_strb.ecc_kv_wr_pkey_ctrl && decoded_req_is_wr && hwif_in.ecc_kv_wr_pkey_ctrl.ecc_pkey_dest_valid.swwe) begin // SW write + next_c = (field_storage.ecc_kv_wr_pkey_ctrl.ecc_pkey_dest_valid.value & ~decoded_wr_biten[9:9]) | (decoded_wr_data[9:9] & decoded_wr_biten[9:9]); + load_next_c = '1; + end + field_combo.ecc_kv_wr_pkey_ctrl.ecc_pkey_dest_valid.next = next_c; + field_combo.ecc_kv_wr_pkey_ctrl.ecc_pkey_dest_valid.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.ecc_kv_wr_pkey_ctrl.ecc_pkey_dest_valid.value <= 1'h0; + end else if(field_combo.ecc_kv_wr_pkey_ctrl.ecc_pkey_dest_valid.load_next) begin + field_storage.ecc_kv_wr_pkey_ctrl.ecc_pkey_dest_valid.value <= field_combo.ecc_kv_wr_pkey_ctrl.ecc_pkey_dest_valid.next; + end + end + assign hwif_out.ecc_kv_wr_pkey_ctrl.ecc_pkey_dest_valid.value = field_storage.ecc_kv_wr_pkey_ctrl.ecc_pkey_dest_valid.value; + // Field: ecc_reg.ecc_kv_wr_pkey_ctrl.ecc_seed_dest_valid + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.ecc_kv_wr_pkey_ctrl.ecc_seed_dest_valid.value; + load_next_c = '0; + if(decoded_reg_strb.ecc_kv_wr_pkey_ctrl && decoded_req_is_wr && hwif_in.ecc_kv_wr_pkey_ctrl.ecc_seed_dest_valid.swwe) begin // SW write + next_c = (field_storage.ecc_kv_wr_pkey_ctrl.ecc_seed_dest_valid.value & ~decoded_wr_biten[10:10]) | (decoded_wr_data[10:10] & decoded_wr_biten[10:10]); + load_next_c = '1; + end + field_combo.ecc_kv_wr_pkey_ctrl.ecc_seed_dest_valid.next = next_c; + field_combo.ecc_kv_wr_pkey_ctrl.ecc_seed_dest_valid.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.ecc_kv_wr_pkey_ctrl.ecc_seed_dest_valid.value <= 1'h0; + end else if(field_combo.ecc_kv_wr_pkey_ctrl.ecc_seed_dest_valid.load_next) begin + field_storage.ecc_kv_wr_pkey_ctrl.ecc_seed_dest_valid.value <= field_combo.ecc_kv_wr_pkey_ctrl.ecc_seed_dest_valid.next; + end + end + assign hwif_out.ecc_kv_wr_pkey_ctrl.ecc_seed_dest_valid.value = field_storage.ecc_kv_wr_pkey_ctrl.ecc_seed_dest_valid.value; + // Field: ecc_reg.ecc_kv_wr_pkey_ctrl.aes_key_dest_valid + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.ecc_kv_wr_pkey_ctrl.aes_key_dest_valid.value; + load_next_c = '0; + if(decoded_reg_strb.ecc_kv_wr_pkey_ctrl && decoded_req_is_wr && hwif_in.ecc_kv_wr_pkey_ctrl.aes_key_dest_valid.swwe) begin // SW write + next_c = (field_storage.ecc_kv_wr_pkey_ctrl.aes_key_dest_valid.value & ~decoded_wr_biten[11:11]) | (decoded_wr_data[11:11] & decoded_wr_biten[11:11]); + load_next_c = '1; + end + field_combo.ecc_kv_wr_pkey_ctrl.aes_key_dest_valid.next = next_c; + field_combo.ecc_kv_wr_pkey_ctrl.aes_key_dest_valid.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.ecc_kv_wr_pkey_ctrl.aes_key_dest_valid.value <= 1'h0; + end else if(field_combo.ecc_kv_wr_pkey_ctrl.aes_key_dest_valid.load_next) begin + field_storage.ecc_kv_wr_pkey_ctrl.aes_key_dest_valid.value <= field_combo.ecc_kv_wr_pkey_ctrl.aes_key_dest_valid.next; + end + end + assign hwif_out.ecc_kv_wr_pkey_ctrl.aes_key_dest_valid.value = field_storage.ecc_kv_wr_pkey_ctrl.aes_key_dest_valid.value; + // Field: ecc_reg.ecc_kv_wr_pkey_ctrl.mlkem_seed_dest_valid + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.ecc_kv_wr_pkey_ctrl.mlkem_seed_dest_valid.value; + load_next_c = '0; + if(decoded_reg_strb.ecc_kv_wr_pkey_ctrl && decoded_req_is_wr && hwif_in.ecc_kv_wr_pkey_ctrl.mlkem_seed_dest_valid.swwe) begin // SW write + next_c = (field_storage.ecc_kv_wr_pkey_ctrl.mlkem_seed_dest_valid.value & ~decoded_wr_biten[12:12]) | (decoded_wr_data[12:12] & decoded_wr_biten[12:12]); + load_next_c = '1; + end + field_combo.ecc_kv_wr_pkey_ctrl.mlkem_seed_dest_valid.next = next_c; + field_combo.ecc_kv_wr_pkey_ctrl.mlkem_seed_dest_valid.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.ecc_kv_wr_pkey_ctrl.mlkem_seed_dest_valid.value <= 1'h0; + end else if(field_combo.ecc_kv_wr_pkey_ctrl.mlkem_seed_dest_valid.load_next) begin + field_storage.ecc_kv_wr_pkey_ctrl.mlkem_seed_dest_valid.value <= field_combo.ecc_kv_wr_pkey_ctrl.mlkem_seed_dest_valid.next; + end + end + assign hwif_out.ecc_kv_wr_pkey_ctrl.mlkem_seed_dest_valid.value = field_storage.ecc_kv_wr_pkey_ctrl.mlkem_seed_dest_valid.value; + // Field: ecc_reg.ecc_kv_wr_pkey_ctrl.mlkem_msg_dest_valid + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.ecc_kv_wr_pkey_ctrl.mlkem_msg_dest_valid.value; + load_next_c = '0; + if(decoded_reg_strb.ecc_kv_wr_pkey_ctrl && decoded_req_is_wr && hwif_in.ecc_kv_wr_pkey_ctrl.mlkem_msg_dest_valid.swwe) begin // SW write + next_c = (field_storage.ecc_kv_wr_pkey_ctrl.mlkem_msg_dest_valid.value & ~decoded_wr_biten[13:13]) | (decoded_wr_data[13:13] & decoded_wr_biten[13:13]); + load_next_c = '1; + end + field_combo.ecc_kv_wr_pkey_ctrl.mlkem_msg_dest_valid.next = next_c; + field_combo.ecc_kv_wr_pkey_ctrl.mlkem_msg_dest_valid.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.ecc_kv_wr_pkey_ctrl.mlkem_msg_dest_valid.value <= 1'h0; + end else if(field_combo.ecc_kv_wr_pkey_ctrl.mlkem_msg_dest_valid.load_next) begin + field_storage.ecc_kv_wr_pkey_ctrl.mlkem_msg_dest_valid.value <= field_combo.ecc_kv_wr_pkey_ctrl.mlkem_msg_dest_valid.next; + end + end + assign hwif_out.ecc_kv_wr_pkey_ctrl.mlkem_msg_dest_valid.value = field_storage.ecc_kv_wr_pkey_ctrl.mlkem_msg_dest_valid.value; + // Field: ecc_reg.ecc_kv_wr_pkey_ctrl.dma_data_dest_valid + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.ecc_kv_wr_pkey_ctrl.dma_data_dest_valid.value; + load_next_c = '0; + if(decoded_reg_strb.ecc_kv_wr_pkey_ctrl && decoded_req_is_wr && hwif_in.ecc_kv_wr_pkey_ctrl.dma_data_dest_valid.swwe) begin // SW write + next_c = (field_storage.ecc_kv_wr_pkey_ctrl.dma_data_dest_valid.value & ~decoded_wr_biten[14:14]) | (decoded_wr_data[14:14] & decoded_wr_biten[14:14]); + load_next_c = '1; + end + field_combo.ecc_kv_wr_pkey_ctrl.dma_data_dest_valid.next = next_c; + field_combo.ecc_kv_wr_pkey_ctrl.dma_data_dest_valid.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.ecc_kv_wr_pkey_ctrl.dma_data_dest_valid.value <= 1'h0; + end else if(field_combo.ecc_kv_wr_pkey_ctrl.dma_data_dest_valid.load_next) begin + field_storage.ecc_kv_wr_pkey_ctrl.dma_data_dest_valid.value <= field_combo.ecc_kv_wr_pkey_ctrl.dma_data_dest_valid.next; + end + end + assign hwif_out.ecc_kv_wr_pkey_ctrl.dma_data_dest_valid.value = field_storage.ecc_kv_wr_pkey_ctrl.dma_data_dest_valid.value; + // Field: ecc_reg.ecc_kv_wr_pkey_ctrl.rsvd + always_comb begin + automatic logic [16:0] next_c; + automatic logic load_next_c; + next_c = field_storage.ecc_kv_wr_pkey_ctrl.rsvd.value; + load_next_c = '0; + if(decoded_reg_strb.ecc_kv_wr_pkey_ctrl && decoded_req_is_wr && hwif_in.ecc_kv_wr_pkey_ctrl.rsvd.swwe) begin // SW write + next_c = (field_storage.ecc_kv_wr_pkey_ctrl.rsvd.value & ~decoded_wr_biten[31:15]) | (decoded_wr_data[31:15] & decoded_wr_biten[31:15]); + load_next_c = '1; + end + field_combo.ecc_kv_wr_pkey_ctrl.rsvd.next = next_c; + field_combo.ecc_kv_wr_pkey_ctrl.rsvd.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.ecc_kv_wr_pkey_ctrl.rsvd.value <= 17'h0; + end else if(field_combo.ecc_kv_wr_pkey_ctrl.rsvd.load_next) begin + field_storage.ecc_kv_wr_pkey_ctrl.rsvd.value <= field_combo.ecc_kv_wr_pkey_ctrl.rsvd.next; + end + end + assign hwif_out.ecc_kv_wr_pkey_ctrl.rsvd.value = field_storage.ecc_kv_wr_pkey_ctrl.rsvd.value; + // Field: ecc_reg.ecc_kv_wr_pkey_status.VALID + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.ecc_kv_wr_pkey_status.VALID.value; + load_next_c = '0; + if(hwif_in.ecc_kv_wr_pkey_status.VALID.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end else if(hwif_in.ecc_kv_wr_pkey_status.VALID.hwclr) begin // HW Clear + next_c = '0; + load_next_c = '1; + end + field_combo.ecc_kv_wr_pkey_status.VALID.next = next_c; + field_combo.ecc_kv_wr_pkey_status.VALID.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.ecc_kv_wr_pkey_status.VALID.value <= 1'h0; + end else if(field_combo.ecc_kv_wr_pkey_status.VALID.load_next) begin + field_storage.ecc_kv_wr_pkey_status.VALID.value <= field_combo.ecc_kv_wr_pkey_status.VALID.next; + end + end + // Field: ecc_reg.intr_block_rf.global_intr_en_r.error_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.global_intr_en_r.error_en.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.global_intr_en_r && decoded_req_is_wr) begin // SW write + next_c = (field_storage.intr_block_rf.global_intr_en_r.error_en.value & ~decoded_wr_biten[0:0]) | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end + field_combo.intr_block_rf.global_intr_en_r.error_en.next = next_c; + field_combo.intr_block_rf.global_intr_en_r.error_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.global_intr_en_r.error_en.value <= 1'h0; + end else if(field_combo.intr_block_rf.global_intr_en_r.error_en.load_next) begin + field_storage.intr_block_rf.global_intr_en_r.error_en.value <= field_combo.intr_block_rf.global_intr_en_r.error_en.next; + end + end + // Field: ecc_reg.intr_block_rf.global_intr_en_r.notif_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.global_intr_en_r.notif_en.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.global_intr_en_r && decoded_req_is_wr) begin // SW write + next_c = (field_storage.intr_block_rf.global_intr_en_r.notif_en.value & ~decoded_wr_biten[1:1]) | (decoded_wr_data[1:1] & decoded_wr_biten[1:1]); + load_next_c = '1; + end + field_combo.intr_block_rf.global_intr_en_r.notif_en.next = next_c; + field_combo.intr_block_rf.global_intr_en_r.notif_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.global_intr_en_r.notif_en.value <= 1'h0; + end else if(field_combo.intr_block_rf.global_intr_en_r.notif_en.load_next) begin + field_storage.intr_block_rf.global_intr_en_r.notif_en.value <= field_combo.intr_block_rf.global_intr_en_r.notif_en.next; + end + end + // Field: ecc_reg.intr_block_rf.error_intr_en_r.error_internal_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_intr_en_r.error_internal_en.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_intr_en_r && decoded_req_is_wr) begin // SW write + next_c = (field_storage.intr_block_rf.error_intr_en_r.error_internal_en.value & ~decoded_wr_biten[0:0]) | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end + field_combo.intr_block_rf.error_intr_en_r.error_internal_en.next = next_c; + field_combo.intr_block_rf.error_intr_en_r.error_internal_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.error_intr_en_r.error_internal_en.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_intr_en_r.error_internal_en.load_next) begin + field_storage.intr_block_rf.error_intr_en_r.error_internal_en.value <= field_combo.intr_block_rf.error_intr_en_r.error_internal_en.next; + end + end + // Field: ecc_reg.intr_block_rf.notif_intr_en_r.notif_cmd_done_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_intr_en_r.notif_cmd_done_en.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.notif_intr_en_r && decoded_req_is_wr) begin // SW write + next_c = (field_storage.intr_block_rf.notif_intr_en_r.notif_cmd_done_en.value & ~decoded_wr_biten[0:0]) | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end + field_combo.intr_block_rf.notif_intr_en_r.notif_cmd_done_en.next = next_c; + field_combo.intr_block_rf.notif_intr_en_r.notif_cmd_done_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.notif_intr_en_r.notif_cmd_done_en.value <= 1'h0; + end else if(field_combo.intr_block_rf.notif_intr_en_r.notif_cmd_done_en.load_next) begin + field_storage.intr_block_rf.notif_intr_en_r.notif_cmd_done_en.value <= field_combo.intr_block_rf.notif_intr_en_r.notif_cmd_done_en.next; + end + end + // Field: ecc_reg.intr_block_rf.error_global_intr_r.agg_sts + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_global_intr_r.agg_sts.value; + load_next_c = '0; + + // HW Write + next_c = hwif_out.intr_block_rf.error_internal_intr_r.intr; + load_next_c = '1; + field_combo.intr_block_rf.error_global_intr_r.agg_sts.next = next_c; + field_combo.intr_block_rf.error_global_intr_r.agg_sts.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.error_global_intr_r.agg_sts.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_global_intr_r.agg_sts.load_next) begin + field_storage.intr_block_rf.error_global_intr_r.agg_sts.value <= field_combo.intr_block_rf.error_global_intr_r.agg_sts.next; + end + end + assign hwif_out.intr_block_rf.error_global_intr_r.intr = + |(field_storage.intr_block_rf.error_global_intr_r.agg_sts.value & field_storage.intr_block_rf.global_intr_en_r.error_en.value); + // Field: ecc_reg.intr_block_rf.notif_global_intr_r.agg_sts + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_global_intr_r.agg_sts.value; + load_next_c = '0; + + // HW Write + next_c = hwif_out.intr_block_rf.notif_internal_intr_r.intr; + load_next_c = '1; + field_combo.intr_block_rf.notif_global_intr_r.agg_sts.next = next_c; + field_combo.intr_block_rf.notif_global_intr_r.agg_sts.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.notif_global_intr_r.agg_sts.value <= 1'h0; + end else if(field_combo.intr_block_rf.notif_global_intr_r.agg_sts.load_next) begin + field_storage.intr_block_rf.notif_global_intr_r.agg_sts.value <= field_combo.intr_block_rf.notif_global_intr_r.agg_sts.next; + end + end + assign hwif_out.intr_block_rf.notif_global_intr_r.intr = + |(field_storage.intr_block_rf.notif_global_intr_r.agg_sts.value & field_storage.intr_block_rf.global_intr_en_r.notif_en.value); + // Field: ecc_reg.intr_block_rf.error_internal_intr_r.error_internal_sts + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_internal_intr_r.error_internal_sts.value; + load_next_c = '0; + if(field_storage.intr_block_rf.error_intr_trig_r.error_internal_trig.value != '0) begin // stickybit + next_c = field_storage.intr_block_rf.error_internal_intr_r.error_internal_sts.value | field_storage.intr_block_rf.error_intr_trig_r.error_internal_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.error_internal_intr_r.error_internal_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end else if(decoded_reg_strb.intr_block_rf.error_internal_intr_r && decoded_req_is_wr) begin // SW write 1 clear + next_c = field_storage.intr_block_rf.error_internal_intr_r.error_internal_sts.value & ~(decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end + field_combo.intr_block_rf.error_internal_intr_r.error_internal_sts.next = next_c; + field_combo.intr_block_rf.error_internal_intr_r.error_internal_sts.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.hard_reset_b) begin + if(~hwif_in.hard_reset_b) begin + field_storage.intr_block_rf.error_internal_intr_r.error_internal_sts.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_internal_intr_r.error_internal_sts.load_next) begin + field_storage.intr_block_rf.error_internal_intr_r.error_internal_sts.value <= field_combo.intr_block_rf.error_internal_intr_r.error_internal_sts.next; + end + end + assign hwif_out.intr_block_rf.error_internal_intr_r.intr = + |(field_storage.intr_block_rf.error_internal_intr_r.error_internal_sts.value & field_storage.intr_block_rf.error_intr_en_r.error_internal_en.value); + // Field: ecc_reg.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.value; + load_next_c = '0; + if(field_storage.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.value != '0) begin // stickybit + next_c = field_storage.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.value | field_storage.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end else if(decoded_reg_strb.intr_block_rf.notif_internal_intr_r && decoded_req_is_wr) begin // SW write 1 clear + next_c = field_storage.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.value & ~(decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end + field_combo.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.next = next_c; + field_combo.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.value <= 1'h0; + end else if(field_combo.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.load_next) begin + field_storage.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.value <= field_combo.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.next; + end + end + assign hwif_out.intr_block_rf.notif_internal_intr_r.intr = + |(field_storage.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.value & field_storage.intr_block_rf.notif_intr_en_r.notif_cmd_done_en.value); + // Field: ecc_reg.intr_block_rf.error_intr_trig_r.error_internal_trig + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_intr_trig_r.error_internal_trig.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_intr_trig_r && decoded_req_is_wr) begin // SW write 1 set + next_c = field_storage.intr_block_rf.error_intr_trig_r.error_internal_trig.value | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end else begin // singlepulse clears back to 0 + next_c = '0; + load_next_c = '1; + end + field_combo.intr_block_rf.error_intr_trig_r.error_internal_trig.next = next_c; + field_combo.intr_block_rf.error_intr_trig_r.error_internal_trig.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.error_intr_trig_r.error_internal_trig.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_intr_trig_r.error_internal_trig.load_next) begin + field_storage.intr_block_rf.error_intr_trig_r.error_internal_trig.value <= field_combo.intr_block_rf.error_intr_trig_r.error_internal_trig.next; + end + end + // Field: ecc_reg.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.notif_intr_trig_r && decoded_req_is_wr) begin // SW write 1 set + next_c = field_storage.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.value | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end else begin // singlepulse clears back to 0 + next_c = '0; + load_next_c = '1; + end + field_combo.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.next = next_c; + field_combo.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.value <= 1'h0; + end else if(field_combo.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.load_next) begin + field_storage.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.value <= field_combo.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.next; + end + end + // Field: ecc_reg.intr_block_rf.error_internal_intr_count_r.cnt + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_internal_intr_count_r.cnt.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_internal_intr_count_r && decoded_req_is_wr) begin // SW write + next_c = (field_storage.intr_block_rf.error_internal_intr_count_r.cnt.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + if(field_storage.intr_block_rf.error_internal_intr_count_incr_r.pulse.value) begin // increment + if(((33)'(next_c) + 32'h1) > 32'hffffffff) begin // up-counter saturated + next_c = 32'hffffffff; + end else begin + next_c = next_c + 32'h1; + end + load_next_c = '1; + end + field_combo.intr_block_rf.error_internal_intr_count_r.cnt.incrthreshold = (field_storage.intr_block_rf.error_internal_intr_count_r.cnt.value >= 32'hffffffff); + field_combo.intr_block_rf.error_internal_intr_count_r.cnt.incrsaturate = (field_storage.intr_block_rf.error_internal_intr_count_r.cnt.value >= 32'hffffffff); + if(next_c > 32'hffffffff) begin + next_c = 32'hffffffff; + load_next_c = '1; + end + field_combo.intr_block_rf.error_internal_intr_count_r.cnt.next = next_c; + field_combo.intr_block_rf.error_internal_intr_count_r.cnt.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.hard_reset_b) begin + if(~hwif_in.hard_reset_b) begin + field_storage.intr_block_rf.error_internal_intr_count_r.cnt.value <= 32'h0; + end else if(field_combo.intr_block_rf.error_internal_intr_count_r.cnt.load_next) begin + field_storage.intr_block_rf.error_internal_intr_count_r.cnt.value <= field_combo.intr_block_rf.error_internal_intr_count_r.cnt.next; + end + end + // Field: ecc_reg.intr_block_rf.notif_cmd_done_intr_count_r.cnt + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_cmd_done_intr_count_r.cnt.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.notif_cmd_done_intr_count_r && decoded_req_is_wr) begin // SW write + next_c = (field_storage.intr_block_rf.notif_cmd_done_intr_count_r.cnt.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + if(field_storage.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.value) begin // increment + if(((33)'(next_c) + 32'h1) > 32'hffffffff) begin // up-counter saturated + next_c = 32'hffffffff; + end else begin + next_c = next_c + 32'h1; + end + load_next_c = '1; + end + field_combo.intr_block_rf.notif_cmd_done_intr_count_r.cnt.incrthreshold = (field_storage.intr_block_rf.notif_cmd_done_intr_count_r.cnt.value >= 32'hffffffff); + field_combo.intr_block_rf.notif_cmd_done_intr_count_r.cnt.incrsaturate = (field_storage.intr_block_rf.notif_cmd_done_intr_count_r.cnt.value >= 32'hffffffff); + if(next_c > 32'hffffffff) begin + next_c = 32'hffffffff; + load_next_c = '1; + end + field_combo.intr_block_rf.notif_cmd_done_intr_count_r.cnt.next = next_c; + field_combo.intr_block_rf.notif_cmd_done_intr_count_r.cnt.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.notif_cmd_done_intr_count_r.cnt.value <= 32'h0; + end else if(field_combo.intr_block_rf.notif_cmd_done_intr_count_r.cnt.load_next) begin + field_storage.intr_block_rf.notif_cmd_done_intr_count_r.cnt.value <= field_combo.intr_block_rf.notif_cmd_done_intr_count_r.cnt.next; + end + end + // Field: ecc_reg.intr_block_rf.error_internal_intr_count_incr_r.pulse + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_internal_intr_count_incr_r.pulse.value; + load_next_c = '0; + if(field_storage.intr_block_rf.error_intr_trig_r.error_internal_trig.value) begin // HW Write - we + next_c = field_storage.intr_block_rf.error_intr_trig_r.error_internal_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.error_internal_intr_r.error_internal_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end + if(field_storage.intr_block_rf.error_internal_intr_count_incr_r.pulse.value) begin // decrement + field_combo.intr_block_rf.error_internal_intr_count_incr_r.pulse.underflow = (next_c < (1'h1)); + next_c = next_c - 1'h1; + load_next_c = '1; + end else begin + field_combo.intr_block_rf.error_internal_intr_count_incr_r.pulse.underflow = '0; + end + field_combo.intr_block_rf.error_internal_intr_count_incr_r.pulse.decrthreshold = (field_storage.intr_block_rf.error_internal_intr_count_incr_r.pulse.value <= 1'd0); + field_combo.intr_block_rf.error_internal_intr_count_incr_r.pulse.next = next_c; + field_combo.intr_block_rf.error_internal_intr_count_incr_r.pulse.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.error_internal_intr_count_incr_r.pulse.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_internal_intr_count_incr_r.pulse.load_next) begin + field_storage.intr_block_rf.error_internal_intr_count_incr_r.pulse.value <= field_combo.intr_block_rf.error_internal_intr_count_incr_r.pulse.next; + end + end + // Field: ecc_reg.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.value; + load_next_c = '0; + if(field_storage.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.value) begin // HW Write - we + next_c = field_storage.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end + if(field_storage.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.value) begin // decrement + field_combo.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.underflow = (next_c < (1'h1)); + next_c = next_c - 1'h1; + load_next_c = '1; + end else begin + field_combo.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.underflow = '0; + end + field_combo.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.decrthreshold = (field_storage.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.value <= 1'd0); + field_combo.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.next = next_c; + field_combo.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.value <= 1'h0; + end else if(field_combo.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.load_next) begin + field_storage.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.value <= field_combo.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.next; + end + end + + //-------------------------------------------------------------------------- + // Write response + //-------------------------------------------------------------------------- + assign cpuif_wr_ack = decoded_req & decoded_req_is_wr; + // Writes are always granted with no error response + assign cpuif_wr_err = '0; + + //-------------------------------------------------------------------------- + // Readback + //-------------------------------------------------------------------------- + + logic readback_err; + logic readback_done; + logic [31:0] readback_data; + + // Assign readback values to a flattened array + logic [108-1:0][31:0] readback_array; + for(genvar i0=0; i0<2; i0++) begin + assign readback_array[i0*1 + 0][31:0] = (decoded_reg_strb.ECC_NAME[i0] && !decoded_req_is_wr) ? hwif_in.ECC_NAME[i0].NAME.next : '0; + end + for(genvar i0=0; i0<2; i0++) begin + assign readback_array[i0*1 + 2][31:0] = (decoded_reg_strb.ECC_VERSION[i0] && !decoded_req_is_wr) ? hwif_in.ECC_VERSION[i0].VERSION.next : '0; + end + assign readback_array[4][0:0] = (decoded_reg_strb.ECC_STATUS && !decoded_req_is_wr) ? hwif_in.ECC_STATUS.READY.next : '0; + assign readback_array[4][1:1] = (decoded_reg_strb.ECC_STATUS && !decoded_req_is_wr) ? hwif_in.ECC_STATUS.VALID.next : '0; + assign readback_array[4][31:2] = '0; + for(genvar i0=0; i0<12; i0++) begin + assign readback_array[i0*1 + 5][31:0] = (decoded_reg_strb.ECC_PRIVKEY_OUT[i0] && !decoded_req_is_wr) ? field_storage.ECC_PRIVKEY_OUT[i0].PRIVKEY_OUT.value : '0; + end + for(genvar i0=0; i0<12; i0++) begin + assign readback_array[i0*1 + 17][31:0] = (decoded_reg_strb.ECC_PUBKEY_X[i0] && !decoded_req_is_wr) ? field_storage.ECC_PUBKEY_X[i0].PUBKEY_X.value : '0; + end + for(genvar i0=0; i0<12; i0++) begin + assign readback_array[i0*1 + 29][31:0] = (decoded_reg_strb.ECC_PUBKEY_Y[i0] && !decoded_req_is_wr) ? field_storage.ECC_PUBKEY_Y[i0].PUBKEY_Y.value : '0; + end + for(genvar i0=0; i0<12; i0++) begin + assign readback_array[i0*1 + 41][31:0] = (decoded_reg_strb.ECC_SIGN_R[i0] && !decoded_req_is_wr) ? field_storage.ECC_SIGN_R[i0].SIGN_R.value : '0; + end + for(genvar i0=0; i0<12; i0++) begin + assign readback_array[i0*1 + 53][31:0] = (decoded_reg_strb.ECC_SIGN_S[i0] && !decoded_req_is_wr) ? field_storage.ECC_SIGN_S[i0].SIGN_S.value : '0; + end + for(genvar i0=0; i0<12; i0++) begin + assign readback_array[i0*1 + 65][31:0] = (decoded_reg_strb.ECC_VERIFY_R[i0] && !decoded_req_is_wr) ? field_storage.ECC_VERIFY_R[i0].VERIFY_R.value : '0; + end + for(genvar i0=0; i0<12; i0++) begin + assign readback_array[i0*1 + 77][31:0] = (decoded_reg_strb.ECC_DH_SHARED_KEY[i0] && !decoded_req_is_wr) ? field_storage.ECC_DH_SHARED_KEY[i0].DH_SHARED_KEY.value : '0; + end + assign readback_array[89][0:0] = (decoded_reg_strb.ecc_kv_rd_pkey_ctrl && !decoded_req_is_wr) ? field_storage.ecc_kv_rd_pkey_ctrl.read_en.value : '0; + assign readback_array[89][5:1] = (decoded_reg_strb.ecc_kv_rd_pkey_ctrl && !decoded_req_is_wr) ? field_storage.ecc_kv_rd_pkey_ctrl.read_entry.value : '0; + assign readback_array[89][6:6] = (decoded_reg_strb.ecc_kv_rd_pkey_ctrl && !decoded_req_is_wr) ? field_storage.ecc_kv_rd_pkey_ctrl.pcr_hash_extend.value : '0; + assign readback_array[89][31:7] = (decoded_reg_strb.ecc_kv_rd_pkey_ctrl && !decoded_req_is_wr) ? field_storage.ecc_kv_rd_pkey_ctrl.rsvd.value : '0; + assign readback_array[90][0:0] = (decoded_reg_strb.ecc_kv_rd_pkey_status && !decoded_req_is_wr) ? hwif_in.ecc_kv_rd_pkey_status.READY.next : '0; + assign readback_array[90][1:1] = (decoded_reg_strb.ecc_kv_rd_pkey_status && !decoded_req_is_wr) ? field_storage.ecc_kv_rd_pkey_status.VALID.value : '0; + assign readback_array[90][9:2] = (decoded_reg_strb.ecc_kv_rd_pkey_status && !decoded_req_is_wr) ? hwif_in.ecc_kv_rd_pkey_status.ERROR.next : '0; + assign readback_array[90][31:10] = '0; + assign readback_array[91][0:0] = (decoded_reg_strb.ecc_kv_rd_seed_ctrl && !decoded_req_is_wr) ? field_storage.ecc_kv_rd_seed_ctrl.read_en.value : '0; + assign readback_array[91][5:1] = (decoded_reg_strb.ecc_kv_rd_seed_ctrl && !decoded_req_is_wr) ? field_storage.ecc_kv_rd_seed_ctrl.read_entry.value : '0; + assign readback_array[91][6:6] = (decoded_reg_strb.ecc_kv_rd_seed_ctrl && !decoded_req_is_wr) ? field_storage.ecc_kv_rd_seed_ctrl.pcr_hash_extend.value : '0; + assign readback_array[91][31:7] = (decoded_reg_strb.ecc_kv_rd_seed_ctrl && !decoded_req_is_wr) ? field_storage.ecc_kv_rd_seed_ctrl.rsvd.value : '0; + assign readback_array[92][0:0] = (decoded_reg_strb.ecc_kv_rd_seed_status && !decoded_req_is_wr) ? hwif_in.ecc_kv_rd_seed_status.READY.next : '0; + assign readback_array[92][1:1] = (decoded_reg_strb.ecc_kv_rd_seed_status && !decoded_req_is_wr) ? field_storage.ecc_kv_rd_seed_status.VALID.value : '0; + assign readback_array[92][9:2] = (decoded_reg_strb.ecc_kv_rd_seed_status && !decoded_req_is_wr) ? hwif_in.ecc_kv_rd_seed_status.ERROR.next : '0; + assign readback_array[92][31:10] = '0; + assign readback_array[93][0:0] = (decoded_reg_strb.ecc_kv_wr_pkey_ctrl && !decoded_req_is_wr) ? field_storage.ecc_kv_wr_pkey_ctrl.write_en.value : '0; + assign readback_array[93][5:1] = (decoded_reg_strb.ecc_kv_wr_pkey_ctrl && !decoded_req_is_wr) ? field_storage.ecc_kv_wr_pkey_ctrl.write_entry.value : '0; + assign readback_array[93][6:6] = (decoded_reg_strb.ecc_kv_wr_pkey_ctrl && !decoded_req_is_wr) ? field_storage.ecc_kv_wr_pkey_ctrl.hmac_key_dest_valid.value : '0; + assign readback_array[93][7:7] = (decoded_reg_strb.ecc_kv_wr_pkey_ctrl && !decoded_req_is_wr) ? field_storage.ecc_kv_wr_pkey_ctrl.hmac_block_dest_valid.value : '0; + assign readback_array[93][8:8] = (decoded_reg_strb.ecc_kv_wr_pkey_ctrl && !decoded_req_is_wr) ? field_storage.ecc_kv_wr_pkey_ctrl.mldsa_seed_dest_valid.value : '0; + assign readback_array[93][9:9] = (decoded_reg_strb.ecc_kv_wr_pkey_ctrl && !decoded_req_is_wr) ? field_storage.ecc_kv_wr_pkey_ctrl.ecc_pkey_dest_valid.value : '0; + assign readback_array[93][10:10] = (decoded_reg_strb.ecc_kv_wr_pkey_ctrl && !decoded_req_is_wr) ? field_storage.ecc_kv_wr_pkey_ctrl.ecc_seed_dest_valid.value : '0; + assign readback_array[93][11:11] = (decoded_reg_strb.ecc_kv_wr_pkey_ctrl && !decoded_req_is_wr) ? field_storage.ecc_kv_wr_pkey_ctrl.aes_key_dest_valid.value : '0; + assign readback_array[93][12:12] = (decoded_reg_strb.ecc_kv_wr_pkey_ctrl && !decoded_req_is_wr) ? field_storage.ecc_kv_wr_pkey_ctrl.mlkem_seed_dest_valid.value : '0; + assign readback_array[93][13:13] = (decoded_reg_strb.ecc_kv_wr_pkey_ctrl && !decoded_req_is_wr) ? field_storage.ecc_kv_wr_pkey_ctrl.mlkem_msg_dest_valid.value : '0; + assign readback_array[93][14:14] = (decoded_reg_strb.ecc_kv_wr_pkey_ctrl && !decoded_req_is_wr) ? field_storage.ecc_kv_wr_pkey_ctrl.dma_data_dest_valid.value : '0; + assign readback_array[93][31:15] = (decoded_reg_strb.ecc_kv_wr_pkey_ctrl && !decoded_req_is_wr) ? field_storage.ecc_kv_wr_pkey_ctrl.rsvd.value : '0; + assign readback_array[94][0:0] = (decoded_reg_strb.ecc_kv_wr_pkey_status && !decoded_req_is_wr) ? hwif_in.ecc_kv_wr_pkey_status.READY.next : '0; + assign readback_array[94][1:1] = (decoded_reg_strb.ecc_kv_wr_pkey_status && !decoded_req_is_wr) ? field_storage.ecc_kv_wr_pkey_status.VALID.value : '0; + assign readback_array[94][9:2] = (decoded_reg_strb.ecc_kv_wr_pkey_status && !decoded_req_is_wr) ? hwif_in.ecc_kv_wr_pkey_status.ERROR.next : '0; + assign readback_array[94][31:10] = '0; + assign readback_array[95][0:0] = (decoded_reg_strb.intr_block_rf.global_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.global_intr_en_r.error_en.value : '0; + assign readback_array[95][1:1] = (decoded_reg_strb.intr_block_rf.global_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.global_intr_en_r.notif_en.value : '0; + assign readback_array[95][31:2] = '0; + assign readback_array[96][0:0] = (decoded_reg_strb.intr_block_rf.error_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_en_r.error_internal_en.value : '0; + assign readback_array[96][31:1] = '0; + assign readback_array[97][0:0] = (decoded_reg_strb.intr_block_rf.notif_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_intr_en_r.notif_cmd_done_en.value : '0; + assign readback_array[97][31:1] = '0; + assign readback_array[98][0:0] = (decoded_reg_strb.intr_block_rf.error_global_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_global_intr_r.agg_sts.value : '0; + assign readback_array[98][31:1] = '0; + assign readback_array[99][0:0] = (decoded_reg_strb.intr_block_rf.notif_global_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_global_intr_r.agg_sts.value : '0; + assign readback_array[99][31:1] = '0; + assign readback_array[100][0:0] = (decoded_reg_strb.intr_block_rf.error_internal_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_internal_intr_r.error_internal_sts.value : '0; + assign readback_array[100][31:1] = '0; + assign readback_array[101][0:0] = (decoded_reg_strb.intr_block_rf.notif_internal_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.value : '0; + assign readback_array[101][31:1] = '0; + assign readback_array[102][0:0] = (decoded_reg_strb.intr_block_rf.error_intr_trig_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_trig_r.error_internal_trig.value : '0; + assign readback_array[102][31:1] = '0; + assign readback_array[103][0:0] = (decoded_reg_strb.intr_block_rf.notif_intr_trig_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.value : '0; + assign readback_array[103][31:1] = '0; + assign readback_array[104][31:0] = (decoded_reg_strb.intr_block_rf.error_internal_intr_count_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_internal_intr_count_r.cnt.value : '0; + assign readback_array[105][31:0] = (decoded_reg_strb.intr_block_rf.notif_cmd_done_intr_count_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_cmd_done_intr_count_r.cnt.value : '0; + assign readback_array[106][0:0] = (decoded_reg_strb.intr_block_rf.error_internal_intr_count_incr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_internal_intr_count_incr_r.pulse.value : '0; + assign readback_array[106][31:1] = '0; + assign readback_array[107][0:0] = (decoded_reg_strb.intr_block_rf.notif_cmd_done_intr_count_incr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.value : '0; + assign readback_array[107][31:1] = '0; + + // Reduce the array + always_comb begin + automatic logic [31:0] readback_data_var; + readback_done = decoded_req & ~decoded_req_is_wr; + readback_err = '0; + readback_data_var = '0; + for(int i=0; i<108; i++) readback_data_var |= readback_array[i]; + readback_data = readback_data_var; + end + + assign cpuif_rd_ack = readback_done; + assign cpuif_rd_data = readback_data; + assign cpuif_rd_err = readback_err; + +`CALIPTRA_ASSERT_KNOWN(ERR_HWIF_IN, hwif_in, clk, !hwif_in.hard_reset_b) + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/ecc_reg_pkg.sv b/designs/Caliptra/src/caliptra-rtl/ecc_reg_pkg.sv new file mode 100644 index 0000000..ec358dc --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/ecc_reg_pkg.sv @@ -0,0 +1,569 @@ +// Generated by PeakRDL-regblock - A free and open-source SystemVerilog generator +// https://github.com/SystemRDL/PeakRDL-regblock + +package ecc_reg_pkg; + + localparam ECC_REG_DATA_WIDTH = 32; + localparam ECC_REG_MIN_ADDR_WIDTH = 12; + + typedef struct packed{ + logic [31:0] next; + } ecc_reg__ECC_NAME__NAME__in_t; + + typedef struct packed{ + ecc_reg__ECC_NAME__NAME__in_t NAME; + } ecc_reg__ECC_NAME__in_t; + + typedef struct packed{ + logic [31:0] next; + } ecc_reg__ECC_VERSION__VERSION__in_t; + + typedef struct packed{ + ecc_reg__ECC_VERSION__VERSION__in_t VERSION; + } ecc_reg__ECC_VERSION__in_t; + + typedef struct packed{ + logic hwclr; + } ecc_reg__ECC_CTRL__CTRL__in_t; + + typedef struct packed{ + logic hwclr; + } ecc_reg__ECC_CTRL__PCR_SIGN__in_t; + + typedef struct packed{ + logic hwclr; + } ecc_reg__ECC_CTRL__DH_SHAREDKEY__in_t; + + typedef struct packed{ + ecc_reg__ECC_CTRL__CTRL__in_t CTRL; + ecc_reg__ECC_CTRL__PCR_SIGN__in_t PCR_SIGN; + ecc_reg__ECC_CTRL__DH_SHAREDKEY__in_t DH_SHAREDKEY; + } ecc_reg__ECC_CTRL__in_t; + + typedef struct packed{ + logic next; + } ecc_reg__ECC_STATUS__READY__in_t; + + typedef struct packed{ + logic next; + } ecc_reg__ECC_STATUS__VALID__in_t; + + typedef struct packed{ + ecc_reg__ECC_STATUS__READY__in_t READY; + ecc_reg__ECC_STATUS__VALID__in_t VALID; + } ecc_reg__ECC_STATUS__in_t; + + typedef struct packed{ + logic [31:0] next; + logic we; + logic swwe; + logic hwclr; + } ecc_reg__ECC_SEED__SEED__in_t; + + typedef struct packed{ + ecc_reg__ECC_SEED__SEED__in_t SEED; + } ecc_reg__ECC_SEED__in_t; + + typedef struct packed{ + logic [31:0] next; + logic we; + logic hwclr; + } ecc_reg__ECC_MSG__MSG__in_t; + + typedef struct packed{ + ecc_reg__ECC_MSG__MSG__in_t MSG; + } ecc_reg__ECC_MSG__in_t; + + typedef struct packed{ + logic [31:0] next; + logic we; + logic hwclr; + } ecc_reg__ECC_PRIVKEY_OUT__PRIVKEY_OUT__in_t; + + typedef struct packed{ + ecc_reg__ECC_PRIVKEY_OUT__PRIVKEY_OUT__in_t PRIVKEY_OUT; + } ecc_reg__ECC_PRIVKEY_OUT__in_t; + + typedef struct packed{ + logic [31:0] next; + logic we; + logic hwclr; + } ecc_reg__ECC_PUBKEY_X__PUBKEY_X__in_t; + + typedef struct packed{ + ecc_reg__ECC_PUBKEY_X__PUBKEY_X__in_t PUBKEY_X; + } ecc_reg__ECC_PUBKEY_X__in_t; + + typedef struct packed{ + logic [31:0] next; + logic we; + logic hwclr; + } ecc_reg__ECC_PUBKEY_Y__PUBKEY_Y__in_t; + + typedef struct packed{ + ecc_reg__ECC_PUBKEY_Y__PUBKEY_Y__in_t PUBKEY_Y; + } ecc_reg__ECC_PUBKEY_Y__in_t; + + typedef struct packed{ + logic [31:0] next; + logic we; + logic hwclr; + } ecc_reg__ECC_SIGN_R__SIGN_R__in_t; + + typedef struct packed{ + ecc_reg__ECC_SIGN_R__SIGN_R__in_t SIGN_R; + } ecc_reg__ECC_SIGN_R__in_t; + + typedef struct packed{ + logic [31:0] next; + logic we; + logic hwclr; + } ecc_reg__ECC_SIGN_S__SIGN_S__in_t; + + typedef struct packed{ + ecc_reg__ECC_SIGN_S__SIGN_S__in_t SIGN_S; + } ecc_reg__ECC_SIGN_S__in_t; + + typedef struct packed{ + logic [31:0] next; + logic we; + logic hwclr; + } ecc_reg__ECC_VERIFY_R__VERIFY_R__in_t; + + typedef struct packed{ + ecc_reg__ECC_VERIFY_R__VERIFY_R__in_t VERIFY_R; + } ecc_reg__ECC_VERIFY_R__in_t; + + typedef struct packed{ + logic hwclr; + } ecc_reg__ECC_IV__IV__in_t; + + typedef struct packed{ + ecc_reg__ECC_IV__IV__in_t IV; + } ecc_reg__ECC_IV__in_t; + + typedef struct packed{ + logic hwclr; + } ecc_reg__ECC_NONCE__NONCE__in_t; + + typedef struct packed{ + ecc_reg__ECC_NONCE__NONCE__in_t NONCE; + } ecc_reg__ECC_NONCE__in_t; + + typedef struct packed{ + logic [31:0] next; + logic we; + logic swwe; + logic hwclr; + } ecc_reg__ECC_PRIVKEY_IN__PRIVKEY_IN__in_t; + + typedef struct packed{ + ecc_reg__ECC_PRIVKEY_IN__PRIVKEY_IN__in_t PRIVKEY_IN; + } ecc_reg__ECC_PRIVKEY_IN__in_t; + + typedef struct packed{ + logic [31:0] next; + logic we; + logic hwclr; + } ecc_reg__ECC_DH_SHARED_KEY__DH_SHARED_KEY__in_t; + + typedef struct packed{ + ecc_reg__ECC_DH_SHARED_KEY__DH_SHARED_KEY__in_t DH_SHARED_KEY; + } ecc_reg__ECC_DH_SHARED_KEY__in_t; + + typedef struct packed{ + logic swwe; + logic hwclr; + } kv_read_ctrl_reg__read_en__in_t; + + typedef struct packed{ + logic swwe; + } kv_read_ctrl_reg__read_entry__in_t; + + typedef struct packed{ + logic swwe; + } kv_read_ctrl_reg__pcr_hash_extend__in_t; + + typedef struct packed{ + logic swwe; + } kv_read_ctrl_reg__rsvd__in_t; + + typedef struct packed{ + kv_read_ctrl_reg__read_en__in_t read_en; + kv_read_ctrl_reg__read_entry__in_t read_entry; + kv_read_ctrl_reg__pcr_hash_extend__in_t pcr_hash_extend; + kv_read_ctrl_reg__rsvd__in_t rsvd; + } kv_read_ctrl_reg__in_t; + + typedef struct packed{ + logic next; + } kv_status_reg__READY__in_t; + + typedef struct packed{ + logic hwclr; + logic hwset; + } kv_status_reg__VALID__in_t; + + typedef struct packed{ + logic [7:0] next; + } kv_status_reg__ERROR__in_t; + + typedef struct packed{ + kv_status_reg__READY__in_t READY; + kv_status_reg__VALID__in_t VALID; + kv_status_reg__ERROR__in_t ERROR; + } kv_status_reg__in_t; + + typedef struct packed{ + logic swwe; + logic hwclr; + } kv_write_ctrl_reg__write_en__in_t; + + typedef struct packed{ + logic swwe; + } kv_write_ctrl_reg__write_entry__in_t; + + typedef struct packed{ + logic swwe; + } kv_write_ctrl_reg__hmac_key_dest_valid__in_t; + + typedef struct packed{ + logic swwe; + } kv_write_ctrl_reg__hmac_block_dest_valid__in_t; + + typedef struct packed{ + logic swwe; + } kv_write_ctrl_reg__mldsa_seed_dest_valid__in_t; + + typedef struct packed{ + logic swwe; + } kv_write_ctrl_reg__ecc_pkey_dest_valid__in_t; + + typedef struct packed{ + logic swwe; + } kv_write_ctrl_reg__ecc_seed_dest_valid__in_t; + + typedef struct packed{ + logic swwe; + } kv_write_ctrl_reg__aes_key_dest_valid__in_t; + + typedef struct packed{ + logic swwe; + } kv_write_ctrl_reg__mlkem_seed_dest_valid__in_t; + + typedef struct packed{ + logic swwe; + } kv_write_ctrl_reg__mlkem_msg_dest_valid__in_t; + + typedef struct packed{ + logic swwe; + } kv_write_ctrl_reg__dma_data_dest_valid__in_t; + + typedef struct packed{ + logic swwe; + } kv_write_ctrl_reg__rsvd__in_t; + + typedef struct packed{ + kv_write_ctrl_reg__write_en__in_t write_en; + kv_write_ctrl_reg__write_entry__in_t write_entry; + kv_write_ctrl_reg__hmac_key_dest_valid__in_t hmac_key_dest_valid; + kv_write_ctrl_reg__hmac_block_dest_valid__in_t hmac_block_dest_valid; + kv_write_ctrl_reg__mldsa_seed_dest_valid__in_t mldsa_seed_dest_valid; + kv_write_ctrl_reg__ecc_pkey_dest_valid__in_t ecc_pkey_dest_valid; + kv_write_ctrl_reg__ecc_seed_dest_valid__in_t ecc_seed_dest_valid; + kv_write_ctrl_reg__aes_key_dest_valid__in_t aes_key_dest_valid; + kv_write_ctrl_reg__mlkem_seed_dest_valid__in_t mlkem_seed_dest_valid; + kv_write_ctrl_reg__mlkem_msg_dest_valid__in_t mlkem_msg_dest_valid; + kv_write_ctrl_reg__dma_data_dest_valid__in_t dma_data_dest_valid; + kv_write_ctrl_reg__rsvd__in_t rsvd; + } kv_write_ctrl_reg__in_t; + + typedef struct packed{ + logic hwset; + } ecc_reg__intr_block_t__error_intr_t_error_internal_sts_83adab02__error_internal_sts_enable_d33001bb_next_52b75ffa_resetsignal_0d7eaa27__in_t; + + typedef struct packed{ + ecc_reg__intr_block_t__error_intr_t_error_internal_sts_83adab02__error_internal_sts_enable_d33001bb_next_52b75ffa_resetsignal_0d7eaa27__in_t error_internal_sts; + } ecc_reg__intr_block_t__error_intr_t_error_internal_sts_83adab02__in_t; + + typedef struct packed{ + logic hwset; + } ecc_reg__intr_block_t__notif_intr_t_notif_cmd_done_sts_1c68637e__notif_cmd_done_sts_enable_dabe0b8b_next_540fa3b7__in_t; + + typedef struct packed{ + ecc_reg__intr_block_t__notif_intr_t_notif_cmd_done_sts_1c68637e__notif_cmd_done_sts_enable_dabe0b8b_next_540fa3b7__in_t notif_cmd_done_sts; + } ecc_reg__intr_block_t__notif_intr_t_notif_cmd_done_sts_1c68637e__in_t; + + typedef struct packed{ + ecc_reg__intr_block_t__error_intr_t_error_internal_sts_83adab02__in_t error_internal_intr_r; + ecc_reg__intr_block_t__notif_intr_t_notif_cmd_done_sts_1c68637e__in_t notif_internal_intr_r; + } ecc_reg__intr_block_t__in_t; + + typedef struct packed{ + logic reset_b; + logic hard_reset_b; + logic ecc_ready; + ecc_reg__ECC_NAME__in_t [2-1:0]ECC_NAME; + ecc_reg__ECC_VERSION__in_t [2-1:0]ECC_VERSION; + ecc_reg__ECC_CTRL__in_t ECC_CTRL; + ecc_reg__ECC_STATUS__in_t ECC_STATUS; + ecc_reg__ECC_SEED__in_t [12-1:0]ECC_SEED; + ecc_reg__ECC_MSG__in_t [12-1:0]ECC_MSG; + ecc_reg__ECC_PRIVKEY_OUT__in_t [12-1:0]ECC_PRIVKEY_OUT; + ecc_reg__ECC_PUBKEY_X__in_t [12-1:0]ECC_PUBKEY_X; + ecc_reg__ECC_PUBKEY_Y__in_t [12-1:0]ECC_PUBKEY_Y; + ecc_reg__ECC_SIGN_R__in_t [12-1:0]ECC_SIGN_R; + ecc_reg__ECC_SIGN_S__in_t [12-1:0]ECC_SIGN_S; + ecc_reg__ECC_VERIFY_R__in_t [12-1:0]ECC_VERIFY_R; + ecc_reg__ECC_IV__in_t [12-1:0]ECC_IV; + ecc_reg__ECC_NONCE__in_t [12-1:0]ECC_NONCE; + ecc_reg__ECC_PRIVKEY_IN__in_t [12-1:0]ECC_PRIVKEY_IN; + ecc_reg__ECC_DH_SHARED_KEY__in_t [12-1:0]ECC_DH_SHARED_KEY; + kv_read_ctrl_reg__in_t ecc_kv_rd_pkey_ctrl; + kv_status_reg__in_t ecc_kv_rd_pkey_status; + kv_read_ctrl_reg__in_t ecc_kv_rd_seed_ctrl; + kv_status_reg__in_t ecc_kv_rd_seed_status; + kv_write_ctrl_reg__in_t ecc_kv_wr_pkey_ctrl; + kv_status_reg__in_t ecc_kv_wr_pkey_status; + ecc_reg__intr_block_t__in_t intr_block_rf; + } ecc_reg__in_t; + + typedef struct packed{ + logic [1:0] value; + } ecc_reg__ECC_CTRL__CTRL__out_t; + + typedef struct packed{ + logic value; + } ecc_reg__ECC_CTRL__ZEROIZE__out_t; + + typedef struct packed{ + logic value; + } ecc_reg__ECC_CTRL__PCR_SIGN__out_t; + + typedef struct packed{ + logic value; + } ecc_reg__ECC_CTRL__DH_SHAREDKEY__out_t; + + typedef struct packed{ + ecc_reg__ECC_CTRL__CTRL__out_t CTRL; + ecc_reg__ECC_CTRL__ZEROIZE__out_t ZEROIZE; + ecc_reg__ECC_CTRL__PCR_SIGN__out_t PCR_SIGN; + ecc_reg__ECC_CTRL__DH_SHAREDKEY__out_t DH_SHAREDKEY; + } ecc_reg__ECC_CTRL__out_t; + + typedef struct packed{ + logic [31:0] value; + } ecc_reg__ECC_SEED__SEED__out_t; + + typedef struct packed{ + ecc_reg__ECC_SEED__SEED__out_t SEED; + } ecc_reg__ECC_SEED__out_t; + + typedef struct packed{ + logic [31:0] value; + } ecc_reg__ECC_MSG__MSG__out_t; + + typedef struct packed{ + ecc_reg__ECC_MSG__MSG__out_t MSG; + } ecc_reg__ECC_MSG__out_t; + + typedef struct packed{ + logic [31:0] value; + } ecc_reg__ECC_PUBKEY_X__PUBKEY_X__out_t; + + typedef struct packed{ + ecc_reg__ECC_PUBKEY_X__PUBKEY_X__out_t PUBKEY_X; + } ecc_reg__ECC_PUBKEY_X__out_t; + + typedef struct packed{ + logic [31:0] value; + } ecc_reg__ECC_PUBKEY_Y__PUBKEY_Y__out_t; + + typedef struct packed{ + ecc_reg__ECC_PUBKEY_Y__PUBKEY_Y__out_t PUBKEY_Y; + } ecc_reg__ECC_PUBKEY_Y__out_t; + + typedef struct packed{ + logic [31:0] value; + } ecc_reg__ECC_SIGN_R__SIGN_R__out_t; + + typedef struct packed{ + ecc_reg__ECC_SIGN_R__SIGN_R__out_t SIGN_R; + } ecc_reg__ECC_SIGN_R__out_t; + + typedef struct packed{ + logic [31:0] value; + } ecc_reg__ECC_SIGN_S__SIGN_S__out_t; + + typedef struct packed{ + ecc_reg__ECC_SIGN_S__SIGN_S__out_t SIGN_S; + } ecc_reg__ECC_SIGN_S__out_t; + + typedef struct packed{ + logic [31:0] value; + } ecc_reg__ECC_VERIFY_R__VERIFY_R__out_t; + + typedef struct packed{ + ecc_reg__ECC_VERIFY_R__VERIFY_R__out_t VERIFY_R; + } ecc_reg__ECC_VERIFY_R__out_t; + + typedef struct packed{ + logic [31:0] value; + } ecc_reg__ECC_IV__IV__out_t; + + typedef struct packed{ + ecc_reg__ECC_IV__IV__out_t IV; + } ecc_reg__ECC_IV__out_t; + + typedef struct packed{ + logic [31:0] value; + } ecc_reg__ECC_NONCE__NONCE__out_t; + + typedef struct packed{ + ecc_reg__ECC_NONCE__NONCE__out_t NONCE; + } ecc_reg__ECC_NONCE__out_t; + + typedef struct packed{ + logic [31:0] value; + } ecc_reg__ECC_PRIVKEY_IN__PRIVKEY_IN__out_t; + + typedef struct packed{ + ecc_reg__ECC_PRIVKEY_IN__PRIVKEY_IN__out_t PRIVKEY_IN; + } ecc_reg__ECC_PRIVKEY_IN__out_t; + + typedef struct packed{ + logic value; + } kv_read_ctrl_reg__read_en__out_t; + + typedef struct packed{ + logic [4:0] value; + } kv_read_ctrl_reg__read_entry__out_t; + + typedef struct packed{ + logic value; + } kv_read_ctrl_reg__pcr_hash_extend__out_t; + + typedef struct packed{ + logic [24:0] value; + } kv_read_ctrl_reg__rsvd__out_t; + + typedef struct packed{ + kv_read_ctrl_reg__read_en__out_t read_en; + kv_read_ctrl_reg__read_entry__out_t read_entry; + kv_read_ctrl_reg__pcr_hash_extend__out_t pcr_hash_extend; + kv_read_ctrl_reg__rsvd__out_t rsvd; + } kv_read_ctrl_reg__out_t; + + typedef struct packed{ + logic value; + } kv_write_ctrl_reg__write_en__out_t; + + typedef struct packed{ + logic [4:0] value; + } kv_write_ctrl_reg__write_entry__out_t; + + typedef struct packed{ + logic value; + } kv_write_ctrl_reg__hmac_key_dest_valid__out_t; + + typedef struct packed{ + logic value; + } kv_write_ctrl_reg__hmac_block_dest_valid__out_t; + + typedef struct packed{ + logic value; + } kv_write_ctrl_reg__mldsa_seed_dest_valid__out_t; + + typedef struct packed{ + logic value; + } kv_write_ctrl_reg__ecc_pkey_dest_valid__out_t; + + typedef struct packed{ + logic value; + } kv_write_ctrl_reg__ecc_seed_dest_valid__out_t; + + typedef struct packed{ + logic value; + } kv_write_ctrl_reg__aes_key_dest_valid__out_t; + + typedef struct packed{ + logic value; + } kv_write_ctrl_reg__mlkem_seed_dest_valid__out_t; + + typedef struct packed{ + logic value; + } kv_write_ctrl_reg__mlkem_msg_dest_valid__out_t; + + typedef struct packed{ + logic value; + } kv_write_ctrl_reg__dma_data_dest_valid__out_t; + + typedef struct packed{ + logic [16:0] value; + } kv_write_ctrl_reg__rsvd__out_t; + + typedef struct packed{ + kv_write_ctrl_reg__write_en__out_t write_en; + kv_write_ctrl_reg__write_entry__out_t write_entry; + kv_write_ctrl_reg__hmac_key_dest_valid__out_t hmac_key_dest_valid; + kv_write_ctrl_reg__hmac_block_dest_valid__out_t hmac_block_dest_valid; + kv_write_ctrl_reg__mldsa_seed_dest_valid__out_t mldsa_seed_dest_valid; + kv_write_ctrl_reg__ecc_pkey_dest_valid__out_t ecc_pkey_dest_valid; + kv_write_ctrl_reg__ecc_seed_dest_valid__out_t ecc_seed_dest_valid; + kv_write_ctrl_reg__aes_key_dest_valid__out_t aes_key_dest_valid; + kv_write_ctrl_reg__mlkem_seed_dest_valid__out_t mlkem_seed_dest_valid; + kv_write_ctrl_reg__mlkem_msg_dest_valid__out_t mlkem_msg_dest_valid; + kv_write_ctrl_reg__dma_data_dest_valid__out_t dma_data_dest_valid; + kv_write_ctrl_reg__rsvd__out_t rsvd; + } kv_write_ctrl_reg__out_t; + + typedef struct packed{ + logic intr; + } ecc_reg__intr_block_t__global_intr_t_agg_sts_dd3dcf0a__out_t; + + typedef struct packed{ + logic intr; + } ecc_reg__intr_block_t__global_intr_t_agg_sts_e6399b4a__out_t; + + typedef struct packed{ + logic intr; + } ecc_reg__intr_block_t__error_intr_t_error_internal_sts_83adab02__out_t; + + typedef struct packed{ + logic intr; + } ecc_reg__intr_block_t__notif_intr_t_notif_cmd_done_sts_1c68637e__out_t; + + typedef struct packed{ + ecc_reg__intr_block_t__global_intr_t_agg_sts_dd3dcf0a__out_t error_global_intr_r; + ecc_reg__intr_block_t__global_intr_t_agg_sts_e6399b4a__out_t notif_global_intr_r; + ecc_reg__intr_block_t__error_intr_t_error_internal_sts_83adab02__out_t error_internal_intr_r; + ecc_reg__intr_block_t__notif_intr_t_notif_cmd_done_sts_1c68637e__out_t notif_internal_intr_r; + } ecc_reg__intr_block_t__out_t; + + typedef struct packed{ + ecc_reg__ECC_CTRL__out_t ECC_CTRL; + ecc_reg__ECC_SEED__out_t [12-1:0]ECC_SEED; + ecc_reg__ECC_MSG__out_t [12-1:0]ECC_MSG; + ecc_reg__ECC_PUBKEY_X__out_t [12-1:0]ECC_PUBKEY_X; + ecc_reg__ECC_PUBKEY_Y__out_t [12-1:0]ECC_PUBKEY_Y; + ecc_reg__ECC_SIGN_R__out_t [12-1:0]ECC_SIGN_R; + ecc_reg__ECC_SIGN_S__out_t [12-1:0]ECC_SIGN_S; + ecc_reg__ECC_VERIFY_R__out_t [12-1:0]ECC_VERIFY_R; + ecc_reg__ECC_IV__out_t [12-1:0]ECC_IV; + ecc_reg__ECC_NONCE__out_t [12-1:0]ECC_NONCE; + ecc_reg__ECC_PRIVKEY_IN__out_t [12-1:0]ECC_PRIVKEY_IN; + kv_read_ctrl_reg__out_t ecc_kv_rd_pkey_ctrl; + kv_read_ctrl_reg__out_t ecc_kv_rd_seed_ctrl; + kv_write_ctrl_reg__out_t ecc_kv_wr_pkey_ctrl; + ecc_reg__intr_block_t__out_t intr_block_rf; + } ecc_reg__out_t; + + typedef enum logic [31:0] { + kv_status_reg__ERROR__kv_error_e__SUCCESS = 'h0, + kv_status_reg__ERROR__kv_error_e__KV_READ_FAIL = 'h1, + kv_status_reg__ERROR__kv_error_e__KV_WRITE_FAIL = 'h2 + } kv_status_reg__ERROR__kv_error_e_e; + + localparam ECC_REG_ADDR_WIDTH = 32'd12; + +endpackage \ No newline at end of file diff --git a/designs/Caliptra/src/caliptra-rtl/ecc_scalar_blinding.sv b/designs/Caliptra/src/caliptra-rtl/ecc_scalar_blinding.sv new file mode 100644 index 0000000..9326307 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/ecc_scalar_blinding.sv @@ -0,0 +1,323 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +// +//====================================================================== +// +// ecc_scalar_blinding.sv +// -------- +// The scalar blinding is a SCA countermeasure described in +// "Resistance against Differential Power Analysis for Elliptic Curve +// Cryptosystems" by Coron. +// Based on "Efficient Side-Channel Attacks on Scalar Blinding on Elliptic +// Curves with Special Structure" by Schindler et. al., the random value size +// should be at least half of group order length. +// +// This module takes the scalar and a random value (rnd) to randomize the scalar +// as follows: +// randomized_scalar = scalar + rnd * group_order +// with the following contraint: +// scalar < group_order +// +// From the contraint, the output has REG_SIZE+RND_SIZE bit length: +// scalar + rnd*group_order < (rnd+1)*group_order < (2^RND_SIZE)*group_order +// +//====================================================================== + +module ecc_scalar_blinding #( + parameter REG_SIZE = 384, + parameter RND_SIZE = 192, + parameter RADIX = 32, + parameter [REG_SIZE-1 : 0] GROUP_ORDER = 384'hffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52973 + ) + ( + // Clock and reset. + input wire clk, + input wire reset_n, + input wire zeroize, + + // DATA PORT + input wire en_i, + input wire [REG_SIZE-1 : 0] data_i, + input wire [RND_SIZE-1 : 0] rnd_i, + output wire [(REG_SIZE+RND_SIZE)-1 : 0] data_o, + output wire busy_o + ); + + //---------------------------------------------------------------- + // Local Parameters + //---------------------------------------------------------------- + // Equivalent to $ceil(REG_SIZE/RADIX) + 1 + localparam REG_DIG_NUM = (((REG_SIZE + RADIX) - 1) / RADIX) + 1; //13 + localparam RND_DIG_NUM = (((RND_SIZE + RADIX) - 1) / RADIX) + 1; //7 + localparam FULL_DIG_NUM = REG_DIG_NUM + RND_DIG_NUM - 1; //19 + + localparam FULL_REG_SIZE = REG_DIG_NUM * RADIX; + localparam FULL_RND_SIZE = RND_DIG_NUM * RADIX; + localparam FULL_SIZE = FULL_DIG_NUM * RADIX; + + localparam [(FULL_RND_SIZE-RND_SIZE)-1 : 0] zero_pad_rnd = '0; + localparam [(FULL_REG_SIZE-REG_SIZE)-1 : 0] zero_pad_reg = '0; + localparam [(FULL_SIZE-REG_SIZE)-1 : 0] zero_pad_reg_full = '0; + localparam [RADIX-1 : 0] zero_pad_radix = '0; + + localparam A_ARR_WIDTH = $clog2(REG_DIG_NUM+1); //4 + localparam B_ARR_WIDTH = $clog2(RND_DIG_NUM+1); //3 + localparam P_ARR_WIDTH = $clog2(FULL_DIG_NUM+1); //5 + + //---------------------------------------------------------------- + // Registers + //---------------------------------------------------------------- + logic [RADIX-1 : 0] a_array[0 : REG_DIG_NUM-1]; + logic [RADIX-1 : 0] b_array[0 : RND_DIG_NUM-1]; + logic [RADIX-1 : 0] p_array[0 : FULL_DIG_NUM-1]; + logic [RADIX-1 : 0] scalar_array[0 : FULL_DIG_NUM-1]; + + logic [A_ARR_WIDTH-1 : 0] a_idx; + logic [B_ARR_WIDTH-1 : 0] b_idx; + + logic [FULL_REG_SIZE-1 : 0] a_reg; //extended with zero + logic [FULL_RND_SIZE-1 : 0] b_reg; //extended with zero + logic [FULL_SIZE-1 : 0] scalar_reg; //extended with zero + logic [FULL_SIZE-1 : 0] p_internal; + + logic [RADIX-1 : 0] mult_opa; + logic [RADIX-1 : 0] mult_opb; + logic [(2*RADIX)-1 : 0] mult_out; + + logic [(3*RADIX)-1 : 0] add0_opa; + logic [(3*RADIX)-1 : 0] add0_opb; + logic [(3*RADIX)-1 : 0] add0_out; + + logic [RADIX-1 : 0] add1_opa; + logic [RADIX-1 : 0] add1_opb; + logic add1_cin; + logic [RADIX-1 : 0] add1_out; + logic add1_cout; + + logic [(3*RADIX)-1 : 0] accu_reg; + logic accu_store; + logic accu_shift; + logic accu_done; + + logic shift_state; + + logic [P_ARR_WIDTH-1 : 0] product_idx; + logic [B_ARR_WIDTH-1 : 0] operand_idx; + logic [P_ARR_WIDTH-1 : 0] product_idx_reg; + logic [B_ARR_WIDTH-1 : 0] operand_idx_reg; + + logic [P_ARR_WIDTH-B_ARR_WIDTH : 0] carry_garbage_bits0; + logic carry_garbage_bit1; + //---------------------------------------------------------------- + // reg update + //---------------------------------------------------------------- + + always_ff @(posedge clk or negedge reset_n) + begin : input_reg + if (!reset_n) begin + a_reg <= '0; + b_reg <= '0; + scalar_reg <= '0; + end + else if (zeroize) begin + a_reg <= '0; + b_reg <= '0; + scalar_reg <= '0; + end + else if (en_i) begin + a_reg <= {zero_pad_reg, GROUP_ORDER}; + b_reg <= {zero_pad_rnd, rnd_i}; + scalar_reg <= {zero_pad_reg_full, data_i}; + end + end // input_reg + + genvar i0; + generate + for (i0=0; i0 < REG_DIG_NUM; i0++) begin : gen_a_array + assign a_array[i0] = a_reg[i0*RADIX +: RADIX]; + end + endgenerate // gen_a_array + + genvar j0; + generate + for (j0=0; j0 < RND_DIG_NUM; j0++) begin : gen_b_array + assign b_array[j0] = b_reg[j0*RADIX +: RADIX]; + end + endgenerate // gen_b_array + + genvar k0; + generate + for (k0=0; k0 < FULL_DIG_NUM; k0++) begin : gen_scalar_array + assign scalar_array[k0] = scalar_reg[k0*RADIX +: RADIX]; + end + endgenerate // gen_scalar_array + + + //---------------------------------------------------------------- + // core instantiation + //---------------------------------------------------------------- + + ecc_mult_dsp #( + .RADIX(RADIX) + ) + ecc_mult_dsp_i ( + .A_i(mult_opa), + .B_i(mult_opb), + .P_o(mult_out) + ); + + ecc_adder #( + .RADIX(3*RADIX) + ) + ecc_adder_i0( + .a_i(add0_opa), + .b_i(add0_opb), + .cin_i(1'b0), + .s_o(add0_out), + .cout_o(carry_garbage_bit1) + ); + + ecc_adder #( + .RADIX(RADIX) + ) + ecc_adder_i1( + .a_i(add1_opa), + .b_i(add1_opb), + .cin_i(add1_cin), + .s_o(add1_out), + .cout_o(add1_cout) + ); + + + //---------------------------------------------------------------- + // accumulator + //---------------------------------------------------------------- + + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) + accu_reg <= '0; + else if (zeroize) + accu_reg <= '0; + else if (en_i) + accu_reg <= '0; + else begin + if (accu_store) + accu_reg <= add0_out; + else if (accu_shift) + accu_reg <= {zero_pad_radix, accu_reg[(3*RADIX)-1 : RADIX]}; + end + end + + //---------------------------------------------------------------- + // multiplier state logic + //---------------------------------------------------------------- + + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) begin + product_idx_reg <= FULL_DIG_NUM[P_ARR_WIDTH-1 : 0]; + operand_idx_reg <= '0; + shift_state <= 0; + add1_cin <= 0; + carry_garbage_bits0 <= '0; + end + else if (zeroize) begin + product_idx_reg <= FULL_DIG_NUM[P_ARR_WIDTH-1 : 0]; + operand_idx_reg <= '0; + shift_state <= 0; + add1_cin <= 0; + carry_garbage_bits0 <= '0; + end + else if (en_i) begin + product_idx_reg <= '0; + operand_idx_reg <= '0; + shift_state <= 0; + add1_cin <= 0; + end + else begin + if (product_idx < FULL_DIG_NUM) begin + if (shift_state) begin + product_idx_reg <= product_idx + 1; + if (product_idx < (REG_DIG_NUM-1)) + operand_idx_reg <= '0; + else + {carry_garbage_bits0, operand_idx_reg} <= (2'h2 + product_idx) - REG_DIG_NUM; + add1_cin <= add1_cout; + shift_state <= 0; + end + else begin + if (({2'b00, operand_idx} < product_idx) & (operand_idx < (RND_DIG_NUM-1))) begin + shift_state <= 0; + operand_idx_reg <= operand_idx + 1; + end + else + shift_state <= 1; + end + end + end + end + + assign product_idx = product_idx_reg; + assign operand_idx = operand_idx_reg; + + assign accu_store = (accu_done)? 0 : (!shift_state); + assign accu_shift = (accu_done)? 0 : shift_state; + assign accu_done = (product_idx == FULL_DIG_NUM); + + // Determines which a and b is pushed through the multiplier + always_comb begin + a_idx = 4'(product_idx - operand_idx); + //2,4 = 5- 3 + b_idx = operand_idx; + mult_opa = a_array[a_idx]; + mult_opb = b_array[b_idx]; + end + + // Determines which a and b is pushed through the adders + always_comb begin + add0_opa = {zero_pad_radix, mult_out}; + add0_opb = accu_reg; + + add1_opa = accu_reg[RADIX-1 : 0]; + add1_opb = scalar_array[product_idx]; + end + + //---------------------------------------------------------------- + // Storing the results + //---------------------------------------------------------------- + genvar t0; + generate + for (t0=0; t0 < FULL_DIG_NUM; t0++) begin : gen_t_reg + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) + p_array[t0] <= '0; + else if (zeroize) + p_array[t0] <= '0; + else if (accu_shift & (t0 == product_idx)) + p_array[t0] <= add1_out; + end + end + endgenerate + + genvar t1; + generate + for (t1=0; t1 < FULL_DIG_NUM; t1++) begin : gen_p_o + assign p_internal[t1*RADIX +: RADIX] = p_array[t1]; + end + endgenerate + + + assign data_o = p_internal[(REG_SIZE+RND_SIZE)-1 : 0]; + assign busy_o = ~accu_done; + +endmodule \ No newline at end of file diff --git a/designs/Caliptra/src/caliptra-rtl/ecc_top.sv b/designs/Caliptra/src/caliptra-rtl/ecc_top.sv new file mode 100644 index 0000000..c8e6e20 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/ecc_top.sv @@ -0,0 +1,162 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +//====================================================================== +// +// ecc_top.sv +// -------- +// top-level wrapper for ecc architecture including: +// 1- ecc_dsa_ctrl module as ecc engin +// 2- ecc_reg module as register memory of ecc to interface with external +// 3- ahb_slv_sif module to handle AHB-lite interface +//====================================================================== + +module ecc_top + import ecc_defines_pkg::*; + import ecc_reg_pkg::*; + import kv_defines_pkg::*; + #( + parameter AHB_ADDR_WIDTH = 32, + parameter AHB_DATA_WIDTH = 32, + parameter CLIENT_DATA_WIDTH = 32 + ) + ( + input wire clk, + input wire reset_n, + input wire cptra_pwrgood, + + //AHB Lite Interface + input wire [AHB_ADDR_WIDTH-1:0] haddr_i, + input wire [AHB_DATA_WIDTH-1:0] hwdata_i, + input wire hsel_i, + input wire hwrite_i, + input wire hready_i, + input wire [1:0] htrans_i, + input wire [2:0] hsize_i, + + output logic hresp_o, + output logic hreadyout_o, + output logic [AHB_DATA_WIDTH-1:0] hrdata_o, + + // KV interface + output kv_read_t [1:0] kv_read, + output kv_write_t kv_write, + input kv_rd_resp_t [1:0] kv_rd_resp, + input kv_wr_resp_t kv_wr_resp, + //PCR Signing + input pcr_signing_t pcr_signing_data, + + input logic ocp_lock_in_progress, + output logic busy_o, + + output logic error_intr, + output logic notif_intr, + input logic debugUnlock_or_scan_mode_switch +); + + //gasket to assemble ecc request + logic ecc_cs; + logic [CLIENT_DATA_WIDTH-1:0] uc_req_rdata; + ecc_req_t uc_req; + + logic ecc_reg_err, ecc_reg_read_err, ecc_reg_write_err; + + ecc_reg__in_t ecc_reg_hwif_in; + ecc_reg__out_t ecc_reg_hwif_out; + + //AHB-Lite Interface + //This module contains the logic for interfacing with the Caliptra uC over the AHB-Lite Interface + //The Caliptra uC sends read and write requests using AHB-Lite Protocol + //This wrapper decodes that protocol and issues requests to the arbitration block + ahb_slv_sif #( + .AHB_ADDR_WIDTH(AHB_ADDR_WIDTH), + .AHB_DATA_WIDTH(AHB_DATA_WIDTH), + .CLIENT_DATA_WIDTH(CLIENT_DATA_WIDTH) + ) + ecc_ahb_slv_i ( + //AMBA AHB Lite INF + .hclk(clk), + .hreset_n(reset_n), + .haddr_i(haddr_i), + .hwdata_i(hwdata_i), + .hsel_i(hsel_i), + .hwrite_i(hwrite_i), + .hready_i(hready_i), + .htrans_i(htrans_i), + .hsize_i(hsize_i), + + .hresp_o(hresp_o), + .hreadyout_o(hreadyout_o), + .hrdata_o(hrdata_o), + + //COMPONENT INF + .dv(ecc_cs), + .hld('0), + .err(ecc_reg_err), + .write(uc_req.write), + .wdata(uc_req.wdata), + .addr(uc_req.addr[AHB_ADDR_WIDTH-1:0]), + + .rdata(uc_req_rdata) + ); + + //Functional Registers + //This module contains the functional registers maintained by the Caliptra ECC + //These registers are memory mapped per the Caliptra Specification + //Read and Write permissions are controlled within this block + always_comb ecc_reg_err = ecc_reg_read_err | ecc_reg_write_err; + + ecc_reg ecc_reg1 ( + .clk(clk), + .rst(reset_n), + + .s_cpuif_req(ecc_cs), + .s_cpuif_req_is_wr(uc_req.write), + .s_cpuif_addr(uc_req.addr[ECC_REG_ADDR_WIDTH-1:0]), + .s_cpuif_wr_data(uc_req.wdata), + .s_cpuif_wr_biten('1), + .s_cpuif_req_stall_wr(), + .s_cpuif_req_stall_rd(), + .s_cpuif_rd_ack(), + .s_cpuif_rd_err(ecc_reg_read_err), + .s_cpuif_rd_data(uc_req_rdata), + .s_cpuif_wr_ack(), + .s_cpuif_wr_err(ecc_reg_write_err), + + .hwif_in(ecc_reg_hwif_in), + .hwif_out(ecc_reg_hwif_out) + ); + + ecc_dsa_ctrl ecc_dsa_ctrl_i( + .clk(clk), + .reset_n(reset_n), + .cptra_pwrgood(cptra_pwrgood), + + .hwif_out(ecc_reg_hwif_out), + .hwif_in(ecc_reg_hwif_in), + + .kv_read(kv_read), + .kv_rd_resp(kv_rd_resp), + .kv_write(kv_write), + .kv_wr_resp(kv_wr_resp), + .pcr_signing_data(pcr_signing_data), + + .ocp_lock_in_progress(ocp_lock_in_progress), + .busy_o(busy_o), + + .error_intr(error_intr), + .notif_intr(notif_intr), + .debugUnlock_or_scan_mode_switch(debugUnlock_or_scan_mode_switch) + ); + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/ecc_top_cov_bind.sv b/designs/Caliptra/src/caliptra-rtl/ecc_top_cov_bind.sv new file mode 100644 index 0000000..a04dc50 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/ecc_top_cov_bind.sv @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. + + +module ecc_top_cov_bind; + `ifdef FCOV + bind ecc_top ecc_top_cov_if i_ecc_top_cov_if(.*); + `endif +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/ecc_top_cov_if.sv b/designs/Caliptra/src/caliptra-rtl/ecc_top_cov_if.sv new file mode 100644 index 0000000..96ee270 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/ecc_top_cov_if.sv @@ -0,0 +1,243 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. + +`ifndef VERILATOR + +interface ecc_top_cov_if + import kv_defines_pkg::*; + ( + input logic clk, + input logic reset_n, + input logic cptra_pwrgood, + input logic ocp_lock_in_progress + +); + + logic [2 : 0] ecc_cmd; + logic [2 : 0] ecc_sw_cmd; + logic zeroize; + logic pcr_sign_mode; + logic ready; + logic valid; + + logic dest_keyvault; + + logic error_flag; + logic privkey_input_outofrange; + logic r_output_outofrange; + logic s_output_outofrange; + logic r_input_outofrange; + logic s_input_outofrange; + logic pubkeyx_input_outofrange; + logic pubkeyy_input_outofrange; + logic pubkey_input_invalid; + logic pcr_sign_input_invalid; + logic keygen_process; + logic signing_process; + logic verifying_process; + logic sharedkey_process; + logic privkey_output_outofrange, pubkeyx_output_outofrange, pubkeyy_output_outofrange; + logic sharedkey_outofrange; + + + logic mod_p_q; + logic add_en; + logic add_sub_i; + logic [383 : 0] add_res0; + logic add_cout0; + logic add_cout1; + logic add_res_less_than_prime; + logic add_res_greater_than_384_bit; + + logic mult_ready; + logic mult_last_reduction; + logic mult_final_subtraction; + + kv_write_filter_metrics_t kv_write_metrics; + kv_write_ctrl_reg_t kv_write_ctrl_reg; + + assign mod_p_q = ecc_top.ecc_dsa_ctrl_i.ecc_arith_unit_i.mod_p_q; + assign add_en = ecc_top.ecc_dsa_ctrl_i.ecc_arith_unit_i.ecc_fau_i.add_en_i; + assign add_sub_i = ecc_top.ecc_dsa_ctrl_i.ecc_arith_unit_i.ecc_fau_i.sub_i; + assign add_res0 = ecc_top.ecc_dsa_ctrl_i.ecc_arith_unit_i.ecc_fau_i.i_ADDER_SUBTRACTOR.r0_reg; + assign add_cout0 = ecc_top.ecc_dsa_ctrl_i.ecc_arith_unit_i.ecc_fau_i.i_ADDER_SUBTRACTOR.carry0_reg; + assign add_cout1 = ecc_top.ecc_dsa_ctrl_i.ecc_arith_unit_i.ecc_fau_i.i_ADDER_SUBTRACTOR.carry1; + assign add_res_less_than_prime = ((add_cout0 == 1'b0) & (add_res0 < ecc_top.ecc_dsa_ctrl_i.ecc_arith_unit_i.ecc_fau_i.prime_i)); + assign add_res_greater_than_384_bit = (add_cout0 == 1'b1); + + assign mult_ready = ecc_top.ecc_dsa_ctrl_i.ecc_arith_unit_i.ecc_fau_i.i_MULTIPLIER.ready_o; + assign mult_last_reduction = ecc_top.ecc_dsa_ctrl_i.ecc_arith_unit_i.ecc_fau_i.i_MULTIPLIER.last_reduction; + assign mult_final_subtraction = mult_ready & mult_last_reduction; + + assign ecc_cmd = ecc_top.ecc_dsa_ctrl_i.cmd_reg; + assign pcr_sign_mode = ecc_top.ecc_dsa_ctrl_i.pcr_sign_mode; + assign zeroize = ecc_top.ecc_dsa_ctrl_i.zeroize_reg; + assign ready = ecc_top.ecc_dsa_ctrl_i.ecc_ready_reg; + assign valid = ecc_top.ecc_dsa_ctrl_i.ecc_valid_reg; + + assign kv_write_metrics = ecc_top.ecc_dsa_ctrl_i.kv_write_metrics; + assign kv_write_ctrl_reg = ecc_top.ecc_dsa_ctrl_i.kv_write_ctrl_reg; + + always_ff @(posedge clk) begin + if (!reset_n) begin + ecc_sw_cmd <= '0; + end + else if (ecc_top.ecc_reg1.decoded_reg_strb.ECC_CTRL && ecc_top.ecc_reg1.decoded_req_is_wr) begin // SW write + ecc_sw_cmd[1:0] <= (ecc_top.ecc_reg1.field_storage.ECC_CTRL.CTRL.value & ~ecc_top.ecc_reg1.decoded_wr_biten[1:0]) | (ecc_top.ecc_reg1.decoded_wr_data[1:0] & ecc_top.ecc_reg1.decoded_wr_biten[1:0]); + ecc_sw_cmd[2] <= (ecc_top.ecc_reg1.field_storage.ECC_CTRL.DH_SHAREDKEY.value & ~ecc_top.ecc_reg1.decoded_wr_biten[4]) | (ecc_top.ecc_reg1.decoded_wr_data[4] & ecc_top.ecc_reg1.decoded_wr_biten[4]); + end + end + + assign dest_keyvault = ecc_top.ecc_dsa_ctrl_i.dest_keyvault; + + assign error_flag = ecc_top.ecc_dsa_ctrl_i.error_flag | ecc_top.ecc_dsa_ctrl_i.error_flag_reg; + assign privkey_input_outofrange = ecc_top.ecc_dsa_ctrl_i.privkey_input_outofrange; + assign r_output_outofrange = ecc_top.ecc_dsa_ctrl_i.r_output_outofrange; + assign s_output_outofrange = ecc_top.ecc_dsa_ctrl_i.s_output_outofrange; + assign r_input_outofrange = ecc_top.ecc_dsa_ctrl_i.r_input_outofrange; + assign s_input_outofrange = ecc_top.ecc_dsa_ctrl_i.s_input_outofrange; + assign pubkeyx_input_outofrange = ecc_top.ecc_dsa_ctrl_i.pubkeyx_input_outofrange; + assign pubkeyy_input_outofrange = ecc_top.ecc_dsa_ctrl_i.pubkeyy_input_outofrange; + assign pubkey_input_invalid = ecc_top.ecc_dsa_ctrl_i.pubkey_input_invalid; + assign pcr_sign_input_invalid = ecc_top.ecc_dsa_ctrl_i.pcr_sign_input_invalid; + assign keygen_process = ecc_top.ecc_dsa_ctrl_i.keygen_process; + assign signing_process = ecc_top.ecc_dsa_ctrl_i.signing_process; + assign verifying_process = ecc_top.ecc_dsa_ctrl_i.verifying_process; + assign sharedkey_process = ecc_top.ecc_dsa_ctrl_i.sharedkey_process; + assign privkey_output_outofrange = ecc_top.ecc_dsa_ctrl_i.privkey_output_outofrange; + assign pubkeyx_output_outofrange = ecc_top.ecc_dsa_ctrl_i.pubkeyx_output_outofrange; + assign pubkeyy_output_outofrange = ecc_top.ecc_dsa_ctrl_i.pubkeyy_output_outofrange; + assign sharedkey_outofrange = ecc_top.ecc_dsa_ctrl_i.sharedkey_outofrange; + + covergroup ecc_top_cov_grp @(posedge clk); + reset_cp: coverpoint reset_n; + //cptra_pwrgood_cp: coverpoint cptra_pwrgood; + + ecc_cmd_cp: coverpoint ecc_cmd { + illegal_bins illegal_values = {5, 6, 7}; + } + pcr_sign_cp: coverpoint pcr_sign_mode; + zeroize_cp: coverpoint zeroize; + ready_cp: coverpoint ready; + valid_cp: coverpoint valid; + + dest_keyvault_cp: coverpoint dest_keyvault; + + error_flag_cp: coverpoint error_flag; + privkey_input_outofrange_cp: coverpoint privkey_input_outofrange; + r_output_outofrange_cp: coverpoint r_output_outofrange; + s_output_outofrange_cp: coverpoint s_output_outofrange; + r_input_outofrange_cp: coverpoint r_input_outofrange; + s_input_outofrange_cp: coverpoint s_input_outofrange; + pubkeyx_input_outofrange_cp: coverpoint pubkeyx_input_outofrange; + pubkeyx_input_outofrange_cross: cross pubkeyx_input_outofrange_cp, verifying_process, sharedkey_process { + // Exclude illegal state + ignore_bins both_active = binsof(verifying_process) intersect {1} && binsof(sharedkey_process) intersect {1}; + ignore_bins neither_active = binsof(verifying_process) intersect {0} && binsof(sharedkey_process) intersect {0}; + } + pubkeyy_input_outofrange_cp: coverpoint pubkeyy_input_outofrange; + pubkeyy_input_outofrange_cross: cross pubkeyy_input_outofrange_cp, verifying_process, sharedkey_process { + // Exclude illegal state + ignore_bins both_active = binsof(verifying_process) intersect {1} && binsof(sharedkey_process) intersect {1}; + ignore_bins neither_active = binsof(verifying_process) intersect {0} && binsof(sharedkey_process) intersect {0}; + } + pubkey_input_invalid_cp: coverpoint pubkey_input_invalid; + pubkey_input_invalid_cross: cross pubkey_input_invalid_cp, verifying_process, sharedkey_process { + // Exclude illegal state + ignore_bins both_active = binsof(verifying_process) intersect {1} && binsof(sharedkey_process) intersect {1}; + ignore_bins neither_active = binsof(verifying_process) intersect {0} && binsof(sharedkey_process) intersect {0}; + } + pcr_sign_input_invalid_cp: coverpoint pcr_sign_input_invalid; + + privkey_output_outofrange_cp: coverpoint privkey_output_outofrange; + pubkeyx_output_outofrange_cp: coverpoint pubkeyx_output_outofrange; + pubkeyy_output_outofrange_cp: coverpoint pubkeyy_output_outofrange; + sharedkey_outofrange_cp: coverpoint sharedkey_outofrange; + + cmd_ready_cp: cross ecc_sw_cmd, ready{ + ignore_bins illegal_sw_cmd = binsof(ecc_sw_cmd) intersect {5, 6, 7}; + } + keygen_kv_cp: cross keygen_process, dest_keyvault; + pcr_ready_cp: cross ready, pcr_sign_mode; + pcr_cmd_cp: cross pcr_sign_mode, ecc_cmd_cp{ + ignore_bins illegal_crosses = binsof(ecc_cmd_cp.illegal_values); + } + zeroize_pcr_cp: cross zeroize, pcr_sign_mode; + zeroize_cmd_cp: cross zeroize, ecc_cmd_cp{ + ignore_bins illegal_crosses = binsof(ecc_cmd_cp.illegal_values); + } + zeroize_error_cp: cross zeroize, error_flag; + zeroize_ready_cp: cross ready, zeroize; + pcr_sign_input_invalid_cmd_cp: cross error_flag, ecc_cmd_cp{ + ignore_bins illegal_crosses = binsof(ecc_cmd_cp.illegal_values) || binsof(ecc_cmd_cp) intersect {2}; + } + error_keygen_cp: cross error_flag, keygen_process; + error_signing_cp: cross error_flag, signing_process; + error_verifying_cp: cross error_flag, verifying_process; + error_sharedkey_cp: cross error_flag, sharedkey_process; + + // modular operation + add_carry_cp: cross mod_p_q, add_sub_i, add_cout0, add_cout1; + add_result_less_than_prime_cp: cross mod_p_q, add_sub_i, add_res_less_than_prime; + add_result_greater_than_384_bit_cp: cross mod_p_q, add_sub_i, add_res_greater_than_384_bit; + + + endgroup + + covergroup ecc_ocp_lock_cov_grp @(posedge clk); + + ocp_lock_in_progress_cp: coverpoint ocp_lock_in_progress; + + kv_read_entry_0_cp: coverpoint {kv_write_metrics.kv_data0_present, kv_write_metrics.kv_data0_entry} + iff (ecc_cmd inside {3'b001}) { + bins fw = {[0:23]}; //{1'b0, [0:$]}; + bins lower_slots = {[32:47]}; //{1'b1, [0:15]}; + bins upper_slots = {[48:54]}; //{1'b1, [16:22]}; + bins slot_23 = {55}; //{1'b1, 23}; + } + + kv_read_entry_1_cp: coverpoint {kv_write_metrics.kv_data1_present, kv_write_metrics.kv_data1_entry} + iff (ecc_cmd inside {3'b100}) { + bins fw = {[0:23]}; //{1'b0, [0:$]}; + bins lower_slots = {[32:47]}; //{1'b1, [0:15]}; + bins upper_slots = {[48:54]}; //{1'b1, [16:22]}; + bins slot_23 = {55}; //{1'b1, 23}; + } + + kv_write_entry_kg_cp: coverpoint {kv_write_ctrl_reg.write_en, kv_write_metrics.kv_write_entry} + iff (ecc_cmd inside {3'b001}) { + bins fw = {[0:23]}; //{1'b0, [0:$]}; + bins lower_slots = {[32:47]}; //{1'b1, [0:15]}; + bins upper_slots = {[48:54]}; //{1'b1, [16:22]}; + bins slot_23 = {55}; //{1'b1, 23}; + } + + kv_write_entry_ecdh_cp: coverpoint {kv_write_ctrl_reg.write_en, kv_write_metrics.kv_write_entry} + iff (ecc_cmd inside {3'b100}) { + bins fw = {[0:23]}; //{1'b0, [0:$]}; + bins lower_slots = {[32:47]}; //{1'b1, [0:15]}; + bins upper_slots = {[48:54]}; //{1'b1, [16:22]}; + bins slot_23 = {55}; //{1'b1, 23}; + } + + ocp_lock_X_kv_read_entry0: cross ocp_lock_in_progress_cp, kv_write_entry_kg_cp, kv_read_entry_0_cp; + ocp_lock_X_kv_read_entry1: cross ocp_lock_in_progress_cp, kv_write_entry_ecdh_cp, kv_read_entry_1_cp; + endgroup + + ecc_top_cov_grp ecc_top_cov_grp1 = new(); + ecc_ocp_lock_cov_grp ecc_ocp_lock_cov_grp1 = new(); + +endinterface + +`endif diff --git a/designs/Caliptra/src/caliptra-rtl/edn_pkg.sv b/designs/Caliptra/src/caliptra-rtl/edn_pkg.sv new file mode 100644 index 0000000..0fa0d39 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/edn_pkg.sv @@ -0,0 +1,76 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// + + +package edn_pkg; + /////////////////////////// + // Peripheral Interfaces // + /////////////////////////// + + parameter int unsigned ENDPOINT_BUS_WIDTH = 32; + parameter int unsigned FIPS_ENDPOINT_BUS_WIDTH = entropy_src_pkg::FIPS_BUS_WIDTH + + ENDPOINT_BUS_WIDTH; + + // EDN request interface + typedef struct packed { + logic edn_req; + } edn_req_t; + typedef struct packed { + logic edn_ack; + logic edn_fips; + logic [ENDPOINT_BUS_WIDTH-1:0] edn_bus; + } edn_rsp_t; + + parameter edn_req_t EDN_REQ_DEFAULT = '0; + parameter edn_rsp_t EDN_RSP_DEFAULT = '0; + parameter csrng_pkg::csrng_cmd_t BOOT_UNINSTANTIATE = 32'h5; + + // Encoding generated with: + // $ ./util/design/sparse-fsm-encode.py -d 3 -m 20 -n 9 \ + // -s 2596398066 --language=sv + // + // Hamming distance histogram: + // + // 0: -- + // 1: -- + // 2: -- + // 3: |||||||||||||| (21.05%) + // 4: |||||||||||||||||||| (30.00%) + // 5: ||||||||||||||| (23.68%) + // 6: |||||||||| (15.26%) + // 7: |||| (7.37%) + // 8: | (2.63%) + // 9: -- + // + // Minimum Hamming distance: 3 + // Maximum Hamming distance: 8 + // Minimum Hamming weight: 2 + // Maximum Hamming weight: 7 + // + localparam int StateWidth = 9; + typedef enum logic [StateWidth-1:0] { + Idle = 9'b011000001, // idle + BootLoadIns = 9'b111000111, // boot: load the instantiate command + BootInsAckWait = 9'b001111001, // boot: wait for instantiate command ack + BootLoadGen = 9'b000000011, // boot: load the generate command + BootGenAckWait = 9'b001110111, // boot: wait for generate command ack + BootPulse = 9'b010101001, // boot: signal a done pulse + BootDone = 9'b011110000, // boot: stay in done state until leaving boot mode + BootLoadUni = 9'b100110101, // boot: load the uninstantiate command + BootUniAckWait = 9'b000101100, // boot: wait for uninstantiate command ack + AutoLoadIns = 9'b110111100, // auto: load the instantiate command + AutoFirstAckWait = 9'b110100011, // auto: wait for first instantiate command ack + AutoAckWait = 9'b010010010, // auto: wait for instantiate command ack + AutoDispatch = 9'b101100001, // auto: determine next command to be sent + AutoCaptGenCnt = 9'b100001110, // auto: capture the gen fifo count + AutoSendGenCmd = 9'b111011101, // auto: send the generate command + AutoCaptReseedCnt = 9'b010111111, // auto: capture the reseed fifo count + AutoSendReseedCmd = 9'b001101010, // auto: send the reseed command + SWPortMode = 9'b010010101, // swport: no hw request mode + RejectCsrngEntropy = 9'b000011000, // stop accepting entropy from CSRNG + Error = 9'b101111110 // illegal state reached and hang + } state_e; + +endpackage : edn_pkg diff --git a/designs/Caliptra/src/caliptra-rtl/el2_dbg.sv b/designs/Caliptra/src/caliptra-rtl/el2_dbg.sv new file mode 100644 index 0000000..0047b8b --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/el2_dbg.sv @@ -0,0 +1,788 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2020 Western Digital Corporation or its affiliates. +// +// 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. +//******************************************************************************** +// $Id$ +// +// Function: Top level VeeR core file to control the debug mode +// Comments: Responsible to put the rest of the core in quiesce mode, +// Send the commands/address. sends WrData and Recieve read Data. +// And then Resume the core to do the normal mode +// Author : +//******************************************************************************** +module el2_dbg +import el2_pkg::*; +#( +`include "el2_param.vh" + )( + // outputs to the core for command and data interface + output logic [31:0] dbg_cmd_addr, + output logic [31:0] dbg_cmd_wrdata, + output logic dbg_cmd_valid, + output logic dbg_cmd_write, // 1: write command, 0: read_command + output logic [1:0] dbg_cmd_type, // 0:gpr 1:csr 2: memory + output logic [1:0] dbg_cmd_size, // size of the abstract mem access debug command + output logic dbg_core_rst_l, // core reset from dm + + // inputs back from the core/dec + input logic [31:0] core_dbg_rddata, + input logic core_dbg_cmd_done, // This will be treated like a valid signal + input logic core_dbg_cmd_fail, // Exception during command run + + // Signals to dma to get a bubble + output logic dbg_dma_bubble, // Debug needs a bubble to send a valid + input logic dma_dbg_ready, // DMA is ready to accept debug request + + // interface with the rest of the core to halt/resume handshaking + output logic dbg_halt_req, // This is a pulse + output logic dbg_resume_req, // Debug sends a resume requests. Pulse + input logic dec_tlu_debug_mode, // Core is in debug mode + input logic dec_tlu_dbg_halted, // The core has finished the queiscing sequence. Core is halted now + input logic dec_tlu_mpc_halted_only, // Only halted due to MPC + input logic dec_tlu_resume_ack, // core sends back an ack for the resume (pulse) + + // inputs from the JTAG + input logic dmi_reg_en, // read or write + input logic [6:0] dmi_reg_addr, // address of DM register + input logic dmi_reg_wr_en, // write instruction + input logic [31:0] dmi_reg_wdata, // write data + + // output + output logic [31:0] dmi_reg_rdata, // read data + + // AXI Write Channels + output logic sb_axi_awvalid, + input logic sb_axi_awready, + /* exclude signals that are tied to constant value in this file */ + /*pragma coverage off*/ + output logic [pt.SB_BUS_TAG-1:0] sb_axi_awid, + /*pragma coverage on*/ + output logic [31:0] sb_axi_awaddr, + output logic [3:0] sb_axi_awregion, + /* exclude signals that are tied to constant value in this file */ + /*pragma coverage off*/ + output logic [7:0] sb_axi_awlen, + /*pragma coverage on*/ + output logic [2:0] sb_axi_awsize, + /* exclude signals that are tied to constant value in this file */ + /*pragma coverage off*/ + output logic [1:0] sb_axi_awburst, + output logic sb_axi_awlock, + output logic [3:0] sb_axi_awcache, + output logic [2:0] sb_axi_awprot, + output logic [3:0] sb_axi_awqos, + /*pragma coverage on*/ + + output logic sb_axi_wvalid, + input logic sb_axi_wready, + output logic [63:0] sb_axi_wdata, + output logic [7:0] sb_axi_wstrb, + output logic sb_axi_wlast, + + input logic sb_axi_bvalid, + output logic sb_axi_bready, + input logic [1:0] sb_axi_bresp, + + // AXI Read Channels + output logic sb_axi_arvalid, + input logic sb_axi_arready, + /* exclude signals that are tied to constant value in this file */ + /*pragma coverage off*/ + output logic [pt.SB_BUS_TAG-1:0] sb_axi_arid, + /*pragma coverage on*/ + output logic [31:0] sb_axi_araddr, + output logic [3:0] sb_axi_arregion, + /* exclude signals that are tied to constant value in this file */ + /*pragma coverage off*/ + output logic [7:0] sb_axi_arlen, + /*pragma coverage on*/ + output logic [2:0] sb_axi_arsize, + /* exclude signals that are tied to constant value in this file */ + /*pragma coverage off*/ + output logic [1:0] sb_axi_arburst, + output logic sb_axi_arlock, + output logic [3:0] sb_axi_arcache, + output logic [2:0] sb_axi_arprot, + output logic [3:0] sb_axi_arqos, + /*pragma coverage on*/ + + input logic sb_axi_rvalid, + /* exclude signals that are tied to constant value in this file */ + /*pragma coverage off*/ + output logic sb_axi_rready, + /*pragma coverage on*/ + input logic [63:0] sb_axi_rdata, + input logic [1:0] sb_axi_rresp, + + input logic dbg_bus_clk_en, + + // general inputs + input logic clk, + input logic free_clk, + input logic rst_l, // This includes both top rst and debug rst + input logic dbg_rst_l, + input logic clk_override, + // Excluding scan_mode from coverage as its usage is determined by the integrator of the VeeR core. + /*pragma coverage off*/ + input logic scan_mode + /*pragma coverage on*/ +); + + + typedef enum logic [3:0] {IDLE=4'h0, HALTING=4'h1, HALTED=4'h2, CORE_CMD_START=4'h3, CORE_CMD_WAIT=4'h4, SB_CMD_START=4'h5, SB_CMD_SEND=4'h6, SB_CMD_RESP=4'h7, CMD_DONE=4'h8, RESUMING=4'h9} state_t; + typedef enum logic [3:0] {SBIDLE=4'h0, WAIT_RD=4'h1, WAIT_WR=4'h2, CMD_RD=4'h3, CMD_WR=4'h4, CMD_WR_ADDR=4'h5, CMD_WR_DATA=4'h6, RSP_RD=4'h7, RSP_WR=4'h8, DONE=4'h9} sb_state_t; + + state_t dbg_state; + state_t dbg_nxtstate; + logic dbg_state_en; + // these are the registers that the debug module implements + logic [31:0] dmstatus_reg; // [26:24]-dmerr, [17:16]-resume ack, [9:8]-halted, [3:0]-version + logic [31:0] dmcontrol_reg; // dmcontrol register has only 6 bits implemented. 31: haltreq, 30: resumereq, 29: haltreset, 28: ackhavereset, 1: ndmreset, 0: dmactive. + logic [31:0] command_reg; + logic [31:0] abstractcs_reg; // bits implemted are [12] - busy and [10:8]= command error + logic [31:0] haltsum0_reg; + logic [31:0] data0_reg; + logic [31:0] data1_reg; + + // data 0 + logic [31:0] data0_din; + logic data0_reg_wren, data0_reg_wren0, data0_reg_wren1, data0_reg_wren2; + // data 1 + logic [31:0] data1_din; + logic data1_reg_wren, data1_reg_wren0, data1_reg_wren1; + // abstractcs + logic abstractcs_busy_wren; + logic abstractcs_busy_din; + logic [2:0] abstractcs_error_din; + logic abstractcs_error_sel0, abstractcs_error_sel1, abstractcs_error_sel2, abstractcs_error_sel3, abstractcs_error_sel4, abstractcs_error_sel5, abstractcs_error_sel6; + logic dbg_sb_bus_error; + // abstractauto + logic abstractauto_reg_wren; + logic [1:0] abstractauto_reg; + + // dmstatus + logic dmstatus_resumeack_wren; + logic dmstatus_resumeack_din; + logic dmstatus_haveresetn_wren; + logic dmstatus_resumeack; + logic dmstatus_unavail; + logic dmstatus_running; + logic dmstatus_halted; + logic dmstatus_havereset, dmstatus_haveresetn; + + // dmcontrol + logic resumereq; + logic dmcontrol_wren, dmcontrol_wren_Q; + // command + logic execute_command_ns, execute_command; + logic command_wren, command_regno_wren; + logic command_transfer_din; + logic command_postexec_din; + logic [31:0] command_din; + logic [3:0] dbg_cmd_addr_incr; + logic [31:0] dbg_cmd_curr_addr; + logic [31:0] dbg_cmd_next_addr; + + // needed to send the read data back for dmi reads + logic [31:0] dmi_reg_rdata_din; + + sb_state_t sb_state; + sb_state_t sb_nxtstate; + logic sb_state_en; + + //System bus section + logic sbcs_wren; + logic sbcs_sbbusy_wren; + logic sbcs_sbbusy_din; + logic sbcs_sbbusyerror_wren; + logic sbcs_sbbusyerror_din; + + logic sbcs_sberror_wren; + logic [2:0] sbcs_sberror_din; + logic sbcs_unaligned; + logic sbcs_illegal_size; + logic [19:15] sbcs_reg_int; + + // data + logic sbdata0_reg_wren0; + logic sbdata0_reg_wren1; + logic sbdata0_reg_wren; + logic [31:0] sbdata0_din; + + logic sbdata1_reg_wren0; + logic sbdata1_reg_wren1; + logic sbdata1_reg_wren; + logic [31:0] sbdata1_din; + + logic sbaddress0_reg_wren0; + logic sbaddress0_reg_wren1; + logic sbaddress0_reg_wren; + logic [31:0] sbaddress0_reg_din; + logic [3:0] sbaddress0_incr; + logic sbreadonaddr_access; + logic sbreadondata_access; + logic sbdata0wr_access; + + logic sb_abmem_cmd_done_in, sb_abmem_data_done_in; + logic sb_abmem_cmd_done_en, sb_abmem_data_done_en; + logic sb_abmem_cmd_done, sb_abmem_data_done; + logic [31:0] abmem_addr; + logic abmem_addr_in_dccm_region, abmem_addr_in_iccm_region, abmem_addr_in_pic_region; + logic abmem_addr_core_local; + logic abmem_addr_external; + + logic sb_cmd_pending, sb_abmem_cmd_pending; + logic sb_abmem_cmd_write; + logic [2:0] sb_abmem_cmd_size; + logic [31:0] sb_abmem_cmd_addr; + logic [31:0] sb_abmem_cmd_wdata; + + logic [2:0] sb_cmd_size; + logic [31:0] sb_cmd_addr; + logic [63:0] sb_cmd_wdata; + + logic sb_bus_cmd_read, sb_bus_cmd_write_addr, sb_bus_cmd_write_data; + logic sb_bus_rsp_read, sb_bus_rsp_write; + logic sb_bus_rsp_error; + logic [63:0] sb_bus_rdata; + + //registers + logic [31:0] sbcs_reg; + logic [31:0] sbaddress0_reg; + logic [31:0] sbdata0_reg; + logic [31:0] sbdata1_reg; + + logic sb_abmem_cmd_arvalid, sb_abmem_cmd_awvalid, sb_abmem_cmd_wvalid; + logic sb_abmem_read_pend; + logic sb_cmd_awvalid, sb_cmd_wvalid, sb_cmd_arvalid; + logic sb_read_pend; + logic [31:0] sb_axi_addr; + logic [63:0] sb_axi_wrdata; + logic [2:0] sb_axi_size; + + logic dbg_dm_rst_l; + logic rst_l_sync; + + //clken + logic dbg_free_clken; + logic dbg_free_clk; + + logic sb_free_clken; + logic sb_free_clk; + + // clocking + // used for the abstract commands. + assign dbg_free_clken = dmi_reg_en | execute_command | (dbg_state != IDLE) | dbg_state_en | dec_tlu_dbg_halted | dec_tlu_mpc_halted_only | dec_tlu_debug_mode | dbg_halt_req | clk_override; + + // used for the system bus + assign sb_free_clken = dmi_reg_en | execute_command | sb_state_en | (sb_state != SBIDLE) | clk_override; + + rvoclkhdr dbg_free_cgc (.en(dbg_free_clken), .l1clk(dbg_free_clk), .*); + rvoclkhdr sb_free_cgc (.en(sb_free_clken), .l1clk(sb_free_clk), .*); + + // end clocking section + + // Reset logic + assign dbg_dm_rst_l = dbg_rst_l & (dmcontrol_reg[0] | scan_mode); + assign dbg_core_rst_l = ~dmcontrol_reg[1] | scan_mode; + + // synchronize the rst + rvsyncss #(1) rstl_syncff (.din(rst_l), .dout(rst_l_sync), .clk(free_clk), .rst_l(dbg_rst_l)); + + // system bus register + // sbcs[31:29], sbcs - [22]:sbbusyerror, [21]: sbbusy, [20]:sbreadonaddr, [19:17]:sbaccess, [16]:sbautoincrement, [15]:sbreadondata, [14:12]:sberror, sbsize=32, 128=0, 64/32/16/8 are legal + assign sbcs_reg[31:29] = 3'b1; + assign sbcs_reg[28:23] = '0; + assign sbcs_reg[19:15] = {sbcs_reg_int[19], ~sbcs_reg_int[18], sbcs_reg_int[17:15]}; + assign sbcs_reg[11:5] = 7'h20; + assign sbcs_reg[4:0] = 5'b01111; + assign sbcs_wren = (dmi_reg_addr == 7'h38) & dmi_reg_en & dmi_reg_wr_en & (sb_state == SBIDLE); + assign sbcs_sbbusyerror_wren = (sbcs_wren & dmi_reg_wdata[22]) | + (sbcs_reg[21] & dmi_reg_en & ((dmi_reg_wr_en & (dmi_reg_addr == 7'h39)) | (dmi_reg_addr == 7'h3c) | (dmi_reg_addr == 7'h3d))); + assign sbcs_sbbusyerror_din = ~(sbcs_wren & dmi_reg_wdata[22]); // Clear when writing one + + rvdffs #(1) sbcs_sbbusyerror_reg (.din(sbcs_sbbusyerror_din), .dout(sbcs_reg[22]), .en(sbcs_sbbusyerror_wren), .rst_l(dbg_dm_rst_l), .clk(sb_free_clk)); + rvdffs #(1) sbcs_sbbusy_reg (.din(sbcs_sbbusy_din), .dout(sbcs_reg[21]), .en(sbcs_sbbusy_wren), .rst_l(dbg_dm_rst_l), .clk(sb_free_clk)); + rvdffs #(1) sbcs_sbreadonaddr_reg (.din(dmi_reg_wdata[20]), .dout(sbcs_reg[20]), .en(sbcs_wren), .rst_l(dbg_dm_rst_l), .clk(sb_free_clk)); + rvdffs #(5) sbcs_misc_reg (.din({dmi_reg_wdata[19],~dmi_reg_wdata[18],dmi_reg_wdata[17:15]}), + .dout(sbcs_reg_int[19:15]), .en(sbcs_wren), .rst_l(dbg_dm_rst_l), .clk(sb_free_clk)); + rvdffs #(3) sbcs_error_reg (.din(sbcs_sberror_din[2:0]), .dout(sbcs_reg[14:12]), .en(sbcs_sberror_wren), .rst_l(dbg_dm_rst_l), .clk(sb_free_clk)); + + assign sbcs_unaligned = ((sbcs_reg[19:17] == 3'b001) & sbaddress0_reg[0]) | + ((sbcs_reg[19:17] == 3'b010) & (|sbaddress0_reg[1:0])) | + ((sbcs_reg[19:17] == 3'b011) & (|sbaddress0_reg[2:0])); + + assign sbcs_illegal_size = sbcs_reg[19]; // Anything bigger than 64 bits is illegal + + assign sbaddress0_incr[3:0] = ({4{(sbcs_reg[19:17] == 3'h0)}} & 4'b0001) | + ({4{(sbcs_reg[19:17] == 3'h1)}} & 4'b0010) | + ({4{(sbcs_reg[19:17] == 3'h2)}} & 4'b0100) | + ({4{(sbcs_reg[19:17] == 3'h3)}} & 4'b1000); + + // sbdata + assign sbdata0_reg_wren0 = dmi_reg_en & dmi_reg_wr_en & (dmi_reg_addr == 7'h3c); // write data only when single read is 0 + assign sbdata0_reg_wren1 = (sb_state == RSP_RD) & sb_state_en & ~sbcs_sberror_wren; + assign sbdata0_reg_wren = sbdata0_reg_wren0 | sbdata0_reg_wren1; + + assign sbdata1_reg_wren0 = dmi_reg_en & dmi_reg_wr_en & (dmi_reg_addr == 7'h3d); // write data only when single read is 0; + assign sbdata1_reg_wren1 = (sb_state == RSP_RD) & sb_state_en & ~sbcs_sberror_wren; + assign sbdata1_reg_wren = sbdata1_reg_wren0 | sbdata1_reg_wren1; + + assign sbdata0_din[31:0] = ({32{sbdata0_reg_wren0}} & dmi_reg_wdata[31:0]) | + ({32{sbdata0_reg_wren1}} & sb_bus_rdata[31:0]); + assign sbdata1_din[31:0] = ({32{sbdata1_reg_wren0}} & dmi_reg_wdata[31:0]) | + ({32{sbdata1_reg_wren1}} & sb_bus_rdata[63:32]); + + rvdffe #(32) dbg_sbdata0_reg (.*, .din(sbdata0_din[31:0]), .dout(sbdata0_reg[31:0]), .en(sbdata0_reg_wren), .rst_l(dbg_dm_rst_l)); + rvdffe #(32) dbg_sbdata1_reg (.*, .din(sbdata1_din[31:0]), .dout(sbdata1_reg[31:0]), .en(sbdata1_reg_wren), .rst_l(dbg_dm_rst_l)); + + // sbaddress + assign sbaddress0_reg_wren0 = dmi_reg_en & dmi_reg_wr_en & (dmi_reg_addr == 7'h39); + assign sbaddress0_reg_wren = sbaddress0_reg_wren0 | sbaddress0_reg_wren1; + assign sbaddress0_reg_din[31:0]= ({32{sbaddress0_reg_wren0}} & dmi_reg_wdata[31:0]) | + ({32{sbaddress0_reg_wren1}} & (32'(sbaddress0_reg[31:0] + {28'b0,sbaddress0_incr[3:0]}))); + rvdffe #(32) dbg_sbaddress0_reg (.*, .din(sbaddress0_reg_din[31:0]), .dout(sbaddress0_reg[31:0]), .en(sbaddress0_reg_wren), .rst_l(dbg_dm_rst_l)); + + assign sbreadonaddr_access = dmi_reg_en & dmi_reg_wr_en & (dmi_reg_addr == 7'h39) & sbcs_reg[20]; // if readonaddr is set the next command will start upon writing of addr0 + assign sbreadondata_access = dmi_reg_en & ~dmi_reg_wr_en & (dmi_reg_addr == 7'h3c) & sbcs_reg[15]; // if readondata is set the next command will start upon reading of data0 + assign sbdata0wr_access = dmi_reg_en & dmi_reg_wr_en & (dmi_reg_addr == 7'h3c); // write to sbdata0 will start write command to system bus + + // memory mapped registers + // dmcontrol register has only 5 bits implemented. 31: haltreq, 30: resumereq, 28: ackhavereset, 1: ndmreset, 0: dmactive. + // rest all the bits are zeroed out + // dmactive flop is reset based on core rst_l, all other flops use dm_rst_l + assign dmcontrol_wren = (dmi_reg_addr == 7'h10) & dmi_reg_en & dmi_reg_wr_en; + assign dmcontrol_reg[29] = '0; + assign dmcontrol_reg[27:2] = '0; + assign resumereq = dmcontrol_reg[30] & ~dmcontrol_reg[31] & dmcontrol_wren_Q; + rvdffs #(4) dmcontrolff (.din({dmi_reg_wdata[31:30],dmi_reg_wdata[28],dmi_reg_wdata[1]}), .dout({dmcontrol_reg[31:30], dmcontrol_reg[28], dmcontrol_reg[1]}), .en(dmcontrol_wren), .rst_l(dbg_dm_rst_l), .clk(dbg_free_clk)); + rvdffs #(1) dmcontrol_dmactive_ff (.din(dmi_reg_wdata[0]), .dout(dmcontrol_reg[0]), .en(dmcontrol_wren), .rst_l(dbg_rst_l), .clk(dbg_free_clk)); + rvdff #(1) dmcontrol_wrenff(.din(dmcontrol_wren), .dout(dmcontrol_wren_Q), .rst_l(dbg_dm_rst_l), .clk(dbg_free_clk)); + + // dmstatus register bits that are implemented + // [19:18]-havereset,[17:16]-resume ack, [9:8]-halted, [3:0]-version + // rest all the bits are zeroed out + //assign dmstatus_wren = (dmi_reg_addr[31:0] == 32'h11) & dmi_reg_en; + assign dmstatus_reg[31:20] = '0; + assign dmstatus_reg[19:18] = {2{dmstatus_havereset}}; + assign dmstatus_reg[15:14] = '0; + assign dmstatus_reg[7] = '1; + assign dmstatus_reg[6:4] = '0; + assign dmstatus_reg[17:16] = {2{dmstatus_resumeack}}; + assign dmstatus_reg[13:12] = {2{dmstatus_unavail}}; + assign dmstatus_reg[11:10] = {2{dmstatus_running}}; + assign dmstatus_reg[9:8] = {2{dmstatus_halted}}; + assign dmstatus_reg[3:0] = 4'h2; + + assign dmstatus_resumeack_wren = ((dbg_state == RESUMING) & dec_tlu_resume_ack) | (dmstatus_resumeack & resumereq & dmstatus_halted); + assign dmstatus_resumeack_din = (dbg_state == RESUMING) & dec_tlu_resume_ack; + + assign dmstatus_haveresetn_wren = (dmi_reg_addr == 7'h10) & dmi_reg_wdata[28] & dmi_reg_en & dmi_reg_wr_en & dmcontrol_reg[0]; // clear the havereset + assign dmstatus_havereset = ~dmstatus_haveresetn; + + assign dmstatus_unavail = dmcontrol_reg[1] | ~rst_l_sync; + assign dmstatus_running = ~(dmstatus_unavail | dmstatus_halted); + + rvdffs #(1) dmstatus_resumeack_reg (.din(dmstatus_resumeack_din), .dout(dmstatus_resumeack), .en(dmstatus_resumeack_wren), .rst_l(dbg_dm_rst_l), .clk(dbg_free_clk)); + rvdff #(1) dmstatus_halted_reg (.din(dec_tlu_dbg_halted & ~dec_tlu_mpc_halted_only), .dout(dmstatus_halted), .rst_l(dbg_dm_rst_l), .clk(dbg_free_clk)); + rvdffs #(1) dmstatus_haveresetn_reg (.din(1'b1), .dout(dmstatus_haveresetn), .en(dmstatus_haveresetn_wren), .rst_l(rst_l), .clk(dbg_free_clk)); + + // haltsum0 register + assign haltsum0_reg[31:1] = '0; + assign haltsum0_reg[0] = dmstatus_halted; + + // abstractcs register + // bits implemted are [12] - busy and [10:8]= command error + assign abstractcs_reg[31:13] = '0; + assign abstractcs_reg[11] = '0; + assign abstractcs_reg[7:4] = '0; + assign abstractcs_reg[3:0] = 4'h2; // One data register + + assign abstractcs_error_sel0 = abstractcs_reg[12] & ~(|abstractcs_reg[10:8]) & dmi_reg_en & ((dmi_reg_wr_en & ((dmi_reg_addr == 7'h16) | (dmi_reg_addr == 7'h17)) | (dmi_reg_addr == 7'h18)) | + (dmi_reg_addr == 7'h4) | (dmi_reg_addr == 7'h5)); + assign abstractcs_error_sel1 = execute_command & ~(|abstractcs_reg[10:8]) & + ((~((command_reg[31:24] == 8'b0) | (command_reg[31:24] == 8'h2))) | // Illegal command + (((command_reg[22:20] == 3'b011) | (command_reg[22])) & (command_reg[31:24] == 8'h2)) | // Illegal abstract memory size (can't be DW or higher) + ((command_reg[22:20] != 3'b010) & ((command_reg[31:24] == 8'h0) & command_reg[17])) | // Illegal abstract reg size + ((command_reg[31:24] == 8'h0) & command_reg[18])); //postexec for abstract register access + assign abstractcs_error_sel2 = ((core_dbg_cmd_done & core_dbg_cmd_fail) | // exception from core + (execute_command & (command_reg[31:24] == 8'h0) & // unimplemented regs + (((command_reg[15:12] == 4'h1) & (command_reg[11:5] != 0)) | (command_reg[15:13] != 0)))) & ~(|abstractcs_reg[10:8]); + assign abstractcs_error_sel3 = execute_command & (dbg_state != HALTED) & ~(|abstractcs_reg[10:8]); + assign abstractcs_error_sel4 = dbg_sb_bus_error & dbg_bus_clk_en & ~(|abstractcs_reg[10:8]);// sb bus error for abstract memory command + assign abstractcs_error_sel5 = execute_command & (command_reg[31:24] == 8'h2) & ~(|abstractcs_reg[10:8]) & + (((command_reg[22:20] == 3'b001) & data1_reg[0]) | ((command_reg[22:20] == 3'b010) & (|data1_reg[1:0]))); //Unaligned address for abstract memory + assign abstractcs_error_sel6 = (dmi_reg_addr == 7'h16) & dmi_reg_en & dmi_reg_wr_en; + + assign abstractcs_error_din[2:0] = abstractcs_error_sel0 ? 3'b001 : // writing command or abstractcs while a command was executing. Or accessing data0 + abstractcs_error_sel1 ? 3'b010 : // writing a illegal command type to cmd field of command + abstractcs_error_sel2 ? 3'b011 : // exception while running command + abstractcs_error_sel3 ? 3'b100 : // writing a comnand when not in the halted state + abstractcs_error_sel4 ? 3'b101 : // Bus error + abstractcs_error_sel5 ? 3'b111 : // unaligned or illegal size abstract memory command + abstractcs_error_sel6 ? (~dmi_reg_wdata[10:8] & abstractcs_reg[10:8]) : //W1C + abstractcs_reg[10:8]; //hold + + rvdffs #(1) dmabstractcs_busy_reg (.din(abstractcs_busy_din), .dout(abstractcs_reg[12]), .en(abstractcs_busy_wren), .rst_l(dbg_dm_rst_l), .clk(dbg_free_clk)); + rvdff #(3) dmabstractcs_error_reg (.din(abstractcs_error_din[2:0]), .dout(abstractcs_reg[10:8]), .rst_l(dbg_dm_rst_l), .clk(dbg_free_clk)); + + // abstract auto reg + assign abstractauto_reg_wren = dmi_reg_en & dmi_reg_wr_en & (dmi_reg_addr == 7'h18) & ~abstractcs_reg[12]; + rvdffs #(2) dbg_abstractauto_reg (.*, .din(dmi_reg_wdata[1:0]), .dout(abstractauto_reg[1:0]), .en(abstractauto_reg_wren), .rst_l(dbg_dm_rst_l), .clk(dbg_free_clk)); + + // command register - implemented all the bits in this register + // command[16] = 1: write, 0: read + assign execute_command_ns = command_wren | + (dmi_reg_en & ~abstractcs_reg[12] & (((dmi_reg_addr == 7'h4) & abstractauto_reg[0]) | ((dmi_reg_addr == 7'h5) & abstractauto_reg[1]))); + assign command_wren = (dmi_reg_addr == 7'h17) & dmi_reg_en & dmi_reg_wr_en; + assign command_regno_wren = command_wren | ((command_reg[31:24] == 8'h0) & command_reg[19] & (dbg_state == CMD_DONE) & ~(|abstractcs_reg[10:8])); // aarpostincrement + assign command_postexec_din = (dmi_reg_wdata[31:24] == 8'h0) & dmi_reg_wdata[18]; + assign command_transfer_din = (dmi_reg_wdata[31:24] == 8'h0) & dmi_reg_wdata[17]; + assign command_din[31:16] = {dmi_reg_wdata[31:24],1'b0,dmi_reg_wdata[22:19],command_postexec_din,command_transfer_din, dmi_reg_wdata[16]}; + assign command_din[15:0] = command_wren ? dmi_reg_wdata[15:0] : dbg_cmd_next_addr[15:0]; + rvdff #(1) execute_commandff (.*, .din(execute_command_ns), .dout(execute_command), .clk(dbg_free_clk), .rst_l(dbg_dm_rst_l)); + rvdffe #(16) dmcommand_reg (.*, .din(command_din[31:16]), .dout(command_reg[31:16]), .en(command_wren), .rst_l(dbg_dm_rst_l)); + rvdffe #(16) dmcommand_regno_reg (.*, .din(command_din[15:0]), .dout(command_reg[15:0]), .en(command_regno_wren), .rst_l(dbg_dm_rst_l)); + + // data0 reg + assign data0_reg_wren0 = (dmi_reg_en & dmi_reg_wr_en & (dmi_reg_addr == 7'h4) & (dbg_state == HALTED) & ~abstractcs_reg[12]); + assign data0_reg_wren1 = core_dbg_cmd_done & (dbg_state == CORE_CMD_WAIT) & ~command_reg[16]; + assign data0_reg_wren = data0_reg_wren0 | data0_reg_wren1 | data0_reg_wren2; + + assign data0_din[31:0] = ({32{data0_reg_wren0}} & dmi_reg_wdata[31:0]) | + ({32{data0_reg_wren1}} & core_dbg_rddata[31:0]) | + ({32{data0_reg_wren2}} & sb_bus_rdata[31:0]); + + rvdffe #(32) dbg_data0_reg (.*, .din(data0_din[31:0]), .dout(data0_reg[31:0]), .en(data0_reg_wren), .rst_l(dbg_dm_rst_l)); + + // data 1 + assign data1_reg_wren0 = (dmi_reg_en & dmi_reg_wr_en & (dmi_reg_addr == 7'h5) & (dbg_state == HALTED) & ~abstractcs_reg[12]); + assign data1_reg_wren1 = (dbg_state == CMD_DONE) & (command_reg[31:24] == 8'h2) & command_reg[19] & ~(|abstractcs_reg[10:8]); // aampostincrement + assign data1_reg_wren = data1_reg_wren0 | data1_reg_wren1; + + assign data1_din[31:0] = ({32{data1_reg_wren0}} & dmi_reg_wdata[31:0]) | + ({32{data1_reg_wren1}} & dbg_cmd_next_addr[31:0]); + + rvdffe #(32) dbg_data1_reg (.*, .din(data1_din[31:0]), .dout(data1_reg[31:0]), .en(data1_reg_wren), .rst_l(dbg_dm_rst_l)); + + rvdffs #(1) sb_abmem_cmd_doneff (.din(sb_abmem_cmd_done_in), .dout(sb_abmem_cmd_done), .en(sb_abmem_cmd_done_en), .clk(dbg_free_clk), .rst_l(dbg_dm_rst_l), .*); + rvdffs #(1) sb_abmem_data_doneff (.din(sb_abmem_data_done_in), .dout(sb_abmem_data_done), .en(sb_abmem_data_done_en), .clk(dbg_free_clk), .rst_l(dbg_dm_rst_l), .*); + + // FSM to control the debug mode entry, command send/recieve, and Resume flow. + always_comb begin + dbg_nxtstate = IDLE; + dbg_state_en = 1'b0; + abstractcs_busy_wren = 1'b0; + abstractcs_busy_din = 1'b0; + dbg_halt_req = dmcontrol_wren_Q & dmcontrol_reg[31]; // single pulse output to the core. Need to drive every time this register is written since core might be halted due to MPC + dbg_resume_req = 1'b0; // single pulse output to the core + dbg_sb_bus_error = 1'b0; + data0_reg_wren2 = 1'b0; + sb_abmem_cmd_done_in = 1'b0; + sb_abmem_data_done_in = 1'b0; + sb_abmem_cmd_done_en = 1'b0; + sb_abmem_data_done_en = 1'b0; + + case (dbg_state) + IDLE: begin + dbg_nxtstate = (dmstatus_reg[9] | dec_tlu_mpc_halted_only) ? HALTED : HALTING; // initiate the halt command to the core + dbg_state_en = dmcontrol_reg[31] | dmstatus_reg[9] | dec_tlu_mpc_halted_only; // when the jtag writes the halt bit in the DM register, OR when the status indicates H + dbg_halt_req = dmcontrol_reg[31]; // only when jtag has written the halt_req bit in the control. Removed debug mode qualification during MPC changes + end + HALTING : begin + dbg_nxtstate = HALTED; // Goto HALTED once the core sends an ACK + dbg_state_en = dmstatus_reg[9] | dec_tlu_mpc_halted_only; // core indicates halted + end + HALTED: begin + // wait for halted to go away before send to resume. Else start of new command + dbg_nxtstate = dmstatus_reg[9] ? (resumereq ? RESUMING : (((command_reg[31:24] == 8'h2) & abmem_addr_external) ? SB_CMD_START : CORE_CMD_START)) : + (dmcontrol_reg[31] ? HALTING : IDLE); // This is MPC halted case + dbg_state_en = (dmstatus_reg[9] & resumereq) | execute_command | ~(dmstatus_reg[9] | dec_tlu_mpc_halted_only); + abstractcs_busy_wren = dbg_state_en & ((dbg_nxtstate == CORE_CMD_START) | (dbg_nxtstate == SB_CMD_START)); // write busy when a new command was written by jtag + abstractcs_busy_din = 1'b1; + dbg_resume_req = dbg_state_en & (dbg_nxtstate == RESUMING); // single cycle pulse to core if resuming + end + CORE_CMD_START: begin + // Don't execute the command if cmderror or transfer=0 for abstract register access + dbg_nxtstate = ((|abstractcs_reg[10:8]) | ((command_reg[31:24] == 8'h0) & ~command_reg[17])) ? CMD_DONE : CORE_CMD_WAIT; // new command sent to the core + dbg_state_en = dbg_cmd_valid | (|abstractcs_reg[10:8]) | ((command_reg[31:24] == 8'h0) & ~command_reg[17]); + end + CORE_CMD_WAIT: begin + dbg_nxtstate = CMD_DONE; + dbg_state_en = core_dbg_cmd_done; // go to done state for one cycle after completing current command + end + SB_CMD_START: begin + dbg_nxtstate = (|abstractcs_reg[10:8]) ? CMD_DONE : SB_CMD_SEND; + dbg_state_en = (dbg_bus_clk_en & ~sb_cmd_pending) | (|abstractcs_reg[10:8]); + end + SB_CMD_SEND: begin + sb_abmem_cmd_done_in = 1'b1; + sb_abmem_data_done_in= 1'b1; + sb_abmem_cmd_done_en = (sb_bus_cmd_read | sb_bus_cmd_write_addr) & dbg_bus_clk_en; + sb_abmem_data_done_en= (sb_bus_cmd_read | sb_bus_cmd_write_data) & dbg_bus_clk_en; + dbg_nxtstate = SB_CMD_RESP; + dbg_state_en = (sb_abmem_cmd_done | sb_abmem_cmd_done_en) & (sb_abmem_data_done | sb_abmem_data_done_en) & dbg_bus_clk_en; + end + SB_CMD_RESP: begin + dbg_nxtstate = CMD_DONE; + dbg_state_en = (sb_bus_rsp_read | sb_bus_rsp_write) & dbg_bus_clk_en; + dbg_sb_bus_error = (sb_bus_rsp_read | sb_bus_rsp_write) & sb_bus_rsp_error & dbg_bus_clk_en; + data0_reg_wren2 = dbg_state_en & ~sb_abmem_cmd_write & ~dbg_sb_bus_error; + end + CMD_DONE: begin + dbg_nxtstate = HALTED; + dbg_state_en = 1'b1; + abstractcs_busy_wren = dbg_state_en; // remove the busy bit from the abstracts ( bit 12 ) + abstractcs_busy_din = 1'b0; + sb_abmem_cmd_done_in = 1'b0; + sb_abmem_data_done_in= 1'b0; + sb_abmem_cmd_done_en = 1'b1; + sb_abmem_data_done_en= 1'b1; + end + RESUMING : begin + dbg_nxtstate = IDLE; + dbg_state_en = dmstatus_reg[17]; // resume ack has been updated in the dmstatus register + end + /* All legal values are handled above. Exclude the default part from coverage. */ + /*pragma coverage off*/ + default : begin + dbg_nxtstate = IDLE; + dbg_state_en = 1'b0; + abstractcs_busy_wren = 1'b0; + abstractcs_busy_din = 1'b0; + dbg_halt_req = 1'b0; // single pulse output to the core + dbg_resume_req = 1'b0; // single pulse output to the core + dbg_sb_bus_error = 1'b0; + data0_reg_wren2 = 1'b0; + sb_abmem_cmd_done_in = 1'b0; + sb_abmem_data_done_in = 1'b0; + sb_abmem_cmd_done_en = 1'b0; + sb_abmem_data_done_en = 1'b0; + end + /*pragma coverage on*/ + endcase + end // always_comb begin + + assign dmi_reg_rdata_din[31:0] = ({32{dmi_reg_addr == 7'h4}} & data0_reg[31:0]) | + ({32{dmi_reg_addr == 7'h5}} & data1_reg[31:0]) | + ({32{dmi_reg_addr == 7'h10}} & {2'b0,dmcontrol_reg[29],1'b0,dmcontrol_reg[27:0]}) | // Read0 to Write only bits + ({32{dmi_reg_addr == 7'h11}} & dmstatus_reg[31:0]) | + ({32{dmi_reg_addr == 7'h16}} & abstractcs_reg[31:0]) | + ({32{dmi_reg_addr == 7'h17}} & command_reg[31:0]) | + ({32{dmi_reg_addr == 7'h18}} & {30'h0,abstractauto_reg[1:0]}) | + ({32{dmi_reg_addr == 7'h40}} & haltsum0_reg[31:0]) | + ({32{dmi_reg_addr == 7'h38}} & sbcs_reg[31:0]) | + ({32{dmi_reg_addr == 7'h39}} & sbaddress0_reg[31:0]) | + ({32{dmi_reg_addr == 7'h3c}} & sbdata0_reg[31:0]) | + ({32{dmi_reg_addr == 7'h3d}} & sbdata1_reg[31:0]); + + + rvdffs #($bits(state_t)) dbg_state_reg (.din(dbg_nxtstate), .dout({dbg_state}), .en(dbg_state_en), .rst_l(dbg_dm_rst_l & rst_l), .clk(dbg_free_clk)); + rvdffe #(32) dmi_rddata_reg (.din(dmi_reg_rdata_din[31:0]), .dout(dmi_reg_rdata[31:0]), .en(dmi_reg_en), .rst_l(dbg_dm_rst_l), .clk(clk), .*); + + assign abmem_addr[31:0] = data1_reg[31:0]; + assign abmem_addr_core_local = (abmem_addr_in_dccm_region | abmem_addr_in_iccm_region | abmem_addr_in_pic_region); + assign abmem_addr_external = ~abmem_addr_core_local; + + assign abmem_addr_in_dccm_region = (abmem_addr[31:28] == pt.DCCM_REGION) & pt.DCCM_ENABLE; + assign abmem_addr_in_iccm_region = (abmem_addr[31:28] == pt.ICCM_REGION) & pt.ICCM_ENABLE; + assign abmem_addr_in_pic_region = (abmem_addr[31:28] == pt.PIC_REGION); + + // interface for the core + assign dbg_cmd_addr[31:0] = (command_reg[31:24] == 8'h2) ? data1_reg[31:0] : {20'b0, command_reg[11:0]}; + assign dbg_cmd_wrdata[31:0] = data0_reg[31:0]; + assign dbg_cmd_valid = (dbg_state == CORE_CMD_START) & ~((|abstractcs_reg[10:8]) | ((command_reg[31:24] == 8'h0) & ~command_reg[17]) | ((command_reg[31:24] == 8'h2) & abmem_addr_external)) & dma_dbg_ready; + assign dbg_cmd_write = command_reg[16]; + assign dbg_cmd_type[1:0] = (command_reg[31:24] == 8'h2) ? 2'b10 : {1'b0, (command_reg[15:12] == 4'b0)}; + assign dbg_cmd_size[1:0] = command_reg[21:20]; + + assign dbg_cmd_addr_incr[3:0] = (command_reg[31:24] == 8'h2) ? (4'h1 << sb_abmem_cmd_size[1:0]) : 4'h1; + assign dbg_cmd_curr_addr[31:0] = (command_reg[31:24] == 8'h2) ? data1_reg[31:0] : {16'b0, command_reg[15:0]}; + assign dbg_cmd_next_addr[31:0] = dbg_cmd_curr_addr[31:0] + {28'h0,dbg_cmd_addr_incr[3:0]}; + + // Ask DMA to stop taking bus trxns since debug request is done + assign dbg_dma_bubble = ((dbg_state == CORE_CMD_START) & ~(|abstractcs_reg[10:8])) | (dbg_state == CORE_CMD_WAIT); + + assign sb_cmd_pending = (sb_state == CMD_RD) | (sb_state == CMD_WR) | (sb_state == CMD_WR_ADDR) | (sb_state == CMD_WR_DATA) | (sb_state == RSP_RD) | (sb_state == RSP_WR); + assign sb_abmem_cmd_pending = (dbg_state == SB_CMD_START) | (dbg_state == SB_CMD_SEND) | (dbg_state== SB_CMD_RESP); + + + // system bus FSM + always_comb begin + sb_nxtstate = SBIDLE; + sb_state_en = 1'b0; + sbcs_sbbusy_wren = 1'b0; + sbcs_sbbusy_din = 1'b0; + sbcs_sberror_wren = 1'b0; + sbcs_sberror_din[2:0] = 3'b0; + sbaddress0_reg_wren1 = 1'b0; + case (sb_state) + SBIDLE: begin + sb_nxtstate = sbdata0wr_access ? WAIT_WR : WAIT_RD; + sb_state_en = (sbdata0wr_access | sbreadondata_access | sbreadonaddr_access) & ~(|sbcs_reg[14:12]) & ~sbcs_reg[22]; + sbcs_sbbusy_wren = sb_state_en; // set the single read bit if it is a singlread command + sbcs_sbbusy_din = 1'b1; + sbcs_sberror_wren = sbcs_wren & (|dmi_reg_wdata[14:12]); // write to clear the error bits + sbcs_sberror_din[2:0] = ~dmi_reg_wdata[14:12] & sbcs_reg[14:12]; + end + WAIT_RD: begin + sb_nxtstate = (sbcs_unaligned | sbcs_illegal_size) ? DONE : CMD_RD; + sb_state_en = (dbg_bus_clk_en & ~sb_abmem_cmd_pending) | sbcs_unaligned | sbcs_illegal_size; + sbcs_sberror_wren = sbcs_unaligned | sbcs_illegal_size; + sbcs_sberror_din[2:0] = sbcs_unaligned ? 3'b011 : 3'b100; + end + WAIT_WR: begin + sb_nxtstate = (sbcs_unaligned | sbcs_illegal_size) ? DONE : CMD_WR; + sb_state_en = (dbg_bus_clk_en & ~sb_abmem_cmd_pending) | sbcs_unaligned | sbcs_illegal_size; + sbcs_sberror_wren = sbcs_unaligned | sbcs_illegal_size; + sbcs_sberror_din[2:0] = sbcs_unaligned ? 3'b011 : 3'b100; + end + CMD_RD : begin + sb_nxtstate = RSP_RD; + sb_state_en = sb_bus_cmd_read & dbg_bus_clk_en; + end + CMD_WR : begin + sb_nxtstate = (sb_bus_cmd_write_addr & sb_bus_cmd_write_data) ? RSP_WR : (sb_bus_cmd_write_data ? CMD_WR_ADDR : CMD_WR_DATA); + sb_state_en = (sb_bus_cmd_write_addr | sb_bus_cmd_write_data) & dbg_bus_clk_en; + end + CMD_WR_ADDR : begin + sb_nxtstate = RSP_WR; + sb_state_en = sb_bus_cmd_write_addr & dbg_bus_clk_en; + end + CMD_WR_DATA : begin + sb_nxtstate = RSP_WR; + sb_state_en = sb_bus_cmd_write_data & dbg_bus_clk_en; + end + RSP_RD: begin + sb_nxtstate = DONE; + sb_state_en = sb_bus_rsp_read & dbg_bus_clk_en; + sbcs_sberror_wren = sb_state_en & sb_bus_rsp_error; + sbcs_sberror_din[2:0] = 3'b010; + end + RSP_WR: begin + sb_nxtstate = DONE; + sb_state_en = sb_bus_rsp_write & dbg_bus_clk_en; + sbcs_sberror_wren = sb_state_en & sb_bus_rsp_error; + sbcs_sberror_din[2:0] = 3'b010; + end + DONE: begin + sb_nxtstate = SBIDLE; + sb_state_en = 1'b1; + sbcs_sbbusy_wren = 1'b1; // reset the single read + sbcs_sbbusy_din = 1'b0; + sbaddress0_reg_wren1 = sbcs_reg[16] & (sbcs_reg[14:12] == 3'b0); // auto increment was set and no error. Update to new address after completing the current command + end + /* All legal values are handled above. Exclude the default part from coverage. */ + /*pragma coverage off*/ + default : begin + sb_nxtstate = SBIDLE; + sb_state_en = 1'b0; + sbcs_sbbusy_wren = 1'b0; + sbcs_sbbusy_din = 1'b0; + sbcs_sberror_wren = 1'b0; + sbcs_sberror_din[2:0] = 3'b0; + sbaddress0_reg_wren1 = 1'b0; + end + /*pragma coverage on*/ + endcase + end // always_comb begin + + rvdffs #($bits(sb_state_t)) sb_state_reg (.din(sb_nxtstate), .dout({sb_state}), .en(sb_state_en), .rst_l(dbg_dm_rst_l), .clk(sb_free_clk)); + + assign sb_abmem_cmd_write = command_reg[16]; + assign sb_abmem_cmd_size[2:0] = {1'b0, command_reg[21:20]}; + assign sb_abmem_cmd_addr[31:0] = abmem_addr[31:0]; + assign sb_abmem_cmd_wdata[31:0] = data0_reg[31:0]; + + assign sb_cmd_size[2:0] = sbcs_reg[19:17]; + assign sb_cmd_wdata[63:0] = {sbdata1_reg[31:0], sbdata0_reg[31:0]}; + assign sb_cmd_addr[31:0] = sbaddress0_reg[31:0]; + + assign sb_abmem_cmd_awvalid = (dbg_state == SB_CMD_SEND) & sb_abmem_cmd_write & ~sb_abmem_cmd_done; + assign sb_abmem_cmd_wvalid = (dbg_state == SB_CMD_SEND) & sb_abmem_cmd_write & ~sb_abmem_data_done; + assign sb_abmem_cmd_arvalid = (dbg_state == SB_CMD_SEND) & ~sb_abmem_cmd_write & ~sb_abmem_cmd_done & ~sb_abmem_data_done; + assign sb_abmem_read_pend = (dbg_state == SB_CMD_RESP) & ~sb_abmem_cmd_write; + + assign sb_cmd_awvalid = ((sb_state == CMD_WR) | (sb_state == CMD_WR_ADDR)); + assign sb_cmd_wvalid = ((sb_state == CMD_WR) | (sb_state == CMD_WR_DATA)); + assign sb_cmd_arvalid = (sb_state == CMD_RD); + assign sb_read_pend = (sb_state == RSP_RD); + + assign sb_axi_size[2:0] = (sb_abmem_cmd_awvalid | sb_abmem_cmd_wvalid | sb_abmem_cmd_arvalid | sb_abmem_read_pend) ? sb_abmem_cmd_size[2:0] : sb_cmd_size[2:0]; + assign sb_axi_addr[31:0] = (sb_abmem_cmd_awvalid | sb_abmem_cmd_wvalid | sb_abmem_cmd_arvalid | sb_abmem_read_pend) ? sb_abmem_cmd_addr[31:0] : sb_cmd_addr[31:0]; + assign sb_axi_wrdata[63:0] = (sb_abmem_cmd_awvalid | sb_abmem_cmd_wvalid) ? {2{sb_abmem_cmd_wdata[31:0]}} : sb_cmd_wdata[63:0]; + + // Generic bus response signals + assign sb_bus_cmd_read = sb_axi_arvalid & sb_axi_arready; + assign sb_bus_cmd_write_addr = sb_axi_awvalid & sb_axi_awready; + assign sb_bus_cmd_write_data = sb_axi_wvalid & sb_axi_wready; + + assign sb_bus_rsp_read = sb_axi_rvalid & sb_axi_rready; + assign sb_bus_rsp_write = sb_axi_bvalid & sb_axi_bready; + assign sb_bus_rsp_error = (sb_bus_rsp_read & (|(sb_axi_rresp[1:0]))) | (sb_bus_rsp_write & (|(sb_axi_bresp[1:0]))); + + // AXI Request signals + assign sb_axi_awvalid = sb_abmem_cmd_awvalid | sb_cmd_awvalid; + assign sb_axi_awaddr[31:0] = sb_axi_addr[31:0]; + assign sb_axi_awid[pt.SB_BUS_TAG-1:0] = '0; + assign sb_axi_awsize[2:0] = sb_axi_size[2:0]; + assign sb_axi_awprot[2:0] = 3'b001; + assign sb_axi_awcache[3:0] = 4'b1111; + assign sb_axi_awregion[3:0] = sb_axi_addr[31:28]; + assign sb_axi_awlen[7:0] = '0; + assign sb_axi_awburst[1:0] = 2'b01; + assign sb_axi_awqos[3:0] = '0; + assign sb_axi_awlock = '0; + + assign sb_axi_wvalid = sb_abmem_cmd_wvalid | sb_cmd_wvalid; + assign sb_axi_wdata[63:0] = ({64{(sb_axi_size[2:0] == 3'h0)}} & {8{sb_axi_wrdata[7:0]}}) | + ({64{(sb_axi_size[2:0] == 3'h1)}} & {4{sb_axi_wrdata[15:0]}}) | + ({64{(sb_axi_size[2:0] == 3'h2)}} & {2{sb_axi_wrdata[31:0]}}) | + ({64{(sb_axi_size[2:0] == 3'h3)}} & {sb_axi_wrdata[63:0]}); + assign sb_axi_wstrb[7:0] = ({8{(sb_axi_size[2:0] == 3'h0)}} & (8'h1 << sb_axi_addr[2:0])) | + ({8{(sb_axi_size[2:0] == 3'h1)}} & (8'h3 << {sb_axi_addr[2:1],1'b0})) | + ({8{(sb_axi_size[2:0] == 3'h2)}} & (8'hf << {sb_axi_addr[2],2'b0})) | + ({8{(sb_axi_size[2:0] == 3'h3)}} & 8'hff); + assign sb_axi_wlast = '1; + + assign sb_axi_arvalid = sb_abmem_cmd_arvalid | sb_cmd_arvalid; + assign sb_axi_araddr[31:0] = sb_axi_addr[31:0]; + assign sb_axi_arid[pt.SB_BUS_TAG-1:0] = '0; + assign sb_axi_arsize[2:0] = sb_axi_size[2:0]; + assign sb_axi_arprot[2:0] = 3'b001; + assign sb_axi_arcache[3:0] = 4'b0; + assign sb_axi_arregion[3:0] = sb_axi_addr[31:28]; + assign sb_axi_arlen[7:0] = '0; + assign sb_axi_arburst[1:0] = 2'b01; + assign sb_axi_arqos[3:0] = '0; + assign sb_axi_arlock = '0; + + // AXI Response signals + assign sb_axi_bready = 1'b1; + + assign sb_axi_rready = 1'b1; + assign sb_bus_rdata[63:0] = ({64{sb_axi_size == 3'h0}} & ((sb_axi_rdata[63:0] >> 8*sb_axi_addr[2:0]) & 64'hff)) | + ({64{sb_axi_size == 3'h1}} & ((sb_axi_rdata[63:0] >> 16*sb_axi_addr[2:1]) & 64'hffff)) | + ({64{sb_axi_size == 3'h2}} & ((sb_axi_rdata[63:0] >> 32*sb_axi_addr[2]) & 64'hffff_ffff)) | + ({64{sb_axi_size == 3'h3}} & sb_axi_rdata[63:0]); + +`ifdef RV_ASSERT_ON +// assertion. +// when the resume_ack is asserted then the dec_tlu_dbg_halted should be 0 + dm_check_resume_and_halted: assert property (@(posedge clk) disable iff(~rst_l) (~dec_tlu_resume_ack | ~dec_tlu_dbg_halted)); + + assert_b2b_haltreq: assert property (@(posedge clk) disable iff (~(rst_l)) (##1 dbg_halt_req |=> ~dbg_halt_req)); // One cycle delay to fix weird issue around reset + assert_halt_resume_onehot: assert #0 ($onehot0({dbg_halt_req, dbg_resume_req})); +`endif +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/el2_dec.sv b/designs/Caliptra/src/caliptra-rtl/el2_dec.sv new file mode 100644 index 0000000..d53430a --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/el2_dec.sv @@ -0,0 +1,483 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2020 Western Digital Corporation or its affiliates. +// +// 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. + +// dec: decode unit - decode, bypassing, ARF, interrupts +// +//******************************************************************************** +// $Id$ +// +// +// Function: Decode +// Comments: Decode, dependency scoreboard, ARF +// +// +// A -> D -> EX1 ... WB +// +//******************************************************************************** + +module el2_dec + import el2_pkg::*; +#( + `include "el2_param.vh" +) ( + input logic clk, // Clock only while core active. Through one clock header. For flops with second clock header built in. Connected to ACTIVE_L2CLK. + input logic active_clk, // Clock only while core active. Through two clock headers. For flops without second clock header built in. + input logic free_clk, // Clock always. Through two clock headers. For flops without second clock header built in. + input logic free_l2clk, // Clock always. Through one clock header. For flops with second header built in. + + input logic lsu_fastint_stall_any, // needed by lsu for 2nd pass of dma with ecc correction, stall next cycle + + output logic dec_extint_stall, // Stall on external interrupt + + output logic dec_i0_decode_d, // Valid instruction at D-stage and not blocked + output logic dec_pause_state_cg, // to top for active state clock gating + + output logic dec_tlu_core_empty, + + input logic rst_l, // reset, active low + // rst_vec is supposed to be connected to a constant in the top level + /*pragma coverage off*/ + input logic [31:1] rst_vec, // reset vector, from core pins + /*pragma coverage on*/ + + input logic nmi_int, // NMI pin + // nmi_vec is supposed to be connected to a constant in the top level + /*pragma coverage off*/ + input logic [31:1] nmi_vec, // NMI vector, from pins + /*pragma coverage on*/ + + input logic i_cpu_halt_req, // Asynchronous Halt request to CPU + input logic i_cpu_run_req, // Asynchronous Restart request to CPU + + output logic o_cpu_halt_status, // Halt status of core (pmu/fw) + output logic o_cpu_halt_ack, // Halt request ack + output logic o_cpu_run_ack, // Run request ack + output logic o_debug_mode_status, // Core to the PMU that core is in debug mode. When core is in debug mode, the PMU should refrain from sendng a halt or run request + + /*pragma coverage off*/ + input logic [31:4] core_id, // CORE ID + /*pragma coverage on*/ + + // external MPC halt/run interface + input logic mpc_debug_halt_req, // Async halt request + input logic mpc_debug_run_req, // Async run request + input logic mpc_reset_run_req, // Run/halt after reset + output logic mpc_debug_halt_ack, // Halt ack + output logic mpc_debug_run_ack, // Run ack + output logic debug_brkpt_status, // debug breakpoint + + input logic exu_pmu_i0_br_misp, // slot 0 branch misp + input logic exu_pmu_i0_br_ataken, // slot 0 branch actual taken + input logic exu_pmu_i0_pc4, // slot 0 4 byte branch + + + input logic lsu_nonblock_load_valid_m, // valid nonblock load at m + input logic [pt.LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_tag_m, // -> corresponding tag + input logic lsu_nonblock_load_inv_r, // invalidate request for nonblock load r + input logic [pt.LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_inv_tag_r, // -> corresponding tag + input logic lsu_nonblock_load_data_valid, // valid nonblock load data back + input logic lsu_nonblock_load_data_error, // nonblock load bus error + input logic [pt.LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_data_tag, // -> corresponding tag + input logic [31:0] lsu_nonblock_load_data, // nonblock load data + + input logic lsu_pmu_bus_trxn, // D side bus transaction + input logic lsu_pmu_bus_misaligned, // D side bus misaligned + input logic lsu_pmu_bus_error, // D side bus error + input logic lsu_pmu_bus_busy, // D side bus busy + input logic lsu_pmu_misaligned_m, // D side load or store misaligned + input logic lsu_pmu_load_external_m, // D side bus load + input logic lsu_pmu_store_external_m, // D side bus store + input logic dma_pmu_dccm_read, // DMA DCCM read + input logic dma_pmu_dccm_write, // DMA DCCM write + input logic dma_pmu_any_read, // DMA read + input logic dma_pmu_any_write, // DMA write + + input logic [31:1] lsu_fir_addr, // Fast int address + input logic [ 1:0] lsu_fir_error, // Fast int lookup error + + input logic ifu_pmu_instr_aligned, // aligned instructions + input logic ifu_pmu_fetch_stall, // fetch unit stalled + input logic ifu_pmu_ic_miss, // icache miss + input logic ifu_pmu_ic_hit, // icache hit + input logic ifu_pmu_bus_error, // Instruction side bus error + input logic ifu_pmu_bus_busy, // Instruction side bus busy + input logic ifu_pmu_bus_trxn, // Instruction side bus transaction + + input logic ifu_ic_error_start, // IC single bit error + input logic ifu_iccm_rd_ecc_single_err, // ICCM single bit error + + input logic [ 3:0] lsu_trigger_match_m, + input logic dbg_cmd_valid, // debugger abstract command valid + input logic dbg_cmd_write, // command is a write + input logic [ 1:0] dbg_cmd_type, // command type + input logic [31:0] dbg_cmd_addr, // command address + input logic [ 1:0] dbg_cmd_wrdata, // command write data, for fence/fence_i + + + input logic ifu_i0_icaf, // icache access fault + input logic [1:0] ifu_i0_icaf_type, // icache access fault type + + input logic ifu_i0_icaf_second, // i0 has access fault on second 2B of 4B inst + input logic ifu_i0_dbecc, // icache/iccm double-bit error + + input logic lsu_idle_any, // lsu idle for halting + + input el2_br_pkt_t i0_brp, // branch packet + input logic [pt.BTB_ADDR_HI:pt.BTB_ADDR_LO] ifu_i0_bp_index, // BP index + input logic [ pt.BHT_GHR_SIZE-1:0] ifu_i0_bp_fghr, // BP FGHR + input logic [ pt.BTB_BTAG_SIZE-1:0] ifu_i0_bp_btag, // BP tag + input logic [ $clog2(pt.BTB_SIZE)-1:0] ifu_i0_fa_index, // Fully associt btb index + + input el2_lsu_error_pkt_t lsu_error_pkt_r, // LSU exception/error packet + input logic lsu_single_ecc_error_incr, // LSU inc SB error counter + + input logic lsu_imprecise_error_load_any, // LSU imprecise load bus error + input logic lsu_imprecise_error_store_any, // LSU imprecise store bus error + input logic [31:0] lsu_imprecise_error_addr_any, // LSU imprecise bus error address + + input logic [31:0] exu_div_result, // final div result + input logic exu_div_wren, // Divide write enable to GPR + + input logic [31:0] exu_csr_rs1_x, // rs1 for csr instruction + + input logic [31:0] lsu_result_m, // load result + input logic [31:0] lsu_result_corr_r, // load result - corrected load data + + input logic lsu_load_stall_any, // This is for blocking loads + input logic lsu_store_stall_any, // This is for blocking stores + input logic dma_dccm_stall_any, // stall any load/store at decode, pmu event + input logic dma_iccm_stall_any, // iccm stalled, pmu event + + input logic iccm_dma_sb_error, // ICCM DMA single bit error + + input logic exu_flush_final, // slot0 flush + + input logic [31:1] exu_npc_r, // next PC + + input logic [31:0] exu_i0_result_x, // alu result x + + + input logic ifu_i0_valid, // fetch valids to instruction buffer + input logic [31:0] ifu_i0_instr, // fetch inst's to instruction buffer + input logic [31:1] ifu_i0_pc, // pc's for instruction buffer + input logic ifu_i0_pc4, // indication of 4B or 2B for corresponding inst + input logic [31:1] exu_i0_pc_x, // pc's for e1 from the alu's + + input logic mexintpend, // External interrupt pending + input logic timer_int, // Timer interrupt pending (from pin) + input logic soft_int, // Software interrupt pending (from pin) + + input logic [7:0] pic_claimid, // PIC claimid + input logic [3:0] pic_pl, // PIC priv level + input logic mhwakeup, // High priority wakeup + + output logic [3:0] dec_tlu_meicurpl, // to PIC, Current priv level + output logic [3:0] dec_tlu_meipt, // to PIC + + input logic [70:0] ifu_ic_debug_rd_data, // diagnostic icache read data + input logic ifu_ic_debug_rd_data_valid, // diagnostic icache read data valid + output el2_cache_debug_pkt_t dec_tlu_ic_diag_pkt, // packet of DICAWICS, DICAD0/1, DICAGO info for icache diagnostics + + + // Debug start + input logic dbg_halt_req, // DM requests a halt + input logic dbg_resume_req, // DM requests a resume + input logic ifu_miss_state_idle, // I-side miss buffer empty + + output logic dec_tlu_dbg_halted, // Core is halted and ready for debug command + output logic dec_tlu_debug_mode, // Core is in debug mode + output logic dec_tlu_resume_ack, // Resume acknowledge + output logic dec_tlu_flush_noredir_r, // Tell fetch to idle on this flush + output logic dec_tlu_mpc_halted_only, // Core is halted only due to MPC + output logic dec_tlu_flush_leak_one_r, // single step + output logic dec_tlu_flush_err_r, // iside perr/ecc rfpc + output logic [31:2] dec_tlu_meihap, // Fast ext int base + + output logic dec_debug_wdata_rs1_d, // insert debug write data into rs1 at decode + + output logic [31:0] dec_dbg_rddata, // debug command read data + + output logic dec_dbg_cmd_done, // abstract command is done + output logic dec_dbg_cmd_fail, // abstract command failed (illegal reg address) + + output el2_trigger_pkt_t [3:0] trigger_pkt_any, // info needed by debug trigger blocks + + output logic dec_tlu_force_halt, // halt has been forced + // Debug end + // branch info from pipe0 for errors or counter updates + input logic [1:0] exu_i0_br_hist_r, // history + input logic exu_i0_br_error_r, // error + input logic exu_i0_br_start_error_r, // start error + input logic exu_i0_br_valid_r, // valid + input logic exu_i0_br_mp_r, // mispredict + input logic exu_i0_br_middle_r, // middle of bank + + // branch info from pipe1 for errors or counter updates + + input logic exu_i0_br_way_r, // way hit or repl + + output logic dec_i0_rs1_en_d, // Qualify GPR RS1 data + output logic dec_i0_rs2_en_d, // Qualify GPR RS2 data + output logic [31:0] gpr_i0_rs1_d, // gpr rs1 data + output logic [31:0] gpr_i0_rs2_d, // gpr rs2 data + + output logic [31:0] dec_i0_immed_d, // immediate data + output logic [12:1] dec_i0_br_immed_d, // br immediate data + + output el2_alu_pkt_t i0_ap, // alu packet + + output logic dec_i0_alu_decode_d, // schedule on D-stage alu + output logic dec_i0_branch_d, // Branch in D-stage + + output logic dec_i0_select_pc_d, // select pc onto rs1 for jal's + + output logic [31:1] dec_i0_pc_d, // pc's at decode + output logic [ 3:0] dec_i0_rs1_bypass_en_d, // rs1 bypass enable + output logic [ 3:0] dec_i0_rs2_bypass_en_d, // rs2 bypass enable + + output logic [31:0] dec_i0_result_r, // Result R-stage + + output el2_lsu_pkt_t lsu_p, // lsu packet + output logic dec_qual_lsu_d, // LSU instruction at D. Use to quiet LSU operands + output el2_mul_pkt_t mul_p, // mul packet + output el2_div_pkt_t div_p, // div packet + output logic dec_div_cancel, // cancel divide operation + + output logic [11:0] dec_lsu_offset_d, // 12b offset for load/store addresses + + output logic dec_csr_ren_d, // CSR read enable + output logic [31:0] dec_csr_rddata_d, // CSR read data + + output logic dec_tlu_flush_lower_r, // tlu flush due to late mp, exception, rfpc, or int + output logic dec_tlu_flush_lower_wb, + output logic [31:1] dec_tlu_flush_path_r, // tlu flush target + output logic dec_tlu_i0_kill_writeb_r, // I0 is flushed, don't writeback any results to arch state + output logic dec_tlu_fence_i_r, // flush is a fence_i rfnpc, flush icache + + output logic [31:1] pred_correct_npc_x, // npc if prediction is correct at e2 stage + + output el2_br_tlu_pkt_t dec_tlu_br0_r_pkt, // slot 0 branch predictor update packet + + output logic dec_tlu_perfcnt0, // toggles when slot0 perf counter 0 has an event inc + output logic dec_tlu_perfcnt1, // toggles when slot0 perf counter 1 has an event inc + output logic dec_tlu_perfcnt2, // toggles when slot0 perf counter 2 has an event inc + output logic dec_tlu_perfcnt3, // toggles when slot0 perf counter 3 has an event inc + + output el2_predict_pkt_t dec_i0_predict_p_d, // prediction packet to alus + output logic [pt.BHT_GHR_SIZE-1:0] i0_predict_fghr_d, // DEC predict fghr + output logic [pt.BTB_ADDR_HI:pt.BTB_ADDR_LO] i0_predict_index_d, // DEC predict index + output logic [pt.BTB_BTAG_SIZE-1:0] i0_predict_btag_d, // DEC predict branch tag + + output logic [$clog2(pt.BTB_SIZE)-1:0] dec_fa_error_index, // Fully associt btb error index + + output logic dec_lsu_valid_raw_d, + + output logic [31:0] dec_tlu_mrac_ff, // CSR for memory region control + + output logic [1:0] dec_data_en, // clock-gate control logic + output logic [1:0] dec_ctl_en, + + input logic [15:0] ifu_i0_cinst, // 16b compressed instruction + + output el2_trace_pkt_t trace_rv_trace_pkt, // trace packet + + // PMP signals + output el2_pmp_cfg_pkt_t pmp_pmpcfg [pt.PMP_ENTRIES], + output logic [31:0] pmp_pmpaddr[pt.PMP_ENTRIES], + +`ifdef RV_USER_MODE + + // Privilege mode + output logic priv_mode, + output logic priv_mode_eff, + output logic priv_mode_ns, + + // mseccfg CSR content for PMP + output el2_mseccfg_pkt_t mseccfg, + +`endif + + // feature disable from mfdc + output logic dec_tlu_external_ldfwd_disable, // disable external load forwarding + output logic dec_tlu_sideeffect_posted_disable, // disable posted stores to side-effect address + output logic dec_tlu_core_ecc_disable, // disable core ECC + output logic dec_tlu_bpred_disable, // disable branch prediction + output logic dec_tlu_wb_coalescing_disable, // disable writebuffer coalescing + output logic [2:0] dec_tlu_dma_qos_prty, // DMA QoS priority coming from MFDC [18:16] + + // clock gating overrides from mcgc + output logic dec_tlu_misc_clk_override, // override misc clock domain gating + output logic dec_tlu_ifu_clk_override, // override fetch clock domain gating + output logic dec_tlu_lsu_clk_override, // override load/store clock domain gating + output logic dec_tlu_bus_clk_override, // override bus clock domain gating + output logic dec_tlu_pic_clk_override, // override PIC clock domain gating + output logic dec_tlu_picio_clk_override, // override PICIO clock domain gating + output logic dec_tlu_dccm_clk_override, // override DCCM clock domain gating + output logic dec_tlu_icm_clk_override, // override ICCM clock domain gating + + output logic dec_tlu_i0_commit_cmt, // committed i0 instruction + // Excluding scan_mode from coverage as its usage is determined by the integrator of the VeeR core. + /*pragma coverage off*/ + input logic scan_mode // Flop scan mode control + /*pragma coverage on*/ + +); + + + logic dec_tlu_dec_clk_override; // to and from dec blocks + logic clk_override; + + logic dec_ib0_valid_d; + + logic dec_pmu_instr_decoded; + logic dec_pmu_decode_stall; + logic dec_pmu_presync_stall; + logic dec_pmu_postsync_stall; + + logic dec_tlu_wr_pause_r; // CSR write to pause reg is at R. + + logic [4:0] dec_i0_rs1_d; + logic [4:0] dec_i0_rs2_d; + + logic [31:0] dec_i0_instr_d; + + logic dec_tlu_trace_disable; + logic dec_tlu_pipelining_disable; + + + logic [4:0] dec_i0_waddr_r; + logic dec_i0_wen_r; + logic [31:0] dec_i0_wdata_r; + logic dec_csr_wen_r; // csr write enable at wb + logic [11:0] dec_csr_rdaddr_r; // read address for csrs + logic [11:0] dec_csr_wraddr_r; // write address for csryes + logic [31:0] dec_csr_wrdata_r; // csr write data at wb + + logic [11:0] dec_csr_rdaddr_d; // read address for csr + logic dec_csr_legal_d; // csr indicates legal operation + + logic dec_csr_wen_unq_d; // valid csr with write - for csr legal + logic dec_csr_any_unq_d; // valid csr - for csr legal + logic dec_csr_stall_int_ff; // csr is mie/mstatus + + el2_trap_pkt_t dec_tlu_packet_r; + + logic dec_i0_pc4_d; + logic dec_tlu_presync_d; + logic dec_tlu_postsync_d; + logic dec_tlu_debug_stall; + + logic [31:0] dec_illegal_inst; + + logic dec_i0_icaf_d; + + logic dec_i0_dbecc_d; + logic dec_i0_icaf_second_d; + logic [3:0] dec_i0_trigger_match_d; + logic dec_debug_fence_d; + logic dec_nonblock_load_wen; + logic [4:0] dec_nonblock_load_waddr; + logic dec_tlu_flush_pause_r; + el2_br_pkt_t dec_i0_brp; + logic [pt.BTB_ADDR_HI:pt.BTB_ADDR_LO] dec_i0_bp_index; + logic [pt.BHT_GHR_SIZE-1:0] dec_i0_bp_fghr; + logic [pt.BTB_BTAG_SIZE-1:0] dec_i0_bp_btag; + logic [$clog2(pt.BTB_SIZE)-1:0] dec_i0_bp_fa_index; // Fully associt btb index + + logic [31:1] dec_tlu_i0_pc_r; + logic dec_tlu_i0_kill_writeb_wb; + logic dec_tlu_i0_valid_r; + + logic dec_pause_state; + + logic [1:0] dec_i0_icaf_type_d; // i0 instruction access fault type + + logic dec_tlu_flush_extint; // Fast ext int started + + logic [31:0] dec_i0_inst_wb; + logic [31:1] dec_i0_pc_wb; + logic dec_tlu_i0_valid_wb1, dec_tlu_int_valid_wb1; + logic [ 4:0] dec_tlu_exc_cause_wb1; + logic [31:0] dec_tlu_mtval_wb1; + logic dec_tlu_i0_exc_valid_wb1; + + logic [ 4:0] div_waddr_wb; + logic dec_div_active; + + logic dec_debug_valid_d; + + assign clk_override = dec_tlu_dec_clk_override; + + + assign dec_dbg_rddata[31:0] = dec_i0_wdata_r[31:0]; + + + el2_dec_ib_ctl #(.pt(pt)) instbuff (.*); + + + el2_dec_decode_ctl #(.pt(pt)) decode (.*); + + + el2_dec_tlu_ctl #(.pt(pt)) tlu (.*); + + + el2_dec_gpr_ctl #( + .pt(pt) + ) arf ( + .*, + // inputs + .raddr0(dec_i0_rs1_d[4:0]), + .raddr1(dec_i0_rs2_d[4:0]), + + .wen0(dec_i0_wen_r), + .waddr0(dec_i0_waddr_r[4:0]), + .wd0(dec_i0_wdata_r[31:0]), + .wen1(dec_nonblock_load_wen), + .waddr1(dec_nonblock_load_waddr[4:0]), + .wd1(lsu_nonblock_load_data[31:0]), + .wen2(exu_div_wren), + .waddr2(div_waddr_wb), + .wd2(exu_div_result[31:0]), + + // outputs + .rd0(gpr_i0_rs1_d[31:0]), + .rd1(gpr_i0_rs2_d[31:0]) + ); + + + // Trigger + + el2_dec_trigger #(.pt(pt)) dec_trigger (.*); + + + + + // trace + assign trace_rv_trace_pkt.trace_rv_i_insn_ip = dec_i0_inst_wb[31:0]; + assign trace_rv_trace_pkt.trace_rv_i_address_ip = {dec_i0_pc_wb[31:1], 1'b0}; + + assign trace_rv_trace_pkt.trace_rv_i_valid_ip = dec_tlu_int_valid_wb1 | dec_tlu_i0_valid_wb1 | dec_tlu_i0_exc_valid_wb1; + assign trace_rv_trace_pkt.trace_rv_i_exception_ip = dec_tlu_int_valid_wb1 | dec_tlu_i0_exc_valid_wb1; + assign trace_rv_trace_pkt.trace_rv_i_ecause_ip = dec_tlu_exc_cause_wb1[4:0]; // replicate across ports + assign trace_rv_trace_pkt.trace_rv_i_interrupt_ip = dec_tlu_int_valid_wb1; + assign trace_rv_trace_pkt.trace_rv_i_tval_ip = dec_tlu_mtval_wb1[31:0]; // replicate across ports + + + + // end trace + + +endmodule // el2_dec + diff --git a/designs/Caliptra/src/caliptra-rtl/el2_dec_csr_equ_m.svh b/designs/Caliptra/src/caliptra-rtl/el2_dec_csr_equ_m.svh new file mode 100644 index 0000000..7769a4a --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/el2_dec_csr_equ_m.svh @@ -0,0 +1,465 @@ +logic csr_misa; +logic csr_mvendorid; +logic csr_marchid; +logic csr_mimpid; +logic csr_mhartid; +logic csr_mstatus; +logic csr_mtvec; +logic csr_mip; +logic csr_mie; +logic csr_mcyclel; +logic csr_mcycleh; +logic csr_minstretl; +logic csr_minstreth; +logic csr_mscratch; +logic csr_mepc; +logic csr_mcause; +logic csr_mscause; +logic csr_mtval; +logic csr_mrac; +logic csr_dmst; +logic csr_mdseac; +logic csr_meihap; +logic csr_meivt; +logic csr_meipt; +logic csr_meicurpl; +logic csr_meicidpl; +logic csr_dcsr; +logic csr_mcgc; +logic csr_mfdc; +logic csr_dpc; +logic csr_mtsel; +logic csr_mtdata1; +logic csr_mtdata2; +logic csr_mhpmc3; +logic csr_mhpmc4; +logic csr_mhpmc5; +logic csr_mhpmc6; +logic csr_mhpmc3h; +logic csr_mhpmc4h; +logic csr_mhpmc5h; +logic csr_mhpmc6h; +logic csr_mhpme3; +logic csr_mhpme4; +logic csr_mhpme5; +logic csr_mhpme6; +logic csr_mcountinhibit; +logic csr_mitctl0; +logic csr_mitctl1; +logic csr_mitb0; +logic csr_mitb1; +logic csr_mitcnt0; +logic csr_mitcnt1; +/* exclude signals that are tied to constant value in this file */ +/*pragma coverage off*/ +logic csr_perfva; +logic csr_perfvb; +logic csr_perfvc; +logic csr_perfvd; +logic csr_perfve; +logic csr_perfvf; +logic csr_perfvg; +logic csr_perfvh; +logic csr_perfvi; +/*pragma coverage on*/ +logic csr_mpmc; +logic csr_mcpc; +logic csr_meicpct; +logic csr_mdeau; +logic csr_micect; +logic csr_miccmect; +logic csr_mdccmect; +logic csr_mfdht; +logic csr_mfdhs; +logic csr_dicawics; +logic csr_dicad0h; +logic csr_dicad0; +logic csr_dicad1; +logic csr_dicago; +logic csr_pmpcfg; +logic csr_pmpaddr0; +logic csr_pmpaddr16; +logic csr_pmpaddr32; +logic csr_pmpaddr48; +logic valid_only; +logic presync; +logic postsync; +assign csr_misa = (!dec_csr_rdaddr_d[11]&!dec_csr_rdaddr_d[6] + &!dec_csr_rdaddr_d[5]&!dec_csr_rdaddr_d[2]&dec_csr_rdaddr_d[0]); + +assign csr_mvendorid = (dec_csr_rdaddr_d[10]&!dec_csr_rdaddr_d[7] + &!dec_csr_rdaddr_d[1]&dec_csr_rdaddr_d[0]); + +assign csr_marchid = (dec_csr_rdaddr_d[10]&!dec_csr_rdaddr_d[7] + &dec_csr_rdaddr_d[1]&!dec_csr_rdaddr_d[0]); + +assign csr_mimpid = (dec_csr_rdaddr_d[10]&!dec_csr_rdaddr_d[6] + &dec_csr_rdaddr_d[1]&dec_csr_rdaddr_d[0]); + +assign csr_mhartid = (dec_csr_rdaddr_d[10]&!dec_csr_rdaddr_d[7] + &dec_csr_rdaddr_d[2]); + +assign csr_mstatus = (!dec_csr_rdaddr_d[11]&!dec_csr_rdaddr_d[6] + &!dec_csr_rdaddr_d[5]&!dec_csr_rdaddr_d[2]&!dec_csr_rdaddr_d[0]); + +assign csr_mtvec = (!dec_csr_rdaddr_d[11]&!dec_csr_rdaddr_d[6] + &!dec_csr_rdaddr_d[5]&dec_csr_rdaddr_d[2]&dec_csr_rdaddr_d[0]); + +assign csr_mip = (!dec_csr_rdaddr_d[7]&dec_csr_rdaddr_d[6]&dec_csr_rdaddr_d[2]); + +assign csr_mie = (!dec_csr_rdaddr_d[11]&!dec_csr_rdaddr_d[6]&!dec_csr_rdaddr_d[5] + &dec_csr_rdaddr_d[2]&!dec_csr_rdaddr_d[0]); + +assign csr_mcyclel = (dec_csr_rdaddr_d[11]&!dec_csr_rdaddr_d[7] + &!dec_csr_rdaddr_d[4]&!dec_csr_rdaddr_d[3]&!dec_csr_rdaddr_d[2] + &!dec_csr_rdaddr_d[1]); + +assign csr_mcycleh = (dec_csr_rdaddr_d[7]&!dec_csr_rdaddr_d[6] + &!dec_csr_rdaddr_d[5]&!dec_csr_rdaddr_d[4]&!dec_csr_rdaddr_d[3] + &!dec_csr_rdaddr_d[2]&!dec_csr_rdaddr_d[1]); + +assign csr_minstretl = (!dec_csr_rdaddr_d[7]&!dec_csr_rdaddr_d[6] + &!dec_csr_rdaddr_d[4]&!dec_csr_rdaddr_d[3]&!dec_csr_rdaddr_d[2] + &dec_csr_rdaddr_d[1]&!dec_csr_rdaddr_d[0]); + +assign csr_minstreth = (dec_csr_rdaddr_d[11]&dec_csr_rdaddr_d[7] + &!dec_csr_rdaddr_d[4]&!dec_csr_rdaddr_d[3]&!dec_csr_rdaddr_d[2] + &dec_csr_rdaddr_d[1]&!dec_csr_rdaddr_d[0]); + +assign csr_mscratch = (!dec_csr_rdaddr_d[7]&dec_csr_rdaddr_d[6] + &!dec_csr_rdaddr_d[2]&!dec_csr_rdaddr_d[1]&!dec_csr_rdaddr_d[0]); + +assign csr_mepc = (!dec_csr_rdaddr_d[7]&dec_csr_rdaddr_d[6]&!dec_csr_rdaddr_d[1] + &dec_csr_rdaddr_d[0]); + +assign csr_mcause = (!dec_csr_rdaddr_d[7]&dec_csr_rdaddr_d[6] + &dec_csr_rdaddr_d[1]&!dec_csr_rdaddr_d[0]); + +assign csr_mscause = (dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[5] + &dec_csr_rdaddr_d[2]); + +assign csr_mtval = (!dec_csr_rdaddr_d[7]&dec_csr_rdaddr_d[6]&dec_csr_rdaddr_d[1] + &dec_csr_rdaddr_d[0]); + +assign csr_mrac = (!dec_csr_rdaddr_d[11]&dec_csr_rdaddr_d[10] + &!dec_csr_rdaddr_d[5]&!dec_csr_rdaddr_d[3]&!dec_csr_rdaddr_d[2] + &!dec_csr_rdaddr_d[1]); + +assign csr_dmst = (dec_csr_rdaddr_d[10]&!dec_csr_rdaddr_d[4]&!dec_csr_rdaddr_d[3] + &dec_csr_rdaddr_d[2]&!dec_csr_rdaddr_d[1]); + +assign csr_mdseac = (dec_csr_rdaddr_d[11]&dec_csr_rdaddr_d[10] + &!dec_csr_rdaddr_d[4]&!dec_csr_rdaddr_d[3]); + +assign csr_meihap = (dec_csr_rdaddr_d[11]&dec_csr_rdaddr_d[10] + &dec_csr_rdaddr_d[3]); + +assign csr_meivt = (dec_csr_rdaddr_d[11]&!dec_csr_rdaddr_d[10] + &dec_csr_rdaddr_d[6]&dec_csr_rdaddr_d[3]&!dec_csr_rdaddr_d[2] + &!dec_csr_rdaddr_d[1]&!dec_csr_rdaddr_d[0]); + +assign csr_meipt = (dec_csr_rdaddr_d[11]&dec_csr_rdaddr_d[6]&!dec_csr_rdaddr_d[1] + &dec_csr_rdaddr_d[0]); + +assign csr_meicurpl = (dec_csr_rdaddr_d[11]&dec_csr_rdaddr_d[6] + &dec_csr_rdaddr_d[2]); + +assign csr_meicidpl = (dec_csr_rdaddr_d[11]&dec_csr_rdaddr_d[6] + &dec_csr_rdaddr_d[1]&dec_csr_rdaddr_d[0]); + +assign csr_dcsr = (dec_csr_rdaddr_d[10]&!dec_csr_rdaddr_d[6]&dec_csr_rdaddr_d[5] + &dec_csr_rdaddr_d[4]&!dec_csr_rdaddr_d[0]); + +assign csr_mcgc = (dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[4]&dec_csr_rdaddr_d[3] + &!dec_csr_rdaddr_d[0]); + +assign csr_mfdc = (dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[4]&dec_csr_rdaddr_d[3] + &!dec_csr_rdaddr_d[1]&dec_csr_rdaddr_d[0]); + +assign csr_dpc = (dec_csr_rdaddr_d[10]&!dec_csr_rdaddr_d[6]&dec_csr_rdaddr_d[5] + &dec_csr_rdaddr_d[4]&dec_csr_rdaddr_d[0]); + +assign csr_mtsel = (dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[5]&!dec_csr_rdaddr_d[4] + &!dec_csr_rdaddr_d[1]&!dec_csr_rdaddr_d[0]); + +assign csr_mtdata1 = (dec_csr_rdaddr_d[10]&!dec_csr_rdaddr_d[4] + &!dec_csr_rdaddr_d[3]&dec_csr_rdaddr_d[0]); + +assign csr_mtdata2 = (dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[5] + &!dec_csr_rdaddr_d[4]&dec_csr_rdaddr_d[1]); + +assign csr_mhpmc3 = (dec_csr_rdaddr_d[11]&!dec_csr_rdaddr_d[7] + &!dec_csr_rdaddr_d[4]&!dec_csr_rdaddr_d[3]&!dec_csr_rdaddr_d[2] + &dec_csr_rdaddr_d[0]); + +assign csr_mhpmc4 = (dec_csr_rdaddr_d[11]&!dec_csr_rdaddr_d[7] + &!dec_csr_rdaddr_d[4]&!dec_csr_rdaddr_d[3]&dec_csr_rdaddr_d[2] + &!dec_csr_rdaddr_d[1]&!dec_csr_rdaddr_d[0]); + +assign csr_mhpmc5 = (dec_csr_rdaddr_d[11]&!dec_csr_rdaddr_d[7] + &!dec_csr_rdaddr_d[4]&!dec_csr_rdaddr_d[3]&!dec_csr_rdaddr_d[1] + &dec_csr_rdaddr_d[0]); + +assign csr_mhpmc6 = (!dec_csr_rdaddr_d[7]&!dec_csr_rdaddr_d[5] + &!dec_csr_rdaddr_d[4]&!dec_csr_rdaddr_d[3]&dec_csr_rdaddr_d[2] + &dec_csr_rdaddr_d[1]&!dec_csr_rdaddr_d[0]); + +assign csr_mhpmc3h = (dec_csr_rdaddr_d[11]&dec_csr_rdaddr_d[7] + &!dec_csr_rdaddr_d[4]&!dec_csr_rdaddr_d[3]&!dec_csr_rdaddr_d[2] + &dec_csr_rdaddr_d[0]); + +assign csr_mhpmc4h = (dec_csr_rdaddr_d[11]&dec_csr_rdaddr_d[7] + &!dec_csr_rdaddr_d[4]&!dec_csr_rdaddr_d[3]&dec_csr_rdaddr_d[2] + &!dec_csr_rdaddr_d[1]&!dec_csr_rdaddr_d[0]); + +assign csr_mhpmc5h = (dec_csr_rdaddr_d[11]&dec_csr_rdaddr_d[7] + &!dec_csr_rdaddr_d[4]&!dec_csr_rdaddr_d[3]&!dec_csr_rdaddr_d[1] + &dec_csr_rdaddr_d[0]); + +assign csr_mhpmc6h = (dec_csr_rdaddr_d[11]&dec_csr_rdaddr_d[7] + &!dec_csr_rdaddr_d[4]&!dec_csr_rdaddr_d[3]&dec_csr_rdaddr_d[2] + &dec_csr_rdaddr_d[1]&!dec_csr_rdaddr_d[0]); + +assign csr_mhpme3 = (!dec_csr_rdaddr_d[7]&dec_csr_rdaddr_d[5] + &!dec_csr_rdaddr_d[4]&!dec_csr_rdaddr_d[3]&!dec_csr_rdaddr_d[2] + &dec_csr_rdaddr_d[0]); + +assign csr_mhpme4 = (!dec_csr_rdaddr_d[7]&dec_csr_rdaddr_d[5] + &!dec_csr_rdaddr_d[4]&!dec_csr_rdaddr_d[3]&dec_csr_rdaddr_d[2] + &!dec_csr_rdaddr_d[1]&!dec_csr_rdaddr_d[0]); + +assign csr_mhpme5 = (!dec_csr_rdaddr_d[7]&dec_csr_rdaddr_d[5] + &!dec_csr_rdaddr_d[4]&!dec_csr_rdaddr_d[3]&!dec_csr_rdaddr_d[1] + &dec_csr_rdaddr_d[0]); + +assign csr_mhpme6 = (!dec_csr_rdaddr_d[7]&dec_csr_rdaddr_d[5] + &!dec_csr_rdaddr_d[4]&!dec_csr_rdaddr_d[3]&dec_csr_rdaddr_d[1] + &!dec_csr_rdaddr_d[0]); + +assign csr_mcountinhibit = (!dec_csr_rdaddr_d[7]&dec_csr_rdaddr_d[5] + &!dec_csr_rdaddr_d[4]&!dec_csr_rdaddr_d[3]&!dec_csr_rdaddr_d[2] + &!dec_csr_rdaddr_d[0]); + +assign csr_mitctl0 = (dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[6] + &dec_csr_rdaddr_d[4]&dec_csr_rdaddr_d[2]&!dec_csr_rdaddr_d[1] + &!dec_csr_rdaddr_d[0]); + +assign csr_mitctl1 = (dec_csr_rdaddr_d[10]&!dec_csr_rdaddr_d[3] + &dec_csr_rdaddr_d[2]&dec_csr_rdaddr_d[1]&dec_csr_rdaddr_d[0]); + +assign csr_mitb0 = (dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[6]&!dec_csr_rdaddr_d[3] + &!dec_csr_rdaddr_d[2]&dec_csr_rdaddr_d[1]&dec_csr_rdaddr_d[0]); + +assign csr_mitb1 = (dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[4]&dec_csr_rdaddr_d[2] + &dec_csr_rdaddr_d[1]&!dec_csr_rdaddr_d[0]); + +assign csr_mitcnt0 = (dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[6] + &!dec_csr_rdaddr_d[5]&dec_csr_rdaddr_d[4]&!dec_csr_rdaddr_d[2] + &!dec_csr_rdaddr_d[0]); + +assign csr_mitcnt1 = (dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[2] + &!dec_csr_rdaddr_d[1]&dec_csr_rdaddr_d[0]); + +assign csr_perfva = 1'b0; + +assign csr_perfvb = 1'b0; + +assign csr_perfvc = 1'b0; + +assign csr_perfvd = 1'b0; + +assign csr_perfve = 1'b0; + +assign csr_perfvf = 1'b0; + +assign csr_perfvg = 1'b0; + +assign csr_perfvh = 1'b0; + +assign csr_perfvi = 1'b0; + +assign csr_mpmc = (dec_csr_rdaddr_d[10]&!dec_csr_rdaddr_d[4]&!dec_csr_rdaddr_d[3] + &dec_csr_rdaddr_d[2]&dec_csr_rdaddr_d[1]); + +assign csr_mcpc = (dec_csr_rdaddr_d[10]&!dec_csr_rdaddr_d[5]&!dec_csr_rdaddr_d[4] + &!dec_csr_rdaddr_d[3]&!dec_csr_rdaddr_d[2]&dec_csr_rdaddr_d[1]); + +assign csr_meicpct = (dec_csr_rdaddr_d[11]&dec_csr_rdaddr_d[6] + &dec_csr_rdaddr_d[1]&!dec_csr_rdaddr_d[0]); + +assign csr_mdeau = (dec_csr_rdaddr_d[11]&!dec_csr_rdaddr_d[10] + &dec_csr_rdaddr_d[6]&!dec_csr_rdaddr_d[3]); + +assign csr_micect = (dec_csr_rdaddr_d[6]&dec_csr_rdaddr_d[5]&dec_csr_rdaddr_d[4] + &!dec_csr_rdaddr_d[3]&!dec_csr_rdaddr_d[1]&!dec_csr_rdaddr_d[0]); + +assign csr_miccmect = (dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[6] + &dec_csr_rdaddr_d[5]&!dec_csr_rdaddr_d[3]&dec_csr_rdaddr_d[0]); + +assign csr_mdccmect = (dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[5] + &dec_csr_rdaddr_d[4]&dec_csr_rdaddr_d[1]&!dec_csr_rdaddr_d[0]); + +assign csr_mfdht = (dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[3]&dec_csr_rdaddr_d[2] + &dec_csr_rdaddr_d[1]&!dec_csr_rdaddr_d[0]); + +assign csr_mfdhs = (dec_csr_rdaddr_d[10]&!dec_csr_rdaddr_d[4] + &dec_csr_rdaddr_d[2]&dec_csr_rdaddr_d[0]); + +assign csr_dicawics = (!dec_csr_rdaddr_d[11]&dec_csr_rdaddr_d[10] + &!dec_csr_rdaddr_d[4]&dec_csr_rdaddr_d[3]&!dec_csr_rdaddr_d[2] + &!dec_csr_rdaddr_d[1]&!dec_csr_rdaddr_d[0]); + +assign csr_dicad0h = (dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[3] + &dec_csr_rdaddr_d[2]&!dec_csr_rdaddr_d[1]); + +assign csr_dicad0 = (dec_csr_rdaddr_d[10]&!dec_csr_rdaddr_d[4] + &dec_csr_rdaddr_d[3]&!dec_csr_rdaddr_d[1]&dec_csr_rdaddr_d[0]); + +assign csr_dicad1 = (dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[3] + &!dec_csr_rdaddr_d[2]&dec_csr_rdaddr_d[1]&!dec_csr_rdaddr_d[0]); + +assign csr_dicago = (dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[3] + &!dec_csr_rdaddr_d[2]&dec_csr_rdaddr_d[1]&dec_csr_rdaddr_d[0]); + +assign csr_pmpcfg = (!dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[7] + &!dec_csr_rdaddr_d[6]&dec_csr_rdaddr_d[5]&!dec_csr_rdaddr_d[4]); + +assign csr_pmpaddr0 = (!dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[7] + &dec_csr_rdaddr_d[5]&dec_csr_rdaddr_d[4]); + +assign csr_pmpaddr16 = (!dec_csr_rdaddr_d[11]&!dec_csr_rdaddr_d[10] + &dec_csr_rdaddr_d[7]&!dec_csr_rdaddr_d[5]&!dec_csr_rdaddr_d[4]); + +assign csr_pmpaddr32 = (!dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[6] + &dec_csr_rdaddr_d[4]); + +assign csr_pmpaddr48 = (dec_csr_rdaddr_d[6]&dec_csr_rdaddr_d[5] + &!dec_csr_rdaddr_d[4]); + +assign valid_only = (dec_csr_rdaddr_d[11]&dec_csr_rdaddr_d[2] + &dec_csr_rdaddr_d[1]&dec_csr_rdaddr_d[0]) | (dec_csr_rdaddr_d[7] + &!dec_csr_rdaddr_d[6]&!dec_csr_rdaddr_d[5]&dec_csr_rdaddr_d[4]) | ( + !dec_csr_rdaddr_d[10]&!dec_csr_rdaddr_d[7]&dec_csr_rdaddr_d[4]) | ( + !dec_csr_rdaddr_d[6]&!dec_csr_rdaddr_d[5]&dec_csr_rdaddr_d[3]) | ( + !dec_csr_rdaddr_d[7]&dec_csr_rdaddr_d[2]&dec_csr_rdaddr_d[1] + &dec_csr_rdaddr_d[0]) | (!dec_csr_rdaddr_d[7]&dec_csr_rdaddr_d[3]); + +assign presync = (dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[4]&dec_csr_rdaddr_d[3] + &!dec_csr_rdaddr_d[1]&dec_csr_rdaddr_d[0]) | (dec_csr_rdaddr_d[10] + &!dec_csr_rdaddr_d[5]&!dec_csr_rdaddr_d[4]&!dec_csr_rdaddr_d[3] + &!dec_csr_rdaddr_d[2]&dec_csr_rdaddr_d[1]) | (!dec_csr_rdaddr_d[7] + &dec_csr_rdaddr_d[5]&!dec_csr_rdaddr_d[4]&!dec_csr_rdaddr_d[3] + &!dec_csr_rdaddr_d[2]&!dec_csr_rdaddr_d[0]) | (dec_csr_rdaddr_d[10] + &!dec_csr_rdaddr_d[4]&!dec_csr_rdaddr_d[3]&dec_csr_rdaddr_d[0]) | ( + dec_csr_rdaddr_d[11]&!dec_csr_rdaddr_d[4]&!dec_csr_rdaddr_d[3] + &!dec_csr_rdaddr_d[2]&dec_csr_rdaddr_d[0]) | (dec_csr_rdaddr_d[11] + &!dec_csr_rdaddr_d[4]&!dec_csr_rdaddr_d[3]&dec_csr_rdaddr_d[2] + &!dec_csr_rdaddr_d[1]) | (dec_csr_rdaddr_d[11]&!dec_csr_rdaddr_d[4] + &!dec_csr_rdaddr_d[3]&dec_csr_rdaddr_d[1]&!dec_csr_rdaddr_d[0]); + +assign postsync = (dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[4]&dec_csr_rdaddr_d[3] + &!dec_csr_rdaddr_d[1]&dec_csr_rdaddr_d[0]) | (!dec_csr_rdaddr_d[11] + &!dec_csr_rdaddr_d[6]&!dec_csr_rdaddr_d[5]&dec_csr_rdaddr_d[2] + &dec_csr_rdaddr_d[0]) | (!dec_csr_rdaddr_d[11]&!dec_csr_rdaddr_d[7] + &!dec_csr_rdaddr_d[6]&!dec_csr_rdaddr_d[4]&!dec_csr_rdaddr_d[3] + &!dec_csr_rdaddr_d[2]&!dec_csr_rdaddr_d[0]) | (dec_csr_rdaddr_d[10] + &!dec_csr_rdaddr_d[4]&!dec_csr_rdaddr_d[3]&dec_csr_rdaddr_d[0]) | ( + !dec_csr_rdaddr_d[11]&dec_csr_rdaddr_d[10]&!dec_csr_rdaddr_d[5] + &!dec_csr_rdaddr_d[4]&!dec_csr_rdaddr_d[3]&!dec_csr_rdaddr_d[1]) | ( + dec_csr_rdaddr_d[10]&!dec_csr_rdaddr_d[4]&!dec_csr_rdaddr_d[3] + &!dec_csr_rdaddr_d[2]&dec_csr_rdaddr_d[1]) | (!dec_csr_rdaddr_d[7] + &dec_csr_rdaddr_d[6]&!dec_csr_rdaddr_d[1]&dec_csr_rdaddr_d[0]); + +logic legal; +assign legal = (!dec_csr_rdaddr_d[11]&dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[9] + &dec_csr_rdaddr_d[8]&dec_csr_rdaddr_d[7]&dec_csr_rdaddr_d[6] + &dec_csr_rdaddr_d[4]&!dec_csr_rdaddr_d[3]&!dec_csr_rdaddr_d[2] + &dec_csr_rdaddr_d[1]&!dec_csr_rdaddr_d[0]) | (!dec_csr_rdaddr_d[10] + &dec_csr_rdaddr_d[9]&dec_csr_rdaddr_d[8]&dec_csr_rdaddr_d[7] + &dec_csr_rdaddr_d[6]&!dec_csr_rdaddr_d[5]&!dec_csr_rdaddr_d[4] + &dec_csr_rdaddr_d[3]&!dec_csr_rdaddr_d[1]&!dec_csr_rdaddr_d[0]) | ( + !dec_csr_rdaddr_d[11]&!dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[9] + &dec_csr_rdaddr_d[8]&dec_csr_rdaddr_d[6]&!dec_csr_rdaddr_d[5] + &!dec_csr_rdaddr_d[4]&!dec_csr_rdaddr_d[3]&!dec_csr_rdaddr_d[1] + &!dec_csr_rdaddr_d[0]) | (!dec_csr_rdaddr_d[11]&!dec_csr_rdaddr_d[10] + &dec_csr_rdaddr_d[9]&dec_csr_rdaddr_d[8]&!dec_csr_rdaddr_d[7] + &!dec_csr_rdaddr_d[6]&!dec_csr_rdaddr_d[5]&!dec_csr_rdaddr_d[4] + &!dec_csr_rdaddr_d[3]&!dec_csr_rdaddr_d[1]) | (dec_csr_rdaddr_d[11] + &!dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[9]&dec_csr_rdaddr_d[8] + &!dec_csr_rdaddr_d[6]&!dec_csr_rdaddr_d[5]&!dec_csr_rdaddr_d[0]) | ( + !dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[9]&dec_csr_rdaddr_d[8] + &dec_csr_rdaddr_d[7]&dec_csr_rdaddr_d[6]&!dec_csr_rdaddr_d[5] + &!dec_csr_rdaddr_d[4]&dec_csr_rdaddr_d[3]&!dec_csr_rdaddr_d[2]) | ( + !dec_csr_rdaddr_d[11]&!dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[9] + &dec_csr_rdaddr_d[8]&!dec_csr_rdaddr_d[7]&!dec_csr_rdaddr_d[6] + &!dec_csr_rdaddr_d[4]&!dec_csr_rdaddr_d[3]&!dec_csr_rdaddr_d[1] + &!dec_csr_rdaddr_d[0]) | (!dec_csr_rdaddr_d[11]&!dec_csr_rdaddr_d[10] + &dec_csr_rdaddr_d[9]&dec_csr_rdaddr_d[8]&dec_csr_rdaddr_d[7] + &dec_csr_rdaddr_d[5]&!dec_csr_rdaddr_d[4]) | (!dec_csr_rdaddr_d[11] + &dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[9]&dec_csr_rdaddr_d[8] + &dec_csr_rdaddr_d[7]&dec_csr_rdaddr_d[6]&dec_csr_rdaddr_d[5] + &dec_csr_rdaddr_d[4]&dec_csr_rdaddr_d[3]&dec_csr_rdaddr_d[2] + &dec_csr_rdaddr_d[1]&dec_csr_rdaddr_d[0]) | (!dec_csr_rdaddr_d[11] + &dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[9]&dec_csr_rdaddr_d[8] + &dec_csr_rdaddr_d[7]&dec_csr_rdaddr_d[6]&dec_csr_rdaddr_d[5] + &dec_csr_rdaddr_d[4]&!dec_csr_rdaddr_d[2]&!dec_csr_rdaddr_d[1]) | ( + dec_csr_rdaddr_d[11]&dec_csr_rdaddr_d[9]&dec_csr_rdaddr_d[8] + &!dec_csr_rdaddr_d[7]&!dec_csr_rdaddr_d[6]&!dec_csr_rdaddr_d[5] + &dec_csr_rdaddr_d[4]&!dec_csr_rdaddr_d[3]&!dec_csr_rdaddr_d[2] + &dec_csr_rdaddr_d[0]) | (dec_csr_rdaddr_d[11]&dec_csr_rdaddr_d[9] + &dec_csr_rdaddr_d[8]&!dec_csr_rdaddr_d[7]&!dec_csr_rdaddr_d[6] + &!dec_csr_rdaddr_d[5]&dec_csr_rdaddr_d[4]&!dec_csr_rdaddr_d[3] + &dec_csr_rdaddr_d[2]&!dec_csr_rdaddr_d[1]&!dec_csr_rdaddr_d[0]) | ( + dec_csr_rdaddr_d[11]&dec_csr_rdaddr_d[9]&dec_csr_rdaddr_d[8] + &!dec_csr_rdaddr_d[7]&!dec_csr_rdaddr_d[6]&!dec_csr_rdaddr_d[5] + &dec_csr_rdaddr_d[4]&!dec_csr_rdaddr_d[3]&!dec_csr_rdaddr_d[2] + &dec_csr_rdaddr_d[1]) | (!dec_csr_rdaddr_d[11]&dec_csr_rdaddr_d[9] + &dec_csr_rdaddr_d[8]&dec_csr_rdaddr_d[7]&!dec_csr_rdaddr_d[6] + &dec_csr_rdaddr_d[5]&!dec_csr_rdaddr_d[3]&!dec_csr_rdaddr_d[2] + &!dec_csr_rdaddr_d[1]) | (!dec_csr_rdaddr_d[11]&!dec_csr_rdaddr_d[10] + &dec_csr_rdaddr_d[9]&dec_csr_rdaddr_d[8]&!dec_csr_rdaddr_d[6] + &dec_csr_rdaddr_d[5]&dec_csr_rdaddr_d[2]) | (!dec_csr_rdaddr_d[11] + &dec_csr_rdaddr_d[9]&dec_csr_rdaddr_d[8]&dec_csr_rdaddr_d[7] + &dec_csr_rdaddr_d[6]&!dec_csr_rdaddr_d[5]&dec_csr_rdaddr_d[4] + &!dec_csr_rdaddr_d[3]&dec_csr_rdaddr_d[2]) | (!dec_csr_rdaddr_d[11] + &dec_csr_rdaddr_d[9]&dec_csr_rdaddr_d[8]&dec_csr_rdaddr_d[7] + &dec_csr_rdaddr_d[6]&!dec_csr_rdaddr_d[5]&!dec_csr_rdaddr_d[4] + &dec_csr_rdaddr_d[3]&dec_csr_rdaddr_d[1]) | (!dec_csr_rdaddr_d[11] + &!dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[9]&dec_csr_rdaddr_d[8] + &!dec_csr_rdaddr_d[6]&dec_csr_rdaddr_d[5]&dec_csr_rdaddr_d[1] + &dec_csr_rdaddr_d[0]) | (dec_csr_rdaddr_d[11]&!dec_csr_rdaddr_d[10] + &dec_csr_rdaddr_d[9]&dec_csr_rdaddr_d[8]&!dec_csr_rdaddr_d[6] + &!dec_csr_rdaddr_d[5]&dec_csr_rdaddr_d[2]) | (!dec_csr_rdaddr_d[11] + &dec_csr_rdaddr_d[9]&dec_csr_rdaddr_d[8]&dec_csr_rdaddr_d[7] + &dec_csr_rdaddr_d[6]&!dec_csr_rdaddr_d[5]&dec_csr_rdaddr_d[4] + &!dec_csr_rdaddr_d[3]&dec_csr_rdaddr_d[1]) | (dec_csr_rdaddr_d[9] + &dec_csr_rdaddr_d[8]&dec_csr_rdaddr_d[7]&dec_csr_rdaddr_d[6] + &!dec_csr_rdaddr_d[5]&!dec_csr_rdaddr_d[4]&!dec_csr_rdaddr_d[2] + &!dec_csr_rdaddr_d[1]&!dec_csr_rdaddr_d[0]) | (!dec_csr_rdaddr_d[11] + &dec_csr_rdaddr_d[9]&dec_csr_rdaddr_d[8]&dec_csr_rdaddr_d[7] + &dec_csr_rdaddr_d[6]&!dec_csr_rdaddr_d[5]&!dec_csr_rdaddr_d[4] + &!dec_csr_rdaddr_d[0]) | (dec_csr_rdaddr_d[11]&!dec_csr_rdaddr_d[10] + &dec_csr_rdaddr_d[9]&dec_csr_rdaddr_d[8]&!dec_csr_rdaddr_d[6] + &!dec_csr_rdaddr_d[5]&dec_csr_rdaddr_d[1]) | (!dec_csr_rdaddr_d[11] + &dec_csr_rdaddr_d[9]&dec_csr_rdaddr_d[8]&dec_csr_rdaddr_d[7] + &dec_csr_rdaddr_d[6]&!dec_csr_rdaddr_d[5]&!dec_csr_rdaddr_d[4] + &dec_csr_rdaddr_d[3]&!dec_csr_rdaddr_d[2]) | (!dec_csr_rdaddr_d[11] + &dec_csr_rdaddr_d[9]&dec_csr_rdaddr_d[8]&dec_csr_rdaddr_d[7] + &!dec_csr_rdaddr_d[6]&dec_csr_rdaddr_d[5]&!dec_csr_rdaddr_d[4] + &!dec_csr_rdaddr_d[3]&!dec_csr_rdaddr_d[2]&!dec_csr_rdaddr_d[0]) | ( + !dec_csr_rdaddr_d[11]&!dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[9] + &dec_csr_rdaddr_d[8]&dec_csr_rdaddr_d[6]&!dec_csr_rdaddr_d[5] + &!dec_csr_rdaddr_d[4]&!dec_csr_rdaddr_d[3]&!dec_csr_rdaddr_d[2]) | ( + !dec_csr_rdaddr_d[11]&!dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[9] + &dec_csr_rdaddr_d[8]&!dec_csr_rdaddr_d[6]&dec_csr_rdaddr_d[5] + &dec_csr_rdaddr_d[3]) | (dec_csr_rdaddr_d[11]&!dec_csr_rdaddr_d[10] + &dec_csr_rdaddr_d[9]&dec_csr_rdaddr_d[8]&!dec_csr_rdaddr_d[6] + &!dec_csr_rdaddr_d[5]&dec_csr_rdaddr_d[3]) | (!dec_csr_rdaddr_d[11] + &!dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[9]&dec_csr_rdaddr_d[8] + &!dec_csr_rdaddr_d[6]&dec_csr_rdaddr_d[5]&dec_csr_rdaddr_d[4]) | ( + dec_csr_rdaddr_d[11]&!dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[9] + &dec_csr_rdaddr_d[8]&!dec_csr_rdaddr_d[6]&!dec_csr_rdaddr_d[5] + &dec_csr_rdaddr_d[4]) | (!dec_csr_rdaddr_d[11]&!dec_csr_rdaddr_d[10] + &dec_csr_rdaddr_d[9]&dec_csr_rdaddr_d[8]&dec_csr_rdaddr_d[7] + &dec_csr_rdaddr_d[6]&!dec_csr_rdaddr_d[5]); + diff --git a/designs/Caliptra/src/caliptra-rtl/el2_dec_decode_ctl.sv b/designs/Caliptra/src/caliptra-rtl/el2_dec_decode_ctl.sv new file mode 100644 index 0000000..3882c83 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/el2_dec_decode_ctl.sv @@ -0,0 +1,1828 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2020 Western Digital Corporation or its affiliates. +// +// 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. + + +module el2_dec_decode_ctl +import el2_pkg::*; +#( +`include "el2_param.vh" + ) + ( + input logic dec_tlu_trace_disable, + input logic dec_debug_valid_d, + + input logic dec_tlu_flush_extint, // Flush external interrupt + + input logic dec_tlu_force_halt, // invalidate nonblock load cam on a force halt event + + output logic dec_extint_stall, // Stall from external interrupt + + input logic [15:0] ifu_i0_cinst, // 16b compressed instruction + output logic [31:0] dec_i0_inst_wb, // 32b instruction at wb+1 for trace encoder + output logic [31:1] dec_i0_pc_wb, // 31b pc at wb+1 for trace encoder + + + input logic lsu_nonblock_load_valid_m, // valid nonblock load at m + input logic [pt.LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_tag_m, // -> corresponding tag + input logic lsu_nonblock_load_inv_r, // invalidate request for nonblock load r + input logic [pt.LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_inv_tag_r, // -> corresponding tag + input logic lsu_nonblock_load_data_valid, // valid nonblock load data back + input logic lsu_nonblock_load_data_error, // nonblock load bus error + input logic [pt.LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_data_tag, // -> corresponding tag + + + input logic [3:0] dec_i0_trigger_match_d, // i0 decode trigger matches + + input logic dec_tlu_wr_pause_r, // pause instruction at r + input logic dec_tlu_pipelining_disable, // pipeline disable - presync, i0 decode only + + input logic [3:0] lsu_trigger_match_m, // lsu trigger matches + + input logic lsu_pmu_misaligned_m, // perf mon: load/store misalign + input logic dec_tlu_debug_stall, // debug stall decode + input logic dec_tlu_flush_leak_one_r, // leak1 instruction + + input logic dec_debug_fence_d, // debug fence instruction + + input logic [1:0] dbg_cmd_wrdata, // disambiguate fence, fence_i + + input logic dec_i0_icaf_d, // icache access fault + input logic dec_i0_icaf_second_d, // i0 instruction access fault on second 2B of 4B inst + input logic [1:0] dec_i0_icaf_type_d, // i0 instruction access fault type + + input logic dec_i0_dbecc_d, // icache/iccm double-bit error + + input el2_br_pkt_t dec_i0_brp, // branch packet + input logic [pt.BTB_ADDR_HI:pt.BTB_ADDR_LO] dec_i0_bp_index, // i0 branch index + input logic [pt.BHT_GHR_SIZE-1:0] dec_i0_bp_fghr, // BP FGHR + input logic [pt.BTB_BTAG_SIZE-1:0] dec_i0_bp_btag, // BP tag + input logic [$clog2(pt.BTB_SIZE)-1:0] dec_i0_bp_fa_index, // Fully associt btb index + + input logic lsu_idle_any, // lsu idle: if fence instr & ~lsu_idle then stall decode + + input logic lsu_load_stall_any, // stall any load at decode + input logic lsu_store_stall_any, // stall any store at decode + input logic dma_dccm_stall_any, // stall any load/store at decode + + input logic exu_div_wren, // nonblocking divide write enable to GPR. + + input logic dec_tlu_i0_kill_writeb_wb, // I0 is flushed, don't writeback any results to arch state + input logic dec_tlu_flush_lower_wb, // trap lower flush + input logic dec_tlu_i0_kill_writeb_r, // I0 is flushed, don't writeback any results to arch state + input logic dec_tlu_flush_lower_r, // trap lower flush + input logic dec_tlu_flush_pause_r, // don't clear pause state on initial lower flush + input logic dec_tlu_presync_d, // CSR read needs to be presync'd + input logic dec_tlu_postsync_d, // CSR ops that need to be postsync'd + + input logic dec_i0_pc4_d, // inst is 4B inst else 2B + + input logic [31:0] dec_csr_rddata_d, // csr read data at wb + input logic dec_csr_legal_d, // csr indicates legal operation + + input logic [31:0] exu_csr_rs1_x, // rs1 for csr instr + + input logic [31:0] lsu_result_m, // load result + input logic [31:0] lsu_result_corr_r, // load result - corrected data for writing gpr's, not for bypassing + + input logic exu_flush_final, // lower flush or i0 flush at X or D + + input logic [31:1] exu_i0_pc_x, // pcs at e1 + + input logic [31:0] dec_i0_instr_d, // inst at decode + + input logic dec_ib0_valid_d, // inst valid at decode + + input logic [31:0] exu_i0_result_x, // from primary alu's + + input logic clk, // Clock only while core active. Through one clock header. For flops with second clock header built in. Connected to ACTIVE_L2CLK. + input logic active_clk, // Clock only while core active. Through two clock headers. For flops without second clock header built in. + input logic free_l2clk, // Clock always. Through one clock header. For flops with second header built in. + + input logic clk_override, // Override non-functional clock gating + input logic rst_l, // Flop reset + + + + output logic dec_i0_rs1_en_d, // rs1 enable at decode + output logic dec_i0_rs2_en_d, // rs2 enable at decode + + output logic [4:0] dec_i0_rs1_d, // rs1 logical source + output logic [4:0] dec_i0_rs2_d, // rs2 logical source + + output logic [31:0] dec_i0_immed_d, // 32b immediate data decode + + + output logic [12:1] dec_i0_br_immed_d, // 12b branch immediate + + output el2_alu_pkt_t i0_ap, // alu packets + + output logic dec_i0_decode_d, // i0 decode + + output logic dec_i0_alu_decode_d, // decode to D-stage alu + output logic dec_i0_branch_d, // Branch in D-stage + + output logic [4:0] dec_i0_waddr_r, // i0 logical source to write to gpr's + output logic dec_i0_wen_r, // i0 write enable + output logic [31:0] dec_i0_wdata_r, // i0 write data + + output logic dec_i0_select_pc_d, // i0 select pc for rs1 - branches + + output logic [3:0] dec_i0_rs1_bypass_en_d, // i0 rs1 bypass enable + output logic [3:0] dec_i0_rs2_bypass_en_d, // i0 rs2 bypass enable + output logic [31:0] dec_i0_result_r, // Result R-stage + + output el2_lsu_pkt_t lsu_p, // load/store packet + output logic dec_qual_lsu_d, // LSU instruction at D. Use to quiet LSU operands + + output el2_mul_pkt_t mul_p, // multiply packet + + output el2_div_pkt_t div_p, // divide packet + output logic [4:0] div_waddr_wb, // DIV write address to GPR + output logic dec_div_cancel, // cancel the divide operation + + output logic dec_lsu_valid_raw_d, + output logic [11:0] dec_lsu_offset_d, + + output logic dec_csr_ren_d, // valid csr decode + output logic dec_csr_wen_unq_d, // valid csr with write - for csr legal + output logic dec_csr_any_unq_d, // valid csr - for csr legal + output logic [11:0] dec_csr_rdaddr_d, // read address for csr + output logic dec_csr_wen_r, // csr write enable at r + output logic [11:0] dec_csr_rdaddr_r, // read address for csr + output logic [11:0] dec_csr_wraddr_r, // write address for csr + output logic [31:0] dec_csr_wrdata_r, // csr write data at r + output logic dec_csr_stall_int_ff, // csr is mie/mstatus + + output dec_tlu_i0_valid_r, // i0 valid inst at c + + output el2_trap_pkt_t dec_tlu_packet_r, // trap packet + + output logic [31:1] dec_tlu_i0_pc_r, // i0 trap pc + + output logic [31:0] dec_illegal_inst, // illegal inst + output logic [31:1] pred_correct_npc_x, // npc e2 if the prediction is correct + + output el2_predict_pkt_t dec_i0_predict_p_d, // i0 predict packet decode + output logic [pt.BHT_GHR_SIZE-1:0] i0_predict_fghr_d, // i0 predict fghr + output logic [pt.BTB_ADDR_HI:pt.BTB_ADDR_LO] i0_predict_index_d, // i0 predict index + output logic [pt.BTB_BTAG_SIZE-1:0] i0_predict_btag_d, // i0_predict branch tag + + output logic [$clog2(pt.BTB_SIZE)-1:0] dec_fa_error_index, // Fully associt btb error index + + output logic [1:0] dec_data_en, // clock-gating logic + output logic [1:0] dec_ctl_en, + + output logic dec_pmu_instr_decoded, // number of instructions decode this cycle encoded + output logic dec_pmu_decode_stall, // decode is stalled + output logic dec_pmu_presync_stall, // decode has presync stall + output logic dec_pmu_postsync_stall, // decode has postsync stall + + output logic dec_nonblock_load_wen, // write enable for nonblock load + output logic [4:0] dec_nonblock_load_waddr, // logical write addr for nonblock load + output logic dec_pause_state, // core in pause state + output logic dec_pause_state_cg, // pause state for clock-gating + + output logic dec_div_active, // non-block divide is active + + // Excluding scan_mode from coverage as its usage is determined by the integrator of the VeeR core. + /*pragma coverage off*/ + input logic scan_mode + /*pragma coverage on*/ + ); + + + + + el2_dec_pkt_t i0_dp_raw, i0_dp; + + logic [31:0] i0; + logic i0_valid_d; + + logic [31:0] i0_result_r; + + logic [2:0] i0_rs1bypass, i0_rs2bypass; + + logic i0_jalimm20; + logic i0_uiimm20; + + logic lsu_decode_d; + logic [31:0] i0_immed_d; + logic i0_presync; + logic i0_postsync; + + logic postsync_stall; + logic ps_stall; + + logic prior_inflight, prior_inflight_wb; + + logic csr_clr_d, csr_set_d, csr_write_d; + + logic csr_clr_x,csr_set_x,csr_write_x,csr_imm_x; + logic [31:0] csr_mask_x; + logic [31:0] write_csr_data_x; + logic [31:0] write_csr_data_in; + logic [31:0] write_csr_data; + logic csr_data_wen; + + logic [4:0] csrimm_x; + + logic [31:0] csr_rddata_x; + + logic mul_decode_d; + logic div_decode_d; + logic div_e1_to_r; + logic div_flush; + logic div_active_in; + logic div_active; + logic i0_nonblock_div_stall; + logic i0_div_prior_div_stall; + logic nonblock_div_cancel; + + logic i0_legal; + logic shift_illegal; + logic illegal_inst_en; + logic illegal_lockout_in, illegal_lockout; + logic i0_legal_decode_d; + logic i0_exulegal_decode_d, i0_exudecode_d, i0_exublock_d; + + logic [12:1] last_br_immed_d; + logic i0_rs1_depend_i0_x, i0_rs1_depend_i0_r; + logic i0_rs2_depend_i0_x, i0_rs2_depend_i0_r; + + logic i0_div_decode_d; + logic i0_load_block_d; + logic [1:0] i0_rs1_depth_d, i0_rs2_depth_d; + + logic i0_load_stall_d; + logic i0_store_stall_d; + + logic i0_predict_nt, i0_predict_t; + + logic i0_notbr_error, i0_br_toffset_error; + logic i0_ret_error; + logic i0_br_error; + logic i0_br_error_all; + logic [11:0] i0_br_offset; + + logic [20:1] i0_pcall_imm; // predicted jal's + logic i0_pcall_12b_offset; + logic i0_pcall_raw; + logic i0_pcall_case; + logic i0_pcall; + + logic i0_pja_raw; + logic i0_pja_case; + logic i0_pja; + + logic i0_pret_case; + logic i0_pret_raw, i0_pret; + + logic i0_jal; // jal's that are not predicted + + + logic i0_predict_br; + + logic store_data_bypass_d, store_data_bypass_m; + + el2_class_pkt_t i0_rs1_class_d, i0_rs2_class_d; + + el2_class_pkt_t i0_d_c, i0_x_c, i0_r_c; + + + logic i0_ap_pc2, i0_ap_pc4; + + logic i0_rd_en_d; + + logic load_ldst_bypass_d; + + logic leak1_i0_stall_in, leak1_i0_stall; + logic leak1_i1_stall_in, leak1_i1_stall; + logic leak1_mode; + + logic i0_csr_write_only_d; + + logic prior_inflight_x, prior_inflight_eff; + logic any_csr_d; + + logic prior_csr_write; + + logic [3:0] i0_pipe_en; + logic i0_r_ctl_en, i0_x_ctl_en, i0_wb_ctl_en; + logic i0_x_data_en, i0_r_data_en, i0_wb_data_en; + + logic debug_fence_i; + logic debug_fence; + + logic i0_csr_write; + logic presync_stall; + + logic i0_instr_error; + logic i0_icaf_d; + + logic clear_pause; + logic pause_state_in, pause_state; + logic pause_stall; + + logic i0_brp_valid; + logic nonblock_load_cancel; + logic lsu_idle; + logic lsu_pmu_misaligned_r; + logic csr_ren_qual_d; + logic csr_read_x; + logic i0_block_d; + logic i0_block_raw_d; // This is use to create the raw valid + logic ps_stall_in; + logic [31:0] i0_result_x; + + el2_dest_pkt_t d_d, x_d, r_d, wbd; + el2_dest_pkt_t x_d_in, r_d_in; + + el2_trap_pkt_t d_t, x_t, x_t_in, r_t_in, r_t; + + logic [3:0] lsu_trigger_match_r; + + logic [31:1] dec_i0_pc_r; + + logic csr_read, csr_write; + logic i0_br_unpred; + + logic nonblock_load_valid_m_delay; + logic i0_wen_r; + + logic tlu_wr_pause_r1; + logic tlu_wr_pause_r2; + + logic flush_final_r; + + logic bitmanip_zbb_legal; + logic bitmanip_zbs_legal; + logic bitmanip_zbe_legal; + logic bitmanip_zbc_legal; + logic bitmanip_zbp_legal; + logic bitmanip_zbr_legal; + logic bitmanip_zbf_legal; + logic bitmanip_zba_legal; + logic bitmanip_zbb_zbp_legal; + logic bitmanip_zbp_zbe_zbf_legal; + logic bitmanip_zbb_zbp_zbe_zbf_legal; + logic bitmanip_legal; + + + localparam NBLOAD_SIZE = pt.LSU_NUM_NBLOAD; + localparam NBLOAD_SIZE_MSB = int'(pt.LSU_NUM_NBLOAD)-1; + localparam NBLOAD_TAG_MSB = pt.LSU_NUM_NBLOAD_WIDTH-1; + + + logic cam_write, cam_inv_reset, cam_data_reset; + logic [NBLOAD_TAG_MSB:0] cam_write_tag, cam_inv_reset_tag, cam_data_reset_tag; + logic [NBLOAD_SIZE_MSB:0] cam_wen; + + logic [NBLOAD_TAG_MSB:0] load_data_tag; + logic [NBLOAD_SIZE_MSB:0] nonblock_load_write; + + el2_load_cam_pkt_t [NBLOAD_SIZE_MSB:0] cam; + el2_load_cam_pkt_t [NBLOAD_SIZE_MSB:0] cam_in; + el2_load_cam_pkt_t [NBLOAD_SIZE_MSB:0] cam_raw; + + logic [4:0] nonblock_load_rd; + logic i0_nonblock_load_stall; + logic i0_nonblock_boundary_stall; + + logic i0_rs1_nonblock_load_bypass_en_d, i0_rs2_nonblock_load_bypass_en_d; + + logic i0_load_kill_wen_r; + + logic found; + + logic [NBLOAD_SIZE_MSB:0] cam_inv_reset_val, cam_data_reset_val; + + logic debug_fence_raw; + + logic [31:0] i0_result_r_raw; + logic [31:0] i0_result_corr_r; + + logic [12:1] last_br_immed_x; + + logic [31:0] i0_inst_d; + logic [31:0] i0_inst_x; + logic [31:0] i0_inst_r; + logic [31:0] i0_inst_wb_in; + logic [31:0] i0_inst_wb; + + logic [31:1] i0_pc_wb; + + logic i0_wb_en; + + logic trace_enable; + + logic debug_valid_x; + + el2_inst_pkt_t i0_itype; + el2_reg_pkt_t i0r; + + + rvdffie #(8) misc1ff (.*, + .clk(free_l2clk), + .din( {leak1_i1_stall_in,leak1_i0_stall_in,dec_tlu_flush_extint,pause_state_in ,dec_tlu_wr_pause_r, tlu_wr_pause_r1,illegal_lockout_in,ps_stall_in}), + .dout({leak1_i1_stall, leak1_i0_stall, dec_extint_stall, pause_state, tlu_wr_pause_r1,tlu_wr_pause_r2,illegal_lockout, ps_stall }) + ); + + rvdffie #(8) misc2ff (.*, + .clk(free_l2clk), + .din( {lsu_trigger_match_m[3:0],lsu_pmu_misaligned_m,div_active_in,exu_flush_final, dec_debug_valid_d}), + .dout({lsu_trigger_match_r[3:0],lsu_pmu_misaligned_r,div_active, flush_final_r, debug_valid_x}) + ); + +if(pt.BTB_ENABLE==1) begin +// branch prediction + + + // in leak1_mode, ignore any predictions for i0, treat branch as if we haven't seen it before + // in leak1 mode, also ignore branch errors for i0 + assign i0_brp_valid = dec_i0_brp.valid & ~leak1_mode & ~i0_icaf_d; + + assign dec_i0_predict_p_d.misp = '0; + assign dec_i0_predict_p_d.ataken = '0; + assign dec_i0_predict_p_d.boffset = '0; + + assign dec_i0_predict_p_d.pcall = i0_pcall; // don't mark as pcall if branch error + assign dec_i0_predict_p_d.pja = i0_pja; + assign dec_i0_predict_p_d.pret = i0_pret; + assign dec_i0_predict_p_d.prett[31:1] = dec_i0_brp.prett[31:1]; + assign dec_i0_predict_p_d.pc4 = dec_i0_pc4_d; + assign dec_i0_predict_p_d.hist[1:0] = dec_i0_brp.hist[1:0]; + assign dec_i0_predict_p_d.valid = i0_brp_valid & i0_legal_decode_d; + assign i0_notbr_error = i0_brp_valid & ~(i0_dp_raw.condbr | i0_pcall_raw | i0_pja_raw | i0_pret_raw); + + // no toffset error for a pret + assign i0_br_toffset_error = i0_brp_valid & dec_i0_brp.hist[1] & (dec_i0_brp.toffset[11:0] != i0_br_offset[11:0]) & ~i0_pret_raw; + assign i0_ret_error = i0_brp_valid & (dec_i0_brp.ret ^ i0_pret_raw); + assign i0_br_error = dec_i0_brp.br_error | i0_notbr_error | i0_br_toffset_error | i0_ret_error; + assign dec_i0_predict_p_d.br_error = i0_br_error & i0_legal_decode_d & ~leak1_mode; + assign dec_i0_predict_p_d.br_start_error = dec_i0_brp.br_start_error & i0_legal_decode_d & ~leak1_mode; + assign i0_predict_index_d[pt.BTB_ADDR_HI:pt.BTB_ADDR_LO] = dec_i0_bp_index; + + assign i0_predict_btag_d[pt.BTB_BTAG_SIZE-1:0] = dec_i0_bp_btag[pt.BTB_BTAG_SIZE-1:0]; + assign i0_br_error_all = (i0_br_error | dec_i0_brp.br_start_error) & ~leak1_mode; + assign dec_i0_predict_p_d.toffset[11:0] = i0_br_offset[11:0]; + assign i0_predict_fghr_d[pt.BHT_GHR_SIZE-1:0] = dec_i0_bp_fghr[pt.BHT_GHR_SIZE-1:0]; + assign dec_i0_predict_p_d.way = dec_i0_brp.way; + + + if(pt.BTB_FULLYA) begin : genblock + logic btb_error_found, btb_error_found_f; + logic [$clog2(pt.BTB_SIZE)-1:0] fa_error_index_ns; + + assign btb_error_found = (i0_br_error_all | btb_error_found_f) & ~dec_tlu_flush_lower_r; + assign fa_error_index_ns = (i0_br_error_all & ~btb_error_found_f) ? dec_i0_bp_fa_index : dec_fa_error_index; + + rvdff #($clog2(pt.BTB_SIZE)+1) btberrorfa_f (.*, .clk(active_clk), + .din({btb_error_found, fa_error_index_ns}), + .dout({btb_error_found_f, dec_fa_error_index})); + + + end + else + assign dec_fa_error_index = 'b0; + + + // end +end // if (pt.BTB_ENABLE==1) +else begin + + always_comb begin + dec_i0_predict_p_d = '0; + dec_i0_predict_p_d.pcall = i0_pcall; // don't mark as pcall if branch error + dec_i0_predict_p_d.pja = i0_pja; + dec_i0_predict_p_d.pret = i0_pret; + dec_i0_predict_p_d.pc4 = dec_i0_pc4_d; + end + + assign i0_br_error_all = '0; + assign i0_predict_index_d = '0; + assign i0_predict_btag_d = '0; + assign i0_predict_fghr_d = '0; + assign i0_brp_valid = '0; +end // else: !if(pt.BTB_ENABLE==1) + + // on br error turn anything into a nop + // on i0 instruction fetch access fault turn anything into a nop + // nop => alu rs1 imm12 rd lor + + assign i0_icaf_d = dec_i0_icaf_d | dec_i0_dbecc_d; + + assign i0_instr_error = i0_icaf_d; + + always_comb begin + i0_dp = i0_dp_raw; + if (i0_br_error_all | i0_instr_error) begin + i0_dp = '0; + i0_dp.alu = 1'b1; + i0_dp.rs1 = 1'b1; + i0_dp.rs2 = 1'b1; + i0_dp.lor = 1'b1; + i0_dp.legal = 1'b1; + i0_dp.postsync = 1'b1; + end + end + + assign i0[31:0] = dec_i0_instr_d[31:0]; + + assign dec_i0_select_pc_d = i0_dp.pc; + + // branches that can be predicted + + assign i0_predict_br = i0_dp.condbr | i0_pcall | i0_pja | i0_pret; + + assign i0_predict_nt = ~(dec_i0_brp.hist[1] & i0_brp_valid) & i0_predict_br; + assign i0_predict_t = (dec_i0_brp.hist[1] & i0_brp_valid) & i0_predict_br; + + assign i0_ap.add = i0_dp.add; + assign i0_ap.sub = i0_dp.sub; + assign i0_ap.land = i0_dp.land; + assign i0_ap.lor = i0_dp.lor; + assign i0_ap.lxor = i0_dp.lxor; + assign i0_ap.sll = i0_dp.sll; + assign i0_ap.srl = i0_dp.srl; + assign i0_ap.sra = i0_dp.sra; + assign i0_ap.slt = i0_dp.slt; + assign i0_ap.unsign = i0_dp.unsign; + assign i0_ap.beq = i0_dp.beq; + assign i0_ap.bne = i0_dp.bne; + assign i0_ap.blt = i0_dp.blt; + assign i0_ap.bge = i0_dp.bge; + + assign i0_ap.clz = i0_dp.clz; + assign i0_ap.ctz = i0_dp.ctz; + assign i0_ap.cpop = i0_dp.cpop; + assign i0_ap.sext_b = i0_dp.sext_b; + assign i0_ap.sext_h = i0_dp.sext_h; + assign i0_ap.sh1add = i0_dp.sh1add; + assign i0_ap.sh2add = i0_dp.sh2add; + assign i0_ap.sh3add = i0_dp.sh3add; + assign i0_ap.zba = i0_dp.zba; + assign i0_ap.min = i0_dp.min; + assign i0_ap.max = i0_dp.max; + assign i0_ap.pack = i0_dp.pack; + assign i0_ap.packu = i0_dp.packu; + assign i0_ap.packh = i0_dp.packh; + assign i0_ap.rol = i0_dp.rol; + assign i0_ap.ror = i0_dp.ror; + assign i0_ap.grev = i0_dp.grev; + assign i0_ap.gorc = i0_dp.gorc; + assign i0_ap.zbb = i0_dp.zbb; + assign i0_ap.bset = i0_dp.bset; + assign i0_ap.bclr = i0_dp.bclr; + assign i0_ap.binv = i0_dp.binv; + assign i0_ap.bext = i0_dp.bext; + + assign i0_ap.csr_write = i0_csr_write_only_d; + assign i0_ap.csr_imm = i0_dp.csr_imm; + assign i0_ap.jal = i0_jal; + + assign i0_ap_pc2 = ~dec_i0_pc4_d; + assign i0_ap_pc4 = dec_i0_pc4_d; + + assign i0_ap.predict_nt = i0_predict_nt; + assign i0_ap.predict_t = i0_predict_t; + + +// non block load cam logic + + always_comb begin + found = 0; + for (int i=0; i coredecode.e +// 2) espresso -Dso -oeqntott < coredecode.e | addassign -pre out. > equations +// 3) copy-paste assignments from the file "equations" and replace ones below. +// +// To generate instruction legality check equation do: +// 1) coredecode -in decode -legal > legal.e +// 2) espresso -Dso -oeqntott < legal.e | addassign -pre out. > legal +// 3) copy-paste assignment from the file "legal" and replace the one below. + +module el2_dec_dec_ctl + import el2_pkg::*; +( + input logic [31:0] inst, + output el2_dec_pkt_t out +); + + logic [31:0] i; + + assign i[31:0] = inst[31:0]; + + assign out.alu = (i[30]&i[24]&i[23]&!i[22]&!i[21]&!i[20]&i[14]&!i[5]&i[4]) | (i[30] + &!i[27]&!i[24]&i[4]) | (!i[30]&!i[25]&i[13]&i[12]) | (!i[29]&!i[27] + &!i[5]&i[4]) | (i[27]&i[25]&i[14]&i[4]) | (!i[29]&!i[25]&!i[13]&!i[12] + &i[4]) | (i[29]&i[27]&!i[14]&i[12]&i[4]) | (!i[27]&i[14]&!i[5]&i[4]) | ( + i[30]&!i[29]&!i[13]&i[4]) | (!i[27]&!i[25]&i[5]&i[4]) | (i[13]&!i[5] + &i[4]) | (i[6]) | (!i[30]&i[29]&!i[24]&!i[23]&i[22]&i[21]&i[20]&!i[5] + &i[4]) | (i[2]) | (!i[12]&!i[5]&i[4]); + + assign out.rs1 = (!i[13]&i[11]&!i[2]) | (!i[13]&i[10]&!i[2]) | (i[19]&i[13]&!i[2]) | ( + !i[13]&i[9]&!i[2]) | (i[18]&i[13]&!i[2]) | (!i[13]&i[8]&!i[2]) | ( + i[17]&i[13]&!i[2]) | (!i[13]&i[7]&!i[2]) | (i[16]&i[13]&!i[2]) | ( + i[15]&i[13]&!i[2]) | (!i[4]&!i[2]) | (!i[14]&!i[13]&i[6]&!i[3]) | ( + !i[6]&!i[2]); + + assign out.rs2 = (i[5] & !i[4] & !i[2]) | (!i[6] & i[5] & !i[2]); + + assign out.imm12 = (!i[4]&!i[3]&i[2]) | (i[13]&!i[5]&i[4]&!i[2]) | (!i[13]&!i[12] + &i[6]&i[4]) | (!i[12]&!i[5]&i[4]&!i[2]); + + assign out.rd = (!i[5] & !i[2]) | (i[5] & i[2]) | (i[4]); + + assign out.shimm5 = (!i[29]&!i[13]&i[12]&!i[5]&i[4]&!i[2]) | (i[27]&!i[13]&i[12] + &!i[5]&i[4]&!i[2]) | (i[14]&!i[13]&i[12]&!i[5]&i[4]&!i[2]); + + assign out.imm20 = (i[5] & i[3]) | (i[4] & i[2]); + + assign out.pc = (!i[5] & !i[3] & i[2]) | (i[5] & i[3]); + + assign out.load = (!i[5] & !i[4] & !i[2]); + + assign out.store = (!i[6] & i[5] & !i[4]); + + assign out.lsu = (!i[6] & !i[4] & !i[2]); + + assign out.add = (!i[14]&!i[13]&!i[12]&!i[5]&i[4]) | (!i[5]&!i[3]&i[2]) | (!i[30] + &!i[25]&!i[14]&!i[13]&!i[12]&!i[6]&i[4]&!i[2]); + + assign out.sub = (i[30]&!i[14]&!i[12]&!i[6]&i[5]&i[4]&!i[2]) | (!i[29]&!i[25]&!i[14] + &i[13]&!i[6]&i[4]&!i[2]) | (i[27]&i[25]&i[14]&!i[6]&i[5]&!i[2]) | ( + !i[14]&i[13]&!i[5]&i[4]&!i[2]) | (i[6]&!i[4]&!i[2]); + + assign out.land = (!i[27]&!i[25]&i[14]&i[13]&i[12]&!i[6]&!i[2]) | (i[14]&i[13]&i[12] + &!i[5]&!i[2]); + + assign out.lor = (!i[29]&!i[27]&!i[25]&i[14]&i[13]&!i[12]&!i[6]&!i[2]) | (!i[6]&i[3]) | ( + i[5]&i[4]&i[2]) | (!i[13]&!i[12]&i[6]&i[4]) | (i[14]&i[13]&!i[12] + &!i[5]&!i[2]); + + assign out.lxor = (!i[29]&!i[27]&!i[25]&i[14]&!i[13]&!i[12]&i[4]&!i[2]) | (i[14] + &!i[13]&!i[12]&!i[5]&i[4]&!i[2]); + + assign out.sll = (!i[29] & !i[27] & !i[25] & !i[14] & !i[13] & i[12] & !i[6] & i[4] & !i[2]); + + assign out.sra = (i[30] & !i[29] & !i[27] & !i[13] & i[12] & !i[6] & i[4] & !i[2]); + + assign out.srl = (!i[30] & !i[27] & !i[25] & i[14] & !i[13] & i[12] & !i[6] & i[4] & !i[2]); + + assign out.slt = (!i[29]&!i[25]&!i[14]&i[13]&!i[6]&i[4]&!i[2]) | (!i[14]&i[13]&!i[5] + &i[4]&!i[2]); + + assign out.unsign = (!i[14]&i[13]&i[12]&!i[5]&!i[2]) | (i[13]&i[6]&!i[4]&!i[2]) | ( + i[14]&!i[5]&!i[4]) | (!i[25]&!i[14]&i[13]&i[12]&!i[6]&!i[2]) | ( + i[25]&i[14]&i[12]&!i[6]&i[5]&!i[2]); + + assign out.condbr = (i[6] & !i[4] & !i[2]); + + assign out.beq = (!i[14] & !i[12] & i[6] & !i[4] & !i[2]); + + assign out.bne = (!i[14] & i[12] & i[6] & !i[4] & !i[2]); + + assign out.bge = (i[14] & i[12] & i[5] & !i[4] & !i[2]); + + assign out.blt = (i[14] & !i[12] & i[5] & !i[4] & !i[2]); + + assign out.jal = (i[6] & i[2]); + + assign out.by = (!i[13] & !i[12] & !i[6] & !i[4] & !i[2]); + + assign out.half = (i[12] & !i[6] & !i[4] & !i[2]); + + assign out.word = (i[13] & !i[6] & !i[4]); + + assign out.csr_read = (i[13]&i[6]&i[4]) | (i[7]&i[6]&i[4]) | (i[8]&i[6]&i[4]) | ( + i[9]&i[6]&i[4]) | (i[10]&i[6]&i[4]) | (i[11]&i[6]&i[4]); + + assign out.csr_clr = (i[15]&i[13]&i[12]&i[6]&i[4]) | (i[16]&i[13]&i[12]&i[6]&i[4]) | ( + i[17]&i[13]&i[12]&i[6]&i[4]) | (i[18]&i[13]&i[12]&i[6]&i[4]) | ( + i[19]&i[13]&i[12]&i[6]&i[4]); + + assign out.csr_set = (i[15]&!i[12]&i[6]&i[4]) | (i[16]&!i[12]&i[6]&i[4]) | (i[17] + &!i[12]&i[6]&i[4]) | (i[18]&!i[12]&i[6]&i[4]) | (i[19]&!i[12]&i[6] + &i[4]); + + assign out.csr_write = (!i[13] & i[12] & i[6] & i[4]); + + assign out.csr_imm = (i[14]&!i[13]&i[6]&i[4]) | (i[15]&i[14]&i[6]&i[4]) | (i[16] + &i[14]&i[6]&i[4]) | (i[17]&i[14]&i[6]&i[4]) | (i[18]&i[14]&i[6]&i[4]) | ( + i[19]&i[14]&i[6]&i[4]); + + assign out.presync = (!i[5]&i[3]) | (!i[13]&i[7]&i[6]&i[4]) | (!i[13]&i[8]&i[6]&i[4]) | ( + !i[13]&i[9]&i[6]&i[4]) | (!i[13]&i[10]&i[6]&i[4]) | (!i[13]&i[11] + &i[6]&i[4]) | (i[15]&i[13]&i[6]&i[4]) | (i[16]&i[13]&i[6]&i[4]) | ( + i[17]&i[13]&i[6]&i[4]) | (i[18]&i[13]&i[6]&i[4]) | (i[19]&i[13]&i[6] + &i[4]); + + assign out.postsync = (!i[22]&!i[13]&!i[12]&i[6]&i[4]) | (i[12]&!i[5]&i[3]) | ( + !i[13]&i[7]&i[6]&i[4]) | (!i[13]&i[8]&i[6]&i[4]) | (!i[13]&i[9]&i[6] + &i[4]) | (!i[13]&i[10]&i[6]&i[4]) | (!i[13]&i[11]&i[6]&i[4]) | ( + i[15]&i[13]&i[6]&i[4]) | (i[16]&i[13]&i[6]&i[4]) | (i[17]&i[13]&i[6] + &i[4]) | (i[18]&i[13]&i[6]&i[4]) | (i[19]&i[13]&i[6]&i[4]); + + assign out.ebreak = (!i[22] & i[20] & !i[13] & !i[12] & i[6] & i[4]); + + assign out.ecall = (!i[21] & !i[20] & !i[13] & !i[12] & i[6] & i[4]); + + assign out.mret = (i[29] & !i[13] & !i[12] & i[6] & i[4]); + + assign out.mul = (i[29]&!i[27]&i[24]&!i[14]&!i[13]&i[12]&!i[5]&i[4]&!i[2]) | (i[30] + &i[27]&i[13]&!i[6]&i[5]&i[4]&!i[2]) | (i[29]&i[27]&!i[23]&!i[20] + &i[14]&!i[13]&i[12]&!i[5]&i[4]&!i[2]) | (i[29]&i[27]&!i[21]&i[20] + &i[14]&!i[13]&i[12]&!i[5]&i[4]&!i[2]) | (i[29]&i[27]&i[24]&i[21] + &i[14]&!i[13]&i[12]&!i[5]&i[4]&!i[2]) | (i[29]&i[27]&!i[24]&!i[22] + &i[14]&!i[13]&i[12]&!i[5]&i[4]&!i[2]) | (!i[30]&i[29]&i[23]&i[14] + &!i[13]&i[12]&!i[5]&i[4]&!i[2]) | (i[30]&i[29]&i[27]&i[22]&i[14] + &!i[13]&i[12]&!i[5]&i[4]&!i[2]) | (i[27]&!i[25]&i[13]&!i[12]&!i[6] + &i[5]&i[4]&!i[2]) | (!i[30]&!i[29]&i[27]&!i[25]&!i[13]&i[12]&!i[6] + &i[4]&!i[2]) | (i[25]&!i[14]&!i[6]&i[5]&i[4]&!i[2]) | (i[29]&i[27] + &i[14]&!i[6]&i[5]&!i[2]); + + assign out.rs1_sign = (!i[27]&i[25]&!i[14]&i[13]&!i[12]&!i[6]&i[5]&i[4]&!i[2]) | ( + !i[27]&i[25]&!i[14]&!i[13]&i[12]&!i[6]&i[4]&!i[2]); + + assign out.rs2_sign = (!i[27] & i[25] & !i[14] & !i[13] & i[12] & !i[6] & i[4] & !i[2]); + + assign out.low = (i[25] & !i[14] & !i[13] & !i[12] & i[5] & i[4] & !i[2]); + + assign out.div = (!i[27] & i[25] & i[14] & !i[6] & i[5] & !i[2]); + + assign out.rem = (!i[27] & i[25] & i[14] & i[13] & !i[6] & i[5] & !i[2]); + + assign out.fence = (!i[5] & i[3]); + + assign out.fence_i = (i[12] & !i[5] & i[3]); + + assign out.clz = (i[29]&!i[27]&!i[24]&!i[22]&!i[21]&!i[20]&!i[14]&!i[13]&i[12]&!i[5] + &i[4]&!i[2]); + + assign out.ctz = (i[29]&!i[27]&!i[24]&!i[22]&i[20]&!i[14]&!i[13]&i[12]&!i[5]&i[4] + &!i[2]); + + assign out.cpop = (i[29]&!i[27]&!i[24]&i[21]&!i[14]&!i[13]&i[12]&!i[5]&i[4]&!i[2]); + + assign out.sext_b = (i[29]&!i[27]&i[22]&!i[20]&!i[14]&!i[13]&i[12]&!i[5]&i[4]&!i[2]); + + assign out.sext_h = (i[29]&!i[27]&i[22]&i[20]&!i[14]&!i[13]&i[12]&!i[5]&i[4]&!i[2]); + + assign out.min = (i[27] & i[25] & i[14] & !i[13] & !i[6] & i[5] & !i[2]); + + assign out.max = (i[27] & i[25] & i[14] & i[13] & !i[6] & i[5] & !i[2]); + + assign out.pack = (!i[30] & !i[29] & i[27] & !i[25] & !i[13] & !i[12] & i[5] & i[4] & !i[2]); + + assign out.packu = (i[30] & i[27] & !i[13] & !i[12] & i[5] & i[4] & !i[2]); + + assign out.packh = (!i[30] & i[27] & !i[25] & i[13] & i[12] & !i[6] & i[5] & !i[2]); + + assign out.rol = (i[29] & !i[27] & !i[14] & i[12] & !i[6] & i[5] & i[4] & !i[2]); + + assign out.ror = (i[29] & !i[27] & i[14] & !i[13] & i[12] & !i[6] & i[4] & !i[2]); + + assign out.zbb = (!i[30]&!i[29]&i[27]&!i[24]&!i[23]&!i[22]&!i[21]&!i[20]&!i[13] + &!i[12]&i[5]&i[4]&!i[2]) | (i[29]&!i[27]&!i[24]&!i[13]&i[12]&!i[5] + &i[4]&!i[2]) | (i[29]&!i[27]&i[14]&!i[13]&i[12]&!i[5]&i[4]&!i[2]) | ( + i[30]&!i[27]&i[14]&!i[12]&!i[6]&i[5]&!i[2]) | (i[30]&!i[27]&i[13] + &!i[6]&i[5]&i[4]&!i[2]) | (i[29]&!i[27]&i[12]&!i[6]&i[5]&i[4]&!i[2]) | ( + !i[30]&i[29]&!i[24]&!i[23]&i[22]&i[21]&i[20]&i[14]&!i[13]&i[12]&!i[5] + &i[4]&!i[2]) | (i[30]&i[29]&i[24]&i[23]&!i[22]&!i[21]&!i[20]&i[14] + &!i[13]&i[12]&!i[5]&i[4]&!i[2]) | (i[27]&i[25]&i[14]&!i[6]&i[5]&!i[2]); + + assign out.bset = (!i[30] & i[29] & !i[14] & !i[13] & i[12] & !i[6] & i[4] & !i[2]); + + assign out.bclr = (i[30] & !i[29] & !i[14] & !i[13] & i[12] & !i[6] & i[4] & !i[2]); + + assign out.binv = (i[30] & i[29] & i[27] & !i[14] & !i[13] & i[12] & !i[6] & i[4] & !i[2]); + + assign out.bext = (i[30] & !i[29] & i[27] & i[14] & !i[13] & i[12] & !i[6] & i[4] & !i[2]); + + assign out.zbs = (i[29]&i[27]&!i[14]&!i[13]&i[12]&!i[6]&i[4]&!i[2]) | (i[30]&!i[29] + &i[27]&!i[13]&i[12]&!i[6]&i[4]&!i[2]); + + assign out.bcompress = (!i[30]&!i[29]&i[27]&!i[25]&i[13]&!i[12]&!i[6]&i[5]&i[4]&!i[2]); + + assign out.bdecompress = (i[30] & i[27] & i[13] & !i[12] & !i[6] & i[5] & i[4] & !i[2]); + + assign out.zbe = (i[30]&i[27]&i[14]&i[13]&!i[12]&!i[6]&i[5]&!i[2]) | (!i[30]&i[27] + &!i[25]&i[13]&i[12]&!i[6]&i[5]&!i[2]) | (!i[30]&!i[29]&i[27]&!i[25] + &!i[12]&!i[6]&i[5]&i[4]&!i[2]); + + assign out.clmul = (i[27] & i[25] & !i[14] & !i[13] & !i[6] & i[5] & i[4] & !i[2]); + + assign out.clmulh = (i[27] & !i[14] & i[13] & i[12] & !i[6] & i[5] & !i[2]); + + assign out.clmulr = (i[27] & i[25] & !i[14] & !i[12] & !i[6] & i[5] & i[4] & !i[2]); + + assign out.zbc = (i[27] & i[25] & !i[14] & !i[6] & i[5] & i[4] & !i[2]); + + assign out.grev = (i[30] & i[29] & i[27] & i[14] & !i[13] & i[12] & !i[6] & i[4] & !i[2]); + + assign out.gorc = (!i[30] & i[29] & i[14] & !i[13] & i[12] & !i[6] & i[4] & !i[2]); + + assign out.shfl = (!i[30]&!i[29]&i[27]&!i[25]&!i[14]&!i[13]&i[12]&!i[6]&i[4]&!i[2]); + + assign out.unshfl = (!i[30]&!i[29]&i[27]&!i[25]&i[14]&!i[13]&i[12]&!i[6]&i[4]&!i[2]); + + assign out.xperm_n = (i[29] & i[27] & !i[14] & !i[12] & !i[6] & i[5] & i[4] & !i[2]); + + assign out.xperm_b = (i[29] & i[27] & !i[13] & !i[12] & i[5] & i[4] & !i[2]); + + assign out.xperm_h = (i[29] & i[27] & i[14] & i[13] & !i[6] & i[5] & !i[2]); + + assign out.zbp = (i[30]&!i[27]&!i[14]&i[12]&!i[6]&i[5]&i[4]&!i[2]) | (!i[30]&i[27] + &!i[25]&i[13]&i[12]&!i[6]&i[5]&!i[2]) | (i[30]&!i[27]&i[13]&!i[6] + &i[5]&i[4]&!i[2]) | (i[27]&!i[25]&!i[13]&!i[12]&i[5]&i[4]&!i[2]) | ( + i[30]&i[14]&!i[13]&!i[12]&i[5]&i[4]&!i[2]) | (i[29]&i[27]&!i[12]&!i[6] + &i[5]&i[4]&!i[2]) | (!i[30]&!i[29]&i[27]&!i[25]&!i[13]&i[12]&!i[6] + &i[4]&!i[2]) | (i[29]&i[14]&!i[13]&i[12]&!i[6]&i[4]&!i[2]); + + assign out.crc32_b = (i[29]&!i[27]&i[24]&!i[23]&!i[21]&!i[20]&!i[14]&!i[13]&i[12] + &!i[5]&i[4]&!i[2]); + + assign out.crc32_h = (i[29]&!i[27]&i[24]&!i[23]&i[20]&!i[14]&!i[13]&i[12]&!i[5]&i[4] + &!i[2]); + + assign out.crc32_w = (i[29]&!i[27]&i[24]&!i[23]&i[21]&!i[14]&!i[13]&i[12]&!i[5]&i[4] + &!i[2]); + + assign out.crc32c_b = (i[29]&!i[27]&i[23]&!i[21]&!i[20]&!i[14]&!i[13]&i[12]&!i[5] + &i[4]&!i[2]); + + assign out.crc32c_h = (i[29]&!i[27]&i[23]&i[20]&!i[14]&!i[13]&i[12]&!i[5]&i[4]&!i[2]); + + assign out.crc32c_w = (i[29]&!i[27]&i[23]&i[21]&!i[14]&!i[13]&i[12]&!i[5]&i[4]&!i[2]); + + assign out.zbr = (i[29] & !i[27] & i[24] & !i[14] & !i[13] & i[12] & !i[5] & i[4] & !i[2]); + + assign out.bfp = (i[30] & i[27] & i[13] & i[12] & !i[6] & i[5] & !i[2]); + + assign out.zbf = (!i[30]&!i[29]&i[27]&!i[25]&!i[13]&!i[12]&i[5]&i[4]&!i[2]) | ( + i[27]&!i[25]&i[13]&i[12]&!i[6]&i[5]&!i[2]); + + assign out.sh1add = (i[29] & !i[27] & !i[14] & !i[12] & !i[6] & i[5] & i[4] & !i[2]); + + assign out.sh2add = (i[29] & !i[27] & i[14] & !i[13] & !i[12] & i[5] & i[4] & !i[2]); + + assign out.sh3add = (i[29] & !i[27] & i[14] & i[13] & !i[6] & i[5] & !i[2]); + + assign out.zba = (i[29] & !i[27] & !i[12] & !i[6] & i[5] & i[4] & !i[2]); + + assign out.pm_alu = (i[28]&i[20]&!i[13]&!i[12]&i[4]) | (!i[30]&!i[29]&!i[27]&!i[25] + &!i[6]&i[4]) | (!i[29]&!i[27]&!i[25]&!i[13]&i[12]&!i[6]&i[4]) | ( + !i[29]&!i[27]&!i[25]&!i[14]&!i[6]&i[4]) | (i[13]&!i[5]&i[4]) | (i[4] + &i[2]) | (!i[12]&!i[5]&i[4]); + + + assign out.legal = (!i[31]&!i[30]&i[29]&i[28]&!i[27]&!i[26]&!i[25]&!i[24]&!i[23] + &!i[22]&i[21]&!i[20]&!i[19]&!i[18]&!i[17]&!i[16]&!i[15]&!i[14]&!i[11] + &!i[10]&!i[9]&!i[8]&!i[7]&i[6]&i[5]&i[4]&!i[3]&!i[2]&i[1]&i[0]) | ( + !i[31]&!i[30]&!i[29]&i[28]&!i[27]&!i[26]&!i[25]&!i[24]&!i[23]&i[22] + &!i[21]&i[20]&!i[19]&!i[18]&!i[17]&!i[16]&!i[15]&!i[14]&!i[11]&!i[10] + &!i[9]&!i[8]&!i[7]&i[6]&i[5]&i[4]&!i[3]&!i[2]&i[1]&i[0]) | (!i[31] + &!i[30]&!i[29]&!i[28]&!i[27]&!i[26]&!i[25]&!i[24]&!i[23]&!i[22]&!i[21] + &!i[19]&!i[18]&!i[17]&!i[16]&!i[15]&!i[14]&!i[11]&!i[10]&!i[9]&!i[8] + &!i[7]&i[5]&i[4]&!i[3]&!i[2]&i[1]&i[0]) | (!i[31]&i[30]&i[29]&!i[28] + &!i[26]&!i[25]&i[24]&!i[22]&!i[20]&!i[6]&!i[5]&i[4]&!i[3]&i[1]&i[0]) | ( + !i[31]&i[30]&i[29]&!i[28]&!i[26]&!i[25]&i[24]&!i[22]&!i[21]&!i[6] + &!i[5]&i[4]&!i[3]&i[1]&i[0]) | (!i[31]&i[30]&i[29]&!i[28]&!i[26] + &!i[25]&!i[23]&!i[22]&!i[20]&!i[6]&!i[5]&i[4]&!i[3]&i[1]&i[0]) | ( + !i[31]&i[30]&i[29]&!i[28]&!i[26]&!i[25]&!i[24]&!i[23]&!i[21]&!i[6] + &!i[5]&i[4]&!i[3]&i[1]&i[0]) | (!i[31]&!i[30]&!i[29]&!i[28]&!i[26] + &i[25]&i[13]&!i[6]&i[4]&!i[3]&i[1]&i[0]) | (!i[31]&!i[28]&i[27]&!i[26] + &!i[25]&!i[24]&!i[6]&!i[5]&i[4]&!i[3]&i[1]&i[0]) | (!i[31]&!i[30] + &i[29]&!i[28]&!i[26]&!i[25]&i[13]&!i[12]&!i[6]&i[4]&!i[3]&i[1]&i[0]) | ( + !i[31]&!i[29]&!i[28]&!i[27]&!i[26]&!i[25]&!i[13]&!i[12]&!i[6]&i[4] + &!i[3]&i[1]&i[0]) | (!i[31]&i[30]&!i[28]&!i[26]&!i[25]&i[14]&!i[6] + &!i[5]&i[4]&!i[3]&i[1]&i[0]) | (!i[31]&!i[30]&!i[29]&!i[28]&!i[26] + &!i[13]&i[12]&i[5]&i[4]&!i[3]&!i[2]&i[1]&i[0]) | (!i[31]&!i[30]&!i[29] + &!i[28]&!i[27]&!i[26]&!i[25]&!i[6]&i[4]&!i[3]&i[1]&i[0]) | (!i[31] + &i[30]&i[29]&!i[28]&!i[26]&!i[25]&!i[13]&i[12]&i[5]&i[4]&!i[3]&!i[2] + &i[1]&i[0]) | (!i[31]&i[30]&!i[28]&i[27]&!i[26]&!i[25]&!i[13]&i[12] + &!i[6]&i[4]&!i[3]&i[1]&i[0]) | (!i[31]&!i[29]&!i[28]&!i[26]&!i[25] + &i[14]&!i[6]&i[5]&i[4]&!i[3]&i[1]&i[0]) | (!i[31]&i[29]&!i[28]&i[27] + &!i[26]&!i[25]&!i[13]&i[12]&!i[6]&i[4]&!i[3]&i[1]&i[0]) | (!i[31] + &!i[30]&!i[29]&!i[28]&!i[27]&!i[26]&!i[6]&i[5]&i[4]&!i[3]&i[1]&i[0]) | ( + !i[31]&!i[30]&!i[29]&!i[28]&!i[26]&i[14]&!i[6]&i[5]&i[4]&!i[3]&i[1] + &i[0]) | (!i[14]&!i[13]&!i[12]&i[6]&i[5]&!i[4]&!i[3]&i[1]&i[0]) | ( + i[14]&i[6]&i[5]&!i[4]&!i[3]&!i[2]&i[1]&i[0]) | (!i[14]&!i[13]&i[5] + &!i[4]&!i[3]&!i[2]&i[1]&i[0]) | (!i[12]&!i[6]&!i[5]&i[4]&!i[3]&i[1] + &i[0]) | (!i[13]&i[12]&i[6]&i[5]&!i[3]&!i[2]&i[1]&i[0]) | (i[13]&i[6] + &i[5]&i[4]&!i[3]&!i[2]&i[1]&i[0]) | (!i[30]&!i[29]&!i[28]&!i[14] + &!i[13]&!i[6]&!i[5]&!i[4]&i[3]&i[2]&i[1]&i[0]) | (!i[31]&!i[30]&!i[28] + &!i[26]&!i[25]&i[14]&!i[12]&!i[6]&i[4]&!i[3]&i[1]&i[0]) | (!i[14] + &!i[13]&i[12]&!i[6]&!i[5]&!i[4]&i[3]&i[2]&i[1]&i[0]) | (i[6]&i[5] + &!i[4]&i[3]&i[2]&i[1]&i[0]) | (!i[14]&!i[12]&!i[6]&!i[4]&!i[3]&!i[2] + &i[1]&i[0]) | (!i[13]&!i[6]&!i[5]&!i[4]&!i[3]&!i[2]&i[1]&i[0]) | ( + i[13]&!i[6]&!i[5]&i[4]&!i[3]&i[1]&i[0]) | (!i[6]&i[4]&!i[3]&i[2]&i[1] + &i[0]); + +endmodule // el2_dec_dec_ctl diff --git a/designs/Caliptra/src/caliptra-rtl/el2_dec_gpr_ctl.sv b/designs/Caliptra/src/caliptra-rtl/el2_dec_gpr_ctl.sv new file mode 100644 index 0000000..8f05515 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/el2_dec_gpr_ctl.sv @@ -0,0 +1,98 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2020 Western Digital Corporation or its affiliates. +// +// 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. + +module el2_dec_gpr_ctl +import el2_pkg::*; +#( + `include "el2_param.vh" + ) ( + input logic [4:0] raddr0, // logical read addresses + input logic [4:0] raddr1, + + input logic wen0, // write enable + input logic [4:0] waddr0, // write address + input logic [31:0] wd0, // write data + + input logic wen1, // write enable + input logic [4:0] waddr1, // write address + input logic [31:0] wd1, // write data + + input logic wen2, // write enable + input logic [4:0] waddr2, // write address + input logic [31:0] wd2, // write data + + input logic clk, + input logic rst_l, + + output logic [31:0] rd0, // read data + output logic [31:0] rd1, + + // Excluding scan_mode from coverage as its usage is determined by the integrator of the VeeR core. + /*pragma coverage off*/ + input logic scan_mode + /*pragma coverage on*/ +); + + logic [31:1] [31:0] gpr_out; // 31 x 32 bit GPRs + logic [31:1] [31:0] gpr_in; + logic [31:1] w0v,w1v,w2v; + logic [31:1] gpr_wr_en; + + // GPR Write Enables + assign gpr_wr_en[31:1] = (w0v[31:1] | w1v[31:1] | w2v[31:1]); + for ( genvar j=1; j<32; j++ ) begin : gpr + rvdffe #(32) gprff (.*, .en(gpr_wr_en[j]), .din(gpr_in[j][31:0]), .dout(gpr_out[j][31:0])); + end : gpr + + // the read out + always_comb begin + rd0[31:0] = 32'b0; + rd1[31:0] = 32'b0; + w0v[31:1] = 31'b0; + w1v[31:1] = 31'b0; + w2v[31:1] = 31'b0; + gpr_in[31:1] = '0; + + // GPR Read logic + for (int j=1; j<32; j++ ) begin + rd0[31:0] |= ({32{(raddr0[4:0]== 5'(j))}} & gpr_out[j][31:0]); + rd1[31:0] |= ({32{(raddr1[4:0]== 5'(j))}} & gpr_out[j][31:0]); + end + + // GPR Write logic + for (int j=1; j<32; j++ ) begin + w0v[j] = wen0 & (waddr0[4:0]== 5'(j) ); + w1v[j] = wen1 & (waddr1[4:0]== 5'(j) ); + w2v[j] = wen2 & (waddr2[4:0]== 5'(j) ); + gpr_in[j] = ({32{w0v[j]}} & wd0[31:0]) | + ({32{w1v[j]}} & wd1[31:0]) | + ({32{w2v[j]}} & wd2[31:0]); + end + end // always_comb begin + +`ifdef RV_ASSERT_ON + + logic write_collision_unused; + assign write_collision_unused = ( (w0v[31:1] == w1v[31:1]) & wen0 & wen1 ) | + ( (w0v[31:1] == w2v[31:1]) & wen0 & wen2 ) | + ( (w1v[31:1] == w2v[31:1]) & wen1 & wen2 ); + + + // asserting that no 2 ports will write to the same gpr simultaneously + assert_multiple_wen_to_same_gpr: assert #0 (~( write_collision_unused ) ); + +`endif + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/el2_dec_ib_ctl.sv b/designs/Caliptra/src/caliptra-rtl/el2_dec_ib_ctl.sv new file mode 100644 index 0000000..8dbaffd --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/el2_dec_ib_ctl.sv @@ -0,0 +1,164 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2020 Western Digital Corporation or its affiliates. +// +// 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. + +module el2_dec_ib_ctl +import el2_pkg::*; +#( +`include "el2_param.vh" + ) + ( + input logic dbg_cmd_valid, // valid dbg cmd + + input logic dbg_cmd_write, // dbg cmd is write + input logic [1:0] dbg_cmd_type, // dbg type + input logic [31:0] dbg_cmd_addr, // expand to 31:0 + + input el2_br_pkt_t i0_brp, // i0 branch packet from aligner + input logic [pt.BTB_ADDR_HI:pt.BTB_ADDR_LO] ifu_i0_bp_index, // BP index + input logic [pt.BHT_GHR_SIZE-1:0] ifu_i0_bp_fghr, // BP FGHR + input logic [pt.BTB_BTAG_SIZE-1:0] ifu_i0_bp_btag, // BP tag + input logic [$clog2(pt.BTB_SIZE)-1:0] ifu_i0_fa_index, // Fully associt btb index + + input logic ifu_i0_pc4, // i0 is 4B inst else 2B + input logic ifu_i0_valid, // i0 valid from ifu + input logic ifu_i0_icaf, // i0 instruction access fault + input logic [1:0] ifu_i0_icaf_type, // i0 instruction access fault type + + input logic ifu_i0_icaf_second, // i0 has access fault on second 2B of 4B inst + input logic ifu_i0_dbecc, // i0 double-bit error + input logic [31:0] ifu_i0_instr, // i0 instruction from the aligner + input logic [31:1] ifu_i0_pc, // i0 pc from the aligner + + + output logic dec_ib0_valid_d, // ib0 valid + output logic dec_debug_valid_d, // Debug read or write at D-stage + + + output logic [31:0] dec_i0_instr_d, // i0 inst at decode + + output logic [31:1] dec_i0_pc_d, // i0 pc at decode + + output logic dec_i0_pc4_d, // i0 is 4B inst else 2B + + output el2_br_pkt_t dec_i0_brp, // i0 branch packet at decode + output logic [pt.BTB_ADDR_HI:pt.BTB_ADDR_LO] dec_i0_bp_index, // i0 branch index + output logic [pt.BHT_GHR_SIZE-1:0] dec_i0_bp_fghr, // BP FGHR + output logic [pt.BTB_BTAG_SIZE-1:0] dec_i0_bp_btag, // BP tag + output logic [$clog2(pt.BTB_SIZE)-1:0] dec_i0_bp_fa_index, // Fully associt btb index + + output logic dec_i0_icaf_d, // i0 instruction access fault at decode + output logic dec_i0_icaf_second_d, // i0 instruction access fault on second 2B of 4B inst + output logic [1:0] dec_i0_icaf_type_d, // i0 instruction access fault type + output logic dec_i0_dbecc_d, // i0 double-bit error at decode + output logic dec_debug_wdata_rs1_d, // put debug write data onto rs1 source: machine is halted + + output logic dec_debug_fence_d // debug fence inst + + ); + + + logic debug_valid; + logic [4:0] dreg; + logic [11:0] dcsr; + logic [31:0] ib0, ib0_debug_in; + + logic debug_read; + logic debug_write; + logic debug_read_gpr; + logic debug_write_gpr; + logic debug_read_csr; + logic debug_write_csr; + + logic [34:0] ifu_i0_pcdata, pc0; + + assign ifu_i0_pcdata[34:0] = { ifu_i0_icaf_second, ifu_i0_dbecc, ifu_i0_icaf, + ifu_i0_pc[31:1], ifu_i0_pc4 }; + + assign pc0[34:0] = ifu_i0_pcdata[34:0]; + + assign dec_i0_icaf_second_d = pc0[34]; // icaf's can only decode as i0 + + assign dec_i0_dbecc_d = pc0[33]; + + assign dec_i0_icaf_d = pc0[32]; + assign dec_i0_pc_d[31:1] = pc0[31:1]; + assign dec_i0_pc4_d = pc0[0]; + + assign dec_i0_icaf_type_d[1:0] = ifu_i0_icaf_type[1:0]; + +// GPR accesses + +// put reg to read on rs1 +// read -> or %x0, %reg,%x0 {000000000000,reg[4:0],110000000110011} + +// put write date on rs1 +// write -> or %reg, %x0, %x0 {00000000000000000110,reg[4:0],0110011} + + +// CSR accesses +// csr is of form rd, csr, rs1 + +// read -> csrrs %x0, %csr, %x0 {csr[11:0],00000010000001110011} + +// put write data on rs1 +// write -> csrrw %x0, %csr, %x0 {csr[11:0],00000001000001110011} + +// abstract memory command not done here + assign debug_valid = dbg_cmd_valid & (dbg_cmd_type[1:0] != 2'h2); + + + assign debug_read = debug_valid & ~dbg_cmd_write; + assign debug_write = debug_valid & dbg_cmd_write; + + assign debug_read_gpr = debug_read & (dbg_cmd_type[1:0]==2'h0); + assign debug_write_gpr = debug_write & (dbg_cmd_type[1:0]==2'h0); + assign debug_read_csr = debug_read & (dbg_cmd_type[1:0]==2'h1); + assign debug_write_csr = debug_write & (dbg_cmd_type[1:0]==2'h1); + + assign dreg[4:0] = dbg_cmd_addr[4:0]; + assign dcsr[11:0] = dbg_cmd_addr[11:0]; + + + assign ib0_debug_in[31:0] = ({32{debug_read_gpr}} & {12'b000000000000,dreg[4:0],15'b110000000110011}) | + ({32{debug_write_gpr}} & {20'b00000000000000000110,dreg[4:0],7'b0110011}) | + ({32{debug_read_csr}} & {dcsr[11:0],20'b00000010000001110011}) | + ({32{debug_write_csr}} & {dcsr[11:0],20'b00000001000001110011}); + + + + // machine is in halted state, pipe empty, write will always happen next cycle + + assign dec_debug_wdata_rs1_d = debug_write_gpr | debug_write_csr; + + + // special fence csr for use only in debug mode + + assign dec_debug_fence_d = debug_write_csr & (dcsr[11:0] == 12'h7c4); + + assign ib0[31:0] = (debug_valid) ? ib0_debug_in[31:0] : ifu_i0_instr[31:0]; + + assign dec_ib0_valid_d = ifu_i0_valid | debug_valid; + + assign dec_debug_valid_d = debug_valid; + + assign dec_i0_instr_d[31:0] = ib0[31:0]; + + assign dec_i0_brp = i0_brp; + assign dec_i0_bp_index = ifu_i0_bp_index; + assign dec_i0_bp_fghr = ifu_i0_bp_fghr; + assign dec_i0_bp_btag = ifu_i0_bp_btag; + assign dec_i0_bp_fa_index = ifu_i0_fa_index; + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/el2_dec_pmp_ctl.sv b/designs/Caliptra/src/caliptra-rtl/el2_dec_pmp_ctl.sv new file mode 100644 index 0000000..a8f7933 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/el2_dec_pmp_ctl.sv @@ -0,0 +1,186 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2023 Antmicro +// +// 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. + + +//******************************************************************************** +// el2_dec_pmp_ctl.sv +// +// +// Function: Physical Memory Protection CSRs +// Comments: +// +//******************************************************************************** + +module el2_dec_pmp_ctl + import el2_pkg::*; +#( +`include "el2_param.vh" + ) + ( + input logic clk, + input logic free_l2clk, + input logic csr_wr_clk, + input logic rst_l, + input logic dec_csr_wen_r_mod, // csr write enable at wb + input logic [11:0] dec_csr_wraddr_r, // write address for csr + input logic [31:0] dec_csr_wrdata_r, // csr write data at wb + input logic [11:0] dec_csr_rdaddr_d, // read address for csr + + input logic csr_pmpcfg, + input logic csr_pmpaddr0, + input logic csr_pmpaddr16, + input logic csr_pmpaddr32, + input logic csr_pmpaddr48, + + input logic dec_pause_state, // Paused + input logic dec_tlu_pmu_fw_halted, // pmu/fw halted + input logic internal_dbg_halt_timers, // debug halted + +`ifdef RV_SMEPMP + input el2_mseccfg_pkt_t mseccfg, +`endif + + output logic [31:0] dec_pmp_rddata_d, // pmp CSR read data + output logic dec_pmp_read_d, // pmp CSR address match + + output el2_pmp_cfg_pkt_t pmp_pmpcfg [pt.PMP_ENTRIES], + output logic [31:0] pmp_pmpaddr [pt.PMP_ENTRIES], + + // Excluding scan_mode from coverage as its usage is determined by the integrator of the VeeR core. + /*pragma coverage off*/ + input logic scan_mode + /*pragma coverage on*/ + ); + + logic wr_pmpcfg_r; + logic [3:0] wr_pmpcfg_group; + + logic wr_pmpaddr0_sel; + logic wr_pmpaddr16_sel; + logic wr_pmpaddr32_sel; + logic wr_pmpaddr48_sel; + logic wr_pmpaddr_r; + logic [1:0] wr_pmpaddr_quarter; + logic [5:0] wr_pmpaddr_address; + + logic [3:0] pmp_quarter_rdaddr; + logic [31:0] pmp_pmpcfg_rddata; + + // ---------------------------------------------------------------------- + + logic [pt.PMP_ENTRIES-1:0] entry_lock_eff; // Effective entry lock + for (genvar r = 0; r < pt.PMP_ENTRIES; r++) begin : g_pmpcfg_lock +`ifdef RV_SMEPMP + // Smepmp allow modifying locked entries when mseccfg.RLB is set + assign entry_lock_eff[r] = pmp_pmpcfg[r].lock & ~mseccfg.RLB; +`else + assign entry_lock_eff[r] = pmp_pmpcfg[r].lock; +`endif + end + + // ---------------------------------------------------------------------- + // PMPCFGx (RW) + // [31:24] : PMP entry (x*4 + 3) configuration + // [23:16] : PMP entry (x*4 + 2) configuration + // [15:8] : PMP entry (x*4 + 1) configuration + // [7:0] : PMP entry (x*4 + 0) configuration + + localparam PMPCFG = 12'h3a0; + localparam PMP_ENTRIES_WIDTH = $clog2(pt.PMP_ENTRIES); + + assign wr_pmpcfg_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:4] == PMPCFG[11:4]); + assign wr_pmpcfg_group = dec_csr_wraddr_r[3:0]; // selects group of 4 pmpcfg entries (group 1 -> entries 4-7; up to 16 groups) + + for (genvar entry_idx = 0; entry_idx < pt.PMP_ENTRIES; entry_idx++) begin : gen_pmpcfg_ff + logic [7:0] raw_wdata; + logic [7:0] csr_wdata; + + // PMPCFG fields are WARL. Mask out bits 6:5 during write. + // When Smepmp is disabled R=0 and W=1 combination is illegal mask out W + // when R is cleared. + assign raw_wdata = dec_csr_wrdata_r[(entry_idx[1:0]*8)+7:(entry_idx[1:0]*8)+0]; +`ifdef RV_SMEPMP + assign csr_wdata = raw_wdata & 8'b10011111; +`else + assign csr_wdata = raw_wdata[0] ? (raw_wdata & 8'b10011111) : (raw_wdata & 8'b10011101); +`endif + + rvdffe #(8) pmpcfg_ff (.*, .clk(free_l2clk), + .en(wr_pmpcfg_r & (wr_pmpcfg_group == entry_idx[5:2]) & (~entry_lock_eff[entry_idx])), + .din(csr_wdata), + .dout(pmp_pmpcfg[entry_idx])); + end + + // ---------------------------------------------------------------------- + // PMPADDRx (RW) + // [31:0] : PMP entry (x) address selector (word addressing) + // + // NOTE: VeeR-EL2 uses 32-bit physical addressing, register bits 31:30 mapping + // to bits 33:32 of the physical address are always set to 0. (WARL) + + localparam PMPADDR0 = 12'h3b0; + localparam PMPADDR16 = 12'h3c0; + localparam PMPADDR32 = 12'h3d0; + localparam PMPADDR48 = 12'h3e0; + + assign wr_pmpaddr0_sel = dec_csr_wraddr_r[11:4] == PMPADDR0[11:4]; + assign wr_pmpaddr16_sel = dec_csr_wraddr_r[11:4] == PMPADDR16[11:4]; + assign wr_pmpaddr32_sel = dec_csr_wraddr_r[11:4] == PMPADDR32[11:4]; + assign wr_pmpaddr48_sel = dec_csr_wraddr_r[11:4] == PMPADDR48[11:4]; + assign wr_pmpaddr_r = dec_csr_wen_r_mod & (wr_pmpaddr0_sel | wr_pmpaddr16_sel | wr_pmpaddr32_sel | wr_pmpaddr48_sel); + + assign wr_pmpaddr_quarter[0] = wr_pmpaddr16_sel | wr_pmpaddr48_sel; + assign wr_pmpaddr_quarter[1] = wr_pmpaddr32_sel | wr_pmpaddr48_sel; + assign wr_pmpaddr_address = {wr_pmpaddr_quarter, dec_csr_wraddr_r[3:0]}; // entry address + + for (genvar entry_idx = 0; entry_idx < pt.PMP_ENTRIES; entry_idx++) begin : gen_pmpaddr_ff + logic pmpaddr_lock; + logic pmpaddr_lock_next; + if (entry_idx+1 < pt.PMP_ENTRIES) + assign pmpaddr_lock_next = entry_lock_eff[entry_idx+1] & pmp_pmpcfg[entry_idx+1].mode == TOR; + else + assign pmpaddr_lock_next = 1'b0; + assign pmpaddr_lock = entry_lock_eff[entry_idx] | pmpaddr_lock_next; + assign pmp_pmpaddr[entry_idx][31:30] = 2'b00; + rvdffe #(30) pmpaddr_ff (.*, .clk(free_l2clk), + .en(wr_pmpaddr_r & (wr_pmpaddr_address == entry_idx) + & (~pmpaddr_lock)), + .din(dec_csr_wrdata_r[29:0]), + .dout(pmp_pmpaddr[entry_idx][29:0])); + end + + // CSR read mux + logic [5:0] pmp_pmpcfg_rdata_selector [4]; + logic [5:0] dec_pmp_rdata_selector [4]; + + assign pmp_quarter_rdaddr = dec_csr_rdaddr_d[3:0]; + for (genvar i = 0; i < 4; i++) begin: gen_csr_selector + assign pmp_pmpcfg_rdata_selector[i] = {pmp_quarter_rdaddr, 2'(i)}; + assign dec_pmp_rdata_selector[i] = {2'(i), pmp_quarter_rdaddr}; + end + + assign pmp_pmpcfg_rddata = { pmp_pmpcfg[pmp_pmpcfg_rdata_selector[3][PMP_ENTRIES_WIDTH-1:0]], + pmp_pmpcfg[pmp_pmpcfg_rdata_selector[2][PMP_ENTRIES_WIDTH-1:0]], + pmp_pmpcfg[pmp_pmpcfg_rdata_selector[1][PMP_ENTRIES_WIDTH-1:0]], + pmp_pmpcfg[pmp_pmpcfg_rdata_selector[0][PMP_ENTRIES_WIDTH-1:0]] + }; + assign dec_pmp_read_d = csr_pmpcfg | csr_pmpaddr0 | csr_pmpaddr16 | csr_pmpaddr32 | csr_pmpaddr48; + assign dec_pmp_rddata_d[31:0] = ( ({32{csr_pmpcfg}} & pmp_pmpcfg_rddata) | + ({32{csr_pmpaddr0}} & pmp_pmpaddr[dec_pmp_rdata_selector[0][PMP_ENTRIES_WIDTH-1:0]]) | + ({32{csr_pmpaddr16}} & pmp_pmpaddr[dec_pmp_rdata_selector[1][PMP_ENTRIES_WIDTH-1:0]]) | + ({32{csr_pmpaddr32}} & pmp_pmpaddr[dec_pmp_rdata_selector[2][PMP_ENTRIES_WIDTH-1:0]]) | + ({32{csr_pmpaddr48}} & pmp_pmpaddr[dec_pmp_rdata_selector[3][PMP_ENTRIES_WIDTH-1:0]]) + ); +endmodule // dec_pmp_ctl diff --git a/designs/Caliptra/src/caliptra-rtl/el2_dec_tlu_ctl.sv b/designs/Caliptra/src/caliptra-rtl/el2_dec_tlu_ctl.sv new file mode 100644 index 0000000..ac44e78 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/el2_dec_tlu_ctl.sv @@ -0,0 +1,3177 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2020 Western Digital Corporation or it's affiliates. +// +// 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. + + +//******************************************************************************** +// el2_dec_tlu_ctl.sv +// +// +// Function: CSRs, Commit/WB, flushing, exceptions, interrupts +// Comments: +// +//******************************************************************************** + +module el2_dec_tlu_ctl +import el2_pkg::*; +#( +`include "el2_param.vh" + ) + ( + input logic clk, + input logic free_clk, + input logic free_l2clk, + input logic rst_l, + // Excluding scan_mode from coverage as its usage is determined by the integrator of the VeeR core. + /*pragma coverage off*/ + input logic scan_mode, + /*pragma coverage on*/ + + //rst_vec is supposed to be connected to constant in the top level + /*pragma coverage off*/ + input logic [31:1] rst_vec, // reset vector, from core pins + /*pragma coverage on*/ + input logic nmi_int, // nmi pin + //nmi_vec is supposed to be connected to constant in the top level + /*pragma coverage off*/ + input logic [31:1] nmi_vec, // nmi vector + /*pragma coverage on*/ + input logic i_cpu_halt_req, // Asynchronous Halt request to CPU + input logic i_cpu_run_req, // Asynchronous Restart request to CPU + + input logic lsu_fastint_stall_any, // needed by lsu for 2nd pass of dma with ecc correction, stall next cycle + + + // perf counter inputs + input logic ifu_pmu_instr_aligned, // aligned instructions + input logic ifu_pmu_fetch_stall, // fetch unit stalled + input logic ifu_pmu_ic_miss, // icache miss + input logic ifu_pmu_ic_hit, // icache hit + input logic ifu_pmu_bus_error, // Instruction side bus error + input logic ifu_pmu_bus_busy, // Instruction side bus busy + input logic ifu_pmu_bus_trxn, // Instruction side bus transaction + input logic dec_pmu_instr_decoded, // decoded instructions + input logic dec_pmu_decode_stall, // decode stall + input logic dec_pmu_presync_stall, // decode stall due to presync'd inst + input logic dec_pmu_postsync_stall,// decode stall due to postsync'd inst + input logic lsu_store_stall_any, // SB or WB is full, stall decode + input logic dma_dccm_stall_any, // DMA stall of lsu + input logic dma_iccm_stall_any, // DMA stall of ifu + input logic exu_pmu_i0_br_misp, // pipe 0 branch misp + input logic exu_pmu_i0_br_ataken, // pipe 0 branch actual taken + input logic exu_pmu_i0_pc4, // pipe 0 4 byte branch + input logic lsu_pmu_bus_trxn, // D side bus transaction + input logic lsu_pmu_bus_misaligned, // D side bus misaligned + input logic lsu_pmu_bus_error, // D side bus error + input logic lsu_pmu_bus_busy, // D side bus busy + input logic lsu_pmu_load_external_m, // D side bus load + input logic lsu_pmu_store_external_m, // D side bus store + input logic dma_pmu_dccm_read, // DMA DCCM read + input logic dma_pmu_dccm_write, // DMA DCCM write + input logic dma_pmu_any_read, // DMA read + input logic dma_pmu_any_write, // DMA write + + input logic [31:1] lsu_fir_addr, // Fast int address + input logic [1:0] lsu_fir_error, // Fast int lookup error + + input logic iccm_dma_sb_error, // I side dma single bit error + + input el2_lsu_error_pkt_t lsu_error_pkt_r, // lsu precise exception/error packet + input logic lsu_single_ecc_error_incr, // LSU inc SB error counter + + input logic dec_pause_state, // Pause counter not zero + input logic lsu_imprecise_error_store_any, // store bus error + input logic lsu_imprecise_error_load_any, // store bus error + input logic [31:0] lsu_imprecise_error_addr_any, // store bus error address + + input logic dec_csr_wen_unq_d, // valid csr with write - for csr legal + input logic dec_csr_any_unq_d, // valid csr - for csr legal + input logic [11:0] dec_csr_rdaddr_d, // read address for csr + + input logic dec_csr_wen_r, // csr write enable at wb + input logic [11:0] dec_csr_rdaddr_r, // read address for csr + input logic [11:0] dec_csr_wraddr_r, // write address for csr + input logic [31:0] dec_csr_wrdata_r, // csr write data at wb + + input logic dec_csr_stall_int_ff, // csr is mie/mstatus + + input logic dec_tlu_i0_valid_r, // pipe 0 op at e4 is valid + + input logic [31:1] exu_npc_r, // for NPC tracking + + input logic [31:1] dec_tlu_i0_pc_r, // for PC/NPC tracking + + input el2_trap_pkt_t dec_tlu_packet_r, // exceptions known at decode + + input logic [31:0] dec_illegal_inst, // For mtval + input logic dec_i0_decode_d, // decode valid, used for clean icache diagnostics + + // branch info from pipe0 for errors or counter updates + input logic [1:0] exu_i0_br_hist_r, // history + input logic exu_i0_br_error_r, // error + input logic exu_i0_br_start_error_r, // start error + input logic exu_i0_br_valid_r, // valid + input logic exu_i0_br_mp_r, // mispredict + input logic exu_i0_br_middle_r, // middle of bank + + // branch info from pipe1 for errors or counter updates + + input logic exu_i0_br_way_r, // way hit or repl + + output logic dec_tlu_core_empty, // core is empty + // Debug start + output logic dec_dbg_cmd_done, // abstract command done + output logic dec_dbg_cmd_fail, // abstract command failed + output logic dec_tlu_dbg_halted, // Core is halted and ready for debug command + output logic dec_tlu_debug_mode, // Core is in debug mode + output logic dec_tlu_resume_ack, // Resume acknowledge + output logic dec_tlu_debug_stall, // stall decode while waiting on core to empty + + output logic dec_tlu_flush_noredir_r , // Tell fetch to idle on this flush + output logic dec_tlu_mpc_halted_only, // Core is halted only due to MPC + output logic dec_tlu_flush_leak_one_r, // single step + output logic dec_tlu_flush_err_r, // iside perr/ecc rfpc. This is the D stage of the error + + output logic dec_tlu_flush_extint, // fast ext int started + output logic [31:2] dec_tlu_meihap, // meihap for fast int + + input logic dbg_halt_req, // DM requests a halt + input logic dbg_resume_req, // DM requests a resume + input logic ifu_miss_state_idle, // I-side miss buffer empty + input logic lsu_idle_any, // lsu is idle + input logic dec_div_active, // oop div is active + output el2_trigger_pkt_t [3:0] trigger_pkt_any, // trigger info for trigger blocks + + input logic ifu_ic_error_start, // IC single bit error + input logic ifu_iccm_rd_ecc_single_err, // ICCM single bit error + + + input logic [70:0] ifu_ic_debug_rd_data, // diagnostic icache read data + input logic ifu_ic_debug_rd_data_valid, // diagnostic icache read data valid + output el2_cache_debug_pkt_t dec_tlu_ic_diag_pkt, // packet of DICAWICS, DICAD0/1, DICAGO info for icache diagnostics + // Debug end + + input logic [7:0] pic_claimid, // pic claimid for csr + input logic [3:0] pic_pl, // pic priv level for csr + input logic mhwakeup, // high priority external int, wakeup if halted + + input logic mexintpend, // external interrupt pending + input logic timer_int, // timer interrupt pending + input logic soft_int, // software interrupt pending + + output logic o_cpu_halt_status, // PMU interface, halted + output logic o_cpu_halt_ack, // halt req ack + output logic o_cpu_run_ack, // run req ack + output logic o_debug_mode_status, // Core to the PMU that core is in debug mode. When core is in debug mode, the PMU should refrain from sendng a halt or run request + + /*pragma coverage off*/ + input logic [31:4] core_id, // Core ID + /*pragma coverage on*/ + + // external MPC halt/run interface + input logic mpc_debug_halt_req, // Async halt request + input logic mpc_debug_run_req, // Async run request + input logic mpc_reset_run_req, // Run/halt after reset + output logic mpc_debug_halt_ack, // Halt ack + output logic mpc_debug_run_ack, // Run ack + output logic debug_brkpt_status, // debug breakpoint + + output logic [3:0] dec_tlu_meicurpl, // to PIC + output logic [3:0] dec_tlu_meipt, // to PIC + + + output logic [31:0] dec_csr_rddata_d, // csr read data at wb + output logic dec_csr_legal_d, // csr indicates legal operation + + output el2_br_tlu_pkt_t dec_tlu_br0_r_pkt, // branch pkt to bp + + output logic dec_tlu_i0_kill_writeb_wb, // I0 is flushed, don't writeback any results to arch state + output logic dec_tlu_flush_lower_wb, // commit has a flush (exception, int, mispredict at e4) + output logic dec_tlu_i0_commit_cmt, // committed an instruction + + output logic dec_tlu_i0_kill_writeb_r, // I0 is flushed, don't writeback any results to arch state + output logic dec_tlu_flush_lower_r, // commit has a flush (exception, int) + output logic [31:1] dec_tlu_flush_path_r, // flush pc + output logic dec_tlu_fence_i_r, // flush is a fence_i rfnpc, flush icache + output logic dec_tlu_wr_pause_r, // CSR write to pause reg is at R. + output logic dec_tlu_flush_pause_r, // Flush is due to pause + + output logic dec_tlu_presync_d, // CSR read needs to be presync'd + output logic dec_tlu_postsync_d, // CSR needs to be presync'd + + + output logic [31:0] dec_tlu_mrac_ff, // CSR for memory region control + + output logic dec_tlu_force_halt, // halt has been forced + + output logic dec_tlu_perfcnt0, // toggles when pipe0 perf counter 0 has an event inc + output logic dec_tlu_perfcnt1, // toggles when pipe0 perf counter 1 has an event inc + output logic dec_tlu_perfcnt2, // toggles when pipe0 perf counter 2 has an event inc + output logic dec_tlu_perfcnt3, // toggles when pipe0 perf counter 3 has an event inc + + output logic dec_tlu_i0_exc_valid_wb1, // pipe 0 exception valid + output logic dec_tlu_i0_valid_wb1, // pipe 0 valid + output logic dec_tlu_int_valid_wb1, // pipe 2 int valid + output logic [4:0] dec_tlu_exc_cause_wb1, // exception or int cause + output logic [31:0] dec_tlu_mtval_wb1, // MTVAL value + + // feature disable from mfdc + output logic dec_tlu_external_ldfwd_disable, // disable external load forwarding + output logic dec_tlu_sideeffect_posted_disable, // disable posted stores to side-effect address + output logic dec_tlu_core_ecc_disable, // disable core ECC + output logic dec_tlu_bpred_disable, // disable branch prediction + output logic dec_tlu_wb_coalescing_disable, // disable writebuffer coalescing + output logic dec_tlu_pipelining_disable, // disable pipelining + output logic dec_tlu_trace_disable, // disable trace + output logic [2:0] dec_tlu_dma_qos_prty, // DMA QoS priority coming from MFDC [18:16] + + // clock gating overrides from mcgc + output logic dec_tlu_misc_clk_override, // override misc clock domain gating + output logic dec_tlu_dec_clk_override, // override decode clock domain gating + output logic dec_tlu_ifu_clk_override, // override fetch clock domain gating + output logic dec_tlu_lsu_clk_override, // override load/store clock domain gating + output logic dec_tlu_bus_clk_override, // override bus clock domain gating + output logic dec_tlu_pic_clk_override, // override PIC clock domain gating + output logic dec_tlu_picio_clk_override,// override PICIO clock domain gating + output logic dec_tlu_dccm_clk_override, // override DCCM clock domain gating + output logic dec_tlu_icm_clk_override, // override ICCM clock domain gating + +`ifdef RV_USER_MODE + + // Privilege mode + // 0 - machine, 1 - user + output logic priv_mode, + output logic priv_mode_eff, + output logic priv_mode_ns, + + // mseccfg CSR content for PMP + output logic [2:0] mseccfg, + +`endif + + // pmp + output el2_pmp_cfg_pkt_t pmp_pmpcfg [pt.PMP_ENTRIES], + output logic [31:0] pmp_pmpaddr [pt.PMP_ENTRIES] + ); + + logic clk_override, e4e5_int_clk, nmi_fir_type, nmi_lsu_load_type, nmi_lsu_store_type, nmi_int_detected_f, nmi_lsu_load_type_f, + nmi_lsu_store_type_f, allow_dbg_halt_csr_write, dbg_cmd_done_ns, i_cpu_run_req_d1_raw, debug_mode_status, lsu_single_ecc_error_r_d1, + sel_npc_r, sel_npc_resume, ce_int, + nmi_in_debug_mode, dpc_capture_npc, dpc_capture_pc, tdata_load, tdata_opcode, tdata_action, perfcnt_halted, tdata_chain, + tdata_kill_write; + + + logic reset_delayed, reset_detect, reset_detected; + logic wr_mstatus_r, wr_mtvec_r, wr_mcyclel_r, wr_mcycleh_r, + wr_minstretl_r, wr_minstreth_r, wr_mscratch_r, wr_mepc_r, wr_mcause_r, wr_mscause_r, wr_mtval_r, + wr_mrac_r, wr_meihap_r, wr_meicurpl_r, wr_meipt_r, wr_dcsr_r, + wr_dpc_r, wr_meicidpl_r, wr_meivt_r, wr_meicpct_r, wr_micect_r, wr_miccmect_r, wr_mfdht_r, wr_mfdhs_r, + wr_mdccmect_r,wr_mhpme3_r, wr_mhpme4_r, wr_mhpme5_r, wr_mhpme6_r; + logic wr_mpmc_r; + logic [1:1] mpmc_b_ns, mpmc, mpmc_b; + logic set_mie_pmu_fw_halt, fw_halted_ns, fw_halted; + logic wr_mcountinhibit_r; +`ifdef RV_USER_MODE + logic wr_mcounteren_r; + logic [5:0] mcounteren; // HPM6, HPM5, HPM4, HPM3, IR, CY + logic wr_mseccfg_r; + logic [2:0] mseccfg_ns; +`endif + logic [6:0] mcountinhibit; + logic wr_mtsel_r, wr_mtdata1_t0_r, wr_mtdata1_t1_r, wr_mtdata1_t2_r, wr_mtdata1_t3_r, wr_mtdata2_t0_r, wr_mtdata2_t1_r, wr_mtdata2_t2_r, wr_mtdata2_t3_r; + logic [31:0] mtdata2_t0, mtdata2_t1, mtdata2_t2, mtdata2_t3, mtdata2_tsel_out, mtdata1_tsel_out; + logic [9:0] mtdata1_t0_ns, mtdata1_t0, mtdata1_t1_ns, mtdata1_t1, mtdata1_t2_ns, mtdata1_t2, mtdata1_t3_ns, mtdata1_t3; + logic [9:0] tdata_wrdata_r; + logic [1:0] mtsel_ns, mtsel; + logic tlu_i0_kill_writeb_r; +`ifdef RV_USER_MODE + logic [3:0] mstatus_ns, mstatus; // MPRV, MPP (inverted! 0-M, 1-U), MPIE, MIE +`else + logic [1:0] mstatus_ns, mstatus; +`endif + logic [1:0] mfdhs_ns, mfdhs; + logic [31:0] force_halt_ctr, force_halt_ctr_f; + logic force_halt; + logic [5:0] mfdht, mfdht_ns; + logic mstatus_mie_ns; + logic [30:0] mtvec_ns, mtvec; + logic [15:2] dcsr_ns, dcsr; + logic [5:0] mip_ns, mip; + logic [5:0] mie_ns, mie; + logic [31:0] mcyclel_ns, mcyclel; + logic [31:0] mcycleh_ns, mcycleh; + logic [31:0] minstretl_ns, minstretl; + logic [31:0] minstreth_ns, minstreth; + logic [31:0] micect_ns, micect, miccmect_ns, miccmect, mdccmect_ns, mdccmect; + logic [26:0] micect_inc, miccmect_inc, mdccmect_inc; + logic [31:0] mscratch; + logic [31:0] mhpmc3, mhpmc3_ns, mhpmc4, mhpmc4_ns, mhpmc5, mhpmc5_ns, mhpmc6, mhpmc6_ns; + logic [31:0] mhpmc3h, mhpmc3h_ns, mhpmc4h, mhpmc4h_ns, mhpmc5h, mhpmc5h_ns, mhpmc6h, mhpmc6h_ns; + logic [9:0] mhpme3, mhpme4, mhpme5, mhpme6; + logic [31:0] mrac; + logic [9:2] meihap; + logic [31:10] meivt; + logic [3:0] meicurpl_ns, meicurpl; + logic [3:0] meicidpl_ns, meicidpl; + logic [3:0] meipt_ns, meipt; + logic [31:0] mdseac; + logic mdseac_locked_ns, mdseac_locked_f, mdseac_en, nmi_lsu_detected; + logic [31:1] mepc_ns, mepc; + logic [31:1] dpc_ns, dpc; + logic [31:0] mcause_ns, mcause; + logic [3:0] mscause_ns, mscause, mscause_type; + logic [31:0] mtval_ns, mtval; + logic dec_pause_state_f, dec_tlu_wr_pause_r_d1, pause_expired_r, pause_expired_wb; + logic tlu_flush_lower_r, tlu_flush_lower_r_d1; + logic [31:1] tlu_flush_path_r, tlu_flush_path_r_d1; + logic i0_valid_wb; + logic tlu_i0_commit_cmt; + logic [31:1] vectored_path, interrupt_path; + logic [16:0] dicawics_ns, dicawics; + logic wr_dicawics_r, wr_dicad0_r, wr_dicad1_r, wr_dicad0h_r; + logic [31:0] dicad0_ns, dicad0, dicad0h_ns, dicad0h; + + logic [6:0] dicad1_ns, dicad1_raw; + logic [31:0] dicad1; + logic ebreak_r, ebreak_to_debug_mode_r, ecall_r, illegal_r, mret_r, inst_acc_r, fence_i_r, + ic_perr_r, iccm_sbecc_r, ebreak_to_debug_mode_r_d1, kill_ebreak_count_r, inst_acc_second_r; + logic ce_int_ready, ext_int_ready, timer_int_ready, soft_int_ready, int_timer0_int_ready, int_timer1_int_ready, mhwakeup_ready, + take_ext_int, take_ce_int, take_timer_int, take_soft_int, take_int_timer0_int, take_int_timer1_int, take_nmi, take_nmi_r_d1, int_timer0_int_possible, int_timer1_int_possible; + logic i0_exception_valid_r, interrupt_valid_r, i0_exception_valid_r_d1, interrupt_valid_r_d1, exc_or_int_valid_r, exc_or_int_valid_r_d1, mdccme_ce_req, miccme_ce_req, mice_ce_req; + logic synchronous_flush_r; + logic [4:0] exc_cause_r, exc_cause_wb; + logic mcyclel_cout, mcyclel_cout_f, mcyclela_cout; + logic [31:0] mcyclel_inc; + logic [31:0] mcycleh_inc; + + logic minstretl_cout, minstretl_cout_f, minstret_enable, minstretl_cout_ns, minstretl_couta; + + logic [31:0] minstretl_inc, minstretl_read; + logic [31:0] minstreth_inc, minstreth_read; + logic [31:1] pc_r, pc_r_d1, npc_r, npc_r_d1; + logic valid_csr; + logic rfpc_i0_r; + logic lsu_i0_rfnpc_r; + logic dec_tlu_br0_error_r, dec_tlu_br0_start_error_r, dec_tlu_br0_v_r; + logic lsu_i0_exc_r, lsu_i0_exc_r_raw, lsu_exc_ma_r, lsu_exc_acc_r, lsu_exc_st_r, + lsu_exc_valid_r, lsu_exc_valid_r_raw, lsu_exc_valid_r_d1, lsu_i0_exc_r_d1, block_interrupts; + logic i0_trigger_eval_r; + + logic request_debug_mode_r, request_debug_mode_r_d1, request_debug_mode_done, request_debug_mode_done_f; + logic take_halt, halt_taken, halt_taken_f, internal_dbg_halt_mode, dbg_tlu_halted_f, take_reset, + dbg_tlu_halted, core_empty, lsu_idle_any_f, ifu_miss_state_idle_f, resume_ack_ns, + debug_halt_req_f, debug_resume_req_f_raw, debug_resume_req_f, enter_debug_halt_req, dcsr_single_step_done, dcsr_single_step_done_f, + debug_halt_req_d1, debug_halt_req_ns, dcsr_single_step_running, dcsr_single_step_running_f, internal_dbg_halt_timers; + + logic [3:0] i0_trigger_r, trigger_action, trigger_enabled, + i0_trigger_chain_masked_r; + logic i0_trigger_hit_r, i0_trigger_hit_raw_r, i0_trigger_action_r, + trigger_hit_r_d1, + mepc_trigger_hit_sel_pc_r; + logic [3:0] update_hit_bit_r, i0_iside_trigger_has_pri_r,i0trigger_qual_r, i0_lsu_trigger_has_pri_r; + logic cpu_halt_status, cpu_halt_ack, cpu_run_ack, ext_halt_pulse, i_cpu_halt_req_d1, i_cpu_run_req_d1; + + logic inst_acc_r_raw, trigger_hit_dmode_r, trigger_hit_dmode_r_d1; + logic [9:0] mcgc, mcgc_ns, mcgc_int; + logic [18:0] mfdc; + logic i_cpu_halt_req_sync_qual, i_cpu_run_req_sync_qual, pmu_fw_halt_req_ns, pmu_fw_halt_req_f, int_timer_stalled, + fw_halt_req, enter_pmu_fw_halt_req, pmu_fw_tlu_halted, pmu_fw_tlu_halted_f, internal_pmu_fw_halt_mode, + internal_pmu_fw_halt_mode_f, int_timer0_int_hold, int_timer1_int_hold, int_timer0_int_hold_f, int_timer1_int_hold_f; + logic nmi_int_delayed, nmi_int_detected; + logic [3:0] trigger_execute, trigger_data, trigger_store; + logic dec_tlu_pmu_fw_halted; + + logic mpc_run_state_ns, debug_brkpt_status_ns, mpc_debug_halt_ack_ns, mpc_debug_run_ack_ns, dbg_halt_state_ns, dbg_run_state_ns, + dbg_halt_state_f, mpc_debug_halt_req_sync_f, mpc_debug_run_req_sync_f, mpc_halt_state_f, mpc_halt_state_ns, mpc_run_state_f, debug_brkpt_status_f, + mpc_debug_halt_ack_f, mpc_debug_run_ack_f, dbg_run_state_f, mpc_debug_halt_req_sync_pulse, + mpc_debug_run_req_sync_pulse, debug_brkpt_valid, debug_halt_req, debug_resume_req, dec_tlu_mpc_halted_only_ns; + logic take_ext_int_start, ext_int_freeze, take_ext_int_start_d1, take_ext_int_start_d2, + take_ext_int_start_d3, ext_int_freeze_d1, ignore_ext_int_due_to_lsu_stall; + logic mcause_sel_nmi_store, mcause_sel_nmi_load, mcause_sel_nmi_ext, fast_int_meicpct; + logic [1:0] mcause_fir_error_type; + logic dbg_halt_req_held_ns, dbg_halt_req_held, dbg_halt_req_final; + logic iccm_repair_state_ns, iccm_repair_state_d1, iccm_repair_state_rfnpc; + + + // internal timer, isolated for size reasons + logic [31:0] dec_timer_rddata_d; + logic dec_timer_read_d, dec_timer_t0_pulse, dec_timer_t1_pulse; + + // PMP unit, isolated for size reasons + logic [31:0] dec_pmp_rddata_d; + logic dec_pmp_read_d; + + logic nmi_int_sync, timer_int_sync, soft_int_sync, i_cpu_halt_req_sync, i_cpu_run_req_sync, mpc_debug_halt_req_sync, mpc_debug_run_req_sync, mpc_debug_halt_req_sync_raw; + logic csr_wr_clk; + logic e4e5_clk, e4_valid, e5_valid, e4e5_valid, internal_dbg_halt_mode_f, internal_dbg_halt_mode_f2; + logic lsu_pmu_load_external_r, lsu_pmu_store_external_r; + logic dec_tlu_flush_noredir_r_d1, dec_tlu_flush_pause_r_d1; + logic lsu_single_ecc_error_r; + logic [31:0] lsu_error_pkt_addr_r; + logic mcyclel_cout_in; + logic i0_valid_no_ebreak_ecall_r; + logic minstret_enable_f; + logic sel_exu_npc_r, sel_flush_npc_r, sel_hold_npc_r; + logic pc0_valid_r; + logic [15:0] mfdc_int, mfdc_ns; + logic [31:0] mrac_in; + logic [31:27] csr_sat; + logic [8:6] dcsr_cause; + logic enter_debug_halt_req_le, dcsr_cause_upgradeable; + logic icache_rd_valid, icache_wr_valid, icache_rd_valid_f, icache_wr_valid_f; + logic [3:0] mhpmc_inc_r, mhpmc_inc_r_d1; + + logic [3:0][9:0] mhpme_vec; + logic mhpmc3_wr_en0, mhpmc3_wr_en1, mhpmc3_wr_en; + logic mhpmc4_wr_en0, mhpmc4_wr_en1, mhpmc4_wr_en; + logic mhpmc5_wr_en0, mhpmc5_wr_en1, mhpmc5_wr_en; + logic mhpmc6_wr_en0, mhpmc6_wr_en1, mhpmc6_wr_en; + logic mhpmc3h_wr_en0, mhpmc3h_wr_en; + logic mhpmc4h_wr_en0, mhpmc4h_wr_en; + logic mhpmc5h_wr_en0, mhpmc5h_wr_en; + logic mhpmc6h_wr_en0, mhpmc6h_wr_en; + logic [63:0] mhpmc3_incr, mhpmc4_incr, mhpmc5_incr, mhpmc6_incr; + logic perfcnt_halted_d1, zero_event_r; + logic [3:0] perfcnt_during_sleep; + logic [9:0] event_r; + + el2_inst_pkt_t pmu_i0_itype_qual; + + logic dec_csr_wen_r_mod; + + logic flush_clkvalid; + logic sel_fir_addr; + logic wr_mie_r; + logic mtval_capture_pc_r; + logic mtval_capture_pc_plus2_r; + logic mtval_capture_inst_r; + logic mtval_capture_lsu_r; + logic mtval_clear_r; + logic wr_mcgc_r; + logic wr_mfdc_r; + logic wr_mdeau_r; + logic trigger_hit_for_dscr_cause_r_d1; + logic conditionally_illegal; + + logic [3:0] ifu_mscause ; + logic ifu_ic_error_start_f, ifu_iccm_rd_ecc_single_err_f; + + // CSR address decoder + +// files "csrdecode_m" (machine mode only) and "csrdecode_mu" (machine mode plus +// user mode) are human readable that have all of the CSR decodes defined and +// are part of the git repo. Modify these files as needed. + +// to generate all the equations below from "csrdecode" except legal equation: + +// 1) coredecode -in csrdecode > corecsrdecode.e + +// 2) espresso -Dso -oeqntott < corecsrdecode.e | addassign > csrequations + +// to generate the legal CSR equation below: + +// 1) coredecode -in csrdecode -legal > csrlegal.e + +// 2) espresso -Dso -oeqntott < csrlegal.e | addassign > csrlegal_equation + +// coredecode -in csrdecode > corecsrdecode.e; espresso -Dso -oeqntott < corecsrdecode.e | addassign > csrequations; coredecode -in csrdecode -legal > csrlegal.e; espresso -Dso -oeqntott csrlegal.e | addassign > csrlegal_equation + +`ifdef RV_USER_MODE + + `include "el2_dec_csr_equ_mu.svh" + + logic csr_acc_r; // CSR access error + logic csr_wr_usr_r; // Write to an unprivileged/user-level CSR + logic csr_rd_usr_r; // REad from an unprivileged/user-level CSR + +`else + + `include "el2_dec_csr_equ_m.svh" + +`endif + + el2_dec_timer_ctl #(.pt(pt)) int_timers(.*); + // end of internal timers + + el2_dec_pmp_ctl #(.pt(pt)) pmp(.*); + // end of pmp + + assign clk_override = dec_tlu_dec_clk_override; + + // Async inputs to the core have to be sync'd to the core clock. + rvsyncss #(7) syncro_ff(.*, + .clk(free_clk), + .din ({nmi_int, timer_int, soft_int, i_cpu_halt_req, i_cpu_run_req, mpc_debug_halt_req, mpc_debug_run_req}), + .dout({nmi_int_sync, timer_int_sync, soft_int_sync, i_cpu_halt_req_sync, i_cpu_run_req_sync, mpc_debug_halt_req_sync_raw, mpc_debug_run_req_sync})); + + // for CSRs that have inpipe writes only + + rvoclkhdr csrwr_r_cgc ( .en(dec_csr_wen_r_mod | clk_override), .l1clk(csr_wr_clk), .* ); + + assign e4_valid = dec_tlu_i0_valid_r; + assign e4e5_valid = e4_valid | e5_valid; + assign flush_clkvalid = internal_dbg_halt_mode_f | i_cpu_run_req_d1 | interrupt_valid_r | interrupt_valid_r_d1 | + reset_delayed | pause_expired_r | pause_expired_wb | ic_perr_r | iccm_sbecc_r | + clk_override; + rvoclkhdr e4e5_cgc ( .en(e4e5_valid | clk_override), .l1clk(e4e5_clk), .* ); + rvoclkhdr e4e5_int_cgc ( .en(e4e5_valid | flush_clkvalid), .l1clk(e4e5_int_clk), .* ); + + rvdffie #(11) freeff (.*, .clk(free_l2clk), + .din ({ifu_ic_error_start, ifu_iccm_rd_ecc_single_err, iccm_repair_state_ns, e4_valid, internal_dbg_halt_mode, + lsu_pmu_load_external_m, lsu_pmu_store_external_m, tlu_flush_lower_r, tlu_i0_kill_writeb_r, + internal_dbg_halt_mode_f, force_halt}), + .dout({ifu_ic_error_start_f, ifu_iccm_rd_ecc_single_err_f, iccm_repair_state_d1, e5_valid, internal_dbg_halt_mode_f, + lsu_pmu_load_external_r, lsu_pmu_store_external_r, tlu_flush_lower_r_d1, dec_tlu_i0_kill_writeb_wb, + internal_dbg_halt_mode_f2, dec_tlu_force_halt})); + + assign dec_tlu_i0_kill_writeb_r = tlu_i0_kill_writeb_r; + + assign nmi_int_detected = (nmi_int_sync & ~nmi_int_delayed) | nmi_lsu_detected | (nmi_int_detected_f & ~take_nmi_r_d1) | nmi_fir_type; + // if the first nmi is a lsu type, note it. If there's already an nmi pending, ignore. Simultaneous with FIR, drop. + assign nmi_lsu_load_type = (nmi_lsu_detected & lsu_imprecise_error_load_any & ~(nmi_int_detected_f & ~take_nmi_r_d1)) | + (nmi_lsu_load_type_f & ~take_nmi_r_d1); + assign nmi_lsu_store_type = (nmi_lsu_detected & lsu_imprecise_error_store_any & ~(nmi_int_detected_f & ~take_nmi_r_d1)) | + (nmi_lsu_store_type_f & ~take_nmi_r_d1); + + assign nmi_fir_type = ~nmi_int_detected_f & take_ext_int_start_d3 & |lsu_fir_error[1:0]; + + // Filter subsequent bus errors after the first, until the lock on MDSEAC is cleared + assign nmi_lsu_detected = ~mdseac_locked_f & (lsu_imprecise_error_load_any | lsu_imprecise_error_store_any) & ~nmi_fir_type; + + +localparam MSTATUS_MIE = 0; +localparam int MSTATUS_MPIE = 1; +`ifdef RV_USER_MODE +localparam MSTATUS_MPP = 2; +localparam MSTATUS_MPRV = 3; +`endif + +localparam MIP_MCEIP = 5; +localparam MIP_MITIP0 = 4; +localparam MIP_MITIP1 = 3; +localparam MIP_MEIP = 2; +localparam MIP_MTIP = 1; +localparam MIP_MSIP = 0; + +localparam MIE_MCEIE = 5; +localparam MIE_MITIE0 = 4; +localparam MIE_MITIE1 = 3; +localparam MIE_MEIE = 2; +localparam MIE_MTIE = 1; +localparam MIE_MSIE = 0; + +localparam DCSR_EBREAKM = 15; +localparam DCSR_STEPIE = 11; +localparam DCSR_STOPC = 10; +localparam DCSR_STEP = 2; + +`ifdef RV_USER_MODE +localparam MCOUNTEREN_CY = 0; +localparam MCOUNTEREN_IR = 1; +localparam MCOUNTEREN_HPM3 = 2; +localparam MCOUNTEREN_HPM4 = 3; +localparam MCOUNTEREN_HPM5 = 4; +localparam MCOUNTEREN_HPM6 = 5; + +localparam MSECCFG_RLB = 2; +localparam MSECCFG_MMWP = 1; +localparam MSECCFG_MML = 0; +`endif + + // ---------------------------------------------------------------------- + // MISA (RO) + // [31:30] XLEN - implementation width, 2'b01 - 32 bits + // [20] U - user mode support (if enabled in config) + // [12] M - integer mul/div + // [8] I - RV32I + // [2] C - Compressed extension + localparam MISA = 12'h301; + + // MVENDORID, MARCHID, MIMPID, MHARTID + localparam MVENDORID = 12'hf11; + localparam MARCHID = 12'hf12; + localparam MIMPID = 12'hf13; + localparam MHARTID = 12'hf14; + + + // ---------------------------------------------------------------------- + // MSTATUS (RW) + // [17] MPRV : Modify PRiVilege (if enabled in config) + // [12:11] MPP : Prior priv level, either 2'b11 (machine) or 2'b00 (user) + // [7] MPIE : Int enable previous [1] + // [3] MIE : Int enable [0] + localparam MSTATUS = 12'h300; + + // ---------------------------------------------------------------------- + // MTVEC (RW) + // [31:2] BASE : Trap vector base address + // [1] - Reserved, not implemented, reads zero + // [0] MODE : 0 = Direct, 1 = Asyncs are vectored to BASE + (4 * CAUSE) + localparam MTVEC = 12'h305; + + // ---------------------------------------------------------------------- + // MIP (RW) + // + // [30] MCEIP : (RO) M-Mode Correctable Error interrupt pending + // [29] MITIP0 : (RO) M-Mode Internal Timer0 interrupt pending + // [28] MITIP1 : (RO) M-Mode Internal Timer1 interrupt pending + // [11] MEIP : (RO) M-Mode external interrupt pending + // [7] MTIP : (RO) M-Mode timer interrupt pending + // [3] MSIP : (RO) M-Mode software interrupt pending + localparam MIP = 12'h344; + + // ---------------------------------------------------------------------- + // MIE (RW) + // [30] MCEIE : (RO) M-Mode Correctable Error interrupt enable + // [29] MITIE0 : (RO) M-Mode Internal Timer0 interrupt enable + // [28] MITIE1 : (RO) M-Mode Internal Timer1 interrupt enable + // [11] MEIE : (RW) M-Mode external interrupt enable + // [7] MTIE : (RW) M-Mode timer interrupt enable + // [3] MSIE : (RW) M-Mode software interrupt enable + localparam MIE = 12'h304; + + // ---------------------------------------------------------------------- + // MCYCLEL (RW) + // [31:0] : Lower Cycle count + + localparam MCYCLEL = 12'hb00; + localparam logic [11:0] CYCLEL = 12'hc00; + + // ---------------------------------------------------------------------- + // MCYCLEH (RW) + // [63:32] : Higher Cycle count + // Chained with mcyclel. Note: mcyclel overflow due to a mcycleh write gets ignored. + + localparam MCYCLEH = 12'hb80; + localparam logic [11:0] CYCLEH = 12'hc80; + + // ---------------------------------------------------------------------- + // MINSTRETL (RW) + // [31:0] : Lower Instruction retired count + // From the spec "Some CSRs, such as the instructions retired counter, instret, may be modified as side effects + // of instruction execution. In these cases, if a CSR access instruction reads a CSR, it reads the + // value prior to the execution of the instruction. If a CSR access instruction writes a CSR, the + // update occurs after the execution of the instruction. In particular, a value written to instret by + // one instruction will be the value read by the following instruction (i.e., the increment of instret + // caused by the first instruction retiring happens before the write of the new value)." + localparam MINSTRETL = 12'hb02; + localparam logic [11:0] INSTRETL = 12'hc02; + + // ---------------------------------------------------------------------- + // MINSTRETH (RW) + // [63:32] : Higher Instret count + // Chained with minstretl. Note: minstretl overflow due to a minstreth write gets ignored. + + localparam MINSTRETH = 12'hb82; + localparam logic [11:0] INSTRETH = 12'hc82; + + // ---------------------------------------------------------------------- + // MSCRATCH (RW) + // [31:0] : Scratch register + localparam MSCRATCH = 12'h340; + + // ---------------------------------------------------------------------- + // MEPC (RW) + // [31:1] : Exception PC + localparam MEPC = 12'h341; + + // ---------------------------------------------------------------------- + // MCAUSE (RW) + // [31:0] : Exception Cause + localparam MCAUSE = 12'h342; + + // ---------------------------------------------------------------------- + // MSCAUSE (RW) + // [2:0] : Secondary exception Cause + localparam MSCAUSE = 12'h7ff; + + // ---------------------------------------------------------------------- + // MTVAL (RW) + // [31:0] : Exception address if relevant + localparam MTVAL = 12'h343; + + // ---------------------------------------------------------------------- + // MCGC (RW) Clock gating control + // [31:10]: Reserved, reads 0x0 + // [9] : picio_clk_override + // [7] : dec_clk_override + // [6] : Unused + // [5] : ifu_clk_override + // [4] : lsu_clk_override + // [3] : bus_clk_override + // [2] : pic_clk_override + // [1] : dccm_clk_override + // [0] : icm_clk_override + // + localparam MCGC = 12'h7f8; + + // ---------------------------------------------------------------------- + // MFDC (RW) Feature Disable Control + // [31:19] : Reserved, reads 0x0 + // [18:16] : DMA QoS Prty + // [15:13] : Reserved, reads 0x0 + // [12] : Disable trace + // [11] : Disable external load forwarding + // [10] : Disable dual issue + // [9] : Disable pic multiple ints + // [8] : Disable core ecc + // [7] : Disable secondary alu?s + // [6] : Unused, 0x0 + // [5] : Disable non-blocking loads/divides + // [4] : Disable fast divide + // [3] : Disable branch prediction and return stack + // [2] : Disable write buffer coalescing + // [1] : Disable load misses that bypass the write buffer + // [0] : Disable pipelining - Enable single instruction execution + // + localparam MFDC = 12'h7f9; + + // ---------------------------------------------------------------------- + // MRAC (RW) + // [31:0] : Region Access Control Register, 16 regions, {side_effect, cachable} pairs + localparam MRAC = 12'h7c0; + + // ---------------------------------------------------------------------- + // MDEAU (WAR0) + // [31:0] : Dbus Error Address Unlock register + // + localparam MDEAU = 12'hbc0; + + // ---------------------------------------------------------------------- + // MDSEAC (R) + // [31:0] : Dbus Store Error Address Capture register + // + localparam MDSEAC = 12'hfc0; + + // ---------------------------------------------------------------------- + // MPMC (R0W1) + // [0] : FW halt + // [1] : Set MSTATUS[MIE] on halt + localparam MPMC = 12'h7c6; + + // ---------------------------------------------------------------------- + // MICECT (I-Cache error counter/threshold) + // [31:27] : Icache parity error threshold + // [26:0] : Icache parity error count + localparam MICECT = 12'h7f0; + + // ---------------------------------------------------------------------- + // MICCMECT (ICCM error counter/threshold) + // [31:27] : ICCM parity error threshold + // [26:0] : ICCM parity error count + localparam MICCMECT = 12'h7f1; + + // ---------------------------------------------------------------------- + // MDCCMECT (DCCM error counter/threshold) + // [31:27] : DCCM parity error threshold + // [26:0] : DCCM parity error count + localparam MDCCMECT = 12'h7f2; + + // ---------------------------------------------------------------------- + // MFDHT (Force Debug Halt Threshold) + // [5:1] : Halt timeout threshold (power of 2) + // [0] : Halt timeout enabled + localparam MFDHT = 12'h7ce; + + // ---------------------------------------------------------------------- + // MFDHS(RW) + // [1] : LSU operation pending when debug halt threshold reached + // [0] : IFU operation pending when debug halt threshold reached + localparam MFDHS = 12'h7cf; + + // ---------------------------------------------------------------------- + // MEIVT (External Interrupt Vector Table (R/W)) + // [31:10]: Base address (R/W) + // [9:0] : Reserved, reads 0x0 + localparam MEIVT = 12'hbc8; + + // ---------------------------------------------------------------------- + // MEICURPL (R/W) + // [31:4] : Reserved (read 0x0) + // [3:0] : CURRPRI - Priority level of current interrupt service routine (R/W) + localparam MEICURPL = 12'hbcc; + + // ---------------------------------------------------------------------- + // MEICIDPL (R/W) + // [31:4] : Reserved (read 0x0) + // [3:0] : External Interrupt Claim ID's Priority Level Register + localparam MEICIDPL = 12'hbcb; + + // ---------------------------------------------------------------------- + // MEICPCT (Capture CLAIMID in MEIHAP and PL in MEICIDPL + // [31:1] : Reserved (read 0x0) + // [0] : Capture (W1, Read 0) + localparam MEICPCT = 12'hbca; + + // ---------------------------------------------------------------------- + // MEIPT (External Interrupt Priority Threshold) + // [31:4] : Reserved (read 0x0) + // [3:0] : PRITHRESH + localparam MEIPT = 12'hbc9; + + // ---------------------------------------------------------------------- + // DCSR (R/W) (Only accessible in debug mode) + // [31:28] : xdebugver (hard coded to 0x4) RO + // [27:16] : 0x0, reserved + // [15] : ebreakm + // [14] : 0x0, reserved + // [13] : ebreaks (0x0 for this core) + // [12] : ebreaku (0x0 for this core) + // [11] : stepie + // [10] : stopcount + // [9] : 0x0 //stoptime + // [8:6] : cause (RO) + // [5:4] : 0x0, reserved + // [3] : nmip + // [2] : step + // [1:0] : prv (0x3 for this core) + // + localparam DCSR = 12'h7b0; + + // ---------------------------------------------------------------------- + // DPC (R/W) (Only accessible in debug mode) + // [31:0] : Debug PC + localparam DPC = 12'h7b1; + + // ---------------------------------------------------------------------- + // DICAWICS (R/W) (Only accessible in debug mode) + // [31:25] : Reserved + // [24] : Array select, 0 is data, 1 is tag + // [23:22] : Reserved + // [21:20] : Way select + // [19:17] : Reserved + // [16:3] : Index + // [2:0] : Reserved + localparam DICAWICS = 12'h7c8; + + // ---------------------------------------------------------------------- + // DICAD0 (R/W) (Only accessible in debug mode) + // + // If dicawics[array] is 0 + // [31:0] : inst data + // + // If dicawics[array] is 1 + // [31:16] : Tag + // [15:7] : Reserved + // [6:4] : LRU + // [3:1] : Reserved + // [0] : Valid + localparam DICAD0 = 12'h7c9; + + // ---------------------------------------------------------------------- + // DICAD0H (R/W) (Only accessible in debug mode) + // + // If dicawics[array] is 0 + // [63:32] : inst data + // + localparam DICAD0H = 12'h7cc; + + // ---------------------------------------------------------------------- + // DICAGO (R/W) (Only accessible in debug mode) + // [0] : Go + localparam DICAGO = 12'h7cb; + + // ---------------------------------------------------------------------- + // MHPMC3H(RW), MHPMC3(RW) + // [63:32][31:0] : Hardware Performance Monitor Counter 3 + localparam MHPMC3 = 12'hB03; + localparam MHPMC3H = 12'hB83; +`ifdef RV_USER_MODE + localparam HPMC3 = 12'hC03; + localparam HPMC3H = 12'hC83; +`endif + + // ---------------------------------------------------------------------- + // MHPMC4H(RW), MHPMC4(RW) + // [63:32][31:0] : Hardware Performance Monitor Counter 4 + localparam MHPMC4 = 12'hB04; + localparam MHPMC4H = 12'hB84; +`ifdef RV_USER_MODE + localparam HPMC4 = 12'hC04; + localparam HPMC4H = 12'hC84; +`endif + + // ---------------------------------------------------------------------- + // MHPMC5H(RW), MHPMC5(RW) + // [63:32][31:0] : Hardware Performance Monitor Counter 5 + localparam MHPMC5 = 12'hB05; + localparam MHPMC5H = 12'hB85; +`ifdef RV_USER_MODE + localparam HPMC5 = 12'hC05; + localparam HPMC5H = 12'hC85; +`endif + + // ---------------------------------------------------------------------- + // MHPMC6H(RW), MHPMC6(RW) + // [63:32][31:0] : Hardware Performance Monitor Counter 6 + localparam MHPMC6 = 12'hB06; + localparam MHPMC6H = 12'hB86; +`ifdef RV_USER_MODE + localparam HPMC6 = 12'hC06; + localparam HPMC6H = 12'hC86; +`endif + + // ---------------------------------------------------------------------- + // MHPME3(RW) + // [9:0] : Hardware Performance Monitor Event 3 + localparam MHPME3 = 12'h323; + + // ---------------------------------------------------------------------- + // MHPME4(RW) + // [9:0] : Hardware Performance Monitor Event 4 + localparam MHPME4 = 12'h324; + + // ---------------------------------------------------------------------- + // MHPME5(RW) + // [9:0] : Hardware Performance Monitor Event 5 + localparam MHPME5 = 12'h325; + + // ---------------------------------------------------------------------- + // MHPME6(RW) + // [9:0] : Hardware Performance Monitor Event 6 + localparam MHPME6 = 12'h326; + + // MCOUNTINHIBIT(RW) + // [31:7] : Reserved, read 0x0 + // [6] : HPM6 disable + // [5] : HPM5 disable + // [4] : HPM4 disable + // [3] : HPM3 disable + // [2] : MINSTRET disable + // [1] : reserved, read 0x0 + // [0] : MCYCLE disable + + localparam MCOUNTINHIBIT = 12'h320; + + // ---------------------------------------------------------------------- + // MTSEL (R/W) + // [1:0] : Trigger select : 00, 01, 10 are data/address triggers. 11 is inst count + localparam MTSEL = 12'h7a0; + + // ---------------------------------------------------------------------- + // MTDATA1 (R/W) + // [31:0] : Trigger Data 1 + localparam MTDATA1 = 12'h7a1; + + // ---------------------------------------------------------------------- + // MTDATA2 (R/W) + // [31:0] : Trigger Data 2 + localparam MTDATA2 = 12'h7a2; + + assign reset_delayed = reset_detect ^ reset_detected; + + // ---------------------------------------------------------------------- + // MPC halt + // - can interact with debugger halt and v-v + + // fast ints in progress have priority + assign mpc_debug_halt_req_sync = mpc_debug_halt_req_sync_raw & ~ext_int_freeze_d1; + + rvdffie #(16) mpvhalt_ff (.*, .clk(free_l2clk), + .din({1'b1, reset_detect, + nmi_int_sync, nmi_int_detected, nmi_lsu_load_type, nmi_lsu_store_type, + mpc_debug_halt_req_sync, mpc_debug_run_req_sync, + mpc_halt_state_ns, mpc_run_state_ns, debug_brkpt_status_ns, + mpc_debug_halt_ack_ns, mpc_debug_run_ack_ns, + dbg_halt_state_ns, dbg_run_state_ns, + dec_tlu_mpc_halted_only_ns}), + .dout({reset_detect, reset_detected, + nmi_int_delayed, nmi_int_detected_f, nmi_lsu_load_type_f, nmi_lsu_store_type_f, + mpc_debug_halt_req_sync_f, mpc_debug_run_req_sync_f, + mpc_halt_state_f, mpc_run_state_f, debug_brkpt_status_f, + mpc_debug_halt_ack_f, mpc_debug_run_ack_f, + dbg_halt_state_f, dbg_run_state_f, + dec_tlu_mpc_halted_only})); + + // turn level sensitive requests into pulses + assign mpc_debug_halt_req_sync_pulse = mpc_debug_halt_req_sync & ~mpc_debug_halt_req_sync_f; + assign mpc_debug_run_req_sync_pulse = mpc_debug_run_req_sync & ~mpc_debug_run_req_sync_f; + + // states + assign mpc_halt_state_ns = (mpc_halt_state_f | mpc_debug_halt_req_sync_pulse | (reset_delayed & ~mpc_reset_run_req)) & ~mpc_debug_run_req_sync; + assign mpc_run_state_ns = (mpc_run_state_f | (mpc_debug_run_req_sync_pulse & ~mpc_debug_run_ack_f)) & (internal_dbg_halt_mode_f & ~dcsr_single_step_running_f); + + // note, MPC halt can allow the jtag debugger to just start sending commands. When that happens, set the interal debugger halt state to prevent + // MPC run from starting the core. + assign dbg_halt_state_ns = (dbg_halt_state_f | (dbg_halt_req_final | dcsr_single_step_done_f | trigger_hit_dmode_r_d1 | ebreak_to_debug_mode_r_d1)) & ~dbg_resume_req; + assign dbg_run_state_ns = (dbg_run_state_f | dbg_resume_req) & (internal_dbg_halt_mode_f & ~dcsr_single_step_running_f); + + // tell dbg we are only MPC halted + assign dec_tlu_mpc_halted_only_ns = ~dbg_halt_state_f & mpc_halt_state_f; + + // this asserts from detection of bkpt until after we leave debug mode + assign debug_brkpt_valid = ebreak_to_debug_mode_r_d1 | trigger_hit_dmode_r_d1; + assign debug_brkpt_status_ns = (debug_brkpt_valid | debug_brkpt_status_f) & (internal_dbg_halt_mode & ~dcsr_single_step_running_f); + + // acks back to interface + assign mpc_debug_halt_ack_ns = (mpc_halt_state_f & internal_dbg_halt_mode_f & mpc_debug_halt_req_sync & core_empty) | (mpc_debug_halt_ack_f & mpc_debug_halt_req_sync); + assign mpc_debug_run_ack_ns = (mpc_debug_run_req_sync & ~internal_dbg_halt_mode & ~mpc_debug_halt_req_sync) | (mpc_debug_run_ack_f & mpc_debug_run_req_sync) ; + + // Pins + assign mpc_debug_halt_ack = mpc_debug_halt_ack_f; + assign mpc_debug_run_ack = mpc_debug_run_ack_f; + assign debug_brkpt_status = debug_brkpt_status_f; + + // DBG halt req is a pulse, fast ext int in progress has priority + assign dbg_halt_req_held_ns = (dbg_halt_req | dbg_halt_req_held) & ext_int_freeze_d1; + assign dbg_halt_req_final = (dbg_halt_req | dbg_halt_req_held) & ~ext_int_freeze_d1; + + // combine MPC and DBG halt requests + assign debug_halt_req = (dbg_halt_req_final | mpc_debug_halt_req_sync | (reset_delayed & ~mpc_reset_run_req)) & ~internal_dbg_halt_mode_f & ~ext_int_freeze_d1; + + assign debug_resume_req = ~debug_resume_req_f & // squash back to back resumes + ((mpc_run_state_ns & ~dbg_halt_state_ns) | // MPC run req + (dbg_run_state_ns & ~mpc_halt_state_ns)); // dbg request is a pulse + + + // HALT + // dbg/pmu/fw requests halt, service as soon as lsu is not blocking interrupts + assign take_halt = (debug_halt_req_f | pmu_fw_halt_req_f) & ~synchronous_flush_r & ~mret_r & ~halt_taken_f & ~dec_tlu_flush_noredir_r_d1 & ~take_reset; + + // hold after we take a halt, so we don't keep taking halts + assign halt_taken = (dec_tlu_flush_noredir_r_d1 & ~dec_tlu_flush_pause_r_d1 & ~take_ext_int_start_d1) | (halt_taken_f & ~dbg_tlu_halted_f & ~pmu_fw_tlu_halted_f & ~interrupt_valid_r_d1); + + // After doing halt flush (RFNPC) wait until core is idle before asserting a particular halt mode + // It takes a cycle for mb_empty to assert after a fetch, take_halt covers that cycle + assign core_empty = force_halt | + (lsu_idle_any & lsu_idle_any_f & ifu_miss_state_idle & ifu_miss_state_idle_f & ~debug_halt_req & ~debug_halt_req_d1 & ~dec_div_active); + + assign dec_tlu_core_empty = core_empty; + +//-------------------------------------------------------------------------------- +// Debug start +// + + assign enter_debug_halt_req = (~internal_dbg_halt_mode_f & debug_halt_req) | dcsr_single_step_done_f | trigger_hit_dmode_r_d1 | ebreak_to_debug_mode_r_d1; + + // dbg halt state active from request until non-step resume + assign internal_dbg_halt_mode = debug_halt_req_ns | (internal_dbg_halt_mode_f & ~(debug_resume_req_f & ~dcsr[DCSR_STEP])); + // dbg halt can access csrs as long as we are not stepping + assign allow_dbg_halt_csr_write = internal_dbg_halt_mode_f & ~dcsr_single_step_running_f; + + + // hold debug_halt_req_ns high until we enter debug halt + assign debug_halt_req_ns = enter_debug_halt_req | (debug_halt_req_f & ~dbg_tlu_halted); + + assign dbg_tlu_halted = (debug_halt_req_f & core_empty & halt_taken) | (dbg_tlu_halted_f & ~debug_resume_req_f); + + assign resume_ack_ns = (debug_resume_req_f & dbg_tlu_halted_f & dbg_run_state_ns); + + assign dcsr_single_step_done = dec_tlu_i0_valid_r & ~dec_tlu_dbg_halted & dcsr[DCSR_STEP] & ~rfpc_i0_r; + + assign dcsr_single_step_running = (debug_resume_req_f & dcsr[DCSR_STEP]) | (dcsr_single_step_running_f & ~dcsr_single_step_done_f); + + assign dbg_cmd_done_ns = dec_tlu_i0_valid_r & dec_tlu_dbg_halted; + + // used to hold off commits after an in-pipe debug mode request (triggers, DCSR) + assign request_debug_mode_r = (trigger_hit_dmode_r | ebreak_to_debug_mode_r) | (request_debug_mode_r_d1 & ~dec_tlu_flush_lower_wb); + + assign request_debug_mode_done = (request_debug_mode_r_d1 | request_debug_mode_done_f) & ~dbg_tlu_halted_f; + + rvdffie #(18) halt_ff (.*, .clk(free_l2clk), + .din({dec_tlu_flush_noredir_r, halt_taken, lsu_idle_any, ifu_miss_state_idle, dbg_tlu_halted, + resume_ack_ns, debug_halt_req_ns, debug_resume_req, trigger_hit_dmode_r, + dcsr_single_step_done, debug_halt_req, dec_tlu_wr_pause_r, dec_pause_state, + request_debug_mode_r, request_debug_mode_done, dcsr_single_step_running, dec_tlu_flush_pause_r, + dbg_halt_req_held_ns}), + .dout({dec_tlu_flush_noredir_r_d1, halt_taken_f, lsu_idle_any_f, ifu_miss_state_idle_f, dbg_tlu_halted_f, + dec_tlu_resume_ack , debug_halt_req_f, debug_resume_req_f_raw, trigger_hit_dmode_r_d1, + dcsr_single_step_done_f, debug_halt_req_d1, dec_tlu_wr_pause_r_d1, dec_pause_state_f, + request_debug_mode_r_d1, request_debug_mode_done_f, dcsr_single_step_running_f, dec_tlu_flush_pause_r_d1, + dbg_halt_req_held})); + + // MPC run collides with DBG halt, fix it here + assign debug_resume_req_f = debug_resume_req_f_raw & ~dbg_halt_req; + + assign dec_tlu_debug_stall = debug_halt_req_f; + assign dec_tlu_dbg_halted = dbg_tlu_halted_f; + assign dec_tlu_debug_mode = internal_dbg_halt_mode_f; + assign dec_tlu_pmu_fw_halted = pmu_fw_tlu_halted_f; + + // kill fetch redirection on flush if going to halt, or if there's a fence during db-halt + assign dec_tlu_flush_noredir_r = take_halt | (fence_i_r & internal_dbg_halt_mode) | dec_tlu_flush_pause_r | (i0_trigger_hit_r & trigger_hit_dmode_r) | take_ext_int_start; + + assign dec_tlu_flush_extint = take_ext_int_start; + + // 1 cycle after writing the PAUSE counter, flush with noredir to idle F1-D. + assign dec_tlu_flush_pause_r = dec_tlu_wr_pause_r_d1 & ~interrupt_valid_r & ~take_ext_int_start; + + // detect end of pause counter and rfpc + assign pause_expired_r = ~dec_pause_state & dec_pause_state_f & ~(ext_int_ready | ce_int_ready | timer_int_ready | soft_int_ready | int_timer0_int_hold_f | int_timer1_int_hold_f | nmi_int_detected | ext_int_freeze_d1) & ~interrupt_valid_r_d1 & ~debug_halt_req_f & ~pmu_fw_halt_req_f & ~halt_taken_f; + + assign dec_tlu_flush_leak_one_r = dec_tlu_flush_lower_r & dcsr[DCSR_STEP] & (dec_tlu_resume_ack | dcsr_single_step_running) & ~dec_tlu_flush_noredir_r; + assign dec_tlu_flush_err_r = dec_tlu_flush_lower_r & (ic_perr_r | iccm_sbecc_r); + + // If DM attempts to access an illegal CSR, send cmd_fail back + assign dec_dbg_cmd_done = dbg_cmd_done_ns; + assign dec_dbg_cmd_fail = illegal_r & dec_dbg_cmd_done; + + + //-------------------------------------------------------------------------------- + //-------------------------------------------------------------------------------- + // Triggers + // +localparam MTDATA1_DMODE = 9; +localparam MTDATA1_SEL = 7; +localparam MTDATA1_ACTION = 6; +localparam MTDATA1_CHAIN = 5; +localparam MTDATA1_MATCH = 4; +localparam MTDATA1_M_ENABLED = 3; +localparam MTDATA1_EXE = 2; +localparam MTDATA1_ST = 1; +localparam MTDATA1_LD = 0; + + // Prioritize trigger hits with other exceptions. + // + // Trigger should have highest priority except: + // - trigger is an execute-data and there is an inst_access exception (lsu triggers won't fire, inst. is nop'd by decode) + // - trigger is a store-data and there is a lsu_acc_exc or lsu_ma_exc. + assign trigger_execute[3:0] = {mtdata1_t3[MTDATA1_EXE], mtdata1_t2[MTDATA1_EXE], mtdata1_t1[MTDATA1_EXE], mtdata1_t0[MTDATA1_EXE]}; + assign trigger_data[3:0] = {mtdata1_t3[MTDATA1_SEL], mtdata1_t2[MTDATA1_SEL], mtdata1_t1[MTDATA1_SEL], mtdata1_t0[MTDATA1_SEL]}; + assign trigger_store[3:0] = {mtdata1_t3[MTDATA1_ST], mtdata1_t2[MTDATA1_ST], mtdata1_t1[MTDATA1_ST], mtdata1_t0[MTDATA1_ST]}; + + // MSTATUS[MIE] needs to be on to take triggers unless the action is trigger to debug mode. + assign trigger_enabled[3:0] = {(mtdata1_t3[MTDATA1_ACTION] | mstatus[MSTATUS_MIE]) & mtdata1_t3[MTDATA1_M_ENABLED], + (mtdata1_t2[MTDATA1_ACTION] | mstatus[MSTATUS_MIE]) & mtdata1_t2[MTDATA1_M_ENABLED], + (mtdata1_t1[MTDATA1_ACTION] | mstatus[MSTATUS_MIE]) & mtdata1_t1[MTDATA1_M_ENABLED], + (mtdata1_t0[MTDATA1_ACTION] | mstatus[MSTATUS_MIE]) & mtdata1_t0[MTDATA1_M_ENABLED]}; + + // iside exceptions are always in i0 + assign i0_iside_trigger_has_pri_r[3:0] = ~( (trigger_execute[3:0] & trigger_data[3:0] & {4{inst_acc_r_raw}}) | // exe-data with inst_acc + ({4{exu_i0_br_error_r | exu_i0_br_start_error_r}})); // branch error in i0 + + // lsu excs have to line up with their respective triggers since the lsu op can be i0 + assign i0_lsu_trigger_has_pri_r[3:0] = ~(trigger_store[3:0] & trigger_data[3:0] & {4{lsu_i0_exc_r_raw}}); + + // trigger hits have to be eval'd to cancel side effect lsu ops even though the pipe is already frozen + assign i0_trigger_eval_r = dec_tlu_i0_valid_r; + + assign i0trigger_qual_r[3:0] = {4{i0_trigger_eval_r}} & dec_tlu_packet_r.i0trigger[3:0] & i0_iside_trigger_has_pri_r[3:0] & i0_lsu_trigger_has_pri_r[3:0] & trigger_enabled[3:0]; + + // Qual trigger hits + assign i0_trigger_r[3:0] = ~{4{dec_tlu_flush_lower_wb | dec_tlu_dbg_halted}} & i0trigger_qual_r[3:0]; + + // chaining can mask raw trigger info + assign i0_trigger_chain_masked_r[3:0] = {i0_trigger_r[3] & (~mtdata1_t2[MTDATA1_CHAIN] | i0_trigger_r[2]), + i0_trigger_r[2] & (~mtdata1_t2[MTDATA1_CHAIN] | i0_trigger_r[3]), + i0_trigger_r[1] & (~mtdata1_t0[MTDATA1_CHAIN] | i0_trigger_r[0]), + i0_trigger_r[0] & (~mtdata1_t0[MTDATA1_CHAIN] | i0_trigger_r[1])}; + + // This is the highest priority by this point. + assign i0_trigger_hit_raw_r = |i0_trigger_chain_masked_r[3:0]; + + assign i0_trigger_hit_r = i0_trigger_hit_raw_r; + + // Actions include breakpoint, or dmode. Dmode is only possible if the DMODE bit is set. + // Otherwise, take a breakpoint. + assign trigger_action[3:0] = {mtdata1_t3[MTDATA1_ACTION] & mtdata1_t3[MTDATA1_DMODE], + mtdata1_t2[MTDATA1_ACTION] & mtdata1_t2[MTDATA1_DMODE] & ~mtdata1_t2[MTDATA1_CHAIN], + mtdata1_t1[MTDATA1_ACTION] & mtdata1_t1[MTDATA1_DMODE], + mtdata1_t0[MTDATA1_ACTION] & mtdata1_t0[MTDATA1_DMODE] & ~mtdata1_t0[MTDATA1_CHAIN]}; + + // this is needed to set the HIT bit in the triggers + assign update_hit_bit_r[3:0] = ({4{|i0_trigger_r[3:0] & ~rfpc_i0_r}} & {i0_trigger_chain_masked_r[3], i0_trigger_r[2], i0_trigger_chain_masked_r[1], i0_trigger_r[0]}); + + // action, 1 means dmode. Simultaneous triggers with at least 1 set for dmode force entire action to dmode. + assign i0_trigger_action_r = |(i0_trigger_chain_masked_r[3:0] & trigger_action[3:0]); + + assign trigger_hit_dmode_r = (i0_trigger_hit_r & i0_trigger_action_r); + + assign mepc_trigger_hit_sel_pc_r = i0_trigger_hit_r & ~trigger_hit_dmode_r; + + +// +// Debug end +//-------------------------------------------------------------------------------- + + //---------------------------------------------------------------------- + // + // Commit + // + //---------------------------------------------------------------------- + + + + //-------------------------------------------------------------------------------- + // External halt (not debug halt) + // - Fully interlocked handshake + // i_cpu_halt_req ____|--------------|_______________ + // core_empty ---------------|___________ + // o_cpu_halt_ack _________________|----|__________ + // o_cpu_halt_status _______________|---------------------|_________ + // i_cpu_run_req ______|----------|____ + // o_cpu_run_ack ____________|------|________ + // + + + // debug mode has priority, ignore PMU/FW halt/run while in debug mode + assign i_cpu_halt_req_sync_qual = i_cpu_halt_req_sync & ~dec_tlu_debug_mode & ~ext_int_freeze_d1; + assign i_cpu_run_req_sync_qual = i_cpu_run_req_sync & ~dec_tlu_debug_mode & pmu_fw_tlu_halted_f & ~ext_int_freeze_d1; + + rvdffie #(10) exthaltff (.*, .clk(free_l2clk), .din({i_cpu_halt_req_sync_qual, i_cpu_run_req_sync_qual, cpu_halt_status, + cpu_halt_ack, cpu_run_ack, internal_pmu_fw_halt_mode, + pmu_fw_halt_req_ns, pmu_fw_tlu_halted, + int_timer0_int_hold, int_timer1_int_hold}), + .dout({i_cpu_halt_req_d1, i_cpu_run_req_d1_raw, o_cpu_halt_status, + o_cpu_halt_ack, o_cpu_run_ack, internal_pmu_fw_halt_mode_f, + pmu_fw_halt_req_f, pmu_fw_tlu_halted_f, + int_timer0_int_hold_f, int_timer1_int_hold_f})); + + // only happens if we aren't in dgb_halt + assign ext_halt_pulse = i_cpu_halt_req_sync_qual & ~i_cpu_halt_req_d1; + + assign enter_pmu_fw_halt_req = ext_halt_pulse | fw_halt_req; + + assign pmu_fw_halt_req_ns = (enter_pmu_fw_halt_req | (pmu_fw_halt_req_f & ~pmu_fw_tlu_halted)) & ~debug_halt_req_f; + + assign internal_pmu_fw_halt_mode = pmu_fw_halt_req_ns | (internal_pmu_fw_halt_mode_f & ~i_cpu_run_req_d1 & ~debug_halt_req_f); + + // debug halt has priority + assign pmu_fw_tlu_halted = ((pmu_fw_halt_req_f & core_empty & halt_taken & ~enter_debug_halt_req) | (pmu_fw_tlu_halted_f & ~i_cpu_run_req_d1)) & ~debug_halt_req_f; + + assign cpu_halt_ack = (i_cpu_halt_req_d1 & pmu_fw_tlu_halted_f) | (o_cpu_halt_ack & i_cpu_halt_req_sync); + assign cpu_halt_status = (pmu_fw_tlu_halted_f & ~i_cpu_run_req_d1) | (o_cpu_halt_status & ~i_cpu_run_req_d1 & ~internal_dbg_halt_mode_f); + assign cpu_run_ack = (~pmu_fw_tlu_halted_f & i_cpu_run_req_sync) | (o_cpu_halt_status & i_cpu_run_req_d1_raw) | (o_cpu_run_ack & i_cpu_run_req_sync); + assign debug_mode_status = internal_dbg_halt_mode_f; + assign o_debug_mode_status = debug_mode_status; + +`ifdef RV_ASSERT_ON + assert_commit_while_halted: assert #0 (~(tlu_i0_commit_cmt & o_cpu_halt_status)) else $display("ERROR: Commiting while cpu_halt_status asserted!"); + assert_flush_while_fastint: assert #0 (~((take_ext_int_start_d1 | take_ext_int_start_d2) & dec_tlu_flush_lower_r)) else $display("ERROR: TLU Flushing inside fast interrupt procedure!"); +`endif + + // high priority interrupts can wakeup from external halt, so can unmasked timer interrupts + assign i_cpu_run_req_d1 = i_cpu_run_req_d1_raw | ((nmi_int_detected | timer_int_ready | soft_int_ready | int_timer0_int_hold_f | int_timer1_int_hold_f | (mhwakeup & mhwakeup_ready)) & o_cpu_halt_status & ~i_cpu_halt_req_d1); + + //-------------------------------------------------------------------------------- + //-------------------------------------------------------------------------------- + + assign lsu_single_ecc_error_r = lsu_single_ecc_error_incr; + + assign lsu_error_pkt_addr_r[31:0] = lsu_error_pkt_r.addr[31:0]; + + + assign lsu_exc_valid_r_raw = lsu_error_pkt_r.exc_valid & ~dec_tlu_flush_lower_wb; + + assign lsu_i0_exc_r_raw = lsu_error_pkt_r.exc_valid; + + assign lsu_i0_exc_r = lsu_i0_exc_r_raw & lsu_exc_valid_r_raw & ~i0_trigger_hit_r & ~rfpc_i0_r; + + assign lsu_exc_valid_r = lsu_i0_exc_r; + + assign lsu_exc_ma_r = lsu_i0_exc_r & ~lsu_error_pkt_r.exc_type; + assign lsu_exc_acc_r = lsu_i0_exc_r & lsu_error_pkt_r.exc_type; + assign lsu_exc_st_r = lsu_i0_exc_r & lsu_error_pkt_r.inst_type; + + // Single bit ECC errors on loads are RFNPC corrected, with the corrected data written to the GPR. + // LSU turns the load into a store and patches the data in the DCCM + assign lsu_i0_rfnpc_r = dec_tlu_i0_valid_r & ~i0_trigger_hit_r & + (~lsu_error_pkt_r.inst_type & lsu_error_pkt_r.single_ecc_error); + + // Final commit valids +`ifdef RV_USER_MODE + assign tlu_i0_commit_cmt = dec_tlu_i0_valid_r & + ~rfpc_i0_r & + ~lsu_i0_exc_r & + ~inst_acc_r & + ~dec_tlu_dbg_halted & + ~request_debug_mode_r_d1 & + ~i0_trigger_hit_r & + ~csr_acc_r; +`else + assign tlu_i0_commit_cmt = dec_tlu_i0_valid_r & + ~rfpc_i0_r & + ~lsu_i0_exc_r & + ~inst_acc_r & + ~dec_tlu_dbg_halted & + ~request_debug_mode_r_d1 & + ~i0_trigger_hit_r; +`endif + + // unified place to manage the killing of arch state writebacks +`ifdef RV_USER_MODE + assign tlu_i0_kill_writeb_r = rfpc_i0_r | lsu_i0_exc_r | inst_acc_r | (illegal_r & dec_tlu_dbg_halted) | i0_trigger_hit_r | csr_acc_r; +`else + assign tlu_i0_kill_writeb_r = rfpc_i0_r | lsu_i0_exc_r | inst_acc_r | (illegal_r & dec_tlu_dbg_halted) | i0_trigger_hit_r; +`endif + assign dec_tlu_i0_commit_cmt = tlu_i0_commit_cmt; + + + // refetch PC, microarch flush + // ic errors only in pipe0 + assign rfpc_i0_r = ((dec_tlu_i0_valid_r & ~tlu_flush_lower_r_d1 & (exu_i0_br_error_r | exu_i0_br_start_error_r)) | // inst commit with rfpc + ((ic_perr_r | iccm_sbecc_r) & ~ext_int_freeze_d1)) & // ic/iccm without inst commit + ~i0_trigger_hit_r & // unless there's a trigger. Err signal to ic/iccm will assert anyway to clear the error. + ~lsu_i0_rfnpc_r; + + // From the indication of a iccm single bit error until the first commit or flush, maintain a repair state. In the repair state, rfnpc i0 commits. + assign iccm_repair_state_ns = iccm_sbecc_r | (iccm_repair_state_d1 & ~dec_tlu_flush_lower_r); + + + localparam MCPC = 12'h7c2; + + // this is a flush of last resort, meaning only assert it if there is no other flush happening. + assign iccm_repair_state_rfnpc = tlu_i0_commit_cmt & iccm_repair_state_d1 & + ~(ebreak_r | ecall_r | mret_r | take_reset | illegal_r | (dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MCPC))); + +if(pt.BTB_ENABLE==1) begin + // go ahead and repair the branch error on other flushes, doesn't have to be the rfpc flush + assign dec_tlu_br0_error_r = exu_i0_br_error_r & dec_tlu_i0_valid_r & ~tlu_flush_lower_r_d1; + assign dec_tlu_br0_start_error_r = exu_i0_br_start_error_r & dec_tlu_i0_valid_r & ~tlu_flush_lower_r_d1; + assign dec_tlu_br0_v_r = exu_i0_br_valid_r & dec_tlu_i0_valid_r & ~tlu_flush_lower_r_d1 & (~exu_i0_br_mp_r | ~exu_pmu_i0_br_ataken); + + + assign dec_tlu_br0_r_pkt.hist[1:0] = exu_i0_br_hist_r[1:0]; + assign dec_tlu_br0_r_pkt.br_error = dec_tlu_br0_error_r; + assign dec_tlu_br0_r_pkt.br_start_error = dec_tlu_br0_start_error_r; + assign dec_tlu_br0_r_pkt.valid = dec_tlu_br0_v_r; + assign dec_tlu_br0_r_pkt.way = exu_i0_br_way_r; + assign dec_tlu_br0_r_pkt.middle = exu_i0_br_middle_r; +end // if (pt.BTB_ENABLE==1) +else begin + assign dec_tlu_br0_error_r = '0; + assign dec_tlu_br0_start_error_r = '0; + assign dec_tlu_br0_v_r = '0; + assign dec_tlu_br0_r_pkt = '0; +end // else: !if(pt.BTB_ENABLE==1) + + + // only expect these in pipe 0 + assign ebreak_r = (dec_tlu_packet_r.pmu_i0_itype == EBREAK) & dec_tlu_i0_valid_r & ~i0_trigger_hit_r & ~dcsr[DCSR_EBREAKM] & ~rfpc_i0_r; + assign ecall_r = (dec_tlu_packet_r.pmu_i0_itype == ECALL) & dec_tlu_i0_valid_r & ~i0_trigger_hit_r & ~rfpc_i0_r; +`ifdef RV_USER_MODE + assign illegal_r = (((dec_tlu_packet_r.pmu_i0_itype == MRET) & priv_mode) | ~dec_tlu_packet_r.legal) & dec_tlu_i0_valid_r & ~i0_trigger_hit_r & ~rfpc_i0_r; + assign mret_r = ( (dec_tlu_packet_r.pmu_i0_itype == MRET) & ~priv_mode ) & dec_tlu_i0_valid_r & ~i0_trigger_hit_r & ~rfpc_i0_r; +`else + assign illegal_r = ~dec_tlu_packet_r.legal & dec_tlu_i0_valid_r & ~i0_trigger_hit_r & ~rfpc_i0_r; + assign mret_r = (dec_tlu_packet_r.pmu_i0_itype == MRET) & dec_tlu_i0_valid_r & ~i0_trigger_hit_r & ~rfpc_i0_r; +`endif + // fence_i includes debug only fence_i's + assign fence_i_r = (dec_tlu_packet_r.fence_i & dec_tlu_i0_valid_r & ~i0_trigger_hit_r) & ~rfpc_i0_r; + assign ic_perr_r = ifu_ic_error_start_f & ~ext_int_freeze_d1 & (~internal_dbg_halt_mode_f | dcsr_single_step_running) & ~internal_pmu_fw_halt_mode_f; + assign iccm_sbecc_r = ifu_iccm_rd_ecc_single_err_f & ~ext_int_freeze_d1 & (~internal_dbg_halt_mode_f | dcsr_single_step_running) & ~internal_pmu_fw_halt_mode_f; + assign inst_acc_r_raw = dec_tlu_packet_r.icaf & dec_tlu_i0_valid_r; + assign inst_acc_r = inst_acc_r_raw & ~rfpc_i0_r & ~i0_trigger_hit_r; + assign inst_acc_second_r = dec_tlu_packet_r.icaf_second; + + assign ebreak_to_debug_mode_r = (dec_tlu_packet_r.pmu_i0_itype == EBREAK) & dec_tlu_i0_valid_r & ~i0_trigger_hit_r & dcsr[DCSR_EBREAKM] & ~rfpc_i0_r; + + rvdff #(1) exctype_wb_ff (.*, .clk(e4e5_clk), + .din (ebreak_to_debug_mode_r ), + .dout(ebreak_to_debug_mode_r_d1)); + + assign dec_tlu_fence_i_r = fence_i_r; + +`ifdef RV_USER_MODE + + // CSR access + // Address bits 9:8 == 2'b00 indicate unprivileged / user-level CSR + assign csr_wr_usr_r = ~|dec_csr_wraddr_r[9:8]; + assign csr_rd_usr_r = ~|dec_csr_rdaddr_r[9:8]; + + // CSR access error + // cycle and instret CSR unprivileged access is controller by bits in mcounteren CSR + logic csr_wr_acc_r; + logic csr_rd_acc_r; + + assign csr_wr_acc_r = csr_wr_usr_r & ( + ((dec_csr_wraddr_r[11:0] == CYCLEL) & mcounteren[MCOUNTEREN_CY]) | + ((dec_csr_wraddr_r[11:0] == CYCLEH) & mcounteren[MCOUNTEREN_CY]) | + ((dec_csr_wraddr_r[11:0] == INSTRETL) & mcounteren[MCOUNTEREN_IR]) | + ((dec_csr_wraddr_r[11:0] == INSTRETH) & mcounteren[MCOUNTEREN_IR]) | + ((dec_csr_wraddr_r[11:0] == HPMC3) & mcounteren[MCOUNTEREN_HPM3]) | + ((dec_csr_wraddr_r[11:0] == HPMC3H) & mcounteren[MCOUNTEREN_HPM3]) | + ((dec_csr_wraddr_r[11:0] == HPMC4) & mcounteren[MCOUNTEREN_HPM4]) | + ((dec_csr_wraddr_r[11:0] == HPMC4H) & mcounteren[MCOUNTEREN_HPM4]) | + ((dec_csr_wraddr_r[11:0] == HPMC5) & mcounteren[MCOUNTEREN_HPM5]) | + ((dec_csr_wraddr_r[11:0] == HPMC5H) & mcounteren[MCOUNTEREN_HPM5]) | + ((dec_csr_wraddr_r[11:0] == HPMC6) & mcounteren[MCOUNTEREN_HPM6]) | + ((dec_csr_wraddr_r[11:0] == HPMC6H) & mcounteren[MCOUNTEREN_HPM6])); + + assign csr_rd_acc_r = csr_rd_usr_r & ( + ((dec_csr_rdaddr_r[11:0] == CYCLEL) & mcounteren[MCOUNTEREN_CY]) | + ((dec_csr_rdaddr_r[11:0] == CYCLEH) & mcounteren[MCOUNTEREN_CY]) | + ((dec_csr_rdaddr_r[11:0] == INSTRETL) & mcounteren[MCOUNTEREN_IR]) | + ((dec_csr_rdaddr_r[11:0] == INSTRETH) & mcounteren[MCOUNTEREN_IR]) | + ((dec_csr_rdaddr_r[11:0] == HPMC3) & mcounteren[MCOUNTEREN_HPM3]) | + ((dec_csr_rdaddr_r[11:0] == HPMC3H) & mcounteren[MCOUNTEREN_HPM3]) | + ((dec_csr_rdaddr_r[11:0] == HPMC4) & mcounteren[MCOUNTEREN_HPM4]) | + ((dec_csr_rdaddr_r[11:0] == HPMC4H) & mcounteren[MCOUNTEREN_HPM4]) | + ((dec_csr_rdaddr_r[11:0] == HPMC5) & mcounteren[MCOUNTEREN_HPM5]) | + ((dec_csr_rdaddr_r[11:0] == HPMC5H) & mcounteren[MCOUNTEREN_HPM5]) | + ((dec_csr_rdaddr_r[11:0] == HPMC6) & mcounteren[MCOUNTEREN_HPM6]) | + ((dec_csr_rdaddr_r[11:0] == HPMC6H) & mcounteren[MCOUNTEREN_HPM6])); + + assign csr_acc_r = priv_mode & dec_tlu_i0_valid_r & ~i0_trigger_hit_r & ~rfpc_i0_r & ( + (dec_tlu_packet_r.pmu_i0_itype == CSRREAD) & ~csr_rd_acc_r | + (dec_tlu_packet_r.pmu_i0_itype == CSRWRITE) & ~csr_wr_acc_r | + (dec_tlu_packet_r.pmu_i0_itype == CSRRW) & ~csr_rd_acc_r & ~csr_wr_acc_r); + +`endif + + // + // Exceptions + // + // - MEPC <- PC + // - PC <- MTVEC, assert flush_lower + // - MCAUSE <- cause + // - MSCAUSE <- secondary cause + // - MTVAL <- + // - MPIE <- MIE + // - MIE <- 0 + // +`ifdef RV_USER_MODE + assign i0_exception_valid_r = (ebreak_r | ecall_r | illegal_r | inst_acc_r | csr_acc_r) & ~rfpc_i0_r & ~dec_tlu_dbg_halted; +`else + assign i0_exception_valid_r = (ebreak_r | ecall_r | illegal_r | inst_acc_r) & ~rfpc_i0_r & ~dec_tlu_dbg_halted; +`endif + + // Cause: + // + // 0x2 : illegal + // 0x3 : breakpoint + // 0x8 : Environment call U-mode (if U-mode is enabled) + // 0xb : Environment call M-mode + + + assign exc_cause_r[4:0] = ( ({5{take_ext_int}} & 5'h0b) | + ({5{take_timer_int}} & 5'h07) | + ({5{take_soft_int}} & 5'h03) | + ({5{take_int_timer0_int}} & 5'h1d) | + ({5{take_int_timer1_int}} & 5'h1c) | + ({5{take_ce_int}} & 5'h1e) | +`ifdef RV_USER_MODE + ({5{illegal_r| csr_acc_r}} & 5'h02) | + ({5{ecall_r & priv_mode}} & 5'h08) | + ({5{ecall_r & ~priv_mode}} & 5'h0b) | +`else + ({5{illegal_r}} & 5'h02) | + ({5{ecall_r}} & 5'h0b) | +`endif + ({5{inst_acc_r}} & 5'h01) | + ({5{ebreak_r | i0_trigger_hit_r}} & 5'h03) | + ({5{lsu_exc_ma_r & ~lsu_exc_st_r}} & 5'h04) | + ({5{lsu_exc_acc_r & ~lsu_exc_st_r}} & 5'h05) | + ({5{lsu_exc_ma_r & lsu_exc_st_r}} & 5'h06) | + ({5{lsu_exc_acc_r & lsu_exc_st_r}} & 5'h07) + ) & ~{5{take_nmi}}; + + // + // Interrupts + // + // exceptions that are committed have already happened and will cause an int at E4 to wait a cycle + // or more if MSTATUS[MIE] is cleared. + // + // -in priority order, highest to lowest + // -single cycle window where a csr write to MIE/MSTATUS is at E4 when the other conditions for externals are met. + // Hold off externals for a cycle to make sure we are consistent with what was just written + assign mhwakeup_ready = ~dec_csr_stall_int_ff & mstatus_mie_ns & mip[MIP_MEIP] & mie_ns[MIE_MEIE]; + assign ext_int_ready = ~dec_csr_stall_int_ff & mstatus_mie_ns & mip[MIP_MEIP] & mie_ns[MIE_MEIE] & ~ignore_ext_int_due_to_lsu_stall; + assign ce_int_ready = ~dec_csr_stall_int_ff & mstatus_mie_ns & mip[MIP_MCEIP] & mie_ns[MIE_MCEIE]; + assign soft_int_ready = ~dec_csr_stall_int_ff & mstatus_mie_ns & mip[MIP_MSIP] & mie_ns[MIE_MSIE]; + assign timer_int_ready = ~dec_csr_stall_int_ff & mstatus_mie_ns & mip[MIP_MTIP] & mie_ns[MIE_MTIE]; + + // MIP for internal timers pulses for 1 clock, resets the timer counter. Mip won't hold past the various stall conditions. + assign int_timer0_int_possible = mstatus_mie_ns & mie_ns[MIE_MITIE0]; + assign int_timer0_int_ready = mip[MIP_MITIP0] & int_timer0_int_possible; + assign int_timer1_int_possible = mstatus_mie_ns & mie_ns[MIE_MITIE1]; + assign int_timer1_int_ready = mip[MIP_MITIP1] & int_timer1_int_possible; + + // Internal timers pulse and reset. If core is PMU/FW halted, the pulse will cause an exit from halt, but won't stick around + // Make it sticky, also for 1 cycle stall conditions. + assign int_timer_stalled = dec_csr_stall_int_ff | synchronous_flush_r | exc_or_int_valid_r_d1 | mret_r; + + assign int_timer0_int_hold = (int_timer0_int_ready & (pmu_fw_tlu_halted_f | int_timer_stalled)) | (int_timer0_int_possible & int_timer0_int_hold_f & ~interrupt_valid_r & ~take_ext_int_start & ~internal_dbg_halt_mode_f); + assign int_timer1_int_hold = (int_timer1_int_ready & (pmu_fw_tlu_halted_f | int_timer_stalled)) | (int_timer1_int_possible & int_timer1_int_hold_f & ~interrupt_valid_r & ~take_ext_int_start & ~internal_dbg_halt_mode_f); + + + assign internal_dbg_halt_timers = internal_dbg_halt_mode_f & ~dcsr_single_step_running; + + + assign block_interrupts = ( (internal_dbg_halt_mode & (~dcsr_single_step_running | dec_tlu_i0_valid_r)) | // No ints in db-halt unless we are single stepping + internal_pmu_fw_halt_mode | i_cpu_halt_req_d1 |// No ints in PMU/FW halt. First we exit halt + take_nmi | // NMI is top priority + ebreak_to_debug_mode_r | // Heading to debug mode, hold off ints + synchronous_flush_r | // exception flush this cycle + exc_or_int_valid_r_d1 | // ext/int past cycle (need time for MIE to update) + mret_r | // mret in progress, for cases were ISR enables ints before mret + ext_int_freeze_d1 // Fast interrupt in progress (optional) + ); + + +if (pt.FAST_INTERRUPT_REDIRECT) begin + + + assign take_ext_int_start = ext_int_ready & ~block_interrupts; + + assign ext_int_freeze = take_ext_int_start | take_ext_int_start_d1 | take_ext_int_start_d2 | take_ext_int_start_d3; + assign take_ext_int = take_ext_int_start_d3 & ~|lsu_fir_error[1:0]; + assign fast_int_meicpct = csr_meicpct & dec_csr_any_unq_d; // MEICPCT becomes illegal if fast ints are enabled + + assign ignore_ext_int_due_to_lsu_stall = lsu_fastint_stall_any; +end +else begin + assign take_ext_int_start = 1'b0; + assign ext_int_freeze = 1'b0; + assign ext_int_freeze_d1 = 1'b0; + assign take_ext_int_start_d1 = 1'b0; + assign take_ext_int_start_d2 = 1'b0; + assign take_ext_int_start_d3 = 1'b0; + assign fast_int_meicpct = 1'b0; + assign ignore_ext_int_due_to_lsu_stall = 1'b0; + + assign take_ext_int = ext_int_ready & ~block_interrupts; +end + + assign take_ce_int = ce_int_ready & ~ext_int_ready & ~block_interrupts; + assign take_soft_int = soft_int_ready & ~ext_int_ready & ~ce_int_ready & ~block_interrupts; + assign take_timer_int = timer_int_ready & ~soft_int_ready & ~ext_int_ready & ~ce_int_ready & ~block_interrupts; + assign take_int_timer0_int = (int_timer0_int_ready | int_timer0_int_hold_f) & int_timer0_int_possible & ~dec_csr_stall_int_ff & + ~timer_int_ready & ~soft_int_ready & ~ext_int_ready & ~ce_int_ready & ~block_interrupts; + assign take_int_timer1_int = (int_timer1_int_ready | int_timer1_int_hold_f) & int_timer1_int_possible & ~dec_csr_stall_int_ff & + ~(int_timer0_int_ready | int_timer0_int_hold_f) & ~timer_int_ready & ~soft_int_ready & ~ext_int_ready & ~ce_int_ready & ~block_interrupts; + + assign take_reset = reset_delayed & mpc_reset_run_req; + assign take_nmi = nmi_int_detected & ~internal_pmu_fw_halt_mode & (~internal_dbg_halt_mode | (dcsr_single_step_running_f & dcsr[DCSR_STEPIE] & ~dec_tlu_i0_valid_r & ~dcsr_single_step_done_f)) & + ~synchronous_flush_r & ~mret_r & ~take_reset & ~ebreak_to_debug_mode_r & (~ext_int_freeze_d1 | (take_ext_int_start_d3 & |lsu_fir_error[1:0])); + + assign interrupt_valid_r = take_ext_int | take_timer_int | take_soft_int | take_nmi | take_ce_int | take_int_timer0_int | take_int_timer1_int; + + + // Compute interrupt path: + // If vectored async is set in mtvec, flush path for interrupts is MTVEC + (4 * CAUSE); + assign vectored_path[31:1] = {mtvec[30:1], 1'b0} + {25'b0, exc_cause_r[4:0], 1'b0}; + assign interrupt_path[31:1] = take_nmi ? nmi_vec[31:1] : ((mtvec[0] == 1'b1) ? vectored_path[31:1] : {mtvec[30:1], 1'b0}); + + assign sel_npc_r = lsu_i0_rfnpc_r | fence_i_r | iccm_repair_state_rfnpc | (i_cpu_run_req_d1 & ~interrupt_valid_r) | (rfpc_i0_r & ~dec_tlu_i0_valid_r); + assign sel_npc_resume = (i_cpu_run_req_d1 & pmu_fw_tlu_halted_f) | pause_expired_r; + + assign sel_fir_addr = take_ext_int_start_d3 & ~|lsu_fir_error[1:0]; + + assign synchronous_flush_r = i0_exception_valid_r | // exception + rfpc_i0_r | // rfpc + lsu_exc_valid_r | // lsu exception in either pipe 0 or pipe 1 + fence_i_r | // fence, a rfnpc + lsu_i0_rfnpc_r | // lsu dccm sb ecc + iccm_repair_state_rfnpc | // Iccm sb ecc + debug_resume_req_f | // resume from debug halt, fetch the dpc + sel_npc_resume | // resume from pmu/fw halt, or from pause and fetch the NPC + dec_tlu_wr_pause_r_d1 | // flush at start of pause + i0_trigger_hit_r; // trigger hit, ebreak or goto debug mode + + assign tlu_flush_lower_r = interrupt_valid_r | mret_r | synchronous_flush_r | take_halt | take_reset | take_ext_int_start; + + assign tlu_flush_path_r[31:1] = take_reset ? rst_vec[31:1] : + + ( ({31{sel_fir_addr}} & lsu_fir_addr[31:1]) | + ({31{~take_nmi & sel_npc_r}} & npc_r[31:1]) | + ({31{~take_nmi & rfpc_i0_r & dec_tlu_i0_valid_r & ~sel_npc_r}} & dec_tlu_i0_pc_r[31:1]) | + ({31{interrupt_valid_r & ~sel_fir_addr}} & interrupt_path[31:1]) | + ({31{(i0_exception_valid_r | lsu_exc_valid_r | + (i0_trigger_hit_r & ~trigger_hit_dmode_r)) & ~interrupt_valid_r & ~sel_fir_addr}} & {mtvec[30:1],1'b0}) | + ({31{~take_nmi & mret_r}} & mepc[31:1]) | + ({31{~take_nmi & debug_resume_req_f}} & dpc[31:1]) | + ({31{~take_nmi & sel_npc_resume}} & npc_r_d1[31:1]) ); + + rvdffpcie #(31) flush_lower_ff (.*, .en(tlu_flush_lower_r), + .din({tlu_flush_path_r[31:1]}), + .dout({tlu_flush_path_r_d1[31:1]})); + + assign dec_tlu_flush_lower_wb = tlu_flush_lower_r_d1; + assign dec_tlu_flush_lower_r = tlu_flush_lower_r; + assign dec_tlu_flush_path_r[31:1] = tlu_flush_path_r[31:1]; + + + // this is used to capture mepc, etc. + assign exc_or_int_valid_r = lsu_exc_valid_r | i0_exception_valid_r | interrupt_valid_r | (i0_trigger_hit_r & ~trigger_hit_dmode_r); + + + rvdffie #(12) excinfo_wb_ff (.*, + .din({interrupt_valid_r, i0_exception_valid_r, exc_or_int_valid_r, + exc_cause_r[4:0], tlu_i0_commit_cmt & ~illegal_r, i0_trigger_hit_r, + take_nmi, pause_expired_r }), + .dout({interrupt_valid_r_d1, i0_exception_valid_r_d1, exc_or_int_valid_r_d1, + exc_cause_wb[4:0], i0_valid_wb, trigger_hit_r_d1, + take_nmi_r_d1, pause_expired_wb})); +`ifdef RV_USER_MODE + + // + // Privilege mode + // + assign priv_mode_ns = (mret_r & mstatus[MSTATUS_MPP]) | + (exc_or_int_valid_r & 1'b0 ) | + ((~mret_r & ~exc_or_int_valid_r) & priv_mode); + + rvdff #(1) priv_ff ( + .clk (free_l2clk), + .rst_l (rst_l), + .din (priv_mode_ns), + .dout (priv_mode) + ); + +`endif + + //---------------------------------------------------------------------- + // + // CSRs + // + //---------------------------------------------------------------------- + + // ---------------------------------------------------------------------- + // MSTATUS (RW) + // [17] MPRV : Modify PRiVilege (if enabled in config) + // [12:11] MPP : Prior priv level, either 2'b11 (machine) or 2'b00 (user) + // [7] MPIE : Int enable previous [1] + // [3] MIE : Int enable [0] + + + //When executing a MRET instruction, supposing MPP holds the value 3, MIE + //is set to MPIE; the privilege mode is changed to 3; MPIE is set to 1; and MPP is set to 3 +`ifdef RV_USER_MODE + assign dec_csr_wen_r_mod = dec_csr_wen_r & ~i0_trigger_hit_r & ~rfpc_i0_r & ~csr_acc_r; +`else + assign dec_csr_wen_r_mod = dec_csr_wen_r & ~i0_trigger_hit_r & ~rfpc_i0_r; +`endif + + assign wr_mstatus_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MSTATUS); + + // set this even if we don't go to fwhalt due to debug halt. We committed the inst, so ... + assign set_mie_pmu_fw_halt = ~mpmc_b_ns[1] & fw_halt_req; + +`ifdef RV_USER_MODE + // mstatus[2] / mstatus_ns[2] actually stores inverse of the MPP field ! + assign mstatus_ns[3:0] = ( ({4{~wr_mstatus_r & exc_or_int_valid_r}} & {mstatus[MSTATUS_MPRV], priv_mode, mstatus[MSTATUS_MIE], 1'b0}) | + ({4{ wr_mstatus_r & exc_or_int_valid_r}} & {mstatus[MSTATUS_MPRV], priv_mode, dec_csr_wrdata_r[3], 1'b0}) | + ({4{mret_r & ~exc_or_int_valid_r}} & {mstatus[MSTATUS_MPRV] & ~mstatus[MSTATUS_MPP], 1'b1, 1'b1, mstatus[MSTATUS_MPIE]}) | + ({4{set_mie_pmu_fw_halt}} & {mstatus[3:2], mstatus[MSTATUS_MPIE], 1'b1}) | + ({4{wr_mstatus_r & ~exc_or_int_valid_r}} & {dec_csr_wrdata_r[17], ~dec_csr_wrdata_r[12], dec_csr_wrdata_r[7], dec_csr_wrdata_r[3]}) | + ({4{~wr_mstatus_r & ~exc_or_int_valid_r & ~mret_r & ~set_mie_pmu_fw_halt}} & mstatus[3:0]) ); + + // gate MIE if we are single stepping and DCSR[STEPIE] is off + // in user mode machine interrupts are always enabled as per RISC-V privilege spec (chapter 3.1.6.1). + assign mstatus_mie_ns = (priv_mode | mstatus[MSTATUS_MIE]) & (~dcsr_single_step_running_f | dcsr[DCSR_STEPIE]); + + // set effective privilege mode according to MPRV and MPP + assign priv_mode_eff = ( mstatus[MSTATUS_MPRV] & mstatus[MSTATUS_MPP]) | // MPRV=1, use MPP + (~mstatus[MSTATUS_MPRV] & priv_mode); // MPRV=0, use current operating mode + +`else + + assign mstatus_ns[1:0] = ( ({2{~wr_mstatus_r & exc_or_int_valid_r}} & {mstatus[MSTATUS_MIE], 1'b0}) | + ({2{ wr_mstatus_r & exc_or_int_valid_r}} & {dec_csr_wrdata_r[3], 1'b0}) | + ({2{mret_r & ~exc_or_int_valid_r}} & {1'b1, mstatus[MSTATUS_MPIE]}) | + ({2{set_mie_pmu_fw_halt}} & {mstatus[MSTATUS_MPIE], 1'b1}) | + ({2{wr_mstatus_r & ~exc_or_int_valid_r}} & {dec_csr_wrdata_r[7], dec_csr_wrdata_r[3]}) | + ({2{~wr_mstatus_r & ~exc_or_int_valid_r & ~mret_r & ~set_mie_pmu_fw_halt}} & mstatus[1:0]) ); + + assign mstatus_mie_ns = mstatus[MSTATUS_MIE] & (~dcsr_single_step_running_f | dcsr[DCSR_STEPIE]); + +`endif + + // ---------------------------------------------------------------------- + // MTVEC (RW) + // [31:2] BASE : Trap vector base address + // [1] - Reserved, not implemented, reads zero + // [0] MODE : 0 = Direct, 1 = Asyncs are vectored to BASE + (4 * CAUSE) + + assign wr_mtvec_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MTVEC); + assign mtvec_ns[30:0] = {dec_csr_wrdata_r[31:2], dec_csr_wrdata_r[0]} ; + rvdffe #(31) mtvec_ff (.*, .en(wr_mtvec_r), .din(mtvec_ns[30:0]), .dout(mtvec[30:0])); + + // ---------------------------------------------------------------------- + // MIP (RW) + // + // [30] MCEIP : (RO) M-Mode Correctable Error interrupt pending + // [29] MITIP0 : (RO) M-Mode Internal Timer0 interrupt pending + // [28] MITIP1 : (RO) M-Mode Internal Timer1 interrupt pending + // [11] MEIP : (RO) M-Mode external interrupt pending + // [7] MTIP : (RO) M-Mode timer interrupt pending + // [3] MSIP : (RO) M-Mode software interrupt pending + + assign ce_int = (mdccme_ce_req | miccme_ce_req | mice_ce_req); + + assign mip_ns[5:0] = {ce_int, dec_timer_t0_pulse, dec_timer_t1_pulse, mexintpend, timer_int_sync, soft_int_sync}; + + // ---------------------------------------------------------------------- + // MIE (RW) + // [30] MCEIE : (RO) M-Mode Correctable Error interrupt enable + // [29] MITIE0 : (RO) M-Mode Internal Timer0 interrupt enable + // [28] MITIE1 : (RO) M-Mode Internal Timer1 interrupt enable + // [11] MEIE : (RW) M-Mode external interrupt enable + // [7] MTIE : (RW) M-Mode timer interrupt enable + // [3] MSIE : (RW) M-Mode software interrupt enable + + assign wr_mie_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MIE); + assign mie_ns[5:0] = wr_mie_r ? {dec_csr_wrdata_r[30:28], dec_csr_wrdata_r[11], dec_csr_wrdata_r[7], dec_csr_wrdata_r[3]} : mie[5:0]; + rvdff #(6) mie_ff (.*, .clk(csr_wr_clk), .din(mie_ns[5:0]), .dout(mie[5:0])); + + + // ---------------------------------------------------------------------- + // MCYCLEL (RW) + // [31:0] : Lower Cycle count + + assign kill_ebreak_count_r = ebreak_to_debug_mode_r & dcsr[DCSR_STOPC]; + + assign wr_mcyclel_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MCYCLEL); + + assign mcyclel_cout_in = ~(kill_ebreak_count_r | (dec_tlu_dbg_halted & dcsr[DCSR_STOPC]) | dec_tlu_pmu_fw_halted | mcountinhibit[0]); + + // split for power + assign {mcyclela_cout, mcyclel_inc[7:0]} = mcyclel[7:0] + {7'b0, 1'b1}; + assign {mcyclel_cout, mcyclel_inc[31:8]} = mcyclel[31:8] + {23'b0, mcyclela_cout}; + + assign mcyclel_ns[31:0] = wr_mcyclel_r ? dec_csr_wrdata_r[31:0] : mcyclel_inc[31:0]; + + rvdffe #(24) mcyclel_bff (.*, .clk(free_l2clk), .en(wr_mcyclel_r | (mcyclela_cout & mcyclel_cout_in)), .din(mcyclel_ns[31:8]), .dout(mcyclel[31:8])); + rvdffe #(8) mcyclel_aff (.*, .clk(free_l2clk), .en(wr_mcyclel_r | mcyclel_cout_in), .din(mcyclel_ns[7:0]), .dout(mcyclel[7:0])); + + // ---------------------------------------------------------------------- + // MCYCLEH (RW) + // [63:32] : Higher Cycle count + // Chained with mcyclel. Note: mcyclel overflow due to a mcycleh write gets ignored. + + assign wr_mcycleh_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MCYCLEH); + + assign mcycleh_inc[31:0] = mcycleh[31:0] + {31'b0, mcyclel_cout_f}; + assign mcycleh_ns[31:0] = wr_mcycleh_r ? dec_csr_wrdata_r[31:0] : mcycleh_inc[31:0]; + + rvdffe #(32) mcycleh_ff (.*, .clk(free_l2clk), .en(wr_mcycleh_r | mcyclel_cout_f), .din(mcycleh_ns[31:0]), .dout(mcycleh[31:0])); + + // ---------------------------------------------------------------------- + // MINSTRETL (RW) + // [31:0] : Lower Instruction retired count + // From the spec "Some CSRs, such as the instructions retired counter, instret, may be modified as side effects + // of instruction execution. In these cases, if a CSR access instruction reads a CSR, it reads the + // value prior to the execution of the instruction. If a CSR access instruction writes a CSR, the + // update occurs after the execution of the instruction. In particular, a value written to instret by + // one instruction will be the value read by the following instruction (i.e., the increment of instret + // caused by the first instruction retiring happens before the write of the new value)." + + assign i0_valid_no_ebreak_ecall_r = dec_tlu_i0_valid_r & ~(ebreak_r | ecall_r | ebreak_to_debug_mode_r | illegal_r | mcountinhibit[2]); + + assign wr_minstretl_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MINSTRETL); + + assign {minstretl_couta, minstretl_inc[7:0]} = minstretl[7:0] + {7'b0,1'b1}; + assign {minstretl_cout, minstretl_inc[31:8]} = minstretl[31:8] + {23'b0, minstretl_couta}; + + assign minstret_enable = (i0_valid_no_ebreak_ecall_r & tlu_i0_commit_cmt) | wr_minstretl_r; + + assign minstretl_cout_ns = minstretl_cout & ~wr_minstreth_r & i0_valid_no_ebreak_ecall_r & ~dec_tlu_dbg_halted; + + assign minstretl_ns[31:0] = wr_minstretl_r ? dec_csr_wrdata_r[31:0] : minstretl_inc[31:0]; + rvdffe #(24) minstretl_bff (.*, .en(wr_minstretl_r | (minstretl_couta & minstret_enable)), + .din(minstretl_ns[31:8]), .dout(minstretl[31:8])); + rvdffe #(8) minstretl_aff (.*, .en(minstret_enable), + .din(minstretl_ns[7:0]), .dout(minstretl[7:0])); + + + assign minstretl_read[31:0] = minstretl[31:0]; + // ---------------------------------------------------------------------- + // MINSTRETH (RW) + // [63:32] : Higher Instret count + // Chained with minstretl. Note: minstretl overflow due to a minstreth write gets ignored. + + assign wr_minstreth_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MINSTRETH); + + assign minstreth_inc[31:0] = minstreth[31:0] + {31'b0, minstretl_cout_f}; + assign minstreth_ns[31:0] = wr_minstreth_r ? dec_csr_wrdata_r[31:0] : minstreth_inc[31:0]; + rvdffe #(32) minstreth_ff (.*, .en((minstret_enable_f & minstretl_cout_f) | wr_minstreth_r), .din(minstreth_ns[31:0]), .dout(minstreth[31:0])); + + assign minstreth_read[31:0] = minstreth_inc[31:0]; + + // ---------------------------------------------------------------------- + // MSCRATCH (RW) + // [31:0] : Scratch register + assign wr_mscratch_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MSCRATCH); + + rvdffe #(32) mscratch_ff (.*, .en(wr_mscratch_r), .din(dec_csr_wrdata_r[31:0]), .dout(mscratch[31:0])); + + // ---------------------------------------------------------------------- + // MEPC (RW) + // [31:1] : Exception PC + + // NPC + + assign sel_exu_npc_r = ~dec_tlu_dbg_halted & ~tlu_flush_lower_r_d1 & dec_tlu_i0_valid_r; + assign sel_flush_npc_r = ~dec_tlu_dbg_halted & tlu_flush_lower_r_d1 & ~dec_tlu_flush_noredir_r_d1; + assign sel_hold_npc_r = ~sel_exu_npc_r & ~sel_flush_npc_r; + + assign npc_r[31:1] = ( ({31{sel_exu_npc_r}} & exu_npc_r[31:1]) | + ({31{~mpc_reset_run_req & reset_delayed}} & rst_vec[31:1]) | // init to reset vector for mpc halt on reset case + ({31{(sel_flush_npc_r)}} & tlu_flush_path_r_d1[31:1]) | + ({31{(sel_hold_npc_r)}} & npc_r_d1[31:1]) ); + + rvdffpcie #(31) npwbc_ff (.*, .en(sel_exu_npc_r | sel_flush_npc_r | reset_delayed), .din(npc_r[31:1]), .dout(npc_r_d1[31:1])); + + // PC has to be captured for exceptions and interrupts. For MRET, we could execute it and then take an + // interrupt before the next instruction. + assign pc0_valid_r = ~dec_tlu_dbg_halted & dec_tlu_i0_valid_r; + + assign pc_r[31:1] = ( ({31{ pc0_valid_r}} & dec_tlu_i0_pc_r[31:1]) | + ({31{~pc0_valid_r}} & pc_r_d1[31:1])); + + rvdffpcie #(31) pwbc_ff (.*, .en(pc0_valid_r), .din(pc_r[31:1]), .dout(pc_r_d1[31:1])); + + assign wr_mepc_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MEPC); + + assign mepc_ns[31:1] = ( ({31{i0_exception_valid_r | lsu_exc_valid_r | mepc_trigger_hit_sel_pc_r}} & pc_r[31:1]) | + ({31{interrupt_valid_r}} & npc_r[31:1]) | + ({31{wr_mepc_r & ~exc_or_int_valid_r}} & dec_csr_wrdata_r[31:1]) | + ({31{~wr_mepc_r & ~exc_or_int_valid_r}} & mepc[31:1]) ); + + + rvdffe #(31) mepc_ff (.*, .en(i0_exception_valid_r | lsu_exc_valid_r | mepc_trigger_hit_sel_pc_r | interrupt_valid_r | wr_mepc_r), .din(mepc_ns[31:1]), .dout(mepc[31:1])); + + // ---------------------------------------------------------------------- + // MCAUSE (RW) + // [31:0] : Exception Cause + + assign wr_mcause_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MCAUSE); + assign mcause_sel_nmi_store = exc_or_int_valid_r & take_nmi & nmi_lsu_store_type; + assign mcause_sel_nmi_load = exc_or_int_valid_r & take_nmi & nmi_lsu_load_type; + assign mcause_sel_nmi_ext = exc_or_int_valid_r & take_nmi & take_ext_int_start_d3 & |lsu_fir_error[1:0] & ~nmi_int_detected_f; + // FIR value decoder + // 0 –no error + // 1 –uncorrectable ecc => f000_1000 + // 2 –dccm region access error => f000_1001 + // 3 –non dccm region access error => f000_1002 + assign mcause_fir_error_type[1:0] = {&lsu_fir_error[1:0], lsu_fir_error[1] & ~lsu_fir_error[0]}; + + assign mcause_ns[31:0] = ( ({32{mcause_sel_nmi_store}} & {32'hf000_0000}) | + ({32{mcause_sel_nmi_load}} & {32'hf000_0001}) | + ({32{mcause_sel_nmi_ext}} & {28'hf000_100, 2'b0, mcause_fir_error_type[1:0]}) | + ({32{exc_or_int_valid_r & ~take_nmi}} & {interrupt_valid_r, 26'b0, exc_cause_r[4:0]}) | + ({32{wr_mcause_r & ~exc_or_int_valid_r}} & dec_csr_wrdata_r[31:0]) | + ({32{~wr_mcause_r & ~exc_or_int_valid_r}} & mcause[31:0]) ); + + rvdffe #(32) mcause_ff (.*, .en(exc_or_int_valid_r | wr_mcause_r), .din(mcause_ns[31:0]), .dout(mcause[31:0])); + // ---------------------------------------------------------------------- + // MSCAUSE (RW) + // [2:0] : Secondary exception Cause + assign wr_mscause_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MSCAUSE); + + assign ifu_mscause[3:0] = (dec_tlu_packet_r.icaf_type[1:0] == 2'b00) ? 4'b1001 : + {2'b00 , dec_tlu_packet_r.icaf_type[1:0]} ; + + assign mscause_type[3:0] = ( ({4{lsu_i0_exc_r}} & lsu_error_pkt_r.mscause[3:0]) | + ({4{i0_trigger_hit_r}} & 4'b0001) | + ({4{ebreak_r}} & 4'b0010) | + ({4{inst_acc_r}} & ifu_mscause[3:0]) + ); + + assign mscause_ns[3:0] = ( ({4{exc_or_int_valid_r}} & mscause_type[3:0]) | + ({4{ wr_mscause_r & ~exc_or_int_valid_r}} & dec_csr_wrdata_r[3:0]) | + ({4{~wr_mscause_r & ~exc_or_int_valid_r}} & mscause[3:0]) + ); + + rvdff #(4) mscause_ff (.*, .clk(e4e5_int_clk), .din(mscause_ns[3:0]), .dout(mscause[3:0])); + // ---------------------------------------------------------------------- + // MTVAL (RW) + // [31:0] : Exception address if relevant + + assign wr_mtval_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MTVAL); + assign mtval_capture_pc_r = exc_or_int_valid_r & (ebreak_r | (inst_acc_r & ~inst_acc_second_r) | mepc_trigger_hit_sel_pc_r) & ~take_nmi; + assign mtval_capture_pc_plus2_r = exc_or_int_valid_r & (inst_acc_r & inst_acc_second_r) & ~take_nmi; + assign mtval_capture_inst_r = exc_or_int_valid_r & illegal_r & ~take_nmi; + assign mtval_capture_lsu_r = exc_or_int_valid_r & lsu_exc_valid_r & ~take_nmi; + assign mtval_clear_r = exc_or_int_valid_r & ~mtval_capture_pc_r & ~mtval_capture_inst_r & ~mtval_capture_lsu_r & ~mepc_trigger_hit_sel_pc_r; + + + assign mtval_ns[31:0] = (({32{mtval_capture_pc_r}} & {pc_r[31:1], 1'b0}) | + ({32{mtval_capture_pc_plus2_r}} & {pc_r[31:1] + 31'b1, 1'b0}) | + ({32{mtval_capture_inst_r}} & dec_illegal_inst[31:0]) | + ({32{mtval_capture_lsu_r}} & lsu_error_pkt_addr_r[31:0]) | + ({32{wr_mtval_r & ~interrupt_valid_r}} & dec_csr_wrdata_r[31:0]) | + ({32{~take_nmi & ~wr_mtval_r & ~mtval_capture_pc_r & ~mtval_capture_inst_r & ~mtval_clear_r & ~mtval_capture_lsu_r}} & mtval[31:0]) ); + + + rvdffe #(32) mtval_ff (.*, .en(tlu_flush_lower_r | wr_mtval_r), .din(mtval_ns[31:0]), .dout(mtval[31:0])); + + // ---------------------------------------------------------------------- + // MSECCFG + // [31:3] : Reserved, read 0x0 + // [2] : RLB + // [1] : MMWP + // [0] : MML + +`ifdef RV_USER_MODE + + localparam MSECCFG = 12'h747; + localparam MSECCFGH = 12'h757; + + // Detect if any PMP region is locked regardless of being enabled. This is + // necessary for mseccfg.RLB bit write behavior + logic [pt.PMP_ENTRIES-1:0] pmp_region_locked; + for (genvar r = 0; r < pt.PMP_ENTRIES; r++) begin : g_regions + assign pmp_region_locked[r] = pmp_pmpcfg[r].lock; + end + + logic pmp_any_region_locked; + assign pmp_any_region_locked = |pmp_region_locked; + + // mseccfg + assign wr_mseccfg_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MSECCFG); + rvdffs #(3) mseccfg_ff (.*, .clk(csr_wr_clk), .en(wr_mseccfg_r), .din(mseccfg_ns), .dout(mseccfg)); + + assign mseccfg_ns = { + pmp_any_region_locked ? + (dec_csr_wrdata_r[MSECCFG_RLB] & mseccfg[MSECCFG_RLB]) : // When any PMP region is locked this bit can only be cleared + dec_csr_wrdata_r[MSECCFG_RLB], // Otherwise regularly writeable + dec_csr_wrdata_r[MSECCFG_MMWP] | mseccfg[MSECCFG_MMWP], // Sticky bit, can only be set but not cleared + dec_csr_wrdata_r[MSECCFG_MML ] | mseccfg[MSECCFG_MML ] // Sticky bit, can only be set but never cleared + }; + +`endif + + // ---------------------------------------------------------------------- + // MCGC (RW) Clock gating control + // [31:10]: Reserved, reads 0x0 + // [9] : picio_clk_override + // [7] : dec_clk_override + // [6] : Unused + // [5] : ifu_clk_override + // [4] : lsu_clk_override + // [3] : bus_clk_override + // [2] : pic_clk_override + // [1] : dccm_clk_override + // [0] : icm_clk_override + // + assign wr_mcgc_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MCGC); + + assign mcgc_ns[9:0] = wr_mcgc_r ? {~dec_csr_wrdata_r[9], dec_csr_wrdata_r[8:0]} : mcgc_int[9:0]; + rvdffe #(10) mcgc_ff (.*, .en(wr_mcgc_r), .din(mcgc_ns[9:0]), .dout(mcgc_int[9:0])); + + assign mcgc[9:0] = {~mcgc_int[9], mcgc_int[8:0]}; + + assign dec_tlu_picio_clk_override= mcgc[9]; + assign dec_tlu_misc_clk_override = mcgc[8]; + assign dec_tlu_dec_clk_override = mcgc[7]; + //sign dec_tlu_exu_clk_override = mcgc[6]; + assign dec_tlu_ifu_clk_override = mcgc[5]; + assign dec_tlu_lsu_clk_override = mcgc[4]; + assign dec_tlu_bus_clk_override = mcgc[3]; + assign dec_tlu_pic_clk_override = mcgc[2]; + assign dec_tlu_dccm_clk_override = mcgc[1]; + assign dec_tlu_icm_clk_override = mcgc[0]; + + // ---------------------------------------------------------------------- + // MFDC (RW) Feature Disable Control + // [31:19] : Reserved, reads 0x0 + // [18:16] : DMA QoS Prty + // [15:13] : Reserved, reads 0x0 + // [12] : Disable trace + // [11] : Disable external load forwarding + // [10] : Disable dual issue + // [9] : Disable pic multiple ints + // [8] : Disable core ecc + // [7] : Disable secondary alu?s + // [6] : Unused, 0x0 + // [5] : Disable non-blocking loads/divides + // [4] : Disable fast divide + // [3] : Disable branch prediction and return stack + // [2] : Disable write buffer coalescing + // [1] : Disable load misses that bypass the write buffer + // [0] : Disable pipelining - Enable single instruction execution + // + + assign wr_mfdc_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MFDC); + + rvdffe #(16) mfdc_ff (.*, .en(wr_mfdc_r), .din({mfdc_ns[15:0]}), .dout(mfdc_int[15:0])); + + // flip poweron value of bit 6 for AXI build + if(pt.BUILD_AXI4==1) begin : axi4 + // flip poweron valid of bit 12 + assign mfdc_ns[15:0] = {~dec_csr_wrdata_r[18:16], dec_csr_wrdata_r[12], dec_csr_wrdata_r[11:7], ~dec_csr_wrdata_r[6], dec_csr_wrdata_r[5:0]}; + assign mfdc[18:0] = {~mfdc_int[15:13], 3'b0, mfdc_int[12], mfdc_int[11:7], ~mfdc_int[6], mfdc_int[5:0]}; + end + else begin + // flip poweron valid of bit 12 + assign mfdc_ns[15:0] = {~dec_csr_wrdata_r[18:16],dec_csr_wrdata_r[12:0]}; + assign mfdc[18:0] = {~mfdc_int[15:13], 3'b0, mfdc_int[12:0]}; + end + + + assign dec_tlu_dma_qos_prty[2:0] = mfdc[18:16]; + assign dec_tlu_trace_disable = mfdc[12]; + assign dec_tlu_external_ldfwd_disable = mfdc[11]; + assign dec_tlu_core_ecc_disable = mfdc[8]; + assign dec_tlu_sideeffect_posted_disable = mfdc[6]; + assign dec_tlu_bpred_disable = mfdc[3]; + assign dec_tlu_wb_coalescing_disable = mfdc[2]; + assign dec_tlu_pipelining_disable = mfdc[0]; + + // ---------------------------------------------------------------------- + // MCPC (RW) Pause counter + // [31:0] : Reads 0x0, decs in the wb register in decode_ctl + + assign dec_tlu_wr_pause_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MCPC) & ~interrupt_valid_r & ~take_ext_int_start; + + // ---------------------------------------------------------------------- + // MRAC (RW) + // [31:0] : Region Access Control Register, 16 regions, {side_effect, cachable} pairs + + assign wr_mrac_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MRAC); + + // prevent pairs of 0x11, side_effect and cacheable + assign mrac_in[31:0] = {dec_csr_wrdata_r[31], dec_csr_wrdata_r[30] & ~dec_csr_wrdata_r[31], + dec_csr_wrdata_r[29], dec_csr_wrdata_r[28] & ~dec_csr_wrdata_r[29], + dec_csr_wrdata_r[27], dec_csr_wrdata_r[26] & ~dec_csr_wrdata_r[27], + dec_csr_wrdata_r[25], dec_csr_wrdata_r[24] & ~dec_csr_wrdata_r[25], + dec_csr_wrdata_r[23], dec_csr_wrdata_r[22] & ~dec_csr_wrdata_r[23], + dec_csr_wrdata_r[21], dec_csr_wrdata_r[20] & ~dec_csr_wrdata_r[21], + dec_csr_wrdata_r[19], dec_csr_wrdata_r[18] & ~dec_csr_wrdata_r[19], + dec_csr_wrdata_r[17], dec_csr_wrdata_r[16] & ~dec_csr_wrdata_r[17], + dec_csr_wrdata_r[15], dec_csr_wrdata_r[14] & ~dec_csr_wrdata_r[15], + dec_csr_wrdata_r[13], dec_csr_wrdata_r[12] & ~dec_csr_wrdata_r[13], + dec_csr_wrdata_r[11], dec_csr_wrdata_r[10] & ~dec_csr_wrdata_r[11], + dec_csr_wrdata_r[9], dec_csr_wrdata_r[8] & ~dec_csr_wrdata_r[9], + dec_csr_wrdata_r[7], dec_csr_wrdata_r[6] & ~dec_csr_wrdata_r[7], + dec_csr_wrdata_r[5], dec_csr_wrdata_r[4] & ~dec_csr_wrdata_r[5], + dec_csr_wrdata_r[3], dec_csr_wrdata_r[2] & ~dec_csr_wrdata_r[3], + dec_csr_wrdata_r[1], dec_csr_wrdata_r[0] & ~dec_csr_wrdata_r[1]}; + + rvdffe #(32) mrac_ff (.*, .en(wr_mrac_r), .din(mrac_in[31:0]), .dout(mrac[31:0])); + + // drive to LSU/IFU + assign dec_tlu_mrac_ff[31:0] = mrac[31:0]; + + // ---------------------------------------------------------------------- + // MDEAU (WAR0) + // [31:0] : Dbus Error Address Unlock register + // + + assign wr_mdeau_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MDEAU); + + + // ---------------------------------------------------------------------- + // MDSEAC (R) + // [31:0] : Dbus Store Error Address Capture register + // + + // only capture error bus if the MDSEAC reg is not locked + assign mdseac_locked_ns = mdseac_en | (mdseac_locked_f & ~wr_mdeau_r); + + assign mdseac_en = (lsu_imprecise_error_store_any | lsu_imprecise_error_load_any) & ~nmi_int_detected_f & ~mdseac_locked_f; + + rvdffe #(32) mdseac_ff (.*, .en(mdseac_en), .din(lsu_imprecise_error_addr_any[31:0]), .dout(mdseac[31:0])); + + // ---------------------------------------------------------------------- + // MPMC (R0W1) + // [0] : FW halt + // [1] : Set MSTATUS[MIE] on halt + + assign wr_mpmc_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MPMC); + + // allow the cycle of the dbg halt flush that contains the wr_mpmc_r to + // set the mstatus bit potentially, use delayed version of internal dbg halt. + assign fw_halt_req = wr_mpmc_r & dec_csr_wrdata_r[0] & ~internal_dbg_halt_mode_f2 & ~ext_int_freeze_d1; + + assign fw_halted_ns = (fw_halt_req | fw_halted) & ~set_mie_pmu_fw_halt; + assign mpmc_b_ns[1] = wr_mpmc_r ? ~dec_csr_wrdata_r[1] : ~mpmc[1]; + rvdff #(1) mpmc_ff (.*, .clk(csr_wr_clk), .din(mpmc_b_ns[1]), .dout(mpmc_b[1])); + assign mpmc[1] = ~mpmc_b[1]; + + // ---------------------------------------------------------------------- + // MICECT (I-Cache error counter/threshold) + // [31:27] : Icache parity error threshold + // [26:0] : Icache parity error count + + assign csr_sat[31:27] = (dec_csr_wrdata_r[31:27] > 5'd26) ? 5'd26 : dec_csr_wrdata_r[31:27]; + + assign wr_micect_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MICECT); + assign micect_inc[26:0] = micect[26:0] + {26'b0, ic_perr_r}; + assign micect_ns = wr_micect_r ? {csr_sat[31:27], dec_csr_wrdata_r[26:0]} : {micect[31:27], micect_inc[26:0]}; + + rvdffe #(32) micect_ff (.*, .en(wr_micect_r | ic_perr_r), .din(micect_ns[31:0]), .dout(micect[31:0])); + + assign mice_ce_req = |({32'hffffffff << micect[31:27]} & {5'b0, micect[26:0]}); + + // ---------------------------------------------------------------------- + // MICCMECT (ICCM error counter/threshold) + // [31:27] : ICCM parity error threshold + // [26:0] : ICCM parity error count + + assign wr_miccmect_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MICCMECT); + assign miccmect_inc[26:0] = miccmect[26:0] + {26'b0, iccm_sbecc_r | iccm_dma_sb_error}; + assign miccmect_ns = wr_miccmect_r ? {csr_sat[31:27], dec_csr_wrdata_r[26:0]} : {miccmect[31:27], miccmect_inc[26:0]}; + + rvdffe #(32) miccmect_ff (.*, .clk(free_l2clk), .en(wr_miccmect_r | iccm_sbecc_r | iccm_dma_sb_error), .din(miccmect_ns[31:0]), .dout(miccmect[31:0])); + + assign miccme_ce_req = |({32'hffffffff << miccmect[31:27]} & {5'b0, miccmect[26:0]}); + + // ---------------------------------------------------------------------- + // MDCCMECT (DCCM error counter/threshold) + // [31:27] : DCCM parity error threshold + // [26:0] : DCCM parity error count + + assign wr_mdccmect_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MDCCMECT); + assign mdccmect_inc[26:0] = mdccmect[26:0] + {26'b0, lsu_single_ecc_error_r_d1}; + assign mdccmect_ns = wr_mdccmect_r ? {csr_sat[31:27], dec_csr_wrdata_r[26:0]} : {mdccmect[31:27], mdccmect_inc[26:0]}; + + rvdffe #(32) mdccmect_ff (.*, .clk(free_l2clk), .en(wr_mdccmect_r | lsu_single_ecc_error_r_d1), .din(mdccmect_ns[31:0]), .dout(mdccmect[31:0])); + + assign mdccme_ce_req = |({32'hffffffff << mdccmect[31:27]} & {5'b0, mdccmect[26:0]}); + + + // ---------------------------------------------------------------------- + // MFDHT (Force Debug Halt Threshold) + // [5:1] : Halt timeout threshold (power of 2) + // [0] : Halt timeout enabled + + assign wr_mfdht_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MFDHT); + + assign mfdht_ns[5:0] = wr_mfdht_r ? dec_csr_wrdata_r[5:0] : mfdht[5:0]; + + rvdffs #(6) mfdht_ff (.*, .clk(csr_wr_clk), .en(wr_mfdht_r), .din(mfdht_ns[5:0]), .dout(mfdht[5:0])); + + // ---------------------------------------------------------------------- + // MFDHS(RW) + // [1] : LSU operation pending when debug halt threshold reached + // [0] : IFU operation pending when debug halt threshold reached + + assign wr_mfdhs_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MFDHS); + + assign mfdhs_ns[1:0] = wr_mfdhs_r ? dec_csr_wrdata_r[1:0] : ((dbg_tlu_halted & ~dbg_tlu_halted_f) ? {~lsu_idle_any_f, ~ifu_miss_state_idle_f} : mfdhs[1:0]); + + rvdffs #(2) mfdhs_ff (.*, .clk(free_clk), .en(wr_mfdhs_r | dbg_tlu_halted), .din(mfdhs_ns[1:0]), .dout(mfdhs[1:0])); + + assign force_halt_ctr[31:0] = debug_halt_req_f ? (force_halt_ctr_f[31:0] + 32'b1) : (dbg_tlu_halted_f ? 32'b0 : force_halt_ctr_f[31:0]); + + rvdffe #(32) forcehaltctr_ff (.*, .en(mfdht[0]), .din(force_halt_ctr[31:0]), .dout(force_halt_ctr_f[31:0])); + + assign force_halt = mfdht[0] & |(force_halt_ctr_f[31:0] & (32'hffffffff << mfdht[5:1])); + + + // ---------------------------------------------------------------------- + // MEIVT (External Interrupt Vector Table (R/W)) + // [31:10]: Base address (R/W) + // [9:0] : Reserved, reads 0x0 + assign wr_meivt_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MEIVT); + + rvdffe #(22) meivt_ff (.*, .en(wr_meivt_r), .din(dec_csr_wrdata_r[31:10]), .dout(meivt[31:10])); + + + // ---------------------------------------------------------------------- + // MEIHAP (External Interrupt Handler Access Pointer (R)) + // [31:10]: Base address (R/W) + // [9:2] : ClaimID (R) + // [1:0] : Reserved, 0x0 + + assign wr_meihap_r = wr_meicpct_r; + + rvdffe #(8) meihap_ff (.*, .en(wr_meihap_r), .din(pic_claimid[7:0]), .dout(meihap[9:2])); + + assign dec_tlu_meihap[31:2] = {meivt[31:10], meihap[9:2]}; + + // ---------------------------------------------------------------------- + // MEICURPL (R/W) + // [31:4] : Reserved (read 0x0) + // [3:0] : CURRPRI - Priority level of current interrupt service routine (R/W) + assign wr_meicurpl_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MEICURPL); + assign meicurpl_ns[3:0] = wr_meicurpl_r ? dec_csr_wrdata_r[3:0] : meicurpl[3:0]; + + rvdff #(4) meicurpl_ff (.*, .clk(csr_wr_clk), .din(meicurpl_ns[3:0]), .dout(meicurpl[3:0])); + + // PIC needs this reg + assign dec_tlu_meicurpl[3:0] = meicurpl[3:0]; + + + // ---------------------------------------------------------------------- + // MEICIDPL (R/W) + // [31:4] : Reserved (read 0x0) + // [3:0] : External Interrupt Claim ID's Priority Level Register + + assign wr_meicidpl_r = (dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MEICIDPL)) | take_ext_int_start; + + assign meicidpl_ns[3:0] = wr_meicpct_r ? pic_pl[3:0] : (wr_meicidpl_r ? dec_csr_wrdata_r[3:0] : meicidpl[3:0]); + + + // ---------------------------------------------------------------------- + // MEICPCT (Capture CLAIMID in MEIHAP and PL in MEICIDPL + // [31:1] : Reserved (read 0x0) + // [0] : Capture (W1, Read 0) + assign wr_meicpct_r = (dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MEICPCT)) | take_ext_int_start; + + // ---------------------------------------------------------------------- + // MEIPT (External Interrupt Priority Threshold) + // [31:4] : Reserved (read 0x0) + // [3:0] : PRITHRESH + + assign wr_meipt_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MEIPT); + assign meipt_ns[3:0] = wr_meipt_r ? dec_csr_wrdata_r[3:0] : meipt[3:0]; + + rvdff #(4) meipt_ff (.*, .clk(csr_wr_clk), .din(meipt_ns[3:0]), .dout(meipt[3:0])); + + // to PIC + assign dec_tlu_meipt[3:0] = meipt[3:0]; + // ---------------------------------------------------------------------- + // DCSR (R/W) (Only accessible in debug mode) + // [31:28] : xdebugver (hard coded to 0x4) RO + // [27:16] : 0x0, reserved + // [15] : ebreakm + // [14] : 0x0, reserved + // [13] : ebreaks (0x0 for this core) + // [12] : ebreaku (0x0 for this core) + // [11] : stepie + // [10] : stopcount + // [9] : 0x0 //stoptime + // [8:6] : cause (RO) + // [5:4] : 0x0, reserved + // [3] : nmip + // [2] : step + // [1:0] : prv (0x3 for this core) + // + + // RV has clarified that 'priority 4' in the spec means top priority. + // 4. single step. 3. Debugger request. 2. Ebreak. 1. Trigger. + + // RV debug spec indicates a cause priority change for trigger hits during single step. + assign trigger_hit_for_dscr_cause_r_d1 = trigger_hit_dmode_r_d1 | (trigger_hit_r_d1 & dcsr_single_step_done_f); + + assign dcsr_cause[8:6] = ( ({3{dcsr_single_step_done_f & ~ebreak_to_debug_mode_r_d1 & ~trigger_hit_for_dscr_cause_r_d1 & ~debug_halt_req}} & 3'b100) | + ({3{debug_halt_req & ~ebreak_to_debug_mode_r_d1 & ~trigger_hit_for_dscr_cause_r_d1}} & 3'b011) | + ({3{ebreak_to_debug_mode_r_d1 & ~trigger_hit_for_dscr_cause_r_d1}} & 3'b001) | + ({3{trigger_hit_for_dscr_cause_r_d1}} & 3'b010)); + + assign wr_dcsr_r = allow_dbg_halt_csr_write & dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == DCSR); + + + + // Multiple halt enter requests can happen before we are halted. + // We have to continue to upgrade based on dcsr_cause priority but we can't downgrade. + assign dcsr_cause_upgradeable = internal_dbg_halt_mode_f & (dcsr[8:6] == 3'b011); + assign enter_debug_halt_req_le = enter_debug_halt_req & (~dbg_tlu_halted | dcsr_cause_upgradeable); + + assign nmi_in_debug_mode = nmi_int_detected_f & internal_dbg_halt_mode_f; + assign dcsr_ns[15:2] = enter_debug_halt_req_le ? {dcsr[15:9], dcsr_cause[8:6], dcsr[5:2]} : + (wr_dcsr_r ? {dec_csr_wrdata_r[15], 3'b0, dec_csr_wrdata_r[11:10], 1'b0, dcsr[8:6], 2'b00, nmi_in_debug_mode | dcsr[3], dec_csr_wrdata_r[2]} : + {dcsr[15:4], nmi_in_debug_mode, dcsr[2]}); + + rvdffe #(14) dcsr_ff (.*, .clk(free_l2clk), .en(enter_debug_halt_req_le | wr_dcsr_r | internal_dbg_halt_mode | take_nmi), .din(dcsr_ns[15:2]), .dout(dcsr[15:2])); + + // ---------------------------------------------------------------------- + // DPC (R/W) (Only accessible in debug mode) + // [31:0] : Debug PC + + assign wr_dpc_r = allow_dbg_halt_csr_write & dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == DPC); + assign dpc_capture_npc = dbg_tlu_halted & ~dbg_tlu_halted_f & ~request_debug_mode_done; + assign dpc_capture_pc = request_debug_mode_r; + + assign dpc_ns[31:1] = ( ({31{~dpc_capture_pc & ~dpc_capture_npc & wr_dpc_r}} & dec_csr_wrdata_r[31:1]) | + ({31{dpc_capture_pc}} & pc_r[31:1]) | + ({31{~dpc_capture_pc & dpc_capture_npc}} & npc_r[31:1]) ); + + rvdffe #(31) dpc_ff (.*, .en(wr_dpc_r | dpc_capture_pc | dpc_capture_npc), .din(dpc_ns[31:1]), .dout(dpc[31:1])); + + // ---------------------------------------------------------------------- + // DICAWICS (R/W) (Only accessible in debug mode) + // [31:25] : Reserved + // [24] : Array select, 0 is data, 1 is tag + // [23:22] : Reserved + // [21:20] : Way select + // [19:17] : Reserved + // [16:3] : Index + // [2:0] : Reserved + + assign dicawics_ns[16:0] = {dec_csr_wrdata_r[24], dec_csr_wrdata_r[21:20], dec_csr_wrdata_r[16:3]}; + assign wr_dicawics_r = allow_dbg_halt_csr_write & dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == DICAWICS); + + rvdffe #(17) dicawics_ff (.*, .en(wr_dicawics_r), .din(dicawics_ns[16:0]), .dout(dicawics[16:0])); + + // ---------------------------------------------------------------------- + // DICAD0 (R/W) (Only accessible in debug mode) + // + // If dicawics[array] is 0 + // [31:0] : inst data + // + // If dicawics[array] is 1 + // [31:16] : Tag + // [15:7] : Reserved + // [6:4] : LRU + // [3:1] : Reserved + // [0] : Valid + + assign dicad0_ns[31:0] = wr_dicad0_r ? dec_csr_wrdata_r[31:0] : ifu_ic_debug_rd_data[31:0]; + + assign wr_dicad0_r = allow_dbg_halt_csr_write & dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == DICAD0); + + rvdffe #(32) dicad0_ff (.*, .en(wr_dicad0_r | ifu_ic_debug_rd_data_valid), .din(dicad0_ns[31:0]), .dout(dicad0[31:0])); + + // ---------------------------------------------------------------------- + // DICAD0H (R/W) (Only accessible in debug mode) + // + // If dicawics[array] is 0 + // [63:32] : inst data + // + + assign dicad0h_ns[31:0] = wr_dicad0h_r ? dec_csr_wrdata_r[31:0] : ifu_ic_debug_rd_data[63:32]; + + assign wr_dicad0h_r = allow_dbg_halt_csr_write & dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == DICAD0H); + + rvdffe #(32) dicad0h_ff (.*, .en(wr_dicad0h_r | ifu_ic_debug_rd_data_valid), .din(dicad0h_ns[31:0]), .dout(dicad0h[31:0])); + + +if (pt.ICACHE_ECC == 1) begin : genblock1 + // ---------------------------------------------------------------------- + // DICAD1 (R/W) (Only accessible in debug mode) + // [6:0] : ECC + localparam DICAD1 = 12'h7ca; + + assign dicad1_ns[6:0] = wr_dicad1_r ? dec_csr_wrdata_r[6:0] : ifu_ic_debug_rd_data[70:64]; + + assign wr_dicad1_r = allow_dbg_halt_csr_write & dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == DICAD1); + + rvdffe #(.WIDTH(7), .OVERRIDE(1)) dicad1_ff (.*, .en(wr_dicad1_r | ifu_ic_debug_rd_data_valid), .din(dicad1_ns[6:0]), .dout(dicad1_raw[6:0])); + + assign dicad1[31:0] = {25'b0, dicad1_raw[6:0]}; + +end +else begin : genblock1 + // ---------------------------------------------------------------------- + // DICAD1 (R/W) (Only accessible in debug mode) + // [3:0] : Parity + localparam DICAD1 = 12'h7ca; + + assign dicad1_ns[3:0] = wr_dicad1_r ? dec_csr_wrdata_r[3:0] : ifu_ic_debug_rd_data[67:64]; + + assign wr_dicad1_r = allow_dbg_halt_csr_write & dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == DICAD1); + + rvdffs #(4) dicad1_ff (.*, .clk(free_clk), .en(wr_dicad1_r | ifu_ic_debug_rd_data_valid), .din(dicad1_ns[3:0]), .dout(dicad1_raw[3:0])); + + assign dicad1[31:0] = {28'b0, dicad1_raw[3:0]}; +end + // ---------------------------------------------------------------------- + // DICAGO (R/W) (Only accessible in debug mode) + // [0] : Go + +if (pt.ICACHE_ECC == 1) + assign dec_tlu_ic_diag_pkt.icache_wrdata[70:0] = { dicad1[6:0], dicad0h[31:0], dicad0[31:0]}; +else + assign dec_tlu_ic_diag_pkt.icache_wrdata[70:0] = {3'b0, dicad1[3:0], dicad0h[31:0], dicad0[31:0]}; + + + assign dec_tlu_ic_diag_pkt.icache_dicawics[16:0] = dicawics[16:0]; + + assign icache_rd_valid = allow_dbg_halt_csr_write & dec_csr_any_unq_d & dec_i0_decode_d & ~dec_csr_wen_unq_d & (dec_csr_rdaddr_d[11:0] == DICAGO); + assign icache_wr_valid = allow_dbg_halt_csr_write & dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == DICAGO); + + + assign dec_tlu_ic_diag_pkt.icache_rd_valid = icache_rd_valid_f; + assign dec_tlu_ic_diag_pkt.icache_wr_valid = icache_wr_valid_f; + + // ---------------------------------------------------------------------- + // MTSEL (R/W) + // [1:0] : Trigger select : 00, 01, 10 are data/address triggers. 11 is inst count + + assign wr_mtsel_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MTSEL); + assign mtsel_ns[1:0] = wr_mtsel_r ? {dec_csr_wrdata_r[1:0]} : mtsel[1:0]; + + rvdff #(2) mtsel_ff (.*, .clk(csr_wr_clk), .din(mtsel_ns[1:0]), .dout(mtsel[1:0])); + + // ---------------------------------------------------------------------- + // MTDATA1 (R/W) + // [31:0] : Trigger Data 1 + + // for triggers 0, 1, 2 and 3 aka Match Control + // [31:28] : type, hard coded to 0x2 + // [27] : dmode + // [26:21] : hard coded to 0x1f + // [20] : hit + // [19] : select (0 - address, 1 - data) + // [18] : timing, always 'before', reads 0x0 + // [17:12] : action, bits [17:13] not implemented and reads 0x0 + // [11] : chain + // [10:7] : match, bits [10:8] not implemented and reads 0x0 + // [6] : M + // [5:3] : not implemented, reads 0x0 + // [2] : execute + // [1] : store + // [0] : load + // + // decoder ring + // [27] : => 9 + // [20] : => 8 + // [19] : => 7 + // [12] : => 6 + // [11] : => 5 + // [7] : => 4 + // [6] : => 3 + // [2] : => 2 + // [1] : => 1 + // [0] : => 0 + + + // don't allow setting load-data. + assign tdata_load = dec_csr_wrdata_r[0] & ~dec_csr_wrdata_r[19]; + // don't allow setting execute-data. + assign tdata_opcode = dec_csr_wrdata_r[2] & ~dec_csr_wrdata_r[19]; + // don't allow clearing DMODE and action=1 + assign tdata_action = (dec_csr_wrdata_r[27] & dbg_tlu_halted_f) & dec_csr_wrdata_r[12]; + + // Chain bit has conditions: WARL for triggers without chains. Force to zero if dmode is 0 but next trigger dmode is 1. + assign tdata_chain = mtsel[0] ? 1'b0 : // triggers 1 and 3 chain bit is always zero + mtsel[1] ? dec_csr_wrdata_r[11] & ~(mtdata1_t3[MTDATA1_DMODE] & ~dec_csr_wrdata_r[27]) : // trigger 2 + dec_csr_wrdata_r[11] & ~(mtdata1_t1[MTDATA1_DMODE] & ~dec_csr_wrdata_r[27]); // trigger 0 + + // Kill mtdata1 write if dmode=1 but prior trigger has dmode=0/chain=1. Only applies to T1 and T3 + assign tdata_kill_write = mtsel[1] ? dec_csr_wrdata_r[27] & (~mtdata1_t2[MTDATA1_DMODE] & mtdata1_t2[MTDATA1_CHAIN]) : // trigger 3 + dec_csr_wrdata_r[27] & (~mtdata1_t0[MTDATA1_DMODE] & mtdata1_t0[MTDATA1_CHAIN]) ; // trigger 1 + + + assign tdata_wrdata_r[9:0] = {dec_csr_wrdata_r[27] & dbg_tlu_halted_f, + dec_csr_wrdata_r[20:19], + tdata_action, + tdata_chain, + dec_csr_wrdata_r[7:6], + tdata_opcode, + dec_csr_wrdata_r[1], + tdata_load}; + + // If the DMODE bit is set, tdata1 can only be updated in debug_mode + assign wr_mtdata1_t0_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MTDATA1) & (mtsel[1:0] == 2'b0) & (~mtdata1_t0[MTDATA1_DMODE] | dbg_tlu_halted_f); + assign mtdata1_t0_ns[9:0] = wr_mtdata1_t0_r ? tdata_wrdata_r[9:0] : + {mtdata1_t0[9], update_hit_bit_r[0] | mtdata1_t0[8], mtdata1_t0[7:0]}; + + assign wr_mtdata1_t1_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MTDATA1) & (mtsel[1:0] == 2'b01) & (~mtdata1_t1[MTDATA1_DMODE] | dbg_tlu_halted_f) & ~tdata_kill_write; + assign mtdata1_t1_ns[9:0] = wr_mtdata1_t1_r ? tdata_wrdata_r[9:0] : + {mtdata1_t1[9], update_hit_bit_r[1] | mtdata1_t1[8], mtdata1_t1[7:0]}; + + assign wr_mtdata1_t2_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MTDATA1) & (mtsel[1:0] == 2'b10) & (~mtdata1_t2[MTDATA1_DMODE] | dbg_tlu_halted_f); + assign mtdata1_t2_ns[9:0] = wr_mtdata1_t2_r ? tdata_wrdata_r[9:0] : + {mtdata1_t2[9], update_hit_bit_r[2] | mtdata1_t2[8], mtdata1_t2[7:0]}; + + assign wr_mtdata1_t3_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MTDATA1) & (mtsel[1:0] == 2'b11) & (~mtdata1_t3[MTDATA1_DMODE] | dbg_tlu_halted_f) & ~tdata_kill_write; + assign mtdata1_t3_ns[9:0] = wr_mtdata1_t3_r ? tdata_wrdata_r[9:0] : + {mtdata1_t3[9], update_hit_bit_r[3] | mtdata1_t3[8], mtdata1_t3[7:0]}; + + + rvdffe #(10) mtdata1_t0_ff (.*, .en(trigger_enabled[0] | wr_mtdata1_t0_r), .din(mtdata1_t0_ns[9:0]), .dout(mtdata1_t0[9:0])); + rvdffe #(10) mtdata1_t1_ff (.*, .en(trigger_enabled[1] | wr_mtdata1_t1_r), .din(mtdata1_t1_ns[9:0]), .dout(mtdata1_t1[9:0])); + rvdffe #(10) mtdata1_t2_ff (.*, .en(trigger_enabled[2] | wr_mtdata1_t2_r), .din(mtdata1_t2_ns[9:0]), .dout(mtdata1_t2[9:0])); + rvdffe #(10) mtdata1_t3_ff (.*, .en(trigger_enabled[3] | wr_mtdata1_t3_r), .din(mtdata1_t3_ns[9:0]), .dout(mtdata1_t3[9:0])); + + assign mtdata1_tsel_out[31:0] = ( ({32{(mtsel[1:0] == 2'b00)}} & {4'h2, mtdata1_t0[9], 6'b011111, mtdata1_t0[8:7], 6'b0, mtdata1_t0[6:5], 3'b0, mtdata1_t0[4:3], 3'b0, mtdata1_t0[2:0]}) | + ({32{(mtsel[1:0] == 2'b01)}} & {4'h2, mtdata1_t1[9], 6'b011111, mtdata1_t1[8:7], 6'b0, mtdata1_t1[6:5], 3'b0, mtdata1_t1[4:3], 3'b0, mtdata1_t1[2:0]}) | + ({32{(mtsel[1:0] == 2'b10)}} & {4'h2, mtdata1_t2[9], 6'b011111, mtdata1_t2[8:7], 6'b0, mtdata1_t2[6:5], 3'b0, mtdata1_t2[4:3], 3'b0, mtdata1_t2[2:0]}) | + ({32{(mtsel[1:0] == 2'b11)}} & {4'h2, mtdata1_t3[9], 6'b011111, mtdata1_t3[8:7], 6'b0, mtdata1_t3[6:5], 3'b0, mtdata1_t3[4:3], 3'b0, mtdata1_t3[2:0]})); + + assign trigger_pkt_any[0].select = mtdata1_t0[MTDATA1_SEL]; + assign trigger_pkt_any[0].match = mtdata1_t0[MTDATA1_MATCH]; + assign trigger_pkt_any[0].store = mtdata1_t0[MTDATA1_ST]; + assign trigger_pkt_any[0].load = mtdata1_t0[MTDATA1_LD]; + assign trigger_pkt_any[0].execute = mtdata1_t0[MTDATA1_EXE]; + assign trigger_pkt_any[0].m = mtdata1_t0[MTDATA1_M_ENABLED]; + + assign trigger_pkt_any[1].select = mtdata1_t1[MTDATA1_SEL]; + assign trigger_pkt_any[1].match = mtdata1_t1[MTDATA1_MATCH]; + assign trigger_pkt_any[1].store = mtdata1_t1[MTDATA1_ST]; + assign trigger_pkt_any[1].load = mtdata1_t1[MTDATA1_LD]; + assign trigger_pkt_any[1].execute = mtdata1_t1[MTDATA1_EXE]; + assign trigger_pkt_any[1].m = mtdata1_t1[MTDATA1_M_ENABLED]; + + assign trigger_pkt_any[2].select = mtdata1_t2[MTDATA1_SEL]; + assign trigger_pkt_any[2].match = mtdata1_t2[MTDATA1_MATCH]; + assign trigger_pkt_any[2].store = mtdata1_t2[MTDATA1_ST]; + assign trigger_pkt_any[2].load = mtdata1_t2[MTDATA1_LD]; + assign trigger_pkt_any[2].execute = mtdata1_t2[MTDATA1_EXE]; + assign trigger_pkt_any[2].m = mtdata1_t2[MTDATA1_M_ENABLED]; + + assign trigger_pkt_any[3].select = mtdata1_t3[MTDATA1_SEL]; + assign trigger_pkt_any[3].match = mtdata1_t3[MTDATA1_MATCH]; + assign trigger_pkt_any[3].store = mtdata1_t3[MTDATA1_ST]; + assign trigger_pkt_any[3].load = mtdata1_t3[MTDATA1_LD]; + assign trigger_pkt_any[3].execute = mtdata1_t3[MTDATA1_EXE]; + assign trigger_pkt_any[3].m = mtdata1_t3[MTDATA1_M_ENABLED]; + + + + + + // ---------------------------------------------------------------------- + // MTDATA2 (R/W) + // [31:0] : Trigger Data 2 + + // If the DMODE bit is set, tdata2 can only be updated in debug_mode + assign wr_mtdata2_t0_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MTDATA2) & (mtsel[1:0] == 2'b0) & (~mtdata1_t0[MTDATA1_DMODE] | dbg_tlu_halted_f); + assign wr_mtdata2_t1_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MTDATA2) & (mtsel[1:0] == 2'b01) & (~mtdata1_t1[MTDATA1_DMODE] | dbg_tlu_halted_f); + assign wr_mtdata2_t2_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MTDATA2) & (mtsel[1:0] == 2'b10) & (~mtdata1_t2[MTDATA1_DMODE] | dbg_tlu_halted_f); + assign wr_mtdata2_t3_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MTDATA2) & (mtsel[1:0] == 2'b11) & (~mtdata1_t3[MTDATA1_DMODE] | dbg_tlu_halted_f); + + rvdffe #(32) mtdata2_t0_ff (.*, .en(wr_mtdata2_t0_r), .din(dec_csr_wrdata_r[31:0]), .dout(mtdata2_t0[31:0])); + rvdffe #(32) mtdata2_t1_ff (.*, .en(wr_mtdata2_t1_r), .din(dec_csr_wrdata_r[31:0]), .dout(mtdata2_t1[31:0])); + rvdffe #(32) mtdata2_t2_ff (.*, .en(wr_mtdata2_t2_r), .din(dec_csr_wrdata_r[31:0]), .dout(mtdata2_t2[31:0])); + rvdffe #(32) mtdata2_t3_ff (.*, .en(wr_mtdata2_t3_r), .din(dec_csr_wrdata_r[31:0]), .dout(mtdata2_t3[31:0])); + + assign mtdata2_tsel_out[31:0] = ( ({32{(mtsel[1:0] == 2'b00)}} & mtdata2_t0[31:0]) | + ({32{(mtsel[1:0] == 2'b01)}} & mtdata2_t1[31:0]) | + ({32{(mtsel[1:0] == 2'b10)}} & mtdata2_t2[31:0]) | + ({32{(mtsel[1:0] == 2'b11)}} & mtdata2_t3[31:0])); + + assign trigger_pkt_any[0].tdata2[31:0] = mtdata2_t0[31:0]; + assign trigger_pkt_any[1].tdata2[31:0] = mtdata2_t1[31:0]; + assign trigger_pkt_any[2].tdata2[31:0] = mtdata2_t2[31:0]; + assign trigger_pkt_any[3].tdata2[31:0] = mtdata2_t3[31:0]; + + + //---------------------------------------------------------------------- + // Performance Monitor Counters section starts + //---------------------------------------------------------------------- + localparam MHPME_NOEVENT = 10'd0; + localparam MHPME_CLK_ACTIVE = 10'd1; // OOP - out of pipe + localparam MHPME_ICACHE_HIT = 10'd2; // OOP + localparam MHPME_ICACHE_MISS = 10'd3; // OOP + localparam MHPME_INST_COMMIT = 10'd4; + localparam MHPME_INST_COMMIT_16B = 10'd5; + localparam MHPME_INST_COMMIT_32B = 10'd6; + localparam MHPME_INST_ALIGNED = 10'd7; // OOP + localparam MHPME_INST_DECODED = 10'd8; // OOP + localparam MHPME_INST_MUL = 10'd9; + localparam MHPME_INST_DIV = 10'd10; + localparam MHPME_INST_LOAD = 10'd11; + localparam MHPME_INST_STORE = 10'd12; + localparam MHPME_INST_MALOAD = 10'd13; + localparam MHPME_INST_MASTORE = 10'd14; + localparam MHPME_INST_ALU = 10'd15; + localparam MHPME_INST_CSRREAD = 10'd16; + localparam MHPME_INST_CSRRW = 10'd17; + localparam MHPME_INST_CSRWRITE = 10'd18; + localparam MHPME_INST_EBREAK = 10'd19; + localparam MHPME_INST_ECALL = 10'd20; + localparam MHPME_INST_FENCE = 10'd21; + localparam MHPME_INST_FENCEI = 10'd22; + localparam MHPME_INST_MRET = 10'd23; + localparam MHPME_INST_BRANCH = 10'd24; + localparam MHPME_BRANCH_MP = 10'd25; + localparam MHPME_BRANCH_TAKEN = 10'd26; + localparam MHPME_BRANCH_NOTP = 10'd27; + localparam MHPME_FETCH_STALL = 10'd28; // OOP + localparam MHPME_DECODE_STALL = 10'd30; // OOP + localparam MHPME_POSTSYNC_STALL = 10'd31; // OOP + localparam MHPME_PRESYNC_STALL = 10'd32; // OOP + localparam MHPME_LSU_SB_WB_STALL = 10'd34; // OOP + localparam MHPME_DMA_DCCM_STALL = 10'd35; // OOP + localparam MHPME_DMA_ICCM_STALL = 10'd36; // OOP + localparam MHPME_EXC_TAKEN = 10'd37; + localparam MHPME_TIMER_INT_TAKEN = 10'd38; + localparam MHPME_EXT_INT_TAKEN = 10'd39; + localparam MHPME_FLUSH_LOWER = 10'd40; + localparam MHPME_BR_ERROR = 10'd41; + localparam MHPME_IBUS_TRANS = 10'd42; // OOP + localparam MHPME_DBUS_TRANS = 10'd43; // OOP + localparam MHPME_DBUS_MA_TRANS = 10'd44; // OOP + localparam MHPME_IBUS_ERROR = 10'd45; // OOP + localparam MHPME_DBUS_ERROR = 10'd46; // OOP + localparam MHPME_IBUS_STALL = 10'd47; // OOP + localparam MHPME_DBUS_STALL = 10'd48; // OOP + localparam MHPME_INT_DISABLED = 10'd49; // OOP + localparam MHPME_INT_STALLED = 10'd50; // OOP + localparam MHPME_INST_BITMANIP = 10'd54; + localparam MHPME_DBUS_LOAD = 10'd55; + localparam MHPME_DBUS_STORE = 10'd56; + // Counts even during sleep state + localparam MHPME_SLEEP_CYC = 10'd512; // OOP + localparam MHPME_DMA_READ_ALL = 10'd513; // OOP + localparam MHPME_DMA_WRITE_ALL = 10'd514; // OOP + localparam MHPME_DMA_READ_DCCM = 10'd515; // OOP + localparam MHPME_DMA_WRITE_DCCM = 10'd516; // OOP + + // Pack the event selects into a vector for genvar + assign mhpme_vec[0][9:0] = mhpme3[9:0]; + assign mhpme_vec[1][9:0] = mhpme4[9:0]; + assign mhpme_vec[2][9:0] = mhpme5[9:0]; + assign mhpme_vec[3][9:0] = mhpme6[9:0]; + + // only consider committed itypes + //logic [3:0] pmu_i0_itype_qual; + assign pmu_i0_itype_qual[3:0] = dec_tlu_packet_r.pmu_i0_itype[3:0] & {4{tlu_i0_commit_cmt}}; + + // Generate the muxed incs for all counters based on event type + for (genvar i=0 ; i < 4; i++) begin + assign mhpmc_inc_r[i] = {{~mcountinhibit[i+3]}} & + ( + ({1{(mhpme_vec[i][9:0] == MHPME_CLK_ACTIVE )}} & 1'b1) | + ({1{(mhpme_vec[i][9:0] == MHPME_ICACHE_HIT )}} & {ifu_pmu_ic_hit}) | + ({1{(mhpme_vec[i][9:0] == MHPME_ICACHE_MISS )}} & {ifu_pmu_ic_miss}) | + ({1{(mhpme_vec[i][9:0] == MHPME_INST_COMMIT )}} & {tlu_i0_commit_cmt & ~illegal_r}) | + ({1{(mhpme_vec[i][9:0] == MHPME_INST_COMMIT_16B )}} & {tlu_i0_commit_cmt & ~exu_pmu_i0_pc4 & ~illegal_r}) | + ({1{(mhpme_vec[i][9:0] == MHPME_INST_COMMIT_32B )}} & {tlu_i0_commit_cmt & exu_pmu_i0_pc4 & ~illegal_r}) | + ({1{(mhpme_vec[i][9:0] == MHPME_INST_ALIGNED )}} & ifu_pmu_instr_aligned) | + ({1{(mhpme_vec[i][9:0] == MHPME_INST_DECODED )}} & dec_pmu_instr_decoded) | + ({1{(mhpme_vec[i][9:0] == MHPME_INST_MUL )}} & {(pmu_i0_itype_qual == MUL)}) | + ({1{(mhpme_vec[i][9:0] == MHPME_INST_DIV )}} & {dec_tlu_packet_r.pmu_divide & tlu_i0_commit_cmt & ~illegal_r}) | + ({1{(mhpme_vec[i][9:0] == MHPME_INST_LOAD )}} & {(pmu_i0_itype_qual == LOAD)}) | + ({1{(mhpme_vec[i][9:0] == MHPME_INST_STORE )}} & {(pmu_i0_itype_qual == STORE)}) | + ({1{(mhpme_vec[i][9:0] == MHPME_INST_MALOAD )}} & {(pmu_i0_itype_qual == LOAD)} & + {1{dec_tlu_packet_r.pmu_lsu_misaligned}}) | + ({1{(mhpme_vec[i][9:0] == MHPME_INST_MASTORE )}} & {(pmu_i0_itype_qual == STORE)} & + {1{dec_tlu_packet_r.pmu_lsu_misaligned}}) | + ({1{(mhpme_vec[i][9:0] == MHPME_INST_ALU )}} & {(pmu_i0_itype_qual == ALU)}) | + ({1{(mhpme_vec[i][9:0] == MHPME_INST_CSRREAD )}} & {(pmu_i0_itype_qual == CSRREAD)}) | + ({1{(mhpme_vec[i][9:0] == MHPME_INST_CSRWRITE )}} & {(pmu_i0_itype_qual == CSRWRITE)})| + ({1{(mhpme_vec[i][9:0] == MHPME_INST_CSRRW )}} & {(pmu_i0_itype_qual == CSRRW)}) | + ({1{(mhpme_vec[i][9:0] == MHPME_INST_EBREAK )}} & {(pmu_i0_itype_qual == EBREAK)}) | + ({1{(mhpme_vec[i][9:0] == MHPME_INST_ECALL )}} & {(pmu_i0_itype_qual == ECALL)}) | + ({1{(mhpme_vec[i][9:0] == MHPME_INST_FENCE )}} & {(pmu_i0_itype_qual == FENCE)}) | + ({1{(mhpme_vec[i][9:0] == MHPME_INST_FENCEI )}} & {(pmu_i0_itype_qual == FENCEI)}) | + ({1{(mhpme_vec[i][9:0] == MHPME_INST_MRET )}} & {(pmu_i0_itype_qual == MRET)}) | + ({1{(mhpme_vec[i][9:0] == MHPME_INST_BRANCH )}} & { + ((pmu_i0_itype_qual == CONDBR) | (pmu_i0_itype_qual == JAL))}) | + ({1{(mhpme_vec[i][9:0] == MHPME_BRANCH_MP )}} & {exu_pmu_i0_br_misp & tlu_i0_commit_cmt & ~illegal_r}) | + ({1{(mhpme_vec[i][9:0] == MHPME_BRANCH_TAKEN )}} & {exu_pmu_i0_br_ataken & tlu_i0_commit_cmt & ~illegal_r}) | + ({1{(mhpme_vec[i][9:0] == MHPME_BRANCH_NOTP )}} & {dec_tlu_packet_r.pmu_i0_br_unpred & tlu_i0_commit_cmt & ~illegal_r}) | + ({1{(mhpme_vec[i][9:0] == MHPME_FETCH_STALL )}} & { ifu_pmu_fetch_stall}) | + ({1{(mhpme_vec[i][9:0] == MHPME_DECODE_STALL )}} & { dec_pmu_decode_stall}) | + ({1{(mhpme_vec[i][9:0] == MHPME_POSTSYNC_STALL )}} & {dec_pmu_postsync_stall}) | + ({1{(mhpme_vec[i][9:0] == MHPME_PRESYNC_STALL )}} & {dec_pmu_presync_stall}) | + ({1{(mhpme_vec[i][9:0] == MHPME_LSU_SB_WB_STALL )}} & { lsu_store_stall_any}) | + ({1{(mhpme_vec[i][9:0] == MHPME_DMA_DCCM_STALL )}} & { dma_dccm_stall_any}) | + ({1{(mhpme_vec[i][9:0] == MHPME_DMA_ICCM_STALL )}} & { dma_iccm_stall_any}) | + ({1{(mhpme_vec[i][9:0] == MHPME_EXC_TAKEN )}} & { (i0_exception_valid_r | i0_trigger_hit_r | lsu_exc_valid_r)}) | + ({1{(mhpme_vec[i][9:0] == MHPME_TIMER_INT_TAKEN )}} & { take_timer_int | take_int_timer0_int | take_int_timer1_int}) | + ({1{(mhpme_vec[i][9:0] == MHPME_EXT_INT_TAKEN )}} & { take_ext_int}) | + ({1{(mhpme_vec[i][9:0] == MHPME_FLUSH_LOWER )}} & { tlu_flush_lower_r}) | + ({1{(mhpme_vec[i][9:0] == MHPME_BR_ERROR )}} & {(dec_tlu_br0_error_r | dec_tlu_br0_start_error_r) & rfpc_i0_r}) | + ({1{(mhpme_vec[i][9:0] == MHPME_IBUS_TRANS )}} & {ifu_pmu_bus_trxn}) | + ({1{(mhpme_vec[i][9:0] == MHPME_DBUS_TRANS )}} & {lsu_pmu_bus_trxn}) | + ({1{(mhpme_vec[i][9:0] == MHPME_DBUS_MA_TRANS )}} & {lsu_pmu_bus_misaligned}) | + ({1{(mhpme_vec[i][9:0] == MHPME_IBUS_ERROR )}} & {ifu_pmu_bus_error}) | + ({1{(mhpme_vec[i][9:0] == MHPME_DBUS_ERROR )}} & {lsu_pmu_bus_error}) | + ({1{(mhpme_vec[i][9:0] == MHPME_IBUS_STALL )}} & {ifu_pmu_bus_busy}) | + ({1{(mhpme_vec[i][9:0] == MHPME_DBUS_STALL )}} & {lsu_pmu_bus_busy}) | + ({1{(mhpme_vec[i][9:0] == MHPME_INT_DISABLED )}} & {~mstatus[MSTATUS_MIE]}) | + ({1{(mhpme_vec[i][9:0] == MHPME_INT_STALLED )}} & {~mstatus[MSTATUS_MIE] & |(mip[5:0] & mie[5:0])}) | + ({1{(mhpme_vec[i][9:0] == MHPME_INST_BITMANIP )}} & {(pmu_i0_itype_qual == BITMANIPU)}) | + ({1{(mhpme_vec[i][9:0] == MHPME_DBUS_LOAD )}} & {tlu_i0_commit_cmt & lsu_pmu_load_external_r & ~illegal_r}) | + ({1{(mhpme_vec[i][9:0] == MHPME_DBUS_STORE )}} & {tlu_i0_commit_cmt & lsu_pmu_store_external_r & ~illegal_r}) | + // These count even during sleep + ({1{(mhpme_vec[i][9:0] == MHPME_SLEEP_CYC )}} & {dec_tlu_pmu_fw_halted}) | + ({1{(mhpme_vec[i][9:0] == MHPME_DMA_READ_ALL )}} & {dma_pmu_any_read}) | + ({1{(mhpme_vec[i][9:0] == MHPME_DMA_WRITE_ALL )}} & {dma_pmu_any_write}) | + ({1{(mhpme_vec[i][9:0] == MHPME_DMA_READ_DCCM )}} & {dma_pmu_dccm_read}) | + ({1{(mhpme_vec[i][9:0] == MHPME_DMA_WRITE_DCCM )}} & {dma_pmu_dccm_write}) + ); + end + + + if(pt.FAST_INTERRUPT_REDIRECT) begin : genblock2 + +`ifdef RV_USER_MODE + rvdffie #(33) mstatus_ff (.*, .clk(free_l2clk), + .din({mdseac_locked_ns, lsu_single_ecc_error_r, lsu_exc_valid_r, lsu_i0_exc_r, + take_ext_int_start, take_ext_int_start_d1, take_ext_int_start_d2, ext_int_freeze, + mip_ns[5:0], mcyclel_cout & ~wr_mcycleh_r & mcyclel_cout_in, + minstret_enable, minstretl_cout_ns, fw_halted_ns, + meicidpl_ns[3:0], icache_rd_valid, icache_wr_valid, mhpmc_inc_r[3:0], perfcnt_halted, + mstatus_ns[3:0]}), + .dout({mdseac_locked_f, lsu_single_ecc_error_r_d1, lsu_exc_valid_r_d1, lsu_i0_exc_r_d1, + take_ext_int_start_d1, take_ext_int_start_d2, take_ext_int_start_d3, ext_int_freeze_d1, + mip[5:0], mcyclel_cout_f, minstret_enable_f, minstretl_cout_f, + fw_halted, meicidpl[3:0], icache_rd_valid_f, icache_wr_valid_f, + mhpmc_inc_r_d1[3:0], perfcnt_halted_d1, + mstatus[3:0]})); +`else + rvdffie #(31) mstatus_ff (.*, .clk(free_l2clk), + .din({mdseac_locked_ns, lsu_single_ecc_error_r, lsu_exc_valid_r, lsu_i0_exc_r, + take_ext_int_start, take_ext_int_start_d1, take_ext_int_start_d2, ext_int_freeze, + mip_ns[5:0], mcyclel_cout & ~wr_mcycleh_r & mcyclel_cout_in, + minstret_enable, minstretl_cout_ns, fw_halted_ns, + meicidpl_ns[3:0], icache_rd_valid, icache_wr_valid, mhpmc_inc_r[3:0], perfcnt_halted, + mstatus_ns[1:0]}), + .dout({mdseac_locked_f, lsu_single_ecc_error_r_d1, lsu_exc_valid_r_d1, lsu_i0_exc_r_d1, + take_ext_int_start_d1, take_ext_int_start_d2, take_ext_int_start_d3, ext_int_freeze_d1, + mip[5:0], mcyclel_cout_f, minstret_enable_f, minstretl_cout_f, + fw_halted, meicidpl[3:0], icache_rd_valid_f, icache_wr_valid_f, + mhpmc_inc_r_d1[3:0], perfcnt_halted_d1, + mstatus[1:0]})); + +`endif + + end + else begin : genblock2 +`ifdef RV_USER_MODE + rvdffie #(29) mstatus_ff (.*, .clk(free_l2clk), + .din({mdseac_locked_ns, lsu_single_ecc_error_r, lsu_exc_valid_r, lsu_i0_exc_r, + mip_ns[5:0], mcyclel_cout & ~wr_mcycleh_r & mcyclel_cout_in, + minstret_enable, minstretl_cout_ns, fw_halted_ns, + meicidpl_ns[3:0], icache_rd_valid, icache_wr_valid, mhpmc_inc_r[3:0], perfcnt_halted, + mstatus_ns[3:0]}), + .dout({mdseac_locked_f, lsu_single_ecc_error_r_d1, lsu_exc_valid_r_d1, lsu_i0_exc_r_d1, + mip[5:0], mcyclel_cout_f, minstret_enable_f, minstretl_cout_f, + fw_halted, meicidpl[3:0], icache_rd_valid_f, icache_wr_valid_f, + mhpmc_inc_r_d1[3:0], perfcnt_halted_d1, + mstatus[3:0]})); +`else + rvdffie #(27) mstatus_ff (.*, .clk(free_l2clk), + .din({mdseac_locked_ns, lsu_single_ecc_error_r, lsu_exc_valid_r, lsu_i0_exc_r, + mip_ns[5:0], mcyclel_cout & ~wr_mcycleh_r & mcyclel_cout_in, + minstret_enable, minstretl_cout_ns, fw_halted_ns, + meicidpl_ns[3:0], icache_rd_valid, icache_wr_valid, mhpmc_inc_r[3:0], perfcnt_halted, + mstatus_ns[1:0]}), + .dout({mdseac_locked_f, lsu_single_ecc_error_r_d1, lsu_exc_valid_r_d1, lsu_i0_exc_r_d1, + mip[5:0], mcyclel_cout_f, minstret_enable_f, minstretl_cout_f, + fw_halted, meicidpl[3:0], icache_rd_valid_f, icache_wr_valid_f, + mhpmc_inc_r_d1[3:0], perfcnt_halted_d1, + mstatus[1:0]})); +`endif + end + + assign perfcnt_halted = ((dec_tlu_dbg_halted & dcsr[DCSR_STOPC]) | dec_tlu_pmu_fw_halted); + assign perfcnt_during_sleep[3:0] = {4{~(dec_tlu_dbg_halted & dcsr[DCSR_STOPC])}} & {mhpme_vec[3][9],mhpme_vec[2][9],mhpme_vec[1][9],mhpme_vec[0][9]}; + + assign dec_tlu_perfcnt0 = mhpmc_inc_r_d1[0] & ~(perfcnt_halted_d1 & ~perfcnt_during_sleep[0]); + assign dec_tlu_perfcnt1 = mhpmc_inc_r_d1[1] & ~(perfcnt_halted_d1 & ~perfcnt_during_sleep[1]); + assign dec_tlu_perfcnt2 = mhpmc_inc_r_d1[2] & ~(perfcnt_halted_d1 & ~perfcnt_during_sleep[2]); + assign dec_tlu_perfcnt3 = mhpmc_inc_r_d1[3] & ~(perfcnt_halted_d1 & ~perfcnt_during_sleep[3]); + + // ---------------------------------------------------------------------- + // MHPMC3H(RW), MHPMC3(RW) + // [63:32][31:0] : Hardware Performance Monitor Counter 3 + + assign mhpmc3_wr_en0 = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MHPMC3); + assign mhpmc3_wr_en1 = (~perfcnt_halted | perfcnt_during_sleep[0]) & (|(mhpmc_inc_r[0])); + assign mhpmc3_wr_en = mhpmc3_wr_en0 | mhpmc3_wr_en1; + assign mhpmc3_incr[63:0] = {mhpmc3h[31:0],mhpmc3[31:0]} + {63'b0, 1'b1}; + assign mhpmc3_ns[31:0] = mhpmc3_wr_en0 ? dec_csr_wrdata_r[31:0] : mhpmc3_incr[31:0]; + rvdffe #(32) mhpmc3_ff (.*, .clk(free_l2clk), .en(mhpmc3_wr_en), .din(mhpmc3_ns[31:0]), .dout(mhpmc3[31:0])); + + assign mhpmc3h_wr_en0 = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MHPMC3H); + assign mhpmc3h_wr_en = mhpmc3h_wr_en0 | mhpmc3_wr_en1; + assign mhpmc3h_ns[31:0] = mhpmc3h_wr_en0 ? dec_csr_wrdata_r[31:0] : mhpmc3_incr[63:32]; + rvdffe #(32) mhpmc3h_ff (.*, .clk(free_l2clk), .en(mhpmc3h_wr_en), .din(mhpmc3h_ns[31:0]), .dout(mhpmc3h[31:0])); + + // ---------------------------------------------------------------------- + // MHPMC4H(RW), MHPMC4(RW) + // [63:32][31:0] : Hardware Performance Monitor Counter 4 + + assign mhpmc4_wr_en0 = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MHPMC4); + assign mhpmc4_wr_en1 = (~perfcnt_halted | perfcnt_during_sleep[1]) & (|(mhpmc_inc_r[1])); + assign mhpmc4_wr_en = mhpmc4_wr_en0 | mhpmc4_wr_en1; + assign mhpmc4_incr[63:0] = {mhpmc4h[31:0],mhpmc4[31:0]} + {63'b0,1'b1}; + assign mhpmc4_ns[31:0] = mhpmc4_wr_en0 ? dec_csr_wrdata_r[31:0] : mhpmc4_incr[31:0]; + rvdffe #(32) mhpmc4_ff (.*, .clk(free_l2clk), .en(mhpmc4_wr_en), .din(mhpmc4_ns[31:0]), .dout(mhpmc4[31:0])); + + assign mhpmc4h_wr_en0 = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MHPMC4H); + assign mhpmc4h_wr_en = mhpmc4h_wr_en0 | mhpmc4_wr_en1; + assign mhpmc4h_ns[31:0] = mhpmc4h_wr_en0 ? dec_csr_wrdata_r[31:0] : mhpmc4_incr[63:32]; + rvdffe #(32) mhpmc4h_ff (.*, .clk(free_l2clk), .en(mhpmc4h_wr_en), .din(mhpmc4h_ns[31:0]), .dout(mhpmc4h[31:0])); + + // ---------------------------------------------------------------------- + // MHPMC5H(RW), MHPMC5(RW) + // [63:32][31:0] : Hardware Performance Monitor Counter 5 + + assign mhpmc5_wr_en0 = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MHPMC5); + assign mhpmc5_wr_en1 = (~perfcnt_halted | perfcnt_during_sleep[2]) & (|(mhpmc_inc_r[2])); + assign mhpmc5_wr_en = mhpmc5_wr_en0 | mhpmc5_wr_en1; + assign mhpmc5_incr[63:0] = {mhpmc5h[31:0],mhpmc5[31:0]} + {63'b0,1'b1}; + assign mhpmc5_ns[31:0] = mhpmc5_wr_en0 ? dec_csr_wrdata_r[31:0] : mhpmc5_incr[31:0]; + rvdffe #(32) mhpmc5_ff (.*, .clk(free_l2clk), .en(mhpmc5_wr_en), .din(mhpmc5_ns[31:0]), .dout(mhpmc5[31:0])); + + assign mhpmc5h_wr_en0 = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MHPMC5H); + assign mhpmc5h_wr_en = mhpmc5h_wr_en0 | mhpmc5_wr_en1; + assign mhpmc5h_ns[31:0] = mhpmc5h_wr_en0 ? dec_csr_wrdata_r[31:0] : mhpmc5_incr[63:32]; + rvdffe #(32) mhpmc5h_ff (.*, .clk(free_l2clk), .en(mhpmc5h_wr_en), .din(mhpmc5h_ns[31:0]), .dout(mhpmc5h[31:0])); + + // ---------------------------------------------------------------------- + // MHPMC6H(RW), MHPMC6(RW) + // [63:32][31:0] : Hardware Performance Monitor Counter 6 + + assign mhpmc6_wr_en0 = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MHPMC6); + assign mhpmc6_wr_en1 = (~perfcnt_halted | perfcnt_during_sleep[3]) & (|(mhpmc_inc_r[3])); + assign mhpmc6_wr_en = mhpmc6_wr_en0 | mhpmc6_wr_en1; + assign mhpmc6_incr[63:0] = {mhpmc6h[31:0],mhpmc6[31:0]} + {63'b0,1'b1}; + assign mhpmc6_ns[31:0] = mhpmc6_wr_en0 ? dec_csr_wrdata_r[31:0] : mhpmc6_incr[31:0]; + rvdffe #(32) mhpmc6_ff (.*, .clk(free_l2clk), .en(mhpmc6_wr_en), .din(mhpmc6_ns[31:0]), .dout(mhpmc6[31:0])); + + assign mhpmc6h_wr_en0 = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MHPMC6H); + assign mhpmc6h_wr_en = mhpmc6h_wr_en0 | mhpmc6_wr_en1; + assign mhpmc6h_ns[31:0] = mhpmc6h_wr_en0 ? dec_csr_wrdata_r[31:0] : mhpmc6_incr[63:32]; + rvdffe #(32) mhpmc6h_ff (.*, .clk(free_l2clk), .en(mhpmc6h_wr_en), .din(mhpmc6h_ns[31:0]), .dout(mhpmc6h[31:0])); + + // ---------------------------------------------------------------------- + // MHPME3(RW) + // [9:0] : Hardware Performance Monitor Event 3 + + // we only have events 0-56 with holes, 512-516, HPME* are WARL so zero otherwise. + assign zero_event_r = ( (dec_csr_wrdata_r[9:0] > 10'd516) | + (|dec_csr_wrdata_r[31:10]) | + ((dec_csr_wrdata_r[9:0] < 10'd512) & (dec_csr_wrdata_r[9:0] > 10'd56)) | + ((dec_csr_wrdata_r[9:0] < 10'd54) & (dec_csr_wrdata_r[9:0] > 10'd50)) | + (dec_csr_wrdata_r[9:0] == 10'd29) | + (dec_csr_wrdata_r[9:0] == 10'd33) + ); + + assign event_r[9:0] = zero_event_r ? '0 : dec_csr_wrdata_r[9:0]; + + assign wr_mhpme3_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MHPME3); + rvdffe #(10) mhpme3_ff (.*, .en(wr_mhpme3_r), .din(event_r[9:0]), .dout(mhpme3[9:0])); + // ---------------------------------------------------------------------- + // MHPME4(RW) + // [9:0] : Hardware Performance Monitor Event 4 + + assign wr_mhpme4_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MHPME4); + rvdffe #(10) mhpme4_ff (.*, .en(wr_mhpme4_r), .din(event_r[9:0]), .dout(mhpme4[9:0])); + // ---------------------------------------------------------------------- + // MHPME5(RW) + // [9:0] : Hardware Performance Monitor Event 5 + + assign wr_mhpme5_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MHPME5); + rvdffe #(10) mhpme5_ff (.*, .en(wr_mhpme5_r), .din(event_r[9:0]), .dout(mhpme5[9:0])); + // ---------------------------------------------------------------------- + // MHPME6(RW) + // [9:0] : Hardware Performance Monitor Event 6 + + assign wr_mhpme6_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MHPME6); + rvdffe #(10) mhpme6_ff (.*, .en(wr_mhpme6_r), .din(event_r[9:0]), .dout(mhpme6[9:0])); + + //---------------------------------------------------------------------- + // Performance Monitor Counters section ends + //---------------------------------------------------------------------- + // ---------------------------------------------------------------------- + + // ---------------------------------------------------------------------- + // MCOUNTEREN + // [31:3] : Reserved, read 0x0 + // [2] : INSTRET user-mode access disable + // [1] : reserved, read 0x0 + // [0] : CYCLE user-mode access disable + +`ifdef RV_USER_MODE + + localparam MCOUNTEREN = 12'h306; + + assign wr_mcounteren_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MCOUNTEREN); + rvdffs #(6) mcounteren_ff (.*, .clk(csr_wr_clk), .en(wr_mcounteren_r), .din({dec_csr_wrdata_r[6:2], dec_csr_wrdata_r[0]}), .dout(mcounteren)); + +`endif + + // MCOUNTINHIBIT(RW) + // [31:7] : Reserved, read 0x0 + // [6] : HPM6 disable + // [5] : HPM5 disable + // [4] : HPM4 disable + // [3] : HPM3 disable + // [2] : MINSTRET disable + // [1] : reserved, read 0x0 + // [0] : MCYCLE disable + + assign wr_mcountinhibit_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MCOUNTINHIBIT); + rvdffs #(6) mcountinhibit_ff (.*, .clk(csr_wr_clk), .en(wr_mcountinhibit_r), .din({dec_csr_wrdata_r[6:2], dec_csr_wrdata_r[0]}), .dout({mcountinhibit[6:2], mcountinhibit[0]})); + assign mcountinhibit[1] = 1'b0; + + //-------------------------------------------------------------------------------- + // trace + //-------------------------------------------------------------------------------- + logic [4:0] dec_tlu_exc_cause_wb1_raw, dec_tlu_exc_cause_wb2; + logic dec_tlu_int_valid_wb1_raw, dec_tlu_int_valid_wb2; + + assign {dec_tlu_i0_valid_wb1, + dec_tlu_i0_exc_valid_wb1, + dec_tlu_exc_cause_wb1_raw[4:0], + dec_tlu_int_valid_wb1_raw} = {8{~dec_tlu_trace_disable}} & {i0_valid_wb, + i0_exception_valid_r_d1 | lsu_i0_exc_r_d1 | (trigger_hit_r_d1 & ~trigger_hit_dmode_r_d1), + exc_cause_wb[4:0], + interrupt_valid_r_d1}; + + + + // skid buffer for ints, reduces trace port count by 1 + rvdffie #(.WIDTH(6), .OVERRIDE(1)) traceskidff (.*, .clk(clk), + .din ({dec_tlu_exc_cause_wb1_raw[4:0], + dec_tlu_int_valid_wb1_raw}), + .dout({dec_tlu_exc_cause_wb2[4:0], + dec_tlu_int_valid_wb2})); + //skid for ints + assign dec_tlu_exc_cause_wb1[4:0] = dec_tlu_int_valid_wb2 ? dec_tlu_exc_cause_wb2[4:0] : dec_tlu_exc_cause_wb1_raw[4:0]; + assign dec_tlu_int_valid_wb1 = dec_tlu_int_valid_wb2; + + assign dec_tlu_mtval_wb1 = mtval[31:0]; + + // end trace + //-------------------------------------------------------------------------------- + + + // ---------------------------------------------------------------------- + // CSR read mux + // ---------------------------------------------------------------------- + +assign dec_tlu_presync_d = presync & dec_csr_any_unq_d & ~dec_csr_wen_unq_d; +assign dec_tlu_postsync_d = postsync & dec_csr_any_unq_d; + + // allow individual configuration of these features +assign conditionally_illegal = ((csr_mitcnt0 | csr_mitcnt1 | csr_mitb0 | csr_mitb1 | csr_mitctl0 | csr_mitctl1) & ~|pt.TIMER_LEGAL_EN); + +assign valid_csr = ( legal & (~(csr_dcsr | csr_dpc | csr_dmst | csr_dicawics | csr_dicad0 | csr_dicad0h | csr_dicad1 | csr_dicago) | dbg_tlu_halted_f) + & ~fast_int_meicpct & ~conditionally_illegal); + +assign dec_csr_legal_d = ( dec_csr_any_unq_d & + valid_csr & // of a valid CSR + ~(dec_csr_wen_unq_d & (csr_mvendorid | csr_marchid | csr_mimpid | csr_mhartid | csr_mdseac | csr_meihap)) // that's not a write to a RO CSR + ); + // CSR read mux +assign dec_csr_rddata_d[31:0] = ( +`ifdef RV_USER_MODE + ({32{csr_misa}} & 32'h40101104) | +`else + ({32{csr_misa}} & 32'h40001104) | +`endif + ({32{csr_mvendorid}} & 32'h00000045) | + ({32{csr_marchid}} & 32'h00000010) | + ({32{csr_mimpid}} & 32'h4) | + ({32{csr_mhartid}} & {core_id[31:4], 4'b0}) | +`ifdef RV_USER_MODE + ({32{csr_mstatus}} & {14'b0, mstatus[MSTATUS_MPRV], 4'b0, ~mstatus[MSTATUS_MPP], ~mstatus[MSTATUS_MPP], 3'b0, mstatus[MSTATUS_MPIE], 3'b0, mstatus[MSTATUS_MIE], 3'b0}) | +`else + ({32{csr_mstatus}} & {19'b0, 2'b11, 3'b0, mstatus[MSTATUS_MPIE], 3'b0, mstatus[MSTATUS_MIE], 3'b0}) | +`endif + ({32{csr_mtvec}} & {mtvec[30:1], 1'b0, mtvec[0]}) | + ({32{csr_mip}} & {1'b0, mip[5:3], 16'b0, mip[2], 3'b0, mip[1], 3'b0, mip[0], 3'b0}) | + ({32{csr_mie}} & {1'b0, mie[5:3], 16'b0, mie[2], 3'b0, mie[1], 3'b0, mie[0], 3'b0}) | + ({32{csr_mcyclel}} & mcyclel[31:0]) | + ({32{csr_mcycleh}} & mcycleh_inc[31:0]) | + ({32{csr_minstretl}} & minstretl_read[31:0]) | + ({32{csr_minstreth}} & minstreth_read[31:0]) | + ({32{csr_mscratch}} & mscratch[31:0]) | + ({32{csr_mepc}} & {mepc[31:1], 1'b0}) | + ({32{csr_mcause}} & mcause[31:0]) | + ({32{csr_mscause}} & {28'b0, mscause[3:0]}) | + ({32{csr_mtval}} & mtval[31:0]) | + ({32{csr_mrac}} & mrac[31:0]) | + ({32{csr_mdseac}} & mdseac[31:0]) | + ({32{csr_meivt}} & {meivt[31:10], 10'b0}) | + ({32{csr_meihap}} & {meivt[31:10], meihap[9:2], 2'b0}) | + ({32{csr_meicurpl}} & {28'b0, meicurpl[3:0]}) | + ({32{csr_meicidpl}} & {28'b0, meicidpl[3:0]}) | + ({32{csr_meipt}} & {28'b0, meipt[3:0]}) | + ({32{csr_mcgc}} & {22'b0, mcgc[9:0]}) | + ({32{csr_mfdc}} & {13'b0, mfdc[18:0]}) | + ({32{csr_dcsr}} & {16'h4000, dcsr[15:2], 2'b11}) | + ({32{csr_dpc}} & {dpc[31:1], 1'b0}) | + ({32{csr_dicad0}} & dicad0[31:0]) | + ({32{csr_dicad0h}} & dicad0h[31:0]) | + ({32{csr_dicad1}} & dicad1[31:0]) | + ({32{csr_dicawics}} & {7'b0, dicawics[16], 2'b0, dicawics[15:14], 3'b0, dicawics[13:0], 3'b0}) | + ({32{csr_mtsel}} & {30'b0, mtsel[1:0]}) | + ({32{csr_mtdata1}} & {mtdata1_tsel_out[31:0]}) | + ({32{csr_mtdata2}} & {mtdata2_tsel_out[31:0]}) | + ({32{csr_micect}} & {micect[31:0]}) | + ({32{csr_miccmect}} & {miccmect[31:0]}) | + ({32{csr_mdccmect}} & {mdccmect[31:0]}) | + ({32{csr_mhpmc3}} & mhpmc3[31:0]) | + ({32{csr_mhpmc4}} & mhpmc4[31:0]) | + ({32{csr_mhpmc5}} & mhpmc5[31:0]) | + ({32{csr_mhpmc6}} & mhpmc6[31:0]) | + ({32{csr_mhpmc3h}} & mhpmc3h[31:0]) | + ({32{csr_mhpmc4h}} & mhpmc4h[31:0]) | + ({32{csr_mhpmc5h}} & mhpmc5h[31:0]) | + ({32{csr_mhpmc6h}} & mhpmc6h[31:0]) | + ({32{csr_mfdht}} & {26'b0, mfdht[5:0]}) | + ({32{csr_mfdhs}} & {30'b0, mfdhs[1:0]}) | + ({32{csr_mhpme3}} & {22'b0,mhpme3[9:0]}) | + ({32{csr_mhpme4}} & {22'b0,mhpme4[9:0]}) | + ({32{csr_mhpme5}} & {22'b0,mhpme5[9:0]}) | + ({32{csr_mhpme6}} & {22'b0,mhpme6[9:0]}) | +`ifdef RV_USER_MODE + ({32{csr_menvcfg}} & 32'd0) | + ({32{csr_menvcfgh}} & 32'd0) | + ({32{csr_mcounteren}} & {25'b0, mcounteren[5:1], 1'b0, mcounteren[0]}) | + ({32{csr_cyclel}} & mcyclel[31:0]) | + ({32{csr_cycleh}} & mcycleh_inc[31:0]) | + ({32{csr_instretl}} & minstretl_read[31:0]) | + ({32{csr_instreth}} & minstreth_read[31:0]) | + ({32{csr_hpmc3}} & mhpmc3[31:0]) | + ({32{csr_hpmc4}} & mhpmc4[31:0]) | + ({32{csr_hpmc5}} & mhpmc5[31:0]) | + ({32{csr_hpmc6}} & mhpmc6[31:0]) | + ({32{csr_hpmc3h}} & mhpmc3h[31:0]) | + ({32{csr_hpmc4h}} & mhpmc4h[31:0]) | + ({32{csr_hpmc5h}} & mhpmc5h[31:0]) | + ({32{csr_hpmc6h}} & mhpmc6h[31:0]) | + ({32{csr_mseccfgl}} & {29'd0, mseccfg}) | + ({32{csr_mseccfgh}} & 32'd0) | // All bits are WPRI +`endif + ({32{csr_mcountinhibit}} & {25'b0, mcountinhibit[6:0]}) | + ({32{csr_mpmc}} & {30'b0, mpmc[1], 1'b0}) | + ({32{dec_timer_read_d}} & dec_timer_rddata_d[31:0]) | + ({32{dec_pmp_read_d}} & dec_pmp_rddata_d[31:0]) + ); + + + +endmodule // el2_dec_tlu_ctl + +module el2_dec_timer_ctl +import el2_pkg::*; +#( +`include "el2_param.vh" + ) + ( + input logic clk, + input logic free_l2clk, + input logic csr_wr_clk, + input logic rst_l, + input logic dec_csr_wen_r_mod, // csr write enable at wb + input logic [11:0] dec_csr_wraddr_r, // write address for csr + input logic [31:0] dec_csr_wrdata_r, // csr write data at wb + + input logic csr_mitctl0, + input logic csr_mitctl1, + input logic csr_mitb0, + input logic csr_mitb1, + input logic csr_mitcnt0, + input logic csr_mitcnt1, + + + input logic dec_pause_state, // Paused + input logic dec_tlu_pmu_fw_halted, // pmu/fw halted + input logic internal_dbg_halt_timers, // debug halted + + output logic [31:0] dec_timer_rddata_d, // timer CSR read data + output logic dec_timer_read_d, // timer CSR address match + output logic dec_timer_t0_pulse, // timer0 int + output logic dec_timer_t1_pulse, // timer1 int + + // Excluding scan_mode from coverage as its usage is determined by the integrator of the VeeR core. + /*pragma coverage off*/ + input logic scan_mode + /*pragma coverage on*/ + ); + localparam MITCTL_ENABLE = 0; + localparam MITCTL_ENABLE_HALTED = 1; + localparam MITCTL_ENABLE_PAUSED = 2; + + logic [31:0] mitcnt0_ns, mitcnt0, mitcnt1_ns, mitcnt1, mitb0, mitb1, mitb0_b, mitb1_b, mitcnt0_inc, mitcnt1_inc; + logic [2:0] mitctl0_ns, mitctl0; + logic [3:0] mitctl1_ns, mitctl1; + logic wr_mitcnt0_r, wr_mitcnt1_r, wr_mitb0_r, wr_mitb1_r, wr_mitctl0_r, wr_mitctl1_r; + logic mitcnt0_inc_ok, mitcnt1_inc_ok; + logic mitcnt0_inc_cout, mitcnt1_inc_cout; + logic mit0_match_ns; + logic mit1_match_ns; + logic mitctl0_0_b_ns; + logic mitctl0_0_b; + logic mitctl1_0_b_ns; + logic mitctl1_0_b; + + assign mit0_match_ns = (mitcnt0[31:0] >= mitb0[31:0]); + assign mit1_match_ns = (mitcnt1[31:0] >= mitb1[31:0]); + + assign dec_timer_t0_pulse = mit0_match_ns; + assign dec_timer_t1_pulse = mit1_match_ns; + // ---------------------------------------------------------------------- + // MITCNT0 (RW) + // [31:0] : Internal Timer Counter 0 + + localparam MITCNT0 = 12'h7d2; + + assign wr_mitcnt0_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MITCNT0); + + assign mitcnt0_inc_ok = mitctl0[MITCTL_ENABLE] & (~dec_pause_state | mitctl0[MITCTL_ENABLE_PAUSED]) & (~dec_tlu_pmu_fw_halted | mitctl0[MITCTL_ENABLE_HALTED]) & ~internal_dbg_halt_timers; + + assign {mitcnt0_inc_cout, mitcnt0_inc[7:0]} = mitcnt0[7:0] + {7'b0, 1'b1}; + assign mitcnt0_inc[31:8] = mitcnt0[31:8] + {23'b0, mitcnt0_inc_cout}; + + assign mitcnt0_ns[31:0] = wr_mitcnt0_r ? dec_csr_wrdata_r[31:0] : mit0_match_ns ? 'b0 : mitcnt0_inc[31:0]; + + rvdffe #(24) mitcnt0_ffb (.*, .clk(free_l2clk), .en(wr_mitcnt0_r | (mitcnt0_inc_ok & mitcnt0_inc_cout) | mit0_match_ns), .din(mitcnt0_ns[31:8]), .dout(mitcnt0[31:8])); + rvdffe #(8) mitcnt0_ffa (.*, .clk(free_l2clk), .en(wr_mitcnt0_r | mitcnt0_inc_ok | mit0_match_ns), .din(mitcnt0_ns[7:0]), .dout(mitcnt0[7:0])); + + // ---------------------------------------------------------------------- + // MITCNT1 (RW) + // [31:0] : Internal Timer Counter 0 + + localparam MITCNT1 = 12'h7d5; + + assign wr_mitcnt1_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MITCNT1); + + assign mitcnt1_inc_ok = mitctl1[MITCTL_ENABLE] & + (~dec_pause_state | mitctl1[MITCTL_ENABLE_PAUSED]) & + (~dec_tlu_pmu_fw_halted | mitctl1[MITCTL_ENABLE_HALTED]) & + ~internal_dbg_halt_timers & + (~mitctl1[3] | mit0_match_ns); + + // only inc MITCNT1 if not cascaded with 0, or if 0 overflows + assign {mitcnt1_inc_cout, mitcnt1_inc[7:0]} = mitcnt1[7:0] + {7'b0, 1'b1}; + assign mitcnt1_inc[31:8] = mitcnt1[31:8] + {23'b0, mitcnt1_inc_cout}; + + assign mitcnt1_ns[31:0] = wr_mitcnt1_r ? dec_csr_wrdata_r[31:0] : mit1_match_ns ? 'b0 : mitcnt1_inc[31:0]; + + rvdffe #(24) mitcnt1_ffb (.*, .clk(free_l2clk), .en(wr_mitcnt1_r | (mitcnt1_inc_ok & mitcnt1_inc_cout) | mit1_match_ns), .din(mitcnt1_ns[31:8]), .dout(mitcnt1[31:8])); + rvdffe #(8) mitcnt1_ffa (.*, .clk(free_l2clk), .en(wr_mitcnt1_r | mitcnt1_inc_ok | mit1_match_ns), .din(mitcnt1_ns[7:0]), .dout(mitcnt1[7:0])); + + + // ---------------------------------------------------------------------- + // MITB0 (RW) + // [31:0] : Internal Timer Bound 0 + + localparam MITB0 = 12'h7d3; + + assign wr_mitb0_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MITB0); + + rvdffe #(32) mitb0_ff (.*, .en(wr_mitb0_r), .din(~dec_csr_wrdata_r[31:0]), .dout(mitb0_b[31:0])); + assign mitb0[31:0] = ~mitb0_b[31:0]; + + // ---------------------------------------------------------------------- + // MITB1 (RW) + // [31:0] : Internal Timer Bound 1 + + localparam MITB1 = 12'h7d6; + + assign wr_mitb1_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MITB1); + + rvdffe #(32) mitb1_ff (.*, .en(wr_mitb1_r), .din(~dec_csr_wrdata_r[31:0]), .dout(mitb1_b[31:0])); + assign mitb1[31:0] = ~mitb1_b[31:0]; + + // ---------------------------------------------------------------------- + // MITCTL0 (RW) Internal Timer Ctl 0 + // [31:3] : Reserved, reads 0x0 + // [2] : Enable while PAUSEd + // [1] : Enable while HALTed + // [0] : Enable (resets to 0x1) + + localparam MITCTL0 = 12'h7d4; + + assign wr_mitctl0_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MITCTL0); + assign mitctl0_ns[2:0] = wr_mitctl0_r ? {dec_csr_wrdata_r[2:0]} : {mitctl0[2:0]}; + + assign mitctl0_0_b_ns = ~mitctl0_ns[0]; + rvdffs #(3) mitctl0_ff (.*, .clk(csr_wr_clk), .en(wr_mitctl0_r), .din({mitctl0_ns[2:1], mitctl0_0_b_ns}), .dout({mitctl0[2:1], mitctl0_0_b})); + assign mitctl0[0] = ~mitctl0_0_b; + + // ---------------------------------------------------------------------- + // MITCTL1 (RW) Internal Timer Ctl 1 + // [31:4] : Reserved, reads 0x0 + // [3] : Cascade + // [2] : Enable while PAUSEd + // [1] : Enable while HALTed + // [0] : Enable (resets to 0x1) + + localparam MITCTL1 = 12'h7d7; + + assign wr_mitctl1_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MITCTL1); + assign mitctl1_ns[3:0] = wr_mitctl1_r ? {dec_csr_wrdata_r[3:0]} : {mitctl1[3:0]}; + + assign mitctl1_0_b_ns = ~mitctl1_ns[0]; + rvdffs #(4) mitctl1_ff (.*, .clk(csr_wr_clk), .en(wr_mitctl1_r), .din({mitctl1_ns[3:1], mitctl1_0_b_ns}), .dout({mitctl1[3:1], mitctl1_0_b})); + assign mitctl1[0] = ~mitctl1_0_b; + assign dec_timer_read_d = csr_mitcnt1 | csr_mitcnt0 | csr_mitb1 | csr_mitb0 | csr_mitctl0 | csr_mitctl1; + assign dec_timer_rddata_d[31:0] = ( ({32{csr_mitcnt0}} & mitcnt0[31:0]) | + ({32{csr_mitcnt1}} & mitcnt1[31:0]) | + ({32{csr_mitb0}} & mitb0[31:0]) | + ({32{csr_mitb1}} & mitb1[31:0]) | + ({32{csr_mitctl0}} & {29'b0, mitctl0[2:0]}) | + ({32{csr_mitctl1}} & {28'b0, mitctl1[3:0]}) + ); + + +endmodule // dec_timer_ctl \ No newline at end of file diff --git a/designs/Caliptra/src/caliptra-rtl/el2_dec_trigger.sv b/designs/Caliptra/src/caliptra-rtl/el2_dec_trigger.sv new file mode 100644 index 0000000..e078d03 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/el2_dec_trigger.sv @@ -0,0 +1,49 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2020 Western Digital Corporation or its affiliates. +// +// 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. + +//******************************************************************************** +// $Id$ +// +// +// Owner: +// Function: DEC Trigger Logic +// Comments: +// +//******************************************************************************** +module el2_dec_trigger +import el2_pkg::*; +#( +`include "el2_param.vh" + )( + + input el2_trigger_pkt_t [3:0] trigger_pkt_any, // Packet from tlu. 'select':0-pc,1-Opcode 'Execute' needs to be set for dec triggers to fire. 'match'-1 do mask, 0: full match + input logic [31:1] dec_i0_pc_d, // i0 pc + + output logic [3:0] dec_i0_trigger_match_d // Trigger match +); + + logic [3:0][31:0] dec_i0_match_data; + logic [3:0] dec_i0_trigger_data_match; + + for (genvar i=0; i<4; i++) begin : genblock + assign dec_i0_match_data[i][31:0] = ({32{~trigger_pkt_any[i].select & trigger_pkt_any[i].execute}} & {dec_i0_pc_d[31:1], trigger_pkt_any[i].tdata2[0]}); // select=0; do a PC match + + rvmaskandmatch trigger_i0_match (.mask(trigger_pkt_any[i].tdata2[31:0]), .data(dec_i0_match_data[i][31:0]), .masken(trigger_pkt_any[i].match), .match(dec_i0_trigger_data_match[i])); + + assign dec_i0_trigger_match_d[i] = trigger_pkt_any[i].execute & trigger_pkt_any[i].m & dec_i0_trigger_data_match[i]; + end + +endmodule // el2_dec_trigger + diff --git a/designs/Caliptra/src/caliptra-rtl/el2_def.sv b/designs/Caliptra/src/caliptra-rtl/el2_def.sv new file mode 100644 index 0000000..eec1d9d --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/el2_def.sv @@ -0,0 +1,457 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright (c) 2023 Antmicro +// +// 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. + +// performance monitor stuff +//`ifndef EL2_DEF_SV +//`define EL2_DEF_SV +package el2_pkg; + +`include "el2_pdef.vh" + +typedef struct packed { + logic trace_rv_i_valid_ip; + logic [31:0] trace_rv_i_insn_ip; + logic [31:0] trace_rv_i_address_ip; + logic trace_rv_i_exception_ip; + logic [4:0] trace_rv_i_ecause_ip; + logic trace_rv_i_interrupt_ip; + logic [31:0] trace_rv_i_tval_ip; + } el2_trace_pkt_t; + + +typedef enum logic [3:0] { + NULL_OP = 4'b0000, + MUL = 4'b0001, + LOAD = 4'b0010, + STORE = 4'b0011, + ALU = 4'b0100, + CSRREAD = 4'b0101, + CSRWRITE = 4'b0110, + CSRRW = 4'b0111, + EBREAK = 4'b1000, + ECALL = 4'b1001, + FENCE = 4'b1010, + FENCEI = 4'b1011, + MRET = 4'b1100, + CONDBR = 4'b1101, + JAL = 4'b1110, + BITMANIPU = 4'b1111 + } el2_inst_pkt_t; + +typedef struct packed { + logic valid; + logic wb; + logic [2:0] tag; + logic [4:0] rd; + } el2_load_cam_pkt_t; + +typedef struct packed { + logic pc0_call; + logic pc0_ret; + logic pc0_pc4; + } el2_rets_pkt_t; +typedef struct packed { + logic valid; + logic [11:0] toffset; + logic [1:0] hist; + logic br_error; + logic br_start_error; + logic bank; + logic [31:1] prett; // predicted ret target + logic way; + logic ret; + } el2_br_pkt_t; + +typedef struct packed { + logic valid; + logic [1:0] hist; + logic br_error; + logic br_start_error; + logic way; + logic middle; + } el2_br_tlu_pkt_t; + +typedef struct packed { + logic misp; + logic ataken; + logic boffset; + logic pc4; + logic [1:0] hist; + logic [11:0] toffset; + logic valid; + logic br_error; + logic br_start_error; + logic pcall; + logic pja; + logic way; + logic pret; + // for power use the pret bit to clock the prett field + logic [31:1] prett; + } el2_predict_pkt_t; + +typedef struct packed { + // unlikely to change + logic icaf; + logic icaf_second; + logic [1:0] icaf_type; + logic fence_i; + logic [3:0] i0trigger; + logic pmu_i0_br_unpred; // pmu + logic pmu_divide; + // likely to change + logic legal; + logic pmu_lsu_misaligned; + el2_inst_pkt_t pmu_i0_itype; // pmu - instruction type + } el2_trap_pkt_t; + +typedef struct packed { + // unlikely to change + logic i0div; + logic csrwen; + logic csrwonly; + logic [11:0] csraddr; + // likely to change + logic [4:0] i0rd; + logic i0load; + logic i0store; + logic i0v; + logic i0valid; + } el2_dest_pkt_t; + +typedef struct packed { + logic mul; + logic load; + logic alu; + } el2_class_pkt_t; + +typedef struct packed { + logic [4:0] rs1; + logic [4:0] rs2; + logic [4:0] rd; + } el2_reg_pkt_t; + + +typedef struct packed { + logic clz; + logic ctz; + logic cpop; + logic sext_b; + logic sext_h; + logic min; + logic max; + logic pack; + logic packu; + logic packh; + logic rol; + logic ror; + logic grev; + logic gorc; + logic zbb; + logic bset; + logic bclr; + logic binv; + logic bext; + logic sh1add; + logic sh2add; + logic sh3add; + logic zba; + logic land; + logic lor; + logic lxor; + logic sll; + logic srl; + logic sra; + logic beq; + logic bne; + logic blt; + logic bge; + logic add; + logic sub; + logic slt; + logic unsign; + logic jal; + logic predict_t; + logic predict_nt; + logic csr_write; + logic csr_imm; + } el2_alu_pkt_t; + +typedef struct packed { + logic fast_int; +/* verilator lint_off SYMRSVDWORD */ + logic stack; +/* verilator lint_on SYMRSVDWORD */ + logic by; + logic half; + logic word; + logic dword; // for dma + logic load; + logic store; + logic unsign; + logic dma; // dma pkt + logic store_data_bypass_d; + logic load_ldst_bypass_d; + logic store_data_bypass_m; + logic valid; + } el2_lsu_pkt_t; + +typedef struct packed { + logic inst_type; //0: Load, 1: Store + //logic dma_valid; + logic exc_type; //0: MisAligned, 1: Access Fault + logic [3:0] mscause; + logic [31:0] addr; + logic single_ecc_error; + logic exc_valid; + } el2_lsu_error_pkt_t; + +typedef struct packed { + logic clz; + logic ctz; + logic cpop; + logic sext_b; + logic sext_h; + logic min; + logic max; + logic pack; + logic packu; + logic packh; + logic rol; + logic ror; + logic grev; + logic gorc; + logic zbb; + logic bset; + logic bclr; + logic binv; + logic bext; + logic zbs; + logic bcompress; + logic bdecompress; + logic zbe; + logic clmul; + logic clmulh; + logic clmulr; + logic zbc; + logic shfl; + logic unshfl; + logic xperm_n; + logic xperm_b; + logic xperm_h; + logic zbp; + logic crc32_b; + logic crc32_h; + logic crc32_w; + logic crc32c_b; + logic crc32c_h; + logic crc32c_w; + logic zbr; + logic bfp; + logic zbf; + logic sh1add; + logic sh2add; + logic sh3add; + logic zba; + logic alu; + logic rs1; + logic rs2; + logic imm12; + logic rd; + logic shimm5; + logic imm20; + logic pc; + logic load; + logic store; + logic lsu; + logic add; + logic sub; + logic land; + logic lor; + logic lxor; + logic sll; + logic sra; + logic srl; + logic slt; + logic unsign; + logic condbr; + logic beq; + logic bne; + logic bge; + logic blt; + logic jal; + logic by; + logic half; + logic word; + logic csr_read; + logic csr_clr; + logic csr_set; + logic csr_write; + logic csr_imm; + logic presync; + logic postsync; + logic ebreak; + logic ecall; + logic mret; + logic mul; + logic rs1_sign; + logic rs2_sign; + logic low; + logic div; + logic rem; + logic fence; + logic fence_i; + logic pm_alu; + logic legal; + } el2_dec_pkt_t; + + +typedef struct packed { + logic valid; + logic rs1_sign; + logic rs2_sign; + logic low; + logic bcompress; + logic bdecompress; + logic clmul; + logic clmulh; + logic clmulr; + logic grev; + logic gorc; + logic shfl; + logic unshfl; + logic crc32_b; + logic crc32_h; + logic crc32_w; + logic crc32c_b; + logic crc32c_h; + logic crc32c_w; + logic bfp; + logic xperm_n; + logic xperm_b; + logic xperm_h; + } el2_mul_pkt_t; + +typedef struct packed { + logic valid; + logic unsign; + logic rem; + } el2_div_pkt_t; + +typedef struct packed { + logic TEST1; + logic RME; + logic [3:0] RM; + + logic LS; + logic DS; + logic SD; + logic TEST_RNM; + logic BC1; + logic BC2; + } el2_ccm_ext_in_pkt_t; + +typedef struct packed { + logic TEST1; + logic RME; + logic [3:0] RM; + logic LS; + logic DS; + logic SD; + logic TEST_RNM; + logic BC1; + logic BC2; + } el2_dccm_ext_in_pkt_t; + + +typedef struct packed { + logic TEST1; + logic RME; + logic [3:0] RM; + logic LS; + logic DS; + logic SD; + logic TEST_RNM; + logic BC1; + logic BC2; + } el2_ic_data_ext_in_pkt_t; + + +typedef struct packed { + logic TEST1; + logic RME; + logic [3:0] RM; + logic LS; + logic DS; + logic SD; + logic TEST_RNM; + logic BC1; + logic BC2; + } el2_ic_tag_ext_in_pkt_t; + + + +typedef struct packed { + logic select; + logic match; + logic store; + logic load; + logic execute; + logic m; + logic [31:0] tdata2; + } el2_trigger_pkt_t; + + +typedef struct packed { + logic [70:0] icache_wrdata; // {dicad1[1:0], dicad0h[31:0], dicad0[31:0]} + logic [16:0] icache_dicawics; // Arraysel:24, Waysel:21:20, Index:16:3 + logic icache_rd_valid; + logic icache_wr_valid; + } el2_cache_debug_pkt_t; + + + typedef enum logic [2:0] { + NONE = 3'b000, + READ = 3'b001, + WRITE = 3'b010, + EXEC = 3'b100 + } el2_pmp_type_pkt_t; + + + typedef enum logic [1:0] { + OFF = 2'b00, + TOR = 2'b01, + NA4 = 2'b10, + NAPOT = 2'b11 + } el2_pmp_mode_pkt_t; + + + typedef struct packed { + logic lock; + logic [1:0] reserved; + el2_pmp_mode_pkt_t mode; + logic execute; + logic write; + logic read; + } el2_pmp_cfg_pkt_t; + + typedef struct packed { + logic RLB; + logic MMWP; + logic MML; + } el2_mseccfg_pkt_t; + +//`endif + +endpackage // el2_pkg diff --git a/designs/Caliptra/src/caliptra-rtl/el2_dma_ctrl.sv b/designs/Caliptra/src/caliptra-rtl/el2_dma_ctrl.sv new file mode 100644 index 0000000..11b5541 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/el2_dma_ctrl.sv @@ -0,0 +1,643 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2020 Western Digital Corporation or its affiliates. +// +// 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. + +//******************************************************************************** +// $Id$ +// +// Function: Top level VeeR core file +// Comments: +// +//******************************************************************************** + +module el2_dma_ctrl +import el2_pkg::*; +#( +`include "el2_param.vh" + )( + input logic clk, + input logic free_clk, + input logic rst_l, + input logic dma_bus_clk_en, // slave bus clock enable + input logic clk_override, + // Excluding scan_mode from coverage as its usage is determined by the integrator of the VeeR core. + /*pragma coverage off*/ + input logic scan_mode, + /*pragma coverage on*/ + + // Debug signals + input logic [31:0] dbg_cmd_addr, + input logic [31:0] dbg_cmd_wrdata, + input logic dbg_cmd_valid, + input logic dbg_cmd_write, // 1: write command, 0: read_command + input logic [1:0] dbg_cmd_type, // 0:gpr 1:csr 2: memory + input logic [1:0] dbg_cmd_size, // size of the abstract mem access debug command + + input logic dbg_dma_bubble, // Debug needs a bubble to send a valid + output logic dma_dbg_ready, // DMA is ready to accept debug request + + output logic dma_dbg_cmd_done, + output logic dma_dbg_cmd_fail, + output logic [31:0] dma_dbg_rddata, + + // Core side signals + output logic dma_dccm_req, // DMA dccm request (only one of dccm/iccm will be set) + output logic dma_iccm_req, // DMA iccm request + output logic [2:0] dma_mem_tag, // DMA Buffer entry number + output logic [31:0] dma_mem_addr, // DMA request address + output logic [2:0] dma_mem_sz, // DMA request size + output logic dma_mem_write, // DMA write to dccm/iccm + output logic [63:0] dma_mem_wdata, // DMA write data + + input logic dccm_dma_rvalid, // dccm data valid for DMA read + input logic dccm_dma_ecc_error, // ECC error on DMA read + input logic [2:0] dccm_dma_rtag, // Tag of the DMA req + input logic [63:0] dccm_dma_rdata, // dccm data for DMA read + input logic iccm_dma_rvalid, // iccm data valid for DMA read + input logic iccm_dma_ecc_error, // ECC error on DMA read + input logic [2:0] iccm_dma_rtag, // Tag of the DMA req + input logic [63:0] iccm_dma_rdata, // iccm data for DMA read + + output logic dma_active, // DMA is busy + output logic dma_dccm_stall_any, // stall dccm pipe (bubble) so that DMA can proceed + output logic dma_iccm_stall_any, // stall iccm pipe (bubble) so that DMA can proceed + input logic dccm_ready, // dccm ready to accept DMA request + input logic iccm_ready, // iccm ready to accept DMA request + input logic [2:0] dec_tlu_dma_qos_prty, // DMA QoS priority coming from MFDC [18:15] + + // PMU signals + output logic dma_pmu_dccm_read, + output logic dma_pmu_dccm_write, + output logic dma_pmu_any_read, + output logic dma_pmu_any_write, + + // AXI Write Channels + input logic dma_axi_awvalid, + output logic dma_axi_awready, + input logic [pt.DMA_BUS_TAG-1:0] dma_axi_awid, + input logic [31:0] dma_axi_awaddr, + input logic [2:0] dma_axi_awsize, + + + input logic dma_axi_wvalid, + output logic dma_axi_wready, + input logic [63:0] dma_axi_wdata, + input logic [7:0] dma_axi_wstrb, + + output logic dma_axi_bvalid, + input logic dma_axi_bready, + output logic [1:0] dma_axi_bresp, + output logic [pt.DMA_BUS_TAG-1:0] dma_axi_bid, + + // AXI Read Channels + input logic dma_axi_arvalid, + output logic dma_axi_arready, + input logic [pt.DMA_BUS_TAG-1:0] dma_axi_arid, + input logic [31:0] dma_axi_araddr, + input logic [2:0] dma_axi_arsize, + + output logic dma_axi_rvalid, + input logic dma_axi_rready, + output logic [pt.DMA_BUS_TAG-1:0] dma_axi_rid, + output logic [63:0] dma_axi_rdata, + output logic [1:0] dma_axi_rresp, + output logic dma_axi_rlast +); + + + localparam DEPTH = pt.DMA_BUF_DEPTH; + localparam DEPTH_PTR = $clog2(DEPTH); + localparam NACK_COUNT = 7; + + logic [DEPTH-1:0] fifo_valid; + logic [DEPTH-1:0][1:0] fifo_error; + logic [DEPTH-1:0] fifo_error_bus; + logic [DEPTH-1:0] fifo_rpend; + logic [DEPTH-1:0] fifo_done; // DMA trxn is done in core + logic [DEPTH-1:0] fifo_done_bus; // DMA trxn is done in core but synced to bus clock + logic [DEPTH-1:0][31:0] fifo_addr; + logic [DEPTH-1:0][2:0] fifo_sz; + logic [DEPTH-1:0][7:0] fifo_byteen; + logic [DEPTH-1:0] fifo_write; + logic [DEPTH-1:0] fifo_posted_write; + logic [DEPTH-1:0] fifo_dbg; + logic [DEPTH-1:0][63:0] fifo_data; + logic [DEPTH-1:0][pt.DMA_BUS_TAG-1:0] fifo_tag; + logic [DEPTH-1:0][pt.DMA_BUS_ID-1:0] fifo_mid; + logic [DEPTH-1:0][pt.DMA_BUS_PRTY-1:0] fifo_prty; + + logic [DEPTH-1:0] fifo_cmd_en; + logic [DEPTH-1:0] fifo_data_en; + logic [DEPTH-1:0] fifo_pend_en; + logic [DEPTH-1:0] fifo_done_en; + logic [DEPTH-1:0] fifo_done_bus_en; + logic [DEPTH-1:0] fifo_error_en; + logic [DEPTH-1:0] fifo_error_bus_en; + logic [DEPTH-1:0] fifo_reset; + logic [DEPTH-1:0][1:0] fifo_error_in; + logic [DEPTH-1:0][63:0] fifo_data_in; + + logic fifo_write_in; + logic fifo_posted_write_in; + logic fifo_dbg_in; + logic [31:0] fifo_addr_in; + logic [2:0] fifo_sz_in; + logic [7:0] fifo_byteen_in; + + logic [DEPTH_PTR-1:0] RspPtr, NxtRspPtr; + logic [DEPTH_PTR-1:0] WrPtr, NxtWrPtr; + logic [DEPTH_PTR-1:0] RdPtr, NxtRdPtr; + logic WrPtrEn, RdPtrEn, RspPtrEn; + + logic [1:0] dma_dbg_sz; + logic [1:0] dma_dbg_addr; + logic [31:0] dma_dbg_mem_rddata; + logic [31:0] dma_dbg_mem_wrdata; + logic dma_dbg_cmd_error; + logic dma_dbg_cmd_done_q; + + logic fifo_full, fifo_full_spec, fifo_empty; + logic dma_address_error, dma_alignment_error; + logic [3:0] num_fifo_vld; + logic dma_mem_req; + logic [31:0] dma_mem_addr_int; + logic [2:0] dma_mem_sz_int; + logic [7:0] dma_mem_byteen; + logic dma_mem_addr_in_dccm; + logic dma_mem_addr_in_iccm; + logic dma_mem_addr_in_pic; + logic dma_mem_addr_in_pic_region_nc; + logic dma_mem_addr_in_dccm_region_nc; + logic dma_mem_addr_in_iccm_region_nc; + + logic [2:0] dma_nack_count, dma_nack_count_d, dma_nack_count_csr; + + logic dma_buffer_c1_clken; + logic dma_free_clken; + logic dma_buffer_c1_clk; + logic dma_free_clk; + logic dma_bus_clk; + + logic bus_rsp_valid, bus_rsp_sent; + logic bus_cmd_valid, bus_cmd_sent; + logic bus_cmd_write, bus_cmd_posted_write; + logic [7:0] bus_cmd_byteen; + logic [2:0] bus_cmd_sz; + logic [31:0] bus_cmd_addr; + logic [63:0] bus_cmd_wdata; + logic [pt.DMA_BUS_TAG-1:0] bus_cmd_tag; + logic [pt.DMA_BUS_ID-1:0] bus_cmd_mid; + logic [pt.DMA_BUS_PRTY-1:0] bus_cmd_prty; + logic bus_posted_write_done; + + logic fifo_full_spec_bus; + logic dbg_dma_bubble_bus; + logic stall_dma_in; + logic dma_fifo_ready; + + logic wrbuf_en, wrbuf_data_en; + logic wrbuf_cmd_sent, wrbuf_rst, wrbuf_data_rst; + logic wrbuf_vld, wrbuf_data_vld; + logic [pt.DMA_BUS_TAG-1:0] wrbuf_tag; + logic [2:0] wrbuf_sz; + logic [31:0] wrbuf_addr; + logic [63:0] wrbuf_data; + logic [7:0] wrbuf_byteen; + + logic rdbuf_en; + logic rdbuf_cmd_sent, rdbuf_rst; + logic rdbuf_vld; + logic [pt.DMA_BUS_TAG-1:0] rdbuf_tag; + logic [2:0] rdbuf_sz; + logic [31:0] rdbuf_addr; + + logic axi_mstr_prty_in, axi_mstr_prty_en; + logic axi_mstr_priority; + logic axi_mstr_sel; + + logic axi_rsp_valid, axi_rsp_sent; + logic axi_rsp_write; + logic [pt.DMA_BUS_TAG-1:0] axi_rsp_tag; + logic [1:0] axi_rsp_error; + logic [63:0] axi_rsp_rdata; + + //------------------------LOGIC STARTS HERE--------------------------------- + + // FIFO inputs + assign fifo_addr_in[31:0] = dbg_cmd_valid ? dbg_cmd_addr[31:0] : bus_cmd_addr[31:0]; + assign fifo_byteen_in[7:0] = {8{~dbg_cmd_valid}} & bus_cmd_byteen[7:0]; // Byte enable is used only for bus requests + assign fifo_sz_in[2:0] = dbg_cmd_valid ? {1'b0,dbg_cmd_size[1:0]} : bus_cmd_sz[2:0]; + assign fifo_write_in = dbg_cmd_valid ? dbg_cmd_write : bus_cmd_write; + assign fifo_posted_write_in = ~dbg_cmd_valid & bus_cmd_posted_write; + assign fifo_dbg_in = dbg_cmd_valid; + + for (genvar i=0 ;i= DEPTH); + + assign dma_fifo_ready = ~(fifo_full | dbg_dma_bubble_bus); + + // Error logic + assign dma_address_error = fifo_valid[RdPtr] & ~fifo_done[RdPtr] & ~fifo_dbg[RdPtr] & (~(dma_mem_addr_in_dccm | dma_mem_addr_in_iccm)); // request not for ICCM or DCCM + assign dma_alignment_error = fifo_valid[RdPtr] & ~fifo_done[RdPtr] & ~fifo_dbg[RdPtr] & ~dma_address_error & + (((dma_mem_sz_int[2:0] == 3'h1) & dma_mem_addr_int[0]) | // HW size but unaligned + ((dma_mem_sz_int[2:0] == 3'h2) & (|dma_mem_addr_int[1:0])) | // W size but unaligned + ((dma_mem_sz_int[2:0] == 3'h3) & (|dma_mem_addr_int[2:0])) | // DW size but unaligned + (dma_mem_addr_in_iccm & ~((dma_mem_sz_int[1:0] == 2'b10) | (dma_mem_sz_int[1:0] == 2'b11))) | // ICCM access not word size + (dma_mem_addr_in_dccm & dma_mem_write & ~((dma_mem_sz_int[1:0] == 2'b10) | (dma_mem_sz_int[1:0] == 2'b11))) | // DCCM write not word size + (dma_mem_write & (dma_mem_sz_int[2:0] == 3'h2) & (dma_mem_addr_int[2:0] == 3'h0) & (dma_mem_byteen[3:0] != 4'hf)) | // Write byte enables not aligned for word store + (dma_mem_write & (dma_mem_sz_int[2:0] == 3'h2) & (dma_mem_addr_int[2:0] == 3'h4) & (dma_mem_byteen[7:4] != 4'hf)) | // Write byte enables not aligned for word store + (dma_mem_write & (dma_mem_sz_int[2:0] == 3'h3) & ~((dma_mem_byteen[7:0] == 8'h0f) | (dma_mem_byteen[7:0] == 8'hf0) | (dma_mem_byteen[7:0] == 8'hff)))); // Write byte enables not aligned for dword store + + + //Dbg outputs + assign dma_dbg_ready = fifo_empty & dbg_dma_bubble; + assign dma_dbg_cmd_done = (fifo_valid[RspPtr] & fifo_dbg[RspPtr] & fifo_done[RspPtr]); + assign dma_dbg_cmd_fail = (|fifo_error[RspPtr] & dma_dbg_cmd_done) ; + + assign dma_dbg_sz[1:0] = fifo_sz[RspPtr][1:0]; + assign dma_dbg_addr[1:0] = fifo_addr[RspPtr][1:0]; + assign dma_dbg_mem_rddata[31:0] = fifo_addr[RspPtr][2] ? fifo_data[RspPtr][63:32] : fifo_data[RspPtr][31:0]; + assign dma_dbg_rddata[31:0] = ({32{(dma_dbg_sz[1:0] == 2'h0)}} & ((dma_dbg_mem_rddata[31:0] >> 8*dma_dbg_addr[1:0]) & 32'hff)) | + ({32{(dma_dbg_sz[1:0] == 2'h1)}} & ((dma_dbg_mem_rddata[31:0] >> 16*dma_dbg_addr[1]) & 32'hffff)) | + ({32{(dma_dbg_sz[1:0] == 2'h2)}} & dma_dbg_mem_rddata[31:0]); + + assign dma_dbg_cmd_error = fifo_valid[RdPtr] & ~fifo_done[RdPtr] & fifo_dbg[RdPtr] & + ((~(dma_mem_addr_in_dccm | dma_mem_addr_in_iccm | dma_mem_addr_in_pic)) | // Address outside of ICCM/DCCM/PIC + ((dma_mem_addr_in_iccm | dma_mem_addr_in_pic) & (dma_mem_sz_int[1:0] != 2'b10))); // Only word accesses allowed for ICCM/PIC + + assign dma_dbg_mem_wrdata[31:0] = ({32{dbg_cmd_size[1:0] == 2'h0}} & {4{dbg_cmd_wrdata[7:0]}}) | + ({32{dbg_cmd_size[1:0] == 2'h1}} & {2{dbg_cmd_wrdata[15:0]}}) | + ({32{dbg_cmd_size[1:0] == 2'h2}} & dbg_cmd_wrdata[31:0]); + + // Block the decode if fifo full + assign dma_dccm_stall_any = dma_mem_req & (dma_mem_addr_in_dccm | dma_mem_addr_in_pic) & (dma_nack_count >= dma_nack_count_csr); + assign dma_iccm_stall_any = dma_mem_req & dma_mem_addr_in_iccm & (dma_nack_count >= dma_nack_count_csr); + + // Used to indicate ready to debug + assign fifo_empty = ~((|(fifo_valid[DEPTH-1:0])) | bus_cmd_sent); + + // Nack counter, stall the lsu pipe if 7 nacks + assign dma_nack_count_csr[2:0] = dec_tlu_dma_qos_prty[2:0]; + assign dma_nack_count_d[2:0] = (dma_nack_count[2:0] >= dma_nack_count_csr[2:0]) ? ({3{~(dma_dccm_req | dma_iccm_req)}} & dma_nack_count[2:0]) : + (dma_mem_req & ~(dma_dccm_req | dma_iccm_req)) ? (dma_nack_count[2:0] + 1'b1) : 3'b0; + + rvdffs #(3) nack_count_dff(.din(dma_nack_count_d[2:0]), .dout(dma_nack_count[2:0]), .en(dma_mem_req), .clk(dma_free_clk), .*); + + // Core outputs + assign dma_mem_req = fifo_valid[RdPtr] & ~fifo_rpend[RdPtr] & ~fifo_done[RdPtr] & ~(dma_address_error | dma_alignment_error | dma_dbg_cmd_error); + assign dma_dccm_req = dma_mem_req & (dma_mem_addr_in_dccm | dma_mem_addr_in_pic) & dccm_ready; + assign dma_iccm_req = dma_mem_req & dma_mem_addr_in_iccm & iccm_ready; + assign dma_mem_tag[2:0] = 3'(RdPtr); + assign dma_mem_addr_int[31:0] = fifo_addr[RdPtr]; + assign dma_mem_sz_int[2:0] = fifo_sz[RdPtr]; + assign dma_mem_addr[31:0] = (dma_mem_write & ~fifo_dbg[RdPtr] & (dma_mem_byteen[7:0] == 8'hf0)) ? {dma_mem_addr_int[31:3],1'b1,dma_mem_addr_int[1:0]} : dma_mem_addr_int[31:0]; + assign dma_mem_sz[2:0] = (dma_mem_write & ~fifo_dbg[RdPtr] & ((dma_mem_byteen[7:0] == 8'h0f) | (dma_mem_byteen[7:0] == 8'hf0))) ? 3'h2 : dma_mem_sz_int[2:0]; + assign dma_mem_byteen[7:0] = fifo_byteen[RdPtr]; + assign dma_mem_write = fifo_write[RdPtr]; + assign dma_mem_wdata[63:0] = fifo_data[RdPtr]; + + // PMU outputs + assign dma_pmu_dccm_read = dma_dccm_req & ~dma_mem_write; + assign dma_pmu_dccm_write = dma_dccm_req & dma_mem_write; + assign dma_pmu_any_read = (dma_dccm_req | dma_iccm_req) & ~dma_mem_write; + assign dma_pmu_any_write = (dma_dccm_req | dma_iccm_req) & dma_mem_write; + + // Address check dccm + if (pt.DCCM_ENABLE) begin: Gen_dccm_enable + rvrangecheck #(.CCM_SADR(pt.DCCM_SADR), + .CCM_SIZE(pt.DCCM_SIZE)) addr_dccm_rangecheck ( + .addr(dma_mem_addr_int[31:0]), + .in_range(dma_mem_addr_in_dccm), + .in_region(dma_mem_addr_in_dccm_region_nc) + ); + end else begin: Gen_dccm_disable + assign dma_mem_addr_in_dccm = '0; + assign dma_mem_addr_in_dccm_region_nc = '0; + end // else: !if(pt.ICCM_ENABLE) + + // Address check iccm + if (pt.ICCM_ENABLE) begin: Gen_iccm_enable + rvrangecheck #(.CCM_SADR(pt.ICCM_SADR), + .CCM_SIZE(pt.ICCM_SIZE)) addr_iccm_rangecheck ( + .addr(dma_mem_addr_int[31:0]), + .in_range(dma_mem_addr_in_iccm), + .in_region(dma_mem_addr_in_iccm_region_nc) + ); + end else begin: Gen_iccm_disable + assign dma_mem_addr_in_iccm = '0; + assign dma_mem_addr_in_iccm_region_nc = '0; + end // else: !if(pt.ICCM_ENABLE) + + + // PIC memory address check + rvrangecheck #(.CCM_SADR(pt.PIC_BASE_ADDR), + .CCM_SIZE(pt.PIC_SIZE)) addr_pic_rangecheck ( + .addr(dma_mem_addr_int[31:0]), + .in_range(dma_mem_addr_in_pic), + .in_region(dma_mem_addr_in_pic_region_nc) + ); + + // Inputs + rvdff_fpga #(1) fifo_full_bus_ff (.din(fifo_full_spec), .dout(fifo_full_spec_bus), .clk(dma_bus_clk), .clken(dma_bus_clk_en), .rawclk(clk), .*); + rvdff_fpga #(1) dbg_dma_bubble_ff (.din(dbg_dma_bubble), .dout(dbg_dma_bubble_bus), .clk(dma_bus_clk), .clken(dma_bus_clk_en), .rawclk(clk), .*); + rvdff #(1) dma_dbg_cmd_doneff (.din(dma_dbg_cmd_done), .dout(dma_dbg_cmd_done_q), .clk(free_clk), .*); + + // Clock Gating logic + assign dma_buffer_c1_clken = (bus_cmd_valid & dma_bus_clk_en) | dbg_cmd_valid | clk_override; + assign dma_free_clken = (bus_cmd_valid | bus_rsp_valid | dbg_cmd_valid | dma_dbg_cmd_done | dma_dbg_cmd_done_q | (|fifo_valid[DEPTH-1:0]) | clk_override); + + rvoclkhdr dma_buffer_c1cgc ( .en(dma_buffer_c1_clken), .l1clk(dma_buffer_c1_clk), .* ); + rvoclkhdr dma_free_cgc (.en(dma_free_clken), .l1clk(dma_free_clk), .*); + +`ifdef RV_FPGA_OPTIMIZE + assign dma_bus_clk = 1'b0; +`else + rvclkhdr dma_bus_cgc (.en(dma_bus_clk_en), .l1clk(dma_bus_clk), .*); +`endif + + // Write channel buffer + assign wrbuf_en = dma_axi_awvalid & dma_axi_awready; + assign wrbuf_data_en = dma_axi_wvalid & dma_axi_wready; + assign wrbuf_cmd_sent = bus_cmd_sent & bus_cmd_write; + assign wrbuf_rst = wrbuf_cmd_sent & ~wrbuf_en; + assign wrbuf_data_rst = wrbuf_cmd_sent & ~wrbuf_data_en; + + rvdffsc_fpga #(.WIDTH(1)) wrbuf_vldff (.din(1'b1), .dout(wrbuf_vld), .en(wrbuf_en), .clear(wrbuf_rst), .clk(dma_bus_clk), .clken(dma_bus_clk_en), .rawclk(clk), .*); + rvdffsc_fpga #(.WIDTH(1)) wrbuf_data_vldff (.din(1'b1), .dout(wrbuf_data_vld), .en(wrbuf_data_en), .clear(wrbuf_data_rst), .clk(dma_bus_clk), .clken(dma_bus_clk_en), .rawclk(clk), .*); + rvdffs_fpga #(.WIDTH(pt.DMA_BUS_TAG)) wrbuf_tagff (.din(dma_axi_awid[pt.DMA_BUS_TAG-1:0]), .dout(wrbuf_tag[pt.DMA_BUS_TAG-1:0]), .en(wrbuf_en), .clk(dma_bus_clk), .clken(dma_bus_clk_en), .rawclk(clk), .*); + rvdffs_fpga #(.WIDTH(3)) wrbuf_szff (.din(dma_axi_awsize[2:0]), .dout(wrbuf_sz[2:0]), .en(wrbuf_en), .clk(dma_bus_clk), .clken(dma_bus_clk_en), .rawclk(clk), .*); + rvdffe #(.WIDTH(32)) wrbuf_addrff (.din(dma_axi_awaddr[31:0]), .dout(wrbuf_addr[31:0]), .en(wrbuf_en & dma_bus_clk_en), .*); + rvdffe #(.WIDTH(64)) wrbuf_dataff (.din(dma_axi_wdata[63:0]), .dout(wrbuf_data[63:0]), .en(wrbuf_data_en & dma_bus_clk_en), .*); + rvdffs_fpga #(.WIDTH(8)) wrbuf_byteenff (.din(dma_axi_wstrb[7:0]), .dout(wrbuf_byteen[7:0]), .en(wrbuf_data_en), .clk(dma_bus_clk), .clken(dma_bus_clk_en), .rawclk(clk), .*); + + // Read channel buffer + assign rdbuf_en = dma_axi_arvalid & dma_axi_arready; + assign rdbuf_cmd_sent = bus_cmd_sent & ~bus_cmd_write; + assign rdbuf_rst = rdbuf_cmd_sent & ~rdbuf_en; + + rvdffsc_fpga #(.WIDTH(1)) rdbuf_vldff (.din(1'b1), .dout(rdbuf_vld), .en(rdbuf_en), .clear(rdbuf_rst), .clk(dma_bus_clk), .clken(dma_bus_clk_en), .rawclk(clk), .*); + rvdffs_fpga #(.WIDTH(pt.DMA_BUS_TAG)) rdbuf_tagff (.din(dma_axi_arid[pt.DMA_BUS_TAG-1:0]), .dout(rdbuf_tag[pt.DMA_BUS_TAG-1:0]), .en(rdbuf_en), .clk(dma_bus_clk), .clken(dma_bus_clk_en), .rawclk(clk), .*); + rvdffs_fpga #(.WIDTH(3)) rdbuf_szff (.din(dma_axi_arsize[2:0]), .dout(rdbuf_sz[2:0]), .en(rdbuf_en), .clk(dma_bus_clk), .clken(dma_bus_clk_en), .rawclk(clk), .*); + rvdffe #(.WIDTH(32)) rdbuf_addrff (.din(dma_axi_araddr[31:0]), .dout(rdbuf_addr[31:0]), .en(rdbuf_en & dma_bus_clk_en), .*); + + assign dma_axi_awready = ~(wrbuf_vld & ~wrbuf_cmd_sent); + assign dma_axi_wready = ~(wrbuf_data_vld & ~wrbuf_cmd_sent); + assign dma_axi_arready = ~(rdbuf_vld & ~rdbuf_cmd_sent); + + //Generate a single request from read/write channel + assign bus_cmd_valid = (wrbuf_vld & wrbuf_data_vld) | rdbuf_vld; + assign bus_cmd_sent = bus_cmd_valid & dma_fifo_ready; + assign bus_cmd_write = axi_mstr_sel; + assign bus_cmd_posted_write = '0; + assign bus_cmd_addr[31:0] = axi_mstr_sel ? wrbuf_addr[31:0] : rdbuf_addr[31:0]; + assign bus_cmd_sz[2:0] = axi_mstr_sel ? wrbuf_sz[2:0] : rdbuf_sz[2:0]; + assign bus_cmd_wdata[63:0] = wrbuf_data[63:0]; + assign bus_cmd_byteen[7:0] = wrbuf_byteen[7:0]; + assign bus_cmd_tag[pt.DMA_BUS_TAG-1:0] = axi_mstr_sel ? wrbuf_tag[pt.DMA_BUS_TAG-1:0] : rdbuf_tag[pt.DMA_BUS_TAG-1:0]; + assign bus_cmd_mid[pt.DMA_BUS_ID-1:0] = '0; + assign bus_cmd_prty[pt.DMA_BUS_PRTY-1:0] = '0; + + // Sel=1 -> write has higher priority + assign axi_mstr_sel = (wrbuf_vld & wrbuf_data_vld & rdbuf_vld) ? axi_mstr_priority : (wrbuf_vld & wrbuf_data_vld); + assign axi_mstr_prty_in = ~axi_mstr_priority; + assign axi_mstr_prty_en = bus_cmd_sent; + rvdffs_fpga #(.WIDTH(1)) mstr_prtyff(.din(axi_mstr_prty_in), .dout(axi_mstr_priority), .en(axi_mstr_prty_en), .clk(dma_bus_clk), .clken(dma_bus_clk_en), .rawclk(clk), .*); + + assign axi_rsp_valid = fifo_valid[RspPtr] & ~fifo_dbg[RspPtr] & fifo_done_bus[RspPtr]; + assign axi_rsp_rdata[63:0] = fifo_data[RspPtr]; + assign axi_rsp_write = fifo_write[RspPtr]; + assign axi_rsp_error[1:0] = fifo_error[RspPtr][0] ? 2'b10 : (fifo_error[RspPtr][1] ? 2'b11 : 2'b0); + assign axi_rsp_tag[pt.DMA_BUS_TAG-1:0] = fifo_tag[RspPtr]; + + // AXI response channel signals + assign dma_axi_bvalid = axi_rsp_valid & axi_rsp_write; + assign dma_axi_bresp[1:0] = axi_rsp_error[1:0]; + assign dma_axi_bid[pt.DMA_BUS_TAG-1:0] = axi_rsp_tag[pt.DMA_BUS_TAG-1:0]; + + assign dma_axi_rvalid = axi_rsp_valid & ~axi_rsp_write; + assign dma_axi_rresp[1:0] = axi_rsp_error; + assign dma_axi_rdata[63:0] = axi_rsp_rdata[63:0]; + assign dma_axi_rlast = 1'b1; + assign dma_axi_rid[pt.DMA_BUS_TAG-1:0] = axi_rsp_tag[pt.DMA_BUS_TAG-1:0]; + + assign bus_posted_write_done = 1'b0; + assign bus_rsp_valid = (dma_axi_bvalid | dma_axi_rvalid); + assign bus_rsp_sent = (dma_axi_bvalid & dma_axi_bready) | (dma_axi_rvalid & dma_axi_rready); + + assign dma_active = wrbuf_vld | rdbuf_vld | (|fifo_valid[DEPTH-1:0]); + + +`ifdef RV_ASSERT_ON + + for (genvar i=0; i $past(dma_bus_clk_en); + endproperty + assert_dma_axi_awvalid_stable: assert property (dma_axi_awvalid_stable) else + $display("DMA AXI awvalid changed in middle of bus clock"); + + // Assertion to check awid stays stable during entire bus clock + property dma_axi_awid_stable; + @(posedge clk) disable iff(~rst_l) (dma_axi_awvalid & (dma_axi_awid[pt.DMA_BUS_TAG-1:0] != $past(dma_axi_awid[pt.DMA_BUS_TAG-1:0]))) |-> $past(dma_bus_clk_en); + endproperty + assert_dma_axi_awid_stable: assert property (dma_axi_awid_stable) else + $display("DMA AXI awid changed in middle of bus clock"); + + // Assertion to check awaddr stays stable during entire bus clock + property dma_axi_awaddr_stable; + @(posedge clk) disable iff(~rst_l) (dma_axi_awvalid & (dma_axi_awaddr[31:0] != $past(dma_axi_awaddr[31:0]))) |-> $past(dma_bus_clk_en); + endproperty + assert_dma_axi_awaddr_stable: assert property (dma_axi_awaddr_stable) else + $display("DMA AXI awaddr changed in middle of bus clock"); + + // Assertion to check awsize stays stable during entire bus clock + property dma_axi_awsize_stable; + @(posedge clk) disable iff(~rst_l) (dma_axi_awvalid & (dma_axi_awsize[2:0] != $past(dma_axi_awsize[2:0]))) |-> $past(dma_bus_clk_en); + endproperty + assert_dma_axi_awsize_stable: assert property (dma_axi_awsize_stable) else + $display("DMA AXI awsize changed in middle of bus clock"); + + // Assertion to check wstrb stays stable during entire bus clock + property dma_axi_wstrb_stable; + @(posedge clk) disable iff(~rst_l) (dma_axi_wvalid & (dma_axi_wstrb[7:0] != $past(dma_axi_wstrb[7:0]))) |-> $past(dma_bus_clk_en); + endproperty + assert_dma_axi_wstrb_stable: assert property (dma_axi_wstrb_stable) else + $display("DMA AXI wstrb changed in middle of bus clock"); + + // Assertion to check wdata stays stable during entire bus clock + property dma_axi_wdata_stable; + @(posedge clk) disable iff(~rst_l) (dma_axi_wvalid & (dma_axi_wdata[63:0] != $past(dma_axi_wdata[63:0]))) |-> $past(dma_bus_clk_en); + endproperty + assert_dma_axi_wdata_stable: assert property (dma_axi_wdata_stable) else + $display("DMA AXI wdata changed in middle of bus clock"); + + // Assertion to check awvalid stays stable during entire bus clock + property dma_axi_arvalid_stable; + @(posedge clk) disable iff(~rst_l) (dma_axi_arvalid != $past(dma_axi_arvalid)) |-> $past(dma_bus_clk_en); + endproperty + assert_dma_axi_arvalid_stable: assert property (dma_axi_arvalid_stable) else + $display("DMA AXI awvalid changed in middle of bus clock"); + + // Assertion to check awid stays stable during entire bus clock + property dma_axi_arid_stable; + @(posedge clk) disable iff(~rst_l) (dma_axi_arvalid & (dma_axi_arid[pt.DMA_BUS_TAG-1:0] != $past(dma_axi_arid[pt.DMA_BUS_TAG-1:0]))) |-> $past(dma_bus_clk_en); + endproperty + assert_dma_axi_arid_stable: assert property (dma_axi_arid_stable) else + $display("DMA AXI awid changed in middle of bus clock"); + + // Assertion to check awaddr stays stable during entire bus clock + property dma_axi_araddr_stable; + @(posedge clk) disable iff(~rst_l) (dma_axi_arvalid & (dma_axi_araddr[31:0] != $past(dma_axi_araddr[31:0]))) |-> $past(dma_bus_clk_en); + endproperty + assert_dma_axi_araddr_stable: assert property (dma_axi_araddr_stable) else + $display("DMA AXI awaddr changed in middle of bus clock"); + + // Assertion to check awsize stays stable during entire bus clock + property dma_axi_arsize_stable; + @(posedge clk) disable iff(~rst_l) (dma_axi_awvalid & (dma_axi_arsize[2:0] != $past(dma_axi_arsize[2:0]))) |-> $past(dma_bus_clk_en); + endproperty + assert_dma_axi_arsize_stable: assert property (dma_axi_arsize_stable) else + $display("DMA AXI awsize changed in middle of bus clock"); + + // Assertion to check bvalid stays stable during entire bus clock + property dma_axi_bvalid_stable; + @(posedge clk) disable iff(~rst_l) (dma_axi_bvalid != $past(dma_axi_bvalid)) |-> $past(dma_bus_clk_en); + endproperty + assert_dma_axi_bvalid_stable: assert property (dma_axi_bvalid_stable) else + $display("DMA AXI bvalid changed in middle of bus clock"); + + // Assertion to check bvalid stays stable if bready is low + property dma_axi_bvalid_stable_till_bready; + @(posedge clk) disable iff(~rst_l) (~dma_axi_bvalid && $past(dma_axi_bvalid)) |-> $past(dma_axi_bready); + endproperty + assert_dma_axi_bvalid_stable_till_bready: assert property (dma_axi_bvalid_stable_till_bready) else + $display("DMA AXI bvalid deasserted without bready"); + + // Assertion to check bresp stays stable during entire bus clock + property dma_axi_bresp_stable; + @(posedge clk) disable iff(~rst_l) (dma_axi_bvalid & (dma_axi_bresp[1:0] != $past(dma_axi_bresp[1:0]))) |-> $past(dma_bus_clk_en); + endproperty + assert_dma_axi_bresp_stable: assert property (dma_axi_bresp_stable) else + $display("DMA AXI bresp changed in middle of bus clock"); + + // Assertion to check bid stays stable during entire bus clock + property dma_axi_bid_stable; + @(posedge clk) disable iff(~rst_l) (dma_axi_bvalid & (dma_axi_bid[pt.DMA_BUS_TAG-1:0] != $past(dma_axi_bid[pt.DMA_BUS_TAG-1:0]))) |-> $past(dma_bus_clk_en); + endproperty + assert_dma_axi_bid_stable: assert property (dma_axi_bid_stable) else + $display("DMA AXI bid changed in middle of bus clock"); + + // Assertion to check rvalid stays stable during entire bus clock + property dma_axi_rvalid_stable; + @(posedge clk) disable iff(~rst_l) (dma_axi_rvalid != $past(dma_axi_rvalid)) |-> $past(dma_bus_clk_en); + endproperty + assert_dma_axi_rvalid_stable: assert property (dma_axi_rvalid_stable) else + $display("DMA AXI bvalid changed in middle of bus clock"); + + // Assertion to check rvalid stays stable if bready is low + property dma_axi_rvalid_stable_till_ready; + @(posedge clk) disable iff(~rst_l) (~dma_axi_rvalid && $past(dma_axi_rvalid)) |-> $past(dma_axi_rready); + endproperty + assert_dma_axi_rvalid_stable_till_ready: assert property (dma_axi_rvalid_stable_till_ready) else + $display("DMA AXI bvalid changed in middle of bus clock"); + + // Assertion to check rresp stays stable during entire bus clock + property dma_axi_rresp_stable; + @(posedge clk) disable iff(~rst_l) (dma_axi_rvalid & (dma_axi_rresp[1:0] != $past(dma_axi_rresp[1:0]))) |-> $past(dma_bus_clk_en); + endproperty + assert_dma_axi_rresp_stable: assert property (dma_axi_rresp_stable) else + $display("DMA AXI bresp changed in middle of bus clock"); + + // Assertion to check rid stays stable during entire bus clock + property dma_axi_rid_stable; + @(posedge clk) disable iff(~rst_l) (dma_axi_rvalid & (dma_axi_rid[pt.DMA_BUS_TAG-1:0] != $past(dma_axi_rid[pt.DMA_BUS_TAG-1:0]))) |-> $past(dma_bus_clk_en); + endproperty + assert_dma_axi_rid_stable: assert property (dma_axi_rid_stable) else + $display("DMA AXI bid changed in middle of bus clock"); + + // Assertion to check rdata stays stable during entire bus clock + property dma_axi_rdata_stable; + @(posedge clk) disable iff(~rst_l) (dma_axi_rvalid & (dma_axi_rdata[63:0] != $past(dma_axi_rdata[63:0]))) |-> $past(dma_bus_clk_en); + endproperty + assert_dma_axi_rdata_stable: assert property (dma_axi_rdata_stable) else + $display("DMA AXI bid changed in middle of bus clock"); + +`endif + +endmodule // el2_dma_ctrl diff --git a/designs/Caliptra/src/caliptra-rtl/el2_exu.sv b/designs/Caliptra/src/caliptra-rtl/el2_exu.sv new file mode 100644 index 0000000..26e90ed --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/el2_exu.sv @@ -0,0 +1,372 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2020 Western Digital Corporation or its affiliates. +// +// 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. + + +module el2_exu +import el2_pkg::*; +#( +`include "el2_param.vh" +) + ( + input logic clk, // Top level clock + input logic rst_l, // Reset + // Excluding scan_mode from coverage as its usage is determined by the integrator of the VeeR core. + /*pragma coverage off*/ + input logic scan_mode, // Scan control + /*pragma coverage on*/ + + input logic [1:0] dec_data_en, // Clock enable {x,r}, one cycle pulse + input logic [1:0] dec_ctl_en, // Clock enable {x,r}, two cycle pulse + input logic [31:0] dbg_cmd_wrdata, // Debug data to primary I0 RS1 + input el2_alu_pkt_t i0_ap, // DEC alu {valid,predecodes} + + input logic dec_debug_wdata_rs1_d, // Debug select to primary I0 RS1 + + input el2_predict_pkt_t dec_i0_predict_p_d, // DEC branch predict packet + input logic [pt.BHT_GHR_SIZE-1:0] i0_predict_fghr_d, // DEC predict fghr + input logic [pt.BTB_ADDR_HI:pt.BTB_ADDR_LO] i0_predict_index_d, // DEC predict index + input logic [pt.BTB_BTAG_SIZE-1:0] i0_predict_btag_d, // DEC predict branch tag + + input logic [31:0] lsu_result_m, // Load result M-stage + input logic [31:0] lsu_nonblock_load_data, // nonblock load data + input logic dec_i0_rs1_en_d, // Qualify GPR RS1 data + input logic dec_i0_rs2_en_d, // Qualify GPR RS2 data + input logic [31:0] gpr_i0_rs1_d, // DEC data gpr + input logic [31:0] gpr_i0_rs2_d, // DEC data gpr + input logic [31:0] dec_i0_immed_d, // DEC data immediate + input logic [31:0] dec_i0_result_r, // DEC result in R-stage + input logic [12:1] dec_i0_br_immed_d, // Branch immediate + input logic dec_i0_alu_decode_d, // Valid to X-stage ALU + input logic dec_i0_branch_d, // Branch in D-stage + input logic dec_i0_select_pc_d, // PC select to RS1 + input logic [31:1] dec_i0_pc_d, // Instruction PC + input logic [3:0] dec_i0_rs1_bypass_en_d, // DEC bypass select 1 - X-stage, 0 - dec bypass data + input logic [3:0] dec_i0_rs2_bypass_en_d, // DEC bypass select 1 - X-stage, 0 - dec bypass data + input logic dec_csr_ren_d, // CSR read select + input logic [31:0] dec_csr_rddata_d, // CSR read data + + input logic dec_qual_lsu_d, // LSU instruction at D. Use to quiet LSU operands + input el2_mul_pkt_t mul_p, // DEC {valid, operand signs, low, operand bypass} + input el2_div_pkt_t div_p, // DEC {valid, unsigned, rem} + input logic dec_div_cancel, // Cancel the divide operation + + input logic [31:1] pred_correct_npc_x, // DEC NPC for correctly predicted branch + + input logic dec_tlu_flush_lower_r, // Flush divide and secondary ALUs + input logic [31:1] dec_tlu_flush_path_r, // Redirect target + + + input logic dec_extint_stall, // External stall mux select + input logic [31:2] dec_tlu_meihap, // External stall mux data + + + output logic [31:0] exu_lsu_rs1_d, // LSU operand + output logic [31:0] exu_lsu_rs2_d, // LSU operand + + output logic exu_flush_final, // Pipe is being flushed this cycle + output logic [31:1] exu_flush_path_final, // Target for the oldest flush source + + output logic [31:0] exu_i0_result_x, // Primary ALU result to DEC + output logic [31:1] exu_i0_pc_x, // Primary PC result to DEC + output logic [31:0] exu_csr_rs1_x, // RS1 source for a CSR instruction + + output logic [31:1] exu_npc_r, // Divide NPC + output logic [1:0] exu_i0_br_hist_r, // to DEC I0 branch history + output logic exu_i0_br_error_r, // to DEC I0 branch error + output logic exu_i0_br_start_error_r, // to DEC I0 branch start error + output logic [pt.BTB_ADDR_HI:pt.BTB_ADDR_LO] exu_i0_br_index_r, // to DEC I0 branch index + output logic exu_i0_br_valid_r, // to DEC I0 branch valid + output logic exu_i0_br_mp_r, // to DEC I0 branch mispredict + output logic exu_i0_br_middle_r, // to DEC I0 branch middle + output logic [pt.BHT_GHR_SIZE-1:0] exu_i0_br_fghr_r, // to DEC I0 branch fghr + output logic exu_i0_br_way_r, // to DEC I0 branch way + + output el2_predict_pkt_t exu_mp_pkt, // Mispredict branch packet + output logic [pt.BHT_GHR_SIZE-1:0] exu_mp_eghr, // Mispredict global history + output logic [pt.BHT_GHR_SIZE-1:0] exu_mp_fghr, // Mispredict fghr + output logic [pt.BTB_ADDR_HI:pt.BTB_ADDR_LO] exu_mp_index, // Mispredict index + output logic [pt.BTB_BTAG_SIZE-1:0] exu_mp_btag, // Mispredict btag + + + output logic exu_pmu_i0_br_misp, // to PMU - I0 E4 branch mispredict + output logic exu_pmu_i0_br_ataken, // to PMU - I0 E4 taken + output logic exu_pmu_i0_pc4, // to PMU - I0 E4 PC + + + output logic [31:0] exu_div_result, // Divide result + output logic exu_div_wren // Divide write enable to GPR + ); + + + + + logic [31:0] i0_rs1_bypass_data_d; + logic [31:0] i0_rs2_bypass_data_d; + logic i0_rs1_bypass_en_d; + logic i0_rs2_bypass_en_d; + logic [31:0] i0_rs1_d, i0_rs2_d; + logic [31:0] muldiv_rs1_d; + logic [31:1] pred_correct_npc_r; + logic i0_pred_correct_upper_r; + logic [31:1] i0_flush_path_upper_r; + logic x_data_en, x_data_en_q1, x_data_en_q2, r_data_en, r_data_en_q2; + logic x_ctl_en, r_ctl_en; + + logic [pt.BHT_GHR_SIZE-1:0] ghr_d_ns, ghr_d; + logic [pt.BHT_GHR_SIZE-1:0] ghr_x_ns, ghr_x; + logic i0_taken_d; + logic i0_taken_x; + logic i0_valid_d; + logic i0_valid_x; + logic [pt.BHT_GHR_SIZE-1:0] after_flush_eghr; + + el2_predict_pkt_t final_predict_mp; + el2_predict_pkt_t i0_predict_newp_d; + + logic flush_in_d; + logic [31:0] alu_result_x; + + logic mul_valid_x; + logic [31:0] mul_result_x; + + el2_predict_pkt_t i0_pp_r; + + logic i0_flush_upper_d; + logic [31:1] i0_flush_path_d; + el2_predict_pkt_t i0_predict_p_d; + logic i0_pred_correct_upper_d; + + logic i0_flush_upper_x; + logic [31:1] i0_flush_path_x; + el2_predict_pkt_t i0_predict_p_x; + logic i0_pred_correct_upper_x; + logic i0_branch_x; + + localparam PREDPIPESIZE = pt.BTB_ADDR_HI-pt.BTB_ADDR_LO+1+pt.BHT_GHR_SIZE+pt.BTB_BTAG_SIZE; + logic [PREDPIPESIZE-1:0] predpipe_d, predpipe_x, predpipe_r, final_predpipe_mp; + + + + + rvdffpcie #(31) i_flush_path_x_ff (.*, .clk(clk), .en ( x_data_en ), .din ( i0_flush_path_d[31:1] ), .dout( i0_flush_path_x[31:1] ) ); + rvdffe #(32) i_csr_rs1_x_ff (.*, .clk(clk), .en ( x_data_en_q1 ), .din ( i0_rs1_d[31:0] ), .dout( exu_csr_rs1_x[31:0] ) ); + rvdffppe #($bits(el2_predict_pkt_t)) i_predictpacket_x_ff (.*, .clk(clk), .en ( x_data_en ), .din ( i0_predict_p_d ), .dout( i0_predict_p_x ) ); + rvdffe #(PREDPIPESIZE) i_predpipe_x_ff (.*, .clk(clk), .en ( x_data_en_q2 ), .din ( predpipe_d ), .dout( predpipe_x ) ); + rvdffe #(PREDPIPESIZE) i_predpipe_r_ff (.*, .clk(clk), .en ( r_data_en_q2 ), .din ( predpipe_x ), .dout( predpipe_r ) ); + + rvdffe #(4+pt.BHT_GHR_SIZE) i_x_ff (.*, .clk(clk), .en ( x_ctl_en ), .din ({i0_valid_d,i0_taken_d,i0_flush_upper_d,i0_pred_correct_upper_d,ghr_x_ns[pt.BHT_GHR_SIZE-1:0]} ), + .dout({i0_valid_x,i0_taken_x,i0_flush_upper_x,i0_pred_correct_upper_x,ghr_x[pt.BHT_GHR_SIZE-1:0]} ) ); + + rvdffppe #($bits(el2_predict_pkt_t)+1) i_r_ff0 (.*, .clk(clk), .en ( r_ctl_en ), .din ({i0_pred_correct_upper_x, i0_predict_p_x}), + .dout({i0_pred_correct_upper_r, i0_pp_r }) ); + + rvdffpcie #(31) i_flush_r_ff (.*, .clk(clk), .en ( r_data_en ), .din ( i0_flush_path_x[31:1] ), .dout( i0_flush_path_upper_r[31:1]) ); + rvdffpcie #(31) i_npc_r_ff (.*, .clk(clk), .en ( r_data_en ), .din ( pred_correct_npc_x[31:1] ), .dout( pred_correct_npc_r[31:1] ) ); + + rvdffie #(pt.BHT_GHR_SIZE+2,1) i_misc_ff (.*, .clk(clk), .din ({ghr_d_ns[pt.BHT_GHR_SIZE-1:0], mul_p.valid, dec_i0_branch_d}), + .dout({ghr_d[pt.BHT_GHR_SIZE-1:0] , mul_valid_x, i0_branch_x}) ); + + + + + + assign predpipe_d[PREDPIPESIZE-1:0] + = {i0_predict_fghr_d, i0_predict_index_d, i0_predict_btag_d}; + + + assign i0_rs1_bypass_en_d = dec_i0_rs1_bypass_en_d[0] | dec_i0_rs1_bypass_en_d[1] | dec_i0_rs1_bypass_en_d[2] | dec_i0_rs1_bypass_en_d[3]; + assign i0_rs2_bypass_en_d = dec_i0_rs2_bypass_en_d[0] | dec_i0_rs2_bypass_en_d[1] | dec_i0_rs2_bypass_en_d[2] | dec_i0_rs2_bypass_en_d[3]; + + assign i0_rs1_bypass_data_d[31:0]=({32{dec_i0_rs1_bypass_en_d[0]}} & dec_i0_result_r[31:0] ) | + ({32{dec_i0_rs1_bypass_en_d[1]}} & lsu_result_m[31:0] ) | + ({32{dec_i0_rs1_bypass_en_d[2]}} & exu_i0_result_x[31:0] ) | + ({32{dec_i0_rs1_bypass_en_d[3]}} & lsu_nonblock_load_data[31:0]); + + assign i0_rs2_bypass_data_d[31:0]=({32{dec_i0_rs2_bypass_en_d[0]}} & dec_i0_result_r[31:0] ) | + ({32{dec_i0_rs2_bypass_en_d[1]}} & lsu_result_m[31:0] ) | + ({32{dec_i0_rs2_bypass_en_d[2]}} & exu_i0_result_x[31:0] ) | + ({32{dec_i0_rs2_bypass_en_d[3]}} & lsu_nonblock_load_data[31:0]); + + + assign i0_rs1_d[31:0] = ({32{ i0_rs1_bypass_en_d }} & i0_rs1_bypass_data_d[31:0]) | + ({32{~i0_rs1_bypass_en_d & dec_i0_select_pc_d }} & {dec_i0_pc_d[31:1],1'b0} ) | // for jal's + ({32{~i0_rs1_bypass_en_d & dec_debug_wdata_rs1_d }} & dbg_cmd_wrdata[31:0] ) | + ({32{~i0_rs1_bypass_en_d & ~dec_debug_wdata_rs1_d & dec_i0_rs1_en_d}} & gpr_i0_rs1_d[31:0] ); + + assign i0_rs2_d[31:0] = ({32{~i0_rs2_bypass_en_d & dec_i0_rs2_en_d}} & gpr_i0_rs2_d[31:0] ) | + ({32{~i0_rs2_bypass_en_d }} & dec_i0_immed_d[31:0] ) | + ({32{ i0_rs2_bypass_en_d }} & i0_rs2_bypass_data_d[31:0]); + + + assign exu_lsu_rs1_d[31:0] = ({32{~i0_rs1_bypass_en_d & ~dec_extint_stall & dec_i0_rs1_en_d & dec_qual_lsu_d}} & gpr_i0_rs1_d[31:0] ) | + ({32{ i0_rs1_bypass_en_d & ~dec_extint_stall & dec_qual_lsu_d}} & i0_rs1_bypass_data_d[31:0]) | + ({32{ dec_extint_stall & dec_qual_lsu_d}} & {dec_tlu_meihap[31:2],2'b0}); + + assign exu_lsu_rs2_d[31:0] = ({32{~i0_rs2_bypass_en_d & ~dec_extint_stall & dec_i0_rs2_en_d & dec_qual_lsu_d}} & gpr_i0_rs2_d[31:0] ) | + ({32{ i0_rs2_bypass_en_d & ~dec_extint_stall & dec_qual_lsu_d}} & i0_rs2_bypass_data_d[31:0]); + + + assign muldiv_rs1_d[31:0] = ({32{~i0_rs1_bypass_en_d & dec_i0_rs1_en_d}} & gpr_i0_rs1_d[31:0] ) | + ({32{ i0_rs1_bypass_en_d }} & i0_rs1_bypass_data_d[31:0]); + + + assign x_data_en = dec_data_en[1]; + assign x_data_en_q1 = dec_data_en[1] & dec_csr_ren_d; + assign x_data_en_q2 = dec_data_en[1] & dec_i0_branch_d; + assign r_data_en = dec_data_en[0]; + assign r_data_en_q2 = dec_data_en[0] & i0_branch_x; + assign x_ctl_en = dec_ctl_en[1]; + assign r_ctl_en = dec_ctl_en[0]; + + + + + el2_exu_alu_ctl #(.pt(pt)) i_alu (.*, + .enable ( x_data_en ), // I + .pp_in ( i0_predict_newp_d ), // I + .valid_in ( dec_i0_alu_decode_d ), // I + .flush_upper_x ( i0_flush_upper_x ), // I + .flush_lower_r ( dec_tlu_flush_lower_r ), // I + .a_in ( i0_rs1_d[31:0] ), // I + .b_in ( i0_rs2_d[31:0] ), // I + .pc_in ( dec_i0_pc_d[31:1] ), // I + .brimm_in ( dec_i0_br_immed_d[12:1] ), // I + .ap ( i0_ap ), // I + .csr_ren_in ( dec_csr_ren_d ), // I + .csr_rddata_in ( dec_csr_rddata_d[31:0] ), // I + .result_ff ( alu_result_x[31:0] ), // O + .flush_upper_out ( i0_flush_upper_d ), // O + .flush_final_out ( exu_flush_final ), // O + .flush_path_out ( i0_flush_path_d[31:1] ), // O + .predict_p_out ( i0_predict_p_d ), // O + .pred_correct_out ( i0_pred_correct_upper_d ), // O + .pc_ff ( exu_i0_pc_x[31:1] )); // O + + + + el2_exu_mul_ctl #(.pt(pt)) i_mul (.*, + .mul_p ( mul_p & {$bits(el2_mul_pkt_t){mul_p.valid}} ), // I + .rs1_in ( muldiv_rs1_d[31:0] & {32{mul_p.valid}} ), // I + .rs2_in ( i0_rs2_d[31:0] & {32{mul_p.valid}} ), // I + .result_x ( mul_result_x[31:0] )); // O + + + + el2_exu_div_ctl #(.pt(pt)) i_div (.*, + .cancel ( dec_div_cancel ), // I + .dp ( div_p ), // I + .dividend ( muldiv_rs1_d[31:0] ), // I + .divisor ( i0_rs2_d[31:0] ), // I + .finish_dly ( exu_div_wren ), // O + .out ( exu_div_result[31:0] )); // O + + + + assign exu_i0_result_x[31:0] = (mul_valid_x) ? mul_result_x[31:0] : alu_result_x[31:0]; + + + + + always_comb begin + i0_predict_newp_d = dec_i0_predict_p_d; + i0_predict_newp_d.boffset = dec_i0_pc_d[1]; // from the start of inst + end + + + assign exu_pmu_i0_br_misp = i0_pp_r.misp; + assign exu_pmu_i0_br_ataken = i0_pp_r.ataken; + assign exu_pmu_i0_pc4 = i0_pp_r.pc4; + + + assign i0_valid_d = i0_predict_p_d.valid & dec_i0_alu_decode_d & ~dec_tlu_flush_lower_r; + assign i0_taken_d = (i0_predict_p_d.ataken & dec_i0_alu_decode_d); + +if(pt.BTB_ENABLE==1) begin + // maintain GHR at D + assign ghr_d_ns[pt.BHT_GHR_SIZE-1:0] + = ({pt.BHT_GHR_SIZE{~dec_tlu_flush_lower_r & i0_valid_d}} & {ghr_d[pt.BHT_GHR_SIZE-2:0], i0_taken_d}) | + ({pt.BHT_GHR_SIZE{~dec_tlu_flush_lower_r & ~i0_valid_d}} & ghr_d[pt.BHT_GHR_SIZE-1:0] ) | + ({pt.BHT_GHR_SIZE{ dec_tlu_flush_lower_r }} & ghr_x[pt.BHT_GHR_SIZE-1:0] ); + + // maintain GHR at X + assign ghr_x_ns[pt.BHT_GHR_SIZE-1:0] + = ({pt.BHT_GHR_SIZE{ i0_valid_x}} & {ghr_x[pt.BHT_GHR_SIZE-2:0], i0_taken_x}) | + ({pt.BHT_GHR_SIZE{~i0_valid_x}} & ghr_x[pt.BHT_GHR_SIZE-1:0] ) ; + + + assign exu_i0_br_valid_r = i0_pp_r.valid; + assign exu_i0_br_mp_r = i0_pp_r.misp; + assign exu_i0_br_way_r = i0_pp_r.way; + assign exu_i0_br_hist_r[1:0] = {2{i0_pp_r.valid}} & i0_pp_r.hist[1:0]; + assign exu_i0_br_error_r = i0_pp_r.br_error; + assign exu_i0_br_middle_r = i0_pp_r.pc4 ^ i0_pp_r.boffset; + assign exu_i0_br_start_error_r = i0_pp_r.br_start_error; + + assign {exu_i0_br_fghr_r[pt.BHT_GHR_SIZE-1:0], + exu_i0_br_index_r[pt.BTB_ADDR_HI:pt.BTB_ADDR_LO]}= predpipe_r[PREDPIPESIZE-1:pt.BTB_BTAG_SIZE]; + + + assign final_predict_mp = (i0_flush_upper_x) ? i0_predict_p_x : '0; + + assign final_predpipe_mp[PREDPIPESIZE-1:0] = (i0_flush_upper_x) ? predpipe_x : '0; + + assign after_flush_eghr[pt.BHT_GHR_SIZE-1:0] = (i0_flush_upper_x & ~dec_tlu_flush_lower_r) ? ghr_d[pt.BHT_GHR_SIZE-1:0] : ghr_x[pt.BHT_GHR_SIZE-1:0]; + + + assign exu_mp_pkt.valid = final_predict_mp.valid; + assign exu_mp_pkt.way = final_predict_mp.way; + assign exu_mp_pkt.misp = final_predict_mp.misp; + assign exu_mp_pkt.pcall = final_predict_mp.pcall; + assign exu_mp_pkt.pja = final_predict_mp.pja; + assign exu_mp_pkt.pret = final_predict_mp.pret; + assign exu_mp_pkt.ataken = final_predict_mp.ataken; + assign exu_mp_pkt.boffset = final_predict_mp.boffset; + assign exu_mp_pkt.pc4 = final_predict_mp.pc4; + assign exu_mp_pkt.hist[1:0] = final_predict_mp.hist[1:0]; + assign exu_mp_pkt.toffset[11:0] = final_predict_mp.toffset[11:0]; + + assign exu_mp_fghr[pt.BHT_GHR_SIZE-1:0] = after_flush_eghr[pt.BHT_GHR_SIZE-1:0]; + + assign {exu_mp_index[pt.BTB_ADDR_HI:pt.BTB_ADDR_LO], + exu_mp_btag[pt.BTB_BTAG_SIZE-1:0]} = final_predpipe_mp[PREDPIPESIZE-pt.BHT_GHR_SIZE-1:0]; + + assign exu_mp_eghr[pt.BHT_GHR_SIZE-1:0] = final_predpipe_mp[PREDPIPESIZE-1:pt.BTB_ADDR_HI-pt.BTB_ADDR_LO+pt.BTB_BTAG_SIZE+1]; // mp ghr for bht write +end // if (pt.BTB_ENABLE==1) +else begin + assign ghr_d_ns = '0; + assign ghr_x_ns = '0; + assign exu_mp_pkt = '0; + assign exu_mp_eghr = '0; + assign exu_mp_fghr = '0; + assign exu_mp_index = '0; + assign exu_mp_btag = '0; + assign exu_i0_br_hist_r = '0; + assign exu_i0_br_error_r = '0; + assign exu_i0_br_start_error_r = '0; + assign exu_i0_br_index_r = '0; + assign exu_i0_br_valid_r = '0; + assign exu_i0_br_mp_r = '0; + assign exu_i0_br_middle_r = '0; + assign exu_i0_br_fghr_r = '0; + assign exu_i0_br_way_r = '0; +end // else: !if(pt.BTB_ENABLE==1) + + assign exu_flush_path_final[31:1] = ( {31{ dec_tlu_flush_lower_r }} & dec_tlu_flush_path_r[31:1] ) | + ( {31{~dec_tlu_flush_lower_r & i0_flush_upper_d}} & i0_flush_path_d[31:1] ); + + assign exu_npc_r[31:1] = (i0_pred_correct_upper_r) ? pred_correct_npc_r[31:1] : i0_flush_path_upper_r[31:1]; + + +endmodule // el2_exu diff --git a/designs/Caliptra/src/caliptra-rtl/el2_exu_alu_ctl.sv b/designs/Caliptra/src/caliptra-rtl/el2_exu_alu_ctl.sv new file mode 100644 index 0000000..b815901 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/el2_exu_alu_ctl.sv @@ -0,0 +1,579 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2020 Western Digital Corporation or its affiliates. +// +// 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. + + +module el2_exu_alu_ctl +import el2_pkg::*; +#( +`include "el2_param.vh" +) + ( + input logic clk, // Top level clock + input logic rst_l, // Reset + // Excluding scan_mode from coverage as its usage is determined by the integrator of the VeeR core. + /*pragma coverage off*/ + input logic scan_mode, // Scan control + /*pragma coverage on*/ + + input logic flush_upper_x, // Branch flush from previous cycle + input logic flush_lower_r, // Master flush of entire pipeline + input logic enable, // Clock enable + input logic valid_in, // Valid + input el2_alu_pkt_t ap, // predecodes + input logic csr_ren_in, // CSR select + input logic [31:0] csr_rddata_in, // CSR data + input logic signed [31:0] a_in, // A operand + input logic [31:0] b_in, // B operand + input logic [31:1] pc_in, // for pc=pc+2,4 calculations + input el2_predict_pkt_t pp_in, // Predicted branch structure + input logic [12:1] brimm_in, // Branch offset + + + output logic [31:0] result_ff, // final result + output logic flush_upper_out, // Branch flush + output logic flush_final_out, // Branch flush or flush entire pipeline + output logic [31:1] flush_path_out, // Branch flush PC + output logic [31:1] pc_ff, // flopped PC + output logic pred_correct_out, // NPC control + output el2_predict_pkt_t predict_p_out // Predicted branch structure + ); + + + logic [31:0] zba_a_in; + logic [31:0] aout; + logic cout,ov,neg; + logic [31:0] lout; + logic [31:0] sout; + logic sel_shift; + logic sel_adder; + logic slt_one; + logic actual_taken; + logic [31:1] pcout; + logic cond_mispredict; + logic target_mispredict; + logic eq, ne, lt, ge; + logic any_jal; + logic [1:0] newhist; + logic sel_pc; + logic [31:0] csr_write_data; + logic [31:0] result; + + + + + // *** Start - BitManip *** + + // Zbb + logic ap_clz; + logic ap_ctz; + logic ap_cpop; + logic ap_sext_b; + logic ap_sext_h; + logic ap_min; + logic ap_max; + logic ap_rol; + logic ap_ror; + logic ap_rev8; + logic ap_orc_b; + logic ap_zbb; + + // Zbs + logic ap_bset; + logic ap_bclr; + logic ap_binv; + logic ap_bext; + + // Zbp + logic ap_pack; + logic ap_packu; + logic ap_packh; + + // Zba + logic ap_sh1add; + logic ap_sh2add; + logic ap_sh3add; + logic ap_zba; + + + + if (pt.BITMANIP_ZBB == 1) + begin + assign ap_clz = ap.clz; + assign ap_ctz = ap.ctz; + assign ap_cpop = ap.cpop; + assign ap_sext_b = ap.sext_b; + assign ap_sext_h = ap.sext_h; + assign ap_min = ap.min; + assign ap_max = ap.max; + end + else + begin + assign ap_clz = 1'b0; + assign ap_ctz = 1'b0; + assign ap_cpop = 1'b0; + assign ap_sext_b = 1'b0; + assign ap_sext_h = 1'b0; + assign ap_min = 1'b0; + assign ap_max = 1'b0; + end + + + if ( (pt.BITMANIP_ZBB == 1) | (pt.BITMANIP_ZBP == 1) ) + begin + assign ap_rol = ap.rol; + assign ap_ror = ap.ror; + assign ap_rev8 = ap.grev & (b_in[4:0] == 5'b11000); + assign ap_orc_b = ap.gorc & (b_in[4:0] == 5'b00111); + assign ap_zbb = ap.zbb; + end + else + begin + assign ap_rol = 1'b0; + assign ap_ror = 1'b0; + assign ap_rev8 = 1'b0; + assign ap_orc_b = 1'b0; + assign ap_zbb = 1'b0; + end + + + if (pt.BITMANIP_ZBS == 1) + begin + assign ap_bset = ap.bset; + assign ap_bclr = ap.bclr; + assign ap_binv = ap.binv; + assign ap_bext = ap.bext; + end + else + begin + assign ap_bset = 1'b0; + assign ap_bclr = 1'b0; + assign ap_binv = 1'b0; + assign ap_bext = 1'b0; + end + + + if (pt.BITMANIP_ZBP == 1) + begin + assign ap_packu = ap.packu; + end + else + begin + assign ap_packu = 1'b0; + end + + + if ( (pt.BITMANIP_ZBB == 1) | (pt.BITMANIP_ZBP == 1) | (pt.BITMANIP_ZBE == 1) | (pt.BITMANIP_ZBF == 1) ) + begin + assign ap_pack = ap.pack; + assign ap_packh = ap.packh; + end + else + begin + assign ap_pack = 1'b0; + assign ap_packh = 1'b0; + end + + + if (pt.BITMANIP_ZBA == 1) + begin + assign ap_sh1add = ap.sh1add; + assign ap_sh2add = ap.sh2add; + assign ap_sh3add = ap.sh3add; + assign ap_zba = ap.zba; + end + else + begin + assign ap_sh1add = 1'b0; + assign ap_sh2add = 1'b0; + assign ap_sh3add = 1'b0; + assign ap_zba = 1'b0; + end + + + + + // *** End - BitManip *** + + + + + rvdffpcie #(31) i_pc_ff (.*, .clk(clk), .en(enable), .din(pc_in[31:1]), .dout(pc_ff[31:1])); // any PC is run through here - doesn't have to be alu + rvdffe #(32) i_result_ff (.*, .clk(clk), .en(enable & valid_in), .din(result[31:0]), .dout(result_ff[31:0])); + + + + // immediates are just muxed into rs2 + + // add => add=1; + // sub => add=1; sub=1; + + // and => lctl=3 + // or => lctl=2 + // xor => lctl=1 + + // sll => sctl=3 + // srl => sctl=2 + // sra => sctl=1 + + // slt => slt + + // lui => lctl=2; or x0, imm20 previously << 12 + // auipc => add; add pc, imm20 previously << 12 + + // beq => bctl=4; add; add x0, pc, sext(offset[12:1]) + // bne => bctl=3; add; add x0, pc, sext(offset[12:1]) + // blt => bctl=2; add; add x0, pc, sext(offset[12:1]) + // bge => bctl=1; add; add x0, pc, sext(offset[12:1]) + + // jal => rs1=pc {pc[31:1],1'b0}, rs2=sext(offset20:1]); rd=pc+[2,4] + // jalr => rs1=rs1, rs2=sext(offset20:1]); rd=pc+[2,4] + + + + assign zba_a_in[31:0] = ( {32{ ap_sh1add}} & {a_in[30:0],1'b0} ) | + ( {32{ ap_sh2add}} & {a_in[29:0],2'b0} ) | + ( {32{ ap_sh3add}} & {a_in[28:0],3'b0} ) | + ( {32{~ap_zba }} & a_in[31:0] ); + + logic [31:0] bm; + + assign bm[31:0] = ( ap.sub ) ? ~b_in[31:0] : b_in[31:0]; + + assign {cout, aout[31:0]} = {1'b0, zba_a_in[31:0]} + {1'b0, bm[31:0]} + {32'b0, ap.sub}; + + assign ov = (~a_in[31] & ~bm[31] & aout[31]) | + ( a_in[31] & bm[31] & ~aout[31] ); + + assign lt = (~ap.unsign & (neg ^ ov)) | + ( ap.unsign & ~cout); + + assign eq = (a_in[31:0] == b_in[31:0]); + assign ne = ~eq; + assign neg = aout[31]; + assign ge = ~lt; + + + + assign lout[31:0] = ( {32{csr_ren_in }} & csr_rddata_in[31:0] ) | + ( {32{ap.land & ~ap_zbb}} & a_in[31:0] & b_in[31:0] ) | + ( {32{ap.lor & ~ap_zbb}} & (a_in[31:0] | b_in[31:0]) ) | + ( {32{ap.lxor & ~ap_zbb}} & (a_in[31:0] ^ b_in[31:0]) ) | + ( {32{ap.land & ap_zbb}} & a_in[31:0] & ~b_in[31:0] ) | + ( {32{ap.lor & ap_zbb}} & (a_in[31:0] | ~b_in[31:0]) ) | + ( {32{ap.lxor & ap_zbb}} & (a_in[31:0] ^ ~b_in[31:0]) ); + + + + + // * * * * * * * * * * * * * * * * * * BitManip : ROL,ROR * * * * * * * * * * * * * * * * * * + // * * * * * * * * * * * * * * * * * * BitManip : ZBEXT * * * * * * * * * * * * * * * * * * + + logic [5:0] shift_amount; + logic [31:0] shift_mask; + logic [62:0] shift_extend; + logic [62:0] shift_long; + + + assign shift_amount[5:0] = ( { 6{ap.sll}} & (6'd32 - {1'b0,b_in[4:0]}) ) | // [5] unused + ( { 6{ap.srl}} & {1'b0,b_in[4:0]} ) | + ( { 6{ap.sra}} & {1'b0,b_in[4:0]} ) | + ( { 6{ap_rol}} & (6'd32 - {1'b0,b_in[4:0]}) ) | + ( { 6{ap_ror}} & {1'b0,b_in[4:0]} ) | + ( { 6{ap_bext}} & {1'b0,b_in[4:0]} ); + + + assign shift_mask[31:0] = ( 32'hffffffff << ({5{ap.sll}} & b_in[4:0]) ); + + + assign shift_extend[31:0] = a_in[31:0]; + + assign shift_extend[62:32] = ( {31{ap.sra}} & {31{a_in[31]}} ) | + ( {31{ap.sll}} & a_in[30:0] ) | + ( {31{ap_rol}} & a_in[30:0] ) | + ( {31{ap_ror}} & a_in[30:0] ); + + + assign shift_long[62:0] = 63'( shift_extend[62:0] >> shift_amount[4:0] ); // 62-32 unused + + assign sout[31:0] = shift_long[31:0] & shift_mask[31:0]; + + + + + // * * * * * * * * * * * * * * * * * * BitManip : CLZ,CTZ * * * * * * * * * * * * * * * * * * + + logic bitmanip_clz_ctz_sel; + logic [31:0] bitmanip_a_reverse_ff; + logic [31:0] bitmanip_lzd_in; + logic [5:0] bitmanip_dw_lzd_enc; + logic [5:0] bitmanip_clz_ctz_result; + + assign bitmanip_clz_ctz_sel = ap_clz | ap_ctz; + + assign bitmanip_a_reverse_ff[31:0] = {a_in[0], a_in[1], a_in[2], a_in[3], a_in[4], a_in[5], a_in[6], a_in[7], + a_in[8], a_in[9], a_in[10], a_in[11], a_in[12], a_in[13], a_in[14], a_in[15], + a_in[16], a_in[17], a_in[18], a_in[19], a_in[20], a_in[21], a_in[22], a_in[23], + a_in[24], a_in[25], a_in[26], a_in[27], a_in[28], a_in[29], a_in[30], a_in[31]}; + + assign bitmanip_lzd_in[31:0] = ( {32{ap_clz}} & a_in[31:0] ) | + ( {32{ap_ctz}} & bitmanip_a_reverse_ff[31:0]); + + logic [31:0] bitmanip_lzd_os; + integer i; + logic found; + + always_comb + begin + bitmanip_lzd_os[31:0] = bitmanip_lzd_in[31:0]; + bitmanip_dw_lzd_enc[5:0]= 6'b0; + found = 1'b0; + + for (int i=0; i<32; i++) begin + if (bitmanip_lzd_os[31] == 1'b0 && found == 0) begin + bitmanip_dw_lzd_enc[5:0]= bitmanip_dw_lzd_enc[5:0] + 6'b00_0001; + bitmanip_lzd_os[31:0] = bitmanip_lzd_os[31:0] << 1; + end + else + found=1'b1; + end + end + + + + assign bitmanip_clz_ctz_result[5:0] = {6{bitmanip_clz_ctz_sel}} & {bitmanip_dw_lzd_enc[5],( {5{~bitmanip_dw_lzd_enc[5]}} & bitmanip_dw_lzd_enc[4:0] )}; + + + + + // * * * * * * * * * * * * * * * * * * BitManip : CPOP * * * * * * * * * * * * * * * * * * + + logic [5:0] bitmanip_cpop; + logic [5:0] bitmanip_cpop_result; + + + integer bitmanip_cpop_i; + + always_comb + begin + bitmanip_cpop[5:0] = 6'b0; + + for (bitmanip_cpop_i=0; bitmanip_cpop_i<32; bitmanip_cpop_i++) + begin + bitmanip_cpop[5:0] = bitmanip_cpop[5:0] + {5'b0,a_in[bitmanip_cpop_i]}; + end // FOR bitmanip_cpop_i + end // ALWAYS_COMB + + + assign bitmanip_cpop_result[5:0] = {6{ap_cpop}} & bitmanip_cpop[5:0]; + + + + + // * * * * * * * * * * * * * * * * * * BitManip : SEXT_B,SEXT_H * * * * * * * * * * * * * * * * * + + logic [31:0] bitmanip_sext_result; + + assign bitmanip_sext_result[31:0] = ( {32{ap_sext_b}} & { {24{a_in[7]}} ,a_in[7:0] } ) | + ( {32{ap_sext_h}} & { {16{a_in[15]}},a_in[15:0] } ); + + + + + // * * * * * * * * * * * * * * * * * * BitManip : MIN,MAX,MINU,MAXU * * * * * * * * * * * * * * * + + logic bitmanip_minmax_sel; + logic [31:0] bitmanip_minmax_result; + + assign bitmanip_minmax_sel = ap_min | ap_max; + + logic bitmanip_minmax_sel_a; + + assign bitmanip_minmax_sel_a = ge ^ ap_min; + + assign bitmanip_minmax_result[31:0] = ({32{bitmanip_minmax_sel & bitmanip_minmax_sel_a}} & a_in[31:0]) | + ({32{bitmanip_minmax_sel & ~bitmanip_minmax_sel_a}} & b_in[31:0]); + + + + + // * * * * * * * * * * * * * * * * * * BitManip : PACK, PACKU, PACKH * * * * * * * * * * * * * * * + + logic [31:0] bitmanip_pack_result; + logic [31:0] bitmanip_packu_result; + logic [31:0] bitmanip_packh_result; + + assign bitmanip_pack_result[31:0] = {32{ap_pack}} & {b_in[15:0], a_in[15:0]}; + assign bitmanip_packu_result[31:0] = {32{ap_packu}} & {b_in[31:16],a_in[31:16]}; + assign bitmanip_packh_result[31:0] = {32{ap_packh}} & {16'b0,b_in[7:0],a_in[7:0]}; + + + + // * * * * * * * * * * * * * * * * * * BitManip : REV, ORC_B * * * * * * * * * * * * * * * * * * + + logic [31:0] bitmanip_rev8_result; + logic [31:0] bitmanip_orc_b_result; + + assign bitmanip_rev8_result[31:0] = {32{ap_rev8}} & {a_in[7:0],a_in[15:8],a_in[23:16],a_in[31:24]}; + + +// uint32_t gorc32(uint32_t rs1, uint32_t rs2) +// { +// uint32_t x = rs1; +// int shamt = rs2 & 31; ORC.B ORC16 +// if (shamt & 1) x |= ((x & 0x55555555) << 1) | ((x & 0xAAAAAAAA) >> 1); 1 0 +// if (shamt & 2) x |= ((x & 0x33333333) << 2) | ((x & 0xCCCCCCCC) >> 2); 1 0 +// if (shamt & 4) x |= ((x & 0x0F0F0F0F) << 4) | ((x & 0xF0F0F0F0) >> 4); 1 0 +// if (shamt & 8) x |= ((x & 0x00FF00FF) << 8) | ((x & 0xFF00FF00) >> 8); 0 0 +// if (shamt & 16) x |= ((x & 0x0000FFFF) << 16) | ((x & 0xFFFF0000) >> 16); 0 1 +// return x; +// } + + +// BEFORE 31 , 30 , 29 , 28 , 27 , 26, 25, 24 +// shamt[0] b = a31|a30,a31|a30,a29|a28,a29|a28, a27|a26,a27|a26,a25|a24,a25|a24 +// shamt[1] c = b31|b29,b30|b28,b31|b29,b30|b28, b27|b25,b26|b24,b27|b25,b26|b24 +// shamt[2] d = c31|c27,c30|c26,c29|c25,c28|c24, c31|c27,c30|c26,c29|c25,c28|c24 +// +// Expand d31 = c31 | c27; +// = b31 | b29 | b27 | b25; +// = a31|a30 | a29|a28 | a27|a26 | a25|a24 + + assign bitmanip_orc_b_result[31:0] = {32{ap_orc_b}} & { {8{| a_in[31:24]}}, {8{| a_in[23:16]}}, {8{| a_in[15:8]}}, {8{| a_in[7:0]}} }; + + + + // * * * * * * * * * * * * * * * * * * BitManip : ZBSET, ZBCLR, ZBINV * * * * * * * * * * * * * * + + logic [31:0] bitmanip_sb_1hot; + logic [31:0] bitmanip_sb_data; + + assign bitmanip_sb_1hot[31:0] = ( 32'h00000001 << b_in[4:0] ); + + assign bitmanip_sb_data[31:0] = ( {32{ap_bset}} & ( a_in[31:0] | bitmanip_sb_1hot[31:0]) ) | + ( {32{ap_bclr}} & ( a_in[31:0] & ~bitmanip_sb_1hot[31:0]) ) | + ( {32{ap_binv}} & ( a_in[31:0] ^ bitmanip_sb_1hot[31:0]) ); + + + + + + + assign sel_shift = ap.sll | ap.srl | ap.sra | ap_rol | ap_ror; + assign sel_adder = (ap.add | ap.sub | ap_zba) & ~ap.slt & ~ap_min & ~ap_max; + assign sel_pc = ap.jal | pp_in.pcall | pp_in.pja | pp_in.pret; + assign csr_write_data[31:0]= (ap.csr_imm) ? b_in[31:0] : a_in[31:0]; + + assign slt_one = ap.slt & lt; + + + + assign result[31:0] = lout[31:0] | + ({32{sel_shift}} & sout[31:0] ) | + ({32{sel_adder}} & aout[31:0] ) | + ({32{sel_pc}} & {pcout[31:1],1'b0} ) | + ({32{ap.csr_write}} & csr_write_data[31:0] ) | + {31'b0, slt_one} | + ({32{ap_bext}} & {31'b0, sout[0]} ) | + {26'b0, bitmanip_clz_ctz_result[5:0]} | + {26'b0, bitmanip_cpop_result[5:0]} | + bitmanip_sext_result[31:0] | + bitmanip_minmax_result[31:0] | + bitmanip_pack_result[31:0] | + bitmanip_packu_result[31:0] | + bitmanip_packh_result[31:0] | + bitmanip_rev8_result[31:0] | + bitmanip_orc_b_result[31:0] | + bitmanip_sb_data[31:0]; + + + + // *** branch handling *** + + assign any_jal = ap.jal | + pp_in.pcall | + pp_in.pja | + pp_in.pret; + + assign actual_taken = (ap.beq & eq) | + (ap.bne & ne) | + (ap.blt & lt) | + (ap.bge & ge) | + any_jal; + + // for a conditional br pcout[] will be the opposite of the branch prediction + // for jal or pcall, it will be the link address pc+2 or pc+4 + + rvbradder ibradder ( + .pc ( pc_in[31:1] ), + .offset ( brimm_in[12:1] ), + .dout ( pcout[31:1] )); + + + // pred_correct is for the npc logic + // pred_correct indicates not to use the flush_path + // for any_jal pred_correct==0 + + assign pred_correct_out = (valid_in & ap.predict_nt & ~actual_taken & ~any_jal) | + (valid_in & ap.predict_t & actual_taken & ~any_jal); + + + // for any_jal adder output is the flush path + assign flush_path_out[31:1]= (any_jal) ? aout[31:1] : pcout[31:1]; + + + // pcall and pret are included here + assign cond_mispredict = (ap.predict_t & ~actual_taken) | + (ap.predict_nt & actual_taken); + + + // target mispredicts on ret's + + assign target_mispredict = pp_in.pret & (pp_in.prett[31:1] != aout[31:1]); + + assign flush_upper_out = (ap.jal | cond_mispredict | target_mispredict) & valid_in & ~flush_upper_x & ~flush_lower_r; + assign flush_final_out = ( (ap.jal | cond_mispredict | target_mispredict) & valid_in & ~flush_upper_x ) | flush_lower_r; + + + // .i 3 + // .o 2 + // .ilb hist[1] hist[0] taken + // .ob newhist[1] newhist[0] + // .type fd + // + // 00 0 01 + // 01 0 01 + // 10 0 00 + // 11 0 10 + // 00 1 10 + // 01 1 00 + // 10 1 11 + // 11 1 11 + + assign newhist[1] = ( pp_in.hist[1] & pp_in.hist[0]) | (~pp_in.hist[0] & actual_taken); + assign newhist[0] = (~pp_in.hist[1] & ~actual_taken) | ( pp_in.hist[1] & actual_taken); + + always_comb begin + predict_p_out = pp_in; + + predict_p_out.misp = ~flush_upper_x & ~flush_lower_r & (cond_mispredict | target_mispredict); + predict_p_out.ataken = actual_taken; + predict_p_out.hist[1] = newhist[1]; + predict_p_out.hist[0] = newhist[0]; + + end + + + +endmodule // el2_exu_alu_ctl diff --git a/designs/Caliptra/src/caliptra-rtl/el2_exu_div_ctl.sv b/designs/Caliptra/src/caliptra-rtl/el2_exu_div_ctl.sv new file mode 100644 index 0000000..d792840 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/el2_exu_div_ctl.sv @@ -0,0 +1,1819 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2020 Western Digital Corporation or its affiliates. +// +// 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. + + +module el2_exu_div_ctl +import el2_pkg::*; +#( +`include "el2_param.vh" +) + ( + input logic clk, // Top level clock + input logic rst_l, // Reset + // Excluding scan_mode from coverage as its usage is determined by the integrator of the VeeR core. + /*pragma coverage off*/ + input logic scan_mode, // Scan mode + /*pragma coverage on*/ + + input el2_div_pkt_t dp, // valid, sign, rem + input logic [31:0] dividend, // Numerator + input logic [31:0] divisor, // Denominator + + input logic cancel, // Cancel divide + + + output logic finish_dly, // Finish to match data + output logic [31:0] out // Result + ); + + + logic [31:0] out_raw; + + assign out[31:0] = {32{finish_dly}} & out_raw[31:0]; // Qualification added to quiet result bus while divide is iterating + + + + if (pt.DIV_NEW == 0) + begin : genblock1 + el2_exu_div_existing_1bit_cheapshortq i_existing_1bit_div_cheapshortq ( + .clk ( clk ), // I + .rst_l ( rst_l ), // I + .scan_mode ( scan_mode ), // I + .cancel ( cancel ), // I + .valid_in ( dp.valid ), // I + .signed_in (~dp.unsign ), // I + .rem_in ( dp.rem ), // I + .dividend_in ( dividend[31:0] ), // I + .divisor_in ( divisor[31:0] ), // I + .valid_out ( finish_dly ), // O + .data_out ( out_raw[31:0] )); // O + end + + + if ( (pt.DIV_NEW == 1) & (pt.DIV_BIT == 1) ) + begin : genblock2 + el2_exu_div_new_1bit_fullshortq i_new_1bit_div_fullshortq ( + .clk ( clk ), // I + .rst_l ( rst_l ), // I + .scan_mode ( scan_mode ), // I + .cancel ( cancel ), // I + .valid_in ( dp.valid ), // I + .signed_in (~dp.unsign ), // I + .rem_in ( dp.rem ), // I + .dividend_in ( dividend[31:0] ), // I + .divisor_in ( divisor[31:0] ), // I + .valid_out ( finish_dly ), // O + .data_out ( out_raw[31:0] )); // O + end + + + if ( (pt.DIV_NEW == 1) & (pt.DIV_BIT == 2) ) + begin : genblock3 + el2_exu_div_new_2bit_fullshortq i_new_2bit_div_fullshortq ( + .clk ( clk ), // I + .rst_l ( rst_l ), // I + .scan_mode ( scan_mode ), // I + .cancel ( cancel ), // I + .valid_in ( dp.valid ), // I + .signed_in (~dp.unsign ), // I + .rem_in ( dp.rem ), // I + .dividend_in ( dividend[31:0] ), // I + .divisor_in ( divisor[31:0] ), // I + .valid_out ( finish_dly ), // O + .data_out ( out_raw[31:0] )); // O + end + + + if ( (pt.DIV_NEW == 1) & (pt.DIV_BIT == 3) ) + begin : genblock4 + el2_exu_div_new_3bit_fullshortq i_new_3bit_div_fullshortq ( + .clk ( clk ), // I + .rst_l ( rst_l ), // I + .scan_mode ( scan_mode ), // I + .cancel ( cancel ), // I + .valid_in ( dp.valid ), // I + .signed_in (~dp.unsign ), // I + .rem_in ( dp.rem ), // I + .dividend_in ( dividend[31:0] ), // I + .divisor_in ( divisor[31:0] ), // I + .valid_out ( finish_dly ), // O + .data_out ( out_raw[31:0] )); // O + end + + + if ( (pt.DIV_NEW == 1) & (pt.DIV_BIT == 4) ) + begin : genblock5 + el2_exu_div_new_4bit_fullshortq i_new_4bit_div_fullshortq ( + .clk ( clk ), // I + .rst_l ( rst_l ), // I + .scan_mode ( scan_mode ), // I + .cancel ( cancel ), // I + .valid_in ( dp.valid ), // I + .signed_in (~dp.unsign ), // I + .rem_in ( dp.rem ), // I + .dividend_in ( dividend[31:0] ), // I + .divisor_in ( divisor[31:0] ), // I + .valid_out ( finish_dly ), // O + .data_out ( out_raw[31:0] )); // O + end + + + +endmodule // el2_exu_div_ctl + + + + + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +module el2_exu_div_existing_1bit_cheapshortq + ( + input logic clk, // Top level clock + input logic rst_l, // Reset + // Excluding scan_mode from coverage as its usage is determined by the integrator of the VeeR core. + /*pragma coverage off*/ + input logic scan_mode, // Scan mode + /*pragma coverage on*/ + + input logic cancel, // Flush pipeline + input logic valid_in, + input logic signed_in, + input logic rem_in, + input logic [31:0] dividend_in, + input logic [31:0] divisor_in, + + output logic valid_out, + output logic [31:0] data_out + ); + + + logic div_clken; + logic run_in, run_state; + logic [5:0] count_in, count; + logic [32:0] m_ff; + logic qff_enable; + logic aff_enable; + logic [32:0] q_in, q_ff; + logic [32:0] a_in, a_ff; + logic [32:0] m_eff; + logic [32:0] a_shift; + logic dividend_neg_ff, divisor_neg_ff; + logic [31:0] dividend_comp; + logic [31:0] dividend_eff; + logic [31:0] q_ff_comp; + logic [31:0] q_ff_eff; + logic [31:0] a_ff_comp; + logic [31:0] a_ff_eff; + logic sign_ff, sign_eff; + logic rem_ff; + logic add; + logic [32:0] a_eff; + logic [64:0] a_eff_shift; + logic rem_correct; + logic valid_ff_x; + logic valid_x; + logic finish; + logic finish_ff; + + logic smallnum_case, smallnum_case_ff; + logic [3:0] smallnum, smallnum_ff; + logic m_already_comp; + + logic [4:0] a_cls; + logic [4:0] b_cls; + logic [5:0] shortq_shift; + logic [5:0] shortq_shift_ff; + logic [5:0] shortq; + logic shortq_enable; + logic shortq_enable_ff; + logic [32:0] short_dividend; + logic [3:0] shortq_raw; + logic [3:0] shortq_shift_xx; + + + + rvdffe #(23) i_misc_ff (.*, .clk(clk), .en(div_clken), .din ({valid_in & ~cancel, + finish & ~cancel, + run_in, + count_in[5:0], + (valid_in & dividend_in[31]) | (~valid_in & dividend_neg_ff), + (valid_in & divisor_in[31] ) | (~valid_in & divisor_neg_ff ), + (valid_in & sign_eff ) | (~valid_in & sign_ff ), + (valid_in & rem_in ) | (~valid_in & rem_ff ), + smallnum_case, + smallnum[3:0], + shortq_enable, + shortq_shift[3:0]}), + + .dout({valid_ff_x, + finish_ff, + run_state, + count[5:0], + dividend_neg_ff, + divisor_neg_ff, + sign_ff, + rem_ff, + smallnum_case_ff, + smallnum_ff[3:0], + shortq_enable_ff, + shortq_shift_xx[3:0]})); + + + rvdffe #(33) mff (.*, .clk(clk), .en(valid_in), .din({signed_in & divisor_in[31], divisor_in[31:0]}), .dout(m_ff[32:0])); + rvdffe #(33) qff (.*, .clk(clk), .en(qff_enable), .din(q_in[32:0]), .dout(q_ff[32:0])); + rvdffe #(33) aff (.*, .clk(clk), .en(aff_enable), .din(a_in[32:0]), .dout(a_ff[32:0])); + + rvtwoscomp #(32) i_dividend_comp (.din(q_ff[31:0]), .dout(dividend_comp[31:0])); + rvtwoscomp #(32) i_q_ff_comp (.din(q_ff[31:0]), .dout(q_ff_comp[31:0])); + rvtwoscomp #(32) i_a_ff_comp (.din(a_ff[31:0]), .dout(a_ff_comp[31:0])); + + + assign valid_x = valid_ff_x & ~cancel; + + + // START - short circuit logic for small numbers {{ + + // small number divides - any 4b / 4b is done in 1 cycle (divisor != 0) + // to generate espresso equations: + // 1. smalldiv > smalldiv.e + // 2. espresso -Dso -oeqntott smalldiv.e | addassign > smalldiv + + // smallnum case does not cover divide by 0 + assign smallnum_case = ((q_ff[31:4] == 28'b0) & (m_ff[31:4] == 28'b0) & (m_ff[31:0] != 32'b0) & ~rem_ff & valid_x) | + ((q_ff[31:0] == 32'b0) & (m_ff[31:0] != 32'b0) & ~rem_ff & valid_x); + + + assign smallnum[3] = ( q_ff[3] & ~m_ff[3] & ~m_ff[2] & ~m_ff[1] ); + + + assign smallnum[2] = ( q_ff[3] & ~m_ff[3] & ~m_ff[2] & ~m_ff[0]) | + ( q_ff[2] & ~m_ff[3] & ~m_ff[2] & ~m_ff[1] ) | + ( q_ff[3] & q_ff[2] & ~m_ff[3] & ~m_ff[2] ); + + + assign smallnum[1] = ( q_ff[2] & ~m_ff[3] & ~m_ff[2] & ~m_ff[0]) | + ( q_ff[1] & ~m_ff[3] & ~m_ff[2] & ~m_ff[1] ) | + ( q_ff[3] & ~m_ff[3] & ~m_ff[1] & ~m_ff[0]) | + ( q_ff[3] & ~q_ff[2] & ~m_ff[3] & ~m_ff[2] & m_ff[1] & m_ff[0]) | + (~q_ff[3] & q_ff[2] & q_ff[1] & ~m_ff[3] & ~m_ff[2] ) | + ( q_ff[3] & q_ff[2] & ~m_ff[3] & ~m_ff[0]) | + ( q_ff[3] & q_ff[2] & ~m_ff[3] & m_ff[2] & ~m_ff[1] ) | + ( q_ff[3] & q_ff[1] & ~m_ff[3] & ~m_ff[1] ) | + ( q_ff[3] & q_ff[2] & q_ff[1] & ~m_ff[3] & m_ff[2] ); + + + assign smallnum[0] = ( q_ff[2] & q_ff[1] & q_ff[0] & ~m_ff[3] & ~m_ff[1] ) | + ( q_ff[3] & ~q_ff[2] & q_ff[0] & ~m_ff[3] & m_ff[1] & m_ff[0]) | + ( q_ff[2] & ~m_ff[3] & ~m_ff[1] & ~m_ff[0]) | + ( q_ff[1] & ~m_ff[3] & ~m_ff[2] & ~m_ff[0]) | + ( q_ff[0] & ~m_ff[3] & ~m_ff[2] & ~m_ff[1] ) | + (~q_ff[3] & q_ff[2] & ~q_ff[1] & ~m_ff[3] & ~m_ff[2] & m_ff[1] & m_ff[0]) | + (~q_ff[3] & q_ff[2] & q_ff[1] & ~m_ff[3] & ~m_ff[0]) | + ( q_ff[3] & ~m_ff[2] & ~m_ff[1] & ~m_ff[0]) | + ( q_ff[3] & ~q_ff[2] & ~m_ff[3] & m_ff[2] & m_ff[1] ) | + (~q_ff[3] & q_ff[2] & q_ff[1] & ~m_ff[3] & m_ff[2] & ~m_ff[1] ) | + (~q_ff[3] & q_ff[2] & q_ff[0] & ~m_ff[3] & ~m_ff[1] ) | + ( q_ff[3] & ~q_ff[2] & ~q_ff[1] & ~m_ff[3] & m_ff[2] & m_ff[0]) | + ( ~q_ff[2] & q_ff[1] & q_ff[0] & ~m_ff[3] & ~m_ff[2] ) | + ( q_ff[3] & q_ff[2] & ~m_ff[1] & ~m_ff[0]) | + ( q_ff[3] & q_ff[1] & ~m_ff[2] & ~m_ff[0]) | + (~q_ff[3] & q_ff[2] & q_ff[1] & q_ff[0] & ~m_ff[3] & m_ff[2] ) | + ( q_ff[3] & q_ff[2] & m_ff[3] & ~m_ff[2] ) | + ( q_ff[3] & q_ff[1] & m_ff[3] & ~m_ff[2] & ~m_ff[1] ) | + ( q_ff[3] & q_ff[0] & ~m_ff[2] & ~m_ff[1] ) | + ( q_ff[3] & ~q_ff[1] & ~m_ff[3] & m_ff[2] & m_ff[1] & m_ff[0]) | + ( q_ff[3] & q_ff[2] & q_ff[1] & m_ff[3] & ~m_ff[0]) | + ( q_ff[3] & q_ff[2] & q_ff[1] & m_ff[3] & ~m_ff[1] ) | + ( q_ff[3] & q_ff[2] & q_ff[0] & m_ff[3] & ~m_ff[1] ) | + ( q_ff[3] & ~q_ff[2] & q_ff[1] & ~m_ff[3] & m_ff[1] ) | + ( q_ff[3] & q_ff[1] & q_ff[0] & ~m_ff[2] ) | + ( q_ff[3] & q_ff[2] & q_ff[1] & q_ff[0] & m_ff[3] ); + + + // END - short circuit logic for small numbers }} + + + // *** Start Short Q *** {{ + + assign short_dividend[31:0] = q_ff[31:0]; + assign short_dividend[32] = sign_ff & q_ff[31]; + + + // A B + // 210 210 SH + // --- --- -- + // 1xx 000 0 + // 1xx 001 8 + // 1xx 01x 16 + // 1xx 1xx 24 + // 01x 000 8 + // 01x 001 16 + // 01x 01x 24 + // 01x 1xx 32 + // 001 000 16 + // 001 001 24 + // 001 01x 32 + // 001 1xx 32 + // 000 000 24 + // 000 001 32 + // 000 01x 32 + // 000 1xx 32 + + assign a_cls[4:3] = 2'b0; + assign a_cls[2] = (~short_dividend[32] & (short_dividend[31:24] != {8{1'b0}})) | ( short_dividend[32] & (short_dividend[31:23] != {9{1'b1}})); + assign a_cls[1] = (~short_dividend[32] & (short_dividend[23:16] != {8{1'b0}})) | ( short_dividend[32] & (short_dividend[22:15] != {8{1'b1}})); + assign a_cls[0] = (~short_dividend[32] & (short_dividend[15:08] != {8{1'b0}})) | ( short_dividend[32] & (short_dividend[14:07] != {8{1'b1}})); + + assign b_cls[4:3] = 2'b0; + assign b_cls[2] = (~m_ff[32] & ( m_ff[31:24] != {8{1'b0}})) | ( m_ff[32] & ( m_ff[31:24] != {8{1'b1}})); + assign b_cls[1] = (~m_ff[32] & ( m_ff[23:16] != {8{1'b0}})) | ( m_ff[32] & ( m_ff[23:16] != {8{1'b1}})); + assign b_cls[0] = (~m_ff[32] & ( m_ff[15:08] != {8{1'b0}})) | ( m_ff[32] & ( m_ff[15:08] != {8{1'b1}})); + + assign shortq_raw[3] = ( (a_cls[2:1] == 2'b01 ) & (b_cls[2] == 1'b1 ) ) | // Shift by 32 + ( (a_cls[2:0] == 3'b001) & (b_cls[2] == 1'b1 ) ) | + ( (a_cls[2:0] == 3'b000) & (b_cls[2] == 1'b1 ) ) | + ( (a_cls[2:0] == 3'b001) & (b_cls[2:1] == 2'b01 ) ) | + ( (a_cls[2:0] == 3'b000) & (b_cls[2:1] == 2'b01 ) ) | + ( (a_cls[2:0] == 3'b000) & (b_cls[2:0] == 3'b001) ); + + assign shortq_raw[2] = ( (a_cls[2] == 1'b1 ) & (b_cls[2] == 1'b1 ) ) | // Shift by 24 + ( (a_cls[2:1] == 2'b01 ) & (b_cls[2:1] == 2'b01 ) ) | + ( (a_cls[2:0] == 3'b001) & (b_cls[2:0] == 3'b001) ) | + ( (a_cls[2:0] == 3'b000) & (b_cls[2:0] == 3'b000) ); + + assign shortq_raw[1] = ( (a_cls[2] == 1'b1 ) & (b_cls[2:1] == 2'b01 ) ) | // Shift by 16 + ( (a_cls[2:1] == 2'b01 ) & (b_cls[2:0] == 3'b001) ) | + ( (a_cls[2:0] == 3'b001) & (b_cls[2:0] == 3'b000) ); + + assign shortq_raw[0] = ( (a_cls[2] == 1'b1 ) & (b_cls[2:0] == 3'b001) ) | // Shift by 8 + ( (a_cls[2:1] == 2'b01 ) & (b_cls[2:0] == 3'b000) ); + + + assign shortq_enable = valid_ff_x & (m_ff[31:0] != 32'b0) & (shortq_raw[3:0] != 4'b0); + + assign shortq_shift[3:0] = ({4{shortq_enable}} & shortq_raw[3:0]); + + assign shortq[5:0] = 6'b0; + assign shortq_shift[5:4] = 2'b0; + assign shortq_shift_ff[5] = 1'b0; + + assign shortq_shift_ff[4:0] = ({5{shortq_shift_xx[3]}} & 5'b1_1111) | // 31 + ({5{shortq_shift_xx[2]}} & 5'b1_1000) | // 24 + ({5{shortq_shift_xx[1]}} & 5'b1_0000) | // 16 + ({5{shortq_shift_xx[0]}} & 5'b0_1000); // 8 + + // *** End Short *** }} + + + + + + assign div_clken = valid_in | run_state | finish | finish_ff; + + assign run_in = (valid_in | run_state) & ~finish & ~cancel; + + assign count_in[5:0] = {6{run_state & ~finish & ~cancel & ~shortq_enable}} & (count[5:0] + {1'b0,shortq_shift_ff[4:0]} + 6'd1); + + + assign finish = (smallnum_case | ((~rem_ff) ? (count[5:0] == 6'd32) : (count[5:0] == 6'd33))); + + assign valid_out = finish_ff & ~cancel; + + assign sign_eff = signed_in & (divisor_in[31:0] != 32'b0); + + + assign q_in[32:0] = ({33{~run_state }} & {1'b0,dividend_in[31:0]}) | + ({33{ run_state & (valid_ff_x | shortq_enable_ff)}} & ({dividend_eff[31:0], ~a_in[32]} << shortq_shift_ff[4:0])) | + ({33{ run_state & ~(valid_ff_x | shortq_enable_ff)}} & {q_ff[31:0], ~a_in[32]}); + + assign qff_enable = valid_in | (run_state & ~shortq_enable); + + + + + assign dividend_eff[31:0] = (sign_ff & dividend_neg_ff) ? dividend_comp[31:0] : q_ff[31:0]; + + + assign m_eff[32:0] = ( add ) ? m_ff[32:0] : ~m_ff[32:0]; + + assign a_eff_shift[64:0] = {33'b0, dividend_eff[31:0]} << shortq_shift_ff[4:0]; + + assign a_eff[32:0] = ({33{ rem_correct }} & a_ff[32:0] ) | + ({33{~rem_correct & ~shortq_enable_ff}} & {a_ff[31:0], q_ff[32]} ) | + ({33{~rem_correct & shortq_enable_ff}} & a_eff_shift[64:32] ); + + assign a_shift[32:0] = {33{run_state}} & a_eff[32:0]; + + assign a_in[32:0] = {33{run_state}} & (a_shift[32:0] + m_eff[32:0] + {32'b0,~add}); + + assign aff_enable = valid_in | (run_state & ~shortq_enable & (count[5:0]!=6'd33)) | rem_correct; + + + assign m_already_comp = (divisor_neg_ff & sign_ff); + + // if m already complemented, then invert operation add->sub, sub->add + assign add = (a_ff[32] | rem_correct) ^ m_already_comp; + + assign rem_correct = (count[5:0] == 6'd33) & rem_ff & a_ff[32]; + + + + assign q_ff_eff[31:0] = (sign_ff & (dividend_neg_ff ^ divisor_neg_ff)) ? q_ff_comp[31:0] : q_ff[31:0]; + + assign a_ff_eff[31:0] = (sign_ff & dividend_neg_ff) ? a_ff_comp[31:0] : a_ff[31:0]; + + assign data_out[31:0] = ({32{ smallnum_case_ff }} & {28'b0, smallnum_ff[3:0]}) | + ({32{ rem_ff}} & a_ff_eff[31:0] ) | + ({32{~smallnum_case_ff & ~rem_ff}} & q_ff_eff[31:0] ); + + + + +endmodule // el2_exu_div_existing_1bit_cheapshortq + + + + + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +module el2_exu_div_new_1bit_fullshortq + ( + input logic clk, // Top level clock + input logic rst_l, // Reset + // Excluding scan_mode from coverage as its usage is determined by the integrator of the VeeR core. + /*pragma coverage off*/ + input logic scan_mode, // Scan mode + /*pragma coverage on*/ + + input logic cancel, // Flush pipeline + input logic valid_in, + input logic signed_in, + input logic rem_in, + input logic [31:0] dividend_in, + input logic [31:0] divisor_in, + + output logic valid_out, + output logic [31:0] data_out + ); + + + logic valid_ff_in, valid_ff; + logic finish_raw, finish, finish_ff; + logic running_state; + logic misc_enable; + logic [2:0] control_in, control_ff; + logic dividend_sign_ff, divisor_sign_ff, rem_ff; + logic count_enable; + logic [6:0] count_in, count_ff; + + logic smallnum_case; + logic [3:0] smallnum; + + logic a_enable, a_shift; + logic [31:0] a_in, a_ff; + + logic b_enable, b_twos_comp; + logic [32:0] b_in, b_ff; + + logic [31:0] q_in, q_ff; + + logic rq_enable, r_sign_sel, r_restore_sel, r_adder_sel; + logic [31:0] r_in, r_ff; + + logic twos_comp_q_sel, twos_comp_b_sel; + logic [31:0] twos_comp_in, twos_comp_out; + + logic quotient_set; + logic [32:0] adder_out; + + logic [63:0] ar_shifted; + logic [5:0] shortq; + logic [4:0] shortq_shift; + logic [4:0] shortq_shift_ff; + logic shortq_enable; + logic shortq_enable_ff; + logic [32:0] shortq_dividend; + + logic by_zero_case; + logic by_zero_case_ff; + + + + rvdffe #(19) i_misc_ff (.*, .clk(clk), .en(misc_enable), .din ({valid_ff_in, control_in[2:0], by_zero_case, shortq_enable, shortq_shift[4:0], finish, count_in[6:0]}), + .dout({valid_ff, control_ff[2:0], by_zero_case_ff, shortq_enable_ff, shortq_shift_ff[4:0], finish_ff, count_ff[6:0]})); + + rvdffe #(32) i_a_ff (.*, .clk(clk), .en(a_enable), .din(a_in[31:0]), .dout(a_ff[31:0])); + rvdffe #(33) i_b_ff (.*, .clk(clk), .en(b_enable), .din(b_in[32:0]), .dout(b_ff[32:0])); + rvdffe #(32) i_r_ff (.*, .clk(clk), .en(rq_enable), .din(r_in[31:0]), .dout(r_ff[31:0])); + rvdffe #(32) i_q_ff (.*, .clk(clk), .en(rq_enable), .din(q_in[31:0]), .dout(q_ff[31:0])); + + + + + assign valid_ff_in = valid_in & ~cancel; + + assign control_in[2] = (~valid_in & control_ff[2]) | (valid_in & signed_in & dividend_in[31]); + assign control_in[1] = (~valid_in & control_ff[1]) | (valid_in & signed_in & divisor_in[31]); + assign control_in[0] = (~valid_in & control_ff[0]) | (valid_in & rem_in); + + assign dividend_sign_ff = control_ff[2]; + assign divisor_sign_ff = control_ff[1]; + assign rem_ff = control_ff[0]; + + + assign by_zero_case = valid_ff & (b_ff[31:0] == 32'b0); + + assign misc_enable = valid_in | valid_ff | cancel | running_state | finish_ff; + assign running_state = (| count_ff[6:0]) | shortq_enable_ff; + assign finish_raw = smallnum_case | + by_zero_case | + (count_ff[6:0] == 7'd32); + + + assign finish = finish_raw & ~cancel; + assign count_enable = (valid_ff | running_state) & ~finish & ~finish_ff & ~cancel & ~shortq_enable; + assign count_in[6:0] = {7{count_enable}} & (count_ff[6:0] + {6'b0,1'b1} + {2'b0,shortq_shift_ff[4:0]}); + + + assign a_enable = valid_in | running_state; + assign a_shift = running_state & ~shortq_enable_ff; + + assign ar_shifted[63:0] = { {32{dividend_sign_ff}} , a_ff[31:0]} << shortq_shift_ff[4:0]; + + assign a_in[31:0] = ( {32{~a_shift & ~shortq_enable_ff}} & dividend_in[31:0] ) | + ( {32{ a_shift }} & {a_ff[30:0],1'b0} ) | + ( {32{ shortq_enable_ff}} & ar_shifted[31:0] ); + + + + assign b_enable = valid_in | b_twos_comp; + assign b_twos_comp = valid_ff & ~(dividend_sign_ff ^ divisor_sign_ff); + + assign b_in[32:0] = ( {33{~b_twos_comp}} & { (signed_in & divisor_in[31]),divisor_in[31:0] } ) | + ( {33{ b_twos_comp}} & {~divisor_sign_ff,twos_comp_out[31:0] } ); + + + assign rq_enable = valid_in | valid_ff | running_state; + assign r_sign_sel = valid_ff & dividend_sign_ff & ~by_zero_case; + assign r_restore_sel = running_state & ~quotient_set & ~shortq_enable_ff; + assign r_adder_sel = running_state & quotient_set & ~shortq_enable_ff; + + + assign r_in[31:0] = ( {32{r_sign_sel }} & 32'hffffffff ) | + ( {32{r_restore_sel }} & {r_ff[30:0] ,a_ff[31]} ) | + ( {32{r_adder_sel }} & adder_out[31:0] ) | + ( {32{shortq_enable_ff}} & ar_shifted[63:32] ) | + ( {32{by_zero_case }} & a_ff[31:0] ); + + + assign q_in[31:0] = ( {32{~valid_ff }} & {q_ff[30:0], quotient_set} ) | + ( {32{ smallnum_case }} & {28'b0 , smallnum[3:0]} ) | + ( {32{ by_zero_case }} & {32{1'b1}} ); + + + + assign adder_out[32:0] = {r_ff[31:0],a_ff[31]} + {b_ff[32:0] }; + + + assign quotient_set = (~adder_out[32] ^ dividend_sign_ff) | ( (a_ff[30:0] == 31'b0) & (adder_out[32:0] == 33'b0) ); + + + + assign twos_comp_b_sel = valid_ff & ~(dividend_sign_ff ^ divisor_sign_ff); + assign twos_comp_q_sel = ~valid_ff & ~rem_ff & (dividend_sign_ff ^ divisor_sign_ff) & ~by_zero_case_ff; + + assign twos_comp_in[31:0] = ( {32{twos_comp_q_sel}} & q_ff[31:0] ) | + ( {32{twos_comp_b_sel}} & b_ff[31:0] ); + + rvtwoscomp #(32) i_twos_comp (.din(twos_comp_in[31:0]), .dout(twos_comp_out[31:0])); + + + + assign valid_out = finish_ff & ~cancel; + + assign data_out[31:0] = ( {32{~rem_ff & ~twos_comp_q_sel}} & q_ff[31:0] ) | + ( {32{ rem_ff }} & r_ff[31:0] ) | + ( {32{ twos_comp_q_sel}} & twos_comp_out[31:0] ); + + + + + // *** *** *** START : SMALLNUM {{ + + assign smallnum_case = ( (a_ff[31:4] == 28'b0) & (b_ff[31:4] == 28'b0) & ~by_zero_case & ~rem_ff & valid_ff & ~cancel) | + ( (a_ff[31:0] == 32'b0) & ~by_zero_case & ~rem_ff & valid_ff & ~cancel); + + assign smallnum[3] = ( a_ff[3] & ~b_ff[3] & ~b_ff[2] & ~b_ff[1] ); + + assign smallnum[2] = ( a_ff[3] & ~b_ff[3] & ~b_ff[2] & ~b_ff[0]) | + ( a_ff[2] & ~b_ff[3] & ~b_ff[2] & ~b_ff[1] ) | + ( a_ff[3] & a_ff[2] & ~b_ff[3] & ~b_ff[2] ); + + assign smallnum[1] = ( a_ff[2] & ~b_ff[3] & ~b_ff[2] & ~b_ff[0]) | + ( a_ff[1] & ~b_ff[3] & ~b_ff[2] & ~b_ff[1] ) | + ( a_ff[3] & ~b_ff[3] & ~b_ff[1] & ~b_ff[0]) | + ( a_ff[3] & ~a_ff[2] & ~b_ff[3] & ~b_ff[2] & b_ff[1] & b_ff[0]) | + (~a_ff[3] & a_ff[2] & a_ff[1] & ~b_ff[3] & ~b_ff[2] ) | + ( a_ff[3] & a_ff[2] & ~b_ff[3] & ~b_ff[0]) | + ( a_ff[3] & a_ff[2] & ~b_ff[3] & b_ff[2] & ~b_ff[1] ) | + ( a_ff[3] & a_ff[1] & ~b_ff[3] & ~b_ff[1] ) | + ( a_ff[3] & a_ff[2] & a_ff[1] & ~b_ff[3] & b_ff[2] ); + + assign smallnum[0] = ( a_ff[2] & a_ff[1] & a_ff[0] & ~b_ff[3] & ~b_ff[1] ) | + ( a_ff[3] & ~a_ff[2] & a_ff[0] & ~b_ff[3] & b_ff[1] & b_ff[0]) | + ( a_ff[2] & ~b_ff[3] & ~b_ff[1] & ~b_ff[0]) | + ( a_ff[1] & ~b_ff[3] & ~b_ff[2] & ~b_ff[0]) | + ( a_ff[0] & ~b_ff[3] & ~b_ff[2] & ~b_ff[1] ) | + (~a_ff[3] & a_ff[2] & ~a_ff[1] & ~b_ff[3] & ~b_ff[2] & b_ff[1] & b_ff[0]) | + (~a_ff[3] & a_ff[2] & a_ff[1] & ~b_ff[3] & ~b_ff[0]) | + ( a_ff[3] & ~b_ff[2] & ~b_ff[1] & ~b_ff[0]) | + ( a_ff[3] & ~a_ff[2] & ~b_ff[3] & b_ff[2] & b_ff[1] ) | + (~a_ff[3] & a_ff[2] & a_ff[1] & ~b_ff[3] & b_ff[2] & ~b_ff[1] ) | + (~a_ff[3] & a_ff[2] & a_ff[0] & ~b_ff[3] & ~b_ff[1] ) | + ( a_ff[3] & ~a_ff[2] & ~a_ff[1] & ~b_ff[3] & b_ff[2] & b_ff[0]) | + ( ~a_ff[2] & a_ff[1] & a_ff[0] & ~b_ff[3] & ~b_ff[2] ) | + ( a_ff[3] & a_ff[2] & ~b_ff[1] & ~b_ff[0]) | + ( a_ff[3] & a_ff[1] & ~b_ff[2] & ~b_ff[0]) | + (~a_ff[3] & a_ff[2] & a_ff[1] & a_ff[0] & ~b_ff[3] & b_ff[2] ) | + ( a_ff[3] & a_ff[2] & b_ff[3] & ~b_ff[2] ) | + ( a_ff[3] & a_ff[1] & b_ff[3] & ~b_ff[2] & ~b_ff[1] ) | + ( a_ff[3] & a_ff[0] & ~b_ff[2] & ~b_ff[1] ) | + ( a_ff[3] & ~a_ff[1] & ~b_ff[3] & b_ff[2] & b_ff[1] & b_ff[0]) | + ( a_ff[3] & a_ff[2] & a_ff[1] & b_ff[3] & ~b_ff[0]) | + ( a_ff[3] & a_ff[2] & a_ff[1] & b_ff[3] & ~b_ff[1] ) | + ( a_ff[3] & a_ff[2] & a_ff[0] & b_ff[3] & ~b_ff[1] ) | + ( a_ff[3] & ~a_ff[2] & a_ff[1] & ~b_ff[3] & b_ff[1] ) | + ( a_ff[3] & a_ff[1] & a_ff[0] & ~b_ff[2] ) | + ( a_ff[3] & a_ff[2] & a_ff[1] & a_ff[0] & b_ff[3] ); + + // *** *** *** END : SMALLNUM }} + + + + + // *** *** *** Start : Short Q {{ + + assign shortq_dividend[32:0] = {dividend_sign_ff,a_ff[31:0]}; + + + logic [5:0] dw_a_enc; + logic [5:0] dw_b_enc; + logic [6:0] dw_shortq_raw; + + + + el2_exu_div_cls i_a_cls ( + .operand ( shortq_dividend[32:0] ), + .cls ( dw_a_enc[4:0] )); + + el2_exu_div_cls i_b_cls ( + .operand ( b_ff[32:0] ), + .cls ( dw_b_enc[4:0] )); + + assign dw_a_enc[5] = 1'b0; + assign dw_b_enc[5] = 1'b0; + + + + assign dw_shortq_raw[6:0] = {1'b0,dw_b_enc[5:0]} - {1'b0,dw_a_enc[5:0]} + 7'd1; + assign shortq[5:0] = dw_shortq_raw[6] ? 6'd0 : dw_shortq_raw[5:0]; + + assign shortq_enable = valid_ff & ~shortq[5] & ~(shortq[4:1] == 4'b1111) & ~cancel; + + assign shortq_shift[4:0] = ~shortq_enable ? 5'd0 : (5'b11111 - shortq[4:0]); + + + // *** *** *** End : Short Q }} + + + + + +endmodule // el2_exu_div_new_1bit_fullshortq + + + + + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +module el2_exu_div_new_2bit_fullshortq + ( + input logic clk, // Top level clock + input logic rst_l, // Reset + // Excluding scan_mode from coverage as its usage is determined by the integrator of the VeeR core. + /*pragma coverage off*/ + input logic scan_mode, // Scan mode + /*pragma coverage on*/ + + input logic cancel, // Flush pipeline + input logic valid_in, + input logic signed_in, + input logic rem_in, + input logic [31:0] dividend_in, + input logic [31:0] divisor_in, + + output logic valid_out, + output logic [31:0] data_out + ); + + + logic valid_ff_in, valid_ff; + logic finish_raw, finish, finish_ff; + logic running_state; + logic misc_enable; + logic [2:0] control_in, control_ff; + logic dividend_sign_ff, divisor_sign_ff, rem_ff; + logic count_enable; + logic [6:0] count_in, count_ff; + + logic smallnum_case; + logic [3:0] smallnum; + + logic a_enable, a_shift; + logic [31:0] a_in, a_ff; + + logic b_enable, b_twos_comp; + logic [32:0] b_in; + logic [34:0] b_ff; + + logic [31:0] q_in, q_ff; + + logic rq_enable, r_sign_sel, r_restore_sel, r_adder1_sel, r_adder2_sel, r_adder3_sel; + logic [31:0] r_in, r_ff; + + logic twos_comp_q_sel, twos_comp_b_sel; + logic [31:0] twos_comp_in, twos_comp_out; + + logic [3:1] quotient_raw; + logic [1:0] quotient_new; + logic [32:0] adder1_out; + logic [33:0] adder2_out; + logic [34:0] adder3_out; + + logic [63:0] ar_shifted; + logic [5:0] shortq; + logic [4:0] shortq_shift; + logic [4:1] shortq_shift_ff; + logic shortq_enable; + logic shortq_enable_ff; + logic [32:0] shortq_dividend; + + logic by_zero_case; + logic by_zero_case_ff; + + + + rvdffe #(18) i_misc_ff (.*, .clk(clk), .en(misc_enable), .din ({valid_ff_in, control_in[2:0], by_zero_case, shortq_enable, shortq_shift[4:1], finish, count_in[6:0]}), + .dout({valid_ff, control_ff[2:0], by_zero_case_ff, shortq_enable_ff, shortq_shift_ff[4:1], finish_ff, count_ff[6:0]})); + + rvdffe #(32) i_a_ff (.*, .clk(clk), .en(a_enable), .din(a_in[31:0]), .dout(a_ff[31:0])); + rvdffe #(33) i_b_ff (.*, .clk(clk), .en(b_enable), .din(b_in[32:0]), .dout(b_ff[32:0])); + rvdffe #(32) i_r_ff (.*, .clk(clk), .en(rq_enable), .din(r_in[31:0]), .dout(r_ff[31:0])); + rvdffe #(32) i_q_ff (.*, .clk(clk), .en(rq_enable), .din(q_in[31:0]), .dout(q_ff[31:0])); + + + + + assign valid_ff_in = valid_in & ~cancel; + + assign control_in[2] = (~valid_in & control_ff[2]) | (valid_in & signed_in & dividend_in[31]); + assign control_in[1] = (~valid_in & control_ff[1]) | (valid_in & signed_in & divisor_in[31]); + assign control_in[0] = (~valid_in & control_ff[0]) | (valid_in & rem_in); + + assign dividend_sign_ff = control_ff[2]; + assign divisor_sign_ff = control_ff[1]; + assign rem_ff = control_ff[0]; + + + assign by_zero_case = valid_ff & (b_ff[31:0] == 32'b0); + + assign misc_enable = valid_in | valid_ff | cancel | running_state | finish_ff; + assign running_state = (| count_ff[6:0]) | shortq_enable_ff; + assign finish_raw = smallnum_case | + by_zero_case | + (count_ff[6:0] == 7'd32); + + + assign finish = finish_raw & ~cancel; + assign count_enable = (valid_ff | running_state) & ~finish & ~finish_ff & ~cancel & ~shortq_enable; + assign count_in[6:0] = {7{count_enable}} & (count_ff[6:0] + {5'b0,2'b10} + {2'b0,shortq_shift_ff[4:1],1'b0}); + + + assign a_enable = valid_in | running_state; + assign a_shift = running_state & ~shortq_enable_ff; + + assign ar_shifted[63:0] = { {32{dividend_sign_ff}} , a_ff[31:0]} << {shortq_shift_ff[4:1],1'b0}; + + assign a_in[31:0] = ( {32{~a_shift & ~shortq_enable_ff}} & dividend_in[31:0] ) | + ( {32{ a_shift }} & {a_ff[29:0],2'b0} ) | + ( {32{ shortq_enable_ff}} & ar_shifted[31:0] ); + + + + assign b_enable = valid_in | b_twos_comp; + assign b_twos_comp = valid_ff & ~(dividend_sign_ff ^ divisor_sign_ff); + + assign b_in[32:0] = ( {33{~b_twos_comp}} & { (signed_in & divisor_in[31]),divisor_in[31:0] } ) | + ( {33{ b_twos_comp}} & {~divisor_sign_ff,twos_comp_out[31:0] } ); + + + assign rq_enable = valid_in | valid_ff | running_state; + assign r_sign_sel = valid_ff & dividend_sign_ff & ~by_zero_case; + assign r_restore_sel = running_state & (quotient_new[1:0] == 2'b00) & ~shortq_enable_ff; + assign r_adder1_sel = running_state & (quotient_new[1:0] == 2'b01) & ~shortq_enable_ff; + assign r_adder2_sel = running_state & (quotient_new[1:0] == 2'b10) & ~shortq_enable_ff; + assign r_adder3_sel = running_state & (quotient_new[1:0] == 2'b11) & ~shortq_enable_ff; + + + assign r_in[31:0] = ( {32{r_sign_sel }} & 32'hffffffff ) | + ( {32{r_restore_sel }} & {r_ff[29:0] ,a_ff[31:30]} ) | + ( {32{r_adder1_sel }} & adder1_out[31:0] ) | + ( {32{r_adder2_sel }} & adder2_out[31:0] ) | + ( {32{r_adder3_sel }} & adder3_out[31:0] ) | + ( {32{shortq_enable_ff}} & ar_shifted[63:32] ) | + ( {32{by_zero_case }} & a_ff[31:0] ); + + + assign q_in[31:0] = ( {32{~valid_ff }} & {q_ff[29:0], quotient_new[1:0]} ) | + ( {32{ smallnum_case }} & {28'b0 , smallnum[3:0]} ) | + ( {32{ by_zero_case }} & {32{1'b1}} ); + + + assign b_ff[34:33] = {b_ff[32],b_ff[32]}; + + + assign adder1_out[32:0] = { r_ff[30:0],a_ff[31:30]} + b_ff[32:0]; + assign adder2_out[33:0] = { r_ff[31:0],a_ff[31:30]} + {b_ff[32:0],1'b0}; + assign adder3_out[34:0] = {r_ff[31],r_ff[31:0],a_ff[31:30]} + {b_ff[33:0],1'b0} + b_ff[34:0]; + + + assign quotient_raw[1] = (~adder1_out[32] ^ dividend_sign_ff) | ( (a_ff[29:0] == 30'b0) & (adder1_out[32:0] == 33'b0) ); + assign quotient_raw[2] = (~adder2_out[33] ^ dividend_sign_ff) | ( (a_ff[29:0] == 30'b0) & (adder2_out[33:0] == 34'b0) ); + assign quotient_raw[3] = (~adder3_out[34] ^ dividend_sign_ff) | ( (a_ff[29:0] == 30'b0) & (adder3_out[34:0] == 35'b0) ); + + assign quotient_new[1] = quotient_raw[3] | quotient_raw[2]; + assign quotient_new[0] = quotient_raw[3] |(~quotient_raw[2] & quotient_raw[1]); + + + assign twos_comp_b_sel = valid_ff & ~(dividend_sign_ff ^ divisor_sign_ff); + assign twos_comp_q_sel = ~valid_ff & ~rem_ff & (dividend_sign_ff ^ divisor_sign_ff) & ~by_zero_case_ff; + + assign twos_comp_in[31:0] = ( {32{twos_comp_q_sel}} & q_ff[31:0] ) | + ( {32{twos_comp_b_sel}} & b_ff[31:0] ); + + rvtwoscomp #(32) i_twos_comp (.din(twos_comp_in[31:0]), .dout(twos_comp_out[31:0])); + + + + assign valid_out = finish_ff & ~cancel; + + assign data_out[31:0] = ( {32{~rem_ff & ~twos_comp_q_sel}} & q_ff[31:0] ) | + ( {32{ rem_ff }} & r_ff[31:0] ) | + ( {32{ twos_comp_q_sel}} & twos_comp_out[31:0] ); + + + + + // *** *** *** START : SMALLNUM {{ + + assign smallnum_case = ( (a_ff[31:4] == 28'b0) & (b_ff[31:4] == 28'b0) & ~by_zero_case & ~rem_ff & valid_ff & ~cancel) | + ( (a_ff[31:0] == 32'b0) & ~by_zero_case & ~rem_ff & valid_ff & ~cancel); + + assign smallnum[3] = ( a_ff[3] & ~b_ff[3] & ~b_ff[2] & ~b_ff[1] ); + + assign smallnum[2] = ( a_ff[3] & ~b_ff[3] & ~b_ff[2] & ~b_ff[0]) | + ( a_ff[2] & ~b_ff[3] & ~b_ff[2] & ~b_ff[1] ) | + ( a_ff[3] & a_ff[2] & ~b_ff[3] & ~b_ff[2] ); + + assign smallnum[1] = ( a_ff[2] & ~b_ff[3] & ~b_ff[2] & ~b_ff[0]) | + ( a_ff[1] & ~b_ff[3] & ~b_ff[2] & ~b_ff[1] ) | + ( a_ff[3] & ~b_ff[3] & ~b_ff[1] & ~b_ff[0]) | + ( a_ff[3] & ~a_ff[2] & ~b_ff[3] & ~b_ff[2] & b_ff[1] & b_ff[0]) | + (~a_ff[3] & a_ff[2] & a_ff[1] & ~b_ff[3] & ~b_ff[2] ) | + ( a_ff[3] & a_ff[2] & ~b_ff[3] & ~b_ff[0]) | + ( a_ff[3] & a_ff[2] & ~b_ff[3] & b_ff[2] & ~b_ff[1] ) | + ( a_ff[3] & a_ff[1] & ~b_ff[3] & ~b_ff[1] ) | + ( a_ff[3] & a_ff[2] & a_ff[1] & ~b_ff[3] & b_ff[2] ); + + assign smallnum[0] = ( a_ff[2] & a_ff[1] & a_ff[0] & ~b_ff[3] & ~b_ff[1] ) | + ( a_ff[3] & ~a_ff[2] & a_ff[0] & ~b_ff[3] & b_ff[1] & b_ff[0]) | + ( a_ff[2] & ~b_ff[3] & ~b_ff[1] & ~b_ff[0]) | + ( a_ff[1] & ~b_ff[3] & ~b_ff[2] & ~b_ff[0]) | + ( a_ff[0] & ~b_ff[3] & ~b_ff[2] & ~b_ff[1] ) | + (~a_ff[3] & a_ff[2] & ~a_ff[1] & ~b_ff[3] & ~b_ff[2] & b_ff[1] & b_ff[0]) | + (~a_ff[3] & a_ff[2] & a_ff[1] & ~b_ff[3] & ~b_ff[0]) | + ( a_ff[3] & ~b_ff[2] & ~b_ff[1] & ~b_ff[0]) | + ( a_ff[3] & ~a_ff[2] & ~b_ff[3] & b_ff[2] & b_ff[1] ) | + (~a_ff[3] & a_ff[2] & a_ff[1] & ~b_ff[3] & b_ff[2] & ~b_ff[1] ) | + (~a_ff[3] & a_ff[2] & a_ff[0] & ~b_ff[3] & ~b_ff[1] ) | + ( a_ff[3] & ~a_ff[2] & ~a_ff[1] & ~b_ff[3] & b_ff[2] & b_ff[0]) | + ( ~a_ff[2] & a_ff[1] & a_ff[0] & ~b_ff[3] & ~b_ff[2] ) | + ( a_ff[3] & a_ff[2] & ~b_ff[1] & ~b_ff[0]) | + ( a_ff[3] & a_ff[1] & ~b_ff[2] & ~b_ff[0]) | + (~a_ff[3] & a_ff[2] & a_ff[1] & a_ff[0] & ~b_ff[3] & b_ff[2] ) | + ( a_ff[3] & a_ff[2] & b_ff[3] & ~b_ff[2] ) | + ( a_ff[3] & a_ff[1] & b_ff[3] & ~b_ff[2] & ~b_ff[1] ) | + ( a_ff[3] & a_ff[0] & ~b_ff[2] & ~b_ff[1] ) | + ( a_ff[3] & ~a_ff[1] & ~b_ff[3] & b_ff[2] & b_ff[1] & b_ff[0]) | + ( a_ff[3] & a_ff[2] & a_ff[1] & b_ff[3] & ~b_ff[0]) | + ( a_ff[3] & a_ff[2] & a_ff[1] & b_ff[3] & ~b_ff[1] ) | + ( a_ff[3] & a_ff[2] & a_ff[0] & b_ff[3] & ~b_ff[1] ) | + ( a_ff[3] & ~a_ff[2] & a_ff[1] & ~b_ff[3] & b_ff[1] ) | + ( a_ff[3] & a_ff[1] & a_ff[0] & ~b_ff[2] ) | + ( a_ff[3] & a_ff[2] & a_ff[1] & a_ff[0] & b_ff[3] ); + + // *** *** *** END : SMALLNUM }} + + + + + // *** *** *** Start : Short Q {{ + + assign shortq_dividend[32:0] = {dividend_sign_ff,a_ff[31:0]}; + + + logic [5:0] dw_a_enc; + logic [5:0] dw_b_enc; + logic [6:0] dw_shortq_raw; + + + + el2_exu_div_cls i_a_cls ( + .operand ( shortq_dividend[32:0] ), + .cls ( dw_a_enc[4:0] )); + + el2_exu_div_cls i_b_cls ( + .operand ( b_ff[32:0] ), + .cls ( dw_b_enc[4:0] )); + + assign dw_a_enc[5] = 1'b0; + assign dw_b_enc[5] = 1'b0; + + + + assign dw_shortq_raw[6:0] = {1'b0,dw_b_enc[5:0]} - {1'b0,dw_a_enc[5:0]} + 7'd1; + assign shortq[5:0] = dw_shortq_raw[6] ? 6'd0 : dw_shortq_raw[5:0]; + + assign shortq_enable = valid_ff & ~shortq[5] & ~(shortq[4:1] == 4'b1111) & ~cancel; + + assign shortq_shift[4:0] = ~shortq_enable ? 5'd0 : (5'b11111 - shortq[4:0]); // [0] is unused + + + // *** *** *** End : Short Q }} + + + + + +endmodule // el2_exu_div_new_2bit_fullshortq + + + + + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +module el2_exu_div_new_3bit_fullshortq + ( + input logic clk, // Top level clock + input logic rst_l, // Reset + // Excluding scan_mode from coverage as its usage is determined by the integrator of the VeeR core. + /*pragma coverage off*/ + input logic scan_mode, // Scan mode + /*pragma coverage on*/ + + input logic cancel, // Flush pipeline + input logic valid_in, + input logic signed_in, + input logic rem_in, + input logic [31:0] dividend_in, + input logic [31:0] divisor_in, + + output logic valid_out, + output logic [31:0] data_out + ); + + + logic valid_ff_in, valid_ff; + logic finish_raw, finish, finish_ff; + logic running_state; + logic misc_enable; + logic [2:0] control_in, control_ff; + logic dividend_sign_ff, divisor_sign_ff, rem_ff; + logic count_enable; + logic [6:0] count_in, count_ff; + + logic smallnum_case; + logic [3:0] smallnum; + + logic a_enable, a_shift; + logic [32:0] a_in, a_ff; + + logic b_enable, b_twos_comp; + logic [32:0] b_in; + logic [36:0] b_ff; + + logic [31:0] q_in, q_ff; + + logic rq_enable; + logic r_sign_sel; + logic r_restore_sel; + logic r_adder1_sel, r_adder2_sel, r_adder3_sel, r_adder4_sel, r_adder5_sel, r_adder6_sel, r_adder7_sel; + logic [32:0] r_in, r_ff; + + logic twos_comp_q_sel, twos_comp_b_sel; + logic [31:0] twos_comp_in, twos_comp_out; + + logic [7:1] quotient_raw; + logic [2:0] quotient_new; + logic [33:0] adder1_out; + logic [34:0] adder2_out; + logic [35:0] adder3_out; + logic [36:0] adder4_out; + logic [36:0] adder5_out; + logic [36:0] adder6_out; + logic [36:0] adder7_out; + + logic [65:0] ar_shifted; + logic [5:0] shortq; + logic [4:0] shortq_shift; + logic [4:0] shortq_decode; + logic [4:0] shortq_shift_ff; + logic shortq_enable; + logic shortq_enable_ff; + logic [32:0] shortq_dividend; + + logic by_zero_case; + logic by_zero_case_ff; + + + + rvdffe #(19) i_misc_ff (.*, .clk(clk), .en(misc_enable), .din ({valid_ff_in, control_in[2:0], by_zero_case, shortq_enable, shortq_shift[4:0], finish, count_in[6:0]}), + .dout({valid_ff, control_ff[2:0], by_zero_case_ff, shortq_enable_ff, shortq_shift_ff[4:0], finish_ff, count_ff[6:0]})); + + rvdffe #(33) i_a_ff (.*, .clk(clk), .en(a_enable), .din(a_in[32:0]), .dout(a_ff[32:0])); + rvdffe #(33) i_b_ff (.*, .clk(clk), .en(b_enable), .din(b_in[32:0]), .dout(b_ff[32:0])); + rvdffe #(33) i_r_ff (.*, .clk(clk), .en(rq_enable), .din(r_in[32:0]), .dout(r_ff[32:0])); + rvdffe #(32) i_q_ff (.*, .clk(clk), .en(rq_enable), .din(q_in[31:0]), .dout(q_ff[31:0])); + + + + + assign valid_ff_in = valid_in & ~cancel; + + assign control_in[2] = (~valid_in & control_ff[2]) | (valid_in & signed_in & dividend_in[31]); + assign control_in[1] = (~valid_in & control_ff[1]) | (valid_in & signed_in & divisor_in[31]); + assign control_in[0] = (~valid_in & control_ff[0]) | (valid_in & rem_in); + + assign dividend_sign_ff = control_ff[2]; + assign divisor_sign_ff = control_ff[1]; + assign rem_ff = control_ff[0]; + + + assign by_zero_case = valid_ff & (b_ff[31:0] == 32'b0); + + assign misc_enable = valid_in | valid_ff | cancel | running_state | finish_ff; + assign running_state = (| count_ff[6:0]) | shortq_enable_ff; + assign finish_raw = smallnum_case | + by_zero_case | + (count_ff[6:0] == 7'd33); + + + assign finish = finish_raw & ~cancel; + assign count_enable = (valid_ff | running_state) & ~finish & ~finish_ff & ~cancel & ~shortq_enable; + assign count_in[6:0] = {7{count_enable}} & (count_ff[6:0] + {5'b0,2'b11} + {2'b0,shortq_shift_ff[4:0]}); + + + assign a_enable = valid_in | running_state; + assign a_shift = running_state & ~shortq_enable_ff; + + assign ar_shifted[65:0] = { {33{dividend_sign_ff}} , a_ff[32:0]} << {shortq_shift_ff[4:0]}; + + assign a_in[32:0] = ( {33{~a_shift & ~shortq_enable_ff}} & {signed_in & dividend_in[31],dividend_in[31:0]} ) | + ( {33{ a_shift }} & {a_ff[29:0],3'b0} ) | + ( {33{ shortq_enable_ff}} & ar_shifted[32:0] ); + + + + assign b_enable = valid_in | b_twos_comp; + assign b_twos_comp = valid_ff & ~(dividend_sign_ff ^ divisor_sign_ff); + + assign b_in[32:0] = ( {33{~b_twos_comp}} & { (signed_in & divisor_in[31]),divisor_in[31:0] } ) | + ( {33{ b_twos_comp}} & {~divisor_sign_ff,twos_comp_out[31:0] } ); + + + assign rq_enable = valid_in | valid_ff | running_state; + assign r_sign_sel = valid_ff & dividend_sign_ff & ~by_zero_case; + assign r_restore_sel = running_state & (quotient_new[2:0] == 3'b000) & ~shortq_enable_ff; + assign r_adder1_sel = running_state & (quotient_new[2:0] == 3'b001) & ~shortq_enable_ff; + assign r_adder2_sel = running_state & (quotient_new[2:0] == 3'b010) & ~shortq_enable_ff; + assign r_adder3_sel = running_state & (quotient_new[2:0] == 3'b011) & ~shortq_enable_ff; + assign r_adder4_sel = running_state & (quotient_new[2:0] == 3'b100) & ~shortq_enable_ff; + assign r_adder5_sel = running_state & (quotient_new[2:0] == 3'b101) & ~shortq_enable_ff; + assign r_adder6_sel = running_state & (quotient_new[2:0] == 3'b110) & ~shortq_enable_ff; + assign r_adder7_sel = running_state & (quotient_new[2:0] == 3'b111) & ~shortq_enable_ff; + + + assign r_in[32:0] = ( {33{r_sign_sel }} & {33{1'b1}} ) | + ( {33{r_restore_sel }} & {r_ff[29:0] ,a_ff[32:30]} ) | + ( {33{r_adder1_sel }} & adder1_out[32:0] ) | + ( {33{r_adder2_sel }} & adder2_out[32:0] ) | + ( {33{r_adder3_sel }} & adder3_out[32:0] ) | + ( {33{r_adder4_sel }} & adder4_out[32:0] ) | + ( {33{r_adder5_sel }} & adder5_out[32:0] ) | + ( {33{r_adder6_sel }} & adder6_out[32:0] ) | + ( {33{r_adder7_sel }} & adder7_out[32:0] ) | + ( {33{shortq_enable_ff}} & ar_shifted[65:33] ) | + ( {33{by_zero_case }} & {1'b0,a_ff[31:0]} ); + + + assign q_in[31:0] = ( {32{~valid_ff }} & {q_ff[28:0], quotient_new[2:0]} ) | + ( {32{ smallnum_case}} & {28'b0 , smallnum[3:0]} ) | + ( {32{ by_zero_case }} & {32{1'b1}} ); + + + assign b_ff[36:33] = {b_ff[32],b_ff[32],b_ff[32],b_ff[32]}; + + + assign adder1_out[33:0] = { r_ff[30:0],a_ff[32:30]} + b_ff[33:0]; + assign adder2_out[34:0] = { r_ff[31:0],a_ff[32:30]} + {b_ff[33:0],1'b0}; + assign adder3_out[35:0] = { r_ff[32:0],a_ff[32:30]} + {b_ff[34:0],1'b0} + b_ff[35:0]; + assign adder4_out[36:0] = {r_ff[32],r_ff[32:0],a_ff[32:30]} + {b_ff[34:0],2'b0}; + assign adder5_out[36:0] = {r_ff[32],r_ff[32:0],a_ff[32:30]} + {b_ff[34:0],2'b0} + b_ff[36:0]; + assign adder6_out[36:0] = {r_ff[32],r_ff[32:0],a_ff[32:30]} + {b_ff[34:0],2'b0} + {b_ff[35:0],1'b0}; + assign adder7_out[36:0] = {r_ff[32],r_ff[32:0],a_ff[32:30]} + {b_ff[34:0],2'b0} + {b_ff[35:0],1'b0} + b_ff[36:0]; + + assign quotient_raw[1] = (~adder1_out[33] ^ dividend_sign_ff) | ( (a_ff[29:0] == 30'b0) & (adder1_out[33:0] == 34'b0) ); + assign quotient_raw[2] = (~adder2_out[34] ^ dividend_sign_ff) | ( (a_ff[29:0] == 30'b0) & (adder2_out[34:0] == 35'b0) ); + assign quotient_raw[3] = (~adder3_out[35] ^ dividend_sign_ff) | ( (a_ff[29:0] == 30'b0) & (adder3_out[35:0] == 36'b0) ); + assign quotient_raw[4] = (~adder4_out[36] ^ dividend_sign_ff) | ( (a_ff[29:0] == 30'b0) & (adder4_out[36:0] == 37'b0) ); + assign quotient_raw[5] = (~adder5_out[36] ^ dividend_sign_ff) | ( (a_ff[29:0] == 30'b0) & (adder5_out[36:0] == 37'b0) ); + assign quotient_raw[6] = (~adder6_out[36] ^ dividend_sign_ff) | ( (a_ff[29:0] == 30'b0) & (adder6_out[36:0] == 37'b0) ); + assign quotient_raw[7] = (~adder7_out[36] ^ dividend_sign_ff) | ( (a_ff[29:0] == 30'b0) & (adder7_out[36:0] == 37'b0) ); + + assign quotient_new[2] = quotient_raw[7] | quotient_raw[6] | quotient_raw[5] | quotient_raw[4]; + assign quotient_new[1] = quotient_raw[7] | quotient_raw[6] | (~quotient_raw[4] & quotient_raw[3]) | (~quotient_raw[3] & quotient_raw[2]); + assign quotient_new[0] = quotient_raw[7] | (~quotient_raw[6] & quotient_raw[5]) | (~quotient_raw[4] & quotient_raw[3]) | (~quotient_raw[2] & quotient_raw[1]); + + + assign twos_comp_b_sel = valid_ff & ~(dividend_sign_ff ^ divisor_sign_ff); + assign twos_comp_q_sel = ~valid_ff & ~rem_ff & (dividend_sign_ff ^ divisor_sign_ff) & ~by_zero_case_ff; + + assign twos_comp_in[31:0] = ( {32{twos_comp_q_sel}} & q_ff[31:0] ) | + ( {32{twos_comp_b_sel}} & b_ff[31:0] ); + + rvtwoscomp #(32) i_twos_comp (.din(twos_comp_in[31:0]), .dout(twos_comp_out[31:0])); + + + + assign valid_out = finish_ff & ~cancel; + + assign data_out[31:0] = ( {32{~rem_ff & ~twos_comp_q_sel}} & q_ff[31:0] ) | + ( {32{ rem_ff }} & r_ff[31:0] ) | + ( {32{ twos_comp_q_sel}} & twos_comp_out[31:0] ); + + + + + // *** *** *** START : SMALLNUM {{ + + assign smallnum_case = ( (a_ff[31:4] == 28'b0) & (b_ff[31:4] == 28'b0) & ~by_zero_case & ~rem_ff & valid_ff & ~cancel) | + ( (a_ff[31:0] == 32'b0) & ~by_zero_case & ~rem_ff & valid_ff & ~cancel); + + assign smallnum[3] = ( a_ff[3] & ~b_ff[3] & ~b_ff[2] & ~b_ff[1] ); + + assign smallnum[2] = ( a_ff[3] & ~b_ff[3] & ~b_ff[2] & ~b_ff[0]) | + ( a_ff[2] & ~b_ff[3] & ~b_ff[2] & ~b_ff[1] ) | + ( a_ff[3] & a_ff[2] & ~b_ff[3] & ~b_ff[2] ); + + assign smallnum[1] = ( a_ff[2] & ~b_ff[3] & ~b_ff[2] & ~b_ff[0]) | + ( a_ff[1] & ~b_ff[3] & ~b_ff[2] & ~b_ff[1] ) | + ( a_ff[3] & ~b_ff[3] & ~b_ff[1] & ~b_ff[0]) | + ( a_ff[3] & ~a_ff[2] & ~b_ff[3] & ~b_ff[2] & b_ff[1] & b_ff[0]) | + (~a_ff[3] & a_ff[2] & a_ff[1] & ~b_ff[3] & ~b_ff[2] ) | + ( a_ff[3] & a_ff[2] & ~b_ff[3] & ~b_ff[0]) | + ( a_ff[3] & a_ff[2] & ~b_ff[3] & b_ff[2] & ~b_ff[1] ) | + ( a_ff[3] & a_ff[1] & ~b_ff[3] & ~b_ff[1] ) | + ( a_ff[3] & a_ff[2] & a_ff[1] & ~b_ff[3] & b_ff[2] ); + + assign smallnum[0] = ( a_ff[2] & a_ff[1] & a_ff[0] & ~b_ff[3] & ~b_ff[1] ) | + ( a_ff[3] & ~a_ff[2] & a_ff[0] & ~b_ff[3] & b_ff[1] & b_ff[0]) | + ( a_ff[2] & ~b_ff[3] & ~b_ff[1] & ~b_ff[0]) | + ( a_ff[1] & ~b_ff[3] & ~b_ff[2] & ~b_ff[0]) | + ( a_ff[0] & ~b_ff[3] & ~b_ff[2] & ~b_ff[1] ) | + (~a_ff[3] & a_ff[2] & ~a_ff[1] & ~b_ff[3] & ~b_ff[2] & b_ff[1] & b_ff[0]) | + (~a_ff[3] & a_ff[2] & a_ff[1] & ~b_ff[3] & ~b_ff[0]) | + ( a_ff[3] & ~b_ff[2] & ~b_ff[1] & ~b_ff[0]) | + ( a_ff[3] & ~a_ff[2] & ~b_ff[3] & b_ff[2] & b_ff[1] ) | + (~a_ff[3] & a_ff[2] & a_ff[1] & ~b_ff[3] & b_ff[2] & ~b_ff[1] ) | + (~a_ff[3] & a_ff[2] & a_ff[0] & ~b_ff[3] & ~b_ff[1] ) | + ( a_ff[3] & ~a_ff[2] & ~a_ff[1] & ~b_ff[3] & b_ff[2] & b_ff[0]) | + ( ~a_ff[2] & a_ff[1] & a_ff[0] & ~b_ff[3] & ~b_ff[2] ) | + ( a_ff[3] & a_ff[2] & ~b_ff[1] & ~b_ff[0]) | + ( a_ff[3] & a_ff[1] & ~b_ff[2] & ~b_ff[0]) | + (~a_ff[3] & a_ff[2] & a_ff[1] & a_ff[0] & ~b_ff[3] & b_ff[2] ) | + ( a_ff[3] & a_ff[2] & b_ff[3] & ~b_ff[2] ) | + ( a_ff[3] & a_ff[1] & b_ff[3] & ~b_ff[2] & ~b_ff[1] ) | + ( a_ff[3] & a_ff[0] & ~b_ff[2] & ~b_ff[1] ) | + ( a_ff[3] & ~a_ff[1] & ~b_ff[3] & b_ff[2] & b_ff[1] & b_ff[0]) | + ( a_ff[3] & a_ff[2] & a_ff[1] & b_ff[3] & ~b_ff[0]) | + ( a_ff[3] & a_ff[2] & a_ff[1] & b_ff[3] & ~b_ff[1] ) | + ( a_ff[3] & a_ff[2] & a_ff[0] & b_ff[3] & ~b_ff[1] ) | + ( a_ff[3] & ~a_ff[2] & a_ff[1] & ~b_ff[3] & b_ff[1] ) | + ( a_ff[3] & a_ff[1] & a_ff[0] & ~b_ff[2] ) | + ( a_ff[3] & a_ff[2] & a_ff[1] & a_ff[0] & b_ff[3] ); + + // *** *** *** END : SMALLNUM }} + + + + + // *** *** *** Start : Short Q {{ + + assign shortq_dividend[32:0] = {dividend_sign_ff,a_ff[31:0]}; + + + logic [5:0] dw_a_enc; + logic [5:0] dw_b_enc; + logic [6:0] dw_shortq_raw; + + + + el2_exu_div_cls i_a_cls ( + .operand ( shortq_dividend[32:0] ), + .cls ( dw_a_enc[4:0] )); + + el2_exu_div_cls i_b_cls ( + .operand ( b_ff[32:0] ), + .cls ( dw_b_enc[4:0] )); + + assign dw_a_enc[5] = 1'b0; + assign dw_b_enc[5] = 1'b0; + + + + assign dw_shortq_raw[6:0] = {1'b0,dw_b_enc[5:0]} - {1'b0,dw_a_enc[5:0]} + 7'd1; + assign shortq[5:0] = dw_shortq_raw[6] ? 6'd0 : dw_shortq_raw[5:0]; + + assign shortq_enable = valid_ff & ~shortq[5] & ~(shortq[4:2] == 3'b111) & ~cancel; + + assign shortq_decode[4:0] = ( {5{shortq[4:0] == 5'd31}} & 5'd00) | + ( {5{shortq[4:0] == 5'd30}} & 5'd00) | + ( {5{shortq[4:0] == 5'd29}} & 5'd00) | + ( {5{shortq[4:0] == 5'd28}} & 5'd00) | + ( {5{shortq[4:0] == 5'd27}} & 5'd03) | + ( {5{shortq[4:0] == 5'd26}} & 5'd06) | + ( {5{shortq[4:0] == 5'd25}} & 5'd06) | + ( {5{shortq[4:0] == 5'd24}} & 5'd06) | + ( {5{shortq[4:0] == 5'd23}} & 5'd09) | + ( {5{shortq[4:0] == 5'd22}} & 5'd09) | + ( {5{shortq[4:0] == 5'd21}} & 5'd09) | + ( {5{shortq[4:0] == 5'd20}} & 5'd12) | + ( {5{shortq[4:0] == 5'd19}} & 5'd12) | + ( {5{shortq[4:0] == 5'd18}} & 5'd12) | + ( {5{shortq[4:0] == 5'd17}} & 5'd15) | + ( {5{shortq[4:0] == 5'd16}} & 5'd15) | + ( {5{shortq[4:0] == 5'd15}} & 5'd15) | + ( {5{shortq[4:0] == 5'd14}} & 5'd18) | + ( {5{shortq[4:0] == 5'd13}} & 5'd18) | + ( {5{shortq[4:0] == 5'd12}} & 5'd18) | + ( {5{shortq[4:0] == 5'd11}} & 5'd21) | + ( {5{shortq[4:0] == 5'd10}} & 5'd21) | + ( {5{shortq[4:0] == 5'd09}} & 5'd21) | + ( {5{shortq[4:0] == 5'd08}} & 5'd24) | + ( {5{shortq[4:0] == 5'd07}} & 5'd24) | + ( {5{shortq[4:0] == 5'd06}} & 5'd24) | + ( {5{shortq[4:0] == 5'd05}} & 5'd27) | + ( {5{shortq[4:0] == 5'd04}} & 5'd27) | + ( {5{shortq[4:0] == 5'd03}} & 5'd27) | + ( {5{shortq[4:0] == 5'd02}} & 5'd27) | + ( {5{shortq[4:0] == 5'd01}} & 5'd27) | + ( {5{shortq[4:0] == 5'd00}} & 5'd27); + + + assign shortq_shift[4:0] = ~shortq_enable ? 5'd0 : shortq_decode[4:0]; + + + // *** *** *** End : Short Q }} + + + + + +endmodule // el2_exu_div_new_3bit_fullshortq + + + + + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +module el2_exu_div_new_4bit_fullshortq + ( + input logic clk, // Top level clock + input logic rst_l, // Reset + // Excluding scan_mode from coverage as its usage is determined by the integrator of the VeeR core. + /*pragma coverage off*/ + input logic scan_mode, // Scan mode + /*pragma coverage on*/ + + input logic cancel, // Flush pipeline + input logic valid_in, + input logic signed_in, + input logic rem_in, + input logic [31:0] dividend_in, + input logic [31:0] divisor_in, + + output logic valid_out, + output logic [31:0] data_out + ); + + + logic valid_ff_in, valid_ff; + logic finish_raw, finish, finish_ff; + logic running_state; + logic misc_enable; + logic [2:0] control_in, control_ff; + logic dividend_sign_ff, divisor_sign_ff, rem_ff; + logic count_enable; + logic [6:0] count_in, count_ff; + + logic smallnum_case; + logic [3:0] smallnum; + + logic a_enable, a_shift; + logic [31:0] a_in, a_ff; + + logic b_enable, b_twos_comp; + logic [32:0] b_in; + logic [37:0] b_ff; + + logic [31:0] q_in, q_ff; + + logic rq_enable; + logic r_sign_sel; + logic r_restore_sel; + logic r_adder01_sel, r_adder02_sel, r_adder03_sel; + logic r_adder04_sel, r_adder05_sel, r_adder06_sel, r_adder07_sel; + logic r_adder08_sel, r_adder09_sel, r_adder10_sel, r_adder11_sel; + logic r_adder12_sel, r_adder13_sel, r_adder14_sel, r_adder15_sel; + logic [32:0] r_in, r_ff; + + logic twos_comp_q_sel, twos_comp_b_sel; + logic [31:0] twos_comp_in, twos_comp_out; + + logic [15:1] quotient_raw; + logic [3:0] quotient_new; + logic [34:0] adder01_out; + logic [35:0] adder02_out; + logic [36:0] adder03_out; + logic [37:0] adder04_out; + logic [37:0] adder05_out; + logic [37:0] adder06_out; + logic [37:0] adder07_out; + logic [37:0] adder08_out; + logic [37:0] adder09_out; + logic [37:0] adder10_out; + logic [37:0] adder11_out; + logic [37:0] adder12_out; + logic [37:0] adder13_out; + logic [37:0] adder14_out; + logic [37:0] adder15_out; + + logic [64:0] ar_shifted; + logic [5:0] shortq; + logic [4:0] shortq_shift; + logic [4:0] shortq_decode; + logic [4:0] shortq_shift_ff; + logic shortq_enable; + logic shortq_enable_ff; + logic [32:0] shortq_dividend; + + logic by_zero_case; + logic by_zero_case_ff; + + + + rvdffe #(19) i_misc_ff (.*, .clk(clk), .en(misc_enable), .din ({valid_ff_in, control_in[2:0], by_zero_case, shortq_enable, shortq_shift[4:0], finish, count_in[6:0]}), + .dout({valid_ff, control_ff[2:0], by_zero_case_ff, shortq_enable_ff, shortq_shift_ff[4:0], finish_ff, count_ff[6:0]})); + + rvdffe #(32) i_a_ff (.*, .clk(clk), .en(a_enable), .din(a_in[31:0]), .dout(a_ff[31:0])); + rvdffe #(33) i_b_ff (.*, .clk(clk), .en(b_enable), .din(b_in[32:0]), .dout(b_ff[32:0])); + rvdffe #(33) i_r_ff (.*, .clk(clk), .en(rq_enable), .din(r_in[32:0]), .dout(r_ff[32:0])); + rvdffe #(32) i_q_ff (.*, .clk(clk), .en(rq_enable), .din(q_in[31:0]), .dout(q_ff[31:0])); + + + + + assign valid_ff_in = valid_in & ~cancel; + + assign control_in[2] = (~valid_in & control_ff[2]) | (valid_in & signed_in & dividend_in[31]); + assign control_in[1] = (~valid_in & control_ff[1]) | (valid_in & signed_in & divisor_in[31]); + assign control_in[0] = (~valid_in & control_ff[0]) | (valid_in & rem_in); + + assign dividend_sign_ff = control_ff[2]; + assign divisor_sign_ff = control_ff[1]; + assign rem_ff = control_ff[0]; + + + assign by_zero_case = valid_ff & (b_ff[31:0] == 32'b0); + + assign misc_enable = valid_in | valid_ff | cancel | running_state | finish_ff; + assign running_state = (| count_ff[6:0]) | shortq_enable_ff; + assign finish_raw = smallnum_case | + by_zero_case | + (count_ff[6:0] == 7'd32); + + + assign finish = finish_raw & ~cancel; + assign count_enable = (valid_ff | running_state) & ~finish & ~finish_ff & ~cancel & ~shortq_enable; + assign count_in[6:0] = {7{count_enable}} & (count_ff[6:0] + 7'd4 + {2'b0,shortq_shift_ff[4:0]}); + + + assign a_enable = valid_in | running_state; + assign a_shift = running_state & ~shortq_enable_ff; + + assign ar_shifted[64:0] = { {33{dividend_sign_ff}} , a_ff[31:0]} << {shortq_shift_ff[4:0]}; + + assign a_in[31:0] = ( {32{~a_shift & ~shortq_enable_ff}} & dividend_in[31:0] ) | + ( {32{ a_shift }} & {a_ff[27:0],4'b0} ) | + ( {32{ shortq_enable_ff}} & ar_shifted[31:0] ); + + + + assign b_enable = valid_in | b_twos_comp; + assign b_twos_comp = valid_ff & ~(dividend_sign_ff ^ divisor_sign_ff); + + assign b_in[32:0] = ( {33{~b_twos_comp}} & { (signed_in & divisor_in[31]),divisor_in[31:0] } ) | + ( {33{ b_twos_comp}} & {~divisor_sign_ff,twos_comp_out[31:0] } ); + + + assign rq_enable = valid_in | valid_ff | running_state; + assign r_sign_sel = valid_ff & dividend_sign_ff & ~by_zero_case; + assign r_restore_sel = running_state & (quotient_new[3:0] == 4'd00) & ~shortq_enable_ff; + assign r_adder01_sel = running_state & (quotient_new[3:0] == 4'd01) & ~shortq_enable_ff; + assign r_adder02_sel = running_state & (quotient_new[3:0] == 4'd02) & ~shortq_enable_ff; + assign r_adder03_sel = running_state & (quotient_new[3:0] == 4'd03) & ~shortq_enable_ff; + assign r_adder04_sel = running_state & (quotient_new[3:0] == 4'd04) & ~shortq_enable_ff; + assign r_adder05_sel = running_state & (quotient_new[3:0] == 4'd05) & ~shortq_enable_ff; + assign r_adder06_sel = running_state & (quotient_new[3:0] == 4'd06) & ~shortq_enable_ff; + assign r_adder07_sel = running_state & (quotient_new[3:0] == 4'd07) & ~shortq_enable_ff; + assign r_adder08_sel = running_state & (quotient_new[3:0] == 4'd08) & ~shortq_enable_ff; + assign r_adder09_sel = running_state & (quotient_new[3:0] == 4'd09) & ~shortq_enable_ff; + assign r_adder10_sel = running_state & (quotient_new[3:0] == 4'd10) & ~shortq_enable_ff; + assign r_adder11_sel = running_state & (quotient_new[3:0] == 4'd11) & ~shortq_enable_ff; + assign r_adder12_sel = running_state & (quotient_new[3:0] == 4'd12) & ~shortq_enable_ff; + assign r_adder13_sel = running_state & (quotient_new[3:0] == 4'd13) & ~shortq_enable_ff; + assign r_adder14_sel = running_state & (quotient_new[3:0] == 4'd14) & ~shortq_enable_ff; + assign r_adder15_sel = running_state & (quotient_new[3:0] == 4'd15) & ~shortq_enable_ff; + + assign r_in[32:0] = ( {33{r_sign_sel }} & {33{1'b1}} ) | + ( {33{r_restore_sel }} & {r_ff[28:0],a_ff[31:28]} ) | + ( {33{r_adder01_sel }} & adder01_out[32:0] ) | + ( {33{r_adder02_sel }} & adder02_out[32:0] ) | + ( {33{r_adder03_sel }} & adder03_out[32:0] ) | + ( {33{r_adder04_sel }} & adder04_out[32:0] ) | + ( {33{r_adder05_sel }} & adder05_out[32:0] ) | + ( {33{r_adder06_sel }} & adder06_out[32:0] ) | + ( {33{r_adder07_sel }} & adder07_out[32:0] ) | + ( {33{r_adder08_sel }} & adder08_out[32:0] ) | + ( {33{r_adder09_sel }} & adder09_out[32:0] ) | + ( {33{r_adder10_sel }} & adder10_out[32:0] ) | + ( {33{r_adder11_sel }} & adder11_out[32:0] ) | + ( {33{r_adder12_sel }} & adder12_out[32:0] ) | + ( {33{r_adder13_sel }} & adder13_out[32:0] ) | + ( {33{r_adder14_sel }} & adder14_out[32:0] ) | + ( {33{r_adder15_sel }} & adder15_out[32:0] ) | + ( {33{shortq_enable_ff}} & ar_shifted[64:32] ) | + ( {33{by_zero_case }} & {1'b0,a_ff[31:0]} ); + + + assign q_in[31:0] = ( {32{~valid_ff }} & {q_ff[27:0], quotient_new[3:0]} ) | + ( {32{ smallnum_case}} & {28'b0 , smallnum[3:0]} ) | + ( {32{ by_zero_case }} & {32{1'b1}} ); + + + assign b_ff[37:33] = {b_ff[32],b_ff[32],b_ff[32],b_ff[32],b_ff[32]}; + + + assign adder01_out[34:0] = { r_ff[30:0],a_ff[31:28]} + b_ff[34:0]; + assign adder02_out[35:0] = { r_ff[31:0],a_ff[31:28]} + {b_ff[34:0],1'b0}; + assign adder03_out[36:0] = { r_ff[32:0],a_ff[31:28]} + {b_ff[35:0],1'b0} + b_ff[36:0]; + assign adder04_out[37:0] = {r_ff[32],r_ff[32:0],a_ff[31:28]} + {b_ff[35:0],2'b0}; + assign adder05_out[37:0] = {r_ff[32],r_ff[32:0],a_ff[31:28]} + {b_ff[35:0],2'b0} + b_ff[37:0]; + assign adder06_out[37:0] = {r_ff[32],r_ff[32:0],a_ff[31:28]} + {b_ff[35:0],2'b0} + {b_ff[36:0],1'b0}; + assign adder07_out[37:0] = {r_ff[32],r_ff[32:0],a_ff[31:28]} + {b_ff[35:0],2'b0} + {b_ff[36:0],1'b0} + b_ff[37:0]; + assign adder08_out[37:0] = {r_ff[32],r_ff[32:0],a_ff[31:28]} + {b_ff[34:0],3'b0}; + assign adder09_out[37:0] = {r_ff[32],r_ff[32:0],a_ff[31:28]} + {b_ff[34:0],3'b0} + b_ff[37:0]; + assign adder10_out[37:0] = {r_ff[32],r_ff[32:0],a_ff[31:28]} + {b_ff[34:0],3'b0} + {b_ff[36:0],1'b0}; + assign adder11_out[37:0] = {r_ff[32],r_ff[32:0],a_ff[31:28]} + {b_ff[34:0],3'b0} + {b_ff[36:0],1'b0} + b_ff[37:0]; + assign adder12_out[37:0] = {r_ff[32],r_ff[32:0],a_ff[31:28]} + {b_ff[34:0],3'b0} + {b_ff[35:0],2'b0}; + assign adder13_out[37:0] = {r_ff[32],r_ff[32:0],a_ff[31:28]} + {b_ff[34:0],3'b0} + {b_ff[35:0],2'b0} + b_ff[37:0]; + assign adder14_out[37:0] = {r_ff[32],r_ff[32:0],a_ff[31:28]} + {b_ff[34:0],3'b0} + {b_ff[35:0],2'b0} + {b_ff[36:0],1'b0}; + assign adder15_out[37:0] = {r_ff[32],r_ff[32:0],a_ff[31:28]} + {b_ff[34:0],3'b0} + {b_ff[35:0],2'b0} + {b_ff[36:0],1'b0} + b_ff[37:0]; + + assign quotient_raw[01] = (~adder01_out[34] ^ dividend_sign_ff) | ( (a_ff[27:0] == 28'b0) & (adder01_out[34:0] == 35'b0) ); + assign quotient_raw[02] = (~adder02_out[35] ^ dividend_sign_ff) | ( (a_ff[27:0] == 28'b0) & (adder02_out[35:0] == 36'b0) ); + assign quotient_raw[03] = (~adder03_out[36] ^ dividend_sign_ff) | ( (a_ff[27:0] == 28'b0) & (adder03_out[36:0] == 37'b0) ); + assign quotient_raw[04] = (~adder04_out[37] ^ dividend_sign_ff) | ( (a_ff[27:0] == 28'b0) & (adder04_out[37:0] == 38'b0) ); + assign quotient_raw[05] = (~adder05_out[37] ^ dividend_sign_ff) | ( (a_ff[27:0] == 28'b0) & (adder05_out[37:0] == 38'b0) ); + assign quotient_raw[06] = (~adder06_out[37] ^ dividend_sign_ff) | ( (a_ff[27:0] == 28'b0) & (adder06_out[37:0] == 38'b0) ); + assign quotient_raw[07] = (~adder07_out[37] ^ dividend_sign_ff) | ( (a_ff[27:0] == 28'b0) & (adder07_out[37:0] == 38'b0) ); + assign quotient_raw[08] = (~adder08_out[37] ^ dividend_sign_ff) | ( (a_ff[27:0] == 28'b0) & (adder08_out[37:0] == 38'b0) ); + assign quotient_raw[09] = (~adder09_out[37] ^ dividend_sign_ff) | ( (a_ff[27:0] == 28'b0) & (adder09_out[37:0] == 38'b0) ); + assign quotient_raw[10] = (~adder10_out[37] ^ dividend_sign_ff) | ( (a_ff[27:0] == 28'b0) & (adder10_out[37:0] == 38'b0) ); + assign quotient_raw[11] = (~adder11_out[37] ^ dividend_sign_ff) | ( (a_ff[27:0] == 28'b0) & (adder11_out[37:0] == 38'b0) ); + assign quotient_raw[12] = (~adder12_out[37] ^ dividend_sign_ff) | ( (a_ff[27:0] == 28'b0) & (adder12_out[37:0] == 38'b0) ); + assign quotient_raw[13] = (~adder13_out[37] ^ dividend_sign_ff) | ( (a_ff[27:0] == 28'b0) & (adder13_out[37:0] == 38'b0) ); + assign quotient_raw[14] = (~adder14_out[37] ^ dividend_sign_ff) | ( (a_ff[27:0] == 28'b0) & (adder14_out[37:0] == 38'b0) ); + assign quotient_raw[15] = (~adder15_out[37] ^ dividend_sign_ff) | ( (a_ff[27:0] == 28'b0) & (adder15_out[37:0] == 38'b0) ); + + + assign quotient_new[0] = ( quotient_raw[15:01] == 15'b000_0000_0000_0001 ) | // 1 + ( quotient_raw[15:03] == 13'b000_0000_0000_01 ) | // 3 + ( quotient_raw[15:05] == 11'b000_0000_0001 ) | // 5 + ( quotient_raw[15:07] == 9'b000_0000_01 ) | // 7 + ( quotient_raw[15:09] == 7'b000_0001 ) | // 9 + ( quotient_raw[15:11] == 5'b000_01 ) | // 11 + ( quotient_raw[15:13] == 3'b001 ) | // 13 + ( quotient_raw[ 15] == 1'b1 ); // 15 + + assign quotient_new[1] = ( quotient_raw[15:02] == 14'b000_0000_0000_001 ) | // 2 + ( quotient_raw[15:03] == 13'b000_0000_0000_01 ) | // 3 + ( quotient_raw[15:06] == 10'b000_0000_001 ) | // 6 + ( quotient_raw[15:07] == 9'b000_0000_01 ) | // 7 + ( quotient_raw[15:10] == 6'b000_001 ) | // 10 + ( quotient_raw[15:11] == 5'b000_01 ) | // 11 + ( quotient_raw[15:14] == 2'b01 ) | // 14 + ( quotient_raw[ 15] == 1'b1 ); // 15 + + assign quotient_new[2] = ( quotient_raw[15:04] == 12'b000_0000_0000_1 ) | // 4 + ( quotient_raw[15:05] == 11'b000_0000_0001 ) | // 5 + ( quotient_raw[15:06] == 10'b000_0000_001 ) | // 6 + ( quotient_raw[15:07] == 9'b000_0000_01 ) | // 7 + ( quotient_raw[15:12] == 4'b000_1 ) | // 12 + ( quotient_raw[15:13] == 3'b001 ) | // 13 + ( quotient_raw[15:14] == 2'b01 ) | // 14 + ( quotient_raw[ 15] == 1'b1 ); // 15 + + assign quotient_new[3] = ( quotient_raw[15:08] == 8'b000_0000_1 ) | // 8 + ( quotient_raw[15:09] == 7'b000_0001 ) | // 9 + ( quotient_raw[15:10] == 6'b000_001 ) | // 10 + ( quotient_raw[15:11] == 5'b000_01 ) | // 11 + ( quotient_raw[15:12] == 4'b000_1 ) | // 12 + ( quotient_raw[15:13] == 3'b001 ) | // 13 + ( quotient_raw[15:14] == 2'b01 ) | // 14 + ( quotient_raw[ 15] == 1'b1 ); // 15 + + + assign twos_comp_b_sel = valid_ff & ~(dividend_sign_ff ^ divisor_sign_ff); + assign twos_comp_q_sel = ~valid_ff & ~rem_ff & (dividend_sign_ff ^ divisor_sign_ff) & ~by_zero_case_ff; + + assign twos_comp_in[31:0] = ( {32{twos_comp_q_sel}} & q_ff[31:0] ) | + ( {32{twos_comp_b_sel}} & b_ff[31:0] ); + + rvtwoscomp #(32) i_twos_comp (.din(twos_comp_in[31:0]), .dout(twos_comp_out[31:0])); + + + + assign valid_out = finish_ff & ~cancel; + + assign data_out[31:0] = ( {32{~rem_ff & ~twos_comp_q_sel}} & q_ff[31:0] ) | + ( {32{ rem_ff }} & r_ff[31:0] ) | + ( {32{ twos_comp_q_sel}} & twos_comp_out[31:0] ); + + + + + // *** *** *** START : SMALLNUM {{ + + assign smallnum_case = ( (a_ff[31:4] == 28'b0) & (b_ff[31:4] == 28'b0) & ~by_zero_case & ~rem_ff & valid_ff & ~cancel) | + ( (a_ff[31:0] == 32'b0) & ~by_zero_case & ~rem_ff & valid_ff & ~cancel); + + assign smallnum[3] = ( a_ff[3] & ~b_ff[3] & ~b_ff[2] & ~b_ff[1] ); + + assign smallnum[2] = ( a_ff[3] & ~b_ff[3] & ~b_ff[2] & ~b_ff[0]) | + ( a_ff[2] & ~b_ff[3] & ~b_ff[2] & ~b_ff[1] ) | + ( a_ff[3] & a_ff[2] & ~b_ff[3] & ~b_ff[2] ); + + assign smallnum[1] = ( a_ff[2] & ~b_ff[3] & ~b_ff[2] & ~b_ff[0]) | + ( a_ff[1] & ~b_ff[3] & ~b_ff[2] & ~b_ff[1] ) | + ( a_ff[3] & ~b_ff[3] & ~b_ff[1] & ~b_ff[0]) | + ( a_ff[3] & ~a_ff[2] & ~b_ff[3] & ~b_ff[2] & b_ff[1] & b_ff[0]) | + (~a_ff[3] & a_ff[2] & a_ff[1] & ~b_ff[3] & ~b_ff[2] ) | + ( a_ff[3] & a_ff[2] & ~b_ff[3] & ~b_ff[0]) | + ( a_ff[3] & a_ff[2] & ~b_ff[3] & b_ff[2] & ~b_ff[1] ) | + ( a_ff[3] & a_ff[1] & ~b_ff[3] & ~b_ff[1] ) | + ( a_ff[3] & a_ff[2] & a_ff[1] & ~b_ff[3] & b_ff[2] ); + + assign smallnum[0] = ( a_ff[2] & a_ff[1] & a_ff[0] & ~b_ff[3] & ~b_ff[1] ) | + ( a_ff[3] & ~a_ff[2] & a_ff[0] & ~b_ff[3] & b_ff[1] & b_ff[0]) | + ( a_ff[2] & ~b_ff[3] & ~b_ff[1] & ~b_ff[0]) | + ( a_ff[1] & ~b_ff[3] & ~b_ff[2] & ~b_ff[0]) | + ( a_ff[0] & ~b_ff[3] & ~b_ff[2] & ~b_ff[1] ) | + (~a_ff[3] & a_ff[2] & ~a_ff[1] & ~b_ff[3] & ~b_ff[2] & b_ff[1] & b_ff[0]) | + (~a_ff[3] & a_ff[2] & a_ff[1] & ~b_ff[3] & ~b_ff[0]) | + ( a_ff[3] & ~b_ff[2] & ~b_ff[1] & ~b_ff[0]) | + ( a_ff[3] & ~a_ff[2] & ~b_ff[3] & b_ff[2] & b_ff[1] ) | + (~a_ff[3] & a_ff[2] & a_ff[1] & ~b_ff[3] & b_ff[2] & ~b_ff[1] ) | + (~a_ff[3] & a_ff[2] & a_ff[0] & ~b_ff[3] & ~b_ff[1] ) | + ( a_ff[3] & ~a_ff[2] & ~a_ff[1] & ~b_ff[3] & b_ff[2] & b_ff[0]) | + ( ~a_ff[2] & a_ff[1] & a_ff[0] & ~b_ff[3] & ~b_ff[2] ) | + ( a_ff[3] & a_ff[2] & ~b_ff[1] & ~b_ff[0]) | + ( a_ff[3] & a_ff[1] & ~b_ff[2] & ~b_ff[0]) | + (~a_ff[3] & a_ff[2] & a_ff[1] & a_ff[0] & ~b_ff[3] & b_ff[2] ) | + ( a_ff[3] & a_ff[2] & b_ff[3] & ~b_ff[2] ) | + ( a_ff[3] & a_ff[1] & b_ff[3] & ~b_ff[2] & ~b_ff[1] ) | + ( a_ff[3] & a_ff[0] & ~b_ff[2] & ~b_ff[1] ) | + ( a_ff[3] & ~a_ff[1] & ~b_ff[3] & b_ff[2] & b_ff[1] & b_ff[0]) | + ( a_ff[3] & a_ff[2] & a_ff[1] & b_ff[3] & ~b_ff[0]) | + ( a_ff[3] & a_ff[2] & a_ff[1] & b_ff[3] & ~b_ff[1] ) | + ( a_ff[3] & a_ff[2] & a_ff[0] & b_ff[3] & ~b_ff[1] ) | + ( a_ff[3] & ~a_ff[2] & a_ff[1] & ~b_ff[3] & b_ff[1] ) | + ( a_ff[3] & a_ff[1] & a_ff[0] & ~b_ff[2] ) | + ( a_ff[3] & a_ff[2] & a_ff[1] & a_ff[0] & b_ff[3] ); + + // *** *** *** END : SMALLNUM }} + + + + + // *** *** *** Start : Short Q {{ + + assign shortq_dividend[32:0] = {dividend_sign_ff,a_ff[31:0]}; + + + logic [5:0] dw_a_enc; + logic [5:0] dw_b_enc; + logic [6:0] dw_shortq_raw; + + + + el2_exu_div_cls i_a_cls ( + .operand ( shortq_dividend[32:0] ), + .cls ( dw_a_enc[4:0] )); + + el2_exu_div_cls i_b_cls ( + .operand ( b_ff[32:0] ), + .cls ( dw_b_enc[4:0] )); + + assign dw_a_enc[5] = 1'b0; + assign dw_b_enc[5] = 1'b0; + + + assign dw_shortq_raw[6:0] = {1'b0,dw_b_enc[5:0]} - {1'b0,dw_a_enc[5:0]} + 7'd1; + assign shortq[5:0] = dw_shortq_raw[6] ? 6'd0 : dw_shortq_raw[5:0]; + + assign shortq_enable = valid_ff & ~shortq[5] & ~(shortq[4:2] == 3'b111) & ~cancel; + + assign shortq_decode[4:0] = ( {5{shortq[4:0] == 5'd31}} & 5'd00) | + ( {5{shortq[4:0] == 5'd30}} & 5'd00) | + ( {5{shortq[4:0] == 5'd29}} & 5'd00) | + ( {5{shortq[4:0] == 5'd28}} & 5'd00) | + ( {5{shortq[4:0] == 5'd27}} & 5'd04) | + ( {5{shortq[4:0] == 5'd26}} & 5'd04) | + ( {5{shortq[4:0] == 5'd25}} & 5'd04) | + ( {5{shortq[4:0] == 5'd24}} & 5'd04) | + ( {5{shortq[4:0] == 5'd23}} & 5'd08) | + ( {5{shortq[4:0] == 5'd22}} & 5'd08) | + ( {5{shortq[4:0] == 5'd21}} & 5'd08) | + ( {5{shortq[4:0] == 5'd20}} & 5'd08) | + ( {5{shortq[4:0] == 5'd19}} & 5'd12) | + ( {5{shortq[4:0] == 5'd18}} & 5'd12) | + ( {5{shortq[4:0] == 5'd17}} & 5'd12) | + ( {5{shortq[4:0] == 5'd16}} & 5'd12) | + ( {5{shortq[4:0] == 5'd15}} & 5'd16) | + ( {5{shortq[4:0] == 5'd14}} & 5'd16) | + ( {5{shortq[4:0] == 5'd13}} & 5'd16) | + ( {5{shortq[4:0] == 5'd12}} & 5'd16) | + ( {5{shortq[4:0] == 5'd11}} & 5'd20) | + ( {5{shortq[4:0] == 5'd10}} & 5'd20) | + ( {5{shortq[4:0] == 5'd09}} & 5'd20) | + ( {5{shortq[4:0] == 5'd08}} & 5'd20) | + ( {5{shortq[4:0] == 5'd07}} & 5'd24) | + ( {5{shortq[4:0] == 5'd06}} & 5'd24) | + ( {5{shortq[4:0] == 5'd05}} & 5'd24) | + ( {5{shortq[4:0] == 5'd04}} & 5'd24) | + ( {5{shortq[4:0] == 5'd03}} & 5'd28) | + ( {5{shortq[4:0] == 5'd02}} & 5'd28) | + ( {5{shortq[4:0] == 5'd01}} & 5'd28) | + ( {5{shortq[4:0] == 5'd00}} & 5'd28); + + + assign shortq_shift[4:0] = ~shortq_enable ? 5'd0 : shortq_decode[4:0]; + + + // *** *** *** End : Short Q }} + + + + + +endmodule // el2_exu_div_new_4bit_fullshortq + + + + + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +module el2_exu_div_cls + ( + input logic [32:0] operand, + + output logic [4:0] cls // Count leading sign bits - "n" format ignoring [32] + ); + + + logic [4:0] cls_zeros; + logic [4:0] cls_ones; + + +assign cls_zeros[4:0] = ({5{operand[31] == { 1'b1} }} & 5'd00) | + ({5{operand[31:30] == {{ 1{1'b0}},1'b1} }} & 5'd01) | + ({5{operand[31:29] == {{ 2{1'b0}},1'b1} }} & 5'd02) | + ({5{operand[31:28] == {{ 3{1'b0}},1'b1} }} & 5'd03) | + ({5{operand[31:27] == {{ 4{1'b0}},1'b1} }} & 5'd04) | + ({5{operand[31:26] == {{ 5{1'b0}},1'b1} }} & 5'd05) | + ({5{operand[31:25] == {{ 6{1'b0}},1'b1} }} & 5'd06) | + ({5{operand[31:24] == {{ 7{1'b0}},1'b1} }} & 5'd07) | + ({5{operand[31:23] == {{ 8{1'b0}},1'b1} }} & 5'd08) | + ({5{operand[31:22] == {{ 9{1'b0}},1'b1} }} & 5'd09) | + ({5{operand[31:21] == {{10{1'b0}},1'b1} }} & 5'd10) | + ({5{operand[31:20] == {{11{1'b0}},1'b1} }} & 5'd11) | + ({5{operand[31:19] == {{12{1'b0}},1'b1} }} & 5'd12) | + ({5{operand[31:18] == {{13{1'b0}},1'b1} }} & 5'd13) | + ({5{operand[31:17] == {{14{1'b0}},1'b1} }} & 5'd14) | + ({5{operand[31:16] == {{15{1'b0}},1'b1} }} & 5'd15) | + ({5{operand[31:15] == {{16{1'b0}},1'b1} }} & 5'd16) | + ({5{operand[31:14] == {{17{1'b0}},1'b1} }} & 5'd17) | + ({5{operand[31:13] == {{18{1'b0}},1'b1} }} & 5'd18) | + ({5{operand[31:12] == {{19{1'b0}},1'b1} }} & 5'd19) | + ({5{operand[31:11] == {{20{1'b0}},1'b1} }} & 5'd20) | + ({5{operand[31:10] == {{21{1'b0}},1'b1} }} & 5'd21) | + ({5{operand[31:09] == {{22{1'b0}},1'b1} }} & 5'd22) | + ({5{operand[31:08] == {{23{1'b0}},1'b1} }} & 5'd23) | + ({5{operand[31:07] == {{24{1'b0}},1'b1} }} & 5'd24) | + ({5{operand[31:06] == {{25{1'b0}},1'b1} }} & 5'd25) | + ({5{operand[31:05] == {{26{1'b0}},1'b1} }} & 5'd26) | + ({5{operand[31:04] == {{27{1'b0}},1'b1} }} & 5'd27) | + ({5{operand[31:03] == {{28{1'b0}},1'b1} }} & 5'd28) | + ({5{operand[31:02] == {{29{1'b0}},1'b1} }} & 5'd29) | + ({5{operand[31:01] == {{30{1'b0}},1'b1} }} & 5'd30) | + ({5{operand[31:00] == {{31{1'b0}},1'b1} }} & 5'd31) | + ({5{operand[31:00] == {{32{1'b0}} } }} & 5'd00); // Don't care case as it will be handled as special case + + +assign cls_ones[4:0] = ({5{operand[31:30] == {{ 1{1'b1}},1'b0} }} & 5'd00) | + ({5{operand[31:29] == {{ 2{1'b1}},1'b0} }} & 5'd01) | + ({5{operand[31:28] == {{ 3{1'b1}},1'b0} }} & 5'd02) | + ({5{operand[31:27] == {{ 4{1'b1}},1'b0} }} & 5'd03) | + ({5{operand[31:26] == {{ 5{1'b1}},1'b0} }} & 5'd04) | + ({5{operand[31:25] == {{ 6{1'b1}},1'b0} }} & 5'd05) | + ({5{operand[31:24] == {{ 7{1'b1}},1'b0} }} & 5'd06) | + ({5{operand[31:23] == {{ 8{1'b1}},1'b0} }} & 5'd07) | + ({5{operand[31:22] == {{ 9{1'b1}},1'b0} }} & 5'd08) | + ({5{operand[31:21] == {{10{1'b1}},1'b0} }} & 5'd09) | + ({5{operand[31:20] == {{11{1'b1}},1'b0} }} & 5'd10) | + ({5{operand[31:19] == {{12{1'b1}},1'b0} }} & 5'd11) | + ({5{operand[31:18] == {{13{1'b1}},1'b0} }} & 5'd12) | + ({5{operand[31:17] == {{14{1'b1}},1'b0} }} & 5'd13) | + ({5{operand[31:16] == {{15{1'b1}},1'b0} }} & 5'd14) | + ({5{operand[31:15] == {{16{1'b1}},1'b0} }} & 5'd15) | + ({5{operand[31:14] == {{17{1'b1}},1'b0} }} & 5'd16) | + ({5{operand[31:13] == {{18{1'b1}},1'b0} }} & 5'd17) | + ({5{operand[31:12] == {{19{1'b1}},1'b0} }} & 5'd18) | + ({5{operand[31:11] == {{20{1'b1}},1'b0} }} & 5'd19) | + ({5{operand[31:10] == {{21{1'b1}},1'b0} }} & 5'd20) | + ({5{operand[31:09] == {{22{1'b1}},1'b0} }} & 5'd21) | + ({5{operand[31:08] == {{23{1'b1}},1'b0} }} & 5'd22) | + ({5{operand[31:07] == {{24{1'b1}},1'b0} }} & 5'd23) | + ({5{operand[31:06] == {{25{1'b1}},1'b0} }} & 5'd24) | + ({5{operand[31:05] == {{26{1'b1}},1'b0} }} & 5'd25) | + ({5{operand[31:04] == {{27{1'b1}},1'b0} }} & 5'd26) | + ({5{operand[31:03] == {{28{1'b1}},1'b0} }} & 5'd27) | + ({5{operand[31:02] == {{29{1'b1}},1'b0} }} & 5'd28) | + ({5{operand[31:01] == {{30{1'b1}},1'b0} }} & 5'd29) | + ({5{operand[31:00] == {{31{1'b1}},1'b0} }} & 5'd30) | + ({5{operand[31:00] == {{32{1'b1}} } }} & 5'd31); + + +assign cls[4:0] = operand[32] ? cls_ones[4:0] : cls_zeros[4:0]; + +endmodule // el2_exu_div_cls diff --git a/designs/Caliptra/src/caliptra-rtl/el2_exu_mul_ctl.sv b/designs/Caliptra/src/caliptra-rtl/el2_exu_mul_ctl.sv new file mode 100644 index 0000000..d45c2f5 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/el2_exu_mul_ctl.sv @@ -0,0 +1,740 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2020 Western Digital Corporation or its affiliates. +// +// 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. + + +module el2_exu_mul_ctl +import el2_pkg::*; +#( +`include "el2_param.vh" + ) + ( + input logic clk, // Top level clock + input logic rst_l, // Reset + // Excluding scan_mode from coverage as its usage is determined by the integrator of the VeeR core. + /*pragma coverage off*/ + input logic scan_mode, // Scan mode + /*pragma coverage on*/ + + input el2_mul_pkt_t mul_p, // {Valid, RS1 signed operand, RS2 signed operand, Select low 32-bits of result} + + input logic [31:0] rs1_in, // A operand + input logic [31:0] rs2_in, // B operand + + + output logic [31:0] result_x // Result + ); + + + logic mul_x_enable; + logic bit_x_enable; + logic signed [32:0] rs1_ext_in; + logic signed [32:0] rs2_ext_in; + logic [65:0] prod_x; + logic low_x; + + + + // *** Start - BitManip *** + + logic bitmanip_sel_d; + logic bitmanip_sel_x; + logic [31:0] bitmanip_d; + logic [31:0] bitmanip_x; + + + + // ZBE + logic ap_bcompress; + logic ap_bdecompress; + + // ZBC + logic ap_clmul; + logic ap_clmulh; + logic ap_clmulr; + + // ZBP + logic ap_grev; + logic ap_gorc; + logic ap_shfl; + logic ap_unshfl; + logic ap_xperm_n; + logic ap_xperm_b; + logic ap_xperm_h; + + // ZBR + logic ap_crc32_b; + logic ap_crc32_h; + logic ap_crc32_w; + logic ap_crc32c_b; + logic ap_crc32c_h; + logic ap_crc32c_w; + + // ZBF + logic ap_bfp; + + + if (pt.BITMANIP_ZBE == 1) + begin + assign ap_bcompress = mul_p.bcompress; + assign ap_bdecompress = mul_p.bdecompress; + end + else + begin + assign ap_bcompress = 1'b0; + assign ap_bdecompress = 1'b0; + end + + if (pt.BITMANIP_ZBC == 1) + begin + assign ap_clmul = mul_p.clmul; + assign ap_clmulh = mul_p.clmulh; + assign ap_clmulr = mul_p.clmulr; + end + else + begin + assign ap_clmul = 1'b0; + assign ap_clmulh = 1'b0; + assign ap_clmulr = 1'b0; + end + + if (pt.BITMANIP_ZBP == 1) + begin + assign ap_grev = mul_p.grev; + assign ap_gorc = mul_p.gorc; + assign ap_shfl = mul_p.shfl; + assign ap_unshfl = mul_p.unshfl; + assign ap_xperm_n = mul_p.xperm_n; + assign ap_xperm_b = mul_p.xperm_b; + assign ap_xperm_h = mul_p.xperm_h; + end + else + begin + assign ap_grev = 1'b0; + assign ap_gorc = 1'b0; + assign ap_shfl = 1'b0; + assign ap_unshfl = 1'b0; + assign ap_xperm_n = 1'b0; + assign ap_xperm_b = 1'b0; + assign ap_xperm_h = 1'b0; + end + + if (pt.BITMANIP_ZBR == 1) + begin + assign ap_crc32_b = mul_p.crc32_b; + assign ap_crc32_h = mul_p.crc32_h; + assign ap_crc32_w = mul_p.crc32_w; + assign ap_crc32c_b = mul_p.crc32c_b; + assign ap_crc32c_h = mul_p.crc32c_h; + assign ap_crc32c_w = mul_p.crc32c_w; + end + else + begin + assign ap_crc32_b = 1'b0; + assign ap_crc32_h = 1'b0; + assign ap_crc32_w = 1'b0; + assign ap_crc32c_b = 1'b0; + assign ap_crc32c_h = 1'b0; + assign ap_crc32c_w = 1'b0; + end + + if (pt.BITMANIP_ZBF == 1) + begin + assign ap_bfp = mul_p.bfp; + end + else + begin + assign ap_bfp = 1'b0; + end + + + // *** End - BitManip *** + + + + assign mul_x_enable = mul_p.valid; + assign bit_x_enable = mul_p.valid; + + assign rs1_ext_in[32] = mul_p.rs1_sign & rs1_in[31]; + assign rs2_ext_in[32] = mul_p.rs2_sign & rs2_in[31]; + + assign rs1_ext_in[31:0] = rs1_in[31:0]; + assign rs2_ext_in[31:0] = rs2_in[31:0]; + + + + // --------------------------- Multiply ---------------------------------- + + + logic signed [32:0] rs1_x; + logic signed [32:0] rs2_x; + + rvdffe #(34) i_a_x_ff (.*, .clk(clk), .din({mul_p.low,rs1_ext_in[32:0]}), .dout({low_x,rs1_x[32:0]}), .en(mul_x_enable)); + rvdffe #(33) i_b_x_ff (.*, .clk(clk), .din( rs2_ext_in[32:0] ), .dout( rs2_x[32:0] ), .en(mul_x_enable)); + + + assign prod_x[65:0] = rs1_x * rs2_x; + + + + + // * * * * * * * * * * * * * * * * * * BitManip : BCOMPRESS, BDECOMPRESS * * * * * * * * * * * * * + + + // *** BCOMPRESS == "gather" *** + + logic [31:0] bcompress_d; + logic bcompress_test_bit_d; + integer bcompress_i, bcompress_j; + + + always_comb + begin + + bcompress_j = 0; + bcompress_test_bit_d = 1'b0; + bcompress_d[31:0] = 32'b0; + + for (bcompress_i=0; bcompress_i<32; bcompress_i++) + begin + bcompress_test_bit_d = rs2_in[bcompress_i]; + if (bcompress_test_bit_d) + begin + bcompress_d[bcompress_j] = rs1_in[bcompress_i]; + bcompress_j = bcompress_j + 1; + end // IF bcompress_test_bit + end // FOR bcompress_i + end // ALWAYS_COMB + + + + // *** BDECOMPRESS == "scatter" *** + + logic [31:0] bdecompress_d; + logic bdecompress_test_bit_d; + integer bdecompress_i, bdecompress_j; + + + always_comb + begin + + bdecompress_j = 0; + bdecompress_test_bit_d = 1'b0; + bdecompress_d[31:0] = 32'b0; + + for (bdecompress_i=0; bdecompress_i<32; bdecompress_i++) + begin + bdecompress_test_bit_d = rs2_in[bdecompress_i]; + if (bdecompress_test_bit_d) + begin + bdecompress_d[bdecompress_i] = rs1_in[bdecompress_j]; + bdecompress_j = bdecompress_j + 1; + end // IF bdecompress_test_bit + end // FOR bdecompress_i + end // ALWAYS_COMB + + + + + // * * * * * * * * * * * * * * * * * * BitManip : CLMUL, CLMULH, CLMULR * * * * * * * * * * * * * + + logic [62:0] clmul_raw_d; + + + assign clmul_raw_d[62:0] = ( {63{rs2_in[00]}} & {31'b0,rs1_in[31:0] } ) ^ + ( {63{rs2_in[01]}} & {30'b0,rs1_in[31:0], 1'b0} ) ^ + ( {63{rs2_in[02]}} & {29'b0,rs1_in[31:0], 2'b0} ) ^ + ( {63{rs2_in[03]}} & {28'b0,rs1_in[31:0], 3'b0} ) ^ + ( {63{rs2_in[04]}} & {27'b0,rs1_in[31:0], 4'b0} ) ^ + ( {63{rs2_in[05]}} & {26'b0,rs1_in[31:0], 5'b0} ) ^ + ( {63{rs2_in[06]}} & {25'b0,rs1_in[31:0], 6'b0} ) ^ + ( {63{rs2_in[07]}} & {24'b0,rs1_in[31:0], 7'b0} ) ^ + ( {63{rs2_in[08]}} & {23'b0,rs1_in[31:0], 8'b0} ) ^ + ( {63{rs2_in[09]}} & {22'b0,rs1_in[31:0], 9'b0} ) ^ + ( {63{rs2_in[10]}} & {21'b0,rs1_in[31:0],10'b0} ) ^ + ( {63{rs2_in[11]}} & {20'b0,rs1_in[31:0],11'b0} ) ^ + ( {63{rs2_in[12]}} & {19'b0,rs1_in[31:0],12'b0} ) ^ + ( {63{rs2_in[13]}} & {18'b0,rs1_in[31:0],13'b0} ) ^ + ( {63{rs2_in[14]}} & {17'b0,rs1_in[31:0],14'b0} ) ^ + ( {63{rs2_in[15]}} & {16'b0,rs1_in[31:0],15'b0} ) ^ + ( {63{rs2_in[16]}} & {15'b0,rs1_in[31:0],16'b0} ) ^ + ( {63{rs2_in[17]}} & {14'b0,rs1_in[31:0],17'b0} ) ^ + ( {63{rs2_in[18]}} & {13'b0,rs1_in[31:0],18'b0} ) ^ + ( {63{rs2_in[19]}} & {12'b0,rs1_in[31:0],19'b0} ) ^ + ( {63{rs2_in[20]}} & {11'b0,rs1_in[31:0],20'b0} ) ^ + ( {63{rs2_in[21]}} & {10'b0,rs1_in[31:0],21'b0} ) ^ + ( {63{rs2_in[22]}} & { 9'b0,rs1_in[31:0],22'b0} ) ^ + ( {63{rs2_in[23]}} & { 8'b0,rs1_in[31:0],23'b0} ) ^ + ( {63{rs2_in[24]}} & { 7'b0,rs1_in[31:0],24'b0} ) ^ + ( {63{rs2_in[25]}} & { 6'b0,rs1_in[31:0],25'b0} ) ^ + ( {63{rs2_in[26]}} & { 5'b0,rs1_in[31:0],26'b0} ) ^ + ( {63{rs2_in[27]}} & { 4'b0,rs1_in[31:0],27'b0} ) ^ + ( {63{rs2_in[28]}} & { 3'b0,rs1_in[31:0],28'b0} ) ^ + ( {63{rs2_in[29]}} & { 2'b0,rs1_in[31:0],29'b0} ) ^ + ( {63{rs2_in[30]}} & { 1'b0,rs1_in[31:0],30'b0} ) ^ + ( {63{rs2_in[31]}} & { rs1_in[31:0],31'b0} ); + + + + + // * * * * * * * * * * * * * * * * * * BitManip : GREV * * * * * * * * * * * * * * * * * * + + // uint32_t grev32(uint32_t rs1, uint32_t rs2) + // { + // uint32_t x = rs1; + // int shamt = rs2 & 31; + // + // if (shamt & 1) x = ( (x & 0x55555555) << 1) | ( (x & 0xAAAAAAAA) >> 1); + // if (shamt & 2) x = ( (x & 0x33333333) << 2) | ( (x & 0xCCCCCCCC) >> 2); + // if (shamt & 4) x = ( (x & 0x0F0F0F0F) << 4) | ( (x & 0xF0F0F0F0) >> 4); + // if (shamt & 8) x = ( (x & 0x00FF00FF) << 8) | ( (x & 0xFF00FF00) >> 8); + // if (shamt & 16) x = ( (x & 0x0000FFFF) << 16) | ( (x & 0xFFFF0000) >> 16); + // + // return x; + // } + + + logic [31:0] grev1_d; + logic [31:0] grev2_d; + logic [31:0] grev4_d; + logic [31:0] grev8_d; + logic [31:0] grev_d; + + + assign grev1_d[31:0] = (rs2_in[0]) ? {rs1_in[30],rs1_in[31],rs1_in[28],rs1_in[29],rs1_in[26],rs1_in[27],rs1_in[24],rs1_in[25], + rs1_in[22],rs1_in[23],rs1_in[20],rs1_in[21],rs1_in[18],rs1_in[19],rs1_in[16],rs1_in[17], + rs1_in[14],rs1_in[15],rs1_in[12],rs1_in[13],rs1_in[10],rs1_in[11],rs1_in[08],rs1_in[09], + rs1_in[06],rs1_in[07],rs1_in[04],rs1_in[05],rs1_in[02],rs1_in[03],rs1_in[00],rs1_in[01]} : rs1_in[31:0]; + + assign grev2_d[31:0] = (rs2_in[1]) ? {grev1_d[29:28],grev1_d[31:30],grev1_d[25:24],grev1_d[27:26], + grev1_d[21:20],grev1_d[23:22],grev1_d[17:16],grev1_d[19:18], + grev1_d[13:12],grev1_d[15:14],grev1_d[09:08],grev1_d[11:10], + grev1_d[05:04],grev1_d[07:06],grev1_d[01:00],grev1_d[03:02]} : grev1_d[31:0]; + + assign grev4_d[31:0] = (rs2_in[2]) ? {grev2_d[27:24],grev2_d[31:28],grev2_d[19:16],grev2_d[23:20], + grev2_d[11:08],grev2_d[15:12],grev2_d[03:00],grev2_d[07:04]} : grev2_d[31:0]; + + assign grev8_d[31:0] = (rs2_in[3]) ? {grev4_d[23:16],grev4_d[31:24],grev4_d[07:00],grev4_d[15:08]} : grev4_d[31:0]; + + assign grev_d[31:0] = (rs2_in[4]) ? {grev8_d[15:00],grev8_d[31:16]} : grev8_d[31:0]; + + + + + // * * * * * * * * * * * * * * * * * * BitManip : GORC * * * * * * * * * * * * * * * * * * + + // uint32_t gorc32(uint32_t rs1, uint32_t rs2) + // { + // uint32_t x = rs1; + // int shamt = rs2 & 31; + // + // if (shamt & 1) x |= ( (x & 0x55555555) << 1) | ( (x & 0xAAAAAAAA) >> 1); + // if (shamt & 2) x |= ( (x & 0x33333333) << 2) | ( (x & 0xCCCCCCCC) >> 2); + // if (shamt & 4) x |= ( (x & 0x0F0F0F0F) << 4) | ( (x & 0xF0F0F0F0) >> 4); + // if (shamt & 8) x |= ( (x & 0x00FF00FF) << 8) | ( (x & 0xFF00FF00) >> 8); + // if (shamt & 16) x |= ( (x & 0x0000FFFF) << 16) | ( (x & 0xFFFF0000) >> 16); + // + // return x; + // } + + + logic [31:0] gorc1_d; + logic [31:0] gorc2_d; + logic [31:0] gorc4_d; + logic [31:0] gorc8_d; + logic [31:0] gorc_d; + + + assign gorc1_d[31:0] = ( {32{rs2_in[0]}} & {rs1_in[30],rs1_in[31],rs1_in[28],rs1_in[29],rs1_in[26],rs1_in[27],rs1_in[24],rs1_in[25], + rs1_in[22],rs1_in[23],rs1_in[20],rs1_in[21],rs1_in[18],rs1_in[19],rs1_in[16],rs1_in[17], + rs1_in[14],rs1_in[15],rs1_in[12],rs1_in[13],rs1_in[10],rs1_in[11],rs1_in[08],rs1_in[09], + rs1_in[06],rs1_in[07],rs1_in[04],rs1_in[05],rs1_in[02],rs1_in[03],rs1_in[00],rs1_in[01]} ) | rs1_in[31:0]; + + assign gorc2_d[31:0] = ( {32{rs2_in[1]}} & {gorc1_d[29:28],gorc1_d[31:30],gorc1_d[25:24],gorc1_d[27:26], + gorc1_d[21:20],gorc1_d[23:22],gorc1_d[17:16],gorc1_d[19:18], + gorc1_d[13:12],gorc1_d[15:14],gorc1_d[09:08],gorc1_d[11:10], + gorc1_d[05:04],gorc1_d[07:06],gorc1_d[01:00],gorc1_d[03:02]} ) | gorc1_d[31:0]; + + assign gorc4_d[31:0] = ( {32{rs2_in[2]}} & {gorc2_d[27:24],gorc2_d[31:28],gorc2_d[19:16],gorc2_d[23:20], + gorc2_d[11:08],gorc2_d[15:12],gorc2_d[03:00],gorc2_d[07:04]} ) | gorc2_d[31:0]; + + assign gorc8_d[31:0] = ( {32{rs2_in[3]}} & {gorc4_d[23:16],gorc4_d[31:24],gorc4_d[07:00],gorc4_d[15:08]} ) | gorc4_d[31:0]; + + assign gorc_d[31:0] = ( {32{rs2_in[4]}} & {gorc8_d[15:00],gorc8_d[31:16]} ) | gorc8_d[31:0]; + + + + + // * * * * * * * * * * * * * * * * * * BitManip : SHFL, UNSHLF * * * * * * * * * * * * * * * * * * + + // uint32_t shuffle32_stage (uint32_t src, uint32_t maskL, uint32_t maskR, int N) + // { + // uint32_t x = src & ~(maskL | maskR); + // x |= ((src << N) & maskL) | ((src >> N) & maskR); + // return x; + // } + // + // + // + // uint32_t shfl32(uint32_t rs1, uint32_t rs2) + // { + // uint32_t x = rs1; + // int shamt = rs2 & 15 + // + // if (shamt & 8) x = shuffle32_stage(x, 0x00ff0000, 0x0000ff00, 8); + // if (shamt & 4) x = shuffle32_stage(x, 0x0f000f00, 0x00f000f0, 4); + // if (shamt & 2) x = shuffle32_stage(x, 0x30303030, 0xc0c0c0c0, 2); + // if (shamt & 1) x = shuffle32_stage(x, 0x44444444, 0x22222222, 1); + // + // return x; + // } + + + logic [31:0] shfl8_d; + logic [31:0] shfl4_d; + logic [31:0] shfl2_d; + logic [31:0] shfl_d; + + + + assign shfl8_d[31:0] = (rs2_in[3]) ? {rs1_in[31:24],rs1_in[15:08],rs1_in[23:16],rs1_in[07:00]} : rs1_in[31:0]; + + assign shfl4_d[31:0] = (rs2_in[2]) ? {shfl8_d[31:28],shfl8_d[23:20],shfl8_d[27:24],shfl8_d[19:16], + shfl8_d[15:12],shfl8_d[07:04],shfl8_d[11:08],shfl8_d[03:00]} : shfl8_d[31:0]; + + assign shfl2_d[31:0] = (rs2_in[1]) ? {shfl4_d[31:30],shfl4_d[27:26],shfl4_d[29:28],shfl4_d[25:24], + shfl4_d[23:22],shfl4_d[19:18],shfl4_d[21:20],shfl4_d[17:16], + shfl4_d[15:14],shfl4_d[11:10],shfl4_d[13:12],shfl4_d[09:08], + shfl4_d[07:06],shfl4_d[03:02],shfl4_d[05:04],shfl4_d[01:00]} : shfl4_d[31:0]; + + assign shfl_d[31:0] = (rs2_in[0]) ? {shfl2_d[31],shfl2_d[29],shfl2_d[30],shfl2_d[28],shfl2_d[27],shfl2_d[25],shfl2_d[26],shfl2_d[24], + shfl2_d[23],shfl2_d[21],shfl2_d[22],shfl2_d[20],shfl2_d[19],shfl2_d[17],shfl2_d[18],shfl2_d[16], + shfl2_d[15],shfl2_d[13],shfl2_d[14],shfl2_d[12],shfl2_d[11],shfl2_d[09],shfl2_d[10],shfl2_d[08], + shfl2_d[07],shfl2_d[05],shfl2_d[06],shfl2_d[04],shfl2_d[03],shfl2_d[01],shfl2_d[02],shfl2_d[00]} : shfl2_d[31:0]; + + + + + // uint32_t unshfl32(uint32_t rs1, uint32_t rs2) + // { + // uint32_t x = rs1; + // int shamt = rs2 & 15 + // + // if (shamt & 1) x = shuffle32_stage(x, 0x44444444, 0x22222222, 1); + // if (shamt & 2) x = shuffle32_stage(x, 0x30303030, 0xc0c0c0c0, 2); + // if (shamt & 4) x = shuffle32_stage(x, 0x0f000f00, 0x00f000f0, 4); + // if (shamt & 8) x = shuffle32_stage(x, 0x00ff0000, 0x0000ff00, 8); + // + // return x; + // } + + + logic [31:0] unshfl1_d; + logic [31:0] unshfl2_d; + logic [31:0] unshfl4_d; + logic [31:0] unshfl_d; + + + assign unshfl1_d[31:0] = (rs2_in[0]) ? {rs1_in[31],rs1_in[29],rs1_in[30],rs1_in[28],rs1_in[27],rs1_in[25],rs1_in[26],rs1_in[24], + rs1_in[23],rs1_in[21],rs1_in[22],rs1_in[20],rs1_in[19],rs1_in[17],rs1_in[18],rs1_in[16], + rs1_in[15],rs1_in[13],rs1_in[14],rs1_in[12],rs1_in[11],rs1_in[09],rs1_in[10],rs1_in[08], + rs1_in[07],rs1_in[05],rs1_in[06],rs1_in[04],rs1_in[03],rs1_in[01],rs1_in[02],rs1_in[00]} : rs1_in[31:0]; + + assign unshfl2_d[31:0] = (rs2_in[1]) ? {unshfl1_d[31:30],unshfl1_d[27:26],unshfl1_d[29:28],unshfl1_d[25:24], + unshfl1_d[23:22],unshfl1_d[19:18],unshfl1_d[21:20],unshfl1_d[17:16], + unshfl1_d[15:14],unshfl1_d[11:10],unshfl1_d[13:12],unshfl1_d[09:08], + unshfl1_d[07:06],unshfl1_d[03:02],unshfl1_d[05:04],unshfl1_d[01:00]} : unshfl1_d[31:0]; + + assign unshfl4_d[31:0] = (rs2_in[2]) ? {unshfl2_d[31:28],unshfl2_d[23:20],unshfl2_d[27:24],unshfl2_d[19:16], + unshfl2_d[15:12],unshfl2_d[07:04],unshfl2_d[11:08],unshfl2_d[03:00]} : unshfl2_d[31:0]; + + assign unshfl_d[31:0] = (rs2_in[3]) ? {unshfl4_d[31:24],unshfl4_d[15:08],unshfl4_d[23:16],unshfl4_d[07:00]} : unshfl4_d[31:0]; + + + + + // * * * * * * * * * * * * * * * * * * BitManip : XPERM * * * * * * * * * * * * * * * * * + +// +// These instructions operate on nibbles/bytes/half-words/words. +// rs1 is a vector of data words and rs2 is a vector of indices into rs1. +// The result of the instruction is the vector rs2 with each element replaced by the corresponding data word from rs1, +// or zero then the index in rs2 is out of bounds. +// +// uint_xlen_t xperm(uint_xlen_t rs1, uint_xlen_t rs2, int sz_log2) +// { +// uint_xlen_t r = 0; +// uint_xlen_t sz = 1LL << sz_log2; +// uint_xlen_t mask = (1LL << sz) - 1; +// for (int i = 0; i < XLEN; i += sz) +// { uint_xlen_t pos = ((rs2 >> i) & mask) << sz_log2; +// if (pos < XLEN) +// r |= ((rs1 >> pos) & mask) << i; +// } +// return r; +// } +// +// uint_xlen_t xperm_n (uint_xlen_t rs1, uint_xlen_t rs2) { return xperm(rs1, rs2, 2); } +// uint_xlen_t xperm_b (uint_xlen_t rs1, uint_xlen_t rs2) { return xperm(rs1, rs2, 3); } +// uint_xlen_t xperm_h (uint_xlen_t rs1, uint_xlen_t rs2) { return xperm(rs1, rs2, 4); } +// uint_xlen_t xperm_w (uint_xlen_t rs1, uint_xlen_t rs2) { return xperm(rs1, rs2, 5); } Not part of RV32 +// +// The xperm.[nbhw] instructions can be implemented with an XLEN/4-lane nibble-wide crossbarswitch. + +// *** XPERM_B *** + + // XLEN = 32 + // SZ_LOG2 = 3 + // SZ = 4'd8; + // MASK = ( 1 << 8 ) - 1 + // = 8'hFF + + // integer xperm_b_i; + // logic [31:0] xperm_b_r; + // logic [3:0] xperm_b_sz; + // logic [7:0] xperm_b_mask; + // logic [31:0] xperm_b_pos; + // + // + // assign xperm_b_sz[3:0] = 4'd8; + // assign xperm_b_mask[7:0] = 8'hff; + // + // always_comb + // begin + // xperm_b_r[31:0] = 32'b0; + // + // for (xperm_b_i=0; xperm_b_i<32; xperm_b_i = xperm_b_i + xperm_b_sz) // This code did not work... + // begin + // xperm_b_pos[31:0] = ( (rs2_in[31:0] >> xperm_b_i) & {24'h0,xperm_b_mask[7:0]} ) << 3; + // if (xperm_b_pos[31:0] < 32'd32) + // xperm_b_r[31:0] = xperm_b_r[31:0] | ( ((rs1_in[31:0] >> xperm_b_pos[4:0]) & {24'h0,xperm_b_mask[7:0]}) << xperm_b_i ); + // end + // end + + logic [31:0] xperm_n; + logic [31:0] xperm_b; + logic [31:0] xperm_h; + + assign xperm_n[03:00] = { 4{ ~rs2_in[03] }} & 4'( (rs1_in[31:0] >> {rs2_in[02:00],2'b0}) & 4'hf ); // This is a 8:1 mux with qualified selects + assign xperm_n[07:04] = { 4{ ~rs2_in[07] }} & 4'( (rs1_in[31:0] >> {rs2_in[06:04],2'b0}) & 4'hf ); + assign xperm_n[11:08] = { 4{ ~rs2_in[11] }} & 4'( (rs1_in[31:0] >> {rs2_in[10:08],2'b0}) & 4'hf ); + assign xperm_n[15:12] = { 4{ ~rs2_in[15] }} & 4'( (rs1_in[31:0] >> {rs2_in[14:12],2'b0}) & 4'hf ); + assign xperm_n[19:16] = { 4{ ~rs2_in[19] }} & 4'( (rs1_in[31:0] >> {rs2_in[18:16],2'b0}) & 4'hf ); + assign xperm_n[23:20] = { 4{ ~rs2_in[23] }} & 4'( (rs1_in[31:0] >> {rs2_in[22:20],2'b0}) & 4'hf ); + assign xperm_n[27:24] = { 4{ ~rs2_in[27] }} & 4'( (rs1_in[31:0] >> {rs2_in[26:24],2'b0}) & 4'hf ); + assign xperm_n[31:28] = { 4{ ~rs2_in[31] }} & 4'( (rs1_in[31:0] >> {rs2_in[30:28],2'b0}) & 4'hf ); + + assign xperm_b[07:00] = { 8{ ~(| rs2_in[07:02]) }} & 8'( (rs1_in[31:0] >> {rs2_in[01:00],3'b0}) & 8'hff ); // This is a 4:1 mux with qualified selects + assign xperm_b[15:08] = { 8{ ~(| rs2_in[15:10]) }} & 8'( (rs1_in[31:0] >> {rs2_in[09:08],3'b0}) & 8'hff ); + assign xperm_b[23:16] = { 8{ ~(| rs2_in[23:18]) }} & 8'( (rs1_in[31:0] >> {rs2_in[17:16],3'b0}) & 8'hff ); + assign xperm_b[31:24] = { 8{ ~(| rs2_in[31:26]) }} & 8'( (rs1_in[31:0] >> {rs2_in[25:24],3'b0}) & 8'hff ); + + assign xperm_h[15:00] = {16{ ~(| rs2_in[15:01]) }} & 16'( (rs1_in[31:0] >> {rs2_in[00] ,4'b0}) & 16'hffff ); // This is a 2:1 mux with qualified selects + assign xperm_h[31:16] = {16{ ~(| rs2_in[31:17]) }} & 16'( (rs1_in[31:0] >> {rs2_in[16] ,4'b0}) & 16'hffff ); + + + + + // * * * * * * * * * * * * * * * * * * BitManip : CRC32, CRC32c * * * * * * * * * * * * * * * * * + + // *** computed from https: //crccalc.com *** + // + // "a" is 8'h61 = 8'b0110_0001 (8'h61 ^ 8'hff = 8'h9e) + // + // Input must first be XORed with 32'hffff_ffff + // + // + // CRC32 + // + // Input Output Input Output + // ----- -------- -------- -------- + // "a" e8b7be43 ffffff9e 174841bc + // "aa" 078a19d7 ffff9e9e f875e628 + // "aaaa" ad98e545 9e9e9e9e 5267a1ba + // + // + // + // CRC32c + // + // Input Output Input Output + // ----- -------- -------- -------- + // "a" c1d04330 ffffff9e 3e2fbccf + // "aa" f1f2dac2 ffff9e9e 0e0d253d + // "aaaa" 6a52eeb0 9e9e9e9e 95ad114f + + + logic crc32_all; + logic [31:0] crc32_poly_rev; + logic [31:0] crc32c_poly_rev; + integer crc32_bi, crc32_hi, crc32_wi, crc32c_bi, crc32c_hi, crc32c_wi; + logic [31:0] crc32_bd, crc32_hd, crc32_wd, crc32c_bd, crc32c_hd, crc32c_wd; + + + assign crc32_all = ap_crc32_b | ap_crc32_h | ap_crc32_w | ap_crc32c_b | ap_crc32c_h | ap_crc32c_w; + + assign crc32_poly_rev[31:0] = 32'hEDB88320; // bit reverse of 32'h04C11DB7 + assign crc32c_poly_rev[31:0] = 32'h82F63B78; // bit reverse of 32'h1EDC6F41 + + + always_comb + begin + crc32_bd[31:0] = rs1_in[31:0]; + + for (crc32_bi=0; crc32_bi<8; crc32_bi++) + begin + crc32_bd[31:0] = (crc32_bd[31:0] >> 1) ^ (crc32_poly_rev[31:0] & {32{crc32_bd[0]}}); + end // FOR crc32_bi + end // ALWAYS_COMB + + + always_comb + begin + crc32_hd[31:0] = rs1_in[31:0]; + + for (crc32_hi=0; crc32_hi<16; crc32_hi++) + begin + crc32_hd[31:0] = (crc32_hd[31:0] >> 1) ^ (crc32_poly_rev[31:0] & {32{crc32_hd[0]}}); + end // FOR crc32_hi + end // ALWAYS_COMB + + + always_comb + begin + crc32_wd[31:0] = rs1_in[31:0]; + + for (crc32_wi=0; crc32_wi<32; crc32_wi++) + begin + crc32_wd[31:0] = (crc32_wd[31:0] >> 1) ^ (crc32_poly_rev[31:0] & {32{crc32_wd[0]}}); + end // FOR crc32_wi + end // ALWAYS_COMB + + + + + always_comb + begin + crc32c_bd[31:0] = rs1_in[31:0]; + + for (crc32c_bi=0; crc32c_bi<8; crc32c_bi++) + begin + crc32c_bd[31:0] = (crc32c_bd[31:0] >> 1) ^ (crc32c_poly_rev[31:0] & {32{crc32c_bd[0]}}); + end // FOR crc32c_bi + end // ALWAYS_COMB + + + always_comb + begin + crc32c_hd[31:0] = rs1_in[31:0]; + + for (crc32c_hi=0; crc32c_hi<16; crc32c_hi++) + begin + crc32c_hd[31:0] = (crc32c_hd[31:0] >> 1) ^ (crc32c_poly_rev[31:0] & {32{crc32c_hd[0]}}); + end // FOR crc32c_hi + end // ALWAYS_COMB + + + always_comb + begin + crc32c_wd[31:0] = rs1_in[31:0]; + + for (crc32c_wi=0; crc32c_wi<32; crc32c_wi++) + begin + crc32c_wd[31:0] = (crc32c_wd[31:0] >> 1) ^ (crc32c_poly_rev[31:0] & {32{crc32c_wd[0]}}); + end // FOR crc32c_wi + end // ALWAYS_COMB + + + + + + // * * * * * * * * * * * * * * * * * * BitManip : BFP * * * * * * * * * * * * * * * * * * + + + // uint_xlen_t bfp(uint_xlen_t rs1, uint_xlen_t rs2) + // { + // uint_xlen_t cfg = rs2 >> (XLEN/2); + // if ((cfg >> 30) == 2) cfg = cfg >> 16; + // int len = (cfg >> 8) & (XLEN/2-1); + // int off = cfg & (XLEN-1); + // len = len ? len : XLEN/2; + // uint_xlen_t mask = slo(0, len) << off; + // uint_xlen_t data = rs2 << off; + // return (data & mask) | (rs1 & ~mask); + + + logic [4:0] bfp_len; + logic [4:0] bfp_off; + logic [31:0] bfp_len_mask_; + logic [31:0] bfp_off_mask_; + logic [15:0] bfp_preshift_data; + logic [31:0] bfp_shift_data; + logic [31:0] bfp_shift_mask; + logic [31:0] bfp_result_d; + + + assign bfp_len[3:0] = rs2_in[27:24]; + assign bfp_len[4] = (bfp_len[3:0] == 4'b0); // If LEN field is zero, then LEN=16 + assign bfp_off[4:0] = rs2_in[20:16]; + + assign bfp_len_mask_[31:0] = 32'hffff_ffff << bfp_len[4:0]; + assign bfp_off_mask_[31:0] = 32'hffff_ffff << bfp_off[4:0]; + assign bfp_preshift_data[15:0]= rs2_in[15:0] & ~bfp_len_mask_[15:0]; + + assign bfp_shift_data[31:0] = {16'b0,bfp_preshift_data[15:0]} << bfp_off[4:0]; + assign bfp_shift_mask[31:0] = (bfp_len_mask_[31:0] << bfp_off[4:0]) | ~bfp_off_mask_[31:0]; + + assign bfp_result_d[31:0] = bfp_shift_data[31:0] | (rs1_in[31:0] & bfp_shift_mask[31:0]); + + + + + // * * * * * * * * * * * * * * * * * * BitManip : Common logic * * * * * * * * * * * * * * * * * * + + + assign bitmanip_sel_d = ap_bcompress | ap_bdecompress | ap_clmul | ap_clmulh | ap_clmulr | ap_grev | ap_gorc | ap_shfl | ap_unshfl | crc32_all | ap_bfp | ap_xperm_n | ap_xperm_b | ap_xperm_h; + + assign bitmanip_d[31:0] = ( {32{ap_bcompress}} & bcompress_d[31:0] ) | + ( {32{ap_bdecompress}} & bdecompress_d[31:0] ) | + ( {32{ap_clmul}} & clmul_raw_d[31:0] ) | + ( {32{ap_clmulh}} & {1'b0,clmul_raw_d[62:32]} ) | + ( {32{ap_clmulr}} & clmul_raw_d[62:31] ) | + ( {32{ap_grev}} & grev_d[31:0] ) | + ( {32{ap_gorc}} & gorc_d[31:0] ) | + ( {32{ap_shfl}} & shfl_d[31:0] ) | + ( {32{ap_unshfl}} & unshfl_d[31:0] ) | + ( {32{ap_crc32_b}} & crc32_bd[31:0] ) | + ( {32{ap_crc32_h}} & crc32_hd[31:0] ) | + ( {32{ap_crc32_w}} & crc32_wd[31:0] ) | + ( {32{ap_crc32c_b}} & crc32c_bd[31:0] ) | + ( {32{ap_crc32c_h}} & crc32c_hd[31:0] ) | + ( {32{ap_crc32c_w}} & crc32c_wd[31:0] ) | + ( {32{ap_bfp}} & bfp_result_d[31:0] ) | + ( {32{ap_xperm_n}} & xperm_n[31:0] ) | + ( {32{ap_xperm_b}} & xperm_b[31:0] ) | + ( {32{ap_xperm_h}} & xperm_h[31:0] ); + + + + rvdffe #(33) i_bitmanip_ff (.*, .clk(clk), .din({bitmanip_sel_d,bitmanip_d[31:0]}), .dout({bitmanip_sel_x,bitmanip_x[31:0]}), .en(bit_x_enable)); + + + + + assign result_x[31:0] = ( {32{~bitmanip_sel_x & ~low_x}} & prod_x[63:32] ) | + ( {32{~bitmanip_sel_x & low_x}} & prod_x[31:0] ) | + bitmanip_x[31:0]; + + + +endmodule // el2_exu_mul_ctl diff --git a/designs/Caliptra/src/caliptra-rtl/el2_ifu.sv b/designs/Caliptra/src/caliptra-rtl/el2_ifu.sv new file mode 100644 index 0000000..a032549 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/el2_ifu.sv @@ -0,0 +1,393 @@ +//******************************************************************************** +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2020 Western Digital Corporation or its affiliates. +// +// 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. +//******************************************************************************** +//******************************************************************************** +// Function: Top level file for Icache, Fetch, Branch prediction & Aligner +// BFF -> F1 -> F2 -> A +//******************************************************************************** + +module el2_ifu +import el2_pkg::*; +#( +`include "el2_param.vh" + ) + ( + input logic free_l2clk, // Clock always. Through one clock header. For flops with second header built in. + input logic active_clk, // Clock only while core active. Through two clock headers. For flops without second clock header built in. + input logic clk, // Clock only while core active. Through one clock header. For flops with second clock header built in. Connected to ACTIVE_L2CLK. + input logic rst_l, // reset, active low + + input logic dec_i0_decode_d, // Valid instruction at D and not blocked + + input logic exu_flush_final, // flush, includes upper and lower + input logic dec_tlu_i0_commit_cmt , // committed i0 + input logic dec_tlu_flush_err_wb , // flush due to parity error. + input logic dec_tlu_flush_noredir_wb, // don't fetch, validated with exu_flush_final + input logic [31:1] exu_flush_path_final, // flush fetch address + + input logic [31:0] dec_tlu_mrac_ff ,// Side_effect , cacheable for each region + input logic dec_tlu_fence_i_wb, // fence.i, invalidate icache, validated with exu_flush_final + input logic dec_tlu_flush_leak_one_wb, // ignore bp for leak one fetches + + input logic dec_tlu_bpred_disable, // disable all branch prediction + input logic dec_tlu_core_ecc_disable, // disable ecc checking and flagging + input logic dec_tlu_force_halt, // force halt + + //-------------------------- IFU AXI signals-------------------------- + // AXI Write Channels + /* exclude signals that are tied to constant value in el2_ifu_mem_ctl.sv */ + /*pragma coverage off*/ + output logic ifu_axi_awvalid, + output logic [pt.IFU_BUS_TAG-1:0] ifu_axi_awid, + output logic [31:0] ifu_axi_awaddr, + output logic [3:0] ifu_axi_awregion, + output logic [7:0] ifu_axi_awlen, + output logic [2:0] ifu_axi_awsize, + output logic [1:0] ifu_axi_awburst, + output logic ifu_axi_awlock, + output logic [3:0] ifu_axi_awcache, + output logic [2:0] ifu_axi_awprot, + output logic [3:0] ifu_axi_awqos, + + output logic ifu_axi_wvalid, + output logic [63:0] ifu_axi_wdata, + output logic [7:0] ifu_axi_wstrb, + output logic ifu_axi_wlast, + + output logic ifu_axi_bready, + /*pragma coverage on*/ + + // AXI Read Channels + output logic ifu_axi_arvalid, + input logic ifu_axi_arready, + output logic [pt.IFU_BUS_TAG-1:0] ifu_axi_arid, + output logic [31:0] ifu_axi_araddr, + output logic [3:0] ifu_axi_arregion, + /* exclude signals that are tied to constant value in el2_ifu_mem_ctl.sv */ + /*pragma coverage off*/ + output logic [7:0] ifu_axi_arlen, + output logic [2:0] ifu_axi_arsize, + output logic [1:0] ifu_axi_arburst, + output logic ifu_axi_arlock, + output logic [3:0] ifu_axi_arcache, + output logic [2:0] ifu_axi_arprot, + output logic [3:0] ifu_axi_arqos, + /*pragma coverage on*/ + + input logic ifu_axi_rvalid, + /* exclude signals that are tied to constant value in el2_ifu_mem_ctl.sv */ + /*pragma coverage off*/ + output logic ifu_axi_rready, + /*pragma coverage on*/ + input logic [pt.IFU_BUS_TAG-1:0] ifu_axi_rid, + input logic [63:0] ifu_axi_rdata, + input logic [1:0] ifu_axi_rresp, + + input logic ifu_bus_clk_en, + + input logic dma_iccm_req, + input logic [31:0] dma_mem_addr, + input logic [2:0] dma_mem_sz, + input logic dma_mem_write, + input logic [63:0] dma_mem_wdata, + input logic [2:0] dma_mem_tag, // DMA Buffer entry number + + + input logic dma_iccm_stall_any, + output logic iccm_dma_ecc_error, + output logic iccm_dma_rvalid, + output logic [63:0] iccm_dma_rdata, + output logic [2:0] iccm_dma_rtag, // Tag of the DMA req + output logic iccm_ready, + + output logic ifu_pmu_instr_aligned, + output logic ifu_pmu_fetch_stall, + output logic ifu_ic_error_start, // has all of the I$ ecc/parity for data/tag + +// I$ & ITAG Ports + output logic [31:1] ic_rw_addr, // Read/Write addresss to the Icache. + output logic [pt.ICACHE_NUM_WAYS-1:0] ic_wr_en, // Icache write enable, when filling the Icache. + output logic ic_rd_en, // Icache read enable. + + output logic [pt.ICACHE_BANKS_WAY-1:0][70:0] ic_wr_data, // Data to fill to the Icache. With ECC + input logic [63:0] ic_rd_data , // Data read from Icache. 2x64bits + parity bits. F2 stage. With ECC + input logic [70:0] ic_debug_rd_data , // Data read from Icache. 2x64bits + parity bits. F2 stage. With ECC + input logic [25:0] ictag_debug_rd_data,// Debug icache tag. + output logic [70:0] ic_debug_wr_data, // Debug wr cache. + + output logic [70:0] ifu_ic_debug_rd_data, + + input logic [pt.ICACHE_BANKS_WAY-1:0] ic_eccerr, // + input logic [pt.ICACHE_BANKS_WAY-1:0] ic_parerr, + output logic [63:0] ic_premux_data, // Premux data to be muxed with each way of the Icache. + output logic ic_sel_premux_data, // Select the premux data. + + output logic [pt.ICACHE_INDEX_HI:3] ic_debug_addr, // Read/Write addresss to the Icache. + output logic ic_debug_rd_en, // Icache debug rd + output logic ic_debug_wr_en, // Icache debug wr + output logic ic_debug_tag_array, // Debug tag array + output logic [pt.ICACHE_NUM_WAYS-1:0] ic_debug_way, // Debug way. Rd or Wr. + + + output logic [pt.ICACHE_NUM_WAYS-1:0] ic_tag_valid, // Valid bits when accessing the Icache. One valid bit per way. F2 stage + + input logic [pt.ICACHE_NUM_WAYS-1:0] ic_rd_hit, // Compare hits from Icache tags. Per way. F2 stage + input logic ic_tag_perr, // Icache Tag parity error + + + // ICCM ports + output logic [pt.ICCM_BITS-1:1] iccm_rw_addr, // ICCM read/write address. + output logic iccm_wren, // ICCM write enable (through the DMA) + output logic iccm_rden, // ICCM read enable. + output logic [77:0] iccm_wr_data, // ICCM write data. + output logic [2:0] iccm_wr_size, // ICCM write location within DW. + + input logic [63:0] iccm_rd_data, // Data read from ICCM. + input logic [77:0] iccm_rd_data_ecc, // Data + ECC read from ICCM. + + // ICCM ECC status + output logic ifu_iccm_dma_rd_ecc_single_err, // This fetch has a single ICCM DMA ECC error. + output logic ifu_iccm_rd_ecc_single_err, // This fetch has a single ICCM ECC error. + output logic ifu_iccm_rd_ecc_double_err, // This fetch has a double ICCM ECC error. + +// Perf counter sigs + output logic ifu_pmu_ic_miss, // ic miss + output logic ifu_pmu_ic_hit, // ic hit + output logic ifu_pmu_bus_error, // iside bus error + output logic ifu_pmu_bus_busy, // iside bus busy + output logic ifu_pmu_bus_trxn, // iside bus transactions + + + output logic ifu_i0_icaf, // Instruction 0 access fault. From Aligner to Decode + output logic [1:0] ifu_i0_icaf_type, // Instruction 0 access fault type + + output logic ifu_i0_valid, // Instruction 0 valid. From Aligner to Decode + output logic ifu_i0_icaf_second, // Instruction 0 has access fault on second 2B of 4B inst + output logic ifu_i0_dbecc, // Instruction 0 has double bit ecc error + output logic iccm_dma_sb_error, // Single Bit ECC error from a DMA access + output logic[31:0] ifu_i0_instr, // Instruction 0 . From Aligner to Decode + output logic[31:1] ifu_i0_pc, // Instruction 0 pc. From Aligner to Decode + output logic ifu_i0_pc4, // Instruction 0 is 4 byte. From Aligner to Decode + + output logic ifu_miss_state_idle, // There is no outstanding miss. Cache miss state is idle. + + output el2_br_pkt_t i0_brp, // Instruction 0 branch packet. From Aligner to Decode + output logic [pt.BTB_ADDR_HI:pt.BTB_ADDR_LO] ifu_i0_bp_index, // BP index + output logic [pt.BHT_GHR_SIZE-1:0] ifu_i0_bp_fghr, // BP FGHR + output logic [pt.BTB_BTAG_SIZE-1:0] ifu_i0_bp_btag, // BP tag + output logic [$clog2(pt.BTB_SIZE)-1:0] ifu_i0_fa_index, // Fully associt btb index + + input el2_predict_pkt_t exu_mp_pkt, // mispredict packet + input logic [pt.BHT_GHR_SIZE-1:0] exu_mp_eghr, // execute ghr + input logic [pt.BHT_GHR_SIZE-1:0] exu_mp_fghr, // Mispredict fghr + input logic [pt.BTB_ADDR_HI:pt.BTB_ADDR_LO] exu_mp_index, // Mispredict index + input logic [pt.BTB_BTAG_SIZE-1:0] exu_mp_btag, // Mispredict btag + + input el2_br_tlu_pkt_t dec_tlu_br0_r_pkt, // slot0 update/error pkt + input logic [pt.BHT_GHR_SIZE-1:0] exu_i0_br_fghr_r, // fghr to bp + input logic [pt.BTB_ADDR_HI:pt.BTB_ADDR_LO] exu_i0_br_index_r, // bp index + input logic [$clog2(pt.BTB_SIZE)-1:0] dec_fa_error_index, // Fully associt btb error index + + input dec_tlu_flush_lower_wb, + + output logic [15:0] ifu_i0_cinst, + + output logic [31:1] ifu_pmp_addr, + input logic ifu_pmp_error, + +/// Icache debug + input el2_cache_debug_pkt_t dec_tlu_ic_diag_pkt , + output logic ifu_ic_debug_rd_data_valid, + output logic iccm_buf_correct_ecc, + output logic iccm_correction_state, + + // Excluding scan_mode from coverage as its usage is determined by the integrator of the VeeR core. + /*pragma coverage off*/ + input logic scan_mode + /*pragma coverage on*/ + ); + + localparam TAGWIDTH = 2 ; + localparam IDWIDTH = 2 ; + + logic ifu_fb_consume1, ifu_fb_consume2; + logic [31:1] ifc_fetch_addr_f; + logic [31:1] ifc_fetch_addr_bf; + assign ifu_pmp_addr = ifc_fetch_addr_bf; + + logic [1:0] ifu_fetch_val; // valids on a 2B boundary, left justified [7] implies valid fetch + logic [31:1] ifu_fetch_pc; // starting pc of fetch + + logic iccm_rd_ecc_single_err, iccm_dma_rd_ecc_single_err, ic_error_start; + assign ifu_iccm_dma_rd_ecc_single_err = iccm_dma_rd_ecc_single_err; + assign ifu_iccm_rd_ecc_single_err = iccm_rd_ecc_single_err; + assign ifu_ic_error_start = ic_error_start; + + + logic ic_write_stall; + logic ic_dma_active; + logic ifc_dma_access_ok; + logic [1:0] ic_access_fault_f; + logic [1:0] ic_access_fault_type_f; + logic ifu_ic_mb_empty; + + logic ic_hit_f; + + logic [1:0] ifu_bp_way_f; // way indication; right justified + logic ifu_bp_hit_taken_f; // kill next fetch; taken target found + logic [31:1] ifu_bp_btb_target_f; // predicted target PC + logic ifu_bp_inst_mask_f; // tell ic which valids to kill because of a taken branch; right justified + logic [1:0] ifu_bp_hist1_f; // history counters for all 4 potential branches; right justified + logic [1:0] ifu_bp_hist0_f; // history counters for all 4 potential branches; right justified + logic [11:0] ifu_bp_poffset_f; // predicted target + logic [1:0] ifu_bp_ret_f; // predicted ret ; right justified + logic [1:0] ifu_bp_pc4_f; // pc4 indication; right justified + logic [1:0] ifu_bp_valid_f; // branch valid, right justified + logic [pt.BHT_GHR_SIZE-1:0] ifu_bp_fghr_f; + logic [1:0] [$clog2(pt.BTB_SIZE)-1:0] ifu_bp_fa_index_f; + + + logic [1:0] ic_fetch_val_f; + logic [31:0] ic_data_f; + logic [31:0] ifu_fetch_data_f; + logic ifc_fetch_req_f; + logic ifc_fetch_req_f_raw; + logic iccm_dma_rd_ecc_double_err; + logic [1:0] iccm_rd_ecc_double_err; // This fetch has an iccm double error. + assign ifu_iccm_rd_ecc_double_err = |iccm_rd_ecc_double_err || |iccm_dma_rd_ecc_double_err; + + logic ifu_async_error_start; + + + assign ifu_fetch_data_f[31:0] = ic_data_f[31:0]; + assign ifu_fetch_val[1:0] = ic_fetch_val_f[1:0]; + assign ifu_fetch_pc[31:1] = ifc_fetch_addr_f[31:1]; + + logic ifc_fetch_uncacheable_bf; // The fetch request is uncacheable space. BF stage + logic ifc_fetch_req_bf; // Fetch request. Comes with the address. BF stage + logic ifc_fetch_req_bf_raw; // Fetch request without some qualifications. Used for clock-gating. BF stage + logic ifc_iccm_access_bf; // This request is to the ICCM. Do not generate misses to the bus. + logic ifc_region_acc_fault_bf; // Access fault. in ICCM region but offset is outside defined ICCM. + + // fetch control + el2_ifu_ifc_ctl #(.pt(pt)) ifc (.* + ); + + // branch predictor + if (pt.BTB_ENABLE==1) begin : bpred + el2_ifu_bp_ctl #(.pt(pt)) bp (.*); + end + else begin : bpred + assign ifu_bp_hit_taken_f = '0; + // verif wires + logic btb_wr_en_way0, btb_wr_en_way1,dec_tlu_error_wb; + logic [16+pt.BTB_BTAG_SIZE:0] btb_wr_data; + assign btb_wr_en_way0 = '0; + assign btb_wr_en_way1 = '0; + assign btb_wr_data = '0; + assign dec_tlu_error_wb ='0; + assign ifu_bp_inst_mask_f = 1'b1; + end + + + + // aligner + + el2_ifu_aln_ctl #(.pt(pt)) aln ( + .* + ); + + + // icache + el2_ifu_mem_ctl #(.pt(pt)) mem_ctl + (.*, + .ic_data_f(ic_data_f[31:0]) + ); + + + + // Performance debug info + // + // +`ifdef DUMP_BTB_ON + logic exu_mp_valid; // conditional branch mispredict + logic exu_mp_way; // conditional branch mispredict + logic exu_mp_ataken; // direction is actual taken + logic exu_mp_boffset; // branch offsett + logic exu_mp_pc4; // branch is a 4B inst + logic exu_mp_call; // branch is a call inst + logic exu_mp_ret; // branch is a ret inst + logic exu_mp_ja; // branch is a jump always + logic [1:0] exu_mp_hist; // new history + logic [11:0] exu_mp_tgt; // target offset + logic [pt.BTB_ADDR_HI:pt.BTB_ADDR_LO] exu_mp_addr; // BTB/BHT address + + assign exu_mp_valid = exu_mp_pkt.misp; // conditional branch mispredict + assign exu_mp_ataken = exu_mp_pkt.ataken; // direction is actual taken + assign exu_mp_boffset = exu_mp_pkt.boffset; // branch offset + assign exu_mp_pc4 = exu_mp_pkt.pc4; // branch is a 4B inst + assign exu_mp_call = exu_mp_pkt.pcall; // branch is a call inst + assign exu_mp_ret = exu_mp_pkt.pret; // branch is a ret inst + assign exu_mp_ja = exu_mp_pkt.pja; // branch is a jump always + assign exu_mp_way = exu_mp_pkt.way; // branch is a jump always + assign exu_mp_hist[1:0] = exu_mp_pkt.hist[1:0]; // new history + assign exu_mp_tgt[11:0] = exu_mp_pkt.toffset[11:0] ; // target offset + assign exu_mp_addr[pt.BTB_ADDR_HI:pt.BTB_ADDR_LO] = exu_mp_index[pt.BTB_ADDR_HI:pt.BTB_ADDR_LO] ; // BTB/BHT address + + logic [pt.BTB_ADDR_HI:pt.BTB_ADDR_LO] btb_rd_addr_f; + `define DEC `CPU_TOP.dec + `define EXU `CPU_TOP.exu + el2_btb_addr_hash f2hash(.pc(ifc_fetch_addr_f[pt.BTB_INDEX3_HI:pt.BTB_INDEX1_LO]), .hash(btb_rd_addr_f[pt.BTB_ADDR_HI:pt.BTB_ADDR_LO])); + logic [31:0] mppc_ns, mppc; + logic exu_flush_final_d1; + assign mppc_ns[31:1] = `EXU.i0_flush_upper_x ? `EXU.exu_i0_pc_x : `EXU.dec_i0_pc_d; + assign mppc_ns[0] = 1'b0; + rvdff #(33) junk_ff (.*, .clk(active_clk), .din({mppc_ns[31:0], exu_flush_final}), .dout({mppc[31:0], exu_flush_final_d1})); + logic tmp_bnk; + assign tmp_bnk = bpred.bp.btb_sel_f[1]; + + always @(negedge clk) begin + if(`DEC.tlu.mcyclel[31:0] == 32'h0000_0010) begin + $display("BTB_CONFIG: %d",pt.BTB_SIZE); + `ifndef BP_NOGSHARE + $display("BHT_CONFIG: %d gshare: 1",pt.BHT_SIZE); + `else + $display("BHT_CONFIG: %d gshare: 0",pt.BHT_SIZE); + `endif + $display("RS_CONFIG: %d", pt.RET_STACK_SIZE); + end + if(exu_flush_final_d1 & ~(dec_tlu_br0_r_pkt.br_error | dec_tlu_br0_r_pkt.br_start_error) & (exu_mp_pkt.misp | exu_mp_pkt.ataken)) + $display("%7d BTB_MP : index: %0h bank: %0h call: %b ret: %b ataken: %b hist: %h valid: %b tag: %h targ: %h eghr: %b pred: %b ghr_index: %h brpc: %h way: %h", `DEC.tlu.mcyclel[31:0]+32'ha, exu_mp_addr[pt.BTB_ADDR_HI:pt.BTB_ADDR_LO], 1'b0, exu_mp_call, exu_mp_ret, exu_mp_ataken, exu_mp_hist[1:0], exu_mp_valid, exu_mp_btag[pt.BTB_BTAG_SIZE-1:0], {exu_flush_path_final[31:1], 1'b0}, exu_mp_eghr[pt.BHT_GHR_SIZE-1:0], exu_mp_valid, bpred.bp.bht_wr_addr0, mppc[31:0], exu_mp_pkt.way); + + for(int i = 0; i < 8; i++) begin + if(ifu_bp_valid_f[i] & ifc_fetch_req_f) + $display("%7d BTB_HIT : index: %0h bank: %0h call: %b ret: %b taken: %b strength: %b tag: %h targ: %0h ghr: %4b ghr_index: %h way: %h", `DEC.tlu.mcyclel[31:0]+32'ha,btb_rd_addr_f[pt.BTB_ADDR_HI:pt.BTB_ADDR_LO],bpred.bp.btb_sel_f[1], bpred.bp.btb_rd_call_f, bpred.bp.btb_rd_ret_f, ifu_bp_hist1_f[tmp_bnk], ifu_bp_hist0_f[tmp_bnk], bpred.bp.fetch_rd_tag_f[pt.BTB_BTAG_SIZE-1:0], {ifu_bp_btb_target_f[31:1], 1'b0}, bpred.bp.fghr[pt.BHT_GHR_SIZE-1:0], bpred.bp.bht_rd_addr_f, ifu_bp_way_f[tmp_bnk]); + end + if(dec_tlu_br0_r_pkt.valid & ~(dec_tlu_br0_r_pkt.br_error | dec_tlu_br0_r_pkt.br_start_error)) + $display("%7d BTB_UPD0: ghr_index: %0h bank: %0h hist: %h way: %h", `DEC.tlu.mcyclel[31:0]+32'ha,bpred.bp.br0_hashed_wb[pt.BHT_ADDR_HI:pt.BHT_ADDR_LO],{dec_tlu_br0_r_pkt.middle}, dec_tlu_br0_r_pkt.hist, dec_tlu_br0_r_pkt.way); + + if(dec_tlu_br0_r_pkt.br_error | dec_tlu_br0_r_pkt.br_start_error) + $display("%7d BTB_ERR0: index: %0h bank: %0h start: %b rfpc: %h way: %h", `DEC.tlu.mcyclel[31:0]+32'ha,exu_i0_br_index_r[pt.BTB_ADDR_HI:pt.BTB_ADDR_LO],1'b0, dec_tlu_br0_r_pkt.br_start_error, {exu_flush_path_final[31:1], 1'b0}, dec_tlu_br0_r_pkt.way); + end // always @ (negedge clk) + function [1:0] encode4_2; + input [3:0] in; + + encode4_2[1] = in[3] | in[2]; + encode4_2[0] = in[3] | in[1]; + + endfunction +`endif +endmodule // el2_ifu diff --git a/designs/Caliptra/src/caliptra-rtl/el2_ifu_aln_ctl.sv b/designs/Caliptra/src/caliptra-rtl/el2_ifu_aln_ctl.sv new file mode 100644 index 0000000..f69b8c4 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/el2_ifu_aln_ctl.sv @@ -0,0 +1,704 @@ +//******************************************************************************** +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2020 Western Digital Corporation or its affiliates. +// +// 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. +//******************************************************************************** + +//******************************************************************************** +// Function: Instruction aligner +//******************************************************************************** +module el2_ifu_aln_ctl +import el2_pkg::*; +#( +`include "el2_param.vh" + ) + ( + + // Excluding scan_mode from coverage as its usage is determined by the integrator of the VeeR core. + /*pragma coverage off*/ + input logic scan_mode, // Flop scan mode control + /*pragma coverage on*/ + input logic rst_l, // reset, active low + input logic clk, // Clock only while core active. Through one clock header. For flops with second clock header built in. Connected to ACTIVE_L2CLK. + input logic active_clk, // Clock only while core active. Through two clock headers. For flops without second clock header built in. + + input logic ifu_async_error_start, // ecc/parity related errors with current fetch - not sent down the pipe + + input logic [1:0] iccm_rd_ecc_double_err, // This fetch has a double ICCM ecc error. + + input logic [1:0] ic_access_fault_f, // Instruction access fault for the current fetch. + input logic [1:0] ic_access_fault_type_f, // Instruction access fault types + + input logic exu_flush_final, // Flush from the pipeline. + + input logic dec_i0_decode_d, // Valid instruction at D-stage and not blocked + + input logic [31:0] ifu_fetch_data_f, // fetch data in memory format - not right justified + + input logic [1:0] ifu_fetch_val, // valids on a 2B boundary, right justified + input logic [31:1] ifu_fetch_pc, // starting pc of fetch + + + + output logic ifu_i0_valid, // Instruction 0 is valid + output logic ifu_i0_icaf, // Instruction 0 has access fault + output logic [1:0] ifu_i0_icaf_type, // Instruction 0 access fault type + output logic ifu_i0_icaf_second, // Instruction 0 has access fault on second 2B of 4B inst + + output logic ifu_i0_dbecc, // Instruction 0 has double bit ecc error + output logic [31:0] ifu_i0_instr, // Instruction 0 + output logic [31:1] ifu_i0_pc, // Instruction 0 PC + output logic ifu_i0_pc4, + + output logic ifu_fb_consume1, // Consumed one buffer. To fetch control fetch for buffer mass balance + output logic ifu_fb_consume2, // Consumed two buffers.To fetch control fetch for buffer mass balance + + + input logic [pt.BHT_GHR_SIZE-1:0] ifu_bp_fghr_f, // fetch GHR + input logic [31:1] ifu_bp_btb_target_f, // predicted RET target + input logic [11:0] ifu_bp_poffset_f, // predicted target offset + input logic [1:0] [$clog2(pt.BTB_SIZE)-1:0] ifu_bp_fa_index_f, // predicted branch index (fully associative option) + + input logic [1:0] ifu_bp_hist0_f, // history counters for all 4 potential branches, bit 1, right justified + input logic [1:0] ifu_bp_hist1_f, // history counters for all 4 potential branches, bit 1, right justified + input logic [1:0] ifu_bp_pc4_f, // pc4 indication, right justified + input logic [1:0] ifu_bp_way_f, // way indication, right justified + input logic [1:0] ifu_bp_valid_f, // branch valid, right justified + input logic [1:0] ifu_bp_ret_f, // predicted ret indication, right justified + + + output el2_br_pkt_t i0_brp, // Branch packet for I0. + output logic [pt.BTB_ADDR_HI:pt.BTB_ADDR_LO] ifu_i0_bp_index, // BP index + output logic [pt.BHT_GHR_SIZE-1:0] ifu_i0_bp_fghr, // BP FGHR + output logic [pt.BTB_BTAG_SIZE-1:0] ifu_i0_bp_btag, // BP tag + + output logic [$clog2(pt.BTB_SIZE)-1:0] ifu_i0_fa_index, // Fully associt btb index + + output logic ifu_pmu_instr_aligned, // number of inst aligned this cycle + + output logic [15:0] ifu_i0_cinst // 16b compress inst for i0 + ); + + + + logic ifvalid; + logic shift_f1_f0, shift_f2_f0, shift_f2_f1; + logic fetch_to_f0, fetch_to_f1, fetch_to_f2; + + logic [1:0] f2val_in, f2val; + logic [1:0] f1val_in, f1val; + logic [1:0] f0val_in, f0val; + logic [1:0] sf1val, sf0val; + + logic [31:0] aligndata; + logic first4B, first2B; + + logic [31:0] uncompress0; + logic i0_shift; + logic shift_2B, shift_4B; + logic f1_shift_2B; + logic f2_valid, sf1_valid, sf0_valid; + + logic [31:0] ifirst; + logic [1:0] alignval; + logic [31:1] firstpc, secondpc; + + logic [11:0] f1poffset; + logic [11:0] f0poffset; + logic [pt.BHT_GHR_SIZE-1:0] f1fghr; + logic [pt.BHT_GHR_SIZE-1:0] f0fghr; + logic [1:0] f1hist1; + logic [1:0] f0hist1; + logic [1:0] f1hist0; + logic [1:0] f0hist0; + + logic [1:0][$clog2(pt.BTB_SIZE)-1:0] f0index, f1index, alignindex; + + logic [1:0] f1ictype; + logic [1:0] f0ictype; + + logic [1:0] f1pc4; + logic [1:0] f0pc4; + + logic [1:0] f1ret; + logic [1:0] f0ret; + logic [1:0] f1way; + logic [1:0] f0way; + + logic [1:0] f1brend; + logic [1:0] f0brend; + + logic [1:0] alignbrend; + logic [1:0] alignpc4; + + logic [1:0] alignret; + logic [1:0] alignway; + logic [1:0] alignhist1; + logic [1:0] alignhist0; + logic [1:1] alignfromf1; + logic i0_ends_f1; + logic i0_br_start_error; + + logic [31:1] f1prett; + logic [31:1] f0prett; + logic [1:0] f1dbecc; + logic [1:0] f0dbecc; + logic [1:0] f1icaf; + logic [1:0] f0icaf; + + logic [1:0] aligndbecc; + logic [1:0] alignicaf; + logic i0_brp_pc4; + + logic [pt.BTB_ADDR_HI:pt.BTB_ADDR_LO] firstpc_hash, secondpc_hash; + + logic first_legal; + + logic [1:0] wrptr, wrptr_in; + logic [1:0] rdptr, rdptr_in; + logic [2:0] qwen; + logic [31:0] q2,q1,q0; + logic q2off_in, q2off; + logic q1off_in, q1off; + logic q0off_in, q0off; + logic f0_shift_2B; + + logic [31:0] q0eff; + logic [31:0] q0final; + logic q0ptr; + logic [1:0] q0sel; + + logic [31:0] q1eff; + logic [15:0] q1final; + logic q1ptr; + logic [1:0] q1sel; + + logic [2:0] qren; + + logic consume_fb1, consume_fb0; + logic [1:0] icaf_eff; + + localparam BRDATA_SIZE = pt.BTB_ENABLE ? 16+($clog2(pt.BTB_SIZE)*2*pt.BTB_FULLYA) : 4; + localparam BRDATA_WIDTH = pt.BTB_ENABLE ? 8+($clog2(pt.BTB_SIZE)*pt.BTB_FULLYA) : 2; + logic [BRDATA_SIZE-1:0] brdata_in, brdata2, brdata1, brdata0; + logic [BRDATA_SIZE-1:0] brdata1eff, brdata0eff; + logic [BRDATA_SIZE-1:0] brdata1final, brdata0final; + + localparam MHI = 1+(pt.BTB_ENABLE * (43+pt.BHT_GHR_SIZE)); + localparam MSIZE = 2+(pt.BTB_ENABLE * (43+pt.BHT_GHR_SIZE)); + + logic [MHI:0] misc_data_in, misc2, misc1, misc0; + logic [MHI:0] misc1eff, misc0eff; + + logic [pt.BTB_BTAG_SIZE-1:0] firstbrtag_hash, secondbrtag_hash; + + logic error_stall_in, error_stall; + + assign error_stall_in = (error_stall | ifu_async_error_start) & ~exu_flush_final; + + rvdff #(.WIDTH(7)) bundle1ff (.*, + .clk(active_clk), + .din ({wrptr_in[1:0],rdptr_in[1:0],q2off_in,q1off_in,q0off_in}), + .dout({wrptr[1:0], rdptr[1:0], q2off, q1off, q0off}) + ); + + rvdffie #(.WIDTH(7),.OVERRIDE(1)) bundle2ff (.*, + .din ({error_stall_in,f2val_in[1:0],f1val_in[1:0],f0val_in[1:0]}), + .dout({error_stall, f2val[1:0], f1val[1:0], f0val[1:0] }) + ); + +if(pt.BTB_ENABLE==1) begin : genblock1 + rvdffe #(BRDATA_SIZE) brdata2ff (.*, .clk(clk), .en(qwen[2]), .din(brdata_in[BRDATA_SIZE-1:0]), .dout(brdata2[BRDATA_SIZE-1:0])); + rvdffe #(BRDATA_SIZE) brdata1ff (.*, .clk(clk), .en(qwen[1]), .din(brdata_in[BRDATA_SIZE-1:0]), .dout(brdata1[BRDATA_SIZE-1:0])); + rvdffe #(BRDATA_SIZE) brdata0ff (.*, .clk(clk), .en(qwen[0]), .din(brdata_in[BRDATA_SIZE-1:0]), .dout(brdata0[BRDATA_SIZE-1:0])); + rvdffe #(MSIZE) misc2ff (.*, .clk(clk), .en(qwen[2]), .din(misc_data_in[MHI:0]), .dout(misc2[MHI:0])); + rvdffe #(MSIZE) misc1ff (.*, .clk(clk), .en(qwen[1]), .din(misc_data_in[MHI:0]), .dout(misc1[MHI:0])); + rvdffe #(MSIZE) misc0ff (.*, .clk(clk), .en(qwen[0]), .din(misc_data_in[MHI:0]), .dout(misc0[MHI:0])); +end +else begin : genblock1 + + rvdffie #((MSIZE*3)+(BRDATA_SIZE*3)) miscff (.*, + .din({qwen[2] ? {misc_data_in[MHI:0], brdata_in[BRDATA_SIZE-1:0]} : {misc2[MHI:0], brdata2[BRDATA_SIZE-1:0]}, + qwen[1] ? {misc_data_in[MHI:0], brdata_in[BRDATA_SIZE-1:0]} : {misc1[MHI:0], brdata1[BRDATA_SIZE-1:0]}, + qwen[0] ? {misc_data_in[MHI:0], brdata_in[BRDATA_SIZE-1:0]} : {misc0[MHI:0], brdata0[BRDATA_SIZE-1:0]}}), + .dout({misc2[MHI:0], brdata2[BRDATA_SIZE-1:0], + misc1[MHI:0], brdata1[BRDATA_SIZE-1:0], + misc0[MHI:0], brdata0[BRDATA_SIZE-1:0]}) + ); +end + + logic [31:1] q2pc, q1pc, q0pc; + + rvdffe #(31) q2pcff (.*, .clk(clk), .en(qwen[2]), .din(ifu_fetch_pc[31:1]), .dout(q2pc[31:1])); + rvdffe #(31) q1pcff (.*, .clk(clk), .en(qwen[1]), .din(ifu_fetch_pc[31:1]), .dout(q1pc[31:1])); + rvdffe #(31) q0pcff (.*, .clk(clk), .en(qwen[0]), .din(ifu_fetch_pc[31:1]), .dout(q0pc[31:1])); + + rvdffe #(32) q2ff (.*, .clk(clk), .en(qwen[2]), .din(ifu_fetch_data_f[31:0]), .dout(q2[31:0])); + rvdffe #(32) q1ff (.*, .clk(clk), .en(qwen[1]), .din(ifu_fetch_data_f[31:0]), .dout(q1[31:0])); + rvdffe #(32) q0ff (.*, .clk(clk), .en(qwen[0]), .din(ifu_fetch_data_f[31:0]), .dout(q0[31:0])); + + + // new queue control logic + + assign qren[2:0] = { rdptr[1:0] == 2'b10, + rdptr[1:0] == 2'b01, + rdptr[1:0] == 2'b00 }; + + assign qwen[2:0] = { (wrptr[1:0] == 2'b10) & ifvalid, + (wrptr[1:0] == 2'b01) & ifvalid, + (wrptr[1:0] == 2'b00) & ifvalid }; + + + assign rdptr_in[1:0] = ({2{ qren[0] & ifu_fb_consume1 & ~exu_flush_final}} & 2'b01 ) | + ({2{ qren[1] & ifu_fb_consume1 & ~exu_flush_final}} & 2'b10 ) | + ({2{ qren[2] & ifu_fb_consume1 & ~exu_flush_final}} & 2'b00 ) | + ({2{ qren[0] & ifu_fb_consume2 & ~exu_flush_final}} & 2'b10 ) | + ({2{ qren[1] & ifu_fb_consume2 & ~exu_flush_final}} & 2'b00 ) | + ({2{ qren[2] & ifu_fb_consume2 & ~exu_flush_final}} & 2'b01 ) | + ({2{~ifu_fb_consume1 & ~ifu_fb_consume2 & ~exu_flush_final}} & rdptr[1:0]); + + assign wrptr_in[1:0] = ({2{ qwen[0] & ~exu_flush_final}} & 2'b01 ) | + ({2{ qwen[1] & ~exu_flush_final}} & 2'b10 ) | + ({2{ qwen[2] & ~exu_flush_final}} & 2'b00 ) | + ({2{~ifvalid & ~exu_flush_final}} & wrptr[1:0]); + + + + assign q2off_in = ( ~qwen[2] & (rdptr[1:0]==2'd2) & (q2off | f0_shift_2B) ) | + ( ~qwen[2] & (rdptr[1:0]==2'd1) & (q2off | f1_shift_2B) ) | + ( ~qwen[2] & (rdptr[1:0]==2'd0) & q2off ); + + assign q1off_in = ( ~qwen[1] & (rdptr[1:0]==2'd1) & (q1off | f0_shift_2B) ) | + ( ~qwen[1] & (rdptr[1:0]==2'd0) & (q1off | f1_shift_2B) ) | + ( ~qwen[1] & (rdptr[1:0]==2'd2) & q1off ); + + assign q0off_in = ( ~qwen[0] & (rdptr[1:0]==2'd0) & (q0off | f0_shift_2B) ) | + ( ~qwen[0] & (rdptr[1:0]==2'd2) & (q0off | f1_shift_2B) ) | + ( ~qwen[0] & (rdptr[1:0]==2'd1) & q0off ); + + + + assign q0ptr = ( (rdptr[1:0]==2'b00) & q0off ) | + ( (rdptr[1:0]==2'b01) & q1off ) | + ( (rdptr[1:0]==2'b10) & q2off ); + + assign q1ptr = ( (rdptr[1:0]==2'b00) & q1off ) | + ( (rdptr[1:0]==2'b01) & q2off ) | + ( (rdptr[1:0]==2'b10) & q0off ); + + assign q0sel[1:0] = {q0ptr,~q0ptr}; + + assign q1sel[1:0] = {q1ptr,~q1ptr}; + + // end new queue control logic + + + // misc data that is associated with each fetch buffer + + if(pt.BTB_ENABLE==1) + assign misc_data_in[MHI:0] = { + + ic_access_fault_type_f[1:0], + ifu_bp_btb_target_f[31:1], + ifu_bp_poffset_f[11:0], + ifu_bp_fghr_f[pt.BHT_GHR_SIZE-1:0] + }; + else + assign misc_data_in[MHI:0] = { + ic_access_fault_type_f[1:0] + }; + + + assign {misc1eff[MHI:0],misc0eff[MHI:0]} = (({MSIZE*2{qren[0]}} & {misc1[MHI:0],misc0[MHI:0]}) | + ({MSIZE*2{qren[1]}} & {misc2[MHI:0],misc1[MHI:0]}) | + ({MSIZE*2{qren[2]}} & {misc0[MHI:0],misc2[MHI:0]})); + + if(pt.BTB_ENABLE==1) begin + assign { + f1ictype[1:0], + f1prett[31:1], + f1poffset[11:0], + f1fghr[pt.BHT_GHR_SIZE-1:0] + } = misc1eff[MHI:0]; + + assign { + f0ictype[1:0], + f0prett[31:1], + f0poffset[11:0], + f0fghr[pt.BHT_GHR_SIZE-1:0] + } = misc0eff[MHI:0]; + + if(pt.BTB_FULLYA) begin + assign brdata_in[BRDATA_SIZE-1:0] = { + ifu_bp_fa_index_f[1], iccm_rd_ecc_double_err[1],ic_access_fault_f[1],ifu_bp_hist1_f[1],ifu_bp_hist0_f[1],ifu_bp_pc4_f[1],ifu_bp_way_f[1],ifu_bp_valid_f[1],ifu_bp_ret_f[1], + ifu_bp_fa_index_f[0], iccm_rd_ecc_double_err[0],ic_access_fault_f[0],ifu_bp_hist1_f[0],ifu_bp_hist0_f[0],ifu_bp_pc4_f[0],ifu_bp_way_f[0],ifu_bp_valid_f[0],ifu_bp_ret_f[0] + }; + assign {f0index[1],f0dbecc[1],f0icaf[1],f0hist1[1],f0hist0[1],f0pc4[1],f0way[1],f0brend[1],f0ret[1], + f0index[0],f0dbecc[0],f0icaf[0],f0hist1[0],f0hist0[0],f0pc4[0],f0way[0],f0brend[0],f0ret[0]} = brdata0final[BRDATA_SIZE-1:0]; + + assign {f1index[1],f1dbecc[1],f1icaf[1],f1hist1[1],f1hist0[1],f1pc4[1],f1way[1],f1brend[1],f1ret[1], + f1index[0],f1dbecc[0],f1icaf[0],f1hist1[0],f1hist0[0],f1pc4[0],f1way[0],f1brend[0],f1ret[0]} = brdata1final[BRDATA_SIZE-1:0]; + + end + else begin + assign brdata_in[BRDATA_SIZE-1:0] = { + iccm_rd_ecc_double_err[1],ic_access_fault_f[1],ifu_bp_hist1_f[1],ifu_bp_hist0_f[1],ifu_bp_pc4_f[1],ifu_bp_way_f[1],ifu_bp_valid_f[1],ifu_bp_ret_f[1], + iccm_rd_ecc_double_err[0],ic_access_fault_f[0],ifu_bp_hist1_f[0],ifu_bp_hist0_f[0],ifu_bp_pc4_f[0],ifu_bp_way_f[0],ifu_bp_valid_f[0],ifu_bp_ret_f[0] + }; + assign {f0dbecc[1],f0icaf[1],f0hist1[1],f0hist0[1],f0pc4[1],f0way[1],f0brend[1],f0ret[1], + f0dbecc[0],f0icaf[0],f0hist1[0],f0hist0[0],f0pc4[0],f0way[0],f0brend[0],f0ret[0]} = brdata0final[BRDATA_SIZE-1:0]; + + assign {f1dbecc[1],f1icaf[1],f1hist1[1],f1hist0[1],f1pc4[1],f1way[1],f1brend[1],f1ret[1], + f1dbecc[0],f1icaf[0],f1hist1[0],f1hist0[0],f1pc4[0],f1way[0],f1brend[0],f1ret[0]} = brdata1final[BRDATA_SIZE-1:0]; + + end + + + + + assign {brdata1eff[BRDATA_SIZE-1:0],brdata0eff[BRDATA_SIZE-1:0]} = (({BRDATA_SIZE*2{qren[0]}} & {brdata1[BRDATA_SIZE-1:0],brdata0[BRDATA_SIZE-1:0]}) | + ({BRDATA_SIZE*2{qren[1]}} & {brdata2[BRDATA_SIZE-1:0],brdata1[BRDATA_SIZE-1:0]}) | + ({BRDATA_SIZE*2{qren[2]}} & {brdata0[BRDATA_SIZE-1:0],brdata2[BRDATA_SIZE-1:0]})); + + assign brdata0final[BRDATA_SIZE-1:0] = (({BRDATA_SIZE{q0sel[0]}} & { brdata0eff[2*BRDATA_WIDTH-1:0]}) | + ({BRDATA_SIZE{q0sel[1]}} & {{BRDATA_WIDTH{1'b0}},brdata0eff[BRDATA_SIZE-1:BRDATA_WIDTH]})); + + assign brdata1final[BRDATA_SIZE-1:0] = (({BRDATA_SIZE{q1sel[0]}} & { brdata1eff[2*BRDATA_WIDTH-1:0]}) | + ({BRDATA_SIZE{q1sel[1]}} & {{BRDATA_WIDTH{1'b0}},brdata1eff[BRDATA_SIZE-1:BRDATA_WIDTH]})); + + end // if (pt.BTB_ENABLE==1) + else begin + assign { + f1ictype[1:0] + } = misc1eff[MHI:0]; + + assign { + f0ictype[1:0] + } = misc0eff[MHI:0]; + + assign brdata_in[BRDATA_SIZE-1:0] = { + iccm_rd_ecc_double_err[1],ic_access_fault_f[1], + iccm_rd_ecc_double_err[0],ic_access_fault_f[0] + }; + assign {f0dbecc[1],f0icaf[1], + f0dbecc[0],f0icaf[0]} = brdata0final[BRDATA_SIZE-1:0]; + + assign {f1dbecc[1],f1icaf[1], + f1dbecc[0],f1icaf[0]} = brdata1final[BRDATA_SIZE-1:0]; + + assign {brdata1eff[BRDATA_SIZE-1:0],brdata0eff[BRDATA_SIZE-1:0]} = (({BRDATA_SIZE*2{qren[0]}} & {brdata1[BRDATA_SIZE-1:0],brdata0[BRDATA_SIZE-1:0]}) | + ({BRDATA_SIZE*2{qren[1]}} & {brdata2[BRDATA_SIZE-1:0],brdata1[BRDATA_SIZE-1:0]}) | + ({BRDATA_SIZE*2{qren[2]}} & {brdata0[BRDATA_SIZE-1:0],brdata2[BRDATA_SIZE-1:0]})); + + assign brdata0final[BRDATA_SIZE-1:0] = (({BRDATA_SIZE{q0sel[0]}} & { brdata0eff[2*BRDATA_WIDTH-1:0]}) | + ({BRDATA_SIZE{q0sel[1]}} & {{BRDATA_WIDTH{1'b0}},brdata0eff[BRDATA_SIZE-1:BRDATA_WIDTH]})); + + assign brdata1final[BRDATA_SIZE-1:0] = (({BRDATA_SIZE{q1sel[0]}} & { brdata1eff[2*BRDATA_WIDTH-1:0]}) | + ({BRDATA_SIZE{q1sel[1]}} & {{BRDATA_WIDTH{1'b0}},brdata1eff[BRDATA_SIZE-1:BRDATA_WIDTH]})); + + end // else: !if(pt.BTB_ENABLE==1) + + + // possible states of { sf0_valid, sf1_valid, f2_valid } + // + // 000 if->f0 + // 100 if->f1 + // 101 illegal + // 010 if->f1, f1->f0 + // 110 if->f2 + // 001 if->f1, f2->f0 + // 011 if->f2, f2->f1, f1->f0 + // 111 !if, no shift + + assign f2_valid = f2val[0]; + assign sf1_valid = sf1val[0]; + assign sf0_valid = sf0val[0]; + + // interface to fetch + + assign consume_fb0 = ~sf0val[0] & f0val[0]; + + assign consume_fb1 = ~sf1val[0] & f1val[0]; + + assign ifu_fb_consume1 = consume_fb0 & ~consume_fb1 & ~exu_flush_final; + assign ifu_fb_consume2 = consume_fb0 & consume_fb1 & ~exu_flush_final; + + assign ifvalid = ifu_fetch_val[0]; + + assign shift_f1_f0 = ~sf0_valid & sf1_valid; + assign shift_f2_f0 = ~sf0_valid & ~sf1_valid & f2_valid; + assign shift_f2_f1 = ~sf0_valid & sf1_valid & f2_valid; + + assign fetch_to_f0 = ~sf0_valid & ~sf1_valid & ~f2_valid & ifvalid; + + assign fetch_to_f1 = (~sf0_valid & ~sf1_valid & f2_valid & ifvalid) | + (~sf0_valid & sf1_valid & ~f2_valid & ifvalid) | + ( sf0_valid & ~sf1_valid & ~f2_valid & ifvalid); + + assign fetch_to_f2 = (~sf0_valid & sf1_valid & f2_valid & ifvalid) | + ( sf0_valid & sf1_valid & ~f2_valid & ifvalid); + + + assign f2val_in[1:0] = ({2{ fetch_to_f2 & ~exu_flush_final}} & ifu_fetch_val[1:0]) | + ({2{~fetch_to_f2 & ~shift_f2_f1 & ~shift_f2_f0 & ~exu_flush_final}} & f2val[1:0] ); + + + assign sf1val[1:0] = ({2{ f1_shift_2B}} & {1'b0,f1val[1]}) | + ({2{~f1_shift_2B}} & f1val[1:0] ); + + assign f1val_in[1:0] = ({2{ fetch_to_f1 & ~exu_flush_final}} & ifu_fetch_val[1:0]) | + ({2{ shift_f2_f1 & ~exu_flush_final}} & f2val[1:0] ) | + ({2{~fetch_to_f1 & ~shift_f2_f1 & ~shift_f1_f0 & ~exu_flush_final}} & sf1val[1:0] ); + + + + assign sf0val[1:0] = ({2{ shift_2B }} & {1'b0,f0val[1]}) | + ({2{~shift_2B & ~shift_4B}} & f0val[1:0]); + + assign f0val_in[1:0] = ({2{fetch_to_f0 & ~exu_flush_final}} & ifu_fetch_val[1:0]) | + ({2{ shift_f2_f0 & ~exu_flush_final}} & f2val[1:0] ) | + ({2{ shift_f1_f0 & ~exu_flush_final}} & sf1val[1:0] ) | + ({2{~fetch_to_f0 & ~shift_f2_f0 & ~shift_f1_f0 & ~exu_flush_final}} & sf0val[1:0] ); + + assign {q1eff[31:0],q0eff[31:0]} = (({64{qren[0]}} & {q1[31:0],q0[31:0]}) | + ({64{qren[1]}} & {q2[31:0],q1[31:0]}) | + ({64{qren[2]}} & {q0[31:0],q2[31:0]})); + + assign q0final[31:0] = ({32{q0sel[0]}} & { q0eff[31:0]}) | + ({32{q0sel[1]}} & {16'b0,q0eff[31:16]}); + + assign q1final[15:0] = ({16{q1sel[0]}} & q1eff[15:0] ) | + ({16{q1sel[1]}} & q1eff[31:16]); + logic [31:1] q0pceff, q0pcfinal; + logic [31:1] q1pceff; + + assign {q1pceff[31:1],q0pceff[31:1]} = (({62{qren[0]}} & {q1pc[31:1],q0pc[31:1]}) | + ({62{qren[1]}} & {q2pc[31:1],q1pc[31:1]}) | + ({62{qren[2]}} & {q0pc[31:1],q2pc[31:1]})); + + + assign q0pcfinal[31:1] = ({31{q0sel[0]}} & ( q0pceff[31:1])) | + ({31{q0sel[1]}} & ( q0pceff[31:1] + 31'd1)); + + assign aligndata[31:0] = ({32{ f0val[1] }} & {q0final[31:0]}) | + ({32{~f0val[1] & f0val[0]}} & {q1final[15:0],q0final[15:0]}); + + assign alignval[1:0] = ({ 2{ f0val[1] }} & {2'b11}) | + ({ 2{~f0val[1] & f0val[0]}} & {f1val[0],1'b1}); + + assign alignicaf[1:0] = ({ 2{ f0val[1] }} & f0icaf[1:0] ) | + ({ 2{~f0val[1] & f0val[0]}} & {f1icaf[0],f0icaf[0]}); + + assign aligndbecc[1:0] = ({ 2{ f0val[1] }} & f0dbecc[1:0] ) | + ({ 2{~f0val[1] & f0val[0]}} & {f1dbecc[0],f0dbecc[0]}); + + if (pt.BTB_ENABLE==1) begin + + // for branch prediction + + assign alignbrend[1:0] = ({ 2{ f0val[1] }} & f0brend[1:0] ) | + ({ 2{~f0val[1] & f0val[0]}} & {f1brend[0],f0brend[0]}); + + assign alignpc4[1:0] = ({ 2{ f0val[1] }} & f0pc4[1:0] ) | + ({ 2{~f0val[1] & f0val[0]}} & {f1pc4[0],f0pc4[0]}); + + if(pt.BTB_FULLYA) begin + assign alignindex[0] = f0index[0]; + assign alignindex[1] = f0val[1] ? f0index[1] : f1index[0]; + end + + assign alignret[1:0] = ({ 2{ f0val[1] }} & f0ret[1:0] ) | + ({ 2{~f0val[1] & f0val[0]}} & {f1ret[0],f0ret[0]}); + + assign alignway[1:0] = ({ 2{ f0val[1] }} & f0way[1:0] ) | + ({ 2{~f0val[1] & f0val[0]}} & {f1way[0],f0way[0]}); + + assign alignhist1[1:0] = ({ 2{ f0val[1] }} & f0hist1[1:0] ) | + ({ 2{~f0val[1] & f0val[0]}} & {f1hist1[0],f0hist1[0]}); + + assign alignhist0[1:0] = ({ 2{ f0val[1] }} & f0hist0[1:0] ) | + ({ 2{~f0val[1] & f0val[0]}} & {f1hist0[0],f0hist0[0]}); + + assign secondpc[31:1] = ({31{ f0val[1] }} & (q0pceff[31:1] + 31'd1)) | + // you need the base pc for 2nd one only (4B max, 2B for the 1st and 2B for the 2nd) + ({31{~f0val[1] & f0val[0]}} & q1pceff[31:1] ); + + + assign firstpc[31:1] = q0pcfinal[31:1]; + end // if (pt.BTB_ENABLE==1) + + assign alignfromf1[1] = ~f0val[1] & f0val[0]; + + + assign ifu_i0_pc[31:1] = q0pcfinal[31:1]; + + + assign ifu_i0_pc4 = first4B; + + + assign ifu_i0_cinst[15:0] = aligndata[15:0]; + + assign first4B = (aligndata[1:0] == 2'b11); + assign first2B = ~first4B; + + assign ifu_i0_valid = (first4B & alignval[1]) | + (first2B & alignval[0]); + + // inst access fault on any byte of inst results in access fault for the inst + assign ifu_i0_icaf = (first4B & (|alignicaf[1:0])) | + (first2B & alignicaf[0] ); + + assign ifu_i0_icaf_type[1:0] = (first4B & ~f0val[1] & f0val[0] & ~alignicaf[0] & ~aligndbecc[0]) ? f1ictype[1:0] : f0ictype[1:0]; + + + assign icaf_eff[1:0] = alignicaf[1:0] | aligndbecc[1:0]; + + assign ifu_i0_icaf_second = first4B & ~icaf_eff[0] & icaf_eff[1]; + + assign ifu_i0_dbecc = (first4B & (|aligndbecc[1:0])) | + (first2B & aligndbecc[0] ); + + + assign ifirst[31:0] = aligndata[31:0]; + + + assign ifu_i0_instr[31:0] = ({32{first4B & alignval[1]}} & ifirst[31:0]) | + ({32{first2B & alignval[0]}} & uncompress0[31:0]); + +if(pt.BTB_ENABLE==1) begin : genblock2 + + // if you detect br does not start on instruction boundary + + el2_btb_addr_hash #(.pt(pt)) firsthash (.pc(firstpc [pt.BTB_INDEX3_HI:pt.BTB_INDEX1_LO]), + .hash(firstpc_hash [pt.BTB_ADDR_HI:pt.BTB_ADDR_LO])); + el2_btb_addr_hash #(.pt(pt)) secondhash(.pc(secondpc[pt.BTB_INDEX3_HI:pt.BTB_INDEX1_LO]), + .hash(secondpc_hash[pt.BTB_ADDR_HI:pt.BTB_ADDR_LO])); + + if(pt.BTB_FULLYA) begin + assign firstbrtag_hash = firstpc; + assign secondbrtag_hash = secondpc; + end + else begin + if(pt.BTB_BTAG_FOLD) begin : btbfold + el2_btb_tag_hash_fold #(.pt(pt)) first_brhash (.pc(firstpc [pt.BTB_ADDR_HI+pt.BTB_BTAG_SIZE+pt.BTB_BTAG_SIZE:pt.BTB_ADDR_HI+1]), + .hash(firstbrtag_hash [pt.BTB_BTAG_SIZE-1:0])); + el2_btb_tag_hash_fold #(.pt(pt)) second_brhash(.pc(secondpc[pt.BTB_ADDR_HI+pt.BTB_BTAG_SIZE+pt.BTB_BTAG_SIZE:pt.BTB_ADDR_HI+1]), + .hash(secondbrtag_hash[pt.BTB_BTAG_SIZE-1:0])); + end + else begin : btbfold + el2_btb_tag_hash #(.pt(pt)) first_brhash (.pc(firstpc [pt.BTB_ADDR_HI+pt.BTB_BTAG_SIZE+pt.BTB_BTAG_SIZE+pt.BTB_BTAG_SIZE:pt.BTB_ADDR_HI+1]), + .hash(firstbrtag_hash [pt.BTB_BTAG_SIZE-1:0])); + el2_btb_tag_hash #(.pt(pt)) second_brhash(.pc(secondpc[pt.BTB_ADDR_HI+pt.BTB_BTAG_SIZE+pt.BTB_BTAG_SIZE+pt.BTB_BTAG_SIZE:pt.BTB_ADDR_HI+1]), + .hash(secondbrtag_hash[pt.BTB_BTAG_SIZE-1:0])); + end + end // else: !if(pt.BTB_FULLYA) + + + // start_indexing - you want pc to be based on where the end of branch is prediction + // normal indexing pc based that's incorrect now for pc4 cases it's pc4 + 2 + + always_comb begin + + i0_brp = '0; + + i0_br_start_error = (first4B & alignval[1] & alignbrend[0]); + + i0_brp.valid = (first2B & alignbrend[0]) | + (first4B & alignbrend[1]) | + i0_br_start_error; + + i0_brp_pc4 = (first2B & alignpc4[0]) | + (first4B & alignpc4[1]); + + i0_brp.ret = (first2B & alignret[0]) | + (first4B & alignret[1]); + + i0_brp.way = (first2B | alignbrend[0]) ? alignway[0] : alignway[1]; + + i0_brp.hist[1] = (first2B & alignhist1[0]) | + (first4B & alignhist1[1]); + + i0_brp.hist[0] = (first2B & alignhist0[0]) | + (first4B & alignhist0[1]); + + i0_ends_f1 = first4B & alignfromf1[1]; + + i0_brp.toffset[11:0] = (i0_ends_f1) ? f1poffset[11:0] : f0poffset[11:0]; + + i0_brp.prett[31:1] = (i0_ends_f1) ? f1prett[31:1] : f0prett[31:1]; + + i0_brp.br_start_error = i0_br_start_error; + + i0_brp.bank = (first2B | alignbrend[0]) ? firstpc[1] : secondpc[1]; + + i0_brp.br_error = (i0_brp.valid & i0_brp_pc4 & first2B) | + (i0_brp.valid & ~i0_brp_pc4 & first4B); + + if(pt.BTB_FULLYA) + ifu_i0_fa_index = (first2B | alignbrend[0]) ? alignindex[0] : alignindex[1]; + else + ifu_i0_fa_index = '0; + + end + + + assign ifu_i0_bp_index[pt.BTB_ADDR_HI:pt.BTB_ADDR_LO] = (first2B | alignbrend[0]) ? firstpc_hash[pt.BTB_ADDR_HI:pt.BTB_ADDR_LO] : + secondpc_hash[pt.BTB_ADDR_HI:pt.BTB_ADDR_LO]; + + assign ifu_i0_bp_fghr[pt.BHT_GHR_SIZE-1:0] = (i0_ends_f1) ? f1fghr[pt.BHT_GHR_SIZE-1:0] : + f0fghr[pt.BHT_GHR_SIZE-1:0]; + + assign ifu_i0_bp_btag[pt.BTB_BTAG_SIZE-1:0] = (first2B | alignbrend[0]) ? firstbrtag_hash[pt.BTB_BTAG_SIZE-1:0] : + secondbrtag_hash[pt.BTB_BTAG_SIZE-1:0]; +end +else begin + assign i0_brp = '0; + assign ifu_i0_bp_index = '0; + assign ifu_i0_bp_fghr = '0; + assign ifu_i0_bp_btag = '0; +end // else: !if(pt.BTB_ENABLE==1) + + // decompress + + // quiet inputs for 4B inst + el2_ifu_compress_ctl compress0 (.din((first2B) ? aligndata[15:0] : '0), .dout(uncompress0[31:0])); + + + + assign i0_shift = dec_i0_decode_d & ~error_stall; + + assign ifu_pmu_instr_aligned = i0_shift; + + + // compute how many bytes are being shifted from f0 + + assign shift_2B = i0_shift & first2B; + + assign shift_4B = i0_shift & first4B; + + // exact equations for the queue logic + assign f0_shift_2B = (shift_2B & f0val[0] ) | + (shift_4B & f0val[0] & ~f0val[1]); + + + // f0 valid states + // 11 + // 10 + // 00 + + assign f1_shift_2B = f0val[0] & ~f0val[1] & shift_4B; + + + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/el2_ifu_bp_ctl.sv b/designs/Caliptra/src/caliptra-rtl/el2_ifu_bp_ctl.sv new file mode 100644 index 0000000..d43b377 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/el2_ifu_bp_ctl.sv @@ -0,0 +1,903 @@ +//******************************************************************************** +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2020 Western Digital Corporation or its affiliates. +// +// 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. +//******************************************************************************** + +//******************************************************************************** +// Function: Branch predictor +// Comments: +// +// +// Bank3 : Bank2 : Bank1 : Bank0 +// FA C 8 4 0 +//******************************************************************************** + +module el2_ifu_bp_ctl +import el2_pkg::*; +#( +`include "el2_param.vh" + ) + ( + + input logic clk, + input logic rst_l, + + input logic ic_hit_f, // Icache hit, enables F address capture + + input logic [31:1] ifc_fetch_addr_f, // look up btb address + input logic ifc_fetch_req_f, // F1 valid + + input el2_br_tlu_pkt_t dec_tlu_br0_r_pkt, // BP commit update packet, includes errors + input logic [pt.BHT_GHR_SIZE-1:0] exu_i0_br_fghr_r, // fghr to bp + input logic [pt.BTB_ADDR_HI:pt.BTB_ADDR_LO] exu_i0_br_index_r, // bp index + + input logic [$clog2(pt.BTB_SIZE)-1:0] dec_fa_error_index, // Fully associative btb error index + + input logic dec_tlu_flush_lower_wb, // used to move EX4 RS to EX1 and F + input logic dec_tlu_flush_leak_one_wb, // don't hit for leak one fetches + + input logic dec_tlu_bpred_disable, // disable all branch prediction + + input el2_predict_pkt_t exu_mp_pkt, // mispredict packet + + input logic [pt.BHT_GHR_SIZE-1:0] exu_mp_eghr, // execute ghr (for patching fghr) + input logic [pt.BHT_GHR_SIZE-1:0] exu_mp_fghr, // Mispredict fghr + input logic [pt.BTB_ADDR_HI:pt.BTB_ADDR_LO] exu_mp_index, // Mispredict index + input logic [pt.BTB_BTAG_SIZE-1:0] exu_mp_btag, // Mispredict btag + + input logic exu_flush_final, // all flushes + + output logic ifu_bp_hit_taken_f, // btb hit, select target + output logic [31:1] ifu_bp_btb_target_f, // predicted target PC + output logic ifu_bp_inst_mask_f, // tell ic which valids to kill because of a taken branch, right justified + + output logic [pt.BHT_GHR_SIZE-1:0] ifu_bp_fghr_f, // fetch ghr + + output logic [1:0] ifu_bp_way_f, // way + output logic [1:0] ifu_bp_ret_f, // predicted ret + output logic [1:0] ifu_bp_hist1_f, // history counters for all 4 potential branches, bit 1, right justified + output logic [1:0] ifu_bp_hist0_f, // history counters for all 4 potential branches, bit 0, right justified + output logic [1:0] ifu_bp_pc4_f, // pc4 indication, right justified + output logic [1:0] ifu_bp_valid_f, // branch valid, right justified + output logic [11:0] ifu_bp_poffset_f, // predicted target + + output logic [1:0] [$clog2(pt.BTB_SIZE)-1:0] ifu_bp_fa_index_f, // predicted branch index (fully associative option) + + // Excluding scan_mode from coverage as its usage is determined by the integrator of the VeeR core. + /*pragma coverage off*/ + input logic scan_mode + /*pragma coverage on*/ + ); + + + localparam BTB_DWIDTH = pt.BTB_TOFFSET_SIZE+pt.BTB_BTAG_SIZE+5; + localparam BTB_DWIDTH_TOP = int'(pt.BTB_TOFFSET_SIZE)+int'(pt.BTB_BTAG_SIZE)+4; + localparam BTB_FA_INDEX = $clog2(pt.BTB_SIZE)-1; + localparam FA_CMP_LOWER = $clog2(pt.ICACHE_LN_SZ); + localparam FA_TAG_END_UPPER= 5+int'(pt.BTB_TOFFSET_SIZE)+int'(FA_CMP_LOWER)-1; // must cast to int or vcs build fails + localparam FA_TAG_START_LOWER = 3+int'(pt.BTB_TOFFSET_SIZE)+int'(FA_CMP_LOWER); + localparam FA_TAG_END_LOWER = 5+int'(pt.BTB_TOFFSET_SIZE); + + localparam TAG_START=BTB_DWIDTH-1; + localparam PC4=4; + localparam BOFF=3; + localparam CALL=2; + localparam RET=1; + localparam BV=0; + + localparam LRU_SIZE=pt.BTB_ARRAY_DEPTH; + localparam NUM_BHT_LOOP = (pt.BHT_ARRAY_DEPTH > 16 ) ? 16 : pt.BHT_ARRAY_DEPTH; + localparam NUM_BHT_LOOP_INNER_HI = (pt.BHT_ARRAY_DEPTH > 16 ) ?pt.BHT_ADDR_LO+3 : pt.BHT_ADDR_HI; + localparam NUM_BHT_LOOP_OUTER_LO = (pt.BHT_ARRAY_DEPTH > 16 ) ?pt.BHT_ADDR_LO+4 : pt.BHT_ADDR_LO; + localparam BHT_NO_ADDR_MATCH = ( pt.BHT_ARRAY_DEPTH <= 16 ); + + + logic exu_mp_valid_write; + logic exu_mp_ataken; + logic exu_mp_valid; // conditional branch mispredict + logic exu_mp_boffset; // branch offsett + logic exu_mp_pc4; // branch is a 4B inst + logic exu_mp_call; // branch is a call inst + logic exu_mp_ret; // branch is a ret inst + logic exu_mp_ja; // branch is a jump always + logic [1:0] exu_mp_hist; // new history + logic [11:0] exu_mp_tgt; // target offset + logic [pt.BTB_ADDR_HI:pt.BTB_ADDR_LO] exu_mp_addr; // BTB/BHT address + logic dec_tlu_br0_v_wb; // WB stage history update + logic [1:0] dec_tlu_br0_hist_wb; // new history + logic [pt.BTB_ADDR_HI:pt.BTB_ADDR_LO] dec_tlu_br0_addr_wb; // addr + logic dec_tlu_br0_error_wb; // error; invalidate bank + logic dec_tlu_br0_start_error_wb; // error; invalidate all 4 banks in fg + logic [pt.BHT_GHR_SIZE-1:0] exu_i0_br_fghr_wb; + + logic use_mp_way, use_mp_way_p1; + logic [pt.RET_STACK_SIZE-1:0][31:0] rets_out, rets_in; + logic [pt.RET_STACK_SIZE-1:0] rsenable; + + + logic [11:0] btb_rd_tgt_f; + logic btb_rd_pc4_f, btb_rd_call_f, btb_rd_ret_f; + logic [1:1] bp_total_branch_offset_f; + + logic [31:1] bp_btb_target_adder_f; + logic [31:1] bp_rs_call_target_f; + logic rs_push, rs_pop, rs_hold; + logic [pt.BTB_ADDR_HI:pt.BTB_ADDR_LO] btb_rd_addr_p1_f, btb_wr_addr, btb_rd_addr_f; + logic [pt.BTB_BTAG_SIZE-1:0] btb_wr_tag, fetch_rd_tag_f, fetch_rd_tag_p1_f; + logic [BTB_DWIDTH-1:0] btb_wr_data; + logic btb_wr_en_way0, btb_wr_en_way1; + + + logic dec_tlu_error_wb, btb_valid, dec_tlu_br0_middle_wb; + logic [pt.BTB_ADDR_HI:pt.BTB_ADDR_LO] btb_error_addr_wb; + logic branch_error_collision_f, fetch_mp_collision_f, branch_error_collision_p1_f, fetch_mp_collision_p1_f; + + logic branch_error_bank_conflict_f; + logic [pt.BHT_GHR_SIZE-1:0] merged_ghr, fghr_ns, fghr; + logic [1:0] num_valids; + logic [LRU_SIZE-1:0] btb_lru_b0_f, btb_lru_b0_hold, btb_lru_b0_ns, + fetch_wrindex_dec, fetch_wrindex_p1_dec, fetch_wrlru_b0, fetch_wrlru_p1_b0, + mp_wrindex_dec, mp_wrlru_b0; + logic btb_lru_rd_f, btb_lru_rd_p1_f, lru_update_valid_f; + logic tag_match_way0_f, tag_match_way1_f; + logic [1:0] way_raw, bht_dir_f, btb_sel_f, wayhit_f, vwayhit_f, wayhit_p1_f; + logic [1:0] bht_valid_f, bht_force_taken_f; + + logic leak_one_f, leak_one_f_d1; + + logic [LRU_SIZE-1:0][BTB_DWIDTH-1:0] btb_bank0_rd_data_way0_out ; + + logic [LRU_SIZE-1:0][BTB_DWIDTH-1:0] btb_bank0_rd_data_way1_out ; + + logic [BTB_DWIDTH-1:0] btb_bank0_rd_data_way0_f ; + logic [BTB_DWIDTH-1:0] btb_bank0_rd_data_way1_f ; + + logic [BTB_DWIDTH-1:0] btb_bank0_rd_data_way0_p1_f ; + logic [BTB_DWIDTH-1:0] btb_bank0_rd_data_way1_p1_f ; + + logic [BTB_DWIDTH-1:0] btb_vbank0_rd_data_f, btb_vbank1_rd_data_f; + + logic final_h; + logic btb_fg_crossing_f; + logic middle_of_bank; + + + logic [1:0] bht_vbank0_rd_data_f, bht_vbank1_rd_data_f; + logic branch_error_bank_conflict_p1_f; + logic tag_match_way0_p1_f, tag_match_way1_p1_f; + + logic [1:0] btb_vlru_rd_f, fetch_start_f, tag_match_vway1_expanded_f, tag_match_way0_expanded_p1_f, tag_match_way1_expanded_p1_f; + logic [31:2] fetch_addr_p1_f; + + + logic exu_mp_way, exu_mp_way_f, dec_tlu_br0_way_wb, dec_tlu_way_wb; + logic [BTB_DWIDTH-1:0] btb_bank0e_rd_data_f, btb_bank0e_rd_data_p1_f; + + logic [BTB_DWIDTH-1:0] btb_bank0o_rd_data_f; + + logic [1:0] tag_match_way0_expanded_f, tag_match_way1_expanded_f; + + + logic [1:0] bht_bank0_rd_data_f; + logic [1:0] bht_bank1_rd_data_f; + logic [1:0] bht_bank0_rd_data_p1_f; + genvar j, i; + + assign exu_mp_valid = exu_mp_pkt.misp & ~leak_one_f; // conditional branch mispredict + assign exu_mp_boffset = exu_mp_pkt.boffset; // branch offset + assign exu_mp_pc4 = exu_mp_pkt.pc4; // branch is a 4B inst + assign exu_mp_call = exu_mp_pkt.pcall; // branch is a call inst + assign exu_mp_ret = exu_mp_pkt.pret; // branch is a ret inst + assign exu_mp_ja = exu_mp_pkt.pja; // branch is a jump always + assign exu_mp_way = exu_mp_pkt.way; // repl way + assign exu_mp_hist[1:0] = exu_mp_pkt.hist[1:0]; // new history + assign exu_mp_tgt[11:0] = exu_mp_pkt.toffset[11:0] ; // target offset + assign exu_mp_addr[pt.BTB_ADDR_HI:pt.BTB_ADDR_LO] = exu_mp_index[pt.BTB_ADDR_HI:pt.BTB_ADDR_LO] ; // BTB/BHT address + assign exu_mp_ataken = exu_mp_pkt.ataken; + + + assign dec_tlu_br0_v_wb = dec_tlu_br0_r_pkt.valid; + assign dec_tlu_br0_hist_wb[1:0] = dec_tlu_br0_r_pkt.hist[1:0]; + assign dec_tlu_br0_addr_wb[pt.BTB_ADDR_HI:pt.BTB_ADDR_LO] = exu_i0_br_index_r[pt.BTB_ADDR_HI:pt.BTB_ADDR_LO]; + assign dec_tlu_br0_error_wb = dec_tlu_br0_r_pkt.br_error; + assign dec_tlu_br0_middle_wb = dec_tlu_br0_r_pkt.middle; + assign dec_tlu_br0_way_wb = dec_tlu_br0_r_pkt.way; + assign dec_tlu_br0_start_error_wb = dec_tlu_br0_r_pkt.br_start_error; + assign exu_i0_br_fghr_wb[pt.BHT_GHR_SIZE-1:0] = exu_i0_br_fghr_r[pt.BHT_GHR_SIZE-1:0]; + + + + + // ---------------------------------------------------------------------- + // READ + // ---------------------------------------------------------------------- + + // hash the incoming fetch PC, first guess at hashing algorithm + el2_btb_addr_hash #(.pt(pt)) f1hash(.pc(ifc_fetch_addr_f[pt.BTB_INDEX3_HI:pt.BTB_INDEX1_LO]), .hash(btb_rd_addr_f[pt.BTB_ADDR_HI:pt.BTB_ADDR_LO])); + + + assign fetch_addr_p1_f[31:2] = ifc_fetch_addr_f[31:2] + 30'b1; + el2_btb_addr_hash #(.pt(pt)) f1hash_p1(.pc(fetch_addr_p1_f[pt.BTB_INDEX3_HI:pt.BTB_INDEX1_LO]), .hash(btb_rd_addr_p1_f[pt.BTB_ADDR_HI:pt.BTB_ADDR_LO])); + + assign btb_sel_f[1] = ~bht_dir_f[0]; + assign btb_sel_f[0] = bht_dir_f[0]; + + assign fetch_start_f[1:0] = {ifc_fetch_addr_f[1], ~ifc_fetch_addr_f[1]}; + + // Errors colliding with fetches must kill the btb/bht hit. + + assign branch_error_collision_f = dec_tlu_error_wb & (btb_error_addr_wb[pt.BTB_ADDR_HI:pt.BTB_ADDR_LO] == btb_rd_addr_f[pt.BTB_ADDR_HI:pt.BTB_ADDR_LO]); + assign branch_error_collision_p1_f = dec_tlu_error_wb & (btb_error_addr_wb[pt.BTB_ADDR_HI:pt.BTB_ADDR_LO] == btb_rd_addr_p1_f[pt.BTB_ADDR_HI:pt.BTB_ADDR_LO]); + + assign branch_error_bank_conflict_f = branch_error_collision_f & dec_tlu_error_wb; + assign branch_error_bank_conflict_p1_f = branch_error_collision_p1_f & dec_tlu_error_wb; + + // set on leak one, hold until next flush without leak one + assign leak_one_f = (dec_tlu_flush_leak_one_wb & dec_tlu_flush_lower_wb) | (leak_one_f_d1 & ~dec_tlu_flush_lower_wb); + +logic exu_flush_final_d1; + + if(!pt.BTB_FULLYA) begin : genblock1 + assign fetch_mp_collision_f = ( (exu_mp_btag[pt.BTB_BTAG_SIZE-1:0] == fetch_rd_tag_f[pt.BTB_BTAG_SIZE-1:0]) & + exu_mp_valid & ifc_fetch_req_f & + (exu_mp_addr[pt.BTB_ADDR_HI:pt.BTB_ADDR_LO] == btb_rd_addr_f[pt.BTB_ADDR_HI:pt.BTB_ADDR_LO]) + ); + assign fetch_mp_collision_p1_f = ( (exu_mp_btag[pt.BTB_BTAG_SIZE-1:0] == fetch_rd_tag_p1_f[pt.BTB_BTAG_SIZE-1:0]) & + exu_mp_valid & ifc_fetch_req_f & + (exu_mp_addr[pt.BTB_ADDR_HI:pt.BTB_ADDR_LO] == btb_rd_addr_p1_f[pt.BTB_ADDR_HI:pt.BTB_ADDR_LO]) + ); + // 2 -way SA, figure out the way hit and mux accordingly + assign tag_match_way0_f = btb_bank0_rd_data_way0_f[BV] & (btb_bank0_rd_data_way0_f[TAG_START:17] == fetch_rd_tag_f[pt.BTB_BTAG_SIZE-1:0]) & + ~(dec_tlu_way_wb & branch_error_bank_conflict_f) & ifc_fetch_req_f & ~leak_one_f; + + assign tag_match_way1_f = btb_bank0_rd_data_way1_f[BV] & (btb_bank0_rd_data_way1_f[TAG_START:17] == fetch_rd_tag_f[pt.BTB_BTAG_SIZE-1:0]) & + ~(dec_tlu_way_wb & branch_error_bank_conflict_f) & ifc_fetch_req_f & ~leak_one_f; + + assign tag_match_way0_p1_f = btb_bank0_rd_data_way0_p1_f[BV] & (btb_bank0_rd_data_way0_p1_f[TAG_START:17] == fetch_rd_tag_p1_f[pt.BTB_BTAG_SIZE-1:0]) & + ~(dec_tlu_way_wb & branch_error_bank_conflict_p1_f) & ifc_fetch_req_f & ~leak_one_f; + + assign tag_match_way1_p1_f = btb_bank0_rd_data_way1_p1_f[BV] & (btb_bank0_rd_data_way1_p1_f[TAG_START:17] == fetch_rd_tag_p1_f[pt.BTB_BTAG_SIZE-1:0]) & + ~(dec_tlu_way_wb & branch_error_bank_conflict_p1_f) & ifc_fetch_req_f & ~leak_one_f; + + + // Both ways could hit, use the offset bit to reorder + + assign tag_match_way0_expanded_f[1:0] = {tag_match_way0_f & (btb_bank0_rd_data_way0_f[BOFF] ^ btb_bank0_rd_data_way0_f[PC4]), + tag_match_way0_f & ~(btb_bank0_rd_data_way0_f[BOFF] ^ btb_bank0_rd_data_way0_f[PC4])}; + + assign tag_match_way1_expanded_f[1:0] = {tag_match_way1_f & (btb_bank0_rd_data_way1_f[BOFF] ^ btb_bank0_rd_data_way1_f[PC4]), + tag_match_way1_f & ~(btb_bank0_rd_data_way1_f[BOFF] ^ btb_bank0_rd_data_way1_f[PC4])}; + + assign tag_match_way0_expanded_p1_f[1:0] = {tag_match_way0_p1_f & (btb_bank0_rd_data_way0_p1_f[BOFF] ^ btb_bank0_rd_data_way0_p1_f[PC4]), + tag_match_way0_p1_f & ~(btb_bank0_rd_data_way0_p1_f[BOFF] ^ btb_bank0_rd_data_way0_p1_f[PC4])}; + + assign tag_match_way1_expanded_p1_f[1:0] = {tag_match_way1_p1_f & (btb_bank0_rd_data_way1_p1_f[BOFF] ^ btb_bank0_rd_data_way1_p1_f[PC4]), + tag_match_way1_p1_f & ~(btb_bank0_rd_data_way1_p1_f[BOFF] ^ btb_bank0_rd_data_way1_p1_f[PC4])}; + + assign wayhit_f[1:0] = tag_match_way0_expanded_f[1:0] | tag_match_way1_expanded_f[1:0]; + assign wayhit_p1_f[1:0] = tag_match_way0_expanded_p1_f[1:0] | tag_match_way1_expanded_p1_f[1:0]; + + assign btb_bank0o_rd_data_f[BTB_DWIDTH-1:0] = ( ({17+pt.BTB_BTAG_SIZE{tag_match_way0_expanded_f[1]}} & btb_bank0_rd_data_way0_f[BTB_DWIDTH-1:0]) | + ({17+pt.BTB_BTAG_SIZE{tag_match_way1_expanded_f[1]}} & btb_bank0_rd_data_way1_f[BTB_DWIDTH-1:0]) ); + assign btb_bank0e_rd_data_f[BTB_DWIDTH-1:0] = ( ({17+pt.BTB_BTAG_SIZE{tag_match_way0_expanded_f[0]}} & btb_bank0_rd_data_way0_f[BTB_DWIDTH-1:0]) | + ({17+pt.BTB_BTAG_SIZE{tag_match_way1_expanded_f[0]}} & btb_bank0_rd_data_way1_f[BTB_DWIDTH-1:0]) ); + + assign btb_bank0e_rd_data_p1_f[BTB_DWIDTH-1:0] = ( ({17+pt.BTB_BTAG_SIZE{tag_match_way0_expanded_p1_f[0]}} & btb_bank0_rd_data_way0_p1_f[BTB_DWIDTH-1:0]) | + ({17+pt.BTB_BTAG_SIZE{tag_match_way1_expanded_p1_f[0]}} & btb_bank0_rd_data_way1_p1_f[BTB_DWIDTH-1:0]) ); + + // virtual bank order + + assign btb_vbank0_rd_data_f[BTB_DWIDTH-1:0] = ( ({17+pt.BTB_BTAG_SIZE{fetch_start_f[0]}} & btb_bank0e_rd_data_f[BTB_DWIDTH-1:0]) | + ({17+pt.BTB_BTAG_SIZE{fetch_start_f[1]}} & btb_bank0o_rd_data_f[BTB_DWIDTH-1:0]) ); + assign btb_vbank1_rd_data_f[BTB_DWIDTH-1:0] = ( ({17+pt.BTB_BTAG_SIZE{fetch_start_f[0]}} & btb_bank0o_rd_data_f[BTB_DWIDTH-1:0]) | + ({17+pt.BTB_BTAG_SIZE{fetch_start_f[1]}} & btb_bank0e_rd_data_p1_f[BTB_DWIDTH-1:0]) ); + + assign way_raw[1:0] = tag_match_vway1_expanded_f[1:0] | (~vwayhit_f[1:0] & btb_vlru_rd_f[1:0]); + + // -------------------------------------------------------------------------------- + // -------------------------------------------------------------------------------- + // update lru + // mp + + // create a onehot lru write vector + assign mp_wrindex_dec[LRU_SIZE-1:0] = {{LRU_SIZE-1{1'b0}},1'b1} << exu_mp_addr[pt.BTB_ADDR_HI:pt.BTB_ADDR_LO]; + + // fetch + assign fetch_wrindex_dec[LRU_SIZE-1:0] = {{LRU_SIZE-1{1'b0}},1'b1} << btb_rd_addr_f[pt.BTB_ADDR_HI:pt.BTB_ADDR_LO]; + assign fetch_wrindex_p1_dec[LRU_SIZE-1:0] = {{LRU_SIZE-1{1'b0}},1'b1} << btb_rd_addr_p1_f[pt.BTB_ADDR_HI:pt.BTB_ADDR_LO]; + + assign mp_wrlru_b0[LRU_SIZE-1:0] = mp_wrindex_dec[LRU_SIZE-1:0] & {LRU_SIZE{exu_mp_valid}}; + + + assign btb_lru_b0_hold[LRU_SIZE-1:0] = ~mp_wrlru_b0[LRU_SIZE-1:0] & ~fetch_wrlru_b0[LRU_SIZE-1:0]; + + // Forward the mp lru information to the fetch, avoids multiple way hits later + assign use_mp_way = fetch_mp_collision_f; + assign use_mp_way_p1 = fetch_mp_collision_p1_f; + + assign lru_update_valid_f = (vwayhit_f[0] | vwayhit_f[1]) & ifc_fetch_req_f & ~leak_one_f; + + + assign fetch_wrlru_b0[LRU_SIZE-1:0] = fetch_wrindex_dec[LRU_SIZE-1:0] & + {LRU_SIZE{lru_update_valid_f}}; + assign fetch_wrlru_p1_b0[LRU_SIZE-1:0] = fetch_wrindex_p1_dec[LRU_SIZE-1:0] & + {LRU_SIZE{lru_update_valid_f}}; + + assign btb_lru_b0_ns[LRU_SIZE-1:0] = ( (btb_lru_b0_hold[LRU_SIZE-1:0] & btb_lru_b0_f[LRU_SIZE-1:0]) | + (mp_wrlru_b0[LRU_SIZE-1:0] & {LRU_SIZE{~exu_mp_way}}) | + (fetch_wrlru_b0[LRU_SIZE-1:0] & {LRU_SIZE{tag_match_way0_f}}) | + (fetch_wrlru_p1_b0[LRU_SIZE-1:0] & {LRU_SIZE{tag_match_way0_p1_f}}) ); + + + + assign btb_lru_rd_f = use_mp_way ? exu_mp_way_f : |(fetch_wrindex_dec[LRU_SIZE-1:0] & btb_lru_b0_f[LRU_SIZE-1:0]); + + assign btb_lru_rd_p1_f = use_mp_way_p1 ? exu_mp_way_f : |(fetch_wrindex_p1_dec[LRU_SIZE-1:0] & btb_lru_b0_f[LRU_SIZE-1:0]); + + // rotated + assign btb_vlru_rd_f[1:0] = ( ({2{fetch_start_f[0]}} & {btb_lru_rd_f, btb_lru_rd_f}) | + ({2{fetch_start_f[1]}} & {btb_lru_rd_p1_f, btb_lru_rd_f})); + + assign tag_match_vway1_expanded_f[1:0] = ( ({2{fetch_start_f[0]}} & {tag_match_way1_expanded_f[1:0]}) | + ({2{fetch_start_f[1]}} & {tag_match_way1_expanded_p1_f[0], tag_match_way1_expanded_f[1]}) ); + + + rvdffe #(LRU_SIZE) btb_lru_ff (.*, .en(ifc_fetch_req_f | exu_mp_valid), + .din(btb_lru_b0_ns[(LRU_SIZE)-1:0]), + .dout(btb_lru_b0_f[(LRU_SIZE)-1:0])); + + end // if (!pt.BTB_FULLYA) + // Detect end of cache line and mask as needed + logic eoc_near; + logic eoc_mask; + assign eoc_near = &ifc_fetch_addr_f[pt.ICACHE_BEAT_ADDR_HI:3]; + assign eoc_mask = ~eoc_near| (|(~ifc_fetch_addr_f[2:1])); + + + + // -------------------------------------------------------------------------------- + // -------------------------------------------------------------------------------- + + // mux out critical hit bank for pc computation + // This is only useful for the first taken branch in the fetch group + logic [16:1] btb_sel_data_f; + + assign btb_rd_tgt_f[11:0] = btb_sel_data_f[16:5]; + assign btb_rd_pc4_f = btb_sel_data_f[4]; + assign btb_rd_call_f = btb_sel_data_f[2]; + assign btb_rd_ret_f = btb_sel_data_f[1]; + + assign btb_sel_data_f[16:1] = ( ({16{btb_sel_f[1]}} & btb_vbank1_rd_data_f[16:1]) | + ({16{btb_sel_f[0]}} & btb_vbank0_rd_data_f[16:1]) ); + + + logic [1:0] hist0_raw, hist1_raw, pc4_raw, pret_raw; + + // a valid taken target needs to kill the next fetch as we compute the target address + assign ifu_bp_hit_taken_f = |(vwayhit_f[1:0] & hist1_raw[1:0]) & ifc_fetch_req_f & ~leak_one_f_d1 & ~dec_tlu_bpred_disable; + + + // Don't put calls/rets/ja in the predictor, force the bht taken instead + assign bht_force_taken_f[1:0] = {(btb_vbank1_rd_data_f[CALL] | btb_vbank1_rd_data_f[RET]), + (btb_vbank0_rd_data_f[CALL] | btb_vbank0_rd_data_f[RET])}; + + + // taken and valid, otherwise, branch errors must clear the bht + assign bht_valid_f[1:0] = vwayhit_f[1:0]; + + assign bht_vbank0_rd_data_f[1:0] = ( ({2{fetch_start_f[0]}} & bht_bank0_rd_data_f[1:0]) | + ({2{fetch_start_f[1]}} & bht_bank1_rd_data_f[1:0]) ); + + assign bht_vbank1_rd_data_f[1:0] = ( ({2{fetch_start_f[0]}} & bht_bank1_rd_data_f[1:0]) | + ({2{fetch_start_f[1]}} & bht_bank0_rd_data_p1_f[1:0]) ); + + + assign bht_dir_f[1:0] = {(bht_force_taken_f[1] | bht_vbank1_rd_data_f[1]) & bht_valid_f[1], + (bht_force_taken_f[0] | bht_vbank0_rd_data_f[1]) & bht_valid_f[0]}; + + assign ifu_bp_inst_mask_f = (ifu_bp_hit_taken_f & btb_sel_f[1]) | ~ifu_bp_hit_taken_f; + + + + + // Branch prediction info is sent with the 2byte lane associated with the end of the branch. + // Cases + // BANK1 BANK0 + // ------------------------------- + // | : | : | + // ------------------------------- + // <------------> : PC4 branch, offset, should be in B1 (indicated on [2]) + // <------------> : PC4 branch, no offset, indicate PC4, VALID, HIST on [1] + // <------------> : PC4 branch, offset, indicate PC4, VALID, HIST on [0] + // <------> : PC2 branch, offset, indicate VALID, HIST on [1] + // <------> : PC2 branch, no offset, indicate VALID, HIST on [0] + // + + + + assign hist1_raw[1:0] = bht_force_taken_f[1:0] | {bht_vbank1_rd_data_f[1], + bht_vbank0_rd_data_f[1]}; + + assign hist0_raw[1:0] = {bht_vbank1_rd_data_f[0], + bht_vbank0_rd_data_f[0]}; + + + assign pc4_raw[1:0] = {vwayhit_f[1] & btb_vbank1_rd_data_f[PC4], + vwayhit_f[0] & btb_vbank0_rd_data_f[PC4]}; + + assign pret_raw[1:0] = {vwayhit_f[1] & ~btb_vbank1_rd_data_f[CALL] & btb_vbank1_rd_data_f[RET], + vwayhit_f[0] & ~btb_vbank0_rd_data_f[CALL] & btb_vbank0_rd_data_f[RET]}; + + // GHR + + + // count the valids with masking based on first taken + assign num_valids[1:0] = countones(bht_valid_f[1:0]); + + // Note that the following property holds + // P: prior ghr, H: history bit of last valid branch in line (could be 1 or 0) + // Num valid branches What new GHR must be + // 2 0H + // 1 PH + // 0 PP + + assign final_h = |(btb_sel_f[1:0] & bht_dir_f[1:0]); + + assign merged_ghr[pt.BHT_GHR_SIZE-1:0] = ( + ({pt.BHT_GHR_SIZE{num_valids[1:0] == 2'h2}} & {fghr[pt.BHT_GHR_SIZE-3:0], 1'b0, final_h}) | // 0H + ({pt.BHT_GHR_SIZE{num_valids[1:0] == 2'h1}} & {fghr[pt.BHT_GHR_SIZE-2:0], final_h}) | // PH + ({pt.BHT_GHR_SIZE{num_valids[1:0] == 2'h0}} & {fghr[pt.BHT_GHR_SIZE-1:0]}) ); // PP + + logic [pt.BHT_GHR_SIZE-1:0] exu_flush_ghr; + assign exu_flush_ghr[pt.BHT_GHR_SIZE-1:0] = exu_mp_fghr[pt.BHT_GHR_SIZE-1:0]; + + assign fghr_ns[pt.BHT_GHR_SIZE-1:0] = ( ({pt.BHT_GHR_SIZE{exu_flush_final_d1}} & exu_flush_ghr[pt.BHT_GHR_SIZE-1:0]) | + ({pt.BHT_GHR_SIZE{~exu_flush_final_d1 & ifc_fetch_req_f & ic_hit_f & ~leak_one_f_d1}} & merged_ghr[pt.BHT_GHR_SIZE-1:0]) | + ({pt.BHT_GHR_SIZE{~exu_flush_final_d1 & ~(ifc_fetch_req_f & ic_hit_f & ~leak_one_f_d1)}} & fghr[pt.BHT_GHR_SIZE-1:0])); + + rvdffie #(.WIDTH(pt.BHT_GHR_SIZE+3),.OVERRIDE(1)) fetchghr (.*, + .din ({exu_flush_final, exu_mp_way, leak_one_f, fghr_ns[pt.BHT_GHR_SIZE-1:0]}), + .dout({exu_flush_final_d1, exu_mp_way_f, leak_one_f_d1, fghr[pt.BHT_GHR_SIZE-1:0]})); + + assign ifu_bp_fghr_f[pt.BHT_GHR_SIZE-1:0] = fghr[pt.BHT_GHR_SIZE-1:0]; + + + assign ifu_bp_way_f[1:0] = way_raw[1:0]; + assign ifu_bp_hist1_f[1:0] = hist1_raw[1:0]; + assign ifu_bp_hist0_f[1:0] = hist0_raw[1:0]; + assign ifu_bp_pc4_f[1:0] = pc4_raw[1:0]; + + assign ifu_bp_valid_f[1:0] = vwayhit_f[1:0] & ~{2{dec_tlu_bpred_disable}}; + assign ifu_bp_ret_f[1:0] = pret_raw[1:0]; + + + // compute target + // Form the fetch group offset based on the btb hit location and the location of the branch within the 4 byte chunk + +// .i 5 +// .o 3 +// .ilb bht_dir_f[1] bht_dir_f[0] fetch_start_f[1] fetch_start_f[0] btb_rd_pc4_f +// .ob bloc_f[1] bloc_f[0] use_fa_plus +// .type fr +// +// +// ## rotdir[1:0] fs pc4 off fapl +// -1 01 - 01 0 +// 10 01 - 10 0 +// +// -1 10 - 10 0 +// 10 10 0 01 1 +// 10 10 1 01 0 +logic [1:0] bloc_f; +logic use_fa_plus; +assign bloc_f[1] = (bht_dir_f[0] & ~fetch_start_f[0]) | (~bht_dir_f[0] + & fetch_start_f[0]); +assign bloc_f[0] = (bht_dir_f[0] & fetch_start_f[0]) | (~bht_dir_f[0] + & ~fetch_start_f[0]); +assign use_fa_plus = (~bht_dir_f[0] & ~fetch_start_f[0] & ~btb_rd_pc4_f); + + + + + assign btb_fg_crossing_f = fetch_start_f[0] & btb_sel_f[0] & btb_rd_pc4_f; + + assign bp_total_branch_offset_f = bloc_f[1] ^ btb_rd_pc4_f; + + logic [31:2] adder_pc_in_f, ifc_fetch_adder_prior; + rvdfflie #(.WIDTH(30), .LEFT(19)) faddrf_ff (.*, .en(ifc_fetch_req_f & ~ifu_bp_hit_taken_f & ic_hit_f), .din(ifc_fetch_addr_f[31:2]), .dout(ifc_fetch_adder_prior[31:2])); + + + assign ifu_bp_poffset_f[11:0] = btb_rd_tgt_f[11:0]; + + assign adder_pc_in_f[31:2] = ( ({30{ use_fa_plus}} & fetch_addr_p1_f[31:2]) | + ({30{ btb_fg_crossing_f}} & ifc_fetch_adder_prior[31:2]) | + ({30{~btb_fg_crossing_f & ~use_fa_plus}} & ifc_fetch_addr_f[31:2])); + + rvbradder predtgt_addr (.pc({adder_pc_in_f[31:2], bp_total_branch_offset_f}), + .offset(btb_rd_tgt_f[11:0]), + .dout(bp_btb_target_adder_f[31:1]) + ); + // mux in the return stack address here for a predicted return assuming the RS is valid, quite if no prediction + assign ifu_bp_btb_target_f[31:1] = (({31{btb_rd_ret_f & ~btb_rd_call_f & rets_out[0][0] & ifu_bp_hit_taken_f}} & rets_out[0][31:1]) | + ({31{~(btb_rd_ret_f & ~btb_rd_call_f & rets_out[0][0]) & ifu_bp_hit_taken_f}} & bp_btb_target_adder_f[31:1]) ); + + + // ---------------------------------------------------------------------- + // Return Stack + // ---------------------------------------------------------------------- + + rvbradder rs_addr (.pc({adder_pc_in_f[31:2], bp_total_branch_offset_f}), + .offset({11'b0, ~btb_rd_pc4_f}), + .dout(bp_rs_call_target_f[31:1]) + ); + + assign rs_push = (btb_rd_call_f & ~btb_rd_ret_f & ifu_bp_hit_taken_f); + assign rs_pop = (btb_rd_ret_f & ~btb_rd_call_f & ifu_bp_hit_taken_f); + assign rs_hold = ~rs_push & ~rs_pop; + + + + // Fetch based (bit 0 is a valid) + assign rets_in[0][31:0] = ( ({32{rs_push}} & {bp_rs_call_target_f[31:1], 1'b1}) | // target[31:1], valid + ({32{rs_pop}} & rets_out[1][31:0]) ); + + assign rsenable[0] = ~rs_hold; + + for (i=0; i0) begin + assign rets_in[i][31:0] = ( ({32{rs_push}} & rets_out[i-1][31:0]) | + ({32{rs_pop}} & rets_out[i+1][31:0]) ); + assign rsenable[i] = rs_push | rs_pop; + end + rvdffe #(32) rets_ff (.*, .en(rsenable[i]), .din(rets_in[i][31:0]), .dout(rets_out[i][31:0])); + + end : retstack + + // ---------------------------------------------------------------------- + // WRITE + // ---------------------------------------------------------------------- + + + assign dec_tlu_error_wb = dec_tlu_br0_start_error_wb | dec_tlu_br0_error_wb; + + assign btb_error_addr_wb[pt.BTB_ADDR_HI:pt.BTB_ADDR_LO] = dec_tlu_br0_addr_wb[pt.BTB_ADDR_HI:pt.BTB_ADDR_LO]; + + assign dec_tlu_way_wb = dec_tlu_br0_way_wb; + + assign btb_valid = exu_mp_valid & ~dec_tlu_error_wb; + + assign btb_wr_tag[pt.BTB_BTAG_SIZE-1:0] = exu_mp_btag[pt.BTB_BTAG_SIZE-1:0]; + + if(!pt.BTB_FULLYA) begin + + if(pt.BTB_BTAG_FOLD) begin : btbfold + el2_btb_tag_hash_fold #(.pt(pt)) rdtagf (.hash(fetch_rd_tag_f[pt.BTB_BTAG_SIZE-1:0]), + .pc({ifc_fetch_addr_f[pt.BTB_ADDR_HI+pt.BTB_BTAG_SIZE+pt.BTB_BTAG_SIZE:pt.BTB_ADDR_HI+1]})); + el2_btb_tag_hash_fold #(.pt(pt)) rdtagp1f(.hash(fetch_rd_tag_p1_f[pt.BTB_BTAG_SIZE-1:0]), + .pc({fetch_addr_p1_f[ pt.BTB_ADDR_HI+pt.BTB_BTAG_SIZE+pt.BTB_BTAG_SIZE:pt.BTB_ADDR_HI+1]})); + end + else begin : btbfold + el2_btb_tag_hash #(.pt(pt)) rdtagf(.hash(fetch_rd_tag_f[pt.BTB_BTAG_SIZE-1:0]), + .pc({ifc_fetch_addr_f[pt.BTB_ADDR_HI+pt.BTB_BTAG_SIZE+pt.BTB_BTAG_SIZE+pt.BTB_BTAG_SIZE:pt.BTB_ADDR_HI+1]})); + el2_btb_tag_hash #(.pt(pt)) rdtagp1f(.hash(fetch_rd_tag_p1_f[pt.BTB_BTAG_SIZE-1:0]), + .pc({fetch_addr_p1_f[pt.BTB_ADDR_HI+pt.BTB_BTAG_SIZE+pt.BTB_BTAG_SIZE+pt.BTB_BTAG_SIZE:pt.BTB_ADDR_HI+1]})); + end + + assign btb_wr_en_way0 = ( ({{~exu_mp_way & exu_mp_valid_write & ~dec_tlu_error_wb}}) | + ({{~dec_tlu_way_wb & dec_tlu_error_wb}})); + + assign btb_wr_en_way1 = ( ({{exu_mp_way & exu_mp_valid_write & ~dec_tlu_error_wb}}) | + ({{dec_tlu_way_wb & dec_tlu_error_wb}})); + assign btb_wr_addr[pt.BTB_ADDR_HI:pt.BTB_ADDR_LO] = dec_tlu_error_wb ? btb_error_addr_wb[pt.BTB_ADDR_HI:pt.BTB_ADDR_LO] : exu_mp_addr[pt.BTB_ADDR_HI:pt.BTB_ADDR_LO]; + + + assign vwayhit_f[1:0] = ( ({2{fetch_start_f[0]}} & {wayhit_f[1:0]}) | + ({2{fetch_start_f[1]}} & {wayhit_p1_f[0], wayhit_f[1]})) & {eoc_mask, 1'b1}; + + end // if (!pt.BTB_FULLYA) + + assign btb_wr_data[BTB_DWIDTH-1:0] = {btb_wr_tag[pt.BTB_BTAG_SIZE-1:0], exu_mp_tgt[pt.BTB_TOFFSET_SIZE-1:0], exu_mp_pc4, exu_mp_boffset, + exu_mp_call | exu_mp_ja, exu_mp_ret | exu_mp_ja, btb_valid} ; + + assign exu_mp_valid_write = exu_mp_valid & exu_mp_ataken & ~exu_mp_pkt.valid; + logic [1:0] bht_wr_data0, bht_wr_data2; + logic [1:0] bht_wr_en0, bht_wr_en2; + + assign middle_of_bank = exu_mp_pc4 ^ exu_mp_boffset; + assign bht_wr_en0[1:0] = {2{exu_mp_valid & ~exu_mp_call & ~exu_mp_ret & ~exu_mp_ja}} & {middle_of_bank, ~middle_of_bank}; + assign bht_wr_en2[1:0] = {2{dec_tlu_br0_v_wb}} & {dec_tlu_br0_middle_wb, ~dec_tlu_br0_middle_wb} ; + + // Experiments show this is the best priority scheme for same bank/index writes at the same time. + assign bht_wr_data0[1:0] = exu_mp_hist[1:0]; // lowest priority + assign bht_wr_data2[1:0] = dec_tlu_br0_hist_wb[1:0]; // highest priority + + + + logic [pt.BHT_ADDR_HI:pt.BHT_ADDR_LO] bht_rd_addr_f, bht_rd_addr_p1_f, bht_wr_addr0, bht_wr_addr2; + + logic [pt.BHT_ADDR_HI:pt.BHT_ADDR_LO] mp_hashed, br0_hashed_wb, bht_rd_addr_hashed_f, bht_rd_addr_hashed_p1_f; + el2_btb_ghr_hash #(.pt(pt)) mpghrhs (.hashin(exu_mp_addr[pt.BTB_ADDR_HI:pt.BTB_ADDR_LO]), .ghr(exu_mp_eghr[pt.BHT_GHR_SIZE-1:0]), .hash(mp_hashed[pt.BHT_ADDR_HI:pt.BHT_ADDR_LO])); + el2_btb_ghr_hash #(.pt(pt)) br0ghrhs (.hashin(dec_tlu_br0_addr_wb[pt.BTB_ADDR_HI:pt.BTB_ADDR_LO]), .ghr(exu_i0_br_fghr_wb[pt.BHT_GHR_SIZE-1:0]), .hash(br0_hashed_wb[pt.BHT_ADDR_HI:pt.BHT_ADDR_LO])); + el2_btb_ghr_hash #(.pt(pt)) fghrhs (.hashin(btb_rd_addr_f[pt.BTB_ADDR_HI:pt.BTB_ADDR_LO]), .ghr(fghr[pt.BHT_GHR_SIZE-1:0]), .hash(bht_rd_addr_hashed_f[pt.BHT_ADDR_HI:pt.BHT_ADDR_LO])); + el2_btb_ghr_hash #(.pt(pt)) fghrhs_p1 (.hashin(btb_rd_addr_p1_f[pt.BTB_ADDR_HI:pt.BTB_ADDR_LO]), .ghr(fghr[pt.BHT_GHR_SIZE-1:0]), .hash(bht_rd_addr_hashed_p1_f[pt.BHT_ADDR_HI:pt.BHT_ADDR_LO])); + + assign bht_wr_addr0[pt.BHT_ADDR_HI:pt.BHT_ADDR_LO] = mp_hashed[pt.BHT_ADDR_HI:pt.BHT_ADDR_LO]; + assign bht_wr_addr2[pt.BHT_ADDR_HI:pt.BHT_ADDR_LO] = br0_hashed_wb[pt.BHT_ADDR_HI:pt.BHT_ADDR_LO]; + assign bht_rd_addr_f[pt.BHT_ADDR_HI:pt.BHT_ADDR_LO] = bht_rd_addr_hashed_f[pt.BHT_ADDR_HI:pt.BHT_ADDR_LO]; + assign bht_rd_addr_p1_f[pt.BHT_ADDR_HI:pt.BHT_ADDR_LO] = bht_rd_addr_hashed_p1_f[pt.BHT_ADDR_HI:pt.BHT_ADDR_LO]; + + + // ---------------------------------------------------------------------- + // Structures. Using FLOPS + // ---------------------------------------------------------------------- + // BTB + // Entry -> tag[pt.BTB_BTAG_SIZE-1:0], toffset[11:0], pc4, boffset, call, ret, valid + + if(!pt.BTB_FULLYA) begin + + for (j=0 ; j direction, strength + // + //----------------------------------------------------------------------------- + +// logic [1:0] [(pt.BHT_ARRAY_DEPTH/NUM_BHT_LOOP)-1:0][NUM_BHT_LOOP-1:0][1:0] bht_bank_wr_data ; + logic [1:0] [pt.BHT_ARRAY_DEPTH-1:0] [1:0] bht_bank_rd_data_out ; + logic [1:0] [(pt.BHT_ARRAY_DEPTH/NUM_BHT_LOOP)-1:0] bht_bank_clken ; + logic [1:0] [(pt.BHT_ARRAY_DEPTH/NUM_BHT_LOOP)-1:0] bht_bank_clk ; +// logic [1:0] [(pt.BHT_ARRAY_DEPTH/NUM_BHT_LOOP)-1:0][NUM_BHT_LOOP-1:0] bht_bank_sel ; + + for ( i=0; i<2; i++) begin : BANKS + wire[pt.BHT_ARRAY_DEPTH-1:0] wr0, wr1; + assign wr0 = pt.BHT_ARRAY_DEPTH'(bht_wr_en0[i] << bht_wr_addr0); + assign wr1 = pt.BHT_ARRAY_DEPTH'(bht_wr_en2[i] << bht_wr_addr2); + for (genvar k=0 ; k < (pt.BHT_ARRAY_DEPTH)/NUM_BHT_LOOP ; k++) begin : BHT_CLK_GROUP + assign bht_bank_clken[i][k] = (bht_wr_en0[i] & ((bht_wr_addr0[pt.BHT_ADDR_HI: NUM_BHT_LOOP_OUTER_LO]==k) | BHT_NO_ADDR_MATCH)) | + (bht_wr_en2[i] & ((bht_wr_addr2[pt.BHT_ADDR_HI: NUM_BHT_LOOP_OUTER_LO]==k) | BHT_NO_ADDR_MATCH)); +`ifndef RV_FPGA_OPTIMIZE + rvclkhdr bht_bank_grp_cgc ( .en(bht_bank_clken[i][k]), .l1clk(bht_bank_clk[i][k]), .* ); // ifndef RV_FPGA_OPTIMIZE +`else + assign bht_bank_clk[i][k] = clk; +`endif + + for (j=0 ; j cdecode.e + +// 2) espresso -Dso -oeqntott cdecode.e | addassign > compress_equations + +// to generate the legal (16b compressed instruction is legal) equation below: + +// 1) coredecode -in cdecode -legal > clegal.e + +// 2) espresso -Dso -oeqntott clegal.e | addassign > clegal_equation + + + + + +// espresso decodes +assign rdrd = (!i[14]&i[6]&i[1]) | (!i[15]&i[14]&i[11]&i[0]) | (!i[14]&i[5]&i[1]) | ( + !i[15]&i[14]&i[10]&i[0]) | (!i[14]&i[4]&i[1]) | (!i[15]&i[14]&i[9] + &i[0]) | (!i[14]&i[3]&i[1]) | (!i[15]&i[14]&!i[8]&i[0]) | (!i[14] + &i[2]&i[1]) | (!i[15]&i[14]&i[7]&i[0]) | (!i[15]&i[1]) | (!i[15] + &!i[13]&i[0]); + +assign rdrs1 = (!i[14]&i[12]&i[11]&i[1]) | (!i[14]&i[12]&i[10]&i[1]) | (!i[14] + &i[12]&i[9]&i[1]) | (!i[14]&i[12]&i[8]&i[1]) | (!i[14]&i[12]&i[7] + &i[1]) | (!i[14]&!i[12]&!i[6]&!i[5]&!i[4]&!i[3]&!i[2]&i[1]) | (!i[14] + &i[12]&i[6]&i[1]) | (!i[14]&i[12]&i[5]&i[1]) | (!i[14]&i[12]&i[4] + &i[1]) | (!i[14]&i[12]&i[3]&i[1]) | (!i[14]&i[12]&i[2]&i[1]) | ( + !i[15]&!i[14]&!i[13]&i[0]) | (!i[15]&!i[14]&i[1]); + +assign rs2rs2 = (i[15]&i[6]&i[1]) | (i[15]&i[5]&i[1]) | (i[15]&i[4]&i[1]) | ( + i[15]&i[3]&i[1]) | (i[15]&i[2]&i[1]) | (i[15]&i[14]&i[1]); + +assign rdprd = (i[15]&!i[14]&!i[13]&i[0]); + +assign rdprs1 = (i[15]&!i[13]&i[0]) | (i[15]&i[14]&i[0]) | (i[14]&!i[1]&!i[0]); + +assign rs2prs2 = (i[15]&!i[14]&!i[13]&i[11]&i[10]&i[0]) | (i[15]&!i[1]&!i[0]); + +assign rs2prd = (!i[15]&!i[1]&!i[0]); + +assign uimm9_2 = (!i[14]&!i[1]&!i[0]); + +assign ulwimm6_2 = (!i[15]&i[14]&!i[1]&!i[0]); + +assign ulwspimm7_2 = (!i[15]&i[14]&i[1]); + +assign rdeq2 = (!i[15]&i[14]&i[13]&!i[11]&!i[10]&!i[9]&i[8]&!i[7]); + +assign rdeq1 = (!i[14]&i[12]&i[11]&!i[6]&!i[5]&!i[4]&!i[3]&!i[2]&i[1]) | (!i[14] + &i[12]&i[10]&!i[6]&!i[5]&!i[4]&!i[3]&!i[2]&i[1]) | (!i[14]&i[12]&i[9] + &!i[6]&!i[5]&!i[4]&!i[3]&!i[2]&i[1]) | (!i[14]&i[12]&i[8]&!i[6]&!i[5] + &!i[4]&!i[3]&!i[2]&i[1]) | (!i[14]&i[12]&i[7]&!i[6]&!i[5]&!i[4]&!i[3] + &!i[2]&i[1]) | (!i[15]&!i[14]&i[13]); + +assign rs1eq2 = (!i[15]&i[14]&i[13]&!i[11]&!i[10]&!i[9]&i[8]&!i[7]) | (i[14] + &i[1]) | (!i[14]&!i[1]&!i[0]); + +assign sbroffset8_1 = (i[15]&i[14]&i[0]); + +assign simm9_4 = (!i[15]&i[14]&i[13]&!i[11]&!i[10]&!i[9]&i[8]&!i[7]); + +assign simm5_0 = (!i[14]&!i[13]&i[11]&!i[10]&i[0]) | (!i[15]&!i[13]&i[0]); + +assign sjaloffset11_1 = (!i[14]&i[13]); + +assign sluimm17_12 = (!i[15]&i[14]&i[13]&i[7]) | (!i[15]&i[14]&i[13]&!i[8]) | ( + !i[15]&i[14]&i[13]&i[9]) | (!i[15]&i[14]&i[13]&i[10]) | (!i[15]&i[14] + &i[13]&i[11]); + +assign uimm5_0 = (i[15]&!i[14]&!i[13]&!i[11]&i[0]) | (!i[15]&!i[14]&i[1]); + +assign uswimm6_2 = (i[15]&!i[1]&!i[0]); + +assign uswspimm7_2 = (i[15]&i[14]&i[1]); + +assign o[31] = 1'b0; + +assign o[30] = (i[15]&!i[14]&!i[13]&i[10]&!i[6]&!i[5]&i[0]) | (i[15]&!i[14] + &!i[13]&!i[11]&i[10]&i[0]); + +assign o[29] = 1'b0; + +assign o[28] = 1'b0; + +assign o[27] = 1'b0; + +assign o[26] = 1'b0; + +assign o[25] = 1'b0; + +assign o[24] = 1'b0; + +assign o[23] = 1'b0; + +assign o[22] = 1'b0; + +assign o[21] = 1'b0; + +assign o[20] = (!i[14]&i[12]&!i[11]&!i[10]&!i[9]&!i[8]&!i[7]&!i[6]&!i[5]&!i[4] + &!i[3]&!i[2]&i[1]); + +assign o[19] = 1'b0; + +assign o[18] = 1'b0; + +assign o[17] = 1'b0; + +assign o[16] = 1'b0; + +assign o[15] = 1'b0; + +assign o[14] = (i[15]&!i[14]&!i[13]&!i[11]&i[0]) | (i[15]&!i[14]&!i[13]&!i[10] + &i[0]) | (i[15]&!i[14]&!i[13]&i[6]&i[0]) | (i[15]&!i[14]&!i[13]&i[5] + &i[0]); + +assign o[13] = (i[15]&!i[14]&!i[13]&i[11]&!i[10]&i[0]) | (i[15]&!i[14]&!i[13] + &i[11]&i[6]&i[0]) | (i[14]&!i[0]); + +assign o[12] = (i[15]&!i[14]&!i[13]&i[6]&i[5]&i[0]) | (i[15]&!i[14]&!i[13]&!i[11] + &i[0]) | (i[15]&!i[14]&!i[13]&!i[10]&i[0]) | (!i[15]&!i[14]&i[1]) | ( + i[15]&i[14]&i[13]); + +assign o[11] = 1'b0; + +assign o[10] = 1'b0; + +assign o[9] = 1'b0; + +assign o[8] = 1'b0; + +assign o[7] = 1'b0; + +assign o[6] = (i[15]&!i[14]&!i[6]&!i[5]&!i[4]&!i[3]&!i[2]&!i[0]) | (!i[14]&i[13]) | ( + i[15]&i[14]&i[0]); + +assign o[5] = (i[15]&!i[0]) | (i[15]&i[11]&i[10]) | (i[13]&!i[8]) | (i[13]&i[7]) | ( + i[13]&i[9]) | (i[13]&i[10]) | (i[13]&i[11]) | (!i[14]&i[13]) | ( + i[15]&i[14]); + +assign o[4] = (!i[14]&!i[11]&!i[10]&!i[9]&!i[8]&!i[7]&!i[0]) | (!i[15]&!i[14] + &!i[0]) | (!i[14]&i[6]&!i[0]) | (!i[15]&i[14]&i[0]) | (!i[14]&i[5] + &!i[0]) | (!i[14]&i[4]&!i[0]) | (!i[14]&!i[13]&i[0]) | (!i[14]&i[3] + &!i[0]) | (!i[14]&i[2]&!i[0]); + +assign o[3] = (!i[14]&i[13]); + +assign o[2] = (!i[14]&i[12]&i[11]&!i[6]&!i[5]&!i[4]&!i[3]&!i[2]&i[1]) | (!i[14] + &i[12]&i[10]&!i[6]&!i[5]&!i[4]&!i[3]&!i[2]&i[1]) | (!i[14]&i[12]&i[9] + &!i[6]&!i[5]&!i[4]&!i[3]&!i[2]&i[1]) | (!i[14]&i[12]&i[8]&!i[6]&!i[5] + &!i[4]&!i[3]&!i[2]&i[1]) | (!i[14]&i[12]&i[7]&!i[6]&!i[5]&!i[4]&!i[3] + &!i[2]&i[1]) | (i[15]&!i[14]&!i[12]&!i[6]&!i[5]&!i[4]&!i[3]&!i[2] + &!i[0]) | (!i[15]&i[13]&!i[8]) | (!i[15]&i[13]&i[7]) | (!i[15]&i[13] + &i[9]) | (!i[15]&i[13]&i[10]) | (!i[15]&i[13]&i[11]) | (!i[14]&i[13]); + +// 32b instruction has lower two bits 2'b11 + +assign o[1] = 1'b1; + +assign o[0] = 1'b1; + +assign legal = (!i[13]&!i[12]&i[11]&i[1]&!i[0]) | (!i[13]&!i[12]&i[10]&i[1]&!i[0]) | ( + !i[15]&!i[13]&i[11]&!i[1]) | (!i[13]&!i[12]&i[9]&i[1]&!i[0]) | ( + !i[13]&!i[12]&i[8]&i[1]&!i[0]) | (!i[15]&!i[13]&i[6]&!i[1]) | (i[15] + &!i[12]&!i[1]&i[0]) | (!i[13]&!i[12]&i[7]&i[1]&!i[0]) | (!i[15]&!i[13] + &i[5]&!i[1]) | (!i[12]&i[6]&!i[1]&i[0]) | (i[15]&!i[13]&i[6]&i[1] + &!i[0]) | (!i[15]&!i[13]&i[10]&!i[1]) | (!i[12]&i[5]&!i[1]&i[0]) | ( + i[12]&i[11]&!i[10]&!i[1]&i[0]) | (i[15]&!i[13]&i[5]&i[1]&!i[0]) | ( + !i[15]&!i[13]&i[9]&!i[1]) | (i[13]&i[12]&!i[1]&i[0]) | (i[15]&!i[13] + &i[4]&i[1]&!i[0]) | (!i[15]&!i[13]&i[8]&!i[1]) | (i[15]&!i[13]&i[3] + &i[1]&!i[0]) | (i[13]&i[4]&!i[1]&i[0]) | (i[15]&!i[13]&i[2]&i[1]&!i[0]) | ( + !i[15]&!i[13]&i[7]&!i[1]) | (i[13]&i[3]&!i[1]&i[0]) | (i[13]&i[2] + &!i[1]&i[0]) | (!i[14]&!i[12]&!i[1]&i[0]) | (i[15]&!i[13]&i[12]&i[1] + &!i[0]) | (i[14]&!i[13]&i[7]&!i[0]) | (i[14]&!i[13]&i[8]&!i[0]) | ( + i[14]&!i[13]&i[9]&!i[0]) | (!i[15]&!i[14]&!i[13]&!i[12]&i[1]&!i[0]) | ( + i[14]&!i[13]&i[10]&!i[0]) | (i[14]&!i[13]&i[11]&!i[0]) | (!i[15] + &!i[13]&i[12]&!i[1]) | (i[15]&i[14]&!i[13]&!i[0]) | (i[14]&!i[13] + &!i[1]); + + + + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/el2_ifu_ic_mem.sv b/designs/Caliptra/src/caliptra-rtl/el2_ifu_ic_mem.sv new file mode 100644 index 0000000..097838c --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/el2_ifu_ic_mem.sv @@ -0,0 +1,1406 @@ +//******************************************************************************** +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2020 Western Digital Corporation or its affiliates. +// +// 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. +//******************************************************************************** +//////////////////////////////////////////////////// +// ICACHE DATA & TAG MODULE WRAPPER // +///////////////////////////////////////////////////// +module el2_ifu_ic_mem +import el2_pkg::*; + #( +`include "el2_param.vh" + ) + ( + input logic clk, // Clock only while core active. Through one clock header. For flops with second clock header built in. Connected to ACTIVE_L2CLK. + input logic active_clk, // Clock only while core active. Through two clock headers. For flops without second clock header built in. + input logic rst_l, // reset, active low + input logic clk_override, // Override non-functional clock gating + input logic dec_tlu_core_ecc_disable, // Disable ECC checking + + input logic [31:1] ic_rw_addr, + input logic [pt.ICACHE_NUM_WAYS-1:0] ic_wr_en , // Which way to write + input logic ic_rd_en , // Read enable + input logic [pt.ICACHE_INDEX_HI:3] ic_debug_addr, // Read/Write addresss to the Icache. + input logic ic_debug_rd_en, // Icache debug rd + input logic ic_debug_wr_en, // Icache debug wr + input logic ic_debug_tag_array, // Debug tag array + input logic [pt.ICACHE_NUM_WAYS-1:0] ic_debug_way, // Debug way. Rd or Wr. + input logic [63:0] ic_premux_data, // Premux data to be muxed with each way of the Icache. + input logic ic_sel_premux_data, // Select the pre_muxed data + + input logic [pt.ICACHE_BANKS_WAY-1:0][70:0] ic_wr_data, // Data to fill to the Icache. With ECC + output logic [63:0] ic_rd_data , // Data read from Icache. 2x64bits + parity bits. F2 stage. With ECC + output logic [70:0] ic_debug_rd_data , // Data read from Icache. 2x64bits + parity bits. F2 stage. With ECC + output logic [25:0] ictag_debug_rd_data,// Debug icache tag. + input logic [70:0] ic_debug_wr_data, // Debug wr cache. + + output logic [pt.ICACHE_BANKS_WAY-1:0] ic_eccerr, // ecc error per bank + output logic [pt.ICACHE_BANKS_WAY-1:0] ic_parerr, // ecc error per bank + input logic [pt.ICACHE_NUM_WAYS-1:0] ic_tag_valid, // Valid from the I$ tag valid outside (in flops). + + el2_mem_if.veer_icache_src icache_export, + + output logic [pt.ICACHE_NUM_WAYS-1:0] ic_rd_hit, // ic_rd_hit[3:0] + output logic ic_tag_perr, // Tag Parity error + // Excluding scan_mode from coverage as its usage is determined by the integrator of the VeeR core. + /*pragma coverage off*/ + input logic scan_mode // Flop scan mode control + /*pragma coverage on*/ + ) ; + + // split the veer_icache_src interface into veer_icache_data and veer_icache_tag + el2_mem_if local_icache_export(); + + always_comb begin + // data + icache_export.ic_b_sb_wren = local_icache_export.ic_b_sb_wren; + icache_export.ic_b_sb_bit_en_vec = local_icache_export.ic_b_sb_bit_en_vec; + icache_export.ic_sb_wr_data = local_icache_export.ic_sb_wr_data; + icache_export.ic_rw_addr_bank_q = local_icache_export.ic_rw_addr_bank_q; + icache_export.ic_bank_way_clken_final = local_icache_export.ic_bank_way_clken_final; + icache_export.ic_bank_way_clken_final_up = local_icache_export.ic_bank_way_clken_final_up; + + local_icache_export.wb_packeddout_pre = icache_export.wb_packeddout_pre; + local_icache_export.wb_dout_pre_up = icache_export.wb_dout_pre_up; + + // tag + icache_export.ic_tag_clken_final = local_icache_export.ic_tag_clken_final; + icache_export.ic_tag_wren_q = local_icache_export.ic_tag_wren_q; + icache_export.ic_tag_wren_biten_vec = local_icache_export.ic_tag_wren_biten_vec; + icache_export.ic_tag_wr_data = local_icache_export.ic_tag_wr_data; + icache_export.ic_rw_addr_q = local_icache_export.ic_rw_addr_q; + + local_icache_export.ic_tag_data_raw_pre = icache_export.ic_tag_data_raw_pre; + local_icache_export.ic_tag_data_raw_packed_pre = icache_export.ic_tag_data_raw_packed_pre; + end + + EL2_IC_TAG #(.pt(pt)) ic_tag_inst + ( + .*, + .icache_export(local_icache_export.veer_icache_tag), + .ic_wr_en (ic_wr_en[pt.ICACHE_NUM_WAYS-1:0]), + .ic_debug_addr(ic_debug_addr[pt.ICACHE_INDEX_HI:3]), + .ic_rw_addr (ic_rw_addr[31:3]) + ) ; + + EL2_IC_DATA #(.pt(pt)) ic_data_inst + ( + .*, + .icache_export(local_icache_export.veer_icache_data), + .ic_wr_en (ic_wr_en[pt.ICACHE_NUM_WAYS-1:0]), + .ic_debug_addr(ic_debug_addr[pt.ICACHE_INDEX_HI:3]), + .ic_rw_addr (ic_rw_addr[31:1]) + ) ; + + endmodule + + +///////////////////////////////////////////////// +////// ICACHE DATA MODULE //////////////////// +///////////////////////////////////////////////// +module EL2_IC_DATA +import el2_pkg::*; +#( +`include "el2_param.vh" + ) + ( + input logic clk, + input logic active_clk, + input logic rst_l, + input logic clk_override, + + input logic [31:1] ic_rw_addr, + input logic [pt.ICACHE_NUM_WAYS-1:0]ic_wr_en, + input logic ic_rd_en, // Read enable + + input logic [pt.ICACHE_BANKS_WAY-1:0][70:0] ic_wr_data, // Data to fill to the Icache. With ECC + output logic [63:0] ic_rd_data , // Data read from Icache. 2x64bits + parity bits. F2 stage. With ECC + input logic [70:0] ic_debug_wr_data, // Debug wr cache. + output logic [70:0] ic_debug_rd_data , // Data read from Icache. 2x64bits + parity bits. F2 stage. With ECC + output logic [pt.ICACHE_BANKS_WAY-1:0] ic_parerr, + output logic [pt.ICACHE_BANKS_WAY-1:0] ic_eccerr, // ecc error per bank + input logic [pt.ICACHE_INDEX_HI:3] ic_debug_addr, // Read/Write addresss to the Icache. + input logic ic_debug_rd_en, // Icache debug rd + input logic ic_debug_wr_en, // Icache debug wr + input logic ic_debug_tag_array, // Debug tag array + input logic [pt.ICACHE_NUM_WAYS-1:0] ic_debug_way, // Debug way. Rd or Wr. + input logic [63:0] ic_premux_data, // Premux data to be muxed with each way of the Icache. + input logic ic_sel_premux_data, // Select the pre_muxed data + + input logic [pt.ICACHE_NUM_WAYS-1:0]ic_rd_hit, + el2_mem_if.veer_icache_data icache_export, + // Excluding scan_mode from coverage as its usage is determined by the integrator of the VeeR core. + /*pragma coverage off*/ + input logic scan_mode + /*pragma coverage on*/ + + ) ; + + logic [pt.ICACHE_TAG_INDEX_LO-1:1] ic_rw_addr_ff; + logic [pt.ICACHE_BANKS_WAY-1:0][pt.ICACHE_NUM_WAYS-1:0] ic_b_sb_wren; //bank x ways + logic [pt.ICACHE_BANKS_WAY-1:0][pt.ICACHE_NUM_WAYS-1:0] ic_b_sb_rden; //bank x ways + + + logic [pt.ICACHE_BANKS_WAY-1:0] ic_b_rden; //bank + logic [pt.ICACHE_BANKS_WAY-1:0] ic_b_rden_ff; //bank + logic [pt.ICACHE_BANKS_WAY-1:0] ic_debug_sel_sb; + + logic [pt.ICACHE_NUM_WAYS-1:0][pt.ICACHE_BANKS_WAY-1:0][70:0] wb_dout ; // ways x bank + logic [pt.ICACHE_BANKS_WAY-1:0][70:0] ic_sb_wr_data, ic_bank_wr_data, wb_dout_ecc_bank; + logic [pt.ICACHE_NUM_WAYS-1:0] [141:0] wb_dout_way_pre; + logic [pt.ICACHE_NUM_WAYS-1:0] [63:0] wb_dout_way, wb_dout_way_with_premux; + logic [141:0] wb_dout_ecc; + + logic [pt.ICACHE_BANKS_WAY-1:0] bank_check_en; + + logic [pt.ICACHE_BANKS_WAY-1:0][pt.ICACHE_NUM_WAYS-1:0] ic_bank_way_clken; + logic [pt.ICACHE_BANKS_WAY-1:0] ic_bank_way_clken_final; + logic [pt.ICACHE_NUM_WAYS-1:0][pt.ICACHE_BANKS_WAY-1:0] ic_bank_way_clken_final_up; + + logic [pt.ICACHE_NUM_WAYS-1:0] ic_debug_rd_way_en; // debug wr_way + logic [pt.ICACHE_NUM_WAYS-1:0] ic_debug_rd_way_en_ff; // debug wr_way + logic [pt.ICACHE_NUM_WAYS-1:0] ic_debug_wr_way_en; // debug wr_way + logic [pt.ICACHE_INDEX_HI:1] ic_rw_addr_q; + + logic [pt.ICACHE_BANKS_WAY-1:0] [pt.ICACHE_INDEX_HI : pt.ICACHE_DATA_INDEX_LO] ic_rw_addr_bank_q; + + logic [pt.ICACHE_TAG_LO-1 : pt.ICACHE_DATA_INDEX_LO] ic_rw_addr_q_inc; + logic [pt.ICACHE_NUM_WAYS-1:0] ic_rd_hit_q; + + + + logic [pt.ICACHE_BANKS_WAY-1:0] ic_b_sram_en; + logic [pt.ICACHE_BANKS_WAY-1:0] ic_b_read_en; + logic [pt.ICACHE_BANKS_WAY-1:0] ic_b_write_en; + logic [pt.ICACHE_BANKS_WAY-1:0][pt.ICACHE_NUM_BYPASS-1:0] [31 : pt.ICACHE_DATA_INDEX_LO] wb_index_hold; + logic [pt.ICACHE_BANKS_WAY-1:0][pt.ICACHE_NUM_BYPASS-1:0] write_bypass_en; //bank + logic [pt.ICACHE_BANKS_WAY-1:0][pt.ICACHE_NUM_BYPASS-1:0] write_bypass_en_ff; //bank + logic [pt.ICACHE_BANKS_WAY-1:0][pt.ICACHE_NUM_BYPASS-1:0] index_valid; //bank + logic [pt.ICACHE_BANKS_WAY-1:0][pt.ICACHE_NUM_BYPASS-1:0] ic_b_clear_en; + logic [pt.ICACHE_BANKS_WAY-1:0][pt.ICACHE_NUM_BYPASS-1:0] ic_b_addr_match; + logic [pt.ICACHE_BANKS_WAY-1:0][pt.ICACHE_NUM_BYPASS-1:0] ic_b_addr_match_index_only; + + logic [pt.ICACHE_NUM_WAYS-1:0][pt.ICACHE_BANKS_WAY-1:0] ic_b_sram_en_up; + logic [pt.ICACHE_NUM_WAYS-1:0][pt.ICACHE_BANKS_WAY-1:0] ic_b_read_en_up; + logic [pt.ICACHE_NUM_WAYS-1:0][pt.ICACHE_BANKS_WAY-1:0] ic_b_write_en_up; + logic [pt.ICACHE_NUM_WAYS-1:0][pt.ICACHE_BANKS_WAY-1:0][pt.ICACHE_NUM_BYPASS-1:0] [31 : pt.ICACHE_DATA_INDEX_LO] wb_index_hold_up; + logic [pt.ICACHE_NUM_WAYS-1:0][pt.ICACHE_BANKS_WAY-1:0][pt.ICACHE_NUM_BYPASS-1:0] write_bypass_en_up; //bank + logic [pt.ICACHE_NUM_WAYS-1:0][pt.ICACHE_BANKS_WAY-1:0][pt.ICACHE_NUM_BYPASS-1:0] write_bypass_en_ff_up; //bank + logic [pt.ICACHE_NUM_WAYS-1:0][pt.ICACHE_BANKS_WAY-1:0][pt.ICACHE_NUM_BYPASS-1:0] index_valid_up; //bank + logic [pt.ICACHE_NUM_WAYS-1:0][pt.ICACHE_BANKS_WAY-1:0][pt.ICACHE_NUM_BYPASS-1:0] ic_b_clear_en_up; + logic [pt.ICACHE_NUM_WAYS-1:0][pt.ICACHE_BANKS_WAY-1:0][pt.ICACHE_NUM_BYPASS-1:0] ic_b_addr_match_up; + logic [pt.ICACHE_NUM_WAYS-1:0][pt.ICACHE_BANKS_WAY-1:0][pt.ICACHE_NUM_BYPASS-1:0] ic_b_addr_match_index_only_up; + + + logic [pt.ICACHE_BANKS_WAY-1:0] [31 : pt.ICACHE_DATA_INDEX_LO] ic_b_rw_addr; + logic [pt.ICACHE_BANKS_WAY-1:0] [pt.ICACHE_INDEX_HI : pt.ICACHE_DATA_INDEX_LO] ic_b_rw_addr_index_only; + + logic [pt.ICACHE_NUM_WAYS-1:0][pt.ICACHE_BANKS_WAY-1:0] [31 : pt.ICACHE_DATA_INDEX_LO] ic_b_rw_addr_up; + logic [pt.ICACHE_NUM_WAYS-1:0][pt.ICACHE_BANKS_WAY-1:0] [pt.ICACHE_INDEX_HI : pt.ICACHE_DATA_INDEX_LO] ic_b_rw_addr_index_only_up; + + + + logic ic_rd_en_with_debug; + logic ic_rw_addr_wrap, ic_cacheline_wrap_ff; + logic ic_debug_rd_en_ff; + + // Use exported ICache interface. Some signals are assigned here, some in the blocks below. + always_comb begin + icache_export.ic_b_sb_wren = ic_b_sb_wren; + icache_export.ic_sb_wr_data = ic_sb_wr_data; + icache_export.ic_rw_addr_bank_q = ic_rw_addr_bank_q; + icache_export.ic_bank_way_clken_final =ic_bank_way_clken_final; + icache_export.ic_bank_way_clken_final_up =ic_bank_way_clken_final_up; + end + + +//----------------------------------------------------------- +// ----------- Logic section starts here -------------------- +//----------------------------------------------------------- + assign ic_debug_rd_way_en[pt.ICACHE_NUM_WAYS-1:0] = {pt.ICACHE_NUM_WAYS{ic_debug_rd_en & ~ic_debug_tag_array}} & ic_debug_way[pt.ICACHE_NUM_WAYS-1:0] ; + assign ic_debug_wr_way_en[pt.ICACHE_NUM_WAYS-1:0] = {pt.ICACHE_NUM_WAYS{ic_debug_wr_en & ~ic_debug_tag_array}} & ic_debug_way[pt.ICACHE_NUM_WAYS-1:0] ; + + logic end_of_cache_line; + assign end_of_cache_line = (pt.ICACHE_LN_SZ==7'h40) ? (&ic_rw_addr_q[5:4]) : ic_rw_addr_q[4]; + always_comb begin : clkens + ic_bank_way_clken = '0; + + for ( int i=0; i +// +// 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. +//******************************************************************************** + +//******************************************************************************** +// Icache closely coupled memory --- ICCM +//******************************************************************************** + +module el2_ifu_iccm_mem +import el2_pkg::*; +#( +`include "el2_param.vh" + )( + input logic clk, // Clock only while core active. Through one clock header. For flops with second clock header built in. Connected to ACTIVE_L2CLK. + input logic active_clk, // Clock only while core active. Through two clock headers. For flops without second clock header built in. + input logic rst_l, // reset, active low + input logic clk_override, // Override non-functional clock gating + + input logic iccm_wren, // ICCM write enable + input logic iccm_rden, // ICCM read enable + input logic [pt.ICCM_BITS-1:1] iccm_rw_addr, // ICCM read/write address + input logic iccm_buf_correct_ecc, // ICCM is doing a single bit error correct cycle + input logic iccm_correction_state, // ICCM under a correction - This is needed to guard replacements when hit + input logic [2:0] iccm_wr_size, // ICCM write size + input logic [77:0] iccm_wr_data, // ICCM write data + + el2_mem_if.veer_iccm iccm_mem_export, // RAM repositioned in testbench and connected by this interface + + output logic [63:0] iccm_rd_data, // ICCM read data + output logic [77:0] iccm_rd_data_ecc, // ICCM read ecc + // Excluding scan_mode from coverage as its usage is determined by the integrator of the VeeR core. + /*pragma coverage off*/ + input logic scan_mode // Scan mode control + /*pragma coverage on*/ + +); + + + logic [pt.ICCM_NUM_BANKS-1:0] wren_bank; + logic [pt.ICCM_NUM_BANKS-1:0] rden_bank; + logic [pt.ICCM_NUM_BANKS-1:0] iccm_clken; + logic [pt.ICCM_NUM_BANKS-1:0] [pt.ICCM_BITS-1:pt.ICCM_BANK_INDEX_LO] addr_bank; + + logic [pt.ICCM_NUM_BANKS-1:0] [38:0] iccm_bank_dout, iccm_bank_dout_fn; + logic [pt.ICCM_NUM_BANKS-1:0] [38:0] iccm_bank_wr_data; + logic [pt.ICCM_BITS-1:1] addr_bank_inc; + logic [pt.ICCM_BANK_HI : 2] iccm_rd_addr_hi_q; + logic [pt.ICCM_BANK_HI : 1] iccm_rd_addr_lo_q; + logic [63:0] iccm_rd_data_pre; + logic [63:0] iccm_data; + logic [1:0] addr_incr; + logic [pt.ICCM_NUM_BANKS-1:0] [38:0] iccm_bank_wr_data_vec; + + // logic to handle hard persisten faults + logic [1:0] [pt.ICCM_BITS-1:2] redundant_address; + logic [1:0] [38:0] redundant_data; + logic [1:0] redundant_valid; + logic [pt.ICCM_NUM_BANKS-1:0] sel_red1, sel_red0, sel_red1_q, sel_red0_q; + + + logic [38:0] redundant_data0_in, redundant_data1_in; + logic redundant_lru, redundant_lru_in, redundant_lru_en; + logic redundant_data0_en; + logic redundant_data1_en; + logic r0_addr_en, r1_addr_en; + + // Testing persistent flip + // logic [3:0] not_iccm_bank_dout; + // logic [15:3] ecc_insert_flip_in, ecc_insert_flip; + // logic flip_en, flip_match, flip_match_q; + // + // assign flip_in = (iccm_rw_addr[3:2] != 2'b00); // dont flip when bank0 - this is to make some progress in DMA streaming cases + // assign flip_en = iccm_rden; + // + // rvdffs #(1) flipmatch (.*, + // .clk(clk), + // .din(flip_in), + // .en(flip_en), + // .dout(flip_match_q)); + // + // end of testing flip + + + assign addr_incr[1:0] = (iccm_wr_size[1:0] == 2'b11) ? 2'b10: 2'b01; + assign addr_bank_inc[pt.ICCM_BITS-1 : 1] = iccm_rw_addr[pt.ICCM_BITS-1 : 1] + addr_incr[1:0]; + + for (genvar i=0; i> (16*iccm_rd_addr_lo_q[1]))}); + assign iccm_rd_data[63:0] = {iccm_data[63:0]}; + assign iccm_rd_data_ecc[77:0] = {iccm_bank_dout_fn[iccm_rd_addr_hi_q][38:0], iccm_bank_dout_fn[iccm_rd_addr_lo_q[pt.ICCM_BANK_HI:2]][38:0]}; + +endmodule // el2_ifu_iccm_mem diff --git a/designs/Caliptra/src/caliptra-rtl/el2_ifu_ifc_ctl.sv b/designs/Caliptra/src/caliptra-rtl/el2_ifu_ifc_ctl.sv new file mode 100644 index 0000000..a1bf761 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/el2_ifu_ifc_ctl.sv @@ -0,0 +1,249 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2020 Western Digital Corporation or its affiliates. +// +// 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. + +//******************************************************************************** +// el2_ifu_ifc_ctl.sv +// Function: Fetch pipe control +// +// Comments: +//******************************************************************************** + +module el2_ifu_ifc_ctl +import el2_pkg::*; +#( +`include "el2_param.vh" + ) + ( + input logic clk, // Clock only while core active. Through one clock header. For flops with second clock header built in. Connected to ACTIVE_L2CLK. + input logic free_l2clk, // Clock always. Through one clock header. For flops with second header built in. + + input logic rst_l, // reset enable, from core pin + // Excluding scan_mode from coverage as its usage is determined by the integrator of the VeeR core. + /*pragma coverage off*/ + input logic scan_mode, // scan + /*pragma coverage on*/ + + input logic ic_hit_f, // Icache hit + input logic ifu_ic_mb_empty, // Miss buffer empty + + input logic ifu_fb_consume1, // Aligner consumed 1 fetch buffer + input logic ifu_fb_consume2, // Aligner consumed 2 fetch buffers + + input logic dec_tlu_flush_noredir_wb, // Don't fetch on flush + input logic exu_flush_final, // FLush + input logic [31:1] exu_flush_path_final, // Flush path + + input logic ifu_bp_hit_taken_f, // btb hit, select the target path + input logic [31:1] ifu_bp_btb_target_f, // predicted target PC + + input logic ic_dma_active, // IC DMA active, stop fetching + input logic ic_write_stall, // IC is writing, stop fetching + input logic dma_iccm_stall_any, // force a stall in the fetch pipe for DMA ICCM access + + input logic [31:0] dec_tlu_mrac_ff , // side_effect and cacheable for each region + + output logic [31:1] ifc_fetch_addr_f, // fetch addr F + output logic [31:1] ifc_fetch_addr_bf, // fetch addr BF + + output logic ifc_fetch_req_f, // fetch request valid F + + output logic ifu_pmu_fetch_stall, // pmu event measuring fetch stall + + output logic ifc_fetch_uncacheable_bf, // The fetch request is uncacheable space. BF stage + output logic ifc_fetch_req_bf, // Fetch request. Comes with the address. BF stage + output logic ifc_fetch_req_bf_raw, // Fetch request without some qualifications. Used for clock-gating. BF stage + output logic ifc_iccm_access_bf, // This request is to the ICCM. Do not generate misses to the bus. + output logic ifc_region_acc_fault_bf, // Access fault. in ICCM region but offset is outside defined ICCM. + + output logic ifc_dma_access_ok // fetch is not accessing the ICCM, DMA can proceed + + + ); + + logic [31:1] fetch_addr_bf; + logic [31:1] fetch_addr_next; + logic [3:0] fb_write_f, fb_write_ns; + + logic fb_full_f_ns, fb_full_f; + logic fb_right, fb_right2, fb_left, wfm, idle; + logic sel_last_addr_bf, sel_next_addr_bf; + logic miss_f, miss_a; + logic flush_fb, dma_iccm_stall_any_f; + logic mb_empty_mod, goto_idle, leave_idle; + logic fetch_bf_en; + logic line_wrap; + logic fetch_addr_next_1; + + // FSM assignment + typedef enum logic [1:0] { IDLE = 2'b00 , + FETCH = 2'b01 , + STALL = 2'b10 , + WFM = 2'b11 } state_t ; + state_t state ; + state_t next_state ; + + logic dma_stall; + assign dma_stall = ic_dma_active | dma_iccm_stall_any_f; + + + + // Fetch address mux + // - flush + // - Miss *or* flush during WFM (icache miss buffer is blocking) + // - Sequential + +if(pt.BTB_ENABLE==1) begin : genblock1 + logic sel_btb_addr_bf; + + assign sel_last_addr_bf = ~exu_flush_final & (~ifc_fetch_req_f | ~ic_hit_f); + assign sel_btb_addr_bf = ~exu_flush_final & ifc_fetch_req_f & ifu_bp_hit_taken_f & ic_hit_f; + assign sel_next_addr_bf = ~exu_flush_final & ifc_fetch_req_f & ~ifu_bp_hit_taken_f & ic_hit_f; + + + assign fetch_addr_bf[31:1] = ( ({31{exu_flush_final}} & exu_flush_path_final[31:1]) | // FLUSH path + ({31{sel_last_addr_bf}} & ifc_fetch_addr_f[31:1]) | // MISS path + ({31{sel_btb_addr_bf}} & {ifu_bp_btb_target_f[31:1]})| // BTB target + ({31{sel_next_addr_bf}} & {fetch_addr_next[31:1]})); // SEQ path + + +end // if (pt.BTB_ENABLE=1) + else begin + assign sel_last_addr_bf = ~exu_flush_final & (~ifc_fetch_req_f | ~ic_hit_f); + assign sel_next_addr_bf = ~exu_flush_final & ifc_fetch_req_f & ic_hit_f; + + + assign fetch_addr_bf[31:1] = ( ({31{exu_flush_final}} & exu_flush_path_final[31:1]) | // FLUSH path + ({31{sel_last_addr_bf}} & ifc_fetch_addr_f[31:1]) | // MISS path + ({31{sel_next_addr_bf}} & {fetch_addr_next[31:1]})); // SEQ path + +end + assign fetch_addr_next[31:1] = {({ifc_fetch_addr_f[31:2]} + 30'b1), fetch_addr_next_1 }; + assign line_wrap = (fetch_addr_next[pt.ICACHE_TAG_INDEX_LO] ^ ifc_fetch_addr_f[pt.ICACHE_TAG_INDEX_LO]); + + assign fetch_addr_next_1 = line_wrap ? 1'b0 : ifc_fetch_addr_f[1]; + + assign ifc_fetch_req_bf_raw = ~idle; + assign ifc_fetch_req_bf = ifc_fetch_req_bf_raw & + + ~(fb_full_f_ns & ~(ifu_fb_consume2 | ifu_fb_consume1)) & + ~dma_stall & + ~ic_write_stall & + ~dec_tlu_flush_noredir_wb; + + + assign fetch_bf_en = exu_flush_final | ifc_fetch_req_f; + + assign miss_f = ifc_fetch_req_f & ~ic_hit_f & ~exu_flush_final; + + assign mb_empty_mod = (ifu_ic_mb_empty | exu_flush_final) & ~dma_stall & ~miss_f & ~miss_a; + + // Halt flushes and takes us to IDLE + assign goto_idle = exu_flush_final & dec_tlu_flush_noredir_wb; + // If we're in IDLE, and we get a flush, goto FETCH + assign leave_idle = exu_flush_final & ~dec_tlu_flush_noredir_wb & idle; + +//.i 7 +//.o 2 +//.ilb state[1] state[0] reset_delayed miss_f mb_empty_mod goto_idle leave_idle +//.ob next_state[1] next_state[0] +//.type fr +// +//# fetch 01, stall 10, wfm 11, idle 00 +//-- 1---- 01 +//-- 0--1- 00 +//00 0--00 00 +//00 0--01 01 +// +//01 01-0- 11 +//01 00-0- 01 +// +//11 0-10- 01 +//11 0-00- 11 + + assign next_state[1] = (~state[1] & state[0] & miss_f & ~goto_idle) | + (state[1] & ~mb_empty_mod & ~goto_idle); + + assign next_state[0] = (~goto_idle & leave_idle) | (state[0] & ~goto_idle); + + assign flush_fb = exu_flush_final; + + // model fb write logic to mass balance the fetch buffers + assign fb_right = ( ifu_fb_consume1 & ~ifu_fb_consume2 & (~ifc_fetch_req_f | miss_f)) | // Consumed and no new fetch + (ifu_fb_consume2 & ifc_fetch_req_f); // Consumed 2 and new fetch + + + assign fb_right2 = (ifu_fb_consume2 & (~ifc_fetch_req_f | miss_f)); // Consumed 2 and no new fetch + + assign fb_left = ifc_fetch_req_f & ~(ifu_fb_consume1 | ifu_fb_consume2) & ~miss_f; + +// CBH + assign fb_write_ns[3:0] = ( ({4{(flush_fb)}} & 4'b0001) | + ({4{~flush_fb & fb_right }} & {1'b0, fb_write_f[3:1]}) | + ({4{~flush_fb & fb_right2}} & {2'b0, fb_write_f[3:2]}) | + ({4{~flush_fb & fb_left }} & {fb_write_f[2:0], 1'b0}) | + ({4{~flush_fb & ~fb_right & ~fb_right2 & ~fb_left}} & fb_write_f[3:0])); + + + assign fb_full_f_ns = fb_write_ns[3]; + + assign idle = state == IDLE ; + assign wfm = state == WFM ; + + rvdffie #(10) fbwrite_ff (.*, .clk(free_l2clk), + .din( {dma_iccm_stall_any, miss_f, ifc_fetch_req_bf, next_state[1:0], fb_full_f_ns, fb_write_ns[3:0]}), + .dout({dma_iccm_stall_any_f, miss_a, ifc_fetch_req_f, state[1:0], fb_full_f, fb_write_f[3:0]})); + + assign ifu_pmu_fetch_stall = wfm | + (ifc_fetch_req_bf_raw & + ( (fb_full_f & ~(ifu_fb_consume2 | ifu_fb_consume1 | exu_flush_final)) | + dma_stall)); + + + + assign ifc_fetch_addr_bf[31:1] = fetch_addr_bf[31:1]; + + rvdffpcie #(31) faddrf1_ff (.*, .en(fetch_bf_en), .din(fetch_addr_bf[31:1]), .dout(ifc_fetch_addr_f[31:1])); + + + if (pt.ICCM_ENABLE) begin : genblock2 + logic iccm_acc_in_region_bf; + logic iccm_acc_in_range_bf; + rvrangecheck #( .CCM_SADR (pt.ICCM_SADR), + .CCM_SIZE (pt.ICCM_SIZE) ) iccm_rangecheck ( + .addr ({ifc_fetch_addr_bf[31:1],1'b0}) , + .in_range (iccm_acc_in_range_bf) , + .in_region(iccm_acc_in_region_bf) + ); + + assign ifc_iccm_access_bf = iccm_acc_in_range_bf ; + + assign ifc_dma_access_ok = ( (~ifc_iccm_access_bf | + (fb_full_f & ~(ifu_fb_consume2 | ifu_fb_consume1)) | + (wfm & ~ifc_fetch_req_bf) | + idle ) & ~exu_flush_final) | + dma_iccm_stall_any_f; + + assign ifc_region_acc_fault_bf = ~iccm_acc_in_range_bf & iccm_acc_in_region_bf ; + end + else begin + assign ifc_iccm_access_bf = 1'b0 ; + assign ifc_dma_access_ok = 1'b0 ; + assign ifc_region_acc_fault_bf = 1'b0 ; + end + + assign ifc_fetch_uncacheable_bf = ~dec_tlu_mrac_ff[{ifc_fetch_addr_bf[31:28] , 1'b0 }] ; // bit 0 of each region description is the cacheable bit + +endmodule // el2_ifu_ifc_ctl + diff --git a/designs/Caliptra/src/caliptra-rtl/el2_ifu_mem_ctl.sv b/designs/Caliptra/src/caliptra-rtl/el2_ifu_mem_ctl.sv new file mode 100644 index 0000000..1ca28c7 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/el2_ifu_mem_ctl.sv @@ -0,0 +1,1719 @@ +//******************************************************************************** +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2020 Western Digital Corporation or its affiliates. +// +// 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. +//******************************************************************************** + + +//******************************************************************************** +// Function: Icache , iccm control +// BFF -> F1 -> F2 -> A +//******************************************************************************** + +module el2_ifu_mem_ctl +import el2_pkg::*; +#( +`include "el2_param.vh" + ) + ( + input logic clk, // Clock only while core active. Through one clock header. For flops with second clock header built in. Connected to ACTIVE_L2CLK. + input logic active_clk, // Clock only while core active. Through two clock headers. For flops without second clock header built in. + input logic free_l2clk, // Clock always. Through one clock header. For flops with second header built in. + input logic rst_l, // reset, active low + + input logic exu_flush_final, // Flush from the pipeline., includes flush lower + input logic dec_tlu_flush_lower_wb, // Flush lower from the pipeline. + input logic dec_tlu_flush_err_wb, // Flush from the pipeline due to perr. + input logic dec_tlu_i0_commit_cmt, // committed i0 instruction + input logic dec_tlu_force_halt, // force halt. + + input logic [31:1] ifc_fetch_addr_bf, // Fetch Address byte aligned always. F1 stage. + input logic ifc_fetch_uncacheable_bf, // The fetch request is uncacheable space. F1 stage + input logic ifc_fetch_req_bf, // Fetch request. Comes with the address. F1 stage + input logic ifc_fetch_req_bf_raw, // Fetch request without some qualifications. Used for clock-gating. F1 stage + input logic ifc_iccm_access_bf, // This request is to the ICCM. Do not generate misses to the bus. + input logic ifc_region_acc_fault_bf, // Access fault. in ICCM region but offset is outside defined ICCM. + input logic ifc_dma_access_ok, // It is OK to give dma access to the ICCM. (ICCM is not busy this cycle). + input logic dec_tlu_fence_i_wb, // Fence.i instruction is committing. Clear all Icache valids. + input logic ifu_bp_hit_taken_f, // Branch is predicted taken. Kill the fetch next cycle. + + input logic ifu_bp_inst_mask_f, // tell ic which valids to kill because of a taken branch, right justified + + output logic ifu_miss_state_idle, // No icache misses are outstanding. + output logic ifu_ic_mb_empty, // Continue with normal fetching. This does not mean that miss is finished. + output logic ic_dma_active , // In the middle of servicing dma request to ICCM. Do not make any new requests. + output logic ic_write_stall, // Stall fetch the cycle we are writing the cache. + +/// PMU signals + output logic ifu_pmu_ic_miss, // IC miss event + output logic ifu_pmu_ic_hit, // IC hit event + output logic ifu_pmu_bus_error, // Bus error event + output logic ifu_pmu_bus_busy, // Bus busy event + output logic ifu_pmu_bus_trxn, // Bus transaction + + //-------------------------- IFU AXI signals-------------------------- + // AXI Write Channels + /* exclude signals that are tied to constant value in this file */ + /*pragma coverage off*/ + output logic ifu_axi_awvalid, + output logic [pt.IFU_BUS_TAG-1:0] ifu_axi_awid, + output logic [31:0] ifu_axi_awaddr, + output logic [3:0] ifu_axi_awregion, + output logic [7:0] ifu_axi_awlen, + output logic [2:0] ifu_axi_awsize, + output logic [1:0] ifu_axi_awburst, + output logic ifu_axi_awlock, + output logic [3:0] ifu_axi_awcache, + output logic [2:0] ifu_axi_awprot, + output logic [3:0] ifu_axi_awqos, + + output logic ifu_axi_wvalid, + output logic [63:0] ifu_axi_wdata, + output logic [7:0] ifu_axi_wstrb, + output logic ifu_axi_wlast, + + output logic ifu_axi_bready, + /*pragma coverage on*/ + + // AXI Read Channels + output logic ifu_axi_arvalid, + input logic ifu_axi_arready, + output logic [pt.IFU_BUS_TAG-1:0] ifu_axi_arid, + output logic [31:0] ifu_axi_araddr, + output logic [3:0] ifu_axi_arregion, + /* exclude signals that are tied to constant value in this file */ + /*pragma coverage off*/ + output logic [7:0] ifu_axi_arlen, + output logic [2:0] ifu_axi_arsize, + output logic [1:0] ifu_axi_arburst, + output logic ifu_axi_arlock, + output logic [3:0] ifu_axi_arcache, + output logic [2:0] ifu_axi_arprot, + output logic [3:0] ifu_axi_arqos, + /*pragma coverage on*/ + + input logic ifu_axi_rvalid, + /* exclude signals that are tied to constant value in this file */ + /*pragma coverage off*/ + output logic ifu_axi_rready, + /*pragma coverage on*/ + input logic [pt.IFU_BUS_TAG-1:0] ifu_axi_rid, + input logic [63:0] ifu_axi_rdata, + input logic [1:0] ifu_axi_rresp, + + input logic ifu_bus_clk_en, + + + input logic dma_iccm_req, // dma iccm command (read or write) + input logic [31:0] dma_mem_addr, // dma address + input logic [2:0] dma_mem_sz, // size + input logic dma_mem_write, // write + input logic [63:0] dma_mem_wdata, // write data + input logic [2:0] dma_mem_tag, // DMA Buffer entry number + + output logic iccm_dma_ecc_error,// Data read from iccm has an ecc error + output logic iccm_dma_rvalid, // Data read from iccm is valid + output logic [63:0] iccm_dma_rdata, // dma data read from iccm + output logic [2:0] iccm_dma_rtag, // Tag of the DMA req + output logic iccm_ready, // iccm ready to accept new command. + + +// I$ & ITAG Ports + output logic [31:1] ic_rw_addr, // Read/Write addresss to the Icache. + output logic [pt.ICACHE_NUM_WAYS-1:0] ic_wr_en, // Icache write enable, when filling the Icache. + output logic ic_rd_en, // Icache read enable. + + output logic [pt.ICACHE_BANKS_WAY-1:0] [70:0] ic_wr_data, // Data to fill to the Icache. With ECC + input logic [63:0] ic_rd_data , // Data read from Icache. 2x64bits + parity bits. F2 stage. With ECC + input logic [70:0] ic_debug_rd_data , // Data read from Icache. 2x64bits + parity bits. F2 stage. With ECC + input logic [25:0] ictag_debug_rd_data, // Debug icache tag. + output logic [70:0] ic_debug_wr_data, // Debug wr cache. + output logic [70:0] ifu_ic_debug_rd_data, // debug data read + + + input logic [pt.ICACHE_BANKS_WAY-1:0] ic_eccerr, // + input logic [pt.ICACHE_BANKS_WAY-1:0] ic_parerr, + + output logic [pt.ICACHE_INDEX_HI:3] ic_debug_addr, // Read/Write addresss to the Icache. + output logic ic_debug_rd_en, // Icache debug rd + output logic ic_debug_wr_en, // Icache debug wr + output logic ic_debug_tag_array, // Debug tag array + output logic [pt.ICACHE_NUM_WAYS-1:0] ic_debug_way, // Debug way. Rd or Wr. + + + output logic [pt.ICACHE_NUM_WAYS-1:0] ic_tag_valid, // Valid bits when accessing the Icache. One valid bit per way. F2 stage + + input logic [pt.ICACHE_NUM_WAYS-1:0] ic_rd_hit, // Compare hits from Icache tags. Per way. F2 stage + input logic ic_tag_perr, // Icache Tag parity error + + // ICCM ports + output logic [pt.ICCM_BITS-1:1] iccm_rw_addr, // ICCM read/write address. + output logic iccm_wren, // ICCM write enable (through the DMA) + output logic iccm_rden, // ICCM read enable. + output logic [77:0] iccm_wr_data, // ICCM write data. + output logic [2:0] iccm_wr_size, // ICCM write location within DW. + + input logic [63:0] iccm_rd_data, // Data read from ICCM. + input logic [77:0] iccm_rd_data_ecc, // Data + ECC read from ICCM. + input logic [1:0] ifu_fetch_val, + // IFU control signals + output logic ic_hit_f, // Hit in Icache(if Icache access) or ICCM access( ICCM always has ic_hit_f) + output logic [1:0] ic_access_fault_f, // Access fault (bus error or ICCM access in region but out of offset range). + output logic [1:0] ic_access_fault_type_f, // Access fault types + output logic iccm_rd_ecc_single_err, // This fetch has a single ICCM ECC error. + output logic [1:0] iccm_rd_ecc_double_err, // This fetch has a double ICCM ECC error. + output logic iccm_dma_rd_ecc_single_err, // This fetch has a single ICCM DMA ECC error. + output logic iccm_dma_rd_ecc_double_err, // This fetch has a double ICCM DMA ECC error. + output logic ic_error_start, // This has any I$ errors ( data/tag/ecc/parity ) + + output logic ifu_async_error_start, // Or of the sb iccm, and all the icache errors sent to aligner to stop + output logic iccm_dma_sb_error, // Single Bit ECC error from a DMA access + output logic [1:0] ic_fetch_val_f, // valid bytes for fetch. To the Aligner. + output logic [31:0] ic_data_f, // Data read from Icache or ICCM. To the Aligner. + output logic [63:0] ic_premux_data, // Premuxed data to be muxed with Icache data + output logic ic_sel_premux_data, // Select premux data. + +///// Debug + input el2_cache_debug_pkt_t dec_tlu_ic_diag_pkt , // Icache/tag debug read/write packet + input logic dec_tlu_core_ecc_disable, // disable the ecc checking and flagging + output logic ifu_ic_debug_rd_data_valid, // debug data valid. + output logic iccm_buf_correct_ecc, + output logic iccm_correction_state, + + input logic ifu_pmp_error, + + + // Excluding scan_mode from coverage as its usage is determined by the integrator of the VeeR core. + /*pragma coverage off*/ + input logic scan_mode + /*pragma coverage on*/ + ); + +// Create different defines for ICACHE and ICCM enable combinations + + localparam NUM_OF_BEATS = 8 ; + + + + logic [31:3] ifu_ic_req_addr_f; + logic uncacheable_miss_in ; + logic uncacheable_miss_ff; + + + + logic bus_ifu_wr_en ; + logic bus_ifu_wr_en_ff ; + logic bus_ifu_wr_en_ff_q ; + logic bus_ifu_wr_en_ff_wo_err ; + logic [pt.ICACHE_NUM_WAYS-1:0] bus_ic_wr_en ; + + logic reset_tag_valid_for_miss ; + + + logic [pt.ICACHE_STATUS_BITS-1:0] way_status; + logic [pt.ICACHE_STATUS_BITS-1:0] way_status_mb_in; + logic [pt.ICACHE_STATUS_BITS-1:0] way_status_rep_new; + logic [pt.ICACHE_STATUS_BITS-1:0] way_status_mb_ff; + logic [pt.ICACHE_STATUS_BITS-1:0] way_status_new; + logic [pt.ICACHE_STATUS_BITS-1:0] way_status_hit_new; + logic [pt.ICACHE_STATUS_BITS-1:0] way_status_new_w_debug; + logic [pt.ICACHE_NUM_WAYS-1:0] tagv_mb_in; + logic [pt.ICACHE_NUM_WAYS-1:0] tagv_mb_ff; + + + logic ifu_wr_data_comb_err ; + logic ifu_byp_data_err_new; + logic [1:0] ifu_byp_data_err_f; + logic ifu_wr_cumulative_err_data; + logic ifu_wr_cumulative_err; + logic ifu_wr_data_comb_err_ff; + logic scnd_miss_index_match ; + + + logic ifc_dma_access_q_ok; + logic ifc_iccm_access_f ; + logic ifc_region_acc_fault_f; + logic ifc_region_acc_fault_final_f; + logic [1:0] ifc_bus_acc_fault_f; + logic ic_act_miss_f; + logic ic_miss_under_miss_f; + logic ic_ignore_2nd_miss_f; + logic ic_act_hit_f; + logic miss_pending; + logic [31:1] imb_in , imb_ff ; + logic [31:pt.ICACHE_BEAT_ADDR_HI+1] miss_addr_in , miss_addr ; + logic miss_wrap_f ; + logic flush_final_f; + logic ifc_fetch_req_f; + logic ifc_fetch_req_f_raw; + logic fetch_req_f_qual ; + logic ifc_fetch_req_qual_bf ; + logic [pt.ICACHE_NUM_WAYS-1:0] replace_way_mb_any; + logic last_beat; + logic reset_beat_cnt ; + logic [pt.ICACHE_BEAT_ADDR_HI:3] ic_req_addr_bits_hi_3 ; + logic [pt.ICACHE_BEAT_ADDR_HI:3] ic_wr_addr_bits_hi_3 ; + logic [31:1] ifu_fetch_addr_int_f ; + logic [31:1] ifu_ic_rw_int_addr ; + logic crit_wd_byp_ok_ff ; + logic ic_crit_wd_rdy_new_ff; + logic [79:0] ic_byp_data_only_pre_new; + logic [79:0] ic_byp_data_only_new; + logic ic_byp_hit_f ; + logic ic_valid ; + logic ic_valid_ff; + logic reset_all_tags; + logic ic_valid_w_debug; + + logic [pt.ICACHE_NUM_WAYS-1:0] ifu_tag_wren,ifu_tag_wren_ff; + logic [pt.ICACHE_NUM_WAYS-1:0] ic_debug_tag_wr_en; + logic [pt.ICACHE_NUM_WAYS-1:0] ifu_tag_wren_w_debug; + logic [pt.ICACHE_NUM_WAYS-1:0] ic_debug_way_ff; + logic ic_debug_rd_en_ff ; + logic fetch_bf_f_c1_clken ; + logic fetch_bf_f_c1_clk; + logic debug_c1_clken; + logic debug_c1_clk; + + logic reset_ic_in ; + logic reset_ic_ff ; + logic [pt.ICACHE_BEAT_ADDR_HI:1] vaddr_f ; + logic [31:1] ifu_status_wr_addr; + logic sel_mb_addr ; + logic sel_mb_addr_ff ; + logic sel_mb_status_addr ; + logic [63:0] ic_final_data; + + logic [pt.ICACHE_STATUS_BITS-1:0] way_status_new_ff ; + logic way_status_wr_en_ff ; + logic [pt.ICACHE_TAG_DEPTH-1:0][pt.ICACHE_STATUS_BITS-1:0] way_status_out ; + logic [1:0] ic_debug_way_enc; + + logic [pt.IFU_BUS_TAG-1:0] ifu_bus_rid_ff; + + logic fetch_req_icache_f; + logic fetch_req_iccm_f; + logic ic_iccm_hit_f; + logic fetch_uncacheable_ff; + logic way_status_wr_en; + logic sel_byp_data; + logic sel_ic_data; + logic sel_iccm_data; + logic ic_rd_parity_final_err; + logic ic_act_miss_f_delayed; + logic bus_ifu_wr_data_error; + logic bus_ifu_wr_data_error_ff; + logic way_status_wr_en_w_debug; + logic ic_debug_tag_val_rd_out; + logic ifu_pmu_ic_miss_in; + logic ifu_pmu_ic_hit_in; + logic ifu_pmu_bus_error_in; + logic ifu_pmu_bus_trxn_in; + logic ifu_pmu_bus_busy_in; + logic ic_debug_ict_array_sel_in; + logic ic_debug_ict_array_sel_ff; + logic debug_data_clken; + logic last_data_recieved_in ; + logic last_data_recieved_ff ; + + logic ifu_bus_rvalid ; + logic ifu_bus_rvalid_ff ; + logic ifu_bus_rvalid_unq_ff ; + logic ifu_bus_arready_unq ; + logic ifu_bus_arready_unq_ff ; + logic ifu_bus_arvalid ; + logic ifu_bus_arvalid_ff ; + logic ifu_bus_arready ; + logic ifu_bus_arready_ff ; + logic [63:0] ifu_bus_rdata_ff ; + logic [1:0] ifu_bus_rresp_ff ; + logic ifu_bus_rsp_valid ; + logic ifu_bus_rsp_ready ; + logic [pt.IFU_BUS_TAG-1:0] ifu_bus_rsp_tag; + logic [63:0] ifu_bus_rsp_rdata; + logic [1:0] ifu_bus_rsp_opc; + + logic [pt.ICACHE_NUM_BEATS-1:0] write_fill_data; + logic [pt.ICACHE_NUM_BEATS-1:0] wr_data_c1_clk; + logic [pt.ICACHE_NUM_BEATS-1:0] ic_miss_buff_data_valid_in; + logic [pt.ICACHE_NUM_BEATS-1:0] ic_miss_buff_data_valid; + logic [pt.ICACHE_NUM_BEATS-1:0] ic_miss_buff_data_error_in; + logic [pt.ICACHE_NUM_BEATS-1:0] ic_miss_buff_data_error; + logic [pt.ICACHE_BEAT_ADDR_HI:1] byp_fetch_index; + logic [pt.ICACHE_BEAT_ADDR_HI:2] byp_fetch_index_0; + logic [pt.ICACHE_BEAT_ADDR_HI:2] byp_fetch_index_1; + logic [pt.ICACHE_BEAT_ADDR_HI:3] byp_fetch_index_inc; + logic [pt.ICACHE_BEAT_ADDR_HI:2] byp_fetch_index_inc_0; + logic [pt.ICACHE_BEAT_ADDR_HI:2] byp_fetch_index_inc_1; + logic miss_buff_hit_unq_f ; + logic stream_hit_f ; + logic stream_miss_f ; + logic stream_eol_f ; + logic crit_byp_hit_f ; + logic [pt.IFU_BUS_TAG-1:0] other_tag ; + logic [(2*pt.ICACHE_NUM_BEATS)-1:0] [31:0] ic_miss_buff_data; + logic [63:0] ic_miss_buff_half; + logic scnd_miss_req, scnd_miss_req_q; + logic scnd_miss_req_in; + + + logic [pt.ICCM_BITS-1:2] iccm_ecc_corr_index_ff; + logic [pt.ICCM_BITS-1:2] iccm_ecc_corr_index_in; + logic [38:0] iccm_ecc_corr_data_ff; + logic iccm_ecc_write_status ; + logic iccm_rd_ecc_single_err_ff ; + logic iccm_error_start; // start the error fsm + logic perr_state_en; + logic miss_state_en; + + logic busclk; + logic busclk_force; + logic busclk_reset; + logic bus_ifu_bus_clk_en_ff; + logic bus_ifu_bus_clk_en ; + + logic ifc_bus_ic_req_ff_in; + logic ifu_bus_cmd_valid ; + logic ifu_bus_cmd_ready ; + + logic bus_inc_data_beat_cnt ; + logic bus_reset_data_beat_cnt ; + logic bus_hold_data_beat_cnt ; + + logic bus_inc_cmd_beat_cnt ; + logic bus_reset_cmd_beat_cnt_0 ; + logic bus_reset_cmd_beat_cnt_secondlast ; + logic bus_hold_cmd_beat_cnt ; + + logic [pt.ICACHE_BEAT_BITS-1:0] bus_new_data_beat_count ; + logic [pt.ICACHE_BEAT_BITS-1:0] bus_data_beat_count ; + + logic [pt.ICACHE_BEAT_BITS-1:0] bus_new_cmd_beat_count ; + logic [pt.ICACHE_BEAT_BITS-1:0] bus_cmd_beat_count ; + + + logic [pt.ICACHE_BEAT_BITS-1:0] bus_new_rd_addr_count; + logic [pt.ICACHE_BEAT_BITS-1:0] bus_rd_addr_count; + + + logic bus_cmd_sent ; + logic bus_last_data_beat ; + + + logic [pt.ICACHE_NUM_WAYS-1:0] bus_wren ; + + logic [pt.ICACHE_NUM_WAYS-1:0] bus_wren_last ; + logic [pt.ICACHE_NUM_WAYS-1:0] wren_reset_miss ; + logic ifc_dma_access_ok_d; + logic ifc_dma_access_ok_prev; + + logic bus_cmd_req_in ; + logic bus_cmd_req_hold ; + + logic second_half_available ; + logic write_ic_16_bytes ; + + logic ifc_region_acc_fault_final_bf; + logic ifc_region_acc_fault_memory_bf; + logic ifc_region_acc_fault_memory_f; + logic ifc_region_acc_okay; + + logic iccm_correct_ecc; + logic dma_sb_err_state, dma_sb_err_state_ff; + logic two_byte_instr; + + typedef enum logic [2:0] {IDLE=3'b000, CRIT_BYP_OK=3'b001, HIT_U_MISS=3'b010, MISS_WAIT=3'b011,CRIT_WRD_RDY=3'b100,SCND_MISS=3'b101,STREAM=3'b110 , STALL_SCND_MISS=3'b111} miss_state_t; + miss_state_t miss_state, miss_nxtstate; + + typedef enum logic [1:0] {ERR_STOP_IDLE=2'b00, ERR_FETCH1=2'b01 , ERR_FETCH2=2'b10 , ERR_STOP_FETCH=2'b11} err_stop_state_t; + err_stop_state_t err_stop_state, err_stop_nxtstate; + logic err_stop_state_en ; + logic err_stop_fetch ; + + logic ic_crit_wd_rdy; // Critical fetch is ready to be bypassed. + + logic ifu_bp_hit_taken_q_f; + logic ifu_bus_rvalid_unq; + logic bus_cmd_beat_en; + + +// ---- Clock gating section ----- +// c1 clock enables + + + assign fetch_bf_f_c1_clken = ifc_fetch_req_bf_raw | ifc_fetch_req_f | miss_pending | exu_flush_final | scnd_miss_req; + assign debug_c1_clken = ic_debug_rd_en | ic_debug_wr_en ; + // C1 - 1 clock pulse for data +`ifdef RV_FPGA_OPTIMIZE + assign fetch_bf_f_c1_clk = 1'b0; + assign debug_c1_clk = 1'b0; +`else + rvclkhdr fetch_bf_f_c1_cgc ( .en(fetch_bf_f_c1_clken), .l1clk(fetch_bf_f_c1_clk), .* ); + rvclkhdr debug_c1_cgc ( .en(debug_c1_clken), .l1clk(debug_c1_clk), .* ); +`endif + + +// ------ end clock gating section ------------------------ + + logic [1:0] iccm_single_ecc_error; + logic dma_iccm_req_f ; + assign iccm_dma_sb_error = (|iccm_single_ecc_error[1:0] ) & dma_iccm_req_f ; + assign ifu_async_error_start = iccm_rd_ecc_single_err | ic_error_start; + + + typedef enum logic [2:0] {ERR_IDLE=3'b000, IC_WFF=3'b001 , ECC_WFF=3'b010 , ECC_CORR=3'b011, DMA_SB_ERR=3'b100} perr_state_t; + perr_state_t perr_state, perr_nxtstate; + + + assign ic_dma_active = iccm_correct_ecc | (perr_state == DMA_SB_ERR) | (err_stop_state == ERR_STOP_FETCH) | err_stop_fetch | + dec_tlu_flush_err_wb; // The last term is to give a error-correction a chance to finish before refetch starts + + assign scnd_miss_req_in = ifu_bus_rsp_valid & bus_ifu_bus_clk_en & ifu_bus_rsp_ready & + (&bus_new_data_beat_count[pt.ICACHE_BEAT_BITS-1:0]) & + ~uncacheable_miss_ff & ((miss_state == SCND_MISS) | (miss_nxtstate == SCND_MISS)) & ~exu_flush_final; + + assign ifu_bp_hit_taken_q_f = ifu_bp_hit_taken_f & ic_hit_f ; + + //////////////////////////////////// Create Miss State Machine /////////////////////// + // Create Miss State Machine // + // Create Miss State Machine // + // Create Miss State Machine // + //////////////////////////////////// Create Miss State Machine /////////////////////// + // FIFO state machine + always_comb begin : MISS_SM + miss_nxtstate = IDLE; + miss_state_en = 1'b0; + case (miss_state) + IDLE: begin : idle + miss_nxtstate = (ic_act_miss_f & ~exu_flush_final) ? CRIT_BYP_OK : HIT_U_MISS ; + miss_state_en = ic_act_miss_f & ~dec_tlu_force_halt ; + end + CRIT_BYP_OK: begin : crit_byp_ok + miss_nxtstate = (dec_tlu_force_halt ) ? IDLE : + ( ic_byp_hit_f & (last_data_recieved_ff | (bus_ifu_wr_en_ff & last_beat)) & uncacheable_miss_ff) ? IDLE : + ( ic_byp_hit_f & ~last_data_recieved_ff & uncacheable_miss_ff) ? MISS_WAIT : + (~ic_byp_hit_f & ~exu_flush_final & (bus_ifu_wr_en_ff & last_beat) & uncacheable_miss_ff) ? CRIT_WRD_RDY : + ( (bus_ifu_wr_en_ff & last_beat) & ~uncacheable_miss_ff) ? IDLE : + ( ic_byp_hit_f & ~exu_flush_final & ~(bus_ifu_wr_en_ff & last_beat) & ~ifu_bp_hit_taken_q_f & ~uncacheable_miss_ff) ? STREAM : + ( bus_ifu_wr_en_ff & ~exu_flush_final & ~(bus_ifu_wr_en_ff & last_beat) & ~ifu_bp_hit_taken_q_f & ~uncacheable_miss_ff) ? STREAM : + (~ic_byp_hit_f & ~exu_flush_final & (bus_ifu_wr_en_ff & last_beat) & ~uncacheable_miss_ff) ? IDLE : + ( (exu_flush_final | ifu_bp_hit_taken_q_f) & ~(bus_ifu_wr_en_ff & last_beat) ) ? HIT_U_MISS : IDLE; + miss_state_en = dec_tlu_force_halt | exu_flush_final | ic_byp_hit_f | ifu_bp_hit_taken_q_f | (bus_ifu_wr_en_ff & last_beat) | (bus_ifu_wr_en_ff & ~uncacheable_miss_ff) ; + end + CRIT_WRD_RDY: begin : crit_wrd_rdy + miss_nxtstate = IDLE ; + miss_state_en = exu_flush_final | flush_final_f | ic_byp_hit_f | dec_tlu_force_halt ; + end + STREAM: begin : stream + miss_nxtstate = ((exu_flush_final | ifu_bp_hit_taken_q_f | stream_eol_f ) & ~(bus_ifu_wr_en_ff & last_beat) & ~dec_tlu_force_halt) ? HIT_U_MISS : IDLE ; + miss_state_en = exu_flush_final | ifu_bp_hit_taken_q_f | stream_eol_f | (bus_ifu_wr_en_ff & last_beat) | dec_tlu_force_halt ; + end + MISS_WAIT: begin : miss_wait + miss_nxtstate = (exu_flush_final & ~(bus_ifu_wr_en_ff & last_beat) & ~dec_tlu_force_halt) ? HIT_U_MISS : IDLE ; + miss_state_en = exu_flush_final | (bus_ifu_wr_en_ff & last_beat) | dec_tlu_force_halt ; + end + HIT_U_MISS: begin : hit_u_miss + miss_nxtstate = ic_miss_under_miss_f & ~(bus_ifu_wr_en_ff & last_beat) & ~dec_tlu_force_halt ? SCND_MISS : + ic_ignore_2nd_miss_f & ~(bus_ifu_wr_en_ff & last_beat) & ~dec_tlu_force_halt ? STALL_SCND_MISS : IDLE ; + miss_state_en = (bus_ifu_wr_en_ff & last_beat) | ic_miss_under_miss_f | ic_ignore_2nd_miss_f | dec_tlu_force_halt; + end + SCND_MISS: begin : scnd_miss + miss_nxtstate = dec_tlu_force_halt ? IDLE : + exu_flush_final ? ((bus_ifu_wr_en_ff & last_beat) ? IDLE : HIT_U_MISS) : CRIT_BYP_OK; + miss_state_en = (bus_ifu_wr_en_ff & last_beat) | exu_flush_final | dec_tlu_force_halt; + end + STALL_SCND_MISS: begin : stall_scnd_miss + miss_nxtstate = dec_tlu_force_halt ? IDLE : + exu_flush_final ? ((bus_ifu_wr_en_ff & last_beat) ? IDLE : HIT_U_MISS) : IDLE; + miss_state_en = (bus_ifu_wr_en_ff & last_beat) | exu_flush_final | dec_tlu_force_halt; + end + /*pragma coverage off*/ + default: begin : def_case + miss_nxtstate = IDLE; + miss_state_en = 1'b0; + end + /*pragma coverage on*/ + endcase + end + rvdffs #(($bits(miss_state_t))) miss_state_ff (.clk(active_clk), .din(miss_nxtstate), .dout({miss_state}), .en(miss_state_en), .*); + + logic sel_hold_imb ; + + assign miss_pending = (miss_state != IDLE) ; + assign crit_wd_byp_ok_ff = (miss_state == CRIT_BYP_OK) | ((miss_state == CRIT_WRD_RDY) & ~flush_final_f); + assign sel_hold_imb = (miss_pending & ~(bus_ifu_wr_en_ff & last_beat) & ~((miss_state == CRIT_WRD_RDY) & exu_flush_final) & + ~((miss_state == CRIT_WRD_RDY) & crit_byp_hit_f) ) | ic_act_miss_f | + (miss_pending & (miss_nxtstate == CRIT_WRD_RDY)) ; + + + logic sel_hold_imb_scnd; + logic [31:1] imb_scnd_in; + logic [31:1] imb_scnd_ff; + logic uncacheable_miss_scnd_in ; + logic uncacheable_miss_scnd_ff ; + + logic [pt.ICACHE_NUM_WAYS-1:0] tagv_mb_scnd_in; + logic [pt.ICACHE_NUM_WAYS-1:0] tagv_mb_scnd_ff; + + logic [pt.ICACHE_STATUS_BITS-1:0] way_status_mb_scnd_in; + logic [pt.ICACHE_STATUS_BITS-1:0] way_status_mb_scnd_ff; + + assign sel_hold_imb_scnd =((miss_state == SCND_MISS) | ic_miss_under_miss_f) & ~flush_final_f ; + assign way_status_mb_scnd_in[pt.ICACHE_STATUS_BITS-1:0] = (miss_state == SCND_MISS) ? way_status_mb_scnd_ff[pt.ICACHE_STATUS_BITS-1:0] : {way_status[pt.ICACHE_STATUS_BITS-1:0]} ; + assign tagv_mb_scnd_in[pt.ICACHE_NUM_WAYS-1:0] = (miss_state == SCND_MISS) ? tagv_mb_scnd_ff[pt.ICACHE_NUM_WAYS-1:0] : ({ic_tag_valid[pt.ICACHE_NUM_WAYS-1:0]} & {pt.ICACHE_NUM_WAYS{~reset_all_tags & ~exu_flush_final}}); + assign uncacheable_miss_scnd_in = sel_hold_imb_scnd ? uncacheable_miss_scnd_ff : ifc_fetch_uncacheable_bf ; + + + rvdff_fpga #(1) unc_miss_scnd_ff (.*, .clk(fetch_bf_f_c1_clk), .clken(fetch_bf_f_c1_clken), .rawclk(clk), .din (uncacheable_miss_scnd_in), .dout(uncacheable_miss_scnd_ff)); + rvdffpcie #(31) imb_f_scnd_ff (.*, .en(fetch_bf_f_c1_clken), .din ({imb_scnd_in[31:1]}), .dout({imb_scnd_ff[31:1]})); + rvdff_fpga #(pt.ICACHE_STATUS_BITS) mb_rep_wayf2_scnd_ff (.*, .clk(fetch_bf_f_c1_clk), .clken(fetch_bf_f_c1_clken), .rawclk(clk), .din ({way_status_mb_scnd_in[pt.ICACHE_STATUS_BITS-1:0]}), .dout({way_status_mb_scnd_ff[pt.ICACHE_STATUS_BITS-1:0]})); + rvdff_fpga #(pt.ICACHE_NUM_WAYS) mb_tagv_scnd_ff (.*, .clk(fetch_bf_f_c1_clk), .clken(fetch_bf_f_c1_clken), .rawclk(clk), .din ({tagv_mb_scnd_in[pt.ICACHE_NUM_WAYS-1:0]}), .dout({tagv_mb_scnd_ff[pt.ICACHE_NUM_WAYS-1:0]})); + + + + + assign ic_req_addr_bits_hi_3[pt.ICACHE_BEAT_ADDR_HI:3] = bus_rd_addr_count[pt.ICACHE_BEAT_BITS-1:0] ; + assign ic_wr_addr_bits_hi_3[pt.ICACHE_BEAT_ADDR_HI:3] = ifu_bus_rid_ff[pt.ICACHE_BEAT_BITS-1:0] & {pt.ICACHE_BEAT_BITS{bus_ifu_wr_en_ff}}; + // NOTE: Cacheline size is 16 bytes in this example. + // Tag Index Bank Offset + // [31:16] [15:5] [4] [3:0] + + + assign fetch_req_icache_f = ifc_fetch_req_f & ~ifc_iccm_access_f & ~ifc_region_acc_fault_final_f; + assign fetch_req_iccm_f = ifc_fetch_req_f & ifc_iccm_access_f; + + assign ic_iccm_hit_f = fetch_req_iccm_f & (~miss_pending | (miss_state==HIT_U_MISS) | (miss_state==STREAM)); + assign ic_byp_hit_f = (crit_byp_hit_f | stream_hit_f) & fetch_req_icache_f & miss_pending ; + assign ic_act_hit_f = (|ic_rd_hit[pt.ICACHE_NUM_WAYS-1:0]) & fetch_req_icache_f & ~reset_all_tags & (~miss_pending | (miss_state==HIT_U_MISS)) & ~sel_mb_addr_ff; + assign ic_act_miss_f = (((~(|ic_rd_hit[pt.ICACHE_NUM_WAYS-1:0]) | reset_all_tags) & fetch_req_icache_f & ~miss_pending) | scnd_miss_req) & ~ifc_region_acc_fault_final_f; + assign ic_miss_under_miss_f = (~(|ic_rd_hit[pt.ICACHE_NUM_WAYS-1:0]) | reset_all_tags) & fetch_req_icache_f & (miss_state == HIT_U_MISS) & + (imb_ff[31:pt.ICACHE_TAG_INDEX_LO] != ifu_fetch_addr_int_f[31:pt.ICACHE_TAG_INDEX_LO]) & ~uncacheable_miss_ff & ~sel_mb_addr_ff & ~ifc_region_acc_fault_final_f; + assign ic_ignore_2nd_miss_f = (~(|ic_rd_hit[pt.ICACHE_NUM_WAYS-1:0]) | reset_all_tags) & fetch_req_icache_f & (miss_state == HIT_U_MISS) & + ((imb_ff[31:pt.ICACHE_TAG_INDEX_LO] == ifu_fetch_addr_int_f[31:pt.ICACHE_TAG_INDEX_LO]) | uncacheable_miss_ff) ; + assign ic_hit_f = ic_act_hit_f | ic_byp_hit_f | ic_iccm_hit_f | (ifc_region_acc_fault_final_f & ifc_fetch_req_f); + + assign uncacheable_miss_in = scnd_miss_req ? uncacheable_miss_scnd_ff : sel_hold_imb ? uncacheable_miss_ff : ifc_fetch_uncacheable_bf ; + assign imb_in[31:1] = scnd_miss_req ? imb_scnd_ff[31:1] : sel_hold_imb ? imb_ff[31:1] : {ifc_fetch_addr_bf[31:1]} ; + + assign imb_scnd_in[31:1] = sel_hold_imb_scnd ? imb_scnd_ff[31:1] : {ifc_fetch_addr_bf[31:1]} ; + + assign scnd_miss_index_match = (imb_ff[pt.ICACHE_INDEX_HI:pt.ICACHE_TAG_INDEX_LO] == imb_scnd_ff[pt.ICACHE_INDEX_HI:pt.ICACHE_TAG_INDEX_LO]) & scnd_miss_req & ~ifu_wr_cumulative_err_data; + assign way_status_mb_in[pt.ICACHE_STATUS_BITS-1:0] = (scnd_miss_req & ~scnd_miss_index_match) ? way_status_mb_scnd_ff[pt.ICACHE_STATUS_BITS-1:0] : + (scnd_miss_req & scnd_miss_index_match) ? way_status_rep_new[pt.ICACHE_STATUS_BITS-1:0] : + miss_pending ? way_status_mb_ff[pt.ICACHE_STATUS_BITS-1:0] : + {way_status[pt.ICACHE_STATUS_BITS-1:0]} ; + assign tagv_mb_in[pt.ICACHE_NUM_WAYS-1:0] = scnd_miss_req ? (tagv_mb_scnd_ff[pt.ICACHE_NUM_WAYS-1:0] | ({pt.ICACHE_NUM_WAYS {scnd_miss_index_match}} & replace_way_mb_any[pt.ICACHE_NUM_WAYS-1:0])) : + miss_pending ? tagv_mb_ff[pt.ICACHE_NUM_WAYS-1:0] : ({ic_tag_valid[pt.ICACHE_NUM_WAYS-1:0]} & {pt.ICACHE_NUM_WAYS{~reset_all_tags & ~exu_flush_final}}) ; + + assign reset_ic_in = miss_pending & ~scnd_miss_req_q & (reset_all_tags | reset_ic_ff) ; + + + + rvdffpcie #(31) ifu_fetch_addr_f_ff (.*, .en(fetch_bf_f_c1_clken), .din ({ifc_fetch_addr_bf[31:1]}), .dout({ifu_fetch_addr_int_f[31:1]})); + + assign vaddr_f[pt.ICACHE_BEAT_ADDR_HI:1] = ifu_fetch_addr_int_f[pt.ICACHE_BEAT_ADDR_HI:1] ; + + rvdffpcie #(31) imb_f_ff (.*, .en(fetch_bf_f_c1_clken), .din (imb_in[31:1]), .dout(imb_ff[31:1])); + rvdff_fpga #(1) unc_miss_ff (.*, .clk(fetch_bf_f_c1_clk), .clken(fetch_bf_f_c1_clken), .rawclk(clk), .din ( uncacheable_miss_in), .dout( uncacheable_miss_ff)); + + + assign miss_addr_in[31:pt.ICACHE_BEAT_ADDR_HI+1] = (~miss_pending ) ? imb_ff[31:pt.ICACHE_BEAT_ADDR_HI+1] : + ( scnd_miss_req_q ) ? imb_scnd_ff[31:pt.ICACHE_BEAT_ADDR_HI+1] : miss_addr[31:pt.ICACHE_BEAT_ADDR_HI+1] ; + + + rvdfflie #(.WIDTH(31-pt.ICACHE_BEAT_ADDR_HI),.LEFT(31-pt.ICACHE_BEAT_ADDR_HI-8)) miss_f_ff (.*, .en(bus_ifu_bus_clk_en | ic_act_miss_f | dec_tlu_force_halt), .din ({miss_addr_in[31:pt.ICACHE_BEAT_ADDR_HI+1]}), .dout({miss_addr[31:pt.ICACHE_BEAT_ADDR_HI+1]})); + + + + + + rvdff_fpga #(pt.ICACHE_STATUS_BITS) mb_rep_wayf2_ff (.*, .clk(fetch_bf_f_c1_clk), .clken(fetch_bf_f_c1_clken), .rawclk(clk), .din ({way_status_mb_in[pt.ICACHE_STATUS_BITS-1:0]}), .dout({way_status_mb_ff[pt.ICACHE_STATUS_BITS-1:0]})); + rvdff_fpga #(pt.ICACHE_NUM_WAYS) mb_tagv_ff (.*, .clk(fetch_bf_f_c1_clk), .clken(fetch_bf_f_c1_clken), .rawclk(clk), .din ({tagv_mb_in[pt.ICACHE_NUM_WAYS-1:0]}), .dout({tagv_mb_ff[pt.ICACHE_NUM_WAYS-1:0]})); + + assign ifc_fetch_req_qual_bf = ifc_fetch_req_bf & ~((miss_state == CRIT_WRD_RDY) & flush_final_f) & ~stream_miss_f ;// & ~exu_flush_final ; + + assign ifc_fetch_req_f = ifc_fetch_req_f_raw & ~exu_flush_final ; + + rvdff_fpga #(1) ifu_iccm_acc_ff (.*, .clk(fetch_bf_f_c1_clk), .clken(fetch_bf_f_c1_clken), .rawclk(clk), .din(ifc_iccm_access_bf), .dout(ifc_iccm_access_f)); + rvdff_fpga #(1) ifu_iccm_reg_acc_ff (.*, .clk(fetch_bf_f_c1_clk), .clken(fetch_bf_f_c1_clken), .rawclk(clk), .din(ifc_region_acc_fault_final_bf), .dout(ifc_region_acc_fault_final_f)); + rvdff_fpga #(1) rgn_acc_ff (.*, .clk(fetch_bf_f_c1_clk), .clken(fetch_bf_f_c1_clken), .rawclk(clk), .din(ifc_region_acc_fault_bf), .dout(ifc_region_acc_fault_f)); + + + assign ifu_ic_req_addr_f[31:3] = {miss_addr[31:pt.ICACHE_BEAT_ADDR_HI+1] , ic_req_addr_bits_hi_3[pt.ICACHE_BEAT_ADDR_HI:3] }; + assign ifu_ic_mb_empty = (((miss_state == HIT_U_MISS) | (miss_state == STREAM)) & ~(bus_ifu_wr_en_ff & last_beat)) | ~miss_pending ; + assign ifu_miss_state_idle = (miss_state == IDLE) ; + + + assign sel_mb_addr = ((miss_pending & write_ic_16_bytes & ~uncacheable_miss_ff) | reset_tag_valid_for_miss) ; + assign ifu_ic_rw_int_addr[31:1] = ({31{ sel_mb_addr}} & {imb_ff[31:pt.ICACHE_BEAT_ADDR_HI+1] , ic_wr_addr_bits_hi_3[pt.ICACHE_BEAT_ADDR_HI:3] , imb_ff[2:1]}) | + ({31{~sel_mb_addr}} & ifc_fetch_addr_bf[31:1] ) ; + + assign sel_mb_status_addr = ((miss_pending & write_ic_16_bytes & ~uncacheable_miss_ff & last_beat & bus_ifu_wr_en_ff_q) | reset_tag_valid_for_miss) ; + assign ifu_status_wr_addr[31:1] = ({31{ sel_mb_status_addr}} & {imb_ff[31:pt.ICACHE_BEAT_ADDR_HI+1] , ic_wr_addr_bits_hi_3[pt.ICACHE_BEAT_ADDR_HI:3] , imb_ff[2:1]}) | + ({31{~sel_mb_status_addr}} & ifu_fetch_addr_int_f[31:1] ) ; + + + assign ic_rw_addr[31:1] = ifu_ic_rw_int_addr[31:1] ; + + +if (pt.ICACHE_ECC == 1) begin: icache_ecc_1 + logic [6:0] ic_wr_ecc; + logic [6:0] ic_miss_buff_ecc; + logic [141:0] ic_wr_16bytes_data ; + logic [70:0] ifu_ic_debug_rd_data_in ; + + rvecc_encode_64 ic_ecc_encode_64_bus ( + .din (ifu_bus_rdata_ff[63:0]), + .ecc_out(ic_wr_ecc[6:0])); + rvecc_encode_64 ic_ecc_encode_64_buff ( + .din (ic_miss_buff_half[63:0]), + .ecc_out(ic_miss_buff_ecc[6:0])); + + for (genvar i=0; i < pt.ICACHE_BANKS_WAY ; i++) begin : ic_wr_data_loop + assign ic_wr_data[i][70:0] = ic_wr_16bytes_data[((71*i)+70): (71*i)]; + end + + + assign ic_debug_wr_data[70:0] = {dec_tlu_ic_diag_pkt.icache_wrdata[70:0]} ; + assign ic_error_start = ((|ic_eccerr[pt.ICACHE_BANKS_WAY-1:0]) & ic_act_hit_f) | ic_rd_parity_final_err; + + + + assign ifu_ic_debug_rd_data_in[70:0] = ic_debug_ict_array_sel_ff ? {2'b0,ictag_debug_rd_data[25:21],32'b0,ictag_debug_rd_data[20:0],{7-pt.ICACHE_STATUS_BITS{1'b0}}, way_status[pt.ICACHE_STATUS_BITS-1:0],3'b0,ic_debug_tag_val_rd_out} : + ic_debug_rd_data[70:0]; + + rvdffe #(71) ifu_debug_data_ff (.*, + .en (debug_data_clken), + .din ({ + ifu_ic_debug_rd_data_in[70:0] + }), + .dout({ + ifu_ic_debug_rd_data[70:0] + }) + ); + + assign ic_wr_16bytes_data[141:0] = ifu_bus_rid_ff[0] ? {ic_wr_ecc[6:0] , ifu_bus_rdata_ff[63:0] , ic_miss_buff_ecc[6:0] , ic_miss_buff_half[63:0] } : + {ic_miss_buff_ecc[6:0] , ic_miss_buff_half[63:0] , ic_wr_ecc[6:0] , ifu_bus_rdata_ff[63:0] } ; + + +end +else begin : icache_parity_1 + logic [3:0] ic_wr_parity; + logic [3:0] ic_miss_buff_parity; + logic [135:0] ic_wr_16bytes_data ; + logic [70:0] ifu_ic_debug_rd_data_in ; + for (genvar i=0 ; i < 4 ; i++) begin : DATA_PGEN + rveven_paritygen #(16) par_bus (.data_in (ifu_bus_rdata_ff[((16*i)+15):(16*i)]), + .parity_out(ic_wr_parity[i])); + rveven_paritygen #(16) par_buff (.data_in (ic_miss_buff_half[((16*i)+15):(16*i)]), + .parity_out(ic_miss_buff_parity[i])); + end + + + for (genvar i=0; i < pt.ICACHE_BANKS_WAY ; i++) begin : ic_wr_data_loop + assign ic_wr_data[i][70:0] = {3'b0, ic_wr_16bytes_data[((68*i)+67): (68*i)]}; + end + + + + + + assign ic_debug_wr_data[70:0] = {dec_tlu_ic_diag_pkt.icache_wrdata[70:0]} ; + assign ic_error_start = ((|ic_parerr[pt.ICACHE_BANKS_WAY-1:0]) & ic_act_hit_f) | ic_rd_parity_final_err; + + assign ifu_ic_debug_rd_data_in[70:0] = ic_debug_ict_array_sel_ff ? {6'b0,ictag_debug_rd_data[21],32'b0,ictag_debug_rd_data[20:0],{7-pt.ICACHE_STATUS_BITS{1'b0}},way_status[pt.ICACHE_STATUS_BITS-1:0],3'b0,ic_debug_tag_val_rd_out} : + ic_debug_rd_data[70:0] ; + + rvdffe #(71) ifu_debug_data_ff (.*, + .en (debug_data_clken), + .din ({ + ifu_ic_debug_rd_data_in[70:0] + }), + .dout({ + ifu_ic_debug_rd_data[70:0] + }) + ); + + assign ic_wr_16bytes_data[135:0] = ifu_bus_rid_ff[0] ? {ic_wr_parity[3:0] , ifu_bus_rdata_ff[63:0] , ic_miss_buff_parity[3:0] , ic_miss_buff_half[63:0] } : + {ic_miss_buff_parity[3:0] , ic_miss_buff_half[63:0] , ic_wr_parity[3:0] , ifu_bus_rdata_ff[63:0] } ; + +end + + + assign ifu_wr_data_comb_err = bus_ifu_wr_data_error_ff ; + assign ifu_wr_cumulative_err = (ifu_wr_data_comb_err | ifu_wr_data_comb_err_ff) & ~reset_beat_cnt; + assign ifu_wr_cumulative_err_data = ifu_wr_data_comb_err | ifu_wr_data_comb_err_ff ; + + + assign sel_byp_data = (ic_crit_wd_rdy | (miss_state == STREAM) | (miss_state == CRIT_BYP_OK)); + assign sel_ic_data = ~(ic_crit_wd_rdy | (miss_state == STREAM) | (miss_state == CRIT_BYP_OK) | (miss_state == MISS_WAIT)) & ~fetch_req_iccm_f & ~ifc_region_acc_fault_final_f; + + if (pt.ICCM_ICACHE==1) begin: iccm_icache + assign sel_iccm_data = fetch_req_iccm_f ; + + assign ic_final_data[63:0] = ({64{sel_byp_data | sel_iccm_data | sel_ic_data}} & {ic_rd_data[63:0]} ) ; + + assign ic_premux_data[63:0] = ({64{sel_byp_data }} & {ic_byp_data_only_new[63:0]} ) | + ({64{sel_iccm_data}} & {iccm_rd_data[63:0]}); + + assign ic_sel_premux_data = sel_iccm_data | sel_byp_data ; + end + +if (pt.ICCM_ONLY == 1 ) begin: iccm_only + assign sel_iccm_data = fetch_req_iccm_f ; + assign ic_final_data[63:0] = ({64{sel_byp_data }} & {ic_byp_data_only_new[63:0]} ) | + ({64{sel_iccm_data}} & {iccm_rd_data[63:0]}); + assign ic_premux_data = '0 ; + assign ic_sel_premux_data = '0 ; +end + +if (pt.ICACHE_ONLY == 1 ) begin: icache_only + assign ic_final_data[63:0] = ({64{sel_byp_data | sel_ic_data}} & {ic_rd_data[63:0]} ) ; + assign ic_premux_data[63:0] = ({64{sel_byp_data }} & {ic_byp_data_only_new[63:0]} ) ; + assign ic_sel_premux_data = sel_byp_data ; +end + + +if (pt.NO_ICCM_NO_ICACHE == 1 ) begin: no_iccm_no_icache + assign ic_final_data[63:0] = ({64{sel_byp_data }} & {ic_byp_data_only_new[63:0]} ) ; + assign ic_premux_data = 0 ; + assign ic_sel_premux_data = '0 ; +end + + + assign ifc_bus_acc_fault_f[1:0] = {2{ic_byp_hit_f}} & ifu_byp_data_err_f[1:0] ; + assign ic_data_f[31:0] = ic_final_data[31:0]; + + + +assign fetch_req_f_qual = ic_hit_f & ~exu_flush_final; +assign ic_access_fault_f[1:0] = ({2{ifc_region_acc_fault_final_f}} | ifc_bus_acc_fault_f[1:0]) & {2{~exu_flush_final}}; +assign ic_access_fault_type_f[1:0] = |iccm_rd_ecc_double_err ? 2'b01 : + ifc_region_acc_fault_f ? 2'b10 : + ifc_region_acc_fault_memory_f ? 2'b11 : 2'b00 ; + + // right justified + +assign ic_fetch_val_f[1] = fetch_req_f_qual & ifu_bp_inst_mask_f & ~(vaddr_f[pt.ICACHE_BEAT_ADDR_HI:1] == {pt.ICACHE_BEAT_ADDR_HI{1'b1}}) & (err_stop_state != ERR_FETCH2); +assign ic_fetch_val_f[0] = fetch_req_f_qual ; +assign two_byte_instr = (ic_data_f[1:0] != 2'b11 ) ; + +///////////////////////////////////////////////////////////////////////////////////// +// Create full buffer... // +///////////////////////////////////////////////////////////////////////////////////// + logic [63:0] ic_miss_buff_data_in; + assign ic_miss_buff_data_in[63:0] = ifu_bus_rsp_rdata[63:0]; + + for (genvar i=0; i +// +// 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. + +module el2_btb_tag_hash +import el2_pkg::*; +#( +`include "el2_param.vh" + ) ( + input logic [pt.BTB_ADDR_HI+pt.BTB_BTAG_SIZE+pt.BTB_BTAG_SIZE+pt.BTB_BTAG_SIZE:pt.BTB_ADDR_HI+1] pc, + output logic [pt.BTB_BTAG_SIZE-1:0] hash + ); + + assign hash = {(pc[pt.BTB_ADDR_HI+pt.BTB_BTAG_SIZE+pt.BTB_BTAG_SIZE+pt.BTB_BTAG_SIZE:pt.BTB_ADDR_HI+pt.BTB_BTAG_SIZE+pt.BTB_BTAG_SIZE+1] ^ + pc[pt.BTB_ADDR_HI+pt.BTB_BTAG_SIZE+pt.BTB_BTAG_SIZE:pt.BTB_ADDR_HI+pt.BTB_BTAG_SIZE+1] ^ + pc[pt.BTB_ADDR_HI+pt.BTB_BTAG_SIZE:pt.BTB_ADDR_HI+1])}; +endmodule + +module el2_btb_tag_hash_fold +import el2_pkg::*; +#( +`include "el2_param.vh" + )( + input logic [pt.BTB_ADDR_HI+pt.BTB_BTAG_SIZE+pt.BTB_BTAG_SIZE:pt.BTB_ADDR_HI+1] pc, + output logic [pt.BTB_BTAG_SIZE-1:0] hash + ); + + assign hash = {( + pc[pt.BTB_ADDR_HI+pt.BTB_BTAG_SIZE+pt.BTB_BTAG_SIZE:pt.BTB_ADDR_HI+pt.BTB_BTAG_SIZE+1] ^ + pc[pt.BTB_ADDR_HI+pt.BTB_BTAG_SIZE:pt.BTB_ADDR_HI+1])}; + +endmodule + +module el2_btb_addr_hash +import el2_pkg::*; +#( +`include "el2_param.vh" + )( + input logic [pt.BTB_INDEX3_HI:pt.BTB_INDEX1_LO] pc, + output logic [pt.BTB_ADDR_HI:pt.BTB_ADDR_LO] hash + ); + + +if(pt.BTB_FOLD2_INDEX_HASH) begin : fold2 + assign hash[pt.BTB_ADDR_HI:pt.BTB_ADDR_LO] = pc[pt.BTB_INDEX1_HI:pt.BTB_INDEX1_LO] ^ + pc[pt.BTB_INDEX3_HI:pt.BTB_INDEX3_LO]; +end + else begin + assign hash[pt.BTB_ADDR_HI:pt.BTB_ADDR_LO] = pc[pt.BTB_INDEX1_HI:pt.BTB_INDEX1_LO] ^ + pc[pt.BTB_INDEX2_HI:pt.BTB_INDEX2_LO] ^ + pc[pt.BTB_INDEX3_HI:pt.BTB_INDEX3_LO]; +end + +endmodule + +module el2_btb_ghr_hash +import el2_pkg::*; +#( +`include "el2_param.vh" + )( + input logic [pt.BTB_ADDR_HI:pt.BTB_ADDR_LO] hashin, + input logic [pt.BHT_GHR_SIZE-1:0] ghr, + output logic [pt.BHT_ADDR_HI:pt.BHT_ADDR_LO] hash + ); + + // The hash function is too complex to write in verilog for all cases. + // The config script generates the logic string based on the bp config. + if(pt.BHT_GHR_HASH_1) begin : ghrhash_cfg1 + assign hash[pt.BHT_ADDR_HI:pt.BHT_ADDR_LO] = { ghr[pt.BHT_GHR_SIZE-1:pt.BTB_INDEX1_HI-1], hashin[pt.BTB_INDEX1_HI:2]^ghr[pt.BTB_INDEX1_HI-2:0]}; + end + else begin : ghrhash_cfg2 + assign hash[pt.BHT_ADDR_HI:pt.BHT_ADDR_LO] = { hashin[pt.BHT_GHR_SIZE+1:2]^ghr[pt.BHT_GHR_SIZE-1:0]}; + end + + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/el2_lsu.sv b/designs/Caliptra/src/caliptra-rtl/el2_lsu.sv new file mode 100644 index 0000000..54afe2c --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/el2_lsu.sv @@ -0,0 +1,468 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2020 Western Digital Corporation or its affiliates. +// +// 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. + +//******************************************************************************** +// $Id$ +// +// +// Function: Top level file for load store unit +// Comments: +// +// +// DC1 -> DC2 -> DC3 -> DC4 (Commit) +// +//******************************************************************************** + +module el2_lsu +import el2_pkg::*; +#( +`include "el2_param.vh" + ) +( + + input logic clk_override, // Override non-functional clock gating + input logic dec_tlu_flush_lower_r, // I0/I1 writeback flush. This is used to flush the old packets only + input logic dec_tlu_i0_kill_writeb_r, // I0 is flushed, don't writeback any results to arch state + input logic dec_tlu_force_halt, // This will be high till TLU goes to debug halt + + // chicken signals + input logic dec_tlu_external_ldfwd_disable, // disable load to load forwarding for externals + input logic dec_tlu_wb_coalescing_disable, // disable the write buffer coalesce + input logic dec_tlu_sideeffect_posted_disable, // disable the posted sideeffect load store to the bus + input logic dec_tlu_core_ecc_disable, // disable the generation of the ecc + + input logic [31:0] exu_lsu_rs1_d, // address rs operand + input logic [31:0] exu_lsu_rs2_d, // store data + input logic [11:0] dec_lsu_offset_d, // address offset operand + + input el2_lsu_pkt_t lsu_p, // lsu control packet + input logic dec_lsu_valid_raw_d, // Raw valid for address computation + input logic [31:0] dec_tlu_mrac_ff, // CSR for memory region control + + output logic [31:0] lsu_result_m, // lsu load data + output logic [31:0] lsu_result_corr_r, // This is the ECC corrected data going to RF + output logic lsu_load_stall_any, // This is for blocking loads in the decode + output logic lsu_store_stall_any, // This is for blocking stores in the decode + output logic lsu_fastint_stall_any, // Stall the fastint in decode-1 stage + output logic lsu_idle_any, // lsu buffers are empty and no instruction in the pipeline. Doesn't include DMA + output logic lsu_active, // Used to turn off top level clk + + output logic [31:1] lsu_fir_addr, // fast interrupt address + output logic [1:0] lsu_fir_error, // Error during fast interrupt lookup + + output logic lsu_single_ecc_error_incr, // Increment the ecc counter + output el2_lsu_error_pkt_t lsu_error_pkt_r, // lsu exception packet + output logic lsu_imprecise_error_load_any, // bus load imprecise error + output logic lsu_imprecise_error_store_any, // bus store imprecise error + output logic [31:0] lsu_imprecise_error_addr_any, // bus store imprecise error address + + // Non-blocking loads + output logic lsu_nonblock_load_valid_m, // there is an external load -> put in the cam + output logic [pt.LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_tag_m, // the tag of the external non block load + output logic lsu_nonblock_load_inv_r, // invalidate signal for the cam entry for non block loads + output logic [pt.LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_inv_tag_r, // tag of the enrty which needs to be invalidated + output logic lsu_nonblock_load_data_valid, // the non block is valid - sending information back to the cam + output logic lsu_nonblock_load_data_error, // non block load has an error + output logic [pt.LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_data_tag, // the tag of the non block load sending the data/error + output logic [31:0] lsu_nonblock_load_data, // Data of the non block load + + output logic lsu_pmu_load_external_m, // PMU : Bus loads + output logic lsu_pmu_store_external_m, // PMU : Bus loads + output logic lsu_pmu_misaligned_m, // PMU : misaligned + output logic lsu_pmu_bus_trxn, // PMU : bus transaction + output logic lsu_pmu_bus_misaligned, // PMU : misaligned access going to the bus + output logic lsu_pmu_bus_error, // PMU : bus sending error back + output logic lsu_pmu_bus_busy, // PMU : bus is not ready + + // Trigger signals + input el2_trigger_pkt_t [3:0] trigger_pkt_any, // Trigger info from the decode + output logic [3:0] lsu_trigger_match_m, // lsu trigger hit (one bit per trigger) + + // DCCM ports + output logic dccm_wren, // DCCM write enable + output logic dccm_rden, // DCCM read enable + output logic [pt.DCCM_BITS-1:0] dccm_wr_addr_lo, // DCCM write address low bank + output logic [pt.DCCM_BITS-1:0] dccm_wr_addr_hi, // DCCM write address hi bank + output logic [pt.DCCM_BITS-1:0] dccm_rd_addr_lo, // DCCM read address low bank + output logic [pt.DCCM_BITS-1:0] dccm_rd_addr_hi, // DCCM read address hi bank (hi and low same if aligned read) + output logic [pt.DCCM_FDATA_WIDTH-1:0] dccm_wr_data_lo, // DCCM write data for lo bank + output logic [pt.DCCM_FDATA_WIDTH-1:0] dccm_wr_data_hi, // DCCM write data for hi bank + + input logic [pt.DCCM_FDATA_WIDTH-1:0] dccm_rd_data_lo, // DCCM read data low bank + input logic [pt.DCCM_FDATA_WIDTH-1:0] dccm_rd_data_hi, // DCCM read data hi bank + + // PIC ports + output logic picm_wren, // PIC memory write enable + output logic picm_rden, // PIC memory read enable + output logic picm_mken, // Need to read the mask for stores to determine which bits to write/forward + output logic [31:0] picm_rdaddr, // address for pic read access + output logic [31:0] picm_wraddr, // address for pic write access + output logic [31:0] picm_wr_data, // PIC memory write data + input logic [31:0] picm_rd_data, // PIC memory read/mask data + + // AXI Write Channels + output logic lsu_axi_awvalid, + input logic lsu_axi_awready, + output logic [pt.LSU_BUS_TAG-1:0] lsu_axi_awid, + output logic [31:0] lsu_axi_awaddr, + output logic [3:0] lsu_axi_awregion, + /* exclude signals that are tied to constant value in el2_lsu_bus_buffer.sv */ + /*pragma coverage off*/ + output logic [7:0] lsu_axi_awlen, + /*pragma coverage on*/ + output logic [2:0] lsu_axi_awsize, + /* exclude signals that are tied to constant value in el2_lsu_bus_buffer.sv */ + /*pragma coverage off*/ + output logic [1:0] lsu_axi_awburst, + output logic lsu_axi_awlock, + /*pragma coverage on*/ + output logic [3:0] lsu_axi_awcache, + /* exclude signals that are tied to constant value in el2_lsu_bus_buffer.sv */ + /*pragma coverage off*/ + output logic [2:0] lsu_axi_awprot, + output logic [3:0] lsu_axi_awqos, + /*pragma coverage on*/ + + output logic lsu_axi_wvalid, + input logic lsu_axi_wready, + output logic [63:0] lsu_axi_wdata, + output logic [7:0] lsu_axi_wstrb, + output logic lsu_axi_wlast, + + input logic lsu_axi_bvalid, + /* exclude signals that are tied to constant value in el2_lsu_bus_buffer.sv */ + /*pragma coverage off*/ + output logic lsu_axi_bready, + /*pragma coverage on*/ + input logic [1:0] lsu_axi_bresp, + input logic [pt.LSU_BUS_TAG-1:0] lsu_axi_bid, + + // AXI Read Channels + output logic lsu_axi_arvalid, + input logic lsu_axi_arready, + output logic [pt.LSU_BUS_TAG-1:0] lsu_axi_arid, + output logic [31:0] lsu_axi_araddr, + output logic [3:0] lsu_axi_arregion, + /* exclude signals that are tied to constant value in el2_lsu_bus_buffer.sv */ + /*pragma coverage off*/ + output logic [7:0] lsu_axi_arlen, + /*pragma coverage on*/ + output logic [2:0] lsu_axi_arsize, + /* exclude signals that are tied to constant value in el2_lsu_bus_buffer.sv */ + /*pragma coverage off*/ + output logic [1:0] lsu_axi_arburst, + output logic lsu_axi_arlock, + /*pragma coverage on*/ + output logic [3:0] lsu_axi_arcache, + /* exclude signals that are tied to constant value in el2_lsu_bus_buffer.sv */ + /*pragma coverage off*/ + output logic [2:0] lsu_axi_arprot, + output logic [3:0] lsu_axi_arqos, + /*pragma coverage on*/ + + input logic lsu_axi_rvalid, + /* exclude signals that are tied to constant value in el2_lsu_bus_buffer.sv */ + /*pragma coverage off*/ + output logic lsu_axi_rready, + /*pragma coverage on*/ + input logic [pt.LSU_BUS_TAG-1:0] lsu_axi_rid, + input logic [63:0] lsu_axi_rdata, + input logic [1:0] lsu_axi_rresp, + input logic lsu_axi_rlast, + + input logic lsu_bus_clk_en, // external drives a clock_en to control bus ratio + + // DMA slave + input logic dma_dccm_req, // DMA read/write to dccm + input logic [2:0] dma_mem_tag, // DMA request tag + input logic [31:0] dma_mem_addr, // DMA address + input logic [2:0] dma_mem_sz, // DMA access size + input logic dma_mem_write, // DMA access is a write + input logic [63:0] dma_mem_wdata, // DMA write data + + output logic dccm_dma_rvalid, // lsu data valid for DMA dccm read + output logic dccm_dma_ecc_error, // DMA load had ecc error + output logic [2:0] dccm_dma_rtag, // DMA request tag + output logic [63:0] dccm_dma_rdata, // lsu data for DMA dccm read + output logic dccm_ready, // lsu ready for DMA access + + // DCCM ECC status + output logic lsu_dccm_rd_ecc_single_err, + output logic lsu_dccm_rd_ecc_double_err, + + // Excluding scan_mode from coverage as its usage is determined by the integrator of the VeeR core. + /*pragma coverage off*/ + input logic scan_mode, // scan mode + /*pragma coverage on*/ + input logic clk, // Clock only while core active. Through one clock header. For flops with second clock header built in. Connected to ACTIVE_L2CLK. + input logic active_clk, // Clock only while core active. Through two clock headers. For flops without second clock header built in. + input logic rst_l, // reset, active low + + output logic [31:0] lsu_pmp_addr_start, + output logic [31:0] lsu_pmp_addr_end, + input logic lsu_pmp_error_start, + input logic lsu_pmp_error_end, + output logic lsu_pmp_we, + output logic lsu_pmp_re + + ); + + logic lsu_dccm_rden_m; + logic lsu_dccm_rden_r; + logic [31:0] store_data_m; + logic [31:0] store_data_r; + logic [31:0] store_data_hi_r, store_data_lo_r; + logic [31:0] store_datafn_hi_r, store_datafn_lo_r; + logic [31:0] sec_data_lo_m, sec_data_hi_m; + logic [31:0] sec_data_lo_r, sec_data_hi_r; + + logic [31:0] lsu_ld_data_m; + logic [31:0] dccm_rdata_hi_m, dccm_rdata_lo_m; + logic [6:0] dccm_data_ecc_hi_m, dccm_data_ecc_lo_m; + logic lsu_single_ecc_error_m; + logic lsu_double_ecc_error_m; + + logic [31:0] lsu_ld_data_r; + logic [31:0] lsu_ld_data_corr_r; + logic [31:0] dccm_rdata_hi_r, dccm_rdata_lo_r; + logic [6:0] dccm_data_ecc_hi_r, dccm_data_ecc_lo_r; + logic single_ecc_error_hi_r, single_ecc_error_lo_r; + logic lsu_single_ecc_error_r; + logic lsu_double_ecc_error_r; + logic ld_single_ecc_error_r, ld_single_ecc_error_r_ff; + assign lsu_dccm_rd_ecc_single_err = lsu_single_ecc_error_r; + assign lsu_dccm_rd_ecc_double_err = lsu_double_ecc_error_r; + + logic [31:0] picm_mask_data_m; + + logic [31:0] lsu_addr_d, lsu_addr_m, lsu_addr_r; + logic [31:0] end_addr_d, end_addr_m, end_addr_r; + assign lsu_pmp_addr_start = lsu_addr_d; + assign lsu_pmp_addr_end = end_addr_d; + + el2_lsu_pkt_t lsu_pkt_d, lsu_pkt_m, lsu_pkt_r; + logic lsu_i0_valid_d, lsu_i0_valid_m, lsu_i0_valid_r; + assign lsu_pmp_we = lsu_pkt_d.store & lsu_pkt_d.valid; + assign lsu_pmp_re = lsu_pkt_d.load & lsu_pkt_d.valid; + + // Store Buffer signals + logic store_stbuf_reqvld_r; + logic ldst_stbuf_reqvld_r; + + logic lsu_commit_r; + logic lsu_exc_m; + + logic addr_in_dccm_d, addr_in_dccm_m, addr_in_dccm_r; + logic addr_in_pic_d, addr_in_pic_m, addr_in_pic_r; + logic ldst_dual_d, ldst_dual_m, ldst_dual_r; + logic addr_external_m; + + logic stbuf_reqvld_any; + logic stbuf_reqvld_flushed_any; + logic [pt.LSU_SB_BITS-1:0] stbuf_addr_any; + logic [pt.DCCM_DATA_WIDTH-1:0] stbuf_data_any; + logic [pt.DCCM_ECC_WIDTH-1:0] stbuf_ecc_any; + logic [pt.DCCM_DATA_WIDTH-1:0] sec_data_lo_r_ff, sec_data_hi_r_ff; + logic [pt.DCCM_ECC_WIDTH-1:0] sec_data_ecc_hi_r_ff, sec_data_ecc_lo_r_ff; + + logic lsu_cmpen_m; + logic [pt.DCCM_DATA_WIDTH-1:0] stbuf_fwddata_hi_m; + logic [pt.DCCM_DATA_WIDTH-1:0] stbuf_fwddata_lo_m; + logic [pt.DCCM_BYTE_WIDTH-1:0] stbuf_fwdbyteen_hi_m; + logic [pt.DCCM_BYTE_WIDTH-1:0] stbuf_fwdbyteen_lo_m; + + logic lsu_stbuf_commit_any; + logic lsu_stbuf_empty_any; // This is for blocking loads + logic lsu_stbuf_full_any; + + // Bus signals + logic lsu_busreq_r; + logic lsu_bus_buffer_pend_any; + logic lsu_bus_buffer_empty_any; + logic lsu_bus_buffer_full_any; + logic lsu_busreq_m; + logic [31:0] bus_read_data_m; + + logic flush_m_up, flush_r; + logic is_sideeffects_m; + logic [2:0] dma_mem_tag_d, dma_mem_tag_m; + logic ldst_nodma_mtor; + logic dma_dccm_wen, dma_pic_wen; + logic [31:0] dma_dccm_wdata_lo, dma_dccm_wdata_hi; + logic [pt.DCCM_ECC_WIDTH-1:0] dma_dccm_wdata_ecc_lo, dma_dccm_wdata_ecc_hi; + + // Clocks + logic lsu_busm_clken; + logic lsu_bus_obuf_c1_clken; + logic lsu_c1_m_clk, lsu_c1_r_clk; + logic lsu_c2_m_clk, lsu_c2_r_clk; + logic lsu_store_c1_m_clk, lsu_store_c1_r_clk; + + logic lsu_stbuf_c1_clk; + logic lsu_bus_ibuf_c1_clk, lsu_bus_obuf_c1_clk, lsu_bus_buf_c1_clk; + logic lsu_busm_clk; + logic lsu_free_c2_clk; + + logic lsu_raw_fwd_lo_m, lsu_raw_fwd_hi_m; + logic lsu_raw_fwd_lo_r, lsu_raw_fwd_hi_r; + + assign lsu_raw_fwd_lo_m = (|stbuf_fwdbyteen_lo_m[pt.DCCM_BYTE_WIDTH-1:0]); + assign lsu_raw_fwd_hi_m = (|stbuf_fwdbyteen_hi_m[pt.DCCM_BYTE_WIDTH-1:0]); + + el2_lsu_lsc_ctl #(.pt(pt)) lsu_lsc_ctl (.*); + + // block stores in decode - for either bus or stbuf reasons + assign lsu_store_stall_any = lsu_stbuf_full_any | lsu_bus_buffer_full_any | ld_single_ecc_error_r_ff; + assign lsu_load_stall_any = lsu_bus_buffer_full_any | ld_single_ecc_error_r_ff; + assign lsu_fastint_stall_any = ld_single_ecc_error_r; // Stall the fastint in decode-1 stage + + // Ready to accept dma trxns + // There can't be any inpipe forwarding from non-dma packet to dma packet since they can be flushed so we can't have st in r when dma is in m + assign dma_mem_tag_d[2:0] = dma_mem_tag[2:0]; + assign ldst_nodma_mtor = (lsu_pkt_m.valid & ~lsu_pkt_m.dma & (addr_in_dccm_m | addr_in_pic_m) & lsu_pkt_m.store); + + assign dccm_ready = ~(dec_lsu_valid_raw_d | ldst_nodma_mtor | ld_single_ecc_error_r_ff); + + assign dma_dccm_wen = dma_dccm_req & dma_mem_write & addr_in_dccm_d & dma_mem_sz[1]; // Perform DMA writes only for word/dword + assign dma_pic_wen = dma_dccm_req & dma_mem_write & addr_in_pic_d; + assign {dma_dccm_wdata_hi[31:0], dma_dccm_wdata_lo[31:0]} = 64'(dma_mem_wdata[63:0] >> {dma_mem_addr[2:0], 3'b000}); // Shift the dma data to lower bits to make it consistent to lsu stores + + + // Generate per cycle flush signals + assign flush_m_up = dec_tlu_flush_lower_r; + assign flush_r = dec_tlu_i0_kill_writeb_r; + + // lsu idle + // lsu halt idle. This is used for entering the halt mode. Also, DMA accesses are allowed during fence. + // Indicates non-idle if there is a instruction valid in d-r or read/write buffers are non-empty since they can come with error + // Store buffer now have only non-dma dccm stores + // stbuf_empty not needed since it has only dccm stores + assign lsu_idle_any = ~((lsu_pkt_m.valid & ~lsu_pkt_m.dma) | + (lsu_pkt_r.valid & ~lsu_pkt_r.dma)) & + lsu_bus_buffer_empty_any; + + assign lsu_active = (lsu_pkt_m.valid | lsu_pkt_r.valid | ld_single_ecc_error_r_ff) | ~lsu_bus_buffer_empty_any; // This includes DMA. Used for gating top clock + + // Instantiate the store buffer + assign store_stbuf_reqvld_r = lsu_pkt_r.valid & lsu_pkt_r.store & addr_in_dccm_r & ~flush_r & (~lsu_pkt_r.dma | ((lsu_pkt_r.by | lsu_pkt_r.half) & ~lsu_double_ecc_error_r)); + + // Disable Forwarding for now + assign lsu_cmpen_m = lsu_pkt_m.valid & (lsu_pkt_m.load | lsu_pkt_m.store) & (addr_in_dccm_m | addr_in_pic_m); + + // Bus signals + assign lsu_busreq_m = lsu_pkt_m.valid & ((lsu_pkt_m.load | lsu_pkt_m.store) & addr_external_m) & ~flush_m_up & ~lsu_exc_m & ~lsu_pkt_m.fast_int; + + // Dual signals + assign ldst_dual_d = (lsu_addr_d[2] != end_addr_d[2]); + assign ldst_dual_m = (lsu_addr_m[2] != end_addr_m[2]); + assign ldst_dual_r = (lsu_addr_r[2] != end_addr_r[2]); + + // PMU signals + assign lsu_pmu_misaligned_m = lsu_pkt_m.valid & ((lsu_pkt_m.half & lsu_addr_m[0]) | (lsu_pkt_m.word & (|lsu_addr_m[1:0]))); + assign lsu_pmu_load_external_m = lsu_pkt_m.valid & lsu_pkt_m.load & addr_external_m; + assign lsu_pmu_store_external_m = lsu_pkt_m.valid & lsu_pkt_m.store & addr_external_m; + + el2_lsu_dccm_ctl #(.pt(pt)) dccm_ctl ( + .lsu_addr_d(lsu_addr_d[31:0]), + .end_addr_d(end_addr_d[pt.DCCM_BITS-1:0]), + .lsu_addr_m(lsu_addr_m[pt.DCCM_BITS-1:0]), + .lsu_addr_r(lsu_addr_r[31:0]), + + .end_addr_m(end_addr_m[pt.DCCM_BITS-1:0]), + .end_addr_r(end_addr_r[pt.DCCM_BITS-1:0]), + .* + ); + + el2_lsu_stbuf #(.pt(pt)) stbuf ( + .lsu_addr_d(lsu_addr_d[pt.LSU_SB_BITS-1:0]), + .end_addr_d(end_addr_d[pt.LSU_SB_BITS-1:0]), + + .* + + ); + + el2_lsu_ecc #(.pt(pt)) ecc ( + .lsu_addr_r(lsu_addr_r[pt.DCCM_BITS-1:0]), + .end_addr_r(end_addr_r[pt.DCCM_BITS-1:0]), + .lsu_addr_m(lsu_addr_m[pt.DCCM_BITS-1:0]), + .end_addr_m(end_addr_m[pt.DCCM_BITS-1:0]), + .* + ); + + el2_lsu_trigger #(.pt(pt)) trigger ( + .store_data_m(store_data_m[31:0]), + .* + ); + + // Clk domain + el2_lsu_clkdomain #(.pt(pt)) clkdomain (.*); + + // Bus interface + el2_lsu_bus_intf #(.pt(pt)) bus_intf ( + .lsu_addr_m(lsu_addr_m[31:0] & {32{addr_external_m & lsu_pkt_m.valid}}), + .lsu_addr_r(lsu_addr_r[31:0] & {32{lsu_busreq_r}}), + + .end_addr_m(end_addr_m[31:0] & {32{addr_external_m & lsu_pkt_m.valid}}), + .end_addr_r(end_addr_r[31:0] & {32{lsu_busreq_r}}), + + .store_data_r(store_data_r[31:0] & {32{lsu_busreq_r}}), + .* + ); + + //Flops + rvdff #(3) dma_mem_tag_mff (.*, .din(dma_mem_tag_d[2:0]), .dout(dma_mem_tag_m[2:0]), .clk(lsu_c1_m_clk)); + rvdff #(2) lsu_raw_fwd_r_ff (.*, .din({lsu_raw_fwd_hi_m, lsu_raw_fwd_lo_m}), .dout({lsu_raw_fwd_hi_r, lsu_raw_fwd_lo_r}), .clk(lsu_c2_r_clk)); + +`ifdef RV_ASSERT_ON + logic [1:0] store_data_bypass_sel; + assign store_data_bypass_sel[1:0] = {lsu_p.store_data_bypass_d, lsu_p.store_data_bypass_m}; + + property exception_no_lsu_flush; + @(posedge clk) disable iff(~rst_l) lsu_lsc_ctl.lsu_error_pkt_m.exc_valid |-> ##[1:2] (flush_r ); + endproperty + assert_exception_no_lsu_flush: assert property (exception_no_lsu_flush) else + $display("No flush within 2 cycles of exception"); + + // offset should be zero for fast interrupt + property offset_0_fastint; + @(posedge clk) disable iff(~rst_l) (lsu_p.valid & lsu_p.fast_int) |-> (dec_lsu_offset_d[11:0] == 12'b0); + endproperty + assert_offset_0_fastint: assert property (offset_0_fastint) else + $display("dec_tlu_offset_d not zero for fast interrupt redirect"); + + // DMA req should assert dccm rden/wren + property dmareq_dccm_wren_or_rden; + @(posedge clk) disable iff(~rst_l) dma_dccm_req |-> (dccm_rden | dccm_wren | addr_in_pic_d); + endproperty + assert_dmareq_dccm_wren_or_rden: assert property(dmareq_dccm_wren_or_rden) else + $display("dccm rden or wren not asserted during DMA request"); + + // fastint_stall should cause load/store stall next cycle + property fastint_stall_imply_loadstore_stall; + @(posedge clk) disable iff(~rst_l) (lsu_fastint_stall_any & (lsu_commit_r | lsu_pkt_r.dma)) |-> ##1 ((lsu_load_stall_any | lsu_store_stall_any) | ~ld_single_ecc_error_r_ff); + endproperty + assert_fastint_stall_imply_loadstore_stall: assert property (fastint_stall_imply_loadstore_stall) else + $display("fastint_stall should be followed by lsu_load/store_stall_any"); + + // Single ECC error implies rfnpc flush + property single_ecc_error_rfnpc_flush; + @(posedge clk) disable iff(~rst_l) (lsu_error_pkt_r.single_ecc_error & lsu_pkt_r.load) |=> ~lsu_commit_r; + endproperty + assert_single_ecc_error_rfnpc_flush: assert property (single_ecc_error_rfnpc_flush) else + $display("LSU commit next cycle after single ecc error"); + +`endif + +endmodule // el2_lsu diff --git a/designs/Caliptra/src/caliptra-rtl/el2_lsu_addrcheck.sv b/designs/Caliptra/src/caliptra-rtl/el2_lsu_addrcheck.sv new file mode 100644 index 0000000..b18eb82 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/el2_lsu_addrcheck.sv @@ -0,0 +1,241 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2020 Western Digital Corporation or its affiliates. +// +// 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. + +//******************************************************************************** +// $Id$ +// +// +// Owner: +// Function: Checks the memory map for the address +// Comments: +// +//******************************************************************************** +module el2_lsu_addrcheck +import el2_pkg::*; +#( +`include "el2_param.vh" + )( + input logic lsu_c2_m_clk, // clock + input logic rst_l, // reset + + input logic [31:0] start_addr_d, // start address for lsu + input logic [31:0] end_addr_d, // end address for lsu + input el2_lsu_pkt_t lsu_pkt_d, // packet in d + input logic [31:0] dec_tlu_mrac_ff, // CSR read + input logic [3:0] rs1_region_d, // address rs operand [31:28] + + input logic [31:0] rs1_d, // address rs operand + + output logic is_sideeffects_m, // is sideffects space + output logic addr_in_dccm_d, // address in dccm + output logic addr_in_pic_d, // address in pic + output logic addr_external_d, // address in external + + output logic access_fault_d, // access fault + output logic misaligned_fault_d, // misaligned + output logic [3:0] exc_mscause_d, // mscause for access/misaligned faults + + output logic fir_dccm_access_error_d, // Fast interrupt dccm access error + output logic fir_nondccm_access_error_d,// Fast interrupt dccm access error + + input logic lsu_pmp_error_start, + input logic lsu_pmp_error_end, + + // Excluding scan_mode from coverage as its usage is determined by the integrator of the VeeR core. + /*pragma coverage off*/ + input logic scan_mode // Scan mode + /*pragma coverage on*/ +); + + + logic non_dccm_access_ok; + logic is_sideeffects_d, is_aligned_d; + logic start_addr_in_dccm_d, end_addr_in_dccm_d; + logic start_addr_in_dccm_region_d, end_addr_in_dccm_region_d; + logic start_addr_in_pic_d, end_addr_in_pic_d; + logic start_addr_in_pic_region_d, end_addr_in_pic_region_d; + logic [4:0] csr_idx; + logic addr_in_iccm; + logic start_addr_dccm_or_pic; + logic base_reg_dccm_or_pic; + logic unmapped_access_fault_d, mpu_access_fault_d, picm_access_fault_d, regpred_access_fault_d; + logic regcross_misaligned_fault_d, sideeffect_misaligned_fault_d; + logic [3:0] access_fault_mscause_d; + logic [3:0] misaligned_fault_mscause_d; + + if (pt.DCCM_ENABLE == 1) begin: Gen_dccm_enable + // Start address check + rvrangecheck #(.CCM_SADR(pt.DCCM_SADR), + .CCM_SIZE(pt.DCCM_SIZE)) start_addr_dccm_rangecheck ( + .addr(start_addr_d[31:0]), + .in_range(start_addr_in_dccm_d), + .in_region(start_addr_in_dccm_region_d) + ); + + // End address check + rvrangecheck #(.CCM_SADR(pt.DCCM_SADR), + .CCM_SIZE(pt.DCCM_SIZE)) end_addr_dccm_rangecheck ( + .addr(end_addr_d[31:0]), + .in_range(end_addr_in_dccm_d), + .in_region(end_addr_in_dccm_region_d) + ); + end else begin: Gen_dccm_disable // block: Gen_dccm_enable + assign start_addr_in_dccm_d = '0; + assign start_addr_in_dccm_region_d = '0; + assign end_addr_in_dccm_d = '0; + assign end_addr_in_dccm_region_d = '0; + end + + if (pt.ICCM_ENABLE == 1) begin : check_iccm + assign addr_in_iccm = (start_addr_d[31:28] == pt.ICCM_REGION); + end else begin + assign addr_in_iccm = 1'b0; + end + + // PIC memory check + // Start address check + rvrangecheck #(.CCM_SADR(pt.PIC_BASE_ADDR), + .CCM_SIZE(pt.PIC_SIZE)) start_addr_pic_rangecheck ( + .addr(start_addr_d[31:0]), + .in_range(start_addr_in_pic_d), + .in_region(start_addr_in_pic_region_d) + ); + + // End address check + rvrangecheck #(.CCM_SADR(pt.PIC_BASE_ADDR), + .CCM_SIZE(pt.PIC_SIZE)) end_addr_pic_rangecheck ( + .addr(end_addr_d[31:0]), + .in_range(end_addr_in_pic_d), + .in_region(end_addr_in_pic_region_d) + ); + + assign start_addr_dccm_or_pic = start_addr_in_dccm_region_d | start_addr_in_pic_region_d; + assign base_reg_dccm_or_pic = (|((rs1_region_d[3:0] == pt.DCCM_REGION) & pt.DCCM_ENABLE)) | (rs1_region_d[3:0] == pt.PIC_REGION); + assign addr_in_dccm_d = (start_addr_in_dccm_d & end_addr_in_dccm_d); + assign addr_in_pic_d = (start_addr_in_pic_d & end_addr_in_pic_d); + + assign addr_external_d = ~(start_addr_in_dccm_region_d | start_addr_in_pic_region_d); + assign csr_idx[4:0] = {start_addr_d[31:28], 1'b1}; + assign is_sideeffects_d = dec_tlu_mrac_ff[csr_idx] & ~(start_addr_in_dccm_region_d | start_addr_in_pic_region_d | addr_in_iccm) & lsu_pkt_d.valid & (lsu_pkt_d.store | lsu_pkt_d.load); //every region has the 2 LSB indicating ( 1: sideeffects/no_side effects, and 0: cacheable ). Ignored in internal regions + assign is_aligned_d = (lsu_pkt_d.word & (start_addr_d[1:0] == 2'b0)) | + (lsu_pkt_d.half & (start_addr_d[0] == 1'b0)) | + lsu_pkt_d.by; + + logic ACCESS0_STARTOK; + logic ACCESS1_STARTOK; + logic ACCESS2_STARTOK; + logic ACCESS3_STARTOK; + logic ACCESS4_STARTOK; + logic ACCESS5_STARTOK; + logic ACCESS6_STARTOK; + logic ACCESS7_STARTOK; + logic ACCESS0_ENDOK; + logic ACCESS1_ENDOK; + logic ACCESS2_ENDOK; + logic ACCESS3_ENDOK; + logic ACCESS4_ENDOK; + logic ACCESS5_ENDOK; + logic ACCESS6_ENDOK; + logic ACCESS7_ENDOK; + + assign ACCESS0_STARTOK = pt.DATA_ACCESS_ENABLE0 & ((start_addr_d[31:0] | pt.DATA_ACCESS_MASK0)) == (pt.DATA_ACCESS_ADDR0 | pt.DATA_ACCESS_MASK0); + assign ACCESS1_STARTOK = pt.DATA_ACCESS_ENABLE1 & ((start_addr_d[31:0] | pt.DATA_ACCESS_MASK1)) == (pt.DATA_ACCESS_ADDR1 | pt.DATA_ACCESS_MASK1); + assign ACCESS2_STARTOK = pt.DATA_ACCESS_ENABLE2 & ((start_addr_d[31:0] | pt.DATA_ACCESS_MASK2)) == (pt.DATA_ACCESS_ADDR2 | pt.DATA_ACCESS_MASK2); + assign ACCESS3_STARTOK = pt.DATA_ACCESS_ENABLE3 & ((start_addr_d[31:0] | pt.DATA_ACCESS_MASK3)) == (pt.DATA_ACCESS_ADDR3 | pt.DATA_ACCESS_MASK3); + assign ACCESS4_STARTOK = pt.DATA_ACCESS_ENABLE4 & ((start_addr_d[31:0] | pt.DATA_ACCESS_MASK4)) == (pt.DATA_ACCESS_ADDR4 | pt.DATA_ACCESS_MASK4); + assign ACCESS5_STARTOK = pt.DATA_ACCESS_ENABLE5 & ((start_addr_d[31:0] | pt.DATA_ACCESS_MASK5)) == (pt.DATA_ACCESS_ADDR5 | pt.DATA_ACCESS_MASK5); + assign ACCESS6_STARTOK = pt.DATA_ACCESS_ENABLE6 & ((start_addr_d[31:0] | pt.DATA_ACCESS_MASK6)) == (pt.DATA_ACCESS_ADDR6 | pt.DATA_ACCESS_MASK6); + assign ACCESS7_STARTOK = pt.DATA_ACCESS_ENABLE7 & ((start_addr_d[31:0] | pt.DATA_ACCESS_MASK7)) == (pt.DATA_ACCESS_ADDR7 | pt.DATA_ACCESS_MASK7); + assign ACCESS0_ENDOK = pt.DATA_ACCESS_ENABLE0 & ((end_addr_d[31:0] | pt.DATA_ACCESS_MASK0)) == (pt.DATA_ACCESS_ADDR0 | pt.DATA_ACCESS_MASK0); + assign ACCESS1_ENDOK = pt.DATA_ACCESS_ENABLE1 & ((end_addr_d[31:0] | pt.DATA_ACCESS_MASK1)) == (pt.DATA_ACCESS_ADDR1 | pt.DATA_ACCESS_MASK1); + assign ACCESS2_ENDOK = pt.DATA_ACCESS_ENABLE2 & ((end_addr_d[31:0] | pt.DATA_ACCESS_MASK2)) == (pt.DATA_ACCESS_ADDR2 | pt.DATA_ACCESS_MASK2); + assign ACCESS3_ENDOK = pt.DATA_ACCESS_ENABLE3 & ((end_addr_d[31:0] | pt.DATA_ACCESS_MASK3)) == (pt.DATA_ACCESS_ADDR3 | pt.DATA_ACCESS_MASK3); + assign ACCESS4_ENDOK = pt.DATA_ACCESS_ENABLE4 & ((end_addr_d[31:0] | pt.DATA_ACCESS_MASK4)) == (pt.DATA_ACCESS_ADDR4 | pt.DATA_ACCESS_MASK4); + assign ACCESS5_ENDOK = pt.DATA_ACCESS_ENABLE5 & ((end_addr_d[31:0] | pt.DATA_ACCESS_MASK5)) == (pt.DATA_ACCESS_ADDR5 | pt.DATA_ACCESS_MASK5); + assign ACCESS6_ENDOK = pt.DATA_ACCESS_ENABLE6 & ((end_addr_d[31:0] | pt.DATA_ACCESS_MASK6)) == (pt.DATA_ACCESS_ADDR6 | pt.DATA_ACCESS_MASK6); + assign ACCESS7_ENDOK = pt.DATA_ACCESS_ENABLE7 & ((end_addr_d[31:0] | pt.DATA_ACCESS_MASK7)) == (pt.DATA_ACCESS_ADDR7 | pt.DATA_ACCESS_MASK7); + + if (pt.PMP_ENTRIES == 0) begin + assign non_dccm_access_ok = (~(|{pt.DATA_ACCESS_ENABLE0,pt.DATA_ACCESS_ENABLE1,pt.DATA_ACCESS_ENABLE2,pt.DATA_ACCESS_ENABLE3,pt.DATA_ACCESS_ENABLE4,pt.DATA_ACCESS_ENABLE5,pt.DATA_ACCESS_ENABLE6,pt.DATA_ACCESS_ENABLE7})) | + (( ACCESS0_STARTOK| + ACCESS1_STARTOK| + ACCESS2_STARTOK| + ACCESS3_STARTOK| + ACCESS4_STARTOK| + ACCESS5_STARTOK| + ACCESS6_STARTOK| + ACCESS7_STARTOK) & + ( ACCESS0_ENDOK| + ACCESS1_ENDOK| + ACCESS2_ENDOK| + ACCESS3_ENDOK| + ACCESS4_ENDOK| + ACCESS5_ENDOK| + ACCESS6_ENDOK| + ACCESS7_ENDOK)); + end + + // Access fault logic + // 0. Unmapped local memory : Addr in dccm region but not in dccm offset OR Addr in picm region but not in picm offset OR DCCM -> PIC cross when DCCM/PIC in same region + // 1. Uncorrectable (double bit) ECC error + // 3. Address is not in a populated non-dccm region + // 5. Region predication access fault: Base Address in DCCM/PIC and Final address in non-DCCM/non-PIC region or vice versa + // 6. Ld/St access to picm are not word aligned or word size + assign regpred_access_fault_d = (start_addr_dccm_or_pic ^ base_reg_dccm_or_pic); // 5. Region predication access fault: Base Address in DCCM/PIC and Final address in non-DCCM/non-PIC region or vice versa + assign picm_access_fault_d = (addr_in_pic_d & ((start_addr_d[1:0] != 2'b0) | ~lsu_pkt_d.word)); // 6. Ld/St access to picm are not word aligned or word size + + if (pt.DCCM_ENABLE & (pt.DCCM_REGION == pt.PIC_REGION)) begin + assign unmapped_access_fault_d = ((start_addr_in_dccm_region_d & ~(start_addr_in_dccm_d | start_addr_in_pic_d)) | // 0. Addr in dccm/pic region but not in dccm/pic offset + (end_addr_in_dccm_region_d & ~(end_addr_in_dccm_d | end_addr_in_pic_d)) | // 0. Addr in dccm/pic region but not in dccm/pic offset + (start_addr_in_dccm_d & end_addr_in_pic_d) | // 0. DCCM -> PIC cross when DCCM/PIC in same region + (start_addr_in_pic_d & end_addr_in_dccm_d)); // 0. DCCM -> PIC cross when DCCM/PIC in same region + if (pt.PMP_ENTRIES > 0) begin + assign mpu_access_fault_d = (lsu_pmp_error_start | lsu_pmp_error_end); // X. Address is in blocked region + end else begin + assign mpu_access_fault_d = (~start_addr_in_dccm_region_d & ~non_dccm_access_ok); // 3. Address is not in a populated non-dccm region + end + end else begin + assign unmapped_access_fault_d = ((start_addr_in_dccm_region_d & ~start_addr_in_dccm_d) | // 0. Addr in dccm region but not in dccm offset + (end_addr_in_dccm_region_d & ~end_addr_in_dccm_d) | // 0. Addr in dccm region but not in dccm offset + (start_addr_in_pic_region_d & ~start_addr_in_pic_d) | // 0. Addr in picm region but not in picm offset + (end_addr_in_pic_region_d & ~end_addr_in_pic_d)); // 0. Addr in picm region but not in picm offset + if (pt.PMP_ENTRIES > 0) begin + assign mpu_access_fault_d = (lsu_pmp_error_start | lsu_pmp_error_end); // X. Address is in blocked region + end else begin + assign mpu_access_fault_d = (~start_addr_in_pic_region_d & ~start_addr_in_dccm_region_d & ~non_dccm_access_ok); // 3. Address is not in a populated non-dccm region + end + end + + assign access_fault_d = (unmapped_access_fault_d | mpu_access_fault_d | picm_access_fault_d | regpred_access_fault_d) & lsu_pkt_d.valid & ~lsu_pkt_d.dma; + assign access_fault_mscause_d[3:0] = unmapped_access_fault_d ? 4'h2 : mpu_access_fault_d ? 4'h3 : regpred_access_fault_d ? 4'h5 : picm_access_fault_d ? 4'h6 : 4'h0; + + // Misaligned happens due to 2 reasons + // 0. Region cross + // 1. sideeffects access which are not aligned + assign regcross_misaligned_fault_d = (start_addr_d[31:28] != end_addr_d[31:28]); + assign sideeffect_misaligned_fault_d = (is_sideeffects_d & ~is_aligned_d); + assign misaligned_fault_d = (regcross_misaligned_fault_d | (sideeffect_misaligned_fault_d & addr_external_d)) & lsu_pkt_d.valid & ~lsu_pkt_d.dma; + assign misaligned_fault_mscause_d[3:0] = regcross_misaligned_fault_d ? 4'h2 : sideeffect_misaligned_fault_d ? 4'h1 : 4'h0; + + assign exc_mscause_d[3:0] = misaligned_fault_d ? misaligned_fault_mscause_d[3:0] : access_fault_mscause_d[3:0]; + + // Fast interrupt error logic + assign fir_dccm_access_error_d = ((start_addr_in_dccm_region_d & ~start_addr_in_dccm_d) | + (end_addr_in_dccm_region_d & ~end_addr_in_dccm_d)) & lsu_pkt_d.valid & lsu_pkt_d.fast_int; + assign fir_nondccm_access_error_d = ~(start_addr_in_dccm_region_d & end_addr_in_dccm_region_d) & lsu_pkt_d.valid & lsu_pkt_d.fast_int; + + rvdff #(.WIDTH(1)) is_sideeffects_mff (.din(is_sideeffects_d), .dout(is_sideeffects_m), .clk(lsu_c2_m_clk), .*); + +endmodule // el2_lsu_addrcheck diff --git a/designs/Caliptra/src/caliptra-rtl/el2_lsu_bus_buffer.sv b/designs/Caliptra/src/caliptra-rtl/el2_lsu_bus_buffer.sv new file mode 100644 index 0000000..1c699f9 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/el2_lsu_bus_buffer.sv @@ -0,0 +1,966 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2020 Western Digital Corporation or its affiliates. +// +// 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. + +//******************************************************************************** +// $Id$ +// +// +// Owner: +// Function: lsu interface with interface queue +// Comments: +// +//******************************************************************************** + +module el2_lsu_bus_buffer +import el2_pkg::*; +#( +`include "el2_param.vh" + )( + input logic clk, // Clock only while core active. Through one clock header. For flops with second clock header built in. Connected to ACTIVE_L2CLK. + input logic clk_override, // Override non-functional clock gating + input logic rst_l, // reset, active low + // Excluding scan_mode from coverage as its usage is determined by the integrator of the VeeR core. + /*pragma coverage off*/ + input logic scan_mode, // scan mode + /*pragma coverage on*/ + input logic dec_tlu_external_ldfwd_disable, // disable load to load forwarding for externals + input logic dec_tlu_wb_coalescing_disable, // disable write buffer coalescing + input logic dec_tlu_sideeffect_posted_disable, // Don't block the sideeffect load store to the bus + input logic dec_tlu_force_halt, + + // various clocks needed for the bus reads and writes + input logic lsu_bus_obuf_c1_clken, + input logic lsu_busm_clken, + input logic lsu_c2_r_clk, + input logic lsu_bus_ibuf_c1_clk, + input logic lsu_bus_obuf_c1_clk, + input logic lsu_bus_buf_c1_clk, + input logic lsu_free_c2_clk, + input logic lsu_busm_clk, + + + input logic dec_lsu_valid_raw_d, // Raw valid for address computation + input el2_lsu_pkt_t lsu_pkt_m, // lsu packet flowing down the pipe + input el2_lsu_pkt_t lsu_pkt_r, // lsu packet flowing down the pipe + + input logic [31:0] lsu_addr_m, // lsu address flowing down the pipe + input logic [31:0] end_addr_m, // lsu address flowing down the pipe + input logic [31:0] lsu_addr_r, // lsu address flowing down the pipe + input logic [31:0] end_addr_r, // lsu address flowing down the pipe + input logic [31:0] store_data_r, // store data flowing down the pipe + + input logic no_word_merge_r, // r store doesn't need to wait in ibuf since it will not coalesce + input logic no_dword_merge_r, // r store doesn't need to wait in ibuf since it will not coalesce + input logic lsu_busreq_m, // bus request is in m + output logic lsu_busreq_r, // bus request is in r + input logic ld_full_hit_m, // load can get all its byte from a write buffer entry + input logic flush_m_up, // flush + input logic flush_r, // flush + input logic lsu_commit_r, // lsu instruction in r commits + input logic is_sideeffects_r, // lsu attribute is side_effects + input logic ldst_dual_d, // load/store is unaligned at 32 bit boundary + input logic ldst_dual_m, // load/store is unaligned at 32 bit boundary + input logic ldst_dual_r, // load/store is unaligned at 32 bit boundary + + input logic [7:0] ldst_byteen_ext_m, // HI and LO signals + + output logic lsu_bus_buffer_pend_any, // bus buffer has a pending bus entry + output logic lsu_bus_buffer_full_any, // bus buffer is full + output logic lsu_bus_buffer_empty_any, // bus buffer is empty + + output logic [3:0] ld_byte_hit_buf_lo, ld_byte_hit_buf_hi, // Byte enables for forwarding data + output logic [31:0] ld_fwddata_buf_lo, ld_fwddata_buf_hi, // load forwarding data + + output logic lsu_imprecise_error_load_any, // imprecise load bus error + output logic lsu_imprecise_error_store_any, // imprecise store bus error + output logic [31:0] lsu_imprecise_error_addr_any, // address of the imprecise error + + // Non-blocking loads + output logic lsu_nonblock_load_valid_m, // there is an external load -> put in the cam + output logic [pt.LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_tag_m, // the tag of the external non block load + output logic lsu_nonblock_load_inv_r, // invalidate signal for the cam entry for non block loads + output logic [pt.LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_inv_tag_r, // tag of the enrty which needs to be invalidated + output logic lsu_nonblock_load_data_valid, // the non block is valid - sending information back to the cam + output logic lsu_nonblock_load_data_error, // non block load has an error + output logic [pt.LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_data_tag, // the tag of the non block load sending the data/error + output logic [31:0] lsu_nonblock_load_data, // Data of the non block load + + // PMU events + output logic lsu_pmu_bus_trxn, + output logic lsu_pmu_bus_misaligned, + output logic lsu_pmu_bus_error, + output logic lsu_pmu_bus_busy, + + // AXI Write Channels + output logic lsu_axi_awvalid, + input logic lsu_axi_awready, + output logic [pt.LSU_BUS_TAG-1:0] lsu_axi_awid, + output logic [31:0] lsu_axi_awaddr, + output logic [3:0] lsu_axi_awregion, + /* exclude signals that are tied to constant value in this file */ + /*pragma coverage off*/ + output logic [7:0] lsu_axi_awlen, + /*pragma coverage on*/ + output logic [2:0] lsu_axi_awsize, + /* exclude signals that are tied to constant value in this file */ + /*pragma coverage off*/ + output logic [1:0] lsu_axi_awburst, + output logic lsu_axi_awlock, + /*pragma coverage on*/ + output logic [3:0] lsu_axi_awcache, + /* exclude signals that are tied to constant value in this file */ + /*pragma coverage off*/ + output logic [2:0] lsu_axi_awprot, + output logic [3:0] lsu_axi_awqos, + /*pragma coverage on*/ + + output logic lsu_axi_wvalid, + input logic lsu_axi_wready, + output logic [63:0] lsu_axi_wdata, + output logic [7:0] lsu_axi_wstrb, + output logic lsu_axi_wlast, + + input logic lsu_axi_bvalid, + /* exclude signals that are tied to constant value in this file */ + /*pragma coverage off*/ + output logic lsu_axi_bready, + /*pragma coverage on*/ + input logic [1:0] lsu_axi_bresp, + input logic [pt.LSU_BUS_TAG-1:0] lsu_axi_bid, + + // AXI Read Channels + output logic lsu_axi_arvalid, + input logic lsu_axi_arready, + output logic [pt.LSU_BUS_TAG-1:0] lsu_axi_arid, + output logic [31:0] lsu_axi_araddr, + output logic [3:0] lsu_axi_arregion, + /* exclude signals that are tied to constant value in this file */ + /*pragma coverage off*/ + output logic [7:0] lsu_axi_arlen, + /*pragma coverage on*/ + output logic [2:0] lsu_axi_arsize, + /* exclude signals that are tied to constant value in this file */ + /*pragma coverage off*/ + output logic [1:0] lsu_axi_arburst, + output logic lsu_axi_arlock, + /*pragma coverage on*/ + output logic [3:0] lsu_axi_arcache, + /* exclude signals that are tied to constant value in this file */ + /*pragma coverage off*/ + output logic [2:0] lsu_axi_arprot, + output logic [3:0] lsu_axi_arqos, + /*pragma coverage on*/ + + input logic lsu_axi_rvalid, + /* exclude signals that are tied to constant value in this file */ + /*pragma coverage off*/ + output logic lsu_axi_rready, + /*pragma coverage on*/ + input logic [pt.LSU_BUS_TAG-1:0] lsu_axi_rid, + input logic [63:0] lsu_axi_rdata, + input logic [1:0] lsu_axi_rresp, + + input logic lsu_bus_clk_en, + input logic lsu_bus_clk_en_q + +); + + // For Ld: IDLE -> START_WAIT -> CMD -> RESP -> DONE_PARTIAL(?) -> DONE_WAIT(?) -> DONE -> IDLE + // For St: IDLE -> START_WAIT -> CMD -> RESP(?) -> IDLE + typedef enum logic [2:0] {IDLE=3'b000, START_WAIT=3'b001, CMD=3'b010, RESP=3'b011, DONE_PARTIAL=3'b100, DONE_WAIT=3'b101, DONE=3'b110} state_t; + + localparam DEPTH = pt.LSU_NUM_NBLOAD; + localparam DEPTH_LOG2 = pt.LSU_NUM_NBLOAD_WIDTH; + localparam TIMER = 8; // This can be only power of 2 + localparam TIMER_MAX = TIMER - 1; // Maximum value of timer + localparam TIMER_LOG2 = (TIMER < 2) ? 1 : $clog2(TIMER); + + logic [3:0] ldst_byteen_hi_m, ldst_byteen_lo_m; + logic [DEPTH-1:0] ld_addr_hitvec_lo, ld_addr_hitvec_hi; + logic [3:0][DEPTH-1:0] ld_byte_hitvec_lo, ld_byte_hitvec_hi; + logic [3:0][DEPTH-1:0] ld_byte_hitvecfn_lo, ld_byte_hitvecfn_hi; + + logic ld_addr_ibuf_hit_lo, ld_addr_ibuf_hit_hi; + logic [3:0] ld_byte_ibuf_hit_lo, ld_byte_ibuf_hit_hi; + + logic [3:0] ldst_byteen_r; + logic [3:0] ldst_byteen_hi_r, ldst_byteen_lo_r; + logic [31:0] store_data_hi_r, store_data_lo_r; + logic is_aligned_r; // Aligned load/store + logic ldst_samedw_r; + + logic lsu_nonblock_load_valid_r; + logic [31:0] lsu_nonblock_load_data_hi, lsu_nonblock_load_data_lo, lsu_nonblock_data_unalgn; + logic [1:0] lsu_nonblock_addr_offset; + logic [1:0] lsu_nonblock_sz; + logic lsu_nonblock_unsign; + logic lsu_nonblock_load_data_ready; + + logic [DEPTH-1:0] CmdPtr0Dec, CmdPtr1Dec; + logic [DEPTH-1:0] RspPtrDec; + logic [DEPTH_LOG2-1:0] CmdPtr0, CmdPtr1; + logic [DEPTH_LOG2-1:0] RspPtr; + logic [DEPTH_LOG2-1:0] WrPtr0_m, WrPtr0_r; + logic [DEPTH_LOG2-1:0] WrPtr1_m, WrPtr1_r; + logic found_wrptr0, found_wrptr1, found_cmdptr0, found_cmdptr1; + logic [3:0] buf_numvld_any, buf_numvld_wrcmd_any, buf_numvld_cmd_any, buf_numvld_pend_any; + logic any_done_wait_state; + logic bus_sideeffect_pend; + logic bus_coalescing_disable; + + logic bus_addr_match_pending; + logic bus_cmd_sent, bus_cmd_ready; + logic bus_wcmd_sent, bus_wdata_sent; + logic bus_rsp_read, bus_rsp_write; + logic [pt.LSU_BUS_TAG-1:0] bus_rsp_read_tag, bus_rsp_write_tag; + logic bus_rsp_read_error, bus_rsp_write_error; + logic [63:0] bus_rsp_rdata; + + // Bus buffer signals + state_t [DEPTH-1:0] buf_state; + logic [DEPTH-1:0][1:0] buf_sz; + logic [DEPTH-1:0][31:0] buf_addr; + logic [DEPTH-1:0][3:0] buf_byteen; + logic [DEPTH-1:0] buf_sideeffect; + logic [DEPTH-1:0] buf_write; + logic [DEPTH-1:0] buf_unsign; + logic [DEPTH-1:0] buf_dual; + logic [DEPTH-1:0] buf_samedw; + logic [DEPTH-1:0] buf_nomerge; + logic [DEPTH-1:0] buf_dualhi; + logic [DEPTH-1:0][DEPTH_LOG2-1:0] buf_dualtag; + logic [DEPTH-1:0] buf_ldfwd; + logic [DEPTH-1:0][DEPTH_LOG2-1:0] buf_ldfwdtag; + logic [DEPTH-1:0] buf_error; + logic [DEPTH-1:0][31:0] buf_data; + logic [DEPTH-1:0][DEPTH-1:0] buf_age, buf_age_younger; + logic [DEPTH-1:0][DEPTH-1:0] buf_rspage, buf_rsp_pickage; + + state_t [DEPTH-1:0] buf_nxtstate; + logic [DEPTH-1:0] buf_rst; + logic [DEPTH-1:0] buf_state_en; + logic [DEPTH-1:0] buf_cmd_state_bus_en; + logic [DEPTH-1:0] buf_resp_state_bus_en; + logic [DEPTH-1:0] buf_state_bus_en; + logic [DEPTH-1:0] buf_dual_in; + logic [DEPTH-1:0] buf_samedw_in; + logic [DEPTH-1:0] buf_nomerge_in; + logic [DEPTH-1:0] buf_sideeffect_in; + logic [DEPTH-1:0] buf_unsign_in; + logic [DEPTH-1:0][1:0] buf_sz_in; + logic [DEPTH-1:0] buf_write_in; + logic [DEPTH-1:0] buf_wr_en; + logic [DEPTH-1:0] buf_dualhi_in; + logic [DEPTH-1:0][DEPTH_LOG2-1:0] buf_dualtag_in; + logic [DEPTH-1:0] buf_ldfwd_en; + logic [DEPTH-1:0] buf_ldfwd_in; + logic [DEPTH-1:0][DEPTH_LOG2-1:0] buf_ldfwdtag_in; + logic [DEPTH-1:0][3:0] buf_byteen_in; + logic [DEPTH-1:0][31:0] buf_addr_in; + logic [DEPTH-1:0][31:0] buf_data_in; + logic [DEPTH-1:0] buf_error_en; + logic [DEPTH-1:0] buf_data_en; + logic [DEPTH-1:0][DEPTH-1:0] buf_age_in; + logic [DEPTH-1:0][DEPTH-1:0] buf_ageQ; + logic [DEPTH-1:0][DEPTH-1:0] buf_rspage_set; + logic [DEPTH-1:0][DEPTH-1:0] buf_rspage_in; + logic [DEPTH-1:0][DEPTH-1:0] buf_rspageQ; + + // Input buffer signals + logic ibuf_valid; + logic ibuf_dual; + logic ibuf_samedw; + logic ibuf_nomerge; + logic [DEPTH_LOG2-1:0] ibuf_tag; + logic [DEPTH_LOG2-1:0] ibuf_dualtag; + logic ibuf_sideeffect; + logic ibuf_unsign; + logic ibuf_write; + logic [1:0] ibuf_sz; + logic [3:0] ibuf_byteen; + logic [31:0] ibuf_addr; + logic [31:0] ibuf_data; + logic [TIMER_LOG2-1:0] ibuf_timer; + + logic ibuf_byp; + logic ibuf_wr_en; + logic ibuf_rst; + logic ibuf_force_drain; + logic ibuf_drain_vld; + logic [DEPTH-1:0] ibuf_drainvec_vld; + logic [DEPTH_LOG2-1:0] ibuf_tag_in; + logic [DEPTH_LOG2-1:0] ibuf_dualtag_in; + logic [1:0] ibuf_sz_in; + logic [31:0] ibuf_addr_in; + logic [3:0] ibuf_byteen_in; + logic [31:0] ibuf_data_in; + logic [TIMER_LOG2-1:0] ibuf_timer_in; + logic [3:0] ibuf_byteen_out; + logic [31:0] ibuf_data_out; + logic ibuf_merge_en, ibuf_merge_in; + + // Output buffer signals + logic obuf_valid; + logic obuf_write; + logic obuf_nosend; + logic obuf_rdrsp_pend; + logic obuf_sideeffect; + logic [31:0] obuf_addr; + logic [63:0] obuf_data; + logic [1:0] obuf_sz; + logic [7:0] obuf_byteen; + logic obuf_merge; + logic obuf_cmd_done, obuf_data_done; + logic [pt.LSU_BUS_TAG-1:0] obuf_tag0; + logic [pt.LSU_BUS_TAG-1:0] obuf_tag1; + logic [pt.LSU_BUS_TAG-1:0] obuf_rdrsp_tag; + + logic ibuf_buf_byp; + logic obuf_force_wr_en; + logic obuf_wr_wait; + logic obuf_wr_en, obuf_wr_enQ; + logic obuf_rst; + logic obuf_write_in; + logic obuf_nosend_in; + logic obuf_rdrsp_pend_en; + logic obuf_rdrsp_pend_in; + logic obuf_sideeffect_in; + logic obuf_aligned_in; + logic [31:0] obuf_addr_in; + logic [63:0] obuf_data_in; + logic [1:0] obuf_sz_in; + logic [7:0] obuf_byteen_in; + logic obuf_merge_in; + logic obuf_cmd_done_in, obuf_data_done_in; + logic [pt.LSU_BUS_TAG-1:0] obuf_tag0_in; + logic [pt.LSU_BUS_TAG-1:0] obuf_tag1_in; + logic [pt.LSU_BUS_TAG-1:0] obuf_rdrsp_tag_in; + + logic obuf_merge_en; + logic [TIMER_LOG2-1:0] obuf_wr_timer, obuf_wr_timer_in; + logic [7:0] obuf_byteen0_in, obuf_byteen1_in; + logic [63:0] obuf_data0_in, obuf_data1_in; + + logic lsu_axi_awvalid_q, lsu_axi_awready_q; + logic lsu_axi_wvalid_q, lsu_axi_wready_q; + logic lsu_axi_arvalid_q, lsu_axi_arready_q; + logic lsu_axi_bvalid_q, lsu_axi_bready_q; + logic lsu_axi_rvalid_q, lsu_axi_rready_q; + logic [pt.LSU_BUS_TAG-1:0] lsu_axi_bid_q, lsu_axi_rid_q; + logic [1:0] lsu_axi_bresp_q, lsu_axi_rresp_q; + logic [pt.LSU_BUS_TAG-1:0] lsu_imprecise_error_store_tag; + logic [63:0] lsu_axi_rdata_q; + + //------------------------------------------------------------------------------ + // Load forwarding logic start + //------------------------------------------------------------------------------ + + // Function to do 8 to 3 bit encoding + function automatic logic [2:0] f_Enc8to3; + input logic [7:0] Dec_value; + + logic [2:0] Enc_value; + Enc_value[0] = Dec_value[1] | Dec_value[3] | Dec_value[5] | Dec_value[7]; + Enc_value[1] = Dec_value[2] | Dec_value[3] | Dec_value[6] | Dec_value[7]; + Enc_value[2] = Dec_value[4] | Dec_value[5] | Dec_value[6] | Dec_value[7]; + + return Enc_value[2:0]; + endfunction // f_Enc8to3 + + // Buffer hit logic for bus load forwarding + assign ldst_byteen_hi_m[3:0] = ldst_byteen_ext_m[7:4]; + assign ldst_byteen_lo_m[3:0] = ldst_byteen_ext_m[3:0]; + for (genvar i=0; i 4'b0) & (obuf_wr_timer < TIMER_MAX)) ? (obuf_wr_timer + 1'b1) : obuf_wr_timer); + assign obuf_force_wr_en = lsu_busreq_m & ~lsu_busreq_r & ~ibuf_valid & (buf_numvld_cmd_any[3:0] == 4'b1) & (lsu_addr_m[31:2] != buf_addr[CmdPtr0][31:2]); // Entry in m can't merge with entry going to obuf and there is no entry in between + assign ibuf_buf_byp = ibuf_byp & (buf_numvld_pend_any[3:0] == 4'b0) & (~lsu_pkt_r.store | no_dword_merge_r); + + assign obuf_wr_en = ((ibuf_buf_byp & lsu_commit_r & ~(is_sideeffects_r & bus_sideeffect_pend)) | + ((buf_state[CmdPtr0] == CMD) & found_cmdptr0 & ~buf_cmd_state_bus_en[CmdPtr0] & ~(buf_sideeffect[CmdPtr0] & bus_sideeffect_pend) & + (~(buf_dual[CmdPtr0] & buf_samedw[CmdPtr0] & ~buf_write[CmdPtr0]) | found_cmdptr1 | buf_nomerge[CmdPtr0] | obuf_force_wr_en))) & + (bus_cmd_ready | ~obuf_valid | obuf_nosend) & ~obuf_wr_wait & ~bus_addr_match_pending & lsu_bus_clk_en; + + assign obuf_rst = ((bus_cmd_sent | (obuf_valid & obuf_nosend)) & ~obuf_wr_en & lsu_bus_clk_en) | dec_tlu_force_halt; + + assign obuf_write_in = ibuf_buf_byp ? lsu_pkt_r.store : buf_write[CmdPtr0]; + assign obuf_sideeffect_in = ibuf_buf_byp ? is_sideeffects_r : buf_sideeffect[CmdPtr0]; + assign obuf_addr_in[31:0] = ibuf_buf_byp ? lsu_addr_r[31:0] : buf_addr[CmdPtr0]; + assign obuf_sz_in[1:0] = ibuf_buf_byp ? {lsu_pkt_r.word, lsu_pkt_r.half} : buf_sz[CmdPtr0]; + assign obuf_merge_in = obuf_merge_en; + assign obuf_tag0_in[pt.LSU_BUS_TAG-1:0] = ibuf_buf_byp ? (pt.LSU_BUS_TAG)'(WrPtr0_r) : (pt.LSU_BUS_TAG)'(CmdPtr0); + assign obuf_tag1_in[pt.LSU_BUS_TAG-1:0] = ibuf_buf_byp ? (pt.LSU_BUS_TAG)'(WrPtr1_r) : (pt.LSU_BUS_TAG)'(CmdPtr1); + + assign obuf_cmd_done_in = ~(obuf_wr_en | obuf_rst) & (obuf_cmd_done | bus_wcmd_sent); + assign obuf_data_done_in = ~(obuf_wr_en | obuf_rst) & (obuf_data_done | bus_wdata_sent); + + assign obuf_aligned_in = ibuf_buf_byp ? is_aligned_r : ((obuf_sz_in[1:0] == 2'b0) | + (obuf_sz_in[0] & ~obuf_addr_in[0]) | + (obuf_sz_in[1] & ~(|obuf_addr_in[1:0]))); + + assign obuf_rdrsp_pend_in = ((~(obuf_wr_en & ~obuf_nosend_in) & obuf_rdrsp_pend & ~(bus_rsp_read & (bus_rsp_read_tag == obuf_rdrsp_tag))) | (bus_cmd_sent & ~obuf_write)) & ~dec_tlu_force_halt; + assign obuf_rdrsp_pend_en = lsu_bus_clk_en | dec_tlu_force_halt; + assign obuf_rdrsp_tag_in[pt.LSU_BUS_TAG-1:0] = (bus_cmd_sent & ~obuf_write) ? obuf_tag0[pt.LSU_BUS_TAG-1:0] : obuf_rdrsp_tag[pt.LSU_BUS_TAG-1:0]; + // No ld to ld fwd for aligned + assign obuf_nosend_in = (obuf_addr_in[31:3] == obuf_addr[31:3]) & obuf_aligned_in & ~obuf_sideeffect & ~obuf_write & ~obuf_write_in & ~dec_tlu_external_ldfwd_disable & + ((obuf_valid & ~obuf_nosend) | (obuf_rdrsp_pend & ~(bus_rsp_read & (bus_rsp_read_tag == obuf_rdrsp_tag)))); + + assign obuf_byteen0_in[7:0] = ibuf_buf_byp ? (lsu_addr_r[2] ? {ldst_byteen_lo_r[3:0],4'b0} : {4'b0,ldst_byteen_lo_r[3:0]}) : + (buf_addr[CmdPtr0][2] ? {buf_byteen[CmdPtr0],4'b0} : {4'b0,buf_byteen[CmdPtr0]}); + assign obuf_byteen1_in[7:0] = ibuf_buf_byp ? (end_addr_r[2] ? {ldst_byteen_hi_r[3:0],4'b0} : {4'b0,ldst_byteen_hi_r[3:0]}) : + (buf_addr[CmdPtr1][2] ? {buf_byteen[CmdPtr1],4'b0} : {4'b0,buf_byteen[CmdPtr1]}); + assign obuf_data0_in[63:0] = ibuf_buf_byp ? (lsu_addr_r[2] ? {store_data_lo_r[31:0],32'b0} : {32'b0,store_data_lo_r[31:0]}) : + (buf_addr[CmdPtr0][2] ? {buf_data[CmdPtr0],32'b0} : {32'b0,buf_data[CmdPtr0]}); + assign obuf_data1_in[63:0] = ibuf_buf_byp ? (end_addr_r[2] ? {store_data_hi_r[31:0],32'b0} :{32'b0,store_data_hi_r[31:0]}) : + (buf_addr[CmdPtr1][2] ? {buf_data[CmdPtr1],32'b0} : {32'b0,buf_data[CmdPtr1]}); + + for (genvar i=0 ;i<8; i++) begin + assign obuf_byteen_in[i] = obuf_byteen0_in[i] | (obuf_merge_en & obuf_byteen1_in[i]); + assign obuf_data_in[(8*i)+7:(8*i)] = (obuf_merge_en & obuf_byteen1_in[i]) ? obuf_data1_in[(8*i)+7:(8*i)] : obuf_data0_in[(8*i)+7:(8*i)]; + end + + // No store obuf merging for AXI since all stores are sent non-posted. Can't track the second id right now + assign obuf_merge_en = ((CmdPtr0 != CmdPtr1) & found_cmdptr0 & found_cmdptr1 & (buf_state[CmdPtr0] == CMD) & (buf_state[CmdPtr1] == CMD) & + ~buf_cmd_state_bus_en[CmdPtr0] & ~buf_sideeffect[CmdPtr0] & + (~buf_write[CmdPtr0] & buf_dual[CmdPtr0] & ~buf_dualhi[CmdPtr0] & buf_samedw[CmdPtr0])) | // CmdPtr0/CmdPtr1 are for same load which is within a DW + (ibuf_buf_byp & ldst_samedw_r & ldst_dual_r); + + + rvdff_fpga #(.WIDTH(1)) obuf_wren_ff (.din(obuf_wr_en), .dout(obuf_wr_enQ), .clk(lsu_busm_clk), .clken(lsu_busm_clken), .rawclk(clk), .*); + rvdffsc #(.WIDTH(1)) obuf_valid_ff (.din(1'b1), .dout(obuf_valid), .en(obuf_wr_en), .clear(obuf_rst), .clk(lsu_free_c2_clk), .*); + rvdffs #(.WIDTH(1)) obuf_nosend_ff (.din(obuf_nosend_in), .dout(obuf_nosend), .en(obuf_wr_en), .clk(lsu_free_c2_clk), .*); + rvdffs #(.WIDTH(1)) obuf_rdrsp_pend_ff(.din(obuf_rdrsp_pend_in), .dout(obuf_rdrsp_pend), .en(obuf_rdrsp_pend_en), .clk(lsu_free_c2_clk), .*); + rvdff_fpga #(.WIDTH(1)) obuf_cmd_done_ff (.din(obuf_cmd_done_in), .dout(obuf_cmd_done), .clk(lsu_busm_clk), .clken(lsu_busm_clken), .rawclk(clk), .*); + rvdff_fpga #(.WIDTH(1)) obuf_data_done_ff (.din(obuf_data_done_in), .dout(obuf_data_done), .clk(lsu_busm_clk), .clken(lsu_busm_clken), .rawclk(clk), .*); + rvdff_fpga #(.WIDTH(pt.LSU_BUS_TAG)) obuf_rdrsp_tagff (.din(obuf_rdrsp_tag_in), .dout(obuf_rdrsp_tag), .clk(lsu_busm_clk), .clken(lsu_busm_clken), .rawclk(clk), .*); + rvdffs_fpga #(.WIDTH(pt.LSU_BUS_TAG)) obuf_tag0ff (.din(obuf_tag0_in), .dout(obuf_tag0), .en(obuf_wr_en), .clk(lsu_bus_obuf_c1_clk), .clken(lsu_bus_obuf_c1_clken), .rawclk(clk), .*); + rvdffs_fpga #(.WIDTH(pt.LSU_BUS_TAG)) obuf_tag1ff (.din(obuf_tag1_in), .dout(obuf_tag1), .en(obuf_wr_en), .clk(lsu_bus_obuf_c1_clk), .clken(lsu_bus_obuf_c1_clken), .rawclk(clk), .*); + rvdffs_fpga #(.WIDTH(1)) obuf_mergeff (.din(obuf_merge_in), .dout(obuf_merge), .en(obuf_wr_en), .clk(lsu_bus_obuf_c1_clk), .clken(lsu_bus_obuf_c1_clken), .rawclk(clk), .*); + rvdffs_fpga #(.WIDTH(1)) obuf_writeff (.din(obuf_write_in), .dout(obuf_write), .en(obuf_wr_en), .clk(lsu_bus_obuf_c1_clk), .clken(lsu_bus_obuf_c1_clken), .rawclk(clk), .*); + rvdffs_fpga #(.WIDTH(1)) obuf_sideeffectff (.din(obuf_sideeffect_in), .dout(obuf_sideeffect), .en(obuf_wr_en), .clk(lsu_bus_obuf_c1_clk), .clken(lsu_bus_obuf_c1_clken), .rawclk(clk), .*); + rvdffs_fpga #(.WIDTH(2)) obuf_szff (.din(obuf_sz_in[1:0]), .dout(obuf_sz), .en(obuf_wr_en), .clk(lsu_bus_obuf_c1_clk), .clken(lsu_bus_obuf_c1_clken), .rawclk(clk), .*); + rvdffs_fpga #(.WIDTH(8)) obuf_byteenff (.din(obuf_byteen_in[7:0]), .dout(obuf_byteen), .en(obuf_wr_en), .clk(lsu_bus_obuf_c1_clk), .clken(lsu_bus_obuf_c1_clken), .rawclk(clk), .*); + rvdffe #(.WIDTH(32)) obuf_addrff (.din(obuf_addr_in[31:0]), .dout(obuf_addr), .en(obuf_wr_en), .*); + rvdffe #(.WIDTH(64)) obuf_dataff (.din(obuf_data_in[63:0]), .dout(obuf_data), .en(obuf_wr_en), .*); + rvdff_fpga #(.WIDTH(TIMER_LOG2)) obuf_timerff (.din(obuf_wr_timer_in), .dout(obuf_wr_timer), .clk(lsu_busm_clk), .clken(lsu_busm_clken), .rawclk(clk), .*); + + + //------------------------------------------------------------------------------ + // Output buffer logic ends here + //------------------------------------------------------------------------------ + + // Find the entry to allocate and entry to send + always_comb begin + WrPtr0_m[DEPTH_LOG2-1:0] = '0; + WrPtr1_m[DEPTH_LOG2-1:0] = '0; + found_wrptr0 = '0; + found_wrptr1 = '0; + + // Find first write pointer + for (int i=0; i= (DEPTH-1)) : (buf_numvld_any[3:0] == DEPTH); + assign lsu_bus_buffer_empty_any = ~(|buf_state[DEPTH-1:0]) & ~ibuf_valid & ~obuf_valid; + + + // Non blocking ports + assign lsu_nonblock_load_valid_m = lsu_busreq_m & lsu_pkt_m.valid & lsu_pkt_m.load & ~flush_m_up & ~ld_full_hit_m; + assign lsu_nonblock_load_tag_m[DEPTH_LOG2-1:0] = WrPtr0_m[DEPTH_LOG2-1:0]; + assign lsu_nonblock_load_inv_r = lsu_nonblock_load_valid_r & ~lsu_commit_r; + assign lsu_nonblock_load_inv_tag_r[DEPTH_LOG2-1:0] = WrPtr0_r[DEPTH_LOG2-1:0]; // r tag needs to be accurate even if there is no invalidate + + always_comb begin + lsu_nonblock_load_data_ready = '0; + lsu_nonblock_load_data_error = '0; + lsu_nonblock_load_data_tag[DEPTH_LOG2-1:0] = '0; + lsu_nonblock_load_data_lo[31:0] = '0; + lsu_nonblock_load_data_hi[31:0] = '0; + for (int i=0; i> 8*lsu_nonblock_addr_offset[1:0]); + + assign lsu_nonblock_load_data_valid = lsu_nonblock_load_data_ready & ~lsu_nonblock_load_data_error; + assign lsu_nonblock_load_data[31:0] = ({32{ lsu_nonblock_unsign & (lsu_nonblock_sz[1:0] == 2'b00)}} & {24'b0,lsu_nonblock_data_unalgn[7:0]}) | + ({32{ lsu_nonblock_unsign & (lsu_nonblock_sz[1:0] == 2'b01)}} & {16'b0,lsu_nonblock_data_unalgn[15:0]}) | + ({32{~lsu_nonblock_unsign & (lsu_nonblock_sz[1:0] == 2'b00)}} & {{24{lsu_nonblock_data_unalgn[7]}}, lsu_nonblock_data_unalgn[7:0]}) | + ({32{~lsu_nonblock_unsign & (lsu_nonblock_sz[1:0] == 2'b01)}} & {{16{lsu_nonblock_data_unalgn[15]}},lsu_nonblock_data_unalgn[15:0]}) | + ({32{(lsu_nonblock_sz[1:0] == 2'b10)}} & lsu_nonblock_data_unalgn[31:0]); + + // Determine if there is a pending return to sideeffect load/store + always_comb begin + bus_sideeffect_pend = obuf_valid & obuf_sideeffect & dec_tlu_sideeffect_posted_disable; + for (int i=0; i put in the cam + output logic [pt.LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_tag_m, // the tag of the external non block load + output logic lsu_nonblock_load_inv_r, // invalidate signal for the cam entry for non block loads + output logic [pt.LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_inv_tag_r, // tag of the enrty which needs to be invalidated + output logic lsu_nonblock_load_data_valid,// the non block is valid - sending information back to the cam + output logic lsu_nonblock_load_data_error,// non block load has an error + output logic [pt.LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_data_tag, // the tag of the non block load sending the data/error + output logic [31:0] lsu_nonblock_load_data, // Data of the non block load + + // PMU events + output logic lsu_pmu_bus_trxn, + output logic lsu_pmu_bus_misaligned, + output logic lsu_pmu_bus_error, + output logic lsu_pmu_bus_busy, + + // AXI Write Channels + output logic lsu_axi_awvalid, + input logic lsu_axi_awready, + output logic [pt.LSU_BUS_TAG-1:0] lsu_axi_awid, + output logic [31:0] lsu_axi_awaddr, + output logic [3:0] lsu_axi_awregion, + /* exclude signals that are tied to constant value in el2_lsu_bus_buffer.sv */ + /*pragma coverage off*/ + output logic [7:0] lsu_axi_awlen, + /*pragma coverage on*/ + output logic [2:0] lsu_axi_awsize, + /* exclude signals that are tied to constant value in el2_lsu_bus_buffer.sv */ + /*pragma coverage off*/ + output logic [1:0] lsu_axi_awburst, + output logic lsu_axi_awlock, + /*pragma coverage on*/ + output logic [3:0] lsu_axi_awcache, + /* exclude signals that are tied to constant value in el2_lsu_bus_buffer.sv */ + /*pragma coverage off*/ + output logic [2:0] lsu_axi_awprot, + output logic [3:0] lsu_axi_awqos, + /*pragma coverage on*/ + + output logic lsu_axi_wvalid, + input logic lsu_axi_wready, + output logic [63:0] lsu_axi_wdata, + output logic [7:0] lsu_axi_wstrb, + output logic lsu_axi_wlast, + + input logic lsu_axi_bvalid, + /* exclude signals that are tied to constant value in el2_lsu_bus_buffer.sv */ + /*pragma coverage off*/ + output logic lsu_axi_bready, + /*pragma coverage on*/ + input logic [1:0] lsu_axi_bresp, + input logic [pt.LSU_BUS_TAG-1:0] lsu_axi_bid, + + // AXI Read Channels + output logic lsu_axi_arvalid, + input logic lsu_axi_arready, + output logic [pt.LSU_BUS_TAG-1:0] lsu_axi_arid, + output logic [31:0] lsu_axi_araddr, + output logic [3:0] lsu_axi_arregion, + /* exclude signals that are tied to constant value in el2_lsu_bus_buffer.sv */ + /*pragma coverage off*/ + output logic [7:0] lsu_axi_arlen, + /*pragma coverage on*/ + output logic [2:0] lsu_axi_arsize, + /* exclude signals that are tied to constant value in el2_lsu_bus_buffer.sv */ + /*pragma coverage off*/ + output logic [1:0] lsu_axi_arburst, + output logic lsu_axi_arlock, + /*pragma coverage on*/ + output logic [3:0] lsu_axi_arcache, + /* exclude signals that are tied to constant value in el2_lsu_bus_buffer.sv */ + /*pragma coverage off*/ + output logic [2:0] lsu_axi_arprot, + output logic [3:0] lsu_axi_arqos, + /*pragma coverage on*/ + + input logic lsu_axi_rvalid, + /* exclude signals that are tied to constant value in el2_lsu_bus_buffer.sv */ + /*pragma coverage off*/ + output logic lsu_axi_rready, + /*pragma coverage on*/ + input logic [pt.LSU_BUS_TAG-1:0] lsu_axi_rid, + input logic [63:0] lsu_axi_rdata, + input logic [1:0] lsu_axi_rresp, + + input logic lsu_bus_clk_en + +); + + + + logic lsu_bus_clk_en_q; + + logic [3:0] ldst_byteen_m, ldst_byteen_r; + logic [7:0] ldst_byteen_ext_m, ldst_byteen_ext_r; + logic [3:0] ldst_byteen_hi_m, ldst_byteen_hi_r; + logic [3:0] ldst_byteen_lo_m, ldst_byteen_lo_r; + logic is_sideeffects_r; + + logic [63:0] store_data_ext_r; + logic [31:0] store_data_hi_r; + logic [31:0] store_data_lo_r; + + logic addr_match_dw_lo_r_m; + logic addr_match_word_lo_r_m; + logic no_word_merge_r, no_dword_merge_r; + + logic ld_addr_rhit_lo_lo, ld_addr_rhit_hi_lo, ld_addr_rhit_lo_hi, ld_addr_rhit_hi_hi; + logic [3:0] ld_byte_rhit_lo_lo, ld_byte_rhit_hi_lo, ld_byte_rhit_lo_hi, ld_byte_rhit_hi_hi; + + logic [3:0] ld_byte_hit_lo, ld_byte_rhit_lo; + logic [3:0] ld_byte_hit_hi, ld_byte_rhit_hi; + + logic [31:0] ld_fwddata_rpipe_lo; + logic [31:0] ld_fwddata_rpipe_hi; + + logic [3:0] ld_byte_hit_buf_lo, ld_byte_hit_buf_hi; + logic [31:0] ld_fwddata_buf_lo, ld_fwddata_buf_hi; + + logic [63:0] ld_fwddata_lo, ld_fwddata_hi; + logic [63:0] ld_fwddata_m; + + logic ld_full_hit_hi_m, ld_full_hit_lo_m; + logic ld_full_hit_m; + + assign ldst_byteen_m[3:0] = ({4{lsu_pkt_m.by}} & 4'b0001) | + ({4{lsu_pkt_m.half}} & 4'b0011) | + ({4{lsu_pkt_m.word}} & 4'b1111); + + // Read/Write Buffer + el2_lsu_bus_buffer #(.pt(pt)) bus_buffer ( + .* + ); + + // Logic to determine if dc5 store can be coalesced or not with younger stores. Bypass ibuf if cannot colaesced + assign addr_match_dw_lo_r_m = (lsu_addr_r[31:3] == lsu_addr_m[31:3]); + assign addr_match_word_lo_r_m = addr_match_dw_lo_r_m & ~(lsu_addr_r[2]^lsu_addr_m[2]); + + assign no_word_merge_r = lsu_busreq_r & ~ldst_dual_r & lsu_busreq_m & (lsu_pkt_m.load | ~addr_match_word_lo_r_m); + assign no_dword_merge_r = lsu_busreq_r & ~ldst_dual_r & lsu_busreq_m & (lsu_pkt_m.load | ~addr_match_dw_lo_r_m); + + // Create Hi/Lo signals + assign ldst_byteen_ext_m[7:0] = {4'b0,ldst_byteen_m[3:0]} << lsu_addr_m[1:0]; + assign ldst_byteen_ext_r[7:0] = {4'b0,ldst_byteen_r[3:0]} << lsu_addr_r[1:0]; + + assign store_data_ext_r[63:0] = {32'b0,store_data_r[31:0]} << {lsu_addr_r[1:0],3'b0}; + + assign ldst_byteen_hi_m[3:0] = ldst_byteen_ext_m[7:4]; + assign ldst_byteen_lo_m[3:0] = ldst_byteen_ext_m[3:0]; + assign ldst_byteen_hi_r[3:0] = ldst_byteen_ext_r[7:4]; + assign ldst_byteen_lo_r[3:0] = ldst_byteen_ext_r[3:0]; + + assign store_data_hi_r[31:0] = store_data_ext_r[63:32]; + assign store_data_lo_r[31:0] = store_data_ext_r[31:0]; + + assign ld_addr_rhit_lo_lo = (lsu_addr_m[31:2] == lsu_addr_r[31:2]) & lsu_pkt_r.valid & lsu_pkt_r.store & lsu_busreq_m & lsu_busreq_r; + assign ld_addr_rhit_lo_hi = (end_addr_m[31:2] == lsu_addr_r[31:2]) & lsu_pkt_r.valid & lsu_pkt_r.store & lsu_busreq_m & lsu_busreq_r; + assign ld_addr_rhit_hi_lo = (lsu_addr_m[31:2] == end_addr_r[31:2]) & lsu_pkt_r.valid & lsu_pkt_r.store & lsu_busreq_m & lsu_busreq_r; + assign ld_addr_rhit_hi_hi = (end_addr_m[31:2] == end_addr_r[31:2]) & lsu_pkt_r.valid & lsu_pkt_r.store & lsu_busreq_m & lsu_busreq_r; + + for (genvar i=0; i<4; i++) begin: GenBusBufFwd + assign ld_byte_rhit_lo_lo[i] = ld_addr_rhit_lo_lo & ldst_byteen_lo_r[i] & ldst_byteen_lo_m[i]; + assign ld_byte_rhit_lo_hi[i] = ld_addr_rhit_lo_hi & ldst_byteen_lo_r[i] & ldst_byteen_hi_m[i]; + assign ld_byte_rhit_hi_lo[i] = ld_addr_rhit_hi_lo & ldst_byteen_hi_r[i] & ldst_byteen_lo_m[i]; + assign ld_byte_rhit_hi_hi[i] = ld_addr_rhit_hi_hi & ldst_byteen_hi_r[i] & ldst_byteen_hi_m[i]; + + assign ld_byte_hit_lo[i] = ld_byte_rhit_lo_lo[i] | ld_byte_rhit_hi_lo[i] | + ld_byte_hit_buf_lo[i]; + + assign ld_byte_hit_hi[i] = ld_byte_rhit_lo_hi[i] | ld_byte_rhit_hi_hi[i] | + ld_byte_hit_buf_hi[i]; + + assign ld_byte_rhit_lo[i] = ld_byte_rhit_lo_lo[i] | ld_byte_rhit_hi_lo[i]; + assign ld_byte_rhit_hi[i] = ld_byte_rhit_lo_hi[i] | ld_byte_rhit_hi_hi[i]; + + assign ld_fwddata_rpipe_lo[(8*i)+7:(8*i)] = ({8{ld_byte_rhit_lo_lo[i]}} & store_data_lo_r[(8*i)+7:(8*i)]) | + ({8{ld_byte_rhit_hi_lo[i]}} & store_data_hi_r[(8*i)+7:(8*i)]); + + assign ld_fwddata_rpipe_hi[(8*i)+7:(8*i)] = ({8{ld_byte_rhit_lo_hi[i]}} & store_data_lo_r[(8*i)+7:(8*i)]) | + ({8{ld_byte_rhit_hi_hi[i]}} & store_data_hi_r[(8*i)+7:(8*i)]); + + // Final muxing between m/r + assign ld_fwddata_lo[(8*i)+7:(8*i)] = ld_byte_rhit_lo[i] ? ld_fwddata_rpipe_lo[(8*i)+7:(8*i)] : ld_fwddata_buf_lo[(8*i)+7:(8*i)]; + + assign ld_fwddata_hi[(8*i)+7:(8*i)] = ld_byte_rhit_hi[i] ? ld_fwddata_rpipe_hi[(8*i)+7:(8*i)] : ld_fwddata_buf_hi[(8*i)+7:(8*i)]; + + end + + always_comb begin + ld_full_hit_lo_m = 1'b1; + ld_full_hit_hi_m = 1'b1; + for (int i=0; i<4; i++) begin + ld_full_hit_lo_m &= (ld_byte_hit_lo[i] | ~ldst_byteen_lo_m[i]); + ld_full_hit_hi_m &= (ld_byte_hit_hi[i] | ~ldst_byteen_hi_m[i]); + end + end + + // This will be high if all the bytes of load hit the stores in pipe/write buffer (m/r/wrbuf) + assign ld_full_hit_m = ld_full_hit_lo_m & ld_full_hit_hi_m & lsu_busreq_m & lsu_pkt_m.load & ~is_sideeffects_m; + + assign ld_fwddata_m[63:0] = 64'({ld_fwddata_hi[31:0], ld_fwddata_lo[31:0]} >> (8*lsu_addr_m[1:0])); + assign bus_read_data_m[31:0] = ld_fwddata_m[31:0]; + + // Fifo flops + + rvdff #(.WIDTH(1)) clken_ff (.din(lsu_bus_clk_en), .dout(lsu_bus_clk_en_q), .clk(active_clk), .*); + + rvdff #(.WIDTH(1)) is_sideeffects_rff (.din(is_sideeffects_m), .dout(is_sideeffects_r), .clk(lsu_c1_r_clk), .*); + + rvdff #(4) lsu_byten_rff (.*, .din(ldst_byteen_m[3:0]), .dout(ldst_byteen_r[3:0]), .clk(lsu_c1_r_clk)); + +`ifdef RV_ASSERT_ON + + // Assertion to check AXI write address is aligned to size + property lsu_axi_awaddr_aligned; + @(posedge lsu_busm_clk) disable iff(~rst_l) lsu_axi_awvalid |-> ((lsu_axi_awsize[2:0] == 3'h0) | + ((lsu_axi_awsize[2:0] == 3'h1) & (lsu_axi_awaddr[0] == 1'b0)) | + ((lsu_axi_awsize[2:0] == 3'h2) & (lsu_axi_awaddr[1:0] == 2'b0)) | + ((lsu_axi_awsize[2:0] == 3'h3) & (lsu_axi_awaddr[2:0] == 3'b0))); + endproperty + assert_lsu_axi_awaddr_aligned: assert property (lsu_axi_awaddr_aligned) else + $display("Assertion lsu_axi_awaddr_aligned failed: lsu_axi_awvalid=1'b%b, lsu_axi_awsize=3'h%h, lsu_axi_awaddr=32'h%h",lsu_axi_awvalid, lsu_axi_awsize[2:0], lsu_axi_awaddr[31:0]); + // Assertion to check awvalid stays stable during entire bus clock + + // Assertion to check AXI read address is aligned to size + property lsu_axi_araddr_aligned; + @(posedge lsu_busm_clk) disable iff(~rst_l) lsu_axi_arvalid |-> ((lsu_axi_arsize[2:0] == 3'h0) | + ((lsu_axi_arsize[2:0] == 3'h1) & (lsu_axi_araddr[0] == 1'b0)) | + ((lsu_axi_arsize[2:0] == 3'h2) & (lsu_axi_araddr[1:0] == 2'b0)) | + ((lsu_axi_arsize[2:0] == 3'h3) & (lsu_axi_araddr[2:0] == 3'b0))); + endproperty + assert_lsu_axi_araddr_aligned: assert property (lsu_axi_araddr_aligned) else + $display("Assertion lsu_axi_araddr_aligned failed: lsu_axi_awvalid=1'b%b, lsu_axi_awsize=3'h%h, lsu_axi_araddr=32'h%h",lsu_axi_awvalid, lsu_axi_awsize[2:0], lsu_axi_araddr[31:0]); + + // Assertion to check awvalid stays stable during entire bus clock + property lsu_axi_awvalid_stable; + @(posedge clk) disable iff(~rst_l) (lsu_axi_awvalid != $past(lsu_axi_awvalid)) |-> ($past(lsu_bus_clk_en) | dec_tlu_force_halt); + endproperty + assert_lsu_axi_awvalid_stable: assert property (lsu_axi_awvalid_stable) else + $display("LSU AXI awvalid changed in middle of bus clock"); + + // Assertion to check awid stays stable during entire bus clock + property lsu_axi_awid_stable; + @(posedge clk) disable iff(~rst_l) (lsu_axi_awvalid & (lsu_axi_awid[pt.LSU_BUS_TAG-1:0] != $past(lsu_axi_awid[pt.LSU_BUS_TAG-1:0]))) |-> $past(lsu_bus_clk_en); + endproperty + assert_lsu_axi_awid_stable: assert property (lsu_axi_awid_stable) else + $display("LSU AXI awid changed in middle of bus clock"); + + // Assertion to check awaddr stays stable during entire bus clock + property lsu_axi_awaddr_stable; + @(posedge clk) disable iff(~rst_l) (lsu_axi_awvalid & (lsu_axi_awaddr[31:0] != $past(lsu_axi_awaddr[31:0]))) |-> $past(lsu_bus_clk_en); + endproperty + assert_lsu_axi_awaddr_stable: assert property (lsu_axi_awaddr_stable) else + $display("LSU AXI awaddr changed in middle of bus clock"); + + // Assertion to check awsize stays stable during entire bus clock + property lsu_axi_awsize_stable; + @(posedge clk) disable iff(~rst_l) (lsu_axi_awvalid & (lsu_axi_awsize[2:0] != $past(lsu_axi_awsize[2:0]))) |-> $past(lsu_bus_clk_en); + endproperty + assert_lsu_axi_awsize_stable: assert property (lsu_axi_awsize_stable) else + $display("LSU AXI awsize changed in middle of bus clock"); + + // Assertion to check wstrb stays stable during entire bus clock + property lsu_axi_wstrb_stable; + @(posedge clk) disable iff(~rst_l) (lsu_axi_wvalid & (lsu_axi_wstrb[7:0] != $past(lsu_axi_wstrb[7:0]))) |-> $past(lsu_bus_clk_en); + endproperty + assert_lsu_axi_wstrb_stable: assert property (lsu_axi_wstrb_stable) else + $display("LSU AXI wstrb changed in middle of bus clock"); + + // Assertion to check wdata stays stable during entire bus clock + property lsu_axi_wdata_stable; + @(posedge clk) disable iff(~rst_l) (lsu_axi_wvalid & (lsu_axi_wdata[63:0] != $past(lsu_axi_wdata[63:0]))) |-> $past(lsu_bus_clk_en); + endproperty + assert_lsu_axi_wdata_stable: assert property (lsu_axi_wdata_stable) else + $display("LSU AXI wdata changed in middle of bus clock"); + + // Assertion to check awvalid stays stable during entire bus clock + property lsu_axi_arvalid_stable; + @(posedge clk) disable iff(~rst_l) (lsu_axi_arvalid != $past(lsu_axi_arvalid)) |-> ($past(lsu_bus_clk_en) | dec_tlu_force_halt); + endproperty + assert_lsu_axi_arvalid_stable: assert property (lsu_axi_arvalid_stable) else + $display("LSU AXI awvalid changed in middle of bus clock"); + + // Assertion to check awid stays stable during entire bus clock + property lsu_axi_arid_stable; + @(posedge clk) disable iff(~rst_l) (lsu_axi_arvalid & (lsu_axi_arid[pt.LSU_BUS_TAG-1:0] != $past(lsu_axi_arid[pt.LSU_BUS_TAG-1:0]))) |-> $past(lsu_bus_clk_en); + endproperty + assert_lsu_axi_arid_stable: assert property (lsu_axi_arid_stable) else + $display("LSU AXI awid changed in middle of bus clock"); + + // Assertion to check awaddr stays stable during entire bus clock + property lsu_axi_araddr_stable; + @(posedge clk) disable iff(~rst_l) (lsu_axi_arvalid & (lsu_axi_araddr[31:0] != $past(lsu_axi_araddr[31:0]))) |-> $past(lsu_bus_clk_en); + endproperty + assert_lsu_axi_araddr_stable: assert property (lsu_axi_araddr_stable) else + $display("LSU AXI awaddr changed in middle of bus clock"); + + // Assertion to check awsize stays stable during entire bus clock + property lsu_axi_arsize_stable; + @(posedge clk) disable iff(~rst_l) (lsu_axi_awvalid & (lsu_axi_arsize[2:0] != $past(lsu_axi_arsize[2:0]))) |-> $past(lsu_bus_clk_en); + endproperty + assert_lsu_axi_arsize_stable: assert property (lsu_axi_arsize_stable) else + $display("LSU AXI awsize changed in middle of bus clock"); + +`endif + +endmodule // el2_lsu_bus_intf diff --git a/designs/Caliptra/src/caliptra-rtl/el2_lsu_clkdomain.sv b/designs/Caliptra/src/caliptra-rtl/el2_lsu_clkdomain.sv new file mode 100644 index 0000000..268ac62 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/el2_lsu_clkdomain.sv @@ -0,0 +1,148 @@ +// Copyright 2020 Western Digital Corporation or its affiliates. +// +// 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. + +//******************************************************************************** +// $Id$ +// +// +// Owner: +// Function: Clock Generation Block +// Comments: All the clocks are generate here +// +// //******************************************************************************** + + +module el2_lsu_clkdomain +import el2_pkg::*; +#( +`include "el2_param.vh" +)( + input logic clk, // Clock only while core active. Through one clock header. For flops with second clock header built in. Connected to ACTIVE_L2CLK. + input logic active_clk, // Clock only while core active. Through two clock headers. For flops without second clock header built in. + input logic rst_l, // reset, active low + input logic dec_tlu_force_halt, // This will be high till TLU goes to debug halt + + // Inputs + input logic clk_override, // chciken bit to turn off clock gating + input logic dma_dccm_req, // dma is active + input logic ldst_stbuf_reqvld_r, // allocating in to the store queue + + input logic stbuf_reqvld_any, // stbuf is draining + input logic stbuf_reqvld_flushed_any, // instruction going to stbuf is flushed + input logic lsu_busreq_r, // busreq in r + input logic lsu_bus_buffer_pend_any, // bus buffer has a pending bus entry + input logic lsu_bus_buffer_empty_any, // external bus buffer is empty + input logic lsu_stbuf_empty_any, // stbuf is empty + + input logic lsu_bus_clk_en, // bus clock enable + + input el2_lsu_pkt_t lsu_p, // lsu packet in decode + input el2_lsu_pkt_t lsu_pkt_d, // lsu packet in d + input el2_lsu_pkt_t lsu_pkt_m, // lsu packet in m + input el2_lsu_pkt_t lsu_pkt_r, // lsu packet in r + + // Outputs + output logic lsu_bus_obuf_c1_clken, // obuf clock enable + output logic lsu_busm_clken, // bus clock enable + + output logic lsu_c1_m_clk, // m pipe single pulse clock + output logic lsu_c1_r_clk, // r pipe single pulse clock + + output logic lsu_c2_m_clk, // m pipe double pulse clock + output logic lsu_c2_r_clk, // r pipe double pulse clock + + output logic lsu_store_c1_m_clk, // store in m + output logic lsu_store_c1_r_clk, // store in r + + output logic lsu_stbuf_c1_clk, + output logic lsu_bus_obuf_c1_clk, // ibuf clock + output logic lsu_bus_ibuf_c1_clk, // ibuf clock + output logic lsu_bus_buf_c1_clk, // ibuf clock + output logic lsu_busm_clk, // bus clock + + output logic lsu_free_c2_clk, // free double pulse clock + + // Excluding scan_mode from coverage as its usage is determined by the integrator of the VeeR core. + /*pragma coverage off*/ + input logic scan_mode // Scan mode + /*pragma coverage on*/ +); + + logic lsu_c1_m_clken, lsu_c1_r_clken; + logic lsu_c2_m_clken, lsu_c2_r_clken; + logic lsu_c1_m_clken_q, lsu_c1_r_clken_q; + logic lsu_store_c1_m_clken, lsu_store_c1_r_clken; + + + logic lsu_stbuf_c1_clken; + logic lsu_bus_ibuf_c1_clken, lsu_bus_buf_c1_clken; + + logic lsu_free_c1_clken, lsu_free_c1_clken_q, lsu_free_c2_clken; + + //------------------------------------------------------------------------------------------- + // Clock Enable logic + //------------------------------------------------------------------------------------------- + + assign lsu_c1_m_clken = lsu_p.valid | dma_dccm_req | clk_override; + assign lsu_c1_r_clken = lsu_pkt_m.valid | lsu_c1_m_clken_q | clk_override; + + assign lsu_c2_m_clken = lsu_c1_m_clken | lsu_c1_m_clken_q | clk_override; + assign lsu_c2_r_clken = lsu_c1_r_clken | lsu_c1_r_clken_q | clk_override; + + assign lsu_store_c1_m_clken = ((lsu_c1_m_clken & lsu_pkt_d.store) | clk_override) ; + assign lsu_store_c1_r_clken = ((lsu_c1_r_clken & lsu_pkt_m.store) | clk_override) ; + + assign lsu_stbuf_c1_clken = ldst_stbuf_reqvld_r | stbuf_reqvld_any | stbuf_reqvld_flushed_any | clk_override; + assign lsu_bus_ibuf_c1_clken = lsu_busreq_r | clk_override; + assign lsu_bus_obuf_c1_clken = (lsu_bus_buffer_pend_any | lsu_busreq_r | clk_override) & lsu_bus_clk_en; + assign lsu_bus_buf_c1_clken = ~lsu_bus_buffer_empty_any | lsu_busreq_r | dec_tlu_force_halt | clk_override; + + assign lsu_free_c1_clken = (lsu_p.valid | lsu_pkt_d.valid | lsu_pkt_m.valid | lsu_pkt_r.valid) | + ~lsu_bus_buffer_empty_any | ~lsu_stbuf_empty_any | clk_override; + assign lsu_free_c2_clken = lsu_free_c1_clken | lsu_free_c1_clken_q | clk_override; + + // Flops + rvdff #(1) lsu_free_c1_clkenff (.din(lsu_free_c1_clken), .dout(lsu_free_c1_clken_q), .clk(active_clk), .*); + + rvdff #(1) lsu_c1_m_clkenff (.din(lsu_c1_m_clken), .dout(lsu_c1_m_clken_q), .clk(lsu_free_c2_clk), .*); + rvdff #(1) lsu_c1_r_clkenff (.din(lsu_c1_r_clken), .dout(lsu_c1_r_clken_q), .clk(lsu_free_c2_clk), .*); + + // Clock Headers + rvoclkhdr lsu_c1m_cgc ( .en(lsu_c1_m_clken), .l1clk(lsu_c1_m_clk), .* ); + rvoclkhdr lsu_c1r_cgc ( .en(lsu_c1_r_clken), .l1clk(lsu_c1_r_clk), .* ); + + rvoclkhdr lsu_c2m_cgc ( .en(lsu_c2_m_clken), .l1clk(lsu_c2_m_clk), .* ); + rvoclkhdr lsu_c2r_cgc ( .en(lsu_c2_r_clken), .l1clk(lsu_c2_r_clk), .* ); + + rvoclkhdr lsu_store_c1m_cgc (.en(lsu_store_c1_m_clken), .l1clk(lsu_store_c1_m_clk), .*); + rvoclkhdr lsu_store_c1r_cgc (.en(lsu_store_c1_r_clken), .l1clk(lsu_store_c1_r_clk), .*); + + rvoclkhdr lsu_stbuf_c1_cgc ( .en(lsu_stbuf_c1_clken), .l1clk(lsu_stbuf_c1_clk), .* ); + rvoclkhdr lsu_bus_ibuf_c1_cgc ( .en(lsu_bus_ibuf_c1_clken), .l1clk(lsu_bus_ibuf_c1_clk), .* ); + rvoclkhdr lsu_bus_buf_c1_cgc ( .en(lsu_bus_buf_c1_clken), .l1clk(lsu_bus_buf_c1_clk), .* ); + + assign lsu_busm_clken = (~lsu_bus_buffer_empty_any | lsu_busreq_r | clk_override) & lsu_bus_clk_en; + +`ifdef RV_FPGA_OPTIMIZE + assign lsu_busm_clk = 1'b0; + assign lsu_bus_obuf_c1_clk = 1'b0; +`else + rvclkhdr lsu_bus_obuf_c1_cgc ( .en(lsu_bus_obuf_c1_clken), .l1clk(lsu_bus_obuf_c1_clk), .* ); + rvclkhdr lsu_busm_cgc (.en(lsu_busm_clken), .l1clk(lsu_busm_clk), .*); +`endif + + rvoclkhdr lsu_free_cgc (.en(lsu_free_c2_clken), .l1clk(lsu_free_c2_clk), .*); + +endmodule + diff --git a/designs/Caliptra/src/caliptra-rtl/el2_lsu_dccm_ctl.sv b/designs/Caliptra/src/caliptra-rtl/el2_lsu_dccm_ctl.sv new file mode 100644 index 0000000..e0fbb98 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/el2_lsu_dccm_ctl.sv @@ -0,0 +1,428 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2020 Western Digital Corporation or its affiliates. +// +// 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. + +//******************************************************************************** +// $Id$ +// +// +// Owner: +// Function: DCCM for LSU pipe +// Comments: Single ported memory +// +// +// DC1 -> DC2 -> DC3 -> DC4 (Commit) +// +// //******************************************************************************** + +module el2_lsu_dccm_ctl +import el2_pkg::*; +#( +`include "el2_param.vh" + ) + ( + input logic lsu_c2_m_clk, // clocks + input logic lsu_c2_r_clk, // clocks + input logic lsu_c1_r_clk, // clocks + input logic lsu_store_c1_r_clk, // clocks + input logic lsu_free_c2_clk, // clocks + input logic clk_override, // Override non-functional clock gating + input logic clk, // Clock only while core active. Through one clock header. For flops with second clock header built in. Connected to ACTIVE_L2CLK. + + input logic rst_l, // reset, active low + + input el2_lsu_pkt_t lsu_pkt_r,// lsu packets + input el2_lsu_pkt_t lsu_pkt_m,// lsu packets + input el2_lsu_pkt_t lsu_pkt_d,// lsu packets + input logic addr_in_dccm_d, // address maps to dccm + input logic addr_in_pic_d, // address maps to pic + input logic addr_in_pic_m, // address maps to pic + input logic addr_in_dccm_m, addr_in_dccm_r, // address in dccm per pipe stage + input logic addr_in_pic_r, // address in pic per pipe stage + input logic lsu_raw_fwd_lo_r, lsu_raw_fwd_hi_r, + input logic lsu_commit_r, // lsu instruction in r commits + input logic ldst_dual_m, ldst_dual_r,// load/store is unaligned at 32 bit boundary per pipe stage + + // lsu address down the pipe + input logic [31:0] lsu_addr_d, + input logic [pt.DCCM_BITS-1:0] lsu_addr_m, + input logic [31:0] lsu_addr_r, + + // lsu address down the pipe - needed to check unaligned + input logic [pt.DCCM_BITS-1:0] end_addr_d, + input logic [pt.DCCM_BITS-1:0] end_addr_m, + input logic [pt.DCCM_BITS-1:0] end_addr_r, + + + input logic stbuf_reqvld_any, // write enable + input logic [pt.LSU_SB_BITS-1:0] stbuf_addr_any, // stbuf address (aligned) + + input logic [pt.DCCM_DATA_WIDTH-1:0] stbuf_data_any, // the read out from stbuf + input logic [pt.DCCM_ECC_WIDTH-1:0] stbuf_ecc_any, // the encoded data with ECC bits + input logic [pt.DCCM_DATA_WIDTH-1:0] stbuf_fwddata_hi_m, // stbuf fowarding to load + input logic [pt.DCCM_DATA_WIDTH-1:0] stbuf_fwddata_lo_m, // stbuf fowarding to load + input logic [pt.DCCM_BYTE_WIDTH-1:0] stbuf_fwdbyteen_hi_m, // stbuf fowarding to load + input logic [pt.DCCM_BYTE_WIDTH-1:0] stbuf_fwdbyteen_lo_m, // stbuf fowarding to load + + output logic [pt.DCCM_DATA_WIDTH-1:0] dccm_rdata_hi_r, // data from the dccm + output logic [pt.DCCM_DATA_WIDTH-1:0] dccm_rdata_lo_r, // data from the dccm + output logic [pt.DCCM_ECC_WIDTH-1:0] dccm_data_ecc_hi_r, // data from the dccm + ecc + output logic [pt.DCCM_ECC_WIDTH-1:0] dccm_data_ecc_lo_r, + output logic [pt.DCCM_DATA_WIDTH-1:0] lsu_ld_data_r, // right justified, ie load byte will have data at 7:0 + output logic [pt.DCCM_DATA_WIDTH-1:0] lsu_ld_data_corr_r, // right justified & ECC corrected, ie load byte will have data at 7:0 + + input logic lsu_double_ecc_error_r, // lsu has a DED + input logic single_ecc_error_hi_r, // sec detected on hi dccm bank + input logic single_ecc_error_lo_r, // sec detected on lower dccm bank + input logic [pt.DCCM_DATA_WIDTH-1:0] sec_data_hi_r, // corrected dccm data + input logic [pt.DCCM_DATA_WIDTH-1:0] sec_data_lo_r, // corrected dccm data + input logic [pt.DCCM_DATA_WIDTH-1:0] sec_data_hi_r_ff, // corrected dccm data + input logic [pt.DCCM_DATA_WIDTH-1:0] sec_data_lo_r_ff, // corrected dccm data + input logic [pt.DCCM_ECC_WIDTH-1:0] sec_data_ecc_hi_r_ff, // the encoded data with ECC bits + input logic [pt.DCCM_ECC_WIDTH-1:0] sec_data_ecc_lo_r_ff, // the encoded data with ECC bits + + output logic [pt.DCCM_DATA_WIDTH-1:0] dccm_rdata_hi_m, // data from the dccm + output logic [pt.DCCM_DATA_WIDTH-1:0] dccm_rdata_lo_m, // data from the dccm + output logic [pt.DCCM_ECC_WIDTH-1:0] dccm_data_ecc_hi_m, // data from the dccm + ecc + output logic [pt.DCCM_ECC_WIDTH-1:0] dccm_data_ecc_lo_m, + output logic [pt.DCCM_DATA_WIDTH-1:0] lsu_ld_data_m, // right justified, ie load byte will have data at 7:0 + + input logic lsu_double_ecc_error_m, // lsu has a DED + input logic [pt.DCCM_DATA_WIDTH-1:0] sec_data_hi_m, // corrected dccm data + input logic [pt.DCCM_DATA_WIDTH-1:0] sec_data_lo_m, // corrected dccm data + + input logic [31:0] store_data_m, // Store data M-stage + input logic dma_dccm_wen, // Perform DMA writes only for word/dword + input logic dma_pic_wen, // Perform PIC writes + input logic [2:0] dma_mem_tag_m, // DMA Buffer entry number M-stage + input logic [31:0] dma_mem_addr, // DMA request address + input logic [63:0] dma_mem_wdata, // DMA write data + input logic [31:0] dma_dccm_wdata_lo, // Shift the dma data to lower bits to make it consistent to lsu stores + input logic [31:0] dma_dccm_wdata_hi, // Shift the dma data to lower bits to make it consistent to lsu stores + input logic [pt.DCCM_ECC_WIDTH-1:0] dma_dccm_wdata_ecc_hi, // ECC bits for the DMA wdata + input logic [pt.DCCM_ECC_WIDTH-1:0] dma_dccm_wdata_ecc_lo, // ECC bits for the DMA wdata + + output logic [pt.DCCM_DATA_WIDTH-1:0] store_data_hi_r, + output logic [pt.DCCM_DATA_WIDTH-1:0] store_data_lo_r, + output logic [pt.DCCM_DATA_WIDTH-1:0] store_datafn_hi_r, // data from the dccm + output logic [pt.DCCM_DATA_WIDTH-1:0] store_datafn_lo_r, // data from the dccm + output logic [31:0] store_data_r, // raw store data to be sent to bus + output logic ld_single_ecc_error_r, + output logic ld_single_ecc_error_r_ff, + + output logic [31:0] picm_mask_data_m, // pic data to stbuf + output logic lsu_stbuf_commit_any, // stbuf wins the dccm port or is to pic + output logic lsu_dccm_rden_m, // dccm read + output logic lsu_dccm_rden_r, // dccm read + + output logic dccm_dma_rvalid, // dccm serviving the dma load + output logic dccm_dma_ecc_error, // DMA load had ecc error + output logic [2:0] dccm_dma_rtag, // DMA return tag + output logic [63:0] dccm_dma_rdata, // dccm data to dma request + + // DCCM ports + output logic dccm_wren, // dccm interface -- write + output logic dccm_rden, // dccm interface -- write + output logic [pt.DCCM_BITS-1:0] dccm_wr_addr_lo, // dccm interface -- wr addr for lo bank + output logic [pt.DCCM_BITS-1:0] dccm_wr_addr_hi, // dccm interface -- wr addr for hi bank + output logic [pt.DCCM_BITS-1:0] dccm_rd_addr_lo, // dccm interface -- read address for lo bank + output logic [pt.DCCM_BITS-1:0] dccm_rd_addr_hi, // dccm interface -- read address for hi bank + output logic [pt.DCCM_FDATA_WIDTH-1:0] dccm_wr_data_lo, // dccm write data for lo bank + output logic [pt.DCCM_FDATA_WIDTH-1:0] dccm_wr_data_hi, // dccm write data for hi bank + + input logic [pt.DCCM_FDATA_WIDTH-1:0] dccm_rd_data_lo, // dccm read data back from the dccm + input logic [pt.DCCM_FDATA_WIDTH-1:0] dccm_rd_data_hi, // dccm read data back from the dccm + + // PIC ports + output logic picm_wren, // write to pic + output logic picm_rden, // read to pick + output logic picm_mken, // write to pic need a mask + output logic [31:0] picm_rdaddr, // address for pic read access + output logic [31:0] picm_wraddr, // address for pic write access + output logic [31:0] picm_wr_data, // write data + input logic [31:0] picm_rd_data, // read data + + // Excluding scan_mode from coverage as its usage is determined by the integrator of the VeeR core. + /*pragma coverage off*/ + input logic scan_mode // scan mode + /*pragma coverage on*/ +); + + + localparam DCCM_WIDTH_BITS = $clog2(pt.DCCM_BYTE_WIDTH); + + logic lsu_dccm_rden_d, lsu_dccm_wren_d; + logic ld_single_ecc_error_lo_r, ld_single_ecc_error_hi_r; + logic ld_single_ecc_error_lo_r_ns, ld_single_ecc_error_hi_r_ns; + logic ld_single_ecc_error_lo_r_ff, ld_single_ecc_error_hi_r_ff; + logic lsu_double_ecc_error_r_ff; + logic [pt.DCCM_BITS-1:0] ld_sec_addr_lo_r_ff, ld_sec_addr_hi_r_ff; + logic [pt.DCCM_DATA_WIDTH-1:0] store_data_lo_r_in, store_data_hi_r_in ; + logic [63:0] picm_rd_data_m; + + logic dccm_wr_bypass_d_m_hi, dccm_wr_bypass_d_r_hi; + logic dccm_wr_bypass_d_m_lo, dccm_wr_bypass_d_r_lo; + logic kill_ecc_corr_lo_r, kill_ecc_corr_hi_r; + + // byte_en flowing down + logic [3:0] store_byteen_m ,store_byteen_r; + logic [7:0] store_byteen_ext_m, store_byteen_ext_r; + + if (pt.LOAD_TO_USE_PLUS1 == 1) begin: L2U_Plus1_1 + logic [63:0] lsu_rdata_r, lsu_rdata_corr_r; + logic [63:0] dccm_rdata_r, dccm_rdata_corr_r; + logic [63:0] stbuf_fwddata_r; + logic [7:0] stbuf_fwdbyteen_r; + logic [31:0] stbuf_fwddata_lo_r, stbuf_fwddata_hi_r; + logic [3:0] stbuf_fwdbyteen_lo_r, stbuf_fwdbyteen_hi_r; + logic [31:0] lsu_rdata_lo_r, lsu_rdata_hi_r; + logic [63:0] picm_rd_data_r; + logic [63:32] lsu_ld_data_r_nc, lsu_ld_data_corr_r_nc; + logic [2:0] dma_mem_tag_r; + logic stbuf_fwddata_en; + + assign dccm_dma_rvalid = lsu_pkt_r.valid & lsu_pkt_r.load & lsu_pkt_r.dma; + assign dccm_dma_ecc_error = lsu_double_ecc_error_r; + assign dccm_dma_rtag[2:0] = dma_mem_tag_r[2:0]; + assign dccm_dma_rdata[63:0] = ldst_dual_r ? lsu_rdata_corr_r[63:0] : {2{lsu_rdata_corr_r[31:0]}}; + assign {lsu_ld_data_r_nc[63:32], lsu_ld_data_r[31:0]} = lsu_rdata_r[63:0] >> 8*lsu_addr_r[1:0]; + assign {lsu_ld_data_corr_r_nc[63:32], lsu_ld_data_corr_r[31:0]} = lsu_rdata_corr_r[63:0] >> 8*lsu_addr_r[1:0]; + + assign picm_rd_data_r[63:32] = picm_rd_data_r[31:0]; + assign dccm_rdata_r[63:0] = {dccm_rdata_hi_r[31:0],dccm_rdata_lo_r[31:0]}; + assign dccm_rdata_corr_r[63:0] = {sec_data_hi_r[31:0],sec_data_lo_r[31:0]}; + assign stbuf_fwddata_r[63:0] = {stbuf_fwddata_hi_r[31:0], stbuf_fwddata_lo_r[31:0]}; + assign stbuf_fwdbyteen_r[7:0] = {stbuf_fwdbyteen_hi_r[3:0], stbuf_fwdbyteen_lo_r[3:0]}; + assign stbuf_fwddata_en = (|stbuf_fwdbyteen_hi_m[3:0]) | (|stbuf_fwdbyteen_lo_m[3:0]) | clk_override; + + for (genvar i=0; i<8; i++) begin: GenDMAData + assign lsu_rdata_corr_r[(8*i)+7:8*i] = stbuf_fwdbyteen_r[i] ? stbuf_fwddata_r[(8*i)+7:8*i] : + (addr_in_pic_r ? picm_rd_data_r[(8*i)+7:8*i] : ({8{addr_in_dccm_r}} & dccm_rdata_corr_r[(8*i)+7:8*i])); + + assign lsu_rdata_r[(8*i)+7:8*i] = stbuf_fwdbyteen_r[i] ? stbuf_fwddata_r[(8*i)+7:8*i] : + (addr_in_pic_r ? picm_rd_data_r[(8*i)+7:8*i] : ({8{addr_in_dccm_r}} & dccm_rdata_r[(8*i)+7:8*i])); + end + rvdffe #(pt.DCCM_DATA_WIDTH) dccm_rdata_hi_r_ff (.*, .din(dccm_rdata_hi_m[pt.DCCM_DATA_WIDTH-1:0]), .dout(dccm_rdata_hi_r[pt.DCCM_DATA_WIDTH-1:0]), .en((lsu_dccm_rden_m & ldst_dual_m) | clk_override)); + rvdffe #(pt.DCCM_DATA_WIDTH) dccm_rdata_lo_r_ff (.*, .din(dccm_rdata_lo_m[pt.DCCM_DATA_WIDTH-1:0]), .dout(dccm_rdata_lo_r[pt.DCCM_DATA_WIDTH-1:0]), .en(lsu_dccm_rden_m | clk_override)); + rvdffe #(2*pt.DCCM_ECC_WIDTH) dccm_data_ecc_r_ff (.*, .din({dccm_data_ecc_hi_m[pt.DCCM_ECC_WIDTH-1:0], dccm_data_ecc_lo_m[pt.DCCM_ECC_WIDTH-1:0]}), + .dout({dccm_data_ecc_hi_r[pt.DCCM_ECC_WIDTH-1:0], dccm_data_ecc_lo_r[pt.DCCM_ECC_WIDTH-1:0]}), .en(lsu_dccm_rden_m | clk_override)); + rvdff #(8) stbuf_fwdbyteen_ff (.*, .din({stbuf_fwdbyteen_hi_m[3:0], stbuf_fwdbyteen_lo_m[3:0]}), .dout({stbuf_fwdbyteen_hi_r[3:0], stbuf_fwdbyteen_lo_r[3:0]}), .clk(lsu_c2_r_clk)); + rvdffe #(64) stbuf_fwddata_ff (.*, .din({stbuf_fwddata_hi_m[31:0], stbuf_fwddata_lo_m[31:0]}), .dout({stbuf_fwddata_hi_r[31:0], stbuf_fwddata_lo_r[31:0]}), .en(stbuf_fwddata_en)); + rvdffe #(32) picm_rddata_rff (.*, .din(picm_rd_data_m[31:0]), .dout(picm_rd_data_r[31:0]), .en(addr_in_pic_m | clk_override)); + rvdff #(3) dma_mem_tag_rff (.*, .din(dma_mem_tag_m[2:0]), .dout(dma_mem_tag_r[2:0]), .clk(lsu_c1_r_clk)); + + end else begin: L2U_Plus1_0 + + logic [63:0] lsu_rdata_m, lsu_rdata_corr_m; + logic [63:0] dccm_rdata_m, dccm_rdata_corr_m; + logic [63:0] stbuf_fwddata_m; + logic [7:0] stbuf_fwdbyteen_m; + logic [63:32] lsu_ld_data_m_nc, lsu_ld_data_corr_m_nc; + logic [31:0] lsu_ld_data_corr_m; + + assign dccm_dma_rvalid = lsu_pkt_m.valid & lsu_pkt_m.load & lsu_pkt_m.dma; + assign dccm_dma_ecc_error = lsu_double_ecc_error_m; + assign dccm_dma_rtag[2:0] = dma_mem_tag_m[2:0]; + assign dccm_dma_rdata[63:0] = ldst_dual_m ? lsu_rdata_corr_m[63:0] : {2{lsu_rdata_corr_m[31:0]}}; + assign {lsu_ld_data_m_nc[63:32], lsu_ld_data_m[31:0]} = 64'(lsu_rdata_m[63:0] >> 8*lsu_addr_m[1:0]); + assign {lsu_ld_data_corr_m_nc[63:32], lsu_ld_data_corr_m[31:0]} = 64'(lsu_rdata_corr_m[63:0] >> 8*lsu_addr_m[1:0]); + + assign dccm_rdata_m[63:0] = {dccm_rdata_hi_m[31:0],dccm_rdata_lo_m[31:0]}; + assign dccm_rdata_corr_m[63:0] = {sec_data_hi_m[31:0],sec_data_lo_m[31:0]}; + assign stbuf_fwddata_m[63:0] = {stbuf_fwddata_hi_m[31:0], stbuf_fwddata_lo_m[31:0]}; + assign stbuf_fwdbyteen_m[7:0] = {stbuf_fwdbyteen_hi_m[3:0], stbuf_fwdbyteen_lo_m[3:0]}; + + for (genvar i=0; i<8; i++) begin: GenLoop + assign lsu_rdata_corr_m[(8*i)+7:8*i] = stbuf_fwdbyteen_m[i] ? stbuf_fwddata_m[(8*i)+7:8*i] : + (addr_in_pic_m ? picm_rd_data_m[(8*i)+7:8*i] : ({8{addr_in_dccm_m}} & dccm_rdata_corr_m[(8*i)+7:8*i])); + + assign lsu_rdata_m[(8*i)+7:8*i] = stbuf_fwdbyteen_m[i] ? stbuf_fwddata_m[(8*i)+7:8*i] : + (addr_in_pic_m ? picm_rd_data_m[(8*i)+7:8*i] : ({8{addr_in_dccm_m}} & dccm_rdata_m[(8*i)+7:8*i])); + end + + rvdffe #(32) lsu_ld_data_corr_rff(.*, .din(lsu_ld_data_corr_m[31:0]), .dout(lsu_ld_data_corr_r[31:0]), .en((lsu_pkt_m.valid & lsu_pkt_m.load & (addr_in_pic_m | addr_in_dccm_m)) | clk_override)); + end + + assign kill_ecc_corr_lo_r = (((lsu_addr_d[pt.DCCM_BITS-1:2] == lsu_addr_r[pt.DCCM_BITS-1:2]) | (end_addr_d[pt.DCCM_BITS-1:2] == lsu_addr_r[pt.DCCM_BITS-1:2])) & lsu_pkt_d.valid & lsu_pkt_d.store & lsu_pkt_d.dma & addr_in_dccm_d) | + (((lsu_addr_m[pt.DCCM_BITS-1:2] == lsu_addr_r[pt.DCCM_BITS-1:2]) | (end_addr_m[pt.DCCM_BITS-1:2] == lsu_addr_r[pt.DCCM_BITS-1:2])) & lsu_pkt_m.valid & lsu_pkt_m.store & lsu_pkt_m.dma & addr_in_dccm_m); + + assign kill_ecc_corr_hi_r = (((lsu_addr_d[pt.DCCM_BITS-1:2] == end_addr_r[pt.DCCM_BITS-1:2]) | (end_addr_d[pt.DCCM_BITS-1:2] == end_addr_r[pt.DCCM_BITS-1:2])) & lsu_pkt_d.valid & lsu_pkt_d.store & lsu_pkt_d.dma & addr_in_dccm_d) | + (((lsu_addr_m[pt.DCCM_BITS-1:2] == end_addr_r[pt.DCCM_BITS-1:2]) | (end_addr_m[pt.DCCM_BITS-1:2] == end_addr_r[pt.DCCM_BITS-1:2])) & lsu_pkt_m.valid & lsu_pkt_m.store & lsu_pkt_m.dma & addr_in_dccm_m); + + assign ld_single_ecc_error_lo_r = lsu_pkt_r.load & single_ecc_error_lo_r & ~lsu_raw_fwd_lo_r; + assign ld_single_ecc_error_hi_r = lsu_pkt_r.load & single_ecc_error_hi_r & ~lsu_raw_fwd_hi_r; + assign ld_single_ecc_error_r = (ld_single_ecc_error_lo_r | ld_single_ecc_error_hi_r) & ~lsu_double_ecc_error_r; + + assign ld_single_ecc_error_lo_r_ns = ld_single_ecc_error_lo_r & (lsu_commit_r | lsu_pkt_r.dma) & ~kill_ecc_corr_lo_r; + assign ld_single_ecc_error_hi_r_ns = ld_single_ecc_error_hi_r & (lsu_commit_r | lsu_pkt_r.dma) & ~kill_ecc_corr_hi_r; + assign ld_single_ecc_error_r_ff = (ld_single_ecc_error_lo_r_ff | ld_single_ecc_error_hi_r_ff) & ~lsu_double_ecc_error_r_ff; + + assign lsu_stbuf_commit_any = stbuf_reqvld_any & + (~(lsu_dccm_rden_d | lsu_dccm_wren_d | ld_single_ecc_error_r_ff) | + (lsu_dccm_rden_d & ~((stbuf_addr_any[pt.DCCM_WIDTH_BITS+:pt.DCCM_BANK_BITS] == lsu_addr_d[pt.DCCM_WIDTH_BITS+:pt.DCCM_BANK_BITS]) | + (stbuf_addr_any[pt.DCCM_WIDTH_BITS+:pt.DCCM_BANK_BITS] == end_addr_d[pt.DCCM_WIDTH_BITS+:pt.DCCM_BANK_BITS])))); + + // No need to read for aligned word/dword stores since ECC will come by new data completely + assign lsu_dccm_rden_d = lsu_pkt_d.valid & (lsu_pkt_d.load | (lsu_pkt_d.store & (~(lsu_pkt_d.word | lsu_pkt_d.dword) | (lsu_addr_d[1:0] != 2'b0)))) & addr_in_dccm_d; + + // DMA will read/write in decode stage + assign lsu_dccm_wren_d = dma_dccm_wen; + + // DCCM inputs + assign dccm_wren = lsu_dccm_wren_d | lsu_stbuf_commit_any | ld_single_ecc_error_r_ff; + assign dccm_rden = lsu_dccm_rden_d & addr_in_dccm_d; + assign dccm_wr_addr_lo[pt.DCCM_BITS-1:0] = ld_single_ecc_error_r_ff ? (ld_single_ecc_error_lo_r_ff ? ld_sec_addr_lo_r_ff[pt.DCCM_BITS-1:0] : ld_sec_addr_hi_r_ff[pt.DCCM_BITS-1:0]) : + lsu_dccm_wren_d ? lsu_addr_d[pt.DCCM_BITS-1:0] : stbuf_addr_any[pt.DCCM_BITS-1:0]; + assign dccm_wr_addr_hi[pt.DCCM_BITS-1:0] = ld_single_ecc_error_r_ff ? (ld_single_ecc_error_hi_r_ff ? ld_sec_addr_hi_r_ff[pt.DCCM_BITS-1:0] : ld_sec_addr_lo_r_ff[pt.DCCM_BITS-1:0]) : + lsu_dccm_wren_d ? end_addr_d[pt.DCCM_BITS-1:0] : stbuf_addr_any[pt.DCCM_BITS-1:0]; + assign dccm_rd_addr_lo[pt.DCCM_BITS-1:0] = lsu_addr_d[pt.DCCM_BITS-1:0]; + assign dccm_rd_addr_hi[pt.DCCM_BITS-1:0] = end_addr_d[pt.DCCM_BITS-1:0]; + assign dccm_wr_data_lo[pt.DCCM_FDATA_WIDTH-1:0] = ld_single_ecc_error_r_ff ? (ld_single_ecc_error_lo_r_ff ? {sec_data_ecc_lo_r_ff[pt.DCCM_ECC_WIDTH-1:0],sec_data_lo_r_ff[pt.DCCM_DATA_WIDTH-1:0]} : + {sec_data_ecc_hi_r_ff[pt.DCCM_ECC_WIDTH-1:0],sec_data_hi_r_ff[pt.DCCM_DATA_WIDTH-1:0]}) : + (dma_dccm_wen ? {dma_dccm_wdata_ecc_lo[pt.DCCM_ECC_WIDTH-1:0],dma_dccm_wdata_lo[pt.DCCM_DATA_WIDTH-1:0]} : + {stbuf_ecc_any[pt.DCCM_ECC_WIDTH-1:0],stbuf_data_any[pt.DCCM_DATA_WIDTH-1:0]}); + assign dccm_wr_data_hi[pt.DCCM_FDATA_WIDTH-1:0] = ld_single_ecc_error_r_ff ? (ld_single_ecc_error_hi_r_ff ? {sec_data_ecc_hi_r_ff[pt.DCCM_ECC_WIDTH-1:0],sec_data_hi_r_ff[pt.DCCM_DATA_WIDTH-1:0]} : + {sec_data_ecc_lo_r_ff[pt.DCCM_ECC_WIDTH-1:0],sec_data_lo_r_ff[pt.DCCM_DATA_WIDTH-1:0]}) : + (dma_dccm_wen ? {dma_dccm_wdata_ecc_hi[pt.DCCM_ECC_WIDTH-1:0],dma_dccm_wdata_hi[pt.DCCM_DATA_WIDTH-1:0]} : + {stbuf_ecc_any[pt.DCCM_ECC_WIDTH-1:0],stbuf_data_any[pt.DCCM_DATA_WIDTH-1:0]}); + + // DCCM outputs + assign store_byteen_m[3:0] = {4{lsu_pkt_m.store}} & + (({4{lsu_pkt_m.by}} & 4'b0001) | + ({4{lsu_pkt_m.half}} & 4'b0011) | + ({4{lsu_pkt_m.word}} & 4'b1111)); + + assign store_byteen_r[3:0] = {4{lsu_pkt_r.store}} & + (({4{lsu_pkt_r.by}} & 4'b0001) | + ({4{lsu_pkt_r.half}} & 4'b0011) | + ({4{lsu_pkt_r.word}} & 4'b1111)); + + assign store_byteen_ext_m[7:0] = {4'b0,store_byteen_m[3:0]} << lsu_addr_m[1:0]; // The packet in m + assign store_byteen_ext_r[7:0] = {4'b0,store_byteen_r[3:0]} << lsu_addr_r[1:0]; + + + + assign dccm_wr_bypass_d_m_lo = (stbuf_addr_any[pt.DCCM_BITS-1:2] == lsu_addr_m[pt.DCCM_BITS-1:2]) & addr_in_dccm_m; + assign dccm_wr_bypass_d_m_hi = (stbuf_addr_any[pt.DCCM_BITS-1:2] == end_addr_m[pt.DCCM_BITS-1:2]) & addr_in_dccm_m; + + assign dccm_wr_bypass_d_r_lo = (stbuf_addr_any[pt.DCCM_BITS-1:2] == lsu_addr_r[pt.DCCM_BITS-1:2]) & addr_in_dccm_r; + assign dccm_wr_bypass_d_r_hi = (stbuf_addr_any[pt.DCCM_BITS-1:2] == end_addr_r[pt.DCCM_BITS-1:2]) & addr_in_dccm_r; + + + if (pt.LOAD_TO_USE_PLUS1 == 1) begin: L2U1_Plus1_1 + logic dccm_wren_Q; + logic [31:0] dccm_wr_data_Q; + logic dccm_wr_bypass_d_m_lo_Q, dccm_wr_bypass_d_m_hi_Q; + logic [31:0] store_data_pre_hi_r, store_data_pre_lo_r; + + assign {store_data_pre_hi_r[31:0], store_data_pre_lo_r[31:0]} = {32'b0,store_data_r[31:0]} << 8*lsu_addr_r[1:0]; + + for (genvar i=0; i<4; i++) begin + assign store_data_lo_r[(8*i)+7:(8*i)] = store_byteen_ext_r[i] ? store_data_pre_lo_r[(8*i)+7:(8*i)] : ((dccm_wren_Q & dccm_wr_bypass_d_m_lo_Q) ? dccm_wr_data_Q[(8*i)+7:(8*i)] : sec_data_lo_r[(8*i)+7:(8*i)]); + assign store_data_hi_r[(8*i)+7:(8*i)] = store_byteen_ext_r[i+4] ? store_data_pre_hi_r[(8*i)+7:(8*i)] : ((dccm_wren_Q & dccm_wr_bypass_d_m_hi_Q) ? dccm_wr_data_Q[(8*i)+7:(8*i)] : sec_data_hi_r[(8*i)+7:(8*i)]); + + assign store_datafn_lo_r[(8*i)+7:(8*i)] = store_byteen_ext_r[i] ? store_data_pre_lo_r[(8*i)+7:(8*i)] : ((lsu_stbuf_commit_any & dccm_wr_bypass_d_r_lo) ? stbuf_data_any[(8*i)+7:(8*i)] : + ((dccm_wren_Q & dccm_wr_bypass_d_m_lo_Q) ? dccm_wr_data_Q[(8*i)+7:(8*i)] : sec_data_lo_r[(8*i)+7:(8*i)])); + assign store_datafn_hi_r[(8*i)+7:(8*i)] = store_byteen_ext_r[i+4] ? store_data_pre_hi_r[(8*i)+7:(8*i)] : ((lsu_stbuf_commit_any & dccm_wr_bypass_d_r_hi) ? stbuf_data_any[(8*i)+7:(8*i)] : + ((dccm_wren_Q & dccm_wr_bypass_d_m_hi_Q) ? dccm_wr_data_Q[(8*i)+7:(8*i)] : sec_data_hi_r[(8*i)+7:(8*i)])); + end + + rvdff #(1) dccm_wren_ff (.*, .din(lsu_stbuf_commit_any), .dout(dccm_wren_Q), .clk(lsu_free_c2_clk)); // ECC load errors writing to dccm shouldn't fwd to stores in pipe + rvdffe #(32) dccm_wrdata_ff (.*, .din(stbuf_data_any[31:0]), .dout(dccm_wr_data_Q[31:0]), .en(lsu_stbuf_commit_any | clk_override), .clk(clk)); + rvdff #(1) dccm_wrbyp_dm_loff (.*, .din(dccm_wr_bypass_d_m_lo), .dout(dccm_wr_bypass_d_m_lo_Q), .clk(lsu_free_c2_clk)); + rvdff #(1) dccm_wrbyp_dm_hiff (.*, .din(dccm_wr_bypass_d_m_hi), .dout(dccm_wr_bypass_d_m_hi_Q), .clk(lsu_free_c2_clk)); + rvdff #(32) store_data_rff (.*, .din(store_data_m[31:0]), .dout(store_data_r[31:0]), .clk(lsu_store_c1_r_clk)); + + end else begin: L2U1_Plus1_0 + + logic [31:0] store_data_hi_m, store_data_lo_m; + logic [63:0] store_data_mask; + assign {store_data_hi_m[31:0] , store_data_lo_m[31:0]} = {32'b0,store_data_m[31:0]} << 8*lsu_addr_m[1:0]; + + for (genvar i=0; i<4; i++) begin + assign store_data_hi_r_in[(8*i)+7:(8*i)] = store_byteen_ext_m[i+4] ? store_data_hi_m[(8*i)+7:(8*i)] : + ((lsu_stbuf_commit_any & dccm_wr_bypass_d_m_hi) ? stbuf_data_any[(8*i)+7:(8*i)] : sec_data_hi_m[(8*i)+7:(8*i)]); + assign store_data_lo_r_in[(8*i)+7:(8*i)] = store_byteen_ext_m[i] ? store_data_lo_m[(8*i)+7:(8*i)] : + ((lsu_stbuf_commit_any & dccm_wr_bypass_d_m_lo) ? stbuf_data_any[(8*i)+7:(8*i)] : sec_data_lo_m[(8*i)+7:(8*i)]); + + assign store_datafn_lo_r[(8*i)+7:(8*i)] = (lsu_stbuf_commit_any & dccm_wr_bypass_d_r_lo & ~store_byteen_ext_r[i]) ? stbuf_data_any[(8*i)+7:(8*i)] : store_data_lo_r[(8*i)+7:(8*i)]; + assign store_datafn_hi_r[(8*i)+7:(8*i)] = (lsu_stbuf_commit_any & dccm_wr_bypass_d_r_hi & ~store_byteen_ext_r[i+4]) ? stbuf_data_any[(8*i)+7:(8*i)] : store_data_hi_r[(8*i)+7:(8*i)]; + end // for (genvar i=0; i> 8*lsu_addr_r[1:0]) & store_data_mask[31:0]; + + rvdffe #(pt.DCCM_DATA_WIDTH) store_data_hi_rff (.*, .din(store_data_hi_r_in[pt.DCCM_DATA_WIDTH-1:0]), .dout(store_data_hi_r[pt.DCCM_DATA_WIDTH-1:0]), .en((ldst_dual_m & lsu_pkt_m.valid & lsu_pkt_m.store) | clk_override), .clk(clk)); + rvdff #(pt.DCCM_DATA_WIDTH) store_data_lo_rff (.*, .din(store_data_lo_r_in[pt.DCCM_DATA_WIDTH-1:0]), .dout(store_data_lo_r[pt.DCCM_DATA_WIDTH-1:0]), .clk(lsu_store_c1_r_clk)); + + end + + assign dccm_rdata_lo_m[pt.DCCM_DATA_WIDTH-1:0] = dccm_rd_data_lo[pt.DCCM_DATA_WIDTH-1:0]; // for ld choose dccm_out + assign dccm_rdata_hi_m[pt.DCCM_DATA_WIDTH-1:0] = dccm_rd_data_hi[pt.DCCM_DATA_WIDTH-1:0]; // for ld this is used for ecc + + assign dccm_data_ecc_lo_m[pt.DCCM_ECC_WIDTH-1:0] = dccm_rd_data_lo[pt.DCCM_FDATA_WIDTH-1:pt.DCCM_DATA_WIDTH]; + assign dccm_data_ecc_hi_m[pt.DCCM_ECC_WIDTH-1:0] = dccm_rd_data_hi[pt.DCCM_FDATA_WIDTH-1:pt.DCCM_DATA_WIDTH]; + + // PIC signals. PIC ignores the lower 2 bits of address since PIC memory registers are 32-bits + assign picm_wren = (lsu_pkt_r.valid & lsu_pkt_r.store & addr_in_pic_r & lsu_commit_r) | dma_pic_wen; + assign picm_rden = lsu_pkt_d.valid & lsu_pkt_d.load & addr_in_pic_d; + assign picm_mken = lsu_pkt_d.valid & lsu_pkt_d.store & addr_in_pic_d; // Get the mask for stores + assign picm_rdaddr[31:0] = pt.PIC_BASE_ADDR | {{32-pt.PIC_BITS{1'b0}},lsu_addr_d[pt.PIC_BITS-1:0]}; + + assign picm_wraddr[31:0] = pt.PIC_BASE_ADDR | {{32-pt.PIC_BITS{1'b0}},(dma_pic_wen ? dma_mem_addr[pt.PIC_BITS-1:0] : lsu_addr_r[pt.PIC_BITS-1:0])}; + + assign picm_wr_data[31:0] = dma_pic_wen ? dma_mem_wdata[31:0] : store_datafn_lo_r[31:0]; + + assign picm_mask_data_m[31:0] = picm_rd_data_m[31:0]; + assign picm_rd_data_m[63:0] = {picm_rd_data[31:0],picm_rd_data[31:0]}; + + if (pt.DCCM_ENABLE == 1) begin: Gen_dccm_enable + rvdff #(1) dccm_rden_mff (.*, .din(lsu_dccm_rden_d), .dout(lsu_dccm_rden_m), .clk(lsu_c2_m_clk)); + rvdff #(1) dccm_rden_rff (.*, .din(lsu_dccm_rden_m), .dout(lsu_dccm_rden_r), .clk(lsu_c2_r_clk)); + + // ECC correction flops since dccm write happens next cycle + // We are writing to dccm in r+1 for ecc correction since fast_int needs to be blocked in decode - 1. We can probably write in r for plus0 configuration since we know ecc error in M. + // In that case these (_ff) flops are needed only in plus1 configuration + rvdff #(1) ld_double_ecc_error_rff (.*, .din(lsu_double_ecc_error_r), .dout(lsu_double_ecc_error_r_ff), .clk(lsu_free_c2_clk)); + rvdff #(1) ld_single_ecc_error_hi_rff (.*, .din(ld_single_ecc_error_hi_r_ns), .dout(ld_single_ecc_error_hi_r_ff), .clk(lsu_free_c2_clk)); + rvdff #(1) ld_single_ecc_error_lo_rff (.*, .din(ld_single_ecc_error_lo_r_ns), .dout(ld_single_ecc_error_lo_r_ff), .clk(lsu_free_c2_clk)); + rvdffe #(pt.DCCM_BITS) ld_sec_addr_hi_rff (.*, .din(end_addr_r[pt.DCCM_BITS-1:0]), .dout(ld_sec_addr_hi_r_ff[pt.DCCM_BITS-1:0]), .en(ld_single_ecc_error_r | clk_override), .clk(clk)); + rvdffe #(pt.DCCM_BITS) ld_sec_addr_lo_rff (.*, .din(lsu_addr_r[pt.DCCM_BITS-1:0]), .dout(ld_sec_addr_lo_r_ff[pt.DCCM_BITS-1:0]), .en(ld_single_ecc_error_r | clk_override), .clk(clk)); + + end else begin: Gen_dccm_disable + assign lsu_dccm_rden_m = '0; + assign lsu_dccm_rden_r = '0; + + assign lsu_double_ecc_error_r_ff = 1'b0; + assign ld_single_ecc_error_hi_r_ff = 1'b0; + assign ld_single_ecc_error_lo_r_ff = 1'b0; + assign ld_sec_addr_hi_r_ff[pt.DCCM_BITS-1:0] = '0; + assign ld_sec_addr_lo_r_ff[pt.DCCM_BITS-1:0] = '0; + end + +`ifdef RV_ASSERT_ON + + // Load single ECC error correction implies commit/dma + property ld_single_ecc_error_commit; + @(posedge clk) disable iff(~rst_l) (ld_single_ecc_error_r_ff & dccm_wren) |-> ($past(lsu_commit_r | lsu_pkt_r.dma)); + endproperty + assert_ld_single_ecc_error_commit: assert property (ld_single_ecc_error_commit) else + $display("No commit or DMA but ECC correction happened"); + + +`endif + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/el2_lsu_dccm_mem.sv b/designs/Caliptra/src/caliptra-rtl/el2_lsu_dccm_mem.sv new file mode 100644 index 0000000..a02bba6 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/el2_lsu_dccm_mem.sv @@ -0,0 +1,123 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2020 Western Digital Corporation or its affiliates. +// Copyright (c) 2023 Antmicro +// +// 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. + +//******************************************************************************** +// $Id$ +// +// +// Owner: +// Function: DCCM for LSU pipe +// Comments: Single ported memory +// +// +// DC1 -> DC2 -> DC3 -> DC4 (Commit) +// +// //******************************************************************************** + +module el2_lsu_dccm_mem + import el2_pkg::*; +#( +`include "el2_param.vh" + )( + input logic clk, // Clock only while core active. Through one clock header. For flops with second clock header built in. Connected to ACTIVE_L2CLK. + input logic active_clk, // Clock only while core active. Through two clock headers. For flops without second clock header built in. + input logic rst_l, // reset, active low + input logic clk_override, // Override non-functional clock gating + + input logic dccm_wren, // write enable + input logic dccm_rden, // read enable + input logic [pt.DCCM_BITS-1:0] dccm_wr_addr_lo, // write address + input logic [pt.DCCM_BITS-1:0] dccm_wr_addr_hi, // write address + input logic [pt.DCCM_BITS-1:0] dccm_rd_addr_lo, // read address + input logic [pt.DCCM_BITS-1:0] dccm_rd_addr_hi, // read address for the upper bank in case of a misaligned access + input logic [pt.DCCM_FDATA_WIDTH-1:0] dccm_wr_data_lo, // write data + input logic [pt.DCCM_FDATA_WIDTH-1:0] dccm_wr_data_hi, // write data + el2_mem_if.veer_dccm dccm_mem_export, // RAM repositioned in testbench and connected by this interface + + output logic [pt.DCCM_FDATA_WIDTH-1:0] dccm_rd_data_lo, // read data from the lo bank + output logic [pt.DCCM_FDATA_WIDTH-1:0] dccm_rd_data_hi, // read data from the hi bank + + // Excluding scan_mode from coverage as its usage is determined by the integrator of the VeeR core. + /*pragma coverage off*/ + input logic scan_mode + /*pragma coverage on*/ +); + + + localparam logic [5:0] DCCM_WIDTH_BITS = $clog2(pt.DCCM_BYTE_WIDTH); + localparam logic [7:0] DCCM_INDEX_BITS = 8'(pt.DCCM_BITS - pt.DCCM_BANK_BITS - pt.DCCM_WIDTH_BITS); + localparam logic [31:0] DCCM_INDEX_DEPTH = ((pt.DCCM_SIZE)*1024)/((pt.DCCM_BYTE_WIDTH)*(pt.DCCM_NUM_BANKS)); // Depth of memory bank + + logic [pt.DCCM_NUM_BANKS-1:0] wren_bank; + logic [pt.DCCM_NUM_BANKS-1:0] rden_bank; + logic [pt.DCCM_NUM_BANKS-1:0] [pt.DCCM_BITS-1:(pt.DCCM_BANK_BITS+2)] addr_bank; + logic [pt.DCCM_BITS-1:(pt.DCCM_BANK_BITS+DCCM_WIDTH_BITS)] rd_addr_even, rd_addr_odd; + logic rd_unaligned, wr_unaligned; + logic [pt.DCCM_NUM_BANKS-1:0] [pt.DCCM_FDATA_WIDTH-1:0] dccm_bank_dout; + logic [pt.DCCM_FDATA_WIDTH-1:0] wrdata; + + logic [pt.DCCM_NUM_BANKS-1:0][pt.DCCM_FDATA_WIDTH-1:0] wr_data_bank; + + logic [(DCCM_WIDTH_BITS+pt.DCCM_BANK_BITS-1):DCCM_WIDTH_BITS] dccm_rd_addr_lo_q; + logic [(DCCM_WIDTH_BITS+pt.DCCM_BANK_BITS-1):DCCM_WIDTH_BITS] dccm_rd_addr_hi_q; + + logic [pt.DCCM_NUM_BANKS-1:0] dccm_clken; + + assign rd_unaligned = (dccm_rd_addr_lo[DCCM_WIDTH_BITS+:pt.DCCM_BANK_BITS] != dccm_rd_addr_hi[DCCM_WIDTH_BITS+:pt.DCCM_BANK_BITS]); + assign wr_unaligned = (dccm_wr_addr_lo[DCCM_WIDTH_BITS+:pt.DCCM_BANK_BITS] != dccm_wr_addr_hi[DCCM_WIDTH_BITS+:pt.DCCM_BANK_BITS]); + + // Align the read data + assign dccm_rd_data_lo[pt.DCCM_FDATA_WIDTH-1:0] = dccm_bank_dout[dccm_rd_addr_lo_q[pt.DCCM_WIDTH_BITS+:pt.DCCM_BANK_BITS]][pt.DCCM_FDATA_WIDTH-1:0]; + assign dccm_rd_data_hi[pt.DCCM_FDATA_WIDTH-1:0] = dccm_bank_dout[dccm_rd_addr_hi_q[DCCM_WIDTH_BITS+:pt.DCCM_BANK_BITS]][pt.DCCM_FDATA_WIDTH-1:0]; + + + // 8 Banks, 16KB each (2048 x 72) + for (genvar i=0; i DC2 -> DC3 -> DC4 (Commit) +// +//******************************************************************************** +module el2_lsu_ecc +import el2_pkg::*; +#( +`include "el2_param.vh" + ) +( + input logic clk, // Clock only while core active. Through one clock header. For flops with second clock header built in. Connected to ACTIVE_L2CLK. + input logic lsu_c2_r_clk, // clock + input logic clk_override, // Override non-functional clock gating + input logic rst_l, // reset, active low + // Excluding scan_mode from coverage as its usage is determined by the integrator of the VeeR core. + /*pragma coverage off*/ + input logic scan_mode, // scan mode + /*pragma coverage on*/ + + input el2_lsu_pkt_t lsu_pkt_m, // packet in m + input el2_lsu_pkt_t lsu_pkt_r, // packet in r + input logic [pt.DCCM_DATA_WIDTH-1:0] stbuf_data_any, + + input logic dec_tlu_core_ecc_disable, // disables the ecc computation and error flagging + + input logic lsu_dccm_rden_r, // dccm rden + input logic addr_in_dccm_r, // address in dccm + input logic [pt.DCCM_BITS-1:0] lsu_addr_r, // start address + input logic [pt.DCCM_BITS-1:0] end_addr_r, // end address + input logic [pt.DCCM_DATA_WIDTH-1:0] dccm_rdata_hi_r, // data from the dccm + input logic [pt.DCCM_DATA_WIDTH-1:0] dccm_rdata_lo_r, // data from the dccm + input logic [pt.DCCM_ECC_WIDTH-1:0] dccm_data_ecc_hi_r, // data from the dccm + ecc + input logic [pt.DCCM_ECC_WIDTH-1:0] dccm_data_ecc_lo_r, // data from the dccm + ecc + output logic [pt.DCCM_DATA_WIDTH-1:0] sec_data_hi_r, // corrected dccm data R-stage + output logic [pt.DCCM_DATA_WIDTH-1:0] sec_data_lo_r, // corrected dccm data R-stage + output logic [pt.DCCM_DATA_WIDTH-1:0] sec_data_hi_r_ff, // corrected dccm data R+1 stage + output logic [pt.DCCM_DATA_WIDTH-1:0] sec_data_lo_r_ff, // corrected dccm data R+1 stage + + input logic ld_single_ecc_error_r, // ld has a single ecc error + input logic ld_single_ecc_error_r_ff, // ld has a single ecc error + input logic lsu_dccm_rden_m, // dccm rden + input logic addr_in_dccm_m, // address in dccm + input logic [pt.DCCM_BITS-1:0] lsu_addr_m, // start address + input logic [pt.DCCM_BITS-1:0] end_addr_m, // end address + input logic [pt.DCCM_DATA_WIDTH-1:0] dccm_rdata_hi_m, // raw data from mem + input logic [pt.DCCM_DATA_WIDTH-1:0] dccm_rdata_lo_m, // raw data from mem + input logic [pt.DCCM_ECC_WIDTH-1:0] dccm_data_ecc_hi_m, // ecc read out from mem + input logic [pt.DCCM_ECC_WIDTH-1:0] dccm_data_ecc_lo_m, // ecc read out from mem + output logic [pt.DCCM_DATA_WIDTH-1:0] sec_data_hi_m, // corrected dccm data M-stage + output logic [pt.DCCM_DATA_WIDTH-1:0] sec_data_lo_m, // corrected dccm data M-stage + + input logic dma_dccm_wen, // Perform DMA writes only for word/dword + input logic [31:0] dma_dccm_wdata_lo, // Shifted dma data to lower bits to make it consistent to lsu stores + input logic [31:0] dma_dccm_wdata_hi, // Shifted dma data to lower bits to make it consistent to lsu stores + output logic [pt.DCCM_ECC_WIDTH-1:0] dma_dccm_wdata_ecc_hi, // ECC bits for the DMA wdata + output logic [pt.DCCM_ECC_WIDTH-1:0] dma_dccm_wdata_ecc_lo, // ECC bits for the DMA wdata + + output logic [pt.DCCM_ECC_WIDTH-1:0] stbuf_ecc_any, // Encoded data with ECC bits + output logic [pt.DCCM_ECC_WIDTH-1:0] sec_data_ecc_hi_r_ff, // Encoded data with ECC bits + output logic [pt.DCCM_ECC_WIDTH-1:0] sec_data_ecc_lo_r_ff, // Encoded data with ECC bits + + output logic single_ecc_error_hi_r, // sec detected + output logic single_ecc_error_lo_r, // sec detected on lower dccm bank + output logic lsu_single_ecc_error_r, // or of the 2 + output logic lsu_double_ecc_error_r, // double error detected + + output logic lsu_single_ecc_error_m, // or of the 2 + output logic lsu_double_ecc_error_m // double error detected + + ); + + logic is_ldst_r; + logic is_ldst_hi_any, is_ldst_lo_any; + logic [pt.DCCM_DATA_WIDTH-1:0] dccm_wdata_hi_any, dccm_wdata_lo_any; + logic [pt.DCCM_ECC_WIDTH-1:0] dccm_wdata_ecc_hi_any, dccm_wdata_ecc_lo_any; + logic [pt.DCCM_DATA_WIDTH-1:0] dccm_rdata_hi_any, dccm_rdata_lo_any; + logic [pt.DCCM_ECC_WIDTH-1:0] dccm_data_ecc_hi_any, dccm_data_ecc_lo_any; + logic [pt.DCCM_DATA_WIDTH-1:0] sec_data_hi_any, sec_data_lo_any; + logic single_ecc_error_hi_any, single_ecc_error_lo_any; + logic double_ecc_error_hi_any, double_ecc_error_lo_any; + + logic double_ecc_error_hi_m, double_ecc_error_lo_m; + logic double_ecc_error_hi_r, double_ecc_error_lo_r; + + logic [6:0] ecc_out_hi_nc, ecc_out_lo_nc; + + + if (pt.LOAD_TO_USE_PLUS1 == 1) begin: L2U_Plus1_1 + logic ldst_dual_m, ldst_dual_r; + logic is_ldst_m; + logic is_ldst_hi_r, is_ldst_lo_r; + + assign ldst_dual_r = (lsu_addr_r[2] != end_addr_r[2]); + assign is_ldst_r = lsu_pkt_r.valid & (lsu_pkt_r.load | lsu_pkt_r.store) & addr_in_dccm_r & lsu_dccm_rden_r; + assign is_ldst_lo_r = is_ldst_r & ~dec_tlu_core_ecc_disable; + assign is_ldst_hi_r = is_ldst_r & ldst_dual_r & ~dec_tlu_core_ecc_disable; // Always check the ECC Hi/Lo for DMA since we don't align for DMA + + assign is_ldst_hi_any = is_ldst_hi_r; + assign dccm_rdata_hi_any[pt.DCCM_DATA_WIDTH-1:0] = dccm_rdata_hi_r[pt.DCCM_DATA_WIDTH-1:0]; + assign dccm_data_ecc_hi_any[pt.DCCM_ECC_WIDTH-1:0] = dccm_data_ecc_hi_r[pt.DCCM_ECC_WIDTH-1:0]; + assign is_ldst_lo_any = is_ldst_lo_r; + assign dccm_rdata_lo_any[pt.DCCM_DATA_WIDTH-1:0] = dccm_rdata_lo_r[pt.DCCM_DATA_WIDTH-1:0]; + assign dccm_data_ecc_lo_any[pt.DCCM_ECC_WIDTH-1:0] = dccm_data_ecc_lo_r[pt.DCCM_ECC_WIDTH-1:0]; + + assign sec_data_hi_r[pt.DCCM_DATA_WIDTH-1:0] = sec_data_hi_any[pt.DCCM_DATA_WIDTH-1:0]; + assign single_ecc_error_hi_r = single_ecc_error_hi_any; + assign double_ecc_error_hi_r = double_ecc_error_hi_any; + assign sec_data_lo_r[pt.DCCM_DATA_WIDTH-1:0] = sec_data_lo_any[pt.DCCM_DATA_WIDTH-1:0]; + assign single_ecc_error_lo_r = single_ecc_error_lo_any; + assign double_ecc_error_lo_r = double_ecc_error_lo_any; + + assign lsu_single_ecc_error_r = single_ecc_error_hi_r | single_ecc_error_lo_r; + assign lsu_double_ecc_error_r = double_ecc_error_hi_r | double_ecc_error_lo_r; + + end else begin: L2U_Plus1_0 + + logic ldst_dual_m; + logic is_ldst_m; + logic is_ldst_hi_m, is_ldst_lo_m; + + assign ldst_dual_m = (lsu_addr_m[2] != end_addr_m[2]); + assign is_ldst_m = lsu_pkt_m.valid & (lsu_pkt_m.load | lsu_pkt_m.store) & addr_in_dccm_m & lsu_dccm_rden_m; + assign is_ldst_lo_m = is_ldst_m & ~dec_tlu_core_ecc_disable; + assign is_ldst_hi_m = is_ldst_m & (ldst_dual_m | lsu_pkt_m.dma) & ~dec_tlu_core_ecc_disable; // Always check the ECC Hi/Lo for DMA since we don't align for DMA + + assign is_ldst_hi_any = is_ldst_hi_m; + assign dccm_rdata_hi_any[pt.DCCM_DATA_WIDTH-1:0] = dccm_rdata_hi_m[pt.DCCM_DATA_WIDTH-1:0]; + assign dccm_data_ecc_hi_any[pt.DCCM_ECC_WIDTH-1:0] = dccm_data_ecc_hi_m[pt.DCCM_ECC_WIDTH-1:0]; + assign is_ldst_lo_any = is_ldst_lo_m; + assign dccm_rdata_lo_any[pt.DCCM_DATA_WIDTH-1:0] = dccm_rdata_lo_m[pt.DCCM_DATA_WIDTH-1:0]; + assign dccm_data_ecc_lo_any[pt.DCCM_ECC_WIDTH-1:0] = dccm_data_ecc_lo_m[pt.DCCM_ECC_WIDTH-1:0]; + + assign sec_data_hi_m[pt.DCCM_DATA_WIDTH-1:0] = sec_data_hi_any[pt.DCCM_DATA_WIDTH-1:0]; + assign double_ecc_error_hi_m = double_ecc_error_hi_any; + assign sec_data_lo_m[pt.DCCM_DATA_WIDTH-1:0] = sec_data_lo_any[pt.DCCM_DATA_WIDTH-1:0]; + assign double_ecc_error_lo_m = double_ecc_error_lo_any; + + assign lsu_single_ecc_error_m = single_ecc_error_hi_any | single_ecc_error_lo_any; + assign lsu_double_ecc_error_m = double_ecc_error_hi_m | double_ecc_error_lo_m; + + // Flops + rvdff #(1) lsu_single_ecc_err_r (.din(lsu_single_ecc_error_m), .dout(lsu_single_ecc_error_r), .clk(lsu_c2_r_clk), .*); + rvdff #(1) lsu_double_ecc_err_r (.din(lsu_double_ecc_error_m), .dout(lsu_double_ecc_error_r), .clk(lsu_c2_r_clk), .*); + rvdff #(.WIDTH(1)) ldst_sec_lo_rff (.din(single_ecc_error_lo_any), .dout(single_ecc_error_lo_r), .clk(lsu_c2_r_clk), .*); + rvdff #(.WIDTH(1)) ldst_sec_hi_rff (.din(single_ecc_error_hi_any), .dout(single_ecc_error_hi_r), .clk(lsu_c2_r_clk), .*); + rvdffe #(.WIDTH(pt.DCCM_DATA_WIDTH)) sec_data_hi_rff (.din(sec_data_hi_m[pt.DCCM_DATA_WIDTH-1:0]), .dout(sec_data_hi_r[pt.DCCM_DATA_WIDTH-1:0]), .en(lsu_single_ecc_error_m | clk_override), .*); + rvdffe #(.WIDTH(pt.DCCM_DATA_WIDTH)) sec_data_lo_rff (.din(sec_data_lo_m[pt.DCCM_DATA_WIDTH-1:0]), .dout(sec_data_lo_r[pt.DCCM_DATA_WIDTH-1:0]), .en(lsu_single_ecc_error_m | clk_override), .*); + + end + + // Logic for ECC generation during write + assign dccm_wdata_lo_any[pt.DCCM_DATA_WIDTH-1:0] = ld_single_ecc_error_r_ff ? sec_data_lo_r_ff[pt.DCCM_DATA_WIDTH-1:0] : (dma_dccm_wen ? dma_dccm_wdata_lo[pt.DCCM_DATA_WIDTH-1:0] : stbuf_data_any[pt.DCCM_DATA_WIDTH-1:0]); + assign dccm_wdata_hi_any[pt.DCCM_DATA_WIDTH-1:0] = ld_single_ecc_error_r_ff ? sec_data_hi_r_ff[pt.DCCM_DATA_WIDTH-1:0] : (dma_dccm_wen ? dma_dccm_wdata_hi[pt.DCCM_DATA_WIDTH-1:0] : 32'h0); + + assign sec_data_ecc_hi_r_ff[pt.DCCM_ECC_WIDTH-1:0] = dccm_wdata_ecc_hi_any[pt.DCCM_ECC_WIDTH-1:0]; + assign sec_data_ecc_lo_r_ff[pt.DCCM_ECC_WIDTH-1:0] = dccm_wdata_ecc_lo_any[pt.DCCM_ECC_WIDTH-1:0]; + assign stbuf_ecc_any[pt.DCCM_ECC_WIDTH-1:0] = dccm_wdata_ecc_lo_any[pt.DCCM_ECC_WIDTH-1:0]; + assign dma_dccm_wdata_ecc_hi[pt.DCCM_ECC_WIDTH-1:0] = dccm_wdata_ecc_hi_any[pt.DCCM_ECC_WIDTH-1:0]; + assign dma_dccm_wdata_ecc_lo[pt.DCCM_ECC_WIDTH-1:0] = dccm_wdata_ecc_lo_any[pt.DCCM_ECC_WIDTH-1:0]; + + // Instantiate ECC blocks + if (pt.DCCM_ENABLE == 1) begin: Gen_dccm_enable + + //Detect/Repair for Hi + rvecc_decode lsu_ecc_decode_hi ( + // Inputs + .en(is_ldst_hi_any), + .sed_ded (1'b0), // 1 : means only detection + .din(dccm_rdata_hi_any[pt.DCCM_DATA_WIDTH-1:0]), + .ecc_in(dccm_data_ecc_hi_any[pt.DCCM_ECC_WIDTH-1:0]), + // Outputs + .dout(sec_data_hi_any[pt.DCCM_DATA_WIDTH-1:0]), + .ecc_out (ecc_out_hi_nc[6:0]), + .single_ecc_error(single_ecc_error_hi_any), + .double_ecc_error(double_ecc_error_hi_any), + .* + ); + + //Detect/Repair for Lo + rvecc_decode lsu_ecc_decode_lo ( + // Inputs + .en(is_ldst_lo_any), + .sed_ded (1'b0), // 1 : means only detection + .din(dccm_rdata_lo_any[pt.DCCM_DATA_WIDTH-1:0] ), + .ecc_in(dccm_data_ecc_lo_any[pt.DCCM_ECC_WIDTH-1:0]), + // Outputs + .dout(sec_data_lo_any[pt.DCCM_DATA_WIDTH-1:0]), + .ecc_out (ecc_out_lo_nc[6:0]), + .single_ecc_error(single_ecc_error_lo_any), + .double_ecc_error(double_ecc_error_lo_any), + .* + ); + + rvecc_encode lsu_ecc_encode_hi ( + //Inputs + .din(dccm_wdata_hi_any[pt.DCCM_DATA_WIDTH-1:0]), + //Outputs + .ecc_out(dccm_wdata_ecc_hi_any[pt.DCCM_ECC_WIDTH-1:0]), + .* + ); + rvecc_encode lsu_ecc_encode_lo ( + //Inputs + .din(dccm_wdata_lo_any[pt.DCCM_DATA_WIDTH-1:0]), + //Outputs + .ecc_out(dccm_wdata_ecc_lo_any[pt.DCCM_ECC_WIDTH-1:0]), + .* + ); + end else begin: Gen_dccm_disable // block: Gen_dccm_enable + assign sec_data_hi_any[pt.DCCM_DATA_WIDTH-1:0] = '0; + assign sec_data_lo_any[pt.DCCM_DATA_WIDTH-1:0] = '0; + assign single_ecc_error_hi_any = '0; + assign double_ecc_error_hi_any = '0; + assign single_ecc_error_lo_any = '0; + assign double_ecc_error_lo_any = '0; + end + + rvdffe #(.WIDTH(pt.DCCM_DATA_WIDTH)) sec_data_hi_rplus1ff (.din(sec_data_hi_r[pt.DCCM_DATA_WIDTH-1:0]), .dout(sec_data_hi_r_ff[pt.DCCM_DATA_WIDTH-1:0]), .en(ld_single_ecc_error_r | clk_override), .clk(clk), .*); + rvdffe #(.WIDTH(pt.DCCM_DATA_WIDTH)) sec_data_lo_rplus1ff (.din(sec_data_lo_r[pt.DCCM_DATA_WIDTH-1:0]), .dout(sec_data_lo_r_ff[pt.DCCM_DATA_WIDTH-1:0]), .en(ld_single_ecc_error_r | clk_override), .clk(clk), .*); + + +endmodule // el2_lsu_ecc diff --git a/designs/Caliptra/src/caliptra-rtl/el2_lsu_lsc_ctl.sv b/designs/Caliptra/src/caliptra-rtl/el2_lsu_lsc_ctl.sv new file mode 100644 index 0000000..8030cc0 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/el2_lsu_lsc_ctl.sv @@ -0,0 +1,347 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2020 Western Digital Corporation or its affiliates. +// +// 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. + +//******************************************************************************** +// $Id$ +// +// +// Owner: +// Function: LSU control +// Comments: +// +// +// DC1 -> DC2 -> DC3 -> DC4 (Commit) +// +//******************************************************************************** +module el2_lsu_lsc_ctl +import el2_pkg::*; +#( +`include "el2_param.vh" + )( + input logic rst_l, // reset, active low + input logic clk_override, // Override non-functional clock gating + input logic clk, // Clock only while core active. Through one clock header. For flops with second clock header built in. Connected to ACTIVE_L2CLK. + + // clocks per pipe + input logic lsu_c1_m_clk, + input logic lsu_c1_r_clk, + input logic lsu_c2_m_clk, + input logic lsu_c2_r_clk, + input logic lsu_store_c1_m_clk, + + input logic [31:0] lsu_ld_data_r, // Load data R-stage + input logic [31:0] lsu_ld_data_corr_r, // ECC corrected data R-stage + input logic lsu_single_ecc_error_r, // ECC single bit error R-stage + input logic lsu_double_ecc_error_r, // ECC double bit error R-stage + + input logic [31:0] lsu_ld_data_m, // Load data M-stage + input logic lsu_single_ecc_error_m, // ECC single bit error M-stage + input logic lsu_double_ecc_error_m, // ECC double bit error M-stage + + input logic flush_m_up, // Flush M and D stage + input logic flush_r, // Flush R-stage + input logic ldst_dual_d, // load/store is unaligned at 32 bit boundary D-stage + input logic ldst_dual_m, // load/store is unaligned at 32 bit boundary M-stage + input logic ldst_dual_r, // load/store is unaligned at 32 bit boundary R-stage + + input logic [31:0] exu_lsu_rs1_d, // address + input logic [31:0] exu_lsu_rs2_d, // store data + + input el2_lsu_pkt_t lsu_p, // lsu control packet + input logic dec_lsu_valid_raw_d, // Raw valid for address computation + input logic [11:0] dec_lsu_offset_d, // 12b offset for load/store addresses + + input logic [31:0] picm_mask_data_m, // PIC data M-stage + input logic [31:0] bus_read_data_m, // the bus return data + output logic [31:0] lsu_result_m, // lsu load data + output logic [31:0] lsu_result_corr_r, // This is the ECC corrected data going to RF + // lsu address down the pipe + output logic [31:0] lsu_addr_d, + output logic [31:0] lsu_addr_m, + output logic [31:0] lsu_addr_r, + // lsu address down the pipe - needed to check unaligned + output logic [31:0] end_addr_d, + output logic [31:0] end_addr_m, + output logic [31:0] end_addr_r, + // store data down the pipe + output logic [31:0] store_data_m, + + input logic [31:0] dec_tlu_mrac_ff, // CSR for memory region control + output logic lsu_exc_m, // Access or misaligned fault + output logic is_sideeffects_m, // is sideffects space + output logic lsu_commit_r, // lsu instruction in r commits + output logic lsu_single_ecc_error_incr,// LSU inc SB error counter + output el2_lsu_error_pkt_t lsu_error_pkt_r, // lsu exception packet + + output logic [31:1] lsu_fir_addr, // fast interrupt address + output logic [1:0] lsu_fir_error, // Error during fast interrupt lookup + + // address in dccm/pic/external per pipe stage + output logic addr_in_dccm_d, + output logic addr_in_dccm_m, + output logic addr_in_dccm_r, + + output logic addr_in_pic_d, + output logic addr_in_pic_m, + output logic addr_in_pic_r, + + output logic addr_external_m, + + // DMA slave + input logic dma_dccm_req, + input logic [31:0] dma_mem_addr, + input logic [2:0] dma_mem_sz, + input logic dma_mem_write, + input logic [63:0] dma_mem_wdata, + + // Store buffer related signals + output el2_lsu_pkt_t lsu_pkt_d, + output el2_lsu_pkt_t lsu_pkt_m, + output el2_lsu_pkt_t lsu_pkt_r, + + input logic lsu_pmp_error_start, + input logic lsu_pmp_error_end, + + // Excluding scan_mode from coverage as its usage is determined by the integrator of the VeeR core. + /*pragma coverage off*/ + input logic scan_mode // Scan mode + /*pragma coverage on*/ + + ); + + logic [31:3] end_addr_pre_m, end_addr_pre_r; + logic [31:0] full_addr_d; + logic [31:0] full_end_addr_d; + logic [31:0] lsu_rs1_d; + logic [11:0] lsu_offset_d; + logic [31:0] rs1_d; + logic [11:0] offset_d; + logic [12:0] end_addr_offset_d; + logic [2:0] addr_offset_d; + + logic [63:0] dma_mem_wdata_shifted; + logic addr_external_d; + logic addr_external_r; + logic access_fault_d, misaligned_fault_d; + logic access_fault_m, misaligned_fault_m; + + logic fir_dccm_access_error_d, fir_nondccm_access_error_d; + logic fir_dccm_access_error_m, fir_nondccm_access_error_m; + + logic [3:0] exc_mscause_d, exc_mscause_m; + logic [31:0] rs1_d_raw; + logic [31:0] store_data_d, store_data_pre_m, store_data_m_in; + logic [31:0] bus_read_data_r; + + el2_lsu_pkt_t dma_pkt_d; + el2_lsu_pkt_t lsu_pkt_m_in, lsu_pkt_r_in; + el2_lsu_error_pkt_t lsu_error_pkt_m; + + + // Premux the rs1/offset for dma + assign lsu_rs1_d[31:0] = dec_lsu_valid_raw_d ? exu_lsu_rs1_d[31:0] : dma_mem_addr[31:0]; + assign lsu_offset_d[11:0] = dec_lsu_offset_d[11:0] & {12{dec_lsu_valid_raw_d}}; + assign rs1_d_raw[31:0] = lsu_rs1_d[31:0]; + assign offset_d[11:0] = lsu_offset_d[11:0]; + + assign rs1_d[31:0] = (lsu_pkt_d.load_ldst_bypass_d) ? lsu_result_m[31:0] : rs1_d_raw[31:0]; + + // generate the ls address + rvlsadder lsadder (.rs1(rs1_d[31:0]), + .offset(offset_d[11:0]), + .dout(full_addr_d[31:0]) + ); + + // Module to generate the memory map of the address + el2_lsu_addrcheck addrcheck ( + .start_addr_d(full_addr_d[31:0]), + .end_addr_d(full_end_addr_d[31:0]), + .rs1_region_d(rs1_d[31:28]), + .* + ); + + // Calculate start/end address for load/store + assign addr_offset_d[2:0] = ({3{lsu_pkt_d.half}} & 3'b01) | ({3{lsu_pkt_d.word}} & 3'b11) | ({3{lsu_pkt_d.dword}} & 3'b111); + assign end_addr_offset_d[12:0] = {offset_d[11],offset_d[11:0]} + {9'b0,addr_offset_d[2:0]}; + assign full_end_addr_d[31:0] = rs1_d[31:0] + {{19{end_addr_offset_d[12]}},end_addr_offset_d[12:0]}; + assign end_addr_d[31:0] = full_end_addr_d[31:0]; + assign lsu_exc_m = access_fault_m | misaligned_fault_m; + + // Goes to TLU to increment the ECC error counter + assign lsu_single_ecc_error_incr = (lsu_single_ecc_error_r & ~lsu_double_ecc_error_r) & (lsu_commit_r | lsu_pkt_r.dma) & lsu_pkt_r.valid; + + if (pt.LOAD_TO_USE_PLUS1 == 1) begin: L2U_Plus1_1 + logic access_fault_r, misaligned_fault_r; + logic [3:0] exc_mscause_r; + logic fir_dccm_access_error_r, fir_nondccm_access_error_r; + + // Generate exception packet + assign lsu_error_pkt_r.exc_valid = (access_fault_r | misaligned_fault_r | lsu_double_ecc_error_r) & lsu_pkt_r.valid & ~lsu_pkt_r.dma & ~lsu_pkt_r.fast_int; + assign lsu_error_pkt_r.single_ecc_error = lsu_single_ecc_error_r & ~lsu_error_pkt_r.exc_valid & ~lsu_pkt_r.dma; + assign lsu_error_pkt_r.inst_type = lsu_pkt_r.store; + assign lsu_error_pkt_r.exc_type = ~misaligned_fault_r; + assign lsu_error_pkt_r.mscause[3:0] = (lsu_double_ecc_error_r & ~misaligned_fault_r & ~access_fault_r) ? 4'h1 : exc_mscause_r[3:0]; + assign lsu_error_pkt_r.addr[31:0] = lsu_addr_r[31:0]; + + assign lsu_fir_error[1:0] = fir_nondccm_access_error_r ? 2'b11 : (fir_dccm_access_error_r ? 2'b10 : ((lsu_pkt_r.fast_int & lsu_double_ecc_error_r) ? 2'b01 : 2'b00)); + + rvdff #(1) access_fault_rff (.din(access_fault_m), .dout(access_fault_r), .clk(lsu_c1_r_clk), .*); + rvdff #(1) misaligned_fault_rff (.din(misaligned_fault_m), .dout(misaligned_fault_r), .clk(lsu_c1_r_clk), .*); + rvdff #(4) exc_mscause_rff (.din(exc_mscause_m[3:0]), .dout(exc_mscause_r[3:0]), .clk(lsu_c1_r_clk), .*); + rvdff #(1) fir_dccm_access_error_mff (.din(fir_dccm_access_error_m), .dout(fir_dccm_access_error_r), .clk(lsu_c1_r_clk), .*); + rvdff #(1) fir_nondccm_access_error_mff (.din(fir_nondccm_access_error_m), .dout(fir_nondccm_access_error_r), .clk(lsu_c1_r_clk), .*); + + end else begin: L2U_Plus1_0 + logic [1:0] lsu_fir_error_m; + + // Generate exception packet + assign lsu_error_pkt_m.exc_valid = (access_fault_m | misaligned_fault_m | lsu_double_ecc_error_m) & lsu_pkt_m.valid & ~lsu_pkt_m.dma & ~lsu_pkt_m.fast_int & ~flush_m_up; + assign lsu_error_pkt_m.single_ecc_error = lsu_single_ecc_error_m & ~lsu_error_pkt_m.exc_valid & ~lsu_pkt_m.dma; + assign lsu_error_pkt_m.inst_type = lsu_pkt_m.store; + assign lsu_error_pkt_m.exc_type = ~misaligned_fault_m; + assign lsu_error_pkt_m.mscause[3:0] = (lsu_double_ecc_error_m & ~misaligned_fault_m & ~access_fault_m) ? 4'h1 : exc_mscause_m[3:0]; + assign lsu_error_pkt_m.addr[31:0] = lsu_addr_m[31:0]; + + assign lsu_fir_error_m[1:0] = fir_nondccm_access_error_m ? 2'b11 : (fir_dccm_access_error_m ? 2'b10 : ((lsu_pkt_m.fast_int & lsu_double_ecc_error_m) ? 2'b01 : 2'b00)); + + rvdff #(1) lsu_exc_valid_rff (.*, .din(lsu_error_pkt_m.exc_valid), .dout(lsu_error_pkt_r.exc_valid), .clk(lsu_c2_r_clk)); + rvdff #(1) lsu_single_ecc_error_rff(.*, .din(lsu_error_pkt_m.single_ecc_error), .dout(lsu_error_pkt_r.single_ecc_error), .clk(lsu_c2_r_clk)); + rvdffe #($bits(el2_lsu_error_pkt_t)-2) lsu_error_pkt_rff (.*, .din(lsu_error_pkt_m[$bits(el2_lsu_error_pkt_t)-1:2]), .dout(lsu_error_pkt_r[$bits(el2_lsu_error_pkt_t)-1:2]), .en(lsu_error_pkt_m.exc_valid | lsu_error_pkt_m.single_ecc_error | clk_override)); + rvdff #(2) lsu_fir_error_rff (.*, .din(lsu_fir_error_m[1:0]), .dout(lsu_fir_error[1:0]), .clk(lsu_c2_r_clk)); + end + + //Create DMA packet + always_comb begin + dma_pkt_d = '0; + dma_pkt_d.valid = dma_dccm_req; + dma_pkt_d.dma = 1'b1; + dma_pkt_d.store = dma_mem_write; + dma_pkt_d.load = ~dma_mem_write; + dma_pkt_d.by = (dma_mem_sz[2:0] == 3'b0); + dma_pkt_d.half = (dma_mem_sz[2:0] == 3'b1); + dma_pkt_d.word = (dma_mem_sz[2:0] == 3'b10); + dma_pkt_d.dword = (dma_mem_sz[2:0] == 3'b11); + end + + always_comb begin + lsu_pkt_d = dec_lsu_valid_raw_d ? lsu_p : dma_pkt_d; + lsu_pkt_m_in = lsu_pkt_d; + lsu_pkt_r_in = lsu_pkt_m; + + lsu_pkt_d.valid = (lsu_p.valid & ~(flush_m_up & ~lsu_p.fast_int)) | dma_dccm_req; + lsu_pkt_m_in.valid = lsu_pkt_d.valid & ~(flush_m_up & ~lsu_pkt_d.dma); + lsu_pkt_r_in.valid = lsu_pkt_m.valid & ~(flush_m_up & ~lsu_pkt_m.dma) ; + end + + // C2 clock for valid and C1 for other bits of packet + rvdff #(1) lsu_pkt_vldmff (.*, .din(lsu_pkt_m_in.valid), .dout(lsu_pkt_m.valid), .clk(lsu_c2_m_clk)); + rvdff #(1) lsu_pkt_vldrff (.*, .din(lsu_pkt_r_in.valid), .dout(lsu_pkt_r.valid), .clk(lsu_c2_r_clk)); + + rvdff #($bits(el2_lsu_pkt_t)-1) lsu_pkt_mff (.*, .din(lsu_pkt_m_in[$bits(el2_lsu_pkt_t)-1:1]), .dout(lsu_pkt_m[$bits(el2_lsu_pkt_t)-1:1]), .clk(lsu_c1_m_clk)); + rvdff #($bits(el2_lsu_pkt_t)-1) lsu_pkt_rff (.*, .din(lsu_pkt_r_in[$bits(el2_lsu_pkt_t)-1:1]), .dout(lsu_pkt_r[$bits(el2_lsu_pkt_t)-1:1]), .clk(lsu_c1_r_clk)); + + + + if (pt.LOAD_TO_USE_PLUS1 == 1) begin: L2U1_Plus1_1 + logic [31:0] lsu_ld_datafn_r, lsu_ld_datafn_corr_r; + + assign lsu_ld_datafn_r[31:0] = addr_external_r ? bus_read_data_r[31:0] : lsu_ld_data_r[31:0]; + assign lsu_ld_datafn_corr_r[31:0] = addr_external_r ? bus_read_data_r[31:0] : lsu_ld_data_corr_r[31:0]; + + // this is really R stage signal + assign lsu_result_m[31:0] = ({32{ lsu_pkt_r.unsign & lsu_pkt_r.by }} & {24'b0,lsu_ld_datafn_r[7:0]}) | + ({32{ lsu_pkt_r.unsign & lsu_pkt_r.half}} & {16'b0,lsu_ld_datafn_r[15:0]}) | + ({32{~lsu_pkt_r.unsign & lsu_pkt_r.by }} & {{24{ lsu_ld_datafn_r[7]}}, lsu_ld_datafn_r[7:0]}) | + ({32{~lsu_pkt_r.unsign & lsu_pkt_r.half}} & {{16{ lsu_ld_datafn_r[15]}},lsu_ld_datafn_r[15:0]}) | + ({32{lsu_pkt_r.word}} & lsu_ld_datafn_r[31:0]); + + // this signal is used for gpr update + assign lsu_result_corr_r[31:0] = ({32{ lsu_pkt_r.unsign & lsu_pkt_r.by }} & {24'b0,lsu_ld_datafn_corr_r[7:0]}) | + ({32{ lsu_pkt_r.unsign & lsu_pkt_r.half}} & {16'b0,lsu_ld_datafn_corr_r[15:0]}) | + ({32{~lsu_pkt_r.unsign & lsu_pkt_r.by }} & {{24{ lsu_ld_datafn_corr_r[7]}}, lsu_ld_datafn_corr_r[7:0]}) | + ({32{~lsu_pkt_r.unsign & lsu_pkt_r.half}} & {{16{ lsu_ld_datafn_corr_r[15]}},lsu_ld_datafn_corr_r[15:0]}) | + ({32{lsu_pkt_r.word}} & lsu_ld_datafn_corr_r[31:0]); + + end else begin: L2U1_Plus1_0 // block: L2U1_Plus1_1 + logic [31:0] lsu_ld_datafn_m, lsu_ld_datafn_corr_r; + + assign lsu_ld_datafn_m[31:0] = addr_external_m ? bus_read_data_m[31:0] : lsu_ld_data_m[31:0]; + assign lsu_ld_datafn_corr_r[31:0] = addr_external_r ? bus_read_data_r[31:0] : lsu_ld_data_corr_r[31:0]; + + // this result must look at prior stores and merge them in + assign lsu_result_m[31:0] = ({32{ lsu_pkt_m.unsign & lsu_pkt_m.by }} & {24'b0,lsu_ld_datafn_m[7:0]}) | + ({32{ lsu_pkt_m.unsign & lsu_pkt_m.half}} & {16'b0,lsu_ld_datafn_m[15:0]}) | + ({32{~lsu_pkt_m.unsign & lsu_pkt_m.by }} & {{24{ lsu_ld_datafn_m[7]}}, lsu_ld_datafn_m[7:0]}) | + ({32{~lsu_pkt_m.unsign & lsu_pkt_m.half}} & {{16{ lsu_ld_datafn_m[15]}},lsu_ld_datafn_m[15:0]}) | + ({32{lsu_pkt_m.word}} & lsu_ld_datafn_m[31:0]); + + // this signal is used for gpr update + assign lsu_result_corr_r[31:0] = ({32{ lsu_pkt_r.unsign & lsu_pkt_r.by }} & {24'b0,lsu_ld_datafn_corr_r[7:0]}) | + ({32{ lsu_pkt_r.unsign & lsu_pkt_r.half}} & {16'b0,lsu_ld_datafn_corr_r[15:0]}) | + ({32{~lsu_pkt_r.unsign & lsu_pkt_r.by }} & {{24{ lsu_ld_datafn_corr_r[7]}}, lsu_ld_datafn_corr_r[7:0]}) | + ({32{~lsu_pkt_r.unsign & lsu_pkt_r.half}} & {{16{ lsu_ld_datafn_corr_r[15]}},lsu_ld_datafn_corr_r[15:0]}) | + ({32{lsu_pkt_r.word}} & lsu_ld_datafn_corr_r[31:0]); + end + + // Fast interrupt address + assign lsu_fir_addr[31:1] = lsu_ld_data_corr_r[31:1]; + + // absence load/store all 0's + assign lsu_addr_d[31:0] = full_addr_d[31:0]; + + // Interrupt as a flush source allows the WB to occur + assign lsu_commit_r = lsu_pkt_r.valid & (lsu_pkt_r.store | lsu_pkt_r.load) & ~flush_r & ~lsu_pkt_r.dma; + + assign dma_mem_wdata_shifted[63:0] = 64'(dma_mem_wdata[63:0] >> {dma_mem_addr[2:0], 3'b000}); // Shift the dma data to lower bits to make it consistent to lsu stores + assign store_data_d[31:0] = dma_dccm_req ? dma_mem_wdata_shifted[31:0] : exu_lsu_rs2_d[31:0]; // Write to PIC still happens in r stage + + assign store_data_m_in[31:0] = (lsu_pkt_d.store_data_bypass_d) ? lsu_result_m[31:0] : store_data_d[31:0]; + + assign store_data_m[31:0] = (picm_mask_data_m[31:0] | {32{~addr_in_pic_m}}) & ((lsu_pkt_m.store_data_bypass_m) ? lsu_result_m[31:0] : store_data_pre_m[31:0]); + + + rvdff #(32) sdmff (.*, .din(store_data_m_in[31:0]), .dout(store_data_pre_m[31:0]), .clk(lsu_store_c1_m_clk)); + + rvdff #(32) samff (.*, .din(lsu_addr_d[31:0]), .dout(lsu_addr_m[31:0]), .clk(lsu_c1_m_clk)); + rvdff #(32) sarff (.*, .din(lsu_addr_m[31:0]), .dout(lsu_addr_r[31:0]), .clk(lsu_c1_r_clk)); + + assign end_addr_m[31:3] = ldst_dual_m ? end_addr_pre_m[31:3] : lsu_addr_m[31:3]; // This is for power saving + assign end_addr_r[31:3] = ldst_dual_r ? end_addr_pre_r[31:3] : lsu_addr_r[31:3]; // This is for power saving + + rvdffe #(29) end_addr_hi_mff (.*, .din(end_addr_d[31:3]), .dout(end_addr_pre_m[31:3]), .en((lsu_pkt_d.valid & ldst_dual_d) | clk_override)); + rvdffe #(29) end_addr_hi_rff (.*, .din(end_addr_m[31:3]), .dout(end_addr_pre_r[31:3]), .en((lsu_pkt_m.valid & ldst_dual_m) | clk_override)); + + rvdff #(3) end_addr_lo_mff (.*, .din(end_addr_d[2:0]), .dout(end_addr_m[2:0]), .clk(lsu_c1_m_clk)); + rvdff #(3) end_addr_lo_rff (.*, .din(end_addr_m[2:0]), .dout(end_addr_r[2:0]), .clk(lsu_c1_r_clk)); + + rvdff #(1) addr_in_dccm_mff(.din(addr_in_dccm_d), .dout(addr_in_dccm_m), .clk(lsu_c1_m_clk), .*); + rvdff #(1) addr_in_dccm_rff(.din(addr_in_dccm_m), .dout(addr_in_dccm_r), .clk(lsu_c1_r_clk), .*); + + rvdff #(1) addr_in_pic_mff(.din(addr_in_pic_d), .dout(addr_in_pic_m), .clk(lsu_c1_m_clk), .*); + rvdff #(1) addr_in_pic_rff(.din(addr_in_pic_m), .dout(addr_in_pic_r), .clk(lsu_c1_r_clk), .*); + + rvdff #(1) addr_external_mff(.din(addr_external_d), .dout(addr_external_m), .clk(lsu_c1_m_clk), .*); + rvdff #(1) addr_external_rff(.din(addr_external_m), .dout(addr_external_r), .clk(lsu_c1_r_clk), .*); + + rvdff #(1) access_fault_mff (.din(access_fault_d), .dout(access_fault_m), .clk(lsu_c1_m_clk), .*); + rvdff #(1) misaligned_fault_mff (.din(misaligned_fault_d), .dout(misaligned_fault_m), .clk(lsu_c1_m_clk), .*); + rvdff #(4) exc_mscause_mff (.din(exc_mscause_d[3:0]), .dout(exc_mscause_m[3:0]), .clk(lsu_c1_m_clk), .*); + + rvdff #(1) fir_dccm_access_error_mff (.din(fir_dccm_access_error_d), .dout(fir_dccm_access_error_m), .clk(lsu_c1_m_clk), .*); + rvdff #(1) fir_nondccm_access_error_mff (.din(fir_nondccm_access_error_d), .dout(fir_nondccm_access_error_m), .clk(lsu_c1_m_clk), .*); + + rvdffe #(32) bus_read_data_r_ff (.*, .din(bus_read_data_m[31:0]), .dout(bus_read_data_r[31:0]), .en(addr_external_m | clk_override)); + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/el2_lsu_stbuf.sv b/designs/Caliptra/src/caliptra-rtl/el2_lsu_stbuf.sv new file mode 100644 index 0000000..9b48406 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/el2_lsu_stbuf.sv @@ -0,0 +1,354 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2020 Western Digital Corporation or its affiliates. +// +// 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. + +//******************************************************************************** +// $Id$ +// +// +// Owner: +// Function: Store Buffer +// Comments: Dual writes and single drain +// +// +// DC1 -> DC2 -> DC3 -> DC4 (Commit) +// +// //******************************************************************************** + + +module el2_lsu_stbuf +import el2_pkg::*; +#( +`include "el2_param.vh" + ) +( + input logic clk, // core clock + input logic rst_l, // reset + + input logic lsu_stbuf_c1_clk, // stbuf clock + input logic lsu_free_c2_clk, // free clk + + // Store Buffer input + input logic store_stbuf_reqvld_r, // core instruction goes to stbuf + input logic lsu_commit_r, // lsu commits + input logic dec_lsu_valid_raw_d, // Speculative decode valid + input logic [pt.DCCM_DATA_WIDTH-1:0] store_data_hi_r, // merged data from the dccm for stores. This is used for fwding + input logic [pt.DCCM_DATA_WIDTH-1:0] store_data_lo_r, // merged data from the dccm for stores. This is used for fwding + input logic [pt.DCCM_DATA_WIDTH-1:0] store_datafn_hi_r, // merged data from the dccm for stores + input logic [pt.DCCM_DATA_WIDTH-1:0] store_datafn_lo_r, // merged data from the dccm for stores + + // Store Buffer output + output logic stbuf_reqvld_any, // stbuf is draining + output logic stbuf_reqvld_flushed_any, // Top entry is flushed + output logic [pt.LSU_SB_BITS-1:0] stbuf_addr_any, // address + output logic [pt.DCCM_DATA_WIDTH-1:0] stbuf_data_any, // stbuf data + + input logic lsu_stbuf_commit_any, // pop the stbuf as it commite + output logic lsu_stbuf_full_any, // stbuf is full + output logic lsu_stbuf_empty_any, // stbuf is empty + output logic ldst_stbuf_reqvld_r, // needed for clocking + + input logic [pt.LSU_SB_BITS-1:0] lsu_addr_d, // lsu address D-stage + input logic [31:0] lsu_addr_m, // lsu address M-stage + input logic [31:0] lsu_addr_r, // lsu address R-stage + + input logic [pt.LSU_SB_BITS-1:0] end_addr_d, // lsu end address D-stage - needed to check unaligned + input logic [31:0] end_addr_m, // lsu end address M-stage - needed to check unaligned + input logic [31:0] end_addr_r, // lsu end address R-stage - needed to check unaligned + + input logic ldst_dual_d, ldst_dual_m, ldst_dual_r, + input logic addr_in_dccm_m, // address is in dccm + input logic addr_in_dccm_r, // address is in dccm + + // Forwarding signals + input logic lsu_cmpen_m, // needed for forwarding stbuf - load + input el2_lsu_pkt_t lsu_pkt_m, // LSU packet M-stage + input el2_lsu_pkt_t lsu_pkt_r, // LSU packet R-stage + + output logic [pt.DCCM_DATA_WIDTH-1:0] stbuf_fwddata_hi_m, // stbuf data + output logic [pt.DCCM_DATA_WIDTH-1:0] stbuf_fwddata_lo_m, // stbuf data + output logic [pt.DCCM_BYTE_WIDTH-1:0] stbuf_fwdbyteen_hi_m, // stbuf data + output logic [pt.DCCM_BYTE_WIDTH-1:0] stbuf_fwdbyteen_lo_m, // stbuf data + + // Excluding scan_mode from coverage as its usage is determined by the integrator of the VeeR core. + /*pragma coverage off*/ + input logic scan_mode // Scan mode + /*pragma coverage on*/ + +); + + + localparam DEPTH = pt.LSU_STBUF_DEPTH; + localparam DATA_WIDTH = pt.DCCM_DATA_WIDTH; + localparam BYTE_WIDTH = pt.DCCM_BYTE_WIDTH; + localparam DEPTH_LOG2 = $clog2(DEPTH); + + // These are the fields in the store queue + logic [DEPTH-1:0] stbuf_vld; + logic [DEPTH-1:0] stbuf_dma_kill; + logic [DEPTH-1:0][pt.LSU_SB_BITS-1:0] stbuf_addr; + logic [DEPTH-1:0][BYTE_WIDTH-1:0] stbuf_byteen; + logic [DEPTH-1:0][DATA_WIDTH-1:0] stbuf_data; + + logic [DEPTH-1:0] sel_lo; + logic [DEPTH-1:0] stbuf_wr_en; + logic [DEPTH-1:0] stbuf_dma_kill_en; + logic [DEPTH-1:0] stbuf_reset; + logic [DEPTH-1:0][pt.LSU_SB_BITS-1:0] stbuf_addrin; + logic [DEPTH-1:0][DATA_WIDTH-1:0] stbuf_datain; + logic [DEPTH-1:0][BYTE_WIDTH-1:0] stbuf_byteenin; + + logic [7:0] store_byteen_ext_r; + logic [BYTE_WIDTH-1:0] store_byteen_hi_r; + logic [BYTE_WIDTH-1:0] store_byteen_lo_r; + + logic WrPtrEn, RdPtrEn; + logic [DEPTH_LOG2-1:0] WrPtr, RdPtr; + logic [DEPTH_LOG2-1:0] NxtWrPtr, NxtRdPtr; + logic [DEPTH_LOG2-1:0] WrPtrPlus1, WrPtrPlus2, RdPtrPlus1; + + logic dual_stbuf_write_r; + + logic isdccmst_m, isdccmst_r; + logic [3:0] stbuf_numvld_any, stbuf_specvld_any; + logic [1:0] stbuf_specvld_m, stbuf_specvld_r; + + logic [pt.LSU_SB_BITS-1:$clog2(BYTE_WIDTH)] cmpaddr_hi_m, cmpaddr_lo_m; + + // variables to detect matching from the store queue + logic [DEPTH-1:0] stbuf_match_hi, stbuf_match_lo; + logic [DEPTH-1:0][BYTE_WIDTH-1:0] stbuf_fwdbyteenvec_hi, stbuf_fwdbyteenvec_lo; + logic [DATA_WIDTH-1:0] stbuf_fwddata_hi_pre_m, stbuf_fwddata_lo_pre_m; + logic [BYTE_WIDTH-1:0] stbuf_fwdbyteen_hi_pre_m, stbuf_fwdbyteen_lo_pre_m; + + // logic to detect matching from the pipe - needed for store - load forwarding + logic [BYTE_WIDTH-1:0] ld_byte_rhit_lo_lo, ld_byte_rhit_hi_lo, ld_byte_rhit_lo_hi, ld_byte_rhit_hi_hi; + logic ld_addr_rhit_lo_lo, ld_addr_rhit_hi_lo, ld_addr_rhit_lo_hi, ld_addr_rhit_hi_hi; + + logic [BYTE_WIDTH-1:0] ld_byte_hit_lo, ld_byte_rhit_lo; + logic [BYTE_WIDTH-1:0] ld_byte_hit_hi, ld_byte_rhit_hi; + + logic [BYTE_WIDTH-1:0] ldst_byteen_hi_r; + logic [BYTE_WIDTH-1:0] ldst_byteen_lo_r; + // byte_en flowing down + logic [7:0] ldst_byteen_r; + logic [7:0] ldst_byteen_ext_r; + // fwd data through the pipe + logic [31:0] ld_fwddata_rpipe_lo; + logic [31:0] ld_fwddata_rpipe_hi; + + // coalescing signals + logic [DEPTH-1:0] store_matchvec_lo_r, store_matchvec_hi_r; + logic store_coalesce_lo_r, store_coalesce_hi_r; + + //---------------------------------------- + // Logic starts here + //---------------------------------------- + // Create high/low byte enables + assign store_byteen_ext_r[7:0] = ldst_byteen_r[7:0] << lsu_addr_r[1:0]; + assign store_byteen_hi_r[BYTE_WIDTH-1:0] = store_byteen_ext_r[7:4] & {4{lsu_pkt_r.store}}; + assign store_byteen_lo_r[BYTE_WIDTH-1:0] = store_byteen_ext_r[3:0] & {4{lsu_pkt_r.store}}; + + assign RdPtrPlus1[DEPTH_LOG2-1:0] = RdPtr[DEPTH_LOG2-1:0] + 1'b1; + assign WrPtrPlus1[DEPTH_LOG2-1:0] = WrPtr[DEPTH_LOG2-1:0] + 1'b1; + assign WrPtrPlus2[DEPTH_LOG2-1:0] = WrPtr[DEPTH_LOG2-1:0] + 2'b10; + + // ecc error on both hi/lo + assign dual_stbuf_write_r = ldst_dual_r & store_stbuf_reqvld_r; + assign ldst_stbuf_reqvld_r = ((lsu_commit_r | lsu_pkt_r.dma) & store_stbuf_reqvld_r); + + // Store Buffer coalescing + for (genvar i=0; i= DEPTH) : (stbuf_specvld_any[3:0] >= (DEPTH-1)); + assign lsu_stbuf_empty_any = (stbuf_numvld_any[3:0] == 4'b0); + + // Load forwarding logic from the store queue + assign cmpaddr_hi_m[pt.LSU_SB_BITS-1:$clog2(BYTE_WIDTH)] = end_addr_m[pt.LSU_SB_BITS-1:$clog2(BYTE_WIDTH)]; + + assign cmpaddr_lo_m[pt.LSU_SB_BITS-1:$clog2(BYTE_WIDTH)] = lsu_addr_m[pt.LSU_SB_BITS-1:$clog2(BYTE_WIDTH)]; + + always_comb begin: GenLdFwd + stbuf_fwdbyteen_hi_pre_m[BYTE_WIDTH-1:0] = '0; + stbuf_fwdbyteen_lo_pre_m[BYTE_WIDTH-1:0] = '0; + + for (int i=0; i (lsu_pkt_r.valid & lsu_pkt_r.store & addr_in_dccm_r); + endproperty + assert_stbuf_wren_store_dccm: assert property (stbuf_wren_store_dccm) else + $display("Illegal store buffer write"); + +`endif + +endmodule + diff --git a/designs/Caliptra/src/caliptra-rtl/el2_lsu_trigger.sv b/designs/Caliptra/src/caliptra-rtl/el2_lsu_trigger.sv new file mode 100644 index 0000000..23bbfc6 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/el2_lsu_trigger.sv @@ -0,0 +1,68 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2020 Western Digital Corporation or its affiliates. +// +// 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. + +//******************************************************************************** +// $Id$ +// +// +// Owner: +// Function: LSU Trigger logic +// Comments: +// +//******************************************************************************** +module el2_lsu_trigger +import el2_pkg::*; +#( +`include "el2_param.vh" + )( + input el2_trigger_pkt_t [3:0] trigger_pkt_any, // trigger packet from dec + input el2_lsu_pkt_t lsu_pkt_m, // lsu packet + input logic [31:0] lsu_addr_m, // address + input logic [31:0] store_data_m, // store data + + output logic [3:0] lsu_trigger_match_m // match result +); + + logic trigger_enable; + logic [3:0][31:0] lsu_match_data; + logic [3:0] lsu_trigger_data_match; + logic [31:0] store_data_trigger_m; + logic [31:0] ldst_addr_trigger_m; + + // Generate the trigger enable (This is for power) + always_comb begin + trigger_enable = 1'b0; + for (int i=0; i<4; i++) begin + trigger_enable |= trigger_pkt_any[i].m; + end + end + + assign store_data_trigger_m[31:0] = {({16{lsu_pkt_m.word}} & store_data_m[31:16]),({8{(lsu_pkt_m.half | lsu_pkt_m.word)}} & store_data_m[15:8]), store_data_m[7:0]} & {32{trigger_enable}}; + assign ldst_addr_trigger_m[31:0] = lsu_addr_m[31:0] & {32{trigger_enable}}; + + + for (genvar i=0; i<4; i++) begin : genblock + assign lsu_match_data[i][31:0] = ({32{~trigger_pkt_any[i].select}} & ldst_addr_trigger_m[31:0]) | + ({32{trigger_pkt_any[i].select & trigger_pkt_any[i].store}} & store_data_trigger_m[31:0]); + + rvmaskandmatch trigger_match (.mask(trigger_pkt_any[i].tdata2[31:0]), .data(lsu_match_data[i][31:0]), .masken(trigger_pkt_any[i].match), .match(lsu_trigger_data_match[i])); + + assign lsu_trigger_match_m[i] = lsu_pkt_m.valid & ~lsu_pkt_m.dma & trigger_enable & + ((trigger_pkt_any[i].store & lsu_pkt_m.store) | (trigger_pkt_any[i].load & lsu_pkt_m.load & ~trigger_pkt_any[i].select)) & + lsu_trigger_data_match[i]; + end + + +endmodule // el2_lsu_trigger diff --git a/designs/Caliptra/src/caliptra-rtl/el2_mem.sv b/designs/Caliptra/src/caliptra-rtl/el2_mem.sv new file mode 100644 index 0000000..85b9658 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/el2_mem.sv @@ -0,0 +1,187 @@ +//******************************************************************************** +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2020 Western Digital Corporation or its affiliates. +// Copyright (c) 2023 Antmicro +// +// 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. +//******************************************************************************** + +module el2_mem +import el2_pkg::*; +#( +`include "el2_param.vh" + ) +( + input logic clk, + input logic rst_l, + input logic dccm_clk_override, + input logic icm_clk_override, + input logic dec_tlu_core_ecc_disable, + + //DCCM ports + input logic dccm_wren, + input logic dccm_rden, + input logic [pt.DCCM_BITS-1:0] dccm_wr_addr_lo, + input logic [pt.DCCM_BITS-1:0] dccm_wr_addr_hi, + input logic [pt.DCCM_BITS-1:0] dccm_rd_addr_lo, + input logic [pt.DCCM_BITS-1:0] dccm_rd_addr_hi, + input logic [pt.DCCM_FDATA_WIDTH-1:0] dccm_wr_data_lo, + input logic [pt.DCCM_FDATA_WIDTH-1:0] dccm_wr_data_hi, + + + output logic [pt.DCCM_FDATA_WIDTH-1:0] dccm_rd_data_lo, + output logic [pt.DCCM_FDATA_WIDTH-1:0] dccm_rd_data_hi, + + //ICCM ports + input logic [pt.ICCM_BITS-1:1] iccm_rw_addr, + input logic iccm_buf_correct_ecc, // ICCM is doing a single bit error correct cycle + input logic iccm_correction_state, // ICCM is doing a single bit error correct cycle + input logic iccm_wren, + input logic iccm_rden, + input logic [2:0] iccm_wr_size, + input logic [77:0] iccm_wr_data, + + output logic [63:0] iccm_rd_data, + output logic [77:0] iccm_rd_data_ecc, + + // Icache and Itag Ports + + input logic [31:1] ic_rw_addr, + input logic [pt.ICACHE_NUM_WAYS-1:0] ic_tag_valid, + input logic [pt.ICACHE_NUM_WAYS-1:0] ic_wr_en, + input logic ic_rd_en, + input logic [63:0] ic_premux_data, // Premux data to be muxed with each way of the Icache. + input logic ic_sel_premux_data, // Premux data sel + + input logic [pt.ICACHE_BANKS_WAY-1:0][70:0] ic_wr_data, // Data to fill to the Icache. With ECC + input logic [70:0] ic_debug_wr_data, // Debug wr cache. + output logic [70:0] ic_debug_rd_data , // Data read from Icache. 2x64bits + parity bits. F2 stage. With ECC + input logic [pt.ICACHE_INDEX_HI:3] ic_debug_addr, // Read/Write addresss to the Icache. + input logic ic_debug_rd_en, // Icache debug rd + input logic ic_debug_wr_en, // Icache debug wr + input logic ic_debug_tag_array, // Debug tag array + input logic [pt.ICACHE_NUM_WAYS-1:0] ic_debug_way, // Debug way. Rd or Wr. + + output logic [63:0] ic_rd_data , // Data read from Icache. 2x64bits + parity bits. F2 stage. With ECC + output logic [25:0] ictag_debug_rd_data,// Debug icache tag. + + + output logic [pt.ICACHE_BANKS_WAY-1:0] ic_eccerr, // ecc error per bank + output logic [pt.ICACHE_BANKS_WAY-1:0] ic_parerr, // parity error per bank + output logic [pt.ICACHE_NUM_WAYS-1:0] ic_rd_hit, + output logic ic_tag_perr, // Icache Tag parity error + + el2_mem_if.veer_sram_src mem_export, + el2_mem_if.veer_icache_src icache_export, + + // Excluding scan_mode from coverage as its usage is determined by the integrator of the VeeR core. + /*pragma coverage off*/ + input logic scan_mode + /*pragma coverage on*/ + +); + + logic active_clk; + rvoclkhdr active_cg ( .en(1'b1), .l1clk(active_clk), .* ); + + el2_mem_if mem_export_local (); + + assign mem_export_local.clk = clk; + + assign mem_export .clk = clk; + + assign mem_export .iccm_clken = mem_export_local.iccm_clken; + assign mem_export .iccm_wren_bank = mem_export_local.iccm_wren_bank; + assign mem_export .iccm_addr_bank = mem_export_local.iccm_addr_bank; + assign mem_export .iccm_bank_wr_data = mem_export_local.iccm_bank_wr_data; + assign mem_export .iccm_bank_wr_ecc = mem_export_local.iccm_bank_wr_ecc; + assign mem_export_local.iccm_bank_dout = mem_export. iccm_bank_dout; + assign mem_export_local.iccm_bank_ecc = mem_export. iccm_bank_ecc; + + assign mem_export .dccm_clken = mem_export_local.dccm_clken; + assign mem_export .dccm_wren_bank = mem_export_local.dccm_wren_bank; + assign mem_export .dccm_addr_bank = mem_export_local.dccm_addr_bank; + assign mem_export .dccm_wr_data_bank = mem_export_local.dccm_wr_data_bank; + assign mem_export .dccm_wr_ecc_bank = mem_export_local.dccm_wr_ecc_bank; + assign mem_export_local.dccm_bank_dout = mem_export .dccm_bank_dout; + assign mem_export_local.dccm_bank_ecc = mem_export .dccm_bank_ecc; + + // icache data + assign icache_export .ic_b_sb_wren = mem_export_local.ic_b_sb_wren; + assign icache_export .ic_b_sb_bit_en_vec = mem_export_local.ic_b_sb_bit_en_vec; + assign icache_export .ic_sb_wr_data = mem_export_local.ic_sb_wr_data; + assign icache_export .ic_rw_addr_bank_q = mem_export_local.ic_rw_addr_bank_q; + assign icache_export .ic_bank_way_clken_final = mem_export_local.ic_bank_way_clken_final; + assign icache_export .ic_bank_way_clken_final_up = mem_export_local.ic_bank_way_clken_final_up; + assign mem_export_local.wb_packeddout_pre = icache_export .wb_packeddout_pre; + assign mem_export_local.wb_dout_pre_up = icache_export .wb_dout_pre_up; + + // icache tag + assign icache_export .ic_tag_clken_final = mem_export_local.ic_tag_clken_final; + assign icache_export .ic_tag_wren_q = mem_export_local.ic_tag_wren_q; + assign icache_export .ic_tag_wren_biten_vec = mem_export_local.ic_tag_wren_biten_vec; + assign icache_export .ic_tag_wr_data = mem_export_local.ic_tag_wr_data; + assign icache_export .ic_rw_addr_q = mem_export_local.ic_rw_addr_q; + assign mem_export_local.ic_tag_data_raw_packed_pre = icache_export .ic_tag_data_raw_packed_pre; + assign mem_export_local.ic_tag_data_raw_pre = icache_export .ic_tag_data_raw_pre; + + // DCCM Instantiation + if (pt.DCCM_ENABLE == 1) begin: Gen_dccm_enable + el2_lsu_dccm_mem #(.pt(pt)) dccm ( + .clk_override(dccm_clk_override), + .dccm_mem_export(mem_export_local.veer_dccm), + .* + ); + end else begin: Gen_dccm_disable + assign dccm_rd_data_lo = '0; + assign dccm_rd_data_hi = '0; + end + +if ( pt.ICACHE_ENABLE ) begin: icache + el2_ifu_ic_mem #(.pt(pt)) icm ( + .clk_override(icm_clk_override), + .icache_export(mem_export_local.veer_icache_src), + .* + ); +end +else begin + assign ic_rd_hit[pt.ICACHE_NUM_WAYS-1:0] = '0; + assign ic_tag_perr = '0 ; + assign ic_rd_data = '0 ; + assign ictag_debug_rd_data = '0 ; + assign ic_debug_rd_data = '0 ; + assign ic_eccerr = '0; +end // else: !if( pt.ICACHE_ENABLE ) + + + +if (pt.ICCM_ENABLE) begin : iccm + el2_ifu_iccm_mem #(.pt(pt)) iccm (.*, + .clk_override(icm_clk_override), + .iccm_rw_addr(iccm_rw_addr[pt.ICCM_BITS-1:1]), + .iccm_rd_data(iccm_rd_data[63:0]), + .iccm_mem_export(mem_export_local.veer_iccm) + ); +end +else begin + assign iccm_rd_data = '0 ; + assign iccm_rd_data_ecc = '0 ; + assign mem_export_local.iccm_addr_bank = '0; + assign mem_export_local.iccm_bank_wr_data = '0; + assign mem_export_local.iccm_bank_wr_ecc = '0; + assign mem_export_local.iccm_clken = '0; + assign mem_export_local.iccm_wren_bank = '0; +end + + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/el2_mem_if.sv b/designs/Caliptra/src/caliptra-rtl/el2_mem_if.sv new file mode 100644 index 0000000..dce5a04 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/el2_mem_if.sv @@ -0,0 +1,149 @@ +//******************************************************************************** +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2020 Western Digital Corporation or its affiliates. +// Copyright 2022 Microsoft Corporation +// Copyright (c) 2023 Antmicro +// +// 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. +//******************************************************************************** + + +import el2_pkg::*; +interface el2_mem_if #( + `include "el2_param.vh" +) (); + ////////////////////////////////////////// + // Clock + logic clk; + + + ////////////////////////////////////////// + // ICCM + logic [pt.ICCM_NUM_BANKS-1:0] iccm_clken; + logic [pt.ICCM_NUM_BANKS-1:0] iccm_wren_bank; + logic [pt.ICCM_NUM_BANKS-1:0][pt.ICCM_BITS-1:pt.ICCM_BANK_INDEX_LO] iccm_addr_bank; + + logic [pt.ICCM_NUM_BANKS-1:0][ 31:0] iccm_bank_wr_data; + logic [pt.ICCM_NUM_BANKS-1:0][ pt.ICCM_ECC_WIDTH-1:0] iccm_bank_wr_ecc; + logic [pt.ICCM_NUM_BANKS-1:0][ 31:0] iccm_bank_dout; + logic [pt.ICCM_NUM_BANKS-1:0][ pt.ICCM_ECC_WIDTH-1:0] iccm_bank_ecc; + + + ////////////////////////////////////////// + // DCCM + logic [pt.DCCM_NUM_BANKS-1:0] dccm_clken; + logic [pt.DCCM_NUM_BANKS-1:0] dccm_wren_bank; + logic [pt.DCCM_NUM_BANKS-1:0][pt.DCCM_BITS-1:(pt.DCCM_BANK_BITS+2)] dccm_addr_bank; + logic [pt.DCCM_NUM_BANKS-1:0][ pt.DCCM_DATA_WIDTH-1:0] dccm_wr_data_bank; + logic [pt.DCCM_NUM_BANKS-1:0][ pt.DCCM_ECC_WIDTH-1:0] dccm_wr_ecc_bank; + logic [pt.DCCM_NUM_BANKS-1:0][ pt.DCCM_DATA_WIDTH-1:0] dccm_bank_dout; + logic [pt.DCCM_NUM_BANKS-1:0][ pt.DCCM_ECC_WIDTH-1:0] dccm_bank_ecc; + + ////////////////////////////////////////// + // ICACHE DATA + logic [pt.ICACHE_BANKS_WAY-1:0][pt.ICACHE_NUM_WAYS-1:0] ic_b_sb_wren; + logic [pt.ICACHE_BANKS_WAY-1:0][(71*pt.ICACHE_NUM_WAYS)-1:0] ic_b_sb_bit_en_vec; + logic [pt.ICACHE_BANKS_WAY-1:0][(71*pt.ICACHE_NUM_WAYS)-1:0] wb_packeddout_pre; + logic [pt.ICACHE_BANKS_WAY-1:0][70:0] ic_sb_wr_data; + logic [pt.ICACHE_BANKS_WAY-1:0][pt.ICACHE_INDEX_HI : pt.ICACHE_DATA_INDEX_LO] ic_rw_addr_bank_q; + logic [pt.ICACHE_BANKS_WAY-1:0] ic_bank_way_clken_final; + logic [pt.ICACHE_NUM_WAYS-1:0][pt.ICACHE_BANKS_WAY-1:0] ic_bank_way_clken_final_up; + logic [pt.ICACHE_NUM_WAYS-1:0][pt.ICACHE_BANKS_WAY-1:0][71-1:0] wb_dout_pre_up; + + ////////////////////////////////////////// + // ICACHE TAG + logic [pt.ICACHE_NUM_WAYS-1:0] ic_tag_clken_final; + logic [pt.ICACHE_NUM_WAYS-1:0] ic_tag_wren_q; + logic [(26*pt.ICACHE_NUM_WAYS)-1 :0] ic_tag_wren_biten_vec; + logic [(26*pt.ICACHE_NUM_WAYS)-1 :0] ic_tag_data_raw_packed_pre; + logic [25:0] ic_tag_wr_data; + logic [pt.ICACHE_INDEX_HI: pt.ICACHE_TAG_INDEX_LO] ic_rw_addr_q; + logic [pt.ICACHE_NUM_WAYS-1:0] [25:0] ic_tag_data_raw_pre; + + ////////////////////////////////////////// + // MODPORTS + // Complete modport + modport veer_sram_icache_src( + output clk, + // ICCM + output iccm_clken, iccm_wren_bank, iccm_addr_bank, iccm_bank_wr_data, iccm_bank_wr_ecc, + input iccm_bank_dout, iccm_bank_ecc, + // DCCM + output dccm_clken, dccm_wren_bank, dccm_addr_bank, dccm_wr_data_bank, dccm_wr_ecc_bank, + input dccm_bank_dout, dccm_bank_ecc, + // ICACHE data + output ic_b_sb_wren, ic_b_sb_bit_en_vec, ic_sb_wr_data, ic_rw_addr_bank_q, ic_bank_way_clken_final, ic_bank_way_clken_final_up, + input wb_packeddout_pre, wb_dout_pre_up, + // ICACHE tag + output ic_tag_clken_final, ic_tag_wren_q, ic_tag_wren_biten_vec, ic_tag_wr_data, ic_rw_addr_q, + input ic_tag_data_raw_packed_pre, ic_tag_data_raw_pre + ); + + modport veer_iccm( + input clk, + // ICCM + output iccm_clken, iccm_wren_bank, iccm_addr_bank, iccm_bank_wr_data, iccm_bank_wr_ecc, + input iccm_bank_dout, iccm_bank_ecc + ); + + modport veer_dccm( + input clk, + // DCCM + output dccm_clken, dccm_wren_bank, dccm_addr_bank, dccm_wr_data_bank, dccm_wr_ecc_bank, + input dccm_bank_dout, dccm_bank_ecc + ); + + modport veer_sram_src( + output clk, + // ICCM + output iccm_clken, iccm_wren_bank, iccm_addr_bank, iccm_bank_wr_data, iccm_bank_wr_ecc, + input iccm_bank_dout, iccm_bank_ecc, + // DCCM + output dccm_clken, dccm_wren_bank, dccm_addr_bank, dccm_wr_data_bank, dccm_wr_ecc_bank, + input dccm_bank_dout, dccm_bank_ecc + ); + + modport veer_sram_sink( + input clk, + // ICCM + input iccm_clken, iccm_wren_bank, iccm_addr_bank, iccm_bank_wr_data, iccm_bank_wr_ecc, + output iccm_bank_dout, iccm_bank_ecc, + // DCCM + input dccm_clken, dccm_wren_bank, dccm_addr_bank, dccm_wr_data_bank, dccm_wr_ecc_bank, + output dccm_bank_dout, dccm_bank_ecc + ); + + modport veer_icache_data( + // data + output ic_b_sb_wren, ic_b_sb_bit_en_vec, ic_sb_wr_data, ic_rw_addr_bank_q, ic_bank_way_clken_final, ic_bank_way_clken_final_up, + input wb_packeddout_pre, wb_dout_pre_up + ); + + modport veer_icache_tag( + // tag + output ic_tag_clken_final, ic_tag_wren_q, ic_tag_wren_biten_vec, ic_tag_wr_data, ic_rw_addr_q, + input ic_tag_data_raw_packed_pre,ic_tag_data_raw_pre + ); + + modport veer_icache_src( + // cache uses the same clk as sram, we do not define clk port in this modport, + // assuming the clk will be connected in sram_src + // data + output ic_b_sb_wren, ic_b_sb_bit_en_vec, ic_sb_wr_data, ic_rw_addr_bank_q, ic_bank_way_clken_final, ic_bank_way_clken_final_up, + input wb_packeddout_pre, wb_dout_pre_up, + // tag + output ic_tag_clken_final, ic_tag_wren_q, ic_tag_wren_biten_vec, ic_tag_wr_data, ic_rw_addr_q, + input ic_tag_data_raw_packed_pre,ic_tag_data_raw_pre + ); + +endinterface diff --git a/designs/Caliptra/src/caliptra-rtl/el2_param.vh b/designs/Caliptra/src/caliptra-rtl/el2_param.vh new file mode 100644 index 0000000..fec11ca --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/el2_param.vh @@ -0,0 +1,196 @@ +//******************************************************************************** +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2020 Western Digital Corporation or its affiliates. +// +// 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. +//******************************************************************************** + +parameter el2_param_t pt = '{ + BHT_ADDR_HI : 8'h09 , + BHT_ADDR_LO : 6'h02 , + BHT_ARRAY_DEPTH : 15'h0100 , + BHT_GHR_HASH_1 : 5'h00 , + BHT_GHR_SIZE : 8'h08 , + BHT_SIZE : 16'h0200 , + BITMANIP_ZBA : 5'h01 , + BITMANIP_ZBB : 5'h01 , + BITMANIP_ZBC : 5'h01 , + BITMANIP_ZBE : 5'h00 , + BITMANIP_ZBF : 5'h00 , + BITMANIP_ZBP : 5'h00 , + BITMANIP_ZBR : 5'h00 , + BITMANIP_ZBS : 5'h01 , + BTB_ADDR_HI : 9'h009 , + BTB_ADDR_LO : 6'h02 , + BTB_ARRAY_DEPTH : 13'h0100 , + BTB_BTAG_FOLD : 5'h00 , + BTB_BTAG_SIZE : 9'h005 , + BTB_ENABLE : 5'h01 , + BTB_FOLD2_INDEX_HASH : 5'h00 , + BTB_FULLYA : 5'h00 , + BTB_INDEX1_HI : 9'h009 , + BTB_INDEX1_LO : 9'h002 , + BTB_INDEX2_HI : 9'h011 , + BTB_INDEX2_LO : 9'h00A , + BTB_INDEX3_HI : 9'h019 , + BTB_INDEX3_LO : 9'h012 , + BTB_SIZE : 14'h0200 , + BTB_TOFFSET_SIZE : 9'h00C , + BUILD_AHB_LITE : 5'h01 , + BUILD_AXI4 : 4'h0 , + BUILD_AXI_NATIVE : 5'h01 , + BUS_PRTY_DEFAULT : 6'h03 , + DATA_ACCESS_ADDR0 : 36'h000000000 , + DATA_ACCESS_ADDR1 : 36'h000000000 , + DATA_ACCESS_ADDR2 : 36'h000000000 , + DATA_ACCESS_ADDR3 : 36'h000000000 , + DATA_ACCESS_ADDR4 : 36'h000000000 , + DATA_ACCESS_ADDR5 : 36'h000000000 , + DATA_ACCESS_ADDR6 : 36'h000000000 , + DATA_ACCESS_ADDR7 : 36'h000000000 , + DATA_ACCESS_ENABLE0 : 5'h00 , + DATA_ACCESS_ENABLE1 : 5'h00 , + DATA_ACCESS_ENABLE2 : 5'h00 , + DATA_ACCESS_ENABLE3 : 5'h00 , + DATA_ACCESS_ENABLE4 : 5'h00 , + DATA_ACCESS_ENABLE5 : 5'h00 , + DATA_ACCESS_ENABLE6 : 5'h00 , + DATA_ACCESS_ENABLE7 : 5'h00 , + DATA_ACCESS_MASK0 : 36'h0FFFFFFFF , + DATA_ACCESS_MASK1 : 36'h0FFFFFFFF , + DATA_ACCESS_MASK2 : 36'h0FFFFFFFF , + DATA_ACCESS_MASK3 : 36'h0FFFFFFFF , + DATA_ACCESS_MASK4 : 36'h0FFFFFFFF , + DATA_ACCESS_MASK5 : 36'h0FFFFFFFF , + DATA_ACCESS_MASK6 : 36'h0FFFFFFFF , + DATA_ACCESS_MASK7 : 36'h0FFFFFFFF , + DCCM_BANK_BITS : 7'h02 , + DCCM_BITS : 9'h012 , + DCCM_BYTE_WIDTH : 7'h04 , + DCCM_DATA_WIDTH : 10'h020 , + DCCM_ECC_WIDTH : 7'h07 , + DCCM_ENABLE : 5'h01 , + DCCM_FDATA_WIDTH : 10'h027 , + DCCM_INDEX_BITS : 8'h0E , + DCCM_NUM_BANKS : 9'h004 , + DCCM_REGION : 8'h05 , + DCCM_SADR : 36'h050000000 , + DCCM_SIZE : 14'h0100 , + DCCM_WIDTH_BITS : 6'h02 , + DIV_BIT : 7'h04 , + DIV_NEW : 5'h01 , + DMA_BUF_DEPTH : 7'h05 , + DMA_BUS_ID : 9'h001 , + DMA_BUS_PRTY : 6'h02 , + DMA_BUS_TAG : 8'h01 , + FAST_INTERRUPT_REDIRECT : 5'h01 , + ICACHE_2BANKS : 5'h01 , + ICACHE_BANK_BITS : 7'h01 , + ICACHE_BANK_HI : 7'h03 , + ICACHE_BANK_LO : 6'h03 , + ICACHE_BANK_WIDTH : 8'h08 , + ICACHE_BANKS_WAY : 7'h02 , + ICACHE_BEAT_ADDR_HI : 8'h05 , + ICACHE_BEAT_BITS : 8'h03 , + ICACHE_BYPASS_ENABLE : 5'h01 , + ICACHE_DATA_DEPTH : 18'h00200 , + ICACHE_DATA_INDEX_LO : 7'h04 , + ICACHE_DATA_WIDTH : 11'h040 , + ICACHE_ECC : 5'h01 , + ICACHE_ENABLE : 5'h00 , + ICACHE_FDATA_WIDTH : 11'h047 , + ICACHE_INDEX_HI : 9'h00C , + ICACHE_LN_SZ : 11'h040 , + ICACHE_NUM_BEATS : 8'h08 , + ICACHE_NUM_BYPASS : 8'h02 , + ICACHE_NUM_BYPASS_WIDTH : 8'h02 , + ICACHE_NUM_WAYS : 7'h02 , + ICACHE_ONLY : 5'h00 , + ICACHE_SCND_LAST : 8'h06 , + ICACHE_SIZE : 13'h0010 , + ICACHE_STATUS_BITS : 7'h01 , + ICACHE_TAG_BYPASS_ENABLE : 5'h01 , + ICACHE_TAG_DEPTH : 17'h00080 , + ICACHE_TAG_INDEX_LO : 7'h06 , + ICACHE_TAG_LO : 9'h00D , + ICACHE_TAG_NUM_BYPASS : 8'h02 , + ICACHE_TAG_NUM_BYPASS_WIDTH : 8'h02 , + ICACHE_WAYPACK : 5'h01 , + ICCM_BANK_BITS : 7'h02 , + ICCM_BANK_HI : 9'h003 , + ICCM_BANK_INDEX_LO : 9'h004 , + ICCM_BITS : 9'h012 , + ICCM_ECC_WIDTH : 7'h07 , + ICCM_ENABLE : 5'h01 , + ICCM_ICACHE : 5'h00 , + ICCM_INDEX_BITS : 8'h0E , + ICCM_NUM_BANKS : 9'h004 , + ICCM_ONLY : 5'h01 , + ICCM_REGION : 8'h04 , + ICCM_SADR : 36'h040000000 , + ICCM_SIZE : 14'h0100 , + IFU_BUS_ID : 5'h01 , + IFU_BUS_PRTY : 6'h02 , + IFU_BUS_TAG : 8'h03 , + INST_ACCESS_ADDR0 : 36'h000000000 , + INST_ACCESS_ADDR1 : 36'h000000000 , + INST_ACCESS_ADDR2 : 36'h000000000 , + INST_ACCESS_ADDR3 : 36'h000000000 , + INST_ACCESS_ADDR4 : 36'h000000000 , + INST_ACCESS_ADDR5 : 36'h000000000 , + INST_ACCESS_ADDR6 : 36'h000000000 , + INST_ACCESS_ADDR7 : 36'h000000000 , + INST_ACCESS_ENABLE0 : 5'h00 , + INST_ACCESS_ENABLE1 : 5'h00 , + INST_ACCESS_ENABLE2 : 5'h00 , + INST_ACCESS_ENABLE3 : 5'h00 , + INST_ACCESS_ENABLE4 : 5'h00 , + INST_ACCESS_ENABLE5 : 5'h00 , + INST_ACCESS_ENABLE6 : 5'h00 , + INST_ACCESS_ENABLE7 : 5'h00 , + INST_ACCESS_MASK0 : 36'h0FFFFFFFF , + INST_ACCESS_MASK1 : 36'h0FFFFFFFF , + INST_ACCESS_MASK2 : 36'h0FFFFFFFF , + INST_ACCESS_MASK3 : 36'h0FFFFFFFF , + INST_ACCESS_MASK4 : 36'h0FFFFFFFF , + INST_ACCESS_MASK5 : 36'h0FFFFFFFF , + INST_ACCESS_MASK6 : 36'h0FFFFFFFF , + INST_ACCESS_MASK7 : 36'h0FFFFFFFF , + LOAD_TO_USE_PLUS1 : 5'h00 , + LSU2DMA : 5'h00 , + LSU_BUS_ID : 5'h01 , + LSU_BUS_PRTY : 6'h02 , + LSU_BUS_TAG : 8'h03 , + LSU_NUM_NBLOAD : 9'h004 , + LSU_NUM_NBLOAD_WIDTH : 7'h02 , + LSU_SB_BITS : 9'h012 , + LSU_STBUF_DEPTH : 8'h04 , + NO_ICCM_NO_ICACHE : 5'h00 , + PIC_2CYCLE : 5'h00 , + PIC_BASE_ADDR : 36'h060000000 , + PIC_BITS : 9'h00F , + PIC_INT_WORDS : 8'h01 , + PIC_REGION : 8'h06 , + PIC_SIZE : 13'h0020 , + PIC_TOTAL_INT : 12'h01F , + PIC_TOTAL_INT_PLUS1 : 13'h0020 , + PMP_ENTRIES : 11'h040 , + RET_STACK_SIZE : 8'h08 , + SB_BUS_ID : 5'h01 , + SB_BUS_PRTY : 6'h02 , + SB_BUS_TAG : 8'h01 , + SMEPMP : 4'h0 , + TIMER_LEGAL_EN : 5'h01 , + USER_MODE : 4'h0 +} +// parameter el2_param_t pt = 2291'h04840400010040010840000020908200002840004808220A0C848200060410C00000000000000000000000000000000000000000000000000000000000000000000000000000000003FFFFFFFC3FFFFFFFC3FFFFFFFC3FFFFFFFC3FFFFFFFC3FFFFFFFC3FFFFFFFC3FFFFFFFC104820401C21387010141400000001000820428042010840830C2010281840200081002008E0C0801004040800C01002100400606810104100C08120E10070102080800000000800420300000000000000000000000000000000000000000000000000000000000000000000000000000000000FFFFFFFF0FFFFFFFF0FFFFFFFF0FFFFFFFF0FFFFFFFF0FFFFFFFF0FFFFFFFF0FFFFFFFF000210181010481000060000000078083008007C04010020210082 diff --git a/designs/Caliptra/src/caliptra-rtl/el2_pdef.vh b/designs/Caliptra/src/caliptra-rtl/el2_pdef.vh new file mode 100644 index 0000000..bdbb9ac --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/el2_pdef.vh @@ -0,0 +1,197 @@ +//******************************************************************************** +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2020 Western Digital Corporation or its affiliates. +// +// 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. +//******************************************************************************** + + +typedef struct packed { + logic [7:0] BHT_ADDR_HI; + logic [5:0] BHT_ADDR_LO; + logic [14:0] BHT_ARRAY_DEPTH; + logic [4:0] BHT_GHR_HASH_1; + logic [7:0] BHT_GHR_SIZE; + logic [15:0] BHT_SIZE; + logic [4:0] BITMANIP_ZBA; + logic [4:0] BITMANIP_ZBB; + logic [4:0] BITMANIP_ZBC; + logic [4:0] BITMANIP_ZBE; + logic [4:0] BITMANIP_ZBF; + logic [4:0] BITMANIP_ZBP; + logic [4:0] BITMANIP_ZBR; + logic [4:0] BITMANIP_ZBS; + logic [8:0] BTB_ADDR_HI; + logic [5:0] BTB_ADDR_LO; + logic [12:0] BTB_ARRAY_DEPTH; + logic [4:0] BTB_BTAG_FOLD; + logic [8:0] BTB_BTAG_SIZE; + logic [4:0] BTB_ENABLE; + logic [4:0] BTB_FOLD2_INDEX_HASH; + logic [4:0] BTB_FULLYA; + logic [8:0] BTB_INDEX1_HI; + logic [8:0] BTB_INDEX1_LO; + logic [8:0] BTB_INDEX2_HI; + logic [8:0] BTB_INDEX2_LO; + logic [8:0] BTB_INDEX3_HI; + logic [8:0] BTB_INDEX3_LO; + logic [13:0] BTB_SIZE; + logic [8:0] BTB_TOFFSET_SIZE; + logic [4:0] BUILD_AHB_LITE; + logic BUILD_AXI4; + logic [4:0] BUILD_AXI_NATIVE; + logic [5:0] BUS_PRTY_DEFAULT; + logic [35:0] DATA_ACCESS_ADDR0; + logic [35:0] DATA_ACCESS_ADDR1; + logic [35:0] DATA_ACCESS_ADDR2; + logic [35:0] DATA_ACCESS_ADDR3; + logic [35:0] DATA_ACCESS_ADDR4; + logic [35:0] DATA_ACCESS_ADDR5; + logic [35:0] DATA_ACCESS_ADDR6; + logic [35:0] DATA_ACCESS_ADDR7; + logic [4:0] DATA_ACCESS_ENABLE0; + logic [4:0] DATA_ACCESS_ENABLE1; + logic [4:0] DATA_ACCESS_ENABLE2; + logic [4:0] DATA_ACCESS_ENABLE3; + logic [4:0] DATA_ACCESS_ENABLE4; + logic [4:0] DATA_ACCESS_ENABLE5; + logic [4:0] DATA_ACCESS_ENABLE6; + logic [4:0] DATA_ACCESS_ENABLE7; + logic [35:0] DATA_ACCESS_MASK0; + logic [35:0] DATA_ACCESS_MASK1; + logic [35:0] DATA_ACCESS_MASK2; + logic [35:0] DATA_ACCESS_MASK3; + logic [35:0] DATA_ACCESS_MASK4; + logic [35:0] DATA_ACCESS_MASK5; + logic [35:0] DATA_ACCESS_MASK6; + logic [35:0] DATA_ACCESS_MASK7; + logic [6:0] DCCM_BANK_BITS; + logic [8:0] DCCM_BITS; + logic [6:0] DCCM_BYTE_WIDTH; + logic [9:0] DCCM_DATA_WIDTH; + logic [6:0] DCCM_ECC_WIDTH; + logic [4:0] DCCM_ENABLE; + logic [9:0] DCCM_FDATA_WIDTH; + logic [7:0] DCCM_INDEX_BITS; + logic [8:0] DCCM_NUM_BANKS; + logic [7:0] DCCM_REGION; + logic [35:0] DCCM_SADR; + logic [13:0] DCCM_SIZE; + logic [5:0] DCCM_WIDTH_BITS; + logic [6:0] DIV_BIT; + logic [4:0] DIV_NEW; + logic [6:0] DMA_BUF_DEPTH; + logic [8:0] DMA_BUS_ID; + logic [5:0] DMA_BUS_PRTY; + logic [7:0] DMA_BUS_TAG; + logic [4:0] FAST_INTERRUPT_REDIRECT; + logic [4:0] ICACHE_2BANKS; + logic [6:0] ICACHE_BANK_BITS; + logic [6:0] ICACHE_BANK_HI; + logic [5:0] ICACHE_BANK_LO; + logic [7:0] ICACHE_BANK_WIDTH; + logic [6:0] ICACHE_BANKS_WAY; + logic [7:0] ICACHE_BEAT_ADDR_HI; + logic [7:0] ICACHE_BEAT_BITS; + logic [4:0] ICACHE_BYPASS_ENABLE; + logic [17:0] ICACHE_DATA_DEPTH; + logic [6:0] ICACHE_DATA_INDEX_LO; + logic [10:0] ICACHE_DATA_WIDTH; + logic [4:0] ICACHE_ECC; + logic [4:0] ICACHE_ENABLE; + logic [10:0] ICACHE_FDATA_WIDTH; + logic [8:0] ICACHE_INDEX_HI; + logic [10:0] ICACHE_LN_SZ; + logic [7:0] ICACHE_NUM_BEATS; + logic [7:0] ICACHE_NUM_BYPASS; + logic [7:0] ICACHE_NUM_BYPASS_WIDTH; + logic [6:0] ICACHE_NUM_WAYS; + logic [4:0] ICACHE_ONLY; + logic [7:0] ICACHE_SCND_LAST; + logic [12:0] ICACHE_SIZE; + logic [6:0] ICACHE_STATUS_BITS; + logic [4:0] ICACHE_TAG_BYPASS_ENABLE; + logic [16:0] ICACHE_TAG_DEPTH; + logic [6:0] ICACHE_TAG_INDEX_LO; + logic [8:0] ICACHE_TAG_LO; + logic [7:0] ICACHE_TAG_NUM_BYPASS; + logic [7:0] ICACHE_TAG_NUM_BYPASS_WIDTH; + logic [4:0] ICACHE_WAYPACK; + logic [6:0] ICCM_BANK_BITS; + logic [8:0] ICCM_BANK_HI; + logic [8:0] ICCM_BANK_INDEX_LO; + logic [8:0] ICCM_BITS; + logic [6:0] ICCM_ECC_WIDTH; + logic [4:0] ICCM_ENABLE; + logic [4:0] ICCM_ICACHE; + logic [7:0] ICCM_INDEX_BITS; + logic [8:0] ICCM_NUM_BANKS; + logic [4:0] ICCM_ONLY; + logic [7:0] ICCM_REGION; + logic [35:0] ICCM_SADR; + logic [13:0] ICCM_SIZE; + logic [4:0] IFU_BUS_ID; + logic [5:0] IFU_BUS_PRTY; + logic [7:0] IFU_BUS_TAG; + logic [35:0] INST_ACCESS_ADDR0; + logic [35:0] INST_ACCESS_ADDR1; + logic [35:0] INST_ACCESS_ADDR2; + logic [35:0] INST_ACCESS_ADDR3; + logic [35:0] INST_ACCESS_ADDR4; + logic [35:0] INST_ACCESS_ADDR5; + logic [35:0] INST_ACCESS_ADDR6; + logic [35:0] INST_ACCESS_ADDR7; + logic [4:0] INST_ACCESS_ENABLE0; + logic [4:0] INST_ACCESS_ENABLE1; + logic [4:0] INST_ACCESS_ENABLE2; + logic [4:0] INST_ACCESS_ENABLE3; + logic [4:0] INST_ACCESS_ENABLE4; + logic [4:0] INST_ACCESS_ENABLE5; + logic [4:0] INST_ACCESS_ENABLE6; + logic [4:0] INST_ACCESS_ENABLE7; + logic [35:0] INST_ACCESS_MASK0; + logic [35:0] INST_ACCESS_MASK1; + logic [35:0] INST_ACCESS_MASK2; + logic [35:0] INST_ACCESS_MASK3; + logic [35:0] INST_ACCESS_MASK4; + logic [35:0] INST_ACCESS_MASK5; + logic [35:0] INST_ACCESS_MASK6; + logic [35:0] INST_ACCESS_MASK7; + logic [4:0] LOAD_TO_USE_PLUS1; + logic [4:0] LSU2DMA; + logic [4:0] LSU_BUS_ID; + logic [5:0] LSU_BUS_PRTY; + logic [7:0] LSU_BUS_TAG; + logic [8:0] LSU_NUM_NBLOAD; + logic [6:0] LSU_NUM_NBLOAD_WIDTH; + logic [8:0] LSU_SB_BITS; + logic [7:0] LSU_STBUF_DEPTH; + logic [4:0] NO_ICCM_NO_ICACHE; + logic [4:0] PIC_2CYCLE; + logic [35:0] PIC_BASE_ADDR; + logic [8:0] PIC_BITS; + logic [7:0] PIC_INT_WORDS; + logic [7:0] PIC_REGION; + logic [12:0] PIC_SIZE; + logic [11:0] PIC_TOTAL_INT; + logic [12:0] PIC_TOTAL_INT_PLUS1; + logic [10:0] PMP_ENTRIES; + logic [7:0] RET_STACK_SIZE; + logic [4:0] SB_BUS_ID; + logic [5:0] SB_BUS_PRTY; + logic [7:0] SB_BUS_TAG; + logic SMEPMP; + logic [4:0] TIMER_LEGAL_EN; + logic USER_MODE; +} el2_param_t; + diff --git a/designs/Caliptra/src/caliptra-rtl/el2_pic_ctrl.sv b/designs/Caliptra/src/caliptra-rtl/el2_pic_ctrl.sv new file mode 100644 index 0000000..07264d1 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/el2_pic_ctrl.sv @@ -0,0 +1,601 @@ +//******************************************************************************** +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2020 Western Digital Corporation or its affiliates. +// +// 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. +//******************************************************************************** + +//******************************************************************************** +// Function: Programmable Interrupt Controller +// Comments: +//******************************************************************************** + +module el2_pic_ctrl +import el2_pkg::*; +#( +`include "el2_param.vh" + ) + ( + + input logic clk, // Core clock + input logic free_clk, // free clock + input logic rst_l, // Reset for all flops + input logic clk_override, // Clock over-ride for gating + input logic io_clk_override, // PIC IO Clock over-ride for gating + input logic [pt.PIC_TOTAL_INT_PLUS1-1:0] extintsrc_req, // Interrupt requests + input logic [31:0] picm_rdaddr, // Address of the register + input logic [31:0] picm_wraddr, // Address of the register + input logic [31:0] picm_wr_data, // Data to be written to the register + input logic picm_wren, // Write enable to the register + input logic picm_rden, // Read enable for the register + input logic picm_mken, // Read the Mask for the register + input logic [3:0] meicurpl, // Current Priority Level + input logic [3:0] meipt, // Current Priority Threshold + + output logic mexintpend, // External Inerrupt request to the core + output logic [7:0] claimid, // Claim Id of the requested interrupt + output logic [3:0] pl, // Priority level of the requested interrupt + output logic [31:0] picm_rd_data, // Read data of the register + output logic mhwakeup, // Wake-up interrupt request + // Excluding scan_mode from coverage as its usage is determined by the integrator of the VeeR core. + /*pragma coverage off*/ + input logic scan_mode // scan mode + /*pragma coverage on*/ + +); + +localparam NUM_LEVELS = $clog2(pt.PIC_TOTAL_INT_PLUS1); +localparam INTPRIORITY_BASE_ADDR = pt.PIC_BASE_ADDR ; +localparam INTPEND_BASE_ADDR = pt.PIC_BASE_ADDR + 32'h00001000 ; +localparam INTENABLE_BASE_ADDR = pt.PIC_BASE_ADDR + 32'h00002000 ; +localparam EXT_INTR_PIC_CONFIG = pt.PIC_BASE_ADDR + 32'h00003000 ; +localparam EXT_INTR_GW_CONFIG = pt.PIC_BASE_ADDR + 32'h00004000 ; +localparam EXT_INTR_GW_CLEAR = pt.PIC_BASE_ADDR + 32'h00005000 ; + + +localparam INTPEND_SIZE = (pt.PIC_TOTAL_INT_PLUS1 <= 32) ? 32 : + (pt.PIC_TOTAL_INT_PLUS1 <= 64) ? 64 : + (pt.PIC_TOTAL_INT_PLUS1 <= 128) ? 128 : + (pt.PIC_TOTAL_INT_PLUS1 <= 256) ? 256 : + (pt.PIC_TOTAL_INT_PLUS1 <= 512) ? 512 : 1024 ; + +localparam INT_GRPS = INTPEND_SIZE / 32 ; +localparam INTPRIORITY_BITS = 4 ; +localparam ID_BITS = 8 ; +localparam int GW_CONFIG[pt.PIC_TOTAL_INT_PLUS1-1:0] = '{default:0} ; + +localparam INT_ENABLE_GRPS = (pt.PIC_TOTAL_INT_PLUS1 - 1) / 4 ; + +logic [pt.PIC_TOTAL_INT_PLUS1-1:0] intenable_clk_enable ; +//logic [INT_ENABLE_GRPS:0] intenable_clk_enable_grp ; +logic [INT_ENABLE_GRPS:0] gw_clk ; + +logic addr_intpend_base_match; + +logic raddr_config_pic_match ; +logic raddr_intenable_base_match; +logic raddr_intpriority_base_match; +logic raddr_config_gw_base_match ; + +logic waddr_config_pic_match ; +logic waddr_intpriority_base_match; +logic waddr_intenable_base_match; +logic waddr_config_gw_base_match ; +logic addr_clear_gw_base_match ; + +logic mexintpend_in; +logic mhwakeup_in ; +logic intpend_reg_read ; + +logic [31:0] picm_rd_data_in, intpend_rd_out; +logic intenable_rd_out ; +logic [INTPRIORITY_BITS-1:0] intpriority_rd_out; +logic [1:0] gw_config_rd_out; + +logic [pt.PIC_TOTAL_INT_PLUS1-1:0] [INTPRIORITY_BITS-1:0] intpriority_reg; +logic [pt.PIC_TOTAL_INT_PLUS1-1:0] [INTPRIORITY_BITS-1:0] intpriority_reg_inv; +logic [pt.PIC_TOTAL_INT_PLUS1-1:0] intpriority_reg_we; +logic [pt.PIC_TOTAL_INT_PLUS1-1:0] intpriority_reg_re; +logic [pt.PIC_TOTAL_INT_PLUS1-1:0] [1:0] gw_config_reg; + +logic [pt.PIC_TOTAL_INT_PLUS1-1:0] intenable_reg; +logic [pt.PIC_TOTAL_INT_PLUS1-1:0] intenable_reg_we; +logic [pt.PIC_TOTAL_INT_PLUS1-1:0] intenable_reg_re; +logic [pt.PIC_TOTAL_INT_PLUS1-1:0] gw_config_reg_we; +logic [pt.PIC_TOTAL_INT_PLUS1-1:0] gw_config_reg_re; +logic [pt.PIC_TOTAL_INT_PLUS1-1:0] gw_clear_reg_we; + +logic [INTPEND_SIZE-1:0] intpend_reg_extended; + +logic [pt.PIC_TOTAL_INT_PLUS1-1:0] [INTPRIORITY_BITS-1:0] intpend_w_prior_en; +logic [pt.PIC_TOTAL_INT_PLUS1-1:0] [ID_BITS-1:0] intpend_id; +logic [INTPRIORITY_BITS-1:0] maxint; +logic [INTPRIORITY_BITS-1:0] selected_int_priority; +logic [INT_GRPS-1:0] [31:0] intpend_rd_part_out ; + +logic config_reg; +logic intpriord; +logic config_reg_we ; +logic config_reg_re ; +logic config_reg_in ; +logic intpriority_reg_read ; +logic intenable_reg_read ; +logic gw_config_reg_read ; +logic picm_wren_ff , picm_rden_ff ; +logic [31:0] picm_raddr_ff; +logic [31:0] picm_waddr_ff; +logic [31:0] picm_wr_data_ff; +logic [3:0] mask; +logic picm_mken_ff; +logic [ID_BITS-1:0] claimid_in ; +logic [INTPRIORITY_BITS-1:0] pl_in ; +logic [INTPRIORITY_BITS-1:0] pl_in_q ; + +//logic [pt.PIC_TOTAL_INT_PLUS1-1:0] extintsrc_req_sync; +logic [pt.PIC_TOTAL_INT_PLUS1-1:0] extintsrc_req_gw; + logic picm_bypass_ff; + +// clkens + logic pic_raddr_c1_clken; + logic pic_waddr_c1_clken; + logic pic_data_c1_clken; + logic pic_pri_c1_clken; + logic pic_int_c1_clken; + logic gw_config_c1_clken; + +// clocks + logic pic_raddr_c1_clk; + logic pic_data_c1_clk; + logic pic_pri_c1_clk; + logic pic_int_c1_clk; + logic gw_config_c1_clk; + +// ---- Clock gating section ------ +// c1 clock enables + assign pic_raddr_c1_clken = picm_mken | picm_rden | clk_override; + assign pic_data_c1_clken = picm_wren | clk_override; + assign pic_pri_c1_clken = (waddr_intpriority_base_match & picm_wren_ff) | (raddr_intpriority_base_match & picm_rden_ff) | clk_override; + assign pic_int_c1_clken = (waddr_intenable_base_match & picm_wren_ff) | (raddr_intenable_base_match & picm_rden_ff) | clk_override; + assign gw_config_c1_clken = (waddr_config_gw_base_match & picm_wren_ff) | (raddr_config_gw_base_match & picm_rden_ff) | clk_override; + + // C1 - 1 clock pulse for data + rvoclkhdr pic_addr_c1_cgc ( .en(pic_raddr_c1_clken), .l1clk(pic_raddr_c1_clk), .* ); + rvoclkhdr pic_data_c1_cgc ( .en(pic_data_c1_clken), .l1clk(pic_data_c1_clk), .* ); + rvoclkhdr pic_pri_c1_cgc ( .en(pic_pri_c1_clken), .l1clk(pic_pri_c1_clk), .* ); + rvoclkhdr pic_int_c1_cgc ( .en(pic_int_c1_clken), .l1clk(pic_int_c1_clk), .* ); + rvoclkhdr gw_config_c1_cgc ( .en(gw_config_c1_clken), .l1clk(gw_config_c1_clk), .* ); + +// ------ end clock gating section ------------------------ + +assign raddr_intenable_base_match = (picm_raddr_ff[31:NUM_LEVELS+2] == INTENABLE_BASE_ADDR[31:NUM_LEVELS+2]) ; +assign raddr_intpriority_base_match = (picm_raddr_ff[31:NUM_LEVELS+2] == INTPRIORITY_BASE_ADDR[31:NUM_LEVELS+2]) ; +assign raddr_config_gw_base_match = (picm_raddr_ff[31:NUM_LEVELS+2] == EXT_INTR_GW_CONFIG[31:NUM_LEVELS+2]) ; +assign raddr_config_pic_match = (picm_raddr_ff[31:0] == EXT_INTR_PIC_CONFIG[31:0]) ; + +assign addr_intpend_base_match = (picm_raddr_ff[31:6] == INTPEND_BASE_ADDR[31:6]) ; + +assign waddr_config_pic_match = (picm_waddr_ff[31:0] == EXT_INTR_PIC_CONFIG[31:0]) ; +assign addr_clear_gw_base_match = (picm_waddr_ff[31:NUM_LEVELS+2] == EXT_INTR_GW_CLEAR[31:NUM_LEVELS+2]) ; +assign waddr_intpriority_base_match = (picm_waddr_ff[31:NUM_LEVELS+2] == INTPRIORITY_BASE_ADDR[31:NUM_LEVELS+2]) ; +assign waddr_intenable_base_match = (picm_waddr_ff[31:NUM_LEVELS+2] == INTENABLE_BASE_ADDR[31:NUM_LEVELS+2]) ; +assign waddr_config_gw_base_match = (picm_waddr_ff[31:NUM_LEVELS+2] == EXT_INTR_GW_CONFIG[31:NUM_LEVELS+2]) ; + + assign picm_bypass_ff = picm_rden_ff & picm_wren_ff & ( picm_raddr_ff[31:0] == picm_waddr_ff[31:0] ); // pic writes and reads to same address together + + +rvdff #(32) picm_radd_flop (.*, .din (picm_rdaddr), .dout(picm_raddr_ff), .clk(pic_raddr_c1_clk)); +rvdff #(32) picm_wadd_flop (.*, .din (picm_wraddr), .dout(picm_waddr_ff), .clk(pic_data_c1_clk)); +rvdff #(1) picm_wre_flop (.*, .din (picm_wren), .dout(picm_wren_ff), .clk(free_clk)); +rvdff #(1) picm_rde_flop (.*, .din (picm_rden), .dout(picm_rden_ff), .clk(free_clk)); +rvdff #(1) picm_mke_flop (.*, .din (picm_mken), .dout(picm_mken_ff), .clk(free_clk)); +rvdff #(32) picm_dat_flop (.*, .din (picm_wr_data[31:0]), .dout(picm_wr_data_ff[31:0]), .clk(pic_data_c1_clk)); + +//rvsyncss #(pt.PIC_TOTAL_INT_PLUS1-1) sync_inst +//( +// .clk (free_clk), +// .dout(extintsrc_req_sync[pt.PIC_TOTAL_INT_PLUS1-1:1]), +// .din (extintsrc_req[pt.PIC_TOTAL_INT_PLUS1-1:1]), +// .*) ; +// +//assign extintsrc_req_sync[0] = extintsrc_req[0]; +/* +genvar p ; +for (p=0; p<=INT_ENABLE_GRPS ; p++) begin : IO_CLK_GRP + if (p==INT_ENABLE_GRPS) begin : LAST_GRP + assign intenable_clk_enable_grp[p] = |intenable_clk_enable[pt.PIC_TOTAL_INT_PLUS1-1 : p*4] | io_clk_override; + rvoclkhdr intenable_c1_cgc ( .en(intenable_clk_enable_grp[p]), .l1clk(gw_clk[p]), .* ); + end else begin : CLK_GRPS + assign intenable_clk_enable_grp[p] = |intenable_clk_enable[p*4+3 : p*4] | io_clk_override; + rvoclkhdr intenable_c1_cgc ( .en(intenable_clk_enable_grp[p]), .l1clk(gw_clk[p]), .* ); + end +end +*/ + + + +genvar i ; +genvar p ; +for (p=0; p<=INT_ENABLE_GRPS ; p++) begin : IO_CLK_GRP +wire grp_clk, grp_clken; + + assign grp_clken = |intenable_clk_enable[(p==INT_ENABLE_GRPS?pt.PIC_TOTAL_INT_PLUS1-1:p*4+3) : p*4] | io_clk_override; + + `ifndef RV_FPGA_OPTIMIZE + rvclkhdr intenable_c1_cgc( .en(grp_clken), .l1clk(grp_clk), .* ); + `else +/*pragma coverage off*/ + assign gw_clk[p] = 1'b0 ; +/*pragma coverage on*/ + `endif + + for(genvar i= (p==0 ? 1: 0); i< (p==INT_ENABLE_GRPS ? pt.PIC_TOTAL_INT_PLUS1-p*4 :4); i++) begin : GW + el2_configurable_gw gw_inst( + .*, + .gw_clk(grp_clk), + .rawclk(clk), + .clken (grp_clken), + .extintsrc_req(extintsrc_req[i+p*4]) , + .meigwctrl_polarity(gw_config_reg[i+p*4][0]) , + .meigwctrl_type(gw_config_reg[i+p*4][1]) , + .meigwclr(gw_clear_reg_we[i+p*4]) , + .extintsrc_req_config(extintsrc_req_gw[i+p*4]) + ); + end +end + + + + + + + + +for (i=0; i 0 ) begin : NON_ZERO_INT + assign intpriority_reg_we[i] = waddr_intpriority_base_match & (picm_waddr_ff[NUM_LEVELS+1:2] == i) & picm_wren_ff; + assign intpriority_reg_re[i] = raddr_intpriority_base_match & (picm_raddr_ff[NUM_LEVELS+1:2] == i) & picm_rden_ff; + + assign intenable_reg_we[i] = waddr_intenable_base_match & (picm_waddr_ff[NUM_LEVELS+1:2] == i) & picm_wren_ff; + assign intenable_reg_re[i] = raddr_intenable_base_match & (picm_raddr_ff[NUM_LEVELS+1:2] == i) & picm_rden_ff; + + assign gw_config_reg_we[i] = waddr_config_gw_base_match & (picm_waddr_ff[NUM_LEVELS+1:2] == i) & picm_wren_ff; + assign gw_config_reg_re[i] = raddr_config_gw_base_match & (picm_raddr_ff[NUM_LEVELS+1:2] == i) & picm_rden_ff; + + assign gw_clear_reg_we[i] = addr_clear_gw_base_match & (picm_waddr_ff[NUM_LEVELS+1:2] == i) & picm_wren_ff ; + + rvdffs #(INTPRIORITY_BITS) intpriority_ff (.*, .en( intpriority_reg_we[i]), .din (picm_wr_data_ff[INTPRIORITY_BITS-1:0]), .dout(intpriority_reg[i]), .clk(pic_pri_c1_clk)); + rvdffs #(1) intenable_ff (.*, .en( intenable_reg_we[i]), .din (picm_wr_data_ff[0]), .dout(intenable_reg[i]), .clk(pic_int_c1_clk)); + rvdffs #(2) gw_config_ff (.*, .en( gw_config_reg_we[i]), .din (picm_wr_data_ff[1:0]), .dout(gw_config_reg[i]), .clk(gw_config_c1_clk)); + + assign intenable_clk_enable[i] = gw_config_reg[i][1] | intenable_reg_we[i] | intenable_reg[i] | gw_clear_reg_we[i] ; + +/* + rvsyncss_fpga #(1) sync_inst + ( + .gw_clk (gw_clk[i/4]), + .rawclk (clk), + .clken (intenable_clk_enable_grp[i/4]), + .dout (extintsrc_req_sync[i]), + .din (extintsrc_req[i]), + .*) ; + + + + + + el2_configurable_gw config_gw_inst(.*, + .gw_clk(gw_clk[i/4]), + .rawclk(clk), + .clken (intenable_clk_enable_grp[i/4]), + .extintsrc_req_sync(extintsrc_req_sync[i]) , + .meigwctrl_polarity(gw_config_reg[i][0]) , + .meigwctrl_type(gw_config_reg[i][1]) , + .meigwclr(gw_clear_reg_we[i]) , + .extintsrc_req_config(extintsrc_req_gw[i]) + ); + */ + + end else begin : INT_ZERO + assign intpriority_reg_we[i] = 1'b0 ; + assign intpriority_reg_re[i] = 1'b0 ; + assign intenable_reg_we[i] = 1'b0 ; + assign intenable_reg_re[i] = 1'b0 ; + + assign gw_config_reg_we[i] = 1'b0 ; + assign gw_config_reg_re[i] = 1'b0 ; + assign gw_clear_reg_we[i] = 1'b0 ; + + assign gw_config_reg[i] = '0 ; + + assign intpriority_reg[i] = {INTPRIORITY_BITS{1'b0}} ; + assign intenable_reg[i] = 1'b0 ; + assign extintsrc_req_gw[i] = 1'b0 ; +// assign extintsrc_req_sync[i] = 1'b0 ; + assign intenable_clk_enable[i] = 1'b0; + end + + + assign intpriority_reg_inv[i] = intpriord ? ~intpriority_reg[i] : intpriority_reg[i] ; + + assign intpend_w_prior_en[i] = {INTPRIORITY_BITS{(extintsrc_req_gw[i] & intenable_reg[i])}} & intpriority_reg_inv[i] ; + assign intpend_id[i] = i ; +end + + + assign pl_in[INTPRIORITY_BITS-1:0] = selected_int_priority[INTPRIORITY_BITS-1:0] ; + +//if (pt.PIC_2CYCLE == 1) begin : genblock +//end +//else begin : genblock +//end + + genvar l, m , j, k; + +if (pt.PIC_2CYCLE == 1) begin : genblock + logic [NUM_LEVELS/2:0] [pt.PIC_TOTAL_INT_PLUS1+2:0] [INTPRIORITY_BITS-1:0] level_intpend_w_prior_en; + logic [NUM_LEVELS/2:0] [pt.PIC_TOTAL_INT_PLUS1+2:0] [ID_BITS-1:0] level_intpend_id; + logic [NUM_LEVELS:NUM_LEVELS/2] [(pt.PIC_TOTAL_INT_PLUS1/2**(NUM_LEVELS/2))+1:0] [INTPRIORITY_BITS-1:0] levelx_intpend_w_prior_en; + logic [NUM_LEVELS:NUM_LEVELS/2] [(pt.PIC_TOTAL_INT_PLUS1/2**(NUM_LEVELS/2))+1:0] [ID_BITS-1:0] levelx_intpend_id; + + assign level_intpend_w_prior_en[0][pt.PIC_TOTAL_INT_PLUS1+2:0] = {4'b0,4'b0,4'b0,intpend_w_prior_en[pt.PIC_TOTAL_INT_PLUS1-1:0]} ; + assign level_intpend_id[0][pt.PIC_TOTAL_INT_PLUS1+2:0] = {8'b0,8'b0,8'b0,intpend_id[pt.PIC_TOTAL_INT_PLUS1-1:0]} ; + + logic [(pt.PIC_TOTAL_INT_PLUS1/2**(NUM_LEVELS/2)):0] [INTPRIORITY_BITS-1:0] l2_intpend_w_prior_en_ff; + logic [(pt.PIC_TOTAL_INT_PLUS1/2**(NUM_LEVELS/2)):0] [ID_BITS-1:0] l2_intpend_id_ff; + + assign levelx_intpend_w_prior_en[NUM_LEVELS/2][(pt.PIC_TOTAL_INT_PLUS1/2**(NUM_LEVELS/2))+1:0] = {{1*INTPRIORITY_BITS{1'b0}},l2_intpend_w_prior_en_ff[(pt.PIC_TOTAL_INT_PLUS1/2**(NUM_LEVELS/2)):0]} ; + assign levelx_intpend_id[NUM_LEVELS/2][(pt.PIC_TOTAL_INT_PLUS1/2**(NUM_LEVELS/2))+1:0] = {{1*ID_BITS{1'b1}},l2_intpend_id_ff[(pt.PIC_TOTAL_INT_PLUS1/2**(NUM_LEVELS/2)):0]} ; +/// Do the prioritization of the interrupts here //////////// + for (l=0; l meipt_inv[INTPRIORITY_BITS-1:0]) & + ( selected_int_priority[INTPRIORITY_BITS-1:0] > meicurpl_inv[INTPRIORITY_BITS-1:0]) ); +rvdff #(1) mexintpend_ff (.*, .clk(free_clk), .din (mexintpend_in), .dout(mexintpend)); + +assign maxint[INTPRIORITY_BITS-1:0] = intpriord ? 0 : 15 ; +assign mhwakeup_in = ( pl_in_q[INTPRIORITY_BITS-1:0] == maxint) ; +rvdff #(1) wake_up_ff (.*, .clk(free_clk), .din (mhwakeup_in), .dout(mhwakeup)); + + + + + +////////////////////////////////////////////////////////////////////////// +// Reads of register. +// 1- intpending +////////////////////////////////////////////////////////////////////////// + +assign intpend_reg_read = addr_intpend_base_match & picm_rden_ff ; +assign intpriority_reg_read = raddr_intpriority_base_match & picm_rden_ff; +assign intenable_reg_read = raddr_intenable_base_match & picm_rden_ff; +assign gw_config_reg_read = raddr_config_gw_base_match & picm_rden_ff; + +assign intpend_reg_extended[INTPEND_SIZE-1:0] = {{INTPEND_SIZE-pt.PIC_TOTAL_INT_PLUS1{1'b0}},extintsrc_req_gw[pt.PIC_TOTAL_INT_PLUS1-1:0]} ; + + for (i=0; i<(INT_GRPS); i++) begin + assign intpend_rd_part_out[i] = (({32{intpend_reg_read & picm_raddr_ff[5:2] == i}}) & intpend_reg_extended[((32*i)+31):(32*i)]) ; + end + + always_comb begin : INTPEND_RD + intpend_rd_out = '0 ; + for (int i=0; i +// +// 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. + +module el2_pmp + import el2_pkg::*; +#( + parameter PMP_CHANNELS = 3, + // Granularity of NAPOT access, + // 0 = No restriction, 1 = 8 byte, 2 = 16 byte, 3 = 32 byte, etc. + parameter PMP_GRANULARITY = 0, // TODO: Move to veer.config + `include "el2_param.vh" +) ( + input logic clk, // Top level clock + input logic rst_l, // Reset + /* pragma coverage off */ + input logic scan_mode, // Scan mode + /* pragma coverage on */ + +`ifdef RV_SMEPMP + input el2_mseccfg_pkt_t mseccfg, // mseccfg CSR content, RLB, MMWP and MML bits +`endif + +`ifdef RV_USER_MODE + input logic priv_mode_ns, // operating privilege mode (next clock cycle) + input logic priv_mode_eff, // operating effective privilege mode +`endif + + input el2_pmp_cfg_pkt_t pmp_pmpcfg [pt.PMP_ENTRIES], + input logic [31:0] pmp_pmpaddr[pt.PMP_ENTRIES], + + input logic [31:0] pmp_chan_addr[PMP_CHANNELS], + input el2_pmp_type_pkt_t pmp_chan_type[PMP_CHANNELS], + output logic pmp_chan_err [PMP_CHANNELS] +); + + logic [ 33:0] csr_pmp_addr_i [pt.PMP_ENTRIES]; + logic [ 33:0] pmp_req_addr_i [ PMP_CHANNELS]; + + logic [ 33:0] region_start_addr [pt.PMP_ENTRIES]; + logic [33:PMP_GRANULARITY+2] region_addr_mask [pt.PMP_ENTRIES]; + logic [ PMP_CHANNELS-1:0][pt.PMP_ENTRIES-1:0] region_match_gt; + logic [ PMP_CHANNELS-1:0][pt.PMP_ENTRIES-1:0] region_match_lt; + logic [ PMP_CHANNELS-1:0][pt.PMP_ENTRIES-1:0] region_match_eq; + logic [ PMP_CHANNELS-1:0][pt.PMP_ENTRIES-1:0] region_match_all; + logic [ PMP_CHANNELS-1:0][pt.PMP_ENTRIES-1:0] region_basic_perm_check; + logic [ PMP_CHANNELS-1:0][pt.PMP_ENTRIES-1:0] region_perm_check; + +`ifdef RV_USER_MODE + logic any_region_enabled; +`endif + + /////////////////////// + // Functions for PMP // + /////////////////////// + + // Flow of the PMP checking operation follows as below + // + // basic_perm_check ---> perm_check_wrapper ---> orig_perm_check ---/ + // | + // region_match_all -----------------> access_fault_check <---------- + // | + // \--> pmp_chan_err + + // A wrapper function in which it is decided which form of permission check function gets called + function automatic logic perm_check_wrapper(el2_mseccfg_pkt_t csr_pmp_mseccfg, + el2_pmp_cfg_pkt_t csr_pmp_cfg, + el2_pmp_type_pkt_t req_type, + logic priv_mode, + logic permission_check); + + return csr_pmp_mseccfg.MML ? mml_perm_check(csr_pmp_cfg, + req_type, + priv_mode, + permission_check) : + orig_perm_check(csr_pmp_cfg.lock, + priv_mode, + permission_check); + endfunction + + // Compute permissions checks that apply when MSECCFG.MML is set. Added for Smepmp support. + function automatic logic mml_perm_check(el2_pmp_cfg_pkt_t csr_pmp_cfg, + el2_pmp_type_pkt_t pmp_req_type, + logic priv_mode, + logic permission_check); + logic result; + logic unused_cfg = |csr_pmp_cfg.mode; + + if (!csr_pmp_cfg.read && csr_pmp_cfg.write) begin + // Special-case shared regions where R = 0, W = 1 + unique case ({csr_pmp_cfg.lock, csr_pmp_cfg.execute}) + // Read/write in M, read only in U + 2'b00: result = + (pmp_req_type == READ) | + ((pmp_req_type == WRITE) & ~priv_mode); + // Read/write in M/U + 2'b01: result = + (pmp_req_type == READ) | + (pmp_req_type == WRITE); + // Execute only on M/U + 2'b10: result = (pmp_req_type == EXEC); + // Read/execute in M, execute only on U + 2'b11: result = + (pmp_req_type == EXEC) | + ((pmp_req_type == READ) & ~priv_mode); + /* pragma coverage off */ + default: ; + /* pragma coverage on */ + endcase + end else begin + if (csr_pmp_cfg.read & csr_pmp_cfg.write & csr_pmp_cfg.execute & csr_pmp_cfg.lock) begin + // Special-case shared read only region when R = 1, W = 1, X = 1, L = 1 + result = (pmp_req_type == READ); + end else begin + // Otherwise use basic permission check. Permission is always denied if in U mode and + // L is set or if in M mode and L is unset. + result = permission_check & (priv_mode ? ~csr_pmp_cfg.lock : csr_pmp_cfg.lock); + end + end + return result; + endfunction + + // Compute permissions checks that apply when MSECCFG.MML is unset. This is the original PMP + // behaviour before Smepmp was added. + function automatic logic orig_perm_check(logic pmp_cfg_lock, + logic priv_mode, + logic permission_check); + // For M-mode, any region which matches with the L-bit clear, or with sufficient + // access permissions will be allowed. + // For other modes, the lock bit doesn't matter + return priv_mode ? (permission_check) : (~pmp_cfg_lock | permission_check); + endfunction + + // Access fault determination / prioritization + function automatic logic access_fault_check(el2_mseccfg_pkt_t csr_pmp_mseccfg, + el2_pmp_type_pkt_t req_type, + logic [pt.PMP_ENTRIES-1:0] match_all, + logic any_region_enabled, + logic priv_mode, + logic [pt.PMP_ENTRIES-1:0] final_perm_check); + +`ifdef RV_USER_MODE + `ifdef RV_SMEPMP + // When MSECCFG.MMWP is set default deny always, otherwise allow for M-mode, deny for other + // modes. Also deny unmatched for M-mode when MSECCFG.MML is set and request type is EXEC. + logic access_fail = csr_pmp_mseccfg.MMWP | priv_mode | + (csr_pmp_mseccfg.MML && (req_type == EXEC)); + `else + // When in user mode and at least one PMP region is enabled deny access by default. + logic access_fail = any_region_enabled & priv_mode; + `endif +`else + logic access_fail = 1'b0; +`endif + + logic matched = 1'b0; + + // PMP entries are statically prioritized, from 0 to N-1 + // The lowest-numbered PMP entry which matches an address determines accessibility + for (int r = 0; r < pt.PMP_ENTRIES; r++) begin + if (!matched && match_all[r]) begin + access_fail = ~final_perm_check[r]; + matched = 1'b1; + end + end + return access_fail; + endfunction + + // --------------- + // Access checking + // --------------- + +`ifdef RV_USER_MODE + logic [pt.PMP_ENTRIES-1:0] region_enabled; + for (genvar r = 0; r < pt.PMP_ENTRIES; r++) begin : g_reg_ena + assign region_enabled[r] = pmp_pmpcfg[r].mode != OFF; + end + assign any_region_enabled = |region_enabled; +`endif + + for (genvar r = 0; r < pt.PMP_ENTRIES; r++) begin : g_addr_exp + assign csr_pmp_addr_i[r] = { + pmp_pmpaddr[r], 2'b00 + }; // addr conv.: word @ 32-bit -> byte @ 34-bit + // Start address for TOR matching + if (r == 0) begin : g_entry0 + assign region_start_addr[r] = (pmp_pmpcfg[r].mode == TOR) ? 34'h000000000 : csr_pmp_addr_i[r]; + end else begin : g_oth + assign region_start_addr[r] = (pmp_pmpcfg[r].mode == TOR) ? csr_pmp_addr_i[r-1] : + csr_pmp_addr_i[r]; + end + // Address mask for NA matching + for (genvar b = PMP_GRANULARITY + 2; b < 34; b++) begin : g_bitmask + if (b == 2) begin : g_bit0 + // Always mask bit 2 for NAPOT + assign region_addr_mask[r][b] = (pmp_pmpcfg[r].mode != NAPOT); + end else begin : g_others + // We will mask this bit if it is within the programmed granule + // i.e. addr = yyyy 0111 + // ^ + // | This bit pos is the top of the mask, all lower bits set + // thus mask = 1111 0000 + if (PMP_GRANULARITY == 0) begin : g_region_addr_mask_zero_granularity + assign region_addr_mask[r][b] = (pmp_pmpcfg[r].mode != NAPOT) | + ~&csr_pmp_addr_i[r][b-1:2]; + end else begin : g_region_addr_mask_other_granularity + assign region_addr_mask[r][b] = (pmp_pmpcfg[r].mode != NAPOT) | + ~&csr_pmp_addr_i[r][b-1:PMP_GRANULARITY+1]; + end + end + end + end + +`ifdef RV_USER_MODE + logic [PMP_CHANNELS-1:0] pmp_priv_mode_eff; + for (genvar c = 0; c < PMP_CHANNELS; c++) begin : g_priv_mode_eff + assign pmp_priv_mode_eff[c] = ( + ((pmp_chan_type[c] == EXEC) & priv_mode_ns) | + ((pmp_chan_type[c] != EXEC) & priv_mode_eff)); // RW affected by mstatus.MPRV + end +`endif + + for (genvar c = 0; c < PMP_CHANNELS; c++) begin : g_access_check + assign pmp_req_addr_i[c] = {2'b00, pmp_chan_addr[c]}; // addr. widening: 32-bit -> 34-bit + for (genvar r = 0; r < pt.PMP_ENTRIES; r++) begin : g_regions + // Comparators are sized according to granularity + assign region_match_eq[c][r] = (pmp_req_addr_i[c][33:PMP_GRANULARITY+2] & + region_addr_mask[r]) == + (region_start_addr[r][33:PMP_GRANULARITY+2] & + region_addr_mask[r]); + assign region_match_gt[c][r] = pmp_req_addr_i[c][33:PMP_GRANULARITY+2] > + region_start_addr[r][33:PMP_GRANULARITY+2]; + assign region_match_lt[c][r] = pmp_req_addr_i[c][33:PMP_GRANULARITY+2] < + csr_pmp_addr_i[r][33:PMP_GRANULARITY+2]; + + always_comb begin + region_match_all[c][r] = 1'b0; + unique case (pmp_pmpcfg[r].mode) + OFF: region_match_all[c][r] = 1'b0; + NA4: region_match_all[c][r] = region_match_eq[c][r]; + NAPOT: region_match_all[c][r] = region_match_eq[c][r]; + TOR: begin + region_match_all[c][r] = (region_match_eq[c][r] | region_match_gt[c][r]) & + region_match_lt[c][r]; + end + default: region_match_all[c][r] = 1'b0; + endcase + end + + // Basic permission check compares cfg register only. + assign region_basic_perm_check[c][r] = + ((pmp_chan_type[c] == EXEC) & pmp_pmpcfg[r].execute) | + ((pmp_chan_type[c] == WRITE) & pmp_pmpcfg[r].write) | + ((pmp_chan_type[c] == READ) & pmp_pmpcfg[r].read); + + // Check specific required permissions since the behaviour is different + // between Smepmp implementation and original PMP. + assign region_perm_check[c][r] = perm_check_wrapper( +`ifdef RV_SMEPMP + mseccfg, +`else + 3'b000, +`endif + pmp_pmpcfg[r], + pmp_chan_type[c], +`ifdef RV_USER_MODE + pmp_priv_mode_eff[c], +`else + 1'b0, +`endif + region_basic_perm_check[c][r] + ); + + // Address bits below PMP granularity (which starts at 4 byte) are deliberately unused. + logic unused_sigs; + assign unused_sigs = ^{region_start_addr[r][PMP_GRANULARITY+2-1:0], + pmp_req_addr_i[c][PMP_GRANULARITY+2-1:0]}; + end + + // Once the permission checks of the regions are done, decide if the access is + // denied by figuring out the matching region and its permission check. + assign pmp_chan_err[c] = access_fault_check( +`ifdef RV_SMEPMP + mseccfg, +`else + 3'b000, +`endif + pmp_chan_type[c], + region_match_all[c], +`ifdef RV_USER_MODE + any_region_enabled, + pmp_priv_mode_eff[c], +`else + 1'b0, + 1'b0, +`endif + region_perm_check[c]); + + end + +endmodule // el2_pmp diff --git a/designs/Caliptra/src/caliptra-rtl/el2_veer.sv b/designs/Caliptra/src/caliptra-rtl/el2_veer.sv new file mode 100644 index 0000000..7d21113 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/el2_veer.sv @@ -0,0 +1,1463 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2020 Western Digital Corporation or its affiliates. +// +// 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. + +//******************************************************************************** +// $Id$ +// +// Function: Top level VeeR core file +// Comments: +// +//******************************************************************************** +module el2_veer +import el2_pkg::*; +#( +`include "el2_param.vh" + ) + ( + input logic clk, + input logic rst_l, + input logic dbg_rst_l, + // rst_vec is supposed to be connected to a constant in the top level + /*pragma coverage off*/ + input logic [31:1] rst_vec, + /*pragma coverage on*/ + input logic nmi_int, + // nmi_vec is supposed to be connected to a constant in the top level + /*pragma coverage off*/ + input logic [31:1] nmi_vec, + /*pragma coverage on*/ + output logic core_rst_l, // This is "rst_l | dbg_rst_l" + + output logic active_l2clk, + output logic free_l2clk, + + output logic [31:0] trace_rv_i_insn_ip, + output logic [31:0] trace_rv_i_address_ip, + output logic trace_rv_i_valid_ip, + output logic trace_rv_i_exception_ip, + output logic [4:0] trace_rv_i_ecause_ip, + output logic trace_rv_i_interrupt_ip, + output logic [31:0] trace_rv_i_tval_ip, + + + output logic dccm_clk_override, + output logic icm_clk_override, + output logic dec_tlu_core_ecc_disable, + + // external halt/run interface + input logic i_cpu_halt_req, // Asynchronous Halt request to CPU + input logic i_cpu_run_req, // Asynchronous Restart request to CPU + output logic o_cpu_halt_ack, // Core Acknowledge to Halt request + output logic o_cpu_halt_status, // 1'b1 indicates processor is halted + output logic o_cpu_run_ack, // Core Acknowledge to run request + output logic o_debug_mode_status, // Core to the PMU that core is in debug mode. When core is in debug mode, the PMU should refrain from sendng a halt or run request + + /*pragma coverage off*/ + input logic [31:4] core_id, // CORE ID + /*pragma coverage on*/ + + // external MPC halt/run interface + input logic mpc_debug_halt_req, // Async halt request + input logic mpc_debug_run_req, // Async run request + input logic mpc_reset_run_req, // Run/halt after reset + output logic mpc_debug_halt_ack, // Halt ack + output logic mpc_debug_run_ack, // Run ack + output logic debug_brkpt_status, // debug breakpoint + + output logic dec_tlu_perfcnt0, // toggles when slot0 perf counter 0 has an event inc + output logic dec_tlu_perfcnt1, + output logic dec_tlu_perfcnt2, + output logic dec_tlu_perfcnt3, + + // DCCM ports + output logic dccm_wren, + output logic dccm_rden, + output logic [pt.DCCM_BITS-1:0] dccm_wr_addr_lo, + output logic [pt.DCCM_BITS-1:0] dccm_wr_addr_hi, + output logic [pt.DCCM_BITS-1:0] dccm_rd_addr_lo, + output logic [pt.DCCM_BITS-1:0] dccm_rd_addr_hi, + output logic [pt.DCCM_FDATA_WIDTH-1:0] dccm_wr_data_lo, + output logic [pt.DCCM_FDATA_WIDTH-1:0] dccm_wr_data_hi, + + input logic [pt.DCCM_FDATA_WIDTH-1:0] dccm_rd_data_lo, + input logic [pt.DCCM_FDATA_WIDTH-1:0] dccm_rd_data_hi, + + // ICCM ports + output logic [pt.ICCM_BITS-1:1] iccm_rw_addr, + output logic iccm_wren, + output logic iccm_rden, + output logic [2:0] iccm_wr_size, + output logic [77:0] iccm_wr_data, + output logic iccm_buf_correct_ecc, + output logic iccm_correction_state, + + input logic [63:0] iccm_rd_data, + input logic [77:0] iccm_rd_data_ecc, + + // ICache , ITAG ports + output logic [31:1] ic_rw_addr, + output logic [pt.ICACHE_NUM_WAYS-1:0] ic_tag_valid, + output logic [pt.ICACHE_NUM_WAYS-1:0] ic_wr_en, + output logic ic_rd_en, + + output logic [pt.ICACHE_BANKS_WAY-1:0][70:0] ic_wr_data, // Data to fill to the Icache. With ECC + input logic [63:0] ic_rd_data , // Data read from Icache. 2x64bits + parity bits. F2 stage. With ECC + input logic [70:0] ic_debug_rd_data , // Data read from Icache. 2x64bits + parity bits. F2 stage. With ECC + input logic [25:0] ictag_debug_rd_data,// Debug icache tag. + output logic [70:0] ic_debug_wr_data, // Debug wr cache. + + input logic [pt.ICACHE_BANKS_WAY-1:0] ic_eccerr, + input logic [pt.ICACHE_BANKS_WAY-1:0] ic_parerr, + output logic [63:0] ic_premux_data, // Premux data to be muxed with each way of the Icache. + output logic ic_sel_premux_data, // Select premux data + + + output logic [pt.ICACHE_INDEX_HI:3] ic_debug_addr, // Read/Write addresss to the Icache. + output logic ic_debug_rd_en, // Icache debug rd + output logic ic_debug_wr_en, // Icache debug wr + output logic ic_debug_tag_array, // Debug tag array + output logic [pt.ICACHE_NUM_WAYS-1:0] ic_debug_way, // Debug way. Rd or Wr. + + + + input logic [pt.ICACHE_NUM_WAYS-1:0] ic_rd_hit, + input logic ic_tag_perr, // Icache Tag parity error + + //-------------------------- LSU AXI signals-------------------------- + // AXI Write Channels + output logic lsu_axi_awvalid, + input logic lsu_axi_awready, + output logic [pt.LSU_BUS_TAG-1:0] lsu_axi_awid, + output logic [31:0] lsu_axi_awaddr, + output logic [3:0] lsu_axi_awregion, + /* exclude signals that are tied to constant value in el2_lsu_bus_buffer.sv */ + /*pragma coverage off*/ + output logic [7:0] lsu_axi_awlen, + /*pragma coverage on*/ + output logic [2:0] lsu_axi_awsize, + /* exclude signals that are tied to constant value in el2_lsu_bus_buffer.sv */ + /*pragma coverage off*/ + output logic [1:0] lsu_axi_awburst, + output logic lsu_axi_awlock, + /*pragma coverage on*/ + output logic [3:0] lsu_axi_awcache, + /* exclude signals that are tied to constant value in el2_lsu_bus_buffer.sv */ + /*pragma coverage off*/ + output logic [2:0] lsu_axi_awprot, + output logic [3:0] lsu_axi_awqos, + /*pragma coverage on*/ + + output logic lsu_axi_wvalid, + input logic lsu_axi_wready, + output logic [63:0] lsu_axi_wdata, + output logic [7:0] lsu_axi_wstrb, + output logic lsu_axi_wlast, + + input logic lsu_axi_bvalid, + /* exclude signals that are tied to constant value in el2_lsu_bus_buffer.sv */ + /*pragma coverage off*/ + output logic lsu_axi_bready, + /*pragma coverage on*/ + input logic [1:0] lsu_axi_bresp, + input logic [pt.LSU_BUS_TAG-1:0] lsu_axi_bid, + + // AXI Read Channels + output logic lsu_axi_arvalid, + input logic lsu_axi_arready, + output logic [pt.LSU_BUS_TAG-1:0] lsu_axi_arid, + output logic [31:0] lsu_axi_araddr, + output logic [3:0] lsu_axi_arregion, + /* exclude signals that are tied to constant value in el2_lsu_bus_buffer.sv */ + /*pragma coverage off*/ + output logic [7:0] lsu_axi_arlen, + /*pragma coverage on*/ + output logic [2:0] lsu_axi_arsize, + /* exclude signals that are tied to constant value in el2_lsu_bus_buffer.sv */ + /*pragma coverage off*/ + output logic [1:0] lsu_axi_arburst, + output logic lsu_axi_arlock, + /*pragma coverage on*/ + output logic [3:0] lsu_axi_arcache, + /* exclude signals that are tied to constant value in el2_lsu_bus_buffer.sv */ + /*pragma coverage off*/ + output logic [2:0] lsu_axi_arprot, + output logic [3:0] lsu_axi_arqos, + /*pragma coverage on*/ + + input logic lsu_axi_rvalid, + /* exclude signals that are tied to constant value in el2_lsu_bus_buffer.sv */ + /*pragma coverage off*/ + output logic lsu_axi_rready, + /*pragma coverage on*/ + input logic [pt.LSU_BUS_TAG-1:0] lsu_axi_rid, + input logic [63:0] lsu_axi_rdata, + input logic [1:0] lsu_axi_rresp, + input logic lsu_axi_rlast, + + //-------------------------- IFU AXI signals-------------------------- + // AXI Write Channels + /* exclude signals that are tied to constant value in el2_ifu_mem_ctl.sv + IFU does not use AXI write channel */ + /*pragma coverage off*/ + output logic ifu_axi_awvalid, + input logic ifu_axi_awready, + output logic [pt.IFU_BUS_TAG-1:0] ifu_axi_awid, + output logic [31:0] ifu_axi_awaddr, + output logic [3:0] ifu_axi_awregion, + output logic [7:0] ifu_axi_awlen, + output logic [2:0] ifu_axi_awsize, + output logic [1:0] ifu_axi_awburst, + output logic ifu_axi_awlock, + output logic [3:0] ifu_axi_awcache, + output logic [2:0] ifu_axi_awprot, + output logic [3:0] ifu_axi_awqos, + + output logic ifu_axi_wvalid, + input logic ifu_axi_wready, + output logic [63:0] ifu_axi_wdata, + output logic [7:0] ifu_axi_wstrb, + output logic ifu_axi_wlast, + + input logic ifu_axi_bvalid, + output logic ifu_axi_bready, + input logic [1:0] ifu_axi_bresp, + input logic [pt.IFU_BUS_TAG-1:0] ifu_axi_bid, + /*pragma coverage on*/ + + // AXI Read Channels + output logic ifu_axi_arvalid, + input logic ifu_axi_arready, + output logic [pt.IFU_BUS_TAG-1:0] ifu_axi_arid, + output logic [31:0] ifu_axi_araddr, + output logic [3:0] ifu_axi_arregion, + /* exclude signals that are tied to constant value in el2_ifu_mem_ctl.sv */ + /*pragma coverage off*/ + output logic [7:0] ifu_axi_arlen, + output logic [2:0] ifu_axi_arsize, + output logic [1:0] ifu_axi_arburst, + output logic ifu_axi_arlock, + output logic [3:0] ifu_axi_arcache, + output logic [2:0] ifu_axi_arprot, + output logic [3:0] ifu_axi_arqos, + /*pragma coverage on*/ + + input logic ifu_axi_rvalid, + /* exclude signals that are tied to constant value in el2_ifu_mem_ctl.sv */ + /*pragma coverage off*/ + output logic ifu_axi_rready, + /*pragma coverage on*/ + input logic [pt.IFU_BUS_TAG-1:0] ifu_axi_rid, + input logic [63:0] ifu_axi_rdata, + input logic [1:0] ifu_axi_rresp, + input logic ifu_axi_rlast, + + //-------------------------- SB AXI signals-------------------------- + // AXI Write Channels + output logic sb_axi_awvalid, + input logic sb_axi_awready, + /* exclude signals that are tied to constant value in dbg/el2_dbg.sv */ + /*pragma coverage off*/ + output logic [pt.SB_BUS_TAG-1:0] sb_axi_awid, + /*pragma coverage on*/ + output logic [31:0] sb_axi_awaddr, + output logic [3:0] sb_axi_awregion, + /* exclude signals that are tied to constant value in dbg/el2_dbg.sv */ + /*pragma coverage off*/ + output logic [7:0] sb_axi_awlen, + /*pragma coverage on*/ + output logic [2:0] sb_axi_awsize, + /* exclude signals that are tied to constant value in dbg/el2_dbg.sv */ + /*pragma coverage off*/ + output logic [1:0] sb_axi_awburst, + output logic sb_axi_awlock, + output logic [3:0] sb_axi_awcache, + output logic [2:0] sb_axi_awprot, + output logic [3:0] sb_axi_awqos, + /*pragma coverage on*/ + + output logic sb_axi_wvalid, + input logic sb_axi_wready, + output logic [63:0] sb_axi_wdata, + output logic [7:0] sb_axi_wstrb, + output logic sb_axi_wlast, + + input logic sb_axi_bvalid, + output logic sb_axi_bready, + input logic [1:0] sb_axi_bresp, + input logic [pt.SB_BUS_TAG-1:0] sb_axi_bid, + + // AXI Read Channels + output logic sb_axi_arvalid, + input logic sb_axi_arready, + /* exclude signals that are tied to constant value in dbg/el2_dbg.sv */ + /*pragma coverage off*/ + output logic [pt.SB_BUS_TAG-1:0] sb_axi_arid, + /*pragma coverage on*/ + output logic [31:0] sb_axi_araddr, + output logic [3:0] sb_axi_arregion, + /* exclude signals that are tied to constant value in dbg/el2_dbg.sv */ + /*pragma coverage off*/ + output logic [7:0] sb_axi_arlen, + /*pragma coverage on*/ + output logic [2:0] sb_axi_arsize, + /* exclude signals that are tied to constant value in dbg/el2_dbg.sv */ + /*pragma coverage off*/ + output logic [1:0] sb_axi_arburst, + output logic sb_axi_arlock, + output logic [3:0] sb_axi_arcache, + output logic [2:0] sb_axi_arprot, + output logic [3:0] sb_axi_arqos, + /*pragma coverage on*/ + + input logic sb_axi_rvalid, + /* exclude signals that are tied to constant value in dbg/el2_dbg.sv */ + /*pragma coverage off*/ + output logic sb_axi_rready, + /*pragma coverage on*/ + input logic [pt.SB_BUS_TAG-1:0] sb_axi_rid, + input logic [63:0] sb_axi_rdata, + input logic [1:0] sb_axi_rresp, + input logic sb_axi_rlast, + + //-------------------------- DMA AXI signals-------------------------- + // AXI Write Channels + input logic dma_axi_awvalid, + output logic dma_axi_awready, + input logic [pt.DMA_BUS_TAG-1:0] dma_axi_awid, + input logic [31:0] dma_axi_awaddr, + input logic [2:0] dma_axi_awsize, + input logic [2:0] dma_axi_awprot, + input logic [7:0] dma_axi_awlen, + input logic [1:0] dma_axi_awburst, + + + input logic dma_axi_wvalid, + output logic dma_axi_wready, + input logic [63:0] dma_axi_wdata, + input logic [7:0] dma_axi_wstrb, + input logic dma_axi_wlast, + + output logic dma_axi_bvalid, + input logic dma_axi_bready, + output logic [1:0] dma_axi_bresp, + output logic [pt.DMA_BUS_TAG-1:0] dma_axi_bid, + + // AXI Read Channels + input logic dma_axi_arvalid, + output logic dma_axi_arready, + input logic [pt.DMA_BUS_TAG-1:0] dma_axi_arid, + input logic [31:0] dma_axi_araddr, + input logic [2:0] dma_axi_arsize, + input logic [2:0] dma_axi_arprot, + input logic [7:0] dma_axi_arlen, + input logic [1:0] dma_axi_arburst, + + output logic dma_axi_rvalid, + input logic dma_axi_rready, + output logic [pt.DMA_BUS_TAG-1:0] dma_axi_rid, + output logic [63:0] dma_axi_rdata, + output logic [1:0] dma_axi_rresp, + output logic dma_axi_rlast, + + + //// AHB LITE BUS + output logic [31:0] haddr, + /* exclude signals that are tied to constant value in axi4_to_ahb.sv */ + /*pragma coverage off*/ + output logic [2:0] hburst, + output logic hmastlock, + /*pragma coverage on*/ + output logic [3:0] hprot, + output logic [2:0] hsize, + output logic [1:0] htrans, + output logic hwrite, + + input logic [63:0] hrdata, + input logic hready, + input logic hresp, + + // LSU AHB Master + output logic [31:0] lsu_haddr, + /* exclude signals that are tied to constant value in axi4_to_ahb.sv */ + /*pragma coverage off*/ + output logic [2:0] lsu_hburst, + output logic lsu_hmastlock, + /*pragma coverage on*/ + output logic [3:0] lsu_hprot, + output logic [2:0] lsu_hsize, + output logic [1:0] lsu_htrans, + output logic lsu_hwrite, + output logic [63:0] lsu_hwdata, + + input logic [63:0] lsu_hrdata, + input logic lsu_hready, + input logic lsu_hresp, + + //System Bus Debug Master + output logic [31:0] sb_haddr, + /* exclude signals that are tied to constant value in axi4_to_ahb.sv */ + /*pragma coverage off*/ + output logic [2:0] sb_hburst, + output logic sb_hmastlock, + /*pragma coverage on*/ + output logic [3:0] sb_hprot, + output logic [2:0] sb_hsize, + output logic [1:0] sb_htrans, + output logic sb_hwrite, + output logic [63:0] sb_hwdata, + + input logic [63:0] sb_hrdata, + input logic sb_hready, + input logic sb_hresp, + + // DMA Slave + input logic dma_hsel, + input logic [31:0] dma_haddr, + input logic [2:0] dma_hburst, + input logic dma_hmastlock, + input logic [3:0] dma_hprot, + input logic [2:0] dma_hsize, + input logic [1:0] dma_htrans, + input logic dma_hwrite, + input logic [63:0] dma_hwdata, + input logic dma_hreadyin, + + output logic [63:0] dma_hrdata, + output logic dma_hreadyout, + output logic dma_hresp, + + input logic lsu_bus_clk_en, + input logic ifu_bus_clk_en, + input logic dbg_bus_clk_en, + input logic dma_bus_clk_en, + + input logic dmi_reg_en, // read or write + input logic [6:0] dmi_reg_addr, // address of DM register + input logic dmi_reg_wr_en, // write instruction + input logic [31:0] dmi_reg_wdata, // write data + output logic [31:0] dmi_reg_rdata, + + // ICCM/DCCM ECC status + output logic iccm_ecc_single_error, + output logic iccm_ecc_double_error, + output logic dccm_ecc_single_error, + output logic dccm_ecc_double_error, + + input logic [pt.PIC_TOTAL_INT:1] extintsrc_req, + input logic timer_int, + input logic soft_int, + // Excluding scan_mode from coverage as its usage is determined by the integrator of the VeeR core. + /*pragma coverage off*/ + input logic scan_mode + /*pragma coverage on*/ +); + + + + + logic [63:0] hwdata_nc; + //---------------------------------------------------------------------- + // + //---------------------------------------------------------------------- + + logic ifu_pmu_instr_aligned; + logic ifu_ic_error_start; + logic ifu_iccm_dma_rd_ecc_single_err; + logic ifu_iccm_rd_ecc_single_err; + logic ifu_iccm_rd_ecc_double_err; + logic lsu_dccm_rd_ecc_single_err; + logic lsu_dccm_rd_ecc_double_err; + + logic lsu_axi_awready_ahb; + logic lsu_axi_wready_ahb; + logic lsu_axi_bvalid_ahb; + logic lsu_axi_bready_ahb; + logic [1:0] lsu_axi_bresp_ahb; + logic [pt.LSU_BUS_TAG-1:0] lsu_axi_bid_ahb; + logic lsu_axi_arready_ahb; + logic lsu_axi_rvalid_ahb; + logic [pt.LSU_BUS_TAG-1:0] lsu_axi_rid_ahb; + logic [63:0] lsu_axi_rdata_ahb; + logic [1:0] lsu_axi_rresp_ahb; + logic lsu_axi_rlast_ahb; + + logic lsu_axi_awready_int; + logic lsu_axi_wready_int; + logic lsu_axi_bvalid_int; + logic lsu_axi_bready_int; + logic [1:0] lsu_axi_bresp_int; + logic [pt.LSU_BUS_TAG-1:0] lsu_axi_bid_int; + logic lsu_axi_arready_int; + logic lsu_axi_rvalid_int; + logic [pt.LSU_BUS_TAG-1:0] lsu_axi_rid_int; + logic [63:0] lsu_axi_rdata_int; + logic [1:0] lsu_axi_rresp_int; + logic lsu_axi_rlast_int; + + logic ifu_axi_awready_ahb; + logic ifu_axi_wready_ahb; + logic ifu_axi_bvalid_ahb; + logic ifu_axi_bready_ahb; + logic [1:0] ifu_axi_bresp_ahb; + logic [pt.IFU_BUS_TAG-1:0] ifu_axi_bid_ahb; + logic ifu_axi_arready_ahb; + logic ifu_axi_rvalid_ahb; + logic [pt.IFU_BUS_TAG-1:0] ifu_axi_rid_ahb; + logic [63:0] ifu_axi_rdata_ahb; + logic [1:0] ifu_axi_rresp_ahb; + logic ifu_axi_rlast_ahb; + + logic ifu_axi_awready_int; + logic ifu_axi_wready_int; + logic ifu_axi_bvalid_int; + logic ifu_axi_bready_int; + logic [1:0] ifu_axi_bresp_int; + logic [pt.IFU_BUS_TAG-1:0] ifu_axi_bid_int; + logic ifu_axi_arready_int; + logic ifu_axi_rvalid_int; + logic [pt.IFU_BUS_TAG-1:0] ifu_axi_rid_int; + logic [63:0] ifu_axi_rdata_int; + logic [1:0] ifu_axi_rresp_int; + logic ifu_axi_rlast_int; + + logic sb_axi_awready_ahb; + logic sb_axi_wready_ahb; + logic sb_axi_bvalid_ahb; + logic sb_axi_bready_ahb; + logic [1:0] sb_axi_bresp_ahb; + logic [pt.SB_BUS_TAG-1:0] sb_axi_bid_ahb; + logic sb_axi_arready_ahb; + logic sb_axi_rvalid_ahb; + logic [pt.SB_BUS_TAG-1:0] sb_axi_rid_ahb; + logic [63:0] sb_axi_rdata_ahb; + logic [1:0] sb_axi_rresp_ahb; + logic sb_axi_rlast_ahb; + + logic sb_axi_awready_int; + logic sb_axi_wready_int; + logic sb_axi_bvalid_int; + logic sb_axi_bready_int; + logic [1:0] sb_axi_bresp_int; + logic [pt.SB_BUS_TAG-1:0] sb_axi_bid_int; + logic sb_axi_arready_int; + logic sb_axi_rvalid_int; + logic [pt.SB_BUS_TAG-1:0] sb_axi_rid_int; + logic [63:0] sb_axi_rdata_int; + logic [1:0] sb_axi_rresp_int; + logic sb_axi_rlast_int; + + logic dma_axi_awvalid_ahb; + /* exclude signals that are tied to constant value in ahb_to_axi4.sv */ + /*pragma coverage off*/ + logic [pt.DMA_BUS_TAG-1:0] dma_axi_awid_ahb; + /*pragma coverage on*/ + logic [31:0] dma_axi_awaddr_ahb; + logic [2:0] dma_axi_awsize_ahb; + /* exclude signals that are tied to constant value in ahb_to_axi4.sv */ + /*pragma coverage off*/ + logic [2:0] dma_axi_awprot_ahb; + logic [7:0] dma_axi_awlen_ahb; + logic [1:0] dma_axi_awburst_ahb; + /*pragma coverage on*/ + logic dma_axi_wvalid_ahb; + logic [63:0] dma_axi_wdata_ahb; + logic [7:0] dma_axi_wstrb_ahb; + /* exclude signals that are tied to constant value in ahb_to_axi4.sv */ + /*pragma coverage off*/ + logic dma_axi_wlast_ahb; + logic dma_axi_bready_ahb; + /*pragma coverage on*/ + logic dma_axi_arvalid_ahb; + /* exclude signals that are tied to constant value in ahb_to_axi4.sv */ + /*pragma coverage off*/ + logic [pt.DMA_BUS_TAG-1:0] dma_axi_arid_ahb; + /*pragma coverage on*/ + logic [31:0] dma_axi_araddr_ahb; + logic [2:0] dma_axi_arsize_ahb; + /* exclude signals that are tied to constant value in ahb_to_axi4.sv */ + /*pragma coverage off*/ + logic [2:0] dma_axi_arprot_ahb; + logic [7:0] dma_axi_arlen_ahb; + logic [1:0] dma_axi_arburst_ahb; + logic dma_axi_rready_ahb; + /*pragma coverage on*/ + + logic dma_axi_awvalid_int; + logic [pt.DMA_BUS_TAG-1:0] dma_axi_awid_int; + logic [31:0] dma_axi_awaddr_int; + logic [2:0] dma_axi_awsize_int; + logic [2:0] dma_axi_awprot_int; + logic [7:0] dma_axi_awlen_int; + logic [1:0] dma_axi_awburst_int; + logic dma_axi_wvalid_int; + logic [63:0] dma_axi_wdata_int; + logic [7:0] dma_axi_wstrb_int; + logic dma_axi_wlast_int; + logic dma_axi_bready_int; + logic dma_axi_arvalid_int; + logic [pt.DMA_BUS_TAG-1:0] dma_axi_arid_int; + logic [31:0] dma_axi_araddr_int; + logic [2:0] dma_axi_arsize_int; + logic [2:0] dma_axi_arprot_int; + logic [7:0] dma_axi_arlen_int; + logic [1:0] dma_axi_arburst_int; + logic dma_axi_rready_int; + + +// Icache debug + logic [70:0] ifu_ic_debug_rd_data; // diagnostic icache read data + logic ifu_ic_debug_rd_data_valid; // diagnostic icache read data valid + el2_cache_debug_pkt_t dec_tlu_ic_diag_pkt; // packet of DICAWICS, DICAD0/1, DICAGO info for icache diagnostics + + + logic dec_i0_rs1_en_d; + logic dec_i0_rs2_en_d; + logic [31:0] gpr_i0_rs1_d; + logic [31:0] gpr_i0_rs2_d; + + logic [31:0] dec_i0_result_r; + logic [31:0] exu_i0_result_x; + logic [31:1] exu_i0_pc_x; + logic [31:1] exu_npc_r; + + el2_alu_pkt_t i0_ap; + + // Trigger signals + el2_trigger_pkt_t [3:0] trigger_pkt_any; + logic [3:0] lsu_trigger_match_m; + + + logic [31:0] dec_i0_immed_d; + logic [12:1] dec_i0_br_immed_d; + logic dec_i0_select_pc_d; + + logic [31:1] dec_i0_pc_d; + logic [3:0] dec_i0_rs1_bypass_en_d; + logic [3:0] dec_i0_rs2_bypass_en_d; + + logic dec_i0_alu_decode_d; + logic dec_i0_branch_d; + + logic ifu_miss_state_idle; + logic dec_tlu_flush_noredir_r; + logic dec_tlu_flush_leak_one_r; + logic dec_tlu_flush_err_r; + logic ifu_i0_valid; + logic [31:0] ifu_i0_instr; + logic [31:1] ifu_i0_pc; + + logic exu_flush_final; + + logic [31:1] exu_flush_path_final; + + logic [31:0] exu_lsu_rs1_d; + logic [31:0] exu_lsu_rs2_d; + + + el2_lsu_pkt_t lsu_p; + logic dec_qual_lsu_d; + + logic dec_lsu_valid_raw_d; + logic [11:0] dec_lsu_offset_d; + + logic [31:0] lsu_result_m; + logic [31:0] lsu_result_corr_r; // This is the ECC corrected data going to RF + logic lsu_single_ecc_error_incr; // Increment the ecc counter + el2_lsu_error_pkt_t lsu_error_pkt_r; + logic lsu_imprecise_error_load_any; + logic lsu_imprecise_error_store_any; + logic [31:0] lsu_imprecise_error_addr_any; + logic lsu_load_stall_any; // This is for blocking loads + logic lsu_store_stall_any; // This is for blocking stores + logic lsu_idle_any; // doesn't include DMA + logic lsu_active; // lsu is active. used for clock + + + logic [31:1] lsu_fir_addr; // fast interrupt address + logic [1:0] lsu_fir_error; // Error during fast interrupt lookup + + // Non-blocking loads + logic lsu_nonblock_load_valid_m; + logic [pt.LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_tag_m; + logic lsu_nonblock_load_inv_r; + logic [pt.LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_inv_tag_r; + logic lsu_nonblock_load_data_valid; + logic [pt.LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_data_tag; + logic [31:0] lsu_nonblock_load_data; + + logic dec_csr_ren_d; + logic [31:0] dec_csr_rddata_d; + + logic [31:0] exu_csr_rs1_x; + + logic dec_tlu_i0_commit_cmt; + logic dec_tlu_flush_lower_r; + logic dec_tlu_flush_lower_wb; + logic dec_tlu_i0_kill_writeb_r; // I0 is flushed, don't writeback any results to arch state + logic dec_tlu_fence_i_r; // flush is a fence_i rfnpc, flush icache + + logic [31:1] dec_tlu_flush_path_r; + logic [31:0] dec_tlu_mrac_ff; // CSR for memory region control + + logic ifu_i0_pc4; + + el2_mul_pkt_t mul_p; + + el2_div_pkt_t div_p; + logic dec_div_cancel; + + logic [31:0] exu_div_result; + logic exu_div_wren; + + logic dec_i0_decode_d; + + + logic [31:1] pred_correct_npc_x; + + el2_br_tlu_pkt_t dec_tlu_br0_r_pkt; + + el2_predict_pkt_t exu_mp_pkt; + logic [pt.BHT_GHR_SIZE-1:0] exu_mp_eghr; + logic [pt.BHT_GHR_SIZE-1:0] exu_mp_fghr; + logic [pt.BTB_ADDR_HI:pt.BTB_ADDR_LO] exu_mp_index; + logic [pt.BTB_BTAG_SIZE-1:0] exu_mp_btag; + + logic [pt.BHT_GHR_SIZE-1:0] exu_i0_br_fghr_r; + logic [1:0] exu_i0_br_hist_r; + logic exu_i0_br_error_r; + logic exu_i0_br_start_error_r; + logic exu_i0_br_valid_r; + logic exu_i0_br_mp_r; + logic exu_i0_br_middle_r; + + logic exu_i0_br_way_r; + + logic [pt.BTB_ADDR_HI:pt.BTB_ADDR_LO] exu_i0_br_index_r; + + logic dma_dccm_req; + logic dma_iccm_req; + logic [2:0] dma_mem_tag; + logic [31:0] dma_mem_addr; + logic [2:0] dma_mem_sz; + logic dma_mem_write; + logic [63:0] dma_mem_wdata; + + logic dccm_dma_rvalid; + logic dccm_dma_ecc_error; + logic [2:0] dccm_dma_rtag; + logic [63:0] dccm_dma_rdata; + logic iccm_dma_rvalid; + logic iccm_dma_ecc_error; + logic [2:0] iccm_dma_rtag; + logic [63:0] iccm_dma_rdata; + + logic dma_dccm_stall_any; // Stall the ld/st in decode if asserted + logic dma_iccm_stall_any; // Stall the fetch + logic dccm_ready; + logic iccm_ready; + + logic dma_pmu_dccm_read; + logic dma_pmu_dccm_write; + logic dma_pmu_any_read; + logic dma_pmu_any_write; + + logic ifu_i0_icaf; + logic [1:0] ifu_i0_icaf_type; + + + logic ifu_i0_icaf_second; + logic ifu_i0_dbecc; + logic iccm_dma_sb_error; + + el2_br_pkt_t i0_brp; + logic [pt.BTB_ADDR_HI:pt.BTB_ADDR_LO] ifu_i0_bp_index; + logic [pt.BHT_GHR_SIZE-1:0] ifu_i0_bp_fghr; + logic [pt.BTB_BTAG_SIZE-1:0] ifu_i0_bp_btag; + + logic [$clog2(pt.BTB_SIZE)-1:0] ifu_i0_fa_index; + logic [$clog2(pt.BTB_SIZE)-1:0] dec_fa_error_index; // Fully associative btb error index + + + el2_predict_pkt_t dec_i0_predict_p_d; + + logic [pt.BHT_GHR_SIZE-1:0] i0_predict_fghr_d; // DEC predict fghr + logic [pt.BTB_ADDR_HI:pt.BTB_ADDR_LO] i0_predict_index_d; // DEC predict index + logic [pt.BTB_BTAG_SIZE-1:0] i0_predict_btag_d; // DEC predict branch tag + + // PIC ports + logic picm_wren; + logic picm_rden; + logic picm_mken; + logic [31:0] picm_rdaddr; + logic [31:0] picm_wraddr; + logic [31:0] picm_wr_data; + logic [31:0] picm_rd_data; + + // feature disable from mfdc + logic dec_tlu_external_ldfwd_disable; // disable external load forwarding + logic dec_tlu_bpred_disable; + logic dec_tlu_wb_coalescing_disable; + logic dec_tlu_sideeffect_posted_disable; + logic [2:0] dec_tlu_dma_qos_prty; // DMA QoS priority coming from MFDC [18:16] + + // clock gating overrides from mcgc + logic dec_tlu_misc_clk_override; + logic dec_tlu_ifu_clk_override; + logic dec_tlu_lsu_clk_override; + logic dec_tlu_bus_clk_override; + logic dec_tlu_pic_clk_override; + logic dec_tlu_dccm_clk_override; + logic dec_tlu_icm_clk_override; + + logic dec_tlu_picio_clk_override; + + assign dccm_clk_override = dec_tlu_dccm_clk_override; // dccm memory + assign icm_clk_override = dec_tlu_icm_clk_override; // icache/iccm memory + + // PMP Signals + el2_pmp_cfg_pkt_t pmp_pmpcfg [pt.PMP_ENTRIES]; + logic [31:0] pmp_pmpaddr [pt.PMP_ENTRIES]; + logic [31:0] pmp_chan_addr [3]; + el2_pmp_type_pkt_t pmp_chan_type [3]; + logic pmp_chan_err [3]; + + logic [31:1] ifu_pmp_addr; + logic ifu_pmp_error; + logic [31:0] lsu_pmp_addr_start; + logic lsu_pmp_error_start; + logic [31:0] lsu_pmp_addr_end; + logic lsu_pmp_error_end; + logic lsu_pmp_we; + logic lsu_pmp_re; + + // -----------------------DEBUG START ------------------------------- + + logic [31:0] dbg_cmd_addr; // the address of the debug command to used by the core + logic [31:0] dbg_cmd_wrdata; // If the debug command is a write command, this has the data to be written to the CSR/GPR + logic dbg_cmd_valid; // commad is being driven by the dbg module. One pulse. Only dirven when core_halted has been seen + logic dbg_cmd_write; // 1: write command; 0: read_command + logic [1:0] dbg_cmd_type; // 0:gpr 1:csr 2: memory + logic [1:0] dbg_cmd_size; // size of the abstract mem access debug command + logic dbg_halt_req; // Sticky signal indicating that the debug module wants to start the entering of debug mode ( start the halting sequence ) + logic dbg_resume_req; // Sticky signal indicating that the debug module wants to resume from debug mode + logic dbg_core_rst_l; // Core reset from DM + + logic core_dbg_cmd_done; // Final muxed cmd done to debug + logic core_dbg_cmd_fail; // Final muxed cmd done to debug + logic [31:0] core_dbg_rddata; // Final muxed cmd done to debug + + logic dma_dbg_cmd_done; // Abstarct memory command sent to dma is done + logic dma_dbg_cmd_fail; // Abstarct memory command sent to dma failed + logic [31:0] dma_dbg_rddata; // Read data for abstract memory access + + logic dbg_dma_bubble; // Debug needs a bubble to send a valid + logic dma_dbg_ready; // DMA is ready to accept debug request + + logic [31:0] dec_dbg_rddata; // The core drives this data ( intercepts the pipe and sends it here ) + logic dec_dbg_cmd_done; // This will be treated like a valid signal + logic dec_dbg_cmd_fail; // Abstract command failed + logic dec_tlu_mpc_halted_only; // Only halted due to MPC + logic dec_tlu_dbg_halted; // The core has finished the queiscing sequence. Sticks this signal high + logic dec_tlu_resume_ack; + logic dec_tlu_debug_mode; // Core is in debug mode + logic dec_debug_wdata_rs1_d; + logic dec_tlu_force_halt; // halt has been forced + + logic [1:0] dec_data_en; + logic [1:0] dec_ctl_en; + + // PMU Signals + logic exu_pmu_i0_br_misp; + logic exu_pmu_i0_br_ataken; + logic exu_pmu_i0_pc4; + + logic lsu_pmu_load_external_m; + logic lsu_pmu_store_external_m; + logic lsu_pmu_misaligned_m; + logic lsu_pmu_bus_trxn; + logic lsu_pmu_bus_misaligned; + logic lsu_pmu_bus_error; + logic lsu_pmu_bus_busy; + + logic ifu_pmu_fetch_stall; + logic ifu_pmu_ic_miss; + logic ifu_pmu_ic_hit; + logic ifu_pmu_bus_error; + logic ifu_pmu_bus_busy; + logic ifu_pmu_bus_trxn; + + logic active_state; + logic free_clk; + logic active_clk; + logic dec_pause_state_cg; + + logic lsu_nonblock_load_data_error; + + logic [15:0] ifu_i0_cinst; + +// fast interrupt + logic [31:2] dec_tlu_meihap; + logic dec_extint_stall; + + el2_trace_pkt_t trace_rv_trace_pkt; + + + logic lsu_fastint_stall_any; + + logic [7:0] pic_claimid; + logic [3:0] pic_pl, dec_tlu_meicurpl, dec_tlu_meipt; + logic mexintpend; + logic mhwakeup; + + logic dma_active; + + + logic pause_state; + logic halt_state; + + logic dec_tlu_core_empty; + + assign pause_state = dec_pause_state_cg & ~(dma_active | lsu_active) & dec_tlu_core_empty; + + assign halt_state = o_cpu_halt_status & ~(dma_active | lsu_active); + + + assign active_state = (~(halt_state | pause_state) | dec_tlu_flush_lower_r | dec_tlu_flush_lower_wb) | dec_tlu_misc_clk_override; + + rvoclkhdr free_cg2 ( .clk(clk), .en(1'b1), .l1clk(free_l2clk), .* ); + rvoclkhdr active_cg2 ( .clk(clk), .en(active_state), .l1clk(active_l2clk), .* ); + +// all other clock headers are 1st level + rvoclkhdr free_cg1 ( .clk(free_l2clk), .en(1'b1), .l1clk(free_clk), .* ); + rvoclkhdr active_cg1 ( .clk(active_l2clk), .en(1'b1), .l1clk(active_clk), .* ); + + + assign core_dbg_cmd_done = dma_dbg_cmd_done | dec_dbg_cmd_done; + assign core_dbg_cmd_fail = dma_dbg_cmd_fail | dec_dbg_cmd_fail; + assign core_dbg_rddata[31:0] = dma_dbg_cmd_done ? dma_dbg_rddata[31:0] : dec_dbg_rddata[31:0]; + + el2_dbg #(.pt(pt)) dbg ( + .rst_l(core_rst_l), + .clk(free_l2clk), + .clk_override(dec_tlu_misc_clk_override), + + // AXI signals + .sb_axi_awready(sb_axi_awready_int), + .sb_axi_wready(sb_axi_wready_int), + .sb_axi_bvalid(sb_axi_bvalid_int), + .sb_axi_bresp(sb_axi_bresp_int[1:0]), + + .sb_axi_arready(sb_axi_arready_int), + .sb_axi_rvalid(sb_axi_rvalid_int), + .sb_axi_rdata(sb_axi_rdata_int[63:0]), + .sb_axi_rresp(sb_axi_rresp_int[1:0]), + .* + ); + +`ifdef RV_ASSERT_ON + assert_fetch_indbghalt: assert #0 (~(ifu.ifc_fetch_req_f & dec.tlu.dbg_tlu_halted_f & ~dec.tlu.dcsr_single_step_running)) else $display("ERROR: Fetching in dBG halt!"); +`endif + + // ----------------- DEBUG END ----------------------------- + + assign core_rst_l = rst_l & (dbg_core_rst_l | scan_mode); + +`ifdef RV_USER_MODE + + // Operating privilege mode, 0 - machine, 1 - user + logic priv_mode; + // Effective privilege mode, 0 - machine, 1 - user (driven in el2_dec_tlu_ctl.sv) + logic priv_mode_eff; + // Next privilege mode + logic priv_mode_ns; + + el2_mseccfg_pkt_t mseccfg; // mseccfg CSR for PMP + +`endif + + // fetch + el2_ifu #(.pt(pt)) ifu ( + .clk(active_l2clk), + .rst_l(core_rst_l), + .dec_tlu_flush_err_wb (dec_tlu_flush_err_r ), + .dec_tlu_flush_noredir_wb (dec_tlu_flush_noredir_r ), + .dec_tlu_fence_i_wb (dec_tlu_fence_i_r ), + .dec_tlu_flush_leak_one_wb (dec_tlu_flush_leak_one_r ), + .dec_tlu_flush_lower_wb (dec_tlu_flush_lower_r ), + + // AXI signals + .ifu_axi_arready(ifu_axi_arready_int), + .ifu_axi_rvalid(ifu_axi_rvalid_int), + .ifu_axi_rid(ifu_axi_rid_int[pt.IFU_BUS_TAG-1:0]), + .ifu_axi_rdata(ifu_axi_rdata_int[63:0]), + .ifu_axi_rresp(ifu_axi_rresp_int[1:0]), + + .* + ); + + + assign iccm_ecc_single_error = ifu_iccm_rd_ecc_single_err || ifu_iccm_dma_rd_ecc_single_err; + assign iccm_ecc_double_error = ifu_iccm_rd_ecc_double_err; + + el2_dec #(.pt(pt)) dec ( + .clk(active_l2clk), + .dbg_cmd_wrdata(dbg_cmd_wrdata[1:0]), + .rst_l(core_rst_l), + .* + ); + + el2_exu #(.pt(pt)) exu ( + .clk(active_l2clk), + .rst_l(core_rst_l), + .* + ); + + el2_lsu #(.pt(pt)) lsu ( + .clk(active_l2clk), + .rst_l(core_rst_l), + .clk_override(dec_tlu_lsu_clk_override), + .dec_tlu_i0_kill_writeb_r(dec_tlu_i0_kill_writeb_r), + + // AXI signals + .lsu_axi_awready(lsu_axi_awready_int), + .lsu_axi_wready(lsu_axi_wready_int), + .lsu_axi_bvalid(lsu_axi_bvalid_int), + .lsu_axi_bid(lsu_axi_bid_int[pt.LSU_BUS_TAG-1:0]), + .lsu_axi_bresp(lsu_axi_bresp_int[1:0]), + + .lsu_axi_arready(lsu_axi_arready_int), + .lsu_axi_rvalid(lsu_axi_rvalid_int), + .lsu_axi_rid(lsu_axi_rid_int[pt.LSU_BUS_TAG-1:0]), + .lsu_axi_rdata(lsu_axi_rdata_int[63:0]), + .lsu_axi_rresp(lsu_axi_rresp_int[1:0]), + .lsu_axi_rlast(lsu_axi_rlast_int), + + .* + + ); + + assign dccm_ecc_single_error = lsu_dccm_rd_ecc_single_err; + assign dccm_ecc_double_error = lsu_dccm_rd_ecc_double_err; + + el2_pic_ctrl #(.pt(pt)) pic_ctrl_inst ( + .clk(free_l2clk), + .clk_override(dec_tlu_pic_clk_override), + .io_clk_override(dec_tlu_picio_clk_override), + .picm_mken (picm_mken), + .extintsrc_req({extintsrc_req[pt.PIC_TOTAL_INT:1],1'b0}), + .pl(pic_pl[3:0]), + .claimid(pic_claimid[7:0]), + .meicurpl(dec_tlu_meicurpl[3:0]), + .meipt(dec_tlu_meipt[3:0]), + .rst_l(core_rst_l), + .*); + + el2_dma_ctrl #(.pt(pt)) dma_ctrl ( + .clk(free_l2clk), + .rst_l(core_rst_l), + .clk_override(dec_tlu_misc_clk_override), + + // AXI signals + .dma_axi_awvalid(dma_axi_awvalid_int), + .dma_axi_awid(dma_axi_awid_int[pt.DMA_BUS_TAG-1:0]), + .dma_axi_awaddr(dma_axi_awaddr_int[31:0]), + .dma_axi_awsize(dma_axi_awsize_int[2:0]), + .dma_axi_wvalid(dma_axi_wvalid_int), + .dma_axi_wdata(dma_axi_wdata_int[63:0]), + .dma_axi_wstrb(dma_axi_wstrb_int[7:0]), + .dma_axi_bready(dma_axi_bready_int), + + .dma_axi_arvalid(dma_axi_arvalid_int), + .dma_axi_arid(dma_axi_arid_int[pt.DMA_BUS_TAG-1:0]), + .dma_axi_araddr(dma_axi_araddr_int[31:0]), + .dma_axi_arsize(dma_axi_arsize_int[2:0]), + .dma_axi_rready(dma_axi_rready_int), + + .* + ); + + assign pmp_chan_addr[0] = {ifu_pmp_addr, 1'b0}; + assign pmp_chan_type[0] = EXEC; + assign ifu_pmp_error = pmp_chan_err[0]; + assign pmp_chan_addr[1] = lsu_pmp_addr_start; + assign pmp_chan_type[1] = lsu_pmp_we ? WRITE : (lsu_pmp_re ? READ : NONE); + assign lsu_pmp_error_start = pmp_chan_err[1]; + assign pmp_chan_addr[2] = lsu_pmp_addr_end; + assign pmp_chan_type[2] = lsu_pmp_we ? WRITE : (lsu_pmp_re ? READ : NONE); + assign lsu_pmp_error_end = pmp_chan_err[2]; + + el2_pmp #( + .PMP_CHANNELS(3), + .pt(pt) + ) pmp ( + .clk (active_l2clk), + .rst_l(core_rst_l), + .* + ); + + if (pt.BUILD_AHB_LITE == 1) begin: Gen_AXI_To_AHB + + // AXI4 -> AHB Gasket for LSU + axi4_to_ahb #(.pt(pt), + .TAG(pt.LSU_BUS_TAG)) lsu_axi4_to_ahb ( + + .clk(free_l2clk), + .free_clk(free_clk), + .rst_l(core_rst_l), + .clk_override(dec_tlu_bus_clk_override), + .bus_clk_en(lsu_bus_clk_en), + .dec_tlu_force_halt(dec_tlu_force_halt), + + // AXI Write Channels + .axi_awvalid(lsu_axi_awvalid), + .axi_awready(lsu_axi_awready_ahb), + .axi_awid(lsu_axi_awid[pt.LSU_BUS_TAG-1:0]), + .axi_awaddr(lsu_axi_awaddr[31:0]), + .axi_awsize(lsu_axi_awsize[2:0]), + .axi_awprot(lsu_axi_awprot[2:0]), + + .axi_wvalid(lsu_axi_wvalid), + .axi_wready(lsu_axi_wready_ahb), + .axi_wdata(lsu_axi_wdata[63:0]), + .axi_wstrb(lsu_axi_wstrb[7:0]), + .axi_wlast(lsu_axi_wlast), + + .axi_bvalid(lsu_axi_bvalid_ahb), + .axi_bready(lsu_axi_bready), + .axi_bresp(lsu_axi_bresp_ahb[1:0]), + .axi_bid(lsu_axi_bid_ahb[pt.LSU_BUS_TAG-1:0]), + + // AXI Read Channels + .axi_arvalid(lsu_axi_arvalid), + .axi_arready(lsu_axi_arready_ahb), + .axi_arid(lsu_axi_arid[pt.LSU_BUS_TAG-1:0]), + .axi_araddr(lsu_axi_araddr[31:0]), + .axi_arsize(lsu_axi_arsize[2:0]), + .axi_arprot(lsu_axi_arprot[2:0]), + + .axi_rvalid(lsu_axi_rvalid_ahb), + .axi_rready(lsu_axi_rready), + .axi_rid(lsu_axi_rid_ahb[pt.LSU_BUS_TAG-1:0]), + .axi_rdata(lsu_axi_rdata_ahb[63:0]), + .axi_rresp(lsu_axi_rresp_ahb[1:0]), + .axi_rlast(lsu_axi_rlast_ahb), + + // AHB-LITE signals + .ahb_haddr(lsu_haddr[31:0]), + .ahb_hburst(lsu_hburst), + .ahb_hmastlock(lsu_hmastlock), + .ahb_hprot(lsu_hprot[3:0]), + .ahb_hsize(lsu_hsize[2:0]), + .ahb_htrans(lsu_htrans[1:0]), + .ahb_hwrite(lsu_hwrite), + .ahb_hwdata(lsu_hwdata[63:0]), + + .ahb_hrdata(lsu_hrdata[63:0]), + .ahb_hready(lsu_hready), + .ahb_hresp(lsu_hresp), + + .* + ); + + axi4_to_ahb #(.pt(pt), + .TAG(pt.IFU_BUS_TAG)) ifu_axi4_to_ahb ( + .clk(free_l2clk), + .free_clk(free_clk), + .rst_l(core_rst_l), + .clk_override(dec_tlu_bus_clk_override), + .bus_clk_en(ifu_bus_clk_en), + .dec_tlu_force_halt(dec_tlu_force_halt), + + // AHB-Lite signals + .ahb_haddr(haddr[31:0]), + .ahb_hburst(hburst), + .ahb_hmastlock(hmastlock), + .ahb_hprot(hprot[3:0]), + .ahb_hsize(hsize[2:0]), + .ahb_htrans(htrans[1:0]), + .ahb_hwrite(hwrite), + .ahb_hwdata(hwdata_nc[63:0]), + + .ahb_hrdata(hrdata[63:0]), + .ahb_hready(hready), + .ahb_hresp(hresp), + + // AXI Write Channels + .axi_awvalid(ifu_axi_awvalid), + .axi_awready(ifu_axi_awready_ahb), + .axi_awid(ifu_axi_awid[pt.IFU_BUS_TAG-1:0]), + .axi_awaddr(ifu_axi_awaddr[31:0]), + .axi_awsize(ifu_axi_awsize[2:0]), + .axi_awprot(ifu_axi_awprot[2:0]), + + .axi_wvalid(ifu_axi_wvalid), + .axi_wready(ifu_axi_wready_ahb), + .axi_wdata(ifu_axi_wdata[63:0]), + .axi_wstrb(ifu_axi_wstrb[7:0]), + .axi_wlast(ifu_axi_wlast), + + .axi_bvalid(ifu_axi_bvalid_ahb), + .axi_bready(1'b1), + .axi_bresp(ifu_axi_bresp_ahb[1:0]), + .axi_bid(ifu_axi_bid_ahb[pt.IFU_BUS_TAG-1:0]), + + // AXI Read Channels + .axi_arvalid(ifu_axi_arvalid), + .axi_arready(ifu_axi_arready_ahb), + .axi_arid(ifu_axi_arid[pt.IFU_BUS_TAG-1:0]), + .axi_araddr(ifu_axi_araddr[31:0]), + .axi_arsize(ifu_axi_arsize[2:0]), + .axi_arprot(ifu_axi_arprot[2:0]), + + .axi_rvalid(ifu_axi_rvalid_ahb), + .axi_rready(ifu_axi_rready), + .axi_rid(ifu_axi_rid_ahb[pt.IFU_BUS_TAG-1:0]), + .axi_rdata(ifu_axi_rdata_ahb[63:0]), + .axi_rresp(ifu_axi_rresp_ahb[1:0]), + .axi_rlast(ifu_axi_rlast_ahb), + .* + ); + + // AXI4 -> AHB Gasket for System Bus + axi4_to_ahb #(.pt(pt), + .TAG(pt.SB_BUS_TAG)) sb_axi4_to_ahb ( + .clk(free_l2clk), + .free_clk(free_clk), + .rst_l(dbg_rst_l), + .clk_override(dec_tlu_bus_clk_override), + .bus_clk_en(dbg_bus_clk_en), + .dec_tlu_force_halt(1'b0), + + // AXI Write Channels + .axi_awvalid(sb_axi_awvalid), + .axi_awready(sb_axi_awready_ahb), + .axi_awid(sb_axi_awid[pt.SB_BUS_TAG-1:0]), + .axi_awaddr(sb_axi_awaddr[31:0]), + .axi_awsize(sb_axi_awsize[2:0]), + .axi_awprot(sb_axi_awprot[2:0]), + + .axi_wvalid(sb_axi_wvalid), + .axi_wready(sb_axi_wready_ahb), + .axi_wdata(sb_axi_wdata[63:0]), + .axi_wstrb(sb_axi_wstrb[7:0]), + .axi_wlast(sb_axi_wlast), + + .axi_bvalid(sb_axi_bvalid_ahb), + .axi_bready(sb_axi_bready), + .axi_bresp(sb_axi_bresp_ahb[1:0]), + .axi_bid(sb_axi_bid_ahb[pt.SB_BUS_TAG-1:0]), + + // AXI Read Channels + .axi_arvalid(sb_axi_arvalid), + .axi_arready(sb_axi_arready_ahb), + .axi_arid(sb_axi_arid[pt.SB_BUS_TAG-1:0]), + .axi_araddr(sb_axi_araddr[31:0]), + .axi_arsize(sb_axi_arsize[2:0]), + .axi_arprot(sb_axi_arprot[2:0]), + + .axi_rvalid(sb_axi_rvalid_ahb), + .axi_rready(sb_axi_rready), + .axi_rid(sb_axi_rid_ahb[pt.SB_BUS_TAG-1:0]), + .axi_rdata(sb_axi_rdata_ahb[63:0]), + .axi_rresp(sb_axi_rresp_ahb[1:0]), + .axi_rlast(sb_axi_rlast_ahb), + // AHB-LITE signals + .ahb_haddr(sb_haddr[31:0]), + .ahb_hburst(sb_hburst), + .ahb_hmastlock(sb_hmastlock), + .ahb_hprot(sb_hprot[3:0]), + .ahb_hsize(sb_hsize[2:0]), + .ahb_htrans(sb_htrans[1:0]), + .ahb_hwrite(sb_hwrite), + .ahb_hwdata(sb_hwdata[63:0]), + + .ahb_hrdata(sb_hrdata[63:0]), + .ahb_hready(sb_hready), + .ahb_hresp(sb_hresp), + + .* + ); + + //AHB -> AXI4 Gasket for DMA + ahb_to_axi4 #(.pt(pt), + .TAG(pt.DMA_BUS_TAG)) dma_ahb_to_axi4 ( + .clk(free_l2clk), + .rst_l(core_rst_l), + .clk_override(dec_tlu_bus_clk_override), + .bus_clk_en(dma_bus_clk_en), + + // AXI Write Channels + .axi_awvalid(dma_axi_awvalid_ahb), + .axi_awready(dma_axi_awready), + .axi_awid(dma_axi_awid_ahb[pt.DMA_BUS_TAG-1:0]), + .axi_awaddr(dma_axi_awaddr_ahb[31:0]), + .axi_awsize(dma_axi_awsize_ahb[2:0]), + .axi_awprot(dma_axi_awprot_ahb[2:0]), + .axi_awlen(dma_axi_awlen_ahb[7:0]), + .axi_awburst(dma_axi_awburst_ahb[1:0]), + + .axi_wvalid(dma_axi_wvalid_ahb), + .axi_wready(dma_axi_wready), + .axi_wdata(dma_axi_wdata_ahb[63:0]), + .axi_wstrb(dma_axi_wstrb_ahb[7:0]), + .axi_wlast(dma_axi_wlast_ahb), + + .axi_bvalid(dma_axi_bvalid), + .axi_bready(dma_axi_bready_ahb), + .axi_bresp(dma_axi_bresp[1:0]), + .axi_bid(dma_axi_bid[pt.DMA_BUS_TAG-1:0]), + + // AXI Read Channels + .axi_arvalid(dma_axi_arvalid_ahb), + .axi_arready(dma_axi_arready), + .axi_arid(dma_axi_arid_ahb[pt.DMA_BUS_TAG-1:0]), + .axi_araddr(dma_axi_araddr_ahb[31:0]), + .axi_arsize(dma_axi_arsize_ahb[2:0]), + .axi_arprot(dma_axi_arprot_ahb[2:0]), + .axi_arlen(dma_axi_arlen_ahb[7:0]), + .axi_arburst(dma_axi_arburst_ahb[1:0]), + + .axi_rvalid(dma_axi_rvalid), + .axi_rready(dma_axi_rready_ahb), + .axi_rid(dma_axi_rid[pt.DMA_BUS_TAG-1:0]), + .axi_rdata(dma_axi_rdata[63:0]), + .axi_rresp(dma_axi_rresp[1:0]), + + // AHB signals + .ahb_haddr(dma_haddr[31:0]), + .ahb_hburst(dma_hburst), + .ahb_hmastlock(dma_hmastlock), + .ahb_hprot(dma_hprot[3:0]), + .ahb_hsize(dma_hsize[2:0]), + .ahb_htrans(dma_htrans[1:0]), + .ahb_hwrite(dma_hwrite), + .ahb_hwdata(dma_hwdata[63:0]), + + .ahb_hrdata(dma_hrdata[63:0]), + .ahb_hreadyout(dma_hreadyout), + .ahb_hresp(dma_hresp), + .ahb_hreadyin(dma_hreadyin), + .ahb_hsel(dma_hsel), + .* + ); + + end + + // Drive the final AXI inputs + assign lsu_axi_awready_int = pt.BUILD_AHB_LITE ? lsu_axi_awready_ahb : lsu_axi_awready; + assign lsu_axi_wready_int = pt.BUILD_AHB_LITE ? lsu_axi_wready_ahb : lsu_axi_wready; + assign lsu_axi_bvalid_int = pt.BUILD_AHB_LITE ? lsu_axi_bvalid_ahb : lsu_axi_bvalid; + assign lsu_axi_bready_int = pt.BUILD_AHB_LITE ? lsu_axi_bready_ahb : lsu_axi_bready; + assign lsu_axi_bresp_int[1:0] = pt.BUILD_AHB_LITE ? lsu_axi_bresp_ahb[1:0] : lsu_axi_bresp[1:0]; + assign lsu_axi_bid_int[pt.LSU_BUS_TAG-1:0] = pt.BUILD_AHB_LITE ? lsu_axi_bid_ahb[pt.LSU_BUS_TAG-1:0] : lsu_axi_bid[pt.LSU_BUS_TAG-1:0]; + assign lsu_axi_arready_int = pt.BUILD_AHB_LITE ? lsu_axi_arready_ahb : lsu_axi_arready; + assign lsu_axi_rvalid_int = pt.BUILD_AHB_LITE ? lsu_axi_rvalid_ahb : lsu_axi_rvalid; + assign lsu_axi_rid_int[pt.LSU_BUS_TAG-1:0] = pt.BUILD_AHB_LITE ? lsu_axi_rid_ahb[pt.LSU_BUS_TAG-1:0] : lsu_axi_rid[pt.LSU_BUS_TAG-1:0]; + assign lsu_axi_rdata_int[63:0] = pt.BUILD_AHB_LITE ? lsu_axi_rdata_ahb[63:0] : lsu_axi_rdata[63:0]; + assign lsu_axi_rresp_int[1:0] = pt.BUILD_AHB_LITE ? lsu_axi_rresp_ahb[1:0] : lsu_axi_rresp[1:0]; + assign lsu_axi_rlast_int = pt.BUILD_AHB_LITE ? lsu_axi_rlast_ahb : lsu_axi_rlast; + + assign ifu_axi_awready_int = pt.BUILD_AHB_LITE ? ifu_axi_awready_ahb : ifu_axi_awready; + assign ifu_axi_wready_int = pt.BUILD_AHB_LITE ? ifu_axi_wready_ahb : ifu_axi_wready; + assign ifu_axi_bvalid_int = pt.BUILD_AHB_LITE ? ifu_axi_bvalid_ahb : ifu_axi_bvalid; + assign ifu_axi_bready_int = pt.BUILD_AHB_LITE ? ifu_axi_bready_ahb : ifu_axi_bready; + assign ifu_axi_bresp_int[1:0] = pt.BUILD_AHB_LITE ? ifu_axi_bresp_ahb[1:0] : ifu_axi_bresp[1:0]; + assign ifu_axi_bid_int[pt.IFU_BUS_TAG-1:0] = pt.BUILD_AHB_LITE ? ifu_axi_bid_ahb[pt.IFU_BUS_TAG-1:0] : ifu_axi_bid[pt.IFU_BUS_TAG-1:0]; + assign ifu_axi_arready_int = pt.BUILD_AHB_LITE ? ifu_axi_arready_ahb : ifu_axi_arready; + assign ifu_axi_rvalid_int = pt.BUILD_AHB_LITE ? ifu_axi_rvalid_ahb : ifu_axi_rvalid; + assign ifu_axi_rid_int[pt.IFU_BUS_TAG-1:0] = pt.BUILD_AHB_LITE ? ifu_axi_rid_ahb[pt.IFU_BUS_TAG-1:0] : ifu_axi_rid[pt.IFU_BUS_TAG-1:0]; + assign ifu_axi_rdata_int[63:0] = pt.BUILD_AHB_LITE ? ifu_axi_rdata_ahb[63:0] : ifu_axi_rdata[63:0]; + assign ifu_axi_rresp_int[1:0] = pt.BUILD_AHB_LITE ? ifu_axi_rresp_ahb[1:0] : ifu_axi_rresp[1:0]; + assign ifu_axi_rlast_int = pt.BUILD_AHB_LITE ? ifu_axi_rlast_ahb : ifu_axi_rlast; + + assign sb_axi_awready_int = pt.BUILD_AHB_LITE ? sb_axi_awready_ahb : sb_axi_awready; + assign sb_axi_wready_int = pt.BUILD_AHB_LITE ? sb_axi_wready_ahb : sb_axi_wready; + assign sb_axi_bvalid_int = pt.BUILD_AHB_LITE ? sb_axi_bvalid_ahb : sb_axi_bvalid; + assign sb_axi_bready_int = pt.BUILD_AHB_LITE ? sb_axi_bready_ahb : sb_axi_bready; + assign sb_axi_bresp_int[1:0] = pt.BUILD_AHB_LITE ? sb_axi_bresp_ahb[1:0] : sb_axi_bresp[1:0]; + assign sb_axi_bid_int[pt.SB_BUS_TAG-1:0] = pt.BUILD_AHB_LITE ? sb_axi_bid_ahb[pt.SB_BUS_TAG-1:0] : sb_axi_bid[pt.SB_BUS_TAG-1:0]; + assign sb_axi_arready_int = pt.BUILD_AHB_LITE ? sb_axi_arready_ahb : sb_axi_arready; + assign sb_axi_rvalid_int = pt.BUILD_AHB_LITE ? sb_axi_rvalid_ahb : sb_axi_rvalid; + assign sb_axi_rid_int[pt.SB_BUS_TAG-1:0] = pt.BUILD_AHB_LITE ? sb_axi_rid_ahb[pt.SB_BUS_TAG-1:0] : sb_axi_rid[pt.SB_BUS_TAG-1:0]; + assign sb_axi_rdata_int[63:0] = pt.BUILD_AHB_LITE ? sb_axi_rdata_ahb[63:0] : sb_axi_rdata[63:0]; + assign sb_axi_rresp_int[1:0] = pt.BUILD_AHB_LITE ? sb_axi_rresp_ahb[1:0] : sb_axi_rresp[1:0]; + assign sb_axi_rlast_int = pt.BUILD_AHB_LITE ? sb_axi_rlast_ahb : sb_axi_rlast; + + assign dma_axi_awvalid_int = pt.BUILD_AHB_LITE ? dma_axi_awvalid_ahb : dma_axi_awvalid; + assign dma_axi_awid_int[pt.DMA_BUS_TAG-1:0] = pt.BUILD_AHB_LITE ? dma_axi_awid_ahb[pt.DMA_BUS_TAG-1:0] : dma_axi_awid[pt.DMA_BUS_TAG-1:0]; + assign dma_axi_awaddr_int[31:0] = pt.BUILD_AHB_LITE ? dma_axi_awaddr_ahb[31:0] : dma_axi_awaddr[31:0]; + assign dma_axi_awsize_int[2:0] = pt.BUILD_AHB_LITE ? dma_axi_awsize_ahb[2:0] : dma_axi_awsize[2:0]; + assign dma_axi_awprot_int[2:0] = pt.BUILD_AHB_LITE ? dma_axi_awprot_ahb[2:0] : dma_axi_awprot[2:0]; + assign dma_axi_awlen_int[7:0] = pt.BUILD_AHB_LITE ? dma_axi_awlen_ahb[7:0] : dma_axi_awlen[7:0]; + assign dma_axi_awburst_int[1:0] = pt.BUILD_AHB_LITE ? dma_axi_awburst_ahb[1:0] : dma_axi_awburst[1:0]; + assign dma_axi_wvalid_int = pt.BUILD_AHB_LITE ? dma_axi_wvalid_ahb : dma_axi_wvalid; + assign dma_axi_wdata_int[63:0] = pt.BUILD_AHB_LITE ? dma_axi_wdata_ahb[63:0] : dma_axi_wdata; + assign dma_axi_wstrb_int[7:0] = pt.BUILD_AHB_LITE ? dma_axi_wstrb_ahb[7:0] : dma_axi_wstrb[7:0]; + assign dma_axi_wlast_int = pt.BUILD_AHB_LITE ? dma_axi_wlast_ahb : dma_axi_wlast; + assign dma_axi_bready_int = pt.BUILD_AHB_LITE ? dma_axi_bready_ahb : dma_axi_bready; + assign dma_axi_arvalid_int = pt.BUILD_AHB_LITE ? dma_axi_arvalid_ahb : dma_axi_arvalid; + assign dma_axi_arid_int[pt.DMA_BUS_TAG-1:0] = pt.BUILD_AHB_LITE ? dma_axi_arid_ahb[pt.DMA_BUS_TAG-1:0] : dma_axi_arid[pt.DMA_BUS_TAG-1:0]; + assign dma_axi_araddr_int[31:0] = pt.BUILD_AHB_LITE ? dma_axi_araddr_ahb[31:0] : dma_axi_araddr[31:0]; + assign dma_axi_arsize_int[2:0] = pt.BUILD_AHB_LITE ? dma_axi_arsize_ahb[2:0] : dma_axi_arsize[2:0]; + assign dma_axi_arprot_int[2:0] = pt.BUILD_AHB_LITE ? dma_axi_arprot_ahb[2:0] : dma_axi_arprot[2:0]; + assign dma_axi_arlen_int[7:0] = pt.BUILD_AHB_LITE ? dma_axi_arlen_ahb[7:0] : dma_axi_arlen[7:0]; + assign dma_axi_arburst_int[1:0] = pt.BUILD_AHB_LITE ? dma_axi_arburst_ahb[1:0] : dma_axi_arburst[1:0]; + assign dma_axi_rready_int = pt.BUILD_AHB_LITE ? dma_axi_rready_ahb : dma_axi_rready; + + +if (pt.BUILD_AHB_LITE == 1) begin +`ifdef RV_ASSERT_ON + property ahb_trxn_aligned; + @(posedge clk) disable iff(~rst_l) (lsu_htrans[1:0] != 2'b0) |-> ((lsu_hsize[2:0] == 3'h0) | + ((lsu_hsize[2:0] == 3'h1) & (lsu_haddr[0] == 1'b0)) | + ((lsu_hsize[2:0] == 3'h2) & (lsu_haddr[1:0] == 2'b0)) | + ((lsu_hsize[2:0] == 3'h3) & (lsu_haddr[2:0] == 3'b0))); + endproperty + assert_ahb_trxn_aligned: assert property (ahb_trxn_aligned) else + $display("Assertion ahb_trxn_aligned failed: lsu_htrans=2'h%h, lsu_hsize=3'h%h, lsu_haddr=32'h%h",lsu_htrans[1:0], lsu_hsize[2:0], lsu_haddr[31:0]); + + property dma_trxn_aligned; + @(posedge clk) disable iff(~rst_l) (dma_htrans[1:0] != 2'b0) |-> ((dma_hsize[2:0] == 3'h0) | + ((dma_hsize[2:0] == 3'h1) & (dma_haddr[0] == 1'b0)) | + ((dma_hsize[2:0] == 3'h2) & (dma_haddr[1:0] == 2'b0)) | + ((dma_hsize[2:0] == 3'h3) & (dma_haddr[2:0] == 3'b0))); + endproperty + + +`endif + end // if (pt.BUILD_AHB_LITE == 1) + + + // unpack packet + // also need retires_p==3 + + assign trace_rv_i_insn_ip[31:0] = trace_rv_trace_pkt.trace_rv_i_insn_ip[31:0]; + + assign trace_rv_i_address_ip[31:0] = trace_rv_trace_pkt.trace_rv_i_address_ip[31:0]; + + assign trace_rv_i_valid_ip = trace_rv_trace_pkt.trace_rv_i_valid_ip; + + assign trace_rv_i_exception_ip = trace_rv_trace_pkt.trace_rv_i_exception_ip; + + assign trace_rv_i_ecause_ip[4:0] = trace_rv_trace_pkt.trace_rv_i_ecause_ip[4:0]; + + assign trace_rv_i_interrupt_ip = trace_rv_trace_pkt.trace_rv_i_interrupt_ip; + + assign trace_rv_i_tval_ip[31:0] = trace_rv_trace_pkt.trace_rv_i_tval_ip[31:0]; + + + +endmodule // el2_veer + diff --git a/designs/Caliptra/src/caliptra-rtl/el2_veer_wrapper.sv b/designs/Caliptra/src/caliptra-rtl/el2_veer_wrapper.sv new file mode 100644 index 0000000..ec23996 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/el2_veer_wrapper.sv @@ -0,0 +1,942 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2020 Western Digital Corporation or its affiliates. +// Copyright (c) 2023 Antmicro +// +// 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. + +//******************************************************************************** +// $Id$ +// +// Function: Top wrapper file with el2_veer/mem instantiated inside +// Comments: +// +//******************************************************************************** +module el2_veer_wrapper +import el2_pkg::*; + #( +`include "el2_param.vh" +) +( + input logic clk, + input logic rst_l, + input logic dbg_rst_l, + // rst_vec is supposed to be tied to constant in the top level + /*pragma coverage off*/ + input logic [31:1] rst_vec, + /*pragma coverage on*/ + input logic nmi_int, + // nmi_vec is supposed to be tied to constants in the top level + /*pragma coverage off*/ + input logic [31:1] nmi_vec, + /*pragma coverage on*/ + + + output logic [31:0] trace_rv_i_insn_ip, + output logic [31:0] trace_rv_i_address_ip, + output logic trace_rv_i_valid_ip, + output logic trace_rv_i_exception_ip, + output logic [4:0] trace_rv_i_ecause_ip, + output logic trace_rv_i_interrupt_ip, + output logic [31:0] trace_rv_i_tval_ip, + + // Bus signals +`ifdef RV_BUILD_AXI4 + //-------------------------- LSU AXI signals-------------------------- + // AXI Write Channels + output logic lsu_axi_awvalid, + input logic lsu_axi_awready, + output logic [pt.LSU_BUS_TAG-1:0] lsu_axi_awid, + output logic [31:0] lsu_axi_awaddr, + output logic [3:0] lsu_axi_awregion, + /* exclude signals that are tied to constant value in el2_lsu_bus_buffer.sv */ + /*pragma coverage off*/ + output logic [7:0] lsu_axi_awlen, + /*pragma coverage on*/ + output logic [2:0] lsu_axi_awsize, + /* exclude signals that are tied to constant value in el2_lsu_bus_buffer.sv */ + /*pragma coverage off*/ + output logic [1:0] lsu_axi_awburst, + output logic lsu_axi_awlock, + /*pragma coverage on*/ + output logic [3:0] lsu_axi_awcache, + /* exclude signals that are tied to constant value in el2_lsu_bus_buffer.sv */ + /*pragma coverage off*/ + output logic [2:0] lsu_axi_awprot, + output logic [3:0] lsu_axi_awqos, + /*pragma coverage on*/ + + output logic lsu_axi_wvalid, + input logic lsu_axi_wready, + output logic [63:0] lsu_axi_wdata, + output logic [7:0] lsu_axi_wstrb, + output logic lsu_axi_wlast, + + input logic lsu_axi_bvalid, + /* exclude signals that are tied to constant value in el2_lsu_bus_buffer.sv */ + /*pragma coverage off*/ + output logic lsu_axi_bready, + /*pragma coverage on*/ + input logic [1:0] lsu_axi_bresp, + input logic [pt.LSU_BUS_TAG-1:0] lsu_axi_bid, + + // AXI Read Channels + output logic lsu_axi_arvalid, + input logic lsu_axi_arready, + output logic [pt.LSU_BUS_TAG-1:0] lsu_axi_arid, + output logic [31:0] lsu_axi_araddr, + output logic [3:0] lsu_axi_arregion, + /* exclude signals that are tied to constant value in el2_lsu_bus_buffer.sv */ + /*pragma coverage off*/ + output logic [7:0] lsu_axi_arlen, + /*pragma coverage on*/ + output logic [2:0] lsu_axi_arsize, + /* exclude signals that are tied to constant value in el2_lsu_bus_buffer.sv */ + /*pragma coverage off*/ + output logic [1:0] lsu_axi_arburst, + output logic lsu_axi_arlock, + /*pragma coverage on*/ + output logic [3:0] lsu_axi_arcache, + /* exclude signals that are tied to constant value in el2_lsu_bus_buffer.sv */ + /*pragma coverage off*/ + output logic [2:0] lsu_axi_arprot, + output logic [3:0] lsu_axi_arqos, + /*pragma coverage on*/ + + input logic lsu_axi_rvalid, + /* exclude signals that are tied to constant value in el2_lsu_bus_buffer.sv */ + /*pragma coverage off*/ + output logic lsu_axi_rready, + /*pragma coverage on*/ + input logic [pt.LSU_BUS_TAG-1:0] lsu_axi_rid, + input logic [63:0] lsu_axi_rdata, + input logic [1:0] lsu_axi_rresp, + input logic lsu_axi_rlast, + + //-------------------------- IFU AXI signals-------------------------- + // AXI Write Channels + /* exclude signals that are tied to constant value in el2_ifu_mem_ctl.sv + IFU does not use AXI write channel */ + /*pragma coverage off*/ + output logic ifu_axi_awvalid, + input logic ifu_axi_awready, + output logic [pt.IFU_BUS_TAG-1:0] ifu_axi_awid, + output logic [31:0] ifu_axi_awaddr, + output logic [3:0] ifu_axi_awregion, + output logic [7:0] ifu_axi_awlen, + output logic [2:0] ifu_axi_awsize, + output logic [1:0] ifu_axi_awburst, + output logic ifu_axi_awlock, + output logic [3:0] ifu_axi_awcache, + output logic [2:0] ifu_axi_awprot, + output logic [3:0] ifu_axi_awqos, + + output logic ifu_axi_wvalid, + input logic ifu_axi_wready, + output logic [63:0] ifu_axi_wdata, + output logic [7:0] ifu_axi_wstrb, + output logic ifu_axi_wlast, + + input logic ifu_axi_bvalid, + output logic ifu_axi_bready, + input logic [1:0] ifu_axi_bresp, + input logic [pt.IFU_BUS_TAG-1:0] ifu_axi_bid, + /*pragma coverage on*/ + + // AXI Read Channels + output logic ifu_axi_arvalid, + input logic ifu_axi_arready, + output logic [pt.IFU_BUS_TAG-1:0] ifu_axi_arid, + output logic [31:0] ifu_axi_araddr, + output logic [3:0] ifu_axi_arregion, + /* exclude signals that are tied to constant value in el2_ifu_mem_ctl.sv */ + /*pragma coverage off*/ + output logic [7:0] ifu_axi_arlen, + output logic [2:0] ifu_axi_arsize, + output logic [1:0] ifu_axi_arburst, + output logic ifu_axi_arlock, + output logic [3:0] ifu_axi_arcache, + output logic [2:0] ifu_axi_arprot, + output logic [3:0] ifu_axi_arqos, + /*pragma coverage on*/ + + input logic ifu_axi_rvalid, + /* exclude signals that are tied to constant value in el2_ifu_mem_ctl.sv */ + /*pragma coverage off*/ + output logic ifu_axi_rready, + /*pragma coverage on*/ + input logic [pt.IFU_BUS_TAG-1:0] ifu_axi_rid, + input logic [63:0] ifu_axi_rdata, + input logic [1:0] ifu_axi_rresp, + input logic ifu_axi_rlast, + + //-------------------------- SB AXI signals-------------------------- + // AXI Write Channels + output logic sb_axi_awvalid, + input logic sb_axi_awready, + /* exclude signals that are tied to constant value in dbg/el2_dbg.sv */ + /*pragma coverage off*/ + output logic [pt.SB_BUS_TAG-1:0] sb_axi_awid, + /*pragma coverage on*/ + output logic [31:0] sb_axi_awaddr, + output logic [3:0] sb_axi_awregion, + /* exclude signals that are tied to constant value in dbg/el2_dbg.sv */ + /*pragma coverage off*/ + output logic [7:0] sb_axi_awlen, + /*pragma coverage on*/ + output logic [2:0] sb_axi_awsize, + /* exclude signals that are tied to constant value in dbg/el2_dbg.sv */ + /*pragma coverage off*/ + output logic [1:0] sb_axi_awburst, + output logic sb_axi_awlock, + output logic [3:0] sb_axi_awcache, + output logic [2:0] sb_axi_awprot, + output logic [3:0] sb_axi_awqos, + /*pragma coverage on*/ + + output logic sb_axi_wvalid, + input logic sb_axi_wready, + output logic [63:0] sb_axi_wdata, + output logic [7:0] sb_axi_wstrb, + output logic sb_axi_wlast, + + input logic sb_axi_bvalid, + output logic sb_axi_bready, + input logic [1:0] sb_axi_bresp, + input logic [pt.SB_BUS_TAG-1:0] sb_axi_bid, + + // AXI Read Channels + output logic sb_axi_arvalid, + input logic sb_axi_arready, + /* exclude signals that are tied to constant value in dbg/el2_dbg.sv */ + /*pragma coverage off*/ + output logic [pt.SB_BUS_TAG-1:0] sb_axi_arid, + /*pragma coverage on*/ + output logic [31:0] sb_axi_araddr, + output logic [3:0] sb_axi_arregion, + /* exclude signals that are tied to constant value in dbg/el2_dbg.sv */ + /*pragma coverage off*/ + output logic [7:0] sb_axi_arlen, + /*pragma coverage on*/ + output logic [2:0] sb_axi_arsize, + /* exclude signals that are tied to constant value in dbg/el2_dbg.sv */ + /*pragma coverage off*/ + output logic [1:0] sb_axi_arburst, + output logic sb_axi_arlock, + output logic [3:0] sb_axi_arcache, + output logic [2:0] sb_axi_arprot, + output logic [3:0] sb_axi_arqos, + /*pragma coverage on*/ + + input logic sb_axi_rvalid, + /* exclude signals that are tied to constant value in dbg/el2_dbg.sv */ + /*pragma coverage off*/ + output logic sb_axi_rready, + /*pragma coverage on*/ + input logic [pt.SB_BUS_TAG-1:0] sb_axi_rid, + input logic [63:0] sb_axi_rdata, + input logic [1:0] sb_axi_rresp, + input logic sb_axi_rlast, + + //-------------------------- DMA AXI signals-------------------------- + // AXI Write Channels + input logic dma_axi_awvalid, + output logic dma_axi_awready, + /* exclude signals that are tied to constant value in tb_top.sv */ + /*pragma coverage off*/ + input logic [pt.DMA_BUS_TAG-1:0] dma_axi_awid, + /*pragma coverage on*/ + input logic [31:0] dma_axi_awaddr, + input logic [2:0] dma_axi_awsize, + input logic [2:0] dma_axi_awprot, + input logic [7:0] dma_axi_awlen, + input logic [1:0] dma_axi_awburst, + + + input logic dma_axi_wvalid, + output logic dma_axi_wready, + input logic [63:0] dma_axi_wdata, + input logic [7:0] dma_axi_wstrb, + input logic dma_axi_wlast, + + output logic dma_axi_bvalid, + input logic dma_axi_bready, + output logic [1:0] dma_axi_bresp, + output logic [pt.DMA_BUS_TAG-1:0] dma_axi_bid, + + // AXI Read Channels + input logic dma_axi_arvalid, + output logic dma_axi_arready, + /* exclude signals that are tied to constant value in tb_top.sv */ + /*pragma coverage off*/ + input logic [pt.DMA_BUS_TAG-1:0] dma_axi_arid, + /*pragma coverage on*/ + input logic [31:0] dma_axi_araddr, + input logic [2:0] dma_axi_arsize, + input logic [2:0] dma_axi_arprot, + input logic [7:0] dma_axi_arlen, + input logic [1:0] dma_axi_arburst, + + output logic dma_axi_rvalid, + input logic dma_axi_rready, + output logic [pt.DMA_BUS_TAG-1:0] dma_axi_rid, + output logic [63:0] dma_axi_rdata, + output logic [1:0] dma_axi_rresp, + output logic dma_axi_rlast, +`endif + +`ifdef RV_BUILD_AHB_LITE + //// AHB LITE BUS + output logic [31:0] haddr, + /* exclude signals that are tied to constant value in axi4_to_ahb.sv */ + /*pragma coverage off*/ + output logic [2:0] hburst, + output logic hmastlock, + /*pragma coverage on*/ + output logic [3:0] hprot, + output logic [2:0] hsize, + output logic [1:0] htrans, + output logic hwrite, + + /* exclude signals that are tied to constant value in this file */ + /*pragma coverage off*/ + input logic [63:0] hrdata, + input logic hready, + input logic hresp, + /*pragma coverage on*/ + + // LSU AHB Master + output logic [31:0] lsu_haddr, + /* exclude signals that are tied to constant value in axi4_to_ahb.sv */ + /*pragma coverage off*/ + output logic [2:0] lsu_hburst, + output logic lsu_hmastlock, + /*pragma coverage on*/ + output logic [3:0] lsu_hprot, + output logic [2:0] lsu_hsize, + output logic [1:0] lsu_htrans, + output logic lsu_hwrite, + output logic [63:0] lsu_hwdata, + + /* exclude signals that are tied to constant value in this file */ + /*pragma coverage off*/ + input logic [63:0] lsu_hrdata, + input logic lsu_hready, + input logic lsu_hresp, + /*pragma coverage on*/ + // Debug Syster Bus AHB + output logic [31:0] sb_haddr, + /* exclude signals that are tied to constant value in axi4_to_ahb.sv */ + /*pragma coverage off*/ + output logic [2:0] sb_hburst, + output logic sb_hmastlock, + /*pragma coverage on*/ + output logic [3:0] sb_hprot, + output logic [2:0] sb_hsize, + output logic [1:0] sb_htrans, + output logic sb_hwrite, + output logic [63:0] sb_hwdata, + + /* exclude signals that are tied to constant value in this file */ + /*pragma coverage off*/ + input logic [63:0] sb_hrdata, + input logic sb_hready, + input logic sb_hresp, + /*pragma coverage on*/ + + // DMA Slave + /* exclude signals that are tied to constant value in tb_top.sv */ + /*pragma coverage off*/ + input logic dma_hsel, + input logic [31:0] dma_haddr, + input logic [2:0] dma_hburst, + input logic dma_hmastlock, + input logic [3:0] dma_hprot, + input logic [2:0] dma_hsize, + input logic [1:0] dma_htrans, + input logic dma_hwrite, + input logic [63:0] dma_hwdata, + /*pragma coverage on*/ + input logic dma_hreadyin, + + output logic [63:0] dma_hrdata, + output logic dma_hreadyout, + output logic dma_hresp, +`endif + // clk ratio signals + input logic lsu_bus_clk_en, // Clock ratio b/w cpu core clk & AHB master interface + input logic ifu_bus_clk_en, // Clock ratio b/w cpu core clk & AHB master interface + input logic dbg_bus_clk_en, // Clock ratio b/w cpu core clk & AHB master interface + input logic dma_bus_clk_en, // Clock ratio b/w cpu core clk & AHB slave interface + + // ICCM/DCCM ECC status + output logic iccm_ecc_single_error, + output logic iccm_ecc_double_error, + output logic dccm_ecc_single_error, + output logic dccm_ecc_double_error, + + // ICache export interface + el2_mem_if.veer_icache_src el2_icache_export, + + input logic timer_int, + input logic soft_int, + input logic [pt.PIC_TOTAL_INT:1] extintsrc_req, + + output logic dec_tlu_perfcnt0, // toggles when slot0 perf counter 0 has an event inc + output logic dec_tlu_perfcnt1, + output logic dec_tlu_perfcnt2, + output logic dec_tlu_perfcnt3, + + // ports added by the soc team + input logic jtag_tck, // JTAG clk + input logic jtag_tms, // JTAG TMS + input logic jtag_tdi, // JTAG tdi + input logic jtag_trst_n, // JTAG Reset + output logic jtag_tdo, // JTAG TDO + output logic jtag_tdoEn, // JTAG Test Data Output enable + + /*pragma coverage off*/ + input logic [31:4] core_id, + /*pragma coverage on*/ + + // Memory Export Interface + el2_mem_if.veer_sram_src el2_mem_export, + + // external MPC halt/run interface + input logic mpc_debug_halt_req, // Async halt request + input logic mpc_debug_run_req, // Async run request + input logic mpc_reset_run_req, // Run/halt after reset + output logic mpc_debug_halt_ack, // Halt ack + output logic mpc_debug_run_ack, // Run ack + output logic debug_brkpt_status, // debug breakpoint + + input logic i_cpu_halt_req, // Async halt req to CPU + output logic o_cpu_halt_ack, // core response to halt + output logic o_cpu_halt_status, // 1'b1 indicates core is halted + output logic o_debug_mode_status, // Core to the PMU that core is in debug mode. When core is in debug mode, the PMU should refrain from sendng a halt or run request + input logic i_cpu_run_req, // Async restart req to CPU + output logic o_cpu_run_ack, // Core response to run req + + // Excluding scan_mode and mbist_mode from coverage as their usage is determined by the integrator of the VeeR core. + /* pragma coverage off */ + input logic scan_mode, // To enable scan mode + input logic mbist_mode, // to enable mbist + + // DMI port for uncore + input logic dmi_core_enable, + input logic dmi_uncore_enable, + output logic dmi_uncore_en, + output logic dmi_uncore_wr_en, + output logic [ 6:0] dmi_uncore_addr, + output logic [31:0] dmi_uncore_wdata, + input logic [31:0] dmi_uncore_rdata, + output logic dmi_active + /* pragma coverage on */ +); + + logic active_l2clk; + logic free_l2clk; + + // DCCM ports + logic dccm_wren; + logic dccm_rden; + logic [pt.DCCM_BITS-1:0] dccm_wr_addr_lo; + logic [pt.DCCM_BITS-1:0] dccm_wr_addr_hi; + logic [pt.DCCM_BITS-1:0] dccm_rd_addr_lo; + logic [pt.DCCM_BITS-1:0] dccm_rd_addr_hi; + logic [pt.DCCM_FDATA_WIDTH-1:0] dccm_wr_data_lo; + logic [pt.DCCM_FDATA_WIDTH-1:0] dccm_wr_data_hi; + + logic [pt.DCCM_FDATA_WIDTH-1:0] dccm_rd_data_lo; + logic [pt.DCCM_FDATA_WIDTH-1:0] dccm_rd_data_hi; + + // PIC ports + + // Icache & Itag ports + logic [31:1] ic_rw_addr; + logic [pt.ICACHE_NUM_WAYS-1:0] ic_wr_en ; // Which way to write + logic ic_rd_en ; + + + logic [pt.ICACHE_NUM_WAYS-1:0] ic_tag_valid; // Valid from the I$ tag valid outside (in flops). + + logic [pt.ICACHE_NUM_WAYS-1:0] ic_rd_hit; // ic_rd_hit[3:0] + logic ic_tag_perr; // Ic tag parity error + + logic [pt.ICACHE_INDEX_HI:3] ic_debug_addr; // Read/Write addresss to the Icache. + logic ic_debug_rd_en; // Icache debug rd + logic ic_debug_wr_en; // Icache debug wr + logic ic_debug_tag_array; // Debug tag array + logic [pt.ICACHE_NUM_WAYS-1:0] ic_debug_way; // Debug way. Rd or Wr. + + logic [25:0] ictag_debug_rd_data; // Debug icache tag. + logic [pt.ICACHE_BANKS_WAY-1:0][70:0] ic_wr_data; + logic [63:0] ic_rd_data; + logic [70:0] ic_debug_rd_data; // Data read from Icache. 2x64bits + parity bits. F2 stage. With ECC + logic [70:0] ic_debug_wr_data; // Debug wr cache. + + logic [pt.ICACHE_BANKS_WAY-1:0] ic_eccerr; // ecc error per bank + logic [pt.ICACHE_BANKS_WAY-1:0] ic_parerr; // parity error per bank + + logic [63:0] ic_premux_data; + logic ic_sel_premux_data; + + // ICCM ports + logic [pt.ICCM_BITS-1:1] iccm_rw_addr; + logic iccm_wren; + logic iccm_rden; + logic [2:0] iccm_wr_size; + logic [77:0] iccm_wr_data; + logic iccm_buf_correct_ecc; + logic iccm_correction_state; + + logic [63:0] iccm_rd_data; + logic [77:0] iccm_rd_data_ecc; + + logic core_rst_l; // Core reset including rst_l and dbg_rst_l + + logic dccm_clk_override; + logic icm_clk_override; + logic dec_tlu_core_ecc_disable; + + + // zero out the signals not presented at the wrapper instantiation level +`ifdef RV_BUILD_AXI4 + // Since all the signals in this block are tied to constant, we exclude this from coverage analysis + /*pragma coverage off*/ + + //// AHB LITE BUS + logic [31:0] haddr; + logic [2:0] hburst; + logic hmastlock; + logic [3:0] hprot; + logic [2:0] hsize; + logic [1:0] htrans; + logic hwrite; + + logic [63:0] hrdata; + logic hready; + logic hresp; + + // LSU AHB Master + logic [31:0] lsu_haddr; + logic [2:0] lsu_hburst; + logic lsu_hmastlock; + logic [3:0] lsu_hprot; + logic [2:0] lsu_hsize; + logic [1:0] lsu_htrans; + logic lsu_hwrite; + logic [63:0] lsu_hwdata; + + logic [63:0] lsu_hrdata; + logic lsu_hready; + logic lsu_hresp; + // Debug Syster Bus AHB + logic [31:0] sb_haddr; + logic [2:0] sb_hburst; + logic sb_hmastlock; + logic [3:0] sb_hprot; + logic [2:0] sb_hsize; + logic [1:0] sb_htrans; + logic sb_hwrite; + logic [63:0] sb_hwdata; + + logic [63:0] sb_hrdata; + logic sb_hready; + logic sb_hresp; + + // DMA Slave + logic dma_hsel; + logic [31:0] dma_haddr; + logic [2:0] dma_hburst; + logic dma_hmastlock; + logic [3:0] dma_hprot; + logic [2:0] dma_hsize; + logic [1:0] dma_htrans; + logic dma_hwrite; + logic [63:0] dma_hwdata; + logic dma_hreadyin; + + logic [63:0] dma_hrdata; + logic dma_hreadyout; + logic dma_hresp; + + + + // AHB + assign hrdata[63:0] = '0; + assign hready = '0; + assign hresp = '0; + // LSU + assign lsu_hrdata[63:0] = '0; + assign lsu_hready = '0; + assign lsu_hresp = '0; + // Debu + assign sb_hrdata[63:0] = '0; + assign sb_hready = '0; + assign sb_hresp = '0; + + // DMA + assign dma_hsel = '0; + assign dma_haddr[31:0] = '0; + assign dma_hburst[2:0] = '0; + assign dma_hmastlock = '0; + assign dma_hprot[3:0] = '0; + assign dma_hsize[2:0] = '0; + assign dma_htrans[1:0] = '0; + assign dma_hwrite = '0; + assign dma_hwdata[63:0] = '0; + assign dma_hreadyin = '0; + + /*pragma coverage on*/ + +`endif // `ifdef RV_BUILD_AXI4 + + +`ifdef RV_BUILD_AHB_LITE + // Since all the signals in this block are tied to constant, we exclude this from coverage analysis + /*pragma coverage off*/ + wire lsu_axi_awvalid; + wire lsu_axi_awready; + wire [pt.LSU_BUS_TAG-1:0] lsu_axi_awid; + wire [31:0] lsu_axi_awaddr; + wire [3:0] lsu_axi_awregion; + wire [7:0] lsu_axi_awlen; + wire [2:0] lsu_axi_awsize; + wire [1:0] lsu_axi_awburst; + wire lsu_axi_awlock; + wire [3:0] lsu_axi_awcache; + wire [2:0] lsu_axi_awprot; + wire [3:0] lsu_axi_awqos; + + + wire lsu_axi_wvalid; + wire lsu_axi_wready; + wire [63:0] lsu_axi_wdata; + wire [7:0] lsu_axi_wstrb; + wire lsu_axi_wlast; + + wire lsu_axi_bvalid; + wire lsu_axi_bready; + wire [1:0] lsu_axi_bresp; + wire [pt.LSU_BUS_TAG-1:0] lsu_axi_bid; + + // AXI Read Channels + wire lsu_axi_arvalid; + wire lsu_axi_arready; + wire [pt.LSU_BUS_TAG-1:0] lsu_axi_arid; + wire [31:0] lsu_axi_araddr; + wire [3:0] lsu_axi_arregion; + wire [7:0] lsu_axi_arlen; + wire [2:0] lsu_axi_arsize; + wire [1:0] lsu_axi_arburst; + wire lsu_axi_arlock; + wire [3:0] lsu_axi_arcache; + wire [2:0] lsu_axi_arprot; + wire [3:0] lsu_axi_arqos; + + wire lsu_axi_rvalid; + wire lsu_axi_rready; + wire [pt.LSU_BUS_TAG-1:0] lsu_axi_rid; + wire [63:0] lsu_axi_rdata; + wire [1:0] lsu_axi_rresp; + wire lsu_axi_rlast; + + assign lsu_axi_awready = '0; + assign lsu_axi_wready = '0; + assign lsu_axi_bvalid = '0; + assign lsu_axi_bresp = '0; + assign lsu_axi_bid = {pt.LSU_BUS_TAG{1'b0}}; + assign lsu_axi_arready = '0; + assign lsu_axi_rvalid = '0; + assign lsu_axi_rid = {pt.LSU_BUS_TAG{1'b0}}; + assign lsu_axi_rdata = '0; + assign lsu_axi_rresp = '0; + assign lsu_axi_rlast = '0; + //-------------------------- IFU AXI signals-------------------------- + // AXI Write Channels + wire ifu_axi_awvalid; + wire ifu_axi_awready; + wire [pt.IFU_BUS_TAG-1:0] ifu_axi_awid; + wire [31:0] ifu_axi_awaddr; + wire [3:0] ifu_axi_awregion; + wire [7:0] ifu_axi_awlen; + wire [2:0] ifu_axi_awsize; + wire [1:0] ifu_axi_awburst; + wire ifu_axi_awlock; + wire [3:0] ifu_axi_awcache; + wire [2:0] ifu_axi_awprot; + wire [3:0] ifu_axi_awqos; + + wire ifu_axi_wvalid; + wire ifu_axi_wready; + wire [63:0] ifu_axi_wdata; + wire [7:0] ifu_axi_wstrb; + wire ifu_axi_wlast; + + wire ifu_axi_bvalid; + wire ifu_axi_bready; + wire [1:0] ifu_axi_bresp; + wire [pt.IFU_BUS_TAG-1:0] ifu_axi_bid; + + // AXI Read Channels + wire ifu_axi_arvalid; + wire ifu_axi_arready; + wire [pt.IFU_BUS_TAG-1:0] ifu_axi_arid; + wire [31:0] ifu_axi_araddr; + wire [3:0] ifu_axi_arregion; + wire [7:0] ifu_axi_arlen; + wire [2:0] ifu_axi_arsize; + wire [1:0] ifu_axi_arburst; + wire ifu_axi_arlock; + wire [3:0] ifu_axi_arcache; + wire [2:0] ifu_axi_arprot; + wire [3:0] ifu_axi_arqos; + + wire ifu_axi_rvalid; + wire ifu_axi_rready; + wire [pt.IFU_BUS_TAG-1:0] ifu_axi_rid; + wire [63:0] ifu_axi_rdata; + wire [1:0] ifu_axi_rresp; + wire ifu_axi_rlast; + + assign ifu_axi_bvalid = '0; + assign ifu_axi_bresp = '0; + assign ifu_axi_bid = {pt.IFU_BUS_TAG{1'b0}}; + assign ifu_axi_arready = '0; + assign ifu_axi_rvalid = '0; + assign ifu_axi_rid = {pt.IFU_BUS_TAG{1'b0}}; + assign ifu_axi_rdata = 0; + assign ifu_axi_rresp = '0; + assign ifu_axi_rlast = '0; + //-------------------------- SB AXI signals-------------------------- + // AXI Write Channels + wire sb_axi_awvalid; + wire sb_axi_awready; + wire [pt.SB_BUS_TAG-1:0] sb_axi_awid; + wire [31:0] sb_axi_awaddr; + wire [3:0] sb_axi_awregion; + wire [7:0] sb_axi_awlen; + wire [2:0] sb_axi_awsize; + wire [1:0] sb_axi_awburst; + wire sb_axi_awlock; + wire [3:0] sb_axi_awcache; + wire [2:0] sb_axi_awprot; + wire [3:0] sb_axi_awqos; + + wire sb_axi_wvalid; + wire sb_axi_wready; + wire [63:0] sb_axi_wdata; + wire [7:0] sb_axi_wstrb; + wire sb_axi_wlast; + + wire sb_axi_bvalid; + wire sb_axi_bready; + wire [1:0] sb_axi_bresp; + wire [pt.SB_BUS_TAG-1:0] sb_axi_bid; + + // AXI Read Channels + wire sb_axi_arvalid; + wire sb_axi_arready; + wire [pt.SB_BUS_TAG-1:0] sb_axi_arid; + wire [31:0] sb_axi_araddr; + wire [3:0] sb_axi_arregion; + wire [7:0] sb_axi_arlen; + wire [2:0] sb_axi_arsize; + wire [1:0] sb_axi_arburst; + wire sb_axi_arlock; + wire [3:0] sb_axi_arcache; + wire [2:0] sb_axi_arprot; + wire [3:0] sb_axi_arqos; + + wire sb_axi_rvalid; + wire sb_axi_rready; + wire [pt.SB_BUS_TAG-1:0] sb_axi_rid; + wire [63:0] sb_axi_rdata; + wire [1:0] sb_axi_rresp; + wire sb_axi_rlast; + + assign sb_axi_awready = '0; + assign sb_axi_wready = '0; + assign sb_axi_bvalid = '0; + assign sb_axi_bresp = '0; + assign sb_axi_bid = {pt.SB_BUS_TAG{1'b0}}; + assign sb_axi_arready = '0; + assign sb_axi_rvalid = '0; + assign sb_axi_rid = {pt.SB_BUS_TAG{1'b0}}; + assign sb_axi_rdata = '0; + assign sb_axi_rresp = '0; + assign sb_axi_rlast = '0; + //-------------------------- DMA AXI signals-------------------------- + // AXI Write Channels + wire dma_axi_awvalid; + wire dma_axi_awready; + wire [pt.DMA_BUS_TAG-1:0] dma_axi_awid; + wire [31:0] dma_axi_awaddr; + wire [2:0] dma_axi_awsize; + wire [2:0] dma_axi_awprot; + wire [7:0] dma_axi_awlen; + wire [1:0] dma_axi_awburst; + + + wire dma_axi_wvalid; + wire dma_axi_wready; + wire [63:0] dma_axi_wdata; + wire [7:0] dma_axi_wstrb; + wire dma_axi_wlast; + + assign dma_axi_awvalid = 1'b0; + assign dma_axi_awid = {pt.DMA_BUS_TAG{1'b0}}; + assign dma_axi_awaddr = 32'd0; + assign dma_axi_awsize = 3'd0; + assign dma_axi_awprot = 3'd0; + assign dma_axi_awlen = 8'd0; + assign dma_axi_awburst = 2'd0; + + + assign dma_axi_wvalid = 1'b0; + assign dma_axi_wdata = 64'd0; + assign dma_axi_wstrb = 8'd0; + assign dma_axi_wlast = 1'b0; + + + wire dma_axi_bvalid; + wire dma_axi_bready; + wire [1:0] dma_axi_bresp; + wire [pt.DMA_BUS_TAG-1:0] dma_axi_bid; + + assign dma_axi_bready = 1'b0; + // AXI Read Channels + wire dma_axi_arvalid; + wire dma_axi_arready; + wire [pt.DMA_BUS_TAG-1:0] dma_axi_arid; + wire [31:0] dma_axi_araddr; + wire [2:0] dma_axi_arsize; + wire [2:0] dma_axi_arprot; + wire [7:0] dma_axi_arlen; + wire [1:0] dma_axi_arburst; + + assign dma_axi_arvalid = 1'b0; + assign dma_axi_arid = {pt.DMA_BUS_TAG{1'b0}}; + assign dma_axi_araddr = 32'd0; + assign dma_axi_arsize = 3'd0; + assign dma_axi_arprot = 3'd0; + assign dma_axi_arlen = 8'd0; + assign dma_axi_arburst = 2'd0; + + + + wire dma_axi_rvalid; + wire dma_axi_rready; + wire [pt.DMA_BUS_TAG-1:0] dma_axi_rid; + wire [63:0] dma_axi_rdata; + wire [1:0] dma_axi_rresp; + wire dma_axi_rlast; + + assign dma_axi_rready = 1'b0; + // AXI + assign ifu_axi_awready = 1'b1; + assign ifu_axi_wready = 1'b1; + assign ifu_axi_bvalid = '0; + assign ifu_axi_bresp[1:0] = '0; + assign ifu_axi_bid[pt.IFU_BUS_TAG-1:0] = '0; + + /*pragma coverage on*/ + +`endif // `ifdef RV_BUILD_AHB_LITE + + // DMI (core) + logic dmi_en; + logic [6:0] dmi_addr; + logic dmi_wr_en; + logic [31:0] dmi_wdata; + logic [31:0] dmi_rdata; + + // DMI (core) + logic dmi_reg_en; + logic [6:0] dmi_reg_addr; + logic dmi_reg_wr_en; + logic [31:0] dmi_reg_wdata; + logic [31:0] dmi_reg_rdata; + + // Instantiate the el2_veer core + el2_veer #(.pt(pt)) veer ( + .clk(clk), + .* + ); + + // Instantiate the mem + el2_mem #(.pt(pt)) mem ( + .clk(active_l2clk), + .rst_l(core_rst_l), + .mem_export(el2_mem_export), + .icache_export(el2_icache_export), + .* + ); + + + logic unused_dmi_hard_reset; + // JTAG/DMI instance + dmi_wrapper dmi_wrapper ( + // JTAG signals + .trst_n (jtag_trst_n), // JTAG reset + .tck (jtag_tck), // JTAG clock + .tms (jtag_tms), // Test mode select + .tdi (jtag_tdi), // Test Data Input + .tdo (jtag_tdo), // Test Data Output + .tdoEnable (jtag_tdoEn), // Test Data Output enable + // Processor Signals + .core_rst_n (dbg_rst_l), // Debug reset, active low + .core_clk (clk), // Core clock + .rd_data (dmi_rdata), // Read data from Processor + .reg_wr_data (dmi_wdata), // Write data to Processor + .reg_wr_addr (dmi_addr), // Write address to Processor + .reg_en (dmi_en), // Write interface bit to Processor + .reg_wr_en (dmi_wr_en), // Write enable to Processor + .dmi_hard_reset (unused_dmi_hard_reset) + ); + + // DMI core/uncore mux + dmi_mux dmi_mux ( + .core_enable (dmi_core_enable), + .uncore_enable (dmi_uncore_enable), + + .dmi_en (dmi_en), + .dmi_wr_en (dmi_wr_en), + .dmi_addr (dmi_addr), + .dmi_wdata (dmi_wdata), + .dmi_rdata (dmi_rdata), + + .dmi_core_en (dmi_reg_en), + .dmi_core_wr_en (dmi_reg_wr_en), + .dmi_core_addr (dmi_reg_addr), + .dmi_core_wdata (dmi_reg_wdata), + .dmi_core_rdata (dmi_reg_rdata), + + .dmi_uncore_en (dmi_uncore_en), + .dmi_uncore_wr_en (dmi_uncore_wr_en), + .dmi_uncore_addr (dmi_uncore_addr), + .dmi_uncore_wdata (dmi_uncore_wdata), + .dmi_uncore_rdata (dmi_uncore_rdata) + ); + + always_comb dmi_active = dmi_en; + +`ifdef RV_ASSERT_ON + // to avoid internal assertions failure at time 0 + initial begin + $assertoff(0, veer); + @(negedge clk) $asserton(0, veer); + end +`endif + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/entropy_src.sv b/designs/Caliptra/src/caliptra-rtl/entropy_src.sv new file mode 100644 index 0000000..92b721f --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/entropy_src.sv @@ -0,0 +1,461 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Description: entropy_src top level wrapper file + +`include "caliptra_prim_assert.sv" + + +module entropy_src + import entropy_src_pkg::*; + import entropy_src_reg_pkg::*; + import caliptra_prim_mubi_pkg::mubi8_t; +#( + parameter bit Stub = 1'b0, + parameter logic [NumAlerts-1:0] AlertAsyncOn = {NumAlerts{1'b1}}, + parameter int EsFifoDepth = 3, + parameter int DistrFifoDepth = 2, + parameter AHBDataWidth = 64, + parameter AHBAddrWidth = 32 +) ( + input logic clk_i, + input logic rst_ni, + + // AMBA AHB Lite Interface + input logic [AHBAddrWidth-1:0] haddr_i, + input logic [AHBDataWidth-1:0] hwdata_i, + input logic hsel_i, + input logic hwrite_i, + input logic hready_i, + input logic [1:0] htrans_i, + input logic [2:0] hsize_i, + + output logic hresp_o, + output logic hreadyout_o, + output logic [AHBDataWidth-1:0] hrdata_o, + + // OTP Interface + // SEC_CM: INTERSIG.MUBI + input mubi8_t otp_en_entropy_src_fw_read_i, + // SEC_CM: INTERSIG.MUBI + input mubi8_t otp_en_entropy_src_fw_over_i, + + // RNG Interface + output logic rng_fips_o, + + // Entropy Interface + input entropy_src_hw_if_req_t entropy_src_hw_if_i, + output entropy_src_hw_if_rsp_t entropy_src_hw_if_o, + + // RNG Interface + output entropy_src_rng_req_t entropy_src_rng_o, + input entropy_src_rng_rsp_t entropy_src_rng_i, + + // CSRNG Interface + output cs_aes_halt_req_t cs_aes_halt_o, + input cs_aes_halt_rsp_t cs_aes_halt_i, + + // External Health Test Interface + output entropy_src_xht_req_t entropy_src_xht_o, + input entropy_src_xht_rsp_t entropy_src_xht_i, + + // Alerts + input caliptra_prim_alert_pkg::alert_rx_t [NumAlerts-1:0] alert_rx_i, + output caliptra_prim_alert_pkg::alert_tx_t [NumAlerts-1:0] alert_tx_o, + + // Interrupts + output logic intr_es_entropy_valid_o, + output logic intr_es_health_test_failed_o, + output logic intr_es_observe_fifo_ready_o, + output logic intr_es_fatal_err_o +); + + localparam int RngBusWidth = 4; // AST RNG bus width + localparam int NumBins = 2**RngBusWidth; // bucket health test bin count + + // common signals + entropy_src_hw2reg_t hw2reg; + entropy_src_reg2hw_t reg2hw; + logic [NumAlerts-1:0] alert_test; + logic [NumAlerts-1:0] alert; + + // core signals + logic core_rst_n; + entropy_src_hw2reg_t core_hw2reg; + entropy_src_hw_if_rsp_t core_entropy_hw_if; + entropy_src_rng_req_t core_rng; + cs_aes_halt_req_t core_aes_halt; + entropy_src_xht_req_t core_xht; + logic core_intr_es_entropy_valid; + logic core_intr_es_health_test_failed; + logic core_intr_es_observe_fifo_ready; + logic core_intr_es_fatal_err; + logic [NumAlerts-1:0] core_alert_test; + logic [NumAlerts-1:0] core_alert; + + //stub signals + localparam int StubLfsrWidth = 64; + localparam int Copies = CSRNG_BUS_WIDTH / StubLfsrWidth; + entropy_src_hw2reg_t stub_hw2reg; + entropy_src_hw_if_rsp_t stub_entropy_hw_if; + logic stub_es_valid; + logic [NumAlerts-1:0] stub_alert_test; + logic [NumAlerts-1:0] stub_alert; + logic [StubLfsrWidth-1:0] stub_lfsr_value; + + /////////////////////////// + // Selecting between core and stub + /////////////////////////// + + assign hw2reg = Stub ? stub_hw2reg : core_hw2reg; + assign core_rst_n = Stub ? '0 : rst_ni; + assign entropy_src_hw_if_o = Stub ? stub_entropy_hw_if : core_entropy_hw_if; + assign entropy_src_rng_o = Stub ? '1 : core_rng; + assign cs_aes_halt_o = Stub ? '0 : core_aes_halt; + assign entropy_src_xht_o = Stub ? '0 : core_xht; + assign intr_es_entropy_valid_o = Stub ? stub_es_valid : core_intr_es_entropy_valid; + assign intr_es_health_test_failed_o = Stub ? '0 : core_intr_es_health_test_failed; + assign intr_es_observe_fifo_ready_o = Stub ? '0 : core_intr_es_observe_fifo_ready; + assign intr_es_fatal_err_o = Stub ? '0 : core_intr_es_fatal_err; + assign alert_test = Stub ? stub_alert_test : core_alert_test; + assign alert = Stub ? stub_alert : core_alert; + + /////////////////////////// + // core entropy operation + /////////////////////////// + + logic [NumAlerts-1:0] intg_err_alert; + assign intg_err_alert[0] = 1'b0; + + // SEC_CM: CONFIG.REGWEN + // SEC_CM: TILE_LINK.BUS.INTEGRITY + + entropy_src_reg_top #( + .AHBDataWidth(AHBDataWidth), + .AHBAddrWidth(AHBAddrWidth) + ) u_reg ( + .clk_i, + .rst_ni, + .haddr_i, + .hwdata_i, + .hsel_i, + .hwrite_i, + .hready_i, + .htrans_i, + .hsize_i, + .hresp_o, + .hreadyout_o, + .hrdata_o, + .reg2hw, + .hw2reg(hw2reg), + .intg_err_o(intg_err_alert[1]) // Assign this alert to the fatal alert index. + ); + + entropy_src_core #( + .EsFifoDepth(EsFifoDepth), + .DistrFifoDepth(DistrFifoDepth) + ) u_entropy_src_core ( + .clk_i, + .rst_ni(core_rst_n), + .reg2hw, + .hw2reg(core_hw2reg), + + .otp_en_entropy_src_fw_read_i(otp_en_entropy_src_fw_read_i), + .otp_en_entropy_src_fw_over_i(otp_en_entropy_src_fw_over_i), + .rng_fips_o, + + .entropy_src_hw_if_o(core_entropy_hw_if), + .entropy_src_hw_if_i, + + .entropy_src_xht_o(core_xht), + .entropy_src_xht_i, + + .entropy_src_rng_o(core_rng), + .entropy_src_rng_i, + + .cs_aes_halt_o(core_aes_halt), + .cs_aes_halt_i, + + .recov_alert_o(core_alert[0]), + .fatal_alert_o(core_alert[1]), + + .recov_alert_test_o(core_alert_test[0]), + .fatal_alert_test_o(core_alert_test[1]), + + .intr_es_entropy_valid_o(core_intr_es_entropy_valid), + .intr_es_health_test_failed_o(core_intr_es_health_test_failed), + .intr_es_observe_fifo_ready_o(core_intr_es_observe_fifo_ready), + .intr_es_fatal_err_o(core_intr_es_fatal_err) + ); + + /////////////////////////// + // stub entropy operation + /////////////////////////// + + assign stub_alert = '0; + assign stub_alert_test = '0; + assign stub_entropy_hw_if = '{ + es_ack: '1, + es_bits: {Copies{stub_lfsr_value}}, + es_fips: '1 + }; + // once enabled, stub entropy is always available + + import caliptra_prim_mubi_pkg::mubi4_t; + import caliptra_prim_mubi_pkg::mubi4_test_true_strict; + + mubi4_t mubi_module_en; + assign mubi_module_en = mubi4_t'(reg2hw.module_enable.q); + assign stub_es_valid = mubi4_test_true_strict(mubi_module_en); + + if (Stub) begin : gen_stub_entropy_src + caliptra_prim_lfsr #( + .LfsrDw(StubLfsrWidth), + .StateOutDw(StubLfsrWidth) + ) u_caliptra_prim_lfsr ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .seed_en_i ('0), + .seed_i ('0), + .lfsr_en_i (stub_es_valid), + .entropy_i ('0), + .state_o (stub_lfsr_value) + ); + + // hardwire hw2reg inputs + always_comb begin + stub_hw2reg = '0; + + // as long as enable is 1, do not allow registers to be written + stub_hw2reg.fw_ov_rd_data.d = stub_lfsr_value[31:0]; + stub_hw2reg.entropy_data.d = stub_lfsr_value[31:0]; + stub_hw2reg.debug_status.main_sm_idle.d = 1'b1; + // need to move this to package so that it can be referenced + stub_hw2reg.debug_status.main_sm_state.d = 8'b01110110; + + stub_hw2reg.intr_state.es_entropy_valid.de = stub_es_valid; + stub_hw2reg.intr_state.es_entropy_valid.d = 1'b1; + + end + end else begin : gen_stub_tieoff + assign stub_hw2reg = '0; + assign stub_lfsr_value = '0; + end + + /////////////////////////// + // Alert generation + /////////////////////////// + for (genvar i = 0; i < NumAlerts; i++) begin : gen_alert_tx + caliptra_prim_alert_sender #( + .AsyncOn(AlertAsyncOn[i]), + .IsFatal(i) + ) u_caliptra_prim_alert_sender ( + .clk_i, + .rst_ni, + .alert_test_i ( alert_test[i] ), + .alert_req_i ( alert[i] || intg_err_alert[i] ), + .alert_ack_o ( ), + .alert_state_o ( ), + .alert_rx_i ( alert_rx_i[i] ), + .alert_tx_o ( alert_tx_o[i] ) + ); + end + + // Outputs should have a known value after reset + `CALIPTRA_ASSERT_KNOWN(AHBRespKnownO_A, hresp_o) + `CALIPTRA_ASSERT_KNOWN(AHBReadyKnownO_A, hreadyout_o) + + // Entropy Interface + `CALIPTRA_ASSERT_KNOWN(EsHwIfEsAckKnownO_A, entropy_src_hw_if_o.es_ack) + `CALIPTRA_ASSERT_KNOWN_IF(EsHwIfEsBitsKnownO_A, entropy_src_hw_if_o.es_bits, + entropy_src_hw_if_o.es_ack) + `CALIPTRA_ASSERT_KNOWN_IF(EsHwIfEsFipsKnownO_A, entropy_src_hw_if_o.es_fips, + entropy_src_hw_if_o.es_ack) + + // RNG Interface + `CALIPTRA_ASSERT_KNOWN(EsRngEnableKnownO_A, entropy_src_rng_o.rng_enable) + + // External Health Test Interface + `CALIPTRA_ASSERT_KNOWN_IF(EsXhtEntropyBitKnownO_A, entropy_src_xht_o.entropy_bit, + entropy_src_xht_o.entropy_bit_valid) + `CALIPTRA_ASSERT_KNOWN(EsXhtEntropyBitValidKnownO_A, entropy_src_xht_o.entropy_bit_valid) + `CALIPTRA_ASSERT_KNOWN(EsXhtClearKnownO_A, entropy_src_xht_o.clear) + `CALIPTRA_ASSERT_KNOWN(EsXhtActiveKnownO_A, entropy_src_xht_o.active) + `CALIPTRA_ASSERT_KNOWN(EsXhtThreshHiKnownO_A, entropy_src_xht_o.thresh_hi) + `CALIPTRA_ASSERT_KNOWN(EsXhtThreshLoKnownO_A, entropy_src_xht_o.thresh_lo) + `CALIPTRA_ASSERT_KNOWN(EsXhtWindowKnownO_A, entropy_src_xht_o.window_wrap_pulse) + + // Alerts + `CALIPTRA_ASSERT_KNOWN(AlertTxKnownO_A, alert_tx_o) + + // Interrupts + `CALIPTRA_ASSERT_KNOWN(IntrEsEntropyValidKnownO_A, intr_es_entropy_valid_o) + `CALIPTRA_ASSERT_KNOWN(IntrEsHealthTestFailedKnownO_A, intr_es_health_test_failed_o) + `CALIPTRA_ASSERT_KNOWN(IntrEsFifoErrKnownO_A, intr_es_fatal_err_o) + + // caliptra_prim_count alerts + `CALIPTRA_ASSERT_PRIM_COUNT_ERROR_TRIGGER_ALERT(CntAlertCheck0_A, + u_entropy_src_core.u_caliptra_prim_count_window_cntr, + alert_tx_o[1]) + + for (genvar sh = 0; sh < RngBusWidth; sh = sh+1) begin : gen_bit_cntrs + `CALIPTRA_ASSERT_PRIM_COUNT_ERROR_TRIGGER_ALERT(CntAlertCheck1_A, + u_entropy_src_core.u_entropy_src_adaptp_ht.gen_cntrs[sh].u_caliptra_prim_count_test_cnt, + alert_tx_o[1]) + end : gen_bit_cntrs + + for (genvar i = 0; i < NumBins; i = i + 1) begin : gen_symbol_match + `CALIPTRA_ASSERT_PRIM_COUNT_ERROR_TRIGGER_ALERT(CntAlertCheck_A, + u_entropy_src_core.u_entropy_src_bucket_ht.gen_symbol_match[i].u_caliptra_prim_count_bin_cntr, + alert_tx_o[1]) + end : gen_symbol_match + + for (genvar sh = 0; sh < RngBusWidth; sh = sh+1) begin : gen_pair_cntrs + `CALIPTRA_ASSERT_PRIM_COUNT_ERROR_TRIGGER_ALERT(CntAlertCheck_A, + u_entropy_src_core.u_entropy_src_markov_ht.gen_cntrs[sh].u_caliptra_prim_count_pair_cntr, + alert_tx_o[1]) + end : gen_pair_cntrs + + for (genvar sh = 0; sh < RngBusWidth; sh = sh+1) begin : gen_rep_cntrs + `CALIPTRA_ASSERT_PRIM_COUNT_ERROR_TRIGGER_ALERT(CntAlertCheck_A, + u_entropy_src_core.u_entropy_src_repcnt_ht.gen_cntrs[sh].u_caliptra_prim_count_rep_cntr, + alert_tx_o[1]) + end : gen_rep_cntrs + + `CALIPTRA_ASSERT_PRIM_COUNT_ERROR_TRIGGER_ALERT(CntAlertCheck7_A, + u_entropy_src_core.u_entropy_src_repcnts_ht.u_caliptra_prim_count_rep_cntr, + alert_tx_o[1]) + + `CALIPTRA_ASSERT_PRIM_FSM_ERROR_TRIGGER_ALERT(CtrlMainFsmCheck_A, + u_entropy_src_core.u_entropy_src_main_sm.u_state_regs, + alert_tx_o[1]) + + `CALIPTRA_ASSERT_PRIM_FSM_ERROR_TRIGGER_ALERT(CtrlAckFsmCheck_A, + u_entropy_src_core.u_entropy_src_ack_sm.u_state_regs, + alert_tx_o[1]) + + `CALIPTRA_ASSERT_PRIM_FSM_ERROR_TRIGGER_ALERT(SHA3FsmCheck_A, + u_entropy_src_core.u_sha3.u_state_regs, alert_tx_o[1]) + + `CALIPTRA_ASSERT_PRIM_FSM_ERROR_TRIGGER_ALERT(KeccakRoundFsmCheck_A, + u_entropy_src_core.u_sha3.u_keccak.u_state_regs, alert_tx_o[1]) + + `CALIPTRA_ASSERT_PRIM_FSM_ERROR_TRIGGER_ALERT(SHA3padFsmCheck_A, + u_entropy_src_core.u_sha3.u_pad.u_state_regs, alert_tx_o[1]) + + + `CALIPTRA_ASSERT_PRIM_COUNT_ERROR_TRIGGER_ALERT(SentMsgCountCheck_A, + u_entropy_src_core.u_sha3.u_pad.u_sentmsg_count, alert_tx_o[1]) + + `CALIPTRA_ASSERT_PRIM_COUNT_ERROR_TRIGGER_ALERT(RoundCountCheck_A, + u_entropy_src_core.u_sha3.u_keccak.u_round_count, alert_tx_o[1]) + + `CALIPTRA_ASSERT_PRIM_COUNT_ERROR_TRIGGER_ALERT(CntAlertCheck8_A, + u_entropy_src_core.u_entropy_src_cntr_reg_repcnt.u_caliptra_prim_count_cntr_reg, + alert_tx_o[1]) + + `CALIPTRA_ASSERT_PRIM_COUNT_ERROR_TRIGGER_ALERT(CntAlertCheck9_A, + u_entropy_src_core.u_entropy_src_cntr_reg_repcnts.u_caliptra_prim_count_cntr_reg, + alert_tx_o[1]) + + `CALIPTRA_ASSERT_PRIM_COUNT_ERROR_TRIGGER_ALERT(CntAlertCheck10_A, + u_entropy_src_core.u_entropy_src_cntr_reg_adaptp_hi.u_caliptra_prim_count_cntr_reg, + alert_tx_o[1]) + + `CALIPTRA_ASSERT_PRIM_COUNT_ERROR_TRIGGER_ALERT(CntAlertCheck11_A, + u_entropy_src_core.u_entropy_src_cntr_reg_adaptp_lo.u_caliptra_prim_count_cntr_reg, + alert_tx_o[1]) + + `CALIPTRA_ASSERT_PRIM_COUNT_ERROR_TRIGGER_ALERT(CntAlertCheck12_A, + u_entropy_src_core.u_entropy_src_cntr_reg_bucket.u_caliptra_prim_count_cntr_reg, + alert_tx_o[1]) + + `CALIPTRA_ASSERT_PRIM_COUNT_ERROR_TRIGGER_ALERT(CntAlertCheck13_A, + u_entropy_src_core.u_entropy_src_cntr_reg_markov_hi.u_caliptra_prim_count_cntr_reg, + alert_tx_o[1]) + + `CALIPTRA_ASSERT_PRIM_COUNT_ERROR_TRIGGER_ALERT(CntAlertCheck14_A, + u_entropy_src_core.u_entropy_src_cntr_reg_markov_lo.u_caliptra_prim_count_cntr_reg, + alert_tx_o[1]) + + `CALIPTRA_ASSERT_PRIM_COUNT_ERROR_TRIGGER_ALERT(CntAlertCheck15_A, + u_entropy_src_core.u_entropy_src_cntr_reg_extht_hi.u_caliptra_prim_count_cntr_reg, + alert_tx_o[1]) + + `CALIPTRA_ASSERT_PRIM_COUNT_ERROR_TRIGGER_ALERT(CntAlertCheck16_A, + u_entropy_src_core.u_entropy_src_cntr_reg_extht_lo.u_caliptra_prim_count_cntr_reg, + alert_tx_o[1]) + + `CALIPTRA_ASSERT_PRIM_COUNT_ERROR_TRIGGER_ALERT(CntAlertCheck17_A, + u_entropy_src_core.u_entropy_src_cntr_reg_any_alert_fails.u_caliptra_prim_count_cntr_reg, + alert_tx_o[1]) + + `CALIPTRA_ASSERT_PRIM_COUNT_ERROR_TRIGGER_ALERT(CntAlertCheck18_A, + u_entropy_src_core.u_entropy_src_cntr_reg_repcnt_alert_fails.u_caliptra_prim_count_cntr_reg, + alert_tx_o[1]) + + `CALIPTRA_ASSERT_PRIM_COUNT_ERROR_TRIGGER_ALERT(CntAlertCheck19_A, + u_entropy_src_core.u_entropy_src_cntr_reg_repcnts_alert_fails.u_caliptra_prim_count_cntr_reg, + alert_tx_o[1]) + + `CALIPTRA_ASSERT_PRIM_COUNT_ERROR_TRIGGER_ALERT(CntAlertCheck20_A, + u_entropy_src_core.u_entropy_src_cntr_reg_adaptp_hi_alert_fails.u_caliptra_prim_count_cntr_reg, + alert_tx_o[1]) + + `CALIPTRA_ASSERT_PRIM_COUNT_ERROR_TRIGGER_ALERT(CntAlertCheck21_A, + u_entropy_src_core.u_entropy_src_cntr_reg_adaptp_lo_alert_fails.u_caliptra_prim_count_cntr_reg, + alert_tx_o[1]) + + `CALIPTRA_ASSERT_PRIM_COUNT_ERROR_TRIGGER_ALERT(CntAlertCheck22_A, + u_entropy_src_core.u_entropy_src_cntr_reg_bucket_alert_fails.u_caliptra_prim_count_cntr_reg, + alert_tx_o[1]) + + `CALIPTRA_ASSERT_PRIM_COUNT_ERROR_TRIGGER_ALERT(CntAlertCheck23_A, + u_entropy_src_core.u_entropy_src_cntr_reg_markov_hi_alert_fails.u_caliptra_prim_count_cntr_reg, + alert_tx_o[1]) + + `CALIPTRA_ASSERT_PRIM_COUNT_ERROR_TRIGGER_ALERT(CntAlertCheck24_A, + u_entropy_src_core.u_entropy_src_cntr_reg_markov_lo_alert_fails.u_caliptra_prim_count_cntr_reg, + alert_tx_o[1]) + + `CALIPTRA_ASSERT_PRIM_COUNT_ERROR_TRIGGER_ALERT(CntAlertCheck25_A, + u_entropy_src_core.u_entropy_src_cntr_reg_extht_hi_alert_fails.u_caliptra_prim_count_cntr_reg, + alert_tx_o[1]) + + `CALIPTRA_ASSERT_PRIM_COUNT_ERROR_TRIGGER_ALERT(CntAlertCheck26_A, + u_entropy_src_core.u_entropy_src_cntr_reg_extht_lo_alert_fails.u_caliptra_prim_count_cntr_reg, + alert_tx_o[1]) + + `CALIPTRA_ASSERT_PRIM_COUNT_ERROR_TRIGGER_ALERT(EsrngFifoWptrCheck_A, + u_entropy_src_core.u_caliptra_prim_fifo_sync_esrng.gen_normal_fifo.u_fifo_cnt.gen_secure_ptrs.u_wptr, + alert_tx_o[1]) + `CALIPTRA_ASSERT_PRIM_COUNT_ERROR_TRIGGER_ALERT(EsrngFifoRptrCheck_A, + u_entropy_src_core.u_caliptra_prim_fifo_sync_esrng.gen_normal_fifo.u_fifo_cnt.gen_secure_ptrs.u_rptr, + alert_tx_o[1]) + + `CALIPTRA_ASSERT_PRIM_COUNT_ERROR_TRIGGER_ALERT(DistrFifoWptrCheck_A, + u_entropy_src_core.u_caliptra_prim_fifo_sync_distr.gen_normal_fifo.u_fifo_cnt.gen_secure_ptrs.u_wptr, + alert_tx_o[1]) + `CALIPTRA_ASSERT_PRIM_COUNT_ERROR_TRIGGER_ALERT(DistrFifoRptrCheck_A, + u_entropy_src_core.u_caliptra_prim_fifo_sync_distr.gen_normal_fifo.u_fifo_cnt.gen_secure_ptrs.u_rptr, + alert_tx_o[1]) + + `CALIPTRA_ASSERT_PRIM_COUNT_ERROR_TRIGGER_ALERT(ObserveFifoWptrCheck_A, + u_entropy_src_core.u_caliptra_prim_fifo_sync_observe.gen_normal_fifo.u_fifo_cnt.gen_secure_ptrs.u_wptr, + alert_tx_o[1]) + `CALIPTRA_ASSERT_PRIM_COUNT_ERROR_TRIGGER_ALERT(ObserveFifoRptrCheck_A, + u_entropy_src_core.u_caliptra_prim_fifo_sync_observe.gen_normal_fifo.u_fifo_cnt.gen_secure_ptrs.u_rptr, + alert_tx_o[1]) + + `CALIPTRA_ASSERT_PRIM_COUNT_ERROR_TRIGGER_ALERT(EsfinalFifoWptrCheck_A, + u_entropy_src_core.u_caliptra_prim_fifo_sync_esfinal.gen_normal_fifo.u_fifo_cnt.gen_secure_ptrs.u_wptr, + alert_tx_o[1]) + `CALIPTRA_ASSERT_PRIM_COUNT_ERROR_TRIGGER_ALERT(EsfinalFifoRptrCheck_A, + u_entropy_src_core.u_caliptra_prim_fifo_sync_esfinal.gen_normal_fifo.u_fifo_cnt.gen_secure_ptrs.u_rptr, + alert_tx_o[1]) + + // Alert assertions for reg_we onehot check + `CALIPTRA_ASSERT_PRIM_REG_WE_ONEHOT_ERROR_TRIGGER_ALERT(RegWeOnehotCheck_A, u_reg, alert_tx_o[1]) + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/entropy_src_ack_sm.sv b/designs/Caliptra/src/caliptra-rtl/entropy_src_ack_sm.sv new file mode 100644 index 0000000..80ddf8a --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/entropy_src_ack_sm.sv @@ -0,0 +1,64 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Description: interface between a req/ack interface and a fifo +// + +module entropy_src_ack_sm ( + input logic clk_i, + input logic rst_ni, + + input logic enable_i, + input logic req_i, + output logic ack_o, + input logic fifo_not_empty_i, + input logic local_escalate_i, + output logic fifo_pop_o, + output logic ack_sm_err_o +); + + import entropy_src_ack_sm_pkg::*; + + state_e state_d, state_q; + + `CALIPTRA_PRIM_FLOP_SPARSE_FSM(u_state_regs, state_d, state_q, state_e, Idle) + + always_comb begin + state_d = state_q; + ack_o = 1'b0; + fifo_pop_o = 1'b0; + ack_sm_err_o = 1'b0; + unique case (state_q) + Idle: begin + if (enable_i) begin + if (req_i) begin + state_d = Wait_Data; + end + end + end + Wait_Data: begin + if (!enable_i) begin + state_d = Idle; + end else begin + if (fifo_not_empty_i) begin + ack_o = 1'b1; + fifo_pop_o = 1'b1; + state_d = Idle; + end + end + end + Error: begin + ack_sm_err_o = 1'b1; + end + default: begin + state_d = Error; + ack_sm_err_o = 1'b1; + end + endcase + if (local_escalate_i) begin + state_d = Error; + end + end + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/entropy_src_ack_sm_pkg.sv b/designs/Caliptra/src/caliptra-rtl/entropy_src_ack_sm_pkg.sv new file mode 100644 index 0000000..f007856 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/entropy_src_ack_sm_pkg.sv @@ -0,0 +1,35 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// State definitions for entropy_src_ack_sm, provided as a separate package for use in DV + +package entropy_src_ack_sm_pkg; + + // Encoding generated with: + // $ ./util/design/sparse-fsm-encode.py -d 3 -m 3 -n 6 \ + // -s 1236774883 --language=sv + // + // Hamming distance histogram: + // + // 0: -- + // 1: -- + // 2: -- + // 3: |||||||||||||||||||| (33.33%) + // 4: |||||||||||||||||||| (33.33%) + // 5: |||||||||||||||||||| (33.33%) + // 6: -- + // + // Minimum Hamming distance: 3 + // Maximum Hamming distance: 5 + // Minimum Hamming weight: 1 + // Maximum Hamming weight: 4 + // + localparam int StateWidth = 6; + typedef enum logic [StateWidth-1:0] { + Idle = 6'b011101, // idle + Wait_Data = 6'b101100, // wait until the fifo has an entry + Error = 6'b000010 // illegal state reached and hang + } state_e; + +endpackage diff --git a/designs/Caliptra/src/caliptra-rtl/entropy_src_adaptp_ht.sv b/designs/Caliptra/src/caliptra-rtl/entropy_src_adaptp_ht.sv new file mode 100644 index 0000000..b005b2c --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/entropy_src_adaptp_ht.sv @@ -0,0 +1,132 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Description: entropy_src adaptive proportion health test module +// + +module entropy_src_adaptp_ht #( + parameter int RegWidth = 16, + parameter int RngBusWidth = 4 +) ( + input logic clk_i, + input logic rst_ni, + + // ins req interface + input logic [RngBusWidth-1:0] entropy_bit_i, + input logic entropy_bit_vld_i, + input logic rng_bit_en_i, + input logic [1:0] rng_bit_sel_i, + input logic clear_i, + input logic active_i, + input logic [RegWidth-1:0] thresh_hi_i, + input logic [RegWidth-1:0] thresh_lo_i, + input logic window_wrap_pulse_i, + input logic threshold_scope_i, + output logic [RegWidth-1:0] test_cnt_hi_o, + output logic [RegWidth-1:0] test_cnt_lo_o, + output logic test_fail_hi_pulse_o, + output logic test_fail_lo_pulse_o, + output logic count_err_o +); + + // signals + logic [RegWidth-1:0] test_cnt_max; + logic [RegWidth-1:0] test_cnt_min, test_cnt_min_tmp; + logic [RegWidth-1:0] test_cnt_sum; + logic [RngBusWidth-1:0][RegWidth-1:0] test_cnt; + logic [RegWidth-1:0] rng_bit_cnt; + logic [RngBusWidth-1:0] test_cnt_err; + + // Adaptive Proportion Test + // + // Test operation + // This is an approved modification of the NIST Adaptive Proportion test in that + // instead of counting the first sampled value (1'b1 or 1'b0), it will count + // only the 1's on all four bit streams and accumulate for the during of the + // window size (W) of the test. + + for (genvar sh = 0; sh < RngBusWidth; sh = sh+1) begin : gen_cntrs + + // cumulative ones counter + // SEC_CM: CTR.REDUN + caliptra_prim_count #( + .Width(RegWidth) + ) u_caliptra_prim_count_test_cnt ( + .clk_i, + .rst_ni, + .clr_i(window_wrap_pulse_i), + .set_i(!active_i || clear_i), + .set_cnt_i(RegWidth'(0)), + .incr_en_i(entropy_bit_vld_i), + .decr_en_i(1'b0), + .step_i(RegWidth'(entropy_bit_i[sh])), + .commit_i(1'b1), + .cnt_o(test_cnt[sh]), + .cnt_after_commit_o(), + .err_o(test_cnt_err[sh]) + ); + end : gen_cntrs + + // determine the highest counter counter value + caliptra_prim_max_tree #( + .NumSrc(RngBusWidth), + .Width(RegWidth) + ) u_max ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .values_i (test_cnt), + .valid_i ({RngBusWidth{1'b1}}), + .max_value_o (test_cnt_max), + .max_idx_o (), + .max_valid_o () + ); + + // determine the lowest counter value + // Negate the inputs and outputs of caliptra_prim_max_tree to find the minimum + // For this unsigned application, one's complement negation (i.e. logical inversion) is fine. + caliptra_prim_max_tree #( + .NumSrc(RngBusWidth), + .Width(RegWidth) + ) u_min ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .values_i (~test_cnt), + .valid_i ({RngBusWidth{1'b1}}), + .max_value_o (test_cnt_min_tmp), + .max_idx_o (), + .max_valid_o () + ); + + assign test_cnt_min = ~test_cnt_min_tmp; + + caliptra_prim_sum_tree #( + .NumSrc(RngBusWidth), + .Width(RegWidth) + ) u_sum ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .values_i (test_cnt), + .valid_i ({RngBusWidth{1'b1}}), + .sum_value_o (test_cnt_sum), + .sum_valid_o () + ); + + assign rng_bit_cnt = (rng_bit_sel_i == 2'h0) ? test_cnt[0] : + (rng_bit_sel_i == 2'h1) ? test_cnt[1] : + (rng_bit_sel_i == 2'h2) ? test_cnt[2] : + test_cnt[3]; + + assign test_cnt_hi_o = rng_bit_en_i ? rng_bit_cnt : + threshold_scope_i ? test_cnt_sum : + test_cnt_max; + assign test_cnt_lo_o = rng_bit_en_i ? rng_bit_cnt : + threshold_scope_i ? test_cnt_sum : + test_cnt_min; + + // the pulses will be only one clock in length + assign test_fail_hi_pulse_o = active_i && window_wrap_pulse_i && (test_cnt_hi_o > thresh_hi_i); + assign test_fail_lo_pulse_o = active_i && window_wrap_pulse_i && (test_cnt_lo_o < thresh_lo_i); + assign count_err_o = |test_cnt_err; + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/entropy_src_bucket_ht.sv b/designs/Caliptra/src/caliptra-rtl/entropy_src_bucket_ht.sv new file mode 100644 index 0000000..63a508a --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/entropy_src_bucket_ht.sv @@ -0,0 +1,90 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Description: entropy_src bucket health test module +// + +module entropy_src_bucket_ht #( + parameter int RegWidth = 16, + parameter int RngBusWidth = 4 +) ( + input logic clk_i, + input logic rst_ni, + + // ins req interface + input logic [RngBusWidth-1:0] entropy_bit_i, + input logic entropy_bit_vld_i, + input logic clear_i, + input logic active_i, + input logic [RegWidth-1:0] thresh_i, + input logic window_wrap_pulse_i, + output logic [RegWidth-1:0] test_cnt_o, + output logic test_fail_pulse_o, + output logic count_err_o +); + + localparam int NUM_BINS = 2**RngBusWidth; + + // signals + logic [NUM_BINS-1:0] bin_incr; + logic [NUM_BINS-1:0] bin_cnt_exceeds_thresh; + logic [NUM_BINS - 1:0][RegWidth - 1:0] bin_cntr; + logic [NUM_BINS-1:0] bin_cntr_err; + logic [RegWidth-1:0] bin_max; + + // Bucket Test + // + // Test operation + // This test will look at 4 bit symbols and increment one of sixteen + // counters, or buckets, to show a histogram of the data stream. + // An error will occur if one of the counters reaches the thresh + // value. + + + // Analyze the incoming symbols + + for (genvar i = 0; i < NUM_BINS; i = i + 1) begin : gen_symbol_match + // set the bin incrementer if the symbol matches that bin + assign bin_incr[i] = entropy_bit_vld_i && (entropy_bit_i == i); + // use the bin incrementer to increase the bin total count + // SEC_CM: CTR.REDUN + caliptra_prim_count #( + .Width(RegWidth) + ) u_caliptra_prim_count_bin_cntr ( + .clk_i, + .rst_ni, + .clr_i(window_wrap_pulse_i), + .set_i(!active_i || clear_i), + .set_cnt_i(RegWidth'(0)), + .incr_en_i(bin_incr[i]), + .decr_en_i(1'b0), + .step_i(RegWidth'(1)), + .commit_i(1'b1), + .cnt_o(bin_cntr[i]), + .cnt_after_commit_o(), + .err_o(bin_cntr_err[i]) + ); + assign bin_cnt_exceeds_thresh[i] = (bin_cntr[i] > thresh_i); + end : gen_symbol_match + + caliptra_prim_max_tree #( + .NumSrc(NUM_BINS), + .Width(RegWidth) + ) u_caliptra_prim_max_tree_bin_cntr_max ( + .clk_i, + .rst_ni, + .values_i (bin_cntr), + .valid_i ({RegWidth{1'b1}}), + .max_value_o(bin_max), + .max_idx_o (), + .max_valid_o() + ); + + // the pulses will be only one clock in length + assign test_fail_pulse_o = active_i && window_wrap_pulse_i && (|bin_cnt_exceeds_thresh); + assign test_cnt_o = bin_max; + assign count_err_o = |bin_cntr_err; + + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/entropy_src_cntr_reg.sv b/designs/Caliptra/src/caliptra-rtl/entropy_src_cntr_reg.sv new file mode 100644 index 0000000..bbf941d --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/entropy_src_cntr_reg.sv @@ -0,0 +1,44 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Description: entropy_src counter register module +// + +module entropy_src_cntr_reg #( + parameter int RegWidth = 16 +) ( + input logic clk_i, + input logic rst_ni, + + // functional interface + input logic clear_i, + input logic event_i, + output logic [RegWidth-1:0] value_o, + output logic err_o +); + + // signals + logic [RegWidth-1:0] counter_value; + + // counter will not wrap when full value is reached + caliptra_prim_count #( + .Width(RegWidth) + ) u_caliptra_prim_count_cntr_reg ( + .clk_i, + .rst_ni, + .clr_i(clear_i), + .set_i(1'b0), + .set_cnt_i(RegWidth'(0)), + .incr_en_i(event_i && (~counter_value != '0)), + .decr_en_i(1'b0), + .step_i(RegWidth'(1)), + .commit_i(1'b1), + .cnt_o(counter_value), + .cnt_after_commit_o(), + .err_o(err_o) + ); + + assign value_o = counter_value; + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/entropy_src_core.sv b/designs/Caliptra/src/caliptra-rtl/entropy_src_core.sv new file mode 100644 index 0000000..ab64060 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/entropy_src_core.sv @@ -0,0 +1,3488 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Description: entropy_src core module +// + +`include "caliptra_prim_assert.sv" + +module entropy_src_core + import entropy_src_pkg::*; + import lc_ctrl_state_pkg::*; + import lc_ctrl_reg_pkg::*; + import lc_ctrl_pkg::*; +#( + parameter int EsFifoDepth = 4, + parameter int DistrFifoDepth = 2 +) ( + input logic clk_i, + input logic rst_ni, + + input entropy_src_reg_pkg::entropy_src_reg2hw_t reg2hw, + output entropy_src_reg_pkg::entropy_src_hw2reg_t hw2reg, + + // Efuse Interface + input caliptra_prim_mubi_pkg::mubi8_t otp_en_entropy_src_fw_read_i, + input caliptra_prim_mubi_pkg::mubi8_t otp_en_entropy_src_fw_over_i, + + // RNG Interface + output logic rng_fips_o, + + // Entropy Interface + input entropy_src_hw_if_req_t entropy_src_hw_if_i, + output entropy_src_hw_if_rsp_t entropy_src_hw_if_o, + + // RNG Interface + output entropy_src_rng_req_t entropy_src_rng_o, + input entropy_src_rng_rsp_t entropy_src_rng_i, + + // CSRNG Interface + output cs_aes_halt_req_t cs_aes_halt_o, + input cs_aes_halt_rsp_t cs_aes_halt_i, + + // External Health Test Interface + output entropy_src_xht_req_t entropy_src_xht_o, + input entropy_src_xht_rsp_t entropy_src_xht_i, + + output logic recov_alert_test_o, + output logic fatal_alert_test_o, + output logic recov_alert_o, + output logic fatal_alert_o, + + output logic intr_es_entropy_valid_o, + output logic intr_es_health_test_failed_o, + output logic intr_es_observe_fifo_ready_o, + output logic intr_es_fatal_err_o +); + + import entropy_src_reg_pkg::*; + import caliptra_prim_mubi_pkg::mubi4_t; + import caliptra_prim_mubi_pkg::mubi4_test_true_strict; + import caliptra_prim_mubi_pkg::mubi4_and_hi; + import caliptra_prim_mubi_pkg::mubi4_test_false_loose; + import caliptra_prim_mubi_pkg::mubi4_test_invalid; + + localparam int EsFifoDepthW = caliptra_prim_util_pkg::vbits(EsFifoDepth); + localparam int PostHTWidth = 32; + localparam int RngBusWidth = 4; + localparam int HalfRegWidth = 16; + localparam int FullRegWidth = 32; + localparam int EighthRegWidth = 4; + localparam int SeedLen = 384; + localparam int DistrFifoWidth = 32; + localparam int ObserveFifoWidth = 32; + localparam int PreCondWidth = 64; + localparam int Clog2ObserveFifoDepth = $clog2(ObserveFifoDepth); + localparam int EsEnableCopies = 20; + localparam int EsEnPulseCopies = 1; + localparam int unsigned NumSwReadsSeed = SeedLen / FullRegWidth; + localparam int unsigned LastSwRead = NumSwReadsSeed - 1; + localparam int unsigned SwReadIdxWidth = caliptra_prim_util_pkg::vbits(NumSwReadsSeed); + + //----------------------- + // SHA3parameters + //----------------------- + // Do not enable masking + localparam bit Sha3EnMasking = 0; + // derived parameter + localparam int Sha3Share = (Sha3EnMasking) ? 2 : 1; + + // signals + logic fw_ov_mode; + logic fw_ov_mode_pfe; + logic fw_ov_mode_pfa; + logic fw_ov_wr_fifo_full; + logic fw_ov_mode_entropy_insert; + logic fw_ov_entropy_insert_pfe; + logic fw_ov_entropy_insert_pfa; + logic fw_ov_sha3_start_pfe; + logic fw_ov_sha3_start_pfe_q; + logic fw_ov_sha3_start_pfa; + logic fw_ov_sha3_disable_pulse; + logic [ObserveFifoWidth-1:0] fw_ov_wr_data; + logic fw_ov_fifo_rd_pulse; + logic fw_ov_fifo_wr_pulse; + logic es_enable_pfa; + + logic fips_enable_pfe; + logic fips_enable_pfa; + logic fips_flag_pfe; + logic fips_flag_pfa; + logic rng_fips_pfe; + logic rng_fips_pfa; + + logic rng_bit_en; + logic rng_bit_enable_pfe; + logic rng_bit_enable_pfa; + logic [1:0] rng_bit_sel; + logic rng_enable_q, rng_enable_d; + logic entropy_data_reg_en_pfe; + logic entropy_data_reg_en_pfa; + logic es_data_reg_rd_en; + logic event_es_entropy_valid; + logic event_es_health_test_failed; + logic event_es_observe_fifo_ready; + logic event_es_fatal_err; + logic es_rng_src_valid; + logic [RngBusWidth-1:0] es_rng_bus; + + logic [RngBusWidth-1:0] sfifo_esrng_wdata; + logic [RngBusWidth-1:0] sfifo_esrng_rdata; + logic sfifo_esrng_push; + logic sfifo_esrng_pop; + logic sfifo_esrng_clr; + logic sfifo_esrng_full; + logic sfifo_esrng_not_empty; + logic sfifo_esrng_not_full; + logic sfifo_esrng_int_err; + logic [2:0] sfifo_esrng_err; + + logic [DistrFifoWidth-1:0] sfifo_distr_wdata; + logic [DistrFifoWidth-1:0] sfifo_distr_rdata; + logic sfifo_distr_push; + logic sfifo_distr_pop; + logic sfifo_distr_clr; + logic sfifo_distr_not_full; + logic sfifo_distr_full; + logic sfifo_distr_not_empty; + logic sfifo_distr_int_err; + logic [2:0] sfifo_distr_err; + + logic [ObserveFifoWidth-1:0] sfifo_observe_wdata; + logic [ObserveFifoWidth-1:0] sfifo_observe_rdata; + logic sfifo_observe_push; + logic sfifo_observe_pop; + logic sfifo_observe_full; + logic sfifo_observe_clr; + logic sfifo_observe_not_empty; + logic [Clog2ObserveFifoDepth:0] sfifo_observe_depth; + logic sfifo_observe_int_err; + logic [2:0] sfifo_observe_err; + + logic [EsFifoDepthW-1:0] sfifo_esfinal_depth; + logic [(1+SeedLen)-1:0] sfifo_esfinal_wdata; + logic [(1+SeedLen)-1:0] sfifo_esfinal_rdata; + logic sfifo_esfinal_push; + logic sfifo_esfinal_pop; + logic sfifo_esfinal_clr; + logic sfifo_esfinal_not_full; + logic sfifo_esfinal_full; + logic sfifo_esfinal_not_empty; + logic sfifo_esfinal_int_err; + logic [2:0] sfifo_esfinal_err; + + logic es_sfifo_int_err; + + logic [SeedLen-1:0] esfinal_data; + logic esfinal_fips_flag; + + logic any_fail_pulse; + logic main_stage_push; + logic main_stage_push_raw; + logic bypass_stage_pop; + logic boot_phase_done; + logic [HalfRegWidth-1:0] any_fail_count; + logic any_fails_cntr_err; + logic alert_threshold_fail; + logic [HalfRegWidth-1:0] alert_threshold; + logic [HalfRegWidth-1:0] alert_threshold_inv; + logic [Clog2ObserveFifoDepth:0] observe_fifo_thresh; + logic observe_fifo_thresh_met; + logic repcnt_active; + logic repcnts_active; + logic adaptp_active; + logic bucket_active; + logic markov_active; + logic extht_active; + logic alert_cntrs_clr; + logic health_test_clr; + logic health_test_done_pulse; + logic [RngBusWidth-1:0] health_test_esbus; + logic health_test_esbus_vld; + logic es_route_pfe; + logic es_route_pfa; + logic es_type_pfe; + logic es_type_pfa; + logic es_route_to_sw; + logic es_bypass_to_sw; + logic es_bypass_mode; + logic rst_alert_cntr; + logic threshold_scope; + logic threshold_scope_pfe; + logic threshold_scope_pfa; + logic fips_compliance; + + logic [HalfRegWidth-1:0] health_test_fips_window; + logic [HalfRegWidth-1:0] health_test_bypass_window; + logic [HalfRegWidth-1:0] health_test_window; + logic [WINDOW_CNTR_WIDTH-1:0] health_test_window_scaled; + + logic [HalfRegWidth-1:0] repcnt_fips_threshold; + logic [HalfRegWidth-1:0] repcnt_fips_threshold_oneway; + logic repcnt_fips_threshold_wr; + logic [HalfRegWidth-1:0] repcnt_bypass_threshold; + logic [HalfRegWidth-1:0] repcnt_bypass_threshold_oneway; + logic repcnt_bypass_threshold_wr; + logic [HalfRegWidth-1:0] repcnt_threshold; + logic [HalfRegWidth-1:0] repcnt_event_cnt; + logic [HalfRegWidth-1:0] repcnt_event_hwm_fips; + logic [HalfRegWidth-1:0] repcnt_event_hwm_bypass; + logic [FullRegWidth-1:0] repcnt_total_fails; + logic [EighthRegWidth-1:0] repcnt_fail_count; + logic repcnt_fail_pulse; + logic repcnt_fails_cntr_err; + logic repcnt_alert_cntr_err; + + logic [HalfRegWidth-1:0] repcnts_fips_threshold; + logic [HalfRegWidth-1:0] repcnts_fips_threshold_oneway; + logic repcnts_fips_threshold_wr; + logic [HalfRegWidth-1:0] repcnts_bypass_threshold; + logic [HalfRegWidth-1:0] repcnts_bypass_threshold_oneway; + logic repcnts_bypass_threshold_wr; + logic [HalfRegWidth-1:0] repcnts_threshold; + logic [HalfRegWidth-1:0] repcnts_event_cnt; + logic [HalfRegWidth-1:0] repcnts_event_hwm_fips; + logic [HalfRegWidth-1:0] repcnts_event_hwm_bypass; + logic [FullRegWidth-1:0] repcnts_total_fails; + logic [EighthRegWidth-1:0] repcnts_fail_count; + logic repcnts_fail_pulse; + logic repcnts_fails_cntr_err; + logic repcnts_alert_cntr_err; + + logic [HalfRegWidth-1:0] adaptp_hi_fips_threshold; + logic [HalfRegWidth-1:0] adaptp_hi_fips_threshold_oneway; + logic adaptp_hi_fips_threshold_wr; + logic [HalfRegWidth-1:0] adaptp_hi_bypass_threshold; + logic [HalfRegWidth-1:0] adaptp_hi_bypass_threshold_oneway; + logic adaptp_hi_bypass_threshold_wr; + logic [HalfRegWidth-1:0] adaptp_hi_threshold; + logic [HalfRegWidth-1:0] adaptp_lo_fips_threshold; + logic [HalfRegWidth-1:0] adaptp_lo_fips_threshold_oneway; + logic adaptp_lo_fips_threshold_wr; + logic [HalfRegWidth-1:0] adaptp_lo_bypass_threshold; + logic [HalfRegWidth-1:0] adaptp_lo_bypass_threshold_oneway; + logic adaptp_lo_bypass_threshold_wr; + logic [HalfRegWidth-1:0] adaptp_lo_threshold; + logic [HalfRegWidth-1:0] adaptp_hi_event_cnt; + logic [HalfRegWidth-1:0] adaptp_lo_event_cnt; + logic [HalfRegWidth-1:0] adaptp_hi_event_hwm_fips; + logic [HalfRegWidth-1:0] adaptp_hi_event_hwm_bypass; + logic [HalfRegWidth-1:0] adaptp_lo_event_hwm_fips; + logic [HalfRegWidth-1:0] adaptp_lo_event_hwm_bypass; + logic [FullRegWidth-1:0] adaptp_hi_total_fails; + logic [FullRegWidth-1:0] adaptp_lo_total_fails; + logic [EighthRegWidth-1:0] adaptp_hi_fail_count; + logic [EighthRegWidth-1:0] adaptp_lo_fail_count; + logic adaptp_hi_fail_pulse; + logic adaptp_lo_fail_pulse; + logic adaptp_hi_fails_cntr_err; + logic adaptp_lo_fails_cntr_err; + logic adaptp_hi_alert_cntr_err; + logic adaptp_lo_alert_cntr_err; + + logic [HalfRegWidth-1:0] bucket_fips_threshold; + logic [HalfRegWidth-1:0] bucket_fips_threshold_oneway; + logic bucket_fips_threshold_wr; + logic [HalfRegWidth-1:0] bucket_bypass_threshold; + logic [HalfRegWidth-1:0] bucket_bypass_threshold_oneway; + logic bucket_bypass_threshold_wr; + logic [HalfRegWidth-1:0] bucket_threshold; + logic [HalfRegWidth-1:0] bucket_event_cnt; + logic [HalfRegWidth-1:0] bucket_event_hwm_fips; + logic [HalfRegWidth-1:0] bucket_event_hwm_bypass; + logic [FullRegWidth-1:0] bucket_total_fails; + logic [EighthRegWidth-1:0] bucket_fail_count; + logic bucket_fail_pulse; + logic bucket_fails_cntr_err; + logic bucket_alert_cntr_err; + + logic [HalfRegWidth-1:0] markov_hi_fips_threshold; + logic [HalfRegWidth-1:0] markov_hi_fips_threshold_oneway; + logic markov_hi_fips_threshold_wr; + logic [HalfRegWidth-1:0] markov_hi_bypass_threshold; + logic [HalfRegWidth-1:0] markov_hi_bypass_threshold_oneway; + logic markov_hi_bypass_threshold_wr; + logic [HalfRegWidth-1:0] markov_hi_threshold; + logic [HalfRegWidth-1:0] markov_lo_fips_threshold; + logic [HalfRegWidth-1:0] markov_lo_fips_threshold_oneway; + logic markov_lo_fips_threshold_wr; + logic [HalfRegWidth-1:0] markov_lo_bypass_threshold; + logic [HalfRegWidth-1:0] markov_lo_bypass_threshold_oneway; + logic markov_lo_bypass_threshold_wr; + logic [HalfRegWidth-1:0] markov_lo_threshold; + logic [HalfRegWidth-1:0] markov_hi_event_cnt; + logic [HalfRegWidth-1:0] markov_lo_event_cnt; + logic [HalfRegWidth-1:0] markov_hi_event_hwm_fips; + logic [HalfRegWidth-1:0] markov_hi_event_hwm_bypass; + logic [HalfRegWidth-1:0] markov_lo_event_hwm_fips; + logic [HalfRegWidth-1:0] markov_lo_event_hwm_bypass; + logic [FullRegWidth-1:0] markov_hi_total_fails; + logic [FullRegWidth-1:0] markov_lo_total_fails; + logic [EighthRegWidth-1:0] markov_hi_fail_count; + logic [EighthRegWidth-1:0] markov_lo_fail_count; + logic markov_hi_fail_pulse; + logic markov_lo_fail_pulse; + logic markov_hi_fails_cntr_err; + logic markov_lo_fails_cntr_err; + logic markov_hi_alert_cntr_err; + logic markov_lo_alert_cntr_err; + + logic [HalfRegWidth-1:0] extht_hi_fips_threshold; + logic [HalfRegWidth-1:0] extht_hi_fips_threshold_oneway; + logic extht_hi_fips_threshold_wr; + logic [HalfRegWidth-1:0] extht_hi_bypass_threshold; + logic [HalfRegWidth-1:0] extht_hi_bypass_threshold_oneway; + logic extht_hi_bypass_threshold_wr; + logic [HalfRegWidth-1:0] extht_hi_threshold; + logic [HalfRegWidth-1:0] extht_lo_fips_threshold; + logic [HalfRegWidth-1:0] extht_lo_fips_threshold_oneway; + logic extht_lo_fips_threshold_wr; + logic [HalfRegWidth-1:0] extht_lo_bypass_threshold; + logic [HalfRegWidth-1:0] extht_lo_bypass_threshold_oneway; + logic extht_lo_bypass_threshold_wr; + logic [HalfRegWidth-1:0] extht_lo_threshold; + logic [HalfRegWidth-1:0] extht_event_cnt_hi; + logic [HalfRegWidth-1:0] extht_event_cnt_lo; + logic [HalfRegWidth-1:0] extht_hi_event_hwm_fips; + logic [HalfRegWidth-1:0] extht_hi_event_hwm_bypass; + logic [HalfRegWidth-1:0] extht_lo_event_hwm_fips; + logic [HalfRegWidth-1:0] extht_lo_event_hwm_bypass; + logic [FullRegWidth-1:0] extht_hi_total_fails; + logic [FullRegWidth-1:0] extht_lo_total_fails; + logic [EighthRegWidth-1:0] extht_hi_fail_count; + logic [EighthRegWidth-1:0] extht_lo_fail_count; + logic extht_hi_fail_pulse; + logic extht_lo_fail_pulse; + logic extht_cont_test; + logic extht_hi_fails_cntr_err; + logic extht_lo_fails_cntr_err; + logic extht_hi_alert_cntr_err; + logic extht_lo_alert_cntr_err; + + + logic pfifo_esbit_wdata; + logic [RngBusWidth-1:0] pfifo_esbit_rdata; + logic pfifo_esbit_not_empty; + logic pfifo_esbit_not_full; + logic pfifo_esbit_push; + logic pfifo_esbit_clr; + logic pfifo_esbit_pop; + + logic [RngBusWidth-1:0] pfifo_postht_wdata; + logic [PostHTWidth-1:0] pfifo_postht_rdata; + logic pfifo_postht_not_empty; + logic pfifo_postht_not_full; + logic pfifo_postht_push; + logic pfifo_postht_clr; + logic pfifo_postht_pop; + + logic [PreCondWidth-1:0] pfifo_cond_wdata; + logic [SeedLen-1:0] pfifo_cond_rdata; + logic pfifo_cond_push; + + logic [ObserveFifoWidth-1:0] pfifo_precon_wdata; + logic [PreCondWidth-1:0] pfifo_precon_rdata; + logic pfifo_precon_not_empty; + logic pfifo_precon_not_full; + logic pfifo_precon_push; + logic pfifo_precon_clr; + logic pfifo_precon_pop; + + logic [PostHTWidth-1:0] pfifo_bypass_wdata; + logic [SeedLen-1:0] pfifo_bypass_rdata; + logic pfifo_bypass_not_empty; + logic pfifo_bypass_not_full; + logic pfifo_bypass_push; + logic pfifo_bypass_clr; + logic pfifo_bypass_pop; + + logic [SwReadIdxWidth-1:0] swread_idx_d, swread_idx_q; + logic swread_idx_incr, swread_idx_clr; + logic [FullRegWidth-1:0] swread_data, swread_data_buf; + logic swread_done; + + logic [SeedLen-1:0] final_es_data; + logic es_hw_if_req; + logic es_hw_if_ack; + logic es_hw_if_fifo_pop; + logic sfifo_esrng_err_sum; + logic sfifo_distr_err_sum; + logic sfifo_observe_err_sum; + logic sfifo_esfinal_err_sum; + // For fifo errors that are generated through the + // ERR_CODE_TEST register, but are not associated + // with any errors: + logic sfifo_test_err_sum; + logic es_ack_sm_err_sum; + logic es_ack_sm_err; + logic es_main_sm_err_sum; + logic es_main_sm_err; + logic es_main_sm_alert; + logic es_bus_cmp_alert; + logic es_thresh_cfg_alert; + logic es_main_sm_idle; + logic [8:0] es_main_sm_state; + logic fifo_write_err_sum; + logic fifo_read_err_sum; + logic fifo_status_err_sum; + logic [30:0] err_code_test_bit; + logic sha3_msgfifo_ready; + logic sha3_state_vld; + logic sha3_start_raw; + logic sha3_start; + logic sha3_process; + logic sha3_block_processed; + caliptra_prim_mubi_pkg::mubi4_t sha3_done; + caliptra_prim_mubi_pkg::mubi4_t sha3_absorbed; + logic sha3_squeezing; + logic [2:0] sha3_fsm; + logic [32:0] sha3_err; + logic cs_aes_halt_req; + logic [WINDOW_CNTR_WIDTH-1:0] window_cntr; + logic window_cntr_incr_en; + + logic [sha3_pkg::StateW-1:0] sha3_state[Sha3Share]; + logic [PreCondWidth-1:0] msg_data[Sha3Share]; + logic es_rdata_capt_vld; + logic window_cntr_err; + logic repcnt_cntr_err; + logic repcnts_cntr_err; + logic adaptp_cntr_err; + logic bucket_cntr_err; + logic markov_cntr_err; + logic es_cntr_err; + logic es_cntr_err_sum; + logic sha3_state_error_sum; + logic sha3_rst_storage_err_sum; + logic efuse_es_sw_reg_en; + logic efuse_es_sw_ov_en; + + logic sha3_state_error; + logic sha3_count_error; + logic sha3_rst_storage_err; + logic es_hw_regwen; + logic recov_alert_state; + logic es_fw_ov_wr_alert; + logic es_fw_ov_disable_alert; + logic fw_ov_corrupted; + logic postht_entropy_drop_alert; + + logic stale_seed_processing; + logic main_sm_enable; + logic main_sm_done_pulse; + logic main_sm_ht_failed; + + logic unused_err_code_test_bit; + logic unused_sha3_state; + logic unused_entropy_data; + logic unused_fw_ov_rd_data; + logic unused_sfifo_esrng_not_full; + logic unused_sfifo_esfinal_not_full; + + caliptra_prim_mubi_pkg::mubi8_t en_entropy_src_fw_read; + caliptra_prim_mubi_pkg::mubi8_t en_entropy_src_fw_over; + + mubi4_t mubi_es_enable; + mubi4_t mubi_module_en_pulse; + + mubi4_t mubi_module_en_raw; + mubi4_t [2:0] mubi_module_en_raw_fanout; + + mubi4_t [EsEnableCopies-1:0] mubi_es_enable_fanout; + logic [EsEnableCopies-1:0] es_enable_fo; + + mubi4_t [EsEnPulseCopies-1:0] mubi_module_en_pulse_fanout; + logic [EsEnPulseCopies-1:0] module_en_pulse_fo; + + // A delayed copy of the enable signal, and enable pulse which are needed to cleanly handle any + // long-duration operations from the previous run. + logic es_delayed_enable; + + mubi4_t [1:0] mubi_rng_bit_en_fanout; + mubi4_t mubi_rng_bit_en; + + // flops + logic ht_failed_qq, ht_failed_q, ht_failed_d; + logic ht_done_pulse_qq, ht_done_pulse_q, ht_done_pulse_d; + logic sha3_err_q, sha3_err_d; + logic cs_aes_halt_q, cs_aes_halt_d; + logic [63:0] es_rdata_capt_q, es_rdata_capt_d; + logic es_rdata_capt_vld_q, es_rdata_capt_vld_d; + mubi4_t mubi_mod_en_dly_d, mubi_mod_en_dly_q; + + + logic sha3_start_mask_q, sha3_start_mask_d; + logic sha3_flush_q, sha3_flush_d; + logic [1:0] fw_ov_corrupted_q, fw_ov_corrupted_d; + + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + ht_failed_q <= '0; + ht_failed_qq <= '0; + ht_done_pulse_q <= '0; + ht_done_pulse_qq <= '0; + sha3_err_q <= '0; + cs_aes_halt_q <= '0; + es_rdata_capt_q <= '0; + es_rdata_capt_vld_q <= '0; + fw_ov_sha3_start_pfe_q <= '0; + mubi_mod_en_dly_q <= caliptra_prim_mubi_pkg::MuBi4False; + sha3_flush_q <= '0; + sha3_start_mask_q <= '0; + fw_ov_corrupted_q <= 2'b00; + rng_enable_q <= 1'b 0; + end else begin + ht_failed_q <= ht_failed_d; + ht_failed_qq <= ht_failed_q; + ht_done_pulse_q <= ht_done_pulse_d; + ht_done_pulse_qq <= ht_done_pulse_q; + sha3_err_q <= sha3_err_d; + cs_aes_halt_q <= cs_aes_halt_d; + es_rdata_capt_q <= es_rdata_capt_d; + es_rdata_capt_vld_q <= es_rdata_capt_vld_d; + fw_ov_sha3_start_pfe_q <= fw_ov_sha3_start_pfe; + sha3_flush_q <= sha3_flush_d; + sha3_start_mask_q <= sha3_start_mask_d; + mubi_mod_en_dly_q <= mubi_mod_en_dly_d; + fw_ov_corrupted_q <= fw_ov_corrupted_d; + rng_enable_q <= rng_enable_d; + end + end + + assign fw_ov_sha3_disable_pulse = fw_ov_sha3_start_pfe_q & ~fw_ov_sha3_start_pfe; + + //-------------------------------------------- + // register lock gating + //-------------------------------------------- + + // Allow writes only if + // 1. SW_REGUPD is true, + // 2. The DUT is disabled + // Block writes if enabled or if internal activities are still in progress (as indicated by + // es_delayed_enable). + assign es_hw_regwen = reg2hw.sw_regupd.q && + mubi4_test_false_loose(mubi_module_en_raw_fanout[0]) && + !es_delayed_enable; + assign hw2reg.regwen.de = 1'b1; + assign hw2reg.regwen.d = es_hw_regwen; + + //-------------------------------------------- + // set up secure enable bits + //-------------------------------------------- + + // check for illegal enable field states, and set alert if detected + + // SEC_CM: CONFIG.MUBI + assign mubi_module_en_raw = mubi4_t'(reg2hw.module_enable.q); + assign es_enable_pfa = mubi4_test_invalid(mubi_module_en_raw_fanout[1]); + assign hw2reg.recov_alert_sts.module_enable_field_alert.de = es_enable_pfa; + assign hw2reg.recov_alert_sts.module_enable_field_alert.d = es_enable_pfa; + + caliptra_prim_mubi4_sync #( + .NumCopies(3), + .AsyncOn(0) + ) u_caliptra_prim_mubi4_sync_entropy_module_en ( + .clk_i, + .rst_ni, + .mubi_i(mubi_module_en_raw), + .mubi_o(mubi_module_en_raw_fanout) + ); + + // Generation of enable pulse, and main enable signals. + // + // This module creates a single mubi_encoded module_enable_pulse, as well as + // a general mubi_es_enable signal. + // + // The module enable pulse is MuBi4True for a single clock after the + // module_enable register is asserted MuBi4True. However in this first clock cycle + // most of the module is not enabled. (The enable pulse is for clearing the + // residual internal state.) + // + // The rest of the module is enabled in the second clock cycle after seting the + // module_enable register to MuBi4True. + // + // When module_enable is set to MuBi4False the module is disabled. No further + // RNG input is accepted and the state machines transition to Idle as soon as + // possible. Some delay may occur if the SHA3 conditioning block is busy, though + // otherwise the main_sm transitions to Idle without delay. + + assign mubi_mod_en_dly_d = mubi_module_en_raw_fanout[2]; + assign mubi_module_en_pulse = mubi4_and_hi(mubi_mod_en_dly_d, mubi4_t'(~mubi_mod_en_dly_q)); + assign mubi_es_enable = mubi4_and_hi(mubi_mod_en_dly_d, mubi_mod_en_dly_q); + + for (genvar i = 0; i < EsEnableCopies; i = i+1) begin : gen_mubi_en_copies + assign es_enable_fo[i] = mubi4_test_true_strict(mubi_es_enable_fanout[i]); + end : gen_mubi_en_copies + + caliptra_prim_mubi4_sync #( + .NumCopies(EsEnableCopies), + .AsyncOn(0) + ) u_caliptra_prim_mubi4_sync_es_enable ( + .clk_i, + .rst_ni, + .mubi_i(mubi_es_enable), + .mubi_o(mubi_es_enable_fanout) + ); + + for (genvar i = 0; i < EsEnPulseCopies; i = i+1) begin : gen_mubi_en_pulse_copies + assign module_en_pulse_fo[i] = mubi4_test_true_strict(mubi_module_en_pulse_fanout[i]); + end : gen_mubi_en_pulse_copies + + caliptra_prim_mubi4_sync #( + .NumCopies(EsEnPulseCopies), + .AsyncOn(0) + ) u_caliptra_prim_mubi4_sync_es_enable_pulse ( + .clk_i, + .rst_ni, + .mubi_i(mubi_module_en_pulse), + .mubi_o(mubi_module_en_pulse_fanout) + ); + + entropy_src_enable_delay u_enable_delay ( + .clk_i, + .rst_ni, + .enable_i(es_enable_fo[0]), + .esrng_fifo_not_empty_i(sfifo_esrng_not_empty), + .esbit_fifo_not_empty_i(pfifo_esbit_not_empty), + .postht_fifo_not_empty_i(pfifo_postht_not_empty), + .distr_fifo_not_empty_i(sfifo_distr_not_empty), + .cs_aes_halt_req_i(cs_aes_halt_req), + .sha3_block_processed_i(sha3_block_processed), + .bypass_mode_i(es_bypass_mode), + .enable_o(es_delayed_enable) + ); + + mubi4_t mubi_fips_en; + mubi4_t [1:0] mubi_fips_en_fanout; + assign mubi_fips_en = mubi4_t'(reg2hw.conf.fips_enable.q); + assign fips_enable_pfe = mubi4_test_true_strict(mubi_fips_en_fanout[0]); + assign fips_enable_pfa = mubi4_test_invalid(mubi_fips_en_fanout[1]); + assign hw2reg.recov_alert_sts.fips_enable_field_alert.de = fips_enable_pfa; + assign hw2reg.recov_alert_sts.fips_enable_field_alert.d = fips_enable_pfa; + + caliptra_prim_mubi4_sync #( + .NumCopies(2), + .AsyncOn(0) + ) u_caliptra_prim_mubi4_sync_entropy_fips_en ( + .clk_i, + .rst_ni, + .mubi_i(mubi_fips_en), + .mubi_o(mubi_fips_en_fanout) + ); + + mubi4_t mubi_fips_flag; + mubi4_t [1:0] mubi_fips_flag_fanout; + assign mubi_fips_flag = mubi4_t'(reg2hw.conf.fips_flag.q); + assign fips_flag_pfa = mubi4_test_invalid(mubi_fips_flag_fanout[1]); + assign fips_flag_pfe = mubi4_test_true_strict(mubi_fips_flag_fanout[0]); + assign hw2reg.recov_alert_sts.fips_flag_field_alert.de = fips_flag_pfa; + assign hw2reg.recov_alert_sts.fips_flag_field_alert.d = fips_flag_pfa; + + caliptra_prim_mubi4_sync #( + .NumCopies(2), + .AsyncOn(0) + ) u_caliptra_prim_mubi4_sync_entropy_fips_flag ( + .clk_i, + .rst_ni, + .mubi_i(mubi_fips_flag), + .mubi_o(mubi_fips_flag_fanout) + ); + + mubi4_t mubi_rng_fips; + mubi4_t [1:0] mubi_rng_fips_fanout; + assign mubi_rng_fips = mubi4_t'(reg2hw.conf.rng_fips.q); + assign rng_fips_pfa = mubi4_test_invalid(mubi_rng_fips_fanout[1]); + assign rng_fips_pfe = caliptra_prim_mubi_pkg::mubi4_test_true_loose(mubi_rng_fips_fanout[0]); + assign hw2reg.recov_alert_sts.rng_fips_field_alert.de = rng_fips_pfa; + assign hw2reg.recov_alert_sts.rng_fips_field_alert.d = rng_fips_pfa; + + caliptra_prim_mubi4_sync #( + .NumCopies(2), + .AsyncOn(0) + ) u_caliptra_prim_mubi4_sync_entropy_rng_fips ( + .clk_i, + .rst_ni, + .mubi_i(mubi_rng_fips), + .mubi_o(mubi_rng_fips_fanout) + ); + + // SEC_CM: CONFIG.MUBI + mubi4_t mubi_entropy_reg_en; + mubi4_t [1:0] mubi_entropy_reg_en_fanout; + assign mubi_entropy_reg_en = mubi4_t'(reg2hw.conf.entropy_data_reg_enable.q); + assign entropy_data_reg_en_pfe = mubi4_test_true_strict(mubi_entropy_reg_en_fanout[0]); + assign entropy_data_reg_en_pfa = mubi4_test_invalid(mubi_entropy_reg_en_fanout[1]); + assign hw2reg.recov_alert_sts.entropy_data_reg_en_field_alert.de = entropy_data_reg_en_pfa; + assign hw2reg.recov_alert_sts.entropy_data_reg_en_field_alert.d = entropy_data_reg_en_pfa; + + caliptra_prim_mubi4_sync #( + .NumCopies(2), + .AsyncOn(0) + ) u_caliptra_prim_mubi4_sync_entropy_data_reg_en ( + .clk_i, + .rst_ni, + .mubi_i(mubi_entropy_reg_en), + .mubi_o(mubi_entropy_reg_en_fanout) + ); + + assign observe_fifo_thresh = reg2hw.observe_fifo_thresh.q; + + // SEC_CM: CONFIG.MUBI + mubi4_t mubi_fw_ov_mode; + mubi4_t [1:0] mubi_fw_ov_mode_fanout; + assign mubi_fw_ov_mode = mubi4_t'(reg2hw.fw_ov_control.fw_ov_mode.q); + assign fw_ov_mode_pfe = mubi4_test_true_strict(mubi_fw_ov_mode_fanout[0]); + assign fw_ov_mode_pfa = mubi4_test_invalid(mubi_fw_ov_mode_fanout[1]); + assign hw2reg.recov_alert_sts.fw_ov_mode_field_alert.de = fw_ov_mode_pfa; + assign hw2reg.recov_alert_sts.fw_ov_mode_field_alert.d = fw_ov_mode_pfa; + + caliptra_prim_mubi4_sync #( + .NumCopies(2), + .AsyncOn(0) + ) u_caliptra_prim_mubi4_sync_fw_ov_mode ( + .clk_i, + .rst_ni, + .mubi_i(mubi_fw_ov_mode), + .mubi_o(mubi_fw_ov_mode_fanout) + ); + + // SEC_CM: CONFIG.MUBI + mubi4_t mubi_fw_ov_entropy_insert; + mubi4_t [1:0] mubi_fw_ov_entropy_insert_fanout; + assign mubi_fw_ov_entropy_insert = mubi4_t'(reg2hw.fw_ov_control.fw_ov_entropy_insert.q); + assign fw_ov_entropy_insert_pfe = mubi4_test_true_strict(mubi_fw_ov_entropy_insert_fanout[0]); + assign fw_ov_entropy_insert_pfa = mubi4_test_invalid(mubi_fw_ov_entropy_insert_fanout[1]); + assign hw2reg.recov_alert_sts.fw_ov_entropy_insert_field_alert.de = fw_ov_entropy_insert_pfa; + assign hw2reg.recov_alert_sts.fw_ov_entropy_insert_field_alert.d = fw_ov_entropy_insert_pfa; + + caliptra_prim_mubi4_sync #( + .NumCopies(2), + .AsyncOn(0) + ) u_caliptra_prim_mubi4_sync_fw_ov_entropy_insert ( + .clk_i, + .rst_ni, + .mubi_i(mubi_fw_ov_entropy_insert), + .mubi_o(mubi_fw_ov_entropy_insert_fanout) + ); + + // SEC_CM: CONFIG.MUBI + mubi4_t mubi_fw_ov_sha3_start; + mubi4_t [1:0] mubi_fw_ov_sha3_start_fanout; + assign mubi_fw_ov_sha3_start = mubi4_t'(reg2hw.fw_ov_sha3_start.q); + assign fw_ov_sha3_start_pfe = mubi4_test_true_strict(mubi_fw_ov_sha3_start_fanout[0]); + assign fw_ov_sha3_start_pfa = mubi4_test_invalid(mubi_fw_ov_sha3_start_fanout[1]); + assign hw2reg.recov_alert_sts.fw_ov_sha3_start_field_alert.de = fw_ov_sha3_start_pfa; + assign hw2reg.recov_alert_sts.fw_ov_sha3_start_field_alert.d = fw_ov_sha3_start_pfa; + + caliptra_prim_mubi4_sync #( + .NumCopies(2), + .AsyncOn(0) + ) u_caliptra_prim_mubi4_sync_fw_ov_sha3_start ( + .clk_i, + .rst_ni, + .mubi_i(mubi_fw_ov_sha3_start), + .mubi_o(mubi_fw_ov_sha3_start_fanout) + ); + + // firmware override controls + assign fw_ov_mode = efuse_es_sw_ov_en && fw_ov_mode_pfe; + assign fw_ov_mode_entropy_insert = fw_ov_mode && fw_ov_entropy_insert_pfe; + assign fw_ov_fifo_rd_pulse = reg2hw.fw_ov_rd_data.re; + assign hw2reg.fw_ov_rd_data.d = sfifo_observe_rdata; + assign fw_ov_fifo_wr_pulse = reg2hw.fw_ov_wr_data.qe; + assign fw_ov_wr_data = reg2hw.fw_ov_wr_data.q; + + assign efuse_es_sw_ov_en = caliptra_prim_mubi_pkg::mubi8_test_true_strict(en_entropy_src_fw_over); + + caliptra_prim_mubi8_sync #( + .NumCopies(1), + .AsyncOn(1) // must be set to one, see note below + ) u_caliptra_prim_mubi8_sync_es_fw_over ( + .clk_i, + .rst_ni, + .mubi_i(otp_en_entropy_src_fw_over_i), + .mubi_o({en_entropy_src_fw_over}) + ); + + // note: the input to the above sync module is from the OTP block. + // It is assumed that the source is in a different time domain, + // and requires the AsyncOn parameter to be set. + + // rng_enable is being used in other clock domains. Need to latch the + // signal. + assign rng_enable_d = es_enable_fo[1] && + es_delayed_enable; + + assign entropy_src_rng_o.rng_enable = rng_enable_q; + + assign es_rng_src_valid = entropy_src_rng_i.rng_valid; + assign es_rng_bus = entropy_src_rng_i.rng_b; + + + //-------------------------------------------- + // instantiate interrupt hardware primitives + //-------------------------------------------- + + caliptra_prim_intr_hw #( + .Width(1) + ) u_intr_hw_es_entropy_valid ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .event_intr_i (event_es_entropy_valid), + .reg2hw_intr_enable_q_i (reg2hw.intr_enable.es_entropy_valid.q), + .reg2hw_intr_test_q_i (reg2hw.intr_test.es_entropy_valid.q), + .reg2hw_intr_test_qe_i (reg2hw.intr_test.es_entropy_valid.qe), + .reg2hw_intr_state_q_i (reg2hw.intr_state.es_entropy_valid.q), + .hw2reg_intr_state_de_o (hw2reg.intr_state.es_entropy_valid.de), + .hw2reg_intr_state_d_o (hw2reg.intr_state.es_entropy_valid.d), + .intr_o (intr_es_entropy_valid_o) + ); + + caliptra_prim_intr_hw #( + .Width(1) + ) u_intr_hw_es_health_test_failed ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .event_intr_i (event_es_health_test_failed), + .reg2hw_intr_enable_q_i (reg2hw.intr_enable.es_health_test_failed.q), + .reg2hw_intr_test_q_i (reg2hw.intr_test.es_health_test_failed.q), + .reg2hw_intr_test_qe_i (reg2hw.intr_test.es_health_test_failed.qe), + .reg2hw_intr_state_q_i (reg2hw.intr_state.es_health_test_failed.q), + .hw2reg_intr_state_de_o (hw2reg.intr_state.es_health_test_failed.de), + .hw2reg_intr_state_d_o (hw2reg.intr_state.es_health_test_failed.d), + .intr_o (intr_es_health_test_failed_o) + ); + + + caliptra_prim_intr_hw #( + .Width(1) + ) u_intr_hw_es_observe_fifo_ready ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .event_intr_i (event_es_observe_fifo_ready), + .reg2hw_intr_enable_q_i (reg2hw.intr_enable.es_observe_fifo_ready.q), + .reg2hw_intr_test_q_i (reg2hw.intr_test.es_observe_fifo_ready.q), + .reg2hw_intr_test_qe_i (reg2hw.intr_test.es_observe_fifo_ready.qe), + .reg2hw_intr_state_q_i (reg2hw.intr_state.es_observe_fifo_ready.q), + .hw2reg_intr_state_de_o (hw2reg.intr_state.es_observe_fifo_ready.de), + .hw2reg_intr_state_d_o (hw2reg.intr_state.es_observe_fifo_ready.d), + .intr_o (intr_es_observe_fifo_ready_o) + ); + + caliptra_prim_intr_hw #( + .Width(1) + ) u_intr_hw_es_fatal_err ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .event_intr_i (event_es_fatal_err), + .reg2hw_intr_enable_q_i (reg2hw.intr_enable.es_fatal_err.q), + .reg2hw_intr_test_q_i (reg2hw.intr_test.es_fatal_err.q), + .reg2hw_intr_test_qe_i (reg2hw.intr_test.es_fatal_err.qe), + .reg2hw_intr_state_q_i (reg2hw.intr_state.es_fatal_err.q), + .hw2reg_intr_state_de_o (hw2reg.intr_state.es_fatal_err.de), + .hw2reg_intr_state_d_o (hw2reg.intr_state.es_fatal_err.d), + .intr_o (intr_es_fatal_err_o) + ); + + //-------------------------------------------- + // tlul register settings + //-------------------------------------------- + + + // set the interrupt event when enabled + assign event_es_entropy_valid = + sfifo_esfinal_not_empty && es_route_to_sw && es_data_reg_rd_en && es_enable_fo[2]; + + + // Collect all internal FIFO errors. + assign es_sfifo_int_err = sfifo_esrng_int_err || + sfifo_distr_int_err || + sfifo_observe_int_err || + sfifo_esfinal_int_err; + + // Counter, internal FIFO errors and FSM errors are structural errors and are always active + // regardless of the functional state. + logic fatal_loc_events; + assign fatal_loc_events = es_cntr_err_sum || + es_sfifo_int_err || + es_main_sm_err_sum || + es_ack_sm_err_sum || + sha3_state_error_sum; + + // set the interrupt sources + assign event_es_fatal_err = (es_enable_fo[3] && + (sfifo_esrng_err_sum || + sfifo_distr_err_sum || + sfifo_observe_err_sum || + sfifo_esfinal_err_sum || + sfifo_test_err_sum) ) || + sha3_rst_storage_err_sum || + fatal_loc_events; + + // set fifo errors that are single instances of source + assign sfifo_esrng_err_sum = (|sfifo_esrng_err) || + err_code_test_bit[0]; + assign sfifo_distr_err_sum = (|sfifo_distr_err) || + err_code_test_bit[1]; + assign sfifo_observe_err_sum = (|sfifo_observe_err) || + err_code_test_bit[2]; + assign sfifo_esfinal_err_sum = (|sfifo_esfinal_err) || + err_code_test_bit[3]; + + // The following test bits help normally diagnose the _type_ of + // error when they are triggred by the fifo. However when + // they are triggered by softwre they are not linked to a + // particular sfifo and do not trigger an alert, unless + // we capture them here. + assign sfifo_test_err_sum = err_code_test_bit[28] || + err_code_test_bit[29] || + err_code_test_bit[30]; + + assign es_ack_sm_err_sum = es_ack_sm_err || + err_code_test_bit[20]; + assign es_main_sm_err_sum = es_main_sm_err || + err_code_test_bit[21]; + assign es_cntr_err_sum = es_cntr_err || + err_code_test_bit[22]; + assign sha3_state_error_sum = sha3_state_error || + err_code_test_bit[23]; + assign sha3_rst_storage_err_sum = sha3_rst_storage_err || + err_code_test_bit[24]; + assign fifo_write_err_sum = + sfifo_esrng_err[2] || + sfifo_observe_err[2] || + sfifo_esfinal_err[2] || + err_code_test_bit[28]; + assign fifo_read_err_sum = + sfifo_esrng_err[1] || + sfifo_observe_err[1] || + sfifo_esfinal_err[1] || + err_code_test_bit[29]; + assign fifo_status_err_sum = + sfifo_esrng_err[0] || + sfifo_observe_err[0] || + sfifo_esfinal_err[0] || + err_code_test_bit[30]; + + // set the err code source bits + assign hw2reg.err_code.sfifo_esrng_err.d = 1'b1; + assign hw2reg.err_code.sfifo_esrng_err.de = sfifo_esrng_err_sum; + + assign hw2reg.err_code.sfifo_distr_err.d = 1'b1; + assign hw2reg.err_code.sfifo_distr_err.de = sfifo_distr_err_sum; + + assign hw2reg.err_code.sfifo_observe_err.d = 1'b1; + assign hw2reg.err_code.sfifo_observe_err.de = sfifo_observe_err_sum; + + assign hw2reg.err_code.sfifo_esfinal_err.d = 1'b1; + assign hw2reg.err_code.sfifo_esfinal_err.de = sfifo_esfinal_err_sum; + + assign hw2reg.err_code.es_ack_sm_err.d = 1'b1; + assign hw2reg.err_code.es_ack_sm_err.de = es_ack_sm_err_sum; + + assign hw2reg.err_code.es_main_sm_err.d = 1'b1; + assign hw2reg.err_code.es_main_sm_err.de = es_main_sm_err_sum; + + assign hw2reg.err_code.es_cntr_err.d = 1'b1; + assign hw2reg.err_code.es_cntr_err.de = es_cntr_err_sum; + + assign hw2reg.err_code.sha3_state_err.d = 1'b1; + assign hw2reg.err_code.sha3_state_err.de = sha3_state_error_sum; + + assign hw2reg.err_code.sha3_rst_storage_err.d = 1'b1; + assign hw2reg.err_code.sha3_rst_storage_err.de = sha3_rst_storage_err_sum; + + + // set the err code type bits + assign hw2reg.err_code.fifo_write_err.d = 1'b1; + assign hw2reg.err_code.fifo_write_err.de = fifo_write_err_sum; + + assign hw2reg.err_code.fifo_read_err.d = 1'b1; + assign hw2reg.err_code.fifo_read_err.de = fifo_read_err_sum; + + assign hw2reg.err_code.fifo_state_err.d = 1'b1; + assign hw2reg.err_code.fifo_state_err.de = fifo_status_err_sum; + + // Error forcing + for (genvar i = 0; i < 31; i = i+1) begin : gen_err_code_test_bit + assign err_code_test_bit[i] = (reg2hw.err_code_test.q == i) && reg2hw.err_code_test.qe; + end : gen_err_code_test_bit + + // alert - send all interrupt sources to the alert for the fatal case + assign fatal_alert_o = (event_es_fatal_err | + sfifo_distr_int_err | sfifo_esrng_int_err | + sfifo_observe_int_err | sfifo_esfinal_int_err); + + // alert test + assign recov_alert_test_o = { + reg2hw.alert_test.recov_alert.q && + reg2hw.alert_test.recov_alert.qe + }; + assign fatal_alert_test_o = { + reg2hw.alert_test.fatal_alert.q && + reg2hw.alert_test.fatal_alert.qe + }; + + + // set the debug status reg + assign hw2reg.debug_status.entropy_fifo_depth.d = sfifo_esfinal_depth; + assign hw2reg.debug_status.sha3_fsm.d = sha3_fsm; + assign hw2reg.debug_status.sha3_block_pr.d = sha3_block_processed; + assign hw2reg.debug_status.sha3_squeezing.d = sha3_squeezing; + assign hw2reg.debug_status.sha3_absorbed.d = + caliptra_prim_mubi_pkg::mubi4_test_true_strict(sha3_absorbed) ? 1'b 1 : 1'b 0; + assign hw2reg.debug_status.sha3_err.d = sha3_err_q; + + assign sha3_err_d = + es_enable_fo[4] ? 1'b0 : + {|sha3_err} ? 1'b1 : + sha3_err_q; + + // state machine status + assign hw2reg.debug_status.main_sm_idle.d = es_main_sm_idle; + assign hw2reg.debug_status.main_sm_boot_done.d = boot_phase_done; + assign hw2reg.main_sm_state.de = 1'b1; + assign hw2reg.main_sm_state.d = es_main_sm_state; + + // fw override wr data status indication + assign fw_ov_wr_fifo_full = fw_ov_mode_entropy_insert && + (es_bypass_mode ? !pfifo_bypass_not_full : !pfifo_precon_not_full); + + assign hw2reg.fw_ov_wr_fifo_full.d = fw_ov_wr_fifo_full; + + + //-------------------------------------------- + // receive in RNG bus input + //-------------------------------------------- + + // SEC_CM: FIFO.CTR.REDUN + caliptra_prim_fifo_sync #( + .Width(RngBusWidth), + .Pass(0), + .Depth(2), + .OutputZeroIfEmpty(0), + .Secure(1) + ) u_caliptra_prim_fifo_sync_esrng ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .clr_i (sfifo_esrng_clr), + .wvalid_i (sfifo_esrng_push), + .wdata_i (sfifo_esrng_wdata), + .wready_o (sfifo_esrng_not_full), + .rvalid_o (sfifo_esrng_not_empty), + .rdata_o (sfifo_esrng_rdata), + .rready_i (sfifo_esrng_pop), + .full_o (sfifo_esrng_full), + .depth_o (), + .err_o (sfifo_esrng_int_err) + ); + + // fifo controls + // We can't handle any backpressure at this point. Unless the ENTROPY_SRC block is turned off, + // the input coming from the noise source / RNG needs to be accepted without dropping samples. + assign sfifo_esrng_push = es_enable_fo[5] && es_delayed_enable && es_rng_src_valid && + rng_enable_q; + + assign sfifo_esrng_clr = ~es_delayed_enable; + assign sfifo_esrng_wdata = es_rng_bus; + // We can't apply any backpressure at this point. Every sample is presented to the health tests + // for exactly one clock cycle. If the receiving FIFO is full, the sample is dropped but the + // health tests are still performed and the results accumulated. + assign sfifo_esrng_pop = sfifo_esrng_not_empty; + + // fifo err + // The esnrg FIFO must never be pushed when it's full as no backpressure can be applied to the + // noise source / RNG. However, we can't raise an error and abort operation of the ENTROPY_SRC + // block as this would mean a catastrophic failure of the whole chip. Instead we need to catch + // this in simulation only. + assign sfifo_esrng_err = + {1'b0, + (sfifo_esrng_pop && !sfifo_esrng_not_empty), + (sfifo_esrng_full && !sfifo_esrng_not_empty) || sfifo_esrng_int_err}; + `CALIPTRA_ASSERT(RngBackpressureNotAllowed_A, sfifo_esrng_push |-> sfifo_esrng_not_full) + + // Read the health test data from the esrng FIFO. + assign health_test_esbus = sfifo_esrng_rdata; + // Perform the health tests whenever data is valid and the receiving FIFO is not being cleared. + // This doesn't mean the receiving FIFO is pushed. The receiving FIFO is only pushed if it has + // indeed space. This means in case of heavy backpressure, we keep testing the noise source + // samples, but we drop them before the postht FIFO. If this happens, the window counter isn't + // incremented. This way we can keep the number of bits going into the conditioner constant, + // independent of potential backpressure within the pipeline. + assign health_test_esbus_vld = + rng_bit_en ? sfifo_esrng_not_empty && !pfifo_esbit_clr : + sfifo_esrng_not_empty && !pfifo_postht_clr; + + // Health test any data that comes in on the RNG interface. + assign repcnt_active = 1'b1; + assign repcnts_active = 1'b1; + assign adaptp_active = 1'b1; + assign bucket_active = 1'b1; + assign markov_active = 1'b1; + assign extht_active = 1'b1; + + // Only reset health tests on re-enable + assign health_test_clr = module_en_pulse_fo[0]; + + assign health_test_fips_window = reg2hw.health_test_windows.fips_window.q; + assign health_test_bypass_window = reg2hw.health_test_windows.bypass_window.q; + + assign repcnt_fips_threshold = reg2hw.repcnt_thresholds.fips_thresh.q; + assign repcnt_fips_threshold_wr = reg2hw.repcnt_thresholds.fips_thresh.qe; + assign hw2reg.repcnt_thresholds.fips_thresh.d = repcnt_fips_threshold_oneway; + assign repcnt_bypass_threshold = reg2hw.repcnt_thresholds.bypass_thresh.q; + assign repcnt_bypass_threshold_wr = reg2hw.repcnt_thresholds.bypass_thresh.qe; + assign hw2reg.repcnt_thresholds.bypass_thresh.d = repcnt_bypass_threshold_oneway; + + assign repcnts_fips_threshold = reg2hw.repcnts_thresholds.fips_thresh.q; + assign repcnts_fips_threshold_wr = reg2hw.repcnts_thresholds.fips_thresh.qe; + assign hw2reg.repcnts_thresholds.fips_thresh.d = repcnts_fips_threshold_oneway; + assign repcnts_bypass_threshold = reg2hw.repcnts_thresholds.bypass_thresh.q; + assign repcnts_bypass_threshold_wr = reg2hw.repcnts_thresholds.bypass_thresh.qe; + assign hw2reg.repcnts_thresholds.bypass_thresh.d = repcnts_bypass_threshold_oneway; + + + assign adaptp_hi_fips_threshold = reg2hw.adaptp_hi_thresholds.fips_thresh.q; + assign adaptp_hi_fips_threshold_wr = reg2hw.adaptp_hi_thresholds.fips_thresh.qe; + assign hw2reg.adaptp_hi_thresholds.fips_thresh.d = adaptp_hi_fips_threshold_oneway; + assign adaptp_hi_bypass_threshold = reg2hw.adaptp_hi_thresholds.bypass_thresh.q; + assign adaptp_hi_bypass_threshold_wr = reg2hw.adaptp_hi_thresholds.bypass_thresh.qe; + assign hw2reg.adaptp_hi_thresholds.bypass_thresh.d = adaptp_hi_bypass_threshold_oneway; + + assign adaptp_lo_fips_threshold = reg2hw.adaptp_lo_thresholds.fips_thresh.q; + assign adaptp_lo_fips_threshold_wr = reg2hw.adaptp_lo_thresholds.fips_thresh.qe; + assign hw2reg.adaptp_lo_thresholds.fips_thresh.d = adaptp_lo_fips_threshold_oneway; + assign adaptp_lo_bypass_threshold = reg2hw.adaptp_lo_thresholds.bypass_thresh.q; + assign adaptp_lo_bypass_threshold_wr = reg2hw.adaptp_lo_thresholds.bypass_thresh.qe; + assign hw2reg.adaptp_lo_thresholds.bypass_thresh.d = adaptp_lo_bypass_threshold_oneway; + + + assign bucket_fips_threshold = reg2hw.bucket_thresholds.fips_thresh.q; + assign bucket_fips_threshold_wr = reg2hw.bucket_thresholds.fips_thresh.qe; + assign hw2reg.bucket_thresholds.fips_thresh.d = bucket_fips_threshold_oneway; + assign bucket_bypass_threshold = reg2hw.bucket_thresholds.bypass_thresh.q; + assign bucket_bypass_threshold_wr = reg2hw.bucket_thresholds.bypass_thresh.qe; + assign hw2reg.bucket_thresholds.bypass_thresh.d = bucket_bypass_threshold_oneway; + + + assign markov_hi_fips_threshold = reg2hw.markov_hi_thresholds.fips_thresh.q; + assign markov_hi_fips_threshold_wr = reg2hw.markov_hi_thresholds.fips_thresh.qe; + assign hw2reg.markov_hi_thresholds.fips_thresh.d = markov_hi_fips_threshold_oneway; + assign markov_hi_bypass_threshold = reg2hw.markov_hi_thresholds.bypass_thresh.q; + assign markov_hi_bypass_threshold_wr = reg2hw.markov_hi_thresholds.bypass_thresh.qe; + assign hw2reg.markov_hi_thresholds.bypass_thresh.d = markov_hi_bypass_threshold_oneway; + + assign markov_lo_fips_threshold = reg2hw.markov_lo_thresholds.fips_thresh.q; + assign markov_lo_fips_threshold_wr = reg2hw.markov_lo_thresholds.fips_thresh.qe; + assign hw2reg.markov_lo_thresholds.fips_thresh.d = markov_lo_fips_threshold_oneway; + assign markov_lo_bypass_threshold = reg2hw.markov_lo_thresholds.bypass_thresh.q; + assign markov_lo_bypass_threshold_wr = reg2hw.markov_lo_thresholds.bypass_thresh.qe; + assign hw2reg.markov_lo_thresholds.bypass_thresh.d = markov_lo_bypass_threshold_oneway; + + + assign extht_hi_fips_threshold = reg2hw.extht_hi_thresholds.fips_thresh.q; + assign extht_hi_fips_threshold_wr = reg2hw.extht_hi_thresholds.fips_thresh.qe; + assign hw2reg.extht_hi_thresholds.fips_thresh.d = extht_hi_fips_threshold_oneway; + assign extht_hi_bypass_threshold = reg2hw.extht_hi_thresholds.bypass_thresh.q; + assign extht_hi_bypass_threshold_wr = reg2hw.extht_hi_thresholds.bypass_thresh.qe; + assign hw2reg.extht_hi_thresholds.bypass_thresh.d = extht_hi_bypass_threshold_oneway; + + assign extht_lo_fips_threshold = reg2hw.extht_lo_thresholds.fips_thresh.q; + assign extht_lo_fips_threshold_wr = reg2hw.extht_lo_thresholds.fips_thresh.qe; + assign hw2reg.extht_lo_thresholds.fips_thresh.d = extht_lo_fips_threshold_oneway; + assign extht_lo_bypass_threshold = reg2hw.extht_lo_thresholds.bypass_thresh.q; + assign extht_lo_bypass_threshold_wr = reg2hw.extht_lo_thresholds.bypass_thresh.qe; + assign hw2reg.extht_lo_thresholds.bypass_thresh.d = extht_lo_bypass_threshold_oneway; + + + assign health_test_window = es_bypass_mode ? health_test_bypass_window : health_test_fips_window; + // Multiply the health test window by four if we are using the single lane mode. + // In single lane mode 4 times as many symbols are tested for the same amount of entropy. + assign health_test_window_scaled = rng_bit_en ? {health_test_window, 2'b0} : + {2'b0, health_test_window}; + + // Window sizes other than 384 bits (the seed length) are currently not tested nor supported in + // bypass or boot-time mode. + `CALIPTRA_ASSERT(EsBootTimeHtWindowSizeSupported_A, + main_sm_enable && es_bypass_mode && !fw_ov_mode_entropy_insert + |-> health_test_bypass_window == HalfRegWidth'(SeedLen/4)) + + //------------------------------ + // repcnt one-way thresholds + //------------------------------ + assign repcnt_threshold = es_bypass_mode ? repcnt_bypass_threshold_oneway : + repcnt_fips_threshold_oneway; + + entropy_src_watermark_reg #( + .RegWidth(HalfRegWidth), + .HighWatermark(0) + ) u_entropy_src_watermark_reg_repcnt_thresh_fips ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .clear_i (1'b0), + .event_i (repcnt_fips_threshold_wr), + .value_i (repcnt_fips_threshold), + .value_o (repcnt_fips_threshold_oneway) + ); + + entropy_src_watermark_reg #( + .RegWidth(HalfRegWidth), + .HighWatermark(0) + ) u_entropy_src_watermark_reg_repcnt_thresh_bypass ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .clear_i (1'b0), + .event_i (repcnt_bypass_threshold_wr), + .value_i (repcnt_bypass_threshold), + .value_o (repcnt_bypass_threshold_oneway) + ); + + //------------------------------ + // repcnts one-way thresholds + //------------------------------ + assign repcnts_threshold = es_bypass_mode ? repcnts_bypass_threshold_oneway : + repcnts_fips_threshold_oneway; + + entropy_src_watermark_reg #( + .RegWidth(HalfRegWidth), + .HighWatermark(0) + ) u_entropy_src_watermark_reg_repcnts_thresh_fips ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .clear_i (1'b0), + .event_i (repcnts_fips_threshold_wr), + .value_i (repcnts_fips_threshold), + .value_o (repcnts_fips_threshold_oneway) + ); + + entropy_src_watermark_reg #( + .RegWidth(HalfRegWidth), + .HighWatermark(0) + ) u_entropy_src_watermark_reg_repcnts_thresh_bypass ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .clear_i (1'b0), + .event_i (repcnts_bypass_threshold_wr), + .value_i (repcnts_bypass_threshold), + .value_o (repcnts_bypass_threshold_oneway) + ); + + + //------------------------------ + // adaptp one-way thresholds + //------------------------------ + assign adaptp_hi_threshold = es_bypass_mode ? adaptp_hi_bypass_threshold_oneway : + adaptp_hi_fips_threshold_oneway; + + entropy_src_watermark_reg #( + .RegWidth(HalfRegWidth), + .HighWatermark(0) + ) u_entropy_src_watermark_reg_adaptp_hi_thresh_fips ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .clear_i (1'b0), + .event_i (adaptp_hi_fips_threshold_wr), + .value_i (adaptp_hi_fips_threshold), + .value_o (adaptp_hi_fips_threshold_oneway) + ); + + entropy_src_watermark_reg #( + .RegWidth(HalfRegWidth), + .HighWatermark(0) + ) u_entropy_src_watermark_reg_adaptp_hi_thresh_bypass ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .clear_i (1'b0), + .event_i (adaptp_hi_bypass_threshold_wr), + .value_i (adaptp_hi_bypass_threshold), + .value_o (adaptp_hi_bypass_threshold_oneway) + ); + + assign adaptp_lo_threshold = es_bypass_mode ? adaptp_lo_bypass_threshold_oneway : + adaptp_lo_fips_threshold_oneway; + + entropy_src_watermark_reg #( + .RegWidth(HalfRegWidth), + .HighWatermark(1) + ) u_entropy_src_watermark_reg_adaptp_lo_thresh_fips ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .clear_i (1'b0), + .event_i (adaptp_lo_fips_threshold_wr), + .value_i (adaptp_lo_fips_threshold), + .value_o (adaptp_lo_fips_threshold_oneway) + ); + + entropy_src_watermark_reg #( + .RegWidth(HalfRegWidth), + .HighWatermark(1) + ) u_entropy_src_watermark_reg_adaptp_lo_thresh_bypass ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .clear_i (1'b0), + .event_i (adaptp_lo_bypass_threshold_wr), + .value_i (adaptp_lo_bypass_threshold), + .value_o (adaptp_lo_bypass_threshold_oneway) + ); + + + //------------------------------ + // bucket one-way thresholds + //------------------------------ + assign bucket_threshold = es_bypass_mode ? bucket_bypass_threshold_oneway : + bucket_fips_threshold_oneway; + + entropy_src_watermark_reg #( + .RegWidth(HalfRegWidth), + .HighWatermark(0) + ) u_entropy_src_watermark_reg_bucket_thresh_fips ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .clear_i (1'b0), + .event_i (bucket_fips_threshold_wr), + .value_i (bucket_fips_threshold), + .value_o (bucket_fips_threshold_oneway) + ); + + entropy_src_watermark_reg #( + .RegWidth(HalfRegWidth), + .HighWatermark(0) + ) u_entropy_src_watermark_reg_bucket_thresh_bypass ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .clear_i (1'b0), + .event_i (bucket_bypass_threshold_wr), + .value_i (bucket_bypass_threshold), + .value_o (bucket_bypass_threshold_oneway) + ); + + + //------------------------------ + // markov one-way thresholds + //------------------------------ + assign markov_hi_threshold = es_bypass_mode ? markov_hi_bypass_threshold_oneway : + markov_hi_fips_threshold_oneway; + + entropy_src_watermark_reg #( + .RegWidth(HalfRegWidth), + .HighWatermark(0) + ) u_entropy_src_watermark_reg_markov_hi_thresh_fips ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .clear_i (1'b0), + .event_i (markov_hi_fips_threshold_wr), + .value_i (markov_hi_fips_threshold), + .value_o (markov_hi_fips_threshold_oneway) + ); + + entropy_src_watermark_reg #( + .RegWidth(HalfRegWidth), + .HighWatermark(0) + ) u_entropy_src_watermark_reg_markov_hi_thresh_bypass ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .clear_i (1'b0), + .event_i (markov_hi_bypass_threshold_wr), + .value_i (markov_hi_bypass_threshold), + .value_o (markov_hi_bypass_threshold_oneway) + ); + + assign markov_lo_threshold = es_bypass_mode ? markov_lo_bypass_threshold_oneway : + markov_lo_fips_threshold_oneway; + + entropy_src_watermark_reg #( + .RegWidth(HalfRegWidth), + .HighWatermark(1) + ) u_entropy_src_watermark_reg_markov_lo_thresh_fips ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .clear_i (1'b0), + .event_i (markov_lo_fips_threshold_wr), + .value_i (markov_lo_fips_threshold), + .value_o (markov_lo_fips_threshold_oneway) + ); + + entropy_src_watermark_reg #( + .RegWidth(HalfRegWidth), + .HighWatermark(1) + ) u_entropy_src_watermark_reg_markov_lo_thresh_bypass ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .clear_i (1'b0), + .event_i (markov_lo_bypass_threshold_wr), + .value_i (markov_lo_bypass_threshold), + .value_o (markov_lo_bypass_threshold_oneway) + ); + + + //------------------------------ + // extht one-way thresholds + //------------------------------ + assign extht_hi_threshold = es_bypass_mode ? extht_hi_bypass_threshold_oneway : + extht_hi_fips_threshold_oneway; + + entropy_src_watermark_reg #( + .RegWidth(HalfRegWidth), + .HighWatermark(0) + ) u_entropy_src_watermark_reg_extht_hi_thresh_fips ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .clear_i (1'b0), + .event_i (extht_hi_fips_threshold_wr), + .value_i (extht_hi_fips_threshold), + .value_o (extht_hi_fips_threshold_oneway) + ); + + entropy_src_watermark_reg #( + .RegWidth(HalfRegWidth), + .HighWatermark(0) + ) u_entropy_src_watermark_reg_extht_hi_thresh_bypass ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .clear_i (1'b0), + .event_i (extht_hi_bypass_threshold_wr), + .value_i (extht_hi_bypass_threshold), + .value_o (extht_hi_bypass_threshold_oneway) + ); + + + assign extht_lo_threshold = es_bypass_mode ? extht_lo_bypass_threshold_oneway : + extht_lo_fips_threshold_oneway; + + entropy_src_watermark_reg #( + .RegWidth(HalfRegWidth), + .HighWatermark(1) + ) u_entropy_src_watermark_reg_extht_lo_thresh_fips ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .clear_i (1'b0), + .event_i (extht_lo_fips_threshold_wr), + .value_i (extht_lo_fips_threshold), + .value_o (extht_lo_fips_threshold_oneway) + ); + + entropy_src_watermark_reg #( + .RegWidth(HalfRegWidth), + .HighWatermark(1) + ) u_entropy_src_watermark_reg_extht_lo_thresh_bypass ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .clear_i (1'b0), + .event_i (extht_lo_bypass_threshold_wr), + .value_i (extht_lo_bypass_threshold), + .value_o (extht_lo_bypass_threshold_oneway) + ); + + + + //------------------------------ + // misc control settings + //------------------------------ + + assign event_es_health_test_failed = es_main_sm_alert; + + assign event_es_observe_fifo_ready = observe_fifo_thresh_met; + + // SEC_CM: CONFIG.MUBI + mubi4_t mubi_es_route; + mubi4_t [1:0] mubi_es_route_fanout; + assign mubi_es_route = mubi4_t'(reg2hw.entropy_control.es_route.q); + assign es_route_pfe = mubi4_test_true_strict(mubi_es_route_fanout[0]); + assign es_route_pfa = mubi4_test_invalid(mubi_es_route_fanout[1]); + assign hw2reg.recov_alert_sts.es_route_field_alert.de = es_route_pfa; + assign hw2reg.recov_alert_sts.es_route_field_alert.d = es_route_pfa; + + caliptra_prim_mubi4_sync #( + .NumCopies(2), + .AsyncOn(0) + ) u_caliptra_prim_mubi4_sync_es_route ( + .clk_i, + .rst_ni, + .mubi_i(mubi_es_route), + .mubi_o(mubi_es_route_fanout) + ); + + // SEC_CM: CONFIG.MUBI + mubi4_t mubi_es_type; + mubi4_t [1:0] mubi_es_type_fanout; + assign mubi_es_type = mubi4_t'(reg2hw.entropy_control.es_type.q); + assign es_type_pfe = mubi4_test_true_strict(mubi_es_type_fanout[0]); + assign es_type_pfa = mubi4_test_invalid(mubi_es_type_fanout[1]); + assign hw2reg.recov_alert_sts.es_type_field_alert.de = es_type_pfa; + assign hw2reg.recov_alert_sts.es_type_field_alert.d = es_type_pfa; + + caliptra_prim_mubi4_sync #( + .NumCopies(2), + .AsyncOn(0) + ) u_caliptra_prim_mubi4_sync_es_type ( + .clk_i, + .rst_ni, + .mubi_i(mubi_es_type), + .mubi_o(mubi_es_type_fanout) + ); + + // SEC_CM: CONFIG.MUBI + mubi4_t mubi_thresh_scope; + assign mubi_thresh_scope = mubi4_t'(reg2hw.conf.threshold_scope.q); + assign threshold_scope_pfe = mubi4_test_true_strict(mubi_thresh_scope); + assign threshold_scope_pfa = mubi4_test_invalid(mubi_thresh_scope); + assign hw2reg.recov_alert_sts.threshold_scope_field_alert.de = threshold_scope_pfa; + assign hw2reg.recov_alert_sts.threshold_scope_field_alert.d = threshold_scope_pfa; + + assign es_route_to_sw = es_route_pfe; + assign es_bypass_to_sw = es_type_pfe; + assign threshold_scope = threshold_scope_pfe; + + // The es_bypass_mode signal determines whether the conditioner is bypassed or not. + // It also determines which thresholds are used and which watermarks are recorded. + // The conditioner can be bypassed by either disabling fips_enable_pfe or by enabling + // both es_bypass_to_sw and es_route_to_sw. + // The combination of es_bypass_to_sw and es_route_to_sw allows for four distinct cases: + // _________________ ________________ + // | | | + // | es_bypass_to_sw | es_route_to_sw | + // |_________________|________________| + // | | | + // | 0 | 0 | In this case the entropy passes through the conditioner + // |_________________|________________| and the entropy is forwarded to the HW endpoints. + // | | | + // | 0 | 1 | In this case the entropy passes through the conditioner + // |_________________|________________| and the entropy is forwarded to software. + // | | | + // | 1 | 0 | In this case nothing happens and whether the conditioner + // |_________________|________________| is bypassed solely depends on fips_enable_pfe. + // | | | + // | 1 | 1 | In this case the conditioner is bypassed and the entropy + // |_________________|________________| is forwarded to software. + + assign es_bypass_mode = (!fips_enable_pfe) || (es_bypass_to_sw && es_route_to_sw); + + // send off to AST RNG for possibly faster entropy generation + assign rng_fips_o = rng_fips_pfe; + + //-------------------------------------------- + // common health test window counter + //-------------------------------------------- + + // Window counter + // SEC_CM: CTR.REDUN + + // We only increment the counter if the currently tested sample can be pushed to the correct FIFO + // following the health tests. This is required to keep the number of samples passed to the + // conditioner constant also when experiencing backpressure from the conditioner. At the same + // time, we're not allowed to drop samples before the health testing. This means the number of + // tested samples might be slightly bigger than the number of samples fed into the conditioner. + assign window_cntr_incr_en = + rng_bit_en ? pfifo_esbit_push && pfifo_esbit_not_full && !pfifo_esbit_clr : + pfifo_postht_push && pfifo_postht_not_full && !pfifo_postht_clr; + + caliptra_prim_count #( + .Width(WINDOW_CNTR_WIDTH) + ) u_caliptra_prim_count_window_cntr ( + .clk_i, + .rst_ni, + .clr_i(!es_delayed_enable), + .set_i(health_test_done_pulse), + .set_cnt_i(WINDOW_CNTR_WIDTH'(0)), + .incr_en_i(window_cntr_incr_en), + .decr_en_i(1'b0), + .step_i(WINDOW_CNTR_WIDTH'(1)), + .commit_i(1'b1), + .cnt_o(window_cntr), + .cnt_after_commit_o(), + .err_o(window_cntr_err) + ); + + // Window wrap condition + assign health_test_done_pulse = (window_cntr >= health_test_window_scaled); + + // Summary of counter errors + assign es_cntr_err = + (window_cntr_err || + repcnt_cntr_err || + repcnts_cntr_err || + adaptp_cntr_err || + bucket_cntr_err || + markov_cntr_err || + repcnt_fails_cntr_err || + repcnt_alert_cntr_err || + repcnts_fails_cntr_err || + repcnts_alert_cntr_err || + adaptp_hi_fails_cntr_err || + adaptp_lo_fails_cntr_err || + adaptp_hi_alert_cntr_err || + adaptp_lo_alert_cntr_err || + bucket_fails_cntr_err || + bucket_alert_cntr_err || + markov_hi_fails_cntr_err || + markov_lo_fails_cntr_err || + markov_hi_alert_cntr_err || + markov_lo_alert_cntr_err || + extht_hi_fails_cntr_err || + extht_lo_fails_cntr_err || + extht_hi_alert_cntr_err || + extht_lo_alert_cntr_err || + any_fails_cntr_err || + sha3_count_error); + + //-------------------------------------------- + // repetitive count test + //-------------------------------------------- + + // SEC_CM: RNG.BKGN_CHK + entropy_src_repcnt_ht #( + .RegWidth(HalfRegWidth), + .RngBusWidth(RngBusWidth) + ) u_entropy_src_repcnt_ht ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .entropy_bit_i (health_test_esbus), + .entropy_bit_vld_i (health_test_esbus_vld), + .rng_bit_en_i (rng_bit_en), + .rng_bit_sel_i (rng_bit_sel), + .clear_i (health_test_clr), + .active_i (repcnt_active), + .thresh_i (repcnt_threshold), + .test_cnt_o (repcnt_event_cnt), + .test_fail_pulse_o (repcnt_fail_pulse), + .count_err_o (repcnt_cntr_err) + ); + + entropy_src_watermark_reg #( + .RegWidth(HalfRegWidth), + .HighWatermark(1) + ) u_entropy_src_watermark_reg_repcnt_fips ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .clear_i (health_test_clr), + .event_i (!es_bypass_mode), + .value_i (repcnt_event_cnt), + .value_o (repcnt_event_hwm_fips) + ); + + entropy_src_watermark_reg #( + .RegWidth(HalfRegWidth), + .HighWatermark(1) + ) u_entropy_src_watermark_reg_repcnt_bypass ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .clear_i (health_test_clr), + .event_i (es_bypass_mode), + .value_i (repcnt_event_cnt), + .value_o (repcnt_event_hwm_bypass) + ); + + // SEC_CM: CTR.REDUN + entropy_src_cntr_reg #( + .RegWidth(FullRegWidth) + ) u_entropy_src_cntr_reg_repcnt ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .clear_i (health_test_clr), + .event_i (repcnt_fail_pulse), + .value_o (repcnt_total_fails), + .err_o (repcnt_fails_cntr_err) + ); + + assign hw2reg.repcnt_hi_watermarks.fips_watermark.d = repcnt_event_hwm_fips; + assign hw2reg.repcnt_hi_watermarks.bypass_watermark.d = repcnt_event_hwm_bypass; + assign hw2reg.repcnt_total_fails.d = repcnt_total_fails; + + //-------------------------------------------- + // repetitive count symbol test + //-------------------------------------------- + + // SEC_CM: RNG.BKGN_CHK + entropy_src_repcnts_ht #( + .RegWidth(HalfRegWidth), + .RngBusWidth(RngBusWidth) + ) u_entropy_src_repcnts_ht ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .entropy_bit_i (health_test_esbus), + .entropy_bit_vld_i (health_test_esbus_vld), + .clear_i (health_test_clr), + .active_i (repcnts_active), + .thresh_i (repcnts_threshold), + .test_cnt_o (repcnts_event_cnt), + .test_fail_pulse_o (repcnts_fail_pulse), + .count_err_o (repcnts_cntr_err) + ); + + entropy_src_watermark_reg #( + .RegWidth(HalfRegWidth), + .HighWatermark(1) + ) u_entropy_src_watermark_reg_repcnts_fips ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .clear_i (health_test_clr), + .event_i (!es_bypass_mode), + .value_i (repcnts_event_cnt), + .value_o (repcnts_event_hwm_fips) + ); + + entropy_src_watermark_reg #( + .RegWidth(HalfRegWidth), + .HighWatermark(1) + ) u_entropy_src_watermark_reg_repcnts_bypass ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .clear_i (health_test_clr), + .event_i (es_bypass_mode), + .value_i (repcnts_event_cnt), + .value_o (repcnts_event_hwm_bypass) + ); + + // SEC_CM: CTR.REDUN + entropy_src_cntr_reg #( + .RegWidth(FullRegWidth) + ) u_entropy_src_cntr_reg_repcnts ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .clear_i (health_test_clr), + .event_i (repcnts_fail_pulse), + .value_o (repcnts_total_fails), + .err_o (repcnts_fails_cntr_err) + ); + + assign hw2reg.repcnts_hi_watermarks.fips_watermark.d = repcnts_event_hwm_fips; + assign hw2reg.repcnts_hi_watermarks.bypass_watermark.d = repcnts_event_hwm_bypass; + assign hw2reg.repcnts_total_fails.d = repcnts_total_fails; + + //-------------------------------------------- + // adaptive proportion test + //-------------------------------------------- + + // SEC_CM: RNG.BKGN_CHK + entropy_src_adaptp_ht #( + .RegWidth(HalfRegWidth), + .RngBusWidth(RngBusWidth) + ) u_entropy_src_adaptp_ht ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .entropy_bit_i (health_test_esbus), + .entropy_bit_vld_i (health_test_esbus_vld), + .rng_bit_en_i (rng_bit_en), + .rng_bit_sel_i (rng_bit_sel), + .clear_i (health_test_clr), + .active_i (adaptp_active), + .thresh_hi_i (adaptp_hi_threshold), + .thresh_lo_i (adaptp_lo_threshold), + .window_wrap_pulse_i (health_test_done_pulse), + .threshold_scope_i (threshold_scope), + .test_cnt_hi_o (adaptp_hi_event_cnt), + .test_cnt_lo_o (adaptp_lo_event_cnt), + .test_fail_hi_pulse_o(adaptp_hi_fail_pulse), + .test_fail_lo_pulse_o(adaptp_lo_fail_pulse), + .count_err_o (adaptp_cntr_err) + ); + + + entropy_src_watermark_reg #( + .RegWidth(HalfRegWidth), + .HighWatermark(1) + ) u_entropy_src_watermark_reg_adaptp_hi_fips ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .clear_i (health_test_clr), + .event_i (health_test_done_pulse && !es_bypass_mode), + .value_i (adaptp_hi_event_cnt), + .value_o (adaptp_hi_event_hwm_fips) + ); + + entropy_src_watermark_reg #( + .RegWidth(HalfRegWidth), + .HighWatermark(1) + ) u_entropy_src_watermark_reg_adaptp_hi_bypass ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .clear_i (health_test_clr), + .event_i (health_test_done_pulse && es_bypass_mode), + .value_i (adaptp_hi_event_cnt), + .value_o (adaptp_hi_event_hwm_bypass) + ); + + // SEC_CM: CTR.REDUN + entropy_src_cntr_reg #( + .RegWidth(FullRegWidth) + ) u_entropy_src_cntr_reg_adaptp_hi ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .clear_i (health_test_clr), + .event_i (adaptp_hi_fail_pulse), + .value_o (adaptp_hi_total_fails), + .err_o (adaptp_hi_fails_cntr_err) + ); + + + assign hw2reg.adaptp_hi_watermarks.fips_watermark.d = adaptp_hi_event_hwm_fips; + assign hw2reg.adaptp_hi_watermarks.bypass_watermark.d = adaptp_hi_event_hwm_bypass; + assign hw2reg.adaptp_hi_total_fails.d = adaptp_hi_total_fails; + + + entropy_src_watermark_reg #( + .RegWidth(HalfRegWidth), + .HighWatermark(0) + ) u_entropy_src_watermark_reg_adaptp_lo_fips ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .clear_i (health_test_clr), + .event_i (health_test_done_pulse && !es_bypass_mode), + .value_i (adaptp_lo_event_cnt), + .value_o (adaptp_lo_event_hwm_fips) + ); + + entropy_src_watermark_reg #( + .RegWidth(HalfRegWidth), + .HighWatermark(0) + ) u_entropy_src_watermark_reg_adaptp_lo_bypass ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .clear_i (health_test_clr), + .event_i (health_test_done_pulse && es_bypass_mode), + .value_i (adaptp_lo_event_cnt), + .value_o (adaptp_lo_event_hwm_bypass) + ); + + // SEC_CM: CTR.REDUN + entropy_src_cntr_reg #( + .RegWidth(FullRegWidth) + ) u_entropy_src_cntr_reg_adaptp_lo ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .clear_i (health_test_clr), + .event_i (adaptp_lo_fail_pulse), + .value_o (adaptp_lo_total_fails), + .err_o (adaptp_lo_fails_cntr_err) + ); + + assign hw2reg.adaptp_lo_watermarks.fips_watermark.d = adaptp_lo_event_hwm_fips; + assign hw2reg.adaptp_lo_watermarks.bypass_watermark.d = adaptp_lo_event_hwm_bypass; + assign hw2reg.adaptp_lo_total_fails.d = adaptp_lo_total_fails; + + + //-------------------------------------------- + // bucket test + //-------------------------------------------- + + // SEC_CM: RNG.BKGN_CHK + entropy_src_bucket_ht #( + .RegWidth(HalfRegWidth), + .RngBusWidth(RngBusWidth) + ) u_entropy_src_bucket_ht ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .entropy_bit_i (health_test_esbus), + .entropy_bit_vld_i (health_test_esbus_vld), + .clear_i (health_test_clr), + .active_i (bucket_active), + .thresh_i (bucket_threshold), + .window_wrap_pulse_i (health_test_done_pulse), + .test_cnt_o (bucket_event_cnt), + .test_fail_pulse_o (bucket_fail_pulse), + .count_err_o (bucket_cntr_err) + ); + + entropy_src_watermark_reg #( + .RegWidth(HalfRegWidth), + .HighWatermark(1) + ) u_entropy_src_watermark_reg_bucket_fips ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .clear_i (health_test_clr), + .event_i (health_test_done_pulse && !es_bypass_mode), + .value_i (bucket_event_cnt), + .value_o (bucket_event_hwm_fips) + ); + + entropy_src_watermark_reg #( + .RegWidth(HalfRegWidth), + .HighWatermark(1) + ) u_entropy_src_watermark_reg_bucket_bypass ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .clear_i (health_test_clr), + .event_i (health_test_done_pulse && es_bypass_mode), + .value_i (bucket_event_cnt), + .value_o (bucket_event_hwm_bypass) + ); + + // SEC_CM: CTR.REDUN + entropy_src_cntr_reg #( + .RegWidth(FullRegWidth) + ) u_entropy_src_cntr_reg_bucket ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .clear_i (health_test_clr), + .event_i (bucket_fail_pulse), + .value_o (bucket_total_fails), + .err_o (bucket_fails_cntr_err) + ); + + assign hw2reg.bucket_hi_watermarks.fips_watermark.d = bucket_event_hwm_fips; + assign hw2reg.bucket_hi_watermarks.bypass_watermark.d = bucket_event_hwm_bypass; + assign hw2reg.bucket_total_fails.d = bucket_total_fails; + + + //-------------------------------------------- + // Markov test + //-------------------------------------------- + + // SEC_CM: RNG.BKGN_CHK + entropy_src_markov_ht #( + .RegWidth(HalfRegWidth), + .RngBusWidth(RngBusWidth) + ) u_entropy_src_markov_ht ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .entropy_bit_i (health_test_esbus), + .entropy_bit_vld_i (health_test_esbus_vld), + .rng_bit_en_i (rng_bit_en), + .rng_bit_sel_i (rng_bit_sel), + .clear_i (health_test_clr), + .active_i (markov_active), + .thresh_hi_i (markov_hi_threshold), + .thresh_lo_i (markov_lo_threshold), + .window_wrap_pulse_i (health_test_done_pulse), + .threshold_scope_i (threshold_scope), + .test_cnt_hi_o (markov_hi_event_cnt), + .test_cnt_lo_o (markov_lo_event_cnt), + .test_fail_hi_pulse_o (markov_hi_fail_pulse), + .test_fail_lo_pulse_o (markov_lo_fail_pulse), + .count_err_o (markov_cntr_err) + ); + + entropy_src_watermark_reg #( + .RegWidth(HalfRegWidth), + .HighWatermark(1) + ) u_entropy_src_watermark_reg_markov_hi_fips ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .clear_i (health_test_clr), + .event_i (health_test_done_pulse && !es_bypass_mode), + .value_i (markov_hi_event_cnt), + .value_o (markov_hi_event_hwm_fips) + ); + + entropy_src_watermark_reg #( + .RegWidth(HalfRegWidth), + .HighWatermark(1) + ) u_entropy_src_watermark_reg_markov_hi_bypass ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .clear_i (health_test_clr), + .event_i (health_test_done_pulse && es_bypass_mode), + .value_i (markov_hi_event_cnt), + .value_o (markov_hi_event_hwm_bypass) + ); + + // SEC_CM: CTR.REDUN + entropy_src_cntr_reg #( + .RegWidth(FullRegWidth) + ) u_entropy_src_cntr_reg_markov_hi ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .clear_i (health_test_clr), + .event_i (markov_hi_fail_pulse), + .value_o (markov_hi_total_fails), + .err_o (markov_hi_fails_cntr_err) + ); + + assign hw2reg.markov_hi_watermarks.fips_watermark.d = markov_hi_event_hwm_fips; + assign hw2reg.markov_hi_watermarks.bypass_watermark.d = markov_hi_event_hwm_bypass; + assign hw2reg.markov_hi_total_fails.d = markov_hi_total_fails; + + + entropy_src_watermark_reg #( + .RegWidth(HalfRegWidth), + .HighWatermark(0) + ) u_entropy_src_watermark_reg_markov_lo_fips ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .clear_i (health_test_clr), + .event_i (health_test_done_pulse && !es_bypass_mode), + .value_i (markov_lo_event_cnt), + .value_o (markov_lo_event_hwm_fips) + ); + + entropy_src_watermark_reg #( + .RegWidth(HalfRegWidth), + .HighWatermark(0) + ) u_entropy_src_watermark_reg_markov_lo_bypass ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .clear_i (health_test_clr), + .event_i (health_test_done_pulse && es_bypass_mode), + .value_i (markov_lo_event_cnt), + .value_o (markov_lo_event_hwm_bypass) + ); + + // SEC_CM: CTR.REDUN + entropy_src_cntr_reg #( + .RegWidth(FullRegWidth) + ) u_entropy_src_cntr_reg_markov_lo ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .clear_i (health_test_clr), + .event_i (markov_lo_fail_pulse), + .value_o (markov_lo_total_fails), + .err_o (markov_lo_fails_cntr_err) + ); + + assign hw2reg.markov_lo_watermarks.fips_watermark.d = markov_lo_event_hwm_fips; + assign hw2reg.markov_lo_watermarks.bypass_watermark.d = markov_lo_event_hwm_bypass; + assign hw2reg.markov_lo_total_fails.d = markov_lo_total_fails; + + + //-------------------------------------------- + // External health test + //-------------------------------------------- + + // set outputs to external health test + assign entropy_src_xht_o.entropy_bit = health_test_esbus; + assign entropy_src_xht_o.entropy_bit_valid = health_test_esbus_vld; + assign entropy_src_xht_o.rng_bit_en = rng_bit_en; + assign entropy_src_xht_o.rng_bit_sel = rng_bit_sel; + assign entropy_src_xht_o.clear = health_test_clr; + assign entropy_src_xht_o.active = extht_active; + assign entropy_src_xht_o.thresh_hi = extht_hi_threshold; + assign entropy_src_xht_o.thresh_lo = extht_lo_threshold; + assign entropy_src_xht_o.window_wrap_pulse = health_test_done_pulse; + assign entropy_src_xht_o.health_test_window = health_test_window_scaled; + assign entropy_src_xht_o.threshold_scope = threshold_scope; + // get inputs from external health test + assign extht_event_cnt_hi = entropy_src_xht_i.test_cnt_hi; + assign extht_event_cnt_lo = entropy_src_xht_i.test_cnt_lo; + assign extht_hi_fail_pulse = entropy_src_xht_i.test_fail_hi_pulse; + assign extht_lo_fail_pulse = entropy_src_xht_i.test_fail_lo_pulse; + assign extht_cont_test = entropy_src_xht_i.continuous_test; + + entropy_src_watermark_reg #( + .RegWidth(HalfRegWidth), + .HighWatermark(1) + ) u_entropy_src_watermark_reg_extht_hi_fips ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .clear_i (health_test_clr), + .event_i ((extht_cont_test || health_test_done_pulse) && !es_bypass_mode), + .value_i (extht_event_cnt_hi), + .value_o (extht_hi_event_hwm_fips) + ); + + entropy_src_watermark_reg #( + .RegWidth(HalfRegWidth), + .HighWatermark(1) + ) u_entropy_src_watermark_reg_extht_hi_bypass ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .clear_i (health_test_clr), + .event_i ((extht_cont_test || health_test_done_pulse) && es_bypass_mode), + .value_i (extht_event_cnt_hi), + .value_o (extht_hi_event_hwm_bypass) + ); + + // SEC_CM: CTR.REDUN + entropy_src_cntr_reg #( + .RegWidth(FullRegWidth) + ) u_entropy_src_cntr_reg_extht_hi ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .clear_i (health_test_clr), + .event_i (extht_hi_fail_pulse), + .value_o (extht_hi_total_fails), + .err_o (extht_hi_fails_cntr_err) + ); + + + assign hw2reg.extht_hi_watermarks.fips_watermark.d = extht_hi_event_hwm_fips; + assign hw2reg.extht_hi_watermarks.bypass_watermark.d = extht_hi_event_hwm_bypass; + assign hw2reg.extht_hi_total_fails.d = extht_hi_total_fails; + + + entropy_src_watermark_reg #( + .RegWidth(HalfRegWidth), + .HighWatermark(0) + ) u_entropy_src_watermark_reg_extht_lo_fips ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .clear_i (health_test_clr), + .event_i ((extht_cont_test || health_test_done_pulse) && !es_bypass_mode), + .value_i (extht_event_cnt_lo), + .value_o (extht_lo_event_hwm_fips) + ); + + entropy_src_watermark_reg #( + .RegWidth(HalfRegWidth), + .HighWatermark(0) + ) u_entropy_src_watermark_reg_extht_lo_bypass ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .clear_i (health_test_clr), + .event_i ((extht_cont_test || health_test_done_pulse) && es_bypass_mode), + .value_i (extht_event_cnt_lo), + .value_o (extht_lo_event_hwm_bypass) + ); + + // SEC_CM: CTR.REDUN + entropy_src_cntr_reg #( + .RegWidth(FullRegWidth) + ) u_entropy_src_cntr_reg_extht_lo ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .clear_i (health_test_clr), + .event_i (extht_lo_fail_pulse), + .value_o (extht_lo_total_fails), + .err_o (extht_lo_fails_cntr_err) + ); + + assign hw2reg.extht_lo_watermarks.fips_watermark.d = extht_lo_event_hwm_fips; + assign hw2reg.extht_lo_watermarks.bypass_watermark.d = extht_lo_event_hwm_bypass; + assign hw2reg.extht_lo_total_fails.d = extht_lo_total_fails; + + + //-------------------------------------------- + // summary and alert registers + //-------------------------------------------- + + assign alert_cntrs_clr = health_test_clr || rst_alert_cntr; + + // SEC_CM: CTR.REDUN + entropy_src_cntr_reg #( + .RegWidth(HalfRegWidth) + ) u_entropy_src_cntr_reg_any_alert_fails ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .clear_i (alert_cntrs_clr), + .event_i (any_fail_pulse), + .value_o (any_fail_count), + .err_o (any_fails_cntr_err) + ); + + assign any_fail_pulse = + repcnt_fail_pulse || + repcnts_fail_pulse || + adaptp_hi_fail_pulse || adaptp_lo_fail_pulse || + bucket_fail_pulse || + markov_hi_fail_pulse || markov_lo_fail_pulse || + extht_hi_fail_pulse || extht_lo_fail_pulse; + + assign ht_failed_d = + (!es_enable_fo[6]) ? 1'b0 : + ht_done_pulse_q ? 1'b0 : + any_fail_pulse ? 1'b1 : + ht_failed_q; + + + // delay health pulse so that main_sm will + // get the correct threshold value comparisons + assign ht_done_pulse_d = health_test_done_pulse; + + assign hw2reg.alert_summary_fail_counts.d = any_fail_count; + + // signal an alert + // SEC_CM: CONFIG.REDUN + assign alert_threshold = reg2hw.alert_threshold.alert_threshold.q; + assign alert_threshold_inv = reg2hw.alert_threshold.alert_threshold_inv.q; + assign es_thresh_cfg_alert = (~alert_threshold_inv != alert_threshold); + + assign alert_threshold_fail = + ((any_fail_count >= ~alert_threshold_inv) && (~alert_threshold_inv != '0)) || + (any_fail_count >= alert_threshold) && (alert_threshold != '0); + + + caliptra_prim_edge_detector #( + .Width(1), + .ResetValue(0), + .EnSync(0) + ) u_caliptra_prim_edge_detector_recov_alert ( + .clk_i, + .rst_ni, + .d_i(recov_alert_state), + .q_sync_o(), + .q_posedge_pulse_o(recov_alert_o), + .q_negedge_pulse_o() + ); + + assign recov_alert_state = + es_enable_pfa || + fips_enable_pfa || + fips_flag_pfa || + rng_fips_pfa || + entropy_data_reg_en_pfa || + threshold_scope_pfa || + rng_bit_enable_pfa || + fw_ov_mode_pfa || + fw_ov_entropy_insert_pfa || + fw_ov_sha3_start_pfa || + es_route_pfa || + es_type_pfa || + es_main_sm_alert || + es_bus_cmp_alert || + es_thresh_cfg_alert || + es_fw_ov_wr_alert || + es_fw_ov_disable_alert || + postht_entropy_drop_alert; + + assign hw2reg.recov_alert_sts.es_main_sm_alert.de = es_main_sm_alert; + assign hw2reg.recov_alert_sts.es_main_sm_alert.d = es_main_sm_alert; + + assign hw2reg.recov_alert_sts.es_bus_cmp_alert.de = es_bus_cmp_alert; + assign hw2reg.recov_alert_sts.es_bus_cmp_alert.d = es_bus_cmp_alert; + + assign hw2reg.recov_alert_sts.es_thresh_cfg_alert.de = es_thresh_cfg_alert; + assign hw2reg.recov_alert_sts.es_thresh_cfg_alert.d = es_thresh_cfg_alert; + + assign hw2reg.recov_alert_sts.es_fw_ov_wr_alert.de = es_fw_ov_wr_alert; + assign hw2reg.recov_alert_sts.es_fw_ov_wr_alert.d = es_fw_ov_wr_alert; + + assign hw2reg.recov_alert_sts.es_fw_ov_disable_alert.de = es_fw_ov_disable_alert; + assign hw2reg.recov_alert_sts.es_fw_ov_disable_alert.d = es_fw_ov_disable_alert; + + // repcnt fail counter + // SEC_CM: CTR.REDUN + entropy_src_cntr_reg #( + .RegWidth(EighthRegWidth) + ) u_entropy_src_cntr_reg_repcnt_alert_fails ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .clear_i (alert_cntrs_clr), + .event_i (repcnt_fail_pulse), + .value_o (repcnt_fail_count), + .err_o (repcnt_alert_cntr_err) + ); + + assign hw2reg.alert_fail_counts.repcnt_fail_count.d = repcnt_fail_count; + + // repcnts fail counter + // SEC_CM: CTR.REDUN + entropy_src_cntr_reg #( + .RegWidth(EighthRegWidth) + ) u_entropy_src_cntr_reg_repcnts_alert_fails ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .clear_i (alert_cntrs_clr), + .event_i (repcnts_fail_pulse), + .value_o (repcnts_fail_count), + .err_o (repcnts_alert_cntr_err) + ); + + assign hw2reg.alert_fail_counts.repcnts_fail_count.d = repcnts_fail_count; + + // adaptp fail counter hi and lo + // SEC_CM: CTR.REDUN + entropy_src_cntr_reg #( + .RegWidth(EighthRegWidth) + ) u_entropy_src_cntr_reg_adaptp_hi_alert_fails ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .clear_i (alert_cntrs_clr), + .event_i (adaptp_hi_fail_pulse), + .value_o (adaptp_hi_fail_count), + .err_o (adaptp_hi_alert_cntr_err) + ); + + assign hw2reg.alert_fail_counts.adaptp_hi_fail_count.d = adaptp_hi_fail_count; + + // SEC_CM: CTR.REDUN + entropy_src_cntr_reg #( + .RegWidth(EighthRegWidth) + ) u_entropy_src_cntr_reg_adaptp_lo_alert_fails ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .clear_i (alert_cntrs_clr), + .event_i (adaptp_lo_fail_pulse), + .value_o (adaptp_lo_fail_count), + .err_o (adaptp_lo_alert_cntr_err) + ); + + assign hw2reg.alert_fail_counts.adaptp_lo_fail_count.d = adaptp_lo_fail_count; + + // bucket fail counter + // SEC_CM: CTR.REDUN + entropy_src_cntr_reg #( + .RegWidth(EighthRegWidth) + ) u_entropy_src_cntr_reg_bucket_alert_fails ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .clear_i (alert_cntrs_clr), + .event_i (bucket_fail_pulse), + .value_o (bucket_fail_count), + .err_o (bucket_alert_cntr_err) + ); + + assign hw2reg.alert_fail_counts.bucket_fail_count.d = bucket_fail_count; + + + // markov fail counter hi and lo + // SEC_CM: CTR.REDUN + entropy_src_cntr_reg #( + .RegWidth(EighthRegWidth) + ) u_entropy_src_cntr_reg_markov_hi_alert_fails ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .clear_i (alert_cntrs_clr), + .event_i (markov_hi_fail_pulse), + .value_o (markov_hi_fail_count), + .err_o (markov_hi_alert_cntr_err) + ); + + assign hw2reg.alert_fail_counts.markov_hi_fail_count.d = markov_hi_fail_count; + + // SEC_CM: CTR.REDUN + entropy_src_cntr_reg #( + .RegWidth(EighthRegWidth) + ) u_entropy_src_cntr_reg_markov_lo_alert_fails ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .clear_i (alert_cntrs_clr), + .event_i (markov_lo_fail_pulse), + .value_o (markov_lo_fail_count), + .err_o (markov_lo_alert_cntr_err) + ); + + assign hw2reg.alert_fail_counts.markov_lo_fail_count.d = markov_lo_fail_count; + + // extht fail counter hi and lo + // SEC_CM: CTR.REDUN + entropy_src_cntr_reg #( + .RegWidth(EighthRegWidth) + ) u_entropy_src_cntr_reg_extht_hi_alert_fails ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .clear_i (alert_cntrs_clr), + .event_i (extht_hi_fail_pulse), + .value_o (extht_hi_fail_count), + .err_o (extht_hi_alert_cntr_err) + ); + + assign hw2reg.extht_fail_counts.extht_hi_fail_count.d = extht_hi_fail_count; + + // SEC_CM: CTR.REDUN + entropy_src_cntr_reg #( + .RegWidth(EighthRegWidth) + ) u_entropy_src_cntr_reg_extht_lo_alert_fails ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .clear_i (alert_cntrs_clr), + .event_i (extht_lo_fail_pulse), + .value_o (extht_lo_fail_count), + .err_o (extht_lo_alert_cntr_err) + ); + + assign hw2reg.extht_fail_counts.extht_lo_fail_count.d = extht_lo_fail_count; + + + //------------------------------------------------------------------ + // Signal a recoverable alert when dropping tested entropy bits. + //------------------------------------------------------------------ + + // Post-health test entropy bits can be dropped from the pipeline in case of e.g. backpressure + // from the conditioner. The conditioner will still use the amount of bits configured in + // HEALTH_TEST_WINDOW.FIPS_WINDOW to produce the seed, and the produced seed is okay to use. + // But as the dropped bits are still tested, the effective test window increases beyond the + // value configured in HEALTH_TEST_WINDOW.FIPS_WINDOW. + // + // Signaling this condition serves the following purposes: + // 1. When running in Firmware Override: Observe mode, dropping post-health test entropy bits + // may cause the entropy bits observed from the Observe FIFO to be non-contiguous, causing + // the observed bits to be not usable for validation purposes. Note that Firmware Override: + // Extract & Insert mode is not affected by this. + // 2. It allows the DV environment to know when entropy bits have been dropped which simplifies + // DV. + // 3. It helps tuning the depth of the distr FIFO which can be used to absorb the backpressure + // of the conditioner. + + // The pop signal of the preceeding esrng FIFO is unconditional, meaning samples are dropped + // whenever the esbit or postht FIFO is full in single-channel or multi-channel mode, + // respectively. + assign postht_entropy_drop_alert = sfifo_esrng_not_empty && + (rng_bit_en ? !pfifo_esbit_not_full : !pfifo_postht_not_full); + + assign hw2reg.recov_alert_sts.postht_entropy_drop_alert.de = postht_entropy_drop_alert; + assign hw2reg.recov_alert_sts.postht_entropy_drop_alert.d = postht_entropy_drop_alert; + + //-------------------------------------------------------------- + // Pack health tested esrng bus into single bit packer FIFO. + //-------------------------------------------------------------- + + // SEC_CM: CONFIG.MUBI + assign mubi_rng_bit_en = mubi4_t'(reg2hw.conf.rng_bit_enable.q); + assign rng_bit_enable_pfe = mubi4_test_true_strict(mubi_rng_bit_en_fanout[0]); + assign rng_bit_enable_pfa = mubi4_test_invalid(mubi_rng_bit_en_fanout[1]); + assign hw2reg.recov_alert_sts.rng_bit_enable_field_alert.de = rng_bit_enable_pfa; + assign hw2reg.recov_alert_sts.rng_bit_enable_field_alert.d = rng_bit_enable_pfa; + + caliptra_prim_mubi4_sync #( + .NumCopies(2), + .AsyncOn(0) + ) u_caliptra_prim_mubi4_sync_rng_bit_en ( + .clk_i, + .rst_ni, + .mubi_i(mubi_rng_bit_en), + .mubi_o(mubi_rng_bit_en_fanout) + ); + + + assign rng_bit_en = rng_bit_enable_pfe; + assign rng_bit_sel = reg2hw.conf.rng_bit_sel.q; + + caliptra_prim_packer_fifo #( + .InW(1), + .OutW(RngBusWidth), + .ClearOnRead(1'b0) + ) u_caliptra_prim_packer_fifo_esbit ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .clr_i (pfifo_esbit_clr), + .wvalid_i (pfifo_esbit_push), + .wdata_i (pfifo_esbit_wdata), + .wready_o (pfifo_esbit_not_full), + .rvalid_o (pfifo_esbit_not_empty), + .rdata_o (pfifo_esbit_rdata), + .rready_i (pfifo_esbit_pop), + .depth_o () + ); + + // The caliptra_prim_packer_fifo primitive is constructed to only accept pushes if there is indeed space + // available. The pop signal of the preceeding esrng FIFO is unconditional, meaning samples can + // be dropped before the esbit FIFO in case of backpressure. The samples are however still + // tested. + assign pfifo_esbit_push = rng_bit_en && sfifo_esrng_not_empty; + assign pfifo_esbit_clr = ~es_delayed_enable; + assign pfifo_esbit_pop = rng_bit_en && pfifo_esbit_not_empty && pfifo_postht_not_full; + assign pfifo_esbit_wdata = + (rng_bit_sel == 2'h0) ? sfifo_esrng_rdata[0] : + (rng_bit_sel == 2'h1) ? sfifo_esrng_rdata[1] : + (rng_bit_sel == 2'h2) ? sfifo_esrng_rdata[2] : + sfifo_esrng_rdata[3]; + + + //-------------------------------------------- + // pack tested entropy into 32 bit packer + //-------------------------------------------- + + caliptra_prim_packer_fifo #( + .InW(RngBusWidth), + .OutW(PostHTWidth), + .ClearOnRead(1'b0) + ) u_caliptra_prim_packer_fifo_postht ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .clr_i (pfifo_postht_clr), + .wvalid_i (pfifo_postht_push), + .wdata_i (pfifo_postht_wdata), + .wready_o (pfifo_postht_not_full), + .rvalid_o (pfifo_postht_not_empty), + .rdata_o (pfifo_postht_rdata), + .rready_i (pfifo_postht_pop), + .depth_o () + ); + + // The caliptra_prim_packer_fifo primitive is constructed to only accept pushes if there is indeed space + // available. In case the single-bit mode is enabled, the pop signal of the preceeding esbit FIFO + // is conditional on the full status of the postht FIFO, meaning backpressure can be handled. In + // case the single-bit mode is disabled, the pop signal of the preceeding esrng FIFO is + // unconditional, meaning samples can be dropped before the esbit in case of backpressure. The + // samples are however still tested. + assign pfifo_postht_push = rng_bit_en ? pfifo_esbit_not_empty : sfifo_esrng_not_empty; + + assign pfifo_postht_wdata = rng_bit_en ? pfifo_esbit_rdata : + sfifo_esrng_rdata; + + // For verification purposes, let post-disable data continue through to the SHA engine if it has + // made it past the health checks, when in standard (non-fw_ov) mode. This allows scoreboards + // to use the same data set for computing both the SHA engine outputs and the health-check stats. + // + // In fw_ov mode it is preferable (from a verification standpoint) to clear all FIFOs whenever + // disabled. Given the lack of handshaking on the fw_ov register path, this is easier to predict. + // Also, there is no association between SHA data and health test windows in FW_OV mode, so there + // is no benefit in this mode to clearing the SHA FIFOs at the same time we clear the HT + // statistics. + assign pfifo_postht_clr = fw_ov_mode_entropy_insert ? !es_enable_fo[7] : !es_delayed_enable; + + // Pop whenever the distribution FIFO is not full. The distribution FIFO can be sized such that + // it's never going to be full even under pessimistic operating conditions. + assign pfifo_postht_pop = sfifo_distr_push & sfifo_distr_not_full; + + //-------------------------------------------- + // buffer entropy in ditribution FIFO + //-------------------------------------------- + + // The purpose of this FIFO is to buffer postht entropy bits in case the conditioner cannot + // accept them at the moment, i.e., because it's busy or because it's waiting on the CS AES halt + // interface before it can run. By properly sizing this FIFO, it can be guaranteed that even + // under pessimistic operating conditions (see entropy_src_rng_max_rate test), entropy bits never + // need to be dropped from the hardware pipeline. + + // SEC_CM: FIFO.CTR.REDUN + caliptra_prim_fifo_sync #( + .Width(DistrFifoWidth), + .Pass(1), + .Depth(DistrFifoDepth), + .OutputZeroIfEmpty(0), + .Secure(1) + ) u_caliptra_prim_fifo_sync_distr ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .clr_i (sfifo_distr_clr), + .wvalid_i (sfifo_distr_push), + .wdata_i (sfifo_distr_wdata), + .wready_o (sfifo_distr_not_full), + .rvalid_o (sfifo_distr_not_empty), + .rdata_o (sfifo_distr_rdata), + .rready_i (sfifo_distr_pop), + .full_o (sfifo_distr_full), + .depth_o (), + .err_o (sfifo_distr_int_err) + ); + + // The caliptra_prim_fifo_sync primitive is constructed to only accept pushes if there is indeed space + // available. Backpressure is handled at the sender. + assign sfifo_distr_push = pfifo_postht_not_empty; + assign sfifo_distr_wdata = pfifo_postht_rdata; + + assign sfifo_distr_clr = fw_ov_mode_entropy_insert ? !es_enable_fo[19] : !es_delayed_enable; + + // In firmware override mode with extract & insert enabled, post-health test entropy bits can + // only move into the observe FIFO. Once the observe FIFO is full, post-health test entropy is + // just discarded. + assign sfifo_distr_pop = fw_ov_mode_entropy_insert ? sfifo_distr_not_empty : + // In firmware override mode (observe only) or during normal + // operation, post-health test entropy bits continue to flow + // through the hardware pipeline. + es_bypass_mode ? pfifo_bypass_push : + pfifo_precon_push & pfifo_precon_not_full; + + // fifo err + // Note that for the used caliptra_prim_fifo_sync and caliptra_prim_packer_fifo primitives it is not an error to + // push to a FIFO that is full. The primitives simply don't accept the data when full. The + // backpressure needs to be handled at the sender. + assign sfifo_distr_err = + {1'b0, + (sfifo_distr_pop && !sfifo_distr_not_empty), + (sfifo_distr_full && !sfifo_distr_not_empty) || sfifo_distr_int_err}; + + //-------------------------------------------- + // store entropy into a 32 entry deep FIFO + //-------------------------------------------- + + // SEC_CM: FIFO.CTR.REDUN + caliptra_prim_fifo_sync #( + .Width(ObserveFifoWidth), + .Pass(0), + .Depth(ObserveFifoDepth), + .OutputZeroIfEmpty(1), // Prevent SVA from firing due unknown module outputs. + .Secure(1) + ) u_caliptra_prim_fifo_sync_observe ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .clr_i (sfifo_observe_clr), + .wvalid_i (sfifo_observe_push), + .wdata_i (sfifo_observe_wdata), + .wready_o (), + .rvalid_o (sfifo_observe_not_empty), + .rdata_o (sfifo_observe_rdata), + .rready_i (sfifo_observe_pop), + .full_o (sfifo_observe_full), + .depth_o (sfifo_observe_depth), + .err_o (sfifo_observe_int_err) + ); + + // The Observe fifo is intended to hold kilobits of contiguous data, yet still gracefully + // drop data when full. This flop gates the observe fifo. If it ever overflows, no new data is + // allowed until it is empty. Thus if the rate of CSR uptake almost matches the RNG data rate + // the FIFO avoids unnecessary segmentation, and guarantees that the remaining RNG data is as + // contiguous as possible. + logic sfifo_observe_gate_d, sfifo_observe_gate_q; + + assign sfifo_observe_gate_d = (sfifo_distr_pop && sfifo_observe_full) ? 1'b0 : + !sfifo_observe_not_empty ? 1'b1 : + sfifo_observe_gate_q; + + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + sfifo_observe_gate_q <= 1'b1; + end else begin + sfifo_observe_gate_q <= sfifo_observe_gate_d; + end + end + + assign hw2reg.fw_ov_rd_fifo_overflow.d = !sfifo_observe_gate_d; + assign hw2reg.fw_ov_rd_fifo_overflow.de = 1'b1; + + assign observe_fifo_thresh_met = fw_ov_mode && (observe_fifo_thresh != '0) && + (observe_fifo_thresh <= sfifo_observe_depth) && es_enable_fo[8]; + + assign hw2reg.observe_fifo_depth.d = sfifo_observe_depth; + + // fifo controls + assign sfifo_observe_push = fw_ov_mode && sfifo_distr_pop && + (sfifo_observe_gate_q || !sfifo_observe_not_empty); + + assign sfifo_observe_clr = ~es_enable_fo[9]; + + assign sfifo_observe_wdata = sfifo_distr_rdata; + + assign sfifo_observe_pop = + (fw_ov_mode && fw_ov_fifo_rd_pulse); + + // fifo err + // Note that for the used caliptra_prim_fifo_sync and caliptra_prim_packer_fifo primitives it is not an error to + // push to a FIFO that is full. The primitives simply don't accept the data when full. The + // backpressure needs to be handled at the sender. + assign sfifo_observe_err = + {1'b0, + (sfifo_observe_pop && !sfifo_observe_not_empty), + (sfifo_observe_full && !sfifo_observe_not_empty) || sfifo_observe_int_err}; + + + //-------------------------------------------- + // pack entropy into 64 bit packer + //-------------------------------------------- + + caliptra_prim_packer_fifo #( + .InW(ObserveFifoWidth), + .OutW(PreCondWidth), + .ClearOnRead(1'b0) + ) u_caliptra_prim_packer_fifo_precon ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .clr_i (pfifo_precon_clr), + .wvalid_i (pfifo_precon_push), + .wdata_i (pfifo_precon_wdata), + .wready_o (pfifo_precon_not_full), + .rvalid_o (pfifo_precon_not_empty), + .rdata_o (pfifo_precon_rdata), + .rready_i (pfifo_precon_pop), + .depth_o () + ); + + // When bypassing the hardware conditioning - due to a) disabling FIPS mode or b) routing entropy + // to the ENTROPY_DATA register (ES_ROUTE) and bypassing the conditioner (ES_TYPE) - nothing is + // going into the conditioner. + assign pfifo_precon_push = es_bypass_mode ? 1'b0 : + // In firmware override mode with extract & insert enabled, only bits + // inserted by firmware continue down the pipeline. + fw_ov_mode_entropy_insert ? fw_ov_fifo_wr_pulse : + // Otherwise post-health test entropy bits continue to flow + // downstream. This includes observe-only firmware override mode. + sfifo_distr_not_empty; + + assign pfifo_precon_wdata = fw_ov_mode_entropy_insert ? fw_ov_wr_data : + sfifo_distr_rdata; + + // For verification purposes, let post-disable data continue through to the SHA engine if it has + // made it past the health checks, when in standard (non-fw_ov) mode. This allows scoreboards + // to use the same data set for computing both the SHA engine outputs and the health-check stats. + // + // In fw_ov mode it is preferable (from a verification standpoint) to clear all FIFOs whenever + // disabled. Given the lack of handshaking on the fw_ov register path, this is easier to predict. + // Also, there is no association between SHA data and health test windows in FW_OV mode, so there + // is no benefit in this mode to clearing the SHA FIFOs at the same time we clear the HT + // statistics. + // + // Corner case: Even in FW_OV mode, if a full SHA word is ready as the disable comes in, + // let it stay in the FIFO until the SHA engine has picked it up, as verification has no way + // of knowing if a word will get stalled by SHA backpressure. This is not a problem however + // as the reset is only important for clearing 32-bit half-SHA-words. + assign pfifo_precon_clr = fw_ov_mode_entropy_insert ? + ~es_enable_fo[10] & ~pfifo_precon_not_empty : + ~es_delayed_enable & ~pfifo_precon_not_empty; + + assign pfifo_precon_pop = (pfifo_cond_push && sha3_msgfifo_ready); + + assign es_fw_ov_wr_alert = fw_ov_mode && fw_ov_mode_entropy_insert && + fw_ov_fifo_wr_pulse && fw_ov_wr_fifo_full; + + assign es_fw_ov_disable_alert = fw_ov_mode && fw_ov_mode_entropy_insert && + !es_bypass_mode && fw_ov_sha3_disable_pulse && fw_ov_wr_fifo_full; + + //-------------------------------------------- + // entropy conditioner + //-------------------------------------------- + // This block takes in either post-health test entropy bits (when running in FIPS/CC compliant + // mode) or entropy injected by software (when running in Firmware Override: Extract & Insert + // mode). + // The amount of entropy consumed to generate a 384-bit seed depends on the mode of operation: + // - In FIPS/CC compliant mode, HEALTH_TEST_WINDOWS.FIPS_WINDOW x 4 bits (by default 2048 bits) + // are required to produce one 384-bit seed. For the first seed after start up, the number of + // bits consumed is doubled to align with the required 1024 samples of 4 bits for startup + // health testing. + // For windows which fail a health test, the entropy is still absorbed by the SHA3 engine + // but no seed is produced. In order for the SHA3 engine to produce a seed, the last window it + // absorbed must have passed the health tests. + // - In Firmware Override: Extract & Insert mode, the operation of the SHA3 engine is software + // defined. + // + // Note that the final absorption operation of the SHA3 engine is triggered by the main state + // machine (upon receiving the health-test done pulse). The SHA3 engine is also triggered + // internally by the padding logic whenever 832 bits (= the rate or block size of SHA3-384) have + // been received. + // + // Note on backpressure handling from the SHA3 engine: + // To avoid inferring a combo loop, the msg_valid_i input (pfifo_cond_push signal) must not + // depend on the msg_ready_o output (sha3_msgfifo_ready). However, we can always push into the + // SHA3 engine as long as the precon FIFO contains valid data. The ready output is just used to + // determine when to pop from the precon FIFO. + + assign pfifo_cond_push = pfifo_precon_not_empty && !es_bypass_mode; + assign pfifo_cond_wdata = pfifo_precon_rdata; + + assign msg_data[0] = pfifo_cond_wdata; + + assign pfifo_cond_rdata = sha3_state[0][SeedLen-1:0]; + + // SHA3 hashing engine + sha3 #( + .EnMasking (Sha3EnMasking) + ) u_sha3 ( + .clk_i, + .rst_ni, + + // MSG_FIFO interface + .msg_valid_i (pfifo_cond_push), + .msg_data_i (msg_data), + .msg_strb_i ({8{pfifo_cond_push}}), + .msg_ready_o (sha3_msgfifo_ready), + + // Entropy interface - not using + .rand_valid_i (1'b0), + .rand_early_i (1'b0), + .rand_data_i ('0), + .rand_aux_i ('0), + .rand_update_o (), + .rand_consumed_o (), + + // N, S: Used in cSHAKE mode + .ns_data_i ('0), // ns_prefix), + + // Configurations + .mode_i (sha3_pkg::Sha3), // Use SHA3 mode + .strength_i (sha3_pkg::L384), // Use keccak_strength_e of L384 + + // Controls (CMD register) + .start_i (sha3_start ), + .process_i (sha3_process ), + .run_i (1'b0 ), // For software application + .done_i (sha3_done ), + + // LC escalation + .lc_escalate_en_i (lc_ctrl_pkg::Off), + + .absorbed_o (sha3_absorbed), + .squeezing_o (sha3_squeezing), + + .block_processed_o (sha3_block_processed), + + .sha3_fsm_o (sha3_fsm), + + .state_valid_o (sha3_state_vld), + .state_o (sha3_state), + + // REQ/ACK interface to avoid power spikes + .run_req_o(cs_aes_halt_req), + .run_ack_i(cs_aes_halt_i.cs_aes_halt_ack), + + .error_o (sha3_err), + .sparse_fsm_error_o (sha3_state_error), + .count_error_o (sha3_count_error), + .keccak_storage_rst_error_o (sha3_rst_storage_err) + ); + + //-------------------------------------------- + // bypass SHA conditioner path + //-------------------------------------------- + + caliptra_prim_packer_fifo #( + .InW(PostHTWidth), + .OutW(SeedLen), + .ClearOnRead(1'b0) + ) u_caliptra_prim_packer_fifo_bypass ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .clr_i (pfifo_bypass_clr), + .wvalid_i (pfifo_bypass_push), + .wdata_i (pfifo_bypass_wdata), + .wready_o (pfifo_bypass_not_full), + .rvalid_o (pfifo_bypass_not_empty), + .rdata_o (pfifo_bypass_rdata), + .rready_i (pfifo_bypass_pop), + .depth_o () + ); + + // Unless the hardware conditioning is bypassed - due to a) disabling FIPS mode or b) routing + // entropy to the ENTROPY_DATA register (ES_ROUTE) and bypassing the conditioner (ES_TYPE) - + // nothing is going into the bypass FIFO. + assign pfifo_bypass_push = !es_bypass_mode ? 1'b0 : + // In firmware override mode with extract & insert enabled, only bits + // inserted by firmware continue down the pipeline + fw_ov_mode_entropy_insert ? fw_ov_fifo_wr_pulse : + // Otherwise post-health test entropy bits continue to flow + // downstream. This includes observe-only firmware override mode. + sfifo_distr_not_empty; + + assign pfifo_bypass_wdata = fw_ov_mode_entropy_insert ? fw_ov_wr_data : + sfifo_distr_rdata; + + assign pfifo_bypass_clr = !es_enable_fo[11]; + + // Corner case: If the main state machine encounters an alert, drain the + // bypass fifo, to get rid of the seeds and let the HT stats continue. + assign pfifo_bypass_pop = + fw_ov_mode_entropy_insert ? pfifo_bypass_not_empty : + bypass_stage_pop; + + // mux to select between fips and bypass mode + assign final_es_data = es_bypass_mode ? pfifo_bypass_rdata : pfifo_cond_rdata; + + + //-------------------------------------------- + // state machine to coordinate fifo flow + //-------------------------------------------- + assign main_sm_done_pulse = rng_bit_en ? ht_done_pulse_qq : ht_done_pulse_q; + assign main_sm_ht_failed = rng_bit_en ? ht_failed_qq : ht_failed_q; + + // SEC_CM: CTR.LOCAL_ESC + // SEC_CM: MAIN_SM.FSM.SPARSE + entropy_src_main_sm + u_entropy_src_main_sm ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .enable_i (main_sm_enable), + .fw_ov_ent_insert_i (fw_ov_mode_entropy_insert), + .fw_ov_sha3_start_i (fw_ov_sha3_start_pfe), + .ht_done_pulse_i (main_sm_done_pulse), + .ht_fail_pulse_i (main_sm_ht_failed), + .alert_thresh_fail_i (alert_threshold_fail), + .rst_alert_cntr_o (rst_alert_cntr), + .bypass_mode_i (es_bypass_mode), + .bypass_stage_rdy_i (pfifo_bypass_not_empty), + .sha3_state_vld_i (sha3_state_vld), + .main_stage_push_o (main_stage_push_raw), + .bypass_stage_pop_o (bypass_stage_pop), + .boot_phase_done_o (boot_phase_done), + .sha3_start_o (sha3_start_raw), + .sha3_process_o (sha3_process), + .sha3_done_o (sha3_done), + .local_escalate_i (fatal_loc_events), + .main_sm_alert_o (es_main_sm_alert), + .main_sm_idle_o (es_main_sm_idle), + .main_sm_state_o (es_main_sm_state), + .main_sm_err_o (es_main_sm_err) + ); + + // es to cs halt request to reduce power spikes + assign cs_aes_halt_d = cs_aes_halt_req; + assign cs_aes_halt_o.cs_aes_halt_req = cs_aes_halt_q; + + //-------------------------------------------- + // Corner case masking of main_sm inputs/outputs + //-------------------------------------------- + + // When operating in RNG mode the state machine does not respond + // immediately to disable requests if it processing the SHA output + // (here indicated by the cs_aes_halt_req handshake). The SHA engine + // will continue to process even if the module is disabled. These seeds + // that continue to process after the disable signal are referred to as + // stale. + // + // If the SHA processing were instantaneous, stale seeds would be discarded + // when the esfinal fifo was cleard on diable. Though since processing + // can push through a disable pulse, stale seeds need to be identified, + // and held back from the esfinal FIFO. + // + // There is at most one seed processing at a time so, we simply need to + // detect when a stale seed has commenced processing, and mask the following + // main_stage_push signal. + + assign stale_seed_processing = ~es_bypass_mode & ~fw_ov_mode_entropy_insert & + cs_aes_halt_req & ~es_enable_fo[12]; + assign sha3_flush_d = stale_seed_processing ? 1'b1 : + main_stage_push_raw ? 1'b0 : + sha3_flush_q; + + // If the user incorrectly disables the fw_ov SHA3 processing while + // data is in the pipeline, it can potentially scramble two outputs. + // Thus in addition to triggering a recoverable alert, we mark the + // following _two_ outputs as corrupted and to not let them in the + // esfinal FIFO + assign fw_ov_corrupted_d = es_fw_ov_disable_alert ? 2'b11 : + !es_bypass_mode && main_stage_push_raw ? {1'b0, fw_ov_corrupted_q[1]} : + fw_ov_corrupted_q; + + assign fw_ov_corrupted = (|fw_ov_corrupted_q) & !es_bypass_mode; + + + assign main_stage_push = main_stage_push_raw & !sha3_flush_q & !fw_ov_corrupted; + + // Use the delayed enable signal to keep the Main SM enabled while Data is in flight, and + // to make sure it receives a delayed disable pulse after finishing any final SHA processing + // commands + assign main_sm_enable = es_delayed_enable; + + // The main SM can also generate redundant start pulses. After data can be pushed into SHA, + // the SM can be disabled leaving entropy in the SHA sponge. This is fine, but the SM will + // have no recollection of this previous start pulse. We track redundant start pulses + // outside the SM and suppress them as needed. + assign sha3_start_mask_d = sha3_start_raw ? 1'b1 : + sha3_process ? 1'b0 : + sha3_start_mask_q; + assign sha3_start = sha3_start_raw & ~sha3_start_mask_q; + + //-------------------------------------------- + // send processed entropy to final fifo + //-------------------------------------------- + + // SEC_CM: FIFO.CTR.REDUN + caliptra_prim_fifo_sync #( + .Width(1+SeedLen), + .Pass(0), + .Depth(EsFifoDepth), + .OutputZeroIfEmpty(0), + .Secure(1) + ) u_caliptra_prim_fifo_sync_esfinal ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .clr_i (sfifo_esfinal_clr), + .wvalid_i (sfifo_esfinal_push), + .wready_o (sfifo_esfinal_not_full), + .wdata_i (sfifo_esfinal_wdata), + .rvalid_o (sfifo_esfinal_not_empty), + .rready_i (sfifo_esfinal_pop), + .rdata_o (sfifo_esfinal_rdata), + .full_o (sfifo_esfinal_full), + .depth_o (sfifo_esfinal_depth), + .err_o (sfifo_esfinal_int_err) + ); + + // The FIPS flag is fully determined in SW. This has to be the case since we don't know + // which mode of operation will be validated/certified. Another reason is that SW can + // set the threshold values arbitrarily, which on its own makes the FIPS bit basically + // SW defined. + assign fips_compliance = es_enable_fo[13] && fips_flag_pfe; + + // fifo controls + // No backpressure is possible at this point. If the esfinal FIFO is already full and a new seed + // is pushed, the push is ignored and the seed is lost. + assign sfifo_esfinal_push = + fw_ov_mode_entropy_insert && es_bypass_mode ? pfifo_bypass_not_empty : + main_stage_push; + + assign sfifo_esfinal_clr = !es_enable_fo[14]; + assign sfifo_esfinal_wdata = {fips_compliance,final_es_data}; + assign sfifo_esfinal_pop = es_route_to_sw ? swread_done : es_hw_if_fifo_pop; + assign {esfinal_fips_flag,esfinal_data} = sfifo_esfinal_rdata; + + // fifo err + // Note that for the used caliptra_prim_fifo_sync and caliptra_prim_packer_fifo primitives it is not an error to + // push to a FIFO that is full. The primitives simply don't accept the data when full. The + // backpressure needs to be handled at the sender. + assign sfifo_esfinal_err = + {1'b0, + (sfifo_esfinal_pop && !sfifo_esfinal_not_empty), + (sfifo_esfinal_full && !sfifo_esfinal_not_empty) || sfifo_esfinal_int_err}; + + // drive out hw interface + assign es_hw_if_req = entropy_src_hw_if_i.es_req; + assign entropy_src_hw_if_o.es_ack = es_hw_if_ack; + assign entropy_src_hw_if_o.es_bits = esfinal_data; + assign entropy_src_hw_if_o.es_fips = esfinal_fips_flag; + + // SEC_CM: ACK_SM.FSM.SPARSE + entropy_src_ack_sm u_entropy_src_ack_sm ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .enable_i (es_enable_fo[15]), + .req_i (es_hw_if_req), + .ack_o (es_hw_if_ack), + .fifo_not_empty_i (sfifo_esfinal_not_empty && !es_route_to_sw), + .local_escalate_i (es_cntr_err), + .fifo_pop_o (es_hw_if_fifo_pop), + .ack_sm_err_o (es_ack_sm_err) + ); + + //-------------------------------------------- + // data path integrity check + // - a countermeasure to detect entropy bus tampering attempts + // - checks to make sure repeated data sets off + // an alert for sw to handle + //-------------------------------------------- + + // SEC_CM: ESFINAL_RDATA.BUS.CONSISTENCY + + // capture a copy of the entropy data + assign es_rdata_capt_vld = (sfifo_esfinal_pop && sfifo_esfinal_not_empty); + + assign es_rdata_capt_d = es_rdata_capt_vld ? sfifo_esfinal_rdata[63:0] : es_rdata_capt_q; + + assign es_rdata_capt_vld_d = + !es_enable_fo[16] ? 1'b0 : + es_rdata_capt_vld ? 1'b1 : + es_rdata_capt_vld_q; + + // continuous compare of the entropy data + assign es_bus_cmp_alert = es_rdata_capt_vld && es_rdata_capt_vld_q && + (es_rdata_capt_q == sfifo_esfinal_rdata[63:0]); + + + //---------------------------------------------------- + // software es read path via ENTROPY_DATA register + //---------------------------------------------------- + + // Sync and evaluate the OTP input. + caliptra_prim_mubi8_sync #( + .NumCopies(1), + .AsyncOn(1) + ) u_caliptra_prim_mubi8_sync_es_fw_read ( + .clk_i, + .rst_ni, + .mubi_i(otp_en_entropy_src_fw_read_i), + .mubi_o({en_entropy_src_fw_read}) + ); + assign efuse_es_sw_reg_en = caliptra_prim_mubi_pkg::mubi8_test_true_strict(en_entropy_src_fw_read); + + // Is the ENTROPY_DATA register readable? + assign es_data_reg_rd_en = es_enable_fo[17] && efuse_es_sw_reg_en && entropy_data_reg_en_pfe; + + // Interface the esfinal FIFO and cut its 384-bit output into 32-bit chunks for software. + // We're done after the last read. + assign swread_done = reg2hw.entropy_data.re && (swread_idx_q == LastSwRead[SwReadIdxWidth-1:0]); + + // Increment the index counter upon reads from software. + assign swread_idx_incr = reg2hw.entropy_data.re; + + // Unless the ENTROPY_DATA CSR is readable, keep clearing the index counter. Clear the counter + // after a full seed has been read. + assign swread_idx_clr = !es_data_reg_rd_en || swread_done; + + // Index counter + assign swread_idx_d = !es_enable_fo[18] ? '0 : + swread_idx_clr ? '0 : + swread_idx_incr ? swread_idx_q + 1'b1 : swread_idx_q; + always_ff @(posedge clk_i or negedge rst_ni) begin : swread_idx_reg + if (!rst_ni) begin + swread_idx_q <= '0; + end else begin + swread_idx_q <= swread_idx_d; + end + end + + // Forward the relevant part of the valid esfinal output or 0 if ES_ROUTE is off. + assign swread_data = sfifo_esfinal_not_empty && es_route_to_sw ? + esfinal_data[swread_idx_q * FullRegWidth +: FullRegWidth] : '0; + + // This primitive is used to place a size-only constraint on the buffers to act as a synthesis + // optimization barrier. This ensures ES_ROUTE and ENTROPY_DATA_REG_ENABLE together with the OTP + // input are taken into account in separately. + caliptra_prim_buf #( + .Width(FullRegWidth) + ) u_caliptra_prim_buf_swread_data ( + .in_i (swread_data), + .out_o(swread_data_buf) + ); + + // Forward the data to the ENTROPY_DATA CSR or 0 if the CSR is not readable. + assign hw2reg.entropy_data.d = es_data_reg_rd_en ? swread_data_buf : '0; + + + //-------------------------------------------- + // unused signals + //-------------------------------------------- + + assign unused_err_code_test_bit = (|{err_code_test_bit[27:25],err_code_test_bit[19:4]}); + assign unused_sha3_state = (|sha3_state[0][sha3_pkg::StateW-1:SeedLen]); + assign unused_entropy_data = (|reg2hw.entropy_data.q); + assign unused_fw_ov_rd_data = (|reg2hw.fw_ov_rd_data.q); + assign unused_sfifo_esrng_not_full = sfifo_esrng_not_full; + assign unused_sfifo_esfinal_not_full = sfifo_esfinal_not_full; + + //-------------------------------------------- + // Assertions + //-------------------------------------------- +`ifdef CALIPTRA_INC_ASSERT + + // Count number of disables since last reset. + logic [63:0] disable_cnt_d, disable_cnt_q; + always_comb begin + disable_cnt_d = disable_cnt_q; + if (!mubi4_test_true_strict(mubi_mod_en_dly_d) && + mubi4_test_true_strict(mubi_mod_en_dly_q)) begin + disable_cnt_d += 1; + end + end + + // Assert that no entropy gets dropped during FIPS-compliant operation mode. + // + // The following code, which includes counters, small FSMs, and assertions, tracks entropy bits + // from the noise source input through Entropy Source to the hardware interface output and checks + // that in FIPS-compliant mode entropy does not get dropped unless it should get dropped. The + // code is arranged in the same order as entropy flows through Entropy Source, so having Entropy + // Source's block diagram ready when reading this code is highly recommended. + + // Delay `es_delayed_enable` by one clock cycle to track when Entropy Source actually accepts RNG + // inputs. + logic es_delayed_enable_d, es_delayed_enable_q; + assign es_delayed_enable_d = es_delayed_enable; + + // Count number of valid bits from RNG input (RNG_BUS_WIDTH wide) while Entropy Source is enabled. + logic [63:0] rng_valid_bit_cnt_d, rng_valid_bit_cnt_q; + assign rng_valid_bit_cnt_d = entropy_src_rng_i.rng_valid && es_delayed_enable_q ? + rng_valid_bit_cnt_q + RNG_BUS_WIDTH : + rng_valid_bit_cnt_q; + + // Count number of bits pushed into esrng FIFO (RngBusWidth wide). + logic [63:0] esrng_push_bit_cnt_d, esrng_push_bit_cnt_q; + assign esrng_push_bit_cnt_d = sfifo_esrng_push & sfifo_esrng_not_full ? + esrng_push_bit_cnt_q + RngBusWidth : + esrng_push_bit_cnt_q; + + // Assert that as many bits got pushed into the esrng FIFO (destination) as there were valid RNG + // input bits (source). RngBusWidth bits may get lost after every re-enable; add a margin to + // account for that. + `CALIPTRA_ASSERT_AT_RESET_AND_FINAL(ValidRngBitsPushedIntoEsrngFifo_A, + `CALIPTRA_WITHIN_MARGIN(esrng_push_bit_cnt_q, // actual + rng_valid_bit_cnt_q, // expected + disable_cnt_q * RngBusWidth, // allowed less + 0)) // allowed more + + // Count number of bits pushed into esbit FIFO (1 wide input, RngBusWidth wide output). + logic [63:0] esbit_push_bit_cnt_d, esbit_push_bit_cnt_q; + assign esbit_push_bit_cnt_d = pfifo_esbit_push & pfifo_esbit_not_full ? + esbit_push_bit_cnt_q + 1 : + esbit_push_bit_cnt_q; + + // Count number of bits pushed into postht FIFO (RngBusWidth wide input, PostHTWidth wide output). + logic [63:0] postht_push_bit_cnt_d, postht_push_bit_cnt_q; + assign postht_push_bit_cnt_d = pfifo_postht_push & pfifo_postht_not_full ? + postht_push_bit_cnt_q + RngBusWidth : + postht_push_bit_cnt_q; + + // Count number of bits pushed into postht FIFO from esrng FIFO. + logic [63:0] postht_from_esrng_push_bit_cnt_d, postht_from_esrng_push_bit_cnt_q; + assign postht_from_esrng_push_bit_cnt_d = + pfifo_postht_push & pfifo_postht_not_full & ~rng_bit_en ? + postht_from_esrng_push_bit_cnt_q + RngBusWidth : + postht_from_esrng_push_bit_cnt_q; + + // Assert that as many bits got pushed into the esbit FIFO or the postht FIFO (destinations) as + // into the esrng FIFO (source). The number of bits pushed into the esbit FIFO has to be + // multiplied by the output width of the esrng FIFO (RngBusWidth) because only 1 bit gets pushed + // into the esbit FIFO for every pop from the esrng FIFO. Add a margin (allowed less) because: + // - RngBusWidth bits may get lost after every re-enable + // - one entry may just have been pushed into esrng FIFO when the assertion gets evaluated. + `CALIPTRA_ASSERT_AT_RESET_AND_FINAL(EsrngFifoPushedIntoEsbitOrPosthtFifos_A, + `CALIPTRA_WITHIN_MARGIN((esbit_push_bit_cnt_q * RngBusWidth + + postht_from_esrng_push_bit_cnt_q), // actual + esrng_push_bit_cnt_q, // expected + (disable_cnt_q + 1) * RngBusWidth, // allowed less + 0)) // allowed more + + // Count number of bits pushed into postht FIFO from esbit FIFO. + logic [63:0] postht_from_esbit_push_bit_cnt_d, postht_from_esbit_push_bit_cnt_q; + assign postht_from_esbit_push_bit_cnt_d = + pfifo_postht_push & pfifo_postht_not_full & rng_bit_en ? + postht_from_esbit_push_bit_cnt_q + RngBusWidth : + postht_from_esbit_push_bit_cnt_q; + + // Assert that as many bits got pushed into the postht FIFO (destination) as into the esbit FIFO + // (source) when the latter was selected as source. Add a margin (allowed less) because: + // - RngBusWidth bits may get lost after every re-enable + // - esbit FIFO may be partially full when the assertion gets evaluated. + `CALIPTRA_ASSERT_AT_RESET_AND_FINAL(EsbitFifoPushedIntoPosthtFifo_A, + `CALIPTRA_WITHIN_MARGIN(postht_from_esbit_push_bit_cnt_q, // actual + esbit_push_bit_cnt_q, // expected + (disable_cnt_q + 1) * RngBusWidth - 1, // allowed less + 0)) // allowed more + + // Assert that as many bits got pushed into the postht FIFO as got counted from the esrng FIFO or + // the esbit FIFO. This assertion checks more the completeness of the other assertions than the + // design itself. + `CALIPTRA_ASSERT_AT_RESET_AND_FINAL(PosthtFifoPushedFromEsbitOrEsrngFifos_A, + postht_push_bit_cnt_q == (postht_from_esrng_push_bit_cnt_q + + postht_from_esbit_push_bit_cnt_q)) + + // Count number of bits popped from postht FIFO (PostHTWidth wide output) when bypass mode was + // disabled. + logic [63:0] postht_non_bypass_pop_bit_cnt_d, postht_non_bypass_pop_bit_cnt_q; + assign postht_non_bypass_pop_bit_cnt_d = + pfifo_postht_pop & pfifo_postht_not_empty & ~es_bypass_mode ? + postht_non_bypass_pop_bit_cnt_q + PostHTWidth : + postht_non_bypass_pop_bit_cnt_q; + + // Count number of bits pushed into distr FIFO (DistrFifoWidth wide input and output). + logic [63:0] distr_non_bypass_push_bit_cnt_d, distr_non_bypass_push_bit_cnt_q; + assign distr_non_bypass_push_bit_cnt_d = + sfifo_distr_push & sfifo_distr_not_full & ~es_bypass_mode ? + distr_non_bypass_push_bit_cnt_q + DistrFifoWidth : + distr_non_bypass_push_bit_cnt_q; + + // Assert that as many bits got pushed into the distr FIFO (destination) as got popped from the + // postht FIFO when bypass mode was disabled (source). + `CALIPTRA_ASSERT_AT_RESET_AND_FINAL(PosthtFifoPushedIntoDistrFifo_A, + distr_non_bypass_push_bit_cnt_q == postht_non_bypass_pop_bit_cnt_q) + + // Count number of bits popped from distr FIFO (DistrFifoWidth wide output) when bypass mode was + // disabled. + logic [63:0] distr_non_bypass_pop_bit_cnt_d, distr_non_bypass_pop_bit_cnt_q; + assign distr_non_bypass_pop_bit_cnt_d = + sfifo_distr_pop & sfifo_distr_not_empty & ~es_bypass_mode ? + distr_non_bypass_pop_bit_cnt_q + DistrFifoWidth : + distr_non_bypass_pop_bit_cnt_q; + + // Count number of bits pushed into precon FIFO (ObserveFifoWidth wide input, PreCondWidth wide + // output). + logic [63:0] precon_push_bit_cnt_d, precon_push_bit_cnt_q; + assign precon_push_bit_cnt_d = pfifo_precon_push & pfifo_precon_not_full ? + precon_push_bit_cnt_q + ObserveFifoWidth : + precon_push_bit_cnt_q; + + // Assert that as many bits got pushed into the precon FIFO (destination) as got popped from the + // distr FIFO when bypass mode was disabled (source). + `CALIPTRA_ASSERT_AT_RESET_AND_FINAL(DistrFifoPushedIntoPreconFifo_A, + precon_push_bit_cnt_q == distr_non_bypass_pop_bit_cnt_q) + + // Track when boot and startup checks are completing. + logic boot_startup_checks_completing; + assign boot_startup_checks_completing = + (u_entropy_src_main_sm.state_q == entropy_src_main_sm_pkg::StartupPass1 & + u_entropy_src_main_sm.ht_done_pulse_i & + ~u_entropy_src_main_sm.ht_fail_pulse_i); + + // Track state of boot and startup checks. + typedef enum logic [1:0] { + BscStIncomplete, // checks incomplete + BscStPassed, // checks passed + BscStPushed // entropy from passed checks pushed + } bsc_state_e; + bsc_state_e bsc_state_d, bsc_state_q; + always_comb begin + bsc_state_d = bsc_state_q; + unique case (bsc_state_q) + BscStIncomplete: begin + if (boot_startup_checks_completing) begin + // Checks have just completed. + bsc_state_d = BscStPassed; + end + end + BscStPassed: begin + if (main_stage_push) begin + // Entropy from passed checks is being pushed. + bsc_state_d = BscStPushed; + end + end + BscStPushed: begin + // Boot and startup checks remained passed and their entropy pushed until Entropy Source + // gets disabled again (which is handled below). + bsc_state_d = bsc_state_q; + end + default: bsc_state_d = BscStIncomplete; + endcase + // If not enabled, always clear to incomplete. + if (!es_delayed_enable) begin + bsc_state_d = BscStIncomplete; + end + end + + // Count number of bits pushed into precon FIFO (ObserveFifoWidth wide input, PreCondWidth wide + // output) after boot and startup checks. + logic [63:0] precon_post_startup_push_bit_cnt_d, precon_post_startup_push_bit_cnt_q; + assign precon_post_startup_push_bit_cnt_d = + pfifo_precon_push & pfifo_precon_not_full & (bsc_state_q != BscStIncomplete) ? + precon_post_startup_push_bit_cnt_q + ObserveFifoWidth : + precon_post_startup_push_bit_cnt_q; + + // Track when esfinal FIFO gets pushed while bypass mode is disabled. + logic esfinal_non_bypass_push; + assign esfinal_non_bypass_push = sfifo_esfinal_push & sfifo_esfinal_not_full & ~es_bypass_mode; + + // Count number of bits pushed into esfinal FIFO (SeedLen bits per push) while bypass mode was + // disabled. + logic [63:0] esfinal_non_bypass_push_cnt_d, esfinal_non_bypass_push_cnt_q; + assign esfinal_non_bypass_push_cnt_d = esfinal_non_bypass_push ? + esfinal_non_bypass_push_cnt_q + SeedLen : + esfinal_non_bypass_push_cnt_q; + + // Count number of bits pushed into esfinal FIFO (SeedLen bits per push) after startup checks have + // passed and while bypass mode was disabled. + logic [63:0] esfinal_post_startup_push_bit_cnt_d, esfinal_post_startup_push_bit_cnt_q; + assign esfinal_post_startup_push_bit_cnt_d = + esfinal_non_bypass_push & (bsc_state_q != BscStIncomplete) ? + esfinal_post_startup_push_bit_cnt_q + SeedLen : + esfinal_post_startup_push_bit_cnt_q; + + // Assert that all bits pushed into the esfinal FIFO came from or after passed startup checks. + `CALIPTRA_ASSERT_AT_RESET_AND_FINAL(EsfinalFifoPushed_A, + esfinal_non_bypass_push_cnt_q == esfinal_post_startup_push_bit_cnt_q) + + // Track result of health tests after boot and startup tests. + typedef enum logic [1:0] { + HtStNoResult, // no health test result is currently available + HtStPassed, // last health test has passed and entropy has not propagated from conditioner yet + HtStFailed // last health test has failed + } ht_state_e; + ht_state_e ht_state_d, ht_state_q; + always_comb begin + ht_state_d = ht_state_q; + if (bsc_state_q == BscStPushed) begin + if (ht_state_q inside {HtStNoResult, HtStFailed}) begin + if (health_test_done_pulse) begin + if (!any_fail_pulse && !alert_threshold_fail) begin + ht_state_d = HtStPassed; + end else begin + ht_state_d = HtStFailed; + end + end + end else if (ht_state_q == HtStPassed) begin + if (main_stage_push_raw) begin + ht_state_d = HtStNoResult; + end + end else begin + ht_state_d = HtStNoResult; + end + if (ht_state_q == HtStFailed) begin + `CALIPTRA_ASSERT_I(NoPushAfterFailedHealthTest_A, rst_ni !== 1'b1 || !main_stage_push_raw) + end + end + // If not enabled, always clear to no result. + if (!es_delayed_enable) begin + ht_state_d = HtStNoResult; + end + end + + // Track when entropy is expected to get dropped instead of pushed into the esfinal FIFO. This is + // the case whenever the esfinal FIFO is full. When routing to SW and the SW read finished at the + // same time, the entropy isn't dropped. + logic esfinal_exp_drop; + assign esfinal_exp_drop = sfifo_esfinal_full & (es_route_to_sw ? ~swread_done : 1'b1); + + // Count number of bits that are expected to have gotten pushed into precon FIFO and into esfinal + // FIFO after boot and startup checks and while bypass mode was disabled. + logic [63:0] precon_post_startup_exp_push_bit_cnt_d, precon_post_startup_exp_push_bit_cnt_q; + logic [63:0] esfinal_post_startup_exp_push_bit_cnt_d, esfinal_post_startup_exp_push_bit_cnt_q; + always_comb begin + esfinal_post_startup_exp_push_bit_cnt_d = esfinal_post_startup_exp_push_bit_cnt_q; + precon_post_startup_exp_push_bit_cnt_d = precon_post_startup_exp_push_bit_cnt_q; + if (bsc_state_q == BscStPassed && bsc_state_d == BscStPushed) begin + // On the completion of boot and startup checks, SeedLen bits are expected to be pushed into + // the esfinal FIFO. + esfinal_post_startup_exp_push_bit_cnt_d += SeedLen; + end + if (bsc_state_q != BscStIncomplete && health_test_done_pulse) begin + // Once boot and startup checks have completed, (4 * health_test_window) bits are expected to + // have gotten pushed into the precon FIFO. + precon_post_startup_exp_push_bit_cnt_d += 4 * health_test_window; + end + if (ht_state_q == HtStPassed && main_stage_push_raw && !esfinal_exp_drop) begin + // If none of the health tests failed and the alert threshold has not been exceeded, SeedLen + // bits are expected to be pushed into the esfinal FIFO -- unless we expect them to get + // dropped (see above). + esfinal_post_startup_exp_push_bit_cnt_d += SeedLen; + end + // When Entropy Source gets disabled after boot and startup checks have been completed, add the + // number of bits that have been pushed into precon FIFO since the last conditioner output to + // the expected number of bits. + if ((bsc_state_q != BscStIncomplete) && (bsc_state_d == BscStIncomplete)) begin + logic [63:0] diff_; + diff_ = precon_post_startup_push_bit_cnt_q - precon_post_startup_exp_push_bit_cnt_q; + // Assert that the difference is not negative. + `CALIPTRA_ASSERT_I(PreconPostStartupDiffNonNegative_A, + rst_ni !== 1'b1 || (precon_post_startup_push_bit_cnt_q >= + precon_post_startup_exp_push_bit_cnt_q)) + // Assert that the difference is smaller than the number of bits that would have sufficed to + // get pushed into the conditioner. + `CALIPTRA_ASSERT_I(PreconPostStartupDiffSmall_A, rst_ni !== 1'b1 || diff_ < (4 * health_test_window)) + precon_post_startup_exp_push_bit_cnt_d += diff_; + end + end + // This code assumes that `health_test_window` does not change dynamically; capture that in an + // assertion ensuring it only changes when entropy_src is not enabled. + `CALIPTRA_ASSERT(HealthTestWindowStableWhenEnabled_A, + mubi4_test_true_strict(mubi_es_enable) |-> $stable(health_test_window)) + + // Assert that all bits pushed into the esfinal FIFO after startup checks were expected. + `CALIPTRA_ASSERT_AT_RESET_AND_FINAL(EsfinalFifoPushedPostStartup_A, + esfinal_post_startup_push_bit_cnt_q == + esfinal_post_startup_exp_push_bit_cnt_q) + + // Assert that the expected number of bits pushed into the precon FIFO based on the number of + // outputs of the conditioner matches the actual number of bits pushed into the precon FIFO after + // startup checks. Add a margin (allowed more) as the simulation may end when bits in the precon + // FIFO have not resulted in conditioner output and Entropy Source has not been disabled. + logic [63:0] ppspb_allowed_more; + assign ppspb_allowed_more = bsc_state_q != BscStIncomplete ? 4 * health_test_window : '0; + `CALIPTRA_ASSERT_AT_RESET_AND_FINAL(PreconFifoPushedPostStartup_A, + `CALIPTRA_WITHIN_MARGIN(precon_post_startup_push_bit_cnt_q, // actual + precon_post_startup_exp_push_bit_cnt_q, // expected + 0, // allowed less + ppspb_allowed_more)) // allowed more + + always_ff @(posedge clk_i, negedge rst_ni) begin + if (!rst_ni) begin + esbit_push_bit_cnt_q <= '0; + esfinal_non_bypass_push_cnt_q <= '0; + esfinal_post_startup_push_bit_cnt_q <= '0; + esrng_push_bit_cnt_q <= '0; + postht_from_esbit_push_bit_cnt_q <= '0; + postht_from_esrng_push_bit_cnt_q <= '0; + postht_non_bypass_pop_bit_cnt_q <= '0; + postht_push_bit_cnt_q <= '0; + distr_non_bypass_pop_bit_cnt_q <= '0; + distr_non_bypass_push_bit_cnt_q <= '0; + precon_post_startup_push_bit_cnt_q <= '0; + precon_push_bit_cnt_q <= '0; + rng_valid_bit_cnt_q <= '0; + end else if (es_delayed_enable & !fw_ov_mode_entropy_insert) begin + // All these counters get updated if and only if entropy_src is enabled and the firmware + // override entropy insertion mode is disabled. Otherwise, there are no guarantees on how + // much entropy from the noise source gets dropped due to backpressure. + esbit_push_bit_cnt_q <= esbit_push_bit_cnt_d; + esfinal_non_bypass_push_cnt_q <= esfinal_non_bypass_push_cnt_d; + esfinal_post_startup_push_bit_cnt_q <= esfinal_post_startup_push_bit_cnt_d; + esrng_push_bit_cnt_q <= esrng_push_bit_cnt_d; + postht_from_esbit_push_bit_cnt_q <= postht_from_esbit_push_bit_cnt_d; + postht_from_esrng_push_bit_cnt_q <= postht_from_esrng_push_bit_cnt_d; + postht_non_bypass_pop_bit_cnt_q <= postht_non_bypass_pop_bit_cnt_d; + postht_push_bit_cnt_q <= postht_push_bit_cnt_d; + distr_non_bypass_pop_bit_cnt_q <= distr_non_bypass_pop_bit_cnt_d; + distr_non_bypass_push_bit_cnt_q <= distr_non_bypass_push_bit_cnt_d; + precon_post_startup_push_bit_cnt_q <= precon_post_startup_push_bit_cnt_d; + precon_push_bit_cnt_q <= precon_push_bit_cnt_d; + rng_valid_bit_cnt_q <= rng_valid_bit_cnt_d; + end + end + + always_ff @(posedge clk_i, negedge rst_ni) begin + if (!rst_ni) begin + bsc_state_q <= BscStIncomplete; + disable_cnt_q <= '0; + es_delayed_enable_q <= '0; + esfinal_post_startup_exp_push_bit_cnt_q <= '0; + ht_state_q <= HtStNoResult; + precon_post_startup_exp_push_bit_cnt_q <= '0; + end else begin + bsc_state_q <= bsc_state_d; + disable_cnt_q <= disable_cnt_d; + es_delayed_enable_q <= es_delayed_enable_d; + esfinal_post_startup_exp_push_bit_cnt_q <= esfinal_post_startup_exp_push_bit_cnt_d; + ht_state_q <= ht_state_d; + precon_post_startup_exp_push_bit_cnt_q <= precon_post_startup_exp_push_bit_cnt_d; + end + end + + // When triggering the conditioner, the precon FIFO must be empty. The postht and distr FIFOs + // must have been empty in the cycle before. Otherwise, some entropy bits tested as part of the + // current window won't make into the corresponding seed. + // + // In Firmware Override: Extract & Insert mode, we don't care as firmware is responsible for + // filling the precon FIFO and for triggering the conditioner: + // - If the conditioner is triggered without the precon FIFO being empty, a recoverable alert is + // signaled. + // - The fill levels of the postht and distr FIFOs are irrelevant for the conditioner in this + // mode. + `CALIPTRA_ASSERT(FifosEmptyWhenShaProcess_A, + !fw_ov_mode_entropy_insert && $rose(sha3_process) |-> + $past(!pfifo_postht_not_empty) && $past(!sfifo_distr_not_empty) && !pfifo_precon_not_empty) +`endif + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/entropy_src_enable_delay.sv b/designs/Caliptra/src/caliptra-rtl/entropy_src_enable_delay.sv new file mode 100644 index 0000000..865fae2 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/entropy_src_enable_delay.sv @@ -0,0 +1,111 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Description: Logic module indicate ongoing activity of after disablement of entropy_src_core +// +// The entropy_src has a great deal of internal state, and when shutting down most of this internal +// state should be cleared. (The two notable exceptions are the health test statistics, which are +// only cleared at the next enable, and the SHA3 conditioning sponge which accumulates unused +// entropy until a seed is generated). There are delays as incoming RNG data is processed, and for +// ease of verification we insist all elements of the data pipeline are cleared consistently. This +// means that once an RNG sample enters the pipeline, that sample should be reflected in the health +// tests. The SHA3 conditioner is also assumed to successfully absorb every 64-bits that enters the +// module. +// +// To acheive this consistency goal the entropy_src delays the clearing of internal data buffers +// and the state machine until: +// 1. Any unprocessed data has been counted at the health checks (regardless of the mode) +// 2. Any RNG data bound for the SHA conditioner has been received at the conditioner. +// 3. Any ongoing SHA processing operations have completed, and the main FSM has been forced +// back to idle. +// +// This block creates a modified version of the enable pulse which: +// 1. Postpones the disable event until any flowing data has passed through the RNG, ESBIT, POSTHT +// and DISTR FIFOs. If backpressure is encountered at the Precon FIFO, the stalled data can +// be discarded, and so a has a maximum time limit of MaxFifoWait=4 clocks is given for this +// check. +// 2. Once the disable signal is received, the rising edge does not occur until: +// 2a. One clock after the falling edge OR +// 2b. One clock after the SHA engine completes, +// Whichever comes later. + +module entropy_src_enable_delay import caliptra_prim_mubi_pkg::*; ( + input logic clk_i, + input logic rst_ni, + + input logic enable_i, + + // Unconsumed FIFO inputs + input logic esrng_fifo_not_empty_i, + input logic esbit_fifo_not_empty_i, + input logic postht_fifo_not_empty_i, + input logic distr_fifo_not_empty_i, + + // SHA3 conditioner inputs + input logic cs_aes_halt_req_i, + input logic sha3_block_processed_i, + + input logic bypass_mode_i, + + output logic enable_o +); + + // Maximum number of cycles to wait for FIFOs to clear out. + // Set to 4 to allow one cycle for each FIFO in the pipeline. + localparam int MaxFifoWait = 4; + + logic suppress_reenable; + logic extend_enable; + + logic data_in_flight; + logic [3:0] fifos_not_empty; + + // Flops + logic [MaxFifoWait - 1:0] fifo_timer_d, fifo_timer_q; + logic sha3_active_post_en_d, sha3_active_post_en_q; + logic sha3_block_processed_q; + logic extend_enable_q; + + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + sha3_active_post_en_q <= 1'b0; + fifo_timer_q <= '0; + sha3_block_processed_q <= 1'b0; + extend_enable_q <= 1'b0; + end else begin + sha3_active_post_en_q <= sha3_active_post_en_d; + fifo_timer_q <= fifo_timer_d; + sha3_block_processed_q <= sha3_block_processed_i; + extend_enable_q <= extend_enable; + end + end + + // Output definition + assign enable_o = (enable_i & ~suppress_reenable) | extend_enable; + + // In flight data monitoring. + // The `fifo_timer` is a small shift register to count out the maximum number of cycles to wait + // for the FIFOs to drain. Since this timer is very small (3 cycles), it is implemented as a shift + // register. + assign fifo_timer_d = enable_i ? {MaxFifoWait{1'b1}} : {fifo_timer_q[MaxFifoWait-2:0], 1'b0}; + assign fifos_not_empty = {esrng_fifo_not_empty_i, esbit_fifo_not_empty_i, + !bypass_mode_i & postht_fifo_not_empty_i, + !bypass_mode_i & distr_fifo_not_empty_i}; + assign data_in_flight = |fifo_timer_q && |fifos_not_empty; + + // Extend the enable by at least one clock to give the FSM time to receive any last + // Health checks. + assign extend_enable = ((fifo_timer_q[0] | data_in_flight) & ~enable_i); + + // Pulse to extend from the falling edge of the incoming enable pulse until one cycle after the + // SHA engine has finished processing the current block. + assign sha3_active_post_en_d = cs_aes_halt_req_i && !enable_i ? 1'b1 : + sha3_block_processed_q ? 1'b0 : + sha3_active_post_en_q; + + // Force the output to be low until sha3_active_post_en_q falls or + // for one more cycle after the falling each of extend_enable + assign suppress_reenable = sha3_active_post_en_q | extend_enable_q; + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/entropy_src_main_sm.sv b/designs/Caliptra/src/caliptra-rtl/entropy_src_main_sm.sv new file mode 100644 index 0000000..7a71037 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/entropy_src_main_sm.sv @@ -0,0 +1,282 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Description: entropy_src main state machine module +// +// determines when new entropy is ready to be forwarded + +module entropy_src_main_sm + import entropy_src_main_sm_pkg::*; +( + input logic clk_i, + input logic rst_ni, + + input logic enable_i, + input logic fw_ov_ent_insert_i, + input logic fw_ov_sha3_start_i, + input logic ht_done_pulse_i, + input logic ht_fail_pulse_i, + input logic alert_thresh_fail_i, + output logic rst_alert_cntr_o, + input logic bypass_mode_i, + input logic bypass_stage_rdy_i, + input logic sha3_state_vld_i, + output logic main_stage_push_o, + output logic bypass_stage_pop_o, + output logic boot_phase_done_o, + output logic sha3_start_o, + output logic sha3_process_o, + output caliptra_prim_mubi_pkg::mubi4_t sha3_done_o, + input logic local_escalate_i, + output logic main_sm_alert_o, + output logic main_sm_idle_o, + output logic [StateWidth-1:0] main_sm_state_o, + output logic main_sm_err_o +); + + // The definition of state_e, the sparse FSM state enum, is in entropy_src_main_sm_pkg.sv + state_e state_d, state_q; + + `CALIPTRA_PRIM_FLOP_SPARSE_FSM(u_state_regs, state_d, state_q, state_e, Idle) + + assign main_sm_state_o = state_q; + + always_comb begin + state_d = state_q; + rst_alert_cntr_o = 1'b0; + main_stage_push_o = 1'b0; + bypass_stage_pop_o = 1'b0; + boot_phase_done_o = 1'b0; + sha3_start_o = 1'b0; + sha3_process_o = 1'b0; + sha3_done_o = caliptra_prim_mubi_pkg::MuBi4False; + main_sm_alert_o = 1'b0; + main_sm_idle_o = 1'b0; + main_sm_err_o = 1'b0; + unique case (state_q) + Idle: begin + main_sm_idle_o = 1'b1; + if (enable_i) begin + // running fw override mode and in sha3 mode + if (fw_ov_ent_insert_i && !bypass_mode_i) begin + sha3_start_o = 1'b1; + if (fw_ov_sha3_start_i) begin + state_d = FWInsertMsg; + end else begin + state_d = FWInsertStart; + end + // running in bypass_mode and not fw override mode + end else if (bypass_mode_i && !fw_ov_ent_insert_i) begin + state_d = BootHTRunning; + // running in bypass_mode and fw override mode + end else if (bypass_mode_i && fw_ov_ent_insert_i) begin + state_d = Idle; + end else begin + state_d = StartupHTStart; + end + end + end + BootHTRunning: begin + if (!enable_i) begin + state_d = Idle; + end else if (ht_done_pulse_i) begin + if (ht_fail_pulse_i) begin + if (bypass_stage_rdy_i) begin + // Remove failed data + bypass_stage_pop_o = 1'b1; + end + if (alert_thresh_fail_i) begin + state_d = AlertState; + end else begin + state_d = Idle; + end + end else begin + // Window sizes other than 384 bits (the seed length) are currently not tested nor + // supported in bypass or boot-time mode. + state_d = BootPostHTChk; + rst_alert_cntr_o = 1'b1; + end + end + end + BootPostHTChk: begin + if (!enable_i) begin + state_d = Idle; + end else begin + if (!bypass_stage_rdy_i) begin + end else begin + bypass_stage_pop_o = 1'b1; + main_stage_push_o = 1'b1; + state_d = BootPhaseDone; + end + end + end + BootPhaseDone: begin + boot_phase_done_o = 1'b1; + if (!enable_i) begin + state_d = Idle; + end + // Even when stalled we keep monitoring for alerts and maintaining alert statistics. + // However, we don't signal alerts or clear HT stats in FW_OV mode. + if(!fw_ov_ent_insert_i && ht_done_pulse_i) begin + if (alert_thresh_fail_i) begin + state_d = AlertState; + end else if (!ht_fail_pulse_i) begin + rst_alert_cntr_o = 1'b1; + end + end + end + StartupHTStart: begin + if (!enable_i) begin + state_d = Idle; + end else begin + sha3_start_o = 1'b1; + state_d = StartupPhase1; + end + end + StartupPhase1: begin + if (!enable_i) begin + state_d = Idle; + end else begin + if (ht_done_pulse_i) begin + if (ht_fail_pulse_i) begin + state_d = StartupFail1; + end else begin + state_d = StartupPass1; + rst_alert_cntr_o = 1'b1; + end + end + end + end + StartupPass1: begin + if (!enable_i) begin + state_d = Idle; + end else begin + if (ht_done_pulse_i) begin + if (ht_fail_pulse_i) begin + state_d = StartupFail1; + end else begin + // We've now passed two consecutive test windows of the configured window length. + // Next, we're going to compress the collected entropy to produce a single seed. + state_d = Sha3Process; + rst_alert_cntr_o = 1'b1; + end + end + end + end + StartupFail1: begin + if (!enable_i) begin + state_d = Idle; + end else begin + if (ht_done_pulse_i) begin + if (ht_fail_pulse_i) begin + // Failed two consecutive tests + state_d = AlertState; + end else begin + state_d = StartupPass1; + rst_alert_cntr_o = 1'b1; + end + end + end + end + ContHTStart: begin + if (!enable_i) begin + state_d = Idle; + end else begin + // Send the Start trigger to the SHA3 engine. After this point, collected raw entropy is + // going to be moved into the conditioner in chunks of 64 bits. The SHA3 engine itself + // will hash the received raw entropy whenever either of the following two conditions are + // met: + // 1) 13 64-bit chunks have been received (13 x 64 = 832 = the rate or block size of + // the employed SHA3-384 engine). This condition is checked internally to the SHA3 + // engine. + // 2) The total amount of received entropy is equal to the configured health test window + // size. This condition is checked by this FSM which then triggers the SHA3 engine + // using the sha3_process_o signal. + sha3_start_o = 1'b1; + state_d = ContHTRunning; + end + end + ContHTRunning: begin + if (!enable_i) begin + state_d = Idle; + end else begin + if (ht_done_pulse_i) begin + // We've finished testing the current window and all the collected and tested entropy + // has been forwarded to the SHA3 engine and has at least partially been absorbed. + if (alert_thresh_fail_i) begin + state_d = AlertState; + end else if (!ht_fail_pulse_i) begin + // Move forward and get the conditioner ready to finish the absorption process. + state_d = Sha3Process; + rst_alert_cntr_o = 1'b1; + end + end + end + end + FWInsertStart: begin + if (!enable_i) begin + state_d = Idle; + end else if (fw_ov_sha3_start_i) begin + state_d = FWInsertMsg; + end + end + FWInsertMsg: begin + if (!enable_i) begin + state_d = Idle; + end else if (!fw_ov_sha3_start_i) begin + state_d = Sha3Process; + end + end + Sha3Process: begin + // Trigger the final absorption operation of the SHA3 engine. + sha3_process_o = 1'b1; + state_d = Sha3Valid; + end + Sha3Valid: begin + if (sha3_state_vld_i) begin + state_d = Sha3Done; + end + end + Sha3Done: begin + if (!enable_i) begin + sha3_done_o = caliptra_prim_mubi_pkg::MuBi4True; + state_d = Sha3MsgDone; + end else begin + // Push the digest produced by the SHA3 engine into the final FIFO and clear the + // internal state of the SHA3 engine to start from scratch for the next seed. + sha3_done_o = caliptra_prim_mubi_pkg::MuBi4True; + main_stage_push_o = 1'b1; + state_d = Sha3MsgDone; + end + end + Sha3MsgDone: begin + if (!enable_i || fw_ov_ent_insert_i) begin + state_d = Idle; + end else begin + state_d = ContHTStart; + end + end + AlertState: begin + main_sm_alert_o = 1'b1; + state_d = AlertHang; + end + AlertHang: begin + if (!enable_i) begin + state_d = Idle; + end + end + Error: begin + main_sm_err_o = 1'b1; + end + default: begin + state_d = Error; + main_sm_err_o = 1'b1; + end + endcase + if (local_escalate_i) begin + state_d = Error; + end + end + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/entropy_src_main_sm_pkg.sv b/designs/Caliptra/src/caliptra-rtl/entropy_src_main_sm_pkg.sv new file mode 100644 index 0000000..b7167b0 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/entropy_src_main_sm_pkg.sv @@ -0,0 +1,54 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// State definitions for entropy_src_main_sm, provided as a separate package for use in DV + +package entropy_src_main_sm_pkg; + + // Encoding generated with: + // $ ./util/design/sparse-fsm-encode.py -d 3 -m 20 -n 9 \ + // -s 2359261201 --language=sv + // + // Hamming distance histogram: + // + // 0: -- + // 1: -- + // 2: -- + // 3: |||||||||||| (18.42%) + // 4: |||||||||||||||||||| (29.47%) + // 5: |||||||||||||||||| (26.84%) + // 6: ||||||||||| (16.32%) + // 7: |||| (6.84%) + // 8: | (2.11%) + // 9: -- + // + // Minimum Hamming distance: 3 + // Maximum Hamming distance: 8 + // Minimum Hamming weight: 1 + // Maximum Hamming weight: 8 + // + localparam int StateWidth = 9; + typedef enum logic [StateWidth-1:0] { + Idle = 9'b011110101, // idle + BootHTRunning = 9'b111010010, // boot mode, wait for health test done pulse + BootPostHTChk = 9'b101101110, // boot mode, wait for post health test packer not empty state + BootPhaseDone = 9'b010001110, // boot mode, stay here until master enable is off + StartupHTStart = 9'b000101100, // startup mode, pulse the sha3 start input + StartupPhase1 = 9'b100000001, // startup mode, look for first test pass/fail + StartupPass1 = 9'b110100101, // startup mode, look for first test pass/fail, done if pass + StartupFail1 = 9'b000010111, // startup mode, look for second fail, alert if fail + ContHTStart = 9'b001000000, // continuous test mode, pulse the sha3 start input + ContHTRunning = 9'b110100010, // continuous test mode, wait for health test done pulse + FWInsertStart = 9'b011000011, // fw ov mode, start the sha3 block + FWInsertMsg = 9'b001011001, // fw ov mode, insert fw message into sha3 block + Sha3MsgDone = 9'b100001111, // sha3 mode, sha3 state cleared, go to continuous check mode + Sha3Process = 9'b011111000, // sha3 mode, pulse the sha3 process input + Sha3Valid = 9'b010111111, // sha3 mode, wait for sha3 valid indication + Sha3Done = 9'b110011000, // sha3 mode, capture sha3 result, pulse done input + AlertState = 9'b111001101, // if some alert condition occurs, pulse an alert indication + AlertHang = 9'b111111011, // after pulsing alert signal, hang here until sw handles + Error = 9'b001110011 // illegal state reached and hang + } state_e; + +endpackage diff --git a/designs/Caliptra/src/caliptra-rtl/entropy_src_markov_ht.sv b/designs/Caliptra/src/caliptra-rtl/entropy_src_markov_ht.sv new file mode 100644 index 0000000..b56e7a3 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/entropy_src_markov_ht.sv @@ -0,0 +1,162 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Description: entropy_src Markov health test module +// + +module entropy_src_markov_ht #( + parameter int RegWidth = 16, + parameter int RngBusWidth = 4 +) ( + input logic clk_i, + input logic rst_ni, + + // ins req interface + input logic [RngBusWidth-1:0] entropy_bit_i, + input logic entropy_bit_vld_i, + input logic rng_bit_en_i, + input logic [1:0] rng_bit_sel_i, + input logic clear_i, + input logic active_i, + input logic [RegWidth-1:0] thresh_hi_i, + input logic [RegWidth-1:0] thresh_lo_i, + input logic window_wrap_pulse_i, + input logic threshold_scope_i, + output logic [RegWidth-1:0] test_cnt_hi_o, + output logic [RegWidth-1:0] test_cnt_lo_o, + output logic test_fail_hi_pulse_o, + output logic test_fail_lo_pulse_o, + output logic count_err_o +); + + // signals + logic [RngBusWidth-1:0] samples_no_match_pulse; + logic [RegWidth-1:0] pair_cntr_max; + logic [RegWidth-1:0] pair_cntr_min, pair_cntr_min_tmp; + logic [RegWidth-1:0] pair_cntr_sum; + logic [RngBusWidth-1:0][RegWidth-1:0] pair_cntr; + logic [RegWidth-1:0] rng_bit_cnt; + logic [RngBusWidth-1:0] pair_cntr_err; + + // flops + logic toggle_q, toggle_d; + logic [RngBusWidth-1:0] prev_sample_q, prev_sample_d; + + always_ff @(posedge clk_i or negedge rst_ni) + if (!rst_ni) begin + toggle_q <= '0; + prev_sample_q <= '0; + end else begin + toggle_q <= toggle_d; + prev_sample_q <= prev_sample_d; + end + + + // Markov Test + // + // Test operation + // This test will look at pairs of bit levels per bitstream. A counter for + // stream will only count when the pair equals 0b01 or 0b10. + + + for (genvar sh = 0; sh < RngBusWidth; sh = sh+1) begin : gen_cntrs + + // bit sampler + assign prev_sample_d[sh] = (!active_i || clear_i) ? '0 : + window_wrap_pulse_i ? '0 : + entropy_bit_vld_i ? entropy_bit_i[sh] : + prev_sample_q[sh]; + + // pair check + assign samples_no_match_pulse[sh] = entropy_bit_vld_i && toggle_q && + (prev_sample_q[sh] == !entropy_bit_i[sh]); + + // pair counter + caliptra_prim_count #( + .Width(RegWidth) + ) u_caliptra_prim_count_pair_cntr ( + .clk_i, + .rst_ni, + .clr_i(window_wrap_pulse_i), + .set_i(!active_i || clear_i), + .set_cnt_i(RegWidth'(0)), + .incr_en_i(samples_no_match_pulse[sh]), + .decr_en_i(1'b0), + .step_i(RegWidth'(1)), + .commit_i(1'b1), + .cnt_o(pair_cntr[sh]), + .cnt_after_commit_o(), + .err_o(pair_cntr_err[sh]) + ); + end : gen_cntrs + + // create a toggle signal to sample pairs with + assign toggle_d = (!active_i || clear_i) ? '0 : + window_wrap_pulse_i ? '0 : + entropy_bit_vld_i ? (!toggle_q) : + toggle_q; + + // determine the highest counter pair counter value + caliptra_prim_max_tree #( + .NumSrc(RngBusWidth), + .Width(RegWidth) + ) u_max ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .values_i (pair_cntr), + .valid_i ({RngBusWidth{1'b1}}), + .max_value_o (pair_cntr_max), + .max_idx_o (), + .max_valid_o () + ); + + // determine the lowest counter pair counter value + // Negate the inputs and outputs of caliptra_prim_max_tree to find the minimum + // For this unsigned application, one's complement negation (i.e. logical inversion) is fine. + caliptra_prim_max_tree #( + .NumSrc(RngBusWidth), + .Width(RegWidth) + ) u_min ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .values_i (~pair_cntr), + .valid_i ({RngBusWidth{1'b1}}), + .max_value_o (pair_cntr_min_tmp), + .max_idx_o (), + .max_valid_o () + ); + + // Invert the output back. + assign pair_cntr_min = ~pair_cntr_min_tmp; + + caliptra_prim_sum_tree #( + .NumSrc(RngBusWidth), + .Width(RegWidth) + ) u_sum ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .values_i (pair_cntr), + .valid_i ({RngBusWidth{1'b1}}), + .sum_value_o (pair_cntr_sum), + .sum_valid_o () + ); + + assign rng_bit_cnt = (rng_bit_sel_i == 2'h0) ? pair_cntr[0] : + (rng_bit_sel_i == 2'h1) ? pair_cntr[1] : + (rng_bit_sel_i == 2'h2) ? pair_cntr[2] : + pair_cntr[3]; + + assign test_cnt_hi_o = rng_bit_en_i ? rng_bit_cnt : + threshold_scope_i ? pair_cntr_sum : + pair_cntr_max; + assign test_cnt_lo_o = rng_bit_en_i ? rng_bit_cnt : + threshold_scope_i ? pair_cntr_sum : + pair_cntr_min; + + // the pulses will be only one clock in length + assign test_fail_hi_pulse_o = active_i && window_wrap_pulse_i && (test_cnt_hi_o > thresh_hi_i); + assign test_fail_lo_pulse_o = active_i && window_wrap_pulse_i && (test_cnt_lo_o < thresh_lo_i); + assign count_err_o = (|pair_cntr_err); + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/entropy_src_pkg.sv b/designs/Caliptra/src/caliptra-rtl/entropy_src_pkg.sv new file mode 100644 index 0000000..41f96d3 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/entropy_src_pkg.sv @@ -0,0 +1,87 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// + +package entropy_src_pkg; + + //------------------------- + // Entropy Interface + //------------------------- + + parameter int RNG_BUS_WIDTH = 4; + parameter int CSRNG_BUS_WIDTH = 384; + parameter int FIPS_BUS_WIDTH = 1; + parameter int FIPS_CSRNG_BUS_WIDTH = FIPS_BUS_WIDTH + CSRNG_BUS_WIDTH; + + // Internal entropy_src parameters. + parameter int WINDOW_CNTR_WIDTH = 18; + + // es entropy i/f + typedef struct packed { + logic es_ack; + logic [CSRNG_BUS_WIDTH-1:0] es_bits; + logic [FIPS_BUS_WIDTH-1:0] es_fips; + } entropy_src_hw_if_rsp_t; + + typedef struct packed { + logic es_req; + } entropy_src_hw_if_req_t; + + parameter entropy_src_hw_if_req_t ENTROPY_SRC_HW_IF_REQ_DEFAULT = '{default: '0}; + parameter entropy_src_hw_if_rsp_t ENTROPY_SRC_HW_IF_RSP_DEFAULT = '{default: '0}; + + + // csrng block encrypt request/ack i/f + typedef struct packed { + logic cs_aes_halt_req; + } cs_aes_halt_req_t; + + typedef struct packed { + logic cs_aes_halt_ack; + } cs_aes_halt_rsp_t; + + parameter cs_aes_halt_req_t CS_AES_HALT_REQ_DEFAULT = '{default: '0}; + parameter cs_aes_halt_rsp_t CS_AES_HALT_RSP_DEFAULT = '{default: '0}; + + // ast rng i/f + typedef struct packed { + logic rng_enable; + } entropy_src_rng_req_t; + + typedef struct packed { + logic rng_valid; + logic [RNG_BUS_WIDTH-1:0] rng_b; + } entropy_src_rng_rsp_t; + + parameter entropy_src_rng_req_t ENTROPY_SRC_RNG_REQ_DEFAULT = '{default: '0}; + parameter entropy_src_rng_rsp_t ENTROPY_SRC_RNG_RSP_DEFAULT = '{default: '0}; + + // external health test i/f + typedef struct packed { + logic [RNG_BUS_WIDTH-1:0] entropy_bit; + logic entropy_bit_valid; + logic rng_bit_en; + logic [1:0] rng_bit_sel; + logic clear; + logic active; + logic [15:0] thresh_hi; + logic [15:0] thresh_lo; + logic [WINDOW_CNTR_WIDTH-1:0] health_test_window; + logic window_wrap_pulse; + logic threshold_scope; + } entropy_src_xht_req_t; + + typedef struct packed { + logic[15:0] test_cnt_hi; + logic[15:0] test_cnt_lo; + logic continuous_test; + logic test_fail_hi_pulse; + logic test_fail_lo_pulse; + } entropy_src_xht_rsp_t; + + parameter entropy_src_xht_req_t ENTROPY_SRC_XHT_REQ_DEFAULT = '{default: '0}; + parameter entropy_src_xht_rsp_t ENTROPY_SRC_XHT_RSP_DEFAULT = + '{test_cnt_lo: 16'hffff, default: '0}; + +endpackage : entropy_src_pkg diff --git a/designs/Caliptra/src/caliptra-rtl/entropy_src_reg_pkg.sv b/designs/Caliptra/src/caliptra-rtl/entropy_src_reg_pkg.sv new file mode 100644 index 0000000..61dbce0 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/entropy_src_reg_pkg.sv @@ -0,0 +1,1040 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Register Package auto-generated by `reggen` containing data structure + +package entropy_src_reg_pkg; + + // Param list + parameter int unsigned ObserveFifoDepth = 32; + parameter int NumAlerts = 2; + + // Address widths within the block + parameter int BlockAw = 8; + + //////////////////////////// + // Typedefs for registers // + //////////////////////////// + + typedef struct packed { + struct packed { + logic q; + } es_fatal_err; + struct packed { + logic q; + } es_observe_fifo_ready; + struct packed { + logic q; + } es_health_test_failed; + struct packed { + logic q; + } es_entropy_valid; + } entropy_src_reg2hw_intr_state_reg_t; + + typedef struct packed { + struct packed { + logic q; + } es_fatal_err; + struct packed { + logic q; + } es_observe_fifo_ready; + struct packed { + logic q; + } es_health_test_failed; + struct packed { + logic q; + } es_entropy_valid; + } entropy_src_reg2hw_intr_enable_reg_t; + + typedef struct packed { + struct packed { + logic q; + logic qe; + } es_fatal_err; + struct packed { + logic q; + logic qe; + } es_observe_fifo_ready; + struct packed { + logic q; + logic qe; + } es_health_test_failed; + struct packed { + logic q; + logic qe; + } es_entropy_valid; + } entropy_src_reg2hw_intr_test_reg_t; + + typedef struct packed { + struct packed { + logic q; + logic qe; + } fatal_alert; + struct packed { + logic q; + logic qe; + } recov_alert; + } entropy_src_reg2hw_alert_test_reg_t; + + typedef struct packed { + logic q; + } entropy_src_reg2hw_sw_regupd_reg_t; + + typedef struct packed { + logic [3:0] q; + } entropy_src_reg2hw_module_enable_reg_t; + + typedef struct packed { + struct packed { + logic [3:0] q; + } entropy_data_reg_enable; + struct packed { + logic [3:0] q; + } threshold_scope; + struct packed { + logic [1:0] q; + } rng_bit_sel; + struct packed { + logic [3:0] q; + } rng_bit_enable; + struct packed { + logic [3:0] q; + } rng_fips; + struct packed { + logic [3:0] q; + } fips_flag; + struct packed { + logic [3:0] q; + } fips_enable; + } entropy_src_reg2hw_conf_reg_t; + + typedef struct packed { + struct packed { + logic [3:0] q; + } es_type; + struct packed { + logic [3:0] q; + } es_route; + } entropy_src_reg2hw_entropy_control_reg_t; + + typedef struct packed { + logic [31:0] q; + logic re; + } entropy_src_reg2hw_entropy_data_reg_t; + + typedef struct packed { + struct packed { + logic [15:0] q; + } bypass_window; + struct packed { + logic [15:0] q; + } fips_window; + } entropy_src_reg2hw_health_test_windows_reg_t; + + typedef struct packed { + struct packed { + logic [15:0] q; + logic qe; + } bypass_thresh; + struct packed { + logic [15:0] q; + logic qe; + } fips_thresh; + } entropy_src_reg2hw_repcnt_thresholds_reg_t; + + typedef struct packed { + struct packed { + logic [15:0] q; + logic qe; + } bypass_thresh; + struct packed { + logic [15:0] q; + logic qe; + } fips_thresh; + } entropy_src_reg2hw_repcnts_thresholds_reg_t; + + typedef struct packed { + struct packed { + logic [15:0] q; + logic qe; + } bypass_thresh; + struct packed { + logic [15:0] q; + logic qe; + } fips_thresh; + } entropy_src_reg2hw_adaptp_hi_thresholds_reg_t; + + typedef struct packed { + struct packed { + logic [15:0] q; + logic qe; + } bypass_thresh; + struct packed { + logic [15:0] q; + logic qe; + } fips_thresh; + } entropy_src_reg2hw_adaptp_lo_thresholds_reg_t; + + typedef struct packed { + struct packed { + logic [15:0] q; + logic qe; + } bypass_thresh; + struct packed { + logic [15:0] q; + logic qe; + } fips_thresh; + } entropy_src_reg2hw_bucket_thresholds_reg_t; + + typedef struct packed { + struct packed { + logic [15:0] q; + logic qe; + } bypass_thresh; + struct packed { + logic [15:0] q; + logic qe; + } fips_thresh; + } entropy_src_reg2hw_markov_hi_thresholds_reg_t; + + typedef struct packed { + struct packed { + logic [15:0] q; + logic qe; + } bypass_thresh; + struct packed { + logic [15:0] q; + logic qe; + } fips_thresh; + } entropy_src_reg2hw_markov_lo_thresholds_reg_t; + + typedef struct packed { + struct packed { + logic [15:0] q; + logic qe; + } bypass_thresh; + struct packed { + logic [15:0] q; + logic qe; + } fips_thresh; + } entropy_src_reg2hw_extht_hi_thresholds_reg_t; + + typedef struct packed { + struct packed { + logic [15:0] q; + logic qe; + } bypass_thresh; + struct packed { + logic [15:0] q; + logic qe; + } fips_thresh; + } entropy_src_reg2hw_extht_lo_thresholds_reg_t; + + typedef struct packed { + struct packed { + logic [15:0] q; + } alert_threshold_inv; + struct packed { + logic [15:0] q; + } alert_threshold; + } entropy_src_reg2hw_alert_threshold_reg_t; + + typedef struct packed { + struct packed { + logic [3:0] q; + } fw_ov_entropy_insert; + struct packed { + logic [3:0] q; + } fw_ov_mode; + } entropy_src_reg2hw_fw_ov_control_reg_t; + + typedef struct packed { + logic [3:0] q; + } entropy_src_reg2hw_fw_ov_sha3_start_reg_t; + + typedef struct packed { + logic [31:0] q; + logic re; + } entropy_src_reg2hw_fw_ov_rd_data_reg_t; + + typedef struct packed { + logic [31:0] q; + logic qe; + } entropy_src_reg2hw_fw_ov_wr_data_reg_t; + + typedef struct packed { + logic [5:0] q; + } entropy_src_reg2hw_observe_fifo_thresh_reg_t; + + typedef struct packed { + logic [4:0] q; + logic qe; + } entropy_src_reg2hw_err_code_test_reg_t; + + typedef struct packed { + struct packed { + logic d; + logic de; + } es_entropy_valid; + struct packed { + logic d; + logic de; + } es_health_test_failed; + struct packed { + logic d; + logic de; + } es_observe_fifo_ready; + struct packed { + logic d; + logic de; + } es_fatal_err; + } entropy_src_hw2reg_intr_state_reg_t; + + typedef struct packed { + logic d; + logic de; + } entropy_src_hw2reg_regwen_reg_t; + + typedef struct packed { + logic [31:0] d; + } entropy_src_hw2reg_entropy_data_reg_t; + + typedef struct packed { + struct packed { + logic [15:0] d; + } fips_thresh; + struct packed { + logic [15:0] d; + } bypass_thresh; + } entropy_src_hw2reg_repcnt_thresholds_reg_t; + + typedef struct packed { + struct packed { + logic [15:0] d; + } fips_thresh; + struct packed { + logic [15:0] d; + } bypass_thresh; + } entropy_src_hw2reg_repcnts_thresholds_reg_t; + + typedef struct packed { + struct packed { + logic [15:0] d; + } fips_thresh; + struct packed { + logic [15:0] d; + } bypass_thresh; + } entropy_src_hw2reg_adaptp_hi_thresholds_reg_t; + + typedef struct packed { + struct packed { + logic [15:0] d; + } fips_thresh; + struct packed { + logic [15:0] d; + } bypass_thresh; + } entropy_src_hw2reg_adaptp_lo_thresholds_reg_t; + + typedef struct packed { + struct packed { + logic [15:0] d; + } fips_thresh; + struct packed { + logic [15:0] d; + } bypass_thresh; + } entropy_src_hw2reg_bucket_thresholds_reg_t; + + typedef struct packed { + struct packed { + logic [15:0] d; + } fips_thresh; + struct packed { + logic [15:0] d; + } bypass_thresh; + } entropy_src_hw2reg_markov_hi_thresholds_reg_t; + + typedef struct packed { + struct packed { + logic [15:0] d; + } fips_thresh; + struct packed { + logic [15:0] d; + } bypass_thresh; + } entropy_src_hw2reg_markov_lo_thresholds_reg_t; + + typedef struct packed { + struct packed { + logic [15:0] d; + } fips_thresh; + struct packed { + logic [15:0] d; + } bypass_thresh; + } entropy_src_hw2reg_extht_hi_thresholds_reg_t; + + typedef struct packed { + struct packed { + logic [15:0] d; + } fips_thresh; + struct packed { + logic [15:0] d; + } bypass_thresh; + } entropy_src_hw2reg_extht_lo_thresholds_reg_t; + + typedef struct packed { + struct packed { + logic [15:0] d; + } fips_watermark; + struct packed { + logic [15:0] d; + } bypass_watermark; + } entropy_src_hw2reg_repcnt_hi_watermarks_reg_t; + + typedef struct packed { + struct packed { + logic [15:0] d; + } fips_watermark; + struct packed { + logic [15:0] d; + } bypass_watermark; + } entropy_src_hw2reg_repcnts_hi_watermarks_reg_t; + + typedef struct packed { + struct packed { + logic [15:0] d; + } fips_watermark; + struct packed { + logic [15:0] d; + } bypass_watermark; + } entropy_src_hw2reg_adaptp_hi_watermarks_reg_t; + + typedef struct packed { + struct packed { + logic [15:0] d; + } fips_watermark; + struct packed { + logic [15:0] d; + } bypass_watermark; + } entropy_src_hw2reg_adaptp_lo_watermarks_reg_t; + + typedef struct packed { + struct packed { + logic [15:0] d; + } fips_watermark; + struct packed { + logic [15:0] d; + } bypass_watermark; + } entropy_src_hw2reg_extht_hi_watermarks_reg_t; + + typedef struct packed { + struct packed { + logic [15:0] d; + } fips_watermark; + struct packed { + logic [15:0] d; + } bypass_watermark; + } entropy_src_hw2reg_extht_lo_watermarks_reg_t; + + typedef struct packed { + struct packed { + logic [15:0] d; + } fips_watermark; + struct packed { + logic [15:0] d; + } bypass_watermark; + } entropy_src_hw2reg_bucket_hi_watermarks_reg_t; + + typedef struct packed { + struct packed { + logic [15:0] d; + } fips_watermark; + struct packed { + logic [15:0] d; + } bypass_watermark; + } entropy_src_hw2reg_markov_hi_watermarks_reg_t; + + typedef struct packed { + struct packed { + logic [15:0] d; + } fips_watermark; + struct packed { + logic [15:0] d; + } bypass_watermark; + } entropy_src_hw2reg_markov_lo_watermarks_reg_t; + + typedef struct packed { + logic [31:0] d; + } entropy_src_hw2reg_repcnt_total_fails_reg_t; + + typedef struct packed { + logic [31:0] d; + } entropy_src_hw2reg_repcnts_total_fails_reg_t; + + typedef struct packed { + logic [31:0] d; + } entropy_src_hw2reg_adaptp_hi_total_fails_reg_t; + + typedef struct packed { + logic [31:0] d; + } entropy_src_hw2reg_adaptp_lo_total_fails_reg_t; + + typedef struct packed { + logic [31:0] d; + } entropy_src_hw2reg_bucket_total_fails_reg_t; + + typedef struct packed { + logic [31:0] d; + } entropy_src_hw2reg_markov_hi_total_fails_reg_t; + + typedef struct packed { + logic [31:0] d; + } entropy_src_hw2reg_markov_lo_total_fails_reg_t; + + typedef struct packed { + logic [31:0] d; + } entropy_src_hw2reg_extht_hi_total_fails_reg_t; + + typedef struct packed { + logic [31:0] d; + } entropy_src_hw2reg_extht_lo_total_fails_reg_t; + + typedef struct packed { + logic [15:0] d; + } entropy_src_hw2reg_alert_summary_fail_counts_reg_t; + + typedef struct packed { + struct packed { + logic [3:0] d; + } repcnt_fail_count; + struct packed { + logic [3:0] d; + } adaptp_hi_fail_count; + struct packed { + logic [3:0] d; + } adaptp_lo_fail_count; + struct packed { + logic [3:0] d; + } bucket_fail_count; + struct packed { + logic [3:0] d; + } markov_hi_fail_count; + struct packed { + logic [3:0] d; + } markov_lo_fail_count; + struct packed { + logic [3:0] d; + } repcnts_fail_count; + } entropy_src_hw2reg_alert_fail_counts_reg_t; + + typedef struct packed { + struct packed { + logic [3:0] d; + } extht_hi_fail_count; + struct packed { + logic [3:0] d; + } extht_lo_fail_count; + } entropy_src_hw2reg_extht_fail_counts_reg_t; + + typedef struct packed { + logic d; + } entropy_src_hw2reg_fw_ov_wr_fifo_full_reg_t; + + typedef struct packed { + logic d; + logic de; + } entropy_src_hw2reg_fw_ov_rd_fifo_overflow_reg_t; + + typedef struct packed { + logic [31:0] d; + } entropy_src_hw2reg_fw_ov_rd_data_reg_t; + + typedef struct packed { + logic [5:0] d; + } entropy_src_hw2reg_observe_fifo_depth_reg_t; + + typedef struct packed { + struct packed { + logic [1:0] d; + } entropy_fifo_depth; + struct packed { + logic [2:0] d; + } sha3_fsm; + struct packed { + logic d; + } sha3_block_pr; + struct packed { + logic d; + } sha3_squeezing; + struct packed { + logic d; + } sha3_absorbed; + struct packed { + logic d; + } sha3_err; + struct packed { + logic d; + } main_sm_idle; + struct packed { + logic d; + } main_sm_boot_done; + } entropy_src_hw2reg_debug_status_reg_t; + + typedef struct packed { + struct packed { + logic d; + logic de; + } fips_enable_field_alert; + struct packed { + logic d; + logic de; + } entropy_data_reg_en_field_alert; + struct packed { + logic d; + logic de; + } module_enable_field_alert; + struct packed { + logic d; + logic de; + } threshold_scope_field_alert; + struct packed { + logic d; + logic de; + } rng_bit_enable_field_alert; + struct packed { + logic d; + logic de; + } fw_ov_sha3_start_field_alert; + struct packed { + logic d; + logic de; + } fw_ov_mode_field_alert; + struct packed { + logic d; + logic de; + } fw_ov_entropy_insert_field_alert; + struct packed { + logic d; + logic de; + } es_route_field_alert; + struct packed { + logic d; + logic de; + } es_type_field_alert; + struct packed { + logic d; + logic de; + } es_main_sm_alert; + struct packed { + logic d; + logic de; + } es_bus_cmp_alert; + struct packed { + logic d; + logic de; + } es_thresh_cfg_alert; + struct packed { + logic d; + logic de; + } es_fw_ov_wr_alert; + struct packed { + logic d; + logic de; + } es_fw_ov_disable_alert; + struct packed { + logic d; + logic de; + } fips_flag_field_alert; + struct packed { + logic d; + logic de; + } rng_fips_field_alert; + struct packed { + logic d; + logic de; + } postht_entropy_drop_alert; + } entropy_src_hw2reg_recov_alert_sts_reg_t; + + typedef struct packed { + struct packed { + logic d; + logic de; + } sfifo_esrng_err; + struct packed { + logic d; + logic de; + } sfifo_distr_err; + struct packed { + logic d; + logic de; + } sfifo_observe_err; + struct packed { + logic d; + logic de; + } sfifo_esfinal_err; + struct packed { + logic d; + logic de; + } es_ack_sm_err; + struct packed { + logic d; + logic de; + } es_main_sm_err; + struct packed { + logic d; + logic de; + } es_cntr_err; + struct packed { + logic d; + logic de; + } sha3_state_err; + struct packed { + logic d; + logic de; + } sha3_rst_storage_err; + struct packed { + logic d; + logic de; + } fifo_write_err; + struct packed { + logic d; + logic de; + } fifo_read_err; + struct packed { + logic d; + logic de; + } fifo_state_err; + } entropy_src_hw2reg_err_code_reg_t; + + typedef struct packed { + logic [8:0] d; + logic de; + } entropy_src_hw2reg_main_sm_state_reg_t; + + // Register -> HW type + typedef struct packed { + entropy_src_reg2hw_intr_state_reg_t intr_state; // [551:548] + entropy_src_reg2hw_intr_enable_reg_t intr_enable; // [547:544] + entropy_src_reg2hw_intr_test_reg_t intr_test; // [543:536] + entropy_src_reg2hw_alert_test_reg_t alert_test; // [535:532] + entropy_src_reg2hw_sw_regupd_reg_t sw_regupd; // [531:531] + entropy_src_reg2hw_module_enable_reg_t module_enable; // [530:527] + entropy_src_reg2hw_conf_reg_t conf; // [526:501] + entropy_src_reg2hw_entropy_control_reg_t entropy_control; // [500:493] + entropy_src_reg2hw_entropy_data_reg_t entropy_data; // [492:460] + entropy_src_reg2hw_health_test_windows_reg_t health_test_windows; // [459:428] + entropy_src_reg2hw_repcnt_thresholds_reg_t repcnt_thresholds; // [427:394] + entropy_src_reg2hw_repcnts_thresholds_reg_t repcnts_thresholds; // [393:360] + entropy_src_reg2hw_adaptp_hi_thresholds_reg_t adaptp_hi_thresholds; // [359:326] + entropy_src_reg2hw_adaptp_lo_thresholds_reg_t adaptp_lo_thresholds; // [325:292] + entropy_src_reg2hw_bucket_thresholds_reg_t bucket_thresholds; // [291:258] + entropy_src_reg2hw_markov_hi_thresholds_reg_t markov_hi_thresholds; // [257:224] + entropy_src_reg2hw_markov_lo_thresholds_reg_t markov_lo_thresholds; // [223:190] + entropy_src_reg2hw_extht_hi_thresholds_reg_t extht_hi_thresholds; // [189:156] + entropy_src_reg2hw_extht_lo_thresholds_reg_t extht_lo_thresholds; // [155:122] + entropy_src_reg2hw_alert_threshold_reg_t alert_threshold; // [121:90] + entropy_src_reg2hw_fw_ov_control_reg_t fw_ov_control; // [89:82] + entropy_src_reg2hw_fw_ov_sha3_start_reg_t fw_ov_sha3_start; // [81:78] + entropy_src_reg2hw_fw_ov_rd_data_reg_t fw_ov_rd_data; // [77:45] + entropy_src_reg2hw_fw_ov_wr_data_reg_t fw_ov_wr_data; // [44:12] + entropy_src_reg2hw_observe_fifo_thresh_reg_t observe_fifo_thresh; // [11:6] + entropy_src_reg2hw_err_code_test_reg_t err_code_test; // [5:0] + } entropy_src_reg2hw_t; + + // HW -> register type + typedef struct packed { + entropy_src_hw2reg_intr_state_reg_t intr_state; // [1079:1072] + entropy_src_hw2reg_regwen_reg_t regwen; // [1071:1070] + entropy_src_hw2reg_entropy_data_reg_t entropy_data; // [1069:1038] + entropy_src_hw2reg_repcnt_thresholds_reg_t repcnt_thresholds; // [1037:1006] + entropy_src_hw2reg_repcnts_thresholds_reg_t repcnts_thresholds; // [1005:974] + entropy_src_hw2reg_adaptp_hi_thresholds_reg_t adaptp_hi_thresholds; // [973:942] + entropy_src_hw2reg_adaptp_lo_thresholds_reg_t adaptp_lo_thresholds; // [941:910] + entropy_src_hw2reg_bucket_thresholds_reg_t bucket_thresholds; // [909:878] + entropy_src_hw2reg_markov_hi_thresholds_reg_t markov_hi_thresholds; // [877:846] + entropy_src_hw2reg_markov_lo_thresholds_reg_t markov_lo_thresholds; // [845:814] + entropy_src_hw2reg_extht_hi_thresholds_reg_t extht_hi_thresholds; // [813:782] + entropy_src_hw2reg_extht_lo_thresholds_reg_t extht_lo_thresholds; // [781:750] + entropy_src_hw2reg_repcnt_hi_watermarks_reg_t repcnt_hi_watermarks; // [749:718] + entropy_src_hw2reg_repcnts_hi_watermarks_reg_t repcnts_hi_watermarks; // [717:686] + entropy_src_hw2reg_adaptp_hi_watermarks_reg_t adaptp_hi_watermarks; // [685:654] + entropy_src_hw2reg_adaptp_lo_watermarks_reg_t adaptp_lo_watermarks; // [653:622] + entropy_src_hw2reg_extht_hi_watermarks_reg_t extht_hi_watermarks; // [621:590] + entropy_src_hw2reg_extht_lo_watermarks_reg_t extht_lo_watermarks; // [589:558] + entropy_src_hw2reg_bucket_hi_watermarks_reg_t bucket_hi_watermarks; // [557:526] + entropy_src_hw2reg_markov_hi_watermarks_reg_t markov_hi_watermarks; // [525:494] + entropy_src_hw2reg_markov_lo_watermarks_reg_t markov_lo_watermarks; // [493:462] + entropy_src_hw2reg_repcnt_total_fails_reg_t repcnt_total_fails; // [461:430] + entropy_src_hw2reg_repcnts_total_fails_reg_t repcnts_total_fails; // [429:398] + entropy_src_hw2reg_adaptp_hi_total_fails_reg_t adaptp_hi_total_fails; // [397:366] + entropy_src_hw2reg_adaptp_lo_total_fails_reg_t adaptp_lo_total_fails; // [365:334] + entropy_src_hw2reg_bucket_total_fails_reg_t bucket_total_fails; // [333:302] + entropy_src_hw2reg_markov_hi_total_fails_reg_t markov_hi_total_fails; // [301:270] + entropy_src_hw2reg_markov_lo_total_fails_reg_t markov_lo_total_fails; // [269:238] + entropy_src_hw2reg_extht_hi_total_fails_reg_t extht_hi_total_fails; // [237:206] + entropy_src_hw2reg_extht_lo_total_fails_reg_t extht_lo_total_fails; // [205:174] + entropy_src_hw2reg_alert_summary_fail_counts_reg_t alert_summary_fail_counts; // [173:158] + entropy_src_hw2reg_alert_fail_counts_reg_t alert_fail_counts; // [157:130] + entropy_src_hw2reg_extht_fail_counts_reg_t extht_fail_counts; // [129:122] + entropy_src_hw2reg_fw_ov_wr_fifo_full_reg_t fw_ov_wr_fifo_full; // [121:121] + entropy_src_hw2reg_fw_ov_rd_fifo_overflow_reg_t fw_ov_rd_fifo_overflow; // [120:119] + entropy_src_hw2reg_fw_ov_rd_data_reg_t fw_ov_rd_data; // [118:87] + entropy_src_hw2reg_observe_fifo_depth_reg_t observe_fifo_depth; // [86:81] + entropy_src_hw2reg_debug_status_reg_t debug_status; // [80:70] + entropy_src_hw2reg_recov_alert_sts_reg_t recov_alert_sts; // [69:34] + entropy_src_hw2reg_err_code_reg_t err_code; // [33:10] + entropy_src_hw2reg_main_sm_state_reg_t main_sm_state; // [9:0] + } entropy_src_hw2reg_t; + + // Register offsets + parameter logic [BlockAw-1:0] ENTROPY_SRC_INTR_STATE_OFFSET = 8'h 0; + parameter logic [BlockAw-1:0] ENTROPY_SRC_INTR_ENABLE_OFFSET = 8'h 4; + parameter logic [BlockAw-1:0] ENTROPY_SRC_INTR_TEST_OFFSET = 8'h 8; + parameter logic [BlockAw-1:0] ENTROPY_SRC_ALERT_TEST_OFFSET = 8'h c; + parameter logic [BlockAw-1:0] ENTROPY_SRC_ME_REGWEN_OFFSET = 8'h 10; + parameter logic [BlockAw-1:0] ENTROPY_SRC_SW_REGUPD_OFFSET = 8'h 14; + parameter logic [BlockAw-1:0] ENTROPY_SRC_REGWEN_OFFSET = 8'h 18; + parameter logic [BlockAw-1:0] ENTROPY_SRC_REV_OFFSET = 8'h 1c; + parameter logic [BlockAw-1:0] ENTROPY_SRC_MODULE_ENABLE_OFFSET = 8'h 20; + parameter logic [BlockAw-1:0] ENTROPY_SRC_CONF_OFFSET = 8'h 24; + parameter logic [BlockAw-1:0] ENTROPY_SRC_ENTROPY_CONTROL_OFFSET = 8'h 28; + parameter logic [BlockAw-1:0] ENTROPY_SRC_ENTROPY_DATA_OFFSET = 8'h 2c; + parameter logic [BlockAw-1:0] ENTROPY_SRC_HEALTH_TEST_WINDOWS_OFFSET = 8'h 30; + parameter logic [BlockAw-1:0] ENTROPY_SRC_REPCNT_THRESHOLDS_OFFSET = 8'h 34; + parameter logic [BlockAw-1:0] ENTROPY_SRC_REPCNTS_THRESHOLDS_OFFSET = 8'h 38; + parameter logic [BlockAw-1:0] ENTROPY_SRC_ADAPTP_HI_THRESHOLDS_OFFSET = 8'h 3c; + parameter logic [BlockAw-1:0] ENTROPY_SRC_ADAPTP_LO_THRESHOLDS_OFFSET = 8'h 40; + parameter logic [BlockAw-1:0] ENTROPY_SRC_BUCKET_THRESHOLDS_OFFSET = 8'h 44; + parameter logic [BlockAw-1:0] ENTROPY_SRC_MARKOV_HI_THRESHOLDS_OFFSET = 8'h 48; + parameter logic [BlockAw-1:0] ENTROPY_SRC_MARKOV_LO_THRESHOLDS_OFFSET = 8'h 4c; + parameter logic [BlockAw-1:0] ENTROPY_SRC_EXTHT_HI_THRESHOLDS_OFFSET = 8'h 50; + parameter logic [BlockAw-1:0] ENTROPY_SRC_EXTHT_LO_THRESHOLDS_OFFSET = 8'h 54; + parameter logic [BlockAw-1:0] ENTROPY_SRC_REPCNT_HI_WATERMARKS_OFFSET = 8'h 58; + parameter logic [BlockAw-1:0] ENTROPY_SRC_REPCNTS_HI_WATERMARKS_OFFSET = 8'h 5c; + parameter logic [BlockAw-1:0] ENTROPY_SRC_ADAPTP_HI_WATERMARKS_OFFSET = 8'h 60; + parameter logic [BlockAw-1:0] ENTROPY_SRC_ADAPTP_LO_WATERMARKS_OFFSET = 8'h 64; + parameter logic [BlockAw-1:0] ENTROPY_SRC_EXTHT_HI_WATERMARKS_OFFSET = 8'h 68; + parameter logic [BlockAw-1:0] ENTROPY_SRC_EXTHT_LO_WATERMARKS_OFFSET = 8'h 6c; + parameter logic [BlockAw-1:0] ENTROPY_SRC_BUCKET_HI_WATERMARKS_OFFSET = 8'h 70; + parameter logic [BlockAw-1:0] ENTROPY_SRC_MARKOV_HI_WATERMARKS_OFFSET = 8'h 74; + parameter logic [BlockAw-1:0] ENTROPY_SRC_MARKOV_LO_WATERMARKS_OFFSET = 8'h 78; + parameter logic [BlockAw-1:0] ENTROPY_SRC_REPCNT_TOTAL_FAILS_OFFSET = 8'h 7c; + parameter logic [BlockAw-1:0] ENTROPY_SRC_REPCNTS_TOTAL_FAILS_OFFSET = 8'h 80; + parameter logic [BlockAw-1:0] ENTROPY_SRC_ADAPTP_HI_TOTAL_FAILS_OFFSET = 8'h 84; + parameter logic [BlockAw-1:0] ENTROPY_SRC_ADAPTP_LO_TOTAL_FAILS_OFFSET = 8'h 88; + parameter logic [BlockAw-1:0] ENTROPY_SRC_BUCKET_TOTAL_FAILS_OFFSET = 8'h 8c; + parameter logic [BlockAw-1:0] ENTROPY_SRC_MARKOV_HI_TOTAL_FAILS_OFFSET = 8'h 90; + parameter logic [BlockAw-1:0] ENTROPY_SRC_MARKOV_LO_TOTAL_FAILS_OFFSET = 8'h 94; + parameter logic [BlockAw-1:0] ENTROPY_SRC_EXTHT_HI_TOTAL_FAILS_OFFSET = 8'h 98; + parameter logic [BlockAw-1:0] ENTROPY_SRC_EXTHT_LO_TOTAL_FAILS_OFFSET = 8'h 9c; + parameter logic [BlockAw-1:0] ENTROPY_SRC_ALERT_THRESHOLD_OFFSET = 8'h a0; + parameter logic [BlockAw-1:0] ENTROPY_SRC_ALERT_SUMMARY_FAIL_COUNTS_OFFSET = 8'h a4; + parameter logic [BlockAw-1:0] ENTROPY_SRC_ALERT_FAIL_COUNTS_OFFSET = 8'h a8; + parameter logic [BlockAw-1:0] ENTROPY_SRC_EXTHT_FAIL_COUNTS_OFFSET = 8'h ac; + parameter logic [BlockAw-1:0] ENTROPY_SRC_FW_OV_CONTROL_OFFSET = 8'h b0; + parameter logic [BlockAw-1:0] ENTROPY_SRC_FW_OV_SHA3_START_OFFSET = 8'h b4; + parameter logic [BlockAw-1:0] ENTROPY_SRC_FW_OV_WR_FIFO_FULL_OFFSET = 8'h b8; + parameter logic [BlockAw-1:0] ENTROPY_SRC_FW_OV_RD_FIFO_OVERFLOW_OFFSET = 8'h bc; + parameter logic [BlockAw-1:0] ENTROPY_SRC_FW_OV_RD_DATA_OFFSET = 8'h c0; + parameter logic [BlockAw-1:0] ENTROPY_SRC_FW_OV_WR_DATA_OFFSET = 8'h c4; + parameter logic [BlockAw-1:0] ENTROPY_SRC_OBSERVE_FIFO_THRESH_OFFSET = 8'h c8; + parameter logic [BlockAw-1:0] ENTROPY_SRC_OBSERVE_FIFO_DEPTH_OFFSET = 8'h cc; + parameter logic [BlockAw-1:0] ENTROPY_SRC_DEBUG_STATUS_OFFSET = 8'h d0; + parameter logic [BlockAw-1:0] ENTROPY_SRC_RECOV_ALERT_STS_OFFSET = 8'h d4; + parameter logic [BlockAw-1:0] ENTROPY_SRC_ERR_CODE_OFFSET = 8'h d8; + parameter logic [BlockAw-1:0] ENTROPY_SRC_ERR_CODE_TEST_OFFSET = 8'h dc; + parameter logic [BlockAw-1:0] ENTROPY_SRC_MAIN_SM_STATE_OFFSET = 8'h e0; + + // Reset values for hwext registers and their fields + parameter logic [3:0] ENTROPY_SRC_INTR_TEST_RESVAL = 4'h 0; + parameter logic [0:0] ENTROPY_SRC_INTR_TEST_ES_ENTROPY_VALID_RESVAL = 1'h 0; + parameter logic [0:0] ENTROPY_SRC_INTR_TEST_ES_HEALTH_TEST_FAILED_RESVAL = 1'h 0; + parameter logic [0:0] ENTROPY_SRC_INTR_TEST_ES_OBSERVE_FIFO_READY_RESVAL = 1'h 0; + parameter logic [0:0] ENTROPY_SRC_INTR_TEST_ES_FATAL_ERR_RESVAL = 1'h 0; + parameter logic [1:0] ENTROPY_SRC_ALERT_TEST_RESVAL = 2'h 0; + parameter logic [0:0] ENTROPY_SRC_ALERT_TEST_RECOV_ALERT_RESVAL = 1'h 0; + parameter logic [0:0] ENTROPY_SRC_ALERT_TEST_FATAL_ALERT_RESVAL = 1'h 0; + parameter logic [31:0] ENTROPY_SRC_ENTROPY_DATA_RESVAL = 32'h 0; + parameter logic [31:0] ENTROPY_SRC_REPCNT_THRESHOLDS_RESVAL = 32'h ffffffff; + parameter logic [15:0] ENTROPY_SRC_REPCNT_THRESHOLDS_FIPS_THRESH_RESVAL = 16'h ffff; + parameter logic [15:0] ENTROPY_SRC_REPCNT_THRESHOLDS_BYPASS_THRESH_RESVAL = 16'h ffff; + parameter logic [31:0] ENTROPY_SRC_REPCNTS_THRESHOLDS_RESVAL = 32'h ffffffff; + parameter logic [15:0] ENTROPY_SRC_REPCNTS_THRESHOLDS_FIPS_THRESH_RESVAL = 16'h ffff; + parameter logic [15:0] ENTROPY_SRC_REPCNTS_THRESHOLDS_BYPASS_THRESH_RESVAL = 16'h ffff; + parameter logic [31:0] ENTROPY_SRC_ADAPTP_HI_THRESHOLDS_RESVAL = 32'h ffffffff; + parameter logic [15:0] ENTROPY_SRC_ADAPTP_HI_THRESHOLDS_FIPS_THRESH_RESVAL = 16'h ffff; + parameter logic [15:0] ENTROPY_SRC_ADAPTP_HI_THRESHOLDS_BYPASS_THRESH_RESVAL = 16'h ffff; + parameter logic [31:0] ENTROPY_SRC_ADAPTP_LO_THRESHOLDS_RESVAL = 32'h 0; + parameter logic [15:0] ENTROPY_SRC_ADAPTP_LO_THRESHOLDS_FIPS_THRESH_RESVAL = 16'h 0; + parameter logic [15:0] ENTROPY_SRC_ADAPTP_LO_THRESHOLDS_BYPASS_THRESH_RESVAL = 16'h 0; + parameter logic [31:0] ENTROPY_SRC_BUCKET_THRESHOLDS_RESVAL = 32'h ffffffff; + parameter logic [15:0] ENTROPY_SRC_BUCKET_THRESHOLDS_FIPS_THRESH_RESVAL = 16'h ffff; + parameter logic [15:0] ENTROPY_SRC_BUCKET_THRESHOLDS_BYPASS_THRESH_RESVAL = 16'h ffff; + parameter logic [31:0] ENTROPY_SRC_MARKOV_HI_THRESHOLDS_RESVAL = 32'h ffffffff; + parameter logic [15:0] ENTROPY_SRC_MARKOV_HI_THRESHOLDS_FIPS_THRESH_RESVAL = 16'h ffff; + parameter logic [15:0] ENTROPY_SRC_MARKOV_HI_THRESHOLDS_BYPASS_THRESH_RESVAL = 16'h ffff; + parameter logic [31:0] ENTROPY_SRC_MARKOV_LO_THRESHOLDS_RESVAL = 32'h 0; + parameter logic [15:0] ENTROPY_SRC_MARKOV_LO_THRESHOLDS_FIPS_THRESH_RESVAL = 16'h 0; + parameter logic [15:0] ENTROPY_SRC_MARKOV_LO_THRESHOLDS_BYPASS_THRESH_RESVAL = 16'h 0; + parameter logic [31:0] ENTROPY_SRC_EXTHT_HI_THRESHOLDS_RESVAL = 32'h ffffffff; + parameter logic [15:0] ENTROPY_SRC_EXTHT_HI_THRESHOLDS_FIPS_THRESH_RESVAL = 16'h ffff; + parameter logic [15:0] ENTROPY_SRC_EXTHT_HI_THRESHOLDS_BYPASS_THRESH_RESVAL = 16'h ffff; + parameter logic [31:0] ENTROPY_SRC_EXTHT_LO_THRESHOLDS_RESVAL = 32'h 0; + parameter logic [15:0] ENTROPY_SRC_EXTHT_LO_THRESHOLDS_FIPS_THRESH_RESVAL = 16'h 0; + parameter logic [15:0] ENTROPY_SRC_EXTHT_LO_THRESHOLDS_BYPASS_THRESH_RESVAL = 16'h 0; + parameter logic [31:0] ENTROPY_SRC_REPCNT_HI_WATERMARKS_RESVAL = 32'h 0; + parameter logic [31:0] ENTROPY_SRC_REPCNTS_HI_WATERMARKS_RESVAL = 32'h 0; + parameter logic [31:0] ENTROPY_SRC_ADAPTP_HI_WATERMARKS_RESVAL = 32'h 0; + parameter logic [31:0] ENTROPY_SRC_ADAPTP_LO_WATERMARKS_RESVAL = 32'h ffffffff; + parameter logic [15:0] ENTROPY_SRC_ADAPTP_LO_WATERMARKS_FIPS_WATERMARK_RESVAL = 16'h ffff; + parameter logic [15:0] ENTROPY_SRC_ADAPTP_LO_WATERMARKS_BYPASS_WATERMARK_RESVAL = 16'h ffff; + parameter logic [31:0] ENTROPY_SRC_EXTHT_HI_WATERMARKS_RESVAL = 32'h 0; + parameter logic [31:0] ENTROPY_SRC_EXTHT_LO_WATERMARKS_RESVAL = 32'h ffffffff; + parameter logic [15:0] ENTROPY_SRC_EXTHT_LO_WATERMARKS_FIPS_WATERMARK_RESVAL = 16'h ffff; + parameter logic [15:0] ENTROPY_SRC_EXTHT_LO_WATERMARKS_BYPASS_WATERMARK_RESVAL = 16'h ffff; + parameter logic [31:0] ENTROPY_SRC_BUCKET_HI_WATERMARKS_RESVAL = 32'h 0; + parameter logic [31:0] ENTROPY_SRC_MARKOV_HI_WATERMARKS_RESVAL = 32'h 0; + parameter logic [31:0] ENTROPY_SRC_MARKOV_LO_WATERMARKS_RESVAL = 32'h ffffffff; + parameter logic [15:0] ENTROPY_SRC_MARKOV_LO_WATERMARKS_FIPS_WATERMARK_RESVAL = 16'h ffff; + parameter logic [15:0] ENTROPY_SRC_MARKOV_LO_WATERMARKS_BYPASS_WATERMARK_RESVAL = 16'h ffff; + parameter logic [31:0] ENTROPY_SRC_REPCNT_TOTAL_FAILS_RESVAL = 32'h 0; + parameter logic [31:0] ENTROPY_SRC_REPCNTS_TOTAL_FAILS_RESVAL = 32'h 0; + parameter logic [31:0] ENTROPY_SRC_ADAPTP_HI_TOTAL_FAILS_RESVAL = 32'h 0; + parameter logic [31:0] ENTROPY_SRC_ADAPTP_LO_TOTAL_FAILS_RESVAL = 32'h 0; + parameter logic [31:0] ENTROPY_SRC_BUCKET_TOTAL_FAILS_RESVAL = 32'h 0; + parameter logic [31:0] ENTROPY_SRC_MARKOV_HI_TOTAL_FAILS_RESVAL = 32'h 0; + parameter logic [31:0] ENTROPY_SRC_MARKOV_LO_TOTAL_FAILS_RESVAL = 32'h 0; + parameter logic [31:0] ENTROPY_SRC_EXTHT_HI_TOTAL_FAILS_RESVAL = 32'h 0; + parameter logic [31:0] ENTROPY_SRC_EXTHT_LO_TOTAL_FAILS_RESVAL = 32'h 0; + parameter logic [15:0] ENTROPY_SRC_ALERT_SUMMARY_FAIL_COUNTS_RESVAL = 16'h 0; + parameter logic [31:0] ENTROPY_SRC_ALERT_FAIL_COUNTS_RESVAL = 32'h 0; + parameter logic [7:0] ENTROPY_SRC_EXTHT_FAIL_COUNTS_RESVAL = 8'h 0; + parameter logic [0:0] ENTROPY_SRC_FW_OV_WR_FIFO_FULL_RESVAL = 1'h 0; + parameter logic [31:0] ENTROPY_SRC_FW_OV_RD_DATA_RESVAL = 32'h 0; + parameter logic [31:0] ENTROPY_SRC_FW_OV_WR_DATA_RESVAL = 32'h 0; + parameter logic [5:0] ENTROPY_SRC_OBSERVE_FIFO_DEPTH_RESVAL = 6'h 0; + parameter logic [17:0] ENTROPY_SRC_DEBUG_STATUS_RESVAL = 18'h 10000; + parameter logic [0:0] ENTROPY_SRC_DEBUG_STATUS_MAIN_SM_IDLE_RESVAL = 1'h 1; + + // Register index + typedef enum logic [31:0] { + ENTROPY_SRC_INTR_STATE, + ENTROPY_SRC_INTR_ENABLE, + ENTROPY_SRC_INTR_TEST, + ENTROPY_SRC_ALERT_TEST, + ENTROPY_SRC_ME_REGWEN, + ENTROPY_SRC_SW_REGUPD, + ENTROPY_SRC_REGWEN, + ENTROPY_SRC_REV, + ENTROPY_SRC_MODULE_ENABLE, + ENTROPY_SRC_CONF, + ENTROPY_SRC_ENTROPY_CONTROL, + ENTROPY_SRC_ENTROPY_DATA, + ENTROPY_SRC_HEALTH_TEST_WINDOWS, + ENTROPY_SRC_REPCNT_THRESHOLDS, + ENTROPY_SRC_REPCNTS_THRESHOLDS, + ENTROPY_SRC_ADAPTP_HI_THRESHOLDS, + ENTROPY_SRC_ADAPTP_LO_THRESHOLDS, + ENTROPY_SRC_BUCKET_THRESHOLDS, + ENTROPY_SRC_MARKOV_HI_THRESHOLDS, + ENTROPY_SRC_MARKOV_LO_THRESHOLDS, + ENTROPY_SRC_EXTHT_HI_THRESHOLDS, + ENTROPY_SRC_EXTHT_LO_THRESHOLDS, + ENTROPY_SRC_REPCNT_HI_WATERMARKS, + ENTROPY_SRC_REPCNTS_HI_WATERMARKS, + ENTROPY_SRC_ADAPTP_HI_WATERMARKS, + ENTROPY_SRC_ADAPTP_LO_WATERMARKS, + ENTROPY_SRC_EXTHT_HI_WATERMARKS, + ENTROPY_SRC_EXTHT_LO_WATERMARKS, + ENTROPY_SRC_BUCKET_HI_WATERMARKS, + ENTROPY_SRC_MARKOV_HI_WATERMARKS, + ENTROPY_SRC_MARKOV_LO_WATERMARKS, + ENTROPY_SRC_REPCNT_TOTAL_FAILS, + ENTROPY_SRC_REPCNTS_TOTAL_FAILS, + ENTROPY_SRC_ADAPTP_HI_TOTAL_FAILS, + ENTROPY_SRC_ADAPTP_LO_TOTAL_FAILS, + ENTROPY_SRC_BUCKET_TOTAL_FAILS, + ENTROPY_SRC_MARKOV_HI_TOTAL_FAILS, + ENTROPY_SRC_MARKOV_LO_TOTAL_FAILS, + ENTROPY_SRC_EXTHT_HI_TOTAL_FAILS, + ENTROPY_SRC_EXTHT_LO_TOTAL_FAILS, + ENTROPY_SRC_ALERT_THRESHOLD, + ENTROPY_SRC_ALERT_SUMMARY_FAIL_COUNTS, + ENTROPY_SRC_ALERT_FAIL_COUNTS, + ENTROPY_SRC_EXTHT_FAIL_COUNTS, + ENTROPY_SRC_FW_OV_CONTROL, + ENTROPY_SRC_FW_OV_SHA3_START, + ENTROPY_SRC_FW_OV_WR_FIFO_FULL, + ENTROPY_SRC_FW_OV_RD_FIFO_OVERFLOW, + ENTROPY_SRC_FW_OV_RD_DATA, + ENTROPY_SRC_FW_OV_WR_DATA, + ENTROPY_SRC_OBSERVE_FIFO_THRESH, + ENTROPY_SRC_OBSERVE_FIFO_DEPTH, + ENTROPY_SRC_DEBUG_STATUS, + ENTROPY_SRC_RECOV_ALERT_STS, + ENTROPY_SRC_ERR_CODE, + ENTROPY_SRC_ERR_CODE_TEST, + ENTROPY_SRC_MAIN_SM_STATE + } entropy_src_id_e; + + // Register width information to check illegal writes + parameter logic [3:0] ENTROPY_SRC_PERMIT [57] = '{ + 4'b 0001, // index[ 0] ENTROPY_SRC_INTR_STATE + 4'b 0001, // index[ 1] ENTROPY_SRC_INTR_ENABLE + 4'b 0001, // index[ 2] ENTROPY_SRC_INTR_TEST + 4'b 0001, // index[ 3] ENTROPY_SRC_ALERT_TEST + 4'b 0001, // index[ 4] ENTROPY_SRC_ME_REGWEN + 4'b 0001, // index[ 5] ENTROPY_SRC_SW_REGUPD + 4'b 0001, // index[ 6] ENTROPY_SRC_REGWEN + 4'b 0111, // index[ 7] ENTROPY_SRC_REV + 4'b 0001, // index[ 8] ENTROPY_SRC_MODULE_ENABLE + 4'b 1111, // index[ 9] ENTROPY_SRC_CONF + 4'b 0001, // index[10] ENTROPY_SRC_ENTROPY_CONTROL + 4'b 1111, // index[11] ENTROPY_SRC_ENTROPY_DATA + 4'b 1111, // index[12] ENTROPY_SRC_HEALTH_TEST_WINDOWS + 4'b 1111, // index[13] ENTROPY_SRC_REPCNT_THRESHOLDS + 4'b 1111, // index[14] ENTROPY_SRC_REPCNTS_THRESHOLDS + 4'b 1111, // index[15] ENTROPY_SRC_ADAPTP_HI_THRESHOLDS + 4'b 1111, // index[16] ENTROPY_SRC_ADAPTP_LO_THRESHOLDS + 4'b 1111, // index[17] ENTROPY_SRC_BUCKET_THRESHOLDS + 4'b 1111, // index[18] ENTROPY_SRC_MARKOV_HI_THRESHOLDS + 4'b 1111, // index[19] ENTROPY_SRC_MARKOV_LO_THRESHOLDS + 4'b 1111, // index[20] ENTROPY_SRC_EXTHT_HI_THRESHOLDS + 4'b 1111, // index[21] ENTROPY_SRC_EXTHT_LO_THRESHOLDS + 4'b 1111, // index[22] ENTROPY_SRC_REPCNT_HI_WATERMARKS + 4'b 1111, // index[23] ENTROPY_SRC_REPCNTS_HI_WATERMARKS + 4'b 1111, // index[24] ENTROPY_SRC_ADAPTP_HI_WATERMARKS + 4'b 1111, // index[25] ENTROPY_SRC_ADAPTP_LO_WATERMARKS + 4'b 1111, // index[26] ENTROPY_SRC_EXTHT_HI_WATERMARKS + 4'b 1111, // index[27] ENTROPY_SRC_EXTHT_LO_WATERMARKS + 4'b 1111, // index[28] ENTROPY_SRC_BUCKET_HI_WATERMARKS + 4'b 1111, // index[29] ENTROPY_SRC_MARKOV_HI_WATERMARKS + 4'b 1111, // index[30] ENTROPY_SRC_MARKOV_LO_WATERMARKS + 4'b 1111, // index[31] ENTROPY_SRC_REPCNT_TOTAL_FAILS + 4'b 1111, // index[32] ENTROPY_SRC_REPCNTS_TOTAL_FAILS + 4'b 1111, // index[33] ENTROPY_SRC_ADAPTP_HI_TOTAL_FAILS + 4'b 1111, // index[34] ENTROPY_SRC_ADAPTP_LO_TOTAL_FAILS + 4'b 1111, // index[35] ENTROPY_SRC_BUCKET_TOTAL_FAILS + 4'b 1111, // index[36] ENTROPY_SRC_MARKOV_HI_TOTAL_FAILS + 4'b 1111, // index[37] ENTROPY_SRC_MARKOV_LO_TOTAL_FAILS + 4'b 1111, // index[38] ENTROPY_SRC_EXTHT_HI_TOTAL_FAILS + 4'b 1111, // index[39] ENTROPY_SRC_EXTHT_LO_TOTAL_FAILS + 4'b 1111, // index[40] ENTROPY_SRC_ALERT_THRESHOLD + 4'b 0011, // index[41] ENTROPY_SRC_ALERT_SUMMARY_FAIL_COUNTS + 4'b 1111, // index[42] ENTROPY_SRC_ALERT_FAIL_COUNTS + 4'b 0001, // index[43] ENTROPY_SRC_EXTHT_FAIL_COUNTS + 4'b 0001, // index[44] ENTROPY_SRC_FW_OV_CONTROL + 4'b 0001, // index[45] ENTROPY_SRC_FW_OV_SHA3_START + 4'b 0001, // index[46] ENTROPY_SRC_FW_OV_WR_FIFO_FULL + 4'b 0001, // index[47] ENTROPY_SRC_FW_OV_RD_FIFO_OVERFLOW + 4'b 1111, // index[48] ENTROPY_SRC_FW_OV_RD_DATA + 4'b 1111, // index[49] ENTROPY_SRC_FW_OV_WR_DATA + 4'b 0001, // index[50] ENTROPY_SRC_OBSERVE_FIFO_THRESH + 4'b 0001, // index[51] ENTROPY_SRC_OBSERVE_FIFO_DEPTH + 4'b 0111, // index[52] ENTROPY_SRC_DEBUG_STATUS + 4'b 1111, // index[53] ENTROPY_SRC_RECOV_ALERT_STS + 4'b 1111, // index[54] ENTROPY_SRC_ERR_CODE + 4'b 0001, // index[55] ENTROPY_SRC_ERR_CODE_TEST + 4'b 0011 // index[56] ENTROPY_SRC_MAIN_SM_STATE + }; + +endpackage diff --git a/designs/Caliptra/src/caliptra-rtl/entropy_src_reg_top.sv b/designs/Caliptra/src/caliptra-rtl/entropy_src_reg_top.sv new file mode 100644 index 0000000..165d3a1 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/entropy_src_reg_top.sv @@ -0,0 +1,4162 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Register Top module auto-generated by `reggen` + +`include "caliptra_prim_assert.sv" + +module entropy_src_reg_top #( + parameter AHBDataWidth = 64, + parameter AHBAddrWidth = 32 + ) ( + input clk_i, + input rst_ni, + // AMBA AHB Lite Interface + input logic [AHBAddrWidth-1:0] haddr_i, + input logic [AHBDataWidth-1:0] hwdata_i, + input logic hsel_i, + input logic hwrite_i, + input logic hready_i, + input logic [1:0] htrans_i, + input logic [2:0] hsize_i, + + output logic hresp_o, + output logic hreadyout_o, + output logic [AHBDataWidth-1:0] hrdata_o, + + // To HW + output entropy_src_reg_pkg::entropy_src_reg2hw_t reg2hw, // Write + input entropy_src_reg_pkg::entropy_src_hw2reg_t hw2reg, // Read + + // Integrity check errors + output logic intg_err_o +); + + import entropy_src_reg_pkg::*; + + localparam int AW = 8; + localparam int DW = 32; + localparam int DBW = DW/8; // Byte Width + + // ahb interface register signals + logic ahb_reg_dv; + logic ahb_reg_hld; + logic ahb_reg_err; + logic ahb_reg_write; + logic [DW-1:0] ahb_reg_wdata; + logic [AW-1:0] ahb_reg_addr; + logic [DW-1:0] ahb_reg_rdata; + // register signals + logic reg_we; + logic reg_re; + logic [AW-1:0] reg_addr; + logic [DW-1:0] reg_wdata; + logic [DBW-1:0] reg_be; + logic [DW-1:0] reg_rdata; + logic reg_error; + + logic addrmiss, wr_err; + + logic [DW-1:0] reg_rdata_next; + logic reg_busy; + + // also check for spurious write enables + logic reg_we_err; + logic [56:0] reg_we_check; + caliptra_prim_reg_we_check #( + .OneHotWidth(57) + ) u_caliptra_prim_reg_we_check ( + .clk_i(clk_i), + .rst_ni(rst_ni), + .oh_i (reg_we_check), + .en_i (reg_we && !addrmiss), + .err_o (reg_we_err) + ); + + logic err_q; + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + err_q <= '0; + end else if (reg_we_err) begin + err_q <= 1'b1; + end + end + + // integrity error output is permanent and should be used for alert generation + // register errors are transactional + assign intg_err_o = err_q | reg_we_err; + + ahb_slv_sif #( + .AHB_DATA_WIDTH (AHBDataWidth), + .AHB_ADDR_WIDTH (AHBAddrWidth), + .CLIENT_DATA_WIDTH (DW), + .CLIENT_ADDR_WIDTH (AW) + ) u_ahb_slv_sif ( + .hclk (clk_i), + .hreset_n (rst_ni), + .haddr_i (haddr_i), + .hwdata_i (hwdata_i), + .hsel_i (hsel_i), + .hwrite_i (hwrite_i), + .hready_i (hready_i), + .htrans_i (htrans_i), + .hsize_i (hsize_i), + .hresp_o (hresp_o), + .hreadyout_o (hreadyout_o), + .hrdata_o (hrdata_o), + //component inf + .dv (ahb_reg_dv), + .hld (ahb_reg_hld), + .err (ahb_reg_err), + .write (ahb_reg_write), + .wdata (ahb_reg_wdata), + .addr (ahb_reg_addr), + .rdata (ahb_reg_rdata) + ); + + ahb_to_reg_adapter #( + .DATA_WIDTH (DW), + .ADDR_WIDTH (AW) + ) u_ahb_to_reg_adapter ( + .clk (clk_i), + .rst_n (rst_ni), + .ahb_reg_dv (ahb_reg_dv), + .ahb_reg_hld (ahb_reg_hld), + .ahb_reg_err (ahb_reg_err), + .ahb_reg_write (ahb_reg_write), + .ahb_reg_wdata (ahb_reg_wdata), + .ahb_reg_addr (ahb_reg_addr), + .ahb_reg_rdata (ahb_reg_rdata), + .reg_we (reg_we), + .reg_re (reg_re), + .reg_addr (reg_addr), + .reg_wdata (reg_wdata), + .reg_be (reg_be), + .reg_rdata (reg_rdata), + .reg_error (reg_error), + .reg_busy (reg_busy) + ); + + // cdc oversampling signals + + assign reg_rdata = reg_rdata_next; + assign reg_error = addrmiss | wr_err; + + // Define SW related signals + // Format: __{wd|we|qs} + // or _{wd|we|qs} if field == 1 or 0 + logic intr_state_we; + logic intr_state_es_entropy_valid_qs; + logic intr_state_es_entropy_valid_wd; + logic intr_state_es_health_test_failed_qs; + logic intr_state_es_health_test_failed_wd; + logic intr_state_es_observe_fifo_ready_qs; + logic intr_state_es_observe_fifo_ready_wd; + logic intr_state_es_fatal_err_qs; + logic intr_state_es_fatal_err_wd; + logic intr_enable_we; + logic intr_enable_es_entropy_valid_qs; + logic intr_enable_es_entropy_valid_wd; + logic intr_enable_es_health_test_failed_qs; + logic intr_enable_es_health_test_failed_wd; + logic intr_enable_es_observe_fifo_ready_qs; + logic intr_enable_es_observe_fifo_ready_wd; + logic intr_enable_es_fatal_err_qs; + logic intr_enable_es_fatal_err_wd; + logic intr_test_we; + logic intr_test_es_entropy_valid_wd; + logic intr_test_es_health_test_failed_wd; + logic intr_test_es_observe_fifo_ready_wd; + logic intr_test_es_fatal_err_wd; + logic alert_test_we; + logic alert_test_recov_alert_wd; + logic alert_test_fatal_alert_wd; + logic me_regwen_we; + logic me_regwen_qs; + logic me_regwen_wd; + logic sw_regupd_we; + logic sw_regupd_qs; + logic sw_regupd_wd; + logic regwen_qs; + logic [7:0] rev_abi_revision_qs; + logic [7:0] rev_hw_revision_qs; + logic [7:0] rev_chip_type_qs; + logic module_enable_we; + logic [3:0] module_enable_qs; + logic [3:0] module_enable_wd; + logic conf_we; + logic [3:0] conf_fips_enable_qs; + logic [3:0] conf_fips_enable_wd; + logic [3:0] conf_fips_flag_qs; + logic [3:0] conf_fips_flag_wd; + logic [3:0] conf_rng_fips_qs; + logic [3:0] conf_rng_fips_wd; + logic [3:0] conf_rng_bit_enable_qs; + logic [3:0] conf_rng_bit_enable_wd; + logic [1:0] conf_rng_bit_sel_qs; + logic [1:0] conf_rng_bit_sel_wd; + logic [3:0] conf_threshold_scope_qs; + logic [3:0] conf_threshold_scope_wd; + logic [3:0] conf_entropy_data_reg_enable_qs; + logic [3:0] conf_entropy_data_reg_enable_wd; + logic entropy_control_we; + logic [3:0] entropy_control_es_route_qs; + logic [3:0] entropy_control_es_route_wd; + logic [3:0] entropy_control_es_type_qs; + logic [3:0] entropy_control_es_type_wd; + logic entropy_data_re; + logic [31:0] entropy_data_qs; + logic health_test_windows_we; + logic [15:0] health_test_windows_fips_window_qs; + logic [15:0] health_test_windows_fips_window_wd; + logic [15:0] health_test_windows_bypass_window_qs; + logic [15:0] health_test_windows_bypass_window_wd; + logic repcnt_thresholds_re; + logic repcnt_thresholds_we; + logic [15:0] repcnt_thresholds_fips_thresh_qs; + logic [15:0] repcnt_thresholds_fips_thresh_wd; + logic [15:0] repcnt_thresholds_bypass_thresh_qs; + logic [15:0] repcnt_thresholds_bypass_thresh_wd; + logic repcnts_thresholds_re; + logic repcnts_thresholds_we; + logic [15:0] repcnts_thresholds_fips_thresh_qs; + logic [15:0] repcnts_thresholds_fips_thresh_wd; + logic [15:0] repcnts_thresholds_bypass_thresh_qs; + logic [15:0] repcnts_thresholds_bypass_thresh_wd; + logic adaptp_hi_thresholds_re; + logic adaptp_hi_thresholds_we; + logic [15:0] adaptp_hi_thresholds_fips_thresh_qs; + logic [15:0] adaptp_hi_thresholds_fips_thresh_wd; + logic [15:0] adaptp_hi_thresholds_bypass_thresh_qs; + logic [15:0] adaptp_hi_thresholds_bypass_thresh_wd; + logic adaptp_lo_thresholds_re; + logic adaptp_lo_thresholds_we; + logic [15:0] adaptp_lo_thresholds_fips_thresh_qs; + logic [15:0] adaptp_lo_thresholds_fips_thresh_wd; + logic [15:0] adaptp_lo_thresholds_bypass_thresh_qs; + logic [15:0] adaptp_lo_thresholds_bypass_thresh_wd; + logic bucket_thresholds_re; + logic bucket_thresholds_we; + logic [15:0] bucket_thresholds_fips_thresh_qs; + logic [15:0] bucket_thresholds_fips_thresh_wd; + logic [15:0] bucket_thresholds_bypass_thresh_qs; + logic [15:0] bucket_thresholds_bypass_thresh_wd; + logic markov_hi_thresholds_re; + logic markov_hi_thresholds_we; + logic [15:0] markov_hi_thresholds_fips_thresh_qs; + logic [15:0] markov_hi_thresholds_fips_thresh_wd; + logic [15:0] markov_hi_thresholds_bypass_thresh_qs; + logic [15:0] markov_hi_thresholds_bypass_thresh_wd; + logic markov_lo_thresholds_re; + logic markov_lo_thresholds_we; + logic [15:0] markov_lo_thresholds_fips_thresh_qs; + logic [15:0] markov_lo_thresholds_fips_thresh_wd; + logic [15:0] markov_lo_thresholds_bypass_thresh_qs; + logic [15:0] markov_lo_thresholds_bypass_thresh_wd; + logic extht_hi_thresholds_re; + logic extht_hi_thresholds_we; + logic [15:0] extht_hi_thresholds_fips_thresh_qs; + logic [15:0] extht_hi_thresholds_fips_thresh_wd; + logic [15:0] extht_hi_thresholds_bypass_thresh_qs; + logic [15:0] extht_hi_thresholds_bypass_thresh_wd; + logic extht_lo_thresholds_re; + logic extht_lo_thresholds_we; + logic [15:0] extht_lo_thresholds_fips_thresh_qs; + logic [15:0] extht_lo_thresholds_fips_thresh_wd; + logic [15:0] extht_lo_thresholds_bypass_thresh_qs; + logic [15:0] extht_lo_thresholds_bypass_thresh_wd; + logic repcnt_hi_watermarks_re; + logic [15:0] repcnt_hi_watermarks_fips_watermark_qs; + logic [15:0] repcnt_hi_watermarks_bypass_watermark_qs; + logic repcnts_hi_watermarks_re; + logic [15:0] repcnts_hi_watermarks_fips_watermark_qs; + logic [15:0] repcnts_hi_watermarks_bypass_watermark_qs; + logic adaptp_hi_watermarks_re; + logic [15:0] adaptp_hi_watermarks_fips_watermark_qs; + logic [15:0] adaptp_hi_watermarks_bypass_watermark_qs; + logic adaptp_lo_watermarks_re; + logic [15:0] adaptp_lo_watermarks_fips_watermark_qs; + logic [15:0] adaptp_lo_watermarks_bypass_watermark_qs; + logic extht_hi_watermarks_re; + logic [15:0] extht_hi_watermarks_fips_watermark_qs; + logic [15:0] extht_hi_watermarks_bypass_watermark_qs; + logic extht_lo_watermarks_re; + logic [15:0] extht_lo_watermarks_fips_watermark_qs; + logic [15:0] extht_lo_watermarks_bypass_watermark_qs; + logic bucket_hi_watermarks_re; + logic [15:0] bucket_hi_watermarks_fips_watermark_qs; + logic [15:0] bucket_hi_watermarks_bypass_watermark_qs; + logic markov_hi_watermarks_re; + logic [15:0] markov_hi_watermarks_fips_watermark_qs; + logic [15:0] markov_hi_watermarks_bypass_watermark_qs; + logic markov_lo_watermarks_re; + logic [15:0] markov_lo_watermarks_fips_watermark_qs; + logic [15:0] markov_lo_watermarks_bypass_watermark_qs; + logic repcnt_total_fails_re; + logic [31:0] repcnt_total_fails_qs; + logic repcnts_total_fails_re; + logic [31:0] repcnts_total_fails_qs; + logic adaptp_hi_total_fails_re; + logic [31:0] adaptp_hi_total_fails_qs; + logic adaptp_lo_total_fails_re; + logic [31:0] adaptp_lo_total_fails_qs; + logic bucket_total_fails_re; + logic [31:0] bucket_total_fails_qs; + logic markov_hi_total_fails_re; + logic [31:0] markov_hi_total_fails_qs; + logic markov_lo_total_fails_re; + logic [31:0] markov_lo_total_fails_qs; + logic extht_hi_total_fails_re; + logic [31:0] extht_hi_total_fails_qs; + logic extht_lo_total_fails_re; + logic [31:0] extht_lo_total_fails_qs; + logic alert_threshold_we; + logic [15:0] alert_threshold_alert_threshold_qs; + logic [15:0] alert_threshold_alert_threshold_wd; + logic [15:0] alert_threshold_alert_threshold_inv_qs; + logic [15:0] alert_threshold_alert_threshold_inv_wd; + logic alert_summary_fail_counts_re; + logic [15:0] alert_summary_fail_counts_qs; + logic alert_fail_counts_re; + logic [3:0] alert_fail_counts_repcnt_fail_count_qs; + logic [3:0] alert_fail_counts_adaptp_hi_fail_count_qs; + logic [3:0] alert_fail_counts_adaptp_lo_fail_count_qs; + logic [3:0] alert_fail_counts_bucket_fail_count_qs; + logic [3:0] alert_fail_counts_markov_hi_fail_count_qs; + logic [3:0] alert_fail_counts_markov_lo_fail_count_qs; + logic [3:0] alert_fail_counts_repcnts_fail_count_qs; + logic extht_fail_counts_re; + logic [3:0] extht_fail_counts_extht_hi_fail_count_qs; + logic [3:0] extht_fail_counts_extht_lo_fail_count_qs; + logic fw_ov_control_we; + logic [3:0] fw_ov_control_fw_ov_mode_qs; + logic [3:0] fw_ov_control_fw_ov_mode_wd; + logic [3:0] fw_ov_control_fw_ov_entropy_insert_qs; + logic [3:0] fw_ov_control_fw_ov_entropy_insert_wd; + logic fw_ov_sha3_start_we; + logic [3:0] fw_ov_sha3_start_qs; + logic [3:0] fw_ov_sha3_start_wd; + logic fw_ov_wr_fifo_full_re; + logic fw_ov_wr_fifo_full_qs; + logic fw_ov_rd_fifo_overflow_we; + logic fw_ov_rd_fifo_overflow_qs; + logic fw_ov_rd_fifo_overflow_wd; + logic fw_ov_rd_data_re; + logic [31:0] fw_ov_rd_data_qs; + logic fw_ov_wr_data_we; + logic [31:0] fw_ov_wr_data_wd; + logic observe_fifo_thresh_we; + logic [5:0] observe_fifo_thresh_qs; + logic [5:0] observe_fifo_thresh_wd; + logic observe_fifo_depth_re; + logic [5:0] observe_fifo_depth_qs; + logic debug_status_re; + logic [1:0] debug_status_entropy_fifo_depth_qs; + logic [2:0] debug_status_sha3_fsm_qs; + logic debug_status_sha3_block_pr_qs; + logic debug_status_sha3_squeezing_qs; + logic debug_status_sha3_absorbed_qs; + logic debug_status_sha3_err_qs; + logic debug_status_main_sm_idle_qs; + logic debug_status_main_sm_boot_done_qs; + logic recov_alert_sts_we; + logic recov_alert_sts_fips_enable_field_alert_qs; + logic recov_alert_sts_fips_enable_field_alert_wd; + logic recov_alert_sts_entropy_data_reg_en_field_alert_qs; + logic recov_alert_sts_entropy_data_reg_en_field_alert_wd; + logic recov_alert_sts_module_enable_field_alert_qs; + logic recov_alert_sts_module_enable_field_alert_wd; + logic recov_alert_sts_threshold_scope_field_alert_qs; + logic recov_alert_sts_threshold_scope_field_alert_wd; + logic recov_alert_sts_rng_bit_enable_field_alert_qs; + logic recov_alert_sts_rng_bit_enable_field_alert_wd; + logic recov_alert_sts_fw_ov_sha3_start_field_alert_qs; + logic recov_alert_sts_fw_ov_sha3_start_field_alert_wd; + logic recov_alert_sts_fw_ov_mode_field_alert_qs; + logic recov_alert_sts_fw_ov_mode_field_alert_wd; + logic recov_alert_sts_fw_ov_entropy_insert_field_alert_qs; + logic recov_alert_sts_fw_ov_entropy_insert_field_alert_wd; + logic recov_alert_sts_es_route_field_alert_qs; + logic recov_alert_sts_es_route_field_alert_wd; + logic recov_alert_sts_es_type_field_alert_qs; + logic recov_alert_sts_es_type_field_alert_wd; + logic recov_alert_sts_es_main_sm_alert_qs; + logic recov_alert_sts_es_main_sm_alert_wd; + logic recov_alert_sts_es_bus_cmp_alert_qs; + logic recov_alert_sts_es_bus_cmp_alert_wd; + logic recov_alert_sts_es_thresh_cfg_alert_qs; + logic recov_alert_sts_es_thresh_cfg_alert_wd; + logic recov_alert_sts_es_fw_ov_wr_alert_qs; + logic recov_alert_sts_es_fw_ov_wr_alert_wd; + logic recov_alert_sts_es_fw_ov_disable_alert_qs; + logic recov_alert_sts_es_fw_ov_disable_alert_wd; + logic recov_alert_sts_fips_flag_field_alert_qs; + logic recov_alert_sts_fips_flag_field_alert_wd; + logic recov_alert_sts_rng_fips_field_alert_qs; + logic recov_alert_sts_rng_fips_field_alert_wd; + logic recov_alert_sts_postht_entropy_drop_alert_qs; + logic recov_alert_sts_postht_entropy_drop_alert_wd; + logic err_code_sfifo_esrng_err_qs; + logic err_code_sfifo_distr_err_qs; + logic err_code_sfifo_observe_err_qs; + logic err_code_sfifo_esfinal_err_qs; + logic err_code_es_ack_sm_err_qs; + logic err_code_es_main_sm_err_qs; + logic err_code_es_cntr_err_qs; + logic err_code_sha3_state_err_qs; + logic err_code_sha3_rst_storage_err_qs; + logic err_code_fifo_write_err_qs; + logic err_code_fifo_read_err_qs; + logic err_code_fifo_state_err_qs; + logic err_code_test_we; + logic [4:0] err_code_test_qs; + logic [4:0] err_code_test_wd; + logic [8:0] main_sm_state_qs; + + // Register instances + // R[intr_state]: V(False) + // F[es_entropy_valid]: 0:0 + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessW1C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_intr_state_es_entropy_valid ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (intr_state_we), + .wd (intr_state_es_entropy_valid_wd), + + // from internal hardware + .de (hw2reg.intr_state.es_entropy_valid.de), + .d (hw2reg.intr_state.es_entropy_valid.d), + + // to internal hardware + .qe (), + .q (reg2hw.intr_state.es_entropy_valid.q), + .ds (), + + // to register interface (read) + .qs (intr_state_es_entropy_valid_qs) + ); + + // F[es_health_test_failed]: 1:1 + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessW1C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_intr_state_es_health_test_failed ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (intr_state_we), + .wd (intr_state_es_health_test_failed_wd), + + // from internal hardware + .de (hw2reg.intr_state.es_health_test_failed.de), + .d (hw2reg.intr_state.es_health_test_failed.d), + + // to internal hardware + .qe (), + .q (reg2hw.intr_state.es_health_test_failed.q), + .ds (), + + // to register interface (read) + .qs (intr_state_es_health_test_failed_qs) + ); + + // F[es_observe_fifo_ready]: 2:2 + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessW1C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_intr_state_es_observe_fifo_ready ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (intr_state_we), + .wd (intr_state_es_observe_fifo_ready_wd), + + // from internal hardware + .de (hw2reg.intr_state.es_observe_fifo_ready.de), + .d (hw2reg.intr_state.es_observe_fifo_ready.d), + + // to internal hardware + .qe (), + .q (reg2hw.intr_state.es_observe_fifo_ready.q), + .ds (), + + // to register interface (read) + .qs (intr_state_es_observe_fifo_ready_qs) + ); + + // F[es_fatal_err]: 3:3 + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessW1C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_intr_state_es_fatal_err ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (intr_state_we), + .wd (intr_state_es_fatal_err_wd), + + // from internal hardware + .de (hw2reg.intr_state.es_fatal_err.de), + .d (hw2reg.intr_state.es_fatal_err.d), + + // to internal hardware + .qe (), + .q (reg2hw.intr_state.es_fatal_err.q), + .ds (), + + // to register interface (read) + .qs (intr_state_es_fatal_err_qs) + ); + + + // R[intr_enable]: V(False) + // F[es_entropy_valid]: 0:0 + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_intr_enable_es_entropy_valid ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (intr_enable_we), + .wd (intr_enable_es_entropy_valid_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.intr_enable.es_entropy_valid.q), + .ds (), + + // to register interface (read) + .qs (intr_enable_es_entropy_valid_qs) + ); + + // F[es_health_test_failed]: 1:1 + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_intr_enable_es_health_test_failed ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (intr_enable_we), + .wd (intr_enable_es_health_test_failed_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.intr_enable.es_health_test_failed.q), + .ds (), + + // to register interface (read) + .qs (intr_enable_es_health_test_failed_qs) + ); + + // F[es_observe_fifo_ready]: 2:2 + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_intr_enable_es_observe_fifo_ready ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (intr_enable_we), + .wd (intr_enable_es_observe_fifo_ready_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.intr_enable.es_observe_fifo_ready.q), + .ds (), + + // to register interface (read) + .qs (intr_enable_es_observe_fifo_ready_qs) + ); + + // F[es_fatal_err]: 3:3 + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_intr_enable_es_fatal_err ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (intr_enable_we), + .wd (intr_enable_es_fatal_err_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.intr_enable.es_fatal_err.q), + .ds (), + + // to register interface (read) + .qs (intr_enable_es_fatal_err_qs) + ); + + + // R[intr_test]: V(True) + logic intr_test_qe; + logic [3:0] intr_test_flds_we; + assign intr_test_qe = &intr_test_flds_we; + // F[es_entropy_valid]: 0:0 + caliptra_prim_subreg_ext #( + .DW (1) + ) u_intr_test_es_entropy_valid ( + .re (1'b0), + .we (intr_test_we), + .wd (intr_test_es_entropy_valid_wd), + .d ('0), + .qre (), + .qe (intr_test_flds_we[0]), + .q (reg2hw.intr_test.es_entropy_valid.q), + .ds (), + .qs () + ); + assign reg2hw.intr_test.es_entropy_valid.qe = intr_test_qe; + + // F[es_health_test_failed]: 1:1 + caliptra_prim_subreg_ext #( + .DW (1) + ) u_intr_test_es_health_test_failed ( + .re (1'b0), + .we (intr_test_we), + .wd (intr_test_es_health_test_failed_wd), + .d ('0), + .qre (), + .qe (intr_test_flds_we[1]), + .q (reg2hw.intr_test.es_health_test_failed.q), + .ds (), + .qs () + ); + assign reg2hw.intr_test.es_health_test_failed.qe = intr_test_qe; + + // F[es_observe_fifo_ready]: 2:2 + caliptra_prim_subreg_ext #( + .DW (1) + ) u_intr_test_es_observe_fifo_ready ( + .re (1'b0), + .we (intr_test_we), + .wd (intr_test_es_observe_fifo_ready_wd), + .d ('0), + .qre (), + .qe (intr_test_flds_we[2]), + .q (reg2hw.intr_test.es_observe_fifo_ready.q), + .ds (), + .qs () + ); + assign reg2hw.intr_test.es_observe_fifo_ready.qe = intr_test_qe; + + // F[es_fatal_err]: 3:3 + caliptra_prim_subreg_ext #( + .DW (1) + ) u_intr_test_es_fatal_err ( + .re (1'b0), + .we (intr_test_we), + .wd (intr_test_es_fatal_err_wd), + .d ('0), + .qre (), + .qe (intr_test_flds_we[3]), + .q (reg2hw.intr_test.es_fatal_err.q), + .ds (), + .qs () + ); + assign reg2hw.intr_test.es_fatal_err.qe = intr_test_qe; + + + // R[alert_test]: V(True) + logic alert_test_qe; + logic [1:0] alert_test_flds_we; + assign alert_test_qe = &alert_test_flds_we; + // F[recov_alert]: 0:0 + caliptra_prim_subreg_ext #( + .DW (1) + ) u_alert_test_recov_alert ( + .re (1'b0), + .we (alert_test_we), + .wd (alert_test_recov_alert_wd), + .d ('0), + .qre (), + .qe (alert_test_flds_we[0]), + .q (reg2hw.alert_test.recov_alert.q), + .ds (), + .qs () + ); + assign reg2hw.alert_test.recov_alert.qe = alert_test_qe; + + // F[fatal_alert]: 1:1 + caliptra_prim_subreg_ext #( + .DW (1) + ) u_alert_test_fatal_alert ( + .re (1'b0), + .we (alert_test_we), + .wd (alert_test_fatal_alert_wd), + .d ('0), + .qre (), + .qe (alert_test_flds_we[1]), + .q (reg2hw.alert_test.fatal_alert.q), + .ds (), + .qs () + ); + assign reg2hw.alert_test.fatal_alert.qe = alert_test_qe; + + + // R[me_regwen]: V(False) + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_me_regwen ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (me_regwen_we), + .wd (me_regwen_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (me_regwen_qs) + ); + + + // R[sw_regupd]: V(False) + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_sw_regupd ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (sw_regupd_we), + .wd (sw_regupd_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.sw_regupd.q), + .ds (), + + // to register interface (read) + .qs (sw_regupd_qs) + ); + + + // R[regwen]: V(False) + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_regwen ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.regwen.de), + .d (hw2reg.regwen.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (regwen_qs) + ); + + + // R[rev]: V(False) + // F[abi_revision]: 7:0 + // constant-only read + assign rev_abi_revision_qs = 8'h3; + + // F[hw_revision]: 15:8 + // constant-only read + assign rev_hw_revision_qs = 8'h3; + + // F[chip_type]: 23:16 + // constant-only read + assign rev_chip_type_qs = 8'h1; + + + // R[module_enable]: V(False) + // Create REGWEN-gated WE signal + logic module_enable_gated_we; + assign module_enable_gated_we = module_enable_we & me_regwen_qs; + caliptra_prim_subreg #( + .DW (4), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_module_enable ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (module_enable_gated_we), + .wd (module_enable_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.module_enable.q), + .ds (), + + // to register interface (read) + .qs (module_enable_qs) + ); + + + // R[conf]: V(False) + // Create REGWEN-gated WE signal + logic conf_gated_we; + assign conf_gated_we = conf_we & regwen_qs; + // F[fips_enable]: 3:0 + caliptra_prim_subreg #( + .DW (4), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_conf_fips_enable ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (conf_gated_we), + .wd (conf_fips_enable_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.conf.fips_enable.q), + .ds (), + + // to register interface (read) + .qs (conf_fips_enable_qs) + ); + + // F[fips_flag]: 7:4 + caliptra_prim_subreg #( + .DW (4), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_conf_fips_flag ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (conf_gated_we), + .wd (conf_fips_flag_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.conf.fips_flag.q), + .ds (), + + // to register interface (read) + .qs (conf_fips_flag_qs) + ); + + // F[rng_fips]: 11:8 + caliptra_prim_subreg #( + .DW (4), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_conf_rng_fips ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (conf_gated_we), + .wd (conf_rng_fips_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.conf.rng_fips.q), + .ds (), + + // to register interface (read) + .qs (conf_rng_fips_qs) + ); + + // F[rng_bit_enable]: 15:12 + caliptra_prim_subreg #( + .DW (4), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_conf_rng_bit_enable ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (conf_gated_we), + .wd (conf_rng_bit_enable_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.conf.rng_bit_enable.q), + .ds (), + + // to register interface (read) + .qs (conf_rng_bit_enable_qs) + ); + + // F[rng_bit_sel]: 17:16 + caliptra_prim_subreg #( + .DW (2), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h0), + .Mubi (1'b0) + ) u_conf_rng_bit_sel ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (conf_gated_we), + .wd (conf_rng_bit_sel_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.conf.rng_bit_sel.q), + .ds (), + + // to register interface (read) + .qs (conf_rng_bit_sel_qs) + ); + + // F[threshold_scope]: 21:18 + caliptra_prim_subreg #( + .DW (4), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_conf_threshold_scope ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (conf_gated_we), + .wd (conf_threshold_scope_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.conf.threshold_scope.q), + .ds (), + + // to register interface (read) + .qs (conf_threshold_scope_qs) + ); + + // F[entropy_data_reg_enable]: 25:22 + caliptra_prim_subreg #( + .DW (4), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_conf_entropy_data_reg_enable ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (conf_gated_we), + .wd (conf_entropy_data_reg_enable_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.conf.entropy_data_reg_enable.q), + .ds (), + + // to register interface (read) + .qs (conf_entropy_data_reg_enable_qs) + ); + + + // R[entropy_control]: V(False) + // Create REGWEN-gated WE signal + logic entropy_control_gated_we; + assign entropy_control_gated_we = entropy_control_we & regwen_qs; + // F[es_route]: 3:0 + caliptra_prim_subreg #( + .DW (4), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_entropy_control_es_route ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (entropy_control_gated_we), + .wd (entropy_control_es_route_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.entropy_control.es_route.q), + .ds (), + + // to register interface (read) + .qs (entropy_control_es_route_qs) + ); + + // F[es_type]: 7:4 + caliptra_prim_subreg #( + .DW (4), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_entropy_control_es_type ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (entropy_control_gated_we), + .wd (entropy_control_es_type_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.entropy_control.es_type.q), + .ds (), + + // to register interface (read) + .qs (entropy_control_es_type_qs) + ); + + + // R[entropy_data]: V(True) + caliptra_prim_subreg_ext #( + .DW (32) + ) u_entropy_data ( + .re (entropy_data_re), + .we (1'b0), + .wd ('0), + .d (hw2reg.entropy_data.d), + .qre (reg2hw.entropy_data.re), + .qe (), + .q (reg2hw.entropy_data.q), + .ds (), + .qs (entropy_data_qs) + ); + + + // R[health_test_windows]: V(False) + // Create REGWEN-gated WE signal + logic health_test_windows_gated_we; + assign health_test_windows_gated_we = health_test_windows_we & regwen_qs; + // F[fips_window]: 15:0 + caliptra_prim_subreg #( + .DW (16), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRW), + .RESVAL (16'h200), + .Mubi (1'b0) + ) u_health_test_windows_fips_window ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (health_test_windows_gated_we), + .wd (health_test_windows_fips_window_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.health_test_windows.fips_window.q), + .ds (), + + // to register interface (read) + .qs (health_test_windows_fips_window_qs) + ); + + // F[bypass_window]: 31:16 + caliptra_prim_subreg #( + .DW (16), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRW), + .RESVAL (16'h60), + .Mubi (1'b0) + ) u_health_test_windows_bypass_window ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (health_test_windows_gated_we), + .wd (health_test_windows_bypass_window_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.health_test_windows.bypass_window.q), + .ds (), + + // to register interface (read) + .qs (health_test_windows_bypass_window_qs) + ); + + + // R[repcnt_thresholds]: V(True) + logic repcnt_thresholds_qe; + logic [1:0] repcnt_thresholds_flds_we; + assign repcnt_thresholds_qe = &repcnt_thresholds_flds_we; + // Create REGWEN-gated WE signal + logic repcnt_thresholds_gated_we; + assign repcnt_thresholds_gated_we = repcnt_thresholds_we & regwen_qs; + // F[fips_thresh]: 15:0 + caliptra_prim_subreg_ext #( + .DW (16) + ) u_repcnt_thresholds_fips_thresh ( + .re (repcnt_thresholds_re), + .we (repcnt_thresholds_gated_we), + .wd (repcnt_thresholds_fips_thresh_wd), + .d (hw2reg.repcnt_thresholds.fips_thresh.d), + .qre (), + .qe (repcnt_thresholds_flds_we[0]), + .q (reg2hw.repcnt_thresholds.fips_thresh.q), + .ds (), + .qs (repcnt_thresholds_fips_thresh_qs) + ); + assign reg2hw.repcnt_thresholds.fips_thresh.qe = repcnt_thresholds_qe; + + // F[bypass_thresh]: 31:16 + caliptra_prim_subreg_ext #( + .DW (16) + ) u_repcnt_thresholds_bypass_thresh ( + .re (repcnt_thresholds_re), + .we (repcnt_thresholds_gated_we), + .wd (repcnt_thresholds_bypass_thresh_wd), + .d (hw2reg.repcnt_thresholds.bypass_thresh.d), + .qre (), + .qe (repcnt_thresholds_flds_we[1]), + .q (reg2hw.repcnt_thresholds.bypass_thresh.q), + .ds (), + .qs (repcnt_thresholds_bypass_thresh_qs) + ); + assign reg2hw.repcnt_thresholds.bypass_thresh.qe = repcnt_thresholds_qe; + + + // R[repcnts_thresholds]: V(True) + logic repcnts_thresholds_qe; + logic [1:0] repcnts_thresholds_flds_we; + assign repcnts_thresholds_qe = &repcnts_thresholds_flds_we; + // Create REGWEN-gated WE signal + logic repcnts_thresholds_gated_we; + assign repcnts_thresholds_gated_we = repcnts_thresholds_we & regwen_qs; + // F[fips_thresh]: 15:0 + caliptra_prim_subreg_ext #( + .DW (16) + ) u_repcnts_thresholds_fips_thresh ( + .re (repcnts_thresholds_re), + .we (repcnts_thresholds_gated_we), + .wd (repcnts_thresholds_fips_thresh_wd), + .d (hw2reg.repcnts_thresholds.fips_thresh.d), + .qre (), + .qe (repcnts_thresholds_flds_we[0]), + .q (reg2hw.repcnts_thresholds.fips_thresh.q), + .ds (), + .qs (repcnts_thresholds_fips_thresh_qs) + ); + assign reg2hw.repcnts_thresholds.fips_thresh.qe = repcnts_thresholds_qe; + + // F[bypass_thresh]: 31:16 + caliptra_prim_subreg_ext #( + .DW (16) + ) u_repcnts_thresholds_bypass_thresh ( + .re (repcnts_thresholds_re), + .we (repcnts_thresholds_gated_we), + .wd (repcnts_thresholds_bypass_thresh_wd), + .d (hw2reg.repcnts_thresholds.bypass_thresh.d), + .qre (), + .qe (repcnts_thresholds_flds_we[1]), + .q (reg2hw.repcnts_thresholds.bypass_thresh.q), + .ds (), + .qs (repcnts_thresholds_bypass_thresh_qs) + ); + assign reg2hw.repcnts_thresholds.bypass_thresh.qe = repcnts_thresholds_qe; + + + // R[adaptp_hi_thresholds]: V(True) + logic adaptp_hi_thresholds_qe; + logic [1:0] adaptp_hi_thresholds_flds_we; + assign adaptp_hi_thresholds_qe = &adaptp_hi_thresholds_flds_we; + // Create REGWEN-gated WE signal + logic adaptp_hi_thresholds_gated_we; + assign adaptp_hi_thresholds_gated_we = adaptp_hi_thresholds_we & regwen_qs; + // F[fips_thresh]: 15:0 + caliptra_prim_subreg_ext #( + .DW (16) + ) u_adaptp_hi_thresholds_fips_thresh ( + .re (adaptp_hi_thresholds_re), + .we (adaptp_hi_thresholds_gated_we), + .wd (adaptp_hi_thresholds_fips_thresh_wd), + .d (hw2reg.adaptp_hi_thresholds.fips_thresh.d), + .qre (), + .qe (adaptp_hi_thresholds_flds_we[0]), + .q (reg2hw.adaptp_hi_thresholds.fips_thresh.q), + .ds (), + .qs (adaptp_hi_thresholds_fips_thresh_qs) + ); + assign reg2hw.adaptp_hi_thresholds.fips_thresh.qe = adaptp_hi_thresholds_qe; + + // F[bypass_thresh]: 31:16 + caliptra_prim_subreg_ext #( + .DW (16) + ) u_adaptp_hi_thresholds_bypass_thresh ( + .re (adaptp_hi_thresholds_re), + .we (adaptp_hi_thresholds_gated_we), + .wd (adaptp_hi_thresholds_bypass_thresh_wd), + .d (hw2reg.adaptp_hi_thresholds.bypass_thresh.d), + .qre (), + .qe (adaptp_hi_thresholds_flds_we[1]), + .q (reg2hw.adaptp_hi_thresholds.bypass_thresh.q), + .ds (), + .qs (adaptp_hi_thresholds_bypass_thresh_qs) + ); + assign reg2hw.adaptp_hi_thresholds.bypass_thresh.qe = adaptp_hi_thresholds_qe; + + + // R[adaptp_lo_thresholds]: V(True) + logic adaptp_lo_thresholds_qe; + logic [1:0] adaptp_lo_thresholds_flds_we; + assign adaptp_lo_thresholds_qe = &adaptp_lo_thresholds_flds_we; + // Create REGWEN-gated WE signal + logic adaptp_lo_thresholds_gated_we; + assign adaptp_lo_thresholds_gated_we = adaptp_lo_thresholds_we & regwen_qs; + // F[fips_thresh]: 15:0 + caliptra_prim_subreg_ext #( + .DW (16) + ) u_adaptp_lo_thresholds_fips_thresh ( + .re (adaptp_lo_thresholds_re), + .we (adaptp_lo_thresholds_gated_we), + .wd (adaptp_lo_thresholds_fips_thresh_wd), + .d (hw2reg.adaptp_lo_thresholds.fips_thresh.d), + .qre (), + .qe (adaptp_lo_thresholds_flds_we[0]), + .q (reg2hw.adaptp_lo_thresholds.fips_thresh.q), + .ds (), + .qs (adaptp_lo_thresholds_fips_thresh_qs) + ); + assign reg2hw.adaptp_lo_thresholds.fips_thresh.qe = adaptp_lo_thresholds_qe; + + // F[bypass_thresh]: 31:16 + caliptra_prim_subreg_ext #( + .DW (16) + ) u_adaptp_lo_thresholds_bypass_thresh ( + .re (adaptp_lo_thresholds_re), + .we (adaptp_lo_thresholds_gated_we), + .wd (adaptp_lo_thresholds_bypass_thresh_wd), + .d (hw2reg.adaptp_lo_thresholds.bypass_thresh.d), + .qre (), + .qe (adaptp_lo_thresholds_flds_we[1]), + .q (reg2hw.adaptp_lo_thresholds.bypass_thresh.q), + .ds (), + .qs (adaptp_lo_thresholds_bypass_thresh_qs) + ); + assign reg2hw.adaptp_lo_thresholds.bypass_thresh.qe = adaptp_lo_thresholds_qe; + + + // R[bucket_thresholds]: V(True) + logic bucket_thresholds_qe; + logic [1:0] bucket_thresholds_flds_we; + assign bucket_thresholds_qe = &bucket_thresholds_flds_we; + // Create REGWEN-gated WE signal + logic bucket_thresholds_gated_we; + assign bucket_thresholds_gated_we = bucket_thresholds_we & regwen_qs; + // F[fips_thresh]: 15:0 + caliptra_prim_subreg_ext #( + .DW (16) + ) u_bucket_thresholds_fips_thresh ( + .re (bucket_thresholds_re), + .we (bucket_thresholds_gated_we), + .wd (bucket_thresholds_fips_thresh_wd), + .d (hw2reg.bucket_thresholds.fips_thresh.d), + .qre (), + .qe (bucket_thresholds_flds_we[0]), + .q (reg2hw.bucket_thresholds.fips_thresh.q), + .ds (), + .qs (bucket_thresholds_fips_thresh_qs) + ); + assign reg2hw.bucket_thresholds.fips_thresh.qe = bucket_thresholds_qe; + + // F[bypass_thresh]: 31:16 + caliptra_prim_subreg_ext #( + .DW (16) + ) u_bucket_thresholds_bypass_thresh ( + .re (bucket_thresholds_re), + .we (bucket_thresholds_gated_we), + .wd (bucket_thresholds_bypass_thresh_wd), + .d (hw2reg.bucket_thresholds.bypass_thresh.d), + .qre (), + .qe (bucket_thresholds_flds_we[1]), + .q (reg2hw.bucket_thresholds.bypass_thresh.q), + .ds (), + .qs (bucket_thresholds_bypass_thresh_qs) + ); + assign reg2hw.bucket_thresholds.bypass_thresh.qe = bucket_thresholds_qe; + + + // R[markov_hi_thresholds]: V(True) + logic markov_hi_thresholds_qe; + logic [1:0] markov_hi_thresholds_flds_we; + assign markov_hi_thresholds_qe = &markov_hi_thresholds_flds_we; + // Create REGWEN-gated WE signal + logic markov_hi_thresholds_gated_we; + assign markov_hi_thresholds_gated_we = markov_hi_thresholds_we & regwen_qs; + // F[fips_thresh]: 15:0 + caliptra_prim_subreg_ext #( + .DW (16) + ) u_markov_hi_thresholds_fips_thresh ( + .re (markov_hi_thresholds_re), + .we (markov_hi_thresholds_gated_we), + .wd (markov_hi_thresholds_fips_thresh_wd), + .d (hw2reg.markov_hi_thresholds.fips_thresh.d), + .qre (), + .qe (markov_hi_thresholds_flds_we[0]), + .q (reg2hw.markov_hi_thresholds.fips_thresh.q), + .ds (), + .qs (markov_hi_thresholds_fips_thresh_qs) + ); + assign reg2hw.markov_hi_thresholds.fips_thresh.qe = markov_hi_thresholds_qe; + + // F[bypass_thresh]: 31:16 + caliptra_prim_subreg_ext #( + .DW (16) + ) u_markov_hi_thresholds_bypass_thresh ( + .re (markov_hi_thresholds_re), + .we (markov_hi_thresholds_gated_we), + .wd (markov_hi_thresholds_bypass_thresh_wd), + .d (hw2reg.markov_hi_thresholds.bypass_thresh.d), + .qre (), + .qe (markov_hi_thresholds_flds_we[1]), + .q (reg2hw.markov_hi_thresholds.bypass_thresh.q), + .ds (), + .qs (markov_hi_thresholds_bypass_thresh_qs) + ); + assign reg2hw.markov_hi_thresholds.bypass_thresh.qe = markov_hi_thresholds_qe; + + + // R[markov_lo_thresholds]: V(True) + logic markov_lo_thresholds_qe; + logic [1:0] markov_lo_thresholds_flds_we; + assign markov_lo_thresholds_qe = &markov_lo_thresholds_flds_we; + // Create REGWEN-gated WE signal + logic markov_lo_thresholds_gated_we; + assign markov_lo_thresholds_gated_we = markov_lo_thresholds_we & regwen_qs; + // F[fips_thresh]: 15:0 + caliptra_prim_subreg_ext #( + .DW (16) + ) u_markov_lo_thresholds_fips_thresh ( + .re (markov_lo_thresholds_re), + .we (markov_lo_thresholds_gated_we), + .wd (markov_lo_thresholds_fips_thresh_wd), + .d (hw2reg.markov_lo_thresholds.fips_thresh.d), + .qre (), + .qe (markov_lo_thresholds_flds_we[0]), + .q (reg2hw.markov_lo_thresholds.fips_thresh.q), + .ds (), + .qs (markov_lo_thresholds_fips_thresh_qs) + ); + assign reg2hw.markov_lo_thresholds.fips_thresh.qe = markov_lo_thresholds_qe; + + // F[bypass_thresh]: 31:16 + caliptra_prim_subreg_ext #( + .DW (16) + ) u_markov_lo_thresholds_bypass_thresh ( + .re (markov_lo_thresholds_re), + .we (markov_lo_thresholds_gated_we), + .wd (markov_lo_thresholds_bypass_thresh_wd), + .d (hw2reg.markov_lo_thresholds.bypass_thresh.d), + .qre (), + .qe (markov_lo_thresholds_flds_we[1]), + .q (reg2hw.markov_lo_thresholds.bypass_thresh.q), + .ds (), + .qs (markov_lo_thresholds_bypass_thresh_qs) + ); + assign reg2hw.markov_lo_thresholds.bypass_thresh.qe = markov_lo_thresholds_qe; + + + // R[extht_hi_thresholds]: V(True) + logic extht_hi_thresholds_qe; + logic [1:0] extht_hi_thresholds_flds_we; + assign extht_hi_thresholds_qe = &extht_hi_thresholds_flds_we; + // Create REGWEN-gated WE signal + logic extht_hi_thresholds_gated_we; + assign extht_hi_thresholds_gated_we = extht_hi_thresholds_we & regwen_qs; + // F[fips_thresh]: 15:0 + caliptra_prim_subreg_ext #( + .DW (16) + ) u_extht_hi_thresholds_fips_thresh ( + .re (extht_hi_thresholds_re), + .we (extht_hi_thresholds_gated_we), + .wd (extht_hi_thresholds_fips_thresh_wd), + .d (hw2reg.extht_hi_thresholds.fips_thresh.d), + .qre (), + .qe (extht_hi_thresholds_flds_we[0]), + .q (reg2hw.extht_hi_thresholds.fips_thresh.q), + .ds (), + .qs (extht_hi_thresholds_fips_thresh_qs) + ); + assign reg2hw.extht_hi_thresholds.fips_thresh.qe = extht_hi_thresholds_qe; + + // F[bypass_thresh]: 31:16 + caliptra_prim_subreg_ext #( + .DW (16) + ) u_extht_hi_thresholds_bypass_thresh ( + .re (extht_hi_thresholds_re), + .we (extht_hi_thresholds_gated_we), + .wd (extht_hi_thresholds_bypass_thresh_wd), + .d (hw2reg.extht_hi_thresholds.bypass_thresh.d), + .qre (), + .qe (extht_hi_thresholds_flds_we[1]), + .q (reg2hw.extht_hi_thresholds.bypass_thresh.q), + .ds (), + .qs (extht_hi_thresholds_bypass_thresh_qs) + ); + assign reg2hw.extht_hi_thresholds.bypass_thresh.qe = extht_hi_thresholds_qe; + + + // R[extht_lo_thresholds]: V(True) + logic extht_lo_thresholds_qe; + logic [1:0] extht_lo_thresholds_flds_we; + assign extht_lo_thresholds_qe = &extht_lo_thresholds_flds_we; + // Create REGWEN-gated WE signal + logic extht_lo_thresholds_gated_we; + assign extht_lo_thresholds_gated_we = extht_lo_thresholds_we & regwen_qs; + // F[fips_thresh]: 15:0 + caliptra_prim_subreg_ext #( + .DW (16) + ) u_extht_lo_thresholds_fips_thresh ( + .re (extht_lo_thresholds_re), + .we (extht_lo_thresholds_gated_we), + .wd (extht_lo_thresholds_fips_thresh_wd), + .d (hw2reg.extht_lo_thresholds.fips_thresh.d), + .qre (), + .qe (extht_lo_thresholds_flds_we[0]), + .q (reg2hw.extht_lo_thresholds.fips_thresh.q), + .ds (), + .qs (extht_lo_thresholds_fips_thresh_qs) + ); + assign reg2hw.extht_lo_thresholds.fips_thresh.qe = extht_lo_thresholds_qe; + + // F[bypass_thresh]: 31:16 + caliptra_prim_subreg_ext #( + .DW (16) + ) u_extht_lo_thresholds_bypass_thresh ( + .re (extht_lo_thresholds_re), + .we (extht_lo_thresholds_gated_we), + .wd (extht_lo_thresholds_bypass_thresh_wd), + .d (hw2reg.extht_lo_thresholds.bypass_thresh.d), + .qre (), + .qe (extht_lo_thresholds_flds_we[1]), + .q (reg2hw.extht_lo_thresholds.bypass_thresh.q), + .ds (), + .qs (extht_lo_thresholds_bypass_thresh_qs) + ); + assign reg2hw.extht_lo_thresholds.bypass_thresh.qe = extht_lo_thresholds_qe; + + + // R[repcnt_hi_watermarks]: V(True) + // F[fips_watermark]: 15:0 + caliptra_prim_subreg_ext #( + .DW (16) + ) u_repcnt_hi_watermarks_fips_watermark ( + .re (repcnt_hi_watermarks_re), + .we (1'b0), + .wd ('0), + .d (hw2reg.repcnt_hi_watermarks.fips_watermark.d), + .qre (), + .qe (), + .q (), + .ds (), + .qs (repcnt_hi_watermarks_fips_watermark_qs) + ); + + // F[bypass_watermark]: 31:16 + caliptra_prim_subreg_ext #( + .DW (16) + ) u_repcnt_hi_watermarks_bypass_watermark ( + .re (repcnt_hi_watermarks_re), + .we (1'b0), + .wd ('0), + .d (hw2reg.repcnt_hi_watermarks.bypass_watermark.d), + .qre (), + .qe (), + .q (), + .ds (), + .qs (repcnt_hi_watermarks_bypass_watermark_qs) + ); + + + // R[repcnts_hi_watermarks]: V(True) + // F[fips_watermark]: 15:0 + caliptra_prim_subreg_ext #( + .DW (16) + ) u_repcnts_hi_watermarks_fips_watermark ( + .re (repcnts_hi_watermarks_re), + .we (1'b0), + .wd ('0), + .d (hw2reg.repcnts_hi_watermarks.fips_watermark.d), + .qre (), + .qe (), + .q (), + .ds (), + .qs (repcnts_hi_watermarks_fips_watermark_qs) + ); + + // F[bypass_watermark]: 31:16 + caliptra_prim_subreg_ext #( + .DW (16) + ) u_repcnts_hi_watermarks_bypass_watermark ( + .re (repcnts_hi_watermarks_re), + .we (1'b0), + .wd ('0), + .d (hw2reg.repcnts_hi_watermarks.bypass_watermark.d), + .qre (), + .qe (), + .q (), + .ds (), + .qs (repcnts_hi_watermarks_bypass_watermark_qs) + ); + + + // R[adaptp_hi_watermarks]: V(True) + // F[fips_watermark]: 15:0 + caliptra_prim_subreg_ext #( + .DW (16) + ) u_adaptp_hi_watermarks_fips_watermark ( + .re (adaptp_hi_watermarks_re), + .we (1'b0), + .wd ('0), + .d (hw2reg.adaptp_hi_watermarks.fips_watermark.d), + .qre (), + .qe (), + .q (), + .ds (), + .qs (adaptp_hi_watermarks_fips_watermark_qs) + ); + + // F[bypass_watermark]: 31:16 + caliptra_prim_subreg_ext #( + .DW (16) + ) u_adaptp_hi_watermarks_bypass_watermark ( + .re (adaptp_hi_watermarks_re), + .we (1'b0), + .wd ('0), + .d (hw2reg.adaptp_hi_watermarks.bypass_watermark.d), + .qre (), + .qe (), + .q (), + .ds (), + .qs (adaptp_hi_watermarks_bypass_watermark_qs) + ); + + + // R[adaptp_lo_watermarks]: V(True) + // F[fips_watermark]: 15:0 + caliptra_prim_subreg_ext #( + .DW (16) + ) u_adaptp_lo_watermarks_fips_watermark ( + .re (adaptp_lo_watermarks_re), + .we (1'b0), + .wd ('0), + .d (hw2reg.adaptp_lo_watermarks.fips_watermark.d), + .qre (), + .qe (), + .q (), + .ds (), + .qs (adaptp_lo_watermarks_fips_watermark_qs) + ); + + // F[bypass_watermark]: 31:16 + caliptra_prim_subreg_ext #( + .DW (16) + ) u_adaptp_lo_watermarks_bypass_watermark ( + .re (adaptp_lo_watermarks_re), + .we (1'b0), + .wd ('0), + .d (hw2reg.adaptp_lo_watermarks.bypass_watermark.d), + .qre (), + .qe (), + .q (), + .ds (), + .qs (adaptp_lo_watermarks_bypass_watermark_qs) + ); + + + // R[extht_hi_watermarks]: V(True) + // F[fips_watermark]: 15:0 + caliptra_prim_subreg_ext #( + .DW (16) + ) u_extht_hi_watermarks_fips_watermark ( + .re (extht_hi_watermarks_re), + .we (1'b0), + .wd ('0), + .d (hw2reg.extht_hi_watermarks.fips_watermark.d), + .qre (), + .qe (), + .q (), + .ds (), + .qs (extht_hi_watermarks_fips_watermark_qs) + ); + + // F[bypass_watermark]: 31:16 + caliptra_prim_subreg_ext #( + .DW (16) + ) u_extht_hi_watermarks_bypass_watermark ( + .re (extht_hi_watermarks_re), + .we (1'b0), + .wd ('0), + .d (hw2reg.extht_hi_watermarks.bypass_watermark.d), + .qre (), + .qe (), + .q (), + .ds (), + .qs (extht_hi_watermarks_bypass_watermark_qs) + ); + + + // R[extht_lo_watermarks]: V(True) + // F[fips_watermark]: 15:0 + caliptra_prim_subreg_ext #( + .DW (16) + ) u_extht_lo_watermarks_fips_watermark ( + .re (extht_lo_watermarks_re), + .we (1'b0), + .wd ('0), + .d (hw2reg.extht_lo_watermarks.fips_watermark.d), + .qre (), + .qe (), + .q (), + .ds (), + .qs (extht_lo_watermarks_fips_watermark_qs) + ); + + // F[bypass_watermark]: 31:16 + caliptra_prim_subreg_ext #( + .DW (16) + ) u_extht_lo_watermarks_bypass_watermark ( + .re (extht_lo_watermarks_re), + .we (1'b0), + .wd ('0), + .d (hw2reg.extht_lo_watermarks.bypass_watermark.d), + .qre (), + .qe (), + .q (), + .ds (), + .qs (extht_lo_watermarks_bypass_watermark_qs) + ); + + + // R[bucket_hi_watermarks]: V(True) + // F[fips_watermark]: 15:0 + caliptra_prim_subreg_ext #( + .DW (16) + ) u_bucket_hi_watermarks_fips_watermark ( + .re (bucket_hi_watermarks_re), + .we (1'b0), + .wd ('0), + .d (hw2reg.bucket_hi_watermarks.fips_watermark.d), + .qre (), + .qe (), + .q (), + .ds (), + .qs (bucket_hi_watermarks_fips_watermark_qs) + ); + + // F[bypass_watermark]: 31:16 + caliptra_prim_subreg_ext #( + .DW (16) + ) u_bucket_hi_watermarks_bypass_watermark ( + .re (bucket_hi_watermarks_re), + .we (1'b0), + .wd ('0), + .d (hw2reg.bucket_hi_watermarks.bypass_watermark.d), + .qre (), + .qe (), + .q (), + .ds (), + .qs (bucket_hi_watermarks_bypass_watermark_qs) + ); + + + // R[markov_hi_watermarks]: V(True) + // F[fips_watermark]: 15:0 + caliptra_prim_subreg_ext #( + .DW (16) + ) u_markov_hi_watermarks_fips_watermark ( + .re (markov_hi_watermarks_re), + .we (1'b0), + .wd ('0), + .d (hw2reg.markov_hi_watermarks.fips_watermark.d), + .qre (), + .qe (), + .q (), + .ds (), + .qs (markov_hi_watermarks_fips_watermark_qs) + ); + + // F[bypass_watermark]: 31:16 + caliptra_prim_subreg_ext #( + .DW (16) + ) u_markov_hi_watermarks_bypass_watermark ( + .re (markov_hi_watermarks_re), + .we (1'b0), + .wd ('0), + .d (hw2reg.markov_hi_watermarks.bypass_watermark.d), + .qre (), + .qe (), + .q (), + .ds (), + .qs (markov_hi_watermarks_bypass_watermark_qs) + ); + + + // R[markov_lo_watermarks]: V(True) + // F[fips_watermark]: 15:0 + caliptra_prim_subreg_ext #( + .DW (16) + ) u_markov_lo_watermarks_fips_watermark ( + .re (markov_lo_watermarks_re), + .we (1'b0), + .wd ('0), + .d (hw2reg.markov_lo_watermarks.fips_watermark.d), + .qre (), + .qe (), + .q (), + .ds (), + .qs (markov_lo_watermarks_fips_watermark_qs) + ); + + // F[bypass_watermark]: 31:16 + caliptra_prim_subreg_ext #( + .DW (16) + ) u_markov_lo_watermarks_bypass_watermark ( + .re (markov_lo_watermarks_re), + .we (1'b0), + .wd ('0), + .d (hw2reg.markov_lo_watermarks.bypass_watermark.d), + .qre (), + .qe (), + .q (), + .ds (), + .qs (markov_lo_watermarks_bypass_watermark_qs) + ); + + + // R[repcnt_total_fails]: V(True) + caliptra_prim_subreg_ext #( + .DW (32) + ) u_repcnt_total_fails ( + .re (repcnt_total_fails_re), + .we (1'b0), + .wd ('0), + .d (hw2reg.repcnt_total_fails.d), + .qre (), + .qe (), + .q (), + .ds (), + .qs (repcnt_total_fails_qs) + ); + + + // R[repcnts_total_fails]: V(True) + caliptra_prim_subreg_ext #( + .DW (32) + ) u_repcnts_total_fails ( + .re (repcnts_total_fails_re), + .we (1'b0), + .wd ('0), + .d (hw2reg.repcnts_total_fails.d), + .qre (), + .qe (), + .q (), + .ds (), + .qs (repcnts_total_fails_qs) + ); + + + // R[adaptp_hi_total_fails]: V(True) + caliptra_prim_subreg_ext #( + .DW (32) + ) u_adaptp_hi_total_fails ( + .re (adaptp_hi_total_fails_re), + .we (1'b0), + .wd ('0), + .d (hw2reg.adaptp_hi_total_fails.d), + .qre (), + .qe (), + .q (), + .ds (), + .qs (adaptp_hi_total_fails_qs) + ); + + + // R[adaptp_lo_total_fails]: V(True) + caliptra_prim_subreg_ext #( + .DW (32) + ) u_adaptp_lo_total_fails ( + .re (adaptp_lo_total_fails_re), + .we (1'b0), + .wd ('0), + .d (hw2reg.adaptp_lo_total_fails.d), + .qre (), + .qe (), + .q (), + .ds (), + .qs (adaptp_lo_total_fails_qs) + ); + + + // R[bucket_total_fails]: V(True) + caliptra_prim_subreg_ext #( + .DW (32) + ) u_bucket_total_fails ( + .re (bucket_total_fails_re), + .we (1'b0), + .wd ('0), + .d (hw2reg.bucket_total_fails.d), + .qre (), + .qe (), + .q (), + .ds (), + .qs (bucket_total_fails_qs) + ); + + + // R[markov_hi_total_fails]: V(True) + caliptra_prim_subreg_ext #( + .DW (32) + ) u_markov_hi_total_fails ( + .re (markov_hi_total_fails_re), + .we (1'b0), + .wd ('0), + .d (hw2reg.markov_hi_total_fails.d), + .qre (), + .qe (), + .q (), + .ds (), + .qs (markov_hi_total_fails_qs) + ); + + + // R[markov_lo_total_fails]: V(True) + caliptra_prim_subreg_ext #( + .DW (32) + ) u_markov_lo_total_fails ( + .re (markov_lo_total_fails_re), + .we (1'b0), + .wd ('0), + .d (hw2reg.markov_lo_total_fails.d), + .qre (), + .qe (), + .q (), + .ds (), + .qs (markov_lo_total_fails_qs) + ); + + + // R[extht_hi_total_fails]: V(True) + caliptra_prim_subreg_ext #( + .DW (32) + ) u_extht_hi_total_fails ( + .re (extht_hi_total_fails_re), + .we (1'b0), + .wd ('0), + .d (hw2reg.extht_hi_total_fails.d), + .qre (), + .qe (), + .q (), + .ds (), + .qs (extht_hi_total_fails_qs) + ); + + + // R[extht_lo_total_fails]: V(True) + caliptra_prim_subreg_ext #( + .DW (32) + ) u_extht_lo_total_fails ( + .re (extht_lo_total_fails_re), + .we (1'b0), + .wd ('0), + .d (hw2reg.extht_lo_total_fails.d), + .qre (), + .qe (), + .q (), + .ds (), + .qs (extht_lo_total_fails_qs) + ); + + + // R[alert_threshold]: V(False) + // Create REGWEN-gated WE signal + logic alert_threshold_gated_we; + assign alert_threshold_gated_we = alert_threshold_we & regwen_qs; + // F[alert_threshold]: 15:0 + caliptra_prim_subreg #( + .DW (16), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRW), + .RESVAL (16'h2), + .Mubi (1'b0) + ) u_alert_threshold_alert_threshold ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (alert_threshold_gated_we), + .wd (alert_threshold_alert_threshold_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.alert_threshold.alert_threshold.q), + .ds (), + + // to register interface (read) + .qs (alert_threshold_alert_threshold_qs) + ); + + // F[alert_threshold_inv]: 31:16 + caliptra_prim_subreg #( + .DW (16), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRW), + .RESVAL (16'hfffd), + .Mubi (1'b0) + ) u_alert_threshold_alert_threshold_inv ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (alert_threshold_gated_we), + .wd (alert_threshold_alert_threshold_inv_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.alert_threshold.alert_threshold_inv.q), + .ds (), + + // to register interface (read) + .qs (alert_threshold_alert_threshold_inv_qs) + ); + + + // R[alert_summary_fail_counts]: V(True) + caliptra_prim_subreg_ext #( + .DW (16) + ) u_alert_summary_fail_counts ( + .re (alert_summary_fail_counts_re), + .we (1'b0), + .wd ('0), + .d (hw2reg.alert_summary_fail_counts.d), + .qre (), + .qe (), + .q (), + .ds (), + .qs (alert_summary_fail_counts_qs) + ); + + + // R[alert_fail_counts]: V(True) + // F[repcnt_fail_count]: 7:4 + caliptra_prim_subreg_ext #( + .DW (4) + ) u_alert_fail_counts_repcnt_fail_count ( + .re (alert_fail_counts_re), + .we (1'b0), + .wd ('0), + .d (hw2reg.alert_fail_counts.repcnt_fail_count.d), + .qre (), + .qe (), + .q (), + .ds (), + .qs (alert_fail_counts_repcnt_fail_count_qs) + ); + + // F[adaptp_hi_fail_count]: 11:8 + caliptra_prim_subreg_ext #( + .DW (4) + ) u_alert_fail_counts_adaptp_hi_fail_count ( + .re (alert_fail_counts_re), + .we (1'b0), + .wd ('0), + .d (hw2reg.alert_fail_counts.adaptp_hi_fail_count.d), + .qre (), + .qe (), + .q (), + .ds (), + .qs (alert_fail_counts_adaptp_hi_fail_count_qs) + ); + + // F[adaptp_lo_fail_count]: 15:12 + caliptra_prim_subreg_ext #( + .DW (4) + ) u_alert_fail_counts_adaptp_lo_fail_count ( + .re (alert_fail_counts_re), + .we (1'b0), + .wd ('0), + .d (hw2reg.alert_fail_counts.adaptp_lo_fail_count.d), + .qre (), + .qe (), + .q (), + .ds (), + .qs (alert_fail_counts_adaptp_lo_fail_count_qs) + ); + + // F[bucket_fail_count]: 19:16 + caliptra_prim_subreg_ext #( + .DW (4) + ) u_alert_fail_counts_bucket_fail_count ( + .re (alert_fail_counts_re), + .we (1'b0), + .wd ('0), + .d (hw2reg.alert_fail_counts.bucket_fail_count.d), + .qre (), + .qe (), + .q (), + .ds (), + .qs (alert_fail_counts_bucket_fail_count_qs) + ); + + // F[markov_hi_fail_count]: 23:20 + caliptra_prim_subreg_ext #( + .DW (4) + ) u_alert_fail_counts_markov_hi_fail_count ( + .re (alert_fail_counts_re), + .we (1'b0), + .wd ('0), + .d (hw2reg.alert_fail_counts.markov_hi_fail_count.d), + .qre (), + .qe (), + .q (), + .ds (), + .qs (alert_fail_counts_markov_hi_fail_count_qs) + ); + + // F[markov_lo_fail_count]: 27:24 + caliptra_prim_subreg_ext #( + .DW (4) + ) u_alert_fail_counts_markov_lo_fail_count ( + .re (alert_fail_counts_re), + .we (1'b0), + .wd ('0), + .d (hw2reg.alert_fail_counts.markov_lo_fail_count.d), + .qre (), + .qe (), + .q (), + .ds (), + .qs (alert_fail_counts_markov_lo_fail_count_qs) + ); + + // F[repcnts_fail_count]: 31:28 + caliptra_prim_subreg_ext #( + .DW (4) + ) u_alert_fail_counts_repcnts_fail_count ( + .re (alert_fail_counts_re), + .we (1'b0), + .wd ('0), + .d (hw2reg.alert_fail_counts.repcnts_fail_count.d), + .qre (), + .qe (), + .q (), + .ds (), + .qs (alert_fail_counts_repcnts_fail_count_qs) + ); + + + // R[extht_fail_counts]: V(True) + // F[extht_hi_fail_count]: 3:0 + caliptra_prim_subreg_ext #( + .DW (4) + ) u_extht_fail_counts_extht_hi_fail_count ( + .re (extht_fail_counts_re), + .we (1'b0), + .wd ('0), + .d (hw2reg.extht_fail_counts.extht_hi_fail_count.d), + .qre (), + .qe (), + .q (), + .ds (), + .qs (extht_fail_counts_extht_hi_fail_count_qs) + ); + + // F[extht_lo_fail_count]: 7:4 + caliptra_prim_subreg_ext #( + .DW (4) + ) u_extht_fail_counts_extht_lo_fail_count ( + .re (extht_fail_counts_re), + .we (1'b0), + .wd ('0), + .d (hw2reg.extht_fail_counts.extht_lo_fail_count.d), + .qre (), + .qe (), + .q (), + .ds (), + .qs (extht_fail_counts_extht_lo_fail_count_qs) + ); + + + // R[fw_ov_control]: V(False) + // Create REGWEN-gated WE signal + logic fw_ov_control_gated_we; + assign fw_ov_control_gated_we = fw_ov_control_we & regwen_qs; + // F[fw_ov_mode]: 3:0 + caliptra_prim_subreg #( + .DW (4), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_fw_ov_control_fw_ov_mode ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (fw_ov_control_gated_we), + .wd (fw_ov_control_fw_ov_mode_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.fw_ov_control.fw_ov_mode.q), + .ds (), + + // to register interface (read) + .qs (fw_ov_control_fw_ov_mode_qs) + ); + + // F[fw_ov_entropy_insert]: 7:4 + caliptra_prim_subreg #( + .DW (4), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_fw_ov_control_fw_ov_entropy_insert ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (fw_ov_control_gated_we), + .wd (fw_ov_control_fw_ov_entropy_insert_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.fw_ov_control.fw_ov_entropy_insert.q), + .ds (), + + // to register interface (read) + .qs (fw_ov_control_fw_ov_entropy_insert_qs) + ); + + + // R[fw_ov_sha3_start]: V(False) + caliptra_prim_subreg #( + .DW (4), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_fw_ov_sha3_start ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (fw_ov_sha3_start_we), + .wd (fw_ov_sha3_start_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.fw_ov_sha3_start.q), + .ds (), + + // to register interface (read) + .qs (fw_ov_sha3_start_qs) + ); + + + // R[fw_ov_wr_fifo_full]: V(True) + caliptra_prim_subreg_ext #( + .DW (1) + ) u_fw_ov_wr_fifo_full ( + .re (fw_ov_wr_fifo_full_re), + .we (1'b0), + .wd ('0), + .d (hw2reg.fw_ov_wr_fifo_full.d), + .qre (), + .qe (), + .q (), + .ds (), + .qs (fw_ov_wr_fifo_full_qs) + ); + + + // R[fw_ov_rd_fifo_overflow]: V(False) + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_fw_ov_rd_fifo_overflow ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.fw_ov_rd_fifo_overflow.de), + .d (hw2reg.fw_ov_rd_fifo_overflow.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (fw_ov_rd_fifo_overflow_qs) + ); + + + // R[fw_ov_rd_data]: V(True) + caliptra_prim_subreg_ext #( + .DW (32) + ) u_fw_ov_rd_data ( + .re (fw_ov_rd_data_re), + .we (1'b0), + .wd ('0), + .d (hw2reg.fw_ov_rd_data.d), + .qre (reg2hw.fw_ov_rd_data.re), + .qe (), + .q (reg2hw.fw_ov_rd_data.q), + .ds (), + .qs (fw_ov_rd_data_qs) + ); + + + // R[fw_ov_wr_data]: V(True) + logic fw_ov_wr_data_qe; + logic [0:0] fw_ov_wr_data_flds_we; + assign fw_ov_wr_data_qe = &fw_ov_wr_data_flds_we; + caliptra_prim_subreg_ext #( + .DW (32) + ) u_fw_ov_wr_data ( + .re (1'b0), + .we (fw_ov_wr_data_we), + .wd (fw_ov_wr_data_wd), + .d ('0), + .qre (), + .qe (fw_ov_wr_data_flds_we[0]), + .q (reg2hw.fw_ov_wr_data.q), + .ds (), + .qs () + ); + assign reg2hw.fw_ov_wr_data.qe = fw_ov_wr_data_qe; + + + // R[observe_fifo_thresh]: V(False) + // Create REGWEN-gated WE signal + logic observe_fifo_thresh_gated_we; + assign observe_fifo_thresh_gated_we = observe_fifo_thresh_we & regwen_qs; + caliptra_prim_subreg #( + .DW (6), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRW), + .RESVAL (6'h10), + .Mubi (1'b0) + ) u_observe_fifo_thresh ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (observe_fifo_thresh_gated_we), + .wd (observe_fifo_thresh_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.observe_fifo_thresh.q), + .ds (), + + // to register interface (read) + .qs (observe_fifo_thresh_qs) + ); + + + // R[observe_fifo_depth]: V(True) + caliptra_prim_subreg_ext #( + .DW (6) + ) u_observe_fifo_depth ( + .re (observe_fifo_depth_re), + .we (1'b0), + .wd ('0), + .d (hw2reg.observe_fifo_depth.d), + .qre (), + .qe (), + .q (), + .ds (), + .qs (observe_fifo_depth_qs) + ); + + + // R[debug_status]: V(True) + // F[entropy_fifo_depth]: 1:0 + caliptra_prim_subreg_ext #( + .DW (2) + ) u_debug_status_entropy_fifo_depth ( + .re (debug_status_re), + .we (1'b0), + .wd ('0), + .d (hw2reg.debug_status.entropy_fifo_depth.d), + .qre (), + .qe (), + .q (), + .ds (), + .qs (debug_status_entropy_fifo_depth_qs) + ); + + // F[sha3_fsm]: 5:3 + caliptra_prim_subreg_ext #( + .DW (3) + ) u_debug_status_sha3_fsm ( + .re (debug_status_re), + .we (1'b0), + .wd ('0), + .d (hw2reg.debug_status.sha3_fsm.d), + .qre (), + .qe (), + .q (), + .ds (), + .qs (debug_status_sha3_fsm_qs) + ); + + // F[sha3_block_pr]: 6:6 + caliptra_prim_subreg_ext #( + .DW (1) + ) u_debug_status_sha3_block_pr ( + .re (debug_status_re), + .we (1'b0), + .wd ('0), + .d (hw2reg.debug_status.sha3_block_pr.d), + .qre (), + .qe (), + .q (), + .ds (), + .qs (debug_status_sha3_block_pr_qs) + ); + + // F[sha3_squeezing]: 7:7 + caliptra_prim_subreg_ext #( + .DW (1) + ) u_debug_status_sha3_squeezing ( + .re (debug_status_re), + .we (1'b0), + .wd ('0), + .d (hw2reg.debug_status.sha3_squeezing.d), + .qre (), + .qe (), + .q (), + .ds (), + .qs (debug_status_sha3_squeezing_qs) + ); + + // F[sha3_absorbed]: 8:8 + caliptra_prim_subreg_ext #( + .DW (1) + ) u_debug_status_sha3_absorbed ( + .re (debug_status_re), + .we (1'b0), + .wd ('0), + .d (hw2reg.debug_status.sha3_absorbed.d), + .qre (), + .qe (), + .q (), + .ds (), + .qs (debug_status_sha3_absorbed_qs) + ); + + // F[sha3_err]: 9:9 + caliptra_prim_subreg_ext #( + .DW (1) + ) u_debug_status_sha3_err ( + .re (debug_status_re), + .we (1'b0), + .wd ('0), + .d (hw2reg.debug_status.sha3_err.d), + .qre (), + .qe (), + .q (), + .ds (), + .qs (debug_status_sha3_err_qs) + ); + + // F[main_sm_idle]: 16:16 + caliptra_prim_subreg_ext #( + .DW (1) + ) u_debug_status_main_sm_idle ( + .re (debug_status_re), + .we (1'b0), + .wd ('0), + .d (hw2reg.debug_status.main_sm_idle.d), + .qre (), + .qe (), + .q (), + .ds (), + .qs (debug_status_main_sm_idle_qs) + ); + + // F[main_sm_boot_done]: 17:17 + caliptra_prim_subreg_ext #( + .DW (1) + ) u_debug_status_main_sm_boot_done ( + .re (debug_status_re), + .we (1'b0), + .wd ('0), + .d (hw2reg.debug_status.main_sm_boot_done.d), + .qre (), + .qe (), + .q (), + .ds (), + .qs (debug_status_main_sm_boot_done_qs) + ); + + + // R[recov_alert_sts]: V(False) + // F[fips_enable_field_alert]: 0:0 + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_recov_alert_sts_fips_enable_field_alert ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (recov_alert_sts_we), + .wd (recov_alert_sts_fips_enable_field_alert_wd), + + // from internal hardware + .de (hw2reg.recov_alert_sts.fips_enable_field_alert.de), + .d (hw2reg.recov_alert_sts.fips_enable_field_alert.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (recov_alert_sts_fips_enable_field_alert_qs) + ); + + // F[entropy_data_reg_en_field_alert]: 1:1 + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_recov_alert_sts_entropy_data_reg_en_field_alert ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (recov_alert_sts_we), + .wd (recov_alert_sts_entropy_data_reg_en_field_alert_wd), + + // from internal hardware + .de (hw2reg.recov_alert_sts.entropy_data_reg_en_field_alert.de), + .d (hw2reg.recov_alert_sts.entropy_data_reg_en_field_alert.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (recov_alert_sts_entropy_data_reg_en_field_alert_qs) + ); + + // F[module_enable_field_alert]: 2:2 + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_recov_alert_sts_module_enable_field_alert ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (recov_alert_sts_we), + .wd (recov_alert_sts_module_enable_field_alert_wd), + + // from internal hardware + .de (hw2reg.recov_alert_sts.module_enable_field_alert.de), + .d (hw2reg.recov_alert_sts.module_enable_field_alert.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (recov_alert_sts_module_enable_field_alert_qs) + ); + + // F[threshold_scope_field_alert]: 3:3 + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_recov_alert_sts_threshold_scope_field_alert ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (recov_alert_sts_we), + .wd (recov_alert_sts_threshold_scope_field_alert_wd), + + // from internal hardware + .de (hw2reg.recov_alert_sts.threshold_scope_field_alert.de), + .d (hw2reg.recov_alert_sts.threshold_scope_field_alert.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (recov_alert_sts_threshold_scope_field_alert_qs) + ); + + // F[rng_bit_enable_field_alert]: 5:5 + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_recov_alert_sts_rng_bit_enable_field_alert ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (recov_alert_sts_we), + .wd (recov_alert_sts_rng_bit_enable_field_alert_wd), + + // from internal hardware + .de (hw2reg.recov_alert_sts.rng_bit_enable_field_alert.de), + .d (hw2reg.recov_alert_sts.rng_bit_enable_field_alert.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (recov_alert_sts_rng_bit_enable_field_alert_qs) + ); + + // F[fw_ov_sha3_start_field_alert]: 7:7 + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_recov_alert_sts_fw_ov_sha3_start_field_alert ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (recov_alert_sts_we), + .wd (recov_alert_sts_fw_ov_sha3_start_field_alert_wd), + + // from internal hardware + .de (hw2reg.recov_alert_sts.fw_ov_sha3_start_field_alert.de), + .d (hw2reg.recov_alert_sts.fw_ov_sha3_start_field_alert.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (recov_alert_sts_fw_ov_sha3_start_field_alert_qs) + ); + + // F[fw_ov_mode_field_alert]: 8:8 + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_recov_alert_sts_fw_ov_mode_field_alert ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (recov_alert_sts_we), + .wd (recov_alert_sts_fw_ov_mode_field_alert_wd), + + // from internal hardware + .de (hw2reg.recov_alert_sts.fw_ov_mode_field_alert.de), + .d (hw2reg.recov_alert_sts.fw_ov_mode_field_alert.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (recov_alert_sts_fw_ov_mode_field_alert_qs) + ); + + // F[fw_ov_entropy_insert_field_alert]: 9:9 + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_recov_alert_sts_fw_ov_entropy_insert_field_alert ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (recov_alert_sts_we), + .wd (recov_alert_sts_fw_ov_entropy_insert_field_alert_wd), + + // from internal hardware + .de (hw2reg.recov_alert_sts.fw_ov_entropy_insert_field_alert.de), + .d (hw2reg.recov_alert_sts.fw_ov_entropy_insert_field_alert.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (recov_alert_sts_fw_ov_entropy_insert_field_alert_qs) + ); + + // F[es_route_field_alert]: 10:10 + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_recov_alert_sts_es_route_field_alert ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (recov_alert_sts_we), + .wd (recov_alert_sts_es_route_field_alert_wd), + + // from internal hardware + .de (hw2reg.recov_alert_sts.es_route_field_alert.de), + .d (hw2reg.recov_alert_sts.es_route_field_alert.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (recov_alert_sts_es_route_field_alert_qs) + ); + + // F[es_type_field_alert]: 11:11 + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_recov_alert_sts_es_type_field_alert ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (recov_alert_sts_we), + .wd (recov_alert_sts_es_type_field_alert_wd), + + // from internal hardware + .de (hw2reg.recov_alert_sts.es_type_field_alert.de), + .d (hw2reg.recov_alert_sts.es_type_field_alert.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (recov_alert_sts_es_type_field_alert_qs) + ); + + // F[es_main_sm_alert]: 12:12 + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_recov_alert_sts_es_main_sm_alert ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (recov_alert_sts_we), + .wd (recov_alert_sts_es_main_sm_alert_wd), + + // from internal hardware + .de (hw2reg.recov_alert_sts.es_main_sm_alert.de), + .d (hw2reg.recov_alert_sts.es_main_sm_alert.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (recov_alert_sts_es_main_sm_alert_qs) + ); + + // F[es_bus_cmp_alert]: 13:13 + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_recov_alert_sts_es_bus_cmp_alert ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (recov_alert_sts_we), + .wd (recov_alert_sts_es_bus_cmp_alert_wd), + + // from internal hardware + .de (hw2reg.recov_alert_sts.es_bus_cmp_alert.de), + .d (hw2reg.recov_alert_sts.es_bus_cmp_alert.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (recov_alert_sts_es_bus_cmp_alert_qs) + ); + + // F[es_thresh_cfg_alert]: 14:14 + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_recov_alert_sts_es_thresh_cfg_alert ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (recov_alert_sts_we), + .wd (recov_alert_sts_es_thresh_cfg_alert_wd), + + // from internal hardware + .de (hw2reg.recov_alert_sts.es_thresh_cfg_alert.de), + .d (hw2reg.recov_alert_sts.es_thresh_cfg_alert.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (recov_alert_sts_es_thresh_cfg_alert_qs) + ); + + // F[es_fw_ov_wr_alert]: 15:15 + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_recov_alert_sts_es_fw_ov_wr_alert ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (recov_alert_sts_we), + .wd (recov_alert_sts_es_fw_ov_wr_alert_wd), + + // from internal hardware + .de (hw2reg.recov_alert_sts.es_fw_ov_wr_alert.de), + .d (hw2reg.recov_alert_sts.es_fw_ov_wr_alert.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (recov_alert_sts_es_fw_ov_wr_alert_qs) + ); + + // F[es_fw_ov_disable_alert]: 16:16 + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_recov_alert_sts_es_fw_ov_disable_alert ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (recov_alert_sts_we), + .wd (recov_alert_sts_es_fw_ov_disable_alert_wd), + + // from internal hardware + .de (hw2reg.recov_alert_sts.es_fw_ov_disable_alert.de), + .d (hw2reg.recov_alert_sts.es_fw_ov_disable_alert.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (recov_alert_sts_es_fw_ov_disable_alert_qs) + ); + + // F[fips_flag_field_alert]: 17:17 + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_recov_alert_sts_fips_flag_field_alert ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (recov_alert_sts_we), + .wd (recov_alert_sts_fips_flag_field_alert_wd), + + // from internal hardware + .de (hw2reg.recov_alert_sts.fips_flag_field_alert.de), + .d (hw2reg.recov_alert_sts.fips_flag_field_alert.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (recov_alert_sts_fips_flag_field_alert_qs) + ); + + // F[rng_fips_field_alert]: 18:18 + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_recov_alert_sts_rng_fips_field_alert ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (recov_alert_sts_we), + .wd (recov_alert_sts_rng_fips_field_alert_wd), + + // from internal hardware + .de (hw2reg.recov_alert_sts.rng_fips_field_alert.de), + .d (hw2reg.recov_alert_sts.rng_fips_field_alert.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (recov_alert_sts_rng_fips_field_alert_qs) + ); + + // F[postht_entropy_drop_alert]: 31:31 + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_recov_alert_sts_postht_entropy_drop_alert ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (recov_alert_sts_we), + .wd (recov_alert_sts_postht_entropy_drop_alert_wd), + + // from internal hardware + .de (hw2reg.recov_alert_sts.postht_entropy_drop_alert.de), + .d (hw2reg.recov_alert_sts.postht_entropy_drop_alert.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (recov_alert_sts_postht_entropy_drop_alert_qs) + ); + + + // R[err_code]: V(False) + // F[sfifo_esrng_err]: 0:0 + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_err_code_sfifo_esrng_err ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.err_code.sfifo_esrng_err.de), + .d (hw2reg.err_code.sfifo_esrng_err.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (err_code_sfifo_esrng_err_qs) + ); + + // F[sfifo_distr_err]: 1:1 + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_err_code_sfifo_distr_err ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.err_code.sfifo_distr_err.de), + .d (hw2reg.err_code.sfifo_distr_err.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (err_code_sfifo_distr_err_qs) + ); + + // F[sfifo_observe_err]: 2:2 + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_err_code_sfifo_observe_err ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.err_code.sfifo_observe_err.de), + .d (hw2reg.err_code.sfifo_observe_err.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (err_code_sfifo_observe_err_qs) + ); + + // F[sfifo_esfinal_err]: 3:3 + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_err_code_sfifo_esfinal_err ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.err_code.sfifo_esfinal_err.de), + .d (hw2reg.err_code.sfifo_esfinal_err.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (err_code_sfifo_esfinal_err_qs) + ); + + // F[es_ack_sm_err]: 20:20 + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_err_code_es_ack_sm_err ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.err_code.es_ack_sm_err.de), + .d (hw2reg.err_code.es_ack_sm_err.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (err_code_es_ack_sm_err_qs) + ); + + // F[es_main_sm_err]: 21:21 + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_err_code_es_main_sm_err ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.err_code.es_main_sm_err.de), + .d (hw2reg.err_code.es_main_sm_err.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (err_code_es_main_sm_err_qs) + ); + + // F[es_cntr_err]: 22:22 + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_err_code_es_cntr_err ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.err_code.es_cntr_err.de), + .d (hw2reg.err_code.es_cntr_err.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (err_code_es_cntr_err_qs) + ); + + // F[sha3_state_err]: 23:23 + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_err_code_sha3_state_err ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.err_code.sha3_state_err.de), + .d (hw2reg.err_code.sha3_state_err.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (err_code_sha3_state_err_qs) + ); + + // F[sha3_rst_storage_err]: 24:24 + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_err_code_sha3_rst_storage_err ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.err_code.sha3_rst_storage_err.de), + .d (hw2reg.err_code.sha3_rst_storage_err.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (err_code_sha3_rst_storage_err_qs) + ); + + // F[fifo_write_err]: 28:28 + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_err_code_fifo_write_err ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.err_code.fifo_write_err.de), + .d (hw2reg.err_code.fifo_write_err.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (err_code_fifo_write_err_qs) + ); + + // F[fifo_read_err]: 29:29 + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_err_code_fifo_read_err ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.err_code.fifo_read_err.de), + .d (hw2reg.err_code.fifo_read_err.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (err_code_fifo_read_err_qs) + ); + + // F[fifo_state_err]: 30:30 + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_err_code_fifo_state_err ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.err_code.fifo_state_err.de), + .d (hw2reg.err_code.fifo_state_err.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (err_code_fifo_state_err_qs) + ); + + + // R[err_code_test]: V(False) + logic err_code_test_qe; + logic [0:0] err_code_test_flds_we; + caliptra_prim_flop #( + .Width(1), + .ResetValue(0) + ) u_err_code_test0_qe ( + .clk_i(clk_i), + .rst_ni(rst_ni), + .d_i(&err_code_test_flds_we), + .q_o(err_code_test_qe) + ); + caliptra_prim_subreg #( + .DW (5), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRW), + .RESVAL (5'h0), + .Mubi (1'b0) + ) u_err_code_test ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (err_code_test_we), + .wd (err_code_test_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (err_code_test_flds_we[0]), + .q (reg2hw.err_code_test.q), + .ds (), + + // to register interface (read) + .qs (err_code_test_qs) + ); + assign reg2hw.err_code_test.qe = err_code_test_qe; + + + // R[main_sm_state]: V(False) + caliptra_prim_subreg #( + .DW (9), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRO), + .RESVAL (9'hf5), + .Mubi (1'b0) + ) u_main_sm_state ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.main_sm_state.de), + .d (hw2reg.main_sm_state.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (main_sm_state_qs) + ); + + + + logic [56:0] addr_hit; + always_comb begin + addr_hit = '0; + addr_hit[ 0] = (reg_addr == ENTROPY_SRC_INTR_STATE_OFFSET); + addr_hit[ 1] = (reg_addr == ENTROPY_SRC_INTR_ENABLE_OFFSET); + addr_hit[ 2] = (reg_addr == ENTROPY_SRC_INTR_TEST_OFFSET); + addr_hit[ 3] = (reg_addr == ENTROPY_SRC_ALERT_TEST_OFFSET); + addr_hit[ 4] = (reg_addr == ENTROPY_SRC_ME_REGWEN_OFFSET); + addr_hit[ 5] = (reg_addr == ENTROPY_SRC_SW_REGUPD_OFFSET); + addr_hit[ 6] = (reg_addr == ENTROPY_SRC_REGWEN_OFFSET); + addr_hit[ 7] = (reg_addr == ENTROPY_SRC_REV_OFFSET); + addr_hit[ 8] = (reg_addr == ENTROPY_SRC_MODULE_ENABLE_OFFSET); + addr_hit[ 9] = (reg_addr == ENTROPY_SRC_CONF_OFFSET); + addr_hit[10] = (reg_addr == ENTROPY_SRC_ENTROPY_CONTROL_OFFSET); + addr_hit[11] = (reg_addr == ENTROPY_SRC_ENTROPY_DATA_OFFSET); + addr_hit[12] = (reg_addr == ENTROPY_SRC_HEALTH_TEST_WINDOWS_OFFSET); + addr_hit[13] = (reg_addr == ENTROPY_SRC_REPCNT_THRESHOLDS_OFFSET); + addr_hit[14] = (reg_addr == ENTROPY_SRC_REPCNTS_THRESHOLDS_OFFSET); + addr_hit[15] = (reg_addr == ENTROPY_SRC_ADAPTP_HI_THRESHOLDS_OFFSET); + addr_hit[16] = (reg_addr == ENTROPY_SRC_ADAPTP_LO_THRESHOLDS_OFFSET); + addr_hit[17] = (reg_addr == ENTROPY_SRC_BUCKET_THRESHOLDS_OFFSET); + addr_hit[18] = (reg_addr == ENTROPY_SRC_MARKOV_HI_THRESHOLDS_OFFSET); + addr_hit[19] = (reg_addr == ENTROPY_SRC_MARKOV_LO_THRESHOLDS_OFFSET); + addr_hit[20] = (reg_addr == ENTROPY_SRC_EXTHT_HI_THRESHOLDS_OFFSET); + addr_hit[21] = (reg_addr == ENTROPY_SRC_EXTHT_LO_THRESHOLDS_OFFSET); + addr_hit[22] = (reg_addr == ENTROPY_SRC_REPCNT_HI_WATERMARKS_OFFSET); + addr_hit[23] = (reg_addr == ENTROPY_SRC_REPCNTS_HI_WATERMARKS_OFFSET); + addr_hit[24] = (reg_addr == ENTROPY_SRC_ADAPTP_HI_WATERMARKS_OFFSET); + addr_hit[25] = (reg_addr == ENTROPY_SRC_ADAPTP_LO_WATERMARKS_OFFSET); + addr_hit[26] = (reg_addr == ENTROPY_SRC_EXTHT_HI_WATERMARKS_OFFSET); + addr_hit[27] = (reg_addr == ENTROPY_SRC_EXTHT_LO_WATERMARKS_OFFSET); + addr_hit[28] = (reg_addr == ENTROPY_SRC_BUCKET_HI_WATERMARKS_OFFSET); + addr_hit[29] = (reg_addr == ENTROPY_SRC_MARKOV_HI_WATERMARKS_OFFSET); + addr_hit[30] = (reg_addr == ENTROPY_SRC_MARKOV_LO_WATERMARKS_OFFSET); + addr_hit[31] = (reg_addr == ENTROPY_SRC_REPCNT_TOTAL_FAILS_OFFSET); + addr_hit[32] = (reg_addr == ENTROPY_SRC_REPCNTS_TOTAL_FAILS_OFFSET); + addr_hit[33] = (reg_addr == ENTROPY_SRC_ADAPTP_HI_TOTAL_FAILS_OFFSET); + addr_hit[34] = (reg_addr == ENTROPY_SRC_ADAPTP_LO_TOTAL_FAILS_OFFSET); + addr_hit[35] = (reg_addr == ENTROPY_SRC_BUCKET_TOTAL_FAILS_OFFSET); + addr_hit[36] = (reg_addr == ENTROPY_SRC_MARKOV_HI_TOTAL_FAILS_OFFSET); + addr_hit[37] = (reg_addr == ENTROPY_SRC_MARKOV_LO_TOTAL_FAILS_OFFSET); + addr_hit[38] = (reg_addr == ENTROPY_SRC_EXTHT_HI_TOTAL_FAILS_OFFSET); + addr_hit[39] = (reg_addr == ENTROPY_SRC_EXTHT_LO_TOTAL_FAILS_OFFSET); + addr_hit[40] = (reg_addr == ENTROPY_SRC_ALERT_THRESHOLD_OFFSET); + addr_hit[41] = (reg_addr == ENTROPY_SRC_ALERT_SUMMARY_FAIL_COUNTS_OFFSET); + addr_hit[42] = (reg_addr == ENTROPY_SRC_ALERT_FAIL_COUNTS_OFFSET); + addr_hit[43] = (reg_addr == ENTROPY_SRC_EXTHT_FAIL_COUNTS_OFFSET); + addr_hit[44] = (reg_addr == ENTROPY_SRC_FW_OV_CONTROL_OFFSET); + addr_hit[45] = (reg_addr == ENTROPY_SRC_FW_OV_SHA3_START_OFFSET); + addr_hit[46] = (reg_addr == ENTROPY_SRC_FW_OV_WR_FIFO_FULL_OFFSET); + addr_hit[47] = (reg_addr == ENTROPY_SRC_FW_OV_RD_FIFO_OVERFLOW_OFFSET); + addr_hit[48] = (reg_addr == ENTROPY_SRC_FW_OV_RD_DATA_OFFSET); + addr_hit[49] = (reg_addr == ENTROPY_SRC_FW_OV_WR_DATA_OFFSET); + addr_hit[50] = (reg_addr == ENTROPY_SRC_OBSERVE_FIFO_THRESH_OFFSET); + addr_hit[51] = (reg_addr == ENTROPY_SRC_OBSERVE_FIFO_DEPTH_OFFSET); + addr_hit[52] = (reg_addr == ENTROPY_SRC_DEBUG_STATUS_OFFSET); + addr_hit[53] = (reg_addr == ENTROPY_SRC_RECOV_ALERT_STS_OFFSET); + addr_hit[54] = (reg_addr == ENTROPY_SRC_ERR_CODE_OFFSET); + addr_hit[55] = (reg_addr == ENTROPY_SRC_ERR_CODE_TEST_OFFSET); + addr_hit[56] = (reg_addr == ENTROPY_SRC_MAIN_SM_STATE_OFFSET); + end + + assign addrmiss = (reg_re || reg_we) ? ~|addr_hit : 1'b0; + + // Check sub-word write is permitted + always_comb begin + wr_err = (reg_we & + ((addr_hit[ 0] & (|(ENTROPY_SRC_PERMIT[ 0] & ~reg_be))) | + (addr_hit[ 1] & (|(ENTROPY_SRC_PERMIT[ 1] & ~reg_be))) | + (addr_hit[ 2] & (|(ENTROPY_SRC_PERMIT[ 2] & ~reg_be))) | + (addr_hit[ 3] & (|(ENTROPY_SRC_PERMIT[ 3] & ~reg_be))) | + (addr_hit[ 4] & (|(ENTROPY_SRC_PERMIT[ 4] & ~reg_be))) | + (addr_hit[ 5] & (|(ENTROPY_SRC_PERMIT[ 5] & ~reg_be))) | + (addr_hit[ 6] & (|(ENTROPY_SRC_PERMIT[ 6] & ~reg_be))) | + (addr_hit[ 7] & (|(ENTROPY_SRC_PERMIT[ 7] & ~reg_be))) | + (addr_hit[ 8] & (|(ENTROPY_SRC_PERMIT[ 8] & ~reg_be))) | + (addr_hit[ 9] & (|(ENTROPY_SRC_PERMIT[ 9] & ~reg_be))) | + (addr_hit[10] & (|(ENTROPY_SRC_PERMIT[10] & ~reg_be))) | + (addr_hit[11] & (|(ENTROPY_SRC_PERMIT[11] & ~reg_be))) | + (addr_hit[12] & (|(ENTROPY_SRC_PERMIT[12] & ~reg_be))) | + (addr_hit[13] & (|(ENTROPY_SRC_PERMIT[13] & ~reg_be))) | + (addr_hit[14] & (|(ENTROPY_SRC_PERMIT[14] & ~reg_be))) | + (addr_hit[15] & (|(ENTROPY_SRC_PERMIT[15] & ~reg_be))) | + (addr_hit[16] & (|(ENTROPY_SRC_PERMIT[16] & ~reg_be))) | + (addr_hit[17] & (|(ENTROPY_SRC_PERMIT[17] & ~reg_be))) | + (addr_hit[18] & (|(ENTROPY_SRC_PERMIT[18] & ~reg_be))) | + (addr_hit[19] & (|(ENTROPY_SRC_PERMIT[19] & ~reg_be))) | + (addr_hit[20] & (|(ENTROPY_SRC_PERMIT[20] & ~reg_be))) | + (addr_hit[21] & (|(ENTROPY_SRC_PERMIT[21] & ~reg_be))) | + (addr_hit[22] & (|(ENTROPY_SRC_PERMIT[22] & ~reg_be))) | + (addr_hit[23] & (|(ENTROPY_SRC_PERMIT[23] & ~reg_be))) | + (addr_hit[24] & (|(ENTROPY_SRC_PERMIT[24] & ~reg_be))) | + (addr_hit[25] & (|(ENTROPY_SRC_PERMIT[25] & ~reg_be))) | + (addr_hit[26] & (|(ENTROPY_SRC_PERMIT[26] & ~reg_be))) | + (addr_hit[27] & (|(ENTROPY_SRC_PERMIT[27] & ~reg_be))) | + (addr_hit[28] & (|(ENTROPY_SRC_PERMIT[28] & ~reg_be))) | + (addr_hit[29] & (|(ENTROPY_SRC_PERMIT[29] & ~reg_be))) | + (addr_hit[30] & (|(ENTROPY_SRC_PERMIT[30] & ~reg_be))) | + (addr_hit[31] & (|(ENTROPY_SRC_PERMIT[31] & ~reg_be))) | + (addr_hit[32] & (|(ENTROPY_SRC_PERMIT[32] & ~reg_be))) | + (addr_hit[33] & (|(ENTROPY_SRC_PERMIT[33] & ~reg_be))) | + (addr_hit[34] & (|(ENTROPY_SRC_PERMIT[34] & ~reg_be))) | + (addr_hit[35] & (|(ENTROPY_SRC_PERMIT[35] & ~reg_be))) | + (addr_hit[36] & (|(ENTROPY_SRC_PERMIT[36] & ~reg_be))) | + (addr_hit[37] & (|(ENTROPY_SRC_PERMIT[37] & ~reg_be))) | + (addr_hit[38] & (|(ENTROPY_SRC_PERMIT[38] & ~reg_be))) | + (addr_hit[39] & (|(ENTROPY_SRC_PERMIT[39] & ~reg_be))) | + (addr_hit[40] & (|(ENTROPY_SRC_PERMIT[40] & ~reg_be))) | + (addr_hit[41] & (|(ENTROPY_SRC_PERMIT[41] & ~reg_be))) | + (addr_hit[42] & (|(ENTROPY_SRC_PERMIT[42] & ~reg_be))) | + (addr_hit[43] & (|(ENTROPY_SRC_PERMIT[43] & ~reg_be))) | + (addr_hit[44] & (|(ENTROPY_SRC_PERMIT[44] & ~reg_be))) | + (addr_hit[45] & (|(ENTROPY_SRC_PERMIT[45] & ~reg_be))) | + (addr_hit[46] & (|(ENTROPY_SRC_PERMIT[46] & ~reg_be))) | + (addr_hit[47] & (|(ENTROPY_SRC_PERMIT[47] & ~reg_be))) | + (addr_hit[48] & (|(ENTROPY_SRC_PERMIT[48] & ~reg_be))) | + (addr_hit[49] & (|(ENTROPY_SRC_PERMIT[49] & ~reg_be))) | + (addr_hit[50] & (|(ENTROPY_SRC_PERMIT[50] & ~reg_be))) | + (addr_hit[51] & (|(ENTROPY_SRC_PERMIT[51] & ~reg_be))) | + (addr_hit[52] & (|(ENTROPY_SRC_PERMIT[52] & ~reg_be))) | + (addr_hit[53] & (|(ENTROPY_SRC_PERMIT[53] & ~reg_be))) | + (addr_hit[54] & (|(ENTROPY_SRC_PERMIT[54] & ~reg_be))) | + (addr_hit[55] & (|(ENTROPY_SRC_PERMIT[55] & ~reg_be))) | + (addr_hit[56] & (|(ENTROPY_SRC_PERMIT[56] & ~reg_be))))); + end + + // Generate write-enables + assign intr_state_we = addr_hit[0] & reg_we & !reg_error; + + assign intr_state_es_entropy_valid_wd = reg_wdata[0]; + + assign intr_state_es_health_test_failed_wd = reg_wdata[1]; + + assign intr_state_es_observe_fifo_ready_wd = reg_wdata[2]; + + assign intr_state_es_fatal_err_wd = reg_wdata[3]; + assign intr_enable_we = addr_hit[1] & reg_we & !reg_error; + + assign intr_enable_es_entropy_valid_wd = reg_wdata[0]; + + assign intr_enable_es_health_test_failed_wd = reg_wdata[1]; + + assign intr_enable_es_observe_fifo_ready_wd = reg_wdata[2]; + + assign intr_enable_es_fatal_err_wd = reg_wdata[3]; + assign intr_test_we = addr_hit[2] & reg_we & !reg_error; + + assign intr_test_es_entropy_valid_wd = reg_wdata[0]; + + assign intr_test_es_health_test_failed_wd = reg_wdata[1]; + + assign intr_test_es_observe_fifo_ready_wd = reg_wdata[2]; + + assign intr_test_es_fatal_err_wd = reg_wdata[3]; + assign alert_test_we = addr_hit[3] & reg_we & !reg_error; + + assign alert_test_recov_alert_wd = reg_wdata[0]; + + assign alert_test_fatal_alert_wd = reg_wdata[1]; + assign me_regwen_we = addr_hit[4] & reg_we & !reg_error; + + assign me_regwen_wd = reg_wdata[0]; + assign sw_regupd_we = addr_hit[5] & reg_we & !reg_error; + + assign sw_regupd_wd = reg_wdata[0]; + assign module_enable_we = addr_hit[8] & reg_we & !reg_error; + + assign module_enable_wd = reg_wdata[3:0]; + assign conf_we = addr_hit[9] & reg_we & !reg_error; + + assign conf_fips_enable_wd = reg_wdata[3:0]; + + assign conf_fips_flag_wd = reg_wdata[7:4]; + + assign conf_rng_fips_wd = reg_wdata[11:8]; + + assign conf_rng_bit_enable_wd = reg_wdata[15:12]; + + assign conf_rng_bit_sel_wd = reg_wdata[17:16]; + + assign conf_threshold_scope_wd = reg_wdata[21:18]; + + assign conf_entropy_data_reg_enable_wd = reg_wdata[25:22]; + assign entropy_control_we = addr_hit[10] & reg_we & !reg_error; + + assign entropy_control_es_route_wd = reg_wdata[3:0]; + + assign entropy_control_es_type_wd = reg_wdata[7:4]; + assign entropy_data_re = addr_hit[11] & reg_re & !reg_error; + assign health_test_windows_we = addr_hit[12] & reg_we & !reg_error; + + assign health_test_windows_fips_window_wd = reg_wdata[15:0]; + + assign health_test_windows_bypass_window_wd = reg_wdata[31:16]; + assign repcnt_thresholds_re = addr_hit[13] & reg_re & !reg_error; + assign repcnt_thresholds_we = addr_hit[13] & reg_we & !reg_error; + + assign repcnt_thresholds_fips_thresh_wd = reg_wdata[15:0]; + + assign repcnt_thresholds_bypass_thresh_wd = reg_wdata[31:16]; + assign repcnts_thresholds_re = addr_hit[14] & reg_re & !reg_error; + assign repcnts_thresholds_we = addr_hit[14] & reg_we & !reg_error; + + assign repcnts_thresholds_fips_thresh_wd = reg_wdata[15:0]; + + assign repcnts_thresholds_bypass_thresh_wd = reg_wdata[31:16]; + assign adaptp_hi_thresholds_re = addr_hit[15] & reg_re & !reg_error; + assign adaptp_hi_thresholds_we = addr_hit[15] & reg_we & !reg_error; + + assign adaptp_hi_thresholds_fips_thresh_wd = reg_wdata[15:0]; + + assign adaptp_hi_thresholds_bypass_thresh_wd = reg_wdata[31:16]; + assign adaptp_lo_thresholds_re = addr_hit[16] & reg_re & !reg_error; + assign adaptp_lo_thresholds_we = addr_hit[16] & reg_we & !reg_error; + + assign adaptp_lo_thresholds_fips_thresh_wd = reg_wdata[15:0]; + + assign adaptp_lo_thresholds_bypass_thresh_wd = reg_wdata[31:16]; + assign bucket_thresholds_re = addr_hit[17] & reg_re & !reg_error; + assign bucket_thresholds_we = addr_hit[17] & reg_we & !reg_error; + + assign bucket_thresholds_fips_thresh_wd = reg_wdata[15:0]; + + assign bucket_thresholds_bypass_thresh_wd = reg_wdata[31:16]; + assign markov_hi_thresholds_re = addr_hit[18] & reg_re & !reg_error; + assign markov_hi_thresholds_we = addr_hit[18] & reg_we & !reg_error; + + assign markov_hi_thresholds_fips_thresh_wd = reg_wdata[15:0]; + + assign markov_hi_thresholds_bypass_thresh_wd = reg_wdata[31:16]; + assign markov_lo_thresholds_re = addr_hit[19] & reg_re & !reg_error; + assign markov_lo_thresholds_we = addr_hit[19] & reg_we & !reg_error; + + assign markov_lo_thresholds_fips_thresh_wd = reg_wdata[15:0]; + + assign markov_lo_thresholds_bypass_thresh_wd = reg_wdata[31:16]; + assign extht_hi_thresholds_re = addr_hit[20] & reg_re & !reg_error; + assign extht_hi_thresholds_we = addr_hit[20] & reg_we & !reg_error; + + assign extht_hi_thresholds_fips_thresh_wd = reg_wdata[15:0]; + + assign extht_hi_thresholds_bypass_thresh_wd = reg_wdata[31:16]; + assign extht_lo_thresholds_re = addr_hit[21] & reg_re & !reg_error; + assign extht_lo_thresholds_we = addr_hit[21] & reg_we & !reg_error; + + assign extht_lo_thresholds_fips_thresh_wd = reg_wdata[15:0]; + + assign extht_lo_thresholds_bypass_thresh_wd = reg_wdata[31:16]; + assign repcnt_hi_watermarks_re = addr_hit[22] & reg_re & !reg_error; + assign repcnts_hi_watermarks_re = addr_hit[23] & reg_re & !reg_error; + assign adaptp_hi_watermarks_re = addr_hit[24] & reg_re & !reg_error; + assign adaptp_lo_watermarks_re = addr_hit[25] & reg_re & !reg_error; + assign extht_hi_watermarks_re = addr_hit[26] & reg_re & !reg_error; + assign extht_lo_watermarks_re = addr_hit[27] & reg_re & !reg_error; + assign bucket_hi_watermarks_re = addr_hit[28] & reg_re & !reg_error; + assign markov_hi_watermarks_re = addr_hit[29] & reg_re & !reg_error; + assign markov_lo_watermarks_re = addr_hit[30] & reg_re & !reg_error; + assign repcnt_total_fails_re = addr_hit[31] & reg_re & !reg_error; + assign repcnts_total_fails_re = addr_hit[32] & reg_re & !reg_error; + assign adaptp_hi_total_fails_re = addr_hit[33] & reg_re & !reg_error; + assign adaptp_lo_total_fails_re = addr_hit[34] & reg_re & !reg_error; + assign bucket_total_fails_re = addr_hit[35] & reg_re & !reg_error; + assign markov_hi_total_fails_re = addr_hit[36] & reg_re & !reg_error; + assign markov_lo_total_fails_re = addr_hit[37] & reg_re & !reg_error; + assign extht_hi_total_fails_re = addr_hit[38] & reg_re & !reg_error; + assign extht_lo_total_fails_re = addr_hit[39] & reg_re & !reg_error; + assign alert_threshold_we = addr_hit[40] & reg_we & !reg_error; + + assign alert_threshold_alert_threshold_wd = reg_wdata[15:0]; + + assign alert_threshold_alert_threshold_inv_wd = reg_wdata[31:16]; + assign alert_summary_fail_counts_re = addr_hit[41] & reg_re & !reg_error; + assign alert_fail_counts_re = addr_hit[42] & reg_re & !reg_error; + assign extht_fail_counts_re = addr_hit[43] & reg_re & !reg_error; + assign fw_ov_control_we = addr_hit[44] & reg_we & !reg_error; + + assign fw_ov_control_fw_ov_mode_wd = reg_wdata[3:0]; + + assign fw_ov_control_fw_ov_entropy_insert_wd = reg_wdata[7:4]; + assign fw_ov_sha3_start_we = addr_hit[45] & reg_we & !reg_error; + + assign fw_ov_sha3_start_wd = reg_wdata[3:0]; + assign fw_ov_wr_fifo_full_re = addr_hit[46] & reg_re & !reg_error; + + assign fw_ov_rd_data_re = addr_hit[48] & reg_re & !reg_error; + assign fw_ov_wr_data_we = addr_hit[49] & reg_we & !reg_error; + + assign fw_ov_wr_data_wd = reg_wdata[31:0]; + assign observe_fifo_thresh_we = addr_hit[50] & reg_we & !reg_error; + + assign observe_fifo_thresh_wd = reg_wdata[5:0]; + assign observe_fifo_depth_re = addr_hit[51] & reg_re & !reg_error; + assign debug_status_re = addr_hit[52] & reg_re & !reg_error; + assign recov_alert_sts_we = addr_hit[53] & reg_we & !reg_error; + + assign recov_alert_sts_fips_enable_field_alert_wd = reg_wdata[0]; + + assign recov_alert_sts_entropy_data_reg_en_field_alert_wd = reg_wdata[1]; + + assign recov_alert_sts_module_enable_field_alert_wd = reg_wdata[2]; + + assign recov_alert_sts_threshold_scope_field_alert_wd = reg_wdata[3]; + + assign recov_alert_sts_rng_bit_enable_field_alert_wd = reg_wdata[5]; + + assign recov_alert_sts_fw_ov_sha3_start_field_alert_wd = reg_wdata[7]; + + assign recov_alert_sts_fw_ov_mode_field_alert_wd = reg_wdata[8]; + + assign recov_alert_sts_fw_ov_entropy_insert_field_alert_wd = reg_wdata[9]; + + assign recov_alert_sts_es_route_field_alert_wd = reg_wdata[10]; + + assign recov_alert_sts_es_type_field_alert_wd = reg_wdata[11]; + + assign recov_alert_sts_es_main_sm_alert_wd = reg_wdata[12]; + + assign recov_alert_sts_es_bus_cmp_alert_wd = reg_wdata[13]; + + assign recov_alert_sts_es_thresh_cfg_alert_wd = reg_wdata[14]; + + assign recov_alert_sts_es_fw_ov_wr_alert_wd = reg_wdata[15]; + + assign recov_alert_sts_es_fw_ov_disable_alert_wd = reg_wdata[16]; + + assign recov_alert_sts_fips_flag_field_alert_wd = reg_wdata[17]; + + assign recov_alert_sts_rng_fips_field_alert_wd = reg_wdata[18]; + + assign recov_alert_sts_postht_entropy_drop_alert_wd = reg_wdata[31]; + assign err_code_test_we = addr_hit[55] & reg_we & !reg_error; + + assign err_code_test_wd = reg_wdata[4:0]; + + // Assign write-enables to checker logic vector. + always_comb begin + reg_we_check = '0; + reg_we_check[0] = intr_state_we; + reg_we_check[1] = intr_enable_we; + reg_we_check[2] = intr_test_we; + reg_we_check[3] = alert_test_we; + reg_we_check[4] = me_regwen_we; + reg_we_check[5] = sw_regupd_we; + reg_we_check[6] = 1'b0; + reg_we_check[7] = 1'b0; + reg_we_check[8] = module_enable_gated_we; + reg_we_check[9] = conf_gated_we; + reg_we_check[10] = entropy_control_gated_we; + reg_we_check[11] = 1'b0; + reg_we_check[12] = health_test_windows_gated_we; + reg_we_check[13] = repcnt_thresholds_gated_we; + reg_we_check[14] = repcnts_thresholds_gated_we; + reg_we_check[15] = adaptp_hi_thresholds_gated_we; + reg_we_check[16] = adaptp_lo_thresholds_gated_we; + reg_we_check[17] = bucket_thresholds_gated_we; + reg_we_check[18] = markov_hi_thresholds_gated_we; + reg_we_check[19] = markov_lo_thresholds_gated_we; + reg_we_check[20] = extht_hi_thresholds_gated_we; + reg_we_check[21] = extht_lo_thresholds_gated_we; + reg_we_check[22] = 1'b0; + reg_we_check[23] = 1'b0; + reg_we_check[24] = 1'b0; + reg_we_check[25] = 1'b0; + reg_we_check[26] = 1'b0; + reg_we_check[27] = 1'b0; + reg_we_check[28] = 1'b0; + reg_we_check[29] = 1'b0; + reg_we_check[30] = 1'b0; + reg_we_check[31] = 1'b0; + reg_we_check[32] = 1'b0; + reg_we_check[33] = 1'b0; + reg_we_check[34] = 1'b0; + reg_we_check[35] = 1'b0; + reg_we_check[36] = 1'b0; + reg_we_check[37] = 1'b0; + reg_we_check[38] = 1'b0; + reg_we_check[39] = 1'b0; + reg_we_check[40] = alert_threshold_gated_we; + reg_we_check[41] = 1'b0; + reg_we_check[42] = 1'b0; + reg_we_check[43] = 1'b0; + reg_we_check[44] = fw_ov_control_gated_we; + reg_we_check[45] = fw_ov_sha3_start_we; + reg_we_check[46] = 1'b0; + reg_we_check[47] = 1'b0; + reg_we_check[48] = 1'b0; + reg_we_check[49] = fw_ov_wr_data_we; + reg_we_check[50] = observe_fifo_thresh_gated_we; + reg_we_check[51] = 1'b0; + reg_we_check[52] = 1'b0; + reg_we_check[53] = recov_alert_sts_we; + reg_we_check[54] = 1'b0; + reg_we_check[55] = err_code_test_we; + reg_we_check[56] = 1'b0; + end + + // Read data return + always_comb begin + reg_rdata_next = '0; + unique case (addr_hit) + 57'h000000000000001: begin + reg_rdata_next[0] = intr_state_es_entropy_valid_qs; + reg_rdata_next[1] = intr_state_es_health_test_failed_qs; + reg_rdata_next[2] = intr_state_es_observe_fifo_ready_qs; + reg_rdata_next[3] = intr_state_es_fatal_err_qs; + end + + 57'h000000000000002: begin + reg_rdata_next[0] = intr_enable_es_entropy_valid_qs; + reg_rdata_next[1] = intr_enable_es_health_test_failed_qs; + reg_rdata_next[2] = intr_enable_es_observe_fifo_ready_qs; + reg_rdata_next[3] = intr_enable_es_fatal_err_qs; + end + + 57'h000000000000004: begin + reg_rdata_next[0] = '0; + reg_rdata_next[1] = '0; + reg_rdata_next[2] = '0; + reg_rdata_next[3] = '0; + end + + 57'h000000000000008: begin + reg_rdata_next[0] = '0; + reg_rdata_next[1] = '0; + end + + 57'h000000000000010: begin + reg_rdata_next[0] = me_regwen_qs; + end + + 57'h000000000000020: begin + reg_rdata_next[0] = sw_regupd_qs; + end + + 57'h000000000000040: begin + reg_rdata_next[0] = regwen_qs; + end + + 57'h000000000000080: begin + reg_rdata_next[7:0] = rev_abi_revision_qs; + reg_rdata_next[15:8] = rev_hw_revision_qs; + reg_rdata_next[23:16] = rev_chip_type_qs; + end + + 57'h000000000000100: begin + reg_rdata_next[3:0] = module_enable_qs; + end + + 57'h000000000000200: begin + reg_rdata_next[3:0] = conf_fips_enable_qs; + reg_rdata_next[7:4] = conf_fips_flag_qs; + reg_rdata_next[11:8] = conf_rng_fips_qs; + reg_rdata_next[15:12] = conf_rng_bit_enable_qs; + reg_rdata_next[17:16] = conf_rng_bit_sel_qs; + reg_rdata_next[21:18] = conf_threshold_scope_qs; + reg_rdata_next[25:22] = conf_entropy_data_reg_enable_qs; + end + + 57'h000000000000400: begin + reg_rdata_next[3:0] = entropy_control_es_route_qs; + reg_rdata_next[7:4] = entropy_control_es_type_qs; + end + + 57'h000000000000800: begin + reg_rdata_next[31:0] = entropy_data_qs; + end + + 57'h000000000001000: begin + reg_rdata_next[15:0] = health_test_windows_fips_window_qs; + reg_rdata_next[31:16] = health_test_windows_bypass_window_qs; + end + + 57'h000000000002000: begin + reg_rdata_next[15:0] = repcnt_thresholds_fips_thresh_qs; + reg_rdata_next[31:16] = repcnt_thresholds_bypass_thresh_qs; + end + + 57'h000000000004000: begin + reg_rdata_next[15:0] = repcnts_thresholds_fips_thresh_qs; + reg_rdata_next[31:16] = repcnts_thresholds_bypass_thresh_qs; + end + + 57'h000000000008000: begin + reg_rdata_next[15:0] = adaptp_hi_thresholds_fips_thresh_qs; + reg_rdata_next[31:16] = adaptp_hi_thresholds_bypass_thresh_qs; + end + + 57'h000000000010000: begin + reg_rdata_next[15:0] = adaptp_lo_thresholds_fips_thresh_qs; + reg_rdata_next[31:16] = adaptp_lo_thresholds_bypass_thresh_qs; + end + + 57'h000000000020000: begin + reg_rdata_next[15:0] = bucket_thresholds_fips_thresh_qs; + reg_rdata_next[31:16] = bucket_thresholds_bypass_thresh_qs; + end + + 57'h000000000040000: begin + reg_rdata_next[15:0] = markov_hi_thresholds_fips_thresh_qs; + reg_rdata_next[31:16] = markov_hi_thresholds_bypass_thresh_qs; + end + + 57'h000000000080000: begin + reg_rdata_next[15:0] = markov_lo_thresholds_fips_thresh_qs; + reg_rdata_next[31:16] = markov_lo_thresholds_bypass_thresh_qs; + end + + 57'h000000000100000: begin + reg_rdata_next[15:0] = extht_hi_thresholds_fips_thresh_qs; + reg_rdata_next[31:16] = extht_hi_thresholds_bypass_thresh_qs; + end + + 57'h000000000200000: begin + reg_rdata_next[15:0] = extht_lo_thresholds_fips_thresh_qs; + reg_rdata_next[31:16] = extht_lo_thresholds_bypass_thresh_qs; + end + + 57'h000000000400000: begin + reg_rdata_next[15:0] = repcnt_hi_watermarks_fips_watermark_qs; + reg_rdata_next[31:16] = repcnt_hi_watermarks_bypass_watermark_qs; + end + + 57'h000000000800000: begin + reg_rdata_next[15:0] = repcnts_hi_watermarks_fips_watermark_qs; + reg_rdata_next[31:16] = repcnts_hi_watermarks_bypass_watermark_qs; + end + + 57'h000000001000000: begin + reg_rdata_next[15:0] = adaptp_hi_watermarks_fips_watermark_qs; + reg_rdata_next[31:16] = adaptp_hi_watermarks_bypass_watermark_qs; + end + + 57'h000000002000000: begin + reg_rdata_next[15:0] = adaptp_lo_watermarks_fips_watermark_qs; + reg_rdata_next[31:16] = adaptp_lo_watermarks_bypass_watermark_qs; + end + + 57'h000000004000000: begin + reg_rdata_next[15:0] = extht_hi_watermarks_fips_watermark_qs; + reg_rdata_next[31:16] = extht_hi_watermarks_bypass_watermark_qs; + end + + 57'h000000008000000: begin + reg_rdata_next[15:0] = extht_lo_watermarks_fips_watermark_qs; + reg_rdata_next[31:16] = extht_lo_watermarks_bypass_watermark_qs; + end + + 57'h000000010000000: begin + reg_rdata_next[15:0] = bucket_hi_watermarks_fips_watermark_qs; + reg_rdata_next[31:16] = bucket_hi_watermarks_bypass_watermark_qs; + end + + 57'h000000020000000: begin + reg_rdata_next[15:0] = markov_hi_watermarks_fips_watermark_qs; + reg_rdata_next[31:16] = markov_hi_watermarks_bypass_watermark_qs; + end + + 57'h000000040000000: begin + reg_rdata_next[15:0] = markov_lo_watermarks_fips_watermark_qs; + reg_rdata_next[31:16] = markov_lo_watermarks_bypass_watermark_qs; + end + + 57'h000000080000000: begin + reg_rdata_next[31:0] = repcnt_total_fails_qs; + end + + 57'h000000100000000: begin + reg_rdata_next[31:0] = repcnts_total_fails_qs; + end + + 57'h000000200000000: begin + reg_rdata_next[31:0] = adaptp_hi_total_fails_qs; + end + + 57'h000000400000000: begin + reg_rdata_next[31:0] = adaptp_lo_total_fails_qs; + end + + 57'h000000800000000: begin + reg_rdata_next[31:0] = bucket_total_fails_qs; + end + + 57'h000001000000000: begin + reg_rdata_next[31:0] = markov_hi_total_fails_qs; + end + + 57'h000002000000000: begin + reg_rdata_next[31:0] = markov_lo_total_fails_qs; + end + + 57'h000004000000000: begin + reg_rdata_next[31:0] = extht_hi_total_fails_qs; + end + + 57'h000008000000000: begin + reg_rdata_next[31:0] = extht_lo_total_fails_qs; + end + + 57'h000010000000000: begin + reg_rdata_next[15:0] = alert_threshold_alert_threshold_qs; + reg_rdata_next[31:16] = alert_threshold_alert_threshold_inv_qs; + end + + 57'h000020000000000: begin + reg_rdata_next[15:0] = alert_summary_fail_counts_qs; + end + + 57'h000040000000000: begin + reg_rdata_next[7:4] = alert_fail_counts_repcnt_fail_count_qs; + reg_rdata_next[11:8] = alert_fail_counts_adaptp_hi_fail_count_qs; + reg_rdata_next[15:12] = alert_fail_counts_adaptp_lo_fail_count_qs; + reg_rdata_next[19:16] = alert_fail_counts_bucket_fail_count_qs; + reg_rdata_next[23:20] = alert_fail_counts_markov_hi_fail_count_qs; + reg_rdata_next[27:24] = alert_fail_counts_markov_lo_fail_count_qs; + reg_rdata_next[31:28] = alert_fail_counts_repcnts_fail_count_qs; + end + + 57'h000080000000000: begin + reg_rdata_next[3:0] = extht_fail_counts_extht_hi_fail_count_qs; + reg_rdata_next[7:4] = extht_fail_counts_extht_lo_fail_count_qs; + end + + 57'h000100000000000: begin + reg_rdata_next[3:0] = fw_ov_control_fw_ov_mode_qs; + reg_rdata_next[7:4] = fw_ov_control_fw_ov_entropy_insert_qs; + end + + 57'h000200000000000: begin + reg_rdata_next[3:0] = fw_ov_sha3_start_qs; + end + + 57'h000400000000000: begin + reg_rdata_next[0] = fw_ov_wr_fifo_full_qs; + end + + 57'h000800000000000: begin + reg_rdata_next[0] = fw_ov_rd_fifo_overflow_qs; + end + + 57'h001000000000000: begin + reg_rdata_next[31:0] = fw_ov_rd_data_qs; + end + + 57'h002000000000000: begin + reg_rdata_next[31:0] = '0; + end + + 57'h004000000000000: begin + reg_rdata_next[5:0] = observe_fifo_thresh_qs; + end + + 57'h008000000000000: begin + reg_rdata_next[5:0] = observe_fifo_depth_qs; + end + + 57'h010000000000000: begin + reg_rdata_next[1:0] = debug_status_entropy_fifo_depth_qs; + reg_rdata_next[5:3] = debug_status_sha3_fsm_qs; + reg_rdata_next[6] = debug_status_sha3_block_pr_qs; + reg_rdata_next[7] = debug_status_sha3_squeezing_qs; + reg_rdata_next[8] = debug_status_sha3_absorbed_qs; + reg_rdata_next[9] = debug_status_sha3_err_qs; + reg_rdata_next[16] = debug_status_main_sm_idle_qs; + reg_rdata_next[17] = debug_status_main_sm_boot_done_qs; + end + + 57'h020000000000000: begin + reg_rdata_next[0] = recov_alert_sts_fips_enable_field_alert_qs; + reg_rdata_next[1] = recov_alert_sts_entropy_data_reg_en_field_alert_qs; + reg_rdata_next[2] = recov_alert_sts_module_enable_field_alert_qs; + reg_rdata_next[3] = recov_alert_sts_threshold_scope_field_alert_qs; + reg_rdata_next[5] = recov_alert_sts_rng_bit_enable_field_alert_qs; + reg_rdata_next[7] = recov_alert_sts_fw_ov_sha3_start_field_alert_qs; + reg_rdata_next[8] = recov_alert_sts_fw_ov_mode_field_alert_qs; + reg_rdata_next[9] = recov_alert_sts_fw_ov_entropy_insert_field_alert_qs; + reg_rdata_next[10] = recov_alert_sts_es_route_field_alert_qs; + reg_rdata_next[11] = recov_alert_sts_es_type_field_alert_qs; + reg_rdata_next[12] = recov_alert_sts_es_main_sm_alert_qs; + reg_rdata_next[13] = recov_alert_sts_es_bus_cmp_alert_qs; + reg_rdata_next[14] = recov_alert_sts_es_thresh_cfg_alert_qs; + reg_rdata_next[15] = recov_alert_sts_es_fw_ov_wr_alert_qs; + reg_rdata_next[16] = recov_alert_sts_es_fw_ov_disable_alert_qs; + reg_rdata_next[17] = recov_alert_sts_fips_flag_field_alert_qs; + reg_rdata_next[18] = recov_alert_sts_rng_fips_field_alert_qs; + reg_rdata_next[31] = recov_alert_sts_postht_entropy_drop_alert_qs; + end + + 57'h040000000000000: begin + reg_rdata_next[0] = err_code_sfifo_esrng_err_qs; + reg_rdata_next[1] = err_code_sfifo_distr_err_qs; + reg_rdata_next[2] = err_code_sfifo_observe_err_qs; + reg_rdata_next[3] = err_code_sfifo_esfinal_err_qs; + reg_rdata_next[20] = err_code_es_ack_sm_err_qs; + reg_rdata_next[21] = err_code_es_main_sm_err_qs; + reg_rdata_next[22] = err_code_es_cntr_err_qs; + reg_rdata_next[23] = err_code_sha3_state_err_qs; + reg_rdata_next[24] = err_code_sha3_rst_storage_err_qs; + reg_rdata_next[28] = err_code_fifo_write_err_qs; + reg_rdata_next[29] = err_code_fifo_read_err_qs; + reg_rdata_next[30] = err_code_fifo_state_err_qs; + end + + 57'h080000000000000: begin + reg_rdata_next[4:0] = err_code_test_qs; + end + + 57'h100000000000000: begin + reg_rdata_next[8:0] = main_sm_state_qs; + end + endcase + end + + // shadow busy + logic shadow_busy; + assign shadow_busy = 1'b0; + + // register busy + assign reg_busy = shadow_busy; + + // Unused signal tieoff + + // wdata / byte enable are not always fully used + // add a blanket unused statement to handle lint waivers + logic unused_wdata; + logic unused_be; + assign unused_wdata = ^reg_wdata; + assign unused_be = ^reg_be; + + // Assertions for Register Interface + `CALIPTRA_ASSERT_PULSE(wePulse, reg_we, clk_i, !rst_ni) + `CALIPTRA_ASSERT_PULSE(rePulse, reg_re, clk_i, !rst_ni) + + `CALIPTRA_ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> hreadyout_o, clk_i, !rst_ni) + + `CALIPTRA_ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit), clk_i, !rst_ni) + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/entropy_src_repcnt_ht.sv b/designs/Caliptra/src/caliptra-rtl/entropy_src_repcnt_ht.sv new file mode 100644 index 0000000..c10bd69 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/entropy_src_repcnt_ht.sv @@ -0,0 +1,132 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Description: entropy_src repetitive count health test module +// + +module entropy_src_repcnt_ht #( + parameter int RegWidth = 16, + parameter int RngBusWidth = 4 +) ( + input logic clk_i, + input logic rst_ni, + + // ins req interface + input logic [RngBusWidth-1:0] entropy_bit_i, + input logic entropy_bit_vld_i, + input logic rng_bit_en_i, + input logic [1:0] rng_bit_sel_i, + input logic clear_i, + input logic active_i, + input logic [RegWidth-1:0] thresh_i, + output logic [RegWidth-1:0] test_cnt_o, + output logic test_fail_pulse_o, + output logic count_err_o +); + + // signals + logic [RngBusWidth-1:0] samples_match_pulse; + logic [RngBusWidth-1:0] samples_no_match_pulse; + logic [RngBusWidth-1:0] rep_cnt_fail; + logic rng_bit_cnt_fail; + logic [RngBusWidth-1:0][RegWidth-1:0] rep_cntr; + logic [RngBusWidth-1:0] rep_cntr_err; + logic [RegWidth-1:0] cntr_max; + logic [RegWidth-1:0] rng_bit_cnt; + logic fail_sampled; + + // flops + logic [RngBusWidth-1:0] prev_sample_q, prev_sample_d; + logic fail_sample_mask_d, fail_sample_mask_q; + + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + prev_sample_q <= '0; + fail_sample_mask_q <= '0; + end else begin + prev_sample_q <= prev_sample_d; + fail_sample_mask_q <= fail_sample_mask_d; + end + end + + // Repetitive Count Test + // + // Test operation + // This test will look for catastrophic stuck bit failures. The rep_cntr + // uses one as the starting value, just as the NIST algorithm does. + + + for (genvar sh = 0; sh < RngBusWidth; sh = sh+1) begin : gen_cntrs + + + // NIST A sample + assign prev_sample_d[sh] = (!active_i || clear_i) ? '0 : + entropy_bit_vld_i ? entropy_bit_i[sh] : + prev_sample_q[sh]; + + assign samples_match_pulse[sh] = entropy_bit_vld_i && + (prev_sample_q[sh] == entropy_bit_i[sh]); + assign samples_no_match_pulse[sh] = entropy_bit_vld_i && + (prev_sample_q[sh] != entropy_bit_i[sh]); + + // NIST B counter + // SEC_CM: CTR.REDUN + caliptra_prim_count #( + .Width(RegWidth) + ) u_caliptra_prim_count_rep_cntr ( + .clk_i, + .rst_ni, + .clr_i(1'b0), + .set_i(!active_i || clear_i || samples_no_match_pulse[sh]), + .set_cnt_i(RegWidth'(1)), + .incr_en_i(samples_match_pulse[sh]), + .decr_en_i(1'b0), + .step_i(RegWidth'(1)), + .commit_i(1'b1), + .cnt_o(rep_cntr[sh]), + .cnt_after_commit_o(), + .err_o(rep_cntr_err[sh]) + ); + + assign rep_cnt_fail[sh] = (rep_cntr[sh] >= thresh_i); + + end : gen_cntrs + + caliptra_prim_max_tree #( + .NumSrc(RngBusWidth), + .Width(RegWidth) + ) u_caliptra_prim_max_tree_rep_cntr_max ( + .clk_i, + .rst_ni, + .values_i (rep_cntr), + .valid_i ({RngBusWidth{1'b1}}), + .max_value_o(cntr_max), + .max_idx_o (), + .max_valid_o() + ); + + assign rng_bit_cnt = (rng_bit_sel_i == 2'h0) ? rep_cntr[0] : + (rng_bit_sel_i == 2'h1) ? rep_cntr[1] : + (rng_bit_sel_i == 2'h2) ? rep_cntr[2] : + rep_cntr[3]; + + assign rng_bit_cnt_fail = (rng_bit_sel_i == 2'h0) ? rep_cnt_fail[0] : + (rng_bit_sel_i == 2'h1) ? rep_cnt_fail[1] : + (rng_bit_sel_i == 2'h2) ? rep_cnt_fail[2] : + rep_cnt_fail[3]; + + // For the purposes of failure pulse generation, we want to sample + // the test output for only one cycle and do it immediately after + // the counter has been updated. + assign fail_sample_mask_d = entropy_bit_vld_i; + assign fail_sampled = fail_sample_mask_q && (rng_bit_en_i ? rng_bit_cnt_fail : + |rep_cnt_fail); + + assign test_fail_pulse_o = active_i & fail_sampled; + + assign test_cnt_o = rng_bit_en_i ? rng_bit_cnt : cntr_max; + assign count_err_o = (|rep_cntr_err); + + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/entropy_src_repcnts_ht.sv b/designs/Caliptra/src/caliptra-rtl/entropy_src_repcnts_ht.sv new file mode 100644 index 0000000..01e943a --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/entropy_src_repcnts_ht.sv @@ -0,0 +1,98 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Description: entropy_src repetitive count symbol based health test module +// + +module entropy_src_repcnts_ht #( + parameter int RegWidth = 16, + parameter int RngBusWidth = 4 +) ( + input logic clk_i, + input logic rst_ni, + + // ins req interface + input logic [RngBusWidth-1:0] entropy_bit_i, + input logic entropy_bit_vld_i, + input logic clear_i, + input logic active_i, + input logic [RegWidth-1:0] thresh_i, + output logic [RegWidth-1:0] test_cnt_o, + output logic test_fail_pulse_o, + output logic count_err_o +); + + // signals + logic samples_match_pulse; + logic samples_no_match_pulse; + logic rep_cnt_fail; + logic [RegWidth-1:0] rep_cntr; + logic rep_cntr_err; + logic fail_sampled; + + // flops + logic [RngBusWidth-1:0] prev_sample_q, prev_sample_d; + logic fail_sample_mask_d, fail_sample_mask_q; + + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + prev_sample_q <= '0; + fail_sample_mask_q <= '0; + end else begin + prev_sample_q <= prev_sample_d; + fail_sample_mask_q <= fail_sample_mask_d; + end + end + + // Repetitive Count Test for symbols + // + // Test operation + // This test will look for catastrophic stuck bit failures. The rep_cntr + // uses one as the starting value, just as the NIST algorithm does. + + + // NIST A sample + assign prev_sample_d = (!active_i || clear_i) ? '0 : + entropy_bit_vld_i ? entropy_bit_i : + prev_sample_q; + + assign samples_match_pulse = entropy_bit_vld_i && + (prev_sample_q == entropy_bit_i); + assign samples_no_match_pulse = entropy_bit_vld_i && + (prev_sample_q != entropy_bit_i); + + // NIST B counter + // SEC_CM: CTR.REDUN + caliptra_prim_count #( + .Width(RegWidth) + ) u_caliptra_prim_count_rep_cntr ( + .clk_i, + .rst_ni, + .clr_i(1'b0), + .set_i(!active_i || clear_i || samples_no_match_pulse), + .set_cnt_i(RegWidth'(1)), + .incr_en_i(samples_match_pulse), + .decr_en_i(1'b0), + .step_i(RegWidth'(1)), + .commit_i(1'b1), + .cnt_o(rep_cntr), + .cnt_after_commit_o(), + .err_o(rep_cntr_err) + ); + + assign rep_cnt_fail = (rep_cntr >= thresh_i); + + // For the purposes of failure pulse generation, we want to sample + // the test output for only one cycle and do it immediately after + // the counter has been updated. + assign fail_sample_mask_d = entropy_bit_vld_i; + assign fail_sampled = rep_cnt_fail & fail_sample_mask_q; + + assign test_fail_pulse_o = active_i & fail_sampled; + + assign test_cnt_o = rep_cntr; + assign count_err_o = (|rep_cntr_err); + + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/entropy_src_watermark_reg.sv b/designs/Caliptra/src/caliptra-rtl/entropy_src_watermark_reg.sv new file mode 100644 index 0000000..f3c18e4 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/entropy_src_watermark_reg.sv @@ -0,0 +1,69 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Description: entropy_src high or how watermark register module +// + +module entropy_src_watermark_reg #( + parameter int RegWidth = 16, + parameter bit HighWatermark = 1 +) ( + input logic clk_i, + input logic rst_ni, + + // functional interface + input logic clear_i, + input logic event_i, + input logic [RegWidth-1:0] value_i, + output logic [RegWidth-1:0] value_o +); + + // signals + logic [RegWidth-1:0] event_cntr_change; + logic [RegWidth-1:0] reg_reset; + + // flops + logic [RegWidth-1:0] event_cntr_q, event_cntr_d; + + // Set mode of this counter to be either a high or low watermark + if (HighWatermark) begin : gen_hi_wm + + assign reg_reset = {RegWidth{1'b0}}; + + assign event_cntr_change = (value_i > event_cntr_q) ? (value_i) : event_cntr_q; + + assign event_cntr_d = clear_i ? reg_reset : + event_i ? event_cntr_change : + event_cntr_q; + + always_ff @(posedge clk_i or negedge rst_ni) + if (!rst_ni) begin + event_cntr_q <= {RegWidth{1'b0}}; + end else begin + event_cntr_q <= event_cntr_d; + end + + end else begin : gen_lo_wm + + assign reg_reset = {RegWidth{1'b1}}; + + assign event_cntr_change = (value_i < event_cntr_q) ? (value_i) : event_cntr_q; + + assign event_cntr_d = clear_i ? reg_reset : + event_i ? event_cntr_change : + event_cntr_q; + + always_ff @(posedge clk_i or negedge rst_ni) + if (!rst_ni) begin + event_cntr_q <= {RegWidth{1'b1}}; + end else begin + event_cntr_q <= event_cntr_d; + end + + end + + // drive output + assign value_o = event_cntr_q; + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/hmac.sv b/designs/Caliptra/src/caliptra-rtl/hmac.sv new file mode 100644 index 0000000..1306f80 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/hmac.sv @@ -0,0 +1,563 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +// +//====================================================================== +// +// hmac.sv +// ------ +// HMAC-512/384 top-level wrapper with 32 bit data access. +// +//====================================================================== +//`include "kv_defines.svh" +`include "kv_macros.svh" + +module hmac + import hmac_param_pkg::*; + import hmac_reg_pkg::*; + import kv_defines_pkg::*; + #( + ADDR_WIDTH = 32, + DATA_WIDTH = 32 + )( + // Clock and reset. + input wire clk, + input wire reset_n, + input wire cptra_pwrgood, + + //csr key + input logic [`CLP_CSR_HMAC_KEY_DWORDS-1:0][31:0] cptra_csr_hmac_key, + + // Control. + input wire cs, + input wire we, + + // Data ports. + input wire [ADDR_WIDTH - 1 : 0] address, + input wire [DATA_WIDTH - 1 : 0] write_data, + output wire [DATA_WIDTH - 1 : 0] read_data, + + // KV interface + output kv_read_t [1:0] kv_read, + output kv_write_t kv_write, + input kv_rd_resp_t [1:0] kv_rd_resp, + input kv_wr_resp_t kv_wr_resp, + + output logic busy_o, + + output wire error_intr, + output wire notif_intr, + input logic ocp_lock_in_progress, + input logic debugUnlock_or_scan_mode_switch + ); + + //---------------------------------------------------------------- + // Registers including update variables and write enable. + //---------------------------------------------------------------- + reg init_reg; + reg init_new; + + reg next_reg; + reg next_new; + + reg mode_reg; + + reg ready_reg; + reg tag_valid_reg; + + localparam BLOCK_SIZE = 1024; + localparam KEY_SIZE = 512; + localparam TAG_SIZE = KEY_SIZE; + localparam LFSR_SEED_SIZE = 384; + localparam BLOCK_NUM_DWORDS = BLOCK_SIZE / DATA_WIDTH; + localparam KEY_NUM_DWORDS = KEY_SIZE / DATA_WIDTH; + localparam TAG_NUM_DWORDS = TAG_SIZE / DATA_WIDTH; + localparam SEED_NUM_DWORDS = ((LFSR_SEED_SIZE - 1) / DATA_WIDTH) + 1; + + reg [KEY_NUM_DWORDS - 1 : 0][DATA_WIDTH - 1 : 0] key_reg; + reg [BLOCK_NUM_DWORDS - 1 : 0][DATA_WIDTH - 1 : 0] block_reg; + reg [SEED_NUM_DWORDS- 1 : 0][DATA_WIDTH - 1 : 0] lfsr_seed_reg; + + logic zeroize_reg; + + //---------------------------------------------------------------- + // Wires. + //---------------------------------------------------------------- + wire [KEY_SIZE-1 : 0] core_key; + wire [BLOCK_SIZE-1 : 0] core_block; + wire core_ready; + wire [TAG_SIZE-1 : 0] core_tag; + wire core_tag_valid; + wire [LFSR_SEED_SIZE-1 : 0] core_lfsr_seed; + reg [TAG_NUM_DWORDS - 1 : 0][DATA_WIDTH - 1 : 0] tag_reg; + reg [TAG_NUM_DWORDS - 1 : 0][DATA_WIDTH - 1 : 0] kv_reg; + + reg [TAG_NUM_DWORDS - 1 : 0][DATA_WIDTH - 1 : 0] get_mask; + + hmac_reg__in_t hwif_in; + hmac_reg__out_t hwif_out; + + //interface with kv client + logic kv_key_write_en; + logic [3:0] kv_key_write_offset; + logic [31:0] kv_key_write_data; + logic kv_block_write_en; + logic [4:0] kv_block_write_offset; + logic [31:0] kv_block_write_data; + //KV Read Data Present + logic kv_key_data_present, kv_key_data_present_set; + logic [BLOCK_NUM_DWORDS-1:0] block_reg_lock, block_reg_lock_nxt; + logic kv_block_data_present, kv_block_data_present_set; + logic kv_data_present, kv_data_present_reset; + + logic dest_keyvault; + kv_error_code_e kv_key_error, kv_block_error, kv_write_error; + logic kv_key_ready, kv_key_done; + logic kv_block_ready, kv_block_done; + logic kv_write_ready, kv_write_done; + + kv_read_ctrl_reg_t kv_key_read_ctrl_reg; + kv_read_ctrl_reg_t kv_block_read_ctrl_reg; + kv_write_ctrl_reg_t kv_write_ctrl_reg; + kv_read_filter_metrics_t kv_key_read_metrics; + kv_read_filter_metrics_t kv_block_read_metrics; + kv_write_filter_metrics_t kv_write_metrics; + logic core_tag_we; + + logic key_zero_error, key_zero_error_reg, key_zero_error_edge; + logic key_mode_error, key_mode_error_reg, key_mode_error_edge; + + logic error_flag; + logic error_flag_reg; + logic error_flag_edge; + //---------------------------------------------------------------- + // Concurrent connectivity for ports etc. + //---------------------------------------------------------------- + assign core_block = {block_reg[00], block_reg[01], block_reg[02], block_reg[03], + block_reg[04], block_reg[05], block_reg[06], block_reg[07], + block_reg[08], block_reg[09], block_reg[10], block_reg[11], + block_reg[12], block_reg[13], block_reg[14], block_reg[15], + block_reg[16], block_reg[17], block_reg[18], block_reg[19], + block_reg[20], block_reg[21], block_reg[22], block_reg[23], + block_reg[24], block_reg[25], block_reg[26], block_reg[27], + block_reg[28], block_reg[29], block_reg[30], block_reg[31]}; + + assign core_key = {key_reg[00], key_reg[01], key_reg[02], key_reg[03], key_reg[04], key_reg[05], + key_reg[06], key_reg[07], key_reg[08], key_reg[09], key_reg[10], key_reg[11], + key_reg[12], key_reg[13], key_reg[14], key_reg[15]} & get_mask; + + assign core_lfsr_seed = {lfsr_seed_reg[00], lfsr_seed_reg[01], lfsr_seed_reg[02], lfsr_seed_reg[03], lfsr_seed_reg[04], lfsr_seed_reg[05], + lfsr_seed_reg[06], lfsr_seed_reg[07], lfsr_seed_reg[08], lfsr_seed_reg[09], lfsr_seed_reg[10], lfsr_seed_reg[11]}; + + //rising edge detect on core tag valid + assign core_tag_we = (core_tag_valid & ~tag_valid_reg) & ~error_flag_reg; + + //---------------------------------------------------------------- + // core instantiation. + //---------------------------------------------------------------- + hmac_core core( + .clk(clk), + .reset_n(reset_n), + .zeroize(zeroize_reg), + + .init_cmd(init_reg), + .next_cmd(next_reg), + .mode_cmd(mode_reg), + + .lfsr_seed(core_lfsr_seed), + + .key(core_key), + + .block_msg(core_block), + + .ready(core_ready), + .tag(core_tag), + .tag_valid(core_tag_valid) + ); + + + //---------------------------------------------------------------- + // reg_update + // + // Update functionality for all registers in the core. + // All registers are positive edge triggered with asynchronous + // active low reset. All registers have write enable. + //---------------------------------------------------------------- + always @ (posedge clk or negedge reset_n) + begin : reg_update + integer ii; + + if (!reset_n) + begin + kv_reg <= '0; + tag_reg <= '0; + tag_valid_reg <= '0; + ready_reg <= '0; + block_reg_lock <= '0; + kv_key_data_present <= '0; + kv_block_data_present <= '0; + end + else if (zeroize_reg) + begin + kv_reg <= '0; + tag_reg <= '0; + tag_valid_reg <= '0; + ready_reg <= '0; + block_reg_lock <= '0; + kv_key_data_present <= '0; + kv_block_data_present <= '0; + end + else + begin + tag_valid_reg <= core_tag_valid & ~error_flag_reg; + ready_reg <= core_ready; + + //write to sw register + if (core_tag_we & ~(dest_keyvault | kv_data_present)) + tag_reg <= core_tag & get_mask; + if (core_tag_we & (dest_keyvault | kv_data_present)) + kv_reg <= core_tag & get_mask; + + block_reg_lock <= block_reg_lock_nxt; + kv_key_data_present <= kv_key_data_present_set ? '1 : + kv_data_present_reset ? '0 : kv_key_data_present; + kv_block_data_present <= kv_block_data_present_set ? '1 : + kv_data_present_reset ? '0 : kv_block_data_present; + end + end // reg_update + +//HMAC register hardware interfaces +always_comb begin + //drive resets to register block + hwif_in.error_reset_b = cptra_pwrgood; + hwif_in.reset_b = reset_n; + //drive hardware writeable registers from hmac core + hwif_in.HMAC512_NAME[0].NAME.next = HMAC_CORE_NAME[31:0]; + hwif_in.HMAC512_NAME[1].NAME.next = HMAC_CORE_NAME[63:32]; + hwif_in.HMAC512_VERSION[0].VERSION.next = HMAC_CORE_VERSION[31:0]; + hwif_in.HMAC512_VERSION[1].VERSION.next = HMAC_CORE_VERSION[63:32]; + //Only allow setting CSR MODE when ready is set + hwif_in.HMAC512_CTRL.CSR_MODE.swwe = ready_reg; + hwif_in.HMAC512_CTRL.INIT.swwe = ready_reg; + hwif_in.HMAC512_CTRL.NEXT.swwe = ready_reg; + hwif_in.HMAC512_CTRL.MODE.swwe = ready_reg; + + //assign hardware readable registers to drive hmac core + //mask the command until kv clients are idle + init_reg = hwif_out.HMAC512_CTRL.INIT.value & kv_key_ready & kv_block_ready; + next_reg = hwif_out.HMAC512_CTRL.NEXT.value & kv_key_ready & kv_block_ready; + zeroize_reg = hwif_out.HMAC512_CTRL.ZEROIZE.value || debugUnlock_or_scan_mode_switch; + mode_reg = hwif_out.HMAC512_CTRL.MODE.value; + + //drive hardware writeable registers from hmac core + hwif_in.HMAC512_STATUS.READY.next = ready_reg; + hwif_in.HMAC512_STATUS.VALID.next = tag_valid_reg; + for (int dword=0; dword < TAG_NUM_DWORDS; dword++) begin + hwif_in.HMAC512_TAG[dword].TAG.next = tag_reg[(TAG_NUM_DWORDS - 1)-dword]; + hwif_in.HMAC512_TAG[dword].TAG.hwclr = zeroize_reg; + end + //drive hardware writable registers from key vault + for (int dword=0; dword < BLOCK_NUM_DWORDS; dword++)begin + hwif_in.HMAC512_BLOCK[dword].BLOCK.we = (kv_block_write_en & (kv_block_write_offset == dword)) & !(zeroize_reg | kv_data_present_reset); + hwif_in.HMAC512_BLOCK[dword].BLOCK.next = kv_block_write_data; + hwif_in.HMAC512_BLOCK[dword].BLOCK.hwclr = zeroize_reg | kv_data_present_reset | (kv_block_error == KV_READ_FAIL); + hwif_in.HMAC512_BLOCK[dword].BLOCK.swwel = block_reg_lock[dword]; + end + for (int dword=0; dword < KEY_NUM_DWORDS; dword++)begin + hwif_in.HMAC512_KEY[dword].KEY.we = (kv_key_write_en & (kv_key_write_offset == dword)) & !(zeroize_reg | kv_data_present_reset); + hwif_in.HMAC512_KEY[dword].KEY.next = kv_key_write_data; + hwif_in.HMAC512_KEY[dword].KEY.hwclr = zeroize_reg | kv_data_present_reset | (kv_key_error == KV_READ_FAIL); + hwif_in.HMAC512_KEY[dword].KEY.swwel = kv_key_data_present; + end + //set ready when keyvault isn't busy + hwif_in.HMAC512_KV_RD_KEY_STATUS.READY.next = kv_key_ready; + hwif_in.HMAC512_KV_RD_BLOCK_STATUS.READY.next = kv_block_ready; + hwif_in.HMAC512_KV_WR_STATUS.READY.next = kv_write_ready; + //set error code + hwif_in.HMAC512_KV_RD_KEY_STATUS.ERROR.next = kv_key_error; + hwif_in.HMAC512_KV_RD_BLOCK_STATUS.ERROR.next = kv_block_error; + hwif_in.HMAC512_KV_WR_STATUS.ERROR.next = kv_write_error; + //set valid when fsm is done + hwif_in.HMAC512_KV_RD_KEY_STATUS.VALID.hwset = kv_key_done; + hwif_in.HMAC512_KV_RD_BLOCK_STATUS.VALID.hwset = kv_block_done; + hwif_in.HMAC512_KV_WR_STATUS.VALID.hwset = kv_write_done; + //clear valid when new request is made + hwif_in.HMAC512_KV_RD_KEY_STATUS.VALID.hwclr = kv_key_read_ctrl_reg.read_en; + hwif_in.HMAC512_KV_RD_BLOCK_STATUS.VALID.hwclr = kv_block_read_ctrl_reg.read_en; + hwif_in.HMAC512_KV_WR_STATUS.VALID.hwclr = kv_write_ctrl_reg.write_en; + //clear enable when busy + hwif_in.HMAC512_KV_RD_KEY_CTRL.read_en.hwclr = ~kv_key_ready; + hwif_in.HMAC512_KV_RD_BLOCK_CTRL.read_en.hwclr = ~kv_block_ready; + hwif_in.HMAC512_KV_WR_CTRL.write_en.hwclr = ~kv_write_ready; + //assign hardware readable registers to drive hmac core + for (int dword=0; dword < KEY_NUM_DWORDS; dword++) begin + key_reg[dword] = hwif_out.HMAC512_CTRL.CSR_MODE.value ? cptra_csr_hmac_key[dword] : hwif_out.HMAC512_KEY[dword].KEY.value; + end + for (int dword=0; dword < BLOCK_NUM_DWORDS; dword++)begin + block_reg[dword] = hwif_out.HMAC512_BLOCK[dword].BLOCK.value; + end + + for (int dword=0; dword < SEED_NUM_DWORDS; dword++)begin + lfsr_seed_reg[dword] = hwif_out.HMAC512_LFSR_SEED[dword].LFSR_SEED.value; + end +end + +always_comb begin + unique case (mode_reg) + 1'b0 : get_mask = {{12{32'hffffffff}}, {4{32'h00000000}}}; //HMAC384 + default : get_mask = {16{32'hffffffff}}; //HMAC512 + endcase +end + +//set the lock for the part of the block being written by KV logic +//release the lock once init has been seen +always_comb begin + for (int dword=0; dword< BLOCK_NUM_DWORDS; dword++) begin + if (init_reg | next_reg) begin + block_reg_lock_nxt[dword] = '0; + end + else begin + block_reg_lock_nxt[dword] = (kv_block_write_en & (kv_block_write_offset == dword)) ? '1 : block_reg_lock[dword]; + end + end +end + +// Software write-enables to prevent KV reg manipulation mid-operation +always_comb hwif_in.HMAC512_KV_RD_KEY_CTRL.read_en.swwe = !kv_key_data_present && core_ready; +always_comb hwif_in.HMAC512_KV_RD_KEY_CTRL.read_entry.swwe = !kv_key_data_present && core_ready; +always_comb hwif_in.HMAC512_KV_RD_KEY_CTRL.pcr_hash_extend.swwe = !kv_key_data_present && core_ready; +always_comb hwif_in.HMAC512_KV_RD_KEY_CTRL.rsvd.swwe = !kv_key_data_present && core_ready; + +always_comb hwif_in.HMAC512_KV_RD_BLOCK_CTRL.read_en.swwe = !kv_block_data_present && core_ready; +always_comb hwif_in.HMAC512_KV_RD_BLOCK_CTRL.read_entry.swwe = !kv_block_data_present && core_ready; +always_comb hwif_in.HMAC512_KV_RD_BLOCK_CTRL.pcr_hash_extend.swwe = !kv_block_data_present && core_ready; +always_comb hwif_in.HMAC512_KV_RD_BLOCK_CTRL.rsvd.swwe = !kv_block_data_present && core_ready; + +// KV write control must be written before HMAC core operation begins, even though +// output isn't written to KV until the end of the operation. +// Prevent partial-key attacks by blocking register modifications during core execution. +always_comb hwif_in.HMAC512_KV_WR_CTRL.write_en.swwe = core_ready; +always_comb hwif_in.HMAC512_KV_WR_CTRL.write_entry.swwe = core_ready; +always_comb hwif_in.HMAC512_KV_WR_CTRL.hmac_key_dest_valid.swwe = core_ready; +always_comb hwif_in.HMAC512_KV_WR_CTRL.hmac_block_dest_valid.swwe = core_ready; +always_comb hwif_in.HMAC512_KV_WR_CTRL.mldsa_seed_dest_valid.swwe = core_ready; +always_comb hwif_in.HMAC512_KV_WR_CTRL.ecc_pkey_dest_valid.swwe = core_ready; +always_comb hwif_in.HMAC512_KV_WR_CTRL.ecc_seed_dest_valid.swwe = core_ready; +always_comb hwif_in.HMAC512_KV_WR_CTRL.aes_key_dest_valid.swwe = core_ready; +always_comb hwif_in.HMAC512_KV_WR_CTRL.mlkem_seed_dest_valid.swwe = core_ready; +always_comb hwif_in.HMAC512_KV_WR_CTRL.mlkem_msg_dest_valid.swwe = core_ready; +always_comb hwif_in.HMAC512_KV_WR_CTRL.dma_data_dest_valid.swwe = core_ready; +always_comb hwif_in.HMAC512_KV_WR_CTRL.rsvd.swwe = core_ready; + +//keyvault control reg macros for assigning to struct +`CALIPTRA_KV_READ_CTRL_REG2STRUCT(kv_key_read_ctrl_reg, HMAC512_KV_RD_KEY_CTRL) +`CALIPTRA_KV_READ_CTRL_REG2STRUCT(kv_block_read_ctrl_reg, HMAC512_KV_RD_BLOCK_CTRL) +`CALIPTRA_KV_WRITE_CTRL_REG2STRUCT(kv_write_ctrl_reg, HMAC512_KV_WR_CTRL) + +//Force result into KV reg whenever source came from KV +always_comb kv_key_data_present_set = kv_key_read_ctrl_reg.read_en; +always_comb kv_block_data_present_set = kv_block_read_ctrl_reg.read_en; +always_comb kv_data_present = kv_key_data_present | kv_block_data_present; +always_comb kv_data_present_reset = kv_data_present & core_tag_we; + +// Register block +hmac_reg i_hmac_reg ( + .clk(clk), + .rst(1'b0), + + .s_cpuif_req (cs), + .s_cpuif_req_is_wr (we), + .s_cpuif_addr (address[HMAC_REG_ADDR_WIDTH-1:0]), + .s_cpuif_wr_data (write_data), + .s_cpuif_wr_biten ('1), + .s_cpuif_req_stall_wr(), + .s_cpuif_req_stall_rd(), + .s_cpuif_rd_ack (), + .s_cpuif_rd_err (), + .s_cpuif_rd_data (read_data), + .s_cpuif_wr_ack (), + .s_cpuif_wr_err (), + + .hwif_in (hwif_in), + .hwif_out(hwif_out) +); + +always_comb key_mode_error = kv_key_data_present & (init_reg | next_reg) & (mode_reg == HMAC512_MODE) & (key_reg[15:12] == 128'b0); +always_comb key_zero_error = kv_key_data_present & (init_reg | next_reg) & (key_reg == 512'b0); + +always_comb error_flag = key_zero_error | key_mode_error; + +always_ff @(posedge clk or negedge reset_n) +begin : error_detection + if(!reset_n) begin + error_flag_reg <= 1'b0; + key_mode_error_reg <= 1'b0; + key_zero_error_reg <= 1'b0; + end + else if(zeroize_reg) begin + error_flag_reg <= 1'b0; + key_mode_error_reg <= 1'b0; + key_zero_error_reg <= 1'b0; + end + else begin + if (error_flag) + error_flag_reg <= 1'b1; + key_mode_error_reg <= key_mode_error; + key_zero_error_reg <= key_zero_error; + end +end // error_detection + +always_comb error_flag_edge = error_flag & (!error_flag_reg); +always_comb key_mode_error_edge = key_mode_error & (!key_mode_error_reg); +always_comb key_zero_error_edge = key_zero_error & (!key_zero_error_reg); + +//Interrupts hardware interface +assign hwif_in.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.hwset = core_tag_we; +assign hwif_in.intr_block_rf.error_internal_intr_r.key_mode_error_sts.hwset = key_mode_error_edge; +assign hwif_in.intr_block_rf.error_internal_intr_r.key_zero_error_sts.hwset = key_zero_error_edge; +assign hwif_in.intr_block_rf.error_internal_intr_r.error2_sts.hwset = 1'b0; // TODO +assign hwif_in.intr_block_rf.error_internal_intr_r.error3_sts.hwset = 1'b0; // TODO + +assign error_intr = hwif_out.intr_block_rf.error_global_intr_r.intr; +assign notif_intr = hwif_out.intr_block_rf.notif_global_intr_r.intr; + +//Key Vault Control Modules +always_comb begin + kv_key_read_metrics.ocp_lock_in_progress = ocp_lock_in_progress; + kv_key_read_metrics.kv_read_dest = KV_NUM_READ'(1< 1, 2 => 0, 0);} + + //init_ready_cp: cross ready, init; + //next_ready_cp: cross ready, next; + mode_ready_cp: cross ready, mode; + zeroize_ready_cp: cross ready, zeroize; + zeroize_init_cp: cross zeroize, init; + zeroize_next_cp: cross zeroize, next; + init_mode_cp: cross init, mode; + next_mode_cp: cross next, mode; + + endgroup + + covergroup hmac_ocp_lock_cov_grp @(posedge clk); + + ocp_lock_in_progress_cp: coverpoint ocp_lock_in_progress; + + kv_read_entry_0_cp: coverpoint {kv_write_metrics.kv_data0_present, kv_write_metrics.kv_data0_entry} + iff (init | next) { + bins fw = {[0:23]}; //{1'b0, [0:$]}; + bins lower_slots = {[32:47]}; //{1'b1, [0:15]}; + bins upper_slots = {[48:54]}; //{1'b1, [16:22]}; + bins slot_23 = {55}; //{1'b1, 23}; + } + + kv_read_entry_1_cp: coverpoint {kv_write_metrics.kv_data1_present, kv_write_metrics.kv_data1_entry} + iff (init | next) { + bins fw = {[0:23]}; //{1'b0, [0:$]}; + bins lower_slots = {[32:47]}; //{1'b1, [0:15]}; + bins upper_slots = {[48:54]}; //{1'b1, [16:22]}; + bins slot_23 = {55}; //{1'b1, 23}; + } + + kv_write_entry_cp: coverpoint {kv_write_ctrl_reg.write_en, kv_write_metrics.kv_write_entry} + iff (init | next) { + bins fw = {[0:23]}; //{1'b0, [0:$]}; + bins lower_slots = {[32:47]}; //{1'b1, [0:15]}; + bins upper_slots = {[48:54]}; //{1'b1, [16:22]}; + bins slot_23 = {55}; //{1'b1, 23}; + } + + ocp_lock_X_kv_entry: cross ocp_lock_in_progress_cp, kv_write_entry_cp, kv_read_entry_0_cp, kv_read_entry_1_cp; + + endgroup + + hmac_ctrl_cov_grp hmac_ctrl_cov_grp1 = new(); + + hmac_ocp_lock_cov_grp hmac_ocp_lock_cov_grp1 = new(); + +endinterface + +`endif \ No newline at end of file diff --git a/designs/Caliptra/src/caliptra-rtl/hmac_drbg.sv b/designs/Caliptra/src/caliptra-rtl/hmac_drbg.sv new file mode 100644 index 0000000..95f8b3c --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/hmac_drbg.sv @@ -0,0 +1,391 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +// +//====================================================================== +// +// hmac_drbg.sv +// ------ +// HMAC384-drbg top-level wrapper with 384 bit data access. +// +// Based on section 10.1.2. of NIST SP 800-90A, Rev 1: +// "Recommendation for Random Number Generation Using +// Deterministic Random Bit Generators", and +// section 3.1. RFC 6979: "Deterministic Usage of the +// Digital Signature Algorithm (DSA) and Elliptic Curve +// Digital Signature Algorithm (ECDSA)" +// +// Functionality: +// Using the given "entropy" and "nonce", the module +// generates a random number with 384-bit. +// the parameter is : +// - [SHA-384] +// - [PredictionResistance = False] +// - [EntropyInputLen = 384] +// - [NonceLen = 384] +// - [PersonalizationStringLen = 0] +// - [AdditionalInputLen = 0] +// - [ReturnedBitsLen = 384] +// +// - INIT: Instantiates HMAC-DRBG with entropy, nonce, (personalization string is empty). +// Then, it calls HMAC_DRBG_Generate_algorithm (additional input string is empty) +// to generate a 384-bit random value while it's in (0, prime) range. +// if the random value is zero or >= prime, it is rejected and a new random value +// is generated by calling HMAC_DRBG_Generate_algorithm. +// There is NO RESEED process. +// - NEXT: it calls HMAC_DRBG_Generate_algorithm (additional input string is empty) +// to generate a 384-bit random value while it's in (0, prime) range. +// if the random value is zero or >= prime, it is rejected and a new random value +// is generated by calling HMAC_DRBG_Generate_algorithm. +// There is NO RESEED process. +//====================================================================== + +module hmac_drbg +#( + parameter REG_SIZE = 384, + parameter [REG_SIZE-1 : 0] HMAC_DRBG_PRIME = 384'hFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973 +) +( + // Clock and reset. + input wire clk, + input wire reset_n, + input wire zeroize, + + //Control + input wire init_cmd, + input wire next_cmd, + output wire ready, + output wire valid, + + //Data + input wire [REG_SIZE-1 : 0] lfsr_seed, + input wire [REG_SIZE-1 : 0] entropy, + input wire [REG_SIZE-1 : 0] nonce, + + output wire [REG_SIZE-1 : 0] drbg +); + + //---------------------------------------------------------------- + // Internal constant and parameter definitions. + //---------------------------------------------------------------- + localparam [REG_SIZE-1 : 0] V_init = 384'h010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101; + localparam [REG_SIZE-1 : 0] K_init = 384'h000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000; + + localparam [(((1024-REG_SIZE)-1)-12)-1 : 0] ZERO_PAD_V = '0; // 1 for header and 12 bit for message length + + localparam [11 : 0] V_SIZE = {1'b0, 11'd1024 + 11'(REG_SIZE)}; + + /*STATES*/ + localparam [4 : 0] IDLE_ST = 5'd0; // IDLE WAIT and Return step + localparam [4 : 0] INIT_ST = 5'd1; + localparam [4 : 0] NEXT_ST = 5'd2; + localparam [4 : 0] K10_ST = 5'd3; // K = HMAC_K(V || 0x00 || entropy || nonce) ->long message + localparam [4 : 0] K11_ST = 5'd4; + localparam [4 : 0] V1_ST = 5'd5; // V = HMAC_K(V) + localparam [4 : 0] K2_INIT_ST = 5'd6; + localparam [4 : 0] K20_ST = 5'd7; // K = HMAC_K(V || 0x01 || entropy || nonce) ->long message + localparam [4 : 0] K21_ST = 5'd8; + localparam [4 : 0] V2_ST = 5'd9; // V = HMAC_K(V) + localparam [4 : 0] T_ST = 5'd10; // T = HMAC_K(V) + localparam [4 : 0] CHCK_ST = 5'd11; // Return T if T is within the [1,q-1] range, otherwise: + localparam [4 : 0] K3_ST = 5'd12; // K = HMAC_K(V || 0x00) + localparam [4 : 0] V3_ST = 5'd13; // V = HMAC_K(V) and Jump to SIGN_T2_ST + localparam [4 : 0] DONE_ST = 5'd14; + + //---------------------------------------------------------------- + // Registers including update variables and write enable. + //---------------------------------------------------------------- + + /*State register*/ + reg [4:0] drbg_st_reg; + reg [4:0] drbg_next_st; + reg [4:0] drbg_st_reg_last; + + reg ready_reg; + reg valid_reg; + reg [REG_SIZE-1 : 0] drbg_reg; + reg first_round; + reg HMAC_tag_valid_last; + reg HMAC_tag_valid_edge; + + reg [REG_SIZE-1:0] K_reg; + reg [REG_SIZE-1:0] V_reg; + + //---------------------------------------------------------------- + // Register/Wires for HMAC-384 module instantiation. + //---------------------------------------------------------------- + reg HMAC_init; + reg HMAC_next; + reg [1023:0] HMAC_block; + reg [REG_SIZE-1:0] HMAC_key; + logic [511:0] HMAC512_key; + + wire HMAC_ready; + wire HMAC_tag_valid; + logic [REG_SIZE-1:0] HMAC_tag; + logic [511:0] HMAC512_tag; + + logic failure_check; + + //---------------------------------------------------------------- + // HMAC module instantiation. + //---------------------------------------------------------------- + hmac_core + HMAC_K + ( + .clk(clk), + .reset_n(reset_n), + .zeroize(zeroize), + .init_cmd(HMAC_init), + .next_cmd(HMAC_next), + .mode_cmd(1'b0), //hardcoded to HMAC384 mode + .lfsr_seed(lfsr_seed), + .key(HMAC512_key), + .block_msg(HMAC_block), + .ready(HMAC_ready), + .tag(HMAC512_tag), + .tag_valid(HMAC_tag_valid) + ); + + //---------------------------------------------------------------- + // reg_update + // Update functionality for all registers in the core. + //---------------------------------------------------------------- + + always_comb + begin + HMAC512_key = {HMAC_key, 128'b0}; + HMAC_tag = HMAC512_tag[511 : 128]; + end + + always_comb + begin : edge_detector + first_round = (drbg_st_reg == drbg_st_reg_last)? 1'b0 : 1'b1; + HMAC_tag_valid_edge = HMAC_tag_valid & (!HMAC_tag_valid_last); + end // edge_detector + + always_ff @ (posedge clk or negedge reset_n) + begin + if (!reset_n) + HMAC_tag_valid_last <= '0; + else if (zeroize) + HMAC_tag_valid_last <= '0; + else + HMAC_tag_valid_last <= HMAC_tag_valid; + end + + always_ff @ (posedge clk or negedge reset_n) + begin : valid_drbg_regs_updates + if (!reset_n) begin + ready_reg <= 1'b0; + valid_reg <= 1'b0; + drbg_reg <= '0; + end + else if (zeroize) begin + ready_reg <= 1'b0; + valid_reg <= 1'b0; + drbg_reg <= '0; + end + else + begin + unique case (drbg_st_reg) + IDLE_ST: begin + if (init_cmd | next_cmd) begin + ready_reg <= 1'b0; + valid_reg <= 1'b0; + end + else + ready_reg <= 1'b1; + end + + DONE_ST: begin + drbg_reg <= HMAC_tag; + valid_reg <= HMAC_tag_valid; + ready_reg <= HMAC_ready; + end + + default: begin + ready_reg <= 1'b0; + valid_reg <= 1'b0; + drbg_reg <= '0; + end + endcase + end + end // valid_drbg_regs_updates + + always_ff @ (posedge clk or negedge reset_n) + begin : hmac_command_update + if (!reset_n) begin + HMAC_init <= 0; + HMAC_next <= 0; + end + else if (zeroize) begin + HMAC_init <= 0; + HMAC_next <= 0; + end + else begin + HMAC_init <= 0; + HMAC_next <= 0; + if (first_round) begin + unique case(drbg_st_reg) + K10_ST: HMAC_init <= 1; + K11_ST: HMAC_next <= 1; + V1_ST: HMAC_init <= 1; + K20_ST: HMAC_init <= 1; + K21_ST: HMAC_next <= 1; + V2_ST: HMAC_init <= 1; + T_ST: HMAC_init <= 1; + K3_ST: HMAC_init <= 1; + V3_ST: HMAC_init <= 1; + default: begin + HMAC_init <= 0; + HMAC_next <= 0; + end + endcase + end + end + end // hmac_command_update + + always_ff @ (posedge clk or negedge reset_n) + begin : hmac_inputs_update + if (!reset_n) begin + K_reg <= '0; + V_reg <= '0; + end + else if (zeroize) begin + K_reg <= '0; + V_reg <= '0; + end + else begin + if (first_round) begin + unique case(drbg_st_reg) + INIT_ST: begin + K_reg <= K_init; + V_reg <= V_init; + end + V1_ST: K_reg <= HMAC_tag; + K20_ST: V_reg <= HMAC_tag; + V2_ST: K_reg <= HMAC_tag; + T_ST: V_reg <= HMAC_tag; + V3_ST: K_reg <= HMAC_tag; + CHCK_ST: V_reg <= HMAC_tag; + default: begin + K_reg <= K_reg; + V_reg <= V_reg; + end + endcase + end + end + end // hmac_inputs_update + + always_comb + begin : hmac_block_update + HMAC_key = K_reg; + unique case(drbg_st_reg) + K10_ST: HMAC_block = {V_reg, 8'h0, entropy, nonce[383:136]}; + K11_ST: HMAC_block = {nonce[135:0], 1'h1, 875'b0, 12'h888}; + V1_ST: HMAC_block = {V_reg, 1'h1, ZERO_PAD_V, V_SIZE}; + K20_ST: HMAC_block = {V_reg, 8'h1, entropy, nonce[383:136]}; + K21_ST: HMAC_block = {nonce[135:0], 1'h1, 875'b0, 12'h888}; + V2_ST: HMAC_block = {V_reg, 1'h1, ZERO_PAD_V, V_SIZE}; + T_ST: HMAC_block = {V_reg, 1'h1, ZERO_PAD_V, V_SIZE}; + K3_ST: HMAC_block = {V_reg, 8'h0, 1'h1, 619'b0, 12'h588}; + V3_ST: HMAC_block = {V_reg, 1'h1, ZERO_PAD_V, V_SIZE}; + default: HMAC_block = '0; + endcase + end // hmac_block_update + + always_ff @ (posedge clk or negedge reset_n) + begin : state_update + if (!reset_n) + drbg_st_reg <= IDLE_ST; + else if (zeroize) + drbg_st_reg <= IDLE_ST; + else + drbg_st_reg <= drbg_next_st; + end // state_update + + always_ff @ (posedge clk or negedge reset_n) + begin : ff_state_update + if (!reset_n) + drbg_st_reg_last <= IDLE_ST; + else if (zeroize) + drbg_st_reg_last <= IDLE_ST; + else + drbg_st_reg_last <= drbg_st_reg; + end // ff_state_update + + //---------------------------------------------------------------- + // FSM_flow + // + // This FSM starts with the init command and then generates a drbg. + // Active low and async reset. + //---------------------------------------------------------------- + + always_comb + begin: state_logic + unique case (drbg_st_reg) + IDLE_ST: // IDLE WAIT + begin + if (HMAC_ready) begin + unique case ({init_cmd, next_cmd}) + 2'b10 : drbg_next_st = INIT_ST; + 2'b01 : drbg_next_st = NEXT_ST; + default: drbg_next_st = IDLE_ST; + endcase + end + else + drbg_next_st = IDLE_ST; + end + + INIT_ST: drbg_next_st = K10_ST; + NEXT_ST: drbg_next_st = K3_ST; + K10_ST: drbg_next_st = (HMAC_tag_valid_edge)? K11_ST : K10_ST; + K11_ST: drbg_next_st = (HMAC_tag_valid_edge)? V1_ST : K11_ST; + V1_ST: drbg_next_st = (HMAC_tag_valid_edge)? K2_INIT_ST : V1_ST; + K2_INIT_ST: drbg_next_st = K20_ST; + K20_ST: drbg_next_st = (HMAC_tag_valid_edge)? K21_ST : K20_ST; + K21_ST: drbg_next_st = (HMAC_tag_valid_edge)? V2_ST : K21_ST; + V2_ST: drbg_next_st = (HMAC_tag_valid_edge)? T_ST : V2_ST; + T_ST: drbg_next_st = (HMAC_tag_valid_edge)? CHCK_ST : T_ST; + + CHCK_ST: + begin + if (failure_check) + drbg_next_st = K3_ST; + else + drbg_next_st = DONE_ST; + end + + K3_ST: drbg_next_st = (HMAC_tag_valid_edge)? V3_ST : K3_ST; + V3_ST: drbg_next_st = (HMAC_tag_valid_edge)? T_ST : V3_ST; + DONE_ST: drbg_next_st = IDLE_ST; + default: drbg_next_st = IDLE_ST; + + endcase + end //state_logic + + always_comb failure_check = (HMAC_tag==0) || (HMAC_tag >= HMAC_DRBG_PRIME); + + //---------------------------------------------------------------- + // Concurrent connectivity for ports etc. + //---------------------------------------------------------------- + assign ready = ready_reg; + assign valid = valid_reg; + assign drbg = drbg_reg; + +endmodule // hmac_drbg + +//====================================================================== +// EOF hmac_drbg.v +//====================================================================== diff --git a/designs/Caliptra/src/caliptra-rtl/hmac_drbg_cov_bind.sv b/designs/Caliptra/src/caliptra-rtl/hmac_drbg_cov_bind.sv new file mode 100644 index 0000000..2d2457f --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/hmac_drbg_cov_bind.sv @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. + + +module hmac_drbg_cov_bind; + `ifdef FCOV + bind hmac_drbg hmac_drbg_cov_if i_hmac_drbg_cov_if(.*); + `endif +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/hmac_drbg_cov_if.sv b/designs/Caliptra/src/caliptra-rtl/hmac_drbg_cov_if.sv new file mode 100644 index 0000000..b8a620a --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/hmac_drbg_cov_if.sv @@ -0,0 +1,82 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. + +`ifndef VERILATOR + +interface hmac_drbg_cov_if + ( + input logic clk, + input logic reset_n +); + + logic init; + logic next; + logic zeroize; + logic ready; + logic valid; + + logic [1 : 0] hmac_drbg_cmd; + logic [4 : 0] drbg_state; + logic [383 : 0] prime; + logic [383 : 0] drbg; + + parameter logic [383:0] HMAC_DRBG_PRIME = hmac_drbg.HMAC_DRBG_PRIME; + + assign init = hmac_drbg.init_cmd; + assign next = hmac_drbg.next_cmd; + assign zeroize = hmac_drbg.zeroize; + assign ready = hmac_drbg.ready_reg; + assign valid = hmac_drbg.valid_reg; + + assign hmac_drbg_cmd = {next, init}; + + assign drbg_state = hmac_drbg.drbg_st_reg; + assign drbg = hmac_drbg.drbg; + + covergroup hmac_drbg_control_cg @(posedge clk); + reset_cp: coverpoint reset_n; + + init_cp: coverpoint init; + next_cp: coverpoint next; + zeroize_cp: coverpoint zeroize; + ready_cp: coverpoint ready; + valid_cp: coverpoint valid; + + hmac_cmd_cp: coverpoint hmac_drbg_cmd {bins cmd[] = (0, 0 => 1, 2 => 0, 0);} + + init_ready_cp: cross ready, init { + illegal_bins illegal_init_when_ready_low = binsof(init) intersect {1} && binsof(ready) intersect {0}; + } + + next_ready_cp: cross ready, next { + illegal_bins illegal_next_when_ready_low = binsof(next) intersect {1} && binsof(ready) intersect {0}; + } + zeroize_ready_cp: cross ready, zeroize; + zeroize_init_cp: cross zeroize, init; + zeroize_next_cp: cross zeroize, next; + + endgroup + + covergroup hmac_drbg_state_cg @(posedge clk); + drbg_state_cp: coverpoint drbg_state { + bins all_states[] = {[0:14]}; + } + endgroup + + hmac_drbg_state_cg hmac_drbg_state_cov = new(); + hmac_drbg_control_cg hmac_drbg_control_cov = new(); + +endinterface + +`endif \ No newline at end of file diff --git a/designs/Caliptra/src/caliptra-rtl/hmac_param_pkg.sv b/designs/Caliptra/src/caliptra-rtl/hmac_param_pkg.sv new file mode 100644 index 0000000..81ee3ce --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/hmac_param_pkg.sv @@ -0,0 +1,39 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +// +//====================================================================== +// +// hmac_param_pkg.sv +// -------- +// HMAC Parameters +// +// +//====================================================================== + +`ifndef HMAC_PARAM_PKG +`define HMAC_PARAM_PKG + +package hmac_param_pkg; + //---------------------------------------------------------------- + // Internal constant and parameter definitions. + //---------------------------------------------------------------- + + localparam bit [63:0] HMAC_CORE_NAME = 64'h61327368_6163686d; // "hmacsha2" + localparam bit [63:0] HMAC_CORE_VERSION = 64'h00000000_3030322e; // "2.00" + + localparam bit HMAC384_MODE = 1'b0; + localparam bit HMAC512_MODE = 1'b1; +endpackage + +`endif \ No newline at end of file diff --git a/designs/Caliptra/src/caliptra-rtl/hmac_reg.sv b/designs/Caliptra/src/caliptra-rtl/hmac_reg.sv new file mode 100644 index 0000000..f665797 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/hmac_reg.sv @@ -0,0 +1,2376 @@ +// Generated by PeakRDL-regblock - A free and open-source SystemVerilog generator +// https://github.com/SystemRDL/PeakRDL-regblock + +module hmac_reg ( + input wire clk, + input wire rst, + + input wire s_cpuif_req, + input wire s_cpuif_req_is_wr, + input wire [11:0] s_cpuif_addr, + input wire [31:0] s_cpuif_wr_data, + input wire [31:0] s_cpuif_wr_biten, + output wire s_cpuif_req_stall_wr, + output wire s_cpuif_req_stall_rd, + output wire s_cpuif_rd_ack, + output wire s_cpuif_rd_err, + output wire [31:0] s_cpuif_rd_data, + output wire s_cpuif_wr_ack, + output wire s_cpuif_wr_err, + + input hmac_reg_pkg::hmac_reg__in_t hwif_in, + output hmac_reg_pkg::hmac_reg__out_t hwif_out + ); + + //-------------------------------------------------------------------------- + // CPU Bus interface logic + //-------------------------------------------------------------------------- + logic cpuif_req; + logic cpuif_req_is_wr; + logic [11:0] cpuif_addr; + logic [31:0] cpuif_wr_data; + logic [31:0] cpuif_wr_biten; + logic cpuif_req_stall_wr; + logic cpuif_req_stall_rd; + + logic cpuif_rd_ack; + logic cpuif_rd_err; + logic [31:0] cpuif_rd_data; + + logic cpuif_wr_ack; + logic cpuif_wr_err; + + assign cpuif_req = s_cpuif_req; + assign cpuif_req_is_wr = s_cpuif_req_is_wr; + assign cpuif_addr = s_cpuif_addr; + assign cpuif_wr_data = s_cpuif_wr_data; + assign cpuif_wr_biten = s_cpuif_wr_biten; + assign s_cpuif_req_stall_wr = cpuif_req_stall_wr; + assign s_cpuif_req_stall_rd = cpuif_req_stall_rd; + assign s_cpuif_rd_ack = cpuif_rd_ack; + assign s_cpuif_rd_err = cpuif_rd_err; + assign s_cpuif_rd_data = cpuif_rd_data; + assign s_cpuif_wr_ack = cpuif_wr_ack; + assign s_cpuif_wr_err = cpuif_wr_err; + + logic cpuif_req_masked; + + // Read & write latencies are balanced. Stalls not required + assign cpuif_req_stall_rd = '0; + assign cpuif_req_stall_wr = '0; + assign cpuif_req_masked = cpuif_req + & !(!cpuif_req_is_wr & cpuif_req_stall_rd) + & !(cpuif_req_is_wr & cpuif_req_stall_wr); + + //-------------------------------------------------------------------------- + // Address Decode + //-------------------------------------------------------------------------- + typedef struct packed{ + logic [2-1:0]HMAC512_NAME; + logic [2-1:0]HMAC512_VERSION; + logic HMAC512_CTRL; + logic HMAC512_STATUS; + logic [16-1:0]HMAC512_KEY; + logic [32-1:0]HMAC512_BLOCK; + logic [16-1:0]HMAC512_TAG; + logic [12-1:0]HMAC512_LFSR_SEED; + logic HMAC512_KV_RD_KEY_CTRL; + logic HMAC512_KV_RD_KEY_STATUS; + logic HMAC512_KV_RD_BLOCK_CTRL; + logic HMAC512_KV_RD_BLOCK_STATUS; + logic HMAC512_KV_WR_CTRL; + logic HMAC512_KV_WR_STATUS; + struct packed{ + logic global_intr_en_r; + logic error_intr_en_r; + logic notif_intr_en_r; + logic error_global_intr_r; + logic notif_global_intr_r; + logic error_internal_intr_r; + logic notif_internal_intr_r; + logic error_intr_trig_r; + logic notif_intr_trig_r; + logic key_mode_error_intr_count_r; + logic key_zero_error_intr_count_r; + logic error2_intr_count_r; + logic error3_intr_count_r; + logic notif_cmd_done_intr_count_r; + logic key_mode_error_intr_count_incr_r; + logic key_zero_error_intr_count_incr_r; + logic error2_intr_count_incr_r; + logic error3_intr_count_incr_r; + logic notif_cmd_done_intr_count_incr_r; + } intr_block_rf; + } decoded_reg_strb_t; + decoded_reg_strb_t decoded_reg_strb; + logic decoded_req; + logic decoded_req_is_wr; + logic [31:0] decoded_wr_data; + logic [31:0] decoded_wr_biten; + + always_comb begin + for(int i0=0; i0<2; i0++) begin + decoded_reg_strb.HMAC512_NAME[i0] = cpuif_req_masked & (cpuif_addr == 12'h0 + i0*12'h4); + end + for(int i0=0; i0<2; i0++) begin + decoded_reg_strb.HMAC512_VERSION[i0] = cpuif_req_masked & (cpuif_addr == 12'h8 + i0*12'h4); + end + decoded_reg_strb.HMAC512_CTRL = cpuif_req_masked & (cpuif_addr == 12'h10); + decoded_reg_strb.HMAC512_STATUS = cpuif_req_masked & (cpuif_addr == 12'h18); + for(int i0=0; i0<16; i0++) begin + decoded_reg_strb.HMAC512_KEY[i0] = cpuif_req_masked & (cpuif_addr == 12'h40 + i0*12'h4); + end + for(int i0=0; i0<32; i0++) begin + decoded_reg_strb.HMAC512_BLOCK[i0] = cpuif_req_masked & (cpuif_addr == 12'h80 + i0*12'h4); + end + for(int i0=0; i0<16; i0++) begin + decoded_reg_strb.HMAC512_TAG[i0] = cpuif_req_masked & (cpuif_addr == 12'h100 + i0*12'h4); + end + for(int i0=0; i0<12; i0++) begin + decoded_reg_strb.HMAC512_LFSR_SEED[i0] = cpuif_req_masked & (cpuif_addr == 12'h140 + i0*12'h4); + end + decoded_reg_strb.HMAC512_KV_RD_KEY_CTRL = cpuif_req_masked & (cpuif_addr == 12'h600); + decoded_reg_strb.HMAC512_KV_RD_KEY_STATUS = cpuif_req_masked & (cpuif_addr == 12'h604); + decoded_reg_strb.HMAC512_KV_RD_BLOCK_CTRL = cpuif_req_masked & (cpuif_addr == 12'h608); + decoded_reg_strb.HMAC512_KV_RD_BLOCK_STATUS = cpuif_req_masked & (cpuif_addr == 12'h60c); + decoded_reg_strb.HMAC512_KV_WR_CTRL = cpuif_req_masked & (cpuif_addr == 12'h610); + decoded_reg_strb.HMAC512_KV_WR_STATUS = cpuif_req_masked & (cpuif_addr == 12'h614); + decoded_reg_strb.intr_block_rf.global_intr_en_r = cpuif_req_masked & (cpuif_addr == 12'h800); + decoded_reg_strb.intr_block_rf.error_intr_en_r = cpuif_req_masked & (cpuif_addr == 12'h804); + decoded_reg_strb.intr_block_rf.notif_intr_en_r = cpuif_req_masked & (cpuif_addr == 12'h808); + decoded_reg_strb.intr_block_rf.error_global_intr_r = cpuif_req_masked & (cpuif_addr == 12'h80c); + decoded_reg_strb.intr_block_rf.notif_global_intr_r = cpuif_req_masked & (cpuif_addr == 12'h810); + decoded_reg_strb.intr_block_rf.error_internal_intr_r = cpuif_req_masked & (cpuif_addr == 12'h814); + decoded_reg_strb.intr_block_rf.notif_internal_intr_r = cpuif_req_masked & (cpuif_addr == 12'h818); + decoded_reg_strb.intr_block_rf.error_intr_trig_r = cpuif_req_masked & (cpuif_addr == 12'h81c); + decoded_reg_strb.intr_block_rf.notif_intr_trig_r = cpuif_req_masked & (cpuif_addr == 12'h820); + decoded_reg_strb.intr_block_rf.key_mode_error_intr_count_r = cpuif_req_masked & (cpuif_addr == 12'h900); + decoded_reg_strb.intr_block_rf.key_zero_error_intr_count_r = cpuif_req_masked & (cpuif_addr == 12'h904); + decoded_reg_strb.intr_block_rf.error2_intr_count_r = cpuif_req_masked & (cpuif_addr == 12'h908); + decoded_reg_strb.intr_block_rf.error3_intr_count_r = cpuif_req_masked & (cpuif_addr == 12'h90c); + decoded_reg_strb.intr_block_rf.notif_cmd_done_intr_count_r = cpuif_req_masked & (cpuif_addr == 12'h980); + decoded_reg_strb.intr_block_rf.key_mode_error_intr_count_incr_r = cpuif_req_masked & (cpuif_addr == 12'ha00); + decoded_reg_strb.intr_block_rf.key_zero_error_intr_count_incr_r = cpuif_req_masked & (cpuif_addr == 12'ha04); + decoded_reg_strb.intr_block_rf.error2_intr_count_incr_r = cpuif_req_masked & (cpuif_addr == 12'ha08); + decoded_reg_strb.intr_block_rf.error3_intr_count_incr_r = cpuif_req_masked & (cpuif_addr == 12'ha0c); + decoded_reg_strb.intr_block_rf.notif_cmd_done_intr_count_incr_r = cpuif_req_masked & (cpuif_addr == 12'ha10); + end + + // Pass down signals to next stage + assign decoded_req = cpuif_req_masked; + assign decoded_req_is_wr = cpuif_req_is_wr; + assign decoded_wr_data = cpuif_wr_data; + assign decoded_wr_biten = cpuif_wr_biten; + + //-------------------------------------------------------------------------- + // Field logic + //-------------------------------------------------------------------------- + typedef struct packed{ + struct packed{ + struct packed{ + logic next; + logic load_next; + } INIT; + struct packed{ + logic next; + logic load_next; + } NEXT; + struct packed{ + logic next; + logic load_next; + } ZEROIZE; + struct packed{ + logic next; + logic load_next; + } MODE; + struct packed{ + logic next; + logic load_next; + } CSR_MODE; + struct packed{ + logic next; + logic load_next; + } Reserved; + } HMAC512_CTRL; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } KEY; + } [16-1:0]HMAC512_KEY; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } BLOCK; + } [32-1:0]HMAC512_BLOCK; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } TAG; + } [16-1:0]HMAC512_TAG; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } LFSR_SEED; + } [12-1:0]HMAC512_LFSR_SEED; + struct packed{ + struct packed{ + logic next; + logic load_next; + } read_en; + struct packed{ + logic [4:0] next; + logic load_next; + } read_entry; + struct packed{ + logic next; + logic load_next; + } pcr_hash_extend; + struct packed{ + logic [24:0] next; + logic load_next; + } rsvd; + } HMAC512_KV_RD_KEY_CTRL; + struct packed{ + struct packed{ + logic next; + logic load_next; + } VALID; + } HMAC512_KV_RD_KEY_STATUS; + struct packed{ + struct packed{ + logic next; + logic load_next; + } read_en; + struct packed{ + logic [4:0] next; + logic load_next; + } read_entry; + struct packed{ + logic next; + logic load_next; + } pcr_hash_extend; + struct packed{ + logic [24:0] next; + logic load_next; + } rsvd; + } HMAC512_KV_RD_BLOCK_CTRL; + struct packed{ + struct packed{ + logic next; + logic load_next; + } VALID; + } HMAC512_KV_RD_BLOCK_STATUS; + struct packed{ + struct packed{ + logic next; + logic load_next; + } write_en; + struct packed{ + logic [4:0] next; + logic load_next; + } write_entry; + struct packed{ + logic next; + logic load_next; + } hmac_key_dest_valid; + struct packed{ + logic next; + logic load_next; + } hmac_block_dest_valid; + struct packed{ + logic next; + logic load_next; + } mldsa_seed_dest_valid; + struct packed{ + logic next; + logic load_next; + } ecc_pkey_dest_valid; + struct packed{ + logic next; + logic load_next; + } ecc_seed_dest_valid; + struct packed{ + logic next; + logic load_next; + } aes_key_dest_valid; + struct packed{ + logic next; + logic load_next; + } mlkem_seed_dest_valid; + struct packed{ + logic next; + logic load_next; + } mlkem_msg_dest_valid; + struct packed{ + logic next; + logic load_next; + } dma_data_dest_valid; + struct packed{ + logic [16:0] next; + logic load_next; + } rsvd; + } HMAC512_KV_WR_CTRL; + struct packed{ + struct packed{ + logic next; + logic load_next; + } VALID; + } HMAC512_KV_WR_STATUS; + struct packed{ + struct packed{ + struct packed{ + logic next; + logic load_next; + } error_en; + struct packed{ + logic next; + logic load_next; + } notif_en; + } global_intr_en_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + } key_mode_error_en; + struct packed{ + logic next; + logic load_next; + } key_zero_error_en; + struct packed{ + logic next; + logic load_next; + } error2_en; + struct packed{ + logic next; + logic load_next; + } error3_en; + } error_intr_en_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + } notif_cmd_done_en; + } notif_intr_en_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + } agg_sts; + } error_global_intr_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + } agg_sts; + } notif_global_intr_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + } key_mode_error_sts; + struct packed{ + logic next; + logic load_next; + } key_zero_error_sts; + struct packed{ + logic next; + logic load_next; + } error2_sts; + struct packed{ + logic next; + logic load_next; + } error3_sts; + } error_internal_intr_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + } notif_cmd_done_sts; + } notif_internal_intr_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + } key_mode_error_trig; + struct packed{ + logic next; + logic load_next; + } key_zero_error_trig; + struct packed{ + logic next; + logic load_next; + } error2_trig; + struct packed{ + logic next; + logic load_next; + } error3_trig; + } error_intr_trig_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + } notif_cmd_done_trig; + } notif_intr_trig_r; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + logic incrthreshold; + logic incrsaturate; + } cnt; + } key_mode_error_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + logic incrthreshold; + logic incrsaturate; + } cnt; + } key_zero_error_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + logic incrthreshold; + logic incrsaturate; + } cnt; + } error2_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + logic incrthreshold; + logic incrsaturate; + } cnt; + } error3_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + logic incrthreshold; + logic incrsaturate; + } cnt; + } notif_cmd_done_intr_count_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + logic decrthreshold; + logic underflow; + } pulse; + } key_mode_error_intr_count_incr_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + logic decrthreshold; + logic underflow; + } pulse; + } key_zero_error_intr_count_incr_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + logic decrthreshold; + logic underflow; + } pulse; + } error2_intr_count_incr_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + logic decrthreshold; + logic underflow; + } pulse; + } error3_intr_count_incr_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + logic decrthreshold; + logic underflow; + } pulse; + } notif_cmd_done_intr_count_incr_r; + } intr_block_rf; + } field_combo_t; + field_combo_t field_combo; + + typedef struct packed{ + struct packed{ + struct packed{ + logic value; + } INIT; + struct packed{ + logic value; + } NEXT; + struct packed{ + logic value; + } ZEROIZE; + struct packed{ + logic value; + } MODE; + struct packed{ + logic value; + } CSR_MODE; + struct packed{ + logic value; + } Reserved; + } HMAC512_CTRL; + struct packed{ + struct packed{ + logic [31:0] value; + } KEY; + } [16-1:0]HMAC512_KEY; + struct packed{ + struct packed{ + logic [31:0] value; + } BLOCK; + } [32-1:0]HMAC512_BLOCK; + struct packed{ + struct packed{ + logic [31:0] value; + } TAG; + } [16-1:0]HMAC512_TAG; + struct packed{ + struct packed{ + logic [31:0] value; + } LFSR_SEED; + } [12-1:0]HMAC512_LFSR_SEED; + struct packed{ + struct packed{ + logic value; + } read_en; + struct packed{ + logic [4:0] value; + } read_entry; + struct packed{ + logic value; + } pcr_hash_extend; + struct packed{ + logic [24:0] value; + } rsvd; + } HMAC512_KV_RD_KEY_CTRL; + struct packed{ + struct packed{ + logic value; + } VALID; + } HMAC512_KV_RD_KEY_STATUS; + struct packed{ + struct packed{ + logic value; + } read_en; + struct packed{ + logic [4:0] value; + } read_entry; + struct packed{ + logic value; + } pcr_hash_extend; + struct packed{ + logic [24:0] value; + } rsvd; + } HMAC512_KV_RD_BLOCK_CTRL; + struct packed{ + struct packed{ + logic value; + } VALID; + } HMAC512_KV_RD_BLOCK_STATUS; + struct packed{ + struct packed{ + logic value; + } write_en; + struct packed{ + logic [4:0] value; + } write_entry; + struct packed{ + logic value; + } hmac_key_dest_valid; + struct packed{ + logic value; + } hmac_block_dest_valid; + struct packed{ + logic value; + } mldsa_seed_dest_valid; + struct packed{ + logic value; + } ecc_pkey_dest_valid; + struct packed{ + logic value; + } ecc_seed_dest_valid; + struct packed{ + logic value; + } aes_key_dest_valid; + struct packed{ + logic value; + } mlkem_seed_dest_valid; + struct packed{ + logic value; + } mlkem_msg_dest_valid; + struct packed{ + logic value; + } dma_data_dest_valid; + struct packed{ + logic [16:0] value; + } rsvd; + } HMAC512_KV_WR_CTRL; + struct packed{ + struct packed{ + logic value; + } VALID; + } HMAC512_KV_WR_STATUS; + struct packed{ + struct packed{ + struct packed{ + logic value; + } error_en; + struct packed{ + logic value; + } notif_en; + } global_intr_en_r; + struct packed{ + struct packed{ + logic value; + } key_mode_error_en; + struct packed{ + logic value; + } key_zero_error_en; + struct packed{ + logic value; + } error2_en; + struct packed{ + logic value; + } error3_en; + } error_intr_en_r; + struct packed{ + struct packed{ + logic value; + } notif_cmd_done_en; + } notif_intr_en_r; + struct packed{ + struct packed{ + logic value; + } agg_sts; + } error_global_intr_r; + struct packed{ + struct packed{ + logic value; + } agg_sts; + } notif_global_intr_r; + struct packed{ + struct packed{ + logic value; + } key_mode_error_sts; + struct packed{ + logic value; + } key_zero_error_sts; + struct packed{ + logic value; + } error2_sts; + struct packed{ + logic value; + } error3_sts; + } error_internal_intr_r; + struct packed{ + struct packed{ + logic value; + } notif_cmd_done_sts; + } notif_internal_intr_r; + struct packed{ + struct packed{ + logic value; + } key_mode_error_trig; + struct packed{ + logic value; + } key_zero_error_trig; + struct packed{ + logic value; + } error2_trig; + struct packed{ + logic value; + } error3_trig; + } error_intr_trig_r; + struct packed{ + struct packed{ + logic value; + } notif_cmd_done_trig; + } notif_intr_trig_r; + struct packed{ + struct packed{ + logic [31:0] value; + } cnt; + } key_mode_error_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] value; + } cnt; + } key_zero_error_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] value; + } cnt; + } error2_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] value; + } cnt; + } error3_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] value; + } cnt; + } notif_cmd_done_intr_count_r; + struct packed{ + struct packed{ + logic value; + } pulse; + } key_mode_error_intr_count_incr_r; + struct packed{ + struct packed{ + logic value; + } pulse; + } key_zero_error_intr_count_incr_r; + struct packed{ + struct packed{ + logic value; + } pulse; + } error2_intr_count_incr_r; + struct packed{ + struct packed{ + logic value; + } pulse; + } error3_intr_count_incr_r; + struct packed{ + struct packed{ + logic value; + } pulse; + } notif_cmd_done_intr_count_incr_r; + } intr_block_rf; + } field_storage_t; + field_storage_t field_storage; + + // Field: hmac_reg.HMAC512_CTRL.INIT + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.HMAC512_CTRL.INIT.value; + load_next_c = '0; + if(decoded_reg_strb.HMAC512_CTRL && decoded_req_is_wr && hwif_in.HMAC512_CTRL.INIT.swwe) begin // SW write + next_c = (field_storage.HMAC512_CTRL.INIT.value & ~decoded_wr_biten[0:0]) | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end else begin // singlepulse clears back to 0 + next_c = '0; + load_next_c = '1; + end + field_combo.HMAC512_CTRL.INIT.next = next_c; + field_combo.HMAC512_CTRL.INIT.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.HMAC512_CTRL.INIT.value <= 1'h0; + end else if(field_combo.HMAC512_CTRL.INIT.load_next) begin + field_storage.HMAC512_CTRL.INIT.value <= field_combo.HMAC512_CTRL.INIT.next; + end + end + assign hwif_out.HMAC512_CTRL.INIT.value = field_storage.HMAC512_CTRL.INIT.value; + // Field: hmac_reg.HMAC512_CTRL.NEXT + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.HMAC512_CTRL.NEXT.value; + load_next_c = '0; + if(decoded_reg_strb.HMAC512_CTRL && decoded_req_is_wr && hwif_in.HMAC512_CTRL.NEXT.swwe) begin // SW write + next_c = (field_storage.HMAC512_CTRL.NEXT.value & ~decoded_wr_biten[1:1]) | (decoded_wr_data[1:1] & decoded_wr_biten[1:1]); + load_next_c = '1; + end else begin // singlepulse clears back to 0 + next_c = '0; + load_next_c = '1; + end + field_combo.HMAC512_CTRL.NEXT.next = next_c; + field_combo.HMAC512_CTRL.NEXT.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.HMAC512_CTRL.NEXT.value <= 1'h0; + end else if(field_combo.HMAC512_CTRL.NEXT.load_next) begin + field_storage.HMAC512_CTRL.NEXT.value <= field_combo.HMAC512_CTRL.NEXT.next; + end + end + assign hwif_out.HMAC512_CTRL.NEXT.value = field_storage.HMAC512_CTRL.NEXT.value; + // Field: hmac_reg.HMAC512_CTRL.ZEROIZE + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.HMAC512_CTRL.ZEROIZE.value; + load_next_c = '0; + if(decoded_reg_strb.HMAC512_CTRL && decoded_req_is_wr) begin // SW write + next_c = (field_storage.HMAC512_CTRL.ZEROIZE.value & ~decoded_wr_biten[2:2]) | (decoded_wr_data[2:2] & decoded_wr_biten[2:2]); + load_next_c = '1; + end else begin // singlepulse clears back to 0 + next_c = '0; + load_next_c = '1; + end + field_combo.HMAC512_CTRL.ZEROIZE.next = next_c; + field_combo.HMAC512_CTRL.ZEROIZE.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.HMAC512_CTRL.ZEROIZE.value <= 1'h0; + end else if(field_combo.HMAC512_CTRL.ZEROIZE.load_next) begin + field_storage.HMAC512_CTRL.ZEROIZE.value <= field_combo.HMAC512_CTRL.ZEROIZE.next; + end + end + assign hwif_out.HMAC512_CTRL.ZEROIZE.value = field_storage.HMAC512_CTRL.ZEROIZE.value; + // Field: hmac_reg.HMAC512_CTRL.MODE + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.HMAC512_CTRL.MODE.value; + load_next_c = '0; + if(decoded_reg_strb.HMAC512_CTRL && decoded_req_is_wr && hwif_in.HMAC512_CTRL.MODE.swwe) begin // SW write + next_c = (field_storage.HMAC512_CTRL.MODE.value & ~decoded_wr_biten[3:3]) | (decoded_wr_data[3:3] & decoded_wr_biten[3:3]); + load_next_c = '1; + end + field_combo.HMAC512_CTRL.MODE.next = next_c; + field_combo.HMAC512_CTRL.MODE.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.HMAC512_CTRL.MODE.value <= 1'h1; + end else if(field_combo.HMAC512_CTRL.MODE.load_next) begin + field_storage.HMAC512_CTRL.MODE.value <= field_combo.HMAC512_CTRL.MODE.next; + end + end + assign hwif_out.HMAC512_CTRL.MODE.value = field_storage.HMAC512_CTRL.MODE.value; + // Field: hmac_reg.HMAC512_CTRL.CSR_MODE + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.HMAC512_CTRL.CSR_MODE.value; + load_next_c = '0; + if(decoded_reg_strb.HMAC512_CTRL && decoded_req_is_wr && hwif_in.HMAC512_CTRL.CSR_MODE.swwe) begin // SW write + next_c = (field_storage.HMAC512_CTRL.CSR_MODE.value & ~decoded_wr_biten[4:4]) | (decoded_wr_data[4:4] & decoded_wr_biten[4:4]); + load_next_c = '1; + end + field_combo.HMAC512_CTRL.CSR_MODE.next = next_c; + field_combo.HMAC512_CTRL.CSR_MODE.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.HMAC512_CTRL.CSR_MODE.value <= 1'h0; + end else if(field_combo.HMAC512_CTRL.CSR_MODE.load_next) begin + field_storage.HMAC512_CTRL.CSR_MODE.value <= field_combo.HMAC512_CTRL.CSR_MODE.next; + end + end + assign hwif_out.HMAC512_CTRL.CSR_MODE.value = field_storage.HMAC512_CTRL.CSR_MODE.value; + // Field: hmac_reg.HMAC512_CTRL.Reserved + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.HMAC512_CTRL.Reserved.value; + load_next_c = '0; + if(decoded_reg_strb.HMAC512_CTRL && decoded_req_is_wr) begin // SW write + next_c = (field_storage.HMAC512_CTRL.Reserved.value & ~decoded_wr_biten[5:5]) | (decoded_wr_data[5:5] & decoded_wr_biten[5:5]); + load_next_c = '1; + end + field_combo.HMAC512_CTRL.Reserved.next = next_c; + field_combo.HMAC512_CTRL.Reserved.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.HMAC512_CTRL.Reserved.value <= 1'h0; + end else if(field_combo.HMAC512_CTRL.Reserved.load_next) begin + field_storage.HMAC512_CTRL.Reserved.value <= field_combo.HMAC512_CTRL.Reserved.next; + end + end + assign hwif_out.HMAC512_CTRL.Reserved.value = field_storage.HMAC512_CTRL.Reserved.value; + for(genvar i0=0; i0<16; i0++) begin + // Field: hmac_reg.HMAC512_KEY[].KEY + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.HMAC512_KEY[i0].KEY.value; + load_next_c = '0; + if(decoded_reg_strb.HMAC512_KEY[i0] && decoded_req_is_wr && !(hwif_in.HMAC512_KEY[i0].KEY.swwel)) begin // SW write + next_c = (field_storage.HMAC512_KEY[i0].KEY.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end else if(hwif_in.HMAC512_KEY[i0].KEY.we) begin // HW Write - we + next_c = hwif_in.HMAC512_KEY[i0].KEY.next; + load_next_c = '1; + end else if(hwif_in.HMAC512_KEY[i0].KEY.hwclr) begin // HW Clear + next_c = '0; + load_next_c = '1; + end + field_combo.HMAC512_KEY[i0].KEY.next = next_c; + field_combo.HMAC512_KEY[i0].KEY.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.HMAC512_KEY[i0].KEY.value <= 32'h0; + end else if(field_combo.HMAC512_KEY[i0].KEY.load_next) begin + field_storage.HMAC512_KEY[i0].KEY.value <= field_combo.HMAC512_KEY[i0].KEY.next; + end + end + assign hwif_out.HMAC512_KEY[i0].KEY.value = field_storage.HMAC512_KEY[i0].KEY.value; + end + for(genvar i0=0; i0<32; i0++) begin + // Field: hmac_reg.HMAC512_BLOCK[].BLOCK + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.HMAC512_BLOCK[i0].BLOCK.value; + load_next_c = '0; + if(decoded_reg_strb.HMAC512_BLOCK[i0] && decoded_req_is_wr && !(hwif_in.HMAC512_BLOCK[i0].BLOCK.swwel)) begin // SW write + next_c = (field_storage.HMAC512_BLOCK[i0].BLOCK.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end else if(hwif_in.HMAC512_BLOCK[i0].BLOCK.we) begin // HW Write - we + next_c = hwif_in.HMAC512_BLOCK[i0].BLOCK.next; + load_next_c = '1; + end else if(hwif_in.HMAC512_BLOCK[i0].BLOCK.hwclr) begin // HW Clear + next_c = '0; + load_next_c = '1; + end + field_combo.HMAC512_BLOCK[i0].BLOCK.next = next_c; + field_combo.HMAC512_BLOCK[i0].BLOCK.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.HMAC512_BLOCK[i0].BLOCK.value <= 32'h0; + end else if(field_combo.HMAC512_BLOCK[i0].BLOCK.load_next) begin + field_storage.HMAC512_BLOCK[i0].BLOCK.value <= field_combo.HMAC512_BLOCK[i0].BLOCK.next; + end + end + assign hwif_out.HMAC512_BLOCK[i0].BLOCK.value = field_storage.HMAC512_BLOCK[i0].BLOCK.value; + end + for(genvar i0=0; i0<16; i0++) begin + // Field: hmac_reg.HMAC512_TAG[].TAG + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.HMAC512_TAG[i0].TAG.value; + load_next_c = '0; + if(hwif_in.HMAC512_TAG[i0].TAG.hwclr) begin // HW Clear + next_c = '0; + load_next_c = '1; + end else begin // HW Write + next_c = hwif_in.HMAC512_TAG[i0].TAG.next; + load_next_c = '1; + end + field_combo.HMAC512_TAG[i0].TAG.next = next_c; + field_combo.HMAC512_TAG[i0].TAG.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.HMAC512_TAG[i0].TAG.value <= 32'h0; + end else if(field_combo.HMAC512_TAG[i0].TAG.load_next) begin + field_storage.HMAC512_TAG[i0].TAG.value <= field_combo.HMAC512_TAG[i0].TAG.next; + end + end + end + for(genvar i0=0; i0<12; i0++) begin + // Field: hmac_reg.HMAC512_LFSR_SEED[].LFSR_SEED + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.HMAC512_LFSR_SEED[i0].LFSR_SEED.value; + load_next_c = '0; + if(decoded_reg_strb.HMAC512_LFSR_SEED[i0] && decoded_req_is_wr) begin // SW write + next_c = (field_storage.HMAC512_LFSR_SEED[i0].LFSR_SEED.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + field_combo.HMAC512_LFSR_SEED[i0].LFSR_SEED.next = next_c; + field_combo.HMAC512_LFSR_SEED[i0].LFSR_SEED.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.HMAC512_LFSR_SEED[i0].LFSR_SEED.value <= 32'h0; + end else if(field_combo.HMAC512_LFSR_SEED[i0].LFSR_SEED.load_next) begin + field_storage.HMAC512_LFSR_SEED[i0].LFSR_SEED.value <= field_combo.HMAC512_LFSR_SEED[i0].LFSR_SEED.next; + end + end + assign hwif_out.HMAC512_LFSR_SEED[i0].LFSR_SEED.value = field_storage.HMAC512_LFSR_SEED[i0].LFSR_SEED.value; + end + // Field: hmac_reg.HMAC512_KV_RD_KEY_CTRL.read_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.HMAC512_KV_RD_KEY_CTRL.read_en.value; + load_next_c = '0; + if(decoded_reg_strb.HMAC512_KV_RD_KEY_CTRL && decoded_req_is_wr && hwif_in.HMAC512_KV_RD_KEY_CTRL.read_en.swwe) begin // SW write + next_c = (field_storage.HMAC512_KV_RD_KEY_CTRL.read_en.value & ~decoded_wr_biten[0:0]) | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end else if(hwif_in.HMAC512_KV_RD_KEY_CTRL.read_en.hwclr) begin // HW Clear + next_c = '0; + load_next_c = '1; + end + field_combo.HMAC512_KV_RD_KEY_CTRL.read_en.next = next_c; + field_combo.HMAC512_KV_RD_KEY_CTRL.read_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.HMAC512_KV_RD_KEY_CTRL.read_en.value <= 1'h0; + end else if(field_combo.HMAC512_KV_RD_KEY_CTRL.read_en.load_next) begin + field_storage.HMAC512_KV_RD_KEY_CTRL.read_en.value <= field_combo.HMAC512_KV_RD_KEY_CTRL.read_en.next; + end + end + assign hwif_out.HMAC512_KV_RD_KEY_CTRL.read_en.value = field_storage.HMAC512_KV_RD_KEY_CTRL.read_en.value; + // Field: hmac_reg.HMAC512_KV_RD_KEY_CTRL.read_entry + always_comb begin + automatic logic [4:0] next_c; + automatic logic load_next_c; + next_c = field_storage.HMAC512_KV_RD_KEY_CTRL.read_entry.value; + load_next_c = '0; + if(decoded_reg_strb.HMAC512_KV_RD_KEY_CTRL && decoded_req_is_wr && hwif_in.HMAC512_KV_RD_KEY_CTRL.read_entry.swwe) begin // SW write + next_c = (field_storage.HMAC512_KV_RD_KEY_CTRL.read_entry.value & ~decoded_wr_biten[5:1]) | (decoded_wr_data[5:1] & decoded_wr_biten[5:1]); + load_next_c = '1; + end + field_combo.HMAC512_KV_RD_KEY_CTRL.read_entry.next = next_c; + field_combo.HMAC512_KV_RD_KEY_CTRL.read_entry.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.HMAC512_KV_RD_KEY_CTRL.read_entry.value <= 5'h0; + end else if(field_combo.HMAC512_KV_RD_KEY_CTRL.read_entry.load_next) begin + field_storage.HMAC512_KV_RD_KEY_CTRL.read_entry.value <= field_combo.HMAC512_KV_RD_KEY_CTRL.read_entry.next; + end + end + assign hwif_out.HMAC512_KV_RD_KEY_CTRL.read_entry.value = field_storage.HMAC512_KV_RD_KEY_CTRL.read_entry.value; + // Field: hmac_reg.HMAC512_KV_RD_KEY_CTRL.pcr_hash_extend + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.HMAC512_KV_RD_KEY_CTRL.pcr_hash_extend.value; + load_next_c = '0; + if(decoded_reg_strb.HMAC512_KV_RD_KEY_CTRL && decoded_req_is_wr && hwif_in.HMAC512_KV_RD_KEY_CTRL.pcr_hash_extend.swwe) begin // SW write + next_c = (field_storage.HMAC512_KV_RD_KEY_CTRL.pcr_hash_extend.value & ~decoded_wr_biten[6:6]) | (decoded_wr_data[6:6] & decoded_wr_biten[6:6]); + load_next_c = '1; + end + field_combo.HMAC512_KV_RD_KEY_CTRL.pcr_hash_extend.next = next_c; + field_combo.HMAC512_KV_RD_KEY_CTRL.pcr_hash_extend.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.HMAC512_KV_RD_KEY_CTRL.pcr_hash_extend.value <= 1'h0; + end else if(field_combo.HMAC512_KV_RD_KEY_CTRL.pcr_hash_extend.load_next) begin + field_storage.HMAC512_KV_RD_KEY_CTRL.pcr_hash_extend.value <= field_combo.HMAC512_KV_RD_KEY_CTRL.pcr_hash_extend.next; + end + end + assign hwif_out.HMAC512_KV_RD_KEY_CTRL.pcr_hash_extend.value = field_storage.HMAC512_KV_RD_KEY_CTRL.pcr_hash_extend.value; + // Field: hmac_reg.HMAC512_KV_RD_KEY_CTRL.rsvd + always_comb begin + automatic logic [24:0] next_c; + automatic logic load_next_c; + next_c = field_storage.HMAC512_KV_RD_KEY_CTRL.rsvd.value; + load_next_c = '0; + if(decoded_reg_strb.HMAC512_KV_RD_KEY_CTRL && decoded_req_is_wr && hwif_in.HMAC512_KV_RD_KEY_CTRL.rsvd.swwe) begin // SW write + next_c = (field_storage.HMAC512_KV_RD_KEY_CTRL.rsvd.value & ~decoded_wr_biten[31:7]) | (decoded_wr_data[31:7] & decoded_wr_biten[31:7]); + load_next_c = '1; + end + field_combo.HMAC512_KV_RD_KEY_CTRL.rsvd.next = next_c; + field_combo.HMAC512_KV_RD_KEY_CTRL.rsvd.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.HMAC512_KV_RD_KEY_CTRL.rsvd.value <= 25'h0; + end else if(field_combo.HMAC512_KV_RD_KEY_CTRL.rsvd.load_next) begin + field_storage.HMAC512_KV_RD_KEY_CTRL.rsvd.value <= field_combo.HMAC512_KV_RD_KEY_CTRL.rsvd.next; + end + end + assign hwif_out.HMAC512_KV_RD_KEY_CTRL.rsvd.value = field_storage.HMAC512_KV_RD_KEY_CTRL.rsvd.value; + // Field: hmac_reg.HMAC512_KV_RD_KEY_STATUS.VALID + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.HMAC512_KV_RD_KEY_STATUS.VALID.value; + load_next_c = '0; + if(hwif_in.HMAC512_KV_RD_KEY_STATUS.VALID.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end else if(hwif_in.HMAC512_KV_RD_KEY_STATUS.VALID.hwclr) begin // HW Clear + next_c = '0; + load_next_c = '1; + end + field_combo.HMAC512_KV_RD_KEY_STATUS.VALID.next = next_c; + field_combo.HMAC512_KV_RD_KEY_STATUS.VALID.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.HMAC512_KV_RD_KEY_STATUS.VALID.value <= 1'h0; + end else if(field_combo.HMAC512_KV_RD_KEY_STATUS.VALID.load_next) begin + field_storage.HMAC512_KV_RD_KEY_STATUS.VALID.value <= field_combo.HMAC512_KV_RD_KEY_STATUS.VALID.next; + end + end + // Field: hmac_reg.HMAC512_KV_RD_BLOCK_CTRL.read_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.HMAC512_KV_RD_BLOCK_CTRL.read_en.value; + load_next_c = '0; + if(decoded_reg_strb.HMAC512_KV_RD_BLOCK_CTRL && decoded_req_is_wr && hwif_in.HMAC512_KV_RD_BLOCK_CTRL.read_en.swwe) begin // SW write + next_c = (field_storage.HMAC512_KV_RD_BLOCK_CTRL.read_en.value & ~decoded_wr_biten[0:0]) | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end else if(hwif_in.HMAC512_KV_RD_BLOCK_CTRL.read_en.hwclr) begin // HW Clear + next_c = '0; + load_next_c = '1; + end + field_combo.HMAC512_KV_RD_BLOCK_CTRL.read_en.next = next_c; + field_combo.HMAC512_KV_RD_BLOCK_CTRL.read_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.HMAC512_KV_RD_BLOCK_CTRL.read_en.value <= 1'h0; + end else if(field_combo.HMAC512_KV_RD_BLOCK_CTRL.read_en.load_next) begin + field_storage.HMAC512_KV_RD_BLOCK_CTRL.read_en.value <= field_combo.HMAC512_KV_RD_BLOCK_CTRL.read_en.next; + end + end + assign hwif_out.HMAC512_KV_RD_BLOCK_CTRL.read_en.value = field_storage.HMAC512_KV_RD_BLOCK_CTRL.read_en.value; + // Field: hmac_reg.HMAC512_KV_RD_BLOCK_CTRL.read_entry + always_comb begin + automatic logic [4:0] next_c; + automatic logic load_next_c; + next_c = field_storage.HMAC512_KV_RD_BLOCK_CTRL.read_entry.value; + load_next_c = '0; + if(decoded_reg_strb.HMAC512_KV_RD_BLOCK_CTRL && decoded_req_is_wr && hwif_in.HMAC512_KV_RD_BLOCK_CTRL.read_entry.swwe) begin // SW write + next_c = (field_storage.HMAC512_KV_RD_BLOCK_CTRL.read_entry.value & ~decoded_wr_biten[5:1]) | (decoded_wr_data[5:1] & decoded_wr_biten[5:1]); + load_next_c = '1; + end + field_combo.HMAC512_KV_RD_BLOCK_CTRL.read_entry.next = next_c; + field_combo.HMAC512_KV_RD_BLOCK_CTRL.read_entry.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.HMAC512_KV_RD_BLOCK_CTRL.read_entry.value <= 5'h0; + end else if(field_combo.HMAC512_KV_RD_BLOCK_CTRL.read_entry.load_next) begin + field_storage.HMAC512_KV_RD_BLOCK_CTRL.read_entry.value <= field_combo.HMAC512_KV_RD_BLOCK_CTRL.read_entry.next; + end + end + assign hwif_out.HMAC512_KV_RD_BLOCK_CTRL.read_entry.value = field_storage.HMAC512_KV_RD_BLOCK_CTRL.read_entry.value; + // Field: hmac_reg.HMAC512_KV_RD_BLOCK_CTRL.pcr_hash_extend + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.HMAC512_KV_RD_BLOCK_CTRL.pcr_hash_extend.value; + load_next_c = '0; + if(decoded_reg_strb.HMAC512_KV_RD_BLOCK_CTRL && decoded_req_is_wr && hwif_in.HMAC512_KV_RD_BLOCK_CTRL.pcr_hash_extend.swwe) begin // SW write + next_c = (field_storage.HMAC512_KV_RD_BLOCK_CTRL.pcr_hash_extend.value & ~decoded_wr_biten[6:6]) | (decoded_wr_data[6:6] & decoded_wr_biten[6:6]); + load_next_c = '1; + end + field_combo.HMAC512_KV_RD_BLOCK_CTRL.pcr_hash_extend.next = next_c; + field_combo.HMAC512_KV_RD_BLOCK_CTRL.pcr_hash_extend.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.HMAC512_KV_RD_BLOCK_CTRL.pcr_hash_extend.value <= 1'h0; + end else if(field_combo.HMAC512_KV_RD_BLOCK_CTRL.pcr_hash_extend.load_next) begin + field_storage.HMAC512_KV_RD_BLOCK_CTRL.pcr_hash_extend.value <= field_combo.HMAC512_KV_RD_BLOCK_CTRL.pcr_hash_extend.next; + end + end + assign hwif_out.HMAC512_KV_RD_BLOCK_CTRL.pcr_hash_extend.value = field_storage.HMAC512_KV_RD_BLOCK_CTRL.pcr_hash_extend.value; + // Field: hmac_reg.HMAC512_KV_RD_BLOCK_CTRL.rsvd + always_comb begin + automatic logic [24:0] next_c; + automatic logic load_next_c; + next_c = field_storage.HMAC512_KV_RD_BLOCK_CTRL.rsvd.value; + load_next_c = '0; + if(decoded_reg_strb.HMAC512_KV_RD_BLOCK_CTRL && decoded_req_is_wr && hwif_in.HMAC512_KV_RD_BLOCK_CTRL.rsvd.swwe) begin // SW write + next_c = (field_storage.HMAC512_KV_RD_BLOCK_CTRL.rsvd.value & ~decoded_wr_biten[31:7]) | (decoded_wr_data[31:7] & decoded_wr_biten[31:7]); + load_next_c = '1; + end + field_combo.HMAC512_KV_RD_BLOCK_CTRL.rsvd.next = next_c; + field_combo.HMAC512_KV_RD_BLOCK_CTRL.rsvd.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.HMAC512_KV_RD_BLOCK_CTRL.rsvd.value <= 25'h0; + end else if(field_combo.HMAC512_KV_RD_BLOCK_CTRL.rsvd.load_next) begin + field_storage.HMAC512_KV_RD_BLOCK_CTRL.rsvd.value <= field_combo.HMAC512_KV_RD_BLOCK_CTRL.rsvd.next; + end + end + assign hwif_out.HMAC512_KV_RD_BLOCK_CTRL.rsvd.value = field_storage.HMAC512_KV_RD_BLOCK_CTRL.rsvd.value; + // Field: hmac_reg.HMAC512_KV_RD_BLOCK_STATUS.VALID + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.HMAC512_KV_RD_BLOCK_STATUS.VALID.value; + load_next_c = '0; + if(hwif_in.HMAC512_KV_RD_BLOCK_STATUS.VALID.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end else if(hwif_in.HMAC512_KV_RD_BLOCK_STATUS.VALID.hwclr) begin // HW Clear + next_c = '0; + load_next_c = '1; + end + field_combo.HMAC512_KV_RD_BLOCK_STATUS.VALID.next = next_c; + field_combo.HMAC512_KV_RD_BLOCK_STATUS.VALID.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.HMAC512_KV_RD_BLOCK_STATUS.VALID.value <= 1'h0; + end else if(field_combo.HMAC512_KV_RD_BLOCK_STATUS.VALID.load_next) begin + field_storage.HMAC512_KV_RD_BLOCK_STATUS.VALID.value <= field_combo.HMAC512_KV_RD_BLOCK_STATUS.VALID.next; + end + end + // Field: hmac_reg.HMAC512_KV_WR_CTRL.write_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.HMAC512_KV_WR_CTRL.write_en.value; + load_next_c = '0; + if(decoded_reg_strb.HMAC512_KV_WR_CTRL && decoded_req_is_wr && hwif_in.HMAC512_KV_WR_CTRL.write_en.swwe) begin // SW write + next_c = (field_storage.HMAC512_KV_WR_CTRL.write_en.value & ~decoded_wr_biten[0:0]) | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end else if(hwif_in.HMAC512_KV_WR_CTRL.write_en.hwclr) begin // HW Clear + next_c = '0; + load_next_c = '1; + end + field_combo.HMAC512_KV_WR_CTRL.write_en.next = next_c; + field_combo.HMAC512_KV_WR_CTRL.write_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.HMAC512_KV_WR_CTRL.write_en.value <= 1'h0; + end else if(field_combo.HMAC512_KV_WR_CTRL.write_en.load_next) begin + field_storage.HMAC512_KV_WR_CTRL.write_en.value <= field_combo.HMAC512_KV_WR_CTRL.write_en.next; + end + end + assign hwif_out.HMAC512_KV_WR_CTRL.write_en.value = field_storage.HMAC512_KV_WR_CTRL.write_en.value; + // Field: hmac_reg.HMAC512_KV_WR_CTRL.write_entry + always_comb begin + automatic logic [4:0] next_c; + automatic logic load_next_c; + next_c = field_storage.HMAC512_KV_WR_CTRL.write_entry.value; + load_next_c = '0; + if(decoded_reg_strb.HMAC512_KV_WR_CTRL && decoded_req_is_wr && hwif_in.HMAC512_KV_WR_CTRL.write_entry.swwe) begin // SW write + next_c = (field_storage.HMAC512_KV_WR_CTRL.write_entry.value & ~decoded_wr_biten[5:1]) | (decoded_wr_data[5:1] & decoded_wr_biten[5:1]); + load_next_c = '1; + end + field_combo.HMAC512_KV_WR_CTRL.write_entry.next = next_c; + field_combo.HMAC512_KV_WR_CTRL.write_entry.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.HMAC512_KV_WR_CTRL.write_entry.value <= 5'h0; + end else if(field_combo.HMAC512_KV_WR_CTRL.write_entry.load_next) begin + field_storage.HMAC512_KV_WR_CTRL.write_entry.value <= field_combo.HMAC512_KV_WR_CTRL.write_entry.next; + end + end + assign hwif_out.HMAC512_KV_WR_CTRL.write_entry.value = field_storage.HMAC512_KV_WR_CTRL.write_entry.value; + // Field: hmac_reg.HMAC512_KV_WR_CTRL.hmac_key_dest_valid + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.HMAC512_KV_WR_CTRL.hmac_key_dest_valid.value; + load_next_c = '0; + if(decoded_reg_strb.HMAC512_KV_WR_CTRL && decoded_req_is_wr && hwif_in.HMAC512_KV_WR_CTRL.hmac_key_dest_valid.swwe) begin // SW write + next_c = (field_storage.HMAC512_KV_WR_CTRL.hmac_key_dest_valid.value & ~decoded_wr_biten[6:6]) | (decoded_wr_data[6:6] & decoded_wr_biten[6:6]); + load_next_c = '1; + end + field_combo.HMAC512_KV_WR_CTRL.hmac_key_dest_valid.next = next_c; + field_combo.HMAC512_KV_WR_CTRL.hmac_key_dest_valid.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.HMAC512_KV_WR_CTRL.hmac_key_dest_valid.value <= 1'h0; + end else if(field_combo.HMAC512_KV_WR_CTRL.hmac_key_dest_valid.load_next) begin + field_storage.HMAC512_KV_WR_CTRL.hmac_key_dest_valid.value <= field_combo.HMAC512_KV_WR_CTRL.hmac_key_dest_valid.next; + end + end + assign hwif_out.HMAC512_KV_WR_CTRL.hmac_key_dest_valid.value = field_storage.HMAC512_KV_WR_CTRL.hmac_key_dest_valid.value; + // Field: hmac_reg.HMAC512_KV_WR_CTRL.hmac_block_dest_valid + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.HMAC512_KV_WR_CTRL.hmac_block_dest_valid.value; + load_next_c = '0; + if(decoded_reg_strb.HMAC512_KV_WR_CTRL && decoded_req_is_wr && hwif_in.HMAC512_KV_WR_CTRL.hmac_block_dest_valid.swwe) begin // SW write + next_c = (field_storage.HMAC512_KV_WR_CTRL.hmac_block_dest_valid.value & ~decoded_wr_biten[7:7]) | (decoded_wr_data[7:7] & decoded_wr_biten[7:7]); + load_next_c = '1; + end + field_combo.HMAC512_KV_WR_CTRL.hmac_block_dest_valid.next = next_c; + field_combo.HMAC512_KV_WR_CTRL.hmac_block_dest_valid.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.HMAC512_KV_WR_CTRL.hmac_block_dest_valid.value <= 1'h0; + end else if(field_combo.HMAC512_KV_WR_CTRL.hmac_block_dest_valid.load_next) begin + field_storage.HMAC512_KV_WR_CTRL.hmac_block_dest_valid.value <= field_combo.HMAC512_KV_WR_CTRL.hmac_block_dest_valid.next; + end + end + assign hwif_out.HMAC512_KV_WR_CTRL.hmac_block_dest_valid.value = field_storage.HMAC512_KV_WR_CTRL.hmac_block_dest_valid.value; + // Field: hmac_reg.HMAC512_KV_WR_CTRL.mldsa_seed_dest_valid + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.HMAC512_KV_WR_CTRL.mldsa_seed_dest_valid.value; + load_next_c = '0; + if(decoded_reg_strb.HMAC512_KV_WR_CTRL && decoded_req_is_wr && hwif_in.HMAC512_KV_WR_CTRL.mldsa_seed_dest_valid.swwe) begin // SW write + next_c = (field_storage.HMAC512_KV_WR_CTRL.mldsa_seed_dest_valid.value & ~decoded_wr_biten[8:8]) | (decoded_wr_data[8:8] & decoded_wr_biten[8:8]); + load_next_c = '1; + end + field_combo.HMAC512_KV_WR_CTRL.mldsa_seed_dest_valid.next = next_c; + field_combo.HMAC512_KV_WR_CTRL.mldsa_seed_dest_valid.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.HMAC512_KV_WR_CTRL.mldsa_seed_dest_valid.value <= 1'h0; + end else if(field_combo.HMAC512_KV_WR_CTRL.mldsa_seed_dest_valid.load_next) begin + field_storage.HMAC512_KV_WR_CTRL.mldsa_seed_dest_valid.value <= field_combo.HMAC512_KV_WR_CTRL.mldsa_seed_dest_valid.next; + end + end + assign hwif_out.HMAC512_KV_WR_CTRL.mldsa_seed_dest_valid.value = field_storage.HMAC512_KV_WR_CTRL.mldsa_seed_dest_valid.value; + // Field: hmac_reg.HMAC512_KV_WR_CTRL.ecc_pkey_dest_valid + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.HMAC512_KV_WR_CTRL.ecc_pkey_dest_valid.value; + load_next_c = '0; + if(decoded_reg_strb.HMAC512_KV_WR_CTRL && decoded_req_is_wr && hwif_in.HMAC512_KV_WR_CTRL.ecc_pkey_dest_valid.swwe) begin // SW write + next_c = (field_storage.HMAC512_KV_WR_CTRL.ecc_pkey_dest_valid.value & ~decoded_wr_biten[9:9]) | (decoded_wr_data[9:9] & decoded_wr_biten[9:9]); + load_next_c = '1; + end + field_combo.HMAC512_KV_WR_CTRL.ecc_pkey_dest_valid.next = next_c; + field_combo.HMAC512_KV_WR_CTRL.ecc_pkey_dest_valid.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.HMAC512_KV_WR_CTRL.ecc_pkey_dest_valid.value <= 1'h0; + end else if(field_combo.HMAC512_KV_WR_CTRL.ecc_pkey_dest_valid.load_next) begin + field_storage.HMAC512_KV_WR_CTRL.ecc_pkey_dest_valid.value <= field_combo.HMAC512_KV_WR_CTRL.ecc_pkey_dest_valid.next; + end + end + assign hwif_out.HMAC512_KV_WR_CTRL.ecc_pkey_dest_valid.value = field_storage.HMAC512_KV_WR_CTRL.ecc_pkey_dest_valid.value; + // Field: hmac_reg.HMAC512_KV_WR_CTRL.ecc_seed_dest_valid + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.HMAC512_KV_WR_CTRL.ecc_seed_dest_valid.value; + load_next_c = '0; + if(decoded_reg_strb.HMAC512_KV_WR_CTRL && decoded_req_is_wr && hwif_in.HMAC512_KV_WR_CTRL.ecc_seed_dest_valid.swwe) begin // SW write + next_c = (field_storage.HMAC512_KV_WR_CTRL.ecc_seed_dest_valid.value & ~decoded_wr_biten[10:10]) | (decoded_wr_data[10:10] & decoded_wr_biten[10:10]); + load_next_c = '1; + end + field_combo.HMAC512_KV_WR_CTRL.ecc_seed_dest_valid.next = next_c; + field_combo.HMAC512_KV_WR_CTRL.ecc_seed_dest_valid.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.HMAC512_KV_WR_CTRL.ecc_seed_dest_valid.value <= 1'h0; + end else if(field_combo.HMAC512_KV_WR_CTRL.ecc_seed_dest_valid.load_next) begin + field_storage.HMAC512_KV_WR_CTRL.ecc_seed_dest_valid.value <= field_combo.HMAC512_KV_WR_CTRL.ecc_seed_dest_valid.next; + end + end + assign hwif_out.HMAC512_KV_WR_CTRL.ecc_seed_dest_valid.value = field_storage.HMAC512_KV_WR_CTRL.ecc_seed_dest_valid.value; + // Field: hmac_reg.HMAC512_KV_WR_CTRL.aes_key_dest_valid + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.HMAC512_KV_WR_CTRL.aes_key_dest_valid.value; + load_next_c = '0; + if(decoded_reg_strb.HMAC512_KV_WR_CTRL && decoded_req_is_wr && hwif_in.HMAC512_KV_WR_CTRL.aes_key_dest_valid.swwe) begin // SW write + next_c = (field_storage.HMAC512_KV_WR_CTRL.aes_key_dest_valid.value & ~decoded_wr_biten[11:11]) | (decoded_wr_data[11:11] & decoded_wr_biten[11:11]); + load_next_c = '1; + end + field_combo.HMAC512_KV_WR_CTRL.aes_key_dest_valid.next = next_c; + field_combo.HMAC512_KV_WR_CTRL.aes_key_dest_valid.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.HMAC512_KV_WR_CTRL.aes_key_dest_valid.value <= 1'h0; + end else if(field_combo.HMAC512_KV_WR_CTRL.aes_key_dest_valid.load_next) begin + field_storage.HMAC512_KV_WR_CTRL.aes_key_dest_valid.value <= field_combo.HMAC512_KV_WR_CTRL.aes_key_dest_valid.next; + end + end + assign hwif_out.HMAC512_KV_WR_CTRL.aes_key_dest_valid.value = field_storage.HMAC512_KV_WR_CTRL.aes_key_dest_valid.value; + // Field: hmac_reg.HMAC512_KV_WR_CTRL.mlkem_seed_dest_valid + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.HMAC512_KV_WR_CTRL.mlkem_seed_dest_valid.value; + load_next_c = '0; + if(decoded_reg_strb.HMAC512_KV_WR_CTRL && decoded_req_is_wr && hwif_in.HMAC512_KV_WR_CTRL.mlkem_seed_dest_valid.swwe) begin // SW write + next_c = (field_storage.HMAC512_KV_WR_CTRL.mlkem_seed_dest_valid.value & ~decoded_wr_biten[12:12]) | (decoded_wr_data[12:12] & decoded_wr_biten[12:12]); + load_next_c = '1; + end + field_combo.HMAC512_KV_WR_CTRL.mlkem_seed_dest_valid.next = next_c; + field_combo.HMAC512_KV_WR_CTRL.mlkem_seed_dest_valid.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.HMAC512_KV_WR_CTRL.mlkem_seed_dest_valid.value <= 1'h0; + end else if(field_combo.HMAC512_KV_WR_CTRL.mlkem_seed_dest_valid.load_next) begin + field_storage.HMAC512_KV_WR_CTRL.mlkem_seed_dest_valid.value <= field_combo.HMAC512_KV_WR_CTRL.mlkem_seed_dest_valid.next; + end + end + assign hwif_out.HMAC512_KV_WR_CTRL.mlkem_seed_dest_valid.value = field_storage.HMAC512_KV_WR_CTRL.mlkem_seed_dest_valid.value; + // Field: hmac_reg.HMAC512_KV_WR_CTRL.mlkem_msg_dest_valid + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.HMAC512_KV_WR_CTRL.mlkem_msg_dest_valid.value; + load_next_c = '0; + if(decoded_reg_strb.HMAC512_KV_WR_CTRL && decoded_req_is_wr && hwif_in.HMAC512_KV_WR_CTRL.mlkem_msg_dest_valid.swwe) begin // SW write + next_c = (field_storage.HMAC512_KV_WR_CTRL.mlkem_msg_dest_valid.value & ~decoded_wr_biten[13:13]) | (decoded_wr_data[13:13] & decoded_wr_biten[13:13]); + load_next_c = '1; + end + field_combo.HMAC512_KV_WR_CTRL.mlkem_msg_dest_valid.next = next_c; + field_combo.HMAC512_KV_WR_CTRL.mlkem_msg_dest_valid.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.HMAC512_KV_WR_CTRL.mlkem_msg_dest_valid.value <= 1'h0; + end else if(field_combo.HMAC512_KV_WR_CTRL.mlkem_msg_dest_valid.load_next) begin + field_storage.HMAC512_KV_WR_CTRL.mlkem_msg_dest_valid.value <= field_combo.HMAC512_KV_WR_CTRL.mlkem_msg_dest_valid.next; + end + end + assign hwif_out.HMAC512_KV_WR_CTRL.mlkem_msg_dest_valid.value = field_storage.HMAC512_KV_WR_CTRL.mlkem_msg_dest_valid.value; + // Field: hmac_reg.HMAC512_KV_WR_CTRL.dma_data_dest_valid + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.HMAC512_KV_WR_CTRL.dma_data_dest_valid.value; + load_next_c = '0; + if(decoded_reg_strb.HMAC512_KV_WR_CTRL && decoded_req_is_wr && hwif_in.HMAC512_KV_WR_CTRL.dma_data_dest_valid.swwe) begin // SW write + next_c = (field_storage.HMAC512_KV_WR_CTRL.dma_data_dest_valid.value & ~decoded_wr_biten[14:14]) | (decoded_wr_data[14:14] & decoded_wr_biten[14:14]); + load_next_c = '1; + end + field_combo.HMAC512_KV_WR_CTRL.dma_data_dest_valid.next = next_c; + field_combo.HMAC512_KV_WR_CTRL.dma_data_dest_valid.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.HMAC512_KV_WR_CTRL.dma_data_dest_valid.value <= 1'h0; + end else if(field_combo.HMAC512_KV_WR_CTRL.dma_data_dest_valid.load_next) begin + field_storage.HMAC512_KV_WR_CTRL.dma_data_dest_valid.value <= field_combo.HMAC512_KV_WR_CTRL.dma_data_dest_valid.next; + end + end + assign hwif_out.HMAC512_KV_WR_CTRL.dma_data_dest_valid.value = field_storage.HMAC512_KV_WR_CTRL.dma_data_dest_valid.value; + // Field: hmac_reg.HMAC512_KV_WR_CTRL.rsvd + always_comb begin + automatic logic [16:0] next_c; + automatic logic load_next_c; + next_c = field_storage.HMAC512_KV_WR_CTRL.rsvd.value; + load_next_c = '0; + if(decoded_reg_strb.HMAC512_KV_WR_CTRL && decoded_req_is_wr && hwif_in.HMAC512_KV_WR_CTRL.rsvd.swwe) begin // SW write + next_c = (field_storage.HMAC512_KV_WR_CTRL.rsvd.value & ~decoded_wr_biten[31:15]) | (decoded_wr_data[31:15] & decoded_wr_biten[31:15]); + load_next_c = '1; + end + field_combo.HMAC512_KV_WR_CTRL.rsvd.next = next_c; + field_combo.HMAC512_KV_WR_CTRL.rsvd.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.HMAC512_KV_WR_CTRL.rsvd.value <= 17'h0; + end else if(field_combo.HMAC512_KV_WR_CTRL.rsvd.load_next) begin + field_storage.HMAC512_KV_WR_CTRL.rsvd.value <= field_combo.HMAC512_KV_WR_CTRL.rsvd.next; + end + end + assign hwif_out.HMAC512_KV_WR_CTRL.rsvd.value = field_storage.HMAC512_KV_WR_CTRL.rsvd.value; + // Field: hmac_reg.HMAC512_KV_WR_STATUS.VALID + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.HMAC512_KV_WR_STATUS.VALID.value; + load_next_c = '0; + if(hwif_in.HMAC512_KV_WR_STATUS.VALID.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end else if(hwif_in.HMAC512_KV_WR_STATUS.VALID.hwclr) begin // HW Clear + next_c = '0; + load_next_c = '1; + end + field_combo.HMAC512_KV_WR_STATUS.VALID.next = next_c; + field_combo.HMAC512_KV_WR_STATUS.VALID.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.HMAC512_KV_WR_STATUS.VALID.value <= 1'h0; + end else if(field_combo.HMAC512_KV_WR_STATUS.VALID.load_next) begin + field_storage.HMAC512_KV_WR_STATUS.VALID.value <= field_combo.HMAC512_KV_WR_STATUS.VALID.next; + end + end + // Field: hmac_reg.intr_block_rf.global_intr_en_r.error_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.global_intr_en_r.error_en.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.global_intr_en_r && decoded_req_is_wr) begin // SW write + next_c = (field_storage.intr_block_rf.global_intr_en_r.error_en.value & ~decoded_wr_biten[0:0]) | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end + field_combo.intr_block_rf.global_intr_en_r.error_en.next = next_c; + field_combo.intr_block_rf.global_intr_en_r.error_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.global_intr_en_r.error_en.value <= 1'h0; + end else if(field_combo.intr_block_rf.global_intr_en_r.error_en.load_next) begin + field_storage.intr_block_rf.global_intr_en_r.error_en.value <= field_combo.intr_block_rf.global_intr_en_r.error_en.next; + end + end + // Field: hmac_reg.intr_block_rf.global_intr_en_r.notif_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.global_intr_en_r.notif_en.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.global_intr_en_r && decoded_req_is_wr) begin // SW write + next_c = (field_storage.intr_block_rf.global_intr_en_r.notif_en.value & ~decoded_wr_biten[1:1]) | (decoded_wr_data[1:1] & decoded_wr_biten[1:1]); + load_next_c = '1; + end + field_combo.intr_block_rf.global_intr_en_r.notif_en.next = next_c; + field_combo.intr_block_rf.global_intr_en_r.notif_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.global_intr_en_r.notif_en.value <= 1'h0; + end else if(field_combo.intr_block_rf.global_intr_en_r.notif_en.load_next) begin + field_storage.intr_block_rf.global_intr_en_r.notif_en.value <= field_combo.intr_block_rf.global_intr_en_r.notif_en.next; + end + end + // Field: hmac_reg.intr_block_rf.error_intr_en_r.key_mode_error_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_intr_en_r.key_mode_error_en.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_intr_en_r && decoded_req_is_wr) begin // SW write + next_c = (field_storage.intr_block_rf.error_intr_en_r.key_mode_error_en.value & ~decoded_wr_biten[0:0]) | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end + field_combo.intr_block_rf.error_intr_en_r.key_mode_error_en.next = next_c; + field_combo.intr_block_rf.error_intr_en_r.key_mode_error_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.error_intr_en_r.key_mode_error_en.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_intr_en_r.key_mode_error_en.load_next) begin + field_storage.intr_block_rf.error_intr_en_r.key_mode_error_en.value <= field_combo.intr_block_rf.error_intr_en_r.key_mode_error_en.next; + end + end + // Field: hmac_reg.intr_block_rf.error_intr_en_r.key_zero_error_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_intr_en_r.key_zero_error_en.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_intr_en_r && decoded_req_is_wr) begin // SW write + next_c = (field_storage.intr_block_rf.error_intr_en_r.key_zero_error_en.value & ~decoded_wr_biten[1:1]) | (decoded_wr_data[1:1] & decoded_wr_biten[1:1]); + load_next_c = '1; + end + field_combo.intr_block_rf.error_intr_en_r.key_zero_error_en.next = next_c; + field_combo.intr_block_rf.error_intr_en_r.key_zero_error_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.error_intr_en_r.key_zero_error_en.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_intr_en_r.key_zero_error_en.load_next) begin + field_storage.intr_block_rf.error_intr_en_r.key_zero_error_en.value <= field_combo.intr_block_rf.error_intr_en_r.key_zero_error_en.next; + end + end + // Field: hmac_reg.intr_block_rf.error_intr_en_r.error2_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_intr_en_r.error2_en.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_intr_en_r && decoded_req_is_wr) begin // SW write + next_c = (field_storage.intr_block_rf.error_intr_en_r.error2_en.value & ~decoded_wr_biten[2:2]) | (decoded_wr_data[2:2] & decoded_wr_biten[2:2]); + load_next_c = '1; + end + field_combo.intr_block_rf.error_intr_en_r.error2_en.next = next_c; + field_combo.intr_block_rf.error_intr_en_r.error2_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.error_intr_en_r.error2_en.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_intr_en_r.error2_en.load_next) begin + field_storage.intr_block_rf.error_intr_en_r.error2_en.value <= field_combo.intr_block_rf.error_intr_en_r.error2_en.next; + end + end + // Field: hmac_reg.intr_block_rf.error_intr_en_r.error3_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_intr_en_r.error3_en.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_intr_en_r && decoded_req_is_wr) begin // SW write + next_c = (field_storage.intr_block_rf.error_intr_en_r.error3_en.value & ~decoded_wr_biten[3:3]) | (decoded_wr_data[3:3] & decoded_wr_biten[3:3]); + load_next_c = '1; + end + field_combo.intr_block_rf.error_intr_en_r.error3_en.next = next_c; + field_combo.intr_block_rf.error_intr_en_r.error3_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.error_intr_en_r.error3_en.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_intr_en_r.error3_en.load_next) begin + field_storage.intr_block_rf.error_intr_en_r.error3_en.value <= field_combo.intr_block_rf.error_intr_en_r.error3_en.next; + end + end + // Field: hmac_reg.intr_block_rf.notif_intr_en_r.notif_cmd_done_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_intr_en_r.notif_cmd_done_en.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.notif_intr_en_r && decoded_req_is_wr) begin // SW write + next_c = (field_storage.intr_block_rf.notif_intr_en_r.notif_cmd_done_en.value & ~decoded_wr_biten[0:0]) | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end + field_combo.intr_block_rf.notif_intr_en_r.notif_cmd_done_en.next = next_c; + field_combo.intr_block_rf.notif_intr_en_r.notif_cmd_done_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.notif_intr_en_r.notif_cmd_done_en.value <= 1'h0; + end else if(field_combo.intr_block_rf.notif_intr_en_r.notif_cmd_done_en.load_next) begin + field_storage.intr_block_rf.notif_intr_en_r.notif_cmd_done_en.value <= field_combo.intr_block_rf.notif_intr_en_r.notif_cmd_done_en.next; + end + end + // Field: hmac_reg.intr_block_rf.error_global_intr_r.agg_sts + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_global_intr_r.agg_sts.value; + load_next_c = '0; + + // HW Write + next_c = hwif_out.intr_block_rf.error_internal_intr_r.intr; + load_next_c = '1; + field_combo.intr_block_rf.error_global_intr_r.agg_sts.next = next_c; + field_combo.intr_block_rf.error_global_intr_r.agg_sts.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.error_global_intr_r.agg_sts.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_global_intr_r.agg_sts.load_next) begin + field_storage.intr_block_rf.error_global_intr_r.agg_sts.value <= field_combo.intr_block_rf.error_global_intr_r.agg_sts.next; + end + end + assign hwif_out.intr_block_rf.error_global_intr_r.intr = + |(field_storage.intr_block_rf.error_global_intr_r.agg_sts.value & field_storage.intr_block_rf.global_intr_en_r.error_en.value); + // Field: hmac_reg.intr_block_rf.notif_global_intr_r.agg_sts + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_global_intr_r.agg_sts.value; + load_next_c = '0; + + // HW Write + next_c = hwif_out.intr_block_rf.notif_internal_intr_r.intr; + load_next_c = '1; + field_combo.intr_block_rf.notif_global_intr_r.agg_sts.next = next_c; + field_combo.intr_block_rf.notif_global_intr_r.agg_sts.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.notif_global_intr_r.agg_sts.value <= 1'h0; + end else if(field_combo.intr_block_rf.notif_global_intr_r.agg_sts.load_next) begin + field_storage.intr_block_rf.notif_global_intr_r.agg_sts.value <= field_combo.intr_block_rf.notif_global_intr_r.agg_sts.next; + end + end + assign hwif_out.intr_block_rf.notif_global_intr_r.intr = + |(field_storage.intr_block_rf.notif_global_intr_r.agg_sts.value & field_storage.intr_block_rf.global_intr_en_r.notif_en.value); + // Field: hmac_reg.intr_block_rf.error_internal_intr_r.key_mode_error_sts + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_internal_intr_r.key_mode_error_sts.value; + load_next_c = '0; + if(field_storage.intr_block_rf.error_intr_trig_r.key_mode_error_trig.value != '0) begin // stickybit + next_c = field_storage.intr_block_rf.error_internal_intr_r.key_mode_error_sts.value | field_storage.intr_block_rf.error_intr_trig_r.key_mode_error_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.error_internal_intr_r.key_mode_error_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end else if(decoded_reg_strb.intr_block_rf.error_internal_intr_r && decoded_req_is_wr) begin // SW write 1 clear + next_c = field_storage.intr_block_rf.error_internal_intr_r.key_mode_error_sts.value & ~(decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end + field_combo.intr_block_rf.error_internal_intr_r.key_mode_error_sts.next = next_c; + field_combo.intr_block_rf.error_internal_intr_r.key_mode_error_sts.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.error_reset_b) begin + if(~hwif_in.error_reset_b) begin + field_storage.intr_block_rf.error_internal_intr_r.key_mode_error_sts.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_internal_intr_r.key_mode_error_sts.load_next) begin + field_storage.intr_block_rf.error_internal_intr_r.key_mode_error_sts.value <= field_combo.intr_block_rf.error_internal_intr_r.key_mode_error_sts.next; + end + end + // Field: hmac_reg.intr_block_rf.error_internal_intr_r.key_zero_error_sts + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_internal_intr_r.key_zero_error_sts.value; + load_next_c = '0; + if(field_storage.intr_block_rf.error_intr_trig_r.key_zero_error_trig.value != '0) begin // stickybit + next_c = field_storage.intr_block_rf.error_internal_intr_r.key_zero_error_sts.value | field_storage.intr_block_rf.error_intr_trig_r.key_zero_error_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.error_internal_intr_r.key_zero_error_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end else if(decoded_reg_strb.intr_block_rf.error_internal_intr_r && decoded_req_is_wr) begin // SW write 1 clear + next_c = field_storage.intr_block_rf.error_internal_intr_r.key_zero_error_sts.value & ~(decoded_wr_data[1:1] & decoded_wr_biten[1:1]); + load_next_c = '1; + end + field_combo.intr_block_rf.error_internal_intr_r.key_zero_error_sts.next = next_c; + field_combo.intr_block_rf.error_internal_intr_r.key_zero_error_sts.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.error_reset_b) begin + if(~hwif_in.error_reset_b) begin + field_storage.intr_block_rf.error_internal_intr_r.key_zero_error_sts.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_internal_intr_r.key_zero_error_sts.load_next) begin + field_storage.intr_block_rf.error_internal_intr_r.key_zero_error_sts.value <= field_combo.intr_block_rf.error_internal_intr_r.key_zero_error_sts.next; + end + end + // Field: hmac_reg.intr_block_rf.error_internal_intr_r.error2_sts + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_internal_intr_r.error2_sts.value; + load_next_c = '0; + if(field_storage.intr_block_rf.error_intr_trig_r.error2_trig.value != '0) begin // stickybit + next_c = field_storage.intr_block_rf.error_internal_intr_r.error2_sts.value | field_storage.intr_block_rf.error_intr_trig_r.error2_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.error_internal_intr_r.error2_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end else if(decoded_reg_strb.intr_block_rf.error_internal_intr_r && decoded_req_is_wr) begin // SW write 1 clear + next_c = field_storage.intr_block_rf.error_internal_intr_r.error2_sts.value & ~(decoded_wr_data[2:2] & decoded_wr_biten[2:2]); + load_next_c = '1; + end + field_combo.intr_block_rf.error_internal_intr_r.error2_sts.next = next_c; + field_combo.intr_block_rf.error_internal_intr_r.error2_sts.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.error_reset_b) begin + if(~hwif_in.error_reset_b) begin + field_storage.intr_block_rf.error_internal_intr_r.error2_sts.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_internal_intr_r.error2_sts.load_next) begin + field_storage.intr_block_rf.error_internal_intr_r.error2_sts.value <= field_combo.intr_block_rf.error_internal_intr_r.error2_sts.next; + end + end + // Field: hmac_reg.intr_block_rf.error_internal_intr_r.error3_sts + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_internal_intr_r.error3_sts.value; + load_next_c = '0; + if(field_storage.intr_block_rf.error_intr_trig_r.error3_trig.value != '0) begin // stickybit + next_c = field_storage.intr_block_rf.error_internal_intr_r.error3_sts.value | field_storage.intr_block_rf.error_intr_trig_r.error3_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.error_internal_intr_r.error3_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end else if(decoded_reg_strb.intr_block_rf.error_internal_intr_r && decoded_req_is_wr) begin // SW write 1 clear + next_c = field_storage.intr_block_rf.error_internal_intr_r.error3_sts.value & ~(decoded_wr_data[3:3] & decoded_wr_biten[3:3]); + load_next_c = '1; + end + field_combo.intr_block_rf.error_internal_intr_r.error3_sts.next = next_c; + field_combo.intr_block_rf.error_internal_intr_r.error3_sts.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.error_reset_b) begin + if(~hwif_in.error_reset_b) begin + field_storage.intr_block_rf.error_internal_intr_r.error3_sts.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_internal_intr_r.error3_sts.load_next) begin + field_storage.intr_block_rf.error_internal_intr_r.error3_sts.value <= field_combo.intr_block_rf.error_internal_intr_r.error3_sts.next; + end + end + assign hwif_out.intr_block_rf.error_internal_intr_r.intr = + |(field_storage.intr_block_rf.error_internal_intr_r.key_mode_error_sts.value & field_storage.intr_block_rf.error_intr_en_r.key_mode_error_en.value) + || |(field_storage.intr_block_rf.error_internal_intr_r.key_zero_error_sts.value & field_storage.intr_block_rf.error_intr_en_r.key_zero_error_en.value) + || |(field_storage.intr_block_rf.error_internal_intr_r.error2_sts.value & field_storage.intr_block_rf.error_intr_en_r.error2_en.value) + || |(field_storage.intr_block_rf.error_internal_intr_r.error3_sts.value & field_storage.intr_block_rf.error_intr_en_r.error3_en.value); + // Field: hmac_reg.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.value; + load_next_c = '0; + if(field_storage.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.value != '0) begin // stickybit + next_c = field_storage.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.value | field_storage.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end else if(decoded_reg_strb.intr_block_rf.notif_internal_intr_r && decoded_req_is_wr) begin // SW write 1 clear + next_c = field_storage.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.value & ~(decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end + field_combo.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.next = next_c; + field_combo.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.value <= 1'h0; + end else if(field_combo.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.load_next) begin + field_storage.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.value <= field_combo.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.next; + end + end + assign hwif_out.intr_block_rf.notif_internal_intr_r.intr = + |(field_storage.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.value & field_storage.intr_block_rf.notif_intr_en_r.notif_cmd_done_en.value); + // Field: hmac_reg.intr_block_rf.error_intr_trig_r.key_mode_error_trig + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_intr_trig_r.key_mode_error_trig.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_intr_trig_r && decoded_req_is_wr) begin // SW write 1 set + next_c = field_storage.intr_block_rf.error_intr_trig_r.key_mode_error_trig.value | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end else begin // singlepulse clears back to 0 + next_c = '0; + load_next_c = '1; + end + field_combo.intr_block_rf.error_intr_trig_r.key_mode_error_trig.next = next_c; + field_combo.intr_block_rf.error_intr_trig_r.key_mode_error_trig.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.error_intr_trig_r.key_mode_error_trig.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_intr_trig_r.key_mode_error_trig.load_next) begin + field_storage.intr_block_rf.error_intr_trig_r.key_mode_error_trig.value <= field_combo.intr_block_rf.error_intr_trig_r.key_mode_error_trig.next; + end + end + // Field: hmac_reg.intr_block_rf.error_intr_trig_r.key_zero_error_trig + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_intr_trig_r.key_zero_error_trig.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_intr_trig_r && decoded_req_is_wr) begin // SW write 1 set + next_c = field_storage.intr_block_rf.error_intr_trig_r.key_zero_error_trig.value | (decoded_wr_data[1:1] & decoded_wr_biten[1:1]); + load_next_c = '1; + end else begin // singlepulse clears back to 0 + next_c = '0; + load_next_c = '1; + end + field_combo.intr_block_rf.error_intr_trig_r.key_zero_error_trig.next = next_c; + field_combo.intr_block_rf.error_intr_trig_r.key_zero_error_trig.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.error_intr_trig_r.key_zero_error_trig.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_intr_trig_r.key_zero_error_trig.load_next) begin + field_storage.intr_block_rf.error_intr_trig_r.key_zero_error_trig.value <= field_combo.intr_block_rf.error_intr_trig_r.key_zero_error_trig.next; + end + end + // Field: hmac_reg.intr_block_rf.error_intr_trig_r.error2_trig + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_intr_trig_r.error2_trig.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_intr_trig_r && decoded_req_is_wr) begin // SW write 1 set + next_c = field_storage.intr_block_rf.error_intr_trig_r.error2_trig.value | (decoded_wr_data[2:2] & decoded_wr_biten[2:2]); + load_next_c = '1; + end else begin // singlepulse clears back to 0 + next_c = '0; + load_next_c = '1; + end + field_combo.intr_block_rf.error_intr_trig_r.error2_trig.next = next_c; + field_combo.intr_block_rf.error_intr_trig_r.error2_trig.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.error_intr_trig_r.error2_trig.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_intr_trig_r.error2_trig.load_next) begin + field_storage.intr_block_rf.error_intr_trig_r.error2_trig.value <= field_combo.intr_block_rf.error_intr_trig_r.error2_trig.next; + end + end + // Field: hmac_reg.intr_block_rf.error_intr_trig_r.error3_trig + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_intr_trig_r.error3_trig.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_intr_trig_r && decoded_req_is_wr) begin // SW write 1 set + next_c = field_storage.intr_block_rf.error_intr_trig_r.error3_trig.value | (decoded_wr_data[3:3] & decoded_wr_biten[3:3]); + load_next_c = '1; + end else begin // singlepulse clears back to 0 + next_c = '0; + load_next_c = '1; + end + field_combo.intr_block_rf.error_intr_trig_r.error3_trig.next = next_c; + field_combo.intr_block_rf.error_intr_trig_r.error3_trig.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.error_intr_trig_r.error3_trig.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_intr_trig_r.error3_trig.load_next) begin + field_storage.intr_block_rf.error_intr_trig_r.error3_trig.value <= field_combo.intr_block_rf.error_intr_trig_r.error3_trig.next; + end + end + // Field: hmac_reg.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.notif_intr_trig_r && decoded_req_is_wr) begin // SW write 1 set + next_c = field_storage.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.value | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end else begin // singlepulse clears back to 0 + next_c = '0; + load_next_c = '1; + end + field_combo.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.next = next_c; + field_combo.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.value <= 1'h0; + end else if(field_combo.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.load_next) begin + field_storage.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.value <= field_combo.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.next; + end + end + // Field: hmac_reg.intr_block_rf.key_mode_error_intr_count_r.cnt + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.key_mode_error_intr_count_r.cnt.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.key_mode_error_intr_count_r && decoded_req_is_wr) begin // SW write + next_c = (field_storage.intr_block_rf.key_mode_error_intr_count_r.cnt.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + if(field_storage.intr_block_rf.key_mode_error_intr_count_incr_r.pulse.value) begin // increment + if(((33)'(next_c) + 32'h1) > 32'hffffffff) begin // up-counter saturated + next_c = 32'hffffffff; + end else begin + next_c = next_c + 32'h1; + end + load_next_c = '1; + end + field_combo.intr_block_rf.key_mode_error_intr_count_r.cnt.incrthreshold = (field_storage.intr_block_rf.key_mode_error_intr_count_r.cnt.value >= 32'hffffffff); + field_combo.intr_block_rf.key_mode_error_intr_count_r.cnt.incrsaturate = (field_storage.intr_block_rf.key_mode_error_intr_count_r.cnt.value >= 32'hffffffff); + if(next_c > 32'hffffffff) begin + next_c = 32'hffffffff; + load_next_c = '1; + end + field_combo.intr_block_rf.key_mode_error_intr_count_r.cnt.next = next_c; + field_combo.intr_block_rf.key_mode_error_intr_count_r.cnt.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.error_reset_b) begin + if(~hwif_in.error_reset_b) begin + field_storage.intr_block_rf.key_mode_error_intr_count_r.cnt.value <= 32'h0; + end else if(field_combo.intr_block_rf.key_mode_error_intr_count_r.cnt.load_next) begin + field_storage.intr_block_rf.key_mode_error_intr_count_r.cnt.value <= field_combo.intr_block_rf.key_mode_error_intr_count_r.cnt.next; + end + end + // Field: hmac_reg.intr_block_rf.key_zero_error_intr_count_r.cnt + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.key_zero_error_intr_count_r.cnt.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.key_zero_error_intr_count_r && decoded_req_is_wr) begin // SW write + next_c = (field_storage.intr_block_rf.key_zero_error_intr_count_r.cnt.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + if(field_storage.intr_block_rf.key_zero_error_intr_count_incr_r.pulse.value) begin // increment + if(((33)'(next_c) + 32'h1) > 32'hffffffff) begin // up-counter saturated + next_c = 32'hffffffff; + end else begin + next_c = next_c + 32'h1; + end + load_next_c = '1; + end + field_combo.intr_block_rf.key_zero_error_intr_count_r.cnt.incrthreshold = (field_storage.intr_block_rf.key_zero_error_intr_count_r.cnt.value >= 32'hffffffff); + field_combo.intr_block_rf.key_zero_error_intr_count_r.cnt.incrsaturate = (field_storage.intr_block_rf.key_zero_error_intr_count_r.cnt.value >= 32'hffffffff); + if(next_c > 32'hffffffff) begin + next_c = 32'hffffffff; + load_next_c = '1; + end + field_combo.intr_block_rf.key_zero_error_intr_count_r.cnt.next = next_c; + field_combo.intr_block_rf.key_zero_error_intr_count_r.cnt.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.error_reset_b) begin + if(~hwif_in.error_reset_b) begin + field_storage.intr_block_rf.key_zero_error_intr_count_r.cnt.value <= 32'h0; + end else if(field_combo.intr_block_rf.key_zero_error_intr_count_r.cnt.load_next) begin + field_storage.intr_block_rf.key_zero_error_intr_count_r.cnt.value <= field_combo.intr_block_rf.key_zero_error_intr_count_r.cnt.next; + end + end + // Field: hmac_reg.intr_block_rf.error2_intr_count_r.cnt + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error2_intr_count_r.cnt.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error2_intr_count_r && decoded_req_is_wr) begin // SW write + next_c = (field_storage.intr_block_rf.error2_intr_count_r.cnt.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + if(field_storage.intr_block_rf.error2_intr_count_incr_r.pulse.value) begin // increment + if(((33)'(next_c) + 32'h1) > 32'hffffffff) begin // up-counter saturated + next_c = 32'hffffffff; + end else begin + next_c = next_c + 32'h1; + end + load_next_c = '1; + end + field_combo.intr_block_rf.error2_intr_count_r.cnt.incrthreshold = (field_storage.intr_block_rf.error2_intr_count_r.cnt.value >= 32'hffffffff); + field_combo.intr_block_rf.error2_intr_count_r.cnt.incrsaturate = (field_storage.intr_block_rf.error2_intr_count_r.cnt.value >= 32'hffffffff); + if(next_c > 32'hffffffff) begin + next_c = 32'hffffffff; + load_next_c = '1; + end + field_combo.intr_block_rf.error2_intr_count_r.cnt.next = next_c; + field_combo.intr_block_rf.error2_intr_count_r.cnt.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.error_reset_b) begin + if(~hwif_in.error_reset_b) begin + field_storage.intr_block_rf.error2_intr_count_r.cnt.value <= 32'h0; + end else if(field_combo.intr_block_rf.error2_intr_count_r.cnt.load_next) begin + field_storage.intr_block_rf.error2_intr_count_r.cnt.value <= field_combo.intr_block_rf.error2_intr_count_r.cnt.next; + end + end + // Field: hmac_reg.intr_block_rf.error3_intr_count_r.cnt + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error3_intr_count_r.cnt.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error3_intr_count_r && decoded_req_is_wr) begin // SW write + next_c = (field_storage.intr_block_rf.error3_intr_count_r.cnt.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + if(field_storage.intr_block_rf.error3_intr_count_incr_r.pulse.value) begin // increment + if(((33)'(next_c) + 32'h1) > 32'hffffffff) begin // up-counter saturated + next_c = 32'hffffffff; + end else begin + next_c = next_c + 32'h1; + end + load_next_c = '1; + end + field_combo.intr_block_rf.error3_intr_count_r.cnt.incrthreshold = (field_storage.intr_block_rf.error3_intr_count_r.cnt.value >= 32'hffffffff); + field_combo.intr_block_rf.error3_intr_count_r.cnt.incrsaturate = (field_storage.intr_block_rf.error3_intr_count_r.cnt.value >= 32'hffffffff); + if(next_c > 32'hffffffff) begin + next_c = 32'hffffffff; + load_next_c = '1; + end + field_combo.intr_block_rf.error3_intr_count_r.cnt.next = next_c; + field_combo.intr_block_rf.error3_intr_count_r.cnt.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.error_reset_b) begin + if(~hwif_in.error_reset_b) begin + field_storage.intr_block_rf.error3_intr_count_r.cnt.value <= 32'h0; + end else if(field_combo.intr_block_rf.error3_intr_count_r.cnt.load_next) begin + field_storage.intr_block_rf.error3_intr_count_r.cnt.value <= field_combo.intr_block_rf.error3_intr_count_r.cnt.next; + end + end + // Field: hmac_reg.intr_block_rf.notif_cmd_done_intr_count_r.cnt + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_cmd_done_intr_count_r.cnt.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.notif_cmd_done_intr_count_r && decoded_req_is_wr) begin // SW write + next_c = (field_storage.intr_block_rf.notif_cmd_done_intr_count_r.cnt.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + if(field_storage.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.value) begin // increment + if(((33)'(next_c) + 32'h1) > 32'hffffffff) begin // up-counter saturated + next_c = 32'hffffffff; + end else begin + next_c = next_c + 32'h1; + end + load_next_c = '1; + end + field_combo.intr_block_rf.notif_cmd_done_intr_count_r.cnt.incrthreshold = (field_storage.intr_block_rf.notif_cmd_done_intr_count_r.cnt.value >= 32'hffffffff); + field_combo.intr_block_rf.notif_cmd_done_intr_count_r.cnt.incrsaturate = (field_storage.intr_block_rf.notif_cmd_done_intr_count_r.cnt.value >= 32'hffffffff); + if(next_c > 32'hffffffff) begin + next_c = 32'hffffffff; + load_next_c = '1; + end + field_combo.intr_block_rf.notif_cmd_done_intr_count_r.cnt.next = next_c; + field_combo.intr_block_rf.notif_cmd_done_intr_count_r.cnt.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.notif_cmd_done_intr_count_r.cnt.value <= 32'h0; + end else if(field_combo.intr_block_rf.notif_cmd_done_intr_count_r.cnt.load_next) begin + field_storage.intr_block_rf.notif_cmd_done_intr_count_r.cnt.value <= field_combo.intr_block_rf.notif_cmd_done_intr_count_r.cnt.next; + end + end + // Field: hmac_reg.intr_block_rf.key_mode_error_intr_count_incr_r.pulse + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.key_mode_error_intr_count_incr_r.pulse.value; + load_next_c = '0; + if(field_storage.intr_block_rf.error_intr_trig_r.key_mode_error_trig.value) begin // HW Write - we + next_c = field_storage.intr_block_rf.error_intr_trig_r.key_mode_error_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.error_internal_intr_r.key_mode_error_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end + if(field_storage.intr_block_rf.key_mode_error_intr_count_incr_r.pulse.value) begin // decrement + field_combo.intr_block_rf.key_mode_error_intr_count_incr_r.pulse.underflow = (next_c < (1'h1)); + next_c = next_c - 1'h1; + load_next_c = '1; + end else begin + field_combo.intr_block_rf.key_mode_error_intr_count_incr_r.pulse.underflow = '0; + end + field_combo.intr_block_rf.key_mode_error_intr_count_incr_r.pulse.decrthreshold = (field_storage.intr_block_rf.key_mode_error_intr_count_incr_r.pulse.value <= 1'd0); + field_combo.intr_block_rf.key_mode_error_intr_count_incr_r.pulse.next = next_c; + field_combo.intr_block_rf.key_mode_error_intr_count_incr_r.pulse.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.key_mode_error_intr_count_incr_r.pulse.value <= 1'h0; + end else if(field_combo.intr_block_rf.key_mode_error_intr_count_incr_r.pulse.load_next) begin + field_storage.intr_block_rf.key_mode_error_intr_count_incr_r.pulse.value <= field_combo.intr_block_rf.key_mode_error_intr_count_incr_r.pulse.next; + end + end + // Field: hmac_reg.intr_block_rf.key_zero_error_intr_count_incr_r.pulse + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.key_zero_error_intr_count_incr_r.pulse.value; + load_next_c = '0; + if(field_storage.intr_block_rf.error_intr_trig_r.key_zero_error_trig.value) begin // HW Write - we + next_c = field_storage.intr_block_rf.error_intr_trig_r.key_zero_error_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.error_internal_intr_r.key_zero_error_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end + if(field_storage.intr_block_rf.key_zero_error_intr_count_incr_r.pulse.value) begin // decrement + field_combo.intr_block_rf.key_zero_error_intr_count_incr_r.pulse.underflow = (next_c < (1'h1)); + next_c = next_c - 1'h1; + load_next_c = '1; + end else begin + field_combo.intr_block_rf.key_zero_error_intr_count_incr_r.pulse.underflow = '0; + end + field_combo.intr_block_rf.key_zero_error_intr_count_incr_r.pulse.decrthreshold = (field_storage.intr_block_rf.key_zero_error_intr_count_incr_r.pulse.value <= 1'd0); + field_combo.intr_block_rf.key_zero_error_intr_count_incr_r.pulse.next = next_c; + field_combo.intr_block_rf.key_zero_error_intr_count_incr_r.pulse.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.key_zero_error_intr_count_incr_r.pulse.value <= 1'h0; + end else if(field_combo.intr_block_rf.key_zero_error_intr_count_incr_r.pulse.load_next) begin + field_storage.intr_block_rf.key_zero_error_intr_count_incr_r.pulse.value <= field_combo.intr_block_rf.key_zero_error_intr_count_incr_r.pulse.next; + end + end + // Field: hmac_reg.intr_block_rf.error2_intr_count_incr_r.pulse + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error2_intr_count_incr_r.pulse.value; + load_next_c = '0; + if(field_storage.intr_block_rf.error_intr_trig_r.error2_trig.value) begin // HW Write - we + next_c = field_storage.intr_block_rf.error_intr_trig_r.error2_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.error_internal_intr_r.error2_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end + if(field_storage.intr_block_rf.error2_intr_count_incr_r.pulse.value) begin // decrement + field_combo.intr_block_rf.error2_intr_count_incr_r.pulse.underflow = (next_c < (1'h1)); + next_c = next_c - 1'h1; + load_next_c = '1; + end else begin + field_combo.intr_block_rf.error2_intr_count_incr_r.pulse.underflow = '0; + end + field_combo.intr_block_rf.error2_intr_count_incr_r.pulse.decrthreshold = (field_storage.intr_block_rf.error2_intr_count_incr_r.pulse.value <= 1'd0); + field_combo.intr_block_rf.error2_intr_count_incr_r.pulse.next = next_c; + field_combo.intr_block_rf.error2_intr_count_incr_r.pulse.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.error2_intr_count_incr_r.pulse.value <= 1'h0; + end else if(field_combo.intr_block_rf.error2_intr_count_incr_r.pulse.load_next) begin + field_storage.intr_block_rf.error2_intr_count_incr_r.pulse.value <= field_combo.intr_block_rf.error2_intr_count_incr_r.pulse.next; + end + end + // Field: hmac_reg.intr_block_rf.error3_intr_count_incr_r.pulse + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error3_intr_count_incr_r.pulse.value; + load_next_c = '0; + if(field_storage.intr_block_rf.error_intr_trig_r.error3_trig.value) begin // HW Write - we + next_c = field_storage.intr_block_rf.error_intr_trig_r.error3_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.error_internal_intr_r.error3_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end + if(field_storage.intr_block_rf.error3_intr_count_incr_r.pulse.value) begin // decrement + field_combo.intr_block_rf.error3_intr_count_incr_r.pulse.underflow = (next_c < (1'h1)); + next_c = next_c - 1'h1; + load_next_c = '1; + end else begin + field_combo.intr_block_rf.error3_intr_count_incr_r.pulse.underflow = '0; + end + field_combo.intr_block_rf.error3_intr_count_incr_r.pulse.decrthreshold = (field_storage.intr_block_rf.error3_intr_count_incr_r.pulse.value <= 1'd0); + field_combo.intr_block_rf.error3_intr_count_incr_r.pulse.next = next_c; + field_combo.intr_block_rf.error3_intr_count_incr_r.pulse.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.error3_intr_count_incr_r.pulse.value <= 1'h0; + end else if(field_combo.intr_block_rf.error3_intr_count_incr_r.pulse.load_next) begin + field_storage.intr_block_rf.error3_intr_count_incr_r.pulse.value <= field_combo.intr_block_rf.error3_intr_count_incr_r.pulse.next; + end + end + // Field: hmac_reg.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.value; + load_next_c = '0; + if(field_storage.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.value) begin // HW Write - we + next_c = field_storage.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end + if(field_storage.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.value) begin // decrement + field_combo.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.underflow = (next_c < (1'h1)); + next_c = next_c - 1'h1; + load_next_c = '1; + end else begin + field_combo.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.underflow = '0; + end + field_combo.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.decrthreshold = (field_storage.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.value <= 1'd0); + field_combo.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.next = next_c; + field_combo.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.value <= 1'h0; + end else if(field_combo.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.load_next) begin + field_storage.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.value <= field_combo.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.next; + end + end + + //-------------------------------------------------------------------------- + // Write response + //-------------------------------------------------------------------------- + assign cpuif_wr_ack = decoded_req & decoded_req_is_wr; + // Writes are always granted with no error response + assign cpuif_wr_err = '0; + + //-------------------------------------------------------------------------- + // Readback + //-------------------------------------------------------------------------- + + logic readback_err; + logic readback_done; + logic [31:0] readback_data; + + // Assign readback values to a flattened array + logic [46-1:0][31:0] readback_array; + for(genvar i0=0; i0<2; i0++) begin + assign readback_array[i0*1 + 0][31:0] = (decoded_reg_strb.HMAC512_NAME[i0] && !decoded_req_is_wr) ? hwif_in.HMAC512_NAME[i0].NAME.next : '0; + end + for(genvar i0=0; i0<2; i0++) begin + assign readback_array[i0*1 + 2][31:0] = (decoded_reg_strb.HMAC512_VERSION[i0] && !decoded_req_is_wr) ? hwif_in.HMAC512_VERSION[i0].VERSION.next : '0; + end + assign readback_array[4][0:0] = (decoded_reg_strb.HMAC512_STATUS && !decoded_req_is_wr) ? hwif_in.HMAC512_STATUS.READY.next : '0; + assign readback_array[4][1:1] = (decoded_reg_strb.HMAC512_STATUS && !decoded_req_is_wr) ? hwif_in.HMAC512_STATUS.VALID.next : '0; + assign readback_array[4][31:2] = '0; + for(genvar i0=0; i0<16; i0++) begin + assign readback_array[i0*1 + 5][31:0] = (decoded_reg_strb.HMAC512_TAG[i0] && !decoded_req_is_wr) ? field_storage.HMAC512_TAG[i0].TAG.value : '0; + end + assign readback_array[21][0:0] = (decoded_reg_strb.HMAC512_KV_RD_KEY_CTRL && !decoded_req_is_wr) ? field_storage.HMAC512_KV_RD_KEY_CTRL.read_en.value : '0; + assign readback_array[21][5:1] = (decoded_reg_strb.HMAC512_KV_RD_KEY_CTRL && !decoded_req_is_wr) ? field_storage.HMAC512_KV_RD_KEY_CTRL.read_entry.value : '0; + assign readback_array[21][6:6] = (decoded_reg_strb.HMAC512_KV_RD_KEY_CTRL && !decoded_req_is_wr) ? field_storage.HMAC512_KV_RD_KEY_CTRL.pcr_hash_extend.value : '0; + assign readback_array[21][31:7] = (decoded_reg_strb.HMAC512_KV_RD_KEY_CTRL && !decoded_req_is_wr) ? field_storage.HMAC512_KV_RD_KEY_CTRL.rsvd.value : '0; + assign readback_array[22][0:0] = (decoded_reg_strb.HMAC512_KV_RD_KEY_STATUS && !decoded_req_is_wr) ? hwif_in.HMAC512_KV_RD_KEY_STATUS.READY.next : '0; + assign readback_array[22][1:1] = (decoded_reg_strb.HMAC512_KV_RD_KEY_STATUS && !decoded_req_is_wr) ? field_storage.HMAC512_KV_RD_KEY_STATUS.VALID.value : '0; + assign readback_array[22][9:2] = (decoded_reg_strb.HMAC512_KV_RD_KEY_STATUS && !decoded_req_is_wr) ? hwif_in.HMAC512_KV_RD_KEY_STATUS.ERROR.next : '0; + assign readback_array[22][31:10] = '0; + assign readback_array[23][0:0] = (decoded_reg_strb.HMAC512_KV_RD_BLOCK_CTRL && !decoded_req_is_wr) ? field_storage.HMAC512_KV_RD_BLOCK_CTRL.read_en.value : '0; + assign readback_array[23][5:1] = (decoded_reg_strb.HMAC512_KV_RD_BLOCK_CTRL && !decoded_req_is_wr) ? field_storage.HMAC512_KV_RD_BLOCK_CTRL.read_entry.value : '0; + assign readback_array[23][6:6] = (decoded_reg_strb.HMAC512_KV_RD_BLOCK_CTRL && !decoded_req_is_wr) ? field_storage.HMAC512_KV_RD_BLOCK_CTRL.pcr_hash_extend.value : '0; + assign readback_array[23][31:7] = (decoded_reg_strb.HMAC512_KV_RD_BLOCK_CTRL && !decoded_req_is_wr) ? field_storage.HMAC512_KV_RD_BLOCK_CTRL.rsvd.value : '0; + assign readback_array[24][0:0] = (decoded_reg_strb.HMAC512_KV_RD_BLOCK_STATUS && !decoded_req_is_wr) ? hwif_in.HMAC512_KV_RD_BLOCK_STATUS.READY.next : '0; + assign readback_array[24][1:1] = (decoded_reg_strb.HMAC512_KV_RD_BLOCK_STATUS && !decoded_req_is_wr) ? field_storage.HMAC512_KV_RD_BLOCK_STATUS.VALID.value : '0; + assign readback_array[24][9:2] = (decoded_reg_strb.HMAC512_KV_RD_BLOCK_STATUS && !decoded_req_is_wr) ? hwif_in.HMAC512_KV_RD_BLOCK_STATUS.ERROR.next : '0; + assign readback_array[24][31:10] = '0; + assign readback_array[25][0:0] = (decoded_reg_strb.HMAC512_KV_WR_CTRL && !decoded_req_is_wr) ? field_storage.HMAC512_KV_WR_CTRL.write_en.value : '0; + assign readback_array[25][5:1] = (decoded_reg_strb.HMAC512_KV_WR_CTRL && !decoded_req_is_wr) ? field_storage.HMAC512_KV_WR_CTRL.write_entry.value : '0; + assign readback_array[25][6:6] = (decoded_reg_strb.HMAC512_KV_WR_CTRL && !decoded_req_is_wr) ? field_storage.HMAC512_KV_WR_CTRL.hmac_key_dest_valid.value : '0; + assign readback_array[25][7:7] = (decoded_reg_strb.HMAC512_KV_WR_CTRL && !decoded_req_is_wr) ? field_storage.HMAC512_KV_WR_CTRL.hmac_block_dest_valid.value : '0; + assign readback_array[25][8:8] = (decoded_reg_strb.HMAC512_KV_WR_CTRL && !decoded_req_is_wr) ? field_storage.HMAC512_KV_WR_CTRL.mldsa_seed_dest_valid.value : '0; + assign readback_array[25][9:9] = (decoded_reg_strb.HMAC512_KV_WR_CTRL && !decoded_req_is_wr) ? field_storage.HMAC512_KV_WR_CTRL.ecc_pkey_dest_valid.value : '0; + assign readback_array[25][10:10] = (decoded_reg_strb.HMAC512_KV_WR_CTRL && !decoded_req_is_wr) ? field_storage.HMAC512_KV_WR_CTRL.ecc_seed_dest_valid.value : '0; + assign readback_array[25][11:11] = (decoded_reg_strb.HMAC512_KV_WR_CTRL && !decoded_req_is_wr) ? field_storage.HMAC512_KV_WR_CTRL.aes_key_dest_valid.value : '0; + assign readback_array[25][12:12] = (decoded_reg_strb.HMAC512_KV_WR_CTRL && !decoded_req_is_wr) ? field_storage.HMAC512_KV_WR_CTRL.mlkem_seed_dest_valid.value : '0; + assign readback_array[25][13:13] = (decoded_reg_strb.HMAC512_KV_WR_CTRL && !decoded_req_is_wr) ? field_storage.HMAC512_KV_WR_CTRL.mlkem_msg_dest_valid.value : '0; + assign readback_array[25][14:14] = (decoded_reg_strb.HMAC512_KV_WR_CTRL && !decoded_req_is_wr) ? field_storage.HMAC512_KV_WR_CTRL.dma_data_dest_valid.value : '0; + assign readback_array[25][31:15] = (decoded_reg_strb.HMAC512_KV_WR_CTRL && !decoded_req_is_wr) ? field_storage.HMAC512_KV_WR_CTRL.rsvd.value : '0; + assign readback_array[26][0:0] = (decoded_reg_strb.HMAC512_KV_WR_STATUS && !decoded_req_is_wr) ? hwif_in.HMAC512_KV_WR_STATUS.READY.next : '0; + assign readback_array[26][1:1] = (decoded_reg_strb.HMAC512_KV_WR_STATUS && !decoded_req_is_wr) ? field_storage.HMAC512_KV_WR_STATUS.VALID.value : '0; + assign readback_array[26][9:2] = (decoded_reg_strb.HMAC512_KV_WR_STATUS && !decoded_req_is_wr) ? hwif_in.HMAC512_KV_WR_STATUS.ERROR.next : '0; + assign readback_array[26][31:10] = '0; + assign readback_array[27][0:0] = (decoded_reg_strb.intr_block_rf.global_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.global_intr_en_r.error_en.value : '0; + assign readback_array[27][1:1] = (decoded_reg_strb.intr_block_rf.global_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.global_intr_en_r.notif_en.value : '0; + assign readback_array[27][31:2] = '0; + assign readback_array[28][0:0] = (decoded_reg_strb.intr_block_rf.error_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_en_r.key_mode_error_en.value : '0; + assign readback_array[28][1:1] = (decoded_reg_strb.intr_block_rf.error_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_en_r.key_zero_error_en.value : '0; + assign readback_array[28][2:2] = (decoded_reg_strb.intr_block_rf.error_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_en_r.error2_en.value : '0; + assign readback_array[28][3:3] = (decoded_reg_strb.intr_block_rf.error_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_en_r.error3_en.value : '0; + assign readback_array[28][31:4] = '0; + assign readback_array[29][0:0] = (decoded_reg_strb.intr_block_rf.notif_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_intr_en_r.notif_cmd_done_en.value : '0; + assign readback_array[29][31:1] = '0; + assign readback_array[30][0:0] = (decoded_reg_strb.intr_block_rf.error_global_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_global_intr_r.agg_sts.value : '0; + assign readback_array[30][31:1] = '0; + assign readback_array[31][0:0] = (decoded_reg_strb.intr_block_rf.notif_global_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_global_intr_r.agg_sts.value : '0; + assign readback_array[31][31:1] = '0; + assign readback_array[32][0:0] = (decoded_reg_strb.intr_block_rf.error_internal_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_internal_intr_r.key_mode_error_sts.value : '0; + assign readback_array[32][1:1] = (decoded_reg_strb.intr_block_rf.error_internal_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_internal_intr_r.key_zero_error_sts.value : '0; + assign readback_array[32][2:2] = (decoded_reg_strb.intr_block_rf.error_internal_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_internal_intr_r.error2_sts.value : '0; + assign readback_array[32][3:3] = (decoded_reg_strb.intr_block_rf.error_internal_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_internal_intr_r.error3_sts.value : '0; + assign readback_array[32][31:4] = '0; + assign readback_array[33][0:0] = (decoded_reg_strb.intr_block_rf.notif_internal_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.value : '0; + assign readback_array[33][31:1] = '0; + assign readback_array[34][0:0] = (decoded_reg_strb.intr_block_rf.error_intr_trig_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_trig_r.key_mode_error_trig.value : '0; + assign readback_array[34][1:1] = (decoded_reg_strb.intr_block_rf.error_intr_trig_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_trig_r.key_zero_error_trig.value : '0; + assign readback_array[34][2:2] = (decoded_reg_strb.intr_block_rf.error_intr_trig_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_trig_r.error2_trig.value : '0; + assign readback_array[34][3:3] = (decoded_reg_strb.intr_block_rf.error_intr_trig_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_trig_r.error3_trig.value : '0; + assign readback_array[34][31:4] = '0; + assign readback_array[35][0:0] = (decoded_reg_strb.intr_block_rf.notif_intr_trig_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.value : '0; + assign readback_array[35][31:1] = '0; + assign readback_array[36][31:0] = (decoded_reg_strb.intr_block_rf.key_mode_error_intr_count_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.key_mode_error_intr_count_r.cnt.value : '0; + assign readback_array[37][31:0] = (decoded_reg_strb.intr_block_rf.key_zero_error_intr_count_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.key_zero_error_intr_count_r.cnt.value : '0; + assign readback_array[38][31:0] = (decoded_reg_strb.intr_block_rf.error2_intr_count_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error2_intr_count_r.cnt.value : '0; + assign readback_array[39][31:0] = (decoded_reg_strb.intr_block_rf.error3_intr_count_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error3_intr_count_r.cnt.value : '0; + assign readback_array[40][31:0] = (decoded_reg_strb.intr_block_rf.notif_cmd_done_intr_count_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_cmd_done_intr_count_r.cnt.value : '0; + assign readback_array[41][0:0] = (decoded_reg_strb.intr_block_rf.key_mode_error_intr_count_incr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.key_mode_error_intr_count_incr_r.pulse.value : '0; + assign readback_array[41][31:1] = '0; + assign readback_array[42][0:0] = (decoded_reg_strb.intr_block_rf.key_zero_error_intr_count_incr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.key_zero_error_intr_count_incr_r.pulse.value : '0; + assign readback_array[42][31:1] = '0; + assign readback_array[43][0:0] = (decoded_reg_strb.intr_block_rf.error2_intr_count_incr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error2_intr_count_incr_r.pulse.value : '0; + assign readback_array[43][31:1] = '0; + assign readback_array[44][0:0] = (decoded_reg_strb.intr_block_rf.error3_intr_count_incr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error3_intr_count_incr_r.pulse.value : '0; + assign readback_array[44][31:1] = '0; + assign readback_array[45][0:0] = (decoded_reg_strb.intr_block_rf.notif_cmd_done_intr_count_incr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.value : '0; + assign readback_array[45][31:1] = '0; + + // Reduce the array + always_comb begin + automatic logic [31:0] readback_data_var; + readback_done = decoded_req & ~decoded_req_is_wr; + readback_err = '0; + readback_data_var = '0; + for(int i=0; i<46; i++) readback_data_var |= readback_array[i]; + readback_data = readback_data_var; + end + + assign cpuif_rd_ack = readback_done; + assign cpuif_rd_data = readback_data; + assign cpuif_rd_err = readback_err; + +`CALIPTRA_ASSERT_KNOWN(ERR_HWIF_IN, hwif_in, clk, !hwif_in.error_reset_b) + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/hmac_reg_pkg.sv b/designs/Caliptra/src/caliptra-rtl/hmac_reg_pkg.sv new file mode 100644 index 0000000..a327ad4 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/hmac_reg_pkg.sv @@ -0,0 +1,439 @@ +// Generated by PeakRDL-regblock - A free and open-source SystemVerilog generator +// https://github.com/SystemRDL/PeakRDL-regblock + +package hmac_reg_pkg; + + localparam HMAC_REG_DATA_WIDTH = 32; + localparam HMAC_REG_MIN_ADDR_WIDTH = 12; + + typedef struct packed{ + logic [31:0] next; + } hmac_reg__HMAC512_NAME__NAME__in_t; + + typedef struct packed{ + hmac_reg__HMAC512_NAME__NAME__in_t NAME; + } hmac_reg__HMAC512_NAME__in_t; + + typedef struct packed{ + logic [31:0] next; + } hmac_reg__HMAC512_VERSION__VERSION__in_t; + + typedef struct packed{ + hmac_reg__HMAC512_VERSION__VERSION__in_t VERSION; + } hmac_reg__HMAC512_VERSION__in_t; + + typedef struct packed{ + logic swwe; + } hmac_reg__HMAC512_CTRL__INIT__in_t; + + typedef struct packed{ + logic swwe; + } hmac_reg__HMAC512_CTRL__NEXT__in_t; + + typedef struct packed{ + logic swwe; + } hmac_reg__HMAC512_CTRL__MODE__in_t; + + typedef struct packed{ + logic swwe; + } hmac_reg__HMAC512_CTRL__CSR_MODE__in_t; + + typedef struct packed{ + hmac_reg__HMAC512_CTRL__INIT__in_t INIT; + hmac_reg__HMAC512_CTRL__NEXT__in_t NEXT; + hmac_reg__HMAC512_CTRL__MODE__in_t MODE; + hmac_reg__HMAC512_CTRL__CSR_MODE__in_t CSR_MODE; + } hmac_reg__HMAC512_CTRL__in_t; + + typedef struct packed{ + logic next; + } hmac_reg__HMAC512_STATUS__READY__in_t; + + typedef struct packed{ + logic next; + } hmac_reg__HMAC512_STATUS__VALID__in_t; + + typedef struct packed{ + hmac_reg__HMAC512_STATUS__READY__in_t READY; + hmac_reg__HMAC512_STATUS__VALID__in_t VALID; + } hmac_reg__HMAC512_STATUS__in_t; + + typedef struct packed{ + logic [31:0] next; + logic we; + logic swwel; + logic hwclr; + } hmac_reg__HMAC512_KEY__KEY__in_t; + + typedef struct packed{ + hmac_reg__HMAC512_KEY__KEY__in_t KEY; + } hmac_reg__HMAC512_KEY__in_t; + + typedef struct packed{ + logic [31:0] next; + logic we; + logic swwel; + logic hwclr; + } hmac_reg__HMAC512_BLOCK__BLOCK__in_t; + + typedef struct packed{ + hmac_reg__HMAC512_BLOCK__BLOCK__in_t BLOCK; + } hmac_reg__HMAC512_BLOCK__in_t; + + typedef struct packed{ + logic [31:0] next; + logic hwclr; + } hmac_reg__HMAC512_TAG__TAG__in_t; + + typedef struct packed{ + hmac_reg__HMAC512_TAG__TAG__in_t TAG; + } hmac_reg__HMAC512_TAG__in_t; + + typedef struct packed{ + logic swwe; + logic hwclr; + } kv_read_ctrl_reg__read_en__in_t; + + typedef struct packed{ + logic swwe; + } kv_read_ctrl_reg__read_entry__in_t; + + typedef struct packed{ + logic swwe; + } kv_read_ctrl_reg__pcr_hash_extend__in_t; + + typedef struct packed{ + logic swwe; + } kv_read_ctrl_reg__rsvd__in_t; + + typedef struct packed{ + kv_read_ctrl_reg__read_en__in_t read_en; + kv_read_ctrl_reg__read_entry__in_t read_entry; + kv_read_ctrl_reg__pcr_hash_extend__in_t pcr_hash_extend; + kv_read_ctrl_reg__rsvd__in_t rsvd; + } kv_read_ctrl_reg__in_t; + + typedef struct packed{ + logic next; + } kv_status_reg__READY__in_t; + + typedef struct packed{ + logic hwclr; + logic hwset; + } kv_status_reg__VALID__in_t; + + typedef struct packed{ + logic [7:0] next; + } kv_status_reg__ERROR__in_t; + + typedef struct packed{ + kv_status_reg__READY__in_t READY; + kv_status_reg__VALID__in_t VALID; + kv_status_reg__ERROR__in_t ERROR; + } kv_status_reg__in_t; + + typedef struct packed{ + logic swwe; + logic hwclr; + } kv_write_ctrl_reg__write_en__in_t; + + typedef struct packed{ + logic swwe; + } kv_write_ctrl_reg__write_entry__in_t; + + typedef struct packed{ + logic swwe; + } kv_write_ctrl_reg__hmac_key_dest_valid__in_t; + + typedef struct packed{ + logic swwe; + } kv_write_ctrl_reg__hmac_block_dest_valid__in_t; + + typedef struct packed{ + logic swwe; + } kv_write_ctrl_reg__mldsa_seed_dest_valid__in_t; + + typedef struct packed{ + logic swwe; + } kv_write_ctrl_reg__ecc_pkey_dest_valid__in_t; + + typedef struct packed{ + logic swwe; + } kv_write_ctrl_reg__ecc_seed_dest_valid__in_t; + + typedef struct packed{ + logic swwe; + } kv_write_ctrl_reg__aes_key_dest_valid__in_t; + + typedef struct packed{ + logic swwe; + } kv_write_ctrl_reg__mlkem_seed_dest_valid__in_t; + + typedef struct packed{ + logic swwe; + } kv_write_ctrl_reg__mlkem_msg_dest_valid__in_t; + + typedef struct packed{ + logic swwe; + } kv_write_ctrl_reg__dma_data_dest_valid__in_t; + + typedef struct packed{ + logic swwe; + } kv_write_ctrl_reg__rsvd__in_t; + + typedef struct packed{ + kv_write_ctrl_reg__write_en__in_t write_en; + kv_write_ctrl_reg__write_entry__in_t write_entry; + kv_write_ctrl_reg__hmac_key_dest_valid__in_t hmac_key_dest_valid; + kv_write_ctrl_reg__hmac_block_dest_valid__in_t hmac_block_dest_valid; + kv_write_ctrl_reg__mldsa_seed_dest_valid__in_t mldsa_seed_dest_valid; + kv_write_ctrl_reg__ecc_pkey_dest_valid__in_t ecc_pkey_dest_valid; + kv_write_ctrl_reg__ecc_seed_dest_valid__in_t ecc_seed_dest_valid; + kv_write_ctrl_reg__aes_key_dest_valid__in_t aes_key_dest_valid; + kv_write_ctrl_reg__mlkem_seed_dest_valid__in_t mlkem_seed_dest_valid; + kv_write_ctrl_reg__mlkem_msg_dest_valid__in_t mlkem_msg_dest_valid; + kv_write_ctrl_reg__dma_data_dest_valid__in_t dma_data_dest_valid; + kv_write_ctrl_reg__rsvd__in_t rsvd; + } kv_write_ctrl_reg__in_t; + + typedef struct packed{ + logic hwset; + } hmac_reg__error_intr_t_error2_sts_b1cf2205_error3_sts_74a35378_key_mode_error_sts_f2304c86_key_zero_error_sts_64a18183__key_mode_error_sts_enable_28f0af4b_next_7027a86d_resetsignal_939e99d4__in_t; + + typedef struct packed{ + logic hwset; + } hmac_reg__error_intr_t_error2_sts_b1cf2205_error3_sts_74a35378_key_mode_error_sts_f2304c86_key_zero_error_sts_64a18183__key_zero_error_sts_enable_8d7a01ba_next_938a4efa_resetsignal_939e99d4__in_t; + + typedef struct packed{ + logic hwset; + } hmac_reg__error_intr_t_error2_sts_b1cf2205_error3_sts_74a35378_key_mode_error_sts_f2304c86_key_zero_error_sts_64a18183__error2_sts_enable_0dacf7a6_next_4b5b9e74_resetsignal_939e99d4__in_t; + + typedef struct packed{ + logic hwset; + } hmac_reg__error_intr_t_error2_sts_b1cf2205_error3_sts_74a35378_key_mode_error_sts_f2304c86_key_zero_error_sts_64a18183__error3_sts_enable_fc3af94b_next_c3125d40_resetsignal_939e99d4__in_t; + + typedef struct packed{ + hmac_reg__error_intr_t_error2_sts_b1cf2205_error3_sts_74a35378_key_mode_error_sts_f2304c86_key_zero_error_sts_64a18183__key_mode_error_sts_enable_28f0af4b_next_7027a86d_resetsignal_939e99d4__in_t key_mode_error_sts; + hmac_reg__error_intr_t_error2_sts_b1cf2205_error3_sts_74a35378_key_mode_error_sts_f2304c86_key_zero_error_sts_64a18183__key_zero_error_sts_enable_8d7a01ba_next_938a4efa_resetsignal_939e99d4__in_t key_zero_error_sts; + hmac_reg__error_intr_t_error2_sts_b1cf2205_error3_sts_74a35378_key_mode_error_sts_f2304c86_key_zero_error_sts_64a18183__error2_sts_enable_0dacf7a6_next_4b5b9e74_resetsignal_939e99d4__in_t error2_sts; + hmac_reg__error_intr_t_error2_sts_b1cf2205_error3_sts_74a35378_key_mode_error_sts_f2304c86_key_zero_error_sts_64a18183__error3_sts_enable_fc3af94b_next_c3125d40_resetsignal_939e99d4__in_t error3_sts; + } hmac_reg__error_intr_t_error2_sts_b1cf2205_error3_sts_74a35378_key_mode_error_sts_f2304c86_key_zero_error_sts_64a18183__in_t; + + typedef struct packed{ + logic hwset; + } hmac_reg__notif_intr_t_notif_cmd_done_sts_1c68637e__notif_cmd_done_sts_enable_dabe0b8b_next_540fa3b7__in_t; + + typedef struct packed{ + hmac_reg__notif_intr_t_notif_cmd_done_sts_1c68637e__notif_cmd_done_sts_enable_dabe0b8b_next_540fa3b7__in_t notif_cmd_done_sts; + } hmac_reg__notif_intr_t_notif_cmd_done_sts_1c68637e__in_t; + + typedef struct packed{ + hmac_reg__error_intr_t_error2_sts_b1cf2205_error3_sts_74a35378_key_mode_error_sts_f2304c86_key_zero_error_sts_64a18183__in_t error_internal_intr_r; + hmac_reg__notif_intr_t_notif_cmd_done_sts_1c68637e__in_t notif_internal_intr_r; + } hmac_reg__intr_block_t__in_t; + + typedef struct packed{ + logic reset_b; + logic error_reset_b; + hmac_reg__HMAC512_NAME__in_t [2-1:0]HMAC512_NAME; + hmac_reg__HMAC512_VERSION__in_t [2-1:0]HMAC512_VERSION; + hmac_reg__HMAC512_CTRL__in_t HMAC512_CTRL; + hmac_reg__HMAC512_STATUS__in_t HMAC512_STATUS; + hmac_reg__HMAC512_KEY__in_t [16-1:0]HMAC512_KEY; + hmac_reg__HMAC512_BLOCK__in_t [32-1:0]HMAC512_BLOCK; + hmac_reg__HMAC512_TAG__in_t [16-1:0]HMAC512_TAG; + kv_read_ctrl_reg__in_t HMAC512_KV_RD_KEY_CTRL; + kv_status_reg__in_t HMAC512_KV_RD_KEY_STATUS; + kv_read_ctrl_reg__in_t HMAC512_KV_RD_BLOCK_CTRL; + kv_status_reg__in_t HMAC512_KV_RD_BLOCK_STATUS; + kv_write_ctrl_reg__in_t HMAC512_KV_WR_CTRL; + kv_status_reg__in_t HMAC512_KV_WR_STATUS; + hmac_reg__intr_block_t__in_t intr_block_rf; + } hmac_reg__in_t; + + typedef struct packed{ + logic value; + } hmac_reg__HMAC512_CTRL__INIT__out_t; + + typedef struct packed{ + logic value; + } hmac_reg__HMAC512_CTRL__NEXT__out_t; + + typedef struct packed{ + logic value; + } hmac_reg__HMAC512_CTRL__ZEROIZE__out_t; + + typedef struct packed{ + logic value; + } hmac_reg__HMAC512_CTRL__MODE__out_t; + + typedef struct packed{ + logic value; + } hmac_reg__HMAC512_CTRL__CSR_MODE__out_t; + + typedef struct packed{ + logic value; + } hmac_reg__HMAC512_CTRL__Reserved__out_t; + + typedef struct packed{ + hmac_reg__HMAC512_CTRL__INIT__out_t INIT; + hmac_reg__HMAC512_CTRL__NEXT__out_t NEXT; + hmac_reg__HMAC512_CTRL__ZEROIZE__out_t ZEROIZE; + hmac_reg__HMAC512_CTRL__MODE__out_t MODE; + hmac_reg__HMAC512_CTRL__CSR_MODE__out_t CSR_MODE; + hmac_reg__HMAC512_CTRL__Reserved__out_t Reserved; + } hmac_reg__HMAC512_CTRL__out_t; + + typedef struct packed{ + logic [31:0] value; + } hmac_reg__HMAC512_KEY__KEY__out_t; + + typedef struct packed{ + hmac_reg__HMAC512_KEY__KEY__out_t KEY; + } hmac_reg__HMAC512_KEY__out_t; + + typedef struct packed{ + logic [31:0] value; + } hmac_reg__HMAC512_BLOCK__BLOCK__out_t; + + typedef struct packed{ + hmac_reg__HMAC512_BLOCK__BLOCK__out_t BLOCK; + } hmac_reg__HMAC512_BLOCK__out_t; + + typedef struct packed{ + logic [31:0] value; + } hmac_reg__HMAC512_LFSR_SEED__LFSR_SEED__out_t; + + typedef struct packed{ + hmac_reg__HMAC512_LFSR_SEED__LFSR_SEED__out_t LFSR_SEED; + } hmac_reg__HMAC512_LFSR_SEED__out_t; + + typedef struct packed{ + logic value; + } kv_read_ctrl_reg__read_en__out_t; + + typedef struct packed{ + logic [4:0] value; + } kv_read_ctrl_reg__read_entry__out_t; + + typedef struct packed{ + logic value; + } kv_read_ctrl_reg__pcr_hash_extend__out_t; + + typedef struct packed{ + logic [24:0] value; + } kv_read_ctrl_reg__rsvd__out_t; + + typedef struct packed{ + kv_read_ctrl_reg__read_en__out_t read_en; + kv_read_ctrl_reg__read_entry__out_t read_entry; + kv_read_ctrl_reg__pcr_hash_extend__out_t pcr_hash_extend; + kv_read_ctrl_reg__rsvd__out_t rsvd; + } kv_read_ctrl_reg__out_t; + + typedef struct packed{ + logic value; + } kv_write_ctrl_reg__write_en__out_t; + + typedef struct packed{ + logic [4:0] value; + } kv_write_ctrl_reg__write_entry__out_t; + + typedef struct packed{ + logic value; + } kv_write_ctrl_reg__hmac_key_dest_valid__out_t; + + typedef struct packed{ + logic value; + } kv_write_ctrl_reg__hmac_block_dest_valid__out_t; + + typedef struct packed{ + logic value; + } kv_write_ctrl_reg__mldsa_seed_dest_valid__out_t; + + typedef struct packed{ + logic value; + } kv_write_ctrl_reg__ecc_pkey_dest_valid__out_t; + + typedef struct packed{ + logic value; + } kv_write_ctrl_reg__ecc_seed_dest_valid__out_t; + + typedef struct packed{ + logic value; + } kv_write_ctrl_reg__aes_key_dest_valid__out_t; + + typedef struct packed{ + logic value; + } kv_write_ctrl_reg__mlkem_seed_dest_valid__out_t; + + typedef struct packed{ + logic value; + } kv_write_ctrl_reg__mlkem_msg_dest_valid__out_t; + + typedef struct packed{ + logic value; + } kv_write_ctrl_reg__dma_data_dest_valid__out_t; + + typedef struct packed{ + logic [16:0] value; + } kv_write_ctrl_reg__rsvd__out_t; + + typedef struct packed{ + kv_write_ctrl_reg__write_en__out_t write_en; + kv_write_ctrl_reg__write_entry__out_t write_entry; + kv_write_ctrl_reg__hmac_key_dest_valid__out_t hmac_key_dest_valid; + kv_write_ctrl_reg__hmac_block_dest_valid__out_t hmac_block_dest_valid; + kv_write_ctrl_reg__mldsa_seed_dest_valid__out_t mldsa_seed_dest_valid; + kv_write_ctrl_reg__ecc_pkey_dest_valid__out_t ecc_pkey_dest_valid; + kv_write_ctrl_reg__ecc_seed_dest_valid__out_t ecc_seed_dest_valid; + kv_write_ctrl_reg__aes_key_dest_valid__out_t aes_key_dest_valid; + kv_write_ctrl_reg__mlkem_seed_dest_valid__out_t mlkem_seed_dest_valid; + kv_write_ctrl_reg__mlkem_msg_dest_valid__out_t mlkem_msg_dest_valid; + kv_write_ctrl_reg__dma_data_dest_valid__out_t dma_data_dest_valid; + kv_write_ctrl_reg__rsvd__out_t rsvd; + } kv_write_ctrl_reg__out_t; + + typedef struct packed{ + logic intr; + } hmac_reg__global_intr_t_agg_sts_dd3dcf0a__out_t; + + typedef struct packed{ + logic intr; + } hmac_reg__global_intr_t_agg_sts_e6399b4a__out_t; + + typedef struct packed{ + logic intr; + } hmac_reg__error_intr_t_error2_sts_b1cf2205_error3_sts_74a35378_key_mode_error_sts_f2304c86_key_zero_error_sts_64a18183__out_t; + + typedef struct packed{ + logic intr; + } hmac_reg__notif_intr_t_notif_cmd_done_sts_1c68637e__out_t; + + typedef struct packed{ + hmac_reg__global_intr_t_agg_sts_dd3dcf0a__out_t error_global_intr_r; + hmac_reg__global_intr_t_agg_sts_e6399b4a__out_t notif_global_intr_r; + hmac_reg__error_intr_t_error2_sts_b1cf2205_error3_sts_74a35378_key_mode_error_sts_f2304c86_key_zero_error_sts_64a18183__out_t error_internal_intr_r; + hmac_reg__notif_intr_t_notif_cmd_done_sts_1c68637e__out_t notif_internal_intr_r; + } hmac_reg__intr_block_t__out_t; + + typedef struct packed{ + hmac_reg__HMAC512_CTRL__out_t HMAC512_CTRL; + hmac_reg__HMAC512_KEY__out_t [16-1:0]HMAC512_KEY; + hmac_reg__HMAC512_BLOCK__out_t [32-1:0]HMAC512_BLOCK; + hmac_reg__HMAC512_LFSR_SEED__out_t [12-1:0]HMAC512_LFSR_SEED; + kv_read_ctrl_reg__out_t HMAC512_KV_RD_KEY_CTRL; + kv_read_ctrl_reg__out_t HMAC512_KV_RD_BLOCK_CTRL; + kv_write_ctrl_reg__out_t HMAC512_KV_WR_CTRL; + hmac_reg__intr_block_t__out_t intr_block_rf; + } hmac_reg__out_t; + + typedef enum logic [31:0] { + kv_status_reg__ERROR__kv_error_e__SUCCESS = 'h0, + kv_status_reg__ERROR__kv_error_e__KV_READ_FAIL = 'h1, + kv_status_reg__ERROR__kv_error_e__KV_WRITE_FAIL = 'h2 + } kv_status_reg__ERROR__kv_error_e_e; + + localparam HMAC_REG_ADDR_WIDTH = 32'd12; + +endpackage \ No newline at end of file diff --git a/designs/Caliptra/src/caliptra-rtl/keccak_2share.sv b/designs/Caliptra/src/caliptra-rtl/keccak_2share.sv new file mode 100644 index 0000000..39cbd18 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/keccak_2share.sv @@ -0,0 +1,566 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// This module is the single round keccak permutation module +// It supports Keccak with up to 1600b of state + +`include "caliptra_prim_assert.sv" + +module keccak_2share + import caliptra_prim_mubi_pkg::*; + import lc_ctrl_state_pkg::*; + import lc_ctrl_reg_pkg::*; + import lc_ctrl_pkg::*; +#( + parameter int Width = 1600, // b= {25, 50, 100, 200, 400, 800, 1600} + + // Derived + localparam int W = Width/25, + localparam int L = $clog2(W), + localparam int MaxRound = 12 + 2*L, // Keccak-f only + localparam int RndW = $clog2(MaxRound+1), // Representing up to MaxRound + + // Control parameters + parameter bit EnMasking = 1'b0, // Enable secure hardening + parameter bit ForceRandExt = 1'b0, // 1: Always forward externally provided randomness. + // 0: Switch between external randomness and internal + // intermediate state according to dom_in_rand_ext_i. + localparam int Share = EnMasking ? 2 : 1 +) ( + input clk_i, + input rst_ni, + + input lc_ctrl_pkg::lc_tx_t lc_escalate_en_i, // Used to disable SVAs when escalating. + + input [RndW-1:0] rnd_i, // Current round index + + // Control inputs used when EnMasking = 1. + input mubi4_t phase_sel_i, // Output mux contol + input dom_out_low_i, // DOM multiplier output mux + input dom_in_low_i, // DOM multiplier input mux + input dom_in_rand_ext_i, // DOM multiplier input randomness mux + input dom_update_i, // DOM multiplier pipeline reg write enable + + input [Width/2-1:0] rand_i, // Randomness for remasking. + + // State input and output + input [Width-1:0] s_i [Share], + output logic [Width-1:0] s_o [Share] +); + /////////// + // Types // + /////////// + // x y z + typedef logic [4:0][4:0][W-1:0] box_t; // (x,y,z) state + typedef logic [W-1:0] lane_t; // (z) + typedef logic [4:0] [W-1:0] plane_t; // (x,z) + typedef logic [4:0][4:0] slice_t; // (x,y) + typedef logic [4:0][W-1:0] sheet_t; // (y,z) identical to plane_t + typedef logic [4:0] row_t; // (x) + typedef logic [4:0] col_t; // (y) identical to row_t + + ////////////// + // Keccak_f // + ////////////// + box_t state_in [Share]; + box_t state_out [Share]; + box_t theta_data [Share]; + box_t rho_data [Share]; + box_t pi_data [Share]; + box_t chi_data [Share]; + box_t iota_data [Share]; + + box_t phase1_in [Share]; + box_t phase1_out [Share]; + box_t phase2_in [Share]; + box_t phase2_out [Share]; + + ///////////////// + // Unused nets // + ///////////////// + // Tie off input signals that aren't used in the unmasked implementation. + if (!EnMasking) begin : gen_tie_unused + logic unused_clk; + logic unused_rst_n; + mubi4_t unused_phase_sel; + logic unused_dom_ctrl; + logic [Width/2-1:0] unused_rand; + assign unused_clk = clk_i; + assign unused_rst_n = rst_ni; + assign unused_phase_sel = phase_sel_i; + assign unused_dom_ctrl = + ^{dom_out_low_i, dom_in_low_i, dom_in_rand_ext_i, dom_update_i}; + assign unused_rand = rand_i; + end + + ////////////////////////////////////////////////// + // Input/output type conversion and interfacing // + ////////////////////////////////////////////////// + for (genvar i = 0 ; i < Share ; i++) begin : g_state_inout + assign state_in[i] = bitarray_to_box(s_i[i]); + assign s_o[i] = box_to_bitarray(state_out[i]); + end : g_state_inout + + if (EnMasking) begin : g_2share_data + assign phase1_in = state_in; + assign phase2_in = state_in; + + always_comb begin + unique case (phase_sel_i) + MuBi4False: state_out = phase1_out; + MuBi4True: state_out = phase2_out; + default: state_out = phase1_out; + endcase + end + end else begin : g_single_data + assign phase1_in = state_in; + assign phase2_in = phase1_out; + assign state_out = phase2_out; + end + + ////////////// + // Datapath // + ////////////// + for (genvar i = 0 ; i < Share ; i++) begin : g_datapath + + // Phase 1: + assign theta_data[i] = theta(phase1_in[i]); + // Commented out rho function as vcs complains z-Offset%W isn't constant + // assign rho_data[i] = rho(theta_data[i]); + + assign pi_data[i] = pi(rho_data[i]); + + // Phase 2 (Cycles 1, 2 and 3): + // Chi : See below + // Iota: See below + end : g_datapath + + assign phase1_out = pi_data; + + // Iota adds Round Constants(RC), so only one share should be XORed + if (EnMasking) begin : g_2share_iota + assign iota_data[0] = iota(chi_data[0], rnd_i); + assign iota_data[1] = chi_data[1]; + end else begin : g_single_iota + assign iota_data[0] = iota(chi_data[0], rnd_i); + end + + if (EnMasking) begin : g_2share_chi + // Domain-Oriented Masking + // reference: https://eprint.iacr.org/2017/395.pdf + + localparam int unsigned WSheetHalf = $bits(sheet_t)/2; + logic [4:0][WSheetHalf-1:0] in_prd, out_prd; + + ///////////////////// + // DOM multipliers // + ///////////////////// + + for (genvar x = 0 ; x < 5 ; x++) begin : g_chi_w + localparam int X1 = (x + 1) % 5; + localparam int X2 = (x + 2) % 5; + + sheet_t sheet0[Share]; // Inverted input X1 + sheet_t sheet1[Share]; // X2 + sheet_t sheet2[Share]; // DOM output + + assign sheet0[0] = ~phase2_in[0][X1]; + assign sheet0[1] = phase2_in[1][X1]; + + assign sheet1[0] = phase2_in[0][X2]; + assign sheet1[1] = phase2_in[1][X2]; + + // Convert sheet_t to 1D arrays, one for the upper and lower half lane. + logic [WSheetHalf-1:0] a0_l, a1_l, b0_l, b1_l; + logic [WSheetHalf-1:0] a0_h, a1_h, b0_h, b1_h; + logic [WSheetHalf-1:0] a0, a1, b0, b1, q0, q1; + + assign a0_l = {sheet0[0][0][W/2-1:0], + sheet0[0][1][W/2-1:0], + sheet0[0][2][W/2-1:0], + sheet0[0][3][W/2-1:0], + sheet0[0][4][W/2-1:0]}; + assign a1_l = {sheet0[1][0][W/2-1:0], + sheet0[1][1][W/2-1:0], + sheet0[1][2][W/2-1:0], + sheet0[1][3][W/2-1:0], + sheet0[1][4][W/2-1:0]}; + + assign a0_h = {sheet0[0][0][W-1:W/2], + sheet0[0][1][W-1:W/2], + sheet0[0][2][W-1:W/2], + sheet0[0][3][W-1:W/2], + sheet0[0][4][W-1:W/2]}; + assign a1_h = {sheet0[1][0][W-1:W/2], + sheet0[1][1][W-1:W/2], + sheet0[1][2][W-1:W/2], + sheet0[1][3][W-1:W/2], + sheet0[1][4][W-1:W/2]}; + + assign b0_l = {sheet1[0][0][W/2-1:0], + sheet1[0][1][W/2-1:0], + sheet1[0][2][W/2-1:0], + sheet1[0][3][W/2-1:0], + sheet1[0][4][W/2-1:0]}; + assign b1_l = {sheet1[1][0][W/2-1:0], + sheet1[1][1][W/2-1:0], + sheet1[1][2][W/2-1:0], + sheet1[1][3][W/2-1:0], + sheet1[1][4][W/2-1:0]}; + + assign b0_h = {sheet1[0][0][W-1:W/2], + sheet1[0][1][W-1:W/2], + sheet1[0][2][W-1:W/2], + sheet1[0][3][W-1:W/2], + sheet1[0][4][W-1:W/2]}; + assign b1_h = {sheet1[1][0][W-1:W/2], + sheet1[1][1][W-1:W/2], + sheet1[1][2][W-1:W/2], + sheet1[1][3][W-1:W/2], + sheet1[1][4][W-1:W/2]}; + + // Input muxing + assign a0 = dom_in_low_i ? a0_l : a0_h; + assign a1 = dom_in_low_i ? a1_l : a1_h; + assign b0 = dom_in_low_i ? b0_l : b0_h; + assign b1 = dom_in_low_i ? b1_l : b1_h; + + // Randomness muxing + if (!ForceRandExt) begin : gen_in_prd_mux + // Intermediate results are rotated across rows. The new Row x depends on + // data from Rows x + 1 and x + 2. Hence we don't want to use intermediate + // results from Rows x, x + 1, and x + 2 for remasking. + assign in_prd[x] = dom_in_rand_ext_i ? rand_i[x * WSheetHalf +: WSheetHalf] : + out_prd[rot_int(x, 5)]; + end else begin : gen_no_in_prd_mux + // Always use the externally provided randomness. + assign in_prd[x] = rand_i[x * WSheetHalf +: WSheetHalf]; + // Tie off unused signals. + logic unused_out_prd; + assign unused_out_prd = ^{dom_in_rand_ext_i, out_prd[rot_int(x, 5)]}; + end + + caliptra_prim_dom_and_2share #( + .DW (WSheetHalf), // a half sheet + .Pipeline(1) // Process the full sheet in 3 clock cycles. This reduces + // SCA leakage. + ) u_dom ( + .clk_i, + .rst_ni, + + .a0_i (a0), + .a1_i (a1), + .b0_i (b0), + .b1_i (b1), + .z_valid_i (dom_update_i), + .z_i (in_prd[x]), + .q0_o (q0), + .q1_o (q1), + .prd_o (out_prd[x]) + ); + + // Output conversion from q0, q1 to sheet_t + // For simplicity, we forward the generated lane half to both the upper + // and lower lane halves at this point. The actual output muxing/selection + // happens after the Iota step when generating phase2_out from iota_data + // and state_in below. + assign sheet2[0][4] = {2{q0[W/2*0+:W/2]}}; + assign sheet2[0][3] = {2{q0[W/2*1+:W/2]}}; + assign sheet2[0][2] = {2{q0[W/2*2+:W/2]}}; + assign sheet2[0][1] = {2{q0[W/2*3+:W/2]}}; + assign sheet2[0][0] = {2{q0[W/2*4+:W/2]}}; + + assign sheet2[1][4] = {2{q1[W/2*0+:W/2]}}; + assign sheet2[1][3] = {2{q1[W/2*1+:W/2]}}; + assign sheet2[1][2] = {2{q1[W/2*2+:W/2]}}; + assign sheet2[1][1] = {2{q1[W/2*3+:W/2]}}; + assign sheet2[1][0] = {2{q1[W/2*4+:W/2]}}; + + // Final XOR to generate the output + assign chi_data[0][x] = sheet2[0] ^ phase2_in[0][x]; + assign chi_data[1][x] = sheet2[1] ^ phase2_in[1][x]; + end : g_chi_w + + // Since Chi and thus Iota are separately applied to the lower and upper half + // lanes, we need to forward the input to the other half. + for (genvar x = 0 ; x < 5 ; x++) begin : g_2share_phase2_out_row + for (genvar y = 0 ; y < 5 ; y++) begin : g_2share_phase2_out_col + assign phase2_out[0][x][y] = dom_out_low_i ? + { state_in[0][x][y][W-1:W/2], iota_data[0][x][y][W/2-1:0]} : + {iota_data[0][x][y][W-1:W/2], state_in[0][x][y][W/2-1:0]}; + assign phase2_out[1][x][y] = dom_out_low_i ? + { state_in[1][x][y][W-1:W/2], iota_data[1][x][y][W/2-1:0]} : + {iota_data[1][x][y][W-1:W/2], state_in[1][x][y][W/2-1:0]}; + end + end + + end else begin : g_single_chi + assign chi_data[0] = chi(phase2_in[0]); + assign phase2_out = iota_data; + end + + // Rho ====================================================================== + // As RhoOffset[x][y] is considered as variable int in VCS, + // it is replaced with generate statement. + // Revised to meet verilator lint. Now RhoOffset is 1-D array + localparam int RhoOffset [25] = '{ + //y 0 1 2 3 4 x + 0, 36, 3, 105, 210, // 0: 0 1 2 3 4 + 1, 300, 10, 45, 66, // 1: 5 6 7 8 9 + 190, 6, 171, 15, 253, // 2: 10 11 12 13 14 + 28, 55, 153, 21, 120, // 3: 15 16 17 18 19 + 91, 276, 231, 136, 78 // 4: 20 21 22 23 24 + }; + for (genvar i = 0 ; i < Share ; i++) begin : g_rho + box_t rho_in, rho_out; + assign rho_in = theta_data[i]; + assign rho_data[i] = rho_out; + + for (genvar x = 0 ; x < 5 ; x++) begin : gen_rho_x + for (genvar y = 0 ; y < 5 ; y++) begin : gen_rho_y + localparam int Offset = RhoOffset[5*x+y]%W; + localparam int ShiftAmt = W- Offset; + if (Offset == 0) begin : gen_offset0 + assign rho_out[x][y][W-1:0] = rho_in[x][y][W-1:0]; + end else begin : gen_others + assign rho_out[x][y][W-1:0] = {rho_in[x][y][0+:ShiftAmt], + rho_in[x][y][ShiftAmt+:Offset]}; + end + end + end + end : g_rho + + //////////////// + // Assertions // + //////////////// + + `CALIPTRA_ASSERT_INIT(ValidWidth_A, + EnMasking == 0 && Width inside {25, 50, 100, 200, 400, 800, 1600} || + EnMasking == 1 && Width inside {50, 100, 200, 400, 800, 1600}) + `CALIPTRA_ASSERT_INIT(ValidW_A, W inside {1, 2, 4, 8, 16, 32, 64}) + `CALIPTRA_ASSERT_INIT(ValidL_A, L inside {0, 1, 2, 3, 4, 5, 6}) + `CALIPTRA_ASSERT_INIT(ValidRound_A, MaxRound <= 24) // Keccak-f only + + // phase_sel_i shall stay for two cycle after change to 1. + lc_ctrl_pkg::lc_tx_t unused_lc_sig; + assign unused_lc_sig = lc_escalate_en_i; + if (EnMasking) begin : gen_selperiod_chk + `CALIPTRA_ASSUME(SelStayTwoCycleIfTrue_A, + ($past(phase_sel_i) == MuBi4False) && (phase_sel_i == MuBi4True) + |=> phase_sel_i == MuBi4True, clk_i, !rst_ni || + lc_ctrl_pkg::lc_tx_test_true_loose(lc_escalate_en_i)) + end + + /////////////// + // Functions // + /////////////// + + // Convert bitarray to 3D box + // Please take a look at FIPS PUB 202 + // https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf + // > For all triples (x,y,z) such that 0<=x<5, 0<=y<5, and 0<=z A[x,y,z]=S[w(5y+x)+z] + function automatic box_t bitarray_to_box(logic [Width-1:0] s_in); + automatic box_t box; + for (int y = 0 ; y < 5 ; y++) begin + for (int x = 0 ; x < 5 ; x++) begin + for (int z = 0 ; z < W ; z++) begin + box[x][y][z] = s_in[W*(5*y+x) + z]; + end + end + end + return box; + endfunction : bitarray_to_box + + // Convert 3D cube to bitarray + function automatic logic [Width-1:0] box_to_bitarray(box_t state); + automatic logic [Width-1:0] bitarray; + for (int y = 0 ; y < 5 ; y++) begin + for (int x = 0 ; x < 5 ; x++) begin + for (int z = 0 ; z < W ; z++) begin + bitarray[W*(5*y+x)+z] = state[x][y][z]; + end + end + end + return bitarray; + endfunction : box_to_bitarray + + // Rotate integer indices + function automatic integer rot_int(integer in, integer num); + integer out; + if (in == 0) begin + out = num - 1; + end else begin + out = in - 1; + end + return out; + endfunction + + // Step Mapping ============================================================= + // theta + // XOR each bit in the state with the parity of two columns + // C[x,z] = A[x,0,z] ^ A[x,1,z] ^ A[x,2,z] ^ A[x,3,z] ^ A[x,4,z] + // D[x,z] = C[x-1,z] ^ C[x+1,z-1] + // theta = A[x,y,z] ^ D[x,z] + localparam logic [2:0] ThetaIndexX1 [5] = '{4, 0, 1, 2, 3}; // (x-1)%5 + localparam logic [2:0] ThetaIndexX2 [5] = '{1, 2, 3, 4, 0}; // (x+1)%5 + function automatic box_t theta(box_t state); + plane_t c; + plane_t d; + box_t result; + for (int x = 0 ; x < 5 ; x++) begin + c[x] = state[x][0] ^ state[x][1] ^ state[x][2] ^ state[x][3] ^ state[x][4]; + end + for (int x = 0 ; x < 5 ; x++) begin + for (int z = 0 ; z < W ; z++) begin + logic [$clog2(W)-1:0] index_z; + index_z = (z == 0) ? W-1 : z-1; // (z+1)%W + d[x][z] = c[ThetaIndexX1[x]][z] ^ c[ThetaIndexX2[x]][index_z]; + end + end + for (int x = 0 ; x < 5 ; x++) begin + for (int y = 0 ; y < 5 ; y++) begin + result[x][y] = state[x][y] ^ d[x]; + end + end + return result; + endfunction : theta + + // rho + + // Commented out entire rho function due to VCS elaboration error. + // (z-RhoOffset[x][y]%W) isn't considered as a constant in VCS. + // Even changing it to W-RhoOffset[x][y]%W and assign to ShiftAmt + // creates same error. + + // Offset : Look at Table 2 in FIPS PUB 202 + //localparam int RhoOffset [5][5] = '{ + // //y 0 1 2 3 4 x + // '{ 0, 36, 3, 105, 210},// 0 + // '{ 1, 300, 10, 45, 66},// 1 + // '{ 190, 6, 171, 15, 253},// 2 + // '{ 28, 55, 153, 21, 120},// 3 + // '{ 91, 276, 231, 136, 78} // 4 + //}; + + // rotate bits of each lane by offset + // 1. rho[0,0,z] = A[0,0,z] + // 2. Offset swap + // a. (x,y) := (1,0) + // b. for t [0..23] + // i. rho[x,y,z] = A[x,y,z-(t+1)(t+2)/2] + // ii. (x,y) = (y, (2x+3y)) + //function automatic box_t rho(box_t state); + // box_t result; + // for (int x = 0 ; x < 5 ; x++) begin + // for (int y = 0 ; y < 5 ; y++) begin + // for (int z = 0 ; z < W ; z++) begin + // automatic int index_z; + // index_z = (z-RhoOffset[x][y])%W; + // result[x][y][z] = state[x][y][(z-RhoOffset[x][y])%W]; + // end + // end + // end + // return result; + //endfunction : rho + + // pi + // rearrange the position of lanes + // pi[x,y,z] = state[(x+3y),x,z] + localparam logic [2:0] PiRotate [5][5] = '{ + //y 0 1 2 3 4 x + '{ 0, 3, 1, 4, 2},// 0 + '{ 1, 4, 2, 0, 3},// 1 + '{ 2, 0, 3, 1, 4},// 2 + '{ 3, 1, 4, 2, 0},// 3 + '{ 4, 2, 0, 3, 1} // 4 + }; + function automatic box_t pi(box_t state); + box_t result; + for (int x = 0 ; x < 5 ; x++) begin + for (int y = 0 ; y < 5 ; y++) begin + result[x][y][W-1:0] = state[PiRotate[x][y]][x][W-1:0]; + end + end + return result; + endfunction : pi + + // chi + // chi[x,y,z] = state[x,y,z] ^ ((state[x+1,y,z] ^ 1) & state[x+2,y,z]) + localparam logic [2:0] ChiIndexX1 [5] = '{1, 2, 3, 4, 0}; // (x+1)%5 + localparam logic [2:0] ChiIndexX2 [5] = '{2, 3, 4, 0, 1}; // (x+2)%5 + function automatic box_t chi(box_t state); + box_t result; + for (int x = 0 ; x < 5 ; x++) begin + result[x] = state[x] ^ ((~state[ChiIndexX1[x]]) & state[ChiIndexX2[x]]); + end + return result; + endfunction : chi + + // iota + // XOR (x,y) = (0,0) with Round Constant (RC) + + // RC parameter: Precomputed by util/keccak_rc.py. Only up-to 0..L-1 is used + // RC = '0 + // RC[2**j-1] = rc(j+7*rnd) + // rc(t) = + // 1. t%255 == 0 -> 1 + // 2. R[0:7] = 'b10000000 + // 3. for i = [1..t%255] + // a. R = 0 || R + // b. R[0] = R[0] ^ R[8] + // c. R[4] = R[4] ^ R[8] + // d. R[5] = R[5] ^ R[8] + // e. R[6] = R[6] ^ R[8] + // f. R = R[0:7] + // 4. return R[0] + // RC has L = [0..6] + // for lower L case, only chopping lower part of 64bit RC is sufficient. + localparam logic [63:0] RC [24] = '{ + 64'h 0000_0000_0000_0001, // Round 0 + 64'h 0000_0000_0000_8082, // Round 1 + 64'h 8000_0000_0000_808A, // Round 2 + 64'h 8000_0000_8000_8000, // Round 3 + 64'h 0000_0000_0000_808B, // Round 4 + 64'h 0000_0000_8000_0001, // Round 5 + 64'h 8000_0000_8000_8081, // Round 6 + 64'h 8000_0000_0000_8009, // Round 7 + 64'h 0000_0000_0000_008A, // Round 8 + 64'h 0000_0000_0000_0088, // Round 9 + 64'h 0000_0000_8000_8009, // Round 10 + 64'h 0000_0000_8000_000A, // Round 11 + 64'h 0000_0000_8000_808B, // Round 12 + 64'h 8000_0000_0000_008B, // Round 13 + 64'h 8000_0000_0000_8089, // Round 14 + 64'h 8000_0000_0000_8003, // Round 15 + 64'h 8000_0000_0000_8002, // Round 16 + 64'h 8000_0000_0000_0080, // Round 17 + 64'h 0000_0000_0000_800A, // Round 18 + 64'h 8000_0000_8000_000A, // Round 19 + 64'h 8000_0000_8000_8081, // Round 20 + 64'h 8000_0000_0000_8080, // Round 21 + 64'h 0000_0000_8000_0001, // Round 22 + 64'h 8000_0000_8000_8008 // Round 23 + }; + + // iota: XOR with RC for (x,y) = (0,0) + function automatic box_t iota(box_t state, logic [RndW-1:0] rnd); + box_t result; + result = state; + result[0][0][W-1:0] = state[0][0][W-1:0] ^ RC[rnd][W-1:0]; + + return result; + endfunction : iota + + // Round function : Rnd(A,i_r) + // Not used due to rho function issue described above. + + //function automatic box_t keccak_rnd(box_t state, logic [RndW-1:0] rnd); + // box_t keccak_state; + // keccak_state = iota(chi(pi(rho(theta(state)))), rnd); + // + // return keccak_state; + //endfunction : keccak_rnd + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/keccak_round.sv b/designs/Caliptra/src/caliptra-rtl/keccak_round.sv new file mode 100644 index 0000000..ecfd0aa --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/keccak_round.sv @@ -0,0 +1,614 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Keccak full round logic based on given input `Width` +// e.g. Width 800 requires 22 rounds +// +// This module has two phases: +// 1. Compute Theta, Rho, Pi steps. +// 2. Computes Chi and Iota steps. +// +// If masking is not enabled, the two phases are completed within a single +// clock cycle. +// +// If masking is enabled, the first phase (Phase1) completes in one cycle. +// The second phase then needs three clock cycles to complete: +// 1. In the first clock cycle, the first stage of Chi is computed for the +// first lane halves. +// 2. In the second clock cycle, the module writes the updated first lane +// halves to the state. +// 3. In the third clock cycle, the new second lane halves are written to +// to the state. +// +// To deter SCA, we randomly decide which lane halves to process first on a +// per-round basis. We use additional randomness generated by the PRNG to take +// this decision (rand_aux_i). For more details, refer to the comments inside +// the FSM below. +// +// If masking is enabled, this implementation uses both randomness provided +// from an external PRNG as well as intermediate results for remasking the DOM +// multipliers below. Per clock cycle, 800b of pseudo-random data (PRD) are +// required. A carfully designed schedule ensures to only ever update the input +// data of the DOM multipliers when also providing fresh randomness and vice +// versa. Updating one without the other could lead to undesired SCA leakage. + +`include "caliptra_prim_assert.sv" + +module keccak_round + import caliptra_prim_mubi_pkg::*; + import lc_ctrl_state_pkg::*; + import lc_ctrl_reg_pkg::*; + import lc_ctrl_pkg::*; +#( + parameter int Width = 1600, // b= {25, 50, 100, 200, 400, 800, 1600} + + // Derived + localparam int W = Width/25, + localparam int L = $clog2(W), + localparam int MaxRound = 12 + 2*L, // Keccak-f only + localparam int RndW = $clog2(MaxRound+1), // Representing up to MaxRound-1 + + // Feed parameters + parameter int DInWidth = 64, // currently only 64bit supported + localparam int DInEntry = Width / DInWidth, + localparam int DInAddr = $clog2(DInEntry), + + // Control parameters + parameter bit EnMasking = 1'b0, // Enable SCA hardening, requires Width >= 50 + parameter bit ForceRandExt = 1'b0, // 1: Always forward externally provided randomness. + // 0: Switch between external randomness and internal + // intermediate state according to schedule. + localparam int Share = EnMasking ? 2 : 1 +) ( + input clk_i, + input rst_ni, + + // Message Feed + input valid_i, + input [DInAddr-1:0] addr_i, + input [DInWidth-1:0] data_i [Share], + output ready_o, + + // In-process control + input run_i, // Pulse signal to initiates Keccak full round + input rand_valid_i, + input rand_early_i, + input [Width/2-1:0] rand_data_i, + input rand_aux_i, + output logic rand_update_o, + output logic rand_consumed_o, + + output logic complete_o, // Indicates full round is done + + // State out. This can be used as Digest + output logic [Width-1:0] state_o [Share], + + // Life cycle + input lc_ctrl_pkg::lc_tx_t lc_escalate_en_i, + + // Errors: + // sparse_fsm_error: Checking if FSM state falls into unknown value + output logic sparse_fsm_error_o, + // round_count_error: caliptra_prim_count checks round value consistency + output logic round_count_error_o, + // rst_storage_error: check if reset signal asserted out of the + // permitted window + output logic rst_storage_error_o, + + input caliptra_prim_mubi_pkg::mubi4_t clear_i // Clear internal state to '0 +); + + import sha3_pkg::*; + + ///////////////////// + // Control signals // + ///////////////////// + + // Update storage register + logic update_storage; + + // Reset the storage to 0 to initiate new Hash operation + logic rst_storage; + + // XOR message into storage register + // It only does based on the given DInWidth. + // If DInWidth < Width, it takes multiple cycles to XOR all message + logic xor_message; + + // Select Keccak_p datapath + // 0: Select Phase1 (Theta -> Rho -> Pi) + // 1: Select Phase2 (Chi -> Iota) + // `phase_sel` needs to be asserted until the Chi stage is consumed, + mubi4_t phase_sel; + + // DOM multiplier input/output mux control + // 0: first compute upper, then lower lane halves + // 1: first compute lower, then upper lane halves + logic low_then_high_d, low_then_high_q; + // 0: drive/select upper lane halves + // 1: drive/select lower lane halves + logic dom_out_low_d, dom_out_low_q; + logic dom_in_low_d, dom_in_low_q; + // 0: forward external randomness input + // 1: forward partial intermediate results + logic dom_in_rand_ext_d, dom_in_rand_ext_q; + // 0: keep current intermediate results in pipeline registers + // 1: latch new intermediate results into pipeline registers + logic dom_update; + + // Increase/ Reset Round number + logic inc_rnd_num; + logic rst_rnd_num; + + // Round reaches end + // This signal indicates the round reaches desired number, which is MaxRound -1. + // MaxRound is dependant on the Width. In case of SHA3/SHAKE, MaxRound is 24. + logic rnd_eq_end; + + // Complete of Keccak_f + // State machine asserts `complete_d` when it reaches at the end of round and + // operation (Phase3 if Masked). The stage, the storage still doesn't have + // the valid states. So precisely it is not completed yet. + // State generated `complete_d` is latched with the clock and creates a pulse + // signal one cycle later. The signal is the indication of completion. + // + // Intentionally removed any intermediate step (so called StComplete) in order + // to save a clock to proceeds next round. + logic complete_d; + + ////////////////////// + // Datapath Signals // + ////////////////////// + + // Single round keccak output data + logic [Width-1:0] keccak_out [Share]; + + // Keccak Round indicator: range from 0 .. MaxRound + logic [RndW-1:0] round; + + // Random value and valid signal used in Keccak_p + logic keccak_rand_update; + logic keccak_rand_consumed; + logic [Width/2-1:0] keccak_rand_data; + + ////////////////////// + // Keccak Round FSM // + ////////////////////// + + // state inputs + assign rnd_eq_end = (int'(round) == MaxRound - 1); + + keccak_st_e keccak_st, keccak_st_d; + `CALIPTRA_PRIM_FLOP_SPARSE_FSM(u_state_regs, keccak_st_d, keccak_st, keccak_st_e, KeccakStIdle) + + // Next state logic and output logic + // SEC_CM: FSM.SPARSE + always_comb begin + // Default values + keccak_st_d = keccak_st; + + xor_message = 1'b 0; + update_storage = 1'b 0; + rst_storage = 1'b 0; + + inc_rnd_num = 1'b 0; + rst_rnd_num = 1'b 0; + + keccak_rand_update = 1'b 0; + keccak_rand_consumed = 1'b 0; + + phase_sel = MuBi4False; + low_then_high_d = low_then_high_q; + dom_in_low_d = dom_in_low_q; + dom_in_rand_ext_d = dom_in_rand_ext_q; + dom_update = 1'b 0; + + complete_d = 1'b 0; + + sparse_fsm_error_o = 1'b 0; + + unique case (keccak_st) + KeccakStIdle: begin + if (valid_i) begin + // State machine allows Sponge Absorbing only in Idle state. + keccak_st_d = KeccakStIdle; + + xor_message = 1'b 1; + update_storage = 1'b 1; + end else if (caliptra_prim_mubi_pkg::mubi4_test_true_strict(clear_i)) begin + // Opt1. State machine allows resetting the storage only in Idle + // Opt2. storage resets regardless of states but clear_i + // Both are added in the design at this time. Will choose the + // direction later. + keccak_st_d = KeccakStIdle; + + rst_storage = 1'b 1; + end else if (EnMasking && run_i) begin + // Masked version of Keccak handling + keccak_st_d = KeccakStPhase1; + + // Drive DOM multiplier I/O mux signals for Phase 1. + dom_in_low_d = low_then_high_q; + dom_in_rand_ext_d = 1'b 0; + end else if (!EnMasking && run_i) begin + // Unmasked version of Keccak handling + keccak_st_d = KeccakStActive; + end else begin + keccak_st_d = KeccakStIdle; + end + end + + KeccakStActive: begin + // Run Keccak single round logic until it reaches MaxRound - 1 + update_storage = 1'b 1; + + if (rnd_eq_end) begin + keccak_st_d = KeccakStIdle; + + rst_rnd_num = 1'b 1; + complete_d = 1'b 1; + end else begin + keccak_st_d = KeccakStActive; + + inc_rnd_num = 1'b 1; + end + end + + KeccakStPhase1: begin + // Compute Theta, Rho, Pi - The DOM multipliers are not evaluated at + // all: their inputs are driven by the first lane halves (same values + // as in Phase2Cycle3 of the last round). Also, the intermediate + // results we already had in Phase2Cycle3 didn't change. + phase_sel = MuBi4False; + dom_update = 1'b 0; + + // Only update the state and move on once we know the auxiliary + // randomness required for Phase2 will be available in the next clock + // cycle. + // + // It's important that the DOM multipliers inside keccak_2share are + // presented the new state (updated with update_storage) at the same + // time as the new randomness (updated with rand_update_o). Otherwise, + // stale entropy is paired with fresh data or vice versa. This could + // lead to undesired SCA leakage. + if (rand_early_i || rand_valid_i) begin + keccak_st_d = KeccakStPhase2Cycle1; + update_storage = 1'b 1; + keccak_rand_update = 1'b 1; + + // Update lane halves processing order for this round. + low_then_high_d = rand_aux_i; + + // Drive DOM multiplier I/O mux signals for next phase. + dom_in_low_d = low_then_high_d; + dom_in_rand_ext_d = 1'b 1; + end else begin + keccak_st_d = KeccakStPhase1; + end + end + + KeccakStPhase2Cycle1: begin + // Compute first stage of Chi for first lane halves using the DOM + // multipliers. Use the fresh randomness provided by the PRNG for + // remasking. + phase_sel = MuBi4True; + dom_update = 1'b 1; + + // Trigger randomness update for next cycle. + // It's important that the DOM multipliers inside keccak_2share are + // presented the second lane halves at the same time as the new + // randomness (updated with rand_update_o). Otherwise, stale entropy + // is paired with fresh data or vice versa. This could lead to + // undesired SCA leakage. + keccak_rand_update = 1'b 1; + + // Unconditionally move to next phase/cycle. + keccak_st_d = KeccakStPhase2Cycle2; + + // Drive DOM multiplier I/O mux signals for next phase. + dom_in_low_d = ~low_then_high_q; + dom_in_rand_ext_d = 1'b 1; + end + + KeccakStPhase2Cycle2: begin + // Chi Stage 1 for second lane halves. + // Chi Stage 2 and Iota for first lane halves. + // Compute second stage of Chi and Iota for first lane halves. + // Compute first stage of Chi for second lane halves. Use the fresh + // randomness provided by the PRNG for remasking the DOM multipliers. + phase_sel = MuBi4True; + dom_update = 1'b 1; + + // Trigger randomness update for next cycle. + // It's important that the DOM multipliers inside keccak_2share are + // presented the updated state at the same as the new randomness + // (updated with rand_update_o) - even if the DOM multipliers don't + // update the pipeline registers in the next cycle. Otherwise, stale + // entropy is paired with fresh data or vice versa. This could lead to + // undesired SCA leakage. + keccak_rand_update = 1'b 1; + + // Trigger auxiliary randomness update for next round. The rand_aux_i + // signal is actually going to change in 2 clock cycles from now + // (Phase1) based on the PRNG output in the next cycle (Phase2Cycle3) + // in which the DOM multipliers don't update the pipeline registers. + keccak_rand_consumed = 1'b 1; + + // Update first lane halves. + update_storage = 1'b 1; + + // Unconditionally move to next phase/cycle. + keccak_st_d = KeccakStPhase2Cycle3; + + // Drive DOM multiplier I/O mux signals for next phase. + dom_in_low_d = low_then_high_q; + dom_in_rand_ext_d = 1'b 0; + end + + KeccakStPhase2Cycle3: begin + // Compute second stage of Chi and Iota for second lane halves. + // Feed again first lane halves to DOM multiplier inputs (now + // the updated values become visible) together with intermediate + // results of Phase2Cycle2. Don't update the register stage inside + // the DOM multipliers. + phase_sel = MuBi4True; + dom_update = 1'b 0; + + // Update second lane halves. + // We don't need fresh randomness for the next cycle as the DOM + // multipliers inside keccak_2share will keep seeing the first + // lane halves in the next cycle. If we updated the randomness, + // old data got combined with frash randomness which is not + // desirable as it could lead to SCA leakage. + update_storage = 1'b 1; + + if (rnd_eq_end) begin + // We're done. + keccak_st_d = KeccakStIdle; + + rst_rnd_num = 1'b 1; + complete_d = 1'b 1; + end else begin + // Continue to the next round. + keccak_st_d = KeccakStPhase1; + + inc_rnd_num = 1'b 1; + + // Drive DOM multiplier I/O mux signals for next phase. + dom_in_low_d = low_then_high_q; + dom_in_rand_ext_d = 1'b 0; + end + end + + KeccakStError: begin + keccak_st_d = KeccakStError; + end + + KeccakStTerminalError: begin + //this state is terminal + keccak_st_d = keccak_st; + sparse_fsm_error_o = 1'b 1; + end + + default: begin + keccak_st_d = KeccakStTerminalError; + sparse_fsm_error_o = 1'b 1; + end + endcase + + // SEC_CM: FSM.GLOBAL_ESC, FSM.LOCAL_ESC + // Unconditionally jump into the terminal error state + // if the life cycle controller triggers an escalation. + if (lc_ctrl_pkg::lc_tx_test_true_loose(lc_escalate_en_i)) begin + keccak_st_d = KeccakStTerminalError; + end + end + + // When taking the lower lane halves in, the upper lane halves are output and + // vice versa. + assign dom_out_low_d = ~dom_in_low_d; + + if (EnMasking) begin : gen_regs_dom_ctrl + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + low_then_high_q <= 1'b 0; + dom_out_low_q <= 1'b 0; + dom_in_low_q <= 1'b 0; + end else begin + low_then_high_q <= low_then_high_d; + dom_out_low_q <= dom_out_low_d; + dom_in_low_q <= dom_in_low_d; + end + end + + if (!ForceRandExt) begin : gen_reg_dom_in_rand_ext + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + dom_in_rand_ext_q <= 1'b 0; + end else begin + dom_in_rand_ext_q <= dom_in_rand_ext_d; + end + end + end else begin : gen_force_dom_in_rand_ext + // Always forward the externally provided randomness. + assign dom_in_rand_ext_q = 1'b 1; + // Tie off unused signals. + logic unused_dom_in_rand_ext; + assign unused_dom_in_rand_ext = dom_in_rand_ext_d; + end + end else begin : gen_no_regs_dom_ctrl + logic unused_dom_ctrl; + assign unused_dom_ctrl = + ^{low_then_high_d, dom_out_low_d, dom_in_low_d, dom_in_rand_ext_d}; + assign low_then_high_q = 1'b 0; + assign dom_out_low_q = 1'b 0; + assign dom_in_low_q = 1'b 0; + assign dom_in_rand_ext_q = 1'b 0; + end + + // Ready indicates the keccak_round is able to receive new message. + // While keccak_round is processing the data, it blocks the new message to be + // XORed into the current state. + assign ready_o = (keccak_st == KeccakStIdle) ? 1'b 1 : 1'b 0; + + //////////////////////////// + // Keccak state registers // + //////////////////////////// + + // SEC_CM: LOGIC.INTEGRITY + logic rst_n; + caliptra_prim_sec_anchor_buf #( + .Width(1) + ) u_caliptra_prim_sec_anchor_buf ( + .in_i(rst_ni), + .out_o(rst_n) + ); + + logic [Width-1:0] storage [Share]; + logic [Width-1:0] storage_d [Share]; + always_ff @(posedge clk_i or negedge rst_n) begin + if (!rst_n) begin + storage <= '{default:'0}; + end else if (rst_storage) begin + storage <= '{default:'0}; + end else if (update_storage) begin + storage <= storage_d; + end + end + + assign state_o = storage; + + // Storage register input + // The incoming message is XORed with the existing storage registers. + // The logic can accept not a block size incoming message chunk but + // the size defined in `DInWidth` parameter with its position. + + always_comb begin + storage_d = keccak_out; + if (xor_message) begin + for (int j = 0 ; j < Share ; j++) begin + for (int unsigned i = 0 ; i < DInEntry ; i++) begin + // ICEBOX(#18029): handle If Width is not integer divisable by DInWidth + // Currently it is not allowed to have partial write + // Please see the Assertion `WidthDivisableByDInWidth_A` + if (addr_i == i[DInAddr-1:0]) begin + storage_d[j][i*DInWidth+:DInWidth] = + storage[j][i*DInWidth+:DInWidth] ^ data_i[j]; + end else begin + storage_d[j][i*DInWidth+:DInWidth] = storage[j][i*DInWidth+:DInWidth]; + end + end // for i + end // for j + end // if xor_message + end + + // Check the rst_storage integrity + logic rst_storage_error; + + always_comb begin : chk_rst_storage + rst_storage_error = 1'b 0; + + if (rst_storage) begin + // FSM should be in KeccakStIdle and clear_i should be high + if ((keccak_st != KeccakStIdle) || + caliptra_prim_mubi_pkg::mubi4_test_false_loose(clear_i)) begin + rst_storage_error = 1'b 1; + end + end + end : chk_rst_storage + + assign rst_storage_error_o = rst_storage_error ; + + ////////////// + // Datapath // + ////////////// + keccak_2share #( + .Width(Width), + .EnMasking(EnMasking), + .ForceRandExt(ForceRandExt) + ) u_keccak_p ( + .clk_i, + .rst_ni, + + .lc_escalate_en_i, + + .rnd_i(round), + + .phase_sel_i (phase_sel), + .dom_out_low_i (dom_out_low_q), + .dom_in_low_i (dom_in_low_q), + .dom_in_rand_ext_i(dom_in_rand_ext_q), + .dom_update_i (dom_update), + + .rand_i(keccak_rand_data), + + .s_i(storage), + .s_o(keccak_out) + ); + + // keccak entropy handling + assign rand_update_o = keccak_rand_update; + assign rand_consumed_o = keccak_rand_consumed; + + assign keccak_rand_data = rand_data_i; + + // Round number + // This primitive is used to place a hardened counter + // SEC_CM: CTR.REDUN + caliptra_prim_count #( + .Width(RndW) + ) u_round_count ( + .clk_i, + .rst_ni, + .clr_i(rst_rnd_num), + .set_i(1'b0), + .set_cnt_i('0), + .incr_en_i(inc_rnd_num), + .decr_en_i(1'b0), + .step_i(RndW'(1)), + .commit_i(1'b1), + .cnt_o(round), + .cnt_after_commit_o(), + .err_o(round_count_error_o) + ); + + // completion signal + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + complete_o <= 1'b 0; + end else begin + complete_o <= complete_d; + end + end + + //////////////// + // Assertions // + //////////////// + + // Only allow `DInWidth` that `Width` is integer divisable by `DInWidth` + `CALIPTRA_ASSERT_INIT(WidthDivisableByDInWidth_A, (Width % DInWidth) == 0) + + // If `run_i` triggerred, it shall complete + //`CALIPTRA_ASSERT(RunResultComplete_A, run_i ##[MaxRound:] complete_o, clk_i, !rst_ni) + + // valid_i and run_i cannot be asserted at the same time + `CALIPTRA_ASSUME(OneHot0ValidAndRun_A, $onehot0({valid_i, run_i}), clk_i, !rst_ni) + + // valid_i, run_i only asserted in Idle state + `CALIPTRA_ASSUME(ValidRunAssertStIdle_A, valid_i || run_i |-> keccak_st == KeccakStIdle, clk_i, !rst_ni) + + // clear_i is assumed to be asserted in Idle state + `CALIPTRA_ASSUME(ClearAssertStIdle_A, + caliptra_prim_mubi_pkg::mubi4_test_true_strict(clear_i) + |-> keccak_st == KeccakStIdle, clk_i, !rst_ni) + + // EnMasking controls the valid states + if (EnMasking) begin : gen_mask_st_chk + `CALIPTRA_ASSERT(EnMaskingValidStates_A, keccak_st != KeccakStActive, clk_i, !rst_ni) + end else begin : gen_unmask_st_chk + `CALIPTRA_ASSERT(UnmaskValidStates_A, !(keccak_st + inside {KeccakStPhase1, KeccakStPhase2Cycle1, KeccakStPhase2Cycle2, KeccakStPhase2Cycle3}), + clk_i, !rst_ni) + end +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/keymgr_pkg.sv b/designs/Caliptra/src/caliptra-rtl/keymgr_pkg.sv new file mode 100644 index 0000000..560a023 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/keymgr_pkg.sv @@ -0,0 +1,19 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// key manager package +// + +package keymgr_pkg; + + parameter int KeyWidth = 256; + parameter int Shares = 2; // number of key shares + + // Key connection to various symmetric modules + typedef struct packed { + logic valid; + logic [Shares-1:0][KeyWidth-1:0] key; + } hw_key_req_t; + +endpackage : keymgr_pkg diff --git a/designs/Caliptra/src/caliptra-rtl/keyvault_cov_if.sv b/designs/Caliptra/src/caliptra-rtl/keyvault_cov_if.sv new file mode 100644 index 0000000..a284993 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/keyvault_cov_if.sv @@ -0,0 +1,214 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. + +// This file contains cross coverage for keyvault at the dut level +// This interface is instantiated in uvmf_kv for coverage during randomized UVM tests + +`ifndef VERILATOR + +interface keyvault_cov_if + import kv_defines_pkg::*; + ( + //Keyvault IO + input logic clk, + input logic rst_b, + input logic core_only_rst_b, + input logic cptra_pwrgood, + input logic debugUnlock_or_scan_mode_switch, + input logic cptra_in_debug_scan_mode +); + + //Intermediate wires + logic [KV_NUM_KEYS-1:0] key_ctrl_lock_wr; + logic [KV_NUM_KEYS-1:0] key_ctrl_lock_use; + logic [KV_NUM_KEYS-1:0] key_ctrl_clear; + + logic clear_secrets_wr; + logic clear_secrets_sel; + logic [KV_NUM_WRITE-1:0] kv_write_en; + logic ahb_write, ahb_read; + + //Assign clear and locks of each KEY_CTRL reg to corresponding bit in the intermediate bus + generate + for(genvar i = 0; i < KV_NUM_KEYS; i++) begin + assign key_ctrl_lock_wr[i] = kv.kv_reg_hwif_out.KEY_CTRL[i].lock_wr; + assign key_ctrl_lock_use[i] = kv.kv_reg_hwif_out.KEY_CTRL[i].lock_use; + assign key_ctrl_clear[i] = kv.kv_reg_hwif_out.KEY_CTRL[i].clear; + end + endgenerate + + //CLEAR_SECRETS + assign clear_secrets_wr = kv.kv_reg_hwif_out.CLEAR_SECRETS.wr_debug_values.value; + assign clear_secrets_sel = kv.kv_reg_hwif_out.CLEAR_SECRETS.sel_debug_value.value; + + //Crypto interface write_en + generate + for(genvar client = 0; client < KV_NUM_WRITE; client++) begin + assign kv_write_en[client] = kv.kv_write[client].write_en; + end + endgenerate + + //AHB signals + assign ahb_write = kv.kv_ahb_slv1.dv & kv.kv_ahb_slv1.write; + assign ahb_read = kv.kv_ahb_slv1.dv & ~kv.kv_ahb_slv1.write; + + covergroup keyvault_top_cov_grp @(posedge clk); + option.per_instance = 1; + debug: coverpoint cptra_in_debug_scan_mode; //debugUnlock_or_scan_mode_switch; + + //Note: Bit transitions and values for lock_wr, lock_use and clear are covered + //in UVM reg coverage. This coverpoint bins the lock/clear bus so that + //they can be used to cross with other signals. Intention is to cover scenarios of debug/scan/clear_secrets events + //while key_ctrl regs have multiple lock/clear bits set and the appropriate entries are cleared. + lock_wr: coverpoint key_ctrl_lock_wr { + wildcard bins zero = {24'b???????????????????????1} iff ($countones(key_ctrl_lock_wr) > 1); + wildcard bins one = {24'b??????????????????????1?} iff ($countones(key_ctrl_lock_wr) > 1); + wildcard bins two = {24'b?????????????????????1??} iff ($countones(key_ctrl_lock_wr) > 1); + wildcard bins three = {24'b????????????????????1???} iff ($countones(key_ctrl_lock_wr) > 1); + wildcard bins four = {24'b???????????????????1????} iff ($countones(key_ctrl_lock_wr) > 1); + wildcard bins five = {24'b??????????????????1?????} iff ($countones(key_ctrl_lock_wr) > 1); + wildcard bins six = {24'b?????????????????1??????} iff ($countones(key_ctrl_lock_wr) > 1); + wildcard bins seven = {24'b????????????????1???????} iff ($countones(key_ctrl_lock_wr) > 1); + wildcard bins eight = {24'b???????????????1????????} iff ($countones(key_ctrl_lock_wr) > 1); + wildcard bins nine = {24'b??????????????1?????????} iff ($countones(key_ctrl_lock_wr) > 1); + wildcard bins ten = {24'b?????????????1??????????} iff ($countones(key_ctrl_lock_wr) > 1); + wildcard bins eleven = {24'b????????????1???????????} iff ($countones(key_ctrl_lock_wr) > 1); + wildcard bins twelve = {24'b???????????1????????????} iff ($countones(key_ctrl_lock_wr) > 1); + wildcard bins thirteen = {24'b??????????1?????????????} iff ($countones(key_ctrl_lock_wr) > 1); + wildcard bins fourteen = {24'b?????????1??????????????} iff ($countones(key_ctrl_lock_wr) > 1); + wildcard bins fifteen = {24'b????????1???????????????} iff ($countones(key_ctrl_lock_wr) > 1); + wildcard bins sixteen = {24'b???????1????????????????} iff ($countones(key_ctrl_lock_wr) > 1); + wildcard bins seventeen = {24'b??????1?????????????????} iff ($countones(key_ctrl_lock_wr) > 1); + wildcard bins eighteen = {24'b?????1??????????????????} iff ($countones(key_ctrl_lock_wr) > 1); + wildcard bins nineteen = {24'b????1???????????????????} iff ($countones(key_ctrl_lock_wr) > 1); + wildcard bins twenty = {24'b???1????????????????????} iff ($countones(key_ctrl_lock_wr) > 1); + wildcard bins twenty_one = {24'b??1?????????????????????} iff ($countones(key_ctrl_lock_wr) > 1); + wildcard bins twenty_two = {24'b?1??????????????????????} iff ($countones(key_ctrl_lock_wr) > 1); + wildcard bins twenty_three = {24'b1???????????????????????} iff ($countones(key_ctrl_lock_wr) > 1); + } + lock_use: coverpoint key_ctrl_lock_use { + wildcard bins zero = {24'b???????????????????????1} iff ($countones(key_ctrl_lock_use) > 1); + wildcard bins one = {24'b??????????????????????1?} iff ($countones(key_ctrl_lock_use) > 1); + wildcard bins two = {24'b?????????????????????1??} iff ($countones(key_ctrl_lock_use) > 1); + wildcard bins three = {24'b????????????????????1???} iff ($countones(key_ctrl_lock_use) > 1); + wildcard bins four = {24'b???????????????????1????} iff ($countones(key_ctrl_lock_use) > 1); + wildcard bins five = {24'b??????????????????1?????} iff ($countones(key_ctrl_lock_use) > 1); + wildcard bins six = {24'b?????????????????1??????} iff ($countones(key_ctrl_lock_use) > 1); + wildcard bins seven = {24'b????????????????1???????} iff ($countones(key_ctrl_lock_use) > 1); + wildcard bins eight = {24'b???????????????1????????} iff ($countones(key_ctrl_lock_use) > 1); + wildcard bins nine = {24'b??????????????1?????????} iff ($countones(key_ctrl_lock_use) > 1); + wildcard bins ten = {24'b?????????????1??????????} iff ($countones(key_ctrl_lock_use) > 1); + wildcard bins eleven = {24'b????????????1???????????} iff ($countones(key_ctrl_lock_use) > 1); + wildcard bins twelve = {24'b???????????1????????????} iff ($countones(key_ctrl_lock_use) > 1); + wildcard bins thirteen = {24'b??????????1?????????????} iff ($countones(key_ctrl_lock_use) > 1); + wildcard bins fourteen = {24'b?????????1??????????????} iff ($countones(key_ctrl_lock_use) > 1); + wildcard bins fifteen = {24'b????????1???????????????} iff ($countones(key_ctrl_lock_use) > 1); + wildcard bins sixteen = {24'b???????1????????????????} iff ($countones(key_ctrl_lock_use) > 1); + wildcard bins seventeen = {24'b??????1?????????????????} iff ($countones(key_ctrl_lock_use) > 1); + wildcard bins eighteen = {24'b?????1??????????????????} iff ($countones(key_ctrl_lock_use) > 1); + wildcard bins nineteen = {24'b????1???????????????????} iff ($countones(key_ctrl_lock_use) > 1); + wildcard bins twenty = {24'b???1????????????????????} iff ($countones(key_ctrl_lock_use) > 1); + wildcard bins twenty_one = {24'b??1?????????????????????} iff ($countones(key_ctrl_lock_use) > 1); + wildcard bins twenty_two = {24'b?1??????????????????????} iff ($countones(key_ctrl_lock_use) > 1); + wildcard bins twenty_three = {24'b1???????????????????????} iff ($countones(key_ctrl_lock_use) > 1); + } + + clear: coverpoint key_ctrl_clear { + wildcard bins zero = {24'b???????????????????????1}; + wildcard bins one = {24'b??????????????????????1?}; + wildcard bins two = {24'b?????????????????????1??}; + wildcard bins three = {24'b????????????????????1???}; + wildcard bins four = {24'b???????????????????1????}; + wildcard bins five = {24'b??????????????????1?????}; + wildcard bins six = {24'b?????????????????1??????}; + wildcard bins seven = {24'b????????????????1???????}; + wildcard bins eight = {24'b???????????????1????????}; + wildcard bins nine = {24'b??????????????1?????????}; + wildcard bins ten = {24'b?????????????1??????????}; + wildcard bins eleven = {24'b????????????1???????????}; + wildcard bins twelve = {24'b???????????1????????????}; + wildcard bins thirteen = {24'b??????????1?????????????}; + wildcard bins fourteen = {24'b?????????1??????????????}; + wildcard bins fifteen = {24'b????????1???????????????}; + wildcard bins sixteen = {24'b???????1????????????????}; + wildcard bins seventeen = {24'b??????1?????????????????}; + wildcard bins eighteen = {24'b?????1??????????????????}; + wildcard bins nineteen = {24'b????1???????????????????}; + wildcard bins twenty = {24'b???1????????????????????}; + wildcard bins twenty_one = {24'b??1?????????????????????}; + wildcard bins twenty_two = {24'b?1??????????????????????}; + wildcard bins twenty_three = {24'b1???????????????????????}; + } + kv_write_en_cp: coverpoint {kv_write_en} + { + bins bin1 = {1}; + bins bin2 = {2}; + bins bin4 = {4}; + bins bin8 = {8}; + bins bin16 = {16}; + } + cp_clear_secrets_sel: coverpoint clear_secrets_sel; + cp_clear_secrets_wr : coverpoint clear_secrets_wr; + cp_ahb_write : coverpoint ahb_write; + cp_ahb_read : coverpoint ahb_read; + + //Cover debug mode unlocked while regs are locked/cleared + debugXlock_wr: cross debug, lock_wr; + debugXlock_use: cross debug, lock_use; + debugXclear: cross debug, clear; + debugXlock_wrXlock_useXclear: cross debug, lock_wr, lock_use, clear; + debugXclear_secrets: cross debug, cp_clear_secrets_wr, cp_clear_secrets_sel; + debugXkv_write: cross debug, kv_write_en_cp; + + //Cover warm reset assertion while regs are locked/cleared + // lock_wrXwarm_rst: cross lock_wr, rst_b; + // lock_useXwarm_rst: cross lock_use, rst_b; + // clearXwarm_rst: cross clear, rst_b; + + //Cover cold reset while regs are locked/cleared + // lock_wrXcold_rst: cross lock_wr, cptra_pwrgood; + // lock_useXcold_rst: cross lock_use, cptra_pwrgood; + // clearXcold_rst: cross clear, cptra_pwrgood; + + //Cover core reset while regs are locked/cleared + // lock_wrXcore_rst: cross lock_wr, core_only_rst_b; + // lock_useXcore_rst: cross lock_use, core_only_rst_b; + // clearXcore_rst: cross clear, core_only_rst_b; + + //Cover simultaneous locks/clear settings + lock_wrXlock_useXclearXclear_secrets: cross lock_wr, lock_use, clear; + + //Cross with crypto write. There's no cross with read since reads are async + //Due to this, at any given time, all signals are by default crossed with read IF + lock_wrXkv_write: cross lock_wr, kv_write_en_cp; + lock_useXkv_write: cross lock_use, kv_write_en_cp; + clearXkv_write: cross clear, kv_write_en_cp; + + clear_secretsXkv_write: cross kv_write_en_cp, cp_clear_secrets_wr, cp_clear_secrets_sel; + + //Cover ahb write/read during crypto write and debug mode unlocked + ahb_writeXkv_write: cross cp_ahb_write, kv_write_en_cp; + ahb_writeXdebug: cross cp_ahb_write, debug; + ahb_readXkv_write: cross cp_ahb_read, kv_write_en_cp; + ahb_readXdebug: cross cp_ahb_read, debug; + + + endgroup + + + keyvault_top_cov_grp keyvault_top_cov_grp1 = new(); + +endinterface + +`endif \ No newline at end of file diff --git a/designs/Caliptra/src/caliptra-rtl/keyvault_cov_props.sv b/designs/Caliptra/src/caliptra-rtl/keyvault_cov_props.sv new file mode 100644 index 0000000..91ed7d3 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/keyvault_cov_props.sv @@ -0,0 +1,123 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2019 Western Digital Corporation or its affiliates. +// +// 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. +// + +// This file contains properties that define various sequences of events in KV + +module keyvault_cov_props + import kv_defines_pkg::*; + (); + + `ifndef VERILATOR + + //clear_secrets followed by warm reset in the next clk + //Expectation: Keys cleared before warm reset + property cover_prop_clear_secr_warm_rst; + @(posedge kv.clk) + (kv.kv_reg_hwif_out.CLEAR_SECRETS.wr_debug_values |-> ##[1:$] !kv.rst_b); + endproperty + covprop_clear_secr_warmrst: cover property(cover_prop_clear_secr_warm_rst); + + generate + for(genvar i = 0; i < KV_NUM_KEYS; i++) begin + + //------------------------------------------------------------------------------ + //lock write => clear secrets => warm reset in next clk + //Expectation: Keys will be flushed since reset is not seen until next clk, locks are reset + //------------------------------------------------------------------------------ + property cover_prop_locks_clear_secr_warm_rst; + @(posedge kv.clk) + (kv.kv_reg_hwif_out.KEY_CTRL[i].lock_wr && kv.kv_reg_hwif_out.CLEAR_SECRETS.wr_debug_values |-> ##[1:$] !kv.rst_b); + endproperty + covprop_lock_clear_secr_warmrst: cover property(cover_prop_locks_clear_secr_warm_rst); + + //------------------------------------------------------------------------------ + //lock write => clear secrets => cold reset in next clk + //Expectation: Keys will be flushed since reset is not seen until next clk, locks and keys are reset once cold reset happens + //------------------------------------------------------------------------------ + property cover_prop_locks_clear_secr_cold_rst; + @(posedge kv.clk) + (kv.kv_reg_hwif_out.KEY_CTRL[i].lock_wr && kv.kv_reg_hwif_out.CLEAR_SECRETS.wr_debug_values |-> ##[1:$] !kv.cptra_pwrgood); + endproperty + covprop_lock_clear_secr_coldrst: cover property(cover_prop_locks_clear_secr_cold_rst); + + //------------------------------------------------------------------------------ + //Check that locks/clear were set before issuing warm reset + //------------------------------------------------------------------------------ + property cover_prop_lock_wr_warmrst; + @(posedge kv.clk) + ($rose(kv.kv_reg_hwif_out.KEY_CTRL[i].lock_wr) |-> ##[0:$] !kv.rst_b); + endproperty + covprop_lock_wr_warmrst: cover property(cover_prop_lock_wr_warmrst); + + property cover_prop_lock_use_warmrst; + @(posedge kv.clk) + ($rose(kv.kv_reg_hwif_out.KEY_CTRL[i].lock_use) |-> ##[0:$] !kv.rst_b); + endproperty + covprop_lock_use_warmrst: cover property(cover_prop_lock_use_warmrst); + + property cover_prop_clear_warmrst; + @(posedge kv.clk) + (kv.kv_reg_hwif_out.KEY_CTRL[i].clear |-> ##[0:$] !kv.rst_b); + endproperty + covprop_clear_warmrst: cover property(cover_prop_clear_warmrst); + + //------------------------------------------------------------------------------ + //Check that locks/clear were set before issuing cold reset + //------------------------------------------------------------------------------ + property cover_prop_lock_wr_coldrst; + @(posedge kv.clk) + ($rose(kv.kv_reg_hwif_out.KEY_CTRL[i].lock_wr) |-> ##[0:$] !kv.cptra_pwrgood); + endproperty + covprop_lock_wr_coldrst: cover property(cover_prop_lock_wr_coldrst); + + property cover_prop_lock_use_coldrst; + @(posedge kv.clk) + ($rose(kv.kv_reg_hwif_out.KEY_CTRL[i].lock_use) |-> ##[0:$] !kv.cptra_pwrgood); + endproperty + covprop_lock_use_coldrst: cover property(cover_prop_lock_use_coldrst); + + property cover_prop_clear_coldrst; + @(posedge kv.clk) + (kv.kv_reg_hwif_out.KEY_CTRL[i].clear |-> ##[0:$] !kv.cptra_pwrgood); + endproperty + covprop_clear_coldrst: cover property(cover_prop_clear_coldrst); + + //------------------------------------------------------------------------------ + //Check that locks/clear were set before issuing core reset + //------------------------------------------------------------------------------ + property cover_prop_lock_wr_corerst; + @(posedge kv.clk) + ($rose(kv.kv_reg_hwif_out.KEY_CTRL[i].lock_wr) |-> ##[0:$] !kv.core_only_rst_b); + endproperty + covprop_lock_wr_corerst: cover property(cover_prop_lock_wr_corerst); + + property cover_prop_lock_use_corerst; + @(posedge kv.clk) + ($rose(kv.kv_reg_hwif_out.KEY_CTRL[i].lock_use) |-> ##[0:$] !kv.core_only_rst_b); + endproperty + covprop_lock_use_corerst: cover property(cover_prop_lock_use_corerst); + + property cover_prop_clear_corerst; + @(posedge kv.clk) + (kv.kv_reg_hwif_out.KEY_CTRL[i].clear |-> ##[0:$] !kv.core_only_rst_b); + endproperty + covprop_clear_corerst: cover property(cover_prop_clear_corerst); + end + endgenerate + + `endif + +endmodule \ No newline at end of file diff --git a/designs/Caliptra/src/caliptra-rtl/kmac.sv b/designs/Caliptra/src/caliptra-rtl/kmac.sv new file mode 100644 index 0000000..33d0789 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/kmac.sv @@ -0,0 +1,1718 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// KMAC/SHA3 + +`include "caliptra_prim_assert.sv" + +module kmac + import caliptra_prim_alert_pkg::*; + import caliptra_prim_mubi_pkg::*; + import kmac_pkg::*; + import kmac_reg_pkg::*; +#( + // EnMasking: Enable masking security hardening inside keccak_round + // If it is enabled, the result digest will be two set of 1600bit. + parameter bit EnMasking = 1, + + // EnFullKmac: Enable full KMAC. If disabled, this module is stripped + // down to only support SHA3, SHAKE and cSHAKE. + parameter bit EnFullKmac = 1, + + // In case EnMasking == 0, this defines whether SW can provide a masked key or whether Share 1 of + // the SW key is simply ignored. In case EnMasking == 1, this parameter has no meaning, always + // both shares of the key provided by SW are used. + // This is useful to allow both for area-optimized unmasked designs as well as unmasked designs + // having a SW interface fully compatible with the masked design. + parameter bit SwKeyMasked = 0, + + // Command delay, useful for SCA measurements only. A value of e.g. 40 allows the processor to go + // into sleep before KMAC starts operation. If a value > 0 is chosen, the processor can provide + // two commands subsquently and then go to sleep. The second command is buffered internally and + // will be presented to the hardware SecCmdDelay number of cycles after the first one. + parameter int SecCmdDelay = 0, + + // Accept SW message when idle and before receiving a START command. Useful for SCA only. + parameter bit SecIdleAcceptSwMsg = 1'b0, + parameter int unsigned NumAppIntf = 2, + parameter app_config_t AppCfg[NumAppIntf] = '{AppCfgKeyMgrStripped, AppCfgKeyMgrStripped}, + + parameter lfsr_perm_t RndCnstLfsrPerm = RndCnstLfsrPermDefault, + parameter lfsr_seed_t RndCnstLfsrSeed = RndCnstLfsrSeedDefault, + parameter buffer_lfsr_seed_t RndCnstBufferLfsrSeed = RndCnstBufferLfsrSeedDefault, + parameter msg_perm_t RndCnstMsgPerm = RndCnstMsgPermDefault, + + parameter logic [NumAlerts-1:0] AlertAsyncOn = {NumAlerts{1'b1}} +) ( + input clk_i, + input rst_ni, + + input rst_shadowed_ni, + + input clk_edn_i, + input rst_edn_ni, + + input caliptra_tlul_pkg::tl_h2d_t tl_i, + output caliptra_tlul_pkg::tl_d2h_t tl_o, + + // Alerts + input alert_rx_t [NumAlerts-1:0] alert_rx_i, + output alert_tx_t [NumAlerts-1:0] alert_tx_o, + + // KeyMgr sideload (secret key) interface + input keymgr_pkg::hw_key_req_t keymgr_key_i, + + // KeyMgr KDF data path + input app_req_t [NumAppIntf-1:0] app_i, + output app_rsp_t [NumAppIntf-1:0] app_o, + + // EDN interface + output edn_pkg::edn_req_t entropy_o, + input edn_pkg::edn_rsp_t entropy_i, + + // Life cycle + input lc_ctrl_pkg::lc_tx_t lc_escalate_en_i, + + // interrupts + output logic intr_kmac_done_o, + output logic intr_fifo_empty_o, + output logic intr_kmac_err_o, + + // parameter consistency check with keymgr + output logic en_masking_o, + + // Idle signal + output mubi4_t idle_o +); + + //////////////// + // Parameters // + //////////////// + localparam int Share = (EnMasking) ? 2 : 1 ; + localparam int SwKeyShare = (EnMasking || SwKeyMasked) ? 2 : 1; + + ///////////////// + // Definitions // + ///////////////// + // This state machine is to track the current process based on SW input and + // KMAC operation. + // Encoding generated with: + // $ ./util/design/sparse-fsm-encode.py -d 3 -m 6 -n 6 \ + // -s 1966361510 --language=sv + // + // Hamming distance histogram: + // + // 0: -- + // 1: -- + // 2: -- + // 3: |||||||||||||||||||| (53.33%) + // 4: ||||||||||||||| (40.00%) + // 5: || (6.67%) + // 6: -- + // + // Minimum Hamming distance: 3 + // Maximum Hamming distance: 5 + // Minimum Hamming weight: 2 + // Maximum Hamming weight: 5 + // + localparam int StateWidth = 6; + typedef enum logic [StateWidth-1:0] { + // Idle state + KmacIdle = 6'b001011, + + // When software writes CmdStart @ KmacIdle and kmac_en, FSM moves to this + KmacPrefix = 6'b000110, + + // When SHA3 engine processes Key block, FSM moves to here. + KmacKeyBlock = 6'b111110, + + // Message Feed + KmacMsgFeed = 6'b010101, + + // Complete and squeeze + KmacDigest = 6'b101101, + + // Error + KmacTerminalError = 6'b110000 + + } kmac_st_e; + + kmac_st_e kmac_st, kmac_st_d; + + ///////////// + // Signals // + ///////////// + kmac_reg2hw_t reg2hw; + kmac_hw2reg_t hw2reg; + + // Window + typedef enum logic [0:0] { + WinState = 0, + WinMsgFifo = 1 + } tl_window_e; + + caliptra_tlul_pkg::tl_h2d_t tl_win_h2d[2]; + caliptra_tlul_pkg::tl_d2h_t tl_win_d2h[2]; + + // SHA3 core control signals and its response. + // Sequence: start --> process(multiple) --> get absorbed event --> {run -->} done + logic sha3_start, sha3_run, unused_sha3_squeeze; + mubi4_t sha3_done; + mubi4_t sha3_done_d; + mubi4_t sha3_absorbed; + + // Indicate one block processed + logic sha3_block_processed; + + // EStatus for entropy + logic entropy_in_keyblock; + + // Application interface logic generates absorbed from sha3_absorbed. + // It is active only if SW initiates the hashing engine. + mubi4_t app_absorbed; + logic event_absorbed; + + ot_sha3_pkg::sha3_st_e sha3_fsm; + + // Prefix: kmac_pkg defines Prefix based on N size and S size. + // Then computes left_encode(len(N)) size and left_encode(len(S)) + // For given default value 32, 256 bits, the max + // encode_string(N) || encode_string(S) is 328. So 11 Prefix registers are + // created. + logic [ot_sha3_pkg::NSRegisterSize*8-1:0] reg_ns_prefix; + logic [ot_sha3_pkg::NSRegisterSize*8-1:0] ns_prefix; + + // NumWordsPrefix from kmac_reg_pkg + `CALIPTRA_ASSERT_INIT(PrefixRegSameToPrefixPkg_A, + kmac_reg_pkg::NumWordsPrefix*4 == ot_sha3_pkg::NSRegisterSize) + + // NumEntriesMsgFifo from kmac_reg_pkg must match calculated MsgFifoDepth + // from kmac_pkg. + `CALIPTRA_ASSERT_INIT(NumEntriesRegSameToNumEntriesPkg_A, + kmac_reg_pkg::NumEntriesMsgFifo == kmac_pkg::MsgFifoDepth) + + // NumBytesMsgFifoEntry from kmac_reg_pkg must match the MsgWidth calculated + // in kmac_pkg (although MsgWidth is in bits, so we multiply by 8). + `CALIPTRA_ASSERT_INIT(EntrySizeRegSameToEntrySizePkg_A, + kmac_reg_pkg::NumBytesMsgFifoEntry * 8 == kmac_pkg::MsgWidth) + + // Output state: this is used to redirect the digest to KeyMgr or Software + // depends on the configuration. + logic state_valid; + logic [ot_sha3_pkg::StateW-1:0] state [Share]; + + // state is de-muxed in keymgr interface logic. + // the output from keymgr logic goes into staterd module to be visible to SW + logic reg_state_valid; + logic [ot_sha3_pkg::StateW-1:0] reg_state [Share]; + + // SHA3 Entropy interface + logic sha3_rand_valid, sha3_rand_early, sha3_rand_update, sha3_rand_consumed; + logic [ot_sha3_pkg::StateW/2-1:0] sha3_rand_data; + logic sha3_rand_aux; + + // FIFO related signals + logic msgfifo_empty, msgfifo_full; + logic [kmac_pkg::MsgFifoDepthW-1:0] msgfifo_depth; + + logic msgfifo_valid ; + logic [kmac_pkg::MsgWidth-1:0] msgfifo_data [Share]; + logic [kmac_pkg::MsgStrbW-1:0] msgfifo_strb ; + logic msgfifo_ready ; + + if (EnMasking) begin : gen_msgfifo_data_masked + // In Masked mode, the input message data is split into two shares. + // Only concern, however, here is the secret key. So message can be + // put into only one share and other is 0. + assign msgfifo_data[1] = '0; + end + + // TL-UL Adapter(MSG_FIFO) signals + logic tlram_req; + logic tlram_gnt; + logic tlram_we; + logic [8:0] tlram_addr; // NOT_READ + logic [31:0] tlram_wdata; + logic [31:0] tlram_wmask; + logic [31:0] tlram_rdata; + logic tlram_rvalid; + logic [1:0] tlram_rerror; + logic [31:0] tlram_wdata_endian; + logic [31:0] tlram_wmask_endian; + + logic sw_msg_valid; + logic [kmac_pkg::MsgWidth-1:0] sw_msg_data ; + logic [kmac_pkg::MsgWidth-1:0] sw_msg_mask ; + logic sw_msg_ready; + + // KeyMgr interface to MSG_FIFO + logic mux2fifo_valid; + logic [kmac_pkg::MsgWidth-1:0] mux2fifo_data ; + logic [kmac_pkg::MsgWidth-1:0] mux2fifo_mask ; + logic mux2fifo_ready; + + // KMAC to SHA3 core + logic msg_valid ; + logic [kmac_pkg::MsgWidth-1:0] msg_data [Share]; + logic [kmac_pkg::MsgWidth-1:0] msg_data_masked [Share]; + logic [kmac_pkg::MsgStrbW-1:0] msg_strb ; + logic msg_ready ; + + // Process control signals + // Process pulse propagates from register to SHA3 engine one by one. + // Each module (MSG_FIFO, KMAC core, SHA3 core) generates the process pulse + // after flushing internal data to the next module. + logic reg2msgfifo_process, msgfifo2kmac_process, kmac2sha3_process; + + + // Secret Key signals + logic [MaxKeyLen-1:0] sw_key_data_reg [SwKeyShare]; + logic [MaxKeyLen-1:0] sw_key_data [Share]; + key_len_e sw_key_len; + logic [MaxKeyLen-1:0] key_data [Share]; + logic key_valid; + key_len_e key_len; + + // SHA3 Mode, Strength, KMAC enable for app interface + logic reg_kmac_en, app_kmac_en; + ot_sha3_pkg::sha3_mode_e reg_sha3_mode, app_sha3_mode; + ot_sha3_pkg::keccak_strength_e reg_keccak_strength, app_keccak_strength; + + // RegIF of enabling unsupported mode & strength + logic cfg_en_unsupported_modestrength; + + // Indicating AppIntf is active. This signal is used to check SW error + logic app_active; + + // SEC_CM: SW_CMD.CTRL.SPARSE + // Command + // sw_cmd is the command written by SW + // checked_sw_cmd is checked in the kmac_errchk module. + // Invalid command is filtered out in the module. + // kmac_cmd is generated in KeyMgr interface. + // If SW initiates the KMAC/SHA3, kmac_cmd represents SW command, + // if KeyMgr drives the data, kmac_cmd is controled in the state machine + // in KeyMgr interface logic. + kmac_cmd_e sw_cmd, checked_sw_cmd, kmac_cmd, cmd_q; + logic cmd_update; + + // Entropy configurations + logic [9:0] wait_timer_prescaler; + logic [15:0] wait_timer_limit; + logic entropy_refresh_req; + logic entropy_seed_update; + logic [31:0] entropy_seed_data; + + logic [HashCntW-1:0] entropy_hash_threshold; + logic [HashCntW-1:0] entropy_hash_cnt; + logic entropy_hash_clr; + + logic entropy_ready; + entropy_mode_e entropy_mode; + logic entropy_fast_process; + + mubi4_t entropy_configured; + + // Message Masking + logic msg_mask_en, cfg_msg_mask; + logic [MsgWidth-1:0] msg_mask; + + // SHA3 Error response + ot_sha3_pkg::err_t sha3_err; + + // KeyMgr Error response + kmac_pkg::err_t app_err; + + // Entropy Generator Error + kmac_pkg::err_t entropy_err; + + // Error checker + kmac_pkg::err_t errchecker_err; + + // MsgFIFO Error + kmac_pkg::err_t msgfifo_err; + + logic err_processed; + + mubi4_t clear_after_error; + + logic alert_fatal, alert_recov_operation; + logic alert_intg_err; + + // Life cycle + localparam int unsigned NumLcSyncCopies = 6; + lc_ctrl_pkg::lc_tx_t [NumLcSyncCopies-1:0] lc_escalate_en_sync; + lc_ctrl_pkg::lc_tx_t [NumLcSyncCopies-1:0] lc_escalate_en; + + ////////////////////////////////////// + // Connecting Register IF to logics // + ////////////////////////////////////// + + // Function-name N and Customization input string S + always_comb begin + for (int i = 0 ; i < NumWordsPrefix; i++) begin + reg_ns_prefix[32*i+:32] = reg2hw.prefix[i].q; + end + end + + // Create a lint error to reduce the risk of accidentally enabling this feature. + `CALIPTRA_ASSERT_STATIC_LINT_ERROR(KmacSecCmdDelayNonDefault, SecCmdDelay == 0) + + if (SecCmdDelay > 0) begin : gen_cmd_delay_buf + // Delay and buffer commands for SCA measurements. + localparam int unsigned WidthCounter = $clog2(SecCmdDelay+1); + logic [WidthCounter-1:0] count_d, count_q; + logic counting_d, counting_q; + logic cmd_buf_empty; + kmac_cmd_e cmd_buf_q; + + assign cmd_buf_empty = (cmd_buf_q == CmdNone); + + // When seeing a write to the cmd register, we start counting. We stop counting once the + // counter has expired and the command buffer is empty. + assign counting_d = reg2hw.cmd.cmd.qe ? 1'b1 : + cmd_update & cmd_buf_empty ? 1'b0 : counting_q; + + // Clear counter upon writes to the cmd register or if the specified delay is reached. + assign count_d = reg2hw.cmd.cmd.qe ? '0 : + cmd_update ? '0 : + counting_q ? count_q + 1'b1 : count_q; + + // The manual run command cannot be delayed. Software expects this to be triggered immediately + // and will poll the status register to wait for the SHA3 engine to return back to the squeeze + // state. + assign cmd_update = (cmd_q == CmdManualRun) ? 1'b1 : + (count_q == SecCmdDelay[WidthCounter-1:0]) ? 1'b1 : 1'b0; + + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + count_q <= '0; + counting_q <= 1'b0; + end else begin + count_q <= count_d; + counting_q <= counting_d; + end + end + + // cmd.q is valid while cmd.qe is high, meaning it needs to be registered. We buffer one + // additional command such that software can write START followed by PROCESS and then go to + // sleep. + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + cmd_q <= CmdNone; + cmd_buf_q <= CmdNone; + end else begin + if (reg2hw.cmd.cmd.qe && cmd_update) begin + // New write & counter expired. + cmd_q <= cmd_buf_q; + cmd_buf_q <= kmac_cmd_e'(reg2hw.cmd.cmd.q); + + end else if (reg2hw.cmd.cmd.qe) begin + // New write. + if (counting_q == 1'b0) begin + cmd_q <= kmac_cmd_e'(reg2hw.cmd.cmd.q); + end else begin + cmd_buf_q <= kmac_cmd_e'(reg2hw.cmd.cmd.q); + end + + end else if (cmd_update) begin + // Counter expired. + cmd_q <= cmd_buf_q; + cmd_buf_q <= CmdNone; + end + end + end + + end else begin : gen_no_cmd_delay_buf + // Directly forward signals from register IF. + assign cmd_update = reg2hw.cmd.cmd.qe; + assign cmd_q = kmac_cmd_e'(reg2hw.cmd.cmd.q); + end + + // Command signals + assign sw_cmd = (cmd_update) ? cmd_q : CmdNone; + `CALIPTRA_ASSERT_KNOWN(KmacCmd_A, sw_cmd) + always_comb begin + sha3_start = 1'b 0; + sha3_run = 1'b 0; + sha3_done_d = MuBi4False; + reg2msgfifo_process = 1'b 0; + + unique case (kmac_cmd) + CmdStart: begin + sha3_start = 1'b 1; + end + + CmdProcess: begin + reg2msgfifo_process = 1'b 1; + end + + CmdManualRun: begin + sha3_run = 1'b 1; + end + + CmdDone: begin + sha3_done_d = MuBi4True; + end + + CmdNone: begin + // inactive state + end + + default: begin + end + endcase + end + + // Status register ========================================================== + // status.squeeze is valid only when SHA3 engine completes the Absorb and not + // running the manual keccak rounds. This status is for SW to determine when + // to read the STATE values. + assign hw2reg.status.sha3_idle.d = sha3_fsm == ot_sha3_pkg::StIdle; + assign hw2reg.status.sha3_absorb.d = sha3_fsm == ot_sha3_pkg::StAbsorb; + assign hw2reg.status.sha3_squeeze.d = sha3_fsm == ot_sha3_pkg::StSqueeze; + + // FIFO related status + assign hw2reg.status.fifo_depth.d[MsgFifoDepthW-1:0] = msgfifo_depth; + if ($bits(hw2reg.status.fifo_depth.d) != MsgFifoDepthW) begin : gen_fifo_depth_tie + assign hw2reg.status.fifo_depth.d[$bits(hw2reg.status.fifo_depth.d)-1:MsgFifoDepthW] = '0; + end + assign hw2reg.status.fifo_empty.d = msgfifo_empty; + assign hw2reg.status.fifo_full.d = msgfifo_full; + + // Configuration Register + logic engine_stable; + assign engine_stable = sha3_fsm == ot_sha3_pkg::StIdle; + + // SEC_CM: CFG_SHADOWED.CONFIG.REGWEN + assign hw2reg.cfg_regwen.d = engine_stable; + + if (EnFullKmac) begin : gen_key_data + // Secret Key + // Secret key is defined as external register. So the logic latches when SW + // writes to KEY_SHARE0 , KEY_SHARE1 registers. + // SEC_CM: SW_KEY.KEY.MASKING + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + sw_key_data_reg[0] <= '0; + end else if (engine_stable) begin + for (int j = 0 ; j < MaxKeyLen/32 ; j++) begin + if (reg2hw.key_share0[j].qe) begin + sw_key_data_reg[0][32*j+:32] <= reg2hw.key_share0[j].q; + end + end // for j + end // else if engine_stable + end // always_ff + + if (EnMasking || SwKeyMasked) begin : gen_key_share1_reg + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + sw_key_data_reg[1] <= '0; + end else if (engine_stable) begin + for (int j = 0 ; j < MaxKeyLen/32 ; j++) begin + if (reg2hw.key_share1[j].qe) begin + sw_key_data_reg[1][32*j+:32] <= reg2hw.key_share1[j].q; + end + end // for j + end // else if engine_stable + end // always_ff + end else begin : gen_no_key_share1_reg + logic unused_key_share1; + assign unused_key_share1 = ^reg2hw.key_share1; + end + + if (EnMasking || !SwKeyMasked) begin : gen_key_forward + // Forward all available key shares as is. + assign sw_key_data = sw_key_data_reg; + end else begin : gen_key_unmask + // Masking is disabled but the SW still provides the key in two shares. + // Unmask the key for processing. + assign sw_key_data[0] = sw_key_data_reg[0] ^ sw_key_data_reg[1]; + end + + assign sw_key_len = key_len_e'(reg2hw.key_len.q); + end else begin : gen_no_key_data + assign sw_key_data_reg[0] = '{default: '0}; + + logic unused_sw_key_data_reg; + if (EnMasking || SwKeyMasked) begin : gen_unused_sw_key_data_masked + assign unused_sw_key_data_reg = ^{sw_key_data_reg[0], sw_key_data_reg[1]}; + end else begin : gen_unused_sw_key_data_unmasked + assign unused_sw_key_data_reg = ^sw_key_data_reg[0]; + end + + assign sw_key_data = '{default: '0}; + assign sw_key_len = key_len_e'(0); + end + + // Entropy configurations + if (EnFullKmac) begin : gen_entropy_mask + assign wait_timer_prescaler = reg2hw.entropy_period.prescaler.q; + assign wait_timer_limit = reg2hw.entropy_period.wait_timer.q; + assign entropy_refresh_req = reg2hw.cmd.entropy_req.q + && reg2hw.cmd.entropy_req.qe; + assign entropy_seed_update = reg2hw.entropy_seed.qe; + assign entropy_seed_data = reg2hw.entropy_seed.q; + + assign entropy_hash_threshold = reg2hw.entropy_refresh_threshold_shadowed.q; + + assign hw2reg.entropy_refresh_hash_cnt.de = 1'b 1; + assign hw2reg.entropy_refresh_hash_cnt.d = entropy_hash_cnt; + + assign entropy_hash_clr = reg2hw.cmd.hash_cnt_clr.qe + && reg2hw.cmd.hash_cnt_clr.q; + + assign entropy_ready = reg2hw.cfg_shadowed.entropy_ready.q + & reg2hw.cfg_shadowed.entropy_ready.qe; + assign entropy_mode = entropy_mode_e'(reg2hw.cfg_shadowed.entropy_mode.q); + assign entropy_fast_process = reg2hw.cfg_shadowed.entropy_fast_process.q; + + // msg_mask_en turns on the message LFSR when KMAC is enabled. + assign cfg_msg_mask = reg2hw.cfg_shadowed.msg_mask.q; + assign msg_mask_en = cfg_msg_mask & msg_valid & msg_ready; + + // Enable unsupported mode & strength combination + assign cfg_en_unsupported_modestrength = reg2hw.cfg_shadowed.en_unsupported_modestrength.q; + + `CALIPTRA_ASSERT(EntropyReadyLatched_A, $rose(entropy_ready) |=> !entropy_ready) + + end else begin : gen_no_entropy_mask + assign wait_timer_prescaler = '0; + assign wait_timer_limit = '0; + assign entropy_refresh_req = 1'b0; + assign entropy_seed_update = 1'b0; + assign entropy_seed_data = '0; + + assign entropy_hash_threshold = '0; + + assign entropy_hash_clr = 1'b0; + assign entropy_ready = 1'b0; + assign entropy_mode = EntropyModeNone; + assign entropy_fast_process = 1'b0; + + // msg_mask_en turns on the message LFSR when KMAC is enabled. + assign cfg_msg_mask = 1'b0; + assign msg_mask_en = 1'b0; + + // Enable unsupported mode & strength combination + assign cfg_en_unsupported_modestrength = 1'b0; + end + + // Idle control (registered output) + // The logic checks idle of SHA3 engine, MSG_FIFO, KMAC_CORE, KEYMGR interface + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + idle_o <= MuBi4True; + end else if ((sha3_fsm == ot_sha3_pkg::StIdle) && (msgfifo_empty || SecIdleAcceptSwMsg)) begin + idle_o <= MuBi4True; + end else begin + idle_o <= MuBi4False; + end + end + + // Clear the error processed + assign err_processed = reg2hw.cmd.err_processed.q & reg2hw.cmd.err_processed.qe; + + // Make sure the field has latch in reg_top + `CALIPTRA_ASSERT(ErrProcessedLatched_A, $rose(err_processed) |=> !err_processed) + + // App mode, strength, kmac_en + if (EnFullKmac) begin : gen_reg_kmac_en + assign reg_kmac_en = reg2hw.cfg_shadowed.kmac_en.q; + end else begin : gen_no_reg_kmac_en + assign reg_kmac_en = 1'b0; + end + + assign reg_sha3_mode = ot_sha3_pkg::sha3_mode_e'(reg2hw.cfg_shadowed.mode.q); + assign reg_keccak_strength = ot_sha3_pkg::keccak_strength_e'(reg2hw.cfg_shadowed.kstrength.q); + + /////////////// + // Interrupt // + /////////////// + + // Hash process absorbed interrupt + // Convert mubi4_t to logic to generate interrupts + assign event_absorbed = mubi4_test_true_strict(app_absorbed); + + caliptra_prim_intr_hw #(.Width(1)) intr_kmac_done ( + .clk_i, + .rst_ni, + .event_intr_i (event_absorbed), + .reg2hw_intr_enable_q_i (reg2hw.intr_enable.kmac_done.q), + .reg2hw_intr_test_q_i (reg2hw.intr_test.kmac_done.q), + .reg2hw_intr_test_qe_i (reg2hw.intr_test.kmac_done.qe), + .reg2hw_intr_state_q_i (reg2hw.intr_state.kmac_done.q), + .hw2reg_intr_state_de_o (hw2reg.intr_state.kmac_done.de), + .hw2reg_intr_state_d_o (hw2reg.intr_state.kmac_done.d), + .intr_o (intr_kmac_done_o) + ); + + `CALIPTRA_ASSERT(Sha3AbsorbedPulse_A, + $rose(mubi4_test_true_strict(sha3_absorbed)) |=> + mubi4_test_false_strict(sha3_absorbed)) + + // Message FIFO empty interrupt + // + // The message FIFO empty interrupt is **not useful** for software if: + // - One of the hardware application interfaces is actively using the KMAC block. In this case + // the message FIFO is managed entirely by the application interface. + // - The SHA3 core is not in the Absorb state. Only in this state, the FIFO is writeable by + // software anyway. + // - Software has already written the Process command. The KMAC block will now empty the + // message FIFO and load its content into the SHA3 core, add the padding and then perfom + // the final absorption. Software cannot append the message further. + // + // The message FIFO empty interrupt can be **useful** for software in particular if: + // - The message FIFO was completely full previously. However, unless the KMAC block is currently + // processing a block or waiting for fresh entropy from EDN, it always empties the message FIFO + // faster than software can fill it up, meaning the message FIFO is empty most of the time. + // Note, the empty status is signaled only once after the FIFO was completely full. The FIFO + // needs to be full again for the empty status to be signaled again next time it's empty. + // + // For further details see also: + // https://opentitan.org/book/hw/ip/kmac/doc/theory_of_operation.html#fifo-depth-and-empty-status + logic status_msgfifo_empty, msgfifo_empty_gate; + logic msgfifo_empty_negedge, msgfifo_empty_q; + logic msgfifo_full_seen_d, msgfifo_full_seen_q; + assign msgfifo_empty_negedge = msgfifo_empty_q & ~msgfifo_empty; + + // Track whether the message FIFO was full after being empty. We clear the tracking: + // - When receiving the Process command. This is to start over for the next message. + // - When seeing a negative edge on the empty signal. This signals that software has reacted to + // the interrupt and is filling up the FIFO again. + assign msgfifo_full_seen_d = + msgfifo_full ? 1'b 1 : + msgfifo_empty_negedge ? 1'b 0 : + msgfifo2kmac_process ? 1'b 0 : msgfifo_full_seen_q; + + // The interrupt is gated unless software is performing an absorption operation (but not the + // final block) and the FIFO was full before. The msgfifo2kmac_process pulse is arriving from the + // FIFO together with the empty signal. + assign msgfifo_empty_gate = + app_active ? 1'b 1 : + sha3_fsm != ot_sha3_pkg::StAbsorb ? 1'b 1 : + msgfifo2kmac_process ? 1'b 1 : ~msgfifo_full_seen_q; + + assign status_msgfifo_empty = msgfifo_empty_gate ? 1'b 0 : msgfifo_empty; + + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + msgfifo_empty_q <= 1'b 0; + msgfifo_full_seen_q <= 1'b 0; + end else begin + msgfifo_empty_q <= msgfifo_empty; + msgfifo_full_seen_q <= msgfifo_full_seen_d; + end + end + + caliptra_prim_intr_hw #( + .Width(1), + .IntrT("Status") + ) intr_fifo_empty ( + .clk_i, + .rst_ni, + .event_intr_i (status_msgfifo_empty), + .reg2hw_intr_enable_q_i (reg2hw.intr_enable.fifo_empty.q), + .reg2hw_intr_test_q_i (reg2hw.intr_test.fifo_empty.q), + .reg2hw_intr_test_qe_i (reg2hw.intr_test.fifo_empty.qe), + .reg2hw_intr_state_q_i (reg2hw.intr_state.fifo_empty.q), + .hw2reg_intr_state_de_o (hw2reg.intr_state.fifo_empty.de), + .hw2reg_intr_state_d_o (hw2reg.intr_state.fifo_empty.d), + .intr_o (intr_fifo_empty_o) + ); + + // Error + + logic event_error; + assign event_error = sha3_err.valid | app_err.valid + | entropy_err.valid | errchecker_err.valid + ; + + // Assing error code to the register + assign hw2reg.err_code.de = event_error; + + always_comb begin + hw2reg.err_code.d = '0; + + priority case (1'b 1) + // app_err has the highest priority. If SW issues an incorrect command + // while app is in active state, the error from AppIntf is passed + // through. + app_err.valid: begin + hw2reg.err_code.d = {app_err.code, app_err.info}; + end + + errchecker_err.valid: begin + hw2reg.err_code.d = {errchecker_err.code , errchecker_err.info}; + end + + sha3_err.valid: begin + hw2reg.err_code.d = {sha3_err.code , sha3_err.info}; + end + + entropy_err.valid: begin + hw2reg.err_code.d = {entropy_err.code, entropy_err.info}; + end + + msgfifo_err.valid: begin + hw2reg.err_code.d = {msgfifo_err.code, msgfifo_err.info}; + end + + default: begin + hw2reg.err_code.d = '0; + end + endcase + end + + // Counter errors + logic counter_error, sha3_count_error, key_index_error; + logic msgfifo_counter_error; + logic kmac_entropy_hash_counter_error; + assign counter_error = sha3_count_error + | kmac_entropy_hash_counter_error + | key_index_error + | msgfifo_counter_error; + + assign msgfifo_counter_error = msgfifo_err.valid; + + // State Errors + logic sparse_fsm_error; + logic sha3_state_error, kmac_errchk_state_error; + logic kmac_core_state_error, kmac_app_state_error; + logic kmac_entropy_state_error, kmac_state_error; + assign sparse_fsm_error = sha3_state_error + | kmac_errchk_state_error + | kmac_core_state_error + | kmac_app_state_error + | kmac_entropy_state_error + | kmac_state_error; + + // Control Signal Integrity Errors + logic control_integrity_error; + logic sha3_storage_rst_error; + assign control_integrity_error = sha3_storage_rst_error; + + caliptra_prim_intr_hw #(.Width(1)) intr_kmac_err ( + .clk_i, + .rst_ni, + .event_intr_i (event_error), + .reg2hw_intr_enable_q_i (reg2hw.intr_enable.kmac_err.q), + .reg2hw_intr_test_q_i (reg2hw.intr_test.kmac_err.q), + .reg2hw_intr_test_qe_i (reg2hw.intr_test.kmac_err.qe), + .reg2hw_intr_state_q_i (reg2hw.intr_state.kmac_err.q), + .hw2reg_intr_state_de_o (hw2reg.intr_state.kmac_err.de), + .hw2reg_intr_state_d_o (hw2reg.intr_state.kmac_err.d), + .intr_o (intr_kmac_err_o) + ); + + /////////////////// + // State Machine // + /////////////////// + + // State FF + `CALIPTRA_PRIM_FLOP_SPARSE_FSM(u_state_regs, kmac_st_d, kmac_st, kmac_st_e, KmacIdle) + + always_comb begin + // Default value + kmac_st_d = kmac_st; + + entropy_in_keyblock = 1'b 0; + kmac_state_error = 1'b 0; + + unique case (kmac_st) + KmacIdle: begin + if (kmac_cmd == CmdStart) begin + // If cSHAKE turned on + if (ot_sha3_pkg::CShake == app_sha3_mode) begin + kmac_st_d = KmacPrefix; + end else begin + // Jump to Msg feed directly + kmac_st_d = KmacMsgFeed; + end + end else begin + kmac_st_d = KmacIdle; + end + end + + KmacPrefix: begin + if (EnFullKmac) begin : gen_kmac_prefix_state + // Wait until SHA3 processes one block + if (sha3_block_processed) begin + kmac_st_d = app_kmac_en ? KmacKeyBlock : KmacMsgFeed; + end else begin + kmac_st_d = KmacPrefix; + end + end else begin : gen_no_kmac_prefix_state + // Wait until SHA3 processes one block + if (sha3_block_processed) begin + kmac_st_d = KmacMsgFeed; + end else begin + kmac_st_d = KmacPrefix; + end + end + end + + KmacKeyBlock: begin + if (EnFullKmac) begin : gen_kmac_key_block_state + entropy_in_keyblock = 1'b 1; + if (sha3_block_processed) begin + kmac_st_d = KmacMsgFeed; + end else begin + kmac_st_d = KmacKeyBlock; + end + end else begin : gen_no_kmac_key_block_state + // If KMAC is stripped down, this state should never be entered. + kmac_st_d = KmacTerminalError; + kmac_state_error = 1'b 1; + end + end + + KmacMsgFeed: begin + // If absorbed, move to Digest + if (mubi4_test_true_strict(sha3_absorbed) && + mubi4_test_true_strict(sha3_done)) begin + // absorbed and done can be asserted at a cycle if Applications have + // requested the hash operation. kmac_app FSM issues CmdDone command + // if it receives absorbed signal. + kmac_st_d = KmacIdle; + end else if (mubi4_test_true_strict(sha3_absorbed) && + mubi4_test_false_loose(sha3_done)) begin + kmac_st_d = KmacDigest; + end else begin + kmac_st_d = KmacMsgFeed; + end + end + + KmacDigest: begin + // SW can manually run it, wait till done + if (mubi4_test_true_strict(sha3_done)) begin + kmac_st_d = KmacIdle; + end else begin + kmac_st_d = KmacDigest; + end + end + + KmacTerminalError: begin + //this state is terminal + kmac_st_d = KmacTerminalError; + kmac_state_error = 1'b 1; + end + + default: begin + kmac_st_d = KmacTerminalError; + kmac_state_error = 1'b 1; + end + endcase + + // SEC_CM: FSM.GLOBAL_ESC, FSM.LOCAL_ESC + // Unconditionally jump into the terminal error state + // if the life cycle controller triggers an escalation. + if (lc_ctrl_pkg::lc_tx_test_true_loose(lc_escalate_en[0])) begin + kmac_st_d = KmacTerminalError; + end + end + `CALIPTRA_ASSERT_KNOWN(KmacStKnown_A, kmac_st) + + /////////////// + // Instances // + /////////////// + + if (EnFullKmac == 1) begin : gen_kmac_core + // KMAC core + kmac_core #( + .EnMasking (EnMasking) + ) u_kmac_core ( + .clk_i, + .rst_ni, + + // from Msg FIFO + .fifo_valid_i (msgfifo_valid), + .fifo_data_i (msgfifo_data ), + .fifo_strb_i (msgfifo_strb ), + .fifo_ready_o (msgfifo_ready), + + // to SHA3 core + .msg_valid_o (msg_valid), + .msg_data_o (msg_data ), + .msg_strb_o (msg_strb ), + .msg_ready_i (msg_ready), + + // Configurations + .kmac_en_i (app_kmac_en), + .mode_i (app_sha3_mode), + .strength_i (app_keccak_strength), + + // Secret key interface + .key_data_i (key_data), + .key_len_i (key_len), + .key_valid_i (key_valid), + + // Controls + .start_i (sha3_start ), + .process_i (msgfifo2kmac_process), + .done_i (sha3_done ), + .process_o (kmac2sha3_process ), + + // LC escalation + .lc_escalate_en_i (lc_escalate_en[1]), + + // Error detection + .sparse_fsm_error_o (kmac_core_state_error), + .key_index_error_o (key_index_error) + ); + + end else begin : gen_no_kmac_core + // When KMAC is disabled, the msgfifo and control signals are simply fed through. + assign msgfifo_ready = msg_ready; + assign msg_valid = msgfifo_valid; + assign msg_data = msgfifo_data; + assign msg_strb = msgfifo_strb; + assign kmac2sha3_process = msgfifo2kmac_process; + // Since kmac_core is not used, it can't produce any errors. + assign kmac_core_state_error = 1'b0; + assign key_index_error = 1'b0; + + // Unused signals. + logic unused_key_data, unused_lc_escalate_en1, unused_app_kmac_en; + + if (EnMasking) begin : gen_unused_key_data_masked + assign unused_key_data = ^{key_data[0], key_data[1], key_len, key_valid}; + end else begin : gen_unused_key_data_unmasked + assign unused_key_data = ^{key_data[0], key_len, key_valid}; + end + + assign unused_lc_escalate_en1 = ^lc_escalate_en[1]; + assign unused_app_kmac_en = app_kmac_en; + end + + // SHA3 hashing engine + + // msg_data masking + if (EnMasking == 1) begin: g_msg_mask + logic [MsgWidth-1:0] msg_mask_permuted; + + // Permute the LFSR output to avoid same lfsr applied to multiple times + always_comb begin + msg_mask_permuted = '0; + for (int unsigned i = 0 ; i < MsgWidth ; i++) begin + // Loop through the MsgPerm constant and swap between the bits + msg_mask_permuted[i] = msg_mask[RndCnstMsgPerm[i]]; + end + end + + for (genvar i = 0 ; i < Share ; i++) begin: g_msg_data_mask + assign msg_data_masked[i] = msg_data[i] + ^ ({MsgWidth{cfg_msg_mask}} & msg_mask_permuted); + end : g_msg_data_mask + end else begin : g_no_msg_mask + assign msg_data_masked[0] = msg_data[0]; + assign msg_mask = '0; + + logic unused_msgmask; + assign unused_msgmask = ^{msg_mask, cfg_msg_mask, msg_mask_en}; + end + + ot_sha3 #( + .EnMasking (EnMasking) + ) u_sha3 ( + .clk_i, + .rst_ni, + + // MSG_FIFO interface (or from KMAC) + .msg_valid_i (msg_valid), + .msg_data_i (msg_data_masked ), + .msg_strb_i (msg_strb ), + .msg_ready_o (msg_ready), + + // Entropy interface + .rand_valid_i (sha3_rand_valid), + .rand_early_i (sha3_rand_early), + .rand_data_i (sha3_rand_data), + .rand_aux_i (sha3_rand_aux), + .rand_update_o (sha3_rand_update), + .rand_consumed_o (sha3_rand_consumed), + + // N, S: Used in cSHAKE mode + .ns_data_i (ns_prefix), + + // Configurations + .mode_i (app_sha3_mode), + .strength_i (app_keccak_strength), + + // Controls (CMD register) + .start_i (sha3_start ), + .process_i (kmac2sha3_process), + .run_i (sha3_run ), + .done_i (sha3_done ), + + // LC escalation + .lc_escalate_en_i (lc_escalate_en[2]), + + .absorbed_o (sha3_absorbed), + .squeezing_o (unused_sha3_squeeze), + + .block_processed_o (sha3_block_processed), + + .sha3_fsm_o (sha3_fsm), + + .state_valid_o (state_valid), + .state_o (state), // [Share] + + // REQ/ACK interface to avoid power spikes + .run_req_o ( ), // Not used + .run_ack_i (1'b 1), // The SHA3 core is always allowed to process. + + .error_o (sha3_err), + .sparse_fsm_error_o (sha3_state_error), + .count_error_o (sha3_count_error), + .keccak_storage_rst_error_o (sha3_storage_rst_error) + ); + + // MSG_FIFO window interface to FIFO interface =============================== + // Tie the read path + assign tlram_rvalid = 1'b 0; + assign tlram_rdata = '0; + assign tlram_rerror = '0; + + // Convert endian here + // prim_packer always packs to the right(bit0). If the input DWORD is + // big-endian, it needs to be swapped to little-endian to maintain the + // order. Internal SHA3(Keccak) runs in little-endian in contrast to HMAC + // So, no endian-swap after prim_packer. + assign tlram_wdata_endian = conv_endian32(tlram_wdata, + reg2hw.cfg_shadowed.msg_endianness.q); + assign tlram_wmask_endian = conv_endian32(tlram_wmask, + reg2hw.cfg_shadowed.msg_endianness.q); + + // TL Adapter + caliptra_tlul_adapter_sram #( + .SramAw ($clog2(MsgWindowDepth)), + .SramDw (MsgWindowWidth), + .Outstanding (1), + .ByteAccess (1), + .ErrOnRead (1) + ) u_tlul_adapter_msgfifo ( + .clk_i, + .rst_ni, + .en_ifetch_i (MuBi4False), + .tl_i (tl_win_h2d[WinMsgFifo]), + .tl_o (tl_win_d2h[WinMsgFifo]), + + .req_o (tlram_req), + .req_type_o (), + .gnt_i (tlram_gnt), + .we_o (tlram_we ), + .addr_o (tlram_addr), + .wdata_o (tlram_wdata), + .wmask_o (tlram_wmask), + .intg_error_o ( ), + .rdata_i (tlram_rdata), + .rvalid_i (tlram_rvalid), + .rerror_i (tlram_rerror), + .compound_txn_in_progress_o (), + .readback_en_i (MuBi4False), + .readback_error_o (), + .wr_collision_i (1'b0), + .write_pending_i (1'b0) + ); + + assign sw_msg_valid = tlram_req & tlram_we ; + if (MsgWidth == MsgWindowWidth) begin : gen_sw_msg_samewidth + assign sw_msg_data = tlram_wdata_endian ; + assign sw_msg_mask = tlram_wmask_endian ; + end else begin : gen_sw_msg_diff + assign sw_msg_data = {{MsgWidth-MsgWindowWidth{1'b0}}, tlram_wdata_endian}; + assign sw_msg_mask = {{MsgWidth-MsgWindowWidth{1'b0}}, tlram_wmask_endian}; + end + assign tlram_gnt = sw_msg_ready ; + + logic unused_tlram_addr; + assign unused_tlram_addr = &{1'b0, tlram_addr}; + + // Keys from key manager are only used for the full KMAC. + logic keymgr_key_en; + if (EnFullKmac == 1) begin : gen_keymgr_key_en + assign keymgr_key_en = reg2hw.cfg_shadowed.sideload.q; + end else begin : gen_no_keymgr_key_en + assign keymgr_key_en = 1'b0; + end + + // Application interface Mux/Demux + kmac_app #( + .EnMasking(EnMasking), + .SecIdleAcceptSwMsg(SecIdleAcceptSwMsg), + .NumAppIntf(NumAppIntf), + .AppCfg(AppCfg), + .EnFullKmac(EnFullKmac) + ) u_app_intf ( + .clk_i, + .rst_ni, + + .reg_key_data_i (sw_key_data), + .reg_key_len_i (sw_key_len), + + .reg_prefix_i (reg_ns_prefix), + + .reg_kmac_en_i (reg_kmac_en), + .reg_sha3_mode_i (reg_sha3_mode), + .reg_keccak_strength_i (reg_keccak_strength), + + // data from tl_adapter + .sw_valid_i (sw_msg_valid), + .sw_data_i (sw_msg_data), + .sw_mask_i (sw_msg_mask), + .sw_ready_o (sw_msg_ready), + + // KeyMgr sideloaded key interface + .keymgr_key_i, + + // Application data in / digest out interface + .app_i, + .app_o, + + // Secret Key output to KMAC Core + .key_data_o (key_data), + .key_len_o (key_len), + .key_valid_o (key_valid), + + // to MSG_FIFO + .kmac_valid_o (mux2fifo_valid), + .kmac_data_o (mux2fifo_data), + .kmac_mask_o (mux2fifo_mask), + .kmac_ready_i (mux2fifo_ready), + + // to KMAC Core + .kmac_en_o (app_kmac_en), + + // to SHA3 Core + .sha3_prefix_o (ns_prefix), + .sha3_mode_o (app_sha3_mode), + .keccak_strength_o (app_keccak_strength), + + // Keccak state from SHA3 core + .keccak_state_valid_i (state_valid), + .keccak_state_i (state), + + // to STATE TL Window + .reg_state_valid_o (reg_state_valid), + .reg_state_o (reg_state), + + // Configuration: Sideloaded Key + .keymgr_key_en_i (keymgr_key_en), + + .absorbed_i (sha3_absorbed), // from SHA3 + .absorbed_o (app_absorbed), // to SW + + .app_active_o(app_active), + + .error_i (sha3_err.valid), + .err_processed_i (err_processed), + + .clear_after_error_o (clear_after_error), + + // Command interface + .sw_cmd_i (checked_sw_cmd), + .cmd_o (kmac_cmd), + + // Status + .entropy_ready_i (entropy_configured), + + // LC escalation + .lc_escalate_en_i (lc_escalate_en[3]), + + // Error report + .error_o (app_err), + .sparse_fsm_error_o (kmac_app_state_error) + + ); + + // Message FIFO + kmac_msgfifo #( + .OutWidth (kmac_pkg::MsgWidth), + .MsgDepth (kmac_pkg::MsgFifoDepth), + .EnMasking (EnMasking) + ) u_msgfifo ( + .clk_i, + .rst_ni, + + .fifo_valid_i (mux2fifo_valid), + .fifo_data_i (mux2fifo_data), + .fifo_mask_i (mux2fifo_mask), + .fifo_ready_o (mux2fifo_ready), + + .msg_valid_o (msgfifo_valid), + .msg_data_o (msgfifo_data[0]), + .msg_strb_o (msgfifo_strb), + .msg_ready_i (msgfifo_ready), + + .fifo_empty_o (msgfifo_empty), // intr and status + .fifo_full_o (msgfifo_full), // connected to status only + .fifo_depth_o (msgfifo_depth), + + .clear_i (sha3_done), + + .process_i (reg2msgfifo_process ), + .process_o (msgfifo2kmac_process), + + .err_o (msgfifo_err) + ); + + logic [ot_sha3_pkg::StateW-1:0] reg_state_tl [Share]; + always_comb begin + for (int i = 0 ; i < Share; i++) begin + reg_state_tl[i] = reg_state_valid ? reg_state[i] : 'b0; + end + end + + // State (Digest) reader + kmac_staterd #( + .AddrW (9), // 512B + .EnMasking (EnMasking) + ) u_staterd ( + .clk_i, + .rst_ni, + + .tl_i (tl_win_h2d[WinState]), + .tl_o (tl_win_d2h[WinState]), + + .state_i (reg_state_tl), + + .endian_swap_i (reg2hw.cfg_shadowed.state_endianness.q) + ); + + // Error checker + kmac_errchk #( + .EnMasking (EnMasking) + ) u_errchk ( + .clk_i, + .rst_ni, + + // Configurations + .cfg_mode_i (reg_sha3_mode ), + .cfg_strength_i(reg_keccak_strength), + + .kmac_en_i (reg_kmac_en ), + .cfg_prefix_6B_i(reg_ns_prefix[47:0]), // first 6B of PREFIX + + .cfg_en_unsupported_modestrength_i (cfg_en_unsupported_modestrength), + + .entropy_ready_pulse_i (entropy_ready), + + // SW commands + .sw_cmd_i(sw_cmd), + .sw_cmd_o(checked_sw_cmd), + + // Status from KMAC_APP + .app_active_i(app_active), + + // Status from SHA3 core + .sha3_absorbed_i(sha3_absorbed ), + .keccak_done_i (sha3_block_processed), + + // LC escalation + .lc_escalate_en_i (lc_escalate_en[4]), + + .err_processed_i (err_processed), + .clear_after_error_i (clear_after_error), + + .error_o (errchecker_err), + .sparse_fsm_error_o (kmac_errchk_state_error) + ); + + // Entropy Generator + if (EnMasking == 1) begin : gen_entropy + + logic entropy_req, entropy_ack; + logic [edn_pkg::ENDPOINT_BUS_WIDTH-1:0] entropy_data; + logic unused_entropy_fips; + + // Synchronize EDN interface + caliptra_prim_sync_reqack_data #( + .Width(edn_pkg::ENDPOINT_BUS_WIDTH), + .DataSrc2Dst(1'b0), + .DataReg(1'b0) + ) u_caliptra_prim_sync_reqack_data ( + .clk_src_i (clk_i), + .rst_src_ni(rst_ni), + .clk_dst_i (clk_edn_i), + .rst_dst_ni(rst_edn_ni), + .req_chk_i (1'b1), + .src_req_i (entropy_req), + .src_ack_o (entropy_ack), + .dst_req_o (entropy_o.edn_req), + .dst_ack_i (entropy_i.edn_ack), + .data_i (entropy_i.edn_bus), + .data_o (entropy_data) + ); + + // We don't track whether the entropy is pre-FIPS or not inside KMAC. + assign unused_entropy_fips = entropy_i.edn_fips; + + kmac_entropy #( + .RndCnstLfsrPerm(RndCnstLfsrPerm), + .RndCnstLfsrSeed(RndCnstLfsrSeed), + .RndCnstBufferLfsrSeed(RndCnstBufferLfsrSeed) + ) u_entropy ( + .clk_i, + .rst_ni, + + // EDN interface + .entropy_req_o (entropy_req), + .entropy_ack_i (entropy_ack), + .entropy_data_i(entropy_data), + + // Entropy to internal logic (DOM AND) + .rand_valid_o (sha3_rand_valid), + .rand_early_o (sha3_rand_early), + .rand_data_o (sha3_rand_data), + .rand_aux_o (sha3_rand_aux), + .rand_update_i (sha3_rand_update), + .rand_consumed_i (sha3_rand_consumed), + + // Status from internal logic + //// KMAC secret block handling indicator + .in_keyblock_i (entropy_in_keyblock), + + // Configuration + .mode_i (entropy_mode), + .entropy_ready_i (entropy_ready), + .fast_process_i (entropy_fast_process), + + //// Entropy refresh period in clk cycles + .wait_timer_prescaler_i (wait_timer_prescaler), + .wait_timer_limit_i (wait_timer_limit), + + //// Message Masking + .msg_mask_en_i (msg_mask_en), + .msg_mask_o (msg_mask), + + //// SW update of seed + .seed_update_i (entropy_seed_update), + .seed_data_i (entropy_seed_data), + .entropy_refresh_req_i (entropy_refresh_req), + + // Status + .hash_cnt_o (entropy_hash_cnt), + .hash_cnt_clr_i (entropy_hash_clr), + .hash_threshold_i (entropy_hash_threshold), + + .entropy_configured_o (entropy_configured), + + // LC escalation + .lc_escalate_en_i (lc_escalate_en[5]), + + // Error + .err_o (entropy_err), + .sparse_fsm_error_o (kmac_entropy_state_error), + .count_error_o (kmac_entropy_hash_counter_error), + .err_processed_i (err_processed) + ); + end else begin : gen_empty_entropy + // If Masking is not used, no need of entropy. Ignore inputs and config; tie output to 0. + edn_pkg::edn_rsp_t unused_entropy_input; + entropy_mode_e unused_entropy_mode; + logic unused_entropy_fast_process; + + assign unused_entropy_input = entropy_i; + assign unused_entropy_mode = entropy_mode; + assign unused_entropy_fast_process = entropy_fast_process; + + assign entropy_o = '{default: '0}; + + logic unused_sha3_rand_update; + logic unused_sha3_rand_consumed; + assign sha3_rand_valid = 1'b 1; + assign sha3_rand_early = 1'b 1; + assign sha3_rand_data = '0; + assign sha3_rand_aux = '0; + assign unused_sha3_rand_update = sha3_rand_update; + assign unused_sha3_rand_consumed = sha3_rand_consumed; + + logic unused_seed_update; + logic unused_seed_data; + logic unused_refresh_period; + logic unused_entropy_refresh_req; + assign unused_seed_data = ^entropy_seed_data; + assign unused_seed_update = entropy_seed_update; + assign unused_refresh_period = ^{wait_timer_limit, wait_timer_prescaler}; + assign unused_entropy_refresh_req = entropy_refresh_req; + + logic unused_entropy_hash; + assign unused_entropy_hash = ^{entropy_hash_clr, entropy_hash_threshold}; + assign entropy_hash_cnt = '0; + + assign entropy_err = '{valid: 1'b 0, code: ErrNone, info: '0}; + + assign kmac_entropy_state_error = 1'b 0; + assign kmac_entropy_hash_counter_error = 1'b 0; + + logic unused_entropy_status; + assign unused_entropy_status = entropy_in_keyblock; + + // If Masking is off, always entropy configured + assign entropy_configured = MuBi4True; + + logic unused_edn_clk_rst; + assign unused_edn_clk_rst = ^{clk_edn_i, rst_edn_ni}; + + logic unused_lc_escalate_en5; + assign unused_lc_escalate_en5 = ^lc_escalate_en[5]; + end + + // MUBI4 buf + caliptra_prim_mubi4_sender #( + .AsyncOn (0) + ) u_sha3_done_sender ( + .clk_i, + .rst_ni, + .mubi_i (sha3_done_d), + .mubi_o (sha3_done) + ); + + // Register top + logic [NumAlerts-1:0] alert_test, alerts, alerts_q; + + logic shadowed_storage_err, shadowed_update_err; + kmac_reg_top u_reg ( + .clk_i, + .rst_ni, + .rst_shadowed_ni, + + .tl_i, + .tl_o, + + .tl_win_o (tl_win_h2d), + .tl_win_i (tl_win_d2h), + + .reg2hw, + .hw2reg, + + // SEC_CM: CFG_SHADOWED.CONFIG.SHADOW + .shadowed_storage_err_o (shadowed_storage_err), + .shadowed_update_err_o (shadowed_update_err), + // SEC_CM: BUS.INTEGRITY + .intg_err_o (alert_intg_err) + ); + + logic unused_cfg_shadowed_qe; + if (EnFullKmac) begin : gen_unused_full_kmac_reg + assign unused_cfg_shadowed_qe = ^{ + reg2hw.cfg_shadowed.kmac_en.qe , + reg2hw.cfg_shadowed.kstrength.qe , + reg2hw.cfg_shadowed.mode.qe , + reg2hw.cfg_shadowed.msg_endianness.qe , + reg2hw.cfg_shadowed.state_endianness.qe , + reg2hw.cfg_shadowed.sideload.qe , + reg2hw.cfg_shadowed.entropy_mode.qe , + reg2hw.cfg_shadowed.entropy_fast_process.qe , + reg2hw.cfg_shadowed.msg_mask.qe , + reg2hw.cfg_shadowed.en_unsupported_modestrength.qe + }; + end else begin : gen_unused_partial_kmac_reg + // If KMAC is disabled there are less signals in the cfg_shadowed register. + assign unused_cfg_shadowed_qe = ^{ + reg2hw.cfg_shadowed.kstrength.qe , + reg2hw.cfg_shadowed.mode.qe , + reg2hw.cfg_shadowed.msg_endianness.qe , + reg2hw.cfg_shadowed.state_endianness.qe + }; + end + + // Alerts + assign alert_test = { + reg2hw.alert_test.fatal_fault_err.q + & reg2hw.alert_test.fatal_fault_err.qe, // [1] + reg2hw.alert_test.recov_operation_err.q + & reg2hw.alert_test.recov_operation_err.qe // [0] + }; + + assign alerts = { + alert_fatal, // Alerts[1] + alert_recov_operation // Alerts[0] + }; + + assign alert_recov_operation = shadowed_update_err; + + // The recoverable alert is observable via status register until the KMAC operation is restarted + // by re-writing the Control Register. + logic status_alert_recov_ctrl_update_err; + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + status_alert_recov_ctrl_update_err <= 1'b 0; + end else if (alert_recov_operation) begin + status_alert_recov_ctrl_update_err <= 1'b 1; + end else if (err_processed) begin + status_alert_recov_ctrl_update_err <= 1'b 0; + end + end + + assign hw2reg.status.alert_recov_ctrl_update_err.d = status_alert_recov_ctrl_update_err; + + assign alert_fatal = shadowed_storage_err + | alert_intg_err + | sparse_fsm_error + | counter_error + | control_integrity_error + ; + + // Make the fatal alert observable via status register. + // Cannot be reset except the hardware reset + logic status_alert_fatal_fault; + + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + status_alert_fatal_fault <= 1'b 0; + end else if (alert_fatal) begin + status_alert_fatal_fault <= 1'b 1; + end + end + assign hw2reg.status.alert_fatal_fault.d = status_alert_fatal_fault; + + for (genvar i = 0; i < NumAlerts; i++) begin : gen_alert_tx + caliptra_prim_alert_sender #( + .AsyncOn(AlertAsyncOn[i]), + .IsFatal(i) + ) u_caliptra_prim_alert_sender ( + .clk_i, + .rst_ni, + .alert_test_i ( alert_test[i] ), + .alert_req_i ( alerts[i] ), + .alert_ack_o ( ), + .alert_state_o ( ), + .alert_rx_i ( alert_rx_i[i] ), + .alert_tx_o ( alert_tx_o[i] ) + ); + end + + // Below assumes NumAlerts == 2 + `CALIPTRA_ASSERT_INIT(NumAlerts2_A, NumAlerts == 2) + + always_ff @(posedge clk_i or negedge rst_ni) begin + // break up the combinatorial path for local escalation + if (!rst_ni) begin + alerts_q[1] <= 1'b0; + end else if (alerts[1]) begin + // fatal alerts cannot be cleared + alerts_q[1] <= 1'b1; + end + end + + always_ff @(posedge clk_i or negedge rst_ni) begin + // break up the combinatorial path for local escalation + if (!rst_ni) begin + alerts_q[0] <= 1'b0; + end else begin + // recoverable alerts can be cleared so just latch the value + alerts_q[0] <= alerts[0]; + end + end + + // Latched recoverable alert[0] is not used. Rather removing above, + // keep alert_q[1:0] and make alert_q[0] unused (lint waive). + logic unused_alerts_q0; + assign unused_alerts_q0 = alerts_q[0]; + + // SEC_CM: LC_ESCALATE_EN.INTERSIG.MUBI, FSM.GLOBAL_ESC, FSM.LOCAL_ESC + lc_ctrl_pkg::lc_tx_t alert_to_lc_tx; + assign alert_to_lc_tx = lc_ctrl_pkg::lc_tx_bool_to_lc_tx(alerts_q[1]); + for (genvar i = 0; i < NumLcSyncCopies; i++) begin : gen_or_alert_lc_sync + assign lc_escalate_en[i] = lc_ctrl_pkg::lc_tx_or_hi(alert_to_lc_tx, lc_escalate_en_sync[i]); + end + + // Synchronize life cycle input + caliptra_prim_lc_sync #( + .NumCopies (NumLcSyncCopies) + ) u_caliptra_prim_lc_sync ( + .clk_i, + .rst_ni, + .lc_en_i ( lc_escalate_en_i ), + .lc_en_o ( lc_escalate_en_sync ) + ); + + assign en_masking_o = EnMasking; + + //////////////// + // Assertions // + //////////////// + + // Assert known for output values + `CALIPTRA_ASSERT_KNOWN(KmacDone_A, intr_kmac_done_o) + `CALIPTRA_ASSERT_KNOWN(FifoEmpty_A, intr_fifo_empty_o) + `CALIPTRA_ASSERT_KNOWN(KmacErr_A, intr_kmac_err_o) + `CALIPTRA_ASSERT_KNOWN(TlODValidKnown_A, tl_o.d_valid) + `CALIPTRA_ASSERT_KNOWN(TlOAReadyKnown_A, tl_o.a_ready) + `CALIPTRA_ASSERT_KNOWN(AlertKnownO_A, alert_tx_o) + `CALIPTRA_ASSERT_KNOWN(EnMaskingKnown_A, en_masking_o) + + // Parameter as desired + `CALIPTRA_ASSERT_INIT(SecretKeyDivideBy32_A, (kmac_pkg::MaxKeyLen % 32) == 0) + + // Command input should be sparse + `CALIPTRA_ASSUME(CmdSparse_M, reg2hw.cmd.cmd.qe |-> reg2hw.cmd.cmd.q inside {CmdStart, CmdProcess, + CmdManualRun,CmdDone, CmdNone}) + + // redundant counter error + `CALIPTRA_ASSERT_PRIM_COUNT_ERROR_TRIGGER_ALERT(SentMsgCountCheck_A, u_sha3.u_pad.u_sentmsg_count, + alert_tx_o[1]) + `CALIPTRA_ASSERT_PRIM_COUNT_ERROR_TRIGGER_ALERT(RoundCountCheck_A, u_sha3.u_keccak.u_round_count, + alert_tx_o[1]) + + if (EnFullKmac == 1) begin : gen_assert_key_index_cnt + `CALIPTRA_ASSERT_PRIM_COUNT_ERROR_TRIGGER_ALERT(KeyIndexCountCheck_A, + gen_kmac_core.u_kmac_core.u_key_index_count, + alert_tx_o[1]) + end + + // Sparse FSM state error + `CALIPTRA_ASSERT_PRIM_FSM_ERROR_TRIGGER_ALERT(KmacAppFsmCheck_A, u_app_intf.u_state_regs, alert_tx_o[1]) + `CALIPTRA_ASSERT_PRIM_FSM_ERROR_TRIGGER_ALERT(SHA3FsmCheck_A, u_sha3.u_state_regs, alert_tx_o[1]) + `CALIPTRA_ASSERT_PRIM_FSM_ERROR_TRIGGER_ALERT(SHA3padFsmCheck_A, u_sha3.u_pad.u_state_regs, alert_tx_o[1]) + `CALIPTRA_ASSERT_PRIM_FSM_ERROR_TRIGGER_ALERT(KeccackFsmCheck_A, u_sha3.u_keccak.u_state_regs, + alert_tx_o[1]) + `CALIPTRA_ASSERT_PRIM_FSM_ERROR_TRIGGER_ALERT(ErrorCheckFsmCheck_A, u_errchk.u_state_regs, alert_tx_o[1]) + `CALIPTRA_ASSERT_PRIM_FSM_ERROR_TRIGGER_ALERT(KmacFsmCheck_A, u_state_regs, alert_tx_o[1]) + if (EnFullKmac == 1) begin : gen_assert_kmac_core_fsm + `CALIPTRA_ASSERT_PRIM_FSM_ERROR_TRIGGER_ALERT(KmacCoreFsmCheck_A, gen_kmac_core.u_kmac_core.u_state_regs, + alert_tx_o[1]) + end + + // prim is only instantiated if masking is enabled + if (EnMasking == 1) begin : g_testassertion + `CALIPTRA_ASSERT_PRIM_FSM_ERROR_TRIGGER_ALERT(EntropyFsmCheck_A, gen_entropy.u_entropy.u_state_regs, + alert_tx_o[1]) + + `CALIPTRA_ASSERT_PRIM_COUNT_ERROR_TRIGGER_ALERT(HashCountCheck_A, gen_entropy.u_entropy.u_hash_count, + alert_tx_o[1]) + + // MsgFifo.Packer + `CALIPTRA_ASSERT_PRIM_COUNT_ERROR_TRIGGER_ALERT( + PackerCountCheck_A, + u_msgfifo.u_packer.g_pos_dupcnt.u_pos, + alert_tx_o[1] + ) + + // MsgFifo.Fifo + `CALIPTRA_ASSERT_PRIM_COUNT_ERROR_TRIGGER_ALERT( + MsgFifoWptrCheck_A, + u_msgfifo.u_msgfifo.gen_normal_fifo.u_fifo_cnt.gen_secure_ptrs.u_wptr, + alert_tx_o[1] + ) + `CALIPTRA_ASSERT_PRIM_COUNT_ERROR_TRIGGER_ALERT( + MsgFifoRptrCheck_A, + u_msgfifo.u_msgfifo.gen_normal_fifo.u_fifo_cnt.gen_secure_ptrs.u_rptr, + alert_tx_o[1] + ) + end + + // Alert assertions for reg_we onehot check + `CALIPTRA_ASSERT_PRIM_REG_WE_ONEHOT_ERROR_TRIGGER_ALERT(RegWeOnehotCheck_A, u_reg, alert_tx_o[1]) + + // Assertions for the case where EnFullKmac is 0. + // In this case KMAC is stripped down to only support SHA3, SHAKE and cSHAKE. + `CALIPTRA_ASSERT(StrippedKmacMaskingDisabled_A, EnFullKmac == 0 |-> EnMasking == 0) + `CALIPTRA_ASSUME(StrippedKmacState_M, EnFullKmac == 0 |-> kmac_st inside + {KmacIdle, KmacPrefix, KmacMsgFeed, KmacDigest, KmacTerminalError}) + `CALIPTRA_ASSUME(StrippedSha3Mode_M, EnFullKmac == 0 |-> app_sha3_mode inside + {ot_sha3_pkg::Sha3, ot_sha3_pkg::Shake, ot_sha3_pkg::CShake}) +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/kmac_app.sv b/designs/Caliptra/src/caliptra-rtl/kmac_app.sv new file mode 100644 index 0000000..43e3671 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/kmac_app.sv @@ -0,0 +1,1010 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// KMAC Application interface + +`include "caliptra_prim_assert.sv" + +module kmac_app + import caliptra_prim_mubi_pkg::*; + import kmac_pkg::*; +#( + // App specific configs are defined in kmac_pkg + parameter bit EnMasking = 1'b0, + parameter bit EnFullKmac = 1'b1, + localparam int Share = (EnMasking) ? 2 : 1, // derived parameter + parameter bit SecIdleAcceptSwMsg = 1'b0, + parameter int unsigned NumAppIntf = 2, + parameter app_config_t AppCfg[NumAppIntf] = '{AppCfgKeyMgrStripped, AppCfgKeyMgrStripped} +) ( + input clk_i, + input rst_ni, + + // Secret Key from register + input [MaxKeyLen-1:0] reg_key_data_i [Share], + input key_len_e reg_key_len_i, + + // Prefix from register + input [ot_sha3_pkg::NSRegisterSize*8-1:0] reg_prefix_i, + + // mode, strength, kmac_en from register + input reg_kmac_en_i, + input ot_sha3_pkg::sha3_mode_e reg_sha3_mode_i, + input ot_sha3_pkg::keccak_strength_e reg_keccak_strength_i, + + // Data from Software + input sw_valid_i, + input [MsgWidth-1:0] sw_data_i, + input [MsgWidth-1:0] sw_mask_i, + output logic sw_ready_o, + + // KeyMgr Sideload Key interface + input keymgr_pkg::hw_key_req_t keymgr_key_i, + + // Application Message in/ Digest out interface + control signals + input app_req_t [NumAppIntf-1:0] app_i, + output app_rsp_t [NumAppIntf-1:0] app_o, + + // to KMAC Core: Secret key + output logic [MaxKeyLen-1:0] key_data_o [Share], + output key_len_e key_len_o, + output logic key_valid_o, + + // to MSG_FIFO + output logic kmac_valid_o, + output logic [MsgWidth-1:0] kmac_data_o, + output logic [MsgWidth-1:0] kmac_mask_o, + input kmac_ready_i, + + // KMAC Core + output logic kmac_en_o, + + // To Sha3 Core + output logic [ot_sha3_pkg::NSRegisterSize*8-1:0] sha3_prefix_o, + output ot_sha3_pkg::sha3_mode_e sha3_mode_o, + output ot_sha3_pkg::keccak_strength_e keccak_strength_o, + + // STATE from SHA3 Core + input keccak_state_valid_i, + input [ot_sha3_pkg::StateW-1:0] keccak_state_i [Share], + + // to STATE TL-window if Application is not active, the incoming state goes to + // register if kdf_en is set, the state value goes to application and the + // output to the register is all zero. + output logic reg_state_valid_o, + output logic [ot_sha3_pkg::StateW-1:0] reg_state_o [Share], + + // Configurations If key_en is set, the logic uses KeyMgr's sideloaded key as + // a secret key rather than register values. This only affects when software + // initiates. If App initiates the hash operation and uses KMAC algorithm, it + // always uses sideloaded key. + input keymgr_key_en_i, + + // Commands + // Command from software + input kmac_cmd_e sw_cmd_i, + + // from SHA3 + input mubi4_t absorbed_i, + + // to KMAC + output kmac_cmd_e cmd_o, + + // to SW + output mubi4_t absorbed_o, + + // To status + output logic app_active_o, + + // Status + // - entropy_ready_i: Entropy configured by SW. It is used to check if App + // is OK to request. + input mubi4_t entropy_ready_i, + + // Error input + // This error comes from KMAC/SHA3 engine. + // KeyMgr interface delivers the error signal to KeyMgr to drop the current op + // and re-initiate. + // If error happens, regardless of SW-initiated or KeyMgr-initiated, the error + // is reported to the ERR_CODE so that SW can look into. + input error_i, + + // SW sets err_processed bit in CTRL then the logic goes to Idle + input err_processed_i, + + output mubi4_t clear_after_error_o, + + // error_o value is pushed to Error FIFO at KMAC/SHA3 top and reported to SW + output kmac_pkg::err_t error_o, + + // Life cycle + input lc_ctrl_pkg::lc_tx_t lc_escalate_en_i, + + output logic sparse_fsm_error_o +); + + import ot_sha3_pkg::KeccakBitCapacity; + import ot_sha3_pkg::L128; + import ot_sha3_pkg::L224; + import ot_sha3_pkg::L256; + import ot_sha3_pkg::L384; + import ot_sha3_pkg::L512; + + ///////////////// + // Definitions // + ///////////////// + + // Digest width is same to the key width `keymgr_pkg::KeyWidth`. + localparam int KeyMgrKeyW = $bits(keymgr_key_i.key[0]); + + localparam key_len_e KeyLengths [5] = '{Key128, Key192, Key256, Key384, Key512}; + + localparam int SelKeySize = (AppKeyW == 128) ? 0 : + (AppKeyW == 192) ? 1 : + (AppKeyW == 256) ? 2 : + (AppKeyW == 384) ? 3 : + (AppKeyW == 512) ? 4 : 0 ; + localparam int SelDigSize = (AppDigestW == 128) ? 0 : + (AppDigestW == 192) ? 1 : + (AppDigestW == 256) ? 2 : + (AppDigestW == 384) ? 3 : + (AppDigestW == 512) ? 4 : 0 ; + localparam key_len_e SideloadedKey = KeyLengths[SelKeySize]; + + // Define right_encode(outlen) value here + // Look at kmac_pkg::key_len_e for the kinds of key size + // + // These values should be exactly the same as the key length encodings + // in kmac_core.sv, with the only difference being that the byte representing + // the byte-length of the encoded value is in the MSB position due to right encoding + // instead of in the LSB position (left encoding). + localparam int OutLenW = 24; + localparam logic [OutLenW-1:0] EncodedOutLen [5]= '{ + 24'h 0001_80, // Key128 + 24'h 0001_C0, // Key192 + 24'h 02_0001, // Key256 + 24'h 02_8001, // Key384 + 24'h 02_0002 // Key512 + }; + + localparam logic [OutLenW-1:0] EncodedOutLenMask [5] = '{ + 24'h 00FFFF, // Key128, + 24'h 00FFFF, // Key192 + 24'h FFFFFF, // Key256 + 24'h FFFFFF, // Key384 + 24'h FFFFFF // Key512 + }; + + ///////////// + // Signals // + ///////////// + + st_e st, st_d; + + logic keymgr_key_used; + + // app_rsp_t signals + // The state machine controls mux selection, which controls the ready signal + // the other responses are controled in separate logic. So define the signals + // here and merge them to the response. + logic app_data_ready, fsm_data_ready; + logic app_digest_done, fsm_digest_done_q, fsm_digest_done_d; + logic [AppDigestW-1:0] app_digest [2]; + + // One more slot for value NumAppIntf. It is the value when no app intf is + // chosen. + localparam int unsigned AppIdxW = $clog2(NumAppIntf); + + // app_id indicates, which app interface was chosen. various logic use this + // value to get the config or return the data. + logic [AppIdxW-1:0] app_id, app_id_d; + logic clr_appid, set_appid; + + // Output length + logic [OutLenW-1:0] encoded_outlen, encoded_outlen_mask; + + // state output + // Mux selection signal + app_mux_sel_e mux_sel; + app_mux_sel_e mux_sel_buf_output; + app_mux_sel_e mux_sel_buf_err_check; + app_mux_sel_e mux_sel_buf_kmac; + + // Error checking logic + + kmac_pkg::err_t fsm_err, mux_err; + + logic service_rejected_error; + logic service_rejected_error_set, service_rejected_error_clr; + logic err_during_sw_d, err_during_sw_q; + + // The service rejected error only occurs for the full KMAC configuration. + if (EnFullKmac) begin : gen_service_rejected_error + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) service_rejected_error <= 1'b 0; + else if (service_rejected_error_set) service_rejected_error <= 1'b 1; + else if (service_rejected_error_clr) service_rejected_error <= 1'b 0; + end + end else begin : gen_no_service_rejected_error + assign service_rejected_error = 1'b0; + logic unused_service_rejected_error_signals; + assign unused_service_rejected_error_signals = ^{service_rejected_error_set, + service_rejected_error_clr}; + end + + //////////////////////////// + // Application Mux/ Demux // + //////////////////////////// + + + // Processing return data. + // sends to only selected app intf. + // clear digest right after done to not leak info to other interface + always_comb begin + for (int unsigned i = 0 ; i < NumAppIntf ; i++) begin + if (i == app_id) begin + app_o[i] = '{ + ready: app_data_ready | fsm_data_ready, + done: app_digest_done | fsm_digest_done_q, + digest_share0: app_digest[0], + digest_share1: app_digest[1], + // if fsm asserts done, should be an error case. + error: error_i | fsm_digest_done_q | sparse_fsm_error_o + | service_rejected_error + }; + end else begin + app_o[i] = '{ + ready: 1'b 0, + done: 1'b 0, + digest_share0: '0, + digest_share1: '0, + error: 1'b 0 + }; + end + end // for {i, NumAppIntf, i++} + end // aiways_comb + + // app_id latch + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) app_id <= AppIdxW'(0) ; // Do not select any + else if (clr_appid) app_id <= AppIdxW'(0); + else if (set_appid) app_id <= app_id_d; + end + + // app_id selection as of now, app_id uses Priority. The assumption is that + // the request normally does not collide. (ROM_CTRL activates very early + // stage at the boot sequence) + // + // If this assumption is not true, consider RR arbiter. + + // Prep for arbiter + logic [NumAppIntf-1:0] app_reqs; + logic [NumAppIntf-1:0] unused_app_gnts; + logic [$clog2(NumAppIntf)-1:0] arb_idx; + logic arb_valid; + logic arb_ready; + + always_comb begin + app_reqs = '0; + for (int unsigned i = 0 ; i < NumAppIntf ; i++) begin + app_reqs[i] = app_i[i].valid; + end + end + + caliptra_prim_arbiter_fixed #( + .N (NumAppIntf), + .DW(1), + .EnDataPort(1'b 0) + ) u_appid_arb ( + .clk_i, + .rst_ni, + + .req_i (app_reqs), + .data_i ('{default:'0}), + .gnt_o (unused_app_gnts), + .idx_o (arb_idx), + + .valid_o (arb_valid), + .data_o (), // not used + .ready_i (arb_ready) + ); + + assign app_id_d = AppIdxW'(arb_idx); + assign arb_ready = set_appid; + + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) fsm_digest_done_q <= 1'b 0; + else fsm_digest_done_q <= fsm_digest_done_d; + end + + ///////// + // FSM // + ///////// + + // State register + `CALIPTRA_PRIM_FLOP_SPARSE_FSM(u_state_regs, st_d, st, st_e, StIdle) + + // Create a lint error to reduce the risk of accidentally enabling this feature. + `CALIPTRA_ASSERT_STATIC_LINT_ERROR(KmacSecIdleAcceptSwMsgNonDefault, SecIdleAcceptSwMsg == 0) + + // Next State & output logic + // SEC_CM: FSM.SPARSE + always_comb begin + st_d = st; + + mux_sel = SecIdleAcceptSwMsg ? SelSw : SelNone; + + // app_id control + set_appid = 1'b 0; + clr_appid = 1'b 0; + + // Commands + cmd_o = CmdNone; + + // Software output + absorbed_o = MuBi4False; + + // Error + fsm_err = '{valid: 1'b 0, code: ErrNone, info: '0}; + sparse_fsm_error_o = 1'b 0; + + clear_after_error_o = MuBi4False; + + service_rejected_error_set = 1'b 0; + service_rejected_error_clr = 1'b 0; + + // If error happens, FSM asserts data ready but discard incoming msg + fsm_data_ready = 1'b 0; + fsm_digest_done_d = 1'b 0; + + unique case (st) + StIdle: begin + if (arb_valid) begin + st_d = StAppCfg; + + // choose app_id + set_appid = 1'b 1; + end else if (sw_cmd_i == CmdStart) begin + st_d = StSw; + // Software initiates the sequence + cmd_o = CmdStart; + end else begin + st_d = StIdle; + end + end + + StAppCfg: begin + if (EnFullKmac) begin : gen_app_cfg_state_error + if (AppCfg[app_id].Mode == AppKMAC && + mubi4_test_false_strict(entropy_ready_i)) begin + // Check if the entropy is not configured but it is needed in + // `AppCfg[app_id]` (KMAC mode). + // + // SW is not properly configured, report and not request Hashing + // Return the app with errors + st_d = StError; + + service_rejected_error_set = 1'b 1; + + end else begin + // As Cfg is stable now, it sends cmd + st_d = StAppMsg; + + // App initiates the data + cmd_o = CmdStart; + end + end else begin : gen_no_app_cfg_state_error + // As Cfg is stable now, it sends cmd + st_d = StAppMsg; + + // App initiates the data + cmd_o = CmdStart; + end + end + + StAppMsg: begin + mux_sel = SelApp; + if (app_i[app_id].valid && app_o[app_id].ready && app_i[app_id].last) begin + + // The StAppOutLen transition only exists if the full KMAC is enabled. + if (EnFullKmac) begin : gen_app_msg_state_kmac + if (AppCfg[app_id].Mode == AppKMAC) begin + st_d = StAppOutLen; + end else begin + st_d = StAppProcess; + end + // With KMAC disabled the next state is StAppProcess. + end else begin : gen_app_msg_state_no_kmac + st_d = StAppProcess; + end + + end else begin + st_d = StAppMsg; + end + end + + StAppOutLen: begin + if (EnFullKmac) begin : gen_app_out_len_state + mux_sel = SelOutLen; + + if (kmac_valid_o && kmac_ready_i) begin + st_d = StAppProcess; + end else begin + st_d = StAppOutLen; + end + end else begin : gen_no_app_out_len_state + // If KMAC is disabled, this state should never be reached. + st_d = StTerminalError; + sparse_fsm_error_o = 1'b 1; + end + end + + StAppProcess: begin + cmd_o = CmdProcess; + st_d = StAppWait; + end + + StAppWait: begin + if (mubi4_test_true_strict(absorbed_i)) begin + // Send digest to KeyMgr and complete the op + st_d = StIdle; + cmd_o = CmdDone; + + clr_appid = 1'b 1; + end else begin + st_d = StAppWait; + end + end + + StSw: begin + mux_sel = SelSw; + + cmd_o = sw_cmd_i; + absorbed_o = absorbed_i; + + if (sw_cmd_i == CmdDone) begin + st_d = StIdle; + end else begin + st_d = StSw; + end + end + + StKeyMgrErrKeyNotValid: begin + st_d = StError; + + // As mux_sel is not set to SelApp, app_data_ready is still 0. + // This logic won't accept the requests from the selected App. + fsm_err.valid = 1'b 1; + fsm_err.code = ErrKeyNotValid; + fsm_err.info = 24'(app_id); + end + + StError: begin + // In this state, the state machine flush out the request + st_d = StError; + + // Absorb data on the app interface. + fsm_data_ready = ~err_during_sw_q; + + // Next step depends on two conditions: + // 1) Error being processed by SW + // 2) Last data provided from the app interface (so that the app interface is completely) + // drained. If the error occurred during a SW operation, the app interface is not + // involved, so this condition gets skipped. + unique case ({err_processed_i, + (app_i[app_id].valid && app_i[app_id].last) || err_during_sw_q}) + 2'b00: begin + // Error not processed by SW and not last data from app interface -> keep current state. + st_d = StError; + end + 2'b01: begin + // Error not processed by SW but last data from app interface: + // 1. Send garbage digest to the app interface (in the next cycle) to complete the + // transaction. + fsm_digest_done_d = ~err_during_sw_q; + if (service_rejected_error) begin + // 2.a) Service was rejected because an app interface tried to configure KMAC while no + // entropy was available. It is assumed that SW is not loaded yet, so don't wait for + // SW to process the error. The last data from the app interface has now arrived, but + // we don't need to wait for the SHA3 core to have absorbed it because the data never + // entered the SHA3 core: the request from the app interface was terminated during the + // configuration phase. + st_d = StErrorServiceRejected; + end else begin + // 2.b) If service was not rejected, wait for SW to process the error. + st_d = StErrorAwaitSw; + end + end + 2'b10: begin + // Error processed by SW but not last data from app interface -> wait for app interface. + st_d = StErrorAwaitApp; + end + 2'b11: begin + // Error processed by SW and last data from app interface: + // Send garbage digest to the app interface (in the next cycle) to complete the + // transaction. + fsm_digest_done_d = ~err_during_sw_q; + // Flush the message FIFO and let the SHA3 engine compute a digest (which won't be used + // but serves to bring the SHA3 engine back to the idle state). + cmd_o = CmdProcess; + st_d = StErrorWaitAbsorbed; + end + default: st_d = StError; + endcase + end + + StErrorAwaitSw: begin + // Just wait for SW to process the error. + if (err_processed_i) begin + // Flush the message FIFO and let the SHA3 engine compute a digest (which won't be used + // but serves to bring the SHA3 engine back to the idle state). + cmd_o = CmdProcess; + st_d = StErrorWaitAbsorbed; + end + end + + StErrorAwaitApp: begin + // Keep absorbing data on the app interface until the last data. + fsm_data_ready = 1'b1; + if (app_i[app_id].valid && app_i[app_id].last) begin + // Send garbage digest to the app interface (in the next cycle) to complete the + // transaction. + fsm_digest_done_d = 1'b1; + // Flush the message FIFO and let the SHA3 engine compute a digest (which won't be used + // but serves to bring the SHA3 engine back to the idle state). + cmd_o = CmdProcess; + st_d = StErrorWaitAbsorbed; + end + end + + StErrorWaitAbsorbed: begin + if (mubi4_test_true_strict(absorbed_i)) begin + // Clear internal variables, send done command, and return to idle. + clr_appid = 1'b1; + clear_after_error_o = MuBi4True; + service_rejected_error_clr = 1'b1; + cmd_o = CmdDone; + st_d = StIdle; + // If error originated from SW, report 'absorbed' to SW. + if (err_during_sw_q) begin + absorbed_o = MuBi4True; + end + end + end + + StErrorServiceRejected: begin + // Clear internal variables and return to idle. + clr_appid = 1'b1; + clear_after_error_o = MuBi4True; + service_rejected_error_clr = 1'b1; + st_d = StIdle; + end + + StTerminalError: begin + // this state is terminal + st_d = st; + sparse_fsm_error_o = 1'b 1; + fsm_err.valid = 1'b 1; + fsm_err.code = ErrFatalError; + fsm_err.info = 24'(app_id); + end + + default: begin + st_d = StTerminalError; + sparse_fsm_error_o = 1'b 1; + end + endcase + + // SEC_CM: FSM.GLOBAL_ESC, FSM.LOCAL_ESC + // Unconditionally jump into the terminal error state + // if the life cycle controller triggers an escalation. + if (lc_ctrl_pkg::lc_tx_test_true_loose(lc_escalate_en_i)) begin + st_d = StTerminalError; + end + + if (EnFullKmac == 1) begin : gen_invalid_key_used + // Handle errors outside the terminal error state. + // Key from keymgr is used but not valid, so abort into the invalid key error state. + if ((st_d != StTerminalError) && keymgr_key_used && !keymgr_key_i.valid) begin + st_d = StKeyMgrErrKeyNotValid; + end + end + + end + + if (EnFullKmac != 1) begin : gen_unused_entropy_ready + logic unused_entropy_ready; + assign unused_entropy_ready = ^entropy_ready_i; + end + + // Track errors occurring in SW mode. + assign err_during_sw_d = + (mux_sel == SelSw) && (st_d inside {StError, StKeyMgrErrKeyNotValid}) ? 1'b1 : // set + (st_d == StIdle) ? 1'b0 : // clear + err_during_sw_q; // hold + +`ifdef CALIPTRA + // In Caliptra st_d can never leave StIdle, so this flop is stuck in reset state. + // Remoing it to avoid lint errors. + assign err_during_sw_q = '0; +`else + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + err_during_sw_q <= 1'b0; + end else begin + err_during_sw_q <= err_during_sw_d; + end + end + `endif + + ////////////// + // Datapath // + ////////////// + + // Encoded output length + assign encoded_outlen = EncodedOutLen[SelDigSize]; + assign encoded_outlen_mask = EncodedOutLenMask[SelKeySize]; + + // Data mux + // This is the main part of the KeyMgr interface logic. + // The FSM selects KeyMgr interface in a cycle after it receives the first + // valid data from KeyMgr. The ready signal to the KeyMgr data interface + // represents the MSG_FIFO ready, only when it is in StKeyMgrMsg state. + // After KeyMgr sends last beat, the kmac interface (to MSG_FIFO) is switched + // to OutLen. OutLen is pre-defined values. See `EncodeOutLen` parameter above. + always_comb begin + app_data_ready = 1'b 0; + sw_ready_o = 1'b 1; + + kmac_valid_o = 1'b 0; + kmac_data_o = '0; + kmac_mask_o = '0; + + unique case (mux_sel_buf_kmac) + SelApp: begin + // app_id is valid at this time + kmac_valid_o = app_i[app_id].valid; + kmac_data_o = app_i[app_id].data; + // Expand strb to bits. prim_packer inside MSG_FIFO accepts the bit masks + for (int i = 0 ; i < $bits(app_i[app_id].strb) ; i++) begin + kmac_mask_o[8*i+:8] = {8{app_i[app_id].strb[i]}}; + end + app_data_ready = kmac_ready_i; + end + + SelOutLen: begin + if (EnFullKmac) begin : gen_sel_out_len_state_kmac + // Write encoded output length value + kmac_valid_o = 1'b 1; // always write + kmac_data_o = MsgWidth'(encoded_outlen); + kmac_mask_o = MsgWidth'(encoded_outlen_mask); + end else begin : gen_sel_out_len_state_no_kmac + // If KMAC is disabled, this state should never be reached. + kmac_valid_o = 1'b 0; + kmac_data_o = '0; + kmac_mask_o = '0; + end + end + + SelSw: begin + kmac_valid_o = sw_valid_i; + kmac_data_o = sw_data_i ; + kmac_mask_o = sw_mask_i ; + sw_ready_o = kmac_ready_i ; + end + + default: begin // Incl. SelNone + kmac_valid_o = 1'b 0; + kmac_data_o = '0; + kmac_mask_o = '0; + end + + endcase + end + + // Error checking for Mux + always_comb begin + mux_err = '{valid: 1'b 0, code: ErrNone, info: '0}; + + if (mux_sel_buf_err_check != SelSw && sw_valid_i) begin + // If SW writes message into FIFO + mux_err = '{ + valid: 1'b 1, + code: ErrSwPushedMsgFifo, + info: 24'({8'h 00, 8'(st), 8'(mux_sel_buf_err_check)}) + }; + end else if (app_active_o && sw_cmd_i != CmdNone) begin + // If SW issues command except start + mux_err = '{ + valid: 1'b 1, + code: ErrSwIssuedCmdInAppActive, + info: 24'(sw_cmd_i) + }; + end + end + + logic [AppMuxWidth-1:0] mux_sel_buf_output_logic; + assign mux_sel_buf_output = app_mux_sel_e'(mux_sel_buf_output_logic); + + // SEC_CM: LOGIC.INTEGRITY + caliptra_prim_sec_anchor_buf #( + .Width(AppMuxWidth) + ) u_prim_buf_state_output_sel ( + .in_i(mux_sel), + .out_o(mux_sel_buf_output_logic) + ); + + logic [AppMuxWidth-1:0] mux_sel_buf_err_check_logic; + assign mux_sel_buf_err_check = app_mux_sel_e'(mux_sel_buf_err_check_logic); + + // SEC_CM: LOGIC.INTEGRITY + caliptra_prim_sec_anchor_buf #( + .Width(AppMuxWidth) + ) u_prim_buf_state_err_check ( + .in_i(mux_sel), + .out_o(mux_sel_buf_err_check_logic) + ); + + logic [AppMuxWidth-1:0] mux_sel_buf_kmac_logic; + assign mux_sel_buf_kmac = app_mux_sel_e'(mux_sel_buf_kmac_logic); + + // SEC_CM: LOGIC.INTEGRITY + caliptra_prim_sec_anchor_buf #( + .Width(AppMuxWidth) + ) u_prim_buf_state_kmac_sel ( + .in_i(mux_sel), + .out_o(mux_sel_buf_kmac_logic) + ); + + // SEC_CM: LOGIC.INTEGRITY + logic reg_state_valid; + caliptra_prim_sec_anchor_buf #( + .Width(1) + ) u_prim_buf_state_output_valid ( + .in_i(reg_state_valid), + .out_o(reg_state_valid_o) + ); + + // Keccak state Demux + // Keccak state --> Register output is enabled when state is in StSw + always_comb begin + reg_state_valid = 1'b 0; + reg_state_o = '{default:'0}; + if ((mux_sel_buf_output == SelSw) && + lc_ctrl_pkg::lc_tx_test_false_strict(lc_escalate_en_i)) begin + reg_state_valid = keccak_state_valid_i; + reg_state_o = keccak_state_i; + // If key is sideloaded and KMAC is SW initiated + // hide the capacity from SW by zeroing (see #17508) + if (EnFullKmac) begin : gen_reg_state_oup_shares + if (keymgr_key_en_i) begin + for (int i = 0; i < Share; i++) begin + unique case (reg_keccak_strength_i) + L128: reg_state_o[i][ot_sha3_pkg::StateW-1-:KeccakBitCapacity[L128]] = '0; + L224: reg_state_o[i][ot_sha3_pkg::StateW-1-:KeccakBitCapacity[L224]] = '0; + L256: reg_state_o[i][ot_sha3_pkg::StateW-1-:KeccakBitCapacity[L256]] = '0; + L384: reg_state_o[i][ot_sha3_pkg::StateW-1-:KeccakBitCapacity[L384]] = '0; + L512: reg_state_o[i][ot_sha3_pkg::StateW-1-:KeccakBitCapacity[L512]] = '0; + default: reg_state_o[i] = '0; + endcase + end + end + end + end + end + + // Keccak state --> KeyMgr + always_comb begin + app_digest_done = 1'b 0; + app_digest = '{default:'0}; + if (st == StAppWait && mubi4_test_true_strict(absorbed_i) && + lc_ctrl_pkg::lc_tx_test_false_strict(lc_escalate_en_i)) begin + // SHA3 engine has calculated the hash. Return the data to KeyMgr + app_digest_done = 1'b 1; + + // digest has always 2 entries. If !EnMasking, second is tied to 0. + for (int i = 0 ; i < Share ; i++) begin + // Return the portion of state. + app_digest[i] = keccak_state_i[i][AppDigestW-1:0]; + end + end + end + + + // Secret Key Mux + + // Prepare merged key if EnMasking is not set. + // Combine share keys into unpacked array for logic below to assign easily. + // SEC_CM: KEY.SIDELOAD + logic [MaxKeyLen-1:0] keymgr_key [Share]; + // If KMAC is disabled, keymgr_key is not used. + if (!EnFullKmac) begin : g_key_unused + assign keymgr_key = '{default: '0}; + end else if (EnMasking == 1) begin : g_key_masked + for (genvar i = 0; i < Share; i++) begin : gen_key_pad + assign keymgr_key[i] = {(MaxKeyLen-KeyMgrKeyW)'(0), keymgr_key_i.key[i]}; + end + end else begin : g_key_unmasked + always_comb begin + keymgr_key[0] = '0; + for (int i = 0; i < keymgr_pkg::Shares; i++) begin + keymgr_key[0][KeyMgrKeyW-1:0] ^= keymgr_key_i.key[i]; + end + end + end + + if (EnFullKmac) begin : gen_keymgr_side_load + // Sideloaded key manage: Keep use sideloaded key for KMAC AppIntf until the + // hashing operation is finished. + always_comb begin + keymgr_key_used = 1'b0; + key_len_o = reg_key_len_i; + for (int i = 0 ; i < Share; i++) begin + key_data_o[i] = reg_key_data_i[i]; + end + // The key is considered invalid in all cases that are not listed below (which includes idle + // and error states). + key_valid_o = 1'b0; + + unique case (st) + StAppCfg, StAppMsg, StAppOutLen, StAppProcess, StAppWait: begin + // Key from keymgr is actually used if the current HW app interface does *keyed* MAC. + keymgr_key_used = AppCfg[app_id].Mode == AppKMAC; + key_len_o = SideloadedKey; + for (int i = 0 ; i < Share; i++) begin + key_data_o[i] = keymgr_key[i]; + end + // Key is valid if the current HW app interface does *keyed* MAC and the key provided by + // keymgr is valid. + key_valid_o = keymgr_key_used && keymgr_key_i.valid; + end + + StSw: begin + if (keymgr_key_en_i) begin + // Key from keymgr is actually used if *keyed* MAC is enabled. + keymgr_key_used = kmac_en_o; + key_len_o = SideloadedKey; + for (int i = 0 ; i < Share; i++) begin + key_data_o[i] = keymgr_key[i]; + end + end + // Key is valid if SW does *keyed* MAC and ... + if (kmac_en_o) begin + if (!keymgr_key_en_i) begin + // ... it uses the key from kmac's CSR, or ... + key_valid_o = 1'b1; + end else begin + // ... it uses the key provided by keymgr and that one is valid. + key_valid_o = keymgr_key_i.valid; + end + end + end + + default: ; + endcase + end + end else begin : gen_no_keymgr_side_load + // If KMAC is disabled, the key is not needed. + assign keymgr_key_used = 1'b0; + assign key_len_o = reg_key_len_i; + always_comb begin + for (int i = 0 ; i < Share; i++) begin + key_data_o[i] = reg_key_data_i[i]; + end + end + assign key_valid_o = 1'b0; + + logic unused_keymgr_key; + if (EnMasking) begin : gen_unused_keymgr_key_masked + assign unused_keymgr_key = ^{keymgr_key_i.key[0], keymgr_key_i.key[1], + keymgr_key_i.valid, keymgr_key_en_i, + keymgr_key[0], keymgr_key[1]}; + end else begin : gen_unused_keymgr_key_unmasked + assign unused_keymgr_key = ^{keymgr_key_i.key[0], keymgr_key_i.key[1], + keymgr_key_i.valid, keymgr_key_en_i, + keymgr_key[0]}; + end + end + + // Prefix Demux + // For SW, always prefix register. + // For App intf, check PrefixMode cfg and if 1, use Prefix cfg. + always_comb begin + sha3_prefix_o = '0; + + unique case (st) + StAppCfg, StAppMsg, StAppOutLen, StAppProcess, StAppWait: begin + // Check app intf cfg + for (int unsigned i = 0 ; i < NumAppIntf ; i++) begin + if (app_id == i) begin + if (AppCfg[i].PrefixMode == 1'b 0) begin + sha3_prefix_o = reg_prefix_i; + end else begin + sha3_prefix_o = AppCfg[i].Prefix; + end + end + end + end + + StSw: begin + sha3_prefix_o = reg_prefix_i; + end + + default: begin + sha3_prefix_o = reg_prefix_i; + end + endcase + end + + // KMAC en / SHA3 mode / Strength + // by default, it uses reg cfg. When app intf reqs come, it uses AppCfg. + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + sha3_mode_o <= ot_sha3_pkg::Sha3; + keccak_strength_o <= ot_sha3_pkg::L256; + end else if (clr_appid) begin + // As App completed, latch reg value + sha3_mode_o <= reg_sha3_mode_i; + keccak_strength_o <= reg_keccak_strength_i; + end else if (set_appid) begin + sha3_mode_o <= AppCfg[arb_idx].Mode == AppSHA3 + ? ot_sha3_pkg::Sha3 : ot_sha3_pkg::CShake; + keccak_strength_o <= AppCfg[arb_idx].KeccakStrength ; + end else if (st == StIdle) begin + sha3_mode_o <= reg_sha3_mode_i; + keccak_strength_o <= reg_keccak_strength_i; + end + end + + if (EnFullKmac) begin : gen_kmac_en_oup + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + kmac_en_o <= 1'b 0; + end else if (clr_appid) begin + // As App completed, latch reg value + kmac_en_o <= reg_kmac_en_i; + end else if (set_appid) begin + kmac_en_o <= (AppCfg[arb_idx].Mode == AppKMAC) ? 1'b 1 : 1'b0; + end else if (st == StIdle) begin + kmac_en_o <= reg_kmac_en_i; + end + end + end else begin : gen_no_kmac_en_oup + assign kmac_en_o = 1'b0; + + logic unused_reg_kmac_en; + assign unused_reg_kmac_en = reg_kmac_en_i; + end + + // Status + assign app_active_o = (st inside {StAppCfg, StAppMsg, StAppOutLen, + StAppProcess, StAppWait}); + + // Error Reporting ========================================================== + always_comb begin + priority casez ({fsm_err.valid, mux_err.valid}) + 2'b ?1: error_o = mux_err; + 2'b 10: error_o = fsm_err; + default: error_o = '{valid: 1'b0, code: ErrNone, info: '0}; + endcase + end + + //////////////// + // Assertions // + //////////////// + + // KeyMgr sideload key and the digest should be in the Key Length value + `CALIPTRA_ASSERT_INIT(SideloadKeySameToDigest_A, KeyMgrKeyW <= AppDigestW) + `CALIPTRA_ASSERT_INIT(AppIntfInRange_A, AppDigestW inside {128, 192, 256, 384, 512}) + + // Issue(#13655): Having a coverage that sideload keylen and CSR keylen are + // different. + `CALIPTRA_COVER(AppIntfUseDifferentSizeKey_C, + (st == StAppCfg && kmac_en_o) |-> reg_key_len_i != SideloadedKey) + + // Assertions for the case where EnFullKmac is 0. + `CALIPTRA_ASSUME(StrippedKMACAppCfgModeAllowed_M, EnFullKmac == 0 |-> + AppCfg[arb_idx].Mode inside {AppCShake, AppSHA3}) + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/kmac_core.sv b/designs/Caliptra/src/caliptra-rtl/kmac_core.sv new file mode 100644 index 0000000..dd17c1d --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/kmac_core.sv @@ -0,0 +1,471 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// KMAC control and padding logic + +`include "caliptra_prim_assert.sv" + +module kmac_core + import caliptra_prim_mubi_pkg::*; + import kmac_pkg::*; +#( + // EnMasking: Enable masking security hardening inside keccak_round + // If it is enabled, the result digest will be two set of 1600bit. + parameter bit EnMasking = 0, + localparam int Share = (EnMasking) ? 2 : 1 // derived parameter +) ( + input clk_i, + input rst_ni, + + // From Message FIFO + input fifo_valid_i, + input [MsgWidth-1:0] fifo_data_i [Share], + input [MsgStrbW-1:0] fifo_strb_i, + output logic fifo_ready_o, + + // to SHA3 Core + output logic msg_valid_o, + output logic [MsgWidth-1:0] msg_data_o [Share], + output logic [MsgStrbW-1:0] msg_strb_o, + input msg_ready_i, + + // Configurations + + // If kmac_en is cleared, Core logic doesn't function but forward incoming + // message to SHA3 core + input kmac_en_i, + input ot_sha3_pkg::sha3_mode_e mode_i, + input ot_sha3_pkg::keccak_strength_e strength_i, + + // Key input from CSR + input [MaxKeyLen-1:0] key_data_i [Share], + input key_len_e key_len_i, + input logic key_valid_i, + + // Controls : same to SHA3 core + input start_i, + input process_i, + input mubi4_t done_i, + + // Control to SHA3 core + output logic process_o, + + // Life cycle + input lc_ctrl_pkg::lc_tx_t lc_escalate_en_i, + + output logic sparse_fsm_error_o, + output logic key_index_error_o +); + + import ot_sha3_pkg::KeccakMsgAddrW; + import ot_sha3_pkg::KeccakCountW; + import ot_sha3_pkg::KeccakRate; + import ot_sha3_pkg::L128; + import ot_sha3_pkg::L224; + import ot_sha3_pkg::L256; + import ot_sha3_pkg::L384; + import ot_sha3_pkg::L512; + + ///////////////// + // Definitions // + ///////////////// + + // Encoding generated with: + // $ ./util/design/sparse-fsm-encode.py -d 3 -m 5 -n 6 \ + // -s 401658243 --language=sv + // + // Hamming distance histogram: + // + // 0: -- + // 1: -- + // 2: -- + // 3: |||||||||||||||||||| (50.00%) + // 4: |||||||||||||||| (40.00%) + // 5: |||| (10.00%) + // 6: -- + // + // Minimum Hamming distance: 3 + // Maximum Hamming distance: 5 + // Minimum Hamming weight: 1 + // Maximum Hamming weight: 4 + // + localparam int StateWidth = 6; + typedef enum logic [StateWidth-1:0] { + StKmacIdle = 6'b011000, + + // Secret Key pushing stage + // The key is sliced by prim_slicer. This state pushes the sliced data into + // SHA3 hashing engine. When it hits the block size limit, + // (same as in sha3pad) the state machine moves to Message. + StKey = 6'b010111, + + // Incoming Message + // The core does nothing but forwarding the incoming message to SHA3 hashing + // engine by turning off `en_kmac_datapath`. + StKmacMsg = 6'b001110, + + // Wait till done signal + StKmacFlush = 6'b101011, + + // Terminal Error + StTerminalError = 6'b100000 + } kmac_st_e ; + + ///////////// + // Signals // + ///////////// + + // represents encode_string(K) + logic [MaxEncodedKeyW-1:0] encoded_key [Share]; + + // Key slice address + // This signal controls the 64 bit output of the sliced secret_key. + logic [ot_sha3_pkg::KeccakMsgAddrW-1:0] key_index; + logic inc_keyidx, clr_keyidx; + + // `sent_blocksize` indicates that the encoded key is sent to sha3 hashing + // engine. If this hits at StKey stage, the state moves to message state. + logic [ot_sha3_pkg::KeccakCountW-1:0] block_addr_limit; + logic sent_blocksize; + + // Internal message signals + logic kmac_valid ; + logic [MsgWidth-1:0] kmac_data [Share]; + logic [MsgStrbW-1:0] kmac_strb ; + + // Control SHA3 core + // `kmac_process` is to forward the process signal to SHA3 core only after + // the KMAC core writes the key block in case of the message is empty. + // If the incoming message is empty, there's chance that the `process_i` + // signal can be asserted while KMAC core processing the key block. + logic kmac_process, process_latched; + + // Indication of Secret key write stage. Only in this stage, the internal + // message interface is active. + logic en_key_write; + logic en_kmac_datapath; + + // Encoded key has wider bits. `key_sliced` is the data to send to sha3 + logic [MsgWidth-1:0] key_sliced [Share]; + + // The following signals are only used in assertions. + logic unused_signals; + assign unused_signals = ^{mode_i, key_valid_i}; + + ///////// + // FSM // + ///////// + kmac_st_e st, st_d; + + // State register + `CALIPTRA_PRIM_FLOP_SPARSE_FSM(u_state_regs, st_d, st, kmac_st_e, StKmacIdle) + + // Next state and output logic + // SEC_CM: FSM.SPARSE + always_comb begin + st_d = st; + + en_kmac_datapath = 1'b 0; + en_key_write = 1'b 0; + + clr_keyidx = 1'b 0; + + kmac_valid = 1'b 0; + kmac_process = 1'b 0; + + sparse_fsm_error_o = 1'b 0; + + unique case (st) + StKmacIdle: begin + if (kmac_en_i && start_i) begin + st_d = StKey; + end else begin + st_d = StKmacIdle; + end + end + + // If State enters here, regardless of the `process_i`, the state writes + // full block size of the key into SHA3 hashing engine. + StKey: begin + en_kmac_datapath = 1'b 1; + en_key_write = 1'b 1; + + if (sent_blocksize) begin + st_d = StKmacMsg; + + kmac_valid = 1'b 0; + clr_keyidx = 1'b 1; + end else begin + st_d = StKey; + + kmac_valid = 1'b 1; + end + end + + StKmacMsg: begin + // If process is previously latched, it is sent to SHA3 here. + if (process_i || process_latched) begin + st_d = StKmacFlush; + + kmac_process = 1'b 1; + end else begin + st_d = StKmacMsg; + end + end + + StKmacFlush: begin + if (mubi4_test_true_strict(done_i)) begin + st_d = StKmacIdle; + end else begin + st_d = StKmacFlush; + end + end + + StTerminalError: begin + // this state is terminal + st_d = st; + sparse_fsm_error_o = 1'b 1; + end + + default: begin + // this state is terminal + st_d = StTerminalError; + sparse_fsm_error_o = 1'b 1; + end + endcase + + // SEC_CM: FSM.GLOBAL_ESC, FSM.LOCAL_ESC + // Unconditionally jump into the terminal error state + // if the life cycle controller triggers an escalation. + if (lc_ctrl_pkg::lc_tx_test_true_loose(lc_escalate_en_i)) begin + st_d = StTerminalError; + end + end + + ////////////// + // Datapath // + ////////////// + + // DATA Mux depending on kmac_en + // When Key write happens, hold the FIFO request. so fifo_ready_o is tied to 0 + assign msg_valid_o = (en_kmac_datapath) ? kmac_valid : fifo_valid_i; + assign msg_data_o = (en_kmac_datapath) ? kmac_data : fifo_data_i ; + assign msg_strb_o = (en_kmac_datapath) ? kmac_strb : fifo_strb_i ; + assign fifo_ready_o = (en_kmac_datapath) ? 1'b 0 : msg_ready_i ; + + // secret key write request to SHA3 hashing engine is always full width write. + // KeyMgr is fixed 256 bit output. So `right_encode(256)` is 0x020100 --> strb 3 + assign kmac_strb = (en_key_write ) ? '1 : '0; + + assign kmac_data = (en_key_write) ? key_sliced : '{default:'0}; + + // Process is controlled by the KMAC core always. + // This is mainly to prevent process_i asserted while KMAC core is writing + // the secret key to SHA3 hashing engine (the empty message case) + assign process_o = (kmac_en_i) ? kmac_process : process_i ; + + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + process_latched <= 1'b 0; + end else if (process_i && !process_o) begin + process_latched <= 1'b 1; + end else if (process_o || + mubi4_test_true_strict(done_i)) begin + process_latched <= 1'b 0; + end + end + + // bytepad(encode_string(K), 168 or 136) ===================================== + // 1. Prepare left_encode(w) + // 2. Prepare left_encode(len(secret_key)) + // 3. Concatenate left_encode(len(secret_key)) || secret_key + // 4. Concaatenate left_encode(w) || encode_string(secret_key) + // 5. Based on the address, slice out the data into MsgWidth bits + + // left_encode(w): Same as used in sha3pad logic. + logic [15:0] encode_bytepad; + assign encode_bytepad = ot_sha3_pkg::encode_bytepad_len(strength_i); + + // left_encode(len(secret_key)) + // encoded length is always byte size. Use MaxEncodedKeyLenByte parameter + // from kmac_pkg and add one more byte to indicate how many bytes used to + // represent len(secret_key) + // Note that if the secret_key is 128 bit, only lower 16 bits of + // `encode_keylen` are valid. Refer `encoded_key` concatenation logic below. + // As the encoded string in the spec big-endian, The endian swap is a must. + logic [MaxEncodedKeyLenSize + 8 - 1:0] encode_keylen [Share]; + + always_comb begin + // the spec mentioned the key length is encoded in left_encode() + // The number is represented in big-endian. For example: + // 384 ==> 0x02 0x01 0x80 + // The first byte is the number of bytes to represent 384 + // The second byte represents 2**8 number, which is 256 here. + // The third byte represents 2**0 number, which is 128. + // The data put into MsgFIFO is little-endian and SHA3(Keccak) processes in + // little-endian. So, below keylen swaps the byte order + unique case (key_len_i) + // endian-swapped key_length num_bytes + // Key128: encode_keylen[0] = {{<<8{MaxEncodedKeyLenSize'(128)}}, 8'h 01}; + // Key192: encode_keylen[0] = {{<<8{MaxEncodedKeyLenSize'(192)}}, 8'h 01}; + // Key256: encode_keylen[0] = {{<<8{MaxEncodedKeyLenSize'(256)}}, 8'h 02}; + // Key384: encode_keylen[0] = {{<<8{MaxEncodedKeyLenSize'(384)}}, 8'h 02}; + // Key512: encode_keylen[0] = {{<<8{MaxEncodedKeyLenSize'(512)}}, 8'h 02}; + + // Vivado does not support stream swap for non context value. So assign + // the value directly. + Key128: encode_keylen[0] = (MaxEncodedKeyLenSize+8)'('h 0080_01); + Key192: encode_keylen[0] = (MaxEncodedKeyLenSize+8)'('h 00C0_01); + Key256: encode_keylen[0] = (MaxEncodedKeyLenSize+8)'('h 0001_02); + Key384: encode_keylen[0] = (MaxEncodedKeyLenSize+8)'('h 8001_02); + Key512: encode_keylen[0] = (MaxEncodedKeyLenSize+8)'('h 0002_02); + default: encode_keylen[0] = '0; + endcase + end + + if (EnMasking) begin: gen_encode_keylen_masked + assign encode_keylen[1] = '0; + end + + // encode_string(secret_key): Concatenate key + // Based on the left_encode(len(secret_key)) size, the concatenation logic + // should be changed. If key length is 128 bit, only lower 16 bits of the + // encoded length are used so that the upper 8 bits are padded with 0 as + // defined in bytepad() function. + + for (genvar i = 0 ; i < Share; i++) begin : gen_encoded_key + always_comb begin + unique case (key_len_i) + // In Key 128, 192 case, only lower parts of encode_keylen signal is + // used. So upper padding requires 8 more bits than MaxKeyLen - keylen + Key128: encoded_key[i] = {(8 + MaxKeyLen - 128)'(0), + key_data_i[i][0+:128], + encode_keylen[i][0+:MaxEncodedKeyLenSize]}; + + Key192: encoded_key[i] = {(8 + MaxKeyLen - 192)'(0), + key_data_i[i][0+:192], + encode_keylen[i][0+:MaxEncodedKeyLenSize]}; + + Key256: encoded_key[i] = {(MaxKeyLen - 256)'(0), + key_data_i[i][0+:256], + encode_keylen[i]}; + + Key384: encoded_key[i] = {(MaxKeyLen - 384)'(0), + key_data_i[i][0+:384], + encode_keylen[i]}; + + // Assume 512bit is the MaxKeyLen + Key512: encoded_key[i] = {key_data_i[i][0+:512], + encode_keylen[i]}; + + default: encoded_key[i] = '0; + endcase + end + end : gen_encoded_key + + // Above logic assumes MaxKeyLen as 512 bits. Revise if it is not. + `CALIPTRA_ASSERT_INIT(MaxKeyLenMatchToKey512_A, kmac_pkg::MaxKeyLen == 512) + + // Combine the bytepad `left_encode(w)` and the `encode_string(secret_key)` + logic [MaxEncodedKeyW + 16 -1 :0] encoded_key_block [Share]; + + assign encoded_key_block[0] = {encoded_key[0], encode_bytepad}; + + if (EnMasking) begin : gen_encoded_key_block_masked + assign encoded_key_block[1] = {encoded_key[1], 16'h 0}; + end + + // Slicer to slice out 64 bits + for (genvar i = 0 ; i < Share ; i++) begin : gen_key_slicer + caliptra_prim_slicer #( + .InW (MaxEncodedKeyW+16), + .IndexW(KeccakMsgAddrW), + .OutW(MsgWidth) + ) u_key_slicer ( + .sel_i (key_index), + .data_i (encoded_key_block[i]), + .data_o (key_sliced[i]) + ); + end + + // `key_index` logic + // key_index is used to select MsgWidth data from long `encoded_key_block` + // It behaves same as `keccak_addr` or `prefix_index` in sha3pad module. + assign inc_keyidx = kmac_valid & msg_ready_i ; + + // This primitive is used to place a hardened counter + // SEC_CM: CTR.REDUN + caliptra_prim_count #( + .Width(ot_sha3_pkg::KeccakMsgAddrW) + ) u_key_index_count ( + .clk_i, + .rst_ni, + .clr_i(clr_keyidx), + .set_i(1'b0), + .set_cnt_i('0), + .incr_en_i(inc_keyidx), + .decr_en_i(1'b0), + .step_i(ot_sha3_pkg::KeccakMsgAddrW'(1)), + .commit_i(1'b1), + .cnt_o(key_index), + .cnt_after_commit_o(), + .err_o(key_index_error_o) + ); + + // Block size based on the address. + // This is used for bytepad() and also pad10*1() + // assign block_addr_limit = KeccakRate[strength_i]; + // but below is easier to understand + always_comb begin + unique case (strength_i) + L128: block_addr_limit = KeccakCountW'(KeccakRate[L128]); + L224: block_addr_limit = KeccakCountW'(KeccakRate[L224]); + L256: block_addr_limit = KeccakCountW'(KeccakRate[L256]); + L384: block_addr_limit = KeccakCountW'(KeccakRate[L384]); + L512: block_addr_limit = KeccakCountW'(KeccakRate[L512]); + + default: block_addr_limit = '0; + endcase + end + + assign sent_blocksize = (key_index == block_addr_limit); + + + // Encoded Output Length ===================================================== + // + // KMAC(K,X,L,S) := cSHAKE(newX,L,"KMAC",S) + // K : Secret Key + // X : Input Message + // L : Output Length + // S : Customization input string + // newX = bytepad(encode_string(key), 168or136) || X || right_encode(L) + // + // Software writes desired output length as encoded value into the message + // FIFO at the end of the message prior to set !!CMD.process. + + + //////////////// + // Assertions // + //////////////// + + // If process_latched is set, then at Message state, it should be cleared + + `CALIPTRA_ASSERT(ProcessLatchedCleared_A, + st == StKmacMsg && process_latched |=> !process_latched) + + // Assume configuration is stable during the operation + `CALIPTRA_ASSUME(KmacEnStable_M, $changed(kmac_en_i) |-> st inside {StKmacIdle, StTerminalError}) + `CALIPTRA_ASSUME(ModeStable_M, $changed(mode_i) |-> st inside {StKmacIdle, StTerminalError}) + `CALIPTRA_ASSUME(StrengthStable_M, + $changed(strength_i) |-> + (st inside {StKmacIdle, StTerminalError}) || + ($past(st) == StKmacIdle)) + `CALIPTRA_ASSUME(KeyLengthStableWhenValid_M, key_valid_i && !$rose(key_valid_i) |-> $stable(key_len_i)) + `CALIPTRA_ASSUME(KeyDataStableWhenValid_M, key_valid_i && !$rose(key_valid_i) |-> $stable(key_data_i)) + + // no acked to MsgFIFO in StKmacMsg + `CALIPTRA_ASSERT(AckOnlyInMessageState_A, + fifo_valid_i && fifo_ready_o && kmac_en_i |-> st == StKmacMsg) + +endmodule : kmac_core diff --git a/designs/Caliptra/src/caliptra-rtl/kmac_entropy.sv b/designs/Caliptra/src/caliptra-rtl/kmac_entropy.sv new file mode 100644 index 0000000..6331a0e --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/kmac_entropy.sv @@ -0,0 +1,779 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// KMAC Entropy Generation module + +`include "caliptra_prim_assert.sv" + +module kmac_entropy + import caliptra_prim_mubi_pkg::*; + import kmac_pkg::*; + import kmac_reg_pkg::*; +#( + parameter lfsr_perm_t RndCnstLfsrPerm = RndCnstLfsrPermDefault, + parameter lfsr_seed_t RndCnstLfsrSeed = RndCnstLfsrSeedDefault, + parameter buffer_lfsr_seed_t RndCnstBufferLfsrSeed = RndCnstBufferLfsrSeedDefault +) ( + input clk_i, + input rst_ni, + + // EDN interface + output logic entropy_req_o, + input entropy_ack_i, + input [edn_pkg::ENDPOINT_BUS_WIDTH-1:0] entropy_data_i, + + // Entropy to internal + output logic rand_valid_o, + output logic rand_early_o, + output logic [ot_sha3_pkg::StateW/2-1:0] rand_data_o, + output logic rand_aux_o, + input rand_update_i, + input rand_consumed_i, + + // Status + input in_keyblock_i, + + // Configurations + input entropy_mode_e mode_i, + //// SW sets ready bit when EDN is ready to accept requests through its app. + //// interface. + input entropy_ready_i, + + //// Garbage random value when not processing Keyblock, if this config is + //// turned on, the logic sending garbage value and never de-assert + //// rand_valid_o unless it is not processing KeyBlock. + input fast_process_i, + + //// PRNG enable for Message Masking + //// If 1, PRNG advances to create 64-bit PRN. This input is used to mask + //// the message fed into SHA3 (Keccak). + input msg_mask_en_i, + output logic [MsgWidth-1:0] msg_mask_o, + + //// SW update of seed + input seed_update_i, + input [31:0] seed_data_i, + + //// SW may initiate manual EDN seed refresh + input entropy_refresh_req_i, + + //// Timer limit value + //// If value is 0, timer is disabled + input [TimerPrescalerW-1:0] wait_timer_prescaler_i, + input [EdnWaitTimerW-1:0] wait_timer_limit_i, + + // Status out + //// Hash Ops counter. Count how many hashing ops (KMAC) have run + //// after the clear request from SW + output logic [HashCntW-1:0] hash_cnt_o, + input hash_cnt_clr_i, + input [HashCntW-1:0] hash_threshold_i, + + output mubi4_t entropy_configured_o, + + // Life cycle + input lc_ctrl_pkg::lc_tx_t lc_escalate_en_i, + + // Error output + output err_t err_o, + output logic sparse_fsm_error_o, + output logic count_error_o, + input err_processed_i +); + + ///////////////// + // Definitions // + ///////////////// + + // Timer Widths are defined in kmac_pkg + + // Encoding generated with: + // $ ./util/design/sparse-fsm-encode.py -d 3 -m 9 -n 10 \ + // -s 507672272 --language=sv + // + // Hamming distance histogram: + // + // 0: -- + // 1: -- + // 2: -- + // 3: ||||||||||| (13.89%) + // 4: ||||||||||||||| (19.44%) + // 5: |||||||||||||||||||| (25.00%) + // 6: ||||||||||||||| (19.44%) + // 7: ||||||||||| (13.89%) + // 8: |||| (5.56%) + // 9: || (2.78%) + // 10: -- + // + // Minimum Hamming distance: 3 + // Maximum Hamming distance: 9 + // Minimum Hamming weight: 2 + // Maximum Hamming weight: 7 + // + localparam int StateWidth = 10; + + // States + typedef enum logic [StateWidth-1:0] { + // Reset: Reset state. The entropy is not ready. The state machine should + // get new entropy from EDN or the seed should be feeded by the software. + StRandReset = 10'b1001111000, + + // The seed is fed into PRNG and the entropy is ready. It means the + // rand_valid is asserted with valid data. It takes a few steps to reach + // this state from StRandReset. + StRandReady = 10'b0110000100, + + // EDN interface: Send request and receive + // RandEdnReq state can be transit from StRandReset or from StRandReady + // + // Reset --> EdnReq: + // If entropy source module is ready, the software sets a bit in CFG + // also sets the entropy mode to EdnMode. Then this FSM moves to EdnReq + // to initialize PRNG seed. + // + // Ready --> EdnReq: + // 1. If a mode is configured as to update entropy everytime it is + // consumed, then the FSM moves from Ready to EdnReq to refresh seed + // 2. If the software enabled EDN timer and the timer is expired and + // also the KMAC is processing the key block, the FSM moves to + // EdnReq to refresh seed + // 3. If a KMAC operation is completed, the FSM also refreshes the PRNG + // seed to prepare next KMAC op or wipe out operation. + StRandEdn = 10'b1100100111, + + // Sw Seed: If mode is set to manual mode, This entropy module needs initial + // seed from the software. It waits the seed update signal to expand initial + // entropy + StSwSeedWait = 10'b1011110110, + + // Generate: In this state, the entropy generator advances the PRNG to + // generate the 800-bits of pseudo random data for the next evaluation. + StRandGenerate = 10'b0000001100, + + // ErrWaitExpired: If Edn timer expires, FSM moves to this state and wait + // the software response. Software should switch to manual mode then disable + // the timer (to 0) and update the seed via register interface. + StRandErrWaitExpired = 10'b0001100011, + + // ErrNoValidMode: If SW sets entropy ready but the mode is not either + // Manual Mode nor EdnMode, this logic reports to SW with + // NoValidEntropyMode. + StRandErrIncorrectMode = 10'b1110010000, + + // Err: After the error is reported, FSM sits in Err state ignoring all the + // requests. It does not generate new entropy and drops the entropy valid + // signal. + // + // SW sets err_processed signal to clear the error. The software should + // clear the entropy ready signal before clear the error interrupt so that + // the FSM sits in StRandReset state not moving forward with incorrect + // configurations. + StRandErr = 10'b1000011110, + + StTerminalError = 10'b0010011000 + } rand_st_e; + + ///////////// + // Signals // + ///////////// + + // Timers + // "Wait Timer": This timer is in active when FSM sends entropy request to EDN + // If EDN does not return the entropy data until the timer expired, FSM + // moves to error state and report the error to the system. + + localparam int unsigned TimerW = EdnWaitTimerW; + logic timer_enable, timer_update, timer_expired, timer_pulse; + logic [TimerW-1:0] timer_limit; + logic [TimerW-1:0] timer_value; + + localparam int unsigned PrescalerW = TimerPrescalerW; + logic [PrescalerW-1:0] prescaler_cnt; + + // PRNG primitive + // SW configures to use EDN or ENTROPY_SEED register as PRNG seed + logic seed_en, seed_done; + logic seed_req, seed_ack; + logic [edn_pkg::ENDPOINT_BUS_WIDTH-1:0] seed; + logic prng_en; + logic [EntropyOutputW-1:0] prng_data, prng_data_permuted; + + // Buffer stage to prevent glitches happening inside the PRNG itself from + // propagating into the masked processing core. + logic [EntropyOutputW-1:0] rand_data_q; + logic data_update; + + // Auxliliary randomness + logic aux_rand_d, aux_rand_q; + logic aux_update; + + // Randomness for controlling PRNG updates. This only matters for clock cycles + // where the PRNG output is not actually used. + logic [3:0] prng_en_rand_d, prng_en_rand_q; + + // Entropy valid signal + // FSM set and clear the valid signal, rand_consume signal clear the valid + // signal. Split the set, clear to make entropy valid while FSM is processing + // other tasks. + logic rand_valid_set, rand_valid_clear; + + // FSM latches the mode and stores into mode_q when the FSM is out from + // StReset. The following states, or internal datapath uses mode_q after that. + // If the SW wants to change the mode, it requires resetting the IP. + logic mode_latch; + entropy_mode_e mode_q; + + // Status out: entropy configured + mubi4_t entropy_configured; + + // Internal entropy request signals. + logic entropy_req; + logic entropy_req_hold_d, entropy_req_hold_q; + + ////////////// + // Datapath // + ////////////// + + // For latching (`wait_timer_limit_i` != 0) during last `timer_update` + // See #16716 + logic non_zero_wait_timer_limit; + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + non_zero_wait_timer_limit <= '0; + end else if (timer_update) begin + non_zero_wait_timer_limit <= |wait_timer_limit_i; + end + end + + logic [TimerPrescalerW-1:0] wait_timer_prescaler_d; + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + wait_timer_prescaler_d <= '0; + end else if (timer_update) begin + wait_timer_prescaler_d <= wait_timer_prescaler_i; + end + end + + // Timers =================================================================== + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + timer_value <= '0; + end else if (timer_update) begin + timer_value <= timer_limit; + end else if (timer_expired) begin + timer_value <= '0; // keep the value + end else if (timer_enable && timer_pulse && |timer_value) begin // if non-zero timer v + timer_value <= timer_value - 1'b 1; + end + end + + assign timer_limit = TimerW'(wait_timer_limit_i); + + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + timer_expired <= 1'b 0; + end else if (timer_update) begin + timer_expired <= 1'b 0; + end else if (timer_enable && (timer_value == '0)) begin + timer_expired <= 1'b 1; + end + end + + // Prescaler + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + prescaler_cnt <= '0; + end else if (timer_update) begin + prescaler_cnt <= wait_timer_prescaler_i; + end else if (timer_enable && prescaler_cnt == '0) begin + prescaler_cnt <= wait_timer_prescaler_d; + end else if (timer_enable) begin + prescaler_cnt <= prescaler_cnt - 1'b 1; + end + end + + assign timer_pulse = (timer_enable && prescaler_cnt == '0); + // Timers ------------------------------------------------------------------- + + // Hash Counter + logic threshold_hit; + logic threshold_hit_q, threshold_hit_clr; // latched hit + + logic hash_progress_d, hash_progress_q; + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) hash_progress_q <= 1'b 0; + else hash_progress_q <= hash_progress_d; + end + + assign hash_progress_d = in_keyblock_i; + + logic hash_cnt_clr; + assign hash_cnt_clr = hash_cnt_clr_i || threshold_hit || entropy_refresh_req_i; + + logic hash_cnt_en; + assign hash_cnt_en = hash_progress_q && !hash_progress_d; + + logic hash_count_error; + + // SEC_CM CTR.REDUN + // This primitive is used to place a hardened counter + caliptra_prim_count #( + .Width(HashCntW) + ) u_hash_count ( + .clk_i, + .rst_ni, + .clr_i(hash_cnt_clr), + .set_i(1'b0), + .set_cnt_i(HashCntW'(0)), + .incr_en_i(hash_cnt_en), + .decr_en_i(1'b0), + .step_i(HashCntW'(1)), + .commit_i(1'b1), + .cnt_o(hash_cnt_o), + .cnt_after_commit_o(), + .err_o(hash_count_error) + ); + + assign threshold_hit = |hash_threshold_i && (hash_threshold_i <= hash_cnt_o); + + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) threshold_hit_q <= 1'b 0; + else if (threshold_hit_clr) threshold_hit_q <= 1'b 0; + else if (threshold_hit) threshold_hit_q <= 1'b 1; + end + + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) mode_q <= EntropyModeNone; + else if (mode_latch) mode_q <= mode_i; + end + + // PRNG primitive =========================================================== + + `CALIPTRA_ASSERT_KNOWN(ModeKnown_A, mode_i) + assign seed = (mode_q == EntropyModeSw) ? seed_data_i : entropy_data_i; + + // We employ a single unrolled Bivium stream cipher primitive to generate + // 800 bits per clock cycle. + caliptra_prim_trivium #( + .BiviumVariant (1), + .OutputWidth (EntropyOutputW), + .StrictLockupProtection(1), + .SeedType (caliptra_prim_trivium_pkg::SeedTypeStatePartial), + .PartialSeedWidth (edn_pkg::ENDPOINT_BUS_WIDTH), + .RndCnstTriviumLfsrSeed(RndCnstLfsrSeed) + ) u_caliptra_prim_trivium ( + .clk_i (clk_i), + .rst_ni(rst_ni), + + .en_i (prng_en || msg_mask_en_i), + .allow_lockup_i ('0), // Not used. + .seed_en_i (seed_en), + .seed_done_o (seed_done), + .seed_req_o (seed_req), + .seed_ack_i (seed_ack), + .seed_key_i ('0), // Not used. + .seed_iv_i ('0), // Not used. + .seed_state_full_i ('0), // Not used. + .seed_state_partial_i(seed), + + .key_o(prng_data), + .err_o() + ); + + // Add a permutation layer to obfuscate the output of the PRNG primitive. + for (genvar i = 0; i < EntropyOutputW; i++) begin : gen_perm + assign prng_data_permuted[i] = prng_data[RndCnstLfsrPerm[i]]; + end + + // Buffer stage to prevent glitches happening inside the PRNG primitive from + // propagating into the masked processing core. + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + rand_data_q <= RndCnstBufferLfsrSeed; + end else if (data_update || msg_mask_en_i) begin + rand_data_q <= prng_data_permuted; + end + end + + // Forwrad LSBs for masking the message. + assign msg_mask_o = rand_data_q[MsgWidth-1:0]; + + // PRNG primitive ---------------------------------------------------------- + + // Auxiliary randomness ===================================================== + assign aux_rand_d = aux_update ? rand_data_q[EntropyOutputW - 1] : + aux_rand_q; + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + aux_rand_q <= '0; + end else begin + aux_rand_q <= aux_rand_d; + end + end + + // Auxiliary randomness ----------------------------------------------------- + + // PRNG enable randomness =================================================== + assign prng_en_rand_d = + aux_update ? rand_data_q[EntropyOutputW - 2 -: 4] : // refresh + {1'b0, prng_en_rand_q[3:1]}; // shift out + + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + prng_en_rand_q <= '0; + end else begin + prng_en_rand_q <= prng_en_rand_d; + end + end + + // PRNG enable randomness --------------------------------------------------- + + // Randomness outputs ======================================================= + assign rand_data_o = rand_data_q; + assign rand_aux_o = aux_rand_q; + + // entropy valid + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + rand_valid_o <= 1'b 0; + end else if (rand_valid_set) begin + rand_valid_o <= 1'b 1; + end else if (rand_valid_clear) begin + rand_valid_o <= 1'b 0; + end + end + + // Let consumers know that the randomness will be valid in the next clock cycle. + assign rand_early_o = rand_valid_set; + + // The Keccak core is not supposed to ever consume randomness unless it's marked + // as valid. The only exception is if the reseeding of the PRNG just finished + // in the previous clock cycle. Because it's possible for the randomness to stay + // valid throughout the reseeding (the valid is for sure de-asserted at the end). + // The Keccak core may base its decision to start processing / consuming entropy + // before the valid is de-asserted. If this happens, the current buffer output + // might be used for both remasking and as auxiliary randomness which isn't ideal + // but given this happens only very rarely it should be okay. + `CALIPTRA_ASSUME(ConsumeNotAssertWhenNotValid_M, + rand_update_i | rand_consumed_i |-> rand_valid_o || $past(seed_done)) + + // Upon escalation or in case the EDN wait timer expires the entropy_req signal + // can be dropped before getting acknowledged. This may leave EDN in a strange + // state. We thus hold the request until it's actually acknowledged. In case the + // request is acknowledged while the FSM is in the StRandErr already, the + // incoming entropy is simply dropped. + assign entropy_req_o = entropy_req | entropy_req_hold_q; + assign entropy_req_hold_d = (entropy_req_hold_q | entropy_req) & ~entropy_ack_i; + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + entropy_req_hold_q <= '0; + end else begin + entropy_req_hold_q <= entropy_req_hold_d; + end + end + + // Randomness outputs ------------------------------------------------------- + + // Remaining outputs + assign count_error_o = hash_count_error; + + /////////////////// + // State Machine // + /////////////////// + + rand_st_e st, st_d; + + // State FF + `CALIPTRA_PRIM_FLOP_SPARSE_FSM(u_state_regs, st_d, st, rand_st_e, StRandReset) + + // State: Next State and Output Logic + // SEC_CM: FSM.SPARSE + always_comb begin + st_d = st; + sparse_fsm_error_o = 1'b 0; + + // Default Timer values + timer_enable = 1'b 0; + timer_update = 1'b 0; + + threshold_hit_clr = 1'b 0; + + // rand is valid when this logic expands the entropy. + // FSM sets the valid signal, the signal is cleared by `consume` signal + // or FSM clear signal. + // Why split the signal to set and clear? + // FSM only set the signal to make entropy valid while processing other + // tasks such as EDN request. + rand_valid_set = 1'b 0; + rand_valid_clear = 1'b 0; + + // mode_latch to store mode_i into mode_q + mode_latch = 1'b 0; + + // PRNG reseed handling + seed_en = 1'b 0; + seed_ack = 1'b 0; + entropy_req = 1'b 0; + + // Randomness control signals + prng_en = 1'b 0; + data_update = 1'b 0; + aux_update = 1'b 0; + + // Error + err_o = '{valid: 1'b 0, code: ErrNone, info: '0}; + + unique case (st) + StRandReset: begin + if (entropy_ready_i) begin + + // As SW ready, discard current dummy entropy and refresh. + rand_valid_clear = 1'b 1; + + mode_latch = 1'b 1; + // SW has configured KMAC + unique case (mode_i) + EntropyModeSw: begin + // Start reseeding the PRNG via ENTROPY_SEED CSR. + seed_en = 1'b 1; + st_d = StSwSeedWait; + end + + EntropyModeEdn: begin + // Start reseeding the PRNG via EDN. + seed_en = 1'b 1; + st_d = StRandEdn; + + // Timer reset + timer_update = 1'b 1; + end + + default: begin + // EntropyModeNone or other values + // Error. No valid mode given, report to SW + st_d = StRandErrIncorrectMode; + end + endcase + end else begin + st_d = StRandReset; + + // Setting the dummy rand gate until SW prepares. + // This lets the Application Interface move forward out of reset + // without SW intervention. + rand_valid_set = 1'b 1; + end + end + + StRandReady: begin + timer_enable = 1'b 1; // If limit is zero, timer won't work + + prng_en = prng_en_rand_q[0]; + + if ((rand_update_i || rand_consumed_i) && + ((fast_process_i && in_keyblock_i) || !fast_process_i)) begin + // If fast_process is set, don't clear the rand valid, even + // consumed. So, the logic does not expand the entropy again. + // If fast_process is not set, then every rand_consume signal + // triggers rand expansion. + prng_en = 1'b 1; + data_update = 1'b 1; + + if (rand_consumed_i) begin + st_d = StRandGenerate; + + rand_valid_clear = 1'b 1; + end else begin + st_d = StRandReady; + end + end else if ((mode_q == EntropyModeEdn) && + (entropy_refresh_req_i || threshold_hit_q)) begin + // Start reseeding the PRNG via EDN. + seed_en = 1'b 1; + st_d = StRandEdn; + + // Timer reset + timer_update = 1'b 1; + + // Clear the threshold as it refreshes the hash + threshold_hit_clr = 1'b 1; + end else begin + st_d = StRandReady; + end + end + + StRandEdn: begin + // Forward request of PRNG primitive. + entropy_req = seed_req; + + // Wait timer + timer_enable = 1'b 1; + + if (timer_expired && non_zero_wait_timer_limit) begin + // If timer count is non-zero and expired; + st_d = StRandErrWaitExpired; + + end else if (entropy_req_o && entropy_ack_i) begin + seed_ack = 1'b 1; + + if (seed_done) begin + st_d = StRandGenerate; + + if ((fast_process_i && in_keyblock_i) || !fast_process_i) begin + prng_en = 1'b 1; + data_update = 1'b 1; + rand_valid_clear = 1'b 1; + end + end else begin + st_d = StRandEdn; + end + end else if ((rand_update_i || rand_consumed_i) && + ((fast_process_i && in_keyblock_i) || !fast_process_i)) begin + // Somehow, while waiting the EDN entropy, the KMAC or SHA3 logic + // consumed the remained entropy. This can happen when the previous + // SHA3/ KMAC op completed and this Entropy FSM has moved to this + // state to refresh the entropy and the SW initiates another hash + // operation while waiting for the EDN response. + st_d = StRandEdn; + + prng_en = 1'b 1; + data_update = 1'b 1; + rand_valid_clear = rand_consumed_i; + end else begin + st_d = StRandEdn; + end + end + + StSwSeedWait: begin + // Forward ack driven by software. + seed_ack = seed_req & seed_update_i; + + if (seed_done) begin + st_d = StRandGenerate; + + prng_en = 1'b 1; + data_update = 1'b 1; + + rand_valid_clear = 1'b 1; + end else begin + st_d = StSwSeedWait; + end + end + + StRandGenerate: begin + // The current buffer output is used as auxiliary randomness and - + // depending on whether keccak_round is parametrized to always forward + // the buffer output and not use intermediate randomness - forwarded + // to the DOM multipliers without them updating in this cycle. We don't + // need to advance the PRNG as there is no risk of accidentally + // re-using the same randomness twice since after the current cycle: + // - We either load and re-mask the message/key which will use + // different PRNG output bits. The PRNG is advanced once per 64 bits + // loaded. + // - Or, the Keccak/SHA3 core is operated but it always starts with + // the linear layers which don't require fresh randomness. While + // processing the linear layers, the PRNG is advanced to have fresh + // randomness for the non-linear layer requiring it. + aux_update = 1'b 1; + rand_valid_set = 1'b 1; + prng_en = prng_en_rand_q[0]; + + st_d = StRandReady; + end + + StRandErrWaitExpired: begin + st_d = StRandErr; + + err_o = '{ valid: 1'b 1, + code: ErrWaitTimerExpired, + info: 24'(timer_value) + }; + end + + StRandErrIncorrectMode: begin + st_d = StRandErr; + + err_o = '{ valid: 1'b 1, + code: ErrIncorrectEntropyMode, + info: 24'(mode_q) + }; + end + + StRandErr: begin + // Keep entropy signal valid to complete current hashing even with error + rand_valid_set = 1'b 1; + + // Advance the PRNG after the entropy has been used. + prng_en = (rand_update_i | rand_consumed_i) & + ((fast_process_i & in_keyblock_i) | ~fast_process_i); + data_update = prng_en; + + if (err_processed_i) begin + st_d = StRandReset; + + end else begin + st_d = StRandErr; + end + + end + + StTerminalError: begin + // this state is terminal + st_d = st; + sparse_fsm_error_o = 1'b 1; + end + + default: begin + st_d = StTerminalError; + sparse_fsm_error_o = 1'b 1; + end + endcase + + // SEC_CM: FSM.GLOBAL_ESC, FSM.LOCAL_ESC + // Unconditionally jump into the terminal error state + // if the life cycle controller triggers an escalation. + if (lc_ctrl_pkg::lc_tx_test_true_loose(lc_escalate_en_i)) begin + st_d = StTerminalError; + end + end + `CALIPTRA_ASSERT_KNOWN(RandStKnown_A, st) + + // mubi4 sender + + assign entropy_configured = (st != StRandReset) + ? MuBi4True + : MuBi4False ; + caliptra_prim_mubi4_sender #( + .AsyncOn(1'b0) + ) u_entropy_configured ( + .clk_i, + .rst_ni, + + .mubi_i (entropy_configured ), + .mubi_o (entropy_configured_o) + ); + + //////////////// + // Assertions // + //////////////// + + // The EDN bus width needs to be equal to the width of the ENTROPY_SEED + // register as this module doesn't perform width adaption. + `CALIPTRA_ASSERT_INIT(EdnBusWidth_A, edn_pkg::ENDPOINT_BUS_WIDTH == 32) + +// the code below is not meant to be synthesized, +// but it is intended to be used in simulation and FPV +`ifndef SYNTHESIS + // Check that the supplied permutations are valid. + logic [EntropyOutputW-1:0] perm_test; + initial begin : p_perm_check + perm_test = '0; + for (int k = 0; k < EntropyOutputW; k++) begin + perm_test[RndCnstLfsrPerm[k]] = 1'b1; + end + // All bit positions must be marked with 1. + `CALIPTRA_ASSERT_I(PermutationCheck_A, &perm_test) + end +`endif + +endmodule : kmac_entropy diff --git a/designs/Caliptra/src/caliptra-rtl/kmac_errchk.sv b/designs/Caliptra/src/caliptra-rtl/kmac_errchk.sv new file mode 100644 index 0000000..1f8d36d --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/kmac_errchk.sv @@ -0,0 +1,471 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// KMAC Error Checking logic +// +// `kmac_err` module checks the SW introduced errors. +// 1. SW command sequencing error. +// 2. SW configuration error. +// +// ## SW Command Sequencing Error +// +// KMAC assumes the application interface and the SW register interface to +// follow the specific sequence. It expects the requester to send the `Start` +// command then push the message body. The `Process` command follows the message +// body. The SW may issue `Run` command if it needs the digest result more than +// a block rate. Then SW completes the hash operation with `Done` command. +// +// This `kmac_err` module checks if the SW issues the correct command. If not, +// it reports the error via ERR_CODE register. +// +// However, the logic does not prevent the error-ed command to be propagated. +// The unexpected commands are filtered by each individual submodule. +// +// st := { Idle, MsgFeed, Processing, Absorbed, Squeeze} +// +// allowed := { +// Idle : { Start }, +// MsgFeed: { Process }, +// Processing: { None }, +// Absorbed: { Run, Done }, +// Squeeze: { None } +// } +// +// ## SW Configuration Error +// +// `kmac_errchk` module checks if SW configured correct combinations of the +// configuration registers when the hashing operation begins. +// +// 1. Mode & Strength combinations +// 2. Kmac Prefix +// * sideload & key_valid -> Checker in kmac_core + +`include "caliptra_prim_assert.sv" + +module kmac_errchk + import caliptra_prim_mubi_pkg::*; + import kmac_pkg::*; + import ot_sha3_pkg::sha3_mode_e; + import ot_sha3_pkg::keccak_strength_e; +#( + parameter bit EnMasking = 1'b 1 +) ( + input clk_i, + input rst_ni, + + // Configurations + input sha3_mode_e cfg_mode_i, + input keccak_strength_e cfg_strength_i, + + input kmac_en_i, + input [47:0] cfg_prefix_6B_i, // first 6B of PREFIX + + // If the signal below is set, errchk propagates the command to the rest of + // the blocks even with err_modestrength. + input cfg_en_unsupported_modestrength_i, + + // Entropy Ready Status to check if SW initiated the hahs without entropy cfg + input entropy_ready_pulse_i, + + // SW commands: Only valid command is sent out to the rest of the modules + input kmac_cmd_e sw_cmd_i, + output kmac_cmd_e sw_cmd_o, + + // Status from KMAC_APP + input app_active_i, + + // Status from SHA3 core + input mubi4_t sha3_absorbed_i, + input keccak_done_i, + + // Life cycle + input lc_ctrl_pkg::lc_tx_t lc_escalate_en_i, + + // Error processed indicator + input err_processed_i, + + input mubi4_t clear_after_error_i, + + output err_t error_o, + output logic sparse_fsm_error_o +); + + // ot_sha3_pkg::sha3_mode_e + import ot_sha3_pkg::L128; + import ot_sha3_pkg::L224; + import ot_sha3_pkg::L256; + import ot_sha3_pkg::L384; + import ot_sha3_pkg::L512; + + // ot_sha3_pkg::keccak_strength_e + import ot_sha3_pkg::Sha3; + import ot_sha3_pkg::Shake; + import ot_sha3_pkg::CShake; + + ///////////////// + // Definitions // + ///////////////// + // Encoding generated with: + // $ ./util/design/sparse-fsm-encode.py -d 3 -m 5 -n 6 \ + // -s 2239170217 --language=sv + // + // Hamming distance histogram: + // + // 0: -- + // 1: -- + // 2: -- + // 3: |||||||||||||||||||| (50.00%) + // 4: |||||||||||||||| (40.00%) + // 5: |||| (10.00%) + // 6: -- + // + // Minimum Hamming distance: 3 + // Maximum Hamming distance: 5 + // Minimum Hamming weight: 2 + // Maximum Hamming weight: 4 + // + localparam int StateWidth = 6; + typedef enum logic [StateWidth-1:0] { + StIdle = 6'b001101, + StMsgFeed = 6'b110001, + StProcessing = 6'b010110, + StAbsorbed = 6'b100010, + StSqueezing = 6'b111100, + StTerminalError = 6'b011011 + } st_e; + st_e st, st_d; + + localparam int StateWidthL = 3; + typedef enum logic [StateWidthL-1:0] { + StIdleL, + StMsgFeedL, + StProcessingL, + StAbsorbedL, + StSqueezingL, + StErrorL + } st_logical_e; + st_logical_e stL; + + + ///////////// + // Signals // + ///////////// + + // `err_swsequence` occurs when SW issues wrong command + logic err_swsequence; + + // `err_modestrength` occcurs when Mode & Strength combinations are not + // allowed. This error does not block the hashing operation. + // UnexpectedModeStrength may stop the processing based on CFG + // The error raises when SW issues CmdStart. + logic err_modestrength; + + // `err_prefix` occurs when the first 6B of !!PREFIX is not + // `encode_string("KMAC")` and kmac is enabled. This error does not block the + // KMAC operation. + logic err_prefix; + + // `err_entropy_ready` occurs when SW initiated the hashing op. without + // configuring the entropy. This error may happen only when EnMasking is + // set. + logic err_entropy_ready; + + // entropy_ready is a pulse signal. Logic needs to store the state. + logic cfg_entropy_ready; + + // Signal to block the SW command propagation + logic block_swcmd; + + /////////////////// + // Error Checker // + /////////////////// + + // SW sequence Error + // info field: Current state, Received command + // SEC_CM: FSM.SPARSE + always_comb begin + err_swsequence = 1'b 0; + sparse_fsm_error_o = 1'b 0; + + unique case (st) + StIdle: begin + // Allow Start command only + if (!(sw_cmd_i inside {CmdNone, CmdStart})) begin + err_swsequence = 1'b 1; + end + end + + StMsgFeed: begin + // Allow Process only + if (!(sw_cmd_i inside {CmdNone, CmdProcess})) begin + err_swsequence = 1'b 1; + end + end + + StProcessing: begin + if (sw_cmd_i != CmdNone) begin + err_swsequence = 1'b 1; + end + end + + StAbsorbed: begin + // Allow ManualRun and Done + if (!(sw_cmd_i inside {CmdNone, CmdManualRun, CmdDone})) begin + err_swsequence = 1'b 1; + end + end + + StSqueezing: begin + if (sw_cmd_i != CmdNone) begin + err_swsequence = 1'b 1; + end + end + + StTerminalError: begin + err_swsequence = 1'b 0; + sparse_fsm_error_o = 1'b 1; + end + + default: begin + err_swsequence = 1'b 0; + sparse_fsm_error_o = 1'b 1; + end + endcase + end + + assign block_swcmd = (err_swsequence) + || (err_modestrength + && !cfg_en_unsupported_modestrength_i) + || err_entropy_ready; + + // sw_cmd_o latch + // To reduce the command path delay, sw_cmd is latched here + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) sw_cmd_o <= CmdNone; + else if (!block_swcmd) sw_cmd_o <= sw_cmd_i; + end + + // Mode & Strength + always_comb begin : check_modestrength + err_modestrength = 1'b 0; + + if (st == StIdle && st_d == StMsgFeed) begin + // When moving to the next stage, checks the config + if (!((cfg_mode_i == Sha3 && + cfg_strength_i inside {L224, L256, L384, L512}) || + ((cfg_mode_i == Shake || cfg_mode_i == CShake) && + (cfg_strength_i inside {L128, L256})))) begin + err_modestrength = 1'b 1; + end + end + end : check_modestrength + + + // Check prefix 6B is `encode_string("KMAC")` + always_comb begin : check_prefix + err_prefix = 1'b 0; + + if (st == StIdle && st_d == StMsgFeed && kmac_en_i) begin + if (cfg_prefix_6B_i != EncodedStringKMAC) begin + err_prefix = 1'b 1; + end + end + end : check_prefix + + if (EnMasking) begin : g_entropy_chk + + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) cfg_entropy_ready <= 1'b 0; + else if (err_processed_i) cfg_entropy_ready <= 1'b 0; + else if (entropy_ready_pulse_i && st == StIdle) begin + cfg_entropy_ready <= 1'b 1; + end + end + + always_comb begin : check_entropy_ready + err_entropy_ready = 1'b 0; + + if (st == StIdle && st_d == StMsgFeed && kmac_en_i) begin + if (!cfg_entropy_ready) begin + err_entropy_ready = 1'b 1; + end + end + end : check_entropy_ready + + end else begin : g_pseudo_entropy_chk + + // If EnMasking is 0, entropy module is not generated. + // tying the error signal to 0. + assign err_entropy_ready = 1'b 0; + + assign cfg_entropy_ready = 1'b 1; + + logic unused_cfg_entropy_ready; + assign unused_cfg_entropy_ready = cfg_entropy_ready; + + logic unused_err_processed; + assign unused_err_processed = err_processed_i; + + logic unused_entropy_ready_puls; + assign unused_entropy_ready_puls = entropy_ready_pulse_i; + + end + + always_comb begin : recode_st + unique case (st) + StIdle : stL = StIdleL; + StMsgFeed : stL = StMsgFeedL; + StProcessing : stL = StProcessingL; + StAbsorbed : stL = StAbsorbedL; + StSqueezing : stL = StSqueezingL; + default : stL = StErrorL; + endcase + end : recode_st + + // Return error code + err_t err; + always_comb begin : err_return + err = '{valid: 1'b0, code: ErrNone, info: '0}; + + priority case (1'b 1) + err_swsequence: begin + err = '{ valid: 1'b 1, + code: ErrSwCmdSequence, + info: {5'h0, + {err_swsequence, err_modestrength, err_prefix}, + {5'h 0, stL}, + {2'b0, sw_cmd_i} + } + }; + end + + err_modestrength: begin + err = '{ valid: 1'b 1, + code: ErrUnexpectedModeStrength, + info: { 5'h 0, + {err_swsequence, err_modestrength, err_prefix}, + 8'h 0, + {2'b 00, cfg_mode_i}, + {1'b 0, cfg_strength_i} + } + }; + end + + err_prefix: begin + err = '{ valid: 1'b 1, + code: ErrIncorrectFunctionName, + info: { 5'h 0, + {err_swsequence, err_modestrength, err_prefix}, + 16'h 0000 + } + }; + end + + err_entropy_ready: begin + err = '{ valid: 1'b 1, + code: ErrSwHashingWithoutEntropyReady, + info: { 8'({ err_entropy_ready, + err_swsequence, + err_modestrength, + err_prefix}), + 16'({kmac_en_i, cfg_entropy_ready}) + } + }; + end + + default: begin + err = '{valid: 1'b0, code: ErrNone, info: '0}; + end + endcase + end : err_return + + assign error_o = err; + + // If below failed, revise err_swsequence error response info field. + `CALIPTRA_ASSERT_INIT(ExpectedStSwCmdBits_A, $bits(st) == StateWidth && $bits(sw_cmd_i) == 6) + + // If failed, revise err_modestrength error info field. + `CALIPTRA_ASSERT_INIT(ExpectedModeStrengthBits_A, + $bits(cfg_mode_i) == 2 && $bits(cfg_strength_i) == 3) + + + /////////////////// + // State Machine // + /////////////////// + st_e st_gated_d; + + `CALIPTRA_PRIM_FLOP_SPARSE_FSM(u_state_regs, st_gated_d, st, st_e, StIdle) + + // ICEBOX(#14631): Move block_swcmd to PRIM_FLOP_SPARSE_FSM() + // + // It would be better to place this condition (block_swcmd) in `always_ff` + // block to clearly indicate the clock gating condition. However, the + // statemachine uses the sparse encoding scheme and macro. It prevents any + // latch enable signals. + assign st_gated_d = (block_swcmd) ? st : st_d ; + + always_comb begin : next_state + st_d = st; + + unique case (st) + StIdle: begin + if (!app_active_i && sw_cmd_i == CmdStart) begin + // Proceed to the next state only when the SW issues the Start command + // in a valid period. + st_d = StMsgFeed; + end + end + + StMsgFeed: begin + if (sw_cmd_i == CmdProcess) begin + st_d = StProcessing; + end + end + + StProcessing: begin + if (mubi4_test_true_strict(sha3_absorbed_i)) begin + st_d = StAbsorbed; + end + end + + StAbsorbed: begin + if (sw_cmd_i == CmdManualRun) begin + st_d = StSqueezing; + end else if (sw_cmd_i == CmdDone) begin + st_d = StIdle; + end + end + + StSqueezing: begin + if (keccak_done_i) begin + st_d = StAbsorbed; + end + end + + StTerminalError: begin + // this state is terminal + st_d = st; + end + + default: begin + // this state is terminal + st_d = StTerminalError; + end + endcase + + // SEC_CM: FSM.GLOBAL_ESC, FSM.LOCAL_ESC + // Unconditionally jump into the terminal error state + // if the life cycle controller triggers an escalation. + if (lc_ctrl_pkg::lc_tx_test_true_loose(lc_escalate_en_i)) begin + st_d = StTerminalError; + end + + if (st_d != StTerminalError && + mubi4_test_true_strict(clear_after_error_i)) begin + st_d = StIdle; + end + end : next_state + `CALIPTRA_ASSERT_KNOWN(StKnown_A, st) + +endmodule : kmac_errchk diff --git a/designs/Caliptra/src/caliptra-rtl/kmac_msgfifo.sv b/designs/Caliptra/src/caliptra-rtl/kmac_msgfifo.sv new file mode 100644 index 0000000..2affea2 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/kmac_msgfifo.sv @@ -0,0 +1,285 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// KMAC MSG_FIFO +// +// This module converts TL-UL interface into MSG_FIFO interface used in KMAC. + +`include "caliptra_prim_assert.sv" + +module kmac_msgfifo + import caliptra_prim_mubi_pkg::*; + import kmac_pkg::*; +#( + // OutWidth is MsgFIFO data width. prim_packer converts InW to OutW prior to + // pushing to MsgFIFO + parameter int OutWidth = 64, + + parameter bit EnMasking = 1'b 1, + + // Internal MsgFIFO Entry count + parameter int MsgDepth = 9, + localparam int MsgDepthW = $clog2(MsgDepth+1) // derived parameter +) ( + input clk_i, + input rst_ni, + + // from REG or KeyMgr Intf input + input fifo_valid_i, + input [OutWidth-1:0] fifo_data_i, + input [OutWidth-1:0] fifo_mask_i, + output fifo_ready_o, + + // MSG interface + output logic msg_valid_o, + output logic [OutWidth-1:0] msg_data_o, + output logic [OutWidth/8-1:0] msg_strb_o, + input msg_ready_i, + + output logic fifo_empty_o, + output logic fifo_full_o, + output logic [MsgDepthW-1:0] fifo_depth_o, + + // Control + input mubi4_t clear_i, + + // process_i --> process_o + // process_o asserted after all internal messages are flushed out to MSG interface + input process_i, + output logic process_o, + + err_t err_o +); + + ///////////////// + // Definitions // + ///////////////// + typedef struct packed { + logic [OutWidth-1:0] data; + logic [OutWidth/8-1:0] strb; // one bit per byte + } fifo_t; + + typedef enum logic [1:0] { + // In Idle, it checks if process input received or not. + // If received, the signal goes to packer and flush internal pending data + FlushIdle, + + // In Packer state, it waits the packer flush operation completes. + // The flush_done signal do nothing but after this, it is assumed that + // MSG FIFO received the request. + FlushPacker, + + // In Fifo, it waits until MsgFifo is empty. Then asserts process_o + FlushFifo, + + // After flushing, it waits the done (clear) signal. It is assumed that + // no incoming messages are transmitted between `process_i` and `clear_i` + FlushClear + } flush_st_e; + + ///////////// + // Signals // + ///////////// + + // Packer write path + logic packer_wvalid; + logic [OutWidth-1:0] packer_wdata; + logic [OutWidth-1:0] packer_wmask; + logic packer_wready; + + // Message FIFO signals + logic fifo_wvalid; + fifo_t fifo_wdata; + logic fifo_wready; + logic fifo_rvalid; + fifo_t fifo_rdata; + logic fifo_rready; + + logic fifo_err; // FIFO dup. counter error + + // packer flush to msg_fifo, then msg_fifo empty out the internals + // then assert msgfifo_flush_done + logic packer_flush_done; + logic msgfifo_flush_done; + + logic packer_err; + + // SEC_CM: PACKER.CTR.REDUN + caliptra_prim_packer #( + .InW (OutWidth), + .OutW (OutWidth), + .HintByteData (1), + + // Turn on dup counter when EnMasking is set + .EnProtection (EnMasking) + ) u_packer ( + .clk_i, + .rst_ni, + + .valid_i (fifo_valid_i), + .data_i (fifo_data_i), + .mask_i (fifo_mask_i), + .ready_o (fifo_ready_o), + + .valid_o (packer_wvalid), + .data_o (packer_wdata), + .mask_o (packer_wmask), + .ready_i (packer_wready), + + .flush_i (process_i), + .flush_done_o (packer_flush_done), + + .err_o (packer_err) + ); + + // Assign packer wdata and wmask to FIFO struct + // In contrast to HMAC case, KMAC SHA3 operates in little-endian. MSG fifo is + // converted into 3-D form so the endianess here is not a problem. + assign fifo_wdata.data = packer_wdata; + always_comb begin + fifo_wdata.strb = '0; + for (int i = 0 ; i < OutWidth/8 ; i++) begin + fifo_wdata.strb[i] = packer_wmask[8*i]; + end + end + + // MsgFIFO + caliptra_prim_fifo_sync #( + .Width ($bits(fifo_t)), + .Pass (1'b 1), + .Depth (MsgDepth), + .Secure (EnMasking) + ) u_msgfifo ( + .clk_i, + .rst_ni, + .clr_i (mubi4_test_true_strict(clear_i)), + + .wvalid_i(fifo_wvalid), + .wready_o(fifo_wready), + .wdata_i (fifo_wdata), + + .rvalid_o (fifo_rvalid), + .rready_i (fifo_rready), + .rdata_o (fifo_rdata), + + .full_o (fifo_full_o), + .depth_o (fifo_depth_o), + .err_o (fifo_err) + + ); + + assign fifo_wvalid = packer_wvalid; + assign packer_wready = fifo_wready; + + assign msg_valid_o = fifo_rvalid; + assign fifo_rready = msg_ready_i; + assign msg_data_o = fifo_rdata.data; + assign msg_strb_o = fifo_rdata.strb; + + assign fifo_empty_o = !fifo_rvalid; + + // Flush (process from outside) handling + flush_st_e flush_st, flush_st_d; + + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + flush_st <= FlushIdle; + end else begin + flush_st <= flush_st_d; + end + end + + always_comb begin + flush_st_d = flush_st; + + msgfifo_flush_done = 1'b 0; + + unique case (flush_st) + FlushIdle: begin + if (process_i) begin + flush_st_d = FlushPacker; + end else begin + flush_st_d = FlushIdle; + end + end + + FlushPacker: begin + if (packer_flush_done) begin + flush_st_d = FlushFifo; + end else begin + flush_st_d = FlushPacker; + end + end + + FlushFifo: begin + if (fifo_empty_o) begin + flush_st_d = FlushClear; + + msgfifo_flush_done = 1'b 1; + end else begin + flush_st_d = FlushFifo; + end + end + + FlushClear: begin + if (mubi4_test_true_strict(clear_i)) begin + flush_st_d = FlushIdle; + end else begin + flush_st_d = FlushClear; + end + end + + default: begin + flush_st_d = FlushIdle; + end + endcase + end + + assign process_o = msgfifo_flush_done; + + err_t error; + assign err_o = error; + + // Error assign + always_comb begin : error_logic + error = '{ + valid: 1'b 0, + code: kmac_pkg::ErrNone, + info: '0 + }; + + // Priority case -> if .. else if + if (packer_err) begin + error = '{ + // If EnProtection is 0, packer_err is tied to 0 + valid: 1'b 1, + code: kmac_pkg::ErrPackerIntegrity, + info: kmac_pkg::ErrInfoW'(flush_st) + }; + end else if (fifo_err) begin + error = '{ + valid: 1'b 1, + code: kmac_pkg::ErrMsgFifoIntegrity, + info: kmac_pkg::ErrInfoW'(flush_st) + }; + end + end : error_logic + + //////////////// + // Assertions // + //////////////// + + // Flush state known checker + `CALIPTRA_ASSERT(FlushStInValid_A, flush_st inside {FlushIdle, FlushPacker, FlushFifo, FlushClear}) + + // Packer done signal is asserted at least one cycle later + `CALIPTRA_ASSERT(PackerDoneDelay_A, $onehot0({process_i, packer_flush_done})) + + // process_i not asserted during the flush operation + `CALIPTRA_ASSUME(PackerDoneValid_a, process_i |-> flush_st == FlushIdle) + + // No messages in between `process_i` and `clear_i` + `CALIPTRA_ASSUME(MessageValid_a, fifo_valid_i |-> flush_st == FlushIdle) + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/kmac_pkg.sv b/designs/Caliptra/src/caliptra-rtl/kmac_pkg.sv new file mode 100644 index 0000000..770c05b --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/kmac_pkg.sv @@ -0,0 +1,485 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// kmac_pkg + +package kmac_pkg; + parameter int MsgWidth = ot_sha3_pkg::MsgWidth; + parameter int MsgStrbW = ot_sha3_pkg::MsgStrbW; + + // Message FIFO depth + // + // Assume entropy is ready always (if Share is reused as an entropy in Chi) + // Then it takes 72 cycles to complete the Keccak round. While Keccak is in + // operation, the module need to store the incoming messages to not degrade + // the throughput. + // + // Based on the observation from HMAC case, the core usually takes 5 clocks + // to fetch data and store into KMAC. So the core can push at most 14.5 X 4B + // which is 58B. After that, Keccak can fetch the data from MSG_FIFO faster + // rate than the core can push. To fetch 58B, it takes around 7~8 cycles. + // For that time, the core only can push at most 2 DW. After that Keccak + // waits the incoming message. + // + // So Message FIFO doesn't need full block size except the KMAC case, which + // is delayed the operation by processing Function Name N, customization S, + // and secret keys. But KMAC doesn't need high throughput anyway (72Mb/s). + parameter int RegIntfWidth = 32; // 32bit interface + parameter int RegLatency = 5; // 5 cycle to write one Word + parameter int Sha3Latency = 72; // Expected masked sha3 processing time 24x3 + + // Total required buffer size while SHA3 is in processing + parameter int BufferCycles = (Sha3Latency + RegLatency - 1)/RegLatency; + parameter int BufferSizeBits = RegIntfWidth * BufferCycles; + + // Required MsgFifoDepth. Adding slightly more buffer for margin + parameter int MsgFifoDepth = 2 + ((BufferSizeBits + MsgWidth - 1)/MsgWidth); + parameter int MsgFifoDepthW = $clog2(MsgFifoDepth+1); + + parameter int MsgWindowWidth = 32; // Register width + parameter int MsgWindowDepth = 512; // 2kB space + + // Key related definitions + // If this value is changed, please modify the logic inside kmac_core + // that assigns the value into `encoded_key` + parameter int MaxKeyLen = 512; + + // size of encode_string(Key) + // $ceil($clog2(MaxKeyLen+1)/8) + parameter int MaxEncodedKeyLenW = $clog2(MaxKeyLen+1); + parameter int MaxEncodedKeyLenByte = (MaxEncodedKeyLenW + 8 - 1) / 8; + parameter int MaxEncodedKeyLenSize = MaxEncodedKeyLenByte * 8; + + // Secret Key left_encode(len(Key)) + // ---------- ------------------------ + parameter int MaxEncodedKeyW = MaxKeyLen + MaxEncodedKeyLenSize + 8; + + // key_len is SW configurable CSR. + // Current KMAC allows 5 key length options. + // This value determines the KMAC core how to map the value + // from Secret Key register to key size block + typedef enum logic [2:0] { + Key128 = 3'b 000, // 128 bit secret key + Key192 = 3'b 001, // 192 bit secret key + Key256 = 3'b 010, // 256 bit secret key + Key384 = 3'b 011, // 384 bit secret key + Key512 = 3'b 100 // 512 bit secret key + } key_len_e; + + + // SEC_CM: SW_CMD.CTRL.SPARSE + // kmac_cmd_e defines the possible command sets that software issues via + // !!CMD register. This is mainly to limit the error scenario that SW writes + // multiple commands at once. Additionally they are sparse encoded to harden + // against FI attacks + // + // Encoding generated with: + // $ ./util/design/sparse-fsm-encode.py -d 3 -m 5 -n 6 \ + // -s 1891656028 --language=sv + // + // Hamming distance histogram: + // + // 0: -- + // 1: -- + // 2: -- + // 3: |||||||||||||||||||| (50.00%) + // 4: |||||||||||||||| (40.00%) + // 5: |||| (10.00%) + // 6: -- + // + // Minimum Hamming distance: 3 + // Maximum Hamming distance: 5 + // Minimum Hamming weight: 3 + // Maximum Hamming weight: 4 + // + typedef enum logic [5:0] { + //CmdNone = 6'b001011, // dec 10 + // CmdNone is manually set to all zero by design! + // The minimum Hamming distance is still 3 + CmdNone = 6'b000000, // dec 0 + CmdStart = 6'b011101, // dec 29 + CmdProcess = 6'b101110, // dec 46 + CmdManualRun = 6'b110001, // dec 49 + CmdDone = 6'b010110 // dec 22 + } kmac_cmd_e; + + // Timer + parameter int unsigned TimerPrescalerW = 10; + parameter int unsigned EdnWaitTimerW = 16; + + // Entropy Mode Selection : Should be matched to register package Enum value + typedef enum logic [1:0] { + EntropyModeNone = 2'h 0, + EntropyModeEdn = 2'h 1, + EntropyModeSw = 2'h 2 + } entropy_mode_e; + + // PRNG (kmac_entropy) + parameter int unsigned EntropyOutputW = 800; + parameter int unsigned EntropyStateW = 288; + + // These LFSR parameters have been generated with + // $ ./util/design/gen-lfsr-seed.py --width 288 --seed 31468618 --prefix "" + typedef logic [EntropyStateW-1:0] lfsr_seed_t; + parameter lfsr_seed_t RndCnstLfsrSeedDefault = { + 32'h758a4420, + 256'h31e1c461_6ea343ec_153282a3_0c132b57_23c5a4cf_4743b3c7_c32d580f_74f1713a + }; + + // We use a single seed that is split down into chunks internally. + // These LFSR parameters have been generated with + // $ ./util/design/gen-lfsr-seed.py --width 800 --seed 3369807298 --prefix "" + typedef logic [EntropyOutputW-1:0][$clog2(EntropyOutputW)-1:0] lfsr_perm_t; + parameter lfsr_perm_t RndCnstLfsrPermDefault = { + 64'hb1a3e87aeb4e69f0, + 256'h2d8a6ee2c9ac567b2aa401a639a2a8ea2553614c0a8daf672c06546fc0d35267, + 256'hc4572024bc116458dd0f1c10a8aef5c4ad9a788968d0d7ca7345c6b8f277a5d3, + 256'hec5da20f261826ed3c8992724e70db897060be51b07a96902e14a42d12d320f8, + 256'h187049b6c25f35d0e485cc4b9ef01dad2865b5e558926f380718b74394fe0f82, + 256'hd5395a7d0aa4845af814e8681107a4c793758572c9467493bf1248a48f1b40c2, + 256'h09319b55111d0401819685a43a06f0da441021a8c220b14f01d44e49c1683a82, + 256'hafeb980964aa050641f4205131d9d4741eb5dd658e603b8ed438cb1096628d42, + 256'h62c9d75ced78ed09a3ddbb60f533eef10aa5a54b478d61a06a4b326eb3402105, + 256'hc27d562c6d91b48440d6d06e543be9871628a4aa9b3d2e51fa0ac2eb89a17f6d, + 256'h207ad96caf25d1fcffab210c1aff12252346fe4d56a7cd9b8605c7fa638895a9, + 256'h60158cd3a1ce4f2f6cf5d48579ac14b1e5219ca8914e0507b635dc712554f6bb, + 256'h0ae412943a7596f4644a0c13646adc91d02c406a10d232791d3de9919eec5424, + 256'haa2cac5f556c15c647eb29365062daf6aa848e10b3f665abccca713036d9f1cb, + 256'h1c9bd4aaeb19c5ac01b1805e0d5479860870da49a55e8f386ca8232c728e2f61, + 256'h3007aa420758818e5312401372eaa00d21c70c7e1158d2e08a1b6ac0b820cb67, + 256'hf0ba4b5c0865ff04f0f9d0175817c65d81918e43e14b2f83d574bfa9c6e6deae, + 256'h64c22c2974a1d5c55e2367004b249d5a02fc566685ea33b6f73aaa0244b34412, + 256'hb1a12230adb1748dc1d956f9f10c8e1aa52f4702e06a16680d92226c830ec4ce, + 256'h4c2eead21f08c387c3f1de89eb33b983c748e848f68b54f256715221177c5a4a, + 256'h0a47d82741955626755ba1cc24e2ba40504111b9e26136be714c5bc0d330c3f7, + 256'h75e863de763270a993890d633c6897218e151943edd8b79ae145cf564b774613, + 256'h0b0a76c40e7e84c876640dc78260c09a85e92e5ab56c22c0e72a8669fe88ba10, + 256'h8b99e437c776f0cea0d144f285b6ab7259e12284f380ae3410171cd6a8b04415, + 256'he95081c8c57e3e526ad5b38019a5c1b5505540462157e7c7e68e6a6a16ac460a, + 256'h5d5578da28092c7cc927cb9c0ed614a79b0e32b4c5b6a269a40743bef42b5e29, + 256'hd9a75ecb5548a29e9d34ddda07c8404aabbf5479456731ece3785f6090c3f862, + 256'h6eb1a5119e8b8e56b1455d820b46e20e15bb7d185a636b10ab8565732c59a302, + 256'h329925186604edbd5029a9f865268e90003b5b69d3e99240c3432291a60c62a4, + 256'hebad1ed028cd021b27260db22089e0c44481b1a4c120134ac63dc52fbc4cafb2, + 256'he065add2665fb361665267b53024329d96587d661f724171155ee73a3f0c47a8, + 256'h149751a5903c8bbcaf1782e415dfda531eb2af67c25e190330a12000e1fbb9cd + }; + + // These LFSR parameters have been generated with + // $ ./util/design/gen-lfsr-seed.py --width 800 --seed 31468618 --prefix "Buffer" + typedef logic [EntropyOutputW-1:0] buffer_lfsr_seed_t; + parameter buffer_lfsr_seed_t RndCnstBufferLfsrSeedDefault = { + 32'h292603b4, + 256'hf1d83863_e0bd0634_4544ad28_a91d8668_24b66efd_92ad8123_5381f2bc_3d65392c, + 256'h83c01ea5_d8be84f1_e2588917_11849a07_5a71f35f_e9b31605_f9077a6b_758a4420, + 256'h31e1c461_6ea343ec_153282a3_0c132b57_23c5a4cf_4743b3c7_c32d580f_74f1713a + }; + + // Message permutation + // These LFSR parameters have been generated with + // $ ./util/design/gen-lfsr-seed.py --width 64 --seed 1201202158 --prefix "" + // And changed the type name from lfsr_perm_t to msg_perm_t + typedef logic [MsgWidth-1:0][$clog2(MsgWidth)-1:0] msg_perm_t; + parameter msg_perm_t RndCnstMsgPermDefault = { + 128'h382af41849db4cfb9c885f72f118c102, + 256'hcb5526978defac799192f65f54148379af21d7e10d82a5a33c3f31a1eaf964b8 + }; + + /////////////////////////// + // Application interface // + /////////////////////////// + + // Application Algorithm + // Each interface can choose algorithms among SHA3, cSHAKE, KMAC + typedef enum logic [1:0] { + // SHA3 mode doer not nees any additional information. + // Prefix will be tied to all zero and not used. + AppSHA3 = 0, + + // In CShake/ KMAC mode, the Prefix can be determined by the compile-time + // parameter or through CSRs. + AppCShake = 1, + + // In KMAC mode, the secret key always comes from sideload. + // KMAC mode needs uniformly distributed entropy. The request will be + // silently discarded in Reset state. + AppKMAC = 2 + } app_mode_e; + + // Predefined encoded_string + parameter logic [15:0] EncodedStringEmpty = 16'h 0001; + parameter logic [47:0] EncodedStringKMAC = 48'h 4341_4D4B_2001; + // encoded_string("LC_CTRL") + parameter logic [71:0] EncodedStringLcCtrl = 72'h 4c_5254_435f_434C_3801; + // encoded_string("ROM_CTRL") + parameter logic [79:0] EncodedStringRomCtrl = 80'h 4c52_5443_5f4d_4f52_4001; + parameter int unsigned NSPrefixW = ot_sha3_pkg::NSRegisterSize*8; + + typedef struct packed { + app_mode_e Mode; + + ot_sha3_pkg::keccak_strength_e KeccakStrength; + + // PrefixMode determines the origin value of Prefix that is used in KMAC + // and cSHAKE operations. + // Choose **0** for CSRs (!!PREFIX), or **1** to use `Prefix` parameter + // below. + logic PrefixMode; + + // If `PrefixMode` is 1'b 1, then this `Prefix` value will be used in + // cSHAKE or KMAC operation. + logic [NSPrefixW-1:0] Prefix; + } app_config_t; + + parameter app_config_t AppCfgKeyMgr = '{ + Mode: AppKMAC, // KeyMgr uses KMAC operation + KeccakStrength: ot_sha3_pkg::L256, + PrefixMode: 1'b1, // Use prefix parameter + // {fname: encoded_string("KMAC"), custom_str: encoded_string("")} + Prefix: NSPrefixW'({EncodedStringEmpty, EncodedStringKMAC}) + }; + + parameter app_config_t AppCfgKeyMgrStripped = '{ + Mode: AppCShake, // For the stripped KMAC KeyMgr uses cSHAKE operation + KeccakStrength: ot_sha3_pkg::L256, + PrefixMode: 1'b1, // Use prefix parameter + // {fname: encoded_string("KMAC"), custom_str: encoded_string("")} + Prefix: NSPrefixW'({EncodedStringEmpty, EncodedStringKMAC}) + }; + + parameter app_config_t AppCfgLcCtrl= '{ + Mode: AppCShake, + KeccakStrength: ot_sha3_pkg::L128, + PrefixMode: 1'b1, // Use prefix parameter + // {fname: encode_string(""), custom_str: encode_string("LC_CTRL")} + Prefix: NSPrefixW'({EncodedStringLcCtrl, EncodedStringEmpty}) + }; + + parameter app_config_t AppCfgRomCtrl = '{ + Mode: AppCShake, + KeccakStrength: ot_sha3_pkg::L256, + PrefixMode: 1'b1, // Use prefix parameter + // {fname: encode_string(""), custom_str: encode_string("ROM_CTRL")} + Prefix: NSPrefixW'({EncodedStringRomCtrl, EncodedStringEmpty}) + }; + + // Exporting the app internal mux selection enum into the package. So that DV + // can use this enum in its scoreboard. + // Encoding generated with: + // $ ./util/design/sparse-fsm-encode.py -d 3 -m 4 -n 5 \ + // -s 713832113 --language=sv + // + // Hamming distance histogram: + // + // 0: -- + // 1: -- + // 2: -- + // 3: |||||||||||||||||||| (66.67%) + // 4: |||||||||| (33.33%) + // 5: -- + // + // Minimum Hamming distance: 3 + // Maximum Hamming distance: 4 + // Minimum Hamming weight: 1 + // Maximum Hamming weight: 4 + // + localparam int AppMuxWidth = 5; + typedef enum logic [AppMuxWidth-1:0] { + SelNone = 5'b10100, + SelApp = 5'b11001, + SelOutLen = 5'b00010, + SelSw = 5'b01111 + } app_mux_sel_e ; + +// Encoding generated with: + // $ ./util/design/sparse-fsm-encode.py -d 3 -m 14 -n 10 \ + // -s 2454278799 --language=sv + // + // Hamming distance histogram: + // + // 0: -- + // 1: -- + // 2: -- + // 3: |||||||||| (14.29%) + // 4: |||||||||||||||||||| (27.47%) + // 5: ||||||||||||| (18.68%) + // 6: |||||||||||||||| (21.98%) + // 7: |||||||| (10.99%) + // 8: |||| (6.59%) + // 9: -- + // 10: -- + // + // Minimum Hamming distance: 3 + // Maximum Hamming distance: 8 + // Minimum Hamming weight: 3 + // Maximum Hamming weight: 8 + // + localparam int AppStateWidth = 10; + typedef enum logic [AppStateWidth-1:0] { + StIdle = 10'b1010111110, + + // Application operation. + // + // if start request comes from an App first, until the operation ends by the + // requested App, all operations are granted to the specific App. SW + // requests and other Apps requests will be ignored. + // + // App interface does not have control signals. When first data valid occurs + // from an App, this logic asserts the start command to the downstream. When + // last beat pulse comes, this logic asserts the process to downstream + // (after the transaction is accepted regardless of partial writes or not) + // When absorbed by SHA3 core, the logic sends digest to the requested App + // and right next cycle, it triggers done command to downstream. + + // In StAppCfg state, it latches the cfg from AppCfg parameter to determine + // the kmac_mode, sha3_mode, keccak strength. + StAppCfg = 10'b1010101101, + + StAppMsg = 10'b1110001011, + + // In StKeyOutLen, this module pushes encoded outlen to the MSG_FIFO. + // Assume the length is 256 bit, the data will be 48'h 02_0100 + StAppOutLen = 10'b1010011000, + StAppProcess = 10'b1110110010, + StAppWait = 10'b1001010000, + + // SW Controlled + // If start request comes from SW first, until the operation ends, all + // requests from KeyMgr will be discarded. + StSw = 10'b0010111011, + + // Error KeyNotValid + // When KeyMgr operates, the secret key is not ready yet. + StKeyMgrErrKeyNotValid = 10'b0111011111, + + StError = 10'b1110010111, + StErrorAwaitSw = 10'b0110001100, + StErrorAwaitApp = 10'b1011100000, + StErrorWaitAbsorbed = 10'b0010100100, + StErrorServiceRejected = 10'b1101000111, + + // This state is used for terminal errors + StTerminalError = 10'b0101110110 + } st_e; + + // MsgWidth : 64 + // MsgStrbW : 8 + parameter int unsigned AppDigestW = 384; + parameter int unsigned AppKeyW = 256; + + typedef struct packed { + logic valid; + logic [MsgWidth-1:0] data; + logic [MsgStrbW-1:0] strb; + logic last; + } app_req_t; + + typedef struct packed { + logic ready; + logic done; + logic [AppDigestW-1:0] digest_share0; + logic [AppDigestW-1:0] digest_share1; + // Error is valid when done is high. If any error occurs during KDF, KMAC + // returns the garbage digest data with error. The KeyMgr discards the + // digest and may re-initiate the process. + logic error; + } app_rsp_t; + + parameter app_req_t APP_REQ_DEFAULT = '{ + valid: 1'b 0, + data: '0, + strb: '0, + last: 1'b 0 + }; + parameter app_rsp_t APP_RSP_DEFAULT = '{ + ready: 1'b1, + done: 1'b1, + digest_share0: AppDigestW'(32'hDEADBEEF), + digest_share1: AppDigestW'(32'hFACEBEEF), + error: 1'b1 + }; + + + //////////////////// + // Error Handling // + //////////////////// + + // Error structure is same to the SHA3 one. The codes do not overlap. + typedef enum logic [7:0] { + ErrNone = 8'h 00, + + // ErrSha3SwControl occurs when software sent wrong flow signal. + // e.g) Sw set `process_i` without `start_i`. The state machine ignores + // the signal and report through the error FIFO. + //ErrSha3SwControl = 8'h 80 + + // ErrKeyNotValid: KeyMgr interface raises an error if the secret key is + // not valid when KeyMgr initiates KDF. + ErrKeyNotValid = 8'h 01, + + // ErrSwPushMsgFifo: Sw writes data into Msg FIFO abruptly. + // This error occurs in below scenario: + // - Sw does not send "Start" command to KMAC then writes data into + // Msg FIFO + // - Sw writes data into Msg FIFO when KeyMgr is in operation + ErrSwPushedMsgFifo = 8'h 02, + + // ErrSwIssuedCmdInAppActive + // - Sw writes any command while AppIntf is in active. + ErrSwIssuedCmdInAppActive = 8'h 03, + + // ErrWaitTimerExpired + // Entropy Wait timer expired. Something wrong on EDN i/f + ErrWaitTimerExpired = 8'h 04, + + // ErrIncorrectEntropyMode + // Incorrect Entropy mode when entropy is ready + ErrIncorrectEntropyMode = 8'h 05, + + // ErrUnexpectedModeStrength + ErrUnexpectedModeStrength = 8'h 06, + + // ErrIncorrectFunctionName "KMAC" + ErrIncorrectFunctionName = 8'h 07, + + // ErrSwCmdSequence + ErrSwCmdSequence = 8'h 08, + + // ErrSwHashingWithoutEntropyReady + // - Sw issues KMAC op without Entropy setting. + ErrSwHashingWithoutEntropyReady = 8'h 09, + + // Error due to lc_escalation_en_i or fatal fault + ErrFatalError = 8'h C1, + + // Error due to the counter integrity check failure inside MsgFifo.Packer + ErrPackerIntegrity = 8'h C2, + + // Error due to the counter integrity check failure inside MsgFifo.Fifo + ErrMsgFifoIntegrity = 8'h C3 + } err_code_e; + + typedef struct packed { + logic valid; + err_code_e code; // Type of error + logic [23:0] info; // Additional Debug info + } err_t; + parameter int unsigned ErrInfoW = 24 ; // err_t::info + + typedef struct packed { + logic [AppDigestW-1:0] digest_share0; + logic [AppDigestW-1:0] digest_share1; + } rsp_digest_t; + /////////////////////// + // Library Functions // + /////////////////////// + + // Endian conversion functions (32-bit, 64-bit) + function automatic logic [31:0] conv_endian32( input logic [31:0] v, input logic swap); + logic [31:0] conv_data; + conv_data = {<<8{v}}; + conv_endian32 = (swap) ? conv_data : v ; + endfunction : conv_endian32 + +endpackage : kmac_pkg diff --git a/designs/Caliptra/src/caliptra-rtl/kmac_reg_pkg.sv b/designs/Caliptra/src/caliptra-rtl/kmac_reg_pkg.sv new file mode 100644 index 0000000..e373fd6 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/kmac_reg_pkg.sv @@ -0,0 +1,277 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Register Package auto-generated by `reggen` containing data structure + +package kmac_reg_pkg; + + // Param list + parameter int NumWordsKey = 16; + parameter int NumWordsPrefix = 11; + parameter int NumEntriesMsgFifo = 10; + parameter int NumBytesMsgFifoEntry = 8; + parameter int unsigned HashCntW = 10; + parameter int NumSeedsEntropy = 6; + parameter int NumAlerts = 2; + + // Address widths within the block + parameter int BlockAw = 12; + + // Number of registers for every interface + parameter int NumRegs = 20; + + //////////////////////////// + // Typedefs for registers // + //////////////////////////// + + typedef struct packed { + struct packed { + logic q; + } kmac_err; + struct packed { + logic q; + } fifo_empty; + struct packed { + logic q; + } kmac_done; + } kmac_reg2hw_intr_state_reg_t; + + typedef struct packed { + struct packed { + logic q; + } kmac_err; + struct packed { + logic q; + } fifo_empty; + struct packed { + logic q; + } kmac_done; + } kmac_reg2hw_intr_enable_reg_t; + + typedef struct packed { + struct packed { + logic q; + logic qe; + } kmac_err; + struct packed { + logic q; + logic qe; + } fifo_empty; + struct packed { + logic q; + logic qe; + } kmac_done; + } kmac_reg2hw_intr_test_reg_t; + + typedef struct packed { + struct packed { + logic q; + logic qe; + } fatal_fault_err; + struct packed { + logic q; + logic qe; + } recov_operation_err; + } kmac_reg2hw_alert_test_reg_t; + + typedef struct packed { + struct packed { + logic q; + logic qe; + } state_endianness; + struct packed { + logic q; + logic qe; + } msg_endianness; + struct packed { + logic [1:0] q; + logic qe; + } mode; + struct packed { + logic [2:0] q; + logic qe; + } kstrength; + } kmac_reg2hw_cfg_shadowed_reg_t; + + typedef struct packed { + struct packed { + logic q; + logic qe; + } err_processed; + struct packed { + logic [5:0] q; + logic qe; + } cmd; + } kmac_reg2hw_cmd_reg_t; + + typedef struct packed { + logic [31:0] q; + } kmac_reg2hw_prefix_mreg_t; + + typedef struct packed { + struct packed { + logic d; + logic de; + } kmac_err; + struct packed { + logic d; + logic de; + } fifo_empty; + struct packed { + logic d; + logic de; + } kmac_done; + } kmac_hw2reg_intr_state_reg_t; + + typedef struct packed { + logic d; + } kmac_hw2reg_cfg_regwen_reg_t; + + typedef struct packed { + struct packed { + logic d; + } alert_recov_ctrl_update_err; + struct packed { + logic d; + } alert_fatal_fault; + struct packed { + logic d; + } fifo_full; + struct packed { + logic d; + } fifo_empty; + struct packed { + logic [4:0] d; + } fifo_depth; + struct packed { + logic d; + } sha3_squeeze; + struct packed { + logic d; + } sha3_absorb; + struct packed { + logic d; + } sha3_idle; + } kmac_hw2reg_status_reg_t; + + typedef struct packed { + logic [31:0] d; + logic de; + } kmac_hw2reg_err_code_reg_t; + + // Register -> HW type + typedef struct packed { + kmac_reg2hw_intr_state_reg_t intr_state; // [387:385] + kmac_reg2hw_intr_enable_reg_t intr_enable; // [384:382] + kmac_reg2hw_intr_test_reg_t intr_test; // [381:376] + kmac_reg2hw_alert_test_reg_t alert_test; // [375:372] + kmac_reg2hw_cfg_shadowed_reg_t cfg_shadowed; // [371:361] + kmac_reg2hw_cmd_reg_t cmd; // [360:352] + kmac_reg2hw_prefix_mreg_t [10:0] prefix; // [351:0] + } kmac_reg2hw_t; + + // HW -> register type + typedef struct packed { + kmac_hw2reg_intr_state_reg_t intr_state; // [51:46] + kmac_hw2reg_cfg_regwen_reg_t cfg_regwen; // [45:45] + kmac_hw2reg_status_reg_t status; // [44:33] + kmac_hw2reg_err_code_reg_t err_code; // [32:0] + } kmac_hw2reg_t; + + // Register offsets + parameter logic [BlockAw-1:0] KMAC_INTR_STATE_OFFSET = 12'h 0; + parameter logic [BlockAw-1:0] KMAC_INTR_ENABLE_OFFSET = 12'h 4; + parameter logic [BlockAw-1:0] KMAC_INTR_TEST_OFFSET = 12'h 8; + parameter logic [BlockAw-1:0] KMAC_ALERT_TEST_OFFSET = 12'h c; + parameter logic [BlockAw-1:0] KMAC_CFG_REGWEN_OFFSET = 12'h 10; + parameter logic [BlockAw-1:0] KMAC_CFG_SHADOWED_OFFSET = 12'h 14; + parameter logic [BlockAw-1:0] KMAC_CMD_OFFSET = 12'h 18; + parameter logic [BlockAw-1:0] KMAC_STATUS_OFFSET = 12'h 1c; + parameter logic [BlockAw-1:0] KMAC_PREFIX_0_OFFSET = 12'h 20; + parameter logic [BlockAw-1:0] KMAC_PREFIX_1_OFFSET = 12'h 24; + parameter logic [BlockAw-1:0] KMAC_PREFIX_2_OFFSET = 12'h 28; + parameter logic [BlockAw-1:0] KMAC_PREFIX_3_OFFSET = 12'h 2c; + parameter logic [BlockAw-1:0] KMAC_PREFIX_4_OFFSET = 12'h 30; + parameter logic [BlockAw-1:0] KMAC_PREFIX_5_OFFSET = 12'h 34; + parameter logic [BlockAw-1:0] KMAC_PREFIX_6_OFFSET = 12'h 38; + parameter logic [BlockAw-1:0] KMAC_PREFIX_7_OFFSET = 12'h 3c; + parameter logic [BlockAw-1:0] KMAC_PREFIX_8_OFFSET = 12'h 40; + parameter logic [BlockAw-1:0] KMAC_PREFIX_9_OFFSET = 12'h 44; + parameter logic [BlockAw-1:0] KMAC_PREFIX_10_OFFSET = 12'h 48; + parameter logic [BlockAw-1:0] KMAC_ERR_CODE_OFFSET = 12'h 4c; + + // Reset values for hwext registers and their fields + parameter logic [2:0] KMAC_INTR_TEST_RESVAL = 3'h 0; + parameter logic [0:0] KMAC_INTR_TEST_KMAC_DONE_RESVAL = 1'h 0; + parameter logic [0:0] KMAC_INTR_TEST_FIFO_EMPTY_RESVAL = 1'h 0; + parameter logic [0:0] KMAC_INTR_TEST_KMAC_ERR_RESVAL = 1'h 0; + parameter logic [1:0] KMAC_ALERT_TEST_RESVAL = 2'h 0; + parameter logic [0:0] KMAC_ALERT_TEST_RECOV_OPERATION_ERR_RESVAL = 1'h 0; + parameter logic [0:0] KMAC_ALERT_TEST_FATAL_FAULT_ERR_RESVAL = 1'h 0; + parameter logic [0:0] KMAC_CFG_REGWEN_RESVAL = 1'h 1; + parameter logic [0:0] KMAC_CFG_REGWEN_EN_RESVAL = 1'h 1; + parameter logic [10:0] KMAC_CMD_RESVAL = 11'h 0; + parameter logic [17:0] KMAC_STATUS_RESVAL = 18'h 4001; + parameter logic [0:0] KMAC_STATUS_SHA3_IDLE_RESVAL = 1'h 1; + parameter logic [0:0] KMAC_STATUS_FIFO_EMPTY_RESVAL = 1'h 1; + parameter logic [0:0] KMAC_STATUS_ALERT_FATAL_FAULT_RESVAL = 1'h 0; + parameter logic [0:0] KMAC_STATUS_ALERT_RECOV_CTRL_UPDATE_ERR_RESVAL = 1'h 0; + + // Window parameters + parameter logic [BlockAw-1:0] KMAC_STATE_OFFSET = 12'h 400; + parameter int unsigned KMAC_STATE_SIZE = 'h 200; + parameter int unsigned KMAC_STATE_IDX = 0; + parameter logic [BlockAw-1:0] KMAC_MSG_FIFO_OFFSET = 12'h 800; + parameter int unsigned KMAC_MSG_FIFO_SIZE = 'h 800; + parameter int unsigned KMAC_MSG_FIFO_IDX = 1; + + // Register index + typedef enum logic [4:0] { + KMAC_INTR_STATE, + KMAC_INTR_ENABLE, + KMAC_INTR_TEST, + KMAC_ALERT_TEST, + KMAC_CFG_REGWEN, + KMAC_CFG_SHADOWED, + KMAC_CMD, + KMAC_STATUS, + KMAC_PREFIX_0, + KMAC_PREFIX_1, + KMAC_PREFIX_2, + KMAC_PREFIX_3, + KMAC_PREFIX_4, + KMAC_PREFIX_5, + KMAC_PREFIX_6, + KMAC_PREFIX_7, + KMAC_PREFIX_8, + KMAC_PREFIX_9, + KMAC_PREFIX_10, + KMAC_ERR_CODE + } kmac_id_e; + + // Register width information to check illegal writes + parameter logic [3:0] KMAC_PERMIT [20] = '{ + 4'b 0001, // index[ 0] KMAC_INTR_STATE + 4'b 0001, // index[ 1] KMAC_INTR_ENABLE + 4'b 0001, // index[ 2] KMAC_INTR_TEST + 4'b 0001, // index[ 3] KMAC_ALERT_TEST + 4'b 0001, // index[ 4] KMAC_CFG_REGWEN + 4'b 0011, // index[ 5] KMAC_CFG_SHADOWED + 4'b 0011, // index[ 6] KMAC_CMD + 4'b 0111, // index[ 7] KMAC_STATUS + 4'b 1111, // index[ 8] KMAC_PREFIX_0 + 4'b 1111, // index[ 9] KMAC_PREFIX_1 + 4'b 1111, // index[10] KMAC_PREFIX_2 + 4'b 1111, // index[11] KMAC_PREFIX_3 + 4'b 1111, // index[12] KMAC_PREFIX_4 + 4'b 1111, // index[13] KMAC_PREFIX_5 + 4'b 1111, // index[14] KMAC_PREFIX_6 + 4'b 1111, // index[15] KMAC_PREFIX_7 + 4'b 1111, // index[16] KMAC_PREFIX_8 + 4'b 1111, // index[17] KMAC_PREFIX_9 + 4'b 1111, // index[18] KMAC_PREFIX_10 + 4'b 1111 // index[19] KMAC_ERR_CODE + }; + +endpackage diff --git a/designs/Caliptra/src/caliptra-rtl/kmac_reg_top.sv b/designs/Caliptra/src/caliptra-rtl/kmac_reg_top.sv new file mode 100644 index 0000000..c2d31b6 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/kmac_reg_top.sv @@ -0,0 +1,1564 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Register Top module auto-generated by `reggen` + +`include "caliptra_prim_assert.sv" + +module kmac_reg_top ( + input clk_i, + input rst_ni, + input rst_shadowed_ni, + input caliptra_tlul_pkg::tl_h2d_t tl_i, + output caliptra_tlul_pkg::tl_d2h_t tl_o, + + // Output port for window + output caliptra_tlul_pkg::tl_h2d_t tl_win_o [2], + input caliptra_tlul_pkg::tl_d2h_t tl_win_i [2], + + // To HW + output kmac_reg_pkg::kmac_reg2hw_t reg2hw, // Write + input kmac_reg_pkg::kmac_hw2reg_t hw2reg, // Read + + output logic shadowed_storage_err_o, + output logic shadowed_update_err_o, + + // Integrity check errors + output logic intg_err_o +); + + import kmac_reg_pkg::* ; + + localparam int AW = 12; + localparam int DW = 32; + localparam int DBW = DW/8; // Byte Width + + // register signals + logic reg_we; + logic reg_re; + logic [AW-1:0] reg_addr; + logic [DW-1:0] reg_wdata; + logic [DBW-1:0] reg_be; + logic [DW-1:0] reg_rdata; + logic reg_error; + + logic addrmiss, wr_err; + + logic [DW-1:0] reg_rdata_next; + logic reg_busy; + + caliptra_tlul_pkg::tl_h2d_t tl_reg_h2d; + caliptra_tlul_pkg::tl_d2h_t tl_reg_d2h; + + + // incoming payload check + logic intg_err; + caliptra_tlul_cmd_intg_chk u_chk ( + .tl_i(tl_i), + .err_o(intg_err) + ); + + // also check for spurious write enables + logic reg_we_err; + logic [19:0] reg_we_check; + caliptra_prim_reg_we_check #( + .OneHotWidth(20) + ) u_caliptra_prim_reg_we_check ( + .clk_i(clk_i), + .rst_ni(rst_ni), + .oh_i (reg_we_check), + .en_i (reg_we && !addrmiss), + .err_o (reg_we_err) + ); + + logic err_q; + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + err_q <= '0; + end else if (intg_err || reg_we_err) begin + err_q <= 1'b1; + end + end + + // integrity error output is permanent and should be used for alert generation + // register errors are transactional + assign intg_err_o = err_q | intg_err | reg_we_err; + + // outgoing integrity generation + caliptra_tlul_pkg::tl_d2h_t tl_o_pre; + caliptra_tlul_rsp_intg_gen #( + .EnableRspIntgGen(1), + .EnableDataIntgGen(1) + ) u_rsp_intg_gen ( + .tl_i(tl_o_pre), + .tl_o(tl_o) + ); + + caliptra_tlul_pkg::tl_h2d_t tl_socket_h2d [3]; + caliptra_tlul_pkg::tl_d2h_t tl_socket_d2h [3]; + + logic [1:0] reg_steer; + + // socket_1n connection + assign tl_reg_h2d = tl_socket_h2d[2]; + assign tl_socket_d2h[2] = tl_reg_d2h; + + assign tl_win_o[0] = tl_socket_h2d[0]; + assign tl_socket_d2h[0] = tl_win_i[0]; + assign tl_win_o[1] = tl_socket_h2d[1]; + assign tl_socket_d2h[1] = tl_win_i[1]; + + // Create Socket_1n + caliptra_tlul_socket_1n #( + .N (3), + .HReqPass (1'b1), + .HRspPass (1'b1), + .DReqPass ({3{1'b1}}), + .DRspPass ({3{1'b1}}), + .HReqDepth (4'h0), + .HRspDepth (4'h0), + .DReqDepth ({3{4'h0}}), + .DRspDepth ({3{4'h0}}), + .ExplicitErrs (1'b0) + ) u_socket ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .tl_h_i (tl_i), + .tl_h_o (tl_o_pre), + .tl_d_o (tl_socket_h2d), + .tl_d_i (tl_socket_d2h), + .dev_select_i (reg_steer) + ); + + // Create steering logic + always_comb begin + reg_steer = + tl_i.a_address[AW-1:0] inside {[1024:1535]} ? 2'd0 : + tl_i.a_address[AW-1:0] inside {[2048:4095]} ? 2'd1 : + // Default set to register + 2'd2; + + // Override this in case of an integrity error + if (intg_err) begin + reg_steer = 2'd2; + end + end + + caliptra_tlul_adapter_reg #( + .RegAw(AW), + .RegDw(DW), + .EnableDataIntgGen(0) + ) u_reg_if ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + .tl_i (tl_reg_h2d), + .tl_o (tl_reg_d2h), + + .en_ifetch_i(caliptra_prim_mubi_pkg::MuBi4False), + .intg_error_o(), + + .we_o (reg_we), + .re_o (reg_re), + .addr_o (reg_addr), + .wdata_o (reg_wdata), + .be_o (reg_be), + .busy_i (reg_busy), + .rdata_i (reg_rdata), + .error_i (reg_error) + ); + + // cdc oversampling signals + + assign reg_rdata = reg_rdata_next ; + assign reg_error = addrmiss | wr_err | intg_err; + + // Define SW related signals + // Format: __{wd|we|qs} + // or _{wd|we|qs} if field == 1 or 0 + logic intr_state_we; + logic intr_state_kmac_done_qs; + logic intr_state_kmac_done_wd; + logic intr_state_fifo_empty_qs; + logic intr_state_kmac_err_qs; + logic intr_state_kmac_err_wd; + logic intr_enable_we; + logic intr_enable_kmac_done_qs; + logic intr_enable_kmac_done_wd; + logic intr_enable_fifo_empty_qs; + logic intr_enable_fifo_empty_wd; + logic intr_enable_kmac_err_qs; + logic intr_enable_kmac_err_wd; + logic intr_test_we; + logic intr_test_kmac_done_wd; + logic intr_test_fifo_empty_wd; + logic intr_test_kmac_err_wd; + logic alert_test_we; + logic alert_test_recov_operation_err_wd; + logic alert_test_fatal_fault_err_wd; + logic cfg_regwen_re; + logic cfg_regwen_qs; + logic cfg_shadowed_re; + logic cfg_shadowed_we; + logic [2:0] cfg_shadowed_kstrength_qs; + logic [2:0] cfg_shadowed_kstrength_wd; + logic cfg_shadowed_kstrength_storage_err; + logic cfg_shadowed_kstrength_update_err; + logic [1:0] cfg_shadowed_mode_qs; + logic [1:0] cfg_shadowed_mode_wd; + logic cfg_shadowed_mode_storage_err; + logic cfg_shadowed_mode_update_err; + logic cfg_shadowed_msg_endianness_qs; + logic cfg_shadowed_msg_endianness_wd; + logic cfg_shadowed_msg_endianness_storage_err; + logic cfg_shadowed_msg_endianness_update_err; + logic cfg_shadowed_state_endianness_qs; + logic cfg_shadowed_state_endianness_wd; + logic cfg_shadowed_state_endianness_storage_err; + logic cfg_shadowed_state_endianness_update_err; + logic cmd_we; + logic [5:0] cmd_cmd_wd; + logic cmd_err_processed_wd; + logic status_re; + logic status_sha3_idle_qs; + logic status_sha3_absorb_qs; + logic status_sha3_squeeze_qs; + logic [4:0] status_fifo_depth_qs; + logic status_fifo_empty_qs; + logic status_fifo_full_qs; + logic status_alert_fatal_fault_qs; + logic status_alert_recov_ctrl_update_err_qs; + logic prefix_0_we; + logic [31:0] prefix_0_qs; + logic [31:0] prefix_0_wd; + logic prefix_1_we; + logic [31:0] prefix_1_qs; + logic [31:0] prefix_1_wd; + logic prefix_2_we; + logic [31:0] prefix_2_qs; + logic [31:0] prefix_2_wd; + logic prefix_3_we; + logic [31:0] prefix_3_qs; + logic [31:0] prefix_3_wd; + logic prefix_4_we; + logic [31:0] prefix_4_qs; + logic [31:0] prefix_4_wd; + logic prefix_5_we; + logic [31:0] prefix_5_qs; + logic [31:0] prefix_5_wd; + logic prefix_6_we; + logic [31:0] prefix_6_qs; + logic [31:0] prefix_6_wd; + logic prefix_7_we; + logic [31:0] prefix_7_qs; + logic [31:0] prefix_7_wd; + logic prefix_8_we; + logic [31:0] prefix_8_qs; + logic [31:0] prefix_8_wd; + logic prefix_9_we; + logic [31:0] prefix_9_qs; + logic [31:0] prefix_9_wd; + logic prefix_10_we; + logic [31:0] prefix_10_qs; + logic [31:0] prefix_10_wd; + logic [31:0] err_code_qs; + + // Register instances + // R[intr_state]: V(False) + // F[kmac_done]: 0:0 + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessW1C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_intr_state_kmac_done ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (intr_state_we), + .wd (intr_state_kmac_done_wd), + + // from internal hardware + .de (hw2reg.intr_state.kmac_done.de), + .d (hw2reg.intr_state.kmac_done.d), + + // to internal hardware + .qe (), + .q (reg2hw.intr_state.kmac_done.q), + .ds (), + + // to register interface (read) + .qs (intr_state_kmac_done_qs) + ); + + // F[fifo_empty]: 1:1 + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_intr_state_fifo_empty ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.intr_state.fifo_empty.de), + .d (hw2reg.intr_state.fifo_empty.d), + + // to internal hardware + .qe (), + .q (reg2hw.intr_state.fifo_empty.q), + .ds (), + + // to register interface (read) + .qs (intr_state_fifo_empty_qs) + ); + + // F[kmac_err]: 2:2 + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessW1C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_intr_state_kmac_err ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (intr_state_we), + .wd (intr_state_kmac_err_wd), + + // from internal hardware + .de (hw2reg.intr_state.kmac_err.de), + .d (hw2reg.intr_state.kmac_err.d), + + // to internal hardware + .qe (), + .q (reg2hw.intr_state.kmac_err.q), + .ds (), + + // to register interface (read) + .qs (intr_state_kmac_err_qs) + ); + + + // R[intr_enable]: V(False) + // F[kmac_done]: 0:0 + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_intr_enable_kmac_done ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (intr_enable_we), + .wd (intr_enable_kmac_done_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.intr_enable.kmac_done.q), + .ds (), + + // to register interface (read) + .qs (intr_enable_kmac_done_qs) + ); + + // F[fifo_empty]: 1:1 + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_intr_enable_fifo_empty ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (intr_enable_we), + .wd (intr_enable_fifo_empty_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.intr_enable.fifo_empty.q), + .ds (), + + // to register interface (read) + .qs (intr_enable_fifo_empty_qs) + ); + + // F[kmac_err]: 2:2 + caliptra_prim_subreg #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_intr_enable_kmac_err ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (intr_enable_we), + .wd (intr_enable_kmac_err_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.intr_enable.kmac_err.q), + .ds (), + + // to register interface (read) + .qs (intr_enable_kmac_err_qs) + ); + + + // R[intr_test]: V(True) + logic intr_test_qe; + logic [2:0] intr_test_flds_we; + assign intr_test_qe = &intr_test_flds_we; + // F[kmac_done]: 0:0 + caliptra_prim_subreg_ext #( + .DW (1) + ) u_intr_test_kmac_done ( + .re (1'b0), + .we (intr_test_we), + .wd (intr_test_kmac_done_wd), + .d ('0), + .qre (), + .qe (intr_test_flds_we[0]), + .q (reg2hw.intr_test.kmac_done.q), + .ds (), + .qs () + ); + assign reg2hw.intr_test.kmac_done.qe = intr_test_qe; + + // F[fifo_empty]: 1:1 + caliptra_prim_subreg_ext #( + .DW (1) + ) u_intr_test_fifo_empty ( + .re (1'b0), + .we (intr_test_we), + .wd (intr_test_fifo_empty_wd), + .d ('0), + .qre (), + .qe (intr_test_flds_we[1]), + .q (reg2hw.intr_test.fifo_empty.q), + .ds (), + .qs () + ); + assign reg2hw.intr_test.fifo_empty.qe = intr_test_qe; + + // F[kmac_err]: 2:2 + caliptra_prim_subreg_ext #( + .DW (1) + ) u_intr_test_kmac_err ( + .re (1'b0), + .we (intr_test_we), + .wd (intr_test_kmac_err_wd), + .d ('0), + .qre (), + .qe (intr_test_flds_we[2]), + .q (reg2hw.intr_test.kmac_err.q), + .ds (), + .qs () + ); + assign reg2hw.intr_test.kmac_err.qe = intr_test_qe; + + + // R[alert_test]: V(True) + logic alert_test_qe; + logic [1:0] alert_test_flds_we; + assign alert_test_qe = &alert_test_flds_we; + // F[recov_operation_err]: 0:0 + caliptra_prim_subreg_ext #( + .DW (1) + ) u_alert_test_recov_operation_err ( + .re (1'b0), + .we (alert_test_we), + .wd (alert_test_recov_operation_err_wd), + .d ('0), + .qre (), + .qe (alert_test_flds_we[0]), + .q (reg2hw.alert_test.recov_operation_err.q), + .ds (), + .qs () + ); + assign reg2hw.alert_test.recov_operation_err.qe = alert_test_qe; + + // F[fatal_fault_err]: 1:1 + caliptra_prim_subreg_ext #( + .DW (1) + ) u_alert_test_fatal_fault_err ( + .re (1'b0), + .we (alert_test_we), + .wd (alert_test_fatal_fault_err_wd), + .d ('0), + .qre (), + .qe (alert_test_flds_we[1]), + .q (reg2hw.alert_test.fatal_fault_err.q), + .ds (), + .qs () + ); + assign reg2hw.alert_test.fatal_fault_err.qe = alert_test_qe; + + + // R[cfg_regwen]: V(True) + caliptra_prim_subreg_ext #( + .DW (1) + ) u_cfg_regwen ( + .re (cfg_regwen_re), + .we (1'b0), + .wd ('0), + .d (hw2reg.cfg_regwen.d), + .qre (), + .qe (), + .q (), + .ds (), + .qs (cfg_regwen_qs) + ); + + + // R[cfg_shadowed]: V(False) + logic cfg_shadowed_qe; + logic [3:0] cfg_shadowed_flds_we; + caliptra_prim_flop #( + .Width(1), + .ResetValue(0) + ) u_cfg_shadowed0_qe ( + .clk_i(clk_i), + .rst_ni(rst_ni), + .d_i(&cfg_shadowed_flds_we), + .q_o(cfg_shadowed_qe) + ); + // Create REGWEN-gated WE signal + logic cfg_shadowed_gated_we; + assign cfg_shadowed_gated_we = cfg_shadowed_we & cfg_regwen_qs; + // F[kstrength]: 3:1 + caliptra_prim_subreg_shadow #( + .DW (3), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRW), + .RESVAL (3'h0), + .Mubi (1'b0) + ) u_cfg_shadowed_kstrength ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .rst_shadowed_ni (rst_shadowed_ni), + + // from register interface + .re (cfg_shadowed_re), + .we (cfg_shadowed_gated_we), + .wd (cfg_shadowed_kstrength_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (cfg_shadowed_flds_we[0]), + .q (reg2hw.cfg_shadowed.kstrength.q), + .ds (), + + // to register interface (read) + .qs (cfg_shadowed_kstrength_qs), + + // Shadow register phase. Relevant for hwext only. + .phase (), + + // Shadow register error conditions + .err_update (cfg_shadowed_kstrength_update_err), + .err_storage (cfg_shadowed_kstrength_storage_err) + ); + assign reg2hw.cfg_shadowed.kstrength.qe = cfg_shadowed_qe; + + // F[mode]: 5:4 + caliptra_prim_subreg_shadow #( + .DW (2), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h0), + .Mubi (1'b0) + ) u_cfg_shadowed_mode ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .rst_shadowed_ni (rst_shadowed_ni), + + // from register interface + .re (cfg_shadowed_re), + .we (cfg_shadowed_gated_we), + .wd (cfg_shadowed_mode_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (cfg_shadowed_flds_we[1]), + .q (reg2hw.cfg_shadowed.mode.q), + .ds (), + + // to register interface (read) + .qs (cfg_shadowed_mode_qs), + + // Shadow register phase. Relevant for hwext only. + .phase (), + + // Shadow register error conditions + .err_update (cfg_shadowed_mode_update_err), + .err_storage (cfg_shadowed_mode_storage_err) + ); + assign reg2hw.cfg_shadowed.mode.qe = cfg_shadowed_qe; + + // F[msg_endianness]: 8:8 + caliptra_prim_subreg_shadow #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_cfg_shadowed_msg_endianness ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .rst_shadowed_ni (rst_shadowed_ni), + + // from register interface + .re (cfg_shadowed_re), + .we (cfg_shadowed_gated_we), + .wd (cfg_shadowed_msg_endianness_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (cfg_shadowed_flds_we[2]), + .q (reg2hw.cfg_shadowed.msg_endianness.q), + .ds (), + + // to register interface (read) + .qs (cfg_shadowed_msg_endianness_qs), + + // Shadow register phase. Relevant for hwext only. + .phase (), + + // Shadow register error conditions + .err_update (cfg_shadowed_msg_endianness_update_err), + .err_storage (cfg_shadowed_msg_endianness_storage_err) + ); + assign reg2hw.cfg_shadowed.msg_endianness.qe = cfg_shadowed_qe; + + // F[state_endianness]: 9:9 + caliptra_prim_subreg_shadow #( + .DW (1), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_cfg_shadowed_state_endianness ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .rst_shadowed_ni (rst_shadowed_ni), + + // from register interface + .re (cfg_shadowed_re), + .we (cfg_shadowed_gated_we), + .wd (cfg_shadowed_state_endianness_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (cfg_shadowed_flds_we[3]), + .q (reg2hw.cfg_shadowed.state_endianness.q), + .ds (), + + // to register interface (read) + .qs (cfg_shadowed_state_endianness_qs), + + // Shadow register phase. Relevant for hwext only. + .phase (), + + // Shadow register error conditions + .err_update (cfg_shadowed_state_endianness_update_err), + .err_storage (cfg_shadowed_state_endianness_storage_err) + ); + assign reg2hw.cfg_shadowed.state_endianness.qe = cfg_shadowed_qe; + + + // R[cmd]: V(True) + logic cmd_qe; + logic [1:0] cmd_flds_we; + assign cmd_qe = &cmd_flds_we; + // F[cmd]: 5:0 + caliptra_prim_subreg_ext #( + .DW (6) + ) u_cmd_cmd ( + .re (1'b0), + .we (cmd_we), + .wd (cmd_cmd_wd), + .d ('0), + .qre (), + .qe (cmd_flds_we[0]), + .q (reg2hw.cmd.cmd.q), + .ds (), + .qs () + ); + assign reg2hw.cmd.cmd.qe = cmd_qe; + + // F[err_processed]: 10:10 + caliptra_prim_subreg_ext #( + .DW (1) + ) u_cmd_err_processed ( + .re (1'b0), + .we (cmd_we), + .wd (cmd_err_processed_wd), + .d ('0), + .qre (), + .qe (cmd_flds_we[1]), + .q (reg2hw.cmd.err_processed.q), + .ds (), + .qs () + ); + assign reg2hw.cmd.err_processed.qe = cmd_qe; + + + // R[status]: V(True) + // F[sha3_idle]: 0:0 + caliptra_prim_subreg_ext #( + .DW (1) + ) u_status_sha3_idle ( + .re (status_re), + .we (1'b0), + .wd ('0), + .d (hw2reg.status.sha3_idle.d), + .qre (), + .qe (), + .q (), + .ds (), + .qs (status_sha3_idle_qs) + ); + + // F[sha3_absorb]: 1:1 + caliptra_prim_subreg_ext #( + .DW (1) + ) u_status_sha3_absorb ( + .re (status_re), + .we (1'b0), + .wd ('0), + .d (hw2reg.status.sha3_absorb.d), + .qre (), + .qe (), + .q (), + .ds (), + .qs (status_sha3_absorb_qs) + ); + + // F[sha3_squeeze]: 2:2 + caliptra_prim_subreg_ext #( + .DW (1) + ) u_status_sha3_squeeze ( + .re (status_re), + .we (1'b0), + .wd ('0), + .d (hw2reg.status.sha3_squeeze.d), + .qre (), + .qe (), + .q (), + .ds (), + .qs (status_sha3_squeeze_qs) + ); + + // F[fifo_depth]: 12:8 + caliptra_prim_subreg_ext #( + .DW (5) + ) u_status_fifo_depth ( + .re (status_re), + .we (1'b0), + .wd ('0), + .d (hw2reg.status.fifo_depth.d), + .qre (), + .qe (), + .q (), + .ds (), + .qs (status_fifo_depth_qs) + ); + + // F[fifo_empty]: 14:14 + caliptra_prim_subreg_ext #( + .DW (1) + ) u_status_fifo_empty ( + .re (status_re), + .we (1'b0), + .wd ('0), + .d (hw2reg.status.fifo_empty.d), + .qre (), + .qe (), + .q (), + .ds (), + .qs (status_fifo_empty_qs) + ); + + // F[fifo_full]: 15:15 + caliptra_prim_subreg_ext #( + .DW (1) + ) u_status_fifo_full ( + .re (status_re), + .we (1'b0), + .wd ('0), + .d (hw2reg.status.fifo_full.d), + .qre (), + .qe (), + .q (), + .ds (), + .qs (status_fifo_full_qs) + ); + + // F[alert_fatal_fault]: 16:16 + caliptra_prim_subreg_ext #( + .DW (1) + ) u_status_alert_fatal_fault ( + .re (status_re), + .we (1'b0), + .wd ('0), + .d (hw2reg.status.alert_fatal_fault.d), + .qre (), + .qe (), + .q (), + .ds (), + .qs (status_alert_fatal_fault_qs) + ); + + // F[alert_recov_ctrl_update_err]: 17:17 + caliptra_prim_subreg_ext #( + .DW (1) + ) u_status_alert_recov_ctrl_update_err ( + .re (status_re), + .we (1'b0), + .wd ('0), + .d (hw2reg.status.alert_recov_ctrl_update_err.d), + .qre (), + .qe (), + .q (), + .ds (), + .qs (status_alert_recov_ctrl_update_err_qs) + ); + + + // Subregister 0 of Multireg prefix + // R[prefix_0]: V(False) + // Create REGWEN-gated WE signal + logic prefix_0_gated_we; + assign prefix_0_gated_we = prefix_0_we & cfg_regwen_qs; + caliptra_prim_subreg #( + .DW (32), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRW), + .RESVAL (32'h0), + .Mubi (1'b0) + ) u_prefix_0 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (prefix_0_gated_we), + .wd (prefix_0_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.prefix[0].q), + .ds (), + + // to register interface (read) + .qs (prefix_0_qs) + ); + + + // Subregister 1 of Multireg prefix + // R[prefix_1]: V(False) + // Create REGWEN-gated WE signal + logic prefix_1_gated_we; + assign prefix_1_gated_we = prefix_1_we & cfg_regwen_qs; + caliptra_prim_subreg #( + .DW (32), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRW), + .RESVAL (32'h0), + .Mubi (1'b0) + ) u_prefix_1 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (prefix_1_gated_we), + .wd (prefix_1_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.prefix[1].q), + .ds (), + + // to register interface (read) + .qs (prefix_1_qs) + ); + + + // Subregister 2 of Multireg prefix + // R[prefix_2]: V(False) + // Create REGWEN-gated WE signal + logic prefix_2_gated_we; + assign prefix_2_gated_we = prefix_2_we & cfg_regwen_qs; + caliptra_prim_subreg #( + .DW (32), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRW), + .RESVAL (32'h0), + .Mubi (1'b0) + ) u_prefix_2 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (prefix_2_gated_we), + .wd (prefix_2_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.prefix[2].q), + .ds (), + + // to register interface (read) + .qs (prefix_2_qs) + ); + + + // Subregister 3 of Multireg prefix + // R[prefix_3]: V(False) + // Create REGWEN-gated WE signal + logic prefix_3_gated_we; + assign prefix_3_gated_we = prefix_3_we & cfg_regwen_qs; + caliptra_prim_subreg #( + .DW (32), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRW), + .RESVAL (32'h0), + .Mubi (1'b0) + ) u_prefix_3 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (prefix_3_gated_we), + .wd (prefix_3_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.prefix[3].q), + .ds (), + + // to register interface (read) + .qs (prefix_3_qs) + ); + + + // Subregister 4 of Multireg prefix + // R[prefix_4]: V(False) + // Create REGWEN-gated WE signal + logic prefix_4_gated_we; + assign prefix_4_gated_we = prefix_4_we & cfg_regwen_qs; + caliptra_prim_subreg #( + .DW (32), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRW), + .RESVAL (32'h0), + .Mubi (1'b0) + ) u_prefix_4 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (prefix_4_gated_we), + .wd (prefix_4_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.prefix[4].q), + .ds (), + + // to register interface (read) + .qs (prefix_4_qs) + ); + + + // Subregister 5 of Multireg prefix + // R[prefix_5]: V(False) + // Create REGWEN-gated WE signal + logic prefix_5_gated_we; + assign prefix_5_gated_we = prefix_5_we & cfg_regwen_qs; + caliptra_prim_subreg #( + .DW (32), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRW), + .RESVAL (32'h0), + .Mubi (1'b0) + ) u_prefix_5 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (prefix_5_gated_we), + .wd (prefix_5_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.prefix[5].q), + .ds (), + + // to register interface (read) + .qs (prefix_5_qs) + ); + + + // Subregister 6 of Multireg prefix + // R[prefix_6]: V(False) + // Create REGWEN-gated WE signal + logic prefix_6_gated_we; + assign prefix_6_gated_we = prefix_6_we & cfg_regwen_qs; + caliptra_prim_subreg #( + .DW (32), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRW), + .RESVAL (32'h0), + .Mubi (1'b0) + ) u_prefix_6 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (prefix_6_gated_we), + .wd (prefix_6_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.prefix[6].q), + .ds (), + + // to register interface (read) + .qs (prefix_6_qs) + ); + + + // Subregister 7 of Multireg prefix + // R[prefix_7]: V(False) + // Create REGWEN-gated WE signal + logic prefix_7_gated_we; + assign prefix_7_gated_we = prefix_7_we & cfg_regwen_qs; + caliptra_prim_subreg #( + .DW (32), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRW), + .RESVAL (32'h0), + .Mubi (1'b0) + ) u_prefix_7 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (prefix_7_gated_we), + .wd (prefix_7_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.prefix[7].q), + .ds (), + + // to register interface (read) + .qs (prefix_7_qs) + ); + + + // Subregister 8 of Multireg prefix + // R[prefix_8]: V(False) + // Create REGWEN-gated WE signal + logic prefix_8_gated_we; + assign prefix_8_gated_we = prefix_8_we & cfg_regwen_qs; + caliptra_prim_subreg #( + .DW (32), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRW), + .RESVAL (32'h0), + .Mubi (1'b0) + ) u_prefix_8 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (prefix_8_gated_we), + .wd (prefix_8_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.prefix[8].q), + .ds (), + + // to register interface (read) + .qs (prefix_8_qs) + ); + + + // Subregister 9 of Multireg prefix + // R[prefix_9]: V(False) + // Create REGWEN-gated WE signal + logic prefix_9_gated_we; + assign prefix_9_gated_we = prefix_9_we & cfg_regwen_qs; + caliptra_prim_subreg #( + .DW (32), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRW), + .RESVAL (32'h0), + .Mubi (1'b0) + ) u_prefix_9 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (prefix_9_gated_we), + .wd (prefix_9_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.prefix[9].q), + .ds (), + + // to register interface (read) + .qs (prefix_9_qs) + ); + + + // Subregister 10 of Multireg prefix + // R[prefix_10]: V(False) + // Create REGWEN-gated WE signal + logic prefix_10_gated_we; + assign prefix_10_gated_we = prefix_10_we & cfg_regwen_qs; + caliptra_prim_subreg #( + .DW (32), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRW), + .RESVAL (32'h0), + .Mubi (1'b0) + ) u_prefix_10 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (prefix_10_gated_we), + .wd (prefix_10_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.prefix[10].q), + .ds (), + + // to register interface (read) + .qs (prefix_10_qs) + ); + + + // R[err_code]: V(False) + caliptra_prim_subreg #( + .DW (32), + .SwAccess(caliptra_prim_subreg_pkg::SwAccessRO), + .RESVAL (32'h0), + .Mubi (1'b0) + ) u_err_code ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.err_code.de), + .d (hw2reg.err_code.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (err_code_qs) + ); + + + + logic [19:0] addr_hit; + always_comb begin + addr_hit[ 0] = (reg_addr == KMAC_INTR_STATE_OFFSET); + addr_hit[ 1] = (reg_addr == KMAC_INTR_ENABLE_OFFSET); + addr_hit[ 2] = (reg_addr == KMAC_INTR_TEST_OFFSET); + addr_hit[ 3] = (reg_addr == KMAC_ALERT_TEST_OFFSET); + addr_hit[ 4] = (reg_addr == KMAC_CFG_REGWEN_OFFSET); + addr_hit[ 5] = (reg_addr == KMAC_CFG_SHADOWED_OFFSET); + addr_hit[ 6] = (reg_addr == KMAC_CMD_OFFSET); + addr_hit[ 7] = (reg_addr == KMAC_STATUS_OFFSET); + addr_hit[ 8] = (reg_addr == KMAC_PREFIX_0_OFFSET); + addr_hit[ 9] = (reg_addr == KMAC_PREFIX_1_OFFSET); + addr_hit[10] = (reg_addr == KMAC_PREFIX_2_OFFSET); + addr_hit[11] = (reg_addr == KMAC_PREFIX_3_OFFSET); + addr_hit[12] = (reg_addr == KMAC_PREFIX_4_OFFSET); + addr_hit[13] = (reg_addr == KMAC_PREFIX_5_OFFSET); + addr_hit[14] = (reg_addr == KMAC_PREFIX_6_OFFSET); + addr_hit[15] = (reg_addr == KMAC_PREFIX_7_OFFSET); + addr_hit[16] = (reg_addr == KMAC_PREFIX_8_OFFSET); + addr_hit[17] = (reg_addr == KMAC_PREFIX_9_OFFSET); + addr_hit[18] = (reg_addr == KMAC_PREFIX_10_OFFSET); + addr_hit[19] = (reg_addr == KMAC_ERR_CODE_OFFSET); + end + + assign addrmiss = (reg_re || reg_we) ? ~|addr_hit : 1'b0 ; + + // Check sub-word write is permitted + always_comb begin + wr_err = (reg_we & + ((addr_hit[ 0] & (|(KMAC_PERMIT[ 0] & ~reg_be))) | + (addr_hit[ 1] & (|(KMAC_PERMIT[ 1] & ~reg_be))) | + (addr_hit[ 2] & (|(KMAC_PERMIT[ 2] & ~reg_be))) | + (addr_hit[ 3] & (|(KMAC_PERMIT[ 3] & ~reg_be))) | + (addr_hit[ 4] & (|(KMAC_PERMIT[ 4] & ~reg_be))) | + (addr_hit[ 5] & (|(KMAC_PERMIT[ 5] & ~reg_be))) | + (addr_hit[ 6] & (|(KMAC_PERMIT[ 6] & ~reg_be))) | + (addr_hit[ 7] & (|(KMAC_PERMIT[ 7] & ~reg_be))) | + (addr_hit[ 8] & (|(KMAC_PERMIT[ 8] & ~reg_be))) | + (addr_hit[ 9] & (|(KMAC_PERMIT[ 9] & ~reg_be))) | + (addr_hit[10] & (|(KMAC_PERMIT[10] & ~reg_be))) | + (addr_hit[11] & (|(KMAC_PERMIT[11] & ~reg_be))) | + (addr_hit[12] & (|(KMAC_PERMIT[12] & ~reg_be))) | + (addr_hit[13] & (|(KMAC_PERMIT[13] & ~reg_be))) | + (addr_hit[14] & (|(KMAC_PERMIT[14] & ~reg_be))) | + (addr_hit[15] & (|(KMAC_PERMIT[15] & ~reg_be))) | + (addr_hit[16] & (|(KMAC_PERMIT[16] & ~reg_be))) | + (addr_hit[17] & (|(KMAC_PERMIT[17] & ~reg_be))) | + (addr_hit[18] & (|(KMAC_PERMIT[18] & ~reg_be))) | + (addr_hit[19] & (|(KMAC_PERMIT[19] & ~reg_be))))); + end + + // Generate write-enables + assign intr_state_we = addr_hit[0] & reg_we & !reg_error; + + assign intr_state_kmac_done_wd = reg_wdata[0]; + + assign intr_state_kmac_err_wd = reg_wdata[2]; + assign intr_enable_we = addr_hit[1] & reg_we & !reg_error; + + assign intr_enable_kmac_done_wd = reg_wdata[0]; + + assign intr_enable_fifo_empty_wd = reg_wdata[1]; + + assign intr_enable_kmac_err_wd = reg_wdata[2]; + assign intr_test_we = addr_hit[2] & reg_we & !reg_error; + + assign intr_test_kmac_done_wd = reg_wdata[0]; + + assign intr_test_fifo_empty_wd = reg_wdata[1]; + + assign intr_test_kmac_err_wd = reg_wdata[2]; + assign alert_test_we = addr_hit[3] & reg_we & !reg_error; + + assign alert_test_recov_operation_err_wd = reg_wdata[0]; + + assign alert_test_fatal_fault_err_wd = reg_wdata[1]; + assign cfg_regwen_re = addr_hit[4] & reg_re & !reg_error; + assign cfg_shadowed_re = addr_hit[5] & reg_re & !reg_error; + assign cfg_shadowed_we = addr_hit[5] & reg_we & !reg_error; + + assign cfg_shadowed_kstrength_wd = reg_wdata[3:1]; + + assign cfg_shadowed_mode_wd = reg_wdata[5:4]; + + assign cfg_shadowed_msg_endianness_wd = reg_wdata[8]; + + assign cfg_shadowed_state_endianness_wd = reg_wdata[9]; + assign cmd_we = addr_hit[6] & reg_we & !reg_error; + + assign cmd_cmd_wd = reg_wdata[5:0]; + + assign cmd_err_processed_wd = reg_wdata[10]; + assign status_re = addr_hit[7] & reg_re & !reg_error; + assign prefix_0_we = addr_hit[8] & reg_we & !reg_error; + + assign prefix_0_wd = reg_wdata[31:0]; + assign prefix_1_we = addr_hit[9] & reg_we & !reg_error; + + assign prefix_1_wd = reg_wdata[31:0]; + assign prefix_2_we = addr_hit[10] & reg_we & !reg_error; + + assign prefix_2_wd = reg_wdata[31:0]; + assign prefix_3_we = addr_hit[11] & reg_we & !reg_error; + + assign prefix_3_wd = reg_wdata[31:0]; + assign prefix_4_we = addr_hit[12] & reg_we & !reg_error; + + assign prefix_4_wd = reg_wdata[31:0]; + assign prefix_5_we = addr_hit[13] & reg_we & !reg_error; + + assign prefix_5_wd = reg_wdata[31:0]; + assign prefix_6_we = addr_hit[14] & reg_we & !reg_error; + + assign prefix_6_wd = reg_wdata[31:0]; + assign prefix_7_we = addr_hit[15] & reg_we & !reg_error; + + assign prefix_7_wd = reg_wdata[31:0]; + assign prefix_8_we = addr_hit[16] & reg_we & !reg_error; + + assign prefix_8_wd = reg_wdata[31:0]; + assign prefix_9_we = addr_hit[17] & reg_we & !reg_error; + + assign prefix_9_wd = reg_wdata[31:0]; + assign prefix_10_we = addr_hit[18] & reg_we & !reg_error; + + assign prefix_10_wd = reg_wdata[31:0]; + + // Assign write-enables to checker logic vector. + always_comb begin + reg_we_check[0] = intr_state_we; + reg_we_check[1] = intr_enable_we; + reg_we_check[2] = intr_test_we; + reg_we_check[3] = alert_test_we; + reg_we_check[4] = 1'b0; + reg_we_check[5] = cfg_shadowed_gated_we; + reg_we_check[6] = cmd_we; + reg_we_check[7] = 1'b0; + reg_we_check[8] = prefix_0_gated_we; + reg_we_check[9] = prefix_1_gated_we; + reg_we_check[10] = prefix_2_gated_we; + reg_we_check[11] = prefix_3_gated_we; + reg_we_check[12] = prefix_4_gated_we; + reg_we_check[13] = prefix_5_gated_we; + reg_we_check[14] = prefix_6_gated_we; + reg_we_check[15] = prefix_7_gated_we; + reg_we_check[16] = prefix_8_gated_we; + reg_we_check[17] = prefix_9_gated_we; + reg_we_check[18] = prefix_10_gated_we; + reg_we_check[19] = 1'b0; + end + + // Read data return + always_comb begin + reg_rdata_next = '0; + unique case (1'b1) + addr_hit[0]: begin + reg_rdata_next[0] = intr_state_kmac_done_qs; + reg_rdata_next[1] = intr_state_fifo_empty_qs; + reg_rdata_next[2] = intr_state_kmac_err_qs; + end + + addr_hit[1]: begin + reg_rdata_next[0] = intr_enable_kmac_done_qs; + reg_rdata_next[1] = intr_enable_fifo_empty_qs; + reg_rdata_next[2] = intr_enable_kmac_err_qs; + end + + addr_hit[2]: begin + reg_rdata_next[0] = '0; + reg_rdata_next[1] = '0; + reg_rdata_next[2] = '0; + end + + addr_hit[3]: begin + reg_rdata_next[0] = '0; + reg_rdata_next[1] = '0; + end + + addr_hit[4]: begin + reg_rdata_next[0] = cfg_regwen_qs; + end + + addr_hit[5]: begin + reg_rdata_next[3:1] = cfg_shadowed_kstrength_qs; + reg_rdata_next[5:4] = cfg_shadowed_mode_qs; + reg_rdata_next[8] = cfg_shadowed_msg_endianness_qs; + reg_rdata_next[9] = cfg_shadowed_state_endianness_qs; + end + + addr_hit[6]: begin + reg_rdata_next[5:0] = '0; + reg_rdata_next[10] = '0; + end + + addr_hit[7]: begin + reg_rdata_next[0] = status_sha3_idle_qs; + reg_rdata_next[1] = status_sha3_absorb_qs; + reg_rdata_next[2] = status_sha3_squeeze_qs; + reg_rdata_next[12:8] = status_fifo_depth_qs; + reg_rdata_next[14] = status_fifo_empty_qs; + reg_rdata_next[15] = status_fifo_full_qs; + reg_rdata_next[16] = status_alert_fatal_fault_qs; + reg_rdata_next[17] = status_alert_recov_ctrl_update_err_qs; + end + + addr_hit[8]: begin + reg_rdata_next[31:0] = prefix_0_qs; + end + + addr_hit[9]: begin + reg_rdata_next[31:0] = prefix_1_qs; + end + + addr_hit[10]: begin + reg_rdata_next[31:0] = prefix_2_qs; + end + + addr_hit[11]: begin + reg_rdata_next[31:0] = prefix_3_qs; + end + + addr_hit[12]: begin + reg_rdata_next[31:0] = prefix_4_qs; + end + + addr_hit[13]: begin + reg_rdata_next[31:0] = prefix_5_qs; + end + + addr_hit[14]: begin + reg_rdata_next[31:0] = prefix_6_qs; + end + + addr_hit[15]: begin + reg_rdata_next[31:0] = prefix_7_qs; + end + + addr_hit[16]: begin + reg_rdata_next[31:0] = prefix_8_qs; + end + + addr_hit[17]: begin + reg_rdata_next[31:0] = prefix_9_qs; + end + + addr_hit[18]: begin + reg_rdata_next[31:0] = prefix_10_qs; + end + + addr_hit[19]: begin + reg_rdata_next[31:0] = err_code_qs; + end + + default: begin + reg_rdata_next = '1; + end + endcase + end + + // shadow busy + logic shadow_busy; + logic rst_done; + logic shadow_rst_done; + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + rst_done <= '0; + end else begin + rst_done <= 1'b1; + end + end + + always_ff @(posedge clk_i or negedge rst_shadowed_ni) begin + if (!rst_shadowed_ni) begin + shadow_rst_done <= '0; + end else begin + shadow_rst_done <= 1'b1; + end + end + + // both shadow and normal resets have been released + assign shadow_busy = ~(rst_done & shadow_rst_done); + + // Collect up storage and update errors + assign shadowed_storage_err_o = |{ + cfg_shadowed_kstrength_storage_err, + cfg_shadowed_mode_storage_err, + cfg_shadowed_msg_endianness_storage_err, + cfg_shadowed_state_endianness_storage_err + }; + assign shadowed_update_err_o = |{ + cfg_shadowed_kstrength_update_err, + cfg_shadowed_mode_update_err, + cfg_shadowed_msg_endianness_update_err, + cfg_shadowed_state_endianness_update_err + }; + + // register busy + assign reg_busy = shadow_busy; + + // Unused signal tieoff + + // wdata / byte enable are not always fully used + // add a blanket unused statement to handle lint waivers + logic unused_wdata; + logic unused_be; + assign unused_wdata = ^reg_wdata; + assign unused_be = ^reg_be; + + // Assertions for Register Interface + `CALIPTRA_ASSERT_PULSE(wePulse, reg_we, clk_i, !rst_ni) + `CALIPTRA_ASSERT_PULSE(rePulse, reg_re, clk_i, !rst_ni) + + `CALIPTRA_ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o_pre.d_valid, clk_i, !rst_ni) + + `CALIPTRA_ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit), clk_i, !rst_ni) + + // this is formulated as an assumption such that the FPV testbenches do disprove this + // property by mistake + //`ASSUME(reqParity, tl_reg_h2d.a_valid |-> tl_reg_h2d.a_user.chk_en == caliptra_tlul_pkg::CheckDis) + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/kmac_staterd.sv b/designs/Caliptra/src/caliptra-rtl/kmac_staterd.sv new file mode 100644 index 0000000..b27ac93 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/kmac_staterd.sv @@ -0,0 +1,130 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Keccak state read + +`include "caliptra_prim_assert.sv" + +module kmac_staterd + import caliptra_prim_mubi_pkg::*; + import kmac_pkg::*; +#( + // TL-UL Address Width. Should be bigger than + // $clog2(kmac_pkg::StateW) * Share + parameter int AddrW = 9, + + // EnMasking: Enable masking security hardening inside keccak_round + // If it is enabled, the result digest will be two set of 1600bit. + parameter bit EnMasking = 1'b0, + localparam int Share = (EnMasking) ? 2 : 1 // derived parameter +) ( + input clk_i, + input rst_ni, + + input caliptra_tlul_pkg::tl_h2d_t tl_i, + output caliptra_tlul_pkg::tl_d2h_t tl_o, + + // State in + input [ot_sha3_pkg::StateW-1:0] state_i [Share], + + // Config + input endian_swap_i +); + + localparam int StateAddrW = $clog2(ot_sha3_pkg::StateW/32); + localparam int SelAddrW = AddrW-2-StateAddrW; + + ///////////// + // Signals // + ///////////// + + // TL-UL Adapter signals + logic tlram_req; + logic tlram_gnt; + logic tlram_we; + logic [AddrW-3:0] tlram_addr; // Word base + logic [31:0] unused_tlram_wdata; + logic [31:0] unused_tlram_wmask; + logic [31:0] tlram_rdata; + logic tlram_rvalid; + logic [1:0] tlram_rerror; + logic [31:0] tlram_rdata_endian; + + // TL Adapter + caliptra_tlul_adapter_sram #( + .SramAw (AddrW-2), + .SramDw (32), + .Outstanding (1), + .ByteAccess (1), + .ErrOnWrite (1), + .ErrOnRead (0) + ) u_tlul_adapter ( + .clk_i, + .rst_ni, + + .tl_i, + .tl_o, + .en_ifetch_i (MuBi4False), + .req_o (tlram_req), + .req_type_o (), + .gnt_i (tlram_gnt), + .we_o (tlram_we ), + .addr_o (tlram_addr), + .wdata_o (unused_tlram_wdata), + .wmask_o (unused_tlram_wmask), + .intg_error_o (), + .rdata_i (tlram_rdata), + .rvalid_i (tlram_rvalid), + .rerror_i (tlram_rerror), + .compound_txn_in_progress_o (), + .readback_en_i (MuBi4False), + .readback_error_o (), + .wr_collision_i (1'b0), + .write_pending_i (1'b0) + ); + + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + tlram_rdata <= '0; + end else if (tlram_req & ~tlram_we) begin + tlram_rdata <= conv_endian32(tlram_rdata_endian, endian_swap_i); + end + end + + // Always grant + assign tlram_gnt = tlram_req & ~tlram_we; + + // always no error on reading + assign tlram_rerror = '0; + + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) tlram_rvalid <= 1'b0; + else tlram_rvalid <= tlram_req & !tlram_we; + end + + logic [31:0] muxed_state [Share]; + + + for (genvar i = 0 ; i < Share ; i++) begin : gen_slicer + caliptra_prim_slicer #( + .InW (ot_sha3_pkg::StateW), + .OutW (32), + .IndexW (StateAddrW) + ) u_state_slice ( + .sel_i (tlram_addr[StateAddrW-1:0]), + .data_i (state_i[i]), + .data_o (muxed_state[i]) + ); + end : gen_slicer + + logic [SelAddrW-1:0] addr_sel; + assign addr_sel = tlram_addr[StateAddrW+:SelAddrW]; + + if (EnMasking) begin : gen_state_sel_masked + assign tlram_rdata_endian = int'(addr_sel) < Share ? muxed_state[addr_sel] : 0; + end else begin : gen_state_sel_unmasked + assign tlram_rdata_endian = int'(addr_sel) < Share ? muxed_state[0] : 0; + end + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/kv.sv b/designs/Caliptra/src/caliptra-rtl/kv.sv new file mode 100644 index 0000000..f0f23e5 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/kv.sv @@ -0,0 +1,289 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +// + + +`include "caliptra_macros.svh" + +module kv + import kv_defines_pkg::*; + import kv_reg_pkg::*; + + #( + parameter AHB_ADDR_WIDTH = KV_ADDR_W + ,parameter AHB_DATA_WIDTH = 32 + ) + ( + input logic clk, + input logic rst_b, + input logic core_only_rst_b, + input logic cptra_pwrgood, + input logic fw_update_rst_window, + input logic cptra_in_debug_scan_mode, + input logic debugUnlock_or_scan_mode_switch, + + //uC AHB Lite Interface + //from SLAVES PORT + input logic [AHB_ADDR_WIDTH-1:0] haddr_i, + input logic [AHB_DATA_WIDTH-1:0] hwdata_i, + input logic hsel_i, + input logic hwrite_i, + input logic hready_i, + input logic [1:0] htrans_i, + input logic [2:0] hsize_i, + + output logic hresp_o, + output logic hreadyout_o, + output logic [AHB_DATA_WIDTH-1:0] hrdata_o, + + input kv_read_t [KV_NUM_READ-1:0] kv_read, + input kv_write_t [KV_NUM_WRITE-1:0] kv_write, + output kv_rd_resp_t [KV_NUM_READ-1:0] kv_rd_resp, + output kv_wr_resp_t [KV_NUM_WRITE-1:0] kv_wr_resp, + output logic [ECC_NUM_DWORDS-1:0][31:0] pcr_ecc_signing_key, + output logic [MLDSA_NUM_DWORDS-1:0][31:0] pcr_mldsa_signing_key +); + +logic uc_req_dv, uc_req_hold; +logic uc_req_error; +logic [31:0] uc_req_rdata; +logic kv_reg_read_error, kv_reg_write_error; +logic [AHB_ADDR_WIDTH-1:0] uc_req_addr; +kv_uc_req_t uc_req; + +logic flush_keyvault; +logic [31:0] debug_value; + +//intermediate signals to make verilator happy +logic [KV_NUM_KEYS-1:0][KV_NUM_DWORDS-1:0] key_entry_we; +logic [KV_NUM_KEYS-1:0] key_entry_ctrl_we; +logic [KV_NUM_KEYS-1:0][KV_NUM_DWORDS-1:0][31:0] key_entry_next; +logic [KV_NUM_KEYS-1:0][KV_NUM_READ-1:0] key_entry_dest_valid_next; +logic [KV_NUM_KEYS-1:0][KV_ENTRY_SIZE_W-1:0] key_entry_last_dword_next; +logic [KV_NUM_KEYS-1:0] lock_wr_q; +logic [KV_NUM_KEYS-1:0] lock_use_q; +kv_reg__in_t kv_reg_hwif_in; +kv_reg__out_t kv_reg_hwif_out; + +logic [KV_NUM_KEYS-1:0] key_entry_clear; + +logic [$clog2(KV_NUM_WRITE)-1:0] kv_write_cnt; +logic kv_multi_write_err; + +ahb_slv_sif #( + .AHB_ADDR_WIDTH(AHB_ADDR_WIDTH), + .AHB_DATA_WIDTH(AHB_DATA_WIDTH), + .CLIENT_DATA_WIDTH(32) +) +kv_ahb_slv1 ( + //AMBA AHB Lite INF + .hclk(clk), + .hreset_n(rst_b), + .haddr_i(haddr_i), + .hwdata_i(hwdata_i), + .hsel_i(hsel_i), + .hwrite_i(hwrite_i), + .hready_i(hready_i), + .htrans_i(htrans_i), + .hsize_i(hsize_i), + + .hresp_o(hresp_o), + .hreadyout_o(hreadyout_o), + .hrdata_o(hrdata_o), + + + //COMPONENT INF + .dv(uc_req_dv), + .hld(uc_req_hold), + .err(uc_req_error), + .write(uc_req.write), + .wdata(uc_req.wdata), + .addr(uc_req_addr), + + .rdata(uc_req_rdata) +); + +always_comb uc_req.addr = uc_req_addr[KV_ADDR_W-1:0]; +always_comb uc_req_error = kv_reg_read_error | kv_reg_write_error; +always_comb uc_req_hold = '0; + +//Flush the keyvault with the debug value when FW pokes the register or we detect debug mode unlocking +always_comb flush_keyvault = debugUnlock_or_scan_mode_switch | + (cptra_in_debug_scan_mode & kv_reg_hwif_out.CLEAR_SECRETS.wr_debug_values.value); +//Pick between keyvault debug mode 0 or 1 +always_comb debug_value = kv_reg_hwif_out.CLEAR_SECRETS.sel_debug_value.value ? CLP_DEBUG_MODE_KV_1 : CLP_DEBUG_MODE_KV_0; + +always_comb begin : keyvault_pcr_ecc_signing + for (int dword = 0; dword < ECC_NUM_DWORDS; dword++) begin + pcr_ecc_signing_key[dword] = kv_reg_hwif_out.KEY_ENTRY[KV_ENTRY_FOR_ECC_SIGNING][dword].data.value; + end +end + +always_comb begin : keyvault_pcr_mldsa_signing + for (int dword = 0; dword < MLDSA_NUM_DWORDS; dword++) begin + pcr_mldsa_signing_key[dword] = kv_reg_hwif_out.KEY_ENTRY[KV_ENTRY_FOR_MLDSA_SIGNING][dword].data.value; + end +end + +always_comb begin + kv_write_cnt = 0; + for (int client = 0; client < KV_NUM_WRITE; client++)begin + if (kv_write[client].write_en) + kv_write_cnt = kv_write_cnt + 'd1; + end +end + +always_comb kv_multi_write_err = kv_write_cnt > 1; + +//Generate clear signal for each key entry +//don't clear when writes are locked +//hold the clear when writes are in progress +generate + for (genvar g_entry = 0; g_entry < KV_NUM_KEYS; g_entry++) begin + always_ff@(posedge clk or negedge rst_b) begin + if(~rst_b) begin + key_entry_clear[g_entry] <= '0; + end + else begin + key_entry_clear[g_entry] <= kv_multi_write_err | + (kv_reg_hwif_out.KEY_CTRL[g_entry].clear.value & ~lock_wr_q[g_entry] & ~lock_use_q[g_entry]) | + (key_entry_clear[g_entry] & key_entry_ctrl_we[g_entry]); + end + end + end +endgenerate + +always_comb begin : keyvault_ctrl + //keyvault control registers + for (int entry = 0; entry < KV_NUM_KEYS; entry++) begin + //init for AND-OR + key_entry_ctrl_we[entry] = '0; + key_entry_dest_valid_next[entry] = '0; + key_entry_last_dword_next[entry] = '0; + + //Qualify lock signals as they are on fw upd reset and create RDC violations if allowed to reset asynchronously + lock_wr_q[entry] = kv_reg_hwif_out.KEY_CTRL[entry].lock_wr.value & ~fw_update_rst_window; + lock_use_q[entry] = kv_reg_hwif_out.KEY_CTRL[entry].lock_use.value & ~fw_update_rst_window; + + for (int client = 0; client < KV_NUM_WRITE; client++) begin + key_entry_ctrl_we[entry] |= (kv_write[client].write_entry == entry) & kv_write[client].write_en & + ~lock_wr_q[entry] & ~lock_use_q[entry]; + key_entry_dest_valid_next[entry] |= (kv_write[client].write_entry == entry) & kv_write[client].write_en ? kv_write[client].write_dest_valid : '0; + //store the final offset on the last write cycle, we'll use that to signal last dword on reads + key_entry_last_dword_next[entry] |= (kv_write[client].write_entry == entry) & kv_write[client].write_en ? kv_write[client].write_offset : '0; + end + //once lock is set, only reset can unset it + kv_reg_hwif_in.KEY_CTRL[entry].lock_wr.swwel = lock_wr_q[entry]; + kv_reg_hwif_in.KEY_CTRL[entry].lock_use.swwel = lock_use_q[entry]; + //clear dest valid and last dword + kv_reg_hwif_in.KEY_CTRL[entry].dest_valid.hwclr = key_entry_clear[entry]; + kv_reg_hwif_in.KEY_CTRL[entry].last_dword.hwclr = key_entry_clear[entry]; + + kv_reg_hwif_in.KEY_CTRL[entry].dest_valid.we = key_entry_ctrl_we[entry] & ~key_entry_clear[entry]; + kv_reg_hwif_in.KEY_CTRL[entry].dest_valid.next = {3'd0,key_entry_dest_valid_next[entry]}; + kv_reg_hwif_in.KEY_CTRL[entry].last_dword.we = key_entry_ctrl_we[entry] & ~key_entry_clear[entry]; + kv_reg_hwif_in.KEY_CTRL[entry].last_dword.next = key_entry_last_dword_next[entry]; + end + + //keyvault storage + //AND-OR mux writes to each entry from crypto blocks + //write to the appropriate dest entry and offset when write_en is set + for (int entry = 0; entry < KV_NUM_KEYS; entry++) begin + for (int dword = 0; dword < KV_NUM_DWORDS; dword++) begin + kv_reg_hwif_in.KEY_ENTRY[entry][dword].data.swwel = '1; //never allow sw writes + //initialize to 0 for AND-OR mux + key_entry_we[entry][dword] = '0; + key_entry_next[entry][dword] = '0; + for (int client = 0; client < KV_NUM_WRITE; client++) begin + key_entry_we[entry][dword] |= ((((kv_write[client].write_entry == entry) & (kv_write[client].write_offset == dword) & + kv_write[client].write_en) | flush_keyvault) & + ((~lock_wr_q[entry] & ~lock_use_q[entry]) | debugUnlock_or_scan_mode_switch)); + key_entry_next[entry][dword] |= flush_keyvault ? debug_value : + kv_write[client].write_en & (kv_write[client].write_entry == entry) ? kv_write[client].write_data : '0; + end + kv_reg_hwif_in.KEY_ENTRY[entry][dword].data.we = key_entry_we[entry][dword] & ~key_entry_clear[entry]; + kv_reg_hwif_in.KEY_ENTRY[entry][dword].data.next = key_entry_next[entry][dword]; + kv_reg_hwif_in.KEY_ENTRY[entry][dword].data.hwclr = key_entry_clear[entry]; + end + end +end + +//read mux for keyvault +//qualify with selected entry, offset +//qualify with lock use bit to ensure that locked values aren't read +//qualify with dest valid to ensure requesting client has permission to read this entry +always_comb begin : keyvault_readmux + for (int client = 0; client < KV_NUM_READ; client++) begin + kv_rd_resp[client].read_data = '0; + kv_rd_resp[client].error = '0; + kv_rd_resp[client].last = '0; + for (int entry = 0; entry < KV_NUM_KEYS; entry++) begin + for (int dword = 0; dword < KV_NUM_DWORDS; dword++) begin + kv_rd_resp[client].read_data |= (kv_read[client].read_entry == entry) & (kv_read[client].read_offset == dword) & + ~lock_use_q[entry] & kv_reg_hwif_out.KEY_CTRL[entry].dest_valid.value[client] ? + kv_reg_hwif_out.KEY_ENTRY[entry][dword].data.value : '0; + end + //signal last when reading the last dword + kv_rd_resp[client].last |= (kv_read[client].read_entry == entry) & (kv_read[client].read_offset == kv_reg_hwif_out.KEY_CTRL[entry].last_dword.value); + kv_rd_resp[client].error |= (kv_read[client].read_entry == entry) & + (lock_use_q[entry] | ~kv_reg_hwif_out.KEY_CTRL[entry].dest_valid.value[client]); + end + end +end + +//Write error when attempting to write to entry that is locked for writes, use, or is being cleared +always_comb begin : keyvault_write_resp + for (int client = 0 ; client < KV_NUM_WRITE; client++) begin + kv_wr_resp[client].error = '0; + for (int entry = 0; entry < KV_NUM_KEYS; entry++) begin + kv_wr_resp[client].error |= (kv_write[client].write_entry == entry) & kv_write[client].write_en & + (key_entry_clear[entry] | lock_wr_q[entry] | lock_use_q[entry]); + end + end +end + +//tie-offs +always_comb begin + for (int entry = 0; entry < KV_NUM_KEYS; entry++) begin + kv_reg_hwif_in.KEY_CTRL[entry].rsvd0.hwclr = '0; + end +end + + +always_comb kv_reg_hwif_in.hard_reset_b = cptra_pwrgood; +always_comb kv_reg_hwif_in.reset_b = rst_b; +always_comb kv_reg_hwif_in.core_only_rst_b = core_only_rst_b; //Note that this signal will also reset when rst_b is asserted + +kv_reg kv_reg1 ( + .clk(clk), + .rst('0), + //qualify request so no addresses alias + .s_cpuif_req(uc_req_dv), + .s_cpuif_req_is_wr(uc_req.write), + .s_cpuif_addr(uc_req.addr[KV_REG_ADDR_WIDTH-1:0]), + .s_cpuif_wr_data(uc_req.wdata), + .s_cpuif_wr_biten('1), + .s_cpuif_req_stall_wr(), + .s_cpuif_req_stall_rd(), + .s_cpuif_rd_ack(), + .s_cpuif_rd_err(kv_reg_read_error), + .s_cpuif_rd_data(uc_req_rdata), + .s_cpuif_wr_ack(), + .s_cpuif_wr_err(kv_reg_write_error), + + .hwif_in(kv_reg_hwif_in), + .hwif_out(kv_reg_hwif_out) +); + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/kv_defines_pkg.sv b/designs/Caliptra/src/caliptra-rtl/kv_defines_pkg.sv new file mode 100644 index 0000000..91bd3ef --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/kv_defines_pkg.sv @@ -0,0 +1,145 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +// +`ifndef CALIPTRA_KV_DEFINES_PKG +`define CALIPTRA_KV_DEFINES_PKG + +package kv_defines_pkg; + +parameter KV_NUM_DWORDS = 16; //number of dwords per key +parameter KV_NUM_KEYS = 24; +parameter KV_ADDR_W = 13; +parameter KV_DATA_W = 32; +parameter KV_ENTRY_ADDR_W = $clog2(KV_NUM_KEYS); +parameter KV_ENTRY_SIZE_W = $clog2(KV_NUM_DWORDS); +parameter KV_NUM_READ=9; +parameter KV_NUM_WRITE=5; +parameter ECC_NUM_DWORDS = 12; +parameter MLDSA_NUM_DWORDS = 8; + +parameter KV_ENTRY_FOR_ECC_SIGNING = 7; +parameter KV_ENTRY_FOR_MLDSA_SIGNING = 8; +parameter PCR_HASH_NUM_DWORDS = 16; + +localparam KV_STANDARD_SLOT_LOW = 0; +localparam KV_STANDARD_SLOT_HI = 15; +localparam KV_OCP_LOCK_SLOT_LOW = 16; +localparam KV_OCP_LOCK_SLOT_HI = 23; + +localparam OCP_LOCK_RT_OBF_KEY_KV_SLOT = 16; // Stores the runtime MEK obf key (derived from devid chain). aka MDK +localparam OCP_LOCK_HEK_SEED_KV_SLOT = 22; // Destination for deobf HEK seed, also for derived HEK +localparam OCP_LOCK_KEY_RELEASE_KV_SLOT = 23; // Stores the fully decrypted MEK +localparam OCP_LOCK_HEK_NUM_DWORDS = 8; // 256b HEK Seed -- used to define the write-size from DOE +localparam OCP_LOCK_MEK_NUM_DWORDS = 16; // 512b MEK -- used to define the entry size fetched from KV + +localparam KV_WRITE_IDX_HMAC = 0; +localparam KV_WRITE_IDX_MLKEM = 1; +localparam KV_WRITE_IDX_ECC = 2; +localparam KV_WRITE_IDX_DOE = 3; +localparam KV_WRITE_IDX_AES = 4; + +localparam KV_DEST_IDX_HMAC_KEY = 0; +localparam KV_DEST_IDX_HMAC_BLOCK = 1; +localparam KV_DEST_IDX_MLDSA_SEED = 2; +localparam KV_DEST_IDX_ECC_PKEY = 3; +localparam KV_DEST_IDX_ECC_SEED = 4; +localparam KV_DEST_IDX_AES_KEY = 5; +localparam KV_DEST_IDX_MLKEM_SEED = 6; +localparam KV_DEST_IDX_MLKEM_MSG = 7; +localparam KV_DEST_IDX_DMA_DATA = 8; + +// HEK seed (deobfuscated) is used as context for SP 800-108 KDF when deriving +// the HEK +localparam OCP_LOCK_HEK_SEED_DEST_VALID = (1 << KV_DEST_IDX_HMAC_BLOCK); + +typedef struct packed { + logic [KV_ADDR_W-1:0] addr; + logic [KV_DATA_W-1:0] wdata; + logic write; +} kv_uc_req_t; + +typedef struct packed { + logic [KV_ENTRY_ADDR_W-1:0] read_entry; + logic [KV_ENTRY_SIZE_W-1:0] read_offset; +} kv_read_t; + +typedef struct packed { + logic write_en; + logic [KV_ENTRY_ADDR_W-1:0] write_entry; + logic [KV_ENTRY_SIZE_W-1:0] write_offset; + logic [KV_DATA_W-1:0] write_data; + logic [KV_NUM_READ-1:0] write_dest_valid; +} kv_write_t; + +typedef struct packed { + logic error; +} kv_wr_resp_t; + +typedef struct packed { + logic error; + logic last; + logic [KV_DATA_W-1:0] read_data; +} kv_rd_resp_t; + +//control register for KV reads +localparam KV_READ_CTRL_RSVD_MSB = 32 - KV_ENTRY_SIZE_W - 1 - 1; +typedef struct packed { + logic [KV_READ_CTRL_RSVD_MSB:0] rsvd; + logic [KV_ENTRY_ADDR_W-1:0] read_entry; + logic pcr_hash_extend; + logic read_en; +} kv_read_ctrl_reg_t; + +//control register for KV writes +localparam KV_WRITE_CTRL_RSVD_MSB = 32 - KV_NUM_READ - KV_ENTRY_ADDR_W - 1; +typedef struct packed { + logic [KV_WRITE_CTRL_RSVD_MSB:0] rsvd; + logic [KV_NUM_READ-1:0] write_dest_vld; + logic [KV_ENTRY_ADDR_W-1:0] write_entry; + logic write_en; +} kv_write_ctrl_reg_t; + +typedef enum logic [7:0] { + KV_SUCCESS = 8'h00, + KV_READ_FAIL = 8'h01, + KV_WRITE_FAIL = 8'h02 +} kv_error_code_e; + +typedef struct packed { + logic [PCR_HASH_NUM_DWORDS-1:0][31:0] pcr_hash; + logic [ECC_NUM_DWORDS-1:0][31:0] pcr_ecc_signing_privkey; + logic [MLDSA_NUM_DWORDS-1:0][31:0] pcr_mldsa_signing_seed; +} pcr_signing_t; + +typedef struct packed { + logic ocp_lock_in_progress; + logic [KV_NUM_READ-1:0] kv_read_dest; + logic [KV_ENTRY_ADDR_W-1:0] kv_key_entry; +} kv_read_filter_metrics_t; + +typedef struct packed { + logic ocp_lock_in_progress; + logic kv_data0_present; + logic [KV_ENTRY_ADDR_W-1:0] kv_data0_entry; + logic kv_data1_present; + logic [KV_ENTRY_ADDR_W-1:0] kv_data1_entry; + logic [KV_NUM_WRITE-1:0] kv_write_src; + logic [KV_ENTRY_ADDR_W-1:0] kv_write_entry; + logic aes_decrypt_ecb_op; +} kv_write_filter_metrics_t; +endpackage + +`endif + + diff --git a/designs/Caliptra/src/caliptra-rtl/kv_fsm.sv b/designs/Caliptra/src/caliptra-rtl/kv_fsm.sv new file mode 100644 index 0000000..a521c26 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/kv_fsm.sv @@ -0,0 +1,196 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +// +//`include "kv_defines.svh" + +module kv_fsm + import kv_defines_pkg::*; + #( + parameter DATA_WIDTH = 512 + ,parameter PAD = 0 + ,parameter HMAC = 0 + ,localparam OFFSET_W = $clog2(DATA_WIDTH/32) +) +( + input logic clk, + input logic rst_b, + input logic zeroize, + + input logic start, + input logic allow, + input logic last, + + input logic pcr_hash_extend, + input logic [OFFSET_W:0] num_dwords, + + output logic [OFFSET_W-1:0] read_offset, + + output logic write_en, + output logic [OFFSET_W-1:0] write_offset, + output logic write_pad, + output logic [31:0] pad_data, + output logic write_last, + + output logic ready, + + output logic done +); +//max dwords for SHA/HMAC blocks that need padding +localparam KV_MAX_DWORDS = 1024/32; +localparam KV_NUM_DWORDS_W = $clog2(KV_MAX_DWORDS); +localparam KV_PAD_LENGTH_START = 28; + +logic [KV_NUM_DWORDS_W:0] num_dwords_data; +logic [KV_NUM_DWORDS_W:0] num_dwords_total; +logic [31:0] length_for_pad; + +//declare fsm state variables +typedef enum logic [2:0] { + KV_IDLE = 3'b000, + KV_RW = 3'b001, + KV_PAD = 3'b011, + KV_ZERO = 3'b010, + KV_LENGTH = 3'b110, + KV_DONE = 3'b100 +} kv_fsm_state_e; + +kv_fsm_state_e kv_fsm_ps, kv_fsm_ns; +logic arc_KV_IDLE_KV_RW; +logic arc_KV_IDLE_KV_DONE; +logic arc_KV_RW_KV_DONE; +logic arc_KV_DONE_KV_IDLE; +logic arc_KV_RW_KV_PAD; +logic arc_KV_PAD_KV_ZERO; +logic arc_KV_ZERO_KV_LENGTH; +logic arc_KV_LENGTH_KV_DONE; + +logic offset_en; +logic offset_rst; +logic [OFFSET_W:0] offset, offset_nxt; + +assign num_dwords_total = pcr_hash_extend ? 'd12 : + ((PAD == 1) ? KV_MAX_DWORDS : $bits(num_dwords_total)'(num_dwords)); + +always_comb ready = (kv_fsm_ps == KV_IDLE); + +// For SHA and HMAC Block - +// Padding starts with a leading 1 after the valid data followed by 0's until +// the length of the valid data is stored in the last 4 dwords. +// HMAC adds 1024 bits to the length to account for the key +always_comb length_for_pad = (HMAC == 1) ? (32'b0 | ((num_dwords_data << 5) + 'd1024)) : (32'b0 | (num_dwords_data << 5)); + +always_comb arc_KV_IDLE_KV_RW = start && allow; +always_comb arc_KV_IDLE_KV_DONE = start && !allow; +always_comb arc_KV_RW_KV_DONE = ((PAD == 0) | pcr_hash_extend) & (($bits(num_dwords_total)'(offset) == (num_dwords_total-1)) | last); //jump to done when we've written all dwords +always_comb arc_KV_RW_KV_PAD = ((PAD == 1) & ~pcr_hash_extend) & last; //jump to pad when data is done +always_comb arc_KV_PAD_KV_ZERO = (PAD == 1) && (kv_fsm_ps == KV_PAD); +always_comb arc_KV_ZERO_KV_LENGTH = (PAD == 1) && ($bits(num_dwords_total)'(offset_nxt) == 'd31); //jump to length when it's time to append length in the last dword +always_comb arc_KV_LENGTH_KV_DONE = (PAD == 1) && (kv_fsm_ps == KV_LENGTH); +always_comb arc_KV_DONE_KV_IDLE = '1; + +always_comb offset_rst = arc_KV_RW_KV_DONE | arc_KV_LENGTH_KV_DONE; +always_comb write_last = arc_KV_RW_KV_DONE | arc_KV_LENGTH_KV_DONE; + +always_comb begin : kv_fsm_comb + kv_fsm_ns = kv_fsm_ps; + write_en = '0; + write_pad = '0; + offset_en = '0; + offset_nxt = '0; + pad_data = '0; + done = '0; + unique case (kv_fsm_ps) + KV_IDLE: begin + if (arc_KV_IDLE_KV_RW) kv_fsm_ns = KV_RW; + else if (arc_KV_IDLE_KV_DONE) kv_fsm_ns = KV_DONE; + end + KV_RW: begin + if (arc_KV_RW_KV_PAD) kv_fsm_ns = KV_PAD; + if (arc_KV_RW_KV_DONE) kv_fsm_ns = KV_DONE; + write_en = '1; + offset_en = '1; + offset_nxt = offset + 'd1; + end + KV_PAD: begin + if (arc_KV_PAD_KV_ZERO) kv_fsm_ns = KV_ZERO; + write_en = '1; + offset_en = '1; + offset_nxt = offset + 'd1; + write_pad = '1; + pad_data = 32'h8000_0000; + end + KV_ZERO: begin + if (arc_KV_ZERO_KV_LENGTH) kv_fsm_ns = KV_LENGTH; + write_en = '1; + offset_en = '1; + offset_nxt = offset + 'd1; + write_pad = '1; + pad_data = '0; + end + KV_LENGTH: begin + if (arc_KV_LENGTH_KV_DONE) kv_fsm_ns = KV_DONE; + write_en = '1; + offset_en = '1; + offset_nxt = offset + 'd1; + write_pad = '1; + pad_data = length_for_pad; + end + KV_DONE: begin + if (arc_KV_DONE_KV_IDLE) kv_fsm_ns = KV_IDLE; + done = '1; + end + default: begin + end + endcase +end + +always_ff @(posedge clk or negedge rst_b) begin + if (!rst_b) begin + kv_fsm_ps <= KV_IDLE; + offset <= '0; + end + else if (zeroize) begin + kv_fsm_ps <= KV_IDLE; + offset <= '0; + end + else begin + kv_fsm_ps <= kv_fsm_ns; + offset <= offset_rst ? '0 : + offset_en ? offset_nxt : offset; + end +end + +generate + if (PAD==1) begin + always_ff @(posedge clk or negedge rst_b) begin + if (!rst_b) begin + num_dwords_data <= '0; + end + else if (zeroize) begin + num_dwords_data <= '0; + end + else begin + //store the offset_nxt on the last cycle of valid data, this is the number of dwords of valid data + num_dwords_data <= arc_KV_RW_KV_PAD ? $bits(num_dwords_data)'(offset_nxt) : num_dwords_data; + end + end + end else begin + always_comb num_dwords_data = '0; + end +endgenerate + +always_comb read_offset = (kv_fsm_ps == KV_RW) ? offset[OFFSET_W-1:0] : '0; +always_comb write_offset = offset[OFFSET_W-1:0]; + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/kv_macros.svh b/designs/Caliptra/src/caliptra-rtl/kv_macros.svh new file mode 100644 index 0000000..b69aacb --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/kv_macros.svh @@ -0,0 +1,56 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +// +`ifndef CALIPTRA_KV_MACROS +`define CALIPTRA_KV_MACROS + + + +`define CALIPTRA_KV_WRITE_CTRL_REG2STRUCT(struct_name, ctrl_reg_name, hwif_name = hwif_out)\ +assign struct_name.rsvd = '0;\ +assign struct_name.write_dest_vld[0] = ``hwif_name.``ctrl_reg_name.hmac_key_dest_valid.value;\ +assign struct_name.write_dest_vld[1] = ``hwif_name.``ctrl_reg_name.hmac_block_dest_valid.value;\ +assign struct_name.write_dest_vld[2] = ``hwif_name.``ctrl_reg_name.mldsa_seed_dest_valid.value;\ +assign struct_name.write_dest_vld[3] = ``hwif_name.``ctrl_reg_name.ecc_pkey_dest_valid.value;\ +assign struct_name.write_dest_vld[4] = ``hwif_name.``ctrl_reg_name.ecc_seed_dest_valid.value;\ +assign struct_name.write_dest_vld[5] = ``hwif_name.``ctrl_reg_name.aes_key_dest_valid.value;\ +assign struct_name.write_dest_vld[6] = ``hwif_name.``ctrl_reg_name.mlkem_seed_dest_valid.value;\ +assign struct_name.write_dest_vld[7] = ``hwif_name.``ctrl_reg_name.mlkem_msg_dest_valid.value;\ +assign struct_name.write_dest_vld[8] = ``hwif_name.``ctrl_reg_name.dma_data_dest_valid.value;\ +assign struct_name.write_entry = ``hwif_name.``ctrl_reg_name.write_entry.value;\ +assign struct_name.write_en = ``hwif_name.``ctrl_reg_name.write_en.value; + +`define CALIPTRA_KV_READ_CTRL_REG2STRUCT(struct_name, ctrl_reg_name, hwif_name = hwif_out)\ +assign struct_name.rsvd = '0;\ +assign struct_name.pcr_hash_extend = ``hwif_name.``ctrl_reg_name.pcr_hash_extend.value;\ +assign struct_name.read_entry = ``hwif_name.``ctrl_reg_name.read_entry.value;\ +assign struct_name.read_en = ``hwif_name.``ctrl_reg_name.read_en.value; + +`define CALIPTRA_KV_READ_STATUS_ASSIGN(sig_prefix, hwif_name = hwif_in)\ +assign ``hwif_name.``sig_prefix``_rd_status.ERROR.next = ``sig_prefix``_error;\ +assign ``hwif_name.``sig_prefix``_rd_status.READY.next = ``sig_prefix``_ready;\ +assign ``hwif_name.``sig_prefix``_rd_status.VALID.hwset = ``sig_prefix``_done;\ +assign ``hwif_name.``sig_prefix``_rd_status.VALID.hwclr = ``sig_prefix``_read_ctrl_reg.read_en;\ +assign ``hwif_name.``sig_prefix``_rd_ctrl.read_en.hwclr = ~``sig_prefix``_ready; + +`define CALIPTRA_KV_WRITE_STATUS_ASSIGN(sig_prefix, hwif_name = hwif_in)\ +assign ``hwif_name.``sig_prefix``_wr_status.ERROR.next = ``sig_prefix``_error;\ +assign ``hwif_name.``sig_prefix``_wr_status.READY.next = ``sig_prefix``_ready;\ +assign ``hwif_name.``sig_prefix``_wr_status.VALID.hwset = ``sig_prefix``_done;\ +assign ``hwif_name.``sig_prefix``_wr_status.VALID.hwclr = ``sig_prefix``_write_ctrl_reg.write_en;\ +assign ``hwif_name.``sig_prefix``_wr_ctrl.write_en.hwclr = ~``sig_prefix``_ready; + +`endif + + diff --git a/designs/Caliptra/src/caliptra-rtl/kv_read_client.sv b/designs/Caliptra/src/caliptra-rtl/kv_read_client.sv new file mode 100644 index 0000000..5e9f81a --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/kv_read_client.sv @@ -0,0 +1,125 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +// +//`include "kv_defines.svh" +`include "caliptra_prim_assert.sv" + +module kv_read_client + import kv_defines_pkg::*; + #( + parameter DATA_WIDTH = 512 + ,parameter HMAC = 0 + ,parameter PAD = 0 + + ,localparam DATA_OFFSET_W = $clog2(DATA_WIDTH/32) +) +( + input logic clk, + input logic rst_b, + input logic zeroize, + + //client control register + input kv_read_ctrl_reg_t read_ctrl_reg, + + //access filtering rule metrics + input var kv_read_filter_metrics_t read_metrics, + + //interface with kv + output kv_read_t kv_read, + input kv_rd_resp_t kv_resp, + + //interface with client + output logic write_en, + output logic [DATA_OFFSET_W-1:0] write_offset, + output logic [31:0] write_data, + + output kv_error_code_e error_code, + output logic kv_ready, + output logic read_done +); + +logic validated_read_en; +logic read_allow; +logic [DATA_OFFSET_W-1:0] read_offset; +logic [DATA_OFFSET_W:0] num_dwords; +logic write_pad; +logic [31:0] pad_data; + +assign num_dwords = DATA_WIDTH/32; + +kv_read_rule_check kv_read_rules +( + .clk (clk ), + .rst_b (rst_b ), + + .read_en_i (read_ctrl_reg.read_en), + .read_done (read_done ), + .read_en_o (validated_read_en ), // Delayed from read_en_i to start read client FSM in sync with rule check result + + .read_metrics(read_metrics ), + .read_allow (read_allow ) +); + +//read fsm +kv_fsm #( + .DATA_WIDTH(DATA_WIDTH), + .HMAC(HMAC), + .PAD(PAD) +) +kv_read_fsm +( + .clk(clk), + .rst_b(rst_b), + .zeroize(zeroize), + .start(validated_read_en), + .allow(read_allow), + .last (kv_resp.last), + .pcr_hash_extend(read_ctrl_reg.pcr_hash_extend), + .num_dwords(num_dwords), + .read_offset(read_offset), + .write_en(write_en), + .write_offset(write_offset), + .write_pad(write_pad), + .write_last(), + .pad_data(pad_data), + .ready(kv_ready), + .done(read_done) +); + +always_comb kv_read.read_entry = read_ctrl_reg.read_entry; +always_comb kv_read.read_offset = KV_ENTRY_SIZE_W'(read_offset); + +always_comb write_data = write_pad ? pad_data : kv_resp.read_data; + +always_ff @(posedge clk or negedge rst_b) begin + if (!rst_b) begin + error_code <= KV_SUCCESS; + end + else if (zeroize) begin + error_code <= KV_SUCCESS; + end + else begin + // On first beat of kv read, latch any error conditions. + // On subsequent beats of kv read, preserve any error that was previously + // flagged or decode new error conditions + error_code <= validated_read_en && |write_offset && (error_code != KV_SUCCESS) ? error_code : + validated_read_en & ~read_allow ? KV_READ_FAIL : + validated_read_en & kv_resp.error ? KV_READ_FAIL : + validated_read_en & ~kv_resp.error ? KV_SUCCESS : error_code; + end +end + +`CALIPTRA_ASSERT_KNOWN(READ_METRICS_X, read_metrics, clk, !rst_b) + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/kv_read_rule_check.sv b/designs/Caliptra/src/caliptra-rtl/kv_read_rule_check.sv new file mode 100644 index 0000000..69c2040 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/kv_read_rule_check.sv @@ -0,0 +1,74 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +// + +module kv_read_rule_check +import kv_defines_pkg::*; +( + input logic clk, + input logic rst_b, + + input logic read_en_i, + input logic read_done, + output logic read_en_o, // Delayed from read_en_i to start read client FSM in sync with rule check result + + input var kv_read_filter_metrics_t read_metrics, + output logic read_allow +); + + + // --------------------------------------- // + // Signals // + // --------------------------------------- // + struct packed { + logic no_read_key_release; // DOE can not write to key release slot + } rule_fail; + + + // --------------------------------------- // + // Rules // + // --------------------------------------- // + // IF (OCP_LOCK_IN_PROGRESS) THEN (cryptos shall not read from OCP_LOCK_KEY_RELEASE_KV_SLOT) + always_comb begin + rule_fail.no_read_key_release = read_metrics.ocp_lock_in_progress && + read_metrics.kv_read_dest != (8'h1 << KV_DEST_IDX_DMA_DATA) && + read_metrics.kv_key_entry == OCP_LOCK_KEY_RELEASE_KV_SLOT; + end + + + // --------------------------------------- // + // Output // + // --------------------------------------- // + // Register the rule-check status; all of the input metrics will be stabilized prior to the + // becomes valid, so registering the output status reduces combinatorial depth + always_ff@(posedge clk or negedge rst_b) begin + if (!rst_b) begin + read_allow <= 1'b0; + read_en_o <= 1'b0; + end + else if (read_done) begin + read_allow <= 1'b0; + read_en_o <= 1'b0; + end + else if (read_en_i) begin + read_allow <= ~|rule_fail; + read_en_o <= 1'b1; + end + else begin + read_allow <= read_allow; + read_en_o <= 1'b0; + end + end + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/kv_reg.sv b/designs/Caliptra/src/caliptra-rtl/kv_reg.sv new file mode 100644 index 0000000..52f1f18 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/kv_reg.sv @@ -0,0 +1,475 @@ +// Generated by PeakRDL-regblock - A free and open-source SystemVerilog generator +// https://github.com/SystemRDL/PeakRDL-regblock + +module kv_reg ( + input wire clk, + input wire rst, + + input wire s_cpuif_req, + input wire s_cpuif_req_is_wr, + input wire [11:0] s_cpuif_addr, + input wire [31:0] s_cpuif_wr_data, + input wire [31:0] s_cpuif_wr_biten, + output wire s_cpuif_req_stall_wr, + output wire s_cpuif_req_stall_rd, + output wire s_cpuif_rd_ack, + output wire s_cpuif_rd_err, + output wire [31:0] s_cpuif_rd_data, + output wire s_cpuif_wr_ack, + output wire s_cpuif_wr_err, + + input kv_reg_pkg::kv_reg__in_t hwif_in, + output kv_reg_pkg::kv_reg__out_t hwif_out + ); + + //-------------------------------------------------------------------------- + // CPU Bus interface logic + //-------------------------------------------------------------------------- + logic cpuif_req; + logic cpuif_req_is_wr; + logic [11:0] cpuif_addr; + logic [31:0] cpuif_wr_data; + logic [31:0] cpuif_wr_biten; + logic cpuif_req_stall_wr; + logic cpuif_req_stall_rd; + + logic cpuif_rd_ack; + logic cpuif_rd_err; + logic [31:0] cpuif_rd_data; + + logic cpuif_wr_ack; + logic cpuif_wr_err; + + assign cpuif_req = s_cpuif_req; + assign cpuif_req_is_wr = s_cpuif_req_is_wr; + assign cpuif_addr = s_cpuif_addr; + assign cpuif_wr_data = s_cpuif_wr_data; + assign cpuif_wr_biten = s_cpuif_wr_biten; + assign s_cpuif_req_stall_wr = cpuif_req_stall_wr; + assign s_cpuif_req_stall_rd = cpuif_req_stall_rd; + assign s_cpuif_rd_ack = cpuif_rd_ack; + assign s_cpuif_rd_err = cpuif_rd_err; + assign s_cpuif_rd_data = cpuif_rd_data; + assign s_cpuif_wr_ack = cpuif_wr_ack; + assign s_cpuif_wr_err = cpuif_wr_err; + + logic cpuif_req_masked; + + // Read & write latencies are balanced. Stalls not required + assign cpuif_req_stall_rd = '0; + assign cpuif_req_stall_wr = '0; + assign cpuif_req_masked = cpuif_req + & !(!cpuif_req_is_wr & cpuif_req_stall_rd) + & !(cpuif_req_is_wr & cpuif_req_stall_wr); + + //-------------------------------------------------------------------------- + // Address Decode + //-------------------------------------------------------------------------- + typedef struct packed{ + logic [24-1:0]KEY_CTRL; + logic [24-1:0][16-1:0]KEY_ENTRY; + logic CLEAR_SECRETS; + } decoded_reg_strb_t; + decoded_reg_strb_t decoded_reg_strb; + logic decoded_req; + logic decoded_req_is_wr; + logic [31:0] decoded_wr_data; + logic [31:0] decoded_wr_biten; + + always_comb begin + for(int i0=0; i0<24; i0++) begin + decoded_reg_strb.KEY_CTRL[i0] = cpuif_req_masked & (cpuif_addr == 12'h0 + i0*12'h4); + end + for(int i0=0; i0<24; i0++) begin + for(int i1=0; i1<16; i1++) begin + decoded_reg_strb.KEY_ENTRY[i0][i1] = cpuif_req_masked & (cpuif_addr == 12'h600 + i0*12'h40 + i1*12'h4); + end + end + decoded_reg_strb.CLEAR_SECRETS = cpuif_req_masked & (cpuif_addr == 12'hc00); + end + + // Pass down signals to next stage + assign decoded_req = cpuif_req_masked; + assign decoded_req_is_wr = cpuif_req_is_wr; + assign decoded_wr_data = cpuif_wr_data; + assign decoded_wr_biten = cpuif_wr_biten; + + //-------------------------------------------------------------------------- + // Field logic + //-------------------------------------------------------------------------- + typedef struct packed{ + struct packed{ + struct packed{ + logic next; + logic load_next; + } lock_wr; + struct packed{ + logic next; + logic load_next; + } lock_use; + struct packed{ + logic next; + logic load_next; + } clear; + struct packed{ + logic next; + logic load_next; + } rsvd0; + struct packed{ + logic [4:0] next; + logic load_next; + } rsvd1; + struct packed{ + logic [8:0] next; + logic load_next; + } dest_valid; + struct packed{ + logic [3:0] next; + logic load_next; + } last_dword; + } [24-1:0]KEY_CTRL; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } data; + } [24-1:0][16-1:0]KEY_ENTRY; + struct packed{ + struct packed{ + logic next; + logic load_next; + } wr_debug_values; + struct packed{ + logic next; + logic load_next; + } sel_debug_value; + } CLEAR_SECRETS; + } field_combo_t; + field_combo_t field_combo; + + typedef struct packed{ + struct packed{ + struct packed{ + logic value; + } lock_wr; + struct packed{ + logic value; + } lock_use; + struct packed{ + logic value; + } clear; + struct packed{ + logic value; + } rsvd0; + struct packed{ + logic [4:0] value; + } rsvd1; + struct packed{ + logic [8:0] value; + } dest_valid; + struct packed{ + logic [3:0] value; + } last_dword; + } [24-1:0]KEY_CTRL; + struct packed{ + struct packed{ + logic [31:0] value; + } data; + } [24-1:0][16-1:0]KEY_ENTRY; + struct packed{ + struct packed{ + logic value; + } wr_debug_values; + struct packed{ + logic value; + } sel_debug_value; + } CLEAR_SECRETS; + } field_storage_t; + field_storage_t field_storage; + + for(genvar i0=0; i0<24; i0++) begin + // Field: kv_reg.KEY_CTRL[].lock_wr + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.KEY_CTRL[i0].lock_wr.value; + load_next_c = '0; + if(decoded_reg_strb.KEY_CTRL[i0] && decoded_req_is_wr && !(hwif_in.KEY_CTRL[i0].lock_wr.swwel)) begin // SW write + next_c = (field_storage.KEY_CTRL[i0].lock_wr.value & ~decoded_wr_biten[0:0]) | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end + field_combo.KEY_CTRL[i0].lock_wr.next = next_c; + field_combo.KEY_CTRL[i0].lock_wr.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.core_only_rst_b) begin + if(~hwif_in.core_only_rst_b) begin + field_storage.KEY_CTRL[i0].lock_wr.value <= 1'h0; + end else if(field_combo.KEY_CTRL[i0].lock_wr.load_next) begin + field_storage.KEY_CTRL[i0].lock_wr.value <= field_combo.KEY_CTRL[i0].lock_wr.next; + end + end + assign hwif_out.KEY_CTRL[i0].lock_wr.value = field_storage.KEY_CTRL[i0].lock_wr.value; + // Field: kv_reg.KEY_CTRL[].lock_use + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.KEY_CTRL[i0].lock_use.value; + load_next_c = '0; + if(decoded_reg_strb.KEY_CTRL[i0] && decoded_req_is_wr && !(hwif_in.KEY_CTRL[i0].lock_use.swwel)) begin // SW write + next_c = (field_storage.KEY_CTRL[i0].lock_use.value & ~decoded_wr_biten[1:1]) | (decoded_wr_data[1:1] & decoded_wr_biten[1:1]); + load_next_c = '1; + end + field_combo.KEY_CTRL[i0].lock_use.next = next_c; + field_combo.KEY_CTRL[i0].lock_use.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.core_only_rst_b) begin + if(~hwif_in.core_only_rst_b) begin + field_storage.KEY_CTRL[i0].lock_use.value <= 1'h0; + end else if(field_combo.KEY_CTRL[i0].lock_use.load_next) begin + field_storage.KEY_CTRL[i0].lock_use.value <= field_combo.KEY_CTRL[i0].lock_use.next; + end + end + assign hwif_out.KEY_CTRL[i0].lock_use.value = field_storage.KEY_CTRL[i0].lock_use.value; + // Field: kv_reg.KEY_CTRL[].clear + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.KEY_CTRL[i0].clear.value; + load_next_c = '0; + if(decoded_reg_strb.KEY_CTRL[i0] && decoded_req_is_wr) begin // SW write + next_c = (field_storage.KEY_CTRL[i0].clear.value & ~decoded_wr_biten[2:2]) | (decoded_wr_data[2:2] & decoded_wr_biten[2:2]); + load_next_c = '1; + end else begin // singlepulse clears back to 0 + next_c = '0; + load_next_c = '1; + end + field_combo.KEY_CTRL[i0].clear.next = next_c; + field_combo.KEY_CTRL[i0].clear.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.KEY_CTRL[i0].clear.value <= 1'h0; + end else if(field_combo.KEY_CTRL[i0].clear.load_next) begin + field_storage.KEY_CTRL[i0].clear.value <= field_combo.KEY_CTRL[i0].clear.next; + end + end + assign hwif_out.KEY_CTRL[i0].clear.value = field_storage.KEY_CTRL[i0].clear.value; + // Field: kv_reg.KEY_CTRL[].rsvd0 + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.KEY_CTRL[i0].rsvd0.value; + load_next_c = '0; + if(decoded_reg_strb.KEY_CTRL[i0] && decoded_req_is_wr) begin // SW write + next_c = (field_storage.KEY_CTRL[i0].rsvd0.value & ~decoded_wr_biten[3:3]) | (decoded_wr_data[3:3] & decoded_wr_biten[3:3]); + load_next_c = '1; + end else if(hwif_in.KEY_CTRL[i0].rsvd0.hwclr) begin // HW Clear + next_c = '0; + load_next_c = '1; + end + field_combo.KEY_CTRL[i0].rsvd0.next = next_c; + field_combo.KEY_CTRL[i0].rsvd0.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.KEY_CTRL[i0].rsvd0.value <= 1'h0; + end else if(field_combo.KEY_CTRL[i0].rsvd0.load_next) begin + field_storage.KEY_CTRL[i0].rsvd0.value <= field_combo.KEY_CTRL[i0].rsvd0.next; + end + end + assign hwif_out.KEY_CTRL[i0].rsvd0.value = field_storage.KEY_CTRL[i0].rsvd0.value; + // Field: kv_reg.KEY_CTRL[].rsvd1 + always_comb begin + automatic logic [4:0] next_c; + automatic logic load_next_c; + next_c = field_storage.KEY_CTRL[i0].rsvd1.value; + load_next_c = '0; + if(decoded_reg_strb.KEY_CTRL[i0] && decoded_req_is_wr) begin // SW write + next_c = (field_storage.KEY_CTRL[i0].rsvd1.value & ~decoded_wr_biten[8:4]) | (decoded_wr_data[8:4] & decoded_wr_biten[8:4]); + load_next_c = '1; + end + field_combo.KEY_CTRL[i0].rsvd1.next = next_c; + field_combo.KEY_CTRL[i0].rsvd1.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.KEY_CTRL[i0].rsvd1.value <= 5'h0; + end else if(field_combo.KEY_CTRL[i0].rsvd1.load_next) begin + field_storage.KEY_CTRL[i0].rsvd1.value <= field_combo.KEY_CTRL[i0].rsvd1.next; + end + end + assign hwif_out.KEY_CTRL[i0].rsvd1.value = field_storage.KEY_CTRL[i0].rsvd1.value; + // Field: kv_reg.KEY_CTRL[].dest_valid + always_comb begin + automatic logic [8:0] next_c; + automatic logic load_next_c; + next_c = field_storage.KEY_CTRL[i0].dest_valid.value; + load_next_c = '0; + if(hwif_in.KEY_CTRL[i0].dest_valid.we) begin // HW Write - we + next_c = hwif_in.KEY_CTRL[i0].dest_valid.next; + load_next_c = '1; + end else if(hwif_in.KEY_CTRL[i0].dest_valid.hwclr) begin // HW Clear + next_c = '0; + load_next_c = '1; + end + field_combo.KEY_CTRL[i0].dest_valid.next = next_c; + field_combo.KEY_CTRL[i0].dest_valid.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.hard_reset_b) begin + if(~hwif_in.hard_reset_b) begin + field_storage.KEY_CTRL[i0].dest_valid.value <= 9'h0; + end else if(field_combo.KEY_CTRL[i0].dest_valid.load_next) begin + field_storage.KEY_CTRL[i0].dest_valid.value <= field_combo.KEY_CTRL[i0].dest_valid.next; + end + end + assign hwif_out.KEY_CTRL[i0].dest_valid.value = field_storage.KEY_CTRL[i0].dest_valid.value; + // Field: kv_reg.KEY_CTRL[].last_dword + always_comb begin + automatic logic [3:0] next_c; + automatic logic load_next_c; + next_c = field_storage.KEY_CTRL[i0].last_dword.value; + load_next_c = '0; + if(hwif_in.KEY_CTRL[i0].last_dword.we) begin // HW Write - we + next_c = hwif_in.KEY_CTRL[i0].last_dword.next; + load_next_c = '1; + end else if(hwif_in.KEY_CTRL[i0].last_dword.hwclr) begin // HW Clear + next_c = '0; + load_next_c = '1; + end + field_combo.KEY_CTRL[i0].last_dword.next = next_c; + field_combo.KEY_CTRL[i0].last_dword.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.hard_reset_b) begin + if(~hwif_in.hard_reset_b) begin + field_storage.KEY_CTRL[i0].last_dword.value <= 4'h0; + end else if(field_combo.KEY_CTRL[i0].last_dword.load_next) begin + field_storage.KEY_CTRL[i0].last_dword.value <= field_combo.KEY_CTRL[i0].last_dword.next; + end + end + assign hwif_out.KEY_CTRL[i0].last_dword.value = field_storage.KEY_CTRL[i0].last_dword.value; + end + for(genvar i0=0; i0<24; i0++) begin + for(genvar i1=0; i1<16; i1++) begin + // Field: kv_reg.KEY_ENTRY[][].data + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.KEY_ENTRY[i0][i1].data.value; + load_next_c = '0; + if(decoded_reg_strb.KEY_ENTRY[i0][i1] && decoded_req_is_wr && !(hwif_in.KEY_ENTRY[i0][i1].data.swwel)) begin // SW write + next_c = (field_storage.KEY_ENTRY[i0][i1].data.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end else if(hwif_in.KEY_ENTRY[i0][i1].data.we) begin // HW Write - we + next_c = hwif_in.KEY_ENTRY[i0][i1].data.next; + load_next_c = '1; + end else if(hwif_in.KEY_ENTRY[i0][i1].data.hwclr) begin // HW Clear + next_c = '0; + load_next_c = '1; + end + field_combo.KEY_ENTRY[i0][i1].data.next = next_c; + field_combo.KEY_ENTRY[i0][i1].data.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.hard_reset_b) begin + if(~hwif_in.hard_reset_b) begin + field_storage.KEY_ENTRY[i0][i1].data.value <= 32'h0; + end else if(field_combo.KEY_ENTRY[i0][i1].data.load_next) begin + field_storage.KEY_ENTRY[i0][i1].data.value <= field_combo.KEY_ENTRY[i0][i1].data.next; + end + end + assign hwif_out.KEY_ENTRY[i0][i1].data.value = field_storage.KEY_ENTRY[i0][i1].data.value; + end + end + // Field: kv_reg.CLEAR_SECRETS.wr_debug_values + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.CLEAR_SECRETS.wr_debug_values.value; + load_next_c = '0; + if(decoded_reg_strb.CLEAR_SECRETS && decoded_req_is_wr) begin // SW write + next_c = (field_storage.CLEAR_SECRETS.wr_debug_values.value & ~decoded_wr_biten[0:0]) | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end else begin // singlepulse clears back to 0 + next_c = '0; + load_next_c = '1; + end + field_combo.CLEAR_SECRETS.wr_debug_values.next = next_c; + field_combo.CLEAR_SECRETS.wr_debug_values.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.CLEAR_SECRETS.wr_debug_values.value <= 1'h0; + end else if(field_combo.CLEAR_SECRETS.wr_debug_values.load_next) begin + field_storage.CLEAR_SECRETS.wr_debug_values.value <= field_combo.CLEAR_SECRETS.wr_debug_values.next; + end + end + assign hwif_out.CLEAR_SECRETS.wr_debug_values.value = field_storage.CLEAR_SECRETS.wr_debug_values.value; + // Field: kv_reg.CLEAR_SECRETS.sel_debug_value + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.CLEAR_SECRETS.sel_debug_value.value; + load_next_c = '0; + if(decoded_reg_strb.CLEAR_SECRETS && decoded_req_is_wr) begin // SW write + next_c = (field_storage.CLEAR_SECRETS.sel_debug_value.value & ~decoded_wr_biten[1:1]) | (decoded_wr_data[1:1] & decoded_wr_biten[1:1]); + load_next_c = '1; + end + field_combo.CLEAR_SECRETS.sel_debug_value.next = next_c; + field_combo.CLEAR_SECRETS.sel_debug_value.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.CLEAR_SECRETS.sel_debug_value.value <= 1'h0; + end else if(field_combo.CLEAR_SECRETS.sel_debug_value.load_next) begin + field_storage.CLEAR_SECRETS.sel_debug_value.value <= field_combo.CLEAR_SECRETS.sel_debug_value.next; + end + end + assign hwif_out.CLEAR_SECRETS.sel_debug_value.value = field_storage.CLEAR_SECRETS.sel_debug_value.value; + + //-------------------------------------------------------------------------- + // Write response + //-------------------------------------------------------------------------- + assign cpuif_wr_ack = decoded_req & decoded_req_is_wr; + // Writes are always granted with no error response + assign cpuif_wr_err = '0; + + //-------------------------------------------------------------------------- + // Readback + //-------------------------------------------------------------------------- + + logic readback_err; + logic readback_done; + logic [31:0] readback_data; + + // Assign readback values to a flattened array + logic [25-1:0][31:0] readback_array; + for(genvar i0=0; i0<24; i0++) begin + assign readback_array[i0*1 + 0][0:0] = (decoded_reg_strb.KEY_CTRL[i0] && !decoded_req_is_wr) ? field_storage.KEY_CTRL[i0].lock_wr.value : '0; + assign readback_array[i0*1 + 0][1:1] = (decoded_reg_strb.KEY_CTRL[i0] && !decoded_req_is_wr) ? field_storage.KEY_CTRL[i0].lock_use.value : '0; + assign readback_array[i0*1 + 0][2:2] = (decoded_reg_strb.KEY_CTRL[i0] && !decoded_req_is_wr) ? field_storage.KEY_CTRL[i0].clear.value : '0; + assign readback_array[i0*1 + 0][3:3] = (decoded_reg_strb.KEY_CTRL[i0] && !decoded_req_is_wr) ? field_storage.KEY_CTRL[i0].rsvd0.value : '0; + assign readback_array[i0*1 + 0][8:4] = (decoded_reg_strb.KEY_CTRL[i0] && !decoded_req_is_wr) ? field_storage.KEY_CTRL[i0].rsvd1.value : '0; + assign readback_array[i0*1 + 0][17:9] = (decoded_reg_strb.KEY_CTRL[i0] && !decoded_req_is_wr) ? field_storage.KEY_CTRL[i0].dest_valid.value : '0; + assign readback_array[i0*1 + 0][21:18] = (decoded_reg_strb.KEY_CTRL[i0] && !decoded_req_is_wr) ? field_storage.KEY_CTRL[i0].last_dword.value : '0; + assign readback_array[i0*1 + 0][31:22] = '0; + end + assign readback_array[24][0:0] = (decoded_reg_strb.CLEAR_SECRETS && !decoded_req_is_wr) ? field_storage.CLEAR_SECRETS.wr_debug_values.value : '0; + assign readback_array[24][1:1] = (decoded_reg_strb.CLEAR_SECRETS && !decoded_req_is_wr) ? field_storage.CLEAR_SECRETS.sel_debug_value.value : '0; + assign readback_array[24][31:2] = '0; + + // Reduce the array + always_comb begin + automatic logic [31:0] readback_data_var; + readback_done = decoded_req & ~decoded_req_is_wr; + readback_err = '0; + readback_data_var = '0; + for(int i=0; i<25; i++) readback_data_var |= readback_array[i]; + readback_data = readback_data_var; + end + + assign cpuif_rd_ack = readback_done; + assign cpuif_rd_data = readback_data; + assign cpuif_rd_err = readback_err; + +`CALIPTRA_ASSERT_KNOWN(ERR_HWIF_IN, hwif_in, clk, !hwif_in.hard_reset_b) + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/kv_reg_pkg.sv b/designs/Caliptra/src/caliptra-rtl/kv_reg_pkg.sv new file mode 100644 index 0000000..71339d0 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/kv_reg_pkg.sv @@ -0,0 +1,127 @@ +// Generated by PeakRDL-regblock - A free and open-source SystemVerilog generator +// https://github.com/SystemRDL/PeakRDL-regblock + +package kv_reg_pkg; + + localparam KV_REG_DATA_WIDTH = 32; + localparam KV_REG_MIN_ADDR_WIDTH = 12; + + typedef struct packed{ + logic swwel; + } kv_reg__kvCtrl__lock_wr__in_t; + + typedef struct packed{ + logic swwel; + } kv_reg__kvCtrl__lock_use__in_t; + + typedef struct packed{ + logic hwclr; + } kv_reg__kvCtrl__rsvd0__in_t; + + typedef struct packed{ + logic [8:0] next; + logic we; + logic hwclr; + } kv_reg__kvCtrl__dest_valid__in_t; + + typedef struct packed{ + logic [3:0] next; + logic we; + logic hwclr; + } kv_reg__kvCtrl__last_dword__in_t; + + typedef struct packed{ + kv_reg__kvCtrl__lock_wr__in_t lock_wr; + kv_reg__kvCtrl__lock_use__in_t lock_use; + kv_reg__kvCtrl__rsvd0__in_t rsvd0; + kv_reg__kvCtrl__dest_valid__in_t dest_valid; + kv_reg__kvCtrl__last_dword__in_t last_dword; + } kv_reg__kvCtrl__in_t; + + typedef struct packed{ + logic [31:0] next; + logic we; + logic swwel; + logic hwclr; + } kv_reg__key_w32__in_t; + + typedef struct packed{ + kv_reg__key_w32__in_t data; + } kv_reg__keyReg__in_t; + + typedef struct packed{ + logic reset_b; + logic core_only_rst_b; + logic hard_reset_b; + kv_reg__kvCtrl__in_t [24-1:0]KEY_CTRL; + kv_reg__keyReg__in_t [24-1:0][16-1:0]KEY_ENTRY; + } kv_reg__in_t; + + typedef struct packed{ + logic value; + } kv_reg__kvCtrl__lock_wr__out_t; + + typedef struct packed{ + logic value; + } kv_reg__kvCtrl__lock_use__out_t; + + typedef struct packed{ + logic value; + } kv_reg__kvCtrl__clear__out_t; + + typedef struct packed{ + logic value; + } kv_reg__kvCtrl__rsvd0__out_t; + + typedef struct packed{ + logic [4:0] value; + } kv_reg__kvCtrl__rsvd1__out_t; + + typedef struct packed{ + logic [8:0] value; + } kv_reg__kvCtrl__dest_valid__out_t; + + typedef struct packed{ + logic [3:0] value; + } kv_reg__kvCtrl__last_dword__out_t; + + typedef struct packed{ + kv_reg__kvCtrl__lock_wr__out_t lock_wr; + kv_reg__kvCtrl__lock_use__out_t lock_use; + kv_reg__kvCtrl__clear__out_t clear; + kv_reg__kvCtrl__rsvd0__out_t rsvd0; + kv_reg__kvCtrl__rsvd1__out_t rsvd1; + kv_reg__kvCtrl__dest_valid__out_t dest_valid; + kv_reg__kvCtrl__last_dword__out_t last_dword; + } kv_reg__kvCtrl__out_t; + + typedef struct packed{ + logic [31:0] value; + } kv_reg__key_w32__out_t; + + typedef struct packed{ + kv_reg__key_w32__out_t data; + } kv_reg__keyReg__out_t; + + typedef struct packed{ + logic value; + } kv_reg__CLEAR_SECRETS__wr_debug_values__out_t; + + typedef struct packed{ + logic value; + } kv_reg__CLEAR_SECRETS__sel_debug_value__out_t; + + typedef struct packed{ + kv_reg__CLEAR_SECRETS__wr_debug_values__out_t wr_debug_values; + kv_reg__CLEAR_SECRETS__sel_debug_value__out_t sel_debug_value; + } kv_reg__CLEAR_SECRETS__out_t; + + typedef struct packed{ + kv_reg__kvCtrl__out_t [24-1:0]KEY_CTRL; + kv_reg__keyReg__out_t [24-1:0][16-1:0]KEY_ENTRY; + kv_reg__CLEAR_SECRETS__out_t CLEAR_SECRETS; + } kv_reg__out_t; + + localparam KV_REG_ADDR_WIDTH = 32'd12; + +endpackage \ No newline at end of file diff --git a/designs/Caliptra/src/caliptra-rtl/kv_write_client.sv b/designs/Caliptra/src/caliptra-rtl/kv_write_client.sv new file mode 100644 index 0000000..13377c1 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/kv_write_client.sv @@ -0,0 +1,127 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +// +//`include "kv_defines.svh" +`include "caliptra_prim_assert.sv" + +module kv_write_client + import kv_defines_pkg::*; + #( + parameter DATA_WIDTH = 512 + ,parameter KV_WRITE_SWAP_DWORDS = 1 + ,localparam DATA_OFFSET_W = $clog2(DATA_WIDTH/32) + ,localparam DATA_NUM_DWORDS = (DATA_WIDTH/32) + +) +( + input logic clk, + input logic rst_b, + input logic zeroize, + + input logic [DATA_OFFSET_W:0] num_dwords, + + //client control register + input kv_write_ctrl_reg_t write_ctrl_reg, + + //access filtering rule metrics + //NOTE: must be stabilized 1 clock cycle prior to dest_data_avail + input var kv_write_filter_metrics_t write_metrics, + + //interface with kv + output kv_write_t kv_write, + input kv_wr_resp_t kv_resp, + + //interface with client + output logic dest_keyvault, + input logic dest_data_avail, + input logic [DATA_NUM_DWORDS-1:0][31:0] dest_data, + + output kv_error_code_e error_code, + output logic kv_ready, + output logic dest_done +); + +logic write_allow; + +logic [DATA_OFFSET_W-1:0] dest_read_offset; +logic [DATA_OFFSET_W-1:0] dest_write_offset; +logic dest_write_en; +logic [31:0] pad_data; +logic write_pad; +logic write_last; + +kv_write_rule_check kv_write_rules +( + .clk (clk ), + .rst_b(rst_b), + + .write_metrics(write_metrics), + .write_allow (write_allow ) +); + +//dest write block +kv_fsm #( + .DATA_WIDTH(DATA_WIDTH), + .PAD(0) +) +kv_dest_write_fsm +( + .clk(clk), + .rst_b(rst_b), + .zeroize(zeroize), + .start(dest_data_avail & write_ctrl_reg.write_en), + .allow(write_allow), + .last('0), + .pcr_hash_extend(1'b0), + .num_dwords(num_dwords), + .read_offset(dest_read_offset), + .write_en(dest_write_en), + .write_offset(dest_write_offset), + .write_pad(write_pad), + .write_last(write_last), + .pad_data(pad_data), + .ready(kv_ready), + .done(dest_done) +); + +always_comb dest_keyvault = write_ctrl_reg.write_en; + +always_comb kv_write.write_entry = write_ctrl_reg.write_entry; +always_comb kv_write.write_offset = KV_ENTRY_SIZE_W'(dest_write_offset); +always_comb kv_write.write_en = dest_write_en; +always_comb kv_write.write_data = KV_WRITE_SWAP_DWORDS ? dest_data[(DATA_NUM_DWORDS-1) - dest_read_offset] : dest_data[dest_read_offset]; +//write zeroes here until last cycle +always_comb kv_write.write_dest_valid = write_last ? write_ctrl_reg.write_dest_vld : '0; + +always_ff @(posedge clk or negedge rst_b) begin + if (!rst_b) begin + error_code <= KV_SUCCESS; + end + else if (zeroize) begin + error_code <= KV_SUCCESS; + end + else begin + // On first beat of kv write, latch any error conditions. + // On subsequent beats of kv write, preserve any error that was previously + // flagged or decode new error conditions + error_code <= dest_write_en && |dest_write_offset && (error_code != KV_SUCCESS) ? error_code : + dest_data_avail & write_ctrl_reg.write_en & !write_allow ? KV_WRITE_FAIL : + dest_write_en & kv_resp.error ? KV_WRITE_FAIL : + dest_write_en & ~kv_resp.error ? KV_SUCCESS : error_code; + end +end + +`CALIPTRA_ASSERT_KNOWN(WRITE_METRICS_X, write_metrics, clk, !rst_b) + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/kv_write_rule_check.sv b/designs/Caliptra/src/caliptra-rtl/kv_write_rule_check.sv new file mode 100644 index 0000000..5e115a9 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/kv_write_rule_check.sv @@ -0,0 +1,104 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +// + +module kv_write_rule_check +import kv_defines_pkg::*; +( + input logic clk, + input logic rst_b, + + input var kv_write_filter_metrics_t write_metrics, + output logic write_allow +); + + + // --------------------------------------- // + // Signals // + // --------------------------------------- // + struct packed { + logic aes_only_to_key_release; // NO crypto other than AES can write to key release slot + logic std_to_std; // Standard slot inputs can only write to standard outputs + logic lock_to_lock; // OCP Lock slot inputs can only write to OCP Lock outputs + logic aes_dec_to_rt_obf_key; + } rule_fail; + + + // --------------------------------------- // + // Rules // + // --------------------------------------- // + // IF (OCP_LOCK_IN_PROGRESS) + // THEN (NO CRYPTO may write to OCP_LOCK_KEY_RELEASE_KV_SLOT, other than AES) + always_comb begin + rule_fail.aes_only_to_key_release = write_metrics.ocp_lock_in_progress && + // Any write source indicated (other than AES) causes rule failure + |(write_metrics.kv_write_src & ~(KV_NUM_WRITE'(1) << KV_WRITE_IDX_AES)) && + write_metrics.kv_write_entry == OCP_LOCK_KEY_RELEASE_KV_SLOT; + end + + // IF (OCP_LOCK_IN_PROGRESS) AND (input inside [STD region]) + // THEN (dest = [STD region]) + always_comb begin + rule_fail.std_to_std = write_metrics.ocp_lock_in_progress && + ((write_metrics.kv_data0_present && + write_metrics.kv_data0_entry inside {[KV_STANDARD_SLOT_LOW:KV_STANDARD_SLOT_HI]}) || + (write_metrics.kv_data1_present && + write_metrics.kv_data1_entry inside {[KV_STANDARD_SLOT_LOW:KV_STANDARD_SLOT_HI]})) && + !(write_metrics.kv_write_entry inside {[KV_STANDARD_SLOT_LOW:KV_STANDARD_SLOT_HI]}); + end + + // IF (OCP_LOCK_IN_PROGRESS) AND (input inside [LOCK region]) + // THEN (dest = [LOCK region]) + always_comb begin + rule_fail.lock_to_lock = write_metrics.ocp_lock_in_progress && + ((write_metrics.kv_data0_present && + write_metrics.kv_data0_entry inside {[KV_OCP_LOCK_SLOT_LOW:KV_OCP_LOCK_SLOT_HI]}) || + (write_metrics.kv_data1_present && + write_metrics.kv_data1_entry inside {[KV_OCP_LOCK_SLOT_LOW:KV_OCP_LOCK_SLOT_HI]})) && + !(write_metrics.kv_write_entry inside {[KV_OCP_LOCK_SLOT_LOW:KV_OCP_LOCK_SLOT_HI]}); + end + + // NOTE: This rule also needs to work in reverse, i.e. if AES is doing a KV write, then + // all of these conditions must be met. + // Therefore, this implementation fails if any condition is not met. + // IF (OCP_LOCK_IN_PROGRESS) AND (AES ECB decrypt) AND (key = OCP_LOCK_RT_OBF_KEY_KV_SLOT) + // THEN (dest = OCP_LOCK_KEY_RELEASE_KV_SLOT) + // ELSEIF (AES any other op) + // THEN (dest = FW) + // NOTE: aes.sv enforces this rule by blocking the register output when kv write is expected due to input criteria being met + always_comb begin + rule_fail.aes_dec_to_rt_obf_key = write_metrics.kv_write_src[KV_WRITE_IDX_AES] && + (!write_metrics.ocp_lock_in_progress || + !write_metrics.aes_decrypt_ecb_op || + !write_metrics.kv_data0_present || + write_metrics.kv_data0_entry != OCP_LOCK_RT_OBF_KEY_KV_SLOT || + write_metrics.kv_write_entry != OCP_LOCK_KEY_RELEASE_KV_SLOT); + end + + + // --------------------------------------- // + // Output // + // --------------------------------------- // + // Register the rule-check status; all of the input metrics will be stabilized long before dest write data + // becomes valid, so registering the output status reduces combinatorial depth + always_ff@(posedge clk or negedge rst_b) begin + if (!rst_b) begin + write_allow <= 1'b0; + end + else begin + write_allow <= ~|rule_fail; + end + end + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/lc_ctrl_pkg.sv b/designs/Caliptra/src/caliptra-rtl/lc_ctrl_pkg.sv new file mode 100644 index 0000000..e922293 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/lc_ctrl_pkg.sv @@ -0,0 +1,383 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// + +`include "caliptra_prim_assert.sv" + +package lc_ctrl_pkg; + + import caliptra_prim_util_pkg::vbits; + import lc_ctrl_state_pkg::*; + + /////////////////////////////////////// + // Netlist Constants (Hashed Tokens) // + /////////////////////////////////////// + + parameter int NumTokens = 8; + parameter int TokenIdxWidth = vbits(NumTokens); + typedef enum logic [TokenIdxWidth-1:0] { + // This is the index for the hashed all-zero constant. + // All unconditional transitions use this token. + ZeroTokenIdx = 3'h0, + RawUnlockTokenIdx = 3'h1, + TestUnlockTokenIdx = 3'h2, + TestExitDevTokenIdx = 3'h3, + DevExitProdTokenIdx = 3'h4, + ProdExitProdEndTokenIdx = 3'h5, + RmaTokenIdx = 3'h6, + // This is the index for an all-zero value (i.e., hashed value = '0). + // This is used as an additional blocker for some invalid state transition edges. + InvalidTokenIdx = 3'h7 + } token_idx_e; + + parameter int TokenMuxBits = 2**TokenIdxWidth*LcTokenWidth; + typedef logic [TokenMuxBits-1:0] lc_token_mux_t; + + //////////////////////////////// + // Typedefs for LC Interfaces // + //////////////////////////////// + + parameter int TxWidth = 4; + + // Note that changing this encoding has implications on isolation cell + // values in RTL. Do not change this unless absolutely needed. + /* + typedef enum logic [TxWidth-1:0] { + On = 4'b0101, + Off = 4'b1010 + } lc_tx_t; + */ + typedef logic [TxWidth-1:0] lc_tx_t; + parameter lc_tx_t On = 4'b0101; + parameter lc_tx_t Off = 4'b1010; + + parameter lc_tx_t LC_TX_DEFAULT = lc_tx_t'(Off); + + parameter int RmaSeedWidth = 32; + typedef logic [RmaSeedWidth-1:0] lc_flash_rma_seed_t; + parameter lc_flash_rma_seed_t LC_FLASH_RMA_SEED_DEFAULT = '0; + + parameter int LcKeymgrDivWidth = 128; + typedef logic [LcKeymgrDivWidth-1:0] lc_keymgr_div_t; + + typedef struct packed { + logic [lc_ctrl_reg_pkg::SiliconCreatorIdWidth-1:0] silicon_creator_id; + logic [lc_ctrl_reg_pkg::ProductIdWidth-1:0] product_id; + logic [lc_ctrl_reg_pkg::RevisionIdWidth-1:0] revision_id; + logic [32-lc_ctrl_reg_pkg::RevisionIdWidth-1:0] reserved; + } lc_hw_rev_t; + + ///////////////////////////////////////////// + // Helper Functions for Life Cycle Signals // + ///////////////////////////////////////////// + + // This is a prerequisite for the multibit functions below to work. + `CALIPTRA_ASSERT_STATIC_IN_PACKAGE(CheckLcTxValsComplementary_A, On == ~Off) + // Check for bit-width matching between lc_tx_t and mubi4_t + `CALIPTRA_ASSERT_STATIC_IN_PACKAGE(LcMuBiWidthCheck_A, $bits(TxWidth) == $bits(caliptra_prim_mubi_pkg::MuBi4Width)) + + // Convert a life cycle signal to mubi4 + // If in the future other versions are desired, this should really be + // moved to caliptra_prim_mubi_pkg + // + // The On ^ MuBi4True determines the bit differences between + // an lc_ctrl_pkg::On and caliptra_prim_mubi_pkg::MuBi4True. + // Once the required inversions are determined, it is then applied + // to the incoming value. If the incoming value is true, it will + // appropriately flip to the correct MuBiValue. + // Since the false value is always complement of the true value, + // this mechanism will also work for the other polarity. + function automatic caliptra_prim_mubi_pkg::mubi4_t lc_to_mubi4(lc_tx_t val); + return caliptra_prim_mubi_pkg::mubi4_t'(val ^ (On ^ caliptra_prim_mubi_pkg::MuBi4True)); + endfunction : lc_to_mubi4 + + function automatic lc_tx_t mubi4_to_lc(caliptra_prim_mubi_pkg::mubi4_t val); + return lc_tx_t'(val ^ (caliptra_prim_mubi_pkg::MuBi4True ^ On)); + endfunction : mubi4_to_lc + + // same function as above, but for an input that is MuBi4True, return Off + // for an input that is MuBi4False, return On + function automatic lc_tx_t mubi4_to_lc_inv(caliptra_prim_mubi_pkg::mubi4_t val); + return lc_tx_t'(val ^ (caliptra_prim_mubi_pkg::MuBi4True ^ Off)); + endfunction : mubi4_to_lc_inv + + // Test whether the value is supplied is one of the valid enumerations + function automatic logic lc_tx_test_invalid(lc_tx_t val); + return ~(val inside {On, Off}); + endfunction : lc_tx_test_invalid + + // Convert a 1 input value to a lc_tx output + function automatic lc_tx_t lc_tx_bool_to_lc_tx(logic val); + return (val ? On : Off); + endfunction : lc_tx_bool_to_lc_tx + + // Test whether the multibit value signals an "enabled" condition. + // The strict version of this function requires + // the multibit value to equal True. + function automatic logic lc_tx_test_true_strict(lc_tx_t val); + return On == val; + endfunction : lc_tx_test_true_strict + + // Test whether the multibit value signals a "disabled" condition. + // The strict version of this function requires + // the multibit value to equal False. + function automatic logic lc_tx_test_false_strict(lc_tx_t val); + return Off == val; + endfunction : lc_tx_test_false_strict + + // Test whether the multibit value signals an "enabled" condition. + // The loose version of this function interprets all + // values other than False as "enabled". + function automatic logic lc_tx_test_true_loose(lc_tx_t val); + return Off != val; + endfunction : lc_tx_test_true_loose + + // Test whether the multibit value signals a "disabled" condition. + // The loose version of this function interprets all + // values other than True as "disabled". + function automatic logic lc_tx_test_false_loose(lc_tx_t val); + return On != val; + endfunction : lc_tx_test_false_loose + + + // Performs a logical OR operation between two multibit values. + // This treats "act" as logical 1, and all other values are + // treated as 0. Truth table: + // + // A | B | OUT + //------+------+----- + // !act | !act | !act + // act | !act | act + // !act | act | act + // act | act | act + // + // Note: due to the nature of the lc_tx_or() function, it is possible that two + // non-strictly "act" values may produce a strictly "act" value. If this is + // of concern, e.g. if the output is consumed with a strict check on "act", + // consider using the caliptra_prim_lc_or_hardened primitive instead. + function automatic lc_tx_t lc_tx_or(lc_tx_t a, lc_tx_t b, lc_tx_t act); + logic [TxWidth-1:0] a_in, b_in, act_in, out; + a_in = a; + b_in = b; + act_in = act; + for (int k = 0; k < TxWidth; k++) begin + if (act_in[k]) begin + out[k] = a_in[k] || b_in[k]; + end else begin + out[k] = a_in[k] && b_in[k]; + end + end + return lc_tx_t'(out); + endfunction : lc_tx_or + + // Performs a logical AND operation between two multibit values. + // This treats "act" as logical 1, and all other values are + // treated as 0. Truth table: + // + // A | B | OUT + //------+------+----- + // !act | !act | !act + // act | !act | !act + // !act | act | !act + // act | act | act + // + // Noite: The lc_tx_and() function does not suffer from the strictness problem + // that the lc_tx_or function above does, since only one output value in the + // truth table is strictly "act". It can hence be used in most scenarios without issues. + // If however the lc_tx_and() function should be strictly rectifying (i.e., only + // output "act" or ~"act"), the caliptra_prim_lc_and_hardened can be used. + function automatic lc_tx_t lc_tx_and(lc_tx_t a, lc_tx_t b, lc_tx_t act); + logic [TxWidth-1:0] a_in, b_in, act_in, out; + a_in = a; + b_in = b; + act_in = act; + for (int k = 0; k < TxWidth; k++) begin + if (act_in[k]) begin + out[k] = a_in[k] && b_in[k]; + end else begin + out[k] = a_in[k] || b_in[k]; + end + end + return lc_tx_t'(out); + endfunction : lc_tx_and + + // Performs a logical OR operation between two multibit values. + // This treats "True" as logical 1, and all other values are + // treated as 0. + function automatic lc_tx_t lc_tx_or_hi(lc_tx_t a, lc_tx_t b); + return lc_tx_or(a, b, On); + endfunction : lc_tx_or_hi + + // Performs a logical AND operation between two multibit values. + // This treats "True" as logical 1, and all other values are + // treated as 0. + function automatic lc_tx_t lc_tx_and_hi(lc_tx_t a, lc_tx_t b); + return lc_tx_and(a, b, On); + endfunction : lc_tx_and_hi + + // Performs a logical OR operation between two multibit values. + // This treats "False" as logical 1, and all other values are + // treated as 0. + function automatic lc_tx_t lc_tx_or_lo(lc_tx_t a, lc_tx_t b); + return lc_tx_or(a, b, Off); + endfunction : lc_tx_or_lo + + // Performs a logical AND operation between two multibit values. + // Tlos treats "False" as logical 1, and all other values are + // treated as 0. + function automatic lc_tx_t lc_tx_and_lo(lc_tx_t a, lc_tx_t b); + return lc_tx_and(a, b, Off); + endfunction : lc_tx_and_lo + + // Inverts the logical meaning of the multibit value. + function automatic lc_tx_t lc_tx_inv(lc_tx_t a); + return lc_tx_t'(~TxWidth'(a)); + endfunction : lc_tx_inv + + //////////////////// + // Main FSM State // + //////////////////// + + // SEC_CM: MAIN.FSM.SPARSE + // Encoding generated with: + // $ ./util/design/sparse-fsm-encode.py -d 5 -m 15 -n 16 \ + // -s 2934212379 --language=sv + // + // Hamming distance histogram: + // + // 0: -- + // 1: -- + // 2: -- + // 3: -- + // 4: -- + // 5: ||||||| (7.62%) + // 6: ||||||||| (9.52%) + // 7: |||||||||||||||| (17.14%) + // 8: |||||||||||||||||||| (20.95%) + // 9: ||||||||||||||||| (18.10%) + // 10: ||||||||||||| (14.29%) + // 11: |||||| (6.67%) + // 12: ||| (3.81%) + // 13: | (1.90%) + // 14: -- + // 15: -- + // 16: -- + // + // Minimum Hamming distance: 5 + // Maximum Hamming distance: 13 + // Minimum Hamming weight: 3 + // Maximum Hamming weight: 11 + // + localparam int FsmStateWidth = 16; + typedef enum logic [FsmStateWidth-1:0] { + ResetSt = 16'b1111011010111100, + IdleSt = 16'b0000011110101101, + ClkMuxSt = 16'b1100111011001001, + CntIncrSt = 16'b0011001111000111, + CntProgSt = 16'b0000110001010100, + TransCheckSt = 16'b0110111010110000, + TokenHashSt = 16'b1101001000111111, + FlashRmaSt = 16'b1110100010001111, + TokenCheck0St = 16'b0010000011000000, + TokenCheck1St = 16'b1101010101101111, + TransProgSt = 16'b1000000110101011, + PostTransSt = 16'b0110110100101100, + ScrapSt = 16'b1010100001010001, + EscalateSt = 16'b1011110110011011, + InvalidSt = 16'b0011000101001100 + } fsm_state_e; + + /////////////////////////////////////////// + // Manufacturing State Transition Matrix // + /////////////////////////////////////////// + + // Helper macro to assemble the token index matrix below. + // From TEST_UNLOCKED(N) + // -> SCRAP, RMA + // -> PROD, PROD_END, DEV + // -> TEST_UNLOCKED(N+1)-7 + // -> TEST_LOCKED(N)-6 + // -> TEST_UNLOCKED0-(N), RAW + `define TEST_UNLOCKED(idx) \ + {2{ZeroTokenIdx}}, \ + {ProdExitProdEndTokenIdx}, \ + {DevExitProdTokenIdx}, \ + {TestExitDevTokenIdx}, \ + {(7-idx){InvalidTokenIdx, \ + ZeroTokenIdx}}, \ + {(2*idx+2){InvalidTokenIdx}} + + // Helper macro to assemble the token index matrix below. + // From TEST_LOCKED(N) + // -> SCRAP + // -> RMA + // -> PROD, PROD_END, DEV + // -> TEST_UNLOCKED(N+1)-7 + // -> TEST_LOCKED(N)-6 + // -> TEST_UNLOCKED0-(N), RAW + `define TEST_LOCKED(idx) \ + ZeroTokenIdx, \ + InvalidTokenIdx, \ + {ProdExitProdEndTokenIdx}, \ + {DevExitProdTokenIdx}, \ + {TestExitDevTokenIdx}, \ + {(7-idx){TestUnlockTokenIdx, \ + InvalidTokenIdx}}, \ + {(2*idx+2){InvalidTokenIdx}} + + // The token index matrix below encodes 1) which transition edges are valid and 2) which token + // to use for a given transition edge. Note that unconditional but otherwise valid transitions + // are assigned the ZeroTokenIdx, whereas invalid transitions are assigned an InvalidTokenIdx. + parameter token_idx_e [NumLcStates-1:0][NumLcStates-1:0] TransTokenIdxMatrix = { + // SCRAP + {21{InvalidTokenIdx}}, // -> TEST_LOCKED0-6, TEST_UNLOCKED0-7, DEV, PROD, PROD_END, RMA, SCRAP + // RMA + ZeroTokenIdx, // -> SCRAP + {20{InvalidTokenIdx}}, // -> TEST_LOCKED0-6, TEST_UNLOCKED0-7, DEV, PROD, PROD_END, RMA + // PROD_END + ZeroTokenIdx, // -> SCRAP + {20{InvalidTokenIdx}}, // -> TEST_LOCKED0-6, TEST_UNLOCKED0-7, DEV, PROD, PROD_END, RMA + // PROD + ZeroTokenIdx, // -> SCRAP + RmaTokenIdx, // -> RMA + ProdExitProdEndTokenIdx, // -> PROD_END + {18{InvalidTokenIdx}}, // -> TEST_LOCKED0-6, TEST_UNLOCKED0-7, DEV, PROD, PROD_END + // DEV + ZeroTokenIdx, // -> SCRAP + RmaTokenIdx, // -> RMA + // {19{InvalidTokenIdx}}, // -> TEST_LOCKED0-6, TEST_UNLOCKED0-7, DEV, PROD, PROD_END + // ============== This is how we enable from DEV to PROD ============================== + ProdExitProdEndTokenIdx, // -> PROD_END + DevExitProdTokenIdx, // -> PROD + {17{InvalidTokenIdx}}, // -> TEST_LOCKED0-6, TEST_UNLOCKED0-7, DEV + // ==================================================================================== + + // TEST_UNLOCKED0-7, TEST_LOCKED0-6 + `TEST_UNLOCKED(7), + `TEST_LOCKED(6), + `TEST_UNLOCKED(6), + `TEST_LOCKED(5), + `TEST_UNLOCKED(5), + `TEST_LOCKED(4), + `TEST_UNLOCKED(4), + `TEST_LOCKED(3), + `TEST_UNLOCKED(3), + `TEST_LOCKED(2), + `TEST_UNLOCKED(2), + `TEST_LOCKED(1), + `TEST_UNLOCKED(1), + `TEST_LOCKED(0), + `TEST_UNLOCKED(0), + // RAW + ZeroTokenIdx, // -> SCRAP + {4{InvalidTokenIdx}}, // -> RMA, PROD, PROD_END, DEV + {8{RawUnlockTokenIdx, // -> TEST_UNLOCKED0-7 + InvalidTokenIdx}} // -> RAW, TEST_LOCKED0-6 + }; + + // These macros are only used locally. + `undef TEST_LOCKED + `undef TEST_UNLOCKED + +endpackage : lc_ctrl_pkg diff --git a/designs/Caliptra/src/caliptra-rtl/lc_ctrl_reg_pkg.sv b/designs/Caliptra/src/caliptra-rtl/lc_ctrl_reg_pkg.sv new file mode 100644 index 0000000..285cfa3 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/lc_ctrl_reg_pkg.sv @@ -0,0 +1,379 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Register Package auto-generated by `reggen` containing data structure + +package lc_ctrl_reg_pkg; + + // Param list + parameter int SiliconCreatorIdWidth = 16; + parameter int ProductIdWidth = 16; + parameter int RevisionIdWidth = 8; + parameter int NumTokenWords = 4; + parameter int CsrLcStateWidth = 30; + parameter int CsrLcCountWidth = 5; + parameter int CsrLcIdStateWidth = 32; + parameter int CsrOtpTestCtrlWidth = 32; + parameter int CsrOtpTestStatusWidth = 32; + parameter int NumDeviceIdWords = 8; + parameter int NumManufStateWords = 8; + parameter int NumRmaAckSigs = 2; + parameter int NumAlerts = 3; + + // Address widths within the block + parameter int BlockAw = 8; + + //////////////////////////// + // Typedefs for registers // + //////////////////////////// + + typedef struct packed { + struct packed { + logic q; + logic qe; + } fatal_bus_integ_error; + struct packed { + logic q; + logic qe; + } fatal_state_error; + struct packed { + logic q; + logic qe; + } fatal_prog_error; + } lc_ctrl_reg2hw_alert_test_reg_t; + + typedef struct packed { + logic [7:0] q; + logic qe; + } lc_ctrl_reg2hw_claim_transition_if_reg_t; + + typedef struct packed { + logic q; + logic qe; + } lc_ctrl_reg2hw_transition_cmd_reg_t; + + typedef struct packed { + struct packed { + logic q; + logic qe; + } volatile_raw_unlock; + struct packed { + logic q; + logic qe; + } ext_clock_en; + } lc_ctrl_reg2hw_transition_ctrl_reg_t; + + typedef struct packed { + logic [31:0] q; + logic qe; + } lc_ctrl_reg2hw_transition_token_mreg_t; + + typedef struct packed { + logic [29:0] q; + logic qe; + } lc_ctrl_reg2hw_transition_target_reg_t; + + typedef struct packed { + logic [31:0] q; + logic qe; + } lc_ctrl_reg2hw_otp_vendor_test_ctrl_reg_t; + + typedef struct packed { + struct packed { + logic d; + } initialized; + struct packed { + logic d; + } ready; + struct packed { + logic d; + } ext_clock_switched; + struct packed { + logic d; + } transition_successful; + struct packed { + logic d; + } transition_count_error; + struct packed { + logic d; + } transition_error; + struct packed { + logic d; + } token_error; + struct packed { + logic d; + } flash_rma_error; + struct packed { + logic d; + } otp_error; + struct packed { + logic d; + } state_error; + struct packed { + logic d; + } bus_integ_error; + struct packed { + logic d; + } otp_partition_error; + } lc_ctrl_hw2reg_status_reg_t; + + typedef struct packed { + logic [7:0] d; + } lc_ctrl_hw2reg_claim_transition_if_reg_t; + + typedef struct packed { + logic d; + } lc_ctrl_hw2reg_transition_regwen_reg_t; + + typedef struct packed { + struct packed { + logic d; + } ext_clock_en; + struct packed { + logic d; + } volatile_raw_unlock; + } lc_ctrl_hw2reg_transition_ctrl_reg_t; + + typedef struct packed { + logic [31:0] d; + } lc_ctrl_hw2reg_transition_token_mreg_t; + + typedef struct packed { + logic [29:0] d; + } lc_ctrl_hw2reg_transition_target_reg_t; + + typedef struct packed { + logic [31:0] d; + } lc_ctrl_hw2reg_otp_vendor_test_ctrl_reg_t; + + typedef struct packed { + logic [31:0] d; + } lc_ctrl_hw2reg_otp_vendor_test_status_reg_t; + + typedef struct packed { + logic [29:0] d; + } lc_ctrl_hw2reg_lc_state_reg_t; + + typedef struct packed { + logic [4:0] d; + } lc_ctrl_hw2reg_lc_transition_cnt_reg_t; + + typedef struct packed { + logic [31:0] d; + } lc_ctrl_hw2reg_lc_id_state_reg_t; + + typedef struct packed { + struct packed { + logic [15:0] d; + } product_id; + struct packed { + logic [15:0] d; + } silicon_creator_id; + } lc_ctrl_hw2reg_hw_revision0_reg_t; + + typedef struct packed { + struct packed { + logic [7:0] d; + } revision_id; + struct packed { + logic [23:0] d; + } reserved; + } lc_ctrl_hw2reg_hw_revision1_reg_t; + + typedef struct packed { + logic [31:0] d; + } lc_ctrl_hw2reg_device_id_mreg_t; + + typedef struct packed { + logic [31:0] d; + } lc_ctrl_hw2reg_manuf_state_mreg_t; + + // Register -> HW type + typedef struct packed { + lc_ctrl_reg2hw_alert_test_reg_t alert_test; // [216:211] + lc_ctrl_reg2hw_claim_transition_if_reg_t claim_transition_if; // [210:202] + lc_ctrl_reg2hw_transition_cmd_reg_t transition_cmd; // [201:200] + lc_ctrl_reg2hw_transition_ctrl_reg_t transition_ctrl; // [199:196] + lc_ctrl_reg2hw_transition_token_mreg_t [3:0] transition_token; // [195:64] + lc_ctrl_reg2hw_transition_target_reg_t transition_target; // [63:33] + lc_ctrl_reg2hw_otp_vendor_test_ctrl_reg_t otp_vendor_test_ctrl; // [32:0] + } lc_ctrl_reg2hw_t; + + // HW -> register type + typedef struct packed { + lc_ctrl_hw2reg_status_reg_t status; // [887:876] + lc_ctrl_hw2reg_claim_transition_if_reg_t claim_transition_if; // [875:868] + lc_ctrl_hw2reg_transition_regwen_reg_t transition_regwen; // [867:867] + lc_ctrl_hw2reg_transition_ctrl_reg_t transition_ctrl; // [866:865] + lc_ctrl_hw2reg_transition_token_mreg_t [3:0] transition_token; // [864:737] + lc_ctrl_hw2reg_transition_target_reg_t transition_target; // [736:707] + lc_ctrl_hw2reg_otp_vendor_test_ctrl_reg_t otp_vendor_test_ctrl; // [706:675] + lc_ctrl_hw2reg_otp_vendor_test_status_reg_t otp_vendor_test_status; // [674:643] + lc_ctrl_hw2reg_lc_state_reg_t lc_state; // [642:613] + lc_ctrl_hw2reg_lc_transition_cnt_reg_t lc_transition_cnt; // [612:608] + lc_ctrl_hw2reg_lc_id_state_reg_t lc_id_state; // [607:576] + lc_ctrl_hw2reg_hw_revision0_reg_t hw_revision0; // [575:544] + lc_ctrl_hw2reg_hw_revision1_reg_t hw_revision1; // [543:512] + lc_ctrl_hw2reg_device_id_mreg_t [7:0] device_id; // [511:256] + lc_ctrl_hw2reg_manuf_state_mreg_t [7:0] manuf_state; // [255:0] + } lc_ctrl_hw2reg_t; + + // Register offsets + parameter logic [BlockAw-1:0] LC_CTRL_ALERT_TEST_OFFSET = 8'h 0; + parameter logic [BlockAw-1:0] LC_CTRL_STATUS_OFFSET = 8'h 4; + parameter logic [BlockAw-1:0] LC_CTRL_CLAIM_TRANSITION_IF_REGWEN_OFFSET = 8'h 8; + parameter logic [BlockAw-1:0] LC_CTRL_CLAIM_TRANSITION_IF_OFFSET = 8'h c; + parameter logic [BlockAw-1:0] LC_CTRL_TRANSITION_REGWEN_OFFSET = 8'h 10; + parameter logic [BlockAw-1:0] LC_CTRL_TRANSITION_CMD_OFFSET = 8'h 14; + parameter logic [BlockAw-1:0] LC_CTRL_TRANSITION_CTRL_OFFSET = 8'h 18; + parameter logic [BlockAw-1:0] LC_CTRL_TRANSITION_TOKEN_0_OFFSET = 8'h 1c; + parameter logic [BlockAw-1:0] LC_CTRL_TRANSITION_TOKEN_1_OFFSET = 8'h 20; + parameter logic [BlockAw-1:0] LC_CTRL_TRANSITION_TOKEN_2_OFFSET = 8'h 24; + parameter logic [BlockAw-1:0] LC_CTRL_TRANSITION_TOKEN_3_OFFSET = 8'h 28; + parameter logic [BlockAw-1:0] LC_CTRL_TRANSITION_TARGET_OFFSET = 8'h 2c; + parameter logic [BlockAw-1:0] LC_CTRL_OTP_VENDOR_TEST_CTRL_OFFSET = 8'h 30; + parameter logic [BlockAw-1:0] LC_CTRL_OTP_VENDOR_TEST_STATUS_OFFSET = 8'h 34; + parameter logic [BlockAw-1:0] LC_CTRL_LC_STATE_OFFSET = 8'h 38; + parameter logic [BlockAw-1:0] LC_CTRL_LC_TRANSITION_CNT_OFFSET = 8'h 3c; + parameter logic [BlockAw-1:0] LC_CTRL_LC_ID_STATE_OFFSET = 8'h 40; + parameter logic [BlockAw-1:0] LC_CTRL_HW_REVISION0_OFFSET = 8'h 44; + parameter logic [BlockAw-1:0] LC_CTRL_HW_REVISION1_OFFSET = 8'h 48; + parameter logic [BlockAw-1:0] LC_CTRL_DEVICE_ID_0_OFFSET = 8'h 4c; + parameter logic [BlockAw-1:0] LC_CTRL_DEVICE_ID_1_OFFSET = 8'h 50; + parameter logic [BlockAw-1:0] LC_CTRL_DEVICE_ID_2_OFFSET = 8'h 54; + parameter logic [BlockAw-1:0] LC_CTRL_DEVICE_ID_3_OFFSET = 8'h 58; + parameter logic [BlockAw-1:0] LC_CTRL_DEVICE_ID_4_OFFSET = 8'h 5c; + parameter logic [BlockAw-1:0] LC_CTRL_DEVICE_ID_5_OFFSET = 8'h 60; + parameter logic [BlockAw-1:0] LC_CTRL_DEVICE_ID_6_OFFSET = 8'h 64; + parameter logic [BlockAw-1:0] LC_CTRL_DEVICE_ID_7_OFFSET = 8'h 68; + parameter logic [BlockAw-1:0] LC_CTRL_MANUF_STATE_0_OFFSET = 8'h 6c; + parameter logic [BlockAw-1:0] LC_CTRL_MANUF_STATE_1_OFFSET = 8'h 70; + parameter logic [BlockAw-1:0] LC_CTRL_MANUF_STATE_2_OFFSET = 8'h 74; + parameter logic [BlockAw-1:0] LC_CTRL_MANUF_STATE_3_OFFSET = 8'h 78; + parameter logic [BlockAw-1:0] LC_CTRL_MANUF_STATE_4_OFFSET = 8'h 7c; + parameter logic [BlockAw-1:0] LC_CTRL_MANUF_STATE_5_OFFSET = 8'h 80; + parameter logic [BlockAw-1:0] LC_CTRL_MANUF_STATE_6_OFFSET = 8'h 84; + parameter logic [BlockAw-1:0] LC_CTRL_MANUF_STATE_7_OFFSET = 8'h 88; + + // Reset values for hwext registers and their fields + parameter logic [2:0] LC_CTRL_ALERT_TEST_RESVAL = 3'h 0; + parameter logic [0:0] LC_CTRL_ALERT_TEST_FATAL_PROG_ERROR_RESVAL = 1'h 0; + parameter logic [0:0] LC_CTRL_ALERT_TEST_FATAL_STATE_ERROR_RESVAL = 1'h 0; + parameter logic [0:0] LC_CTRL_ALERT_TEST_FATAL_BUS_INTEG_ERROR_RESVAL = 1'h 0; + parameter logic [11:0] LC_CTRL_STATUS_RESVAL = 12'h 0; + parameter logic [7:0] LC_CTRL_CLAIM_TRANSITION_IF_RESVAL = 8'h 69; + parameter logic [7:0] LC_CTRL_CLAIM_TRANSITION_IF_MUTEX_RESVAL = 8'h 69; + parameter logic [0:0] LC_CTRL_TRANSITION_REGWEN_RESVAL = 1'h 0; + parameter logic [0:0] LC_CTRL_TRANSITION_REGWEN_TRANSITION_REGWEN_RESVAL = 1'h 0; + parameter logic [0:0] LC_CTRL_TRANSITION_CMD_RESVAL = 1'h 0; + parameter logic [1:0] LC_CTRL_TRANSITION_CTRL_RESVAL = 2'h 0; + parameter logic [31:0] LC_CTRL_TRANSITION_TOKEN_0_RESVAL = 32'h 0; + parameter logic [31:0] LC_CTRL_TRANSITION_TOKEN_1_RESVAL = 32'h 0; + parameter logic [31:0] LC_CTRL_TRANSITION_TOKEN_2_RESVAL = 32'h 0; + parameter logic [31:0] LC_CTRL_TRANSITION_TOKEN_3_RESVAL = 32'h 0; + parameter logic [29:0] LC_CTRL_TRANSITION_TARGET_RESVAL = 30'h 0; + parameter logic [31:0] LC_CTRL_OTP_VENDOR_TEST_CTRL_RESVAL = 32'h 0; + parameter logic [31:0] LC_CTRL_OTP_VENDOR_TEST_STATUS_RESVAL = 32'h 0; + parameter logic [29:0] LC_CTRL_LC_STATE_RESVAL = 30'h 0; + parameter logic [4:0] LC_CTRL_LC_TRANSITION_CNT_RESVAL = 5'h 0; + parameter logic [31:0] LC_CTRL_LC_ID_STATE_RESVAL = 32'h 0; + parameter logic [31:0] LC_CTRL_HW_REVISION0_RESVAL = 32'h 0; + parameter logic [31:0] LC_CTRL_HW_REVISION1_RESVAL = 32'h 0; + parameter logic [23:0] LC_CTRL_HW_REVISION1_RESERVED_RESVAL = 24'h 0; + parameter logic [31:0] LC_CTRL_DEVICE_ID_0_RESVAL = 32'h 0; + parameter logic [31:0] LC_CTRL_DEVICE_ID_1_RESVAL = 32'h 0; + parameter logic [31:0] LC_CTRL_DEVICE_ID_2_RESVAL = 32'h 0; + parameter logic [31:0] LC_CTRL_DEVICE_ID_3_RESVAL = 32'h 0; + parameter logic [31:0] LC_CTRL_DEVICE_ID_4_RESVAL = 32'h 0; + parameter logic [31:0] LC_CTRL_DEVICE_ID_5_RESVAL = 32'h 0; + parameter logic [31:0] LC_CTRL_DEVICE_ID_6_RESVAL = 32'h 0; + parameter logic [31:0] LC_CTRL_DEVICE_ID_7_RESVAL = 32'h 0; + parameter logic [31:0] LC_CTRL_MANUF_STATE_0_RESVAL = 32'h 0; + parameter logic [31:0] LC_CTRL_MANUF_STATE_1_RESVAL = 32'h 0; + parameter logic [31:0] LC_CTRL_MANUF_STATE_2_RESVAL = 32'h 0; + parameter logic [31:0] LC_CTRL_MANUF_STATE_3_RESVAL = 32'h 0; + parameter logic [31:0] LC_CTRL_MANUF_STATE_4_RESVAL = 32'h 0; + parameter logic [31:0] LC_CTRL_MANUF_STATE_5_RESVAL = 32'h 0; + parameter logic [31:0] LC_CTRL_MANUF_STATE_6_RESVAL = 32'h 0; + parameter logic [31:0] LC_CTRL_MANUF_STATE_7_RESVAL = 32'h 0; + + // Register index + typedef enum logic [31:0] { + LC_CTRL_ALERT_TEST, + LC_CTRL_STATUS, + LC_CTRL_CLAIM_TRANSITION_IF_REGWEN, + LC_CTRL_CLAIM_TRANSITION_IF, + LC_CTRL_TRANSITION_REGWEN, + LC_CTRL_TRANSITION_CMD, + LC_CTRL_TRANSITION_CTRL, + LC_CTRL_TRANSITION_TOKEN_0, + LC_CTRL_TRANSITION_TOKEN_1, + LC_CTRL_TRANSITION_TOKEN_2, + LC_CTRL_TRANSITION_TOKEN_3, + LC_CTRL_TRANSITION_TARGET, + LC_CTRL_OTP_VENDOR_TEST_CTRL, + LC_CTRL_OTP_VENDOR_TEST_STATUS, + LC_CTRL_LC_STATE, + LC_CTRL_LC_TRANSITION_CNT, + LC_CTRL_LC_ID_STATE, + LC_CTRL_HW_REVISION0, + LC_CTRL_HW_REVISION1, + LC_CTRL_DEVICE_ID_0, + LC_CTRL_DEVICE_ID_1, + LC_CTRL_DEVICE_ID_2, + LC_CTRL_DEVICE_ID_3, + LC_CTRL_DEVICE_ID_4, + LC_CTRL_DEVICE_ID_5, + LC_CTRL_DEVICE_ID_6, + LC_CTRL_DEVICE_ID_7, + LC_CTRL_MANUF_STATE_0, + LC_CTRL_MANUF_STATE_1, + LC_CTRL_MANUF_STATE_2, + LC_CTRL_MANUF_STATE_3, + LC_CTRL_MANUF_STATE_4, + LC_CTRL_MANUF_STATE_5, + LC_CTRL_MANUF_STATE_6, + LC_CTRL_MANUF_STATE_7 + } lc_ctrl_id_e; + + // Register width information to check illegal writes + parameter logic [3:0] LC_CTRL_PERMIT [35] = '{ + 4'b 0001, // index[ 0] LC_CTRL_ALERT_TEST + 4'b 0011, // index[ 1] LC_CTRL_STATUS + 4'b 0001, // index[ 2] LC_CTRL_CLAIM_TRANSITION_IF_REGWEN + 4'b 0001, // index[ 3] LC_CTRL_CLAIM_TRANSITION_IF + 4'b 0001, // index[ 4] LC_CTRL_TRANSITION_REGWEN + 4'b 0001, // index[ 5] LC_CTRL_TRANSITION_CMD + 4'b 0001, // index[ 6] LC_CTRL_TRANSITION_CTRL + 4'b 1111, // index[ 7] LC_CTRL_TRANSITION_TOKEN_0 + 4'b 1111, // index[ 8] LC_CTRL_TRANSITION_TOKEN_1 + 4'b 1111, // index[ 9] LC_CTRL_TRANSITION_TOKEN_2 + 4'b 1111, // index[10] LC_CTRL_TRANSITION_TOKEN_3 + 4'b 1111, // index[11] LC_CTRL_TRANSITION_TARGET + 4'b 1111, // index[12] LC_CTRL_OTP_VENDOR_TEST_CTRL + 4'b 1111, // index[13] LC_CTRL_OTP_VENDOR_TEST_STATUS + 4'b 1111, // index[14] LC_CTRL_LC_STATE + 4'b 0001, // index[15] LC_CTRL_LC_TRANSITION_CNT + 4'b 1111, // index[16] LC_CTRL_LC_ID_STATE + 4'b 1111, // index[17] LC_CTRL_HW_REVISION0 + 4'b 1111, // index[18] LC_CTRL_HW_REVISION1 + 4'b 1111, // index[19] LC_CTRL_DEVICE_ID_0 + 4'b 1111, // index[20] LC_CTRL_DEVICE_ID_1 + 4'b 1111, // index[21] LC_CTRL_DEVICE_ID_2 + 4'b 1111, // index[22] LC_CTRL_DEVICE_ID_3 + 4'b 1111, // index[23] LC_CTRL_DEVICE_ID_4 + 4'b 1111, // index[24] LC_CTRL_DEVICE_ID_5 + 4'b 1111, // index[25] LC_CTRL_DEVICE_ID_6 + 4'b 1111, // index[26] LC_CTRL_DEVICE_ID_7 + 4'b 1111, // index[27] LC_CTRL_MANUF_STATE_0 + 4'b 1111, // index[28] LC_CTRL_MANUF_STATE_1 + 4'b 1111, // index[29] LC_CTRL_MANUF_STATE_2 + 4'b 1111, // index[30] LC_CTRL_MANUF_STATE_3 + 4'b 1111, // index[31] LC_CTRL_MANUF_STATE_4 + 4'b 1111, // index[32] LC_CTRL_MANUF_STATE_5 + 4'b 1111, // index[33] LC_CTRL_MANUF_STATE_6 + 4'b 1111 // index[34] LC_CTRL_MANUF_STATE_7 + }; + +endpackage diff --git a/designs/Caliptra/src/caliptra-rtl/lc_ctrl_state_pkg.sv b/designs/Caliptra/src/caliptra-rtl/lc_ctrl_state_pkg.sv new file mode 100644 index 0000000..adea7be --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/lc_ctrl_state_pkg.sv @@ -0,0 +1,433 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Life cycle state encoding definition. +// +// DO NOT EDIT THIS FILE DIRECTLY. +// It has been generated with +// $ ./util/design/gen-lc-state-enc.py --seed 40182201019264397688411770949626922549663256047001778394918990008320537410392 +// +package lc_ctrl_state_pkg; + + import caliptra_prim_util_pkg::vbits; + + /////////////////////////////// + // General size declarations // + /////////////////////////////// + + parameter int LcValueWidth = 16; + + parameter int NumLcStateValues = 20; + parameter int LcStateWidth = NumLcStateValues * LcValueWidth; + parameter int NumLcStates = 21; + parameter int DecLcStateWidth = vbits(NumLcStates); + parameter int NumSocDbgStateValues = 2; + parameter int SocDbgStateWidth = NumSocDbgStateValues * LcValueWidth; + parameter int NumOwnershipStateValues = 8; + parameter int OwnershipStateWidth = NumOwnershipStateValues * LcValueWidth; + parameter int NumAuthStateValues = 2; + parameter int AuthStateWidth = NumAuthStateValues * LcValueWidth; + + // Redundant version used in the CSRs. + parameter int DecLcStateNumRep = 32/DecLcStateWidth; + parameter int ExtDecLcStateWidth = DecLcStateNumRep*DecLcStateWidth; + + parameter int NumLcCountValues = 24; + parameter int LcCountWidth = NumLcCountValues * LcValueWidth; + parameter int NumLcCountStates = 25; + parameter int DecLcCountWidth = vbits(NumLcCountStates); + + // This state is not stored in OTP, but inferred from the locked + // status of the secret partitions. Hence, only the decoded ID state + // is declared here for exposure through the CSR interface. + parameter int NumLcIdStates = 2; + parameter int DecLcIdStateWidth = vbits(NumLcIdStates+1); + // Redundant version used in the CSRs. + parameter int DecLcIdStateNumRep = 32/DecLcIdStateWidth; + parameter int ExtDecLcIdStateWidth = DecLcIdStateNumRep*DecLcIdStateWidth; + + ///////////////////////////////////////////// + // Life cycle manufacturing state encoding // + ///////////////////////////////////////////// + + // These values have been generated such that they are incrementally writeable with respect + // to the ECC polynomial specified. The values are used to define the life cycle manufacturing + // state and transition counter encoding in lc_ctrl_pkg.sv. + // + // The values are unique and have the following statistics (considering all 16 + // data and 6 ECC bits): + // + // - Minimum Hamming weight: 6 + // - Maximum Hamming weight: 16 + // - Minimum Hamming distance from any other value: 6 + // - Maximum Hamming distance from any other value: 18 + // + // Hamming distance histogram: + // + // 0: -- + // 1: -- + // 2: -- + // 3: -- + // 4: -- + // 5: -- + // 6: ||| (5.04%) + // 7: -- + // 8: ||||||||||| (16.97%) + // 9: -- + // 10: |||||||||||||||||||| (30.12%) + // 11: -- + // 12: ||||||||||||||||||| (29.34%) + // 13: -- + // 14: ||||||||| (14.35%) + // 15: -- + // 16: || (3.80%) + // 17: -- + // 18: (0.39%) + // 19: -- + // 20: -- + // 21: -- + // 22: -- + // + // + // Note that the ECC bits are not defined in this package as they will be calculated by + // the OTP ECC logic at runtime. + + // SEC_CM: MANUF.STATE.SPARSE + // The A/B values are used for the encoded LC state. + parameter logic [15:0] A0 = 16'b0110010010101110; // ECC: 6'b001010 + parameter logic [15:0] B0 = 16'b0111010111101110; // ECC: 6'b111110 + + parameter logic [15:0] A1 = 16'b0000011110110100; // ECC: 6'b100101 + parameter logic [15:0] B1 = 16'b0000111111111110; // ECC: 6'b111101 + + parameter logic [15:0] A2 = 16'b0011000111010010; // ECC: 6'b000111 + parameter logic [15:0] B2 = 16'b0111101111111110; // ECC: 6'b000111 + + parameter logic [15:0] A3 = 16'b0010111001001101; // ECC: 6'b001010 + parameter logic [15:0] B3 = 16'b0011111101101111; // ECC: 6'b111010 + + parameter logic [15:0] A4 = 16'b0100000111111000; // ECC: 6'b011010 + parameter logic [15:0] B4 = 16'b0101111111111100; // ECC: 6'b011110 + + parameter logic [15:0] A5 = 16'b1010110010000101; // ECC: 6'b110001 + parameter logic [15:0] B5 = 16'b1111110110011111; // ECC: 6'b110001 + + parameter logic [15:0] A6 = 16'b1001100110001100; // ECC: 6'b010110 + parameter logic [15:0] B6 = 16'b1111100110011111; // ECC: 6'b011110 + + parameter logic [15:0] A7 = 16'b0101001100001111; // ECC: 6'b100010 + parameter logic [15:0] B7 = 16'b1101101101101111; // ECC: 6'b100111 + + parameter logic [15:0] A8 = 16'b0111000101100000; // ECC: 6'b111001 + parameter logic [15:0] B8 = 16'b0111001101111111; // ECC: 6'b111001 + + parameter logic [15:0] A9 = 16'b0010110001100011; // ECC: 6'b101010 + parameter logic [15:0] B9 = 16'b0110110001101111; // ECC: 6'b111111 + + parameter logic [15:0] A10 = 16'b0110110100001000; // ECC: 6'b110011 + parameter logic [15:0] B10 = 16'b0110111110011110; // ECC: 6'b111011 + + parameter logic [15:0] A11 = 16'b1001001001001100; // ECC: 6'b000011 + parameter logic [15:0] B11 = 16'b1101001111011100; // ECC: 6'b111111 + + parameter logic [15:0] A12 = 16'b0111000001000000; // ECC: 6'b011110 + parameter logic [15:0] B12 = 16'b0111011101010010; // ECC: 6'b111110 + + parameter logic [15:0] A13 = 16'b1001001010111110; // ECC: 6'b000010 + parameter logic [15:0] B13 = 16'b1111001011111110; // ECC: 6'b101110 + + parameter logic [15:0] A14 = 16'b1001010011010010; // ECC: 6'b100011 + parameter logic [15:0] B14 = 16'b1011110111010011; // ECC: 6'b101111 + + parameter logic [15:0] A15 = 16'b0110001010001101; // ECC: 6'b000111 + parameter logic [15:0] B15 = 16'b0110111111001101; // ECC: 6'b011111 + + parameter logic [15:0] A16 = 16'b1011001000101000; // ECC: 6'b010111 + parameter logic [15:0] B16 = 16'b1011001011111011; // ECC: 6'b011111 + + parameter logic [15:0] A17 = 16'b0001111001110001; // ECC: 6'b001001 + parameter logic [15:0] B17 = 16'b1001111111110101; // ECC: 6'b011011 + + parameter logic [15:0] A18 = 16'b0010110110011011; // ECC: 6'b000100 + parameter logic [15:0] B18 = 16'b0011111111011111; // ECC: 6'b010101 + + parameter logic [15:0] A19 = 16'b0100110110001100; // ECC: 6'b101010 + parameter logic [15:0] B19 = 16'b1101110110111110; // ECC: 6'b101011 + + + // SEC_CM: TRANSITION.CTR.SPARSE + // The C/D values are used for the encoded LC transition counter. + parameter logic [15:0] C0 = 16'b0001010010011110; // ECC: 6'b011100 + parameter logic [15:0] D0 = 16'b1011011011011111; // ECC: 6'b111100 + + parameter logic [15:0] C1 = 16'b0101101011000100; // ECC: 6'b111000 + parameter logic [15:0] D1 = 16'b1111101011110100; // ECC: 6'b111101 + + parameter logic [15:0] C2 = 16'b0001111100100100; // ECC: 6'b100011 + parameter logic [15:0] D2 = 16'b0001111110111111; // ECC: 6'b100111 + + parameter logic [15:0] C3 = 16'b1100111010000101; // ECC: 6'b011000 + parameter logic [15:0] D3 = 16'b1100111011101111; // ECC: 6'b011011 + + parameter logic [15:0] C4 = 16'b0100001010011111; // ECC: 6'b011000 + parameter logic [15:0] D4 = 16'b0101101110111111; // ECC: 6'b111100 + + parameter logic [15:0] C5 = 16'b1001111000100010; // ECC: 6'b111000 + parameter logic [15:0] D5 = 16'b1111111110100010; // ECC: 6'b111110 + + parameter logic [15:0] C6 = 16'b0010011110000110; // ECC: 6'b010000 + parameter logic [15:0] D6 = 16'b0111011111000110; // ECC: 6'b011101 + + parameter logic [15:0] C7 = 16'b0010111101000110; // ECC: 6'b000110 + parameter logic [15:0] D7 = 16'b1010111111000110; // ECC: 6'b111111 + + parameter logic [15:0] C8 = 16'b0000001011011011; // ECC: 6'b000001 + parameter logic [15:0] D8 = 16'b1010101111011011; // ECC: 6'b111011 + + parameter logic [15:0] C9 = 16'b0111000011000110; // ECC: 6'b110001 + parameter logic [15:0] D9 = 16'b1111111011001110; // ECC: 6'b110011 + + parameter logic [15:0] C10 = 16'b0100001000010010; // ECC: 6'b110110 + parameter logic [15:0] D10 = 16'b0111001010110110; // ECC: 6'b110111 + + parameter logic [15:0] C11 = 16'b0100101111110001; // ECC: 6'b000001 + parameter logic [15:0] D11 = 16'b0110101111110011; // ECC: 6'b110111 + + parameter logic [15:0] C12 = 16'b1000100101000001; // ECC: 6'b000001 + parameter logic [15:0] D12 = 16'b1011110101001111; // ECC: 6'b001011 + + parameter logic [15:0] C13 = 16'b1000000000010001; // ECC: 6'b011111 + parameter logic [15:0] D13 = 16'b1001100010110011; // ECC: 6'b111111 + + parameter logic [15:0] C14 = 16'b0101110000000100; // ECC: 6'b111110 + parameter logic [15:0] D14 = 16'b1111111010001101; // ECC: 6'b111110 + + parameter logic [15:0] C15 = 16'b1100001000001001; // ECC: 6'b001011 + parameter logic [15:0] D15 = 16'b1110011000011011; // ECC: 6'b111011 + + parameter logic [15:0] C16 = 16'b0101001001101100; // ECC: 6'b001000 + parameter logic [15:0] D16 = 16'b0111111001111110; // ECC: 6'b001001 + + parameter logic [15:0] C17 = 16'b0100001001110100; // ECC: 6'b010100 + parameter logic [15:0] D17 = 16'b1100101001110111; // ECC: 6'b110110 + + parameter logic [15:0] C18 = 16'b1100000001100111; // ECC: 6'b100000 + parameter logic [15:0] D18 = 16'b1100011101110111; // ECC: 6'b100101 + + parameter logic [15:0] C19 = 16'b1010000001001010; // ECC: 6'b101111 + parameter logic [15:0] D19 = 16'b1111011101101010; // ECC: 6'b101111 + + parameter logic [15:0] C20 = 16'b1001001001010101; // ECC: 6'b001110 + parameter logic [15:0] D20 = 16'b1101111011011101; // ECC: 6'b001111 + + parameter logic [15:0] C21 = 16'b1001010000011011; // ECC: 6'b100000 + parameter logic [15:0] D21 = 16'b1001111000111011; // ECC: 6'b110101 + + parameter logic [15:0] C22 = 16'b1011101101100001; // ECC: 6'b000100 + parameter logic [15:0] D22 = 16'b1011111101111111; // ECC: 6'b000110 + + parameter logic [15:0] C23 = 16'b1101101000000111; // ECC: 6'b001100 + parameter logic [15:0] D23 = 16'b1101111011100111; // ECC: 6'b101110 + + + // The F/E values are used for the encoded SOC_DBG state. + parameter logic [15:0] E0 = 16'b0000101001000100; // ECC: 6'b010010 + parameter logic [15:0] F0 = 16'b1001111001101100; // ECC: 6'b110111 + + parameter logic [15:0] E1 = 16'b0000110111111000; // ECC: 6'b110000 + parameter logic [15:0] F1 = 16'b1100111111111001; // ECC: 6'b111100 + + + // The G/H values are used for the encoded OWNERSHIP state. + parameter logic [15:0] G0 = 16'b0110000100111100; // ECC: 6'b001000 + parameter logic [15:0] H0 = 16'b0111010110111100; // ECC: 6'b111001 + + parameter logic [15:0] G1 = 16'b1000110100111001; // ECC: 6'b100001 + parameter logic [15:0] H1 = 16'b1011110101111101; // ECC: 6'b101101 + + parameter logic [15:0] G2 = 16'b0110100001100010; // ECC: 6'b010010 + parameter logic [15:0] H2 = 16'b1111100111101010; // ECC: 6'b010011 + + parameter logic [15:0] G3 = 16'b1001001110000101; // ECC: 6'b001101 + parameter logic [15:0] H3 = 16'b1101001110110111; // ECC: 6'b011111 + + parameter logic [15:0] G4 = 16'b1010011000011101; // ECC: 6'b001100 + parameter logic [15:0] H4 = 16'b1110011101011101; // ECC: 6'b111110 + + parameter logic [15:0] G5 = 16'b1110110101100000; // ECC: 6'b000000 + parameter logic [15:0] H5 = 16'b1110111111101001; // ECC: 6'b000110 + + parameter logic [15:0] G6 = 16'b1011000100101010; // ECC: 6'b110001 + parameter logic [15:0] H6 = 16'b1111101110101011; // ECC: 6'b110101 + + parameter logic [15:0] G7 = 16'b0000111110001010; // ECC: 6'b010011 + parameter logic [15:0] H7 = 16'b1100111110111110; // ECC: 6'b010111 + + + // The I/Jvalues are used for the encoded AUTH state. + parameter logic [15:0] I0 = 16'b0110011110000001; // ECC: 6'b000100 + parameter logic [15:0] J0 = 16'b0111111110100001; // ECC: 6'b101101 + + parameter logic [15:0] I1 = 16'b1110100010100001; // ECC: 6'b100110 + parameter logic [15:0] J1 = 16'b1110100111110101; // ECC: 6'b101111 + + + parameter logic [15:0] ZRO = 16'h0; + + //////////////////////// + // Derived enum types // + //////////////////////// + + // Use lc_state_t and lc_cnt_t in interfaces as very wide enumerations ( > 64 bits ) + // are not supported for virtual interfaces by Excelium yet + // https://github.com/lowRISC/opentitan/issues/8884 (Cadence issue: cds_46570160) + // The enumeration types lc_state_e and lc_cnt_e are still ok in other circumstances + // NOTE: Caliptra-SS required the following change in this decoding: + // LcStProd = {XX, XX, XX, XX, A15 -> B15, XX, ...} This allows LC to switch from DEV to PROD + // LcStProdEnd = {XX, XX, XX, A16->B16, A15 -> B15, XX, ...} This allows LC to switch from DEV to PROD_END or PROD to PROD_END + // However, PROD_END can branch only to SCARP and nothing else + // Note that the DEV state is being reused as MANUF state + + typedef logic [LcStateWidth-1:0] lc_state_t; + typedef enum lc_state_t { + LcStRaw = {ZRO, ZRO, ZRO, ZRO, ZRO, ZRO, ZRO, ZRO, ZRO, ZRO, ZRO, ZRO, ZRO, ZRO, ZRO, ZRO, ZRO, ZRO, ZRO, ZRO}, + LcStTestUnlocked0 = {A19, A18, A17, A16, A15, A14, A13, A12, A11, A10, A9, A8, A7, A6, A5, A4, A3, A2, A1, B0}, + LcStTestLocked0 = {A19, A18, A17, A16, A15, A14, A13, A12, A11, A10, A9, A8, A7, A6, A5, A4, A3, A2, B1, B0}, + LcStTestUnlocked1 = {A19, A18, A17, A16, A15, A14, A13, A12, A11, A10, A9, A8, A7, A6, A5, A4, A3, B2, B1, B0}, + LcStTestLocked1 = {A19, A18, A17, A16, A15, A14, A13, A12, A11, A10, A9, A8, A7, A6, A5, A4, B3, B2, B1, B0}, + LcStTestUnlocked2 = {A19, A18, A17, A16, A15, A14, A13, A12, A11, A10, A9, A8, A7, A6, A5, B4, B3, B2, B1, B0}, + LcStTestLocked2 = {A19, A18, A17, A16, A15, A14, A13, A12, A11, A10, A9, A8, A7, A6, B5, B4, B3, B2, B1, B0}, + LcStTestUnlocked3 = {A19, A18, A17, A16, A15, A14, A13, A12, A11, A10, A9, A8, A7, B6, B5, B4, B3, B2, B1, B0}, + LcStTestLocked3 = {A19, A18, A17, A16, A15, A14, A13, A12, A11, A10, A9, A8, B7, B6, B5, B4, B3, B2, B1, B0}, + LcStTestUnlocked4 = {A19, A18, A17, A16, A15, A14, A13, A12, A11, A10, A9, B8, B7, B6, B5, B4, B3, B2, B1, B0}, + LcStTestLocked4 = {A19, A18, A17, A16, A15, A14, A13, A12, A11, A10, B9, B8, B7, B6, B5, B4, B3, B2, B1, B0}, + LcStTestUnlocked5 = {A19, A18, A17, A16, A15, A14, A13, A12, A11, B10, B9, B8, B7, B6, B5, B4, B3, B2, B1, B0}, + LcStTestLocked5 = {A19, A18, A17, A16, A15, A14, A13, A12, B11, B10, B9, B8, B7, B6, B5, B4, B3, B2, B1, B0}, + LcStTestUnlocked6 = {A19, A18, A17, A16, A15, A14, A13, B12, B11, B10, B9, B8, B7, B6, B5, B4, B3, B2, B1, B0}, + LcStTestLocked6 = {A19, A18, A17, A16, A15, A14, B13, B12, B11, B10, B9, B8, B7, B6, B5, B4, B3, B2, B1, B0}, + LcStTestUnlocked7 = {A19, A18, A17, A16, A15, B14, B13, B12, B11, B10, B9, B8, B7, B6, B5, B4, B3, B2, B1, B0}, + LcStDev = {A19, A18, A17, A16, B15, B14, B13, B12, B11, B10, B9, B8, B7, B6, B5, B4, B3, B2, B1, B0}, + LcStProd = {A19, A18, A17, B16, B15, B14, B13, B12, B11, B10, B9, B8, B7, B6, B5, B4, B3, B2, B1, B0}, + LcStProdEnd = {A19, A18, B17, B16, B15, B14, B13, B12, B11, B10, B9, B8, B7, B6, B5, B4, B3, B2, B1, B0}, + LcStRma = {A19, B18, B17, B16, B15, B14, B13, B12, B11, B10, B9, B8, B7, B6, B5, B4, B3, B2, B1, B0}, + LcStScrap = {B19, B18, B17, B16, B15, B14, B13, B12, B11, B10, B9, B8, B7, B6, B5, B4, B3, B2, B1, B0} + } lc_state_e; + + typedef logic [LcCountWidth-1:0] lc_cnt_t; + typedef enum lc_cnt_t { + LcCnt0 = {ZRO, ZRO, ZRO, ZRO, ZRO, ZRO, ZRO, ZRO, ZRO, ZRO, ZRO, ZRO, ZRO, ZRO, ZRO, ZRO, ZRO, ZRO, ZRO, ZRO, ZRO, ZRO, ZRO, ZRO}, + LcCnt1 = {C23, C22, C21, C20, C19, C18, C17, C16, C15, C14, C13, C12, C11, C10, C9, C8, C7, C6, C5, C4, C3, C2, C1, D0}, + LcCnt2 = {C23, C22, C21, C20, C19, C18, C17, C16, C15, C14, C13, C12, C11, C10, C9, C8, C7, C6, C5, C4, C3, C2, D1, D0}, + LcCnt3 = {C23, C22, C21, C20, C19, C18, C17, C16, C15, C14, C13, C12, C11, C10, C9, C8, C7, C6, C5, C4, C3, D2, D1, D0}, + LcCnt4 = {C23, C22, C21, C20, C19, C18, C17, C16, C15, C14, C13, C12, C11, C10, C9, C8, C7, C6, C5, C4, D3, D2, D1, D0}, + LcCnt5 = {C23, C22, C21, C20, C19, C18, C17, C16, C15, C14, C13, C12, C11, C10, C9, C8, C7, C6, C5, D4, D3, D2, D1, D0}, + LcCnt6 = {C23, C22, C21, C20, C19, C18, C17, C16, C15, C14, C13, C12, C11, C10, C9, C8, C7, C6, D5, D4, D3, D2, D1, D0}, + LcCnt7 = {C23, C22, C21, C20, C19, C18, C17, C16, C15, C14, C13, C12, C11, C10, C9, C8, C7, D6, D5, D4, D3, D2, D1, D0}, + LcCnt8 = {C23, C22, C21, C20, C19, C18, C17, C16, C15, C14, C13, C12, C11, C10, C9, C8, D7, D6, D5, D4, D3, D2, D1, D0}, + LcCnt9 = {C23, C22, C21, C20, C19, C18, C17, C16, C15, C14, C13, C12, C11, C10, C9, D8, D7, D6, D5, D4, D3, D2, D1, D0}, + LcCnt10 = {C23, C22, C21, C20, C19, C18, C17, C16, C15, C14, C13, C12, C11, C10, D9, D8, D7, D6, D5, D4, D3, D2, D1, D0}, + LcCnt11 = {C23, C22, C21, C20, C19, C18, C17, C16, C15, C14, C13, C12, C11, D10, D9, D8, D7, D6, D5, D4, D3, D2, D1, D0}, + LcCnt12 = {C23, C22, C21, C20, C19, C18, C17, C16, C15, C14, C13, C12, D11, D10, D9, D8, D7, D6, D5, D4, D3, D2, D1, D0}, + LcCnt13 = {C23, C22, C21, C20, C19, C18, C17, C16, C15, C14, C13, D12, D11, D10, D9, D8, D7, D6, D5, D4, D3, D2, D1, D0}, + LcCnt14 = {C23, C22, C21, C20, C19, C18, C17, C16, C15, C14, D13, D12, D11, D10, D9, D8, D7, D6, D5, D4, D3, D2, D1, D0}, + LcCnt15 = {C23, C22, C21, C20, C19, C18, C17, C16, C15, D14, D13, D12, D11, D10, D9, D8, D7, D6, D5, D4, D3, D2, D1, D0}, + LcCnt16 = {C23, C22, C21, C20, C19, C18, C17, C16, D15, D14, D13, D12, D11, D10, D9, D8, D7, D6, D5, D4, D3, D2, D1, D0}, + LcCnt17 = {C23, C22, C21, C20, C19, C18, C17, D16, D15, D14, D13, D12, D11, D10, D9, D8, D7, D6, D5, D4, D3, D2, D1, D0}, + LcCnt18 = {C23, C22, C21, C20, C19, C18, D17, D16, D15, D14, D13, D12, D11, D10, D9, D8, D7, D6, D5, D4, D3, D2, D1, D0}, + LcCnt19 = {C23, C22, C21, C20, C19, D18, D17, D16, D15, D14, D13, D12, D11, D10, D9, D8, D7, D6, D5, D4, D3, D2, D1, D0}, + LcCnt20 = {C23, C22, C21, C20, D19, D18, D17, D16, D15, D14, D13, D12, D11, D10, D9, D8, D7, D6, D5, D4, D3, D2, D1, D0}, + LcCnt21 = {C23, C22, C21, D20, D19, D18, D17, D16, D15, D14, D13, D12, D11, D10, D9, D8, D7, D6, D5, D4, D3, D2, D1, D0}, + LcCnt22 = {C23, C22, D21, D20, D19, D18, D17, D16, D15, D14, D13, D12, D11, D10, D9, D8, D7, D6, D5, D4, D3, D2, D1, D0}, + LcCnt23 = {C23, D22, D21, D20, D19, D18, D17, D16, D15, D14, D13, D12, D11, D10, D9, D8, D7, D6, D5, D4, D3, D2, D1, D0}, + LcCnt24 = {D23, D22, D21, D20, D19, D18, D17, D16, D15, D14, D13, D12, D11, D10, D9, D8, D7, D6, D5, D4, D3, D2, D1, D0} + } lc_cnt_e; + + typedef logic [SocDbgStateWidth-1:0] soc_dbg_state_t; + typedef enum soc_dbg_state_t { + SocDbgStBlank = {ZRO, ZRO}, + SocDbgStPreProd = { E1, E0}, + SocDbgStProd = { F1, F0} + } soc_dbg_state_e; + + typedef logic [OwnershipStateWidth-1:0] ownership_state_t; + typedef enum ownership_state_t { + OwnershipStBlank = {ZRO, ZRO, ZRO, ZRO, ZRO, ZRO, ZRO, ZRO}, + OwnershipStLocked0 = { G7, G6, G5, G4, G3, G2, G1, G0}, + OwnershipStReleased0 = { G7, G6, G5, G4, G3, G2, G1, H0}, + OwnershipStLocked1 = { G7, G6, G5, G4, G3, G2, H1, H0}, + OwnershipStReleased1 = { G7, G6, G5, G4, G3, H2, H1, H0}, + OwnershipStLocked2 = { G7, G6, G5, G4, H3, H2, H1, H0}, + OwnershipStReleased2 = { G7, G6, G5, H4, H3, H2, H1, H0}, + OwnershipStLocked3 = { G7, G6, H5, H4, H3, H2, H1, H0}, + OwnershipStScrapped = { H7, H6, H5, H4, H3, H2, H1, H0} + } ownership_state_e; + + typedef logic [AuthStateWidth-1:0] auth_state_t; + typedef enum auth_state_t { + AuthStBlank = {ZRO, ZRO}, + AuthStEnabled = { I1, I0}, + AuthStDisabled = { J1, J0} + } auth_state_e; + + // Decoded life cycle state, used to interface with CSRs and TAP. + typedef enum logic [DecLcStateWidth-1:0] { + DecLcStRaw = 0, + DecLcStTestUnlocked0 = 1, + DecLcStTestLocked0 = 2, + DecLcStTestUnlocked1 = 3, + DecLcStTestLocked1 = 4, + DecLcStTestUnlocked2 = 5, + DecLcStTestLocked2 = 6, + DecLcStTestUnlocked3 = 7, + DecLcStTestLocked3 = 8, + DecLcStTestUnlocked4 = 9, + DecLcStTestLocked4 = 10, + DecLcStTestUnlocked5 = 11, + DecLcStTestLocked5 = 12, + DecLcStTestUnlocked6 = 13, + DecLcStTestLocked6 = 14, + DecLcStTestUnlocked7 = 15, + DecLcStDev = 16, + DecLcStProd = 17, + DecLcStProdEnd = 18, + DecLcStRma = 19, + DecLcStScrap = 20, + DecLcStPostTrans = 21, + DecLcStEscalate = 22, + DecLcStInvalid = 23 + } dec_lc_state_e; + + typedef dec_lc_state_e [DecLcStateNumRep-1:0] ext_dec_lc_state_t; + + typedef enum logic [DecLcIdStateWidth-1:0] { + DecLcIdBlank, + DecLcIdPersonalized, + DecLcIdInvalid + } dec_lc_id_state_e; + + typedef logic [DecLcCountWidth-1:0] dec_lc_cnt_t; + + + /////////////////////////////////////////// + // Hashed RAW unlock and all-zero tokens // + /////////////////////////////////////////// + + parameter int LcTokenWidth = 128; + typedef logic [LcTokenWidth-1:0] lc_token_t; + + parameter lc_token_t AllZeroToken = { + 128'h0 + }; + //TODO: Temporary rename of RndCnstRawUnlockToken to RndCnstRawUnlockTokenDefault + parameter lc_token_t RndCnstRawUnlockTokenDefault = { + 128'hEA2B3F32CBE77554E43C8EA7EBF197C2 + }; + parameter lc_token_t AllZeroTokenHashed = { + 128'h3852305BAECF5FF1D5C1D25F6DB9058D + }; + parameter lc_token_t RndCnstRawUnlockTokenHashed = { + 128'h4748d3f5_358f685c_1e213794_3c8ff2b6 + }; + +endpackage : lc_ctrl_state_pkg diff --git a/designs/Caliptra/src/caliptra-rtl/mbox.sv b/designs/Caliptra/src/caliptra-rtl/mbox.sv new file mode 100644 index 0000000..08a3587 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/mbox.sv @@ -0,0 +1,764 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. + +`include "caliptra_sva.svh" + +module mbox + import mbox_pkg::*; + import mbox_csr_pkg::*; + #( + parameter DMI_REG_MBOX_DLEN_ADDR = 7'h50 + ,parameter DMI_REG_MBOX_LOCK_ADDR = 7'h75 + ,parameter DMI_REG_MBOX_CMD_ADDR = 7'h76 + ,parameter DMI_REG_MBOX_EXECUTE_ADDR = 7'h77 + ,parameter DMI_REG_MBOX_STATUS_ADDR = 7'h52 + //Mailbox interface configuration + ,parameter MBOX_IFC_DATA_W = 32 + ,parameter MBOX_IFC_USER_W = 32 + ,parameter MBOX_IFC_ADDR_W = 32 + //Mailbox size configuration + ,parameter MBOX_SIZE_KB = 256 + ,parameter MBOX_DATA_W = 32 + ,parameter MBOX_ECC_DATA_W = 7 + ,localparam MBOX_SIZE_BYTES = MBOX_SIZE_KB * 1024 + ,localparam MBOX_SIZE_DWORDS = MBOX_SIZE_BYTES/4 + ,localparam MBOX_DATA_AND_ECC_W = MBOX_DATA_W + MBOX_ECC_DATA_W + ,localparam MBOX_DEPTH = (MBOX_SIZE_KB * 1024 * 8) / MBOX_DATA_W + ,localparam MBOX_ADDR_W = $clog2(MBOX_DEPTH) + ,localparam MBOX_DEPTH_LOG2 = $clog2(MBOX_DEPTH) + ) + ( + input logic clk, + input logic rst_b, + + //mailbox request + input logic req_dv, + output logic req_hold, + input logic dir_req_dv, + input logic [MBOX_IFC_ADDR_W-1:0] req_data_addr, + input logic [MBOX_IFC_DATA_W-1:0] req_data_wdata, + input logic [MBOX_IFC_DATA_W/8-1:0] req_data_wstrb, + input logic [MBOX_IFC_USER_W-1:0] req_data_user, + input logic req_data_write, + input logic req_data_soc_req, + + output logic mbox_error, + + output logic [MBOX_DATA_W-1:0] rdata, + output logic [MBOX_DATA_W-1:0] dir_rdata, + + input logic sha_sram_req_dv, + input logic [MBOX_ADDR_W-1:0] sha_sram_req_addr, + output logic [MBOX_ECC_DATA_W-1:0] sha_sram_resp_ecc, + output logic [MBOX_DATA_W-1:0] sha_sram_resp_data, + output logic sha_sram_hold, // Throttle the SRAM requests when writing corrected ECC + + //dma req + input logic dma_sram_req_dv, + input logic dma_sram_req_write, + input logic [MBOX_IFC_ADDR_W-1:0] dma_sram_req_addr, + input logic [MBOX_IFC_DATA_W-1:0] dma_sram_req_wdata, + output logic [MBOX_IFC_DATA_W-1:0] dma_sram_rdata, + output logic dma_sram_hold, // Throttle the SRAM requests when SHA accel has access. + output logic dma_sram_error, + + //SRAM interface + output logic mbox_sram_req_cs, + output logic mbox_sram_req_we, + output logic [MBOX_ADDR_W-1:0] mbox_sram_req_addr, + output logic [MBOX_ECC_DATA_W-1:0] mbox_sram_req_ecc, + output logic [MBOX_DATA_W-1:0] mbox_sram_req_wdata, + input logic [MBOX_ECC_DATA_W-1:0] mbox_sram_resp_ecc, + input logic [MBOX_DATA_W-1:0] mbox_sram_resp_data, + + // ECC Status + output logic sram_single_ecc_error, + output logic sram_double_ecc_error, + + // Status + output logic uc_mbox_lock, + + //interrupts + output logic uc_mbox_data_avail, + output logic soc_mbox_data_avail, + output logic soc_req_mbox_lock, + output mbox_protocol_error_t mbox_protocol_error, + output logic mbox_inv_axi_user_axs, + + //DMI reg access + input logic dmi_mbox_avail, + input logic dmi_inc_rdptr, + input logic dmi_inc_wrptr, + input logic dmi_reg_wen, + input logic dmi_reg_ren, + input logic [31:0] dmi_reg_wdata, + input logic [6:0] dmi_reg_addr, + output mbox_dmi_reg_t dmi_reg + +); + +//this module is used to instantiate a single mailbox instance +//requests within the address space of this mailbox are routed here from the top level + +//State Machine +//The state machine controls the access to the mailbox. +//This will be used to ensure that protocol is followed and +//requests are granted only to the device that has locked the mailbox + +//present and next state +mbox_fsm_state_e mbox_fsm_ns; +mbox_fsm_state_e mbox_fsm_ps; + +//arcs between states +logic arc_FORCE_MBOX_UNLOCK; +logic arc_MBOX_IDLE_MBOX_RDY_FOR_CMD; +logic arc_MBOX_RDY_FOR_CMD_MBOX_RDY_FOR_DLEN; +logic arc_MBOX_RDY_FOR_DLEN_MBOX_RDY_FOR_DATA; +logic arc_MBOX_RDY_FOR_DATA_MBOX_EXECUTE_UC; +logic arc_MBOX_RDY_FOR_DATA_MBOX_EXECUTE_SOC; +logic arc_MBOX_RDY_FOR_DATA_MBOX_EXECUTE_TAP; +logic arc_MBOX_EXECUTE_UC_MBOX_IDLE; +logic arc_MBOX_EXECUTE_SOC_MBOX_IDLE; +logic arc_MBOX_EXECUTE_TAP_MBOX_IDLE; +logic arc_MBOX_EXECUTE_UC_MBOX_EXECUTE_SOC; +logic arc_MBOX_EXECUTE_SOC_MBOX_EXECUTE_UC; +logic arc_MBOX_EXECUTE_TAP_MBOX_EXECUTE_UC; +logic arc_MBOX_EXECUTE_UC_MBOX_EXECUTE_TAP; +logic arc_MBOX_RDY_FOR_CMD_MBOX_ERROR; +logic arc_MBOX_RDY_FOR_DLEN_MBOX_ERROR; +logic arc_MBOX_RDY_FOR_DATA_MBOX_ERROR; +logic arc_MBOX_EXECUTE_UC_MBOX_ERROR; +logic arc_MBOX_EXECUTE_SOC_MBOX_ERROR; +logic arc_MBOX_EXECUTE_TAP_MBOX_ERROR; +//sram +logic [MBOX_DATA_W-1:0] sram_wdata; +logic [MBOX_ECC_DATA_W-1:0] sram_wdata_ecc; +logic [MBOX_DEPTH_LOG2-1:0] sram_waddr; +logic [MBOX_DEPTH_LOG2-1:0] mbox_wrptr, mbox_wrptr_nxt; +logic mbox_wr_full, mbox_wr_full_nxt; +logic inc_wrptr; +logic [MBOX_DEPTH_LOG2-1:0] sram_rdaddr; +logic [MBOX_DEPTH_LOG2-1:0] mbox_rdptr, mbox_rdptr_nxt; +logic mbox_rd_full, mbox_rd_full_nxt; +logic inc_rdptr; +logic rst_mbox_rdptr; +logic rst_mbox_wrptr; +logic sram_rd_ecc_en; +logic [MBOX_DATA_W-1:0] sram_rdata; +logic [MBOX_ECC_DATA_W-1:0] sram_rdata_ecc; +logic [MBOX_DATA_W-1:0] sram_rdata_cor; +logic [MBOX_ECC_DATA_W-1:0] sram_rdata_cor_ecc; +logic sram_we; +logic mbox_protocol_sram_we; +logic mbox_protocol_sram_rd, mbox_protocol_sram_rd_f; +logic dir_req_dv_q, dir_req_rd_phase; +logic dir_req_wr_ph; +logic dma_sram_req_dv_q, dma_sram_req_rd_phase; +logic mask_rdata; +logic [MBOX_DEPTH_LOG2-1:0] dir_req_addr; + +logic soc_has_lock, soc_has_lock_nxt; +logic uc_has_lock, uc_has_lock_nxt; +logic tap_has_lock, tap_has_lock_nxt; +logic req_data_uc_req; +logic valid_requester; +logic valid_receiver; + +logic [MBOX_DEPTH_LOG2:0] mbox_dlen_in_dws; +logic latch_dlen_in_dws; +logic [MBOX_DEPTH_LOG2:0] dlen_in_dws, dlen_in_dws_nxt; +logic rdptr_inc_valid; +logic mbox_rd_valid, mbox_rd_valid_f; +logic wrptr_inc_valid; + +mbox_protocol_error_t mbox_protocol_error_nxt; + +logic tap_mode; +logic tap_mbox_data_avail; + +//csr +logic [MBOX_DATA_W-1:0] csr_rdata; +logic read_error; +logic write_error; + +mbox_csr__in_t hwif_in; +mbox_csr__out_t hwif_out; + +assign mbox_error = read_error | write_error; + +assign tap_mode = hwif_out.tap_mode.enabled.value; + +assign uc_mbox_lock = uc_has_lock; + +assign req_data_uc_req = ~req_data_soc_req; + + +//Determine if this is a valid request from the requester side +//1) uC requests are valid if uc has lock +//2) SoC requests are valid if soc has lock and it's the AXI USER that locked it +always_comb valid_requester = hwif_out.mbox_lock.lock.value & + ((req_data_uc_req & (uc_has_lock || (mbox_fsm_ps == MBOX_EXECUTE_UC))) | + (req_data_soc_req & soc_has_lock & (req_data_user == hwif_out.mbox_user.user.value[MBOX_IFC_USER_W-1:0]))); + +//Determine if this is a valid request from the receiver side +always_comb valid_receiver = hwif_out.mbox_lock.lock.value & + //Receiver is valid when in their execute state + //if they don't have the lock + ((req_data_uc_req & (soc_has_lock | tap_has_lock) & (mbox_fsm_ps == MBOX_EXECUTE_UC )) | + (req_data_soc_req & uc_has_lock & (mbox_fsm_ps == MBOX_EXECUTE_SOC)) | + //Receiver is valid when they are reading a response to their request + (valid_requester & ((soc_has_lock & (mbox_fsm_ps == MBOX_EXECUTE_SOC)) | + (uc_has_lock & (mbox_fsm_ps == MBOX_EXECUTE_UC))))); + +//We want to mask read data when +//Invalid ID is trying to access the mailbox data +always_comb mask_rdata = hwif_out.mbox_dataout.dataout.swacc & ~valid_receiver; + +//move from idle to rdy for command when lock is acquired +//we have a valid read, to the lock register, and it's not currently locked +always_comb arc_MBOX_IDLE_MBOX_RDY_FOR_CMD = (mbox_fsm_ps == MBOX_IDLE) & ~hwif_out.mbox_lock.lock.value & (hwif_out.mbox_lock.lock.swmod | hwif_in.mbox_lock.lock.hwset); +//move from rdy for cmd to rdy for dlen when cmd is written +always_comb arc_MBOX_RDY_FOR_CMD_MBOX_RDY_FOR_DLEN = (mbox_fsm_ps == MBOX_RDY_FOR_CMD) & ((hwif_out.mbox_cmd.command.swmod & valid_requester) | hwif_in.mbox_cmd.command.we); +//move from rdy for dlen to rdy for data when dlen is written +always_comb arc_MBOX_RDY_FOR_DLEN_MBOX_RDY_FOR_DATA = (mbox_fsm_ps == MBOX_RDY_FOR_DLEN) & ((hwif_out.mbox_dlen.length.swmod & valid_requester) | hwif_in.mbox_dlen.length.we); +//move from rdy for data to execute uc when SoC sets execute bit +always_comb arc_MBOX_RDY_FOR_DATA_MBOX_EXECUTE_UC = (mbox_fsm_ps == MBOX_RDY_FOR_DATA) & hwif_out.mbox_execute.execute.value & (soc_has_lock | tap_has_lock); +//move from rdy for data to execute soc when uc writes to execute +always_comb arc_MBOX_RDY_FOR_DATA_MBOX_EXECUTE_SOC = (mbox_fsm_ps == MBOX_RDY_FOR_DATA) & hwif_out.mbox_execute.execute.value & uc_has_lock & ~tap_mode; +//move from rdy for data to execute tap when uc writes to execute in tap_mode +always_comb arc_MBOX_RDY_FOR_DATA_MBOX_EXECUTE_TAP = (mbox_fsm_ps == MBOX_RDY_FOR_DATA) & hwif_out.mbox_execute.execute.value & uc_has_lock & tap_mode; +//move from rdy to execute to idle when uc resets execute +always_comb arc_MBOX_EXECUTE_UC_MBOX_IDLE = (mbox_fsm_ps == MBOX_EXECUTE_UC) & ~hwif_out.mbox_execute.execute.value; +always_comb arc_MBOX_EXECUTE_UC_MBOX_EXECUTE_SOC = (mbox_fsm_ps == MBOX_EXECUTE_UC) & soc_has_lock & ~tap_mode & (hwif_out.mbox_status.status.value != CMD_BUSY); +always_comb arc_MBOX_EXECUTE_UC_MBOX_EXECUTE_TAP = (mbox_fsm_ps == MBOX_EXECUTE_UC) & tap_has_lock & (hwif_out.mbox_status.status.value != CMD_BUSY); +//move from rdy to execute to idle when SoC resets execute +always_comb arc_MBOX_EXECUTE_SOC_MBOX_IDLE = (mbox_fsm_ps == MBOX_EXECUTE_SOC) & ~hwif_out.mbox_execute.execute.value; +always_comb arc_MBOX_EXECUTE_SOC_MBOX_EXECUTE_UC = (mbox_fsm_ps == MBOX_EXECUTE_SOC) & uc_has_lock & ~tap_mode & (hwif_out.mbox_status.status.value != CMD_BUSY); +//move from rdy to execute to idle when uc resets execute +always_comb arc_MBOX_EXECUTE_TAP_MBOX_IDLE = (mbox_fsm_ps == MBOX_EXECUTE_TAP) & ~hwif_out.mbox_execute.execute.value; +always_comb arc_MBOX_EXECUTE_TAP_MBOX_EXECUTE_UC = (mbox_fsm_ps == MBOX_EXECUTE_TAP) & uc_has_lock & tap_mode & ~tap_has_lock & (hwif_out.mbox_status.status.value != CMD_BUSY); +//move back to IDLE and unlock when force unlock is set +always_comb arc_FORCE_MBOX_UNLOCK = hwif_out.mbox_unlock.unlock.value; +// Detect error conditions and peg to the error state until serviced. +// Any register write (or read from mbox_dataout) by a VALID agent +// while in the incorrect state for access to that register results +// in transition to MBOX_ERROR and assertion of the protocol_error. +// Any register write or read by an INVALID agent results in the access +// being silently dropped. +// Assumption: uC (ROM, FMC, RT) will never make an invalid request. +// NOTE: Any AXI agent can trigger the error at any point during a uC->SOC flow +// by writing to mbox_status (since it's a valid_receiver). +// FIXED! valid_receiver is restricted by FSM state now. +always_comb arc_MBOX_RDY_FOR_CMD_MBOX_ERROR = (mbox_fsm_ps == MBOX_RDY_FOR_CMD) && + req_dv && req_data_soc_req && ~req_hold && valid_requester && + (req_data_write ? (!hwif_out.mbox_cmd.command.swmod) : + (hwif_out.mbox_dataout.dataout.swacc)); +always_comb arc_MBOX_RDY_FOR_DLEN_MBOX_ERROR = (mbox_fsm_ps == MBOX_RDY_FOR_DLEN) && + req_dv && req_data_soc_req && ~req_hold && valid_requester && + (req_data_write ? (!hwif_out.mbox_dlen.length.swmod) : + (hwif_out.mbox_dataout.dataout.swacc)); +always_comb arc_MBOX_RDY_FOR_DATA_MBOX_ERROR = (mbox_fsm_ps == MBOX_RDY_FOR_DATA) && + req_dv && req_data_soc_req && ~req_hold && valid_requester && + (req_data_write ? (!(hwif_out.mbox_datain.datain.swmod || hwif_out.mbox_execute.execute.swmod)) : + (hwif_out.mbox_dataout.dataout.swacc)); +always_comb arc_MBOX_EXECUTE_UC_MBOX_ERROR = (mbox_fsm_ps == MBOX_EXECUTE_UC) && + req_dv && req_data_soc_req && ~req_hold && valid_requester && + (req_data_write ? (1'b1/* any write by 'valid' soc is illegal here */) : + (hwif_out.mbox_dataout.dataout.swacc)); +always_comb arc_MBOX_EXECUTE_SOC_MBOX_ERROR = (mbox_fsm_ps == MBOX_EXECUTE_SOC) && + req_dv && req_data_soc_req && ~req_hold && + (req_data_write ? ((valid_requester && !(hwif_out.mbox_execute.execute.swmod)) || + (uc_has_lock && !(hwif_out.mbox_status.status.swmod))) : + (1'b0 /* any read allowed by SoC during this stage; dataout consumption is expected */)); +always_comb arc_MBOX_EXECUTE_TAP_MBOX_ERROR = 1'b0; + +//capture the dlen when we change to execute states, this ensures that only the dlen programmed +//by the client filling the mailbox is used for masking the data +//Store the dlen as a ptr to the last entry +always_comb latch_dlen_in_dws = arc_MBOX_RDY_FOR_DATA_MBOX_EXECUTE_UC | arc_MBOX_RDY_FOR_DATA_MBOX_EXECUTE_SOC | arc_MBOX_EXECUTE_UC_MBOX_EXECUTE_SOC | + arc_MBOX_RDY_FOR_DATA_MBOX_EXECUTE_TAP | arc_MBOX_EXECUTE_TAP_MBOX_EXECUTE_UC | arc_MBOX_EXECUTE_UC_MBOX_EXECUTE_TAP; +always_comb mbox_dlen_in_dws = (hwif_out.mbox_dlen.length.value >= MBOX_SIZE_BYTES) ? MBOX_SIZE_DWORDS[MBOX_DEPTH_LOG2:0] : + (hwif_out.mbox_dlen.length.value[MBOX_DEPTH_LOG2+2:2]) + (hwif_out.mbox_dlen.length.value[0] | hwif_out.mbox_dlen.length.value[1]); +//latched dlen is the smaller of the programmed dlen or the current wrptr +//this avoids a case where a sender writes less than programmed and the receiver can read beyond that +//if the mailbox is full (flag set when writing last entry), always take the programmed dlen +always_comb dlen_in_dws_nxt = (~mbox_wr_full & ({1'b0,mbox_wrptr} < mbox_dlen_in_dws)) ? {1'b0,mbox_wrptr} : mbox_dlen_in_dws; + +// Restrict the read pointer from passing the dlen or rolling over +always_comb rdptr_inc_valid = ({1'b0,mbox_rdptr} < dlen_in_dws) & (mbox_rdptr < (MBOX_SIZE_DWORDS-1)); +// No more valid reads if we read the last entry +// On pre-load of entry 0, ensure that next dlen isn't 0 +// Restrict reads once read pointer has passed the dlen +always_comb mbox_rd_valid = (rst_mbox_rdptr & (dlen_in_dws_nxt != 0)) | (~rst_mbox_rdptr & ~mbox_rd_full & ({1'b0,mbox_rdptr} < dlen_in_dws)); +// Restrict the write pointer from rolling over +always_comb wrptr_inc_valid = mbox_wrptr < (MBOX_SIZE_DWORDS-1); + + +always_comb begin : mbox_fsm_combo + uc_has_lock_nxt = 0; + soc_has_lock_nxt = 0; + tap_has_lock_nxt = 0; + rst_mbox_rdptr = 0; //resetting the read pointer will pre-load dataout + rst_mbox_wrptr = 0; + inc_rdptr = 0; + inc_wrptr = 0; + uc_mbox_data_avail = 0; + soc_mbox_data_avail = 0; + tap_mbox_data_avail = 0; + mbox_protocol_error_nxt = '{default: 0}; + mbox_fsm_ns = mbox_fsm_ps; + + unique case (mbox_fsm_ps) + MBOX_IDLE: begin + if (arc_MBOX_IDLE_MBOX_RDY_FOR_CMD) begin + mbox_fsm_ns = MBOX_RDY_FOR_CMD; + soc_has_lock_nxt = req_data_soc_req & hwif_out.mbox_lock.lock.swmod; //soc requested the lock + uc_has_lock_nxt = ~req_data_soc_req & hwif_out.mbox_lock.lock.swmod; //uc requested the lock + tap_has_lock_nxt = hwif_in.mbox_lock.lock.hwset; //tap set the lock + end + // Flag a non-fatal error, but don't change states, if mbox is already IDLE + // when an unexpected SOC access happens + if (req_dv && req_data_soc_req && ~req_hold && (req_data_write || hwif_out.mbox_dataout.dataout.swacc)) begin + mbox_protocol_error_nxt.axs_without_lock = 1'b1; + end + end + MBOX_RDY_FOR_CMD: begin + if (arc_MBOX_RDY_FOR_CMD_MBOX_RDY_FOR_DLEN) begin + mbox_fsm_ns = MBOX_RDY_FOR_DLEN; + end + else if (arc_MBOX_RDY_FOR_CMD_MBOX_ERROR) begin + mbox_fsm_ns = MBOX_ERROR; + mbox_protocol_error_nxt.axs_incorrect_order = 1'b1; + end + if (arc_FORCE_MBOX_UNLOCK) begin + mbox_fsm_ns = MBOX_IDLE; + mbox_protocol_error_nxt = '{default: 0}; + end + end + MBOX_RDY_FOR_DLEN: begin + if (arc_MBOX_RDY_FOR_DLEN_MBOX_RDY_FOR_DATA) begin + mbox_fsm_ns = MBOX_RDY_FOR_DATA; + rst_mbox_wrptr = 1; + end + else if (arc_MBOX_RDY_FOR_DLEN_MBOX_ERROR) begin + mbox_fsm_ns = MBOX_ERROR; + mbox_protocol_error_nxt.axs_incorrect_order = 1'b1; + end + if (arc_FORCE_MBOX_UNLOCK) begin + mbox_fsm_ns = MBOX_IDLE; + mbox_protocol_error_nxt = '{default: 0}; + end + end + MBOX_RDY_FOR_DATA: begin + //update the write pointers to sram when accessing datain register + inc_wrptr = (hwif_out.mbox_datain.datain.swmod & valid_requester & ~req_hold) | + (dmi_inc_wrptr & tap_has_lock); + if (arc_MBOX_RDY_FOR_DATA_MBOX_EXECUTE_UC) begin + mbox_fsm_ns = MBOX_EXECUTE_UC; + //reset wrptr so receiver can write response + rst_mbox_wrptr = 1; + rst_mbox_rdptr = 1; + end + else if (arc_MBOX_RDY_FOR_DATA_MBOX_EXECUTE_SOC) begin + mbox_fsm_ns = MBOX_EXECUTE_SOC; + //reset wrptr so receiver can write response + rst_mbox_wrptr = 1; + rst_mbox_rdptr = 1; + end + else if (arc_MBOX_RDY_FOR_DATA_MBOX_EXECUTE_TAP) begin + mbox_fsm_ns = MBOX_EXECUTE_TAP; + //reset wrptr so receiver can write response + rst_mbox_wrptr = 1; + rst_mbox_rdptr = 1; + end + else if (arc_MBOX_RDY_FOR_DATA_MBOX_ERROR) begin + mbox_fsm_ns = MBOX_ERROR; + mbox_protocol_error_nxt.axs_incorrect_order = 1'b1; + end + if (arc_FORCE_MBOX_UNLOCK) begin + mbox_fsm_ns = MBOX_IDLE; + inc_wrptr = 0; + inc_rdptr = 0; + mbox_protocol_error_nxt = '{default: 0}; + end + end + //SoC set execute, data is for the uC + //only uC can read from mbox + //only uC can write to datain here to respond to SoC + MBOX_EXECUTE_UC: begin + uc_mbox_data_avail = 1; + inc_rdptr = dmi_inc_rdptr | (hwif_out.mbox_dataout.dataout.swacc & req_data_uc_req & ~req_hold); + inc_wrptr = hwif_out.mbox_datain.datain.swmod & req_data_uc_req & ~req_hold; + if (arc_MBOX_EXECUTE_UC_MBOX_IDLE) begin + mbox_fsm_ns = MBOX_IDLE; + end + else if (arc_MBOX_EXECUTE_UC_MBOX_EXECUTE_SOC) begin + mbox_fsm_ns = MBOX_EXECUTE_SOC; + rst_mbox_wrptr = 1; + rst_mbox_rdptr = 1; + end + else if (arc_MBOX_EXECUTE_UC_MBOX_EXECUTE_TAP) begin + mbox_fsm_ns = MBOX_EXECUTE_TAP; + rst_mbox_wrptr = 1; + rst_mbox_rdptr = 1; + end + else if (arc_MBOX_EXECUTE_UC_MBOX_ERROR) begin + mbox_fsm_ns = MBOX_ERROR; + mbox_protocol_error_nxt.axs_incorrect_order = 1'b1; + end + if (arc_FORCE_MBOX_UNLOCK) begin + mbox_fsm_ns = MBOX_IDLE; + inc_wrptr = 0; + inc_rdptr = 0; + mbox_protocol_error_nxt = '{default: 0}; + end + end + //uC set execute, data is for the SoC + //If we're here, restrict reading to the AXI USER that requested the data + //Only SoC can read from mbox + //Only SoC can write to datain here to respond to uC + MBOX_EXECUTE_SOC: begin + soc_mbox_data_avail = 1; + inc_rdptr = (dmi_inc_rdptr | (hwif_out.mbox_dataout.dataout.swacc & req_data_soc_req & valid_receiver & ~req_hold)); + if (arc_MBOX_EXECUTE_SOC_MBOX_IDLE) begin + mbox_fsm_ns = MBOX_IDLE; + end + else if (arc_MBOX_EXECUTE_SOC_MBOX_EXECUTE_UC) begin + mbox_fsm_ns = MBOX_EXECUTE_UC; + rst_mbox_wrptr = 1; + rst_mbox_rdptr = 1; + end + else if (arc_MBOX_EXECUTE_SOC_MBOX_ERROR) begin + mbox_fsm_ns = MBOX_ERROR; + mbox_protocol_error_nxt.axs_incorrect_order = 1'b1; + end + if (arc_FORCE_MBOX_UNLOCK) begin + mbox_fsm_ns = MBOX_IDLE; + inc_wrptr = 0; + inc_rdptr = 0; + mbox_protocol_error_nxt = '{default: 0}; + end + end + MBOX_EXECUTE_TAP: begin + tap_mbox_data_avail = 1; + inc_rdptr = (dmi_inc_rdptr); + inc_wrptr = (dmi_inc_wrptr); + if (arc_MBOX_EXECUTE_TAP_MBOX_IDLE) begin + mbox_fsm_ns = MBOX_IDLE; + end + else if (arc_MBOX_EXECUTE_TAP_MBOX_EXECUTE_UC) begin + mbox_fsm_ns = MBOX_EXECUTE_UC; + rst_mbox_wrptr = 1; + rst_mbox_rdptr = 1; + end + else if (arc_MBOX_EXECUTE_TAP_MBOX_ERROR) begin + mbox_fsm_ns = MBOX_ERROR; + mbox_protocol_error_nxt.axs_incorrect_order = 1'b1; + end + if (arc_FORCE_MBOX_UNLOCK) begin + mbox_fsm_ns = MBOX_IDLE; + inc_wrptr = 0; + inc_rdptr = 0; + mbox_protocol_error_nxt = '{default: 0}; + end + end + MBOX_ERROR: begin + mbox_protocol_error_nxt = '{default: 0}; + if (arc_FORCE_MBOX_UNLOCK) begin + mbox_fsm_ns = MBOX_IDLE; + mbox_protocol_error_nxt = '{default: 0}; + end + end + + default: begin + mbox_fsm_ns = mbox_fsm_ps; + end + endcase +end + +// Any ol' AXI_USER is fine for reg-reads (except dataout) +// NOTE: This only captures accesses by AXI agents that are valid, but do not +// have lock. Invalid agent accesses are blocked by arbiter. +assign mbox_inv_axi_user_axs = req_dv && req_data_soc_req && !req_hold && + !valid_requester && !valid_receiver && + (req_data_write || hwif_out.mbox_dataout.dataout.swacc); + + +//increment read ptr only if its allowed +always_comb mbox_protocol_sram_rd = inc_rdptr | rst_mbox_rdptr; +always_comb mbox_protocol_sram_we = inc_wrptr & ~mbox_wr_full; + +//flops +always_ff @(posedge clk or negedge rst_b) begin + if (!rst_b)begin + mbox_fsm_ps <= MBOX_IDLE; + soc_has_lock <= '0; + uc_has_lock <= '0; + tap_has_lock <= '0; + dir_req_rd_phase <= '0; + dma_sram_req_rd_phase <= '0; + mbox_wrptr <= '0; + mbox_wr_full <= '0; + mbox_rdptr <= '0; + mbox_rd_full <= '0; + mbox_rd_valid_f <= '0; + mbox_protocol_sram_rd_f <= '0; + dlen_in_dws <= '0; + mbox_protocol_error <= '0; + sram_rd_ecc_en <= '0; + end + else begin + mbox_fsm_ps <= mbox_fsm_ns; + soc_has_lock <= arc_MBOX_IDLE_MBOX_RDY_FOR_CMD ? soc_has_lock_nxt : + hwif_out.mbox_lock.lock.value ? soc_has_lock : '0; + uc_has_lock <= arc_MBOX_IDLE_MBOX_RDY_FOR_CMD ? uc_has_lock_nxt : + hwif_out.mbox_lock.lock.value ? uc_has_lock : '0; + tap_has_lock <= arc_MBOX_IDLE_MBOX_RDY_FOR_CMD ? tap_has_lock_nxt : + hwif_out.mbox_lock.lock.value ? tap_has_lock : '0; + dir_req_rd_phase <= dir_req_dv_q & ~sha_sram_req_dv & ~(dma_sram_req_dv_q & dma_sram_req_write) & ~req_data_write; + dma_sram_req_rd_phase <= dma_sram_req_dv_q & ~sha_sram_req_dv & ~dma_sram_req_write; + mbox_wrptr <= ((inc_wrptr & wrptr_inc_valid) | rst_mbox_wrptr) ? mbox_wrptr_nxt : mbox_wrptr; + mbox_wr_full <= (inc_wrptr | rst_mbox_wrptr) ? mbox_wr_full_nxt : mbox_wr_full; + mbox_rdptr <= (mbox_protocol_sram_rd) ? mbox_rdptr_nxt : mbox_rdptr; + mbox_protocol_sram_rd_f <= (mbox_protocol_sram_rd | mbox_protocol_sram_rd_f) ? mbox_protocol_sram_rd : mbox_protocol_sram_rd_f; + mbox_rd_full <= (inc_rdptr | rst_mbox_rdptr) ? mbox_rd_full_nxt : mbox_rd_full; + mbox_rd_valid_f <= (mbox_rd_valid | mbox_rd_valid_f) ? mbox_rd_valid : mbox_rd_valid_f; + + dlen_in_dws <= latch_dlen_in_dws ? dlen_in_dws_nxt : dlen_in_dws; + mbox_protocol_error <= mbox_protocol_error_nxt; + //enable ecc for mbox protocol, direct reads, or SHA direct reads + sram_rd_ecc_en <= mbox_protocol_sram_rd | (dir_req_dv_q & ~sha_sram_req_dv & ~req_data_write) | (dma_sram_req_dv_q & ~dma_sram_req_write) | sha_sram_req_dv; + end +end + +always_comb dma_sram_req_dv_q = dma_sram_req_dv & hwif_out.mbox_lock.lock.value & uc_has_lock & ~dma_sram_req_rd_phase; +//need to hold direct read accesses for 1 clock to get response +//create a qualified direct request signal that is masked during the data phase +//hold the interface to insert wait state when direct request comes +//mask the request and hold the interface if SHA is using the mailbox +//hold when a read to dataout is coming and we haven't updated the data yet +always_comb dir_req_dv_q = (dir_req_dv & ~dir_req_rd_phase & hwif_out.mbox_lock.lock.value & (uc_has_lock | (mbox_fsm_ps == MBOX_EXECUTE_UC))) | + (dma_sram_req_dv_q) | + sha_sram_req_dv; +always_comb dir_req_wr_ph = dir_req_dv_q & ~sha_sram_req_dv & ((~dma_sram_req_dv_q & req_data_write) | (dma_sram_req_dv_q & dma_sram_req_write)); +always_comb dir_req_addr = sha_sram_req_dv ? sha_sram_req_addr : + dma_sram_req_dv_q ? dma_sram_req_addr[MBOX_DEPTH_LOG2+1:2] : + req_data_addr[MBOX_DEPTH_LOG2+1:2]; + +// Arb precedence: +// SHA accelerator: highest +// DMA (with lock): next +// Direct request: lowest +// No arbitration/round-robin -- this is strictly observed for every txn + + //Direct read from uC, stall 1 clock dv_q will be de-asserted second clock +always_comb req_hold = (dir_req_dv_q & ~sha_sram_req_dv & ~dma_sram_req_dv_q & ~req_data_write) | + //Direct access from uC while sha accelerator or DMA is accessing + (dir_req_dv & ~dir_req_rd_phase & (sha_sram_req_dv | dma_sram_req_dv_q | dma_sram_req_rd_phase)) | + //in an update cycle for dataout register + (hwif_out.mbox_dataout.dataout.swacc & mbox_protocol_sram_rd_f); + +always_comb dma_sram_hold = (sha_sram_req_dv && !dma_sram_req_rd_phase) || (dma_sram_req_dv_q && !dma_sram_req_write); +always_comb sha_sram_hold = 1'b0; + +//SRAM interface +always_comb sram_we = dir_req_wr_ph | mbox_protocol_sram_we; +//align the direct address to a word +always_comb sram_rdaddr = dir_req_dv_q ? dir_req_addr : + rst_mbox_rdptr ? 'd0 : mbox_rdptr; +always_comb sram_waddr = dir_req_dv_q ? dir_req_addr : mbox_wrptr; +//data phase after request for direct access +//We want to mask the read data for certain accesses +always_comb rdata = ({MBOX_DATA_W{~mask_rdata}} & csr_rdata); +always_comb dir_rdata = dir_req_rd_phase ? sram_rdata_cor : '0; +always_comb dma_sram_rdata = dma_sram_req_rd_phase ? sram_rdata_cor : '0; + +always_comb dma_sram_error = 1'b0; // TODO: ecc error? + +always_comb begin: mbox_sram_inf + //read live on direct access, or when pointer has been incremented, for pre-load on read pointer reset, or ecc correction + mbox_sram_req_cs = dir_req_dv_q | mbox_protocol_sram_we | mbox_protocol_sram_rd; + mbox_sram_req_we = sram_we; + mbox_sram_req_addr = sram_we ? sram_waddr : sram_rdaddr; + mbox_sram_req_wdata = sram_wdata; + mbox_sram_req_ecc = sram_wdata_ecc; + + sram_rdata = mbox_sram_resp_data; + sram_rdata_ecc = mbox_sram_resp_ecc; + sha_sram_resp_ecc = sram_rdata_cor_ecc; + sha_sram_resp_data = sram_rdata_cor; +end + +// From RISC-V core beh_lib.sv +// 32-bit data width hardcoded +// 7-bit ECC width hardcoded +rvecc_encode mbox_ecc_encode ( + .din (sram_wdata ), + .ecc_out(sram_wdata_ecc) +); +// synthesis translate_off +`ifdef CLP_ASSERT_ON +initial assert(MBOX_DATA_W == 32) else + $error("%m::rvecc_encode supports 32-bit data width; must change SRAM ECC implementation to support MBOX_DATA_W = %d", MBOX_DATA_W); +`endif +// synthesis translate_on +rvecc_decode ecc_decode ( + .en (sram_rd_ecc_en ), + .sed_ded ( 1'b0 ), // 1 : means only detection + .din (sram_rdata ), + .ecc_in (sram_rdata_ecc ), + .dout (sram_rdata_cor ), + .ecc_out (sram_rdata_cor_ecc ), + .single_ecc_error(sram_single_ecc_error), // TODO use to flag write-back + .double_ecc_error(sram_double_ecc_error) // TODO use to flag command error +); + +//control for sram write and read pointer +//SoC access is controlled by mailbox, each subsequent read or write increments the pointer +//uC accesses can specify the specific read or write address, or rely on mailbox to control +//if tap has lock or is responding to a request it can write instead +always_comb sram_wdata = (dma_sram_req_dv_q && dma_sram_req_write ) ? dma_sram_req_wdata : + (dmi_inc_wrptr & ((mbox_fsm_ps == MBOX_EXECUTE_TAP) | tap_has_lock)) ? dmi_reg_wdata : + req_data_wdata; + +//in ready for data state we increment the pointer each time we write +always_comb mbox_wrptr_nxt = rst_mbox_wrptr ? '0 : + (inc_wrptr & wrptr_inc_valid) ? mbox_wrptr + 'd1 : + mbox_wrptr; + +always_comb mbox_wr_full_nxt = rst_mbox_wrptr ? '0 : inc_wrptr & (mbox_wrptr == (MBOX_DEPTH-1)); + +//in execute state we increment the pointer each time we write +always_comb mbox_rdptr_nxt = rst_mbox_rdptr ? 'd1 : + (inc_rdptr & rdptr_inc_valid) ? mbox_rdptr + 'd1 : + mbox_rdptr; + +always_comb mbox_rd_full_nxt = rst_mbox_rdptr ? '0 : inc_rdptr & (mbox_rdptr == (MBOX_DEPTH-1)); + +//Intterupts +//Notify uC when it has the lock and SoC is requesting the lock +always_comb soc_req_mbox_lock = hwif_out.mbox_lock.lock.value & uc_has_lock & hwif_out.mbox_lock.lock.swmod & req_data_soc_req; + +always_comb hwif_in.cptra_rst_b = rst_b; +always_comb hwif_in.mbox_user.user.next = 32'(req_data_user); +always_comb hwif_in.mbox_status.mbox_fsm_ps.next = mbox_fsm_ps; + +always_comb hwif_in.soc_req = req_data_soc_req; +//check the requesting ID: +//don't update mailbox data if lock hasn't been acquired +//if uc has the lock, check that this request is from uc +//if soc has the lock, check that this request is from soc and ID attributes match +always_comb hwif_in.valid_requester = valid_requester; +always_comb hwif_in.valid_receiver = valid_receiver; + +//indicate that requesting ID is setting the lock +always_comb hwif_in.lock_set = arc_MBOX_IDLE_MBOX_RDY_FOR_CMD; + +//update dataout +always_comb hwif_in.mbox_dataout.dataout.swwe = '0; //no sw write enable, but need the storage element +//update dataout whenever we read from the sram for a dataout access +//we load the first entry on the arc to execute +always_comb hwif_in.mbox_dataout.dataout.we = mbox_protocol_sram_rd_f; +always_comb hwif_in.mbox_dataout.dataout.next = mbox_rd_valid_f ? sram_rdata_cor : '0; +//clear the lock when moving from execute to idle +always_comb hwif_in.mbox_lock.lock.hwclr = arc_MBOX_EXECUTE_SOC_MBOX_IDLE | arc_MBOX_EXECUTE_UC_MBOX_IDLE | arc_MBOX_EXECUTE_TAP_MBOX_IDLE | arc_FORCE_MBOX_UNLOCK; +//clear the mailbox status when we go back to IDLE +always_comb hwif_in.mbox_status.status.hwclr = arc_MBOX_EXECUTE_SOC_MBOX_IDLE | arc_MBOX_EXECUTE_UC_MBOX_IDLE | arc_MBOX_EXECUTE_TAP_MBOX_IDLE | arc_FORCE_MBOX_UNLOCK; +//clear the execute register when we force unlock +always_comb hwif_in.mbox_execute.execute.hwclr = arc_FORCE_MBOX_UNLOCK; +// Set mbox_csr status fields in response to ECC errors +always_comb hwif_in.mbox_status.ecc_single_error.hwset = sram_single_ecc_error; +always_comb hwif_in.mbox_status.ecc_double_error.hwset = sram_double_ecc_error; +always_comb hwif_in.mbox_status.soc_has_lock.next = soc_has_lock; +always_comb hwif_in.mbox_status.tap_has_lock.next = tap_has_lock; +//Assign valid read pointer bits to status register +always_comb begin + hwif_in.mbox_status.mbox_rdptr.next = '0; + for (int i = 0; i < MBOX_DEPTH_LOG2; i++) begin //rdptr status register is hardcoded to 256KB depth + hwif_in.mbox_status.mbox_rdptr.next[i] = mbox_rdptr[i]; + end +end + +//Set the lock if tap is reading a 0 +always_comb hwif_in.mbox_lock.lock.hwset = dmi_mbox_avail & dmi_reg_ren & (dmi_reg_addr == DMI_REG_MBOX_LOCK_ADDR) & ~hwif_out.mbox_lock.lock.value & ~hwif_out.mbox_lock.lock.swmod; + +always_comb hwif_in.mbox_cmd.command.we = dmi_mbox_avail & dmi_reg_wen & (dmi_reg_addr == DMI_REG_MBOX_CMD_ADDR) & (tap_has_lock | (mbox_fsm_ps == MBOX_EXECUTE_TAP)); +always_comb hwif_in.mbox_cmd.command.next = dmi_reg_wdata; + +always_comb hwif_in.mbox_dlen.length.we = dmi_mbox_avail & dmi_reg_wen & (dmi_reg_addr == DMI_REG_MBOX_DLEN_ADDR) & (tap_has_lock | (mbox_fsm_ps == MBOX_EXECUTE_TAP)); +always_comb hwif_in.mbox_dlen.length.next = dmi_reg_wdata; + +always_comb hwif_in.mbox_status.status.we = dmi_mbox_avail & dmi_reg_wen & (dmi_reg_addr == DMI_REG_MBOX_STATUS_ADDR) & (tap_has_lock | (mbox_fsm_ps == MBOX_EXECUTE_TAP)); +always_comb hwif_in.mbox_status.status.next = dmi_reg_wdata[3:0]; + +always_comb hwif_in.mbox_execute.execute.we = dmi_mbox_avail & dmi_reg_wen & (dmi_reg_addr == DMI_REG_MBOX_EXECUTE_ADDR) & (tap_has_lock); +always_comb hwif_in.mbox_execute.execute.next = dmi_reg_wdata[0]; + + +//return a 1 on the lock if software is requesting the lock to avoid tap and sw thinking they got the lock +//always show locked if dmi mbox avail not set +always_comb dmi_reg.MBOX_LOCK = {31'b0, (hwif_out.mbox_lock.lock.value | hwif_out.mbox_lock.lock.swmod | ~dmi_mbox_avail)}; +always_comb dmi_reg.MBOX_CMD = hwif_out.mbox_cmd.command.value; +always_comb dmi_reg.MBOX_DLEN = hwif_out.mbox_dlen.length.value; +always_comb dmi_reg.MBOX_DOUT = hwif_out.mbox_dataout.dataout.value; +always_comb dmi_reg.MBOX_STATUS = {5'b0, /* [31:27] */ + hwif_out.mbox_status.tap_has_lock.value, /* [26] */ + hwif_out.mbox_status.mbox_rdptr.value, /* [25:10]*/ + hwif_out.mbox_status.soc_has_lock.value, /* [9] */ + hwif_out.mbox_status.mbox_fsm_ps.value, /* [8:6] */ + hwif_out.mbox_status.ecc_double_error.value, /* [5] */ + hwif_out.mbox_status.ecc_single_error.value, /* [4] */ + hwif_out.mbox_status.status.value /* [3:0] */ + }; + +logic [MBOX_IFC_DATA_W-1:0] s_cpuif_wr_biten; +logic s_cpuif_req_stall_wr_nc; +logic s_cpuif_req_stall_rd_nc; +logic s_cpuif_rd_ack_nc; +logic s_cpuif_wr_ack_nc; + +genvar i; +generate + for (i=0;i= 50 + parameter bit ForceRandExt = 1'b0, // 1: Always forward externally provided randomness. + // 0: Switch between external randomness and internal + // intermediate state according to schedule. + localparam int Share = EnMasking ? 2 : 1 +) ( + input clk_i, + input rst_ni, + + // Message Feed + input valid_i, + input [DInAddr-1:0] addr_i, + input [DInWidth-1:0] data_i [Share], + output ready_o, + + // In-process control + input run_i, // Pulse signal to initiates Keccak full round + input rand_valid_i, + input rand_early_i, + input [Width/2-1:0] rand_data_i, + input rand_aux_i, + output logic rand_update_o, + output logic rand_consumed_o, + + output logic complete_o, // Indicates full round is done + + // State out. This can be used as Digest + output logic [Width-1:0] state_o [Share], + + // Life cycle + input lc_ctrl_pkg::lc_tx_t lc_escalate_en_i, + + // Errors: + // sparse_fsm_error: Checking if FSM state falls into unknown value + output logic sparse_fsm_error_o, + // round_count_error: prim_count checks round value consistency + output logic round_count_error_o, + // rst_storage_error: check if reset signal asserted out of the + // permitted window + output logic rst_storage_error_o, + + input mubi4_t clear_i // Clear internal state to '0 +); + + import ot_sha3_pkg::*; + + ///////////////////// + // Control signals // + ///////////////////// + + // Update storage register + logic update_storage; + + // Reset the storage to 0 to initiate new Hash operation + logic rst_storage; + + // XOR message into storage register + // It only does based on the given DInWidth. + // If DInWidth < Width, it takes multiple cycles to XOR all message + logic xor_message; + + // Select Keccak_p datapath + // 0: Select Phase1 (Theta -> Rho -> Pi) + // 1: Select Phase2 (Chi -> Iota) + // `phase_sel` needs to be asserted until the Chi stage is consumed, + mubi4_t phase_sel; + + // DOM multiplier input/output mux control + // 0: first compute upper, then lower lane halves + // 1: first compute lower, then upper lane halves + logic low_then_high_d, low_then_high_q; + // 0: drive/select upper lane halves + // 1: drive/select lower lane halves + logic dom_out_low_d, dom_out_low_q; + logic dom_in_low_d, dom_in_low_q; + // 0: forward external randomness input + // 1: forward partial intermediate results + logic dom_in_rand_ext_d, dom_in_rand_ext_q; + // 0: keep current intermediate results in pipeline registers + // 1: latch new intermediate results into pipeline registers + logic dom_update; + + // Increase/ Reset Round number + logic inc_rnd_num; + logic rst_rnd_num; + + // Round reaches end + // This signal indicates the round reaches desired number, which is MaxRound -1. + // MaxRound is dependant on the Width. In case of SHA3/SHAKE, MaxRound is 24. + logic rnd_eq_end; + + // Complete of Keccak_f + // State machine asserts `complete_d` when it reaches at the end of round and + // operation (Phase3 if Masked). The stage, the storage still doesn't have + // the valid states. So precisely it is not completed yet. + // State generated `complete_d` is latched with the clock and creates a pulse + // signal one cycle later. The signal is the indication of completion. + // + // Intentionally removed any intermediate step (so called StComplete) in order + // to save a clock to proceeds next round. + logic complete_d; + + ////////////////////// + // Datapath Signals // + ////////////////////// + + // Single round keccak output data + logic [Width-1:0] keccak_out [Share]; + + // Keccak Round indicator: range from 0 .. MaxRound + logic [RndW-1:0] round; + + // Random value and valid signal used in Keccak_p + logic keccak_rand_update; + logic keccak_rand_consumed; + logic [Width/2-1:0] keccak_rand_data; + + ////////////////////// + // Keccak Round FSM // + ////////////////////// + + // state inputs + assign rnd_eq_end = (int'(round) == MaxRound - 1); + + keccak_st_e keccak_st, keccak_st_d; + `CALIPTRA_PRIM_FLOP_SPARSE_FSM(u_state_regs, keccak_st_d, keccak_st, keccak_st_e, KeccakStIdle) + + // Next state logic and output logic + // SEC_CM: FSM.SPARSE + always_comb begin + // Default values + keccak_st_d = keccak_st; + + xor_message = 1'b 0; + update_storage = 1'b 0; + rst_storage = 1'b 0; + + inc_rnd_num = 1'b 0; + rst_rnd_num = 1'b 0; + + keccak_rand_update = 1'b 0; + keccak_rand_consumed = 1'b 0; + + phase_sel = MuBi4False; + low_then_high_d = low_then_high_q; + dom_in_low_d = dom_in_low_q; + dom_in_rand_ext_d = dom_in_rand_ext_q; + dom_update = 1'b 0; + + complete_d = 1'b 0; + + sparse_fsm_error_o = 1'b 0; + + unique case (keccak_st) + KeccakStIdle: begin + if (valid_i) begin + // State machine allows Sponge Absorbing only in Idle state. + keccak_st_d = KeccakStIdle; + + xor_message = 1'b 1; + update_storage = 1'b 1; + end else if (mubi4_test_true_strict(clear_i)) begin + // Opt1. State machine allows resetting the storage only in Idle + // Opt2. storage resets regardless of states but clear_i + // Both are added in the design at this time. Will choose the + // direction later. + keccak_st_d = KeccakStIdle; + + rst_storage = 1'b 1; + end else if (EnMasking && run_i) begin + // Masked version of Keccak handling + keccak_st_d = KeccakStPhase1; + + // Drive DOM multiplier I/O mux signals for Phase 1. + dom_in_low_d = low_then_high_q; + dom_in_rand_ext_d = 1'b 0; + end else if (!EnMasking && run_i) begin + // Unmasked version of Keccak handling + keccak_st_d = KeccakStActive; + end else begin + keccak_st_d = KeccakStIdle; + end + end + + KeccakStActive: begin + // Run Keccak single round logic until it reaches MaxRound - 1 + update_storage = 1'b 1; + + if (rnd_eq_end) begin + keccak_st_d = KeccakStIdle; + + rst_rnd_num = 1'b 1; + complete_d = 1'b 1; + end else begin + keccak_st_d = KeccakStActive; + + inc_rnd_num = 1'b 1; + end + end + + KeccakStPhase1: begin + // Compute Theta, Rho, Pi - The DOM multipliers are not evaluated at + // all: their inputs are driven by the first lane halves (same values + // as in Phase2Cycle3 of the last round). Also, the intermediate + // results we already had in Phase2Cycle3 didn't change. + phase_sel = MuBi4False; + dom_update = 1'b 0; + + // Only update the state and move on once we know the auxiliary + // randomness required for Phase2 will be available in the next clock + // cycle. + // + // It's important that the DOM multipliers inside keccak_2share are + // presented the new state (updated with update_storage) at the same + // time as the new randomness (updated with rand_update_o). Otherwise, + // stale entropy is paired with fresh data or vice versa. This could + // lead to undesired SCA leakage. + if (rand_early_i || rand_valid_i) begin + keccak_st_d = KeccakStPhase2Cycle1; + update_storage = 1'b 1; + keccak_rand_update = 1'b 1; + + // Update lane halves processing order for this round. + low_then_high_d = rand_aux_i; + + // Drive DOM multiplier I/O mux signals for next phase. + dom_in_low_d = low_then_high_d; + dom_in_rand_ext_d = 1'b 1; + end else begin + keccak_st_d = KeccakStPhase1; + end + end + + KeccakStPhase2Cycle1: begin + // Compute first stage of Chi for first lane halves using the DOM + // multipliers. Use the fresh randomness provided by the PRNG for + // remasking. + phase_sel = MuBi4True; + dom_update = 1'b 1; + + // Trigger randomness update for next cycle. + // It's important that the DOM multipliers inside keccak_2share are + // presented the second lane halves at the same time as the new + // randomness (updated with rand_update_o). Otherwise, stale entropy + // is paired with fresh data or vice versa. This could lead to + // undesired SCA leakage. + keccak_rand_update = 1'b 1; + + // Unconditionally move to next phase/cycle. + keccak_st_d = KeccakStPhase2Cycle2; + + // Drive DOM multiplier I/O mux signals for next phase. + dom_in_low_d = ~low_then_high_q; + dom_in_rand_ext_d = 1'b 1; + end + + KeccakStPhase2Cycle2: begin + // Chi Stage 1 for second lane halves. + // Chi Stage 2 and Iota for first lane halves. + // Compute second stage of Chi and Iota for first lane halves. + // Compute first stage of Chi for second lane halves. Use the fresh + // randomness provided by the PRNG for remasking the DOM multipliers. + phase_sel = MuBi4True; + dom_update = 1'b 1; + + // Trigger randomness update for next cycle. + // It's important that the DOM multipliers inside keccak_2share are + // presented the updated state at the same as the new randomness + // (updated with rand_update_o) - even if the DOM multipliers don't + // update the pipeline registers in the next cycle. Otherwise, stale + // entropy is paired with fresh data or vice versa. This could lead to + // undesired SCA leakage. + keccak_rand_update = 1'b 1; + + // Trigger auxiliary randomness update for next round. The rand_aux_i + // signal is actually going to change in 2 clock cycles from now + // (Phase1) based on the PRNG output in the next cycle (Phase2Cycle3) + // in which the DOM multipliers don't update the pipeline registers. + keccak_rand_consumed = 1'b 1; + + // Update first lane halves. + update_storage = 1'b 1; + + // Unconditionally move to next phase/cycle. + keccak_st_d = KeccakStPhase2Cycle3; + + // Drive DOM multiplier I/O mux signals for next phase. + dom_in_low_d = low_then_high_q; + dom_in_rand_ext_d = 1'b 0; + end + + KeccakStPhase2Cycle3: begin + // Compute second stage of Chi and Iota for second lane halves. + // Feed again first lane halves to DOM multiplier inputs (now + // the updated values become visible) together with intermediate + // results of Phase2Cycle2. Don't update the register stage inside + // the DOM multipliers. + phase_sel = MuBi4True; + dom_update = 1'b 0; + + // Update second lane halves. + // We don't need fresh randomness for the next cycle as the DOM + // multipliers inside keccak_2share will keep seeing the first + // lane halves in the next cycle. If we updated the randomness, + // old data got combined with frash randomness which is not + // desirable as it could lead to SCA leakage. + update_storage = 1'b 1; + + if (rnd_eq_end) begin + // We're done. + keccak_st_d = KeccakStIdle; + + rst_rnd_num = 1'b 1; + complete_d = 1'b 1; + end else begin + // Continue to the next round. + keccak_st_d = KeccakStPhase1; + + inc_rnd_num = 1'b 1; + + // Drive DOM multiplier I/O mux signals for next phase. + dom_in_low_d = low_then_high_q; + dom_in_rand_ext_d = 1'b 0; + end + end + + KeccakStError: begin + keccak_st_d = KeccakStError; + end + + KeccakStTerminalError: begin + //this state is terminal + keccak_st_d = keccak_st; + sparse_fsm_error_o = 1'b 1; + end + + default: begin + keccak_st_d = KeccakStTerminalError; + sparse_fsm_error_o = 1'b 1; + end + endcase + + // SEC_CM: FSM.GLOBAL_ESC, FSM.LOCAL_ESC + // Unconditionally jump into the terminal error state + // if the life cycle controller triggers an escalation. + if (lc_ctrl_pkg::lc_tx_test_true_loose(lc_escalate_en_i)) begin + keccak_st_d = KeccakStTerminalError; + end + end + + // When taking the lower lane halves in, the upper lane halves are output and + // vice versa. + assign dom_out_low_d = ~dom_in_low_d; + + if (EnMasking) begin : gen_regs_dom_ctrl + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + low_then_high_q <= 1'b 0; + dom_out_low_q <= 1'b 0; + dom_in_low_q <= 1'b 0; + end else begin + low_then_high_q <= low_then_high_d; + dom_out_low_q <= dom_out_low_d; + dom_in_low_q <= dom_in_low_d; + end + end + + if (!ForceRandExt) begin : gen_reg_dom_in_rand_ext + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + dom_in_rand_ext_q <= 1'b 0; + end else begin + dom_in_rand_ext_q <= dom_in_rand_ext_d; + end + end + end else begin : gen_force_dom_in_rand_ext + // Always forward the externally provided randomness. + assign dom_in_rand_ext_q = 1'b 1; + // Tie off unused signals. + logic unused_dom_in_rand_ext; + assign unused_dom_in_rand_ext = dom_in_rand_ext_d; + end + end else begin : gen_no_regs_dom_ctrl + logic unused_dom_ctrl; + assign unused_dom_ctrl = + ^{low_then_high_d, dom_out_low_d, dom_in_low_d, dom_in_rand_ext_d}; + assign low_then_high_q = 1'b 0; + assign dom_out_low_q = 1'b 0; + assign dom_in_low_q = 1'b 0; + assign dom_in_rand_ext_q = 1'b 0; + end + + // Ready indicates the keccak_round is able to receive new message. + // While keccak_round is processing the data, it blocks the new message to be + // XORed into the current state. + assign ready_o = (keccak_st == KeccakStIdle) ? 1'b 1 : 1'b 0; + + //////////////////////////// + // Keccak state registers // + //////////////////////////// + + // SEC_CM: LOGIC.INTEGRITY + logic rst_n; + caliptra_prim_sec_anchor_buf #( + .Width(1) + ) u_caliptra_prim_sec_anchor_buf ( + .in_i(rst_ni), + .out_o(rst_n) + ); + + logic [Width-1:0] storage [Share]; + logic [Width-1:0] storage_d [Share]; + always_ff @(posedge clk_i or negedge rst_n) begin + if (!rst_n) begin + storage <= '{default:'0}; + end else if (rst_storage) begin + storage <= '{default:'0}; + end else if (update_storage) begin + storage <= storage_d; + end + end + + assign state_o = storage; + + // Storage register input + // The incoming message is XORed with the existing storage registers. + // The logic can accept not a block size incoming message chunk but + // the size defined in `DInWidth` parameter with its position. + + always_comb begin + storage_d = keccak_out; + if (xor_message) begin + for (int j = 0 ; j < Share ; j++) begin + for (int unsigned i = 0 ; i < DInEntry ; i++) begin + // ICEBOX(#18029): handle If Width is not integer divisable by DInWidth + // Currently it is not allowed to have partial write + // Please see the Assertion `WidthDivisableByDInWidth_A` + if (addr_i == i[DInAddr-1:0]) begin + storage_d[j][i*DInWidth+:DInWidth] = + storage[j][i*DInWidth+:DInWidth] ^ data_i[j]; + end else begin + storage_d[j][i*DInWidth+:DInWidth] = storage[j][i*DInWidth+:DInWidth]; + end + end // for i + end // for j + end // if xor_message + end + + // Check the rst_storage integrity + logic rst_storage_error; + + always_comb begin : chk_rst_storage + rst_storage_error = 1'b 0; + + if (rst_storage) begin + // FSM should be in KeccakStIdle and clear_i should be high + if ((keccak_st != KeccakStIdle) || + mubi4_test_false_loose(clear_i)) begin + rst_storage_error = 1'b 1; + end + end + end : chk_rst_storage + + assign rst_storage_error_o = rst_storage_error ; + + ////////////// + // Datapath // + ////////////// + ot_keccak_2share #( + .Width(Width), + .EnMasking(EnMasking), + .ForceRandExt(ForceRandExt) + ) u_keccak_p ( + .clk_i, + .rst_ni, + + .lc_escalate_en_i, + + .rnd_i(round), + + .phase_sel_i (phase_sel), + .dom_out_low_i (dom_out_low_q), + .dom_in_low_i (dom_in_low_q), + .dom_in_rand_ext_i(dom_in_rand_ext_q), + .dom_update_i (dom_update), + + .rand_i(keccak_rand_data), + + .s_i(storage), + .s_o(keccak_out) + ); + + // keccak entropy handling + assign rand_update_o = keccak_rand_update; + assign rand_consumed_o = keccak_rand_consumed; + + assign keccak_rand_data = rand_data_i; + + // Round number + // This primitive is used to place a hardened counter + // SEC_CM: CTR.REDUN + caliptra_prim_count #( + .Width(RndW) + ) u_round_count ( + .clk_i, + .rst_ni, + .clr_i(rst_rnd_num), + .set_i(1'b0), + .set_cnt_i('0), + .incr_en_i(inc_rnd_num), + .decr_en_i(1'b0), + .step_i(RndW'(1)), + .commit_i(1'b1), + .cnt_o(round), + .cnt_after_commit_o(), + .err_o(round_count_error_o) + ); + + // completion signal + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + complete_o <= 1'b 0; + end else begin + complete_o <= complete_d; + end + end + + //////////////// + // Assertions // + //////////////// + + // Only allow `DInWidth` that `Width` is integer divisable by `DInWidth` + `CALIPTRA_ASSERT_INIT(WidthDivisableByDInWidth_A, (Width % DInWidth) == 0) + + // If `run_i` triggerred, it shall complete + //`CALIPTRA_ASSERT(RunResultComplete_A, run_i ##[MaxRound:] complete_o, clk_i, !rst_ni) + + // valid_i and run_i cannot be asserted at the same time + `CALIPTRA_ASSUME(OneHot0ValidAndRun_A, $onehot0({valid_i, run_i}), clk_i, !rst_ni) + + // valid_i, run_i only asserted in Idle state + `CALIPTRA_ASSUME(ValidRunAssertStIdle_A, valid_i || run_i |-> keccak_st == KeccakStIdle, clk_i, !rst_ni) + + // clear_i is assumed to be asserted in Idle state + `CALIPTRA_ASSUME(ClearAssertStIdle_A, + mubi4_test_true_strict(clear_i) + |-> keccak_st == KeccakStIdle, clk_i, !rst_ni) + + // EnMasking controls the valid states + if (EnMasking) begin : gen_mask_st_chk + `CALIPTRA_ASSERT(EnMaskingValidStates_A, keccak_st != KeccakStActive, clk_i, !rst_ni) + end else begin : gen_unmask_st_chk + `CALIPTRA_ASSERT(UnmaskValidStates_A, !(keccak_st + inside {KeccakStPhase1, KeccakStPhase2Cycle1, KeccakStPhase2Cycle2, KeccakStPhase2Cycle3}), + clk_i, !rst_ni) + end +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/ot_sha3.sv b/designs/Caliptra/src/caliptra-rtl/ot_sha3.sv new file mode 100644 index 0000000..1e22d56 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/ot_sha3.sv @@ -0,0 +1,533 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// SHA3 core is a fully functional SHA3/SHAKE/cSHAKE hashing module. +// +// It instantiates a keccak_round with 1600 bits of the state. + +`include "caliptra_prim_assert.sv" + +module ot_sha3 + import caliptra_prim_mubi_pkg::*; + import ot_sha3_pkg::*; +#( + // Enable Masked Keccak if 1 + parameter bit EnMasking = 0, + // derived parameter + localparam int Share = (EnMasking) ? 2 : 1 +) ( + input clk_i, + input rst_ni, + + // MSG interface + input msg_valid_i, + input [MsgWidth-1:0] msg_data_i [Share], + input [MsgStrbW-1:0] msg_strb_i, // one strobe for shares + output logic msg_ready_o, + + // Entropy interface + input rand_valid_i, + input rand_early_i, + input [StateW/2-1:0] rand_data_i, + input rand_aux_i, + output logic rand_update_o, + output logic rand_consumed_o, + + // N, S: Used in cSHAKE mode only + input [NSRegisterSize*8-1:0] ns_data_i, // See ot_sha3_pkg for details + + // configurations + input sha3_mode_e mode_i, // see sha3pad for details + input keccak_strength_e strength_i, // see sha3pad for details + + // controls + input start_i, // see sha3pad for details + input process_i, // see sha3pad for details + + // run_i is a pulse signal to trigger the keccak_round manually by SW. + // It is used to run additional keccak_f after sponge absorbing is completed. + // See `keccak_run` signal + input run_i, + input mubi4_t done_i, // see sha3pad for details + + output mubi4_t absorbed_o, + output logic squeezing_o, + + // Indicate of one block processed. KMAC main state tracks the progression + // based on this signal. + output logic block_processed_o, + + output sha3_st_e sha3_fsm_o, + + // digest output + // This value is valid only after all absorbing process is completed. + // In invalid state, the output `state` will be zero to prevent information + // leakage. + output logic state_valid_o, + output logic [StateW-1:0] state_o [Share], + + // REQ/ACK interface for the Keccak core. This can be used to delay the + // processing e.g. to avoid power spikes at the chip level due to too many + // blocks being active simultaneously. + output logic run_req_o, + input run_ack_i, + + // Life cycle + input lc_ctrl_pkg::lc_tx_t lc_escalate_en_i, + + // error_o value is pushed to Error FIFO at KMAC/SHA3 top and reported to SW + output err_t error_o, + + // sparse_fsm_alert + output logic sparse_fsm_error_o, + + // counter error + output logic count_error_o, + + // error on rst_storage in Keccak + output logic keccak_storage_rst_error_o + +); + ///////////////// + // Definitions // + ///////////////// + + typedef enum logic[2:0] { + MuxGuard = 3'b 010, + MuxRelease = 3'b 101 + } state_mux_sel_e; + + ///////////// + // Signals // + ///////////// + + // State --> Digest + // State is exposed to the outside if the hashing process is completed. + logic state_valid; + logic [StateW-1:0] state [Share]; + logic [StateW-1:0] state_guarded [Share]; + + // State --> digest mux select signal + state_mux_sel_e mux_sel; + + // absorbed is a pulse signal that indicates sponge absorbing is done. + // After this, sha3 core allows software to manually run until squeezing + // is completed, which is the `done_i` pulse signal. + mubi4_t absorbed; + + // `squeezing` is a status indicator that SHA3 core is in sponge squeezing + // stage. In this stage, the state output is valid, and software can manually + // trigger keccak_round logic to get more digest outputs in case the output + // length is bigger than the block limit. + logic squeezing; + + // If process_i is received, the logic initiates the final absorbing process. + // While absorbing, the processing inticator is turned on. This signal is used + // to check if multiple process_i is received or not. + logic processing; + + // FSM variable + sha3_st_sparse_e st, st_d; + + // Keccak control signal (filtered by State Machine) + logic keccak_start, keccak_process; + mubi4_t keccak_done; + + // alert signals + logic round_count_error, msg_count_error; + assign count_error_o = round_count_error | msg_count_error; + + logic sha3_state_error; + logic keccak_round_state_error; + logic sha3pad_state_error; + + assign sparse_fsm_error_o = sha3_state_error | keccak_round_state_error | sha3pad_state_error; + + // Keccak rst_storage is asserted unexpectedly + logic keccak_storage_rst_error; + assign keccak_storage_rst_error_o = keccak_storage_rst_error; + + ///////////////// + // Connections // + ///////////////// + + logic keccak_valid; + logic [KeccakMsgAddrW-1:0] keccak_addr; + logic [MsgWidth-1:0] keccak_data [Share]; + logic keccak_ready; + + // Keccak round run signal can be controlled by sha3pad and also by software + // after all message feeding is done. it is mainly used for sponge squeezing + // operation after absorbing is completed when output length is longer than + // the block size. + logic keccak_run, sha3pad_keccak_run, sw_keccak_run; + logic keccak_run_req_d, keccak_run_req_q; + logic keccak_triggered_d, keccak_triggered_q; + logic keccak_complete; + + // Announce that we want to run the Keccak core and tell other blocks to go + // quiet. Keep holding the REQ until the Keccak core is done with the + // processing. The keccak_complete signal is received once the Keccak core + // is back in the Idle state and again susceptible to keccak_run. + assign run_req_o = keccak_run_req_d; + assign keccak_run_req_d = + sha3pad_keccak_run || sw_keccak_run ? 1'b 1 : + keccak_complete ? 1'b 0 : keccak_run_req_q; + + // Trigger the Keccak engine with a single pulse upon receiving the ACK. + assign keccak_run = run_req_o & run_ack_i & ~keccak_triggered_q; + assign keccak_triggered_d = + keccak_run ? 1'b 1 : + keccak_complete ? 1'b 0 : keccak_triggered_q; + + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + keccak_run_req_q <= 1'b 0; + keccak_triggered_q <= 1'b 0; + end else begin + keccak_run_req_q <= keccak_run_req_d; + keccak_triggered_q <= keccak_triggered_d; + end + end + + // Absorb pulse output : used to generate interrupts + // Latch absorbed signal as kmac_keymgr asserts `CmdDone` when it sees + // `absorbed` signal. When this signal goes out, the state is still in + // `StAbsorb`. Next state is `StSqueeze`. + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) absorbed_o <= MuBi4False; + else absorbed_o <= absorbed; + end + + // Squeezing output + assign squeezing_o = squeezing; + + // processing + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) processing <= 1'b 0; + else if (process_i) processing <= 1'b 1; + else if (mubi4_test_true_strict(absorbed)) begin + processing <= 1'b 0; + end + end + + assign block_processed_o = keccak_complete; + + // State connection + assign state_valid_o = state_valid; + assign state_o = state_guarded; + + assign sha3_fsm_o = sparse2logic(st); + + /////////////////// + // State Machine // + /////////////////// + + // State Register + `CALIPTRA_PRIM_FLOP_SPARSE_FSM(u_state_regs, st_d, st, sha3_st_sparse_e, StIdle_sparse) + + + // Next State and Output Logic + // Mainly the FSM controls the input signal access + // StIdle: only start_i signal is allowed + // StAbsorb: only process_i signal is allowed + // StSqueeze: only run_i, done_i signal is allowed + + always_comb begin + st_d = st; + + // default output values + keccak_start = 1'b 0; + keccak_process = 1'b 0; + sw_keccak_run = 1'b 0; + keccak_done = MuBi4False; + + squeezing = 1'b 0; + + state_valid = 1'b 0; + mux_sel = MuxGuard ; + + sha3_state_error = 1'b 0; + + unique case (st) + StIdle_sparse: begin + if (start_i) begin + st_d = StAbsorb_sparse; + + keccak_start = 1'b 1; + end else begin + st_d = StIdle_sparse; + end + end + + StAbsorb_sparse: begin + if (process_i && !processing) begin + st_d = StAbsorb_sparse; + + keccak_process = 1'b 1; + end else if (mubi4_test_true_strict(absorbed)) begin + st_d = StSqueeze_sparse; + end else begin + st_d = StAbsorb_sparse; + end + end + + StSqueeze_sparse: begin + state_valid = 1'b 1; + mux_sel = MuxRelease; // Expose state to register interface + + squeezing = 1'b 1; + + if (run_i) begin + st_d = StManualRun_sparse; + + sw_keccak_run = 1'b 1; + end else if (mubi4_test_true_strict(done_i)) begin + st_d = StFlush_sparse; + + keccak_done = done_i; + end else begin + st_d = StSqueeze_sparse; + end + end + + StManualRun_sparse: begin + if (keccak_complete) begin + st_d = StSqueeze_sparse; + end else begin + st_d = StManualRun_sparse; + end + end + + StFlush_sparse: begin + st_d = StIdle_sparse; + end + + StTerminalError_sparse: begin + //this state is terminal + st_d = StTerminalError_sparse; + sha3_state_error = 1'b 1; + end + + default: begin + st_d = StTerminalError_sparse; + sha3_state_error = 1'b 1; + end + endcase + + // SEC_CM: FSM.GLOBAL_ESC, FSM.LOCAL_ESC + // Unconditionally jump into the terminal error state + // if the life cycle controller triggers an escalation. + if (lc_ctrl_pkg::lc_tx_test_true_loose(lc_escalate_en_i)) begin + st_d = StTerminalError_sparse; + end + end + + ////////////// + // Datapath // + ////////////// + + // State --> Digest output + always_comb begin : state_guarded_mux + unique case (mux_sel) + MuxGuard: state_guarded = '{default: '0}; + MuxRelease: state_guarded = state; + default: state_guarded = '{default: '0}; // a valid, safe output + endcase + end + + + // Error Detecting + // ErrSha3SwControl: + // info[ 0]: start_i set + // info[ 1]: process_i set + // info[ 2]: run_i set + // info[ 3]: done_i set + // - Sw set process_i, run_i, done_i without start_i + + always_comb begin + error_o = '{valid: 1'b0, code: ErrNone, info: '0}; + + unique case (st) + StIdle_sparse: begin + if (process_i || run_i || + mubi4_test_true_loose(done_i)) begin + error_o = '{ + valid: 1'b 1, + code: ErrSha3SwControl, + info: 24'({done_i, run_i, process_i, start_i}) + }; + end + end + + StAbsorb_sparse: begin + if (start_i || run_i || mubi4_test_true_loose(done_i) + || (process_i && processing)) begin + error_o = '{ + valid: 1'b 1, + code: ErrSha3SwControl, + info: 24'({done_i, run_i, process_i, start_i}) + }; + end + end + + StSqueeze_sparse: begin + if (start_i || process_i) begin + error_o = '{ + valid: 1'b 1, + code: ErrSha3SwControl, + info: 24'({done_i, run_i, process_i, start_i}) + }; + end + end + + StManualRun_sparse: begin + if (start_i || process_i || run_i || + mubi4_test_true_loose(done_i)) begin + error_o = '{ + valid: 1'b 1, + code: ErrSha3SwControl, + info: 24'({done_i, run_i, process_i, start_i}) + }; + end + end + + StFlush_sparse: begin + if (start_i || process_i || run_i || + mubi4_test_true_loose(done_i)) begin + error_o = '{ + valid: 1'b 1, + code: ErrSha3SwControl, + info: 24'({done_i, run_i, process_i, start_i}) + }; + end + end + + default: begin + end + endcase + end + /////////////// + // Instances // + /////////////// + + // SHA3 pad logic + ot_sha3pad #( + .EnMasking (EnMasking) + ) u_pad ( + .clk_i, + .rst_ni, + + // MSG_FIFO (or from KMAC core) + .msg_valid_i, + .msg_data_i, // [Share] + .msg_strb_i, + .msg_ready_o, + + // Encoded N, S + .ns_data_i, + + // output to keccak_round: message path + .keccak_valid_o (keccak_valid), + .keccak_addr_o (keccak_addr ), + .keccak_data_o (keccak_data ), // [Share] + .keccak_ready_i (keccak_ready), + + .keccak_run_o (sha3pad_keccak_run), + .keccak_complete_i (keccak_complete ), + + // configurations + .mode_i, + .strength_i, + + // LC + .lc_escalate_en_i (lc_escalate_en_i), + + // controls + .start_i (keccak_start), + .process_i (keccak_process), + .done_i (keccak_done), + + // output + .absorbed_o (absorbed), + .sparse_fsm_error_o (sha3pad_state_error), + .msg_count_error_o (msg_count_error) + ); + + // Keccak round logic + ot_keccak_round #( + .Width (ot_sha3_pkg::StateW), + .DInWidth (ot_sha3_pkg::MsgWidth), + + .EnMasking (EnMasking) + ) u_keccak ( + .clk_i, + .rst_ni, + + .valid_i (keccak_valid), + .addr_i (keccak_addr ), + .data_i (keccak_data ), + .ready_o (keccak_ready), + + .rand_valid_i, + .rand_early_i, + .rand_data_i, + .rand_aux_i, + .rand_update_o, + .rand_consumed_o, + + .run_i (keccak_run ), + .complete_o (keccak_complete), + + .state_o (state), + + // LC + .lc_escalate_en_i (lc_escalate_en_i), + + .sparse_fsm_error_o (keccak_round_state_error), + .round_count_error_o (round_count_error), + .rst_storage_error_o (keccak_storage_rst_error), + + .clear_i (keccak_done) + ); + + //////////////// + // Assertions // + //////////////// + + // The Keccak core can only be active when the run REQ is ACKed. + `CALIPTRA_ASSERT(KeccakIdleWhenNoRunHs_A, + u_keccak.keccak_st inside {KeccakStActive, + KeccakStPhase1, + KeccakStPhase2Cycle1, + KeccakStPhase2Cycle2, + KeccakStPhase2Cycle3} |-> + run_req_o && run_ack_i) + + // Unknown check for case statement + `CALIPTRA_ASSERT(MuxSelKnown_A, mux_sel inside {MuxGuard, MuxRelease}) + `CALIPTRA_ASSERT(FsmKnown_A, st inside {StIdle_sparse, StAbsorb_sparse, StSqueeze_sparse, + StManualRun_sparse, StFlush_sparse, StTerminalError_sparse}) + + // `state` shall be 0 in invalid + if (EnMasking) begin: gen_chk_digest_masked + `CALIPTRA_ASSERT(StateZeroInvalid_A, !state_valid_o |-> ((|state_o[0]) | (|state_o[1])) == 1'b 0) + end else begin : gen_chk_digest_unmasked + `CALIPTRA_ASSERT(StateZeroInvalid_A, !state_valid_o |-> (|state_o[0]) == 1'b 0) + end + + // `state_valid_o` asserts only in between the completion and done + //`CALIPTRA_ASSERT(StateValidPeriod_A, state_valid_o |-> ) + + // skip the msg interface assertions as they are in ot_sha3pad.sv + + // Software run signal happens in Squeezing stage + `CALIPTRA_ASSUME(SwRunInSqueezing_a, run_i |-> error_o.valid || (st == StSqueeze_sparse)) + + // If control received but not propagated into submodules, it is error condition + `CALIPTRA_ASSERT(ErrDetection_A, error_o.valid + |-> {start_i, process_i, run_i, done_i} + != {keccak_start, keccak_process, sw_keccak_run, keccak_done}) + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/ot_sha3_pkg.sv b/designs/Caliptra/src/caliptra-rtl/ot_sha3_pkg.sv new file mode 100644 index 0000000..59ca003 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/ot_sha3_pkg.sv @@ -0,0 +1,294 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// ot_sha3_pkg + +package ot_sha3_pkg; + + // StateW represents the width of Keccak state variable. + // As Sha3 assume the state value as 1600, this shouldn't be modified. + // Note that keccak_round is flexible. It can have any values defined in SHA3 + // specification. But sha3pad logic assumes the value as 1600. + parameter int StateW = 1600; + + // Function Name (N) and Customzation String (S) shall be + // smaller than 2**256 bits and integer divisiable by 8. + parameter int FnWidth = 32; // up to 32bit Function Name + parameter int CsWidth = 256; // up to 256bit Customization Input + + // Calculate left_encode(len( X )) bit size. + // Assume the enc_8(n) is always 1 (up to 255 byte of len(S) size) + // e.g) 248bit --> two bytes , 256bit --> three bytes + // round8bit(clog2(X+1))/8 + + parameter int MaxFnEncodeSize = ($clog2(FnWidth+1) + 8 - 1) / 8 + 1; + parameter int MaxCsEncodeSize = ($clog2(CsWidth+1) + 8 - 1) / 8 + 1; + + parameter int NSRegisterSizePre = FnWidth/8 + CsWidth/8 + + MaxFnEncodeSize + MaxCsEncodeSize; + // Round up to 32bit word base + parameter int NSRegisterSize = ((NSRegisterSizePre + 4 - 1 ) / 4) * 4; + + // Prefix represents bytepad(encode_string(N) || encode_string(S), 168 or 136) + // +2 represents left_encoding(168 or 136) which could be either: + // 10000000 || 00010101 // 168 + // 10000000 || 00010001 // 136 + parameter int PrefixSize = NSRegisterSize + 2; + + // index width for `N` and `S` + parameter int PrefixIndexW = $clog2(PrefixSize/64); + + // Datapath width in KMAC, this also affects the output of MSG_FIFO + // This is assumed as 64 in KMAC design. If this value is changed, some parts + // of the KMAC design need to be changed. + // + // 1. keccak_round logic datapath. Keccak round logic assumes MsgWidth + // divides 1600 keccak state `Width`. Choose the value accordingly. + // 2. sha3pad module has fixed width mux for funcpad logic. If MsgWidth is + // changed, the logic also need to be revised. + // 3. kmac core logic also has fixed size mux for appeding output length. + // Revise the case statement to fit into revised MsgWidth value. + parameter int MsgWidth = 64; + parameter int MsgStrbW = MsgWidth / 8; + + // Keccak module supports SHA3, SHAKE, cSHAKE function. + // This mode determines if the module uses encoded N and S or not. + // Also it chooses the padding value. + // + // mode | little-endian + // -------|---------------- + // Sha3 | 2'b 10 + // Shake | 4'b 1111 + // CShake | 2'b 00 + // + // Please remind that if input strings N and S are empty, SW shall + // choose SHAKE even for cSHAKE operation. + typedef enum logic[1:0] { + Sha3 = 2'b 00, + Shake = 2'b 10, + CShake = 2'b 11 + } sha3_mode_e; + + // keccak_strength_e determines the security strength against collision attack + // This value decides the _rate_ and _capacity_ of the keccak states. + // It affects the sha3pad module too. the padding module implements + // `bytepad(X,168)` for L128, `bytepad(X,136)` for L256 in cSHAKE + typedef enum logic [2:0] { + L128 = 3'b 000, // rate: 1344 bit / capacity: 256 bit Keccak[ 256](, 128) + L224 = 3'b 001, // rate: 1152 bit / capacity: 448 bit Keccak[ 448](, 224) + L256 = 3'b 010, // rate: 1088 bit / capacity: 512 bit Keccak[ 512](, 256) + L384 = 3'b 011, // rate: 832 bit / capacity: 768 bit Keccak[ 768](, 384) + L512 = 3'b 100 // rate: 576 bit / capacity: 1024 bit Keccak[1024](, 512) + } keccak_strength_e; + + parameter int unsigned KeccakRate [5] = '{ + 1344/MsgWidth, // 21 depth := (1600 - 128*2) + 1152/MsgWidth, // 18 depth := (1600 - 224*2) + 1088/MsgWidth, // 17 depth := (1600 - 256*2) + 832/MsgWidth, // 13 depth := (1600 - 384*2) + 576/MsgWidth // 9 depth := (1600 - 512*2) + }; + + parameter int unsigned KeccakBitCapacity [5] = '{ + 2 * 128, // capacity for L128 + 2 * 224, // capacity for L224 + 2 * 256, // capacity for L256 + 2 * 384, // capacity for L384 + 2 * 512 // capacity for L512 + }; + + parameter int unsigned MaxBlockSize = KeccakRate[0]; + + parameter int unsigned KeccakEntries = 1600/MsgWidth; + parameter int unsigned KeccakMsgAddrW = $clog2(KeccakEntries); + + parameter int unsigned KeccakCountW = $clog2(KeccakEntries+1); + + // SHA3 core state. This state value is used in sha3core module + // and also in KMAC top module and the register interface for sw to track the + // sha3 status. + // Encoding generated with: + // $ ./util/design/sparse-fsm-encode.py -d 3 -m 7 -n 6 \ + // -s 4082450958 --language=sv + // + // Hamming distance histogram: + // + // 0: -- + // 1: -- + // 2: -- + // 3: |||||||||||||||||||| (57.14%) + // 4: ||||||||||||||| (42.86%) + // 5: -- + // 6: -- + // + // Minimum Hamming distance: 3 + // Maximum Hamming distance: 4 + // Minimum Hamming weight: 1 + // Maximum Hamming weight: 4 + // + localparam int StateWidth = 6; + typedef enum logic [StateWidth-1:0] { + StIdle_sparse = 6'b101100, + + // Absorb stage receives the message bitstream and computes the keccak + // rounds. This internal operation is mainly done inside sha3pad module + // not sha3core. The core module and this state machine observe the status + // of the process and mainly waits until all the sponge absorbing is + // completed. The main indicator is `absorbed` signal. + StAbsorb_sparse = 6'b100001, + + // Reserved state for context-switching. See #3479. + // Abort stage can be moved from StAbsorb stage. It basically holds the + // keccak round operation and opens up the internal state variable to the + // software. This stage is for the software to pause current operation and + // store the internal state elsewhere then initiates new KMAC/SHA3 process. + // StAbort only can be moved to _StFlush_. + //StAbort_sparse = 6'b011101, + + // Squeeze stage allows the software to read the internal state. + // If `EnMasking`, it opens the read permission of two share of the state. + // The squeezing in SHA3 specification describes the software to read up to + // the rate of SHA3 algorithm but this logic opens up the entire 1600 bits + // of the state (3200bits if `EnMasking`). + StSqueeze_sparse = 6'b001011, + + // ManualRun stage initiaties the keccak round and waits the completion. + // This state is moved from Squeeze state by writing 1 to manual_run CSR. + // When keccak round is completed, it goes back to Squeeze state. + StManualRun_sparse = 6'b010000, + + // Flush stage, the core clears out the internal variables and also + // submodules' variables too. Then moves back to Idle state. + StFlush_sparse = 6'b000110, + + StTerminalError_sparse = 6'b111010 + } sha3_st_sparse_e; + + localparam int StateWidthLogic = 3; + typedef enum logic [StateWidthLogic-1:0] { + StIdle, + StAbsorb, + //StAbort, + StSqueeze, + StManualRun, + StFlush, + StError + } sha3_st_e; + + function automatic sha3_st_e sparse2logic(sha3_st_sparse_e st); + unique case (st) + StIdle_sparse : return StIdle; + StAbsorb_sparse : return StAbsorb; + //StAbort_sparse : return StAbort; + StSqueeze_sparse : return StSqueeze; + StManualRun_sparse : return StManualRun; + StFlush_sparse : return StFlush; + default : return StError; + endcase + endfunction : sparse2logic + + + ////////////////////// + // Keccak Round FSM // + ////////////////////// + + // Encoding generated with: + // $ ./util/design/sparse-fsm-encode.py -d 3 -m 8 -n 6 \ + // -s 1363425333 --language=sv + // + // Hamming distance histogram: + // + // 0: -- + // 1: -- + // 2: -- + // 3: |||||||||||||||||||| (57.14%) + // 4: ||||||||||||||| (42.86%) + // 5: -- + // 6: -- + // + // Minimum Hamming distance: 3 + // Maximum Hamming distance: 4 + // Minimum Hamming weight: 1 + // Maximum Hamming weight: 5 + // + localparam int KeccakFsmWidth = 6; + typedef enum logic [KeccakFsmWidth-1:0] { + KeccakStIdle = 6'b011111, + + // Active state is used in Unmasked version only. + // It handles keccak round in a cycle + KeccakStActive = 6'b000100, + + // Phase1 --> Phase2Cycle1 --> Phase2Cycle2 --> Phase2Cycle3 + // Activated only in Masked version. + // Phase1 processes Theta, Rho, Pi steps in a cycle and stores the states + // into storage. It only moves to Phase2 once the randomness required for + // Phase2 is available. + KeccakStPhase1 = 6'b101101, + + // Chi Stage 1 for first lane halves. Unconditionally move to Phase2Cycle2. + KeccakStPhase2Cycle1 = 6'b000011, + + // Chi Stage 2 and Iota for first lane halves. Chi Stage 1 for second + // lane halves. Unconditionally move to Phase2Cycle3. + KeccakStPhase2Cycle2 = 6'b011000, + + // Chi Stage 2 and Iota for second lane halves. + // When doing the last round (MaxRound -1) it completes the process and + // goes back to Idle. If not, it repeats the phases again. + KeccakStPhase2Cycle3 = 6'b101010, + + // Error state. Not clearly defined yet. + // Intention is if any unexpected input in the process, state moves to + // here and report through the error fifo with debugging information. + KeccakStError = 6'b110001, + + KeccakStTerminalError = 6'b110110 + } keccak_st_e; + + + ////////////////// + // Error Report // + ////////////////// + typedef enum logic [7:0] { + ErrNone = 8'h 00, + + // ErrSha3SwControl occurs when software sent wrong flow signal. + // e.g) Sw set `process_i` without `start_i`. The state machine ignores + // the signal and report through the error FIFO. + ErrSha3SwControl = 8'h 80 + } err_code_e; + + typedef struct packed { + logic valid; + err_code_e code; // Type of error + logic [23:0] info; // Additional Debug info + } err_t; + + + /////////////// + // Functions // + /////////////// + + // Bytepading function + // `encode_bytepad_len` represents the first two bytes of bytepad() + // It depends on the block size. We can reuse KeccakRate + // 10000000 || 00010101 // 168 + // 10000000 || 00010001 // 136 + function automatic logic [15:0] encode_bytepad_len(keccak_strength_e kstrength); + logic [15:0] result; + unique case (kstrength) + L128: result = 16'h A801; // cSHAKE128 + L224: result = 16'h 9001; // not used + L256: result = 16'h 8801; // cSHAKE256 + L384: result = 16'h 6801; // not used + L512: result = 16'h 4801; // not used + + default: result = 16'h 0000; + endcase + return result; + endfunction : encode_bytepad_len + + +endpackage : ot_sha3_pkg diff --git a/designs/Caliptra/src/caliptra-rtl/ot_sha3pad.sv b/designs/Caliptra/src/caliptra-rtl/ot_sha3pad.sv new file mode 100644 index 0000000..9ad1f80 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/ot_sha3pad.sv @@ -0,0 +1,885 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// SHA3 padding logic + +`include "caliptra_prim_assert.sv" + +module ot_sha3pad + import caliptra_prim_mubi_pkg::*; + import ot_sha3_pkg::*; +#( + parameter bit EnMasking = 0, + localparam int Share = (EnMasking) ? 2 : 1 +) ( + input clk_i, + input rst_ni, + + // Message interface (FIFO) + input msg_valid_i, + input [MsgWidth-1:0] msg_data_i [Share], + input [MsgStrbW-1:0] msg_strb_i, // one strobe for shares + output logic msg_ready_o, + + // N, S: Used in cSHAKE mode only + input [NSRegisterSize*8-1:0] ns_data_i, // See sha3_pkg for details + + // output to keccak_round: message path + output logic keccak_valid_o, + output logic [KeccakMsgAddrW-1:0] keccak_addr_o, + output logic [MsgWidth-1:0] keccak_data_o [Share], + input logic keccak_ready_i, + + // keccak_round control and status + // `run` initiates the keccak_round to process full keccak_f (24rounds). + // `complete` is an input from keccak round showing the current keccak_f is + // completed. + output logic keccak_run_o, + input keccak_complete_i, + + // configurations + input sha3_mode_e mode_i, + // strength_i is used in bytepad operation. bytepad() is used in cSHAKE only. + // SHA3, SHAKE doesn't have encode_N,S + input keccak_strength_e strength_i, + + // control signal + // start_i is a pulse signal triggers the padding logic (and the rest of SHA) + // to accept the incoming messages. This signal is used in the pad module, + // to initiate the prefix transmitting to keccak_round + input start_i, + // process_i is a pulse signal triggers the pad logic to stop receiving the + // message from MSG_FIFO and pad the trailing bits specified in the SHA3 + // standard. Look at `funcpad` signal for the values. + input process_i, + // done_i is a pulse signal to make the pad logic to clear internal variables + // and to move back to the Idle state for next hashing process. + // done_i may not needed if sw controls the keccak_round directly. + input mubi4_t done_i, + + // Indication of the Keccak Sponge Absorbing is complete, it is time for SW to + // control the Keccak-round if it needs more digest, or complete by asserting + // `done_i` + output mubi4_t absorbed_o, + + // Life cycle + input lc_ctrl_pkg::lc_tx_t lc_escalate_en_i, + + // Indication that there was a fault in the sparse encoding + output logic sparse_fsm_error_o, + + // Indication that there was a fault in the counter + output logic msg_count_error_o +); + + ///////////////// + // Definitions // + ///////////////// + + // Padding States + // Encoding generated with: + // $ ./util/design/sparse-fsm-encode.py -d 3 -m 10 -n 7 \ + // -s 1116691466 --language=sv + // + // Hamming distance histogram: + // + // 0: -- + // 1: -- + // 2: -- + // 3: |||||||||||||||||||| (42.22%) + // 4: |||||||||||||||||| (40.00%) + // 5: ||||| (11.11%) + // 6: || (4.44%) + // 7: | (2.22%) + // + // Minimum Hamming distance: 3 + // Maximum Hamming distance: 7 + // Minimum Hamming weight: 2 + // Maximum Hamming weight: 5 + // + localparam int StateWidthPad = 7; + typedef enum logic [StateWidthPad-1:0] { + StPadIdle = 7'b1000010, + + // Sending a block of prefix, if cSHAKE mode is turned on. For the rest + // (SHA3, SHAKE), sending prefix is not needed. FSM moves from Idle to + // Message directly in that case. + // + // As prim_slicer is instantiated, zerofill after the actual prefix is done + // by the module. + StPrefix = 7'b0111100, + StPrefixWait =7'b1001100, + + // Sending Message. In this state, it directly forwards the incoming data + // to Keccak round module. If `process_i` is asserted, then the rest of the + // messages will be discarded until new `start_i` is asserted. + // + // The incoming data can be partial write. Padding logic counts the number + // of bytes received and pause if a block size is transferred. + StMessage = 7'b0100101, + StMessageWait = 7'b0001111, + + // After sending the messages, then `process_i` is set, the FSM pads at the + // end of the message based on `mode_i`. If this is the last byte of the + // block, then it pads [7] to 1 to complete `pad10*1()` function. + StPad = 7'b1111010, + StPadRun = 7'b0011001, + + // If the padding isn't the end of the block byte (which will be rare case), + // FSM moves to another zerofill state. In contrast to StZerofill, this state + StPad01 = 7'b1101001, + + // Flushing the internal packers in front of the Keccak data output port. + StPadFlush = 7'b1010111, + + StTerminalError = 7'b0110011 + } pad_st_e; + + typedef enum logic [2:0] { + MuxNone = 3'b 000, + MuxFifo = 3'b 001, + MuxPrefix = 3'b 010, + MuxFuncPad = 3'b 011, + MuxZeroEnd = 3'b 100 + } mux_sel_e; + + //////////////////// + // Configurations // + //////////////////// + + logic [KeccakCountW-1:0] block_addr_limit; + + // Block size based on the address. + // This is used for bytepad() and also pad10*1() + // assign block_addr_limit = KeccakRate[strength_i]; + // but below is easier to understand + always_comb begin + unique case (strength_i) + L128: block_addr_limit = KeccakCountW'(KeccakRate[L128]); + L224: block_addr_limit = KeccakCountW'(KeccakRate[L224]); + L256: block_addr_limit = KeccakCountW'(KeccakRate[L256]); + L384: block_addr_limit = KeccakCountW'(KeccakRate[L384]); + L512: block_addr_limit = KeccakCountW'(KeccakRate[L512]); + + default: block_addr_limit = '0; + endcase + end + + ///////////////////// + // Control Signals // + ///////////////////// + + // `sel_mux` selects the output data among the incoming or internally generated data. + // MuxFifo: data from external (msg_data_i) + // MuxPrefix: bytepad(encode_string(N)||encode_string(S), ) + // MuxFuncPad: function_pad with end of message + // MuxZeroEnd: all 0 + mux_sel_e sel_mux; + + // `sent_message` indicates the number of entries sent to keccak round per + // block. The value shall be enough to cover Maximum entry of the Keccak + // storage as defined in sha3_pkg, `$clog2(KeccakEntries+1)`. Logically, + // it is not needed to have more than KeccakEntries but for safety in case of + // SHA3 context switch resuming the SHA3 from the middle of sponge + // construction. If needed, the software should be able to write whole 1600 + // bits. The `sent_message` is used to check sent_blocksize. + logic [KeccakCountW-1:0] sent_message; + logic inc_sentmsg, clr_sentmsg; + + // This primitive is used to place a hardened counter + // SEC_CM: CTR.REDUN + caliptra_prim_count #( + .Width(KeccakCountW) + ) u_sentmsg_count ( + .clk_i, + .rst_ni, + .clr_i(clr_sentmsg), + .set_i(1'b0), + .set_cnt_i(KeccakCountW'(0)), + .incr_en_i(inc_sentmsg), + .decr_en_i(1'b0), + .step_i(KeccakCountW'(1)), + .commit_i(1'b1), + .cnt_o(sent_message), + .cnt_after_commit_o(), + .err_o(msg_count_error_o) + ); + + + assign inc_sentmsg = keccak_valid_o & keccak_ready_i ; + + // Prefix index to slice the `prefix` n-bits into multiple of 64bit. + logic [KeccakMsgAddrW-1:0] prefix_index; + assign prefix_index = (sent_message < block_addr_limit) ? sent_message : '0; + + // fsm_keccak_valid is an output signal from FSM which to send data generated + // inside the pad logic to keccak_round + logic fsm_keccak_valid; + + // hold_msg to prevent message from being forwarded into keccak_round and + // acked. Mainly the usage is to hold the message and initiates the + // keccak_round for current block. + logic hold_msg; + + // latch the partial write. Latched data is used for funcpad_merged + logic en_msgbuf; + logic clr_msgbuf; + + /////////////////// + // State Machine // + /////////////////// + + // Inputs + + // FSM moves to StPrefix only when cSHAKE is enabled + logic mode_eq_cshake; + assign mode_eq_cshake = (mode_i == CShake) ? 1'b 1 : 1'b 0; + + // `sent_blocksize` indicates the pad logic pushed block size data into + // keccak round logic. + logic sent_blocksize; + + assign sent_blocksize = (sent_message == block_addr_limit) ? 1'b 1 : 1'b 0; + + // `keccak_ack` indicates the request is accepted in keccak_round + logic keccak_ack; + + assign keccak_ack = keccak_valid_o & keccak_ready_i ; + + // msg_partial indicates the incoming message is partial write or not. + // This is used to check if the incoming message need to be latched inside or + // not. If no partial message is at the end, msg_buf doesn't have to latch + // msg_data_i. It is assumed that the partial message is permitted only at + // the end of the message. So if (msg_valid_i && msg_partial && msg_ready_o), + // there will be no msg_valid_i till process_latched. + // Shall be used with msg_valid_i together. + logic msg_partial; + assign msg_partial = (&msg_strb_i != 1'b 1); + + + // `process_latched` latches the `process_i` input before it is seen in the + // FSM. `process_i` may follow `start_i` too fast so that the FSM may not + // see it fast enought in case of cSHAKE mode. cSHAKE needs to process the + // prefix prior to see the process indicator. + logic process_latched; + + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + process_latched <= 1'b 0; + end else if (process_i) begin + process_latched <= 1'b 1; + end else if (mubi4_test_true_strict(done_i)) begin + process_latched <= 1'b0; + end + end + + // State Register =========================================================== + pad_st_e st, st_d; + + `CALIPTRA_PRIM_FLOP_SPARSE_FSM(u_state_regs, st_d, st, pad_st_e, StPadIdle) + + // `end_of_block` indicates current beat is end of the block + // It shall set when the address reaches to the end of the block. End address + // is set by the strength_i, which is `block_addr_limit`. + logic end_of_block; + + assign end_of_block = ((sent_message + 1'b1) == block_addr_limit) ? 1'b 1 : 1'b 0; + + + // Next logic and output logic ============================================== + // SEC_CM: ABSORBED.CTRL.MUBI + mubi4_t absorbed_d; + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) absorbed_o <= MuBi4False; + else absorbed_o <= absorbed_d; + end + + always_comb begin + st_d = st; + + // FSM output : default values + keccak_run_o = 1'b 0; + sel_mux = MuxNone; + + fsm_keccak_valid = 1'b 0; + + hold_msg = 1'b 0; + clr_sentmsg = 1'b 0; + + en_msgbuf = 1'b 0; + clr_msgbuf = 1'b 0; + + absorbed_d = MuBi4False; + + sparse_fsm_error_o = 1'b 0; + + unique case (st) + + // In Idle state, the FSM checks if the software (or upper FSM) initiates + // the hash process. If `start_i` is asserted (assume it is pulse), FSM + // starts to push the data into the keccak round logic. Depending on the + // hashing mode, FSM may push additional prefex in front of the actual + // message. It means, the message could be back-pressured until the first + // prefix is processed. + StPadIdle: begin + if (start_i) begin + // If cSHAKE, move to Prefix state + if (mode_eq_cshake) begin + st_d = StPrefix; + end else begin + st_d = StMessage; + end + end else begin + st_d = StPadIdle; + end + end + + // At Prefix state, FSM pushes + // `bytepad(encode_string(N)||encode_string(S), 168or136)`. The software + // already prepared `encode_string(N) || encode_string(S)` in the regs. + // So, the FSM adds 2Byte in front of ns_data_i, which is an encoded + // block size (see `encoded_bytepad` below) + // After pushing the prefix, it initiates the hash process and move to + // Message state. + StPrefix: begin + sel_mux = MuxPrefix; + + if (sent_blocksize) begin + st_d = StPrefixWait; + + keccak_run_o = 1'b 1; + fsm_keccak_valid = 1'b 0; + clr_sentmsg = 1'b 1; + end else begin + st_d = StPrefix; + + fsm_keccak_valid = 1'b 1; + end + end + + StPrefixWait: begin + sel_mux = MuxPrefix; + + if (keccak_complete_i) begin + st_d = StMessage; + end else begin + st_d = StPrefixWait; + end + end + + // Message state pushes the incoming message into keccak round logic. + // It forwards the message while counting the data and if it reaches + // the block size, it triggers the keccak round to run. If `process` is + // set, it moves to Pad state. + StMessage: begin + sel_mux = MuxFifo; + + if (msg_valid_i && msg_partial) begin + st_d = StMessage; + + en_msgbuf = 1'b 1; + end else if (sent_blocksize) begin + // Check block completion first even process is set. + st_d = StMessageWait; + + keccak_run_o = 1'b 1; + clr_sentmsg = 1'b 1; + hold_msg = 1'b 1; + end else if (process_latched || process_i) begin + st_d = StPad; + + // Not asserting the msg_ready_o + hold_msg = 1'b 1; + end else begin + st_d = StMessage; + + end + end + + StMessageWait: begin + hold_msg = 1'b 1; + + if (keccak_complete_i) begin + st_d = StMessage; + end else begin + st_d = StMessageWait; + end + end + + // Pad state just pushes the ending suffix. Depending on the mode, the + // padding value is unique. SHA3 adds 2'b10, SHAKE adds 4'b1111, and + // cSHAKE adds 2'b 00. Refer `function_pad`. The signal has one more bit + // defined to accomodate first 1 bit of `pad10*1()` function. + StPad: begin + sel_mux = MuxFuncPad; + + fsm_keccak_valid = 1'b 1; + + if (keccak_ack && end_of_block) begin + // If padding is the last block, don't have to move to StPad01, just + // run Keccak and complete + st_d = StPadRun; + + // always clear the latched msgbuf + clr_msgbuf = 1'b 1; + clr_sentmsg = 1'b 1; + end else if (keccak_ack) begin + st_d = StPad01; + clr_msgbuf = 1'b 1; + end else begin + st_d = StPad; + end + end + + StPadRun: begin + st_d = StPadFlush; + + keccak_run_o = 1'b 1; + clr_sentmsg = 1'b 1; + end + + // Pad01 pushes the end bit of pad10*1() function. As keccak accepts byte + // size only, StPad always pushes partial (5bits). So at this state, it + // pushes rest of 3bits. If the data pushed in StPad is the last byte of + // the block, then Pad01 pushes to the same byte, if not, it first + // zero-fill the block then pad 1 to the end. + StPad01: begin + sel_mux = MuxZeroEnd; + + // There's no chance StPad01 can be a start of the block. So can be + // discard that the sent_blocksize is set at the beginning. + if (sent_blocksize) begin + st_d = StPadFlush; + + fsm_keccak_valid = 1'b 0; + keccak_run_o = 1'b 1; + clr_sentmsg = 1'b 1; + end else begin + st_d = StPad01; + + fsm_keccak_valid = 1'b 1; + end + end + + StPadFlush: begin + // Wait completion from keccak_round or wait SW indicator. + clr_sentmsg = 1'b 1; + clr_msgbuf = 1'b 1; + + if (keccak_complete_i) begin + st_d = StPadIdle; + + absorbed_d = MuBi4True; + end else begin + st_d = StPadFlush; + end + end + + StTerminalError: begin + // this state is terminal + st_d = st; + sparse_fsm_error_o = 1'b 1; + end + + default: begin + // this state is terminal + st_d = StTerminalError; + sparse_fsm_error_o = 1'b 1; + end + endcase + + // SEC_CM: FSM.GLOBAL_ESC, FSM.LOCAL_ESC + // Unconditionally jump into the terminal error state + // if the life cycle controller triggers an escalation. + if (lc_ctrl_pkg::lc_tx_test_true_loose(lc_escalate_en_i)) begin + st_d = StTerminalError; + end + end + + ////////////// + // Datapath // + ////////////// + + // `encode_bytepad` represents the first two bytes of bytepad() + // It depends on the block size. We can reuse KeccakRate + // 10000000 || 00010101 // 168 + // 10000000 || 00010001 // 136 + logic [15:0] encode_bytepad; + + assign encode_bytepad = encode_bytepad_len(strength_i); + + // Prefix size ============================================================== + // Prefix represents bytepad(encode_string(N) || encode_string(S), 168 or 136) + // encode_string(N) || encode_string(S) is prepared by the software and given + // through `ns_data_i`. The first part of bytepad is determined by the + // `strength_i` and stored into `encode_bytepad`. + + // It is assumed that the prefix always smaller than the block size. + logic [PrefixSize*8-1:0] prefix; + + assign prefix = {ns_data_i, encode_bytepad}; + + logic [MsgWidth-1:0] prefix_sliced; + logic [MsgWidth-1:0] prefix_data [Share]; + + caliptra_prim_slicer #( + .InW (PrefixSize*8), + .IndexW(KeccakMsgAddrW), + .OutW(MsgWidth) + ) u_prefix_slicer ( + .sel_i (prefix_index), + .data_i (prefix), + .data_o (prefix_sliced) + ); + + if (EnMasking) begin : gen_prefix_masked + // If Masking is enabled, prefix is two share. + assign prefix_data[0] = '0; + assign prefix_data[1] = prefix_sliced; + end else begin : gen_prefix_unmasked + // If Unmasked, only one share exists. + assign prefix_data[0] = prefix_sliced; + end + + // ========================================================================== + // function_pad is the unique value padded at the end of the message based on + // the function among SHA3, SHAKE, cSHAKE. The standard mentioned that SHA3 + // pads `01` , SHAKE pads `1111`, and cSHAKE pads `00`. + // + // Then pad10*1() function follows. It adds `1` first then fill 0 until it + // reaches the block size -1, then adds `1`. + // + // It means always `1` is followed by the function pad. + logic [4:0] funcpad; + + logic [MsgWidth-1:0] funcpad_data [Share]; + + always_comb begin + unique case (mode_i) + Sha3: funcpad = 5'b 00110; + Shake: funcpad = 5'b 11111; + CShake: funcpad = 5'b 00100; + + default: begin + // Just create non-padding but pad10*1 only + funcpad = 5'b 00001; + end + endcase + end + + // ========================================================================== + // `zero_with_endbit` contains all zero unless the message is for the last + // MsgWidth beat in the block. If it is the end of the block, the last bit + // will be set to complete pad10*1() functionality. + logic [MsgWidth-1:0] zero_with_endbit [Share]; + + if (EnMasking) begin : gen_zeroend_masked + assign zero_with_endbit[0] = '0; + assign zero_with_endbit[1][MsgWidth-1] = end_of_block; + assign zero_with_endbit[1][MsgWidth-2:0] = '0; + end else begin : gen_zeroend_unmasked + assign zero_with_endbit[0][MsgWidth-1] = end_of_block; + assign zero_with_endbit[0][MsgWidth-2:0] = '0; + end + + // ========================================================================== + // Data mux for output data + + assign keccak_addr_o = (sent_message < block_addr_limit) ? sent_message : '0; + + always_comb begin + unique case (sel_mux) + MuxFifo: keccak_data_o = msg_data_i; + MuxPrefix: keccak_data_o = prefix_data; + MuxFuncPad: keccak_data_o = funcpad_data; + MuxZeroEnd: keccak_data_o = zero_with_endbit; + + // MuxNone + default: keccak_data_o = '{default:'0}; + endcase + end + + always_comb begin + unique case (sel_mux) + MuxFifo: keccak_valid_o = msg_valid_i & ~hold_msg & ~en_msgbuf; + MuxPrefix: keccak_valid_o = fsm_keccak_valid; + MuxFuncPad: keccak_valid_o = fsm_keccak_valid; + MuxZeroEnd: keccak_valid_o = fsm_keccak_valid; + + // MuxNone + default: keccak_valid_o = 1'b 0; + endcase + end + + always_comb begin + unique case (sel_mux) + MuxFifo: msg_ready_o = en_msgbuf | (keccak_ready_i & ~hold_msg); + MuxPrefix: msg_ready_o = 1'b 0; + MuxFuncPad: msg_ready_o = 1'b 0; + MuxZeroEnd: msg_ready_o = 1'b 0; + + // MuxNone + default: msg_ready_o = 1'b 0; + endcase + end + + // prim_packer : packing to 64bit to update keccak storage + // two prim_packer in this module are used to pack the data received from + // upper layer (KMAC core) and also the 5bit padding bits. + // It is assumed that the message from upper layer could be partial at the + // end of the message. Then the 2 or 4bit padding is required. It can be + // handled by some custom logic or could be done by prim_packer. + // If packer is used, the MSG_FIFO doesn't have to have another prim_packer + // in front of the FIFO. This logic can handle the partial writes from the + // software. + // + // If a custom logic is implemented here, prim_packer is necessary in front + // of the FIFO, as this logic only appends at the end of the message when + // `process_i` is asserted. Also, in this case, even prim_packer is not + // needed, still 64bit registers to latch the partial write is required. + // If not, the logic has to delay the acceptance of the incoming write + // accesses. It may trigger the back-pressuring in some case which may result + // that the software(or upper layer) may not set process_i. + // + // For custom logic, it could be implemented by the 8 mux selection. + // for instance: (subject to be changed) + // unique case (sent_byte[2:0]) // generated from msg_strb_i + // 3'b 000: funcpad_merged = {end_of_block, 63'(function_pad) }; + // 3'b 001: funcpad_merged = {end_of_block, 55'(function_pad), msg_data_i[ 7:0]}; + // 3'b 010: funcpad_merged = {end_of_block, 47'(function_pad), msg_data_i[15:0]}; + // 3'b 011: funcpad_merged = {end_of_block, 39'(function_pad), msg_data_i[23:0]}; + // 3'b 100: funcpad_merged = {end_of_block, 31'(function_pad), msg_data_i[31:0]}; + // 3'b 101: funcpad_merged = {end_of_block, 23'(function_pad), msg_data_i[39:0]}; + // 3'b 110: funcpad_merged = {end_of_block, 15'(function_pad), msg_data_i[47:0]}; + // 3'b 111: funcpad_merged = {end_of_block, 7'(function_pad), msg_data_i[55:0]}; + // default: funcpad_merged = '0; + // endcase + + // internal buffer to store partial write. It doesn't have to store last byte as it + // stores only when partial write. + logic [MsgWidth-8-1:0] msg_buf [Share]; + logic [MsgStrbW-1-1:0] msg_strb; + + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + msg_buf <= '{default:'0}; + msg_strb <= '0; + end else if (en_msgbuf) begin + for (int i = 0 ; i < Share ; i++) begin + msg_buf[i] <= msg_data_i[i][0+:(MsgWidth-8)]; + end + msg_strb <= msg_strb_i[0+:(MsgStrbW-1)]; + end else if (clr_msgbuf) begin + msg_buf <= '{default:'0}; + msg_strb <= '0; + end + end + + if (EnMasking) begin : gen_funcpad_data_masked + always_comb begin + unique case (msg_strb) + 7'b 000_0000: begin + funcpad_data[0] = '0; + funcpad_data[1] = {end_of_block, 63'(funcpad) }; + end + 7'b 000_0001: begin + funcpad_data[0] = {56'h0, msg_buf[0][ 7:0]}; + funcpad_data[1] = {end_of_block, 55'(funcpad), msg_buf[1][ 7:0]}; + end + 7'b 000_0011: begin + funcpad_data[0] = {48'h0, msg_buf[0][15:0]}; + funcpad_data[1] = {end_of_block, 47'(funcpad), msg_buf[1][15:0]}; + end + 7'b 000_0111: begin + funcpad_data[0] = {40'h0, msg_buf[0][23:0]}; + funcpad_data[1] = {end_of_block, 39'(funcpad), msg_buf[1][23:0]}; + end + 7'b 000_1111: begin + funcpad_data[0] = {32'h0, msg_buf[0][31:0]}; + funcpad_data[1] = {end_of_block, 31'(funcpad), msg_buf[1][31:0]}; + end + 7'b 001_1111: begin + funcpad_data[0] = {24'h0, msg_buf[0][39:0]}; + funcpad_data[1] = {end_of_block, 23'(funcpad), msg_buf[1][39:0]}; + end + 7'b 011_1111: begin + funcpad_data[0] = {16'h0, msg_buf[0][47:0]}; + funcpad_data[1] = {end_of_block, 15'(funcpad), msg_buf[1][47:0]}; + end + 7'b 111_1111: begin + funcpad_data[0] = { 8'h0, msg_buf[0][55:0]}; + funcpad_data[1] = {end_of_block, 7'(funcpad), msg_buf[1][55:0]}; + end + + default: funcpad_data = '{default:'0}; + endcase + end + end else begin : gen_funcpad_data_unmasked + always_comb begin + unique case (msg_strb) + 7'b 000_0000: funcpad_data[0] = {end_of_block, 63'(funcpad) }; + 7'b 000_0001: funcpad_data[0] = {end_of_block, 55'(funcpad), msg_buf[0][ 7:0]}; + 7'b 000_0011: funcpad_data[0] = {end_of_block, 47'(funcpad), msg_buf[0][15:0]}; + 7'b 000_0111: funcpad_data[0] = {end_of_block, 39'(funcpad), msg_buf[0][23:0]}; + 7'b 000_1111: funcpad_data[0] = {end_of_block, 31'(funcpad), msg_buf[0][31:0]}; + 7'b 001_1111: funcpad_data[0] = {end_of_block, 23'(funcpad), msg_buf[0][39:0]}; + 7'b 011_1111: funcpad_data[0] = {end_of_block, 15'(funcpad), msg_buf[0][47:0]}; + 7'b 111_1111: funcpad_data[0] = {end_of_block, 7'(funcpad), msg_buf[0][55:0]}; + + default: funcpad_data = '{default:'0}; + endcase + end + end + + //////////////// + // Assertions // + //////////////// + + // Prefix size is smaller than the smallest Keccak Block Size, which is 72 bytes. + `CALIPTRA_ASSERT_INIT(PrefixLessThanBlock_A, PrefixSize/8 < KeccakRate[4]) + + // Some part of datapath in sha3pad assumes Data width as 64bit. + // If data width need to be changed, funcpad_data part should be changed too. + // Also, The blocksize shall be divided by MsgWidth, which means, MsgWidth + // can be {16, 32, 64} even funcpad_data mux is fully flexible. + `CALIPTRA_ASSERT_INIT(MsgWidthidth_A, MsgWidth == 64) + + // Assume pulse signals: start, process, done + `CALIPTRA_ASSUME(StartPulse_A, start_i |=> !start_i) + `CALIPTRA_ASSUME(ProcessPulse_A, process_i |=> !process_i) + `CALIPTRA_ASSUME(DonePulse_A, + mubi4_test_true_strict(done_i) |=> + mubi4_test_false_strict(done_i)) + + // ASSERT output pulse signals: absorbed_o, keccak_run_o + `CALIPTRA_ASSERT(AbsorbedPulse_A, + mubi4_test_true_strict(absorbed_o) |=> + mubi4_test_false_strict(absorbed_o)) + `CALIPTRA_ASSERT(KeccakRunPulse_A, keccak_run_o |=> !keccak_run_o) + + // start_i, done_i, process_i cannot set high at the same time + `CALIPTRA_ASSUME(StartProcessDoneMutex_a, + $onehot0({ + start_i, + process_i, + mubi4_test_true_loose(done_i) + })) + + // Sequence, start_i --> process_i --> absorbed_o --> done_i + //`CALIPTRA_ASSUME(Sequence_a, start_i ##[1:$] process_i ##[1:$] ##[1:$] absorbed_o ##[1:$] done_i) + +`ifndef SYNTHESIS + // Process only asserts after start and all message are fed. + // These valid signals are qualifier of FPV to trigger the control signal + // It is a little bit hard to specify these criteria in SVA property so creating + // qualifiers in RTL form is easier. + logic start_valid, process_valid, absorb_valid, done_valid; + + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + start_valid <= 1'b 1; + end else if (start_i) begin + start_valid <= 1'b 0; + end else if (mubi4_test_true_strict(done_i)) begin + start_valid <= 1'b 1; + end + end + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + process_valid <= 1'b 0; + end else if (start_i) begin + process_valid <= 1'b 1; + end else if (process_i) begin + process_valid <= 1'b 0; + end + end + + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + done_valid <= 1'b 0; + end else if (mubi4_test_true_strict(absorbed_o)) begin + done_valid <= 1'b 1; + end else if (mubi4_test_true_strict(done_i)) begin + done_valid <= 1'b 0; + end + end + + // Message can be fed in between start_i and process_i. + `CALIPTRA_ASSUME(MessageCondition_M, msg_valid_i && msg_ready_o |-> process_valid && !process_i) + + // Message ready should be asserted only in between start_i and process_i + `CALIPTRA_ASSERT(MsgReadyCondition_A, msg_ready_o |-> process_valid && !process_i) + + `CALIPTRA_ASSUME(ProcessCondition_M, process_i |-> process_valid) + `CALIPTRA_ASSUME(StartCondition_M, start_i |-> start_valid) + `CALIPTRA_ASSUME(DoneCondition_M, + mubi4_test_true_strict(done_i) |-> done_valid) + + // Assume mode_i and strength_i are stable during the operation + // This will be guarded at the kmac top level + `CALIPTRA_ASSUME(ModeStableDuringOp_M, + $changed(mode_i) |-> start_valid) + `CALIPTRA_ASSUME(StrengthStableDuringOp_M, + $changed(strength_i) |-> start_valid) + +`endif // SYNTHESIS + + // If not full block is written, the pad shall send message to keccak_round + // If it is end of the message, the state moves to StPad and send the request + `CALIPTRA_ASSERT(CompleteBlockWhenProcess_A, + $rose(process_latched) && (!end_of_block && !sent_blocksize ) + && !(st inside {StPrefixWait, StMessageWait}) |-> ##[1:5] keccak_valid_o, + clk_i, !rst_ni || lc_ctrl_pkg::lc_tx_test_true_loose(lc_escalate_en_i)) + + // If process_i asserted, completion shall be asserted shall be asserted + //`CALIPTRA_ASSERT(ProcessToAbsorbed_A, process_i |=> strong(##[24*Share:$] absorbed_o)) + + + // Assumption of input mode_i and strength_i + // SHA3 variants: SHA3-224, SHA3-256, SHA3-384, SHA3-512 + // SHAKE, cSHAKE variants: SHAKE128, SHAKE256, cSHAKE128, cSHAKE256 + `CALIPTRA_ASSUME_FPV(ModeStrengthCombinations_M, + start_i |-> + (mode_i == Sha3 && (strength_i inside {L224, L256, L384, L512})) || + ((mode_i == Shake || mode_i == CShake) && (strength_i inside {L128, L256})), + clk_i, !rst_ni) + + // No partial write is allowed for Message FIFO interface + `CALIPTRA_ASSUME(NoPartialMsgFifo_M, + keccak_valid_o && (sel_mux == MuxFifo) |-> (&msg_strb_i) == 1'b1, + clk_i, !rst_ni) + + // When transaction is stored into msg_buf, it shall be partial write. + `CALIPTRA_ASSUME(AlwaysPartialMsgBuf_M, + en_msgbuf |-> msg_valid_i && (msg_strb_i[MsgStrbW-1] == 1'b0), + clk_i, !rst_ni) + + // if partial write comes and is acked, then no more msg_valid_i until + // next message + `CALIPTRA_ASSUME(PartialEndOfMsg_M, + msg_valid_i && msg_ready_o && msg_partial |=> + !msg_valid_i ##[1:$] $stable(msg_valid_i) ##1 process_latched, + clk_i, !rst_ni) + + // At the first clock in StPad01 state, sent_blocksize shall not be set + `CALIPTRA_ASSERT(Pad01NotAttheEndOfBlock_A, + (st == StPad && st_d == StPad01) |-> !end_of_block, + clk_i, !rst_ni) + + // When data sent to the keccak_round, the address should be in the range + `CALIPTRA_ASSERT(KeccakAddrInRange_A, + keccak_valid_o |-> keccak_addr_o < KeccakRate[strength_i], + clk_i, !rst_ni) + + // NS data shall be stable during the operation. + //`CALIPTRA_ASSUME(NsStableInProcess_A, + // $stable(ns_data_i) throughout(start_i ##[1:$] process_i ##[1:$] absorbed_o), + // clk_i, !rst_ni) + + // Functional Coverage + `CALIPTRA_COVER(StMessageFeed_C, st == StMessage) + `CALIPTRA_COVER(StPad_C, st == StPad01 && sent_blocksize) + `CALIPTRA_COVER(StPadSendMsg_C, st == StPad01 && keccak_ack) + `CALIPTRA_COVER(StComplete_C, st == StPadFlush) +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/pcrvault_cov_bind.sv b/designs/Caliptra/src/caliptra-rtl/pcrvault_cov_bind.sv new file mode 100644 index 0000000..c54f3fc --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/pcrvault_cov_bind.sv @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. + + +module pcrvault_cov_bind; + `ifdef FCOV + bind pv pcrvault_cov_if i_pcrvault_cov_if(.*); + bind pv pcrvault_cov_props i_pcrvault_cov_props(.*); + `endif +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/pcrvault_cov_if.sv b/designs/Caliptra/src/caliptra-rtl/pcrvault_cov_if.sv new file mode 100644 index 0000000..45ae4d9 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/pcrvault_cov_if.sv @@ -0,0 +1,95 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. + +`ifndef VERILATOR + +interface pcrvault_cov_if + import pv_defines_pkg::*; + ( + input logic clk, + input logic rst_b, + input logic cptra_pwrgood +); + + logic [PV_NUM_PCR-1:0] pcr_ctrl_lock; + logic [PV_NUM_PCR-1:0] pcr_ctrl_clear; + + logic [PV_NUM_WRITE-1:0] pv_write_en; + logic ahb_write, ahb_read; + + //Assign clear and locks of each PCR_CTRL reg to corresponding bit in the intermediate bus + generate + for(genvar i = 0; i < PV_NUM_PCR; i++) begin + assign pcr_ctrl_lock[i] = pv.pv_reg_hwif_out.PCR_CTRL[i].lock; + end + endgenerate + + generate + for(genvar client = 0; client < PV_NUM_WRITE; client++) begin + assign pv_write_en[client] = pv.pv_write[client].write_en; + end + endgenerate + + //AHB signals + assign ahb_write = pv.pv_ahb_slv1.dv & pv.pv_ahb_slv1.write; + assign ahb_read = pv.pv_ahb_slv1.dv & ~pv.pv_ahb_slv1.write; + + covergroup pcrvault_top_cov_grp @(posedge clk); + option.per_instance = 1; + + //Note: Bit transitions and values for lock and clear are covered + //in UVM reg coverage. This coverpoint bins the 32-bit lock/clear bus so that + //they can be used to cross with other signals + lock: coverpoint pcr_ctrl_lock { + bins bin0 = {[0:'hFFFF]}; + bins bin1 = {['h1_0000:'hF_FFFF]}; + bins bin2 = {['h10_0000:'hFF_FFFF]}; + bins bin3 = {['h100_0000:'hFFF_FFFF]}; + bins bin4 = {['h1000_0000: 'hFFFF_FFFF]}; + } + clear: coverpoint pcr_ctrl_clear { + bins bin0 = {[0:'hFFFF]}; + bins bin1 = {['h1_0000:'hF_FFFF]}; + bins bin2 = {['h10_0000:'hFF_FFFF]}; + bins bin3 = {['h100_0000:'hFFF_FFFF]}; + bins bin4 = {['h1000_0000: 'hFFFF_FFFF]}; + } + + //Cover warm reset assertion while regs are locked/cleared + lockXwarm_rst: cross lock, rst_b; + clearXwarm_rst: cross clear, rst_b; + + //Cover cold reset assertion while regs are locked/cleared + lockXcold_rst: cross lock, cptra_pwrgood; + clearXcold_rst: cross clear, cptra_pwrgood; + + // lockXcore_rst: cross lock, core_only_rst_b; + // clearXcore_rst: cross clear, core_only_rst_b; + + //Cover crypto writes to locked/cleared regs + lockXpv_write: cross lock, pv_write_en; + clearXpv_write: cross clear, pv_write_en; + + //Cover ahb write and read when crypto writes are happening + ahbXpv_write: cross ahb_write, ahb_read, pv_write_en; + + + endgroup + + + pcrvault_top_cov_grp pcrvault_top_cov_grp1 = new(); + +endinterface + +`endif \ No newline at end of file diff --git a/designs/Caliptra/src/caliptra-rtl/pcrvault_cov_props.sv b/designs/Caliptra/src/caliptra-rtl/pcrvault_cov_props.sv new file mode 100644 index 0000000..3df578a --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/pcrvault_cov_props.sv @@ -0,0 +1,54 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2019 Western Digital Corporation or its affiliates. +// +// 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. +// + +module pcrvault_cov_props + import pv_defines_pkg::*; + (); + + `ifndef VERILATOR + + generate + for(genvar i = 0; i < PV_NUM_PCR; i++) begin + + //clear followed by warm reset in the next clk + //Expectation: PCRs cleared before warm reset + property cover_prop_clear_warm_rst; + @(posedge pv.clk) + (pv.pv_reg_hwif_out.PCR_CTRL[i].clear |-> ##[1:$] !pv.rst_b); + endproperty + covprop_clear_warmrst: cover property(cover_prop_clear_warm_rst); + + //locks, followed by clear, followed by warm reset in the next clk + //Expectation: Unlocked PCRs cleared before warm reset, locks cleared on warm reset + property cover_prop_lock_clear_warm_rst; + @(posedge pv.clk) + (pv.pv_reg_hwif_out.PCR_CTRL[i].lock |-> ##[0:$] pv.pv_reg_hwif_out.PCR_CTRL[i].clear |-> ##[1:$] !pv.rst_b); + endproperty + covprop_lock_clear_warmrst: cover property(cover_prop_lock_clear_warm_rst); + + //locks, followed by clear, followed by cold reset in the next clk + //Expectation: Unlocked PCRs cleared before cold reset, everything cleared on cold reset + property cover_prop_lock_clear_cold_rst; + @(posedge pv.clk) + (pv.pv_reg_hwif_out.PCR_CTRL[i].lock |-> ##[0:$] pv.pv_reg_hwif_out.PCR_CTRL[i].clear |-> ##[1:$] !pv.cptra_pwrgood); + endproperty + covprop_lock_clear_coldrst: cover property(cover_prop_lock_clear_cold_rst); + end + endgenerate + + `endif + +endmodule \ No newline at end of file diff --git a/designs/Caliptra/src/caliptra-rtl/physical_rng.sv b/designs/Caliptra/src/caliptra-rtl/physical_rng.sv new file mode 100644 index 0000000..2d922ba --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/physical_rng.sv @@ -0,0 +1,71 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +// +//====================================================================== +// +// physical_rng.sv +// -------- +// Simple simulation model for a rng. Generates 32b of random data +// and pushes out 4b at a time through the data/valid interface. +// +// An initial seed is provided to generate deterministic results for +// simulation. After the first 384 bits, random data will be generated. +// +//====================================================================== + +module physical_rng #( + // Set UseInitialSeed to 0 to disable + parameter logic UseInitialSeed = 1'b1, + parameter logic [383:0] InitialSeed = 384'h33F63B65F57AD68765693560E743CC5010518E4BF4ECBEBA71DC56AAA08B394311731D9DF763FC5D27E4ED3E4B7DE947, + // Parameter chosen to mimic a slow source (Expected 50kbps in hw) + parameter int unsigned DutyCycle = 500 +) ( + input logic clk, + input logic enable, + output logic [3:0] data, + output logic valid +); + + logic [31:0] count, pulse_count, random_data; + + wire pulse = (count == DutyCycle - 1); + + assign data = random_data[3:0]; + + always @(posedge clk) begin + if (enable) begin + valid <= 1'b0; + count <= count + 1'b1; + + // Generate random data + if (pulse) begin + if (UseInitialSeed && + (pulse_count < $bits(InitialSeed)/$bits(data))) begin + pulse_count <= pulse_count + 1'b1; + random_data[3:0] <= InitialSeed[pulse_count * $bits(data) +:$bits(data)]; + end else begin + random_data <= $urandom(); + end + + valid <= 1'b1; + count <= '0; + end + end else begin + pulse_count <= '0; + valid <= 1'b0; + count <= '0; + end + end + +endmodule : physical_rng diff --git a/designs/Caliptra/src/caliptra-rtl/pic_map_auto.h b/designs/Caliptra/src/caliptra-rtl/pic_map_auto.h new file mode 100644 index 0000000..dd99bbf --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/pic_map_auto.h @@ -0,0 +1,117 @@ +//******************************************************************************** +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2020 Western Digital Corporation or its affiliates. +// +// 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. +//******************************************************************************** + +// mask[3:0] = { 4'b1000 - 30b mask,4'b0100 - 31b mask, 4'b0010 - 28b mask, 4'b0001 - 32b mask } +always_comb begin + case (address[14:0]) + 15'b011000000000000 : mask[3:0] = 4'b0100; + 15'b100000000000100 : mask[3:0] = 4'b1000; + 15'b100000000001000 : mask[3:0] = 4'b1000; + 15'b100000000001100 : mask[3:0] = 4'b1000; + 15'b100000000010000 : mask[3:0] = 4'b1000; + 15'b100000000010100 : mask[3:0] = 4'b1000; + 15'b100000000011000 : mask[3:0] = 4'b1000; + 15'b100000000011100 : mask[3:0] = 4'b1000; + 15'b100000000100000 : mask[3:0] = 4'b1000; + 15'b100000000100100 : mask[3:0] = 4'b1000; + 15'b100000000101000 : mask[3:0] = 4'b1000; + 15'b100000000101100 : mask[3:0] = 4'b1000; + 15'b100000000110000 : mask[3:0] = 4'b1000; + 15'b100000000110100 : mask[3:0] = 4'b1000; + 15'b100000000111000 : mask[3:0] = 4'b1000; + 15'b100000000111100 : mask[3:0] = 4'b1000; + 15'b100000001000000 : mask[3:0] = 4'b1000; + 15'b100000001000100 : mask[3:0] = 4'b1000; + 15'b100000001001000 : mask[3:0] = 4'b1000; + 15'b100000001001100 : mask[3:0] = 4'b1000; + 15'b100000001010000 : mask[3:0] = 4'b1000; + 15'b100000001010100 : mask[3:0] = 4'b1000; + 15'b100000001011000 : mask[3:0] = 4'b1000; + 15'b100000001011100 : mask[3:0] = 4'b1000; + 15'b100000001100000 : mask[3:0] = 4'b1000; + 15'b100000001100100 : mask[3:0] = 4'b1000; + 15'b100000001101000 : mask[3:0] = 4'b1000; + 15'b100000001101100 : mask[3:0] = 4'b1000; + 15'b100000001110000 : mask[3:0] = 4'b1000; + 15'b100000001110100 : mask[3:0] = 4'b1000; + 15'b100000001111000 : mask[3:0] = 4'b1000; + 15'b100000001111100 : mask[3:0] = 4'b1000; + 15'b010000000000100 : mask[3:0] = 4'b0100; + 15'b010000000001000 : mask[3:0] = 4'b0100; + 15'b010000000001100 : mask[3:0] = 4'b0100; + 15'b010000000010000 : mask[3:0] = 4'b0100; + 15'b010000000010100 : mask[3:0] = 4'b0100; + 15'b010000000011000 : mask[3:0] = 4'b0100; + 15'b010000000011100 : mask[3:0] = 4'b0100; + 15'b010000000100000 : mask[3:0] = 4'b0100; + 15'b010000000100100 : mask[3:0] = 4'b0100; + 15'b010000000101000 : mask[3:0] = 4'b0100; + 15'b010000000101100 : mask[3:0] = 4'b0100; + 15'b010000000110000 : mask[3:0] = 4'b0100; + 15'b010000000110100 : mask[3:0] = 4'b0100; + 15'b010000000111000 : mask[3:0] = 4'b0100; + 15'b010000000111100 : mask[3:0] = 4'b0100; + 15'b010000001000000 : mask[3:0] = 4'b0100; + 15'b010000001000100 : mask[3:0] = 4'b0100; + 15'b010000001001000 : mask[3:0] = 4'b0100; + 15'b010000001001100 : mask[3:0] = 4'b0100; + 15'b010000001010000 : mask[3:0] = 4'b0100; + 15'b010000001010100 : mask[3:0] = 4'b0100; + 15'b010000001011000 : mask[3:0] = 4'b0100; + 15'b010000001011100 : mask[3:0] = 4'b0100; + 15'b010000001100000 : mask[3:0] = 4'b0100; + 15'b010000001100100 : mask[3:0] = 4'b0100; + 15'b010000001101000 : mask[3:0] = 4'b0100; + 15'b010000001101100 : mask[3:0] = 4'b0100; + 15'b010000001110000 : mask[3:0] = 4'b0100; + 15'b010000001110100 : mask[3:0] = 4'b0100; + 15'b010000001111000 : mask[3:0] = 4'b0100; + 15'b010000001111100 : mask[3:0] = 4'b0100; + 15'b000000000000100 : mask[3:0] = 4'b0010; + 15'b000000000001000 : mask[3:0] = 4'b0010; + 15'b000000000001100 : mask[3:0] = 4'b0010; + 15'b000000000010000 : mask[3:0] = 4'b0010; + 15'b000000000010100 : mask[3:0] = 4'b0010; + 15'b000000000011000 : mask[3:0] = 4'b0010; + 15'b000000000011100 : mask[3:0] = 4'b0010; + 15'b000000000100000 : mask[3:0] = 4'b0010; + 15'b000000000100100 : mask[3:0] = 4'b0010; + 15'b000000000101000 : mask[3:0] = 4'b0010; + 15'b000000000101100 : mask[3:0] = 4'b0010; + 15'b000000000110000 : mask[3:0] = 4'b0010; + 15'b000000000110100 : mask[3:0] = 4'b0010; + 15'b000000000111000 : mask[3:0] = 4'b0010; + 15'b000000000111100 : mask[3:0] = 4'b0010; + 15'b000000001000000 : mask[3:0] = 4'b0010; + 15'b000000001000100 : mask[3:0] = 4'b0010; + 15'b000000001001000 : mask[3:0] = 4'b0010; + 15'b000000001001100 : mask[3:0] = 4'b0010; + 15'b000000001010000 : mask[3:0] = 4'b0010; + 15'b000000001010100 : mask[3:0] = 4'b0010; + 15'b000000001011000 : mask[3:0] = 4'b0010; + 15'b000000001011100 : mask[3:0] = 4'b0010; + 15'b000000001100000 : mask[3:0] = 4'b0010; + 15'b000000001100100 : mask[3:0] = 4'b0010; + 15'b000000001101000 : mask[3:0] = 4'b0010; + 15'b000000001101100 : mask[3:0] = 4'b0010; + 15'b000000001110000 : mask[3:0] = 4'b0010; + 15'b000000001110100 : mask[3:0] = 4'b0010; + 15'b000000001111000 : mask[3:0] = 4'b0010; + 15'b000000001111100 : mask[3:0] = 4'b0010; + default : mask[3:0] = 4'b0001; + endcase +end diff --git a/designs/Caliptra/src/caliptra-rtl/pv.sv b/designs/Caliptra/src/caliptra-rtl/pv.sv new file mode 100644 index 0000000..1a0a1ff --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/pv.sv @@ -0,0 +1,196 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +// + + +`include "caliptra_macros.svh" + +module pv + import pv_defines_pkg::*; + import pv_reg_pkg::*; + + #( + parameter AHB_ADDR_WIDTH = PV_ADDR_W + ,parameter AHB_DATA_WIDTH = 32 + ) + ( + input logic clk, + input logic rst_b, + input logic core_only_rst_b, + input logic cptra_pwrgood, + input logic fw_update_rst_window, + + //uC AHB Lite Interface + //from SLAVES PORT + input logic [AHB_ADDR_WIDTH-1:0] haddr_i, + input logic [AHB_DATA_WIDTH-1:0] hwdata_i, + input logic hsel_i, + input logic hwrite_i, + input logic hready_i, + input logic [1:0] htrans_i, + input logic [2:0] hsize_i, + + output logic hresp_o, + output logic hreadyout_o, + output logic [AHB_DATA_WIDTH-1:0] hrdata_o, + + input pv_read_t [PV_NUM_READ-1:0] pv_read, + input pv_write_t [PV_NUM_WRITE-1:0] pv_write, + output pv_rd_resp_t [PV_NUM_READ-1:0] pv_rd_resp, + output pv_wr_resp_t [PV_NUM_WRITE-1:0] pv_wr_resp + +); + +logic uc_req_dv, uc_req_hold; +logic uc_req_error; +logic [31:0] uc_req_rdata; +logic pv_reg_read_error, pv_reg_write_error; +logic [AHB_ADDR_WIDTH-1:0] uc_req_addr; +pv_uc_req_t uc_req; + +//intermediate signals to make verilator happy +logic [PV_NUM_PCR-1:0][PV_NUM_DWORDS-1:0] pv_entry_we; +logic [PV_NUM_PCR-1:0][PV_NUM_DWORDS-1:0][31:0] pv_entry_next; + +pv_reg__in_t pv_reg_hwif_in; +pv_reg__out_t pv_reg_hwif_out; + +ahb_slv_sif #( + .AHB_ADDR_WIDTH(AHB_ADDR_WIDTH), + .AHB_DATA_WIDTH(AHB_DATA_WIDTH), + .CLIENT_DATA_WIDTH(32) +) +pv_ahb_slv1 ( + //AMBA AHB Lite INF + .hclk(clk), + .hreset_n(rst_b), + .haddr_i(haddr_i), + .hwdata_i(hwdata_i), + .hsel_i(hsel_i), + .hwrite_i(hwrite_i), + .hready_i(hready_i), + .htrans_i(htrans_i), + .hsize_i(hsize_i), + + .hresp_o(hresp_o), + .hreadyout_o(hreadyout_o), + .hrdata_o(hrdata_o), + + + //COMPONENT INF + .dv(uc_req_dv), + .hld(uc_req_hold), + .err(uc_req_error), + .write(uc_req.write), + .wdata(uc_req.wdata), + .addr(uc_req_addr), + + .rdata(uc_req_rdata) +); + +always_comb uc_req.addr = uc_req_addr[PV_ADDR_W-1:0]; +always_comb uc_req_error = pv_reg_read_error | pv_reg_write_error; +always_comb uc_req_hold = '0; + +always_comb begin : keyvault_ctrl + for (int entry = 0; entry < PV_NUM_PCR; entry++) begin + //once lock is set, any reset can unset it + //During a fw update reset we'll be de-asserting locks - avoid RDC violation by synchronously de-asserting + pv_reg_hwif_in.PCR_CTRL[entry].lock.swwel = pv_reg_hwif_out.PCR_CTRL[entry].lock.value & ~fw_update_rst_window; + pv_reg_hwif_in.PCR_CTRL[entry].clear.swwel = pv_reg_hwif_out.PCR_CTRL[entry].lock.value & ~fw_update_rst_window; + end + + //pcrvault storage + //AND-OR mux writes to each entry from crypto blocks + //write to the appropriate dest entry and offset when write_en is set + for (int entry = 0; entry < PV_NUM_PCR; entry++) begin + for (int dword = 0; dword < PV_NUM_DWORDS; dword++) begin + //initialize to 0 for AND-OR mux + pv_entry_we[entry][dword] = '0; + pv_entry_next[entry][dword] = '0; + + for (int client = 0; client < PV_NUM_WRITE; client++) begin + pv_entry_we[entry][dword] |= pv_write[client].write_en &(pv_write[client].write_entry == entry) & + (pv_write[client].write_offset == dword); + pv_entry_next[entry][dword] |= pv_write[client].write_en & (pv_write[client].write_entry == entry) ? pv_write[client].write_data : '0; + end + pv_reg_hwif_in.PCR_ENTRY[entry][dword].data.we = pv_entry_we[entry][dword]; + pv_reg_hwif_in.PCR_ENTRY[entry][dword].data.next = pv_entry_next[entry][dword]; + pv_reg_hwif_in.PCR_ENTRY[entry][dword].data.hwclr = pv_reg_hwif_out.PCR_CTRL[entry].clear.value; + end + end +end + +//read mux for pcrvault +//qualify with selected entry, offset +always_comb begin : keyvault_readmux + for (int client = 0; client < PV_NUM_READ; client++) begin + pv_rd_resp[client].read_data = '0; + pv_rd_resp[client].last = '0; + pv_rd_resp[client].error = '0; + for (int entry = 0; entry < PV_NUM_PCR; entry++) begin + for (int dword = 0; dword < PV_NUM_DWORDS; dword++) begin + pv_rd_resp[client].read_data |= (pv_read[client].read_entry == entry) & (pv_read[client].read_offset == dword) ? + pv_reg_hwif_out.PCR_ENTRY[entry][dword].data.value : '0; + end + pv_rd_resp[client].last |= (pv_read[client].read_entry == entry) & (pv_read[client].read_offset == PV_NUM_DWORDS-1); + pv_rd_resp[client].error |= '0; //currently no read errors for PCR + end + end +end + +//Write error when attempting to write to entry that is locked for writes +always_comb begin : keyvault_write_resp + for (int client = 0 ; client < PV_NUM_WRITE; client++) begin + pv_wr_resp[client].error = '0; + for (int entry = 0; entry < PV_NUM_PCR; entry++) begin + pv_wr_resp[client].error |= '0; //currently no write errors for PCR + end + end +end + +//tie-offs +always_comb begin + for (int entry = 0; entry < PV_NUM_PCR; entry++) begin + pv_reg_hwif_in.PCR_CTRL[entry].rsvd0.hwclr = '0; + end +end + + +always_comb pv_reg_hwif_in.hard_reset_b = cptra_pwrgood; +always_comb pv_reg_hwif_in.reset_b = rst_b; +always_comb pv_reg_hwif_in.core_only_rst_b = core_only_rst_b; //Note that this signal will also reset when rst_b is asserted + +pv_reg pv_reg1 ( + .clk(clk), + .rst('0), + //qualify request so no addresses alias + .s_cpuif_req(uc_req_dv & (uc_req.addr[PV_ADDR_W-1:PV_REG_ADDR_WIDTH] == '0)), + .s_cpuif_req_is_wr(uc_req.write), + .s_cpuif_addr(uc_req.addr[PV_REG_ADDR_WIDTH-1:0]), + .s_cpuif_wr_data(uc_req.wdata), + .s_cpuif_wr_biten('1), + .s_cpuif_req_stall_wr(), + .s_cpuif_req_stall_rd(), + .s_cpuif_rd_ack(), + .s_cpuif_rd_err(pv_reg_read_error), + .s_cpuif_rd_data(uc_req_rdata), + .s_cpuif_wr_ack(), + .s_cpuif_wr_err(pv_reg_write_error), + + .hwif_in(pv_reg_hwif_in), + .hwif_out(pv_reg_hwif_out) +); + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/pv_defines_pkg.sv b/designs/Caliptra/src/caliptra-rtl/pv_defines_pkg.sv new file mode 100644 index 0000000..b69c43b --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/pv_defines_pkg.sv @@ -0,0 +1,63 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +// +`ifndef PV_DEFINES_PKG +`define PV_DEFINES_PKG + +package pv_defines_pkg; + +parameter PV_NUM_DWORDS = 12; //number of dwords per pcr +parameter PV_NUM_PCR = 32; +parameter PV_ADDR_W = 13; +parameter PV_DATA_W = 32; +parameter PV_ENTRY_ADDR_W = $clog2(PV_NUM_PCR); +parameter PV_ENTRY_SIZE_WIDTH = $clog2(PV_NUM_DWORDS); +parameter PV_NUM_READ = 1; +parameter PV_NUM_WRITE = 1; +parameter PV_SIZE_OF_NONCE = 256; + + +typedef struct packed { + logic [PV_ADDR_W-1:0] addr; + logic [PV_DATA_W-1:0] wdata; + logic write; +} pv_uc_req_t; + +typedef struct packed { + logic [PV_ENTRY_ADDR_W-1:0] read_entry; + logic [PV_ENTRY_SIZE_WIDTH-1:0] read_offset; +} pv_read_t; + +typedef struct packed { + logic write_en; + logic [PV_ENTRY_ADDR_W-1:0] write_entry; + logic [PV_ENTRY_SIZE_WIDTH-1:0] write_offset; + logic [PV_DATA_W-1:0] write_data; +} pv_write_t; + +typedef struct packed { + logic error; +} pv_wr_resp_t; + +typedef struct packed { + logic error; + logic last; + logic [PV_DATA_W-1:0] read_data; +} pv_rd_resp_t; + +endpackage + +`endif + + diff --git a/designs/Caliptra/src/caliptra-rtl/pv_gen_hash.sv b/designs/Caliptra/src/caliptra-rtl/pv_gen_hash.sv new file mode 100644 index 0000000..689e752 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/pv_gen_hash.sv @@ -0,0 +1,223 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +// + + +`include "caliptra_macros.svh" + +module pv_gen_hash + import pv_defines_pkg::*; + #( + parameter BLOCK_W = 1024 + ,parameter DATA_W = 32 + ,localparam BLOCK_NO = BLOCK_W/DATA_W + ,localparam BLOCK_OFFSET_W = $clog2(BLOCK_NO) + ,localparam NONCE_LEN_DWORD = PV_SIZE_OF_NONCE/DATA_W + ,localparam NONCE_OFFSET_W = $clog2(NONCE_LEN_DWORD) + ) + ( + input logic clk, + input logic rst_b, + input logic zeroize, + + input logic start, + input logic core_ready, + input logic core_digest_valid, + input [NONCE_LEN_DWORD-1:0][DATA_W-1:0] nonce, + + output logic gen_hash_ip, + output logic gen_hash_init_reg, + output logic gen_hash_next_reg, + output logic gen_hash_last_reg, + + output logic block_we, + output logic [BLOCK_OFFSET_W-1:0] block_offset, + output logic [DATA_W-1:0] block_wr_data, + + output pv_read_t pv_read, + input pv_rd_resp_t pv_rd_resp + +); + +localparam PAD_LEN_DWORD = BLOCK_NO - 4; + +typedef enum logic [3:0] { + GEN_HASH_IDLE = 4'b0000, + GEN_HASH_BLOCK_0 = 4'b0001, + GEN_HASH_BLOCK_N = 4'b0011, + GEN_HASH_NONCE = 4'b0010, + GEN_HASH_PAD_LD1 = 4'b0110, + GEN_HASH_PAD_0S = 4'b0111, + GEN_HASH_PAD_LEN = 4'b0101, + GEN_HASH_WT_LAST = 4'b0100, + GEN_HASH_DONE = 4'b1100 + } gen_hash_fsm_state_e; + +logic init_reg; +logic next_reg; + +gen_hash_fsm_state_e gen_hash_fsm_ps, gen_hash_fsm_ns; + +logic arc_GEN_HASH_IDLE_GEN_HASH_BLOCK_0; +logic arc_GEN_HASH_BLOCK_0_GEN_HASH_BLOCK_N; +logic arc_GEN_HASH_BLOCK_0_GEN_HASH_NONCE; +logic arc_GEN_HASH_BLOCK_N_GEN_HASH_BLOCK_N; +logic arc_GEN_HASH_BLOCK_N_GEN_HASH_NONCE; +logic arc_GEN_HASH_NONCE_GEN_HASH_PAD_LD1; +logic arc_GEN_HASH_PAD_LD1_GEN_HASH_PAD_0S; +logic arc_GEN_HASH_PAD_0S_GEN_HASH_PAD_LEN; +logic arc_GEN_HASH_PAD_LEN_GEN_HASH_WT_LAST; +logic arc_GEN_HASH_WT_LAST_GEN_HASH_DONE; + +logic [3:0][31:0] pad_length; + +logic [BLOCK_OFFSET_W:0] block_offset_i,block_offset_nxt; +logic block_full; +logic last_dword_wr; + +logic [PV_ENTRY_ADDR_W-1:0] read_entry, read_entry_nxt; +logic [PV_ENTRY_SIZE_WIDTH-1:0] read_offset, read_offset_nxt; +logic inc_rd_ptr; +logic rst_rd_ptr; + +logic [NONCE_OFFSET_W-1:0] nonce_offset_i, nonce_offset_nxt; + + +assign gen_hash_ip = (gen_hash_fsm_ps != GEN_HASH_IDLE); +assign gen_hash_init_reg = arc_GEN_HASH_BLOCK_0_GEN_HASH_BLOCK_N; +assign gen_hash_next_reg = arc_GEN_HASH_BLOCK_N_GEN_HASH_BLOCK_N | + (block_full & gen_hash_fsm_ps inside {GEN_HASH_NONCE, GEN_HASH_PAD_LD1, GEN_HASH_PAD_0S, GEN_HASH_PAD_LEN} & core_ready); +assign gen_hash_last_reg = gen_hash_fsm_ps == GEN_HASH_WT_LAST; +assign pad_length = (PV_NUM_PCR * PV_NUM_DWORDS * PV_DATA_W) + PV_SIZE_OF_NONCE; + +assign block_offset = block_offset_i[BLOCK_OFFSET_W-1:0]; + + //PCR read pointer + always_comb read_offset_nxt = (rst_rd_ptr | (inc_rd_ptr & (read_offset == PV_NUM_DWORDS-1))) ? '0 : + inc_rd_ptr ? read_offset + 'd1 : + read_offset; + always_comb read_entry_nxt = rst_rd_ptr ? '0 : + (inc_rd_ptr & (read_offset == PV_NUM_DWORDS-1)) ? read_entry + 'd1 : + read_entry; + + always_comb block_we = ~(gen_hash_fsm_ps inside {GEN_HASH_IDLE,GEN_HASH_WT_LAST,GEN_HASH_DONE}) & ~block_full; + always_comb block_offset_nxt = (gen_hash_fsm_ps != GEN_HASH_IDLE) & block_full & core_ready ? '0 : + (block_we ? block_offset_i + 'd1 : block_offset_i); + + always_comb block_full = block_offset_i == BLOCK_NO; + always_comb last_dword_wr = (read_offset == PV_NUM_DWORDS-1) & (read_entry == PV_NUM_PCR-1); + + always_comb inc_rd_ptr = gen_hash_fsm_ps inside {GEN_HASH_BLOCK_0, GEN_HASH_BLOCK_N} & ~block_full; + always_comb rst_rd_ptr = arc_GEN_HASH_BLOCK_0_GEN_HASH_NONCE | arc_GEN_HASH_BLOCK_N_GEN_HASH_NONCE; + + + always_comb nonce_offset_nxt = (gen_hash_fsm_ps != GEN_HASH_NONCE) ? '0 : + (block_we ? nonce_offset_i + 'd1 : nonce_offset_i); + + //State Machine + //Start processing + always_comb arc_GEN_HASH_IDLE_GEN_HASH_BLOCK_0 = (gen_hash_fsm_ps == GEN_HASH_IDLE) & start; + //Process first full block when full and core is ready + always_comb arc_GEN_HASH_BLOCK_0_GEN_HASH_BLOCK_N = (gen_hash_fsm_ps == GEN_HASH_BLOCK_0) & block_full & core_ready; + //Process Nth block when block is full and core is ready + always_comb arc_GEN_HASH_BLOCK_N_GEN_HASH_BLOCK_N = (gen_hash_fsm_ps == GEN_HASH_BLOCK_N) & block_full & core_ready; + //Finished reading, start padding - wait for block to process if we need to start a new block + always_comb arc_GEN_HASH_BLOCK_0_GEN_HASH_NONCE = (gen_hash_fsm_ps == GEN_HASH_BLOCK_0) & ~block_full & last_dword_wr; + always_comb arc_GEN_HASH_BLOCK_N_GEN_HASH_NONCE = (gen_hash_fsm_ps == GEN_HASH_BLOCK_N) & ~block_full & last_dword_wr; + always_comb arc_GEN_HASH_NONCE_GEN_HASH_PAD_LD1 = (gen_hash_fsm_ps == GEN_HASH_NONCE) & ~block_full & (nonce_offset_i == NONCE_LEN_DWORD-1); + always_comb arc_GEN_HASH_PAD_LD1_GEN_HASH_PAD_0S = (gen_hash_fsm_ps == GEN_HASH_PAD_LD1) & ~block_full; + //Switch from padding zeros to padding the length + always_comb arc_GEN_HASH_PAD_0S_GEN_HASH_PAD_LEN = (gen_hash_fsm_ps == GEN_HASH_PAD_0S) & ~block_full & (block_offset_i == PAD_LEN_DWORD-1); + //Move to wait for last state + always_comb arc_GEN_HASH_PAD_LEN_GEN_HASH_WT_LAST = (gen_hash_fsm_ps == GEN_HASH_PAD_LEN) & block_full & core_ready; + //move to done when finished processing the last block + always_comb arc_GEN_HASH_WT_LAST_GEN_HASH_DONE = (gen_hash_fsm_ps == GEN_HASH_WT_LAST) & core_digest_valid; + + //GEN_HASH API FSM State Combo + always_comb begin : sha_api_combo + //default back to present state + gen_hash_fsm_ns = gen_hash_fsm_ps; + block_wr_data = '0; + + unique case (gen_hash_fsm_ps) inside + GEN_HASH_IDLE: begin + if (arc_GEN_HASH_IDLE_GEN_HASH_BLOCK_0) gen_hash_fsm_ns = GEN_HASH_BLOCK_0; + end + GEN_HASH_BLOCK_0: begin + if (arc_GEN_HASH_BLOCK_0_GEN_HASH_BLOCK_N) gen_hash_fsm_ns = GEN_HASH_BLOCK_N; + else if (arc_GEN_HASH_BLOCK_0_GEN_HASH_NONCE) gen_hash_fsm_ns = GEN_HASH_NONCE; + block_wr_data = pv_rd_resp.read_data; + end + GEN_HASH_BLOCK_N: begin + if (arc_GEN_HASH_BLOCK_N_GEN_HASH_BLOCK_N) gen_hash_fsm_ns = GEN_HASH_BLOCK_N; + else if (arc_GEN_HASH_BLOCK_N_GEN_HASH_NONCE) gen_hash_fsm_ns = GEN_HASH_NONCE; + block_wr_data = pv_rd_resp.read_data; + end + GEN_HASH_NONCE: begin + if (arc_GEN_HASH_NONCE_GEN_HASH_PAD_LD1) gen_hash_fsm_ns = GEN_HASH_PAD_LD1; + block_wr_data = nonce[NONCE_LEN_DWORD-1-nonce_offset_i]; + end + GEN_HASH_PAD_LD1: begin + if (arc_GEN_HASH_PAD_LD1_GEN_HASH_PAD_0S) gen_hash_fsm_ns = GEN_HASH_PAD_0S; + block_wr_data = 'h8000_0000; + end + GEN_HASH_PAD_0S: begin + if (arc_GEN_HASH_PAD_0S_GEN_HASH_PAD_LEN) gen_hash_fsm_ns = GEN_HASH_PAD_LEN; + block_wr_data = 'h0000_0000; + end + GEN_HASH_PAD_LEN: begin + if (arc_GEN_HASH_PAD_LEN_GEN_HASH_WT_LAST) gen_hash_fsm_ns = GEN_HASH_WT_LAST; + block_wr_data = pad_length[3-block_offset_i[1:0]]; + end + GEN_HASH_WT_LAST: begin + if (arc_GEN_HASH_WT_LAST_GEN_HASH_DONE) gen_hash_fsm_ns = GEN_HASH_DONE; + end + GEN_HASH_DONE: begin + gen_hash_fsm_ns = GEN_HASH_IDLE; + end + default: begin + //TODO Error condition + gen_hash_fsm_ns = GEN_HASH_IDLE; + end + endcase + end + + assign pv_read.read_entry = read_entry; + assign pv_read.read_offset = read_offset; + + always_ff @(posedge clk or negedge rst_b) begin : api_regs + if (~rst_b) begin + gen_hash_fsm_ps <= GEN_HASH_IDLE; + block_offset_i <= '0; + nonce_offset_i <= '0; + read_entry <= '0; + read_offset <= '0; + end + else if (zeroize) begin + gen_hash_fsm_ps <= GEN_HASH_IDLE; + block_offset_i <= '0; + nonce_offset_i <= '0; + read_entry <= '0; + read_offset <= '0; + end + else begin + gen_hash_fsm_ps <= gen_hash_fsm_ns; + block_offset_i <= block_offset_nxt; + nonce_offset_i <= nonce_offset_nxt; + read_entry <= read_entry_nxt; + read_offset <= read_offset_nxt; + end + end + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/pv_macros.svh b/designs/Caliptra/src/caliptra-rtl/pv_macros.svh new file mode 100644 index 0000000..0240131 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/pv_macros.svh @@ -0,0 +1,41 @@ +// SPDX-License-Identifier: Apache-2.0PV_MACROS +// +// 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. +// +`ifndef PV_MACROS +`define PV_MACROS + + + +`define PV_WRITE_CTRL_REG2STRUCT(struct_name, ctrl_reg_name)\ +assign struct_name.rsvd = '0;\ +assign struct_name.write_dest_vld[0] = hwif_out.``ctrl_reg_name.hmac_key_dest_valid.value;\ +assign struct_name.write_dest_vld[1] = hwif_out.``ctrl_reg_name.hmac_block_dest_valid.value;\ +assign struct_name.write_dest_vld[2] = hwif_out.``ctrl_reg_name.sha_block_dest_valid.value;\ +assign struct_name.write_dest_vld[3] = hwif_out.``ctrl_reg_name.ecc_pkey_dest_valid.value;\ +assign struct_name.write_dest_vld[4] = hwif_out.``ctrl_reg_name.ecc_seed_dest_valid.value;\ +assign struct_name.write_dest_vld[5] = hwif_out.``ctrl_reg_name.ecc_msg_dest_valid.value;\ +assign struct_name.entry_is_pv = hwif_out.``ctrl_reg_name.entry_is_pv.value;\ +assign struct_name.write_entry = hwif_out.``ctrl_reg_name.write_entry.value;\ +assign struct_name.write_en = hwif_out.``ctrl_reg_name.write_en.value; + +`define PV_READ_CTRL_REG2STRUCT(struct_name, ctrl_reg_name)\ +assign struct_name.rsvd = '0;\ +assign struct_name.entry_data_size = hwif_out.``ctrl_reg_name.entry_data_size.value;\ +assign struct_name.entry_is_pv = hwif_out.``ctrl_reg_name.entry_is_pv.value;\ +assign struct_name.read_entry = hwif_out.``ctrl_reg_name.read_entry.value;\ +assign struct_name.read_en = hwif_out.``ctrl_reg_name.read_en.value; + +`endif + + diff --git a/designs/Caliptra/src/caliptra-rtl/pv_reg.sv b/designs/Caliptra/src/caliptra-rtl/pv_reg.sv new file mode 100644 index 0000000..fee15c4 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/pv_reg.sv @@ -0,0 +1,316 @@ +// Generated by PeakRDL-regblock - A free and open-source SystemVerilog generator +// https://github.com/SystemRDL/PeakRDL-regblock + +module pv_reg ( + input wire clk, + input wire rst, + + input wire s_cpuif_req, + input wire s_cpuif_req_is_wr, + input wire [11:0] s_cpuif_addr, + input wire [31:0] s_cpuif_wr_data, + input wire [31:0] s_cpuif_wr_biten, + output wire s_cpuif_req_stall_wr, + output wire s_cpuif_req_stall_rd, + output wire s_cpuif_rd_ack, + output wire s_cpuif_rd_err, + output wire [31:0] s_cpuif_rd_data, + output wire s_cpuif_wr_ack, + output wire s_cpuif_wr_err, + + input pv_reg_pkg::pv_reg__in_t hwif_in, + output pv_reg_pkg::pv_reg__out_t hwif_out + ); + + //-------------------------------------------------------------------------- + // CPU Bus interface logic + //-------------------------------------------------------------------------- + logic cpuif_req; + logic cpuif_req_is_wr; + logic [11:0] cpuif_addr; + logic [31:0] cpuif_wr_data; + logic [31:0] cpuif_wr_biten; + logic cpuif_req_stall_wr; + logic cpuif_req_stall_rd; + + logic cpuif_rd_ack; + logic cpuif_rd_err; + logic [31:0] cpuif_rd_data; + + logic cpuif_wr_ack; + logic cpuif_wr_err; + + assign cpuif_req = s_cpuif_req; + assign cpuif_req_is_wr = s_cpuif_req_is_wr; + assign cpuif_addr = s_cpuif_addr; + assign cpuif_wr_data = s_cpuif_wr_data; + assign cpuif_wr_biten = s_cpuif_wr_biten; + assign s_cpuif_req_stall_wr = cpuif_req_stall_wr; + assign s_cpuif_req_stall_rd = cpuif_req_stall_rd; + assign s_cpuif_rd_ack = cpuif_rd_ack; + assign s_cpuif_rd_err = cpuif_rd_err; + assign s_cpuif_rd_data = cpuif_rd_data; + assign s_cpuif_wr_ack = cpuif_wr_ack; + assign s_cpuif_wr_err = cpuif_wr_err; + + logic cpuif_req_masked; + + // Read & write latencies are balanced. Stalls not required + assign cpuif_req_stall_rd = '0; + assign cpuif_req_stall_wr = '0; + assign cpuif_req_masked = cpuif_req + & !(!cpuif_req_is_wr & cpuif_req_stall_rd) + & !(cpuif_req_is_wr & cpuif_req_stall_wr); + + //-------------------------------------------------------------------------- + // Address Decode + //-------------------------------------------------------------------------- + typedef struct packed{ + logic [32-1:0]PCR_CTRL; + logic [32-1:0][12-1:0]PCR_ENTRY; + } decoded_reg_strb_t; + decoded_reg_strb_t decoded_reg_strb; + logic decoded_req; + logic decoded_req_is_wr; + logic [31:0] decoded_wr_data; + logic [31:0] decoded_wr_biten; + + always_comb begin + for(int i0=0; i0<32; i0++) begin + decoded_reg_strb.PCR_CTRL[i0] = cpuif_req_masked & (cpuif_addr == 12'h0 + i0*12'h4); + end + for(int i0=0; i0<32; i0++) begin + for(int i1=0; i1<12; i1++) begin + decoded_reg_strb.PCR_ENTRY[i0][i1] = cpuif_req_masked & (cpuif_addr == 12'h600 + i0*12'h30 + i1*12'h4); + end + end + end + + // Pass down signals to next stage + assign decoded_req = cpuif_req_masked; + assign decoded_req_is_wr = cpuif_req_is_wr; + assign decoded_wr_data = cpuif_wr_data; + assign decoded_wr_biten = cpuif_wr_biten; + + //-------------------------------------------------------------------------- + // Field logic + //-------------------------------------------------------------------------- + typedef struct packed{ + struct packed{ + struct packed{ + logic next; + logic load_next; + } lock; + struct packed{ + logic next; + logic load_next; + } clear; + struct packed{ + logic next; + logic load_next; + } rsvd0; + struct packed{ + logic [4:0] next; + logic load_next; + } rsvd1; + } [32-1:0]PCR_CTRL; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } data; + } [32-1:0][12-1:0]PCR_ENTRY; + } field_combo_t; + field_combo_t field_combo; + + typedef struct packed{ + struct packed{ + struct packed{ + logic value; + } lock; + struct packed{ + logic value; + } clear; + struct packed{ + logic value; + } rsvd0; + struct packed{ + logic [4:0] value; + } rsvd1; + } [32-1:0]PCR_CTRL; + struct packed{ + struct packed{ + logic [31:0] value; + } data; + } [32-1:0][12-1:0]PCR_ENTRY; + } field_storage_t; + field_storage_t field_storage; + + for(genvar i0=0; i0<32; i0++) begin + // Field: pv_reg.PCR_CTRL[].lock + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.PCR_CTRL[i0].lock.value; + load_next_c = '0; + if(decoded_reg_strb.PCR_CTRL[i0] && decoded_req_is_wr && !(hwif_in.PCR_CTRL[i0].lock.swwel)) begin // SW write + next_c = (field_storage.PCR_CTRL[i0].lock.value & ~decoded_wr_biten[0:0]) | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end + field_combo.PCR_CTRL[i0].lock.next = next_c; + field_combo.PCR_CTRL[i0].lock.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.core_only_rst_b) begin + if(~hwif_in.core_only_rst_b) begin + field_storage.PCR_CTRL[i0].lock.value <= 1'h0; + end else if(field_combo.PCR_CTRL[i0].lock.load_next) begin + field_storage.PCR_CTRL[i0].lock.value <= field_combo.PCR_CTRL[i0].lock.next; + end + end + assign hwif_out.PCR_CTRL[i0].lock.value = field_storage.PCR_CTRL[i0].lock.value; + // Field: pv_reg.PCR_CTRL[].clear + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.PCR_CTRL[i0].clear.value; + load_next_c = '0; + if(decoded_reg_strb.PCR_CTRL[i0] && decoded_req_is_wr && !(hwif_in.PCR_CTRL[i0].clear.swwel)) begin // SW write + next_c = (field_storage.PCR_CTRL[i0].clear.value & ~decoded_wr_biten[1:1]) | (decoded_wr_data[1:1] & decoded_wr_biten[1:1]); + load_next_c = '1; + end else begin // singlepulse clears back to 0 + next_c = '0; + load_next_c = '1; + end + field_combo.PCR_CTRL[i0].clear.next = next_c; + field_combo.PCR_CTRL[i0].clear.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.PCR_CTRL[i0].clear.value <= 1'h0; + end else if(field_combo.PCR_CTRL[i0].clear.load_next) begin + field_storage.PCR_CTRL[i0].clear.value <= field_combo.PCR_CTRL[i0].clear.next; + end + end + assign hwif_out.PCR_CTRL[i0].clear.value = field_storage.PCR_CTRL[i0].clear.value; + // Field: pv_reg.PCR_CTRL[].rsvd0 + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.PCR_CTRL[i0].rsvd0.value; + load_next_c = '0; + if(decoded_reg_strb.PCR_CTRL[i0] && decoded_req_is_wr) begin // SW write + next_c = (field_storage.PCR_CTRL[i0].rsvd0.value & ~decoded_wr_biten[2:2]) | (decoded_wr_data[2:2] & decoded_wr_biten[2:2]); + load_next_c = '1; + end else if(hwif_in.PCR_CTRL[i0].rsvd0.hwclr) begin // HW Clear + next_c = '0; + load_next_c = '1; + end + field_combo.PCR_CTRL[i0].rsvd0.next = next_c; + field_combo.PCR_CTRL[i0].rsvd0.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.PCR_CTRL[i0].rsvd0.value <= 1'h0; + end else if(field_combo.PCR_CTRL[i0].rsvd0.load_next) begin + field_storage.PCR_CTRL[i0].rsvd0.value <= field_combo.PCR_CTRL[i0].rsvd0.next; + end + end + assign hwif_out.PCR_CTRL[i0].rsvd0.value = field_storage.PCR_CTRL[i0].rsvd0.value; + // Field: pv_reg.PCR_CTRL[].rsvd1 + always_comb begin + automatic logic [4:0] next_c; + automatic logic load_next_c; + next_c = field_storage.PCR_CTRL[i0].rsvd1.value; + load_next_c = '0; + if(decoded_reg_strb.PCR_CTRL[i0] && decoded_req_is_wr) begin // SW write + next_c = (field_storage.PCR_CTRL[i0].rsvd1.value & ~decoded_wr_biten[7:3]) | (decoded_wr_data[7:3] & decoded_wr_biten[7:3]); + load_next_c = '1; + end + field_combo.PCR_CTRL[i0].rsvd1.next = next_c; + field_combo.PCR_CTRL[i0].rsvd1.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.PCR_CTRL[i0].rsvd1.value <= 5'h0; + end else if(field_combo.PCR_CTRL[i0].rsvd1.load_next) begin + field_storage.PCR_CTRL[i0].rsvd1.value <= field_combo.PCR_CTRL[i0].rsvd1.next; + end + end + assign hwif_out.PCR_CTRL[i0].rsvd1.value = field_storage.PCR_CTRL[i0].rsvd1.value; + end + for(genvar i0=0; i0<32; i0++) begin + for(genvar i1=0; i1<12; i1++) begin + // Field: pv_reg.PCR_ENTRY[][].data + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.PCR_ENTRY[i0][i1].data.value; + load_next_c = '0; + if(hwif_in.PCR_ENTRY[i0][i1].data.we) begin // HW Write - we + next_c = hwif_in.PCR_ENTRY[i0][i1].data.next; + load_next_c = '1; + end else if(hwif_in.PCR_ENTRY[i0][i1].data.hwclr) begin // HW Clear + next_c = '0; + load_next_c = '1; + end + field_combo.PCR_ENTRY[i0][i1].data.next = next_c; + field_combo.PCR_ENTRY[i0][i1].data.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.hard_reset_b) begin + if(~hwif_in.hard_reset_b) begin + field_storage.PCR_ENTRY[i0][i1].data.value <= 32'h0; + end else if(field_combo.PCR_ENTRY[i0][i1].data.load_next) begin + field_storage.PCR_ENTRY[i0][i1].data.value <= field_combo.PCR_ENTRY[i0][i1].data.next; + end + end + assign hwif_out.PCR_ENTRY[i0][i1].data.value = field_storage.PCR_ENTRY[i0][i1].data.value; + end + end + + //-------------------------------------------------------------------------- + // Write response + //-------------------------------------------------------------------------- + assign cpuif_wr_ack = decoded_req & decoded_req_is_wr; + // Writes are always granted with no error response + assign cpuif_wr_err = '0; + + //-------------------------------------------------------------------------- + // Readback + //-------------------------------------------------------------------------- + + logic readback_err; + logic readback_done; + logic [31:0] readback_data; + + // Assign readback values to a flattened array + logic [416-1:0][31:0] readback_array; + for(genvar i0=0; i0<32; i0++) begin + assign readback_array[i0*1 + 0][0:0] = (decoded_reg_strb.PCR_CTRL[i0] && !decoded_req_is_wr) ? field_storage.PCR_CTRL[i0].lock.value : '0; + assign readback_array[i0*1 + 0][1:1] = (decoded_reg_strb.PCR_CTRL[i0] && !decoded_req_is_wr) ? field_storage.PCR_CTRL[i0].clear.value : '0; + assign readback_array[i0*1 + 0][2:2] = (decoded_reg_strb.PCR_CTRL[i0] && !decoded_req_is_wr) ? field_storage.PCR_CTRL[i0].rsvd0.value : '0; + assign readback_array[i0*1 + 0][7:3] = (decoded_reg_strb.PCR_CTRL[i0] && !decoded_req_is_wr) ? field_storage.PCR_CTRL[i0].rsvd1.value : '0; + assign readback_array[i0*1 + 0][31:8] = '0; + end + for(genvar i0=0; i0<32; i0++) begin + for(genvar i1=0; i1<12; i1++) begin + assign readback_array[i0*12 + i1*1 + 32][31:0] = (decoded_reg_strb.PCR_ENTRY[i0][i1] && !decoded_req_is_wr) ? field_storage.PCR_ENTRY[i0][i1].data.value : '0; + end + end + + // Reduce the array + always_comb begin + automatic logic [31:0] readback_data_var; + readback_done = decoded_req & ~decoded_req_is_wr; + readback_err = '0; + readback_data_var = '0; + for(int i=0; i<416; i++) readback_data_var |= readback_array[i]; + readback_data = readback_data_var; + end + + assign cpuif_rd_ack = readback_done; + assign cpuif_rd_data = readback_data; + assign cpuif_rd_err = readback_err; + +`CALIPTRA_ASSERT_KNOWN(ERR_HWIF_IN, hwif_in, clk, !hwif_in.hard_reset_b) + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/pv_reg_pkg.sv b/designs/Caliptra/src/caliptra-rtl/pv_reg_pkg.sv new file mode 100644 index 0000000..9ce3d28 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/pv_reg_pkg.sv @@ -0,0 +1,83 @@ +// Generated by PeakRDL-regblock - A free and open-source SystemVerilog generator +// https://github.com/SystemRDL/PeakRDL-regblock + +package pv_reg_pkg; + + localparam PV_REG_DATA_WIDTH = 32; + localparam PV_REG_MIN_ADDR_WIDTH = 12; + + typedef struct packed{ + logic swwel; + } pv_reg__pvCtrl__lock__in_t; + + typedef struct packed{ + logic swwel; + } pv_reg__pvCtrl__clear__in_t; + + typedef struct packed{ + logic hwclr; + } pv_reg__pvCtrl__rsvd0__in_t; + + typedef struct packed{ + pv_reg__pvCtrl__lock__in_t lock; + pv_reg__pvCtrl__clear__in_t clear; + pv_reg__pvCtrl__rsvd0__in_t rsvd0; + } pv_reg__pvCtrl__in_t; + + typedef struct packed{ + logic [31:0] next; + logic we; + logic hwclr; + } pv_reg__pcr_w32__in_t; + + typedef struct packed{ + pv_reg__pcr_w32__in_t data; + } pv_reg__pcrReg__in_t; + + typedef struct packed{ + logic reset_b; + logic core_only_rst_b; + logic hard_reset_b; + pv_reg__pvCtrl__in_t [32-1:0]PCR_CTRL; + pv_reg__pcrReg__in_t [32-1:0][12-1:0]PCR_ENTRY; + } pv_reg__in_t; + + typedef struct packed{ + logic value; + } pv_reg__pvCtrl__lock__out_t; + + typedef struct packed{ + logic value; + } pv_reg__pvCtrl__clear__out_t; + + typedef struct packed{ + logic value; + } pv_reg__pvCtrl__rsvd0__out_t; + + typedef struct packed{ + logic [4:0] value; + } pv_reg__pvCtrl__rsvd1__out_t; + + typedef struct packed{ + pv_reg__pvCtrl__lock__out_t lock; + pv_reg__pvCtrl__clear__out_t clear; + pv_reg__pvCtrl__rsvd0__out_t rsvd0; + pv_reg__pvCtrl__rsvd1__out_t rsvd1; + } pv_reg__pvCtrl__out_t; + + typedef struct packed{ + logic [31:0] value; + } pv_reg__pcr_w32__out_t; + + typedef struct packed{ + pv_reg__pcr_w32__out_t data; + } pv_reg__pcrReg__out_t; + + typedef struct packed{ + pv_reg__pvCtrl__out_t [32-1:0]PCR_CTRL; + pv_reg__pcrReg__out_t [32-1:0][12-1:0]PCR_ENTRY; + } pv_reg__out_t; + + localparam PV_REG_ADDR_WIDTH = 32'd12; + +endpackage \ No newline at end of file diff --git a/designs/Caliptra/src/caliptra-rtl/rvjtag_tap.v b/designs/Caliptra/src/caliptra-rtl/rvjtag_tap.v new file mode 100644 index 0000000..7db1b90 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/rvjtag_tap.v @@ -0,0 +1,216 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2019 Western Digital Corporation or it's affiliates. +// +// 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 + +module rvjtag_tap #( +parameter AWIDTH = 7 +) +( +input trst, +input tck, +input tms, +input tdi, +output reg tdo, +output tdoEnable, + +output [31:0] wr_data, +output [AWIDTH-1:0] wr_addr, +output wr_en, +output rd_en, + +input [31:0] rd_data, +/*pragma coverage off*/ +input [1:0] rd_status, +/*pragma coverage on*/ + +output reg dmi_reset, +output reg dmi_hard_reset, + +/*pragma coverage off*/ +input [2:0] idle, +input [1:0] dmi_stat, +input [3:0] version +/*pragma coverage on*/ +); + +localparam USER_DR_LENGTH = AWIDTH + 34; + + +reg [USER_DR_LENGTH-1:0] sr, nsr, dr; + +/////////////////////////////////////////////////////// +// Tap controller +/////////////////////////////////////////////////////// +logic[3:0] state, nstate; +logic [4:0] ir; +wire jtag_reset; +wire shift_dr; +wire pause_dr; +wire update_dr; +wire capture_dr; +wire shift_ir; +wire pause_ir ; +wire update_ir ; +wire capture_ir; +wire[1:0] dr_en; +wire [5:0] abits; + +assign abits = AWIDTH[5:0]; + + +localparam TEST_LOGIC_RESET_STATE = 0; +localparam RUN_TEST_IDLE_STATE = 1; +localparam SELECT_DR_SCAN_STATE = 2; +localparam CAPTURE_DR_STATE = 3; +localparam SHIFT_DR_STATE = 4; +localparam EXIT1_DR_STATE = 5; +localparam PAUSE_DR_STATE = 6; +localparam EXIT2_DR_STATE = 7; +localparam UPDATE_DR_STATE = 8; +localparam SELECT_IR_SCAN_STATE = 9; +localparam CAPTURE_IR_STATE = 10; +localparam SHIFT_IR_STATE = 11; +localparam EXIT1_IR_STATE = 12; +localparam PAUSE_IR_STATE = 13; +localparam EXIT2_IR_STATE = 14; +localparam UPDATE_IR_STATE = 15; + +always_comb begin + nstate = state; + case(state) + TEST_LOGIC_RESET_STATE: nstate = tms ? TEST_LOGIC_RESET_STATE : RUN_TEST_IDLE_STATE; + RUN_TEST_IDLE_STATE: nstate = tms ? SELECT_DR_SCAN_STATE : RUN_TEST_IDLE_STATE; + SELECT_DR_SCAN_STATE: nstate = tms ? SELECT_IR_SCAN_STATE : CAPTURE_DR_STATE; + CAPTURE_DR_STATE: nstate = tms ? EXIT1_DR_STATE : SHIFT_DR_STATE; + SHIFT_DR_STATE: nstate = tms ? EXIT1_DR_STATE : SHIFT_DR_STATE; + EXIT1_DR_STATE: nstate = tms ? UPDATE_DR_STATE : PAUSE_DR_STATE; + PAUSE_DR_STATE: nstate = tms ? EXIT2_DR_STATE : PAUSE_DR_STATE; + EXIT2_DR_STATE: nstate = tms ? UPDATE_DR_STATE : SHIFT_DR_STATE; + UPDATE_DR_STATE: nstate = tms ? SELECT_DR_SCAN_STATE : RUN_TEST_IDLE_STATE; + SELECT_IR_SCAN_STATE: nstate = tms ? TEST_LOGIC_RESET_STATE : CAPTURE_IR_STATE; + CAPTURE_IR_STATE: nstate = tms ? EXIT1_IR_STATE : SHIFT_IR_STATE; + SHIFT_IR_STATE: nstate = tms ? EXIT1_IR_STATE : SHIFT_IR_STATE; + EXIT1_IR_STATE: nstate = tms ? UPDATE_IR_STATE : PAUSE_IR_STATE; + PAUSE_IR_STATE: nstate = tms ? EXIT2_IR_STATE : PAUSE_IR_STATE; + EXIT2_IR_STATE: nstate = tms ? UPDATE_IR_STATE : SHIFT_IR_STATE; + UPDATE_IR_STATE: nstate = tms ? SELECT_DR_SCAN_STATE : RUN_TEST_IDLE_STATE; + default: nstate = TEST_LOGIC_RESET_STATE; + endcase +end + +always @ (posedge tck or negedge trst) begin + if(!trst) state <= TEST_LOGIC_RESET_STATE; + else state <= nstate; +end + +assign jtag_reset = state == TEST_LOGIC_RESET_STATE; +assign shift_dr = state == SHIFT_DR_STATE; +assign pause_dr = state == PAUSE_DR_STATE; +assign update_dr = state == UPDATE_DR_STATE; +assign capture_dr = state == CAPTURE_DR_STATE; +assign shift_ir = state == SHIFT_IR_STATE; +assign pause_ir = state == PAUSE_IR_STATE; +assign update_ir = state == UPDATE_IR_STATE; +assign capture_ir = state == CAPTURE_IR_STATE; + +assign tdoEnable = shift_dr | shift_ir; + +/////////////////////////////////////////////////////// +// IR register +/////////////////////////////////////////////////////// + +always @ (negedge tck or negedge trst) begin + if (!trst) ir <= 5'b1; + else begin + if (jtag_reset) ir <= 5'b1; + else if (update_ir) ir <= (sr[4:0] == '0) ? 5'h1f :sr[4:0]; + end +end + + +assign dr_en[0] = ir == 5'b10000; +assign dr_en[1] = ir == 5'b10001; + +/////////////////////////////////////////////////////// +// Shift register +/////////////////////////////////////////////////////// +always @ (posedge tck or negedge trst) begin + if(!trst)begin + sr <= '0; + end + else begin + sr <= nsr; + end +end + +// SR next value +always_comb begin + nsr = sr; + case(1) + shift_dr: begin + case(1) + dr_en[1]: nsr = {tdi, sr[USER_DR_LENGTH-1:1]}; + dr_en[0]: nsr = {{USER_DR_LENGTH-32{1'b0}},tdi, sr[31:1]}; + default: nsr = {{USER_DR_LENGTH-1{1'b0}},tdi}; // bypass + endcase + end + capture_dr: begin + nsr[0] = 1'b0; + case(1) + dr_en[0]: nsr = {{USER_DR_LENGTH-15{1'b0}}, idle, dmi_stat, abits, version}; + dr_en[1]: nsr = {{AWIDTH{1'b0}}, rd_data, rd_status}; + endcase + end + shift_ir: nsr = {{USER_DR_LENGTH-5{1'b0}},tdi, sr[4:1]}; + capture_ir: nsr = {{USER_DR_LENGTH-1{1'b0}},1'b1}; + endcase +end + +// TDO retiming +always @ (negedge tck ) tdo <= sr[0]; + +// DMI CS register +always @ (posedge tck or negedge trst) begin + if(!trst) begin + dmi_hard_reset <= 1'b0; + dmi_reset <= 1'b0; + end + else if (update_dr & dr_en[0]) begin + dmi_hard_reset <= sr[17]; + dmi_reset <= sr[16]; + end + else begin + dmi_hard_reset <= 1'b0; + dmi_reset <= 1'b0; + end +end + +// DR register +always @ (posedge tck or negedge trst) begin + if(!trst) + dr <= '0; + else begin + if (update_dr & dr_en[1]) + dr <= sr; + else + dr <= {dr[USER_DR_LENGTH-1:2],2'b0}; + end +end + +assign {wr_addr, wr_data, wr_en, rd_en} = dr; + + + + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/sha256.sv b/designs/Caliptra/src/caliptra-rtl/sha256.sv new file mode 100644 index 0000000..20b06bf --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/sha256.sv @@ -0,0 +1,446 @@ +//====================================================================== +// +// Updated by Caliptra team to modify data access width +// +// sha256.sv +// -------- +// Top level wrapper for the SHA-256 hash function providing +// a simple memory like interface with 32 bit data access. +// +// +// Author: Joachim Strombergson +// Copyright (c) 2013, 201, Secworks Sweden AB +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or +// without modification, are permitted provided that the following +// conditions are met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in +// the documentation and/or other materials provided with the +// distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +//====================================================================== + +module sha256 + import sha256_reg_pkg::*; + import sha256_params_pkg::*; + #( + parameter ADDR_WIDTH = 32, + parameter DATA_WIDTH = 32 + )( + // Clock and reset. + input wire clk, + input wire reset_n, + input wire cptra_pwrgood, + + // Control. + input wire cs, + input wire we, + + // Data ports. + input wire [ADDR_WIDTH-1 : 0] address, + input wire [DATA_WIDTH-1 : 0] write_data, + output wire [DATA_WIDTH-1 : 0] read_data, + output wire err, + + + // Interrupts + output wire error_intr, + output wire notif_intr, + input logic debugUnlock_or_scan_mode_switch + ); + + //---------------------------------------------------------------- + // Internal constant and parameter definitions. + //---------------------------------------------------------------- + // `include "sha256_param.sv" + + //---------------------------------------------------------------- + // Registers including update variables and write enable. + //---------------------------------------------------------------- + reg init_reg; + reg next_reg; + reg mode_reg; + reg ready_reg; + reg zeroize_reg; + logic mode; + + localparam BLOCK_NO = 512 / DATA_WIDTH; + reg [DATA_WIDTH-1 : 0] block_reg [BLOCK_NO-1 : 0]; + + reg [0 : 7][31 : 0] digest_reg; + reg [0 : 7][31 : 0] get_mask; + reg digest_valid_reg; + + // Interrupts + sha256_reg__in_t hwif_in; + sha256_reg__out_t hwif_out; + logic read_error, write_error; + + //---------------------------------------------------------------- + // Wires. + //---------------------------------------------------------------- + wire core_ready; + logic [511 : 0] core_block; + wire [0:7][31:0] core_digest; //Intentionally reverse ordered to prepare block input in wntz mode + wire core_digest_valid; + logic core_digest_valid_reg; + + logic ready_flag; + logic ready_flag_reg; + logic valid_flag; + logic valid_flag_reg; + + + logic wntz_enable; + logic wntz_j_inc; + logic [7:0] wntz_j_init, wntz_j_reg; + logic wntz_busy; // to regiser + logic wntz_mode; // from registers + logic wntz_n_mode, wntz_n_mode_reg; + logic [3:0] wntz_w, wntz_w_reg; + logic wntz_w_invalid, wntz_mode_invalid, wntz_j_invalid; + logic invalid_sha_op; + logic core_init, core_next, core_mode; + logic wntz_init; + logic wntz_init_reg; + logic wntz_blk_done; + logic [7:0] wntz_iter, wntz_iter_reg; + logic [175: 0] wntz_prefix; + + typedef enum logic [1:0] {WNTZ_IDLE, WNTZ_1ST, WNTZ_OTHERS} wntz_fsm_t; + wntz_fsm_t wntz_fsm, wntz_fsm_next; + + + //---------------------------------------------------------------- + // Concurrent connectivity for ports etc. + //---------------------------------------------------------------- + + always_comb begin + if (wntz_busy) begin + core_block = wntz_n_mode_reg ? + //SHA256 + {wntz_prefix, wntz_j_reg, + digest_reg[0], digest_reg[1], + digest_reg[2], digest_reg[3], + digest_reg[4], digest_reg[5], + digest_reg[6], digest_reg[7], + 8'h80, // Padding + 64'h01b8} // L = 440bits per SHA256 padding + : //SHA192 + {wntz_prefix, wntz_j_reg, + digest_reg[0], digest_reg[1], + digest_reg[2], digest_reg[3], + digest_reg[4], digest_reg[5], + 8'h80, 64'h0, // Padding + 64'h0178}; // L = 376bits per SHA256 padding + + core_init = wntz_init_reg; + core_next = 1'b0; + core_mode = 1'b1; //always SHA256 for Winternitz. mode_reg set to 0 will trig error. Digest is truncated based on wntz_n_mode + end else begin + core_block = {block_reg[00], block_reg[01], block_reg[02], block_reg[03], + block_reg[04], block_reg[05], block_reg[06], block_reg[07], + block_reg[08], block_reg[09], block_reg[10], block_reg[11], + block_reg[12], block_reg[13], block_reg[14], block_reg[15]}; + core_init = init_reg; + core_next = next_reg; + core_mode = mode; + end + end // always_comb + + assign err = read_error | write_error; + + //---------------------------------------------------------------- + // core instantiation. + //---------------------------------------------------------------- + sha256_core core( + .clk(clk), + .reset_n(reset_n), + .zeroize(zeroize_reg), + + .init_cmd(core_init), + .next_cmd(core_next), + .mode(core_mode), + + .block_msg(core_block), + + .ready(core_ready), + + .digest(core_digest), + .digest_valid(core_digest_valid) + ); + + //---------------------------------------------------------------- + assign wntz_busy = (wntz_fsm != WNTZ_IDLE); + assign wntz_blk_done = core_digest_valid & ~core_digest_valid_reg; + assign wntz_w_invalid = wntz_busy & ~(wntz_w_reg inside {'h1, 'h2, 'h4, 'h8}); + assign wntz_mode_invalid = wntz_busy & ~mode_reg; + assign wntz_j_invalid = wntz_mode & (wntz_j_init > wntz_iter); + assign invalid_sha_op = init_reg & next_reg; //Trigger an error when init and next are high in the same cycle + + always_comb begin + unique case(wntz_w) + 4'h1: wntz_iter = 'd0; //2**w - 1 (-1) (1st iteration is considered separately) + 4'h2: wntz_iter = 'd2; + 4'h4: wntz_iter = 'd14; + 4'h8: wntz_iter = 'd254; + default: wntz_iter = 'd0; + endcase + end + + assign wntz_j_init = block_reg[5][15:8]; + + always_comb begin + wntz_init = 1'b0; + wntz_enable = 1'b0; + wntz_j_inc = 1'b0; + case (wntz_fsm) + WNTZ_IDLE: + begin + if (wntz_mode && init_reg && ready_reg && (wntz_j_init <= wntz_iter)) begin + wntz_fsm_next = WNTZ_1ST; + wntz_enable = 1'b1; + end else + wntz_fsm_next = WNTZ_IDLE; + end + + WNTZ_1ST: + begin + if (wntz_blk_done && (wntz_j_reg < wntz_iter_reg)) begin + wntz_fsm_next = WNTZ_OTHERS; + wntz_init = 1'b1; + wntz_j_inc = 1'b1; + end else if (wntz_blk_done) + wntz_fsm_next = WNTZ_IDLE; + else + wntz_fsm_next = WNTZ_1ST; + end + + WNTZ_OTHERS: + begin + if (wntz_blk_done && (wntz_j_reg < wntz_iter_reg)) begin + wntz_fsm_next = WNTZ_OTHERS; + wntz_init = 1'b1; + wntz_j_inc = 1'b1; + end else if (wntz_blk_done) + wntz_fsm_next = WNTZ_IDLE; + else + wntz_fsm_next = WNTZ_OTHERS; + end + + default: + wntz_fsm_next = WNTZ_IDLE; + + endcase + + end + + + always @ (posedge clk or negedge reset_n) begin + if (!reset_n) + wntz_fsm <= WNTZ_IDLE; + else if (zeroize_reg) + wntz_fsm <= WNTZ_IDLE; + else + wntz_fsm <= wntz_fsm_next; + end + + always @ (posedge clk or negedge reset_n) begin + if (!reset_n) begin + wntz_j_reg <= '0; + wntz_prefix <= '0; + wntz_n_mode_reg <= '0; + wntz_w_reg <= '0; + wntz_iter_reg <= '0; + end else if (zeroize_reg) begin + wntz_j_reg <= '0; + wntz_prefix <= '0; + wntz_n_mode_reg <= '0; + wntz_w_reg <= '0; + wntz_iter_reg <= '0; + end else begin + if (wntz_enable) begin + wntz_j_reg <= wntz_j_init; + wntz_prefix <= {block_reg[00], block_reg[01], block_reg[02], block_reg[03], // I: 16byte, q: 4bytes, i: 2bytes + block_reg[04], block_reg[05][31:16]}; + wntz_n_mode_reg <= wntz_n_mode; + wntz_w_reg <= wntz_w; + wntz_iter_reg <= wntz_iter; + end else if (wntz_j_inc) + wntz_j_reg <= wntz_j_reg + 1; + end + end + + always @ (posedge clk or negedge reset_n) begin + if (!reset_n) + wntz_init_reg <= 1'b0; + else if (zeroize_reg) + wntz_init_reg <= 1'b0; + else begin + if (wntz_init) + wntz_init_reg <= 1'b1; + else + wntz_init_reg <= 1'b0; + end + end + + + always @ (posedge clk or negedge reset_n) begin + if (!reset_n) + mode_reg <= '0; + else if (zeroize_reg) + mode_reg <= '0; + else begin + if (ready_reg) + mode_reg <= mode; + end + end + + //---------------------------------------------------------------- + // reg_update + // + // Update functionality for all registers in the core. + // All registers are positive edge triggered with asynchronous + // active low reset. All registers have write enable. + //---------------------------------------------------------------- + always @ (posedge clk or negedge reset_n) begin + if (!reset_n) begin + get_mask <= {8{32'hffff_ffff}}; + end + else if (wntz_busy) begin + unique case (wntz_n_mode_reg) + 0: get_mask <= {{6{32'hffff_ffff}}, {2{32'h0000_0000}}}; + default: get_mask <= {8{32'hffff_ffff}}; + endcase + end + else begin + unique case (mode_reg) + 0: get_mask <= {{7{32'hffff_ffff}}, {1{32'h0000_0000}}}; + default: get_mask <= {8{32'hffff_ffff}}; + endcase + end + end + + assign ready_flag = core_ready & ~wntz_busy; + assign ready_reg = ready_flag & ready_flag_reg; + assign valid_flag = core_digest_valid & ~wntz_busy; + assign digest_valid_reg = valid_flag & valid_flag_reg; + + always @ (posedge clk or negedge reset_n) + begin : reg_update + if (!reset_n) begin + ready_flag_reg <= '0; + digest_reg <= '0; + valid_flag_reg <= '0; + core_digest_valid_reg <= '0; + end + else if (zeroize_reg) begin + ready_flag_reg <= '0; + digest_reg <= '0; + valid_flag_reg <= '0; + core_digest_valid_reg <= '0; + end + else begin + ready_flag_reg <= ready_flag; + valid_flag_reg <= valid_flag; + core_digest_valid_reg <= core_digest_valid; + + if (core_digest_valid & ~digest_valid_reg) begin + digest_reg <= core_digest & get_mask; + end + end + end // reg_update + + + //register hw interface + always_comb begin + + hwif_in.SHA256_NAME[0].NAME.next = SHA256_CORE_NAME0; + hwif_in.SHA256_NAME[1].NAME.next = SHA256_CORE_NAME1; + + hwif_in.SHA256_VERSION[0].VERSION.next = SHA256_CORE_VERSION0; + hwif_in.SHA256_VERSION[1].VERSION.next = SHA256_CORE_VERSION1; + + init_reg = hwif_out.SHA256_CTRL.INIT.value; + next_reg = hwif_out.SHA256_CTRL.NEXT.value; + mode = hwif_out.SHA256_CTRL.MODE.value; + zeroize_reg = hwif_out.SHA256_CTRL.ZEROIZE.value || debugUnlock_or_scan_mode_switch; + wntz_mode = hwif_out.SHA256_CTRL.WNTZ_MODE.value; + wntz_n_mode = hwif_out.SHA256_CTRL.WNTZ_N_MODE.value; + wntz_w = hwif_out.SHA256_CTRL.WNTZ_W.value; + + hwif_in.SHA256_STATUS.READY.next = ready_reg; + hwif_in.SHA256_STATUS.VALID.next = digest_valid_reg; + hwif_in.SHA256_STATUS.WNTZ_BUSY.next = wntz_busy; + + for (int dword =0; dword < 8; dword++) begin +// hwif_in.SHA256_DIGEST[dword].DIGEST.next = digest_reg[7-dword]; + hwif_in.SHA256_DIGEST[dword].DIGEST.next = digest_reg[dword]; + hwif_in.SHA256_DIGEST[dword].DIGEST.hwclr = zeroize_reg; + end + + for (int dword=0; dword< BLOCK_NO; dword++) begin + block_reg[dword] = hwif_out.SHA256_BLOCK[dword].BLOCK.value; + hwif_in.SHA256_BLOCK[dword].BLOCK.hwclr = zeroize_reg; + end + + end + + // Register Block + sha256_reg i_sha256_reg ( + .clk(clk), + .rst(1'b0), + + .s_cpuif_req (cs), + .s_cpuif_req_is_wr (we), + .s_cpuif_addr (address[SHA256_REG_ADDR_WIDTH-1:0]), + .s_cpuif_wr_data (write_data), + .s_cpuif_wr_biten ('1), + .s_cpuif_req_stall_wr( ), + .s_cpuif_req_stall_rd( ), + .s_cpuif_rd_ack ( ), + .s_cpuif_rd_err (read_error), + .s_cpuif_rd_data (read_data), + .s_cpuif_wr_ack ( ), + .s_cpuif_wr_err (write_error), + + .hwif_in (hwif_in ), + .hwif_out(hwif_out) + ); + + //interrupt register hw interface + assign hwif_in.sha256_ready = ready_reg; + assign hwif_in.reset_b = reset_n; + assign hwif_in.error_reset_b = cptra_pwrgood; + assign hwif_in.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.hwset = (~wntz_busy & core_digest_valid & ~digest_valid_reg); + assign hwif_in.intr_block_rf.error_internal_intr_r.error0_sts.hwset = wntz_w_invalid | wntz_mode_invalid | wntz_j_invalid; + assign hwif_in.intr_block_rf.error_internal_intr_r.error1_sts.hwset = invalid_sha_op; + assign hwif_in.intr_block_rf.error_internal_intr_r.error2_sts.hwset = 1'b0; + assign hwif_in.intr_block_rf.error_internal_intr_r.error3_sts.hwset = 1'b0; + + assign error_intr = hwif_out.intr_block_rf.error_global_intr_r.intr; + assign notif_intr = hwif_out.intr_block_rf.notif_global_intr_r.intr; +endmodule // sha256 + +//====================================================================== +// EOF sha256.v +//====================================================================== diff --git a/designs/Caliptra/src/caliptra-rtl/sha256_core.v b/designs/Caliptra/src/caliptra-rtl/sha256_core.v new file mode 100644 index 0000000..6f24ccf --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/sha256_core.v @@ -0,0 +1,582 @@ +//====================================================================== +// +// sha256_core.v +// ------------- +// Verilog 2001 implementation of the SHA-256 hash function. +// This is the internal core with wide interfaces. +// +// +// Author: Joachim Strombergson +// Copyright (c) 2013, Secworks Sweden AB +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or +// without modification, are permitted provided that the following +// conditions are met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in +// the documentation and/or other materials provided with the +// distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +//====================================================================== + +module sha256_core( + // Clock and reset. + input wire clk, + input wire reset_n, + input wire zeroize, + + // Control. + input wire init_cmd, + input wire next_cmd, + input wire mode, + + // Data ports. + input wire [511 : 0] block_msg, + + output wire ready, + output wire [255 : 0] digest, + output wire digest_valid + ); + + + //---------------------------------------------------------------- + // Internal constant and parameter definitions. + //---------------------------------------------------------------- + localparam SHA224_H0_0 = 32'hc1059ed8; + localparam SHA224_H0_1 = 32'h367cd507; + localparam SHA224_H0_2 = 32'h3070dd17; + localparam SHA224_H0_3 = 32'hf70e5939; + localparam SHA224_H0_4 = 32'hffc00b31; + localparam SHA224_H0_5 = 32'h68581511; + localparam SHA224_H0_6 = 32'h64f98fa7; + localparam SHA224_H0_7 = 32'hbefa4fa4; + + localparam SHA256_H0_0 = 32'h6a09e667; + localparam SHA256_H0_1 = 32'hbb67ae85; + localparam SHA256_H0_2 = 32'h3c6ef372; + localparam SHA256_H0_3 = 32'ha54ff53a; + localparam SHA256_H0_4 = 32'h510e527f; + localparam SHA256_H0_5 = 32'h9b05688c; + localparam SHA256_H0_6 = 32'h1f83d9ab; + localparam SHA256_H0_7 = 32'h5be0cd19; + + localparam SHA256_ROUNDS = 63; + + localparam [1:0] CTRL_IDLE = 0; + localparam [1:0] CTRL_ROUNDS = 1; + localparam [1:0] CTRL_DONE = 2; + + + //---------------------------------------------------------------- + // Registers including update variables and write enable. + //---------------------------------------------------------------- + reg [31 : 0] a_reg; + reg [31 : 0] a_new; + reg [31 : 0] b_reg; + reg [31 : 0] b_new; + reg [31 : 0] c_reg; + reg [31 : 0] c_new; + reg [31 : 0] d_reg; + reg [31 : 0] d_new; + reg [31 : 0] e_reg; + reg [31 : 0] e_new; + reg [31 : 0] f_reg; + reg [31 : 0] f_new; + reg [31 : 0] g_reg; + reg [31 : 0] g_new; + reg [31 : 0] h_reg; + reg [31 : 0] h_new; + reg a_h_we; + + reg [31 : 0] H0_reg; + reg [31 : 0] H0_new; + reg [31 : 0] H1_reg; + reg [31 : 0] H1_new; + reg [31 : 0] H2_reg; + reg [31 : 0] H2_new; + reg [31 : 0] H3_reg; + reg [31 : 0] H3_new; + reg [31 : 0] H4_reg; + reg [31 : 0] H4_new; + reg [31 : 0] H5_reg; + reg [31 : 0] H5_new; + reg [31 : 0] H6_reg; + reg [31 : 0] H6_new; + reg [31 : 0] H7_reg; + reg [31 : 0] H7_new; + reg H_we; + + reg [5 : 0] t_ctr_reg; + reg [5 : 0] t_ctr_new; + reg t_ctr_we; + reg t_ctr_inc; + reg t_ctr_rst; + + reg digest_valid_reg; + reg digest_valid_new; + reg digest_valid_we; + + reg [1 : 0] sha256_ctrl_reg; + reg [1 : 0] sha256_ctrl_new; + reg sha256_ctrl_we; + + + //---------------------------------------------------------------- + // Wires. + //---------------------------------------------------------------- + reg digest_init; + reg digest_update; + + reg state_init; + reg state_update; + + reg first_block; + + reg ready_flag; + + reg [31 : 0] t1; + reg [31 : 0] t2; + + wire [31 : 0] k_data; + + reg w_init; + reg w_next; + wire [31 : 0] w_data; + + + //---------------------------------------------------------------- + // Module instantiantions. + //---------------------------------------------------------------- + sha256_k_constants k_constants_inst( + .round(t_ctr_reg), + .K_val(k_data) + ); + + + sha256_w_mem w_mem_inst( + .clk(clk), + .reset_n(reset_n), + .zeroize(zeroize), + + .block_msg(block_msg), + + .init_cmd(w_init), + .next_cmd(w_next), + .w_val(w_data) + ); + + + //---------------------------------------------------------------- + // Concurrent connectivity for ports etc. + //---------------------------------------------------------------- + assign ready = ready_flag; + + assign digest = {H0_reg, H1_reg, H2_reg, H3_reg, + H4_reg, H5_reg, H6_reg, H7_reg}; + + assign digest_valid = digest_valid_reg; + + + //---------------------------------------------------------------- + // reg_update + // Update functionality for all registers in the core. + // All registers are positive edge triggered with asynchronous + // active low reset. All registers have write enable. + //---------------------------------------------------------------- + always @ (posedge clk or negedge reset_n) + begin : reg_update + if (!reset_n) + begin + a_reg <= 32'h0; + b_reg <= 32'h0; + c_reg <= 32'h0; + d_reg <= 32'h0; + e_reg <= 32'h0; + f_reg <= 32'h0; + g_reg <= 32'h0; + h_reg <= 32'h0; + H0_reg <= 32'h0; + H1_reg <= 32'h0; + H2_reg <= 32'h0; + H3_reg <= 32'h0; + H4_reg <= 32'h0; + H5_reg <= 32'h0; + H6_reg <= 32'h0; + H7_reg <= 32'h0; + digest_valid_reg <= 0; + t_ctr_reg <= 6'h0; + sha256_ctrl_reg <= CTRL_IDLE; + end + else if (zeroize) + begin + a_reg <= 32'h0; + b_reg <= 32'h0; + c_reg <= 32'h0; + d_reg <= 32'h0; + e_reg <= 32'h0; + f_reg <= 32'h0; + g_reg <= 32'h0; + h_reg <= 32'h0; + H0_reg <= 32'h0; + H1_reg <= 32'h0; + H2_reg <= 32'h0; + H3_reg <= 32'h0; + H4_reg <= 32'h0; + H5_reg <= 32'h0; + H6_reg <= 32'h0; + H7_reg <= 32'h0; + digest_valid_reg <= 0; + t_ctr_reg <= 6'h0; + sha256_ctrl_reg <= CTRL_IDLE; + end + else + begin + + if (a_h_we) + begin + a_reg <= a_new; + b_reg <= b_new; + c_reg <= c_new; + d_reg <= d_new; + e_reg <= e_new; + f_reg <= f_new; + g_reg <= g_new; + h_reg <= h_new; + end + + if (H_we) + begin + H0_reg <= H0_new; + H1_reg <= H1_new; + H2_reg <= H2_new; + H3_reg <= H3_new; + H4_reg <= H4_new; + H5_reg <= H5_new; + H6_reg <= H6_new; + H7_reg <= H7_new; + end + + if (t_ctr_we) + t_ctr_reg <= t_ctr_new; + + if (digest_valid_we) + digest_valid_reg <= digest_valid_new; + + if (sha256_ctrl_we) + sha256_ctrl_reg <= sha256_ctrl_new; + end + end // reg_update + + + //---------------------------------------------------------------- + // digest_logic + // + // The logic needed to init as well as update the digest. + //---------------------------------------------------------------- + always @* + begin : digest_logic + H0_new = 32'h0; + H1_new = 32'h0; + H2_new = 32'h0; + H3_new = 32'h0; + H4_new = 32'h0; + H5_new = 32'h0; + H6_new = 32'h0; + H7_new = 32'h0; + H_we = 0; + + if (digest_init) + begin + H_we = 1; + if (mode) + begin + H0_new = SHA256_H0_0; + H1_new = SHA256_H0_1; + H2_new = SHA256_H0_2; + H3_new = SHA256_H0_3; + H4_new = SHA256_H0_4; + H5_new = SHA256_H0_5; + H6_new = SHA256_H0_6; + H7_new = SHA256_H0_7; + end + else + begin + H0_new = SHA224_H0_0; + H1_new = SHA224_H0_1; + H2_new = SHA224_H0_2; + H3_new = SHA224_H0_3; + H4_new = SHA224_H0_4; + H5_new = SHA224_H0_5; + H6_new = SHA224_H0_6; + H7_new = SHA224_H0_7; + end + end + + if (digest_update) + begin + H0_new = H0_reg + a_reg; + H1_new = H1_reg + b_reg; + H2_new = H2_reg + c_reg; + H3_new = H3_reg + d_reg; + H4_new = H4_reg + e_reg; + H5_new = H5_reg + f_reg; + H6_new = H6_reg + g_reg; + H7_new = H7_reg + h_reg; + H_we = 1; + end + end // digest_logic + + + //---------------------------------------------------------------- + // t1_logic + // + // The logic for the T1 function. + //---------------------------------------------------------------- + always @* + begin : t1_logic + reg [31 : 0] sum1; + reg [31 : 0] ch; + + sum1 = {e_reg[5 : 0], e_reg[31 : 6]} ^ + {e_reg[10 : 0], e_reg[31 : 11]} ^ + {e_reg[24 : 0], e_reg[31 : 25]}; + + ch = (e_reg & f_reg) ^ ((~e_reg) & g_reg); + + t1 = h_reg + sum1 + ch + w_data + k_data; + end // t1_logic + + + //---------------------------------------------------------------- + // t2_logic + // + // The logic for the T2 function + //---------------------------------------------------------------- + always @* + begin : t2_logic + reg [31 : 0] sum0; + reg [31 : 0] maj; + + sum0 = {a_reg[1 : 0], a_reg[31 : 2]} ^ + {a_reg[12 : 0], a_reg[31 : 13]} ^ + {a_reg[21 : 0], a_reg[31 : 22]}; + + maj = (a_reg & b_reg) ^ (a_reg & c_reg) ^ (b_reg & c_reg); + + t2 = sum0 + maj; + end // t2_logic + + + //---------------------------------------------------------------- + // state_logicerr + // + // The logic needed to init as well as update the state during + // round processing. + //---------------------------------------------------------------- + always @* + begin : state_logic + a_new = 32'h0; + b_new = 32'h0; + c_new = 32'h0; + d_new = 32'h0; + e_new = 32'h0; + f_new = 32'h0; + g_new = 32'h0; + h_new = 32'h0; + a_h_we = 0; + + if (state_init) + begin + a_h_we = 1; + if (first_block) + begin + if (mode) + begin + a_new = SHA256_H0_0; + b_new = SHA256_H0_1; + c_new = SHA256_H0_2; + d_new = SHA256_H0_3; + e_new = SHA256_H0_4; + f_new = SHA256_H0_5; + g_new = SHA256_H0_6; + h_new = SHA256_H0_7; + end + else + begin + a_new = SHA224_H0_0; + b_new = SHA224_H0_1; + c_new = SHA224_H0_2; + d_new = SHA224_H0_3; + e_new = SHA224_H0_4; + f_new = SHA224_H0_5; + g_new = SHA224_H0_6; + h_new = SHA224_H0_7; + end + end + else + begin + a_new = H0_reg; + b_new = H1_reg; + c_new = H2_reg; + d_new = H3_reg; + e_new = H4_reg; + f_new = H5_reg; + g_new = H6_reg; + h_new = H7_reg; + end + end + + if (state_update) + begin + a_new = t1 + t2; + b_new = a_reg; + c_new = b_reg; + d_new = c_reg; + e_new = d_reg + t1; + f_new = e_reg; + g_new = f_reg; + h_new = g_reg; + a_h_we = 1; + end + end // state_logic + + + //---------------------------------------------------------------- + // t_ctr + // + // Update logic for the round counter, a monotonically + // increasing counter with reset. + //---------------------------------------------------------------- + always @* + begin : t_ctr + t_ctr_new = 0; + t_ctr_we = 0; + + if (t_ctr_rst) + begin + t_ctr_new = 0; + t_ctr_we = 1; + end + + if (t_ctr_inc) + begin + t_ctr_new = t_ctr_reg + 1'b1; + t_ctr_we = 1; + end + end // t_ctr + + + //---------------------------------------------------------------- + // sha256_ctrl_fsm + // + // Logic for the state machine controlling the core behaviour. + //---------------------------------------------------------------- + always @* + begin : sha256_ctrl_fsm + digest_init = 0; + digest_update = 0; + + state_init = 0; + state_update = 0; + + first_block = 0; + ready_flag = 0; + + w_init = 0; + w_next = 0; + + t_ctr_inc = 0; + t_ctr_rst = 0; + + digest_valid_new = 0; + digest_valid_we = 0; + + sha256_ctrl_new = CTRL_IDLE; + sha256_ctrl_we = 0; + + + case (sha256_ctrl_reg) + CTRL_IDLE: + begin + ready_flag = 1; + + if (init_cmd) + begin + digest_init = 1; + w_init = 1; + state_init = 1; + first_block = 1; + t_ctr_rst = 1; + digest_valid_new = 0; + digest_valid_we = 1; + sha256_ctrl_new = CTRL_ROUNDS; + sha256_ctrl_we = 1; + end + + if (next_cmd) + begin + t_ctr_rst = 1; + w_init = 1; + state_init = 1; + digest_valid_new = 0; + digest_valid_we = 1; + sha256_ctrl_new = CTRL_ROUNDS; + sha256_ctrl_we = 1; + end + end + + + CTRL_ROUNDS: + begin + w_next = 1; + state_update = 1; + t_ctr_inc = 1; + + if (t_ctr_reg == SHA256_ROUNDS) + begin + sha256_ctrl_new = CTRL_DONE; + sha256_ctrl_we = 1; + end + end + + + CTRL_DONE: + begin + digest_update = 1; + digest_valid_new = 1; + digest_valid_we = 1; + + sha256_ctrl_new = CTRL_IDLE; + sha256_ctrl_we = 1; + end + default: + begin + sha256_ctrl_new = sha256_ctrl_reg; + sha256_ctrl_we = 0; + end + endcase // case (sha256_ctrl_reg) + end // sha256_ctrl_fsm + +endmodule // sha256_core + +//====================================================================== +// EOF sha256_core.v +//====================================================================== diff --git a/designs/Caliptra/src/caliptra-rtl/sha256_ctrl.sv b/designs/Caliptra/src/caliptra-rtl/sha256_ctrl.sv new file mode 100644 index 0000000..970770f --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/sha256_ctrl.sv @@ -0,0 +1,123 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +// +//====================================================================== +// +// sha256_ctrl.sv +// -------- +// SHA256 controller for the AHb_lite interface. +// +// +//====================================================================== + +module sha256_ctrl #( + parameter AHB_DATA_WIDTH = 32, + parameter AHB_ADDR_WIDTH = 32 +) +( + // Clock and reset. + input wire clk, + input wire reset_n, + input wire cptra_pwrgood, + + // from SLAVES PORT + input logic [AHB_ADDR_WIDTH-1:0] haddr_i, + input logic [AHB_DATA_WIDTH-1:0] hwdata_i, + input logic hsel_i, + input logic hwrite_i, + input logic hready_i, + input logic [1:0] htrans_i, + input logic [2:0] hsize_i, + + output logic hresp_o, + output logic hreadyout_o, + output logic [AHB_DATA_WIDTH-1:0] hrdata_o, + + // Interrupt + output logic error_intr, + output logic notif_intr, + input logic debugUnlock_or_scan_mode_switch +); + + //---------------------------------------------------------------- + // sha256 + //---------------------------------------------------------------- + logic sha256_cs; + logic sha256_we; + logic [AHB_ADDR_WIDTH-1 : 0] sha256_address; + logic [31 : 0] sha256_write_data; + logic [31 : 0] sha256_read_data; + logic sha256_err; + + sha256 #( + .ADDR_WIDTH(AHB_ADDR_WIDTH), + .DATA_WIDTH(32) + ) sha256_inst( + .clk(clk), + .reset_n(reset_n), + .cptra_pwrgood(cptra_pwrgood), + .cs(sha256_cs), + .we(sha256_we), + .address(sha256_address), + .write_data(sha256_write_data), + .read_data(sha256_read_data), + .err(sha256_err), + .error_intr(error_intr), + .notif_intr(notif_intr), + .debugUnlock_or_scan_mode_switch(debugUnlock_or_scan_mode_switch) + ); + + + //---------------------------------------------------------------- + // AHB Slave node + //---------------------------------------------------------------- + + //instantiate ahb lite module + ahb_slv_sif #( + .AHB_ADDR_WIDTH(AHB_ADDR_WIDTH), + .AHB_DATA_WIDTH(AHB_DATA_WIDTH), + .CLIENT_DATA_WIDTH(32) + ) ahb_slv_sif_uut + ( + //AMBA AHB Lite INF + .hclk(clk), + .hreset_n(reset_n), + .haddr_i(haddr_i), + .hwdata_i(hwdata_i), + .hsel_i(hsel_i), + .hwrite_i(hwrite_i), + .hready_i(hready_i), + .htrans_i(htrans_i), + .hsize_i(hsize_i), + + .hresp_o(hresp_o), + .hreadyout_o(hreadyout_o), + .hrdata_o(hrdata_o), + + //COMPONENT INF + .dv(sha256_cs), + .hld(1'b0), //no holds from sha256 + .err(1'b0), + .write(sha256_we), + .wdata(sha256_write_data), + .addr(sha256_address), + + .rdata(sha256_read_data) + ); + +endmodule //sha256_ctrl + +//====================================================================== +// EOF sha256_ctrl.sv +//====================================================================== diff --git a/designs/Caliptra/src/caliptra-rtl/sha256_ctrl_cov_bind.sv b/designs/Caliptra/src/caliptra-rtl/sha256_ctrl_cov_bind.sv new file mode 100644 index 0000000..77ffe59 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/sha256_ctrl_cov_bind.sv @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. + + +module sha256_ctrl_cov_bind; + `ifdef FCOV + bind sha256_ctrl sha256_ctrl_cov_if i_sha256_ctrl_cov_if(.*); + `endif +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/sha256_ctrl_cov_if.sv b/designs/Caliptra/src/caliptra-rtl/sha256_ctrl_cov_if.sv new file mode 100644 index 0000000..84669a9 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/sha256_ctrl_cov_if.sv @@ -0,0 +1,100 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. + +`ifndef VERILATOR + +interface sha256_ctrl_cov_if + ( + input logic clk, + input logic reset_n, + input logic cptra_pwrgood + +); + + logic init; + logic next; + logic mode; + logic zeroize; + logic ready; + logic valid; + logic wntz_mode; + logic [3:0] wntz_w; + logic wntz_n_mode; + + + logic [1 : 0] hash_cmd; + + logic wntz_w_invalid; + logic wntz_mode_invalid; + logic wntz_j_invalid; + + assign init = sha256_ctrl.sha256_inst.init_reg; + assign next = sha256_ctrl.sha256_inst.next_reg; + assign mode = sha256_ctrl.sha256_inst.mode_reg; + assign zeroize = sha256_ctrl.sha256_inst.zeroize_reg; + assign ready = sha256_ctrl.sha256_inst.ready_reg; + assign valid = sha256_ctrl.sha256_inst.digest_valid_reg; + + assign wntz_mode = sha256_ctrl.sha256_inst.wntz_mode; + assign wntz_w = sha256_ctrl.sha256_inst.wntz_w; + assign wntz_n_mode = sha256_ctrl.sha256_inst.wntz_n_mode; + + assign hash_cmd = {next, init}; + + assign wntz_w_invalid = sha256_ctrl.sha256_inst.wntz_w_invalid; + assign wntz_mode_invalid = sha256_ctrl.sha256_inst.wntz_mode_invalid; + assign wntz_j_invalid = sha256_ctrl.sha256_inst.wntz_j_invalid; + + covergroup sha256_ctrl_cov_grp @(posedge clk); + reset_cp: coverpoint reset_n; + // cptra_pwrgood_cp: coverpoint cptra_pwrgood; + + init_cp: coverpoint init; + next_cp: coverpoint next; + mode_cp: coverpoint mode; + zeroize_cp: coverpoint zeroize; + ready_cp: coverpoint ready; + valid_cp: coverpoint valid; + wntz_mode_cp: coverpoint wntz_mode; + wntz_n_mode_cp: coverpoint wntz_n_mode; + wntz_w_cp: coverpoint wntz_w { bins wntz_w_bin[] = {4'd1, 4'd2, 4'd4, 4'd8}; } + + hash_cmd_cp: coverpoint hash_cmd {bins cmd[] = (0, 0 => 1, 2 => 0, 0);} + + wntz_w_invalid_cp: coverpoint wntz_w_invalid; + wntz_mode_invalid_cp: coverpoint wntz_mode_invalid; + wntz_j_invalid_cp: coverpoint wntz_j_invalid; + + init_ready_cp: cross ready, init; + // next_ready_cp: cross ready, next; + zeroize_ready_cp: cross ready, zeroize; + mode_ready_cp: cross ready, mode; + zeroize_init_cp: cross zeroize, init; + zeroize_next_cp: cross zeroize, next; + + wntzmode_init_cp: cross wntz_mode, init{ + ignore_bins invalid_case = binsof(wntz_mode) intersect {1} && binsof(init) intersect {0}; + } + wntzmode_ready_cp: cross ready, wntz_mode; + wntzmode_zeroize_cp: cross zeroize, wntz_mode; + wntz_n_w_cp: cross wntz_n_mode, wntz_w_cp; + + + endgroup + + sha256_ctrl_cov_grp sha256_ctrl_cov_grp1 = new(); + +endinterface + +`endif \ No newline at end of file diff --git a/designs/Caliptra/src/caliptra-rtl/sha256_k_constants.v b/designs/Caliptra/src/caliptra-rtl/sha256_k_constants.v new file mode 100644 index 0000000..e3db8eb --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/sha256_k_constants.v @@ -0,0 +1,132 @@ +//====================================================================== +// +// sha256_k_constants.v +// -------------------- +// The table K with constants in the SHA-256 hash function. +// +// +// Author: Joachim Strombergson +// Copyright (c) 2013, Secworks Sweden AB +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or +// without modification, are permitted provided that the following +// conditions are met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in +// the documentation and/or other materials provided with the +// distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +//====================================================================== + +module sha256_k_constants( + input wire [5 : 0] round, + output wire [31 : 0] K_val + ); + + //---------------------------------------------------------------- + // Wires. + //---------------------------------------------------------------- + reg [31 : 0] tmp_K; + + + //---------------------------------------------------------------- + // Concurrent connectivity for ports etc. + //---------------------------------------------------------------- + assign K_val = tmp_K; + + + //---------------------------------------------------------------- + // round_mux + //---------------------------------------------------------------- + always @* + begin : round_mux + case(round) + 00: tmp_K = 32'h428a2f98; + 01: tmp_K = 32'h71374491; + 02: tmp_K = 32'hb5c0fbcf; + 03: tmp_K = 32'he9b5dba5; + 04: tmp_K = 32'h3956c25b; + 05: tmp_K = 32'h59f111f1; + 06: tmp_K = 32'h923f82a4; + 07: tmp_K = 32'hab1c5ed5; + 08: tmp_K = 32'hd807aa98; + 09: tmp_K = 32'h12835b01; + 10: tmp_K = 32'h243185be; + 11: tmp_K = 32'h550c7dc3; + 12: tmp_K = 32'h72be5d74; + 13: tmp_K = 32'h80deb1fe; + 14: tmp_K = 32'h9bdc06a7; + 15: tmp_K = 32'hc19bf174; + 16: tmp_K = 32'he49b69c1; + 17: tmp_K = 32'hefbe4786; + 18: tmp_K = 32'h0fc19dc6; + 19: tmp_K = 32'h240ca1cc; + 20: tmp_K = 32'h2de92c6f; + 21: tmp_K = 32'h4a7484aa; + 22: tmp_K = 32'h5cb0a9dc; + 23: tmp_K = 32'h76f988da; + 24: tmp_K = 32'h983e5152; + 25: tmp_K = 32'ha831c66d; + 26: tmp_K = 32'hb00327c8; + 27: tmp_K = 32'hbf597fc7; + 28: tmp_K = 32'hc6e00bf3; + 29: tmp_K = 32'hd5a79147; + 30: tmp_K = 32'h06ca6351; + 31: tmp_K = 32'h14292967; + 32: tmp_K = 32'h27b70a85; + 33: tmp_K = 32'h2e1b2138; + 34: tmp_K = 32'h4d2c6dfc; + 35: tmp_K = 32'h53380d13; + 36: tmp_K = 32'h650a7354; + 37: tmp_K = 32'h766a0abb; + 38: tmp_K = 32'h81c2c92e; + 39: tmp_K = 32'h92722c85; + 40: tmp_K = 32'ha2bfe8a1; + 41: tmp_K = 32'ha81a664b; + 42: tmp_K = 32'hc24b8b70; + 43: tmp_K = 32'hc76c51a3; + 44: tmp_K = 32'hd192e819; + 45: tmp_K = 32'hd6990624; + 46: tmp_K = 32'hf40e3585; + 47: tmp_K = 32'h106aa070; + 48: tmp_K = 32'h19a4c116; + 49: tmp_K = 32'h1e376c08; + 50: tmp_K = 32'h2748774c; + 51: tmp_K = 32'h34b0bcb5; + 52: tmp_K = 32'h391c0cb3; + 53: tmp_K = 32'h4ed8aa4a; + 54: tmp_K = 32'h5b9cca4f; + 55: tmp_K = 32'h682e6ff3; + 56: tmp_K = 32'h748f82ee; + 57: tmp_K = 32'h78a5636f; + 58: tmp_K = 32'h84c87814; + 59: tmp_K = 32'h8cc70208; + 60: tmp_K = 32'h90befffa; + 61: tmp_K = 32'ha4506ceb; + 62: tmp_K = 32'hbef9a3f7; + 63: tmp_K = 32'hc67178f2; + endcase // case (round) + end // block: round_mux +endmodule // sha256_k_constants + +//====================================================================== +// sha256_k_constants.v +//====================================================================== diff --git a/designs/Caliptra/src/caliptra-rtl/sha256_params_pkg.sv b/designs/Caliptra/src/caliptra-rtl/sha256_params_pkg.sv new file mode 100644 index 0000000..00c36b5 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/sha256_params_pkg.sv @@ -0,0 +1,30 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +// +// + +package sha256_params_pkg; + + localparam SHA256_CORE_NAME0 = 32'h61327368; // "sha2" + localparam SHA256_CORE_NAME1 = 32'h35362d32; // "-256" + localparam SHA256_CORE_VERSION0 = 32'h3830312e; // "1.80" + localparam SHA256_CORE_VERSION1 = 32'h00000000; // "0" + + localparam SHA256_MODE_SHA_224 = 1'h0; + localparam SHA256_MODE_SHA_256 = 1'h1; + +endpackage +//====================================================================== +// EOF sha256_params_pkg.sv +//====================================================================== diff --git a/designs/Caliptra/src/caliptra-rtl/sha256_reg.sv b/designs/Caliptra/src/caliptra-rtl/sha256_reg.sv new file mode 100644 index 0000000..4c06e29 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/sha256_reg.sv @@ -0,0 +1,1596 @@ +// Generated by PeakRDL-regblock - A free and open-source SystemVerilog generator +// https://github.com/SystemRDL/PeakRDL-regblock + +module sha256_reg ( + input wire clk, + input wire rst, + + input wire s_cpuif_req, + input wire s_cpuif_req_is_wr, + input wire [11:0] s_cpuif_addr, + input wire [31:0] s_cpuif_wr_data, + input wire [31:0] s_cpuif_wr_biten, + output wire s_cpuif_req_stall_wr, + output wire s_cpuif_req_stall_rd, + output wire s_cpuif_rd_ack, + output wire s_cpuif_rd_err, + output wire [31:0] s_cpuif_rd_data, + output wire s_cpuif_wr_ack, + output wire s_cpuif_wr_err, + + input sha256_reg_pkg::sha256_reg__in_t hwif_in, + output sha256_reg_pkg::sha256_reg__out_t hwif_out + ); + + //-------------------------------------------------------------------------- + // CPU Bus interface logic + //-------------------------------------------------------------------------- + logic cpuif_req; + logic cpuif_req_is_wr; + logic [11:0] cpuif_addr; + logic [31:0] cpuif_wr_data; + logic [31:0] cpuif_wr_biten; + logic cpuif_req_stall_wr; + logic cpuif_req_stall_rd; + + logic cpuif_rd_ack; + logic cpuif_rd_err; + logic [31:0] cpuif_rd_data; + + logic cpuif_wr_ack; + logic cpuif_wr_err; + + assign cpuif_req = s_cpuif_req; + assign cpuif_req_is_wr = s_cpuif_req_is_wr; + assign cpuif_addr = s_cpuif_addr; + assign cpuif_wr_data = s_cpuif_wr_data; + assign cpuif_wr_biten = s_cpuif_wr_biten; + assign s_cpuif_req_stall_wr = cpuif_req_stall_wr; + assign s_cpuif_req_stall_rd = cpuif_req_stall_rd; + assign s_cpuif_rd_ack = cpuif_rd_ack; + assign s_cpuif_rd_err = cpuif_rd_err; + assign s_cpuif_rd_data = cpuif_rd_data; + assign s_cpuif_wr_ack = cpuif_wr_ack; + assign s_cpuif_wr_err = cpuif_wr_err; + + logic cpuif_req_masked; + + // Read & write latencies are balanced. Stalls not required + assign cpuif_req_stall_rd = '0; + assign cpuif_req_stall_wr = '0; + assign cpuif_req_masked = cpuif_req + & !(!cpuif_req_is_wr & cpuif_req_stall_rd) + & !(cpuif_req_is_wr & cpuif_req_stall_wr); + + //-------------------------------------------------------------------------- + // Address Decode + //-------------------------------------------------------------------------- + typedef struct packed{ + logic [2-1:0]SHA256_NAME; + logic [2-1:0]SHA256_VERSION; + logic SHA256_CTRL; + logic SHA256_STATUS; + logic [16-1:0]SHA256_BLOCK; + logic [8-1:0]SHA256_DIGEST; + struct packed{ + logic global_intr_en_r; + logic error_intr_en_r; + logic notif_intr_en_r; + logic error_global_intr_r; + logic notif_global_intr_r; + logic error_internal_intr_r; + logic notif_internal_intr_r; + logic error_intr_trig_r; + logic notif_intr_trig_r; + logic error0_intr_count_r; + logic error1_intr_count_r; + logic error2_intr_count_r; + logic error3_intr_count_r; + logic notif_cmd_done_intr_count_r; + logic error0_intr_count_incr_r; + logic error1_intr_count_incr_r; + logic error2_intr_count_incr_r; + logic error3_intr_count_incr_r; + logic notif_cmd_done_intr_count_incr_r; + } intr_block_rf; + } decoded_reg_strb_t; + decoded_reg_strb_t decoded_reg_strb; + logic decoded_req; + logic decoded_req_is_wr; + logic [31:0] decoded_wr_data; + logic [31:0] decoded_wr_biten; + + always_comb begin + for(int i0=0; i0<2; i0++) begin + decoded_reg_strb.SHA256_NAME[i0] = cpuif_req_masked & (cpuif_addr == 12'h0 + i0*12'h4); + end + for(int i0=0; i0<2; i0++) begin + decoded_reg_strb.SHA256_VERSION[i0] = cpuif_req_masked & (cpuif_addr == 12'h8 + i0*12'h4); + end + decoded_reg_strb.SHA256_CTRL = cpuif_req_masked & (cpuif_addr == 12'h10); + decoded_reg_strb.SHA256_STATUS = cpuif_req_masked & (cpuif_addr == 12'h18); + for(int i0=0; i0<16; i0++) begin + decoded_reg_strb.SHA256_BLOCK[i0] = cpuif_req_masked & (cpuif_addr == 12'h80 + i0*12'h4); + end + for(int i0=0; i0<8; i0++) begin + decoded_reg_strb.SHA256_DIGEST[i0] = cpuif_req_masked & (cpuif_addr == 12'h100 + i0*12'h4); + end + decoded_reg_strb.intr_block_rf.global_intr_en_r = cpuif_req_masked & (cpuif_addr == 12'h800); + decoded_reg_strb.intr_block_rf.error_intr_en_r = cpuif_req_masked & (cpuif_addr == 12'h804); + decoded_reg_strb.intr_block_rf.notif_intr_en_r = cpuif_req_masked & (cpuif_addr == 12'h808); + decoded_reg_strb.intr_block_rf.error_global_intr_r = cpuif_req_masked & (cpuif_addr == 12'h80c); + decoded_reg_strb.intr_block_rf.notif_global_intr_r = cpuif_req_masked & (cpuif_addr == 12'h810); + decoded_reg_strb.intr_block_rf.error_internal_intr_r = cpuif_req_masked & (cpuif_addr == 12'h814); + decoded_reg_strb.intr_block_rf.notif_internal_intr_r = cpuif_req_masked & (cpuif_addr == 12'h818); + decoded_reg_strb.intr_block_rf.error_intr_trig_r = cpuif_req_masked & (cpuif_addr == 12'h81c); + decoded_reg_strb.intr_block_rf.notif_intr_trig_r = cpuif_req_masked & (cpuif_addr == 12'h820); + decoded_reg_strb.intr_block_rf.error0_intr_count_r = cpuif_req_masked & (cpuif_addr == 12'h900); + decoded_reg_strb.intr_block_rf.error1_intr_count_r = cpuif_req_masked & (cpuif_addr == 12'h904); + decoded_reg_strb.intr_block_rf.error2_intr_count_r = cpuif_req_masked & (cpuif_addr == 12'h908); + decoded_reg_strb.intr_block_rf.error3_intr_count_r = cpuif_req_masked & (cpuif_addr == 12'h90c); + decoded_reg_strb.intr_block_rf.notif_cmd_done_intr_count_r = cpuif_req_masked & (cpuif_addr == 12'h980); + decoded_reg_strb.intr_block_rf.error0_intr_count_incr_r = cpuif_req_masked & (cpuif_addr == 12'ha00); + decoded_reg_strb.intr_block_rf.error1_intr_count_incr_r = cpuif_req_masked & (cpuif_addr == 12'ha04); + decoded_reg_strb.intr_block_rf.error2_intr_count_incr_r = cpuif_req_masked & (cpuif_addr == 12'ha08); + decoded_reg_strb.intr_block_rf.error3_intr_count_incr_r = cpuif_req_masked & (cpuif_addr == 12'ha0c); + decoded_reg_strb.intr_block_rf.notif_cmd_done_intr_count_incr_r = cpuif_req_masked & (cpuif_addr == 12'ha10); + end + + // Pass down signals to next stage + assign decoded_req = cpuif_req_masked; + assign decoded_req_is_wr = cpuif_req_is_wr; + assign decoded_wr_data = cpuif_wr_data; + assign decoded_wr_biten = cpuif_wr_biten; + + //-------------------------------------------------------------------------- + // Field logic + //-------------------------------------------------------------------------- + typedef struct packed{ + struct packed{ + struct packed{ + logic next; + logic load_next; + } INIT; + struct packed{ + logic next; + logic load_next; + } NEXT; + struct packed{ + logic next; + logic load_next; + } MODE; + struct packed{ + logic next; + logic load_next; + } ZEROIZE; + struct packed{ + logic next; + logic load_next; + } WNTZ_MODE; + struct packed{ + logic [3:0] next; + logic load_next; + } WNTZ_W; + struct packed{ + logic next; + logic load_next; + } WNTZ_N_MODE; + } SHA256_CTRL; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } BLOCK; + } [16-1:0]SHA256_BLOCK; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } DIGEST; + } [8-1:0]SHA256_DIGEST; + struct packed{ + struct packed{ + struct packed{ + logic next; + logic load_next; + } error_en; + struct packed{ + logic next; + logic load_next; + } notif_en; + } global_intr_en_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + } error0_en; + struct packed{ + logic next; + logic load_next; + } error1_en; + struct packed{ + logic next; + logic load_next; + } error2_en; + struct packed{ + logic next; + logic load_next; + } error3_en; + } error_intr_en_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + } notif_cmd_done_en; + } notif_intr_en_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + } agg_sts; + } error_global_intr_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + } agg_sts; + } notif_global_intr_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + } error0_sts; + struct packed{ + logic next; + logic load_next; + } error1_sts; + struct packed{ + logic next; + logic load_next; + } error2_sts; + struct packed{ + logic next; + logic load_next; + } error3_sts; + } error_internal_intr_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + } notif_cmd_done_sts; + } notif_internal_intr_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + } error0_trig; + struct packed{ + logic next; + logic load_next; + } error1_trig; + struct packed{ + logic next; + logic load_next; + } error2_trig; + struct packed{ + logic next; + logic load_next; + } error3_trig; + } error_intr_trig_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + } notif_cmd_done_trig; + } notif_intr_trig_r; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + logic incrthreshold; + logic incrsaturate; + } cnt; + } error0_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + logic incrthreshold; + logic incrsaturate; + } cnt; + } error1_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + logic incrthreshold; + logic incrsaturate; + } cnt; + } error2_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + logic incrthreshold; + logic incrsaturate; + } cnt; + } error3_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + logic incrthreshold; + logic incrsaturate; + } cnt; + } notif_cmd_done_intr_count_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + logic decrthreshold; + logic underflow; + } pulse; + } error0_intr_count_incr_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + logic decrthreshold; + logic underflow; + } pulse; + } error1_intr_count_incr_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + logic decrthreshold; + logic underflow; + } pulse; + } error2_intr_count_incr_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + logic decrthreshold; + logic underflow; + } pulse; + } error3_intr_count_incr_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + logic decrthreshold; + logic underflow; + } pulse; + } notif_cmd_done_intr_count_incr_r; + } intr_block_rf; + } field_combo_t; + field_combo_t field_combo; + + typedef struct packed{ + struct packed{ + struct packed{ + logic value; + } INIT; + struct packed{ + logic value; + } NEXT; + struct packed{ + logic value; + } MODE; + struct packed{ + logic value; + } ZEROIZE; + struct packed{ + logic value; + } WNTZ_MODE; + struct packed{ + logic [3:0] value; + } WNTZ_W; + struct packed{ + logic value; + } WNTZ_N_MODE; + } SHA256_CTRL; + struct packed{ + struct packed{ + logic [31:0] value; + } BLOCK; + } [16-1:0]SHA256_BLOCK; + struct packed{ + struct packed{ + logic [31:0] value; + } DIGEST; + } [8-1:0]SHA256_DIGEST; + struct packed{ + struct packed{ + struct packed{ + logic value; + } error_en; + struct packed{ + logic value; + } notif_en; + } global_intr_en_r; + struct packed{ + struct packed{ + logic value; + } error0_en; + struct packed{ + logic value; + } error1_en; + struct packed{ + logic value; + } error2_en; + struct packed{ + logic value; + } error3_en; + } error_intr_en_r; + struct packed{ + struct packed{ + logic value; + } notif_cmd_done_en; + } notif_intr_en_r; + struct packed{ + struct packed{ + logic value; + } agg_sts; + } error_global_intr_r; + struct packed{ + struct packed{ + logic value; + } agg_sts; + } notif_global_intr_r; + struct packed{ + struct packed{ + logic value; + } error0_sts; + struct packed{ + logic value; + } error1_sts; + struct packed{ + logic value; + } error2_sts; + struct packed{ + logic value; + } error3_sts; + } error_internal_intr_r; + struct packed{ + struct packed{ + logic value; + } notif_cmd_done_sts; + } notif_internal_intr_r; + struct packed{ + struct packed{ + logic value; + } error0_trig; + struct packed{ + logic value; + } error1_trig; + struct packed{ + logic value; + } error2_trig; + struct packed{ + logic value; + } error3_trig; + } error_intr_trig_r; + struct packed{ + struct packed{ + logic value; + } notif_cmd_done_trig; + } notif_intr_trig_r; + struct packed{ + struct packed{ + logic [31:0] value; + } cnt; + } error0_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] value; + } cnt; + } error1_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] value; + } cnt; + } error2_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] value; + } cnt; + } error3_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] value; + } cnt; + } notif_cmd_done_intr_count_r; + struct packed{ + struct packed{ + logic value; + } pulse; + } error0_intr_count_incr_r; + struct packed{ + struct packed{ + logic value; + } pulse; + } error1_intr_count_incr_r; + struct packed{ + struct packed{ + logic value; + } pulse; + } error2_intr_count_incr_r; + struct packed{ + struct packed{ + logic value; + } pulse; + } error3_intr_count_incr_r; + struct packed{ + struct packed{ + logic value; + } pulse; + } notif_cmd_done_intr_count_incr_r; + } intr_block_rf; + } field_storage_t; + field_storage_t field_storage; + + // Field: sha256_reg.SHA256_CTRL.INIT + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.SHA256_CTRL.INIT.value; + load_next_c = '0; + if(decoded_reg_strb.SHA256_CTRL && decoded_req_is_wr && hwif_in.sha256_ready) begin // SW write + next_c = (field_storage.SHA256_CTRL.INIT.value & ~decoded_wr_biten[0:0]) | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end else begin // singlepulse clears back to 0 + next_c = '0; + load_next_c = '1; + end + field_combo.SHA256_CTRL.INIT.next = next_c; + field_combo.SHA256_CTRL.INIT.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.SHA256_CTRL.INIT.value <= 1'h0; + end else if(field_combo.SHA256_CTRL.INIT.load_next) begin + field_storage.SHA256_CTRL.INIT.value <= field_combo.SHA256_CTRL.INIT.next; + end + end + assign hwif_out.SHA256_CTRL.INIT.value = field_storage.SHA256_CTRL.INIT.value; + // Field: sha256_reg.SHA256_CTRL.NEXT + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.SHA256_CTRL.NEXT.value; + load_next_c = '0; + if(decoded_reg_strb.SHA256_CTRL && decoded_req_is_wr && hwif_in.sha256_ready) begin // SW write + next_c = (field_storage.SHA256_CTRL.NEXT.value & ~decoded_wr_biten[1:1]) | (decoded_wr_data[1:1] & decoded_wr_biten[1:1]); + load_next_c = '1; + end else begin // singlepulse clears back to 0 + next_c = '0; + load_next_c = '1; + end + field_combo.SHA256_CTRL.NEXT.next = next_c; + field_combo.SHA256_CTRL.NEXT.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.SHA256_CTRL.NEXT.value <= 1'h0; + end else if(field_combo.SHA256_CTRL.NEXT.load_next) begin + field_storage.SHA256_CTRL.NEXT.value <= field_combo.SHA256_CTRL.NEXT.next; + end + end + assign hwif_out.SHA256_CTRL.NEXT.value = field_storage.SHA256_CTRL.NEXT.value; + // Field: sha256_reg.SHA256_CTRL.MODE + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.SHA256_CTRL.MODE.value; + load_next_c = '0; + if(decoded_reg_strb.SHA256_CTRL && decoded_req_is_wr && hwif_in.sha256_ready) begin // SW write + next_c = (field_storage.SHA256_CTRL.MODE.value & ~decoded_wr_biten[2:2]) | (decoded_wr_data[2:2] & decoded_wr_biten[2:2]); + load_next_c = '1; + end + field_combo.SHA256_CTRL.MODE.next = next_c; + field_combo.SHA256_CTRL.MODE.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.SHA256_CTRL.MODE.value <= 1'h1; + end else if(field_combo.SHA256_CTRL.MODE.load_next) begin + field_storage.SHA256_CTRL.MODE.value <= field_combo.SHA256_CTRL.MODE.next; + end + end + assign hwif_out.SHA256_CTRL.MODE.value = field_storage.SHA256_CTRL.MODE.value; + // Field: sha256_reg.SHA256_CTRL.ZEROIZE + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.SHA256_CTRL.ZEROIZE.value; + load_next_c = '0; + if(decoded_reg_strb.SHA256_CTRL && decoded_req_is_wr) begin // SW write + next_c = (field_storage.SHA256_CTRL.ZEROIZE.value & ~decoded_wr_biten[3:3]) | (decoded_wr_data[3:3] & decoded_wr_biten[3:3]); + load_next_c = '1; + end else begin // singlepulse clears back to 0 + next_c = '0; + load_next_c = '1; + end + field_combo.SHA256_CTRL.ZEROIZE.next = next_c; + field_combo.SHA256_CTRL.ZEROIZE.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.SHA256_CTRL.ZEROIZE.value <= 1'h0; + end else if(field_combo.SHA256_CTRL.ZEROIZE.load_next) begin + field_storage.SHA256_CTRL.ZEROIZE.value <= field_combo.SHA256_CTRL.ZEROIZE.next; + end + end + assign hwif_out.SHA256_CTRL.ZEROIZE.value = field_storage.SHA256_CTRL.ZEROIZE.value; + // Field: sha256_reg.SHA256_CTRL.WNTZ_MODE + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.SHA256_CTRL.WNTZ_MODE.value; + load_next_c = '0; + if(decoded_reg_strb.SHA256_CTRL && decoded_req_is_wr && hwif_in.sha256_ready) begin // SW write + next_c = (field_storage.SHA256_CTRL.WNTZ_MODE.value & ~decoded_wr_biten[4:4]) | (decoded_wr_data[4:4] & decoded_wr_biten[4:4]); + load_next_c = '1; + end else begin // singlepulse clears back to 0 + next_c = '0; + load_next_c = '1; + end + field_combo.SHA256_CTRL.WNTZ_MODE.next = next_c; + field_combo.SHA256_CTRL.WNTZ_MODE.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.SHA256_CTRL.WNTZ_MODE.value <= 1'h0; + end else if(field_combo.SHA256_CTRL.WNTZ_MODE.load_next) begin + field_storage.SHA256_CTRL.WNTZ_MODE.value <= field_combo.SHA256_CTRL.WNTZ_MODE.next; + end + end + assign hwif_out.SHA256_CTRL.WNTZ_MODE.value = field_storage.SHA256_CTRL.WNTZ_MODE.value; + // Field: sha256_reg.SHA256_CTRL.WNTZ_W + always_comb begin + automatic logic [3:0] next_c; + automatic logic load_next_c; + next_c = field_storage.SHA256_CTRL.WNTZ_W.value; + load_next_c = '0; + if(decoded_reg_strb.SHA256_CTRL && decoded_req_is_wr && hwif_in.sha256_ready) begin // SW write + next_c = (field_storage.SHA256_CTRL.WNTZ_W.value & ~decoded_wr_biten[8:5]) | (decoded_wr_data[8:5] & decoded_wr_biten[8:5]); + load_next_c = '1; + end + field_combo.SHA256_CTRL.WNTZ_W.next = next_c; + field_combo.SHA256_CTRL.WNTZ_W.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.SHA256_CTRL.WNTZ_W.value <= 4'h4; + end else if(field_combo.SHA256_CTRL.WNTZ_W.load_next) begin + field_storage.SHA256_CTRL.WNTZ_W.value <= field_combo.SHA256_CTRL.WNTZ_W.next; + end + end + assign hwif_out.SHA256_CTRL.WNTZ_W.value = field_storage.SHA256_CTRL.WNTZ_W.value; + // Field: sha256_reg.SHA256_CTRL.WNTZ_N_MODE + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.SHA256_CTRL.WNTZ_N_MODE.value; + load_next_c = '0; + if(decoded_reg_strb.SHA256_CTRL && decoded_req_is_wr && hwif_in.sha256_ready) begin // SW write + next_c = (field_storage.SHA256_CTRL.WNTZ_N_MODE.value & ~decoded_wr_biten[9:9]) | (decoded_wr_data[9:9] & decoded_wr_biten[9:9]); + load_next_c = '1; + end + field_combo.SHA256_CTRL.WNTZ_N_MODE.next = next_c; + field_combo.SHA256_CTRL.WNTZ_N_MODE.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.SHA256_CTRL.WNTZ_N_MODE.value <= 1'h0; + end else if(field_combo.SHA256_CTRL.WNTZ_N_MODE.load_next) begin + field_storage.SHA256_CTRL.WNTZ_N_MODE.value <= field_combo.SHA256_CTRL.WNTZ_N_MODE.next; + end + end + assign hwif_out.SHA256_CTRL.WNTZ_N_MODE.value = field_storage.SHA256_CTRL.WNTZ_N_MODE.value; + for(genvar i0=0; i0<16; i0++) begin + // Field: sha256_reg.SHA256_BLOCK[].BLOCK + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.SHA256_BLOCK[i0].BLOCK.value; + load_next_c = '0; + if(decoded_reg_strb.SHA256_BLOCK[i0] && decoded_req_is_wr) begin // SW write + next_c = (field_storage.SHA256_BLOCK[i0].BLOCK.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end else if(hwif_in.SHA256_BLOCK[i0].BLOCK.hwclr) begin // HW Clear + next_c = '0; + load_next_c = '1; + end + field_combo.SHA256_BLOCK[i0].BLOCK.next = next_c; + field_combo.SHA256_BLOCK[i0].BLOCK.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.SHA256_BLOCK[i0].BLOCK.value <= 32'h0; + end else if(field_combo.SHA256_BLOCK[i0].BLOCK.load_next) begin + field_storage.SHA256_BLOCK[i0].BLOCK.value <= field_combo.SHA256_BLOCK[i0].BLOCK.next; + end + end + assign hwif_out.SHA256_BLOCK[i0].BLOCK.value = field_storage.SHA256_BLOCK[i0].BLOCK.value; + end + for(genvar i0=0; i0<8; i0++) begin + // Field: sha256_reg.SHA256_DIGEST[].DIGEST + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.SHA256_DIGEST[i0].DIGEST.value; + load_next_c = '0; + if(hwif_in.SHA256_DIGEST[i0].DIGEST.hwclr) begin // HW Clear + next_c = '0; + load_next_c = '1; + end else begin // HW Write + next_c = hwif_in.SHA256_DIGEST[i0].DIGEST.next; + load_next_c = '1; + end + field_combo.SHA256_DIGEST[i0].DIGEST.next = next_c; + field_combo.SHA256_DIGEST[i0].DIGEST.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.SHA256_DIGEST[i0].DIGEST.value <= 32'h0; + end else if(field_combo.SHA256_DIGEST[i0].DIGEST.load_next) begin + field_storage.SHA256_DIGEST[i0].DIGEST.value <= field_combo.SHA256_DIGEST[i0].DIGEST.next; + end + end + end + // Field: sha256_reg.intr_block_rf.global_intr_en_r.error_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.global_intr_en_r.error_en.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.global_intr_en_r && decoded_req_is_wr) begin // SW write + next_c = (field_storage.intr_block_rf.global_intr_en_r.error_en.value & ~decoded_wr_biten[0:0]) | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end + field_combo.intr_block_rf.global_intr_en_r.error_en.next = next_c; + field_combo.intr_block_rf.global_intr_en_r.error_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.global_intr_en_r.error_en.value <= 1'h0; + end else if(field_combo.intr_block_rf.global_intr_en_r.error_en.load_next) begin + field_storage.intr_block_rf.global_intr_en_r.error_en.value <= field_combo.intr_block_rf.global_intr_en_r.error_en.next; + end + end + // Field: sha256_reg.intr_block_rf.global_intr_en_r.notif_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.global_intr_en_r.notif_en.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.global_intr_en_r && decoded_req_is_wr) begin // SW write + next_c = (field_storage.intr_block_rf.global_intr_en_r.notif_en.value & ~decoded_wr_biten[1:1]) | (decoded_wr_data[1:1] & decoded_wr_biten[1:1]); + load_next_c = '1; + end + field_combo.intr_block_rf.global_intr_en_r.notif_en.next = next_c; + field_combo.intr_block_rf.global_intr_en_r.notif_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.global_intr_en_r.notif_en.value <= 1'h0; + end else if(field_combo.intr_block_rf.global_intr_en_r.notif_en.load_next) begin + field_storage.intr_block_rf.global_intr_en_r.notif_en.value <= field_combo.intr_block_rf.global_intr_en_r.notif_en.next; + end + end + // Field: sha256_reg.intr_block_rf.error_intr_en_r.error0_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_intr_en_r.error0_en.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_intr_en_r && decoded_req_is_wr) begin // SW write + next_c = (field_storage.intr_block_rf.error_intr_en_r.error0_en.value & ~decoded_wr_biten[0:0]) | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end + field_combo.intr_block_rf.error_intr_en_r.error0_en.next = next_c; + field_combo.intr_block_rf.error_intr_en_r.error0_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.error_intr_en_r.error0_en.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_intr_en_r.error0_en.load_next) begin + field_storage.intr_block_rf.error_intr_en_r.error0_en.value <= field_combo.intr_block_rf.error_intr_en_r.error0_en.next; + end + end + // Field: sha256_reg.intr_block_rf.error_intr_en_r.error1_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_intr_en_r.error1_en.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_intr_en_r && decoded_req_is_wr) begin // SW write + next_c = (field_storage.intr_block_rf.error_intr_en_r.error1_en.value & ~decoded_wr_biten[1:1]) | (decoded_wr_data[1:1] & decoded_wr_biten[1:1]); + load_next_c = '1; + end + field_combo.intr_block_rf.error_intr_en_r.error1_en.next = next_c; + field_combo.intr_block_rf.error_intr_en_r.error1_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.error_intr_en_r.error1_en.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_intr_en_r.error1_en.load_next) begin + field_storage.intr_block_rf.error_intr_en_r.error1_en.value <= field_combo.intr_block_rf.error_intr_en_r.error1_en.next; + end + end + // Field: sha256_reg.intr_block_rf.error_intr_en_r.error2_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_intr_en_r.error2_en.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_intr_en_r && decoded_req_is_wr) begin // SW write + next_c = (field_storage.intr_block_rf.error_intr_en_r.error2_en.value & ~decoded_wr_biten[2:2]) | (decoded_wr_data[2:2] & decoded_wr_biten[2:2]); + load_next_c = '1; + end + field_combo.intr_block_rf.error_intr_en_r.error2_en.next = next_c; + field_combo.intr_block_rf.error_intr_en_r.error2_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.error_intr_en_r.error2_en.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_intr_en_r.error2_en.load_next) begin + field_storage.intr_block_rf.error_intr_en_r.error2_en.value <= field_combo.intr_block_rf.error_intr_en_r.error2_en.next; + end + end + // Field: sha256_reg.intr_block_rf.error_intr_en_r.error3_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_intr_en_r.error3_en.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_intr_en_r && decoded_req_is_wr) begin // SW write + next_c = (field_storage.intr_block_rf.error_intr_en_r.error3_en.value & ~decoded_wr_biten[3:3]) | (decoded_wr_data[3:3] & decoded_wr_biten[3:3]); + load_next_c = '1; + end + field_combo.intr_block_rf.error_intr_en_r.error3_en.next = next_c; + field_combo.intr_block_rf.error_intr_en_r.error3_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.error_intr_en_r.error3_en.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_intr_en_r.error3_en.load_next) begin + field_storage.intr_block_rf.error_intr_en_r.error3_en.value <= field_combo.intr_block_rf.error_intr_en_r.error3_en.next; + end + end + // Field: sha256_reg.intr_block_rf.notif_intr_en_r.notif_cmd_done_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_intr_en_r.notif_cmd_done_en.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.notif_intr_en_r && decoded_req_is_wr) begin // SW write + next_c = (field_storage.intr_block_rf.notif_intr_en_r.notif_cmd_done_en.value & ~decoded_wr_biten[0:0]) | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end + field_combo.intr_block_rf.notif_intr_en_r.notif_cmd_done_en.next = next_c; + field_combo.intr_block_rf.notif_intr_en_r.notif_cmd_done_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.notif_intr_en_r.notif_cmd_done_en.value <= 1'h0; + end else if(field_combo.intr_block_rf.notif_intr_en_r.notif_cmd_done_en.load_next) begin + field_storage.intr_block_rf.notif_intr_en_r.notif_cmd_done_en.value <= field_combo.intr_block_rf.notif_intr_en_r.notif_cmd_done_en.next; + end + end + // Field: sha256_reg.intr_block_rf.error_global_intr_r.agg_sts + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_global_intr_r.agg_sts.value; + load_next_c = '0; + + // HW Write + next_c = hwif_out.intr_block_rf.error_internal_intr_r.intr; + load_next_c = '1; + field_combo.intr_block_rf.error_global_intr_r.agg_sts.next = next_c; + field_combo.intr_block_rf.error_global_intr_r.agg_sts.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.error_global_intr_r.agg_sts.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_global_intr_r.agg_sts.load_next) begin + field_storage.intr_block_rf.error_global_intr_r.agg_sts.value <= field_combo.intr_block_rf.error_global_intr_r.agg_sts.next; + end + end + assign hwif_out.intr_block_rf.error_global_intr_r.intr = + |(field_storage.intr_block_rf.error_global_intr_r.agg_sts.value & field_storage.intr_block_rf.global_intr_en_r.error_en.value); + // Field: sha256_reg.intr_block_rf.notif_global_intr_r.agg_sts + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_global_intr_r.agg_sts.value; + load_next_c = '0; + + // HW Write + next_c = hwif_out.intr_block_rf.notif_internal_intr_r.intr; + load_next_c = '1; + field_combo.intr_block_rf.notif_global_intr_r.agg_sts.next = next_c; + field_combo.intr_block_rf.notif_global_intr_r.agg_sts.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.notif_global_intr_r.agg_sts.value <= 1'h0; + end else if(field_combo.intr_block_rf.notif_global_intr_r.agg_sts.load_next) begin + field_storage.intr_block_rf.notif_global_intr_r.agg_sts.value <= field_combo.intr_block_rf.notif_global_intr_r.agg_sts.next; + end + end + assign hwif_out.intr_block_rf.notif_global_intr_r.intr = + |(field_storage.intr_block_rf.notif_global_intr_r.agg_sts.value & field_storage.intr_block_rf.global_intr_en_r.notif_en.value); + // Field: sha256_reg.intr_block_rf.error_internal_intr_r.error0_sts + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_internal_intr_r.error0_sts.value; + load_next_c = '0; + if(field_storage.intr_block_rf.error_intr_trig_r.error0_trig.value != '0) begin // stickybit + next_c = field_storage.intr_block_rf.error_internal_intr_r.error0_sts.value | field_storage.intr_block_rf.error_intr_trig_r.error0_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.error_internal_intr_r.error0_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end else if(decoded_reg_strb.intr_block_rf.error_internal_intr_r && decoded_req_is_wr) begin // SW write 1 clear + next_c = field_storage.intr_block_rf.error_internal_intr_r.error0_sts.value & ~(decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end + field_combo.intr_block_rf.error_internal_intr_r.error0_sts.next = next_c; + field_combo.intr_block_rf.error_internal_intr_r.error0_sts.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.error_reset_b) begin + if(~hwif_in.error_reset_b) begin + field_storage.intr_block_rf.error_internal_intr_r.error0_sts.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_internal_intr_r.error0_sts.load_next) begin + field_storage.intr_block_rf.error_internal_intr_r.error0_sts.value <= field_combo.intr_block_rf.error_internal_intr_r.error0_sts.next; + end + end + // Field: sha256_reg.intr_block_rf.error_internal_intr_r.error1_sts + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_internal_intr_r.error1_sts.value; + load_next_c = '0; + if(field_storage.intr_block_rf.error_intr_trig_r.error1_trig.value != '0) begin // stickybit + next_c = field_storage.intr_block_rf.error_internal_intr_r.error1_sts.value | field_storage.intr_block_rf.error_intr_trig_r.error1_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.error_internal_intr_r.error1_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end else if(decoded_reg_strb.intr_block_rf.error_internal_intr_r && decoded_req_is_wr) begin // SW write 1 clear + next_c = field_storage.intr_block_rf.error_internal_intr_r.error1_sts.value & ~(decoded_wr_data[1:1] & decoded_wr_biten[1:1]); + load_next_c = '1; + end + field_combo.intr_block_rf.error_internal_intr_r.error1_sts.next = next_c; + field_combo.intr_block_rf.error_internal_intr_r.error1_sts.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.error_reset_b) begin + if(~hwif_in.error_reset_b) begin + field_storage.intr_block_rf.error_internal_intr_r.error1_sts.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_internal_intr_r.error1_sts.load_next) begin + field_storage.intr_block_rf.error_internal_intr_r.error1_sts.value <= field_combo.intr_block_rf.error_internal_intr_r.error1_sts.next; + end + end + // Field: sha256_reg.intr_block_rf.error_internal_intr_r.error2_sts + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_internal_intr_r.error2_sts.value; + load_next_c = '0; + if(field_storage.intr_block_rf.error_intr_trig_r.error2_trig.value != '0) begin // stickybit + next_c = field_storage.intr_block_rf.error_internal_intr_r.error2_sts.value | field_storage.intr_block_rf.error_intr_trig_r.error2_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.error_internal_intr_r.error2_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end else if(decoded_reg_strb.intr_block_rf.error_internal_intr_r && decoded_req_is_wr) begin // SW write 1 clear + next_c = field_storage.intr_block_rf.error_internal_intr_r.error2_sts.value & ~(decoded_wr_data[2:2] & decoded_wr_biten[2:2]); + load_next_c = '1; + end + field_combo.intr_block_rf.error_internal_intr_r.error2_sts.next = next_c; + field_combo.intr_block_rf.error_internal_intr_r.error2_sts.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.error_reset_b) begin + if(~hwif_in.error_reset_b) begin + field_storage.intr_block_rf.error_internal_intr_r.error2_sts.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_internal_intr_r.error2_sts.load_next) begin + field_storage.intr_block_rf.error_internal_intr_r.error2_sts.value <= field_combo.intr_block_rf.error_internal_intr_r.error2_sts.next; + end + end + // Field: sha256_reg.intr_block_rf.error_internal_intr_r.error3_sts + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_internal_intr_r.error3_sts.value; + load_next_c = '0; + if(field_storage.intr_block_rf.error_intr_trig_r.error3_trig.value != '0) begin // stickybit + next_c = field_storage.intr_block_rf.error_internal_intr_r.error3_sts.value | field_storage.intr_block_rf.error_intr_trig_r.error3_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.error_internal_intr_r.error3_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end else if(decoded_reg_strb.intr_block_rf.error_internal_intr_r && decoded_req_is_wr) begin // SW write 1 clear + next_c = field_storage.intr_block_rf.error_internal_intr_r.error3_sts.value & ~(decoded_wr_data[3:3] & decoded_wr_biten[3:3]); + load_next_c = '1; + end + field_combo.intr_block_rf.error_internal_intr_r.error3_sts.next = next_c; + field_combo.intr_block_rf.error_internal_intr_r.error3_sts.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.error_reset_b) begin + if(~hwif_in.error_reset_b) begin + field_storage.intr_block_rf.error_internal_intr_r.error3_sts.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_internal_intr_r.error3_sts.load_next) begin + field_storage.intr_block_rf.error_internal_intr_r.error3_sts.value <= field_combo.intr_block_rf.error_internal_intr_r.error3_sts.next; + end + end + assign hwif_out.intr_block_rf.error_internal_intr_r.intr = + |(field_storage.intr_block_rf.error_internal_intr_r.error0_sts.value & field_storage.intr_block_rf.error_intr_en_r.error0_en.value) + || |(field_storage.intr_block_rf.error_internal_intr_r.error1_sts.value & field_storage.intr_block_rf.error_intr_en_r.error1_en.value) + || |(field_storage.intr_block_rf.error_internal_intr_r.error2_sts.value & field_storage.intr_block_rf.error_intr_en_r.error2_en.value) + || |(field_storage.intr_block_rf.error_internal_intr_r.error3_sts.value & field_storage.intr_block_rf.error_intr_en_r.error3_en.value); + // Field: sha256_reg.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.value; + load_next_c = '0; + if(field_storage.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.value != '0) begin // stickybit + next_c = field_storage.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.value | field_storage.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end else if(decoded_reg_strb.intr_block_rf.notif_internal_intr_r && decoded_req_is_wr) begin // SW write 1 clear + next_c = field_storage.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.value & ~(decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end + field_combo.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.next = next_c; + field_combo.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.value <= 1'h0; + end else if(field_combo.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.load_next) begin + field_storage.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.value <= field_combo.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.next; + end + end + assign hwif_out.intr_block_rf.notif_internal_intr_r.intr = + |(field_storage.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.value & field_storage.intr_block_rf.notif_intr_en_r.notif_cmd_done_en.value); + // Field: sha256_reg.intr_block_rf.error_intr_trig_r.error0_trig + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_intr_trig_r.error0_trig.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_intr_trig_r && decoded_req_is_wr) begin // SW write 1 set + next_c = field_storage.intr_block_rf.error_intr_trig_r.error0_trig.value | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end else begin // singlepulse clears back to 0 + next_c = '0; + load_next_c = '1; + end + field_combo.intr_block_rf.error_intr_trig_r.error0_trig.next = next_c; + field_combo.intr_block_rf.error_intr_trig_r.error0_trig.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.error_intr_trig_r.error0_trig.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_intr_trig_r.error0_trig.load_next) begin + field_storage.intr_block_rf.error_intr_trig_r.error0_trig.value <= field_combo.intr_block_rf.error_intr_trig_r.error0_trig.next; + end + end + // Field: sha256_reg.intr_block_rf.error_intr_trig_r.error1_trig + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_intr_trig_r.error1_trig.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_intr_trig_r && decoded_req_is_wr) begin // SW write 1 set + next_c = field_storage.intr_block_rf.error_intr_trig_r.error1_trig.value | (decoded_wr_data[1:1] & decoded_wr_biten[1:1]); + load_next_c = '1; + end else begin // singlepulse clears back to 0 + next_c = '0; + load_next_c = '1; + end + field_combo.intr_block_rf.error_intr_trig_r.error1_trig.next = next_c; + field_combo.intr_block_rf.error_intr_trig_r.error1_trig.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.error_intr_trig_r.error1_trig.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_intr_trig_r.error1_trig.load_next) begin + field_storage.intr_block_rf.error_intr_trig_r.error1_trig.value <= field_combo.intr_block_rf.error_intr_trig_r.error1_trig.next; + end + end + // Field: sha256_reg.intr_block_rf.error_intr_trig_r.error2_trig + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_intr_trig_r.error2_trig.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_intr_trig_r && decoded_req_is_wr) begin // SW write 1 set + next_c = field_storage.intr_block_rf.error_intr_trig_r.error2_trig.value | (decoded_wr_data[2:2] & decoded_wr_biten[2:2]); + load_next_c = '1; + end else begin // singlepulse clears back to 0 + next_c = '0; + load_next_c = '1; + end + field_combo.intr_block_rf.error_intr_trig_r.error2_trig.next = next_c; + field_combo.intr_block_rf.error_intr_trig_r.error2_trig.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.error_intr_trig_r.error2_trig.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_intr_trig_r.error2_trig.load_next) begin + field_storage.intr_block_rf.error_intr_trig_r.error2_trig.value <= field_combo.intr_block_rf.error_intr_trig_r.error2_trig.next; + end + end + // Field: sha256_reg.intr_block_rf.error_intr_trig_r.error3_trig + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_intr_trig_r.error3_trig.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_intr_trig_r && decoded_req_is_wr) begin // SW write 1 set + next_c = field_storage.intr_block_rf.error_intr_trig_r.error3_trig.value | (decoded_wr_data[3:3] & decoded_wr_biten[3:3]); + load_next_c = '1; + end else begin // singlepulse clears back to 0 + next_c = '0; + load_next_c = '1; + end + field_combo.intr_block_rf.error_intr_trig_r.error3_trig.next = next_c; + field_combo.intr_block_rf.error_intr_trig_r.error3_trig.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.error_intr_trig_r.error3_trig.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_intr_trig_r.error3_trig.load_next) begin + field_storage.intr_block_rf.error_intr_trig_r.error3_trig.value <= field_combo.intr_block_rf.error_intr_trig_r.error3_trig.next; + end + end + // Field: sha256_reg.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.notif_intr_trig_r && decoded_req_is_wr) begin // SW write 1 set + next_c = field_storage.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.value | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end else begin // singlepulse clears back to 0 + next_c = '0; + load_next_c = '1; + end + field_combo.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.next = next_c; + field_combo.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.value <= 1'h0; + end else if(field_combo.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.load_next) begin + field_storage.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.value <= field_combo.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.next; + end + end + // Field: sha256_reg.intr_block_rf.error0_intr_count_r.cnt + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error0_intr_count_r.cnt.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error0_intr_count_r && decoded_req_is_wr) begin // SW write + next_c = (field_storage.intr_block_rf.error0_intr_count_r.cnt.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + if(field_storage.intr_block_rf.error0_intr_count_incr_r.pulse.value) begin // increment + if(((33)'(next_c) + 32'h1) > 32'hffffffff) begin // up-counter saturated + next_c = 32'hffffffff; + end else begin + next_c = next_c + 32'h1; + end + load_next_c = '1; + end + field_combo.intr_block_rf.error0_intr_count_r.cnt.incrthreshold = (field_storage.intr_block_rf.error0_intr_count_r.cnt.value >= 32'hffffffff); + field_combo.intr_block_rf.error0_intr_count_r.cnt.incrsaturate = (field_storage.intr_block_rf.error0_intr_count_r.cnt.value >= 32'hffffffff); + if(next_c > 32'hffffffff) begin + next_c = 32'hffffffff; + load_next_c = '1; + end + field_combo.intr_block_rf.error0_intr_count_r.cnt.next = next_c; + field_combo.intr_block_rf.error0_intr_count_r.cnt.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.error_reset_b) begin + if(~hwif_in.error_reset_b) begin + field_storage.intr_block_rf.error0_intr_count_r.cnt.value <= 32'h0; + end else if(field_combo.intr_block_rf.error0_intr_count_r.cnt.load_next) begin + field_storage.intr_block_rf.error0_intr_count_r.cnt.value <= field_combo.intr_block_rf.error0_intr_count_r.cnt.next; + end + end + // Field: sha256_reg.intr_block_rf.error1_intr_count_r.cnt + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error1_intr_count_r.cnt.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error1_intr_count_r && decoded_req_is_wr) begin // SW write + next_c = (field_storage.intr_block_rf.error1_intr_count_r.cnt.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + if(field_storage.intr_block_rf.error1_intr_count_incr_r.pulse.value) begin // increment + if(((33)'(next_c) + 32'h1) > 32'hffffffff) begin // up-counter saturated + next_c = 32'hffffffff; + end else begin + next_c = next_c + 32'h1; + end + load_next_c = '1; + end + field_combo.intr_block_rf.error1_intr_count_r.cnt.incrthreshold = (field_storage.intr_block_rf.error1_intr_count_r.cnt.value >= 32'hffffffff); + field_combo.intr_block_rf.error1_intr_count_r.cnt.incrsaturate = (field_storage.intr_block_rf.error1_intr_count_r.cnt.value >= 32'hffffffff); + if(next_c > 32'hffffffff) begin + next_c = 32'hffffffff; + load_next_c = '1; + end + field_combo.intr_block_rf.error1_intr_count_r.cnt.next = next_c; + field_combo.intr_block_rf.error1_intr_count_r.cnt.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.error_reset_b) begin + if(~hwif_in.error_reset_b) begin + field_storage.intr_block_rf.error1_intr_count_r.cnt.value <= 32'h0; + end else if(field_combo.intr_block_rf.error1_intr_count_r.cnt.load_next) begin + field_storage.intr_block_rf.error1_intr_count_r.cnt.value <= field_combo.intr_block_rf.error1_intr_count_r.cnt.next; + end + end + // Field: sha256_reg.intr_block_rf.error2_intr_count_r.cnt + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error2_intr_count_r.cnt.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error2_intr_count_r && decoded_req_is_wr) begin // SW write + next_c = (field_storage.intr_block_rf.error2_intr_count_r.cnt.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + if(field_storage.intr_block_rf.error2_intr_count_incr_r.pulse.value) begin // increment + if(((33)'(next_c) + 32'h1) > 32'hffffffff) begin // up-counter saturated + next_c = 32'hffffffff; + end else begin + next_c = next_c + 32'h1; + end + load_next_c = '1; + end + field_combo.intr_block_rf.error2_intr_count_r.cnt.incrthreshold = (field_storage.intr_block_rf.error2_intr_count_r.cnt.value >= 32'hffffffff); + field_combo.intr_block_rf.error2_intr_count_r.cnt.incrsaturate = (field_storage.intr_block_rf.error2_intr_count_r.cnt.value >= 32'hffffffff); + if(next_c > 32'hffffffff) begin + next_c = 32'hffffffff; + load_next_c = '1; + end + field_combo.intr_block_rf.error2_intr_count_r.cnt.next = next_c; + field_combo.intr_block_rf.error2_intr_count_r.cnt.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.error_reset_b) begin + if(~hwif_in.error_reset_b) begin + field_storage.intr_block_rf.error2_intr_count_r.cnt.value <= 32'h0; + end else if(field_combo.intr_block_rf.error2_intr_count_r.cnt.load_next) begin + field_storage.intr_block_rf.error2_intr_count_r.cnt.value <= field_combo.intr_block_rf.error2_intr_count_r.cnt.next; + end + end + // Field: sha256_reg.intr_block_rf.error3_intr_count_r.cnt + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error3_intr_count_r.cnt.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error3_intr_count_r && decoded_req_is_wr) begin // SW write + next_c = (field_storage.intr_block_rf.error3_intr_count_r.cnt.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + if(field_storage.intr_block_rf.error3_intr_count_incr_r.pulse.value) begin // increment + if(((33)'(next_c) + 32'h1) > 32'hffffffff) begin // up-counter saturated + next_c = 32'hffffffff; + end else begin + next_c = next_c + 32'h1; + end + load_next_c = '1; + end + field_combo.intr_block_rf.error3_intr_count_r.cnt.incrthreshold = (field_storage.intr_block_rf.error3_intr_count_r.cnt.value >= 32'hffffffff); + field_combo.intr_block_rf.error3_intr_count_r.cnt.incrsaturate = (field_storage.intr_block_rf.error3_intr_count_r.cnt.value >= 32'hffffffff); + if(next_c > 32'hffffffff) begin + next_c = 32'hffffffff; + load_next_c = '1; + end + field_combo.intr_block_rf.error3_intr_count_r.cnt.next = next_c; + field_combo.intr_block_rf.error3_intr_count_r.cnt.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.error_reset_b) begin + if(~hwif_in.error_reset_b) begin + field_storage.intr_block_rf.error3_intr_count_r.cnt.value <= 32'h0; + end else if(field_combo.intr_block_rf.error3_intr_count_r.cnt.load_next) begin + field_storage.intr_block_rf.error3_intr_count_r.cnt.value <= field_combo.intr_block_rf.error3_intr_count_r.cnt.next; + end + end + // Field: sha256_reg.intr_block_rf.notif_cmd_done_intr_count_r.cnt + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_cmd_done_intr_count_r.cnt.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.notif_cmd_done_intr_count_r && decoded_req_is_wr) begin // SW write + next_c = (field_storage.intr_block_rf.notif_cmd_done_intr_count_r.cnt.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + if(field_storage.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.value) begin // increment + if(((33)'(next_c) + 32'h1) > 32'hffffffff) begin // up-counter saturated + next_c = 32'hffffffff; + end else begin + next_c = next_c + 32'h1; + end + load_next_c = '1; + end + field_combo.intr_block_rf.notif_cmd_done_intr_count_r.cnt.incrthreshold = (field_storage.intr_block_rf.notif_cmd_done_intr_count_r.cnt.value >= 32'hffffffff); + field_combo.intr_block_rf.notif_cmd_done_intr_count_r.cnt.incrsaturate = (field_storage.intr_block_rf.notif_cmd_done_intr_count_r.cnt.value >= 32'hffffffff); + if(next_c > 32'hffffffff) begin + next_c = 32'hffffffff; + load_next_c = '1; + end + field_combo.intr_block_rf.notif_cmd_done_intr_count_r.cnt.next = next_c; + field_combo.intr_block_rf.notif_cmd_done_intr_count_r.cnt.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.notif_cmd_done_intr_count_r.cnt.value <= 32'h0; + end else if(field_combo.intr_block_rf.notif_cmd_done_intr_count_r.cnt.load_next) begin + field_storage.intr_block_rf.notif_cmd_done_intr_count_r.cnt.value <= field_combo.intr_block_rf.notif_cmd_done_intr_count_r.cnt.next; + end + end + // Field: sha256_reg.intr_block_rf.error0_intr_count_incr_r.pulse + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error0_intr_count_incr_r.pulse.value; + load_next_c = '0; + if(field_storage.intr_block_rf.error_intr_trig_r.error0_trig.value) begin // HW Write - we + next_c = field_storage.intr_block_rf.error_intr_trig_r.error0_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.error_internal_intr_r.error0_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end + if(field_storage.intr_block_rf.error0_intr_count_incr_r.pulse.value) begin // decrement + field_combo.intr_block_rf.error0_intr_count_incr_r.pulse.underflow = (next_c < (1'h1)); + next_c = next_c - 1'h1; + load_next_c = '1; + end else begin + field_combo.intr_block_rf.error0_intr_count_incr_r.pulse.underflow = '0; + end + field_combo.intr_block_rf.error0_intr_count_incr_r.pulse.decrthreshold = (field_storage.intr_block_rf.error0_intr_count_incr_r.pulse.value <= 1'd0); + field_combo.intr_block_rf.error0_intr_count_incr_r.pulse.next = next_c; + field_combo.intr_block_rf.error0_intr_count_incr_r.pulse.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.error0_intr_count_incr_r.pulse.value <= 1'h0; + end else if(field_combo.intr_block_rf.error0_intr_count_incr_r.pulse.load_next) begin + field_storage.intr_block_rf.error0_intr_count_incr_r.pulse.value <= field_combo.intr_block_rf.error0_intr_count_incr_r.pulse.next; + end + end + // Field: sha256_reg.intr_block_rf.error1_intr_count_incr_r.pulse + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error1_intr_count_incr_r.pulse.value; + load_next_c = '0; + if(field_storage.intr_block_rf.error_intr_trig_r.error1_trig.value) begin // HW Write - we + next_c = field_storage.intr_block_rf.error_intr_trig_r.error1_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.error_internal_intr_r.error1_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end + if(field_storage.intr_block_rf.error1_intr_count_incr_r.pulse.value) begin // decrement + field_combo.intr_block_rf.error1_intr_count_incr_r.pulse.underflow = (next_c < (1'h1)); + next_c = next_c - 1'h1; + load_next_c = '1; + end else begin + field_combo.intr_block_rf.error1_intr_count_incr_r.pulse.underflow = '0; + end + field_combo.intr_block_rf.error1_intr_count_incr_r.pulse.decrthreshold = (field_storage.intr_block_rf.error1_intr_count_incr_r.pulse.value <= 1'd0); + field_combo.intr_block_rf.error1_intr_count_incr_r.pulse.next = next_c; + field_combo.intr_block_rf.error1_intr_count_incr_r.pulse.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.error1_intr_count_incr_r.pulse.value <= 1'h0; + end else if(field_combo.intr_block_rf.error1_intr_count_incr_r.pulse.load_next) begin + field_storage.intr_block_rf.error1_intr_count_incr_r.pulse.value <= field_combo.intr_block_rf.error1_intr_count_incr_r.pulse.next; + end + end + // Field: sha256_reg.intr_block_rf.error2_intr_count_incr_r.pulse + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error2_intr_count_incr_r.pulse.value; + load_next_c = '0; + if(field_storage.intr_block_rf.error_intr_trig_r.error2_trig.value) begin // HW Write - we + next_c = field_storage.intr_block_rf.error_intr_trig_r.error2_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.error_internal_intr_r.error2_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end + if(field_storage.intr_block_rf.error2_intr_count_incr_r.pulse.value) begin // decrement + field_combo.intr_block_rf.error2_intr_count_incr_r.pulse.underflow = (next_c < (1'h1)); + next_c = next_c - 1'h1; + load_next_c = '1; + end else begin + field_combo.intr_block_rf.error2_intr_count_incr_r.pulse.underflow = '0; + end + field_combo.intr_block_rf.error2_intr_count_incr_r.pulse.decrthreshold = (field_storage.intr_block_rf.error2_intr_count_incr_r.pulse.value <= 1'd0); + field_combo.intr_block_rf.error2_intr_count_incr_r.pulse.next = next_c; + field_combo.intr_block_rf.error2_intr_count_incr_r.pulse.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.error2_intr_count_incr_r.pulse.value <= 1'h0; + end else if(field_combo.intr_block_rf.error2_intr_count_incr_r.pulse.load_next) begin + field_storage.intr_block_rf.error2_intr_count_incr_r.pulse.value <= field_combo.intr_block_rf.error2_intr_count_incr_r.pulse.next; + end + end + // Field: sha256_reg.intr_block_rf.error3_intr_count_incr_r.pulse + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error3_intr_count_incr_r.pulse.value; + load_next_c = '0; + if(field_storage.intr_block_rf.error_intr_trig_r.error3_trig.value) begin // HW Write - we + next_c = field_storage.intr_block_rf.error_intr_trig_r.error3_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.error_internal_intr_r.error3_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end + if(field_storage.intr_block_rf.error3_intr_count_incr_r.pulse.value) begin // decrement + field_combo.intr_block_rf.error3_intr_count_incr_r.pulse.underflow = (next_c < (1'h1)); + next_c = next_c - 1'h1; + load_next_c = '1; + end else begin + field_combo.intr_block_rf.error3_intr_count_incr_r.pulse.underflow = '0; + end + field_combo.intr_block_rf.error3_intr_count_incr_r.pulse.decrthreshold = (field_storage.intr_block_rf.error3_intr_count_incr_r.pulse.value <= 1'd0); + field_combo.intr_block_rf.error3_intr_count_incr_r.pulse.next = next_c; + field_combo.intr_block_rf.error3_intr_count_incr_r.pulse.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.error3_intr_count_incr_r.pulse.value <= 1'h0; + end else if(field_combo.intr_block_rf.error3_intr_count_incr_r.pulse.load_next) begin + field_storage.intr_block_rf.error3_intr_count_incr_r.pulse.value <= field_combo.intr_block_rf.error3_intr_count_incr_r.pulse.next; + end + end + // Field: sha256_reg.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.value; + load_next_c = '0; + if(field_storage.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.value) begin // HW Write - we + next_c = field_storage.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end + if(field_storage.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.value) begin // decrement + field_combo.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.underflow = (next_c < (1'h1)); + next_c = next_c - 1'h1; + load_next_c = '1; + end else begin + field_combo.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.underflow = '0; + end + field_combo.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.decrthreshold = (field_storage.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.value <= 1'd0); + field_combo.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.next = next_c; + field_combo.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.value <= 1'h0; + end else if(field_combo.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.load_next) begin + field_storage.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.value <= field_combo.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.next; + end + end + + //-------------------------------------------------------------------------- + // Write response + //-------------------------------------------------------------------------- + assign cpuif_wr_ack = decoded_req & decoded_req_is_wr; + // Writes are always granted with no error response + assign cpuif_wr_err = '0; + + //-------------------------------------------------------------------------- + // Readback + //-------------------------------------------------------------------------- + + logic readback_err; + logic readback_done; + logic [31:0] readback_data; + + // Assign readback values to a flattened array + logic [32-1:0][31:0] readback_array; + for(genvar i0=0; i0<2; i0++) begin + assign readback_array[i0*1 + 0][31:0] = (decoded_reg_strb.SHA256_NAME[i0] && !decoded_req_is_wr) ? hwif_in.SHA256_NAME[i0].NAME.next : '0; + end + for(genvar i0=0; i0<2; i0++) begin + assign readback_array[i0*1 + 2][31:0] = (decoded_reg_strb.SHA256_VERSION[i0] && !decoded_req_is_wr) ? hwif_in.SHA256_VERSION[i0].VERSION.next : '0; + end + assign readback_array[4][0:0] = (decoded_reg_strb.SHA256_STATUS && !decoded_req_is_wr) ? hwif_in.SHA256_STATUS.READY.next : '0; + assign readback_array[4][1:1] = (decoded_reg_strb.SHA256_STATUS && !decoded_req_is_wr) ? hwif_in.SHA256_STATUS.VALID.next : '0; + assign readback_array[4][2:2] = (decoded_reg_strb.SHA256_STATUS && !decoded_req_is_wr) ? hwif_in.SHA256_STATUS.WNTZ_BUSY.next : '0; + assign readback_array[4][31:3] = '0; + for(genvar i0=0; i0<8; i0++) begin + assign readback_array[i0*1 + 5][31:0] = (decoded_reg_strb.SHA256_DIGEST[i0] && !decoded_req_is_wr) ? field_storage.SHA256_DIGEST[i0].DIGEST.value : '0; + end + assign readback_array[13][0:0] = (decoded_reg_strb.intr_block_rf.global_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.global_intr_en_r.error_en.value : '0; + assign readback_array[13][1:1] = (decoded_reg_strb.intr_block_rf.global_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.global_intr_en_r.notif_en.value : '0; + assign readback_array[13][31:2] = '0; + assign readback_array[14][0:0] = (decoded_reg_strb.intr_block_rf.error_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_en_r.error0_en.value : '0; + assign readback_array[14][1:1] = (decoded_reg_strb.intr_block_rf.error_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_en_r.error1_en.value : '0; + assign readback_array[14][2:2] = (decoded_reg_strb.intr_block_rf.error_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_en_r.error2_en.value : '0; + assign readback_array[14][3:3] = (decoded_reg_strb.intr_block_rf.error_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_en_r.error3_en.value : '0; + assign readback_array[14][31:4] = '0; + assign readback_array[15][0:0] = (decoded_reg_strb.intr_block_rf.notif_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_intr_en_r.notif_cmd_done_en.value : '0; + assign readback_array[15][31:1] = '0; + assign readback_array[16][0:0] = (decoded_reg_strb.intr_block_rf.error_global_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_global_intr_r.agg_sts.value : '0; + assign readback_array[16][31:1] = '0; + assign readback_array[17][0:0] = (decoded_reg_strb.intr_block_rf.notif_global_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_global_intr_r.agg_sts.value : '0; + assign readback_array[17][31:1] = '0; + assign readback_array[18][0:0] = (decoded_reg_strb.intr_block_rf.error_internal_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_internal_intr_r.error0_sts.value : '0; + assign readback_array[18][1:1] = (decoded_reg_strb.intr_block_rf.error_internal_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_internal_intr_r.error1_sts.value : '0; + assign readback_array[18][2:2] = (decoded_reg_strb.intr_block_rf.error_internal_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_internal_intr_r.error2_sts.value : '0; + assign readback_array[18][3:3] = (decoded_reg_strb.intr_block_rf.error_internal_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_internal_intr_r.error3_sts.value : '0; + assign readback_array[18][31:4] = '0; + assign readback_array[19][0:0] = (decoded_reg_strb.intr_block_rf.notif_internal_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.value : '0; + assign readback_array[19][31:1] = '0; + assign readback_array[20][0:0] = (decoded_reg_strb.intr_block_rf.error_intr_trig_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_trig_r.error0_trig.value : '0; + assign readback_array[20][1:1] = (decoded_reg_strb.intr_block_rf.error_intr_trig_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_trig_r.error1_trig.value : '0; + assign readback_array[20][2:2] = (decoded_reg_strb.intr_block_rf.error_intr_trig_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_trig_r.error2_trig.value : '0; + assign readback_array[20][3:3] = (decoded_reg_strb.intr_block_rf.error_intr_trig_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_trig_r.error3_trig.value : '0; + assign readback_array[20][31:4] = '0; + assign readback_array[21][0:0] = (decoded_reg_strb.intr_block_rf.notif_intr_trig_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.value : '0; + assign readback_array[21][31:1] = '0; + assign readback_array[22][31:0] = (decoded_reg_strb.intr_block_rf.error0_intr_count_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error0_intr_count_r.cnt.value : '0; + assign readback_array[23][31:0] = (decoded_reg_strb.intr_block_rf.error1_intr_count_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error1_intr_count_r.cnt.value : '0; + assign readback_array[24][31:0] = (decoded_reg_strb.intr_block_rf.error2_intr_count_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error2_intr_count_r.cnt.value : '0; + assign readback_array[25][31:0] = (decoded_reg_strb.intr_block_rf.error3_intr_count_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error3_intr_count_r.cnt.value : '0; + assign readback_array[26][31:0] = (decoded_reg_strb.intr_block_rf.notif_cmd_done_intr_count_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_cmd_done_intr_count_r.cnt.value : '0; + assign readback_array[27][0:0] = (decoded_reg_strb.intr_block_rf.error0_intr_count_incr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error0_intr_count_incr_r.pulse.value : '0; + assign readback_array[27][31:1] = '0; + assign readback_array[28][0:0] = (decoded_reg_strb.intr_block_rf.error1_intr_count_incr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error1_intr_count_incr_r.pulse.value : '0; + assign readback_array[28][31:1] = '0; + assign readback_array[29][0:0] = (decoded_reg_strb.intr_block_rf.error2_intr_count_incr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error2_intr_count_incr_r.pulse.value : '0; + assign readback_array[29][31:1] = '0; + assign readback_array[30][0:0] = (decoded_reg_strb.intr_block_rf.error3_intr_count_incr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error3_intr_count_incr_r.pulse.value : '0; + assign readback_array[30][31:1] = '0; + assign readback_array[31][0:0] = (decoded_reg_strb.intr_block_rf.notif_cmd_done_intr_count_incr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.value : '0; + assign readback_array[31][31:1] = '0; + + // Reduce the array + always_comb begin + automatic logic [31:0] readback_data_var; + readback_done = decoded_req & ~decoded_req_is_wr; + readback_err = '0; + readback_data_var = '0; + for(int i=0; i<32; i++) readback_data_var |= readback_array[i]; + readback_data = readback_data_var; + end + + assign cpuif_rd_ack = readback_done; + assign cpuif_rd_data = readback_data; + assign cpuif_rd_err = readback_err; + +`CALIPTRA_ASSERT_KNOWN(ERR_HWIF_IN, hwif_in, clk, !hwif_in.error_reset_b) + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/sha256_reg_pkg.sv b/designs/Caliptra/src/caliptra-rtl/sha256_reg_pkg.sv new file mode 100644 index 0000000..07edcad --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/sha256_reg_pkg.sv @@ -0,0 +1,185 @@ +// Generated by PeakRDL-regblock - A free and open-source SystemVerilog generator +// https://github.com/SystemRDL/PeakRDL-regblock + +package sha256_reg_pkg; + + localparam SHA256_REG_DATA_WIDTH = 32; + localparam SHA256_REG_MIN_ADDR_WIDTH = 12; + + typedef struct packed{ + logic [31:0] next; + } sha256_reg__SHA256_NAME__NAME__in_t; + + typedef struct packed{ + sha256_reg__SHA256_NAME__NAME__in_t NAME; + } sha256_reg__SHA256_NAME__in_t; + + typedef struct packed{ + logic [31:0] next; + } sha256_reg__SHA256_VERSION__VERSION__in_t; + + typedef struct packed{ + sha256_reg__SHA256_VERSION__VERSION__in_t VERSION; + } sha256_reg__SHA256_VERSION__in_t; + + typedef struct packed{ + logic next; + } sha256_reg__SHA256_STATUS__READY__in_t; + + typedef struct packed{ + logic next; + } sha256_reg__SHA256_STATUS__VALID__in_t; + + typedef struct packed{ + logic next; + } sha256_reg__SHA256_STATUS__WNTZ_BUSY__in_t; + + typedef struct packed{ + sha256_reg__SHA256_STATUS__READY__in_t READY; + sha256_reg__SHA256_STATUS__VALID__in_t VALID; + sha256_reg__SHA256_STATUS__WNTZ_BUSY__in_t WNTZ_BUSY; + } sha256_reg__SHA256_STATUS__in_t; + + typedef struct packed{ + logic hwclr; + } sha256_reg__SHA256_BLOCK__BLOCK__in_t; + + typedef struct packed{ + sha256_reg__SHA256_BLOCK__BLOCK__in_t BLOCK; + } sha256_reg__SHA256_BLOCK__in_t; + + typedef struct packed{ + logic [31:0] next; + logic hwclr; + } sha256_reg__SHA256_DIGEST__DIGEST__in_t; + + typedef struct packed{ + sha256_reg__SHA256_DIGEST__DIGEST__in_t DIGEST; + } sha256_reg__SHA256_DIGEST__in_t; + + typedef struct packed{ + logic hwset; + } sha256_reg__error_intr_t_error0_sts_28545624_error1_sts_40e0d3e1_error2_sts_b1cf2205_error3_sts_74a35378__error0_sts_enable_528ccada_next_b1018582_resetsignal_939e99d4__in_t; + + typedef struct packed{ + logic hwset; + } sha256_reg__error_intr_t_error0_sts_28545624_error1_sts_40e0d3e1_error2_sts_b1cf2205_error3_sts_74a35378__error1_sts_enable_938cafef_next_f460eb81_resetsignal_939e99d4__in_t; + + typedef struct packed{ + logic hwset; + } sha256_reg__error_intr_t_error0_sts_28545624_error1_sts_40e0d3e1_error2_sts_b1cf2205_error3_sts_74a35378__error2_sts_enable_0dacf7a6_next_4b5b9e74_resetsignal_939e99d4__in_t; + + typedef struct packed{ + logic hwset; + } sha256_reg__error_intr_t_error0_sts_28545624_error1_sts_40e0d3e1_error2_sts_b1cf2205_error3_sts_74a35378__error3_sts_enable_fc3af94b_next_c3125d40_resetsignal_939e99d4__in_t; + + typedef struct packed{ + sha256_reg__error_intr_t_error0_sts_28545624_error1_sts_40e0d3e1_error2_sts_b1cf2205_error3_sts_74a35378__error0_sts_enable_528ccada_next_b1018582_resetsignal_939e99d4__in_t error0_sts; + sha256_reg__error_intr_t_error0_sts_28545624_error1_sts_40e0d3e1_error2_sts_b1cf2205_error3_sts_74a35378__error1_sts_enable_938cafef_next_f460eb81_resetsignal_939e99d4__in_t error1_sts; + sha256_reg__error_intr_t_error0_sts_28545624_error1_sts_40e0d3e1_error2_sts_b1cf2205_error3_sts_74a35378__error2_sts_enable_0dacf7a6_next_4b5b9e74_resetsignal_939e99d4__in_t error2_sts; + sha256_reg__error_intr_t_error0_sts_28545624_error1_sts_40e0d3e1_error2_sts_b1cf2205_error3_sts_74a35378__error3_sts_enable_fc3af94b_next_c3125d40_resetsignal_939e99d4__in_t error3_sts; + } sha256_reg__error_intr_t_error0_sts_28545624_error1_sts_40e0d3e1_error2_sts_b1cf2205_error3_sts_74a35378__in_t; + + typedef struct packed{ + logic hwset; + } sha256_reg__notif_intr_t_notif_cmd_done_sts_1c68637e__notif_cmd_done_sts_enable_dabe0b8b_next_540fa3b7__in_t; + + typedef struct packed{ + sha256_reg__notif_intr_t_notif_cmd_done_sts_1c68637e__notif_cmd_done_sts_enable_dabe0b8b_next_540fa3b7__in_t notif_cmd_done_sts; + } sha256_reg__notif_intr_t_notif_cmd_done_sts_1c68637e__in_t; + + typedef struct packed{ + sha256_reg__error_intr_t_error0_sts_28545624_error1_sts_40e0d3e1_error2_sts_b1cf2205_error3_sts_74a35378__in_t error_internal_intr_r; + sha256_reg__notif_intr_t_notif_cmd_done_sts_1c68637e__in_t notif_internal_intr_r; + } sha256_reg__intr_block_t__in_t; + + typedef struct packed{ + logic reset_b; + logic error_reset_b; + logic sha256_ready; + sha256_reg__SHA256_NAME__in_t [2-1:0]SHA256_NAME; + sha256_reg__SHA256_VERSION__in_t [2-1:0]SHA256_VERSION; + sha256_reg__SHA256_STATUS__in_t SHA256_STATUS; + sha256_reg__SHA256_BLOCK__in_t [16-1:0]SHA256_BLOCK; + sha256_reg__SHA256_DIGEST__in_t [8-1:0]SHA256_DIGEST; + sha256_reg__intr_block_t__in_t intr_block_rf; + } sha256_reg__in_t; + + typedef struct packed{ + logic value; + } sha256_reg__SHA256_CTRL__INIT__out_t; + + typedef struct packed{ + logic value; + } sha256_reg__SHA256_CTRL__NEXT__out_t; + + typedef struct packed{ + logic value; + } sha256_reg__SHA256_CTRL__MODE__out_t; + + typedef struct packed{ + logic value; + } sha256_reg__SHA256_CTRL__ZEROIZE__out_t; + + typedef struct packed{ + logic value; + } sha256_reg__SHA256_CTRL__WNTZ_MODE__out_t; + + typedef struct packed{ + logic [3:0] value; + } sha256_reg__SHA256_CTRL__WNTZ_W__out_t; + + typedef struct packed{ + logic value; + } sha256_reg__SHA256_CTRL__WNTZ_N_MODE__out_t; + + typedef struct packed{ + sha256_reg__SHA256_CTRL__INIT__out_t INIT; + sha256_reg__SHA256_CTRL__NEXT__out_t NEXT; + sha256_reg__SHA256_CTRL__MODE__out_t MODE; + sha256_reg__SHA256_CTRL__ZEROIZE__out_t ZEROIZE; + sha256_reg__SHA256_CTRL__WNTZ_MODE__out_t WNTZ_MODE; + sha256_reg__SHA256_CTRL__WNTZ_W__out_t WNTZ_W; + sha256_reg__SHA256_CTRL__WNTZ_N_MODE__out_t WNTZ_N_MODE; + } sha256_reg__SHA256_CTRL__out_t; + + typedef struct packed{ + logic [31:0] value; + } sha256_reg__SHA256_BLOCK__BLOCK__out_t; + + typedef struct packed{ + sha256_reg__SHA256_BLOCK__BLOCK__out_t BLOCK; + } sha256_reg__SHA256_BLOCK__out_t; + + typedef struct packed{ + logic intr; + } sha256_reg__global_intr_t_agg_sts_dd3dcf0a__out_t; + + typedef struct packed{ + logic intr; + } sha256_reg__global_intr_t_agg_sts_e6399b4a__out_t; + + typedef struct packed{ + logic intr; + } sha256_reg__error_intr_t_error0_sts_28545624_error1_sts_40e0d3e1_error2_sts_b1cf2205_error3_sts_74a35378__out_t; + + typedef struct packed{ + logic intr; + } sha256_reg__notif_intr_t_notif_cmd_done_sts_1c68637e__out_t; + + typedef struct packed{ + sha256_reg__global_intr_t_agg_sts_dd3dcf0a__out_t error_global_intr_r; + sha256_reg__global_intr_t_agg_sts_e6399b4a__out_t notif_global_intr_r; + sha256_reg__error_intr_t_error0_sts_28545624_error1_sts_40e0d3e1_error2_sts_b1cf2205_error3_sts_74a35378__out_t error_internal_intr_r; + sha256_reg__notif_intr_t_notif_cmd_done_sts_1c68637e__out_t notif_internal_intr_r; + } sha256_reg__intr_block_t__out_t; + + typedef struct packed{ + sha256_reg__SHA256_CTRL__out_t SHA256_CTRL; + sha256_reg__SHA256_BLOCK__out_t [16-1:0]SHA256_BLOCK; + sha256_reg__intr_block_t__out_t intr_block_rf; + } sha256_reg__out_t; + + localparam SHA256_REG_ADDR_WIDTH = 32'd12; + +endpackage \ No newline at end of file diff --git a/designs/Caliptra/src/caliptra-rtl/sha256_w_mem.v b/designs/Caliptra/src/caliptra-rtl/sha256_w_mem.v new file mode 100644 index 0000000..db24cd1 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/sha256_w_mem.v @@ -0,0 +1,279 @@ +//====================================================================== +// +// sha256_w_mem_regs.v +// ------------------- +// The W memory. This version uses 16 32-bit registers as a sliding +// window to generate the 64 words. +// +// +// Author: Joachim Strombergson +// Copyright (c) 2013, Secworks Sweden AB +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or +// without modification, are permitted provided that the following +// conditions are met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in +// the documentation and/or other materials provided with the +// distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +//====================================================================== + +module sha256_w_mem( + // Clock and reset. + input wire clk, + input wire reset_n, + input wire zeroize, + // Data port. + input wire [511 : 0] block_msg, + // Control. + input wire init_cmd, + input wire next_cmd, + output wire [31 : 0] w_val + ); + + + //---------------------------------------------------------------- + // Registers including update variables and write enable. + //---------------------------------------------------------------- + reg [31 : 0] w_mem [0 : 15]; + reg [31 : 0] w_mem00_new; + reg [31 : 0] w_mem01_new; + reg [31 : 0] w_mem02_new; + reg [31 : 0] w_mem03_new; + reg [31 : 0] w_mem04_new; + reg [31 : 0] w_mem05_new; + reg [31 : 0] w_mem06_new; + reg [31 : 0] w_mem07_new; + reg [31 : 0] w_mem08_new; + reg [31 : 0] w_mem09_new; + reg [31 : 0] w_mem10_new; + reg [31 : 0] w_mem11_new; + reg [31 : 0] w_mem12_new; + reg [31 : 0] w_mem13_new; + reg [31 : 0] w_mem14_new; + reg [31 : 0] w_mem15_new; + reg w_mem_we; + + reg [5 : 0] w_ctr_reg; + reg [5 : 0] w_ctr_new; + reg w_ctr_we; + + + //---------------------------------------------------------------- + // Wires. + //---------------------------------------------------------------- + reg [31 : 0] w_tmp; + reg [31 : 0] w_new; + + + //---------------------------------------------------------------- + // Concurrent connectivity for ports etc. + //---------------------------------------------------------------- + assign w_val = w_tmp; + + + //---------------------------------------------------------------- + // reg_update + // Update functionality for all registers in the core. + // All registers are positive edge triggered with synchronous + // active low reset. All registers have write enable. + //---------------------------------------------------------------- + always @ (posedge clk or negedge reset_n) + begin : reg_update + integer ii; + + if (!reset_n) + begin + for (ii = 0 ; ii < 16 ; ii = ii + 1) + w_mem[ii] <= 32'h0; + + w_ctr_reg <= 6'h0; + end + else if (zeroize) + begin + for (ii = 0 ; ii < 16 ; ii = ii + 1) + w_mem[ii] <= 32'h0; + + w_ctr_reg <= 6'h0; + end + else + begin + if (w_mem_we) + begin + w_mem[00] <= w_mem00_new; + w_mem[01] <= w_mem01_new; + w_mem[02] <= w_mem02_new; + w_mem[03] <= w_mem03_new; + w_mem[04] <= w_mem04_new; + w_mem[05] <= w_mem05_new; + w_mem[06] <= w_mem06_new; + w_mem[07] <= w_mem07_new; + w_mem[08] <= w_mem08_new; + w_mem[09] <= w_mem09_new; + w_mem[10] <= w_mem10_new; + w_mem[11] <= w_mem11_new; + w_mem[12] <= w_mem12_new; + w_mem[13] <= w_mem13_new; + w_mem[14] <= w_mem14_new; + w_mem[15] <= w_mem15_new; + end + + if (w_ctr_we) + w_ctr_reg <= w_ctr_new; + end + end // reg_update + + + //---------------------------------------------------------------- + // select_w + // + // Mux for the external read operation. This is where we exract + // the W variable. + //---------------------------------------------------------------- + always @* + begin : select_w + if (w_ctr_reg < 16) + w_tmp = w_mem[w_ctr_reg[3 : 0]]; + else + w_tmp = w_new; + end // select_w + + + //---------------------------------------------------------------- + // w_new_logic + // + // Logic that calculates the next value to be inserted into + // the sliding window of the memory. + //---------------------------------------------------------------- + always @* + begin : w_mem_update_logic + reg [31 : 0] w_0; + reg [31 : 0] w_1; + reg [31 : 0] w_9; + reg [31 : 0] w_14; + reg [31 : 0] d0; + reg [31 : 0] d1; + + w_mem00_new = 32'h0; + w_mem01_new = 32'h0; + w_mem02_new = 32'h0; + w_mem03_new = 32'h0; + w_mem04_new = 32'h0; + w_mem05_new = 32'h0; + w_mem06_new = 32'h0; + w_mem07_new = 32'h0; + w_mem08_new = 32'h0; + w_mem09_new = 32'h0; + w_mem10_new = 32'h0; + w_mem11_new = 32'h0; + w_mem12_new = 32'h0; + w_mem13_new = 32'h0; + w_mem14_new = 32'h0; + w_mem15_new = 32'h0; + w_mem_we = 0; + + w_0 = w_mem[0]; + w_1 = w_mem[1]; + w_9 = w_mem[9]; + w_14 = w_mem[14]; + + d0 = {w_1[6 : 0], w_1[31 : 7]} ^ + {w_1[17 : 0], w_1[31 : 18]} ^ + {3'b000, w_1[31 : 3]}; + + d1 = {w_14[16 : 0], w_14[31 : 17]} ^ + {w_14[18 : 0], w_14[31 : 19]} ^ + {10'b0000000000, w_14[31 : 10]}; + + w_new = d1 + w_9 + d0 + w_0; + + if (init_cmd) + begin + w_mem00_new = block_msg[511 : 480]; + w_mem01_new = block_msg[479 : 448]; + w_mem02_new = block_msg[447 : 416]; + w_mem03_new = block_msg[415 : 384]; + w_mem04_new = block_msg[383 : 352]; + w_mem05_new = block_msg[351 : 320]; + w_mem06_new = block_msg[319 : 288]; + w_mem07_new = block_msg[287 : 256]; + w_mem08_new = block_msg[255 : 224]; + w_mem09_new = block_msg[223 : 192]; + w_mem10_new = block_msg[191 : 160]; + w_mem11_new = block_msg[159 : 128]; + w_mem12_new = block_msg[127 : 96]; + w_mem13_new = block_msg[95 : 64]; + w_mem14_new = block_msg[63 : 32]; + w_mem15_new = block_msg[31 : 0]; + w_mem_we = 1; + end + + if (next_cmd && (w_ctr_reg > 15)) + begin + w_mem00_new = w_mem[01]; + w_mem01_new = w_mem[02]; + w_mem02_new = w_mem[03]; + w_mem03_new = w_mem[04]; + w_mem04_new = w_mem[05]; + w_mem05_new = w_mem[06]; + w_mem06_new = w_mem[07]; + w_mem07_new = w_mem[08]; + w_mem08_new = w_mem[09]; + w_mem09_new = w_mem[10]; + w_mem10_new = w_mem[11]; + w_mem11_new = w_mem[12]; + w_mem12_new = w_mem[13]; + w_mem13_new = w_mem[14]; + w_mem14_new = w_mem[15]; + w_mem15_new = w_new; + w_mem_we = 1; + end + end // w_mem_update_logic + + + //---------------------------------------------------------------- + // w_ctr + // W schedule adress counter. Counts from 0x10 to 0x3f and + // is used to expand the block into words. + //---------------------------------------------------------------- + always @* + begin : w_ctr + w_ctr_new = 6'h0; + w_ctr_we = 1'h0; + + if (init_cmd) + begin + w_ctr_new = 6'h0; + w_ctr_we = 1'h1; + end + + if (next_cmd) + begin + w_ctr_new = w_ctr_reg + 6'h01; + w_ctr_we = 1'h1; + end + end // w_ctr +endmodule // sha256_w_mem + +//====================================================================== +// sha256_w_mem.v +//====================================================================== diff --git a/designs/Caliptra/src/caliptra-rtl/sha3.sv b/designs/Caliptra/src/caliptra-rtl/sha3.sv new file mode 100644 index 0000000..521e785 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/sha3.sv @@ -0,0 +1,535 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// SHA3 core is a fully functional SHA3/SHAKE/cSHAKE hashing module. +// +// It instantiates a keccak_round with 1600 bits of the state. + +`include "caliptra_prim_assert.sv" + +module sha3 + import sha3_pkg::*; + import lc_ctrl_state_pkg::*; + import lc_ctrl_reg_pkg::*; + import lc_ctrl_pkg::*; +#( + // Enable Masked Keccak if 1 + parameter bit EnMasking = 0, + // derived parameter + localparam int Share = (EnMasking) ? 2 : 1 +) ( + input clk_i, + input rst_ni, + + // MSG interface + input msg_valid_i, + input [MsgWidth-1:0] msg_data_i [Share], + input [MsgStrbW-1:0] msg_strb_i, // one strobe for shares + output logic msg_ready_o, + + // Entropy interface + input rand_valid_i, + input rand_early_i, + input [StateW/2-1:0] rand_data_i, + input rand_aux_i, + output logic rand_update_o, + output logic rand_consumed_o, + + // N, S: Used in cSHAKE mode only + input [NSRegisterSize*8-1:0] ns_data_i, // See sha3_pkg for details + + // configurations + input sha3_mode_e mode_i, // see sha3pad for details + input keccak_strength_e strength_i, // see sha3pad for details + + // controls + input start_i, // see sha3pad for details + input process_i, // see sha3pad for details + + // run_i is a pulse signal to trigger the keccak_round manually by SW. + // It is used to run additional keccak_f after sponge absorbing is completed. + // See `keccak_run` signal + input run_i, + input caliptra_prim_mubi_pkg::mubi4_t done_i, // see sha3pad for details + + output caliptra_prim_mubi_pkg::mubi4_t absorbed_o, + output logic squeezing_o, + + // Indicate of one block processed. KMAC main state tracks the progression + // based on this signal. + output logic block_processed_o, + + output sha3_st_e sha3_fsm_o, + + // digest output + // This value is valid only after all absorbing process is completed. + // In invalid state, the output `state` will be zero to prevent information + // leakage. + output logic state_valid_o, + output logic [StateW-1:0] state_o [Share], + + // REQ/ACK interface for the Keccak core. This can be used to delay the + // processing e.g. to avoid power spikes at the chip level due to too many + // blocks being active simultaneously. + output logic run_req_o, + input run_ack_i, + + // Life cycle + input lc_ctrl_pkg::lc_tx_t lc_escalate_en_i, + + // error_o value is pushed to Error FIFO at KMAC/SHA3 top and reported to SW + output err_t error_o, + + // sparse_fsm_alert + output logic sparse_fsm_error_o, + + // counter error + output logic count_error_o, + + // error on rst_storage in Keccak + output logic keccak_storage_rst_error_o + +); + ///////////////// + // Definitions // + ///////////////// + + typedef enum logic[2:0] { + MuxGuard = 3'b 010, + MuxRelease = 3'b 101 + } state_mux_sel_e; + + ///////////// + // Signals // + ///////////// + + // State --> Digest + // State is exposed to the outside if the hashing process is completed. + logic state_valid; + logic [StateW-1:0] state [Share]; + logic [StateW-1:0] state_guarded [Share]; + + // State --> digest mux select signal + state_mux_sel_e mux_sel; + + // absorbed is a pulse signal that indicates sponge absorbing is done. + // After this, sha3 core allows software to manually run until squeezing + // is completed, which is the `done_i` pulse signal. + caliptra_prim_mubi_pkg::mubi4_t absorbed; + + // `squeezing` is a status indicator that SHA3 core is in sponge squeezing + // stage. In this stage, the state output is valid, and software can manually + // trigger keccak_round logic to get more digest outputs in case the output + // length is bigger than the block limit. + logic squeezing; + + // If process_i is received, the logic initiates the final absorbing process. + // While absorbing, the processing inticator is turned on. This signal is used + // to check if multiple process_i is received or not. + logic processing; + + // FSM variable + sha3_st_sparse_e st, st_d; + + // Keccak control signal (filtered by State Machine) + logic keccak_start, keccak_process; + caliptra_prim_mubi_pkg::mubi4_t keccak_done; + + // alert signals + logic round_count_error, msg_count_error; + assign count_error_o = round_count_error | msg_count_error; + + logic sha3_state_error; + logic keccak_round_state_error; + logic sha3pad_state_error; + + assign sparse_fsm_error_o = sha3_state_error | keccak_round_state_error | sha3pad_state_error; + + // Keccak rst_storage is asserted unexpectedly + logic keccak_storage_rst_error; + assign keccak_storage_rst_error_o = keccak_storage_rst_error; + + ///////////////// + // Connections // + ///////////////// + + logic keccak_valid; + logic [KeccakMsgAddrW-1:0] keccak_addr; + logic [MsgWidth-1:0] keccak_data [Share]; + logic keccak_ready; + + // Keccak round run signal can be controlled by sha3pad and also by software + // after all message feeding is done. it is mainly used for sponge squeezing + // operation after absorbing is completed when output length is longer than + // the block size. + logic keccak_run, sha3pad_keccak_run, sw_keccak_run; + logic keccak_run_req_d, keccak_run_req_q; + logic keccak_triggered_d, keccak_triggered_q; + logic keccak_complete; + + // Announce that we want to run the Keccak core and tell other blocks to go + // quiet. Keep holding the REQ until the Keccak core is done with the + // processing. The keccak_complete signal is received once the Keccak core + // is back in the Idle state and again susceptible to keccak_run. + assign run_req_o = keccak_run_req_d; + assign keccak_run_req_d = + sha3pad_keccak_run || sw_keccak_run ? 1'b 1 : + keccak_complete ? 1'b 0 : keccak_run_req_q; + + // Trigger the Keccak engine with a single pulse upon receiving the ACK. + assign keccak_run = run_req_o & run_ack_i & ~keccak_triggered_q; + assign keccak_triggered_d = + keccak_run ? 1'b 1 : + keccak_complete ? 1'b 0 : keccak_triggered_q; + + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + keccak_run_req_q <= 1'b 0; + keccak_triggered_q <= 1'b 0; + end else begin + keccak_run_req_q <= keccak_run_req_d; + keccak_triggered_q <= keccak_triggered_d; + end + end + + // Absorb pulse output : used to generate interrupts + // Latch absorbed signal as kmac_keymgr asserts `CmdDone` when it sees + // `absorbed` signal. When this signal goes out, the state is still in + // `StAbsorb`. Next state is `StSqueeze`. + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) absorbed_o <= caliptra_prim_mubi_pkg::MuBi4False; + else absorbed_o <= absorbed; + end + + // Squeezing output + assign squeezing_o = squeezing; + + // processing + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) processing <= 1'b 0; + else if (process_i) processing <= 1'b 1; + else if (caliptra_prim_mubi_pkg::mubi4_test_true_strict(absorbed)) begin + processing <= 1'b 0; + end + end + + assign block_processed_o = keccak_complete; + + // State connection + assign state_valid_o = state_valid; + assign state_o = state_guarded; + + assign sha3_fsm_o = sparse2logic(st); + + /////////////////// + // State Machine // + /////////////////// + + // State Register + `CALIPTRA_PRIM_FLOP_SPARSE_FSM(u_state_regs, st_d, st, sha3_st_sparse_e, StIdle_sparse) + + + // Next State and Output Logic + // Mainly the FSM controls the input signal access + // StIdle: only start_i signal is allowed + // StAbsorb: only process_i signal is allowed + // StSqueeze: only run_i, done_i signal is allowed + + always_comb begin + st_d = st; + + // default output values + keccak_start = 1'b 0; + keccak_process = 1'b 0; + sw_keccak_run = 1'b 0; + keccak_done = caliptra_prim_mubi_pkg::MuBi4False; + + squeezing = 1'b 0; + + state_valid = 1'b 0; + mux_sel = MuxGuard ; + + sha3_state_error = 1'b 0; + + unique case (st) + StIdle_sparse: begin + if (start_i) begin + st_d = StAbsorb_sparse; + + keccak_start = 1'b 1; + end else begin + st_d = StIdle_sparse; + end + end + + StAbsorb_sparse: begin + if (process_i && !processing) begin + st_d = StAbsorb_sparse; + + keccak_process = 1'b 1; + end else if (caliptra_prim_mubi_pkg::mubi4_test_true_strict(absorbed)) begin + st_d = StSqueeze_sparse; + end else begin + st_d = StAbsorb_sparse; + end + end + + StSqueeze_sparse: begin + state_valid = 1'b 1; + mux_sel = MuxRelease; // Expose state to register interface + + squeezing = 1'b 1; + + if (run_i) begin + st_d = StManualRun_sparse; + + sw_keccak_run = 1'b 1; + end else if (caliptra_prim_mubi_pkg::mubi4_test_true_strict(done_i)) begin + st_d = StFlush_sparse; + + keccak_done = done_i; + end else begin + st_d = StSqueeze_sparse; + end + end + + StManualRun_sparse: begin + if (keccak_complete) begin + st_d = StSqueeze_sparse; + end else begin + st_d = StManualRun_sparse; + end + end + + StFlush_sparse: begin + st_d = StIdle_sparse; + end + + StTerminalError_sparse: begin + //this state is terminal + st_d = StTerminalError_sparse; + sha3_state_error = 1'b 1; + end + + default: begin + st_d = StTerminalError_sparse; + sha3_state_error = 1'b 1; + end + endcase + + // SEC_CM: FSM.GLOBAL_ESC, FSM.LOCAL_ESC + // Unconditionally jump into the terminal error state + // if the life cycle controller triggers an escalation. + if (lc_ctrl_pkg::lc_tx_test_true_loose(lc_escalate_en_i)) begin + st_d = StTerminalError_sparse; + end + end + + ////////////// + // Datapath // + ////////////// + + // State --> Digest output + always_comb begin : state_guarded_mux + unique case (mux_sel) + MuxGuard: state_guarded = '{default: '0}; + MuxRelease: state_guarded = state; + default: state_guarded = '{default: '0}; // a valid, safe output + endcase + end + + + // Error Detecting + // ErrSha3SwControl: + // info[ 0]: start_i set + // info[ 1]: process_i set + // info[ 2]: run_i set + // info[ 3]: done_i set + // - Sw set process_i, run_i, done_i without start_i + + always_comb begin + error_o = '{valid: 1'b0, code: ErrNone, info: '0}; + + unique case (st) + StIdle_sparse: begin + if (process_i || run_i || + caliptra_prim_mubi_pkg::mubi4_test_true_loose(done_i)) begin + error_o = '{ + valid: 1'b 1, + code: ErrSha3SwControl, + info: 24'({done_i, run_i, process_i, start_i}) + }; + end + end + + StAbsorb_sparse: begin + if (start_i || run_i || caliptra_prim_mubi_pkg::mubi4_test_true_loose(done_i) + || (process_i && processing)) begin + error_o = '{ + valid: 1'b 1, + code: ErrSha3SwControl, + info: 24'({done_i, run_i, process_i, start_i}) + }; + end + end + + StSqueeze_sparse: begin + if (start_i || process_i) begin + error_o = '{ + valid: 1'b 1, + code: ErrSha3SwControl, + info: 24'({done_i, run_i, process_i, start_i}) + }; + end + end + + StManualRun_sparse: begin + if (start_i || process_i || run_i || + caliptra_prim_mubi_pkg::mubi4_test_true_loose(done_i)) begin + error_o = '{ + valid: 1'b 1, + code: ErrSha3SwControl, + info: 24'({done_i, run_i, process_i, start_i}) + }; + end + end + + StFlush_sparse: begin + if (start_i || process_i || run_i || + caliptra_prim_mubi_pkg::mubi4_test_true_loose(done_i)) begin + error_o = '{ + valid: 1'b 1, + code: ErrSha3SwControl, + info: 24'({done_i, run_i, process_i, start_i}) + }; + end + end + + default: begin + end + endcase + end + /////////////// + // Instances // + /////////////// + + // SHA3 pad logic + sha3pad #( + .EnMasking (EnMasking) + ) u_pad ( + .clk_i, + .rst_ni, + + // MSG_FIFO (or from KMAC core) + .msg_valid_i, + .msg_data_i, // [Share] + .msg_strb_i, + .msg_ready_o, + + // Encoded N, S + .ns_data_i, + + // output to keccak_round: message path + .keccak_valid_o (keccak_valid), + .keccak_addr_o (keccak_addr ), + .keccak_data_o (keccak_data ), // [Share] + .keccak_ready_i (keccak_ready), + + .keccak_run_o (sha3pad_keccak_run), + .keccak_complete_i (keccak_complete ), + + // configurations + .mode_i, + .strength_i, + + // LC + .lc_escalate_en_i (lc_escalate_en_i), + + // controls + .start_i (keccak_start), + .process_i (keccak_process), + .done_i (keccak_done), + + // output + .absorbed_o (absorbed), + .sparse_fsm_error_o (sha3pad_state_error), + .msg_count_error_o (msg_count_error) + ); + + // Keccak round logic + keccak_round #( + .Width (sha3_pkg::StateW), + .DInWidth (sha3_pkg::MsgWidth), + + .EnMasking (EnMasking) + ) u_keccak ( + .clk_i, + .rst_ni, + + .valid_i (keccak_valid), + .addr_i (keccak_addr ), + .data_i (keccak_data ), + .ready_o (keccak_ready), + + .rand_valid_i, + .rand_early_i, + .rand_data_i, + .rand_aux_i, + .rand_update_o, + .rand_consumed_o, + + .run_i (keccak_run ), + .complete_o (keccak_complete), + + .state_o (state), + + // LC + .lc_escalate_en_i (lc_escalate_en_i), + + .sparse_fsm_error_o (keccak_round_state_error), + .round_count_error_o (round_count_error), + .rst_storage_error_o (keccak_storage_rst_error), + + .clear_i (keccak_done) + ); + + //////////////// + // Assertions // + //////////////// + + // The Keccak core can only be active when the run REQ is ACKed. + `CALIPTRA_ASSERT(KeccakIdleWhenNoRunHs_A, + u_keccak.keccak_st inside {KeccakStActive, + KeccakStPhase1, + KeccakStPhase2Cycle1, + KeccakStPhase2Cycle2, + KeccakStPhase2Cycle3} |-> + run_req_o && run_ack_i) + + // Unknown check for case statement + `CALIPTRA_ASSERT(MuxSelKnown_A, mux_sel inside {MuxGuard, MuxRelease}) + `CALIPTRA_ASSERT(FsmKnown_A, st inside {StIdle_sparse, StAbsorb_sparse, StSqueeze_sparse, + StManualRun_sparse, StFlush_sparse, StTerminalError_sparse}) + + // `state` shall be 0 in invalid + if (EnMasking) begin: gen_chk_digest_masked + `CALIPTRA_ASSERT(StateZeroInvalid_A, !state_valid_o |-> ((|state_o[0]) | (|state_o[1])) == 1'b 0) + end else begin : gen_chk_digest_unmasked + `CALIPTRA_ASSERT(StateZeroInvalid_A, !state_valid_o |-> (|state_o[0]) == 1'b 0) + end + + // `state_valid_o` asserts only in between the completion and done + //`CALIPTRA_ASSERT(StateValidPeriod_A, state_valid_o |-> ) + + // skip the msg interface assertions as they are in sha3pad.sv + + // Software run signal happens in Squeezing stage + `CALIPTRA_ASSUME(SwRunInSqueezing_a, run_i |-> error_o.valid || (st == StSqueeze_sparse)) + + // If control received but not propagated into submodules, it is error condition + `CALIPTRA_ASSERT(ErrDetection_A, error_o.valid + |-> {start_i, process_i, run_i, done_i} + != {keccak_start, keccak_process, sw_keccak_run, keccak_done}) + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/sha3_ctrl.sv b/designs/Caliptra/src/caliptra-rtl/sha3_ctrl.sv new file mode 100644 index 0000000..33de991 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/sha3_ctrl.sv @@ -0,0 +1,313 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +// +//====================================================================== +// +// sha3_ctrl.sv +// -------- +// Wrapper for instantiation sha3 engine +// +// +// +//====================================================================== + +module sha3_ctrl + import sha3_param_pkg::*; + import sha3_reg_pkg::*; + import kmac_pkg::*; +#( + parameter AHB_DATA_WIDTH = 32, + parameter AHB_ADDR_WIDTH = 32 +) ( + // Clock and reset. + input wire clk, + input wire reset_n, + input wire cptra_pwrgood, + + input logic [AHB_ADDR_WIDTH-1:0] haddr_i, + input logic [AHB_DATA_WIDTH-1:0] hwdata_i, + input logic hsel_i, + input logic hwrite_i, + input logic hready_i, + input logic [1:0] htrans_i, + input logic [2:0] hsize_i, + + output logic hresp_o, + output logic hreadyout_o, + output logic [AHB_DATA_WIDTH-1:0] hrdata_o, + + output logic busy_o, + + output logic error_intr, + output logic notif_intr, + input logic debugUnlock_or_scan_mode_switch +); + +caliptra_tlul_pkg::tl_h2d_t adapter_to_kmac_tl; +caliptra_tlul_pkg::tl_d2h_t kmac_to_adapter_tl; + +logic ahb_dv; +logic ahb_hold; +logic ahb_write; +logic ahb_err; +logic [AHB_ADDR_WIDTH-1 : 0] ahb_addr; +logic [31 : 0] ahb_wdata; +logic [31 : 0] ahb_rdata; +logic [2 : 0] ahb_size; +logic [3 : 0] ahb_wstrb; + +logic clp_reg_dv; +logic clp_reg_write; +logic [31 : 0] clp_reg_rdata; +logic [31 : 0] clp_reg_wdata; +logic [caliptra_tlul_pkg::TL_AW-1 : 0] clp_reg_addr; + +sha3_reg__in_t hwif_in; +sha3_reg__out_t hwif_out; + +caliptra_prim_mubi_pkg::mubi4_t sha_idle; + +logic intr_kmac_done, intr_kmac_done_reg, intr_kmac_done_edge; +logic intr_fifo_empty, intr_fifo_empty_reg, intr_fifo_empty_edge; +logic intr_kmac_err, intr_kmac_err_reg, intr_kmac_err_edge; + +assign busy_o = caliptra_prim_mubi_pkg::mubi4_test_false_loose(sha_idle); + +//AHB interface +ahb_slv_sif #( + .AHB_ADDR_WIDTH(AHB_ADDR_WIDTH), + .AHB_DATA_WIDTH(AHB_DATA_WIDTH), + .CLIENT_DATA_WIDTH(32) +) ahb_slv_sif_inst +( + //AMBA AHB Lite INF + .hclk(clk), + .hreset_n(reset_n), + .haddr_i(haddr_i), + .hwdata_i(hwdata_i), + .hsel_i(hsel_i), + .hwrite_i(hwrite_i), + .hready_i(hready_i), + .htrans_i(htrans_i), + .hsize_i(hsize_i), + + .hresp_o(hresp_o), + .hreadyout_o(hreadyout_o), + .hrdata_o(hrdata_o), + + + //COMPONENT INF + .dv(ahb_dv), + .hld(ahb_hold), + .err(ahb_err), + .write(ahb_write), + .wdata(ahb_wdata), + .addr(ahb_addr), + + .rdata(ahb_rdata) +); + +// This is a workaround. A cleaner solution is tracked in issue #914 to integrate this functionality into ahb_slv_sif: +// https://github.com/chipsalliance/caliptra-rtl/issues/914 +always_ff @(posedge clk or negedge reset_n) begin + if(!reset_n) begin + ahb_size <= '0; + end else begin + if(hready_i & hsel_i) begin + ahb_size <= hsize_i; + end + end +end + +always_comb begin + unique case (ahb_size) + 'h0: begin + ahb_wstrb = 1 << ahb_addr[1:0]; + end + 'h1: begin + ahb_wstrb = ahb_addr[1] ? 4'b1100 : 4'b0011; + end + 'h2: begin + ahb_wstrb = 4'b1111; + end + default: begin + ahb_wstrb = 4'b0000; + end + endcase +end + +//TLUL Adapter +caliptra_tlul_adapter_vh +#( + .VH_REGISTER_ADDRESS_OFFSET(32'h0000_1000) +) +caliptra_tlul_adapter_vh_inst +( + .clk_i(clk), + .rst_ni(reset_n), + + .tl_o(adapter_to_kmac_tl), + .tl_i(kmac_to_adapter_tl), + + // Valid-Hold device interface (VH to TLUL). + .dv_i(ahb_dv), + .hld_o(ahb_hold), + .addr_i({ {caliptra_tlul_pkg::TL_AW-AHB_ADDR_WIDTH{1'b0}}, ahb_addr }), + .write_i(ahb_write), + .wdata_i(ahb_wdata), + .wstrb_i(ahb_wstrb), + .size_i(ahb_size), + .rdata_o(ahb_rdata), + .error_o(ahb_err), + .last_i('0), + .user_i('0), + .id_i('0), + + // Valid-Hold host interface (VH to internal registers). The signals from the VH device interface + // are routed to the VH host interface for every internal access, see the `internal_access` signal. + .int_dv_o(clp_reg_dv), + .int_hld_i('0), + .int_addr_o(clp_reg_addr), + .int_write_o(clp_reg_write), + .int_wdata_o(clp_reg_wdata), + .int_wstrb_o(), + .int_size_o(), + .int_rdata_i(clp_reg_rdata), + .int_error_i('0), + .int_last_o(), + .int_user_o(), + .int_id_o() +); + +//Internal register block +sha3_reg sha_reg_inst ( + .clk(clk), + .rst(1'b0), + + .s_cpuif_req (clp_reg_dv), + .s_cpuif_req_is_wr (clp_reg_write), + .s_cpuif_addr (clp_reg_addr[SHA3_REG_MIN_ADDR_WIDTH-1:0]), + .s_cpuif_wr_data (clp_reg_wdata), + .s_cpuif_wr_biten ('1), + .s_cpuif_req_stall_wr(), + .s_cpuif_req_stall_rd(), + .s_cpuif_rd_ack (), + .s_cpuif_rd_err (), + .s_cpuif_rd_data (clp_reg_rdata), + .s_cpuif_wr_ack (), + .s_cpuif_wr_err (), + + .hwif_in (hwif_in), + .hwif_out(hwif_out) +); + +kmac +#( + .EnMasking (0), + .EnFullKmac (0), + .SwKeyMasked (0), + .NumAppIntf (2), + .AppCfg ('{AppCfgKeyMgrStripped, AppCfgKeyMgrStripped}) +) +u_sha_inst ( + .clk_i (clk), + .rst_ni (reset_n), + .rst_shadowed_ni (reset_n), + + .clk_edn_i (1'b0), + .rst_edn_ni (1'b1), + + // Bus interface + .tl_i (adapter_to_kmac_tl), + .tl_o (kmac_to_adapter_tl), + + // Alerts + .alert_rx_i ('0), + .alert_tx_o (), + + // KeyMgr sideload (secret key) interface + .keymgr_key_i ('0), + + // KeyMgr KDF data path + .app_i ('0), + .app_o (), + + // EDN interface + .entropy_o (), + .entropy_i ('0), + + // Life cycle + .lc_escalate_en_i (lc_ctrl_pkg::Off), + + // interrupts + .intr_kmac_done_o (intr_kmac_done), + .intr_fifo_empty_o (intr_fifo_empty), + .intr_kmac_err_o (intr_kmac_err), + + // parameter consistency check with keymgr + .en_masking_o (), + + // Idle signal + .idle_o (sha_idle) +); + +always_comb begin + hwif_in.error_reset_b = cptra_pwrgood; + hwif_in.reset_b = reset_n; + hwif_in.SHA3_NAME[0].NAME.next = SHA3_CORE_NAME[31:0]; + hwif_in.SHA3_NAME[1].NAME.next = SHA3_CORE_NAME[63:32]; + hwif_in.SHA3_VERSION[0].VERSION.next = SHA3_CORE_VERSION[31:0]; + hwif_in.SHA3_VERSION[1].VERSION.next = SHA3_CORE_VERSION[63:32]; + + // Duplicates of regs in top_reg are tied to 0. + hwif_in.STATUS = '{default: '0}; + hwif_in.STATE = '{default: '0}; + hwif_in.MSG_FIFO = '{default: '0}; + hwif_in.ERR_CODE.ERR_CODE.next = '0; + hwif_in.CFG_SHADOWED = '{default: '0}; + hwif_in.CFG_REGWEN.en.next = 1'b0; +end + +// Detect edges for interrupts and errors. +always_ff @(posedge clk or negedge reset_n) +begin : error_interrupt_detection + if(!reset_n) begin + intr_kmac_err_reg <= 1'b0; + intr_kmac_done_reg <= 1'b0; + intr_fifo_empty_reg <= 1'b0; + end + else begin + intr_kmac_err_reg <= intr_kmac_err; + intr_kmac_done_reg <= intr_kmac_done; + intr_fifo_empty_reg <= intr_fifo_empty; + end +end // error_interrupt_detection + +// Error/Interrupt edge detection signals. +always_comb intr_kmac_err_edge = intr_kmac_err & (!intr_kmac_err_reg); +always_comb intr_kmac_done_edge = intr_kmac_done & (!intr_kmac_done_reg); +always_comb intr_fifo_empty_edge = intr_fifo_empty & (!intr_fifo_empty_reg); + +// Assign error/interrupt signals +assign hwif_in.intr_block_rf.error_internal_intr_r.sha3_error_sts.hwset = intr_kmac_err_edge; +assign hwif_in.intr_block_rf.error_internal_intr_r.error1_sts.hwset = 1'b0; +assign hwif_in.intr_block_rf.error_internal_intr_r.error2_sts.hwset = 1'b0; +assign hwif_in.intr_block_rf.error_internal_intr_r.error3_sts.hwset = 1'b0; +assign hwif_in.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.hwset = intr_kmac_done_edge; +assign hwif_in.intr_block_rf.notif_internal_intr_r.notif_msg_fifo_empty_sts.hwset = intr_fifo_empty_edge; + +assign error_intr = hwif_out.intr_block_rf.error_global_intr_r.intr; +assign notif_intr = hwif_out.intr_block_rf.notif_global_intr_r.intr; + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/sha3_param_pkg.sv b/designs/Caliptra/src/caliptra-rtl/sha3_param_pkg.sv new file mode 100644 index 0000000..517b4ef --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/sha3_param_pkg.sv @@ -0,0 +1,36 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +// +//====================================================================== +// +// sha3_param_pkg.sv +// -------- +// SHA3 Parameters +// +// +//====================================================================== + +`ifndef SHA3_PARAM_PKG +`define SHA3_PARAM_PKG + +package sha3_param_pkg; + //---------------------------------------------------------------- + // Internal constant and parameter definitions. + //---------------------------------------------------------------- + + localparam bit [63:0] SHA3_CORE_NAME = 64'h00000000_61337368; // "sha3" + localparam bit [63:0] SHA3_CORE_VERSION = 64'h00000000_3030312e; // "2.00" +endpackage + +`endif diff --git a/designs/Caliptra/src/caliptra-rtl/sha3_pkg.sv b/designs/Caliptra/src/caliptra-rtl/sha3_pkg.sv new file mode 100644 index 0000000..ea22cfa --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/sha3_pkg.sv @@ -0,0 +1,294 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// sha3_pkg + +package sha3_pkg; + + // StateW represents the width of Keccak state variable. + // As Sha3 assume the state value as 1600, this shouldn't be modified. + // Note that keccak_round is flexible. It can have any values defined in SHA3 + // specification. But sha3pad logic assumes the value as 1600. + parameter int StateW = 1600; + + // Function Name (N) and Customzation String (S) shall be + // smaller than 2**256 bits and integer divisiable by 8. + parameter int FnWidth = 32; // up to 32bit Function Name + parameter int CsWidth = 256; // up to 256bit Customization Input + + // Calculate left_encode(len( X )) bit size. + // Assume the enc_8(n) is always 1 (up to 255 byte of len(S) size) + // e.g) 248bit --> two bytes , 256bit --> three bytes + // round8bit(clog2(X+1))/8 + + parameter int MaxFnEncodeSize = ($clog2(FnWidth+1) + 8 - 1) / 8 + 1; + parameter int MaxCsEncodeSize = ($clog2(CsWidth+1) + 8 - 1) / 8 + 1; + + parameter int NSRegisterSizePre = FnWidth/8 + CsWidth/8 + + MaxFnEncodeSize + MaxCsEncodeSize; + // Round up to 32bit word base + parameter int NSRegisterSize = ((NSRegisterSizePre + 4 - 1 ) / 4) * 4; + + // Prefix represents bytepad(encode_string(N) || encode_string(S), 168 or 136) + // +2 represents left_encoding(168 or 136) which could be either: + // 10000000 || 00010101 // 168 + // 10000000 || 00010001 // 136 + parameter int PrefixSize = NSRegisterSize + 2; + + // index width for `N` and `S` + parameter int PrefixIndexW = $clog2(PrefixSize/64); + + // Datapath width in KMAC, this also affects the output of MSG_FIFO + // This is assumed as 64 in KMAC design. If this value is changed, some parts + // of the KMAC design need to be changed. + // + // 1. keccak_round logic datapath. Keccak round logic assumes MsgWidth + // divides 1600 keccak state `Width`. Choose the value accordingly. + // 2. sha3pad module has fixed width mux for funcpad logic. If MsgWidth is + // changed, the logic also need to be revised. + // 3. kmac core logic also has fixed size mux for appeding output length. + // Revise the case statement to fit into revised MsgWidth value. + parameter int MsgWidth = 64; + parameter int MsgStrbW = MsgWidth / 8; + + // Keccak module supports SHA3, SHAKE, cSHAKE function. + // This mode determines if the module uses encoded N and S or not. + // Also it chooses the padding value. + // + // mode | little-endian + // -------|---------------- + // Sha3 | 2'b 10 + // Shake | 4'b 1111 + // CShake | 2'b 00 + // + // Please remind that if input strings N and S are empty, SW shall + // choose SHAKE even for cSHAKE operation. + typedef enum logic[1:0] { + Sha3 = 2'b 00, + Shake = 2'b 10, + CShake = 2'b 11 + } sha3_mode_e; + + // keccak_strength_e determines the security strength against collision attack + // This value decides the _rate_ and _capacity_ of the keccak states. + // It affects the sha3pad module too. the padding module implements + // `bytepad(X,168)` for L128, `bytepad(X,136)` for L256 in cSHAKE + typedef enum logic [2:0] { + L128 = 3'b 000, // rate: 1344 bit / capacity: 256 bit Keccak[ 256](, 128) + L224 = 3'b 001, // rate: 1152 bit / capacity: 448 bit Keccak[ 448](, 224) + L256 = 3'b 010, // rate: 1088 bit / capacity: 512 bit Keccak[ 512](, 256) + L384 = 3'b 011, // rate: 832 bit / capacity: 768 bit Keccak[ 768](, 384) + L512 = 3'b 100 // rate: 576 bit / capacity: 1024 bit Keccak[1024](, 512) + } keccak_strength_e; + + parameter int unsigned KeccakRate [5] = '{ + 1344/MsgWidth, // 21 depth := (1600 - 128*2) + 1152/MsgWidth, // 18 depth := (1600 - 224*2) + 1088/MsgWidth, // 17 depth := (1600 - 256*2) + 832/MsgWidth, // 13 depth := (1600 - 384*2) + 576/MsgWidth // 9 depth := (1600 - 512*2) + }; + + parameter int unsigned KeccakBitCapacity [5] = '{ + 2 * 128, // capacity for L128 + 2 * 224, // capacity for L224 + 2 * 256, // capacity for L256 + 2 * 384, // capacity for L384 + 2 * 512 // capacity for L512 + }; + + parameter int unsigned MaxBlockSize = KeccakRate[0]; + + parameter int unsigned KeccakEntries = 1600/MsgWidth; + parameter int unsigned KeccakMsgAddrW = $clog2(KeccakEntries); + + parameter int unsigned KeccakCountW = $clog2(KeccakEntries+1); + + // SHA3 core state. This state value is used in sha3core module + // and also in KMAC top module and the register interface for sw to track the + // sha3 status. + // Encoding generated with: + // $ ./util/design/sparse-fsm-encode.py -d 3 -m 7 -n 6 \ + // -s 4082450958 --language=sv + // + // Hamming distance histogram: + // + // 0: -- + // 1: -- + // 2: -- + // 3: |||||||||||||||||||| (57.14%) + // 4: ||||||||||||||| (42.86%) + // 5: -- + // 6: -- + // + // Minimum Hamming distance: 3 + // Maximum Hamming distance: 4 + // Minimum Hamming weight: 1 + // Maximum Hamming weight: 4 + // + localparam int StateWidth = 6; + typedef enum logic [StateWidth-1:0] { + StIdle_sparse = 6'b101100, + + // Absorb stage receives the message bitstream and computes the keccak + // rounds. This internal operation is mainly done inside sha3pad module + // not sha3core. The core module and this state machine observe the status + // of the process and mainly waits until all the sponge absorbing is + // completed. The main indicator is `absorbed` signal. + StAbsorb_sparse = 6'b100001, + + // Reserved state for context-switching. See #3479. + // Abort stage can be moved from StAbsorb stage. It basically holds the + // keccak round operation and opens up the internal state variable to the + // software. This stage is for the software to pause current operation and + // store the internal state elsewhere then initiates new KMAC/SHA3 process. + // StAbort only can be moved to _StFlush_. + //StAbort_sparse = 6'b011101, + + // Squeeze stage allows the software to read the internal state. + // If `EnMasking`, it opens the read permission of two share of the state. + // The squeezing in SHA3 specification describes the software to read up to + // the rate of SHA3 algorithm but this logic opens up the entire 1600 bits + // of the state (3200bits if `EnMasking`). + StSqueeze_sparse = 6'b001011, + + // ManualRun stage initiaties the keccak round and waits the completion. + // This state is moved from Squeeze state by writing 1 to manual_run CSR. + // When keccak round is completed, it goes back to Squeeze state. + StManualRun_sparse = 6'b010000, + + // Flush stage, the core clears out the internal variables and also + // submodules' variables too. Then moves back to Idle state. + StFlush_sparse = 6'b000110, + + StTerminalError_sparse = 6'b111010 + } sha3_st_sparse_e; + + localparam int StateWidthLogic = 3; + typedef enum logic [StateWidthLogic-1:0] { + StIdle, + StAbsorb, + //StAbort, + StSqueeze, + StManualRun, + StFlush, + StError + } sha3_st_e; + + function automatic sha3_st_e sparse2logic(sha3_st_sparse_e st); + unique case (st) + StIdle_sparse : return StIdle; + StAbsorb_sparse : return StAbsorb; + //StAbort_sparse : return StAbort; + StSqueeze_sparse : return StSqueeze; + StManualRun_sparse : return StManualRun; + StFlush_sparse : return StFlush; + default : return StError; + endcase + endfunction : sparse2logic + + + ////////////////////// + // Keccak Round FSM // + ////////////////////// + + // Encoding generated with: + // $ ./util/design/sparse-fsm-encode.py -d 3 -m 8 -n 6 \ + // -s 1363425333 --language=sv + // + // Hamming distance histogram: + // + // 0: -- + // 1: -- + // 2: -- + // 3: |||||||||||||||||||| (57.14%) + // 4: ||||||||||||||| (42.86%) + // 5: -- + // 6: -- + // + // Minimum Hamming distance: 3 + // Maximum Hamming distance: 4 + // Minimum Hamming weight: 1 + // Maximum Hamming weight: 5 + // + localparam int KeccakFsmWidth = 6; + typedef enum logic [KeccakFsmWidth-1:0] { + KeccakStIdle = 6'b011111, + + // Active state is used in Unmasked version only. + // It handles keccak round in a cycle + KeccakStActive = 6'b000100, + + // Phase1 --> Phase2Cycle1 --> Phase2Cycle2 --> Phase2Cycle3 + // Activated only in Masked version. + // Phase1 processes Theta, Rho, Pi steps in a cycle and stores the states + // into storage. It only moves to Phase2 once the randomness required for + // Phase2 is available. + KeccakStPhase1 = 6'b101101, + + // Chi Stage 1 for first lane halves. Unconditionally move to Phase2Cycle2. + KeccakStPhase2Cycle1 = 6'b000011, + + // Chi Stage 2 and Iota for first lane halves. Chi Stage 1 for second + // lane halves. Unconditionally move to Phase2Cycle3. + KeccakStPhase2Cycle2 = 6'b011000, + + // Chi Stage 2 and Iota for second lane halves. + // When doing the last round (MaxRound -1) it completes the process and + // goes back to Idle. If not, it repeats the phases again. + KeccakStPhase2Cycle3 = 6'b101010, + + // Error state. Not clearly defined yet. + // Intention is if any unexpected input in the process, state moves to + // here and report through the error fifo with debugging information. + KeccakStError = 6'b110001, + + KeccakStTerminalError = 6'b110110 + } keccak_st_e; + + + ////////////////// + // Error Report // + ////////////////// + typedef enum logic [7:0] { + ErrNone = 8'h 00, + + // ErrSha3SwControl occurs when software sent wrong flow signal. + // e.g) Sw set `process_i` without `start_i`. The state machine ignores + // the signal and report through the error FIFO. + ErrSha3SwControl = 8'h 80 + } err_code_e; + + typedef struct packed { + logic valid; + err_code_e code; // Type of error + logic [23:0] info; // Additional Debug info + } err_t; + + + /////////////// + // Functions // + /////////////// + + // Bytepading function + // `encode_bytepad_len` represents the first two bytes of bytepad() + // It depends on the block size. We can reuse KeccakRate + // 10000000 || 00010101 // 168 + // 10000000 || 00010001 // 136 + function automatic logic [15:0] encode_bytepad_len(keccak_strength_e kstrength); + logic [15:0] result; + unique case (kstrength) + L128: result = 16'h A801; // cSHAKE128 + L224: result = 16'h 9001; // not used + L256: result = 16'h 8801; // cSHAKE256 + L384: result = 16'h 6801; // not used + L512: result = 16'h 4801; // not used + + default: result = 16'h 0000; + endcase + return result; + endfunction : encode_bytepad_len + + +endpackage : sha3_pkg diff --git a/designs/Caliptra/src/caliptra-rtl/sha3_reg.sv b/designs/Caliptra/src/caliptra-rtl/sha3_reg.sv new file mode 100644 index 0000000..6a84694 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/sha3_reg.sv @@ -0,0 +1,1582 @@ +// Generated by PeakRDL-regblock - A free and open-source SystemVerilog generator +// https://github.com/SystemRDL/PeakRDL-regblock + +module sha3_reg ( + input wire clk, + input wire rst, + + input wire s_cpuif_req, + input wire s_cpuif_req_is_wr, + input wire [11:0] s_cpuif_addr, + input wire [31:0] s_cpuif_wr_data, + input wire [31:0] s_cpuif_wr_biten, + output wire s_cpuif_req_stall_wr, + output wire s_cpuif_req_stall_rd, + output wire s_cpuif_rd_ack, + output wire s_cpuif_rd_err, + output wire [31:0] s_cpuif_rd_data, + output wire s_cpuif_wr_ack, + output wire s_cpuif_wr_err, + + input sha3_reg_pkg::sha3_reg__in_t hwif_in, + output sha3_reg_pkg::sha3_reg__out_t hwif_out + ); + + //-------------------------------------------------------------------------- + // CPU Bus interface logic + //-------------------------------------------------------------------------- + logic cpuif_req; + logic cpuif_req_is_wr; + logic [11:0] cpuif_addr; + logic [31:0] cpuif_wr_data; + logic [31:0] cpuif_wr_biten; + logic cpuif_req_stall_wr; + logic cpuif_req_stall_rd; + + logic cpuif_rd_ack; + logic cpuif_rd_err; + logic [31:0] cpuif_rd_data; + + logic cpuif_wr_ack; + logic cpuif_wr_err; + + assign cpuif_req = s_cpuif_req; + assign cpuif_req_is_wr = s_cpuif_req_is_wr; + assign cpuif_addr = s_cpuif_addr; + assign cpuif_wr_data = s_cpuif_wr_data; + assign cpuif_wr_biten = s_cpuif_wr_biten; + assign s_cpuif_req_stall_wr = cpuif_req_stall_wr; + assign s_cpuif_req_stall_rd = cpuif_req_stall_rd; + assign s_cpuif_rd_ack = cpuif_rd_ack; + assign s_cpuif_rd_err = cpuif_rd_err; + assign s_cpuif_rd_data = cpuif_rd_data; + assign s_cpuif_wr_ack = cpuif_wr_ack; + assign s_cpuif_wr_err = cpuif_wr_err; + + logic cpuif_req_masked; + logic external_req; + logic external_pending; + logic external_wr_ack; + logic external_rd_ack; + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + external_pending <= '0; + end else begin + if(external_req & ~external_wr_ack & ~external_rd_ack) external_pending <= '1; + else if(external_wr_ack | external_rd_ack) external_pending <= '0; + assert(!external_wr_ack || (external_pending | external_req)) + else $error("An external wr_ack strobe was asserted when no external request was active"); + assert(!external_rd_ack || (external_pending | external_req)) + else $error("An external rd_ack strobe was asserted when no external request was active"); + end + end + + // Read & write latencies are balanced. Stalls not required + // except if external + assign cpuif_req_stall_rd = external_pending; + assign cpuif_req_stall_wr = external_pending; + assign cpuif_req_masked = cpuif_req + & !(!cpuif_req_is_wr & cpuif_req_stall_rd) + & !(cpuif_req_is_wr & cpuif_req_stall_wr); + + //-------------------------------------------------------------------------- + // Address Decode + //-------------------------------------------------------------------------- + typedef struct packed{ + logic [2-1:0]SHA3_NAME; + logic [2-1:0]SHA3_VERSION; + logic ALERT_TEST; + logic CFG_REGWEN; + logic CFG_SHADOWED; + logic CMD; + logic STATUS; + logic ERR_CODE; + logic STATE; + struct packed{ + logic global_intr_en_r; + logic error_intr_en_r; + logic notif_intr_en_r; + logic error_global_intr_r; + logic notif_global_intr_r; + logic error_internal_intr_r; + logic notif_internal_intr_r; + logic error_intr_trig_r; + logic notif_intr_trig_r; + logic sha3_error_intr_count_r; + logic error1_intr_count_r; + logic error2_intr_count_r; + logic error3_intr_count_r; + logic notif_cmd_done_intr_count_r; + logic sha3_error_intr_count_incr_r; + logic error1_intr_count_incr_r; + logic error2_intr_count_incr_r; + logic error3_intr_count_incr_r; + logic notif_cmd_done_intr_count_incr_r; + } intr_block_rf; + logic MSG_FIFO; + } decoded_reg_strb_t; + decoded_reg_strb_t decoded_reg_strb; + logic decoded_strb_is_external; + + logic [11:0] decoded_addr; + + logic decoded_req; + logic decoded_req_is_wr; + logic [31:0] decoded_wr_data; + logic [31:0] decoded_wr_biten; + + always_comb begin + automatic logic is_external; + is_external = '0; + for(int i0=0; i0<2; i0++) begin + decoded_reg_strb.SHA3_NAME[i0] = cpuif_req_masked & (cpuif_addr == 12'h0 + i0*12'h4); + end + for(int i0=0; i0<2; i0++) begin + decoded_reg_strb.SHA3_VERSION[i0] = cpuif_req_masked & (cpuif_addr == 12'h8 + i0*12'h4); + end + decoded_reg_strb.ALERT_TEST = cpuif_req_masked & (cpuif_addr == 12'h1c); + decoded_reg_strb.CFG_REGWEN = cpuif_req_masked & (cpuif_addr == 12'h20); + decoded_reg_strb.CFG_SHADOWED = cpuif_req_masked & (cpuif_addr == 12'h24); + is_external |= cpuif_req_masked & (cpuif_addr == 12'h24); + decoded_reg_strb.CMD = cpuif_req_masked & (cpuif_addr == 12'h28); + decoded_reg_strb.STATUS = cpuif_req_masked & (cpuif_addr == 12'h2c); + decoded_reg_strb.ERR_CODE = cpuif_req_masked & (cpuif_addr == 12'hd0); + decoded_reg_strb.STATE = cpuif_req_masked & (cpuif_addr >= 12'h200) & (cpuif_addr <= 12'h200 + 12'hff); + is_external |= cpuif_req_masked & (cpuif_addr >= 12'h200) & (cpuif_addr <= 12'h200 + 12'hff); + decoded_reg_strb.intr_block_rf.global_intr_en_r = cpuif_req_masked & (cpuif_addr == 12'h400); + decoded_reg_strb.intr_block_rf.error_intr_en_r = cpuif_req_masked & (cpuif_addr == 12'h404); + decoded_reg_strb.intr_block_rf.notif_intr_en_r = cpuif_req_masked & (cpuif_addr == 12'h408); + decoded_reg_strb.intr_block_rf.error_global_intr_r = cpuif_req_masked & (cpuif_addr == 12'h40c); + decoded_reg_strb.intr_block_rf.notif_global_intr_r = cpuif_req_masked & (cpuif_addr == 12'h410); + decoded_reg_strb.intr_block_rf.error_internal_intr_r = cpuif_req_masked & (cpuif_addr == 12'h414); + decoded_reg_strb.intr_block_rf.notif_internal_intr_r = cpuif_req_masked & (cpuif_addr == 12'h418); + decoded_reg_strb.intr_block_rf.error_intr_trig_r = cpuif_req_masked & (cpuif_addr == 12'h41c); + decoded_reg_strb.intr_block_rf.notif_intr_trig_r = cpuif_req_masked & (cpuif_addr == 12'h420); + decoded_reg_strb.intr_block_rf.sha3_error_intr_count_r = cpuif_req_masked & (cpuif_addr == 12'h500); + decoded_reg_strb.intr_block_rf.error1_intr_count_r = cpuif_req_masked & (cpuif_addr == 12'h504); + decoded_reg_strb.intr_block_rf.error2_intr_count_r = cpuif_req_masked & (cpuif_addr == 12'h508); + decoded_reg_strb.intr_block_rf.error3_intr_count_r = cpuif_req_masked & (cpuif_addr == 12'h50c); + decoded_reg_strb.intr_block_rf.notif_cmd_done_intr_count_r = cpuif_req_masked & (cpuif_addr == 12'h580); + decoded_reg_strb.intr_block_rf.sha3_error_intr_count_incr_r = cpuif_req_masked & (cpuif_addr == 12'h600); + decoded_reg_strb.intr_block_rf.error1_intr_count_incr_r = cpuif_req_masked & (cpuif_addr == 12'h604); + decoded_reg_strb.intr_block_rf.error2_intr_count_incr_r = cpuif_req_masked & (cpuif_addr == 12'h608); + decoded_reg_strb.intr_block_rf.error3_intr_count_incr_r = cpuif_req_masked & (cpuif_addr == 12'h60c); + decoded_reg_strb.intr_block_rf.notif_cmd_done_intr_count_incr_r = cpuif_req_masked & (cpuif_addr == 12'h610); + decoded_reg_strb.MSG_FIFO = cpuif_req_masked & (cpuif_addr >= 12'hc00) & (cpuif_addr <= 12'hc00 + 12'hff); + is_external |= cpuif_req_masked & (cpuif_addr >= 12'hc00) & (cpuif_addr <= 12'hc00 + 12'hff); + decoded_strb_is_external = is_external; + external_req = is_external; + end + + // Pass down signals to next stage + assign decoded_addr = cpuif_addr; + + assign decoded_req = cpuif_req_masked; + assign decoded_req_is_wr = cpuif_req_is_wr; + assign decoded_wr_data = cpuif_wr_data; + assign decoded_wr_biten = cpuif_wr_biten; + + //-------------------------------------------------------------------------- + // Field logic + //-------------------------------------------------------------------------- + typedef struct packed{ + struct packed{ + struct packed{ + logic next; + logic load_next; + } en; + } CFG_REGWEN; + struct packed{ + struct packed{ + logic [5:0] next; + logic load_next; + } cmd; + struct packed{ + logic next; + logic load_next; + } err_processed; + } CMD; + struct packed{ + struct packed{ + struct packed{ + logic next; + logic load_next; + } error_en; + struct packed{ + logic next; + logic load_next; + } notif_en; + } global_intr_en_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + } sha3_error_en; + struct packed{ + logic next; + logic load_next; + } error1_en; + struct packed{ + logic next; + logic load_next; + } error2_en; + struct packed{ + logic next; + logic load_next; + } error3_en; + } error_intr_en_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + } notif_cmd_done_en; + struct packed{ + logic next; + logic load_next; + } notif_msg_fifo_empty_en; + } notif_intr_en_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + } agg_sts; + } error_global_intr_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + } agg_sts; + } notif_global_intr_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + } sha3_error_sts; + struct packed{ + logic next; + logic load_next; + } error1_sts; + struct packed{ + logic next; + logic load_next; + } error2_sts; + struct packed{ + logic next; + logic load_next; + } error3_sts; + } error_internal_intr_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + } notif_cmd_done_sts; + struct packed{ + logic next; + logic load_next; + } notif_msg_fifo_empty_sts; + } notif_internal_intr_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + } sha3_error_trig; + struct packed{ + logic next; + logic load_next; + } error1_trig; + struct packed{ + logic next; + logic load_next; + } error2_trig; + struct packed{ + logic next; + logic load_next; + } error3_trig; + } error_intr_trig_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + } notif_cmd_done_trig; + struct packed{ + logic next; + logic load_next; + } notif_msg_fifo_empty_trig; + } notif_intr_trig_r; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + logic incrthreshold; + logic incrsaturate; + } cnt; + } sha3_error_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + logic incrthreshold; + logic incrsaturate; + } cnt; + } error1_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + logic incrthreshold; + logic incrsaturate; + } cnt; + } error2_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + logic incrthreshold; + logic incrsaturate; + } cnt; + } error3_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + logic incrthreshold; + logic incrsaturate; + } cnt; + } notif_cmd_done_intr_count_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + logic decrthreshold; + logic underflow; + } pulse; + } sha3_error_intr_count_incr_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + logic decrthreshold; + logic underflow; + } pulse; + } error1_intr_count_incr_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + logic decrthreshold; + logic underflow; + } pulse; + } error2_intr_count_incr_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + logic decrthreshold; + logic underflow; + } pulse; + } error3_intr_count_incr_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + logic decrthreshold; + logic underflow; + } pulse; + } notif_cmd_done_intr_count_incr_r; + } intr_block_rf; + } field_combo_t; + field_combo_t field_combo; + + typedef struct packed{ + struct packed{ + struct packed{ + logic value; + } en; + } CFG_REGWEN; + struct packed{ + struct packed{ + logic [5:0] value; + } cmd; + struct packed{ + logic value; + } err_processed; + } CMD; + struct packed{ + struct packed{ + struct packed{ + logic value; + } error_en; + struct packed{ + logic value; + } notif_en; + } global_intr_en_r; + struct packed{ + struct packed{ + logic value; + } sha3_error_en; + struct packed{ + logic value; + } error1_en; + struct packed{ + logic value; + } error2_en; + struct packed{ + logic value; + } error3_en; + } error_intr_en_r; + struct packed{ + struct packed{ + logic value; + } notif_cmd_done_en; + struct packed{ + logic value; + } notif_msg_fifo_empty_en; + } notif_intr_en_r; + struct packed{ + struct packed{ + logic value; + } agg_sts; + } error_global_intr_r; + struct packed{ + struct packed{ + logic value; + } agg_sts; + } notif_global_intr_r; + struct packed{ + struct packed{ + logic value; + } sha3_error_sts; + struct packed{ + logic value; + } error1_sts; + struct packed{ + logic value; + } error2_sts; + struct packed{ + logic value; + } error3_sts; + } error_internal_intr_r; + struct packed{ + struct packed{ + logic value; + } notif_cmd_done_sts; + struct packed{ + logic value; + } notif_msg_fifo_empty_sts; + } notif_internal_intr_r; + struct packed{ + struct packed{ + logic value; + } sha3_error_trig; + struct packed{ + logic value; + } error1_trig; + struct packed{ + logic value; + } error2_trig; + struct packed{ + logic value; + } error3_trig; + } error_intr_trig_r; + struct packed{ + struct packed{ + logic value; + } notif_cmd_done_trig; + struct packed{ + logic value; + } notif_msg_fifo_empty_trig; + } notif_intr_trig_r; + struct packed{ + struct packed{ + logic [31:0] value; + } cnt; + } sha3_error_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] value; + } cnt; + } error1_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] value; + } cnt; + } error2_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] value; + } cnt; + } error3_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] value; + } cnt; + } notif_cmd_done_intr_count_r; + struct packed{ + struct packed{ + logic value; + } pulse; + } sha3_error_intr_count_incr_r; + struct packed{ + struct packed{ + logic value; + } pulse; + } error1_intr_count_incr_r; + struct packed{ + struct packed{ + logic value; + } pulse; + } error2_intr_count_incr_r; + struct packed{ + struct packed{ + logic value; + } pulse; + } error3_intr_count_incr_r; + struct packed{ + struct packed{ + logic value; + } pulse; + } notif_cmd_done_intr_count_incr_r; + } intr_block_rf; + } field_storage_t; + field_storage_t field_storage; + + // Field: sha3_reg.CFG_REGWEN.en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.CFG_REGWEN.en.value; + load_next_c = '0; + + // HW Write + next_c = hwif_in.CFG_REGWEN.en.next; + load_next_c = '1; + field_combo.CFG_REGWEN.en.next = next_c; + field_combo.CFG_REGWEN.en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.CFG_REGWEN.en.value <= 1'h1; + end else if(field_combo.CFG_REGWEN.en.load_next) begin + field_storage.CFG_REGWEN.en.value <= field_combo.CFG_REGWEN.en.next; + end + end + assign hwif_out.CFG_REGWEN.en.value = field_storage.CFG_REGWEN.en.value; + + assign hwif_out.CFG_SHADOWED.req = decoded_reg_strb.CFG_SHADOWED; + assign hwif_out.CFG_SHADOWED.req_is_wr = decoded_req_is_wr; + assign hwif_out.CFG_SHADOWED.wr_data = decoded_wr_data; + assign hwif_out.CFG_SHADOWED.wr_biten = decoded_wr_biten; + // Field: sha3_reg.CMD.cmd + always_comb begin + automatic logic [5:0] next_c; + automatic logic load_next_c; + next_c = field_storage.CMD.cmd.value; + load_next_c = '0; + if(decoded_reg_strb.CMD && decoded_req_is_wr) begin // SW write 1 clear + next_c = field_storage.CMD.cmd.value & ~(decoded_wr_data[5:0] & decoded_wr_biten[5:0]); + load_next_c = '1; + end + field_combo.CMD.cmd.next = next_c; + field_combo.CMD.cmd.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.CMD.cmd.value <= 6'h0; + end else if(field_combo.CMD.cmd.load_next) begin + field_storage.CMD.cmd.value <= field_combo.CMD.cmd.next; + end + end + assign hwif_out.CMD.cmd.value = field_storage.CMD.cmd.value; + // Field: sha3_reg.CMD.err_processed + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.CMD.err_processed.value; + load_next_c = '0; + if(decoded_reg_strb.CMD && decoded_req_is_wr) begin // SW write 1 clear + next_c = field_storage.CMD.err_processed.value & ~(decoded_wr_data[10:10] & decoded_wr_biten[10:10]); + load_next_c = '1; + end + field_combo.CMD.err_processed.next = next_c; + field_combo.CMD.err_processed.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.CMD.err_processed.value <= 1'h0; + end else if(field_combo.CMD.err_processed.load_next) begin + field_storage.CMD.err_processed.value <= field_combo.CMD.err_processed.next; + end + end + assign hwif_out.CMD.err_processed.value = field_storage.CMD.err_processed.value; + assign hwif_out.STATE.req = decoded_reg_strb.STATE; + assign hwif_out.STATE.addr = decoded_addr[8:0]; + assign hwif_out.STATE.req_is_wr = decoded_req_is_wr; + assign hwif_out.STATE.wr_data = decoded_wr_data; + assign hwif_out.STATE.wr_biten = decoded_wr_biten; + // Field: sha3_reg.intr_block_rf.global_intr_en_r.error_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.global_intr_en_r.error_en.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.global_intr_en_r && decoded_req_is_wr) begin // SW write + next_c = (field_storage.intr_block_rf.global_intr_en_r.error_en.value & ~decoded_wr_biten[0:0]) | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end + field_combo.intr_block_rf.global_intr_en_r.error_en.next = next_c; + field_combo.intr_block_rf.global_intr_en_r.error_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.global_intr_en_r.error_en.value <= 1'h0; + end else if(field_combo.intr_block_rf.global_intr_en_r.error_en.load_next) begin + field_storage.intr_block_rf.global_intr_en_r.error_en.value <= field_combo.intr_block_rf.global_intr_en_r.error_en.next; + end + end + // Field: sha3_reg.intr_block_rf.global_intr_en_r.notif_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.global_intr_en_r.notif_en.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.global_intr_en_r && decoded_req_is_wr) begin // SW write + next_c = (field_storage.intr_block_rf.global_intr_en_r.notif_en.value & ~decoded_wr_biten[1:1]) | (decoded_wr_data[1:1] & decoded_wr_biten[1:1]); + load_next_c = '1; + end + field_combo.intr_block_rf.global_intr_en_r.notif_en.next = next_c; + field_combo.intr_block_rf.global_intr_en_r.notif_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.global_intr_en_r.notif_en.value <= 1'h0; + end else if(field_combo.intr_block_rf.global_intr_en_r.notif_en.load_next) begin + field_storage.intr_block_rf.global_intr_en_r.notif_en.value <= field_combo.intr_block_rf.global_intr_en_r.notif_en.next; + end + end + // Field: sha3_reg.intr_block_rf.error_intr_en_r.sha3_error_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_intr_en_r.sha3_error_en.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_intr_en_r && decoded_req_is_wr) begin // SW write + next_c = (field_storage.intr_block_rf.error_intr_en_r.sha3_error_en.value & ~decoded_wr_biten[0:0]) | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end + field_combo.intr_block_rf.error_intr_en_r.sha3_error_en.next = next_c; + field_combo.intr_block_rf.error_intr_en_r.sha3_error_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.error_intr_en_r.sha3_error_en.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_intr_en_r.sha3_error_en.load_next) begin + field_storage.intr_block_rf.error_intr_en_r.sha3_error_en.value <= field_combo.intr_block_rf.error_intr_en_r.sha3_error_en.next; + end + end + // Field: sha3_reg.intr_block_rf.error_intr_en_r.error1_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_intr_en_r.error1_en.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_intr_en_r && decoded_req_is_wr) begin // SW write + next_c = (field_storage.intr_block_rf.error_intr_en_r.error1_en.value & ~decoded_wr_biten[1:1]) | (decoded_wr_data[1:1] & decoded_wr_biten[1:1]); + load_next_c = '1; + end + field_combo.intr_block_rf.error_intr_en_r.error1_en.next = next_c; + field_combo.intr_block_rf.error_intr_en_r.error1_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.error_intr_en_r.error1_en.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_intr_en_r.error1_en.load_next) begin + field_storage.intr_block_rf.error_intr_en_r.error1_en.value <= field_combo.intr_block_rf.error_intr_en_r.error1_en.next; + end + end + // Field: sha3_reg.intr_block_rf.error_intr_en_r.error2_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_intr_en_r.error2_en.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_intr_en_r && decoded_req_is_wr) begin // SW write + next_c = (field_storage.intr_block_rf.error_intr_en_r.error2_en.value & ~decoded_wr_biten[2:2]) | (decoded_wr_data[2:2] & decoded_wr_biten[2:2]); + load_next_c = '1; + end + field_combo.intr_block_rf.error_intr_en_r.error2_en.next = next_c; + field_combo.intr_block_rf.error_intr_en_r.error2_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.error_intr_en_r.error2_en.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_intr_en_r.error2_en.load_next) begin + field_storage.intr_block_rf.error_intr_en_r.error2_en.value <= field_combo.intr_block_rf.error_intr_en_r.error2_en.next; + end + end + // Field: sha3_reg.intr_block_rf.error_intr_en_r.error3_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_intr_en_r.error3_en.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_intr_en_r && decoded_req_is_wr) begin // SW write + next_c = (field_storage.intr_block_rf.error_intr_en_r.error3_en.value & ~decoded_wr_biten[3:3]) | (decoded_wr_data[3:3] & decoded_wr_biten[3:3]); + load_next_c = '1; + end + field_combo.intr_block_rf.error_intr_en_r.error3_en.next = next_c; + field_combo.intr_block_rf.error_intr_en_r.error3_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.error_intr_en_r.error3_en.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_intr_en_r.error3_en.load_next) begin + field_storage.intr_block_rf.error_intr_en_r.error3_en.value <= field_combo.intr_block_rf.error_intr_en_r.error3_en.next; + end + end + // Field: sha3_reg.intr_block_rf.notif_intr_en_r.notif_cmd_done_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_intr_en_r.notif_cmd_done_en.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.notif_intr_en_r && decoded_req_is_wr) begin // SW write + next_c = (field_storage.intr_block_rf.notif_intr_en_r.notif_cmd_done_en.value & ~decoded_wr_biten[0:0]) | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end + field_combo.intr_block_rf.notif_intr_en_r.notif_cmd_done_en.next = next_c; + field_combo.intr_block_rf.notif_intr_en_r.notif_cmd_done_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.notif_intr_en_r.notif_cmd_done_en.value <= 1'h0; + end else if(field_combo.intr_block_rf.notif_intr_en_r.notif_cmd_done_en.load_next) begin + field_storage.intr_block_rf.notif_intr_en_r.notif_cmd_done_en.value <= field_combo.intr_block_rf.notif_intr_en_r.notif_cmd_done_en.next; + end + end + // Field: sha3_reg.intr_block_rf.notif_intr_en_r.notif_msg_fifo_empty_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_intr_en_r.notif_msg_fifo_empty_en.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.notif_intr_en_r && decoded_req_is_wr) begin // SW write + next_c = (field_storage.intr_block_rf.notif_intr_en_r.notif_msg_fifo_empty_en.value & ~decoded_wr_biten[1:1]) | (decoded_wr_data[1:1] & decoded_wr_biten[1:1]); + load_next_c = '1; + end + field_combo.intr_block_rf.notif_intr_en_r.notif_msg_fifo_empty_en.next = next_c; + field_combo.intr_block_rf.notif_intr_en_r.notif_msg_fifo_empty_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.notif_intr_en_r.notif_msg_fifo_empty_en.value <= 1'h0; + end else if(field_combo.intr_block_rf.notif_intr_en_r.notif_msg_fifo_empty_en.load_next) begin + field_storage.intr_block_rf.notif_intr_en_r.notif_msg_fifo_empty_en.value <= field_combo.intr_block_rf.notif_intr_en_r.notif_msg_fifo_empty_en.next; + end + end + // Field: sha3_reg.intr_block_rf.error_global_intr_r.agg_sts + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_global_intr_r.agg_sts.value; + load_next_c = '0; + + // HW Write + next_c = hwif_out.intr_block_rf.error_internal_intr_r.intr; + load_next_c = '1; + field_combo.intr_block_rf.error_global_intr_r.agg_sts.next = next_c; + field_combo.intr_block_rf.error_global_intr_r.agg_sts.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.error_global_intr_r.agg_sts.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_global_intr_r.agg_sts.load_next) begin + field_storage.intr_block_rf.error_global_intr_r.agg_sts.value <= field_combo.intr_block_rf.error_global_intr_r.agg_sts.next; + end + end + assign hwif_out.intr_block_rf.error_global_intr_r.intr = + |(field_storage.intr_block_rf.error_global_intr_r.agg_sts.value & field_storage.intr_block_rf.global_intr_en_r.error_en.value); + // Field: sha3_reg.intr_block_rf.notif_global_intr_r.agg_sts + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_global_intr_r.agg_sts.value; + load_next_c = '0; + + // HW Write + next_c = hwif_out.intr_block_rf.notif_internal_intr_r.intr; + load_next_c = '1; + field_combo.intr_block_rf.notif_global_intr_r.agg_sts.next = next_c; + field_combo.intr_block_rf.notif_global_intr_r.agg_sts.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.notif_global_intr_r.agg_sts.value <= 1'h0; + end else if(field_combo.intr_block_rf.notif_global_intr_r.agg_sts.load_next) begin + field_storage.intr_block_rf.notif_global_intr_r.agg_sts.value <= field_combo.intr_block_rf.notif_global_intr_r.agg_sts.next; + end + end + assign hwif_out.intr_block_rf.notif_global_intr_r.intr = + |(field_storage.intr_block_rf.notif_global_intr_r.agg_sts.value & field_storage.intr_block_rf.global_intr_en_r.notif_en.value); + // Field: sha3_reg.intr_block_rf.error_internal_intr_r.sha3_error_sts + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_internal_intr_r.sha3_error_sts.value; + load_next_c = '0; + if(field_storage.intr_block_rf.error_intr_trig_r.sha3_error_trig.value != '0) begin // stickybit + next_c = field_storage.intr_block_rf.error_internal_intr_r.sha3_error_sts.value | field_storage.intr_block_rf.error_intr_trig_r.sha3_error_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.error_internal_intr_r.sha3_error_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end else if(decoded_reg_strb.intr_block_rf.error_internal_intr_r && decoded_req_is_wr) begin // SW write 1 clear + next_c = field_storage.intr_block_rf.error_internal_intr_r.sha3_error_sts.value & ~(decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end + field_combo.intr_block_rf.error_internal_intr_r.sha3_error_sts.next = next_c; + field_combo.intr_block_rf.error_internal_intr_r.sha3_error_sts.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.error_reset_b) begin + if(~hwif_in.error_reset_b) begin + field_storage.intr_block_rf.error_internal_intr_r.sha3_error_sts.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_internal_intr_r.sha3_error_sts.load_next) begin + field_storage.intr_block_rf.error_internal_intr_r.sha3_error_sts.value <= field_combo.intr_block_rf.error_internal_intr_r.sha3_error_sts.next; + end + end + // Field: sha3_reg.intr_block_rf.error_internal_intr_r.error1_sts + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_internal_intr_r.error1_sts.value; + load_next_c = '0; + if(field_storage.intr_block_rf.error_intr_trig_r.error1_trig.value != '0) begin // stickybit + next_c = field_storage.intr_block_rf.error_internal_intr_r.error1_sts.value | field_storage.intr_block_rf.error_intr_trig_r.error1_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.error_internal_intr_r.error1_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end else if(decoded_reg_strb.intr_block_rf.error_internal_intr_r && decoded_req_is_wr) begin // SW write 1 clear + next_c = field_storage.intr_block_rf.error_internal_intr_r.error1_sts.value & ~(decoded_wr_data[1:1] & decoded_wr_biten[1:1]); + load_next_c = '1; + end + field_combo.intr_block_rf.error_internal_intr_r.error1_sts.next = next_c; + field_combo.intr_block_rf.error_internal_intr_r.error1_sts.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.error_reset_b) begin + if(~hwif_in.error_reset_b) begin + field_storage.intr_block_rf.error_internal_intr_r.error1_sts.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_internal_intr_r.error1_sts.load_next) begin + field_storage.intr_block_rf.error_internal_intr_r.error1_sts.value <= field_combo.intr_block_rf.error_internal_intr_r.error1_sts.next; + end + end + // Field: sha3_reg.intr_block_rf.error_internal_intr_r.error2_sts + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_internal_intr_r.error2_sts.value; + load_next_c = '0; + if(field_storage.intr_block_rf.error_intr_trig_r.error2_trig.value != '0) begin // stickybit + next_c = field_storage.intr_block_rf.error_internal_intr_r.error2_sts.value | field_storage.intr_block_rf.error_intr_trig_r.error2_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.error_internal_intr_r.error2_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end else if(decoded_reg_strb.intr_block_rf.error_internal_intr_r && decoded_req_is_wr) begin // SW write 1 clear + next_c = field_storage.intr_block_rf.error_internal_intr_r.error2_sts.value & ~(decoded_wr_data[2:2] & decoded_wr_biten[2:2]); + load_next_c = '1; + end + field_combo.intr_block_rf.error_internal_intr_r.error2_sts.next = next_c; + field_combo.intr_block_rf.error_internal_intr_r.error2_sts.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.error_reset_b) begin + if(~hwif_in.error_reset_b) begin + field_storage.intr_block_rf.error_internal_intr_r.error2_sts.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_internal_intr_r.error2_sts.load_next) begin + field_storage.intr_block_rf.error_internal_intr_r.error2_sts.value <= field_combo.intr_block_rf.error_internal_intr_r.error2_sts.next; + end + end + // Field: sha3_reg.intr_block_rf.error_internal_intr_r.error3_sts + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_internal_intr_r.error3_sts.value; + load_next_c = '0; + if(field_storage.intr_block_rf.error_intr_trig_r.error3_trig.value != '0) begin // stickybit + next_c = field_storage.intr_block_rf.error_internal_intr_r.error3_sts.value | field_storage.intr_block_rf.error_intr_trig_r.error3_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.error_internal_intr_r.error3_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end else if(decoded_reg_strb.intr_block_rf.error_internal_intr_r && decoded_req_is_wr) begin // SW write 1 clear + next_c = field_storage.intr_block_rf.error_internal_intr_r.error3_sts.value & ~(decoded_wr_data[3:3] & decoded_wr_biten[3:3]); + load_next_c = '1; + end + field_combo.intr_block_rf.error_internal_intr_r.error3_sts.next = next_c; + field_combo.intr_block_rf.error_internal_intr_r.error3_sts.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.error_reset_b) begin + if(~hwif_in.error_reset_b) begin + field_storage.intr_block_rf.error_internal_intr_r.error3_sts.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_internal_intr_r.error3_sts.load_next) begin + field_storage.intr_block_rf.error_internal_intr_r.error3_sts.value <= field_combo.intr_block_rf.error_internal_intr_r.error3_sts.next; + end + end + assign hwif_out.intr_block_rf.error_internal_intr_r.intr = + |(field_storage.intr_block_rf.error_internal_intr_r.sha3_error_sts.value & field_storage.intr_block_rf.error_intr_en_r.sha3_error_en.value) + || |(field_storage.intr_block_rf.error_internal_intr_r.error1_sts.value & field_storage.intr_block_rf.error_intr_en_r.error1_en.value) + || |(field_storage.intr_block_rf.error_internal_intr_r.error2_sts.value & field_storage.intr_block_rf.error_intr_en_r.error2_en.value) + || |(field_storage.intr_block_rf.error_internal_intr_r.error3_sts.value & field_storage.intr_block_rf.error_intr_en_r.error3_en.value); + // Field: sha3_reg.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.value; + load_next_c = '0; + if(field_storage.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.value != '0) begin // stickybit + next_c = field_storage.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.value | field_storage.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end else if(decoded_reg_strb.intr_block_rf.notif_internal_intr_r && decoded_req_is_wr) begin // SW write 1 clear + next_c = field_storage.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.value & ~(decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end + field_combo.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.next = next_c; + field_combo.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.value <= 1'h0; + end else if(field_combo.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.load_next) begin + field_storage.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.value <= field_combo.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.next; + end + end + // Field: sha3_reg.intr_block_rf.notif_internal_intr_r.notif_msg_fifo_empty_sts + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_internal_intr_r.notif_msg_fifo_empty_sts.value; + load_next_c = '0; + if(field_storage.intr_block_rf.notif_intr_trig_r.notif_msg_fifo_empty_trig.value != '0) begin // stickybit + next_c = field_storage.intr_block_rf.notif_internal_intr_r.notif_msg_fifo_empty_sts.value | field_storage.intr_block_rf.notif_intr_trig_r.notif_msg_fifo_empty_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.notif_internal_intr_r.notif_msg_fifo_empty_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end else if(decoded_reg_strb.intr_block_rf.notif_internal_intr_r && decoded_req_is_wr) begin // SW write 1 clear + next_c = field_storage.intr_block_rf.notif_internal_intr_r.notif_msg_fifo_empty_sts.value & ~(decoded_wr_data[1:1] & decoded_wr_biten[1:1]); + load_next_c = '1; + end + field_combo.intr_block_rf.notif_internal_intr_r.notif_msg_fifo_empty_sts.next = next_c; + field_combo.intr_block_rf.notif_internal_intr_r.notif_msg_fifo_empty_sts.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.notif_internal_intr_r.notif_msg_fifo_empty_sts.value <= 1'h0; + end else if(field_combo.intr_block_rf.notif_internal_intr_r.notif_msg_fifo_empty_sts.load_next) begin + field_storage.intr_block_rf.notif_internal_intr_r.notif_msg_fifo_empty_sts.value <= field_combo.intr_block_rf.notif_internal_intr_r.notif_msg_fifo_empty_sts.next; + end + end + assign hwif_out.intr_block_rf.notif_internal_intr_r.intr = + |(field_storage.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.value & field_storage.intr_block_rf.notif_intr_en_r.notif_cmd_done_en.value) + || |(field_storage.intr_block_rf.notif_internal_intr_r.notif_msg_fifo_empty_sts.value & field_storage.intr_block_rf.notif_intr_en_r.notif_msg_fifo_empty_en.value); + // Field: sha3_reg.intr_block_rf.error_intr_trig_r.sha3_error_trig + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_intr_trig_r.sha3_error_trig.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_intr_trig_r && decoded_req_is_wr) begin // SW write 1 set + next_c = field_storage.intr_block_rf.error_intr_trig_r.sha3_error_trig.value | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end else begin // singlepulse clears back to 0 + next_c = '0; + load_next_c = '1; + end + field_combo.intr_block_rf.error_intr_trig_r.sha3_error_trig.next = next_c; + field_combo.intr_block_rf.error_intr_trig_r.sha3_error_trig.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.error_intr_trig_r.sha3_error_trig.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_intr_trig_r.sha3_error_trig.load_next) begin + field_storage.intr_block_rf.error_intr_trig_r.sha3_error_trig.value <= field_combo.intr_block_rf.error_intr_trig_r.sha3_error_trig.next; + end + end + // Field: sha3_reg.intr_block_rf.error_intr_trig_r.error1_trig + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_intr_trig_r.error1_trig.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_intr_trig_r && decoded_req_is_wr) begin // SW write 1 set + next_c = field_storage.intr_block_rf.error_intr_trig_r.error1_trig.value | (decoded_wr_data[1:1] & decoded_wr_biten[1:1]); + load_next_c = '1; + end else begin // singlepulse clears back to 0 + next_c = '0; + load_next_c = '1; + end + field_combo.intr_block_rf.error_intr_trig_r.error1_trig.next = next_c; + field_combo.intr_block_rf.error_intr_trig_r.error1_trig.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.error_intr_trig_r.error1_trig.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_intr_trig_r.error1_trig.load_next) begin + field_storage.intr_block_rf.error_intr_trig_r.error1_trig.value <= field_combo.intr_block_rf.error_intr_trig_r.error1_trig.next; + end + end + // Field: sha3_reg.intr_block_rf.error_intr_trig_r.error2_trig + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_intr_trig_r.error2_trig.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_intr_trig_r && decoded_req_is_wr) begin // SW write 1 set + next_c = field_storage.intr_block_rf.error_intr_trig_r.error2_trig.value | (decoded_wr_data[2:2] & decoded_wr_biten[2:2]); + load_next_c = '1; + end else begin // singlepulse clears back to 0 + next_c = '0; + load_next_c = '1; + end + field_combo.intr_block_rf.error_intr_trig_r.error2_trig.next = next_c; + field_combo.intr_block_rf.error_intr_trig_r.error2_trig.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.error_intr_trig_r.error2_trig.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_intr_trig_r.error2_trig.load_next) begin + field_storage.intr_block_rf.error_intr_trig_r.error2_trig.value <= field_combo.intr_block_rf.error_intr_trig_r.error2_trig.next; + end + end + // Field: sha3_reg.intr_block_rf.error_intr_trig_r.error3_trig + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_intr_trig_r.error3_trig.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_intr_trig_r && decoded_req_is_wr) begin // SW write 1 set + next_c = field_storage.intr_block_rf.error_intr_trig_r.error3_trig.value | (decoded_wr_data[3:3] & decoded_wr_biten[3:3]); + load_next_c = '1; + end else begin // singlepulse clears back to 0 + next_c = '0; + load_next_c = '1; + end + field_combo.intr_block_rf.error_intr_trig_r.error3_trig.next = next_c; + field_combo.intr_block_rf.error_intr_trig_r.error3_trig.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.error_intr_trig_r.error3_trig.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_intr_trig_r.error3_trig.load_next) begin + field_storage.intr_block_rf.error_intr_trig_r.error3_trig.value <= field_combo.intr_block_rf.error_intr_trig_r.error3_trig.next; + end + end + // Field: sha3_reg.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.notif_intr_trig_r && decoded_req_is_wr) begin // SW write 1 set + next_c = field_storage.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.value | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end else begin // singlepulse clears back to 0 + next_c = '0; + load_next_c = '1; + end + field_combo.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.next = next_c; + field_combo.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.value <= 1'h0; + end else if(field_combo.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.load_next) begin + field_storage.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.value <= field_combo.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.next; + end + end + // Field: sha3_reg.intr_block_rf.notif_intr_trig_r.notif_msg_fifo_empty_trig + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_intr_trig_r.notif_msg_fifo_empty_trig.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.notif_intr_trig_r && decoded_req_is_wr) begin // SW write 1 set + next_c = field_storage.intr_block_rf.notif_intr_trig_r.notif_msg_fifo_empty_trig.value | (decoded_wr_data[1:1] & decoded_wr_biten[1:1]); + load_next_c = '1; + end else begin // singlepulse clears back to 0 + next_c = '0; + load_next_c = '1; + end + field_combo.intr_block_rf.notif_intr_trig_r.notif_msg_fifo_empty_trig.next = next_c; + field_combo.intr_block_rf.notif_intr_trig_r.notif_msg_fifo_empty_trig.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.notif_intr_trig_r.notif_msg_fifo_empty_trig.value <= 1'h0; + end else if(field_combo.intr_block_rf.notif_intr_trig_r.notif_msg_fifo_empty_trig.load_next) begin + field_storage.intr_block_rf.notif_intr_trig_r.notif_msg_fifo_empty_trig.value <= field_combo.intr_block_rf.notif_intr_trig_r.notif_msg_fifo_empty_trig.next; + end + end + // Field: sha3_reg.intr_block_rf.sha3_error_intr_count_r.cnt + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.sha3_error_intr_count_r.cnt.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.sha3_error_intr_count_r && decoded_req_is_wr) begin // SW write + next_c = (field_storage.intr_block_rf.sha3_error_intr_count_r.cnt.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + if(field_storage.intr_block_rf.sha3_error_intr_count_incr_r.pulse.value) begin // increment + if(((33)'(next_c) + 32'h1) > 32'hffffffff) begin // up-counter saturated + next_c = 32'hffffffff; + end else begin + next_c = next_c + 32'h1; + end + load_next_c = '1; + end + field_combo.intr_block_rf.sha3_error_intr_count_r.cnt.incrthreshold = (field_storage.intr_block_rf.sha3_error_intr_count_r.cnt.value >= 32'hffffffff); + field_combo.intr_block_rf.sha3_error_intr_count_r.cnt.incrsaturate = (field_storage.intr_block_rf.sha3_error_intr_count_r.cnt.value >= 32'hffffffff); + if(next_c > 32'hffffffff) begin + next_c = 32'hffffffff; + load_next_c = '1; + end + field_combo.intr_block_rf.sha3_error_intr_count_r.cnt.next = next_c; + field_combo.intr_block_rf.sha3_error_intr_count_r.cnt.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.error_reset_b) begin + if(~hwif_in.error_reset_b) begin + field_storage.intr_block_rf.sha3_error_intr_count_r.cnt.value <= 32'h0; + end else if(field_combo.intr_block_rf.sha3_error_intr_count_r.cnt.load_next) begin + field_storage.intr_block_rf.sha3_error_intr_count_r.cnt.value <= field_combo.intr_block_rf.sha3_error_intr_count_r.cnt.next; + end + end + // Field: sha3_reg.intr_block_rf.error1_intr_count_r.cnt + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error1_intr_count_r.cnt.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error1_intr_count_r && decoded_req_is_wr) begin // SW write + next_c = (field_storage.intr_block_rf.error1_intr_count_r.cnt.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + if(field_storage.intr_block_rf.error1_intr_count_incr_r.pulse.value) begin // increment + if(((33)'(next_c) + 32'h1) > 32'hffffffff) begin // up-counter saturated + next_c = 32'hffffffff; + end else begin + next_c = next_c + 32'h1; + end + load_next_c = '1; + end + field_combo.intr_block_rf.error1_intr_count_r.cnt.incrthreshold = (field_storage.intr_block_rf.error1_intr_count_r.cnt.value >= 32'hffffffff); + field_combo.intr_block_rf.error1_intr_count_r.cnt.incrsaturate = (field_storage.intr_block_rf.error1_intr_count_r.cnt.value >= 32'hffffffff); + if(next_c > 32'hffffffff) begin + next_c = 32'hffffffff; + load_next_c = '1; + end + field_combo.intr_block_rf.error1_intr_count_r.cnt.next = next_c; + field_combo.intr_block_rf.error1_intr_count_r.cnt.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.error_reset_b) begin + if(~hwif_in.error_reset_b) begin + field_storage.intr_block_rf.error1_intr_count_r.cnt.value <= 32'h0; + end else if(field_combo.intr_block_rf.error1_intr_count_r.cnt.load_next) begin + field_storage.intr_block_rf.error1_intr_count_r.cnt.value <= field_combo.intr_block_rf.error1_intr_count_r.cnt.next; + end + end + // Field: sha3_reg.intr_block_rf.error2_intr_count_r.cnt + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error2_intr_count_r.cnt.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error2_intr_count_r && decoded_req_is_wr) begin // SW write + next_c = (field_storage.intr_block_rf.error2_intr_count_r.cnt.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + if(field_storage.intr_block_rf.error2_intr_count_incr_r.pulse.value) begin // increment + if(((33)'(next_c) + 32'h1) > 32'hffffffff) begin // up-counter saturated + next_c = 32'hffffffff; + end else begin + next_c = next_c + 32'h1; + end + load_next_c = '1; + end + field_combo.intr_block_rf.error2_intr_count_r.cnt.incrthreshold = (field_storage.intr_block_rf.error2_intr_count_r.cnt.value >= 32'hffffffff); + field_combo.intr_block_rf.error2_intr_count_r.cnt.incrsaturate = (field_storage.intr_block_rf.error2_intr_count_r.cnt.value >= 32'hffffffff); + if(next_c > 32'hffffffff) begin + next_c = 32'hffffffff; + load_next_c = '1; + end + field_combo.intr_block_rf.error2_intr_count_r.cnt.next = next_c; + field_combo.intr_block_rf.error2_intr_count_r.cnt.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.error_reset_b) begin + if(~hwif_in.error_reset_b) begin + field_storage.intr_block_rf.error2_intr_count_r.cnt.value <= 32'h0; + end else if(field_combo.intr_block_rf.error2_intr_count_r.cnt.load_next) begin + field_storage.intr_block_rf.error2_intr_count_r.cnt.value <= field_combo.intr_block_rf.error2_intr_count_r.cnt.next; + end + end + // Field: sha3_reg.intr_block_rf.error3_intr_count_r.cnt + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error3_intr_count_r.cnt.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error3_intr_count_r && decoded_req_is_wr) begin // SW write + next_c = (field_storage.intr_block_rf.error3_intr_count_r.cnt.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + if(field_storage.intr_block_rf.error3_intr_count_incr_r.pulse.value) begin // increment + if(((33)'(next_c) + 32'h1) > 32'hffffffff) begin // up-counter saturated + next_c = 32'hffffffff; + end else begin + next_c = next_c + 32'h1; + end + load_next_c = '1; + end + field_combo.intr_block_rf.error3_intr_count_r.cnt.incrthreshold = (field_storage.intr_block_rf.error3_intr_count_r.cnt.value >= 32'hffffffff); + field_combo.intr_block_rf.error3_intr_count_r.cnt.incrsaturate = (field_storage.intr_block_rf.error3_intr_count_r.cnt.value >= 32'hffffffff); + if(next_c > 32'hffffffff) begin + next_c = 32'hffffffff; + load_next_c = '1; + end + field_combo.intr_block_rf.error3_intr_count_r.cnt.next = next_c; + field_combo.intr_block_rf.error3_intr_count_r.cnt.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.error_reset_b) begin + if(~hwif_in.error_reset_b) begin + field_storage.intr_block_rf.error3_intr_count_r.cnt.value <= 32'h0; + end else if(field_combo.intr_block_rf.error3_intr_count_r.cnt.load_next) begin + field_storage.intr_block_rf.error3_intr_count_r.cnt.value <= field_combo.intr_block_rf.error3_intr_count_r.cnt.next; + end + end + // Field: sha3_reg.intr_block_rf.notif_cmd_done_intr_count_r.cnt + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_cmd_done_intr_count_r.cnt.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.notif_cmd_done_intr_count_r && decoded_req_is_wr) begin // SW write + next_c = (field_storage.intr_block_rf.notif_cmd_done_intr_count_r.cnt.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + if(field_storage.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.value) begin // increment + if(((33)'(next_c) + 32'h1) > 32'hffffffff) begin // up-counter saturated + next_c = 32'hffffffff; + end else begin + next_c = next_c + 32'h1; + end + load_next_c = '1; + end + field_combo.intr_block_rf.notif_cmd_done_intr_count_r.cnt.incrthreshold = (field_storage.intr_block_rf.notif_cmd_done_intr_count_r.cnt.value >= 32'hffffffff); + field_combo.intr_block_rf.notif_cmd_done_intr_count_r.cnt.incrsaturate = (field_storage.intr_block_rf.notif_cmd_done_intr_count_r.cnt.value >= 32'hffffffff); + if(next_c > 32'hffffffff) begin + next_c = 32'hffffffff; + load_next_c = '1; + end + field_combo.intr_block_rf.notif_cmd_done_intr_count_r.cnt.next = next_c; + field_combo.intr_block_rf.notif_cmd_done_intr_count_r.cnt.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.notif_cmd_done_intr_count_r.cnt.value <= 32'h0; + end else if(field_combo.intr_block_rf.notif_cmd_done_intr_count_r.cnt.load_next) begin + field_storage.intr_block_rf.notif_cmd_done_intr_count_r.cnt.value <= field_combo.intr_block_rf.notif_cmd_done_intr_count_r.cnt.next; + end + end + // Field: sha3_reg.intr_block_rf.sha3_error_intr_count_incr_r.pulse + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.sha3_error_intr_count_incr_r.pulse.value; + load_next_c = '0; + if(field_storage.intr_block_rf.error_intr_trig_r.sha3_error_trig.value) begin // HW Write - we + next_c = field_storage.intr_block_rf.error_intr_trig_r.sha3_error_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.error_internal_intr_r.sha3_error_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end + if(field_storage.intr_block_rf.sha3_error_intr_count_incr_r.pulse.value) begin // decrement + field_combo.intr_block_rf.sha3_error_intr_count_incr_r.pulse.underflow = (next_c < (1'h1)); + next_c = next_c - 1'h1; + load_next_c = '1; + end else begin + field_combo.intr_block_rf.sha3_error_intr_count_incr_r.pulse.underflow = '0; + end + field_combo.intr_block_rf.sha3_error_intr_count_incr_r.pulse.decrthreshold = (field_storage.intr_block_rf.sha3_error_intr_count_incr_r.pulse.value <= 1'd0); + field_combo.intr_block_rf.sha3_error_intr_count_incr_r.pulse.next = next_c; + field_combo.intr_block_rf.sha3_error_intr_count_incr_r.pulse.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.sha3_error_intr_count_incr_r.pulse.value <= 1'h0; + end else if(field_combo.intr_block_rf.sha3_error_intr_count_incr_r.pulse.load_next) begin + field_storage.intr_block_rf.sha3_error_intr_count_incr_r.pulse.value <= field_combo.intr_block_rf.sha3_error_intr_count_incr_r.pulse.next; + end + end + // Field: sha3_reg.intr_block_rf.error1_intr_count_incr_r.pulse + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error1_intr_count_incr_r.pulse.value; + load_next_c = '0; + if(field_storage.intr_block_rf.error_intr_trig_r.error1_trig.value) begin // HW Write - we + next_c = field_storage.intr_block_rf.error_intr_trig_r.error1_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.error_internal_intr_r.error1_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end + if(field_storage.intr_block_rf.error1_intr_count_incr_r.pulse.value) begin // decrement + field_combo.intr_block_rf.error1_intr_count_incr_r.pulse.underflow = (next_c < (1'h1)); + next_c = next_c - 1'h1; + load_next_c = '1; + end else begin + field_combo.intr_block_rf.error1_intr_count_incr_r.pulse.underflow = '0; + end + field_combo.intr_block_rf.error1_intr_count_incr_r.pulse.decrthreshold = (field_storage.intr_block_rf.error1_intr_count_incr_r.pulse.value <= 1'd0); + field_combo.intr_block_rf.error1_intr_count_incr_r.pulse.next = next_c; + field_combo.intr_block_rf.error1_intr_count_incr_r.pulse.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.error1_intr_count_incr_r.pulse.value <= 1'h0; + end else if(field_combo.intr_block_rf.error1_intr_count_incr_r.pulse.load_next) begin + field_storage.intr_block_rf.error1_intr_count_incr_r.pulse.value <= field_combo.intr_block_rf.error1_intr_count_incr_r.pulse.next; + end + end + // Field: sha3_reg.intr_block_rf.error2_intr_count_incr_r.pulse + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error2_intr_count_incr_r.pulse.value; + load_next_c = '0; + if(field_storage.intr_block_rf.error_intr_trig_r.error2_trig.value) begin // HW Write - we + next_c = field_storage.intr_block_rf.error_intr_trig_r.error2_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.error_internal_intr_r.error2_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end + if(field_storage.intr_block_rf.error2_intr_count_incr_r.pulse.value) begin // decrement + field_combo.intr_block_rf.error2_intr_count_incr_r.pulse.underflow = (next_c < (1'h1)); + next_c = next_c - 1'h1; + load_next_c = '1; + end else begin + field_combo.intr_block_rf.error2_intr_count_incr_r.pulse.underflow = '0; + end + field_combo.intr_block_rf.error2_intr_count_incr_r.pulse.decrthreshold = (field_storage.intr_block_rf.error2_intr_count_incr_r.pulse.value <= 1'd0); + field_combo.intr_block_rf.error2_intr_count_incr_r.pulse.next = next_c; + field_combo.intr_block_rf.error2_intr_count_incr_r.pulse.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.error2_intr_count_incr_r.pulse.value <= 1'h0; + end else if(field_combo.intr_block_rf.error2_intr_count_incr_r.pulse.load_next) begin + field_storage.intr_block_rf.error2_intr_count_incr_r.pulse.value <= field_combo.intr_block_rf.error2_intr_count_incr_r.pulse.next; + end + end + // Field: sha3_reg.intr_block_rf.error3_intr_count_incr_r.pulse + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error3_intr_count_incr_r.pulse.value; + load_next_c = '0; + if(field_storage.intr_block_rf.error_intr_trig_r.error3_trig.value) begin // HW Write - we + next_c = field_storage.intr_block_rf.error_intr_trig_r.error3_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.error_internal_intr_r.error3_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end + if(field_storage.intr_block_rf.error3_intr_count_incr_r.pulse.value) begin // decrement + field_combo.intr_block_rf.error3_intr_count_incr_r.pulse.underflow = (next_c < (1'h1)); + next_c = next_c - 1'h1; + load_next_c = '1; + end else begin + field_combo.intr_block_rf.error3_intr_count_incr_r.pulse.underflow = '0; + end + field_combo.intr_block_rf.error3_intr_count_incr_r.pulse.decrthreshold = (field_storage.intr_block_rf.error3_intr_count_incr_r.pulse.value <= 1'd0); + field_combo.intr_block_rf.error3_intr_count_incr_r.pulse.next = next_c; + field_combo.intr_block_rf.error3_intr_count_incr_r.pulse.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.error3_intr_count_incr_r.pulse.value <= 1'h0; + end else if(field_combo.intr_block_rf.error3_intr_count_incr_r.pulse.load_next) begin + field_storage.intr_block_rf.error3_intr_count_incr_r.pulse.value <= field_combo.intr_block_rf.error3_intr_count_incr_r.pulse.next; + end + end + // Field: sha3_reg.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.value; + load_next_c = '0; + if(field_storage.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.value) begin // HW Write - we + next_c = field_storage.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end + if(field_storage.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.value) begin // decrement + field_combo.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.underflow = (next_c < (1'h1)); + next_c = next_c - 1'h1; + load_next_c = '1; + end else begin + field_combo.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.underflow = '0; + end + field_combo.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.decrthreshold = (field_storage.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.value <= 1'd0); + field_combo.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.next = next_c; + field_combo.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.value <= 1'h0; + end else if(field_combo.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.load_next) begin + field_storage.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.value <= field_combo.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.next; + end + end + assign hwif_out.MSG_FIFO.req = decoded_reg_strb.MSG_FIFO; + assign hwif_out.MSG_FIFO.addr = decoded_addr[8:0]; + assign hwif_out.MSG_FIFO.req_is_wr = decoded_req_is_wr; + assign hwif_out.MSG_FIFO.wr_data = decoded_wr_data; + assign hwif_out.MSG_FIFO.wr_biten = decoded_wr_biten; + + //-------------------------------------------------------------------------- + // Write response + //-------------------------------------------------------------------------- + always_comb begin + automatic logic wr_ack; + wr_ack = '0; + wr_ack |= hwif_in.CFG_SHADOWED.wr_ack; + wr_ack |= hwif_in.STATE.wr_ack; + wr_ack |= hwif_in.MSG_FIFO.wr_ack; + external_wr_ack = wr_ack; + end + assign cpuif_wr_ack = external_wr_ack | (decoded_req & decoded_req_is_wr & ~decoded_strb_is_external); + // Writes are always granted with no error response + assign cpuif_wr_err = '0; + + //-------------------------------------------------------------------------- + // Readback + //-------------------------------------------------------------------------- + logic readback_external_rd_ack_c; + always_comb begin + automatic logic rd_ack; + rd_ack = '0; + rd_ack |= hwif_in.CFG_SHADOWED.rd_ack; + rd_ack |= hwif_in.STATE.rd_ack; + rd_ack |= hwif_in.MSG_FIFO.rd_ack; + readback_external_rd_ack_c = rd_ack; + end + + logic readback_external_rd_ack; + + assign readback_external_rd_ack = readback_external_rd_ack_c; + + logic readback_err; + logic readback_done; + logic [31:0] readback_data; + + // Assign readback values to a flattened array + logic [30-1:0][31:0] readback_array; + for(genvar i0=0; i0<2; i0++) begin + assign readback_array[i0*1 + 0][31:0] = (decoded_reg_strb.SHA3_NAME[i0] && !decoded_req_is_wr) ? hwif_in.SHA3_NAME[i0].NAME.next : '0; + end + for(genvar i0=0; i0<2; i0++) begin + assign readback_array[i0*1 + 2][31:0] = (decoded_reg_strb.SHA3_VERSION[i0] && !decoded_req_is_wr) ? hwif_in.SHA3_VERSION[i0].VERSION.next : '0; + end + assign readback_array[4][0:0] = (decoded_reg_strb.CFG_REGWEN && !decoded_req_is_wr) ? field_storage.CFG_REGWEN.en.value : '0; + assign readback_array[4][31:1] = '0; + assign readback_array[5] = hwif_in.CFG_SHADOWED.rd_ack ? hwif_in.CFG_SHADOWED.rd_data : '0; + assign readback_array[6][5:0] = (decoded_reg_strb.CMD && !decoded_req_is_wr) ? field_storage.CMD.cmd.value : '0; + assign readback_array[6][9:6] = '0; + assign readback_array[6][10:10] = (decoded_reg_strb.CMD && !decoded_req_is_wr) ? field_storage.CMD.err_processed.value : '0; + assign readback_array[6][31:11] = '0; + assign readback_array[7][0:0] = (decoded_reg_strb.STATUS && !decoded_req_is_wr) ? hwif_in.STATUS.sha3_idle.next : '0; + assign readback_array[7][1:1] = (decoded_reg_strb.STATUS && !decoded_req_is_wr) ? hwif_in.STATUS.sha3_absorb.next : '0; + assign readback_array[7][2:2] = (decoded_reg_strb.STATUS && !decoded_req_is_wr) ? hwif_in.STATUS.sha3_squeeze.next : '0; + assign readback_array[7][7:3] = '0; + assign readback_array[7][12:8] = (decoded_reg_strb.STATUS && !decoded_req_is_wr) ? hwif_in.STATUS.fifo_depth.next : '0; + assign readback_array[7][13:13] = '0; + assign readback_array[7][14:14] = (decoded_reg_strb.STATUS && !decoded_req_is_wr) ? hwif_in.STATUS.fifo_empty.next : '0; + assign readback_array[7][15:15] = (decoded_reg_strb.STATUS && !decoded_req_is_wr) ? hwif_in.STATUS.fifo_full.next : '0; + assign readback_array[7][16:16] = (decoded_reg_strb.STATUS && !decoded_req_is_wr) ? hwif_in.STATUS.ALERT_FATAL_FAULT.next : '0; + assign readback_array[7][17:17] = (decoded_reg_strb.STATUS && !decoded_req_is_wr) ? hwif_in.STATUS.ALERT_RECOV_CTRL_UPDATE_ERR.next : '0; + assign readback_array[7][31:18] = '0; + assign readback_array[8][31:0] = (decoded_reg_strb.ERR_CODE && !decoded_req_is_wr) ? hwif_in.ERR_CODE.ERR_CODE.next : '0; + assign readback_array[9] = hwif_in.STATE.rd_ack ? hwif_in.STATE.rd_data : '0; + assign readback_array[10][0:0] = (decoded_reg_strb.intr_block_rf.global_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.global_intr_en_r.error_en.value : '0; + assign readback_array[10][1:1] = (decoded_reg_strb.intr_block_rf.global_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.global_intr_en_r.notif_en.value : '0; + assign readback_array[10][31:2] = '0; + assign readback_array[11][0:0] = (decoded_reg_strb.intr_block_rf.error_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_en_r.sha3_error_en.value : '0; + assign readback_array[11][1:1] = (decoded_reg_strb.intr_block_rf.error_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_en_r.error1_en.value : '0; + assign readback_array[11][2:2] = (decoded_reg_strb.intr_block_rf.error_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_en_r.error2_en.value : '0; + assign readback_array[11][3:3] = (decoded_reg_strb.intr_block_rf.error_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_en_r.error3_en.value : '0; + assign readback_array[11][31:4] = '0; + assign readback_array[12][0:0] = (decoded_reg_strb.intr_block_rf.notif_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_intr_en_r.notif_cmd_done_en.value : '0; + assign readback_array[12][1:1] = (decoded_reg_strb.intr_block_rf.notif_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_intr_en_r.notif_msg_fifo_empty_en.value : '0; + assign readback_array[12][31:2] = '0; + assign readback_array[13][0:0] = (decoded_reg_strb.intr_block_rf.error_global_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_global_intr_r.agg_sts.value : '0; + assign readback_array[13][31:1] = '0; + assign readback_array[14][0:0] = (decoded_reg_strb.intr_block_rf.notif_global_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_global_intr_r.agg_sts.value : '0; + assign readback_array[14][31:1] = '0; + assign readback_array[15][0:0] = (decoded_reg_strb.intr_block_rf.error_internal_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_internal_intr_r.sha3_error_sts.value : '0; + assign readback_array[15][1:1] = (decoded_reg_strb.intr_block_rf.error_internal_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_internal_intr_r.error1_sts.value : '0; + assign readback_array[15][2:2] = (decoded_reg_strb.intr_block_rf.error_internal_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_internal_intr_r.error2_sts.value : '0; + assign readback_array[15][3:3] = (decoded_reg_strb.intr_block_rf.error_internal_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_internal_intr_r.error3_sts.value : '0; + assign readback_array[15][31:4] = '0; + assign readback_array[16][0:0] = (decoded_reg_strb.intr_block_rf.notif_internal_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.value : '0; + assign readback_array[16][1:1] = (decoded_reg_strb.intr_block_rf.notif_internal_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_internal_intr_r.notif_msg_fifo_empty_sts.value : '0; + assign readback_array[16][31:2] = '0; + assign readback_array[17][0:0] = (decoded_reg_strb.intr_block_rf.error_intr_trig_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_trig_r.sha3_error_trig.value : '0; + assign readback_array[17][1:1] = (decoded_reg_strb.intr_block_rf.error_intr_trig_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_trig_r.error1_trig.value : '0; + assign readback_array[17][2:2] = (decoded_reg_strb.intr_block_rf.error_intr_trig_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_trig_r.error2_trig.value : '0; + assign readback_array[17][3:3] = (decoded_reg_strb.intr_block_rf.error_intr_trig_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_trig_r.error3_trig.value : '0; + assign readback_array[17][31:4] = '0; + assign readback_array[18][0:0] = (decoded_reg_strb.intr_block_rf.notif_intr_trig_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.value : '0; + assign readback_array[18][1:1] = (decoded_reg_strb.intr_block_rf.notif_intr_trig_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_intr_trig_r.notif_msg_fifo_empty_trig.value : '0; + assign readback_array[18][31:2] = '0; + assign readback_array[19][31:0] = (decoded_reg_strb.intr_block_rf.sha3_error_intr_count_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.sha3_error_intr_count_r.cnt.value : '0; + assign readback_array[20][31:0] = (decoded_reg_strb.intr_block_rf.error1_intr_count_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error1_intr_count_r.cnt.value : '0; + assign readback_array[21][31:0] = (decoded_reg_strb.intr_block_rf.error2_intr_count_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error2_intr_count_r.cnt.value : '0; + assign readback_array[22][31:0] = (decoded_reg_strb.intr_block_rf.error3_intr_count_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error3_intr_count_r.cnt.value : '0; + assign readback_array[23][31:0] = (decoded_reg_strb.intr_block_rf.notif_cmd_done_intr_count_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_cmd_done_intr_count_r.cnt.value : '0; + assign readback_array[24][0:0] = (decoded_reg_strb.intr_block_rf.sha3_error_intr_count_incr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.sha3_error_intr_count_incr_r.pulse.value : '0; + assign readback_array[24][31:1] = '0; + assign readback_array[25][0:0] = (decoded_reg_strb.intr_block_rf.error1_intr_count_incr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error1_intr_count_incr_r.pulse.value : '0; + assign readback_array[25][31:1] = '0; + assign readback_array[26][0:0] = (decoded_reg_strb.intr_block_rf.error2_intr_count_incr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error2_intr_count_incr_r.pulse.value : '0; + assign readback_array[26][31:1] = '0; + assign readback_array[27][0:0] = (decoded_reg_strb.intr_block_rf.error3_intr_count_incr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error3_intr_count_incr_r.pulse.value : '0; + assign readback_array[27][31:1] = '0; + assign readback_array[28][0:0] = (decoded_reg_strb.intr_block_rf.notif_cmd_done_intr_count_incr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.value : '0; + assign readback_array[28][31:1] = '0; + assign readback_array[29] = hwif_in.MSG_FIFO.rd_ack ? hwif_in.MSG_FIFO.rd_data : '0; + + // Reduce the array + always_comb begin + automatic logic [31:0] readback_data_var; + readback_done = decoded_req & ~decoded_req_is_wr & ~decoded_strb_is_external; + readback_err = '0; + readback_data_var = '0; + for(int i=0; i<30; i++) readback_data_var |= readback_array[i]; + readback_data = readback_data_var; + end + + assign external_rd_ack = readback_external_rd_ack; + assign cpuif_rd_ack = readback_done | readback_external_rd_ack; + assign cpuif_rd_data = readback_data; + assign cpuif_rd_err = readback_err; + +`CALIPTRA_ASSERT_KNOWN(ERR_HWIF_IN, hwif_in, clk, !hwif_in.error_reset_b) + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/sha3_reg_pkg.sv b/designs/Caliptra/src/caliptra-rtl/sha3_reg_pkg.sv new file mode 100644 index 0000000..191769b --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/sha3_reg_pkg.sv @@ -0,0 +1,235 @@ +// Generated by PeakRDL-regblock - A free and open-source SystemVerilog generator +// https://github.com/SystemRDL/PeakRDL-regblock + +package sha3_reg_pkg; + + localparam SHA3_REG_DATA_WIDTH = 32; + localparam SHA3_REG_MIN_ADDR_WIDTH = 12; + + typedef struct packed{ + logic [31:0] next; + } sha3_reg__SHA3_NAME__NAME__in_t; + + typedef struct packed{ + sha3_reg__SHA3_NAME__NAME__in_t NAME; + } sha3_reg__SHA3_NAME__in_t; + + typedef struct packed{ + logic [31:0] next; + } sha3_reg__SHA3_VERSION__VERSION__in_t; + + typedef struct packed{ + sha3_reg__SHA3_VERSION__VERSION__in_t VERSION; + } sha3_reg__SHA3_VERSION__in_t; + + typedef struct packed{ + logic next; + } sha3_reg__CFG_REGWEN__en__in_t; + + typedef struct packed{ + sha3_reg__CFG_REGWEN__en__in_t en; + } sha3_reg__CFG_REGWEN__in_t; + + typedef struct packed{ + logic rd_ack; + logic [31:0] rd_data; + logic wr_ack; + } sha3_reg__CFG_SHADOWED__external__in_t; + + typedef struct packed{ + logic next; + } sha3_reg__STATUS__sha3_idle__in_t; + + typedef struct packed{ + logic next; + } sha3_reg__STATUS__sha3_absorb__in_t; + + typedef struct packed{ + logic next; + } sha3_reg__STATUS__sha3_squeeze__in_t; + + typedef struct packed{ + logic [4:0] next; + } sha3_reg__STATUS__fifo_depth__in_t; + + typedef struct packed{ + logic next; + } sha3_reg__STATUS__fifo_empty__in_t; + + typedef struct packed{ + logic next; + } sha3_reg__STATUS__fifo_full__in_t; + + typedef struct packed{ + logic next; + } sha3_reg__STATUS__ALERT_FATAL_FAULT__in_t; + + typedef struct packed{ + logic next; + } sha3_reg__STATUS__ALERT_RECOV_CTRL_UPDATE_ERR__in_t; + + typedef struct packed{ + sha3_reg__STATUS__sha3_idle__in_t sha3_idle; + sha3_reg__STATUS__sha3_absorb__in_t sha3_absorb; + sha3_reg__STATUS__sha3_squeeze__in_t sha3_squeeze; + sha3_reg__STATUS__fifo_depth__in_t fifo_depth; + sha3_reg__STATUS__fifo_empty__in_t fifo_empty; + sha3_reg__STATUS__fifo_full__in_t fifo_full; + sha3_reg__STATUS__ALERT_FATAL_FAULT__in_t ALERT_FATAL_FAULT; + sha3_reg__STATUS__ALERT_RECOV_CTRL_UPDATE_ERR__in_t ALERT_RECOV_CTRL_UPDATE_ERR; + } sha3_reg__STATUS__in_t; + + typedef struct packed{ + logic [31:0] next; + } sha3_reg__ERR_CODE__ERR_CODE__in_t; + + typedef struct packed{ + sha3_reg__ERR_CODE__ERR_CODE__in_t ERR_CODE; + } sha3_reg__ERR_CODE__in_t; + + typedef struct packed{ + logic rd_ack; + logic [31:0] rd_data; + logic wr_ack; + } sha3_reg__STATE__external__in_t; + + typedef struct packed{ + logic hwset; + } sha3_reg__error_intr_t_error1_sts_40e0d3e1_error2_sts_b1cf2205_error3_sts_74a35378_sha3_error_sts_a3cfdcf2__sha3_error_sts_enable_d9cec3d3_next_cfb72aff_resetsignal_939e99d4__in_t; + + typedef struct packed{ + logic hwset; + } sha3_reg__error_intr_t_error1_sts_40e0d3e1_error2_sts_b1cf2205_error3_sts_74a35378_sha3_error_sts_a3cfdcf2__error1_sts_enable_938cafef_next_f460eb81_resetsignal_939e99d4__in_t; + + typedef struct packed{ + logic hwset; + } sha3_reg__error_intr_t_error1_sts_40e0d3e1_error2_sts_b1cf2205_error3_sts_74a35378_sha3_error_sts_a3cfdcf2__error2_sts_enable_0dacf7a6_next_4b5b9e74_resetsignal_939e99d4__in_t; + + typedef struct packed{ + logic hwset; + } sha3_reg__error_intr_t_error1_sts_40e0d3e1_error2_sts_b1cf2205_error3_sts_74a35378_sha3_error_sts_a3cfdcf2__error3_sts_enable_fc3af94b_next_c3125d40_resetsignal_939e99d4__in_t; + + typedef struct packed{ + sha3_reg__error_intr_t_error1_sts_40e0d3e1_error2_sts_b1cf2205_error3_sts_74a35378_sha3_error_sts_a3cfdcf2__sha3_error_sts_enable_d9cec3d3_next_cfb72aff_resetsignal_939e99d4__in_t sha3_error_sts; + sha3_reg__error_intr_t_error1_sts_40e0d3e1_error2_sts_b1cf2205_error3_sts_74a35378_sha3_error_sts_a3cfdcf2__error1_sts_enable_938cafef_next_f460eb81_resetsignal_939e99d4__in_t error1_sts; + sha3_reg__error_intr_t_error1_sts_40e0d3e1_error2_sts_b1cf2205_error3_sts_74a35378_sha3_error_sts_a3cfdcf2__error2_sts_enable_0dacf7a6_next_4b5b9e74_resetsignal_939e99d4__in_t error2_sts; + sha3_reg__error_intr_t_error1_sts_40e0d3e1_error2_sts_b1cf2205_error3_sts_74a35378_sha3_error_sts_a3cfdcf2__error3_sts_enable_fc3af94b_next_c3125d40_resetsignal_939e99d4__in_t error3_sts; + } sha3_reg__error_intr_t_error1_sts_40e0d3e1_error2_sts_b1cf2205_error3_sts_74a35378_sha3_error_sts_a3cfdcf2__in_t; + + typedef struct packed{ + logic hwset; + } sha3_reg__notif_intr_t_notif_cmd_done_sts_1c68637e_notif_msg_fifo_empty_sts_df694e73__notif_cmd_done_sts_enable_dabe0b8b_next_540fa3b7__in_t; + + typedef struct packed{ + logic hwset; + } sha3_reg__notif_intr_t_notif_cmd_done_sts_1c68637e_notif_msg_fifo_empty_sts_df694e73__notif_msg_fifo_empty_sts_enable_16bab8d8_next_b0e8f486__in_t; + + typedef struct packed{ + sha3_reg__notif_intr_t_notif_cmd_done_sts_1c68637e_notif_msg_fifo_empty_sts_df694e73__notif_cmd_done_sts_enable_dabe0b8b_next_540fa3b7__in_t notif_cmd_done_sts; + sha3_reg__notif_intr_t_notif_cmd_done_sts_1c68637e_notif_msg_fifo_empty_sts_df694e73__notif_msg_fifo_empty_sts_enable_16bab8d8_next_b0e8f486__in_t notif_msg_fifo_empty_sts; + } sha3_reg__notif_intr_t_notif_cmd_done_sts_1c68637e_notif_msg_fifo_empty_sts_df694e73__in_t; + + typedef struct packed{ + sha3_reg__error_intr_t_error1_sts_40e0d3e1_error2_sts_b1cf2205_error3_sts_74a35378_sha3_error_sts_a3cfdcf2__in_t error_internal_intr_r; + sha3_reg__notif_intr_t_notif_cmd_done_sts_1c68637e_notif_msg_fifo_empty_sts_df694e73__in_t notif_internal_intr_r; + } sha3_reg__intr_block_t__in_t; + + typedef struct packed{ + logic rd_ack; + logic [31:0] rd_data; + logic wr_ack; + } sha3_reg__MSG_FIFO__external__in_t; + + typedef struct packed{ + logic reset_b; + logic error_reset_b; + sha3_reg__SHA3_NAME__in_t [2-1:0]SHA3_NAME; + sha3_reg__SHA3_VERSION__in_t [2-1:0]SHA3_VERSION; + sha3_reg__CFG_REGWEN__in_t CFG_REGWEN; + sha3_reg__CFG_SHADOWED__external__in_t CFG_SHADOWED; + sha3_reg__STATUS__in_t STATUS; + sha3_reg__ERR_CODE__in_t ERR_CODE; + sha3_reg__STATE__external__in_t STATE; + sha3_reg__intr_block_t__in_t intr_block_rf; + sha3_reg__MSG_FIFO__external__in_t MSG_FIFO; + } sha3_reg__in_t; + + typedef struct packed{ + logic value; + } sha3_reg__CFG_REGWEN__en__out_t; + + typedef struct packed{ + sha3_reg__CFG_REGWEN__en__out_t en; + } sha3_reg__CFG_REGWEN__out_t; + + typedef struct packed{ + logic req; + logic req_is_wr; + logic [31:0] wr_data; + logic [31:0] wr_biten; + } sha3_reg__CFG_SHADOWED__external__out_t; + + typedef struct packed{ + logic [5:0] value; + } sha3_reg__CMD__cmd__out_t; + + typedef struct packed{ + logic value; + } sha3_reg__CMD__err_processed__out_t; + + typedef struct packed{ + sha3_reg__CMD__cmd__out_t cmd; + sha3_reg__CMD__err_processed__out_t err_processed; + } sha3_reg__CMD__out_t; + + typedef struct packed{ + logic req; + logic [7:0] addr; + logic req_is_wr; + logic [31:0] wr_data; + logic [31:0] wr_biten; + } sha3_reg__STATE__external__out_t; + + typedef struct packed{ + logic intr; + } sha3_reg__global_intr_t_agg_sts_dd3dcf0a__out_t; + + typedef struct packed{ + logic intr; + } sha3_reg__global_intr_t_agg_sts_e6399b4a__out_t; + + typedef struct packed{ + logic intr; + } sha3_reg__error_intr_t_error1_sts_40e0d3e1_error2_sts_b1cf2205_error3_sts_74a35378_sha3_error_sts_a3cfdcf2__out_t; + + typedef struct packed{ + logic intr; + } sha3_reg__notif_intr_t_notif_cmd_done_sts_1c68637e_notif_msg_fifo_empty_sts_df694e73__out_t; + + typedef struct packed{ + sha3_reg__global_intr_t_agg_sts_dd3dcf0a__out_t error_global_intr_r; + sha3_reg__global_intr_t_agg_sts_e6399b4a__out_t notif_global_intr_r; + sha3_reg__error_intr_t_error1_sts_40e0d3e1_error2_sts_b1cf2205_error3_sts_74a35378_sha3_error_sts_a3cfdcf2__out_t error_internal_intr_r; + sha3_reg__notif_intr_t_notif_cmd_done_sts_1c68637e_notif_msg_fifo_empty_sts_df694e73__out_t notif_internal_intr_r; + } sha3_reg__intr_block_t__out_t; + + typedef struct packed{ + logic req; + logic [7:0] addr; + logic req_is_wr; + logic [31:0] wr_data; + logic [31:0] wr_biten; + } sha3_reg__MSG_FIFO__external__out_t; + + typedef struct packed{ + sha3_reg__CFG_REGWEN__out_t CFG_REGWEN; + sha3_reg__CFG_SHADOWED__external__out_t CFG_SHADOWED; + sha3_reg__CMD__out_t CMD; + sha3_reg__STATE__external__out_t STATE; + sha3_reg__intr_block_t__out_t intr_block_rf; + sha3_reg__MSG_FIFO__external__out_t MSG_FIFO; + } sha3_reg__out_t; + + localparam SHA3_REG_ADDR_WIDTH = 32'd12; + +endpackage \ No newline at end of file diff --git a/designs/Caliptra/src/caliptra-rtl/sha3pad.sv b/designs/Caliptra/src/caliptra-rtl/sha3pad.sv new file mode 100644 index 0000000..54fc798 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/sha3pad.sv @@ -0,0 +1,887 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// SHA3 padding logic + +`include "caliptra_prim_assert.sv" + +module sha3pad + import sha3_pkg::*; + import lc_ctrl_state_pkg::*; + import lc_ctrl_reg_pkg::*; + import lc_ctrl_pkg::*; +#( + parameter bit EnMasking = 0, + localparam int Share = (EnMasking) ? 2 : 1 +) ( + input clk_i, + input rst_ni, + + // Message interface (FIFO) + input msg_valid_i, + input [MsgWidth-1:0] msg_data_i [Share], + input [MsgStrbW-1:0] msg_strb_i, // one strobe for shares + output logic msg_ready_o, + + // N, S: Used in cSHAKE mode only + input [NSRegisterSize*8-1:0] ns_data_i, // See sha3_pkg for details + + // output to keccak_round: message path + output logic keccak_valid_o, + output logic [KeccakMsgAddrW-1:0] keccak_addr_o, + output logic [MsgWidth-1:0] keccak_data_o [Share], + input logic keccak_ready_i, + + // keccak_round control and status + // `run` initiates the keccak_round to process full keccak_f (24rounds). + // `complete` is an input from keccak round showing the current keccak_f is + // completed. + output logic keccak_run_o, + input keccak_complete_i, + + // configurations + input sha3_mode_e mode_i, + // strength_i is used in bytepad operation. bytepad() is used in cSHAKE only. + // SHA3, SHAKE doesn't have encode_N,S + input keccak_strength_e strength_i, + + // control signal + // start_i is a pulse signal triggers the padding logic (and the rest of SHA) + // to accept the incoming messages. This signal is used in the pad module, + // to initiate the prefix transmitting to keccak_round + input start_i, + // process_i is a pulse signal triggers the pad logic to stop receiving the + // message from MSG_FIFO and pad the trailing bits specified in the SHA3 + // standard. Look at `funcpad` signal for the values. + input process_i, + // done_i is a pulse signal to make the pad logic to clear internal variables + // and to move back to the Idle state for next hashing process. + // done_i may not needed if sw controls the keccak_round directly. + input caliptra_prim_mubi_pkg::mubi4_t done_i, + + // Indication of the Keccak Sponge Absorbing is complete, it is time for SW to + // control the Keccak-round if it needs more digest, or complete by asserting + // `done_i` + output caliptra_prim_mubi_pkg::mubi4_t absorbed_o, + + // Life cycle + input lc_ctrl_pkg::lc_tx_t lc_escalate_en_i, + + // Indication that there was a fault in the sparse encoding + output logic sparse_fsm_error_o, + + // Indication that there was a fault in the counter + output logic msg_count_error_o +); + + ///////////////// + // Definitions // + ///////////////// + + // Padding States + // Encoding generated with: + // $ ./util/design/sparse-fsm-encode.py -d 3 -m 10 -n 7 \ + // -s 1116691466 --language=sv + // + // Hamming distance histogram: + // + // 0: -- + // 1: -- + // 2: -- + // 3: |||||||||||||||||||| (42.22%) + // 4: |||||||||||||||||| (40.00%) + // 5: ||||| (11.11%) + // 6: || (4.44%) + // 7: | (2.22%) + // + // Minimum Hamming distance: 3 + // Maximum Hamming distance: 7 + // Minimum Hamming weight: 2 + // Maximum Hamming weight: 5 + // + localparam int StateWidthPad = 7; + typedef enum logic [StateWidthPad-1:0] { + StPadIdle = 7'b1000010, + + // Sending a block of prefix, if cSHAKE mode is turned on. For the rest + // (SHA3, SHAKE), sending prefix is not needed. FSM moves from Idle to + // Message directly in that case. + // + // As caliptra_prim_slicer is instantiated, zerofill after the actual prefix is done + // by the module. + StPrefix = 7'b0111100, + StPrefixWait =7'b1001100, + + // Sending Message. In this state, it directly forwards the incoming data + // to Keccak round module. If `process_i` is asserted, then the rest of the + // messages will be discarded until new `start_i` is asserted. + // + // The incoming data can be partial write. Padding logic counts the number + // of bytes received and pause if a block size is transferred. + StMessage = 7'b0100101, + StMessageWait = 7'b0001111, + + // After sending the messages, then `process_i` is set, the FSM pads at the + // end of the message based on `mode_i`. If this is the last byte of the + // block, then it pads [7] to 1 to complete `pad10*1()` function. + StPad = 7'b1111010, + StPadRun = 7'b0011001, + + // If the padding isn't the end of the block byte (which will be rare case), + // FSM moves to another zerofill state. In contrast to StZerofill, this state + StPad01 = 7'b1101001, + + // Flushing the internal packers in front of the Keccak data output port. + StPadFlush = 7'b1010111, + + StTerminalError = 7'b0110011 + } pad_st_e; + + typedef enum logic [2:0] { + MuxNone = 3'b 000, + MuxFifo = 3'b 001, + MuxPrefix = 3'b 010, + MuxFuncPad = 3'b 011, + MuxZeroEnd = 3'b 100 + } mux_sel_e; + + //////////////////// + // Configurations // + //////////////////// + + logic [KeccakCountW-1:0] block_addr_limit; + + // Block size based on the address. + // This is used for bytepad() and also pad10*1() + // assign block_addr_limit = KeccakRate[strength_i]; + // but below is easier to understand + always_comb begin + unique case (strength_i) + L128: block_addr_limit = KeccakCountW'(KeccakRate[L128]); + L224: block_addr_limit = KeccakCountW'(KeccakRate[L224]); + L256: block_addr_limit = KeccakCountW'(KeccakRate[L256]); + L384: block_addr_limit = KeccakCountW'(KeccakRate[L384]); + L512: block_addr_limit = KeccakCountW'(KeccakRate[L512]); + + default: block_addr_limit = '0; + endcase + end + + ///////////////////// + // Control Signals // + ///////////////////// + + // `sel_mux` selects the output data among the incoming or internally generated data. + // MuxFifo: data from external (msg_data_i) + // MuxPrefix: bytepad(encode_string(N)||encode_string(S), ) + // MuxFuncPad: function_pad with end of message + // MuxZeroEnd: all 0 + mux_sel_e sel_mux; + + // `sent_message` indicates the number of entries sent to keccak round per + // block. The value shall be enough to cover Maximum entry of the Keccak + // storage as defined in sha3_pkg, `$clog2(KeccakEntries+1)`. Logically, + // it is not needed to have more than KeccakEntries but for safety in case of + // SHA3 context switch resuming the SHA3 from the middle of sponge + // construction. If needed, the software should be able to write whole 1600 + // bits. The `sent_message` is used to check sent_blocksize. + logic [KeccakCountW-1:0] sent_message; + logic inc_sentmsg, clr_sentmsg; + + // This primitive is used to place a hardened counter + // SEC_CM: CTR.REDUN + caliptra_prim_count #( + .Width(KeccakCountW) + ) u_sentmsg_count ( + .clk_i, + .rst_ni, + .clr_i(clr_sentmsg), + .set_i(1'b0), + .set_cnt_i(KeccakCountW'(0)), + .incr_en_i(inc_sentmsg), + .decr_en_i(1'b0), + .step_i(KeccakCountW'(1)), + .commit_i(1'b1), + .cnt_o(sent_message), + .cnt_after_commit_o(), + .err_o(msg_count_error_o) + ); + + + assign inc_sentmsg = keccak_valid_o & keccak_ready_i ; + + // Prefix index to slice the `prefix` n-bits into multiple of 64bit. + logic [KeccakMsgAddrW-1:0] prefix_index; + assign prefix_index = (sent_message < block_addr_limit) ? sent_message : '0; + + // fsm_keccak_valid is an output signal from FSM which to send data generated + // inside the pad logic to keccak_round + logic fsm_keccak_valid; + + // hold_msg to prevent message from being forwarded into keccak_round and + // acked. Mainly the usage is to hold the message and initiates the + // keccak_round for current block. + logic hold_msg; + + // latch the partial write. Latched data is used for funcpad_merged + logic en_msgbuf; + logic clr_msgbuf; + + /////////////////// + // State Machine // + /////////////////// + + // Inputs + + // FSM moves to StPrefix only when cSHAKE is enabled + logic mode_eq_cshake; + assign mode_eq_cshake = (mode_i == CShake) ? 1'b 1 : 1'b 0; + + // `sent_blocksize` indicates the pad logic pushed block size data into + // keccak round logic. + logic sent_blocksize; + + assign sent_blocksize = (sent_message == block_addr_limit) ? 1'b 1 : 1'b 0; + + // `keccak_ack` indicates the request is accepted in keccak_round + logic keccak_ack; + + assign keccak_ack = keccak_valid_o & keccak_ready_i ; + + // msg_partial indicates the incoming message is partial write or not. + // This is used to check if the incoming message need to be latched inside or + // not. If no partial message is at the end, msg_buf doesn't have to latch + // msg_data_i. It is assumed that the partial message is permitted only at + // the end of the message. So if (msg_valid_i && msg_partial && msg_ready_o), + // there will be no msg_valid_i till process_latched. + // Shall be used with msg_valid_i together. + logic msg_partial; + assign msg_partial = (&msg_strb_i != 1'b 1); + + + // `process_latched` latches the `process_i` input before it is seen in the + // FSM. `process_i` may follow `start_i` too fast so that the FSM may not + // see it fast enought in case of cSHAKE mode. cSHAKE needs to process the + // prefix prior to see the process indicator. + logic process_latched; + + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + process_latched <= 1'b 0; + end else if (process_i) begin + process_latched <= 1'b 1; + end else if (caliptra_prim_mubi_pkg::mubi4_test_true_strict(done_i)) begin + process_latched <= 1'b0; + end + end + + // State Register =========================================================== + pad_st_e st, st_d; + + `CALIPTRA_PRIM_FLOP_SPARSE_FSM(u_state_regs, st_d, st, pad_st_e, StPadIdle) + + // `end_of_block` indicates current beat is end of the block + // It shall set when the address reaches to the end of the block. End address + // is set by the strength_i, which is `block_addr_limit`. + logic end_of_block; + + assign end_of_block = ((sent_message + 1'b1) == block_addr_limit) ? 1'b 1 : 1'b 0; + + + // Next logic and output logic ============================================== + // SEC_CM: ABSORBED.CTRL.MUBI + caliptra_prim_mubi_pkg::mubi4_t absorbed_d; + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) absorbed_o <= caliptra_prim_mubi_pkg::MuBi4False; + else absorbed_o <= absorbed_d; + end + + always_comb begin + st_d = st; + + // FSM output : default values + keccak_run_o = 1'b 0; + sel_mux = MuxNone; + + fsm_keccak_valid = 1'b 0; + + hold_msg = 1'b 0; + clr_sentmsg = 1'b 0; + + en_msgbuf = 1'b 0; + clr_msgbuf = 1'b 0; + + absorbed_d = caliptra_prim_mubi_pkg::MuBi4False; + + sparse_fsm_error_o = 1'b 0; + + unique case (st) + + // In Idle state, the FSM checks if the software (or upper FSM) initiates + // the hash process. If `start_i` is asserted (assume it is pulse), FSM + // starts to push the data into the keccak round logic. Depending on the + // hashing mode, FSM may push additional prefex in front of the actual + // message. It means, the message could be back-pressured until the first + // prefix is processed. + StPadIdle: begin + if (start_i) begin + // If cSHAKE, move to Prefix state + if (mode_eq_cshake) begin + st_d = StPrefix; + end else begin + st_d = StMessage; + end + end else begin + st_d = StPadIdle; + end + end + + // At Prefix state, FSM pushes + // `bytepad(encode_string(N)||encode_string(S), 168or136)`. The software + // already prepared `encode_string(N) || encode_string(S)` in the regs. + // So, the FSM adds 2Byte in front of ns_data_i, which is an encoded + // block size (see `encoded_bytepad` below) + // After pushing the prefix, it initiates the hash process and move to + // Message state. + StPrefix: begin + sel_mux = MuxPrefix; + + if (sent_blocksize) begin + st_d = StPrefixWait; + + keccak_run_o = 1'b 1; + fsm_keccak_valid = 1'b 0; + clr_sentmsg = 1'b 1; + end else begin + st_d = StPrefix; + + fsm_keccak_valid = 1'b 1; + end + end + + StPrefixWait: begin + sel_mux = MuxPrefix; + + if (keccak_complete_i) begin + st_d = StMessage; + end else begin + st_d = StPrefixWait; + end + end + + // Message state pushes the incoming message into keccak round logic. + // It forwards the message while counting the data and if it reaches + // the block size, it triggers the keccak round to run. If `process` is + // set, it moves to Pad state. + StMessage: begin + sel_mux = MuxFifo; + + if (msg_valid_i && msg_partial) begin + st_d = StMessage; + + en_msgbuf = 1'b 1; + end else if (sent_blocksize) begin + // Check block completion first even process is set. + st_d = StMessageWait; + + keccak_run_o = 1'b 1; + clr_sentmsg = 1'b 1; + hold_msg = 1'b 1; + end else if (process_latched || process_i) begin + st_d = StPad; + + // Not asserting the msg_ready_o + hold_msg = 1'b 1; + end else begin + st_d = StMessage; + + end + end + + StMessageWait: begin + hold_msg = 1'b 1; + + if (keccak_complete_i) begin + st_d = StMessage; + end else begin + st_d = StMessageWait; + end + end + + // Pad state just pushes the ending suffix. Depending on the mode, the + // padding value is unique. SHA3 adds 2'b10, SHAKE adds 4'b1111, and + // cSHAKE adds 2'b 00. Refer `function_pad`. The signal has one more bit + // defined to accomodate first 1 bit of `pad10*1()` function. + StPad: begin + sel_mux = MuxFuncPad; + + fsm_keccak_valid = 1'b 1; + + if (keccak_ack && end_of_block) begin + // If padding is the last block, don't have to move to StPad01, just + // run Keccak and complete + st_d = StPadRun; + + // always clear the latched msgbuf + clr_msgbuf = 1'b 1; + clr_sentmsg = 1'b 1; + end else if (keccak_ack) begin + st_d = StPad01; + clr_msgbuf = 1'b 1; + end else begin + st_d = StPad; + end + end + + StPadRun: begin + st_d = StPadFlush; + + keccak_run_o = 1'b 1; + clr_sentmsg = 1'b 1; + end + + // Pad01 pushes the end bit of pad10*1() function. As keccak accepts byte + // size only, StPad always pushes partial (5bits). So at this state, it + // pushes rest of 3bits. If the data pushed in StPad is the last byte of + // the block, then Pad01 pushes to the same byte, if not, it first + // zero-fill the block then pad 1 to the end. + StPad01: begin + sel_mux = MuxZeroEnd; + + // There's no chance StPad01 can be a start of the block. So can be + // discard that the sent_blocksize is set at the beginning. + if (sent_blocksize) begin + st_d = StPadFlush; + + fsm_keccak_valid = 1'b 0; + keccak_run_o = 1'b 1; + clr_sentmsg = 1'b 1; + end else begin + st_d = StPad01; + + fsm_keccak_valid = 1'b 1; + end + end + + StPadFlush: begin + // Wait completion from keccak_round or wait SW indicator. + clr_sentmsg = 1'b 1; + clr_msgbuf = 1'b 1; + + if (keccak_complete_i) begin + st_d = StPadIdle; + + absorbed_d = caliptra_prim_mubi_pkg::MuBi4True; + end else begin + st_d = StPadFlush; + end + end + + StTerminalError: begin + // this state is terminal + st_d = st; + sparse_fsm_error_o = 1'b 1; + end + + default: begin + // this state is terminal + st_d = StTerminalError; + sparse_fsm_error_o = 1'b 1; + end + endcase + + // SEC_CM: FSM.GLOBAL_ESC, FSM.LOCAL_ESC + // Unconditionally jump into the terminal error state + // if the life cycle controller triggers an escalation. + if (lc_ctrl_pkg::lc_tx_test_true_loose(lc_escalate_en_i)) begin + st_d = StTerminalError; + end + end + + ////////////// + // Datapath // + ////////////// + + // `encode_bytepad` represents the first two bytes of bytepad() + // It depends on the block size. We can reuse KeccakRate + // 10000000 || 00010101 // 168 + // 10000000 || 00010001 // 136 + logic [15:0] encode_bytepad; + + assign encode_bytepad = encode_bytepad_len(strength_i); + + // Prefix size ============================================================== + // Prefix represents bytepad(encode_string(N) || encode_string(S), 168 or 136) + // encode_string(N) || encode_string(S) is prepared by the software and given + // through `ns_data_i`. The first part of bytepad is determined by the + // `strength_i` and stored into `encode_bytepad`. + + // It is assumed that the prefix always smaller than the block size. + logic [PrefixSize*8-1:0] prefix; + + assign prefix = {ns_data_i, encode_bytepad}; + + logic [MsgWidth-1:0] prefix_sliced; + logic [MsgWidth-1:0] prefix_data [Share]; + + caliptra_prim_slicer #( + .InW (PrefixSize*8), + .IndexW(KeccakMsgAddrW), + .OutW(MsgWidth) + ) u_prefix_slicer ( + .sel_i (prefix_index), + .data_i (prefix), + .data_o (prefix_sliced) + ); + + if (EnMasking) begin : gen_prefix_masked + // If Masking is enabled, prefix is two share. + assign prefix_data[0] = '0; + assign prefix_data[1] = prefix_sliced; + end else begin : gen_prefix_unmasked + // If Unmasked, only one share exists. + assign prefix_data[0] = prefix_sliced; + end + + // ========================================================================== + // function_pad is the unique value padded at the end of the message based on + // the function among SHA3, SHAKE, cSHAKE. The standard mentioned that SHA3 + // pads `01` , SHAKE pads `1111`, and cSHAKE pads `00`. + // + // Then pad10*1() function follows. It adds `1` first then fill 0 until it + // reaches the block size -1, then adds `1`. + // + // It means always `1` is followed by the function pad. + logic [4:0] funcpad; + + logic [MsgWidth-1:0] funcpad_data [Share]; + + always_comb begin + unique case (mode_i) + Sha3: funcpad = 5'b 00110; + Shake: funcpad = 5'b 11111; + CShake: funcpad = 5'b 00100; + + default: begin + // Just create non-padding but pad10*1 only + funcpad = 5'b 00001; + end + endcase + end + + // ========================================================================== + // `zero_with_endbit` contains all zero unless the message is for the last + // MsgWidth beat in the block. If it is the end of the block, the last bit + // will be set to complete pad10*1() functionality. + logic [MsgWidth-1:0] zero_with_endbit [Share]; + + if (EnMasking) begin : gen_zeroend_masked + assign zero_with_endbit[0] = '0; + assign zero_with_endbit[1][MsgWidth-1] = end_of_block; + assign zero_with_endbit[1][MsgWidth-2:0] = '0; + end else begin : gen_zeroend_unmasked + assign zero_with_endbit[0][MsgWidth-1] = end_of_block; + assign zero_with_endbit[0][MsgWidth-2:0] = '0; + end + + // ========================================================================== + // Data mux for output data + + assign keccak_addr_o = (sent_message < block_addr_limit) ? sent_message : '0; + + always_comb begin + unique case (sel_mux) + MuxFifo: keccak_data_o = msg_data_i; + MuxPrefix: keccak_data_o = prefix_data; + MuxFuncPad: keccak_data_o = funcpad_data; + MuxZeroEnd: keccak_data_o = zero_with_endbit; + + // MuxNone + default: keccak_data_o = '{default:'0}; + endcase + end + + always_comb begin + unique case (sel_mux) + MuxFifo: keccak_valid_o = msg_valid_i & ~hold_msg & ~en_msgbuf; + MuxPrefix: keccak_valid_o = fsm_keccak_valid; + MuxFuncPad: keccak_valid_o = fsm_keccak_valid; + MuxZeroEnd: keccak_valid_o = fsm_keccak_valid; + + // MuxNone + default: keccak_valid_o = 1'b 0; + endcase + end + + always_comb begin + unique case (sel_mux) + MuxFifo: msg_ready_o = en_msgbuf | (keccak_ready_i & ~hold_msg); + MuxPrefix: msg_ready_o = 1'b 0; + MuxFuncPad: msg_ready_o = 1'b 0; + MuxZeroEnd: msg_ready_o = 1'b 0; + + // MuxNone + default: msg_ready_o = 1'b 0; + endcase + end + + // caliptra_prim_packer : packing to 64bit to update keccak storage + // two caliptra_prim_packer in this module are used to pack the data received from + // upper layer (KMAC core) and also the 5bit padding bits. + // It is assumed that the message from upper layer could be partial at the + // end of the message. Then the 2 or 4bit padding is required. It can be + // handled by some custom logic or could be done by caliptra_prim_packer. + // If packer is used, the MSG_FIFO doesn't have to have another caliptra_prim_packer + // in front of the FIFO. This logic can handle the partial writes from the + // software. + // + // If a custom logic is implemented here, caliptra_prim_packer is necessary in front + // of the FIFO, as this logic only appends at the end of the message when + // `process_i` is asserted. Also, in this case, even caliptra_prim_packer is not + // needed, still 64bit registers to latch the partial write is required. + // If not, the logic has to delay the acceptance of the incoming write + // accesses. It may trigger the back-pressuring in some case which may result + // that the software(or upper layer) may not set process_i. + // + // For custom logic, it could be implemented by the 8 mux selection. + // for instance: (subject to be changed) + // unique case (sent_byte[2:0]) // generated from msg_strb_i + // 3'b 000: funcpad_merged = {end_of_block, 63'(function_pad) }; + // 3'b 001: funcpad_merged = {end_of_block, 55'(function_pad), msg_data_i[ 7:0]}; + // 3'b 010: funcpad_merged = {end_of_block, 47'(function_pad), msg_data_i[15:0]}; + // 3'b 011: funcpad_merged = {end_of_block, 39'(function_pad), msg_data_i[23:0]}; + // 3'b 100: funcpad_merged = {end_of_block, 31'(function_pad), msg_data_i[31:0]}; + // 3'b 101: funcpad_merged = {end_of_block, 23'(function_pad), msg_data_i[39:0]}; + // 3'b 110: funcpad_merged = {end_of_block, 15'(function_pad), msg_data_i[47:0]}; + // 3'b 111: funcpad_merged = {end_of_block, 7'(function_pad), msg_data_i[55:0]}; + // default: funcpad_merged = '0; + // endcase + + // internal buffer to store partial write. It doesn't have to store last byte as it + // stores only when partial write. + logic [MsgWidth-8-1:0] msg_buf [Share]; + logic [MsgStrbW-1-1:0] msg_strb; + + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + msg_buf <= '{default:'0}; + msg_strb <= '0; + end else if (en_msgbuf) begin + for (int i = 0 ; i < Share ; i++) begin + msg_buf[i] <= msg_data_i[i][0+:(MsgWidth-8)]; + end + msg_strb <= msg_strb_i[0+:(MsgStrbW-1)]; + end else if (clr_msgbuf) begin + msg_buf <= '{default:'0}; + msg_strb <= '0; + end + end + + if (EnMasking) begin : gen_funcpad_data_masked + always_comb begin + unique case (msg_strb) + 7'b 000_0000: begin + funcpad_data[0] = '0; + funcpad_data[1] = {end_of_block, 63'(funcpad) }; + end + 7'b 000_0001: begin + funcpad_data[0] = {56'h0, msg_buf[0][ 7:0]}; + funcpad_data[1] = {end_of_block, 55'(funcpad), msg_buf[1][ 7:0]}; + end + 7'b 000_0011: begin + funcpad_data[0] = {48'h0, msg_buf[0][15:0]}; + funcpad_data[1] = {end_of_block, 47'(funcpad), msg_buf[1][15:0]}; + end + 7'b 000_0111: begin + funcpad_data[0] = {40'h0, msg_buf[0][23:0]}; + funcpad_data[1] = {end_of_block, 39'(funcpad), msg_buf[1][23:0]}; + end + 7'b 000_1111: begin + funcpad_data[0] = {32'h0, msg_buf[0][31:0]}; + funcpad_data[1] = {end_of_block, 31'(funcpad), msg_buf[1][31:0]}; + end + 7'b 001_1111: begin + funcpad_data[0] = {24'h0, msg_buf[0][39:0]}; + funcpad_data[1] = {end_of_block, 23'(funcpad), msg_buf[1][39:0]}; + end + 7'b 011_1111: begin + funcpad_data[0] = {16'h0, msg_buf[0][47:0]}; + funcpad_data[1] = {end_of_block, 15'(funcpad), msg_buf[1][47:0]}; + end + 7'b 111_1111: begin + funcpad_data[0] = { 8'h0, msg_buf[0][55:0]}; + funcpad_data[1] = {end_of_block, 7'(funcpad), msg_buf[1][55:0]}; + end + + default: funcpad_data = '{default:'0}; + endcase + end + end else begin : gen_funcpad_data_unmasked + always_comb begin + unique case (msg_strb) + 7'b 000_0000: funcpad_data[0] = {end_of_block, 63'(funcpad) }; + 7'b 000_0001: funcpad_data[0] = {end_of_block, 55'(funcpad), msg_buf[0][ 7:0]}; + 7'b 000_0011: funcpad_data[0] = {end_of_block, 47'(funcpad), msg_buf[0][15:0]}; + 7'b 000_0111: funcpad_data[0] = {end_of_block, 39'(funcpad), msg_buf[0][23:0]}; + 7'b 000_1111: funcpad_data[0] = {end_of_block, 31'(funcpad), msg_buf[0][31:0]}; + 7'b 001_1111: funcpad_data[0] = {end_of_block, 23'(funcpad), msg_buf[0][39:0]}; + 7'b 011_1111: funcpad_data[0] = {end_of_block, 15'(funcpad), msg_buf[0][47:0]}; + 7'b 111_1111: funcpad_data[0] = {end_of_block, 7'(funcpad), msg_buf[0][55:0]}; + + default: funcpad_data = '{default:'0}; + endcase + end + end + + //////////////// + // Assertions // + //////////////// + + // Prefix size is smaller than the smallest Keccak Block Size, which is 72 bytes. + `CALIPTRA_ASSERT_INIT(PrefixLessThanBlock_A, PrefixSize/8 < KeccakRate[4]) + + // Some part of datapath in sha3pad assumes Data width as 64bit. + // If data width need to be changed, funcpad_data part should be changed too. + // Also, The blocksize shall be divided by MsgWidth, which means, MsgWidth + // can be {16, 32, 64} even funcpad_data mux is fully flexible. + `CALIPTRA_ASSERT_INIT(MsgWidthidth_A, MsgWidth == 64) + + // Assume pulse signals: start, process, done + `CALIPTRA_ASSUME(StartPulse_A, start_i |=> !start_i) + `CALIPTRA_ASSUME(ProcessPulse_A, process_i |=> !process_i) + `CALIPTRA_ASSUME(DonePulse_A, + caliptra_prim_mubi_pkg::mubi4_test_true_strict(done_i) |=> + caliptra_prim_mubi_pkg::mubi4_test_false_strict(done_i)) + + // CALIPTRA_ASSERT output pulse signals: absorbed_o, keccak_run_o + `CALIPTRA_ASSERT(AbsorbedPulse_A, + caliptra_prim_mubi_pkg::mubi4_test_true_strict(absorbed_o) |=> + caliptra_prim_mubi_pkg::mubi4_test_false_strict(absorbed_o)) + `CALIPTRA_ASSERT(KeccakRunPulse_A, keccak_run_o |=> !keccak_run_o) + + // start_i, done_i, process_i cannot set high at the same time + `CALIPTRA_ASSUME(StartProcessDoneMutex_a, + $onehot0({ + start_i, + process_i, + caliptra_prim_mubi_pkg::mubi4_test_true_loose(done_i) + })) + + // Sequence, start_i --> process_i --> absorbed_o --> done_i + //`CALIPTRA_ASSUME(Sequence_a, start_i ##[1:$] process_i ##[1:$] ##[1:$] absorbed_o ##[1:$] done_i) + +`ifndef SYNTHESIS + // Process only asserts after start and all message are fed. + // These valid signals are qualifier of FPV to trigger the control signal + // It is a little bit hard to specify these criteria in SVA property so creating + // qualifiers in RTL form is easier. + logic start_valid, process_valid, absorb_valid, done_valid; + + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + start_valid <= 1'b 1; + end else if (start_i) begin + start_valid <= 1'b 0; + end else if (caliptra_prim_mubi_pkg::mubi4_test_true_strict(done_i)) begin + start_valid <= 1'b 1; + end + end + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + process_valid <= 1'b 0; + end else if (start_i) begin + process_valid <= 1'b 1; + end else if (process_i) begin + process_valid <= 1'b 0; + end + end + + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + done_valid <= 1'b 0; + end else if (caliptra_prim_mubi_pkg::mubi4_test_true_strict(absorbed_o)) begin + done_valid <= 1'b 1; + end else if (caliptra_prim_mubi_pkg::mubi4_test_true_strict(done_i)) begin + done_valid <= 1'b 0; + end + end + + // Message can be fed in between start_i and process_i. + `CALIPTRA_ASSUME(MessageCondition_M, msg_valid_i && msg_ready_o |-> process_valid && !process_i) + + // Message ready should be asserted only in between start_i and process_i + `CALIPTRA_ASSERT(MsgReadyCondition_A, msg_ready_o |-> process_valid && !process_i) + + `CALIPTRA_ASSUME(ProcessCondition_M, process_i |-> process_valid) + `CALIPTRA_ASSUME(StartCondition_M, start_i |-> start_valid) + `CALIPTRA_ASSUME(DoneCondition_M, + caliptra_prim_mubi_pkg::mubi4_test_true_strict(done_i) |-> done_valid) + + // Assume mode_i and strength_i are stable during the operation + // This will be guarded at the kmac top level + `CALIPTRA_ASSUME(ModeStableDuringOp_M, + $changed(mode_i) |-> start_valid) + `CALIPTRA_ASSUME(StrengthStableDuringOp_M, + $changed(strength_i) |-> start_valid) + +`endif // SYNTHESIS + + // If not full block is written, the pad shall send message to keccak_round + // If it is end of the message, the state moves to StPad and send the request + `CALIPTRA_ASSERT(CompleteBlockWhenProcess_A, + $rose(process_latched) && (!end_of_block && !sent_blocksize ) + && !(st inside {StPrefixWait, StMessageWait}) |-> ##[1:5] keccak_valid_o, + clk_i, !rst_ni || lc_ctrl_pkg::lc_tx_test_true_loose(lc_escalate_en_i)) + + // If process_i asserted, completion shall be asserted shall be asserted + //`CALIPTRA_ASSERT(ProcessToAbsorbed_A, process_i |=> strong(##[24*Share:$] absorbed_o)) + + + // Assumption of input mode_i and strength_i + // SHA3 variants: SHA3-224, SHA3-256, SHA3-384, SHA3-512 + // SHAKE, cSHAKE variants: SHAKE128, SHAKE256, cSHAKE128, cSHAKE256 + `CALIPTRA_ASSUME_FPV(ModeStrengthCombinations_M, + start_i |-> + (mode_i == Sha3 && (strength_i inside {L224, L256, L384, L512})) || + ((mode_i == Shake || mode_i == CShake) && (strength_i inside {L128, L256})), + clk_i, !rst_ni) + + // No partial write is allowed for Message FIFO interface + `CALIPTRA_ASSUME(NoPartialMsgFifo_M, + keccak_valid_o && (sel_mux == MuxFifo) |-> (&msg_strb_i) == 1'b1, + clk_i, !rst_ni) + + // When transaction is stored into msg_buf, it shall be partial write. + `CALIPTRA_ASSUME(AlwaysPartialMsgBuf_M, + en_msgbuf |-> msg_valid_i && (msg_strb_i[MsgStrbW-1] == 1'b0), + clk_i, !rst_ni) + + // if partial write comes and is acked, then no more msg_valid_i until + // next message + `CALIPTRA_ASSUME(PartialEndOfMsg_M, + msg_valid_i && msg_ready_o && msg_partial |=> + !msg_valid_i ##[1:$] $stable(msg_valid_i) ##1 process_latched, + clk_i, !rst_ni) + + // At the first clock in StPad01 state, sent_blocksize shall not be set + `CALIPTRA_ASSERT(Pad01NotAttheEndOfBlock_A, + (st == StPad && st_d == StPad01) |-> !end_of_block, + clk_i, !rst_ni) + + // When data sent to the keccak_round, the address should be in the range + `CALIPTRA_ASSERT(KeccakAddrInRange_A, + keccak_valid_o |-> keccak_addr_o < KeccakRate[strength_i], + clk_i, !rst_ni) + + // NS data shall be stable during the operation. + //`CALIPTRA_ASSUME(NsStableInProcess_A, + // $stable(ns_data_i) throughout(start_i ##[1:$] process_i ##[1:$] absorbed_o), + // clk_i, !rst_ni) + + // Functional Coverage + `CALIPTRA_COVER(StMessageFeed_C, st == StMessage) + `CALIPTRA_COVER(StPad_C, st == StPad01 && sent_blocksize) + `CALIPTRA_COVER(StPadSendMsg_C, st == StPad01 && keccak_ack) + `CALIPTRA_COVER(StComplete_C, st == StPadFlush) +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/sha512.sv b/designs/Caliptra/src/caliptra-rtl/sha512.sv new file mode 100644 index 0000000..df7ba44 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/sha512.sv @@ -0,0 +1,544 @@ +//====================================================================== +// Updated by Caliptra team to modify data access width +// and removing the work factor +// +// sha512.sv +// -------- +// Top level wrapper for the SHA-512 hash function providing +// a simple memory like interface with 32 bit data access. +// +// +// Author: Joachim Strombergson +// Copyright (c) 2014, Secworks Sweden AB +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or +// without modification, are permitted provided that the following +// conditions are met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in +// the documentation and/or other materials provided with the +// distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +//====================================================================== + +module sha512 + import sha512_reg_pkg::*; + import sha512_params_pkg::*; + import kv_defines_pkg::*; + import pv_defines_pkg::*; + #( + parameter ADDR_WIDTH = 32, + parameter DATA_WIDTH = 64 + )( + // Clock and reset. + input wire clk, + input wire reset_n, + input wire cptra_pwrgood, + + // Control. + input wire cs, + input wire we, + + // Data ports. + input wire [ADDR_WIDTH-1 : 0] address, + input wire [DATA_WIDTH-1 : 0] write_data, + output wire [DATA_WIDTH-1 : 0] read_data, + output wire err, + + // PV interface + output pv_read_t pv_read, + output pv_write_t pv_write, + input pv_rd_resp_t pv_rd_resp, + input pv_wr_resp_t pv_wr_resp, + output logic [PCR_HASH_NUM_DWORDS-1:0][DATA_WIDTH-1:0] pcr_signing_hash, + + // Interrupts + output wire error_intr, + output wire notif_intr, + input logic debugUnlock_or_scan_mode_switch + ); + + //---------------------------------------------------------------- + // Registers including update variables and write enable. + //---------------------------------------------------------------- + reg init_reg; + reg next_reg; + reg restore_reg; + reg ready_reg; + reg [1 : 0] mode_reg; + logic zeroize_reg; + logic last_reg; + + localparam BLOCK_SIZE = 1024; + localparam DIG_SIZE = 512; + + localparam BLOCK_NUM_DWORDS = BLOCK_SIZE / DATA_WIDTH; + localparam DIG_NUM_DWORDS = DIG_SIZE / DATA_WIDTH; + localparam NONCE_NUM_DWORDS = PV_SIZE_OF_NONCE / DATA_WIDTH; + + reg [DATA_WIDTH-1 : 0][BLOCK_NUM_DWORDS-1 : 0] block_reg ; + reg [DIG_NUM_DWORDS-1 : 0][DATA_WIDTH-1 : 0] digest_reg; + reg [PV_NUM_DWORDS -1 : 0][DATA_WIDTH-1 : 0] kv_reg; + + + reg [PCR_HASH_NUM_DWORDS -1 : 0][DATA_WIDTH-1 : 0] pcr_sign_reg; + logic [PCR_HASH_NUM_DWORDS-1 : 0][DATA_WIDTH-1 : 0] pcr_sign; + logic pcr_sign_we; + reg digest_valid_reg; + logic digest_we; + + sha512_reg__in_t hwif_in; + sha512_reg__out_t hwif_out; + logic read_error, write_error; + + //KV/PV Gasket + kv_read_t vault_read; + kv_write_t vault_write; + kv_rd_resp_t vault_rd_resp; + kv_wr_resp_t vault_wr_resp; + + pv_read_t gen_hash_pv_read; + + //interface with client + logic kv_src_write_en; + logic [4:0] kv_src_write_offset; + logic [31:0] kv_src_write_data; + + kv_error_code_e kv_src_error, kv_dest_error; + logic kv_src_ready, kv_src_done; + logic kv_dest_ready, kv_dest_done; + + logic dest_keyvault; + kv_write_ctrl_reg_t kv_write_ctrl_reg; + kv_write_ctrl_reg_t kv_write_ctrl_reg_q; + kv_read_ctrl_reg_t kv_read_ctrl_reg; + kv_read_filter_metrics_t kv_read_metrics; + kv_write_filter_metrics_t kv_write_metrics; + + //KV Read Data Present + logic kv_read_data_present; + logic kv_read_data_present_set, kv_read_data_present_reset; + //PCR Hash Extend Function + logic pcr_hash_extend_ip; + logic pcr_hash_extend_set, pcr_hash_extend_reset; + logic [KV_ENTRY_ADDR_W-1:0] hash_extend_entry; + logic dest_data_avail; + logic [31:0] block_reg_lock,block_reg_lock_nxt; + //PCR Gen Hash Function + logic gen_hash_start; + logic gen_hash_ip; + logic gen_hash_init_reg; + logic gen_hash_next_reg; + logic gen_hash_last_reg; + logic gen_hash_block_write_en; + logic [4:0] gen_hash_block_write_offset; + logic [31:0] gen_hash_block_write_data; + + logic [NONCE_NUM_DWORDS-1 : 0][DATA_WIDTH-1 : 0] pv_nonce; + //---------------------------------------------------------------- + // Wires. + //---------------------------------------------------------------- + wire core_ready; + wire [BLOCK_SIZE-1 : 0] core_block; + wire [DIG_NUM_DWORDS-1 : 0][DATA_WIDTH-1 : 0] core_digest; + wire core_digest_valid; + logic [DIG_NUM_DWORDS-1 : 0][DATA_WIDTH-1 : 0] restore_digest; + + //---------------------------------------------------------------- + // Concurrent connectivity for ports etc. + //---------------------------------------------------------------- + assign core_block = { block_reg[00], block_reg[01], block_reg[02], block_reg[03], + block_reg[04], block_reg[05], block_reg[06], block_reg[07], + block_reg[08], block_reg[09], block_reg[10], block_reg[11], + block_reg[12], block_reg[13], block_reg[14], block_reg[15], + block_reg[16], block_reg[17], block_reg[18], block_reg[19], + block_reg[20], block_reg[21], block_reg[22], block_reg[23], + block_reg[24], block_reg[25], block_reg[26], block_reg[27], + block_reg[28], block_reg[29], block_reg[30], block_reg[31]}; + + assign err = read_error | write_error; + + always_comb begin // ecc_reg_writing + for (int dword=0; dword < PCR_HASH_NUM_DWORDS; dword++)begin + pcr_signing_hash[dword] = pcr_sign_reg[(PCR_HASH_NUM_DWORDS-1)-dword]; + end + end + + //---------------------------------------------------------------- + // core instantiation. + //---------------------------------------------------------------- + sha512_core core( + .clk(clk), + .reset_n(reset_n), + .zeroize(zeroize_reg), + + .init_cmd(init_reg), + .next_cmd(next_reg), + .restore_cmd(restore_reg), + .mode(mode_reg), + + .block_msg(core_block), + .restore_digest(restore_digest), + + .ready(core_ready), + + .digest(core_digest), + .digest_valid(core_digest_valid) + ); + + + //---------------------------------------------------------------- + // reg_update + // + // Update functionality for all registers in the core. + // All registers are positive edge triggered with asynchronous + // active low reset. All registers have write enable. + //---------------------------------------------------------------- + always @ (posedge clk or negedge reset_n) begin : reg_update + if (!reset_n) begin + ready_reg <= '0; + digest_reg <= '0; + digest_valid_reg <= '0; + kv_reg <= '0; + pcr_sign_reg <= '0; + block_reg_lock <= '0; + pcr_hash_extend_ip <= '0; + hash_extend_entry <= '0; + kv_read_data_present <= '0; + digest_we <= '0; + end + else if (zeroize_reg) begin + ready_reg <= '0; + digest_reg <= '0; + digest_valid_reg <= '0; + kv_reg <= '0; + pcr_sign_reg <= '0; + kv_read_data_present <= '0; + digest_we <= '0; + block_reg_lock <= '0; + end + else begin + ready_reg <= core_ready; + digest_valid_reg <= core_digest_valid; + + if (core_digest_valid & ~digest_valid_reg & ~(dest_keyvault | kv_read_data_present)) begin + digest_reg <= core_digest; + digest_we <= 1'b1; + end + else + digest_we <= '0; + if (core_digest_valid & ~digest_valid_reg & (dest_keyvault | kv_read_data_present)) + kv_reg <= core_digest[DIG_NUM_DWORDS-1:DIG_NUM_DWORDS-PV_NUM_DWORDS]; + if (pcr_sign_we) + pcr_sign_reg <= pcr_sign; + + block_reg_lock <= block_reg_lock_nxt; + pcr_hash_extend_ip <= pcr_hash_extend_set ? '1 : + pcr_hash_extend_reset ? '0 : pcr_hash_extend_ip; + hash_extend_entry <= pcr_hash_extend_set ? kv_read_ctrl_reg.read_entry : hash_extend_entry; + kv_read_data_present <= kv_read_data_present_set ? '1 : + kv_read_data_present_reset ? '0 : kv_read_data_present; + end + end // reg_update + + always_comb begin + pcr_sign_we = (dest_data_avail & gen_hash_ip); + pcr_sign = core_digest[DIG_NUM_DWORDS-1:DIG_NUM_DWORDS-PCR_HASH_NUM_DWORDS]; + end + + //register hw interface + always_comb begin + + hwif_in.SHA512_NAME[0].NAME.next = SHA512_CORE_NAME0; + hwif_in.SHA512_NAME[1].NAME.next = SHA512_CORE_NAME1; + + hwif_in.SHA512_VERSION[0].VERSION.next = SHA512_CORE_VERSION0; + hwif_in.SHA512_VERSION[1].VERSION.next = SHA512_CORE_VERSION1; + + //Mask commands when keyvault is busy to prevent runs with partial keys. + init_reg = gen_hash_ip ? gen_hash_init_reg : (hwif_out.SHA512_CTRL.INIT.value & kv_src_ready); + next_reg = gen_hash_ip ? gen_hash_next_reg : (hwif_out.SHA512_CTRL.NEXT.value & kv_src_ready); + restore_reg = gen_hash_ip ? '0 : (hwif_out.SHA512_CTRL.RESTORE.value & kv_src_ready); + mode_reg = gen_hash_ip ? MODE_SHA_512 : hwif_out.SHA512_CTRL.MODE.value; + zeroize_reg = hwif_out.SHA512_CTRL.ZEROIZE.value || debugUnlock_or_scan_mode_switch; + last_reg = gen_hash_ip ? gen_hash_last_reg : hwif_out.SHA512_CTRL.LAST.value; + hwif_in.SHA512_CTRL.LAST.hwclr = core_digest_valid & ~digest_valid_reg; + + hwif_in.SHA512_STATUS.READY.next = ready_reg; + hwif_in.SHA512_STATUS.VALID.next = digest_valid_reg; + + //output comes in big endian + for (int dword =0; dword < DIG_NUM_DWORDS; dword++) begin + restore_digest[dword] = hwif_out.SHA512_DIGEST[(DIG_NUM_DWORDS-1)-dword].DIGEST.value; + hwif_in.SHA512_DIGEST[dword].DIGEST.we = zeroize_reg? 0 : digest_we; + hwif_in.SHA512_DIGEST[dword].DIGEST.next = digest_reg[(DIG_NUM_DWORDS-1)-dword]; + hwif_in.SHA512_DIGEST[dword].DIGEST.hwclr = zeroize_reg; + end + //output comes in big endian + for (int dword =0; dword < PCR_HASH_NUM_DWORDS; dword++) begin + hwif_in.SHA512_GEN_PCR_HASH_DIGEST[dword].DIGEST.next = pcr_sign_reg[(PCR_HASH_NUM_DWORDS-1)-dword]; + hwif_in.SHA512_GEN_PCR_HASH_DIGEST[dword].DIGEST.hwclr = zeroize_reg; + end + + for (int dword=0; dword< BLOCK_NUM_DWORDS; dword++) begin + block_reg[dword] = hwif_out.SHA512_BLOCK[dword].BLOCK.value; + hwif_in.SHA512_BLOCK[dword].BLOCK.we = zeroize_reg ? 0 : + gen_hash_ip ? gen_hash_block_write_en & (gen_hash_block_write_offset == dword) : + (kv_src_write_en & (kv_src_write_offset == dword)); + hwif_in.SHA512_BLOCK[dword].BLOCK.next = gen_hash_ip ? gen_hash_block_write_data : kv_src_write_data; + hwif_in.SHA512_BLOCK[dword].BLOCK.hwclr = zeroize_reg | kv_read_data_present_reset; + //lock the block during gen hash operation + hwif_in.SHA512_BLOCK[dword].BLOCK.swwel = gen_hash_ip ? '1 : block_reg_lock[dword]; + end + //Set valid when fsm is done + hwif_in.SHA512_VAULT_RD_STATUS.ERROR.next = kv_src_error; + hwif_in.SHA512_KV_WR_STATUS.ERROR.next = kv_dest_error; + //Set valid when fsm is done + hwif_in.SHA512_VAULT_RD_STATUS.READY.next = kv_src_ready; + hwif_in.SHA512_KV_WR_STATUS.READY.next = kv_dest_ready; + //Set valid when fsm is done + hwif_in.SHA512_VAULT_RD_STATUS.VALID.hwset = kv_src_done; + hwif_in.SHA512_KV_WR_STATUS.VALID.hwset = kv_dest_done; + //reset valid when fsm is started + hwif_in.SHA512_VAULT_RD_STATUS.VALID.hwclr = kv_read_ctrl_reg.read_en; + hwif_in.SHA512_KV_WR_STATUS.VALID.hwclr = kv_write_ctrl_reg.write_en; + //clear en when busy + hwif_in.SHA512_VAULT_RD_CTRL.read_en.hwclr = ~kv_src_ready; + hwif_in.SHA512_KV_WR_CTRL.write_en.hwclr = ~kv_dest_ready; + + gen_hash_start = hwif_out.SHA512_GEN_PCR_HASH_CTRL.START.value; + hwif_in.SHA512_GEN_PCR_HASH_STATUS.READY.next = ~gen_hash_ip & ~pcr_hash_extend_ip & ready_reg; + hwif_in.SHA512_GEN_PCR_HASH_STATUS.VALID.hwset = gen_hash_ip & dest_data_avail; + hwif_in.SHA512_GEN_PCR_HASH_STATUS.VALID.hwclr = gen_hash_start; + + end + + // Software write-enables to prevent KV reg manipulation mid-operation + always_comb hwif_in.SHA512_VAULT_RD_CTRL.read_en.swwe = !kv_read_data_present && ready_reg && !gen_hash_ip; + always_comb hwif_in.SHA512_VAULT_RD_CTRL.read_entry.swwe = !kv_read_data_present && ready_reg && !gen_hash_ip; + always_comb hwif_in.SHA512_VAULT_RD_CTRL.pcr_hash_extend.swwe = !kv_read_data_present && ready_reg && !gen_hash_ip; + always_comb hwif_in.SHA512_VAULT_RD_CTRL.rsvd.swwe = !kv_read_data_present && ready_reg && !gen_hash_ip; + + // KV write control must be written before SHA core operation begins, even though + // output isn't written to KV until the end of the operation. + // Prevent partial-key attacks by blocking register modifications during core execution. + always_comb hwif_in.SHA512_KV_WR_CTRL.write_en.swwe = ready_reg && !gen_hash_ip; + always_comb hwif_in.SHA512_KV_WR_CTRL.write_entry.swwe = ready_reg && !gen_hash_ip; + always_comb hwif_in.SHA512_KV_WR_CTRL.hmac_key_dest_valid.swwe = ready_reg && !gen_hash_ip; + always_comb hwif_in.SHA512_KV_WR_CTRL.hmac_block_dest_valid.swwe = ready_reg && !gen_hash_ip; + always_comb hwif_in.SHA512_KV_WR_CTRL.mldsa_seed_dest_valid.swwe = ready_reg && !gen_hash_ip; + always_comb hwif_in.SHA512_KV_WR_CTRL.ecc_pkey_dest_valid.swwe = ready_reg && !gen_hash_ip; + always_comb hwif_in.SHA512_KV_WR_CTRL.ecc_seed_dest_valid.swwe = ready_reg && !gen_hash_ip; + always_comb hwif_in.SHA512_KV_WR_CTRL.aes_key_dest_valid.swwe = ready_reg && !gen_hash_ip; + always_comb hwif_in.SHA512_KV_WR_CTRL.mlkem_seed_dest_valid.swwe = ready_reg && !gen_hash_ip; + always_comb hwif_in.SHA512_KV_WR_CTRL.mlkem_msg_dest_valid.swwe = ready_reg && !gen_hash_ip; + always_comb hwif_in.SHA512_KV_WR_CTRL.dma_data_dest_valid.swwe = ready_reg && !gen_hash_ip; + always_comb hwif_in.SHA512_KV_WR_CTRL.rsvd.swwe = ready_reg && !gen_hash_ip; + + `CALIPTRA_KV_WRITE_CTRL_REG2STRUCT(kv_write_ctrl_reg, SHA512_KV_WR_CTRL) + `CALIPTRA_KV_READ_CTRL_REG2STRUCT(kv_read_ctrl_reg, SHA512_VAULT_RD_CTRL) + +//Force result into KV reg whenever source came from KV + always_comb kv_read_data_present_set = kv_read_ctrl_reg.read_en & ~kv_read_ctrl_reg.pcr_hash_extend; + always_comb kv_read_data_present_reset = kv_read_data_present & dest_data_avail; + +//Hash extend logic + always_comb pcr_hash_extend_set = kv_read_ctrl_reg.read_en & kv_read_ctrl_reg.pcr_hash_extend; + always_comb pcr_hash_extend_reset = pcr_hash_extend_ip & kv_dest_done; + +//set the lock for the part of the block being written by KV logic during PCR hash extend +//release the lock once init has been seen +always_comb begin + for (int dword=0; dword< BLOCK_NUM_DWORDS; dword++) begin + if (init_reg | next_reg) begin + block_reg_lock_nxt[dword] = '0; + end + else begin + //Lock the block for any keyvault data + block_reg_lock_nxt[dword] = (kv_src_write_en & (kv_src_write_offset == dword)) ? '1 : block_reg_lock[dword]; + end + end +end + +// Register Block +sha512_reg i_sha512_reg ( + .clk(clk), + .rst(1'b0), + + .s_cpuif_req (cs), + .s_cpuif_req_is_wr (we), + .s_cpuif_addr (address[SHA512_REG_ADDR_WIDTH-1:0]), + .s_cpuif_wr_data (write_data), + .s_cpuif_wr_biten ('1), + .s_cpuif_req_stall_wr( ), + .s_cpuif_req_stall_rd( ), + .s_cpuif_rd_ack ( ), + .s_cpuif_rd_err (read_error), + .s_cpuif_rd_data (read_data), + .s_cpuif_wr_ack ( ), + .s_cpuif_wr_err (write_error), + + .hwif_in (hwif_in ), + .hwif_out(hwif_out) +); + +//interrupt register hw interface +assign hwif_in.reset_b = reset_n; +assign hwif_in.error_reset_b = cptra_pwrgood; +assign hwif_in.sha512_ready = ready_reg; +assign hwif_in.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.hwset = core_digest_valid & ~digest_valid_reg; +assign hwif_in.intr_block_rf.error_internal_intr_r.error0_sts.hwset = 1'b0; // TODO +assign hwif_in.intr_block_rf.error_internal_intr_r.error1_sts.hwset = 1'b0; // TODO +assign hwif_in.intr_block_rf.error_internal_intr_r.error2_sts.hwset = 1'b0; // TODO +assign hwif_in.intr_block_rf.error_internal_intr_r.error3_sts.hwset = 1'b0; // TODO + +assign error_intr = hwif_out.intr_block_rf.error_global_intr_r.intr; +assign notif_intr = hwif_out.intr_block_rf.notif_global_intr_r.intr; + +//Read Block +always_comb pv_read = gen_hash_ip ? gen_hash_pv_read : + pcr_hash_extend_ip ? vault_read : '0; +always_comb vault_rd_resp = pv_rd_resp; + + + +kv_read_client #( + .DATA_WIDTH(BLOCK_SIZE), + .PAD(1) +) +sha512_block_kv_read +( + .clk(clk), + .rst_b(reset_n), + .zeroize(zeroize_reg), + + //client control register + .read_ctrl_reg(kv_read_ctrl_reg), + .read_metrics(kv_read_metrics), + + //interface with kv + .kv_read(vault_read), + .kv_resp(vault_rd_resp), + + //interface with client + .write_en(kv_src_write_en), + .write_offset(kv_src_write_offset), + .write_data(kv_src_write_data), + + .error_code(kv_src_error), + .kv_ready(kv_src_ready), + .read_done(kv_src_done) +); + +always_comb begin + pv_write.write_data = pcr_hash_extend_ip ? vault_write.write_data : '0; + pv_write.write_en = pcr_hash_extend_ip ? vault_write.write_en : '0; + pv_write.write_entry = pcr_hash_extend_ip ? vault_write.write_entry : '0; + pv_write.write_offset = pcr_hash_extend_ip ? vault_write.write_offset : '0; +end +always_comb vault_wr_resp = pv_wr_resp; + +//during PCR hash extend overload write control +//force write enable and always write to the source address that we read from +always_comb begin + kv_write_ctrl_reg_q = kv_write_ctrl_reg; + kv_write_ctrl_reg_q.write_en = ~pcr_hash_extend_ip ? kv_write_ctrl_reg.write_en : '1; + kv_write_ctrl_reg_q.write_entry = ~pcr_hash_extend_ip ? kv_write_ctrl_reg.write_entry : hash_extend_entry; +end + +//write out the dest data to KV or PCR on last iteration of SHA +always_comb dest_data_avail = core_digest_valid & ~digest_valid_reg & last_reg; + +always_comb begin + for (int dword=0; dword< NONCE_NUM_DWORDS; dword++) begin + pv_nonce[dword] = hwif_out.SHA512_GEN_PCR_HASH_NONCE[dword].NONCE.value; + end +end + +//No filtering rules for SHA512, goes to PCR vault +always_comb begin + kv_read_metrics = '{default: '0}; + kv_write_metrics = '{default: '0}; +end + +kv_write_client #( + .DATA_WIDTH(PV_NUM_DWORDS*PV_DATA_W) +) +sha512_result_kv_write +( + .clk(clk), + .rst_b(reset_n), + .zeroize(zeroize_reg), + + //client control register + .write_ctrl_reg(kv_write_ctrl_reg_q), + .num_dwords(PV_NUM_DWORDS[4:0]), + .write_metrics(kv_write_metrics), + + //interface with kv + .kv_write(vault_write), + .kv_resp(vault_wr_resp), + + //interface with client + .dest_keyvault(dest_keyvault), + .dest_data_avail(dest_data_avail), + .dest_data(kv_reg), + + .error_code(kv_dest_error), + .kv_ready(kv_dest_ready), + .dest_done(kv_dest_done) +); + +pv_gen_hash +pv_gen_hash1 +( + .clk(clk), + .rst_b(reset_n), + .zeroize(zeroize_reg), + + .core_ready(ready_reg), + .core_digest_valid(gen_hash_ip & dest_data_avail), + + .start(gen_hash_start), + .nonce(pv_nonce), + + .gen_hash_ip(gen_hash_ip), + .gen_hash_init_reg(gen_hash_init_reg), + .gen_hash_next_reg(gen_hash_next_reg), + .gen_hash_last_reg(gen_hash_last_reg), + + .block_we(gen_hash_block_write_en), + .block_offset(gen_hash_block_write_offset), + .block_wr_data(gen_hash_block_write_data), + + .pv_read(gen_hash_pv_read), + .pv_rd_resp(pv_rd_resp) +); + +`CALIPTRA_ASSERT_STABLE(ERR_SHA_KEY_RD_CTRL_NOT_STABLE, kv_read_ctrl_reg, clk, (!reset_n || ready_reg) ) +`CALIPTRA_ASSERT_STABLE(ERR_SHA_WR_CTRL_NOT_STABLE, kv_write_ctrl_reg, clk, (!reset_n || ready_reg) ) +`CALIPTRA_ASSERT_STABLE(ERR_SHA_BLOCK_NOT_STABLE, block_reg, clk, (!reset_n || ready_reg) ) + +endmodule // sha512 + +//====================================================================== +// EOF sha512.sv +//====================================================================== diff --git a/designs/Caliptra/src/caliptra-rtl/sha512_acc_csr.sv b/designs/Caliptra/src/caliptra-rtl/sha512_acc_csr.sv new file mode 100644 index 0000000..ba52bf8 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/sha512_acc_csr.sv @@ -0,0 +1,1710 @@ +// Generated by PeakRDL-regblock - A free and open-source SystemVerilog generator +// https://github.com/SystemRDL/PeakRDL-regblock + +module sha512_acc_csr ( + input wire clk, + input wire rst, + + input wire s_cpuif_req, + input wire s_cpuif_req_is_wr, + input wire [11:0] s_cpuif_addr, + input wire [31:0] s_cpuif_wr_data, + input wire [31:0] s_cpuif_wr_biten, + output wire s_cpuif_req_stall_wr, + output wire s_cpuif_req_stall_rd, + output wire s_cpuif_rd_ack, + output wire s_cpuif_rd_err, + output wire [31:0] s_cpuif_rd_data, + output wire s_cpuif_wr_ack, + output wire s_cpuif_wr_err, + + input sha512_acc_csr_pkg::sha512_acc_csr__in_t hwif_in, + output sha512_acc_csr_pkg::sha512_acc_csr__out_t hwif_out + ); + + //-------------------------------------------------------------------------- + // CPU Bus interface logic + //-------------------------------------------------------------------------- + logic cpuif_req; + logic cpuif_req_is_wr; + logic [11:0] cpuif_addr; + logic [31:0] cpuif_wr_data; + logic [31:0] cpuif_wr_biten; + logic cpuif_req_stall_wr; + logic cpuif_req_stall_rd; + + logic cpuif_rd_ack; + logic cpuif_rd_err; + logic [31:0] cpuif_rd_data; + + logic cpuif_wr_ack; + logic cpuif_wr_err; + + assign cpuif_req = s_cpuif_req; + assign cpuif_req_is_wr = s_cpuif_req_is_wr; + assign cpuif_addr = s_cpuif_addr; + assign cpuif_wr_data = s_cpuif_wr_data; + assign cpuif_wr_biten = s_cpuif_wr_biten; + assign s_cpuif_req_stall_wr = cpuif_req_stall_wr; + assign s_cpuif_req_stall_rd = cpuif_req_stall_rd; + assign s_cpuif_rd_ack = cpuif_rd_ack; + assign s_cpuif_rd_err = cpuif_rd_err; + assign s_cpuif_rd_data = cpuif_rd_data; + assign s_cpuif_wr_ack = cpuif_wr_ack; + assign s_cpuif_wr_err = cpuif_wr_err; + + logic cpuif_req_masked; + + // Read & write latencies are balanced. Stalls not required + assign cpuif_req_stall_rd = '0; + assign cpuif_req_stall_wr = '0; + assign cpuif_req_masked = cpuif_req + & !(!cpuif_req_is_wr & cpuif_req_stall_rd) + & !(cpuif_req_is_wr & cpuif_req_stall_wr); + + //-------------------------------------------------------------------------- + // Address Decode + //-------------------------------------------------------------------------- + typedef struct packed{ + logic LOCK; + logic USER; + logic MODE; + logic START_ADDRESS; + logic DLEN; + logic DATAIN; + logic EXECUTE; + logic STATUS; + logic [16-1:0]DIGEST; + logic CONTROL; + struct packed{ + logic global_intr_en_r; + logic error_intr_en_r; + logic notif_intr_en_r; + logic error_global_intr_r; + logic notif_global_intr_r; + logic error_internal_intr_r; + logic notif_internal_intr_r; + logic error_intr_trig_r; + logic notif_intr_trig_r; + logic error0_intr_count_r; + logic error1_intr_count_r; + logic error2_intr_count_r; + logic error3_intr_count_r; + logic notif_cmd_done_intr_count_r; + logic error0_intr_count_incr_r; + logic error1_intr_count_incr_r; + logic error2_intr_count_incr_r; + logic error3_intr_count_incr_r; + logic notif_cmd_done_intr_count_incr_r; + } intr_block_rf; + } decoded_reg_strb_t; + decoded_reg_strb_t decoded_reg_strb; + logic decoded_req; + logic decoded_req_is_wr; + logic [31:0] decoded_wr_data; + logic [31:0] decoded_wr_biten; + + always_comb begin + decoded_reg_strb.LOCK = cpuif_req_masked & (cpuif_addr == 12'h0); + decoded_reg_strb.USER = cpuif_req_masked & (cpuif_addr == 12'h4); + decoded_reg_strb.MODE = cpuif_req_masked & (cpuif_addr == 12'h8); + decoded_reg_strb.START_ADDRESS = cpuif_req_masked & (cpuif_addr == 12'hc); + decoded_reg_strb.DLEN = cpuif_req_masked & (cpuif_addr == 12'h10); + decoded_reg_strb.DATAIN = cpuif_req_masked & (cpuif_addr == 12'h14); + decoded_reg_strb.EXECUTE = cpuif_req_masked & (cpuif_addr == 12'h18); + decoded_reg_strb.STATUS = cpuif_req_masked & (cpuif_addr == 12'h1c); + for(int i0=0; i0<16; i0++) begin + decoded_reg_strb.DIGEST[i0] = cpuif_req_masked & (cpuif_addr == 12'h20 + i0*12'h4); + end + decoded_reg_strb.CONTROL = cpuif_req_masked & (cpuif_addr == 12'h60); + decoded_reg_strb.intr_block_rf.global_intr_en_r = cpuif_req_masked & (cpuif_addr == 12'h800); + decoded_reg_strb.intr_block_rf.error_intr_en_r = cpuif_req_masked & (cpuif_addr == 12'h804); + decoded_reg_strb.intr_block_rf.notif_intr_en_r = cpuif_req_masked & (cpuif_addr == 12'h808); + decoded_reg_strb.intr_block_rf.error_global_intr_r = cpuif_req_masked & (cpuif_addr == 12'h80c); + decoded_reg_strb.intr_block_rf.notif_global_intr_r = cpuif_req_masked & (cpuif_addr == 12'h810); + decoded_reg_strb.intr_block_rf.error_internal_intr_r = cpuif_req_masked & (cpuif_addr == 12'h814); + decoded_reg_strb.intr_block_rf.notif_internal_intr_r = cpuif_req_masked & (cpuif_addr == 12'h818); + decoded_reg_strb.intr_block_rf.error_intr_trig_r = cpuif_req_masked & (cpuif_addr == 12'h81c); + decoded_reg_strb.intr_block_rf.notif_intr_trig_r = cpuif_req_masked & (cpuif_addr == 12'h820); + decoded_reg_strb.intr_block_rf.error0_intr_count_r = cpuif_req_masked & (cpuif_addr == 12'h900); + decoded_reg_strb.intr_block_rf.error1_intr_count_r = cpuif_req_masked & (cpuif_addr == 12'h904); + decoded_reg_strb.intr_block_rf.error2_intr_count_r = cpuif_req_masked & (cpuif_addr == 12'h908); + decoded_reg_strb.intr_block_rf.error3_intr_count_r = cpuif_req_masked & (cpuif_addr == 12'h90c); + decoded_reg_strb.intr_block_rf.notif_cmd_done_intr_count_r = cpuif_req_masked & (cpuif_addr == 12'h980); + decoded_reg_strb.intr_block_rf.error0_intr_count_incr_r = cpuif_req_masked & (cpuif_addr == 12'ha00); + decoded_reg_strb.intr_block_rf.error1_intr_count_incr_r = cpuif_req_masked & (cpuif_addr == 12'ha04); + decoded_reg_strb.intr_block_rf.error2_intr_count_incr_r = cpuif_req_masked & (cpuif_addr == 12'ha08); + decoded_reg_strb.intr_block_rf.error3_intr_count_incr_r = cpuif_req_masked & (cpuif_addr == 12'ha0c); + decoded_reg_strb.intr_block_rf.notif_cmd_done_intr_count_incr_r = cpuif_req_masked & (cpuif_addr == 12'ha10); + end + + // Pass down signals to next stage + assign decoded_req = cpuif_req_masked; + assign decoded_req_is_wr = cpuif_req_is_wr; + assign decoded_wr_data = cpuif_wr_data; + assign decoded_wr_biten = cpuif_wr_biten; + + //-------------------------------------------------------------------------- + // Field logic + //-------------------------------------------------------------------------- + typedef struct packed{ + struct packed{ + struct packed{ + logic next; + logic load_next; + } LOCK; + } LOCK; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } USER; + } USER; + struct packed{ + struct packed{ + logic [1:0] next; + logic load_next; + } MODE; + struct packed{ + logic next; + logic load_next; + } ENDIAN_TOGGLE; + } MODE; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } ADDR; + } START_ADDRESS; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } LENGTH; + } DLEN; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } DATAIN; + } DATAIN; + struct packed{ + struct packed{ + logic next; + logic load_next; + } EXECUTE; + } EXECUTE; + struct packed{ + struct packed{ + logic next; + logic load_next; + } VALID; + struct packed{ + logic next; + logic load_next; + } SOC_HAS_LOCK; + } STATUS; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } DIGEST; + } [16-1:0]DIGEST; + struct packed{ + struct packed{ + logic next; + logic load_next; + } ZEROIZE; + } CONTROL; + struct packed{ + struct packed{ + struct packed{ + logic next; + logic load_next; + } error_en; + struct packed{ + logic next; + logic load_next; + } notif_en; + } global_intr_en_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + } error0_en; + struct packed{ + logic next; + logic load_next; + } error1_en; + struct packed{ + logic next; + logic load_next; + } error2_en; + struct packed{ + logic next; + logic load_next; + } error3_en; + } error_intr_en_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + } notif_cmd_done_en; + } notif_intr_en_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + } agg_sts; + } error_global_intr_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + } agg_sts; + } notif_global_intr_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + } error0_sts; + struct packed{ + logic next; + logic load_next; + } error1_sts; + struct packed{ + logic next; + logic load_next; + } error2_sts; + struct packed{ + logic next; + logic load_next; + } error3_sts; + } error_internal_intr_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + } notif_cmd_done_sts; + } notif_internal_intr_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + } error0_trig; + struct packed{ + logic next; + logic load_next; + } error1_trig; + struct packed{ + logic next; + logic load_next; + } error2_trig; + struct packed{ + logic next; + logic load_next; + } error3_trig; + } error_intr_trig_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + } notif_cmd_done_trig; + } notif_intr_trig_r; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + logic incrthreshold; + logic incrsaturate; + } cnt; + } error0_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + logic incrthreshold; + logic incrsaturate; + } cnt; + } error1_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + logic incrthreshold; + logic incrsaturate; + } cnt; + } error2_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + logic incrthreshold; + logic incrsaturate; + } cnt; + } error3_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + logic incrthreshold; + logic incrsaturate; + } cnt; + } notif_cmd_done_intr_count_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + logic decrthreshold; + logic underflow; + } pulse; + } error0_intr_count_incr_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + logic decrthreshold; + logic underflow; + } pulse; + } error1_intr_count_incr_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + logic decrthreshold; + logic underflow; + } pulse; + } error2_intr_count_incr_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + logic decrthreshold; + logic underflow; + } pulse; + } error3_intr_count_incr_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + logic decrthreshold; + logic underflow; + } pulse; + } notif_cmd_done_intr_count_incr_r; + } intr_block_rf; + } field_combo_t; + field_combo_t field_combo; + + typedef struct packed{ + struct packed{ + struct packed{ + logic value; + } LOCK; + } LOCK; + struct packed{ + struct packed{ + logic [31:0] value; + } USER; + } USER; + struct packed{ + struct packed{ + logic [1:0] value; + } MODE; + struct packed{ + logic value; + } ENDIAN_TOGGLE; + } MODE; + struct packed{ + struct packed{ + logic [31:0] value; + } ADDR; + } START_ADDRESS; + struct packed{ + struct packed{ + logic [31:0] value; + } LENGTH; + } DLEN; + struct packed{ + struct packed{ + logic [31:0] value; + } DATAIN; + } DATAIN; + struct packed{ + struct packed{ + logic value; + } EXECUTE; + } EXECUTE; + struct packed{ + struct packed{ + logic value; + } VALID; + struct packed{ + logic value; + } SOC_HAS_LOCK; + } STATUS; + struct packed{ + struct packed{ + logic [31:0] value; + } DIGEST; + } [16-1:0]DIGEST; + struct packed{ + struct packed{ + logic value; + } ZEROIZE; + } CONTROL; + struct packed{ + struct packed{ + struct packed{ + logic value; + } error_en; + struct packed{ + logic value; + } notif_en; + } global_intr_en_r; + struct packed{ + struct packed{ + logic value; + } error0_en; + struct packed{ + logic value; + } error1_en; + struct packed{ + logic value; + } error2_en; + struct packed{ + logic value; + } error3_en; + } error_intr_en_r; + struct packed{ + struct packed{ + logic value; + } notif_cmd_done_en; + } notif_intr_en_r; + struct packed{ + struct packed{ + logic value; + } agg_sts; + } error_global_intr_r; + struct packed{ + struct packed{ + logic value; + } agg_sts; + } notif_global_intr_r; + struct packed{ + struct packed{ + logic value; + } error0_sts; + struct packed{ + logic value; + } error1_sts; + struct packed{ + logic value; + } error2_sts; + struct packed{ + logic value; + } error3_sts; + } error_internal_intr_r; + struct packed{ + struct packed{ + logic value; + } notif_cmd_done_sts; + } notif_internal_intr_r; + struct packed{ + struct packed{ + logic value; + } error0_trig; + struct packed{ + logic value; + } error1_trig; + struct packed{ + logic value; + } error2_trig; + struct packed{ + logic value; + } error3_trig; + } error_intr_trig_r; + struct packed{ + struct packed{ + logic value; + } notif_cmd_done_trig; + } notif_intr_trig_r; + struct packed{ + struct packed{ + logic [31:0] value; + } cnt; + } error0_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] value; + } cnt; + } error1_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] value; + } cnt; + } error2_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] value; + } cnt; + } error3_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] value; + } cnt; + } notif_cmd_done_intr_count_r; + struct packed{ + struct packed{ + logic value; + } pulse; + } error0_intr_count_incr_r; + struct packed{ + struct packed{ + logic value; + } pulse; + } error1_intr_count_incr_r; + struct packed{ + struct packed{ + logic value; + } pulse; + } error2_intr_count_incr_r; + struct packed{ + struct packed{ + logic value; + } pulse; + } error3_intr_count_incr_r; + struct packed{ + struct packed{ + logic value; + } pulse; + } notif_cmd_done_intr_count_incr_r; + } intr_block_rf; + } field_storage_t; + field_storage_t field_storage; + + // Field: sha512_acc_csr.LOCK.LOCK + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.LOCK.LOCK.value; + load_next_c = '0; + if(decoded_reg_strb.LOCK && !decoded_req_is_wr) begin // SW set on read + next_c = '1; + load_next_c = '1; + end else if(decoded_reg_strb.LOCK && decoded_req_is_wr && hwif_in.valid_user) begin // SW write 1 clear + next_c = field_storage.LOCK.LOCK.value & ~(decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end + field_combo.LOCK.LOCK.next = next_c; + field_combo.LOCK.LOCK.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.LOCK.LOCK.value <= 1'h1; + end else if(field_combo.LOCK.LOCK.load_next) begin + field_storage.LOCK.LOCK.value <= field_combo.LOCK.LOCK.next; + end + end + assign hwif_out.LOCK.LOCK.value = field_storage.LOCK.LOCK.value; + assign hwif_out.LOCK.LOCK.swmod = decoded_reg_strb.LOCK; + // Field: sha512_acc_csr.USER.USER + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.USER.USER.value; + load_next_c = '0; + if(hwif_in.lock_set) begin // HW Write - we + next_c = hwif_in.USER.USER.next; + load_next_c = '1; + end + field_combo.USER.USER.next = next_c; + field_combo.USER.USER.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.USER.USER.value <= 32'h0; + end else if(field_combo.USER.USER.load_next) begin + field_storage.USER.USER.value <= field_combo.USER.USER.next; + end + end + assign hwif_out.USER.USER.value = field_storage.USER.USER.value; + // Field: sha512_acc_csr.MODE.MODE + always_comb begin + automatic logic [1:0] next_c; + automatic logic load_next_c; + next_c = field_storage.MODE.MODE.value; + load_next_c = '0; + if(decoded_reg_strb.MODE && decoded_req_is_wr && hwif_in.valid_user) begin // SW write + next_c = (field_storage.MODE.MODE.value & ~decoded_wr_biten[1:0]) | (decoded_wr_data[1:0] & decoded_wr_biten[1:0]); + load_next_c = '1; + end + field_combo.MODE.MODE.next = next_c; + field_combo.MODE.MODE.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.MODE.MODE.value <= 2'h0; + end else if(field_combo.MODE.MODE.load_next) begin + field_storage.MODE.MODE.value <= field_combo.MODE.MODE.next; + end + end + assign hwif_out.MODE.MODE.value = field_storage.MODE.MODE.value; + assign hwif_out.MODE.MODE.swmod = decoded_reg_strb.MODE && decoded_req_is_wr; + // Field: sha512_acc_csr.MODE.ENDIAN_TOGGLE + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.MODE.ENDIAN_TOGGLE.value; + load_next_c = '0; + if(decoded_reg_strb.MODE && decoded_req_is_wr && hwif_in.valid_user) begin // SW write + next_c = (field_storage.MODE.ENDIAN_TOGGLE.value & ~decoded_wr_biten[2:2]) | (decoded_wr_data[2:2] & decoded_wr_biten[2:2]); + load_next_c = '1; + end + field_combo.MODE.ENDIAN_TOGGLE.next = next_c; + field_combo.MODE.ENDIAN_TOGGLE.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.MODE.ENDIAN_TOGGLE.value <= 1'h0; + end else if(field_combo.MODE.ENDIAN_TOGGLE.load_next) begin + field_storage.MODE.ENDIAN_TOGGLE.value <= field_combo.MODE.ENDIAN_TOGGLE.next; + end + end + assign hwif_out.MODE.ENDIAN_TOGGLE.value = field_storage.MODE.ENDIAN_TOGGLE.value; + // Field: sha512_acc_csr.START_ADDRESS.ADDR + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.START_ADDRESS.ADDR.value; + load_next_c = '0; + if(decoded_reg_strb.START_ADDRESS && decoded_req_is_wr && hwif_in.valid_user) begin // SW write + next_c = (field_storage.START_ADDRESS.ADDR.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + field_combo.START_ADDRESS.ADDR.next = next_c; + field_combo.START_ADDRESS.ADDR.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.START_ADDRESS.ADDR.value <= 32'h0; + end else if(field_combo.START_ADDRESS.ADDR.load_next) begin + field_storage.START_ADDRESS.ADDR.value <= field_combo.START_ADDRESS.ADDR.next; + end + end + assign hwif_out.START_ADDRESS.ADDR.value = field_storage.START_ADDRESS.ADDR.value; + // Field: sha512_acc_csr.DLEN.LENGTH + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.DLEN.LENGTH.value; + load_next_c = '0; + if(decoded_reg_strb.DLEN && decoded_req_is_wr && hwif_in.valid_user) begin // SW write + next_c = (field_storage.DLEN.LENGTH.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + field_combo.DLEN.LENGTH.next = next_c; + field_combo.DLEN.LENGTH.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.DLEN.LENGTH.value <= 32'h0; + end else if(field_combo.DLEN.LENGTH.load_next) begin + field_storage.DLEN.LENGTH.value <= field_combo.DLEN.LENGTH.next; + end + end + assign hwif_out.DLEN.LENGTH.value = field_storage.DLEN.LENGTH.value; + // Field: sha512_acc_csr.DATAIN.DATAIN + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.DATAIN.DATAIN.value; + load_next_c = '0; + if(decoded_reg_strb.DATAIN && decoded_req_is_wr && hwif_in.valid_user) begin // SW write + next_c = (field_storage.DATAIN.DATAIN.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + field_combo.DATAIN.DATAIN.next = next_c; + field_combo.DATAIN.DATAIN.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.DATAIN.DATAIN.value <= 32'h0; + end else if(field_combo.DATAIN.DATAIN.load_next) begin + field_storage.DATAIN.DATAIN.value <= field_combo.DATAIN.DATAIN.next; + end + end + assign hwif_out.DATAIN.DATAIN.swmod = decoded_reg_strb.DATAIN && decoded_req_is_wr; + // Field: sha512_acc_csr.EXECUTE.EXECUTE + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.EXECUTE.EXECUTE.value; + load_next_c = '0; + if(decoded_reg_strb.EXECUTE && decoded_req_is_wr && hwif_in.valid_user) begin // SW write + next_c = (field_storage.EXECUTE.EXECUTE.value & ~decoded_wr_biten[0:0]) | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end else if(hwif_in.EXECUTE.EXECUTE.hwclr) begin // HW Clear + next_c = '0; + load_next_c = '1; + end + field_combo.EXECUTE.EXECUTE.next = next_c; + field_combo.EXECUTE.EXECUTE.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.EXECUTE.EXECUTE.value <= 1'h0; + end else if(field_combo.EXECUTE.EXECUTE.load_next) begin + field_storage.EXECUTE.EXECUTE.value <= field_combo.EXECUTE.EXECUTE.next; + end + end + assign hwif_out.EXECUTE.EXECUTE.value = field_storage.EXECUTE.EXECUTE.value; + // Field: sha512_acc_csr.STATUS.VALID + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.STATUS.VALID.value; + load_next_c = '0; + + // HW Write + next_c = hwif_in.STATUS.VALID.next; + load_next_c = '1; + field_combo.STATUS.VALID.next = next_c; + field_combo.STATUS.VALID.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.STATUS.VALID.value <= 1'h0; + end else if(field_combo.STATUS.VALID.load_next) begin + field_storage.STATUS.VALID.value <= field_combo.STATUS.VALID.next; + end + end + assign hwif_out.STATUS.VALID.value = field_storage.STATUS.VALID.value; + // Field: sha512_acc_csr.STATUS.SOC_HAS_LOCK + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.STATUS.SOC_HAS_LOCK.value; + load_next_c = '0; + + // HW Write + next_c = hwif_in.STATUS.SOC_HAS_LOCK.next; + load_next_c = '1; + field_combo.STATUS.SOC_HAS_LOCK.next = next_c; + field_combo.STATUS.SOC_HAS_LOCK.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.STATUS.SOC_HAS_LOCK.value <= 1'h0; + end else if(field_combo.STATUS.SOC_HAS_LOCK.load_next) begin + field_storage.STATUS.SOC_HAS_LOCK.value <= field_combo.STATUS.SOC_HAS_LOCK.next; + end + end + assign hwif_out.STATUS.SOC_HAS_LOCK.value = field_storage.STATUS.SOC_HAS_LOCK.value; + for(genvar i0=0; i0<16; i0++) begin + // Field: sha512_acc_csr.DIGEST[].DIGEST + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.DIGEST[i0].DIGEST.value; + load_next_c = '0; + if(hwif_in.DIGEST[i0].DIGEST.hwclr) begin // HW Clear + next_c = '0; + load_next_c = '1; + end else begin // HW Write + next_c = hwif_in.DIGEST[i0].DIGEST.next; + load_next_c = '1; + end + field_combo.DIGEST[i0].DIGEST.next = next_c; + field_combo.DIGEST[i0].DIGEST.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.DIGEST[i0].DIGEST.value <= 32'h0; + end else if(field_combo.DIGEST[i0].DIGEST.load_next) begin + field_storage.DIGEST[i0].DIGEST.value <= field_combo.DIGEST[i0].DIGEST.next; + end + end + end + // Field: sha512_acc_csr.CONTROL.ZEROIZE + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.CONTROL.ZEROIZE.value; + load_next_c = '0; + if(decoded_reg_strb.CONTROL && decoded_req_is_wr) begin // SW write + next_c = (field_storage.CONTROL.ZEROIZE.value & ~decoded_wr_biten[0:0]) | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end else begin // singlepulse clears back to 0 + next_c = '0; + load_next_c = '1; + end + field_combo.CONTROL.ZEROIZE.next = next_c; + field_combo.CONTROL.ZEROIZE.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.CONTROL.ZEROIZE.value <= 1'h0; + end else if(field_combo.CONTROL.ZEROIZE.load_next) begin + field_storage.CONTROL.ZEROIZE.value <= field_combo.CONTROL.ZEROIZE.next; + end + end + assign hwif_out.CONTROL.ZEROIZE.value = field_storage.CONTROL.ZEROIZE.value; + // Field: sha512_acc_csr.intr_block_rf.global_intr_en_r.error_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.global_intr_en_r.error_en.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.global_intr_en_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.intr_block_rf.global_intr_en_r.error_en.value & ~decoded_wr_biten[0:0]) | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end + field_combo.intr_block_rf.global_intr_en_r.error_en.next = next_c; + field_combo.intr_block_rf.global_intr_en_r.error_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.global_intr_en_r.error_en.value <= 1'h0; + end else if(field_combo.intr_block_rf.global_intr_en_r.error_en.load_next) begin + field_storage.intr_block_rf.global_intr_en_r.error_en.value <= field_combo.intr_block_rf.global_intr_en_r.error_en.next; + end + end + // Field: sha512_acc_csr.intr_block_rf.global_intr_en_r.notif_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.global_intr_en_r.notif_en.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.global_intr_en_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.intr_block_rf.global_intr_en_r.notif_en.value & ~decoded_wr_biten[1:1]) | (decoded_wr_data[1:1] & decoded_wr_biten[1:1]); + load_next_c = '1; + end + field_combo.intr_block_rf.global_intr_en_r.notif_en.next = next_c; + field_combo.intr_block_rf.global_intr_en_r.notif_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.global_intr_en_r.notif_en.value <= 1'h0; + end else if(field_combo.intr_block_rf.global_intr_en_r.notif_en.load_next) begin + field_storage.intr_block_rf.global_intr_en_r.notif_en.value <= field_combo.intr_block_rf.global_intr_en_r.notif_en.next; + end + end + // Field: sha512_acc_csr.intr_block_rf.error_intr_en_r.error0_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_intr_en_r.error0_en.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_intr_en_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.intr_block_rf.error_intr_en_r.error0_en.value & ~decoded_wr_biten[0:0]) | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end + field_combo.intr_block_rf.error_intr_en_r.error0_en.next = next_c; + field_combo.intr_block_rf.error_intr_en_r.error0_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.error_intr_en_r.error0_en.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_intr_en_r.error0_en.load_next) begin + field_storage.intr_block_rf.error_intr_en_r.error0_en.value <= field_combo.intr_block_rf.error_intr_en_r.error0_en.next; + end + end + // Field: sha512_acc_csr.intr_block_rf.error_intr_en_r.error1_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_intr_en_r.error1_en.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_intr_en_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.intr_block_rf.error_intr_en_r.error1_en.value & ~decoded_wr_biten[1:1]) | (decoded_wr_data[1:1] & decoded_wr_biten[1:1]); + load_next_c = '1; + end + field_combo.intr_block_rf.error_intr_en_r.error1_en.next = next_c; + field_combo.intr_block_rf.error_intr_en_r.error1_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.error_intr_en_r.error1_en.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_intr_en_r.error1_en.load_next) begin + field_storage.intr_block_rf.error_intr_en_r.error1_en.value <= field_combo.intr_block_rf.error_intr_en_r.error1_en.next; + end + end + // Field: sha512_acc_csr.intr_block_rf.error_intr_en_r.error2_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_intr_en_r.error2_en.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_intr_en_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.intr_block_rf.error_intr_en_r.error2_en.value & ~decoded_wr_biten[2:2]) | (decoded_wr_data[2:2] & decoded_wr_biten[2:2]); + load_next_c = '1; + end + field_combo.intr_block_rf.error_intr_en_r.error2_en.next = next_c; + field_combo.intr_block_rf.error_intr_en_r.error2_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.error_intr_en_r.error2_en.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_intr_en_r.error2_en.load_next) begin + field_storage.intr_block_rf.error_intr_en_r.error2_en.value <= field_combo.intr_block_rf.error_intr_en_r.error2_en.next; + end + end + // Field: sha512_acc_csr.intr_block_rf.error_intr_en_r.error3_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_intr_en_r.error3_en.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_intr_en_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.intr_block_rf.error_intr_en_r.error3_en.value & ~decoded_wr_biten[3:3]) | (decoded_wr_data[3:3] & decoded_wr_biten[3:3]); + load_next_c = '1; + end + field_combo.intr_block_rf.error_intr_en_r.error3_en.next = next_c; + field_combo.intr_block_rf.error_intr_en_r.error3_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.error_intr_en_r.error3_en.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_intr_en_r.error3_en.load_next) begin + field_storage.intr_block_rf.error_intr_en_r.error3_en.value <= field_combo.intr_block_rf.error_intr_en_r.error3_en.next; + end + end + // Field: sha512_acc_csr.intr_block_rf.notif_intr_en_r.notif_cmd_done_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_intr_en_r.notif_cmd_done_en.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.notif_intr_en_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.intr_block_rf.notif_intr_en_r.notif_cmd_done_en.value & ~decoded_wr_biten[0:0]) | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end + field_combo.intr_block_rf.notif_intr_en_r.notif_cmd_done_en.next = next_c; + field_combo.intr_block_rf.notif_intr_en_r.notif_cmd_done_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.notif_intr_en_r.notif_cmd_done_en.value <= 1'h0; + end else if(field_combo.intr_block_rf.notif_intr_en_r.notif_cmd_done_en.load_next) begin + field_storage.intr_block_rf.notif_intr_en_r.notif_cmd_done_en.value <= field_combo.intr_block_rf.notif_intr_en_r.notif_cmd_done_en.next; + end + end + // Field: sha512_acc_csr.intr_block_rf.error_global_intr_r.agg_sts + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_global_intr_r.agg_sts.value; + load_next_c = '0; + + // HW Write + next_c = hwif_out.intr_block_rf.error_internal_intr_r.intr; + load_next_c = '1; + field_combo.intr_block_rf.error_global_intr_r.agg_sts.next = next_c; + field_combo.intr_block_rf.error_global_intr_r.agg_sts.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.error_global_intr_r.agg_sts.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_global_intr_r.agg_sts.load_next) begin + field_storage.intr_block_rf.error_global_intr_r.agg_sts.value <= field_combo.intr_block_rf.error_global_intr_r.agg_sts.next; + end + end + assign hwif_out.intr_block_rf.error_global_intr_r.intr = + |(field_storage.intr_block_rf.error_global_intr_r.agg_sts.value & field_storage.intr_block_rf.global_intr_en_r.error_en.value); + // Field: sha512_acc_csr.intr_block_rf.notif_global_intr_r.agg_sts + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_global_intr_r.agg_sts.value; + load_next_c = '0; + + // HW Write + next_c = hwif_out.intr_block_rf.notif_internal_intr_r.intr; + load_next_c = '1; + field_combo.intr_block_rf.notif_global_intr_r.agg_sts.next = next_c; + field_combo.intr_block_rf.notif_global_intr_r.agg_sts.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.notif_global_intr_r.agg_sts.value <= 1'h0; + end else if(field_combo.intr_block_rf.notif_global_intr_r.agg_sts.load_next) begin + field_storage.intr_block_rf.notif_global_intr_r.agg_sts.value <= field_combo.intr_block_rf.notif_global_intr_r.agg_sts.next; + end + end + assign hwif_out.intr_block_rf.notif_global_intr_r.intr = + |(field_storage.intr_block_rf.notif_global_intr_r.agg_sts.value & field_storage.intr_block_rf.global_intr_en_r.notif_en.value); + // Field: sha512_acc_csr.intr_block_rf.error_internal_intr_r.error0_sts + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_internal_intr_r.error0_sts.value; + load_next_c = '0; + if(field_storage.intr_block_rf.error_intr_trig_r.error0_trig.value != '0) begin // stickybit + next_c = field_storage.intr_block_rf.error_internal_intr_r.error0_sts.value | field_storage.intr_block_rf.error_intr_trig_r.error0_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.error_internal_intr_r.error0_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end else if(decoded_reg_strb.intr_block_rf.error_internal_intr_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write 1 clear + next_c = field_storage.intr_block_rf.error_internal_intr_r.error0_sts.value & ~(decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end + field_combo.intr_block_rf.error_internal_intr_r.error0_sts.next = next_c; + field_combo.intr_block_rf.error_internal_intr_r.error0_sts.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.intr_block_rf.error_internal_intr_r.error0_sts.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_internal_intr_r.error0_sts.load_next) begin + field_storage.intr_block_rf.error_internal_intr_r.error0_sts.value <= field_combo.intr_block_rf.error_internal_intr_r.error0_sts.next; + end + end + // Field: sha512_acc_csr.intr_block_rf.error_internal_intr_r.error1_sts + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_internal_intr_r.error1_sts.value; + load_next_c = '0; + if(field_storage.intr_block_rf.error_intr_trig_r.error1_trig.value != '0) begin // stickybit + next_c = field_storage.intr_block_rf.error_internal_intr_r.error1_sts.value | field_storage.intr_block_rf.error_intr_trig_r.error1_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.error_internal_intr_r.error1_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end else if(decoded_reg_strb.intr_block_rf.error_internal_intr_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write 1 clear + next_c = field_storage.intr_block_rf.error_internal_intr_r.error1_sts.value & ~(decoded_wr_data[1:1] & decoded_wr_biten[1:1]); + load_next_c = '1; + end + field_combo.intr_block_rf.error_internal_intr_r.error1_sts.next = next_c; + field_combo.intr_block_rf.error_internal_intr_r.error1_sts.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.intr_block_rf.error_internal_intr_r.error1_sts.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_internal_intr_r.error1_sts.load_next) begin + field_storage.intr_block_rf.error_internal_intr_r.error1_sts.value <= field_combo.intr_block_rf.error_internal_intr_r.error1_sts.next; + end + end + // Field: sha512_acc_csr.intr_block_rf.error_internal_intr_r.error2_sts + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_internal_intr_r.error2_sts.value; + load_next_c = '0; + if(field_storage.intr_block_rf.error_intr_trig_r.error2_trig.value != '0) begin // stickybit + next_c = field_storage.intr_block_rf.error_internal_intr_r.error2_sts.value | field_storage.intr_block_rf.error_intr_trig_r.error2_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.error_internal_intr_r.error2_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end else if(decoded_reg_strb.intr_block_rf.error_internal_intr_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write 1 clear + next_c = field_storage.intr_block_rf.error_internal_intr_r.error2_sts.value & ~(decoded_wr_data[2:2] & decoded_wr_biten[2:2]); + load_next_c = '1; + end + field_combo.intr_block_rf.error_internal_intr_r.error2_sts.next = next_c; + field_combo.intr_block_rf.error_internal_intr_r.error2_sts.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.intr_block_rf.error_internal_intr_r.error2_sts.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_internal_intr_r.error2_sts.load_next) begin + field_storage.intr_block_rf.error_internal_intr_r.error2_sts.value <= field_combo.intr_block_rf.error_internal_intr_r.error2_sts.next; + end + end + // Field: sha512_acc_csr.intr_block_rf.error_internal_intr_r.error3_sts + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_internal_intr_r.error3_sts.value; + load_next_c = '0; + if(field_storage.intr_block_rf.error_intr_trig_r.error3_trig.value != '0) begin // stickybit + next_c = field_storage.intr_block_rf.error_internal_intr_r.error3_sts.value | field_storage.intr_block_rf.error_intr_trig_r.error3_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.error_internal_intr_r.error3_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end else if(decoded_reg_strb.intr_block_rf.error_internal_intr_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write 1 clear + next_c = field_storage.intr_block_rf.error_internal_intr_r.error3_sts.value & ~(decoded_wr_data[3:3] & decoded_wr_biten[3:3]); + load_next_c = '1; + end + field_combo.intr_block_rf.error_internal_intr_r.error3_sts.next = next_c; + field_combo.intr_block_rf.error_internal_intr_r.error3_sts.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.intr_block_rf.error_internal_intr_r.error3_sts.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_internal_intr_r.error3_sts.load_next) begin + field_storage.intr_block_rf.error_internal_intr_r.error3_sts.value <= field_combo.intr_block_rf.error_internal_intr_r.error3_sts.next; + end + end + assign hwif_out.intr_block_rf.error_internal_intr_r.intr = + |(field_storage.intr_block_rf.error_internal_intr_r.error0_sts.value & field_storage.intr_block_rf.error_intr_en_r.error0_en.value) + || |(field_storage.intr_block_rf.error_internal_intr_r.error1_sts.value & field_storage.intr_block_rf.error_intr_en_r.error1_en.value) + || |(field_storage.intr_block_rf.error_internal_intr_r.error2_sts.value & field_storage.intr_block_rf.error_intr_en_r.error2_en.value) + || |(field_storage.intr_block_rf.error_internal_intr_r.error3_sts.value & field_storage.intr_block_rf.error_intr_en_r.error3_en.value); + // Field: sha512_acc_csr.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.value; + load_next_c = '0; + if(field_storage.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.value != '0) begin // stickybit + next_c = field_storage.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.value | field_storage.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end else if(decoded_reg_strb.intr_block_rf.notif_internal_intr_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write 1 clear + next_c = field_storage.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.value & ~(decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end + field_combo.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.next = next_c; + field_combo.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.value <= 1'h0; + end else if(field_combo.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.load_next) begin + field_storage.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.value <= field_combo.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.next; + end + end + assign hwif_out.intr_block_rf.notif_internal_intr_r.intr = + |(field_storage.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.value & field_storage.intr_block_rf.notif_intr_en_r.notif_cmd_done_en.value); + // Field: sha512_acc_csr.intr_block_rf.error_intr_trig_r.error0_trig + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_intr_trig_r.error0_trig.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_intr_trig_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write 1 set + next_c = field_storage.intr_block_rf.error_intr_trig_r.error0_trig.value | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end else begin // singlepulse clears back to 0 + next_c = '0; + load_next_c = '1; + end + field_combo.intr_block_rf.error_intr_trig_r.error0_trig.next = next_c; + field_combo.intr_block_rf.error_intr_trig_r.error0_trig.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.error_intr_trig_r.error0_trig.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_intr_trig_r.error0_trig.load_next) begin + field_storage.intr_block_rf.error_intr_trig_r.error0_trig.value <= field_combo.intr_block_rf.error_intr_trig_r.error0_trig.next; + end + end + // Field: sha512_acc_csr.intr_block_rf.error_intr_trig_r.error1_trig + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_intr_trig_r.error1_trig.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_intr_trig_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write 1 set + next_c = field_storage.intr_block_rf.error_intr_trig_r.error1_trig.value | (decoded_wr_data[1:1] & decoded_wr_biten[1:1]); + load_next_c = '1; + end else begin // singlepulse clears back to 0 + next_c = '0; + load_next_c = '1; + end + field_combo.intr_block_rf.error_intr_trig_r.error1_trig.next = next_c; + field_combo.intr_block_rf.error_intr_trig_r.error1_trig.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.error_intr_trig_r.error1_trig.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_intr_trig_r.error1_trig.load_next) begin + field_storage.intr_block_rf.error_intr_trig_r.error1_trig.value <= field_combo.intr_block_rf.error_intr_trig_r.error1_trig.next; + end + end + // Field: sha512_acc_csr.intr_block_rf.error_intr_trig_r.error2_trig + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_intr_trig_r.error2_trig.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_intr_trig_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write 1 set + next_c = field_storage.intr_block_rf.error_intr_trig_r.error2_trig.value | (decoded_wr_data[2:2] & decoded_wr_biten[2:2]); + load_next_c = '1; + end else begin // singlepulse clears back to 0 + next_c = '0; + load_next_c = '1; + end + field_combo.intr_block_rf.error_intr_trig_r.error2_trig.next = next_c; + field_combo.intr_block_rf.error_intr_trig_r.error2_trig.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.error_intr_trig_r.error2_trig.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_intr_trig_r.error2_trig.load_next) begin + field_storage.intr_block_rf.error_intr_trig_r.error2_trig.value <= field_combo.intr_block_rf.error_intr_trig_r.error2_trig.next; + end + end + // Field: sha512_acc_csr.intr_block_rf.error_intr_trig_r.error3_trig + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_intr_trig_r.error3_trig.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_intr_trig_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write 1 set + next_c = field_storage.intr_block_rf.error_intr_trig_r.error3_trig.value | (decoded_wr_data[3:3] & decoded_wr_biten[3:3]); + load_next_c = '1; + end else begin // singlepulse clears back to 0 + next_c = '0; + load_next_c = '1; + end + field_combo.intr_block_rf.error_intr_trig_r.error3_trig.next = next_c; + field_combo.intr_block_rf.error_intr_trig_r.error3_trig.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.error_intr_trig_r.error3_trig.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_intr_trig_r.error3_trig.load_next) begin + field_storage.intr_block_rf.error_intr_trig_r.error3_trig.value <= field_combo.intr_block_rf.error_intr_trig_r.error3_trig.next; + end + end + // Field: sha512_acc_csr.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.notif_intr_trig_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write 1 set + next_c = field_storage.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.value | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end else begin // singlepulse clears back to 0 + next_c = '0; + load_next_c = '1; + end + field_combo.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.next = next_c; + field_combo.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.value <= 1'h0; + end else if(field_combo.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.load_next) begin + field_storage.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.value <= field_combo.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.next; + end + end + // Field: sha512_acc_csr.intr_block_rf.error0_intr_count_r.cnt + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error0_intr_count_r.cnt.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error0_intr_count_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.intr_block_rf.error0_intr_count_r.cnt.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + if(field_storage.intr_block_rf.error0_intr_count_incr_r.pulse.value) begin // increment + if(((33)'(next_c) + 32'h1) > 32'hffffffff) begin // up-counter saturated + next_c = 32'hffffffff; + end else begin + next_c = next_c + 32'h1; + end + load_next_c = '1; + end + field_combo.intr_block_rf.error0_intr_count_r.cnt.incrthreshold = (field_storage.intr_block_rf.error0_intr_count_r.cnt.value >= 32'hffffffff); + field_combo.intr_block_rf.error0_intr_count_r.cnt.incrsaturate = (field_storage.intr_block_rf.error0_intr_count_r.cnt.value >= 32'hffffffff); + if(next_c > 32'hffffffff) begin + next_c = 32'hffffffff; + load_next_c = '1; + end + field_combo.intr_block_rf.error0_intr_count_r.cnt.next = next_c; + field_combo.intr_block_rf.error0_intr_count_r.cnt.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.intr_block_rf.error0_intr_count_r.cnt.value <= 32'h0; + end else if(field_combo.intr_block_rf.error0_intr_count_r.cnt.load_next) begin + field_storage.intr_block_rf.error0_intr_count_r.cnt.value <= field_combo.intr_block_rf.error0_intr_count_r.cnt.next; + end + end + // Field: sha512_acc_csr.intr_block_rf.error1_intr_count_r.cnt + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error1_intr_count_r.cnt.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error1_intr_count_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.intr_block_rf.error1_intr_count_r.cnt.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + if(field_storage.intr_block_rf.error1_intr_count_incr_r.pulse.value) begin // increment + if(((33)'(next_c) + 32'h1) > 32'hffffffff) begin // up-counter saturated + next_c = 32'hffffffff; + end else begin + next_c = next_c + 32'h1; + end + load_next_c = '1; + end + field_combo.intr_block_rf.error1_intr_count_r.cnt.incrthreshold = (field_storage.intr_block_rf.error1_intr_count_r.cnt.value >= 32'hffffffff); + field_combo.intr_block_rf.error1_intr_count_r.cnt.incrsaturate = (field_storage.intr_block_rf.error1_intr_count_r.cnt.value >= 32'hffffffff); + if(next_c > 32'hffffffff) begin + next_c = 32'hffffffff; + load_next_c = '1; + end + field_combo.intr_block_rf.error1_intr_count_r.cnt.next = next_c; + field_combo.intr_block_rf.error1_intr_count_r.cnt.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.intr_block_rf.error1_intr_count_r.cnt.value <= 32'h0; + end else if(field_combo.intr_block_rf.error1_intr_count_r.cnt.load_next) begin + field_storage.intr_block_rf.error1_intr_count_r.cnt.value <= field_combo.intr_block_rf.error1_intr_count_r.cnt.next; + end + end + // Field: sha512_acc_csr.intr_block_rf.error2_intr_count_r.cnt + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error2_intr_count_r.cnt.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error2_intr_count_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.intr_block_rf.error2_intr_count_r.cnt.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + if(field_storage.intr_block_rf.error2_intr_count_incr_r.pulse.value) begin // increment + if(((33)'(next_c) + 32'h1) > 32'hffffffff) begin // up-counter saturated + next_c = 32'hffffffff; + end else begin + next_c = next_c + 32'h1; + end + load_next_c = '1; + end + field_combo.intr_block_rf.error2_intr_count_r.cnt.incrthreshold = (field_storage.intr_block_rf.error2_intr_count_r.cnt.value >= 32'hffffffff); + field_combo.intr_block_rf.error2_intr_count_r.cnt.incrsaturate = (field_storage.intr_block_rf.error2_intr_count_r.cnt.value >= 32'hffffffff); + if(next_c > 32'hffffffff) begin + next_c = 32'hffffffff; + load_next_c = '1; + end + field_combo.intr_block_rf.error2_intr_count_r.cnt.next = next_c; + field_combo.intr_block_rf.error2_intr_count_r.cnt.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.intr_block_rf.error2_intr_count_r.cnt.value <= 32'h0; + end else if(field_combo.intr_block_rf.error2_intr_count_r.cnt.load_next) begin + field_storage.intr_block_rf.error2_intr_count_r.cnt.value <= field_combo.intr_block_rf.error2_intr_count_r.cnt.next; + end + end + // Field: sha512_acc_csr.intr_block_rf.error3_intr_count_r.cnt + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error3_intr_count_r.cnt.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error3_intr_count_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.intr_block_rf.error3_intr_count_r.cnt.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + if(field_storage.intr_block_rf.error3_intr_count_incr_r.pulse.value) begin // increment + if(((33)'(next_c) + 32'h1) > 32'hffffffff) begin // up-counter saturated + next_c = 32'hffffffff; + end else begin + next_c = next_c + 32'h1; + end + load_next_c = '1; + end + field_combo.intr_block_rf.error3_intr_count_r.cnt.incrthreshold = (field_storage.intr_block_rf.error3_intr_count_r.cnt.value >= 32'hffffffff); + field_combo.intr_block_rf.error3_intr_count_r.cnt.incrsaturate = (field_storage.intr_block_rf.error3_intr_count_r.cnt.value >= 32'hffffffff); + if(next_c > 32'hffffffff) begin + next_c = 32'hffffffff; + load_next_c = '1; + end + field_combo.intr_block_rf.error3_intr_count_r.cnt.next = next_c; + field_combo.intr_block_rf.error3_intr_count_r.cnt.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.intr_block_rf.error3_intr_count_r.cnt.value <= 32'h0; + end else if(field_combo.intr_block_rf.error3_intr_count_r.cnt.load_next) begin + field_storage.intr_block_rf.error3_intr_count_r.cnt.value <= field_combo.intr_block_rf.error3_intr_count_r.cnt.next; + end + end + // Field: sha512_acc_csr.intr_block_rf.notif_cmd_done_intr_count_r.cnt + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_cmd_done_intr_count_r.cnt.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.notif_cmd_done_intr_count_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.intr_block_rf.notif_cmd_done_intr_count_r.cnt.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + if(field_storage.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.value) begin // increment + if(((33)'(next_c) + 32'h1) > 32'hffffffff) begin // up-counter saturated + next_c = 32'hffffffff; + end else begin + next_c = next_c + 32'h1; + end + load_next_c = '1; + end + field_combo.intr_block_rf.notif_cmd_done_intr_count_r.cnt.incrthreshold = (field_storage.intr_block_rf.notif_cmd_done_intr_count_r.cnt.value >= 32'hffffffff); + field_combo.intr_block_rf.notif_cmd_done_intr_count_r.cnt.incrsaturate = (field_storage.intr_block_rf.notif_cmd_done_intr_count_r.cnt.value >= 32'hffffffff); + if(next_c > 32'hffffffff) begin + next_c = 32'hffffffff; + load_next_c = '1; + end + field_combo.intr_block_rf.notif_cmd_done_intr_count_r.cnt.next = next_c; + field_combo.intr_block_rf.notif_cmd_done_intr_count_r.cnt.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.notif_cmd_done_intr_count_r.cnt.value <= 32'h0; + end else if(field_combo.intr_block_rf.notif_cmd_done_intr_count_r.cnt.load_next) begin + field_storage.intr_block_rf.notif_cmd_done_intr_count_r.cnt.value <= field_combo.intr_block_rf.notif_cmd_done_intr_count_r.cnt.next; + end + end + // Field: sha512_acc_csr.intr_block_rf.error0_intr_count_incr_r.pulse + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error0_intr_count_incr_r.pulse.value; + load_next_c = '0; + if(field_storage.intr_block_rf.error_intr_trig_r.error0_trig.value) begin // HW Write - we + next_c = field_storage.intr_block_rf.error_intr_trig_r.error0_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.error_internal_intr_r.error0_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end + if(field_storage.intr_block_rf.error0_intr_count_incr_r.pulse.value) begin // decrement + field_combo.intr_block_rf.error0_intr_count_incr_r.pulse.underflow = (next_c < (1'h1)); + next_c = next_c - 1'h1; + load_next_c = '1; + end else begin + field_combo.intr_block_rf.error0_intr_count_incr_r.pulse.underflow = '0; + end + field_combo.intr_block_rf.error0_intr_count_incr_r.pulse.decrthreshold = (field_storage.intr_block_rf.error0_intr_count_incr_r.pulse.value <= 1'd0); + field_combo.intr_block_rf.error0_intr_count_incr_r.pulse.next = next_c; + field_combo.intr_block_rf.error0_intr_count_incr_r.pulse.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.error0_intr_count_incr_r.pulse.value <= 1'h0; + end else if(field_combo.intr_block_rf.error0_intr_count_incr_r.pulse.load_next) begin + field_storage.intr_block_rf.error0_intr_count_incr_r.pulse.value <= field_combo.intr_block_rf.error0_intr_count_incr_r.pulse.next; + end + end + // Field: sha512_acc_csr.intr_block_rf.error1_intr_count_incr_r.pulse + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error1_intr_count_incr_r.pulse.value; + load_next_c = '0; + if(field_storage.intr_block_rf.error_intr_trig_r.error1_trig.value) begin // HW Write - we + next_c = field_storage.intr_block_rf.error_intr_trig_r.error1_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.error_internal_intr_r.error1_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end + if(field_storage.intr_block_rf.error1_intr_count_incr_r.pulse.value) begin // decrement + field_combo.intr_block_rf.error1_intr_count_incr_r.pulse.underflow = (next_c < (1'h1)); + next_c = next_c - 1'h1; + load_next_c = '1; + end else begin + field_combo.intr_block_rf.error1_intr_count_incr_r.pulse.underflow = '0; + end + field_combo.intr_block_rf.error1_intr_count_incr_r.pulse.decrthreshold = (field_storage.intr_block_rf.error1_intr_count_incr_r.pulse.value <= 1'd0); + field_combo.intr_block_rf.error1_intr_count_incr_r.pulse.next = next_c; + field_combo.intr_block_rf.error1_intr_count_incr_r.pulse.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.error1_intr_count_incr_r.pulse.value <= 1'h0; + end else if(field_combo.intr_block_rf.error1_intr_count_incr_r.pulse.load_next) begin + field_storage.intr_block_rf.error1_intr_count_incr_r.pulse.value <= field_combo.intr_block_rf.error1_intr_count_incr_r.pulse.next; + end + end + // Field: sha512_acc_csr.intr_block_rf.error2_intr_count_incr_r.pulse + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error2_intr_count_incr_r.pulse.value; + load_next_c = '0; + if(field_storage.intr_block_rf.error_intr_trig_r.error2_trig.value) begin // HW Write - we + next_c = field_storage.intr_block_rf.error_intr_trig_r.error2_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.error_internal_intr_r.error2_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end + if(field_storage.intr_block_rf.error2_intr_count_incr_r.pulse.value) begin // decrement + field_combo.intr_block_rf.error2_intr_count_incr_r.pulse.underflow = (next_c < (1'h1)); + next_c = next_c - 1'h1; + load_next_c = '1; + end else begin + field_combo.intr_block_rf.error2_intr_count_incr_r.pulse.underflow = '0; + end + field_combo.intr_block_rf.error2_intr_count_incr_r.pulse.decrthreshold = (field_storage.intr_block_rf.error2_intr_count_incr_r.pulse.value <= 1'd0); + field_combo.intr_block_rf.error2_intr_count_incr_r.pulse.next = next_c; + field_combo.intr_block_rf.error2_intr_count_incr_r.pulse.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.error2_intr_count_incr_r.pulse.value <= 1'h0; + end else if(field_combo.intr_block_rf.error2_intr_count_incr_r.pulse.load_next) begin + field_storage.intr_block_rf.error2_intr_count_incr_r.pulse.value <= field_combo.intr_block_rf.error2_intr_count_incr_r.pulse.next; + end + end + // Field: sha512_acc_csr.intr_block_rf.error3_intr_count_incr_r.pulse + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error3_intr_count_incr_r.pulse.value; + load_next_c = '0; + if(field_storage.intr_block_rf.error_intr_trig_r.error3_trig.value) begin // HW Write - we + next_c = field_storage.intr_block_rf.error_intr_trig_r.error3_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.error_internal_intr_r.error3_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end + if(field_storage.intr_block_rf.error3_intr_count_incr_r.pulse.value) begin // decrement + field_combo.intr_block_rf.error3_intr_count_incr_r.pulse.underflow = (next_c < (1'h1)); + next_c = next_c - 1'h1; + load_next_c = '1; + end else begin + field_combo.intr_block_rf.error3_intr_count_incr_r.pulse.underflow = '0; + end + field_combo.intr_block_rf.error3_intr_count_incr_r.pulse.decrthreshold = (field_storage.intr_block_rf.error3_intr_count_incr_r.pulse.value <= 1'd0); + field_combo.intr_block_rf.error3_intr_count_incr_r.pulse.next = next_c; + field_combo.intr_block_rf.error3_intr_count_incr_r.pulse.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.error3_intr_count_incr_r.pulse.value <= 1'h0; + end else if(field_combo.intr_block_rf.error3_intr_count_incr_r.pulse.load_next) begin + field_storage.intr_block_rf.error3_intr_count_incr_r.pulse.value <= field_combo.intr_block_rf.error3_intr_count_incr_r.pulse.next; + end + end + // Field: sha512_acc_csr.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.value; + load_next_c = '0; + if(field_storage.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.value) begin // HW Write - we + next_c = field_storage.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end + if(field_storage.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.value) begin // decrement + field_combo.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.underflow = (next_c < (1'h1)); + next_c = next_c - 1'h1; + load_next_c = '1; + end else begin + field_combo.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.underflow = '0; + end + field_combo.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.decrthreshold = (field_storage.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.value <= 1'd0); + field_combo.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.next = next_c; + field_combo.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.value <= 1'h0; + end else if(field_combo.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.load_next) begin + field_storage.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.value <= field_combo.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.next; + end + end + + //-------------------------------------------------------------------------- + // Write response + //-------------------------------------------------------------------------- + assign cpuif_wr_ack = decoded_req & decoded_req_is_wr; + // Writes are always granted with no error response + assign cpuif_wr_err = '0; + + //-------------------------------------------------------------------------- + // Readback + //-------------------------------------------------------------------------- + + logic readback_err; + logic readback_done; + logic [31:0] readback_data; + + // Assign readback values to a flattened array + logic [44-1:0][31:0] readback_array; + assign readback_array[0][0:0] = (decoded_reg_strb.LOCK && !decoded_req_is_wr) ? field_storage.LOCK.LOCK.value : '0; + assign readback_array[0][31:1] = '0; + assign readback_array[1][31:0] = (decoded_reg_strb.USER && !decoded_req_is_wr) ? field_storage.USER.USER.value : '0; + assign readback_array[2][1:0] = (decoded_reg_strb.MODE && !decoded_req_is_wr) ? field_storage.MODE.MODE.value : '0; + assign readback_array[2][2:2] = (decoded_reg_strb.MODE && !decoded_req_is_wr) ? field_storage.MODE.ENDIAN_TOGGLE.value : '0; + assign readback_array[2][31:3] = '0; + assign readback_array[3][31:0] = (decoded_reg_strb.START_ADDRESS && !decoded_req_is_wr) ? field_storage.START_ADDRESS.ADDR.value : '0; + assign readback_array[4][31:0] = (decoded_reg_strb.DLEN && !decoded_req_is_wr) ? field_storage.DLEN.LENGTH.value : '0; + assign readback_array[5][31:0] = (decoded_reg_strb.DATAIN && !decoded_req_is_wr) ? field_storage.DATAIN.DATAIN.value : '0; + assign readback_array[6][0:0] = (decoded_reg_strb.EXECUTE && !decoded_req_is_wr) ? field_storage.EXECUTE.EXECUTE.value : '0; + assign readback_array[6][31:1] = '0; + assign readback_array[7][0:0] = (decoded_reg_strb.STATUS && !decoded_req_is_wr) ? field_storage.STATUS.VALID.value : '0; + assign readback_array[7][1:1] = (decoded_reg_strb.STATUS && !decoded_req_is_wr) ? field_storage.STATUS.SOC_HAS_LOCK.value : '0; + assign readback_array[7][31:2] = '0; + for(genvar i0=0; i0<16; i0++) begin + assign readback_array[i0*1 + 8][31:0] = (decoded_reg_strb.DIGEST[i0] && !decoded_req_is_wr) ? field_storage.DIGEST[i0].DIGEST.value : '0; + end + assign readback_array[24][0:0] = (decoded_reg_strb.CONTROL && !decoded_req_is_wr) ? field_storage.CONTROL.ZEROIZE.value : '0; + assign readback_array[24][31:1] = '0; + assign readback_array[25][0:0] = (decoded_reg_strb.intr_block_rf.global_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.global_intr_en_r.error_en.value : '0; + assign readback_array[25][1:1] = (decoded_reg_strb.intr_block_rf.global_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.global_intr_en_r.notif_en.value : '0; + assign readback_array[25][31:2] = '0; + assign readback_array[26][0:0] = (decoded_reg_strb.intr_block_rf.error_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_en_r.error0_en.value : '0; + assign readback_array[26][1:1] = (decoded_reg_strb.intr_block_rf.error_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_en_r.error1_en.value : '0; + assign readback_array[26][2:2] = (decoded_reg_strb.intr_block_rf.error_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_en_r.error2_en.value : '0; + assign readback_array[26][3:3] = (decoded_reg_strb.intr_block_rf.error_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_en_r.error3_en.value : '0; + assign readback_array[26][31:4] = '0; + assign readback_array[27][0:0] = (decoded_reg_strb.intr_block_rf.notif_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_intr_en_r.notif_cmd_done_en.value : '0; + assign readback_array[27][31:1] = '0; + assign readback_array[28][0:0] = (decoded_reg_strb.intr_block_rf.error_global_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_global_intr_r.agg_sts.value : '0; + assign readback_array[28][31:1] = '0; + assign readback_array[29][0:0] = (decoded_reg_strb.intr_block_rf.notif_global_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_global_intr_r.agg_sts.value : '0; + assign readback_array[29][31:1] = '0; + assign readback_array[30][0:0] = (decoded_reg_strb.intr_block_rf.error_internal_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_internal_intr_r.error0_sts.value : '0; + assign readback_array[30][1:1] = (decoded_reg_strb.intr_block_rf.error_internal_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_internal_intr_r.error1_sts.value : '0; + assign readback_array[30][2:2] = (decoded_reg_strb.intr_block_rf.error_internal_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_internal_intr_r.error2_sts.value : '0; + assign readback_array[30][3:3] = (decoded_reg_strb.intr_block_rf.error_internal_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_internal_intr_r.error3_sts.value : '0; + assign readback_array[30][31:4] = '0; + assign readback_array[31][0:0] = (decoded_reg_strb.intr_block_rf.notif_internal_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.value : '0; + assign readback_array[31][31:1] = '0; + assign readback_array[32][0:0] = (decoded_reg_strb.intr_block_rf.error_intr_trig_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_trig_r.error0_trig.value : '0; + assign readback_array[32][1:1] = (decoded_reg_strb.intr_block_rf.error_intr_trig_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_trig_r.error1_trig.value : '0; + assign readback_array[32][2:2] = (decoded_reg_strb.intr_block_rf.error_intr_trig_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_trig_r.error2_trig.value : '0; + assign readback_array[32][3:3] = (decoded_reg_strb.intr_block_rf.error_intr_trig_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_trig_r.error3_trig.value : '0; + assign readback_array[32][31:4] = '0; + assign readback_array[33][0:0] = (decoded_reg_strb.intr_block_rf.notif_intr_trig_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.value : '0; + assign readback_array[33][31:1] = '0; + assign readback_array[34][31:0] = (decoded_reg_strb.intr_block_rf.error0_intr_count_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error0_intr_count_r.cnt.value : '0; + assign readback_array[35][31:0] = (decoded_reg_strb.intr_block_rf.error1_intr_count_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error1_intr_count_r.cnt.value : '0; + assign readback_array[36][31:0] = (decoded_reg_strb.intr_block_rf.error2_intr_count_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error2_intr_count_r.cnt.value : '0; + assign readback_array[37][31:0] = (decoded_reg_strb.intr_block_rf.error3_intr_count_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error3_intr_count_r.cnt.value : '0; + assign readback_array[38][31:0] = (decoded_reg_strb.intr_block_rf.notif_cmd_done_intr_count_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_cmd_done_intr_count_r.cnt.value : '0; + assign readback_array[39][0:0] = (decoded_reg_strb.intr_block_rf.error0_intr_count_incr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error0_intr_count_incr_r.pulse.value : '0; + assign readback_array[39][31:1] = '0; + assign readback_array[40][0:0] = (decoded_reg_strb.intr_block_rf.error1_intr_count_incr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error1_intr_count_incr_r.pulse.value : '0; + assign readback_array[40][31:1] = '0; + assign readback_array[41][0:0] = (decoded_reg_strb.intr_block_rf.error2_intr_count_incr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error2_intr_count_incr_r.pulse.value : '0; + assign readback_array[41][31:1] = '0; + assign readback_array[42][0:0] = (decoded_reg_strb.intr_block_rf.error3_intr_count_incr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error3_intr_count_incr_r.pulse.value : '0; + assign readback_array[42][31:1] = '0; + assign readback_array[43][0:0] = (decoded_reg_strb.intr_block_rf.notif_cmd_done_intr_count_incr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.value : '0; + assign readback_array[43][31:1] = '0; + + // Reduce the array + always_comb begin + automatic logic [31:0] readback_data_var; + readback_done = decoded_req & ~decoded_req_is_wr; + readback_err = '0; + readback_data_var = '0; + for(int i=0; i<44; i++) readback_data_var |= readback_array[i]; + readback_data = readback_data_var; + end + + assign cpuif_rd_ack = readback_done; + assign cpuif_rd_data = readback_data; + assign cpuif_rd_err = readback_err; + +`CALIPTRA_ASSERT_KNOWN(ERR_HWIF_IN, hwif_in, clk, !hwif_in.cptra_pwrgood) + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/sha512_acc_csr_pkg.sv b/designs/Caliptra/src/caliptra-rtl/sha512_acc_csr_pkg.sv new file mode 100644 index 0000000..71e0470 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/sha512_acc_csr_pkg.sv @@ -0,0 +1,225 @@ +// Generated by PeakRDL-regblock - A free and open-source SystemVerilog generator +// https://github.com/SystemRDL/PeakRDL-regblock + +package sha512_acc_csr_pkg; + + localparam SHA512_ACC_CSR_DATA_WIDTH = 32; + localparam SHA512_ACC_CSR_MIN_ADDR_WIDTH = 12; + + typedef struct packed{ + logic [31:0] next; + } sha512_acc_csr__USER__USER__in_t; + + typedef struct packed{ + sha512_acc_csr__USER__USER__in_t USER; + } sha512_acc_csr__USER__in_t; + + typedef struct packed{ + logic hwclr; + } sha512_acc_csr__EXECUTE__EXECUTE__in_t; + + typedef struct packed{ + sha512_acc_csr__EXECUTE__EXECUTE__in_t EXECUTE; + } sha512_acc_csr__EXECUTE__in_t; + + typedef struct packed{ + logic next; + } sha512_acc_csr__STATUS__VALID__in_t; + + typedef struct packed{ + logic next; + } sha512_acc_csr__STATUS__SOC_HAS_LOCK__in_t; + + typedef struct packed{ + sha512_acc_csr__STATUS__VALID__in_t VALID; + sha512_acc_csr__STATUS__SOC_HAS_LOCK__in_t SOC_HAS_LOCK; + } sha512_acc_csr__STATUS__in_t; + + typedef struct packed{ + logic [31:0] next; + logic hwclr; + } sha512_acc_csr__DIGEST__DIGEST__in_t; + + typedef struct packed{ + sha512_acc_csr__DIGEST__DIGEST__in_t DIGEST; + } sha512_acc_csr__DIGEST__in_t; + + typedef struct packed{ + logic hwset; + } sha512_acc_csr__error_intr_t_error0_sts_5ee134bf_error1_sts_aad9583f_error2_sts_6cad4575_error3_sts_735bbeba__error0_sts_enable_528ccada_next_b1018582_resetsignal_f7aac87a__in_t; + + typedef struct packed{ + logic hwset; + } sha512_acc_csr__error_intr_t_error0_sts_5ee134bf_error1_sts_aad9583f_error2_sts_6cad4575_error3_sts_735bbeba__error1_sts_enable_938cafef_next_f460eb81_resetsignal_f7aac87a__in_t; + + typedef struct packed{ + logic hwset; + } sha512_acc_csr__error_intr_t_error0_sts_5ee134bf_error1_sts_aad9583f_error2_sts_6cad4575_error3_sts_735bbeba__error2_sts_enable_0dacf7a6_next_4b5b9e74_resetsignal_f7aac87a__in_t; + + typedef struct packed{ + logic hwset; + } sha512_acc_csr__error_intr_t_error0_sts_5ee134bf_error1_sts_aad9583f_error2_sts_6cad4575_error3_sts_735bbeba__error3_sts_enable_fc3af94b_next_c3125d40_resetsignal_f7aac87a__in_t; + + typedef struct packed{ + sha512_acc_csr__error_intr_t_error0_sts_5ee134bf_error1_sts_aad9583f_error2_sts_6cad4575_error3_sts_735bbeba__error0_sts_enable_528ccada_next_b1018582_resetsignal_f7aac87a__in_t error0_sts; + sha512_acc_csr__error_intr_t_error0_sts_5ee134bf_error1_sts_aad9583f_error2_sts_6cad4575_error3_sts_735bbeba__error1_sts_enable_938cafef_next_f460eb81_resetsignal_f7aac87a__in_t error1_sts; + sha512_acc_csr__error_intr_t_error0_sts_5ee134bf_error1_sts_aad9583f_error2_sts_6cad4575_error3_sts_735bbeba__error2_sts_enable_0dacf7a6_next_4b5b9e74_resetsignal_f7aac87a__in_t error2_sts; + sha512_acc_csr__error_intr_t_error0_sts_5ee134bf_error1_sts_aad9583f_error2_sts_6cad4575_error3_sts_735bbeba__error3_sts_enable_fc3af94b_next_c3125d40_resetsignal_f7aac87a__in_t error3_sts; + } sha512_acc_csr__error_intr_t_error0_sts_5ee134bf_error1_sts_aad9583f_error2_sts_6cad4575_error3_sts_735bbeba__in_t; + + typedef struct packed{ + logic hwset; + } sha512_acc_csr__notif_intr_t_notif_cmd_done_sts_1c68637e__notif_cmd_done_sts_enable_dabe0b8b_next_540fa3b7__in_t; + + typedef struct packed{ + sha512_acc_csr__notif_intr_t_notif_cmd_done_sts_1c68637e__notif_cmd_done_sts_enable_dabe0b8b_next_540fa3b7__in_t notif_cmd_done_sts; + } sha512_acc_csr__notif_intr_t_notif_cmd_done_sts_1c68637e__in_t; + + typedef struct packed{ + sha512_acc_csr__error_intr_t_error0_sts_5ee134bf_error1_sts_aad9583f_error2_sts_6cad4575_error3_sts_735bbeba__in_t error_internal_intr_r; + sha512_acc_csr__notif_intr_t_notif_cmd_done_sts_1c68637e__in_t notif_internal_intr_r; + } sha512_acc_csr__intr_block_t__in_t; + + typedef struct packed{ + logic lock_set; + logic valid_user; + logic soc_req; + logic cptra_rst_b; + logic cptra_pwrgood; + sha512_acc_csr__USER__in_t USER; + sha512_acc_csr__EXECUTE__in_t EXECUTE; + sha512_acc_csr__STATUS__in_t STATUS; + sha512_acc_csr__DIGEST__in_t [16-1:0]DIGEST; + sha512_acc_csr__intr_block_t__in_t intr_block_rf; + } sha512_acc_csr__in_t; + + typedef struct packed{ + logic value; + logic swmod; + } sha512_acc_csr__LOCK__LOCK__out_t; + + typedef struct packed{ + sha512_acc_csr__LOCK__LOCK__out_t LOCK; + } sha512_acc_csr__LOCK__out_t; + + typedef struct packed{ + logic [31:0] value; + } sha512_acc_csr__USER__USER__out_t; + + typedef struct packed{ + sha512_acc_csr__USER__USER__out_t USER; + } sha512_acc_csr__USER__out_t; + + typedef struct packed{ + logic [1:0] value; + logic swmod; + } sha512_acc_csr__MODE__MODE__out_t; + + typedef struct packed{ + logic value; + } sha512_acc_csr__MODE__ENDIAN_TOGGLE__out_t; + + typedef struct packed{ + sha512_acc_csr__MODE__MODE__out_t MODE; + sha512_acc_csr__MODE__ENDIAN_TOGGLE__out_t ENDIAN_TOGGLE; + } sha512_acc_csr__MODE__out_t; + + typedef struct packed{ + logic [31:0] value; + } sha512_acc_csr__START_ADDRESS__ADDR__out_t; + + typedef struct packed{ + sha512_acc_csr__START_ADDRESS__ADDR__out_t ADDR; + } sha512_acc_csr__START_ADDRESS__out_t; + + typedef struct packed{ + logic [31:0] value; + } sha512_acc_csr__DLEN__LENGTH__out_t; + + typedef struct packed{ + sha512_acc_csr__DLEN__LENGTH__out_t LENGTH; + } sha512_acc_csr__DLEN__out_t; + + typedef struct packed{ + logic swmod; + } sha512_acc_csr__DATAIN__DATAIN__out_t; + + typedef struct packed{ + sha512_acc_csr__DATAIN__DATAIN__out_t DATAIN; + } sha512_acc_csr__DATAIN__out_t; + + typedef struct packed{ + logic value; + } sha512_acc_csr__EXECUTE__EXECUTE__out_t; + + typedef struct packed{ + sha512_acc_csr__EXECUTE__EXECUTE__out_t EXECUTE; + } sha512_acc_csr__EXECUTE__out_t; + + typedef struct packed{ + logic value; + } sha512_acc_csr__STATUS__VALID__out_t; + + typedef struct packed{ + logic value; + } sha512_acc_csr__STATUS__SOC_HAS_LOCK__out_t; + + typedef struct packed{ + sha512_acc_csr__STATUS__VALID__out_t VALID; + sha512_acc_csr__STATUS__SOC_HAS_LOCK__out_t SOC_HAS_LOCK; + } sha512_acc_csr__STATUS__out_t; + + typedef struct packed{ + logic value; + } sha512_acc_csr__CONTROL__ZEROIZE__out_t; + + typedef struct packed{ + sha512_acc_csr__CONTROL__ZEROIZE__out_t ZEROIZE; + } sha512_acc_csr__CONTROL__out_t; + + typedef struct packed{ + logic intr; + } sha512_acc_csr__global_intr_t_agg_sts_dd3dcf0a__out_t; + + typedef struct packed{ + logic intr; + } sha512_acc_csr__global_intr_t_agg_sts_e6399b4a__out_t; + + typedef struct packed{ + logic intr; + } sha512_acc_csr__error_intr_t_error0_sts_5ee134bf_error1_sts_aad9583f_error2_sts_6cad4575_error3_sts_735bbeba__out_t; + + typedef struct packed{ + logic intr; + } sha512_acc_csr__notif_intr_t_notif_cmd_done_sts_1c68637e__out_t; + + typedef struct packed{ + sha512_acc_csr__global_intr_t_agg_sts_dd3dcf0a__out_t error_global_intr_r; + sha512_acc_csr__global_intr_t_agg_sts_e6399b4a__out_t notif_global_intr_r; + sha512_acc_csr__error_intr_t_error0_sts_5ee134bf_error1_sts_aad9583f_error2_sts_6cad4575_error3_sts_735bbeba__out_t error_internal_intr_r; + sha512_acc_csr__notif_intr_t_notif_cmd_done_sts_1c68637e__out_t notif_internal_intr_r; + } sha512_acc_csr__intr_block_t__out_t; + + typedef struct packed{ + sha512_acc_csr__LOCK__out_t LOCK; + sha512_acc_csr__USER__out_t USER; + sha512_acc_csr__MODE__out_t MODE; + sha512_acc_csr__START_ADDRESS__out_t START_ADDRESS; + sha512_acc_csr__DLEN__out_t DLEN; + sha512_acc_csr__DATAIN__out_t DATAIN; + sha512_acc_csr__EXECUTE__out_t EXECUTE; + sha512_acc_csr__STATUS__out_t STATUS; + sha512_acc_csr__CONTROL__out_t CONTROL; + sha512_acc_csr__intr_block_t__out_t intr_block_rf; + } sha512_acc_csr__out_t; + + typedef enum logic [31:0] { + sha512_acc_csr__MODE__MODE__sha_cmd_e__SHA_STREAM_384 = 'h0, + sha512_acc_csr__MODE__MODE__sha_cmd_e__SHA_STREAM_512 = 'h1, + sha512_acc_csr__MODE__MODE__sha_cmd_e__SHA_MBOX_384 = 'h2, + sha512_acc_csr__MODE__MODE__sha_cmd_e__SHA_MBOX_512 = 'h3 + } sha512_acc_csr__MODE__MODE__sha_cmd_e_e; + + localparam SHA512_ACC_CSR_ADDR_WIDTH = 32'd12; + +endpackage \ No newline at end of file diff --git a/designs/Caliptra/src/caliptra-rtl/sha512_acc_top.sv b/designs/Caliptra/src/caliptra-rtl/sha512_acc_top.sv new file mode 100644 index 0000000..333ff77 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/sha512_acc_top.sv @@ -0,0 +1,451 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. + +module sha512_acc_top + import soc_ifc_pkg::*; + import mbox_pkg::*; + import sha512_acc_csr_pkg::*; + import sha512_params_pkg::*; + #( + parameter DATA_WIDTH = 32 + )( + // Clock and reset. + input logic clk, + input logic rst_b, + input logic cptra_pwrgood, + + // Incoming request from ahb or axi + input logic req_dv, + output logic req_hold, + input soc_ifc_req_t req_data, + output logic [DATA_WIDTH-1:0] rdata, + output logic err, + + // Direct access to mailbox + output logic sha_sram_req_dv, + output logic [CPTRA_MBOX_ADDR_W-1:0] sha_sram_req_addr, + input cptra_mbox_sram_resp_t sha_sram_resp, + input logic sha_sram_hold, + + // Interrupts + output logic error_intr, + output logic notif_intr + ); + + //---------------------------------------------------------------- + // Internal constant and parameter definitions. + //---------------------------------------------------------------- + localparam DATA_NUM_BYTES = DATA_WIDTH / 8; + localparam BLOCK_NO = 1024 / DATA_WIDTH; + localparam BYTE_NO = 1024 / 8; + localparam BLOCK_OFFSET_W = $clog2(BLOCK_NO); + localparam BYTE_OFFSET_W = $clog2(1024/8); + + logic lock_set; + logic datain_write; + logic stall_write; + logic execute_set; + + logic init_reg; + logic next_reg; + logic soc_has_lock; + logic [1:0] mode; + logic [1:0] sha_mode; + logic streaming_mode; + logic mailbox_mode; + + logic [BYTE_OFFSET_W-1:0] num_bytes_data; + logic extra_pad_block_required; + + //extra bit for roll over on full read + logic [CPTRA_MBOX_ADDR_W:0] mbox_rdptr; + logic [CPTRA_MBOX_ADDR_W-1:0] mbox_start_addr, mbox_end_addr; + logic mbox_read_to_end; + logic mbox_read_en; + logic mbox_read_done; + logic mbox_block_we; + + sha_fsm_state_e sha_fsm_ps, sha_fsm_ns; + + logic arc_SHA_IDLE_SHA_BLOCK_0; + logic arc_SHA_BLOCK_0_SHA_BLOCK_N; + logic arc_SHA_BLOCK_0_SHA_PAD0; + logic arc_SHA_BLOCK_N_SHA_BLOCK_N; + logic arc_SHA_BLOCK_N_SHA_PAD0; + logic arc_SHA_PAD0_SHA_PAD1; + logic arc_SHA_PAD0_SHA_DONE; + logic arc_SHA_PAD1_SHA_DONE; + logic arc_IDLE; + + logic mbox_mode_block_we; + logic stream_mode_block_we; + logic block_we; + logic mbox_mode_last_dword_wr; + logic block_full; + logic [31:0] num_bytes_wr; + logic [BLOCK_OFFSET_W:0] block_wptr; + logic [DATA_NUM_BYTES-1:0][7:0] mbox_rdata; + logic [DATA_NUM_BYTES-1:0][7:0] streaming_wdata; + logic [DATA_NUM_BYTES-1:0][7:0] input_data; + logic [DATA_NUM_BYTES-1:0][7:0] swizzled_data; + logic [DATA_WIDTH-1:0] block_wdata; + logic [0:BLOCK_NO-1][DATA_WIDTH-1:0] block_reg,block_reg_nxt; + logic [0:BYTE_NO-1][7:0] block_reg_nxt_pad; + logic [1023:0] pad_mask; + logic [127:0] pad_length; + + //output comes in big endian + logic [0:15][31:0] digest_reg; + logic digest_valid_reg; + + sha512_acc_csr__in_t hwif_in; + sha512_acc_csr__out_t hwif_out; + + logic read_error, write_error; + logic [DATA_WIDTH-1:0] reg_biten; + + logic core_ready; + logic core_ready_q; + logic [15:0][31:0] core_digest; + logic core_digest_valid; + logic core_digest_valid_q; + + logic zeroize_pulse; + + assign req_hold = stall_write; + + assign err = read_error | write_error; + + assign zeroize_pulse = hwif_out.CONTROL.ZEROIZE.value; + + //---------------------------------------------------------------- + // core instantiation. + //---------------------------------------------------------------- + sha512_core core( + .clk(clk), + .reset_n(rst_b), + .zeroize(zeroize_pulse), + + .init_cmd(init_reg), + .next_cmd(next_reg), + .restore_cmd(1'b0), + .mode(sha_mode), + + .block_msg(block_reg), + .restore_digest('0), + + .ready(core_ready), + + .digest(core_digest), + .digest_valid(core_digest_valid) + ); + +always_comb core_ready_q = core_ready & ~(init_reg | next_reg); +always_comb core_digest_valid_q = core_digest_valid & ~(init_reg | next_reg); +//registers for sha core controls + always_ff @(posedge clk or negedge rst_b) begin : sha_regs + if (!rst_b) begin + digest_reg <= '0; + digest_valid_reg <= '0; + init_reg <= '0; + next_reg <= '0; + end + else begin + init_reg <= arc_SHA_BLOCK_0_SHA_BLOCK_N | arc_SHA_BLOCK_0_SHA_PAD0; + next_reg <= arc_SHA_BLOCK_N_SHA_BLOCK_N | arc_SHA_BLOCK_N_SHA_PAD0 | arc_SHA_PAD0_SHA_PAD1; + digest_valid_reg <= core_digest_valid; + if (core_digest_valid & ~digest_valid_reg) + digest_reg <= core_digest; + end + end // reg_update + + //SHA API + //Acquire the lock and store the user + always_comb hwif_in.USER.USER.next = 32'(req_data.user); + //Detect the lock getting set when swmod is asserted and lock is 0 and it's not a write + //Since this lock is cleared by writing, the swmod asserts on write attempts too, but we only want to set lock on read when value is 0 + always_comb lock_set = ~hwif_out.LOCK.LOCK.value & hwif_out.LOCK.LOCK.swmod & ~req_data.write; + always_comb hwif_in.lock_set = lock_set; + + //check the requesting user: + //don't update SHA registers if lock hasn't been acquired + //if uc has the lock, check that this request is from uc + //if soc has the lock, check that this request is from soc and user attributes match + always_comb hwif_in.valid_user = hwif_out.LOCK.LOCK.value & ((~soc_has_lock & ~req_data.soc_req) | + (soc_has_lock & req_data.soc_req & (req_data.user == hwif_out.USER.USER.value[SOC_IFC_USER_W-1:0]))); + always_comb hwif_in.soc_req = req_data.soc_req; + always_comb hwif_in.STATUS.SOC_HAS_LOCK.next = soc_has_lock; + + always_comb mode = hwif_out.MODE.MODE.value; + //mode encoding bit 0 determines 512 or 384. + always_comb sha_mode = mode[0] ? MODE_SHA_512 : MODE_SHA_384; + //determine streaming or mailbox mode - SoC is limited to streaming mode only + always_comb streaming_mode = ~mode[1] | soc_has_lock; + always_comb mailbox_mode = mode[1] & ~soc_has_lock; + //Detect writes to datain register + always_comb datain_write = hwif_in.valid_user & hwif_out.DATAIN.DATAIN.swmod; + always_comb execute_set = hwif_out.EXECUTE.EXECUTE.value; + + //When we reach the end of a block we indicate block full + //If this is also the end of the entire DLEN, mask block full so that we properly pad the last dword + //We don't want to mask this if num bytes wr is == dlen. This means we wrote a full dword and no padding goes here + always_comb block_full = block_wptr[BLOCK_OFFSET_W] & ~(num_bytes_wr > hwif_out.DLEN.LENGTH.value); + always_comb mbox_mode_last_dword_wr = mbox_mode_block_we & (block_wptr == (BLOCK_NO-1)); + + //read from mbox is one clock ahead of writes + //stall reads based on hold signal from mbox (which is asserted during ECC write-back) + //don't read the next dword if we are writing the last dword of a block and core isn't ready + //keep stalling the read once the block is full until core is ready - this will reset the block pointer and start the next one + always_comb mbox_read_en = mailbox_mode & ~mbox_read_done & !sha_sram_hold & ~(mbox_mode_last_dword_wr | block_full); + + always_comb sha_sram_req_dv = mbox_read_en; + always_comb sha_sram_req_addr = mbox_rdptr[CPTRA_MBOX_ADDR_W-1:0]; + + //stall the write if we are trying to stream datain and it's the end of a block but the core isn't ready + always_comb stall_write = datain_write & block_full; + + always_comb mbox_mode_block_we = (mailbox_mode & mbox_block_we); + always_comb stream_mode_block_we = (streaming_mode & datain_write & ~stall_write); + + always_comb block_we = mbox_mode_block_we | stream_mode_block_we; + + genvar b; + generate + for (b=0; b= 112 bytes of data in the block we can't fit the length + assign extra_pad_block_required = (num_bytes_data >= 'd112); + + always_comb begin : sha_padding_logic + pad_mask = '1; + //set the valid bytes to '1 to keep the valid data and zero out the rest + pad_mask = pad_mask << (1024-(num_bytes_data*8)); + //we append the length in bits to the least significant 128 bits + pad_length = {{($bits(pad_length)-32){1'b0}}, hwif_out.DLEN.LENGTH.value} << 3; + + //First case - Padding and length fit - just pad and add the length in this block + //This might be an empty padded block with just length if dlen is divisible by 1024 + if (~extra_pad_block_required & (arc_SHA_BLOCK_0_SHA_PAD0 | arc_SHA_BLOCK_N_SHA_PAD0)) begin + block_reg_nxt_pad = block_reg & pad_mask; + //force the pad bit on the MSB of the first byte of padding + block_reg_nxt_pad[num_bytes_data] = 8'h80; + //write the length in bits into the highest 128 bits + //only if this is a case where dlen is divisible by 1024 + block_reg_nxt_pad[112:127] = pad_length; + end + //Second case - length won't fit, we need to first send valid data + pad followed by zeroes and length + else if (extra_pad_block_required & (arc_SHA_BLOCK_0_SHA_PAD0 | arc_SHA_BLOCK_N_SHA_PAD0)) begin + block_reg_nxt_pad = block_reg & pad_mask; + //force the pad bit on the MSB of the first byte of padding + block_reg_nxt_pad[num_bytes_data] = 8'h80; + end + //This is sending the zeroes and length since we started the padding in the previous block + else if (arc_SHA_PAD0_SHA_PAD1) begin + block_reg_nxt_pad = '0; + //write the length in bits into the highest 128 bits + block_reg_nxt_pad[112:127] = pad_length; + end + //Default case is to just send the block as-is + else begin + block_reg_nxt_pad = block_reg; + end + block_reg_nxt = block_reg_nxt_pad; + end + + //byte address aligning to mailbox read pointer + always_comb mbox_start_addr = hwif_out.START_ADDRESS.ADDR.value[CPTRA_MBOX_ADDR_W+1:2]; + + //Convert DLEN to an end address. DLEN is in bytes, address is in dwords + //detect overflow of end address to indicate we want to read to the end of the mailbox + always_comb {mbox_read_to_end, mbox_end_addr} = mbox_start_addr + + hwif_out.DLEN.LENGTH.value[CPTRA_MBOX_ADDR_W+2:2] + + (hwif_out.DLEN.LENGTH.value[1] | hwif_out.DLEN.LENGTH.value[0]); + + always_comb mbox_read_done = (sha_fsm_ps == SHA_IDLE) | ~mailbox_mode | + //If the DLEN overflowed our end address, just read to the end of the mailbox and stop + //Otherwise read until read pointer == end address + (~mbox_read_to_end & mbox_rdptr[CPTRA_MBOX_ADDR_W-1:0] == mbox_end_addr) | + (mbox_read_to_end & mbox_rdptr[CPTRA_MBOX_ADDR_W]); + + //HW API State Machine + //whenever lock is cleared, go back to idle + always_comb arc_IDLE = ~hwif_out.LOCK.LOCK.value; + //Streaming mode - go to block 0 when first datain comes + //Mailbox mode - go to block 0 when execute is set + always_comb arc_SHA_IDLE_SHA_BLOCK_0 = (sha_fsm_ps == SHA_IDLE) & ( + (streaming_mode & datain_write) | + (mailbox_mode & execute_set)); + //When a full block is complete, send INIT and move to BLOCK_N state + always_comb arc_SHA_BLOCK_0_SHA_BLOCK_N = (sha_fsm_ps == SHA_BLOCK_0) & block_full & core_ready_q; + always_comb arc_SHA_BLOCK_N_SHA_BLOCK_N = (sha_fsm_ps == SHA_BLOCK_N) & block_full & core_ready_q; + //When execute is set for streaming, OR we reach the end of the mailbox region, move to PAD0 + //If a block ends on 1024 bit boundary, we can't move to PAD until that block is processed + //so we give priority to the end of block arcs, and move to PAD only after core is ready for the pad block + always_comb arc_SHA_BLOCK_0_SHA_PAD0 = (sha_fsm_ps == SHA_BLOCK_0) & ~arc_SHA_BLOCK_0_SHA_BLOCK_N & + (streaming_mode & (execute_set & core_ready_q) | + mailbox_mode & (mbox_read_done & ~block_we & core_ready_q)); + always_comb arc_SHA_BLOCK_N_SHA_PAD0 = (sha_fsm_ps == SHA_BLOCK_N) & ~arc_SHA_BLOCK_N_SHA_BLOCK_N & + (streaming_mode & (execute_set & core_ready_q) | + mailbox_mode & (mbox_read_done & ~block_we & core_ready_q)); + //Moving to PAD0 fills in the padding for the current block and sends NEXT command + //If we can't fit the length into the current block we'll need another block to pad and write the length in + //So go to PAD1 after PAD0 in this case + always_comb arc_SHA_PAD0_SHA_PAD1 = (sha_fsm_ps == SHA_PAD0) & extra_pad_block_required & core_ready_q; + //Move to done state as soon as SHA is done with the final padded block + always_comb arc_SHA_PAD0_SHA_DONE = (sha_fsm_ps == SHA_PAD0) & ~extra_pad_block_required & core_digest_valid_q; + always_comb arc_SHA_PAD1_SHA_DONE = (sha_fsm_ps == SHA_PAD1) & core_digest_valid_q; + + //SHA API FSM State Combo + always_comb begin : sha_api_combo + //default back to present state + sha_fsm_ns = sha_fsm_ps; + + unique case (sha_fsm_ps) inside + SHA_IDLE: begin + if (arc_SHA_IDLE_SHA_BLOCK_0) sha_fsm_ns = SHA_BLOCK_0; + end + SHA_BLOCK_0: begin + if (arc_IDLE) sha_fsm_ns = SHA_IDLE; + else if (arc_SHA_BLOCK_0_SHA_BLOCK_N) sha_fsm_ns = SHA_BLOCK_N; + else if (arc_SHA_BLOCK_0_SHA_PAD0) sha_fsm_ns = SHA_PAD0; + end + SHA_BLOCK_N: begin + if (arc_IDLE) sha_fsm_ns = SHA_IDLE; + else if (arc_SHA_BLOCK_N_SHA_BLOCK_N) sha_fsm_ns = SHA_BLOCK_N; + else if (arc_SHA_BLOCK_N_SHA_PAD0) sha_fsm_ns = SHA_PAD0; + end + SHA_PAD0: begin + if (arc_IDLE) sha_fsm_ns = SHA_IDLE; + else if (arc_SHA_PAD0_SHA_PAD1) sha_fsm_ns = SHA_PAD1; + else if (arc_SHA_PAD0_SHA_DONE) sha_fsm_ns = SHA_DONE; + end + SHA_PAD1: begin + if (arc_IDLE) sha_fsm_ns = SHA_IDLE; + else if (arc_SHA_PAD1_SHA_DONE) sha_fsm_ns = SHA_DONE; + end + SHA_DONE: begin + if (arc_IDLE) sha_fsm_ns = SHA_IDLE; + end + default: begin + //TODO Error condition + sha_fsm_ns = SHA_IDLE; + end + endcase + end + +//register hw interface +always_comb begin + hwif_in.STATUS.VALID.next = (sha_fsm_ps == SHA_DONE); + hwif_in.EXECUTE.EXECUTE.hwclr = arc_IDLE; + for (int dword =0; dword < 16; dword++) begin + hwif_in.DIGEST[dword].DIGEST.next = digest_reg[dword]; + hwif_in.DIGEST[dword].DIGEST.hwclr = zeroize_pulse; + end +end + +genvar i; +generate + for (i=0;i 1, 2 => 0, 0);} + + init_ready_cp: cross ready, init; //TB + next_ready_cp: cross ready, next; //TB + zeroize_ready_cp: cross ready, zeroize; + mode_ready_cp: cross ready, mode; + pcr_ready_cp: cross ready, gen_hash_start; //TB + pcr_init_cp: cross gen_hash_ip_cp, init; + pcr_next_cp: cross gen_hash_ip_cp, next; + zeroize_pcr_cp: cross zeroize, gen_hash_ip_cp; + zeroize_init_cp: cross zeroize, init; //TB + zeroize_next_cp: cross zeroize, next; //TB + zeroize_restore_cp: cross zeroize, restore; + + endgroup + + sha512_ctrl_cov_grp sha512_ctrl_cov_grp1 = new(); + +endinterface + +`endif \ No newline at end of file diff --git a/designs/Caliptra/src/caliptra-rtl/sha512_h_constants.v b/designs/Caliptra/src/caliptra-rtl/sha512_h_constants.v new file mode 100644 index 0000000..bd0046e --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/sha512_h_constants.v @@ -0,0 +1,156 @@ +//====================================================================== +// +// sha512_h_constants.v +// --------------------- +// The H initial constants for the different modes in SHA-512. +// +// +// Author: Joachim Strombergson +// Copyright (c) 2014 Secworks Sweden AB +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or +// without modification, are permitted provided that the following +// conditions are met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in +// the documentation and/or other materials provided with the +// distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +//====================================================================== + +module sha512_h_constants( + input wire [1 : 0] mode, + + output wire [63 : 0] H0, + output wire [63 : 0] H1, + output wire [63 : 0] H2, + output wire [63 : 0] H3, + output wire [63 : 0] H4, + output wire [63 : 0] H5, + output wire [63 : 0] H6, + output wire [63 : 0] H7 + ); + + //---------------------------------------------------------------- + // Wires. + //---------------------------------------------------------------- + reg [63 : 0] tmp_H0; + reg [63 : 0] tmp_H1; + reg [63 : 0] tmp_H2; + reg [63 : 0] tmp_H3; + reg [63 : 0] tmp_H4; + reg [63 : 0] tmp_H5; + reg [63 : 0] tmp_H6; + reg [63 : 0] tmp_H7; + + + //---------------------------------------------------------------- + // Concurrent connectivity for ports etc. + //---------------------------------------------------------------- + assign H0 = tmp_H0; + assign H1 = tmp_H1; + assign H2 = tmp_H2; + assign H3 = tmp_H3; + assign H4 = tmp_H4; + assign H5 = tmp_H5; + assign H6 = tmp_H6; + assign H7 = tmp_H7; + + + //---------------------------------------------------------------- + // mode_mux + // + // Based on the given mode, the correct H constants are selected. + //---------------------------------------------------------------- + always @* + begin : mode_mux + unique case (mode) + 0: + begin + // SHA-512/224 + tmp_H0 = 64'h8c3d37c819544da2; + tmp_H1 = 64'h73e1996689dcd4d6; + tmp_H2 = 64'h1dfab7ae32ff9c82; + tmp_H3 = 64'h679dd514582f9fcf; + tmp_H4 = 64'h0f6d2b697bd44da8; + tmp_H5 = 64'h77e36f7304c48942; + tmp_H6 = 64'h3f9d85a86a1d36c8; + tmp_H7 = 64'h1112e6ad91d692a1; + end + + 1: + begin + // SHA-512/256 + tmp_H0 = 64'h22312194fc2bf72c; + tmp_H1 = 64'h9f555fa3c84c64c2; + tmp_H2 = 64'h2393b86b6f53b151; + tmp_H3 = 64'h963877195940eabd; + tmp_H4 = 64'h96283ee2a88effe3; + tmp_H5 = 64'hbe5e1e2553863992; + tmp_H6 = 64'h2b0199fc2c85b8aa; + tmp_H7 = 64'h0eb72ddc81c52ca2; + end + + 2: + begin + // SHA-384 + tmp_H0 = 64'hcbbb9d5dc1059ed8; + tmp_H1 = 64'h629a292a367cd507; + tmp_H2 = 64'h9159015a3070dd17; + tmp_H3 = 64'h152fecd8f70e5939; + tmp_H4 = 64'h67332667ffc00b31; + tmp_H5 = 64'h8eb44a8768581511; + tmp_H6 = 64'hdb0c2e0d64f98fa7; + tmp_H7 = 64'h47b5481dbefa4fa4; + end + + 3: + begin + // SHA-512 + tmp_H0 = 64'h6a09e667f3bcc908; + tmp_H1 = 64'hbb67ae8584caa73b; + tmp_H2 = 64'h3c6ef372fe94f82b; + tmp_H3 = 64'ha54ff53a5f1d36f1; + tmp_H4 = 64'h510e527fade682d1; + tmp_H5 = 64'h9b05688c2b3e6c1f; + tmp_H6 = 64'h1f83d9abfb41bd6b; + tmp_H7 = 64'h5be0cd19137e2179; + end + + default: + begin + // SHA-384 + tmp_H0 = 64'hcbbb9d5dc1059ed8; + tmp_H1 = 64'h629a292a367cd507; + tmp_H2 = 64'h9159015a3070dd17; + tmp_H3 = 64'h152fecd8f70e5939; + tmp_H4 = 64'h67332667ffc00b31; + tmp_H5 = 64'h8eb44a8768581511; + tmp_H6 = 64'hdb0c2e0d64f98fa7; + tmp_H7 = 64'h47b5481dbefa4fa4; + end + endcase // case (addr) + end // block: mode_mux +endmodule // sha512_h_constants + +//====================================================================== +// sha512_h_constants.v +//====================================================================== diff --git a/designs/Caliptra/src/caliptra-rtl/sha512_k_constants.v b/designs/Caliptra/src/caliptra-rtl/sha512_k_constants.v new file mode 100644 index 0000000..4270a71 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/sha512_k_constants.v @@ -0,0 +1,151 @@ +//====================================================================== +// +// sha512_k_constants.v +// -------------------- +// The table K with constants in the SHA-512 hash function. +// +// +// Author: Joachim Strombergson +// Copyright (c) 2014 Secworks Sweden AB +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or +// without modification, are permitted provided that the following +// conditions are met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in +// the documentation and/or other materials provided with the +// distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +//====================================================================== + +module sha512_k_constants( + input wire [6 : 0] addr, + output wire [63 : 0] K_val + ); + + //---------------------------------------------------------------- + // Wires. + //---------------------------------------------------------------- + reg [63 : 0] tmp_K; + + + //---------------------------------------------------------------- + // Concurrent connectivity for ports etc. + //---------------------------------------------------------------- + assign K_val = tmp_K; + + + //---------------------------------------------------------------- + // addr_mux + //---------------------------------------------------------------- + always @* + begin : addr_mux + unique case(addr) + 0: tmp_K = 64'h428a2f98d728ae22; + 1: tmp_K = 64'h7137449123ef65cd; + 2: tmp_K = 64'hb5c0fbcfec4d3b2f; + 3: tmp_K = 64'he9b5dba58189dbbc; + 4: tmp_K = 64'h3956c25bf348b538; + 5: tmp_K = 64'h59f111f1b605d019; + 6: tmp_K = 64'h923f82a4af194f9b; + 7: tmp_K = 64'hab1c5ed5da6d8118; + 8: tmp_K = 64'hd807aa98a3030242; + 9: tmp_K = 64'h12835b0145706fbe; + 10: tmp_K = 64'h243185be4ee4b28c; + 11: tmp_K = 64'h550c7dc3d5ffb4e2; + 12: tmp_K = 64'h72be5d74f27b896f; + 13: tmp_K = 64'h80deb1fe3b1696b1; + 14: tmp_K = 64'h9bdc06a725c71235; + 15: tmp_K = 64'hc19bf174cf692694; + 16: tmp_K = 64'he49b69c19ef14ad2; + 17: tmp_K = 64'hefbe4786384f25e3; + 18: tmp_K = 64'h0fc19dc68b8cd5b5; + 19: tmp_K = 64'h240ca1cc77ac9c65; + 20: tmp_K = 64'h2de92c6f592b0275; + 21: tmp_K = 64'h4a7484aa6ea6e483; + 22: tmp_K = 64'h5cb0a9dcbd41fbd4; + 23: tmp_K = 64'h76f988da831153b5; + 24: tmp_K = 64'h983e5152ee66dfab; + 25: tmp_K = 64'ha831c66d2db43210; + 26: tmp_K = 64'hb00327c898fb213f; + 27: tmp_K = 64'hbf597fc7beef0ee4; + 28: tmp_K = 64'hc6e00bf33da88fc2; + 29: tmp_K = 64'hd5a79147930aa725; + 30: tmp_K = 64'h06ca6351e003826f; + 31: tmp_K = 64'h142929670a0e6e70; + 32: tmp_K = 64'h27b70a8546d22ffc; + 33: tmp_K = 64'h2e1b21385c26c926; + 34: tmp_K = 64'h4d2c6dfc5ac42aed; + 35: tmp_K = 64'h53380d139d95b3df; + 36: tmp_K = 64'h650a73548baf63de; + 37: tmp_K = 64'h766a0abb3c77b2a8; + 38: tmp_K = 64'h81c2c92e47edaee6; + 39: tmp_K = 64'h92722c851482353b; + 40: tmp_K = 64'ha2bfe8a14cf10364; + 41: tmp_K = 64'ha81a664bbc423001; + 42: tmp_K = 64'hc24b8b70d0f89791; + 43: tmp_K = 64'hc76c51a30654be30; + 44: tmp_K = 64'hd192e819d6ef5218; + 45: tmp_K = 64'hd69906245565a910; + 46: tmp_K = 64'hf40e35855771202a; + 47: tmp_K = 64'h106aa07032bbd1b8; + 48: tmp_K = 64'h19a4c116b8d2d0c8; + 49: tmp_K = 64'h1e376c085141ab53; + 50: tmp_K = 64'h2748774cdf8eeb99; + 51: tmp_K = 64'h34b0bcb5e19b48a8; + 52: tmp_K = 64'h391c0cb3c5c95a63; + 53: tmp_K = 64'h4ed8aa4ae3418acb; + 54: tmp_K = 64'h5b9cca4f7763e373; + 55: tmp_K = 64'h682e6ff3d6b2b8a3; + 56: tmp_K = 64'h748f82ee5defb2fc; + 57: tmp_K = 64'h78a5636f43172f60; + 58: tmp_K = 64'h84c87814a1f0ab72; + 59: tmp_K = 64'h8cc702081a6439ec; + 60: tmp_K = 64'h90befffa23631e28; + 61: tmp_K = 64'ha4506cebde82bde9; + 62: tmp_K = 64'hbef9a3f7b2c67915; + 63: tmp_K = 64'hc67178f2e372532b; + 64: tmp_K = 64'hca273eceea26619c; + 65: tmp_K = 64'hd186b8c721c0c207; + 66: tmp_K = 64'heada7dd6cde0eb1e; + 67: tmp_K = 64'hf57d4f7fee6ed178; + 68: tmp_K = 64'h06f067aa72176fba; + 69: tmp_K = 64'h0a637dc5a2c898a6; + 70: tmp_K = 64'h113f9804bef90dae; + 71: tmp_K = 64'h1b710b35131c471b; + 72: tmp_K = 64'h28db77f523047d84; + 73: tmp_K = 64'h32caab7b40c72493; + 74: tmp_K = 64'h3c9ebe0a15c9bebc; + 75: tmp_K = 64'h431d67c49c100d4c; + 76: tmp_K = 64'h4cc5d4becb3e42b6; + 77: tmp_K = 64'h597f299cfc657e2a; + 78: tmp_K = 64'h5fcb6fab3ad6faec; + 79: tmp_K = 64'h6c44198c4a475817; + + default: + tmp_K = 64'h0; + endcase // case (addr) + end // block: addr_mux +endmodule // sha512_k_constants + +//====================================================================== +// sha512_k_constants.v +//====================================================================== diff --git a/designs/Caliptra/src/caliptra-rtl/sha512_masked_core.sv b/designs/Caliptra/src/caliptra-rtl/sha512_masked_core.sv new file mode 100644 index 0000000..81f3fda --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/sha512_masked_core.sv @@ -0,0 +1,736 @@ +//====================================================================== +// +// sha512_masked_core.sv +// ------------- +// Verilog 2001 implementation of the SHA-512 hash function. +// This is the internal core with wide interfaces. +// +// +// Author: Joachim Strombergson +// Copyright (c) 2014 Secworks Sweden AB +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or +// without modification, are permitted provided that the following +// conditions are met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in +// the documentation and/or other materials provided with the +// distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +//====================================================================== +// +// Module: +// sha512_masked_core.sv +// +// The embedded countermeasures for SHA512 is based on +// "Differential Power Analysis of HMAC Based on SHA-2, and Countermeasures" +// by McEvoy et. al. +// +// The countermeasures are added into the unmasked SHA512 implementation +// from Secworks. +// +// For providing the required random values to mask intermediate values, +// we use a lightweight LFSR. Based on +// "Spin Me Right Round Rotational Symmetry for FPGA-specific AES" by +// Wegener et. al., LFSR is sufficient for masking statistical randomness. +//====================================================================== + + +module sha512_masked_core + import sha512_masked_defines_pkg::*; + ( + // Clock and reset. + input wire clk, + input wire reset_n, + input wire zeroize, + // Control. + input wire init_cmd, + input wire next_cmd, + input wire [1 : 0] mode, + + // Data port. + input wire [191 : 0] entropy, + + + input wire [1023 : 0] block_msg, + + output wire ready, + output wire [511 : 0] digest, + output wire digest_valid + ); + + + //---------------------------------------------------------------- + // Internal constant and parameter definitions. + //---------------------------------------------------------------- + localparam SHA512_ROUNDS = 79; + localparam SHA512_RNDs = 8; + + localparam CTRL_IDLE = 2'h0; + localparam CTRL_RND = 2'h1; + localparam CTRL_ROUNDS = 2'h2; + localparam CTRL_DONE = 2'h3; + + + //---------------------------------------------------------------- + // Registers including update variables and write enable. + //---------------------------------------------------------------- + logic masking_init; + logic masking_update; + logic [23:0][63:0] masking_rnd; + logic [7:0][63:0] rh_masking_rnd; + logic [1023:0] rw_masking_rnd; + logic [9:0] q_masking_rnd; + + logic init_reg_set; + logic init_reg_reset; + logic init_reg; + + masked_reg_t a_reg; + masked_reg_t a_new; + masked_reg_t b_reg; + masked_reg_t b_new; + masked_reg_t c_reg; + masked_reg_t c_new; + masked_reg_t d_reg; + masked_reg_t d_new; + masked_reg_t e_reg; + masked_reg_t e_new; + masked_reg_t f_reg; + masked_reg_t f_new; + masked_reg_t g_reg; + masked_reg_t g_new; + masked_reg_t h_reg; + masked_reg_t h_new; + reg a_h_we; + + reg [63 : 0] H0_reg; + reg [63 : 0] H0_new; + reg [63 : 0] H1_reg; + reg [63 : 0] H1_new; + reg [63 : 0] H2_reg; + reg [63 : 0] H2_new; + reg [63 : 0] H3_reg; + reg [63 : 0] H3_new; + reg [63 : 0] H4_reg; + reg [63 : 0] H4_new; + reg [63 : 0] H5_reg; + reg [63 : 0] H5_new; + reg [63 : 0] H6_reg; + reg [63 : 0] H6_new; + reg [63 : 0] H7_reg; + reg [63 : 0] H7_new; + reg H_we; + + reg [6 : 0] round_ctr_reg; + reg [6 : 0] round_ctr_new; + reg round_ctr_we; + reg round_ctr_inc; + reg round_ctr_rst; + + reg ready_reg; + reg ready_new; + reg ready_we; + + reg digest_valid_reg; + reg digest_valid_new; + reg digest_valid_we; + + reg [1 : 0] sha512_ctrl_reg; + reg [1 : 0] sha512_ctrl_new; + reg sha512_ctrl_we; + + reg [6 : 0] rnd_ctr_reg; + reg [6 : 0] rnd_ctr_new; + reg rnd_ctr_we; + reg rnd_ctr_inc; + reg rnd_ctr_rst; + //---------------------------------------------------------------- + // Wires. + //---------------------------------------------------------------- + reg digest_init; + reg digest_update; + + reg state_init; + reg state_update; + + reg first_block; + + masked_reg_t t1_b2a; + masked_reg_t t2_b2a; + masked_reg_t a_new_a2b; + masked_reg_t e_new_a2b; + + wire [63 : 0] k_data; + + reg w_init; + reg w_next; + masked_reg_t w_data; + + wire [63 : 0] H0_0; + wire [63 : 0] H0_1; + wire [63 : 0] H0_2; + wire [63 : 0] H0_3; + wire [63 : 0] H0_4; + wire [63 : 0] H0_5; + wire [63 : 0] H0_6; + wire [63 : 0] H0_7; + + + //---------------------------------------------------------------- + // Module instantiantions. + //---------------------------------------------------------------- + sha512_k_constants k_constants_inst( + .addr(round_ctr_reg), + .K_val(k_data) + ); + + + sha512_h_constants h_constants_inst( + .mode(mode), + + .H0(H0_0), + .H1(H0_1), + .H2(H0_2), + .H3(H0_3), + .H4(H0_4), + .H5(H0_5), + .H6(H0_6), + .H7(H0_7) + ); + + + sha512_masked_w_mem w_mem_inst( + .clk(clk), + .reset_n(reset_n), + .zeroize(zeroize), + + .block_msg(block_msg), + .rw_masking_rnd(rw_masking_rnd), + .entropy(entropy[4 : 0]), + + .init_cmd(w_init), + .next_cmd(w_next), + .w_val(w_data) + ); + + //---------------------------------------------------------------- + // Concurrent connectivity for ports etc. + //---------------------------------------------------------------- + assign ready = ready_reg; + + assign digest = {H0_reg, H1_reg, H2_reg, H3_reg, + H4_reg, H5_reg, H6_reg, H7_reg}; + + assign digest_valid = digest_valid_reg; + + genvar i; + generate + for (i=0; i < 8; i++) begin : rh_masking_assign + assign rh_masking_rnd[i] = masking_rnd[i]; + end + endgenerate + + assign rw_masking_rnd = {masking_rnd[08], masking_rnd[09], masking_rnd[10], masking_rnd[11], + masking_rnd[12], masking_rnd[13], masking_rnd[14], masking_rnd[15], + masking_rnd[16], masking_rnd[17], masking_rnd[18], masking_rnd[19], + masking_rnd[20], masking_rnd[21], masking_rnd[22], masking_rnd[23]}; + //---------------------------------------------------------------- + // reg_update + // Update functionality for all registers in the core. + // All registers are positive edge triggered with asynchronous + // active low reset. All registers have write enable. + //---------------------------------------------------------------- + always @ (posedge clk or negedge reset_n) + begin : reg_update + if (!reset_n) + begin + a_reg <= {64'h0, 64'h0}; + b_reg <= {64'h0, 64'h0}; + c_reg <= {64'h0, 64'h0}; + d_reg <= {64'h0, 64'h0}; + e_reg <= {64'h0, 64'h0}; + f_reg <= {64'h0, 64'h0}; + g_reg <= {64'h0, 64'h0}; + h_reg <= {64'h0, 64'h0}; + H0_reg <= 64'h0; + H1_reg <= 64'h0; + H2_reg <= 64'h0; + H3_reg <= 64'h0; + H4_reg <= 64'h0; + H5_reg <= 64'h0; + H6_reg <= 64'h0; + H7_reg <= 64'h0; + ready_reg <= 1'b1; + digest_valid_reg <= 1'b0; + round_ctr_reg <= 7'h0; + rnd_ctr_reg <= 7'h0; + sha512_ctrl_reg <= CTRL_IDLE; + masking_rnd <= '0; + end + + else if (zeroize) + begin + a_reg <= {64'h0, 64'h0}; + b_reg <= {64'h0, 64'h0}; + c_reg <= {64'h0, 64'h0}; + d_reg <= {64'h0, 64'h0}; + e_reg <= {64'h0, 64'h0}; + f_reg <= {64'h0, 64'h0}; + g_reg <= {64'h0, 64'h0}; + h_reg <= {64'h0, 64'h0}; + H0_reg <= 64'h0; + H1_reg <= 64'h0; + H2_reg <= 64'h0; + H3_reg <= 64'h0; + H4_reg <= 64'h0; + H5_reg <= 64'h0; + H6_reg <= 64'h0; + H7_reg <= 64'h0; + ready_reg <= 1'b1; + digest_valid_reg <= 1'b0; + round_ctr_reg <= 7'h0; + rnd_ctr_reg <= 7'h0; + sha512_ctrl_reg <= CTRL_IDLE; + masking_rnd <= '0; + end + + else + begin + if (a_h_we) + begin + a_reg <= a_new; + b_reg <= b_new; + c_reg <= c_new; + d_reg <= d_new; + e_reg <= e_new; + f_reg <= f_new; + g_reg <= g_new; + h_reg <= h_new; + end + + if (H_we) + begin + H0_reg <= H0_new; + H1_reg <= H1_new; + H2_reg <= H2_new; + H3_reg <= H3_new; + H4_reg <= H4_new; + H5_reg <= H5_new; + H6_reg <= H6_new; + H7_reg <= H7_new; + end + + if (round_ctr_we) + round_ctr_reg <= round_ctr_new; + + if (rnd_ctr_we) + rnd_ctr_reg <= rnd_ctr_new; + + if (ready_we) + ready_reg <= ready_new; + + if (digest_valid_we) + digest_valid_reg <= digest_valid_new; + + if (sha512_ctrl_we) + sha512_ctrl_reg <= sha512_ctrl_new; + + if (masking_init) begin + masking_rnd[3*rnd_ctr_reg[2 : 0]] <= entropy[63 : 0]; + masking_rnd[3*rnd_ctr_reg[2 : 0]+1] <= entropy[127 : 64]; + masking_rnd[3*rnd_ctr_reg[2 : 0]+2] <= entropy[191 : 128]; + end + end + end // reg_update + + always @ (posedge clk or negedge reset_n) + begin : init_reg_update + if (!reset_n) + init_reg <= '0; + else if (zeroize) + init_reg <= '0; + else if (init_reg_set) + init_reg <= 1'b1; + else if (init_reg_reset) + init_reg <= 1'b0; + end // init_reg_update + + //---------------------------------------------------------------- + // digest_logic + // + // The logic needed to init as well as update the digest. + //---------------------------------------------------------------- + always @* + begin : digest_logic + H0_new = 64'h0; + H1_new = 64'h0; + H2_new = 64'h0; + H3_new = 64'h0; + H4_new = 64'h0; + H5_new = 64'h0; + H6_new = 64'h0; + H7_new = 64'h0; + H_we = 0; + + if (digest_init) + begin + H0_new = H0_0; + H1_new = H0_1; + H2_new = H0_2; + H3_new = H0_3; + H4_new = H0_4; + H5_new = H0_5; + H6_new = H0_6; + H7_new = H0_7; + H_we = 1; + end + + if (digest_update) + begin + H0_new = H0_reg + (a_reg.masked ^ a_reg.random); + H1_new = H1_reg + (b_reg.masked ^ b_reg.random); + H2_new = H2_reg + (c_reg.masked ^ c_reg.random); + H3_new = H3_reg + (d_reg.masked ^ d_reg.random); + H4_new = H4_reg + (e_reg.masked ^ e_reg.random); + H5_new = H5_reg + (f_reg.masked ^ f_reg.random); + H6_new = H6_reg + (g_reg.masked ^ g_reg.random); + H7_new = H7_reg + (h_reg.masked ^ h_reg.random); + H_we = 1; + end + end // digest_logic + + //---------------------------------------------------------------- + // t1_logic + // + // The logic for the T1 function. + //---------------------------------------------------------------- + always @* + begin : t1_logic + masked_reg_t sum1; + masked_reg_t ch; + + masked_reg_t k_data_s; + + masked_reg_t h_reg_b2a; + masked_reg_t sum1_b2a; + masked_reg_t ch_b2a; + masked_reg_t k_data_b2a; + masked_reg_t w_data_b2a; + + sum1 = {sigma1(e_reg.masked), sigma1(e_reg.random)}; + + ch = masked_ch(e_reg, f_reg, g_reg); // (e_reg & f_reg) ^ ((~e_reg) & g_reg); + + k_data_s = {k_data, 64'h0}; + h_reg_b2a = B2A_conv(h_reg, q_masking_rnd[0]); + sum1_b2a = B2A_conv(sum1, q_masking_rnd[1]); + ch_b2a = B2A_conv(ch, q_masking_rnd[2]); + k_data_b2a = B2A_conv(k_data_s, q_masking_rnd[3]); + w_data_b2a = B2A_conv(w_data, q_masking_rnd[4]); + + t1_b2a = masked_sum(h_reg_b2a, masked_sum(sum1_b2a, masked_sum(ch_b2a, masked_sum(k_data_b2a, w_data_b2a)))); + end // t1_logic + + + //---------------------------------------------------------------- + // t2_logic + // + // The logic for the T2 function + //---------------------------------------------------------------- + always @* + begin : t2_logic + masked_reg_t sum0; + masked_reg_t maj; + + masked_reg_t sum0_b2a; + masked_reg_t maj_b2a; + + sum0 = {sigma0(a_reg.masked), sigma0(a_reg.random)}; + + maj = masked_maj(a_reg, b_reg, c_reg); // (a_reg & b_reg) ^ (a_reg & c_reg) ^ (b_reg & c_reg); + + sum0_b2a = B2A_conv(sum0, q_masking_rnd[5]); + maj_b2a = B2A_conv(maj, q_masking_rnd[6]); + + t2_b2a = masked_sum(sum0_b2a, maj_b2a); + end // t2_logic + + //---------------------------------------------------------------- + // A2B_logic + // + // The logic for the A2B function + //---------------------------------------------------------------- + always @* + begin : A2B_logic + masked_reg_t d_reg_b2a; + + d_reg_b2a = B2A_conv(d_reg, q_masking_rnd[7]); + + a_new_a2b = A2B_conv(masked_sum(t1_b2a, t2_b2a), q_masking_rnd[8]); + e_new_a2b = A2B_conv(masked_sum(d_reg_b2a, t1_b2a), q_masking_rnd[9]); + + end // A2B_logic + + //---------------------------------------------------------------- + // state_logic + // + // The logic needed to init as well as update the state during + // round processing. + //---------------------------------------------------------------- + always @* + begin : state_logic + a_new = {64'h0, 64'h0}; + b_new = {64'h0, 64'h0}; + c_new = {64'h0, 64'h0}; + d_new = {64'h0, 64'h0}; + e_new = {64'h0, 64'h0}; + f_new = {64'h0, 64'h0}; + g_new = {64'h0, 64'h0}; + h_new = {64'h0, 64'h0}; + a_h_we = 0; + + if (state_init) + begin + if (first_block) + begin + a_new = {H0_0 ^ rh_masking_rnd[0], rh_masking_rnd[0]}; + b_new = {H0_1 ^ rh_masking_rnd[1], rh_masking_rnd[1]}; + c_new = {H0_2 ^ rh_masking_rnd[2], rh_masking_rnd[2]}; + d_new = {H0_3 ^ rh_masking_rnd[3], rh_masking_rnd[3]}; + e_new = {H0_4 ^ rh_masking_rnd[4], rh_masking_rnd[4]}; + f_new = {H0_5 ^ rh_masking_rnd[5], rh_masking_rnd[5]}; + g_new = {H0_6 ^ rh_masking_rnd[6], rh_masking_rnd[6]}; + h_new = {H0_7 ^ rh_masking_rnd[7], rh_masking_rnd[7]}; + a_h_we = 1; + end + else + begin + a_new = {H0_reg ^ rh_masking_rnd[0], rh_masking_rnd[0]}; + b_new = {H1_reg ^ rh_masking_rnd[1], rh_masking_rnd[1]}; + c_new = {H2_reg ^ rh_masking_rnd[2], rh_masking_rnd[2]}; + d_new = {H3_reg ^ rh_masking_rnd[3], rh_masking_rnd[3]}; + e_new = {H4_reg ^ rh_masking_rnd[4], rh_masking_rnd[4]}; + f_new = {H5_reg ^ rh_masking_rnd[5], rh_masking_rnd[5]}; + g_new = {H6_reg ^ rh_masking_rnd[6], rh_masking_rnd[6]}; + h_new = {H7_reg ^ rh_masking_rnd[7], rh_masking_rnd[7]}; + a_h_we = 1; + end + end + + if (state_update) + begin + a_new = a_new_a2b; + b_new = a_reg; + c_new = b_reg; + d_new = c_reg; + e_new = e_new_a2b; + f_new = e_reg; + g_new = f_reg; + h_new = g_reg; + a_h_we = 1; + end + end // state_logic + + + //---------------------------------------------------------------- + // round_ctr + // + // Update logic for the round counter, a monotonically + // increasing counter with reset. + //---------------------------------------------------------------- + always @* + begin : round_ctr + round_ctr_new = '0; + round_ctr_we = 0; + + if (round_ctr_rst) + begin + round_ctr_new = '0; + round_ctr_we = 1; + end + + if (round_ctr_inc) + begin + round_ctr_new = round_ctr_reg + 1'b1; + round_ctr_we = 1; + end + end // round_ctr + + //---------------------------------------------------------------- + // rnd_ctr + // + // Update logic for the rnd counter, a monotonically + // increasing counter with reset. + //---------------------------------------------------------------- + always @* + begin : rnd_ctr + rnd_ctr_new = '0; + rnd_ctr_we = 0; + + if (rnd_ctr_rst) + begin + rnd_ctr_new = '0; + rnd_ctr_we = 1; + end + + if (rnd_ctr_inc) + begin + rnd_ctr_new = rnd_ctr_reg + 1'b1; + rnd_ctr_we = 1; + end + end // rnd_ctr + + //---------------------------------------------------------------- + // masking_rnd + // + // Update logic for the rw_masking_rnd and q_masking_rnd + //---------------------------------------------------------------- + always @* + begin : masking_random + masking_init = rnd_ctr_inc; + masking_update = round_ctr_inc; + q_masking_rnd = '0; + + if (masking_update) begin + q_masking_rnd = entropy[14 : 5]; + end + end // masking_rnd + + //---------------------------------------------------------------- + // sha512_ctrl_fsm + // + // Logic for the state machine controlling the core behaviour. + //---------------------------------------------------------------- + always @* + begin : sha512_ctrl_fsm + digest_init = 1'b0; + digest_update = 1'b0; + state_init = 1'b0; + state_update = 1'b0; + first_block = 1'b0; + w_init = 1'b0; + w_next = 1'b0; + round_ctr_inc = 1'b0; + round_ctr_rst = 1'b0; + digest_valid_new = 1'b0; + digest_valid_we = 1'b0; + ready_new = 1'b0; + ready_we = 1'b0; + sha512_ctrl_new = CTRL_IDLE; + sha512_ctrl_we = 1'b0; + rnd_ctr_inc = 1'b0; + rnd_ctr_rst = 1'b0; + init_reg_set = 1'b0; + init_reg_reset = 1'b0; + + unique case (sha512_ctrl_reg) + CTRL_IDLE: + begin + if (init_cmd | next_cmd) + begin + ready_new = 1'b0; + ready_we = 1'b1; + digest_valid_new = 0; + digest_valid_we = 1; + rnd_ctr_rst = 1'b1; + sha512_ctrl_new = CTRL_RND; + sha512_ctrl_we = 1; + init_reg_set = init_cmd; + end + end + + CTRL_RND: + begin + rnd_ctr_inc = 1; + + if (rnd_ctr_reg == SHA512_RNDs) + begin + w_init = 1; + state_init = 1; + round_ctr_rst = 1; + sha512_ctrl_new = CTRL_ROUNDS; + sha512_ctrl_we = 1; + init_reg_reset = 1; + + if (init_reg) + begin + digest_init = 1; + first_block = 1; + end + end + end + + CTRL_ROUNDS: + begin + w_next = 1; + state_update = 1; + round_ctr_inc = 1; + + if (round_ctr_reg == SHA512_ROUNDS) + begin + sha512_ctrl_new = CTRL_DONE; + sha512_ctrl_we = 1; + end + end + + + CTRL_DONE: + begin + ready_new = 1'b1; + ready_we = 1'b1; + digest_update = 1'b1; + digest_valid_new = 1'b1; + digest_valid_we = 1'b1; + sha512_ctrl_new = CTRL_IDLE; + sha512_ctrl_we = 1'b1; + end + + + default: + begin + digest_init = 1'b0; + digest_update = 1'b0; + state_init = 1'b0; + state_update = 1'b0; + first_block = 1'b0; + w_init = 1'b0; + w_next = 1'b0; + round_ctr_inc = 1'b0; + round_ctr_rst = 1'b0; + digest_valid_new = 1'b0; + digest_valid_we = 1'b0; + ready_new = 1'b0; + ready_we = 1'b0; + sha512_ctrl_new = CTRL_IDLE; + sha512_ctrl_we = 1'b0; + rnd_ctr_inc = 1'b0; + rnd_ctr_rst = 1'b0; + end + + endcase // case (sha512_ctrl_reg) + end // sha512_ctrl_fsm + +endmodule // sha512_core + +//====================================================================== +// EOF sha512_core.v +//====================================================================== diff --git a/designs/Caliptra/src/caliptra-rtl/sha512_masked_defines_pkg.sv b/designs/Caliptra/src/caliptra-rtl/sha512_masked_defines_pkg.sv new file mode 100644 index 0000000..def18f5 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/sha512_masked_defines_pkg.sv @@ -0,0 +1,107 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +// +`ifndef CALIPTRA_SHA512_MASKED_DEFINES_PKG +`define CALIPTRA_SHA512_MASKED_DEFINES_PKG + +package sha512_masked_defines_pkg; + + typedef struct packed { + reg [63:0] masked; + reg [63:0] random; + } masked_reg_t; + + //---------------------------------------------------------------- + // Function definition. + //---------------------------------------------------------------- + function automatic masked_reg_t masked_not (input masked_reg_t x); + return {~x.masked, x.random}; + endfunction + + function automatic reg [63:0] masked_and (input masked_reg_t x, y); + return ~y.masked & (~y.random & x.random | y.random & x.masked) | y.masked & (y.random & x.random | ~y.random & x.masked); //x & y; + endfunction + + function automatic masked_reg_t masked_maj (input masked_reg_t a, b, c); + return {masked_and(a, b) ^ masked_and(a, c) ^ masked_and(b, c), b.random}; + endfunction + + function automatic masked_reg_t masked_ch (input masked_reg_t e, f, g); + return {masked_and(e, f) ^ masked_and(g, masked_not(e)), e.random ^ g.random}; + endfunction + + function automatic reg [63:0] sigma0 (input reg [63:0] x); + return {x[27 : 0], x[63 : 28]} ^ + {x[33 : 0], x[63 : 34]} ^ + {x[38 : 0], x[63 : 39]}; + endfunction + + function automatic reg [63:0] sigma1 (input reg [63:0] x); + return {x[13 : 0], x[63 : 14]} ^ + {x[17 : 0], x[63 : 18]} ^ + {x[40 : 0], x[63 : 41]}; + endfunction + + function automatic reg [63:0] ROT1 (input reg [63:0] x); + return {x[0], x[63 : 1]} ^ // ROTR1 + {x[7 : 0], x[63 : 8]} ^ // ROTR8 + {7'b0000000, x[63 : 7]}; // SHR7 + endfunction + + function automatic reg [63:0] ROT14 (input reg [63:0] x); + return {x[18 : 0], x[63 : 19]} ^ // ROTR19 + {x[60 : 0], x[63 : 61]} ^ // ROTR61 + {6'b000000, x[63 : 6]}; // SHR6 + endfunction + + function automatic masked_reg_t masked_sum (input masked_reg_t x, y); + return {(x.masked + y.masked), (x.random + y.random)}; + endfunction + + function automatic masked_reg_t B2A_conv (input masked_reg_t x, logic q); // convert x_masked = x ^ rnd to x_prime = x + rand + reg [63 : 0] masked_carry; // masked_carry[j] = c[j] ^ q + reg [63 : 0] x_prime; + for (int j = 0; j < 64 ; j++) begin + if (j == 0) begin + masked_carry[j] = ~x.masked[j] & (x.random[j] ^ q) | (x.masked[j] & q); + x_prime[j] = x.masked[j]; + end + else begin + masked_carry[j] = ~x.masked[j] & (x.random[j] ^ q) | x.masked[j] & masked_carry[j-1]; + x_prime[j] = (x.masked[j] ^ masked_carry[j-1]) ^ q; + end + end + return {x_prime, x.random}; + endfunction + + function automatic masked_reg_t A2B_conv (input masked_reg_t x, logic q); // convert x_prime = x + rand to x_masked = x ^ rnd + reg [63 : 0] masked_carry; // masked_carry[j] = c[j] ^ q + reg [63 : 0] x_masked; + + for (int j = 0; j < 64 ; j++) begin + if (j == 0) begin + masked_carry[j] = (~x.masked[0] & x.random[0]) ^ q; + x_masked[j] = x.masked[j]; + end + else begin + masked_carry[j] = (x.masked[j] ^ x.random[j]) & (x.random[j] ^ q) | (~x.masked[j] ^ x.random[j]) & masked_carry[j-1]; + x_masked[j] = (x.masked[j] ^ masked_carry[j-1]) ^ q; + end + end + return {x_masked, x.random}; + endfunction + +endpackage + +`endif diff --git a/designs/Caliptra/src/caliptra-rtl/sha512_masked_w_mem.sv b/designs/Caliptra/src/caliptra-rtl/sha512_masked_w_mem.sv new file mode 100644 index 0000000..f077894 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/sha512_masked_w_mem.sv @@ -0,0 +1,290 @@ +//====================================================================== +// +// sha512_masked_w_mem_regs.v +// ------------------- +// The W memory for the SHA-512 core. This version uses 16 +// 32-bit registers as a sliding window to generate the 64 words. +// +// +// Author: Joachim Strombergson +// Copyright (c) 2014 Secworks Sweden AB +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or +// without modification, are permitted provided that the following +// conditions are met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in +// the documentation and/or other materials provided with the +// distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +//====================================================================== + +module sha512_masked_w_mem + import sha512_masked_defines_pkg::*; + ( + input wire clk, + input wire reset_n, + input wire zeroize, + + input wire [1023 : 0] block_msg, + input wire [1023 : 0] rw_masking_rnd, + input wire [4 : 0] entropy, + + input wire init_cmd, + input wire next_cmd, + output wire masked_reg_t w_val + ); + + + //---------------------------------------------------------------- + // Registers including update variables and write enable. + //---------------------------------------------------------------- + masked_reg_t w_mem [0 : 15]; + masked_reg_t w_mem00_new; + masked_reg_t w_mem01_new; + masked_reg_t w_mem02_new; + masked_reg_t w_mem03_new; + masked_reg_t w_mem04_new; + masked_reg_t w_mem05_new; + masked_reg_t w_mem06_new; + masked_reg_t w_mem07_new; + masked_reg_t w_mem08_new; + masked_reg_t w_mem09_new; + masked_reg_t w_mem10_new; + masked_reg_t w_mem11_new; + masked_reg_t w_mem12_new; + masked_reg_t w_mem13_new; + masked_reg_t w_mem14_new; + masked_reg_t w_mem15_new; + reg w_mem_we; + + reg [6 : 0] w_ctr_reg; + reg [6 : 0] w_ctr_new; + reg w_ctr_we; + + //---------------------------------------------------------------- + // Wires. + //---------------------------------------------------------------- + masked_reg_t w_tmp; + masked_reg_t w_new; + + + //---------------------------------------------------------------- + // Concurrent connectivity for ports etc. + //---------------------------------------------------------------- + assign w_val = w_tmp; + + + //---------------------------------------------------------------- + // reg_update + // Update functionality for all registers in the core. + // All registers are positive edge triggered with asynchronous + // active low reset. All registers have write enable. + //---------------------------------------------------------------- + always @ (posedge clk or negedge reset_n) + begin : reg_update + integer ii; + + if (!reset_n) begin + for (ii = 0; ii < 16; ii = ii + 1) + w_mem[ii] <= {64'h0, 64'h0}; + + w_ctr_reg <= 7'h0; + end + else begin + if (zeroize) begin + for (ii = 0; ii < 16; ii = ii + 1) + w_mem[ii] <= {64'h0, 64'h0}; + + w_ctr_reg <= 7'h0; + end + else begin + if (w_mem_we) + begin + w_mem[00] <= w_mem00_new; + w_mem[01] <= w_mem01_new; + w_mem[02] <= w_mem02_new; + w_mem[03] <= w_mem03_new; + w_mem[04] <= w_mem04_new; + w_mem[05] <= w_mem05_new; + w_mem[06] <= w_mem06_new; + w_mem[07] <= w_mem07_new; + w_mem[08] <= w_mem08_new; + w_mem[09] <= w_mem09_new; + w_mem[10] <= w_mem10_new; + w_mem[11] <= w_mem11_new; + w_mem[12] <= w_mem12_new; + w_mem[13] <= w_mem13_new; + w_mem[14] <= w_mem14_new; + w_mem[15] <= w_mem15_new; + end + + if (w_ctr_we) + w_ctr_reg <= w_ctr_new; + end + end + end // reg_update + + + //---------------------------------------------------------------- + // select_w + // + // Mux for the external read operation. This is where we exract + // the W variable. + //---------------------------------------------------------------- + always @* + begin : select_w + if (w_ctr_reg < 16) + w_tmp = w_mem[w_ctr_reg[3 : 0]]; + else + w_tmp = w_new; + end // select_w + + + //---------------------------------------------------------------- + // w_new_logic + // + // Logic that calculates the next value to be inserted into + // the sliding window of the memory. + //---------------------------------------------------------------- + masked_reg_t w_0; + masked_reg_t w_1; + masked_reg_t w_9; + masked_reg_t w_14; + masked_reg_t d0; + masked_reg_t d1; + + masked_reg_t w_0_b2a; + masked_reg_t w_9_b2a; + masked_reg_t d0_b2a; + masked_reg_t d1_b2a; + + always @* + begin : w_mem_update_logic + + + w_mem00_new = {64'h0, 64'h0}; + w_mem01_new = {64'h0, 64'h0}; + w_mem02_new = {64'h0, 64'h0}; + w_mem03_new = {64'h0, 64'h0}; + w_mem04_new = {64'h0, 64'h0}; + w_mem05_new = {64'h0, 64'h0}; + w_mem06_new = {64'h0, 64'h0}; + w_mem07_new = {64'h0, 64'h0}; + w_mem08_new = {64'h0, 64'h0}; + w_mem09_new = {64'h0, 64'h0}; + w_mem10_new = {64'h0, 64'h0}; + w_mem11_new = {64'h0, 64'h0}; + w_mem12_new = {64'h0, 64'h0}; + w_mem13_new = {64'h0, 64'h0}; + w_mem14_new = {64'h0, 64'h0}; + w_mem15_new = {64'h0, 64'h0}; + w_mem_we = 0; + + w_0 = w_mem[0]; + w_1 = w_mem[1]; + w_9 = w_mem[9]; + w_14 = w_mem[14]; + + d0 = {ROT1(w_1.masked), ROT1(w_1.random)}; + + d1 = {ROT14(w_14.masked), ROT14(w_14.random)}; + + w_0_b2a = B2A_conv(w_0, entropy[0]); + d0_b2a = B2A_conv(d0, entropy[1]); + w_9_b2a = B2A_conv(w_9, entropy[2]); + d1_b2a = B2A_conv(d1, entropy[3]); + + //w_new = w_0 + d0 + w_9 + d1; + w_new = A2B_conv(masked_sum(w_0_b2a, masked_sum(d0_b2a, masked_sum(w_9_b2a, d1_b2a))), entropy[4]); + + if (init_cmd) + begin + w_mem00_new = {block_msg[1023 : 960] ^ rw_masking_rnd[1023 : 960], rw_masking_rnd[1023 : 960]}; + w_mem01_new = {block_msg[959 : 896] ^ rw_masking_rnd[959 : 896], rw_masking_rnd[959 : 896]}; + w_mem02_new = {block_msg[895 : 832] ^ rw_masking_rnd[895 : 832], rw_masking_rnd[895 : 832]}; + w_mem03_new = {block_msg[831 : 768] ^ rw_masking_rnd[831 : 768], rw_masking_rnd[831 : 768]}; + w_mem04_new = {block_msg[767 : 704] ^ rw_masking_rnd[767 : 704], rw_masking_rnd[767 : 704]}; + w_mem05_new = {block_msg[703 : 640] ^ rw_masking_rnd[703 : 640], rw_masking_rnd[703 : 640]}; + w_mem06_new = {block_msg[639 : 576] ^ rw_masking_rnd[639 : 576], rw_masking_rnd[639 : 576]}; + w_mem07_new = {block_msg[575 : 512] ^ rw_masking_rnd[575 : 512], rw_masking_rnd[575 : 512]}; + w_mem08_new = {block_msg[511 : 448] ^ rw_masking_rnd[511 : 448], rw_masking_rnd[511 : 448]}; + w_mem09_new = {block_msg[447 : 384] ^ rw_masking_rnd[447 : 384], rw_masking_rnd[447 : 384]}; + w_mem10_new = {block_msg[383 : 320] ^ rw_masking_rnd[383 : 320], rw_masking_rnd[383 : 320]}; + w_mem11_new = {block_msg[319 : 256] ^ rw_masking_rnd[319 : 256], rw_masking_rnd[319 : 256]}; + w_mem12_new = {block_msg[255 : 192] ^ rw_masking_rnd[255 : 192], rw_masking_rnd[255 : 192]}; + w_mem13_new = {block_msg[191 : 128] ^ rw_masking_rnd[191 : 128], rw_masking_rnd[191 : 128]}; + w_mem14_new = {block_msg[127 : 64] ^ rw_masking_rnd[127 : 64], rw_masking_rnd[127 : 64]}; + w_mem15_new = {block_msg[63 : 0] ^ rw_masking_rnd[63 : 0], rw_masking_rnd[63 : 0]}; + w_mem_we = 1; + end + + if (next_cmd && (w_ctr_reg > 15)) + begin + w_mem00_new = w_mem[01]; + w_mem01_new = w_mem[02]; + w_mem02_new = w_mem[03]; + w_mem03_new = w_mem[04]; + w_mem04_new = w_mem[05]; + w_mem05_new = w_mem[06]; + w_mem06_new = w_mem[07]; + w_mem07_new = w_mem[08]; + w_mem08_new = w_mem[09]; + w_mem09_new = w_mem[10]; + w_mem10_new = w_mem[11]; + w_mem11_new = w_mem[12]; + w_mem12_new = w_mem[13]; + w_mem13_new = w_mem[14]; + w_mem14_new = w_mem[15]; + w_mem15_new = w_new; + w_mem_we = 1; + end + end // w_mem_update_logic + + + //---------------------------------------------------------------- + // w_ctr + // W schedule adress counter. Counts from 0x10 to 0x3f and + // is used to expand the block into words. + //---------------------------------------------------------------- + always @* + begin : w_ctr + w_ctr_new = 7'h0; + w_ctr_we = 1'h0; + + if (init_cmd) + begin + w_ctr_new = 7'h00; + w_ctr_we = 1'h1; + end + + if (next_cmd) + begin + w_ctr_new = w_ctr_reg + 7'h01; + w_ctr_we = 1'h1; + end + end // w_ctr + +endmodule // sha512_w_mem + +//====================================================================== +// EOF sha512_masked_w_mem.v +//====================================================================== \ No newline at end of file diff --git a/designs/Caliptra/src/caliptra-rtl/sha512_params_pkg.sv b/designs/Caliptra/src/caliptra-rtl/sha512_params_pkg.sv new file mode 100644 index 0000000..292503a --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/sha512_params_pkg.sv @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +// +// +package sha512_params_pkg; + + localparam SHA512_CORE_NAME0 = 32'h61327368; // "sha2" + localparam SHA512_CORE_NAME1 = 32'h31322d35; // "-512" + localparam SHA512_CORE_VERSION0 = 32'h3830302e; // "0.80" + localparam SHA512_CORE_VERSION1 = 32'h00000000; // "0" + + localparam MODE_SHA_512_224 = 2'h0; + localparam MODE_SHA_512_256 = 2'h1; + localparam MODE_SHA_384 = 2'h2; + localparam MODE_SHA_512 = 2'h3; + +endpackage +//====================================================================== +// EOF sha512_params_pkg.sv +//====================================================================== diff --git a/designs/Caliptra/src/caliptra-rtl/sha512_reg.sv b/designs/Caliptra/src/caliptra-rtl/sha512_reg.sv new file mode 100644 index 0000000..843d93a --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/sha512_reg.sv @@ -0,0 +1,2296 @@ +// Generated by PeakRDL-regblock - A free and open-source SystemVerilog generator +// https://github.com/SystemRDL/PeakRDL-regblock + +module sha512_reg ( + input wire clk, + input wire rst, + + input wire s_cpuif_req, + input wire s_cpuif_req_is_wr, + input wire [11:0] s_cpuif_addr, + input wire [31:0] s_cpuif_wr_data, + input wire [31:0] s_cpuif_wr_biten, + output wire s_cpuif_req_stall_wr, + output wire s_cpuif_req_stall_rd, + output wire s_cpuif_rd_ack, + output wire s_cpuif_rd_err, + output wire [31:0] s_cpuif_rd_data, + output wire s_cpuif_wr_ack, + output wire s_cpuif_wr_err, + + input sha512_reg_pkg::sha512_reg__in_t hwif_in, + output sha512_reg_pkg::sha512_reg__out_t hwif_out + ); + + //-------------------------------------------------------------------------- + // CPU Bus interface logic + //-------------------------------------------------------------------------- + logic cpuif_req; + logic cpuif_req_is_wr; + logic [11:0] cpuif_addr; + logic [31:0] cpuif_wr_data; + logic [31:0] cpuif_wr_biten; + logic cpuif_req_stall_wr; + logic cpuif_req_stall_rd; + + logic cpuif_rd_ack; + logic cpuif_rd_err; + logic [31:0] cpuif_rd_data; + + logic cpuif_wr_ack; + logic cpuif_wr_err; + + assign cpuif_req = s_cpuif_req; + assign cpuif_req_is_wr = s_cpuif_req_is_wr; + assign cpuif_addr = s_cpuif_addr; + assign cpuif_wr_data = s_cpuif_wr_data; + assign cpuif_wr_biten = s_cpuif_wr_biten; + assign s_cpuif_req_stall_wr = cpuif_req_stall_wr; + assign s_cpuif_req_stall_rd = cpuif_req_stall_rd; + assign s_cpuif_rd_ack = cpuif_rd_ack; + assign s_cpuif_rd_err = cpuif_rd_err; + assign s_cpuif_rd_data = cpuif_rd_data; + assign s_cpuif_wr_ack = cpuif_wr_ack; + assign s_cpuif_wr_err = cpuif_wr_err; + + logic cpuif_req_masked; + + // Read & write latencies are balanced. Stalls not required + assign cpuif_req_stall_rd = '0; + assign cpuif_req_stall_wr = '0; + assign cpuif_req_masked = cpuif_req + & !(!cpuif_req_is_wr & cpuif_req_stall_rd) + & !(cpuif_req_is_wr & cpuif_req_stall_wr); + + //-------------------------------------------------------------------------- + // Address Decode + //-------------------------------------------------------------------------- + typedef struct packed{ + logic [2-1:0]SHA512_NAME; + logic [2-1:0]SHA512_VERSION; + logic SHA512_CTRL; + logic SHA512_STATUS; + logic [32-1:0]SHA512_BLOCK; + logic [16-1:0]SHA512_DIGEST; + logic SHA512_VAULT_RD_CTRL; + logic SHA512_VAULT_RD_STATUS; + logic SHA512_KV_WR_CTRL; + logic SHA512_KV_WR_STATUS; + logic [8-1:0]SHA512_GEN_PCR_HASH_NONCE; + logic SHA512_GEN_PCR_HASH_CTRL; + logic SHA512_GEN_PCR_HASH_STATUS; + logic [16-1:0]SHA512_GEN_PCR_HASH_DIGEST; + struct packed{ + logic global_intr_en_r; + logic error_intr_en_r; + logic notif_intr_en_r; + logic error_global_intr_r; + logic notif_global_intr_r; + logic error_internal_intr_r; + logic notif_internal_intr_r; + logic error_intr_trig_r; + logic notif_intr_trig_r; + logic error0_intr_count_r; + logic error1_intr_count_r; + logic error2_intr_count_r; + logic error3_intr_count_r; + logic notif_cmd_done_intr_count_r; + logic error0_intr_count_incr_r; + logic error1_intr_count_incr_r; + logic error2_intr_count_incr_r; + logic error3_intr_count_incr_r; + logic notif_cmd_done_intr_count_incr_r; + } intr_block_rf; + } decoded_reg_strb_t; + decoded_reg_strb_t decoded_reg_strb; + logic decoded_req; + logic decoded_req_is_wr; + logic [31:0] decoded_wr_data; + logic [31:0] decoded_wr_biten; + + always_comb begin + for(int i0=0; i0<2; i0++) begin + decoded_reg_strb.SHA512_NAME[i0] = cpuif_req_masked & (cpuif_addr == 12'h0 + i0*12'h4); + end + for(int i0=0; i0<2; i0++) begin + decoded_reg_strb.SHA512_VERSION[i0] = cpuif_req_masked & (cpuif_addr == 12'h8 + i0*12'h4); + end + decoded_reg_strb.SHA512_CTRL = cpuif_req_masked & (cpuif_addr == 12'h10); + decoded_reg_strb.SHA512_STATUS = cpuif_req_masked & (cpuif_addr == 12'h18); + for(int i0=0; i0<32; i0++) begin + decoded_reg_strb.SHA512_BLOCK[i0] = cpuif_req_masked & (cpuif_addr == 12'h80 + i0*12'h4); + end + for(int i0=0; i0<16; i0++) begin + decoded_reg_strb.SHA512_DIGEST[i0] = cpuif_req_masked & (cpuif_addr == 12'h100 + i0*12'h4); + end + decoded_reg_strb.SHA512_VAULT_RD_CTRL = cpuif_req_masked & (cpuif_addr == 12'h600); + decoded_reg_strb.SHA512_VAULT_RD_STATUS = cpuif_req_masked & (cpuif_addr == 12'h604); + decoded_reg_strb.SHA512_KV_WR_CTRL = cpuif_req_masked & (cpuif_addr == 12'h608); + decoded_reg_strb.SHA512_KV_WR_STATUS = cpuif_req_masked & (cpuif_addr == 12'h60c); + for(int i0=0; i0<8; i0++) begin + decoded_reg_strb.SHA512_GEN_PCR_HASH_NONCE[i0] = cpuif_req_masked & (cpuif_addr == 12'h610 + i0*12'h4); + end + decoded_reg_strb.SHA512_GEN_PCR_HASH_CTRL = cpuif_req_masked & (cpuif_addr == 12'h630); + decoded_reg_strb.SHA512_GEN_PCR_HASH_STATUS = cpuif_req_masked & (cpuif_addr == 12'h634); + for(int i0=0; i0<16; i0++) begin + decoded_reg_strb.SHA512_GEN_PCR_HASH_DIGEST[i0] = cpuif_req_masked & (cpuif_addr == 12'h638 + i0*12'h4); + end + decoded_reg_strb.intr_block_rf.global_intr_en_r = cpuif_req_masked & (cpuif_addr == 12'h800); + decoded_reg_strb.intr_block_rf.error_intr_en_r = cpuif_req_masked & (cpuif_addr == 12'h804); + decoded_reg_strb.intr_block_rf.notif_intr_en_r = cpuif_req_masked & (cpuif_addr == 12'h808); + decoded_reg_strb.intr_block_rf.error_global_intr_r = cpuif_req_masked & (cpuif_addr == 12'h80c); + decoded_reg_strb.intr_block_rf.notif_global_intr_r = cpuif_req_masked & (cpuif_addr == 12'h810); + decoded_reg_strb.intr_block_rf.error_internal_intr_r = cpuif_req_masked & (cpuif_addr == 12'h814); + decoded_reg_strb.intr_block_rf.notif_internal_intr_r = cpuif_req_masked & (cpuif_addr == 12'h818); + decoded_reg_strb.intr_block_rf.error_intr_trig_r = cpuif_req_masked & (cpuif_addr == 12'h81c); + decoded_reg_strb.intr_block_rf.notif_intr_trig_r = cpuif_req_masked & (cpuif_addr == 12'h820); + decoded_reg_strb.intr_block_rf.error0_intr_count_r = cpuif_req_masked & (cpuif_addr == 12'h900); + decoded_reg_strb.intr_block_rf.error1_intr_count_r = cpuif_req_masked & (cpuif_addr == 12'h904); + decoded_reg_strb.intr_block_rf.error2_intr_count_r = cpuif_req_masked & (cpuif_addr == 12'h908); + decoded_reg_strb.intr_block_rf.error3_intr_count_r = cpuif_req_masked & (cpuif_addr == 12'h90c); + decoded_reg_strb.intr_block_rf.notif_cmd_done_intr_count_r = cpuif_req_masked & (cpuif_addr == 12'h980); + decoded_reg_strb.intr_block_rf.error0_intr_count_incr_r = cpuif_req_masked & (cpuif_addr == 12'ha00); + decoded_reg_strb.intr_block_rf.error1_intr_count_incr_r = cpuif_req_masked & (cpuif_addr == 12'ha04); + decoded_reg_strb.intr_block_rf.error2_intr_count_incr_r = cpuif_req_masked & (cpuif_addr == 12'ha08); + decoded_reg_strb.intr_block_rf.error3_intr_count_incr_r = cpuif_req_masked & (cpuif_addr == 12'ha0c); + decoded_reg_strb.intr_block_rf.notif_cmd_done_intr_count_incr_r = cpuif_req_masked & (cpuif_addr == 12'ha10); + end + + // Pass down signals to next stage + assign decoded_req = cpuif_req_masked; + assign decoded_req_is_wr = cpuif_req_is_wr; + assign decoded_wr_data = cpuif_wr_data; + assign decoded_wr_biten = cpuif_wr_biten; + + //-------------------------------------------------------------------------- + // Field logic + //-------------------------------------------------------------------------- + typedef struct packed{ + struct packed{ + struct packed{ + logic next; + logic load_next; + } INIT; + struct packed{ + logic next; + logic load_next; + } NEXT; + struct packed{ + logic [1:0] next; + logic load_next; + } MODE; + struct packed{ + logic next; + logic load_next; + } ZEROIZE; + struct packed{ + logic next; + logic load_next; + } LAST; + struct packed{ + logic next; + logic load_next; + } RESTORE; + } SHA512_CTRL; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } BLOCK; + } [32-1:0]SHA512_BLOCK; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } DIGEST; + } [16-1:0]SHA512_DIGEST; + struct packed{ + struct packed{ + logic next; + logic load_next; + } read_en; + struct packed{ + logic [4:0] next; + logic load_next; + } read_entry; + struct packed{ + logic next; + logic load_next; + } pcr_hash_extend; + struct packed{ + logic [24:0] next; + logic load_next; + } rsvd; + } SHA512_VAULT_RD_CTRL; + struct packed{ + struct packed{ + logic next; + logic load_next; + } VALID; + } SHA512_VAULT_RD_STATUS; + struct packed{ + struct packed{ + logic next; + logic load_next; + } write_en; + struct packed{ + logic [4:0] next; + logic load_next; + } write_entry; + struct packed{ + logic next; + logic load_next; + } hmac_key_dest_valid; + struct packed{ + logic next; + logic load_next; + } hmac_block_dest_valid; + struct packed{ + logic next; + logic load_next; + } mldsa_seed_dest_valid; + struct packed{ + logic next; + logic load_next; + } ecc_pkey_dest_valid; + struct packed{ + logic next; + logic load_next; + } ecc_seed_dest_valid; + struct packed{ + logic next; + logic load_next; + } aes_key_dest_valid; + struct packed{ + logic next; + logic load_next; + } mlkem_seed_dest_valid; + struct packed{ + logic next; + logic load_next; + } mlkem_msg_dest_valid; + struct packed{ + logic next; + logic load_next; + } dma_data_dest_valid; + struct packed{ + logic [16:0] next; + logic load_next; + } rsvd; + } SHA512_KV_WR_CTRL; + struct packed{ + struct packed{ + logic next; + logic load_next; + } VALID; + } SHA512_KV_WR_STATUS; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } NONCE; + } [8-1:0]SHA512_GEN_PCR_HASH_NONCE; + struct packed{ + struct packed{ + logic next; + logic load_next; + } START; + } SHA512_GEN_PCR_HASH_CTRL; + struct packed{ + struct packed{ + logic next; + logic load_next; + } VALID; + } SHA512_GEN_PCR_HASH_STATUS; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } DIGEST; + } [16-1:0]SHA512_GEN_PCR_HASH_DIGEST; + struct packed{ + struct packed{ + struct packed{ + logic next; + logic load_next; + } error_en; + struct packed{ + logic next; + logic load_next; + } notif_en; + } global_intr_en_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + } error0_en; + struct packed{ + logic next; + logic load_next; + } error1_en; + struct packed{ + logic next; + logic load_next; + } error2_en; + struct packed{ + logic next; + logic load_next; + } error3_en; + } error_intr_en_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + } notif_cmd_done_en; + } notif_intr_en_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + } agg_sts; + } error_global_intr_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + } agg_sts; + } notif_global_intr_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + } error0_sts; + struct packed{ + logic next; + logic load_next; + } error1_sts; + struct packed{ + logic next; + logic load_next; + } error2_sts; + struct packed{ + logic next; + logic load_next; + } error3_sts; + } error_internal_intr_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + } notif_cmd_done_sts; + } notif_internal_intr_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + } error0_trig; + struct packed{ + logic next; + logic load_next; + } error1_trig; + struct packed{ + logic next; + logic load_next; + } error2_trig; + struct packed{ + logic next; + logic load_next; + } error3_trig; + } error_intr_trig_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + } notif_cmd_done_trig; + } notif_intr_trig_r; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + logic incrthreshold; + logic incrsaturate; + } cnt; + } error0_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + logic incrthreshold; + logic incrsaturate; + } cnt; + } error1_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + logic incrthreshold; + logic incrsaturate; + } cnt; + } error2_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + logic incrthreshold; + logic incrsaturate; + } cnt; + } error3_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + logic incrthreshold; + logic incrsaturate; + } cnt; + } notif_cmd_done_intr_count_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + logic decrthreshold; + logic underflow; + } pulse; + } error0_intr_count_incr_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + logic decrthreshold; + logic underflow; + } pulse; + } error1_intr_count_incr_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + logic decrthreshold; + logic underflow; + } pulse; + } error2_intr_count_incr_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + logic decrthreshold; + logic underflow; + } pulse; + } error3_intr_count_incr_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + logic decrthreshold; + logic underflow; + } pulse; + } notif_cmd_done_intr_count_incr_r; + } intr_block_rf; + } field_combo_t; + field_combo_t field_combo; + + typedef struct packed{ + struct packed{ + struct packed{ + logic value; + } INIT; + struct packed{ + logic value; + } NEXT; + struct packed{ + logic [1:0] value; + } MODE; + struct packed{ + logic value; + } ZEROIZE; + struct packed{ + logic value; + } LAST; + struct packed{ + logic value; + } RESTORE; + } SHA512_CTRL; + struct packed{ + struct packed{ + logic [31:0] value; + } BLOCK; + } [32-1:0]SHA512_BLOCK; + struct packed{ + struct packed{ + logic [31:0] value; + } DIGEST; + } [16-1:0]SHA512_DIGEST; + struct packed{ + struct packed{ + logic value; + } read_en; + struct packed{ + logic [4:0] value; + } read_entry; + struct packed{ + logic value; + } pcr_hash_extend; + struct packed{ + logic [24:0] value; + } rsvd; + } SHA512_VAULT_RD_CTRL; + struct packed{ + struct packed{ + logic value; + } VALID; + } SHA512_VAULT_RD_STATUS; + struct packed{ + struct packed{ + logic value; + } write_en; + struct packed{ + logic [4:0] value; + } write_entry; + struct packed{ + logic value; + } hmac_key_dest_valid; + struct packed{ + logic value; + } hmac_block_dest_valid; + struct packed{ + logic value; + } mldsa_seed_dest_valid; + struct packed{ + logic value; + } ecc_pkey_dest_valid; + struct packed{ + logic value; + } ecc_seed_dest_valid; + struct packed{ + logic value; + } aes_key_dest_valid; + struct packed{ + logic value; + } mlkem_seed_dest_valid; + struct packed{ + logic value; + } mlkem_msg_dest_valid; + struct packed{ + logic value; + } dma_data_dest_valid; + struct packed{ + logic [16:0] value; + } rsvd; + } SHA512_KV_WR_CTRL; + struct packed{ + struct packed{ + logic value; + } VALID; + } SHA512_KV_WR_STATUS; + struct packed{ + struct packed{ + logic [31:0] value; + } NONCE; + } [8-1:0]SHA512_GEN_PCR_HASH_NONCE; + struct packed{ + struct packed{ + logic value; + } START; + } SHA512_GEN_PCR_HASH_CTRL; + struct packed{ + struct packed{ + logic value; + } VALID; + } SHA512_GEN_PCR_HASH_STATUS; + struct packed{ + struct packed{ + logic [31:0] value; + } DIGEST; + } [16-1:0]SHA512_GEN_PCR_HASH_DIGEST; + struct packed{ + struct packed{ + struct packed{ + logic value; + } error_en; + struct packed{ + logic value; + } notif_en; + } global_intr_en_r; + struct packed{ + struct packed{ + logic value; + } error0_en; + struct packed{ + logic value; + } error1_en; + struct packed{ + logic value; + } error2_en; + struct packed{ + logic value; + } error3_en; + } error_intr_en_r; + struct packed{ + struct packed{ + logic value; + } notif_cmd_done_en; + } notif_intr_en_r; + struct packed{ + struct packed{ + logic value; + } agg_sts; + } error_global_intr_r; + struct packed{ + struct packed{ + logic value; + } agg_sts; + } notif_global_intr_r; + struct packed{ + struct packed{ + logic value; + } error0_sts; + struct packed{ + logic value; + } error1_sts; + struct packed{ + logic value; + } error2_sts; + struct packed{ + logic value; + } error3_sts; + } error_internal_intr_r; + struct packed{ + struct packed{ + logic value; + } notif_cmd_done_sts; + } notif_internal_intr_r; + struct packed{ + struct packed{ + logic value; + } error0_trig; + struct packed{ + logic value; + } error1_trig; + struct packed{ + logic value; + } error2_trig; + struct packed{ + logic value; + } error3_trig; + } error_intr_trig_r; + struct packed{ + struct packed{ + logic value; + } notif_cmd_done_trig; + } notif_intr_trig_r; + struct packed{ + struct packed{ + logic [31:0] value; + } cnt; + } error0_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] value; + } cnt; + } error1_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] value; + } cnt; + } error2_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] value; + } cnt; + } error3_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] value; + } cnt; + } notif_cmd_done_intr_count_r; + struct packed{ + struct packed{ + logic value; + } pulse; + } error0_intr_count_incr_r; + struct packed{ + struct packed{ + logic value; + } pulse; + } error1_intr_count_incr_r; + struct packed{ + struct packed{ + logic value; + } pulse; + } error2_intr_count_incr_r; + struct packed{ + struct packed{ + logic value; + } pulse; + } error3_intr_count_incr_r; + struct packed{ + struct packed{ + logic value; + } pulse; + } notif_cmd_done_intr_count_incr_r; + } intr_block_rf; + } field_storage_t; + field_storage_t field_storage; + + // Field: sha512_reg.SHA512_CTRL.INIT + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.SHA512_CTRL.INIT.value; + load_next_c = '0; + if(decoded_reg_strb.SHA512_CTRL && decoded_req_is_wr && hwif_in.sha512_ready) begin // SW write + next_c = (field_storage.SHA512_CTRL.INIT.value & ~decoded_wr_biten[0:0]) | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end else begin // singlepulse clears back to 0 + next_c = '0; + load_next_c = '1; + end + field_combo.SHA512_CTRL.INIT.next = next_c; + field_combo.SHA512_CTRL.INIT.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.SHA512_CTRL.INIT.value <= 1'h0; + end else if(field_combo.SHA512_CTRL.INIT.load_next) begin + field_storage.SHA512_CTRL.INIT.value <= field_combo.SHA512_CTRL.INIT.next; + end + end + assign hwif_out.SHA512_CTRL.INIT.value = field_storage.SHA512_CTRL.INIT.value; + // Field: sha512_reg.SHA512_CTRL.NEXT + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.SHA512_CTRL.NEXT.value; + load_next_c = '0; + if(decoded_reg_strb.SHA512_CTRL && decoded_req_is_wr && hwif_in.sha512_ready) begin // SW write + next_c = (field_storage.SHA512_CTRL.NEXT.value & ~decoded_wr_biten[1:1]) | (decoded_wr_data[1:1] & decoded_wr_biten[1:1]); + load_next_c = '1; + end else begin // singlepulse clears back to 0 + next_c = '0; + load_next_c = '1; + end + field_combo.SHA512_CTRL.NEXT.next = next_c; + field_combo.SHA512_CTRL.NEXT.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.SHA512_CTRL.NEXT.value <= 1'h0; + end else if(field_combo.SHA512_CTRL.NEXT.load_next) begin + field_storage.SHA512_CTRL.NEXT.value <= field_combo.SHA512_CTRL.NEXT.next; + end + end + assign hwif_out.SHA512_CTRL.NEXT.value = field_storage.SHA512_CTRL.NEXT.value; + // Field: sha512_reg.SHA512_CTRL.MODE + always_comb begin + automatic logic [1:0] next_c; + automatic logic load_next_c; + next_c = field_storage.SHA512_CTRL.MODE.value; + load_next_c = '0; + if(decoded_reg_strb.SHA512_CTRL && decoded_req_is_wr && hwif_in.sha512_ready) begin // SW write + next_c = (field_storage.SHA512_CTRL.MODE.value & ~decoded_wr_biten[3:2]) | (decoded_wr_data[3:2] & decoded_wr_biten[3:2]); + load_next_c = '1; + end + field_combo.SHA512_CTRL.MODE.next = next_c; + field_combo.SHA512_CTRL.MODE.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.SHA512_CTRL.MODE.value <= 2'h2; + end else if(field_combo.SHA512_CTRL.MODE.load_next) begin + field_storage.SHA512_CTRL.MODE.value <= field_combo.SHA512_CTRL.MODE.next; + end + end + assign hwif_out.SHA512_CTRL.MODE.value = field_storage.SHA512_CTRL.MODE.value; + // Field: sha512_reg.SHA512_CTRL.ZEROIZE + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.SHA512_CTRL.ZEROIZE.value; + load_next_c = '0; + if(decoded_reg_strb.SHA512_CTRL && decoded_req_is_wr) begin // SW write + next_c = (field_storage.SHA512_CTRL.ZEROIZE.value & ~decoded_wr_biten[4:4]) | (decoded_wr_data[4:4] & decoded_wr_biten[4:4]); + load_next_c = '1; + end else begin // singlepulse clears back to 0 + next_c = '0; + load_next_c = '1; + end + field_combo.SHA512_CTRL.ZEROIZE.next = next_c; + field_combo.SHA512_CTRL.ZEROIZE.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.SHA512_CTRL.ZEROIZE.value <= 1'h0; + end else if(field_combo.SHA512_CTRL.ZEROIZE.load_next) begin + field_storage.SHA512_CTRL.ZEROIZE.value <= field_combo.SHA512_CTRL.ZEROIZE.next; + end + end + assign hwif_out.SHA512_CTRL.ZEROIZE.value = field_storage.SHA512_CTRL.ZEROIZE.value; + // Field: sha512_reg.SHA512_CTRL.LAST + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.SHA512_CTRL.LAST.value; + load_next_c = '0; + if(decoded_reg_strb.SHA512_CTRL && decoded_req_is_wr && hwif_in.sha512_ready) begin // SW write + next_c = (field_storage.SHA512_CTRL.LAST.value & ~decoded_wr_biten[5:5]) | (decoded_wr_data[5:5] & decoded_wr_biten[5:5]); + load_next_c = '1; + end else if(hwif_in.SHA512_CTRL.LAST.hwclr) begin // HW Clear + next_c = '0; + load_next_c = '1; + end + field_combo.SHA512_CTRL.LAST.next = next_c; + field_combo.SHA512_CTRL.LAST.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.SHA512_CTRL.LAST.value <= 1'h0; + end else if(field_combo.SHA512_CTRL.LAST.load_next) begin + field_storage.SHA512_CTRL.LAST.value <= field_combo.SHA512_CTRL.LAST.next; + end + end + assign hwif_out.SHA512_CTRL.LAST.value = field_storage.SHA512_CTRL.LAST.value; + // Field: sha512_reg.SHA512_CTRL.RESTORE + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.SHA512_CTRL.RESTORE.value; + load_next_c = '0; + if(decoded_reg_strb.SHA512_CTRL && decoded_req_is_wr && hwif_in.sha512_ready) begin // SW write + next_c = (field_storage.SHA512_CTRL.RESTORE.value & ~decoded_wr_biten[6:6]) | (decoded_wr_data[6:6] & decoded_wr_biten[6:6]); + load_next_c = '1; + end else begin // singlepulse clears back to 0 + next_c = '0; + load_next_c = '1; + end + field_combo.SHA512_CTRL.RESTORE.next = next_c; + field_combo.SHA512_CTRL.RESTORE.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.SHA512_CTRL.RESTORE.value <= 1'h0; + end else if(field_combo.SHA512_CTRL.RESTORE.load_next) begin + field_storage.SHA512_CTRL.RESTORE.value <= field_combo.SHA512_CTRL.RESTORE.next; + end + end + assign hwif_out.SHA512_CTRL.RESTORE.value = field_storage.SHA512_CTRL.RESTORE.value; + for(genvar i0=0; i0<32; i0++) begin + // Field: sha512_reg.SHA512_BLOCK[].BLOCK + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.SHA512_BLOCK[i0].BLOCK.value; + load_next_c = '0; + if(decoded_reg_strb.SHA512_BLOCK[i0] && decoded_req_is_wr && !(hwif_in.SHA512_BLOCK[i0].BLOCK.swwel)) begin // SW write + next_c = (field_storage.SHA512_BLOCK[i0].BLOCK.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end else if(hwif_in.SHA512_BLOCK[i0].BLOCK.we) begin // HW Write - we + next_c = hwif_in.SHA512_BLOCK[i0].BLOCK.next; + load_next_c = '1; + end else if(hwif_in.SHA512_BLOCK[i0].BLOCK.hwclr) begin // HW Clear + next_c = '0; + load_next_c = '1; + end + field_combo.SHA512_BLOCK[i0].BLOCK.next = next_c; + field_combo.SHA512_BLOCK[i0].BLOCK.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.SHA512_BLOCK[i0].BLOCK.value <= 32'h0; + end else if(field_combo.SHA512_BLOCK[i0].BLOCK.load_next) begin + field_storage.SHA512_BLOCK[i0].BLOCK.value <= field_combo.SHA512_BLOCK[i0].BLOCK.next; + end + end + assign hwif_out.SHA512_BLOCK[i0].BLOCK.value = field_storage.SHA512_BLOCK[i0].BLOCK.value; + end + for(genvar i0=0; i0<16; i0++) begin + // Field: sha512_reg.SHA512_DIGEST[].DIGEST + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.SHA512_DIGEST[i0].DIGEST.value; + load_next_c = '0; + if(decoded_reg_strb.SHA512_DIGEST[i0] && decoded_req_is_wr) begin // SW write + next_c = (field_storage.SHA512_DIGEST[i0].DIGEST.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end else if(hwif_in.SHA512_DIGEST[i0].DIGEST.we) begin // HW Write - we + next_c = hwif_in.SHA512_DIGEST[i0].DIGEST.next; + load_next_c = '1; + end else if(hwif_in.SHA512_DIGEST[i0].DIGEST.hwclr) begin // HW Clear + next_c = '0; + load_next_c = '1; + end + field_combo.SHA512_DIGEST[i0].DIGEST.next = next_c; + field_combo.SHA512_DIGEST[i0].DIGEST.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.SHA512_DIGEST[i0].DIGEST.value <= 32'h0; + end else if(field_combo.SHA512_DIGEST[i0].DIGEST.load_next) begin + field_storage.SHA512_DIGEST[i0].DIGEST.value <= field_combo.SHA512_DIGEST[i0].DIGEST.next; + end + end + assign hwif_out.SHA512_DIGEST[i0].DIGEST.value = field_storage.SHA512_DIGEST[i0].DIGEST.value; + end + // Field: sha512_reg.SHA512_VAULT_RD_CTRL.read_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.SHA512_VAULT_RD_CTRL.read_en.value; + load_next_c = '0; + if(decoded_reg_strb.SHA512_VAULT_RD_CTRL && decoded_req_is_wr && hwif_in.SHA512_VAULT_RD_CTRL.read_en.swwe) begin // SW write + next_c = (field_storage.SHA512_VAULT_RD_CTRL.read_en.value & ~decoded_wr_biten[0:0]) | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end else if(hwif_in.SHA512_VAULT_RD_CTRL.read_en.hwclr) begin // HW Clear + next_c = '0; + load_next_c = '1; + end + field_combo.SHA512_VAULT_RD_CTRL.read_en.next = next_c; + field_combo.SHA512_VAULT_RD_CTRL.read_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.SHA512_VAULT_RD_CTRL.read_en.value <= 1'h0; + end else if(field_combo.SHA512_VAULT_RD_CTRL.read_en.load_next) begin + field_storage.SHA512_VAULT_RD_CTRL.read_en.value <= field_combo.SHA512_VAULT_RD_CTRL.read_en.next; + end + end + assign hwif_out.SHA512_VAULT_RD_CTRL.read_en.value = field_storage.SHA512_VAULT_RD_CTRL.read_en.value; + // Field: sha512_reg.SHA512_VAULT_RD_CTRL.read_entry + always_comb begin + automatic logic [4:0] next_c; + automatic logic load_next_c; + next_c = field_storage.SHA512_VAULT_RD_CTRL.read_entry.value; + load_next_c = '0; + if(decoded_reg_strb.SHA512_VAULT_RD_CTRL && decoded_req_is_wr && hwif_in.SHA512_VAULT_RD_CTRL.read_entry.swwe) begin // SW write + next_c = (field_storage.SHA512_VAULT_RD_CTRL.read_entry.value & ~decoded_wr_biten[5:1]) | (decoded_wr_data[5:1] & decoded_wr_biten[5:1]); + load_next_c = '1; + end + field_combo.SHA512_VAULT_RD_CTRL.read_entry.next = next_c; + field_combo.SHA512_VAULT_RD_CTRL.read_entry.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.SHA512_VAULT_RD_CTRL.read_entry.value <= 5'h0; + end else if(field_combo.SHA512_VAULT_RD_CTRL.read_entry.load_next) begin + field_storage.SHA512_VAULT_RD_CTRL.read_entry.value <= field_combo.SHA512_VAULT_RD_CTRL.read_entry.next; + end + end + assign hwif_out.SHA512_VAULT_RD_CTRL.read_entry.value = field_storage.SHA512_VAULT_RD_CTRL.read_entry.value; + // Field: sha512_reg.SHA512_VAULT_RD_CTRL.pcr_hash_extend + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.SHA512_VAULT_RD_CTRL.pcr_hash_extend.value; + load_next_c = '0; + if(decoded_reg_strb.SHA512_VAULT_RD_CTRL && decoded_req_is_wr && hwif_in.SHA512_VAULT_RD_CTRL.pcr_hash_extend.swwe) begin // SW write + next_c = (field_storage.SHA512_VAULT_RD_CTRL.pcr_hash_extend.value & ~decoded_wr_biten[6:6]) | (decoded_wr_data[6:6] & decoded_wr_biten[6:6]); + load_next_c = '1; + end + field_combo.SHA512_VAULT_RD_CTRL.pcr_hash_extend.next = next_c; + field_combo.SHA512_VAULT_RD_CTRL.pcr_hash_extend.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.SHA512_VAULT_RD_CTRL.pcr_hash_extend.value <= 1'h0; + end else if(field_combo.SHA512_VAULT_RD_CTRL.pcr_hash_extend.load_next) begin + field_storage.SHA512_VAULT_RD_CTRL.pcr_hash_extend.value <= field_combo.SHA512_VAULT_RD_CTRL.pcr_hash_extend.next; + end + end + assign hwif_out.SHA512_VAULT_RD_CTRL.pcr_hash_extend.value = field_storage.SHA512_VAULT_RD_CTRL.pcr_hash_extend.value; + // Field: sha512_reg.SHA512_VAULT_RD_CTRL.rsvd + always_comb begin + automatic logic [24:0] next_c; + automatic logic load_next_c; + next_c = field_storage.SHA512_VAULT_RD_CTRL.rsvd.value; + load_next_c = '0; + if(decoded_reg_strb.SHA512_VAULT_RD_CTRL && decoded_req_is_wr && hwif_in.SHA512_VAULT_RD_CTRL.rsvd.swwe) begin // SW write + next_c = (field_storage.SHA512_VAULT_RD_CTRL.rsvd.value & ~decoded_wr_biten[31:7]) | (decoded_wr_data[31:7] & decoded_wr_biten[31:7]); + load_next_c = '1; + end + field_combo.SHA512_VAULT_RD_CTRL.rsvd.next = next_c; + field_combo.SHA512_VAULT_RD_CTRL.rsvd.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.SHA512_VAULT_RD_CTRL.rsvd.value <= 25'h0; + end else if(field_combo.SHA512_VAULT_RD_CTRL.rsvd.load_next) begin + field_storage.SHA512_VAULT_RD_CTRL.rsvd.value <= field_combo.SHA512_VAULT_RD_CTRL.rsvd.next; + end + end + assign hwif_out.SHA512_VAULT_RD_CTRL.rsvd.value = field_storage.SHA512_VAULT_RD_CTRL.rsvd.value; + // Field: sha512_reg.SHA512_VAULT_RD_STATUS.VALID + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.SHA512_VAULT_RD_STATUS.VALID.value; + load_next_c = '0; + if(hwif_in.SHA512_VAULT_RD_STATUS.VALID.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end else if(hwif_in.SHA512_VAULT_RD_STATUS.VALID.hwclr) begin // HW Clear + next_c = '0; + load_next_c = '1; + end + field_combo.SHA512_VAULT_RD_STATUS.VALID.next = next_c; + field_combo.SHA512_VAULT_RD_STATUS.VALID.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.SHA512_VAULT_RD_STATUS.VALID.value <= 1'h0; + end else if(field_combo.SHA512_VAULT_RD_STATUS.VALID.load_next) begin + field_storage.SHA512_VAULT_RD_STATUS.VALID.value <= field_combo.SHA512_VAULT_RD_STATUS.VALID.next; + end + end + // Field: sha512_reg.SHA512_KV_WR_CTRL.write_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.SHA512_KV_WR_CTRL.write_en.value; + load_next_c = '0; + if(decoded_reg_strb.SHA512_KV_WR_CTRL && decoded_req_is_wr && hwif_in.SHA512_KV_WR_CTRL.write_en.swwe) begin // SW write + next_c = (field_storage.SHA512_KV_WR_CTRL.write_en.value & ~decoded_wr_biten[0:0]) | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end else if(hwif_in.SHA512_KV_WR_CTRL.write_en.hwclr) begin // HW Clear + next_c = '0; + load_next_c = '1; + end + field_combo.SHA512_KV_WR_CTRL.write_en.next = next_c; + field_combo.SHA512_KV_WR_CTRL.write_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.SHA512_KV_WR_CTRL.write_en.value <= 1'h0; + end else if(field_combo.SHA512_KV_WR_CTRL.write_en.load_next) begin + field_storage.SHA512_KV_WR_CTRL.write_en.value <= field_combo.SHA512_KV_WR_CTRL.write_en.next; + end + end + assign hwif_out.SHA512_KV_WR_CTRL.write_en.value = field_storage.SHA512_KV_WR_CTRL.write_en.value; + // Field: sha512_reg.SHA512_KV_WR_CTRL.write_entry + always_comb begin + automatic logic [4:0] next_c; + automatic logic load_next_c; + next_c = field_storage.SHA512_KV_WR_CTRL.write_entry.value; + load_next_c = '0; + if(decoded_reg_strb.SHA512_KV_WR_CTRL && decoded_req_is_wr && hwif_in.SHA512_KV_WR_CTRL.write_entry.swwe) begin // SW write + next_c = (field_storage.SHA512_KV_WR_CTRL.write_entry.value & ~decoded_wr_biten[5:1]) | (decoded_wr_data[5:1] & decoded_wr_biten[5:1]); + load_next_c = '1; + end + field_combo.SHA512_KV_WR_CTRL.write_entry.next = next_c; + field_combo.SHA512_KV_WR_CTRL.write_entry.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.SHA512_KV_WR_CTRL.write_entry.value <= 5'h0; + end else if(field_combo.SHA512_KV_WR_CTRL.write_entry.load_next) begin + field_storage.SHA512_KV_WR_CTRL.write_entry.value <= field_combo.SHA512_KV_WR_CTRL.write_entry.next; + end + end + assign hwif_out.SHA512_KV_WR_CTRL.write_entry.value = field_storage.SHA512_KV_WR_CTRL.write_entry.value; + // Field: sha512_reg.SHA512_KV_WR_CTRL.hmac_key_dest_valid + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.SHA512_KV_WR_CTRL.hmac_key_dest_valid.value; + load_next_c = '0; + if(decoded_reg_strb.SHA512_KV_WR_CTRL && decoded_req_is_wr && hwif_in.SHA512_KV_WR_CTRL.hmac_key_dest_valid.swwe) begin // SW write + next_c = (field_storage.SHA512_KV_WR_CTRL.hmac_key_dest_valid.value & ~decoded_wr_biten[6:6]) | (decoded_wr_data[6:6] & decoded_wr_biten[6:6]); + load_next_c = '1; + end + field_combo.SHA512_KV_WR_CTRL.hmac_key_dest_valid.next = next_c; + field_combo.SHA512_KV_WR_CTRL.hmac_key_dest_valid.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.SHA512_KV_WR_CTRL.hmac_key_dest_valid.value <= 1'h0; + end else if(field_combo.SHA512_KV_WR_CTRL.hmac_key_dest_valid.load_next) begin + field_storage.SHA512_KV_WR_CTRL.hmac_key_dest_valid.value <= field_combo.SHA512_KV_WR_CTRL.hmac_key_dest_valid.next; + end + end + assign hwif_out.SHA512_KV_WR_CTRL.hmac_key_dest_valid.value = field_storage.SHA512_KV_WR_CTRL.hmac_key_dest_valid.value; + // Field: sha512_reg.SHA512_KV_WR_CTRL.hmac_block_dest_valid + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.SHA512_KV_WR_CTRL.hmac_block_dest_valid.value; + load_next_c = '0; + if(decoded_reg_strb.SHA512_KV_WR_CTRL && decoded_req_is_wr && hwif_in.SHA512_KV_WR_CTRL.hmac_block_dest_valid.swwe) begin // SW write + next_c = (field_storage.SHA512_KV_WR_CTRL.hmac_block_dest_valid.value & ~decoded_wr_biten[7:7]) | (decoded_wr_data[7:7] & decoded_wr_biten[7:7]); + load_next_c = '1; + end + field_combo.SHA512_KV_WR_CTRL.hmac_block_dest_valid.next = next_c; + field_combo.SHA512_KV_WR_CTRL.hmac_block_dest_valid.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.SHA512_KV_WR_CTRL.hmac_block_dest_valid.value <= 1'h0; + end else if(field_combo.SHA512_KV_WR_CTRL.hmac_block_dest_valid.load_next) begin + field_storage.SHA512_KV_WR_CTRL.hmac_block_dest_valid.value <= field_combo.SHA512_KV_WR_CTRL.hmac_block_dest_valid.next; + end + end + assign hwif_out.SHA512_KV_WR_CTRL.hmac_block_dest_valid.value = field_storage.SHA512_KV_WR_CTRL.hmac_block_dest_valid.value; + // Field: sha512_reg.SHA512_KV_WR_CTRL.mldsa_seed_dest_valid + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.SHA512_KV_WR_CTRL.mldsa_seed_dest_valid.value; + load_next_c = '0; + if(decoded_reg_strb.SHA512_KV_WR_CTRL && decoded_req_is_wr && hwif_in.SHA512_KV_WR_CTRL.mldsa_seed_dest_valid.swwe) begin // SW write + next_c = (field_storage.SHA512_KV_WR_CTRL.mldsa_seed_dest_valid.value & ~decoded_wr_biten[8:8]) | (decoded_wr_data[8:8] & decoded_wr_biten[8:8]); + load_next_c = '1; + end + field_combo.SHA512_KV_WR_CTRL.mldsa_seed_dest_valid.next = next_c; + field_combo.SHA512_KV_WR_CTRL.mldsa_seed_dest_valid.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.SHA512_KV_WR_CTRL.mldsa_seed_dest_valid.value <= 1'h0; + end else if(field_combo.SHA512_KV_WR_CTRL.mldsa_seed_dest_valid.load_next) begin + field_storage.SHA512_KV_WR_CTRL.mldsa_seed_dest_valid.value <= field_combo.SHA512_KV_WR_CTRL.mldsa_seed_dest_valid.next; + end + end + assign hwif_out.SHA512_KV_WR_CTRL.mldsa_seed_dest_valid.value = field_storage.SHA512_KV_WR_CTRL.mldsa_seed_dest_valid.value; + // Field: sha512_reg.SHA512_KV_WR_CTRL.ecc_pkey_dest_valid + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.SHA512_KV_WR_CTRL.ecc_pkey_dest_valid.value; + load_next_c = '0; + if(decoded_reg_strb.SHA512_KV_WR_CTRL && decoded_req_is_wr && hwif_in.SHA512_KV_WR_CTRL.ecc_pkey_dest_valid.swwe) begin // SW write + next_c = (field_storage.SHA512_KV_WR_CTRL.ecc_pkey_dest_valid.value & ~decoded_wr_biten[9:9]) | (decoded_wr_data[9:9] & decoded_wr_biten[9:9]); + load_next_c = '1; + end + field_combo.SHA512_KV_WR_CTRL.ecc_pkey_dest_valid.next = next_c; + field_combo.SHA512_KV_WR_CTRL.ecc_pkey_dest_valid.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.SHA512_KV_WR_CTRL.ecc_pkey_dest_valid.value <= 1'h0; + end else if(field_combo.SHA512_KV_WR_CTRL.ecc_pkey_dest_valid.load_next) begin + field_storage.SHA512_KV_WR_CTRL.ecc_pkey_dest_valid.value <= field_combo.SHA512_KV_WR_CTRL.ecc_pkey_dest_valid.next; + end + end + assign hwif_out.SHA512_KV_WR_CTRL.ecc_pkey_dest_valid.value = field_storage.SHA512_KV_WR_CTRL.ecc_pkey_dest_valid.value; + // Field: sha512_reg.SHA512_KV_WR_CTRL.ecc_seed_dest_valid + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.SHA512_KV_WR_CTRL.ecc_seed_dest_valid.value; + load_next_c = '0; + if(decoded_reg_strb.SHA512_KV_WR_CTRL && decoded_req_is_wr && hwif_in.SHA512_KV_WR_CTRL.ecc_seed_dest_valid.swwe) begin // SW write + next_c = (field_storage.SHA512_KV_WR_CTRL.ecc_seed_dest_valid.value & ~decoded_wr_biten[10:10]) | (decoded_wr_data[10:10] & decoded_wr_biten[10:10]); + load_next_c = '1; + end + field_combo.SHA512_KV_WR_CTRL.ecc_seed_dest_valid.next = next_c; + field_combo.SHA512_KV_WR_CTRL.ecc_seed_dest_valid.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.SHA512_KV_WR_CTRL.ecc_seed_dest_valid.value <= 1'h0; + end else if(field_combo.SHA512_KV_WR_CTRL.ecc_seed_dest_valid.load_next) begin + field_storage.SHA512_KV_WR_CTRL.ecc_seed_dest_valid.value <= field_combo.SHA512_KV_WR_CTRL.ecc_seed_dest_valid.next; + end + end + assign hwif_out.SHA512_KV_WR_CTRL.ecc_seed_dest_valid.value = field_storage.SHA512_KV_WR_CTRL.ecc_seed_dest_valid.value; + // Field: sha512_reg.SHA512_KV_WR_CTRL.aes_key_dest_valid + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.SHA512_KV_WR_CTRL.aes_key_dest_valid.value; + load_next_c = '0; + if(decoded_reg_strb.SHA512_KV_WR_CTRL && decoded_req_is_wr && hwif_in.SHA512_KV_WR_CTRL.aes_key_dest_valid.swwe) begin // SW write + next_c = (field_storage.SHA512_KV_WR_CTRL.aes_key_dest_valid.value & ~decoded_wr_biten[11:11]) | (decoded_wr_data[11:11] & decoded_wr_biten[11:11]); + load_next_c = '1; + end + field_combo.SHA512_KV_WR_CTRL.aes_key_dest_valid.next = next_c; + field_combo.SHA512_KV_WR_CTRL.aes_key_dest_valid.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.SHA512_KV_WR_CTRL.aes_key_dest_valid.value <= 1'h0; + end else if(field_combo.SHA512_KV_WR_CTRL.aes_key_dest_valid.load_next) begin + field_storage.SHA512_KV_WR_CTRL.aes_key_dest_valid.value <= field_combo.SHA512_KV_WR_CTRL.aes_key_dest_valid.next; + end + end + assign hwif_out.SHA512_KV_WR_CTRL.aes_key_dest_valid.value = field_storage.SHA512_KV_WR_CTRL.aes_key_dest_valid.value; + // Field: sha512_reg.SHA512_KV_WR_CTRL.mlkem_seed_dest_valid + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.SHA512_KV_WR_CTRL.mlkem_seed_dest_valid.value; + load_next_c = '0; + if(decoded_reg_strb.SHA512_KV_WR_CTRL && decoded_req_is_wr && hwif_in.SHA512_KV_WR_CTRL.mlkem_seed_dest_valid.swwe) begin // SW write + next_c = (field_storage.SHA512_KV_WR_CTRL.mlkem_seed_dest_valid.value & ~decoded_wr_biten[12:12]) | (decoded_wr_data[12:12] & decoded_wr_biten[12:12]); + load_next_c = '1; + end + field_combo.SHA512_KV_WR_CTRL.mlkem_seed_dest_valid.next = next_c; + field_combo.SHA512_KV_WR_CTRL.mlkem_seed_dest_valid.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.SHA512_KV_WR_CTRL.mlkem_seed_dest_valid.value <= 1'h0; + end else if(field_combo.SHA512_KV_WR_CTRL.mlkem_seed_dest_valid.load_next) begin + field_storage.SHA512_KV_WR_CTRL.mlkem_seed_dest_valid.value <= field_combo.SHA512_KV_WR_CTRL.mlkem_seed_dest_valid.next; + end + end + assign hwif_out.SHA512_KV_WR_CTRL.mlkem_seed_dest_valid.value = field_storage.SHA512_KV_WR_CTRL.mlkem_seed_dest_valid.value; + // Field: sha512_reg.SHA512_KV_WR_CTRL.mlkem_msg_dest_valid + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.SHA512_KV_WR_CTRL.mlkem_msg_dest_valid.value; + load_next_c = '0; + if(decoded_reg_strb.SHA512_KV_WR_CTRL && decoded_req_is_wr && hwif_in.SHA512_KV_WR_CTRL.mlkem_msg_dest_valid.swwe) begin // SW write + next_c = (field_storage.SHA512_KV_WR_CTRL.mlkem_msg_dest_valid.value & ~decoded_wr_biten[13:13]) | (decoded_wr_data[13:13] & decoded_wr_biten[13:13]); + load_next_c = '1; + end + field_combo.SHA512_KV_WR_CTRL.mlkem_msg_dest_valid.next = next_c; + field_combo.SHA512_KV_WR_CTRL.mlkem_msg_dest_valid.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.SHA512_KV_WR_CTRL.mlkem_msg_dest_valid.value <= 1'h0; + end else if(field_combo.SHA512_KV_WR_CTRL.mlkem_msg_dest_valid.load_next) begin + field_storage.SHA512_KV_WR_CTRL.mlkem_msg_dest_valid.value <= field_combo.SHA512_KV_WR_CTRL.mlkem_msg_dest_valid.next; + end + end + assign hwif_out.SHA512_KV_WR_CTRL.mlkem_msg_dest_valid.value = field_storage.SHA512_KV_WR_CTRL.mlkem_msg_dest_valid.value; + // Field: sha512_reg.SHA512_KV_WR_CTRL.dma_data_dest_valid + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.SHA512_KV_WR_CTRL.dma_data_dest_valid.value; + load_next_c = '0; + if(decoded_reg_strb.SHA512_KV_WR_CTRL && decoded_req_is_wr && hwif_in.SHA512_KV_WR_CTRL.dma_data_dest_valid.swwe) begin // SW write + next_c = (field_storage.SHA512_KV_WR_CTRL.dma_data_dest_valid.value & ~decoded_wr_biten[14:14]) | (decoded_wr_data[14:14] & decoded_wr_biten[14:14]); + load_next_c = '1; + end + field_combo.SHA512_KV_WR_CTRL.dma_data_dest_valid.next = next_c; + field_combo.SHA512_KV_WR_CTRL.dma_data_dest_valid.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.SHA512_KV_WR_CTRL.dma_data_dest_valid.value <= 1'h0; + end else if(field_combo.SHA512_KV_WR_CTRL.dma_data_dest_valid.load_next) begin + field_storage.SHA512_KV_WR_CTRL.dma_data_dest_valid.value <= field_combo.SHA512_KV_WR_CTRL.dma_data_dest_valid.next; + end + end + assign hwif_out.SHA512_KV_WR_CTRL.dma_data_dest_valid.value = field_storage.SHA512_KV_WR_CTRL.dma_data_dest_valid.value; + // Field: sha512_reg.SHA512_KV_WR_CTRL.rsvd + always_comb begin + automatic logic [16:0] next_c; + automatic logic load_next_c; + next_c = field_storage.SHA512_KV_WR_CTRL.rsvd.value; + load_next_c = '0; + if(decoded_reg_strb.SHA512_KV_WR_CTRL && decoded_req_is_wr && hwif_in.SHA512_KV_WR_CTRL.rsvd.swwe) begin // SW write + next_c = (field_storage.SHA512_KV_WR_CTRL.rsvd.value & ~decoded_wr_biten[31:15]) | (decoded_wr_data[31:15] & decoded_wr_biten[31:15]); + load_next_c = '1; + end + field_combo.SHA512_KV_WR_CTRL.rsvd.next = next_c; + field_combo.SHA512_KV_WR_CTRL.rsvd.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.SHA512_KV_WR_CTRL.rsvd.value <= 17'h0; + end else if(field_combo.SHA512_KV_WR_CTRL.rsvd.load_next) begin + field_storage.SHA512_KV_WR_CTRL.rsvd.value <= field_combo.SHA512_KV_WR_CTRL.rsvd.next; + end + end + assign hwif_out.SHA512_KV_WR_CTRL.rsvd.value = field_storage.SHA512_KV_WR_CTRL.rsvd.value; + // Field: sha512_reg.SHA512_KV_WR_STATUS.VALID + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.SHA512_KV_WR_STATUS.VALID.value; + load_next_c = '0; + if(hwif_in.SHA512_KV_WR_STATUS.VALID.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end else if(hwif_in.SHA512_KV_WR_STATUS.VALID.hwclr) begin // HW Clear + next_c = '0; + load_next_c = '1; + end + field_combo.SHA512_KV_WR_STATUS.VALID.next = next_c; + field_combo.SHA512_KV_WR_STATUS.VALID.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.SHA512_KV_WR_STATUS.VALID.value <= 1'h0; + end else if(field_combo.SHA512_KV_WR_STATUS.VALID.load_next) begin + field_storage.SHA512_KV_WR_STATUS.VALID.value <= field_combo.SHA512_KV_WR_STATUS.VALID.next; + end + end + for(genvar i0=0; i0<8; i0++) begin + // Field: sha512_reg.SHA512_GEN_PCR_HASH_NONCE[].NONCE + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.SHA512_GEN_PCR_HASH_NONCE[i0].NONCE.value; + load_next_c = '0; + if(decoded_reg_strb.SHA512_GEN_PCR_HASH_NONCE[i0] && decoded_req_is_wr) begin // SW write + next_c = (field_storage.SHA512_GEN_PCR_HASH_NONCE[i0].NONCE.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + field_combo.SHA512_GEN_PCR_HASH_NONCE[i0].NONCE.next = next_c; + field_combo.SHA512_GEN_PCR_HASH_NONCE[i0].NONCE.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.SHA512_GEN_PCR_HASH_NONCE[i0].NONCE.value <= 32'h0; + end else if(field_combo.SHA512_GEN_PCR_HASH_NONCE[i0].NONCE.load_next) begin + field_storage.SHA512_GEN_PCR_HASH_NONCE[i0].NONCE.value <= field_combo.SHA512_GEN_PCR_HASH_NONCE[i0].NONCE.next; + end + end + assign hwif_out.SHA512_GEN_PCR_HASH_NONCE[i0].NONCE.value = field_storage.SHA512_GEN_PCR_HASH_NONCE[i0].NONCE.value; + end + // Field: sha512_reg.SHA512_GEN_PCR_HASH_CTRL.START + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.SHA512_GEN_PCR_HASH_CTRL.START.value; + load_next_c = '0; + if(decoded_reg_strb.SHA512_GEN_PCR_HASH_CTRL && decoded_req_is_wr && hwif_in.sha512_ready) begin // SW write + next_c = (field_storage.SHA512_GEN_PCR_HASH_CTRL.START.value & ~decoded_wr_biten[0:0]) | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end else begin // singlepulse clears back to 0 + next_c = '0; + load_next_c = '1; + end + field_combo.SHA512_GEN_PCR_HASH_CTRL.START.next = next_c; + field_combo.SHA512_GEN_PCR_HASH_CTRL.START.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.SHA512_GEN_PCR_HASH_CTRL.START.value <= 1'h0; + end else if(field_combo.SHA512_GEN_PCR_HASH_CTRL.START.load_next) begin + field_storage.SHA512_GEN_PCR_HASH_CTRL.START.value <= field_combo.SHA512_GEN_PCR_HASH_CTRL.START.next; + end + end + assign hwif_out.SHA512_GEN_PCR_HASH_CTRL.START.value = field_storage.SHA512_GEN_PCR_HASH_CTRL.START.value; + // Field: sha512_reg.SHA512_GEN_PCR_HASH_STATUS.VALID + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.SHA512_GEN_PCR_HASH_STATUS.VALID.value; + load_next_c = '0; + if(hwif_in.SHA512_GEN_PCR_HASH_STATUS.VALID.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end else if(hwif_in.SHA512_GEN_PCR_HASH_STATUS.VALID.hwclr) begin // HW Clear + next_c = '0; + load_next_c = '1; + end + field_combo.SHA512_GEN_PCR_HASH_STATUS.VALID.next = next_c; + field_combo.SHA512_GEN_PCR_HASH_STATUS.VALID.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.SHA512_GEN_PCR_HASH_STATUS.VALID.value <= 1'h0; + end else if(field_combo.SHA512_GEN_PCR_HASH_STATUS.VALID.load_next) begin + field_storage.SHA512_GEN_PCR_HASH_STATUS.VALID.value <= field_combo.SHA512_GEN_PCR_HASH_STATUS.VALID.next; + end + end + for(genvar i0=0; i0<16; i0++) begin + // Field: sha512_reg.SHA512_GEN_PCR_HASH_DIGEST[].DIGEST + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.SHA512_GEN_PCR_HASH_DIGEST[i0].DIGEST.value; + load_next_c = '0; + if(hwif_in.SHA512_GEN_PCR_HASH_DIGEST[i0].DIGEST.hwclr) begin // HW Clear + next_c = '0; + load_next_c = '1; + end else begin // HW Write + next_c = hwif_in.SHA512_GEN_PCR_HASH_DIGEST[i0].DIGEST.next; + load_next_c = '1; + end + field_combo.SHA512_GEN_PCR_HASH_DIGEST[i0].DIGEST.next = next_c; + field_combo.SHA512_GEN_PCR_HASH_DIGEST[i0].DIGEST.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.SHA512_GEN_PCR_HASH_DIGEST[i0].DIGEST.value <= 32'h0; + end else if(field_combo.SHA512_GEN_PCR_HASH_DIGEST[i0].DIGEST.load_next) begin + field_storage.SHA512_GEN_PCR_HASH_DIGEST[i0].DIGEST.value <= field_combo.SHA512_GEN_PCR_HASH_DIGEST[i0].DIGEST.next; + end + end + end + // Field: sha512_reg.intr_block_rf.global_intr_en_r.error_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.global_intr_en_r.error_en.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.global_intr_en_r && decoded_req_is_wr) begin // SW write + next_c = (field_storage.intr_block_rf.global_intr_en_r.error_en.value & ~decoded_wr_biten[0:0]) | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end + field_combo.intr_block_rf.global_intr_en_r.error_en.next = next_c; + field_combo.intr_block_rf.global_intr_en_r.error_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.global_intr_en_r.error_en.value <= 1'h0; + end else if(field_combo.intr_block_rf.global_intr_en_r.error_en.load_next) begin + field_storage.intr_block_rf.global_intr_en_r.error_en.value <= field_combo.intr_block_rf.global_intr_en_r.error_en.next; + end + end + // Field: sha512_reg.intr_block_rf.global_intr_en_r.notif_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.global_intr_en_r.notif_en.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.global_intr_en_r && decoded_req_is_wr) begin // SW write + next_c = (field_storage.intr_block_rf.global_intr_en_r.notif_en.value & ~decoded_wr_biten[1:1]) | (decoded_wr_data[1:1] & decoded_wr_biten[1:1]); + load_next_c = '1; + end + field_combo.intr_block_rf.global_intr_en_r.notif_en.next = next_c; + field_combo.intr_block_rf.global_intr_en_r.notif_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.global_intr_en_r.notif_en.value <= 1'h0; + end else if(field_combo.intr_block_rf.global_intr_en_r.notif_en.load_next) begin + field_storage.intr_block_rf.global_intr_en_r.notif_en.value <= field_combo.intr_block_rf.global_intr_en_r.notif_en.next; + end + end + // Field: sha512_reg.intr_block_rf.error_intr_en_r.error0_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_intr_en_r.error0_en.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_intr_en_r && decoded_req_is_wr) begin // SW write + next_c = (field_storage.intr_block_rf.error_intr_en_r.error0_en.value & ~decoded_wr_biten[0:0]) | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end + field_combo.intr_block_rf.error_intr_en_r.error0_en.next = next_c; + field_combo.intr_block_rf.error_intr_en_r.error0_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.error_intr_en_r.error0_en.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_intr_en_r.error0_en.load_next) begin + field_storage.intr_block_rf.error_intr_en_r.error0_en.value <= field_combo.intr_block_rf.error_intr_en_r.error0_en.next; + end + end + // Field: sha512_reg.intr_block_rf.error_intr_en_r.error1_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_intr_en_r.error1_en.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_intr_en_r && decoded_req_is_wr) begin // SW write + next_c = (field_storage.intr_block_rf.error_intr_en_r.error1_en.value & ~decoded_wr_biten[1:1]) | (decoded_wr_data[1:1] & decoded_wr_biten[1:1]); + load_next_c = '1; + end + field_combo.intr_block_rf.error_intr_en_r.error1_en.next = next_c; + field_combo.intr_block_rf.error_intr_en_r.error1_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.error_intr_en_r.error1_en.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_intr_en_r.error1_en.load_next) begin + field_storage.intr_block_rf.error_intr_en_r.error1_en.value <= field_combo.intr_block_rf.error_intr_en_r.error1_en.next; + end + end + // Field: sha512_reg.intr_block_rf.error_intr_en_r.error2_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_intr_en_r.error2_en.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_intr_en_r && decoded_req_is_wr) begin // SW write + next_c = (field_storage.intr_block_rf.error_intr_en_r.error2_en.value & ~decoded_wr_biten[2:2]) | (decoded_wr_data[2:2] & decoded_wr_biten[2:2]); + load_next_c = '1; + end + field_combo.intr_block_rf.error_intr_en_r.error2_en.next = next_c; + field_combo.intr_block_rf.error_intr_en_r.error2_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.error_intr_en_r.error2_en.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_intr_en_r.error2_en.load_next) begin + field_storage.intr_block_rf.error_intr_en_r.error2_en.value <= field_combo.intr_block_rf.error_intr_en_r.error2_en.next; + end + end + // Field: sha512_reg.intr_block_rf.error_intr_en_r.error3_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_intr_en_r.error3_en.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_intr_en_r && decoded_req_is_wr) begin // SW write + next_c = (field_storage.intr_block_rf.error_intr_en_r.error3_en.value & ~decoded_wr_biten[3:3]) | (decoded_wr_data[3:3] & decoded_wr_biten[3:3]); + load_next_c = '1; + end + field_combo.intr_block_rf.error_intr_en_r.error3_en.next = next_c; + field_combo.intr_block_rf.error_intr_en_r.error3_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.error_intr_en_r.error3_en.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_intr_en_r.error3_en.load_next) begin + field_storage.intr_block_rf.error_intr_en_r.error3_en.value <= field_combo.intr_block_rf.error_intr_en_r.error3_en.next; + end + end + // Field: sha512_reg.intr_block_rf.notif_intr_en_r.notif_cmd_done_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_intr_en_r.notif_cmd_done_en.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.notif_intr_en_r && decoded_req_is_wr) begin // SW write + next_c = (field_storage.intr_block_rf.notif_intr_en_r.notif_cmd_done_en.value & ~decoded_wr_biten[0:0]) | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end + field_combo.intr_block_rf.notif_intr_en_r.notif_cmd_done_en.next = next_c; + field_combo.intr_block_rf.notif_intr_en_r.notif_cmd_done_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.notif_intr_en_r.notif_cmd_done_en.value <= 1'h0; + end else if(field_combo.intr_block_rf.notif_intr_en_r.notif_cmd_done_en.load_next) begin + field_storage.intr_block_rf.notif_intr_en_r.notif_cmd_done_en.value <= field_combo.intr_block_rf.notif_intr_en_r.notif_cmd_done_en.next; + end + end + // Field: sha512_reg.intr_block_rf.error_global_intr_r.agg_sts + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_global_intr_r.agg_sts.value; + load_next_c = '0; + + // HW Write + next_c = hwif_out.intr_block_rf.error_internal_intr_r.intr; + load_next_c = '1; + field_combo.intr_block_rf.error_global_intr_r.agg_sts.next = next_c; + field_combo.intr_block_rf.error_global_intr_r.agg_sts.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.error_global_intr_r.agg_sts.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_global_intr_r.agg_sts.load_next) begin + field_storage.intr_block_rf.error_global_intr_r.agg_sts.value <= field_combo.intr_block_rf.error_global_intr_r.agg_sts.next; + end + end + assign hwif_out.intr_block_rf.error_global_intr_r.intr = + |(field_storage.intr_block_rf.error_global_intr_r.agg_sts.value & field_storage.intr_block_rf.global_intr_en_r.error_en.value); + // Field: sha512_reg.intr_block_rf.notif_global_intr_r.agg_sts + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_global_intr_r.agg_sts.value; + load_next_c = '0; + + // HW Write + next_c = hwif_out.intr_block_rf.notif_internal_intr_r.intr; + load_next_c = '1; + field_combo.intr_block_rf.notif_global_intr_r.agg_sts.next = next_c; + field_combo.intr_block_rf.notif_global_intr_r.agg_sts.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.notif_global_intr_r.agg_sts.value <= 1'h0; + end else if(field_combo.intr_block_rf.notif_global_intr_r.agg_sts.load_next) begin + field_storage.intr_block_rf.notif_global_intr_r.agg_sts.value <= field_combo.intr_block_rf.notif_global_intr_r.agg_sts.next; + end + end + assign hwif_out.intr_block_rf.notif_global_intr_r.intr = + |(field_storage.intr_block_rf.notif_global_intr_r.agg_sts.value & field_storage.intr_block_rf.global_intr_en_r.notif_en.value); + // Field: sha512_reg.intr_block_rf.error_internal_intr_r.error0_sts + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_internal_intr_r.error0_sts.value; + load_next_c = '0; + if(field_storage.intr_block_rf.error_intr_trig_r.error0_trig.value != '0) begin // stickybit + next_c = field_storage.intr_block_rf.error_internal_intr_r.error0_sts.value | field_storage.intr_block_rf.error_intr_trig_r.error0_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.error_internal_intr_r.error0_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end else if(decoded_reg_strb.intr_block_rf.error_internal_intr_r && decoded_req_is_wr) begin // SW write 1 clear + next_c = field_storage.intr_block_rf.error_internal_intr_r.error0_sts.value & ~(decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end + field_combo.intr_block_rf.error_internal_intr_r.error0_sts.next = next_c; + field_combo.intr_block_rf.error_internal_intr_r.error0_sts.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.error_reset_b) begin + if(~hwif_in.error_reset_b) begin + field_storage.intr_block_rf.error_internal_intr_r.error0_sts.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_internal_intr_r.error0_sts.load_next) begin + field_storage.intr_block_rf.error_internal_intr_r.error0_sts.value <= field_combo.intr_block_rf.error_internal_intr_r.error0_sts.next; + end + end + // Field: sha512_reg.intr_block_rf.error_internal_intr_r.error1_sts + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_internal_intr_r.error1_sts.value; + load_next_c = '0; + if(field_storage.intr_block_rf.error_intr_trig_r.error1_trig.value != '0) begin // stickybit + next_c = field_storage.intr_block_rf.error_internal_intr_r.error1_sts.value | field_storage.intr_block_rf.error_intr_trig_r.error1_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.error_internal_intr_r.error1_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end else if(decoded_reg_strb.intr_block_rf.error_internal_intr_r && decoded_req_is_wr) begin // SW write 1 clear + next_c = field_storage.intr_block_rf.error_internal_intr_r.error1_sts.value & ~(decoded_wr_data[1:1] & decoded_wr_biten[1:1]); + load_next_c = '1; + end + field_combo.intr_block_rf.error_internal_intr_r.error1_sts.next = next_c; + field_combo.intr_block_rf.error_internal_intr_r.error1_sts.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.error_reset_b) begin + if(~hwif_in.error_reset_b) begin + field_storage.intr_block_rf.error_internal_intr_r.error1_sts.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_internal_intr_r.error1_sts.load_next) begin + field_storage.intr_block_rf.error_internal_intr_r.error1_sts.value <= field_combo.intr_block_rf.error_internal_intr_r.error1_sts.next; + end + end + // Field: sha512_reg.intr_block_rf.error_internal_intr_r.error2_sts + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_internal_intr_r.error2_sts.value; + load_next_c = '0; + if(field_storage.intr_block_rf.error_intr_trig_r.error2_trig.value != '0) begin // stickybit + next_c = field_storage.intr_block_rf.error_internal_intr_r.error2_sts.value | field_storage.intr_block_rf.error_intr_trig_r.error2_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.error_internal_intr_r.error2_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end else if(decoded_reg_strb.intr_block_rf.error_internal_intr_r && decoded_req_is_wr) begin // SW write 1 clear + next_c = field_storage.intr_block_rf.error_internal_intr_r.error2_sts.value & ~(decoded_wr_data[2:2] & decoded_wr_biten[2:2]); + load_next_c = '1; + end + field_combo.intr_block_rf.error_internal_intr_r.error2_sts.next = next_c; + field_combo.intr_block_rf.error_internal_intr_r.error2_sts.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.error_reset_b) begin + if(~hwif_in.error_reset_b) begin + field_storage.intr_block_rf.error_internal_intr_r.error2_sts.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_internal_intr_r.error2_sts.load_next) begin + field_storage.intr_block_rf.error_internal_intr_r.error2_sts.value <= field_combo.intr_block_rf.error_internal_intr_r.error2_sts.next; + end + end + // Field: sha512_reg.intr_block_rf.error_internal_intr_r.error3_sts + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_internal_intr_r.error3_sts.value; + load_next_c = '0; + if(field_storage.intr_block_rf.error_intr_trig_r.error3_trig.value != '0) begin // stickybit + next_c = field_storage.intr_block_rf.error_internal_intr_r.error3_sts.value | field_storage.intr_block_rf.error_intr_trig_r.error3_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.error_internal_intr_r.error3_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end else if(decoded_reg_strb.intr_block_rf.error_internal_intr_r && decoded_req_is_wr) begin // SW write 1 clear + next_c = field_storage.intr_block_rf.error_internal_intr_r.error3_sts.value & ~(decoded_wr_data[3:3] & decoded_wr_biten[3:3]); + load_next_c = '1; + end + field_combo.intr_block_rf.error_internal_intr_r.error3_sts.next = next_c; + field_combo.intr_block_rf.error_internal_intr_r.error3_sts.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.error_reset_b) begin + if(~hwif_in.error_reset_b) begin + field_storage.intr_block_rf.error_internal_intr_r.error3_sts.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_internal_intr_r.error3_sts.load_next) begin + field_storage.intr_block_rf.error_internal_intr_r.error3_sts.value <= field_combo.intr_block_rf.error_internal_intr_r.error3_sts.next; + end + end + assign hwif_out.intr_block_rf.error_internal_intr_r.intr = + |(field_storage.intr_block_rf.error_internal_intr_r.error0_sts.value & field_storage.intr_block_rf.error_intr_en_r.error0_en.value) + || |(field_storage.intr_block_rf.error_internal_intr_r.error1_sts.value & field_storage.intr_block_rf.error_intr_en_r.error1_en.value) + || |(field_storage.intr_block_rf.error_internal_intr_r.error2_sts.value & field_storage.intr_block_rf.error_intr_en_r.error2_en.value) + || |(field_storage.intr_block_rf.error_internal_intr_r.error3_sts.value & field_storage.intr_block_rf.error_intr_en_r.error3_en.value); + // Field: sha512_reg.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.value; + load_next_c = '0; + if(field_storage.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.value != '0) begin // stickybit + next_c = field_storage.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.value | field_storage.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end else if(decoded_reg_strb.intr_block_rf.notif_internal_intr_r && decoded_req_is_wr) begin // SW write 1 clear + next_c = field_storage.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.value & ~(decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end + field_combo.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.next = next_c; + field_combo.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.value <= 1'h0; + end else if(field_combo.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.load_next) begin + field_storage.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.value <= field_combo.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.next; + end + end + assign hwif_out.intr_block_rf.notif_internal_intr_r.intr = + |(field_storage.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.value & field_storage.intr_block_rf.notif_intr_en_r.notif_cmd_done_en.value); + // Field: sha512_reg.intr_block_rf.error_intr_trig_r.error0_trig + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_intr_trig_r.error0_trig.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_intr_trig_r && decoded_req_is_wr) begin // SW write 1 set + next_c = field_storage.intr_block_rf.error_intr_trig_r.error0_trig.value | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end else begin // singlepulse clears back to 0 + next_c = '0; + load_next_c = '1; + end + field_combo.intr_block_rf.error_intr_trig_r.error0_trig.next = next_c; + field_combo.intr_block_rf.error_intr_trig_r.error0_trig.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.error_intr_trig_r.error0_trig.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_intr_trig_r.error0_trig.load_next) begin + field_storage.intr_block_rf.error_intr_trig_r.error0_trig.value <= field_combo.intr_block_rf.error_intr_trig_r.error0_trig.next; + end + end + // Field: sha512_reg.intr_block_rf.error_intr_trig_r.error1_trig + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_intr_trig_r.error1_trig.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_intr_trig_r && decoded_req_is_wr) begin // SW write 1 set + next_c = field_storage.intr_block_rf.error_intr_trig_r.error1_trig.value | (decoded_wr_data[1:1] & decoded_wr_biten[1:1]); + load_next_c = '1; + end else begin // singlepulse clears back to 0 + next_c = '0; + load_next_c = '1; + end + field_combo.intr_block_rf.error_intr_trig_r.error1_trig.next = next_c; + field_combo.intr_block_rf.error_intr_trig_r.error1_trig.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.error_intr_trig_r.error1_trig.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_intr_trig_r.error1_trig.load_next) begin + field_storage.intr_block_rf.error_intr_trig_r.error1_trig.value <= field_combo.intr_block_rf.error_intr_trig_r.error1_trig.next; + end + end + // Field: sha512_reg.intr_block_rf.error_intr_trig_r.error2_trig + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_intr_trig_r.error2_trig.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_intr_trig_r && decoded_req_is_wr) begin // SW write 1 set + next_c = field_storage.intr_block_rf.error_intr_trig_r.error2_trig.value | (decoded_wr_data[2:2] & decoded_wr_biten[2:2]); + load_next_c = '1; + end else begin // singlepulse clears back to 0 + next_c = '0; + load_next_c = '1; + end + field_combo.intr_block_rf.error_intr_trig_r.error2_trig.next = next_c; + field_combo.intr_block_rf.error_intr_trig_r.error2_trig.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.error_intr_trig_r.error2_trig.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_intr_trig_r.error2_trig.load_next) begin + field_storage.intr_block_rf.error_intr_trig_r.error2_trig.value <= field_combo.intr_block_rf.error_intr_trig_r.error2_trig.next; + end + end + // Field: sha512_reg.intr_block_rf.error_intr_trig_r.error3_trig + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_intr_trig_r.error3_trig.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_intr_trig_r && decoded_req_is_wr) begin // SW write 1 set + next_c = field_storage.intr_block_rf.error_intr_trig_r.error3_trig.value | (decoded_wr_data[3:3] & decoded_wr_biten[3:3]); + load_next_c = '1; + end else begin // singlepulse clears back to 0 + next_c = '0; + load_next_c = '1; + end + field_combo.intr_block_rf.error_intr_trig_r.error3_trig.next = next_c; + field_combo.intr_block_rf.error_intr_trig_r.error3_trig.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.error_intr_trig_r.error3_trig.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_intr_trig_r.error3_trig.load_next) begin + field_storage.intr_block_rf.error_intr_trig_r.error3_trig.value <= field_combo.intr_block_rf.error_intr_trig_r.error3_trig.next; + end + end + // Field: sha512_reg.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.notif_intr_trig_r && decoded_req_is_wr) begin // SW write 1 set + next_c = field_storage.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.value | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end else begin // singlepulse clears back to 0 + next_c = '0; + load_next_c = '1; + end + field_combo.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.next = next_c; + field_combo.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.value <= 1'h0; + end else if(field_combo.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.load_next) begin + field_storage.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.value <= field_combo.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.next; + end + end + // Field: sha512_reg.intr_block_rf.error0_intr_count_r.cnt + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error0_intr_count_r.cnt.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error0_intr_count_r && decoded_req_is_wr) begin // SW write + next_c = (field_storage.intr_block_rf.error0_intr_count_r.cnt.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + if(field_storage.intr_block_rf.error0_intr_count_incr_r.pulse.value) begin // increment + if(((33)'(next_c) + 32'h1) > 32'hffffffff) begin // up-counter saturated + next_c = 32'hffffffff; + end else begin + next_c = next_c + 32'h1; + end + load_next_c = '1; + end + field_combo.intr_block_rf.error0_intr_count_r.cnt.incrthreshold = (field_storage.intr_block_rf.error0_intr_count_r.cnt.value >= 32'hffffffff); + field_combo.intr_block_rf.error0_intr_count_r.cnt.incrsaturate = (field_storage.intr_block_rf.error0_intr_count_r.cnt.value >= 32'hffffffff); + if(next_c > 32'hffffffff) begin + next_c = 32'hffffffff; + load_next_c = '1; + end + field_combo.intr_block_rf.error0_intr_count_r.cnt.next = next_c; + field_combo.intr_block_rf.error0_intr_count_r.cnt.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.error_reset_b) begin + if(~hwif_in.error_reset_b) begin + field_storage.intr_block_rf.error0_intr_count_r.cnt.value <= 32'h0; + end else if(field_combo.intr_block_rf.error0_intr_count_r.cnt.load_next) begin + field_storage.intr_block_rf.error0_intr_count_r.cnt.value <= field_combo.intr_block_rf.error0_intr_count_r.cnt.next; + end + end + // Field: sha512_reg.intr_block_rf.error1_intr_count_r.cnt + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error1_intr_count_r.cnt.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error1_intr_count_r && decoded_req_is_wr) begin // SW write + next_c = (field_storage.intr_block_rf.error1_intr_count_r.cnt.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + if(field_storage.intr_block_rf.error1_intr_count_incr_r.pulse.value) begin // increment + if(((33)'(next_c) + 32'h1) > 32'hffffffff) begin // up-counter saturated + next_c = 32'hffffffff; + end else begin + next_c = next_c + 32'h1; + end + load_next_c = '1; + end + field_combo.intr_block_rf.error1_intr_count_r.cnt.incrthreshold = (field_storage.intr_block_rf.error1_intr_count_r.cnt.value >= 32'hffffffff); + field_combo.intr_block_rf.error1_intr_count_r.cnt.incrsaturate = (field_storage.intr_block_rf.error1_intr_count_r.cnt.value >= 32'hffffffff); + if(next_c > 32'hffffffff) begin + next_c = 32'hffffffff; + load_next_c = '1; + end + field_combo.intr_block_rf.error1_intr_count_r.cnt.next = next_c; + field_combo.intr_block_rf.error1_intr_count_r.cnt.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.error_reset_b) begin + if(~hwif_in.error_reset_b) begin + field_storage.intr_block_rf.error1_intr_count_r.cnt.value <= 32'h0; + end else if(field_combo.intr_block_rf.error1_intr_count_r.cnt.load_next) begin + field_storage.intr_block_rf.error1_intr_count_r.cnt.value <= field_combo.intr_block_rf.error1_intr_count_r.cnt.next; + end + end + // Field: sha512_reg.intr_block_rf.error2_intr_count_r.cnt + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error2_intr_count_r.cnt.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error2_intr_count_r && decoded_req_is_wr) begin // SW write + next_c = (field_storage.intr_block_rf.error2_intr_count_r.cnt.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + if(field_storage.intr_block_rf.error2_intr_count_incr_r.pulse.value) begin // increment + if(((33)'(next_c) + 32'h1) > 32'hffffffff) begin // up-counter saturated + next_c = 32'hffffffff; + end else begin + next_c = next_c + 32'h1; + end + load_next_c = '1; + end + field_combo.intr_block_rf.error2_intr_count_r.cnt.incrthreshold = (field_storage.intr_block_rf.error2_intr_count_r.cnt.value >= 32'hffffffff); + field_combo.intr_block_rf.error2_intr_count_r.cnt.incrsaturate = (field_storage.intr_block_rf.error2_intr_count_r.cnt.value >= 32'hffffffff); + if(next_c > 32'hffffffff) begin + next_c = 32'hffffffff; + load_next_c = '1; + end + field_combo.intr_block_rf.error2_intr_count_r.cnt.next = next_c; + field_combo.intr_block_rf.error2_intr_count_r.cnt.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.error_reset_b) begin + if(~hwif_in.error_reset_b) begin + field_storage.intr_block_rf.error2_intr_count_r.cnt.value <= 32'h0; + end else if(field_combo.intr_block_rf.error2_intr_count_r.cnt.load_next) begin + field_storage.intr_block_rf.error2_intr_count_r.cnt.value <= field_combo.intr_block_rf.error2_intr_count_r.cnt.next; + end + end + // Field: sha512_reg.intr_block_rf.error3_intr_count_r.cnt + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error3_intr_count_r.cnt.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error3_intr_count_r && decoded_req_is_wr) begin // SW write + next_c = (field_storage.intr_block_rf.error3_intr_count_r.cnt.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + if(field_storage.intr_block_rf.error3_intr_count_incr_r.pulse.value) begin // increment + if(((33)'(next_c) + 32'h1) > 32'hffffffff) begin // up-counter saturated + next_c = 32'hffffffff; + end else begin + next_c = next_c + 32'h1; + end + load_next_c = '1; + end + field_combo.intr_block_rf.error3_intr_count_r.cnt.incrthreshold = (field_storage.intr_block_rf.error3_intr_count_r.cnt.value >= 32'hffffffff); + field_combo.intr_block_rf.error3_intr_count_r.cnt.incrsaturate = (field_storage.intr_block_rf.error3_intr_count_r.cnt.value >= 32'hffffffff); + if(next_c > 32'hffffffff) begin + next_c = 32'hffffffff; + load_next_c = '1; + end + field_combo.intr_block_rf.error3_intr_count_r.cnt.next = next_c; + field_combo.intr_block_rf.error3_intr_count_r.cnt.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.error_reset_b) begin + if(~hwif_in.error_reset_b) begin + field_storage.intr_block_rf.error3_intr_count_r.cnt.value <= 32'h0; + end else if(field_combo.intr_block_rf.error3_intr_count_r.cnt.load_next) begin + field_storage.intr_block_rf.error3_intr_count_r.cnt.value <= field_combo.intr_block_rf.error3_intr_count_r.cnt.next; + end + end + // Field: sha512_reg.intr_block_rf.notif_cmd_done_intr_count_r.cnt + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_cmd_done_intr_count_r.cnt.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.notif_cmd_done_intr_count_r && decoded_req_is_wr) begin // SW write + next_c = (field_storage.intr_block_rf.notif_cmd_done_intr_count_r.cnt.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + if(field_storage.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.value) begin // increment + if(((33)'(next_c) + 32'h1) > 32'hffffffff) begin // up-counter saturated + next_c = 32'hffffffff; + end else begin + next_c = next_c + 32'h1; + end + load_next_c = '1; + end + field_combo.intr_block_rf.notif_cmd_done_intr_count_r.cnt.incrthreshold = (field_storage.intr_block_rf.notif_cmd_done_intr_count_r.cnt.value >= 32'hffffffff); + field_combo.intr_block_rf.notif_cmd_done_intr_count_r.cnt.incrsaturate = (field_storage.intr_block_rf.notif_cmd_done_intr_count_r.cnt.value >= 32'hffffffff); + if(next_c > 32'hffffffff) begin + next_c = 32'hffffffff; + load_next_c = '1; + end + field_combo.intr_block_rf.notif_cmd_done_intr_count_r.cnt.next = next_c; + field_combo.intr_block_rf.notif_cmd_done_intr_count_r.cnt.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.notif_cmd_done_intr_count_r.cnt.value <= 32'h0; + end else if(field_combo.intr_block_rf.notif_cmd_done_intr_count_r.cnt.load_next) begin + field_storage.intr_block_rf.notif_cmd_done_intr_count_r.cnt.value <= field_combo.intr_block_rf.notif_cmd_done_intr_count_r.cnt.next; + end + end + // Field: sha512_reg.intr_block_rf.error0_intr_count_incr_r.pulse + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error0_intr_count_incr_r.pulse.value; + load_next_c = '0; + if(field_storage.intr_block_rf.error_intr_trig_r.error0_trig.value) begin // HW Write - we + next_c = field_storage.intr_block_rf.error_intr_trig_r.error0_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.error_internal_intr_r.error0_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end + if(field_storage.intr_block_rf.error0_intr_count_incr_r.pulse.value) begin // decrement + field_combo.intr_block_rf.error0_intr_count_incr_r.pulse.underflow = (next_c < (1'h1)); + next_c = next_c - 1'h1; + load_next_c = '1; + end else begin + field_combo.intr_block_rf.error0_intr_count_incr_r.pulse.underflow = '0; + end + field_combo.intr_block_rf.error0_intr_count_incr_r.pulse.decrthreshold = (field_storage.intr_block_rf.error0_intr_count_incr_r.pulse.value <= 1'd0); + field_combo.intr_block_rf.error0_intr_count_incr_r.pulse.next = next_c; + field_combo.intr_block_rf.error0_intr_count_incr_r.pulse.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.error0_intr_count_incr_r.pulse.value <= 1'h0; + end else if(field_combo.intr_block_rf.error0_intr_count_incr_r.pulse.load_next) begin + field_storage.intr_block_rf.error0_intr_count_incr_r.pulse.value <= field_combo.intr_block_rf.error0_intr_count_incr_r.pulse.next; + end + end + // Field: sha512_reg.intr_block_rf.error1_intr_count_incr_r.pulse + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error1_intr_count_incr_r.pulse.value; + load_next_c = '0; + if(field_storage.intr_block_rf.error_intr_trig_r.error1_trig.value) begin // HW Write - we + next_c = field_storage.intr_block_rf.error_intr_trig_r.error1_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.error_internal_intr_r.error1_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end + if(field_storage.intr_block_rf.error1_intr_count_incr_r.pulse.value) begin // decrement + field_combo.intr_block_rf.error1_intr_count_incr_r.pulse.underflow = (next_c < (1'h1)); + next_c = next_c - 1'h1; + load_next_c = '1; + end else begin + field_combo.intr_block_rf.error1_intr_count_incr_r.pulse.underflow = '0; + end + field_combo.intr_block_rf.error1_intr_count_incr_r.pulse.decrthreshold = (field_storage.intr_block_rf.error1_intr_count_incr_r.pulse.value <= 1'd0); + field_combo.intr_block_rf.error1_intr_count_incr_r.pulse.next = next_c; + field_combo.intr_block_rf.error1_intr_count_incr_r.pulse.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.error1_intr_count_incr_r.pulse.value <= 1'h0; + end else if(field_combo.intr_block_rf.error1_intr_count_incr_r.pulse.load_next) begin + field_storage.intr_block_rf.error1_intr_count_incr_r.pulse.value <= field_combo.intr_block_rf.error1_intr_count_incr_r.pulse.next; + end + end + // Field: sha512_reg.intr_block_rf.error2_intr_count_incr_r.pulse + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error2_intr_count_incr_r.pulse.value; + load_next_c = '0; + if(field_storage.intr_block_rf.error_intr_trig_r.error2_trig.value) begin // HW Write - we + next_c = field_storage.intr_block_rf.error_intr_trig_r.error2_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.error_internal_intr_r.error2_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end + if(field_storage.intr_block_rf.error2_intr_count_incr_r.pulse.value) begin // decrement + field_combo.intr_block_rf.error2_intr_count_incr_r.pulse.underflow = (next_c < (1'h1)); + next_c = next_c - 1'h1; + load_next_c = '1; + end else begin + field_combo.intr_block_rf.error2_intr_count_incr_r.pulse.underflow = '0; + end + field_combo.intr_block_rf.error2_intr_count_incr_r.pulse.decrthreshold = (field_storage.intr_block_rf.error2_intr_count_incr_r.pulse.value <= 1'd0); + field_combo.intr_block_rf.error2_intr_count_incr_r.pulse.next = next_c; + field_combo.intr_block_rf.error2_intr_count_incr_r.pulse.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.error2_intr_count_incr_r.pulse.value <= 1'h0; + end else if(field_combo.intr_block_rf.error2_intr_count_incr_r.pulse.load_next) begin + field_storage.intr_block_rf.error2_intr_count_incr_r.pulse.value <= field_combo.intr_block_rf.error2_intr_count_incr_r.pulse.next; + end + end + // Field: sha512_reg.intr_block_rf.error3_intr_count_incr_r.pulse + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error3_intr_count_incr_r.pulse.value; + load_next_c = '0; + if(field_storage.intr_block_rf.error_intr_trig_r.error3_trig.value) begin // HW Write - we + next_c = field_storage.intr_block_rf.error_intr_trig_r.error3_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.error_internal_intr_r.error3_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end + if(field_storage.intr_block_rf.error3_intr_count_incr_r.pulse.value) begin // decrement + field_combo.intr_block_rf.error3_intr_count_incr_r.pulse.underflow = (next_c < (1'h1)); + next_c = next_c - 1'h1; + load_next_c = '1; + end else begin + field_combo.intr_block_rf.error3_intr_count_incr_r.pulse.underflow = '0; + end + field_combo.intr_block_rf.error3_intr_count_incr_r.pulse.decrthreshold = (field_storage.intr_block_rf.error3_intr_count_incr_r.pulse.value <= 1'd0); + field_combo.intr_block_rf.error3_intr_count_incr_r.pulse.next = next_c; + field_combo.intr_block_rf.error3_intr_count_incr_r.pulse.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.error3_intr_count_incr_r.pulse.value <= 1'h0; + end else if(field_combo.intr_block_rf.error3_intr_count_incr_r.pulse.load_next) begin + field_storage.intr_block_rf.error3_intr_count_incr_r.pulse.value <= field_combo.intr_block_rf.error3_intr_count_incr_r.pulse.next; + end + end + // Field: sha512_reg.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.value; + load_next_c = '0; + if(field_storage.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.value) begin // HW Write - we + next_c = field_storage.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end + if(field_storage.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.value) begin // decrement + field_combo.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.underflow = (next_c < (1'h1)); + next_c = next_c - 1'h1; + load_next_c = '1; + end else begin + field_combo.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.underflow = '0; + end + field_combo.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.decrthreshold = (field_storage.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.value <= 1'd0); + field_combo.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.next = next_c; + field_combo.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.reset_b) begin + if(~hwif_in.reset_b) begin + field_storage.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.value <= 1'h0; + end else if(field_combo.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.load_next) begin + field_storage.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.value <= field_combo.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.next; + end + end + + //-------------------------------------------------------------------------- + // Write response + //-------------------------------------------------------------------------- + assign cpuif_wr_ack = decoded_req & decoded_req_is_wr; + // Writes are always granted with no error response + assign cpuif_wr_err = '0; + + //-------------------------------------------------------------------------- + // Readback + //-------------------------------------------------------------------------- + + logic readback_err; + logic readback_done; + logic [31:0] readback_data; + + // Assign readback values to a flattened array + logic [61-1:0][31:0] readback_array; + for(genvar i0=0; i0<2; i0++) begin + assign readback_array[i0*1 + 0][31:0] = (decoded_reg_strb.SHA512_NAME[i0] && !decoded_req_is_wr) ? hwif_in.SHA512_NAME[i0].NAME.next : '0; + end + for(genvar i0=0; i0<2; i0++) begin + assign readback_array[i0*1 + 2][31:0] = (decoded_reg_strb.SHA512_VERSION[i0] && !decoded_req_is_wr) ? hwif_in.SHA512_VERSION[i0].VERSION.next : '0; + end + assign readback_array[4][0:0] = (decoded_reg_strb.SHA512_STATUS && !decoded_req_is_wr) ? hwif_in.SHA512_STATUS.READY.next : '0; + assign readback_array[4][1:1] = (decoded_reg_strb.SHA512_STATUS && !decoded_req_is_wr) ? hwif_in.SHA512_STATUS.VALID.next : '0; + assign readback_array[4][31:2] = '0; + for(genvar i0=0; i0<16; i0++) begin + assign readback_array[i0*1 + 5][31:0] = (decoded_reg_strb.SHA512_DIGEST[i0] && !decoded_req_is_wr) ? field_storage.SHA512_DIGEST[i0].DIGEST.value : '0; + end + assign readback_array[21][0:0] = (decoded_reg_strb.SHA512_VAULT_RD_CTRL && !decoded_req_is_wr) ? field_storage.SHA512_VAULT_RD_CTRL.read_en.value : '0; + assign readback_array[21][5:1] = (decoded_reg_strb.SHA512_VAULT_RD_CTRL && !decoded_req_is_wr) ? field_storage.SHA512_VAULT_RD_CTRL.read_entry.value : '0; + assign readback_array[21][6:6] = (decoded_reg_strb.SHA512_VAULT_RD_CTRL && !decoded_req_is_wr) ? field_storage.SHA512_VAULT_RD_CTRL.pcr_hash_extend.value : '0; + assign readback_array[21][31:7] = (decoded_reg_strb.SHA512_VAULT_RD_CTRL && !decoded_req_is_wr) ? field_storage.SHA512_VAULT_RD_CTRL.rsvd.value : '0; + assign readback_array[22][0:0] = (decoded_reg_strb.SHA512_VAULT_RD_STATUS && !decoded_req_is_wr) ? hwif_in.SHA512_VAULT_RD_STATUS.READY.next : '0; + assign readback_array[22][1:1] = (decoded_reg_strb.SHA512_VAULT_RD_STATUS && !decoded_req_is_wr) ? field_storage.SHA512_VAULT_RD_STATUS.VALID.value : '0; + assign readback_array[22][9:2] = (decoded_reg_strb.SHA512_VAULT_RD_STATUS && !decoded_req_is_wr) ? hwif_in.SHA512_VAULT_RD_STATUS.ERROR.next : '0; + assign readback_array[22][31:10] = '0; + assign readback_array[23][0:0] = (decoded_reg_strb.SHA512_KV_WR_CTRL && !decoded_req_is_wr) ? field_storage.SHA512_KV_WR_CTRL.write_en.value : '0; + assign readback_array[23][5:1] = (decoded_reg_strb.SHA512_KV_WR_CTRL && !decoded_req_is_wr) ? field_storage.SHA512_KV_WR_CTRL.write_entry.value : '0; + assign readback_array[23][6:6] = (decoded_reg_strb.SHA512_KV_WR_CTRL && !decoded_req_is_wr) ? field_storage.SHA512_KV_WR_CTRL.hmac_key_dest_valid.value : '0; + assign readback_array[23][7:7] = (decoded_reg_strb.SHA512_KV_WR_CTRL && !decoded_req_is_wr) ? field_storage.SHA512_KV_WR_CTRL.hmac_block_dest_valid.value : '0; + assign readback_array[23][8:8] = (decoded_reg_strb.SHA512_KV_WR_CTRL && !decoded_req_is_wr) ? field_storage.SHA512_KV_WR_CTRL.mldsa_seed_dest_valid.value : '0; + assign readback_array[23][9:9] = (decoded_reg_strb.SHA512_KV_WR_CTRL && !decoded_req_is_wr) ? field_storage.SHA512_KV_WR_CTRL.ecc_pkey_dest_valid.value : '0; + assign readback_array[23][10:10] = (decoded_reg_strb.SHA512_KV_WR_CTRL && !decoded_req_is_wr) ? field_storage.SHA512_KV_WR_CTRL.ecc_seed_dest_valid.value : '0; + assign readback_array[23][11:11] = (decoded_reg_strb.SHA512_KV_WR_CTRL && !decoded_req_is_wr) ? field_storage.SHA512_KV_WR_CTRL.aes_key_dest_valid.value : '0; + assign readback_array[23][12:12] = (decoded_reg_strb.SHA512_KV_WR_CTRL && !decoded_req_is_wr) ? field_storage.SHA512_KV_WR_CTRL.mlkem_seed_dest_valid.value : '0; + assign readback_array[23][13:13] = (decoded_reg_strb.SHA512_KV_WR_CTRL && !decoded_req_is_wr) ? field_storage.SHA512_KV_WR_CTRL.mlkem_msg_dest_valid.value : '0; + assign readback_array[23][14:14] = (decoded_reg_strb.SHA512_KV_WR_CTRL && !decoded_req_is_wr) ? field_storage.SHA512_KV_WR_CTRL.dma_data_dest_valid.value : '0; + assign readback_array[23][31:15] = (decoded_reg_strb.SHA512_KV_WR_CTRL && !decoded_req_is_wr) ? field_storage.SHA512_KV_WR_CTRL.rsvd.value : '0; + assign readback_array[24][0:0] = (decoded_reg_strb.SHA512_KV_WR_STATUS && !decoded_req_is_wr) ? hwif_in.SHA512_KV_WR_STATUS.READY.next : '0; + assign readback_array[24][1:1] = (decoded_reg_strb.SHA512_KV_WR_STATUS && !decoded_req_is_wr) ? field_storage.SHA512_KV_WR_STATUS.VALID.value : '0; + assign readback_array[24][9:2] = (decoded_reg_strb.SHA512_KV_WR_STATUS && !decoded_req_is_wr) ? hwif_in.SHA512_KV_WR_STATUS.ERROR.next : '0; + assign readback_array[24][31:10] = '0; + assign readback_array[25][0:0] = (decoded_reg_strb.SHA512_GEN_PCR_HASH_STATUS && !decoded_req_is_wr) ? hwif_in.SHA512_GEN_PCR_HASH_STATUS.READY.next : '0; + assign readback_array[25][1:1] = (decoded_reg_strb.SHA512_GEN_PCR_HASH_STATUS && !decoded_req_is_wr) ? field_storage.SHA512_GEN_PCR_HASH_STATUS.VALID.value : '0; + assign readback_array[25][31:2] = '0; + for(genvar i0=0; i0<16; i0++) begin + assign readback_array[i0*1 + 26][31:0] = (decoded_reg_strb.SHA512_GEN_PCR_HASH_DIGEST[i0] && !decoded_req_is_wr) ? field_storage.SHA512_GEN_PCR_HASH_DIGEST[i0].DIGEST.value : '0; + end + assign readback_array[42][0:0] = (decoded_reg_strb.intr_block_rf.global_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.global_intr_en_r.error_en.value : '0; + assign readback_array[42][1:1] = (decoded_reg_strb.intr_block_rf.global_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.global_intr_en_r.notif_en.value : '0; + assign readback_array[42][31:2] = '0; + assign readback_array[43][0:0] = (decoded_reg_strb.intr_block_rf.error_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_en_r.error0_en.value : '0; + assign readback_array[43][1:1] = (decoded_reg_strb.intr_block_rf.error_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_en_r.error1_en.value : '0; + assign readback_array[43][2:2] = (decoded_reg_strb.intr_block_rf.error_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_en_r.error2_en.value : '0; + assign readback_array[43][3:3] = (decoded_reg_strb.intr_block_rf.error_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_en_r.error3_en.value : '0; + assign readback_array[43][31:4] = '0; + assign readback_array[44][0:0] = (decoded_reg_strb.intr_block_rf.notif_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_intr_en_r.notif_cmd_done_en.value : '0; + assign readback_array[44][31:1] = '0; + assign readback_array[45][0:0] = (decoded_reg_strb.intr_block_rf.error_global_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_global_intr_r.agg_sts.value : '0; + assign readback_array[45][31:1] = '0; + assign readback_array[46][0:0] = (decoded_reg_strb.intr_block_rf.notif_global_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_global_intr_r.agg_sts.value : '0; + assign readback_array[46][31:1] = '0; + assign readback_array[47][0:0] = (decoded_reg_strb.intr_block_rf.error_internal_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_internal_intr_r.error0_sts.value : '0; + assign readback_array[47][1:1] = (decoded_reg_strb.intr_block_rf.error_internal_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_internal_intr_r.error1_sts.value : '0; + assign readback_array[47][2:2] = (decoded_reg_strb.intr_block_rf.error_internal_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_internal_intr_r.error2_sts.value : '0; + assign readback_array[47][3:3] = (decoded_reg_strb.intr_block_rf.error_internal_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_internal_intr_r.error3_sts.value : '0; + assign readback_array[47][31:4] = '0; + assign readback_array[48][0:0] = (decoded_reg_strb.intr_block_rf.notif_internal_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_internal_intr_r.notif_cmd_done_sts.value : '0; + assign readback_array[48][31:1] = '0; + assign readback_array[49][0:0] = (decoded_reg_strb.intr_block_rf.error_intr_trig_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_trig_r.error0_trig.value : '0; + assign readback_array[49][1:1] = (decoded_reg_strb.intr_block_rf.error_intr_trig_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_trig_r.error1_trig.value : '0; + assign readback_array[49][2:2] = (decoded_reg_strb.intr_block_rf.error_intr_trig_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_trig_r.error2_trig.value : '0; + assign readback_array[49][3:3] = (decoded_reg_strb.intr_block_rf.error_intr_trig_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_trig_r.error3_trig.value : '0; + assign readback_array[49][31:4] = '0; + assign readback_array[50][0:0] = (decoded_reg_strb.intr_block_rf.notif_intr_trig_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_intr_trig_r.notif_cmd_done_trig.value : '0; + assign readback_array[50][31:1] = '0; + assign readback_array[51][31:0] = (decoded_reg_strb.intr_block_rf.error0_intr_count_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error0_intr_count_r.cnt.value : '0; + assign readback_array[52][31:0] = (decoded_reg_strb.intr_block_rf.error1_intr_count_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error1_intr_count_r.cnt.value : '0; + assign readback_array[53][31:0] = (decoded_reg_strb.intr_block_rf.error2_intr_count_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error2_intr_count_r.cnt.value : '0; + assign readback_array[54][31:0] = (decoded_reg_strb.intr_block_rf.error3_intr_count_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error3_intr_count_r.cnt.value : '0; + assign readback_array[55][31:0] = (decoded_reg_strb.intr_block_rf.notif_cmd_done_intr_count_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_cmd_done_intr_count_r.cnt.value : '0; + assign readback_array[56][0:0] = (decoded_reg_strb.intr_block_rf.error0_intr_count_incr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error0_intr_count_incr_r.pulse.value : '0; + assign readback_array[56][31:1] = '0; + assign readback_array[57][0:0] = (decoded_reg_strb.intr_block_rf.error1_intr_count_incr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error1_intr_count_incr_r.pulse.value : '0; + assign readback_array[57][31:1] = '0; + assign readback_array[58][0:0] = (decoded_reg_strb.intr_block_rf.error2_intr_count_incr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error2_intr_count_incr_r.pulse.value : '0; + assign readback_array[58][31:1] = '0; + assign readback_array[59][0:0] = (decoded_reg_strb.intr_block_rf.error3_intr_count_incr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error3_intr_count_incr_r.pulse.value : '0; + assign readback_array[59][31:1] = '0; + assign readback_array[60][0:0] = (decoded_reg_strb.intr_block_rf.notif_cmd_done_intr_count_incr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_cmd_done_intr_count_incr_r.pulse.value : '0; + assign readback_array[60][31:1] = '0; + + // Reduce the array + always_comb begin + automatic logic [31:0] readback_data_var; + readback_done = decoded_req & ~decoded_req_is_wr; + readback_err = '0; + readback_data_var = '0; + for(int i=0; i<61; i++) readback_data_var |= readback_array[i]; + readback_data = readback_data_var; + end + + assign cpuif_rd_ack = readback_done; + assign cpuif_rd_data = readback_data; + assign cpuif_rd_err = readback_err; + +`CALIPTRA_ASSERT_KNOWN(ERR_HWIF_IN, hwif_in, clk, !hwif_in.error_reset_b) + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/sha512_reg_pkg.sv b/designs/Caliptra/src/caliptra-rtl/sha512_reg_pkg.sv new file mode 100644 index 0000000..4eda4b3 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/sha512_reg_pkg.sv @@ -0,0 +1,445 @@ +// Generated by PeakRDL-regblock - A free and open-source SystemVerilog generator +// https://github.com/SystemRDL/PeakRDL-regblock + +package sha512_reg_pkg; + + localparam SHA512_REG_DATA_WIDTH = 32; + localparam SHA512_REG_MIN_ADDR_WIDTH = 12; + + typedef struct packed{ + logic [31:0] next; + } sha512_reg__SHA512_NAME__NAME__in_t; + + typedef struct packed{ + sha512_reg__SHA512_NAME__NAME__in_t NAME; + } sha512_reg__SHA512_NAME__in_t; + + typedef struct packed{ + logic [31:0] next; + } sha512_reg__SHA512_VERSION__VERSION__in_t; + + typedef struct packed{ + sha512_reg__SHA512_VERSION__VERSION__in_t VERSION; + } sha512_reg__SHA512_VERSION__in_t; + + typedef struct packed{ + logic hwclr; + } sha512_reg__SHA512_CTRL__LAST__in_t; + + typedef struct packed{ + sha512_reg__SHA512_CTRL__LAST__in_t LAST; + } sha512_reg__SHA512_CTRL__in_t; + + typedef struct packed{ + logic next; + } sha512_reg__SHA512_STATUS__READY__in_t; + + typedef struct packed{ + logic next; + } sha512_reg__SHA512_STATUS__VALID__in_t; + + typedef struct packed{ + sha512_reg__SHA512_STATUS__READY__in_t READY; + sha512_reg__SHA512_STATUS__VALID__in_t VALID; + } sha512_reg__SHA512_STATUS__in_t; + + typedef struct packed{ + logic [31:0] next; + logic we; + logic swwel; + logic hwclr; + } sha512_reg__SHA512_BLOCK__BLOCK__in_t; + + typedef struct packed{ + sha512_reg__SHA512_BLOCK__BLOCK__in_t BLOCK; + } sha512_reg__SHA512_BLOCK__in_t; + + typedef struct packed{ + logic [31:0] next; + logic we; + logic hwclr; + } sha512_reg__SHA512_DIGEST__DIGEST__in_t; + + typedef struct packed{ + sha512_reg__SHA512_DIGEST__DIGEST__in_t DIGEST; + } sha512_reg__SHA512_DIGEST__in_t; + + typedef struct packed{ + logic swwe; + logic hwclr; + } kv_read_ctrl_reg__read_en__in_t; + + typedef struct packed{ + logic swwe; + } kv_read_ctrl_reg__read_entry__in_t; + + typedef struct packed{ + logic swwe; + } kv_read_ctrl_reg__pcr_hash_extend__in_t; + + typedef struct packed{ + logic swwe; + } kv_read_ctrl_reg__rsvd__in_t; + + typedef struct packed{ + kv_read_ctrl_reg__read_en__in_t read_en; + kv_read_ctrl_reg__read_entry__in_t read_entry; + kv_read_ctrl_reg__pcr_hash_extend__in_t pcr_hash_extend; + kv_read_ctrl_reg__rsvd__in_t rsvd; + } kv_read_ctrl_reg__in_t; + + typedef struct packed{ + logic next; + } kv_status_reg__READY__in_t; + + typedef struct packed{ + logic hwclr; + logic hwset; + } kv_status_reg__VALID__in_t; + + typedef struct packed{ + logic [7:0] next; + } kv_status_reg__ERROR__in_t; + + typedef struct packed{ + kv_status_reg__READY__in_t READY; + kv_status_reg__VALID__in_t VALID; + kv_status_reg__ERROR__in_t ERROR; + } kv_status_reg__in_t; + + typedef struct packed{ + logic swwe; + logic hwclr; + } kv_write_ctrl_reg__write_en__in_t; + + typedef struct packed{ + logic swwe; + } kv_write_ctrl_reg__write_entry__in_t; + + typedef struct packed{ + logic swwe; + } kv_write_ctrl_reg__hmac_key_dest_valid__in_t; + + typedef struct packed{ + logic swwe; + } kv_write_ctrl_reg__hmac_block_dest_valid__in_t; + + typedef struct packed{ + logic swwe; + } kv_write_ctrl_reg__mldsa_seed_dest_valid__in_t; + + typedef struct packed{ + logic swwe; + } kv_write_ctrl_reg__ecc_pkey_dest_valid__in_t; + + typedef struct packed{ + logic swwe; + } kv_write_ctrl_reg__ecc_seed_dest_valid__in_t; + + typedef struct packed{ + logic swwe; + } kv_write_ctrl_reg__aes_key_dest_valid__in_t; + + typedef struct packed{ + logic swwe; + } kv_write_ctrl_reg__mlkem_seed_dest_valid__in_t; + + typedef struct packed{ + logic swwe; + } kv_write_ctrl_reg__mlkem_msg_dest_valid__in_t; + + typedef struct packed{ + logic swwe; + } kv_write_ctrl_reg__dma_data_dest_valid__in_t; + + typedef struct packed{ + logic swwe; + } kv_write_ctrl_reg__rsvd__in_t; + + typedef struct packed{ + kv_write_ctrl_reg__write_en__in_t write_en; + kv_write_ctrl_reg__write_entry__in_t write_entry; + kv_write_ctrl_reg__hmac_key_dest_valid__in_t hmac_key_dest_valid; + kv_write_ctrl_reg__hmac_block_dest_valid__in_t hmac_block_dest_valid; + kv_write_ctrl_reg__mldsa_seed_dest_valid__in_t mldsa_seed_dest_valid; + kv_write_ctrl_reg__ecc_pkey_dest_valid__in_t ecc_pkey_dest_valid; + kv_write_ctrl_reg__ecc_seed_dest_valid__in_t ecc_seed_dest_valid; + kv_write_ctrl_reg__aes_key_dest_valid__in_t aes_key_dest_valid; + kv_write_ctrl_reg__mlkem_seed_dest_valid__in_t mlkem_seed_dest_valid; + kv_write_ctrl_reg__mlkem_msg_dest_valid__in_t mlkem_msg_dest_valid; + kv_write_ctrl_reg__dma_data_dest_valid__in_t dma_data_dest_valid; + kv_write_ctrl_reg__rsvd__in_t rsvd; + } kv_write_ctrl_reg__in_t; + + typedef struct packed{ + logic next; + } sha512_reg__SHA512_GEN_PCR_HASH_STATUS__READY__in_t; + + typedef struct packed{ + logic hwclr; + logic hwset; + } sha512_reg__SHA512_GEN_PCR_HASH_STATUS__VALID__in_t; + + typedef struct packed{ + sha512_reg__SHA512_GEN_PCR_HASH_STATUS__READY__in_t READY; + sha512_reg__SHA512_GEN_PCR_HASH_STATUS__VALID__in_t VALID; + } sha512_reg__SHA512_GEN_PCR_HASH_STATUS__in_t; + + typedef struct packed{ + logic [31:0] next; + logic hwclr; + } sha512_reg__SHA512_GEN_PCR_HASH_DIGEST__DIGEST__in_t; + + typedef struct packed{ + sha512_reg__SHA512_GEN_PCR_HASH_DIGEST__DIGEST__in_t DIGEST; + } sha512_reg__SHA512_GEN_PCR_HASH_DIGEST__in_t; + + typedef struct packed{ + logic hwset; + } sha512_reg__error_intr_t_error0_sts_28545624_error1_sts_40e0d3e1_error2_sts_b1cf2205_error3_sts_74a35378__error0_sts_enable_528ccada_next_b1018582_resetsignal_939e99d4__in_t; + + typedef struct packed{ + logic hwset; + } sha512_reg__error_intr_t_error0_sts_28545624_error1_sts_40e0d3e1_error2_sts_b1cf2205_error3_sts_74a35378__error1_sts_enable_938cafef_next_f460eb81_resetsignal_939e99d4__in_t; + + typedef struct packed{ + logic hwset; + } sha512_reg__error_intr_t_error0_sts_28545624_error1_sts_40e0d3e1_error2_sts_b1cf2205_error3_sts_74a35378__error2_sts_enable_0dacf7a6_next_4b5b9e74_resetsignal_939e99d4__in_t; + + typedef struct packed{ + logic hwset; + } sha512_reg__error_intr_t_error0_sts_28545624_error1_sts_40e0d3e1_error2_sts_b1cf2205_error3_sts_74a35378__error3_sts_enable_fc3af94b_next_c3125d40_resetsignal_939e99d4__in_t; + + typedef struct packed{ + sha512_reg__error_intr_t_error0_sts_28545624_error1_sts_40e0d3e1_error2_sts_b1cf2205_error3_sts_74a35378__error0_sts_enable_528ccada_next_b1018582_resetsignal_939e99d4__in_t error0_sts; + sha512_reg__error_intr_t_error0_sts_28545624_error1_sts_40e0d3e1_error2_sts_b1cf2205_error3_sts_74a35378__error1_sts_enable_938cafef_next_f460eb81_resetsignal_939e99d4__in_t error1_sts; + sha512_reg__error_intr_t_error0_sts_28545624_error1_sts_40e0d3e1_error2_sts_b1cf2205_error3_sts_74a35378__error2_sts_enable_0dacf7a6_next_4b5b9e74_resetsignal_939e99d4__in_t error2_sts; + sha512_reg__error_intr_t_error0_sts_28545624_error1_sts_40e0d3e1_error2_sts_b1cf2205_error3_sts_74a35378__error3_sts_enable_fc3af94b_next_c3125d40_resetsignal_939e99d4__in_t error3_sts; + } sha512_reg__error_intr_t_error0_sts_28545624_error1_sts_40e0d3e1_error2_sts_b1cf2205_error3_sts_74a35378__in_t; + + typedef struct packed{ + logic hwset; + } sha512_reg__notif_intr_t_notif_cmd_done_sts_1c68637e__notif_cmd_done_sts_enable_dabe0b8b_next_540fa3b7__in_t; + + typedef struct packed{ + sha512_reg__notif_intr_t_notif_cmd_done_sts_1c68637e__notif_cmd_done_sts_enable_dabe0b8b_next_540fa3b7__in_t notif_cmd_done_sts; + } sha512_reg__notif_intr_t_notif_cmd_done_sts_1c68637e__in_t; + + typedef struct packed{ + sha512_reg__error_intr_t_error0_sts_28545624_error1_sts_40e0d3e1_error2_sts_b1cf2205_error3_sts_74a35378__in_t error_internal_intr_r; + sha512_reg__notif_intr_t_notif_cmd_done_sts_1c68637e__in_t notif_internal_intr_r; + } sha512_reg__intr_block_t__in_t; + + typedef struct packed{ + logic reset_b; + logic error_reset_b; + logic sha512_ready; + sha512_reg__SHA512_NAME__in_t [2-1:0]SHA512_NAME; + sha512_reg__SHA512_VERSION__in_t [2-1:0]SHA512_VERSION; + sha512_reg__SHA512_CTRL__in_t SHA512_CTRL; + sha512_reg__SHA512_STATUS__in_t SHA512_STATUS; + sha512_reg__SHA512_BLOCK__in_t [32-1:0]SHA512_BLOCK; + sha512_reg__SHA512_DIGEST__in_t [16-1:0]SHA512_DIGEST; + kv_read_ctrl_reg__in_t SHA512_VAULT_RD_CTRL; + kv_status_reg__in_t SHA512_VAULT_RD_STATUS; + kv_write_ctrl_reg__in_t SHA512_KV_WR_CTRL; + kv_status_reg__in_t SHA512_KV_WR_STATUS; + sha512_reg__SHA512_GEN_PCR_HASH_STATUS__in_t SHA512_GEN_PCR_HASH_STATUS; + sha512_reg__SHA512_GEN_PCR_HASH_DIGEST__in_t [16-1:0]SHA512_GEN_PCR_HASH_DIGEST; + sha512_reg__intr_block_t__in_t intr_block_rf; + } sha512_reg__in_t; + + typedef struct packed{ + logic value; + } sha512_reg__SHA512_CTRL__INIT__out_t; + + typedef struct packed{ + logic value; + } sha512_reg__SHA512_CTRL__NEXT__out_t; + + typedef struct packed{ + logic [1:0] value; + } sha512_reg__SHA512_CTRL__MODE__out_t; + + typedef struct packed{ + logic value; + } sha512_reg__SHA512_CTRL__ZEROIZE__out_t; + + typedef struct packed{ + logic value; + } sha512_reg__SHA512_CTRL__LAST__out_t; + + typedef struct packed{ + logic value; + } sha512_reg__SHA512_CTRL__RESTORE__out_t; + + typedef struct packed{ + sha512_reg__SHA512_CTRL__INIT__out_t INIT; + sha512_reg__SHA512_CTRL__NEXT__out_t NEXT; + sha512_reg__SHA512_CTRL__MODE__out_t MODE; + sha512_reg__SHA512_CTRL__ZEROIZE__out_t ZEROIZE; + sha512_reg__SHA512_CTRL__LAST__out_t LAST; + sha512_reg__SHA512_CTRL__RESTORE__out_t RESTORE; + } sha512_reg__SHA512_CTRL__out_t; + + typedef struct packed{ + logic [31:0] value; + } sha512_reg__SHA512_BLOCK__BLOCK__out_t; + + typedef struct packed{ + sha512_reg__SHA512_BLOCK__BLOCK__out_t BLOCK; + } sha512_reg__SHA512_BLOCK__out_t; + + typedef struct packed{ + logic [31:0] value; + } sha512_reg__SHA512_DIGEST__DIGEST__out_t; + + typedef struct packed{ + sha512_reg__SHA512_DIGEST__DIGEST__out_t DIGEST; + } sha512_reg__SHA512_DIGEST__out_t; + + typedef struct packed{ + logic value; + } kv_read_ctrl_reg__read_en__out_t; + + typedef struct packed{ + logic [4:0] value; + } kv_read_ctrl_reg__read_entry__out_t; + + typedef struct packed{ + logic value; + } kv_read_ctrl_reg__pcr_hash_extend__out_t; + + typedef struct packed{ + logic [24:0] value; + } kv_read_ctrl_reg__rsvd__out_t; + + typedef struct packed{ + kv_read_ctrl_reg__read_en__out_t read_en; + kv_read_ctrl_reg__read_entry__out_t read_entry; + kv_read_ctrl_reg__pcr_hash_extend__out_t pcr_hash_extend; + kv_read_ctrl_reg__rsvd__out_t rsvd; + } kv_read_ctrl_reg__out_t; + + typedef struct packed{ + logic value; + } kv_write_ctrl_reg__write_en__out_t; + + typedef struct packed{ + logic [4:0] value; + } kv_write_ctrl_reg__write_entry__out_t; + + typedef struct packed{ + logic value; + } kv_write_ctrl_reg__hmac_key_dest_valid__out_t; + + typedef struct packed{ + logic value; + } kv_write_ctrl_reg__hmac_block_dest_valid__out_t; + + typedef struct packed{ + logic value; + } kv_write_ctrl_reg__mldsa_seed_dest_valid__out_t; + + typedef struct packed{ + logic value; + } kv_write_ctrl_reg__ecc_pkey_dest_valid__out_t; + + typedef struct packed{ + logic value; + } kv_write_ctrl_reg__ecc_seed_dest_valid__out_t; + + typedef struct packed{ + logic value; + } kv_write_ctrl_reg__aes_key_dest_valid__out_t; + + typedef struct packed{ + logic value; + } kv_write_ctrl_reg__mlkem_seed_dest_valid__out_t; + + typedef struct packed{ + logic value; + } kv_write_ctrl_reg__mlkem_msg_dest_valid__out_t; + + typedef struct packed{ + logic value; + } kv_write_ctrl_reg__dma_data_dest_valid__out_t; + + typedef struct packed{ + logic [16:0] value; + } kv_write_ctrl_reg__rsvd__out_t; + + typedef struct packed{ + kv_write_ctrl_reg__write_en__out_t write_en; + kv_write_ctrl_reg__write_entry__out_t write_entry; + kv_write_ctrl_reg__hmac_key_dest_valid__out_t hmac_key_dest_valid; + kv_write_ctrl_reg__hmac_block_dest_valid__out_t hmac_block_dest_valid; + kv_write_ctrl_reg__mldsa_seed_dest_valid__out_t mldsa_seed_dest_valid; + kv_write_ctrl_reg__ecc_pkey_dest_valid__out_t ecc_pkey_dest_valid; + kv_write_ctrl_reg__ecc_seed_dest_valid__out_t ecc_seed_dest_valid; + kv_write_ctrl_reg__aes_key_dest_valid__out_t aes_key_dest_valid; + kv_write_ctrl_reg__mlkem_seed_dest_valid__out_t mlkem_seed_dest_valid; + kv_write_ctrl_reg__mlkem_msg_dest_valid__out_t mlkem_msg_dest_valid; + kv_write_ctrl_reg__dma_data_dest_valid__out_t dma_data_dest_valid; + kv_write_ctrl_reg__rsvd__out_t rsvd; + } kv_write_ctrl_reg__out_t; + + typedef struct packed{ + logic [31:0] value; + } sha512_reg__SHA512_GEN_PCR_HASH_NONCE__NONCE__out_t; + + typedef struct packed{ + sha512_reg__SHA512_GEN_PCR_HASH_NONCE__NONCE__out_t NONCE; + } sha512_reg__SHA512_GEN_PCR_HASH_NONCE__out_t; + + typedef struct packed{ + logic value; + } sha512_reg__SHA512_GEN_PCR_HASH_CTRL__START__out_t; + + typedef struct packed{ + sha512_reg__SHA512_GEN_PCR_HASH_CTRL__START__out_t START; + } sha512_reg__SHA512_GEN_PCR_HASH_CTRL__out_t; + + typedef struct packed{ + logic intr; + } sha512_reg__global_intr_t_agg_sts_dd3dcf0a__out_t; + + typedef struct packed{ + logic intr; + } sha512_reg__global_intr_t_agg_sts_e6399b4a__out_t; + + typedef struct packed{ + logic intr; + } sha512_reg__error_intr_t_error0_sts_28545624_error1_sts_40e0d3e1_error2_sts_b1cf2205_error3_sts_74a35378__out_t; + + typedef struct packed{ + logic intr; + } sha512_reg__notif_intr_t_notif_cmd_done_sts_1c68637e__out_t; + + typedef struct packed{ + sha512_reg__global_intr_t_agg_sts_dd3dcf0a__out_t error_global_intr_r; + sha512_reg__global_intr_t_agg_sts_e6399b4a__out_t notif_global_intr_r; + sha512_reg__error_intr_t_error0_sts_28545624_error1_sts_40e0d3e1_error2_sts_b1cf2205_error3_sts_74a35378__out_t error_internal_intr_r; + sha512_reg__notif_intr_t_notif_cmd_done_sts_1c68637e__out_t notif_internal_intr_r; + } sha512_reg__intr_block_t__out_t; + + typedef struct packed{ + sha512_reg__SHA512_CTRL__out_t SHA512_CTRL; + sha512_reg__SHA512_BLOCK__out_t [32-1:0]SHA512_BLOCK; + sha512_reg__SHA512_DIGEST__out_t [16-1:0]SHA512_DIGEST; + kv_read_ctrl_reg__out_t SHA512_VAULT_RD_CTRL; + kv_write_ctrl_reg__out_t SHA512_KV_WR_CTRL; + sha512_reg__SHA512_GEN_PCR_HASH_NONCE__out_t [8-1:0]SHA512_GEN_PCR_HASH_NONCE; + sha512_reg__SHA512_GEN_PCR_HASH_CTRL__out_t SHA512_GEN_PCR_HASH_CTRL; + sha512_reg__intr_block_t__out_t intr_block_rf; + } sha512_reg__out_t; + + typedef enum logic [31:0] { + kv_status_reg__ERROR__kv_error_e__SUCCESS = 'h0, + kv_status_reg__ERROR__kv_error_e__KV_READ_FAIL = 'h1, + kv_status_reg__ERROR__kv_error_e__KV_WRITE_FAIL = 'h2 + } kv_status_reg__ERROR__kv_error_e_e; + + localparam SHA512_REG_ADDR_WIDTH = 32'd12; + +endpackage \ No newline at end of file diff --git a/designs/Caliptra/src/caliptra-rtl/sha512_w_mem.v b/designs/Caliptra/src/caliptra-rtl/sha512_w_mem.v new file mode 100644 index 0000000..e72ed75 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/sha512_w_mem.v @@ -0,0 +1,278 @@ +//====================================================================== +// +// sha512_w_mem_regs.v +// ------------------- +// The W memory for the SHA-512 core. This version uses 16 +// 32-bit registers as a sliding window to generate the 64 words. +// +// +// Author: Joachim Strombergson +// Copyright (c) 2014 Secworks Sweden AB +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or +// without modification, are permitted provided that the following +// conditions are met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in +// the documentation and/or other materials provided with the +// distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +//====================================================================== + +module sha512_w_mem( + input wire clk, + input wire reset_n, + input wire zeroize, + + input wire [1023 : 0] block_msg, + + input wire init_cmd, + input wire next_cmd, + output wire [63 : 0] w_val + ); + + + //---------------------------------------------------------------- + // Registers including update variables and write enable. + //---------------------------------------------------------------- + reg [63 : 0] w_mem [0 : 15]; + reg [63 : 0] w_mem00_new; + reg [63 : 0] w_mem01_new; + reg [63 : 0] w_mem02_new; + reg [63 : 0] w_mem03_new; + reg [63 : 0] w_mem04_new; + reg [63 : 0] w_mem05_new; + reg [63 : 0] w_mem06_new; + reg [63 : 0] w_mem07_new; + reg [63 : 0] w_mem08_new; + reg [63 : 0] w_mem09_new; + reg [63 : 0] w_mem10_new; + reg [63 : 0] w_mem11_new; + reg [63 : 0] w_mem12_new; + reg [63 : 0] w_mem13_new; + reg [63 : 0] w_mem14_new; + reg [63 : 0] w_mem15_new; + reg w_mem_we; + + reg [6 : 0] w_ctr_reg; + reg [6 : 0] w_ctr_new; + reg w_ctr_we; + + + //---------------------------------------------------------------- + // Wires. + //---------------------------------------------------------------- + reg [63 : 0] w_tmp; + reg [63 : 0] w_new; + + + //---------------------------------------------------------------- + // Concurrent connectivity for ports etc. + //---------------------------------------------------------------- + assign w_val = w_tmp; + + + //---------------------------------------------------------------- + // reg_update + // Update functionality for all registers in the core. + // All registers are positive edge triggered with asynchronous + // active low reset. All registers have write enable. + //---------------------------------------------------------------- + always @ (posedge clk or negedge reset_n) + begin : reg_update + integer ii; + + if (!reset_n) begin + for (ii = 0; ii < 16; ii = ii + 1) + w_mem[ii] <= 64'h0; + + w_ctr_reg <= 7'h0; + end + else begin + if (zeroize) begin + for (ii = 0; ii < 16; ii = ii + 1) + w_mem[ii] <= 64'h0; + + w_ctr_reg <= 7'h0; + end + else begin + if (w_mem_we) + begin + w_mem[00] <= w_mem00_new; + w_mem[01] <= w_mem01_new; + w_mem[02] <= w_mem02_new; + w_mem[03] <= w_mem03_new; + w_mem[04] <= w_mem04_new; + w_mem[05] <= w_mem05_new; + w_mem[06] <= w_mem06_new; + w_mem[07] <= w_mem07_new; + w_mem[08] <= w_mem08_new; + w_mem[09] <= w_mem09_new; + w_mem[10] <= w_mem10_new; + w_mem[11] <= w_mem11_new; + w_mem[12] <= w_mem12_new; + w_mem[13] <= w_mem13_new; + w_mem[14] <= w_mem14_new; + w_mem[15] <= w_mem15_new; + end + + if (w_ctr_we) + w_ctr_reg <= w_ctr_new; + end + end + end // reg_update + + + //---------------------------------------------------------------- + // select_w + // + // Mux for the external read operation. This is where we exract + // the W variable. + //---------------------------------------------------------------- + always @* + begin : select_w + if (w_ctr_reg < 16) + w_tmp = w_mem[w_ctr_reg[3 : 0]]; + else + w_tmp = w_new; + end // select_w + + + //---------------------------------------------------------------- + // w_new_logic + // + // Logic that calculates the next value to be inserted into + // the sliding window of the memory. + //---------------------------------------------------------------- + always @* + begin : w_mem_update_logic + reg [63 : 0] w_0; + reg [63 : 0] w_1; + reg [63 : 0] w_9; + reg [63 : 0] w_14; + reg [63 : 0] d0; + reg [63 : 0] d1; + + w_mem00_new = 64'h0; + w_mem01_new = 64'h0; + w_mem02_new = 64'h0; + w_mem03_new = 64'h0; + w_mem04_new = 64'h0; + w_mem05_new = 64'h0; + w_mem06_new = 64'h0; + w_mem07_new = 64'h0; + w_mem08_new = 64'h0; + w_mem09_new = 64'h0; + w_mem10_new = 64'h0; + w_mem11_new = 64'h0; + w_mem12_new = 64'h0; + w_mem13_new = 64'h0; + w_mem14_new = 64'h0; + w_mem15_new = 64'h0; + w_mem_we = 0; + + w_0 = w_mem[0]; + w_1 = w_mem[1]; + w_9 = w_mem[9]; + w_14 = w_mem[14]; + + d0 = {w_1[0], w_1[63 : 1]} ^ // ROTR1 + {w_1[7 : 0], w_1[63 : 8]} ^ // ROTR8 + {7'b0000000, w_1[63 : 7]}; // SHR7 + + d1 = {w_14[18 : 0], w_14[63 : 19]} ^ // ROTR19 + {w_14[60 : 0], w_14[63 : 61]} ^ // ROTR61 + {6'b000000, w_14[63 : 6]}; // SHR6 + + w_new = w_0 + d0 + w_9 + d1; + + if (init_cmd) + begin + w_mem00_new = block_msg[1023 : 960]; + w_mem01_new = block_msg[959 : 896]; + w_mem02_new = block_msg[895 : 832]; + w_mem03_new = block_msg[831 : 768]; + w_mem04_new = block_msg[767 : 704]; + w_mem05_new = block_msg[703 : 640]; + w_mem06_new = block_msg[639 : 576]; + w_mem07_new = block_msg[575 : 512]; + w_mem08_new = block_msg[511 : 448]; + w_mem09_new = block_msg[447 : 384]; + w_mem10_new = block_msg[383 : 320]; + w_mem11_new = block_msg[319 : 256]; + w_mem12_new = block_msg[255 : 192]; + w_mem13_new = block_msg[191 : 128]; + w_mem14_new = block_msg[127 : 64]; + w_mem15_new = block_msg[63 : 0]; + w_mem_we = 1; + end + + if (next_cmd && (w_ctr_reg > 15)) + begin + w_mem00_new = w_mem[01]; + w_mem01_new = w_mem[02]; + w_mem02_new = w_mem[03]; + w_mem03_new = w_mem[04]; + w_mem04_new = w_mem[05]; + w_mem05_new = w_mem[06]; + w_mem06_new = w_mem[07]; + w_mem07_new = w_mem[08]; + w_mem08_new = w_mem[09]; + w_mem09_new = w_mem[10]; + w_mem10_new = w_mem[11]; + w_mem11_new = w_mem[12]; + w_mem12_new = w_mem[13]; + w_mem13_new = w_mem[14]; + w_mem14_new = w_mem[15]; + w_mem15_new = w_new; + w_mem_we = 1; + end + end // w_mem_update_logic + + + //---------------------------------------------------------------- + // w_ctr + // W schedule adress counter. Counts from 0x10 to 0x3f and + // is used to expand the block into words. + //---------------------------------------------------------------- + always @* + begin : w_ctr + w_ctr_new = 7'h0; + w_ctr_we = 1'h0; + + if (init_cmd) + begin + w_ctr_new = 7'h00; + w_ctr_we = 1'h1; + end + + if (next_cmd) + begin + w_ctr_new = w_ctr_reg + 7'h01; + w_ctr_we = 1'h1; + end + end // w_ctr + +endmodule // sha512_w_mem + +//====================================================================== +// EOF sha512_w_mem.v +//====================================================================== diff --git a/designs/Caliptra/src/caliptra-rtl/skidbuffer.v b/designs/Caliptra/src/caliptra-rtl/skidbuffer.v new file mode 100644 index 0000000..0d15a11 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/skidbuffer.v @@ -0,0 +1,499 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// Filename: skidbuffer.v +// {{{ +// Project: WB2AXIPSP: bus bridges and other odds and ends +// +// Purpose: A basic SKID buffer. +// {{{ +// Skid buffers are required for high throughput AXI code, since the AXI +// specification requires that all outputs be registered. This means +// that, if there are any stall conditions calculated, it will take a clock +// cycle before the stall can be propagated up stream. This means that +// the data will need to be buffered for a cycle until the stall signal +// can make it to the output. +// +// Handling that buffer is the purpose of this core. +// +// On one end of this core, you have the i_valid and i_data inputs to +// connect to your bus interface. There's also a registered o_ready +// signal to signal stalls for the bus interface. +// +// The other end of the core has the same basic interface, but it isn't +// registered. This allows you to interact with the bus interfaces +// as though they were combinatorial logic, by interacting with this half +// of the core. +// +// If at any time the incoming !stall signal, i_ready, signals a stall, +// the incoming data is placed into a buffer. Internally, that buffer +// is held in r_data with the r_valid flag used to indicate that valid +// data is within it. +// }}} +// Parameters: +// {{{ +// DW or data width +// In order to make this core generic, the width of the data in the +// skid buffer is parameterized +// +// OPT_LOWPOWER +// Forces both o_data and r_data to zero if the respective *VALID +// signal is also low. While this costs extra logic, it can also +// be used to guarantee that any unused values aren't toggling and +// therefore unnecessarily using power. +// +// This excess toggling can be particularly problematic if the +// bus signals have a high fanout rate, or a long signal path +// across an FPGA. +// +// OPT_OUTREG +// Causes the outputs to be registered +// +// OPT_PASSTHROUGH +// Turns the skid buffer into a passthrough. Used for formal +// verification only. +// }}} +// Creator: Dan Gisselquist, Ph.D. +// Gisselquist Technology, LLC +// +// Caliptra Modifications: +// * Revert the default_nettype assignment at file end +// * Convert i_reset from active-high synchronous reset to +// active-low asynchronous reset +// * Enable OPT_INITIAL behavior by default using async reset instead of +// initial block +// +//////////////////////////////////////////////////////////////////////////////// +// }}} +// Copyright (C) 2019-2024, Gisselquist Technology, LLC +// {{{ +// This file is part of the WB2AXIP project. +// +// The WB2AXIP project contains free software and gateware, licensed under the +// Apache License, Version 2.0 (the "License"). You may not use this project, +// or 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. +// +//////////////////////////////////////////////////////////////////////////////// +// +// +`default_nettype none +// }}} +module skidbuffer #( + // {{{ + parameter [0:0] OPT_LOWPOWER = 0, + parameter [0:0] OPT_OUTREG = 1, + // + parameter [0:0] OPT_PASSTHROUGH = 0, + parameter DW = 8 + // }}} + ) ( + // {{{ + input wire i_clk, i_reset, // Changed to resetn, async + input wire i_valid, + output wire o_ready, + input wire [DW-1:0] i_data, + output wire o_valid, + input wire i_ready, + output reg [DW-1:0] o_data + // }}} + ); + + wire [DW-1:0] w_data; + + generate if (OPT_PASSTHROUGH) + begin : PASSTHROUGH + // {{{ + assign { o_valid, o_ready } = { i_valid, i_ready }; + + always @(*) + if (!i_valid && OPT_LOWPOWER) + o_data = 0; + else + o_data = i_data; + + assign w_data = 0; + + // Keep Verilator happy + // Verilator lint_off UNUSED + // {{{ + wire unused_passthrough; + assign unused_passthrough = &{ 1'b0, i_clk, i_reset }; + // }}} + // Verilator lint_on UNUSED + // }}} + end else begin : BUF_STAGE + // We'll start with skid buffer itself + // {{{ + reg r_valid; + reg [DW-1:0] r_data; + + // r_valid + // {{{ + always @(posedge i_clk or negedge i_reset) + if (!i_reset) + r_valid <= 0; + else if ((i_valid && o_ready) && (o_valid && !i_ready)) + // We have incoming data, but the output is stalled + r_valid <= 1; + else if (i_ready) + r_valid <= 0; + // }}} + + // r_data + // {{{ + always @(posedge i_clk or negedge i_reset) + if (!i_reset) + r_data <= 0; + else if (OPT_LOWPOWER && (!o_valid || i_ready)) + r_data <= 0; + else if ((!OPT_LOWPOWER || !OPT_OUTREG || i_valid) && o_ready) + r_data <= i_data; + + assign w_data = r_data; + // }}} + + // o_ready + // {{{ + assign o_ready = !r_valid; + // }}} + + // + // And then move on to the output port + // + if (!OPT_OUTREG) + begin : NET_OUTPUT + // Outputs are combinatorially determined from inputs + // {{{ + // o_valid + // {{{ + // NOTE: As i_reset is now asynchronous, omit from the equation + assign o_valid = /*i_reset && */(i_valid || r_valid); + // }}} + + // o_data + // {{{ + always @(*) + if (r_valid) + o_data = r_data; + else if (!OPT_LOWPOWER || i_valid) + o_data = i_data; + else + o_data = 0; + // }}} + // }}} + end else begin : REG_OUTPUT + // Register our outputs + // {{{ + // o_valid + // {{{ + reg ro_valid; + + always @(posedge i_clk or negedge i_reset) + if (!i_reset) + ro_valid <= 0; + else if (!o_valid || i_ready) + ro_valid <= (i_valid || r_valid); + + assign o_valid = ro_valid; + // }}} + + // o_data + // {{{ + always @(posedge i_clk or negedge i_reset) + if (!i_reset) + o_data <= 0; + else if (!o_valid || i_ready) + begin + + if (r_valid) + o_data <= r_data; + else if (!OPT_LOWPOWER || i_valid) + o_data <= i_data; + else + o_data <= 0; + end + // }}} + + // }}} + end + // }}} + end endgenerate + + // Keep Verilator happy + // {{{ + // Verilator lint_off UNUSED + wire unused; + assign unused = &{ 1'b0, w_data }; + // Verilator lint_on UNUSED + // }}} +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +// +// Formal properties +// {{{ +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +`ifdef FORMAL +`ifdef SKIDBUFFER +`define ASSUME assume +`else +`define ASSUME assert +`endif + + reg f_past_valid; + + initial f_past_valid = 0; + always @(posedge i_clk) + f_past_valid <= 1; + + always @(*) + if (!f_past_valid) + assume(!i_reset); + + //////////////////////////////////////////////////////////////////////// + // + // Incoming stream properties / assumptions + // {{{ + //////////////////////////////////////////////////////////////////////// + // + always @(posedge i_clk) + if (!f_past_valid) + begin + `ASSUME(!i_valid); + end else if ($past(i_valid && !o_ready && i_reset) && i_reset) + `ASSUME(i_valid && $stable(i_data)); + +`ifdef VERIFIC +`define FORMAL_VERIFIC + // Reset properties + property RESET_CLEARS_IVALID; + @(posedge i_clk) !i_reset |=> !i_valid; + endproperty + + property IDATA_HELD_WHEN_NOT_READY; + @(posedge i_clk) disable iff (!i_reset) + i_valid && !o_ready |=> i_valid && $stable(i_data); + endproperty + +`ifdef SKIDBUFFER + assume property (IDATA_HELD_WHEN_NOT_READY); +`else + assert property (IDATA_HELD_WHEN_NOT_READY); +`endif +`endif + // }}} + //////////////////////////////////////////////////////////////////////// + // + // Outgoing stream properties / assumptions + // {{{ + //////////////////////////////////////////////////////////////////////// + // + + generate if (!OPT_PASSTHROUGH) + begin + + always @(posedge i_clk) + if (!f_past_valid) // || $past(!i_reset)) + begin + // Following any reset, valid must be deasserted + assert(!o_valid); + end else if ($past(o_valid && !i_ready && i_reset) && i_reset) + // Following any stall, valid must remain high and + // data must be preserved + assert(o_valid && $stable(o_data)); + + end endgenerate + // }}} + //////////////////////////////////////////////////////////////////////// + // + // Other properties + // {{{ + //////////////////////////////////////////////////////////////////////// + // + // + generate if (!OPT_PASSTHROUGH) + begin + // Rule #1: + // If registered, then following any reset we should be + // ready for a new request + // {{{ + always @(posedge i_clk) + if (f_past_valid && $past(OPT_OUTREG && !i_reset)) + assert(o_ready); + // }}} + + // Rule #2: + // All incoming data must either go directly to the + // output port, or into the skid buffer + // {{{ +`ifndef VERIFIC + always @(posedge i_clk) + if (f_past_valid && !$past(!i_reset) && $past(i_valid && o_ready + && (!OPT_OUTREG || o_valid) && !i_ready)) + assert(!o_ready && w_data == $past(i_data)); +`else + assert property (@(posedge i_clk) + disable iff (!i_reset) + (i_valid && o_ready + && (!OPT_OUTREG || o_valid) && !i_ready) + |=> (!o_ready && w_data == $past(i_data))); +`endif + // }}} + + // Rule #3: + // After the last transaction, o_valid should become idle + // {{{ + if (!OPT_OUTREG) + begin + // {{{ + always @(posedge i_clk) + if (f_past_valid && !$past(!i_reset) && i_reset + && $past(i_ready)) + begin + assert(o_valid == i_valid); + assert(!i_valid || (o_data == i_data)); + end + // }}} + end else begin + // {{{ + always @(posedge i_clk) + if (f_past_valid && !$past(!i_reset)) + begin + if ($past(i_valid && o_ready)) + assert(o_valid); + + if ($past(!i_valid && o_ready && i_ready)) + assert(!o_valid); + end + // }}} + end + // }}} + + // Rule #4 + // Same thing, but this time for o_ready + // {{{ + always @(posedge i_clk) + if (f_past_valid && $past(!o_ready && i_ready)) + assert(o_ready); + // }}} + + // If OPT_LOWPOWER is set, o_data and w_data both need to be + // zero any time !o_valid or !r_valid respectively + // {{{ + if (OPT_LOWPOWER) + begin + always @(*) + if ((OPT_OUTREG || i_reset) && !o_valid) + assert(o_data == 0); + + always @(*) + if (o_ready) + assert(w_data == 0); + + end + // }}} + end endgenerate + // }}} + //////////////////////////////////////////////////////////////////////// + // + // Cover checks + // {{{ + //////////////////////////////////////////////////////////////////////// + // + // +`ifdef SKIDBUFFER + generate if (!OPT_PASSTHROUGH) + begin + reg f_changed_data; + + initial f_changed_data = 0; + always @(posedge i_clk) + if (!i_reset) + f_changed_data <= 1; + else if (i_valid && $past(!i_valid || o_ready)) + begin + if (i_data != $past(i_data + 1)) + f_changed_data <= 0; + end else if (!i_valid && i_data != 0) + f_changed_data <= 0; + + +`ifndef VERIFIC + reg [3:0] cvr_steps, cvr_hold; + + always @(posedge i_clk) + if (!i_reset) + begin + cvr_steps <= 0; + cvr_hold <= 0; + end else begin + cvr_steps <= cvr_steps + 1; + cvr_hold <= cvr_hold + 1; + case(cvr_steps) + 0: if (o_valid || i_valid) + cvr_steps <= 0; + 1: if (!i_valid || !i_ready) + cvr_steps <= 0; + 2: if (!i_valid || !i_ready) + cvr_steps <= 0; + 3: if (!i_valid || !i_ready) + cvr_steps <= 0; + 4: if (!i_valid || i_ready) + cvr_steps <= 0; + 5: if (!i_valid || !i_ready) + cvr_steps <= 0; + 6: if (!i_valid || !i_ready) + cvr_steps <= 0; + 7: if (!i_valid || i_ready) + cvr_steps <= 0; + 8: if (!i_valid || i_ready) + cvr_steps <= 0; + 9: if (!i_valid || !i_ready) + cvr_steps <= 0; + 10: if (!i_valid || !i_ready) + cvr_steps <= 0; + 11: if (!i_valid || !i_ready) + cvr_steps <= 0; + 12: begin + cvr_steps <= cvr_steps; + cover(!o_valid && !i_valid && f_changed_data); + if (!o_valid || !i_ready) + cvr_steps <= 0; + else + cvr_hold <= cvr_hold + 1; + end + default: assert(0); + endcase + end + +`else + // Cover test + cover property (@(posedge i_clk) + disable iff (!i_reset) + (!o_valid && !i_valid) + ##1 i_valid && i_ready [*3] + ##1 i_valid && !i_ready + ##1 i_valid && i_ready [*2] + ##1 i_valid && !i_ready [*2] + ##1 i_valid && i_ready [*3] + // Wait for the design to clear + ##1 o_valid && i_ready [*0:5] + ##1 (!o_valid && !i_valid && f_changed_data)); +`endif + end endgenerate +`endif // SKIDBUFFER + // }}} +`endif +// }}} +endmodule +`default_nettype wire diff --git a/designs/Caliptra/src/caliptra-rtl/soc_ifc_arb.sv b/designs/Caliptra/src/caliptra-rtl/soc_ifc_arb.sv new file mode 100644 index 0000000..470bf7e --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/soc_ifc_arb.sv @@ -0,0 +1,257 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. + +module soc_ifc_arb + import soc_ifc_pkg::*; + #( + parameter AXI_USER_WIDTH = 32 + )( + input logic clk, + input logic rst_b, + + input logic [4:0][AXI_USER_WIDTH-1:0] valid_mbox_users, + input logic valid_fuse_user, + input logic valid_sha_user, + //UC inf + input logic uc_req_dv, + output logic uc_req_hold, + input soc_ifc_req_t uc_req_data, + output logic [SOC_IFC_DATA_W-1:0] uc_rdata, + output logic uc_error, + //SOC inf + input logic soc_req_dv, + output logic soc_req_hold, + input soc_ifc_req_t soc_req_data, + output logic [SOC_IFC_DATA_W-1:0] soc_rdata, + output logic soc_error, + //MBOX inf + output logic mbox_req_dv, + output logic mbox_dir_req_dv, + input logic mbox_req_hold, + output soc_ifc_req_t mbox_req_data, + input logic [SOC_IFC_DATA_W-1:0] mbox_rdata, + input logic [SOC_IFC_DATA_W-1:0] mbox_dir_rdata, + input logic mbox_error, + //SHA inf + output logic sha_req_dv, + input logic sha_req_hold, + output soc_ifc_req_t sha_req_data, + input logic [SOC_IFC_DATA_W-1:0] sha_rdata, + input logic sha_error, + // AXI DMA INF + output logic dma_reg_req_dv, + output soc_ifc_req_t dma_reg_req_data, + input logic dma_reg_req_hold, + input logic [SOC_IFC_DATA_W-1:0] dma_reg_rdata, + input logic dma_reg_error, + + //SOC IFC REG inf + output logic soc_ifc_reg_req_dv, + input logic soc_ifc_reg_req_hold, + output soc_ifc_req_t soc_ifc_reg_req_data, + input logic [SOC_IFC_DATA_W-1:0] soc_ifc_reg_rdata, + input logic soc_ifc_reg_error + +); +//track priority +logic soc_priority; +logic uc_has_priority; +logic soc_has_priority; +logic toggle_priority; +logic req_collision; + +//dv for each req/target +logic soc_mbox_req; +logic soc_reg_req; +logic soc_sha_req; +logic soc_dma_req; + +logic uc_mbox_req; +logic uc_mbox_reg_req; +logic uc_mbox_dir_req; +logic uc_reg_req; +logic uc_sha_req; +logic uc_dma_req; + +//grant for each request +logic soc_mbox_gnt; +logic soc_reg_gnt; +logic soc_sha_gnt; +logic soc_dma_gnt; + +logic uc_mbox_gnt; +logic uc_reg_gnt; +logic uc_sha_gnt; +logic uc_dma_gnt; + +//track in-progress grants +logic soc_req_ip; + +logic uc_req_ip; + +//filter mailbox requests by user +logic valid_mbox_req; + + +//simple arbitration scheme, track most recently granted client (SOC or UC) +//give priority in case of collision to the least recently granted client +always_ff @(posedge clk or negedge rst_b) begin + if (!rst_b) begin + soc_priority <= '0; + + soc_req_ip <= '0; + + uc_req_ip <= '0; + end + else begin + soc_priority <= toggle_priority ? ~soc_priority : soc_priority; + + soc_req_ip <= (soc_mbox_gnt & mbox_req_hold) | (soc_reg_gnt & soc_ifc_reg_req_hold) | (soc_sha_gnt & sha_req_hold) | (soc_dma_gnt & dma_reg_req_hold); + + uc_req_ip <= (uc_mbox_gnt & mbox_req_hold) | (uc_reg_gnt & soc_ifc_reg_req_hold) | (uc_sha_gnt & sha_req_hold) | (uc_dma_gnt & dma_reg_req_hold); + end +end +//Assign priority - first to the client who's already in progress and held +// second to the client with priority pointing to them, unless there is a req ip +// This condition only matters for collisions. Simultaneous transactions to different +// destinations can result in both signals being asserted together. +always_comb uc_has_priority = uc_req_ip | (~soc_priority & ~soc_req_ip); +always_comb soc_has_priority = soc_req_ip | ( soc_priority & ~uc_req_ip); + +//toggle the priority when collision is detected +always_comb toggle_priority = req_collision; + +//figure out which client is requesting which block +//uC requests to mailbox +always_comb uc_mbox_req = uc_mbox_reg_req | uc_mbox_dir_req; +always_comb uc_mbox_reg_req = (uc_req_dv & (uc_req_data.addr inside {[MBOX_REG_START_ADDR:MBOX_REG_END_ADDR]})); +/* verilator lint_off UNSIGNED */ +always_comb uc_mbox_dir_req = (uc_req_dv & (uc_req_data.addr inside {[MBOX_DIR_START_ADDR:MBOX_DIR_END_ADDR]})); +/* verilator lint_on UNSIGNED */ +//SoC requests to mailbox +always_comb soc_mbox_req = (valid_mbox_req & (soc_req_data.addr inside {[MBOX_REG_START_ADDR:MBOX_REG_END_ADDR]})); +//Requests to arch/fuse register block +//Ensure that requests to fuse block match the appropriate user value +always_comb uc_reg_req = (uc_req_dv & (uc_req_data.addr inside {[SOC_IFC_REG_START_ADDR:SOC_IFC_REG_END_ADDR]})); +always_comb soc_reg_req = (soc_req_dv & (soc_req_data.addr inside {[SOC_IFC_REG_START_ADDR:SOC_IFC_REG_END_ADDR]}) & + (~(soc_req_data.addr inside {[SOC_IFC_FUSE_START_ADDR:SOC_IFC_FUSE_END_ADDR]}) | valid_fuse_user)); + +//Requests to SHA +always_comb uc_sha_req = (uc_req_dv & (uc_req_data.addr inside {[SHA_REG_START_ADDR:SHA_REG_END_ADDR]})); +always_comb soc_sha_req = (soc_req_dv & (soc_req_data.addr inside {[SHA_REG_START_ADDR:SHA_REG_END_ADDR]})) & valid_sha_user; + +// Requests to DMA +always_comb uc_dma_req = (uc_req_dv & (uc_req_data.addr inside {[DMA_REG_START_ADDR:DMA_REG_END_ADDR]})); +always_comb soc_dma_req = (soc_req_dv & (soc_req_data.addr inside {[DMA_REG_START_ADDR:DMA_REG_END_ADDR]})); + +//Check if SoC request is coming from a valid user +//There are 5 valid user registers, check if user attribute matches any of them +//Check if user matches Default Valid user parameter - this user value is always valid +always_comb begin + valid_mbox_req = '0; + for (int i=0; i < 5; i++) begin + valid_mbox_req |= soc_req_dv & (soc_req_data.user == valid_mbox_users[i]); + end + valid_mbox_req |= soc_req_dv & (soc_req_data.user == CPTRA_DEF_MBOX_VALID_AXI_USER[SOC_IFC_USER_W-1:0]); +end + +//check for collisions +//don't toggle priority if the request was held +always_comb req_collision = (uc_mbox_req & soc_mbox_req & ~mbox_req_hold) | + (uc_reg_req & soc_reg_req & ~soc_ifc_reg_req_hold) | + (uc_sha_req & soc_sha_req & ~sha_req_hold) | + (uc_dma_req & soc_dma_req & ~dma_reg_req_hold); + +//drive the dv to the appropriate destination if either client is trying to +always_comb mbox_req_dv = uc_mbox_reg_req | soc_mbox_gnt; +always_comb mbox_dir_req_dv = uc_mbox_dir_req & uc_mbox_gnt; +always_comb soc_ifc_reg_req_dv = uc_reg_req | soc_reg_req; +always_comb sha_req_dv = uc_sha_req | soc_sha_req; +always_comb dma_reg_req_dv = uc_dma_req | soc_dma_req; + +//determine which requests get granted +//if a request is colliding with another, grant the one with priority +//ignore priority if one of the requests was already in progress +//this prevents the "priority" request from interrupting an in progress request +always_comb soc_mbox_gnt = soc_mbox_req & (~uc_mbox_req | soc_has_priority); +always_comb soc_reg_gnt = soc_reg_req & (~uc_reg_req | soc_has_priority); +always_comb soc_sha_gnt = soc_sha_req & (~uc_sha_req | soc_has_priority); +always_comb soc_dma_gnt = soc_dma_req & (~uc_dma_req | soc_has_priority); + +always_comb uc_mbox_gnt = uc_mbox_req & (~soc_mbox_req | uc_has_priority); +always_comb uc_reg_gnt = uc_reg_req & (~soc_reg_req | uc_has_priority); +always_comb uc_sha_gnt = uc_sha_req & (~soc_sha_req | uc_has_priority); +always_comb uc_dma_gnt = uc_dma_req & (~soc_dma_req | uc_has_priority); + +//drive the appropriate request to each destination +always_comb mbox_req_data = ({$bits(soc_ifc_req_t){soc_mbox_gnt}} & soc_req_data) | + ({$bits(soc_ifc_req_t){uc_mbox_gnt}} & uc_req_data); + +always_comb soc_ifc_reg_req_data = ({$bits(soc_ifc_req_t){soc_reg_gnt}} & soc_req_data) | + ({$bits(soc_ifc_req_t){uc_reg_gnt}} & uc_req_data); + +always_comb sha_req_data = ({$bits(soc_ifc_req_t){soc_sha_gnt}} & soc_req_data) | + ({$bits(soc_ifc_req_t){uc_sha_gnt}} & uc_req_data); + +always_comb dma_reg_req_data = ({$bits(soc_ifc_req_t){soc_dma_gnt}} & soc_req_data) | + ({$bits(soc_ifc_req_t){uc_dma_gnt}} & uc_req_data); + +//drive the appropriate read data back to uc or soc +//AND/OR mux here, assert that requests are always mutex +always_comb uc_rdata = ({SOC_IFC_DATA_W{uc_mbox_reg_req}} & mbox_rdata) | + ({SOC_IFC_DATA_W{uc_mbox_dir_req}} & mbox_dir_rdata) | + ({SOC_IFC_DATA_W{uc_reg_req}} & soc_ifc_reg_rdata) | + ({SOC_IFC_DATA_W{uc_sha_req}} & sha_rdata) | + ({SOC_IFC_DATA_W{uc_dma_req}} & dma_reg_rdata); + +always_comb soc_rdata = ({SOC_IFC_DATA_W{soc_mbox_req}} & mbox_rdata) | + ({SOC_IFC_DATA_W{soc_reg_req}} & soc_ifc_reg_rdata) | + ({SOC_IFC_DATA_W{soc_sha_req}} & sha_rdata) | + ({SOC_IFC_DATA_W{soc_dma_req}} & dma_reg_rdata); + +//drive the appropraite holds back to uc or soc +//AND/OR mux here, assert that requests are always mutex +always_comb uc_req_hold = (uc_mbox_req & (~uc_mbox_gnt | mbox_req_hold)) | + (uc_reg_req & (~uc_reg_gnt | soc_ifc_reg_req_hold)) | + (uc_sha_req & (~ uc_sha_gnt | sha_req_hold)) | + (uc_dma_req & (~ uc_dma_gnt | dma_reg_req_hold)); + +always_comb soc_req_hold = (soc_mbox_req & (~soc_mbox_gnt | mbox_req_hold)) | + (soc_reg_req & (~soc_reg_gnt | soc_ifc_reg_req_hold)) | + (soc_sha_req & (~soc_sha_gnt | sha_req_hold)) | + (soc_dma_req & (~soc_dma_gnt | dma_reg_req_hold)); + +//Assert error when requested client drives error back, or a request is made that doesn't map to any of the clients +always_comb uc_error = (uc_mbox_gnt & mbox_error) | + (uc_reg_gnt & soc_ifc_reg_error) | + (uc_sha_gnt & sha_error) | + (uc_dma_gnt & dma_reg_error) | + (uc_req_dv & ~(uc_mbox_req | uc_reg_req | uc_sha_req | uc_dma_req)); + +always_comb soc_error = (soc_mbox_gnt & mbox_error) | + (soc_reg_gnt & soc_ifc_reg_error) | + (soc_sha_gnt & sha_error) | + (soc_dma_gnt & dma_reg_error) | + (soc_req_dv & ~(soc_mbox_req | soc_reg_req | soc_sha_req | soc_dma_req)); + +`CALIPTRA_ASSERT (ERR_ARB_MBOX_ADDR , mbox_req_dv -> mbox_req_data.addr inside {[MBOX_REG_START_ADDR:MBOX_REG_END_ADDR]}, clk, !rst_b) +`CALIPTRA_ASSERT (ERR_ARB_MBOX_DIR_ADDR , mbox_dir_req_dv -> mbox_req_data.addr inside {[MBOX_DIR_START_ADDR:MBOX_DIR_END_ADDR]}, clk, !rst_b) + +`CALIPTRA_ASSERT_MUTEX(ERR_ARB_MBOX_ACCESS_MUTEX, {uc_mbox_gnt,soc_mbox_gnt}, clk, !rst_b) +`CALIPTRA_ASSERT_MUTEX(ERR_ARB_REG_ACCESS_MUTEX , {uc_reg_gnt,soc_reg_gnt}, clk, !rst_b) +`CALIPTRA_ASSERT_MUTEX(ERR_ARB_SHA_ACCESS_MUTEX , {uc_sha_gnt,soc_sha_gnt}, clk, !rst_b) +`CALIPTRA_ASSERT_MUTEX(ERR_ARB_DMA_ACCESS_MUTEX , {uc_dma_gnt,soc_dma_gnt}, clk, !rst_b) +`CALIPTRA_ASSERT_MUTEX(ERR_ARB_MBOX_REG_AND_DIR_ACCESS_MUTEX, {mbox_req_dv,mbox_dir_req_dv}, clk, !rst_b) + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/soc_ifc_boot_fsm.sv b/designs/Caliptra/src/caliptra-rtl/soc_ifc_boot_fsm.sv new file mode 100644 index 0000000..27bd118 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/soc_ifc_boot_fsm.sv @@ -0,0 +1,275 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. + +module soc_ifc_boot_fsm + import soc_ifc_pkg::*; + import soc_ifc_reg_pkg::*; + ( + input logic clk, + input logic cptra_pwrgood, + input logic cptra_rst_b, + input logic scan_mode, + input logic fw_update_rst, + input logic [7:0] fw_update_rst_wait_cycles, + + // Debug wires to Stop the BootFSM from bringing uC out of reset and continue on a write + input logic BootFSM_BrkPoint, + input logic BootFSM_Continue, + + output logic ready_for_fuses, + output boot_fsm_state_e boot_fsm_ps, + + input logic fuse_done, + input logic fuse_wr_done_observed, + + output logic cptra_noncore_rst_b, //Global rst that goes to all other blocks + output logic cptra_uc_rst_b, //Global + fw update rst that goes to VeeR core only, + output logic iccm_unlock, + output logic fw_upd_rst_executed, + output logic rdc_clk_dis, + output logic fw_update_rst_window +); + +`include "caliptra_sva.svh" + +logic cptra_uc_rst_b_nq; +logic cptra_noncore_rst_b_nq; + +//present and next state +boot_fsm_state_e boot_fsm_ns; +//arcs between states - global rst +logic arc_BOOT_IDLE_BOOT_FUSE; +logic arc_BOOT_FUSE_BOOT_DONE; +logic arc_BOOT_FUSE_BOOT_WAIT; +logic arc_BOOT_DONE_BOOT_IDLE; +//arcs for fw update rst +logic arc_BOOT_DONE_BOOT_FWRST; +logic arc_BOOT_FWRST_BOOT_WAIT; +logic arc_BOOT_WAIT_BOOT_DONE; +logic arc_IDLE; +//reset generation +logic fsm_synch_noncore_rst_b; +logic synch_noncore_rst_b; +logic fsm_synch_uc_rst_b; +logic synch_uc_rst_b; + +logic fsm_iccm_unlock; +logic [7:0] wait_count; +logic wait_count_rst; +logic wait_count_decr; + +logic cptra_rst_window; +logic cptra_rst_window_sync, cptra_rst_window_sync_f, cptra_rst_window_sync_2f; + +//move to fuse state when SoC de-asserts reset +always_comb arc_BOOT_IDLE_BOOT_FUSE = (boot_fsm_ps == BOOT_IDLE) & ~cptra_rst_window_sync & ~cptra_rst_window_sync_f & ~cptra_rst_window_sync_2f; +//move from fuse state to done when fuse done register is set OR +//if it was already set (since its locked across warm reset), that the write was observed from SOC +always_comb arc_BOOT_FUSE_BOOT_DONE = fuse_done & fuse_wr_done_observed; + +// Hold the bootFSM from bringing uC out of reset if the breakpoint is set after fuse writes are done +always_comb arc_BOOT_FUSE_BOOT_WAIT = BootFSM_BrkPoint; + +//dummy arc for terminal state lint check +always_comb arc_BOOT_DONE_BOOT_IDLE = '0; + +always_comb arc_IDLE = cptra_rst_window_sync; + +//Masks combo paths from uc reset flops into other reset domains +always_comb fw_update_rst_window = (boot_fsm_ps == BOOT_FW_RST) | + ((boot_fsm_ps == BOOT_WAIT) & (wait_count != 0)); +//clock gate all flops on warm reset to prevent RDC metastability issues +//cover 2 clocks after synchronized reset assertion (cptra_rst_window_sync) to handle bootfsm transitions +always_comb rdc_clk_dis = cptra_rst_window_sync | cptra_rst_window_sync_f | cptra_rst_window_sync_2f; + +//move to rst state when reg bit is set to 1. This state will assert fw_rst to uc +always_comb arc_BOOT_DONE_BOOT_FWRST = (boot_fsm_ps == BOOT_DONE) & fw_update_rst; +//advance to boot wait when reset starts to propagate +always_comb arc_BOOT_FWRST_BOOT_WAIT = ~synch_uc_rst_b; + +// Move to BOOT_DONE state when +// a fixed time is met AND +// if the BootFSM breakpoint is asserted and the BootFSM continue is not set, stay put in WAIT state +always_comb arc_BOOT_WAIT_BOOT_DONE = (wait_count == '0) & ~(BootFSM_BrkPoint & ~BootFSM_Continue); + + +always_comb begin + boot_fsm_ns = boot_fsm_ps; + fw_upd_rst_executed = '0; + fsm_synch_noncore_rst_b = '0; + fsm_iccm_unlock = '0; + fsm_synch_uc_rst_b = '0; + wait_count_decr = 0; + wait_count_rst = 0; + + unique case (boot_fsm_ps) inside + BOOT_IDLE: begin + if (arc_BOOT_IDLE_BOOT_FUSE) begin + boot_fsm_ns = BOOT_FUSE; + end + //reset flags in IDLE + // NOTE: FSM is only in BOOT_IDLE when system reset is asserted, so + // also assert the internal core/noncore resets + fsm_synch_uc_rst_b = '0; + fsm_synch_noncore_rst_b = '0; + fsm_iccm_unlock = '0; + wait_count_decr = 0; + wait_count_rst = 0; + end + BOOT_FUSE: begin + if (arc_BOOT_FUSE_BOOT_DONE) begin + if (arc_BOOT_FUSE_BOOT_WAIT) begin + boot_fsm_ns = BOOT_WAIT; + end + else begin + boot_fsm_ns = BOOT_DONE; + end + end + + //reset flags + fsm_synch_uc_rst_b = '0; + fsm_synch_noncore_rst_b = '1; + fsm_iccm_unlock = '0; + wait_count_decr = 0; + wait_count_rst = 0; + end + BOOT_FW_RST: begin + if (arc_BOOT_FWRST_BOOT_WAIT) boot_fsm_ns = BOOT_WAIT; + + //Assert core reset + fsm_synch_uc_rst_b = '0; + fsm_synch_noncore_rst_b = '1; + //Keep ICCM locked until end of fw rst + fsm_iccm_unlock = '0; + //Start timer + wait_count_decr = 0; + wait_count_rst = 1; + end + BOOT_WAIT: begin + if (arc_BOOT_WAIT_BOOT_DONE) begin + boot_fsm_ns = BOOT_DONE; + fsm_iccm_unlock = 1'b1; + end + // Unlock ICCM at the end of reset flow to avoid a potential + // race-condition attack against ICCM + else begin + fsm_iccm_unlock = '0; + end + fsm_synch_uc_rst_b = '0; + fsm_synch_noncore_rst_b = '1; + wait_count_decr = 1; + wait_count_rst = 0; + end + BOOT_DONE: begin + if (arc_BOOT_DONE_BOOT_IDLE) begin + boot_fsm_ns = BOOT_IDLE; + end + else if (arc_BOOT_DONE_BOOT_FWRST) begin + boot_fsm_ns = BOOT_FW_RST; + // Even a single FW_UPD_RESET flow will assert this bit and it will never be deasserted. + // This is fine because if there is WARM or COLD RESET, this register bit gets reset. + // Implying the only time this bit can be observed as '1 is because the reset is happening due to a FW UPD RESET + // If that assumption changes, by adding a new reset state, then this bit needs to change + fw_upd_rst_executed = 1; + end + + //Deassert reset + fsm_synch_uc_rst_b = '1; + fsm_synch_noncore_rst_b = '1; + fsm_iccm_unlock = '0; + //Timer re-init + wait_count_rst = 0; + wait_count_decr = 0; + end + default: begin + boot_fsm_ns = boot_fsm_ps; + fw_upd_rst_executed = '0; + fsm_synch_noncore_rst_b = '0; + fsm_iccm_unlock = '0; + fsm_synch_uc_rst_b = '0; + wait_count_decr = 0; + wait_count_rst = 0; + end + endcase +end + +//next state -> present state +//reset boot fsm to idle on cptra_pwrgood +always_ff @(posedge clk or negedge cptra_pwrgood) begin + if (~cptra_pwrgood) begin + boot_fsm_ps <= BOOT_IDLE; + synch_noncore_rst_b <= '0; + synch_uc_rst_b <= 0; + cptra_noncore_rst_b_nq <= '0; + cptra_uc_rst_b_nq <= '0; + + cptra_rst_window_sync_f <= '1; + cptra_rst_window_sync_2f <= '1; + end + else begin + boot_fsm_ps <= arc_IDLE ? BOOT_IDLE : boot_fsm_ns; + synch_noncore_rst_b <= fsm_synch_noncore_rst_b; + synch_uc_rst_b <= fsm_synch_uc_rst_b; + cptra_noncore_rst_b_nq <= synch_noncore_rst_b; + cptra_uc_rst_b_nq <= synch_noncore_rst_b && synch_uc_rst_b; //uc comes out of rst only when both global and fw rsts are deasserted (through 2FF sync) + + cptra_rst_window_sync_f <= cptra_rst_window_sync; + cptra_rst_window_sync_2f <= cptra_rst_window_sync_f; + end +end + +//protect resets during scan mode +//utilize warm reset pin to drive reset during scan mode +assign cptra_noncore_rst_b = scan_mode ? cptra_rst_b : cptra_noncore_rst_b_nq; +assign cptra_uc_rst_b = scan_mode ? cptra_rst_b : cptra_uc_rst_b_nq; + +//uC reset generation +always_ff @(posedge clk or negedge cptra_rst_b) begin + if (~cptra_rst_b) begin + cptra_rst_window <= '1; + end + else begin + cptra_rst_window <= 0; + end +end + +// Ready for fuses output signal +always_ff @(posedge clk or negedge cptra_noncore_rst_b) begin + if (~cptra_noncore_rst_b) begin + ready_for_fuses <= 1'b0; + wait_count <= '0; + iccm_unlock <= 0; + end + else begin + ready_for_fuses <= (boot_fsm_ps == BOOT_FUSE) && !fuse_wr_done_observed; + wait_count <= (wait_count_decr && (wait_count != '0)) ? wait_count - 1 : + wait_count_rst ? fw_update_rst_wait_cycles : + wait_count ; + iccm_unlock <= fsm_iccm_unlock; + end +end + +caliptra_2ff_sync #(.WIDTH(1), .RST_VAL('d1)) i_rst_window_sync (.clk(clk), .rst_b(cptra_pwrgood), .din(cptra_rst_window), .dout(cptra_rst_window_sync)); + +//Check for x prop +`CALIPTRA_ASSERT_KNOWN(ERR_FSM_ARC_X, {arc_BOOT_FUSE_BOOT_DONE, arc_BOOT_DONE_BOOT_FWRST, arc_BOOT_WAIT_BOOT_DONE}, clk, !cptra_rst_b) +`CALIPTRA_ASSERT_KNOWN(ERR_FSM_STATE_X, boot_fsm_ps, clk, !cptra_rst_b) +`CALIPTRA_ASSERT_KNOWN(ERR_UC_RST_X, cptra_noncore_rst_b, clk, !cptra_rst_b) +`CALIPTRA_ASSERT_KNOWN(ERR_UC_FWRST_X, cptra_uc_rst_b, clk, !cptra_rst_b) + +//Reset got asserted, but cptra rst window wasn't asserted to protect RDC +`CALIPTRA_ASSERT_NEVER(ERR_RST_ASSERT_NO_WINDOW, $fell(cptra_noncore_rst_b) && ~rdc_clk_dis, clk, !(cptra_pwrgood && ~scan_mode)) +`CALIPTRA_ASSERT_NEVER(ERR_UC_RST_ASSERT_NO_WINDOW, $fell(cptra_uc_rst_b) && ~(fw_update_rst_window || rdc_clk_dis), clk, !(cptra_pwrgood && ~scan_mode)) + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/soc_ifc_cov_bind.sv b/designs/Caliptra/src/caliptra-rtl/soc_ifc_cov_bind.sv new file mode 100644 index 0000000..6072e6b --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/soc_ifc_cov_bind.sv @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. + + +module soc_ifc_cov_bind; + `ifdef FCOV + import soc_ifc_pkg::*; + bind soc_ifc_top soc_ifc_cov_if #( + .AHB_ADDR_WIDTH(`CALIPTRA_SLAVE_ADDR_WIDTH(`CALIPTRA_SLAVE_SEL_SOC_IFC)), + .AHB_DATA_WIDTH(`CALIPTRA_AHB_HDATA_SIZE), + .AXI_ADDR_WIDTH(`CALIPTRA_SLAVE_ADDR_WIDTH(`CALIPTRA_SLAVE_SEL_SOC_IFC)), + .AXI_DATA_WIDTH(`CALIPTRA_AXI_DATA_WIDTH), + .AXI_ID_WIDTH (`CALIPTRA_AXI_ID_WIDTH ), + .AXI_USER_WIDTH(`CALIPTRA_AXI_USER_WIDTH), + .AXIM_ADDR_WIDTH(`CALIPTRA_AXI_DMA_ADDR_WIDTH), + .AXIM_DATA_WIDTH(soc_ifc_pkg::CPTRA_AXI_DMA_DATA_WIDTH), + .AXIM_ID_WIDTH (soc_ifc_pkg::CPTRA_AXI_DMA_ID_WIDTH), + .AXIM_USER_WIDTH(soc_ifc_pkg::CPTRA_AXI_DMA_USER_WIDTH) + ) + i_soc_ifc_cov_if (.*); + `endif +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/soc_ifc_cov_if.sv b/designs/Caliptra/src/caliptra-rtl/soc_ifc_cov_if.sv new file mode 100644 index 0000000..6911a25 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/soc_ifc_cov_if.sv @@ -0,0 +1,4328 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. + + + +// -- What the section under 'SCRIPT_OUTPUT' output covers -- +// +// Covergroups. +// - One per register; array of wide registers are under a single covergroup. +// +// Coverpoints: +// - Bins for total addressible space per register (including all fields) +// - Transition bins: An AXI or AHB Write followed by AXI or AHB Read within 1000 cycles +// - Ignore bins: IDLE (no read/write activity), simultaneous RD and WR over AXI or AHB. +// +// Not covered and TODO. +// - Bins for individual fields within a register for special behavior. +// - New covergroups likely needed for cross coverage of related registers. +// - Registers that don't have storage allocated (CPTRA_SECURITY_STATE, CPTRA_HW_REV_ID, CPTRA_HW_CONFIG) +// - Possibly reduce the number of unique covergroup definitions + + +`ifndef VERILATOR + +interface soc_ifc_cov_if + import soc_ifc_pkg::*; + import mbox_pkg::*; + import soc_ifc_reg_pkg::*; + import axi_pkg::*; + import axi_dma_reg_pkg::*; + import kv_defines_pkg::*; + #( + parameter AXI_ADDR_WIDTH = 18 + ,parameter AXI_DATA_WIDTH = 32 + ,parameter AXI_ID_WIDTH = 32 + ,parameter AXI_USER_WIDTH = 32 + ,parameter AHB_ADDR_WIDTH = 18 + ,parameter AHB_DATA_WIDTH = 32 + ,parameter AXIM_ADDR_WIDTH = 48 + ,parameter AXIM_DATA_WIDTH = 32 + ,parameter AXIM_ID_WIDTH = 5 + ,parameter AXIM_USER_WIDTH = 32 + ) + ( + input logic clk, + input logic clk_cg, + input logic soc_ifc_clk_cg, + input logic rdc_clk_cg, + + //SoC boot signals + input logic cptra_pwrgood, + input logic cptra_rst_b, + + input logic ready_for_fuses, + input logic ready_for_mb_processing, + input logic ready_for_runtime, + + input logic mailbox_data_avail, + input logic mailbox_flow_done, + + input logic recovery_data_avail, + input logic recovery_image_activated, + + input var security_state_t security_state, + + input logic [1:0][31:0] generic_input_wires, + input logic BootFSM_BrkPoint, + input logic [1:0][31:0] generic_output_wires, + + //SoC AXI Interface + axi_if.w_sub s_axi_w_if, + axi_if.r_sub s_axi_r_if, + + //uC AHB Lite Interface + input logic [AHB_ADDR_WIDTH-1:0] haddr_i, + input logic [AHB_DATA_WIDTH-1:0] hwdata_i, + input logic hsel_i, + input logic hwrite_i, + input logic hready_i, + input logic [1:0] htrans_i, + input logic [2:0] hsize_i, + + input logic hresp_o, + input logic hreadyout_o, + input logic [AHB_DATA_WIDTH-1:0] hrdata_o, + + // AXI Manager INF + axi_if.w_mgr m_axi_w_if, + axi_if.r_mgr m_axi_r_if, + + //SoC Interrupts + input logic cptra_error_fatal, + input logic cptra_error_non_fatal, + input logic trng_req, + + //uC Interrupts + input wire soc_ifc_error_intr, + input wire soc_ifc_notif_intr, + input wire sha_error_intr, + input wire sha_notif_intr, + input wire dma_error_intr, + input wire dma_notif_intr, + input wire timer_intr, + + //SRAM interface + input cptra_mbox_sram_req_t mbox_sram_req, + input cptra_mbox_sram_resp_t mbox_sram_resp, + + // RV ECC Status Interface + input rv_ecc_sts_t rv_ecc_sts, + + // Clear KeyVault secrets + input logic debugUnlock_or_scan_mode_switch, + + //Obfuscated UDS and FE + input logic clear_obf_secrets, + input logic scan_mode, + input logic [`CLP_OBF_KEY_DWORDS-1:0][31:0] cptra_obf_key, + input logic [`CLP_OBF_KEY_DWORDS-1:0][31:0] cptra_obf_key_reg, + input logic cptra_obf_field_entropy_vld, + input logic [`CLP_OBF_FE_DWORDS-1 :0][31:0] cptra_obf_field_entropy, + input logic [`CLP_OBF_FE_DWORDS-1 :0][31:0] obf_field_entropy, + input logic cptra_obf_uds_seed_vld, + input logic [`CLP_OBF_UDS_DWORDS-1:0][31:0] cptra_obf_uds_seed, + input logic [`CLP_OBF_UDS_DWORDS-1:0][31:0] obf_uds_seed, + input logic [OCP_LOCK_HEK_NUM_DWORDS-1:0][31:0] obf_hek_seed, + + input logic aes_input_ready, + input logic aes_output_valid, + input logic aes_status_idle, + input logic aes_req_dv, + input logic aes_req_hold, + input soc_ifc_req_t aes_req_data, + input logic [SOC_IFC_DATA_W-1:0] aes_rdata, + input logic aes_error, + + // kv interface + input kv_read_t kv_read, + input kv_rd_resp_t kv_rd_resp, + + + // Subsystem mode straps + input logic [63:0] strap_ss_caliptra_base_addr, + input logic [63:0] strap_ss_mci_base_addr, + input logic [63:0] strap_ss_recovery_ifc_base_addr, + input logic [63:0] strap_ss_external_staging_area_base_addr, + input logic [63:0] strap_ss_otp_fc_base_addr, + input logic [63:0] strap_ss_uds_seed_base_addr, + input logic [63:0] strap_ss_key_release_base_addr, + input logic [15:0] strap_ss_key_release_key_size, + input logic [31:0] strap_ss_prod_debug_unlock_auth_pk_hash_reg_bank_offset, + input logic [31:0] strap_ss_num_of_prod_debug_unlock_auth_pk_hashes, + input logic [31:0] strap_ss_strap_generic_0, + input logic [31:0] strap_ss_strap_generic_1, + input logic [31:0] strap_ss_strap_generic_2, + input logic [31:0] strap_ss_strap_generic_3, + input logic [31:0] strap_ss_caliptra_dma_axi_user, + input logic ss_debug_intent, + input logic cptra_ss_debug_intent, + + // Subsystem mode debug outputs + input logic ss_dbg_manuf_enable, + input logic [63:0] ss_soc_dbg_unlock_level, + + // Subsystem mode firmware execution control + input logic [127:0] ss_generic_fw_exec_ctrl, + + // Subsystem mode OCP LOCK status + input logic ss_ocp_lock_en, + input logic ss_ocp_lock_in_progress, + input logic [15:0] ss_key_release_key_size, + + // NMI Vector + input logic [31:0] nmi_vector, + input logic nmi_intr, + + // ICCM Lock + input logic iccm_lock, + input logic iccm_axs_blocked, + + //soc ifc register HW inf + input soc_ifc_reg__out_t soc_ifc_reg_hwif_out, + + //Other blocks reset + input logic cptra_noncore_rst_b, + //uC reset + input logic cptra_uc_rst_b, + //Clock gating + input logic clk_gating_en, + input logic rdc_clk_dis, + input logic fw_update_rst_window, + + input logic crypto_error, + + input logic uc_req_dv, + input soc_ifc_req_t uc_req, + input logic soc_req_dv, + input soc_ifc_req_t soc_req, + input logic soc_ifc_reg_req_dv, + input soc_ifc_req_t soc_ifc_reg_req_data + +); + + `define AXI_DMA_TOP i_axi_dma + `define AXI_DMA_CTRL `AXI_DMA_TOP.i_axi_dma_ctrl + + enum bit [3:0] {IDLE = '0, AHB_RD = 4'h8, AHB_WR = 4'h4, AXI_RD = 4'h2, AXI_WR = 4'h1} bus_event_e; + + typedef enum logic [1:0] { + DMA_IDLE, + DMA_WAIT_DATA, + DMA_DONE, + DMA_ERROR + } dma_ctrl_fsm_e; + + axi_dma_reg__ctrl__rd_route__rd_route_e_e dma_rd_route; + axi_dma_reg__ctrl__wr_route__wr_route_e_e dma_wr_route; + dma_ctrl_fsm_e dma_ctrl_fsm_ps; + + assign dma_rd_route = axi_dma_reg__ctrl__rd_route__rd_route_e_e'(`AXI_DMA_CTRL.hwif_out.ctrl.rd_route.value); + assign dma_wr_route = axi_dma_reg__ctrl__wr_route__wr_route_e_e'(`AXI_DMA_CTRL.hwif_out.ctrl.wr_route.value); + assign dma_ctrl_fsm_ps = dma_ctrl_fsm_e'(`AXI_DMA_CTRL.ctrl_fsm_ps); + + logic uc_rd, uc_wr, soc_rd, soc_wr; + logic [63:0] generic_input_wires_flat; + logic [63:0] generic_output_wires_flat; + + assign uc_rd = uc_req_dv & ~uc_req.write; + assign uc_wr = uc_req_dv & uc_req.write; + assign soc_rd = soc_req_dv & ~soc_req.write; + assign soc_wr = soc_req_dv & soc_req.write; + + assign generic_input_wires_flat = {generic_input_wires [1],generic_input_wires [0]}; + assign generic_output_wires_flat = {generic_output_wires[1],generic_output_wires[0]}; + + covergroup soc_ifc_top_cov_grp @(posedge clk); + //IO + cptra_pwrgood_cp: coverpoint cptra_pwrgood; + cptra_rst_b_cp: coverpoint cptra_rst_b; + cptra_noncore_rst_b_cp: coverpoint cptra_noncore_rst_b; + cptra_uc_rst_b_cp: coverpoint cptra_uc_rst_b; + clk_gating_en_cp: coverpoint clk_gating_en; + rdc_clk_dis_cp: coverpoint rdc_clk_dis; + fw_update_rst_window_cp: coverpoint fw_update_rst_window; + crypto_error_cp: coverpoint crypto_error; + security_state_cp: coverpoint security_state; + ready_for_fuses_cp: coverpoint ready_for_fuses; + ready_for_mb_processing_cp: coverpoint ready_for_mb_processing; + ready_for_runtime_cp: coverpoint ready_for_runtime; + mailbox_data_avail_cp: coverpoint mailbox_data_avail; + mailbox_flow_done_cp: coverpoint mailbox_flow_done; + recovery_data_avail_cp: coverpoint recovery_data_avail; + recovery_image_activated_cp: coverpoint recovery_image_activated; + cptra_error_fatal_cp: coverpoint cptra_error_fatal; + cptra_error_non_fatal_cp: coverpoint cptra_error_non_fatal; + trng_req_cp: coverpoint trng_req; + BootFSM_BrkPoint_cp: coverpoint BootFSM_BrkPoint; + generic_input_wires_cp: coverpoint generic_input_wires_flat { + bins byte0_active = generic_input_wires_cp with (|(item & (64'hFF << 0))); + bins byte1_active = generic_input_wires_cp with (|(item & (64'hFF << 8))); + bins byte2_active = generic_input_wires_cp with (|(item & (64'hFF << 16))); + bins byte3_active = generic_input_wires_cp with (|(item & (64'hFF << 24))); + bins byte4_active = generic_input_wires_cp with (|(item & (64'hFF << 32))); + bins byte5_active = generic_input_wires_cp with (|(item & (64'hFF << 40))); + bins byte6_active = generic_input_wires_cp with (|(item & (64'hFF << 48))); + bins byte7_active = generic_input_wires_cp with (|(item & (64'hFF << 56))); + } + generic_output_wires_cp: coverpoint generic_output_wires_flat { + bins byte0_active = generic_output_wires_cp with (|(item & (64'hFF << 0))); + bins byte1_active = generic_output_wires_cp with (|(item & (64'hFF << 8))); + bins byte2_active = generic_output_wires_cp with (|(item & (64'hFF << 16))); + bins byte3_active = generic_output_wires_cp with (|(item & (64'hFF << 24))); + bins byte4_active = generic_output_wires_cp with (|(item & (64'hFF << 32))); + bins byte5_active = generic_output_wires_cp with (|(item & (64'hFF << 40))); + bins byte6_active = generic_output_wires_cp with (|(item & (64'hFF << 48))); + bins byte7_active = generic_output_wires_cp with (|(item & (64'hFF << 56))); + } + nmi_vector_cp: coverpoint nmi_vector; + nmi_intr_cp: coverpoint nmi_intr; + soc_ifc_error_intr_cp: coverpoint soc_ifc_error_intr; + soc_ifc_notif_intr_cp: coverpoint soc_ifc_notif_intr; + sha_error_intr_cp: coverpoint sha_error_intr; + sha_notif_intr_cp: coverpoint sha_notif_intr; + dma_error_intr_cp: coverpoint dma_error_intr; + dma_notif_intr_cp: coverpoint dma_notif_intr; + timer_intr_cp: coverpoint timer_intr; + mbox_sram_req_cp: coverpoint mbox_sram_req; + mbox_sram_resp_cp: coverpoint mbox_sram_resp; + rv_ecc_sts_cp: coverpoint rv_ecc_sts; + clear_obf_secrets_cp: coverpoint clear_obf_secrets; + scan_mode_cp: coverpoint scan_mode; + cptra_obf_key_reg_cp: coverpoint cptra_obf_key_reg; + cptra_obf_field_entropy_vld_cp: coverpoint cptra_obf_field_entropy_vld; + cptra_obf_field_entropy_cp: coverpoint cptra_obf_field_entropy; + obf_field_entropy_cp: coverpoint obf_field_entropy; + cptra_obf_uds_seed_vld_cp: coverpoint cptra_obf_uds_seed_vld; + cptra_obf_uds_seed_cp: coverpoint cptra_obf_uds_seed; + obf_uds_seed_cp: coverpoint obf_uds_seed; + obf_hek_seed_cp: coverpoint obf_hek_seed; + aes_input_ready_cp: coverpoint aes_input_ready; + aes_output_valid_cp: coverpoint aes_output_valid; + aes_status_idle_cp: coverpoint aes_status_idle; + aes_req_dv_cp: coverpoint aes_req_dv; + aes_req_hold_cp: coverpoint aes_req_hold; + aes_req_data_cp: coverpoint aes_req_data; + aes_rdata_cp: coverpoint aes_rdata; + aes_error_cp: coverpoint aes_error; + + kv_read_read_entry_cp: coverpoint kv_read.read_entry; + kv_read_read_offset_cp: coverpoint kv_read.read_offset; + kv_rd_resp_error_cp: coverpoint kv_rd_resp.error; + kv_rd_resp_last_cp: coverpoint kv_rd_resp.last; + kv_rd_resp_read_data_cp: coverpoint kv_rd_resp.read_data; + + strap_ss_caliptra_base_addr_cp: coverpoint strap_ss_caliptra_base_addr; + strap_ss_mci_base_addr_cp: coverpoint strap_ss_mci_base_addr; + strap_ss_recovery_ifc_base_addr_cp: coverpoint strap_ss_recovery_ifc_base_addr; + strap_ss_external_staging_area_base_addr_cp: coverpoint strap_ss_external_staging_area_base_addr; + strap_ss_otp_fc_base_addr_cp: coverpoint strap_ss_otp_fc_base_addr; + strap_ss_uds_seed_base_addr_cp: coverpoint strap_ss_uds_seed_base_addr; + strap_ss_key_release_base_addr_cp: coverpoint strap_ss_key_release_base_addr; + strap_ss_key_release_key_size_cp: coverpoint strap_ss_key_release_key_size; + strap_ss_prod_debug_unlock_auth_pk_hash_reg_bank_offset_cp: coverpoint strap_ss_prod_debug_unlock_auth_pk_hash_reg_bank_offset; + strap_ss_num_of_prod_debug_unlock_auth_pk_hashes_cp: coverpoint strap_ss_num_of_prod_debug_unlock_auth_pk_hashes; + strap_ss_caliptra_dma_axi_user_cp: coverpoint strap_ss_caliptra_dma_axi_user; + strap_ss_strap_generic_0_cp: coverpoint strap_ss_strap_generic_0; + strap_ss_strap_generic_1_cp: coverpoint strap_ss_strap_generic_1; + strap_ss_strap_generic_2_cp: coverpoint strap_ss_strap_generic_2; + strap_ss_strap_generic_3_cp: coverpoint strap_ss_strap_generic_3; + ss_debug_intent_cp: coverpoint ss_debug_intent; + cptra_ss_debug_intent_cp: coverpoint cptra_ss_debug_intent; + ss_dbg_manuf_enable_cp: coverpoint ss_dbg_manuf_enable; + ss_soc_dbg_unlock_level_cp: coverpoint ss_soc_dbg_unlock_level { + wildcard bins bit0 = {64'b???????????????????????????????????????????????????????????????1}; + wildcard bins bit1 = {64'b??????????????????????????????????????????????????????????????1?}; + wildcard bins bit2 = {64'b?????????????????????????????????????????????????????????????1??}; + wildcard bins bit3 = {64'b????????????????????????????????????????????????????????????1???}; + wildcard bins bit4 = {64'b???????????????????????????????????????????????????????????1????}; + wildcard bins bit5 = {64'b??????????????????????????????????????????????????????????1?????}; + wildcard bins bit6 = {64'b?????????????????????????????????????????????????????????1??????}; + wildcard bins bit7 = {64'b????????????????????????????????????????????????????????1???????}; + bins byte1_active = ss_soc_dbg_unlock_level_cp with (|(item & (64'hFF << 8))); + bins byte2_active = ss_soc_dbg_unlock_level_cp with (|(item & (64'hFF << 16))); + bins byte3_active = ss_soc_dbg_unlock_level_cp with (|(item & (64'hFF << 24))); + bins dword1_active = ss_soc_dbg_unlock_level_cp with (|(item & (64'hFFFFFFFF << 32))); + } + ss_generic_fw_exec_ctrl_cp: coverpoint ss_generic_fw_exec_ctrl { + bins byte0_active = ss_generic_fw_exec_ctrl_cp with (|(item & (128'hFF << 0))); + bins byte1_active = ss_generic_fw_exec_ctrl_cp with (|(item & (128'hFF << 8))); + bins byte2_active = ss_generic_fw_exec_ctrl_cp with (|(item & (128'hFF << 16))); + bins byte3_active = ss_generic_fw_exec_ctrl_cp with (|(item & (128'hFF << 24))); + bins byte4_active = ss_generic_fw_exec_ctrl_cp with (|(item & (128'hFF << 32))); + bins byte5_active = ss_generic_fw_exec_ctrl_cp with (|(item & (128'hFF << 40))); + bins byte6_active = ss_generic_fw_exec_ctrl_cp with (|(item & (128'hFF << 48))); + bins byte7_active = ss_generic_fw_exec_ctrl_cp with (|(item & (128'hFF << 56))); + bins byte8_active = ss_generic_fw_exec_ctrl_cp with (|(item & (128'hFF << 64))); + bins byte9_active = ss_generic_fw_exec_ctrl_cp with (|(item & (128'hFF << 72))); + bins byte10_active = ss_generic_fw_exec_ctrl_cp with (|(item & (128'hFF << 80))); + bins byte11_active = ss_generic_fw_exec_ctrl_cp with (|(item & (128'hFF << 88))); + bins byte12_active = ss_generic_fw_exec_ctrl_cp with (|(item & (128'hFF << 96))); + bins byte13_active = ss_generic_fw_exec_ctrl_cp with (|(item & (128'hFF << 104))); + bins byte14_active = ss_generic_fw_exec_ctrl_cp with (|(item & (128'hFF << 112))); + bins byte15_active = ss_generic_fw_exec_ctrl_cp with (|(item & (128'hFF << 120))); + } + ss_ocp_lock_en_cp: coverpoint ss_ocp_lock_en; + ss_ocp_lock_in_progress_cp: coverpoint ss_ocp_lock_in_progress; + ss_key_release_key_size_cp: coverpoint ss_key_release_key_size { + bins zero = {0}; + bins lt40 = {[1:39]}; + bins eq40 = {40}; + bins gt40 = {[41:65535]}; + // RTL allows reg-writes to set non-aligned values, but this violates the documented requirements and produces undefined behavior. + // NOTE: If hardware is updated to enforce alignment on reg-writes, this should be changed to illegal_bins + bins not_aligned_to_4 = ss_key_release_key_size_cp with (item[1:0] != 2'b00); + } + iccm_lock_cp: coverpoint iccm_lock; + iccm_axs_blocked_cp: coverpoint iccm_axs_blocked; + + endgroup + + logic valid_arb_cycle; + assign valid_arb_cycle = i_soc_ifc_arb.uc_req_dv | i_soc_ifc_arb.soc_req_dv; + + covergroup soc_ifc_arb_cov_grp @(posedge clk iff (cptra_rst_b & valid_arb_cycle)); + req_collision_cp: coverpoint i_soc_ifc_arb.req_collision; + soc_priority_cp: coverpoint i_soc_ifc_arb.soc_priority; + soc_has_priority_cp: coverpoint i_soc_ifc_arb.soc_has_priority; + uc_has_priority_cp: coverpoint i_soc_ifc_arb.uc_has_priority; + valid_mbox_req_cp: coverpoint i_soc_ifc_arb.valid_mbox_req; + soc_mbox_addr_cp: coverpoint i_soc_ifc_arb.soc_req_data.addr inside {[MBOX_REG_START_ADDR:MBOX_REG_END_ADDR]}; + + soc_req_ip_cp: coverpoint i_soc_ifc_arb.soc_req_ip; + uc_req_ip_cp: coverpoint i_soc_ifc_arb.uc_req_ip; + + uc_mbox_reg_req_cp: coverpoint i_soc_ifc_arb.uc_mbox_reg_req; + uc_mbox_dir_req_cp: coverpoint i_soc_ifc_arb.uc_mbox_dir_req; + soc_mbox_req_cp: coverpoint i_soc_ifc_arb.soc_mbox_req; + + uc_reg_req_cp: coverpoint i_soc_ifc_arb.uc_reg_req; + soc_reg_req_cp: coverpoint i_soc_ifc_arb.soc_reg_req; + + uc_sha_req_cp: coverpoint i_soc_ifc_arb.uc_sha_req; + soc_sha_req_cp: coverpoint i_soc_ifc_arb.soc_sha_req; + + uc_dma_req_cp: coverpoint i_soc_ifc_arb.uc_dma_req; + soc_dma_req_cp: coverpoint i_soc_ifc_arb.soc_dma_req; + + //Cover soc req to mbox addr range with and without valid pauser. + soc_mbox_reqXvalid_mbox_req: cross soc_mbox_addr_cp, valid_mbox_req_cp; + //Collision crosses + collisionXuc_prioXprio_flag: cross req_collision_cp, uc_has_priority_cp, soc_priority_cp; + collisionXsoc_prioXprio_Flag: cross req_collision_cp, soc_has_priority_cp, soc_priority_cp; + endgroup + + covergroup soc_ifc_boot_fsm_cov_grp @(posedge clk iff cptra_rst_b); + //FSM + boot_fsm_ps_cp: coverpoint i_soc_ifc_boot_fsm.boot_fsm_ps; + arc_BOOT_IDLE_BOOT_FUSE_cp: coverpoint i_soc_ifc_boot_fsm.arc_BOOT_IDLE_BOOT_FUSE; + arc_BOOT_FUSE_BOOT_DONE_cp: coverpoint i_soc_ifc_boot_fsm.arc_BOOT_FUSE_BOOT_DONE; + arc_BOOT_FUSE_BOOT_WAIT_cp: coverpoint i_soc_ifc_boot_fsm.arc_BOOT_FUSE_BOOT_WAIT; + //Not a real arc - tied off to zero + //arc_BOOT_DONE_BOOT_IDLE_cp: coverpoint i_soc_ifc_boot_fsm.arc_BOOT_DONE_BOOT_IDLE; + arc_BOOT_DONE_BOOT_FWRST_cp: coverpoint i_soc_ifc_boot_fsm.arc_BOOT_DONE_BOOT_FWRST; + arc_BOOT_FWRST_BOOT_WAIT_cp: coverpoint i_soc_ifc_boot_fsm.arc_BOOT_FWRST_BOOT_WAIT; + arc_BOOT_WAIT_BOOT_DONE_cp: coverpoint i_soc_ifc_boot_fsm.arc_BOOT_WAIT_BOOT_DONE; + arc_IDLE_cp: coverpoint i_soc_ifc_boot_fsm.arc_IDLE & ($bits(boot_fsm_state_e)'(i_soc_ifc_boot_fsm.boot_fsm_ps) != BOOT_IDLE); + fsm_iccm_unlock_cp: coverpoint i_soc_ifc_boot_fsm.fsm_iccm_unlock; + + + endgroup + + sha_fsm_state_e sha_fsm_ps; + assign sha_fsm_ps = sha_fsm_state_e'(i_sha512_acc_top.sha_fsm_ps); + + covergroup sha512_acc_cov_grp @(posedge clk iff cptra_rst_b); + //FSM + sha_fsm_ps_cp: coverpoint sha_fsm_ps; + arc_SHA_IDLE_SHA_BLOCK_0_cp: coverpoint i_sha512_acc_top.arc_SHA_IDLE_SHA_BLOCK_0; + arc_SHA_BLOCK_0_SHA_BLOCK_N_cp: coverpoint i_sha512_acc_top.arc_SHA_BLOCK_0_SHA_BLOCK_N; + arc_SHA_BLOCK_0_SHA_PAD0_cp: coverpoint i_sha512_acc_top.arc_SHA_BLOCK_0_SHA_PAD0; + arc_SHA_BLOCK_N_SHA_BLOCK_N_cp: coverpoint i_sha512_acc_top.arc_SHA_BLOCK_N_SHA_BLOCK_N; + arc_SHA_BLOCK_N_SHA_PAD0_cp: coverpoint i_sha512_acc_top.arc_SHA_BLOCK_N_SHA_PAD0; + arc_SHA_PAD0_SHA_PAD1_cp: coverpoint i_sha512_acc_top.arc_SHA_PAD0_SHA_PAD1; + arc_SHA_PAD0_SHA_DONE_cp: coverpoint i_sha512_acc_top.arc_SHA_PAD0_SHA_DONE; + arc_SHA_PAD1_SHA_DONE_cp: coverpoint i_sha512_acc_top.arc_SHA_PAD1_SHA_DONE; + arc_IDLE_cp: coverpoint (i_sha512_acc_top.arc_IDLE & (sha_fsm_ps != SHA_IDLE)); + + //controls + extra_pad_block_required_cp: coverpoint i_sha512_acc_top.extra_pad_block_required; + num_bytes_data_cp: coverpoint i_sha512_acc_top.num_bytes_data; + mailbox_mode_cp: coverpoint i_sha512_acc_top.mailbox_mode; + sha_mode_cp: coverpoint i_sha512_acc_top.sha_mode { + option.comment = "SHA Mode Encoding"; + bins MODE_SHA_384 = {2'h2}; + bins MODE_SHA_512 = {2'h3}; + } + + //crosses + mailbox_modeXextra_pad: cross mailbox_mode_cp, extra_pad_block_required_cp; + mailbox_modeXnum_bytes_data: cross mailbox_mode_cp, num_bytes_data_cp; + mailbox_modeXsha_mode_cpXsha_fsm_ps: cross mailbox_mode_cp, sha_mode_cp, sha_fsm_ps_cp; + + endgroup + + mbox_fsm_state_e mbox_fsm_ps; + assign mbox_fsm_ps = mbox_fsm_state_e'(i_mbox.mbox_fsm_ps); + + covergroup mbox_cov_grp @(posedge clk iff cptra_rst_b); + //FSM + mbox_fsm_ps_cp: coverpoint mbox_fsm_ps; + arc_FORCE_MBOX_UNLOCK_cp: coverpoint i_mbox.arc_FORCE_MBOX_UNLOCK; + arc_MBOX_IDLE_MBOX_RDY_FOR_CMD_cp: coverpoint i_mbox.arc_MBOX_IDLE_MBOX_RDY_FOR_CMD; + arc_MBOX_RDY_FOR_CMD_MBOX_RDY_FOR_DLEN_cp: coverpoint i_mbox.arc_MBOX_RDY_FOR_CMD_MBOX_RDY_FOR_DLEN; + arc_MBOX_RDY_FOR_DLEN_MBOX_RDY_FOR_DATA_cp: coverpoint i_mbox.arc_MBOX_RDY_FOR_DLEN_MBOX_RDY_FOR_DATA; + arc_MBOX_RDY_FOR_DATA_MBOX_EXECUTE_UC_cp: coverpoint i_mbox.arc_MBOX_RDY_FOR_DATA_MBOX_EXECUTE_UC; + arc_MBOX_RDY_FOR_DATA_MBOX_EXECUTE_SOC_cp: coverpoint i_mbox.arc_MBOX_RDY_FOR_DATA_MBOX_EXECUTE_SOC; + arc_MBOX_RDY_FOR_DATA_MBOX_EXECUTE_TAP_cp: coverpoint i_mbox.arc_MBOX_RDY_FOR_DATA_MBOX_EXECUTE_TAP; + arc_MBOX_EXECUTE_UC_MBOX_IDLE_cp: coverpoint i_mbox.arc_MBOX_EXECUTE_UC_MBOX_IDLE; + arc_MBOX_EXECUTE_SOC_MBOX_IDLE_cp: coverpoint i_mbox.arc_MBOX_EXECUTE_SOC_MBOX_IDLE; + arc_MBOX_EXECUTE_TAP_MBOX_IDLE_cp: coverpoint i_mbox.arc_MBOX_EXECUTE_TAP_MBOX_IDLE; + arc_MBOX_EXECUTE_UC_MBOX_EXECUTE_SOC_cp: coverpoint i_mbox.arc_MBOX_EXECUTE_UC_MBOX_EXECUTE_SOC; + arc_MBOX_EXECUTE_UC_MBOX_EXECUTE_TAP_cp: coverpoint i_mbox.arc_MBOX_EXECUTE_UC_MBOX_EXECUTE_TAP; + arc_MBOX_EXECUTE_SOC_MBOX_EXECUTE_UC_cp: coverpoint i_mbox.arc_MBOX_EXECUTE_SOC_MBOX_EXECUTE_UC; + arc_MBOX_EXECUTE_TAP_MBOX_EXECUTE_UC_cp: coverpoint i_mbox.arc_MBOX_EXECUTE_TAP_MBOX_EXECUTE_UC; + arc_MBOX_RDY_FOR_CMD_MBOX_ERROR_cp: coverpoint i_mbox.arc_MBOX_RDY_FOR_CMD_MBOX_ERROR; + arc_MBOX_RDY_FOR_DLEN_MBOX_ERROR_cp: coverpoint i_mbox.arc_MBOX_RDY_FOR_DLEN_MBOX_ERROR; + arc_MBOX_RDY_FOR_DATA_MBOX_ERROR_cp: coverpoint i_mbox.arc_MBOX_RDY_FOR_DATA_MBOX_ERROR; + arc_MBOX_EXECUTE_UC_MBOX_ERROR_cp: coverpoint i_mbox.arc_MBOX_EXECUTE_UC_MBOX_ERROR; + arc_MBOX_EXECUTE_SOC_MBOX_ERROR_cp: coverpoint i_mbox.arc_MBOX_EXECUTE_SOC_MBOX_ERROR; + arc_MBOX_EXECUTE_TAP_MBOX_ERROR_cp: coverpoint i_mbox.arc_MBOX_EXECUTE_TAP_MBOX_ERROR; + + //controls + soc_has_lock_cp: coverpoint i_mbox.soc_has_lock; + uc_has_lock_cp: coverpoint i_mbox.uc_has_lock; + tap_has_lock_cp: coverpoint i_mbox.tap_has_lock; + mask_rdata_cp: coverpoint i_mbox.mask_rdata; + dlen_in_dws_cp: coverpoint i_mbox.dlen_in_dws { + bins zero = {0}; + bins one = {1}; + bins range[32] = {[2:CPTRA_MBOX_SIZE_DWORDS-2]}; + bins almost_full = {CPTRA_MBOX_SIZE_DWORDS-1}; + bins full = {CPTRA_MBOX_SIZE_DWORDS};} + + sram_single_ecc_error_cp: coverpoint i_mbox.sram_single_ecc_error; + sram_double_ecc_error_cp: coverpoint i_mbox.sram_double_ecc_error; + + //req hold varieties + req_hold0_cp: coverpoint (i_mbox.dir_req_dv_q & ~i_mbox.sha_sram_req_dv & ~i_mbox.req_data_write); + req_hold1_cp: coverpoint (i_mbox.dir_req_dv & ~i_mbox.dir_req_rd_phase & i_mbox.sha_sram_req_dv); + req_hold2_cp: coverpoint i_mbox.req_dv & (i_mbox.hwif_out.mbox_dataout.dataout.swacc & i_mbox.mbox_protocol_sram_rd_f); + //sha_sram_hold_cp: coverpoint i_mbox.sha_sram_hold; + + //special scenarios - only care about bin of 1 + dlen_gt_mbox_size_cp: coverpoint i_mbox.hwif_out.mbox_dlen.length.value > CPTRA_MBOX_SIZE_BYTES { + option.comment = "DLEN is programmed greater than mailbox size"; + bins one = {1};} + req_wrptr_gt_dlen_cp: coverpoint (mbox_fsm_ps == MBOX_RDY_FOR_DATA) & (i_mbox.mbox_wrptr > i_mbox.dlen_in_dws) { + option.comment = "Requester caused write pointer to increment past DLEN"; + bins one = {1};} + resp_wrptr_gt_dlen_cp: coverpoint (mbox_fsm_ps inside {MBOX_EXECUTE_UC,MBOX_EXECUTE_SOC}) & (i_mbox.mbox_wrptr > i_mbox.dlen_in_dws) { + option.comment = "Receiver caused write pointer to increment past DLEN"; + bins one = {1};} + wrptr_rollover_cp: coverpoint i_mbox.inc_wrptr & ~i_mbox.wrptr_inc_valid { + option.comment = "Write pointer tried to increment past mailbox size"; + bins one = {1};} + rdptr_gt_dlen_cp: coverpoint i_mbox.inc_rdptr & ~(i_mbox.mbox_rdptr <= i_mbox.dlen_in_dws) { + option.comment = "Read pointer tried to increment passed DLEN"; + bins one = {1};} + rdptr_rollover_cp: coverpoint i_mbox.inc_rdptr & ~(i_mbox.mbox_rdptr < (CPTRA_MBOX_SIZE_DWORDS-1)) { + option.comment = "Read pointer tried to increment passed mailbox size"; + bins one = {1};} + + endgroup + + covergroup axi_dma_cov_grp @(posedge clk iff cptra_rst_b); + //DMA Accesses in progress + AHBtoAXI_ip_cp: coverpoint (dma_ctrl_fsm_ps != DMA_IDLE) & + (dma_rd_route == axi_dma_reg__ctrl__rd_route__rd_route_e__DISABLE) & + (dma_wr_route == axi_dma_reg__ctrl__wr_route__wr_route_e__AHB_FIFO) { + option.comment = "DMA Access: AHB FIFO data sent to AXI location"; + bins one = {1};} + AXItoAHB_ip_cp: coverpoint (dma_ctrl_fsm_ps != DMA_IDLE) & + (dma_rd_route == axi_dma_reg__ctrl__rd_route__rd_route_e__AHB_FIFO) & + (dma_wr_route == axi_dma_reg__ctrl__wr_route__wr_route_e__DISABLE) { + option.comment = "DMA Access: AXI read into AHB FIFO"; + bins one = {1};} + AXItoAXI_ip_cp: coverpoint (dma_ctrl_fsm_ps != DMA_IDLE) & + (dma_rd_route == axi_dma_reg__ctrl__rd_route__rd_route_e__AXI_WR) & + (dma_wr_route == axi_dma_reg__ctrl__wr_route__wr_route_e__AXI_RD) { + option.comment = "DMA Access: AXI to AXI"; + bins one = {1};} + MBOXtoAXI_ip_cp: coverpoint (dma_ctrl_fsm_ps != DMA_IDLE) & + (dma_rd_route == axi_dma_reg__ctrl__rd_route__rd_route_e__DISABLE) & + (dma_wr_route == axi_dma_reg__ctrl__wr_route__wr_route_e__MBOX) { + option.comment = "DMA Access: MBOX data sent to AXI location"; + bins one = {1};} + AXItoMBOX_ip_cp: coverpoint (dma_ctrl_fsm_ps != DMA_IDLE) & + (dma_rd_route == axi_dma_reg__ctrl__rd_route__rd_route_e__MBOX) & + (dma_wr_route == axi_dma_reg__ctrl__wr_route__wr_route_e__DISABLE) { + option.comment = "DMA Access: AXI read into MBOX"; + bins one = {1};} + AXItoSHA_ip_cp: coverpoint (sha_fsm_ps != SHA_IDLE) & + (i_sha512_acc_top.hwif_out.USER.USER.value == soc_ifc_reg_hwif_out.SS_CALIPTRA_DMA_AXI_USER.user.value) & + (dma_ctrl_fsm_ps != DMA_IDLE) & + (dma_rd_route == axi_dma_reg__ctrl__rd_route__rd_route_e__AXI_WR) & + (dma_wr_route == axi_dma_reg__ctrl__wr_route__wr_route_e__AXI_RD) { + option.comment = "DMA Access: AXI to SHA"; + bins one = {1};} + + //Other accesses to cross with + MBOX_ip_cp: coverpoint (mbox_fsm_ps != MBOX_IDLE) { + option.comment = "Mailbox access in progress"; + bins one = {1};} + TRNG_ip_cp: coverpoint (trng_req) { + option.comment = "TRNG access in progress"; + bins one = {1};} + REG_ip_cp: coverpoint (soc_ifc_reg_req_dv) { + option.comment = "SOC Reg access in progress"; + bins one = {1};} + + AHBtoAXIxMailbox: cross AHBtoAXI_ip_cp, MBOX_ip_cp; + AHBtoAXIxTRNG: cross AHBtoAXI_ip_cp, TRNG_ip_cp; + AHBtoAXIxREG: cross AHBtoAXI_ip_cp, REG_ip_cp; + MBOXtoAXIxMailbox: cross MBOXtoAXI_ip_cp, MBOX_ip_cp; + MBOXtoAXIxTRNG: cross MBOXtoAXI_ip_cp, TRNG_ip_cp; + MBOXtoAXIxREG: cross MBOXtoAXI_ip_cp, REG_ip_cp; + AXItoAXIxMailbox: cross AXItoAXI_ip_cp, MBOX_ip_cp; + AXItoAXIxTRNG: cross AXItoAXI_ip_cp, TRNG_ip_cp; + AXItoAXIxREG: cross AXItoAXI_ip_cp, REG_ip_cp; + AXItoAHBxMailbox: cross AXItoAHB_ip_cp, MBOX_ip_cp; + AXItoAHBxTRNG: cross AXItoAHB_ip_cp, TRNG_ip_cp; + AXItoAHBxREG: cross AXItoAHB_ip_cp, REG_ip_cp; + AXItoMBOXxMailbox: cross AXItoMBOX_ip_cp, MBOX_ip_cp; + AXItoMBOXxTRNG: cross AXItoMBOX_ip_cp, TRNG_ip_cp; + AXItoMBOXxREG: cross AXItoMBOX_ip_cp, REG_ip_cp; + AXItoSHAxMailbox: cross AXItoSHA_ip_cp, MBOX_ip_cp; + AXItoSHAxTRNG: cross AXItoSHA_ip_cp, TRNG_ip_cp; + AXItoSHAxREG: cross AXItoSHA_ip_cp, REG_ip_cp; + endgroup + + soc_ifc_top_cov_grp soc_ifc_top_cov_grp1 = new(); + soc_ifc_arb_cov_grp soc_ifc_arb_cov_grp1 = new(); + soc_ifc_boot_fsm_cov_grp soc_ifc_boot_fsm_cov_grp1 = new(); + sha512_acc_cov_grp sha512_acc_cov_grp1 = new(); + mbox_cov_grp mbox_cov_grp1 = new(); + axi_dma_cov_grp axi_dma_cov_grp1 = new(); + +/* -- Working Reference -- + for(genvar i = 0; i < 4; i++) begin : fuse_runtime_svn_blk + covergroup soc_ifc_fuse_runtime_svn_cg @(posedge clk); + option.comment = {"fuse_runtime_svn", "_cp"}; + coverpoint i_soc_ifc_reg.field_storage.fuse_runtime_svn[i]; + endgroup + soc_ifc_fuse_runtime_svn_cg fuse_runtime_svn_cg = new(); + end +*/ + + + + + // ------------------------------------------------------------------- + // begin SCRIPT_OUTPUT + // ------------------------------------------------------------------- + + + // ------------------- COVERGROUP related signals & assigns ------------------- + + logic hit_CPTRA_HW_ERROR_FATAL; + logic [3:0] bus_CPTRA_HW_ERROR_FATAL; + logic [31:0] full_addr_CPTRA_HW_ERROR_FATAL = `CLP_SOC_IFC_REG_CPTRA_HW_ERROR_FATAL; + + logic hit_CPTRA_HW_ERROR_NON_FATAL; + logic [3:0] bus_CPTRA_HW_ERROR_NON_FATAL; + logic [31:0] full_addr_CPTRA_HW_ERROR_NON_FATAL = `CLP_SOC_IFC_REG_CPTRA_HW_ERROR_NON_FATAL; + + logic hit_CPTRA_FW_ERROR_FATAL; + logic [3:0] bus_CPTRA_FW_ERROR_FATAL; + logic [31:0] full_addr_CPTRA_FW_ERROR_FATAL = `CLP_SOC_IFC_REG_CPTRA_FW_ERROR_FATAL; + + logic hit_CPTRA_FW_ERROR_NON_FATAL; + logic [3:0] bus_CPTRA_FW_ERROR_NON_FATAL; + logic [31:0] full_addr_CPTRA_FW_ERROR_NON_FATAL = `CLP_SOC_IFC_REG_CPTRA_FW_ERROR_NON_FATAL; + + logic hit_CPTRA_HW_ERROR_ENC; + logic [3:0] bus_CPTRA_HW_ERROR_ENC; + logic [31:0] full_addr_CPTRA_HW_ERROR_ENC = `CLP_SOC_IFC_REG_CPTRA_HW_ERROR_ENC; + + logic hit_CPTRA_FW_ERROR_ENC; + logic [3:0] bus_CPTRA_FW_ERROR_ENC; + logic [31:0] full_addr_CPTRA_FW_ERROR_ENC = `CLP_SOC_IFC_REG_CPTRA_FW_ERROR_ENC; + + logic hit_CPTRA_FW_EXTENDED_ERROR_INFO[0:7]; + logic [3:0] bus_CPTRA_FW_EXTENDED_ERROR_INFO[0:7]; + logic [31:0] full_addr_CPTRA_FW_EXTENDED_ERROR_INFO[0:7]; + assign full_addr_CPTRA_FW_EXTENDED_ERROR_INFO[0] = `CLP_SOC_IFC_REG_CPTRA_FW_EXTENDED_ERROR_INFO_0; + assign full_addr_CPTRA_FW_EXTENDED_ERROR_INFO[1] = `CLP_SOC_IFC_REG_CPTRA_FW_EXTENDED_ERROR_INFO_1; + assign full_addr_CPTRA_FW_EXTENDED_ERROR_INFO[2] = `CLP_SOC_IFC_REG_CPTRA_FW_EXTENDED_ERROR_INFO_2; + assign full_addr_CPTRA_FW_EXTENDED_ERROR_INFO[3] = `CLP_SOC_IFC_REG_CPTRA_FW_EXTENDED_ERROR_INFO_3; + assign full_addr_CPTRA_FW_EXTENDED_ERROR_INFO[4] = `CLP_SOC_IFC_REG_CPTRA_FW_EXTENDED_ERROR_INFO_4; + assign full_addr_CPTRA_FW_EXTENDED_ERROR_INFO[5] = `CLP_SOC_IFC_REG_CPTRA_FW_EXTENDED_ERROR_INFO_5; + assign full_addr_CPTRA_FW_EXTENDED_ERROR_INFO[6] = `CLP_SOC_IFC_REG_CPTRA_FW_EXTENDED_ERROR_INFO_6; + assign full_addr_CPTRA_FW_EXTENDED_ERROR_INFO[7] = `CLP_SOC_IFC_REG_CPTRA_FW_EXTENDED_ERROR_INFO_7; + + logic hit_CPTRA_BOOT_STATUS; + logic [3:0] bus_CPTRA_BOOT_STATUS; + logic [31:0] full_addr_CPTRA_BOOT_STATUS = `CLP_SOC_IFC_REG_CPTRA_BOOT_STATUS; + + logic hit_CPTRA_FLOW_STATUS; + logic [3:0] bus_CPTRA_FLOW_STATUS; + logic [31:0] full_addr_CPTRA_FLOW_STATUS = `CLP_SOC_IFC_REG_CPTRA_FLOW_STATUS; + + logic hit_CPTRA_RESET_REASON; + logic [3:0] bus_CPTRA_RESET_REASON; + logic [31:0] full_addr_CPTRA_RESET_REASON = `CLP_SOC_IFC_REG_CPTRA_RESET_REASON; + + // logic hit_CPTRA_SECURITY_STATE; + // logic [3:0] bus_CPTRA_SECURITY_STATE; + // logic [31:0] full_addr_CPTRA_SECURITY_STATE = `CLP_SOC_IFC_REG_CPTRA_SECURITY_STATE; + + logic hit_CPTRA_MBOX_VALID_AXI_USER[0:4]; + logic [3:0] bus_CPTRA_MBOX_VALID_AXI_USER[0:4]; + logic [31:0] full_addr_CPTRA_MBOX_VALID_AXI_USER[0:4]; + assign full_addr_CPTRA_MBOX_VALID_AXI_USER[0] = `CLP_SOC_IFC_REG_CPTRA_MBOX_VALID_AXI_USER_0; + assign full_addr_CPTRA_MBOX_VALID_AXI_USER[1] = `CLP_SOC_IFC_REG_CPTRA_MBOX_VALID_AXI_USER_1; + assign full_addr_CPTRA_MBOX_VALID_AXI_USER[2] = `CLP_SOC_IFC_REG_CPTRA_MBOX_VALID_AXI_USER_2; + assign full_addr_CPTRA_MBOX_VALID_AXI_USER[3] = `CLP_SOC_IFC_REG_CPTRA_MBOX_VALID_AXI_USER_3; + assign full_addr_CPTRA_MBOX_VALID_AXI_USER[4] = `CLP_SOC_IFC_REG_CPTRA_MBOX_VALID_AXI_USER_4; + + logic hit_CPTRA_MBOX_AXI_USER_LOCK[0:4]; + logic [3:0] bus_CPTRA_MBOX_AXI_USER_LOCK[0:4]; + logic [31:0] full_addr_CPTRA_MBOX_AXI_USER_LOCK[0:4]; + assign full_addr_CPTRA_MBOX_AXI_USER_LOCK[0] = `CLP_SOC_IFC_REG_CPTRA_MBOX_AXI_USER_LOCK_0; + assign full_addr_CPTRA_MBOX_AXI_USER_LOCK[1] = `CLP_SOC_IFC_REG_CPTRA_MBOX_AXI_USER_LOCK_1; + assign full_addr_CPTRA_MBOX_AXI_USER_LOCK[2] = `CLP_SOC_IFC_REG_CPTRA_MBOX_AXI_USER_LOCK_2; + assign full_addr_CPTRA_MBOX_AXI_USER_LOCK[3] = `CLP_SOC_IFC_REG_CPTRA_MBOX_AXI_USER_LOCK_3; + assign full_addr_CPTRA_MBOX_AXI_USER_LOCK[4] = `CLP_SOC_IFC_REG_CPTRA_MBOX_AXI_USER_LOCK_4; + + logic hit_CPTRA_TRNG_VALID_AXI_USER; + logic [3:0] bus_CPTRA_TRNG_VALID_AXI_USER; + logic [31:0] full_addr_CPTRA_TRNG_VALID_AXI_USER = `CLP_SOC_IFC_REG_CPTRA_TRNG_VALID_AXI_USER; + + logic hit_CPTRA_TRNG_AXI_USER_LOCK; + logic [3:0] bus_CPTRA_TRNG_AXI_USER_LOCK; + logic [31:0] full_addr_CPTRA_TRNG_AXI_USER_LOCK = `CLP_SOC_IFC_REG_CPTRA_TRNG_AXI_USER_LOCK; + + logic hit_CPTRA_TRNG_DATA[0:11]; + logic [3:0] bus_CPTRA_TRNG_DATA[0:11]; + logic [31:0] full_addr_CPTRA_TRNG_DATA[0:11]; + assign full_addr_CPTRA_TRNG_DATA[0] = `CLP_SOC_IFC_REG_CPTRA_TRNG_DATA_0; + assign full_addr_CPTRA_TRNG_DATA[1] = `CLP_SOC_IFC_REG_CPTRA_TRNG_DATA_1; + assign full_addr_CPTRA_TRNG_DATA[2] = `CLP_SOC_IFC_REG_CPTRA_TRNG_DATA_2; + assign full_addr_CPTRA_TRNG_DATA[3] = `CLP_SOC_IFC_REG_CPTRA_TRNG_DATA_3; + assign full_addr_CPTRA_TRNG_DATA[4] = `CLP_SOC_IFC_REG_CPTRA_TRNG_DATA_4; + assign full_addr_CPTRA_TRNG_DATA[5] = `CLP_SOC_IFC_REG_CPTRA_TRNG_DATA_5; + assign full_addr_CPTRA_TRNG_DATA[6] = `CLP_SOC_IFC_REG_CPTRA_TRNG_DATA_6; + assign full_addr_CPTRA_TRNG_DATA[7] = `CLP_SOC_IFC_REG_CPTRA_TRNG_DATA_7; + assign full_addr_CPTRA_TRNG_DATA[8] = `CLP_SOC_IFC_REG_CPTRA_TRNG_DATA_8; + assign full_addr_CPTRA_TRNG_DATA[9] = `CLP_SOC_IFC_REG_CPTRA_TRNG_DATA_9; + assign full_addr_CPTRA_TRNG_DATA[10] = `CLP_SOC_IFC_REG_CPTRA_TRNG_DATA_10; + assign full_addr_CPTRA_TRNG_DATA[11] = `CLP_SOC_IFC_REG_CPTRA_TRNG_DATA_11; + + logic hit_CPTRA_TRNG_CTRL; + logic [3:0] bus_CPTRA_TRNG_CTRL; + logic [31:0] full_addr_CPTRA_TRNG_CTRL = `CLP_SOC_IFC_REG_CPTRA_TRNG_CTRL; + + logic hit_CPTRA_TRNG_STATUS; + logic [3:0] bus_CPTRA_TRNG_STATUS; + logic [31:0] full_addr_CPTRA_TRNG_STATUS = `CLP_SOC_IFC_REG_CPTRA_TRNG_STATUS; + + logic hit_CPTRA_FUSE_WR_DONE; + logic [3:0] bus_CPTRA_FUSE_WR_DONE; + logic [31:0] full_addr_CPTRA_FUSE_WR_DONE = `CLP_SOC_IFC_REG_CPTRA_FUSE_WR_DONE; + + logic hit_CPTRA_TIMER_CONFIG; + logic [3:0] bus_CPTRA_TIMER_CONFIG; + logic [31:0] full_addr_CPTRA_TIMER_CONFIG = `CLP_SOC_IFC_REG_CPTRA_TIMER_CONFIG; + + logic hit_CPTRA_BOOTFSM_GO; + logic [3:0] bus_CPTRA_BOOTFSM_GO; + logic [31:0] full_addr_CPTRA_BOOTFSM_GO = `CLP_SOC_IFC_REG_CPTRA_BOOTFSM_GO; + + logic hit_CPTRA_DBG_MANUF_SERVICE_REG; + logic [3:0] bus_CPTRA_DBG_MANUF_SERVICE_REG; + logic [31:0] full_addr_CPTRA_DBG_MANUF_SERVICE_REG = `CLP_SOC_IFC_REG_CPTRA_DBG_MANUF_SERVICE_REG; + + logic hit_CPTRA_CLK_GATING_EN; + logic [3:0] bus_CPTRA_CLK_GATING_EN; + logic [31:0] full_addr_CPTRA_CLK_GATING_EN = `CLP_SOC_IFC_REG_CPTRA_CLK_GATING_EN; + + logic hit_CPTRA_GENERIC_INPUT_WIRES[0:1]; + logic [3:0] bus_CPTRA_GENERIC_INPUT_WIRES[0:1]; + logic [31:0] full_addr_CPTRA_GENERIC_INPUT_WIRES[0:1]; + assign full_addr_CPTRA_GENERIC_INPUT_WIRES[0] = `CLP_SOC_IFC_REG_CPTRA_GENERIC_INPUT_WIRES_0; + assign full_addr_CPTRA_GENERIC_INPUT_WIRES[1] = `CLP_SOC_IFC_REG_CPTRA_GENERIC_INPUT_WIRES_1; + + logic hit_CPTRA_GENERIC_OUTPUT_WIRES[0:1]; + logic [3:0] bus_CPTRA_GENERIC_OUTPUT_WIRES[0:1]; + logic [31:0] full_addr_CPTRA_GENERIC_OUTPUT_WIRES[0:1]; + assign full_addr_CPTRA_GENERIC_OUTPUT_WIRES[0] = `CLP_SOC_IFC_REG_CPTRA_GENERIC_OUTPUT_WIRES_0; + assign full_addr_CPTRA_GENERIC_OUTPUT_WIRES[1] = `CLP_SOC_IFC_REG_CPTRA_GENERIC_OUTPUT_WIRES_1; + + // logic hit_CPTRA_HW_REV_ID; + // logic [3:0] bus_CPTRA_HW_REV_ID; + // logic [31:0] full_addr_CPTRA_HW_REV_ID = `CLP_SOC_IFC_REG_CPTRA_HW_REV_ID; + + logic hit_CPTRA_FW_REV_ID[0:1]; + logic [3:0] bus_CPTRA_FW_REV_ID[0:1]; + logic [31:0] full_addr_CPTRA_FW_REV_ID[0:1]; + assign full_addr_CPTRA_FW_REV_ID[0] = `CLP_SOC_IFC_REG_CPTRA_FW_REV_ID_0; + assign full_addr_CPTRA_FW_REV_ID[1] = `CLP_SOC_IFC_REG_CPTRA_FW_REV_ID_1; + + // logic hit_CPTRA_HW_CONFIG; + // logic [3:0] bus_CPTRA_HW_CONFIG; + // logic [31:0] full_addr_CPTRA_HW_CONFIG = `CLP_SOC_IFC_REG_CPTRA_HW_CONFIG; + + logic hit_CPTRA_WDT_TIMER1_EN; + logic [3:0] bus_CPTRA_WDT_TIMER1_EN; + logic [31:0] full_addr_CPTRA_WDT_TIMER1_EN = `CLP_SOC_IFC_REG_CPTRA_WDT_TIMER1_EN; + + logic hit_CPTRA_WDT_TIMER1_CTRL; + logic [3:0] bus_CPTRA_WDT_TIMER1_CTRL; + logic [31:0] full_addr_CPTRA_WDT_TIMER1_CTRL = `CLP_SOC_IFC_REG_CPTRA_WDT_TIMER1_CTRL; + + logic hit_CPTRA_WDT_TIMER1_TIMEOUT_PERIOD[0:1]; + logic [3:0] bus_CPTRA_WDT_TIMER1_TIMEOUT_PERIOD[0:1]; + logic [31:0] full_addr_CPTRA_WDT_TIMER1_TIMEOUT_PERIOD[0:1]; + assign full_addr_CPTRA_WDT_TIMER1_TIMEOUT_PERIOD[0] = `CLP_SOC_IFC_REG_CPTRA_WDT_TIMER1_TIMEOUT_PERIOD_0; + assign full_addr_CPTRA_WDT_TIMER1_TIMEOUT_PERIOD[1] = `CLP_SOC_IFC_REG_CPTRA_WDT_TIMER1_TIMEOUT_PERIOD_1; + + logic hit_CPTRA_WDT_TIMER2_EN; + logic [3:0] bus_CPTRA_WDT_TIMER2_EN; + logic [31:0] full_addr_CPTRA_WDT_TIMER2_EN = `CLP_SOC_IFC_REG_CPTRA_WDT_TIMER2_EN; + + logic hit_CPTRA_WDT_TIMER2_CTRL; + logic [3:0] bus_CPTRA_WDT_TIMER2_CTRL; + logic [31:0] full_addr_CPTRA_WDT_TIMER2_CTRL = `CLP_SOC_IFC_REG_CPTRA_WDT_TIMER2_CTRL; + + logic hit_CPTRA_WDT_TIMER2_TIMEOUT_PERIOD[0:1]; + logic [3:0] bus_CPTRA_WDT_TIMER2_TIMEOUT_PERIOD[0:1]; + logic [31:0] full_addr_CPTRA_WDT_TIMER2_TIMEOUT_PERIOD[0:1]; + assign full_addr_CPTRA_WDT_TIMER2_TIMEOUT_PERIOD[0] = `CLP_SOC_IFC_REG_CPTRA_WDT_TIMER2_TIMEOUT_PERIOD_0; + assign full_addr_CPTRA_WDT_TIMER2_TIMEOUT_PERIOD[1] = `CLP_SOC_IFC_REG_CPTRA_WDT_TIMER2_TIMEOUT_PERIOD_1; + + logic hit_CPTRA_WDT_STATUS; + logic [3:0] bus_CPTRA_WDT_STATUS; + logic [31:0] full_addr_CPTRA_WDT_STATUS = `CLP_SOC_IFC_REG_CPTRA_WDT_STATUS; + + logic hit_CPTRA_FUSE_VALID_AXI_USER; + logic [3:0] bus_CPTRA_FUSE_VALID_AXI_USER; + logic [31:0] full_addr_CPTRA_FUSE_VALID_AXI_USER = `CLP_SOC_IFC_REG_CPTRA_FUSE_VALID_AXI_USER; + + logic hit_CPTRA_FUSE_AXI_USER_LOCK; + logic [3:0] bus_CPTRA_FUSE_AXI_USER_LOCK; + logic [31:0] full_addr_CPTRA_FUSE_AXI_USER_LOCK = `CLP_SOC_IFC_REG_CPTRA_FUSE_AXI_USER_LOCK; + + logic hit_CPTRA_WDT_CFG[0:1]; + logic [3:0] bus_CPTRA_WDT_CFG[0:1]; + logic [31:0] full_addr_CPTRA_WDT_CFG[0:1]; + assign full_addr_CPTRA_WDT_CFG[0] = `CLP_SOC_IFC_REG_CPTRA_WDT_CFG_0; + assign full_addr_CPTRA_WDT_CFG[1] = `CLP_SOC_IFC_REG_CPTRA_WDT_CFG_1; + + logic hit_CPTRA_iTRNG_ENTROPY_CONFIG_0; + logic [3:0] bus_CPTRA_iTRNG_ENTROPY_CONFIG_0; + logic [31:0] full_addr_CPTRA_iTRNG_ENTROPY_CONFIG_0 = `CLP_SOC_IFC_REG_CPTRA_ITRNG_ENTROPY_CONFIG_0; + + logic hit_CPTRA_iTRNG_ENTROPY_CONFIG_1; + logic [3:0] bus_CPTRA_iTRNG_ENTROPY_CONFIG_1; + logic [31:0] full_addr_CPTRA_iTRNG_ENTROPY_CONFIG_1 = `CLP_SOC_IFC_REG_CPTRA_ITRNG_ENTROPY_CONFIG_1; + + logic hit_CPTRA_RSVD_REG[0:1]; + logic [3:0] bus_CPTRA_RSVD_REG[0:1]; + logic [31:0] full_addr_CPTRA_RSVD_REG[0:1]; + assign full_addr_CPTRA_RSVD_REG[0] = `CLP_SOC_IFC_REG_CPTRA_RSVD_REG_0; + assign full_addr_CPTRA_RSVD_REG[1] = `CLP_SOC_IFC_REG_CPTRA_RSVD_REG_1; + + logic hit_CPTRA_HW_CAPABILITIES; + logic [3:0] bus_CPTRA_HW_CAPABILITIES; + logic [31:0] full_addr_CPTRA_HW_CAPABILITIES = `CLP_SOC_IFC_REG_CPTRA_HW_CAPABILITIES; + + logic hit_CPTRA_FW_CAPABILITIES; + logic [3:0] bus_CPTRA_FW_CAPABILITIES; + logic [31:0] full_addr_CPTRA_FW_CAPABILITIES = `CLP_SOC_IFC_REG_CPTRA_FW_CAPABILITIES; + + logic hit_CPTRA_CAP_LOCK; + logic [3:0] bus_CPTRA_CAP_LOCK; + logic [31:0] full_addr_CPTRA_CAP_LOCK = `CLP_SOC_IFC_REG_CPTRA_CAP_LOCK; + + logic hit_CPTRA_OWNER_PK_HASH[0:11]; + logic [3:0] bus_CPTRA_OWNER_PK_HASH[0:11]; + logic [31:0] full_addr_CPTRA_OWNER_PK_HASH[0:11]; + assign full_addr_CPTRA_OWNER_PK_HASH[0] = `CLP_SOC_IFC_REG_CPTRA_OWNER_PK_HASH_0; + assign full_addr_CPTRA_OWNER_PK_HASH[1] = `CLP_SOC_IFC_REG_CPTRA_OWNER_PK_HASH_1; + assign full_addr_CPTRA_OWNER_PK_HASH[2] = `CLP_SOC_IFC_REG_CPTRA_OWNER_PK_HASH_2; + assign full_addr_CPTRA_OWNER_PK_HASH[3] = `CLP_SOC_IFC_REG_CPTRA_OWNER_PK_HASH_3; + assign full_addr_CPTRA_OWNER_PK_HASH[4] = `CLP_SOC_IFC_REG_CPTRA_OWNER_PK_HASH_4; + assign full_addr_CPTRA_OWNER_PK_HASH[5] = `CLP_SOC_IFC_REG_CPTRA_OWNER_PK_HASH_5; + assign full_addr_CPTRA_OWNER_PK_HASH[6] = `CLP_SOC_IFC_REG_CPTRA_OWNER_PK_HASH_6; + assign full_addr_CPTRA_OWNER_PK_HASH[7] = `CLP_SOC_IFC_REG_CPTRA_OWNER_PK_HASH_7; + assign full_addr_CPTRA_OWNER_PK_HASH[8] = `CLP_SOC_IFC_REG_CPTRA_OWNER_PK_HASH_8; + assign full_addr_CPTRA_OWNER_PK_HASH[9] = `CLP_SOC_IFC_REG_CPTRA_OWNER_PK_HASH_9; + assign full_addr_CPTRA_OWNER_PK_HASH[10] = `CLP_SOC_IFC_REG_CPTRA_OWNER_PK_HASH_10; + assign full_addr_CPTRA_OWNER_PK_HASH[11] = `CLP_SOC_IFC_REG_CPTRA_OWNER_PK_HASH_11; + + logic hit_CPTRA_OWNER_PK_HASH_LOCK; + logic [3:0] bus_CPTRA_OWNER_PK_HASH_LOCK; + logic [31:0] full_addr_CPTRA_OWNER_PK_HASH_LOCK = `CLP_SOC_IFC_REG_CPTRA_OWNER_PK_HASH_LOCK; + + logic hit_fuse_uds_seed[0:15]; + logic [3:0] bus_fuse_uds_seed[0:15]; + logic [31:0] full_addr_fuse_uds_seed[0:15]; + assign full_addr_fuse_uds_seed[0] = `CLP_SOC_IFC_REG_FUSE_UDS_SEED_0; + assign full_addr_fuse_uds_seed[1] = `CLP_SOC_IFC_REG_FUSE_UDS_SEED_1; + assign full_addr_fuse_uds_seed[2] = `CLP_SOC_IFC_REG_FUSE_UDS_SEED_2; + assign full_addr_fuse_uds_seed[3] = `CLP_SOC_IFC_REG_FUSE_UDS_SEED_3; + assign full_addr_fuse_uds_seed[4] = `CLP_SOC_IFC_REG_FUSE_UDS_SEED_4; + assign full_addr_fuse_uds_seed[5] = `CLP_SOC_IFC_REG_FUSE_UDS_SEED_5; + assign full_addr_fuse_uds_seed[6] = `CLP_SOC_IFC_REG_FUSE_UDS_SEED_6; + assign full_addr_fuse_uds_seed[7] = `CLP_SOC_IFC_REG_FUSE_UDS_SEED_7; + assign full_addr_fuse_uds_seed[8] = `CLP_SOC_IFC_REG_FUSE_UDS_SEED_8; + assign full_addr_fuse_uds_seed[9] = `CLP_SOC_IFC_REG_FUSE_UDS_SEED_9; + assign full_addr_fuse_uds_seed[10] = `CLP_SOC_IFC_REG_FUSE_UDS_SEED_10; + assign full_addr_fuse_uds_seed[11] = `CLP_SOC_IFC_REG_FUSE_UDS_SEED_11; + assign full_addr_fuse_uds_seed[12] = `CLP_SOC_IFC_REG_FUSE_UDS_SEED_12; + assign full_addr_fuse_uds_seed[13] = `CLP_SOC_IFC_REG_FUSE_UDS_SEED_13; + assign full_addr_fuse_uds_seed[14] = `CLP_SOC_IFC_REG_FUSE_UDS_SEED_14; + assign full_addr_fuse_uds_seed[15] = `CLP_SOC_IFC_REG_FUSE_UDS_SEED_15; + + logic hit_fuse_field_entropy[0:7]; + logic [3:0] bus_fuse_field_entropy[0:7]; + logic [31:0] full_addr_fuse_field_entropy[0:7]; + assign full_addr_fuse_field_entropy[0] = `CLP_SOC_IFC_REG_FUSE_FIELD_ENTROPY_0; + assign full_addr_fuse_field_entropy[1] = `CLP_SOC_IFC_REG_FUSE_FIELD_ENTROPY_1; + assign full_addr_fuse_field_entropy[2] = `CLP_SOC_IFC_REG_FUSE_FIELD_ENTROPY_2; + assign full_addr_fuse_field_entropy[3] = `CLP_SOC_IFC_REG_FUSE_FIELD_ENTROPY_3; + assign full_addr_fuse_field_entropy[4] = `CLP_SOC_IFC_REG_FUSE_FIELD_ENTROPY_4; + assign full_addr_fuse_field_entropy[5] = `CLP_SOC_IFC_REG_FUSE_FIELD_ENTROPY_5; + assign full_addr_fuse_field_entropy[6] = `CLP_SOC_IFC_REG_FUSE_FIELD_ENTROPY_6; + assign full_addr_fuse_field_entropy[7] = `CLP_SOC_IFC_REG_FUSE_FIELD_ENTROPY_7; + + logic hit_fuse_vendor_pk_hash[0:11]; + logic [3:0] bus_fuse_vendor_pk_hash[0:11]; + logic [31:0] full_addr_fuse_vendor_pk_hash[0:11]; + assign full_addr_fuse_vendor_pk_hash[0] = `CLP_SOC_IFC_REG_FUSE_VENDOR_PK_HASH_0; + assign full_addr_fuse_vendor_pk_hash[1] = `CLP_SOC_IFC_REG_FUSE_VENDOR_PK_HASH_1; + assign full_addr_fuse_vendor_pk_hash[2] = `CLP_SOC_IFC_REG_FUSE_VENDOR_PK_HASH_2; + assign full_addr_fuse_vendor_pk_hash[3] = `CLP_SOC_IFC_REG_FUSE_VENDOR_PK_HASH_3; + assign full_addr_fuse_vendor_pk_hash[4] = `CLP_SOC_IFC_REG_FUSE_VENDOR_PK_HASH_4; + assign full_addr_fuse_vendor_pk_hash[5] = `CLP_SOC_IFC_REG_FUSE_VENDOR_PK_HASH_5; + assign full_addr_fuse_vendor_pk_hash[6] = `CLP_SOC_IFC_REG_FUSE_VENDOR_PK_HASH_6; + assign full_addr_fuse_vendor_pk_hash[7] = `CLP_SOC_IFC_REG_FUSE_VENDOR_PK_HASH_7; + assign full_addr_fuse_vendor_pk_hash[8] = `CLP_SOC_IFC_REG_FUSE_VENDOR_PK_HASH_8; + assign full_addr_fuse_vendor_pk_hash[9] = `CLP_SOC_IFC_REG_FUSE_VENDOR_PK_HASH_9; + assign full_addr_fuse_vendor_pk_hash[10] = `CLP_SOC_IFC_REG_FUSE_VENDOR_PK_HASH_10; + assign full_addr_fuse_vendor_pk_hash[11] = `CLP_SOC_IFC_REG_FUSE_VENDOR_PK_HASH_11; + + logic hit_fuse_ecc_revocation; + logic [3:0] bus_fuse_ecc_revocation; + logic [31:0] full_addr_fuse_ecc_revocation = `CLP_SOC_IFC_REG_FUSE_ECC_REVOCATION; + + logic hit_fuse_fmc_key_manifest_svn; + logic [3:0] bus_fuse_fmc_key_manifest_svn; + logic [31:0] full_addr_fuse_fmc_key_manifest_svn = `CLP_SOC_IFC_REG_FUSE_FMC_KEY_MANIFEST_SVN; + + logic hit_fuse_runtime_svn[0:3]; + logic [3:0] bus_fuse_runtime_svn[0:3]; + logic [31:0] full_addr_fuse_runtime_svn[0:3]; + assign full_addr_fuse_runtime_svn[0] = `CLP_SOC_IFC_REG_FUSE_RUNTIME_SVN_0; + assign full_addr_fuse_runtime_svn[1] = `CLP_SOC_IFC_REG_FUSE_RUNTIME_SVN_1; + assign full_addr_fuse_runtime_svn[2] = `CLP_SOC_IFC_REG_FUSE_RUNTIME_SVN_2; + assign full_addr_fuse_runtime_svn[3] = `CLP_SOC_IFC_REG_FUSE_RUNTIME_SVN_3; + + logic hit_fuse_anti_rollback_disable; + logic [3:0] bus_fuse_anti_rollback_disable; + logic [31:0] full_addr_fuse_anti_rollback_disable = `CLP_SOC_IFC_REG_FUSE_ANTI_ROLLBACK_DISABLE; + + logic hit_fuse_idevid_cert_attr[0:23]; + logic [3:0] bus_fuse_idevid_cert_attr[0:23]; + logic [31:0] full_addr_fuse_idevid_cert_attr[0:23]; + assign full_addr_fuse_idevid_cert_attr[0] = `CLP_SOC_IFC_REG_FUSE_IDEVID_CERT_ATTR_0; + assign full_addr_fuse_idevid_cert_attr[1] = `CLP_SOC_IFC_REG_FUSE_IDEVID_CERT_ATTR_1; + assign full_addr_fuse_idevid_cert_attr[2] = `CLP_SOC_IFC_REG_FUSE_IDEVID_CERT_ATTR_2; + assign full_addr_fuse_idevid_cert_attr[3] = `CLP_SOC_IFC_REG_FUSE_IDEVID_CERT_ATTR_3; + assign full_addr_fuse_idevid_cert_attr[4] = `CLP_SOC_IFC_REG_FUSE_IDEVID_CERT_ATTR_4; + assign full_addr_fuse_idevid_cert_attr[5] = `CLP_SOC_IFC_REG_FUSE_IDEVID_CERT_ATTR_5; + assign full_addr_fuse_idevid_cert_attr[6] = `CLP_SOC_IFC_REG_FUSE_IDEVID_CERT_ATTR_6; + assign full_addr_fuse_idevid_cert_attr[7] = `CLP_SOC_IFC_REG_FUSE_IDEVID_CERT_ATTR_7; + assign full_addr_fuse_idevid_cert_attr[8] = `CLP_SOC_IFC_REG_FUSE_IDEVID_CERT_ATTR_8; + assign full_addr_fuse_idevid_cert_attr[9] = `CLP_SOC_IFC_REG_FUSE_IDEVID_CERT_ATTR_9; + assign full_addr_fuse_idevid_cert_attr[10] = `CLP_SOC_IFC_REG_FUSE_IDEVID_CERT_ATTR_10; + assign full_addr_fuse_idevid_cert_attr[11] = `CLP_SOC_IFC_REG_FUSE_IDEVID_CERT_ATTR_11; + assign full_addr_fuse_idevid_cert_attr[12] = `CLP_SOC_IFC_REG_FUSE_IDEVID_CERT_ATTR_12; + assign full_addr_fuse_idevid_cert_attr[13] = `CLP_SOC_IFC_REG_FUSE_IDEVID_CERT_ATTR_13; + assign full_addr_fuse_idevid_cert_attr[14] = `CLP_SOC_IFC_REG_FUSE_IDEVID_CERT_ATTR_14; + assign full_addr_fuse_idevid_cert_attr[15] = `CLP_SOC_IFC_REG_FUSE_IDEVID_CERT_ATTR_15; + assign full_addr_fuse_idevid_cert_attr[16] = `CLP_SOC_IFC_REG_FUSE_IDEVID_CERT_ATTR_16; + assign full_addr_fuse_idevid_cert_attr[17] = `CLP_SOC_IFC_REG_FUSE_IDEVID_CERT_ATTR_17; + assign full_addr_fuse_idevid_cert_attr[18] = `CLP_SOC_IFC_REG_FUSE_IDEVID_CERT_ATTR_18; + assign full_addr_fuse_idevid_cert_attr[19] = `CLP_SOC_IFC_REG_FUSE_IDEVID_CERT_ATTR_19; + assign full_addr_fuse_idevid_cert_attr[20] = `CLP_SOC_IFC_REG_FUSE_IDEVID_CERT_ATTR_20; + assign full_addr_fuse_idevid_cert_attr[21] = `CLP_SOC_IFC_REG_FUSE_IDEVID_CERT_ATTR_21; + assign full_addr_fuse_idevid_cert_attr[22] = `CLP_SOC_IFC_REG_FUSE_IDEVID_CERT_ATTR_22; + assign full_addr_fuse_idevid_cert_attr[23] = `CLP_SOC_IFC_REG_FUSE_IDEVID_CERT_ATTR_23; + + logic hit_fuse_idevid_manuf_hsm_id[0:3]; + logic [3:0] bus_fuse_idevid_manuf_hsm_id[0:3]; + logic [31:0] full_addr_fuse_idevid_manuf_hsm_id[0:3]; + assign full_addr_fuse_idevid_manuf_hsm_id[0] = `CLP_SOC_IFC_REG_FUSE_IDEVID_MANUF_HSM_ID_0; + assign full_addr_fuse_idevid_manuf_hsm_id[1] = `CLP_SOC_IFC_REG_FUSE_IDEVID_MANUF_HSM_ID_1; + assign full_addr_fuse_idevid_manuf_hsm_id[2] = `CLP_SOC_IFC_REG_FUSE_IDEVID_MANUF_HSM_ID_2; + assign full_addr_fuse_idevid_manuf_hsm_id[3] = `CLP_SOC_IFC_REG_FUSE_IDEVID_MANUF_HSM_ID_3; + + logic hit_fuse_lms_revocation; + logic [3:0] bus_fuse_lms_revocation; + logic [31:0] full_addr_fuse_lms_revocation = `CLP_SOC_IFC_REG_FUSE_LMS_REVOCATION; + + logic hit_fuse_mldsa_revocation; + logic [3:0] bus_fuse_mldsa_revocation; + logic [31:0] full_addr_fuse_mldsa_revocation = `CLP_SOC_IFC_REG_FUSE_MLDSA_REVOCATION; + + logic hit_fuse_soc_stepping_id; + logic [3:0] bus_fuse_soc_stepping_id; + logic [31:0] full_addr_fuse_soc_stepping_id = `CLP_SOC_IFC_REG_FUSE_SOC_STEPPING_ID; + + logic hit_fuse_manuf_dbg_unlock_token[0:15]; + logic [3:0] bus_fuse_manuf_dbg_unlock_token[0:15]; + logic [31:0] full_addr_fuse_manuf_dbg_unlock_token[0:15]; + assign full_addr_fuse_manuf_dbg_unlock_token[0] = `CLP_SOC_IFC_REG_FUSE_MANUF_DBG_UNLOCK_TOKEN_0; + assign full_addr_fuse_manuf_dbg_unlock_token[1] = `CLP_SOC_IFC_REG_FUSE_MANUF_DBG_UNLOCK_TOKEN_1; + assign full_addr_fuse_manuf_dbg_unlock_token[2] = `CLP_SOC_IFC_REG_FUSE_MANUF_DBG_UNLOCK_TOKEN_2; + assign full_addr_fuse_manuf_dbg_unlock_token[3] = `CLP_SOC_IFC_REG_FUSE_MANUF_DBG_UNLOCK_TOKEN_3; + assign full_addr_fuse_manuf_dbg_unlock_token[4] = `CLP_SOC_IFC_REG_FUSE_MANUF_DBG_UNLOCK_TOKEN_4; + assign full_addr_fuse_manuf_dbg_unlock_token[5] = `CLP_SOC_IFC_REG_FUSE_MANUF_DBG_UNLOCK_TOKEN_5; + assign full_addr_fuse_manuf_dbg_unlock_token[6] = `CLP_SOC_IFC_REG_FUSE_MANUF_DBG_UNLOCK_TOKEN_6; + assign full_addr_fuse_manuf_dbg_unlock_token[7] = `CLP_SOC_IFC_REG_FUSE_MANUF_DBG_UNLOCK_TOKEN_7; + assign full_addr_fuse_manuf_dbg_unlock_token[8] = `CLP_SOC_IFC_REG_FUSE_MANUF_DBG_UNLOCK_TOKEN_8; + assign full_addr_fuse_manuf_dbg_unlock_token[9] = `CLP_SOC_IFC_REG_FUSE_MANUF_DBG_UNLOCK_TOKEN_9; + assign full_addr_fuse_manuf_dbg_unlock_token[10] = `CLP_SOC_IFC_REG_FUSE_MANUF_DBG_UNLOCK_TOKEN_10; + assign full_addr_fuse_manuf_dbg_unlock_token[11] = `CLP_SOC_IFC_REG_FUSE_MANUF_DBG_UNLOCK_TOKEN_11; + assign full_addr_fuse_manuf_dbg_unlock_token[12] = `CLP_SOC_IFC_REG_FUSE_MANUF_DBG_UNLOCK_TOKEN_12; + assign full_addr_fuse_manuf_dbg_unlock_token[13] = `CLP_SOC_IFC_REG_FUSE_MANUF_DBG_UNLOCK_TOKEN_13; + assign full_addr_fuse_manuf_dbg_unlock_token[14] = `CLP_SOC_IFC_REG_FUSE_MANUF_DBG_UNLOCK_TOKEN_14; + assign full_addr_fuse_manuf_dbg_unlock_token[15] = `CLP_SOC_IFC_REG_FUSE_MANUF_DBG_UNLOCK_TOKEN_15; + + logic hit_fuse_pqc_key_type; + logic [3:0] bus_fuse_pqc_key_type; + logic [31:0] full_addr_fuse_pqc_key_type = `CLP_SOC_IFC_REG_FUSE_PQC_KEY_TYPE; + + logic hit_fuse_soc_manifest_svn[0:3]; + logic [3:0] bus_fuse_soc_manifest_svn[0:3]; + logic [31:0] full_addr_fuse_soc_manifest_svn[0:3]; + assign full_addr_fuse_soc_manifest_svn[0] = `CLP_SOC_IFC_REG_FUSE_SOC_MANIFEST_SVN_0; + assign full_addr_fuse_soc_manifest_svn[1] = `CLP_SOC_IFC_REG_FUSE_SOC_MANIFEST_SVN_1; + assign full_addr_fuse_soc_manifest_svn[2] = `CLP_SOC_IFC_REG_FUSE_SOC_MANIFEST_SVN_2; + assign full_addr_fuse_soc_manifest_svn[3] = `CLP_SOC_IFC_REG_FUSE_SOC_MANIFEST_SVN_3; + + logic hit_fuse_soc_manifest_max_svn; + logic [3:0] bus_fuse_soc_manifest_max_svn; + logic [31:0] full_addr_fuse_soc_manifest_max_svn = `CLP_SOC_IFC_REG_FUSE_SOC_MANIFEST_MAX_SVN; + + logic hit_fuse_hek_seed[0:7]; + logic [3:0] bus_fuse_hek_seed[0:7]; + logic [31:0] full_addr_fuse_hek_seed[0:7]; + assign full_addr_fuse_hek_seed[0] = `CLP_SOC_IFC_REG_FUSE_HEK_SEED_0; + assign full_addr_fuse_hek_seed[1] = `CLP_SOC_IFC_REG_FUSE_HEK_SEED_1; + assign full_addr_fuse_hek_seed[2] = `CLP_SOC_IFC_REG_FUSE_HEK_SEED_2; + assign full_addr_fuse_hek_seed[3] = `CLP_SOC_IFC_REG_FUSE_HEK_SEED_3; + assign full_addr_fuse_hek_seed[4] = `CLP_SOC_IFC_REG_FUSE_HEK_SEED_4; + assign full_addr_fuse_hek_seed[5] = `CLP_SOC_IFC_REG_FUSE_HEK_SEED_5; + assign full_addr_fuse_hek_seed[6] = `CLP_SOC_IFC_REG_FUSE_HEK_SEED_6; + assign full_addr_fuse_hek_seed[7] = `CLP_SOC_IFC_REG_FUSE_HEK_SEED_7; + + logic hit_SS_CALIPTRA_BASE_ADDR_L; + logic [3:0] bus_SS_CALIPTRA_BASE_ADDR_L; + logic [31:0] full_addr_SS_CALIPTRA_BASE_ADDR_L = `CLP_SOC_IFC_REG_SS_CALIPTRA_BASE_ADDR_L; + + logic hit_SS_CALIPTRA_BASE_ADDR_H; + logic [3:0] bus_SS_CALIPTRA_BASE_ADDR_H; + logic [31:0] full_addr_SS_CALIPTRA_BASE_ADDR_H = `CLP_SOC_IFC_REG_SS_CALIPTRA_BASE_ADDR_H; + + logic hit_SS_MCI_BASE_ADDR_L; + logic [3:0] bus_SS_MCI_BASE_ADDR_L; + logic [31:0] full_addr_SS_MCI_BASE_ADDR_L = `CLP_SOC_IFC_REG_SS_MCI_BASE_ADDR_L; + + logic hit_SS_MCI_BASE_ADDR_H; + logic [3:0] bus_SS_MCI_BASE_ADDR_H; + logic [31:0] full_addr_SS_MCI_BASE_ADDR_H = `CLP_SOC_IFC_REG_SS_MCI_BASE_ADDR_H; + + logic hit_SS_RECOVERY_IFC_BASE_ADDR_L; + logic [3:0] bus_SS_RECOVERY_IFC_BASE_ADDR_L; + logic [31:0] full_addr_SS_RECOVERY_IFC_BASE_ADDR_L = `CLP_SOC_IFC_REG_SS_RECOVERY_IFC_BASE_ADDR_L; + + logic hit_SS_RECOVERY_IFC_BASE_ADDR_H; + logic [3:0] bus_SS_RECOVERY_IFC_BASE_ADDR_H; + logic [31:0] full_addr_SS_RECOVERY_IFC_BASE_ADDR_H = `CLP_SOC_IFC_REG_SS_RECOVERY_IFC_BASE_ADDR_H; + + logic hit_SS_OTP_FC_BASE_ADDR_L; + logic [3:0] bus_SS_OTP_FC_BASE_ADDR_L; + logic [31:0] full_addr_SS_OTP_FC_BASE_ADDR_L = `CLP_SOC_IFC_REG_SS_OTP_FC_BASE_ADDR_L; + + logic hit_SS_OTP_FC_BASE_ADDR_H; + logic [3:0] bus_SS_OTP_FC_BASE_ADDR_H; + logic [31:0] full_addr_SS_OTP_FC_BASE_ADDR_H = `CLP_SOC_IFC_REG_SS_OTP_FC_BASE_ADDR_H; + + logic hit_SS_UDS_SEED_BASE_ADDR_L; + logic [3:0] bus_SS_UDS_SEED_BASE_ADDR_L; + logic [31:0] full_addr_SS_UDS_SEED_BASE_ADDR_L = `CLP_SOC_IFC_REG_SS_UDS_SEED_BASE_ADDR_L; + + logic hit_SS_UDS_SEED_BASE_ADDR_H; + logic [3:0] bus_SS_UDS_SEED_BASE_ADDR_H; + logic [31:0] full_addr_SS_UDS_SEED_BASE_ADDR_H = `CLP_SOC_IFC_REG_SS_UDS_SEED_BASE_ADDR_H; + + logic hit_SS_PROD_DEBUG_UNLOCK_AUTH_PK_HASH_REG_BANK_OFFSET; + logic [3:0] bus_SS_PROD_DEBUG_UNLOCK_AUTH_PK_HASH_REG_BANK_OFFSET; + logic [31:0] full_addr_SS_PROD_DEBUG_UNLOCK_AUTH_PK_HASH_REG_BANK_OFFSET = `CLP_SOC_IFC_REG_SS_PROD_DEBUG_UNLOCK_AUTH_PK_HASH_REG_BANK_OFFSET; + + logic hit_SS_NUM_OF_PROD_DEBUG_UNLOCK_AUTH_PK_HASHES; + logic [3:0] bus_SS_NUM_OF_PROD_DEBUG_UNLOCK_AUTH_PK_HASHES; + logic [31:0] full_addr_SS_NUM_OF_PROD_DEBUG_UNLOCK_AUTH_PK_HASHES = `CLP_SOC_IFC_REG_SS_NUM_OF_PROD_DEBUG_UNLOCK_AUTH_PK_HASHES; + + logic hit_SS_DEBUG_INTENT; + logic [3:0] bus_SS_DEBUG_INTENT; + logic [31:0] full_addr_SS_DEBUG_INTENT = `CLP_SOC_IFC_REG_SS_DEBUG_INTENT; + + logic hit_SS_CALIPTRA_DMA_AXI_USER; + logic [3:0] bus_SS_CALIPTRA_DMA_AXI_USER; + logic [31:0] full_addr_SS_CALIPTRA_DMA_AXI_USER = `CLP_SOC_IFC_REG_SS_CALIPTRA_DMA_AXI_USER; + + logic hit_SS_EXTERNAL_STAGING_AREA_BASE_ADDR_L; + logic [3:0] bus_SS_EXTERNAL_STAGING_AREA_BASE_ADDR_L; + logic [31:0] full_addr_SS_EXTERNAL_STAGING_AREA_BASE_ADDR_L = `CLP_SOC_IFC_REG_SS_EXTERNAL_STAGING_AREA_BASE_ADDR_L; + + logic hit_SS_EXTERNAL_STAGING_AREA_BASE_ADDR_H; + logic [3:0] bus_SS_EXTERNAL_STAGING_AREA_BASE_ADDR_H; + logic [31:0] full_addr_SS_EXTERNAL_STAGING_AREA_BASE_ADDR_H = `CLP_SOC_IFC_REG_SS_EXTERNAL_STAGING_AREA_BASE_ADDR_H; + + logic hit_SS_KEY_RELEASE_BASE_ADDR_L; + logic [3:0] bus_SS_KEY_RELEASE_BASE_ADDR_L; + logic [31:0] full_addr_SS_KEY_RELEASE_BASE_ADDR_L = `CLP_SOC_IFC_REG_SS_KEY_RELEASE_BASE_ADDR_L; + + logic hit_SS_KEY_RELEASE_BASE_ADDR_H; + logic [3:0] bus_SS_KEY_RELEASE_BASE_ADDR_H; + logic [31:0] full_addr_SS_KEY_RELEASE_BASE_ADDR_H = `CLP_SOC_IFC_REG_SS_KEY_RELEASE_BASE_ADDR_H; + + logic hit_SS_KEY_RELEASE_SIZE; + logic [3:0] bus_SS_KEY_RELEASE_SIZE; + logic [31:0] full_addr_SS_KEY_RELEASE_SIZE = `CLP_SOC_IFC_REG_SS_KEY_RELEASE_SIZE; + + logic hit_SS_OCP_LOCK_CTRL; + logic [3:0] bus_SS_OCP_LOCK_CTRL; + logic [31:0] full_addr_SS_OCP_LOCK_CTRL = `CLP_SOC_IFC_REG_SS_OCP_LOCK_CTRL; + + logic hit_SS_STRAP_GENERIC[0:3]; + logic [3:0] bus_SS_STRAP_GENERIC[0:3]; + logic [31:0] full_addr_SS_STRAP_GENERIC[0:3]; + assign full_addr_SS_STRAP_GENERIC[0] = `CLP_SOC_IFC_REG_SS_STRAP_GENERIC_0; + assign full_addr_SS_STRAP_GENERIC[1] = `CLP_SOC_IFC_REG_SS_STRAP_GENERIC_1; + assign full_addr_SS_STRAP_GENERIC[2] = `CLP_SOC_IFC_REG_SS_STRAP_GENERIC_2; + assign full_addr_SS_STRAP_GENERIC[3] = `CLP_SOC_IFC_REG_SS_STRAP_GENERIC_3; + + logic hit_SS_DBG_SERVICE_REG_REQ; + logic [3:0] bus_SS_DBG_SERVICE_REG_REQ; + logic [31:0] full_addr_SS_DBG_SERVICE_REG_REQ = `CLP_SOC_IFC_REG_SS_DBG_SERVICE_REG_REQ; + + logic hit_SS_DBG_SERVICE_REG_RSP; + logic [3:0] bus_SS_DBG_SERVICE_REG_RSP; + logic [31:0] full_addr_SS_DBG_SERVICE_REG_RSP = `CLP_SOC_IFC_REG_SS_DBG_SERVICE_REG_RSP; + + logic hit_SS_SOC_DBG_UNLOCK_LEVEL[0:1]; + logic [3:0] bus_SS_SOC_DBG_UNLOCK_LEVEL[0:1]; + logic [31:0] full_addr_SS_SOC_DBG_UNLOCK_LEVEL[0:1]; + assign full_addr_SS_SOC_DBG_UNLOCK_LEVEL[0] = `CLP_SOC_IFC_REG_SS_SOC_DBG_UNLOCK_LEVEL_0; + assign full_addr_SS_SOC_DBG_UNLOCK_LEVEL[1] = `CLP_SOC_IFC_REG_SS_SOC_DBG_UNLOCK_LEVEL_1; + + logic hit_SS_GENERIC_FW_EXEC_CTRL[0:3]; + logic [3:0] bus_SS_GENERIC_FW_EXEC_CTRL[0:3]; + logic [31:0] full_addr_SS_GENERIC_FW_EXEC_CTRL[0:3]; + assign full_addr_SS_GENERIC_FW_EXEC_CTRL[0] = `CLP_SOC_IFC_REG_SS_GENERIC_FW_EXEC_CTRL_0; + assign full_addr_SS_GENERIC_FW_EXEC_CTRL[1] = `CLP_SOC_IFC_REG_SS_GENERIC_FW_EXEC_CTRL_1; + assign full_addr_SS_GENERIC_FW_EXEC_CTRL[2] = `CLP_SOC_IFC_REG_SS_GENERIC_FW_EXEC_CTRL_2; + assign full_addr_SS_GENERIC_FW_EXEC_CTRL[3] = `CLP_SOC_IFC_REG_SS_GENERIC_FW_EXEC_CTRL_3; + + logic hit_internal_obf_key[0:7]; + logic [3:0] bus_internal_obf_key[0:7]; + logic [31:0] full_addr_internal_obf_key[0:7]; + assign full_addr_internal_obf_key[0] = `CLP_SOC_IFC_REG_INTERNAL_OBF_KEY_0; + assign full_addr_internal_obf_key[1] = `CLP_SOC_IFC_REG_INTERNAL_OBF_KEY_1; + assign full_addr_internal_obf_key[2] = `CLP_SOC_IFC_REG_INTERNAL_OBF_KEY_2; + assign full_addr_internal_obf_key[3] = `CLP_SOC_IFC_REG_INTERNAL_OBF_KEY_3; + assign full_addr_internal_obf_key[4] = `CLP_SOC_IFC_REG_INTERNAL_OBF_KEY_4; + assign full_addr_internal_obf_key[5] = `CLP_SOC_IFC_REG_INTERNAL_OBF_KEY_5; + assign full_addr_internal_obf_key[6] = `CLP_SOC_IFC_REG_INTERNAL_OBF_KEY_6; + assign full_addr_internal_obf_key[7] = `CLP_SOC_IFC_REG_INTERNAL_OBF_KEY_7; + + logic hit_internal_iccm_lock; + logic [3:0] bus_internal_iccm_lock; + logic [31:0] full_addr_internal_iccm_lock = `CLP_SOC_IFC_REG_INTERNAL_ICCM_LOCK; + + logic hit_internal_fw_update_reset; + logic [3:0] bus_internal_fw_update_reset; + logic [31:0] full_addr_internal_fw_update_reset = `CLP_SOC_IFC_REG_INTERNAL_FW_UPDATE_RESET; + + logic hit_internal_fw_update_reset_wait_cycles; + logic [3:0] bus_internal_fw_update_reset_wait_cycles; + logic [31:0] full_addr_internal_fw_update_reset_wait_cycles = `CLP_SOC_IFC_REG_INTERNAL_FW_UPDATE_RESET_WAIT_CYCLES; + + logic hit_internal_nmi_vector; + logic [3:0] bus_internal_nmi_vector; + logic [31:0] full_addr_internal_nmi_vector = `CLP_SOC_IFC_REG_INTERNAL_NMI_VECTOR; + + logic hit_internal_hw_error_fatal_mask; + logic [3:0] bus_internal_hw_error_fatal_mask; + logic [31:0] full_addr_internal_hw_error_fatal_mask = `CLP_SOC_IFC_REG_INTERNAL_HW_ERROR_FATAL_MASK; + + logic hit_internal_hw_error_non_fatal_mask; + logic [3:0] bus_internal_hw_error_non_fatal_mask; + logic [31:0] full_addr_internal_hw_error_non_fatal_mask = `CLP_SOC_IFC_REG_INTERNAL_HW_ERROR_NON_FATAL_MASK; + + logic hit_internal_fw_error_fatal_mask; + logic [3:0] bus_internal_fw_error_fatal_mask; + logic [31:0] full_addr_internal_fw_error_fatal_mask = `CLP_SOC_IFC_REG_INTERNAL_FW_ERROR_FATAL_MASK; + + logic hit_internal_fw_error_non_fatal_mask; + logic [3:0] bus_internal_fw_error_non_fatal_mask; + logic [31:0] full_addr_internal_fw_error_non_fatal_mask = `CLP_SOC_IFC_REG_INTERNAL_FW_ERROR_NON_FATAL_MASK; + + logic hit_internal_rv_mtime_l; + logic [3:0] bus_internal_rv_mtime_l; + logic [31:0] full_addr_internal_rv_mtime_l = `CLP_SOC_IFC_REG_INTERNAL_RV_MTIME_L; + + logic hit_internal_rv_mtime_h; + logic [3:0] bus_internal_rv_mtime_h; + logic [31:0] full_addr_internal_rv_mtime_h = `CLP_SOC_IFC_REG_INTERNAL_RV_MTIME_H; + + logic hit_internal_rv_mtimecmp_l; + logic [3:0] bus_internal_rv_mtimecmp_l; + logic [31:0] full_addr_internal_rv_mtimecmp_l = `CLP_SOC_IFC_REG_INTERNAL_RV_MTIMECMP_L; + + logic hit_internal_rv_mtimecmp_h; + logic [3:0] bus_internal_rv_mtimecmp_h; + logic [31:0] full_addr_internal_rv_mtimecmp_h = `CLP_SOC_IFC_REG_INTERNAL_RV_MTIMECMP_H; + + logic hit_intr_brf_global_intr_en_r; + logic [3:0] bus_intr_brf_global_intr_en_r; + logic [31:0] full_addr_intr_brf_global_intr_en_r = `CLP_SOC_IFC_REG_INTR_BLOCK_RF_GLOBAL_INTR_EN_R; + + logic hit_intr_brf_error_intr_en_r; + logic [3:0] bus_intr_brf_error_intr_en_r; + logic [31:0] full_addr_intr_brf_error_intr_en_r = `CLP_SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R; + + logic hit_intr_brf_notif_intr_en_r; + logic [3:0] bus_intr_brf_notif_intr_en_r; + logic [31:0] full_addr_intr_brf_notif_intr_en_r = `CLP_SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_INTR_EN_R; + + logic hit_intr_brf_error_global_intr_r; + logic [3:0] bus_intr_brf_error_global_intr_r; + logic [31:0] full_addr_intr_brf_error_global_intr_r = `CLP_SOC_IFC_REG_INTR_BLOCK_RF_ERROR_GLOBAL_INTR_R; + + logic hit_intr_brf_notif_global_intr_r; + logic [3:0] bus_intr_brf_notif_global_intr_r; + logic [31:0] full_addr_intr_brf_notif_global_intr_r = `CLP_SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_GLOBAL_INTR_R; + + logic hit_intr_brf_error_internal_intr_r; + logic [3:0] bus_intr_brf_error_internal_intr_r; + logic [31:0] full_addr_intr_brf_error_internal_intr_r = `CLP_SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R; + + logic hit_intr_brf_notif_internal_intr_r; + logic [3:0] bus_intr_brf_notif_internal_intr_r; + logic [31:0] full_addr_intr_brf_notif_internal_intr_r = `CLP_SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R; + + logic hit_intr_brf_error_intr_trig_r; + logic [3:0] bus_intr_brf_error_intr_trig_r; + logic [31:0] full_addr_intr_brf_error_intr_trig_r = `CLP_SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTR_TRIG_R; + + logic hit_intr_brf_notif_intr_trig_r; + logic [3:0] bus_intr_brf_notif_intr_trig_r; + logic [31:0] full_addr_intr_brf_notif_intr_trig_r = `CLP_SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_INTR_TRIG_R; + + logic hit_intr_brf_error_internal_intr_count_r; + logic [3:0] bus_intr_brf_error_internal_intr_count_r; + logic [31:0] full_addr_intr_brf_error_internal_intr_count_r = `CLP_SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_COUNT_R; + + logic hit_intr_brf_error_inv_dev_intr_count_r; + logic [3:0] bus_intr_brf_error_inv_dev_intr_count_r; + logic [31:0] full_addr_intr_brf_error_inv_dev_intr_count_r = `CLP_SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INV_DEV_INTR_COUNT_R; + + logic hit_intr_brf_error_cmd_fail_intr_count_r; + logic [3:0] bus_intr_brf_error_cmd_fail_intr_count_r; + logic [31:0] full_addr_intr_brf_error_cmd_fail_intr_count_r = `CLP_SOC_IFC_REG_INTR_BLOCK_RF_ERROR_CMD_FAIL_INTR_COUNT_R; + + logic hit_intr_brf_error_bad_fuse_intr_count_r; + logic [3:0] bus_intr_brf_error_bad_fuse_intr_count_r; + logic [31:0] full_addr_intr_brf_error_bad_fuse_intr_count_r = `CLP_SOC_IFC_REG_INTR_BLOCK_RF_ERROR_BAD_FUSE_INTR_COUNT_R; + + logic hit_intr_brf_error_iccm_blocked_intr_count_r; + logic [3:0] bus_intr_brf_error_iccm_blocked_intr_count_r; + logic [31:0] full_addr_intr_brf_error_iccm_blocked_intr_count_r = `CLP_SOC_IFC_REG_INTR_BLOCK_RF_ERROR_ICCM_BLOCKED_INTR_COUNT_R; + + logic hit_intr_brf_error_mbox_ecc_unc_intr_count_r; + logic [3:0] bus_intr_brf_error_mbox_ecc_unc_intr_count_r; + logic [31:0] full_addr_intr_brf_error_mbox_ecc_unc_intr_count_r = `CLP_SOC_IFC_REG_INTR_BLOCK_RF_ERROR_MBOX_ECC_UNC_INTR_COUNT_R; + + logic hit_intr_brf_error_wdt_timer1_timeout_intr_count_r; + logic [3:0] bus_intr_brf_error_wdt_timer1_timeout_intr_count_r; + logic [31:0] full_addr_intr_brf_error_wdt_timer1_timeout_intr_count_r = `CLP_SOC_IFC_REG_INTR_BLOCK_RF_ERROR_WDT_TIMER1_TIMEOUT_INTR_COUNT_R; + + logic hit_intr_brf_error_wdt_timer2_timeout_intr_count_r; + logic [3:0] bus_intr_brf_error_wdt_timer2_timeout_intr_count_r; + logic [31:0] full_addr_intr_brf_error_wdt_timer2_timeout_intr_count_r = `CLP_SOC_IFC_REG_INTR_BLOCK_RF_ERROR_WDT_TIMER2_TIMEOUT_INTR_COUNT_R; + + logic hit_intr_brf_notif_cmd_avail_intr_count_r; + logic [3:0] bus_intr_brf_notif_cmd_avail_intr_count_r; + logic [31:0] full_addr_intr_brf_notif_cmd_avail_intr_count_r = `CLP_SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_CMD_AVAIL_INTR_COUNT_R; + + logic hit_intr_brf_notif_mbox_ecc_cor_intr_count_r; + logic [3:0] bus_intr_brf_notif_mbox_ecc_cor_intr_count_r; + logic [31:0] full_addr_intr_brf_notif_mbox_ecc_cor_intr_count_r = `CLP_SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_MBOX_ECC_COR_INTR_COUNT_R; + + logic hit_intr_brf_notif_debug_locked_intr_count_r; + logic [3:0] bus_intr_brf_notif_debug_locked_intr_count_r; + logic [31:0] full_addr_intr_brf_notif_debug_locked_intr_count_r = `CLP_SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_DEBUG_LOCKED_INTR_COUNT_R; + + logic hit_intr_brf_notif_scan_mode_intr_count_r; + logic [3:0] bus_intr_brf_notif_scan_mode_intr_count_r; + logic [31:0] full_addr_intr_brf_notif_scan_mode_intr_count_r = `CLP_SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_SCAN_MODE_INTR_COUNT_R; + + logic hit_intr_brf_notif_soc_req_lock_intr_count_r; + logic [3:0] bus_intr_brf_notif_soc_req_lock_intr_count_r; + logic [31:0] full_addr_intr_brf_notif_soc_req_lock_intr_count_r = `CLP_SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_SOC_REQ_LOCK_INTR_COUNT_R; + + logic hit_intr_brf_notif_gen_in_toggle_intr_count_r; + logic [3:0] bus_intr_brf_notif_gen_in_toggle_intr_count_r; + logic [31:0] full_addr_intr_brf_notif_gen_in_toggle_intr_count_r = `CLP_SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_GEN_IN_TOGGLE_INTR_COUNT_R; + + logic hit_intr_brf_error_internal_intr_count_incr_r; + logic [3:0] bus_intr_brf_error_internal_intr_count_incr_r; + logic [31:0] full_addr_intr_brf_error_internal_intr_count_incr_r = `CLP_SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_COUNT_INCR_R; + + logic hit_intr_brf_error_inv_dev_intr_count_incr_r; + logic [3:0] bus_intr_brf_error_inv_dev_intr_count_incr_r; + logic [31:0] full_addr_intr_brf_error_inv_dev_intr_count_incr_r = `CLP_SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INV_DEV_INTR_COUNT_INCR_R; + + logic hit_intr_brf_error_cmd_fail_intr_count_incr_r; + logic [3:0] bus_intr_brf_error_cmd_fail_intr_count_incr_r; + logic [31:0] full_addr_intr_brf_error_cmd_fail_intr_count_incr_r = `CLP_SOC_IFC_REG_INTR_BLOCK_RF_ERROR_CMD_FAIL_INTR_COUNT_INCR_R; + + logic hit_intr_brf_error_bad_fuse_intr_count_incr_r; + logic [3:0] bus_intr_brf_error_bad_fuse_intr_count_incr_r; + logic [31:0] full_addr_intr_brf_error_bad_fuse_intr_count_incr_r = `CLP_SOC_IFC_REG_INTR_BLOCK_RF_ERROR_BAD_FUSE_INTR_COUNT_INCR_R; + + logic hit_intr_brf_error_iccm_blocked_intr_count_incr_r; + logic [3:0] bus_intr_brf_error_iccm_blocked_intr_count_incr_r; + logic [31:0] full_addr_intr_brf_error_iccm_blocked_intr_count_incr_r = `CLP_SOC_IFC_REG_INTR_BLOCK_RF_ERROR_ICCM_BLOCKED_INTR_COUNT_INCR_R; + + logic hit_intr_brf_error_mbox_ecc_unc_intr_count_incr_r; + logic [3:0] bus_intr_brf_error_mbox_ecc_unc_intr_count_incr_r; + logic [31:0] full_addr_intr_brf_error_mbox_ecc_unc_intr_count_incr_r = `CLP_SOC_IFC_REG_INTR_BLOCK_RF_ERROR_MBOX_ECC_UNC_INTR_COUNT_INCR_R; + + logic hit_intr_brf_error_wdt_timer1_timeout_intr_count_incr_r; + logic [3:0] bus_intr_brf_error_wdt_timer1_timeout_intr_count_incr_r; + logic [31:0] full_addr_intr_brf_error_wdt_timer1_timeout_intr_count_incr_r = `CLP_SOC_IFC_REG_INTR_BLOCK_RF_ERROR_WDT_TIMER1_TIMEOUT_INTR_COUNT_INCR_R; + + logic hit_intr_brf_error_wdt_timer2_timeout_intr_count_incr_r; + logic [3:0] bus_intr_brf_error_wdt_timer2_timeout_intr_count_incr_r; + logic [31:0] full_addr_intr_brf_error_wdt_timer2_timeout_intr_count_incr_r = `CLP_SOC_IFC_REG_INTR_BLOCK_RF_ERROR_WDT_TIMER2_TIMEOUT_INTR_COUNT_INCR_R; + + logic hit_intr_brf_notif_cmd_avail_intr_count_incr_r; + logic [3:0] bus_intr_brf_notif_cmd_avail_intr_count_incr_r; + logic [31:0] full_addr_intr_brf_notif_cmd_avail_intr_count_incr_r = `CLP_SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_CMD_AVAIL_INTR_COUNT_INCR_R; + + logic hit_intr_brf_notif_mbox_ecc_cor_intr_count_incr_r; + logic [3:0] bus_intr_brf_notif_mbox_ecc_cor_intr_count_incr_r; + logic [31:0] full_addr_intr_brf_notif_mbox_ecc_cor_intr_count_incr_r = `CLP_SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_MBOX_ECC_COR_INTR_COUNT_INCR_R; + + logic hit_intr_brf_notif_debug_locked_intr_count_incr_r; + logic [3:0] bus_intr_brf_notif_debug_locked_intr_count_incr_r; + logic [31:0] full_addr_intr_brf_notif_debug_locked_intr_count_incr_r = `CLP_SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_DEBUG_LOCKED_INTR_COUNT_INCR_R; + + logic hit_intr_brf_notif_scan_mode_intr_count_incr_r; + logic [3:0] bus_intr_brf_notif_scan_mode_intr_count_incr_r; + logic [31:0] full_addr_intr_brf_notif_scan_mode_intr_count_incr_r = `CLP_SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_SCAN_MODE_INTR_COUNT_INCR_R; + + logic hit_intr_brf_notif_soc_req_lock_intr_count_incr_r; + logic [3:0] bus_intr_brf_notif_soc_req_lock_intr_count_incr_r; + logic [31:0] full_addr_intr_brf_notif_soc_req_lock_intr_count_incr_r = `CLP_SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_SOC_REQ_LOCK_INTR_COUNT_INCR_R; + + logic hit_intr_brf_notif_gen_in_toggle_intr_count_incr_r; + logic [3:0] bus_intr_brf_notif_gen_in_toggle_intr_count_incr_r; + logic [31:0] full_addr_intr_brf_notif_gen_in_toggle_intr_count_incr_r = `CLP_SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_GEN_IN_TOGGLE_INTR_COUNT_INCR_R; + + + assign hit_CPTRA_HW_ERROR_FATAL = (soc_ifc_reg_req_data.addr == full_addr_CPTRA_HW_ERROR_FATAL[AXI_ADDR_WIDTH-1:0]); + assign bus_CPTRA_HW_ERROR_FATAL = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_CPTRA_HW_ERROR_FATAL}}; + + assign hit_CPTRA_HW_ERROR_NON_FATAL = (soc_ifc_reg_req_data.addr == full_addr_CPTRA_HW_ERROR_NON_FATAL[AXI_ADDR_WIDTH-1:0]); + assign bus_CPTRA_HW_ERROR_NON_FATAL = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_CPTRA_HW_ERROR_NON_FATAL}}; + + assign hit_CPTRA_FW_ERROR_FATAL = (soc_ifc_reg_req_data.addr == full_addr_CPTRA_FW_ERROR_FATAL[AXI_ADDR_WIDTH-1:0]); + assign bus_CPTRA_FW_ERROR_FATAL = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_CPTRA_FW_ERROR_FATAL}}; + + assign hit_CPTRA_FW_ERROR_NON_FATAL = (soc_ifc_reg_req_data.addr == full_addr_CPTRA_FW_ERROR_NON_FATAL[AXI_ADDR_WIDTH-1:0]); + assign bus_CPTRA_FW_ERROR_NON_FATAL = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_CPTRA_FW_ERROR_NON_FATAL}}; + + assign hit_CPTRA_HW_ERROR_ENC = (soc_ifc_reg_req_data.addr == full_addr_CPTRA_HW_ERROR_ENC[AXI_ADDR_WIDTH-1:0]); + assign bus_CPTRA_HW_ERROR_ENC = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_CPTRA_HW_ERROR_ENC}}; + + assign hit_CPTRA_FW_ERROR_ENC = (soc_ifc_reg_req_data.addr == full_addr_CPTRA_FW_ERROR_ENC[AXI_ADDR_WIDTH-1:0]); + assign bus_CPTRA_FW_ERROR_ENC = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_CPTRA_FW_ERROR_ENC}}; + + assign hit_CPTRA_FW_EXTENDED_ERROR_INFO[0] = (soc_ifc_reg_req_data.addr == full_addr_CPTRA_FW_EXTENDED_ERROR_INFO[0][18-1:0]); + assign bus_CPTRA_FW_EXTENDED_ERROR_INFO[0] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_CPTRA_FW_EXTENDED_ERROR_INFO[0]}}; + + assign hit_CPTRA_FW_EXTENDED_ERROR_INFO[1] = (soc_ifc_reg_req_data.addr == full_addr_CPTRA_FW_EXTENDED_ERROR_INFO[1][18-1:0]); + assign bus_CPTRA_FW_EXTENDED_ERROR_INFO[1] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_CPTRA_FW_EXTENDED_ERROR_INFO[1]}}; + + assign hit_CPTRA_FW_EXTENDED_ERROR_INFO[2] = (soc_ifc_reg_req_data.addr == full_addr_CPTRA_FW_EXTENDED_ERROR_INFO[2][18-1:0]); + assign bus_CPTRA_FW_EXTENDED_ERROR_INFO[2] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_CPTRA_FW_EXTENDED_ERROR_INFO[2]}}; + + assign hit_CPTRA_FW_EXTENDED_ERROR_INFO[3] = (soc_ifc_reg_req_data.addr == full_addr_CPTRA_FW_EXTENDED_ERROR_INFO[3][18-1:0]); + assign bus_CPTRA_FW_EXTENDED_ERROR_INFO[3] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_CPTRA_FW_EXTENDED_ERROR_INFO[3]}}; + + assign hit_CPTRA_FW_EXTENDED_ERROR_INFO[4] = (soc_ifc_reg_req_data.addr == full_addr_CPTRA_FW_EXTENDED_ERROR_INFO[4][18-1:0]); + assign bus_CPTRA_FW_EXTENDED_ERROR_INFO[4] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_CPTRA_FW_EXTENDED_ERROR_INFO[4]}}; + + assign hit_CPTRA_FW_EXTENDED_ERROR_INFO[5] = (soc_ifc_reg_req_data.addr == full_addr_CPTRA_FW_EXTENDED_ERROR_INFO[5][18-1:0]); + assign bus_CPTRA_FW_EXTENDED_ERROR_INFO[5] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_CPTRA_FW_EXTENDED_ERROR_INFO[5]}}; + + assign hit_CPTRA_FW_EXTENDED_ERROR_INFO[6] = (soc_ifc_reg_req_data.addr == full_addr_CPTRA_FW_EXTENDED_ERROR_INFO[6][18-1:0]); + assign bus_CPTRA_FW_EXTENDED_ERROR_INFO[6] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_CPTRA_FW_EXTENDED_ERROR_INFO[6]}}; + + assign hit_CPTRA_FW_EXTENDED_ERROR_INFO[7] = (soc_ifc_reg_req_data.addr == full_addr_CPTRA_FW_EXTENDED_ERROR_INFO[7][18-1:0]); + assign bus_CPTRA_FW_EXTENDED_ERROR_INFO[7] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_CPTRA_FW_EXTENDED_ERROR_INFO[7]}}; + + assign hit_CPTRA_BOOT_STATUS = (soc_ifc_reg_req_data.addr == full_addr_CPTRA_BOOT_STATUS[AXI_ADDR_WIDTH-1:0]); + assign bus_CPTRA_BOOT_STATUS = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_CPTRA_BOOT_STATUS}}; + + assign hit_CPTRA_FLOW_STATUS = (soc_ifc_reg_req_data.addr == full_addr_CPTRA_FLOW_STATUS[AXI_ADDR_WIDTH-1:0]); + assign bus_CPTRA_FLOW_STATUS = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_CPTRA_FLOW_STATUS}}; + + assign hit_CPTRA_RESET_REASON = (soc_ifc_reg_req_data.addr == full_addr_CPTRA_RESET_REASON[AXI_ADDR_WIDTH-1:0]); + assign bus_CPTRA_RESET_REASON = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_CPTRA_RESET_REASON}}; + + // assign hit_CPTRA_SECURITY_STATE = (soc_ifc_reg_req_data.addr == full_addr_CPTRA_SECURITY_STATE[AXI_ADDR_WIDTH-1:0]); + // assign bus_CPTRA_SECURITY_STATE = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_CPTRA_SECURITY_STATE}}; + + assign hit_CPTRA_MBOX_VALID_AXI_USER[0] = (soc_ifc_reg_req_data.addr == full_addr_CPTRA_MBOX_VALID_AXI_USER[0][18-1:0]); + assign bus_CPTRA_MBOX_VALID_AXI_USER[0] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_CPTRA_MBOX_VALID_AXI_USER[0]}}; + + assign hit_CPTRA_MBOX_VALID_AXI_USER[1] = (soc_ifc_reg_req_data.addr == full_addr_CPTRA_MBOX_VALID_AXI_USER[1][18-1:0]); + assign bus_CPTRA_MBOX_VALID_AXI_USER[1] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_CPTRA_MBOX_VALID_AXI_USER[1]}}; + + assign hit_CPTRA_MBOX_VALID_AXI_USER[2] = (soc_ifc_reg_req_data.addr == full_addr_CPTRA_MBOX_VALID_AXI_USER[2][18-1:0]); + assign bus_CPTRA_MBOX_VALID_AXI_USER[2] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_CPTRA_MBOX_VALID_AXI_USER[2]}}; + + assign hit_CPTRA_MBOX_VALID_AXI_USER[3] = (soc_ifc_reg_req_data.addr == full_addr_CPTRA_MBOX_VALID_AXI_USER[3][18-1:0]); + assign bus_CPTRA_MBOX_VALID_AXI_USER[3] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_CPTRA_MBOX_VALID_AXI_USER[3]}}; + + assign hit_CPTRA_MBOX_VALID_AXI_USER[4] = (soc_ifc_reg_req_data.addr == full_addr_CPTRA_MBOX_VALID_AXI_USER[4][18-1:0]); + assign bus_CPTRA_MBOX_VALID_AXI_USER[4] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_CPTRA_MBOX_VALID_AXI_USER[4]}}; + + assign hit_CPTRA_MBOX_AXI_USER_LOCK[0] = (soc_ifc_reg_req_data.addr == full_addr_CPTRA_MBOX_AXI_USER_LOCK[0][18-1:0]); + assign bus_CPTRA_MBOX_AXI_USER_LOCK[0] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_CPTRA_MBOX_AXI_USER_LOCK[0]}}; + + assign hit_CPTRA_MBOX_AXI_USER_LOCK[1] = (soc_ifc_reg_req_data.addr == full_addr_CPTRA_MBOX_AXI_USER_LOCK[1][18-1:0]); + assign bus_CPTRA_MBOX_AXI_USER_LOCK[1] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_CPTRA_MBOX_AXI_USER_LOCK[1]}}; + + assign hit_CPTRA_MBOX_AXI_USER_LOCK[2] = (soc_ifc_reg_req_data.addr == full_addr_CPTRA_MBOX_AXI_USER_LOCK[2][18-1:0]); + assign bus_CPTRA_MBOX_AXI_USER_LOCK[2] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_CPTRA_MBOX_AXI_USER_LOCK[2]}}; + + assign hit_CPTRA_MBOX_AXI_USER_LOCK[3] = (soc_ifc_reg_req_data.addr == full_addr_CPTRA_MBOX_AXI_USER_LOCK[3][18-1:0]); + assign bus_CPTRA_MBOX_AXI_USER_LOCK[3] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_CPTRA_MBOX_AXI_USER_LOCK[3]}}; + + assign hit_CPTRA_MBOX_AXI_USER_LOCK[4] = (soc_ifc_reg_req_data.addr == full_addr_CPTRA_MBOX_AXI_USER_LOCK[4][18-1:0]); + assign bus_CPTRA_MBOX_AXI_USER_LOCK[4] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_CPTRA_MBOX_AXI_USER_LOCK[4]}}; + + assign hit_CPTRA_TRNG_VALID_AXI_USER = (soc_ifc_reg_req_data.addr == full_addr_CPTRA_TRNG_VALID_AXI_USER[AXI_ADDR_WIDTH-1:0]); + assign bus_CPTRA_TRNG_VALID_AXI_USER = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_CPTRA_TRNG_VALID_AXI_USER}}; + + assign hit_CPTRA_TRNG_AXI_USER_LOCK = (soc_ifc_reg_req_data.addr == full_addr_CPTRA_TRNG_AXI_USER_LOCK[AXI_ADDR_WIDTH-1:0]); + assign bus_CPTRA_TRNG_AXI_USER_LOCK = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_CPTRA_TRNG_AXI_USER_LOCK}}; + + assign hit_CPTRA_TRNG_DATA[0] = (soc_ifc_reg_req_data.addr == full_addr_CPTRA_TRNG_DATA[0][18-1:0]); + assign bus_CPTRA_TRNG_DATA[0] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_CPTRA_TRNG_DATA[0]}}; + + assign hit_CPTRA_TRNG_DATA[1] = (soc_ifc_reg_req_data.addr == full_addr_CPTRA_TRNG_DATA[1][18-1:0]); + assign bus_CPTRA_TRNG_DATA[1] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_CPTRA_TRNG_DATA[1]}}; + + assign hit_CPTRA_TRNG_DATA[2] = (soc_ifc_reg_req_data.addr == full_addr_CPTRA_TRNG_DATA[2][18-1:0]); + assign bus_CPTRA_TRNG_DATA[2] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_CPTRA_TRNG_DATA[2]}}; + + assign hit_CPTRA_TRNG_DATA[3] = (soc_ifc_reg_req_data.addr == full_addr_CPTRA_TRNG_DATA[3][18-1:0]); + assign bus_CPTRA_TRNG_DATA[3] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_CPTRA_TRNG_DATA[3]}}; + + assign hit_CPTRA_TRNG_DATA[4] = (soc_ifc_reg_req_data.addr == full_addr_CPTRA_TRNG_DATA[4][18-1:0]); + assign bus_CPTRA_TRNG_DATA[4] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_CPTRA_TRNG_DATA[4]}}; + + assign hit_CPTRA_TRNG_DATA[5] = (soc_ifc_reg_req_data.addr == full_addr_CPTRA_TRNG_DATA[5][18-1:0]); + assign bus_CPTRA_TRNG_DATA[5] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_CPTRA_TRNG_DATA[5]}}; + + assign hit_CPTRA_TRNG_DATA[6] = (soc_ifc_reg_req_data.addr == full_addr_CPTRA_TRNG_DATA[6][18-1:0]); + assign bus_CPTRA_TRNG_DATA[6] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_CPTRA_TRNG_DATA[6]}}; + + assign hit_CPTRA_TRNG_DATA[7] = (soc_ifc_reg_req_data.addr == full_addr_CPTRA_TRNG_DATA[7][18-1:0]); + assign bus_CPTRA_TRNG_DATA[7] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_CPTRA_TRNG_DATA[7]}}; + + assign hit_CPTRA_TRNG_DATA[8] = (soc_ifc_reg_req_data.addr == full_addr_CPTRA_TRNG_DATA[8][18-1:0]); + assign bus_CPTRA_TRNG_DATA[8] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_CPTRA_TRNG_DATA[8]}}; + + assign hit_CPTRA_TRNG_DATA[9] = (soc_ifc_reg_req_data.addr == full_addr_CPTRA_TRNG_DATA[9][18-1:0]); + assign bus_CPTRA_TRNG_DATA[9] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_CPTRA_TRNG_DATA[9]}}; + + assign hit_CPTRA_TRNG_DATA[10] = (soc_ifc_reg_req_data.addr == full_addr_CPTRA_TRNG_DATA[10][18-1:0]); + assign bus_CPTRA_TRNG_DATA[10] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_CPTRA_TRNG_DATA[10]}}; + + assign hit_CPTRA_TRNG_DATA[11] = (soc_ifc_reg_req_data.addr == full_addr_CPTRA_TRNG_DATA[11][18-1:0]); + assign bus_CPTRA_TRNG_DATA[11] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_CPTRA_TRNG_DATA[11]}}; + + assign hit_CPTRA_TRNG_CTRL = (soc_ifc_reg_req_data.addr == full_addr_CPTRA_TRNG_CTRL[AXI_ADDR_WIDTH-1:0]); + assign bus_CPTRA_TRNG_CTRL = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_CPTRA_TRNG_CTRL}}; + + assign hit_CPTRA_TRNG_STATUS = (soc_ifc_reg_req_data.addr == full_addr_CPTRA_TRNG_STATUS[AXI_ADDR_WIDTH-1:0]); + assign bus_CPTRA_TRNG_STATUS = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_CPTRA_TRNG_STATUS}}; + + assign hit_CPTRA_FUSE_WR_DONE = (soc_ifc_reg_req_data.addr == full_addr_CPTRA_FUSE_WR_DONE[AXI_ADDR_WIDTH-1:0]); + assign bus_CPTRA_FUSE_WR_DONE = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_CPTRA_FUSE_WR_DONE}}; + + assign hit_CPTRA_TIMER_CONFIG = (soc_ifc_reg_req_data.addr == full_addr_CPTRA_TIMER_CONFIG[AXI_ADDR_WIDTH-1:0]); + assign bus_CPTRA_TIMER_CONFIG = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_CPTRA_TIMER_CONFIG}}; + + assign hit_CPTRA_BOOTFSM_GO = (soc_ifc_reg_req_data.addr == full_addr_CPTRA_BOOTFSM_GO[AXI_ADDR_WIDTH-1:0]); + assign bus_CPTRA_BOOTFSM_GO = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_CPTRA_BOOTFSM_GO}}; + + assign hit_CPTRA_DBG_MANUF_SERVICE_REG = (soc_ifc_reg_req_data.addr == full_addr_CPTRA_DBG_MANUF_SERVICE_REG[AXI_ADDR_WIDTH-1:0]); + assign bus_CPTRA_DBG_MANUF_SERVICE_REG = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_CPTRA_DBG_MANUF_SERVICE_REG}}; + + assign hit_CPTRA_CLK_GATING_EN = (soc_ifc_reg_req_data.addr == full_addr_CPTRA_CLK_GATING_EN[AXI_ADDR_WIDTH-1:0]); + assign bus_CPTRA_CLK_GATING_EN = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_CPTRA_CLK_GATING_EN}}; + + assign hit_CPTRA_GENERIC_INPUT_WIRES[0] = (soc_ifc_reg_req_data.addr == full_addr_CPTRA_GENERIC_INPUT_WIRES[0][18-1:0]); + assign bus_CPTRA_GENERIC_INPUT_WIRES[0] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_CPTRA_GENERIC_INPUT_WIRES[0]}}; + + assign hit_CPTRA_GENERIC_INPUT_WIRES[1] = (soc_ifc_reg_req_data.addr == full_addr_CPTRA_GENERIC_INPUT_WIRES[1][18-1:0]); + assign bus_CPTRA_GENERIC_INPUT_WIRES[1] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_CPTRA_GENERIC_INPUT_WIRES[1]}}; + + assign hit_CPTRA_GENERIC_OUTPUT_WIRES[0] = (soc_ifc_reg_req_data.addr == full_addr_CPTRA_GENERIC_OUTPUT_WIRES[0][18-1:0]); + assign bus_CPTRA_GENERIC_OUTPUT_WIRES[0] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_CPTRA_GENERIC_OUTPUT_WIRES[0]}}; + + assign hit_CPTRA_GENERIC_OUTPUT_WIRES[1] = (soc_ifc_reg_req_data.addr == full_addr_CPTRA_GENERIC_OUTPUT_WIRES[1][18-1:0]); + assign bus_CPTRA_GENERIC_OUTPUT_WIRES[1] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_CPTRA_GENERIC_OUTPUT_WIRES[1]}}; + + // assign hit_CPTRA_HW_REV_ID = (soc_ifc_reg_req_data.addr == full_addr_CPTRA_HW_REV_ID[AXI_ADDR_WIDTH-1:0]); + // assign bus_CPTRA_HW_REV_ID = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_CPTRA_HW_REV_ID}}; + + assign hit_CPTRA_FW_REV_ID[0] = (soc_ifc_reg_req_data.addr == full_addr_CPTRA_FW_REV_ID[0][18-1:0]); + assign bus_CPTRA_FW_REV_ID[0] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_CPTRA_FW_REV_ID[0]}}; + + assign hit_CPTRA_FW_REV_ID[1] = (soc_ifc_reg_req_data.addr == full_addr_CPTRA_FW_REV_ID[1][18-1:0]); + assign bus_CPTRA_FW_REV_ID[1] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_CPTRA_FW_REV_ID[1]}}; + + // assign hit_CPTRA_HW_CONFIG = (soc_ifc_reg_req_data.addr == full_addr_CPTRA_HW_CONFIG[AXI_ADDR_WIDTH-1:0]); + // assign bus_CPTRA_HW_CONFIG = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_CPTRA_HW_CONFIG}}; + + assign hit_CPTRA_WDT_TIMER1_EN = (soc_ifc_reg_req_data.addr == full_addr_CPTRA_WDT_TIMER1_EN[AXI_ADDR_WIDTH-1:0]); + assign bus_CPTRA_WDT_TIMER1_EN = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_CPTRA_WDT_TIMER1_EN}}; + + assign hit_CPTRA_WDT_TIMER1_CTRL = (soc_ifc_reg_req_data.addr == full_addr_CPTRA_WDT_TIMER1_CTRL[AXI_ADDR_WIDTH-1:0]); + assign bus_CPTRA_WDT_TIMER1_CTRL = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_CPTRA_WDT_TIMER1_CTRL}}; + + assign hit_CPTRA_WDT_TIMER1_TIMEOUT_PERIOD[0] = (soc_ifc_reg_req_data.addr == full_addr_CPTRA_WDT_TIMER1_TIMEOUT_PERIOD[0][18-1:0]); + assign bus_CPTRA_WDT_TIMER1_TIMEOUT_PERIOD[0] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_CPTRA_WDT_TIMER1_TIMEOUT_PERIOD[0]}}; + + assign hit_CPTRA_WDT_TIMER1_TIMEOUT_PERIOD[1] = (soc_ifc_reg_req_data.addr == full_addr_CPTRA_WDT_TIMER1_TIMEOUT_PERIOD[1][18-1:0]); + assign bus_CPTRA_WDT_TIMER1_TIMEOUT_PERIOD[1] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_CPTRA_WDT_TIMER1_TIMEOUT_PERIOD[1]}}; + + assign hit_CPTRA_WDT_TIMER2_EN = (soc_ifc_reg_req_data.addr == full_addr_CPTRA_WDT_TIMER2_EN[AXI_ADDR_WIDTH-1:0]); + assign bus_CPTRA_WDT_TIMER2_EN = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_CPTRA_WDT_TIMER2_EN}}; + + assign hit_CPTRA_WDT_TIMER2_CTRL = (soc_ifc_reg_req_data.addr == full_addr_CPTRA_WDT_TIMER2_CTRL[AXI_ADDR_WIDTH-1:0]); + assign bus_CPTRA_WDT_TIMER2_CTRL = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_CPTRA_WDT_TIMER2_CTRL}}; + + assign hit_CPTRA_WDT_TIMER2_TIMEOUT_PERIOD[0] = (soc_ifc_reg_req_data.addr == full_addr_CPTRA_WDT_TIMER2_TIMEOUT_PERIOD[0][18-1:0]); + assign bus_CPTRA_WDT_TIMER2_TIMEOUT_PERIOD[0] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_CPTRA_WDT_TIMER2_TIMEOUT_PERIOD[0]}}; + + assign hit_CPTRA_WDT_TIMER2_TIMEOUT_PERIOD[1] = (soc_ifc_reg_req_data.addr == full_addr_CPTRA_WDT_TIMER2_TIMEOUT_PERIOD[1][18-1:0]); + assign bus_CPTRA_WDT_TIMER2_TIMEOUT_PERIOD[1] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_CPTRA_WDT_TIMER2_TIMEOUT_PERIOD[1]}}; + + assign hit_CPTRA_WDT_STATUS = (soc_ifc_reg_req_data.addr == full_addr_CPTRA_WDT_STATUS[AXI_ADDR_WIDTH-1:0]); + assign bus_CPTRA_WDT_STATUS = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_CPTRA_WDT_STATUS}}; + + assign hit_CPTRA_FUSE_VALID_AXI_USER = (soc_ifc_reg_req_data.addr == full_addr_CPTRA_FUSE_VALID_AXI_USER[AXI_ADDR_WIDTH-1:0]); + assign bus_CPTRA_FUSE_VALID_AXI_USER = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_CPTRA_FUSE_VALID_AXI_USER}}; + + assign hit_CPTRA_FUSE_AXI_USER_LOCK = (soc_ifc_reg_req_data.addr == full_addr_CPTRA_FUSE_AXI_USER_LOCK[AXI_ADDR_WIDTH-1:0]); + assign bus_CPTRA_FUSE_AXI_USER_LOCK = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_CPTRA_FUSE_AXI_USER_LOCK}}; + + assign hit_CPTRA_WDT_CFG[0] = (soc_ifc_reg_req_data.addr == full_addr_CPTRA_WDT_CFG[0][18-1:0]); + assign bus_CPTRA_WDT_CFG[0] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_CPTRA_WDT_CFG[0]}}; + + assign hit_CPTRA_WDT_CFG[1] = (soc_ifc_reg_req_data.addr == full_addr_CPTRA_WDT_CFG[1][18-1:0]); + assign bus_CPTRA_WDT_CFG[1] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_CPTRA_WDT_CFG[1]}}; + + assign hit_CPTRA_iTRNG_ENTROPY_CONFIG_0 = (soc_ifc_reg_req_data.addr == full_addr_CPTRA_iTRNG_ENTROPY_CONFIG_0[AXI_ADDR_WIDTH-1:0]); + assign bus_CPTRA_iTRNG_ENTROPY_CONFIG_0 = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_CPTRA_iTRNG_ENTROPY_CONFIG_0}}; + + assign hit_CPTRA_iTRNG_ENTROPY_CONFIG_1 = (soc_ifc_reg_req_data.addr == full_addr_CPTRA_iTRNG_ENTROPY_CONFIG_1[AXI_ADDR_WIDTH-1:0]); + assign bus_CPTRA_iTRNG_ENTROPY_CONFIG_1 = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_CPTRA_iTRNG_ENTROPY_CONFIG_1}}; + + assign hit_CPTRA_RSVD_REG[0] = (soc_ifc_reg_req_data.addr == full_addr_CPTRA_RSVD_REG[0][18-1:0]); + assign bus_CPTRA_RSVD_REG[0] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_CPTRA_RSVD_REG[0]}}; + + assign hit_CPTRA_RSVD_REG[1] = (soc_ifc_reg_req_data.addr == full_addr_CPTRA_RSVD_REG[1][18-1:0]); + assign bus_CPTRA_RSVD_REG[1] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_CPTRA_RSVD_REG[1]}}; + + assign hit_CPTRA_HW_CAPABILITIES = (soc_ifc_reg_req_data.addr == full_addr_CPTRA_HW_CAPABILITIES[AXI_ADDR_WIDTH-1:0]); + assign bus_CPTRA_HW_CAPABILITIES = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_CPTRA_HW_CAPABILITIES}}; + + assign hit_CPTRA_FW_CAPABILITIES = (soc_ifc_reg_req_data.addr == full_addr_CPTRA_FW_CAPABILITIES[AXI_ADDR_WIDTH-1:0]); + assign bus_CPTRA_FW_CAPABILITIES = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_CPTRA_FW_CAPABILITIES}}; + + assign hit_CPTRA_CAP_LOCK = (soc_ifc_reg_req_data.addr == full_addr_CPTRA_CAP_LOCK[AXI_ADDR_WIDTH-1:0]); + assign bus_CPTRA_CAP_LOCK = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_CPTRA_CAP_LOCK}}; + + assign hit_CPTRA_OWNER_PK_HASH[0] = (soc_ifc_reg_req_data.addr == full_addr_CPTRA_OWNER_PK_HASH[0][18-1:0]); + assign bus_CPTRA_OWNER_PK_HASH[0] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_CPTRA_OWNER_PK_HASH[0]}}; + + assign hit_CPTRA_OWNER_PK_HASH[1] = (soc_ifc_reg_req_data.addr == full_addr_CPTRA_OWNER_PK_HASH[1][18-1:0]); + assign bus_CPTRA_OWNER_PK_HASH[1] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_CPTRA_OWNER_PK_HASH[1]}}; + + assign hit_CPTRA_OWNER_PK_HASH[2] = (soc_ifc_reg_req_data.addr == full_addr_CPTRA_OWNER_PK_HASH[2][18-1:0]); + assign bus_CPTRA_OWNER_PK_HASH[2] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_CPTRA_OWNER_PK_HASH[2]}}; + + assign hit_CPTRA_OWNER_PK_HASH[3] = (soc_ifc_reg_req_data.addr == full_addr_CPTRA_OWNER_PK_HASH[3][18-1:0]); + assign bus_CPTRA_OWNER_PK_HASH[3] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_CPTRA_OWNER_PK_HASH[3]}}; + + assign hit_CPTRA_OWNER_PK_HASH[4] = (soc_ifc_reg_req_data.addr == full_addr_CPTRA_OWNER_PK_HASH[4][18-1:0]); + assign bus_CPTRA_OWNER_PK_HASH[4] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_CPTRA_OWNER_PK_HASH[4]}}; + + assign hit_CPTRA_OWNER_PK_HASH[5] = (soc_ifc_reg_req_data.addr == full_addr_CPTRA_OWNER_PK_HASH[5][18-1:0]); + assign bus_CPTRA_OWNER_PK_HASH[5] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_CPTRA_OWNER_PK_HASH[5]}}; + + assign hit_CPTRA_OWNER_PK_HASH[6] = (soc_ifc_reg_req_data.addr == full_addr_CPTRA_OWNER_PK_HASH[6][18-1:0]); + assign bus_CPTRA_OWNER_PK_HASH[6] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_CPTRA_OWNER_PK_HASH[6]}}; + + assign hit_CPTRA_OWNER_PK_HASH[7] = (soc_ifc_reg_req_data.addr == full_addr_CPTRA_OWNER_PK_HASH[7][18-1:0]); + assign bus_CPTRA_OWNER_PK_HASH[7] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_CPTRA_OWNER_PK_HASH[7]}}; + + assign hit_CPTRA_OWNER_PK_HASH[8] = (soc_ifc_reg_req_data.addr == full_addr_CPTRA_OWNER_PK_HASH[8][18-1:0]); + assign bus_CPTRA_OWNER_PK_HASH[8] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_CPTRA_OWNER_PK_HASH[8]}}; + + assign hit_CPTRA_OWNER_PK_HASH[9] = (soc_ifc_reg_req_data.addr == full_addr_CPTRA_OWNER_PK_HASH[9][18-1:0]); + assign bus_CPTRA_OWNER_PK_HASH[9] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_CPTRA_OWNER_PK_HASH[9]}}; + + assign hit_CPTRA_OWNER_PK_HASH[10] = (soc_ifc_reg_req_data.addr == full_addr_CPTRA_OWNER_PK_HASH[10][18-1:0]); + assign bus_CPTRA_OWNER_PK_HASH[10] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_CPTRA_OWNER_PK_HASH[10]}}; + + assign hit_CPTRA_OWNER_PK_HASH[11] = (soc_ifc_reg_req_data.addr == full_addr_CPTRA_OWNER_PK_HASH[11][18-1:0]); + assign bus_CPTRA_OWNER_PK_HASH[11] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_CPTRA_OWNER_PK_HASH[11]}}; + + assign hit_CPTRA_OWNER_PK_HASH_LOCK = (soc_ifc_reg_req_data.addr == full_addr_CPTRA_OWNER_PK_HASH_LOCK[AXI_ADDR_WIDTH-1:0]); + assign bus_CPTRA_OWNER_PK_HASH_LOCK = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_CPTRA_OWNER_PK_HASH_LOCK}}; + + assign hit_fuse_uds_seed[0] = (soc_ifc_reg_req_data.addr == full_addr_fuse_uds_seed[0][18-1:0]); + assign bus_fuse_uds_seed[0] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_uds_seed[0]}}; + + assign hit_fuse_uds_seed[1] = (soc_ifc_reg_req_data.addr == full_addr_fuse_uds_seed[1][18-1:0]); + assign bus_fuse_uds_seed[1] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_uds_seed[1]}}; + + assign hit_fuse_uds_seed[2] = (soc_ifc_reg_req_data.addr == full_addr_fuse_uds_seed[2][18-1:0]); + assign bus_fuse_uds_seed[2] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_uds_seed[2]}}; + + assign hit_fuse_uds_seed[3] = (soc_ifc_reg_req_data.addr == full_addr_fuse_uds_seed[3][18-1:0]); + assign bus_fuse_uds_seed[3] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_uds_seed[3]}}; + + assign hit_fuse_uds_seed[4] = (soc_ifc_reg_req_data.addr == full_addr_fuse_uds_seed[4][18-1:0]); + assign bus_fuse_uds_seed[4] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_uds_seed[4]}}; + + assign hit_fuse_uds_seed[5] = (soc_ifc_reg_req_data.addr == full_addr_fuse_uds_seed[5][18-1:0]); + assign bus_fuse_uds_seed[5] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_uds_seed[5]}}; + + assign hit_fuse_uds_seed[6] = (soc_ifc_reg_req_data.addr == full_addr_fuse_uds_seed[6][18-1:0]); + assign bus_fuse_uds_seed[6] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_uds_seed[6]}}; + + assign hit_fuse_uds_seed[7] = (soc_ifc_reg_req_data.addr == full_addr_fuse_uds_seed[7][18-1:0]); + assign bus_fuse_uds_seed[7] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_uds_seed[7]}}; + + assign hit_fuse_uds_seed[8] = (soc_ifc_reg_req_data.addr == full_addr_fuse_uds_seed[8][18-1:0]); + assign bus_fuse_uds_seed[8] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_uds_seed[8]}}; + + assign hit_fuse_uds_seed[9] = (soc_ifc_reg_req_data.addr == full_addr_fuse_uds_seed[9][18-1:0]); + assign bus_fuse_uds_seed[9] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_uds_seed[9]}}; + + assign hit_fuse_uds_seed[10] = (soc_ifc_reg_req_data.addr == full_addr_fuse_uds_seed[10][18-1:0]); + assign bus_fuse_uds_seed[10] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_uds_seed[10]}}; + + assign hit_fuse_uds_seed[11] = (soc_ifc_reg_req_data.addr == full_addr_fuse_uds_seed[11][18-1:0]); + assign bus_fuse_uds_seed[11] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_uds_seed[11]}}; + + assign hit_fuse_uds_seed[12] = (soc_ifc_reg_req_data.addr == full_addr_fuse_uds_seed[12][18-1:0]); + assign bus_fuse_uds_seed[12] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_uds_seed[12]}}; + + assign hit_fuse_uds_seed[13] = (soc_ifc_reg_req_data.addr == full_addr_fuse_uds_seed[13][18-1:0]); + assign bus_fuse_uds_seed[13] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_uds_seed[13]}}; + + assign hit_fuse_uds_seed[14] = (soc_ifc_reg_req_data.addr == full_addr_fuse_uds_seed[14][18-1:0]); + assign bus_fuse_uds_seed[14] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_uds_seed[14]}}; + + assign hit_fuse_uds_seed[15] = (soc_ifc_reg_req_data.addr == full_addr_fuse_uds_seed[15][18-1:0]); + assign bus_fuse_uds_seed[15] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_uds_seed[15]}}; + + assign hit_fuse_field_entropy[0] = (soc_ifc_reg_req_data.addr == full_addr_fuse_field_entropy[0][18-1:0]); + assign bus_fuse_field_entropy[0] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_field_entropy[0]}}; + + assign hit_fuse_field_entropy[1] = (soc_ifc_reg_req_data.addr == full_addr_fuse_field_entropy[1][18-1:0]); + assign bus_fuse_field_entropy[1] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_field_entropy[1]}}; + + assign hit_fuse_field_entropy[2] = (soc_ifc_reg_req_data.addr == full_addr_fuse_field_entropy[2][18-1:0]); + assign bus_fuse_field_entropy[2] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_field_entropy[2]}}; + + assign hit_fuse_field_entropy[3] = (soc_ifc_reg_req_data.addr == full_addr_fuse_field_entropy[3][18-1:0]); + assign bus_fuse_field_entropy[3] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_field_entropy[3]}}; + + assign hit_fuse_field_entropy[4] = (soc_ifc_reg_req_data.addr == full_addr_fuse_field_entropy[4][18-1:0]); + assign bus_fuse_field_entropy[4] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_field_entropy[4]}}; + + assign hit_fuse_field_entropy[5] = (soc_ifc_reg_req_data.addr == full_addr_fuse_field_entropy[5][18-1:0]); + assign bus_fuse_field_entropy[5] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_field_entropy[5]}}; + + assign hit_fuse_field_entropy[6] = (soc_ifc_reg_req_data.addr == full_addr_fuse_field_entropy[6][18-1:0]); + assign bus_fuse_field_entropy[6] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_field_entropy[6]}}; + + assign hit_fuse_field_entropy[7] = (soc_ifc_reg_req_data.addr == full_addr_fuse_field_entropy[7][18-1:0]); + assign bus_fuse_field_entropy[7] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_field_entropy[7]}}; + + assign hit_fuse_vendor_pk_hash[0] = (soc_ifc_reg_req_data.addr == full_addr_fuse_vendor_pk_hash[0][18-1:0]); + assign bus_fuse_vendor_pk_hash[0] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_vendor_pk_hash[0]}}; + + assign hit_fuse_vendor_pk_hash[1] = (soc_ifc_reg_req_data.addr == full_addr_fuse_vendor_pk_hash[1][18-1:0]); + assign bus_fuse_vendor_pk_hash[1] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_vendor_pk_hash[1]}}; + + assign hit_fuse_vendor_pk_hash[2] = (soc_ifc_reg_req_data.addr == full_addr_fuse_vendor_pk_hash[2][18-1:0]); + assign bus_fuse_vendor_pk_hash[2] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_vendor_pk_hash[2]}}; + + assign hit_fuse_vendor_pk_hash[3] = (soc_ifc_reg_req_data.addr == full_addr_fuse_vendor_pk_hash[3][18-1:0]); + assign bus_fuse_vendor_pk_hash[3] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_vendor_pk_hash[3]}}; + + assign hit_fuse_vendor_pk_hash[4] = (soc_ifc_reg_req_data.addr == full_addr_fuse_vendor_pk_hash[4][18-1:0]); + assign bus_fuse_vendor_pk_hash[4] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_vendor_pk_hash[4]}}; + + assign hit_fuse_vendor_pk_hash[5] = (soc_ifc_reg_req_data.addr == full_addr_fuse_vendor_pk_hash[5][18-1:0]); + assign bus_fuse_vendor_pk_hash[5] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_vendor_pk_hash[5]}}; + + assign hit_fuse_vendor_pk_hash[6] = (soc_ifc_reg_req_data.addr == full_addr_fuse_vendor_pk_hash[6][18-1:0]); + assign bus_fuse_vendor_pk_hash[6] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_vendor_pk_hash[6]}}; + + assign hit_fuse_vendor_pk_hash[7] = (soc_ifc_reg_req_data.addr == full_addr_fuse_vendor_pk_hash[7][18-1:0]); + assign bus_fuse_vendor_pk_hash[7] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_vendor_pk_hash[7]}}; + + assign hit_fuse_vendor_pk_hash[8] = (soc_ifc_reg_req_data.addr == full_addr_fuse_vendor_pk_hash[8][18-1:0]); + assign bus_fuse_vendor_pk_hash[8] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_vendor_pk_hash[8]}}; + + assign hit_fuse_vendor_pk_hash[9] = (soc_ifc_reg_req_data.addr == full_addr_fuse_vendor_pk_hash[9][18-1:0]); + assign bus_fuse_vendor_pk_hash[9] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_vendor_pk_hash[9]}}; + + assign hit_fuse_vendor_pk_hash[10] = (soc_ifc_reg_req_data.addr == full_addr_fuse_vendor_pk_hash[10][18-1:0]); + assign bus_fuse_vendor_pk_hash[10] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_vendor_pk_hash[10]}}; + + assign hit_fuse_vendor_pk_hash[11] = (soc_ifc_reg_req_data.addr == full_addr_fuse_vendor_pk_hash[11][18-1:0]); + assign bus_fuse_vendor_pk_hash[11] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_vendor_pk_hash[11]}}; + + assign hit_fuse_ecc_revocation = (soc_ifc_reg_req_data.addr == full_addr_fuse_ecc_revocation[AXI_ADDR_WIDTH-1:0]); + assign bus_fuse_ecc_revocation = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_ecc_revocation}}; + + assign hit_fuse_fmc_key_manifest_svn = (soc_ifc_reg_req_data.addr == full_addr_fuse_fmc_key_manifest_svn[AXI_ADDR_WIDTH-1:0]); + assign bus_fuse_fmc_key_manifest_svn = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_fmc_key_manifest_svn}}; + + assign hit_fuse_runtime_svn[0] = (soc_ifc_reg_req_data.addr == full_addr_fuse_runtime_svn[0][18-1:0]); + assign bus_fuse_runtime_svn[0] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_runtime_svn[0]}}; + + assign hit_fuse_runtime_svn[1] = (soc_ifc_reg_req_data.addr == full_addr_fuse_runtime_svn[1][18-1:0]); + assign bus_fuse_runtime_svn[1] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_runtime_svn[1]}}; + + assign hit_fuse_runtime_svn[2] = (soc_ifc_reg_req_data.addr == full_addr_fuse_runtime_svn[2][18-1:0]); + assign bus_fuse_runtime_svn[2] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_runtime_svn[2]}}; + + assign hit_fuse_runtime_svn[3] = (soc_ifc_reg_req_data.addr == full_addr_fuse_runtime_svn[3][18-1:0]); + assign bus_fuse_runtime_svn[3] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_runtime_svn[3]}}; + + assign hit_fuse_anti_rollback_disable = (soc_ifc_reg_req_data.addr == full_addr_fuse_anti_rollback_disable[AXI_ADDR_WIDTH-1:0]); + assign bus_fuse_anti_rollback_disable = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_anti_rollback_disable}}; + + assign hit_fuse_idevid_cert_attr[0] = (soc_ifc_reg_req_data.addr == full_addr_fuse_idevid_cert_attr[0][18-1:0]); + assign bus_fuse_idevid_cert_attr[0] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_idevid_cert_attr[0]}}; + + assign hit_fuse_idevid_cert_attr[1] = (soc_ifc_reg_req_data.addr == full_addr_fuse_idevid_cert_attr[1][18-1:0]); + assign bus_fuse_idevid_cert_attr[1] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_idevid_cert_attr[1]}}; + + assign hit_fuse_idevid_cert_attr[2] = (soc_ifc_reg_req_data.addr == full_addr_fuse_idevid_cert_attr[2][18-1:0]); + assign bus_fuse_idevid_cert_attr[2] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_idevid_cert_attr[2]}}; + + assign hit_fuse_idevid_cert_attr[3] = (soc_ifc_reg_req_data.addr == full_addr_fuse_idevid_cert_attr[3][18-1:0]); + assign bus_fuse_idevid_cert_attr[3] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_idevid_cert_attr[3]}}; + + assign hit_fuse_idevid_cert_attr[4] = (soc_ifc_reg_req_data.addr == full_addr_fuse_idevid_cert_attr[4][18-1:0]); + assign bus_fuse_idevid_cert_attr[4] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_idevid_cert_attr[4]}}; + + assign hit_fuse_idevid_cert_attr[5] = (soc_ifc_reg_req_data.addr == full_addr_fuse_idevid_cert_attr[5][18-1:0]); + assign bus_fuse_idevid_cert_attr[5] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_idevid_cert_attr[5]}}; + + assign hit_fuse_idevid_cert_attr[6] = (soc_ifc_reg_req_data.addr == full_addr_fuse_idevid_cert_attr[6][18-1:0]); + assign bus_fuse_idevid_cert_attr[6] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_idevid_cert_attr[6]}}; + + assign hit_fuse_idevid_cert_attr[7] = (soc_ifc_reg_req_data.addr == full_addr_fuse_idevid_cert_attr[7][18-1:0]); + assign bus_fuse_idevid_cert_attr[7] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_idevid_cert_attr[7]}}; + + assign hit_fuse_idevid_cert_attr[8] = (soc_ifc_reg_req_data.addr == full_addr_fuse_idevid_cert_attr[8][18-1:0]); + assign bus_fuse_idevid_cert_attr[8] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_idevid_cert_attr[8]}}; + + assign hit_fuse_idevid_cert_attr[9] = (soc_ifc_reg_req_data.addr == full_addr_fuse_idevid_cert_attr[9][18-1:0]); + assign bus_fuse_idevid_cert_attr[9] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_idevid_cert_attr[9]}}; + + assign hit_fuse_idevid_cert_attr[10] = (soc_ifc_reg_req_data.addr == full_addr_fuse_idevid_cert_attr[10][18-1:0]); + assign bus_fuse_idevid_cert_attr[10] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_idevid_cert_attr[10]}}; + + assign hit_fuse_idevid_cert_attr[11] = (soc_ifc_reg_req_data.addr == full_addr_fuse_idevid_cert_attr[11][18-1:0]); + assign bus_fuse_idevid_cert_attr[11] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_idevid_cert_attr[11]}}; + + assign hit_fuse_idevid_cert_attr[12] = (soc_ifc_reg_req_data.addr == full_addr_fuse_idevid_cert_attr[12][18-1:0]); + assign bus_fuse_idevid_cert_attr[12] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_idevid_cert_attr[12]}}; + + assign hit_fuse_idevid_cert_attr[13] = (soc_ifc_reg_req_data.addr == full_addr_fuse_idevid_cert_attr[13][18-1:0]); + assign bus_fuse_idevid_cert_attr[13] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_idevid_cert_attr[13]}}; + + assign hit_fuse_idevid_cert_attr[14] = (soc_ifc_reg_req_data.addr == full_addr_fuse_idevid_cert_attr[14][18-1:0]); + assign bus_fuse_idevid_cert_attr[14] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_idevid_cert_attr[14]}}; + + assign hit_fuse_idevid_cert_attr[15] = (soc_ifc_reg_req_data.addr == full_addr_fuse_idevid_cert_attr[15][18-1:0]); + assign bus_fuse_idevid_cert_attr[15] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_idevid_cert_attr[15]}}; + + assign hit_fuse_idevid_cert_attr[16] = (soc_ifc_reg_req_data.addr == full_addr_fuse_idevid_cert_attr[16][18-1:0]); + assign bus_fuse_idevid_cert_attr[16] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_idevid_cert_attr[16]}}; + + assign hit_fuse_idevid_cert_attr[17] = (soc_ifc_reg_req_data.addr == full_addr_fuse_idevid_cert_attr[17][18-1:0]); + assign bus_fuse_idevid_cert_attr[17] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_idevid_cert_attr[17]}}; + + assign hit_fuse_idevid_cert_attr[18] = (soc_ifc_reg_req_data.addr == full_addr_fuse_idevid_cert_attr[18][18-1:0]); + assign bus_fuse_idevid_cert_attr[18] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_idevid_cert_attr[18]}}; + + assign hit_fuse_idevid_cert_attr[19] = (soc_ifc_reg_req_data.addr == full_addr_fuse_idevid_cert_attr[19][18-1:0]); + assign bus_fuse_idevid_cert_attr[19] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_idevid_cert_attr[19]}}; + + assign hit_fuse_idevid_cert_attr[20] = (soc_ifc_reg_req_data.addr == full_addr_fuse_idevid_cert_attr[20][18-1:0]); + assign bus_fuse_idevid_cert_attr[20] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_idevid_cert_attr[20]}}; + + assign hit_fuse_idevid_cert_attr[21] = (soc_ifc_reg_req_data.addr == full_addr_fuse_idevid_cert_attr[21][18-1:0]); + assign bus_fuse_idevid_cert_attr[21] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_idevid_cert_attr[21]}}; + + assign hit_fuse_idevid_cert_attr[22] = (soc_ifc_reg_req_data.addr == full_addr_fuse_idevid_cert_attr[22][18-1:0]); + assign bus_fuse_idevid_cert_attr[22] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_idevid_cert_attr[22]}}; + + assign hit_fuse_idevid_cert_attr[23] = (soc_ifc_reg_req_data.addr == full_addr_fuse_idevid_cert_attr[23][18-1:0]); + assign bus_fuse_idevid_cert_attr[23] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_idevid_cert_attr[23]}}; + + assign hit_fuse_idevid_manuf_hsm_id[0] = (soc_ifc_reg_req_data.addr == full_addr_fuse_idevid_manuf_hsm_id[0][18-1:0]); + assign bus_fuse_idevid_manuf_hsm_id[0] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_idevid_manuf_hsm_id[0]}}; + + assign hit_fuse_idevid_manuf_hsm_id[1] = (soc_ifc_reg_req_data.addr == full_addr_fuse_idevid_manuf_hsm_id[1][18-1:0]); + assign bus_fuse_idevid_manuf_hsm_id[1] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_idevid_manuf_hsm_id[1]}}; + + assign hit_fuse_idevid_manuf_hsm_id[2] = (soc_ifc_reg_req_data.addr == full_addr_fuse_idevid_manuf_hsm_id[2][18-1:0]); + assign bus_fuse_idevid_manuf_hsm_id[2] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_idevid_manuf_hsm_id[2]}}; + + assign hit_fuse_idevid_manuf_hsm_id[3] = (soc_ifc_reg_req_data.addr == full_addr_fuse_idevid_manuf_hsm_id[3][18-1:0]); + assign bus_fuse_idevid_manuf_hsm_id[3] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_idevid_manuf_hsm_id[3]}}; + + assign hit_fuse_lms_revocation = (soc_ifc_reg_req_data.addr == full_addr_fuse_lms_revocation[AXI_ADDR_WIDTH-1:0]); + assign bus_fuse_lms_revocation = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_lms_revocation}}; + + assign hit_fuse_mldsa_revocation = (soc_ifc_reg_req_data.addr == full_addr_fuse_mldsa_revocation[AXI_ADDR_WIDTH-1:0]); + assign bus_fuse_mldsa_revocation = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_mldsa_revocation}}; + + assign hit_fuse_soc_stepping_id = (soc_ifc_reg_req_data.addr == full_addr_fuse_soc_stepping_id[AXI_ADDR_WIDTH-1:0]); + assign bus_fuse_soc_stepping_id = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_soc_stepping_id}}; + + assign hit_fuse_manuf_dbg_unlock_token[0] = (soc_ifc_reg_req_data.addr == full_addr_fuse_manuf_dbg_unlock_token[0][18-1:0]); + assign bus_fuse_manuf_dbg_unlock_token[0] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_manuf_dbg_unlock_token[0]}}; + + assign hit_fuse_manuf_dbg_unlock_token[1] = (soc_ifc_reg_req_data.addr == full_addr_fuse_manuf_dbg_unlock_token[1][18-1:0]); + assign bus_fuse_manuf_dbg_unlock_token[1] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_manuf_dbg_unlock_token[1]}}; + + assign hit_fuse_manuf_dbg_unlock_token[2] = (soc_ifc_reg_req_data.addr == full_addr_fuse_manuf_dbg_unlock_token[2][18-1:0]); + assign bus_fuse_manuf_dbg_unlock_token[2] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_manuf_dbg_unlock_token[2]}}; + + assign hit_fuse_manuf_dbg_unlock_token[3] = (soc_ifc_reg_req_data.addr == full_addr_fuse_manuf_dbg_unlock_token[3][18-1:0]); + assign bus_fuse_manuf_dbg_unlock_token[3] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_manuf_dbg_unlock_token[3]}}; + + assign hit_fuse_manuf_dbg_unlock_token[4] = (soc_ifc_reg_req_data.addr == full_addr_fuse_manuf_dbg_unlock_token[4][18-1:0]); + assign bus_fuse_manuf_dbg_unlock_token[4] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_manuf_dbg_unlock_token[4]}}; + + assign hit_fuse_manuf_dbg_unlock_token[5] = (soc_ifc_reg_req_data.addr == full_addr_fuse_manuf_dbg_unlock_token[5][18-1:0]); + assign bus_fuse_manuf_dbg_unlock_token[5] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_manuf_dbg_unlock_token[5]}}; + + assign hit_fuse_manuf_dbg_unlock_token[6] = (soc_ifc_reg_req_data.addr == full_addr_fuse_manuf_dbg_unlock_token[6][18-1:0]); + assign bus_fuse_manuf_dbg_unlock_token[6] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_manuf_dbg_unlock_token[6]}}; + + assign hit_fuse_manuf_dbg_unlock_token[7] = (soc_ifc_reg_req_data.addr == full_addr_fuse_manuf_dbg_unlock_token[7][18-1:0]); + assign bus_fuse_manuf_dbg_unlock_token[7] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_manuf_dbg_unlock_token[7]}}; + + assign hit_fuse_manuf_dbg_unlock_token[8] = (soc_ifc_reg_req_data.addr == full_addr_fuse_manuf_dbg_unlock_token[8][18-1:0]); + assign bus_fuse_manuf_dbg_unlock_token[8] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_manuf_dbg_unlock_token[8]}}; + + assign hit_fuse_manuf_dbg_unlock_token[9] = (soc_ifc_reg_req_data.addr == full_addr_fuse_manuf_dbg_unlock_token[9][18-1:0]); + assign bus_fuse_manuf_dbg_unlock_token[9] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_manuf_dbg_unlock_token[9]}}; + + assign hit_fuse_manuf_dbg_unlock_token[10] = (soc_ifc_reg_req_data.addr == full_addr_fuse_manuf_dbg_unlock_token[10][18-1:0]); + assign bus_fuse_manuf_dbg_unlock_token[10] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_manuf_dbg_unlock_token[10]}}; + + assign hit_fuse_manuf_dbg_unlock_token[11] = (soc_ifc_reg_req_data.addr == full_addr_fuse_manuf_dbg_unlock_token[11][18-1:0]); + assign bus_fuse_manuf_dbg_unlock_token[11] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_manuf_dbg_unlock_token[11]}}; + + assign hit_fuse_manuf_dbg_unlock_token[12] = (soc_ifc_reg_req_data.addr == full_addr_fuse_manuf_dbg_unlock_token[12][18-1:0]); + assign bus_fuse_manuf_dbg_unlock_token[12] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_manuf_dbg_unlock_token[12]}}; + + assign hit_fuse_manuf_dbg_unlock_token[13] = (soc_ifc_reg_req_data.addr == full_addr_fuse_manuf_dbg_unlock_token[13][18-1:0]); + assign bus_fuse_manuf_dbg_unlock_token[13] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_manuf_dbg_unlock_token[13]}}; + + assign hit_fuse_manuf_dbg_unlock_token[14] = (soc_ifc_reg_req_data.addr == full_addr_fuse_manuf_dbg_unlock_token[14][18-1:0]); + assign bus_fuse_manuf_dbg_unlock_token[14] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_manuf_dbg_unlock_token[14]}}; + + assign hit_fuse_manuf_dbg_unlock_token[15] = (soc_ifc_reg_req_data.addr == full_addr_fuse_manuf_dbg_unlock_token[15][18-1:0]); + assign bus_fuse_manuf_dbg_unlock_token[15] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_manuf_dbg_unlock_token[15]}}; + + assign hit_fuse_pqc_key_type = (soc_ifc_reg_req_data.addr == full_addr_fuse_pqc_key_type[AXI_ADDR_WIDTH-1:0]); + assign bus_fuse_pqc_key_type = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_pqc_key_type}}; + + assign hit_fuse_soc_manifest_svn[0] = (soc_ifc_reg_req_data.addr == full_addr_fuse_soc_manifest_svn[0][18-1:0]); + assign bus_fuse_soc_manifest_svn[0] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_soc_manifest_svn[0]}}; + + assign hit_fuse_soc_manifest_svn[1] = (soc_ifc_reg_req_data.addr == full_addr_fuse_soc_manifest_svn[1][18-1:0]); + assign bus_fuse_soc_manifest_svn[1] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_soc_manifest_svn[1]}}; + + assign hit_fuse_soc_manifest_svn[2] = (soc_ifc_reg_req_data.addr == full_addr_fuse_soc_manifest_svn[2][18-1:0]); + assign bus_fuse_soc_manifest_svn[2] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_soc_manifest_svn[2]}}; + + assign hit_fuse_soc_manifest_svn[3] = (soc_ifc_reg_req_data.addr == full_addr_fuse_soc_manifest_svn[3][18-1:0]); + assign bus_fuse_soc_manifest_svn[3] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_soc_manifest_svn[3]}}; + + assign hit_fuse_soc_manifest_max_svn = (soc_ifc_reg_req_data.addr == full_addr_fuse_soc_manifest_max_svn[AXI_ADDR_WIDTH-1:0]); + assign bus_fuse_soc_manifest_max_svn = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_soc_manifest_max_svn}}; + + assign hit_fuse_hek_seed[0] = (soc_ifc_reg_req_data.addr == full_addr_fuse_hek_seed[0][18-1:0]); + assign bus_fuse_hek_seed[0] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_hek_seed[0]}}; + + assign hit_fuse_hek_seed[1] = (soc_ifc_reg_req_data.addr == full_addr_fuse_hek_seed[1][18-1:0]); + assign bus_fuse_hek_seed[1] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_hek_seed[1]}}; + + assign hit_fuse_hek_seed[2] = (soc_ifc_reg_req_data.addr == full_addr_fuse_hek_seed[2][18-1:0]); + assign bus_fuse_hek_seed[2] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_hek_seed[2]}}; + + assign hit_fuse_hek_seed[3] = (soc_ifc_reg_req_data.addr == full_addr_fuse_hek_seed[3][18-1:0]); + assign bus_fuse_hek_seed[3] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_hek_seed[3]}}; + + assign hit_fuse_hek_seed[4] = (soc_ifc_reg_req_data.addr == full_addr_fuse_hek_seed[4][18-1:0]); + assign bus_fuse_hek_seed[4] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_hek_seed[4]}}; + + assign hit_fuse_hek_seed[5] = (soc_ifc_reg_req_data.addr == full_addr_fuse_hek_seed[5][18-1:0]); + assign bus_fuse_hek_seed[5] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_hek_seed[5]}}; + + assign hit_fuse_hek_seed[6] = (soc_ifc_reg_req_data.addr == full_addr_fuse_hek_seed[6][18-1:0]); + assign bus_fuse_hek_seed[6] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_hek_seed[6]}}; + + assign hit_fuse_hek_seed[7] = (soc_ifc_reg_req_data.addr == full_addr_fuse_hek_seed[7][18-1:0]); + assign bus_fuse_hek_seed[7] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_fuse_hek_seed[7]}}; + + assign hit_SS_CALIPTRA_BASE_ADDR_L = (soc_ifc_reg_req_data.addr == full_addr_SS_CALIPTRA_BASE_ADDR_L[AXI_ADDR_WIDTH-1:0]); + assign bus_SS_CALIPTRA_BASE_ADDR_L = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_SS_CALIPTRA_BASE_ADDR_L}}; + + assign hit_SS_CALIPTRA_BASE_ADDR_H = (soc_ifc_reg_req_data.addr == full_addr_SS_CALIPTRA_BASE_ADDR_H[AXI_ADDR_WIDTH-1:0]); + assign bus_SS_CALIPTRA_BASE_ADDR_H = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_SS_CALIPTRA_BASE_ADDR_H}}; + + assign hit_SS_MCI_BASE_ADDR_L = (soc_ifc_reg_req_data.addr == full_addr_SS_MCI_BASE_ADDR_L[AXI_ADDR_WIDTH-1:0]); + assign bus_SS_MCI_BASE_ADDR_L = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_SS_MCI_BASE_ADDR_L}}; + + assign hit_SS_MCI_BASE_ADDR_H = (soc_ifc_reg_req_data.addr == full_addr_SS_MCI_BASE_ADDR_H[AXI_ADDR_WIDTH-1:0]); + assign bus_SS_MCI_BASE_ADDR_H = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_SS_MCI_BASE_ADDR_H}}; + + assign hit_SS_RECOVERY_IFC_BASE_ADDR_L = (soc_ifc_reg_req_data.addr == full_addr_SS_RECOVERY_IFC_BASE_ADDR_L[AXI_ADDR_WIDTH-1:0]); + assign bus_SS_RECOVERY_IFC_BASE_ADDR_L = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_SS_RECOVERY_IFC_BASE_ADDR_L}}; + + assign hit_SS_RECOVERY_IFC_BASE_ADDR_H = (soc_ifc_reg_req_data.addr == full_addr_SS_RECOVERY_IFC_BASE_ADDR_H[AXI_ADDR_WIDTH-1:0]); + assign bus_SS_RECOVERY_IFC_BASE_ADDR_H = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_SS_RECOVERY_IFC_BASE_ADDR_H}}; + + assign hit_SS_OTP_FC_BASE_ADDR_L = (soc_ifc_reg_req_data.addr == full_addr_SS_OTP_FC_BASE_ADDR_L[AXI_ADDR_WIDTH-1:0]); + assign bus_SS_OTP_FC_BASE_ADDR_L = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_SS_OTP_FC_BASE_ADDR_L}}; + + assign hit_SS_OTP_FC_BASE_ADDR_H = (soc_ifc_reg_req_data.addr == full_addr_SS_OTP_FC_BASE_ADDR_H[AXI_ADDR_WIDTH-1:0]); + assign bus_SS_OTP_FC_BASE_ADDR_H = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_SS_OTP_FC_BASE_ADDR_H}}; + + assign hit_SS_UDS_SEED_BASE_ADDR_L = (soc_ifc_reg_req_data.addr == full_addr_SS_UDS_SEED_BASE_ADDR_L[AXI_ADDR_WIDTH-1:0]); + assign bus_SS_UDS_SEED_BASE_ADDR_L = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_SS_UDS_SEED_BASE_ADDR_L}}; + + assign hit_SS_UDS_SEED_BASE_ADDR_H = (soc_ifc_reg_req_data.addr == full_addr_SS_UDS_SEED_BASE_ADDR_H[AXI_ADDR_WIDTH-1:0]); + assign bus_SS_UDS_SEED_BASE_ADDR_H = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_SS_UDS_SEED_BASE_ADDR_H}}; + + assign hit_SS_PROD_DEBUG_UNLOCK_AUTH_PK_HASH_REG_BANK_OFFSET = (soc_ifc_reg_req_data.addr == full_addr_SS_PROD_DEBUG_UNLOCK_AUTH_PK_HASH_REG_BANK_OFFSET[AXI_ADDR_WIDTH-1:0]); + assign bus_SS_PROD_DEBUG_UNLOCK_AUTH_PK_HASH_REG_BANK_OFFSET = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_SS_PROD_DEBUG_UNLOCK_AUTH_PK_HASH_REG_BANK_OFFSET}}; + + assign hit_SS_NUM_OF_PROD_DEBUG_UNLOCK_AUTH_PK_HASHES = (soc_ifc_reg_req_data.addr == full_addr_SS_NUM_OF_PROD_DEBUG_UNLOCK_AUTH_PK_HASHES[AXI_ADDR_WIDTH-1:0]); + assign bus_SS_NUM_OF_PROD_DEBUG_UNLOCK_AUTH_PK_HASHES = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_SS_NUM_OF_PROD_DEBUG_UNLOCK_AUTH_PK_HASHES}}; + + assign hit_SS_DEBUG_INTENT = (soc_ifc_reg_req_data.addr == full_addr_SS_DEBUG_INTENT[AXI_ADDR_WIDTH-1:0]); + assign bus_SS_DEBUG_INTENT = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_SS_DEBUG_INTENT}}; + + assign hit_SS_CALIPTRA_DMA_AXI_USER = (soc_ifc_reg_req_data.addr == full_addr_SS_CALIPTRA_DMA_AXI_USER[AXI_ADDR_WIDTH-1:0]); + assign bus_SS_CALIPTRA_DMA_AXI_USER = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_SS_CALIPTRA_DMA_AXI_USER}}; + + assign hit_SS_EXTERNAL_STAGING_AREA_BASE_ADDR_L = (soc_ifc_reg_req_data.addr == full_addr_SS_EXTERNAL_STAGING_AREA_BASE_ADDR_L[AXI_ADDR_WIDTH-1:0]); + assign bus_SS_EXTERNAL_STAGING_AREA_BASE_ADDR_L = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_SS_EXTERNAL_STAGING_AREA_BASE_ADDR_L}}; + + assign hit_SS_EXTERNAL_STAGING_AREA_BASE_ADDR_H = (soc_ifc_reg_req_data.addr == full_addr_SS_EXTERNAL_STAGING_AREA_BASE_ADDR_H[AXI_ADDR_WIDTH-1:0]); + assign bus_SS_EXTERNAL_STAGING_AREA_BASE_ADDR_H = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_SS_EXTERNAL_STAGING_AREA_BASE_ADDR_H}}; + + assign hit_SS_KEY_RELEASE_BASE_ADDR_L = (soc_ifc_reg_req_data.addr == full_addr_SS_KEY_RELEASE_BASE_ADDR_L[AXI_ADDR_WIDTH-1:0]); + assign bus_SS_KEY_RELEASE_BASE_ADDR_L = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_SS_KEY_RELEASE_BASE_ADDR_L}}; + + assign hit_SS_KEY_RELEASE_BASE_ADDR_H = (soc_ifc_reg_req_data.addr == full_addr_SS_KEY_RELEASE_BASE_ADDR_H[AXI_ADDR_WIDTH-1:0]); + assign bus_SS_KEY_RELEASE_BASE_ADDR_H = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_SS_KEY_RELEASE_BASE_ADDR_H}}; + + assign hit_SS_KEY_RELEASE_SIZE = (soc_ifc_reg_req_data.addr == full_addr_SS_KEY_RELEASE_SIZE[AXI_ADDR_WIDTH-1:0]); + assign bus_SS_KEY_RELEASE_SIZE = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_SS_KEY_RELEASE_SIZE}}; + + assign hit_SS_OCP_LOCK_CTRL = (soc_ifc_reg_req_data.addr == full_addr_SS_OCP_LOCK_CTRL[AXI_ADDR_WIDTH-1:0]); + assign bus_SS_OCP_LOCK_CTRL = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_SS_OCP_LOCK_CTRL}}; + + assign hit_SS_STRAP_GENERIC[0] = (soc_ifc_reg_req_data.addr == full_addr_SS_STRAP_GENERIC[0][18-1:0]); + assign bus_SS_STRAP_GENERIC[0] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_SS_STRAP_GENERIC[0]}}; + + assign hit_SS_STRAP_GENERIC[1] = (soc_ifc_reg_req_data.addr == full_addr_SS_STRAP_GENERIC[1][18-1:0]); + assign bus_SS_STRAP_GENERIC[1] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_SS_STRAP_GENERIC[1]}}; + + assign hit_SS_STRAP_GENERIC[2] = (soc_ifc_reg_req_data.addr == full_addr_SS_STRAP_GENERIC[2][18-1:0]); + assign bus_SS_STRAP_GENERIC[2] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_SS_STRAP_GENERIC[2]}}; + + assign hit_SS_STRAP_GENERIC[3] = (soc_ifc_reg_req_data.addr == full_addr_SS_STRAP_GENERIC[3][18-1:0]); + assign bus_SS_STRAP_GENERIC[3] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_SS_STRAP_GENERIC[3]}}; + + assign hit_SS_DBG_SERVICE_REG_REQ = (soc_ifc_reg_req_data.addr == full_addr_SS_DBG_SERVICE_REG_REQ[AXI_ADDR_WIDTH-1:0]); + assign bus_SS_DBG_SERVICE_REG_REQ = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_SS_DBG_SERVICE_REG_REQ}}; + + assign hit_SS_DBG_SERVICE_REG_RSP = (soc_ifc_reg_req_data.addr == full_addr_SS_DBG_SERVICE_REG_RSP[AXI_ADDR_WIDTH-1:0]); + assign bus_SS_DBG_SERVICE_REG_RSP = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_SS_DBG_SERVICE_REG_RSP}}; + + assign hit_SS_SOC_DBG_UNLOCK_LEVEL[0] = (soc_ifc_reg_req_data.addr == full_addr_SS_SOC_DBG_UNLOCK_LEVEL[0][18-1:0]); + assign bus_SS_SOC_DBG_UNLOCK_LEVEL[0] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_SS_SOC_DBG_UNLOCK_LEVEL[0]}}; + + assign hit_SS_SOC_DBG_UNLOCK_LEVEL[1] = (soc_ifc_reg_req_data.addr == full_addr_SS_SOC_DBG_UNLOCK_LEVEL[1][18-1:0]); + assign bus_SS_SOC_DBG_UNLOCK_LEVEL[1] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_SS_SOC_DBG_UNLOCK_LEVEL[1]}}; + + assign hit_SS_GENERIC_FW_EXEC_CTRL[0] = (soc_ifc_reg_req_data.addr == full_addr_SS_GENERIC_FW_EXEC_CTRL[0][18-1:0]); + assign bus_SS_GENERIC_FW_EXEC_CTRL[0] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_SS_GENERIC_FW_EXEC_CTRL[0]}}; + + assign hit_SS_GENERIC_FW_EXEC_CTRL[1] = (soc_ifc_reg_req_data.addr == full_addr_SS_GENERIC_FW_EXEC_CTRL[1][18-1:0]); + assign bus_SS_GENERIC_FW_EXEC_CTRL[1] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_SS_GENERIC_FW_EXEC_CTRL[1]}}; + + assign hit_SS_GENERIC_FW_EXEC_CTRL[2] = (soc_ifc_reg_req_data.addr == full_addr_SS_GENERIC_FW_EXEC_CTRL[2][18-1:0]); + assign bus_SS_GENERIC_FW_EXEC_CTRL[2] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_SS_GENERIC_FW_EXEC_CTRL[2]}}; + + assign hit_SS_GENERIC_FW_EXEC_CTRL[3] = (soc_ifc_reg_req_data.addr == full_addr_SS_GENERIC_FW_EXEC_CTRL[3][18-1:0]); + assign bus_SS_GENERIC_FW_EXEC_CTRL[3] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_SS_GENERIC_FW_EXEC_CTRL[3]}}; + + assign hit_internal_obf_key[0] = (soc_ifc_reg_req_data.addr == full_addr_internal_obf_key[0][18-1:0]); + assign bus_internal_obf_key[0] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_internal_obf_key[0]}}; + + assign hit_internal_obf_key[1] = (soc_ifc_reg_req_data.addr == full_addr_internal_obf_key[1][18-1:0]); + assign bus_internal_obf_key[1] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_internal_obf_key[1]}}; + + assign hit_internal_obf_key[2] = (soc_ifc_reg_req_data.addr == full_addr_internal_obf_key[2][18-1:0]); + assign bus_internal_obf_key[2] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_internal_obf_key[2]}}; + + assign hit_internal_obf_key[3] = (soc_ifc_reg_req_data.addr == full_addr_internal_obf_key[3][18-1:0]); + assign bus_internal_obf_key[3] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_internal_obf_key[3]}}; + + assign hit_internal_obf_key[4] = (soc_ifc_reg_req_data.addr == full_addr_internal_obf_key[4][18-1:0]); + assign bus_internal_obf_key[4] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_internal_obf_key[4]}}; + + assign hit_internal_obf_key[5] = (soc_ifc_reg_req_data.addr == full_addr_internal_obf_key[5][18-1:0]); + assign bus_internal_obf_key[5] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_internal_obf_key[5]}}; + + assign hit_internal_obf_key[6] = (soc_ifc_reg_req_data.addr == full_addr_internal_obf_key[6][18-1:0]); + assign bus_internal_obf_key[6] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_internal_obf_key[6]}}; + + assign hit_internal_obf_key[7] = (soc_ifc_reg_req_data.addr == full_addr_internal_obf_key[7][18-1:0]); + assign bus_internal_obf_key[7] = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_internal_obf_key[7]}}; + + assign hit_internal_iccm_lock = (soc_ifc_reg_req_data.addr == full_addr_internal_iccm_lock[AXI_ADDR_WIDTH-1:0]); + assign bus_internal_iccm_lock = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_internal_iccm_lock}}; + + assign hit_internal_fw_update_reset = (soc_ifc_reg_req_data.addr == full_addr_internal_fw_update_reset[AXI_ADDR_WIDTH-1:0]); + assign bus_internal_fw_update_reset = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_internal_fw_update_reset}}; + + assign hit_internal_fw_update_reset_wait_cycles = (soc_ifc_reg_req_data.addr == full_addr_internal_fw_update_reset_wait_cycles[AXI_ADDR_WIDTH-1:0]); + assign bus_internal_fw_update_reset_wait_cycles = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_internal_fw_update_reset_wait_cycles}}; + + assign hit_internal_nmi_vector = (soc_ifc_reg_req_data.addr == full_addr_internal_nmi_vector[AXI_ADDR_WIDTH-1:0]); + assign bus_internal_nmi_vector = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_internal_nmi_vector}}; + + assign hit_internal_hw_error_fatal_mask = (soc_ifc_reg_req_data.addr == full_addr_internal_hw_error_fatal_mask[AXI_ADDR_WIDTH-1:0]); + assign bus_internal_hw_error_fatal_mask = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_internal_hw_error_fatal_mask}}; + + assign hit_internal_hw_error_non_fatal_mask = (soc_ifc_reg_req_data.addr == full_addr_internal_hw_error_non_fatal_mask[AXI_ADDR_WIDTH-1:0]); + assign bus_internal_hw_error_non_fatal_mask = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_internal_hw_error_non_fatal_mask}}; + + assign hit_internal_fw_error_fatal_mask = (soc_ifc_reg_req_data.addr == full_addr_internal_fw_error_fatal_mask[AXI_ADDR_WIDTH-1:0]); + assign bus_internal_fw_error_fatal_mask = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_internal_fw_error_fatal_mask}}; + + assign hit_internal_fw_error_non_fatal_mask = (soc_ifc_reg_req_data.addr == full_addr_internal_fw_error_non_fatal_mask[AXI_ADDR_WIDTH-1:0]); + assign bus_internal_fw_error_non_fatal_mask = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_internal_fw_error_non_fatal_mask}}; + + assign hit_internal_rv_mtime_l = (soc_ifc_reg_req_data.addr == full_addr_internal_rv_mtime_l[AXI_ADDR_WIDTH-1:0]); + assign bus_internal_rv_mtime_l = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_internal_rv_mtime_l}}; + + assign hit_internal_rv_mtime_h = (soc_ifc_reg_req_data.addr == full_addr_internal_rv_mtime_h[AXI_ADDR_WIDTH-1:0]); + assign bus_internal_rv_mtime_h = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_internal_rv_mtime_h}}; + + assign hit_internal_rv_mtimecmp_l = (soc_ifc_reg_req_data.addr == full_addr_internal_rv_mtimecmp_l[AXI_ADDR_WIDTH-1:0]); + assign bus_internal_rv_mtimecmp_l = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_internal_rv_mtimecmp_l}}; + + assign hit_internal_rv_mtimecmp_h = (soc_ifc_reg_req_data.addr == full_addr_internal_rv_mtimecmp_h[AXI_ADDR_WIDTH-1:0]); + assign bus_internal_rv_mtimecmp_h = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_internal_rv_mtimecmp_h}}; + + assign hit_intr_brf_global_intr_en_r = (soc_ifc_reg_req_data.addr == full_addr_intr_brf_global_intr_en_r[AXI_ADDR_WIDTH-1:0]); + assign bus_intr_brf_global_intr_en_r = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_intr_brf_global_intr_en_r}}; + + assign hit_intr_brf_error_intr_en_r = (soc_ifc_reg_req_data.addr == full_addr_intr_brf_error_intr_en_r[AXI_ADDR_WIDTH-1:0]); + assign bus_intr_brf_error_intr_en_r = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_intr_brf_error_intr_en_r}}; + + assign hit_intr_brf_notif_intr_en_r = (soc_ifc_reg_req_data.addr == full_addr_intr_brf_notif_intr_en_r[AXI_ADDR_WIDTH-1:0]); + assign bus_intr_brf_notif_intr_en_r = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_intr_brf_notif_intr_en_r}}; + + assign hit_intr_brf_error_global_intr_r = (soc_ifc_reg_req_data.addr == full_addr_intr_brf_error_global_intr_r[AXI_ADDR_WIDTH-1:0]); + assign bus_intr_brf_error_global_intr_r = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_intr_brf_error_global_intr_r}}; + + assign hit_intr_brf_notif_global_intr_r = (soc_ifc_reg_req_data.addr == full_addr_intr_brf_notif_global_intr_r[AXI_ADDR_WIDTH-1:0]); + assign bus_intr_brf_notif_global_intr_r = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_intr_brf_notif_global_intr_r}}; + + assign hit_intr_brf_error_internal_intr_r = (soc_ifc_reg_req_data.addr == full_addr_intr_brf_error_internal_intr_r[AXI_ADDR_WIDTH-1:0]); + assign bus_intr_brf_error_internal_intr_r = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_intr_brf_error_internal_intr_r}}; + + assign hit_intr_brf_notif_internal_intr_r = (soc_ifc_reg_req_data.addr == full_addr_intr_brf_notif_internal_intr_r[AXI_ADDR_WIDTH-1:0]); + assign bus_intr_brf_notif_internal_intr_r = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_intr_brf_notif_internal_intr_r}}; + + assign hit_intr_brf_error_intr_trig_r = (soc_ifc_reg_req_data.addr == full_addr_intr_brf_error_intr_trig_r[AXI_ADDR_WIDTH-1:0]); + assign bus_intr_brf_error_intr_trig_r = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_intr_brf_error_intr_trig_r}}; + + assign hit_intr_brf_notif_intr_trig_r = (soc_ifc_reg_req_data.addr == full_addr_intr_brf_notif_intr_trig_r[AXI_ADDR_WIDTH-1:0]); + assign bus_intr_brf_notif_intr_trig_r = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_intr_brf_notif_intr_trig_r}}; + + assign hit_intr_brf_error_internal_intr_count_r = (soc_ifc_reg_req_data.addr == full_addr_intr_brf_error_internal_intr_count_r[AXI_ADDR_WIDTH-1:0]); + assign bus_intr_brf_error_internal_intr_count_r = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_intr_brf_error_internal_intr_count_r}}; + + assign hit_intr_brf_error_inv_dev_intr_count_r = (soc_ifc_reg_req_data.addr == full_addr_intr_brf_error_inv_dev_intr_count_r[AXI_ADDR_WIDTH-1:0]); + assign bus_intr_brf_error_inv_dev_intr_count_r = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_intr_brf_error_inv_dev_intr_count_r}}; + + assign hit_intr_brf_error_cmd_fail_intr_count_r = (soc_ifc_reg_req_data.addr == full_addr_intr_brf_error_cmd_fail_intr_count_r[AXI_ADDR_WIDTH-1:0]); + assign bus_intr_brf_error_cmd_fail_intr_count_r = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_intr_brf_error_cmd_fail_intr_count_r}}; + + assign hit_intr_brf_error_bad_fuse_intr_count_r = (soc_ifc_reg_req_data.addr == full_addr_intr_brf_error_bad_fuse_intr_count_r[AXI_ADDR_WIDTH-1:0]); + assign bus_intr_brf_error_bad_fuse_intr_count_r = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_intr_brf_error_bad_fuse_intr_count_r}}; + + assign hit_intr_brf_error_iccm_blocked_intr_count_r = (soc_ifc_reg_req_data.addr == full_addr_intr_brf_error_iccm_blocked_intr_count_r[AXI_ADDR_WIDTH-1:0]); + assign bus_intr_brf_error_iccm_blocked_intr_count_r = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_intr_brf_error_iccm_blocked_intr_count_r}}; + + assign hit_intr_brf_error_mbox_ecc_unc_intr_count_r = (soc_ifc_reg_req_data.addr == full_addr_intr_brf_error_mbox_ecc_unc_intr_count_r[AXI_ADDR_WIDTH-1:0]); + assign bus_intr_brf_error_mbox_ecc_unc_intr_count_r = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_intr_brf_error_mbox_ecc_unc_intr_count_r}}; + + assign hit_intr_brf_error_wdt_timer1_timeout_intr_count_r = (soc_ifc_reg_req_data.addr == full_addr_intr_brf_error_wdt_timer1_timeout_intr_count_r[AXI_ADDR_WIDTH-1:0]); + assign bus_intr_brf_error_wdt_timer1_timeout_intr_count_r = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_intr_brf_error_wdt_timer1_timeout_intr_count_r}}; + + assign hit_intr_brf_error_wdt_timer2_timeout_intr_count_r = (soc_ifc_reg_req_data.addr == full_addr_intr_brf_error_wdt_timer2_timeout_intr_count_r[AXI_ADDR_WIDTH-1:0]); + assign bus_intr_brf_error_wdt_timer2_timeout_intr_count_r = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_intr_brf_error_wdt_timer2_timeout_intr_count_r}}; + + assign hit_intr_brf_notif_cmd_avail_intr_count_r = (soc_ifc_reg_req_data.addr == full_addr_intr_brf_notif_cmd_avail_intr_count_r[AXI_ADDR_WIDTH-1:0]); + assign bus_intr_brf_notif_cmd_avail_intr_count_r = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_intr_brf_notif_cmd_avail_intr_count_r}}; + + assign hit_intr_brf_notif_mbox_ecc_cor_intr_count_r = (soc_ifc_reg_req_data.addr == full_addr_intr_brf_notif_mbox_ecc_cor_intr_count_r[AXI_ADDR_WIDTH-1:0]); + assign bus_intr_brf_notif_mbox_ecc_cor_intr_count_r = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_intr_brf_notif_mbox_ecc_cor_intr_count_r}}; + + assign hit_intr_brf_notif_debug_locked_intr_count_r = (soc_ifc_reg_req_data.addr == full_addr_intr_brf_notif_debug_locked_intr_count_r[AXI_ADDR_WIDTH-1:0]); + assign bus_intr_brf_notif_debug_locked_intr_count_r = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_intr_brf_notif_debug_locked_intr_count_r}}; + + assign hit_intr_brf_notif_scan_mode_intr_count_r = (soc_ifc_reg_req_data.addr == full_addr_intr_brf_notif_scan_mode_intr_count_r[AXI_ADDR_WIDTH-1:0]); + assign bus_intr_brf_notif_scan_mode_intr_count_r = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_intr_brf_notif_scan_mode_intr_count_r}}; + + assign hit_intr_brf_notif_soc_req_lock_intr_count_r = (soc_ifc_reg_req_data.addr == full_addr_intr_brf_notif_soc_req_lock_intr_count_r[AXI_ADDR_WIDTH-1:0]); + assign bus_intr_brf_notif_soc_req_lock_intr_count_r = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_intr_brf_notif_soc_req_lock_intr_count_r}}; + + assign hit_intr_brf_notif_gen_in_toggle_intr_count_r = (soc_ifc_reg_req_data.addr == full_addr_intr_brf_notif_gen_in_toggle_intr_count_r[AXI_ADDR_WIDTH-1:0]); + assign bus_intr_brf_notif_gen_in_toggle_intr_count_r = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_intr_brf_notif_gen_in_toggle_intr_count_r}}; + + assign hit_intr_brf_error_internal_intr_count_incr_r = (soc_ifc_reg_req_data.addr == full_addr_intr_brf_error_internal_intr_count_incr_r[AXI_ADDR_WIDTH-1:0]); + assign bus_intr_brf_error_internal_intr_count_incr_r = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_intr_brf_error_internal_intr_count_incr_r}}; + + assign hit_intr_brf_error_inv_dev_intr_count_incr_r = (soc_ifc_reg_req_data.addr == full_addr_intr_brf_error_inv_dev_intr_count_incr_r[AXI_ADDR_WIDTH-1:0]); + assign bus_intr_brf_error_inv_dev_intr_count_incr_r = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_intr_brf_error_inv_dev_intr_count_incr_r}}; + + assign hit_intr_brf_error_cmd_fail_intr_count_incr_r = (soc_ifc_reg_req_data.addr == full_addr_intr_brf_error_cmd_fail_intr_count_incr_r[AXI_ADDR_WIDTH-1:0]); + assign bus_intr_brf_error_cmd_fail_intr_count_incr_r = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_intr_brf_error_cmd_fail_intr_count_incr_r}}; + + assign hit_intr_brf_error_bad_fuse_intr_count_incr_r = (soc_ifc_reg_req_data.addr == full_addr_intr_brf_error_bad_fuse_intr_count_incr_r[AXI_ADDR_WIDTH-1:0]); + assign bus_intr_brf_error_bad_fuse_intr_count_incr_r = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_intr_brf_error_bad_fuse_intr_count_incr_r}}; + + assign hit_intr_brf_error_iccm_blocked_intr_count_incr_r = (soc_ifc_reg_req_data.addr == full_addr_intr_brf_error_iccm_blocked_intr_count_incr_r[AXI_ADDR_WIDTH-1:0]); + assign bus_intr_brf_error_iccm_blocked_intr_count_incr_r = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_intr_brf_error_iccm_blocked_intr_count_incr_r}}; + + assign hit_intr_brf_error_mbox_ecc_unc_intr_count_incr_r = (soc_ifc_reg_req_data.addr == full_addr_intr_brf_error_mbox_ecc_unc_intr_count_incr_r[AXI_ADDR_WIDTH-1:0]); + assign bus_intr_brf_error_mbox_ecc_unc_intr_count_incr_r = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_intr_brf_error_mbox_ecc_unc_intr_count_incr_r}}; + + assign hit_intr_brf_error_wdt_timer1_timeout_intr_count_incr_r = (soc_ifc_reg_req_data.addr == full_addr_intr_brf_error_wdt_timer1_timeout_intr_count_incr_r[AXI_ADDR_WIDTH-1:0]); + assign bus_intr_brf_error_wdt_timer1_timeout_intr_count_incr_r = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_intr_brf_error_wdt_timer1_timeout_intr_count_incr_r}}; + + assign hit_intr_brf_error_wdt_timer2_timeout_intr_count_incr_r = (soc_ifc_reg_req_data.addr == full_addr_intr_brf_error_wdt_timer2_timeout_intr_count_incr_r[AXI_ADDR_WIDTH-1:0]); + assign bus_intr_brf_error_wdt_timer2_timeout_intr_count_incr_r = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_intr_brf_error_wdt_timer2_timeout_intr_count_incr_r}}; + + assign hit_intr_brf_notif_cmd_avail_intr_count_incr_r = (soc_ifc_reg_req_data.addr == full_addr_intr_brf_notif_cmd_avail_intr_count_incr_r[AXI_ADDR_WIDTH-1:0]); + assign bus_intr_brf_notif_cmd_avail_intr_count_incr_r = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_intr_brf_notif_cmd_avail_intr_count_incr_r}}; + + assign hit_intr_brf_notif_mbox_ecc_cor_intr_count_incr_r = (soc_ifc_reg_req_data.addr == full_addr_intr_brf_notif_mbox_ecc_cor_intr_count_incr_r[AXI_ADDR_WIDTH-1:0]); + assign bus_intr_brf_notif_mbox_ecc_cor_intr_count_incr_r = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_intr_brf_notif_mbox_ecc_cor_intr_count_incr_r}}; + + assign hit_intr_brf_notif_debug_locked_intr_count_incr_r = (soc_ifc_reg_req_data.addr == full_addr_intr_brf_notif_debug_locked_intr_count_incr_r[AXI_ADDR_WIDTH-1:0]); + assign bus_intr_brf_notif_debug_locked_intr_count_incr_r = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_intr_brf_notif_debug_locked_intr_count_incr_r}}; + + assign hit_intr_brf_notif_scan_mode_intr_count_incr_r = (soc_ifc_reg_req_data.addr == full_addr_intr_brf_notif_scan_mode_intr_count_incr_r[AXI_ADDR_WIDTH-1:0]); + assign bus_intr_brf_notif_scan_mode_intr_count_incr_r = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_intr_brf_notif_scan_mode_intr_count_incr_r}}; + + assign hit_intr_brf_notif_soc_req_lock_intr_count_incr_r = (soc_ifc_reg_req_data.addr == full_addr_intr_brf_notif_soc_req_lock_intr_count_incr_r[AXI_ADDR_WIDTH-1:0]); + assign bus_intr_brf_notif_soc_req_lock_intr_count_incr_r = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_intr_brf_notif_soc_req_lock_intr_count_incr_r}}; + + assign hit_intr_brf_notif_gen_in_toggle_intr_count_incr_r = (soc_ifc_reg_req_data.addr == full_addr_intr_brf_notif_gen_in_toggle_intr_count_incr_r[AXI_ADDR_WIDTH-1:0]); + assign bus_intr_brf_notif_gen_in_toggle_intr_count_incr_r = {uc_rd, uc_wr, soc_rd, soc_wr} & {4{hit_intr_brf_notif_gen_in_toggle_intr_count_incr_r}}; + + // ----------------------- COVERGROUP CPTRA_HW_ERROR_FATAL ----------------------- + covergroup soc_ifc_CPTRA_HW_ERROR_FATAL_cg (ref logic [3:0] bus_event) @(posedge clk); + CPTRA_HW_ERROR_FATAL_cp : coverpoint i_soc_ifc_reg.field_storage.CPTRA_HW_ERROR_FATAL; + bus_CPTRA_HW_ERROR_FATAL_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP CPTRA_HW_ERROR_NON_FATAL ----------------------- + covergroup soc_ifc_CPTRA_HW_ERROR_NON_FATAL_cg (ref logic [3:0] bus_event) @(posedge clk); + CPTRA_HW_ERROR_NON_FATAL_cp : coverpoint i_soc_ifc_reg.field_storage.CPTRA_HW_ERROR_NON_FATAL; + bus_CPTRA_HW_ERROR_NON_FATAL_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP CPTRA_FW_ERROR_FATAL ----------------------- + covergroup soc_ifc_CPTRA_FW_ERROR_FATAL_cg (ref logic [3:0] bus_event) @(posedge clk); + CPTRA_FW_ERROR_FATAL_cp : coverpoint i_soc_ifc_reg.field_storage.CPTRA_FW_ERROR_FATAL; + bus_CPTRA_FW_ERROR_FATAL_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP CPTRA_FW_ERROR_NON_FATAL ----------------------- + covergroup soc_ifc_CPTRA_FW_ERROR_NON_FATAL_cg (ref logic [3:0] bus_event) @(posedge clk); + CPTRA_FW_ERROR_NON_FATAL_cp : coverpoint i_soc_ifc_reg.field_storage.CPTRA_FW_ERROR_NON_FATAL; + bus_CPTRA_FW_ERROR_NON_FATAL_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP CPTRA_HW_ERROR_ENC ----------------------- + covergroup soc_ifc_CPTRA_HW_ERROR_ENC_cg (ref logic [3:0] bus_event) @(posedge clk); + CPTRA_HW_ERROR_ENC_cp : coverpoint i_soc_ifc_reg.field_storage.CPTRA_HW_ERROR_ENC; + bus_CPTRA_HW_ERROR_ENC_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP CPTRA_FW_ERROR_ENC ----------------------- + covergroup soc_ifc_CPTRA_FW_ERROR_ENC_cg (ref logic [3:0] bus_event) @(posedge clk); + CPTRA_FW_ERROR_ENC_cp : coverpoint i_soc_ifc_reg.field_storage.CPTRA_FW_ERROR_ENC; + bus_CPTRA_FW_ERROR_ENC_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP CPTRA_FW_EXTENDED_ERROR_INFO [0:7] ----------------------- + covergroup soc_ifc_CPTRA_FW_EXTENDED_ERROR_INFO_cg (ref logic [3:0] bus_event[0:7]) @(posedge clk); + CPTRA_FW_EXTENDED_ERROR_INFO0_cp : coverpoint i_soc_ifc_reg.field_storage.CPTRA_FW_EXTENDED_ERROR_INFO[0]; + bus_CPTRA_FW_EXTENDED_ERROR_INFO0_cp : coverpoint bus_event[0] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + CPTRA_FW_EXTENDED_ERROR_INFO1_cp : coverpoint i_soc_ifc_reg.field_storage.CPTRA_FW_EXTENDED_ERROR_INFO[1]; + bus_CPTRA_FW_EXTENDED_ERROR_INFO1_cp : coverpoint bus_event[1] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + CPTRA_FW_EXTENDED_ERROR_INFO2_cp : coverpoint i_soc_ifc_reg.field_storage.CPTRA_FW_EXTENDED_ERROR_INFO[2]; + bus_CPTRA_FW_EXTENDED_ERROR_INFO2_cp : coverpoint bus_event[2] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + CPTRA_FW_EXTENDED_ERROR_INFO3_cp : coverpoint i_soc_ifc_reg.field_storage.CPTRA_FW_EXTENDED_ERROR_INFO[3]; + bus_CPTRA_FW_EXTENDED_ERROR_INFO3_cp : coverpoint bus_event[3] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + CPTRA_FW_EXTENDED_ERROR_INFO4_cp : coverpoint i_soc_ifc_reg.field_storage.CPTRA_FW_EXTENDED_ERROR_INFO[4]; + bus_CPTRA_FW_EXTENDED_ERROR_INFO4_cp : coverpoint bus_event[4] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + CPTRA_FW_EXTENDED_ERROR_INFO5_cp : coverpoint i_soc_ifc_reg.field_storage.CPTRA_FW_EXTENDED_ERROR_INFO[5]; + bus_CPTRA_FW_EXTENDED_ERROR_INFO5_cp : coverpoint bus_event[5] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + CPTRA_FW_EXTENDED_ERROR_INFO6_cp : coverpoint i_soc_ifc_reg.field_storage.CPTRA_FW_EXTENDED_ERROR_INFO[6]; + bus_CPTRA_FW_EXTENDED_ERROR_INFO6_cp : coverpoint bus_event[6] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + CPTRA_FW_EXTENDED_ERROR_INFO7_cp : coverpoint i_soc_ifc_reg.field_storage.CPTRA_FW_EXTENDED_ERROR_INFO[7]; + bus_CPTRA_FW_EXTENDED_ERROR_INFO7_cp : coverpoint bus_event[7] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP CPTRA_BOOT_STATUS ----------------------- + covergroup soc_ifc_CPTRA_BOOT_STATUS_cg (ref logic [3:0] bus_event) @(posedge clk); + CPTRA_BOOT_STATUS_cp : coverpoint i_soc_ifc_reg.field_storage.CPTRA_BOOT_STATUS; + bus_CPTRA_BOOT_STATUS_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP CPTRA_FLOW_STATUS ----------------------- + covergroup soc_ifc_CPTRA_FLOW_STATUS_cg (ref logic [3:0] bus_event) @(posedge clk); + CPTRA_FLOW_STATUS_cp : coverpoint i_soc_ifc_reg.field_storage.CPTRA_FLOW_STATUS; + bus_CPTRA_FLOW_STATUS_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP CPTRA_RESET_REASON ----------------------- + covergroup soc_ifc_CPTRA_RESET_REASON_cg (ref logic [3:0] bus_event) @(posedge clk); + CPTRA_RESET_REASON_cp : coverpoint i_soc_ifc_reg.field_storage.CPTRA_RESET_REASON; + bus_CPTRA_RESET_REASON_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // // ----------------------- COVERGROUP CPTRA_SECURITY_STATE ----------------------- + // covergroup soc_ifc_CPTRA_SECURITY_STATE_cg (ref logic [3:0] bus_event) @(posedge clk); + // CPTRA_SECURITY_STATE_cp : coverpoint i_soc_ifc_reg.field_storage.CPTRA_SECURITY_STATE; + // bus_CPTRA_SECURITY_STATE_cp : coverpoint bus_event { + // bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + // ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + // } + // endgroup + + // ----------------------- COVERGROUP CPTRA_MBOX_VALID_AXI_USER [0:4] ----------------------- + covergroup soc_ifc_CPTRA_MBOX_VALID_AXI_USER_cg (ref logic [3:0] bus_event[0:4]) @(posedge clk); + CPTRA_MBOX_VALID_AXI_USER0_cp : coverpoint i_soc_ifc_reg.field_storage.CPTRA_MBOX_VALID_AXI_USER[0]; + bus_CPTRA_MBOX_VALID_AXI_USER0_cp : coverpoint bus_event[0] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + CPTRA_MBOX_VALID_AXI_USER1_cp : coverpoint i_soc_ifc_reg.field_storage.CPTRA_MBOX_VALID_AXI_USER[1]; + bus_CPTRA_MBOX_VALID_AXI_USER1_cp : coverpoint bus_event[1] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + CPTRA_MBOX_VALID_AXI_USER2_cp : coverpoint i_soc_ifc_reg.field_storage.CPTRA_MBOX_VALID_AXI_USER[2]; + bus_CPTRA_MBOX_VALID_AXI_USER2_cp : coverpoint bus_event[2] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + CPTRA_MBOX_VALID_AXI_USER3_cp : coverpoint i_soc_ifc_reg.field_storage.CPTRA_MBOX_VALID_AXI_USER[3]; + bus_CPTRA_MBOX_VALID_AXI_USER3_cp : coverpoint bus_event[3] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + CPTRA_MBOX_VALID_AXI_USER4_cp : coverpoint i_soc_ifc_reg.field_storage.CPTRA_MBOX_VALID_AXI_USER[4]; + bus_CPTRA_MBOX_VALID_AXI_USER4_cp : coverpoint bus_event[4] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP CPTRA_MBOX_AXI_USER_LOCK [0:4] ----------------------- + covergroup soc_ifc_CPTRA_MBOX_AXI_USER_LOCK_cg (ref logic [3:0] bus_event[0:4]) @(posedge clk); + CPTRA_MBOX_AXI_USER_LOCK0_cp : coverpoint i_soc_ifc_reg.field_storage.CPTRA_MBOX_AXI_USER_LOCK[0]; + bus_CPTRA_MBOX_AXI_USER_LOCK0_cp : coverpoint bus_event[0] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + CPTRA_MBOX_AXI_USER_LOCK1_cp : coverpoint i_soc_ifc_reg.field_storage.CPTRA_MBOX_AXI_USER_LOCK[1]; + bus_CPTRA_MBOX_AXI_USER_LOCK1_cp : coverpoint bus_event[1] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + CPTRA_MBOX_AXI_USER_LOCK2_cp : coverpoint i_soc_ifc_reg.field_storage.CPTRA_MBOX_AXI_USER_LOCK[2]; + bus_CPTRA_MBOX_AXI_USER_LOCK2_cp : coverpoint bus_event[2] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + CPTRA_MBOX_AXI_USER_LOCK3_cp : coverpoint i_soc_ifc_reg.field_storage.CPTRA_MBOX_AXI_USER_LOCK[3]; + bus_CPTRA_MBOX_AXI_USER_LOCK3_cp : coverpoint bus_event[3] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + CPTRA_MBOX_AXI_USER_LOCK4_cp : coverpoint i_soc_ifc_reg.field_storage.CPTRA_MBOX_AXI_USER_LOCK[4]; + bus_CPTRA_MBOX_AXI_USER_LOCK4_cp : coverpoint bus_event[4] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP CPTRA_TRNG_VALID_AXI_USER ----------------------- + covergroup soc_ifc_CPTRA_TRNG_VALID_AXI_USER_cg (ref logic [3:0] bus_event) @(posedge clk); + CPTRA_TRNG_VALID_AXI_USER_cp : coverpoint i_soc_ifc_reg.field_storage.CPTRA_TRNG_VALID_AXI_USER; + bus_CPTRA_TRNG_VALID_AXI_USER_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP CPTRA_TRNG_AXI_USER_LOCK ----------------------- + covergroup soc_ifc_CPTRA_TRNG_AXI_USER_LOCK_cg (ref logic [3:0] bus_event) @(posedge clk); + CPTRA_TRNG_AXI_USER_LOCK_cp : coverpoint i_soc_ifc_reg.field_storage.CPTRA_TRNG_AXI_USER_LOCK; + bus_CPTRA_TRNG_AXI_USER_LOCK_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP CPTRA_TRNG_DATA [0:11] ----------------------- + covergroup soc_ifc_CPTRA_TRNG_DATA_cg (ref logic [3:0] bus_event[0:11]) @(posedge clk); + CPTRA_TRNG_DATA0_cp : coverpoint i_soc_ifc_reg.field_storage.CPTRA_TRNG_DATA[0]; + bus_CPTRA_TRNG_DATA0_cp : coverpoint bus_event[0] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + CPTRA_TRNG_DATA1_cp : coverpoint i_soc_ifc_reg.field_storage.CPTRA_TRNG_DATA[1]; + bus_CPTRA_TRNG_DATA1_cp : coverpoint bus_event[1] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + CPTRA_TRNG_DATA2_cp : coverpoint i_soc_ifc_reg.field_storage.CPTRA_TRNG_DATA[2]; + bus_CPTRA_TRNG_DATA2_cp : coverpoint bus_event[2] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + CPTRA_TRNG_DATA3_cp : coverpoint i_soc_ifc_reg.field_storage.CPTRA_TRNG_DATA[3]; + bus_CPTRA_TRNG_DATA3_cp : coverpoint bus_event[3] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + CPTRA_TRNG_DATA4_cp : coverpoint i_soc_ifc_reg.field_storage.CPTRA_TRNG_DATA[4]; + bus_CPTRA_TRNG_DATA4_cp : coverpoint bus_event[4] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + CPTRA_TRNG_DATA5_cp : coverpoint i_soc_ifc_reg.field_storage.CPTRA_TRNG_DATA[5]; + bus_CPTRA_TRNG_DATA5_cp : coverpoint bus_event[5] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + CPTRA_TRNG_DATA6_cp : coverpoint i_soc_ifc_reg.field_storage.CPTRA_TRNG_DATA[6]; + bus_CPTRA_TRNG_DATA6_cp : coverpoint bus_event[6] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + CPTRA_TRNG_DATA7_cp : coverpoint i_soc_ifc_reg.field_storage.CPTRA_TRNG_DATA[7]; + bus_CPTRA_TRNG_DATA7_cp : coverpoint bus_event[7] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + CPTRA_TRNG_DATA8_cp : coverpoint i_soc_ifc_reg.field_storage.CPTRA_TRNG_DATA[8]; + bus_CPTRA_TRNG_DATA8_cp : coverpoint bus_event[8] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + CPTRA_TRNG_DATA9_cp : coverpoint i_soc_ifc_reg.field_storage.CPTRA_TRNG_DATA[9]; + bus_CPTRA_TRNG_DATA9_cp : coverpoint bus_event[9] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + CPTRA_TRNG_DATA10_cp : coverpoint i_soc_ifc_reg.field_storage.CPTRA_TRNG_DATA[10]; + bus_CPTRA_TRNG_DATA10_cp : coverpoint bus_event[10] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + CPTRA_TRNG_DATA11_cp : coverpoint i_soc_ifc_reg.field_storage.CPTRA_TRNG_DATA[11]; + bus_CPTRA_TRNG_DATA11_cp : coverpoint bus_event[11] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP CPTRA_TRNG_CTRL ----------------------- + covergroup soc_ifc_CPTRA_TRNG_CTRL_cg (ref logic [3:0] bus_event) @(posedge clk); + CPTRA_TRNG_CTRL_cp : coverpoint i_soc_ifc_reg.field_storage.CPTRA_TRNG_CTRL; + bus_CPTRA_TRNG_CTRL_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP CPTRA_TRNG_STATUS ----------------------- + covergroup soc_ifc_CPTRA_TRNG_STATUS_cg (ref logic [3:0] bus_event) @(posedge clk); + CPTRA_TRNG_STATUS_cp : coverpoint i_soc_ifc_reg.field_storage.CPTRA_TRNG_STATUS; + bus_CPTRA_TRNG_STATUS_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP CPTRA_FUSE_WR_DONE ----------------------- + covergroup soc_ifc_CPTRA_FUSE_WR_DONE_cg (ref logic [3:0] bus_event) @(posedge clk); + CPTRA_FUSE_WR_DONE_cp : coverpoint i_soc_ifc_reg.field_storage.CPTRA_FUSE_WR_DONE; + bus_CPTRA_FUSE_WR_DONE_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP CPTRA_TIMER_CONFIG ----------------------- + covergroup soc_ifc_CPTRA_TIMER_CONFIG_cg (ref logic [3:0] bus_event) @(posedge clk); + CPTRA_TIMER_CONFIG_cp : coverpoint i_soc_ifc_reg.field_storage.CPTRA_TIMER_CONFIG; + bus_CPTRA_TIMER_CONFIG_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP CPTRA_BOOTFSM_GO ----------------------- + covergroup soc_ifc_CPTRA_BOOTFSM_GO_cg (ref logic [3:0] bus_event) @(posedge clk); + CPTRA_BOOTFSM_GO_cp : coverpoint i_soc_ifc_reg.field_storage.CPTRA_BOOTFSM_GO; + bus_CPTRA_BOOTFSM_GO_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP CPTRA_DBG_MANUF_SERVICE_REG ----------------------- + covergroup soc_ifc_CPTRA_DBG_MANUF_SERVICE_REG_cg (ref logic [3:0] bus_event) @(posedge clk); + CPTRA_DBG_MANUF_SERVICE_REG_cp : coverpoint i_soc_ifc_reg.field_storage.CPTRA_DBG_MANUF_SERVICE_REG; + bus_CPTRA_DBG_MANUF_SERVICE_REG_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP CPTRA_CLK_GATING_EN ----------------------- + covergroup soc_ifc_CPTRA_CLK_GATING_EN_cg (ref logic [3:0] bus_event) @(posedge clk); + CPTRA_CLK_GATING_EN_cp : coverpoint i_soc_ifc_reg.field_storage.CPTRA_CLK_GATING_EN; + bus_CPTRA_CLK_GATING_EN_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP CPTRA_GENERIC_INPUT_WIRES [0:1] ----------------------- + covergroup soc_ifc_CPTRA_GENERIC_INPUT_WIRES_cg (ref logic [3:0] bus_event[0:1]) @(posedge clk); + CPTRA_GENERIC_INPUT_WIRES0_cp : coverpoint i_soc_ifc_reg.field_storage.CPTRA_GENERIC_INPUT_WIRES[0]; + bus_CPTRA_GENERIC_INPUT_WIRES0_cp : coverpoint bus_event[0] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + CPTRA_GENERIC_INPUT_WIRES1_cp : coverpoint i_soc_ifc_reg.field_storage.CPTRA_GENERIC_INPUT_WIRES[1]; + bus_CPTRA_GENERIC_INPUT_WIRES1_cp : coverpoint bus_event[1] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP CPTRA_GENERIC_OUTPUT_WIRES [0:1] ----------------------- + covergroup soc_ifc_CPTRA_GENERIC_OUTPUT_WIRES_cg (ref logic [3:0] bus_event[0:1]) @(posedge clk); + CPTRA_GENERIC_OUTPUT_WIRES0_cp : coverpoint i_soc_ifc_reg.field_storage.CPTRA_GENERIC_OUTPUT_WIRES[0]; + bus_CPTRA_GENERIC_OUTPUT_WIRES0_cp : coverpoint bus_event[0] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + CPTRA_GENERIC_OUTPUT_WIRES1_cp : coverpoint i_soc_ifc_reg.field_storage.CPTRA_GENERIC_OUTPUT_WIRES[1]; + bus_CPTRA_GENERIC_OUTPUT_WIRES1_cp : coverpoint bus_event[1] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // // ----------------------- COVERGROUP CPTRA_HW_REV_ID ----------------------- + // covergroup soc_ifc_CPTRA_HW_REV_ID_cg (ref logic [3:0] bus_event) @(posedge clk); + // CPTRA_HW_REV_ID_cp : coverpoint i_soc_ifc_reg.field_storage.CPTRA_HW_REV_ID; + // bus_CPTRA_HW_REV_ID_cp : coverpoint bus_event { + // bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + // ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + // } + // endgroup + + // ----------------------- COVERGROUP CPTRA_FW_REV_ID [0:1] ----------------------- + covergroup soc_ifc_CPTRA_FW_REV_ID_cg (ref logic [3:0] bus_event[0:1]) @(posedge clk); + CPTRA_FW_REV_ID0_cp : coverpoint i_soc_ifc_reg.field_storage.CPTRA_FW_REV_ID[0]; + bus_CPTRA_FW_REV_ID0_cp : coverpoint bus_event[0] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + CPTRA_FW_REV_ID1_cp : coverpoint i_soc_ifc_reg.field_storage.CPTRA_FW_REV_ID[1]; + bus_CPTRA_FW_REV_ID1_cp : coverpoint bus_event[1] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // // ----------------------- COVERGROUP CPTRA_HW_CONFIG ----------------------- + // covergroup soc_ifc_CPTRA_HW_CONFIG_cg (ref logic [3:0] bus_event) @(posedge clk); + // CPTRA_HW_CONFIG_cp : coverpoint i_soc_ifc_reg.field_storage.CPTRA_HW_CONFIG; + // bus_CPTRA_HW_CONFIG_cp : coverpoint bus_event { + // bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + // ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + // } + // endgroup + + // ----------------------- COVERGROUP CPTRA_WDT_TIMER1_EN ----------------------- + covergroup soc_ifc_CPTRA_WDT_TIMER1_EN_cg (ref logic [3:0] bus_event) @(posedge clk); + CPTRA_WDT_TIMER1_EN_cp : coverpoint i_soc_ifc_reg.field_storage.CPTRA_WDT_TIMER1_EN; + bus_CPTRA_WDT_TIMER1_EN_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP CPTRA_WDT_TIMER1_CTRL ----------------------- + covergroup soc_ifc_CPTRA_WDT_TIMER1_CTRL_cg (ref logic [3:0] bus_event) @(posedge clk); + CPTRA_WDT_TIMER1_CTRL_cp : coverpoint i_soc_ifc_reg.field_storage.CPTRA_WDT_TIMER1_CTRL; + bus_CPTRA_WDT_TIMER1_CTRL_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP CPTRA_WDT_TIMER1_TIMEOUT_PERIOD [0:1] ----------------------- + covergroup soc_ifc_CPTRA_WDT_TIMER1_TIMEOUT_PERIOD_cg (ref logic [3:0] bus_event[0:1]) @(posedge clk); + CPTRA_WDT_TIMER1_TIMEOUT_PERIOD0_cp : coverpoint i_soc_ifc_reg.field_storage.CPTRA_WDT_TIMER1_TIMEOUT_PERIOD[0]; + bus_CPTRA_WDT_TIMER1_TIMEOUT_PERIOD0_cp : coverpoint bus_event[0] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + CPTRA_WDT_TIMER1_TIMEOUT_PERIOD1_cp : coverpoint i_soc_ifc_reg.field_storage.CPTRA_WDT_TIMER1_TIMEOUT_PERIOD[1]; + bus_CPTRA_WDT_TIMER1_TIMEOUT_PERIOD1_cp : coverpoint bus_event[1] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP CPTRA_WDT_TIMER2_EN ----------------------- + covergroup soc_ifc_CPTRA_WDT_TIMER2_EN_cg (ref logic [3:0] bus_event) @(posedge clk); + CPTRA_WDT_TIMER2_EN_cp : coverpoint i_soc_ifc_reg.field_storage.CPTRA_WDT_TIMER2_EN; + bus_CPTRA_WDT_TIMER2_EN_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP CPTRA_WDT_TIMER2_CTRL ----------------------- + covergroup soc_ifc_CPTRA_WDT_TIMER2_CTRL_cg (ref logic [3:0] bus_event) @(posedge clk); + CPTRA_WDT_TIMER2_CTRL_cp : coverpoint i_soc_ifc_reg.field_storage.CPTRA_WDT_TIMER2_CTRL; + bus_CPTRA_WDT_TIMER2_CTRL_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP CPTRA_WDT_TIMER2_TIMEOUT_PERIOD [0:1] ----------------------- + covergroup soc_ifc_CPTRA_WDT_TIMER2_TIMEOUT_PERIOD_cg (ref logic [3:0] bus_event[0:1]) @(posedge clk); + CPTRA_WDT_TIMER2_TIMEOUT_PERIOD0_cp : coverpoint i_soc_ifc_reg.field_storage.CPTRA_WDT_TIMER2_TIMEOUT_PERIOD[0]; + bus_CPTRA_WDT_TIMER2_TIMEOUT_PERIOD0_cp : coverpoint bus_event[0] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + CPTRA_WDT_TIMER2_TIMEOUT_PERIOD1_cp : coverpoint i_soc_ifc_reg.field_storage.CPTRA_WDT_TIMER2_TIMEOUT_PERIOD[1]; + bus_CPTRA_WDT_TIMER2_TIMEOUT_PERIOD1_cp : coverpoint bus_event[1] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP CPTRA_WDT_STATUS ----------------------- + covergroup soc_ifc_CPTRA_WDT_STATUS_cg (ref logic [3:0] bus_event) @(posedge clk); + CPTRA_WDT_STATUS_cp : coverpoint i_soc_ifc_reg.field_storage.CPTRA_WDT_STATUS; + bus_CPTRA_WDT_STATUS_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP CPTRA_FUSE_VALID_AXI_USER ----------------------- + covergroup soc_ifc_CPTRA_FUSE_VALID_AXI_USER_cg (ref logic [3:0] bus_event) @(posedge clk); + CPTRA_FUSE_VALID_AXI_USER_cp : coverpoint i_soc_ifc_reg.field_storage.CPTRA_FUSE_VALID_AXI_USER; + bus_CPTRA_FUSE_VALID_AXI_USER_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP CPTRA_FUSE_AXI_USER_LOCK ----------------------- + covergroup soc_ifc_CPTRA_FUSE_AXI_USER_LOCK_cg (ref logic [3:0] bus_event) @(posedge clk); + CPTRA_FUSE_AXI_USER_LOCK_cp : coverpoint i_soc_ifc_reg.field_storage.CPTRA_FUSE_AXI_USER_LOCK; + bus_CPTRA_FUSE_AXI_USER_LOCK_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP CPTRA_WDT_CFG [0:1] ----------------------- + covergroup soc_ifc_CPTRA_WDT_CFG_cg (ref logic [3:0] bus_event[0:1]) @(posedge clk); + CPTRA_WDT_CFG0_cp : coverpoint i_soc_ifc_reg.field_storage.CPTRA_WDT_CFG[0]; + bus_CPTRA_WDT_CFG0_cp : coverpoint bus_event[0] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + CPTRA_WDT_CFG1_cp : coverpoint i_soc_ifc_reg.field_storage.CPTRA_WDT_CFG[1]; + bus_CPTRA_WDT_CFG1_cp : coverpoint bus_event[1] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP CPTRA_iTRNG_ENTROPY_CONFIG_0 ----------------------- + covergroup soc_ifc_CPTRA_iTRNG_ENTROPY_CONFIG_0_cg (ref logic [3:0] bus_event) @(posedge clk); + CPTRA_iTRNG_ENTROPY_CONFIG_0_cp : coverpoint i_soc_ifc_reg.field_storage.CPTRA_iTRNG_ENTROPY_CONFIG_0; + bus_CPTRA_iTRNG_ENTROPY_CONFIG_0_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP CPTRA_iTRNG_ENTROPY_CONFIG_1 ----------------------- + covergroup soc_ifc_CPTRA_iTRNG_ENTROPY_CONFIG_1_cg (ref logic [3:0] bus_event) @(posedge clk); + CPTRA_iTRNG_ENTROPY_CONFIG_1_cp : coverpoint i_soc_ifc_reg.field_storage.CPTRA_iTRNG_ENTROPY_CONFIG_1; + bus_CPTRA_iTRNG_ENTROPY_CONFIG_1_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP CPTRA_RSVD_REG [0:1] ----------------------- + covergroup soc_ifc_CPTRA_RSVD_REG_cg (ref logic [3:0] bus_event[0:1]) @(posedge clk); + CPTRA_RSVD_REG0_cp : coverpoint i_soc_ifc_reg.field_storage.CPTRA_RSVD_REG[0]; + bus_CPTRA_RSVD_REG0_cp : coverpoint bus_event[0] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + CPTRA_RSVD_REG1_cp : coverpoint i_soc_ifc_reg.field_storage.CPTRA_RSVD_REG[1]; + bus_CPTRA_RSVD_REG1_cp : coverpoint bus_event[1] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP CPTRA_HW_CAPABILITIES ----------------------- + covergroup soc_ifc_CPTRA_HW_CAPABILITIES_cg (ref logic [3:0] bus_event) @(posedge clk); + CPTRA_HW_CAPABILITIES_cp : coverpoint i_soc_ifc_reg.field_storage.CPTRA_HW_CAPABILITIES; + bus_CPTRA_HW_CAPABILITIES_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP CPTRA_FW_CAPABILITIES ----------------------- + covergroup soc_ifc_CPTRA_FW_CAPABILITIES_cg (ref logic [3:0] bus_event) @(posedge clk); + CPTRA_FW_CAPABILITIES_cp : coverpoint i_soc_ifc_reg.field_storage.CPTRA_FW_CAPABILITIES; + bus_CPTRA_FW_CAPABILITIES_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP CPTRA_CAP_LOCK ----------------------- + covergroup soc_ifc_CPTRA_CAP_LOCK_cg (ref logic [3:0] bus_event) @(posedge clk); + CPTRA_CAP_LOCK_cp : coverpoint i_soc_ifc_reg.field_storage.CPTRA_CAP_LOCK; + bus_CPTRA_CAP_LOCK_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP CPTRA_OWNER_PK_HASH [0:11] ----------------------- + covergroup soc_ifc_CPTRA_OWNER_PK_HASH_cg (ref logic [3:0] bus_event[0:11]) @(posedge clk); + CPTRA_OWNER_PK_HASH0_cp : coverpoint i_soc_ifc_reg.field_storage.CPTRA_OWNER_PK_HASH[0]; + bus_CPTRA_OWNER_PK_HASH0_cp : coverpoint bus_event[0] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + CPTRA_OWNER_PK_HASH1_cp : coverpoint i_soc_ifc_reg.field_storage.CPTRA_OWNER_PK_HASH[1]; + bus_CPTRA_OWNER_PK_HASH1_cp : coverpoint bus_event[1] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + CPTRA_OWNER_PK_HASH2_cp : coverpoint i_soc_ifc_reg.field_storage.CPTRA_OWNER_PK_HASH[2]; + bus_CPTRA_OWNER_PK_HASH2_cp : coverpoint bus_event[2] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + CPTRA_OWNER_PK_HASH3_cp : coverpoint i_soc_ifc_reg.field_storage.CPTRA_OWNER_PK_HASH[3]; + bus_CPTRA_OWNER_PK_HASH3_cp : coverpoint bus_event[3] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + CPTRA_OWNER_PK_HASH4_cp : coverpoint i_soc_ifc_reg.field_storage.CPTRA_OWNER_PK_HASH[4]; + bus_CPTRA_OWNER_PK_HASH4_cp : coverpoint bus_event[4] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + CPTRA_OWNER_PK_HASH5_cp : coverpoint i_soc_ifc_reg.field_storage.CPTRA_OWNER_PK_HASH[5]; + bus_CPTRA_OWNER_PK_HASH5_cp : coverpoint bus_event[5] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + CPTRA_OWNER_PK_HASH6_cp : coverpoint i_soc_ifc_reg.field_storage.CPTRA_OWNER_PK_HASH[6]; + bus_CPTRA_OWNER_PK_HASH6_cp : coverpoint bus_event[6] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + CPTRA_OWNER_PK_HASH7_cp : coverpoint i_soc_ifc_reg.field_storage.CPTRA_OWNER_PK_HASH[7]; + bus_CPTRA_OWNER_PK_HASH7_cp : coverpoint bus_event[7] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + CPTRA_OWNER_PK_HASH8_cp : coverpoint i_soc_ifc_reg.field_storage.CPTRA_OWNER_PK_HASH[8]; + bus_CPTRA_OWNER_PK_HASH8_cp : coverpoint bus_event[8] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + CPTRA_OWNER_PK_HASH9_cp : coverpoint i_soc_ifc_reg.field_storage.CPTRA_OWNER_PK_HASH[9]; + bus_CPTRA_OWNER_PK_HASH9_cp : coverpoint bus_event[9] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + CPTRA_OWNER_PK_HASH10_cp : coverpoint i_soc_ifc_reg.field_storage.CPTRA_OWNER_PK_HASH[10]; + bus_CPTRA_OWNER_PK_HASH10_cp : coverpoint bus_event[10] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + CPTRA_OWNER_PK_HASH11_cp : coverpoint i_soc_ifc_reg.field_storage.CPTRA_OWNER_PK_HASH[11]; + bus_CPTRA_OWNER_PK_HASH11_cp : coverpoint bus_event[11] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP CPTRA_OWNER_PK_HASH_LOCK ----------------------- + covergroup soc_ifc_CPTRA_OWNER_PK_HASH_LOCK_cg (ref logic [3:0] bus_event) @(posedge clk); + CPTRA_OWNER_PK_HASH_LOCK_cp : coverpoint i_soc_ifc_reg.field_storage.CPTRA_OWNER_PK_HASH_LOCK; + bus_CPTRA_OWNER_PK_HASH_LOCK_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP fuse_uds_seed [0:15] ----------------------- + covergroup soc_ifc_fuse_uds_seed_cg (ref logic [3:0] bus_event[0:15]) @(posedge clk); + fuse_uds_seed0_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_uds_seed[0]; + bus_fuse_uds_seed0_cp : coverpoint bus_event[0] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + fuse_uds_seed1_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_uds_seed[1]; + bus_fuse_uds_seed1_cp : coverpoint bus_event[1] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + fuse_uds_seed2_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_uds_seed[2]; + bus_fuse_uds_seed2_cp : coverpoint bus_event[2] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + fuse_uds_seed3_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_uds_seed[3]; + bus_fuse_uds_seed3_cp : coverpoint bus_event[3] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + fuse_uds_seed4_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_uds_seed[4]; + bus_fuse_uds_seed4_cp : coverpoint bus_event[4] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + fuse_uds_seed5_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_uds_seed[5]; + bus_fuse_uds_seed5_cp : coverpoint bus_event[5] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + fuse_uds_seed6_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_uds_seed[6]; + bus_fuse_uds_seed6_cp : coverpoint bus_event[6] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + fuse_uds_seed7_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_uds_seed[7]; + bus_fuse_uds_seed7_cp : coverpoint bus_event[7] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + fuse_uds_seed8_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_uds_seed[8]; + bus_fuse_uds_seed8_cp : coverpoint bus_event[8] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + fuse_uds_seed9_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_uds_seed[9]; + bus_fuse_uds_seed9_cp : coverpoint bus_event[9] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + fuse_uds_seed10_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_uds_seed[10]; + bus_fuse_uds_seed10_cp : coverpoint bus_event[10] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + fuse_uds_seed11_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_uds_seed[11]; + bus_fuse_uds_seed11_cp : coverpoint bus_event[11] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + fuse_uds_seed12_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_uds_seed[12]; + bus_fuse_uds_seed12_cp : coverpoint bus_event[12] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + fuse_uds_seed13_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_uds_seed[13]; + bus_fuse_uds_seed13_cp : coverpoint bus_event[13] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + fuse_uds_seed14_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_uds_seed[14]; + bus_fuse_uds_seed14_cp : coverpoint bus_event[14] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + fuse_uds_seed15_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_uds_seed[15]; + bus_fuse_uds_seed15_cp : coverpoint bus_event[15] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP fuse_field_entropy [0:7] ----------------------- + covergroup soc_ifc_fuse_field_entropy_cg (ref logic [3:0] bus_event[0:7]) @(posedge clk); + fuse_field_entropy0_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_field_entropy[0]; + bus_fuse_field_entropy0_cp : coverpoint bus_event[0] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + fuse_field_entropy1_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_field_entropy[1]; + bus_fuse_field_entropy1_cp : coverpoint bus_event[1] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + fuse_field_entropy2_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_field_entropy[2]; + bus_fuse_field_entropy2_cp : coverpoint bus_event[2] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + fuse_field_entropy3_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_field_entropy[3]; + bus_fuse_field_entropy3_cp : coverpoint bus_event[3] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + fuse_field_entropy4_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_field_entropy[4]; + bus_fuse_field_entropy4_cp : coverpoint bus_event[4] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + fuse_field_entropy5_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_field_entropy[5]; + bus_fuse_field_entropy5_cp : coverpoint bus_event[5] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + fuse_field_entropy6_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_field_entropy[6]; + bus_fuse_field_entropy6_cp : coverpoint bus_event[6] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + fuse_field_entropy7_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_field_entropy[7]; + bus_fuse_field_entropy7_cp : coverpoint bus_event[7] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP fuse_vendor_pk_hash [0:11] ----------------------- + covergroup soc_ifc_fuse_vendor_pk_hash_cg (ref logic [3:0] bus_event[0:11]) @(posedge clk); + fuse_vendor_pk_hash0_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_vendor_pk_hash[0]; + bus_fuse_vendor_pk_hash0_cp : coverpoint bus_event[0] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + fuse_vendor_pk_hash1_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_vendor_pk_hash[1]; + bus_fuse_vendor_pk_hash1_cp : coverpoint bus_event[1] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + fuse_vendor_pk_hash2_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_vendor_pk_hash[2]; + bus_fuse_vendor_pk_hash2_cp : coverpoint bus_event[2] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + fuse_vendor_pk_hash3_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_vendor_pk_hash[3]; + bus_fuse_vendor_pk_hash3_cp : coverpoint bus_event[3] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + fuse_vendor_pk_hash4_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_vendor_pk_hash[4]; + bus_fuse_vendor_pk_hash4_cp : coverpoint bus_event[4] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + fuse_vendor_pk_hash5_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_vendor_pk_hash[5]; + bus_fuse_vendor_pk_hash5_cp : coverpoint bus_event[5] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + fuse_vendor_pk_hash6_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_vendor_pk_hash[6]; + bus_fuse_vendor_pk_hash6_cp : coverpoint bus_event[6] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + fuse_vendor_pk_hash7_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_vendor_pk_hash[7]; + bus_fuse_vendor_pk_hash7_cp : coverpoint bus_event[7] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + fuse_vendor_pk_hash8_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_vendor_pk_hash[8]; + bus_fuse_vendor_pk_hash8_cp : coverpoint bus_event[8] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + fuse_vendor_pk_hash9_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_vendor_pk_hash[9]; + bus_fuse_vendor_pk_hash9_cp : coverpoint bus_event[9] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + fuse_vendor_pk_hash10_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_vendor_pk_hash[10]; + bus_fuse_vendor_pk_hash10_cp : coverpoint bus_event[10] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + fuse_vendor_pk_hash11_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_vendor_pk_hash[11]; + bus_fuse_vendor_pk_hash11_cp : coverpoint bus_event[11] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP fuse_ecc_revocation ----------------------- + covergroup soc_ifc_fuse_ecc_revocation_cg (ref logic [3:0] bus_event) @(posedge clk); + fuse_ecc_revocation_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_ecc_revocation; + bus_fuse_ecc_revocation_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP fuse_fmc_key_manifest_svn ----------------------- + covergroup soc_ifc_fuse_fmc_key_manifest_svn_cg (ref logic [3:0] bus_event) @(posedge clk); + fuse_fmc_key_manifest_svn_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_fmc_key_manifest_svn; + bus_fuse_fmc_key_manifest_svn_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP fuse_runtime_svn [0:3] ----------------------- + covergroup soc_ifc_fuse_runtime_svn_cg (ref logic [3:0] bus_event[0:3]) @(posedge clk); + fuse_runtime_svn0_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_runtime_svn[0]; + bus_fuse_runtime_svn0_cp : coverpoint bus_event[0] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + fuse_runtime_svn1_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_runtime_svn[1]; + bus_fuse_runtime_svn1_cp : coverpoint bus_event[1] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + fuse_runtime_svn2_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_runtime_svn[2]; + bus_fuse_runtime_svn2_cp : coverpoint bus_event[2] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + fuse_runtime_svn3_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_runtime_svn[3]; + bus_fuse_runtime_svn3_cp : coverpoint bus_event[3] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP fuse_anti_rollback_disable ----------------------- + covergroup soc_ifc_fuse_anti_rollback_disable_cg (ref logic [3:0] bus_event) @(posedge clk); + fuse_anti_rollback_disable_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_anti_rollback_disable; + bus_fuse_anti_rollback_disable_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP fuse_idevid_cert_attr [0:23] ----------------------- + covergroup soc_ifc_fuse_idevid_cert_attr_cg (ref logic [3:0] bus_event[0:23]) @(posedge clk); + fuse_idevid_cert_attr0_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_idevid_cert_attr[0]; + bus_fuse_idevid_cert_attr0_cp : coverpoint bus_event[0] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + fuse_idevid_cert_attr1_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_idevid_cert_attr[1]; + bus_fuse_idevid_cert_attr1_cp : coverpoint bus_event[1] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + fuse_idevid_cert_attr2_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_idevid_cert_attr[2]; + bus_fuse_idevid_cert_attr2_cp : coverpoint bus_event[2] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + fuse_idevid_cert_attr3_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_idevid_cert_attr[3]; + bus_fuse_idevid_cert_attr3_cp : coverpoint bus_event[3] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + fuse_idevid_cert_attr4_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_idevid_cert_attr[4]; + bus_fuse_idevid_cert_attr4_cp : coverpoint bus_event[4] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + fuse_idevid_cert_attr5_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_idevid_cert_attr[5]; + bus_fuse_idevid_cert_attr5_cp : coverpoint bus_event[5] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + fuse_idevid_cert_attr6_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_idevid_cert_attr[6]; + bus_fuse_idevid_cert_attr6_cp : coverpoint bus_event[6] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + fuse_idevid_cert_attr7_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_idevid_cert_attr[7]; + bus_fuse_idevid_cert_attr7_cp : coverpoint bus_event[7] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + fuse_idevid_cert_attr8_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_idevid_cert_attr[8]; + bus_fuse_idevid_cert_attr8_cp : coverpoint bus_event[8] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + fuse_idevid_cert_attr9_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_idevid_cert_attr[9]; + bus_fuse_idevid_cert_attr9_cp : coverpoint bus_event[9] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + fuse_idevid_cert_attr10_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_idevid_cert_attr[10]; + bus_fuse_idevid_cert_attr10_cp : coverpoint bus_event[10] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + fuse_idevid_cert_attr11_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_idevid_cert_attr[11]; + bus_fuse_idevid_cert_attr11_cp : coverpoint bus_event[11] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + fuse_idevid_cert_attr12_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_idevid_cert_attr[12]; + bus_fuse_idevid_cert_attr12_cp : coverpoint bus_event[12] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + fuse_idevid_cert_attr13_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_idevid_cert_attr[13]; + bus_fuse_idevid_cert_attr13_cp : coverpoint bus_event[13] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + fuse_idevid_cert_attr14_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_idevid_cert_attr[14]; + bus_fuse_idevid_cert_attr14_cp : coverpoint bus_event[14] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + fuse_idevid_cert_attr15_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_idevid_cert_attr[15]; + bus_fuse_idevid_cert_attr15_cp : coverpoint bus_event[15] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + fuse_idevid_cert_attr16_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_idevid_cert_attr[16]; + bus_fuse_idevid_cert_attr16_cp : coverpoint bus_event[16] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + fuse_idevid_cert_attr17_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_idevid_cert_attr[17]; + bus_fuse_idevid_cert_attr17_cp : coverpoint bus_event[17] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + fuse_idevid_cert_attr18_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_idevid_cert_attr[18]; + bus_fuse_idevid_cert_attr18_cp : coverpoint bus_event[18] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + fuse_idevid_cert_attr19_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_idevid_cert_attr[19]; + bus_fuse_idevid_cert_attr19_cp : coverpoint bus_event[19] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + fuse_idevid_cert_attr20_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_idevid_cert_attr[20]; + bus_fuse_idevid_cert_attr20_cp : coverpoint bus_event[20] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + fuse_idevid_cert_attr21_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_idevid_cert_attr[21]; + bus_fuse_idevid_cert_attr21_cp : coverpoint bus_event[21] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + fuse_idevid_cert_attr22_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_idevid_cert_attr[22]; + bus_fuse_idevid_cert_attr22_cp : coverpoint bus_event[22] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + fuse_idevid_cert_attr23_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_idevid_cert_attr[23]; + bus_fuse_idevid_cert_attr23_cp : coverpoint bus_event[23] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP fuse_idevid_manuf_hsm_id [0:3] ----------------------- + covergroup soc_ifc_fuse_idevid_manuf_hsm_id_cg (ref logic [3:0] bus_event[0:3]) @(posedge clk); + fuse_idevid_manuf_hsm_id0_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_idevid_manuf_hsm_id[0]; + bus_fuse_idevid_manuf_hsm_id0_cp : coverpoint bus_event[0] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + fuse_idevid_manuf_hsm_id1_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_idevid_manuf_hsm_id[1]; + bus_fuse_idevid_manuf_hsm_id1_cp : coverpoint bus_event[1] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + fuse_idevid_manuf_hsm_id2_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_idevid_manuf_hsm_id[2]; + bus_fuse_idevid_manuf_hsm_id2_cp : coverpoint bus_event[2] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + fuse_idevid_manuf_hsm_id3_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_idevid_manuf_hsm_id[3]; + bus_fuse_idevid_manuf_hsm_id3_cp : coverpoint bus_event[3] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP fuse_lms_revocation ----------------------- + covergroup soc_ifc_fuse_lms_revocation_cg (ref logic [3:0] bus_event) @(posedge clk); + fuse_lms_revocation_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_lms_revocation; + bus_fuse_lms_revocation_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP fuse_mldsa_revocation ----------------------- + covergroup soc_ifc_fuse_mldsa_revocation_cg (ref logic [3:0] bus_event) @(posedge clk); + fuse_mldsa_revocation_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_mldsa_revocation; + bus_fuse_mldsa_revocation_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP fuse_soc_stepping_id ----------------------- + covergroup soc_ifc_fuse_soc_stepping_id_cg (ref logic [3:0] bus_event) @(posedge clk); + fuse_soc_stepping_id_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_soc_stepping_id; + bus_fuse_soc_stepping_id_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP fuse_manuf_dbg_unlock_token [0:15] ----------------------- + covergroup soc_ifc_fuse_manuf_dbg_unlock_token_cg (ref logic [3:0] bus_event[0:15]) @(posedge clk); + fuse_manuf_dbg_unlock_token0_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_manuf_dbg_unlock_token[0]; + bus_fuse_manuf_dbg_unlock_token0_cp : coverpoint bus_event[0] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + fuse_manuf_dbg_unlock_token1_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_manuf_dbg_unlock_token[1]; + bus_fuse_manuf_dbg_unlock_token1_cp : coverpoint bus_event[1] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + fuse_manuf_dbg_unlock_token2_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_manuf_dbg_unlock_token[2]; + bus_fuse_manuf_dbg_unlock_token2_cp : coverpoint bus_event[2] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + fuse_manuf_dbg_unlock_token3_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_manuf_dbg_unlock_token[3]; + bus_fuse_manuf_dbg_unlock_token3_cp : coverpoint bus_event[3] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + fuse_manuf_dbg_unlock_token4_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_manuf_dbg_unlock_token[4]; + bus_fuse_manuf_dbg_unlock_token4_cp : coverpoint bus_event[4] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + fuse_manuf_dbg_unlock_token5_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_manuf_dbg_unlock_token[5]; + bus_fuse_manuf_dbg_unlock_token5_cp : coverpoint bus_event[5] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + fuse_manuf_dbg_unlock_token6_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_manuf_dbg_unlock_token[6]; + bus_fuse_manuf_dbg_unlock_token6_cp : coverpoint bus_event[6] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + fuse_manuf_dbg_unlock_token7_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_manuf_dbg_unlock_token[7]; + bus_fuse_manuf_dbg_unlock_token7_cp : coverpoint bus_event[7] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + fuse_manuf_dbg_unlock_token8_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_manuf_dbg_unlock_token[8]; + bus_fuse_manuf_dbg_unlock_token8_cp : coverpoint bus_event[8] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + fuse_manuf_dbg_unlock_token9_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_manuf_dbg_unlock_token[9]; + bus_fuse_manuf_dbg_unlock_token9_cp : coverpoint bus_event[9] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + fuse_manuf_dbg_unlock_token10_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_manuf_dbg_unlock_token[10]; + bus_fuse_manuf_dbg_unlock_token10_cp : coverpoint bus_event[10] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + fuse_manuf_dbg_unlock_token11_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_manuf_dbg_unlock_token[11]; + bus_fuse_manuf_dbg_unlock_token11_cp : coverpoint bus_event[11] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + fuse_manuf_dbg_unlock_token12_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_manuf_dbg_unlock_token[12]; + bus_fuse_manuf_dbg_unlock_token12_cp : coverpoint bus_event[12] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + fuse_manuf_dbg_unlock_token13_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_manuf_dbg_unlock_token[13]; + bus_fuse_manuf_dbg_unlock_token13_cp : coverpoint bus_event[13] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + fuse_manuf_dbg_unlock_token14_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_manuf_dbg_unlock_token[14]; + bus_fuse_manuf_dbg_unlock_token14_cp : coverpoint bus_event[14] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + fuse_manuf_dbg_unlock_token15_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_manuf_dbg_unlock_token[15]; + bus_fuse_manuf_dbg_unlock_token15_cp : coverpoint bus_event[15] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP fuse_pqc_key_type ----------------------- + covergroup soc_ifc_fuse_pqc_key_type_cg (ref logic [3:0] bus_event) @(posedge clk); + fuse_pqc_key_type_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_pqc_key_type; + bus_fuse_pqc_key_type_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP fuse_soc_manifest_svn [0:3] ----------------------- + covergroup soc_ifc_fuse_soc_manifest_svn_cg (ref logic [3:0] bus_event[0:3]) @(posedge clk); + fuse_soc_manifest_svn0_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_soc_manifest_svn[0]; + bus_fuse_soc_manifest_svn0_cp : coverpoint bus_event[0] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + fuse_soc_manifest_svn1_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_soc_manifest_svn[1]; + bus_fuse_soc_manifest_svn1_cp : coverpoint bus_event[1] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + fuse_soc_manifest_svn2_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_soc_manifest_svn[2]; + bus_fuse_soc_manifest_svn2_cp : coverpoint bus_event[2] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + fuse_soc_manifest_svn3_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_soc_manifest_svn[3]; + bus_fuse_soc_manifest_svn3_cp : coverpoint bus_event[3] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP fuse_soc_manifest_max_svn ----------------------- + covergroup soc_ifc_fuse_soc_manifest_max_svn_cg (ref logic [3:0] bus_event) @(posedge clk); + fuse_soc_manifest_max_svn_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_soc_manifest_max_svn; + bus_fuse_soc_manifest_max_svn_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP fuse_hek_seed [0:7] ----------------------- + covergroup soc_ifc_fuse_hek_seed_cg (ref logic [3:0] bus_event[0:7]) @(posedge clk); + fuse_hek_seed0_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_hek_seed[0]; + bus_fuse_hek_seed0_cp : coverpoint bus_event[0] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + fuse_hek_seed1_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_hek_seed[1]; + bus_fuse_hek_seed1_cp : coverpoint bus_event[1] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + fuse_hek_seed2_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_hek_seed[2]; + bus_fuse_hek_seed2_cp : coverpoint bus_event[2] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + fuse_hek_seed3_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_hek_seed[3]; + bus_fuse_hek_seed3_cp : coverpoint bus_event[3] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + fuse_hek_seed4_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_hek_seed[4]; + bus_fuse_hek_seed4_cp : coverpoint bus_event[4] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + fuse_hek_seed5_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_hek_seed[5]; + bus_fuse_hek_seed5_cp : coverpoint bus_event[5] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + fuse_hek_seed6_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_hek_seed[6]; + bus_fuse_hek_seed6_cp : coverpoint bus_event[6] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + fuse_hek_seed7_cp : coverpoint i_soc_ifc_reg.field_storage.fuse_hek_seed[7]; + bus_fuse_hek_seed7_cp : coverpoint bus_event[7] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP SS_CALIPTRA_BASE_ADDR_L ----------------------- + covergroup soc_ifc_SS_CALIPTRA_BASE_ADDR_L_cg (ref logic [3:0] bus_event) @(posedge clk); + SS_CALIPTRA_BASE_ADDR_L_cp : coverpoint i_soc_ifc_reg.field_storage.SS_CALIPTRA_BASE_ADDR_L; + bus_SS_CALIPTRA_BASE_ADDR_L_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP SS_CALIPTRA_BASE_ADDR_H ----------------------- + covergroup soc_ifc_SS_CALIPTRA_BASE_ADDR_H_cg (ref logic [3:0] bus_event) @(posedge clk); + SS_CALIPTRA_BASE_ADDR_H_cp : coverpoint i_soc_ifc_reg.field_storage.SS_CALIPTRA_BASE_ADDR_H; + bus_SS_CALIPTRA_BASE_ADDR_H_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP SS_MCI_BASE_ADDR_L ----------------------- + covergroup soc_ifc_SS_MCI_BASE_ADDR_L_cg (ref logic [3:0] bus_event) @(posedge clk); + SS_MCI_BASE_ADDR_L_cp : coverpoint i_soc_ifc_reg.field_storage.SS_MCI_BASE_ADDR_L; + bus_SS_MCI_BASE_ADDR_L_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP SS_MCI_BASE_ADDR_H ----------------------- + covergroup soc_ifc_SS_MCI_BASE_ADDR_H_cg (ref logic [3:0] bus_event) @(posedge clk); + SS_MCI_BASE_ADDR_H_cp : coverpoint i_soc_ifc_reg.field_storage.SS_MCI_BASE_ADDR_H; + bus_SS_MCI_BASE_ADDR_H_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP SS_RECOVERY_IFC_BASE_ADDR_L ----------------------- + covergroup soc_ifc_SS_RECOVERY_IFC_BASE_ADDR_L_cg (ref logic [3:0] bus_event) @(posedge clk); + SS_RECOVERY_IFC_BASE_ADDR_L_cp : coverpoint i_soc_ifc_reg.field_storage.SS_RECOVERY_IFC_BASE_ADDR_L; + bus_SS_RECOVERY_IFC_BASE_ADDR_L_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP SS_RECOVERY_IFC_BASE_ADDR_H ----------------------- + covergroup soc_ifc_SS_RECOVERY_IFC_BASE_ADDR_H_cg (ref logic [3:0] bus_event) @(posedge clk); + SS_RECOVERY_IFC_BASE_ADDR_H_cp : coverpoint i_soc_ifc_reg.field_storage.SS_RECOVERY_IFC_BASE_ADDR_H; + bus_SS_RECOVERY_IFC_BASE_ADDR_H_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP SS_OTP_FC_BASE_ADDR_L ----------------------- + covergroup soc_ifc_SS_OTP_FC_BASE_ADDR_L_cg (ref logic [3:0] bus_event) @(posedge clk); + SS_OTP_FC_BASE_ADDR_L_cp : coverpoint i_soc_ifc_reg.field_storage.SS_OTP_FC_BASE_ADDR_L; + bus_SS_OTP_FC_BASE_ADDR_L_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP SS_OTP_FC_BASE_ADDR_H ----------------------- + covergroup soc_ifc_SS_OTP_FC_BASE_ADDR_H_cg (ref logic [3:0] bus_event) @(posedge clk); + SS_OTP_FC_BASE_ADDR_H_cp : coverpoint i_soc_ifc_reg.field_storage.SS_OTP_FC_BASE_ADDR_H; + bus_SS_OTP_FC_BASE_ADDR_H_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP SS_UDS_SEED_BASE_ADDR_L ----------------------- + covergroup soc_ifc_SS_UDS_SEED_BASE_ADDR_L_cg (ref logic [3:0] bus_event) @(posedge clk); + SS_UDS_SEED_BASE_ADDR_L_cp : coverpoint i_soc_ifc_reg.field_storage.SS_UDS_SEED_BASE_ADDR_L; + bus_SS_UDS_SEED_BASE_ADDR_L_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP SS_UDS_SEED_BASE_ADDR_H ----------------------- + covergroup soc_ifc_SS_UDS_SEED_BASE_ADDR_H_cg (ref logic [3:0] bus_event) @(posedge clk); + SS_UDS_SEED_BASE_ADDR_H_cp : coverpoint i_soc_ifc_reg.field_storage.SS_UDS_SEED_BASE_ADDR_H; + bus_SS_UDS_SEED_BASE_ADDR_H_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP SS_PROD_DEBUG_UNLOCK_AUTH_PK_HASH_REG_BANK_OFFSET ----------------------- + covergroup soc_ifc_SS_PROD_DEBUG_UNLOCK_AUTH_PK_HASH_REG_BANK_OFFSET_cg (ref logic [3:0] bus_event) @(posedge clk); + SS_PROD_DEBUG_UNLOCK_AUTH_PK_HASH_REG_BANK_OFFSET_cp : coverpoint i_soc_ifc_reg.field_storage.SS_PROD_DEBUG_UNLOCK_AUTH_PK_HASH_REG_BANK_OFFSET; + bus_SS_PROD_DEBUG_UNLOCK_AUTH_PK_HASH_REG_BANK_OFFSET_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP SS_NUM_OF_PROD_DEBUG_UNLOCK_AUTH_PK_HASHES ----------------------- + covergroup soc_ifc_SS_NUM_OF_PROD_DEBUG_UNLOCK_AUTH_PK_HASHES_cg (ref logic [3:0] bus_event) @(posedge clk); + SS_NUM_OF_PROD_DEBUG_UNLOCK_AUTH_PK_HASHES_cp : coverpoint i_soc_ifc_reg.field_storage.SS_NUM_OF_PROD_DEBUG_UNLOCK_AUTH_PK_HASHES; + bus_SS_NUM_OF_PROD_DEBUG_UNLOCK_AUTH_PK_HASHES_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP SS_DEBUG_INTENT ----------------------- + covergroup soc_ifc_SS_DEBUG_INTENT_cg (ref logic [3:0] bus_event) @(posedge clk); + SS_DEBUG_INTENT_cp : coverpoint i_soc_ifc_reg.field_storage.SS_DEBUG_INTENT; + bus_SS_DEBUG_INTENT_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP SS_CALIPTRA_DMA_AXI_USER ----------------------- + covergroup soc_ifc_SS_CALIPTRA_DMA_AXI_USER_cg (ref logic [3:0] bus_event) @(posedge clk); + SS_CALIPTRA_DMA_AXI_USER_cp : coverpoint i_soc_ifc_reg.field_storage.SS_CALIPTRA_DMA_AXI_USER; + bus_SS_CALIPTRA_DMA_AXI_USER_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP SS_EXTERNAL_STAGING_AREA_BASE_ADDR_L ----------------------- + covergroup soc_ifc_SS_EXTERNAL_STAGING_AREA_BASE_ADDR_L_cg (ref logic [3:0] bus_event) @(posedge clk); + SS_EXTERNAL_STAGING_AREA_BASE_ADDR_L_cp : coverpoint i_soc_ifc_reg.field_storage.SS_EXTERNAL_STAGING_AREA_BASE_ADDR_L; + bus_SS_EXTERNAL_STAGING_AREA_BASE_ADDR_L_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP SS_EXTERNAL_STAGING_AREA_BASE_ADDR_H ----------------------- + covergroup soc_ifc_SS_EXTERNAL_STAGING_AREA_BASE_ADDR_H_cg (ref logic [3:0] bus_event) @(posedge clk); + SS_EXTERNAL_STAGING_AREA_BASE_ADDR_H_cp : coverpoint i_soc_ifc_reg.field_storage.SS_EXTERNAL_STAGING_AREA_BASE_ADDR_H; + bus_SS_EXTERNAL_STAGING_AREA_BASE_ADDR_H_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP SS_KEY_RELEASE_BASE_ADDR_L ----------------------- + covergroup soc_ifc_SS_KEY_RELEASE_BASE_ADDR_L_cg (ref logic [3:0] bus_event) @(posedge clk); + SS_KEY_RELEASE_BASE_ADDR_L_cp : coverpoint i_soc_ifc_reg.field_storage.SS_KEY_RELEASE_BASE_ADDR_L; + bus_SS_KEY_RELEASE_BASE_ADDR_L_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP SS_KEY_RELEASE_BASE_ADDR_H ----------------------- + covergroup soc_ifc_SS_KEY_RELEASE_BASE_ADDR_H_cg (ref logic [3:0] bus_event) @(posedge clk); + SS_KEY_RELEASE_BASE_ADDR_H_cp : coverpoint i_soc_ifc_reg.field_storage.SS_KEY_RELEASE_BASE_ADDR_H; + bus_SS_KEY_RELEASE_BASE_ADDR_H_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP SS_KEY_RELEASE_SIZE ----------------------- + covergroup soc_ifc_SS_KEY_RELEASE_SIZE_cg (ref logic [3:0] bus_event) @(posedge clk); + SS_KEY_RELEASE_SIZE_cp : coverpoint i_soc_ifc_reg.field_storage.SS_KEY_RELEASE_SIZE; + bus_SS_KEY_RELEASE_SIZE_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP SS_OCP_LOCK_CTRL ----------------------- + covergroup soc_ifc_SS_OCP_LOCK_CTRL_cg (ref logic [3:0] bus_event) @(posedge clk); + SS_OCP_LOCK_CTRL_cp : coverpoint i_soc_ifc_reg.field_storage.SS_OCP_LOCK_CTRL; + bus_SS_OCP_LOCK_CTRL_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP SS_STRAP_GENERIC [0:3] ----------------------- + covergroup soc_ifc_SS_STRAP_GENERIC_cg (ref logic [3:0] bus_event[0:3]) @(posedge clk); + SS_STRAP_GENERIC0_cp : coverpoint i_soc_ifc_reg.field_storage.SS_STRAP_GENERIC[0]; + bus_SS_STRAP_GENERIC0_cp : coverpoint bus_event[0] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + SS_STRAP_GENERIC1_cp : coverpoint i_soc_ifc_reg.field_storage.SS_STRAP_GENERIC[1]; + bus_SS_STRAP_GENERIC1_cp : coverpoint bus_event[1] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + SS_STRAP_GENERIC2_cp : coverpoint i_soc_ifc_reg.field_storage.SS_STRAP_GENERIC[2]; + bus_SS_STRAP_GENERIC2_cp : coverpoint bus_event[2] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + SS_STRAP_GENERIC3_cp : coverpoint i_soc_ifc_reg.field_storage.SS_STRAP_GENERIC[3]; + bus_SS_STRAP_GENERIC3_cp : coverpoint bus_event[3] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP SS_DBG_SERVICE_REG_REQ ----------------------- + covergroup soc_ifc_SS_DBG_SERVICE_REG_REQ_cg (ref logic [3:0] bus_event) @(posedge clk); + SS_DBG_SERVICE_REG_REQ_cp : coverpoint i_soc_ifc_reg.field_storage.SS_DBG_SERVICE_REG_REQ; + bus_SS_DBG_SERVICE_REG_REQ_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP SS_DBG_SERVICE_REG_RSP ----------------------- + covergroup soc_ifc_SS_DBG_SERVICE_REG_RSP_cg (ref logic [3:0] bus_event) @(posedge clk); + SS_DBG_SERVICE_REG_RSP_cp : coverpoint i_soc_ifc_reg.field_storage.SS_DBG_SERVICE_REG_RSP; + bus_SS_DBG_SERVICE_REG_RSP_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP SS_SOC_DBG_UNLOCK_LEVEL [0:1] ----------------------- + covergroup soc_ifc_SS_SOC_DBG_UNLOCK_LEVEL_cg (ref logic [3:0] bus_event[0:1]) @(posedge clk); + SS_SOC_DBG_UNLOCK_LEVEL0_cp : coverpoint i_soc_ifc_reg.field_storage.SS_SOC_DBG_UNLOCK_LEVEL[0]; + bus_SS_SOC_DBG_UNLOCK_LEVEL0_cp : coverpoint bus_event[0] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + SS_SOC_DBG_UNLOCK_LEVEL1_cp : coverpoint i_soc_ifc_reg.field_storage.SS_SOC_DBG_UNLOCK_LEVEL[1]; + bus_SS_SOC_DBG_UNLOCK_LEVEL1_cp : coverpoint bus_event[1] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP SS_GENERIC_FW_EXEC_CTRL [0:3] ----------------------- + covergroup soc_ifc_SS_GENERIC_FW_EXEC_CTRL_cg (ref logic [3:0] bus_event[0:3]) @(posedge clk); + SS_GENERIC_FW_EXEC_CTRL0_cp : coverpoint i_soc_ifc_reg.field_storage.SS_GENERIC_FW_EXEC_CTRL[0]; + bus_SS_GENERIC_FW_EXEC_CTRL0_cp : coverpoint bus_event[0] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + SS_GENERIC_FW_EXEC_CTRL1_cp : coverpoint i_soc_ifc_reg.field_storage.SS_GENERIC_FW_EXEC_CTRL[1]; + bus_SS_GENERIC_FW_EXEC_CTRL1_cp : coverpoint bus_event[1] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + SS_GENERIC_FW_EXEC_CTRL2_cp : coverpoint i_soc_ifc_reg.field_storage.SS_GENERIC_FW_EXEC_CTRL[2]; + bus_SS_GENERIC_FW_EXEC_CTRL2_cp : coverpoint bus_event[2] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + SS_GENERIC_FW_EXEC_CTRL3_cp : coverpoint i_soc_ifc_reg.field_storage.SS_GENERIC_FW_EXEC_CTRL[3]; + bus_SS_GENERIC_FW_EXEC_CTRL3_cp : coverpoint bus_event[3] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP internal_obf_key [0:7] ----------------------- + covergroup soc_ifc_internal_obf_key_cg (ref logic [3:0] bus_event[0:7]) @(posedge clk); + internal_obf_key0_cp : coverpoint i_soc_ifc_reg.field_storage.internal_obf_key[0]; + bus_internal_obf_key0_cp : coverpoint bus_event[0] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + internal_obf_key1_cp : coverpoint i_soc_ifc_reg.field_storage.internal_obf_key[1]; + bus_internal_obf_key1_cp : coverpoint bus_event[1] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + internal_obf_key2_cp : coverpoint i_soc_ifc_reg.field_storage.internal_obf_key[2]; + bus_internal_obf_key2_cp : coverpoint bus_event[2] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + internal_obf_key3_cp : coverpoint i_soc_ifc_reg.field_storage.internal_obf_key[3]; + bus_internal_obf_key3_cp : coverpoint bus_event[3] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + internal_obf_key4_cp : coverpoint i_soc_ifc_reg.field_storage.internal_obf_key[4]; + bus_internal_obf_key4_cp : coverpoint bus_event[4] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + internal_obf_key5_cp : coverpoint i_soc_ifc_reg.field_storage.internal_obf_key[5]; + bus_internal_obf_key5_cp : coverpoint bus_event[5] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + internal_obf_key6_cp : coverpoint i_soc_ifc_reg.field_storage.internal_obf_key[6]; + bus_internal_obf_key6_cp : coverpoint bus_event[6] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + internal_obf_key7_cp : coverpoint i_soc_ifc_reg.field_storage.internal_obf_key[7]; + bus_internal_obf_key7_cp : coverpoint bus_event[7] { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP internal_iccm_lock ----------------------- + covergroup soc_ifc_internal_iccm_lock_cg (ref logic [3:0] bus_event) @(posedge clk); + internal_iccm_lock_cp : coverpoint i_soc_ifc_reg.field_storage.internal_iccm_lock; + bus_internal_iccm_lock_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP internal_fw_update_reset ----------------------- + covergroup soc_ifc_internal_fw_update_reset_cg (ref logic [3:0] bus_event) @(posedge clk); + internal_fw_update_reset_cp : coverpoint i_soc_ifc_reg.field_storage.internal_fw_update_reset; + bus_internal_fw_update_reset_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP internal_fw_update_reset_wait_cycles ----------------------- + covergroup soc_ifc_internal_fw_update_reset_wait_cycles_cg (ref logic [3:0] bus_event) @(posedge clk); + internal_fw_update_reset_wait_cycles_cp : coverpoint i_soc_ifc_reg.field_storage.internal_fw_update_reset_wait_cycles; + bus_internal_fw_update_reset_wait_cycles_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP internal_nmi_vector ----------------------- + covergroup soc_ifc_internal_nmi_vector_cg (ref logic [3:0] bus_event) @(posedge clk); + internal_nmi_vector_cp : coverpoint i_soc_ifc_reg.field_storage.internal_nmi_vector; + bus_internal_nmi_vector_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP internal_hw_error_fatal_mask ----------------------- + covergroup soc_ifc_internal_hw_error_fatal_mask_cg (ref logic [3:0] bus_event) @(posedge clk); + internal_hw_error_fatal_mask_cp : coverpoint i_soc_ifc_reg.field_storage.internal_hw_error_fatal_mask; + bus_internal_hw_error_fatal_mask_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP internal_hw_error_non_fatal_mask ----------------------- + covergroup soc_ifc_internal_hw_error_non_fatal_mask_cg (ref logic [3:0] bus_event) @(posedge clk); + internal_hw_error_non_fatal_mask_cp : coverpoint i_soc_ifc_reg.field_storage.internal_hw_error_non_fatal_mask; + bus_internal_hw_error_non_fatal_mask_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP internal_fw_error_fatal_mask ----------------------- + covergroup soc_ifc_internal_fw_error_fatal_mask_cg (ref logic [3:0] bus_event) @(posedge clk); + internal_fw_error_fatal_mask_cp : coverpoint i_soc_ifc_reg.field_storage.internal_fw_error_fatal_mask; + bus_internal_fw_error_fatal_mask_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP internal_fw_error_non_fatal_mask ----------------------- + covergroup soc_ifc_internal_fw_error_non_fatal_mask_cg (ref logic [3:0] bus_event) @(posedge clk); + internal_fw_error_non_fatal_mask_cp : coverpoint i_soc_ifc_reg.field_storage.internal_fw_error_non_fatal_mask; + bus_internal_fw_error_non_fatal_mask_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP internal_rv_mtime_l ----------------------- + covergroup soc_ifc_internal_rv_mtime_l_cg (ref logic [3:0] bus_event) @(posedge clk); + internal_rv_mtime_l_cp : coverpoint i_soc_ifc_reg.field_storage.internal_rv_mtime_l; + bus_internal_rv_mtime_l_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP internal_rv_mtime_h ----------------------- + covergroup soc_ifc_internal_rv_mtime_h_cg (ref logic [3:0] bus_event) @(posedge clk); + internal_rv_mtime_h_cp : coverpoint i_soc_ifc_reg.field_storage.internal_rv_mtime_h; + bus_internal_rv_mtime_h_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP internal_rv_mtimecmp_l ----------------------- + covergroup soc_ifc_internal_rv_mtimecmp_l_cg (ref logic [3:0] bus_event) @(posedge clk); + internal_rv_mtimecmp_l_cp : coverpoint i_soc_ifc_reg.field_storage.internal_rv_mtimecmp_l; + bus_internal_rv_mtimecmp_l_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP internal_rv_mtimecmp_h ----------------------- + covergroup soc_ifc_internal_rv_mtimecmp_h_cg (ref logic [3:0] bus_event) @(posedge clk); + internal_rv_mtimecmp_h_cp : coverpoint i_soc_ifc_reg.field_storage.internal_rv_mtimecmp_h; + bus_internal_rv_mtimecmp_h_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP intr_brf_global_intr_en_r ----------------------- + covergroup soc_ifc_intr_brf_global_intr_en_r_cg (ref logic [3:0] bus_event) @(posedge clk); + intr_brf_global_intr_en_r_cp : coverpoint i_soc_ifc_reg.field_storage.intr_block_rf.global_intr_en_r; + bus_intr_brf_global_intr_en_r_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP intr_brf_error_intr_en_r ----------------------- + covergroup soc_ifc_intr_brf_error_intr_en_r_cg (ref logic [3:0] bus_event) @(posedge clk); + intr_brf_error_intr_en_r_cp : coverpoint i_soc_ifc_reg.field_storage.intr_block_rf.error_intr_en_r; + bus_intr_brf_error_intr_en_r_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP intr_brf_notif_intr_en_r ----------------------- + covergroup soc_ifc_intr_brf_notif_intr_en_r_cg (ref logic [3:0] bus_event) @(posedge clk); + intr_brf_notif_intr_en_r_cp : coverpoint i_soc_ifc_reg.field_storage.intr_block_rf.notif_intr_en_r; + bus_intr_brf_notif_intr_en_r_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP intr_brf_error_global_intr_r ----------------------- + covergroup soc_ifc_intr_brf_error_global_intr_r_cg (ref logic [3:0] bus_event) @(posedge clk); + intr_brf_error_global_intr_r_cp : coverpoint i_soc_ifc_reg.field_storage.intr_block_rf.error_global_intr_r; + bus_intr_brf_error_global_intr_r_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP intr_brf_notif_global_intr_r ----------------------- + covergroup soc_ifc_intr_brf_notif_global_intr_r_cg (ref logic [3:0] bus_event) @(posedge clk); + intr_brf_notif_global_intr_r_cp : coverpoint i_soc_ifc_reg.field_storage.intr_block_rf.notif_global_intr_r; + bus_intr_brf_notif_global_intr_r_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP intr_brf_error_internal_intr_r ----------------------- + covergroup soc_ifc_intr_brf_error_internal_intr_r_cg (ref logic [3:0] bus_event) @(posedge clk); + intr_brf_error_internal_intr_r_cp : coverpoint i_soc_ifc_reg.field_storage.intr_block_rf.error_internal_intr_r; + bus_intr_brf_error_internal_intr_r_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP intr_brf_notif_internal_intr_r ----------------------- + covergroup soc_ifc_intr_brf_notif_internal_intr_r_cg (ref logic [3:0] bus_event) @(posedge clk); + intr_brf_notif_internal_intr_r_cp : coverpoint i_soc_ifc_reg.field_storage.intr_block_rf.notif_internal_intr_r; + bus_intr_brf_notif_internal_intr_r_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP intr_brf_error_intr_trig_r ----------------------- + covergroup soc_ifc_intr_brf_error_intr_trig_r_cg (ref logic [3:0] bus_event) @(posedge clk); + intr_brf_error_intr_trig_r_cp : coverpoint i_soc_ifc_reg.field_storage.intr_block_rf.error_intr_trig_r; + bus_intr_brf_error_intr_trig_r_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP intr_brf_notif_intr_trig_r ----------------------- + covergroup soc_ifc_intr_brf_notif_intr_trig_r_cg (ref logic [3:0] bus_event) @(posedge clk); + intr_brf_notif_intr_trig_r_cp : coverpoint i_soc_ifc_reg.field_storage.intr_block_rf.notif_intr_trig_r; + bus_intr_brf_notif_intr_trig_r_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP intr_brf_error_internal_intr_count_r ----------------------- + covergroup soc_ifc_intr_brf_error_internal_intr_count_r_cg (ref logic [3:0] bus_event) @(posedge clk); + intr_brf_error_internal_intr_count_r_cp : coverpoint i_soc_ifc_reg.field_storage.intr_block_rf.error_internal_intr_count_r; + bus_intr_brf_error_internal_intr_count_r_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP intr_brf_error_inv_dev_intr_count_r ----------------------- + covergroup soc_ifc_intr_brf_error_inv_dev_intr_count_r_cg (ref logic [3:0] bus_event) @(posedge clk); + intr_brf_error_inv_dev_intr_count_r_cp : coverpoint i_soc_ifc_reg.field_storage.intr_block_rf.error_inv_dev_intr_count_r; + bus_intr_brf_error_inv_dev_intr_count_r_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP intr_brf_error_cmd_fail_intr_count_r ----------------------- + covergroup soc_ifc_intr_brf_error_cmd_fail_intr_count_r_cg (ref logic [3:0] bus_event) @(posedge clk); + intr_brf_error_cmd_fail_intr_count_r_cp : coverpoint i_soc_ifc_reg.field_storage.intr_block_rf.error_cmd_fail_intr_count_r; + bus_intr_brf_error_cmd_fail_intr_count_r_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP intr_brf_error_bad_fuse_intr_count_r ----------------------- + covergroup soc_ifc_intr_brf_error_bad_fuse_intr_count_r_cg (ref logic [3:0] bus_event) @(posedge clk); + intr_brf_error_bad_fuse_intr_count_r_cp : coverpoint i_soc_ifc_reg.field_storage.intr_block_rf.error_bad_fuse_intr_count_r; + bus_intr_brf_error_bad_fuse_intr_count_r_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP intr_brf_error_iccm_blocked_intr_count_r ----------------------- + covergroup soc_ifc_intr_brf_error_iccm_blocked_intr_count_r_cg (ref logic [3:0] bus_event) @(posedge clk); + intr_brf_error_iccm_blocked_intr_count_r_cp : coverpoint i_soc_ifc_reg.field_storage.intr_block_rf.error_iccm_blocked_intr_count_r; + bus_intr_brf_error_iccm_blocked_intr_count_r_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP intr_brf_error_mbox_ecc_unc_intr_count_r ----------------------- + covergroup soc_ifc_intr_brf_error_mbox_ecc_unc_intr_count_r_cg (ref logic [3:0] bus_event) @(posedge clk); + intr_brf_error_mbox_ecc_unc_intr_count_r_cp : coverpoint i_soc_ifc_reg.field_storage.intr_block_rf.error_mbox_ecc_unc_intr_count_r; + bus_intr_brf_error_mbox_ecc_unc_intr_count_r_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP intr_brf_error_wdt_timer1_timeout_intr_count_r ----------------------- + covergroup soc_ifc_intr_brf_error_wdt_timer1_timeout_intr_count_r_cg (ref logic [3:0] bus_event) @(posedge clk); + intr_brf_error_wdt_timer1_timeout_intr_count_r_cp : coverpoint i_soc_ifc_reg.field_storage.intr_block_rf.error_wdt_timer1_timeout_intr_count_r; + bus_intr_brf_error_wdt_timer1_timeout_intr_count_r_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP intr_brf_error_wdt_timer2_timeout_intr_count_r ----------------------- + covergroup soc_ifc_intr_brf_error_wdt_timer2_timeout_intr_count_r_cg (ref logic [3:0] bus_event) @(posedge clk); + intr_brf_error_wdt_timer2_timeout_intr_count_r_cp : coverpoint i_soc_ifc_reg.field_storage.intr_block_rf.error_wdt_timer2_timeout_intr_count_r; + bus_intr_brf_error_wdt_timer2_timeout_intr_count_r_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP intr_brf_notif_cmd_avail_intr_count_r ----------------------- + covergroup soc_ifc_intr_brf_notif_cmd_avail_intr_count_r_cg (ref logic [3:0] bus_event) @(posedge clk); + intr_brf_notif_cmd_avail_intr_count_r_cp : coverpoint i_soc_ifc_reg.field_storage.intr_block_rf.notif_cmd_avail_intr_count_r; + bus_intr_brf_notif_cmd_avail_intr_count_r_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP intr_brf_notif_mbox_ecc_cor_intr_count_r ----------------------- + covergroup soc_ifc_intr_brf_notif_mbox_ecc_cor_intr_count_r_cg (ref logic [3:0] bus_event) @(posedge clk); + intr_brf_notif_mbox_ecc_cor_intr_count_r_cp : coverpoint i_soc_ifc_reg.field_storage.intr_block_rf.notif_mbox_ecc_cor_intr_count_r; + bus_intr_brf_notif_mbox_ecc_cor_intr_count_r_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP intr_brf_notif_debug_locked_intr_count_r ----------------------- + covergroup soc_ifc_intr_brf_notif_debug_locked_intr_count_r_cg (ref logic [3:0] bus_event) @(posedge clk); + intr_brf_notif_debug_locked_intr_count_r_cp : coverpoint i_soc_ifc_reg.field_storage.intr_block_rf.notif_debug_locked_intr_count_r; + bus_intr_brf_notif_debug_locked_intr_count_r_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP intr_brf_notif_scan_mode_intr_count_r ----------------------- + covergroup soc_ifc_intr_brf_notif_scan_mode_intr_count_r_cg (ref logic [3:0] bus_event) @(posedge clk); + intr_brf_notif_scan_mode_intr_count_r_cp : coverpoint i_soc_ifc_reg.field_storage.intr_block_rf.notif_scan_mode_intr_count_r; + bus_intr_brf_notif_scan_mode_intr_count_r_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP intr_brf_notif_soc_req_lock_intr_count_r ----------------------- + covergroup soc_ifc_intr_brf_notif_soc_req_lock_intr_count_r_cg (ref logic [3:0] bus_event) @(posedge clk); + intr_brf_notif_soc_req_lock_intr_count_r_cp : coverpoint i_soc_ifc_reg.field_storage.intr_block_rf.notif_soc_req_lock_intr_count_r; + bus_intr_brf_notif_soc_req_lock_intr_count_r_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP intr_brf_notif_gen_in_toggle_intr_count_r ----------------------- + covergroup soc_ifc_intr_brf_notif_gen_in_toggle_intr_count_r_cg (ref logic [3:0] bus_event) @(posedge clk); + intr_brf_notif_gen_in_toggle_intr_count_r_cp : coverpoint i_soc_ifc_reg.field_storage.intr_block_rf.notif_gen_in_toggle_intr_count_r; + bus_intr_brf_notif_gen_in_toggle_intr_count_r_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP intr_brf_error_internal_intr_count_incr_r ----------------------- + covergroup soc_ifc_intr_brf_error_internal_intr_count_incr_r_cg (ref logic [3:0] bus_event) @(posedge clk); + intr_brf_error_internal_intr_count_incr_r_cp : coverpoint i_soc_ifc_reg.field_storage.intr_block_rf.error_internal_intr_count_incr_r; + bus_intr_brf_error_internal_intr_count_incr_r_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP intr_brf_error_inv_dev_intr_count_incr_r ----------------------- + covergroup soc_ifc_intr_brf_error_inv_dev_intr_count_incr_r_cg (ref logic [3:0] bus_event) @(posedge clk); + intr_brf_error_inv_dev_intr_count_incr_r_cp : coverpoint i_soc_ifc_reg.field_storage.intr_block_rf.error_inv_dev_intr_count_incr_r; + bus_intr_brf_error_inv_dev_intr_count_incr_r_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP intr_brf_error_cmd_fail_intr_count_incr_r ----------------------- + covergroup soc_ifc_intr_brf_error_cmd_fail_intr_count_incr_r_cg (ref logic [3:0] bus_event) @(posedge clk); + intr_brf_error_cmd_fail_intr_count_incr_r_cp : coverpoint i_soc_ifc_reg.field_storage.intr_block_rf.error_cmd_fail_intr_count_incr_r; + bus_intr_brf_error_cmd_fail_intr_count_incr_r_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP intr_brf_error_bad_fuse_intr_count_incr_r ----------------------- + covergroup soc_ifc_intr_brf_error_bad_fuse_intr_count_incr_r_cg (ref logic [3:0] bus_event) @(posedge clk); + intr_brf_error_bad_fuse_intr_count_incr_r_cp : coverpoint i_soc_ifc_reg.field_storage.intr_block_rf.error_bad_fuse_intr_count_incr_r; + bus_intr_brf_error_bad_fuse_intr_count_incr_r_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP intr_brf_error_iccm_blocked_intr_count_incr_r ----------------------- + covergroup soc_ifc_intr_brf_error_iccm_blocked_intr_count_incr_r_cg (ref logic [3:0] bus_event) @(posedge clk); + intr_brf_error_iccm_blocked_intr_count_incr_r_cp : coverpoint i_soc_ifc_reg.field_storage.intr_block_rf.error_iccm_blocked_intr_count_incr_r; + bus_intr_brf_error_iccm_blocked_intr_count_incr_r_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP intr_brf_error_mbox_ecc_unc_intr_count_incr_r ----------------------- + covergroup soc_ifc_intr_brf_error_mbox_ecc_unc_intr_count_incr_r_cg (ref logic [3:0] bus_event) @(posedge clk); + intr_brf_error_mbox_ecc_unc_intr_count_incr_r_cp : coverpoint i_soc_ifc_reg.field_storage.intr_block_rf.error_mbox_ecc_unc_intr_count_incr_r; + bus_intr_brf_error_mbox_ecc_unc_intr_count_incr_r_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP intr_brf_error_wdt_timer1_timeout_intr_count_incr_r ----------------------- + covergroup soc_ifc_intr_brf_error_wdt_timer1_timeout_intr_count_incr_r_cg (ref logic [3:0] bus_event) @(posedge clk); + intr_brf_error_wdt_timer1_timeout_intr_count_incr_r_cp : coverpoint i_soc_ifc_reg.field_storage.intr_block_rf.error_wdt_timer1_timeout_intr_count_incr_r; + bus_intr_brf_error_wdt_timer1_timeout_intr_count_incr_r_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP intr_brf_error_wdt_timer2_timeout_intr_count_incr_r ----------------------- + covergroup soc_ifc_intr_brf_error_wdt_timer2_timeout_intr_count_incr_r_cg (ref logic [3:0] bus_event) @(posedge clk); + intr_brf_error_wdt_timer2_timeout_intr_count_incr_r_cp : coverpoint i_soc_ifc_reg.field_storage.intr_block_rf.error_wdt_timer2_timeout_intr_count_incr_r; + bus_intr_brf_error_wdt_timer2_timeout_intr_count_incr_r_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP intr_brf_notif_cmd_avail_intr_count_incr_r ----------------------- + covergroup soc_ifc_intr_brf_notif_cmd_avail_intr_count_incr_r_cg (ref logic [3:0] bus_event) @(posedge clk); + intr_brf_notif_cmd_avail_intr_count_incr_r_cp : coverpoint i_soc_ifc_reg.field_storage.intr_block_rf.notif_cmd_avail_intr_count_incr_r; + bus_intr_brf_notif_cmd_avail_intr_count_incr_r_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP intr_brf_notif_mbox_ecc_cor_intr_count_incr_r ----------------------- + covergroup soc_ifc_intr_brf_notif_mbox_ecc_cor_intr_count_incr_r_cg (ref logic [3:0] bus_event) @(posedge clk); + intr_brf_notif_mbox_ecc_cor_intr_count_incr_r_cp : coverpoint i_soc_ifc_reg.field_storage.intr_block_rf.notif_mbox_ecc_cor_intr_count_incr_r; + bus_intr_brf_notif_mbox_ecc_cor_intr_count_incr_r_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP intr_brf_notif_debug_locked_intr_count_incr_r ----------------------- + covergroup soc_ifc_intr_brf_notif_debug_locked_intr_count_incr_r_cg (ref logic [3:0] bus_event) @(posedge clk); + intr_brf_notif_debug_locked_intr_count_incr_r_cp : coverpoint i_soc_ifc_reg.field_storage.intr_block_rf.notif_debug_locked_intr_count_incr_r; + bus_intr_brf_notif_debug_locked_intr_count_incr_r_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP intr_brf_notif_scan_mode_intr_count_incr_r ----------------------- + covergroup soc_ifc_intr_brf_notif_scan_mode_intr_count_incr_r_cg (ref logic [3:0] bus_event) @(posedge clk); + intr_brf_notif_scan_mode_intr_count_incr_r_cp : coverpoint i_soc_ifc_reg.field_storage.intr_block_rf.notif_scan_mode_intr_count_incr_r; + bus_intr_brf_notif_scan_mode_intr_count_incr_r_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP intr_brf_notif_soc_req_lock_intr_count_incr_r ----------------------- + covergroup soc_ifc_intr_brf_notif_soc_req_lock_intr_count_incr_r_cg (ref logic [3:0] bus_event) @(posedge clk); + intr_brf_notif_soc_req_lock_intr_count_incr_r_cp : coverpoint i_soc_ifc_reg.field_storage.intr_block_rf.notif_soc_req_lock_intr_count_incr_r; + bus_intr_brf_notif_soc_req_lock_intr_count_incr_r_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + // ----------------------- COVERGROUP intr_brf_notif_gen_in_toggle_intr_count_incr_r ----------------------- + covergroup soc_ifc_intr_brf_notif_gen_in_toggle_intr_count_incr_r_cg (ref logic [3:0] bus_event) @(posedge clk); + intr_brf_notif_gen_in_toggle_intr_count_incr_r_cp : coverpoint i_soc_ifc_reg.field_storage.intr_block_rf.notif_gen_in_toggle_intr_count_incr_r; + bus_intr_brf_notif_gen_in_toggle_intr_count_incr_r_cp : coverpoint bus_event { + bins wr_rd[] = (AHB_WR, AXI_WR => IDLE [*1:1000] => AHB_RD, AXI_RD); + ignore_bins dont_care = {IDLE, 4'hf, (AXI_RD | AXI_WR), (AHB_RD | AHB_WR)}; + } + endgroup + + + // ----------------------- COVERGROUP Instantiations ----------------------- + + soc_ifc_CPTRA_HW_ERROR_FATAL_cg CPTRA_HW_ERROR_FATAL_cg = new(bus_CPTRA_HW_ERROR_FATAL); + soc_ifc_CPTRA_HW_ERROR_NON_FATAL_cg CPTRA_HW_ERROR_NON_FATAL_cg = new(bus_CPTRA_HW_ERROR_NON_FATAL); + soc_ifc_CPTRA_FW_ERROR_FATAL_cg CPTRA_FW_ERROR_FATAL_cg = new(bus_CPTRA_FW_ERROR_FATAL); + soc_ifc_CPTRA_FW_ERROR_NON_FATAL_cg CPTRA_FW_ERROR_NON_FATAL_cg = new(bus_CPTRA_FW_ERROR_NON_FATAL); + soc_ifc_CPTRA_HW_ERROR_ENC_cg CPTRA_HW_ERROR_ENC_cg = new(bus_CPTRA_HW_ERROR_ENC); + soc_ifc_CPTRA_FW_ERROR_ENC_cg CPTRA_FW_ERROR_ENC_cg = new(bus_CPTRA_FW_ERROR_ENC); + soc_ifc_CPTRA_FW_EXTENDED_ERROR_INFO_cg CPTRA_FW_EXTENDED_ERROR_INFO_cg = new(bus_CPTRA_FW_EXTENDED_ERROR_INFO); + soc_ifc_CPTRA_BOOT_STATUS_cg CPTRA_BOOT_STATUS_cg = new(bus_CPTRA_BOOT_STATUS); + soc_ifc_CPTRA_FLOW_STATUS_cg CPTRA_FLOW_STATUS_cg = new(bus_CPTRA_FLOW_STATUS); + soc_ifc_CPTRA_RESET_REASON_cg CPTRA_RESET_REASON_cg = new(bus_CPTRA_RESET_REASON); + // soc_ifc_CPTRA_SECURITY_STATE_cg CPTRA_SECURITY_STATE_cg = new(bus_CPTRA_SECURITY_STATE); + soc_ifc_CPTRA_MBOX_VALID_AXI_USER_cg CPTRA_MBOX_VALID_AXI_USER_cg = new(bus_CPTRA_MBOX_VALID_AXI_USER); + soc_ifc_CPTRA_MBOX_AXI_USER_LOCK_cg CPTRA_MBOX_AXI_USER_LOCK_cg = new(bus_CPTRA_MBOX_AXI_USER_LOCK); + soc_ifc_CPTRA_TRNG_VALID_AXI_USER_cg CPTRA_TRNG_VALID_AXI_USER_cg = new(bus_CPTRA_TRNG_VALID_AXI_USER); + soc_ifc_CPTRA_TRNG_AXI_USER_LOCK_cg CPTRA_TRNG_AXI_USER_LOCK_cg = new(bus_CPTRA_TRNG_AXI_USER_LOCK); + soc_ifc_CPTRA_TRNG_DATA_cg CPTRA_TRNG_DATA_cg = new(bus_CPTRA_TRNG_DATA); + soc_ifc_CPTRA_TRNG_CTRL_cg CPTRA_TRNG_CTRL_cg = new(bus_CPTRA_TRNG_CTRL); + soc_ifc_CPTRA_TRNG_STATUS_cg CPTRA_TRNG_STATUS_cg = new(bus_CPTRA_TRNG_STATUS); + soc_ifc_CPTRA_FUSE_WR_DONE_cg CPTRA_FUSE_WR_DONE_cg = new(bus_CPTRA_FUSE_WR_DONE); + soc_ifc_CPTRA_TIMER_CONFIG_cg CPTRA_TIMER_CONFIG_cg = new(bus_CPTRA_TIMER_CONFIG); + soc_ifc_CPTRA_BOOTFSM_GO_cg CPTRA_BOOTFSM_GO_cg = new(bus_CPTRA_BOOTFSM_GO); + soc_ifc_CPTRA_DBG_MANUF_SERVICE_REG_cg CPTRA_DBG_MANUF_SERVICE_REG_cg = new(bus_CPTRA_DBG_MANUF_SERVICE_REG); + soc_ifc_CPTRA_CLK_GATING_EN_cg CPTRA_CLK_GATING_EN_cg = new(bus_CPTRA_CLK_GATING_EN); + soc_ifc_CPTRA_GENERIC_INPUT_WIRES_cg CPTRA_GENERIC_INPUT_WIRES_cg = new(bus_CPTRA_GENERIC_INPUT_WIRES); + soc_ifc_CPTRA_GENERIC_OUTPUT_WIRES_cg CPTRA_GENERIC_OUTPUT_WIRES_cg = new(bus_CPTRA_GENERIC_OUTPUT_WIRES); + // soc_ifc_CPTRA_HW_REV_ID_cg CPTRA_HW_REV_ID_cg = new(bus_CPTRA_HW_REV_ID); + soc_ifc_CPTRA_FW_REV_ID_cg CPTRA_FW_REV_ID_cg = new(bus_CPTRA_FW_REV_ID); + // soc_ifc_CPTRA_HW_CONFIG_cg CPTRA_HW_CONFIG_cg = new(bus_CPTRA_HW_CONFIG); + soc_ifc_CPTRA_WDT_TIMER1_EN_cg CPTRA_WDT_TIMER1_EN_cg = new(bus_CPTRA_WDT_TIMER1_EN); + soc_ifc_CPTRA_WDT_TIMER1_CTRL_cg CPTRA_WDT_TIMER1_CTRL_cg = new(bus_CPTRA_WDT_TIMER1_CTRL); + soc_ifc_CPTRA_WDT_TIMER1_TIMEOUT_PERIOD_cg CPTRA_WDT_TIMER1_TIMEOUT_PERIOD_cg = new(bus_CPTRA_WDT_TIMER1_TIMEOUT_PERIOD); + soc_ifc_CPTRA_WDT_TIMER2_EN_cg CPTRA_WDT_TIMER2_EN_cg = new(bus_CPTRA_WDT_TIMER2_EN); + soc_ifc_CPTRA_WDT_TIMER2_CTRL_cg CPTRA_WDT_TIMER2_CTRL_cg = new(bus_CPTRA_WDT_TIMER2_CTRL); + soc_ifc_CPTRA_WDT_TIMER2_TIMEOUT_PERIOD_cg CPTRA_WDT_TIMER2_TIMEOUT_PERIOD_cg = new(bus_CPTRA_WDT_TIMER2_TIMEOUT_PERIOD); + soc_ifc_CPTRA_WDT_STATUS_cg CPTRA_WDT_STATUS_cg = new(bus_CPTRA_WDT_STATUS); + soc_ifc_CPTRA_FUSE_VALID_AXI_USER_cg CPTRA_FUSE_VALID_AXI_USER_cg = new(bus_CPTRA_FUSE_VALID_AXI_USER); + soc_ifc_CPTRA_FUSE_AXI_USER_LOCK_cg CPTRA_FUSE_AXI_USER_LOCK_cg = new(bus_CPTRA_FUSE_AXI_USER_LOCK); + soc_ifc_CPTRA_WDT_CFG_cg CPTRA_WDT_CFG_cg = new(bus_CPTRA_WDT_CFG); + soc_ifc_CPTRA_iTRNG_ENTROPY_CONFIG_0_cg CPTRA_iTRNG_ENTROPY_CONFIG_0_cg = new(bus_CPTRA_iTRNG_ENTROPY_CONFIG_0); + soc_ifc_CPTRA_iTRNG_ENTROPY_CONFIG_1_cg CPTRA_iTRNG_ENTROPY_CONFIG_1_cg = new(bus_CPTRA_iTRNG_ENTROPY_CONFIG_1); + soc_ifc_CPTRA_RSVD_REG_cg CPTRA_RSVD_REG_cg = new(bus_CPTRA_RSVD_REG); + soc_ifc_CPTRA_HW_CAPABILITIES_cg CPTRA_HW_CAPABILITIES_cg = new(bus_CPTRA_HW_CAPABILITIES); + soc_ifc_CPTRA_FW_CAPABILITIES_cg CPTRA_FW_CAPABILITIES_cg = new(bus_CPTRA_FW_CAPABILITIES); + soc_ifc_CPTRA_CAP_LOCK_cg CPTRA_CAP_LOCK_cg = new(bus_CPTRA_CAP_LOCK); + soc_ifc_CPTRA_OWNER_PK_HASH_cg CPTRA_OWNER_PK_HASH_cg = new(bus_CPTRA_OWNER_PK_HASH); + soc_ifc_CPTRA_OWNER_PK_HASH_LOCK_cg CPTRA_OWNER_PK_HASH_LOCK_cg = new(bus_CPTRA_OWNER_PK_HASH_LOCK); + soc_ifc_fuse_uds_seed_cg fuse_uds_seed_cg = new(bus_fuse_uds_seed); + soc_ifc_fuse_field_entropy_cg fuse_field_entropy_cg = new(bus_fuse_field_entropy); + soc_ifc_fuse_vendor_pk_hash_cg fuse_vendor_pk_hash_cg = new(bus_fuse_vendor_pk_hash); + soc_ifc_fuse_ecc_revocation_cg fuse_ecc_revocation_cg = new(bus_fuse_ecc_revocation); + soc_ifc_fuse_fmc_key_manifest_svn_cg fuse_fmc_key_manifest_svn_cg = new(bus_fuse_fmc_key_manifest_svn); + soc_ifc_fuse_runtime_svn_cg fuse_runtime_svn_cg = new(bus_fuse_runtime_svn); + soc_ifc_fuse_anti_rollback_disable_cg fuse_anti_rollback_disable_cg = new(bus_fuse_anti_rollback_disable); + soc_ifc_fuse_idevid_cert_attr_cg fuse_idevid_cert_attr_cg = new(bus_fuse_idevid_cert_attr); + soc_ifc_fuse_idevid_manuf_hsm_id_cg fuse_idevid_manuf_hsm_id_cg = new(bus_fuse_idevid_manuf_hsm_id); + soc_ifc_fuse_lms_revocation_cg fuse_lms_revocation_cg = new(bus_fuse_lms_revocation); + soc_ifc_fuse_mldsa_revocation_cg fuse_mldsa_revocation_cg = new(bus_fuse_mldsa_revocation); + soc_ifc_fuse_soc_stepping_id_cg fuse_soc_stepping_id_cg = new(bus_fuse_soc_stepping_id); + soc_ifc_fuse_manuf_dbg_unlock_token_cg fuse_manuf_dbg_unlock_token_cg = new(bus_fuse_manuf_dbg_unlock_token); + soc_ifc_fuse_pqc_key_type_cg fuse_pqc_key_type_cg = new(bus_fuse_pqc_key_type); + soc_ifc_fuse_soc_manifest_svn_cg fuse_soc_manifest_svn_cg = new(bus_fuse_soc_manifest_svn); + soc_ifc_fuse_soc_manifest_max_svn_cg fuse_soc_manifest_max_svn_cg = new(bus_fuse_soc_manifest_max_svn); + soc_ifc_fuse_hek_seed_cg fuse_hek_seed_cg = new(bus_fuse_hek_seed); + soc_ifc_SS_CALIPTRA_BASE_ADDR_L_cg SS_CALIPTRA_BASE_ADDR_L_cg = new(bus_SS_CALIPTRA_BASE_ADDR_L); + soc_ifc_SS_CALIPTRA_BASE_ADDR_H_cg SS_CALIPTRA_BASE_ADDR_H_cg = new(bus_SS_CALIPTRA_BASE_ADDR_H); + soc_ifc_SS_MCI_BASE_ADDR_L_cg SS_MCI_BASE_ADDR_L_cg = new(bus_SS_MCI_BASE_ADDR_L); + soc_ifc_SS_MCI_BASE_ADDR_H_cg SS_MCI_BASE_ADDR_H_cg = new(bus_SS_MCI_BASE_ADDR_H); + soc_ifc_SS_RECOVERY_IFC_BASE_ADDR_L_cg SS_RECOVERY_IFC_BASE_ADDR_L_cg = new(bus_SS_RECOVERY_IFC_BASE_ADDR_L); + soc_ifc_SS_RECOVERY_IFC_BASE_ADDR_H_cg SS_RECOVERY_IFC_BASE_ADDR_H_cg = new(bus_SS_RECOVERY_IFC_BASE_ADDR_H); + soc_ifc_SS_OTP_FC_BASE_ADDR_L_cg SS_OTP_FC_BASE_ADDR_L_cg = new(bus_SS_OTP_FC_BASE_ADDR_L); + soc_ifc_SS_OTP_FC_BASE_ADDR_H_cg SS_OTP_FC_BASE_ADDR_H_cg = new(bus_SS_OTP_FC_BASE_ADDR_H); + soc_ifc_SS_UDS_SEED_BASE_ADDR_L_cg SS_UDS_SEED_BASE_ADDR_L_cg = new(bus_SS_UDS_SEED_BASE_ADDR_L); + soc_ifc_SS_UDS_SEED_BASE_ADDR_H_cg SS_UDS_SEED_BASE_ADDR_H_cg = new(bus_SS_UDS_SEED_BASE_ADDR_H); + soc_ifc_SS_PROD_DEBUG_UNLOCK_AUTH_PK_HASH_REG_BANK_OFFSET_cg SS_PROD_DEBUG_UNLOCK_AUTH_PK_HASH_REG_BANK_OFFSET_cg = new(bus_SS_PROD_DEBUG_UNLOCK_AUTH_PK_HASH_REG_BANK_OFFSET); + soc_ifc_SS_NUM_OF_PROD_DEBUG_UNLOCK_AUTH_PK_HASHES_cg SS_NUM_OF_PROD_DEBUG_UNLOCK_AUTH_PK_HASHES_cg = new(bus_SS_NUM_OF_PROD_DEBUG_UNLOCK_AUTH_PK_HASHES); + soc_ifc_SS_DEBUG_INTENT_cg SS_DEBUG_INTENT_cg = new(bus_SS_DEBUG_INTENT); + soc_ifc_SS_CALIPTRA_DMA_AXI_USER_cg SS_CALIPTRA_DMA_AXI_USER_cg = new(bus_SS_CALIPTRA_DMA_AXI_USER); + soc_ifc_SS_EXTERNAL_STAGING_AREA_BASE_ADDR_L_cg SS_EXTERNAL_STAGING_AREA_BASE_ADDR_L_cg = new(bus_SS_EXTERNAL_STAGING_AREA_BASE_ADDR_L); + soc_ifc_SS_EXTERNAL_STAGING_AREA_BASE_ADDR_H_cg SS_EXTERNAL_STAGING_AREA_BASE_ADDR_H_cg = new(bus_SS_EXTERNAL_STAGING_AREA_BASE_ADDR_H); + soc_ifc_SS_KEY_RELEASE_BASE_ADDR_L_cg SS_KEY_RELEASE_BASE_ADDR_L_cg = new(bus_SS_KEY_RELEASE_BASE_ADDR_L); + soc_ifc_SS_KEY_RELEASE_BASE_ADDR_H_cg SS_KEY_RELEASE_BASE_ADDR_H_cg = new(bus_SS_KEY_RELEASE_BASE_ADDR_H); + soc_ifc_SS_KEY_RELEASE_SIZE_cg SS_KEY_RELEASE_SIZE_cg = new(bus_SS_KEY_RELEASE_SIZE); + soc_ifc_SS_OCP_LOCK_CTRL_cg SS_OCP_LOCK_CTRL_cg = new(bus_SS_OCP_LOCK_CTRL); + soc_ifc_SS_STRAP_GENERIC_cg SS_STRAP_GENERIC_cg = new(bus_SS_STRAP_GENERIC); + soc_ifc_SS_DBG_SERVICE_REG_REQ_cg SS_DBG_SERVICE_REG_REQ_cg = new(bus_SS_DBG_SERVICE_REG_REQ); + soc_ifc_SS_DBG_SERVICE_REG_RSP_cg SS_DBG_SERVICE_REG_RSP_cg = new(bus_SS_DBG_SERVICE_REG_RSP); + soc_ifc_SS_SOC_DBG_UNLOCK_LEVEL_cg SS_SOC_DBG_UNLOCK_LEVEL_cg = new(bus_SS_SOC_DBG_UNLOCK_LEVEL); + soc_ifc_SS_GENERIC_FW_EXEC_CTRL_cg SS_GENERIC_FW_EXEC_CTRL_cg = new(bus_SS_GENERIC_FW_EXEC_CTRL); + soc_ifc_internal_obf_key_cg internal_obf_key_cg = new(bus_internal_obf_key); + soc_ifc_internal_iccm_lock_cg internal_iccm_lock_cg = new(bus_internal_iccm_lock); + soc_ifc_internal_fw_update_reset_cg internal_fw_update_reset_cg = new(bus_internal_fw_update_reset); + soc_ifc_internal_fw_update_reset_wait_cycles_cg internal_fw_update_reset_wait_cycles_cg = new(bus_internal_fw_update_reset_wait_cycles); + soc_ifc_internal_nmi_vector_cg internal_nmi_vector_cg = new(bus_internal_nmi_vector); + soc_ifc_internal_hw_error_fatal_mask_cg internal_hw_error_fatal_mask_cg = new(bus_internal_hw_error_fatal_mask); + soc_ifc_internal_hw_error_non_fatal_mask_cg internal_hw_error_non_fatal_mask_cg = new(bus_internal_hw_error_non_fatal_mask); + soc_ifc_internal_fw_error_fatal_mask_cg internal_fw_error_fatal_mask_cg = new(bus_internal_fw_error_fatal_mask); + soc_ifc_internal_fw_error_non_fatal_mask_cg internal_fw_error_non_fatal_mask_cg = new(bus_internal_fw_error_non_fatal_mask); + soc_ifc_internal_rv_mtime_l_cg internal_rv_mtime_l_cg = new(bus_internal_rv_mtime_l); + soc_ifc_internal_rv_mtime_h_cg internal_rv_mtime_h_cg = new(bus_internal_rv_mtime_h); + soc_ifc_internal_rv_mtimecmp_l_cg internal_rv_mtimecmp_l_cg = new(bus_internal_rv_mtimecmp_l); + soc_ifc_internal_rv_mtimecmp_h_cg internal_rv_mtimecmp_h_cg = new(bus_internal_rv_mtimecmp_h); + soc_ifc_intr_brf_global_intr_en_r_cg intr_brf_global_intr_en_r_cg = new(bus_intr_brf_global_intr_en_r); + soc_ifc_intr_brf_error_intr_en_r_cg intr_brf_error_intr_en_r_cg = new(bus_intr_brf_error_intr_en_r); + soc_ifc_intr_brf_notif_intr_en_r_cg intr_brf_notif_intr_en_r_cg = new(bus_intr_brf_notif_intr_en_r); + soc_ifc_intr_brf_error_global_intr_r_cg intr_brf_error_global_intr_r_cg = new(bus_intr_brf_error_global_intr_r); + soc_ifc_intr_brf_notif_global_intr_r_cg intr_brf_notif_global_intr_r_cg = new(bus_intr_brf_notif_global_intr_r); + soc_ifc_intr_brf_error_internal_intr_r_cg intr_brf_error_internal_intr_r_cg = new(bus_intr_brf_error_internal_intr_r); + soc_ifc_intr_brf_notif_internal_intr_r_cg intr_brf_notif_internal_intr_r_cg = new(bus_intr_brf_notif_internal_intr_r); + soc_ifc_intr_brf_error_intr_trig_r_cg intr_brf_error_intr_trig_r_cg = new(bus_intr_brf_error_intr_trig_r); + soc_ifc_intr_brf_notif_intr_trig_r_cg intr_brf_notif_intr_trig_r_cg = new(bus_intr_brf_notif_intr_trig_r); + soc_ifc_intr_brf_error_internal_intr_count_r_cg intr_brf_error_internal_intr_count_r_cg = new(bus_intr_brf_error_internal_intr_count_r); + soc_ifc_intr_brf_error_inv_dev_intr_count_r_cg intr_brf_error_inv_dev_intr_count_r_cg = new(bus_intr_brf_error_inv_dev_intr_count_r); + soc_ifc_intr_brf_error_cmd_fail_intr_count_r_cg intr_brf_error_cmd_fail_intr_count_r_cg = new(bus_intr_brf_error_cmd_fail_intr_count_r); + soc_ifc_intr_brf_error_bad_fuse_intr_count_r_cg intr_brf_error_bad_fuse_intr_count_r_cg = new(bus_intr_brf_error_bad_fuse_intr_count_r); + soc_ifc_intr_brf_error_iccm_blocked_intr_count_r_cg intr_brf_error_iccm_blocked_intr_count_r_cg = new(bus_intr_brf_error_iccm_blocked_intr_count_r); + soc_ifc_intr_brf_error_mbox_ecc_unc_intr_count_r_cg intr_brf_error_mbox_ecc_unc_intr_count_r_cg = new(bus_intr_brf_error_mbox_ecc_unc_intr_count_r); + soc_ifc_intr_brf_error_wdt_timer1_timeout_intr_count_r_cg intr_brf_error_wdt_timer1_timeout_intr_count_r_cg = new(bus_intr_brf_error_wdt_timer1_timeout_intr_count_r); + soc_ifc_intr_brf_error_wdt_timer2_timeout_intr_count_r_cg intr_brf_error_wdt_timer2_timeout_intr_count_r_cg = new(bus_intr_brf_error_wdt_timer2_timeout_intr_count_r); + soc_ifc_intr_brf_notif_cmd_avail_intr_count_r_cg intr_brf_notif_cmd_avail_intr_count_r_cg = new(bus_intr_brf_notif_cmd_avail_intr_count_r); + soc_ifc_intr_brf_notif_mbox_ecc_cor_intr_count_r_cg intr_brf_notif_mbox_ecc_cor_intr_count_r_cg = new(bus_intr_brf_notif_mbox_ecc_cor_intr_count_r); + soc_ifc_intr_brf_notif_debug_locked_intr_count_r_cg intr_brf_notif_debug_locked_intr_count_r_cg = new(bus_intr_brf_notif_debug_locked_intr_count_r); + soc_ifc_intr_brf_notif_scan_mode_intr_count_r_cg intr_brf_notif_scan_mode_intr_count_r_cg = new(bus_intr_brf_notif_scan_mode_intr_count_r); + soc_ifc_intr_brf_notif_soc_req_lock_intr_count_r_cg intr_brf_notif_soc_req_lock_intr_count_r_cg = new(bus_intr_brf_notif_soc_req_lock_intr_count_r); + soc_ifc_intr_brf_notif_gen_in_toggle_intr_count_r_cg intr_brf_notif_gen_in_toggle_intr_count_r_cg = new(bus_intr_brf_notif_gen_in_toggle_intr_count_r); + soc_ifc_intr_brf_error_internal_intr_count_incr_r_cg intr_brf_error_internal_intr_count_incr_r_cg = new(bus_intr_brf_error_internal_intr_count_incr_r); + soc_ifc_intr_brf_error_inv_dev_intr_count_incr_r_cg intr_brf_error_inv_dev_intr_count_incr_r_cg = new(bus_intr_brf_error_inv_dev_intr_count_incr_r); + soc_ifc_intr_brf_error_cmd_fail_intr_count_incr_r_cg intr_brf_error_cmd_fail_intr_count_incr_r_cg = new(bus_intr_brf_error_cmd_fail_intr_count_incr_r); + soc_ifc_intr_brf_error_bad_fuse_intr_count_incr_r_cg intr_brf_error_bad_fuse_intr_count_incr_r_cg = new(bus_intr_brf_error_bad_fuse_intr_count_incr_r); + soc_ifc_intr_brf_error_iccm_blocked_intr_count_incr_r_cg intr_brf_error_iccm_blocked_intr_count_incr_r_cg = new(bus_intr_brf_error_iccm_blocked_intr_count_incr_r); + soc_ifc_intr_brf_error_mbox_ecc_unc_intr_count_incr_r_cg intr_brf_error_mbox_ecc_unc_intr_count_incr_r_cg = new(bus_intr_brf_error_mbox_ecc_unc_intr_count_incr_r); + soc_ifc_intr_brf_error_wdt_timer1_timeout_intr_count_incr_r_cg intr_brf_error_wdt_timer1_timeout_intr_count_incr_r_cg = new(bus_intr_brf_error_wdt_timer1_timeout_intr_count_incr_r); + soc_ifc_intr_brf_error_wdt_timer2_timeout_intr_count_incr_r_cg intr_brf_error_wdt_timer2_timeout_intr_count_incr_r_cg = new(bus_intr_brf_error_wdt_timer2_timeout_intr_count_incr_r); + soc_ifc_intr_brf_notif_cmd_avail_intr_count_incr_r_cg intr_brf_notif_cmd_avail_intr_count_incr_r_cg = new(bus_intr_brf_notif_cmd_avail_intr_count_incr_r); + soc_ifc_intr_brf_notif_mbox_ecc_cor_intr_count_incr_r_cg intr_brf_notif_mbox_ecc_cor_intr_count_incr_r_cg = new(bus_intr_brf_notif_mbox_ecc_cor_intr_count_incr_r); + soc_ifc_intr_brf_notif_debug_locked_intr_count_incr_r_cg intr_brf_notif_debug_locked_intr_count_incr_r_cg = new(bus_intr_brf_notif_debug_locked_intr_count_incr_r); + soc_ifc_intr_brf_notif_scan_mode_intr_count_incr_r_cg intr_brf_notif_scan_mode_intr_count_incr_r_cg = new(bus_intr_brf_notif_scan_mode_intr_count_incr_r); + soc_ifc_intr_brf_notif_soc_req_lock_intr_count_incr_r_cg intr_brf_notif_soc_req_lock_intr_count_incr_r_cg = new(bus_intr_brf_notif_soc_req_lock_intr_count_incr_r); + soc_ifc_intr_brf_notif_gen_in_toggle_intr_count_incr_r_cg intr_brf_notif_gen_in_toggle_intr_count_incr_r_cg = new(bus_intr_brf_notif_gen_in_toggle_intr_count_incr_r); + + // ------------------------------------------------------------------- + // end SCRIPT_OUTPUT + // ------------------------------------------------------------------- + +endinterface + + +`endif + diff --git a/designs/Caliptra/src/caliptra-rtl/soc_ifc_pkg.sv b/designs/Caliptra/src/caliptra-rtl/soc_ifc_pkg.sv new file mode 100644 index 0000000..c49cf46 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/soc_ifc_pkg.sv @@ -0,0 +1,199 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. + +`ifndef SOC_IFC_PKG +`define SOC_IFC_PKG + +`include "config_defines.svh" +`include "caliptra_reg_defines.svh" +`include "caliptra_reg_field_defines.svh" + +package soc_ifc_pkg; + + parameter SOC_IFC_ADDR_W = 19; + parameter SOC_IFC_DATA_W = 32; + parameter SOC_IFC_USER_W = 32; + parameter SOC_IFC_ID_W = `CALIPTRA_AXI_ID_WIDTH; + + parameter CPTRA_AXI_DMA_DATA_WIDTH = 32; + parameter CPTRA_AXI_DMA_ID_WIDTH = 5; // FIXME related to CALIPTRA_AXI_ID_WIDTH? + parameter CPTRA_AXI_DMA_USER_WIDTH = 32; + + parameter SOC_IFC_WDT_TIMEOUT_PERIOD_NUM_DWORDS = 2; + parameter SOC_IFC_WDT_TIMEOUT_PERIOD_W = SOC_IFC_WDT_TIMEOUT_PERIOD_NUM_DWORDS * 32; + + parameter SOC_IFC_REG_OFFSET = 32'h3000_0000; + + //Mailbox size configuration +`ifdef CALIPTRA_MODE_SUBSYSTEM + parameter CPTRA_MBOX_SIZE_KB = 16; +`else + parameter CPTRA_MBOX_SIZE_KB = 256; +`endif + parameter CPTRA_MBOX_DATA_W = 32; + parameter CPTRA_MBOX_ECC_DATA_W = 7; + parameter CPTRA_MBOX_SIZE_BYTES = CPTRA_MBOX_SIZE_KB * 1024; + parameter CPTRA_MBOX_SIZE_DWORDS = CPTRA_MBOX_SIZE_BYTES/4; + parameter CPTRA_MBOX_DATA_AND_ECC_W = CPTRA_MBOX_DATA_W + CPTRA_MBOX_ECC_DATA_W; + parameter CPTRA_MBOX_DEPTH = (CPTRA_MBOX_SIZE_KB * 1024 * 8) / CPTRA_MBOX_DATA_W; + parameter CPTRA_MBOX_ADDR_W = $clog2(CPTRA_MBOX_DEPTH); + parameter CPTRA_MBOX_DEPTH_LOG2 = $clog2(CPTRA_MBOX_DEPTH); + + //memory map + parameter MBOX_REG_START_ADDR = `CLP_MBOX_CSR_BASE_ADDR - SOC_IFC_REG_OFFSET; + parameter MBOX_REG_END_ADDR = MBOX_REG_START_ADDR + 32'h0000_0FFF; + parameter SHA_REG_START_ADDR = `CLP_SHA512_ACC_CSR_BASE_ADDR - SOC_IFC_REG_OFFSET; + parameter SHA_REG_END_ADDR = SHA_REG_START_ADDR + 32'h0000_0FFF; + parameter DMA_REG_START_ADDR = `CLP_AXI_DMA_REG_BASE_ADDR - SOC_IFC_REG_OFFSET; + parameter DMA_REG_END_ADDR = DMA_REG_START_ADDR + 32'h0000_0FFF; + parameter SOC_IFC_REG_START_ADDR = `CLP_SOC_IFC_REG_BASE_ADDR - SOC_IFC_REG_OFFSET; + parameter SOC_IFC_REG_END_ADDR = SOC_IFC_REG_START_ADDR + 32'h0000_FFFF; + parameter SOC_IFC_FUSE_START_ADDR = SOC_IFC_REG_START_ADDR + 32'h0000_0200; + parameter SOC_IFC_FUSE_END_ADDR = SOC_IFC_REG_START_ADDR + 32'h0000_05FF; + parameter MBOX_DIR_START_ADDR = `CLP_MBOX_SRAM_BASE_ADDR - SOC_IFC_REG_OFFSET; + parameter MBOX_DIR_END_ADDR = `CLP_MBOX_SRAM_END_ADDR - SOC_IFC_REG_OFFSET; + parameter MBOX_DIR_MEM_SIZE = MBOX_DIR_END_ADDR + 1 - MBOX_DIR_START_ADDR; + + + //Valid AXI_USER + //Lock the AXI_USER values from integration time + parameter [4:0] CPTRA_SET_MBOX_AXI_USER_INTEG = { 1'b0, 1'b0, 1'b0, 1'b0, 1'b0}; + parameter [4:0][31:0] CPTRA_MBOX_VALID_AXI_USER = {32'h4444_4444, 32'h3333_3333, 32'h2222_2222, 32'h1111_1111, 32'h0000_0000}; + parameter [31:0] CPTRA_DEF_MBOX_VALID_AXI_USER = 32'hFFFF_FFFF; + + parameter CPTRA_SET_FUSE_AXI_USER_INTEG = 1'b0; + parameter [31:0] CPTRA_FUSE_VALID_AXI_USER = 32'h0000_0000; + + //DMI Register encodings + //Read only registers + parameter DMI_REG_MBOX_DOUT = 7'h51; + parameter DMI_REG_BOOT_STATUS = 7'h53; + parameter DMI_REG_CPTRA_HW_ERRROR_ENC = 7'h54; + parameter DMI_REG_CPTRA_FW_ERROR_ENC = 7'h55; + parameter DMI_REG_SS_UDS_SEED_BASE_ADDR_L = 7'h56; + parameter DMI_REG_SS_UDS_SEED_BASE_ADDR_H = 7'h57; + parameter DMI_REG_HW_FATAL_ERROR = 7'h58; + parameter DMI_REG_FW_FATAL_ERROR = 7'h59; + parameter DMI_REG_HW_NON_FATAL_ERROR = 7'h5a; + parameter DMI_REG_FW_NON_FATAL_ERROR = 7'h5b; + //RW registers + parameter DMI_REG_CPTRA_DBG_MANUF_SERVICE_REG = 7'h60; + parameter DMI_REG_BOOTFSM_GO = 7'h61; + parameter DMI_REG_MBOX_DLEN = 7'h50; + parameter DMI_REG_MBOX_DIN = 7'h62; + parameter DMI_REG_MBOX_STATUS = 7'h52; + parameter DMI_REG_SS_DEBUG_INTENT = 7'h63; + parameter DMI_REG_SS_CALIPTRA_BASE_ADDR_L = 7'h64; + parameter DMI_REG_SS_CALIPTRA_BASE_ADDR_H = 7'h65; + parameter DMI_REG_SS_MCI_BASE_ADDR_L = 7'h66; + parameter DMI_REG_SS_MCI_BASE_ADDR_H = 7'h67; + parameter DMI_REG_SS_RECOVERY_IFC_BASE_ADDR_L = 7'h68; + parameter DMI_REG_SS_RECOVERY_IFC_BASE_ADDR_H = 7'h69; + parameter DMI_REG_SS_OTP_FC_BASE_ADDR_L = 7'h6A; + parameter DMI_REG_SS_OTP_FC_BASE_ADDR_H = 7'h6B; + parameter DMI_REG_SS_STRAP_GENERIC_0 = 7'h6C; + parameter DMI_REG_SS_STRAP_GENERIC_1 = 7'h6D; + parameter DMI_REG_SS_STRAP_GENERIC_2 = 7'h6E; + parameter DMI_REG_SS_STRAP_GENERIC_3 = 7'h6F; + parameter DMI_REG_SS_DBG_SERVICE_REG_REQ = 7'h70; + parameter DMI_REG_SS_DBG_SERVICE_REG_RSP = 7'h71; + parameter DMI_REG_SS_DBG_UNLOCK_LEVEL0 = 7'h72; + parameter DMI_REG_SS_DBG_UNLOCK_LEVEL1 = 7'h73; + parameter DMI_REG_SS_STRAP_CALIPTRA_DMA_AXI_USER = 7'h74; + parameter DMI_REG_MBOX_LOCK = 7'h75; + parameter DMI_REG_MBOX_CMD = 7'h76; + parameter DMI_REG_MBOX_EXECUTE = 7'h77; + parameter DMI_REG_SS_EXTERNAL_STAGING_AREA_BASE_ADDR_L = 7'h78; + parameter DMI_REG_SS_EXTERNAL_STAGING_AREA_BASE_ADDR_H = 7'h79; + + + // This parameter describes the hard-coded implementation in the BOOT FSM + // that results in noncore reset assertion being delayed from the soft reset + // (cptra_rst_b) by some integer number of clock cycles, due to synchronization + // stages and the rst window signaling. + // This is useful in validation environments for controlling the predicted + // timing in a reset event. + parameter SOC_IFC_CPTRA_RST_NONCORE_RST_DELAY = 4; + + //BOOT FSM + typedef enum logic [2:0] { + BOOT_IDLE = 3'b000, + BOOT_FUSE = 3'b001, + BOOT_FW_RST = 3'b010, + BOOT_WAIT = 3'b011, + BOOT_DONE = 3'b100 + } boot_fsm_state_e; + + //SHA FSM + typedef enum logic [2:0] { + SHA_IDLE = 3'b000, + SHA_BLOCK_0 = 3'b001, + SHA_BLOCK_N = 3'b011, + SHA_PAD0 = 3'b010, + SHA_PAD1 = 3'b110, + SHA_DONE = 3'b100 + } sha_fsm_state_e; + + //Any request into soc ifc block + typedef struct packed { + logic [SOC_IFC_ADDR_W-1:0] addr; + logic [SOC_IFC_DATA_W-1:0] wdata; + logic [SOC_IFC_DATA_W/8-1:0] wstrb; + logic [SOC_IFC_USER_W-1:0] user; + logic [SOC_IFC_ID_W -1:0] id; + logic write; + logic soc_req; + } soc_ifc_req_t; + + typedef struct packed { + logic cptra_iccm_ecc_single_error; + logic cptra_iccm_ecc_double_error; + logic cptra_dccm_ecc_single_error; + logic cptra_dccm_ecc_double_error; + } rv_ecc_sts_t; + + typedef enum logic [1:0] { + DEVICE_UNPROVISIONED = 2'b00, + DEVICE_MANUFACTURING = 2'b01, + DEVICE_PRODUCTION = 2'b11 + } device_lifecycle_e; + + typedef struct packed { + logic debug_locked; + device_lifecycle_e device_lifecycle; + } security_state_t; + + //Caliptra Mailbox + // ECC protected data + typedef struct packed { + logic [CPTRA_MBOX_ECC_DATA_W-1:0] ecc; + logic [CPTRA_MBOX_DATA_W-1:0] data; + } cptra_mbox_sram_data_t; + + //Request to mbox sram + typedef struct packed { + logic cs; + logic we; + logic [CPTRA_MBOX_ADDR_W-1:0] addr; + cptra_mbox_sram_data_t wdata; + } cptra_mbox_sram_req_t; + + //Response from mbox sram + typedef struct packed { + cptra_mbox_sram_data_t rdata; + } cptra_mbox_sram_resp_t; + +endpackage + +`endif diff --git a/designs/Caliptra/src/caliptra-rtl/soc_ifc_reg.sv b/designs/Caliptra/src/caliptra-rtl/soc_ifc_reg.sv new file mode 100644 index 0000000..0d9f4ff --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/soc_ifc_reg.sv @@ -0,0 +1,7635 @@ +// Generated by PeakRDL-regblock - A free and open-source SystemVerilog generator +// https://github.com/SystemRDL/PeakRDL-regblock + +module soc_ifc_reg ( + input wire clk, + input wire rst, + + input wire s_cpuif_req, + input wire s_cpuif_req_is_wr, + input wire [11:0] s_cpuif_addr, + input wire [31:0] s_cpuif_wr_data, + input wire [31:0] s_cpuif_wr_biten, + output wire s_cpuif_req_stall_wr, + output wire s_cpuif_req_stall_rd, + output wire s_cpuif_rd_ack, + output wire s_cpuif_rd_err, + output wire [31:0] s_cpuif_rd_data, + output wire s_cpuif_wr_ack, + output wire s_cpuif_wr_err, + + input soc_ifc_reg_pkg::soc_ifc_reg__in_t hwif_in, + output soc_ifc_reg_pkg::soc_ifc_reg__out_t hwif_out + ); + + //-------------------------------------------------------------------------- + // CPU Bus interface logic + //-------------------------------------------------------------------------- + logic cpuif_req; + logic cpuif_req_is_wr; + logic [11:0] cpuif_addr; + logic [31:0] cpuif_wr_data; + logic [31:0] cpuif_wr_biten; + logic cpuif_req_stall_wr; + logic cpuif_req_stall_rd; + + logic cpuif_rd_ack; + logic cpuif_rd_err; + logic [31:0] cpuif_rd_data; + + logic cpuif_wr_ack; + logic cpuif_wr_err; + + assign cpuif_req = s_cpuif_req; + assign cpuif_req_is_wr = s_cpuif_req_is_wr; + assign cpuif_addr = s_cpuif_addr; + assign cpuif_wr_data = s_cpuif_wr_data; + assign cpuif_wr_biten = s_cpuif_wr_biten; + assign s_cpuif_req_stall_wr = cpuif_req_stall_wr; + assign s_cpuif_req_stall_rd = cpuif_req_stall_rd; + assign s_cpuif_rd_ack = cpuif_rd_ack; + assign s_cpuif_rd_err = cpuif_rd_err; + assign s_cpuif_rd_data = cpuif_rd_data; + assign s_cpuif_wr_ack = cpuif_wr_ack; + assign s_cpuif_wr_err = cpuif_wr_err; + + logic cpuif_req_masked; + + // Read & write latencies are balanced. Stalls not required + assign cpuif_req_stall_rd = '0; + assign cpuif_req_stall_wr = '0; + assign cpuif_req_masked = cpuif_req + & !(!cpuif_req_is_wr & cpuif_req_stall_rd) + & !(cpuif_req_is_wr & cpuif_req_stall_wr); + + //-------------------------------------------------------------------------- + // Address Decode + //-------------------------------------------------------------------------- + typedef struct packed{ + logic CPTRA_HW_ERROR_FATAL; + logic CPTRA_HW_ERROR_NON_FATAL; + logic CPTRA_FW_ERROR_FATAL; + logic CPTRA_FW_ERROR_NON_FATAL; + logic CPTRA_HW_ERROR_ENC; + logic CPTRA_FW_ERROR_ENC; + logic [8-1:0]CPTRA_FW_EXTENDED_ERROR_INFO; + logic CPTRA_BOOT_STATUS; + logic CPTRA_FLOW_STATUS; + logic CPTRA_RESET_REASON; + logic CPTRA_SECURITY_STATE; + logic [5-1:0]CPTRA_MBOX_VALID_AXI_USER; + logic [5-1:0]CPTRA_MBOX_AXI_USER_LOCK; + logic CPTRA_TRNG_VALID_AXI_USER; + logic CPTRA_TRNG_AXI_USER_LOCK; + logic [12-1:0]CPTRA_TRNG_DATA; + logic CPTRA_TRNG_CTRL; + logic CPTRA_TRNG_STATUS; + logic CPTRA_FUSE_WR_DONE; + logic CPTRA_TIMER_CONFIG; + logic CPTRA_BOOTFSM_GO; + logic CPTRA_DBG_MANUF_SERVICE_REG; + logic CPTRA_CLK_GATING_EN; + logic [2-1:0]CPTRA_GENERIC_INPUT_WIRES; + logic [2-1:0]CPTRA_GENERIC_OUTPUT_WIRES; + logic CPTRA_HW_REV_ID; + logic [2-1:0]CPTRA_FW_REV_ID; + logic CPTRA_HW_CONFIG; + logic CPTRA_WDT_TIMER1_EN; + logic CPTRA_WDT_TIMER1_CTRL; + logic [2-1:0]CPTRA_WDT_TIMER1_TIMEOUT_PERIOD; + logic CPTRA_WDT_TIMER2_EN; + logic CPTRA_WDT_TIMER2_CTRL; + logic [2-1:0]CPTRA_WDT_TIMER2_TIMEOUT_PERIOD; + logic CPTRA_WDT_STATUS; + logic CPTRA_FUSE_VALID_AXI_USER; + logic CPTRA_FUSE_AXI_USER_LOCK; + logic [2-1:0]CPTRA_WDT_CFG; + logic CPTRA_iTRNG_ENTROPY_CONFIG_0; + logic CPTRA_iTRNG_ENTROPY_CONFIG_1; + logic [2-1:0]CPTRA_RSVD_REG; + logic CPTRA_HW_CAPABILITIES; + logic CPTRA_FW_CAPABILITIES; + logic CPTRA_CAP_LOCK; + logic [12-1:0]CPTRA_OWNER_PK_HASH; + logic CPTRA_OWNER_PK_HASH_LOCK; + logic [16-1:0]fuse_uds_seed; + logic [8-1:0]fuse_field_entropy; + logic [12-1:0]fuse_vendor_pk_hash; + logic fuse_ecc_revocation; + logic fuse_fmc_key_manifest_svn; + logic [4-1:0]fuse_runtime_svn; + logic fuse_anti_rollback_disable; + logic [24-1:0]fuse_idevid_cert_attr; + logic [4-1:0]fuse_idevid_manuf_hsm_id; + logic fuse_lms_revocation; + logic fuse_mldsa_revocation; + logic fuse_soc_stepping_id; + logic [16-1:0]fuse_manuf_dbg_unlock_token; + logic fuse_pqc_key_type; + logic [4-1:0]fuse_soc_manifest_svn; + logic fuse_soc_manifest_max_svn; + logic [8-1:0]fuse_hek_seed; + logic SS_CALIPTRA_BASE_ADDR_L; + logic SS_CALIPTRA_BASE_ADDR_H; + logic SS_MCI_BASE_ADDR_L; + logic SS_MCI_BASE_ADDR_H; + logic SS_RECOVERY_IFC_BASE_ADDR_L; + logic SS_RECOVERY_IFC_BASE_ADDR_H; + logic SS_OTP_FC_BASE_ADDR_L; + logic SS_OTP_FC_BASE_ADDR_H; + logic SS_UDS_SEED_BASE_ADDR_L; + logic SS_UDS_SEED_BASE_ADDR_H; + logic SS_PROD_DEBUG_UNLOCK_AUTH_PK_HASH_REG_BANK_OFFSET; + logic SS_NUM_OF_PROD_DEBUG_UNLOCK_AUTH_PK_HASHES; + logic SS_DEBUG_INTENT; + logic SS_CALIPTRA_DMA_AXI_USER; + logic SS_EXTERNAL_STAGING_AREA_BASE_ADDR_L; + logic SS_EXTERNAL_STAGING_AREA_BASE_ADDR_H; + logic SS_KEY_RELEASE_BASE_ADDR_L; + logic SS_KEY_RELEASE_BASE_ADDR_H; + logic SS_KEY_RELEASE_SIZE; + logic SS_OCP_LOCK_CTRL; + logic [4-1:0]SS_STRAP_GENERIC; + logic SS_DBG_SERVICE_REG_REQ; + logic SS_DBG_SERVICE_REG_RSP; + logic [2-1:0]SS_SOC_DBG_UNLOCK_LEVEL; + logic [4-1:0]SS_GENERIC_FW_EXEC_CTRL; + logic [8-1:0]internal_obf_key; + logic internal_iccm_lock; + logic internal_fw_update_reset; + logic internal_fw_update_reset_wait_cycles; + logic internal_nmi_vector; + logic internal_hw_error_fatal_mask; + logic internal_hw_error_non_fatal_mask; + logic internal_fw_error_fatal_mask; + logic internal_fw_error_non_fatal_mask; + logic internal_rv_mtime_l; + logic internal_rv_mtime_h; + logic internal_rv_mtimecmp_l; + logic internal_rv_mtimecmp_h; + struct packed{ + logic global_intr_en_r; + logic error_intr_en_r; + logic notif_intr_en_r; + logic error_global_intr_r; + logic notif_global_intr_r; + logic error_internal_intr_r; + logic notif_internal_intr_r; + logic error_intr_trig_r; + logic notif_intr_trig_r; + logic error_internal_intr_count_r; + logic error_inv_dev_intr_count_r; + logic error_cmd_fail_intr_count_r; + logic error_bad_fuse_intr_count_r; + logic error_iccm_blocked_intr_count_r; + logic error_mbox_ecc_unc_intr_count_r; + logic error_wdt_timer1_timeout_intr_count_r; + logic error_wdt_timer2_timeout_intr_count_r; + logic notif_cmd_avail_intr_count_r; + logic notif_mbox_ecc_cor_intr_count_r; + logic notif_debug_locked_intr_count_r; + logic notif_scan_mode_intr_count_r; + logic notif_soc_req_lock_intr_count_r; + logic notif_gen_in_toggle_intr_count_r; + logic error_internal_intr_count_incr_r; + logic error_inv_dev_intr_count_incr_r; + logic error_cmd_fail_intr_count_incr_r; + logic error_bad_fuse_intr_count_incr_r; + logic error_iccm_blocked_intr_count_incr_r; + logic error_mbox_ecc_unc_intr_count_incr_r; + logic error_wdt_timer1_timeout_intr_count_incr_r; + logic error_wdt_timer2_timeout_intr_count_incr_r; + logic notif_cmd_avail_intr_count_incr_r; + logic notif_mbox_ecc_cor_intr_count_incr_r; + logic notif_debug_locked_intr_count_incr_r; + logic notif_scan_mode_intr_count_incr_r; + logic notif_soc_req_lock_intr_count_incr_r; + logic notif_gen_in_toggle_intr_count_incr_r; + } intr_block_rf; + } decoded_reg_strb_t; + decoded_reg_strb_t decoded_reg_strb; + logic decoded_req; + logic decoded_req_is_wr; + logic [31:0] decoded_wr_data; + logic [31:0] decoded_wr_biten; + + always_comb begin + decoded_reg_strb.CPTRA_HW_ERROR_FATAL = cpuif_req_masked & (cpuif_addr == 12'h0); + decoded_reg_strb.CPTRA_HW_ERROR_NON_FATAL = cpuif_req_masked & (cpuif_addr == 12'h4); + decoded_reg_strb.CPTRA_FW_ERROR_FATAL = cpuif_req_masked & (cpuif_addr == 12'h8); + decoded_reg_strb.CPTRA_FW_ERROR_NON_FATAL = cpuif_req_masked & (cpuif_addr == 12'hc); + decoded_reg_strb.CPTRA_HW_ERROR_ENC = cpuif_req_masked & (cpuif_addr == 12'h10); + decoded_reg_strb.CPTRA_FW_ERROR_ENC = cpuif_req_masked & (cpuif_addr == 12'h14); + for(int i0=0; i0<8; i0++) begin + decoded_reg_strb.CPTRA_FW_EXTENDED_ERROR_INFO[i0] = cpuif_req_masked & (cpuif_addr == 12'h18 + i0*12'h4); + end + decoded_reg_strb.CPTRA_BOOT_STATUS = cpuif_req_masked & (cpuif_addr == 12'h38); + decoded_reg_strb.CPTRA_FLOW_STATUS = cpuif_req_masked & (cpuif_addr == 12'h3c); + decoded_reg_strb.CPTRA_RESET_REASON = cpuif_req_masked & (cpuif_addr == 12'h40); + decoded_reg_strb.CPTRA_SECURITY_STATE = cpuif_req_masked & (cpuif_addr == 12'h44); + for(int i0=0; i0<5; i0++) begin + decoded_reg_strb.CPTRA_MBOX_VALID_AXI_USER[i0] = cpuif_req_masked & (cpuif_addr == 12'h48 + i0*12'h4); + end + for(int i0=0; i0<5; i0++) begin + decoded_reg_strb.CPTRA_MBOX_AXI_USER_LOCK[i0] = cpuif_req_masked & (cpuif_addr == 12'h5c + i0*12'h4); + end + decoded_reg_strb.CPTRA_TRNG_VALID_AXI_USER = cpuif_req_masked & (cpuif_addr == 12'h70); + decoded_reg_strb.CPTRA_TRNG_AXI_USER_LOCK = cpuif_req_masked & (cpuif_addr == 12'h74); + for(int i0=0; i0<12; i0++) begin + decoded_reg_strb.CPTRA_TRNG_DATA[i0] = cpuif_req_masked & (cpuif_addr == 12'h78 + i0*12'h4); + end + decoded_reg_strb.CPTRA_TRNG_CTRL = cpuif_req_masked & (cpuif_addr == 12'ha8); + decoded_reg_strb.CPTRA_TRNG_STATUS = cpuif_req_masked & (cpuif_addr == 12'hac); + decoded_reg_strb.CPTRA_FUSE_WR_DONE = cpuif_req_masked & (cpuif_addr == 12'hb0); + decoded_reg_strb.CPTRA_TIMER_CONFIG = cpuif_req_masked & (cpuif_addr == 12'hb4); + decoded_reg_strb.CPTRA_BOOTFSM_GO = cpuif_req_masked & (cpuif_addr == 12'hb8); + decoded_reg_strb.CPTRA_DBG_MANUF_SERVICE_REG = cpuif_req_masked & (cpuif_addr == 12'hbc); + decoded_reg_strb.CPTRA_CLK_GATING_EN = cpuif_req_masked & (cpuif_addr == 12'hc0); + for(int i0=0; i0<2; i0++) begin + decoded_reg_strb.CPTRA_GENERIC_INPUT_WIRES[i0] = cpuif_req_masked & (cpuif_addr == 12'hc4 + i0*12'h4); + end + for(int i0=0; i0<2; i0++) begin + decoded_reg_strb.CPTRA_GENERIC_OUTPUT_WIRES[i0] = cpuif_req_masked & (cpuif_addr == 12'hcc + i0*12'h4); + end + decoded_reg_strb.CPTRA_HW_REV_ID = cpuif_req_masked & (cpuif_addr == 12'hd4); + for(int i0=0; i0<2; i0++) begin + decoded_reg_strb.CPTRA_FW_REV_ID[i0] = cpuif_req_masked & (cpuif_addr == 12'hd8 + i0*12'h4); + end + decoded_reg_strb.CPTRA_HW_CONFIG = cpuif_req_masked & (cpuif_addr == 12'he0); + decoded_reg_strb.CPTRA_WDT_TIMER1_EN = cpuif_req_masked & (cpuif_addr == 12'he4); + decoded_reg_strb.CPTRA_WDT_TIMER1_CTRL = cpuif_req_masked & (cpuif_addr == 12'he8); + for(int i0=0; i0<2; i0++) begin + decoded_reg_strb.CPTRA_WDT_TIMER1_TIMEOUT_PERIOD[i0] = cpuif_req_masked & (cpuif_addr == 12'hec + i0*12'h4); + end + decoded_reg_strb.CPTRA_WDT_TIMER2_EN = cpuif_req_masked & (cpuif_addr == 12'hf4); + decoded_reg_strb.CPTRA_WDT_TIMER2_CTRL = cpuif_req_masked & (cpuif_addr == 12'hf8); + for(int i0=0; i0<2; i0++) begin + decoded_reg_strb.CPTRA_WDT_TIMER2_TIMEOUT_PERIOD[i0] = cpuif_req_masked & (cpuif_addr == 12'hfc + i0*12'h4); + end + decoded_reg_strb.CPTRA_WDT_STATUS = cpuif_req_masked & (cpuif_addr == 12'h104); + decoded_reg_strb.CPTRA_FUSE_VALID_AXI_USER = cpuif_req_masked & (cpuif_addr == 12'h108); + decoded_reg_strb.CPTRA_FUSE_AXI_USER_LOCK = cpuif_req_masked & (cpuif_addr == 12'h10c); + for(int i0=0; i0<2; i0++) begin + decoded_reg_strb.CPTRA_WDT_CFG[i0] = cpuif_req_masked & (cpuif_addr == 12'h110 + i0*12'h4); + end + decoded_reg_strb.CPTRA_iTRNG_ENTROPY_CONFIG_0 = cpuif_req_masked & (cpuif_addr == 12'h118); + decoded_reg_strb.CPTRA_iTRNG_ENTROPY_CONFIG_1 = cpuif_req_masked & (cpuif_addr == 12'h11c); + for(int i0=0; i0<2; i0++) begin + decoded_reg_strb.CPTRA_RSVD_REG[i0] = cpuif_req_masked & (cpuif_addr == 12'h120 + i0*12'h4); + end + decoded_reg_strb.CPTRA_HW_CAPABILITIES = cpuif_req_masked & (cpuif_addr == 12'h128); + decoded_reg_strb.CPTRA_FW_CAPABILITIES = cpuif_req_masked & (cpuif_addr == 12'h12c); + decoded_reg_strb.CPTRA_CAP_LOCK = cpuif_req_masked & (cpuif_addr == 12'h130); + for(int i0=0; i0<12; i0++) begin + decoded_reg_strb.CPTRA_OWNER_PK_HASH[i0] = cpuif_req_masked & (cpuif_addr == 12'h140 + i0*12'h4); + end + decoded_reg_strb.CPTRA_OWNER_PK_HASH_LOCK = cpuif_req_masked & (cpuif_addr == 12'h170); + for(int i0=0; i0<16; i0++) begin + decoded_reg_strb.fuse_uds_seed[i0] = cpuif_req_masked & (cpuif_addr == 12'h200 + i0*12'h4); + end + for(int i0=0; i0<8; i0++) begin + decoded_reg_strb.fuse_field_entropy[i0] = cpuif_req_masked & (cpuif_addr == 12'h240 + i0*12'h4); + end + for(int i0=0; i0<12; i0++) begin + decoded_reg_strb.fuse_vendor_pk_hash[i0] = cpuif_req_masked & (cpuif_addr == 12'h260 + i0*12'h4); + end + decoded_reg_strb.fuse_ecc_revocation = cpuif_req_masked & (cpuif_addr == 12'h290); + decoded_reg_strb.fuse_fmc_key_manifest_svn = cpuif_req_masked & (cpuif_addr == 12'h2b4); + for(int i0=0; i0<4; i0++) begin + decoded_reg_strb.fuse_runtime_svn[i0] = cpuif_req_masked & (cpuif_addr == 12'h2b8 + i0*12'h4); + end + decoded_reg_strb.fuse_anti_rollback_disable = cpuif_req_masked & (cpuif_addr == 12'h2c8); + for(int i0=0; i0<24; i0++) begin + decoded_reg_strb.fuse_idevid_cert_attr[i0] = cpuif_req_masked & (cpuif_addr == 12'h2cc + i0*12'h4); + end + for(int i0=0; i0<4; i0++) begin + decoded_reg_strb.fuse_idevid_manuf_hsm_id[i0] = cpuif_req_masked & (cpuif_addr == 12'h32c + i0*12'h4); + end + decoded_reg_strb.fuse_lms_revocation = cpuif_req_masked & (cpuif_addr == 12'h340); + decoded_reg_strb.fuse_mldsa_revocation = cpuif_req_masked & (cpuif_addr == 12'h344); + decoded_reg_strb.fuse_soc_stepping_id = cpuif_req_masked & (cpuif_addr == 12'h348); + for(int i0=0; i0<16; i0++) begin + decoded_reg_strb.fuse_manuf_dbg_unlock_token[i0] = cpuif_req_masked & (cpuif_addr == 12'h34c + i0*12'h4); + end + decoded_reg_strb.fuse_pqc_key_type = cpuif_req_masked & (cpuif_addr == 12'h38c); + for(int i0=0; i0<4; i0++) begin + decoded_reg_strb.fuse_soc_manifest_svn[i0] = cpuif_req_masked & (cpuif_addr == 12'h390 + i0*12'h4); + end + decoded_reg_strb.fuse_soc_manifest_max_svn = cpuif_req_masked & (cpuif_addr == 12'h3a0); + for(int i0=0; i0<8; i0++) begin + decoded_reg_strb.fuse_hek_seed[i0] = cpuif_req_masked & (cpuif_addr == 12'h3c0 + i0*12'h4); + end + decoded_reg_strb.SS_CALIPTRA_BASE_ADDR_L = cpuif_req_masked & (cpuif_addr == 12'h500); + decoded_reg_strb.SS_CALIPTRA_BASE_ADDR_H = cpuif_req_masked & (cpuif_addr == 12'h504); + decoded_reg_strb.SS_MCI_BASE_ADDR_L = cpuif_req_masked & (cpuif_addr == 12'h508); + decoded_reg_strb.SS_MCI_BASE_ADDR_H = cpuif_req_masked & (cpuif_addr == 12'h50c); + decoded_reg_strb.SS_RECOVERY_IFC_BASE_ADDR_L = cpuif_req_masked & (cpuif_addr == 12'h510); + decoded_reg_strb.SS_RECOVERY_IFC_BASE_ADDR_H = cpuif_req_masked & (cpuif_addr == 12'h514); + decoded_reg_strb.SS_OTP_FC_BASE_ADDR_L = cpuif_req_masked & (cpuif_addr == 12'h518); + decoded_reg_strb.SS_OTP_FC_BASE_ADDR_H = cpuif_req_masked & (cpuif_addr == 12'h51c); + decoded_reg_strb.SS_UDS_SEED_BASE_ADDR_L = cpuif_req_masked & (cpuif_addr == 12'h520); + decoded_reg_strb.SS_UDS_SEED_BASE_ADDR_H = cpuif_req_masked & (cpuif_addr == 12'h524); + decoded_reg_strb.SS_PROD_DEBUG_UNLOCK_AUTH_PK_HASH_REG_BANK_OFFSET = cpuif_req_masked & (cpuif_addr == 12'h528); + decoded_reg_strb.SS_NUM_OF_PROD_DEBUG_UNLOCK_AUTH_PK_HASHES = cpuif_req_masked & (cpuif_addr == 12'h52c); + decoded_reg_strb.SS_DEBUG_INTENT = cpuif_req_masked & (cpuif_addr == 12'h530); + decoded_reg_strb.SS_CALIPTRA_DMA_AXI_USER = cpuif_req_masked & (cpuif_addr == 12'h534); + decoded_reg_strb.SS_EXTERNAL_STAGING_AREA_BASE_ADDR_L = cpuif_req_masked & (cpuif_addr == 12'h538); + decoded_reg_strb.SS_EXTERNAL_STAGING_AREA_BASE_ADDR_H = cpuif_req_masked & (cpuif_addr == 12'h53c); + decoded_reg_strb.SS_KEY_RELEASE_BASE_ADDR_L = cpuif_req_masked & (cpuif_addr == 12'h540); + decoded_reg_strb.SS_KEY_RELEASE_BASE_ADDR_H = cpuif_req_masked & (cpuif_addr == 12'h544); + decoded_reg_strb.SS_KEY_RELEASE_SIZE = cpuif_req_masked & (cpuif_addr == 12'h548); + decoded_reg_strb.SS_OCP_LOCK_CTRL = cpuif_req_masked & (cpuif_addr == 12'h54c); + for(int i0=0; i0<4; i0++) begin + decoded_reg_strb.SS_STRAP_GENERIC[i0] = cpuif_req_masked & (cpuif_addr == 12'h5a0 + i0*12'h4); + end + decoded_reg_strb.SS_DBG_SERVICE_REG_REQ = cpuif_req_masked & (cpuif_addr == 12'h5c0); + decoded_reg_strb.SS_DBG_SERVICE_REG_RSP = cpuif_req_masked & (cpuif_addr == 12'h5c4); + for(int i0=0; i0<2; i0++) begin + decoded_reg_strb.SS_SOC_DBG_UNLOCK_LEVEL[i0] = cpuif_req_masked & (cpuif_addr == 12'h5c8 + i0*12'h4); + end + for(int i0=0; i0<4; i0++) begin + decoded_reg_strb.SS_GENERIC_FW_EXEC_CTRL[i0] = cpuif_req_masked & (cpuif_addr == 12'h5d0 + i0*12'h4); + end + for(int i0=0; i0<8; i0++) begin + decoded_reg_strb.internal_obf_key[i0] = cpuif_req_masked & (cpuif_addr == 12'h600 + i0*12'h4); + end + decoded_reg_strb.internal_iccm_lock = cpuif_req_masked & (cpuif_addr == 12'h620); + decoded_reg_strb.internal_fw_update_reset = cpuif_req_masked & (cpuif_addr == 12'h624); + decoded_reg_strb.internal_fw_update_reset_wait_cycles = cpuif_req_masked & (cpuif_addr == 12'h628); + decoded_reg_strb.internal_nmi_vector = cpuif_req_masked & (cpuif_addr == 12'h62c); + decoded_reg_strb.internal_hw_error_fatal_mask = cpuif_req_masked & (cpuif_addr == 12'h630); + decoded_reg_strb.internal_hw_error_non_fatal_mask = cpuif_req_masked & (cpuif_addr == 12'h634); + decoded_reg_strb.internal_fw_error_fatal_mask = cpuif_req_masked & (cpuif_addr == 12'h638); + decoded_reg_strb.internal_fw_error_non_fatal_mask = cpuif_req_masked & (cpuif_addr == 12'h63c); + decoded_reg_strb.internal_rv_mtime_l = cpuif_req_masked & (cpuif_addr == 12'h640); + decoded_reg_strb.internal_rv_mtime_h = cpuif_req_masked & (cpuif_addr == 12'h644); + decoded_reg_strb.internal_rv_mtimecmp_l = cpuif_req_masked & (cpuif_addr == 12'h648); + decoded_reg_strb.internal_rv_mtimecmp_h = cpuif_req_masked & (cpuif_addr == 12'h64c); + decoded_reg_strb.intr_block_rf.global_intr_en_r = cpuif_req_masked & (cpuif_addr == 12'h800); + decoded_reg_strb.intr_block_rf.error_intr_en_r = cpuif_req_masked & (cpuif_addr == 12'h804); + decoded_reg_strb.intr_block_rf.notif_intr_en_r = cpuif_req_masked & (cpuif_addr == 12'h808); + decoded_reg_strb.intr_block_rf.error_global_intr_r = cpuif_req_masked & (cpuif_addr == 12'h80c); + decoded_reg_strb.intr_block_rf.notif_global_intr_r = cpuif_req_masked & (cpuif_addr == 12'h810); + decoded_reg_strb.intr_block_rf.error_internal_intr_r = cpuif_req_masked & (cpuif_addr == 12'h814); + decoded_reg_strb.intr_block_rf.notif_internal_intr_r = cpuif_req_masked & (cpuif_addr == 12'h818); + decoded_reg_strb.intr_block_rf.error_intr_trig_r = cpuif_req_masked & (cpuif_addr == 12'h81c); + decoded_reg_strb.intr_block_rf.notif_intr_trig_r = cpuif_req_masked & (cpuif_addr == 12'h820); + decoded_reg_strb.intr_block_rf.error_internal_intr_count_r = cpuif_req_masked & (cpuif_addr == 12'h900); + decoded_reg_strb.intr_block_rf.error_inv_dev_intr_count_r = cpuif_req_masked & (cpuif_addr == 12'h904); + decoded_reg_strb.intr_block_rf.error_cmd_fail_intr_count_r = cpuif_req_masked & (cpuif_addr == 12'h908); + decoded_reg_strb.intr_block_rf.error_bad_fuse_intr_count_r = cpuif_req_masked & (cpuif_addr == 12'h90c); + decoded_reg_strb.intr_block_rf.error_iccm_blocked_intr_count_r = cpuif_req_masked & (cpuif_addr == 12'h910); + decoded_reg_strb.intr_block_rf.error_mbox_ecc_unc_intr_count_r = cpuif_req_masked & (cpuif_addr == 12'h914); + decoded_reg_strb.intr_block_rf.error_wdt_timer1_timeout_intr_count_r = cpuif_req_masked & (cpuif_addr == 12'h918); + decoded_reg_strb.intr_block_rf.error_wdt_timer2_timeout_intr_count_r = cpuif_req_masked & (cpuif_addr == 12'h91c); + decoded_reg_strb.intr_block_rf.notif_cmd_avail_intr_count_r = cpuif_req_masked & (cpuif_addr == 12'h980); + decoded_reg_strb.intr_block_rf.notif_mbox_ecc_cor_intr_count_r = cpuif_req_masked & (cpuif_addr == 12'h984); + decoded_reg_strb.intr_block_rf.notif_debug_locked_intr_count_r = cpuif_req_masked & (cpuif_addr == 12'h988); + decoded_reg_strb.intr_block_rf.notif_scan_mode_intr_count_r = cpuif_req_masked & (cpuif_addr == 12'h98c); + decoded_reg_strb.intr_block_rf.notif_soc_req_lock_intr_count_r = cpuif_req_masked & (cpuif_addr == 12'h990); + decoded_reg_strb.intr_block_rf.notif_gen_in_toggle_intr_count_r = cpuif_req_masked & (cpuif_addr == 12'h994); + decoded_reg_strb.intr_block_rf.error_internal_intr_count_incr_r = cpuif_req_masked & (cpuif_addr == 12'ha00); + decoded_reg_strb.intr_block_rf.error_inv_dev_intr_count_incr_r = cpuif_req_masked & (cpuif_addr == 12'ha04); + decoded_reg_strb.intr_block_rf.error_cmd_fail_intr_count_incr_r = cpuif_req_masked & (cpuif_addr == 12'ha08); + decoded_reg_strb.intr_block_rf.error_bad_fuse_intr_count_incr_r = cpuif_req_masked & (cpuif_addr == 12'ha0c); + decoded_reg_strb.intr_block_rf.error_iccm_blocked_intr_count_incr_r = cpuif_req_masked & (cpuif_addr == 12'ha10); + decoded_reg_strb.intr_block_rf.error_mbox_ecc_unc_intr_count_incr_r = cpuif_req_masked & (cpuif_addr == 12'ha14); + decoded_reg_strb.intr_block_rf.error_wdt_timer1_timeout_intr_count_incr_r = cpuif_req_masked & (cpuif_addr == 12'ha18); + decoded_reg_strb.intr_block_rf.error_wdt_timer2_timeout_intr_count_incr_r = cpuif_req_masked & (cpuif_addr == 12'ha1c); + decoded_reg_strb.intr_block_rf.notif_cmd_avail_intr_count_incr_r = cpuif_req_masked & (cpuif_addr == 12'ha20); + decoded_reg_strb.intr_block_rf.notif_mbox_ecc_cor_intr_count_incr_r = cpuif_req_masked & (cpuif_addr == 12'ha24); + decoded_reg_strb.intr_block_rf.notif_debug_locked_intr_count_incr_r = cpuif_req_masked & (cpuif_addr == 12'ha28); + decoded_reg_strb.intr_block_rf.notif_scan_mode_intr_count_incr_r = cpuif_req_masked & (cpuif_addr == 12'ha2c); + decoded_reg_strb.intr_block_rf.notif_soc_req_lock_intr_count_incr_r = cpuif_req_masked & (cpuif_addr == 12'ha30); + decoded_reg_strb.intr_block_rf.notif_gen_in_toggle_intr_count_incr_r = cpuif_req_masked & (cpuif_addr == 12'ha34); + end + + // Pass down signals to next stage + assign decoded_req = cpuif_req_masked; + assign decoded_req_is_wr = cpuif_req_is_wr; + assign decoded_wr_data = cpuif_wr_data; + assign decoded_wr_biten = cpuif_wr_biten; + + //-------------------------------------------------------------------------- + // Field logic + //-------------------------------------------------------------------------- + typedef struct packed{ + struct packed{ + struct packed{ + logic next; + logic load_next; + } iccm_ecc_unc; + struct packed{ + logic next; + logic load_next; + } dccm_ecc_unc; + struct packed{ + logic next; + logic load_next; + } nmi_pin; + struct packed{ + logic next; + logic load_next; + } crypto_err; + } CPTRA_HW_ERROR_FATAL; + struct packed{ + struct packed{ + logic next; + logic load_next; + } mbox_prot_no_lock; + struct packed{ + logic next; + logic load_next; + } mbox_prot_ooo; + struct packed{ + logic next; + logic load_next; + } mbox_ecc_unc; + } CPTRA_HW_ERROR_NON_FATAL; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } error_code; + } CPTRA_FW_ERROR_FATAL; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } error_code; + } CPTRA_FW_ERROR_NON_FATAL; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } error_code; + } CPTRA_HW_ERROR_ENC; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } error_code; + } CPTRA_FW_ERROR_ENC; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } error_info; + } [8-1:0]CPTRA_FW_EXTENDED_ERROR_INFO; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } status; + } CPTRA_BOOT_STATUS; + struct packed{ + struct packed{ + logic [23:0] next; + logic load_next; + } status; + struct packed{ + logic next; + logic load_next; + } idevid_csr_ready; + struct packed{ + logic next; + logic load_next; + } ready_for_mb_processing; + struct packed{ + logic next; + logic load_next; + } ready_for_runtime; + struct packed{ + logic next; + logic load_next; + } mailbox_flow_done; + } CPTRA_FLOW_STATUS; + struct packed{ + struct packed{ + logic next; + logic load_next; + } FW_UPD_RESET; + struct packed{ + logic next; + logic load_next; + } WARM_RESET; + } CPTRA_RESET_REASON; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } AXI_USER; + } [5-1:0]CPTRA_MBOX_VALID_AXI_USER; + struct packed{ + struct packed{ + logic next; + logic load_next; + } LOCK; + } [5-1:0]CPTRA_MBOX_AXI_USER_LOCK; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } AXI_USER; + } CPTRA_TRNG_VALID_AXI_USER; + struct packed{ + struct packed{ + logic next; + logic load_next; + } LOCK; + } CPTRA_TRNG_AXI_USER_LOCK; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } DATA; + } [12-1:0]CPTRA_TRNG_DATA; + struct packed{ + struct packed{ + logic next; + logic load_next; + } clear; + } CPTRA_TRNG_CTRL; + struct packed{ + struct packed{ + logic next; + logic load_next; + } DATA_REQ; + struct packed{ + logic next; + logic load_next; + } DATA_WR_DONE; + } CPTRA_TRNG_STATUS; + struct packed{ + struct packed{ + logic next; + logic load_next; + } done; + } CPTRA_FUSE_WR_DONE; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } clk_period; + } CPTRA_TIMER_CONFIG; + struct packed{ + struct packed{ + logic next; + logic load_next; + } GO; + } CPTRA_BOOTFSM_GO; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } DATA; + } CPTRA_DBG_MANUF_SERVICE_REG; + struct packed{ + struct packed{ + logic next; + logic load_next; + } clk_gating_en; + } CPTRA_CLK_GATING_EN; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } generic_wires; + } [2-1:0]CPTRA_GENERIC_INPUT_WIRES; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } generic_wires; + } [2-1:0]CPTRA_GENERIC_OUTPUT_WIRES; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } REV_ID; + } [2-1:0]CPTRA_FW_REV_ID; + struct packed{ + struct packed{ + logic next; + logic load_next; + } timer1_en; + } CPTRA_WDT_TIMER1_EN; + struct packed{ + struct packed{ + logic next; + logic load_next; + } timer1_restart; + } CPTRA_WDT_TIMER1_CTRL; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } timer1_timeout_period; + } [2-1:0]CPTRA_WDT_TIMER1_TIMEOUT_PERIOD; + struct packed{ + struct packed{ + logic next; + logic load_next; + } timer2_en; + } CPTRA_WDT_TIMER2_EN; + struct packed{ + struct packed{ + logic next; + logic load_next; + } timer2_restart; + } CPTRA_WDT_TIMER2_CTRL; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } timer2_timeout_period; + } [2-1:0]CPTRA_WDT_TIMER2_TIMEOUT_PERIOD; + struct packed{ + struct packed{ + logic next; + logic load_next; + } t1_timeout; + struct packed{ + logic next; + logic load_next; + } t2_timeout; + } CPTRA_WDT_STATUS; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } AXI_USER; + } CPTRA_FUSE_VALID_AXI_USER; + struct packed{ + struct packed{ + logic next; + logic load_next; + } LOCK; + } CPTRA_FUSE_AXI_USER_LOCK; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } TIMEOUT; + } [2-1:0]CPTRA_WDT_CFG; + struct packed{ + struct packed{ + logic [15:0] next; + logic load_next; + } low_threshold; + struct packed{ + logic [15:0] next; + logic load_next; + } high_threshold; + } CPTRA_iTRNG_ENTROPY_CONFIG_0; + struct packed{ + struct packed{ + logic [15:0] next; + logic load_next; + } repetition_count; + struct packed{ + logic [15:0] next; + logic load_next; + } RSVD; + } CPTRA_iTRNG_ENTROPY_CONFIG_1; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } RSVD; + } [2-1:0]CPTRA_RSVD_REG; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } cap; + } CPTRA_HW_CAPABILITIES; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } cap; + } CPTRA_FW_CAPABILITIES; + struct packed{ + struct packed{ + logic next; + logic load_next; + } lock; + } CPTRA_CAP_LOCK; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } hash; + } [12-1:0]CPTRA_OWNER_PK_HASH; + struct packed{ + struct packed{ + logic next; + logic load_next; + } lock; + } CPTRA_OWNER_PK_HASH_LOCK; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } seed; + } [16-1:0]fuse_uds_seed; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } seed; + } [8-1:0]fuse_field_entropy; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } hash; + } [12-1:0]fuse_vendor_pk_hash; + struct packed{ + struct packed{ + logic [3:0] next; + logic load_next; + } ecc_revocation; + } fuse_ecc_revocation; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } svn; + } fuse_fmc_key_manifest_svn; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } svn; + } [4-1:0]fuse_runtime_svn; + struct packed{ + struct packed{ + logic next; + logic load_next; + } dis; + } fuse_anti_rollback_disable; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } cert; + } [24-1:0]fuse_idevid_cert_attr; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } hsm_id; + } [4-1:0]fuse_idevid_manuf_hsm_id; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } lms_revocation; + } fuse_lms_revocation; + struct packed{ + struct packed{ + logic [3:0] next; + logic load_next; + } mldsa_revocation; + } fuse_mldsa_revocation; + struct packed{ + struct packed{ + logic [15:0] next; + logic load_next; + } soc_stepping_id; + } fuse_soc_stepping_id; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } token; + } [16-1:0]fuse_manuf_dbg_unlock_token; + struct packed{ + struct packed{ + logic [1:0] next; + logic load_next; + } key_type; + } fuse_pqc_key_type; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } svn; + } [4-1:0]fuse_soc_manifest_svn; + struct packed{ + struct packed{ + logic [7:0] next; + logic load_next; + } svn; + } fuse_soc_manifest_max_svn; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } seed; + } [8-1:0]fuse_hek_seed; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } addr_l; + } SS_CALIPTRA_BASE_ADDR_L; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } addr_h; + } SS_CALIPTRA_BASE_ADDR_H; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } addr_l; + } SS_MCI_BASE_ADDR_L; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } addr_h; + } SS_MCI_BASE_ADDR_H; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } addr_l; + } SS_RECOVERY_IFC_BASE_ADDR_L; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } addr_h; + } SS_RECOVERY_IFC_BASE_ADDR_H; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } addr_l; + } SS_OTP_FC_BASE_ADDR_L; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } addr_h; + } SS_OTP_FC_BASE_ADDR_H; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } addr_l; + } SS_UDS_SEED_BASE_ADDR_L; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } addr_h; + } SS_UDS_SEED_BASE_ADDR_H; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } offset; + } SS_PROD_DEBUG_UNLOCK_AUTH_PK_HASH_REG_BANK_OFFSET; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } num; + } SS_NUM_OF_PROD_DEBUG_UNLOCK_AUTH_PK_HASHES; + struct packed{ + struct packed{ + logic next; + logic load_next; + } debug_intent; + } SS_DEBUG_INTENT; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } user; + } SS_CALIPTRA_DMA_AXI_USER; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } addr_l; + } SS_EXTERNAL_STAGING_AREA_BASE_ADDR_L; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } addr_h; + } SS_EXTERNAL_STAGING_AREA_BASE_ADDR_H; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } addr_l; + } SS_KEY_RELEASE_BASE_ADDR_L; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } addr_h; + } SS_KEY_RELEASE_BASE_ADDR_H; + struct packed{ + struct packed{ + logic [15:0] next; + logic load_next; + } size; + } SS_KEY_RELEASE_SIZE; + struct packed{ + struct packed{ + logic next; + logic load_next; + } LOCK_IN_PROGRESS; + } SS_OCP_LOCK_CTRL; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } data; + } [4-1:0]SS_STRAP_GENERIC; + struct packed{ + struct packed{ + logic next; + logic load_next; + } MANUF_DBG_UNLOCK_REQ; + struct packed{ + logic next; + logic load_next; + } PROD_DBG_UNLOCK_REQ; + struct packed{ + logic next; + logic load_next; + } UDS_PROGRAM_REQ; + } SS_DBG_SERVICE_REG_REQ; + struct packed{ + struct packed{ + logic next; + logic load_next; + } MANUF_DBG_UNLOCK_SUCCESS; + struct packed{ + logic next; + logic load_next; + } MANUF_DBG_UNLOCK_FAIL; + struct packed{ + logic next; + logic load_next; + } MANUF_DBG_UNLOCK_IN_PROGRESS; + struct packed{ + logic next; + logic load_next; + } PROD_DBG_UNLOCK_SUCCESS; + struct packed{ + logic next; + logic load_next; + } PROD_DBG_UNLOCK_FAIL; + struct packed{ + logic next; + logic load_next; + } PROD_DBG_UNLOCK_IN_PROGRESS; + struct packed{ + logic next; + logic load_next; + } UDS_PROGRAM_SUCCESS; + struct packed{ + logic next; + logic load_next; + } UDS_PROGRAM_FAIL; + struct packed{ + logic next; + logic load_next; + } UDS_PROGRAM_IN_PROGRESS; + struct packed{ + logic next; + logic load_next; + } TAP_MAILBOX_AVAILABLE; + } SS_DBG_SERVICE_REG_RSP; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } LEVEL; + } [2-1:0]SS_SOC_DBG_UNLOCK_LEVEL; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } go; + } [4-1:0]SS_GENERIC_FW_EXEC_CTRL; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } key; + } [8-1:0]internal_obf_key; + struct packed{ + struct packed{ + logic next; + logic load_next; + } lock; + } internal_iccm_lock; + struct packed{ + struct packed{ + logic next; + logic load_next; + } core_rst; + } internal_fw_update_reset; + struct packed{ + struct packed{ + logic [7:0] next; + logic load_next; + } wait_cycles; + } internal_fw_update_reset_wait_cycles; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } vec; + } internal_nmi_vector; + struct packed{ + struct packed{ + logic next; + logic load_next; + } mask_iccm_ecc_unc; + struct packed{ + logic next; + logic load_next; + } mask_dccm_ecc_unc; + struct packed{ + logic next; + logic load_next; + } mask_nmi_pin; + } internal_hw_error_fatal_mask; + struct packed{ + struct packed{ + logic next; + logic load_next; + } mask_mbox_prot_no_lock; + struct packed{ + logic next; + logic load_next; + } mask_mbox_prot_ooo; + struct packed{ + logic next; + logic load_next; + } mask_mbox_ecc_unc; + } internal_hw_error_non_fatal_mask; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } mask; + } internal_fw_error_fatal_mask; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } mask; + } internal_fw_error_non_fatal_mask; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + logic incrthreshold; + logic overflow; + } count_l; + } internal_rv_mtime_l; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + logic incrthreshold; + logic overflow; + } count_h; + } internal_rv_mtime_h; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } compare_l; + } internal_rv_mtimecmp_l; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } compare_h; + } internal_rv_mtimecmp_h; + struct packed{ + struct packed{ + struct packed{ + logic next; + logic load_next; + } error_en; + struct packed{ + logic next; + logic load_next; + } notif_en; + } global_intr_en_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + } error_internal_en; + struct packed{ + logic next; + logic load_next; + } error_inv_dev_en; + struct packed{ + logic next; + logic load_next; + } error_cmd_fail_en; + struct packed{ + logic next; + logic load_next; + } error_bad_fuse_en; + struct packed{ + logic next; + logic load_next; + } error_iccm_blocked_en; + struct packed{ + logic next; + logic load_next; + } error_mbox_ecc_unc_en; + struct packed{ + logic next; + logic load_next; + } error_wdt_timer1_timeout_en; + struct packed{ + logic next; + logic load_next; + } error_wdt_timer2_timeout_en; + } error_intr_en_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + } notif_cmd_avail_en; + struct packed{ + logic next; + logic load_next; + } notif_mbox_ecc_cor_en; + struct packed{ + logic next; + logic load_next; + } notif_debug_locked_en; + struct packed{ + logic next; + logic load_next; + } notif_scan_mode_en; + struct packed{ + logic next; + logic load_next; + } notif_soc_req_lock_en; + struct packed{ + logic next; + logic load_next; + } notif_gen_in_toggle_en; + } notif_intr_en_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + } agg_sts; + } error_global_intr_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + } agg_sts; + } notif_global_intr_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + } error_internal_sts; + struct packed{ + logic next; + logic load_next; + } error_inv_dev_sts; + struct packed{ + logic next; + logic load_next; + } error_cmd_fail_sts; + struct packed{ + logic next; + logic load_next; + } error_bad_fuse_sts; + struct packed{ + logic next; + logic load_next; + } error_iccm_blocked_sts; + struct packed{ + logic next; + logic load_next; + } error_mbox_ecc_unc_sts; + struct packed{ + logic next; + logic load_next; + } error_wdt_timer1_timeout_sts; + struct packed{ + logic next; + logic load_next; + } error_wdt_timer2_timeout_sts; + } error_internal_intr_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + } notif_cmd_avail_sts; + struct packed{ + logic next; + logic load_next; + } notif_mbox_ecc_cor_sts; + struct packed{ + logic next; + logic load_next; + } notif_debug_locked_sts; + struct packed{ + logic next; + logic load_next; + } notif_scan_mode_sts; + struct packed{ + logic next; + logic load_next; + } notif_soc_req_lock_sts; + struct packed{ + logic next; + logic load_next; + } notif_gen_in_toggle_sts; + } notif_internal_intr_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + } error_internal_trig; + struct packed{ + logic next; + logic load_next; + } error_inv_dev_trig; + struct packed{ + logic next; + logic load_next; + } error_cmd_fail_trig; + struct packed{ + logic next; + logic load_next; + } error_bad_fuse_trig; + struct packed{ + logic next; + logic load_next; + } error_iccm_blocked_trig; + struct packed{ + logic next; + logic load_next; + } error_mbox_ecc_unc_trig; + struct packed{ + logic next; + logic load_next; + } error_wdt_timer1_timeout_trig; + struct packed{ + logic next; + logic load_next; + } error_wdt_timer2_timeout_trig; + } error_intr_trig_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + } notif_cmd_avail_trig; + struct packed{ + logic next; + logic load_next; + } notif_mbox_ecc_cor_trig; + struct packed{ + logic next; + logic load_next; + } notif_debug_locked_trig; + struct packed{ + logic next; + logic load_next; + } notif_scan_mode_trig; + struct packed{ + logic next; + logic load_next; + } notif_soc_req_lock_trig; + struct packed{ + logic next; + logic load_next; + } notif_gen_in_toggle_trig; + } notif_intr_trig_r; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + logic incrthreshold; + logic incrsaturate; + } cnt; + } error_internal_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + logic incrthreshold; + logic incrsaturate; + } cnt; + } error_inv_dev_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + logic incrthreshold; + logic incrsaturate; + } cnt; + } error_cmd_fail_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + logic incrthreshold; + logic incrsaturate; + } cnt; + } error_bad_fuse_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + logic incrthreshold; + logic incrsaturate; + } cnt; + } error_iccm_blocked_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + logic incrthreshold; + logic incrsaturate; + } cnt; + } error_mbox_ecc_unc_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + logic incrthreshold; + logic incrsaturate; + } cnt; + } error_wdt_timer1_timeout_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + logic incrthreshold; + logic incrsaturate; + } cnt; + } error_wdt_timer2_timeout_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + logic incrthreshold; + logic incrsaturate; + } cnt; + } notif_cmd_avail_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + logic incrthreshold; + logic incrsaturate; + } cnt; + } notif_mbox_ecc_cor_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + logic incrthreshold; + logic incrsaturate; + } cnt; + } notif_debug_locked_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + logic incrthreshold; + logic incrsaturate; + } cnt; + } notif_scan_mode_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + logic incrthreshold; + logic incrsaturate; + } cnt; + } notif_soc_req_lock_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + logic incrthreshold; + logic incrsaturate; + } cnt; + } notif_gen_in_toggle_intr_count_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + logic decrthreshold; + logic underflow; + } pulse; + } error_internal_intr_count_incr_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + logic decrthreshold; + logic underflow; + } pulse; + } error_inv_dev_intr_count_incr_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + logic decrthreshold; + logic underflow; + } pulse; + } error_cmd_fail_intr_count_incr_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + logic decrthreshold; + logic underflow; + } pulse; + } error_bad_fuse_intr_count_incr_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + logic decrthreshold; + logic underflow; + } pulse; + } error_iccm_blocked_intr_count_incr_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + logic decrthreshold; + logic underflow; + } pulse; + } error_mbox_ecc_unc_intr_count_incr_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + logic decrthreshold; + logic underflow; + } pulse; + } error_wdt_timer1_timeout_intr_count_incr_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + logic decrthreshold; + logic underflow; + } pulse; + } error_wdt_timer2_timeout_intr_count_incr_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + logic decrthreshold; + logic underflow; + } pulse; + } notif_cmd_avail_intr_count_incr_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + logic decrthreshold; + logic underflow; + } pulse; + } notif_mbox_ecc_cor_intr_count_incr_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + logic decrthreshold; + logic underflow; + } pulse; + } notif_debug_locked_intr_count_incr_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + logic decrthreshold; + logic underflow; + } pulse; + } notif_scan_mode_intr_count_incr_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + logic decrthreshold; + logic underflow; + } pulse; + } notif_soc_req_lock_intr_count_incr_r; + struct packed{ + struct packed{ + logic next; + logic load_next; + logic decrthreshold; + logic underflow; + } pulse; + } notif_gen_in_toggle_intr_count_incr_r; + } intr_block_rf; + } field_combo_t; + field_combo_t field_combo; + + typedef struct packed{ + struct packed{ + struct packed{ + logic value; + } iccm_ecc_unc; + struct packed{ + logic value; + } dccm_ecc_unc; + struct packed{ + logic value; + } nmi_pin; + struct packed{ + logic value; + } crypto_err; + } CPTRA_HW_ERROR_FATAL; + struct packed{ + struct packed{ + logic value; + } mbox_prot_no_lock; + struct packed{ + logic value; + } mbox_prot_ooo; + struct packed{ + logic value; + } mbox_ecc_unc; + } CPTRA_HW_ERROR_NON_FATAL; + struct packed{ + struct packed{ + logic [31:0] value; + } error_code; + } CPTRA_FW_ERROR_FATAL; + struct packed{ + struct packed{ + logic [31:0] value; + } error_code; + } CPTRA_FW_ERROR_NON_FATAL; + struct packed{ + struct packed{ + logic [31:0] value; + } error_code; + } CPTRA_HW_ERROR_ENC; + struct packed{ + struct packed{ + logic [31:0] value; + } error_code; + } CPTRA_FW_ERROR_ENC; + struct packed{ + struct packed{ + logic [31:0] value; + } error_info; + } [8-1:0]CPTRA_FW_EXTENDED_ERROR_INFO; + struct packed{ + struct packed{ + logic [31:0] value; + } status; + } CPTRA_BOOT_STATUS; + struct packed{ + struct packed{ + logic [23:0] value; + } status; + struct packed{ + logic value; + } idevid_csr_ready; + struct packed{ + logic value; + } ready_for_mb_processing; + struct packed{ + logic value; + } ready_for_runtime; + struct packed{ + logic value; + } mailbox_flow_done; + } CPTRA_FLOW_STATUS; + struct packed{ + struct packed{ + logic value; + } FW_UPD_RESET; + struct packed{ + logic value; + } WARM_RESET; + } CPTRA_RESET_REASON; + struct packed{ + struct packed{ + logic [31:0] value; + } AXI_USER; + } [5-1:0]CPTRA_MBOX_VALID_AXI_USER; + struct packed{ + struct packed{ + logic value; + } LOCK; + } [5-1:0]CPTRA_MBOX_AXI_USER_LOCK; + struct packed{ + struct packed{ + logic [31:0] value; + } AXI_USER; + } CPTRA_TRNG_VALID_AXI_USER; + struct packed{ + struct packed{ + logic value; + } LOCK; + } CPTRA_TRNG_AXI_USER_LOCK; + struct packed{ + struct packed{ + logic [31:0] value; + } DATA; + } [12-1:0]CPTRA_TRNG_DATA; + struct packed{ + struct packed{ + logic value; + } clear; + } CPTRA_TRNG_CTRL; + struct packed{ + struct packed{ + logic value; + } DATA_REQ; + struct packed{ + logic value; + } DATA_WR_DONE; + } CPTRA_TRNG_STATUS; + struct packed{ + struct packed{ + logic value; + } done; + } CPTRA_FUSE_WR_DONE; + struct packed{ + struct packed{ + logic [31:0] value; + } clk_period; + } CPTRA_TIMER_CONFIG; + struct packed{ + struct packed{ + logic value; + } GO; + } CPTRA_BOOTFSM_GO; + struct packed{ + struct packed{ + logic [31:0] value; + } DATA; + } CPTRA_DBG_MANUF_SERVICE_REG; + struct packed{ + struct packed{ + logic value; + } clk_gating_en; + } CPTRA_CLK_GATING_EN; + struct packed{ + struct packed{ + logic [31:0] value; + } generic_wires; + } [2-1:0]CPTRA_GENERIC_INPUT_WIRES; + struct packed{ + struct packed{ + logic [31:0] value; + } generic_wires; + } [2-1:0]CPTRA_GENERIC_OUTPUT_WIRES; + struct packed{ + struct packed{ + logic [31:0] value; + } REV_ID; + } [2-1:0]CPTRA_FW_REV_ID; + struct packed{ + struct packed{ + logic value; + } timer1_en; + } CPTRA_WDT_TIMER1_EN; + struct packed{ + struct packed{ + logic value; + } timer1_restart; + } CPTRA_WDT_TIMER1_CTRL; + struct packed{ + struct packed{ + logic [31:0] value; + } timer1_timeout_period; + } [2-1:0]CPTRA_WDT_TIMER1_TIMEOUT_PERIOD; + struct packed{ + struct packed{ + logic value; + } timer2_en; + } CPTRA_WDT_TIMER2_EN; + struct packed{ + struct packed{ + logic value; + } timer2_restart; + } CPTRA_WDT_TIMER2_CTRL; + struct packed{ + struct packed{ + logic [31:0] value; + } timer2_timeout_period; + } [2-1:0]CPTRA_WDT_TIMER2_TIMEOUT_PERIOD; + struct packed{ + struct packed{ + logic value; + } t1_timeout; + struct packed{ + logic value; + } t2_timeout; + } CPTRA_WDT_STATUS; + struct packed{ + struct packed{ + logic [31:0] value; + } AXI_USER; + } CPTRA_FUSE_VALID_AXI_USER; + struct packed{ + struct packed{ + logic value; + } LOCK; + } CPTRA_FUSE_AXI_USER_LOCK; + struct packed{ + struct packed{ + logic [31:0] value; + } TIMEOUT; + } [2-1:0]CPTRA_WDT_CFG; + struct packed{ + struct packed{ + logic [15:0] value; + } low_threshold; + struct packed{ + logic [15:0] value; + } high_threshold; + } CPTRA_iTRNG_ENTROPY_CONFIG_0; + struct packed{ + struct packed{ + logic [15:0] value; + } repetition_count; + struct packed{ + logic [15:0] value; + } RSVD; + } CPTRA_iTRNG_ENTROPY_CONFIG_1; + struct packed{ + struct packed{ + logic [31:0] value; + } RSVD; + } [2-1:0]CPTRA_RSVD_REG; + struct packed{ + struct packed{ + logic [31:0] value; + } cap; + } CPTRA_HW_CAPABILITIES; + struct packed{ + struct packed{ + logic [31:0] value; + } cap; + } CPTRA_FW_CAPABILITIES; + struct packed{ + struct packed{ + logic value; + } lock; + } CPTRA_CAP_LOCK; + struct packed{ + struct packed{ + logic [31:0] value; + } hash; + } [12-1:0]CPTRA_OWNER_PK_HASH; + struct packed{ + struct packed{ + logic value; + } lock; + } CPTRA_OWNER_PK_HASH_LOCK; + struct packed{ + struct packed{ + logic [31:0] value; + } seed; + } [16-1:0]fuse_uds_seed; + struct packed{ + struct packed{ + logic [31:0] value; + } seed; + } [8-1:0]fuse_field_entropy; + struct packed{ + struct packed{ + logic [31:0] value; + } hash; + } [12-1:0]fuse_vendor_pk_hash; + struct packed{ + struct packed{ + logic [3:0] value; + } ecc_revocation; + } fuse_ecc_revocation; + struct packed{ + struct packed{ + logic [31:0] value; + } svn; + } fuse_fmc_key_manifest_svn; + struct packed{ + struct packed{ + logic [31:0] value; + } svn; + } [4-1:0]fuse_runtime_svn; + struct packed{ + struct packed{ + logic value; + } dis; + } fuse_anti_rollback_disable; + struct packed{ + struct packed{ + logic [31:0] value; + } cert; + } [24-1:0]fuse_idevid_cert_attr; + struct packed{ + struct packed{ + logic [31:0] value; + } hsm_id; + } [4-1:0]fuse_idevid_manuf_hsm_id; + struct packed{ + struct packed{ + logic [31:0] value; + } lms_revocation; + } fuse_lms_revocation; + struct packed{ + struct packed{ + logic [3:0] value; + } mldsa_revocation; + } fuse_mldsa_revocation; + struct packed{ + struct packed{ + logic [15:0] value; + } soc_stepping_id; + } fuse_soc_stepping_id; + struct packed{ + struct packed{ + logic [31:0] value; + } token; + } [16-1:0]fuse_manuf_dbg_unlock_token; + struct packed{ + struct packed{ + logic [1:0] value; + } key_type; + } fuse_pqc_key_type; + struct packed{ + struct packed{ + logic [31:0] value; + } svn; + } [4-1:0]fuse_soc_manifest_svn; + struct packed{ + struct packed{ + logic [7:0] value; + } svn; + } fuse_soc_manifest_max_svn; + struct packed{ + struct packed{ + logic [31:0] value; + } seed; + } [8-1:0]fuse_hek_seed; + struct packed{ + struct packed{ + logic [31:0] value; + } addr_l; + } SS_CALIPTRA_BASE_ADDR_L; + struct packed{ + struct packed{ + logic [31:0] value; + } addr_h; + } SS_CALIPTRA_BASE_ADDR_H; + struct packed{ + struct packed{ + logic [31:0] value; + } addr_l; + } SS_MCI_BASE_ADDR_L; + struct packed{ + struct packed{ + logic [31:0] value; + } addr_h; + } SS_MCI_BASE_ADDR_H; + struct packed{ + struct packed{ + logic [31:0] value; + } addr_l; + } SS_RECOVERY_IFC_BASE_ADDR_L; + struct packed{ + struct packed{ + logic [31:0] value; + } addr_h; + } SS_RECOVERY_IFC_BASE_ADDR_H; + struct packed{ + struct packed{ + logic [31:0] value; + } addr_l; + } SS_OTP_FC_BASE_ADDR_L; + struct packed{ + struct packed{ + logic [31:0] value; + } addr_h; + } SS_OTP_FC_BASE_ADDR_H; + struct packed{ + struct packed{ + logic [31:0] value; + } addr_l; + } SS_UDS_SEED_BASE_ADDR_L; + struct packed{ + struct packed{ + logic [31:0] value; + } addr_h; + } SS_UDS_SEED_BASE_ADDR_H; + struct packed{ + struct packed{ + logic [31:0] value; + } offset; + } SS_PROD_DEBUG_UNLOCK_AUTH_PK_HASH_REG_BANK_OFFSET; + struct packed{ + struct packed{ + logic [31:0] value; + } num; + } SS_NUM_OF_PROD_DEBUG_UNLOCK_AUTH_PK_HASHES; + struct packed{ + struct packed{ + logic value; + } debug_intent; + } SS_DEBUG_INTENT; + struct packed{ + struct packed{ + logic [31:0] value; + } user; + } SS_CALIPTRA_DMA_AXI_USER; + struct packed{ + struct packed{ + logic [31:0] value; + } addr_l; + } SS_EXTERNAL_STAGING_AREA_BASE_ADDR_L; + struct packed{ + struct packed{ + logic [31:0] value; + } addr_h; + } SS_EXTERNAL_STAGING_AREA_BASE_ADDR_H; + struct packed{ + struct packed{ + logic [31:0] value; + } addr_l; + } SS_KEY_RELEASE_BASE_ADDR_L; + struct packed{ + struct packed{ + logic [31:0] value; + } addr_h; + } SS_KEY_RELEASE_BASE_ADDR_H; + struct packed{ + struct packed{ + logic [15:0] value; + } size; + } SS_KEY_RELEASE_SIZE; + struct packed{ + struct packed{ + logic value; + } LOCK_IN_PROGRESS; + } SS_OCP_LOCK_CTRL; + struct packed{ + struct packed{ + logic [31:0] value; + } data; + } [4-1:0]SS_STRAP_GENERIC; + struct packed{ + struct packed{ + logic value; + } MANUF_DBG_UNLOCK_REQ; + struct packed{ + logic value; + } PROD_DBG_UNLOCK_REQ; + struct packed{ + logic value; + } UDS_PROGRAM_REQ; + } SS_DBG_SERVICE_REG_REQ; + struct packed{ + struct packed{ + logic value; + } MANUF_DBG_UNLOCK_SUCCESS; + struct packed{ + logic value; + } MANUF_DBG_UNLOCK_FAIL; + struct packed{ + logic value; + } MANUF_DBG_UNLOCK_IN_PROGRESS; + struct packed{ + logic value; + } PROD_DBG_UNLOCK_SUCCESS; + struct packed{ + logic value; + } PROD_DBG_UNLOCK_FAIL; + struct packed{ + logic value; + } PROD_DBG_UNLOCK_IN_PROGRESS; + struct packed{ + logic value; + } UDS_PROGRAM_SUCCESS; + struct packed{ + logic value; + } UDS_PROGRAM_FAIL; + struct packed{ + logic value; + } UDS_PROGRAM_IN_PROGRESS; + struct packed{ + logic value; + } TAP_MAILBOX_AVAILABLE; + } SS_DBG_SERVICE_REG_RSP; + struct packed{ + struct packed{ + logic [31:0] value; + } LEVEL; + } [2-1:0]SS_SOC_DBG_UNLOCK_LEVEL; + struct packed{ + struct packed{ + logic [31:0] value; + } go; + } [4-1:0]SS_GENERIC_FW_EXEC_CTRL; + struct packed{ + struct packed{ + logic [31:0] value; + } key; + } [8-1:0]internal_obf_key; + struct packed{ + struct packed{ + logic value; + } lock; + } internal_iccm_lock; + struct packed{ + struct packed{ + logic value; + } core_rst; + } internal_fw_update_reset; + struct packed{ + struct packed{ + logic [7:0] value; + } wait_cycles; + } internal_fw_update_reset_wait_cycles; + struct packed{ + struct packed{ + logic [31:0] value; + } vec; + } internal_nmi_vector; + struct packed{ + struct packed{ + logic value; + } mask_iccm_ecc_unc; + struct packed{ + logic value; + } mask_dccm_ecc_unc; + struct packed{ + logic value; + } mask_nmi_pin; + } internal_hw_error_fatal_mask; + struct packed{ + struct packed{ + logic value; + } mask_mbox_prot_no_lock; + struct packed{ + logic value; + } mask_mbox_prot_ooo; + struct packed{ + logic value; + } mask_mbox_ecc_unc; + } internal_hw_error_non_fatal_mask; + struct packed{ + struct packed{ + logic [31:0] value; + } mask; + } internal_fw_error_fatal_mask; + struct packed{ + struct packed{ + logic [31:0] value; + } mask; + } internal_fw_error_non_fatal_mask; + struct packed{ + struct packed{ + logic [31:0] value; + } count_l; + } internal_rv_mtime_l; + struct packed{ + struct packed{ + logic [31:0] value; + } count_h; + } internal_rv_mtime_h; + struct packed{ + struct packed{ + logic [31:0] value; + } compare_l; + } internal_rv_mtimecmp_l; + struct packed{ + struct packed{ + logic [31:0] value; + } compare_h; + } internal_rv_mtimecmp_h; + struct packed{ + struct packed{ + struct packed{ + logic value; + } error_en; + struct packed{ + logic value; + } notif_en; + } global_intr_en_r; + struct packed{ + struct packed{ + logic value; + } error_internal_en; + struct packed{ + logic value; + } error_inv_dev_en; + struct packed{ + logic value; + } error_cmd_fail_en; + struct packed{ + logic value; + } error_bad_fuse_en; + struct packed{ + logic value; + } error_iccm_blocked_en; + struct packed{ + logic value; + } error_mbox_ecc_unc_en; + struct packed{ + logic value; + } error_wdt_timer1_timeout_en; + struct packed{ + logic value; + } error_wdt_timer2_timeout_en; + } error_intr_en_r; + struct packed{ + struct packed{ + logic value; + } notif_cmd_avail_en; + struct packed{ + logic value; + } notif_mbox_ecc_cor_en; + struct packed{ + logic value; + } notif_debug_locked_en; + struct packed{ + logic value; + } notif_scan_mode_en; + struct packed{ + logic value; + } notif_soc_req_lock_en; + struct packed{ + logic value; + } notif_gen_in_toggle_en; + } notif_intr_en_r; + struct packed{ + struct packed{ + logic value; + } agg_sts; + } error_global_intr_r; + struct packed{ + struct packed{ + logic value; + } agg_sts; + } notif_global_intr_r; + struct packed{ + struct packed{ + logic value; + } error_internal_sts; + struct packed{ + logic value; + } error_inv_dev_sts; + struct packed{ + logic value; + } error_cmd_fail_sts; + struct packed{ + logic value; + } error_bad_fuse_sts; + struct packed{ + logic value; + } error_iccm_blocked_sts; + struct packed{ + logic value; + } error_mbox_ecc_unc_sts; + struct packed{ + logic value; + } error_wdt_timer1_timeout_sts; + struct packed{ + logic value; + } error_wdt_timer2_timeout_sts; + } error_internal_intr_r; + struct packed{ + struct packed{ + logic value; + } notif_cmd_avail_sts; + struct packed{ + logic value; + } notif_mbox_ecc_cor_sts; + struct packed{ + logic value; + } notif_debug_locked_sts; + struct packed{ + logic value; + } notif_scan_mode_sts; + struct packed{ + logic value; + } notif_soc_req_lock_sts; + struct packed{ + logic value; + } notif_gen_in_toggle_sts; + } notif_internal_intr_r; + struct packed{ + struct packed{ + logic value; + } error_internal_trig; + struct packed{ + logic value; + } error_inv_dev_trig; + struct packed{ + logic value; + } error_cmd_fail_trig; + struct packed{ + logic value; + } error_bad_fuse_trig; + struct packed{ + logic value; + } error_iccm_blocked_trig; + struct packed{ + logic value; + } error_mbox_ecc_unc_trig; + struct packed{ + logic value; + } error_wdt_timer1_timeout_trig; + struct packed{ + logic value; + } error_wdt_timer2_timeout_trig; + } error_intr_trig_r; + struct packed{ + struct packed{ + logic value; + } notif_cmd_avail_trig; + struct packed{ + logic value; + } notif_mbox_ecc_cor_trig; + struct packed{ + logic value; + } notif_debug_locked_trig; + struct packed{ + logic value; + } notif_scan_mode_trig; + struct packed{ + logic value; + } notif_soc_req_lock_trig; + struct packed{ + logic value; + } notif_gen_in_toggle_trig; + } notif_intr_trig_r; + struct packed{ + struct packed{ + logic [31:0] value; + } cnt; + } error_internal_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] value; + } cnt; + } error_inv_dev_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] value; + } cnt; + } error_cmd_fail_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] value; + } cnt; + } error_bad_fuse_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] value; + } cnt; + } error_iccm_blocked_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] value; + } cnt; + } error_mbox_ecc_unc_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] value; + } cnt; + } error_wdt_timer1_timeout_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] value; + } cnt; + } error_wdt_timer2_timeout_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] value; + } cnt; + } notif_cmd_avail_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] value; + } cnt; + } notif_mbox_ecc_cor_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] value; + } cnt; + } notif_debug_locked_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] value; + } cnt; + } notif_scan_mode_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] value; + } cnt; + } notif_soc_req_lock_intr_count_r; + struct packed{ + struct packed{ + logic [31:0] value; + } cnt; + } notif_gen_in_toggle_intr_count_r; + struct packed{ + struct packed{ + logic value; + } pulse; + } error_internal_intr_count_incr_r; + struct packed{ + struct packed{ + logic value; + } pulse; + } error_inv_dev_intr_count_incr_r; + struct packed{ + struct packed{ + logic value; + } pulse; + } error_cmd_fail_intr_count_incr_r; + struct packed{ + struct packed{ + logic value; + } pulse; + } error_bad_fuse_intr_count_incr_r; + struct packed{ + struct packed{ + logic value; + } pulse; + } error_iccm_blocked_intr_count_incr_r; + struct packed{ + struct packed{ + logic value; + } pulse; + } error_mbox_ecc_unc_intr_count_incr_r; + struct packed{ + struct packed{ + logic value; + } pulse; + } error_wdt_timer1_timeout_intr_count_incr_r; + struct packed{ + struct packed{ + logic value; + } pulse; + } error_wdt_timer2_timeout_intr_count_incr_r; + struct packed{ + struct packed{ + logic value; + } pulse; + } notif_cmd_avail_intr_count_incr_r; + struct packed{ + struct packed{ + logic value; + } pulse; + } notif_mbox_ecc_cor_intr_count_incr_r; + struct packed{ + struct packed{ + logic value; + } pulse; + } notif_debug_locked_intr_count_incr_r; + struct packed{ + struct packed{ + logic value; + } pulse; + } notif_scan_mode_intr_count_incr_r; + struct packed{ + struct packed{ + logic value; + } pulse; + } notif_soc_req_lock_intr_count_incr_r; + struct packed{ + struct packed{ + logic value; + } pulse; + } notif_gen_in_toggle_intr_count_incr_r; + } intr_block_rf; + } field_storage_t; + field_storage_t field_storage; + + // Field: soc_ifc_reg.CPTRA_HW_ERROR_FATAL.iccm_ecc_unc + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.CPTRA_HW_ERROR_FATAL.iccm_ecc_unc.value; + load_next_c = '0; + if(decoded_reg_strb.CPTRA_HW_ERROR_FATAL && decoded_req_is_wr) begin // SW write 1 clear + next_c = field_storage.CPTRA_HW_ERROR_FATAL.iccm_ecc_unc.value & ~(decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end else if(hwif_in.CPTRA_HW_ERROR_FATAL.iccm_ecc_unc.we) begin // HW Write - we + next_c = hwif_in.CPTRA_HW_ERROR_FATAL.iccm_ecc_unc.next; + load_next_c = '1; + end + field_combo.CPTRA_HW_ERROR_FATAL.iccm_ecc_unc.next = next_c; + field_combo.CPTRA_HW_ERROR_FATAL.iccm_ecc_unc.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.CPTRA_HW_ERROR_FATAL.iccm_ecc_unc.value <= 1'h0; + end else if(field_combo.CPTRA_HW_ERROR_FATAL.iccm_ecc_unc.load_next) begin + field_storage.CPTRA_HW_ERROR_FATAL.iccm_ecc_unc.value <= field_combo.CPTRA_HW_ERROR_FATAL.iccm_ecc_unc.next; + end + end + assign hwif_out.CPTRA_HW_ERROR_FATAL.iccm_ecc_unc.value = field_storage.CPTRA_HW_ERROR_FATAL.iccm_ecc_unc.value; + // Field: soc_ifc_reg.CPTRA_HW_ERROR_FATAL.dccm_ecc_unc + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.CPTRA_HW_ERROR_FATAL.dccm_ecc_unc.value; + load_next_c = '0; + if(decoded_reg_strb.CPTRA_HW_ERROR_FATAL && decoded_req_is_wr) begin // SW write 1 clear + next_c = field_storage.CPTRA_HW_ERROR_FATAL.dccm_ecc_unc.value & ~(decoded_wr_data[1:1] & decoded_wr_biten[1:1]); + load_next_c = '1; + end else if(hwif_in.CPTRA_HW_ERROR_FATAL.dccm_ecc_unc.we) begin // HW Write - we + next_c = hwif_in.CPTRA_HW_ERROR_FATAL.dccm_ecc_unc.next; + load_next_c = '1; + end + field_combo.CPTRA_HW_ERROR_FATAL.dccm_ecc_unc.next = next_c; + field_combo.CPTRA_HW_ERROR_FATAL.dccm_ecc_unc.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.CPTRA_HW_ERROR_FATAL.dccm_ecc_unc.value <= 1'h0; + end else if(field_combo.CPTRA_HW_ERROR_FATAL.dccm_ecc_unc.load_next) begin + field_storage.CPTRA_HW_ERROR_FATAL.dccm_ecc_unc.value <= field_combo.CPTRA_HW_ERROR_FATAL.dccm_ecc_unc.next; + end + end + assign hwif_out.CPTRA_HW_ERROR_FATAL.dccm_ecc_unc.value = field_storage.CPTRA_HW_ERROR_FATAL.dccm_ecc_unc.value; + // Field: soc_ifc_reg.CPTRA_HW_ERROR_FATAL.nmi_pin + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.CPTRA_HW_ERROR_FATAL.nmi_pin.value; + load_next_c = '0; + if(decoded_reg_strb.CPTRA_HW_ERROR_FATAL && decoded_req_is_wr) begin // SW write 1 clear + next_c = field_storage.CPTRA_HW_ERROR_FATAL.nmi_pin.value & ~(decoded_wr_data[2:2] & decoded_wr_biten[2:2]); + load_next_c = '1; + end else if(hwif_in.CPTRA_HW_ERROR_FATAL.nmi_pin.we) begin // HW Write - we + next_c = hwif_in.CPTRA_HW_ERROR_FATAL.nmi_pin.next; + load_next_c = '1; + end + field_combo.CPTRA_HW_ERROR_FATAL.nmi_pin.next = next_c; + field_combo.CPTRA_HW_ERROR_FATAL.nmi_pin.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.CPTRA_HW_ERROR_FATAL.nmi_pin.value <= 1'h0; + end else if(field_combo.CPTRA_HW_ERROR_FATAL.nmi_pin.load_next) begin + field_storage.CPTRA_HW_ERROR_FATAL.nmi_pin.value <= field_combo.CPTRA_HW_ERROR_FATAL.nmi_pin.next; + end + end + assign hwif_out.CPTRA_HW_ERROR_FATAL.nmi_pin.value = field_storage.CPTRA_HW_ERROR_FATAL.nmi_pin.value; + // Field: soc_ifc_reg.CPTRA_HW_ERROR_FATAL.crypto_err + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.CPTRA_HW_ERROR_FATAL.crypto_err.value; + load_next_c = '0; + if(decoded_reg_strb.CPTRA_HW_ERROR_FATAL && decoded_req_is_wr) begin // SW write 1 clear + next_c = field_storage.CPTRA_HW_ERROR_FATAL.crypto_err.value & ~(decoded_wr_data[3:3] & decoded_wr_biten[3:3]); + load_next_c = '1; + end else if(hwif_in.CPTRA_HW_ERROR_FATAL.crypto_err.we) begin // HW Write - we + next_c = hwif_in.CPTRA_HW_ERROR_FATAL.crypto_err.next; + load_next_c = '1; + end + field_combo.CPTRA_HW_ERROR_FATAL.crypto_err.next = next_c; + field_combo.CPTRA_HW_ERROR_FATAL.crypto_err.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.CPTRA_HW_ERROR_FATAL.crypto_err.value <= 1'h0; + end else if(field_combo.CPTRA_HW_ERROR_FATAL.crypto_err.load_next) begin + field_storage.CPTRA_HW_ERROR_FATAL.crypto_err.value <= field_combo.CPTRA_HW_ERROR_FATAL.crypto_err.next; + end + end + assign hwif_out.CPTRA_HW_ERROR_FATAL.crypto_err.value = field_storage.CPTRA_HW_ERROR_FATAL.crypto_err.value; + // Field: soc_ifc_reg.CPTRA_HW_ERROR_NON_FATAL.mbox_prot_no_lock + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.CPTRA_HW_ERROR_NON_FATAL.mbox_prot_no_lock.value; + load_next_c = '0; + if(decoded_reg_strb.CPTRA_HW_ERROR_NON_FATAL && decoded_req_is_wr) begin // SW write 1 clear + next_c = field_storage.CPTRA_HW_ERROR_NON_FATAL.mbox_prot_no_lock.value & ~(decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end else if(hwif_in.CPTRA_HW_ERROR_NON_FATAL.mbox_prot_no_lock.we) begin // HW Write - we + next_c = hwif_in.CPTRA_HW_ERROR_NON_FATAL.mbox_prot_no_lock.next; + load_next_c = '1; + end + field_combo.CPTRA_HW_ERROR_NON_FATAL.mbox_prot_no_lock.next = next_c; + field_combo.CPTRA_HW_ERROR_NON_FATAL.mbox_prot_no_lock.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.CPTRA_HW_ERROR_NON_FATAL.mbox_prot_no_lock.value <= 1'h0; + end else if(field_combo.CPTRA_HW_ERROR_NON_FATAL.mbox_prot_no_lock.load_next) begin + field_storage.CPTRA_HW_ERROR_NON_FATAL.mbox_prot_no_lock.value <= field_combo.CPTRA_HW_ERROR_NON_FATAL.mbox_prot_no_lock.next; + end + end + assign hwif_out.CPTRA_HW_ERROR_NON_FATAL.mbox_prot_no_lock.value = field_storage.CPTRA_HW_ERROR_NON_FATAL.mbox_prot_no_lock.value; + // Field: soc_ifc_reg.CPTRA_HW_ERROR_NON_FATAL.mbox_prot_ooo + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.CPTRA_HW_ERROR_NON_FATAL.mbox_prot_ooo.value; + load_next_c = '0; + if(decoded_reg_strb.CPTRA_HW_ERROR_NON_FATAL && decoded_req_is_wr) begin // SW write 1 clear + next_c = field_storage.CPTRA_HW_ERROR_NON_FATAL.mbox_prot_ooo.value & ~(decoded_wr_data[1:1] & decoded_wr_biten[1:1]); + load_next_c = '1; + end else if(hwif_in.CPTRA_HW_ERROR_NON_FATAL.mbox_prot_ooo.we) begin // HW Write - we + next_c = hwif_in.CPTRA_HW_ERROR_NON_FATAL.mbox_prot_ooo.next; + load_next_c = '1; + end + field_combo.CPTRA_HW_ERROR_NON_FATAL.mbox_prot_ooo.next = next_c; + field_combo.CPTRA_HW_ERROR_NON_FATAL.mbox_prot_ooo.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.CPTRA_HW_ERROR_NON_FATAL.mbox_prot_ooo.value <= 1'h0; + end else if(field_combo.CPTRA_HW_ERROR_NON_FATAL.mbox_prot_ooo.load_next) begin + field_storage.CPTRA_HW_ERROR_NON_FATAL.mbox_prot_ooo.value <= field_combo.CPTRA_HW_ERROR_NON_FATAL.mbox_prot_ooo.next; + end + end + assign hwif_out.CPTRA_HW_ERROR_NON_FATAL.mbox_prot_ooo.value = field_storage.CPTRA_HW_ERROR_NON_FATAL.mbox_prot_ooo.value; + // Field: soc_ifc_reg.CPTRA_HW_ERROR_NON_FATAL.mbox_ecc_unc + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.CPTRA_HW_ERROR_NON_FATAL.mbox_ecc_unc.value; + load_next_c = '0; + if(decoded_reg_strb.CPTRA_HW_ERROR_NON_FATAL && decoded_req_is_wr) begin // SW write 1 clear + next_c = field_storage.CPTRA_HW_ERROR_NON_FATAL.mbox_ecc_unc.value & ~(decoded_wr_data[2:2] & decoded_wr_biten[2:2]); + load_next_c = '1; + end else if(hwif_in.CPTRA_HW_ERROR_NON_FATAL.mbox_ecc_unc.we) begin // HW Write - we + next_c = hwif_in.CPTRA_HW_ERROR_NON_FATAL.mbox_ecc_unc.next; + load_next_c = '1; + end + field_combo.CPTRA_HW_ERROR_NON_FATAL.mbox_ecc_unc.next = next_c; + field_combo.CPTRA_HW_ERROR_NON_FATAL.mbox_ecc_unc.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.CPTRA_HW_ERROR_NON_FATAL.mbox_ecc_unc.value <= 1'h0; + end else if(field_combo.CPTRA_HW_ERROR_NON_FATAL.mbox_ecc_unc.load_next) begin + field_storage.CPTRA_HW_ERROR_NON_FATAL.mbox_ecc_unc.value <= field_combo.CPTRA_HW_ERROR_NON_FATAL.mbox_ecc_unc.next; + end + end + assign hwif_out.CPTRA_HW_ERROR_NON_FATAL.mbox_ecc_unc.value = field_storage.CPTRA_HW_ERROR_NON_FATAL.mbox_ecc_unc.value; + // Field: soc_ifc_reg.CPTRA_FW_ERROR_FATAL.error_code + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.CPTRA_FW_ERROR_FATAL.error_code.value; + load_next_c = '0; + if(decoded_reg_strb.CPTRA_FW_ERROR_FATAL && decoded_req_is_wr) begin // SW write + next_c = (field_storage.CPTRA_FW_ERROR_FATAL.error_code.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end else if(hwif_in.CPTRA_FW_ERROR_FATAL.error_code.we) begin // HW Write - we + next_c = hwif_in.CPTRA_FW_ERROR_FATAL.error_code.next; + load_next_c = '1; + end + field_combo.CPTRA_FW_ERROR_FATAL.error_code.next = next_c; + field_combo.CPTRA_FW_ERROR_FATAL.error_code.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.CPTRA_FW_ERROR_FATAL.error_code.value <= 32'h0; + end else if(field_combo.CPTRA_FW_ERROR_FATAL.error_code.load_next) begin + field_storage.CPTRA_FW_ERROR_FATAL.error_code.value <= field_combo.CPTRA_FW_ERROR_FATAL.error_code.next; + end + end + assign hwif_out.CPTRA_FW_ERROR_FATAL.error_code.value = field_storage.CPTRA_FW_ERROR_FATAL.error_code.value; + assign hwif_out.CPTRA_FW_ERROR_FATAL.error_code.swmod = decoded_reg_strb.CPTRA_FW_ERROR_FATAL && decoded_req_is_wr; + // Field: soc_ifc_reg.CPTRA_FW_ERROR_NON_FATAL.error_code + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.CPTRA_FW_ERROR_NON_FATAL.error_code.value; + load_next_c = '0; + if(decoded_reg_strb.CPTRA_FW_ERROR_NON_FATAL && decoded_req_is_wr) begin // SW write + next_c = (field_storage.CPTRA_FW_ERROR_NON_FATAL.error_code.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end else if(hwif_in.CPTRA_FW_ERROR_NON_FATAL.error_code.we) begin // HW Write - we + next_c = hwif_in.CPTRA_FW_ERROR_NON_FATAL.error_code.next; + load_next_c = '1; + end + field_combo.CPTRA_FW_ERROR_NON_FATAL.error_code.next = next_c; + field_combo.CPTRA_FW_ERROR_NON_FATAL.error_code.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.CPTRA_FW_ERROR_NON_FATAL.error_code.value <= 32'h0; + end else if(field_combo.CPTRA_FW_ERROR_NON_FATAL.error_code.load_next) begin + field_storage.CPTRA_FW_ERROR_NON_FATAL.error_code.value <= field_combo.CPTRA_FW_ERROR_NON_FATAL.error_code.next; + end + end + assign hwif_out.CPTRA_FW_ERROR_NON_FATAL.error_code.value = field_storage.CPTRA_FW_ERROR_NON_FATAL.error_code.value; + assign hwif_out.CPTRA_FW_ERROR_NON_FATAL.error_code.swmod = decoded_reg_strb.CPTRA_FW_ERROR_NON_FATAL && decoded_req_is_wr; + // Field: soc_ifc_reg.CPTRA_HW_ERROR_ENC.error_code + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.CPTRA_HW_ERROR_ENC.error_code.value; + load_next_c = '0; + if(decoded_reg_strb.CPTRA_HW_ERROR_ENC && decoded_req_is_wr) begin // SW write + next_c = (field_storage.CPTRA_HW_ERROR_ENC.error_code.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + field_combo.CPTRA_HW_ERROR_ENC.error_code.next = next_c; + field_combo.CPTRA_HW_ERROR_ENC.error_code.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.CPTRA_HW_ERROR_ENC.error_code.value <= 32'h0; + end else if(field_combo.CPTRA_HW_ERROR_ENC.error_code.load_next) begin + field_storage.CPTRA_HW_ERROR_ENC.error_code.value <= field_combo.CPTRA_HW_ERROR_ENC.error_code.next; + end + end + assign hwif_out.CPTRA_HW_ERROR_ENC.error_code.value = field_storage.CPTRA_HW_ERROR_ENC.error_code.value; + // Field: soc_ifc_reg.CPTRA_FW_ERROR_ENC.error_code + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.CPTRA_FW_ERROR_ENC.error_code.value; + load_next_c = '0; + if(decoded_reg_strb.CPTRA_FW_ERROR_ENC && decoded_req_is_wr) begin // SW write + next_c = (field_storage.CPTRA_FW_ERROR_ENC.error_code.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + field_combo.CPTRA_FW_ERROR_ENC.error_code.next = next_c; + field_combo.CPTRA_FW_ERROR_ENC.error_code.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.CPTRA_FW_ERROR_ENC.error_code.value <= 32'h0; + end else if(field_combo.CPTRA_FW_ERROR_ENC.error_code.load_next) begin + field_storage.CPTRA_FW_ERROR_ENC.error_code.value <= field_combo.CPTRA_FW_ERROR_ENC.error_code.next; + end + end + assign hwif_out.CPTRA_FW_ERROR_ENC.error_code.value = field_storage.CPTRA_FW_ERROR_ENC.error_code.value; + for(genvar i0=0; i0<8; i0++) begin + // Field: soc_ifc_reg.CPTRA_FW_EXTENDED_ERROR_INFO[].error_info + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.CPTRA_FW_EXTENDED_ERROR_INFO[i0].error_info.value; + load_next_c = '0; + if(decoded_reg_strb.CPTRA_FW_EXTENDED_ERROR_INFO[i0] && decoded_req_is_wr) begin // SW write + next_c = (field_storage.CPTRA_FW_EXTENDED_ERROR_INFO[i0].error_info.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + field_combo.CPTRA_FW_EXTENDED_ERROR_INFO[i0].error_info.next = next_c; + field_combo.CPTRA_FW_EXTENDED_ERROR_INFO[i0].error_info.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.CPTRA_FW_EXTENDED_ERROR_INFO[i0].error_info.value <= 32'h0; + end else if(field_combo.CPTRA_FW_EXTENDED_ERROR_INFO[i0].error_info.load_next) begin + field_storage.CPTRA_FW_EXTENDED_ERROR_INFO[i0].error_info.value <= field_combo.CPTRA_FW_EXTENDED_ERROR_INFO[i0].error_info.next; + end + end + assign hwif_out.CPTRA_FW_EXTENDED_ERROR_INFO[i0].error_info.value = field_storage.CPTRA_FW_EXTENDED_ERROR_INFO[i0].error_info.value; + end + // Field: soc_ifc_reg.CPTRA_BOOT_STATUS.status + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.CPTRA_BOOT_STATUS.status.value; + load_next_c = '0; + if(decoded_reg_strb.CPTRA_BOOT_STATUS && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.CPTRA_BOOT_STATUS.status.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + field_combo.CPTRA_BOOT_STATUS.status.next = next_c; + field_combo.CPTRA_BOOT_STATUS.status.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.CPTRA_BOOT_STATUS.status.value <= 32'h0; + end else if(field_combo.CPTRA_BOOT_STATUS.status.load_next) begin + field_storage.CPTRA_BOOT_STATUS.status.value <= field_combo.CPTRA_BOOT_STATUS.status.next; + end + end + assign hwif_out.CPTRA_BOOT_STATUS.status.value = field_storage.CPTRA_BOOT_STATUS.status.value; + // Field: soc_ifc_reg.CPTRA_FLOW_STATUS.status + always_comb begin + automatic logic [23:0] next_c; + automatic logic load_next_c; + next_c = field_storage.CPTRA_FLOW_STATUS.status.value; + load_next_c = '0; + if(decoded_reg_strb.CPTRA_FLOW_STATUS && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.CPTRA_FLOW_STATUS.status.value & ~decoded_wr_biten[23:0]) | (decoded_wr_data[23:0] & decoded_wr_biten[23:0]); + load_next_c = '1; + end + field_combo.CPTRA_FLOW_STATUS.status.next = next_c; + field_combo.CPTRA_FLOW_STATUS.status.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.CPTRA_FLOW_STATUS.status.value <= 24'h0; + end else if(field_combo.CPTRA_FLOW_STATUS.status.load_next) begin + field_storage.CPTRA_FLOW_STATUS.status.value <= field_combo.CPTRA_FLOW_STATUS.status.next; + end + end + // Field: soc_ifc_reg.CPTRA_FLOW_STATUS.idevid_csr_ready + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.CPTRA_FLOW_STATUS.idevid_csr_ready.value; + load_next_c = '0; + if(decoded_reg_strb.CPTRA_FLOW_STATUS && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.CPTRA_FLOW_STATUS.idevid_csr_ready.value & ~decoded_wr_biten[24:24]) | (decoded_wr_data[24:24] & decoded_wr_biten[24:24]); + load_next_c = '1; + end + field_combo.CPTRA_FLOW_STATUS.idevid_csr_ready.next = next_c; + field_combo.CPTRA_FLOW_STATUS.idevid_csr_ready.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.CPTRA_FLOW_STATUS.idevid_csr_ready.value <= 1'h0; + end else if(field_combo.CPTRA_FLOW_STATUS.idevid_csr_ready.load_next) begin + field_storage.CPTRA_FLOW_STATUS.idevid_csr_ready.value <= field_combo.CPTRA_FLOW_STATUS.idevid_csr_ready.next; + end + end + assign hwif_out.CPTRA_FLOW_STATUS.idevid_csr_ready.value = field_storage.CPTRA_FLOW_STATUS.idevid_csr_ready.value; + // Field: soc_ifc_reg.CPTRA_FLOW_STATUS.ready_for_mb_processing + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.CPTRA_FLOW_STATUS.ready_for_mb_processing.value; + load_next_c = '0; + if(decoded_reg_strb.CPTRA_FLOW_STATUS && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.CPTRA_FLOW_STATUS.ready_for_mb_processing.value & ~decoded_wr_biten[28:28]) | (decoded_wr_data[28:28] & decoded_wr_biten[28:28]); + load_next_c = '1; + end + field_combo.CPTRA_FLOW_STATUS.ready_for_mb_processing.next = next_c; + field_combo.CPTRA_FLOW_STATUS.ready_for_mb_processing.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.CPTRA_FLOW_STATUS.ready_for_mb_processing.value <= 1'h0; + end else if(field_combo.CPTRA_FLOW_STATUS.ready_for_mb_processing.load_next) begin + field_storage.CPTRA_FLOW_STATUS.ready_for_mb_processing.value <= field_combo.CPTRA_FLOW_STATUS.ready_for_mb_processing.next; + end + end + assign hwif_out.CPTRA_FLOW_STATUS.ready_for_mb_processing.value = field_storage.CPTRA_FLOW_STATUS.ready_for_mb_processing.value; + // Field: soc_ifc_reg.CPTRA_FLOW_STATUS.ready_for_runtime + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.CPTRA_FLOW_STATUS.ready_for_runtime.value; + load_next_c = '0; + if(decoded_reg_strb.CPTRA_FLOW_STATUS && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.CPTRA_FLOW_STATUS.ready_for_runtime.value & ~decoded_wr_biten[29:29]) | (decoded_wr_data[29:29] & decoded_wr_biten[29:29]); + load_next_c = '1; + end + field_combo.CPTRA_FLOW_STATUS.ready_for_runtime.next = next_c; + field_combo.CPTRA_FLOW_STATUS.ready_for_runtime.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.CPTRA_FLOW_STATUS.ready_for_runtime.value <= 1'h0; + end else if(field_combo.CPTRA_FLOW_STATUS.ready_for_runtime.load_next) begin + field_storage.CPTRA_FLOW_STATUS.ready_for_runtime.value <= field_combo.CPTRA_FLOW_STATUS.ready_for_runtime.next; + end + end + assign hwif_out.CPTRA_FLOW_STATUS.ready_for_runtime.value = field_storage.CPTRA_FLOW_STATUS.ready_for_runtime.value; + // Field: soc_ifc_reg.CPTRA_FLOW_STATUS.mailbox_flow_done + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.CPTRA_FLOW_STATUS.mailbox_flow_done.value; + load_next_c = '0; + if(decoded_reg_strb.CPTRA_FLOW_STATUS && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.CPTRA_FLOW_STATUS.mailbox_flow_done.value & ~decoded_wr_biten[31:31]) | (decoded_wr_data[31:31] & decoded_wr_biten[31:31]); + load_next_c = '1; + end + field_combo.CPTRA_FLOW_STATUS.mailbox_flow_done.next = next_c; + field_combo.CPTRA_FLOW_STATUS.mailbox_flow_done.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.CPTRA_FLOW_STATUS.mailbox_flow_done.value <= 1'h0; + end else if(field_combo.CPTRA_FLOW_STATUS.mailbox_flow_done.load_next) begin + field_storage.CPTRA_FLOW_STATUS.mailbox_flow_done.value <= field_combo.CPTRA_FLOW_STATUS.mailbox_flow_done.next; + end + end + assign hwif_out.CPTRA_FLOW_STATUS.mailbox_flow_done.value = field_storage.CPTRA_FLOW_STATUS.mailbox_flow_done.value; + // Field: soc_ifc_reg.CPTRA_RESET_REASON.FW_UPD_RESET + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.CPTRA_RESET_REASON.FW_UPD_RESET.value; + load_next_c = '0; + if(hwif_in.CPTRA_RESET_REASON.FW_UPD_RESET.we) begin // HW Write - we + next_c = hwif_in.CPTRA_RESET_REASON.FW_UPD_RESET.next; + load_next_c = '1; + end + field_combo.CPTRA_RESET_REASON.FW_UPD_RESET.next = next_c; + field_combo.CPTRA_RESET_REASON.FW_UPD_RESET.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.CPTRA_RESET_REASON.FW_UPD_RESET.value <= 1'h0; + end else if(field_combo.CPTRA_RESET_REASON.FW_UPD_RESET.load_next) begin + field_storage.CPTRA_RESET_REASON.FW_UPD_RESET.value <= field_combo.CPTRA_RESET_REASON.FW_UPD_RESET.next; + end + end + assign hwif_out.CPTRA_RESET_REASON.FW_UPD_RESET.value = field_storage.CPTRA_RESET_REASON.FW_UPD_RESET.value; + // Field: soc_ifc_reg.CPTRA_RESET_REASON.WARM_RESET + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.CPTRA_RESET_REASON.WARM_RESET.value; + load_next_c = '0; + + // HW Write + next_c = hwif_in.CPTRA_RESET_REASON.WARM_RESET.next; + load_next_c = '1; + field_combo.CPTRA_RESET_REASON.WARM_RESET.next = next_c; + field_combo.CPTRA_RESET_REASON.WARM_RESET.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.CPTRA_RESET_REASON.WARM_RESET.value <= 1'h0; + end else if(field_combo.CPTRA_RESET_REASON.WARM_RESET.load_next) begin + field_storage.CPTRA_RESET_REASON.WARM_RESET.value <= field_combo.CPTRA_RESET_REASON.WARM_RESET.next; + end + end + assign hwif_out.CPTRA_RESET_REASON.WARM_RESET.value = field_storage.CPTRA_RESET_REASON.WARM_RESET.value; + for(genvar i0=0; i0<5; i0++) begin + // Field: soc_ifc_reg.CPTRA_MBOX_VALID_AXI_USER[].AXI_USER + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.CPTRA_MBOX_VALID_AXI_USER[i0].AXI_USER.value; + load_next_c = '0; + if(decoded_reg_strb.CPTRA_MBOX_VALID_AXI_USER[i0] && decoded_req_is_wr && !(hwif_in.CPTRA_MBOX_VALID_AXI_USER[i0].AXI_USER.swwel)) begin // SW write + next_c = (field_storage.CPTRA_MBOX_VALID_AXI_USER[i0].AXI_USER.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + field_combo.CPTRA_MBOX_VALID_AXI_USER[i0].AXI_USER.next = next_c; + field_combo.CPTRA_MBOX_VALID_AXI_USER[i0].AXI_USER.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.CPTRA_MBOX_VALID_AXI_USER[i0].AXI_USER.value <= 32'hffffffff; + end else if(field_combo.CPTRA_MBOX_VALID_AXI_USER[i0].AXI_USER.load_next) begin + field_storage.CPTRA_MBOX_VALID_AXI_USER[i0].AXI_USER.value <= field_combo.CPTRA_MBOX_VALID_AXI_USER[i0].AXI_USER.next; + end + end + assign hwif_out.CPTRA_MBOX_VALID_AXI_USER[i0].AXI_USER.value = field_storage.CPTRA_MBOX_VALID_AXI_USER[i0].AXI_USER.value; + end + for(genvar i0=0; i0<5; i0++) begin + // Field: soc_ifc_reg.CPTRA_MBOX_AXI_USER_LOCK[].LOCK + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.CPTRA_MBOX_AXI_USER_LOCK[i0].LOCK.value; + load_next_c = '0; + if(decoded_reg_strb.CPTRA_MBOX_AXI_USER_LOCK[i0] && decoded_req_is_wr && !(hwif_in.CPTRA_MBOX_AXI_USER_LOCK[i0].LOCK.swwel)) begin // SW write + next_c = (field_storage.CPTRA_MBOX_AXI_USER_LOCK[i0].LOCK.value & ~decoded_wr_biten[0:0]) | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end + field_combo.CPTRA_MBOX_AXI_USER_LOCK[i0].LOCK.next = next_c; + field_combo.CPTRA_MBOX_AXI_USER_LOCK[i0].LOCK.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.CPTRA_MBOX_AXI_USER_LOCK[i0].LOCK.value <= 1'h0; + end else if(field_combo.CPTRA_MBOX_AXI_USER_LOCK[i0].LOCK.load_next) begin + field_storage.CPTRA_MBOX_AXI_USER_LOCK[i0].LOCK.value <= field_combo.CPTRA_MBOX_AXI_USER_LOCK[i0].LOCK.next; + end + end + assign hwif_out.CPTRA_MBOX_AXI_USER_LOCK[i0].LOCK.value = field_storage.CPTRA_MBOX_AXI_USER_LOCK[i0].LOCK.value; + end + // Field: soc_ifc_reg.CPTRA_TRNG_VALID_AXI_USER.AXI_USER + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.CPTRA_TRNG_VALID_AXI_USER.AXI_USER.value; + load_next_c = '0; + if(decoded_reg_strb.CPTRA_TRNG_VALID_AXI_USER && decoded_req_is_wr && !(hwif_in.CPTRA_TRNG_VALID_AXI_USER.AXI_USER.swwel)) begin // SW write + next_c = (field_storage.CPTRA_TRNG_VALID_AXI_USER.AXI_USER.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + field_combo.CPTRA_TRNG_VALID_AXI_USER.AXI_USER.next = next_c; + field_combo.CPTRA_TRNG_VALID_AXI_USER.AXI_USER.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.CPTRA_TRNG_VALID_AXI_USER.AXI_USER.value <= 32'hffffffff; + end else if(field_combo.CPTRA_TRNG_VALID_AXI_USER.AXI_USER.load_next) begin + field_storage.CPTRA_TRNG_VALID_AXI_USER.AXI_USER.value <= field_combo.CPTRA_TRNG_VALID_AXI_USER.AXI_USER.next; + end + end + assign hwif_out.CPTRA_TRNG_VALID_AXI_USER.AXI_USER.value = field_storage.CPTRA_TRNG_VALID_AXI_USER.AXI_USER.value; + // Field: soc_ifc_reg.CPTRA_TRNG_AXI_USER_LOCK.LOCK + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.CPTRA_TRNG_AXI_USER_LOCK.LOCK.value; + load_next_c = '0; + if(decoded_reg_strb.CPTRA_TRNG_AXI_USER_LOCK && decoded_req_is_wr && !(hwif_in.CPTRA_TRNG_AXI_USER_LOCK.LOCK.swwel)) begin // SW write + next_c = (field_storage.CPTRA_TRNG_AXI_USER_LOCK.LOCK.value & ~decoded_wr_biten[0:0]) | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end + field_combo.CPTRA_TRNG_AXI_USER_LOCK.LOCK.next = next_c; + field_combo.CPTRA_TRNG_AXI_USER_LOCK.LOCK.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.CPTRA_TRNG_AXI_USER_LOCK.LOCK.value <= 1'h0; + end else if(field_combo.CPTRA_TRNG_AXI_USER_LOCK.LOCK.load_next) begin + field_storage.CPTRA_TRNG_AXI_USER_LOCK.LOCK.value <= field_combo.CPTRA_TRNG_AXI_USER_LOCK.LOCK.next; + end + end + assign hwif_out.CPTRA_TRNG_AXI_USER_LOCK.LOCK.value = field_storage.CPTRA_TRNG_AXI_USER_LOCK.LOCK.value; + for(genvar i0=0; i0<12; i0++) begin + // Field: soc_ifc_reg.CPTRA_TRNG_DATA[].DATA + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.CPTRA_TRNG_DATA[i0].DATA.value; + load_next_c = '0; + if(decoded_reg_strb.CPTRA_TRNG_DATA[i0] && decoded_req_is_wr && hwif_in.CPTRA_TRNG_DATA[i0].DATA.swwe) begin // SW write + next_c = (field_storage.CPTRA_TRNG_DATA[i0].DATA.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end else if(hwif_in.CPTRA_TRNG_DATA[i0].DATA.hwclr) begin // HW Clear + next_c = '0; + load_next_c = '1; + end + field_combo.CPTRA_TRNG_DATA[i0].DATA.next = next_c; + field_combo.CPTRA_TRNG_DATA[i0].DATA.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.CPTRA_TRNG_DATA[i0].DATA.value <= 32'h0; + end else if(field_combo.CPTRA_TRNG_DATA[i0].DATA.load_next) begin + field_storage.CPTRA_TRNG_DATA[i0].DATA.value <= field_combo.CPTRA_TRNG_DATA[i0].DATA.next; + end + end + assign hwif_out.CPTRA_TRNG_DATA[i0].DATA.swacc = decoded_reg_strb.CPTRA_TRNG_DATA[i0]; + end + // Field: soc_ifc_reg.CPTRA_TRNG_CTRL.clear + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.CPTRA_TRNG_CTRL.clear.value; + load_next_c = '0; + if(decoded_reg_strb.CPTRA_TRNG_CTRL && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.CPTRA_TRNG_CTRL.clear.value & ~decoded_wr_biten[0:0]) | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end else begin // singlepulse clears back to 0 + next_c = '0; + load_next_c = '1; + end + field_combo.CPTRA_TRNG_CTRL.clear.next = next_c; + field_combo.CPTRA_TRNG_CTRL.clear.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.CPTRA_TRNG_CTRL.clear.value <= 1'h0; + end else if(field_combo.CPTRA_TRNG_CTRL.clear.load_next) begin + field_storage.CPTRA_TRNG_CTRL.clear.value <= field_combo.CPTRA_TRNG_CTRL.clear.next; + end + end + assign hwif_out.CPTRA_TRNG_CTRL.clear.value = field_storage.CPTRA_TRNG_CTRL.clear.value; + // Field: soc_ifc_reg.CPTRA_TRNG_STATUS.DATA_REQ + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.CPTRA_TRNG_STATUS.DATA_REQ.value; + load_next_c = '0; + if(decoded_reg_strb.CPTRA_TRNG_STATUS && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.CPTRA_TRNG_STATUS.DATA_REQ.value & ~decoded_wr_biten[0:0]) | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end + field_combo.CPTRA_TRNG_STATUS.DATA_REQ.next = next_c; + field_combo.CPTRA_TRNG_STATUS.DATA_REQ.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.CPTRA_TRNG_STATUS.DATA_REQ.value <= 1'h0; + end else if(field_combo.CPTRA_TRNG_STATUS.DATA_REQ.load_next) begin + field_storage.CPTRA_TRNG_STATUS.DATA_REQ.value <= field_combo.CPTRA_TRNG_STATUS.DATA_REQ.next; + end + end + assign hwif_out.CPTRA_TRNG_STATUS.DATA_REQ.value = field_storage.CPTRA_TRNG_STATUS.DATA_REQ.value; + // Field: soc_ifc_reg.CPTRA_TRNG_STATUS.DATA_WR_DONE + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.CPTRA_TRNG_STATUS.DATA_WR_DONE.value; + load_next_c = '0; + if(decoded_reg_strb.CPTRA_TRNG_STATUS && decoded_req_is_wr && hwif_in.CPTRA_TRNG_STATUS.DATA_WR_DONE.swwe) begin // SW write + next_c = (field_storage.CPTRA_TRNG_STATUS.DATA_WR_DONE.value & ~decoded_wr_biten[1:1]) | (decoded_wr_data[1:1] & decoded_wr_biten[1:1]); + load_next_c = '1; + end else if(hwif_in.CPTRA_TRNG_STATUS.DATA_WR_DONE.hwclr) begin // HW Clear + next_c = '0; + load_next_c = '1; + end + field_combo.CPTRA_TRNG_STATUS.DATA_WR_DONE.next = next_c; + field_combo.CPTRA_TRNG_STATUS.DATA_WR_DONE.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.CPTRA_TRNG_STATUS.DATA_WR_DONE.value <= 1'h0; + end else if(field_combo.CPTRA_TRNG_STATUS.DATA_WR_DONE.load_next) begin + field_storage.CPTRA_TRNG_STATUS.DATA_WR_DONE.value <= field_combo.CPTRA_TRNG_STATUS.DATA_WR_DONE.next; + end + end + // Field: soc_ifc_reg.CPTRA_FUSE_WR_DONE.done + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.CPTRA_FUSE_WR_DONE.done.value; + load_next_c = '0; + if(decoded_reg_strb.CPTRA_FUSE_WR_DONE && decoded_req_is_wr && hwif_in.CPTRA_FUSE_WR_DONE.done.swwe) begin // SW write + next_c = (field_storage.CPTRA_FUSE_WR_DONE.done.value & ~decoded_wr_biten[0:0]) | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end + field_combo.CPTRA_FUSE_WR_DONE.done.next = next_c; + field_combo.CPTRA_FUSE_WR_DONE.done.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.CPTRA_FUSE_WR_DONE.done.value <= 1'h0; + end else if(field_combo.CPTRA_FUSE_WR_DONE.done.load_next) begin + field_storage.CPTRA_FUSE_WR_DONE.done.value <= field_combo.CPTRA_FUSE_WR_DONE.done.next; + end + end + assign hwif_out.CPTRA_FUSE_WR_DONE.done.value = field_storage.CPTRA_FUSE_WR_DONE.done.value; + assign hwif_out.CPTRA_FUSE_WR_DONE.done.swmod = decoded_reg_strb.CPTRA_FUSE_WR_DONE && decoded_req_is_wr; + // Field: soc_ifc_reg.CPTRA_TIMER_CONFIG.clk_period + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.CPTRA_TIMER_CONFIG.clk_period.value; + load_next_c = '0; + if(decoded_reg_strb.CPTRA_TIMER_CONFIG && decoded_req_is_wr) begin // SW write + next_c = (field_storage.CPTRA_TIMER_CONFIG.clk_period.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + field_combo.CPTRA_TIMER_CONFIG.clk_period.next = next_c; + field_combo.CPTRA_TIMER_CONFIG.clk_period.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.CPTRA_TIMER_CONFIG.clk_period.value <= 32'h0; + end else if(field_combo.CPTRA_TIMER_CONFIG.clk_period.load_next) begin + field_storage.CPTRA_TIMER_CONFIG.clk_period.value <= field_combo.CPTRA_TIMER_CONFIG.clk_period.next; + end + end + // Field: soc_ifc_reg.CPTRA_BOOTFSM_GO.GO + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.CPTRA_BOOTFSM_GO.GO.value; + load_next_c = '0; + if(decoded_reg_strb.CPTRA_BOOTFSM_GO && decoded_req_is_wr && hwif_in.soc_req) begin // SW write + next_c = (field_storage.CPTRA_BOOTFSM_GO.GO.value & ~decoded_wr_biten[0:0]) | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end else if(hwif_in.CPTRA_BOOTFSM_GO.GO.we) begin // HW Write - we + next_c = hwif_in.CPTRA_BOOTFSM_GO.GO.next; + load_next_c = '1; + end + field_combo.CPTRA_BOOTFSM_GO.GO.next = next_c; + field_combo.CPTRA_BOOTFSM_GO.GO.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.CPTRA_BOOTFSM_GO.GO.value <= 1'h0; + end else if(field_combo.CPTRA_BOOTFSM_GO.GO.load_next) begin + field_storage.CPTRA_BOOTFSM_GO.GO.value <= field_combo.CPTRA_BOOTFSM_GO.GO.next; + end + end + assign hwif_out.CPTRA_BOOTFSM_GO.GO.value = field_storage.CPTRA_BOOTFSM_GO.GO.value; + // Field: soc_ifc_reg.CPTRA_DBG_MANUF_SERVICE_REG.DATA + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.CPTRA_DBG_MANUF_SERVICE_REG.DATA.value; + load_next_c = '0; + if(decoded_reg_strb.CPTRA_DBG_MANUF_SERVICE_REG && decoded_req_is_wr) begin // SW write + next_c = (field_storage.CPTRA_DBG_MANUF_SERVICE_REG.DATA.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end else if(hwif_in.CPTRA_DBG_MANUF_SERVICE_REG.DATA.we) begin // HW Write - we + next_c = hwif_in.CPTRA_DBG_MANUF_SERVICE_REG.DATA.next; + load_next_c = '1; + end + field_combo.CPTRA_DBG_MANUF_SERVICE_REG.DATA.next = next_c; + field_combo.CPTRA_DBG_MANUF_SERVICE_REG.DATA.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.CPTRA_DBG_MANUF_SERVICE_REG.DATA.value <= 32'h0; + end else if(field_combo.CPTRA_DBG_MANUF_SERVICE_REG.DATA.load_next) begin + field_storage.CPTRA_DBG_MANUF_SERVICE_REG.DATA.value <= field_combo.CPTRA_DBG_MANUF_SERVICE_REG.DATA.next; + end + end + assign hwif_out.CPTRA_DBG_MANUF_SERVICE_REG.DATA.value = field_storage.CPTRA_DBG_MANUF_SERVICE_REG.DATA.value; + // Field: soc_ifc_reg.CPTRA_CLK_GATING_EN.clk_gating_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.CPTRA_CLK_GATING_EN.clk_gating_en.value; + load_next_c = '0; + if(decoded_reg_strb.CPTRA_CLK_GATING_EN && decoded_req_is_wr && hwif_in.soc_req) begin // SW write + next_c = (field_storage.CPTRA_CLK_GATING_EN.clk_gating_en.value & ~decoded_wr_biten[0:0]) | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end + field_combo.CPTRA_CLK_GATING_EN.clk_gating_en.next = next_c; + field_combo.CPTRA_CLK_GATING_EN.clk_gating_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.CPTRA_CLK_GATING_EN.clk_gating_en.value <= 1'h0; + end else if(field_combo.CPTRA_CLK_GATING_EN.clk_gating_en.load_next) begin + field_storage.CPTRA_CLK_GATING_EN.clk_gating_en.value <= field_combo.CPTRA_CLK_GATING_EN.clk_gating_en.next; + end + end + assign hwif_out.CPTRA_CLK_GATING_EN.clk_gating_en.value = field_storage.CPTRA_CLK_GATING_EN.clk_gating_en.value; + for(genvar i0=0; i0<2; i0++) begin + // Field: soc_ifc_reg.CPTRA_GENERIC_INPUT_WIRES[].generic_wires + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.CPTRA_GENERIC_INPUT_WIRES[i0].generic_wires.value; + load_next_c = '0; + + // HW Write + next_c = hwif_in.CPTRA_GENERIC_INPUT_WIRES[i0].generic_wires.next; + load_next_c = '1; + field_combo.CPTRA_GENERIC_INPUT_WIRES[i0].generic_wires.next = next_c; + field_combo.CPTRA_GENERIC_INPUT_WIRES[i0].generic_wires.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.CPTRA_GENERIC_INPUT_WIRES[i0].generic_wires.value <= 32'h0; + end else if(field_combo.CPTRA_GENERIC_INPUT_WIRES[i0].generic_wires.load_next) begin + field_storage.CPTRA_GENERIC_INPUT_WIRES[i0].generic_wires.value <= field_combo.CPTRA_GENERIC_INPUT_WIRES[i0].generic_wires.next; + end + end + assign hwif_out.CPTRA_GENERIC_INPUT_WIRES[i0].generic_wires.value = field_storage.CPTRA_GENERIC_INPUT_WIRES[i0].generic_wires.value; + end + for(genvar i0=0; i0<2; i0++) begin + // Field: soc_ifc_reg.CPTRA_GENERIC_OUTPUT_WIRES[].generic_wires + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.CPTRA_GENERIC_OUTPUT_WIRES[i0].generic_wires.value; + load_next_c = '0; + if(decoded_reg_strb.CPTRA_GENERIC_OUTPUT_WIRES[i0] && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.CPTRA_GENERIC_OUTPUT_WIRES[i0].generic_wires.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + field_combo.CPTRA_GENERIC_OUTPUT_WIRES[i0].generic_wires.next = next_c; + field_combo.CPTRA_GENERIC_OUTPUT_WIRES[i0].generic_wires.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.CPTRA_GENERIC_OUTPUT_WIRES[i0].generic_wires.value <= 32'h0; + end else if(field_combo.CPTRA_GENERIC_OUTPUT_WIRES[i0].generic_wires.load_next) begin + field_storage.CPTRA_GENERIC_OUTPUT_WIRES[i0].generic_wires.value <= field_combo.CPTRA_GENERIC_OUTPUT_WIRES[i0].generic_wires.next; + end + end + assign hwif_out.CPTRA_GENERIC_OUTPUT_WIRES[i0].generic_wires.value = field_storage.CPTRA_GENERIC_OUTPUT_WIRES[i0].generic_wires.value; + end + for(genvar i0=0; i0<2; i0++) begin + // Field: soc_ifc_reg.CPTRA_FW_REV_ID[].REV_ID + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.CPTRA_FW_REV_ID[i0].REV_ID.value; + load_next_c = '0; + if(decoded_reg_strb.CPTRA_FW_REV_ID[i0] && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.CPTRA_FW_REV_ID[i0].REV_ID.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + field_combo.CPTRA_FW_REV_ID[i0].REV_ID.next = next_c; + field_combo.CPTRA_FW_REV_ID[i0].REV_ID.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.CPTRA_FW_REV_ID[i0].REV_ID.value <= 32'h0; + end else if(field_combo.CPTRA_FW_REV_ID[i0].REV_ID.load_next) begin + field_storage.CPTRA_FW_REV_ID[i0].REV_ID.value <= field_combo.CPTRA_FW_REV_ID[i0].REV_ID.next; + end + end + assign hwif_out.CPTRA_FW_REV_ID[i0].REV_ID.value = field_storage.CPTRA_FW_REV_ID[i0].REV_ID.value; + end + // Field: soc_ifc_reg.CPTRA_WDT_TIMER1_EN.timer1_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.CPTRA_WDT_TIMER1_EN.timer1_en.value; + load_next_c = '0; + if(decoded_reg_strb.CPTRA_WDT_TIMER1_EN && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.CPTRA_WDT_TIMER1_EN.timer1_en.value & ~decoded_wr_biten[0:0]) | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end + field_combo.CPTRA_WDT_TIMER1_EN.timer1_en.next = next_c; + field_combo.CPTRA_WDT_TIMER1_EN.timer1_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.CPTRA_WDT_TIMER1_EN.timer1_en.value <= 1'h0; + end else if(field_combo.CPTRA_WDT_TIMER1_EN.timer1_en.load_next) begin + field_storage.CPTRA_WDT_TIMER1_EN.timer1_en.value <= field_combo.CPTRA_WDT_TIMER1_EN.timer1_en.next; + end + end + assign hwif_out.CPTRA_WDT_TIMER1_EN.timer1_en.value = field_storage.CPTRA_WDT_TIMER1_EN.timer1_en.value; + // Field: soc_ifc_reg.CPTRA_WDT_TIMER1_CTRL.timer1_restart + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.CPTRA_WDT_TIMER1_CTRL.timer1_restart.value; + load_next_c = '0; + if(decoded_reg_strb.CPTRA_WDT_TIMER1_CTRL && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.CPTRA_WDT_TIMER1_CTRL.timer1_restart.value & ~decoded_wr_biten[0:0]) | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end else begin // singlepulse clears back to 0 + next_c = '0; + load_next_c = '1; + end + field_combo.CPTRA_WDT_TIMER1_CTRL.timer1_restart.next = next_c; + field_combo.CPTRA_WDT_TIMER1_CTRL.timer1_restart.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.CPTRA_WDT_TIMER1_CTRL.timer1_restart.value <= 1'h0; + end else if(field_combo.CPTRA_WDT_TIMER1_CTRL.timer1_restart.load_next) begin + field_storage.CPTRA_WDT_TIMER1_CTRL.timer1_restart.value <= field_combo.CPTRA_WDT_TIMER1_CTRL.timer1_restart.next; + end + end + assign hwif_out.CPTRA_WDT_TIMER1_CTRL.timer1_restart.value = field_storage.CPTRA_WDT_TIMER1_CTRL.timer1_restart.value; + for(genvar i0=0; i0<2; i0++) begin + // Field: soc_ifc_reg.CPTRA_WDT_TIMER1_TIMEOUT_PERIOD[].timer1_timeout_period + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.CPTRA_WDT_TIMER1_TIMEOUT_PERIOD[i0].timer1_timeout_period.value; + load_next_c = '0; + if(decoded_reg_strb.CPTRA_WDT_TIMER1_TIMEOUT_PERIOD[i0] && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.CPTRA_WDT_TIMER1_TIMEOUT_PERIOD[i0].timer1_timeout_period.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + field_combo.CPTRA_WDT_TIMER1_TIMEOUT_PERIOD[i0].timer1_timeout_period.next = next_c; + field_combo.CPTRA_WDT_TIMER1_TIMEOUT_PERIOD[i0].timer1_timeout_period.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.CPTRA_WDT_TIMER1_TIMEOUT_PERIOD[i0].timer1_timeout_period.value <= 32'hffffffff; + end else if(field_combo.CPTRA_WDT_TIMER1_TIMEOUT_PERIOD[i0].timer1_timeout_period.load_next) begin + field_storage.CPTRA_WDT_TIMER1_TIMEOUT_PERIOD[i0].timer1_timeout_period.value <= field_combo.CPTRA_WDT_TIMER1_TIMEOUT_PERIOD[i0].timer1_timeout_period.next; + end + end + assign hwif_out.CPTRA_WDT_TIMER1_TIMEOUT_PERIOD[i0].timer1_timeout_period.value = field_storage.CPTRA_WDT_TIMER1_TIMEOUT_PERIOD[i0].timer1_timeout_period.value; + end + // Field: soc_ifc_reg.CPTRA_WDT_TIMER2_EN.timer2_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.CPTRA_WDT_TIMER2_EN.timer2_en.value; + load_next_c = '0; + if(decoded_reg_strb.CPTRA_WDT_TIMER2_EN && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.CPTRA_WDT_TIMER2_EN.timer2_en.value & ~decoded_wr_biten[0:0]) | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end + field_combo.CPTRA_WDT_TIMER2_EN.timer2_en.next = next_c; + field_combo.CPTRA_WDT_TIMER2_EN.timer2_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.CPTRA_WDT_TIMER2_EN.timer2_en.value <= 1'h0; + end else if(field_combo.CPTRA_WDT_TIMER2_EN.timer2_en.load_next) begin + field_storage.CPTRA_WDT_TIMER2_EN.timer2_en.value <= field_combo.CPTRA_WDT_TIMER2_EN.timer2_en.next; + end + end + assign hwif_out.CPTRA_WDT_TIMER2_EN.timer2_en.value = field_storage.CPTRA_WDT_TIMER2_EN.timer2_en.value; + // Field: soc_ifc_reg.CPTRA_WDT_TIMER2_CTRL.timer2_restart + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.CPTRA_WDT_TIMER2_CTRL.timer2_restart.value; + load_next_c = '0; + if(decoded_reg_strb.CPTRA_WDT_TIMER2_CTRL && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.CPTRA_WDT_TIMER2_CTRL.timer2_restart.value & ~decoded_wr_biten[0:0]) | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end else begin // singlepulse clears back to 0 + next_c = '0; + load_next_c = '1; + end + field_combo.CPTRA_WDT_TIMER2_CTRL.timer2_restart.next = next_c; + field_combo.CPTRA_WDT_TIMER2_CTRL.timer2_restart.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.CPTRA_WDT_TIMER2_CTRL.timer2_restart.value <= 1'h0; + end else if(field_combo.CPTRA_WDT_TIMER2_CTRL.timer2_restart.load_next) begin + field_storage.CPTRA_WDT_TIMER2_CTRL.timer2_restart.value <= field_combo.CPTRA_WDT_TIMER2_CTRL.timer2_restart.next; + end + end + assign hwif_out.CPTRA_WDT_TIMER2_CTRL.timer2_restart.value = field_storage.CPTRA_WDT_TIMER2_CTRL.timer2_restart.value; + for(genvar i0=0; i0<2; i0++) begin + // Field: soc_ifc_reg.CPTRA_WDT_TIMER2_TIMEOUT_PERIOD[].timer2_timeout_period + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.CPTRA_WDT_TIMER2_TIMEOUT_PERIOD[i0].timer2_timeout_period.value; + load_next_c = '0; + if(decoded_reg_strb.CPTRA_WDT_TIMER2_TIMEOUT_PERIOD[i0] && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.CPTRA_WDT_TIMER2_TIMEOUT_PERIOD[i0].timer2_timeout_period.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + field_combo.CPTRA_WDT_TIMER2_TIMEOUT_PERIOD[i0].timer2_timeout_period.next = next_c; + field_combo.CPTRA_WDT_TIMER2_TIMEOUT_PERIOD[i0].timer2_timeout_period.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.CPTRA_WDT_TIMER2_TIMEOUT_PERIOD[i0].timer2_timeout_period.value <= 32'hffffffff; + end else if(field_combo.CPTRA_WDT_TIMER2_TIMEOUT_PERIOD[i0].timer2_timeout_period.load_next) begin + field_storage.CPTRA_WDT_TIMER2_TIMEOUT_PERIOD[i0].timer2_timeout_period.value <= field_combo.CPTRA_WDT_TIMER2_TIMEOUT_PERIOD[i0].timer2_timeout_period.next; + end + end + assign hwif_out.CPTRA_WDT_TIMER2_TIMEOUT_PERIOD[i0].timer2_timeout_period.value = field_storage.CPTRA_WDT_TIMER2_TIMEOUT_PERIOD[i0].timer2_timeout_period.value; + end + // Field: soc_ifc_reg.CPTRA_WDT_STATUS.t1_timeout + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.CPTRA_WDT_STATUS.t1_timeout.value; + load_next_c = '0; + if(decoded_reg_strb.CPTRA_WDT_STATUS && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.CPTRA_WDT_STATUS.t1_timeout.value & ~decoded_wr_biten[0:0]) | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end else begin // HW Write + next_c = hwif_in.CPTRA_WDT_STATUS.t1_timeout.next; + load_next_c = '1; + end + field_combo.CPTRA_WDT_STATUS.t1_timeout.next = next_c; + field_combo.CPTRA_WDT_STATUS.t1_timeout.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.CPTRA_WDT_STATUS.t1_timeout.value <= 1'h0; + end else if(field_combo.CPTRA_WDT_STATUS.t1_timeout.load_next) begin + field_storage.CPTRA_WDT_STATUS.t1_timeout.value <= field_combo.CPTRA_WDT_STATUS.t1_timeout.next; + end + end + assign hwif_out.CPTRA_WDT_STATUS.t1_timeout.value = field_storage.CPTRA_WDT_STATUS.t1_timeout.value; + // Field: soc_ifc_reg.CPTRA_WDT_STATUS.t2_timeout + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.CPTRA_WDT_STATUS.t2_timeout.value; + load_next_c = '0; + if(decoded_reg_strb.CPTRA_WDT_STATUS && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.CPTRA_WDT_STATUS.t2_timeout.value & ~decoded_wr_biten[1:1]) | (decoded_wr_data[1:1] & decoded_wr_biten[1:1]); + load_next_c = '1; + end else begin // HW Write + next_c = hwif_in.CPTRA_WDT_STATUS.t2_timeout.next; + load_next_c = '1; + end + field_combo.CPTRA_WDT_STATUS.t2_timeout.next = next_c; + field_combo.CPTRA_WDT_STATUS.t2_timeout.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.CPTRA_WDT_STATUS.t2_timeout.value <= 1'h0; + end else if(field_combo.CPTRA_WDT_STATUS.t2_timeout.load_next) begin + field_storage.CPTRA_WDT_STATUS.t2_timeout.value <= field_combo.CPTRA_WDT_STATUS.t2_timeout.next; + end + end + assign hwif_out.CPTRA_WDT_STATUS.t2_timeout.value = field_storage.CPTRA_WDT_STATUS.t2_timeout.value; + // Field: soc_ifc_reg.CPTRA_FUSE_VALID_AXI_USER.AXI_USER + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.CPTRA_FUSE_VALID_AXI_USER.AXI_USER.value; + load_next_c = '0; + if(decoded_reg_strb.CPTRA_FUSE_VALID_AXI_USER && decoded_req_is_wr && !(hwif_in.CPTRA_FUSE_VALID_AXI_USER.AXI_USER.swwel)) begin // SW write + next_c = (field_storage.CPTRA_FUSE_VALID_AXI_USER.AXI_USER.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + field_combo.CPTRA_FUSE_VALID_AXI_USER.AXI_USER.next = next_c; + field_combo.CPTRA_FUSE_VALID_AXI_USER.AXI_USER.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.CPTRA_FUSE_VALID_AXI_USER.AXI_USER.value <= 32'hffffffff; + end else if(field_combo.CPTRA_FUSE_VALID_AXI_USER.AXI_USER.load_next) begin + field_storage.CPTRA_FUSE_VALID_AXI_USER.AXI_USER.value <= field_combo.CPTRA_FUSE_VALID_AXI_USER.AXI_USER.next; + end + end + assign hwif_out.CPTRA_FUSE_VALID_AXI_USER.AXI_USER.value = field_storage.CPTRA_FUSE_VALID_AXI_USER.AXI_USER.value; + // Field: soc_ifc_reg.CPTRA_FUSE_AXI_USER_LOCK.LOCK + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.CPTRA_FUSE_AXI_USER_LOCK.LOCK.value; + load_next_c = '0; + if(decoded_reg_strb.CPTRA_FUSE_AXI_USER_LOCK && decoded_req_is_wr && !(hwif_in.CPTRA_FUSE_AXI_USER_LOCK.LOCK.swwel)) begin // SW write + next_c = (field_storage.CPTRA_FUSE_AXI_USER_LOCK.LOCK.value & ~decoded_wr_biten[0:0]) | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end + field_combo.CPTRA_FUSE_AXI_USER_LOCK.LOCK.next = next_c; + field_combo.CPTRA_FUSE_AXI_USER_LOCK.LOCK.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.CPTRA_FUSE_AXI_USER_LOCK.LOCK.value <= 1'h0; + end else if(field_combo.CPTRA_FUSE_AXI_USER_LOCK.LOCK.load_next) begin + field_storage.CPTRA_FUSE_AXI_USER_LOCK.LOCK.value <= field_combo.CPTRA_FUSE_AXI_USER_LOCK.LOCK.next; + end + end + assign hwif_out.CPTRA_FUSE_AXI_USER_LOCK.LOCK.value = field_storage.CPTRA_FUSE_AXI_USER_LOCK.LOCK.value; + for(genvar i0=0; i0<2; i0++) begin + // Field: soc_ifc_reg.CPTRA_WDT_CFG[].TIMEOUT + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.CPTRA_WDT_CFG[i0].TIMEOUT.value; + load_next_c = '0; + if(decoded_reg_strb.CPTRA_WDT_CFG[i0] && decoded_req_is_wr) begin // SW write + next_c = (field_storage.CPTRA_WDT_CFG[i0].TIMEOUT.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + field_combo.CPTRA_WDT_CFG[i0].TIMEOUT.next = next_c; + field_combo.CPTRA_WDT_CFG[i0].TIMEOUT.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.CPTRA_WDT_CFG[i0].TIMEOUT.value <= 32'h0; + end else if(field_combo.CPTRA_WDT_CFG[i0].TIMEOUT.load_next) begin + field_storage.CPTRA_WDT_CFG[i0].TIMEOUT.value <= field_combo.CPTRA_WDT_CFG[i0].TIMEOUT.next; + end + end + end + // Field: soc_ifc_reg.CPTRA_iTRNG_ENTROPY_CONFIG_0.low_threshold + always_comb begin + automatic logic [15:0] next_c; + automatic logic load_next_c; + next_c = field_storage.CPTRA_iTRNG_ENTROPY_CONFIG_0.low_threshold.value; + load_next_c = '0; + if(decoded_reg_strb.CPTRA_iTRNG_ENTROPY_CONFIG_0 && decoded_req_is_wr) begin // SW write + next_c = (field_storage.CPTRA_iTRNG_ENTROPY_CONFIG_0.low_threshold.value & ~decoded_wr_biten[15:0]) | (decoded_wr_data[15:0] & decoded_wr_biten[15:0]); + load_next_c = '1; + end + field_combo.CPTRA_iTRNG_ENTROPY_CONFIG_0.low_threshold.next = next_c; + field_combo.CPTRA_iTRNG_ENTROPY_CONFIG_0.low_threshold.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.CPTRA_iTRNG_ENTROPY_CONFIG_0.low_threshold.value <= 16'h0; + end else if(field_combo.CPTRA_iTRNG_ENTROPY_CONFIG_0.low_threshold.load_next) begin + field_storage.CPTRA_iTRNG_ENTROPY_CONFIG_0.low_threshold.value <= field_combo.CPTRA_iTRNG_ENTROPY_CONFIG_0.low_threshold.next; + end + end + // Field: soc_ifc_reg.CPTRA_iTRNG_ENTROPY_CONFIG_0.high_threshold + always_comb begin + automatic logic [15:0] next_c; + automatic logic load_next_c; + next_c = field_storage.CPTRA_iTRNG_ENTROPY_CONFIG_0.high_threshold.value; + load_next_c = '0; + if(decoded_reg_strb.CPTRA_iTRNG_ENTROPY_CONFIG_0 && decoded_req_is_wr) begin // SW write + next_c = (field_storage.CPTRA_iTRNG_ENTROPY_CONFIG_0.high_threshold.value & ~decoded_wr_biten[31:16]) | (decoded_wr_data[31:16] & decoded_wr_biten[31:16]); + load_next_c = '1; + end + field_combo.CPTRA_iTRNG_ENTROPY_CONFIG_0.high_threshold.next = next_c; + field_combo.CPTRA_iTRNG_ENTROPY_CONFIG_0.high_threshold.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.CPTRA_iTRNG_ENTROPY_CONFIG_0.high_threshold.value <= 16'h0; + end else if(field_combo.CPTRA_iTRNG_ENTROPY_CONFIG_0.high_threshold.load_next) begin + field_storage.CPTRA_iTRNG_ENTROPY_CONFIG_0.high_threshold.value <= field_combo.CPTRA_iTRNG_ENTROPY_CONFIG_0.high_threshold.next; + end + end + // Field: soc_ifc_reg.CPTRA_iTRNG_ENTROPY_CONFIG_1.repetition_count + always_comb begin + automatic logic [15:0] next_c; + automatic logic load_next_c; + next_c = field_storage.CPTRA_iTRNG_ENTROPY_CONFIG_1.repetition_count.value; + load_next_c = '0; + if(decoded_reg_strb.CPTRA_iTRNG_ENTROPY_CONFIG_1 && decoded_req_is_wr) begin // SW write + next_c = (field_storage.CPTRA_iTRNG_ENTROPY_CONFIG_1.repetition_count.value & ~decoded_wr_biten[15:0]) | (decoded_wr_data[15:0] & decoded_wr_biten[15:0]); + load_next_c = '1; + end + field_combo.CPTRA_iTRNG_ENTROPY_CONFIG_1.repetition_count.next = next_c; + field_combo.CPTRA_iTRNG_ENTROPY_CONFIG_1.repetition_count.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.CPTRA_iTRNG_ENTROPY_CONFIG_1.repetition_count.value <= 16'h0; + end else if(field_combo.CPTRA_iTRNG_ENTROPY_CONFIG_1.repetition_count.load_next) begin + field_storage.CPTRA_iTRNG_ENTROPY_CONFIG_1.repetition_count.value <= field_combo.CPTRA_iTRNG_ENTROPY_CONFIG_1.repetition_count.next; + end + end + // Field: soc_ifc_reg.CPTRA_iTRNG_ENTROPY_CONFIG_1.RSVD + always_comb begin + automatic logic [15:0] next_c; + automatic logic load_next_c; + next_c = field_storage.CPTRA_iTRNG_ENTROPY_CONFIG_1.RSVD.value; + load_next_c = '0; + if(decoded_reg_strb.CPTRA_iTRNG_ENTROPY_CONFIG_1 && decoded_req_is_wr) begin // SW write + next_c = (field_storage.CPTRA_iTRNG_ENTROPY_CONFIG_1.RSVD.value & ~decoded_wr_biten[31:16]) | (decoded_wr_data[31:16] & decoded_wr_biten[31:16]); + load_next_c = '1; + end + field_combo.CPTRA_iTRNG_ENTROPY_CONFIG_1.RSVD.next = next_c; + field_combo.CPTRA_iTRNG_ENTROPY_CONFIG_1.RSVD.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.CPTRA_iTRNG_ENTROPY_CONFIG_1.RSVD.value <= 16'h0; + end else if(field_combo.CPTRA_iTRNG_ENTROPY_CONFIG_1.RSVD.load_next) begin + field_storage.CPTRA_iTRNG_ENTROPY_CONFIG_1.RSVD.value <= field_combo.CPTRA_iTRNG_ENTROPY_CONFIG_1.RSVD.next; + end + end + for(genvar i0=0; i0<2; i0++) begin + // Field: soc_ifc_reg.CPTRA_RSVD_REG[].RSVD + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.CPTRA_RSVD_REG[i0].RSVD.value; + load_next_c = '0; + if(decoded_reg_strb.CPTRA_RSVD_REG[i0] && decoded_req_is_wr) begin // SW write + next_c = (field_storage.CPTRA_RSVD_REG[i0].RSVD.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + field_combo.CPTRA_RSVD_REG[i0].RSVD.next = next_c; + field_combo.CPTRA_RSVD_REG[i0].RSVD.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.CPTRA_RSVD_REG[i0].RSVD.value <= 32'h0; + end else if(field_combo.CPTRA_RSVD_REG[i0].RSVD.load_next) begin + field_storage.CPTRA_RSVD_REG[i0].RSVD.value <= field_combo.CPTRA_RSVD_REG[i0].RSVD.next; + end + end + end + // Field: soc_ifc_reg.CPTRA_HW_CAPABILITIES.cap + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.CPTRA_HW_CAPABILITIES.cap.value; + load_next_c = '0; + if(decoded_reg_strb.CPTRA_HW_CAPABILITIES && decoded_req_is_wr && !(hwif_in.CPTRA_HW_CAPABILITIES.cap.swwel)) begin // SW write + next_c = (field_storage.CPTRA_HW_CAPABILITIES.cap.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + field_combo.CPTRA_HW_CAPABILITIES.cap.next = next_c; + field_combo.CPTRA_HW_CAPABILITIES.cap.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.CPTRA_HW_CAPABILITIES.cap.value <= 32'h0; + end else if(field_combo.CPTRA_HW_CAPABILITIES.cap.load_next) begin + field_storage.CPTRA_HW_CAPABILITIES.cap.value <= field_combo.CPTRA_HW_CAPABILITIES.cap.next; + end + end + // Field: soc_ifc_reg.CPTRA_FW_CAPABILITIES.cap + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.CPTRA_FW_CAPABILITIES.cap.value; + load_next_c = '0; + if(decoded_reg_strb.CPTRA_FW_CAPABILITIES && decoded_req_is_wr && !(hwif_in.CPTRA_FW_CAPABILITIES.cap.swwel)) begin // SW write + next_c = (field_storage.CPTRA_FW_CAPABILITIES.cap.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + field_combo.CPTRA_FW_CAPABILITIES.cap.next = next_c; + field_combo.CPTRA_FW_CAPABILITIES.cap.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.CPTRA_FW_CAPABILITIES.cap.value <= 32'h0; + end else if(field_combo.CPTRA_FW_CAPABILITIES.cap.load_next) begin + field_storage.CPTRA_FW_CAPABILITIES.cap.value <= field_combo.CPTRA_FW_CAPABILITIES.cap.next; + end + end + // Field: soc_ifc_reg.CPTRA_CAP_LOCK.lock + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.CPTRA_CAP_LOCK.lock.value; + load_next_c = '0; + if(decoded_reg_strb.CPTRA_CAP_LOCK && decoded_req_is_wr && !(hwif_in.CPTRA_CAP_LOCK.lock.swwel)) begin // SW write + next_c = (field_storage.CPTRA_CAP_LOCK.lock.value & ~decoded_wr_biten[0:0]) | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end + field_combo.CPTRA_CAP_LOCK.lock.next = next_c; + field_combo.CPTRA_CAP_LOCK.lock.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.CPTRA_CAP_LOCK.lock.value <= 1'h0; + end else if(field_combo.CPTRA_CAP_LOCK.lock.load_next) begin + field_storage.CPTRA_CAP_LOCK.lock.value <= field_combo.CPTRA_CAP_LOCK.lock.next; + end + end + assign hwif_out.CPTRA_CAP_LOCK.lock.value = field_storage.CPTRA_CAP_LOCK.lock.value; + for(genvar i0=0; i0<12; i0++) begin + // Field: soc_ifc_reg.CPTRA_OWNER_PK_HASH[].hash + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.CPTRA_OWNER_PK_HASH[i0].hash.value; + load_next_c = '0; + if(decoded_reg_strb.CPTRA_OWNER_PK_HASH[i0] && decoded_req_is_wr && !(hwif_in.CPTRA_OWNER_PK_HASH[i0].hash.swwel)) begin // SW write + next_c = (field_storage.CPTRA_OWNER_PK_HASH[i0].hash.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + field_combo.CPTRA_OWNER_PK_HASH[i0].hash.next = next_c; + field_combo.CPTRA_OWNER_PK_HASH[i0].hash.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.CPTRA_OWNER_PK_HASH[i0].hash.value <= 32'h0; + end else if(field_combo.CPTRA_OWNER_PK_HASH[i0].hash.load_next) begin + field_storage.CPTRA_OWNER_PK_HASH[i0].hash.value <= field_combo.CPTRA_OWNER_PK_HASH[i0].hash.next; + end + end + assign hwif_out.CPTRA_OWNER_PK_HASH[i0].hash.value = field_storage.CPTRA_OWNER_PK_HASH[i0].hash.value; + end + // Field: soc_ifc_reg.CPTRA_OWNER_PK_HASH_LOCK.lock + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.CPTRA_OWNER_PK_HASH_LOCK.lock.value; + load_next_c = '0; + if(decoded_reg_strb.CPTRA_OWNER_PK_HASH_LOCK && decoded_req_is_wr && hwif_in.CPTRA_OWNER_PK_HASH_LOCK.lock.swwe) begin // SW write + next_c = (field_storage.CPTRA_OWNER_PK_HASH_LOCK.lock.value & ~decoded_wr_biten[0:0]) | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end + field_combo.CPTRA_OWNER_PK_HASH_LOCK.lock.next = next_c; + field_combo.CPTRA_OWNER_PK_HASH_LOCK.lock.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.CPTRA_OWNER_PK_HASH_LOCK.lock.value <= 1'h0; + end else if(field_combo.CPTRA_OWNER_PK_HASH_LOCK.lock.load_next) begin + field_storage.CPTRA_OWNER_PK_HASH_LOCK.lock.value <= field_combo.CPTRA_OWNER_PK_HASH_LOCK.lock.next; + end + end + assign hwif_out.CPTRA_OWNER_PK_HASH_LOCK.lock.value = field_storage.CPTRA_OWNER_PK_HASH_LOCK.lock.value; + for(genvar i0=0; i0<16; i0++) begin + // Field: soc_ifc_reg.fuse_uds_seed[].seed + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.fuse_uds_seed[i0].seed.value; + load_next_c = '0; + if(hwif_in.fuse_uds_seed[i0].seed.we) begin // HW Write - we + next_c = hwif_in.fuse_uds_seed[i0].seed.next; + load_next_c = '1; + end else if(hwif_in.fuse_uds_seed[i0].seed.hwclr) begin // HW Clear + next_c = '0; + load_next_c = '1; + end else if(decoded_reg_strb.fuse_uds_seed[i0] && decoded_req_is_wr && !(hwif_in.fuse_uds_seed[i0].seed.swwel)) begin // SW write + next_c = (field_storage.fuse_uds_seed[i0].seed.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + field_combo.fuse_uds_seed[i0].seed.next = next_c; + field_combo.fuse_uds_seed[i0].seed.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.fuse_uds_seed[i0].seed.value <= 32'h0; + end else if(field_combo.fuse_uds_seed[i0].seed.load_next) begin + field_storage.fuse_uds_seed[i0].seed.value <= field_combo.fuse_uds_seed[i0].seed.next; + end + end + assign hwif_out.fuse_uds_seed[i0].seed.value = field_storage.fuse_uds_seed[i0].seed.value; + end + for(genvar i0=0; i0<8; i0++) begin + // Field: soc_ifc_reg.fuse_field_entropy[].seed + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.fuse_field_entropy[i0].seed.value; + load_next_c = '0; + if(hwif_in.fuse_field_entropy[i0].seed.we) begin // HW Write - we + next_c = hwif_in.fuse_field_entropy[i0].seed.next; + load_next_c = '1; + end else if(hwif_in.fuse_field_entropy[i0].seed.hwclr) begin // HW Clear + next_c = '0; + load_next_c = '1; + end else if(decoded_reg_strb.fuse_field_entropy[i0] && decoded_req_is_wr && !(hwif_in.fuse_field_entropy[i0].seed.swwel)) begin // SW write + next_c = (field_storage.fuse_field_entropy[i0].seed.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + field_combo.fuse_field_entropy[i0].seed.next = next_c; + field_combo.fuse_field_entropy[i0].seed.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.fuse_field_entropy[i0].seed.value <= 32'h0; + end else if(field_combo.fuse_field_entropy[i0].seed.load_next) begin + field_storage.fuse_field_entropy[i0].seed.value <= field_combo.fuse_field_entropy[i0].seed.next; + end + end + assign hwif_out.fuse_field_entropy[i0].seed.value = field_storage.fuse_field_entropy[i0].seed.value; + end + for(genvar i0=0; i0<12; i0++) begin + // Field: soc_ifc_reg.fuse_vendor_pk_hash[].hash + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.fuse_vendor_pk_hash[i0].hash.value; + load_next_c = '0; + if(decoded_reg_strb.fuse_vendor_pk_hash[i0] && decoded_req_is_wr && !(hwif_in.fuse_vendor_pk_hash[i0].hash.swwel)) begin // SW write + next_c = (field_storage.fuse_vendor_pk_hash[i0].hash.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + field_combo.fuse_vendor_pk_hash[i0].hash.next = next_c; + field_combo.fuse_vendor_pk_hash[i0].hash.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.fuse_vendor_pk_hash[i0].hash.value <= 32'h0; + end else if(field_combo.fuse_vendor_pk_hash[i0].hash.load_next) begin + field_storage.fuse_vendor_pk_hash[i0].hash.value <= field_combo.fuse_vendor_pk_hash[i0].hash.next; + end + end + assign hwif_out.fuse_vendor_pk_hash[i0].hash.value = field_storage.fuse_vendor_pk_hash[i0].hash.value; + end + // Field: soc_ifc_reg.fuse_ecc_revocation.ecc_revocation + always_comb begin + automatic logic [3:0] next_c; + automatic logic load_next_c; + next_c = field_storage.fuse_ecc_revocation.ecc_revocation.value; + load_next_c = '0; + if(decoded_reg_strb.fuse_ecc_revocation && decoded_req_is_wr && !(hwif_in.fuse_ecc_revocation.ecc_revocation.swwel)) begin // SW write + next_c = (field_storage.fuse_ecc_revocation.ecc_revocation.value & ~decoded_wr_biten[3:0]) | (decoded_wr_data[3:0] & decoded_wr_biten[3:0]); + load_next_c = '1; + end + field_combo.fuse_ecc_revocation.ecc_revocation.next = next_c; + field_combo.fuse_ecc_revocation.ecc_revocation.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.fuse_ecc_revocation.ecc_revocation.value <= 4'h0; + end else if(field_combo.fuse_ecc_revocation.ecc_revocation.load_next) begin + field_storage.fuse_ecc_revocation.ecc_revocation.value <= field_combo.fuse_ecc_revocation.ecc_revocation.next; + end + end + assign hwif_out.fuse_ecc_revocation.ecc_revocation.value = field_storage.fuse_ecc_revocation.ecc_revocation.value; + // Field: soc_ifc_reg.fuse_fmc_key_manifest_svn.svn + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.fuse_fmc_key_manifest_svn.svn.value; + load_next_c = '0; + if(decoded_reg_strb.fuse_fmc_key_manifest_svn && decoded_req_is_wr && !(hwif_in.fuse_fmc_key_manifest_svn.svn.swwel)) begin // SW write + next_c = (field_storage.fuse_fmc_key_manifest_svn.svn.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + field_combo.fuse_fmc_key_manifest_svn.svn.next = next_c; + field_combo.fuse_fmc_key_manifest_svn.svn.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.fuse_fmc_key_manifest_svn.svn.value <= 32'h0; + end else if(field_combo.fuse_fmc_key_manifest_svn.svn.load_next) begin + field_storage.fuse_fmc_key_manifest_svn.svn.value <= field_combo.fuse_fmc_key_manifest_svn.svn.next; + end + end + assign hwif_out.fuse_fmc_key_manifest_svn.svn.value = field_storage.fuse_fmc_key_manifest_svn.svn.value; + for(genvar i0=0; i0<4; i0++) begin + // Field: soc_ifc_reg.fuse_runtime_svn[].svn + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.fuse_runtime_svn[i0].svn.value; + load_next_c = '0; + if(decoded_reg_strb.fuse_runtime_svn[i0] && decoded_req_is_wr && !(hwif_in.fuse_runtime_svn[i0].svn.swwel)) begin // SW write + next_c = (field_storage.fuse_runtime_svn[i0].svn.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + field_combo.fuse_runtime_svn[i0].svn.next = next_c; + field_combo.fuse_runtime_svn[i0].svn.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.fuse_runtime_svn[i0].svn.value <= 32'h0; + end else if(field_combo.fuse_runtime_svn[i0].svn.load_next) begin + field_storage.fuse_runtime_svn[i0].svn.value <= field_combo.fuse_runtime_svn[i0].svn.next; + end + end + assign hwif_out.fuse_runtime_svn[i0].svn.value = field_storage.fuse_runtime_svn[i0].svn.value; + end + // Field: soc_ifc_reg.fuse_anti_rollback_disable.dis + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.fuse_anti_rollback_disable.dis.value; + load_next_c = '0; + if(decoded_reg_strb.fuse_anti_rollback_disable && decoded_req_is_wr && !(hwif_in.fuse_anti_rollback_disable.dis.swwel)) begin // SW write + next_c = (field_storage.fuse_anti_rollback_disable.dis.value & ~decoded_wr_biten[0:0]) | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end + field_combo.fuse_anti_rollback_disable.dis.next = next_c; + field_combo.fuse_anti_rollback_disable.dis.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.fuse_anti_rollback_disable.dis.value <= 1'h0; + end else if(field_combo.fuse_anti_rollback_disable.dis.load_next) begin + field_storage.fuse_anti_rollback_disable.dis.value <= field_combo.fuse_anti_rollback_disable.dis.next; + end + end + assign hwif_out.fuse_anti_rollback_disable.dis.value = field_storage.fuse_anti_rollback_disable.dis.value; + for(genvar i0=0; i0<24; i0++) begin + // Field: soc_ifc_reg.fuse_idevid_cert_attr[].cert + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.fuse_idevid_cert_attr[i0].cert.value; + load_next_c = '0; + if(decoded_reg_strb.fuse_idevid_cert_attr[i0] && decoded_req_is_wr && !(hwif_in.fuse_idevid_cert_attr[i0].cert.swwel)) begin // SW write + next_c = (field_storage.fuse_idevid_cert_attr[i0].cert.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + field_combo.fuse_idevid_cert_attr[i0].cert.next = next_c; + field_combo.fuse_idevid_cert_attr[i0].cert.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.fuse_idevid_cert_attr[i0].cert.value <= 32'h0; + end else if(field_combo.fuse_idevid_cert_attr[i0].cert.load_next) begin + field_storage.fuse_idevid_cert_attr[i0].cert.value <= field_combo.fuse_idevid_cert_attr[i0].cert.next; + end + end + assign hwif_out.fuse_idevid_cert_attr[i0].cert.value = field_storage.fuse_idevid_cert_attr[i0].cert.value; + end + for(genvar i0=0; i0<4; i0++) begin + // Field: soc_ifc_reg.fuse_idevid_manuf_hsm_id[].hsm_id + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.fuse_idevid_manuf_hsm_id[i0].hsm_id.value; + load_next_c = '0; + if(decoded_reg_strb.fuse_idevid_manuf_hsm_id[i0] && decoded_req_is_wr && !(hwif_in.fuse_idevid_manuf_hsm_id[i0].hsm_id.swwel)) begin // SW write + next_c = (field_storage.fuse_idevid_manuf_hsm_id[i0].hsm_id.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + field_combo.fuse_idevid_manuf_hsm_id[i0].hsm_id.next = next_c; + field_combo.fuse_idevid_manuf_hsm_id[i0].hsm_id.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.fuse_idevid_manuf_hsm_id[i0].hsm_id.value <= 32'h0; + end else if(field_combo.fuse_idevid_manuf_hsm_id[i0].hsm_id.load_next) begin + field_storage.fuse_idevid_manuf_hsm_id[i0].hsm_id.value <= field_combo.fuse_idevid_manuf_hsm_id[i0].hsm_id.next; + end + end + assign hwif_out.fuse_idevid_manuf_hsm_id[i0].hsm_id.value = field_storage.fuse_idevid_manuf_hsm_id[i0].hsm_id.value; + end + // Field: soc_ifc_reg.fuse_lms_revocation.lms_revocation + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.fuse_lms_revocation.lms_revocation.value; + load_next_c = '0; + if(decoded_reg_strb.fuse_lms_revocation && decoded_req_is_wr && !(hwif_in.fuse_lms_revocation.lms_revocation.swwel)) begin // SW write + next_c = (field_storage.fuse_lms_revocation.lms_revocation.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + field_combo.fuse_lms_revocation.lms_revocation.next = next_c; + field_combo.fuse_lms_revocation.lms_revocation.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.fuse_lms_revocation.lms_revocation.value <= 32'h0; + end else if(field_combo.fuse_lms_revocation.lms_revocation.load_next) begin + field_storage.fuse_lms_revocation.lms_revocation.value <= field_combo.fuse_lms_revocation.lms_revocation.next; + end + end + assign hwif_out.fuse_lms_revocation.lms_revocation.value = field_storage.fuse_lms_revocation.lms_revocation.value; + // Field: soc_ifc_reg.fuse_mldsa_revocation.mldsa_revocation + always_comb begin + automatic logic [3:0] next_c; + automatic logic load_next_c; + next_c = field_storage.fuse_mldsa_revocation.mldsa_revocation.value; + load_next_c = '0; + if(decoded_reg_strb.fuse_mldsa_revocation && decoded_req_is_wr && !(hwif_in.fuse_mldsa_revocation.mldsa_revocation.swwel)) begin // SW write + next_c = (field_storage.fuse_mldsa_revocation.mldsa_revocation.value & ~decoded_wr_biten[3:0]) | (decoded_wr_data[3:0] & decoded_wr_biten[3:0]); + load_next_c = '1; + end + field_combo.fuse_mldsa_revocation.mldsa_revocation.next = next_c; + field_combo.fuse_mldsa_revocation.mldsa_revocation.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.fuse_mldsa_revocation.mldsa_revocation.value <= 4'h0; + end else if(field_combo.fuse_mldsa_revocation.mldsa_revocation.load_next) begin + field_storage.fuse_mldsa_revocation.mldsa_revocation.value <= field_combo.fuse_mldsa_revocation.mldsa_revocation.next; + end + end + assign hwif_out.fuse_mldsa_revocation.mldsa_revocation.value = field_storage.fuse_mldsa_revocation.mldsa_revocation.value; + // Field: soc_ifc_reg.fuse_soc_stepping_id.soc_stepping_id + always_comb begin + automatic logic [15:0] next_c; + automatic logic load_next_c; + next_c = field_storage.fuse_soc_stepping_id.soc_stepping_id.value; + load_next_c = '0; + if(decoded_reg_strb.fuse_soc_stepping_id && decoded_req_is_wr && !(hwif_in.fuse_soc_stepping_id.soc_stepping_id.swwel)) begin // SW write + next_c = (field_storage.fuse_soc_stepping_id.soc_stepping_id.value & ~decoded_wr_biten[15:0]) | (decoded_wr_data[15:0] & decoded_wr_biten[15:0]); + load_next_c = '1; + end + field_combo.fuse_soc_stepping_id.soc_stepping_id.next = next_c; + field_combo.fuse_soc_stepping_id.soc_stepping_id.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.fuse_soc_stepping_id.soc_stepping_id.value <= 16'h0; + end else if(field_combo.fuse_soc_stepping_id.soc_stepping_id.load_next) begin + field_storage.fuse_soc_stepping_id.soc_stepping_id.value <= field_combo.fuse_soc_stepping_id.soc_stepping_id.next; + end + end + assign hwif_out.fuse_soc_stepping_id.soc_stepping_id.value = field_storage.fuse_soc_stepping_id.soc_stepping_id.value; + for(genvar i0=0; i0<16; i0++) begin + // Field: soc_ifc_reg.fuse_manuf_dbg_unlock_token[].token + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.fuse_manuf_dbg_unlock_token[i0].token.value; + load_next_c = '0; + if(decoded_reg_strb.fuse_manuf_dbg_unlock_token[i0] && decoded_req_is_wr && !(hwif_in.fuse_manuf_dbg_unlock_token[i0].token.swwel)) begin // SW write + next_c = (field_storage.fuse_manuf_dbg_unlock_token[i0].token.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + field_combo.fuse_manuf_dbg_unlock_token[i0].token.next = next_c; + field_combo.fuse_manuf_dbg_unlock_token[i0].token.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.fuse_manuf_dbg_unlock_token[i0].token.value <= 32'h0; + end else if(field_combo.fuse_manuf_dbg_unlock_token[i0].token.load_next) begin + field_storage.fuse_manuf_dbg_unlock_token[i0].token.value <= field_combo.fuse_manuf_dbg_unlock_token[i0].token.next; + end + end + assign hwif_out.fuse_manuf_dbg_unlock_token[i0].token.value = field_storage.fuse_manuf_dbg_unlock_token[i0].token.value; + end + // Field: soc_ifc_reg.fuse_pqc_key_type.key_type + always_comb begin + automatic logic [1:0] next_c; + automatic logic load_next_c; + next_c = field_storage.fuse_pqc_key_type.key_type.value; + load_next_c = '0; + if(decoded_reg_strb.fuse_pqc_key_type && decoded_req_is_wr && !(hwif_in.fuse_pqc_key_type.key_type.swwel)) begin // SW write + next_c = (field_storage.fuse_pqc_key_type.key_type.value & ~decoded_wr_biten[1:0]) | (decoded_wr_data[1:0] & decoded_wr_biten[1:0]); + load_next_c = '1; + end + field_combo.fuse_pqc_key_type.key_type.next = next_c; + field_combo.fuse_pqc_key_type.key_type.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.fuse_pqc_key_type.key_type.value <= 2'h0; + end else if(field_combo.fuse_pqc_key_type.key_type.load_next) begin + field_storage.fuse_pqc_key_type.key_type.value <= field_combo.fuse_pqc_key_type.key_type.next; + end + end + assign hwif_out.fuse_pqc_key_type.key_type.value = field_storage.fuse_pqc_key_type.key_type.value; + for(genvar i0=0; i0<4; i0++) begin + // Field: soc_ifc_reg.fuse_soc_manifest_svn[].svn + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.fuse_soc_manifest_svn[i0].svn.value; + load_next_c = '0; + if(decoded_reg_strb.fuse_soc_manifest_svn[i0] && decoded_req_is_wr && !(hwif_in.fuse_soc_manifest_svn[i0].svn.swwel)) begin // SW write + next_c = (field_storage.fuse_soc_manifest_svn[i0].svn.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + field_combo.fuse_soc_manifest_svn[i0].svn.next = next_c; + field_combo.fuse_soc_manifest_svn[i0].svn.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.fuse_soc_manifest_svn[i0].svn.value <= 32'h0; + end else if(field_combo.fuse_soc_manifest_svn[i0].svn.load_next) begin + field_storage.fuse_soc_manifest_svn[i0].svn.value <= field_combo.fuse_soc_manifest_svn[i0].svn.next; + end + end + assign hwif_out.fuse_soc_manifest_svn[i0].svn.value = field_storage.fuse_soc_manifest_svn[i0].svn.value; + end + // Field: soc_ifc_reg.fuse_soc_manifest_max_svn.svn + always_comb begin + automatic logic [7:0] next_c; + automatic logic load_next_c; + next_c = field_storage.fuse_soc_manifest_max_svn.svn.value; + load_next_c = '0; + if(decoded_reg_strb.fuse_soc_manifest_max_svn && decoded_req_is_wr && !(hwif_in.fuse_soc_manifest_max_svn.svn.swwel)) begin // SW write + next_c = (field_storage.fuse_soc_manifest_max_svn.svn.value & ~decoded_wr_biten[7:0]) | (decoded_wr_data[7:0] & decoded_wr_biten[7:0]); + load_next_c = '1; + end + field_combo.fuse_soc_manifest_max_svn.svn.next = next_c; + field_combo.fuse_soc_manifest_max_svn.svn.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.fuse_soc_manifest_max_svn.svn.value <= 8'h0; + end else if(field_combo.fuse_soc_manifest_max_svn.svn.load_next) begin + field_storage.fuse_soc_manifest_max_svn.svn.value <= field_combo.fuse_soc_manifest_max_svn.svn.next; + end + end + assign hwif_out.fuse_soc_manifest_max_svn.svn.value = field_storage.fuse_soc_manifest_max_svn.svn.value; + for(genvar i0=0; i0<8; i0++) begin + // Field: soc_ifc_reg.fuse_hek_seed[].seed + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.fuse_hek_seed[i0].seed.value; + load_next_c = '0; + if(decoded_reg_strb.fuse_hek_seed[i0] && decoded_req_is_wr && !(hwif_in.fuse_hek_seed[i0].seed.swwel)) begin // SW write + next_c = (field_storage.fuse_hek_seed[i0].seed.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + field_combo.fuse_hek_seed[i0].seed.next = next_c; + field_combo.fuse_hek_seed[i0].seed.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.fuse_hek_seed[i0].seed.value <= 32'h0; + end else if(field_combo.fuse_hek_seed[i0].seed.load_next) begin + field_storage.fuse_hek_seed[i0].seed.value <= field_combo.fuse_hek_seed[i0].seed.next; + end + end + assign hwif_out.fuse_hek_seed[i0].seed.value = field_storage.fuse_hek_seed[i0].seed.value; + end + // Field: soc_ifc_reg.SS_CALIPTRA_BASE_ADDR_L.addr_l + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.SS_CALIPTRA_BASE_ADDR_L.addr_l.value; + load_next_c = '0; + if(decoded_reg_strb.SS_CALIPTRA_BASE_ADDR_L && decoded_req_is_wr && !(hwif_in.SS_CALIPTRA_BASE_ADDR_L.addr_l.swwel)) begin // SW write + next_c = (field_storage.SS_CALIPTRA_BASE_ADDR_L.addr_l.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end else if(hwif_in.SS_CALIPTRA_BASE_ADDR_L.addr_l.we) begin // HW Write - we + next_c = hwif_in.SS_CALIPTRA_BASE_ADDR_L.addr_l.next; + load_next_c = '1; + end + field_combo.SS_CALIPTRA_BASE_ADDR_L.addr_l.next = next_c; + field_combo.SS_CALIPTRA_BASE_ADDR_L.addr_l.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.SS_CALIPTRA_BASE_ADDR_L.addr_l.value <= 32'h0; + end else if(field_combo.SS_CALIPTRA_BASE_ADDR_L.addr_l.load_next) begin + field_storage.SS_CALIPTRA_BASE_ADDR_L.addr_l.value <= field_combo.SS_CALIPTRA_BASE_ADDR_L.addr_l.next; + end + end + assign hwif_out.SS_CALIPTRA_BASE_ADDR_L.addr_l.value = field_storage.SS_CALIPTRA_BASE_ADDR_L.addr_l.value; + // Field: soc_ifc_reg.SS_CALIPTRA_BASE_ADDR_H.addr_h + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.SS_CALIPTRA_BASE_ADDR_H.addr_h.value; + load_next_c = '0; + if(decoded_reg_strb.SS_CALIPTRA_BASE_ADDR_H && decoded_req_is_wr && !(hwif_in.SS_CALIPTRA_BASE_ADDR_H.addr_h.swwel)) begin // SW write + next_c = (field_storage.SS_CALIPTRA_BASE_ADDR_H.addr_h.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end else if(hwif_in.SS_CALIPTRA_BASE_ADDR_H.addr_h.we) begin // HW Write - we + next_c = hwif_in.SS_CALIPTRA_BASE_ADDR_H.addr_h.next; + load_next_c = '1; + end + field_combo.SS_CALIPTRA_BASE_ADDR_H.addr_h.next = next_c; + field_combo.SS_CALIPTRA_BASE_ADDR_H.addr_h.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.SS_CALIPTRA_BASE_ADDR_H.addr_h.value <= 32'h0; + end else if(field_combo.SS_CALIPTRA_BASE_ADDR_H.addr_h.load_next) begin + field_storage.SS_CALIPTRA_BASE_ADDR_H.addr_h.value <= field_combo.SS_CALIPTRA_BASE_ADDR_H.addr_h.next; + end + end + assign hwif_out.SS_CALIPTRA_BASE_ADDR_H.addr_h.value = field_storage.SS_CALIPTRA_BASE_ADDR_H.addr_h.value; + // Field: soc_ifc_reg.SS_MCI_BASE_ADDR_L.addr_l + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.SS_MCI_BASE_ADDR_L.addr_l.value; + load_next_c = '0; + if(decoded_reg_strb.SS_MCI_BASE_ADDR_L && decoded_req_is_wr && !(hwif_in.SS_MCI_BASE_ADDR_L.addr_l.swwel)) begin // SW write + next_c = (field_storage.SS_MCI_BASE_ADDR_L.addr_l.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end else if(hwif_in.SS_MCI_BASE_ADDR_L.addr_l.we) begin // HW Write - we + next_c = hwif_in.SS_MCI_BASE_ADDR_L.addr_l.next; + load_next_c = '1; + end + field_combo.SS_MCI_BASE_ADDR_L.addr_l.next = next_c; + field_combo.SS_MCI_BASE_ADDR_L.addr_l.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.SS_MCI_BASE_ADDR_L.addr_l.value <= 32'h0; + end else if(field_combo.SS_MCI_BASE_ADDR_L.addr_l.load_next) begin + field_storage.SS_MCI_BASE_ADDR_L.addr_l.value <= field_combo.SS_MCI_BASE_ADDR_L.addr_l.next; + end + end + assign hwif_out.SS_MCI_BASE_ADDR_L.addr_l.value = field_storage.SS_MCI_BASE_ADDR_L.addr_l.value; + // Field: soc_ifc_reg.SS_MCI_BASE_ADDR_H.addr_h + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.SS_MCI_BASE_ADDR_H.addr_h.value; + load_next_c = '0; + if(decoded_reg_strb.SS_MCI_BASE_ADDR_H && decoded_req_is_wr && !(hwif_in.SS_MCI_BASE_ADDR_H.addr_h.swwel)) begin // SW write + next_c = (field_storage.SS_MCI_BASE_ADDR_H.addr_h.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end else if(hwif_in.SS_MCI_BASE_ADDR_H.addr_h.we) begin // HW Write - we + next_c = hwif_in.SS_MCI_BASE_ADDR_H.addr_h.next; + load_next_c = '1; + end + field_combo.SS_MCI_BASE_ADDR_H.addr_h.next = next_c; + field_combo.SS_MCI_BASE_ADDR_H.addr_h.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.SS_MCI_BASE_ADDR_H.addr_h.value <= 32'h0; + end else if(field_combo.SS_MCI_BASE_ADDR_H.addr_h.load_next) begin + field_storage.SS_MCI_BASE_ADDR_H.addr_h.value <= field_combo.SS_MCI_BASE_ADDR_H.addr_h.next; + end + end + assign hwif_out.SS_MCI_BASE_ADDR_H.addr_h.value = field_storage.SS_MCI_BASE_ADDR_H.addr_h.value; + // Field: soc_ifc_reg.SS_RECOVERY_IFC_BASE_ADDR_L.addr_l + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.SS_RECOVERY_IFC_BASE_ADDR_L.addr_l.value; + load_next_c = '0; + if(decoded_reg_strb.SS_RECOVERY_IFC_BASE_ADDR_L && decoded_req_is_wr && !(hwif_in.SS_RECOVERY_IFC_BASE_ADDR_L.addr_l.swwel)) begin // SW write + next_c = (field_storage.SS_RECOVERY_IFC_BASE_ADDR_L.addr_l.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end else if(hwif_in.SS_RECOVERY_IFC_BASE_ADDR_L.addr_l.we) begin // HW Write - we + next_c = hwif_in.SS_RECOVERY_IFC_BASE_ADDR_L.addr_l.next; + load_next_c = '1; + end + field_combo.SS_RECOVERY_IFC_BASE_ADDR_L.addr_l.next = next_c; + field_combo.SS_RECOVERY_IFC_BASE_ADDR_L.addr_l.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.SS_RECOVERY_IFC_BASE_ADDR_L.addr_l.value <= 32'h0; + end else if(field_combo.SS_RECOVERY_IFC_BASE_ADDR_L.addr_l.load_next) begin + field_storage.SS_RECOVERY_IFC_BASE_ADDR_L.addr_l.value <= field_combo.SS_RECOVERY_IFC_BASE_ADDR_L.addr_l.next; + end + end + assign hwif_out.SS_RECOVERY_IFC_BASE_ADDR_L.addr_l.value = field_storage.SS_RECOVERY_IFC_BASE_ADDR_L.addr_l.value; + // Field: soc_ifc_reg.SS_RECOVERY_IFC_BASE_ADDR_H.addr_h + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.SS_RECOVERY_IFC_BASE_ADDR_H.addr_h.value; + load_next_c = '0; + if(decoded_reg_strb.SS_RECOVERY_IFC_BASE_ADDR_H && decoded_req_is_wr && !(hwif_in.SS_RECOVERY_IFC_BASE_ADDR_H.addr_h.swwel)) begin // SW write + next_c = (field_storage.SS_RECOVERY_IFC_BASE_ADDR_H.addr_h.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end else if(hwif_in.SS_RECOVERY_IFC_BASE_ADDR_H.addr_h.we) begin // HW Write - we + next_c = hwif_in.SS_RECOVERY_IFC_BASE_ADDR_H.addr_h.next; + load_next_c = '1; + end + field_combo.SS_RECOVERY_IFC_BASE_ADDR_H.addr_h.next = next_c; + field_combo.SS_RECOVERY_IFC_BASE_ADDR_H.addr_h.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.SS_RECOVERY_IFC_BASE_ADDR_H.addr_h.value <= 32'h0; + end else if(field_combo.SS_RECOVERY_IFC_BASE_ADDR_H.addr_h.load_next) begin + field_storage.SS_RECOVERY_IFC_BASE_ADDR_H.addr_h.value <= field_combo.SS_RECOVERY_IFC_BASE_ADDR_H.addr_h.next; + end + end + assign hwif_out.SS_RECOVERY_IFC_BASE_ADDR_H.addr_h.value = field_storage.SS_RECOVERY_IFC_BASE_ADDR_H.addr_h.value; + // Field: soc_ifc_reg.SS_OTP_FC_BASE_ADDR_L.addr_l + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.SS_OTP_FC_BASE_ADDR_L.addr_l.value; + load_next_c = '0; + if(decoded_reg_strb.SS_OTP_FC_BASE_ADDR_L && decoded_req_is_wr && !(hwif_in.SS_OTP_FC_BASE_ADDR_L.addr_l.swwel)) begin // SW write + next_c = (field_storage.SS_OTP_FC_BASE_ADDR_L.addr_l.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end else if(hwif_in.SS_OTP_FC_BASE_ADDR_L.addr_l.we) begin // HW Write - we + next_c = hwif_in.SS_OTP_FC_BASE_ADDR_L.addr_l.next; + load_next_c = '1; + end + field_combo.SS_OTP_FC_BASE_ADDR_L.addr_l.next = next_c; + field_combo.SS_OTP_FC_BASE_ADDR_L.addr_l.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.SS_OTP_FC_BASE_ADDR_L.addr_l.value <= 32'h0; + end else if(field_combo.SS_OTP_FC_BASE_ADDR_L.addr_l.load_next) begin + field_storage.SS_OTP_FC_BASE_ADDR_L.addr_l.value <= field_combo.SS_OTP_FC_BASE_ADDR_L.addr_l.next; + end + end + assign hwif_out.SS_OTP_FC_BASE_ADDR_L.addr_l.value = field_storage.SS_OTP_FC_BASE_ADDR_L.addr_l.value; + // Field: soc_ifc_reg.SS_OTP_FC_BASE_ADDR_H.addr_h + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.SS_OTP_FC_BASE_ADDR_H.addr_h.value; + load_next_c = '0; + if(decoded_reg_strb.SS_OTP_FC_BASE_ADDR_H && decoded_req_is_wr && !(hwif_in.SS_OTP_FC_BASE_ADDR_H.addr_h.swwel)) begin // SW write + next_c = (field_storage.SS_OTP_FC_BASE_ADDR_H.addr_h.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end else if(hwif_in.SS_OTP_FC_BASE_ADDR_H.addr_h.we) begin // HW Write - we + next_c = hwif_in.SS_OTP_FC_BASE_ADDR_H.addr_h.next; + load_next_c = '1; + end + field_combo.SS_OTP_FC_BASE_ADDR_H.addr_h.next = next_c; + field_combo.SS_OTP_FC_BASE_ADDR_H.addr_h.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.SS_OTP_FC_BASE_ADDR_H.addr_h.value <= 32'h0; + end else if(field_combo.SS_OTP_FC_BASE_ADDR_H.addr_h.load_next) begin + field_storage.SS_OTP_FC_BASE_ADDR_H.addr_h.value <= field_combo.SS_OTP_FC_BASE_ADDR_H.addr_h.next; + end + end + assign hwif_out.SS_OTP_FC_BASE_ADDR_H.addr_h.value = field_storage.SS_OTP_FC_BASE_ADDR_H.addr_h.value; + // Field: soc_ifc_reg.SS_UDS_SEED_BASE_ADDR_L.addr_l + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.SS_UDS_SEED_BASE_ADDR_L.addr_l.value; + load_next_c = '0; + if(decoded_reg_strb.SS_UDS_SEED_BASE_ADDR_L && decoded_req_is_wr && !(hwif_in.SS_UDS_SEED_BASE_ADDR_L.addr_l.swwel)) begin // SW write + next_c = (field_storage.SS_UDS_SEED_BASE_ADDR_L.addr_l.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end else if(hwif_in.SS_UDS_SEED_BASE_ADDR_L.addr_l.we) begin // HW Write - we + next_c = hwif_in.SS_UDS_SEED_BASE_ADDR_L.addr_l.next; + load_next_c = '1; + end + field_combo.SS_UDS_SEED_BASE_ADDR_L.addr_l.next = next_c; + field_combo.SS_UDS_SEED_BASE_ADDR_L.addr_l.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.SS_UDS_SEED_BASE_ADDR_L.addr_l.value <= 32'h0; + end else if(field_combo.SS_UDS_SEED_BASE_ADDR_L.addr_l.load_next) begin + field_storage.SS_UDS_SEED_BASE_ADDR_L.addr_l.value <= field_combo.SS_UDS_SEED_BASE_ADDR_L.addr_l.next; + end + end + assign hwif_out.SS_UDS_SEED_BASE_ADDR_L.addr_l.value = field_storage.SS_UDS_SEED_BASE_ADDR_L.addr_l.value; + // Field: soc_ifc_reg.SS_UDS_SEED_BASE_ADDR_H.addr_h + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.SS_UDS_SEED_BASE_ADDR_H.addr_h.value; + load_next_c = '0; + if(decoded_reg_strb.SS_UDS_SEED_BASE_ADDR_H && decoded_req_is_wr && !(hwif_in.SS_UDS_SEED_BASE_ADDR_H.addr_h.swwel)) begin // SW write + next_c = (field_storage.SS_UDS_SEED_BASE_ADDR_H.addr_h.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end else if(hwif_in.SS_UDS_SEED_BASE_ADDR_H.addr_h.we) begin // HW Write - we + next_c = hwif_in.SS_UDS_SEED_BASE_ADDR_H.addr_h.next; + load_next_c = '1; + end + field_combo.SS_UDS_SEED_BASE_ADDR_H.addr_h.next = next_c; + field_combo.SS_UDS_SEED_BASE_ADDR_H.addr_h.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.SS_UDS_SEED_BASE_ADDR_H.addr_h.value <= 32'h0; + end else if(field_combo.SS_UDS_SEED_BASE_ADDR_H.addr_h.load_next) begin + field_storage.SS_UDS_SEED_BASE_ADDR_H.addr_h.value <= field_combo.SS_UDS_SEED_BASE_ADDR_H.addr_h.next; + end + end + assign hwif_out.SS_UDS_SEED_BASE_ADDR_H.addr_h.value = field_storage.SS_UDS_SEED_BASE_ADDR_H.addr_h.value; + // Field: soc_ifc_reg.SS_PROD_DEBUG_UNLOCK_AUTH_PK_HASH_REG_BANK_OFFSET.offset + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.SS_PROD_DEBUG_UNLOCK_AUTH_PK_HASH_REG_BANK_OFFSET.offset.value; + load_next_c = '0; + if(decoded_reg_strb.SS_PROD_DEBUG_UNLOCK_AUTH_PK_HASH_REG_BANK_OFFSET && decoded_req_is_wr && !(hwif_in.SS_PROD_DEBUG_UNLOCK_AUTH_PK_HASH_REG_BANK_OFFSET.offset.swwel)) begin // SW write + next_c = (field_storage.SS_PROD_DEBUG_UNLOCK_AUTH_PK_HASH_REG_BANK_OFFSET.offset.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end else if(hwif_in.SS_PROD_DEBUG_UNLOCK_AUTH_PK_HASH_REG_BANK_OFFSET.offset.we) begin // HW Write - we + next_c = hwif_in.SS_PROD_DEBUG_UNLOCK_AUTH_PK_HASH_REG_BANK_OFFSET.offset.next; + load_next_c = '1; + end + field_combo.SS_PROD_DEBUG_UNLOCK_AUTH_PK_HASH_REG_BANK_OFFSET.offset.next = next_c; + field_combo.SS_PROD_DEBUG_UNLOCK_AUTH_PK_HASH_REG_BANK_OFFSET.offset.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.SS_PROD_DEBUG_UNLOCK_AUTH_PK_HASH_REG_BANK_OFFSET.offset.value <= 32'h0; + end else if(field_combo.SS_PROD_DEBUG_UNLOCK_AUTH_PK_HASH_REG_BANK_OFFSET.offset.load_next) begin + field_storage.SS_PROD_DEBUG_UNLOCK_AUTH_PK_HASH_REG_BANK_OFFSET.offset.value <= field_combo.SS_PROD_DEBUG_UNLOCK_AUTH_PK_HASH_REG_BANK_OFFSET.offset.next; + end + end + assign hwif_out.SS_PROD_DEBUG_UNLOCK_AUTH_PK_HASH_REG_BANK_OFFSET.offset.value = field_storage.SS_PROD_DEBUG_UNLOCK_AUTH_PK_HASH_REG_BANK_OFFSET.offset.value; + // Field: soc_ifc_reg.SS_NUM_OF_PROD_DEBUG_UNLOCK_AUTH_PK_HASHES.num + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.SS_NUM_OF_PROD_DEBUG_UNLOCK_AUTH_PK_HASHES.num.value; + load_next_c = '0; + if(decoded_reg_strb.SS_NUM_OF_PROD_DEBUG_UNLOCK_AUTH_PK_HASHES && decoded_req_is_wr && !(hwif_in.SS_NUM_OF_PROD_DEBUG_UNLOCK_AUTH_PK_HASHES.num.swwel)) begin // SW write + next_c = (field_storage.SS_NUM_OF_PROD_DEBUG_UNLOCK_AUTH_PK_HASHES.num.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end else if(hwif_in.SS_NUM_OF_PROD_DEBUG_UNLOCK_AUTH_PK_HASHES.num.we) begin // HW Write - we + next_c = hwif_in.SS_NUM_OF_PROD_DEBUG_UNLOCK_AUTH_PK_HASHES.num.next; + load_next_c = '1; + end + field_combo.SS_NUM_OF_PROD_DEBUG_UNLOCK_AUTH_PK_HASHES.num.next = next_c; + field_combo.SS_NUM_OF_PROD_DEBUG_UNLOCK_AUTH_PK_HASHES.num.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.SS_NUM_OF_PROD_DEBUG_UNLOCK_AUTH_PK_HASHES.num.value <= 32'h8; + end else if(field_combo.SS_NUM_OF_PROD_DEBUG_UNLOCK_AUTH_PK_HASHES.num.load_next) begin + field_storage.SS_NUM_OF_PROD_DEBUG_UNLOCK_AUTH_PK_HASHES.num.value <= field_combo.SS_NUM_OF_PROD_DEBUG_UNLOCK_AUTH_PK_HASHES.num.next; + end + end + assign hwif_out.SS_NUM_OF_PROD_DEBUG_UNLOCK_AUTH_PK_HASHES.num.value = field_storage.SS_NUM_OF_PROD_DEBUG_UNLOCK_AUTH_PK_HASHES.num.value; + // Field: soc_ifc_reg.SS_DEBUG_INTENT.debug_intent + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.SS_DEBUG_INTENT.debug_intent.value; + load_next_c = '0; + if(hwif_in.SS_DEBUG_INTENT.debug_intent.we) begin // HW Write - we + next_c = hwif_in.SS_DEBUG_INTENT.debug_intent.next; + load_next_c = '1; + end + field_combo.SS_DEBUG_INTENT.debug_intent.next = next_c; + field_combo.SS_DEBUG_INTENT.debug_intent.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.SS_DEBUG_INTENT.debug_intent.value <= 1'h0; + end else if(field_combo.SS_DEBUG_INTENT.debug_intent.load_next) begin + field_storage.SS_DEBUG_INTENT.debug_intent.value <= field_combo.SS_DEBUG_INTENT.debug_intent.next; + end + end + assign hwif_out.SS_DEBUG_INTENT.debug_intent.value = field_storage.SS_DEBUG_INTENT.debug_intent.value; + // Field: soc_ifc_reg.SS_CALIPTRA_DMA_AXI_USER.user + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.SS_CALIPTRA_DMA_AXI_USER.user.value; + load_next_c = '0; + if(decoded_reg_strb.SS_CALIPTRA_DMA_AXI_USER && decoded_req_is_wr && !(hwif_in.SS_CALIPTRA_DMA_AXI_USER.user.swwel)) begin // SW write + next_c = (field_storage.SS_CALIPTRA_DMA_AXI_USER.user.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end else if(hwif_in.SS_CALIPTRA_DMA_AXI_USER.user.we) begin // HW Write - we + next_c = hwif_in.SS_CALIPTRA_DMA_AXI_USER.user.next; + load_next_c = '1; + end + field_combo.SS_CALIPTRA_DMA_AXI_USER.user.next = next_c; + field_combo.SS_CALIPTRA_DMA_AXI_USER.user.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.SS_CALIPTRA_DMA_AXI_USER.user.value <= 32'h0; + end else if(field_combo.SS_CALIPTRA_DMA_AXI_USER.user.load_next) begin + field_storage.SS_CALIPTRA_DMA_AXI_USER.user.value <= field_combo.SS_CALIPTRA_DMA_AXI_USER.user.next; + end + end + assign hwif_out.SS_CALIPTRA_DMA_AXI_USER.user.value = field_storage.SS_CALIPTRA_DMA_AXI_USER.user.value; + // Field: soc_ifc_reg.SS_EXTERNAL_STAGING_AREA_BASE_ADDR_L.addr_l + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.SS_EXTERNAL_STAGING_AREA_BASE_ADDR_L.addr_l.value; + load_next_c = '0; + if(decoded_reg_strb.SS_EXTERNAL_STAGING_AREA_BASE_ADDR_L && decoded_req_is_wr && !(hwif_in.SS_EXTERNAL_STAGING_AREA_BASE_ADDR_L.addr_l.swwel)) begin // SW write + next_c = (field_storage.SS_EXTERNAL_STAGING_AREA_BASE_ADDR_L.addr_l.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end else if(hwif_in.SS_EXTERNAL_STAGING_AREA_BASE_ADDR_L.addr_l.we) begin // HW Write - we + next_c = hwif_in.SS_EXTERNAL_STAGING_AREA_BASE_ADDR_L.addr_l.next; + load_next_c = '1; + end + field_combo.SS_EXTERNAL_STAGING_AREA_BASE_ADDR_L.addr_l.next = next_c; + field_combo.SS_EXTERNAL_STAGING_AREA_BASE_ADDR_L.addr_l.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.SS_EXTERNAL_STAGING_AREA_BASE_ADDR_L.addr_l.value <= 32'h0; + end else if(field_combo.SS_EXTERNAL_STAGING_AREA_BASE_ADDR_L.addr_l.load_next) begin + field_storage.SS_EXTERNAL_STAGING_AREA_BASE_ADDR_L.addr_l.value <= field_combo.SS_EXTERNAL_STAGING_AREA_BASE_ADDR_L.addr_l.next; + end + end + assign hwif_out.SS_EXTERNAL_STAGING_AREA_BASE_ADDR_L.addr_l.value = field_storage.SS_EXTERNAL_STAGING_AREA_BASE_ADDR_L.addr_l.value; + // Field: soc_ifc_reg.SS_EXTERNAL_STAGING_AREA_BASE_ADDR_H.addr_h + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.SS_EXTERNAL_STAGING_AREA_BASE_ADDR_H.addr_h.value; + load_next_c = '0; + if(decoded_reg_strb.SS_EXTERNAL_STAGING_AREA_BASE_ADDR_H && decoded_req_is_wr && !(hwif_in.SS_EXTERNAL_STAGING_AREA_BASE_ADDR_H.addr_h.swwel)) begin // SW write + next_c = (field_storage.SS_EXTERNAL_STAGING_AREA_BASE_ADDR_H.addr_h.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end else if(hwif_in.SS_EXTERNAL_STAGING_AREA_BASE_ADDR_H.addr_h.we) begin // HW Write - we + next_c = hwif_in.SS_EXTERNAL_STAGING_AREA_BASE_ADDR_H.addr_h.next; + load_next_c = '1; + end + field_combo.SS_EXTERNAL_STAGING_AREA_BASE_ADDR_H.addr_h.next = next_c; + field_combo.SS_EXTERNAL_STAGING_AREA_BASE_ADDR_H.addr_h.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.SS_EXTERNAL_STAGING_AREA_BASE_ADDR_H.addr_h.value <= 32'h0; + end else if(field_combo.SS_EXTERNAL_STAGING_AREA_BASE_ADDR_H.addr_h.load_next) begin + field_storage.SS_EXTERNAL_STAGING_AREA_BASE_ADDR_H.addr_h.value <= field_combo.SS_EXTERNAL_STAGING_AREA_BASE_ADDR_H.addr_h.next; + end + end + assign hwif_out.SS_EXTERNAL_STAGING_AREA_BASE_ADDR_H.addr_h.value = field_storage.SS_EXTERNAL_STAGING_AREA_BASE_ADDR_H.addr_h.value; + // Field: soc_ifc_reg.SS_KEY_RELEASE_BASE_ADDR_L.addr_l + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.SS_KEY_RELEASE_BASE_ADDR_L.addr_l.value; + load_next_c = '0; + if(decoded_reg_strb.SS_KEY_RELEASE_BASE_ADDR_L && decoded_req_is_wr && !(hwif_in.SS_KEY_RELEASE_BASE_ADDR_L.addr_l.swwel)) begin // SW write + next_c = (field_storage.SS_KEY_RELEASE_BASE_ADDR_L.addr_l.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end else if(hwif_in.SS_KEY_RELEASE_BASE_ADDR_L.addr_l.we) begin // HW Write - we + next_c = hwif_in.SS_KEY_RELEASE_BASE_ADDR_L.addr_l.next; + load_next_c = '1; + end + field_combo.SS_KEY_RELEASE_BASE_ADDR_L.addr_l.next = next_c; + field_combo.SS_KEY_RELEASE_BASE_ADDR_L.addr_l.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.SS_KEY_RELEASE_BASE_ADDR_L.addr_l.value <= 32'h0; + end else if(field_combo.SS_KEY_RELEASE_BASE_ADDR_L.addr_l.load_next) begin + field_storage.SS_KEY_RELEASE_BASE_ADDR_L.addr_l.value <= field_combo.SS_KEY_RELEASE_BASE_ADDR_L.addr_l.next; + end + end + assign hwif_out.SS_KEY_RELEASE_BASE_ADDR_L.addr_l.value = field_storage.SS_KEY_RELEASE_BASE_ADDR_L.addr_l.value; + // Field: soc_ifc_reg.SS_KEY_RELEASE_BASE_ADDR_H.addr_h + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.SS_KEY_RELEASE_BASE_ADDR_H.addr_h.value; + load_next_c = '0; + if(decoded_reg_strb.SS_KEY_RELEASE_BASE_ADDR_H && decoded_req_is_wr && !(hwif_in.SS_KEY_RELEASE_BASE_ADDR_H.addr_h.swwel)) begin // SW write + next_c = (field_storage.SS_KEY_RELEASE_BASE_ADDR_H.addr_h.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end else if(hwif_in.SS_KEY_RELEASE_BASE_ADDR_H.addr_h.we) begin // HW Write - we + next_c = hwif_in.SS_KEY_RELEASE_BASE_ADDR_H.addr_h.next; + load_next_c = '1; + end + field_combo.SS_KEY_RELEASE_BASE_ADDR_H.addr_h.next = next_c; + field_combo.SS_KEY_RELEASE_BASE_ADDR_H.addr_h.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.SS_KEY_RELEASE_BASE_ADDR_H.addr_h.value <= 32'h0; + end else if(field_combo.SS_KEY_RELEASE_BASE_ADDR_H.addr_h.load_next) begin + field_storage.SS_KEY_RELEASE_BASE_ADDR_H.addr_h.value <= field_combo.SS_KEY_RELEASE_BASE_ADDR_H.addr_h.next; + end + end + assign hwif_out.SS_KEY_RELEASE_BASE_ADDR_H.addr_h.value = field_storage.SS_KEY_RELEASE_BASE_ADDR_H.addr_h.value; + // Field: soc_ifc_reg.SS_KEY_RELEASE_SIZE.size + always_comb begin + automatic logic [15:0] next_c; + automatic logic load_next_c; + next_c = field_storage.SS_KEY_RELEASE_SIZE.size.value; + load_next_c = '0; + if(decoded_reg_strb.SS_KEY_RELEASE_SIZE && decoded_req_is_wr && !(hwif_in.SS_KEY_RELEASE_SIZE.size.swwel)) begin // SW write + next_c = (field_storage.SS_KEY_RELEASE_SIZE.size.value & ~decoded_wr_biten[15:0]) | (decoded_wr_data[15:0] & decoded_wr_biten[15:0]); + load_next_c = '1; + end else if(hwif_in.SS_KEY_RELEASE_SIZE.size.we) begin // HW Write - we + next_c = hwif_in.SS_KEY_RELEASE_SIZE.size.next; + load_next_c = '1; + end + field_combo.SS_KEY_RELEASE_SIZE.size.next = next_c; + field_combo.SS_KEY_RELEASE_SIZE.size.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.SS_KEY_RELEASE_SIZE.size.value <= 16'h0; + end else if(field_combo.SS_KEY_RELEASE_SIZE.size.load_next) begin + field_storage.SS_KEY_RELEASE_SIZE.size.value <= field_combo.SS_KEY_RELEASE_SIZE.size.next; + end + end + assign hwif_out.SS_KEY_RELEASE_SIZE.size.value = field_storage.SS_KEY_RELEASE_SIZE.size.value; + // Field: soc_ifc_reg.SS_OCP_LOCK_CTRL.LOCK_IN_PROGRESS + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.SS_OCP_LOCK_CTRL.LOCK_IN_PROGRESS.value; + load_next_c = '0; + if(decoded_reg_strb.SS_OCP_LOCK_CTRL && decoded_req_is_wr && !(hwif_in.SS_OCP_LOCK_CTRL.LOCK_IN_PROGRESS.swwel)) begin // SW write + next_c = (field_storage.SS_OCP_LOCK_CTRL.LOCK_IN_PROGRESS.value & ~decoded_wr_biten[0:0]) | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end + field_combo.SS_OCP_LOCK_CTRL.LOCK_IN_PROGRESS.next = next_c; + field_combo.SS_OCP_LOCK_CTRL.LOCK_IN_PROGRESS.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.SS_OCP_LOCK_CTRL.LOCK_IN_PROGRESS.value <= 1'h0; + end else if(field_combo.SS_OCP_LOCK_CTRL.LOCK_IN_PROGRESS.load_next) begin + field_storage.SS_OCP_LOCK_CTRL.LOCK_IN_PROGRESS.value <= field_combo.SS_OCP_LOCK_CTRL.LOCK_IN_PROGRESS.next; + end + end + assign hwif_out.SS_OCP_LOCK_CTRL.LOCK_IN_PROGRESS.value = field_storage.SS_OCP_LOCK_CTRL.LOCK_IN_PROGRESS.value; + for(genvar i0=0; i0<4; i0++) begin + // Field: soc_ifc_reg.SS_STRAP_GENERIC[].data + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.SS_STRAP_GENERIC[i0].data.value; + load_next_c = '0; + if(decoded_reg_strb.SS_STRAP_GENERIC[i0] && decoded_req_is_wr && !(hwif_in.SS_STRAP_GENERIC[i0].data.swwel)) begin // SW write + next_c = (field_storage.SS_STRAP_GENERIC[i0].data.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end else if(hwif_in.SS_STRAP_GENERIC[i0].data.we) begin // HW Write - we + next_c = hwif_in.SS_STRAP_GENERIC[i0].data.next; + load_next_c = '1; + end + field_combo.SS_STRAP_GENERIC[i0].data.next = next_c; + field_combo.SS_STRAP_GENERIC[i0].data.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.SS_STRAP_GENERIC[i0].data.value <= 32'h0; + end else if(field_combo.SS_STRAP_GENERIC[i0].data.load_next) begin + field_storage.SS_STRAP_GENERIC[i0].data.value <= field_combo.SS_STRAP_GENERIC[i0].data.next; + end + end + assign hwif_out.SS_STRAP_GENERIC[i0].data.value = field_storage.SS_STRAP_GENERIC[i0].data.value; + end + // Field: soc_ifc_reg.SS_DBG_SERVICE_REG_REQ.MANUF_DBG_UNLOCK_REQ + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.SS_DBG_SERVICE_REG_REQ.MANUF_DBG_UNLOCK_REQ.value; + load_next_c = '0; + if(decoded_reg_strb.SS_DBG_SERVICE_REG_REQ && decoded_req_is_wr && hwif_in.SS_DBG_SERVICE_REG_REQ.MANUF_DBG_UNLOCK_REQ.swwe) begin // SW write + next_c = (field_storage.SS_DBG_SERVICE_REG_REQ.MANUF_DBG_UNLOCK_REQ.value & ~decoded_wr_biten[0:0]) | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end else if(hwif_in.SS_DBG_SERVICE_REG_REQ.MANUF_DBG_UNLOCK_REQ.we) begin // HW Write - we + next_c = hwif_in.SS_DBG_SERVICE_REG_REQ.MANUF_DBG_UNLOCK_REQ.next; + load_next_c = '1; + end + field_combo.SS_DBG_SERVICE_REG_REQ.MANUF_DBG_UNLOCK_REQ.next = next_c; + field_combo.SS_DBG_SERVICE_REG_REQ.MANUF_DBG_UNLOCK_REQ.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.SS_DBG_SERVICE_REG_REQ.MANUF_DBG_UNLOCK_REQ.value <= 1'h0; + end else if(field_combo.SS_DBG_SERVICE_REG_REQ.MANUF_DBG_UNLOCK_REQ.load_next) begin + field_storage.SS_DBG_SERVICE_REG_REQ.MANUF_DBG_UNLOCK_REQ.value <= field_combo.SS_DBG_SERVICE_REG_REQ.MANUF_DBG_UNLOCK_REQ.next; + end + end + assign hwif_out.SS_DBG_SERVICE_REG_REQ.MANUF_DBG_UNLOCK_REQ.value = field_storage.SS_DBG_SERVICE_REG_REQ.MANUF_DBG_UNLOCK_REQ.value; + // Field: soc_ifc_reg.SS_DBG_SERVICE_REG_REQ.PROD_DBG_UNLOCK_REQ + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.SS_DBG_SERVICE_REG_REQ.PROD_DBG_UNLOCK_REQ.value; + load_next_c = '0; + if(decoded_reg_strb.SS_DBG_SERVICE_REG_REQ && decoded_req_is_wr && hwif_in.SS_DBG_SERVICE_REG_REQ.PROD_DBG_UNLOCK_REQ.swwe) begin // SW write + next_c = (field_storage.SS_DBG_SERVICE_REG_REQ.PROD_DBG_UNLOCK_REQ.value & ~decoded_wr_biten[1:1]) | (decoded_wr_data[1:1] & decoded_wr_biten[1:1]); + load_next_c = '1; + end else if(hwif_in.SS_DBG_SERVICE_REG_REQ.PROD_DBG_UNLOCK_REQ.we) begin // HW Write - we + next_c = hwif_in.SS_DBG_SERVICE_REG_REQ.PROD_DBG_UNLOCK_REQ.next; + load_next_c = '1; + end + field_combo.SS_DBG_SERVICE_REG_REQ.PROD_DBG_UNLOCK_REQ.next = next_c; + field_combo.SS_DBG_SERVICE_REG_REQ.PROD_DBG_UNLOCK_REQ.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.SS_DBG_SERVICE_REG_REQ.PROD_DBG_UNLOCK_REQ.value <= 1'h0; + end else if(field_combo.SS_DBG_SERVICE_REG_REQ.PROD_DBG_UNLOCK_REQ.load_next) begin + field_storage.SS_DBG_SERVICE_REG_REQ.PROD_DBG_UNLOCK_REQ.value <= field_combo.SS_DBG_SERVICE_REG_REQ.PROD_DBG_UNLOCK_REQ.next; + end + end + assign hwif_out.SS_DBG_SERVICE_REG_REQ.PROD_DBG_UNLOCK_REQ.value = field_storage.SS_DBG_SERVICE_REG_REQ.PROD_DBG_UNLOCK_REQ.value; + // Field: soc_ifc_reg.SS_DBG_SERVICE_REG_REQ.UDS_PROGRAM_REQ + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.SS_DBG_SERVICE_REG_REQ.UDS_PROGRAM_REQ.value; + load_next_c = '0; + if(decoded_reg_strb.SS_DBG_SERVICE_REG_REQ && decoded_req_is_wr && hwif_in.SS_DBG_SERVICE_REG_REQ.UDS_PROGRAM_REQ.swwe) begin // SW write + next_c = (field_storage.SS_DBG_SERVICE_REG_REQ.UDS_PROGRAM_REQ.value & ~decoded_wr_biten[2:2]) | (decoded_wr_data[2:2] & decoded_wr_biten[2:2]); + load_next_c = '1; + end else if(hwif_in.SS_DBG_SERVICE_REG_REQ.UDS_PROGRAM_REQ.we) begin // HW Write - we + next_c = hwif_in.SS_DBG_SERVICE_REG_REQ.UDS_PROGRAM_REQ.next; + load_next_c = '1; + end + field_combo.SS_DBG_SERVICE_REG_REQ.UDS_PROGRAM_REQ.next = next_c; + field_combo.SS_DBG_SERVICE_REG_REQ.UDS_PROGRAM_REQ.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.SS_DBG_SERVICE_REG_REQ.UDS_PROGRAM_REQ.value <= 1'h0; + end else if(field_combo.SS_DBG_SERVICE_REG_REQ.UDS_PROGRAM_REQ.load_next) begin + field_storage.SS_DBG_SERVICE_REG_REQ.UDS_PROGRAM_REQ.value <= field_combo.SS_DBG_SERVICE_REG_REQ.UDS_PROGRAM_REQ.next; + end + end + assign hwif_out.SS_DBG_SERVICE_REG_REQ.UDS_PROGRAM_REQ.value = field_storage.SS_DBG_SERVICE_REG_REQ.UDS_PROGRAM_REQ.value; + // Field: soc_ifc_reg.SS_DBG_SERVICE_REG_RSP.MANUF_DBG_UNLOCK_SUCCESS + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.SS_DBG_SERVICE_REG_RSP.MANUF_DBG_UNLOCK_SUCCESS.value; + load_next_c = '0; + if(decoded_reg_strb.SS_DBG_SERVICE_REG_RSP && decoded_req_is_wr && hwif_in.SS_DBG_SERVICE_REG_RSP.MANUF_DBG_UNLOCK_SUCCESS.swwe) begin // SW write + next_c = (field_storage.SS_DBG_SERVICE_REG_RSP.MANUF_DBG_UNLOCK_SUCCESS.value & ~decoded_wr_biten[0:0]) | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end + field_combo.SS_DBG_SERVICE_REG_RSP.MANUF_DBG_UNLOCK_SUCCESS.next = next_c; + field_combo.SS_DBG_SERVICE_REG_RSP.MANUF_DBG_UNLOCK_SUCCESS.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.SS_DBG_SERVICE_REG_RSP.MANUF_DBG_UNLOCK_SUCCESS.value <= 1'h0; + end else if(field_combo.SS_DBG_SERVICE_REG_RSP.MANUF_DBG_UNLOCK_SUCCESS.load_next) begin + field_storage.SS_DBG_SERVICE_REG_RSP.MANUF_DBG_UNLOCK_SUCCESS.value <= field_combo.SS_DBG_SERVICE_REG_RSP.MANUF_DBG_UNLOCK_SUCCESS.next; + end + end + assign hwif_out.SS_DBG_SERVICE_REG_RSP.MANUF_DBG_UNLOCK_SUCCESS.value = field_storage.SS_DBG_SERVICE_REG_RSP.MANUF_DBG_UNLOCK_SUCCESS.value; + // Field: soc_ifc_reg.SS_DBG_SERVICE_REG_RSP.MANUF_DBG_UNLOCK_FAIL + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.SS_DBG_SERVICE_REG_RSP.MANUF_DBG_UNLOCK_FAIL.value; + load_next_c = '0; + if(decoded_reg_strb.SS_DBG_SERVICE_REG_RSP && decoded_req_is_wr && hwif_in.SS_DBG_SERVICE_REG_RSP.MANUF_DBG_UNLOCK_FAIL.swwe) begin // SW write + next_c = (field_storage.SS_DBG_SERVICE_REG_RSP.MANUF_DBG_UNLOCK_FAIL.value & ~decoded_wr_biten[1:1]) | (decoded_wr_data[1:1] & decoded_wr_biten[1:1]); + load_next_c = '1; + end + field_combo.SS_DBG_SERVICE_REG_RSP.MANUF_DBG_UNLOCK_FAIL.next = next_c; + field_combo.SS_DBG_SERVICE_REG_RSP.MANUF_DBG_UNLOCK_FAIL.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.SS_DBG_SERVICE_REG_RSP.MANUF_DBG_UNLOCK_FAIL.value <= 1'h0; + end else if(field_combo.SS_DBG_SERVICE_REG_RSP.MANUF_DBG_UNLOCK_FAIL.load_next) begin + field_storage.SS_DBG_SERVICE_REG_RSP.MANUF_DBG_UNLOCK_FAIL.value <= field_combo.SS_DBG_SERVICE_REG_RSP.MANUF_DBG_UNLOCK_FAIL.next; + end + end + assign hwif_out.SS_DBG_SERVICE_REG_RSP.MANUF_DBG_UNLOCK_FAIL.value = field_storage.SS_DBG_SERVICE_REG_RSP.MANUF_DBG_UNLOCK_FAIL.value; + // Field: soc_ifc_reg.SS_DBG_SERVICE_REG_RSP.MANUF_DBG_UNLOCK_IN_PROGRESS + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.SS_DBG_SERVICE_REG_RSP.MANUF_DBG_UNLOCK_IN_PROGRESS.value; + load_next_c = '0; + if(decoded_reg_strb.SS_DBG_SERVICE_REG_RSP && decoded_req_is_wr && hwif_in.SS_DBG_SERVICE_REG_RSP.MANUF_DBG_UNLOCK_IN_PROGRESS.swwe) begin // SW write + next_c = (field_storage.SS_DBG_SERVICE_REG_RSP.MANUF_DBG_UNLOCK_IN_PROGRESS.value & ~decoded_wr_biten[2:2]) | (decoded_wr_data[2:2] & decoded_wr_biten[2:2]); + load_next_c = '1; + end + field_combo.SS_DBG_SERVICE_REG_RSP.MANUF_DBG_UNLOCK_IN_PROGRESS.next = next_c; + field_combo.SS_DBG_SERVICE_REG_RSP.MANUF_DBG_UNLOCK_IN_PROGRESS.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.SS_DBG_SERVICE_REG_RSP.MANUF_DBG_UNLOCK_IN_PROGRESS.value <= 1'h0; + end else if(field_combo.SS_DBG_SERVICE_REG_RSP.MANUF_DBG_UNLOCK_IN_PROGRESS.load_next) begin + field_storage.SS_DBG_SERVICE_REG_RSP.MANUF_DBG_UNLOCK_IN_PROGRESS.value <= field_combo.SS_DBG_SERVICE_REG_RSP.MANUF_DBG_UNLOCK_IN_PROGRESS.next; + end + end + assign hwif_out.SS_DBG_SERVICE_REG_RSP.MANUF_DBG_UNLOCK_IN_PROGRESS.value = field_storage.SS_DBG_SERVICE_REG_RSP.MANUF_DBG_UNLOCK_IN_PROGRESS.value; + // Field: soc_ifc_reg.SS_DBG_SERVICE_REG_RSP.PROD_DBG_UNLOCK_SUCCESS + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.SS_DBG_SERVICE_REG_RSP.PROD_DBG_UNLOCK_SUCCESS.value; + load_next_c = '0; + if(decoded_reg_strb.SS_DBG_SERVICE_REG_RSP && decoded_req_is_wr && hwif_in.SS_DBG_SERVICE_REG_RSP.PROD_DBG_UNLOCK_SUCCESS.swwe) begin // SW write + next_c = (field_storage.SS_DBG_SERVICE_REG_RSP.PROD_DBG_UNLOCK_SUCCESS.value & ~decoded_wr_biten[3:3]) | (decoded_wr_data[3:3] & decoded_wr_biten[3:3]); + load_next_c = '1; + end + field_combo.SS_DBG_SERVICE_REG_RSP.PROD_DBG_UNLOCK_SUCCESS.next = next_c; + field_combo.SS_DBG_SERVICE_REG_RSP.PROD_DBG_UNLOCK_SUCCESS.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.SS_DBG_SERVICE_REG_RSP.PROD_DBG_UNLOCK_SUCCESS.value <= 1'h0; + end else if(field_combo.SS_DBG_SERVICE_REG_RSP.PROD_DBG_UNLOCK_SUCCESS.load_next) begin + field_storage.SS_DBG_SERVICE_REG_RSP.PROD_DBG_UNLOCK_SUCCESS.value <= field_combo.SS_DBG_SERVICE_REG_RSP.PROD_DBG_UNLOCK_SUCCESS.next; + end + end + assign hwif_out.SS_DBG_SERVICE_REG_RSP.PROD_DBG_UNLOCK_SUCCESS.value = field_storage.SS_DBG_SERVICE_REG_RSP.PROD_DBG_UNLOCK_SUCCESS.value; + // Field: soc_ifc_reg.SS_DBG_SERVICE_REG_RSP.PROD_DBG_UNLOCK_FAIL + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.SS_DBG_SERVICE_REG_RSP.PROD_DBG_UNLOCK_FAIL.value; + load_next_c = '0; + if(decoded_reg_strb.SS_DBG_SERVICE_REG_RSP && decoded_req_is_wr && hwif_in.SS_DBG_SERVICE_REG_RSP.PROD_DBG_UNLOCK_FAIL.swwe) begin // SW write + next_c = (field_storage.SS_DBG_SERVICE_REG_RSP.PROD_DBG_UNLOCK_FAIL.value & ~decoded_wr_biten[4:4]) | (decoded_wr_data[4:4] & decoded_wr_biten[4:4]); + load_next_c = '1; + end + field_combo.SS_DBG_SERVICE_REG_RSP.PROD_DBG_UNLOCK_FAIL.next = next_c; + field_combo.SS_DBG_SERVICE_REG_RSP.PROD_DBG_UNLOCK_FAIL.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.SS_DBG_SERVICE_REG_RSP.PROD_DBG_UNLOCK_FAIL.value <= 1'h0; + end else if(field_combo.SS_DBG_SERVICE_REG_RSP.PROD_DBG_UNLOCK_FAIL.load_next) begin + field_storage.SS_DBG_SERVICE_REG_RSP.PROD_DBG_UNLOCK_FAIL.value <= field_combo.SS_DBG_SERVICE_REG_RSP.PROD_DBG_UNLOCK_FAIL.next; + end + end + assign hwif_out.SS_DBG_SERVICE_REG_RSP.PROD_DBG_UNLOCK_FAIL.value = field_storage.SS_DBG_SERVICE_REG_RSP.PROD_DBG_UNLOCK_FAIL.value; + // Field: soc_ifc_reg.SS_DBG_SERVICE_REG_RSP.PROD_DBG_UNLOCK_IN_PROGRESS + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.SS_DBG_SERVICE_REG_RSP.PROD_DBG_UNLOCK_IN_PROGRESS.value; + load_next_c = '0; + if(decoded_reg_strb.SS_DBG_SERVICE_REG_RSP && decoded_req_is_wr && hwif_in.SS_DBG_SERVICE_REG_RSP.PROD_DBG_UNLOCK_IN_PROGRESS.swwe) begin // SW write + next_c = (field_storage.SS_DBG_SERVICE_REG_RSP.PROD_DBG_UNLOCK_IN_PROGRESS.value & ~decoded_wr_biten[5:5]) | (decoded_wr_data[5:5] & decoded_wr_biten[5:5]); + load_next_c = '1; + end + field_combo.SS_DBG_SERVICE_REG_RSP.PROD_DBG_UNLOCK_IN_PROGRESS.next = next_c; + field_combo.SS_DBG_SERVICE_REG_RSP.PROD_DBG_UNLOCK_IN_PROGRESS.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.SS_DBG_SERVICE_REG_RSP.PROD_DBG_UNLOCK_IN_PROGRESS.value <= 1'h0; + end else if(field_combo.SS_DBG_SERVICE_REG_RSP.PROD_DBG_UNLOCK_IN_PROGRESS.load_next) begin + field_storage.SS_DBG_SERVICE_REG_RSP.PROD_DBG_UNLOCK_IN_PROGRESS.value <= field_combo.SS_DBG_SERVICE_REG_RSP.PROD_DBG_UNLOCK_IN_PROGRESS.next; + end + end + assign hwif_out.SS_DBG_SERVICE_REG_RSP.PROD_DBG_UNLOCK_IN_PROGRESS.value = field_storage.SS_DBG_SERVICE_REG_RSP.PROD_DBG_UNLOCK_IN_PROGRESS.value; + // Field: soc_ifc_reg.SS_DBG_SERVICE_REG_RSP.UDS_PROGRAM_SUCCESS + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.SS_DBG_SERVICE_REG_RSP.UDS_PROGRAM_SUCCESS.value; + load_next_c = '0; + if(decoded_reg_strb.SS_DBG_SERVICE_REG_RSP && decoded_req_is_wr && hwif_in.SS_DBG_SERVICE_REG_RSP.UDS_PROGRAM_SUCCESS.swwe) begin // SW write + next_c = (field_storage.SS_DBG_SERVICE_REG_RSP.UDS_PROGRAM_SUCCESS.value & ~decoded_wr_biten[6:6]) | (decoded_wr_data[6:6] & decoded_wr_biten[6:6]); + load_next_c = '1; + end + field_combo.SS_DBG_SERVICE_REG_RSP.UDS_PROGRAM_SUCCESS.next = next_c; + field_combo.SS_DBG_SERVICE_REG_RSP.UDS_PROGRAM_SUCCESS.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.SS_DBG_SERVICE_REG_RSP.UDS_PROGRAM_SUCCESS.value <= 1'h0; + end else if(field_combo.SS_DBG_SERVICE_REG_RSP.UDS_PROGRAM_SUCCESS.load_next) begin + field_storage.SS_DBG_SERVICE_REG_RSP.UDS_PROGRAM_SUCCESS.value <= field_combo.SS_DBG_SERVICE_REG_RSP.UDS_PROGRAM_SUCCESS.next; + end + end + assign hwif_out.SS_DBG_SERVICE_REG_RSP.UDS_PROGRAM_SUCCESS.value = field_storage.SS_DBG_SERVICE_REG_RSP.UDS_PROGRAM_SUCCESS.value; + // Field: soc_ifc_reg.SS_DBG_SERVICE_REG_RSP.UDS_PROGRAM_FAIL + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.SS_DBG_SERVICE_REG_RSP.UDS_PROGRAM_FAIL.value; + load_next_c = '0; + if(decoded_reg_strb.SS_DBG_SERVICE_REG_RSP && decoded_req_is_wr && hwif_in.SS_DBG_SERVICE_REG_RSP.UDS_PROGRAM_FAIL.swwe) begin // SW write + next_c = (field_storage.SS_DBG_SERVICE_REG_RSP.UDS_PROGRAM_FAIL.value & ~decoded_wr_biten[7:7]) | (decoded_wr_data[7:7] & decoded_wr_biten[7:7]); + load_next_c = '1; + end + field_combo.SS_DBG_SERVICE_REG_RSP.UDS_PROGRAM_FAIL.next = next_c; + field_combo.SS_DBG_SERVICE_REG_RSP.UDS_PROGRAM_FAIL.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.SS_DBG_SERVICE_REG_RSP.UDS_PROGRAM_FAIL.value <= 1'h0; + end else if(field_combo.SS_DBG_SERVICE_REG_RSP.UDS_PROGRAM_FAIL.load_next) begin + field_storage.SS_DBG_SERVICE_REG_RSP.UDS_PROGRAM_FAIL.value <= field_combo.SS_DBG_SERVICE_REG_RSP.UDS_PROGRAM_FAIL.next; + end + end + assign hwif_out.SS_DBG_SERVICE_REG_RSP.UDS_PROGRAM_FAIL.value = field_storage.SS_DBG_SERVICE_REG_RSP.UDS_PROGRAM_FAIL.value; + // Field: soc_ifc_reg.SS_DBG_SERVICE_REG_RSP.UDS_PROGRAM_IN_PROGRESS + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.SS_DBG_SERVICE_REG_RSP.UDS_PROGRAM_IN_PROGRESS.value; + load_next_c = '0; + if(decoded_reg_strb.SS_DBG_SERVICE_REG_RSP && decoded_req_is_wr && hwif_in.SS_DBG_SERVICE_REG_RSP.UDS_PROGRAM_IN_PROGRESS.swwe) begin // SW write + next_c = (field_storage.SS_DBG_SERVICE_REG_RSP.UDS_PROGRAM_IN_PROGRESS.value & ~decoded_wr_biten[8:8]) | (decoded_wr_data[8:8] & decoded_wr_biten[8:8]); + load_next_c = '1; + end + field_combo.SS_DBG_SERVICE_REG_RSP.UDS_PROGRAM_IN_PROGRESS.next = next_c; + field_combo.SS_DBG_SERVICE_REG_RSP.UDS_PROGRAM_IN_PROGRESS.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.SS_DBG_SERVICE_REG_RSP.UDS_PROGRAM_IN_PROGRESS.value <= 1'h0; + end else if(field_combo.SS_DBG_SERVICE_REG_RSP.UDS_PROGRAM_IN_PROGRESS.load_next) begin + field_storage.SS_DBG_SERVICE_REG_RSP.UDS_PROGRAM_IN_PROGRESS.value <= field_combo.SS_DBG_SERVICE_REG_RSP.UDS_PROGRAM_IN_PROGRESS.next; + end + end + assign hwif_out.SS_DBG_SERVICE_REG_RSP.UDS_PROGRAM_IN_PROGRESS.value = field_storage.SS_DBG_SERVICE_REG_RSP.UDS_PROGRAM_IN_PROGRESS.value; + // Field: soc_ifc_reg.SS_DBG_SERVICE_REG_RSP.TAP_MAILBOX_AVAILABLE + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.SS_DBG_SERVICE_REG_RSP.TAP_MAILBOX_AVAILABLE.value; + load_next_c = '0; + if(decoded_reg_strb.SS_DBG_SERVICE_REG_RSP && decoded_req_is_wr && hwif_in.SS_DBG_SERVICE_REG_RSP.TAP_MAILBOX_AVAILABLE.swwe) begin // SW write + next_c = (field_storage.SS_DBG_SERVICE_REG_RSP.TAP_MAILBOX_AVAILABLE.value & ~decoded_wr_biten[9:9]) | (decoded_wr_data[9:9] & decoded_wr_biten[9:9]); + load_next_c = '1; + end + field_combo.SS_DBG_SERVICE_REG_RSP.TAP_MAILBOX_AVAILABLE.next = next_c; + field_combo.SS_DBG_SERVICE_REG_RSP.TAP_MAILBOX_AVAILABLE.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.SS_DBG_SERVICE_REG_RSP.TAP_MAILBOX_AVAILABLE.value <= 1'h0; + end else if(field_combo.SS_DBG_SERVICE_REG_RSP.TAP_MAILBOX_AVAILABLE.load_next) begin + field_storage.SS_DBG_SERVICE_REG_RSP.TAP_MAILBOX_AVAILABLE.value <= field_combo.SS_DBG_SERVICE_REG_RSP.TAP_MAILBOX_AVAILABLE.next; + end + end + assign hwif_out.SS_DBG_SERVICE_REG_RSP.TAP_MAILBOX_AVAILABLE.value = field_storage.SS_DBG_SERVICE_REG_RSP.TAP_MAILBOX_AVAILABLE.value; + for(genvar i0=0; i0<2; i0++) begin + // Field: soc_ifc_reg.SS_SOC_DBG_UNLOCK_LEVEL[].LEVEL + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.SS_SOC_DBG_UNLOCK_LEVEL[i0].LEVEL.value; + load_next_c = '0; + if(decoded_reg_strb.SS_SOC_DBG_UNLOCK_LEVEL[i0] && decoded_req_is_wr && !(hwif_in.SS_SOC_DBG_UNLOCK_LEVEL[i0].LEVEL.swwel)) begin // SW write + next_c = (field_storage.SS_SOC_DBG_UNLOCK_LEVEL[i0].LEVEL.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end else if(hwif_in.SS_SOC_DBG_UNLOCK_LEVEL[i0].LEVEL.we) begin // HW Write - we + next_c = hwif_in.SS_SOC_DBG_UNLOCK_LEVEL[i0].LEVEL.next; + load_next_c = '1; + end + field_combo.SS_SOC_DBG_UNLOCK_LEVEL[i0].LEVEL.next = next_c; + field_combo.SS_SOC_DBG_UNLOCK_LEVEL[i0].LEVEL.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.SS_SOC_DBG_UNLOCK_LEVEL[i0].LEVEL.value <= 32'h0; + end else if(field_combo.SS_SOC_DBG_UNLOCK_LEVEL[i0].LEVEL.load_next) begin + field_storage.SS_SOC_DBG_UNLOCK_LEVEL[i0].LEVEL.value <= field_combo.SS_SOC_DBG_UNLOCK_LEVEL[i0].LEVEL.next; + end + end + assign hwif_out.SS_SOC_DBG_UNLOCK_LEVEL[i0].LEVEL.value = field_storage.SS_SOC_DBG_UNLOCK_LEVEL[i0].LEVEL.value; + end + for(genvar i0=0; i0<4; i0++) begin + // Field: soc_ifc_reg.SS_GENERIC_FW_EXEC_CTRL[].go + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.SS_GENERIC_FW_EXEC_CTRL[i0].go.value; + load_next_c = '0; + if(decoded_reg_strb.SS_GENERIC_FW_EXEC_CTRL[i0] && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.SS_GENERIC_FW_EXEC_CTRL[i0].go.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + field_combo.SS_GENERIC_FW_EXEC_CTRL[i0].go.next = next_c; + field_combo.SS_GENERIC_FW_EXEC_CTRL[i0].go.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.SS_GENERIC_FW_EXEC_CTRL[i0].go.value <= 32'h0; + end else if(field_combo.SS_GENERIC_FW_EXEC_CTRL[i0].go.load_next) begin + field_storage.SS_GENERIC_FW_EXEC_CTRL[i0].go.value <= field_combo.SS_GENERIC_FW_EXEC_CTRL[i0].go.next; + end + end + assign hwif_out.SS_GENERIC_FW_EXEC_CTRL[i0].go.value = field_storage.SS_GENERIC_FW_EXEC_CTRL[i0].go.value; + end + for(genvar i0=0; i0<8; i0++) begin + // Field: soc_ifc_reg.internal_obf_key[].key + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.internal_obf_key[i0].key.value; + load_next_c = '0; + if(!hwif_in.internal_obf_key[i0].key.wel) begin // HW Write - wel + next_c = hwif_in.internal_obf_key[i0].key.next; + load_next_c = '1; + end else if(hwif_in.internal_obf_key[i0].key.hwclr) begin // HW Clear + next_c = '0; + load_next_c = '1; + end else if(decoded_reg_strb.internal_obf_key[i0] && decoded_req_is_wr && hwif_in.internal_obf_key[i0].key.swwe) begin // SW write + next_c = (field_storage.internal_obf_key[i0].key.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + field_combo.internal_obf_key[i0].key.next = next_c; + field_combo.internal_obf_key[i0].key.load_next = load_next_c; + end + + always_ff @(posedge clk) begin + if(field_combo.internal_obf_key[i0].key.load_next) begin + field_storage.internal_obf_key[i0].key.value <= field_combo.internal_obf_key[i0].key.next; + end + end + assign hwif_out.internal_obf_key[i0].key.value = field_storage.internal_obf_key[i0].key.value; + end + // Field: soc_ifc_reg.internal_iccm_lock.lock + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.internal_iccm_lock.lock.value; + load_next_c = '0; + if(hwif_in.internal_iccm_lock.lock.hwclr) begin // HW Clear + next_c = '0; + load_next_c = '1; + end else if(decoded_reg_strb.internal_iccm_lock && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write 1 set + next_c = field_storage.internal_iccm_lock.lock.value | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end + field_combo.internal_iccm_lock.lock.next = next_c; + field_combo.internal_iccm_lock.lock.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.internal_iccm_lock.lock.value <= 1'h0; + end else if(field_combo.internal_iccm_lock.lock.load_next) begin + field_storage.internal_iccm_lock.lock.value <= field_combo.internal_iccm_lock.lock.next; + end + end + assign hwif_out.internal_iccm_lock.lock.value = field_storage.internal_iccm_lock.lock.value; + // Field: soc_ifc_reg.internal_fw_update_reset.core_rst + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.internal_fw_update_reset.core_rst.value; + load_next_c = '0; + if(decoded_reg_strb.internal_fw_update_reset && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.internal_fw_update_reset.core_rst.value & ~decoded_wr_biten[0:0]) | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end else begin // singlepulse clears back to 0 + next_c = '0; + load_next_c = '1; + end + field_combo.internal_fw_update_reset.core_rst.next = next_c; + field_combo.internal_fw_update_reset.core_rst.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.internal_fw_update_reset.core_rst.value <= 1'h0; + end else if(field_combo.internal_fw_update_reset.core_rst.load_next) begin + field_storage.internal_fw_update_reset.core_rst.value <= field_combo.internal_fw_update_reset.core_rst.next; + end + end + assign hwif_out.internal_fw_update_reset.core_rst.value = field_storage.internal_fw_update_reset.core_rst.value; + // Field: soc_ifc_reg.internal_fw_update_reset_wait_cycles.wait_cycles + always_comb begin + automatic logic [7:0] next_c; + automatic logic load_next_c; + next_c = field_storage.internal_fw_update_reset_wait_cycles.wait_cycles.value; + load_next_c = '0; + if(decoded_reg_strb.internal_fw_update_reset_wait_cycles && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.internal_fw_update_reset_wait_cycles.wait_cycles.value & ~decoded_wr_biten[7:0]) | (decoded_wr_data[7:0] & decoded_wr_biten[7:0]); + load_next_c = '1; + end + field_combo.internal_fw_update_reset_wait_cycles.wait_cycles.next = next_c; + field_combo.internal_fw_update_reset_wait_cycles.wait_cycles.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.internal_fw_update_reset_wait_cycles.wait_cycles.value <= 8'h5; + end else if(field_combo.internal_fw_update_reset_wait_cycles.wait_cycles.load_next) begin + field_storage.internal_fw_update_reset_wait_cycles.wait_cycles.value <= field_combo.internal_fw_update_reset_wait_cycles.wait_cycles.next; + end + end + assign hwif_out.internal_fw_update_reset_wait_cycles.wait_cycles.value = field_storage.internal_fw_update_reset_wait_cycles.wait_cycles.value; + // Field: soc_ifc_reg.internal_nmi_vector.vec + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.internal_nmi_vector.vec.value; + load_next_c = '0; + if(decoded_reg_strb.internal_nmi_vector && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.internal_nmi_vector.vec.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + field_combo.internal_nmi_vector.vec.next = next_c; + field_combo.internal_nmi_vector.vec.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.internal_nmi_vector.vec.value <= 32'h0; + end else if(field_combo.internal_nmi_vector.vec.load_next) begin + field_storage.internal_nmi_vector.vec.value <= field_combo.internal_nmi_vector.vec.next; + end + end + assign hwif_out.internal_nmi_vector.vec.value = field_storage.internal_nmi_vector.vec.value; + // Field: soc_ifc_reg.internal_hw_error_fatal_mask.mask_iccm_ecc_unc + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.internal_hw_error_fatal_mask.mask_iccm_ecc_unc.value; + load_next_c = '0; + if(decoded_reg_strb.internal_hw_error_fatal_mask && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.internal_hw_error_fatal_mask.mask_iccm_ecc_unc.value & ~decoded_wr_biten[0:0]) | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end + field_combo.internal_hw_error_fatal_mask.mask_iccm_ecc_unc.next = next_c; + field_combo.internal_hw_error_fatal_mask.mask_iccm_ecc_unc.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.internal_hw_error_fatal_mask.mask_iccm_ecc_unc.value <= 1'h0; + end else if(field_combo.internal_hw_error_fatal_mask.mask_iccm_ecc_unc.load_next) begin + field_storage.internal_hw_error_fatal_mask.mask_iccm_ecc_unc.value <= field_combo.internal_hw_error_fatal_mask.mask_iccm_ecc_unc.next; + end + end + assign hwif_out.internal_hw_error_fatal_mask.mask_iccm_ecc_unc.value = field_storage.internal_hw_error_fatal_mask.mask_iccm_ecc_unc.value; + // Field: soc_ifc_reg.internal_hw_error_fatal_mask.mask_dccm_ecc_unc + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.internal_hw_error_fatal_mask.mask_dccm_ecc_unc.value; + load_next_c = '0; + if(decoded_reg_strb.internal_hw_error_fatal_mask && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.internal_hw_error_fatal_mask.mask_dccm_ecc_unc.value & ~decoded_wr_biten[1:1]) | (decoded_wr_data[1:1] & decoded_wr_biten[1:1]); + load_next_c = '1; + end + field_combo.internal_hw_error_fatal_mask.mask_dccm_ecc_unc.next = next_c; + field_combo.internal_hw_error_fatal_mask.mask_dccm_ecc_unc.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.internal_hw_error_fatal_mask.mask_dccm_ecc_unc.value <= 1'h0; + end else if(field_combo.internal_hw_error_fatal_mask.mask_dccm_ecc_unc.load_next) begin + field_storage.internal_hw_error_fatal_mask.mask_dccm_ecc_unc.value <= field_combo.internal_hw_error_fatal_mask.mask_dccm_ecc_unc.next; + end + end + assign hwif_out.internal_hw_error_fatal_mask.mask_dccm_ecc_unc.value = field_storage.internal_hw_error_fatal_mask.mask_dccm_ecc_unc.value; + // Field: soc_ifc_reg.internal_hw_error_fatal_mask.mask_nmi_pin + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.internal_hw_error_fatal_mask.mask_nmi_pin.value; + load_next_c = '0; + if(decoded_reg_strb.internal_hw_error_fatal_mask && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.internal_hw_error_fatal_mask.mask_nmi_pin.value & ~decoded_wr_biten[2:2]) | (decoded_wr_data[2:2] & decoded_wr_biten[2:2]); + load_next_c = '1; + end + field_combo.internal_hw_error_fatal_mask.mask_nmi_pin.next = next_c; + field_combo.internal_hw_error_fatal_mask.mask_nmi_pin.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.internal_hw_error_fatal_mask.mask_nmi_pin.value <= 1'h0; + end else if(field_combo.internal_hw_error_fatal_mask.mask_nmi_pin.load_next) begin + field_storage.internal_hw_error_fatal_mask.mask_nmi_pin.value <= field_combo.internal_hw_error_fatal_mask.mask_nmi_pin.next; + end + end + assign hwif_out.internal_hw_error_fatal_mask.mask_nmi_pin.value = field_storage.internal_hw_error_fatal_mask.mask_nmi_pin.value; + // Field: soc_ifc_reg.internal_hw_error_non_fatal_mask.mask_mbox_prot_no_lock + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.internal_hw_error_non_fatal_mask.mask_mbox_prot_no_lock.value; + load_next_c = '0; + if(decoded_reg_strb.internal_hw_error_non_fatal_mask && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.internal_hw_error_non_fatal_mask.mask_mbox_prot_no_lock.value & ~decoded_wr_biten[0:0]) | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end + field_combo.internal_hw_error_non_fatal_mask.mask_mbox_prot_no_lock.next = next_c; + field_combo.internal_hw_error_non_fatal_mask.mask_mbox_prot_no_lock.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.internal_hw_error_non_fatal_mask.mask_mbox_prot_no_lock.value <= 1'h0; + end else if(field_combo.internal_hw_error_non_fatal_mask.mask_mbox_prot_no_lock.load_next) begin + field_storage.internal_hw_error_non_fatal_mask.mask_mbox_prot_no_lock.value <= field_combo.internal_hw_error_non_fatal_mask.mask_mbox_prot_no_lock.next; + end + end + assign hwif_out.internal_hw_error_non_fatal_mask.mask_mbox_prot_no_lock.value = field_storage.internal_hw_error_non_fatal_mask.mask_mbox_prot_no_lock.value; + // Field: soc_ifc_reg.internal_hw_error_non_fatal_mask.mask_mbox_prot_ooo + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.internal_hw_error_non_fatal_mask.mask_mbox_prot_ooo.value; + load_next_c = '0; + if(decoded_reg_strb.internal_hw_error_non_fatal_mask && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.internal_hw_error_non_fatal_mask.mask_mbox_prot_ooo.value & ~decoded_wr_biten[1:1]) | (decoded_wr_data[1:1] & decoded_wr_biten[1:1]); + load_next_c = '1; + end + field_combo.internal_hw_error_non_fatal_mask.mask_mbox_prot_ooo.next = next_c; + field_combo.internal_hw_error_non_fatal_mask.mask_mbox_prot_ooo.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.internal_hw_error_non_fatal_mask.mask_mbox_prot_ooo.value <= 1'h0; + end else if(field_combo.internal_hw_error_non_fatal_mask.mask_mbox_prot_ooo.load_next) begin + field_storage.internal_hw_error_non_fatal_mask.mask_mbox_prot_ooo.value <= field_combo.internal_hw_error_non_fatal_mask.mask_mbox_prot_ooo.next; + end + end + assign hwif_out.internal_hw_error_non_fatal_mask.mask_mbox_prot_ooo.value = field_storage.internal_hw_error_non_fatal_mask.mask_mbox_prot_ooo.value; + // Field: soc_ifc_reg.internal_hw_error_non_fatal_mask.mask_mbox_ecc_unc + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.internal_hw_error_non_fatal_mask.mask_mbox_ecc_unc.value; + load_next_c = '0; + if(decoded_reg_strb.internal_hw_error_non_fatal_mask && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.internal_hw_error_non_fatal_mask.mask_mbox_ecc_unc.value & ~decoded_wr_biten[2:2]) | (decoded_wr_data[2:2] & decoded_wr_biten[2:2]); + load_next_c = '1; + end + field_combo.internal_hw_error_non_fatal_mask.mask_mbox_ecc_unc.next = next_c; + field_combo.internal_hw_error_non_fatal_mask.mask_mbox_ecc_unc.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.internal_hw_error_non_fatal_mask.mask_mbox_ecc_unc.value <= 1'h0; + end else if(field_combo.internal_hw_error_non_fatal_mask.mask_mbox_ecc_unc.load_next) begin + field_storage.internal_hw_error_non_fatal_mask.mask_mbox_ecc_unc.value <= field_combo.internal_hw_error_non_fatal_mask.mask_mbox_ecc_unc.next; + end + end + assign hwif_out.internal_hw_error_non_fatal_mask.mask_mbox_ecc_unc.value = field_storage.internal_hw_error_non_fatal_mask.mask_mbox_ecc_unc.value; + // Field: soc_ifc_reg.internal_fw_error_fatal_mask.mask + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.internal_fw_error_fatal_mask.mask.value; + load_next_c = '0; + if(decoded_reg_strb.internal_fw_error_fatal_mask && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.internal_fw_error_fatal_mask.mask.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + field_combo.internal_fw_error_fatal_mask.mask.next = next_c; + field_combo.internal_fw_error_fatal_mask.mask.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.internal_fw_error_fatal_mask.mask.value <= 32'h0; + end else if(field_combo.internal_fw_error_fatal_mask.mask.load_next) begin + field_storage.internal_fw_error_fatal_mask.mask.value <= field_combo.internal_fw_error_fatal_mask.mask.next; + end + end + assign hwif_out.internal_fw_error_fatal_mask.mask.value = field_storage.internal_fw_error_fatal_mask.mask.value; + // Field: soc_ifc_reg.internal_fw_error_non_fatal_mask.mask + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.internal_fw_error_non_fatal_mask.mask.value; + load_next_c = '0; + if(decoded_reg_strb.internal_fw_error_non_fatal_mask && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.internal_fw_error_non_fatal_mask.mask.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + field_combo.internal_fw_error_non_fatal_mask.mask.next = next_c; + field_combo.internal_fw_error_non_fatal_mask.mask.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.internal_fw_error_non_fatal_mask.mask.value <= 32'h0; + end else if(field_combo.internal_fw_error_non_fatal_mask.mask.load_next) begin + field_storage.internal_fw_error_non_fatal_mask.mask.value <= field_combo.internal_fw_error_non_fatal_mask.mask.next; + end + end + assign hwif_out.internal_fw_error_non_fatal_mask.mask.value = field_storage.internal_fw_error_non_fatal_mask.mask.value; + // Field: soc_ifc_reg.internal_rv_mtime_l.count_l + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.internal_rv_mtime_l.count_l.value; + load_next_c = '0; + if(decoded_reg_strb.internal_rv_mtime_l && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.internal_rv_mtime_l.count_l.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + if(hwif_in.internal_rv_mtime_l.count_l.incr) begin // increment + field_combo.internal_rv_mtime_l.count_l.overflow = (((33)'(next_c) + 32'h1) > 32'hffffffff); + next_c = next_c + 32'h1; + load_next_c = '1; + end else begin + field_combo.internal_rv_mtime_l.count_l.overflow = '0; + end + field_combo.internal_rv_mtime_l.count_l.incrthreshold = (field_storage.internal_rv_mtime_l.count_l.value >= 32'hffffffff); + field_combo.internal_rv_mtime_l.count_l.next = next_c; + field_combo.internal_rv_mtime_l.count_l.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.internal_rv_mtime_l.count_l.value <= 32'h0; + end else if(field_combo.internal_rv_mtime_l.count_l.load_next) begin + field_storage.internal_rv_mtime_l.count_l.value <= field_combo.internal_rv_mtime_l.count_l.next; + end + end + assign hwif_out.internal_rv_mtime_l.count_l.value = field_storage.internal_rv_mtime_l.count_l.value; + assign hwif_out.internal_rv_mtime_l.count_l.swmod = decoded_reg_strb.internal_rv_mtime_l && decoded_req_is_wr; + assign hwif_out.internal_rv_mtime_l.count_l.overflow = field_combo.internal_rv_mtime_l.count_l.overflow; + // Field: soc_ifc_reg.internal_rv_mtime_h.count_h + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.internal_rv_mtime_h.count_h.value; + load_next_c = '0; + if(decoded_reg_strb.internal_rv_mtime_h && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.internal_rv_mtime_h.count_h.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + if(hwif_in.internal_rv_mtime_h.count_h.incr) begin // increment + field_combo.internal_rv_mtime_h.count_h.overflow = (((33)'(next_c) + 32'h1) > 32'hffffffff); + next_c = next_c + 32'h1; + load_next_c = '1; + end else begin + field_combo.internal_rv_mtime_h.count_h.overflow = '0; + end + field_combo.internal_rv_mtime_h.count_h.incrthreshold = (field_storage.internal_rv_mtime_h.count_h.value >= 32'hffffffff); + field_combo.internal_rv_mtime_h.count_h.next = next_c; + field_combo.internal_rv_mtime_h.count_h.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.internal_rv_mtime_h.count_h.value <= 32'h0; + end else if(field_combo.internal_rv_mtime_h.count_h.load_next) begin + field_storage.internal_rv_mtime_h.count_h.value <= field_combo.internal_rv_mtime_h.count_h.next; + end + end + assign hwif_out.internal_rv_mtime_h.count_h.value = field_storage.internal_rv_mtime_h.count_h.value; + assign hwif_out.internal_rv_mtime_h.count_h.swmod = decoded_reg_strb.internal_rv_mtime_h && decoded_req_is_wr; + // Field: soc_ifc_reg.internal_rv_mtimecmp_l.compare_l + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.internal_rv_mtimecmp_l.compare_l.value; + load_next_c = '0; + if(decoded_reg_strb.internal_rv_mtimecmp_l && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.internal_rv_mtimecmp_l.compare_l.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + field_combo.internal_rv_mtimecmp_l.compare_l.next = next_c; + field_combo.internal_rv_mtimecmp_l.compare_l.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.internal_rv_mtimecmp_l.compare_l.value <= 32'h0; + end else if(field_combo.internal_rv_mtimecmp_l.compare_l.load_next) begin + field_storage.internal_rv_mtimecmp_l.compare_l.value <= field_combo.internal_rv_mtimecmp_l.compare_l.next; + end + end + assign hwif_out.internal_rv_mtimecmp_l.compare_l.value = field_storage.internal_rv_mtimecmp_l.compare_l.value; + // Field: soc_ifc_reg.internal_rv_mtimecmp_h.compare_h + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.internal_rv_mtimecmp_h.compare_h.value; + load_next_c = '0; + if(decoded_reg_strb.internal_rv_mtimecmp_h && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.internal_rv_mtimecmp_h.compare_h.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + field_combo.internal_rv_mtimecmp_h.compare_h.next = next_c; + field_combo.internal_rv_mtimecmp_h.compare_h.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.internal_rv_mtimecmp_h.compare_h.value <= 32'h0; + end else if(field_combo.internal_rv_mtimecmp_h.compare_h.load_next) begin + field_storage.internal_rv_mtimecmp_h.compare_h.value <= field_combo.internal_rv_mtimecmp_h.compare_h.next; + end + end + assign hwif_out.internal_rv_mtimecmp_h.compare_h.value = field_storage.internal_rv_mtimecmp_h.compare_h.value; + // Field: soc_ifc_reg.intr_block_rf.global_intr_en_r.error_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.global_intr_en_r.error_en.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.global_intr_en_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.intr_block_rf.global_intr_en_r.error_en.value & ~decoded_wr_biten[0:0]) | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end + field_combo.intr_block_rf.global_intr_en_r.error_en.next = next_c; + field_combo.intr_block_rf.global_intr_en_r.error_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.global_intr_en_r.error_en.value <= 1'h0; + end else if(field_combo.intr_block_rf.global_intr_en_r.error_en.load_next) begin + field_storage.intr_block_rf.global_intr_en_r.error_en.value <= field_combo.intr_block_rf.global_intr_en_r.error_en.next; + end + end + // Field: soc_ifc_reg.intr_block_rf.global_intr_en_r.notif_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.global_intr_en_r.notif_en.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.global_intr_en_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.intr_block_rf.global_intr_en_r.notif_en.value & ~decoded_wr_biten[1:1]) | (decoded_wr_data[1:1] & decoded_wr_biten[1:1]); + load_next_c = '1; + end + field_combo.intr_block_rf.global_intr_en_r.notif_en.next = next_c; + field_combo.intr_block_rf.global_intr_en_r.notif_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.global_intr_en_r.notif_en.value <= 1'h0; + end else if(field_combo.intr_block_rf.global_intr_en_r.notif_en.load_next) begin + field_storage.intr_block_rf.global_intr_en_r.notif_en.value <= field_combo.intr_block_rf.global_intr_en_r.notif_en.next; + end + end + // Field: soc_ifc_reg.intr_block_rf.error_intr_en_r.error_internal_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_intr_en_r.error_internal_en.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_intr_en_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.intr_block_rf.error_intr_en_r.error_internal_en.value & ~decoded_wr_biten[0:0]) | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end + field_combo.intr_block_rf.error_intr_en_r.error_internal_en.next = next_c; + field_combo.intr_block_rf.error_intr_en_r.error_internal_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.error_intr_en_r.error_internal_en.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_intr_en_r.error_internal_en.load_next) begin + field_storage.intr_block_rf.error_intr_en_r.error_internal_en.value <= field_combo.intr_block_rf.error_intr_en_r.error_internal_en.next; + end + end + // Field: soc_ifc_reg.intr_block_rf.error_intr_en_r.error_inv_dev_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_intr_en_r.error_inv_dev_en.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_intr_en_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.intr_block_rf.error_intr_en_r.error_inv_dev_en.value & ~decoded_wr_biten[1:1]) | (decoded_wr_data[1:1] & decoded_wr_biten[1:1]); + load_next_c = '1; + end + field_combo.intr_block_rf.error_intr_en_r.error_inv_dev_en.next = next_c; + field_combo.intr_block_rf.error_intr_en_r.error_inv_dev_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.error_intr_en_r.error_inv_dev_en.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_intr_en_r.error_inv_dev_en.load_next) begin + field_storage.intr_block_rf.error_intr_en_r.error_inv_dev_en.value <= field_combo.intr_block_rf.error_intr_en_r.error_inv_dev_en.next; + end + end + // Field: soc_ifc_reg.intr_block_rf.error_intr_en_r.error_cmd_fail_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_intr_en_r.error_cmd_fail_en.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_intr_en_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.intr_block_rf.error_intr_en_r.error_cmd_fail_en.value & ~decoded_wr_biten[2:2]) | (decoded_wr_data[2:2] & decoded_wr_biten[2:2]); + load_next_c = '1; + end + field_combo.intr_block_rf.error_intr_en_r.error_cmd_fail_en.next = next_c; + field_combo.intr_block_rf.error_intr_en_r.error_cmd_fail_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.error_intr_en_r.error_cmd_fail_en.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_intr_en_r.error_cmd_fail_en.load_next) begin + field_storage.intr_block_rf.error_intr_en_r.error_cmd_fail_en.value <= field_combo.intr_block_rf.error_intr_en_r.error_cmd_fail_en.next; + end + end + // Field: soc_ifc_reg.intr_block_rf.error_intr_en_r.error_bad_fuse_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_intr_en_r.error_bad_fuse_en.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_intr_en_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.intr_block_rf.error_intr_en_r.error_bad_fuse_en.value & ~decoded_wr_biten[3:3]) | (decoded_wr_data[3:3] & decoded_wr_biten[3:3]); + load_next_c = '1; + end + field_combo.intr_block_rf.error_intr_en_r.error_bad_fuse_en.next = next_c; + field_combo.intr_block_rf.error_intr_en_r.error_bad_fuse_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.error_intr_en_r.error_bad_fuse_en.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_intr_en_r.error_bad_fuse_en.load_next) begin + field_storage.intr_block_rf.error_intr_en_r.error_bad_fuse_en.value <= field_combo.intr_block_rf.error_intr_en_r.error_bad_fuse_en.next; + end + end + // Field: soc_ifc_reg.intr_block_rf.error_intr_en_r.error_iccm_blocked_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_intr_en_r.error_iccm_blocked_en.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_intr_en_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.intr_block_rf.error_intr_en_r.error_iccm_blocked_en.value & ~decoded_wr_biten[4:4]) | (decoded_wr_data[4:4] & decoded_wr_biten[4:4]); + load_next_c = '1; + end + field_combo.intr_block_rf.error_intr_en_r.error_iccm_blocked_en.next = next_c; + field_combo.intr_block_rf.error_intr_en_r.error_iccm_blocked_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.error_intr_en_r.error_iccm_blocked_en.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_intr_en_r.error_iccm_blocked_en.load_next) begin + field_storage.intr_block_rf.error_intr_en_r.error_iccm_blocked_en.value <= field_combo.intr_block_rf.error_intr_en_r.error_iccm_blocked_en.next; + end + end + // Field: soc_ifc_reg.intr_block_rf.error_intr_en_r.error_mbox_ecc_unc_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_intr_en_r.error_mbox_ecc_unc_en.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_intr_en_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.intr_block_rf.error_intr_en_r.error_mbox_ecc_unc_en.value & ~decoded_wr_biten[5:5]) | (decoded_wr_data[5:5] & decoded_wr_biten[5:5]); + load_next_c = '1; + end + field_combo.intr_block_rf.error_intr_en_r.error_mbox_ecc_unc_en.next = next_c; + field_combo.intr_block_rf.error_intr_en_r.error_mbox_ecc_unc_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.error_intr_en_r.error_mbox_ecc_unc_en.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_intr_en_r.error_mbox_ecc_unc_en.load_next) begin + field_storage.intr_block_rf.error_intr_en_r.error_mbox_ecc_unc_en.value <= field_combo.intr_block_rf.error_intr_en_r.error_mbox_ecc_unc_en.next; + end + end + // Field: soc_ifc_reg.intr_block_rf.error_intr_en_r.error_wdt_timer1_timeout_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_intr_en_r.error_wdt_timer1_timeout_en.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_intr_en_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.intr_block_rf.error_intr_en_r.error_wdt_timer1_timeout_en.value & ~decoded_wr_biten[6:6]) | (decoded_wr_data[6:6] & decoded_wr_biten[6:6]); + load_next_c = '1; + end + field_combo.intr_block_rf.error_intr_en_r.error_wdt_timer1_timeout_en.next = next_c; + field_combo.intr_block_rf.error_intr_en_r.error_wdt_timer1_timeout_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.error_intr_en_r.error_wdt_timer1_timeout_en.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_intr_en_r.error_wdt_timer1_timeout_en.load_next) begin + field_storage.intr_block_rf.error_intr_en_r.error_wdt_timer1_timeout_en.value <= field_combo.intr_block_rf.error_intr_en_r.error_wdt_timer1_timeout_en.next; + end + end + // Field: soc_ifc_reg.intr_block_rf.error_intr_en_r.error_wdt_timer2_timeout_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_intr_en_r.error_wdt_timer2_timeout_en.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_intr_en_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.intr_block_rf.error_intr_en_r.error_wdt_timer2_timeout_en.value & ~decoded_wr_biten[7:7]) | (decoded_wr_data[7:7] & decoded_wr_biten[7:7]); + load_next_c = '1; + end + field_combo.intr_block_rf.error_intr_en_r.error_wdt_timer2_timeout_en.next = next_c; + field_combo.intr_block_rf.error_intr_en_r.error_wdt_timer2_timeout_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.error_intr_en_r.error_wdt_timer2_timeout_en.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_intr_en_r.error_wdt_timer2_timeout_en.load_next) begin + field_storage.intr_block_rf.error_intr_en_r.error_wdt_timer2_timeout_en.value <= field_combo.intr_block_rf.error_intr_en_r.error_wdt_timer2_timeout_en.next; + end + end + // Field: soc_ifc_reg.intr_block_rf.notif_intr_en_r.notif_cmd_avail_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_intr_en_r.notif_cmd_avail_en.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.notif_intr_en_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.intr_block_rf.notif_intr_en_r.notif_cmd_avail_en.value & ~decoded_wr_biten[0:0]) | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end + field_combo.intr_block_rf.notif_intr_en_r.notif_cmd_avail_en.next = next_c; + field_combo.intr_block_rf.notif_intr_en_r.notif_cmd_avail_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.notif_intr_en_r.notif_cmd_avail_en.value <= 1'h0; + end else if(field_combo.intr_block_rf.notif_intr_en_r.notif_cmd_avail_en.load_next) begin + field_storage.intr_block_rf.notif_intr_en_r.notif_cmd_avail_en.value <= field_combo.intr_block_rf.notif_intr_en_r.notif_cmd_avail_en.next; + end + end + // Field: soc_ifc_reg.intr_block_rf.notif_intr_en_r.notif_mbox_ecc_cor_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_intr_en_r.notif_mbox_ecc_cor_en.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.notif_intr_en_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.intr_block_rf.notif_intr_en_r.notif_mbox_ecc_cor_en.value & ~decoded_wr_biten[1:1]) | (decoded_wr_data[1:1] & decoded_wr_biten[1:1]); + load_next_c = '1; + end + field_combo.intr_block_rf.notif_intr_en_r.notif_mbox_ecc_cor_en.next = next_c; + field_combo.intr_block_rf.notif_intr_en_r.notif_mbox_ecc_cor_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.notif_intr_en_r.notif_mbox_ecc_cor_en.value <= 1'h0; + end else if(field_combo.intr_block_rf.notif_intr_en_r.notif_mbox_ecc_cor_en.load_next) begin + field_storage.intr_block_rf.notif_intr_en_r.notif_mbox_ecc_cor_en.value <= field_combo.intr_block_rf.notif_intr_en_r.notif_mbox_ecc_cor_en.next; + end + end + // Field: soc_ifc_reg.intr_block_rf.notif_intr_en_r.notif_debug_locked_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_intr_en_r.notif_debug_locked_en.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.notif_intr_en_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.intr_block_rf.notif_intr_en_r.notif_debug_locked_en.value & ~decoded_wr_biten[2:2]) | (decoded_wr_data[2:2] & decoded_wr_biten[2:2]); + load_next_c = '1; + end + field_combo.intr_block_rf.notif_intr_en_r.notif_debug_locked_en.next = next_c; + field_combo.intr_block_rf.notif_intr_en_r.notif_debug_locked_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.notif_intr_en_r.notif_debug_locked_en.value <= 1'h0; + end else if(field_combo.intr_block_rf.notif_intr_en_r.notif_debug_locked_en.load_next) begin + field_storage.intr_block_rf.notif_intr_en_r.notif_debug_locked_en.value <= field_combo.intr_block_rf.notif_intr_en_r.notif_debug_locked_en.next; + end + end + // Field: soc_ifc_reg.intr_block_rf.notif_intr_en_r.notif_scan_mode_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_intr_en_r.notif_scan_mode_en.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.notif_intr_en_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.intr_block_rf.notif_intr_en_r.notif_scan_mode_en.value & ~decoded_wr_biten[3:3]) | (decoded_wr_data[3:3] & decoded_wr_biten[3:3]); + load_next_c = '1; + end + field_combo.intr_block_rf.notif_intr_en_r.notif_scan_mode_en.next = next_c; + field_combo.intr_block_rf.notif_intr_en_r.notif_scan_mode_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.notif_intr_en_r.notif_scan_mode_en.value <= 1'h0; + end else if(field_combo.intr_block_rf.notif_intr_en_r.notif_scan_mode_en.load_next) begin + field_storage.intr_block_rf.notif_intr_en_r.notif_scan_mode_en.value <= field_combo.intr_block_rf.notif_intr_en_r.notif_scan_mode_en.next; + end + end + // Field: soc_ifc_reg.intr_block_rf.notif_intr_en_r.notif_soc_req_lock_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_intr_en_r.notif_soc_req_lock_en.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.notif_intr_en_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.intr_block_rf.notif_intr_en_r.notif_soc_req_lock_en.value & ~decoded_wr_biten[4:4]) | (decoded_wr_data[4:4] & decoded_wr_biten[4:4]); + load_next_c = '1; + end + field_combo.intr_block_rf.notif_intr_en_r.notif_soc_req_lock_en.next = next_c; + field_combo.intr_block_rf.notif_intr_en_r.notif_soc_req_lock_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.notif_intr_en_r.notif_soc_req_lock_en.value <= 1'h0; + end else if(field_combo.intr_block_rf.notif_intr_en_r.notif_soc_req_lock_en.load_next) begin + field_storage.intr_block_rf.notif_intr_en_r.notif_soc_req_lock_en.value <= field_combo.intr_block_rf.notif_intr_en_r.notif_soc_req_lock_en.next; + end + end + // Field: soc_ifc_reg.intr_block_rf.notif_intr_en_r.notif_gen_in_toggle_en + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_intr_en_r.notif_gen_in_toggle_en.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.notif_intr_en_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.intr_block_rf.notif_intr_en_r.notif_gen_in_toggle_en.value & ~decoded_wr_biten[5:5]) | (decoded_wr_data[5:5] & decoded_wr_biten[5:5]); + load_next_c = '1; + end + field_combo.intr_block_rf.notif_intr_en_r.notif_gen_in_toggle_en.next = next_c; + field_combo.intr_block_rf.notif_intr_en_r.notif_gen_in_toggle_en.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.notif_intr_en_r.notif_gen_in_toggle_en.value <= 1'h0; + end else if(field_combo.intr_block_rf.notif_intr_en_r.notif_gen_in_toggle_en.load_next) begin + field_storage.intr_block_rf.notif_intr_en_r.notif_gen_in_toggle_en.value <= field_combo.intr_block_rf.notif_intr_en_r.notif_gen_in_toggle_en.next; + end + end + // Field: soc_ifc_reg.intr_block_rf.error_global_intr_r.agg_sts + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_global_intr_r.agg_sts.value; + load_next_c = '0; + + // HW Write + next_c = hwif_out.intr_block_rf.error_internal_intr_r.intr; + load_next_c = '1; + field_combo.intr_block_rf.error_global_intr_r.agg_sts.next = next_c; + field_combo.intr_block_rf.error_global_intr_r.agg_sts.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.error_global_intr_r.agg_sts.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_global_intr_r.agg_sts.load_next) begin + field_storage.intr_block_rf.error_global_intr_r.agg_sts.value <= field_combo.intr_block_rf.error_global_intr_r.agg_sts.next; + end + end + assign hwif_out.intr_block_rf.error_global_intr_r.intr = + |(field_storage.intr_block_rf.error_global_intr_r.agg_sts.value & field_storage.intr_block_rf.global_intr_en_r.error_en.value); + // Field: soc_ifc_reg.intr_block_rf.notif_global_intr_r.agg_sts + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_global_intr_r.agg_sts.value; + load_next_c = '0; + + // HW Write + next_c = hwif_out.intr_block_rf.notif_internal_intr_r.intr; + load_next_c = '1; + field_combo.intr_block_rf.notif_global_intr_r.agg_sts.next = next_c; + field_combo.intr_block_rf.notif_global_intr_r.agg_sts.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.notif_global_intr_r.agg_sts.value <= 1'h0; + end else if(field_combo.intr_block_rf.notif_global_intr_r.agg_sts.load_next) begin + field_storage.intr_block_rf.notif_global_intr_r.agg_sts.value <= field_combo.intr_block_rf.notif_global_intr_r.agg_sts.next; + end + end + assign hwif_out.intr_block_rf.notif_global_intr_r.intr = + |(field_storage.intr_block_rf.notif_global_intr_r.agg_sts.value & field_storage.intr_block_rf.global_intr_en_r.notif_en.value); + // Field: soc_ifc_reg.intr_block_rf.error_internal_intr_r.error_internal_sts + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_internal_intr_r.error_internal_sts.value; + load_next_c = '0; + if(field_storage.intr_block_rf.error_intr_trig_r.error_internal_trig.value != '0) begin // stickybit + next_c = field_storage.intr_block_rf.error_internal_intr_r.error_internal_sts.value | field_storage.intr_block_rf.error_intr_trig_r.error_internal_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.error_internal_intr_r.error_internal_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end else if(decoded_reg_strb.intr_block_rf.error_internal_intr_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write 1 clear + next_c = field_storage.intr_block_rf.error_internal_intr_r.error_internal_sts.value & ~(decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end + field_combo.intr_block_rf.error_internal_intr_r.error_internal_sts.next = next_c; + field_combo.intr_block_rf.error_internal_intr_r.error_internal_sts.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.intr_block_rf.error_internal_intr_r.error_internal_sts.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_internal_intr_r.error_internal_sts.load_next) begin + field_storage.intr_block_rf.error_internal_intr_r.error_internal_sts.value <= field_combo.intr_block_rf.error_internal_intr_r.error_internal_sts.next; + end + end + // Field: soc_ifc_reg.intr_block_rf.error_internal_intr_r.error_inv_dev_sts + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_internal_intr_r.error_inv_dev_sts.value; + load_next_c = '0; + if(field_storage.intr_block_rf.error_intr_trig_r.error_inv_dev_trig.value != '0) begin // stickybit + next_c = field_storage.intr_block_rf.error_internal_intr_r.error_inv_dev_sts.value | field_storage.intr_block_rf.error_intr_trig_r.error_inv_dev_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.error_internal_intr_r.error_inv_dev_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end else if(decoded_reg_strb.intr_block_rf.error_internal_intr_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write 1 clear + next_c = field_storage.intr_block_rf.error_internal_intr_r.error_inv_dev_sts.value & ~(decoded_wr_data[1:1] & decoded_wr_biten[1:1]); + load_next_c = '1; + end + field_combo.intr_block_rf.error_internal_intr_r.error_inv_dev_sts.next = next_c; + field_combo.intr_block_rf.error_internal_intr_r.error_inv_dev_sts.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.intr_block_rf.error_internal_intr_r.error_inv_dev_sts.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_internal_intr_r.error_inv_dev_sts.load_next) begin + field_storage.intr_block_rf.error_internal_intr_r.error_inv_dev_sts.value <= field_combo.intr_block_rf.error_internal_intr_r.error_inv_dev_sts.next; + end + end + // Field: soc_ifc_reg.intr_block_rf.error_internal_intr_r.error_cmd_fail_sts + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_internal_intr_r.error_cmd_fail_sts.value; + load_next_c = '0; + if(field_storage.intr_block_rf.error_intr_trig_r.error_cmd_fail_trig.value != '0) begin // stickybit + next_c = field_storage.intr_block_rf.error_internal_intr_r.error_cmd_fail_sts.value | field_storage.intr_block_rf.error_intr_trig_r.error_cmd_fail_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.error_internal_intr_r.error_cmd_fail_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end else if(decoded_reg_strb.intr_block_rf.error_internal_intr_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write 1 clear + next_c = field_storage.intr_block_rf.error_internal_intr_r.error_cmd_fail_sts.value & ~(decoded_wr_data[2:2] & decoded_wr_biten[2:2]); + load_next_c = '1; + end + field_combo.intr_block_rf.error_internal_intr_r.error_cmd_fail_sts.next = next_c; + field_combo.intr_block_rf.error_internal_intr_r.error_cmd_fail_sts.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.intr_block_rf.error_internal_intr_r.error_cmd_fail_sts.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_internal_intr_r.error_cmd_fail_sts.load_next) begin + field_storage.intr_block_rf.error_internal_intr_r.error_cmd_fail_sts.value <= field_combo.intr_block_rf.error_internal_intr_r.error_cmd_fail_sts.next; + end + end + // Field: soc_ifc_reg.intr_block_rf.error_internal_intr_r.error_bad_fuse_sts + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_internal_intr_r.error_bad_fuse_sts.value; + load_next_c = '0; + if(field_storage.intr_block_rf.error_intr_trig_r.error_bad_fuse_trig.value != '0) begin // stickybit + next_c = field_storage.intr_block_rf.error_internal_intr_r.error_bad_fuse_sts.value | field_storage.intr_block_rf.error_intr_trig_r.error_bad_fuse_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.error_internal_intr_r.error_bad_fuse_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end else if(decoded_reg_strb.intr_block_rf.error_internal_intr_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write 1 clear + next_c = field_storage.intr_block_rf.error_internal_intr_r.error_bad_fuse_sts.value & ~(decoded_wr_data[3:3] & decoded_wr_biten[3:3]); + load_next_c = '1; + end + field_combo.intr_block_rf.error_internal_intr_r.error_bad_fuse_sts.next = next_c; + field_combo.intr_block_rf.error_internal_intr_r.error_bad_fuse_sts.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.intr_block_rf.error_internal_intr_r.error_bad_fuse_sts.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_internal_intr_r.error_bad_fuse_sts.load_next) begin + field_storage.intr_block_rf.error_internal_intr_r.error_bad_fuse_sts.value <= field_combo.intr_block_rf.error_internal_intr_r.error_bad_fuse_sts.next; + end + end + // Field: soc_ifc_reg.intr_block_rf.error_internal_intr_r.error_iccm_blocked_sts + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_internal_intr_r.error_iccm_blocked_sts.value; + load_next_c = '0; + if(field_storage.intr_block_rf.error_intr_trig_r.error_iccm_blocked_trig.value != '0) begin // stickybit + next_c = field_storage.intr_block_rf.error_internal_intr_r.error_iccm_blocked_sts.value | field_storage.intr_block_rf.error_intr_trig_r.error_iccm_blocked_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.error_internal_intr_r.error_iccm_blocked_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end else if(decoded_reg_strb.intr_block_rf.error_internal_intr_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write 1 clear + next_c = field_storage.intr_block_rf.error_internal_intr_r.error_iccm_blocked_sts.value & ~(decoded_wr_data[4:4] & decoded_wr_biten[4:4]); + load_next_c = '1; + end + field_combo.intr_block_rf.error_internal_intr_r.error_iccm_blocked_sts.next = next_c; + field_combo.intr_block_rf.error_internal_intr_r.error_iccm_blocked_sts.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.intr_block_rf.error_internal_intr_r.error_iccm_blocked_sts.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_internal_intr_r.error_iccm_blocked_sts.load_next) begin + field_storage.intr_block_rf.error_internal_intr_r.error_iccm_blocked_sts.value <= field_combo.intr_block_rf.error_internal_intr_r.error_iccm_blocked_sts.next; + end + end + // Field: soc_ifc_reg.intr_block_rf.error_internal_intr_r.error_mbox_ecc_unc_sts + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_internal_intr_r.error_mbox_ecc_unc_sts.value; + load_next_c = '0; + if(field_storage.intr_block_rf.error_intr_trig_r.error_mbox_ecc_unc_trig.value != '0) begin // stickybit + next_c = field_storage.intr_block_rf.error_internal_intr_r.error_mbox_ecc_unc_sts.value | field_storage.intr_block_rf.error_intr_trig_r.error_mbox_ecc_unc_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.error_internal_intr_r.error_mbox_ecc_unc_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end else if(decoded_reg_strb.intr_block_rf.error_internal_intr_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write 1 clear + next_c = field_storage.intr_block_rf.error_internal_intr_r.error_mbox_ecc_unc_sts.value & ~(decoded_wr_data[5:5] & decoded_wr_biten[5:5]); + load_next_c = '1; + end + field_combo.intr_block_rf.error_internal_intr_r.error_mbox_ecc_unc_sts.next = next_c; + field_combo.intr_block_rf.error_internal_intr_r.error_mbox_ecc_unc_sts.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.intr_block_rf.error_internal_intr_r.error_mbox_ecc_unc_sts.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_internal_intr_r.error_mbox_ecc_unc_sts.load_next) begin + field_storage.intr_block_rf.error_internal_intr_r.error_mbox_ecc_unc_sts.value <= field_combo.intr_block_rf.error_internal_intr_r.error_mbox_ecc_unc_sts.next; + end + end + // Field: soc_ifc_reg.intr_block_rf.error_internal_intr_r.error_wdt_timer1_timeout_sts + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_internal_intr_r.error_wdt_timer1_timeout_sts.value; + load_next_c = '0; + if(field_storage.intr_block_rf.error_intr_trig_r.error_wdt_timer1_timeout_trig.value != '0) begin // stickybit + next_c = field_storage.intr_block_rf.error_internal_intr_r.error_wdt_timer1_timeout_sts.value | field_storage.intr_block_rf.error_intr_trig_r.error_wdt_timer1_timeout_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.error_internal_intr_r.error_wdt_timer1_timeout_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end else if(decoded_reg_strb.intr_block_rf.error_internal_intr_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write 1 clear + next_c = field_storage.intr_block_rf.error_internal_intr_r.error_wdt_timer1_timeout_sts.value & ~(decoded_wr_data[6:6] & decoded_wr_biten[6:6]); + load_next_c = '1; + end + field_combo.intr_block_rf.error_internal_intr_r.error_wdt_timer1_timeout_sts.next = next_c; + field_combo.intr_block_rf.error_internal_intr_r.error_wdt_timer1_timeout_sts.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.intr_block_rf.error_internal_intr_r.error_wdt_timer1_timeout_sts.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_internal_intr_r.error_wdt_timer1_timeout_sts.load_next) begin + field_storage.intr_block_rf.error_internal_intr_r.error_wdt_timer1_timeout_sts.value <= field_combo.intr_block_rf.error_internal_intr_r.error_wdt_timer1_timeout_sts.next; + end + end + // Field: soc_ifc_reg.intr_block_rf.error_internal_intr_r.error_wdt_timer2_timeout_sts + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_internal_intr_r.error_wdt_timer2_timeout_sts.value; + load_next_c = '0; + if(field_storage.intr_block_rf.error_intr_trig_r.error_wdt_timer2_timeout_trig.value != '0) begin // stickybit + next_c = field_storage.intr_block_rf.error_internal_intr_r.error_wdt_timer2_timeout_sts.value | field_storage.intr_block_rf.error_intr_trig_r.error_wdt_timer2_timeout_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.error_internal_intr_r.error_wdt_timer2_timeout_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end else if(decoded_reg_strb.intr_block_rf.error_internal_intr_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write 1 clear + next_c = field_storage.intr_block_rf.error_internal_intr_r.error_wdt_timer2_timeout_sts.value & ~(decoded_wr_data[7:7] & decoded_wr_biten[7:7]); + load_next_c = '1; + end + field_combo.intr_block_rf.error_internal_intr_r.error_wdt_timer2_timeout_sts.next = next_c; + field_combo.intr_block_rf.error_internal_intr_r.error_wdt_timer2_timeout_sts.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.intr_block_rf.error_internal_intr_r.error_wdt_timer2_timeout_sts.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_internal_intr_r.error_wdt_timer2_timeout_sts.load_next) begin + field_storage.intr_block_rf.error_internal_intr_r.error_wdt_timer2_timeout_sts.value <= field_combo.intr_block_rf.error_internal_intr_r.error_wdt_timer2_timeout_sts.next; + end + end + assign hwif_out.intr_block_rf.error_internal_intr_r.intr = + |(field_storage.intr_block_rf.error_internal_intr_r.error_internal_sts.value & field_storage.intr_block_rf.error_intr_en_r.error_internal_en.value) + || |(field_storage.intr_block_rf.error_internal_intr_r.error_inv_dev_sts.value & field_storage.intr_block_rf.error_intr_en_r.error_inv_dev_en.value) + || |(field_storage.intr_block_rf.error_internal_intr_r.error_cmd_fail_sts.value & field_storage.intr_block_rf.error_intr_en_r.error_cmd_fail_en.value) + || |(field_storage.intr_block_rf.error_internal_intr_r.error_bad_fuse_sts.value & field_storage.intr_block_rf.error_intr_en_r.error_bad_fuse_en.value) + || |(field_storage.intr_block_rf.error_internal_intr_r.error_iccm_blocked_sts.value & field_storage.intr_block_rf.error_intr_en_r.error_iccm_blocked_en.value) + || |(field_storage.intr_block_rf.error_internal_intr_r.error_mbox_ecc_unc_sts.value & field_storage.intr_block_rf.error_intr_en_r.error_mbox_ecc_unc_en.value) + || |(field_storage.intr_block_rf.error_internal_intr_r.error_wdt_timer1_timeout_sts.value & field_storage.intr_block_rf.error_intr_en_r.error_wdt_timer1_timeout_en.value) + || |(field_storage.intr_block_rf.error_internal_intr_r.error_wdt_timer2_timeout_sts.value & field_storage.intr_block_rf.error_intr_en_r.error_wdt_timer2_timeout_en.value); + // Field: soc_ifc_reg.intr_block_rf.notif_internal_intr_r.notif_cmd_avail_sts + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_internal_intr_r.notif_cmd_avail_sts.value; + load_next_c = '0; + if(field_storage.intr_block_rf.notif_intr_trig_r.notif_cmd_avail_trig.value != '0) begin // stickybit + next_c = field_storage.intr_block_rf.notif_internal_intr_r.notif_cmd_avail_sts.value | field_storage.intr_block_rf.notif_intr_trig_r.notif_cmd_avail_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.notif_internal_intr_r.notif_cmd_avail_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end else if(decoded_reg_strb.intr_block_rf.notif_internal_intr_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write 1 clear + next_c = field_storage.intr_block_rf.notif_internal_intr_r.notif_cmd_avail_sts.value & ~(decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end + field_combo.intr_block_rf.notif_internal_intr_r.notif_cmd_avail_sts.next = next_c; + field_combo.intr_block_rf.notif_internal_intr_r.notif_cmd_avail_sts.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.notif_internal_intr_r.notif_cmd_avail_sts.value <= 1'h0; + end else if(field_combo.intr_block_rf.notif_internal_intr_r.notif_cmd_avail_sts.load_next) begin + field_storage.intr_block_rf.notif_internal_intr_r.notif_cmd_avail_sts.value <= field_combo.intr_block_rf.notif_internal_intr_r.notif_cmd_avail_sts.next; + end + end + // Field: soc_ifc_reg.intr_block_rf.notif_internal_intr_r.notif_mbox_ecc_cor_sts + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_internal_intr_r.notif_mbox_ecc_cor_sts.value; + load_next_c = '0; + if(field_storage.intr_block_rf.notif_intr_trig_r.notif_mbox_ecc_cor_trig.value != '0) begin // stickybit + next_c = field_storage.intr_block_rf.notif_internal_intr_r.notif_mbox_ecc_cor_sts.value | field_storage.intr_block_rf.notif_intr_trig_r.notif_mbox_ecc_cor_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.notif_internal_intr_r.notif_mbox_ecc_cor_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end else if(decoded_reg_strb.intr_block_rf.notif_internal_intr_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write 1 clear + next_c = field_storage.intr_block_rf.notif_internal_intr_r.notif_mbox_ecc_cor_sts.value & ~(decoded_wr_data[1:1] & decoded_wr_biten[1:1]); + load_next_c = '1; + end + field_combo.intr_block_rf.notif_internal_intr_r.notif_mbox_ecc_cor_sts.next = next_c; + field_combo.intr_block_rf.notif_internal_intr_r.notif_mbox_ecc_cor_sts.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.notif_internal_intr_r.notif_mbox_ecc_cor_sts.value <= 1'h0; + end else if(field_combo.intr_block_rf.notif_internal_intr_r.notif_mbox_ecc_cor_sts.load_next) begin + field_storage.intr_block_rf.notif_internal_intr_r.notif_mbox_ecc_cor_sts.value <= field_combo.intr_block_rf.notif_internal_intr_r.notif_mbox_ecc_cor_sts.next; + end + end + // Field: soc_ifc_reg.intr_block_rf.notif_internal_intr_r.notif_debug_locked_sts + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_internal_intr_r.notif_debug_locked_sts.value; + load_next_c = '0; + if(field_storage.intr_block_rf.notif_intr_trig_r.notif_debug_locked_trig.value != '0) begin // stickybit + next_c = field_storage.intr_block_rf.notif_internal_intr_r.notif_debug_locked_sts.value | field_storage.intr_block_rf.notif_intr_trig_r.notif_debug_locked_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.notif_internal_intr_r.notif_debug_locked_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end else if(decoded_reg_strb.intr_block_rf.notif_internal_intr_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write 1 clear + next_c = field_storage.intr_block_rf.notif_internal_intr_r.notif_debug_locked_sts.value & ~(decoded_wr_data[2:2] & decoded_wr_biten[2:2]); + load_next_c = '1; + end + field_combo.intr_block_rf.notif_internal_intr_r.notif_debug_locked_sts.next = next_c; + field_combo.intr_block_rf.notif_internal_intr_r.notif_debug_locked_sts.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.notif_internal_intr_r.notif_debug_locked_sts.value <= 1'h0; + end else if(field_combo.intr_block_rf.notif_internal_intr_r.notif_debug_locked_sts.load_next) begin + field_storage.intr_block_rf.notif_internal_intr_r.notif_debug_locked_sts.value <= field_combo.intr_block_rf.notif_internal_intr_r.notif_debug_locked_sts.next; + end + end + // Field: soc_ifc_reg.intr_block_rf.notif_internal_intr_r.notif_scan_mode_sts + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_internal_intr_r.notif_scan_mode_sts.value; + load_next_c = '0; + if(field_storage.intr_block_rf.notif_intr_trig_r.notif_scan_mode_trig.value != '0) begin // stickybit + next_c = field_storage.intr_block_rf.notif_internal_intr_r.notif_scan_mode_sts.value | field_storage.intr_block_rf.notif_intr_trig_r.notif_scan_mode_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.notif_internal_intr_r.notif_scan_mode_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end else if(decoded_reg_strb.intr_block_rf.notif_internal_intr_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write 1 clear + next_c = field_storage.intr_block_rf.notif_internal_intr_r.notif_scan_mode_sts.value & ~(decoded_wr_data[3:3] & decoded_wr_biten[3:3]); + load_next_c = '1; + end + field_combo.intr_block_rf.notif_internal_intr_r.notif_scan_mode_sts.next = next_c; + field_combo.intr_block_rf.notif_internal_intr_r.notif_scan_mode_sts.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.notif_internal_intr_r.notif_scan_mode_sts.value <= 1'h0; + end else if(field_combo.intr_block_rf.notif_internal_intr_r.notif_scan_mode_sts.load_next) begin + field_storage.intr_block_rf.notif_internal_intr_r.notif_scan_mode_sts.value <= field_combo.intr_block_rf.notif_internal_intr_r.notif_scan_mode_sts.next; + end + end + // Field: soc_ifc_reg.intr_block_rf.notif_internal_intr_r.notif_soc_req_lock_sts + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_internal_intr_r.notif_soc_req_lock_sts.value; + load_next_c = '0; + if(field_storage.intr_block_rf.notif_intr_trig_r.notif_soc_req_lock_trig.value != '0) begin // stickybit + next_c = field_storage.intr_block_rf.notif_internal_intr_r.notif_soc_req_lock_sts.value | field_storage.intr_block_rf.notif_intr_trig_r.notif_soc_req_lock_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.notif_internal_intr_r.notif_soc_req_lock_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end else if(decoded_reg_strb.intr_block_rf.notif_internal_intr_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write 1 clear + next_c = field_storage.intr_block_rf.notif_internal_intr_r.notif_soc_req_lock_sts.value & ~(decoded_wr_data[4:4] & decoded_wr_biten[4:4]); + load_next_c = '1; + end + field_combo.intr_block_rf.notif_internal_intr_r.notif_soc_req_lock_sts.next = next_c; + field_combo.intr_block_rf.notif_internal_intr_r.notif_soc_req_lock_sts.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.notif_internal_intr_r.notif_soc_req_lock_sts.value <= 1'h0; + end else if(field_combo.intr_block_rf.notif_internal_intr_r.notif_soc_req_lock_sts.load_next) begin + field_storage.intr_block_rf.notif_internal_intr_r.notif_soc_req_lock_sts.value <= field_combo.intr_block_rf.notif_internal_intr_r.notif_soc_req_lock_sts.next; + end + end + // Field: soc_ifc_reg.intr_block_rf.notif_internal_intr_r.notif_gen_in_toggle_sts + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_internal_intr_r.notif_gen_in_toggle_sts.value; + load_next_c = '0; + if(field_storage.intr_block_rf.notif_intr_trig_r.notif_gen_in_toggle_trig.value != '0) begin // stickybit + next_c = field_storage.intr_block_rf.notif_internal_intr_r.notif_gen_in_toggle_sts.value | field_storage.intr_block_rf.notif_intr_trig_r.notif_gen_in_toggle_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.notif_internal_intr_r.notif_gen_in_toggle_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end else if(decoded_reg_strb.intr_block_rf.notif_internal_intr_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write 1 clear + next_c = field_storage.intr_block_rf.notif_internal_intr_r.notif_gen_in_toggle_sts.value & ~(decoded_wr_data[5:5] & decoded_wr_biten[5:5]); + load_next_c = '1; + end + field_combo.intr_block_rf.notif_internal_intr_r.notif_gen_in_toggle_sts.next = next_c; + field_combo.intr_block_rf.notif_internal_intr_r.notif_gen_in_toggle_sts.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.notif_internal_intr_r.notif_gen_in_toggle_sts.value <= 1'h0; + end else if(field_combo.intr_block_rf.notif_internal_intr_r.notif_gen_in_toggle_sts.load_next) begin + field_storage.intr_block_rf.notif_internal_intr_r.notif_gen_in_toggle_sts.value <= field_combo.intr_block_rf.notif_internal_intr_r.notif_gen_in_toggle_sts.next; + end + end + assign hwif_out.intr_block_rf.notif_internal_intr_r.intr = + |(field_storage.intr_block_rf.notif_internal_intr_r.notif_cmd_avail_sts.value & field_storage.intr_block_rf.notif_intr_en_r.notif_cmd_avail_en.value) + || |(field_storage.intr_block_rf.notif_internal_intr_r.notif_mbox_ecc_cor_sts.value & field_storage.intr_block_rf.notif_intr_en_r.notif_mbox_ecc_cor_en.value) + || |(field_storage.intr_block_rf.notif_internal_intr_r.notif_debug_locked_sts.value & field_storage.intr_block_rf.notif_intr_en_r.notif_debug_locked_en.value) + || |(field_storage.intr_block_rf.notif_internal_intr_r.notif_scan_mode_sts.value & field_storage.intr_block_rf.notif_intr_en_r.notif_scan_mode_en.value) + || |(field_storage.intr_block_rf.notif_internal_intr_r.notif_soc_req_lock_sts.value & field_storage.intr_block_rf.notif_intr_en_r.notif_soc_req_lock_en.value) + || |(field_storage.intr_block_rf.notif_internal_intr_r.notif_gen_in_toggle_sts.value & field_storage.intr_block_rf.notif_intr_en_r.notif_gen_in_toggle_en.value); + // Field: soc_ifc_reg.intr_block_rf.error_intr_trig_r.error_internal_trig + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_intr_trig_r.error_internal_trig.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_intr_trig_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write 1 set + next_c = field_storage.intr_block_rf.error_intr_trig_r.error_internal_trig.value | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end else begin // singlepulse clears back to 0 + next_c = '0; + load_next_c = '1; + end + field_combo.intr_block_rf.error_intr_trig_r.error_internal_trig.next = next_c; + field_combo.intr_block_rf.error_intr_trig_r.error_internal_trig.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.error_intr_trig_r.error_internal_trig.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_intr_trig_r.error_internal_trig.load_next) begin + field_storage.intr_block_rf.error_intr_trig_r.error_internal_trig.value <= field_combo.intr_block_rf.error_intr_trig_r.error_internal_trig.next; + end + end + // Field: soc_ifc_reg.intr_block_rf.error_intr_trig_r.error_inv_dev_trig + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_intr_trig_r.error_inv_dev_trig.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_intr_trig_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write 1 set + next_c = field_storage.intr_block_rf.error_intr_trig_r.error_inv_dev_trig.value | (decoded_wr_data[1:1] & decoded_wr_biten[1:1]); + load_next_c = '1; + end else begin // singlepulse clears back to 0 + next_c = '0; + load_next_c = '1; + end + field_combo.intr_block_rf.error_intr_trig_r.error_inv_dev_trig.next = next_c; + field_combo.intr_block_rf.error_intr_trig_r.error_inv_dev_trig.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.error_intr_trig_r.error_inv_dev_trig.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_intr_trig_r.error_inv_dev_trig.load_next) begin + field_storage.intr_block_rf.error_intr_trig_r.error_inv_dev_trig.value <= field_combo.intr_block_rf.error_intr_trig_r.error_inv_dev_trig.next; + end + end + // Field: soc_ifc_reg.intr_block_rf.error_intr_trig_r.error_cmd_fail_trig + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_intr_trig_r.error_cmd_fail_trig.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_intr_trig_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write 1 set + next_c = field_storage.intr_block_rf.error_intr_trig_r.error_cmd_fail_trig.value | (decoded_wr_data[2:2] & decoded_wr_biten[2:2]); + load_next_c = '1; + end else begin // singlepulse clears back to 0 + next_c = '0; + load_next_c = '1; + end + field_combo.intr_block_rf.error_intr_trig_r.error_cmd_fail_trig.next = next_c; + field_combo.intr_block_rf.error_intr_trig_r.error_cmd_fail_trig.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.error_intr_trig_r.error_cmd_fail_trig.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_intr_trig_r.error_cmd_fail_trig.load_next) begin + field_storage.intr_block_rf.error_intr_trig_r.error_cmd_fail_trig.value <= field_combo.intr_block_rf.error_intr_trig_r.error_cmd_fail_trig.next; + end + end + // Field: soc_ifc_reg.intr_block_rf.error_intr_trig_r.error_bad_fuse_trig + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_intr_trig_r.error_bad_fuse_trig.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_intr_trig_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write 1 set + next_c = field_storage.intr_block_rf.error_intr_trig_r.error_bad_fuse_trig.value | (decoded_wr_data[3:3] & decoded_wr_biten[3:3]); + load_next_c = '1; + end else begin // singlepulse clears back to 0 + next_c = '0; + load_next_c = '1; + end + field_combo.intr_block_rf.error_intr_trig_r.error_bad_fuse_trig.next = next_c; + field_combo.intr_block_rf.error_intr_trig_r.error_bad_fuse_trig.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.error_intr_trig_r.error_bad_fuse_trig.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_intr_trig_r.error_bad_fuse_trig.load_next) begin + field_storage.intr_block_rf.error_intr_trig_r.error_bad_fuse_trig.value <= field_combo.intr_block_rf.error_intr_trig_r.error_bad_fuse_trig.next; + end + end + // Field: soc_ifc_reg.intr_block_rf.error_intr_trig_r.error_iccm_blocked_trig + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_intr_trig_r.error_iccm_blocked_trig.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_intr_trig_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write 1 set + next_c = field_storage.intr_block_rf.error_intr_trig_r.error_iccm_blocked_trig.value | (decoded_wr_data[4:4] & decoded_wr_biten[4:4]); + load_next_c = '1; + end else begin // singlepulse clears back to 0 + next_c = '0; + load_next_c = '1; + end + field_combo.intr_block_rf.error_intr_trig_r.error_iccm_blocked_trig.next = next_c; + field_combo.intr_block_rf.error_intr_trig_r.error_iccm_blocked_trig.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.error_intr_trig_r.error_iccm_blocked_trig.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_intr_trig_r.error_iccm_blocked_trig.load_next) begin + field_storage.intr_block_rf.error_intr_trig_r.error_iccm_blocked_trig.value <= field_combo.intr_block_rf.error_intr_trig_r.error_iccm_blocked_trig.next; + end + end + // Field: soc_ifc_reg.intr_block_rf.error_intr_trig_r.error_mbox_ecc_unc_trig + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_intr_trig_r.error_mbox_ecc_unc_trig.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_intr_trig_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write 1 set + next_c = field_storage.intr_block_rf.error_intr_trig_r.error_mbox_ecc_unc_trig.value | (decoded_wr_data[5:5] & decoded_wr_biten[5:5]); + load_next_c = '1; + end else begin // singlepulse clears back to 0 + next_c = '0; + load_next_c = '1; + end + field_combo.intr_block_rf.error_intr_trig_r.error_mbox_ecc_unc_trig.next = next_c; + field_combo.intr_block_rf.error_intr_trig_r.error_mbox_ecc_unc_trig.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.error_intr_trig_r.error_mbox_ecc_unc_trig.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_intr_trig_r.error_mbox_ecc_unc_trig.load_next) begin + field_storage.intr_block_rf.error_intr_trig_r.error_mbox_ecc_unc_trig.value <= field_combo.intr_block_rf.error_intr_trig_r.error_mbox_ecc_unc_trig.next; + end + end + // Field: soc_ifc_reg.intr_block_rf.error_intr_trig_r.error_wdt_timer1_timeout_trig + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_intr_trig_r.error_wdt_timer1_timeout_trig.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_intr_trig_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write 1 set + next_c = field_storage.intr_block_rf.error_intr_trig_r.error_wdt_timer1_timeout_trig.value | (decoded_wr_data[6:6] & decoded_wr_biten[6:6]); + load_next_c = '1; + end else begin // singlepulse clears back to 0 + next_c = '0; + load_next_c = '1; + end + field_combo.intr_block_rf.error_intr_trig_r.error_wdt_timer1_timeout_trig.next = next_c; + field_combo.intr_block_rf.error_intr_trig_r.error_wdt_timer1_timeout_trig.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.error_intr_trig_r.error_wdt_timer1_timeout_trig.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_intr_trig_r.error_wdt_timer1_timeout_trig.load_next) begin + field_storage.intr_block_rf.error_intr_trig_r.error_wdt_timer1_timeout_trig.value <= field_combo.intr_block_rf.error_intr_trig_r.error_wdt_timer1_timeout_trig.next; + end + end + // Field: soc_ifc_reg.intr_block_rf.error_intr_trig_r.error_wdt_timer2_timeout_trig + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_intr_trig_r.error_wdt_timer2_timeout_trig.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_intr_trig_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write 1 set + next_c = field_storage.intr_block_rf.error_intr_trig_r.error_wdt_timer2_timeout_trig.value | (decoded_wr_data[7:7] & decoded_wr_biten[7:7]); + load_next_c = '1; + end else begin // singlepulse clears back to 0 + next_c = '0; + load_next_c = '1; + end + field_combo.intr_block_rf.error_intr_trig_r.error_wdt_timer2_timeout_trig.next = next_c; + field_combo.intr_block_rf.error_intr_trig_r.error_wdt_timer2_timeout_trig.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.error_intr_trig_r.error_wdt_timer2_timeout_trig.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_intr_trig_r.error_wdt_timer2_timeout_trig.load_next) begin + field_storage.intr_block_rf.error_intr_trig_r.error_wdt_timer2_timeout_trig.value <= field_combo.intr_block_rf.error_intr_trig_r.error_wdt_timer2_timeout_trig.next; + end + end + // Field: soc_ifc_reg.intr_block_rf.notif_intr_trig_r.notif_cmd_avail_trig + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_intr_trig_r.notif_cmd_avail_trig.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.notif_intr_trig_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write 1 set + next_c = field_storage.intr_block_rf.notif_intr_trig_r.notif_cmd_avail_trig.value | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end else begin // singlepulse clears back to 0 + next_c = '0; + load_next_c = '1; + end + field_combo.intr_block_rf.notif_intr_trig_r.notif_cmd_avail_trig.next = next_c; + field_combo.intr_block_rf.notif_intr_trig_r.notif_cmd_avail_trig.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.notif_intr_trig_r.notif_cmd_avail_trig.value <= 1'h0; + end else if(field_combo.intr_block_rf.notif_intr_trig_r.notif_cmd_avail_trig.load_next) begin + field_storage.intr_block_rf.notif_intr_trig_r.notif_cmd_avail_trig.value <= field_combo.intr_block_rf.notif_intr_trig_r.notif_cmd_avail_trig.next; + end + end + // Field: soc_ifc_reg.intr_block_rf.notif_intr_trig_r.notif_mbox_ecc_cor_trig + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_intr_trig_r.notif_mbox_ecc_cor_trig.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.notif_intr_trig_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write 1 set + next_c = field_storage.intr_block_rf.notif_intr_trig_r.notif_mbox_ecc_cor_trig.value | (decoded_wr_data[1:1] & decoded_wr_biten[1:1]); + load_next_c = '1; + end else begin // singlepulse clears back to 0 + next_c = '0; + load_next_c = '1; + end + field_combo.intr_block_rf.notif_intr_trig_r.notif_mbox_ecc_cor_trig.next = next_c; + field_combo.intr_block_rf.notif_intr_trig_r.notif_mbox_ecc_cor_trig.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.notif_intr_trig_r.notif_mbox_ecc_cor_trig.value <= 1'h0; + end else if(field_combo.intr_block_rf.notif_intr_trig_r.notif_mbox_ecc_cor_trig.load_next) begin + field_storage.intr_block_rf.notif_intr_trig_r.notif_mbox_ecc_cor_trig.value <= field_combo.intr_block_rf.notif_intr_trig_r.notif_mbox_ecc_cor_trig.next; + end + end + // Field: soc_ifc_reg.intr_block_rf.notif_intr_trig_r.notif_debug_locked_trig + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_intr_trig_r.notif_debug_locked_trig.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.notif_intr_trig_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write 1 set + next_c = field_storage.intr_block_rf.notif_intr_trig_r.notif_debug_locked_trig.value | (decoded_wr_data[2:2] & decoded_wr_biten[2:2]); + load_next_c = '1; + end else begin // singlepulse clears back to 0 + next_c = '0; + load_next_c = '1; + end + field_combo.intr_block_rf.notif_intr_trig_r.notif_debug_locked_trig.next = next_c; + field_combo.intr_block_rf.notif_intr_trig_r.notif_debug_locked_trig.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.notif_intr_trig_r.notif_debug_locked_trig.value <= 1'h0; + end else if(field_combo.intr_block_rf.notif_intr_trig_r.notif_debug_locked_trig.load_next) begin + field_storage.intr_block_rf.notif_intr_trig_r.notif_debug_locked_trig.value <= field_combo.intr_block_rf.notif_intr_trig_r.notif_debug_locked_trig.next; + end + end + // Field: soc_ifc_reg.intr_block_rf.notif_intr_trig_r.notif_scan_mode_trig + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_intr_trig_r.notif_scan_mode_trig.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.notif_intr_trig_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write 1 set + next_c = field_storage.intr_block_rf.notif_intr_trig_r.notif_scan_mode_trig.value | (decoded_wr_data[3:3] & decoded_wr_biten[3:3]); + load_next_c = '1; + end else begin // singlepulse clears back to 0 + next_c = '0; + load_next_c = '1; + end + field_combo.intr_block_rf.notif_intr_trig_r.notif_scan_mode_trig.next = next_c; + field_combo.intr_block_rf.notif_intr_trig_r.notif_scan_mode_trig.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.notif_intr_trig_r.notif_scan_mode_trig.value <= 1'h0; + end else if(field_combo.intr_block_rf.notif_intr_trig_r.notif_scan_mode_trig.load_next) begin + field_storage.intr_block_rf.notif_intr_trig_r.notif_scan_mode_trig.value <= field_combo.intr_block_rf.notif_intr_trig_r.notif_scan_mode_trig.next; + end + end + // Field: soc_ifc_reg.intr_block_rf.notif_intr_trig_r.notif_soc_req_lock_trig + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_intr_trig_r.notif_soc_req_lock_trig.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.notif_intr_trig_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write 1 set + next_c = field_storage.intr_block_rf.notif_intr_trig_r.notif_soc_req_lock_trig.value | (decoded_wr_data[4:4] & decoded_wr_biten[4:4]); + load_next_c = '1; + end else begin // singlepulse clears back to 0 + next_c = '0; + load_next_c = '1; + end + field_combo.intr_block_rf.notif_intr_trig_r.notif_soc_req_lock_trig.next = next_c; + field_combo.intr_block_rf.notif_intr_trig_r.notif_soc_req_lock_trig.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.notif_intr_trig_r.notif_soc_req_lock_trig.value <= 1'h0; + end else if(field_combo.intr_block_rf.notif_intr_trig_r.notif_soc_req_lock_trig.load_next) begin + field_storage.intr_block_rf.notif_intr_trig_r.notif_soc_req_lock_trig.value <= field_combo.intr_block_rf.notif_intr_trig_r.notif_soc_req_lock_trig.next; + end + end + // Field: soc_ifc_reg.intr_block_rf.notif_intr_trig_r.notif_gen_in_toggle_trig + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_intr_trig_r.notif_gen_in_toggle_trig.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.notif_intr_trig_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write 1 set + next_c = field_storage.intr_block_rf.notif_intr_trig_r.notif_gen_in_toggle_trig.value | (decoded_wr_data[5:5] & decoded_wr_biten[5:5]); + load_next_c = '1; + end else begin // singlepulse clears back to 0 + next_c = '0; + load_next_c = '1; + end + field_combo.intr_block_rf.notif_intr_trig_r.notif_gen_in_toggle_trig.next = next_c; + field_combo.intr_block_rf.notif_intr_trig_r.notif_gen_in_toggle_trig.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.notif_intr_trig_r.notif_gen_in_toggle_trig.value <= 1'h0; + end else if(field_combo.intr_block_rf.notif_intr_trig_r.notif_gen_in_toggle_trig.load_next) begin + field_storage.intr_block_rf.notif_intr_trig_r.notif_gen_in_toggle_trig.value <= field_combo.intr_block_rf.notif_intr_trig_r.notif_gen_in_toggle_trig.next; + end + end + // Field: soc_ifc_reg.intr_block_rf.error_internal_intr_count_r.cnt + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_internal_intr_count_r.cnt.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_internal_intr_count_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.intr_block_rf.error_internal_intr_count_r.cnt.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + if(field_storage.intr_block_rf.error_internal_intr_count_incr_r.pulse.value) begin // increment + if(((33)'(next_c) + 32'h1) > 32'hffffffff) begin // up-counter saturated + next_c = 32'hffffffff; + end else begin + next_c = next_c + 32'h1; + end + load_next_c = '1; + end + field_combo.intr_block_rf.error_internal_intr_count_r.cnt.incrthreshold = (field_storage.intr_block_rf.error_internal_intr_count_r.cnt.value >= 32'hffffffff); + field_combo.intr_block_rf.error_internal_intr_count_r.cnt.incrsaturate = (field_storage.intr_block_rf.error_internal_intr_count_r.cnt.value >= 32'hffffffff); + if(next_c > 32'hffffffff) begin + next_c = 32'hffffffff; + load_next_c = '1; + end + field_combo.intr_block_rf.error_internal_intr_count_r.cnt.next = next_c; + field_combo.intr_block_rf.error_internal_intr_count_r.cnt.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.intr_block_rf.error_internal_intr_count_r.cnt.value <= 32'h0; + end else if(field_combo.intr_block_rf.error_internal_intr_count_r.cnt.load_next) begin + field_storage.intr_block_rf.error_internal_intr_count_r.cnt.value <= field_combo.intr_block_rf.error_internal_intr_count_r.cnt.next; + end + end + // Field: soc_ifc_reg.intr_block_rf.error_inv_dev_intr_count_r.cnt + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_inv_dev_intr_count_r.cnt.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_inv_dev_intr_count_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.intr_block_rf.error_inv_dev_intr_count_r.cnt.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + if(field_storage.intr_block_rf.error_inv_dev_intr_count_incr_r.pulse.value) begin // increment + if(((33)'(next_c) + 32'h1) > 32'hffffffff) begin // up-counter saturated + next_c = 32'hffffffff; + end else begin + next_c = next_c + 32'h1; + end + load_next_c = '1; + end + field_combo.intr_block_rf.error_inv_dev_intr_count_r.cnt.incrthreshold = (field_storage.intr_block_rf.error_inv_dev_intr_count_r.cnt.value >= 32'hffffffff); + field_combo.intr_block_rf.error_inv_dev_intr_count_r.cnt.incrsaturate = (field_storage.intr_block_rf.error_inv_dev_intr_count_r.cnt.value >= 32'hffffffff); + if(next_c > 32'hffffffff) begin + next_c = 32'hffffffff; + load_next_c = '1; + end + field_combo.intr_block_rf.error_inv_dev_intr_count_r.cnt.next = next_c; + field_combo.intr_block_rf.error_inv_dev_intr_count_r.cnt.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.intr_block_rf.error_inv_dev_intr_count_r.cnt.value <= 32'h0; + end else if(field_combo.intr_block_rf.error_inv_dev_intr_count_r.cnt.load_next) begin + field_storage.intr_block_rf.error_inv_dev_intr_count_r.cnt.value <= field_combo.intr_block_rf.error_inv_dev_intr_count_r.cnt.next; + end + end + // Field: soc_ifc_reg.intr_block_rf.error_cmd_fail_intr_count_r.cnt + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_cmd_fail_intr_count_r.cnt.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_cmd_fail_intr_count_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.intr_block_rf.error_cmd_fail_intr_count_r.cnt.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + if(field_storage.intr_block_rf.error_cmd_fail_intr_count_incr_r.pulse.value) begin // increment + if(((33)'(next_c) + 32'h1) > 32'hffffffff) begin // up-counter saturated + next_c = 32'hffffffff; + end else begin + next_c = next_c + 32'h1; + end + load_next_c = '1; + end + field_combo.intr_block_rf.error_cmd_fail_intr_count_r.cnt.incrthreshold = (field_storage.intr_block_rf.error_cmd_fail_intr_count_r.cnt.value >= 32'hffffffff); + field_combo.intr_block_rf.error_cmd_fail_intr_count_r.cnt.incrsaturate = (field_storage.intr_block_rf.error_cmd_fail_intr_count_r.cnt.value >= 32'hffffffff); + if(next_c > 32'hffffffff) begin + next_c = 32'hffffffff; + load_next_c = '1; + end + field_combo.intr_block_rf.error_cmd_fail_intr_count_r.cnt.next = next_c; + field_combo.intr_block_rf.error_cmd_fail_intr_count_r.cnt.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.intr_block_rf.error_cmd_fail_intr_count_r.cnt.value <= 32'h0; + end else if(field_combo.intr_block_rf.error_cmd_fail_intr_count_r.cnt.load_next) begin + field_storage.intr_block_rf.error_cmd_fail_intr_count_r.cnt.value <= field_combo.intr_block_rf.error_cmd_fail_intr_count_r.cnt.next; + end + end + // Field: soc_ifc_reg.intr_block_rf.error_bad_fuse_intr_count_r.cnt + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_bad_fuse_intr_count_r.cnt.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_bad_fuse_intr_count_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.intr_block_rf.error_bad_fuse_intr_count_r.cnt.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + if(field_storage.intr_block_rf.error_bad_fuse_intr_count_incr_r.pulse.value) begin // increment + if(((33)'(next_c) + 32'h1) > 32'hffffffff) begin // up-counter saturated + next_c = 32'hffffffff; + end else begin + next_c = next_c + 32'h1; + end + load_next_c = '1; + end + field_combo.intr_block_rf.error_bad_fuse_intr_count_r.cnt.incrthreshold = (field_storage.intr_block_rf.error_bad_fuse_intr_count_r.cnt.value >= 32'hffffffff); + field_combo.intr_block_rf.error_bad_fuse_intr_count_r.cnt.incrsaturate = (field_storage.intr_block_rf.error_bad_fuse_intr_count_r.cnt.value >= 32'hffffffff); + if(next_c > 32'hffffffff) begin + next_c = 32'hffffffff; + load_next_c = '1; + end + field_combo.intr_block_rf.error_bad_fuse_intr_count_r.cnt.next = next_c; + field_combo.intr_block_rf.error_bad_fuse_intr_count_r.cnt.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.intr_block_rf.error_bad_fuse_intr_count_r.cnt.value <= 32'h0; + end else if(field_combo.intr_block_rf.error_bad_fuse_intr_count_r.cnt.load_next) begin + field_storage.intr_block_rf.error_bad_fuse_intr_count_r.cnt.value <= field_combo.intr_block_rf.error_bad_fuse_intr_count_r.cnt.next; + end + end + // Field: soc_ifc_reg.intr_block_rf.error_iccm_blocked_intr_count_r.cnt + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_iccm_blocked_intr_count_r.cnt.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_iccm_blocked_intr_count_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.intr_block_rf.error_iccm_blocked_intr_count_r.cnt.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + if(field_storage.intr_block_rf.error_iccm_blocked_intr_count_incr_r.pulse.value) begin // increment + if(((33)'(next_c) + 32'h1) > 32'hffffffff) begin // up-counter saturated + next_c = 32'hffffffff; + end else begin + next_c = next_c + 32'h1; + end + load_next_c = '1; + end + field_combo.intr_block_rf.error_iccm_blocked_intr_count_r.cnt.incrthreshold = (field_storage.intr_block_rf.error_iccm_blocked_intr_count_r.cnt.value >= 32'hffffffff); + field_combo.intr_block_rf.error_iccm_blocked_intr_count_r.cnt.incrsaturate = (field_storage.intr_block_rf.error_iccm_blocked_intr_count_r.cnt.value >= 32'hffffffff); + if(next_c > 32'hffffffff) begin + next_c = 32'hffffffff; + load_next_c = '1; + end + field_combo.intr_block_rf.error_iccm_blocked_intr_count_r.cnt.next = next_c; + field_combo.intr_block_rf.error_iccm_blocked_intr_count_r.cnt.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.intr_block_rf.error_iccm_blocked_intr_count_r.cnt.value <= 32'h0; + end else if(field_combo.intr_block_rf.error_iccm_blocked_intr_count_r.cnt.load_next) begin + field_storage.intr_block_rf.error_iccm_blocked_intr_count_r.cnt.value <= field_combo.intr_block_rf.error_iccm_blocked_intr_count_r.cnt.next; + end + end + // Field: soc_ifc_reg.intr_block_rf.error_mbox_ecc_unc_intr_count_r.cnt + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_mbox_ecc_unc_intr_count_r.cnt.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_mbox_ecc_unc_intr_count_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.intr_block_rf.error_mbox_ecc_unc_intr_count_r.cnt.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + if(field_storage.intr_block_rf.error_mbox_ecc_unc_intr_count_incr_r.pulse.value) begin // increment + if(((33)'(next_c) + 32'h1) > 32'hffffffff) begin // up-counter saturated + next_c = 32'hffffffff; + end else begin + next_c = next_c + 32'h1; + end + load_next_c = '1; + end + field_combo.intr_block_rf.error_mbox_ecc_unc_intr_count_r.cnt.incrthreshold = (field_storage.intr_block_rf.error_mbox_ecc_unc_intr_count_r.cnt.value >= 32'hffffffff); + field_combo.intr_block_rf.error_mbox_ecc_unc_intr_count_r.cnt.incrsaturate = (field_storage.intr_block_rf.error_mbox_ecc_unc_intr_count_r.cnt.value >= 32'hffffffff); + if(next_c > 32'hffffffff) begin + next_c = 32'hffffffff; + load_next_c = '1; + end + field_combo.intr_block_rf.error_mbox_ecc_unc_intr_count_r.cnt.next = next_c; + field_combo.intr_block_rf.error_mbox_ecc_unc_intr_count_r.cnt.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.intr_block_rf.error_mbox_ecc_unc_intr_count_r.cnt.value <= 32'h0; + end else if(field_combo.intr_block_rf.error_mbox_ecc_unc_intr_count_r.cnt.load_next) begin + field_storage.intr_block_rf.error_mbox_ecc_unc_intr_count_r.cnt.value <= field_combo.intr_block_rf.error_mbox_ecc_unc_intr_count_r.cnt.next; + end + end + // Field: soc_ifc_reg.intr_block_rf.error_wdt_timer1_timeout_intr_count_r.cnt + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_wdt_timer1_timeout_intr_count_r.cnt.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_wdt_timer1_timeout_intr_count_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.intr_block_rf.error_wdt_timer1_timeout_intr_count_r.cnt.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + if(field_storage.intr_block_rf.error_wdt_timer1_timeout_intr_count_incr_r.pulse.value) begin // increment + if(((33)'(next_c) + 32'h1) > 32'hffffffff) begin // up-counter saturated + next_c = 32'hffffffff; + end else begin + next_c = next_c + 32'h1; + end + load_next_c = '1; + end + field_combo.intr_block_rf.error_wdt_timer1_timeout_intr_count_r.cnt.incrthreshold = (field_storage.intr_block_rf.error_wdt_timer1_timeout_intr_count_r.cnt.value >= 32'hffffffff); + field_combo.intr_block_rf.error_wdt_timer1_timeout_intr_count_r.cnt.incrsaturate = (field_storage.intr_block_rf.error_wdt_timer1_timeout_intr_count_r.cnt.value >= 32'hffffffff); + if(next_c > 32'hffffffff) begin + next_c = 32'hffffffff; + load_next_c = '1; + end + field_combo.intr_block_rf.error_wdt_timer1_timeout_intr_count_r.cnt.next = next_c; + field_combo.intr_block_rf.error_wdt_timer1_timeout_intr_count_r.cnt.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.intr_block_rf.error_wdt_timer1_timeout_intr_count_r.cnt.value <= 32'h0; + end else if(field_combo.intr_block_rf.error_wdt_timer1_timeout_intr_count_r.cnt.load_next) begin + field_storage.intr_block_rf.error_wdt_timer1_timeout_intr_count_r.cnt.value <= field_combo.intr_block_rf.error_wdt_timer1_timeout_intr_count_r.cnt.next; + end + end + // Field: soc_ifc_reg.intr_block_rf.error_wdt_timer2_timeout_intr_count_r.cnt + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_wdt_timer2_timeout_intr_count_r.cnt.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.error_wdt_timer2_timeout_intr_count_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.intr_block_rf.error_wdt_timer2_timeout_intr_count_r.cnt.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + if(field_storage.intr_block_rf.error_wdt_timer2_timeout_intr_count_incr_r.pulse.value) begin // increment + if(((33)'(next_c) + 32'h1) > 32'hffffffff) begin // up-counter saturated + next_c = 32'hffffffff; + end else begin + next_c = next_c + 32'h1; + end + load_next_c = '1; + end + field_combo.intr_block_rf.error_wdt_timer2_timeout_intr_count_r.cnt.incrthreshold = (field_storage.intr_block_rf.error_wdt_timer2_timeout_intr_count_r.cnt.value >= 32'hffffffff); + field_combo.intr_block_rf.error_wdt_timer2_timeout_intr_count_r.cnt.incrsaturate = (field_storage.intr_block_rf.error_wdt_timer2_timeout_intr_count_r.cnt.value >= 32'hffffffff); + if(next_c > 32'hffffffff) begin + next_c = 32'hffffffff; + load_next_c = '1; + end + field_combo.intr_block_rf.error_wdt_timer2_timeout_intr_count_r.cnt.next = next_c; + field_combo.intr_block_rf.error_wdt_timer2_timeout_intr_count_r.cnt.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.intr_block_rf.error_wdt_timer2_timeout_intr_count_r.cnt.value <= 32'h0; + end else if(field_combo.intr_block_rf.error_wdt_timer2_timeout_intr_count_r.cnt.load_next) begin + field_storage.intr_block_rf.error_wdt_timer2_timeout_intr_count_r.cnt.value <= field_combo.intr_block_rf.error_wdt_timer2_timeout_intr_count_r.cnt.next; + end + end + // Field: soc_ifc_reg.intr_block_rf.notif_cmd_avail_intr_count_r.cnt + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_cmd_avail_intr_count_r.cnt.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.notif_cmd_avail_intr_count_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.intr_block_rf.notif_cmd_avail_intr_count_r.cnt.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + if(field_storage.intr_block_rf.notif_cmd_avail_intr_count_incr_r.pulse.value) begin // increment + if(((33)'(next_c) + 32'h1) > 32'hffffffff) begin // up-counter saturated + next_c = 32'hffffffff; + end else begin + next_c = next_c + 32'h1; + end + load_next_c = '1; + end + field_combo.intr_block_rf.notif_cmd_avail_intr_count_r.cnt.incrthreshold = (field_storage.intr_block_rf.notif_cmd_avail_intr_count_r.cnt.value >= 32'hffffffff); + field_combo.intr_block_rf.notif_cmd_avail_intr_count_r.cnt.incrsaturate = (field_storage.intr_block_rf.notif_cmd_avail_intr_count_r.cnt.value >= 32'hffffffff); + if(next_c > 32'hffffffff) begin + next_c = 32'hffffffff; + load_next_c = '1; + end + field_combo.intr_block_rf.notif_cmd_avail_intr_count_r.cnt.next = next_c; + field_combo.intr_block_rf.notif_cmd_avail_intr_count_r.cnt.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.notif_cmd_avail_intr_count_r.cnt.value <= 32'h0; + end else if(field_combo.intr_block_rf.notif_cmd_avail_intr_count_r.cnt.load_next) begin + field_storage.intr_block_rf.notif_cmd_avail_intr_count_r.cnt.value <= field_combo.intr_block_rf.notif_cmd_avail_intr_count_r.cnt.next; + end + end + // Field: soc_ifc_reg.intr_block_rf.notif_mbox_ecc_cor_intr_count_r.cnt + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_mbox_ecc_cor_intr_count_r.cnt.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.notif_mbox_ecc_cor_intr_count_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.intr_block_rf.notif_mbox_ecc_cor_intr_count_r.cnt.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + if(field_storage.intr_block_rf.notif_mbox_ecc_cor_intr_count_incr_r.pulse.value) begin // increment + if(((33)'(next_c) + 32'h1) > 32'hffffffff) begin // up-counter saturated + next_c = 32'hffffffff; + end else begin + next_c = next_c + 32'h1; + end + load_next_c = '1; + end + field_combo.intr_block_rf.notif_mbox_ecc_cor_intr_count_r.cnt.incrthreshold = (field_storage.intr_block_rf.notif_mbox_ecc_cor_intr_count_r.cnt.value >= 32'hffffffff); + field_combo.intr_block_rf.notif_mbox_ecc_cor_intr_count_r.cnt.incrsaturate = (field_storage.intr_block_rf.notif_mbox_ecc_cor_intr_count_r.cnt.value >= 32'hffffffff); + if(next_c > 32'hffffffff) begin + next_c = 32'hffffffff; + load_next_c = '1; + end + field_combo.intr_block_rf.notif_mbox_ecc_cor_intr_count_r.cnt.next = next_c; + field_combo.intr_block_rf.notif_mbox_ecc_cor_intr_count_r.cnt.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.notif_mbox_ecc_cor_intr_count_r.cnt.value <= 32'h0; + end else if(field_combo.intr_block_rf.notif_mbox_ecc_cor_intr_count_r.cnt.load_next) begin + field_storage.intr_block_rf.notif_mbox_ecc_cor_intr_count_r.cnt.value <= field_combo.intr_block_rf.notif_mbox_ecc_cor_intr_count_r.cnt.next; + end + end + // Field: soc_ifc_reg.intr_block_rf.notif_debug_locked_intr_count_r.cnt + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_debug_locked_intr_count_r.cnt.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.notif_debug_locked_intr_count_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.intr_block_rf.notif_debug_locked_intr_count_r.cnt.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + if(field_storage.intr_block_rf.notif_debug_locked_intr_count_incr_r.pulse.value) begin // increment + if(((33)'(next_c) + 32'h1) > 32'hffffffff) begin // up-counter saturated + next_c = 32'hffffffff; + end else begin + next_c = next_c + 32'h1; + end + load_next_c = '1; + end + field_combo.intr_block_rf.notif_debug_locked_intr_count_r.cnt.incrthreshold = (field_storage.intr_block_rf.notif_debug_locked_intr_count_r.cnt.value >= 32'hffffffff); + field_combo.intr_block_rf.notif_debug_locked_intr_count_r.cnt.incrsaturate = (field_storage.intr_block_rf.notif_debug_locked_intr_count_r.cnt.value >= 32'hffffffff); + if(next_c > 32'hffffffff) begin + next_c = 32'hffffffff; + load_next_c = '1; + end + field_combo.intr_block_rf.notif_debug_locked_intr_count_r.cnt.next = next_c; + field_combo.intr_block_rf.notif_debug_locked_intr_count_r.cnt.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.notif_debug_locked_intr_count_r.cnt.value <= 32'h0; + end else if(field_combo.intr_block_rf.notif_debug_locked_intr_count_r.cnt.load_next) begin + field_storage.intr_block_rf.notif_debug_locked_intr_count_r.cnt.value <= field_combo.intr_block_rf.notif_debug_locked_intr_count_r.cnt.next; + end + end + // Field: soc_ifc_reg.intr_block_rf.notif_scan_mode_intr_count_r.cnt + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_scan_mode_intr_count_r.cnt.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.notif_scan_mode_intr_count_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.intr_block_rf.notif_scan_mode_intr_count_r.cnt.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + if(field_storage.intr_block_rf.notif_scan_mode_intr_count_incr_r.pulse.value) begin // increment + if(((33)'(next_c) + 32'h1) > 32'hffffffff) begin // up-counter saturated + next_c = 32'hffffffff; + end else begin + next_c = next_c + 32'h1; + end + load_next_c = '1; + end + field_combo.intr_block_rf.notif_scan_mode_intr_count_r.cnt.incrthreshold = (field_storage.intr_block_rf.notif_scan_mode_intr_count_r.cnt.value >= 32'hffffffff); + field_combo.intr_block_rf.notif_scan_mode_intr_count_r.cnt.incrsaturate = (field_storage.intr_block_rf.notif_scan_mode_intr_count_r.cnt.value >= 32'hffffffff); + if(next_c > 32'hffffffff) begin + next_c = 32'hffffffff; + load_next_c = '1; + end + field_combo.intr_block_rf.notif_scan_mode_intr_count_r.cnt.next = next_c; + field_combo.intr_block_rf.notif_scan_mode_intr_count_r.cnt.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.notif_scan_mode_intr_count_r.cnt.value <= 32'h0; + end else if(field_combo.intr_block_rf.notif_scan_mode_intr_count_r.cnt.load_next) begin + field_storage.intr_block_rf.notif_scan_mode_intr_count_r.cnt.value <= field_combo.intr_block_rf.notif_scan_mode_intr_count_r.cnt.next; + end + end + // Field: soc_ifc_reg.intr_block_rf.notif_soc_req_lock_intr_count_r.cnt + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_soc_req_lock_intr_count_r.cnt.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.notif_soc_req_lock_intr_count_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.intr_block_rf.notif_soc_req_lock_intr_count_r.cnt.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + if(field_storage.intr_block_rf.notif_soc_req_lock_intr_count_incr_r.pulse.value) begin // increment + if(((33)'(next_c) + 32'h1) > 32'hffffffff) begin // up-counter saturated + next_c = 32'hffffffff; + end else begin + next_c = next_c + 32'h1; + end + load_next_c = '1; + end + field_combo.intr_block_rf.notif_soc_req_lock_intr_count_r.cnt.incrthreshold = (field_storage.intr_block_rf.notif_soc_req_lock_intr_count_r.cnt.value >= 32'hffffffff); + field_combo.intr_block_rf.notif_soc_req_lock_intr_count_r.cnt.incrsaturate = (field_storage.intr_block_rf.notif_soc_req_lock_intr_count_r.cnt.value >= 32'hffffffff); + if(next_c > 32'hffffffff) begin + next_c = 32'hffffffff; + load_next_c = '1; + end + field_combo.intr_block_rf.notif_soc_req_lock_intr_count_r.cnt.next = next_c; + field_combo.intr_block_rf.notif_soc_req_lock_intr_count_r.cnt.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.notif_soc_req_lock_intr_count_r.cnt.value <= 32'h0; + end else if(field_combo.intr_block_rf.notif_soc_req_lock_intr_count_r.cnt.load_next) begin + field_storage.intr_block_rf.notif_soc_req_lock_intr_count_r.cnt.value <= field_combo.intr_block_rf.notif_soc_req_lock_intr_count_r.cnt.next; + end + end + // Field: soc_ifc_reg.intr_block_rf.notif_gen_in_toggle_intr_count_r.cnt + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_gen_in_toggle_intr_count_r.cnt.value; + load_next_c = '0; + if(decoded_reg_strb.intr_block_rf.notif_gen_in_toggle_intr_count_r && decoded_req_is_wr && !(hwif_in.soc_req)) begin // SW write + next_c = (field_storage.intr_block_rf.notif_gen_in_toggle_intr_count_r.cnt.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + if(field_storage.intr_block_rf.notif_gen_in_toggle_intr_count_incr_r.pulse.value) begin // increment + if(((33)'(next_c) + 32'h1) > 32'hffffffff) begin // up-counter saturated + next_c = 32'hffffffff; + end else begin + next_c = next_c + 32'h1; + end + load_next_c = '1; + end + field_combo.intr_block_rf.notif_gen_in_toggle_intr_count_r.cnt.incrthreshold = (field_storage.intr_block_rf.notif_gen_in_toggle_intr_count_r.cnt.value >= 32'hffffffff); + field_combo.intr_block_rf.notif_gen_in_toggle_intr_count_r.cnt.incrsaturate = (field_storage.intr_block_rf.notif_gen_in_toggle_intr_count_r.cnt.value >= 32'hffffffff); + if(next_c > 32'hffffffff) begin + next_c = 32'hffffffff; + load_next_c = '1; + end + field_combo.intr_block_rf.notif_gen_in_toggle_intr_count_r.cnt.next = next_c; + field_combo.intr_block_rf.notif_gen_in_toggle_intr_count_r.cnt.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.notif_gen_in_toggle_intr_count_r.cnt.value <= 32'h0; + end else if(field_combo.intr_block_rf.notif_gen_in_toggle_intr_count_r.cnt.load_next) begin + field_storage.intr_block_rf.notif_gen_in_toggle_intr_count_r.cnt.value <= field_combo.intr_block_rf.notif_gen_in_toggle_intr_count_r.cnt.next; + end + end + // Field: soc_ifc_reg.intr_block_rf.error_internal_intr_count_incr_r.pulse + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_internal_intr_count_incr_r.pulse.value; + load_next_c = '0; + if(field_storage.intr_block_rf.error_intr_trig_r.error_internal_trig.value) begin // HW Write - we + next_c = field_storage.intr_block_rf.error_intr_trig_r.error_internal_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.error_internal_intr_r.error_internal_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end + if(field_storage.intr_block_rf.error_internal_intr_count_incr_r.pulse.value) begin // decrement + field_combo.intr_block_rf.error_internal_intr_count_incr_r.pulse.underflow = (next_c < (1'h1)); + next_c = next_c - 1'h1; + load_next_c = '1; + end else begin + field_combo.intr_block_rf.error_internal_intr_count_incr_r.pulse.underflow = '0; + end + field_combo.intr_block_rf.error_internal_intr_count_incr_r.pulse.decrthreshold = (field_storage.intr_block_rf.error_internal_intr_count_incr_r.pulse.value <= 1'd0); + field_combo.intr_block_rf.error_internal_intr_count_incr_r.pulse.next = next_c; + field_combo.intr_block_rf.error_internal_intr_count_incr_r.pulse.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.error_internal_intr_count_incr_r.pulse.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_internal_intr_count_incr_r.pulse.load_next) begin + field_storage.intr_block_rf.error_internal_intr_count_incr_r.pulse.value <= field_combo.intr_block_rf.error_internal_intr_count_incr_r.pulse.next; + end + end + // Field: soc_ifc_reg.intr_block_rf.error_inv_dev_intr_count_incr_r.pulse + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_inv_dev_intr_count_incr_r.pulse.value; + load_next_c = '0; + if(field_storage.intr_block_rf.error_intr_trig_r.error_inv_dev_trig.value) begin // HW Write - we + next_c = field_storage.intr_block_rf.error_intr_trig_r.error_inv_dev_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.error_internal_intr_r.error_inv_dev_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end + if(field_storage.intr_block_rf.error_inv_dev_intr_count_incr_r.pulse.value) begin // decrement + field_combo.intr_block_rf.error_inv_dev_intr_count_incr_r.pulse.underflow = (next_c < (1'h1)); + next_c = next_c - 1'h1; + load_next_c = '1; + end else begin + field_combo.intr_block_rf.error_inv_dev_intr_count_incr_r.pulse.underflow = '0; + end + field_combo.intr_block_rf.error_inv_dev_intr_count_incr_r.pulse.decrthreshold = (field_storage.intr_block_rf.error_inv_dev_intr_count_incr_r.pulse.value <= 1'd0); + field_combo.intr_block_rf.error_inv_dev_intr_count_incr_r.pulse.next = next_c; + field_combo.intr_block_rf.error_inv_dev_intr_count_incr_r.pulse.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.error_inv_dev_intr_count_incr_r.pulse.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_inv_dev_intr_count_incr_r.pulse.load_next) begin + field_storage.intr_block_rf.error_inv_dev_intr_count_incr_r.pulse.value <= field_combo.intr_block_rf.error_inv_dev_intr_count_incr_r.pulse.next; + end + end + // Field: soc_ifc_reg.intr_block_rf.error_cmd_fail_intr_count_incr_r.pulse + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_cmd_fail_intr_count_incr_r.pulse.value; + load_next_c = '0; + if(field_storage.intr_block_rf.error_intr_trig_r.error_cmd_fail_trig.value) begin // HW Write - we + next_c = field_storage.intr_block_rf.error_intr_trig_r.error_cmd_fail_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.error_internal_intr_r.error_cmd_fail_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end + if(field_storage.intr_block_rf.error_cmd_fail_intr_count_incr_r.pulse.value) begin // decrement + field_combo.intr_block_rf.error_cmd_fail_intr_count_incr_r.pulse.underflow = (next_c < (1'h1)); + next_c = next_c - 1'h1; + load_next_c = '1; + end else begin + field_combo.intr_block_rf.error_cmd_fail_intr_count_incr_r.pulse.underflow = '0; + end + field_combo.intr_block_rf.error_cmd_fail_intr_count_incr_r.pulse.decrthreshold = (field_storage.intr_block_rf.error_cmd_fail_intr_count_incr_r.pulse.value <= 1'd0); + field_combo.intr_block_rf.error_cmd_fail_intr_count_incr_r.pulse.next = next_c; + field_combo.intr_block_rf.error_cmd_fail_intr_count_incr_r.pulse.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.error_cmd_fail_intr_count_incr_r.pulse.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_cmd_fail_intr_count_incr_r.pulse.load_next) begin + field_storage.intr_block_rf.error_cmd_fail_intr_count_incr_r.pulse.value <= field_combo.intr_block_rf.error_cmd_fail_intr_count_incr_r.pulse.next; + end + end + // Field: soc_ifc_reg.intr_block_rf.error_bad_fuse_intr_count_incr_r.pulse + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_bad_fuse_intr_count_incr_r.pulse.value; + load_next_c = '0; + if(field_storage.intr_block_rf.error_intr_trig_r.error_bad_fuse_trig.value) begin // HW Write - we + next_c = field_storage.intr_block_rf.error_intr_trig_r.error_bad_fuse_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.error_internal_intr_r.error_bad_fuse_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end + if(field_storage.intr_block_rf.error_bad_fuse_intr_count_incr_r.pulse.value) begin // decrement + field_combo.intr_block_rf.error_bad_fuse_intr_count_incr_r.pulse.underflow = (next_c < (1'h1)); + next_c = next_c - 1'h1; + load_next_c = '1; + end else begin + field_combo.intr_block_rf.error_bad_fuse_intr_count_incr_r.pulse.underflow = '0; + end + field_combo.intr_block_rf.error_bad_fuse_intr_count_incr_r.pulse.decrthreshold = (field_storage.intr_block_rf.error_bad_fuse_intr_count_incr_r.pulse.value <= 1'd0); + field_combo.intr_block_rf.error_bad_fuse_intr_count_incr_r.pulse.next = next_c; + field_combo.intr_block_rf.error_bad_fuse_intr_count_incr_r.pulse.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.error_bad_fuse_intr_count_incr_r.pulse.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_bad_fuse_intr_count_incr_r.pulse.load_next) begin + field_storage.intr_block_rf.error_bad_fuse_intr_count_incr_r.pulse.value <= field_combo.intr_block_rf.error_bad_fuse_intr_count_incr_r.pulse.next; + end + end + // Field: soc_ifc_reg.intr_block_rf.error_iccm_blocked_intr_count_incr_r.pulse + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_iccm_blocked_intr_count_incr_r.pulse.value; + load_next_c = '0; + if(field_storage.intr_block_rf.error_intr_trig_r.error_iccm_blocked_trig.value) begin // HW Write - we + next_c = field_storage.intr_block_rf.error_intr_trig_r.error_iccm_blocked_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.error_internal_intr_r.error_iccm_blocked_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end + if(field_storage.intr_block_rf.error_iccm_blocked_intr_count_incr_r.pulse.value) begin // decrement + field_combo.intr_block_rf.error_iccm_blocked_intr_count_incr_r.pulse.underflow = (next_c < (1'h1)); + next_c = next_c - 1'h1; + load_next_c = '1; + end else begin + field_combo.intr_block_rf.error_iccm_blocked_intr_count_incr_r.pulse.underflow = '0; + end + field_combo.intr_block_rf.error_iccm_blocked_intr_count_incr_r.pulse.decrthreshold = (field_storage.intr_block_rf.error_iccm_blocked_intr_count_incr_r.pulse.value <= 1'd0); + field_combo.intr_block_rf.error_iccm_blocked_intr_count_incr_r.pulse.next = next_c; + field_combo.intr_block_rf.error_iccm_blocked_intr_count_incr_r.pulse.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.error_iccm_blocked_intr_count_incr_r.pulse.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_iccm_blocked_intr_count_incr_r.pulse.load_next) begin + field_storage.intr_block_rf.error_iccm_blocked_intr_count_incr_r.pulse.value <= field_combo.intr_block_rf.error_iccm_blocked_intr_count_incr_r.pulse.next; + end + end + // Field: soc_ifc_reg.intr_block_rf.error_mbox_ecc_unc_intr_count_incr_r.pulse + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_mbox_ecc_unc_intr_count_incr_r.pulse.value; + load_next_c = '0; + if(field_storage.intr_block_rf.error_intr_trig_r.error_mbox_ecc_unc_trig.value) begin // HW Write - we + next_c = field_storage.intr_block_rf.error_intr_trig_r.error_mbox_ecc_unc_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.error_internal_intr_r.error_mbox_ecc_unc_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end + if(field_storage.intr_block_rf.error_mbox_ecc_unc_intr_count_incr_r.pulse.value) begin // decrement + field_combo.intr_block_rf.error_mbox_ecc_unc_intr_count_incr_r.pulse.underflow = (next_c < (1'h1)); + next_c = next_c - 1'h1; + load_next_c = '1; + end else begin + field_combo.intr_block_rf.error_mbox_ecc_unc_intr_count_incr_r.pulse.underflow = '0; + end + field_combo.intr_block_rf.error_mbox_ecc_unc_intr_count_incr_r.pulse.decrthreshold = (field_storage.intr_block_rf.error_mbox_ecc_unc_intr_count_incr_r.pulse.value <= 1'd0); + field_combo.intr_block_rf.error_mbox_ecc_unc_intr_count_incr_r.pulse.next = next_c; + field_combo.intr_block_rf.error_mbox_ecc_unc_intr_count_incr_r.pulse.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.error_mbox_ecc_unc_intr_count_incr_r.pulse.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_mbox_ecc_unc_intr_count_incr_r.pulse.load_next) begin + field_storage.intr_block_rf.error_mbox_ecc_unc_intr_count_incr_r.pulse.value <= field_combo.intr_block_rf.error_mbox_ecc_unc_intr_count_incr_r.pulse.next; + end + end + // Field: soc_ifc_reg.intr_block_rf.error_wdt_timer1_timeout_intr_count_incr_r.pulse + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_wdt_timer1_timeout_intr_count_incr_r.pulse.value; + load_next_c = '0; + if(field_storage.intr_block_rf.error_intr_trig_r.error_wdt_timer1_timeout_trig.value) begin // HW Write - we + next_c = field_storage.intr_block_rf.error_intr_trig_r.error_wdt_timer1_timeout_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.error_internal_intr_r.error_wdt_timer1_timeout_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end + if(field_storage.intr_block_rf.error_wdt_timer1_timeout_intr_count_incr_r.pulse.value) begin // decrement + field_combo.intr_block_rf.error_wdt_timer1_timeout_intr_count_incr_r.pulse.underflow = (next_c < (1'h1)); + next_c = next_c - 1'h1; + load_next_c = '1; + end else begin + field_combo.intr_block_rf.error_wdt_timer1_timeout_intr_count_incr_r.pulse.underflow = '0; + end + field_combo.intr_block_rf.error_wdt_timer1_timeout_intr_count_incr_r.pulse.decrthreshold = (field_storage.intr_block_rf.error_wdt_timer1_timeout_intr_count_incr_r.pulse.value <= 1'd0); + field_combo.intr_block_rf.error_wdt_timer1_timeout_intr_count_incr_r.pulse.next = next_c; + field_combo.intr_block_rf.error_wdt_timer1_timeout_intr_count_incr_r.pulse.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.error_wdt_timer1_timeout_intr_count_incr_r.pulse.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_wdt_timer1_timeout_intr_count_incr_r.pulse.load_next) begin + field_storage.intr_block_rf.error_wdt_timer1_timeout_intr_count_incr_r.pulse.value <= field_combo.intr_block_rf.error_wdt_timer1_timeout_intr_count_incr_r.pulse.next; + end + end + // Field: soc_ifc_reg.intr_block_rf.error_wdt_timer2_timeout_intr_count_incr_r.pulse + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.error_wdt_timer2_timeout_intr_count_incr_r.pulse.value; + load_next_c = '0; + if(field_storage.intr_block_rf.error_intr_trig_r.error_wdt_timer2_timeout_trig.value) begin // HW Write - we + next_c = field_storage.intr_block_rf.error_intr_trig_r.error_wdt_timer2_timeout_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.error_internal_intr_r.error_wdt_timer2_timeout_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end + if(field_storage.intr_block_rf.error_wdt_timer2_timeout_intr_count_incr_r.pulse.value) begin // decrement + field_combo.intr_block_rf.error_wdt_timer2_timeout_intr_count_incr_r.pulse.underflow = (next_c < (1'h1)); + next_c = next_c - 1'h1; + load_next_c = '1; + end else begin + field_combo.intr_block_rf.error_wdt_timer2_timeout_intr_count_incr_r.pulse.underflow = '0; + end + field_combo.intr_block_rf.error_wdt_timer2_timeout_intr_count_incr_r.pulse.decrthreshold = (field_storage.intr_block_rf.error_wdt_timer2_timeout_intr_count_incr_r.pulse.value <= 1'd0); + field_combo.intr_block_rf.error_wdt_timer2_timeout_intr_count_incr_r.pulse.next = next_c; + field_combo.intr_block_rf.error_wdt_timer2_timeout_intr_count_incr_r.pulse.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.error_wdt_timer2_timeout_intr_count_incr_r.pulse.value <= 1'h0; + end else if(field_combo.intr_block_rf.error_wdt_timer2_timeout_intr_count_incr_r.pulse.load_next) begin + field_storage.intr_block_rf.error_wdt_timer2_timeout_intr_count_incr_r.pulse.value <= field_combo.intr_block_rf.error_wdt_timer2_timeout_intr_count_incr_r.pulse.next; + end + end + // Field: soc_ifc_reg.intr_block_rf.notif_cmd_avail_intr_count_incr_r.pulse + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_cmd_avail_intr_count_incr_r.pulse.value; + load_next_c = '0; + if(field_storage.intr_block_rf.notif_intr_trig_r.notif_cmd_avail_trig.value) begin // HW Write - we + next_c = field_storage.intr_block_rf.notif_intr_trig_r.notif_cmd_avail_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.notif_internal_intr_r.notif_cmd_avail_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end + if(field_storage.intr_block_rf.notif_cmd_avail_intr_count_incr_r.pulse.value) begin // decrement + field_combo.intr_block_rf.notif_cmd_avail_intr_count_incr_r.pulse.underflow = (next_c < (1'h1)); + next_c = next_c - 1'h1; + load_next_c = '1; + end else begin + field_combo.intr_block_rf.notif_cmd_avail_intr_count_incr_r.pulse.underflow = '0; + end + field_combo.intr_block_rf.notif_cmd_avail_intr_count_incr_r.pulse.decrthreshold = (field_storage.intr_block_rf.notif_cmd_avail_intr_count_incr_r.pulse.value <= 1'd0); + field_combo.intr_block_rf.notif_cmd_avail_intr_count_incr_r.pulse.next = next_c; + field_combo.intr_block_rf.notif_cmd_avail_intr_count_incr_r.pulse.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.notif_cmd_avail_intr_count_incr_r.pulse.value <= 1'h0; + end else if(field_combo.intr_block_rf.notif_cmd_avail_intr_count_incr_r.pulse.load_next) begin + field_storage.intr_block_rf.notif_cmd_avail_intr_count_incr_r.pulse.value <= field_combo.intr_block_rf.notif_cmd_avail_intr_count_incr_r.pulse.next; + end + end + // Field: soc_ifc_reg.intr_block_rf.notif_mbox_ecc_cor_intr_count_incr_r.pulse + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_mbox_ecc_cor_intr_count_incr_r.pulse.value; + load_next_c = '0; + if(field_storage.intr_block_rf.notif_intr_trig_r.notif_mbox_ecc_cor_trig.value) begin // HW Write - we + next_c = field_storage.intr_block_rf.notif_intr_trig_r.notif_mbox_ecc_cor_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.notif_internal_intr_r.notif_mbox_ecc_cor_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end + if(field_storage.intr_block_rf.notif_mbox_ecc_cor_intr_count_incr_r.pulse.value) begin // decrement + field_combo.intr_block_rf.notif_mbox_ecc_cor_intr_count_incr_r.pulse.underflow = (next_c < (1'h1)); + next_c = next_c - 1'h1; + load_next_c = '1; + end else begin + field_combo.intr_block_rf.notif_mbox_ecc_cor_intr_count_incr_r.pulse.underflow = '0; + end + field_combo.intr_block_rf.notif_mbox_ecc_cor_intr_count_incr_r.pulse.decrthreshold = (field_storage.intr_block_rf.notif_mbox_ecc_cor_intr_count_incr_r.pulse.value <= 1'd0); + field_combo.intr_block_rf.notif_mbox_ecc_cor_intr_count_incr_r.pulse.next = next_c; + field_combo.intr_block_rf.notif_mbox_ecc_cor_intr_count_incr_r.pulse.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.notif_mbox_ecc_cor_intr_count_incr_r.pulse.value <= 1'h0; + end else if(field_combo.intr_block_rf.notif_mbox_ecc_cor_intr_count_incr_r.pulse.load_next) begin + field_storage.intr_block_rf.notif_mbox_ecc_cor_intr_count_incr_r.pulse.value <= field_combo.intr_block_rf.notif_mbox_ecc_cor_intr_count_incr_r.pulse.next; + end + end + // Field: soc_ifc_reg.intr_block_rf.notif_debug_locked_intr_count_incr_r.pulse + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_debug_locked_intr_count_incr_r.pulse.value; + load_next_c = '0; + if(field_storage.intr_block_rf.notif_intr_trig_r.notif_debug_locked_trig.value) begin // HW Write - we + next_c = field_storage.intr_block_rf.notif_intr_trig_r.notif_debug_locked_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.notif_internal_intr_r.notif_debug_locked_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end + if(field_storage.intr_block_rf.notif_debug_locked_intr_count_incr_r.pulse.value) begin // decrement + field_combo.intr_block_rf.notif_debug_locked_intr_count_incr_r.pulse.underflow = (next_c < (1'h1)); + next_c = next_c - 1'h1; + load_next_c = '1; + end else begin + field_combo.intr_block_rf.notif_debug_locked_intr_count_incr_r.pulse.underflow = '0; + end + field_combo.intr_block_rf.notif_debug_locked_intr_count_incr_r.pulse.decrthreshold = (field_storage.intr_block_rf.notif_debug_locked_intr_count_incr_r.pulse.value <= 1'd0); + field_combo.intr_block_rf.notif_debug_locked_intr_count_incr_r.pulse.next = next_c; + field_combo.intr_block_rf.notif_debug_locked_intr_count_incr_r.pulse.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.notif_debug_locked_intr_count_incr_r.pulse.value <= 1'h0; + end else if(field_combo.intr_block_rf.notif_debug_locked_intr_count_incr_r.pulse.load_next) begin + field_storage.intr_block_rf.notif_debug_locked_intr_count_incr_r.pulse.value <= field_combo.intr_block_rf.notif_debug_locked_intr_count_incr_r.pulse.next; + end + end + // Field: soc_ifc_reg.intr_block_rf.notif_scan_mode_intr_count_incr_r.pulse + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_scan_mode_intr_count_incr_r.pulse.value; + load_next_c = '0; + if(field_storage.intr_block_rf.notif_intr_trig_r.notif_scan_mode_trig.value) begin // HW Write - we + next_c = field_storage.intr_block_rf.notif_intr_trig_r.notif_scan_mode_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.notif_internal_intr_r.notif_scan_mode_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end + if(field_storage.intr_block_rf.notif_scan_mode_intr_count_incr_r.pulse.value) begin // decrement + field_combo.intr_block_rf.notif_scan_mode_intr_count_incr_r.pulse.underflow = (next_c < (1'h1)); + next_c = next_c - 1'h1; + load_next_c = '1; + end else begin + field_combo.intr_block_rf.notif_scan_mode_intr_count_incr_r.pulse.underflow = '0; + end + field_combo.intr_block_rf.notif_scan_mode_intr_count_incr_r.pulse.decrthreshold = (field_storage.intr_block_rf.notif_scan_mode_intr_count_incr_r.pulse.value <= 1'd0); + field_combo.intr_block_rf.notif_scan_mode_intr_count_incr_r.pulse.next = next_c; + field_combo.intr_block_rf.notif_scan_mode_intr_count_incr_r.pulse.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.notif_scan_mode_intr_count_incr_r.pulse.value <= 1'h0; + end else if(field_combo.intr_block_rf.notif_scan_mode_intr_count_incr_r.pulse.load_next) begin + field_storage.intr_block_rf.notif_scan_mode_intr_count_incr_r.pulse.value <= field_combo.intr_block_rf.notif_scan_mode_intr_count_incr_r.pulse.next; + end + end + // Field: soc_ifc_reg.intr_block_rf.notif_soc_req_lock_intr_count_incr_r.pulse + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_soc_req_lock_intr_count_incr_r.pulse.value; + load_next_c = '0; + if(field_storage.intr_block_rf.notif_intr_trig_r.notif_soc_req_lock_trig.value) begin // HW Write - we + next_c = field_storage.intr_block_rf.notif_intr_trig_r.notif_soc_req_lock_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.notif_internal_intr_r.notif_soc_req_lock_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end + if(field_storage.intr_block_rf.notif_soc_req_lock_intr_count_incr_r.pulse.value) begin // decrement + field_combo.intr_block_rf.notif_soc_req_lock_intr_count_incr_r.pulse.underflow = (next_c < (1'h1)); + next_c = next_c - 1'h1; + load_next_c = '1; + end else begin + field_combo.intr_block_rf.notif_soc_req_lock_intr_count_incr_r.pulse.underflow = '0; + end + field_combo.intr_block_rf.notif_soc_req_lock_intr_count_incr_r.pulse.decrthreshold = (field_storage.intr_block_rf.notif_soc_req_lock_intr_count_incr_r.pulse.value <= 1'd0); + field_combo.intr_block_rf.notif_soc_req_lock_intr_count_incr_r.pulse.next = next_c; + field_combo.intr_block_rf.notif_soc_req_lock_intr_count_incr_r.pulse.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.notif_soc_req_lock_intr_count_incr_r.pulse.value <= 1'h0; + end else if(field_combo.intr_block_rf.notif_soc_req_lock_intr_count_incr_r.pulse.load_next) begin + field_storage.intr_block_rf.notif_soc_req_lock_intr_count_incr_r.pulse.value <= field_combo.intr_block_rf.notif_soc_req_lock_intr_count_incr_r.pulse.next; + end + end + // Field: soc_ifc_reg.intr_block_rf.notif_gen_in_toggle_intr_count_incr_r.pulse + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.intr_block_rf.notif_gen_in_toggle_intr_count_incr_r.pulse.value; + load_next_c = '0; + if(field_storage.intr_block_rf.notif_intr_trig_r.notif_gen_in_toggle_trig.value) begin // HW Write - we + next_c = field_storage.intr_block_rf.notif_intr_trig_r.notif_gen_in_toggle_trig.value; + load_next_c = '1; + end else if(hwif_in.intr_block_rf.notif_internal_intr_r.notif_gen_in_toggle_sts.hwset) begin // HW Set + next_c = '1; + load_next_c = '1; + end + if(field_storage.intr_block_rf.notif_gen_in_toggle_intr_count_incr_r.pulse.value) begin // decrement + field_combo.intr_block_rf.notif_gen_in_toggle_intr_count_incr_r.pulse.underflow = (next_c < (1'h1)); + next_c = next_c - 1'h1; + load_next_c = '1; + end else begin + field_combo.intr_block_rf.notif_gen_in_toggle_intr_count_incr_r.pulse.underflow = '0; + end + field_combo.intr_block_rf.notif_gen_in_toggle_intr_count_incr_r.pulse.decrthreshold = (field_storage.intr_block_rf.notif_gen_in_toggle_intr_count_incr_r.pulse.value <= 1'd0); + field_combo.intr_block_rf.notif_gen_in_toggle_intr_count_incr_r.pulse.next = next_c; + field_combo.intr_block_rf.notif_gen_in_toggle_intr_count_incr_r.pulse.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.intr_block_rf.notif_gen_in_toggle_intr_count_incr_r.pulse.value <= 1'h0; + end else if(field_combo.intr_block_rf.notif_gen_in_toggle_intr_count_incr_r.pulse.load_next) begin + field_storage.intr_block_rf.notif_gen_in_toggle_intr_count_incr_r.pulse.value <= field_combo.intr_block_rf.notif_gen_in_toggle_intr_count_incr_r.pulse.next; + end + end + + //-------------------------------------------------------------------------- + // Write response + //-------------------------------------------------------------------------- + assign cpuif_wr_ack = decoded_req & decoded_req_is_wr; + // Writes are always granted with no error response + assign cpuif_wr_err = '0; + + //-------------------------------------------------------------------------- + // Readback + //-------------------------------------------------------------------------- + + logic readback_err; + logic readback_done; + logic [31:0] readback_data; + + // Assign readback values to a flattened array + logic [251-1:0][31:0] readback_array; + assign readback_array[0][0:0] = (decoded_reg_strb.CPTRA_HW_ERROR_FATAL && !decoded_req_is_wr) ? field_storage.CPTRA_HW_ERROR_FATAL.iccm_ecc_unc.value : '0; + assign readback_array[0][1:1] = (decoded_reg_strb.CPTRA_HW_ERROR_FATAL && !decoded_req_is_wr) ? field_storage.CPTRA_HW_ERROR_FATAL.dccm_ecc_unc.value : '0; + assign readback_array[0][2:2] = (decoded_reg_strb.CPTRA_HW_ERROR_FATAL && !decoded_req_is_wr) ? field_storage.CPTRA_HW_ERROR_FATAL.nmi_pin.value : '0; + assign readback_array[0][3:3] = (decoded_reg_strb.CPTRA_HW_ERROR_FATAL && !decoded_req_is_wr) ? field_storage.CPTRA_HW_ERROR_FATAL.crypto_err.value : '0; + assign readback_array[0][31:4] = (decoded_reg_strb.CPTRA_HW_ERROR_FATAL && !decoded_req_is_wr) ? hwif_in.CPTRA_HW_ERROR_FATAL.rsvd.next : '0; + assign readback_array[1][0:0] = (decoded_reg_strb.CPTRA_HW_ERROR_NON_FATAL && !decoded_req_is_wr) ? field_storage.CPTRA_HW_ERROR_NON_FATAL.mbox_prot_no_lock.value : '0; + assign readback_array[1][1:1] = (decoded_reg_strb.CPTRA_HW_ERROR_NON_FATAL && !decoded_req_is_wr) ? field_storage.CPTRA_HW_ERROR_NON_FATAL.mbox_prot_ooo.value : '0; + assign readback_array[1][2:2] = (decoded_reg_strb.CPTRA_HW_ERROR_NON_FATAL && !decoded_req_is_wr) ? field_storage.CPTRA_HW_ERROR_NON_FATAL.mbox_ecc_unc.value : '0; + assign readback_array[1][31:3] = (decoded_reg_strb.CPTRA_HW_ERROR_NON_FATAL && !decoded_req_is_wr) ? hwif_in.CPTRA_HW_ERROR_NON_FATAL.rsvd.next : '0; + assign readback_array[2][31:0] = (decoded_reg_strb.CPTRA_FW_ERROR_FATAL && !decoded_req_is_wr) ? field_storage.CPTRA_FW_ERROR_FATAL.error_code.value : '0; + assign readback_array[3][31:0] = (decoded_reg_strb.CPTRA_FW_ERROR_NON_FATAL && !decoded_req_is_wr) ? field_storage.CPTRA_FW_ERROR_NON_FATAL.error_code.value : '0; + assign readback_array[4][31:0] = (decoded_reg_strb.CPTRA_HW_ERROR_ENC && !decoded_req_is_wr) ? field_storage.CPTRA_HW_ERROR_ENC.error_code.value : '0; + assign readback_array[5][31:0] = (decoded_reg_strb.CPTRA_FW_ERROR_ENC && !decoded_req_is_wr) ? field_storage.CPTRA_FW_ERROR_ENC.error_code.value : '0; + for(genvar i0=0; i0<8; i0++) begin + assign readback_array[i0*1 + 6][31:0] = (decoded_reg_strb.CPTRA_FW_EXTENDED_ERROR_INFO[i0] && !decoded_req_is_wr) ? field_storage.CPTRA_FW_EXTENDED_ERROR_INFO[i0].error_info.value : '0; + end + assign readback_array[14][31:0] = (decoded_reg_strb.CPTRA_BOOT_STATUS && !decoded_req_is_wr) ? field_storage.CPTRA_BOOT_STATUS.status.value : '0; + assign readback_array[15][23:0] = (decoded_reg_strb.CPTRA_FLOW_STATUS && !decoded_req_is_wr) ? field_storage.CPTRA_FLOW_STATUS.status.value : '0; + assign readback_array[15][24:24] = (decoded_reg_strb.CPTRA_FLOW_STATUS && !decoded_req_is_wr) ? field_storage.CPTRA_FLOW_STATUS.idevid_csr_ready.value : '0; + assign readback_array[15][27:25] = (decoded_reg_strb.CPTRA_FLOW_STATUS && !decoded_req_is_wr) ? hwif_in.CPTRA_FLOW_STATUS.boot_fsm_ps.next : '0; + assign readback_array[15][28:28] = (decoded_reg_strb.CPTRA_FLOW_STATUS && !decoded_req_is_wr) ? field_storage.CPTRA_FLOW_STATUS.ready_for_mb_processing.value : '0; + assign readback_array[15][29:29] = (decoded_reg_strb.CPTRA_FLOW_STATUS && !decoded_req_is_wr) ? field_storage.CPTRA_FLOW_STATUS.ready_for_runtime.value : '0; + assign readback_array[15][30:30] = (decoded_reg_strb.CPTRA_FLOW_STATUS && !decoded_req_is_wr) ? hwif_in.CPTRA_FLOW_STATUS.ready_for_fuses.next : '0; + assign readback_array[15][31:31] = (decoded_reg_strb.CPTRA_FLOW_STATUS && !decoded_req_is_wr) ? field_storage.CPTRA_FLOW_STATUS.mailbox_flow_done.value : '0; + assign readback_array[16][0:0] = (decoded_reg_strb.CPTRA_RESET_REASON && !decoded_req_is_wr) ? field_storage.CPTRA_RESET_REASON.FW_UPD_RESET.value : '0; + assign readback_array[16][1:1] = (decoded_reg_strb.CPTRA_RESET_REASON && !decoded_req_is_wr) ? field_storage.CPTRA_RESET_REASON.WARM_RESET.value : '0; + assign readback_array[16][31:2] = '0; + assign readback_array[17][1:0] = (decoded_reg_strb.CPTRA_SECURITY_STATE && !decoded_req_is_wr) ? hwif_in.CPTRA_SECURITY_STATE.device_lifecycle.next : '0; + assign readback_array[17][2:2] = (decoded_reg_strb.CPTRA_SECURITY_STATE && !decoded_req_is_wr) ? hwif_in.CPTRA_SECURITY_STATE.debug_locked.next : '0; + assign readback_array[17][3:3] = (decoded_reg_strb.CPTRA_SECURITY_STATE && !decoded_req_is_wr) ? hwif_in.CPTRA_SECURITY_STATE.scan_mode.next : '0; + assign readback_array[17][31:4] = (decoded_reg_strb.CPTRA_SECURITY_STATE && !decoded_req_is_wr) ? 28'h0 : '0; + for(genvar i0=0; i0<5; i0++) begin + assign readback_array[i0*1 + 18][31:0] = (decoded_reg_strb.CPTRA_MBOX_VALID_AXI_USER[i0] && !decoded_req_is_wr) ? field_storage.CPTRA_MBOX_VALID_AXI_USER[i0].AXI_USER.value : '0; + end + for(genvar i0=0; i0<5; i0++) begin + assign readback_array[i0*1 + 23][0:0] = (decoded_reg_strb.CPTRA_MBOX_AXI_USER_LOCK[i0] && !decoded_req_is_wr) ? field_storage.CPTRA_MBOX_AXI_USER_LOCK[i0].LOCK.value : '0; + assign readback_array[i0*1 + 23][31:1] = '0; + end + assign readback_array[28][31:0] = (decoded_reg_strb.CPTRA_TRNG_VALID_AXI_USER && !decoded_req_is_wr) ? field_storage.CPTRA_TRNG_VALID_AXI_USER.AXI_USER.value : '0; + assign readback_array[29][0:0] = (decoded_reg_strb.CPTRA_TRNG_AXI_USER_LOCK && !decoded_req_is_wr) ? field_storage.CPTRA_TRNG_AXI_USER_LOCK.LOCK.value : '0; + assign readback_array[29][31:1] = '0; + for(genvar i0=0; i0<12; i0++) begin + assign readback_array[i0*1 + 30][31:0] = (decoded_reg_strb.CPTRA_TRNG_DATA[i0] && !decoded_req_is_wr) ? field_storage.CPTRA_TRNG_DATA[i0].DATA.value : '0; + end + assign readback_array[42][0:0] = (decoded_reg_strb.CPTRA_TRNG_CTRL && !decoded_req_is_wr) ? field_storage.CPTRA_TRNG_CTRL.clear.value : '0; + assign readback_array[42][31:1] = '0; + assign readback_array[43][0:0] = (decoded_reg_strb.CPTRA_TRNG_STATUS && !decoded_req_is_wr) ? field_storage.CPTRA_TRNG_STATUS.DATA_REQ.value : '0; + assign readback_array[43][1:1] = (decoded_reg_strb.CPTRA_TRNG_STATUS && !decoded_req_is_wr) ? field_storage.CPTRA_TRNG_STATUS.DATA_WR_DONE.value : '0; + assign readback_array[43][31:2] = '0; + assign readback_array[44][0:0] = (decoded_reg_strb.CPTRA_FUSE_WR_DONE && !decoded_req_is_wr) ? field_storage.CPTRA_FUSE_WR_DONE.done.value : '0; + assign readback_array[44][31:1] = '0; + assign readback_array[45][31:0] = (decoded_reg_strb.CPTRA_TIMER_CONFIG && !decoded_req_is_wr) ? field_storage.CPTRA_TIMER_CONFIG.clk_period.value : '0; + assign readback_array[46][0:0] = (decoded_reg_strb.CPTRA_BOOTFSM_GO && !decoded_req_is_wr) ? field_storage.CPTRA_BOOTFSM_GO.GO.value : '0; + assign readback_array[46][31:1] = '0; + assign readback_array[47][31:0] = (decoded_reg_strb.CPTRA_DBG_MANUF_SERVICE_REG && !decoded_req_is_wr) ? field_storage.CPTRA_DBG_MANUF_SERVICE_REG.DATA.value : '0; + assign readback_array[48][0:0] = (decoded_reg_strb.CPTRA_CLK_GATING_EN && !decoded_req_is_wr) ? field_storage.CPTRA_CLK_GATING_EN.clk_gating_en.value : '0; + assign readback_array[48][31:1] = '0; + for(genvar i0=0; i0<2; i0++) begin + assign readback_array[i0*1 + 49][31:0] = (decoded_reg_strb.CPTRA_GENERIC_INPUT_WIRES[i0] && !decoded_req_is_wr) ? field_storage.CPTRA_GENERIC_INPUT_WIRES[i0].generic_wires.value : '0; + end + for(genvar i0=0; i0<2; i0++) begin + assign readback_array[i0*1 + 51][31:0] = (decoded_reg_strb.CPTRA_GENERIC_OUTPUT_WIRES[i0] && !decoded_req_is_wr) ? field_storage.CPTRA_GENERIC_OUTPUT_WIRES[i0].generic_wires.value : '0; + end + assign readback_array[53][15:0] = (decoded_reg_strb.CPTRA_HW_REV_ID && !decoded_req_is_wr) ? 16'h12 : '0; + assign readback_array[53][31:16] = (decoded_reg_strb.CPTRA_HW_REV_ID && !decoded_req_is_wr) ? hwif_in.CPTRA_HW_REV_ID.SOC_STEPPING_ID.next : '0; + for(genvar i0=0; i0<2; i0++) begin + assign readback_array[i0*1 + 54][31:0] = (decoded_reg_strb.CPTRA_FW_REV_ID[i0] && !decoded_req_is_wr) ? field_storage.CPTRA_FW_REV_ID[i0].REV_ID.value : '0; + end + assign readback_array[56][0:0] = (decoded_reg_strb.CPTRA_HW_CONFIG && !decoded_req_is_wr) ? hwif_in.CPTRA_HW_CONFIG.iTRNG_en.next : '0; + assign readback_array[56][1:1] = (decoded_reg_strb.CPTRA_HW_CONFIG && !decoded_req_is_wr) ? hwif_in.CPTRA_HW_CONFIG.Fuse_Granularity.next : '0; + assign readback_array[56][3:2] = (decoded_reg_strb.CPTRA_HW_CONFIG && !decoded_req_is_wr) ? hwif_in.CPTRA_HW_CONFIG.RSVD_en.next : '0; + assign readback_array[56][4:4] = (decoded_reg_strb.CPTRA_HW_CONFIG && !decoded_req_is_wr) ? hwif_in.CPTRA_HW_CONFIG.LMS_acc_en.next : '0; + assign readback_array[56][5:5] = (decoded_reg_strb.CPTRA_HW_CONFIG && !decoded_req_is_wr) ? hwif_in.CPTRA_HW_CONFIG.SUBSYSTEM_MODE_en.next : '0; + assign readback_array[56][6:6] = (decoded_reg_strb.CPTRA_HW_CONFIG && !decoded_req_is_wr) ? hwif_in.CPTRA_HW_CONFIG.OCP_LOCK_MODE_en.next : '0; + assign readback_array[56][31:7] = '0; + assign readback_array[57][0:0] = (decoded_reg_strb.CPTRA_WDT_TIMER1_EN && !decoded_req_is_wr) ? field_storage.CPTRA_WDT_TIMER1_EN.timer1_en.value : '0; + assign readback_array[57][31:1] = '0; + assign readback_array[58][0:0] = (decoded_reg_strb.CPTRA_WDT_TIMER1_CTRL && !decoded_req_is_wr) ? field_storage.CPTRA_WDT_TIMER1_CTRL.timer1_restart.value : '0; + assign readback_array[58][31:1] = '0; + for(genvar i0=0; i0<2; i0++) begin + assign readback_array[i0*1 + 59][31:0] = (decoded_reg_strb.CPTRA_WDT_TIMER1_TIMEOUT_PERIOD[i0] && !decoded_req_is_wr) ? field_storage.CPTRA_WDT_TIMER1_TIMEOUT_PERIOD[i0].timer1_timeout_period.value : '0; + end + assign readback_array[61][0:0] = (decoded_reg_strb.CPTRA_WDT_TIMER2_EN && !decoded_req_is_wr) ? field_storage.CPTRA_WDT_TIMER2_EN.timer2_en.value : '0; + assign readback_array[61][31:1] = '0; + assign readback_array[62][0:0] = (decoded_reg_strb.CPTRA_WDT_TIMER2_CTRL && !decoded_req_is_wr) ? field_storage.CPTRA_WDT_TIMER2_CTRL.timer2_restart.value : '0; + assign readback_array[62][31:1] = '0; + for(genvar i0=0; i0<2; i0++) begin + assign readback_array[i0*1 + 63][31:0] = (decoded_reg_strb.CPTRA_WDT_TIMER2_TIMEOUT_PERIOD[i0] && !decoded_req_is_wr) ? field_storage.CPTRA_WDT_TIMER2_TIMEOUT_PERIOD[i0].timer2_timeout_period.value : '0; + end + assign readback_array[65][0:0] = (decoded_reg_strb.CPTRA_WDT_STATUS && !decoded_req_is_wr) ? field_storage.CPTRA_WDT_STATUS.t1_timeout.value : '0; + assign readback_array[65][1:1] = (decoded_reg_strb.CPTRA_WDT_STATUS && !decoded_req_is_wr) ? field_storage.CPTRA_WDT_STATUS.t2_timeout.value : '0; + assign readback_array[65][31:2] = '0; + assign readback_array[66][31:0] = (decoded_reg_strb.CPTRA_FUSE_VALID_AXI_USER && !decoded_req_is_wr) ? field_storage.CPTRA_FUSE_VALID_AXI_USER.AXI_USER.value : '0; + assign readback_array[67][0:0] = (decoded_reg_strb.CPTRA_FUSE_AXI_USER_LOCK && !decoded_req_is_wr) ? field_storage.CPTRA_FUSE_AXI_USER_LOCK.LOCK.value : '0; + assign readback_array[67][31:1] = '0; + for(genvar i0=0; i0<2; i0++) begin + assign readback_array[i0*1 + 68][31:0] = (decoded_reg_strb.CPTRA_WDT_CFG[i0] && !decoded_req_is_wr) ? field_storage.CPTRA_WDT_CFG[i0].TIMEOUT.value : '0; + end + assign readback_array[70][15:0] = (decoded_reg_strb.CPTRA_iTRNG_ENTROPY_CONFIG_0 && !decoded_req_is_wr) ? field_storage.CPTRA_iTRNG_ENTROPY_CONFIG_0.low_threshold.value : '0; + assign readback_array[70][31:16] = (decoded_reg_strb.CPTRA_iTRNG_ENTROPY_CONFIG_0 && !decoded_req_is_wr) ? field_storage.CPTRA_iTRNG_ENTROPY_CONFIG_0.high_threshold.value : '0; + assign readback_array[71][15:0] = (decoded_reg_strb.CPTRA_iTRNG_ENTROPY_CONFIG_1 && !decoded_req_is_wr) ? field_storage.CPTRA_iTRNG_ENTROPY_CONFIG_1.repetition_count.value : '0; + assign readback_array[71][31:16] = (decoded_reg_strb.CPTRA_iTRNG_ENTROPY_CONFIG_1 && !decoded_req_is_wr) ? field_storage.CPTRA_iTRNG_ENTROPY_CONFIG_1.RSVD.value : '0; + for(genvar i0=0; i0<2; i0++) begin + assign readback_array[i0*1 + 72][31:0] = (decoded_reg_strb.CPTRA_RSVD_REG[i0] && !decoded_req_is_wr) ? field_storage.CPTRA_RSVD_REG[i0].RSVD.value : '0; + end + assign readback_array[74][31:0] = (decoded_reg_strb.CPTRA_HW_CAPABILITIES && !decoded_req_is_wr) ? field_storage.CPTRA_HW_CAPABILITIES.cap.value : '0; + assign readback_array[75][31:0] = (decoded_reg_strb.CPTRA_FW_CAPABILITIES && !decoded_req_is_wr) ? field_storage.CPTRA_FW_CAPABILITIES.cap.value : '0; + assign readback_array[76][0:0] = (decoded_reg_strb.CPTRA_CAP_LOCK && !decoded_req_is_wr) ? field_storage.CPTRA_CAP_LOCK.lock.value : '0; + assign readback_array[76][31:1] = '0; + for(genvar i0=0; i0<12; i0++) begin + assign readback_array[i0*1 + 77][31:0] = (decoded_reg_strb.CPTRA_OWNER_PK_HASH[i0] && !decoded_req_is_wr) ? field_storage.CPTRA_OWNER_PK_HASH[i0].hash.value : '0; + end + assign readback_array[89][0:0] = (decoded_reg_strb.CPTRA_OWNER_PK_HASH_LOCK && !decoded_req_is_wr) ? field_storage.CPTRA_OWNER_PK_HASH_LOCK.lock.value : '0; + assign readback_array[89][31:1] = '0; + for(genvar i0=0; i0<12; i0++) begin + assign readback_array[i0*1 + 90][31:0] = (decoded_reg_strb.fuse_vendor_pk_hash[i0] && !decoded_req_is_wr) ? field_storage.fuse_vendor_pk_hash[i0].hash.value : '0; + end + assign readback_array[102][3:0] = (decoded_reg_strb.fuse_ecc_revocation && !decoded_req_is_wr) ? field_storage.fuse_ecc_revocation.ecc_revocation.value : '0; + assign readback_array[102][31:4] = '0; + assign readback_array[103][31:0] = (decoded_reg_strb.fuse_fmc_key_manifest_svn && !decoded_req_is_wr) ? field_storage.fuse_fmc_key_manifest_svn.svn.value : '0; + for(genvar i0=0; i0<4; i0++) begin + assign readback_array[i0*1 + 104][31:0] = (decoded_reg_strb.fuse_runtime_svn[i0] && !decoded_req_is_wr) ? field_storage.fuse_runtime_svn[i0].svn.value : '0; + end + assign readback_array[108][0:0] = (decoded_reg_strb.fuse_anti_rollback_disable && !decoded_req_is_wr) ? field_storage.fuse_anti_rollback_disable.dis.value : '0; + assign readback_array[108][31:1] = '0; + for(genvar i0=0; i0<24; i0++) begin + assign readback_array[i0*1 + 109][31:0] = (decoded_reg_strb.fuse_idevid_cert_attr[i0] && !decoded_req_is_wr) ? field_storage.fuse_idevid_cert_attr[i0].cert.value : '0; + end + for(genvar i0=0; i0<4; i0++) begin + assign readback_array[i0*1 + 133][31:0] = (decoded_reg_strb.fuse_idevid_manuf_hsm_id[i0] && !decoded_req_is_wr) ? field_storage.fuse_idevid_manuf_hsm_id[i0].hsm_id.value : '0; + end + assign readback_array[137][31:0] = (decoded_reg_strb.fuse_lms_revocation && !decoded_req_is_wr) ? field_storage.fuse_lms_revocation.lms_revocation.value : '0; + assign readback_array[138][3:0] = (decoded_reg_strb.fuse_mldsa_revocation && !decoded_req_is_wr) ? field_storage.fuse_mldsa_revocation.mldsa_revocation.value : '0; + assign readback_array[138][31:4] = '0; + assign readback_array[139][15:0] = (decoded_reg_strb.fuse_soc_stepping_id && !decoded_req_is_wr) ? field_storage.fuse_soc_stepping_id.soc_stepping_id.value : '0; + assign readback_array[139][31:16] = '0; + for(genvar i0=0; i0<16; i0++) begin + assign readback_array[i0*1 + 140][31:0] = (decoded_reg_strb.fuse_manuf_dbg_unlock_token[i0] && !decoded_req_is_wr) ? field_storage.fuse_manuf_dbg_unlock_token[i0].token.value : '0; + end + assign readback_array[156][1:0] = (decoded_reg_strb.fuse_pqc_key_type && !decoded_req_is_wr) ? field_storage.fuse_pqc_key_type.key_type.value : '0; + assign readback_array[156][31:2] = '0; + for(genvar i0=0; i0<4; i0++) begin + assign readback_array[i0*1 + 157][31:0] = (decoded_reg_strb.fuse_soc_manifest_svn[i0] && !decoded_req_is_wr) ? field_storage.fuse_soc_manifest_svn[i0].svn.value : '0; + end + assign readback_array[161][7:0] = (decoded_reg_strb.fuse_soc_manifest_max_svn && !decoded_req_is_wr) ? field_storage.fuse_soc_manifest_max_svn.svn.value : '0; + assign readback_array[161][31:8] = '0; + for(genvar i0=0; i0<8; i0++) begin + assign readback_array[i0*1 + 162][31:0] = (decoded_reg_strb.fuse_hek_seed[i0] && !decoded_req_is_wr) ? field_storage.fuse_hek_seed[i0].seed.value : '0; + end + assign readback_array[170][31:0] = (decoded_reg_strb.SS_CALIPTRA_BASE_ADDR_L && !decoded_req_is_wr) ? field_storage.SS_CALIPTRA_BASE_ADDR_L.addr_l.value : '0; + assign readback_array[171][31:0] = (decoded_reg_strb.SS_CALIPTRA_BASE_ADDR_H && !decoded_req_is_wr) ? field_storage.SS_CALIPTRA_BASE_ADDR_H.addr_h.value : '0; + assign readback_array[172][31:0] = (decoded_reg_strb.SS_MCI_BASE_ADDR_L && !decoded_req_is_wr) ? field_storage.SS_MCI_BASE_ADDR_L.addr_l.value : '0; + assign readback_array[173][31:0] = (decoded_reg_strb.SS_MCI_BASE_ADDR_H && !decoded_req_is_wr) ? field_storage.SS_MCI_BASE_ADDR_H.addr_h.value : '0; + assign readback_array[174][31:0] = (decoded_reg_strb.SS_RECOVERY_IFC_BASE_ADDR_L && !decoded_req_is_wr) ? field_storage.SS_RECOVERY_IFC_BASE_ADDR_L.addr_l.value : '0; + assign readback_array[175][31:0] = (decoded_reg_strb.SS_RECOVERY_IFC_BASE_ADDR_H && !decoded_req_is_wr) ? field_storage.SS_RECOVERY_IFC_BASE_ADDR_H.addr_h.value : '0; + assign readback_array[176][31:0] = (decoded_reg_strb.SS_OTP_FC_BASE_ADDR_L && !decoded_req_is_wr) ? field_storage.SS_OTP_FC_BASE_ADDR_L.addr_l.value : '0; + assign readback_array[177][31:0] = (decoded_reg_strb.SS_OTP_FC_BASE_ADDR_H && !decoded_req_is_wr) ? field_storage.SS_OTP_FC_BASE_ADDR_H.addr_h.value : '0; + assign readback_array[178][31:0] = (decoded_reg_strb.SS_UDS_SEED_BASE_ADDR_L && !decoded_req_is_wr) ? field_storage.SS_UDS_SEED_BASE_ADDR_L.addr_l.value : '0; + assign readback_array[179][31:0] = (decoded_reg_strb.SS_UDS_SEED_BASE_ADDR_H && !decoded_req_is_wr) ? field_storage.SS_UDS_SEED_BASE_ADDR_H.addr_h.value : '0; + assign readback_array[180][31:0] = (decoded_reg_strb.SS_PROD_DEBUG_UNLOCK_AUTH_PK_HASH_REG_BANK_OFFSET && !decoded_req_is_wr) ? field_storage.SS_PROD_DEBUG_UNLOCK_AUTH_PK_HASH_REG_BANK_OFFSET.offset.value : '0; + assign readback_array[181][31:0] = (decoded_reg_strb.SS_NUM_OF_PROD_DEBUG_UNLOCK_AUTH_PK_HASHES && !decoded_req_is_wr) ? field_storage.SS_NUM_OF_PROD_DEBUG_UNLOCK_AUTH_PK_HASHES.num.value : '0; + assign readback_array[182][0:0] = (decoded_reg_strb.SS_DEBUG_INTENT && !decoded_req_is_wr) ? field_storage.SS_DEBUG_INTENT.debug_intent.value : '0; + assign readback_array[182][31:1] = '0; + assign readback_array[183][31:0] = (decoded_reg_strb.SS_CALIPTRA_DMA_AXI_USER && !decoded_req_is_wr) ? field_storage.SS_CALIPTRA_DMA_AXI_USER.user.value : '0; + assign readback_array[184][31:0] = (decoded_reg_strb.SS_EXTERNAL_STAGING_AREA_BASE_ADDR_L && !decoded_req_is_wr) ? field_storage.SS_EXTERNAL_STAGING_AREA_BASE_ADDR_L.addr_l.value : '0; + assign readback_array[185][31:0] = (decoded_reg_strb.SS_EXTERNAL_STAGING_AREA_BASE_ADDR_H && !decoded_req_is_wr) ? field_storage.SS_EXTERNAL_STAGING_AREA_BASE_ADDR_H.addr_h.value : '0; + assign readback_array[186][31:0] = (decoded_reg_strb.SS_KEY_RELEASE_BASE_ADDR_L && !decoded_req_is_wr) ? field_storage.SS_KEY_RELEASE_BASE_ADDR_L.addr_l.value : '0; + assign readback_array[187][31:0] = (decoded_reg_strb.SS_KEY_RELEASE_BASE_ADDR_H && !decoded_req_is_wr) ? field_storage.SS_KEY_RELEASE_BASE_ADDR_H.addr_h.value : '0; + assign readback_array[188][15:0] = (decoded_reg_strb.SS_KEY_RELEASE_SIZE && !decoded_req_is_wr) ? field_storage.SS_KEY_RELEASE_SIZE.size.value : '0; + assign readback_array[188][31:16] = '0; + assign readback_array[189][0:0] = (decoded_reg_strb.SS_OCP_LOCK_CTRL && !decoded_req_is_wr) ? field_storage.SS_OCP_LOCK_CTRL.LOCK_IN_PROGRESS.value : '0; + assign readback_array[189][31:1] = '0; + for(genvar i0=0; i0<4; i0++) begin + assign readback_array[i0*1 + 190][31:0] = (decoded_reg_strb.SS_STRAP_GENERIC[i0] && !decoded_req_is_wr) ? field_storage.SS_STRAP_GENERIC[i0].data.value : '0; + end + assign readback_array[194][0:0] = (decoded_reg_strb.SS_DBG_SERVICE_REG_REQ && !decoded_req_is_wr) ? field_storage.SS_DBG_SERVICE_REG_REQ.MANUF_DBG_UNLOCK_REQ.value : '0; + assign readback_array[194][1:1] = (decoded_reg_strb.SS_DBG_SERVICE_REG_REQ && !decoded_req_is_wr) ? field_storage.SS_DBG_SERVICE_REG_REQ.PROD_DBG_UNLOCK_REQ.value : '0; + assign readback_array[194][2:2] = (decoded_reg_strb.SS_DBG_SERVICE_REG_REQ && !decoded_req_is_wr) ? field_storage.SS_DBG_SERVICE_REG_REQ.UDS_PROGRAM_REQ.value : '0; + assign readback_array[194][31:3] = (decoded_reg_strb.SS_DBG_SERVICE_REG_REQ && !decoded_req_is_wr) ? hwif_in.SS_DBG_SERVICE_REG_REQ.RSVD.next : '0; + assign readback_array[195][0:0] = (decoded_reg_strb.SS_DBG_SERVICE_REG_RSP && !decoded_req_is_wr) ? field_storage.SS_DBG_SERVICE_REG_RSP.MANUF_DBG_UNLOCK_SUCCESS.value : '0; + assign readback_array[195][1:1] = (decoded_reg_strb.SS_DBG_SERVICE_REG_RSP && !decoded_req_is_wr) ? field_storage.SS_DBG_SERVICE_REG_RSP.MANUF_DBG_UNLOCK_FAIL.value : '0; + assign readback_array[195][2:2] = (decoded_reg_strb.SS_DBG_SERVICE_REG_RSP && !decoded_req_is_wr) ? field_storage.SS_DBG_SERVICE_REG_RSP.MANUF_DBG_UNLOCK_IN_PROGRESS.value : '0; + assign readback_array[195][3:3] = (decoded_reg_strb.SS_DBG_SERVICE_REG_RSP && !decoded_req_is_wr) ? field_storage.SS_DBG_SERVICE_REG_RSP.PROD_DBG_UNLOCK_SUCCESS.value : '0; + assign readback_array[195][4:4] = (decoded_reg_strb.SS_DBG_SERVICE_REG_RSP && !decoded_req_is_wr) ? field_storage.SS_DBG_SERVICE_REG_RSP.PROD_DBG_UNLOCK_FAIL.value : '0; + assign readback_array[195][5:5] = (decoded_reg_strb.SS_DBG_SERVICE_REG_RSP && !decoded_req_is_wr) ? field_storage.SS_DBG_SERVICE_REG_RSP.PROD_DBG_UNLOCK_IN_PROGRESS.value : '0; + assign readback_array[195][6:6] = (decoded_reg_strb.SS_DBG_SERVICE_REG_RSP && !decoded_req_is_wr) ? field_storage.SS_DBG_SERVICE_REG_RSP.UDS_PROGRAM_SUCCESS.value : '0; + assign readback_array[195][7:7] = (decoded_reg_strb.SS_DBG_SERVICE_REG_RSP && !decoded_req_is_wr) ? field_storage.SS_DBG_SERVICE_REG_RSP.UDS_PROGRAM_FAIL.value : '0; + assign readback_array[195][8:8] = (decoded_reg_strb.SS_DBG_SERVICE_REG_RSP && !decoded_req_is_wr) ? field_storage.SS_DBG_SERVICE_REG_RSP.UDS_PROGRAM_IN_PROGRESS.value : '0; + assign readback_array[195][9:9] = (decoded_reg_strb.SS_DBG_SERVICE_REG_RSP && !decoded_req_is_wr) ? field_storage.SS_DBG_SERVICE_REG_RSP.TAP_MAILBOX_AVAILABLE.value : '0; + assign readback_array[195][31:10] = (decoded_reg_strb.SS_DBG_SERVICE_REG_RSP && !decoded_req_is_wr) ? hwif_in.SS_DBG_SERVICE_REG_RSP.RSVD.next : '0; + for(genvar i0=0; i0<2; i0++) begin + assign readback_array[i0*1 + 196][31:0] = (decoded_reg_strb.SS_SOC_DBG_UNLOCK_LEVEL[i0] && !decoded_req_is_wr) ? field_storage.SS_SOC_DBG_UNLOCK_LEVEL[i0].LEVEL.value : '0; + end + for(genvar i0=0; i0<4; i0++) begin + assign readback_array[i0*1 + 198][31:0] = (decoded_reg_strb.SS_GENERIC_FW_EXEC_CTRL[i0] && !decoded_req_is_wr) ? field_storage.SS_GENERIC_FW_EXEC_CTRL[i0].go.value : '0; + end + assign readback_array[202][0:0] = (decoded_reg_strb.internal_iccm_lock && !decoded_req_is_wr) ? field_storage.internal_iccm_lock.lock.value : '0; + assign readback_array[202][31:1] = '0; + assign readback_array[203][0:0] = (decoded_reg_strb.internal_fw_update_reset && !decoded_req_is_wr) ? field_storage.internal_fw_update_reset.core_rst.value : '0; + assign readback_array[203][31:1] = '0; + assign readback_array[204][7:0] = (decoded_reg_strb.internal_fw_update_reset_wait_cycles && !decoded_req_is_wr) ? field_storage.internal_fw_update_reset_wait_cycles.wait_cycles.value : '0; + assign readback_array[204][31:8] = '0; + assign readback_array[205][31:0] = (decoded_reg_strb.internal_nmi_vector && !decoded_req_is_wr) ? field_storage.internal_nmi_vector.vec.value : '0; + assign readback_array[206][0:0] = (decoded_reg_strb.internal_hw_error_fatal_mask && !decoded_req_is_wr) ? field_storage.internal_hw_error_fatal_mask.mask_iccm_ecc_unc.value : '0; + assign readback_array[206][1:1] = (decoded_reg_strb.internal_hw_error_fatal_mask && !decoded_req_is_wr) ? field_storage.internal_hw_error_fatal_mask.mask_dccm_ecc_unc.value : '0; + assign readback_array[206][2:2] = (decoded_reg_strb.internal_hw_error_fatal_mask && !decoded_req_is_wr) ? field_storage.internal_hw_error_fatal_mask.mask_nmi_pin.value : '0; + assign readback_array[206][3:3] = (decoded_reg_strb.internal_hw_error_fatal_mask && !decoded_req_is_wr) ? 1'h0 : '0; + assign readback_array[206][31:4] = '0; + assign readback_array[207][0:0] = (decoded_reg_strb.internal_hw_error_non_fatal_mask && !decoded_req_is_wr) ? field_storage.internal_hw_error_non_fatal_mask.mask_mbox_prot_no_lock.value : '0; + assign readback_array[207][1:1] = (decoded_reg_strb.internal_hw_error_non_fatal_mask && !decoded_req_is_wr) ? field_storage.internal_hw_error_non_fatal_mask.mask_mbox_prot_ooo.value : '0; + assign readback_array[207][2:2] = (decoded_reg_strb.internal_hw_error_non_fatal_mask && !decoded_req_is_wr) ? field_storage.internal_hw_error_non_fatal_mask.mask_mbox_ecc_unc.value : '0; + assign readback_array[207][31:3] = '0; + assign readback_array[208][31:0] = (decoded_reg_strb.internal_fw_error_fatal_mask && !decoded_req_is_wr) ? field_storage.internal_fw_error_fatal_mask.mask.value : '0; + assign readback_array[209][31:0] = (decoded_reg_strb.internal_fw_error_non_fatal_mask && !decoded_req_is_wr) ? field_storage.internal_fw_error_non_fatal_mask.mask.value : '0; + assign readback_array[210][31:0] = (decoded_reg_strb.internal_rv_mtime_l && !decoded_req_is_wr) ? field_storage.internal_rv_mtime_l.count_l.value : '0; + assign readback_array[211][31:0] = (decoded_reg_strb.internal_rv_mtime_h && !decoded_req_is_wr) ? field_storage.internal_rv_mtime_h.count_h.value : '0; + assign readback_array[212][31:0] = (decoded_reg_strb.internal_rv_mtimecmp_l && !decoded_req_is_wr) ? field_storage.internal_rv_mtimecmp_l.compare_l.value : '0; + assign readback_array[213][31:0] = (decoded_reg_strb.internal_rv_mtimecmp_h && !decoded_req_is_wr) ? field_storage.internal_rv_mtimecmp_h.compare_h.value : '0; + assign readback_array[214][0:0] = (decoded_reg_strb.intr_block_rf.global_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.global_intr_en_r.error_en.value : '0; + assign readback_array[214][1:1] = (decoded_reg_strb.intr_block_rf.global_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.global_intr_en_r.notif_en.value : '0; + assign readback_array[214][31:2] = '0; + assign readback_array[215][0:0] = (decoded_reg_strb.intr_block_rf.error_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_en_r.error_internal_en.value : '0; + assign readback_array[215][1:1] = (decoded_reg_strb.intr_block_rf.error_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_en_r.error_inv_dev_en.value : '0; + assign readback_array[215][2:2] = (decoded_reg_strb.intr_block_rf.error_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_en_r.error_cmd_fail_en.value : '0; + assign readback_array[215][3:3] = (decoded_reg_strb.intr_block_rf.error_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_en_r.error_bad_fuse_en.value : '0; + assign readback_array[215][4:4] = (decoded_reg_strb.intr_block_rf.error_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_en_r.error_iccm_blocked_en.value : '0; + assign readback_array[215][5:5] = (decoded_reg_strb.intr_block_rf.error_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_en_r.error_mbox_ecc_unc_en.value : '0; + assign readback_array[215][6:6] = (decoded_reg_strb.intr_block_rf.error_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_en_r.error_wdt_timer1_timeout_en.value : '0; + assign readback_array[215][7:7] = (decoded_reg_strb.intr_block_rf.error_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_en_r.error_wdt_timer2_timeout_en.value : '0; + assign readback_array[215][31:8] = '0; + assign readback_array[216][0:0] = (decoded_reg_strb.intr_block_rf.notif_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_intr_en_r.notif_cmd_avail_en.value : '0; + assign readback_array[216][1:1] = (decoded_reg_strb.intr_block_rf.notif_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_intr_en_r.notif_mbox_ecc_cor_en.value : '0; + assign readback_array[216][2:2] = (decoded_reg_strb.intr_block_rf.notif_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_intr_en_r.notif_debug_locked_en.value : '0; + assign readback_array[216][3:3] = (decoded_reg_strb.intr_block_rf.notif_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_intr_en_r.notif_scan_mode_en.value : '0; + assign readback_array[216][4:4] = (decoded_reg_strb.intr_block_rf.notif_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_intr_en_r.notif_soc_req_lock_en.value : '0; + assign readback_array[216][5:5] = (decoded_reg_strb.intr_block_rf.notif_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_intr_en_r.notif_gen_in_toggle_en.value : '0; + assign readback_array[216][31:6] = '0; + assign readback_array[217][0:0] = (decoded_reg_strb.intr_block_rf.error_global_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_global_intr_r.agg_sts.value : '0; + assign readback_array[217][31:1] = '0; + assign readback_array[218][0:0] = (decoded_reg_strb.intr_block_rf.notif_global_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_global_intr_r.agg_sts.value : '0; + assign readback_array[218][31:1] = '0; + assign readback_array[219][0:0] = (decoded_reg_strb.intr_block_rf.error_internal_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_internal_intr_r.error_internal_sts.value : '0; + assign readback_array[219][1:1] = (decoded_reg_strb.intr_block_rf.error_internal_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_internal_intr_r.error_inv_dev_sts.value : '0; + assign readback_array[219][2:2] = (decoded_reg_strb.intr_block_rf.error_internal_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_internal_intr_r.error_cmd_fail_sts.value : '0; + assign readback_array[219][3:3] = (decoded_reg_strb.intr_block_rf.error_internal_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_internal_intr_r.error_bad_fuse_sts.value : '0; + assign readback_array[219][4:4] = (decoded_reg_strb.intr_block_rf.error_internal_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_internal_intr_r.error_iccm_blocked_sts.value : '0; + assign readback_array[219][5:5] = (decoded_reg_strb.intr_block_rf.error_internal_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_internal_intr_r.error_mbox_ecc_unc_sts.value : '0; + assign readback_array[219][6:6] = (decoded_reg_strb.intr_block_rf.error_internal_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_internal_intr_r.error_wdt_timer1_timeout_sts.value : '0; + assign readback_array[219][7:7] = (decoded_reg_strb.intr_block_rf.error_internal_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_internal_intr_r.error_wdt_timer2_timeout_sts.value : '0; + assign readback_array[219][31:8] = '0; + assign readback_array[220][0:0] = (decoded_reg_strb.intr_block_rf.notif_internal_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_internal_intr_r.notif_cmd_avail_sts.value : '0; + assign readback_array[220][1:1] = (decoded_reg_strb.intr_block_rf.notif_internal_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_internal_intr_r.notif_mbox_ecc_cor_sts.value : '0; + assign readback_array[220][2:2] = (decoded_reg_strb.intr_block_rf.notif_internal_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_internal_intr_r.notif_debug_locked_sts.value : '0; + assign readback_array[220][3:3] = (decoded_reg_strb.intr_block_rf.notif_internal_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_internal_intr_r.notif_scan_mode_sts.value : '0; + assign readback_array[220][4:4] = (decoded_reg_strb.intr_block_rf.notif_internal_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_internal_intr_r.notif_soc_req_lock_sts.value : '0; + assign readback_array[220][5:5] = (decoded_reg_strb.intr_block_rf.notif_internal_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_internal_intr_r.notif_gen_in_toggle_sts.value : '0; + assign readback_array[220][31:6] = '0; + assign readback_array[221][0:0] = (decoded_reg_strb.intr_block_rf.error_intr_trig_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_trig_r.error_internal_trig.value : '0; + assign readback_array[221][1:1] = (decoded_reg_strb.intr_block_rf.error_intr_trig_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_trig_r.error_inv_dev_trig.value : '0; + assign readback_array[221][2:2] = (decoded_reg_strb.intr_block_rf.error_intr_trig_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_trig_r.error_cmd_fail_trig.value : '0; + assign readback_array[221][3:3] = (decoded_reg_strb.intr_block_rf.error_intr_trig_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_trig_r.error_bad_fuse_trig.value : '0; + assign readback_array[221][4:4] = (decoded_reg_strb.intr_block_rf.error_intr_trig_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_trig_r.error_iccm_blocked_trig.value : '0; + assign readback_array[221][5:5] = (decoded_reg_strb.intr_block_rf.error_intr_trig_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_trig_r.error_mbox_ecc_unc_trig.value : '0; + assign readback_array[221][6:6] = (decoded_reg_strb.intr_block_rf.error_intr_trig_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_trig_r.error_wdt_timer1_timeout_trig.value : '0; + assign readback_array[221][7:7] = (decoded_reg_strb.intr_block_rf.error_intr_trig_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_trig_r.error_wdt_timer2_timeout_trig.value : '0; + assign readback_array[221][31:8] = '0; + assign readback_array[222][0:0] = (decoded_reg_strb.intr_block_rf.notif_intr_trig_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_intr_trig_r.notif_cmd_avail_trig.value : '0; + assign readback_array[222][1:1] = (decoded_reg_strb.intr_block_rf.notif_intr_trig_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_intr_trig_r.notif_mbox_ecc_cor_trig.value : '0; + assign readback_array[222][2:2] = (decoded_reg_strb.intr_block_rf.notif_intr_trig_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_intr_trig_r.notif_debug_locked_trig.value : '0; + assign readback_array[222][3:3] = (decoded_reg_strb.intr_block_rf.notif_intr_trig_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_intr_trig_r.notif_scan_mode_trig.value : '0; + assign readback_array[222][4:4] = (decoded_reg_strb.intr_block_rf.notif_intr_trig_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_intr_trig_r.notif_soc_req_lock_trig.value : '0; + assign readback_array[222][5:5] = (decoded_reg_strb.intr_block_rf.notif_intr_trig_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_intr_trig_r.notif_gen_in_toggle_trig.value : '0; + assign readback_array[222][31:6] = '0; + assign readback_array[223][31:0] = (decoded_reg_strb.intr_block_rf.error_internal_intr_count_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_internal_intr_count_r.cnt.value : '0; + assign readback_array[224][31:0] = (decoded_reg_strb.intr_block_rf.error_inv_dev_intr_count_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_inv_dev_intr_count_r.cnt.value : '0; + assign readback_array[225][31:0] = (decoded_reg_strb.intr_block_rf.error_cmd_fail_intr_count_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_cmd_fail_intr_count_r.cnt.value : '0; + assign readback_array[226][31:0] = (decoded_reg_strb.intr_block_rf.error_bad_fuse_intr_count_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_bad_fuse_intr_count_r.cnt.value : '0; + assign readback_array[227][31:0] = (decoded_reg_strb.intr_block_rf.error_iccm_blocked_intr_count_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_iccm_blocked_intr_count_r.cnt.value : '0; + assign readback_array[228][31:0] = (decoded_reg_strb.intr_block_rf.error_mbox_ecc_unc_intr_count_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_mbox_ecc_unc_intr_count_r.cnt.value : '0; + assign readback_array[229][31:0] = (decoded_reg_strb.intr_block_rf.error_wdt_timer1_timeout_intr_count_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_wdt_timer1_timeout_intr_count_r.cnt.value : '0; + assign readback_array[230][31:0] = (decoded_reg_strb.intr_block_rf.error_wdt_timer2_timeout_intr_count_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_wdt_timer2_timeout_intr_count_r.cnt.value : '0; + assign readback_array[231][31:0] = (decoded_reg_strb.intr_block_rf.notif_cmd_avail_intr_count_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_cmd_avail_intr_count_r.cnt.value : '0; + assign readback_array[232][31:0] = (decoded_reg_strb.intr_block_rf.notif_mbox_ecc_cor_intr_count_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_mbox_ecc_cor_intr_count_r.cnt.value : '0; + assign readback_array[233][31:0] = (decoded_reg_strb.intr_block_rf.notif_debug_locked_intr_count_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_debug_locked_intr_count_r.cnt.value : '0; + assign readback_array[234][31:0] = (decoded_reg_strb.intr_block_rf.notif_scan_mode_intr_count_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_scan_mode_intr_count_r.cnt.value : '0; + assign readback_array[235][31:0] = (decoded_reg_strb.intr_block_rf.notif_soc_req_lock_intr_count_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_soc_req_lock_intr_count_r.cnt.value : '0; + assign readback_array[236][31:0] = (decoded_reg_strb.intr_block_rf.notif_gen_in_toggle_intr_count_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_gen_in_toggle_intr_count_r.cnt.value : '0; + assign readback_array[237][0:0] = (decoded_reg_strb.intr_block_rf.error_internal_intr_count_incr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_internal_intr_count_incr_r.pulse.value : '0; + assign readback_array[237][31:1] = '0; + assign readback_array[238][0:0] = (decoded_reg_strb.intr_block_rf.error_inv_dev_intr_count_incr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_inv_dev_intr_count_incr_r.pulse.value : '0; + assign readback_array[238][31:1] = '0; + assign readback_array[239][0:0] = (decoded_reg_strb.intr_block_rf.error_cmd_fail_intr_count_incr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_cmd_fail_intr_count_incr_r.pulse.value : '0; + assign readback_array[239][31:1] = '0; + assign readback_array[240][0:0] = (decoded_reg_strb.intr_block_rf.error_bad_fuse_intr_count_incr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_bad_fuse_intr_count_incr_r.pulse.value : '0; + assign readback_array[240][31:1] = '0; + assign readback_array[241][0:0] = (decoded_reg_strb.intr_block_rf.error_iccm_blocked_intr_count_incr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_iccm_blocked_intr_count_incr_r.pulse.value : '0; + assign readback_array[241][31:1] = '0; + assign readback_array[242][0:0] = (decoded_reg_strb.intr_block_rf.error_mbox_ecc_unc_intr_count_incr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_mbox_ecc_unc_intr_count_incr_r.pulse.value : '0; + assign readback_array[242][31:1] = '0; + assign readback_array[243][0:0] = (decoded_reg_strb.intr_block_rf.error_wdt_timer1_timeout_intr_count_incr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_wdt_timer1_timeout_intr_count_incr_r.pulse.value : '0; + assign readback_array[243][31:1] = '0; + assign readback_array[244][0:0] = (decoded_reg_strb.intr_block_rf.error_wdt_timer2_timeout_intr_count_incr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_wdt_timer2_timeout_intr_count_incr_r.pulse.value : '0; + assign readback_array[244][31:1] = '0; + assign readback_array[245][0:0] = (decoded_reg_strb.intr_block_rf.notif_cmd_avail_intr_count_incr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_cmd_avail_intr_count_incr_r.pulse.value : '0; + assign readback_array[245][31:1] = '0; + assign readback_array[246][0:0] = (decoded_reg_strb.intr_block_rf.notif_mbox_ecc_cor_intr_count_incr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_mbox_ecc_cor_intr_count_incr_r.pulse.value : '0; + assign readback_array[246][31:1] = '0; + assign readback_array[247][0:0] = (decoded_reg_strb.intr_block_rf.notif_debug_locked_intr_count_incr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_debug_locked_intr_count_incr_r.pulse.value : '0; + assign readback_array[247][31:1] = '0; + assign readback_array[248][0:0] = (decoded_reg_strb.intr_block_rf.notif_scan_mode_intr_count_incr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_scan_mode_intr_count_incr_r.pulse.value : '0; + assign readback_array[248][31:1] = '0; + assign readback_array[249][0:0] = (decoded_reg_strb.intr_block_rf.notif_soc_req_lock_intr_count_incr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_soc_req_lock_intr_count_incr_r.pulse.value : '0; + assign readback_array[249][31:1] = '0; + assign readback_array[250][0:0] = (decoded_reg_strb.intr_block_rf.notif_gen_in_toggle_intr_count_incr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_gen_in_toggle_intr_count_incr_r.pulse.value : '0; + assign readback_array[250][31:1] = '0; + + // Reduce the array + always_comb begin + automatic logic [31:0] readback_data_var; + readback_done = decoded_req & ~decoded_req_is_wr; + readback_err = '0; + readback_data_var = '0; + for(int i=0; i<251; i++) readback_data_var |= readback_array[i]; + readback_data = readback_data_var; + end + + assign cpuif_rd_ack = readback_done; + assign cpuif_rd_data = readback_data; + assign cpuif_rd_err = readback_err; + +`CALIPTRA_ASSERT_KNOWN(ERR_HWIF_IN, hwif_in, clk, !hwif_in.cptra_pwrgood) + +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/soc_ifc_reg_pkg.sv b/designs/Caliptra/src/caliptra-rtl/soc_ifc_reg_pkg.sv new file mode 100644 index 0000000..c65ba80 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/soc_ifc_reg_pkg.sv @@ -0,0 +1,1609 @@ +// Generated by PeakRDL-regblock - A free and open-source SystemVerilog generator +// https://github.com/SystemRDL/PeakRDL-regblock + +package soc_ifc_reg_pkg; + + localparam SOC_IFC_REG_DATA_WIDTH = 32; + localparam SOC_IFC_REG_MIN_ADDR_WIDTH = 12; + + typedef struct packed{ + logic next; + logic we; + } soc_ifc_reg__rw_rw_sticky_hw__in_t; + + typedef struct packed{ + logic [27:0] next; + } soc_ifc_reg__CPTRA_HW_ERROR_FATAL__rsvd__in_t; + + typedef struct packed{ + soc_ifc_reg__rw_rw_sticky_hw__in_t iccm_ecc_unc; + soc_ifc_reg__rw_rw_sticky_hw__in_t dccm_ecc_unc; + soc_ifc_reg__rw_rw_sticky_hw__in_t nmi_pin; + soc_ifc_reg__rw_rw_sticky_hw__in_t crypto_err; + soc_ifc_reg__CPTRA_HW_ERROR_FATAL__rsvd__in_t rsvd; + } soc_ifc_reg__CPTRA_HW_ERROR_FATAL__in_t; + + typedef struct packed{ + logic [28:0] next; + } soc_ifc_reg__CPTRA_HW_ERROR_NON_FATAL__rsvd__in_t; + + typedef struct packed{ + soc_ifc_reg__rw_rw_sticky_hw__in_t mbox_prot_no_lock; + soc_ifc_reg__rw_rw_sticky_hw__in_t mbox_prot_ooo; + soc_ifc_reg__rw_rw_sticky_hw__in_t mbox_ecc_unc; + soc_ifc_reg__CPTRA_HW_ERROR_NON_FATAL__rsvd__in_t rsvd; + } soc_ifc_reg__CPTRA_HW_ERROR_NON_FATAL__in_t; + + typedef struct packed{ + logic [31:0] next; + logic we; + } soc_ifc_reg__rw_rw_sticky_w32__in_t; + + typedef struct packed{ + soc_ifc_reg__rw_rw_sticky_w32__in_t error_code; + } soc_ifc_reg__CPTRA_FW_ERROR_FATAL__in_t; + + typedef struct packed{ + soc_ifc_reg__rw_rw_sticky_w32__in_t error_code; + } soc_ifc_reg__CPTRA_FW_ERROR_NON_FATAL__in_t; + + typedef struct packed{ + logic [2:0] next; + } soc_ifc_reg__CPTRA_FLOW_STATUS__boot_fsm_ps__in_t; + + typedef struct packed{ + logic next; + } soc_ifc_reg__CPTRA_FLOW_STATUS__ready_for_fuses__in_t; + + typedef struct packed{ + soc_ifc_reg__CPTRA_FLOW_STATUS__boot_fsm_ps__in_t boot_fsm_ps; + soc_ifc_reg__CPTRA_FLOW_STATUS__ready_for_fuses__in_t ready_for_fuses; + } soc_ifc_reg__CPTRA_FLOW_STATUS__in_t; + + typedef struct packed{ + logic next; + logic we; + } soc_ifc_reg__CPTRA_RESET_REASON__FW_UPD_RESET__in_t; + + typedef struct packed{ + logic next; + } soc_ifc_reg__CPTRA_RESET_REASON__WARM_RESET__in_t; + + typedef struct packed{ + soc_ifc_reg__CPTRA_RESET_REASON__FW_UPD_RESET__in_t FW_UPD_RESET; + soc_ifc_reg__CPTRA_RESET_REASON__WARM_RESET__in_t WARM_RESET; + } soc_ifc_reg__CPTRA_RESET_REASON__in_t; + + typedef struct packed{ + logic [1:0] next; + } soc_ifc_reg__CPTRA_SECURITY_STATE__device_lifecycle__in_t; + + typedef struct packed{ + logic next; + } soc_ifc_reg__CPTRA_SECURITY_STATE__debug_locked__in_t; + + typedef struct packed{ + logic next; + } soc_ifc_reg__CPTRA_SECURITY_STATE__scan_mode__in_t; + + typedef struct packed{ + soc_ifc_reg__CPTRA_SECURITY_STATE__device_lifecycle__in_t device_lifecycle; + soc_ifc_reg__CPTRA_SECURITY_STATE__debug_locked__in_t debug_locked; + soc_ifc_reg__CPTRA_SECURITY_STATE__scan_mode__in_t scan_mode; + } soc_ifc_reg__CPTRA_SECURITY_STATE__in_t; + + typedef struct packed{ + logic swwel; + } soc_ifc_reg__CPTRA_MBOX_VALID_AXI_USER__AXI_USER__in_t; + + typedef struct packed{ + soc_ifc_reg__CPTRA_MBOX_VALID_AXI_USER__AXI_USER__in_t AXI_USER; + } soc_ifc_reg__CPTRA_MBOX_VALID_AXI_USER__in_t; + + typedef struct packed{ + logic swwel; + } soc_ifc_reg__CPTRA_MBOX_AXI_USER_LOCK__LOCK__in_t; + + typedef struct packed{ + soc_ifc_reg__CPTRA_MBOX_AXI_USER_LOCK__LOCK__in_t LOCK; + } soc_ifc_reg__CPTRA_MBOX_AXI_USER_LOCK__in_t; + + typedef struct packed{ + logic swwel; + } soc_ifc_reg__CPTRA_TRNG_VALID_AXI_USER__AXI_USER__in_t; + + typedef struct packed{ + soc_ifc_reg__CPTRA_TRNG_VALID_AXI_USER__AXI_USER__in_t AXI_USER; + } soc_ifc_reg__CPTRA_TRNG_VALID_AXI_USER__in_t; + + typedef struct packed{ + logic swwel; + } soc_ifc_reg__CPTRA_TRNG_AXI_USER_LOCK__LOCK__in_t; + + typedef struct packed{ + soc_ifc_reg__CPTRA_TRNG_AXI_USER_LOCK__LOCK__in_t LOCK; + } soc_ifc_reg__CPTRA_TRNG_AXI_USER_LOCK__in_t; + + typedef struct packed{ + logic swwe; + logic hwclr; + } soc_ifc_reg__CPTRA_TRNG_DATA__DATA__in_t; + + typedef struct packed{ + soc_ifc_reg__CPTRA_TRNG_DATA__DATA__in_t DATA; + } soc_ifc_reg__CPTRA_TRNG_DATA__in_t; + + typedef struct packed{ + logic swwe; + logic hwclr; + } soc_ifc_reg__CPTRA_TRNG_STATUS__DATA_WR_DONE__in_t; + + typedef struct packed{ + soc_ifc_reg__CPTRA_TRNG_STATUS__DATA_WR_DONE__in_t DATA_WR_DONE; + } soc_ifc_reg__CPTRA_TRNG_STATUS__in_t; + + typedef struct packed{ + logic swwe; + } soc_ifc_reg__CPTRA_FUSE_WR_DONE__done__in_t; + + typedef struct packed{ + soc_ifc_reg__CPTRA_FUSE_WR_DONE__done__in_t done; + } soc_ifc_reg__CPTRA_FUSE_WR_DONE__in_t; + + typedef struct packed{ + logic next; + logic we; + } soc_ifc_reg__CPTRA_BOOTFSM_GO__GO__in_t; + + typedef struct packed{ + soc_ifc_reg__CPTRA_BOOTFSM_GO__GO__in_t GO; + } soc_ifc_reg__CPTRA_BOOTFSM_GO__in_t; + + typedef struct packed{ + logic [31:0] next; + logic we; + } soc_ifc_reg__CPTRA_DBG_MANUF_SERVICE_REG__DATA__in_t; + + typedef struct packed{ + soc_ifc_reg__CPTRA_DBG_MANUF_SERVICE_REG__DATA__in_t DATA; + } soc_ifc_reg__CPTRA_DBG_MANUF_SERVICE_REG__in_t; + + typedef struct packed{ + logic [31:0] next; + } soc_ifc_reg__CPTRA_GENERIC_INPUT_WIRES__generic_wires__in_t; + + typedef struct packed{ + soc_ifc_reg__CPTRA_GENERIC_INPUT_WIRES__generic_wires__in_t generic_wires; + } soc_ifc_reg__CPTRA_GENERIC_INPUT_WIRES__in_t; + + typedef struct packed{ + logic [15:0] next; + } soc_ifc_reg__CPTRA_HW_REV_ID__SOC_STEPPING_ID__in_t; + + typedef struct packed{ + soc_ifc_reg__CPTRA_HW_REV_ID__SOC_STEPPING_ID__in_t SOC_STEPPING_ID; + } soc_ifc_reg__CPTRA_HW_REV_ID__in_t; + + typedef struct packed{ + logic next; + } soc_ifc_reg__CPTRA_HW_CONFIG__iTRNG_en__in_t; + + typedef struct packed{ + logic next; + } soc_ifc_reg__CPTRA_HW_CONFIG__Fuse_Granularity__in_t; + + typedef struct packed{ + logic [1:0] next; + } soc_ifc_reg__CPTRA_HW_CONFIG__RSVD_en__in_t; + + typedef struct packed{ + logic next; + } soc_ifc_reg__CPTRA_HW_CONFIG__LMS_acc_en__in_t; + + typedef struct packed{ + logic next; + } soc_ifc_reg__CPTRA_HW_CONFIG__SUBSYSTEM_MODE_en__in_t; + + typedef struct packed{ + logic next; + } soc_ifc_reg__CPTRA_HW_CONFIG__OCP_LOCK_MODE_en__in_t; + + typedef struct packed{ + soc_ifc_reg__CPTRA_HW_CONFIG__iTRNG_en__in_t iTRNG_en; + soc_ifc_reg__CPTRA_HW_CONFIG__Fuse_Granularity__in_t Fuse_Granularity; + soc_ifc_reg__CPTRA_HW_CONFIG__RSVD_en__in_t RSVD_en; + soc_ifc_reg__CPTRA_HW_CONFIG__LMS_acc_en__in_t LMS_acc_en; + soc_ifc_reg__CPTRA_HW_CONFIG__SUBSYSTEM_MODE_en__in_t SUBSYSTEM_MODE_en; + soc_ifc_reg__CPTRA_HW_CONFIG__OCP_LOCK_MODE_en__in_t OCP_LOCK_MODE_en; + } soc_ifc_reg__CPTRA_HW_CONFIG__in_t; + + typedef struct packed{ + logic next; + } soc_ifc_reg__CPTRA_WDT_STATUS__t1_timeout__in_t; + + typedef struct packed{ + logic next; + } soc_ifc_reg__CPTRA_WDT_STATUS__t2_timeout__in_t; + + typedef struct packed{ + soc_ifc_reg__CPTRA_WDT_STATUS__t1_timeout__in_t t1_timeout; + soc_ifc_reg__CPTRA_WDT_STATUS__t2_timeout__in_t t2_timeout; + } soc_ifc_reg__CPTRA_WDT_STATUS__in_t; + + typedef struct packed{ + logic swwel; + } soc_ifc_reg__CPTRA_FUSE_VALID_AXI_USER__AXI_USER__in_t; + + typedef struct packed{ + soc_ifc_reg__CPTRA_FUSE_VALID_AXI_USER__AXI_USER__in_t AXI_USER; + } soc_ifc_reg__CPTRA_FUSE_VALID_AXI_USER__in_t; + + typedef struct packed{ + logic swwel; + } soc_ifc_reg__CPTRA_FUSE_AXI_USER_LOCK__LOCK__in_t; + + typedef struct packed{ + soc_ifc_reg__CPTRA_FUSE_AXI_USER_LOCK__LOCK__in_t LOCK; + } soc_ifc_reg__CPTRA_FUSE_AXI_USER_LOCK__in_t; + + typedef struct packed{ + logic swwel; + } soc_ifc_reg__CPTRA_HW_CAPABILITIES__cap__in_t; + + typedef struct packed{ + soc_ifc_reg__CPTRA_HW_CAPABILITIES__cap__in_t cap; + } soc_ifc_reg__CPTRA_HW_CAPABILITIES__in_t; + + typedef struct packed{ + logic swwel; + } soc_ifc_reg__CPTRA_FW_CAPABILITIES__cap__in_t; + + typedef struct packed{ + soc_ifc_reg__CPTRA_FW_CAPABILITIES__cap__in_t cap; + } soc_ifc_reg__CPTRA_FW_CAPABILITIES__in_t; + + typedef struct packed{ + logic swwel; + } soc_ifc_reg__CPTRA_CAP_LOCK__lock__in_t; + + typedef struct packed{ + soc_ifc_reg__CPTRA_CAP_LOCK__lock__in_t lock; + } soc_ifc_reg__CPTRA_CAP_LOCK__in_t; + + typedef struct packed{ + logic swwel; + } soc_ifc_reg__CPTRA_OWNER_PK_HASH__hash__in_t; + + typedef struct packed{ + soc_ifc_reg__CPTRA_OWNER_PK_HASH__hash__in_t hash; + } soc_ifc_reg__CPTRA_OWNER_PK_HASH__in_t; + + typedef struct packed{ + logic swwe; + } soc_ifc_reg__CPTRA_OWNER_PK_HASH_LOCK__lock__in_t; + + typedef struct packed{ + soc_ifc_reg__CPTRA_OWNER_PK_HASH_LOCK__lock__in_t lock; + } soc_ifc_reg__CPTRA_OWNER_PK_HASH_LOCK__in_t; + + typedef struct packed{ + logic [31:0] next; + logic we; + logic swwel; + logic hwclr; + } soc_ifc_reg__secret_w32__in_t; + + typedef struct packed{ + soc_ifc_reg__secret_w32__in_t seed; + } soc_ifc_reg__fuse_uds_seed__in_t; + + typedef struct packed{ + soc_ifc_reg__secret_w32__in_t seed; + } soc_ifc_reg__fuse_field_entropy__in_t; + + typedef struct packed{ + logic swwel; + } soc_ifc_reg__Fuse_w32__in_t; + + typedef struct packed{ + soc_ifc_reg__Fuse_w32__in_t hash; + } soc_ifc_reg__fuse_vendor_pk_hash__in_t; + + typedef struct packed{ + logic swwel; + } soc_ifc_reg__Fuse_w4__in_t; + + typedef struct packed{ + soc_ifc_reg__Fuse_w4__in_t ecc_revocation; + } soc_ifc_reg__fuse_ecc_revocation__in_t; + + typedef struct packed{ + soc_ifc_reg__Fuse_w32__in_t svn; + } soc_ifc_reg__fuse_fmc_key_manifest_svn__in_t; + + typedef struct packed{ + soc_ifc_reg__Fuse_w32__in_t svn; + } soc_ifc_reg__fuse_runtime_svn__in_t; + + typedef struct packed{ + logic swwel; + } soc_ifc_reg__Fuse__in_t; + + typedef struct packed{ + soc_ifc_reg__Fuse__in_t dis; + } soc_ifc_reg__fuse_anti_rollback_disable__in_t; + + typedef struct packed{ + soc_ifc_reg__Fuse_w32__in_t cert; + } soc_ifc_reg__fuse_idevid_cert_attr__in_t; + + typedef struct packed{ + soc_ifc_reg__Fuse_w32__in_t hsm_id; + } soc_ifc_reg__fuse_idevid_manuf_hsm_id__in_t; + + typedef struct packed{ + soc_ifc_reg__Fuse_w32__in_t lms_revocation; + } soc_ifc_reg__fuse_lms_revocation__in_t; + + typedef struct packed{ + soc_ifc_reg__Fuse_w4__in_t mldsa_revocation; + } soc_ifc_reg__fuse_mldsa_revocation__in_t; + + typedef struct packed{ + logic swwel; + } soc_ifc_reg__Fuse_w16__in_t; + + typedef struct packed{ + soc_ifc_reg__Fuse_w16__in_t soc_stepping_id; + } soc_ifc_reg__fuse_soc_stepping_id__in_t; + + typedef struct packed{ + soc_ifc_reg__Fuse_w32__in_t token; + } soc_ifc_reg__fuse_manuf_dbg_unlock_token__in_t; + + typedef struct packed{ + logic swwel; + } soc_ifc_reg__Fuse_w2__in_t; + + typedef struct packed{ + soc_ifc_reg__Fuse_w2__in_t key_type; + } soc_ifc_reg__fuse_pqc_key_type__in_t; + + typedef struct packed{ + soc_ifc_reg__Fuse_w32__in_t svn; + } soc_ifc_reg__fuse_soc_manifest_svn__in_t; + + typedef struct packed{ + logic swwel; + } soc_ifc_reg__Fuse_w8__in_t; + + typedef struct packed{ + soc_ifc_reg__Fuse_w8__in_t svn; + } soc_ifc_reg__fuse_soc_manifest_max_svn__in_t; + + typedef struct packed{ + soc_ifc_reg__Fuse_w32__in_t seed; + } soc_ifc_reg__fuse_hek_seed__in_t; + + typedef struct packed{ + logic [31:0] next; + logic we; + logic swwel; + } soc_ifc_reg__strap_w32__in_t; + + typedef struct packed{ + soc_ifc_reg__strap_w32__in_t addr_l; + } soc_ifc_reg__SS_CALIPTRA_BASE_ADDR_L__in_t; + + typedef struct packed{ + soc_ifc_reg__strap_w32__in_t addr_h; + } soc_ifc_reg__SS_CALIPTRA_BASE_ADDR_H__in_t; + + typedef struct packed{ + soc_ifc_reg__strap_w32__in_t addr_l; + } soc_ifc_reg__SS_MCI_BASE_ADDR_L__in_t; + + typedef struct packed{ + soc_ifc_reg__strap_w32__in_t addr_h; + } soc_ifc_reg__SS_MCI_BASE_ADDR_H__in_t; + + typedef struct packed{ + soc_ifc_reg__strap_w32__in_t addr_l; + } soc_ifc_reg__SS_RECOVERY_IFC_BASE_ADDR_L__in_t; + + typedef struct packed{ + soc_ifc_reg__strap_w32__in_t addr_h; + } soc_ifc_reg__SS_RECOVERY_IFC_BASE_ADDR_H__in_t; + + typedef struct packed{ + soc_ifc_reg__strap_w32__in_t addr_l; + } soc_ifc_reg__SS_OTP_FC_BASE_ADDR_L__in_t; + + typedef struct packed{ + soc_ifc_reg__strap_w32__in_t addr_h; + } soc_ifc_reg__SS_OTP_FC_BASE_ADDR_H__in_t; + + typedef struct packed{ + soc_ifc_reg__strap_w32__in_t addr_l; + } soc_ifc_reg__SS_UDS_SEED_BASE_ADDR_L__in_t; + + typedef struct packed{ + soc_ifc_reg__strap_w32__in_t addr_h; + } soc_ifc_reg__SS_UDS_SEED_BASE_ADDR_H__in_t; + + typedef struct packed{ + soc_ifc_reg__strap_w32__in_t offset; + } soc_ifc_reg__SS_PROD_DEBUG_UNLOCK_AUTH_PK_HASH_REG_BANK_OFFSET__in_t; + + typedef struct packed{ + soc_ifc_reg__strap_w32__in_t num; + } soc_ifc_reg__SS_NUM_OF_PROD_DEBUG_UNLOCK_AUTH_PK_HASHES__in_t; + + typedef struct packed{ + logic next; + logic we; + } soc_ifc_reg__SS_DEBUG_INTENT__strap__in_t; + + typedef struct packed{ + soc_ifc_reg__SS_DEBUG_INTENT__strap__in_t debug_intent; + } soc_ifc_reg__SS_DEBUG_INTENT__in_t; + + typedef struct packed{ + soc_ifc_reg__strap_w32__in_t user; + } soc_ifc_reg__SS_CALIPTRA_DMA_AXI_USER__in_t; + + typedef struct packed{ + soc_ifc_reg__strap_w32__in_t addr_l; + } soc_ifc_reg__SS_EXTERNAL_STAGING_AREA_BASE_ADDR_L__in_t; + + typedef struct packed{ + soc_ifc_reg__strap_w32__in_t addr_h; + } soc_ifc_reg__SS_EXTERNAL_STAGING_AREA_BASE_ADDR_H__in_t; + + typedef struct packed{ + soc_ifc_reg__strap_w32__in_t addr_l; + } soc_ifc_reg__SS_KEY_RELEASE_BASE_ADDR_L__in_t; + + typedef struct packed{ + soc_ifc_reg__strap_w32__in_t addr_h; + } soc_ifc_reg__SS_KEY_RELEASE_BASE_ADDR_H__in_t; + + typedef struct packed{ + logic [15:0] next; + logic we; + logic swwel; + } soc_ifc_reg__strap_w16__in_t; + + typedef struct packed{ + soc_ifc_reg__strap_w16__in_t size; + } soc_ifc_reg__SS_KEY_RELEASE_SIZE__in_t; + + typedef struct packed{ + logic swwel; + } soc_ifc_reg__SS_OCP_LOCK_CTRL__LOCK_IN_PROGRESS__in_t; + + typedef struct packed{ + soc_ifc_reg__SS_OCP_LOCK_CTRL__LOCK_IN_PROGRESS__in_t LOCK_IN_PROGRESS; + } soc_ifc_reg__SS_OCP_LOCK_CTRL__in_t; + + typedef struct packed{ + soc_ifc_reg__strap_w32__in_t data; + } soc_ifc_reg__SS_STRAP_GENERIC__in_t; + + typedef struct packed{ + logic next; + logic we; + logic swwe; + } soc_ifc_reg__SS_DBG_SERVICE_REG_REQ__MANUF_DBG_UNLOCK_REQ__in_t; + + typedef struct packed{ + logic next; + logic we; + logic swwe; + } soc_ifc_reg__SS_DBG_SERVICE_REG_REQ__PROD_DBG_UNLOCK_REQ__in_t; + + typedef struct packed{ + logic next; + logic we; + logic swwe; + } soc_ifc_reg__SS_DBG_SERVICE_REG_REQ__UDS_PROGRAM_REQ__in_t; + + typedef struct packed{ + logic [28:0] next; + } soc_ifc_reg__SS_DBG_SERVICE_REG_REQ__RSVD__in_t; + + typedef struct packed{ + soc_ifc_reg__SS_DBG_SERVICE_REG_REQ__MANUF_DBG_UNLOCK_REQ__in_t MANUF_DBG_UNLOCK_REQ; + soc_ifc_reg__SS_DBG_SERVICE_REG_REQ__PROD_DBG_UNLOCK_REQ__in_t PROD_DBG_UNLOCK_REQ; + soc_ifc_reg__SS_DBG_SERVICE_REG_REQ__UDS_PROGRAM_REQ__in_t UDS_PROGRAM_REQ; + soc_ifc_reg__SS_DBG_SERVICE_REG_REQ__RSVD__in_t RSVD; + } soc_ifc_reg__SS_DBG_SERVICE_REG_REQ__in_t; + + typedef struct packed{ + logic swwe; + } soc_ifc_reg__SS_DBG_SERVICE_REG_RSP__MANUF_DBG_UNLOCK_SUCCESS__in_t; + + typedef struct packed{ + logic swwe; + } soc_ifc_reg__SS_DBG_SERVICE_REG_RSP__MANUF_DBG_UNLOCK_FAIL__in_t; + + typedef struct packed{ + logic swwe; + } soc_ifc_reg__SS_DBG_SERVICE_REG_RSP__MANUF_DBG_UNLOCK_IN_PROGRESS__in_t; + + typedef struct packed{ + logic swwe; + } soc_ifc_reg__SS_DBG_SERVICE_REG_RSP__PROD_DBG_UNLOCK_SUCCESS__in_t; + + typedef struct packed{ + logic swwe; + } soc_ifc_reg__SS_DBG_SERVICE_REG_RSP__PROD_DBG_UNLOCK_FAIL__in_t; + + typedef struct packed{ + logic swwe; + } soc_ifc_reg__SS_DBG_SERVICE_REG_RSP__PROD_DBG_UNLOCK_IN_PROGRESS__in_t; + + typedef struct packed{ + logic swwe; + } soc_ifc_reg__SS_DBG_SERVICE_REG_RSP__UDS_PROGRAM_SUCCESS__in_t; + + typedef struct packed{ + logic swwe; + } soc_ifc_reg__SS_DBG_SERVICE_REG_RSP__UDS_PROGRAM_FAIL__in_t; + + typedef struct packed{ + logic swwe; + } soc_ifc_reg__SS_DBG_SERVICE_REG_RSP__UDS_PROGRAM_IN_PROGRESS__in_t; + + typedef struct packed{ + logic swwe; + } soc_ifc_reg__SS_DBG_SERVICE_REG_RSP__TAP_MAILBOX_AVAILABLE__in_t; + + typedef struct packed{ + logic [21:0] next; + } soc_ifc_reg__SS_DBG_SERVICE_REG_RSP__RSVD__in_t; + + typedef struct packed{ + soc_ifc_reg__SS_DBG_SERVICE_REG_RSP__MANUF_DBG_UNLOCK_SUCCESS__in_t MANUF_DBG_UNLOCK_SUCCESS; + soc_ifc_reg__SS_DBG_SERVICE_REG_RSP__MANUF_DBG_UNLOCK_FAIL__in_t MANUF_DBG_UNLOCK_FAIL; + soc_ifc_reg__SS_DBG_SERVICE_REG_RSP__MANUF_DBG_UNLOCK_IN_PROGRESS__in_t MANUF_DBG_UNLOCK_IN_PROGRESS; + soc_ifc_reg__SS_DBG_SERVICE_REG_RSP__PROD_DBG_UNLOCK_SUCCESS__in_t PROD_DBG_UNLOCK_SUCCESS; + soc_ifc_reg__SS_DBG_SERVICE_REG_RSP__PROD_DBG_UNLOCK_FAIL__in_t PROD_DBG_UNLOCK_FAIL; + soc_ifc_reg__SS_DBG_SERVICE_REG_RSP__PROD_DBG_UNLOCK_IN_PROGRESS__in_t PROD_DBG_UNLOCK_IN_PROGRESS; + soc_ifc_reg__SS_DBG_SERVICE_REG_RSP__UDS_PROGRAM_SUCCESS__in_t UDS_PROGRAM_SUCCESS; + soc_ifc_reg__SS_DBG_SERVICE_REG_RSP__UDS_PROGRAM_FAIL__in_t UDS_PROGRAM_FAIL; + soc_ifc_reg__SS_DBG_SERVICE_REG_RSP__UDS_PROGRAM_IN_PROGRESS__in_t UDS_PROGRAM_IN_PROGRESS; + soc_ifc_reg__SS_DBG_SERVICE_REG_RSP__TAP_MAILBOX_AVAILABLE__in_t TAP_MAILBOX_AVAILABLE; + soc_ifc_reg__SS_DBG_SERVICE_REG_RSP__RSVD__in_t RSVD; + } soc_ifc_reg__SS_DBG_SERVICE_REG_RSP__in_t; + + typedef struct packed{ + logic [31:0] next; + logic we; + logic swwel; + } soc_ifc_reg__SS_SOC_DBG_UNLOCK_LEVEL__LEVEL__in_t; + + typedef struct packed{ + soc_ifc_reg__SS_SOC_DBG_UNLOCK_LEVEL__LEVEL__in_t LEVEL; + } soc_ifc_reg__SS_SOC_DBG_UNLOCK_LEVEL__in_t; + + typedef struct packed{ + logic [31:0] next; + logic wel; + logic swwe; + logic hwclr; + } soc_ifc_reg__key_w32__in_t; + + typedef struct packed{ + soc_ifc_reg__key_w32__in_t key; + } soc_ifc_reg__internal_obf_key__in_t; + + typedef struct packed{ + logic hwclr; + } soc_ifc_reg__internal_iccm_lock__lock__in_t; + + typedef struct packed{ + soc_ifc_reg__internal_iccm_lock__lock__in_t lock; + } soc_ifc_reg__internal_iccm_lock__in_t; + + typedef struct packed{ + logic incr; + } soc_ifc_reg__internal_rv_mtime_l__count_l__in_t; + + typedef struct packed{ + soc_ifc_reg__internal_rv_mtime_l__count_l__in_t count_l; + } soc_ifc_reg__internal_rv_mtime_l__in_t; + + typedef struct packed{ + logic incr; + } soc_ifc_reg__internal_rv_mtime_h__count_h__in_t; + + typedef struct packed{ + soc_ifc_reg__internal_rv_mtime_h__count_h__in_t count_h; + } soc_ifc_reg__internal_rv_mtime_h__in_t; + + typedef struct packed{ + logic hwset; + } soc_ifc_reg__intr_block_t__error_intr_t_error_bad_fuse_sts_23f67582_error_cmd_fail_sts_b85845f8_error_iccm_blocked_sts_e81e6ad2_error_internal_sts_caad62e2_error_inv_dev_sts_6693e7db_error_mbox_ecc_unc_sts_30bff330_error_wdt_timer1_timeout_sts_6aaa9655_error_wdt_timer2_timeout_sts_cda8789f__error_internal_sts_enable_d33001bb_next_52b75ffa_resetsignal_f7aac87a__in_t; + + typedef struct packed{ + logic hwset; + } soc_ifc_reg__intr_block_t__error_intr_t_error_bad_fuse_sts_23f67582_error_cmd_fail_sts_b85845f8_error_iccm_blocked_sts_e81e6ad2_error_internal_sts_caad62e2_error_inv_dev_sts_6693e7db_error_mbox_ecc_unc_sts_30bff330_error_wdt_timer1_timeout_sts_6aaa9655_error_wdt_timer2_timeout_sts_cda8789f__error_inv_dev_sts_enable_e83f2724_next_8318aff8_resetsignal_f7aac87a__in_t; + + typedef struct packed{ + logic hwset; + } soc_ifc_reg__intr_block_t__error_intr_t_error_bad_fuse_sts_23f67582_error_cmd_fail_sts_b85845f8_error_iccm_blocked_sts_e81e6ad2_error_internal_sts_caad62e2_error_inv_dev_sts_6693e7db_error_mbox_ecc_unc_sts_30bff330_error_wdt_timer1_timeout_sts_6aaa9655_error_wdt_timer2_timeout_sts_cda8789f__error_cmd_fail_sts_enable_d535c05b_next_eee7e362_resetsignal_f7aac87a__in_t; + + typedef struct packed{ + logic hwset; + } soc_ifc_reg__intr_block_t__error_intr_t_error_bad_fuse_sts_23f67582_error_cmd_fail_sts_b85845f8_error_iccm_blocked_sts_e81e6ad2_error_internal_sts_caad62e2_error_inv_dev_sts_6693e7db_error_mbox_ecc_unc_sts_30bff330_error_wdt_timer1_timeout_sts_6aaa9655_error_wdt_timer2_timeout_sts_cda8789f__error_bad_fuse_sts_enable_fceb289f_next_14761353_resetsignal_f7aac87a__in_t; + + typedef struct packed{ + logic hwset; + } soc_ifc_reg__intr_block_t__error_intr_t_error_bad_fuse_sts_23f67582_error_cmd_fail_sts_b85845f8_error_iccm_blocked_sts_e81e6ad2_error_internal_sts_caad62e2_error_inv_dev_sts_6693e7db_error_mbox_ecc_unc_sts_30bff330_error_wdt_timer1_timeout_sts_6aaa9655_error_wdt_timer2_timeout_sts_cda8789f__error_iccm_blocked_sts_enable_4ccfea15_next_86c0a4d2_resetsignal_f7aac87a__in_t; + + typedef struct packed{ + logic hwset; + } soc_ifc_reg__intr_block_t__error_intr_t_error_bad_fuse_sts_23f67582_error_cmd_fail_sts_b85845f8_error_iccm_blocked_sts_e81e6ad2_error_internal_sts_caad62e2_error_inv_dev_sts_6693e7db_error_mbox_ecc_unc_sts_30bff330_error_wdt_timer1_timeout_sts_6aaa9655_error_wdt_timer2_timeout_sts_cda8789f__error_mbox_ecc_unc_sts_enable_18d80a94_next_91af8aa5_resetsignal_f7aac87a__in_t; + + typedef struct packed{ + logic hwset; + } soc_ifc_reg__intr_block_t__error_intr_t_error_bad_fuse_sts_23f67582_error_cmd_fail_sts_b85845f8_error_iccm_blocked_sts_e81e6ad2_error_internal_sts_caad62e2_error_inv_dev_sts_6693e7db_error_mbox_ecc_unc_sts_30bff330_error_wdt_timer1_timeout_sts_6aaa9655_error_wdt_timer2_timeout_sts_cda8789f__error_wdt_timer1_timeout_sts_enable_fa7e6d0f_next_293a6067_resetsignal_f7aac87a__in_t; + + typedef struct packed{ + logic hwset; + } soc_ifc_reg__intr_block_t__error_intr_t_error_bad_fuse_sts_23f67582_error_cmd_fail_sts_b85845f8_error_iccm_blocked_sts_e81e6ad2_error_internal_sts_caad62e2_error_inv_dev_sts_6693e7db_error_mbox_ecc_unc_sts_30bff330_error_wdt_timer1_timeout_sts_6aaa9655_error_wdt_timer2_timeout_sts_cda8789f__error_wdt_timer2_timeout_sts_enable_38137b0c_next_1084f7bd_resetsignal_f7aac87a__in_t; + + typedef struct packed{ + soc_ifc_reg__intr_block_t__error_intr_t_error_bad_fuse_sts_23f67582_error_cmd_fail_sts_b85845f8_error_iccm_blocked_sts_e81e6ad2_error_internal_sts_caad62e2_error_inv_dev_sts_6693e7db_error_mbox_ecc_unc_sts_30bff330_error_wdt_timer1_timeout_sts_6aaa9655_error_wdt_timer2_timeout_sts_cda8789f__error_internal_sts_enable_d33001bb_next_52b75ffa_resetsignal_f7aac87a__in_t error_internal_sts; + soc_ifc_reg__intr_block_t__error_intr_t_error_bad_fuse_sts_23f67582_error_cmd_fail_sts_b85845f8_error_iccm_blocked_sts_e81e6ad2_error_internal_sts_caad62e2_error_inv_dev_sts_6693e7db_error_mbox_ecc_unc_sts_30bff330_error_wdt_timer1_timeout_sts_6aaa9655_error_wdt_timer2_timeout_sts_cda8789f__error_inv_dev_sts_enable_e83f2724_next_8318aff8_resetsignal_f7aac87a__in_t error_inv_dev_sts; + soc_ifc_reg__intr_block_t__error_intr_t_error_bad_fuse_sts_23f67582_error_cmd_fail_sts_b85845f8_error_iccm_blocked_sts_e81e6ad2_error_internal_sts_caad62e2_error_inv_dev_sts_6693e7db_error_mbox_ecc_unc_sts_30bff330_error_wdt_timer1_timeout_sts_6aaa9655_error_wdt_timer2_timeout_sts_cda8789f__error_cmd_fail_sts_enable_d535c05b_next_eee7e362_resetsignal_f7aac87a__in_t error_cmd_fail_sts; + soc_ifc_reg__intr_block_t__error_intr_t_error_bad_fuse_sts_23f67582_error_cmd_fail_sts_b85845f8_error_iccm_blocked_sts_e81e6ad2_error_internal_sts_caad62e2_error_inv_dev_sts_6693e7db_error_mbox_ecc_unc_sts_30bff330_error_wdt_timer1_timeout_sts_6aaa9655_error_wdt_timer2_timeout_sts_cda8789f__error_bad_fuse_sts_enable_fceb289f_next_14761353_resetsignal_f7aac87a__in_t error_bad_fuse_sts; + soc_ifc_reg__intr_block_t__error_intr_t_error_bad_fuse_sts_23f67582_error_cmd_fail_sts_b85845f8_error_iccm_blocked_sts_e81e6ad2_error_internal_sts_caad62e2_error_inv_dev_sts_6693e7db_error_mbox_ecc_unc_sts_30bff330_error_wdt_timer1_timeout_sts_6aaa9655_error_wdt_timer2_timeout_sts_cda8789f__error_iccm_blocked_sts_enable_4ccfea15_next_86c0a4d2_resetsignal_f7aac87a__in_t error_iccm_blocked_sts; + soc_ifc_reg__intr_block_t__error_intr_t_error_bad_fuse_sts_23f67582_error_cmd_fail_sts_b85845f8_error_iccm_blocked_sts_e81e6ad2_error_internal_sts_caad62e2_error_inv_dev_sts_6693e7db_error_mbox_ecc_unc_sts_30bff330_error_wdt_timer1_timeout_sts_6aaa9655_error_wdt_timer2_timeout_sts_cda8789f__error_mbox_ecc_unc_sts_enable_18d80a94_next_91af8aa5_resetsignal_f7aac87a__in_t error_mbox_ecc_unc_sts; + soc_ifc_reg__intr_block_t__error_intr_t_error_bad_fuse_sts_23f67582_error_cmd_fail_sts_b85845f8_error_iccm_blocked_sts_e81e6ad2_error_internal_sts_caad62e2_error_inv_dev_sts_6693e7db_error_mbox_ecc_unc_sts_30bff330_error_wdt_timer1_timeout_sts_6aaa9655_error_wdt_timer2_timeout_sts_cda8789f__error_wdt_timer1_timeout_sts_enable_fa7e6d0f_next_293a6067_resetsignal_f7aac87a__in_t error_wdt_timer1_timeout_sts; + soc_ifc_reg__intr_block_t__error_intr_t_error_bad_fuse_sts_23f67582_error_cmd_fail_sts_b85845f8_error_iccm_blocked_sts_e81e6ad2_error_internal_sts_caad62e2_error_inv_dev_sts_6693e7db_error_mbox_ecc_unc_sts_30bff330_error_wdt_timer1_timeout_sts_6aaa9655_error_wdt_timer2_timeout_sts_cda8789f__error_wdt_timer2_timeout_sts_enable_38137b0c_next_1084f7bd_resetsignal_f7aac87a__in_t error_wdt_timer2_timeout_sts; + } soc_ifc_reg__intr_block_t__error_intr_t_error_bad_fuse_sts_23f67582_error_cmd_fail_sts_b85845f8_error_iccm_blocked_sts_e81e6ad2_error_internal_sts_caad62e2_error_inv_dev_sts_6693e7db_error_mbox_ecc_unc_sts_30bff330_error_wdt_timer1_timeout_sts_6aaa9655_error_wdt_timer2_timeout_sts_cda8789f__in_t; + + typedef struct packed{ + logic hwset; + } soc_ifc_reg__intr_block_t__notif_intr_t_notif_cmd_avail_sts_1871606b_notif_debug_locked_sts_5f024102_notif_gen_in_toggle_sts_59f84b64_notif_mbox_ecc_cor_sts_5c3d26bb_notif_scan_mode_sts_122f6367_notif_soc_req_lock_sts_deddde70__notif_cmd_avail_sts_enable_f40f37a0_next_6afe0a88__in_t; + + typedef struct packed{ + logic hwset; + } soc_ifc_reg__intr_block_t__notif_intr_t_notif_cmd_avail_sts_1871606b_notif_debug_locked_sts_5f024102_notif_gen_in_toggle_sts_59f84b64_notif_mbox_ecc_cor_sts_5c3d26bb_notif_scan_mode_sts_122f6367_notif_soc_req_lock_sts_deddde70__notif_mbox_ecc_cor_sts_enable_c4f9db68_next_96c01bef__in_t; + + typedef struct packed{ + logic hwset; + } soc_ifc_reg__intr_block_t__notif_intr_t_notif_cmd_avail_sts_1871606b_notif_debug_locked_sts_5f024102_notif_gen_in_toggle_sts_59f84b64_notif_mbox_ecc_cor_sts_5c3d26bb_notif_scan_mode_sts_122f6367_notif_soc_req_lock_sts_deddde70__notif_debug_locked_sts_enable_097fcd5b_next_36fa44d8__in_t; + + typedef struct packed{ + logic hwset; + } soc_ifc_reg__intr_block_t__notif_intr_t_notif_cmd_avail_sts_1871606b_notif_debug_locked_sts_5f024102_notif_gen_in_toggle_sts_59f84b64_notif_mbox_ecc_cor_sts_5c3d26bb_notif_scan_mode_sts_122f6367_notif_soc_req_lock_sts_deddde70__notif_scan_mode_sts_enable_ed1d9036_next_eb34855d__in_t; + + typedef struct packed{ + logic hwset; + } soc_ifc_reg__intr_block_t__notif_intr_t_notif_cmd_avail_sts_1871606b_notif_debug_locked_sts_5f024102_notif_gen_in_toggle_sts_59f84b64_notif_mbox_ecc_cor_sts_5c3d26bb_notif_scan_mode_sts_122f6367_notif_soc_req_lock_sts_deddde70__notif_soc_req_lock_sts_enable_52b75726_next_228b63de__in_t; + + typedef struct packed{ + logic hwset; + } soc_ifc_reg__intr_block_t__notif_intr_t_notif_cmd_avail_sts_1871606b_notif_debug_locked_sts_5f024102_notif_gen_in_toggle_sts_59f84b64_notif_mbox_ecc_cor_sts_5c3d26bb_notif_scan_mode_sts_122f6367_notif_soc_req_lock_sts_deddde70__notif_gen_in_toggle_sts_enable_9918ab15_next_e02c99b9__in_t; + + typedef struct packed{ + soc_ifc_reg__intr_block_t__notif_intr_t_notif_cmd_avail_sts_1871606b_notif_debug_locked_sts_5f024102_notif_gen_in_toggle_sts_59f84b64_notif_mbox_ecc_cor_sts_5c3d26bb_notif_scan_mode_sts_122f6367_notif_soc_req_lock_sts_deddde70__notif_cmd_avail_sts_enable_f40f37a0_next_6afe0a88__in_t notif_cmd_avail_sts; + soc_ifc_reg__intr_block_t__notif_intr_t_notif_cmd_avail_sts_1871606b_notif_debug_locked_sts_5f024102_notif_gen_in_toggle_sts_59f84b64_notif_mbox_ecc_cor_sts_5c3d26bb_notif_scan_mode_sts_122f6367_notif_soc_req_lock_sts_deddde70__notif_mbox_ecc_cor_sts_enable_c4f9db68_next_96c01bef__in_t notif_mbox_ecc_cor_sts; + soc_ifc_reg__intr_block_t__notif_intr_t_notif_cmd_avail_sts_1871606b_notif_debug_locked_sts_5f024102_notif_gen_in_toggle_sts_59f84b64_notif_mbox_ecc_cor_sts_5c3d26bb_notif_scan_mode_sts_122f6367_notif_soc_req_lock_sts_deddde70__notif_debug_locked_sts_enable_097fcd5b_next_36fa44d8__in_t notif_debug_locked_sts; + soc_ifc_reg__intr_block_t__notif_intr_t_notif_cmd_avail_sts_1871606b_notif_debug_locked_sts_5f024102_notif_gen_in_toggle_sts_59f84b64_notif_mbox_ecc_cor_sts_5c3d26bb_notif_scan_mode_sts_122f6367_notif_soc_req_lock_sts_deddde70__notif_scan_mode_sts_enable_ed1d9036_next_eb34855d__in_t notif_scan_mode_sts; + soc_ifc_reg__intr_block_t__notif_intr_t_notif_cmd_avail_sts_1871606b_notif_debug_locked_sts_5f024102_notif_gen_in_toggle_sts_59f84b64_notif_mbox_ecc_cor_sts_5c3d26bb_notif_scan_mode_sts_122f6367_notif_soc_req_lock_sts_deddde70__notif_soc_req_lock_sts_enable_52b75726_next_228b63de__in_t notif_soc_req_lock_sts; + soc_ifc_reg__intr_block_t__notif_intr_t_notif_cmd_avail_sts_1871606b_notif_debug_locked_sts_5f024102_notif_gen_in_toggle_sts_59f84b64_notif_mbox_ecc_cor_sts_5c3d26bb_notif_scan_mode_sts_122f6367_notif_soc_req_lock_sts_deddde70__notif_gen_in_toggle_sts_enable_9918ab15_next_e02c99b9__in_t notif_gen_in_toggle_sts; + } soc_ifc_reg__intr_block_t__notif_intr_t_notif_cmd_avail_sts_1871606b_notif_debug_locked_sts_5f024102_notif_gen_in_toggle_sts_59f84b64_notif_mbox_ecc_cor_sts_5c3d26bb_notif_scan_mode_sts_122f6367_notif_soc_req_lock_sts_deddde70__in_t; + + typedef struct packed{ + soc_ifc_reg__intr_block_t__error_intr_t_error_bad_fuse_sts_23f67582_error_cmd_fail_sts_b85845f8_error_iccm_blocked_sts_e81e6ad2_error_internal_sts_caad62e2_error_inv_dev_sts_6693e7db_error_mbox_ecc_unc_sts_30bff330_error_wdt_timer1_timeout_sts_6aaa9655_error_wdt_timer2_timeout_sts_cda8789f__in_t error_internal_intr_r; + soc_ifc_reg__intr_block_t__notif_intr_t_notif_cmd_avail_sts_1871606b_notif_debug_locked_sts_5f024102_notif_gen_in_toggle_sts_59f84b64_notif_mbox_ecc_cor_sts_5c3d26bb_notif_scan_mode_sts_122f6367_notif_soc_req_lock_sts_deddde70__in_t notif_internal_intr_r; + } soc_ifc_reg__intr_block_t__in_t; + + typedef struct packed{ + logic cptra_rst_b; + logic cptra_pwrgood; + logic soc_req; + soc_ifc_reg__CPTRA_HW_ERROR_FATAL__in_t CPTRA_HW_ERROR_FATAL; + soc_ifc_reg__CPTRA_HW_ERROR_NON_FATAL__in_t CPTRA_HW_ERROR_NON_FATAL; + soc_ifc_reg__CPTRA_FW_ERROR_FATAL__in_t CPTRA_FW_ERROR_FATAL; + soc_ifc_reg__CPTRA_FW_ERROR_NON_FATAL__in_t CPTRA_FW_ERROR_NON_FATAL; + soc_ifc_reg__CPTRA_FLOW_STATUS__in_t CPTRA_FLOW_STATUS; + soc_ifc_reg__CPTRA_RESET_REASON__in_t CPTRA_RESET_REASON; + soc_ifc_reg__CPTRA_SECURITY_STATE__in_t CPTRA_SECURITY_STATE; + soc_ifc_reg__CPTRA_MBOX_VALID_AXI_USER__in_t [5-1:0]CPTRA_MBOX_VALID_AXI_USER; + soc_ifc_reg__CPTRA_MBOX_AXI_USER_LOCK__in_t [5-1:0]CPTRA_MBOX_AXI_USER_LOCK; + soc_ifc_reg__CPTRA_TRNG_VALID_AXI_USER__in_t CPTRA_TRNG_VALID_AXI_USER; + soc_ifc_reg__CPTRA_TRNG_AXI_USER_LOCK__in_t CPTRA_TRNG_AXI_USER_LOCK; + soc_ifc_reg__CPTRA_TRNG_DATA__in_t [12-1:0]CPTRA_TRNG_DATA; + soc_ifc_reg__CPTRA_TRNG_STATUS__in_t CPTRA_TRNG_STATUS; + soc_ifc_reg__CPTRA_FUSE_WR_DONE__in_t CPTRA_FUSE_WR_DONE; + soc_ifc_reg__CPTRA_BOOTFSM_GO__in_t CPTRA_BOOTFSM_GO; + soc_ifc_reg__CPTRA_DBG_MANUF_SERVICE_REG__in_t CPTRA_DBG_MANUF_SERVICE_REG; + soc_ifc_reg__CPTRA_GENERIC_INPUT_WIRES__in_t [2-1:0]CPTRA_GENERIC_INPUT_WIRES; + soc_ifc_reg__CPTRA_HW_REV_ID__in_t CPTRA_HW_REV_ID; + soc_ifc_reg__CPTRA_HW_CONFIG__in_t CPTRA_HW_CONFIG; + soc_ifc_reg__CPTRA_WDT_STATUS__in_t CPTRA_WDT_STATUS; + soc_ifc_reg__CPTRA_FUSE_VALID_AXI_USER__in_t CPTRA_FUSE_VALID_AXI_USER; + soc_ifc_reg__CPTRA_FUSE_AXI_USER_LOCK__in_t CPTRA_FUSE_AXI_USER_LOCK; + soc_ifc_reg__CPTRA_HW_CAPABILITIES__in_t CPTRA_HW_CAPABILITIES; + soc_ifc_reg__CPTRA_FW_CAPABILITIES__in_t CPTRA_FW_CAPABILITIES; + soc_ifc_reg__CPTRA_CAP_LOCK__in_t CPTRA_CAP_LOCK; + soc_ifc_reg__CPTRA_OWNER_PK_HASH__in_t [12-1:0]CPTRA_OWNER_PK_HASH; + soc_ifc_reg__CPTRA_OWNER_PK_HASH_LOCK__in_t CPTRA_OWNER_PK_HASH_LOCK; + soc_ifc_reg__fuse_uds_seed__in_t [16-1:0]fuse_uds_seed; + soc_ifc_reg__fuse_field_entropy__in_t [8-1:0]fuse_field_entropy; + soc_ifc_reg__fuse_vendor_pk_hash__in_t [12-1:0]fuse_vendor_pk_hash; + soc_ifc_reg__fuse_ecc_revocation__in_t fuse_ecc_revocation; + soc_ifc_reg__fuse_fmc_key_manifest_svn__in_t fuse_fmc_key_manifest_svn; + soc_ifc_reg__fuse_runtime_svn__in_t [4-1:0]fuse_runtime_svn; + soc_ifc_reg__fuse_anti_rollback_disable__in_t fuse_anti_rollback_disable; + soc_ifc_reg__fuse_idevid_cert_attr__in_t [24-1:0]fuse_idevid_cert_attr; + soc_ifc_reg__fuse_idevid_manuf_hsm_id__in_t [4-1:0]fuse_idevid_manuf_hsm_id; + soc_ifc_reg__fuse_lms_revocation__in_t fuse_lms_revocation; + soc_ifc_reg__fuse_mldsa_revocation__in_t fuse_mldsa_revocation; + soc_ifc_reg__fuse_soc_stepping_id__in_t fuse_soc_stepping_id; + soc_ifc_reg__fuse_manuf_dbg_unlock_token__in_t [16-1:0]fuse_manuf_dbg_unlock_token; + soc_ifc_reg__fuse_pqc_key_type__in_t fuse_pqc_key_type; + soc_ifc_reg__fuse_soc_manifest_svn__in_t [4-1:0]fuse_soc_manifest_svn; + soc_ifc_reg__fuse_soc_manifest_max_svn__in_t fuse_soc_manifest_max_svn; + soc_ifc_reg__fuse_hek_seed__in_t [8-1:0]fuse_hek_seed; + soc_ifc_reg__SS_CALIPTRA_BASE_ADDR_L__in_t SS_CALIPTRA_BASE_ADDR_L; + soc_ifc_reg__SS_CALIPTRA_BASE_ADDR_H__in_t SS_CALIPTRA_BASE_ADDR_H; + soc_ifc_reg__SS_MCI_BASE_ADDR_L__in_t SS_MCI_BASE_ADDR_L; + soc_ifc_reg__SS_MCI_BASE_ADDR_H__in_t SS_MCI_BASE_ADDR_H; + soc_ifc_reg__SS_RECOVERY_IFC_BASE_ADDR_L__in_t SS_RECOVERY_IFC_BASE_ADDR_L; + soc_ifc_reg__SS_RECOVERY_IFC_BASE_ADDR_H__in_t SS_RECOVERY_IFC_BASE_ADDR_H; + soc_ifc_reg__SS_OTP_FC_BASE_ADDR_L__in_t SS_OTP_FC_BASE_ADDR_L; + soc_ifc_reg__SS_OTP_FC_BASE_ADDR_H__in_t SS_OTP_FC_BASE_ADDR_H; + soc_ifc_reg__SS_UDS_SEED_BASE_ADDR_L__in_t SS_UDS_SEED_BASE_ADDR_L; + soc_ifc_reg__SS_UDS_SEED_BASE_ADDR_H__in_t SS_UDS_SEED_BASE_ADDR_H; + soc_ifc_reg__SS_PROD_DEBUG_UNLOCK_AUTH_PK_HASH_REG_BANK_OFFSET__in_t SS_PROD_DEBUG_UNLOCK_AUTH_PK_HASH_REG_BANK_OFFSET; + soc_ifc_reg__SS_NUM_OF_PROD_DEBUG_UNLOCK_AUTH_PK_HASHES__in_t SS_NUM_OF_PROD_DEBUG_UNLOCK_AUTH_PK_HASHES; + soc_ifc_reg__SS_DEBUG_INTENT__in_t SS_DEBUG_INTENT; + soc_ifc_reg__SS_CALIPTRA_DMA_AXI_USER__in_t SS_CALIPTRA_DMA_AXI_USER; + soc_ifc_reg__SS_EXTERNAL_STAGING_AREA_BASE_ADDR_L__in_t SS_EXTERNAL_STAGING_AREA_BASE_ADDR_L; + soc_ifc_reg__SS_EXTERNAL_STAGING_AREA_BASE_ADDR_H__in_t SS_EXTERNAL_STAGING_AREA_BASE_ADDR_H; + soc_ifc_reg__SS_KEY_RELEASE_BASE_ADDR_L__in_t SS_KEY_RELEASE_BASE_ADDR_L; + soc_ifc_reg__SS_KEY_RELEASE_BASE_ADDR_H__in_t SS_KEY_RELEASE_BASE_ADDR_H; + soc_ifc_reg__SS_KEY_RELEASE_SIZE__in_t SS_KEY_RELEASE_SIZE; + soc_ifc_reg__SS_OCP_LOCK_CTRL__in_t SS_OCP_LOCK_CTRL; + soc_ifc_reg__SS_STRAP_GENERIC__in_t [4-1:0]SS_STRAP_GENERIC; + soc_ifc_reg__SS_DBG_SERVICE_REG_REQ__in_t SS_DBG_SERVICE_REG_REQ; + soc_ifc_reg__SS_DBG_SERVICE_REG_RSP__in_t SS_DBG_SERVICE_REG_RSP; + soc_ifc_reg__SS_SOC_DBG_UNLOCK_LEVEL__in_t [2-1:0]SS_SOC_DBG_UNLOCK_LEVEL; + soc_ifc_reg__internal_obf_key__in_t [8-1:0]internal_obf_key; + soc_ifc_reg__internal_iccm_lock__in_t internal_iccm_lock; + soc_ifc_reg__internal_rv_mtime_l__in_t internal_rv_mtime_l; + soc_ifc_reg__internal_rv_mtime_h__in_t internal_rv_mtime_h; + soc_ifc_reg__intr_block_t__in_t intr_block_rf; + } soc_ifc_reg__in_t; + + typedef struct packed{ + logic value; + } soc_ifc_reg__rw_rw_sticky_hw__out_t; + + typedef struct packed{ + soc_ifc_reg__rw_rw_sticky_hw__out_t iccm_ecc_unc; + soc_ifc_reg__rw_rw_sticky_hw__out_t dccm_ecc_unc; + soc_ifc_reg__rw_rw_sticky_hw__out_t nmi_pin; + soc_ifc_reg__rw_rw_sticky_hw__out_t crypto_err; + } soc_ifc_reg__CPTRA_HW_ERROR_FATAL__out_t; + + typedef struct packed{ + soc_ifc_reg__rw_rw_sticky_hw__out_t mbox_prot_no_lock; + soc_ifc_reg__rw_rw_sticky_hw__out_t mbox_prot_ooo; + soc_ifc_reg__rw_rw_sticky_hw__out_t mbox_ecc_unc; + } soc_ifc_reg__CPTRA_HW_ERROR_NON_FATAL__out_t; + + typedef struct packed{ + logic [31:0] value; + logic swmod; + } soc_ifc_reg__rw_rw_sticky_w32__out_t; + + typedef struct packed{ + soc_ifc_reg__rw_rw_sticky_w32__out_t error_code; + } soc_ifc_reg__CPTRA_FW_ERROR_FATAL__out_t; + + typedef struct packed{ + soc_ifc_reg__rw_rw_sticky_w32__out_t error_code; + } soc_ifc_reg__CPTRA_FW_ERROR_NON_FATAL__out_t; + + typedef struct packed{ + logic [31:0] value; + } soc_ifc_reg__CPTRA_HW_ERROR_ENC__error_code__out_t; + + typedef struct packed{ + soc_ifc_reg__CPTRA_HW_ERROR_ENC__error_code__out_t error_code; + } soc_ifc_reg__CPTRA_HW_ERROR_ENC__out_t; + + typedef struct packed{ + logic [31:0] value; + } soc_ifc_reg__CPTRA_FW_ERROR_ENC__error_code__out_t; + + typedef struct packed{ + soc_ifc_reg__CPTRA_FW_ERROR_ENC__error_code__out_t error_code; + } soc_ifc_reg__CPTRA_FW_ERROR_ENC__out_t; + + typedef struct packed{ + logic [31:0] value; + } soc_ifc_reg__CPTRA_FW_EXTENDED_ERROR_INFO__error_info__out_t; + + typedef struct packed{ + soc_ifc_reg__CPTRA_FW_EXTENDED_ERROR_INFO__error_info__out_t error_info; + } soc_ifc_reg__CPTRA_FW_EXTENDED_ERROR_INFO__out_t; + + typedef struct packed{ + logic [31:0] value; + } soc_ifc_reg__CPTRA_BOOT_STATUS__status__out_t; + + typedef struct packed{ + soc_ifc_reg__CPTRA_BOOT_STATUS__status__out_t status; + } soc_ifc_reg__CPTRA_BOOT_STATUS__out_t; + + typedef struct packed{ + logic value; + } soc_ifc_reg__CPTRA_FLOW_STATUS__idevid_csr_ready__out_t; + + typedef struct packed{ + logic value; + } soc_ifc_reg__CPTRA_FLOW_STATUS__ready_for_mb_processing__out_t; + + typedef struct packed{ + logic value; + } soc_ifc_reg__CPTRA_FLOW_STATUS__ready_for_runtime__out_t; + + typedef struct packed{ + logic value; + } soc_ifc_reg__CPTRA_FLOW_STATUS__mailbox_flow_done__out_t; + + typedef struct packed{ + soc_ifc_reg__CPTRA_FLOW_STATUS__idevid_csr_ready__out_t idevid_csr_ready; + soc_ifc_reg__CPTRA_FLOW_STATUS__ready_for_mb_processing__out_t ready_for_mb_processing; + soc_ifc_reg__CPTRA_FLOW_STATUS__ready_for_runtime__out_t ready_for_runtime; + soc_ifc_reg__CPTRA_FLOW_STATUS__mailbox_flow_done__out_t mailbox_flow_done; + } soc_ifc_reg__CPTRA_FLOW_STATUS__out_t; + + typedef struct packed{ + logic value; + } soc_ifc_reg__CPTRA_RESET_REASON__FW_UPD_RESET__out_t; + + typedef struct packed{ + logic value; + } soc_ifc_reg__CPTRA_RESET_REASON__WARM_RESET__out_t; + + typedef struct packed{ + soc_ifc_reg__CPTRA_RESET_REASON__FW_UPD_RESET__out_t FW_UPD_RESET; + soc_ifc_reg__CPTRA_RESET_REASON__WARM_RESET__out_t WARM_RESET; + } soc_ifc_reg__CPTRA_RESET_REASON__out_t; + + typedef struct packed{ + logic [31:0] value; + } soc_ifc_reg__CPTRA_MBOX_VALID_AXI_USER__AXI_USER__out_t; + + typedef struct packed{ + soc_ifc_reg__CPTRA_MBOX_VALID_AXI_USER__AXI_USER__out_t AXI_USER; + } soc_ifc_reg__CPTRA_MBOX_VALID_AXI_USER__out_t; + + typedef struct packed{ + logic value; + } soc_ifc_reg__CPTRA_MBOX_AXI_USER_LOCK__LOCK__out_t; + + typedef struct packed{ + soc_ifc_reg__CPTRA_MBOX_AXI_USER_LOCK__LOCK__out_t LOCK; + } soc_ifc_reg__CPTRA_MBOX_AXI_USER_LOCK__out_t; + + typedef struct packed{ + logic [31:0] value; + } soc_ifc_reg__CPTRA_TRNG_VALID_AXI_USER__AXI_USER__out_t; + + typedef struct packed{ + soc_ifc_reg__CPTRA_TRNG_VALID_AXI_USER__AXI_USER__out_t AXI_USER; + } soc_ifc_reg__CPTRA_TRNG_VALID_AXI_USER__out_t; + + typedef struct packed{ + logic value; + } soc_ifc_reg__CPTRA_TRNG_AXI_USER_LOCK__LOCK__out_t; + + typedef struct packed{ + soc_ifc_reg__CPTRA_TRNG_AXI_USER_LOCK__LOCK__out_t LOCK; + } soc_ifc_reg__CPTRA_TRNG_AXI_USER_LOCK__out_t; + + typedef struct packed{ + logic swacc; + } soc_ifc_reg__CPTRA_TRNG_DATA__DATA__out_t; + + typedef struct packed{ + soc_ifc_reg__CPTRA_TRNG_DATA__DATA__out_t DATA; + } soc_ifc_reg__CPTRA_TRNG_DATA__out_t; + + typedef struct packed{ + logic value; + } soc_ifc_reg__CPTRA_TRNG_CTRL__clear__out_t; + + typedef struct packed{ + soc_ifc_reg__CPTRA_TRNG_CTRL__clear__out_t clear; + } soc_ifc_reg__CPTRA_TRNG_CTRL__out_t; + + typedef struct packed{ + logic value; + } soc_ifc_reg__CPTRA_TRNG_STATUS__DATA_REQ__out_t; + + typedef struct packed{ + soc_ifc_reg__CPTRA_TRNG_STATUS__DATA_REQ__out_t DATA_REQ; + } soc_ifc_reg__CPTRA_TRNG_STATUS__out_t; + + typedef struct packed{ + logic value; + logic swmod; + } soc_ifc_reg__CPTRA_FUSE_WR_DONE__done__out_t; + + typedef struct packed{ + soc_ifc_reg__CPTRA_FUSE_WR_DONE__done__out_t done; + } soc_ifc_reg__CPTRA_FUSE_WR_DONE__out_t; + + typedef struct packed{ + logic value; + } soc_ifc_reg__CPTRA_BOOTFSM_GO__GO__out_t; + + typedef struct packed{ + soc_ifc_reg__CPTRA_BOOTFSM_GO__GO__out_t GO; + } soc_ifc_reg__CPTRA_BOOTFSM_GO__out_t; + + typedef struct packed{ + logic [31:0] value; + } soc_ifc_reg__CPTRA_DBG_MANUF_SERVICE_REG__DATA__out_t; + + typedef struct packed{ + soc_ifc_reg__CPTRA_DBG_MANUF_SERVICE_REG__DATA__out_t DATA; + } soc_ifc_reg__CPTRA_DBG_MANUF_SERVICE_REG__out_t; + + typedef struct packed{ + logic value; + } soc_ifc_reg__CPTRA_CLK_GATING_EN__clk_gating_en__out_t; + + typedef struct packed{ + soc_ifc_reg__CPTRA_CLK_GATING_EN__clk_gating_en__out_t clk_gating_en; + } soc_ifc_reg__CPTRA_CLK_GATING_EN__out_t; + + typedef struct packed{ + logic [31:0] value; + } soc_ifc_reg__CPTRA_GENERIC_INPUT_WIRES__generic_wires__out_t; + + typedef struct packed{ + soc_ifc_reg__CPTRA_GENERIC_INPUT_WIRES__generic_wires__out_t generic_wires; + } soc_ifc_reg__CPTRA_GENERIC_INPUT_WIRES__out_t; + + typedef struct packed{ + logic [31:0] value; + } soc_ifc_reg__CPTRA_GENERIC_OUTPUT_WIRES__generic_wires__out_t; + + typedef struct packed{ + soc_ifc_reg__CPTRA_GENERIC_OUTPUT_WIRES__generic_wires__out_t generic_wires; + } soc_ifc_reg__CPTRA_GENERIC_OUTPUT_WIRES__out_t; + + typedef struct packed{ + logic [31:0] value; + } soc_ifc_reg__CPTRA_FW_REV_ID__REV_ID__out_t; + + typedef struct packed{ + soc_ifc_reg__CPTRA_FW_REV_ID__REV_ID__out_t REV_ID; + } soc_ifc_reg__CPTRA_FW_REV_ID__out_t; + + typedef struct packed{ + logic value; + } soc_ifc_reg__CPTRA_WDT_TIMER1_EN__timer1_en__out_t; + + typedef struct packed{ + soc_ifc_reg__CPTRA_WDT_TIMER1_EN__timer1_en__out_t timer1_en; + } soc_ifc_reg__CPTRA_WDT_TIMER1_EN__out_t; + + typedef struct packed{ + logic value; + } soc_ifc_reg__CPTRA_WDT_TIMER1_CTRL__timer1_restart__out_t; + + typedef struct packed{ + soc_ifc_reg__CPTRA_WDT_TIMER1_CTRL__timer1_restart__out_t timer1_restart; + } soc_ifc_reg__CPTRA_WDT_TIMER1_CTRL__out_t; + + typedef struct packed{ + logic [31:0] value; + } soc_ifc_reg__CPTRA_WDT_TIMER1_TIMEOUT_PERIOD__timer1_timeout_period__out_t; + + typedef struct packed{ + soc_ifc_reg__CPTRA_WDT_TIMER1_TIMEOUT_PERIOD__timer1_timeout_period__out_t timer1_timeout_period; + } soc_ifc_reg__CPTRA_WDT_TIMER1_TIMEOUT_PERIOD__out_t; + + typedef struct packed{ + logic value; + } soc_ifc_reg__CPTRA_WDT_TIMER2_EN__timer2_en__out_t; + + typedef struct packed{ + soc_ifc_reg__CPTRA_WDT_TIMER2_EN__timer2_en__out_t timer2_en; + } soc_ifc_reg__CPTRA_WDT_TIMER2_EN__out_t; + + typedef struct packed{ + logic value; + } soc_ifc_reg__CPTRA_WDT_TIMER2_CTRL__timer2_restart__out_t; + + typedef struct packed{ + soc_ifc_reg__CPTRA_WDT_TIMER2_CTRL__timer2_restart__out_t timer2_restart; + } soc_ifc_reg__CPTRA_WDT_TIMER2_CTRL__out_t; + + typedef struct packed{ + logic [31:0] value; + } soc_ifc_reg__CPTRA_WDT_TIMER2_TIMEOUT_PERIOD__timer2_timeout_period__out_t; + + typedef struct packed{ + soc_ifc_reg__CPTRA_WDT_TIMER2_TIMEOUT_PERIOD__timer2_timeout_period__out_t timer2_timeout_period; + } soc_ifc_reg__CPTRA_WDT_TIMER2_TIMEOUT_PERIOD__out_t; + + typedef struct packed{ + logic value; + } soc_ifc_reg__CPTRA_WDT_STATUS__t1_timeout__out_t; + + typedef struct packed{ + logic value; + } soc_ifc_reg__CPTRA_WDT_STATUS__t2_timeout__out_t; + + typedef struct packed{ + soc_ifc_reg__CPTRA_WDT_STATUS__t1_timeout__out_t t1_timeout; + soc_ifc_reg__CPTRA_WDT_STATUS__t2_timeout__out_t t2_timeout; + } soc_ifc_reg__CPTRA_WDT_STATUS__out_t; + + typedef struct packed{ + logic [31:0] value; + } soc_ifc_reg__CPTRA_FUSE_VALID_AXI_USER__AXI_USER__out_t; + + typedef struct packed{ + soc_ifc_reg__CPTRA_FUSE_VALID_AXI_USER__AXI_USER__out_t AXI_USER; + } soc_ifc_reg__CPTRA_FUSE_VALID_AXI_USER__out_t; + + typedef struct packed{ + logic value; + } soc_ifc_reg__CPTRA_FUSE_AXI_USER_LOCK__LOCK__out_t; + + typedef struct packed{ + soc_ifc_reg__CPTRA_FUSE_AXI_USER_LOCK__LOCK__out_t LOCK; + } soc_ifc_reg__CPTRA_FUSE_AXI_USER_LOCK__out_t; + + typedef struct packed{ + logic value; + } soc_ifc_reg__CPTRA_CAP_LOCK__lock__out_t; + + typedef struct packed{ + soc_ifc_reg__CPTRA_CAP_LOCK__lock__out_t lock; + } soc_ifc_reg__CPTRA_CAP_LOCK__out_t; + + typedef struct packed{ + logic [31:0] value; + } soc_ifc_reg__CPTRA_OWNER_PK_HASH__hash__out_t; + + typedef struct packed{ + soc_ifc_reg__CPTRA_OWNER_PK_HASH__hash__out_t hash; + } soc_ifc_reg__CPTRA_OWNER_PK_HASH__out_t; + + typedef struct packed{ + logic value; + } soc_ifc_reg__CPTRA_OWNER_PK_HASH_LOCK__lock__out_t; + + typedef struct packed{ + soc_ifc_reg__CPTRA_OWNER_PK_HASH_LOCK__lock__out_t lock; + } soc_ifc_reg__CPTRA_OWNER_PK_HASH_LOCK__out_t; + + typedef struct packed{ + logic [31:0] value; + } soc_ifc_reg__secret_w32__out_t; + + typedef struct packed{ + soc_ifc_reg__secret_w32__out_t seed; + } soc_ifc_reg__fuse_uds_seed__out_t; + + typedef struct packed{ + soc_ifc_reg__secret_w32__out_t seed; + } soc_ifc_reg__fuse_field_entropy__out_t; + + typedef struct packed{ + logic [31:0] value; + } soc_ifc_reg__Fuse_w32__out_t; + + typedef struct packed{ + soc_ifc_reg__Fuse_w32__out_t hash; + } soc_ifc_reg__fuse_vendor_pk_hash__out_t; + + typedef struct packed{ + logic [3:0] value; + } soc_ifc_reg__Fuse_w4__out_t; + + typedef struct packed{ + soc_ifc_reg__Fuse_w4__out_t ecc_revocation; + } soc_ifc_reg__fuse_ecc_revocation__out_t; + + typedef struct packed{ + soc_ifc_reg__Fuse_w32__out_t svn; + } soc_ifc_reg__fuse_fmc_key_manifest_svn__out_t; + + typedef struct packed{ + soc_ifc_reg__Fuse_w32__out_t svn; + } soc_ifc_reg__fuse_runtime_svn__out_t; + + typedef struct packed{ + logic value; + } soc_ifc_reg__Fuse__out_t; + + typedef struct packed{ + soc_ifc_reg__Fuse__out_t dis; + } soc_ifc_reg__fuse_anti_rollback_disable__out_t; + + typedef struct packed{ + soc_ifc_reg__Fuse_w32__out_t cert; + } soc_ifc_reg__fuse_idevid_cert_attr__out_t; + + typedef struct packed{ + soc_ifc_reg__Fuse_w32__out_t hsm_id; + } soc_ifc_reg__fuse_idevid_manuf_hsm_id__out_t; + + typedef struct packed{ + soc_ifc_reg__Fuse_w32__out_t lms_revocation; + } soc_ifc_reg__fuse_lms_revocation__out_t; + + typedef struct packed{ + soc_ifc_reg__Fuse_w4__out_t mldsa_revocation; + } soc_ifc_reg__fuse_mldsa_revocation__out_t; + + typedef struct packed{ + logic [15:0] value; + } soc_ifc_reg__Fuse_w16__out_t; + + typedef struct packed{ + soc_ifc_reg__Fuse_w16__out_t soc_stepping_id; + } soc_ifc_reg__fuse_soc_stepping_id__out_t; + + typedef struct packed{ + soc_ifc_reg__Fuse_w32__out_t token; + } soc_ifc_reg__fuse_manuf_dbg_unlock_token__out_t; + + typedef struct packed{ + logic [1:0] value; + } soc_ifc_reg__Fuse_w2__out_t; + + typedef struct packed{ + soc_ifc_reg__Fuse_w2__out_t key_type; + } soc_ifc_reg__fuse_pqc_key_type__out_t; + + typedef struct packed{ + soc_ifc_reg__Fuse_w32__out_t svn; + } soc_ifc_reg__fuse_soc_manifest_svn__out_t; + + typedef struct packed{ + logic [7:0] value; + } soc_ifc_reg__Fuse_w8__out_t; + + typedef struct packed{ + soc_ifc_reg__Fuse_w8__out_t svn; + } soc_ifc_reg__fuse_soc_manifest_max_svn__out_t; + + typedef struct packed{ + soc_ifc_reg__Fuse_w32__out_t seed; + } soc_ifc_reg__fuse_hek_seed__out_t; + + typedef struct packed{ + logic [31:0] value; + } soc_ifc_reg__strap_w32__out_t; + + typedef struct packed{ + soc_ifc_reg__strap_w32__out_t addr_l; + } soc_ifc_reg__SS_CALIPTRA_BASE_ADDR_L__out_t; + + typedef struct packed{ + soc_ifc_reg__strap_w32__out_t addr_h; + } soc_ifc_reg__SS_CALIPTRA_BASE_ADDR_H__out_t; + + typedef struct packed{ + soc_ifc_reg__strap_w32__out_t addr_l; + } soc_ifc_reg__SS_MCI_BASE_ADDR_L__out_t; + + typedef struct packed{ + soc_ifc_reg__strap_w32__out_t addr_h; + } soc_ifc_reg__SS_MCI_BASE_ADDR_H__out_t; + + typedef struct packed{ + soc_ifc_reg__strap_w32__out_t addr_l; + } soc_ifc_reg__SS_RECOVERY_IFC_BASE_ADDR_L__out_t; + + typedef struct packed{ + soc_ifc_reg__strap_w32__out_t addr_h; + } soc_ifc_reg__SS_RECOVERY_IFC_BASE_ADDR_H__out_t; + + typedef struct packed{ + soc_ifc_reg__strap_w32__out_t addr_l; + } soc_ifc_reg__SS_OTP_FC_BASE_ADDR_L__out_t; + + typedef struct packed{ + soc_ifc_reg__strap_w32__out_t addr_h; + } soc_ifc_reg__SS_OTP_FC_BASE_ADDR_H__out_t; + + typedef struct packed{ + soc_ifc_reg__strap_w32__out_t addr_l; + } soc_ifc_reg__SS_UDS_SEED_BASE_ADDR_L__out_t; + + typedef struct packed{ + soc_ifc_reg__strap_w32__out_t addr_h; + } soc_ifc_reg__SS_UDS_SEED_BASE_ADDR_H__out_t; + + typedef struct packed{ + soc_ifc_reg__strap_w32__out_t offset; + } soc_ifc_reg__SS_PROD_DEBUG_UNLOCK_AUTH_PK_HASH_REG_BANK_OFFSET__out_t; + + typedef struct packed{ + soc_ifc_reg__strap_w32__out_t num; + } soc_ifc_reg__SS_NUM_OF_PROD_DEBUG_UNLOCK_AUTH_PK_HASHES__out_t; + + typedef struct packed{ + logic value; + } soc_ifc_reg__SS_DEBUG_INTENT__strap__out_t; + + typedef struct packed{ + soc_ifc_reg__SS_DEBUG_INTENT__strap__out_t debug_intent; + } soc_ifc_reg__SS_DEBUG_INTENT__out_t; + + typedef struct packed{ + soc_ifc_reg__strap_w32__out_t user; + } soc_ifc_reg__SS_CALIPTRA_DMA_AXI_USER__out_t; + + typedef struct packed{ + soc_ifc_reg__strap_w32__out_t addr_l; + } soc_ifc_reg__SS_EXTERNAL_STAGING_AREA_BASE_ADDR_L__out_t; + + typedef struct packed{ + soc_ifc_reg__strap_w32__out_t addr_h; + } soc_ifc_reg__SS_EXTERNAL_STAGING_AREA_BASE_ADDR_H__out_t; + + typedef struct packed{ + soc_ifc_reg__strap_w32__out_t addr_l; + } soc_ifc_reg__SS_KEY_RELEASE_BASE_ADDR_L__out_t; + + typedef struct packed{ + soc_ifc_reg__strap_w32__out_t addr_h; + } soc_ifc_reg__SS_KEY_RELEASE_BASE_ADDR_H__out_t; + + typedef struct packed{ + logic [15:0] value; + } soc_ifc_reg__strap_w16__out_t; + + typedef struct packed{ + soc_ifc_reg__strap_w16__out_t size; + } soc_ifc_reg__SS_KEY_RELEASE_SIZE__out_t; + + typedef struct packed{ + logic value; + } soc_ifc_reg__SS_OCP_LOCK_CTRL__LOCK_IN_PROGRESS__out_t; + + typedef struct packed{ + soc_ifc_reg__SS_OCP_LOCK_CTRL__LOCK_IN_PROGRESS__out_t LOCK_IN_PROGRESS; + } soc_ifc_reg__SS_OCP_LOCK_CTRL__out_t; + + typedef struct packed{ + soc_ifc_reg__strap_w32__out_t data; + } soc_ifc_reg__SS_STRAP_GENERIC__out_t; + + typedef struct packed{ + logic value; + } soc_ifc_reg__SS_DBG_SERVICE_REG_REQ__MANUF_DBG_UNLOCK_REQ__out_t; + + typedef struct packed{ + logic value; + } soc_ifc_reg__SS_DBG_SERVICE_REG_REQ__PROD_DBG_UNLOCK_REQ__out_t; + + typedef struct packed{ + logic value; + } soc_ifc_reg__SS_DBG_SERVICE_REG_REQ__UDS_PROGRAM_REQ__out_t; + + typedef struct packed{ + soc_ifc_reg__SS_DBG_SERVICE_REG_REQ__MANUF_DBG_UNLOCK_REQ__out_t MANUF_DBG_UNLOCK_REQ; + soc_ifc_reg__SS_DBG_SERVICE_REG_REQ__PROD_DBG_UNLOCK_REQ__out_t PROD_DBG_UNLOCK_REQ; + soc_ifc_reg__SS_DBG_SERVICE_REG_REQ__UDS_PROGRAM_REQ__out_t UDS_PROGRAM_REQ; + } soc_ifc_reg__SS_DBG_SERVICE_REG_REQ__out_t; + + typedef struct packed{ + logic value; + } soc_ifc_reg__SS_DBG_SERVICE_REG_RSP__MANUF_DBG_UNLOCK_SUCCESS__out_t; + + typedef struct packed{ + logic value; + } soc_ifc_reg__SS_DBG_SERVICE_REG_RSP__MANUF_DBG_UNLOCK_FAIL__out_t; + + typedef struct packed{ + logic value; + } soc_ifc_reg__SS_DBG_SERVICE_REG_RSP__MANUF_DBG_UNLOCK_IN_PROGRESS__out_t; + + typedef struct packed{ + logic value; + } soc_ifc_reg__SS_DBG_SERVICE_REG_RSP__PROD_DBG_UNLOCK_SUCCESS__out_t; + + typedef struct packed{ + logic value; + } soc_ifc_reg__SS_DBG_SERVICE_REG_RSP__PROD_DBG_UNLOCK_FAIL__out_t; + + typedef struct packed{ + logic value; + } soc_ifc_reg__SS_DBG_SERVICE_REG_RSP__PROD_DBG_UNLOCK_IN_PROGRESS__out_t; + + typedef struct packed{ + logic value; + } soc_ifc_reg__SS_DBG_SERVICE_REG_RSP__UDS_PROGRAM_SUCCESS__out_t; + + typedef struct packed{ + logic value; + } soc_ifc_reg__SS_DBG_SERVICE_REG_RSP__UDS_PROGRAM_FAIL__out_t; + + typedef struct packed{ + logic value; + } soc_ifc_reg__SS_DBG_SERVICE_REG_RSP__UDS_PROGRAM_IN_PROGRESS__out_t; + + typedef struct packed{ + logic value; + } soc_ifc_reg__SS_DBG_SERVICE_REG_RSP__TAP_MAILBOX_AVAILABLE__out_t; + + typedef struct packed{ + soc_ifc_reg__SS_DBG_SERVICE_REG_RSP__MANUF_DBG_UNLOCK_SUCCESS__out_t MANUF_DBG_UNLOCK_SUCCESS; + soc_ifc_reg__SS_DBG_SERVICE_REG_RSP__MANUF_DBG_UNLOCK_FAIL__out_t MANUF_DBG_UNLOCK_FAIL; + soc_ifc_reg__SS_DBG_SERVICE_REG_RSP__MANUF_DBG_UNLOCK_IN_PROGRESS__out_t MANUF_DBG_UNLOCK_IN_PROGRESS; + soc_ifc_reg__SS_DBG_SERVICE_REG_RSP__PROD_DBG_UNLOCK_SUCCESS__out_t PROD_DBG_UNLOCK_SUCCESS; + soc_ifc_reg__SS_DBG_SERVICE_REG_RSP__PROD_DBG_UNLOCK_FAIL__out_t PROD_DBG_UNLOCK_FAIL; + soc_ifc_reg__SS_DBG_SERVICE_REG_RSP__PROD_DBG_UNLOCK_IN_PROGRESS__out_t PROD_DBG_UNLOCK_IN_PROGRESS; + soc_ifc_reg__SS_DBG_SERVICE_REG_RSP__UDS_PROGRAM_SUCCESS__out_t UDS_PROGRAM_SUCCESS; + soc_ifc_reg__SS_DBG_SERVICE_REG_RSP__UDS_PROGRAM_FAIL__out_t UDS_PROGRAM_FAIL; + soc_ifc_reg__SS_DBG_SERVICE_REG_RSP__UDS_PROGRAM_IN_PROGRESS__out_t UDS_PROGRAM_IN_PROGRESS; + soc_ifc_reg__SS_DBG_SERVICE_REG_RSP__TAP_MAILBOX_AVAILABLE__out_t TAP_MAILBOX_AVAILABLE; + } soc_ifc_reg__SS_DBG_SERVICE_REG_RSP__out_t; + + typedef struct packed{ + logic [31:0] value; + } soc_ifc_reg__SS_SOC_DBG_UNLOCK_LEVEL__LEVEL__out_t; + + typedef struct packed{ + soc_ifc_reg__SS_SOC_DBG_UNLOCK_LEVEL__LEVEL__out_t LEVEL; + } soc_ifc_reg__SS_SOC_DBG_UNLOCK_LEVEL__out_t; + + typedef struct packed{ + logic [31:0] value; + } soc_ifc_reg__SS_GENERIC_FW_EXEC_CTRL__go__out_t; + + typedef struct packed{ + soc_ifc_reg__SS_GENERIC_FW_EXEC_CTRL__go__out_t go; + } soc_ifc_reg__SS_GENERIC_FW_EXEC_CTRL__out_t; + + typedef struct packed{ + logic [31:0] value; + } soc_ifc_reg__key_w32__out_t; + + typedef struct packed{ + soc_ifc_reg__key_w32__out_t key; + } soc_ifc_reg__internal_obf_key__out_t; + + typedef struct packed{ + logic value; + } soc_ifc_reg__internal_iccm_lock__lock__out_t; + + typedef struct packed{ + soc_ifc_reg__internal_iccm_lock__lock__out_t lock; + } soc_ifc_reg__internal_iccm_lock__out_t; + + typedef struct packed{ + logic value; + } soc_ifc_reg__internal_fw_update_reset__core_rst__out_t; + + typedef struct packed{ + soc_ifc_reg__internal_fw_update_reset__core_rst__out_t core_rst; + } soc_ifc_reg__internal_fw_update_reset__out_t; + + typedef struct packed{ + logic [7:0] value; + } soc_ifc_reg__internal_fw_update_reset_wait_cycles__wait_cycles__out_t; + + typedef struct packed{ + soc_ifc_reg__internal_fw_update_reset_wait_cycles__wait_cycles__out_t wait_cycles; + } soc_ifc_reg__internal_fw_update_reset_wait_cycles__out_t; + + typedef struct packed{ + logic [31:0] value; + } soc_ifc_reg__internal_nmi_vector__vec__out_t; + + typedef struct packed{ + soc_ifc_reg__internal_nmi_vector__vec__out_t vec; + } soc_ifc_reg__internal_nmi_vector__out_t; + + typedef struct packed{ + logic value; + } soc_ifc_reg__rw_ro_hw__out_t; + + typedef struct packed{ + soc_ifc_reg__rw_ro_hw__out_t mask_iccm_ecc_unc; + soc_ifc_reg__rw_ro_hw__out_t mask_dccm_ecc_unc; + soc_ifc_reg__rw_ro_hw__out_t mask_nmi_pin; + } soc_ifc_reg__internal_hw_error_fatal_mask__out_t; + + typedef struct packed{ + soc_ifc_reg__rw_ro_hw__out_t mask_mbox_prot_no_lock; + soc_ifc_reg__rw_ro_hw__out_t mask_mbox_prot_ooo; + soc_ifc_reg__rw_ro_hw__out_t mask_mbox_ecc_unc; + } soc_ifc_reg__internal_hw_error_non_fatal_mask__out_t; + + typedef struct packed{ + logic [31:0] value; + } soc_ifc_reg__rw_ro_hw_w32__out_t; + + typedef struct packed{ + soc_ifc_reg__rw_ro_hw_w32__out_t mask; + } soc_ifc_reg__internal_fw_error_fatal_mask__out_t; + + typedef struct packed{ + soc_ifc_reg__rw_ro_hw_w32__out_t mask; + } soc_ifc_reg__internal_fw_error_non_fatal_mask__out_t; + + typedef struct packed{ + logic [31:0] value; + logic swmod; + logic overflow; + } soc_ifc_reg__internal_rv_mtime_l__count_l__out_t; + + typedef struct packed{ + soc_ifc_reg__internal_rv_mtime_l__count_l__out_t count_l; + } soc_ifc_reg__internal_rv_mtime_l__out_t; + + typedef struct packed{ + logic [31:0] value; + logic swmod; + } soc_ifc_reg__internal_rv_mtime_h__count_h__out_t; + + typedef struct packed{ + soc_ifc_reg__internal_rv_mtime_h__count_h__out_t count_h; + } soc_ifc_reg__internal_rv_mtime_h__out_t; + + typedef struct packed{ + logic [31:0] value; + } soc_ifc_reg__internal_rv_mtimecmp_l__compare_l__out_t; + + typedef struct packed{ + soc_ifc_reg__internal_rv_mtimecmp_l__compare_l__out_t compare_l; + } soc_ifc_reg__internal_rv_mtimecmp_l__out_t; + + typedef struct packed{ + logic [31:0] value; + } soc_ifc_reg__internal_rv_mtimecmp_h__compare_h__out_t; + + typedef struct packed{ + soc_ifc_reg__internal_rv_mtimecmp_h__compare_h__out_t compare_h; + } soc_ifc_reg__internal_rv_mtimecmp_h__out_t; + + typedef struct packed{ + logic intr; + } soc_ifc_reg__intr_block_t__global_intr_t_agg_sts_dd3dcf0a__out_t; + + typedef struct packed{ + logic intr; + } soc_ifc_reg__intr_block_t__global_intr_t_agg_sts_e6399b4a__out_t; + + typedef struct packed{ + logic intr; + } soc_ifc_reg__intr_block_t__error_intr_t_error_bad_fuse_sts_23f67582_error_cmd_fail_sts_b85845f8_error_iccm_blocked_sts_e81e6ad2_error_internal_sts_caad62e2_error_inv_dev_sts_6693e7db_error_mbox_ecc_unc_sts_30bff330_error_wdt_timer1_timeout_sts_6aaa9655_error_wdt_timer2_timeout_sts_cda8789f__out_t; + + typedef struct packed{ + logic intr; + } soc_ifc_reg__intr_block_t__notif_intr_t_notif_cmd_avail_sts_1871606b_notif_debug_locked_sts_5f024102_notif_gen_in_toggle_sts_59f84b64_notif_mbox_ecc_cor_sts_5c3d26bb_notif_scan_mode_sts_122f6367_notif_soc_req_lock_sts_deddde70__out_t; + + typedef struct packed{ + soc_ifc_reg__intr_block_t__global_intr_t_agg_sts_dd3dcf0a__out_t error_global_intr_r; + soc_ifc_reg__intr_block_t__global_intr_t_agg_sts_e6399b4a__out_t notif_global_intr_r; + soc_ifc_reg__intr_block_t__error_intr_t_error_bad_fuse_sts_23f67582_error_cmd_fail_sts_b85845f8_error_iccm_blocked_sts_e81e6ad2_error_internal_sts_caad62e2_error_inv_dev_sts_6693e7db_error_mbox_ecc_unc_sts_30bff330_error_wdt_timer1_timeout_sts_6aaa9655_error_wdt_timer2_timeout_sts_cda8789f__out_t error_internal_intr_r; + soc_ifc_reg__intr_block_t__notif_intr_t_notif_cmd_avail_sts_1871606b_notif_debug_locked_sts_5f024102_notif_gen_in_toggle_sts_59f84b64_notif_mbox_ecc_cor_sts_5c3d26bb_notif_scan_mode_sts_122f6367_notif_soc_req_lock_sts_deddde70__out_t notif_internal_intr_r; + } soc_ifc_reg__intr_block_t__out_t; + + typedef struct packed{ + soc_ifc_reg__CPTRA_HW_ERROR_FATAL__out_t CPTRA_HW_ERROR_FATAL; + soc_ifc_reg__CPTRA_HW_ERROR_NON_FATAL__out_t CPTRA_HW_ERROR_NON_FATAL; + soc_ifc_reg__CPTRA_FW_ERROR_FATAL__out_t CPTRA_FW_ERROR_FATAL; + soc_ifc_reg__CPTRA_FW_ERROR_NON_FATAL__out_t CPTRA_FW_ERROR_NON_FATAL; + soc_ifc_reg__CPTRA_HW_ERROR_ENC__out_t CPTRA_HW_ERROR_ENC; + soc_ifc_reg__CPTRA_FW_ERROR_ENC__out_t CPTRA_FW_ERROR_ENC; + soc_ifc_reg__CPTRA_FW_EXTENDED_ERROR_INFO__out_t [8-1:0]CPTRA_FW_EXTENDED_ERROR_INFO; + soc_ifc_reg__CPTRA_BOOT_STATUS__out_t CPTRA_BOOT_STATUS; + soc_ifc_reg__CPTRA_FLOW_STATUS__out_t CPTRA_FLOW_STATUS; + soc_ifc_reg__CPTRA_RESET_REASON__out_t CPTRA_RESET_REASON; + soc_ifc_reg__CPTRA_MBOX_VALID_AXI_USER__out_t [5-1:0]CPTRA_MBOX_VALID_AXI_USER; + soc_ifc_reg__CPTRA_MBOX_AXI_USER_LOCK__out_t [5-1:0]CPTRA_MBOX_AXI_USER_LOCK; + soc_ifc_reg__CPTRA_TRNG_VALID_AXI_USER__out_t CPTRA_TRNG_VALID_AXI_USER; + soc_ifc_reg__CPTRA_TRNG_AXI_USER_LOCK__out_t CPTRA_TRNG_AXI_USER_LOCK; + soc_ifc_reg__CPTRA_TRNG_DATA__out_t [12-1:0]CPTRA_TRNG_DATA; + soc_ifc_reg__CPTRA_TRNG_CTRL__out_t CPTRA_TRNG_CTRL; + soc_ifc_reg__CPTRA_TRNG_STATUS__out_t CPTRA_TRNG_STATUS; + soc_ifc_reg__CPTRA_FUSE_WR_DONE__out_t CPTRA_FUSE_WR_DONE; + soc_ifc_reg__CPTRA_BOOTFSM_GO__out_t CPTRA_BOOTFSM_GO; + soc_ifc_reg__CPTRA_DBG_MANUF_SERVICE_REG__out_t CPTRA_DBG_MANUF_SERVICE_REG; + soc_ifc_reg__CPTRA_CLK_GATING_EN__out_t CPTRA_CLK_GATING_EN; + soc_ifc_reg__CPTRA_GENERIC_INPUT_WIRES__out_t [2-1:0]CPTRA_GENERIC_INPUT_WIRES; + soc_ifc_reg__CPTRA_GENERIC_OUTPUT_WIRES__out_t [2-1:0]CPTRA_GENERIC_OUTPUT_WIRES; + soc_ifc_reg__CPTRA_FW_REV_ID__out_t [2-1:0]CPTRA_FW_REV_ID; + soc_ifc_reg__CPTRA_WDT_TIMER1_EN__out_t CPTRA_WDT_TIMER1_EN; + soc_ifc_reg__CPTRA_WDT_TIMER1_CTRL__out_t CPTRA_WDT_TIMER1_CTRL; + soc_ifc_reg__CPTRA_WDT_TIMER1_TIMEOUT_PERIOD__out_t [2-1:0]CPTRA_WDT_TIMER1_TIMEOUT_PERIOD; + soc_ifc_reg__CPTRA_WDT_TIMER2_EN__out_t CPTRA_WDT_TIMER2_EN; + soc_ifc_reg__CPTRA_WDT_TIMER2_CTRL__out_t CPTRA_WDT_TIMER2_CTRL; + soc_ifc_reg__CPTRA_WDT_TIMER2_TIMEOUT_PERIOD__out_t [2-1:0]CPTRA_WDT_TIMER2_TIMEOUT_PERIOD; + soc_ifc_reg__CPTRA_WDT_STATUS__out_t CPTRA_WDT_STATUS; + soc_ifc_reg__CPTRA_FUSE_VALID_AXI_USER__out_t CPTRA_FUSE_VALID_AXI_USER; + soc_ifc_reg__CPTRA_FUSE_AXI_USER_LOCK__out_t CPTRA_FUSE_AXI_USER_LOCK; + soc_ifc_reg__CPTRA_CAP_LOCK__out_t CPTRA_CAP_LOCK; + soc_ifc_reg__CPTRA_OWNER_PK_HASH__out_t [12-1:0]CPTRA_OWNER_PK_HASH; + soc_ifc_reg__CPTRA_OWNER_PK_HASH_LOCK__out_t CPTRA_OWNER_PK_HASH_LOCK; + soc_ifc_reg__fuse_uds_seed__out_t [16-1:0]fuse_uds_seed; + soc_ifc_reg__fuse_field_entropy__out_t [8-1:0]fuse_field_entropy; + soc_ifc_reg__fuse_vendor_pk_hash__out_t [12-1:0]fuse_vendor_pk_hash; + soc_ifc_reg__fuse_ecc_revocation__out_t fuse_ecc_revocation; + soc_ifc_reg__fuse_fmc_key_manifest_svn__out_t fuse_fmc_key_manifest_svn; + soc_ifc_reg__fuse_runtime_svn__out_t [4-1:0]fuse_runtime_svn; + soc_ifc_reg__fuse_anti_rollback_disable__out_t fuse_anti_rollback_disable; + soc_ifc_reg__fuse_idevid_cert_attr__out_t [24-1:0]fuse_idevid_cert_attr; + soc_ifc_reg__fuse_idevid_manuf_hsm_id__out_t [4-1:0]fuse_idevid_manuf_hsm_id; + soc_ifc_reg__fuse_lms_revocation__out_t fuse_lms_revocation; + soc_ifc_reg__fuse_mldsa_revocation__out_t fuse_mldsa_revocation; + soc_ifc_reg__fuse_soc_stepping_id__out_t fuse_soc_stepping_id; + soc_ifc_reg__fuse_manuf_dbg_unlock_token__out_t [16-1:0]fuse_manuf_dbg_unlock_token; + soc_ifc_reg__fuse_pqc_key_type__out_t fuse_pqc_key_type; + soc_ifc_reg__fuse_soc_manifest_svn__out_t [4-1:0]fuse_soc_manifest_svn; + soc_ifc_reg__fuse_soc_manifest_max_svn__out_t fuse_soc_manifest_max_svn; + soc_ifc_reg__fuse_hek_seed__out_t [8-1:0]fuse_hek_seed; + soc_ifc_reg__SS_CALIPTRA_BASE_ADDR_L__out_t SS_CALIPTRA_BASE_ADDR_L; + soc_ifc_reg__SS_CALIPTRA_BASE_ADDR_H__out_t SS_CALIPTRA_BASE_ADDR_H; + soc_ifc_reg__SS_MCI_BASE_ADDR_L__out_t SS_MCI_BASE_ADDR_L; + soc_ifc_reg__SS_MCI_BASE_ADDR_H__out_t SS_MCI_BASE_ADDR_H; + soc_ifc_reg__SS_RECOVERY_IFC_BASE_ADDR_L__out_t SS_RECOVERY_IFC_BASE_ADDR_L; + soc_ifc_reg__SS_RECOVERY_IFC_BASE_ADDR_H__out_t SS_RECOVERY_IFC_BASE_ADDR_H; + soc_ifc_reg__SS_OTP_FC_BASE_ADDR_L__out_t SS_OTP_FC_BASE_ADDR_L; + soc_ifc_reg__SS_OTP_FC_BASE_ADDR_H__out_t SS_OTP_FC_BASE_ADDR_H; + soc_ifc_reg__SS_UDS_SEED_BASE_ADDR_L__out_t SS_UDS_SEED_BASE_ADDR_L; + soc_ifc_reg__SS_UDS_SEED_BASE_ADDR_H__out_t SS_UDS_SEED_BASE_ADDR_H; + soc_ifc_reg__SS_PROD_DEBUG_UNLOCK_AUTH_PK_HASH_REG_BANK_OFFSET__out_t SS_PROD_DEBUG_UNLOCK_AUTH_PK_HASH_REG_BANK_OFFSET; + soc_ifc_reg__SS_NUM_OF_PROD_DEBUG_UNLOCK_AUTH_PK_HASHES__out_t SS_NUM_OF_PROD_DEBUG_UNLOCK_AUTH_PK_HASHES; + soc_ifc_reg__SS_DEBUG_INTENT__out_t SS_DEBUG_INTENT; + soc_ifc_reg__SS_CALIPTRA_DMA_AXI_USER__out_t SS_CALIPTRA_DMA_AXI_USER; + soc_ifc_reg__SS_EXTERNAL_STAGING_AREA_BASE_ADDR_L__out_t SS_EXTERNAL_STAGING_AREA_BASE_ADDR_L; + soc_ifc_reg__SS_EXTERNAL_STAGING_AREA_BASE_ADDR_H__out_t SS_EXTERNAL_STAGING_AREA_BASE_ADDR_H; + soc_ifc_reg__SS_KEY_RELEASE_BASE_ADDR_L__out_t SS_KEY_RELEASE_BASE_ADDR_L; + soc_ifc_reg__SS_KEY_RELEASE_BASE_ADDR_H__out_t SS_KEY_RELEASE_BASE_ADDR_H; + soc_ifc_reg__SS_KEY_RELEASE_SIZE__out_t SS_KEY_RELEASE_SIZE; + soc_ifc_reg__SS_OCP_LOCK_CTRL__out_t SS_OCP_LOCK_CTRL; + soc_ifc_reg__SS_STRAP_GENERIC__out_t [4-1:0]SS_STRAP_GENERIC; + soc_ifc_reg__SS_DBG_SERVICE_REG_REQ__out_t SS_DBG_SERVICE_REG_REQ; + soc_ifc_reg__SS_DBG_SERVICE_REG_RSP__out_t SS_DBG_SERVICE_REG_RSP; + soc_ifc_reg__SS_SOC_DBG_UNLOCK_LEVEL__out_t [2-1:0]SS_SOC_DBG_UNLOCK_LEVEL; + soc_ifc_reg__SS_GENERIC_FW_EXEC_CTRL__out_t [4-1:0]SS_GENERIC_FW_EXEC_CTRL; + soc_ifc_reg__internal_obf_key__out_t [8-1:0]internal_obf_key; + soc_ifc_reg__internal_iccm_lock__out_t internal_iccm_lock; + soc_ifc_reg__internal_fw_update_reset__out_t internal_fw_update_reset; + soc_ifc_reg__internal_fw_update_reset_wait_cycles__out_t internal_fw_update_reset_wait_cycles; + soc_ifc_reg__internal_nmi_vector__out_t internal_nmi_vector; + soc_ifc_reg__internal_hw_error_fatal_mask__out_t internal_hw_error_fatal_mask; + soc_ifc_reg__internal_hw_error_non_fatal_mask__out_t internal_hw_error_non_fatal_mask; + soc_ifc_reg__internal_fw_error_fatal_mask__out_t internal_fw_error_fatal_mask; + soc_ifc_reg__internal_fw_error_non_fatal_mask__out_t internal_fw_error_non_fatal_mask; + soc_ifc_reg__internal_rv_mtime_l__out_t internal_rv_mtime_l; + soc_ifc_reg__internal_rv_mtime_h__out_t internal_rv_mtime_h; + soc_ifc_reg__internal_rv_mtimecmp_l__out_t internal_rv_mtimecmp_l; + soc_ifc_reg__internal_rv_mtimecmp_h__out_t internal_rv_mtimecmp_h; + soc_ifc_reg__intr_block_t__out_t intr_block_rf; + } soc_ifc_reg__out_t; + + typedef enum logic [31:0] { + soc_ifc_reg__CPTRA_SECURITY_STATE__device_lifecycle_e__DEVICE_UNPROVISIONED = 'h0, + soc_ifc_reg__CPTRA_SECURITY_STATE__device_lifecycle_e__DEVICE_MANUFACTURING = 'h1, + soc_ifc_reg__CPTRA_SECURITY_STATE__device_lifecycle_e__DEVICE_PRODUCTION = 'h3 + } soc_ifc_reg__CPTRA_SECURITY_STATE__device_lifecycle_e_e; + + localparam SOC_IFC_REG_ADDR_WIDTH = 32'd12; + +endpackage \ No newline at end of file diff --git a/designs/Caliptra/src/caliptra-rtl/soc_ifc_top.sv b/designs/Caliptra/src/caliptra-rtl/soc_ifc_top.sv new file mode 100644 index 0000000..032160e --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/soc_ifc_top.sv @@ -0,0 +1,1556 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. + +`include "caliptra_sva.svh" +`include "caliptra_macros.svh" +`include "caliptra_reg_defines.svh" +`include "caliptra_reg_field_defines.svh" + +module soc_ifc_top + import soc_ifc_pkg::*; + import mbox_pkg::*; + import soc_ifc_reg_pkg::*; + import kv_defines_pkg::*; + #( + parameter AXI_ADDR_WIDTH = 18 + ,parameter AXI_DATA_WIDTH = 32 + ,parameter AXI_ID_WIDTH = 32 + ,parameter AXI_USER_WIDTH = 32 + ,parameter AHB_ADDR_WIDTH = 18 + ,parameter AHB_DATA_WIDTH = 32 + ,parameter AXIM_ADDR_WIDTH = 48 + ,parameter AXIM_DATA_WIDTH = 32 + ,parameter AXIM_ID_WIDTH = 5 + ,parameter AXIM_USER_WIDTH = 32 + ) + ( + input logic clk, + input logic clk_cg, + input logic soc_ifc_clk_cg, + input logic rdc_clk_cg, + + //SoC boot signals + input logic cptra_pwrgood, + input logic cptra_rst_b, + + output logic ready_for_fuses, + output logic ready_for_mb_processing, + output logic ready_for_runtime, + + output logic mailbox_data_avail, + output logic mailbox_flow_done, + + input logic recovery_data_avail, + input logic recovery_image_activated, + + input var security_state_t security_state, + + input logic [1:0][31:0] generic_input_wires, + input logic BootFSM_BrkPoint, + output logic [1:0][31:0] generic_output_wires, + + //SoC AXI Interface + axi_if.w_sub s_axi_w_if, + axi_if.r_sub s_axi_r_if, + + //uC AHB Lite Interface + input logic [AHB_ADDR_WIDTH-1:0] haddr_i, + input logic [AHB_DATA_WIDTH-1:0] hwdata_i, + input logic hsel_i, + input logic hwrite_i, + input logic hready_i, + input logic [1:0] htrans_i, + input logic [2:0] hsize_i, + + output logic hresp_o, + output logic hreadyout_o, + output logic [AHB_DATA_WIDTH-1:0] hrdata_o, + + // AXI Manager INF + axi_if.w_mgr m_axi_w_if, + axi_if.r_mgr m_axi_r_if, + + //SoC Interrupts + output logic cptra_error_fatal, + output logic cptra_error_non_fatal, + output logic trng_req, + + //uC Interrupts + output wire soc_ifc_error_intr, + output wire soc_ifc_notif_intr, + output wire sha_error_intr, + output wire sha_notif_intr, + output wire dma_error_intr, + output wire dma_notif_intr, + output wire timer_intr, + + //SRAM interface + output cptra_mbox_sram_req_t mbox_sram_req, + input cptra_mbox_sram_resp_t mbox_sram_resp, + + // RV ECC Status Interface + input rv_ecc_sts_t rv_ecc_sts, + + // Clear KeyVault secrets + input logic debugUnlock_or_scan_mode_switch, + + //Obfuscated UDS and FE + input logic clear_obf_secrets, + input logic scan_mode, + input logic [`CLP_OBF_KEY_DWORDS-1:0][31:0] cptra_obf_key, + output logic [`CLP_OBF_KEY_DWORDS-1:0][31:0] cptra_obf_key_reg, + input logic cptra_obf_field_entropy_vld, + input logic [`CLP_OBF_FE_DWORDS-1 :0][31:0] cptra_obf_field_entropy, + output logic [`CLP_OBF_FE_DWORDS-1 :0][31:0] obf_field_entropy, + input logic cptra_obf_uds_seed_vld, + input logic [`CLP_OBF_UDS_DWORDS-1:0][31:0] cptra_obf_uds_seed, + output logic [`CLP_OBF_UDS_DWORDS-1:0][31:0] obf_uds_seed, + output logic [OCP_LOCK_HEK_NUM_DWORDS-1:0][31:0] obf_hek_seed, + + + input logic aes_input_ready, + input logic aes_output_valid, + input logic aes_status_idle, + output logic aes_req_dv, + input logic aes_req_hold, + output soc_ifc_req_t aes_req_data, + input logic [SOC_IFC_DATA_W-1:0] aes_rdata, + input logic aes_error, + + // kv interface + output kv_read_t kv_read, + input kv_rd_resp_t kv_rd_resp, + + // Subsystem mode straps + input logic [63:0] strap_ss_caliptra_base_addr, + input logic [63:0] strap_ss_mci_base_addr, + input logic [63:0] strap_ss_recovery_ifc_base_addr, + input logic [63:0] strap_ss_external_staging_area_base_addr, + input logic [63:0] strap_ss_otp_fc_base_addr, + input logic [63:0] strap_ss_uds_seed_base_addr, + input logic [63:0] strap_ss_key_release_base_addr, + input logic [15:0] strap_ss_key_release_key_size, + input logic [31:0] strap_ss_prod_debug_unlock_auth_pk_hash_reg_bank_offset, + input logic [31:0] strap_ss_num_of_prod_debug_unlock_auth_pk_hashes, + input logic [31:0] strap_ss_strap_generic_0, + input logic [31:0] strap_ss_strap_generic_1, + input logic [31:0] strap_ss_strap_generic_2, + input logic [31:0] strap_ss_strap_generic_3, + input logic [31:0] strap_ss_caliptra_dma_axi_user, + input logic ss_debug_intent, + output logic cptra_ss_debug_intent, + + // Subsystem mode debug outputs + output logic ss_dbg_manuf_enable, + output logic [63:0] ss_soc_dbg_unlock_level, + + // Subsystem mode firmware execution control + output logic [127:0] ss_generic_fw_exec_ctrl, + + // Subsystem mode OCP LOCK status + input logic ss_ocp_lock_en, + output logic ss_ocp_lock_in_progress, + output logic [15:0] ss_key_release_key_size, + + // NMI Vector + output logic [31:0] nmi_vector, + output logic nmi_intr, + + // ICCM Lock + output logic iccm_lock, + input logic iccm_axs_blocked, + + //Other blocks reset + output logic cptra_noncore_rst_b, + //uC reset + output logic cptra_uc_rst_b, + //Clock gating + output logic clk_gating_en, + output logic rdc_clk_dis, + output logic fw_update_rst_window, + + input logic crypto_error, + + //caliptra uncore jtag ports + input logic cptra_uncore_dmi_reg_en, + input logic cptra_uncore_dmi_reg_wr_en, + output logic [31:0] cptra_uncore_dmi_reg_rdata, + input logic [6:0] cptra_uncore_dmi_reg_addr, + input logic [31:0] cptra_uncore_dmi_reg_wdata +); + +//gasket to assemble mailbox request +logic soc_req_dv, soc_req_hold; +logic soc_req_error; +logic [AXI_DATA_WIDTH-1:0] soc_req_rdata; +soc_ifc_req_t soc_req; + +//gasket to assemble mailbox request +logic uc_req_dv, uc_req_hold; +logic uc_req_error; +logic [SOC_IFC_DATA_W-1:0] uc_req_rdata; +soc_ifc_req_t uc_req; + +//mbox req inf +logic mbox_req_dv; +logic mbox_dir_req_dv; +logic mbox_req_hold; +soc_ifc_req_t mbox_req_data; +logic [SOC_IFC_DATA_W-1:0] mbox_rdata; +logic [SOC_IFC_DATA_W-1:0] mbox_dir_rdata; +logic mbox_error; + +//sha req inf +logic sha_req_dv; +logic sha_req_hold; +soc_ifc_req_t sha_req_data; +logic [SOC_IFC_DATA_W-1:0] sha_rdata; +logic sha_error; + +//DMA reg inf +logic dma_reg_req_dv; +logic dma_reg_req_hold; +soc_ifc_req_t dma_reg_req_data; +logic [SOC_IFC_DATA_W-1:0] dma_reg_rdata; +logic dma_reg_error; + +//mbox reg inf +logic soc_ifc_reg_req_dv; +logic soc_ifc_reg_req_hold; +soc_ifc_req_t soc_ifc_reg_req_data; +logic [SOC_IFC_DATA_W-1:0] soc_ifc_reg_rdata_pre, soc_ifc_reg_rdata; +logic soc_ifc_reg_error, soc_ifc_reg_read_error, soc_ifc_reg_write_error; +logic soc_ifc_reg_rdata_mask; + +logic sha_sram_req_dv; +logic [CPTRA_MBOX_ADDR_W-1:0] sha_sram_req_addr; +cptra_mbox_sram_resp_t sha_sram_resp; +logic sha_sram_hold; + +//DMA SRAM direct inf +logic dma_sram_req_dv; +logic dma_sram_req_hold; +soc_ifc_req_t dma_sram_req_data; +logic [SOC_IFC_DATA_W-1:0] dma_sram_rdata; +logic dma_sram_error; + +logic [4:0][AXI_USER_WIDTH-1:0] valid_mbox_users; + +// Pulse signals to trigger interrupts +logic uc_mbox_data_avail; +logic uc_mbox_data_avail_d; +logic uc_cmd_avail_p; +logic security_state_debug_locked_d; +logic security_state_debug_locked_p; +logic scan_mode_f; +logic scan_mode_p; +logic sram_single_ecc_error; +logic sram_double_ecc_error; +logic soc_req_mbox_lock; +logic [1:0] generic_input_toggle; +mbox_protocol_error_t mbox_protocol_error; +logic mbox_inv_user_p; + +logic uc_mbox_lock; +logic iccm_unlock; +logic fw_upd_rst_executed; +logic fuse_wr_done_reg_write_observed; +logic fuse_done; + +logic unmasked_hw_error_fatal_write; +logic unmasked_hw_error_non_fatal_write; +logic unmasked_hw_error_non_fatal_is_set; + +logic pwrgood_toggle_hint; +logic Warm_Reset_Capture_Flag; + +logic BootFSM_BrkPoint_Latched; +logic BootFSM_BrkPoint_valid; +logic BootFSM_BrkPoint_Flag; + +logic cptra_uncore_dmi_locked_reg_en; +logic cptra_uncore_dmi_unlocked_reg_en; +logic dmi_inc_rdptr; +logic dmi_inc_wrptr; +logic cptra_uncore_dmi_reg_dout_access_f; +logic cptra_uncore_dmi_reg_din_access_f; +mbox_dmi_reg_t mbox_dmi_reg; +logic [31:0] cptra_uncore_dmi_locked_reg_rdata_in; +logic [31:0] cptra_uncore_dmi_unlocked_reg_rdata_in; + +logic strap_we; +logic cptra_uncore_dmi_unlocked_reg_wr_en; +logic cptra_uncore_dmi_locked_reg_wr_en; + +soc_ifc_reg__in_t soc_ifc_reg_hwif_in; +soc_ifc_reg__out_t soc_ifc_reg_hwif_out; + +//WDT signals +logic [SOC_IFC_WDT_TIMEOUT_PERIOD_NUM_DWORDS-1:0][31:0] timer1_timeout_period; +logic [SOC_IFC_WDT_TIMEOUT_PERIOD_NUM_DWORDS-1:0][31:0] timer2_timeout_period; +logic timer1_en; +logic timer2_en; +logic timer1_restart; +logic timer2_restart; +logic t1_timeout; +logic t1_timeout_f; //To generate interrupt pulse +logic t1_timeout_p; +logic t2_timeout; +logic t2_timeout_f; //To generate interrupt pulse +logic t2_timeout_p; +logic wdt_error_t1_intr_serviced; +logic wdt_error_t2_intr_serviced; + +logic valid_trng_user; +logic valid_fuse_user; +logic valid_sha_user; + +logic strap_we_pre_fuse_done; + +boot_fsm_state_e boot_fsm_ps; + +assign fuse_done = soc_ifc_reg_hwif_out.CPTRA_FUSE_WR_DONE.done.value; + +//Boot FSM +//This module contains the logic required to control the Caliptra Boot Flow +//Once the SoC has powered on Caliptra and de-asserted RESET, we can request fuses +//This FSM will de-assert reset and allow the Caliptra uC to boot after fuses are downloaded +soc_ifc_boot_fsm i_soc_ifc_boot_fsm ( + .clk(clk), + .cptra_pwrgood(cptra_pwrgood), + .cptra_rst_b (cptra_rst_b), + .scan_mode(scan_mode), + .fw_update_rst (soc_ifc_reg_hwif_out.internal_fw_update_reset.core_rst.value), + .fw_update_rst_wait_cycles (soc_ifc_reg_hwif_out.internal_fw_update_reset_wait_cycles.wait_cycles.value), + .ready_for_fuses(ready_for_fuses), + .boot_fsm_ps(boot_fsm_ps), + + .fuse_done(fuse_done), + .fuse_wr_done_observed(fuse_wr_done_reg_write_observed), + + .BootFSM_BrkPoint(BootFSM_BrkPoint_valid), + .BootFSM_Continue(soc_ifc_reg_hwif_out.CPTRA_BOOTFSM_GO.GO.value), + + .cptra_noncore_rst_b(cptra_noncore_rst_b), //goes to all other blocks + .cptra_uc_rst_b(cptra_uc_rst_b), //goes to veer core + .iccm_unlock(iccm_unlock), + .fw_upd_rst_executed(fw_upd_rst_executed), + .rdc_clk_dis(rdc_clk_dis), + .fw_update_rst_window(fw_update_rst_window) +); + +always_comb soc_ifc_reg_hwif_in.CPTRA_RESET_REASON.FW_UPD_RESET.we = fw_upd_rst_executed; +always_comb soc_ifc_reg_hwif_in.CPTRA_RESET_REASON.FW_UPD_RESET.next = 1; + +//AXI Interface +//This module contains the logic for interfacing with the SoC over the AXI Interface +//The SoC sends read and write requests using AXI Protocol +//This wrapper decodes that protocol, collapses the full-duplex protocol to +// simplex, and issues requests to the soc_ifc arbitration block +axi_sub #( + .AW (AXI_ADDR_WIDTH), + .DW (AXI_DATA_WIDTH), + .UW (AXI_USER_WIDTH), + .IW (AXI_ID_WIDTH ), + .EX_EN(0 ), + .C_LAT(0 ) +) i_axi_sub_sif_soc_ifc ( + .clk (soc_ifc_clk_cg ), + .rst_n(cptra_noncore_rst_b), + + // AXI INF + .s_axi_w_if(s_axi_w_if), + .s_axi_r_if(s_axi_r_if), + + //COMPONENT INF + .dv (soc_req_dv ), + .addr (soc_req.addr ), // Byte address + .write (soc_req.write ), + .user (soc_req.user ), + .id (soc_req.id ), + .wdata (soc_req.wdata ), // Requires: Component dwidth == AXI dwidth + .wstrb (soc_req.wstrb ), // Requires: Component dwidth == AXI dwidth + .rdata (soc_req_rdata ), // Requires: Component dwidth == AXI dwidth + .last ( ), // Asserted with final 'dv' of a burst + .hld (soc_req_hold ), + .size ( ), + .rd_err(soc_req_error ), + .wr_err(soc_req_error ) +); + +//req from axi is for soc always +always_comb soc_req.soc_req = 1'b1; + +//AHB-Lite Interface +//This module contains the logic for interfacing with the Caliptra uC over the AHB-Lite Interface +//The Caliptra uC sends read and write requests using AHB-Lite Protocol +//This wrapper decodes that protocol and issues requests to the arbitration block +ahb_slv_sif #( + .AHB_ADDR_WIDTH(AHB_ADDR_WIDTH), + .AHB_DATA_WIDTH(AHB_DATA_WIDTH), + .CLIENT_DATA_WIDTH(SOC_IFC_DATA_W) +) +i_ahb_slv_sif_soc_ifc ( + //AMBA AHB Lite INF + .hclk(clk_cg), + .hreset_n(cptra_noncore_rst_b), + .haddr_i(haddr_i), + .hwdata_i(hwdata_i), + .hsel_i(hsel_i), + .hwrite_i(hwrite_i), + .hready_i(hready_i), + .htrans_i(htrans_i), + .hsize_i(hsize_i), + + .hresp_o(hresp_o), + .hreadyout_o(hreadyout_o), + .hrdata_o(hrdata_o), + + + //COMPONENT INF + .dv(uc_req_dv), + .hld(uc_req_hold), + .err(uc_req_error), + .write(uc_req.write), + .wdata(uc_req.wdata), + .addr(uc_req.addr), + + .rdata(uc_req_rdata) +); + +always_comb uc_req.user = '1; +always_comb uc_req.id = '1; +always_comb uc_req.soc_req = 1'b0; +always_comb uc_req.wstrb = {SOC_IFC_DATA_W/8{1'b1}}; + +//mailbox_arb +//This module contains the arbitration logic between SoC and Caliptra uC requests +//Requests are serviced using round robin arbitration + +soc_ifc_arb #( + .AXI_USER_WIDTH(AXI_USER_WIDTH) + ) + i_soc_ifc_arb ( + .clk(soc_ifc_clk_cg), + .rst_b(cptra_noncore_rst_b), + .valid_mbox_users(valid_mbox_users), + .valid_fuse_user(valid_fuse_user), + .valid_sha_user(valid_sha_user), + //UC inf + .uc_req_dv(uc_req_dv), + .uc_req_hold(uc_req_hold), + .uc_req_data(uc_req), + .uc_rdata(uc_req_rdata), + .uc_error(uc_req_error), + //SOC inf + .soc_req_dv(soc_req_dv), + .soc_req_hold(soc_req_hold), + .soc_req_data(soc_req), + .soc_rdata(soc_req_rdata), + .soc_error(soc_req_error), + //MBOX inf + .mbox_req_dv(mbox_req_dv), + .mbox_dir_req_dv(mbox_dir_req_dv), + .mbox_req_hold(mbox_req_hold), + .mbox_req_data(mbox_req_data), + .mbox_rdata(mbox_rdata), + .mbox_dir_rdata(mbox_dir_rdata), + .mbox_error(mbox_error), + //SHA inf + .sha_req_dv(sha_req_dv), + .sha_req_hold(sha_req_hold), + .sha_req_data(sha_req_data), + .sha_rdata(sha_rdata), + .sha_error(sha_error), + //DMA inf + .dma_reg_req_dv (dma_reg_req_dv ), + .dma_reg_req_data(dma_reg_req_data), + .dma_reg_req_hold(dma_reg_req_hold), + .dma_reg_rdata (dma_reg_rdata ), + .dma_reg_error (dma_reg_error ), + + //FUNC reg inf + .soc_ifc_reg_req_dv(soc_ifc_reg_req_dv), + .soc_ifc_reg_req_hold(soc_ifc_reg_req_hold), + .soc_ifc_reg_req_data(soc_ifc_reg_req_data), + .soc_ifc_reg_rdata(soc_ifc_reg_rdata), + .soc_ifc_reg_error(soc_ifc_reg_error) + +); + +always_comb soc_ifc_reg_req_hold = 1'b0; + + +//Functional Registers and Fuses +//This module contains the functional registers maintained by the Caliptra Mailbox +//These registers are memory mapped per the Caliptra Specification +//Read and Write permissions are controlled within this block +always_comb soc_ifc_reg_error = soc_ifc_reg_read_error | soc_ifc_reg_write_error; + +always_comb soc_ifc_reg_hwif_in.cptra_rst_b = cptra_noncore_rst_b; +always_comb soc_ifc_reg_hwif_in.cptra_pwrgood = cptra_pwrgood; +always_comb soc_ifc_reg_hwif_in.soc_req = soc_ifc_reg_req_data.soc_req; + +`ifdef CALIPTRA_FUSE_GRANULARITY_32 +always_comb soc_ifc_reg_hwif_in.CPTRA_HW_CONFIG.Fuse_Granularity.next = 1'b1; +`else +always_comb soc_ifc_reg_hwif_in.CPTRA_HW_CONFIG.Fuse_Granularity.next = 1'b0; +`endif + +`ifdef CALIPTRA_INTERNAL_TRNG +always_comb soc_ifc_reg_hwif_in.CPTRA_HW_CONFIG.iTRNG_en.next = 1'b1; +`else +always_comb soc_ifc_reg_hwif_in.CPTRA_HW_CONFIG.iTRNG_en.next = 1'b0; +`endif +always_comb soc_ifc_reg_hwif_in.CPTRA_HW_CONFIG.RSVD_en.next = 3'b0; +// Hardcoded because all future revs will have LMS accelerator available +always_comb soc_ifc_reg_hwif_in.CPTRA_HW_CONFIG.LMS_acc_en.next = 1'b1; +`ifdef CALIPTRA_MODE_SUBSYSTEM + always_comb soc_ifc_reg_hwif_in.CPTRA_HW_CONFIG.SUBSYSTEM_MODE_en.next = 1'b1; + always_comb soc_ifc_reg_hwif_in.CPTRA_HW_CONFIG.OCP_LOCK_MODE_en.next = ss_ocp_lock_en; +`else + always_comb soc_ifc_reg_hwif_in.CPTRA_HW_CONFIG.SUBSYSTEM_MODE_en.next = 1'b0; + always_comb soc_ifc_reg_hwif_in.CPTRA_HW_CONFIG.OCP_LOCK_MODE_en.next = 1'b0; +`endif + +//SOC Stepping ID update +always_comb begin + soc_ifc_reg_hwif_in.CPTRA_HW_REV_ID.SOC_STEPPING_ID.next = soc_ifc_reg_hwif_out.fuse_soc_stepping_id.soc_stepping_id.value[15:0]; +end + +always_comb begin + for (int i = 0; i < `CLP_OBF_KEY_DWORDS; i++) begin + soc_ifc_reg_hwif_in.internal_obf_key[i].key.swwe = '0; //sw can't write to obf key + //Sample only if its a pwrgood cycle, in debug locked state and scan mode is not asserted (as in do not sample if it was a warm reset or debug or scan mode) + soc_ifc_reg_hwif_in.internal_obf_key[i].key.wel = ~pwrgood_toggle_hint || ~security_state.debug_locked || scan_mode_f || clear_obf_secrets; + soc_ifc_reg_hwif_in.internal_obf_key[i].key.next = cptra_obf_key[i]; + soc_ifc_reg_hwif_in.internal_obf_key[i].key.hwclr = clear_obf_secrets; + cptra_obf_key_reg[i] = soc_ifc_reg_hwif_out.internal_obf_key[i].key.value; + end + for (int i = 0; i < `CLP_OBF_UDS_DWORDS; i++) begin + soc_ifc_reg_hwif_in.fuse_uds_seed[i].seed.hwclr = clear_obf_secrets; + //Sample immediately after we leave warm reset. + //Only if debug locked, not scan mode, and the fuse valid bit is set + soc_ifc_reg_hwif_in.fuse_uds_seed[i].seed.we = ~Warm_Reset_Capture_Flag && security_state.debug_locked && ~scan_mode_f && !clear_obf_secrets && cptra_obf_uds_seed_vld && ~soc_ifc_reg_hwif_out.CPTRA_FUSE_WR_DONE.done.value; + soc_ifc_reg_hwif_in.fuse_uds_seed[i].seed.next = cptra_obf_uds_seed[i]; + obf_uds_seed[i] = soc_ifc_reg_hwif_out.fuse_uds_seed[i].seed.value; + end + for (int i = 0; i < `CLP_OBF_FE_DWORDS; i++) begin + soc_ifc_reg_hwif_in.fuse_field_entropy[i].seed.hwclr = clear_obf_secrets; + //Sample immediately after we leave warm reset. + //Only if debug locked, not scan mode, and the fuse valid bit is set + soc_ifc_reg_hwif_in.fuse_field_entropy[i].seed.we = ~Warm_Reset_Capture_Flag && security_state.debug_locked && ~scan_mode_f && !clear_obf_secrets && cptra_obf_field_entropy_vld && ~soc_ifc_reg_hwif_out.CPTRA_FUSE_WR_DONE.done.value; + soc_ifc_reg_hwif_in.fuse_field_entropy[i].seed.next = cptra_obf_field_entropy[i]; + obf_field_entropy[i] = soc_ifc_reg_hwif_out.fuse_field_entropy[i].seed.value; + end + for (int i = 0; i < OCP_LOCK_HEK_NUM_DWORDS; i++) begin + obf_hek_seed[i] = soc_ifc_reg_hwif_out.fuse_hek_seed[i].seed.value; + end + + //flow status + mailbox_flow_done = soc_ifc_reg_hwif_out.CPTRA_FLOW_STATUS.mailbox_flow_done.value; + ready_for_mb_processing = soc_ifc_reg_hwif_out.CPTRA_FLOW_STATUS.ready_for_mb_processing.value; + ready_for_runtime = soc_ifc_reg_hwif_out.CPTRA_FLOW_STATUS.ready_for_runtime.value; + soc_ifc_reg_hwif_in.CPTRA_FLOW_STATUS.ready_for_fuses.next = ready_for_fuses; + soc_ifc_reg_hwif_in.CPTRA_FLOW_STATUS.boot_fsm_ps.next = boot_fsm_ps; + soc_ifc_reg_hwif_in.CPTRA_SECURITY_STATE.device_lifecycle.next = security_state.device_lifecycle; + soc_ifc_reg_hwif_in.CPTRA_SECURITY_STATE.debug_locked.next = security_state.debug_locked; + soc_ifc_reg_hwif_in.CPTRA_SECURITY_STATE.scan_mode.next = scan_mode; + //generic wires + for (int i = 0; i < 2; i++) begin + generic_output_wires[i] = soc_ifc_reg_hwif_out.CPTRA_GENERIC_OUTPUT_WIRES[i].generic_wires.value; + soc_ifc_reg_hwif_in.CPTRA_GENERIC_INPUT_WIRES[i].generic_wires.next = generic_input_wires[i]; + if (|(soc_ifc_reg_hwif_out.CPTRA_GENERIC_INPUT_WIRES[i].generic_wires.value ^ generic_input_wires[i])) begin + generic_input_toggle[i] = 1; + end + else begin + generic_input_toggle[i] = 0; + end + end + +end + +logic cptra_in_dbg_or_manuf_mode; + +// Breakpoint value captured on a Caliptra reset deassertion (0->1 signal transition) +// BootFSM_Continue will allow the boot fsm to continue +// Security State in Debug or Manuf Mode +assign cptra_in_dbg_or_manuf_mode = ~(security_state.debug_locked) | + ((security_state.debug_locked) & (security_state.device_lifecycle == DEVICE_MANUFACTURING)); + +always_ff @(posedge rdc_clk_cg or negedge cptra_noncore_rst_b) begin + if (~cptra_noncore_rst_b) begin + BootFSM_BrkPoint_Latched <= 0; + BootFSM_BrkPoint_Flag <= 0; + end + // Breakpoint value captured on a Caliptra reset deassertion (0->1 signal transition) and is reset on BootFSM_Continue is set + // BootFSM_Continue's reset value is zero + else if(!BootFSM_BrkPoint_Flag) begin + BootFSM_BrkPoint_Latched <= BootFSM_BrkPoint; + BootFSM_BrkPoint_Flag <= 1; + end +end + +// Bootfsm break point is valid if Caliptra is in debug mode or manuf mode OR the debug intent is set +assign BootFSM_BrkPoint_valid = BootFSM_BrkPoint_Latched & (cptra_in_dbg_or_manuf_mode | cptra_ss_debug_intent); + +// pwrgood_hint informs if the powergood toggled +always_ff @(posedge rdc_clk_cg or negedge cptra_pwrgood) begin + if(~cptra_pwrgood) begin + pwrgood_toggle_hint <= 1; + end + // Reset the bit after warm reset deassertion has been observed + else if(Warm_Reset_Capture_Flag) begin + pwrgood_toggle_hint <= 0; + end +end + +always_ff @(posedge rdc_clk_cg or negedge cptra_noncore_rst_b) begin + if (~cptra_noncore_rst_b) begin + Warm_Reset_Capture_Flag <= 0; + end + else if(!Warm_Reset_Capture_Flag) begin + Warm_Reset_Capture_Flag <= 1; + end +end + +// PwrGood is used to decide if the warm reset toggle happened due to pwrgood or +// only due to warm reset. We also need to clear this bit when its +// FW_UPD_RESET only path +always_comb begin + if (!Warm_Reset_Capture_Flag) begin + soc_ifc_reg_hwif_in.CPTRA_RESET_REASON.WARM_RESET.next = ~pwrgood_toggle_hint; + end + else if (soc_ifc_reg_hwif_out.CPTRA_RESET_REASON.FW_UPD_RESET.value) begin + soc_ifc_reg_hwif_in.CPTRA_RESET_REASON.WARM_RESET.next = 1'b0; + end + else begin + soc_ifc_reg_hwif_in.CPTRA_RESET_REASON.WARM_RESET.next = soc_ifc_reg_hwif_out.CPTRA_RESET_REASON.WARM_RESET.value; + end +end + + +// Generate a pulse to set the interrupt bit +always_ff @(posedge rdc_clk_cg or negedge cptra_noncore_rst_b) begin + if (~cptra_noncore_rst_b) begin + security_state_debug_locked_d <= '0; + end + else begin + security_state_debug_locked_d <= security_state.debug_locked; + end +end + +always_comb security_state_debug_locked_p = security_state.debug_locked ^ security_state_debug_locked_d; + +// Generate a pulse to set the interrupt bit +always_ff @(posedge clk or negedge cptra_noncore_rst_b) begin + if (~cptra_noncore_rst_b) begin + scan_mode_f <= '0; + end + else begin + scan_mode_f <= scan_mode; + end +end + +always_comb scan_mode_p = scan_mode & ~scan_mode_f; + +//Filtering by AXI_USER +always_comb begin + for (int i=0; i<5; i++) begin + //once locked, can't be cleared until reset + soc_ifc_reg_hwif_in.CPTRA_MBOX_AXI_USER_LOCK[i].LOCK.swwel = soc_ifc_reg_hwif_out.CPTRA_MBOX_AXI_USER_LOCK[i].LOCK.value; + //lock the writes to valid user field once lock is set + soc_ifc_reg_hwif_in.CPTRA_MBOX_VALID_AXI_USER[i].AXI_USER.swwel = soc_ifc_reg_hwif_out.CPTRA_MBOX_AXI_USER_LOCK[i].LOCK.value; + //If integrator set AXI_USER values at integration time, pick it up from the define + valid_mbox_users[i] = CPTRA_SET_MBOX_AXI_USER_INTEG[i] ? CPTRA_MBOX_VALID_AXI_USER[i][AXI_USER_WIDTH-1:0] : + soc_ifc_reg_hwif_out.CPTRA_MBOX_AXI_USER_LOCK[i].LOCK.value ? + soc_ifc_reg_hwif_out.CPTRA_MBOX_VALID_AXI_USER[i].AXI_USER.value[AXI_USER_WIDTH-1:0] : CPTRA_DEF_MBOX_VALID_AXI_USER; + end +end + +//can't write to trng valid user after it is locked +always_comb soc_ifc_reg_hwif_in.CPTRA_TRNG_VALID_AXI_USER.AXI_USER.swwel = soc_ifc_reg_hwif_out.CPTRA_TRNG_AXI_USER_LOCK.LOCK.value; +always_comb soc_ifc_reg_hwif_in.CPTRA_TRNG_AXI_USER_LOCK.LOCK.swwel = soc_ifc_reg_hwif_out.CPTRA_TRNG_AXI_USER_LOCK.LOCK.value; + +//fuse register AXI USER fields +always_comb soc_ifc_reg_hwif_in.CPTRA_FUSE_VALID_AXI_USER.AXI_USER.swwel = soc_ifc_reg_hwif_out.CPTRA_FUSE_AXI_USER_LOCK.LOCK.value; +always_comb soc_ifc_reg_hwif_in.CPTRA_FUSE_AXI_USER_LOCK.LOCK.swwel = soc_ifc_reg_hwif_out.CPTRA_FUSE_AXI_USER_LOCK.LOCK.value; + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Can't write to RW-able fuses once fuse_done is set (implies the register is being locked using the fuse_wr_done) +///////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +always_ff @(posedge soc_ifc_clk_cg or negedge cptra_noncore_rst_b) begin + if(~cptra_noncore_rst_b) begin + fuse_wr_done_reg_write_observed <= 0; + end + else begin + if(!fuse_wr_done_reg_write_observed) begin + fuse_wr_done_reg_write_observed <= soc_ifc_reg_hwif_out.CPTRA_FUSE_WR_DONE.done.swmod; + end + end +end + +// Make the relevant fuses sticky on fuse_wr_done +always_comb begin + for (int i=0; i < `CLP_OBF_UDS_DWORDS; i++) begin + soc_ifc_reg_hwif_in.fuse_uds_seed[i].seed.swwel = soc_ifc_reg_hwif_out.CPTRA_FUSE_WR_DONE.done.value; + end + for (int i=0; i<12; i++) begin + soc_ifc_reg_hwif_in.fuse_vendor_pk_hash[i].hash.swwel = soc_ifc_reg_hwif_out.CPTRA_FUSE_WR_DONE.done.value; + end + + for (int i=0; i < `CLP_OBF_FE_DWORDS; i++) begin + soc_ifc_reg_hwif_in.fuse_field_entropy[i].seed.swwel = soc_ifc_reg_hwif_out.CPTRA_FUSE_WR_DONE.done.value; + end + + for (int i=0; i<24; i++) begin + soc_ifc_reg_hwif_in.fuse_idevid_cert_attr[i].cert.swwel = soc_ifc_reg_hwif_out.CPTRA_FUSE_WR_DONE.done.value; + end + + for (int i=0; i<4; i++) begin + soc_ifc_reg_hwif_in.fuse_idevid_manuf_hsm_id[i].hsm_id.swwel = soc_ifc_reg_hwif_out.CPTRA_FUSE_WR_DONE.done.value; + end + + for (int i=0; i<4; i++) begin + soc_ifc_reg_hwif_in.fuse_runtime_svn[i].svn.swwel = soc_ifc_reg_hwif_out.CPTRA_FUSE_WR_DONE.done.value; + end + + foreach(soc_ifc_reg_hwif_in.fuse_manuf_dbg_unlock_token[i]) begin + soc_ifc_reg_hwif_in.fuse_manuf_dbg_unlock_token[i].token.swwel = soc_ifc_reg_hwif_out.CPTRA_FUSE_WR_DONE.done.value; + end + + for (int i=0; i<4; i++) begin + soc_ifc_reg_hwif_in.fuse_soc_manifest_svn[i].svn.swwel = soc_ifc_reg_hwif_out.CPTRA_FUSE_WR_DONE.done.value; + end + + foreach(soc_ifc_reg_hwif_in.fuse_hek_seed[i]) begin + soc_ifc_reg_hwif_in.fuse_hek_seed[i].seed.swwel = soc_ifc_reg_hwif_out.CPTRA_FUSE_WR_DONE.done.value; + end +end + +always_comb soc_ifc_reg_hwif_in.fuse_ecc_revocation.ecc_revocation.swwel = soc_ifc_reg_hwif_out.CPTRA_FUSE_WR_DONE.done.value; +always_comb soc_ifc_reg_hwif_in.fuse_fmc_key_manifest_svn.svn.swwel = soc_ifc_reg_hwif_out.CPTRA_FUSE_WR_DONE.done.value; +always_comb soc_ifc_reg_hwif_in.fuse_anti_rollback_disable.dis.swwel = soc_ifc_reg_hwif_out.CPTRA_FUSE_WR_DONE.done.value; +always_comb soc_ifc_reg_hwif_in.fuse_lms_revocation.lms_revocation.swwel = soc_ifc_reg_hwif_out.CPTRA_FUSE_WR_DONE.done.value; +always_comb soc_ifc_reg_hwif_in.fuse_mldsa_revocation.mldsa_revocation.swwel = soc_ifc_reg_hwif_out.CPTRA_FUSE_WR_DONE.done.value; +always_comb soc_ifc_reg_hwif_in.fuse_soc_stepping_id.soc_stepping_id.swwel = soc_ifc_reg_hwif_out.CPTRA_FUSE_WR_DONE.done.value; +always_comb soc_ifc_reg_hwif_in.fuse_pqc_key_type.key_type.swwel = soc_ifc_reg_hwif_out.CPTRA_FUSE_WR_DONE.done.value; +always_comb soc_ifc_reg_hwif_in.fuse_soc_manifest_max_svn.svn.swwel = soc_ifc_reg_hwif_out.CPTRA_FUSE_WR_DONE.done.value; + +// Lockable registers +always_comb begin + soc_ifc_reg_hwif_in.CPTRA_HW_CAPABILITIES.cap.swwel = soc_ifc_reg_req_data.soc_req || soc_ifc_reg_hwif_out.CPTRA_CAP_LOCK.lock.value; + soc_ifc_reg_hwif_in.CPTRA_FW_CAPABILITIES.cap.swwel = soc_ifc_reg_req_data.soc_req || soc_ifc_reg_hwif_out.CPTRA_CAP_LOCK.lock.value; + for (int i=0; i<12; i++) begin + soc_ifc_reg_hwif_in.CPTRA_OWNER_PK_HASH[i].hash.swwel = soc_ifc_reg_hwif_out.CPTRA_OWNER_PK_HASH_LOCK.lock.value | ~soc_ifc_reg_req_data.soc_req; + end +end + +// OCP Lock progress register is w1-set, meaning once set to 1 it persists until reset (on the uC fw upd reset domain) +// It is also only settable when Caliptra was configured to support OCP LOCK operations (via the LOCK_EN strap) +`ifdef CALIPTRA_MODE_SUBSYSTEM +always_comb soc_ifc_reg_hwif_in.SS_OCP_LOCK_CTRL.LOCK_IN_PROGRESS.swwel = !ss_ocp_lock_en || soc_ifc_reg_req_data.soc_req || soc_ifc_reg_hwif_out.SS_OCP_LOCK_CTRL.LOCK_IN_PROGRESS.value; +`else +always_comb soc_ifc_reg_hwif_in.SS_OCP_LOCK_CTRL.LOCK_IN_PROGRESS.swwel = 1'b1; +`endif + +assign ss_ocp_lock_in_progress = soc_ifc_reg_hwif_out.SS_OCP_LOCK_CTRL.LOCK_IN_PROGRESS.value; +assign ss_key_release_key_size = soc_ifc_reg_hwif_out.SS_KEY_RELEASE_SIZE.size.value; + + +//Uncore registers only open for debug unlock or manufacturing +always_comb cptra_uncore_dmi_unlocked_reg_en = cptra_uncore_dmi_reg_en & + (~(security_state.debug_locked) | + (security_state.device_lifecycle == DEVICE_MANUFACTURING)); +//Uncore registers open for all cases +always_comb cptra_uncore_dmi_locked_reg_en = cptra_uncore_dmi_reg_en; + +always_comb cptra_uncore_dmi_unlocked_reg_wr_en = (cptra_uncore_dmi_reg_wr_en & cptra_uncore_dmi_unlocked_reg_en); +always_comb cptra_uncore_dmi_locked_reg_wr_en = (cptra_uncore_dmi_reg_wr_en & cptra_uncore_dmi_locked_reg_en); + +assign strap_we_pre_fuse_done = strap_we & ~fuse_done; + +// Subsystem straps capture the initial value from input port on rising edge of noncore_rst +always_ff @(posedge clk or negedge cptra_noncore_rst_b) begin + if(~cptra_noncore_rst_b) begin + strap_we <= 1'b1; + end + else begin + strap_we <= 1'b0; + end +end + +always_comb begin : ss_reg_hwwe + //SS STRAPS WITH TAP WRITE ACCESS + soc_ifc_reg_hwif_in.SS_CALIPTRA_BASE_ADDR_L.addr_l.we = strap_we_pre_fuse_done | (cptra_uncore_dmi_unlocked_reg_wr_en & + (cptra_uncore_dmi_reg_addr == DMI_REG_SS_CALIPTRA_BASE_ADDR_L)); + soc_ifc_reg_hwif_in.SS_CALIPTRA_BASE_ADDR_H.addr_h.we = strap_we_pre_fuse_done | (cptra_uncore_dmi_unlocked_reg_wr_en & + (cptra_uncore_dmi_reg_addr == DMI_REG_SS_CALIPTRA_BASE_ADDR_H)); + soc_ifc_reg_hwif_in.SS_MCI_BASE_ADDR_L.addr_l.we = strap_we_pre_fuse_done | (cptra_uncore_dmi_unlocked_reg_wr_en & + (cptra_uncore_dmi_reg_addr == DMI_REG_SS_MCI_BASE_ADDR_L)); + soc_ifc_reg_hwif_in.SS_MCI_BASE_ADDR_H.addr_h.we = strap_we_pre_fuse_done | (cptra_uncore_dmi_unlocked_reg_wr_en & + (cptra_uncore_dmi_reg_addr == DMI_REG_SS_MCI_BASE_ADDR_H)); + soc_ifc_reg_hwif_in.SS_RECOVERY_IFC_BASE_ADDR_L.addr_l.we = strap_we_pre_fuse_done | (cptra_uncore_dmi_unlocked_reg_wr_en & + (cptra_uncore_dmi_reg_addr == DMI_REG_SS_RECOVERY_IFC_BASE_ADDR_L)); + soc_ifc_reg_hwif_in.SS_RECOVERY_IFC_BASE_ADDR_H.addr_h.we = strap_we_pre_fuse_done | (cptra_uncore_dmi_unlocked_reg_wr_en & + (cptra_uncore_dmi_reg_addr == DMI_REG_SS_RECOVERY_IFC_BASE_ADDR_H)); + soc_ifc_reg_hwif_in.SS_EXTERNAL_STAGING_AREA_BASE_ADDR_L.addr_l.we = strap_we_pre_fuse_done | (cptra_uncore_dmi_unlocked_reg_wr_en & + (cptra_uncore_dmi_reg_addr == DMI_REG_SS_EXTERNAL_STAGING_AREA_BASE_ADDR_L)); + soc_ifc_reg_hwif_in.SS_EXTERNAL_STAGING_AREA_BASE_ADDR_H.addr_h.we = strap_we_pre_fuse_done | (cptra_uncore_dmi_unlocked_reg_wr_en & + (cptra_uncore_dmi_reg_addr == DMI_REG_SS_EXTERNAL_STAGING_AREA_BASE_ADDR_H)); + soc_ifc_reg_hwif_in.SS_OTP_FC_BASE_ADDR_L.addr_l.we = strap_we_pre_fuse_done | (cptra_uncore_dmi_unlocked_reg_wr_en & + (cptra_uncore_dmi_reg_addr == DMI_REG_SS_OTP_FC_BASE_ADDR_L)); + soc_ifc_reg_hwif_in.SS_OTP_FC_BASE_ADDR_H.addr_h.we = strap_we_pre_fuse_done | (cptra_uncore_dmi_unlocked_reg_wr_en & + (cptra_uncore_dmi_reg_addr == DMI_REG_SS_OTP_FC_BASE_ADDR_H)); + soc_ifc_reg_hwif_in.SS_CALIPTRA_DMA_AXI_USER.user.we = strap_we_pre_fuse_done | (cptra_uncore_dmi_unlocked_reg_wr_en & + (cptra_uncore_dmi_reg_addr == DMI_REG_SS_STRAP_CALIPTRA_DMA_AXI_USER)); + soc_ifc_reg_hwif_in.SS_STRAP_GENERIC[0].data.we = strap_we_pre_fuse_done | (cptra_uncore_dmi_unlocked_reg_wr_en & + (cptra_uncore_dmi_reg_addr == DMI_REG_SS_STRAP_GENERIC_0)); + soc_ifc_reg_hwif_in.SS_STRAP_GENERIC[1].data.we = strap_we_pre_fuse_done | (cptra_uncore_dmi_unlocked_reg_wr_en & + (cptra_uncore_dmi_reg_addr == DMI_REG_SS_STRAP_GENERIC_1)); + soc_ifc_reg_hwif_in.SS_STRAP_GENERIC[2].data.we = strap_we_pre_fuse_done | (cptra_uncore_dmi_unlocked_reg_wr_en & + (cptra_uncore_dmi_reg_addr == DMI_REG_SS_STRAP_GENERIC_2)); + soc_ifc_reg_hwif_in.SS_STRAP_GENERIC[3].data.we = strap_we_pre_fuse_done | (cptra_uncore_dmi_unlocked_reg_wr_en & + (cptra_uncore_dmi_reg_addr == DMI_REG_SS_STRAP_GENERIC_3)); + soc_ifc_reg_hwif_in.SS_DEBUG_INTENT.debug_intent.we = strap_we_pre_fuse_done | (cptra_uncore_dmi_unlocked_reg_wr_en & + (cptra_uncore_dmi_reg_addr == DMI_REG_SS_DEBUG_INTENT)); + //SS REGISTERS WITH TAP WRITE ACCESS + soc_ifc_reg_hwif_in.SS_DBG_SERVICE_REG_REQ.MANUF_DBG_UNLOCK_REQ.we = (cptra_uncore_dmi_locked_reg_wr_en & + (security_state.device_lifecycle inside {DEVICE_MANUFACTURING, DEVICE_UNPROVISIONED}) & + (cptra_uncore_dmi_reg_addr == DMI_REG_SS_DBG_SERVICE_REG_REQ)); + soc_ifc_reg_hwif_in.SS_DBG_SERVICE_REG_REQ.PROD_DBG_UNLOCK_REQ.we = (cptra_uncore_dmi_locked_reg_wr_en & + (cptra_uncore_dmi_reg_addr == DMI_REG_SS_DBG_SERVICE_REG_REQ)); + soc_ifc_reg_hwif_in.SS_DBG_SERVICE_REG_REQ.UDS_PROGRAM_REQ.we = (cptra_uncore_dmi_locked_reg_wr_en & + (security_state.device_lifecycle inside {DEVICE_MANUFACTURING, DEVICE_UNPROVISIONED}) & + (cptra_uncore_dmi_reg_addr == DMI_REG_SS_DBG_SERVICE_REG_REQ)); + soc_ifc_reg_hwif_in.SS_SOC_DBG_UNLOCK_LEVEL[0].LEVEL.we = (cptra_uncore_dmi_unlocked_reg_wr_en & + (cptra_uncore_dmi_reg_addr == DMI_REG_SS_DBG_UNLOCK_LEVEL0)); + soc_ifc_reg_hwif_in.SS_SOC_DBG_UNLOCK_LEVEL[1].LEVEL.we = (cptra_uncore_dmi_unlocked_reg_wr_en & + (cptra_uncore_dmi_reg_addr == DMI_REG_SS_DBG_UNLOCK_LEVEL1)); + //STRAPS WITH RO or NO TAP ACCESS + soc_ifc_reg_hwif_in.SS_UDS_SEED_BASE_ADDR_L.addr_l.we = strap_we_pre_fuse_done; //RO by TAP + soc_ifc_reg_hwif_in.SS_UDS_SEED_BASE_ADDR_H.addr_h.we = strap_we_pre_fuse_done; //RO by TAP + soc_ifc_reg_hwif_in.SS_KEY_RELEASE_BASE_ADDR_L.addr_l.we = strap_we_pre_fuse_done; //RO by TAP + soc_ifc_reg_hwif_in.SS_KEY_RELEASE_BASE_ADDR_H.addr_h.we = strap_we_pre_fuse_done; //RO by TAP + soc_ifc_reg_hwif_in.SS_KEY_RELEASE_SIZE.size.we = strap_we_pre_fuse_done; //RO by TAP + soc_ifc_reg_hwif_in.SS_PROD_DEBUG_UNLOCK_AUTH_PK_HASH_REG_BANK_OFFSET.offset.we = strap_we_pre_fuse_done; //No TAP access + soc_ifc_reg_hwif_in.SS_NUM_OF_PROD_DEBUG_UNLOCK_AUTH_PK_HASHES.num.we = strap_we_pre_fuse_done; //No TAP access +end + +always_comb begin : ss_reg_next_vals + //SS STRAPS WITH TAP WRITE ACCESS + soc_ifc_reg_hwif_in.SS_CALIPTRA_BASE_ADDR_L.addr_l.next = strap_we_pre_fuse_done ? strap_ss_caliptra_base_addr[31:0] : cptra_uncore_dmi_reg_wdata; + soc_ifc_reg_hwif_in.SS_CALIPTRA_BASE_ADDR_H.addr_h.next = strap_we_pre_fuse_done ? strap_ss_caliptra_base_addr[63:32] : cptra_uncore_dmi_reg_wdata; + soc_ifc_reg_hwif_in.SS_MCI_BASE_ADDR_L.addr_l.next = strap_we_pre_fuse_done ? strap_ss_mci_base_addr[31:0] : cptra_uncore_dmi_reg_wdata; + soc_ifc_reg_hwif_in.SS_MCI_BASE_ADDR_H.addr_h.next = strap_we_pre_fuse_done ? strap_ss_mci_base_addr[63:32] : cptra_uncore_dmi_reg_wdata; + soc_ifc_reg_hwif_in.SS_RECOVERY_IFC_BASE_ADDR_L.addr_l.next = strap_we_pre_fuse_done ? strap_ss_recovery_ifc_base_addr[31:0] : cptra_uncore_dmi_reg_wdata; + soc_ifc_reg_hwif_in.SS_RECOVERY_IFC_BASE_ADDR_H.addr_h.next = strap_we_pre_fuse_done ? strap_ss_recovery_ifc_base_addr[63:32] : cptra_uncore_dmi_reg_wdata; + soc_ifc_reg_hwif_in.SS_EXTERNAL_STAGING_AREA_BASE_ADDR_L.addr_l.next = strap_we_pre_fuse_done ? strap_ss_external_staging_area_base_addr[31:0] : cptra_uncore_dmi_reg_wdata; + soc_ifc_reg_hwif_in.SS_EXTERNAL_STAGING_AREA_BASE_ADDR_H.addr_h.next = strap_we_pre_fuse_done ? strap_ss_external_staging_area_base_addr[63:32] : cptra_uncore_dmi_reg_wdata; + soc_ifc_reg_hwif_in.SS_OTP_FC_BASE_ADDR_L.addr_l.next = strap_we_pre_fuse_done ? strap_ss_otp_fc_base_addr[31:0] : cptra_uncore_dmi_reg_wdata; + soc_ifc_reg_hwif_in.SS_OTP_FC_BASE_ADDR_H.addr_h.next = strap_we_pre_fuse_done ? strap_ss_otp_fc_base_addr[63:32] : cptra_uncore_dmi_reg_wdata; + soc_ifc_reg_hwif_in.SS_CALIPTRA_DMA_AXI_USER.user.next = strap_we_pre_fuse_done ? strap_ss_caliptra_dma_axi_user : cptra_uncore_dmi_reg_wdata; + soc_ifc_reg_hwif_in.SS_STRAP_GENERIC[0].data.next = strap_we_pre_fuse_done ? strap_ss_strap_generic_0 : cptra_uncore_dmi_reg_wdata; + soc_ifc_reg_hwif_in.SS_STRAP_GENERIC[1].data.next = strap_we_pre_fuse_done ? strap_ss_strap_generic_1 : cptra_uncore_dmi_reg_wdata; + soc_ifc_reg_hwif_in.SS_STRAP_GENERIC[2].data.next = strap_we_pre_fuse_done ? strap_ss_strap_generic_2 : cptra_uncore_dmi_reg_wdata; + soc_ifc_reg_hwif_in.SS_STRAP_GENERIC[3].data.next = strap_we_pre_fuse_done ? strap_ss_strap_generic_3 : cptra_uncore_dmi_reg_wdata; + //SS REGISTERS WITH TAP WRITE ACCESS + soc_ifc_reg_hwif_in.SS_DBG_SERVICE_REG_REQ.MANUF_DBG_UNLOCK_REQ.next = cptra_uncore_dmi_reg_wdata[0]; + soc_ifc_reg_hwif_in.SS_DBG_SERVICE_REG_REQ.PROD_DBG_UNLOCK_REQ.next = cptra_uncore_dmi_reg_wdata[1]; + soc_ifc_reg_hwif_in.SS_DBG_SERVICE_REG_REQ.UDS_PROGRAM_REQ.next = cptra_uncore_dmi_reg_wdata[2]; + soc_ifc_reg_hwif_in.SS_DBG_SERVICE_REG_REQ.RSVD.next[28:0] = 29'h0; + soc_ifc_reg_hwif_in.SS_SOC_DBG_UNLOCK_LEVEL[0].LEVEL.next = cptra_uncore_dmi_reg_wdata; + soc_ifc_reg_hwif_in.SS_SOC_DBG_UNLOCK_LEVEL[1].LEVEL.next = cptra_uncore_dmi_reg_wdata; + //STRAPS WITH RO or NO TAP ACCESS + soc_ifc_reg_hwif_in.SS_UDS_SEED_BASE_ADDR_L.addr_l.next = strap_ss_uds_seed_base_addr[31:0]; + soc_ifc_reg_hwif_in.SS_UDS_SEED_BASE_ADDR_H.addr_h.next = strap_ss_uds_seed_base_addr[63:32]; + soc_ifc_reg_hwif_in.SS_KEY_RELEASE_BASE_ADDR_L.addr_l.next = strap_ss_key_release_base_addr[31:0]; + soc_ifc_reg_hwif_in.SS_KEY_RELEASE_BASE_ADDR_H.addr_h.next = strap_ss_key_release_base_addr[63:32]; + soc_ifc_reg_hwif_in.SS_KEY_RELEASE_SIZE.size.next = {strap_ss_key_release_key_size[15:2],2'b00}; // Enforce dw-multiple + soc_ifc_reg_hwif_in.SS_PROD_DEBUG_UNLOCK_AUTH_PK_HASH_REG_BANK_OFFSET.offset.next = strap_ss_prod_debug_unlock_auth_pk_hash_reg_bank_offset; + soc_ifc_reg_hwif_in.SS_NUM_OF_PROD_DEBUG_UNLOCK_AUTH_PK_HASHES.num.next = strap_ss_num_of_prod_debug_unlock_auth_pk_hashes; + + // Debug intent is latched on rising edge of cptra_pwrgood and may not be modified until cold reset + // Debug intent register is only populated in Subsystem mode. Passive mode uses + // legacy debug unlock flow + `ifdef CALIPTRA_MODE_SUBSYSTEM + soc_ifc_reg_hwif_in.SS_DEBUG_INTENT.debug_intent.next = strap_we_pre_fuse_done ? ss_debug_intent : cptra_uncore_dmi_reg_wdata[0]; + `else + soc_ifc_reg_hwif_in.SS_DEBUG_INTENT.debug_intent.next = 1'b0; + `endif +end + +always_comb cptra_ss_debug_intent = soc_ifc_reg_hwif_out.SS_DEBUG_INTENT.debug_intent.value; + +// Also RW-able by SW until CPTRA_FUSE_WR_DONE +always_comb soc_ifc_reg_hwif_in.SS_CALIPTRA_BASE_ADDR_L.addr_l.swwel = soc_ifc_reg_hwif_out.CPTRA_FUSE_WR_DONE.done.value; +always_comb soc_ifc_reg_hwif_in.SS_CALIPTRA_BASE_ADDR_H.addr_h.swwel = soc_ifc_reg_hwif_out.CPTRA_FUSE_WR_DONE.done.value; +always_comb soc_ifc_reg_hwif_in.SS_MCI_BASE_ADDR_L.addr_l.swwel = soc_ifc_reg_hwif_out.CPTRA_FUSE_WR_DONE.done.value; +always_comb soc_ifc_reg_hwif_in.SS_MCI_BASE_ADDR_H.addr_h.swwel = soc_ifc_reg_hwif_out.CPTRA_FUSE_WR_DONE.done.value; +always_comb soc_ifc_reg_hwif_in.SS_RECOVERY_IFC_BASE_ADDR_L.addr_l.swwel = soc_ifc_reg_hwif_out.CPTRA_FUSE_WR_DONE.done.value; +always_comb soc_ifc_reg_hwif_in.SS_RECOVERY_IFC_BASE_ADDR_H.addr_h.swwel = soc_ifc_reg_hwif_out.CPTRA_FUSE_WR_DONE.done.value; +always_comb soc_ifc_reg_hwif_in.SS_EXTERNAL_STAGING_AREA_BASE_ADDR_L.addr_l.swwel = soc_ifc_reg_hwif_out.CPTRA_FUSE_WR_DONE.done.value; +always_comb soc_ifc_reg_hwif_in.SS_EXTERNAL_STAGING_AREA_BASE_ADDR_H.addr_h.swwel = soc_ifc_reg_hwif_out.CPTRA_FUSE_WR_DONE.done.value; +always_comb soc_ifc_reg_hwif_in.SS_OTP_FC_BASE_ADDR_L.addr_l.swwel = soc_ifc_reg_hwif_out.CPTRA_FUSE_WR_DONE.done.value; +always_comb soc_ifc_reg_hwif_in.SS_OTP_FC_BASE_ADDR_H.addr_h.swwel = soc_ifc_reg_hwif_out.CPTRA_FUSE_WR_DONE.done.value; +always_comb soc_ifc_reg_hwif_in.SS_UDS_SEED_BASE_ADDR_L.addr_l.swwel = soc_ifc_reg_hwif_out.CPTRA_FUSE_WR_DONE.done.value; +always_comb soc_ifc_reg_hwif_in.SS_UDS_SEED_BASE_ADDR_H.addr_h.swwel = soc_ifc_reg_hwif_out.CPTRA_FUSE_WR_DONE.done.value; +always_comb soc_ifc_reg_hwif_in.SS_PROD_DEBUG_UNLOCK_AUTH_PK_HASH_REG_BANK_OFFSET.offset.swwel = soc_ifc_reg_hwif_out.CPTRA_FUSE_WR_DONE.done.value; +always_comb soc_ifc_reg_hwif_in.SS_NUM_OF_PROD_DEBUG_UNLOCK_AUTH_PK_HASHES.num.swwel = soc_ifc_reg_hwif_out.CPTRA_FUSE_WR_DONE.done.value; +always_comb soc_ifc_reg_hwif_in.SS_CALIPTRA_DMA_AXI_USER.user.swwel = soc_ifc_reg_hwif_out.CPTRA_FUSE_WR_DONE.done.value; +always_comb soc_ifc_reg_hwif_in.SS_KEY_RELEASE_BASE_ADDR_L.addr_l.swwel = soc_ifc_reg_hwif_out.CPTRA_FUSE_WR_DONE.done.value; +always_comb soc_ifc_reg_hwif_in.SS_KEY_RELEASE_BASE_ADDR_H.addr_h.swwel = soc_ifc_reg_hwif_out.CPTRA_FUSE_WR_DONE.done.value; +always_comb soc_ifc_reg_hwif_in.SS_KEY_RELEASE_SIZE.size.swwel = soc_ifc_reg_hwif_out.CPTRA_FUSE_WR_DONE.done.value; +always_comb soc_ifc_reg_hwif_in.SS_STRAP_GENERIC[0].data.swwel = soc_ifc_reg_hwif_out.CPTRA_FUSE_WR_DONE.done.value; +always_comb soc_ifc_reg_hwif_in.SS_STRAP_GENERIC[1].data.swwel = soc_ifc_reg_hwif_out.CPTRA_FUSE_WR_DONE.done.value; +always_comb soc_ifc_reg_hwif_in.SS_STRAP_GENERIC[2].data.swwel = soc_ifc_reg_hwif_out.CPTRA_FUSE_WR_DONE.done.value; +always_comb soc_ifc_reg_hwif_in.SS_STRAP_GENERIC[3].data.swwel = soc_ifc_reg_hwif_out.CPTRA_FUSE_WR_DONE.done.value; + +// DEBUG service request signals are writable based on lifecycle state +always_comb soc_ifc_reg_hwif_in.SS_DBG_SERVICE_REG_REQ.MANUF_DBG_UNLOCK_REQ.swwe = soc_ifc_reg_hwif_out.SS_DEBUG_INTENT.debug_intent.value && (security_state.device_lifecycle == DEVICE_MANUFACTURING); +always_comb soc_ifc_reg_hwif_in.SS_DBG_SERVICE_REG_REQ.PROD_DBG_UNLOCK_REQ.swwe = soc_ifc_reg_hwif_out.SS_DEBUG_INTENT.debug_intent.value && (security_state.device_lifecycle == DEVICE_PRODUCTION); +always_comb soc_ifc_reg_hwif_in.SS_DBG_SERVICE_REG_REQ.UDS_PROGRAM_REQ.swwe = '0; //RO from sw + +// DEBUG service response signals are writable based on lifecycle state; success bits are also sticky until reset +always_comb soc_ifc_reg_hwif_in.SS_DBG_SERVICE_REG_RSP.MANUF_DBG_UNLOCK_SUCCESS .swwe = !soc_ifc_reg_req_data.soc_req && soc_ifc_reg_hwif_out.SS_DEBUG_INTENT.debug_intent.value && (security_state.device_lifecycle == DEVICE_MANUFACTURING) && !soc_ifc_reg_hwif_out.SS_DBG_SERVICE_REG_RSP.MANUF_DBG_UNLOCK_SUCCESS.value; +always_comb soc_ifc_reg_hwif_in.SS_DBG_SERVICE_REG_RSP.MANUF_DBG_UNLOCK_FAIL .swwe = !soc_ifc_reg_req_data.soc_req && soc_ifc_reg_hwif_out.SS_DEBUG_INTENT.debug_intent.value && (security_state.device_lifecycle == DEVICE_MANUFACTURING); +always_comb soc_ifc_reg_hwif_in.SS_DBG_SERVICE_REG_RSP.MANUF_DBG_UNLOCK_IN_PROGRESS.swwe = !soc_ifc_reg_req_data.soc_req && soc_ifc_reg_hwif_out.SS_DEBUG_INTENT.debug_intent.value && (security_state.device_lifecycle == DEVICE_MANUFACTURING); +always_comb soc_ifc_reg_hwif_in.SS_DBG_SERVICE_REG_RSP.PROD_DBG_UNLOCK_SUCCESS .swwe = !soc_ifc_reg_req_data.soc_req && soc_ifc_reg_hwif_out.SS_DEBUG_INTENT.debug_intent.value && (security_state.device_lifecycle == DEVICE_PRODUCTION) && !soc_ifc_reg_hwif_out.SS_DBG_SERVICE_REG_RSP.PROD_DBG_UNLOCK_SUCCESS.value; +always_comb soc_ifc_reg_hwif_in.SS_DBG_SERVICE_REG_RSP.PROD_DBG_UNLOCK_FAIL .swwe = !soc_ifc_reg_req_data.soc_req && soc_ifc_reg_hwif_out.SS_DEBUG_INTENT.debug_intent.value && (security_state.device_lifecycle == DEVICE_PRODUCTION); +always_comb soc_ifc_reg_hwif_in.SS_DBG_SERVICE_REG_RSP.PROD_DBG_UNLOCK_IN_PROGRESS .swwe = !soc_ifc_reg_req_data.soc_req && soc_ifc_reg_hwif_out.SS_DEBUG_INTENT.debug_intent.value && (security_state.device_lifecycle == DEVICE_PRODUCTION); +always_comb soc_ifc_reg_hwif_in.SS_DBG_SERVICE_REG_RSP.UDS_PROGRAM_SUCCESS .swwe = !soc_ifc_reg_req_data.soc_req; //Caliptra access only to this register field. +always_comb soc_ifc_reg_hwif_in.SS_DBG_SERVICE_REG_RSP.UDS_PROGRAM_FAIL .swwe = !soc_ifc_reg_req_data.soc_req; //Caliptra access only to this register field. +always_comb soc_ifc_reg_hwif_in.SS_DBG_SERVICE_REG_RSP.UDS_PROGRAM_IN_PROGRESS .swwe = !soc_ifc_reg_req_data.soc_req; //Caliptra access only to this register field. +always_comb soc_ifc_reg_hwif_in.SS_DBG_SERVICE_REG_RSP.TAP_MAILBOX_AVAILABLE .swwe = !soc_ifc_reg_req_data.soc_req; +always_comb soc_ifc_reg_hwif_in.SS_DBG_SERVICE_REG_RSP.RSVD.next = '0; + +always_comb ss_dbg_manuf_enable = soc_ifc_reg_hwif_out.SS_DBG_SERVICE_REG_RSP.MANUF_DBG_UNLOCK_SUCCESS.value; + +// DEBUG unlock level signal is only writable by Caliptra, and only when DEBUG_INTENT is 1 +always_comb begin + for (int i=0; i<2; i++) begin + soc_ifc_reg_hwif_in.SS_SOC_DBG_UNLOCK_LEVEL[i].LEVEL.swwel = soc_ifc_reg_req_data.soc_req || !soc_ifc_reg_hwif_out.SS_DEBUG_INTENT.debug_intent.value; + end +end +always_comb ss_soc_dbg_unlock_level = {soc_ifc_reg_hwif_out.SS_SOC_DBG_UNLOCK_LEVEL[1].LEVEL.value, + soc_ifc_reg_hwif_out.SS_SOC_DBG_UNLOCK_LEVEL[0].LEVEL.value}; + +always_comb ss_generic_fw_exec_ctrl = {soc_ifc_reg_hwif_out.SS_GENERIC_FW_EXEC_CTRL[3].go.value, + soc_ifc_reg_hwif_out.SS_GENERIC_FW_EXEC_CTRL[2].go.value, + soc_ifc_reg_hwif_out.SS_GENERIC_FW_EXEC_CTRL[1].go.value, + soc_ifc_reg_hwif_out.SS_GENERIC_FW_EXEC_CTRL[0].go.value}; + +// Fuse write done can be written by SOC if it is already NOT '1. +// uController can only read this bit. The bit gets reset on cold reset +always_comb soc_ifc_reg_hwif_in.CPTRA_FUSE_WR_DONE.done.swwe = soc_ifc_reg_req_data.soc_req & ~soc_ifc_reg_hwif_out.CPTRA_FUSE_WR_DONE.done.value; +// CPTRA_CAP_LOCK is a lockable register. +// "lock" can be written by Caliptra if it is already NOT '1. SoC can only read this bit. The bit gets reset on warm reset +always_comb soc_ifc_reg_hwif_in.CPTRA_CAP_LOCK.lock.swwel = soc_ifc_reg_req_data.soc_req || soc_ifc_reg_hwif_out.CPTRA_CAP_LOCK.lock.value; +// OWNER PK HASH LOCK is a lockable register. +// "lock" can be written by SOC if it is already NOT '1. uController can only read this bit. The bit gets reset on cold reset +always_comb soc_ifc_reg_hwif_in.CPTRA_OWNER_PK_HASH_LOCK.lock.swwe = soc_ifc_reg_req_data.soc_req & ~soc_ifc_reg_hwif_out.CPTRA_OWNER_PK_HASH_LOCK.lock.value; +///////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +//When TRNG_AXI_USER_LOCK is one only allow valid users to write to TRNG +//If TRNG_AXI_USER_LOCK is zero allow any user to write to TRNG +always_comb valid_trng_user = soc_ifc_reg_req_data.soc_req & (~soc_ifc_reg_hwif_out.CPTRA_TRNG_AXI_USER_LOCK.LOCK.value | + (soc_ifc_reg_req_data.user == soc_ifc_reg_hwif_out.CPTRA_TRNG_VALID_AXI_USER.AXI_USER.value[AXI_USER_WIDTH-1:0])); + +always_comb soc_ifc_reg_hwif_in.CPTRA_TRNG_STATUS.DATA_WR_DONE.swwe = valid_trng_user; + +always_comb begin + for (int i = 0; i < 12; i++) begin + soc_ifc_reg_hwif_in.CPTRA_TRNG_DATA[i].DATA.swwe = valid_trng_user; + soc_ifc_reg_hwif_in.CPTRA_TRNG_DATA[i].DATA.hwclr = soc_ifc_reg_hwif_out.CPTRA_TRNG_CTRL.clear.value; + end +end + +//Clear the DATA_WR_DONE when FW clears the req bit +always_comb soc_ifc_reg_hwif_in.CPTRA_TRNG_STATUS.DATA_WR_DONE.hwclr = ~soc_ifc_reg_hwif_out.CPTRA_TRNG_STATUS.DATA_REQ.value; + +generate + if (CPTRA_SET_FUSE_AXI_USER_INTEG) begin + always_comb valid_fuse_user = soc_req_dv & (soc_req.user == CPTRA_FUSE_VALID_AXI_USER); + end else begin + always_comb valid_fuse_user = soc_req_dv & (~soc_ifc_reg_hwif_out.CPTRA_FUSE_AXI_USER_LOCK.LOCK.value | + (soc_req.user == soc_ifc_reg_hwif_out.CPTRA_FUSE_VALID_AXI_USER.AXI_USER.value[AXI_USER_WIDTH-1:0])); + end +endgenerate + +always_comb valid_sha_user = soc_req_dv & (soc_req.user == soc_ifc_reg_hwif_out.SS_CALIPTRA_DMA_AXI_USER.user.value); + + +// Generate a pulse to set the interrupt bit +always_ff @(posedge soc_ifc_clk_cg or negedge cptra_noncore_rst_b) begin + if (~cptra_noncore_rst_b) begin + uc_mbox_data_avail_d <= '0; + end + else begin + uc_mbox_data_avail_d <= uc_mbox_data_avail; + end +end + +always_comb uc_cmd_avail_p = uc_mbox_data_avail & !uc_mbox_data_avail_d; +// Pulse input to soc_ifc_reg to set the interrupt status bit and generate interrupt output (if enabled) +always_comb soc_ifc_reg_hwif_in.intr_block_rf.error_internal_intr_r.error_internal_sts.hwset = 1'b0; // TODO +always_comb soc_ifc_reg_hwif_in.intr_block_rf.error_internal_intr_r.error_inv_dev_sts.hwset = mbox_inv_user_p; // All invalid user, or only 'valid user but != mbox_user.user'? +always_comb soc_ifc_reg_hwif_in.intr_block_rf.error_internal_intr_r.error_cmd_fail_sts.hwset = |mbox_protocol_error; // Set by any protocol error violation (mirrors the bits in CPTRA_HW_ERROR_NON_FATAL) +always_comb soc_ifc_reg_hwif_in.intr_block_rf.error_internal_intr_r.error_bad_fuse_sts.hwset = 1'b0; // TODO +always_comb soc_ifc_reg_hwif_in.intr_block_rf.error_internal_intr_r.error_iccm_blocked_sts.hwset = iccm_axs_blocked; +always_comb soc_ifc_reg_hwif_in.intr_block_rf.error_internal_intr_r.error_mbox_ecc_unc_sts.hwset = sram_double_ecc_error; +always_comb soc_ifc_reg_hwif_in.intr_block_rf.notif_internal_intr_r.notif_cmd_avail_sts.hwset = uc_cmd_avail_p; +always_comb soc_ifc_reg_hwif_in.intr_block_rf.notif_internal_intr_r.notif_mbox_ecc_cor_sts.hwset = sram_single_ecc_error; +always_comb soc_ifc_reg_hwif_in.intr_block_rf.notif_internal_intr_r.notif_debug_locked_sts.hwset = security_state_debug_locked_p; // Any transition results in interrupt +always_comb soc_ifc_reg_hwif_in.intr_block_rf.notif_internal_intr_r.notif_scan_mode_sts.hwset = scan_mode_p; // Posedge results in interrupt +always_comb soc_ifc_reg_hwif_in.intr_block_rf.notif_internal_intr_r.notif_soc_req_lock_sts.hwset = soc_req_mbox_lock; +always_comb soc_ifc_reg_hwif_in.intr_block_rf.notif_internal_intr_r.notif_gen_in_toggle_sts.hwset = |generic_input_toggle; +always_comb soc_ifc_reg_hwif_in.intr_block_rf.error_internal_intr_r.error_wdt_timer1_timeout_sts.hwset = t1_timeout_p; +always_comb soc_ifc_reg_hwif_in.intr_block_rf.error_internal_intr_r.error_wdt_timer2_timeout_sts.hwset = t2_timeout_p && timer2_en; + +always_comb soc_ifc_reg_hwif_in.internal_iccm_lock.lock.hwclr = iccm_unlock; + + + + +logic [SOC_IFC_DATA_W-1:0] s_cpuif_wr_biten; +logic s_cpuif_req_stall_wr_nc; +logic s_cpuif_req_stall_rd_nc; +logic s_cpuif_rd_ack_nc; +logic s_cpuif_wr_ack_nc; + +always_comb begin + for (int i=0;i= + {soc_ifc_reg_hwif_out.internal_rv_mtimecmp_h.compare_h.value,soc_ifc_reg_hwif_out.internal_rv_mtimecmp_l.compare_l.value}; + +//SHA Accelerator +sha512_acc_top #( + .DATA_WIDTH(AXI_DATA_WIDTH) +) +i_sha512_acc_top ( + .clk(soc_ifc_clk_cg), + .rst_b(cptra_noncore_rst_b), + .cptra_pwrgood(cptra_pwrgood), + + .req_dv(sha_req_dv), + .req_hold(sha_req_hold), + .req_data(sha_req_data), + + .rdata(sha_rdata), + .err(sha_error), + + .sha_sram_req_dv(sha_sram_req_dv), + .sha_sram_req_addr(sha_sram_req_addr), + .sha_sram_resp(sha_sram_resp), + .sha_sram_hold(sha_sram_hold), + + .error_intr(sha_error_intr), + .notif_intr(sha_notif_intr) +); + +//Mailbox +//This module contains the Caliptra Mailbox and associated control logic +//The SoC and uC can read and write to the mailbox by following the Caliptra Mailbox Protocol +mbox +#( + .DMI_REG_MBOX_LOCK_ADDR(soc_ifc_pkg::DMI_REG_MBOX_LOCK), + .DMI_REG_MBOX_DLEN_ADDR(soc_ifc_pkg::DMI_REG_MBOX_DLEN), + .DMI_REG_MBOX_CMD_ADDR(soc_ifc_pkg::DMI_REG_MBOX_CMD), + .DMI_REG_MBOX_EXECUTE_ADDR(soc_ifc_pkg::DMI_REG_MBOX_EXECUTE), + .DMI_REG_MBOX_STATUS_ADDR(soc_ifc_pkg::DMI_REG_MBOX_STATUS), + .MBOX_SIZE_KB(CPTRA_MBOX_SIZE_KB), + .MBOX_DATA_W(CPTRA_MBOX_DATA_W), + .MBOX_ECC_DATA_W(CPTRA_MBOX_ECC_DATA_W), + .MBOX_IFC_DATA_W(SOC_IFC_DATA_W), + .MBOX_IFC_USER_W(SOC_IFC_USER_W), + .MBOX_IFC_ADDR_W(SOC_IFC_ADDR_W) +) +i_mbox ( + .clk(soc_ifc_clk_cg), + .rst_b(cptra_noncore_rst_b), + .req_dv(mbox_req_dv), + .req_hold(mbox_req_hold), + .dir_req_dv(mbox_dir_req_dv), + .req_data_addr(mbox_req_data.addr), + .req_data_wdata(mbox_req_data.wdata), + .req_data_wstrb(mbox_req_data.wstrb), + .req_data_user(mbox_req_data.user), + .req_data_write(mbox_req_data.write), + .req_data_soc_req(mbox_req_data.soc_req), + .mbox_error(mbox_error), + .rdata(mbox_rdata), + .dir_rdata(mbox_dir_rdata), + .sha_sram_req_dv(sha_sram_req_dv), + .sha_sram_req_addr(sha_sram_req_addr), + .sha_sram_resp_ecc(sha_sram_resp.rdata.ecc), + .sha_sram_resp_data(sha_sram_resp.rdata.data), + .sha_sram_hold(sha_sram_hold), + .dma_sram_req_dv (dma_sram_req_dv ), + .dma_sram_req_write(dma_sram_req_data.write), + .dma_sram_req_addr(dma_sram_req_data.addr), + .dma_sram_req_wdata(dma_sram_req_data.wdata), + .dma_sram_rdata (dma_sram_rdata ), + .dma_sram_hold (dma_sram_req_hold), + .dma_sram_error (dma_sram_error ), + .mbox_sram_req_cs(mbox_sram_req.cs), + .mbox_sram_req_we(mbox_sram_req.we), + .mbox_sram_req_addr(mbox_sram_req.addr), + .mbox_sram_req_ecc(mbox_sram_req.wdata.ecc), + .mbox_sram_req_wdata(mbox_sram_req.wdata.data), + .mbox_sram_resp_ecc(mbox_sram_resp.rdata.ecc), + .mbox_sram_resp_data(mbox_sram_resp.rdata.data), + .sram_single_ecc_error(sram_single_ecc_error), + .sram_double_ecc_error(sram_double_ecc_error), + .uc_mbox_lock(uc_mbox_lock), + .soc_mbox_data_avail(mailbox_data_avail), + .uc_mbox_data_avail(uc_mbox_data_avail), + .soc_req_mbox_lock(soc_req_mbox_lock), + .mbox_protocol_error(mbox_protocol_error), + .mbox_inv_axi_user_axs(mbox_inv_user_p), + .dmi_mbox_avail(soc_ifc_reg_hwif_out.SS_DBG_SERVICE_REG_RSP.TAP_MAILBOX_AVAILABLE.value), + .dmi_inc_rdptr(dmi_inc_rdptr), + .dmi_inc_wrptr(dmi_inc_wrptr), + .dmi_reg_wen(cptra_uncore_dmi_locked_reg_wr_en), + .dmi_reg_ren(cptra_uncore_dmi_locked_reg_en & ~cptra_uncore_dmi_reg_wr_en), + .dmi_reg_addr(cptra_uncore_dmi_reg_addr), + .dmi_reg_wdata(cptra_uncore_dmi_reg_wdata), + .dmi_reg(mbox_dmi_reg) +); + +// AXI Manager (DMA) +axi_dma_top #( + .AW(AXIM_ADDR_WIDTH), // Addr Width + .DW(AXIM_DATA_WIDTH), // Data Width + .UW(AXIM_USER_WIDTH), // User Width + .IW(AXIM_ID_WIDTH) // ID Width +) i_axi_dma ( + .clk (rdc_clk_cg ), + .cptra_pwrgood(cptra_pwrgood ), + .rst_n (cptra_noncore_rst_b), + + // Recovery INF Interrupt + // Should only assert when a full block_size of data is available at the + // recovery interface FIFO + .recovery_data_avail(recovery_data_avail), + .recovery_image_activated(recovery_image_activated), + + // SOC_IFC Internal Signaling + .mbox_lock(uc_mbox_lock), + .sha_lock (1'b0 ), // SHA direct-access (internally) not implemented; DMA can use AXI-side for SHA operations + .debugUnlock_or_scan_mode_switch(debugUnlock_or_scan_mode_switch ), + .ocp_lock_in_progress (ss_ocp_lock_in_progress ), + .key_release_addr ({soc_ifc_reg_hwif_out.SS_KEY_RELEASE_BASE_ADDR_H.addr_h.value, + soc_ifc_reg_hwif_out.SS_KEY_RELEASE_BASE_ADDR_L.addr_l.value}), + .key_release_size (ss_key_release_key_size ), + + // kv interface + .kv_read (kv_read ), + .kv_rd_resp(kv_rd_resp), + + // Configuration for requests + .axuser(AXIM_USER_WIDTH'(soc_ifc_reg_hwif_out.SS_CALIPTRA_DMA_AXI_USER.user.value)), + + // AXI INF + .m_axi_w_if(m_axi_w_if), + .m_axi_r_if(m_axi_r_if), + + // Component INF + .dv (dma_reg_req_dv ), + .req_data(dma_reg_req_data), + .hold (dma_reg_req_hold), + .rdata (dma_reg_rdata ), + .error (dma_reg_error ), + + // AES IF + .aes_input_ready, + .aes_output_valid, + .aes_status_idle, + .aes_req_dv(aes_req_dv), + .aes_req_hold(aes_req_hold), + .aes_req_data(aes_req_data), + .aes_rdata(aes_rdata), + .aes_err(aes_error), + + + // Mailbox SRAM INF + .mb_dv (dma_sram_req_dv ), + .mb_hold (dma_sram_req_hold), + .mb_error(dma_sram_error ), + .mb_data (dma_sram_req_data), + .mb_rdata(dma_sram_rdata ), + + // Interrupt + .notif_intr(dma_notif_intr), + .error_intr(dma_error_intr) + +); + +//------------------------- +//Watchdog timer +//------------------------- +assign timer1_en = soc_ifc_reg_hwif_out.CPTRA_WDT_TIMER1_EN.timer1_en.value; +assign timer2_en = soc_ifc_reg_hwif_out.CPTRA_WDT_TIMER2_EN.timer2_en.value; +assign timer1_restart = soc_ifc_reg_hwif_out.CPTRA_WDT_TIMER1_CTRL.timer1_restart.value; +assign timer2_restart = soc_ifc_reg_hwif_out.CPTRA_WDT_TIMER2_CTRL.timer2_restart.value; + +for (genvar i = 0; i < SOC_IFC_WDT_TIMEOUT_PERIOD_NUM_DWORDS; i++) begin + assign timer1_timeout_period[i] = soc_ifc_reg_hwif_out.CPTRA_WDT_TIMER1_TIMEOUT_PERIOD[i].timer1_timeout_period.value; + assign timer2_timeout_period[i] = soc_ifc_reg_hwif_out.CPTRA_WDT_TIMER2_TIMEOUT_PERIOD[i].timer2_timeout_period.value; +end + +//Set WDT status reg +always_comb begin + soc_ifc_reg_hwif_in.CPTRA_WDT_STATUS.t1_timeout.next = t1_timeout; + soc_ifc_reg_hwif_in.CPTRA_WDT_STATUS.t2_timeout.next = t2_timeout; +end + +//Generate t1 and t2 timeout interrupt pulse +always_ff @(posedge rdc_clk_cg or negedge cptra_noncore_rst_b) begin + if(!cptra_noncore_rst_b) begin + t1_timeout_f <= 'b0; + t2_timeout_f <= 'b0; + end + else begin + t1_timeout_f <= t1_timeout; + t2_timeout_f <= t2_timeout; + end +end + +always_comb t1_timeout_p = t1_timeout & ~t1_timeout_f; +always_comb t2_timeout_p = t2_timeout & ~t2_timeout_f; + +// NOTE: Since error_internal_intr_r is Write-1-to-clear, capture writes to the +// WDT interrupt bits to detect the interrupt being serviced. +// It would be preferable to decode this from interrupt signals somehow, +// but that would require modifying interrupt register RDL which has been +// standardized. +always_ff @(posedge soc_ifc_clk_cg or negedge cptra_noncore_rst_b) begin + if(!cptra_noncore_rst_b) begin + wdt_error_t1_intr_serviced <= 1'b0; + wdt_error_t2_intr_serviced <= 1'b0; + end + else if (soc_ifc_reg_req_dv && soc_ifc_reg_req_data.write && (soc_ifc_reg_req_data.addr[SOC_IFC_REG_ADDR_WIDTH-1:0] == SOC_IFC_REG_ADDR_WIDTH'(`SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R))) begin + wdt_error_t1_intr_serviced <= soc_ifc_reg_req_data.wdata[`SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_WDT_TIMER1_TIMEOUT_STS_LOW]; + wdt_error_t2_intr_serviced <= soc_ifc_reg_req_data.wdata[`SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_WDT_TIMER2_TIMEOUT_STS_LOW]; + end + else begin + wdt_error_t1_intr_serviced <= 1'b0; + wdt_error_t2_intr_serviced <= 1'b0; + end +end + +wdt #( + .WDT_TIMEOUT_PERIOD_NUM_DWORDS(SOC_IFC_WDT_TIMEOUT_PERIOD_NUM_DWORDS) +)i_wdt ( + .clk(rdc_clk_cg), + .cptra_rst_b(cptra_noncore_rst_b), + .timer1_en(timer1_en), + .timer2_en(timer2_en), + .timer1_restart(timer1_restart), + .timer2_restart(timer2_restart), + .timer1_timeout_period(timer1_timeout_period), + .timer2_timeout_period(timer2_timeout_period), + .wdt_timer1_timeout_serviced(wdt_error_t1_intr_serviced), + .wdt_timer2_timeout_serviced(wdt_error_t2_intr_serviced), + .t1_timeout(t1_timeout), + .t2_timeout(t2_timeout), + .fatal_timeout(nmi_intr) //Only issue nmi if WDT timers are cascaded and t2 times out +); + +//////////////////////////////////////////////////////// +// Write-enables for CPTRA_HW_ERROR_FATAL and CPTRA_HW_ERROR_NON_FATAL +// Also calculate whether or not an unmasked event is being set, so we can +// trigger the SOC interrupt signal +always_comb soc_ifc_reg_hwif_in.CPTRA_HW_ERROR_FATAL.crypto_err .we = crypto_error; +always_comb soc_ifc_reg_hwif_in.CPTRA_HW_ERROR_FATAL.iccm_ecc_unc.we = rv_ecc_sts.cptra_iccm_ecc_double_error & ~fw_update_rst_window; +always_comb soc_ifc_reg_hwif_in.CPTRA_HW_ERROR_FATAL.dccm_ecc_unc.we = rv_ecc_sts.cptra_dccm_ecc_double_error & ~fw_update_rst_window; +always_comb soc_ifc_reg_hwif_in.CPTRA_HW_ERROR_FATAL.nmi_pin .we = nmi_intr; +// Using we+next instead of hwset allows us to encode the reserved fields in some fashion +// other than bit-hot in the future, if needed (e.g. we need to encode > 32 FATAL events) +always_comb soc_ifc_reg_hwif_in.CPTRA_HW_ERROR_FATAL.crypto_err .next = 1'b1; +always_comb soc_ifc_reg_hwif_in.CPTRA_HW_ERROR_FATAL.iccm_ecc_unc.next = 1'b1; +always_comb soc_ifc_reg_hwif_in.CPTRA_HW_ERROR_FATAL.dccm_ecc_unc.next = 1'b1; +always_comb soc_ifc_reg_hwif_in.CPTRA_HW_ERROR_FATAL.nmi_pin .next = 1'b1; +always_comb soc_ifc_reg_hwif_in.CPTRA_HW_ERROR_FATAL.rsvd.next[27:0] = 28'h0; +// Flag the write even if the field being written to is already set to 1 - this is a new occurrence of the error and should trigger a new interrupt +always_comb unmasked_hw_error_fatal_write = (soc_ifc_reg_hwif_in.CPTRA_HW_ERROR_FATAL.crypto_err .we && |soc_ifc_reg_hwif_in.CPTRA_HW_ERROR_FATAL.crypto_err .next) || + (soc_ifc_reg_hwif_in.CPTRA_HW_ERROR_FATAL.iccm_ecc_unc.we && ~soc_ifc_reg_hwif_out.internal_hw_error_fatal_mask.mask_iccm_ecc_unc.value && |soc_ifc_reg_hwif_in.CPTRA_HW_ERROR_FATAL.iccm_ecc_unc.next) || + (soc_ifc_reg_hwif_in.CPTRA_HW_ERROR_FATAL.dccm_ecc_unc.we && ~soc_ifc_reg_hwif_out.internal_hw_error_fatal_mask.mask_dccm_ecc_unc.value && |soc_ifc_reg_hwif_in.CPTRA_HW_ERROR_FATAL.dccm_ecc_unc.next) || + (soc_ifc_reg_hwif_in.CPTRA_HW_ERROR_FATAL.nmi_pin .we && ~soc_ifc_reg_hwif_out.internal_hw_error_fatal_mask.mask_nmi_pin .value && |soc_ifc_reg_hwif_in.CPTRA_HW_ERROR_FATAL.nmi_pin .next); + +always_comb soc_ifc_reg_hwif_in.CPTRA_HW_ERROR_NON_FATAL.mbox_prot_no_lock.we = mbox_protocol_error.axs_without_lock; +always_comb soc_ifc_reg_hwif_in.CPTRA_HW_ERROR_NON_FATAL.mbox_prot_ooo .we = mbox_protocol_error.axs_incorrect_order; +always_comb soc_ifc_reg_hwif_in.CPTRA_HW_ERROR_NON_FATAL.mbox_ecc_unc .we = sram_double_ecc_error; +// Using we+next instead of hwset allows us to encode the reserved fields in some fashion +// other than bit-hot in the future, if needed (e.g. we need to encode > 32 NON-FATAL events) +always_comb soc_ifc_reg_hwif_in.CPTRA_HW_ERROR_NON_FATAL.mbox_prot_no_lock.next = 1'b1; +always_comb soc_ifc_reg_hwif_in.CPTRA_HW_ERROR_NON_FATAL.mbox_prot_ooo .next = 1'b1; +always_comb soc_ifc_reg_hwif_in.CPTRA_HW_ERROR_NON_FATAL.mbox_ecc_unc .next = 1'b1; +always_comb soc_ifc_reg_hwif_in.CPTRA_HW_ERROR_NON_FATAL.rsvd.next[28:0] = 29'h0; +// Flag the write even if the field being written to is already set to 1 - this is a new occurrence of the error and should trigger a new interrupt +always_comb unmasked_hw_error_non_fatal_write = (soc_ifc_reg_hwif_in.CPTRA_HW_ERROR_NON_FATAL.mbox_prot_no_lock.we && ~soc_ifc_reg_hwif_out.internal_hw_error_non_fatal_mask.mask_mbox_prot_no_lock.value && |soc_ifc_reg_hwif_in.CPTRA_HW_ERROR_NON_FATAL.mbox_prot_no_lock.next) || + (soc_ifc_reg_hwif_in.CPTRA_HW_ERROR_NON_FATAL.mbox_prot_ooo .we && ~soc_ifc_reg_hwif_out.internal_hw_error_non_fatal_mask.mask_mbox_prot_ooo .value && |soc_ifc_reg_hwif_in.CPTRA_HW_ERROR_NON_FATAL.mbox_prot_ooo .next) || + (soc_ifc_reg_hwif_in.CPTRA_HW_ERROR_NON_FATAL.mbox_ecc_unc .we && ~soc_ifc_reg_hwif_out.internal_hw_error_non_fatal_mask.mask_mbox_ecc_unc .value && |soc_ifc_reg_hwif_in.CPTRA_HW_ERROR_NON_FATAL.mbox_ecc_unc .next); +always_comb unmasked_hw_error_non_fatal_is_set = (soc_ifc_reg_hwif_out.CPTRA_HW_ERROR_NON_FATAL.mbox_prot_no_lock.value && ~soc_ifc_reg_hwif_out.internal_hw_error_non_fatal_mask.mask_mbox_prot_no_lock.value) || + (soc_ifc_reg_hwif_out.CPTRA_HW_ERROR_NON_FATAL.mbox_prot_ooo .value && ~soc_ifc_reg_hwif_out.internal_hw_error_non_fatal_mask.mask_mbox_prot_ooo .value) || + (soc_ifc_reg_hwif_out.CPTRA_HW_ERROR_NON_FATAL.mbox_ecc_unc .value && ~soc_ifc_reg_hwif_out.internal_hw_error_non_fatal_mask.mask_mbox_ecc_unc .value); + +//TIE-OFFS +always_comb begin + soc_ifc_reg_hwif_in.CPTRA_FW_ERROR_FATAL.error_code.we = 'b0; + soc_ifc_reg_hwif_in.CPTRA_FW_ERROR_FATAL.error_code.next = 'h0; + soc_ifc_reg_hwif_in.CPTRA_FW_ERROR_NON_FATAL.error_code.we = 'b0; + soc_ifc_reg_hwif_in.CPTRA_FW_ERROR_NON_FATAL.error_code.next = 'h0; +end + +//DMI register writes +always_comb soc_ifc_reg_hwif_in.CPTRA_BOOTFSM_GO.GO.we = cptra_uncore_dmi_locked_reg_wr_en & + (cptra_uncore_dmi_reg_addr == DMI_REG_BOOTFSM_GO); +always_comb soc_ifc_reg_hwif_in.CPTRA_BOOTFSM_GO.GO.next = cptra_uncore_dmi_reg_wdata[0]; +always_comb soc_ifc_reg_hwif_in.CPTRA_DBG_MANUF_SERVICE_REG.DATA.we = cptra_uncore_dmi_locked_reg_wr_en & + (cptra_uncore_dmi_reg_addr == DMI_REG_CPTRA_DBG_MANUF_SERVICE_REG); +always_comb soc_ifc_reg_hwif_in.CPTRA_DBG_MANUF_SERVICE_REG.DATA.next = cptra_uncore_dmi_reg_wdata; + +//DMI locked register read mux +always_comb cptra_uncore_dmi_locked_reg_rdata_in = ({32{(cptra_uncore_dmi_reg_addr == DMI_REG_MBOX_DLEN)}} & mbox_dmi_reg.MBOX_DLEN) | + ({32{(cptra_uncore_dmi_reg_addr == DMI_REG_MBOX_DOUT)}} & mbox_dmi_reg.MBOX_DOUT) | + ({32{(cptra_uncore_dmi_reg_addr == DMI_REG_MBOX_STATUS)}} & mbox_dmi_reg.MBOX_STATUS) | + ({32{(cptra_uncore_dmi_reg_addr == DMI_REG_MBOX_CMD)}} & mbox_dmi_reg.MBOX_CMD) | + ({32{(cptra_uncore_dmi_reg_addr == DMI_REG_MBOX_LOCK)}} & mbox_dmi_reg.MBOX_LOCK) | + ({32{(cptra_uncore_dmi_reg_addr == DMI_REG_BOOT_STATUS)}} & soc_ifc_reg_hwif_out.CPTRA_BOOT_STATUS.status.value) | + ({32{(cptra_uncore_dmi_reg_addr == DMI_REG_CPTRA_HW_ERRROR_ENC)}} & soc_ifc_reg_hwif_out.CPTRA_HW_ERROR_ENC.error_code.value) | + ({32{(cptra_uncore_dmi_reg_addr == DMI_REG_CPTRA_FW_ERROR_ENC)}} & soc_ifc_reg_hwif_out.CPTRA_FW_ERROR_ENC.error_code.value) | + ({32{(cptra_uncore_dmi_reg_addr == DMI_REG_BOOTFSM_GO)}} & {31'b0, soc_ifc_reg_hwif_out.CPTRA_BOOTFSM_GO.GO.value}) | + ({32{(cptra_uncore_dmi_reg_addr == DMI_REG_CPTRA_DBG_MANUF_SERVICE_REG)}} & soc_ifc_reg_hwif_out.CPTRA_DBG_MANUF_SERVICE_REG.DATA.value) | + ({32{(cptra_uncore_dmi_reg_addr == DMI_REG_HW_FATAL_ERROR)}} & {soc_ifc_reg_hwif_in .CPTRA_HW_ERROR_FATAL.rsvd.next[27:0], + soc_ifc_reg_hwif_out.CPTRA_HW_ERROR_FATAL.crypto_err.value, + soc_ifc_reg_hwif_out.CPTRA_HW_ERROR_FATAL.nmi_pin.value, + soc_ifc_reg_hwif_out.CPTRA_HW_ERROR_FATAL.dccm_ecc_unc.value, + soc_ifc_reg_hwif_out.CPTRA_HW_ERROR_FATAL.iccm_ecc_unc.value}) | + ({32{(cptra_uncore_dmi_reg_addr == DMI_REG_FW_FATAL_ERROR)}} & soc_ifc_reg_hwif_out.CPTRA_FW_ERROR_FATAL.error_code.value) | + ({32{(cptra_uncore_dmi_reg_addr == DMI_REG_HW_NON_FATAL_ERROR)}} & {soc_ifc_reg_hwif_in .CPTRA_HW_ERROR_NON_FATAL.rsvd.next[28:0], + soc_ifc_reg_hwif_out.CPTRA_HW_ERROR_NON_FATAL.mbox_ecc_unc.value, + soc_ifc_reg_hwif_out.CPTRA_HW_ERROR_NON_FATAL.mbox_prot_ooo.value, + soc_ifc_reg_hwif_out.CPTRA_HW_ERROR_NON_FATAL.mbox_prot_no_lock.value}) | + ({32{(cptra_uncore_dmi_reg_addr == DMI_REG_FW_NON_FATAL_ERROR)}} & soc_ifc_reg_hwif_out.CPTRA_FW_ERROR_NON_FATAL.error_code.value) | + ({32{(cptra_uncore_dmi_reg_addr == DMI_REG_SS_DBG_SERVICE_REG_REQ)}} & {soc_ifc_reg_hwif_in .SS_DBG_SERVICE_REG_REQ.RSVD.next[28:0], + soc_ifc_reg_hwif_out.SS_DBG_SERVICE_REG_REQ.UDS_PROGRAM_REQ.value, + soc_ifc_reg_hwif_out.SS_DBG_SERVICE_REG_REQ.PROD_DBG_UNLOCK_REQ.value, + soc_ifc_reg_hwif_out.SS_DBG_SERVICE_REG_REQ.MANUF_DBG_UNLOCK_REQ.value}) | + ({32{(cptra_uncore_dmi_reg_addr == DMI_REG_SS_DBG_SERVICE_REG_RSP)}} & {soc_ifc_reg_hwif_in .SS_DBG_SERVICE_REG_RSP.RSVD.next[21:0], + soc_ifc_reg_hwif_out.SS_DBG_SERVICE_REG_RSP.TAP_MAILBOX_AVAILABLE.value, + soc_ifc_reg_hwif_out.SS_DBG_SERVICE_REG_RSP.UDS_PROGRAM_IN_PROGRESS.value, + soc_ifc_reg_hwif_out.SS_DBG_SERVICE_REG_RSP.UDS_PROGRAM_FAIL.value, + soc_ifc_reg_hwif_out.SS_DBG_SERVICE_REG_RSP.UDS_PROGRAM_SUCCESS.value, + soc_ifc_reg_hwif_out.SS_DBG_SERVICE_REG_RSP.PROD_DBG_UNLOCK_IN_PROGRESS.value, + soc_ifc_reg_hwif_out.SS_DBG_SERVICE_REG_RSP.PROD_DBG_UNLOCK_FAIL.value, + soc_ifc_reg_hwif_out.SS_DBG_SERVICE_REG_RSP.PROD_DBG_UNLOCK_SUCCESS.value, + soc_ifc_reg_hwif_out.SS_DBG_SERVICE_REG_RSP.MANUF_DBG_UNLOCK_IN_PROGRESS.value, + soc_ifc_reg_hwif_out.SS_DBG_SERVICE_REG_RSP.MANUF_DBG_UNLOCK_FAIL.value, + soc_ifc_reg_hwif_out.SS_DBG_SERVICE_REG_RSP.MANUF_DBG_UNLOCK_SUCCESS.value}) ; + +//DMI unlocked register read mux +always_comb cptra_uncore_dmi_unlocked_reg_rdata_in = ({32{(cptra_uncore_dmi_reg_addr == DMI_REG_MBOX_DLEN)}} & mbox_dmi_reg.MBOX_DLEN) | + ({32{(cptra_uncore_dmi_reg_addr == DMI_REG_MBOX_DOUT)}} & mbox_dmi_reg.MBOX_DOUT) | + ({32{(cptra_uncore_dmi_reg_addr == DMI_REG_MBOX_STATUS)}} & mbox_dmi_reg.MBOX_STATUS) | + ({32{(cptra_uncore_dmi_reg_addr == DMI_REG_MBOX_CMD)}} & mbox_dmi_reg.MBOX_CMD) | + ({32{(cptra_uncore_dmi_reg_addr == DMI_REG_MBOX_LOCK)}} & mbox_dmi_reg.MBOX_LOCK) | + ({32{(cptra_uncore_dmi_reg_addr == DMI_REG_BOOT_STATUS)}} & soc_ifc_reg_hwif_out.CPTRA_BOOT_STATUS.status.value) | + ({32{(cptra_uncore_dmi_reg_addr == DMI_REG_CPTRA_HW_ERRROR_ENC)}} & soc_ifc_reg_hwif_out.CPTRA_HW_ERROR_ENC.error_code.value) | + ({32{(cptra_uncore_dmi_reg_addr == DMI_REG_CPTRA_FW_ERROR_ENC)}} & soc_ifc_reg_hwif_out.CPTRA_FW_ERROR_ENC.error_code.value) | + ({32{(cptra_uncore_dmi_reg_addr == DMI_REG_BOOTFSM_GO)}} & {31'b0, soc_ifc_reg_hwif_out.CPTRA_BOOTFSM_GO.GO.value}) | + ({32{(cptra_uncore_dmi_reg_addr == DMI_REG_CPTRA_DBG_MANUF_SERVICE_REG)}} & soc_ifc_reg_hwif_out.CPTRA_DBG_MANUF_SERVICE_REG.DATA.value) | + ({32{(cptra_uncore_dmi_reg_addr == DMI_REG_HW_FATAL_ERROR)}} & {soc_ifc_reg_hwif_in .CPTRA_HW_ERROR_FATAL.rsvd.next[27:0], + soc_ifc_reg_hwif_out.CPTRA_HW_ERROR_FATAL.crypto_err.value, + soc_ifc_reg_hwif_out.CPTRA_HW_ERROR_FATAL.nmi_pin.value, + soc_ifc_reg_hwif_out.CPTRA_HW_ERROR_FATAL.dccm_ecc_unc.value, + soc_ifc_reg_hwif_out.CPTRA_HW_ERROR_FATAL.iccm_ecc_unc.value}) | + ({32{(cptra_uncore_dmi_reg_addr == DMI_REG_FW_FATAL_ERROR)}} & soc_ifc_reg_hwif_out.CPTRA_FW_ERROR_FATAL.error_code.value) | + ({32{(cptra_uncore_dmi_reg_addr == DMI_REG_HW_NON_FATAL_ERROR)}} & {soc_ifc_reg_hwif_in .CPTRA_HW_ERROR_NON_FATAL.rsvd.next[28:0], + soc_ifc_reg_hwif_out.CPTRA_HW_ERROR_NON_FATAL.mbox_ecc_unc.value, + soc_ifc_reg_hwif_out.CPTRA_HW_ERROR_NON_FATAL.mbox_prot_ooo.value, + soc_ifc_reg_hwif_out.CPTRA_HW_ERROR_NON_FATAL.mbox_prot_no_lock.value}) | + ({32{(cptra_uncore_dmi_reg_addr == DMI_REG_FW_NON_FATAL_ERROR)}} & soc_ifc_reg_hwif_out.CPTRA_FW_ERROR_NON_FATAL.error_code.value) | + ({32{(cptra_uncore_dmi_reg_addr == DMI_REG_SS_UDS_SEED_BASE_ADDR_L)}} & soc_ifc_reg_hwif_out.SS_UDS_SEED_BASE_ADDR_L.addr_l.value ) | + ({32{(cptra_uncore_dmi_reg_addr == DMI_REG_SS_UDS_SEED_BASE_ADDR_H)}} & soc_ifc_reg_hwif_out.SS_UDS_SEED_BASE_ADDR_H.addr_h.value ) | + ({32{(cptra_uncore_dmi_reg_addr == DMI_REG_SS_DEBUG_INTENT)}} & {31'b0, soc_ifc_reg_hwif_out.SS_DEBUG_INTENT.debug_intent.value}) | + ({32{(cptra_uncore_dmi_reg_addr == DMI_REG_SS_CALIPTRA_BASE_ADDR_L)}} & soc_ifc_reg_hwif_out.SS_CALIPTRA_BASE_ADDR_L.addr_l.value ) | + ({32{(cptra_uncore_dmi_reg_addr == DMI_REG_SS_CALIPTRA_BASE_ADDR_H)}} & soc_ifc_reg_hwif_out.SS_CALIPTRA_BASE_ADDR_H.addr_h.value ) | + ({32{(cptra_uncore_dmi_reg_addr == DMI_REG_SS_MCI_BASE_ADDR_L)}} & soc_ifc_reg_hwif_out.SS_MCI_BASE_ADDR_L.addr_l.value ) | + ({32{(cptra_uncore_dmi_reg_addr == DMI_REG_SS_MCI_BASE_ADDR_H)}} & soc_ifc_reg_hwif_out.SS_MCI_BASE_ADDR_H.addr_h.value ) | + ({32{(cptra_uncore_dmi_reg_addr == DMI_REG_SS_RECOVERY_IFC_BASE_ADDR_L)}} & soc_ifc_reg_hwif_out.SS_RECOVERY_IFC_BASE_ADDR_L.addr_l.value ) | + ({32{(cptra_uncore_dmi_reg_addr == DMI_REG_SS_RECOVERY_IFC_BASE_ADDR_H)}} & soc_ifc_reg_hwif_out.SS_RECOVERY_IFC_BASE_ADDR_H.addr_h.value ) | + ({32{(cptra_uncore_dmi_reg_addr == DMI_REG_SS_EXTERNAL_STAGING_AREA_BASE_ADDR_L)}} & soc_ifc_reg_hwif_out.SS_EXTERNAL_STAGING_AREA_BASE_ADDR_L.addr_l.value ) | + ({32{(cptra_uncore_dmi_reg_addr == DMI_REG_SS_EXTERNAL_STAGING_AREA_BASE_ADDR_H)}} & soc_ifc_reg_hwif_out.SS_EXTERNAL_STAGING_AREA_BASE_ADDR_H.addr_h.value ) | + ({32{(cptra_uncore_dmi_reg_addr == DMI_REG_SS_OTP_FC_BASE_ADDR_L)}} & soc_ifc_reg_hwif_out.SS_OTP_FC_BASE_ADDR_L.addr_l.value ) | + ({32{(cptra_uncore_dmi_reg_addr == DMI_REG_SS_OTP_FC_BASE_ADDR_H)}} & soc_ifc_reg_hwif_out.SS_OTP_FC_BASE_ADDR_H.addr_h.value ) | + ({32{(cptra_uncore_dmi_reg_addr == DMI_REG_SS_STRAP_CALIPTRA_DMA_AXI_USER)}} & soc_ifc_reg_hwif_out.SS_CALIPTRA_DMA_AXI_USER.user.value ) | + ({32{(cptra_uncore_dmi_reg_addr == DMI_REG_SS_STRAP_GENERIC_0)}} & soc_ifc_reg_hwif_out.SS_STRAP_GENERIC[0].data.value ) | + ({32{(cptra_uncore_dmi_reg_addr == DMI_REG_SS_STRAP_GENERIC_1)}} & soc_ifc_reg_hwif_out.SS_STRAP_GENERIC[1].data.value ) | + ({32{(cptra_uncore_dmi_reg_addr == DMI_REG_SS_STRAP_GENERIC_2)}} & soc_ifc_reg_hwif_out.SS_STRAP_GENERIC[2].data.value ) | + ({32{(cptra_uncore_dmi_reg_addr == DMI_REG_SS_STRAP_GENERIC_3)}} & soc_ifc_reg_hwif_out.SS_STRAP_GENERIC[3].data.value ) | + ({32{(cptra_uncore_dmi_reg_addr == DMI_REG_SS_DBG_SERVICE_REG_REQ)}} & {soc_ifc_reg_hwif_in .SS_DBG_SERVICE_REG_REQ.RSVD.next[28:0], + soc_ifc_reg_hwif_out.SS_DBG_SERVICE_REG_REQ.UDS_PROGRAM_REQ.value, + soc_ifc_reg_hwif_out.SS_DBG_SERVICE_REG_REQ.PROD_DBG_UNLOCK_REQ.value, + soc_ifc_reg_hwif_out.SS_DBG_SERVICE_REG_REQ.MANUF_DBG_UNLOCK_REQ.value}) | + ({32{(cptra_uncore_dmi_reg_addr == DMI_REG_SS_DBG_SERVICE_REG_RSP)}} & {soc_ifc_reg_hwif_in .SS_DBG_SERVICE_REG_RSP.RSVD.next[21:0], + soc_ifc_reg_hwif_out.SS_DBG_SERVICE_REG_RSP.TAP_MAILBOX_AVAILABLE.value, + soc_ifc_reg_hwif_out.SS_DBG_SERVICE_REG_RSP.UDS_PROGRAM_IN_PROGRESS.value, + soc_ifc_reg_hwif_out.SS_DBG_SERVICE_REG_RSP.UDS_PROGRAM_FAIL.value, + soc_ifc_reg_hwif_out.SS_DBG_SERVICE_REG_RSP.UDS_PROGRAM_SUCCESS.value, + soc_ifc_reg_hwif_out.SS_DBG_SERVICE_REG_RSP.PROD_DBG_UNLOCK_IN_PROGRESS.value, + soc_ifc_reg_hwif_out.SS_DBG_SERVICE_REG_RSP.PROD_DBG_UNLOCK_FAIL.value, + soc_ifc_reg_hwif_out.SS_DBG_SERVICE_REG_RSP.PROD_DBG_UNLOCK_SUCCESS.value, + soc_ifc_reg_hwif_out.SS_DBG_SERVICE_REG_RSP.MANUF_DBG_UNLOCK_IN_PROGRESS.value, + soc_ifc_reg_hwif_out.SS_DBG_SERVICE_REG_RSP.MANUF_DBG_UNLOCK_FAIL.value, + soc_ifc_reg_hwif_out.SS_DBG_SERVICE_REG_RSP.MANUF_DBG_UNLOCK_SUCCESS.value}) | + ({32{(cptra_uncore_dmi_reg_addr == DMI_REG_SS_DBG_UNLOCK_LEVEL0)}} & soc_ifc_reg_hwif_out.SS_SOC_DBG_UNLOCK_LEVEL[0].LEVEL.value ) | + ({32{(cptra_uncore_dmi_reg_addr == DMI_REG_SS_DBG_UNLOCK_LEVEL1)}} & soc_ifc_reg_hwif_out.SS_SOC_DBG_UNLOCK_LEVEL[1].LEVEL.value ) ; + + + + + +//Increment the read pointer when we had a dmi read to data out and no access this clock +//This assumes that reg_en goes low between read accesses +always_comb dmi_inc_rdptr = cptra_uncore_dmi_reg_dout_access_f & ~cptra_uncore_dmi_locked_reg_en; +always_comb dmi_inc_wrptr = cptra_uncore_dmi_reg_din_access_f & ~cptra_uncore_dmi_locked_reg_en; + +always_ff @(posedge rdc_clk_cg or negedge cptra_pwrgood) begin + if (~cptra_pwrgood) begin + cptra_uncore_dmi_reg_rdata <= '0; + cptra_uncore_dmi_reg_dout_access_f <= '0; + cptra_uncore_dmi_reg_din_access_f <= '0; + end + else begin + cptra_uncore_dmi_reg_rdata <= cptra_uncore_dmi_unlocked_reg_en ? cptra_uncore_dmi_unlocked_reg_rdata_in : + cptra_uncore_dmi_locked_reg_en ? cptra_uncore_dmi_locked_reg_rdata_in : cptra_uncore_dmi_reg_rdata; + + cptra_uncore_dmi_reg_dout_access_f <= cptra_uncore_dmi_locked_reg_en & ~cptra_uncore_dmi_reg_wr_en & (cptra_uncore_dmi_reg_addr == DMI_REG_MBOX_DOUT); + cptra_uncore_dmi_reg_din_access_f <= cptra_uncore_dmi_locked_reg_en & cptra_uncore_dmi_reg_wr_en & (cptra_uncore_dmi_reg_addr == DMI_REG_MBOX_DIN); + end +end + +`CALIPTRA_ASSERT (SS_STRAP_KEY_SIZE_DW_MULT , strap_ss_key_release_key_size[1:0] == 2'b00 , clk, !cptra_noncore_rst_b) +`CALIPTRA_ASSERT (SS_STRAP_KEY_SIZE_LTE_64 , strap_ss_key_release_key_size[15:0] <= 16'h40, clk, !cptra_noncore_rst_b) +`CALIPTRA_ASSERT (AXI_SUB_ADDR_WIDTH, SOC_IFC_ADDR_W == AXI_ADDR_WIDTH, clk, !cptra_noncore_rst_b) +`CALIPTRA_ASSERT (AXI_SUB_DATA_WIDTH, SOC_IFC_DATA_W == AXI_DATA_WIDTH, clk, !cptra_noncore_rst_b) +`CALIPTRA_ASSERT (AXI_SUB_USER_WIDTH, SOC_IFC_USER_W == AXI_USER_WIDTH, clk, !cptra_noncore_rst_b) +`CALIPTRA_ASSERT (AXI_SUB_ID_WIDTH , SOC_IFC_ID_W == AXI_ID_WIDTH, clk, !cptra_noncore_rst_b) + +`CALIPTRA_ASSERT_KNOWN(ERR_AHB_INF_X, {hreadyout_o,hresp_o}, clk, !cptra_noncore_rst_b) +//this generates an NMI in the core, but we don't have a handler so it just hangs +`CALIPTRA_ASSERT_NEVER(ERR_SOC_IFC_AHB_ERR, hresp_o, clk, !cptra_noncore_rst_b) +endmodule diff --git a/designs/Caliptra/src/caliptra-rtl/wdt.sv b/designs/Caliptra/src/caliptra-rtl/wdt.sv new file mode 100644 index 0000000..8375ea7 --- /dev/null +++ b/designs/Caliptra/src/caliptra-rtl/wdt.sv @@ -0,0 +1,121 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// 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. + +module wdt + #( + parameter WDT_TIMEOUT_PERIOD_NUM_DWORDS = 2, + localparam WDT_TIMEOUT_PERIOD_W = WDT_TIMEOUT_PERIOD_NUM_DWORDS * 32 + ) +( + input logic clk, + input logic cptra_rst_b, + //Timer inputs + input logic timer1_en, + input logic timer2_en, + input logic timer1_restart, + input logic timer2_restart, + input logic [WDT_TIMEOUT_PERIOD_W-1:0] timer1_timeout_period, + input logic [WDT_TIMEOUT_PERIOD_W-1:0] timer2_timeout_period, + //Interrupts + input logic wdt_timer1_timeout_serviced, + input logic wdt_timer2_timeout_serviced, + //WDT STATUS bits + output logic t1_timeout, + output logic t2_timeout, + output logic fatal_timeout + +); + +//Timer1 +logic [WDT_TIMEOUT_PERIOD_W-1:0] timer1_count; +logic timer1_count_en; +logic wdt_timer1_timeout_serviced_qual; +logic wdt_timer1_timeout_serviced_restart; + +//Timer2 +logic [WDT_TIMEOUT_PERIOD_W-1:0] timer2_count; +logic timer2_count_en; +logic wdt_timer2_timeout_serviced_qual; +logic wdt_timer2_timeout_serviced_restart; + +//Output assignments +assign t1_timeout = (timer1_count == timer1_timeout_period); +assign t2_timeout = (timer2_count == timer2_timeout_period); + + +assign timer1_count_en = timer1_en; +assign timer2_count_en = !timer2_en ? t1_timeout : timer2_en; + +// In cascade mode if T2 timesout it is a fatal error. +assign fatal_timeout = t2_timeout && !timer2_en; + + +// Timeout Service Logic + +// Only acknowledge the T1 timeout servicing request if T1 has timeout +assign wdt_timer1_timeout_serviced_qual = wdt_timer1_timeout_serviced & t1_timeout; + +// Only restart T1 via timeout service request if: +// 1. In independent mode and T1 has timed out +// 2. In cascade mode and T2 hasn't timed out +assign wdt_timer1_timeout_serviced_restart = wdt_timer1_timeout_serviced_qual & (timer2_en | ~t2_timeout); + + +// Only acknowledge the T2 timeout servicing request if T2 has timeout and in parallel mode +assign wdt_timer2_timeout_serviced_qual = wdt_timer2_timeout_serviced & t2_timeout & timer2_en; + +// Only restart T2 via timeout service request if: +// 1. In cascade mode T2 hasn't timeout out and T1 has been serviced +// 2. In independent mode and T2 has timed out +assign wdt_timer2_timeout_serviced_restart = (wdt_timer1_timeout_serviced_qual & ~t2_timeout & ~timer2_en) | wdt_timer2_timeout_serviced_qual; + + +//Timer1 +always_ff @(posedge clk or negedge cptra_rst_b) begin + if(!cptra_rst_b) begin + timer1_count <= 'h0; + end + else if(timer1_count_en) begin + //Count up always. If restart = 1, count from 0 again + //If it timed out, an intr is triggered to core. Don't reset + //until intr is serviced. If serviced, and t2 has not timed out, + //start count from 0 again. In all other cases, hold the count + //Note: if t2 has timed out, expect a warm reset to re-init timers + timer1_count <= timer1_restart && !t1_timeout ? 'h0 + : wdt_timer1_timeout_serviced_restart ? 'h0 + : !t1_timeout ? (timer1_count + 'h1) + : timer1_count; + end +end + +//Timer2 +always_ff @(posedge clk or negedge cptra_rst_b) begin + if(!cptra_rst_b) begin + timer2_count <= 'h0; + end + else if(timer2_count_en) begin + //If t1 timed out and an intr was triggered, once that is serviced + //and t2 has not yet timed out, restart both t1 and t2. Otherwise, + //hold the count. In case of time out, nmi and fatal error are triggered + //Warm reset is expected to re-init timers + //Note: if timer1 and timer2 are independently enabled, we want to remove the dependency of timer1 on timer2 and vice versa + //Note: Only allow timer2_restart to reset T2 if in independent mode + timer2_count <= timer2_restart && timer2_en && !t2_timeout ? 'h0 + : wdt_timer2_timeout_serviced_restart ? 'h0 + : !t2_timeout ? (timer2_count + 'h1) + : timer2_count; + end +end + +endmodule diff --git a/designs/Caliptra/tests/hello/dccm.hex b/designs/Caliptra/tests/hello/dccm.hex new file mode 100644 index 0000000..8718a05 --- /dev/null +++ b/designs/Caliptra/tests/hello/dccm.hex @@ -0,0 +1,7411 @@ +@000231F0 +CC 00 03 30 02 00 00 00 00 00 00 00 00 00 00 00 +2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D +2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D +2D 2D 2D 2D 2D 2D 2D 2D 0A 48 65 6C 6C 6F 20 57 +6F 72 6C 64 20 66 72 6F 6D 20 56 65 65 52 20 45 +4C 32 20 49 43 43 4D 20 20 20 21 21 0A 2D 2D 2D +2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D +2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D +2D 2D 2D 2D 2D 0A 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +C0 0E 00 00 D0 0D 00 00 14 1A 00 00 E0 0C 00 00 +D6 18 00 00 F0 0B 00 00 98 17 00 00 00 0B 00 00 +10 0A 00 00 20 09 00 00 5A 16 00 00 30 08 00 00 +1C 15 00 00 34 0F 00 00 34 0F 00 00 34 0F 00 00 +34 0F 00 00 40 07 00 00 50 06 00 00 FA 12 00 00 +D8 10 00 00 60 05 00 00 9A 0F 00 00 70 04 00 00 +80 03 00 00 90 02 00 00 A0 01 00 00 34 0F 00 00 +34 0F 00 00 34 0F 00 00 34 0F 00 00 34 0F 00 00 +@00023480 +B7 01 03 30 93 81 C1 0C 17 32 02 10 13 02 82 1F +83 02 02 00 23 80 51 00 05 02 E3 9B 02 FE 82 80 +00 00 00 00 01 00 00 00 02 00 00 00 03 00 00 00 +04 00 00 00 +@000234B4 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +@000254B4 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +@000274B4 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +@000294B4 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +@0002B4B4 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +@0002D4B4 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +@0002F4B4 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +@000314B4 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +@000334B4 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +@000354B4 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +@000374B4 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +@000394B4 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +@0003B4B4 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +@0003D4B4 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +@0003F4B4 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 diff --git a/designs/Caliptra/tests/hello/iccm.hex b/designs/Caliptra/tests/hello/iccm.hex new file mode 100644 index 0000000..e69de29 diff --git a/designs/Caliptra/tests/hello/mailbox.hex b/designs/Caliptra/tests/hello/mailbox.hex new file mode 100644 index 0000000..e69de29 diff --git a/designs/Caliptra/tests/hello/program.hex b/designs/Caliptra/tests/hello/program.hex new file mode 100644 index 0000000..4cc9a7e --- /dev/null +++ b/designs/Caliptra/tests/hello/program.hex @@ -0,0 +1,6150 @@ +@00000000 +B7 B0 AA AA 93 80 A0 AA 73 90 00 7C EF 10 70 34 +91 41 73 90 91 7F B7 01 00 40 17 32 02 50 13 02 +62 46 97 32 02 50 93 82 22 49 03 23 02 00 23 A0 +61 00 11 02 91 01 E3 6A 52 FE 0F 10 00 00 97 00 +00 40 E7 80 20 FC B7 01 03 30 93 81 C1 0C 93 02 +F0 0F 23 80 51 00 E3 08 00 FE 01 00 01 00 01 00 +01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00 +01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00 +01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00 +01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00 +01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00 +01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00 +01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00 +01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00 +01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00 +01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00 +01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00 +01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00 +01 00 00 00 6F 10 90 55 6F 00 D0 60 00 00 00 00 +6F 00 50 60 00 00 00 00 6F 00 D0 5F 00 00 00 00 +6F 10 90 44 00 00 00 00 6F 00 D0 5E 00 00 00 00 +6F 00 50 5E 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 6F 10 50 46 6F 10 90 46 +5D 71 2A DA 13 05 B0 0F 22 DE 36 D4 3E D0 86 C6 +96 C4 9A C2 9E C0 26 DC 2E D8 32 D6 3A D2 42 CE +46 CC 4A CA 4E C8 72 C6 76 C4 7A C2 7E C0 37 34 +02 50 EF 20 40 61 83 26 44 1F 8D 47 63 E9 D7 08 +F3 27 B0 BC F3 29 C0 BC 73 29 10 34 F3 24 00 30 +73 24 40 30 73 90 C7 BC A1 47 73 A0 07 30 37 37 +02 50 83 27 87 1F 0D 46 85 07 23 2C F7 1E 63 69 +D6 06 A1 47 73 B0 07 30 73 90 C9 BC 73 10 19 34 +89 67 93 87 07 88 FD 8C 73 A0 04 30 85 67 93 87 +87 88 7D 8C 73 20 44 30 13 05 C0 0F EF 20 A0 5A +72 54 B6 40 A6 42 16 43 86 43 E2 54 52 55 C2 55 +32 56 A2 56 12 57 82 57 72 48 E2 48 52 49 C2 49 +32 4E A2 4E 12 4F 82 4F 61 61 73 00 20 30 37 15 +02 50 13 05 85 9C EF 20 00 59 83 26 44 1F 8D B7 +83 25 87 1F 09 65 13 05 C5 F7 EF 20 C0 59 51 B7 +5D 71 2A DA 13 05 B0 0F 22 DE 36 D4 3E D0 86 C6 +96 C4 9A C2 9E C0 26 DC 2E D8 32 D6 3A D2 42 CE +46 CC 4A CA 4E C8 72 C6 76 C4 7A C2 7E C0 37 34 +02 50 EF 20 40 52 83 26 44 1F 8D 47 63 E9 D7 08 +F3 27 B0 BC F3 29 C0 BC 73 29 10 34 F3 24 00 30 +73 24 40 30 73 90 C7 BC A1 47 73 A0 07 30 37 37 +02 50 83 27 87 1F 0D 46 85 07 23 2C F7 1E 63 69 +D6 06 A1 47 73 B0 07 30 73 90 C9 BC 73 10 19 34 +89 67 93 87 07 88 FD 8C 73 A0 04 30 85 67 93 87 +87 88 7D 8C 73 20 44 30 13 05 C0 0F EF 20 A0 4B +72 54 B6 40 A6 42 16 43 86 43 E2 54 52 55 C2 55 +32 56 A2 56 12 57 82 57 72 48 E2 48 52 49 C2 49 +32 4E A2 4E 12 4F 82 4F 61 61 73 00 20 30 37 15 +02 50 13 05 C5 9D EF 20 00 4A 83 26 44 1F 8D B7 +83 25 87 1F 09 65 13 05 45 F9 EF 20 C0 4A 51 B7 +5D 71 2A DA 13 05 B0 0F 22 DE 36 D4 3E D0 86 C6 +96 C4 9A C2 9E C0 26 DC 2E D8 32 D6 3A D2 42 CE +46 CC 4A CA 4E C8 72 C6 76 C4 7A C2 7E C0 37 34 +02 50 EF 20 40 43 83 26 44 1F 8D 47 63 E9 D7 08 +F3 27 B0 BC F3 29 C0 BC 73 29 10 34 F3 24 00 30 +73 24 40 30 73 90 C7 BC A1 47 73 A0 07 30 37 37 +02 50 83 27 87 1F 0D 46 85 07 23 2C F7 1E 63 69 +D6 06 A1 47 73 B0 07 30 73 90 C9 BC 73 10 19 34 +89 67 93 87 07 88 FD 8C 73 A0 04 30 85 67 93 87 +87 88 7D 8C 73 20 44 30 13 05 C0 0F EF 20 A0 3C +72 54 B6 40 A6 42 16 43 86 43 E2 54 52 55 C2 55 +32 56 A2 56 12 57 82 57 72 48 E2 48 52 49 C2 49 +32 4E A2 4E 12 4F 82 4F 61 61 73 00 20 30 37 15 +02 50 13 05 05 9F EF 20 00 3B 83 26 44 1F 8D B7 +83 25 87 1F 09 65 13 05 C5 FA EF 20 C0 3B 51 B7 +5D 71 2A DA 13 05 B0 0F 22 DE 36 D4 3E D0 86 C6 +96 C4 9A C2 9E C0 26 DC 2E D8 32 D6 3A D2 42 CE +46 CC 4A CA 4E C8 72 C6 76 C4 7A C2 7E C0 37 34 +02 50 EF 20 40 34 83 26 44 1F 8D 47 63 E9 D7 08 +F3 27 B0 BC F3 29 C0 BC 73 29 10 34 F3 24 00 30 +73 24 40 30 73 90 C7 BC A1 47 73 A0 07 30 37 37 +02 50 83 27 87 1F 0D 46 85 07 23 2C F7 1E 63 69 +D6 06 A1 47 73 B0 07 30 73 90 C9 BC 73 10 19 34 +89 67 93 87 07 88 FD 8C 73 A0 04 30 85 67 93 87 +87 88 7D 8C 73 20 44 30 13 05 C0 0F EF 20 A0 2D +72 54 B6 40 A6 42 16 43 86 43 E2 54 52 55 C2 55 +32 56 A2 56 12 57 82 57 72 48 E2 48 52 49 C2 49 +32 4E A2 4E 12 4F 82 4F 61 61 73 00 20 30 37 15 +02 50 13 05 05 A0 EF 20 00 2C 83 26 44 1F 8D B7 +83 25 87 1F 09 65 13 05 05 FC EF 20 C0 2C 51 B7 +5D 71 2A DA 13 05 B0 0F 22 DE 36 D4 3E D0 86 C6 +96 C4 9A C2 9E C0 26 DC 2E D8 32 D6 3A D2 42 CE +46 CC 4A CA 4E C8 72 C6 76 C4 7A C2 7E C0 37 34 +02 50 EF 20 40 25 83 26 44 1F 8D 47 63 E9 D7 08 +F3 27 B0 BC F3 29 C0 BC 73 29 10 34 F3 24 00 30 +73 24 40 30 73 90 C7 BC A1 47 73 A0 07 30 37 37 +02 50 83 27 87 1F 0D 46 85 07 23 2C F7 1E 63 69 +D6 06 A1 47 73 B0 07 30 73 90 C9 BC 73 10 19 34 +89 67 93 87 07 88 FD 8C 73 A0 04 30 85 67 93 87 +87 88 7D 8C 73 20 44 30 13 05 C0 0F EF 20 A0 1E +72 54 B6 40 A6 42 16 43 86 43 E2 54 52 55 C2 55 +32 56 A2 56 12 57 82 57 72 48 E2 48 52 49 C2 49 +32 4E A2 4E 12 4F 82 4F 61 61 73 00 20 30 37 15 +02 50 13 05 05 A1 EF 20 00 1D 83 26 44 1F 8D B7 +83 25 87 1F 09 65 13 05 45 FD EF 20 C0 1D 51 B7 +5D 71 2A DA 13 05 B0 0F 22 DE 36 D4 3E D0 86 C6 +96 C4 9A C2 9E C0 26 DC 2E D8 32 D6 3A D2 42 CE +46 CC 4A CA 4E C8 72 C6 76 C4 7A C2 7E C0 37 34 +02 50 EF 20 40 16 83 26 44 1F 8D 47 63 E9 D7 08 +F3 27 B0 BC F3 29 C0 BC 73 29 10 34 F3 24 00 30 +73 24 40 30 73 90 C7 BC A1 47 73 A0 07 30 37 37 +02 50 83 27 87 1F 0D 46 85 07 23 2C F7 1E 63 69 +D6 06 A1 47 73 B0 07 30 73 90 C9 BC 73 10 19 34 +89 67 93 87 07 88 FD 8C 73 A0 04 30 85 67 93 87 +87 88 7D 8C 73 20 44 30 13 05 C0 0F EF 20 A0 0F +72 54 B6 40 A6 42 16 43 86 43 E2 54 52 55 C2 55 +32 56 A2 56 12 57 82 57 72 48 E2 48 52 49 C2 49 +32 4E A2 4E 12 4F 82 4F 61 61 73 00 20 30 37 15 +02 50 13 05 45 A2 EF 20 00 0E 83 26 44 1F 8D B7 +83 25 87 1F 09 65 13 05 05 FF EF 20 C0 0E 51 B7 +5D 71 2A DA 13 05 B0 0F 22 DE 36 D4 3E D0 86 C6 +96 C4 9A C2 9E C0 26 DC 2E D8 32 D6 3A D2 42 CE +46 CC 4A CA 4E C8 72 C6 76 C4 7A C2 7E C0 37 34 +02 50 EF 20 40 07 83 26 44 1F 8D 47 63 E9 D7 08 +F3 27 B0 BC F3 29 C0 BC 73 29 10 34 F3 24 00 30 +73 24 40 30 73 90 C7 BC A1 47 73 A0 07 30 37 37 +02 50 83 27 87 1F 0D 46 85 07 23 2C F7 1E 63 69 +D6 06 A1 47 73 B0 07 30 73 90 C9 BC 73 10 19 34 +89 67 93 87 07 88 FD 8C 73 A0 04 30 85 67 93 87 +87 88 7D 8C 73 20 44 30 13 05 C0 0F EF 20 A0 00 +72 54 B6 40 A6 42 16 43 86 43 E2 54 52 55 C2 55 +32 56 A2 56 12 57 82 57 72 48 E2 48 52 49 C2 49 +32 4E A2 4E 12 4F 82 4F 61 61 73 00 20 30 37 15 +02 50 13 05 45 A3 EF 10 10 7F 83 26 44 1F 8D B7 +83 25 87 1F 09 65 13 05 45 00 EF 10 D0 7F 51 B7 +5D 71 2A DA 13 05 B0 0F 22 DE 36 D4 3E D0 86 C6 +96 C4 9A C2 9E C0 26 DC 2E D8 32 D6 3A D2 42 CE +46 CC 4A CA 4E C8 72 C6 76 C4 7A C2 7E C0 37 34 +02 50 EF 10 50 78 83 26 44 1F 8D 47 63 E9 D7 08 +F3 27 B0 BC F3 29 C0 BC 73 29 10 34 F3 24 00 30 +73 24 40 30 73 90 C7 BC A1 47 73 A0 07 30 37 37 +02 50 83 27 87 1F 0D 46 85 07 23 2C F7 1E 63 69 +D6 06 A1 47 73 B0 07 30 73 90 C9 BC 73 10 19 34 +89 67 93 87 07 88 FD 8C 73 A0 04 30 85 67 93 87 +87 88 7D 8C 73 20 44 30 13 05 C0 0F EF 10 B0 71 +72 54 B6 40 A6 42 16 43 86 43 E2 54 52 55 C2 55 +32 56 A2 56 12 57 82 57 72 48 E2 48 52 49 C2 49 +32 4E A2 4E 12 4F 82 4F 61 61 73 00 20 30 37 15 +02 50 13 05 45 A4 EF 10 10 70 83 26 44 1F 8D B7 +83 25 87 1F 09 65 13 05 85 01 EF 10 D0 70 51 B7 +5D 71 2A DA 13 05 B0 0F 22 DE 36 D4 3E D0 86 C6 +96 C4 9A C2 9E C0 26 DC 2E D8 32 D6 3A D2 42 CE +46 CC 4A CA 4E C8 72 C6 76 C4 7A C2 7E C0 37 34 +02 50 EF 10 50 69 83 26 44 1F 8D 47 63 E9 D7 08 +F3 27 B0 BC F3 29 C0 BC 73 29 10 34 F3 24 00 30 +73 24 40 30 73 90 C7 BC A1 47 73 A0 07 30 37 37 +02 50 83 27 87 1F 0D 46 85 07 23 2C F7 1E 63 69 +D6 06 A1 47 73 B0 07 30 73 90 C9 BC 73 10 19 34 +89 67 93 87 07 88 FD 8C 73 A0 04 30 85 67 93 87 +87 88 7D 8C 73 20 44 30 13 05 C0 0F EF 10 B0 62 +72 54 B6 40 A6 42 16 43 86 43 E2 54 52 55 C2 55 +32 56 A2 56 12 57 82 57 72 48 E2 48 52 49 C2 49 +32 4E A2 4E 12 4F 82 4F 61 61 73 00 20 30 37 15 +02 50 13 05 45 A5 EF 10 10 61 83 26 44 1F 8D B7 +83 25 87 1F 09 65 13 05 05 03 EF 10 D0 61 51 B7 +5D 71 2A DA 13 05 B0 0F 22 DE 36 D4 3E D0 86 C6 +96 C4 9A C2 9E C0 26 DC 2E D8 32 D6 3A D2 42 CE +46 CC 4A CA 4E C8 72 C6 76 C4 7A C2 7E C0 37 34 +02 50 EF 10 50 5A 83 26 44 1F 8D 47 63 E9 D7 08 +F3 27 B0 BC F3 29 C0 BC 73 29 10 34 F3 24 00 30 +73 24 40 30 73 90 C7 BC A1 47 73 A0 07 30 37 37 +02 50 83 27 87 1F 0D 46 85 07 23 2C F7 1E 63 69 +D6 06 A1 47 73 B0 07 30 73 90 C9 BC 73 10 19 34 +89 67 93 87 07 88 FD 8C 73 A0 04 30 85 67 93 87 +87 88 7D 8C 73 20 44 30 13 05 C0 0F EF 10 B0 53 +72 54 B6 40 A6 42 16 43 86 43 E2 54 52 55 C2 55 +32 56 A2 56 12 57 82 57 72 48 E2 48 52 49 C2 49 +32 4E A2 4E 12 4F 82 4F 61 61 73 00 20 30 37 15 +02 50 13 05 45 A6 EF 10 10 52 83 26 44 1F 8D B7 +83 25 87 1F 09 65 13 05 85 04 EF 10 D0 52 51 B7 +5D 71 2A DA 13 05 B0 0F 22 DE 36 D4 3E D0 86 C6 +96 C4 9A C2 9E C0 26 DC 2E D8 32 D6 3A D2 42 CE +46 CC 4A CA 4E C8 72 C6 76 C4 7A C2 7E C0 37 34 +02 50 EF 10 50 4B 83 26 44 1F 8D 47 63 E9 D7 08 +F3 27 B0 BC F3 29 C0 BC 73 29 10 34 F3 24 00 30 +73 24 40 30 73 90 C7 BC A1 47 73 A0 07 30 37 37 +02 50 83 27 87 1F 0D 46 85 07 23 2C F7 1E 63 69 +D6 06 A1 47 73 B0 07 30 73 90 C9 BC 73 10 19 34 +89 67 93 87 07 88 FD 8C 73 A0 04 30 85 67 93 87 +87 88 7D 8C 73 20 44 30 13 05 C0 0F EF 10 B0 44 +72 54 B6 40 A6 42 16 43 86 43 E2 54 52 55 C2 55 +32 56 A2 56 12 57 82 57 72 48 E2 48 52 49 C2 49 +32 4E A2 4E 12 4F 82 4F 61 61 73 00 20 30 37 15 +02 50 13 05 05 A7 EF 10 10 43 83 26 44 1F 8D B7 +83 25 87 1F 09 65 13 05 C5 05 EF 10 D0 43 51 B7 +5D 71 2A DA 13 05 B0 0F 22 DE 36 D4 3E D0 86 C6 +96 C4 9A C2 9E C0 26 DC 2E D8 32 D6 3A D2 42 CE +46 CC 4A CA 4E C8 72 C6 76 C4 7A C2 7E C0 37 34 +02 50 EF 10 50 3C 83 26 44 1F 8D 47 63 E9 D7 08 +F3 27 B0 BC F3 29 C0 BC 73 29 10 34 F3 24 00 30 +73 24 40 30 73 90 C7 BC A1 47 73 A0 07 30 37 37 +02 50 83 27 87 1F 0D 46 85 07 23 2C F7 1E 63 69 +D6 06 A1 47 73 B0 07 30 73 90 C9 BC 73 10 19 34 +89 67 93 87 07 88 FD 8C 73 A0 04 30 85 67 93 87 +87 88 7D 8C 73 20 44 30 13 05 C0 0F EF 10 B0 35 +72 54 B6 40 A6 42 16 43 86 43 E2 54 52 55 C2 55 +32 56 A2 56 12 57 82 57 72 48 E2 48 52 49 C2 49 +32 4E A2 4E 12 4F 82 4F 61 61 73 00 20 30 37 15 +02 50 13 05 C5 A7 EF 10 10 34 83 26 44 1F 8D B7 +83 25 87 1F 09 65 13 05 05 07 EF 10 D0 34 51 B7 +5D 71 2A DA 13 05 B0 0F 22 DE 36 D4 3E D0 86 C6 +96 C4 9A C2 9E C0 26 DC 2E D8 32 D6 3A D2 42 CE +46 CC 4A CA 4E C8 72 C6 76 C4 7A C2 7E C0 37 34 +02 50 EF 10 50 2D 83 26 44 1F 8D 47 63 E9 D7 08 +F3 27 B0 BC F3 29 C0 BC 73 29 10 34 F3 24 00 30 +73 24 40 30 73 90 C7 BC A1 47 73 A0 07 30 37 37 +02 50 83 27 87 1F 0D 46 85 07 23 2C F7 1E 63 69 +D6 06 A1 47 73 B0 07 30 73 90 C9 BC 73 10 19 34 +89 67 93 87 07 88 FD 8C 73 A0 04 30 85 67 93 87 +87 88 7D 8C 73 20 44 30 13 05 C0 0F EF 10 B0 26 +72 54 B6 40 A6 42 16 43 86 43 E2 54 52 55 C2 55 +32 56 A2 56 12 57 82 57 72 48 E2 48 52 49 C2 49 +32 4E A2 4E 12 4F 82 4F 61 61 73 00 20 30 37 15 +02 50 13 05 C5 A8 EF 10 10 25 83 26 44 1F 8D B7 +83 25 87 1F 09 65 13 05 45 08 EF 10 D0 25 51 B7 +5D 71 2A DA 13 05 B0 0F 22 DE 36 D4 3E D0 86 C6 +96 C4 9A C2 9E C0 26 DC 2E D8 32 D6 3A D2 42 CE +46 CC 4A CA 4E C8 72 C6 76 C4 7A C2 7E C0 37 34 +02 50 EF 10 50 1E 83 26 44 1F 8D 47 63 E9 D7 08 +F3 27 B0 BC F3 29 C0 BC 73 29 10 34 F3 24 00 30 +73 24 40 30 73 90 C7 BC A1 47 73 A0 07 30 37 37 +02 50 83 27 87 1F 0D 46 85 07 23 2C F7 1E 63 69 +D6 06 A1 47 73 B0 07 30 73 90 C9 BC 73 10 19 34 +89 67 93 87 07 88 FD 8C 73 A0 04 30 85 67 93 87 +87 88 7D 8C 73 20 44 30 13 05 C0 0F EF 10 B0 17 +72 54 B6 40 A6 42 16 43 86 43 E2 54 52 55 C2 55 +32 56 A2 56 12 57 82 57 72 48 E2 48 52 49 C2 49 +32 4E A2 4E 12 4F 82 4F 61 61 73 00 20 30 37 15 +02 50 13 05 C5 A9 EF 10 10 16 83 26 44 1F 8D B7 +83 25 87 1F 09 65 13 05 85 09 EF 10 D0 16 51 B7 +39 71 2A D6 13 05 B0 0F 3A CE 3E CC 06 DE 16 DC +1A DA 1E D8 2E D4 32 D2 36 D0 42 CA 46 C8 72 C6 +76 C4 7A C2 7E C0 EF 10 10 10 B7 37 02 50 03 A7 +47 1F 8D 47 63 E9 E7 02 13 05 C0 0F EF 10 B0 0E +F2 50 E2 52 52 53 C2 53 32 55 A2 55 12 56 82 56 +72 47 E2 47 52 48 C2 48 32 4E A2 4E 12 4F 82 4F +21 61 73 00 20 30 37 15 02 50 13 05 C5 AA EF 10 +90 0D D9 B7 39 71 3E CC B7 37 02 50 3A CE 03 A7 +47 1F 06 DE 16 DC 1A DA 1E D8 2A D6 2E D4 32 D2 +36 D0 42 CA 46 C8 72 C6 76 C4 7A C2 7E C0 91 47 +63 E5 E7 02 F2 50 E2 52 52 53 C2 53 32 55 A2 55 +12 56 82 56 72 47 E2 47 52 48 C2 48 32 4E A2 4E +12 4F 82 4F 21 61 73 00 20 30 F3 25 20 34 09 65 +13 05 C5 0A EF 10 30 09 F1 B7 1D 71 AA C2 13 05 +B0 0F A2 C6 36 DC 3E D8 86 CE 96 CC 9A CA 9E C8 +A6 C4 AE C0 32 DE 3A DA 42 D6 46 D4 4A D2 4E D0 +52 CE 72 CC 76 CA 7A C8 7E C6 37 34 02 50 EF 10 +90 01 83 26 44 1F 8D 47 63 ED D7 0C F3 27 B0 BC +73 2A C0 BC F3 29 10 34 73 29 00 30 F3 24 40 30 +73 90 C7 BC A1 47 73 A0 07 30 37 37 02 50 83 27 +87 1F 0D 46 85 07 23 2C F7 1E 63 6C D6 08 37 27 +02 30 83 27 87 81 93 F6 17 00 A5 CE B7 37 02 50 +93 87 C7 1F D4 5F 05 46 23 2C C7 80 13 E7 16 00 +D8 DF A1 47 73 B0 07 30 73 10 CA BC 73 90 19 34 +89 67 93 87 07 88 33 79 F9 00 73 20 09 30 85 67 +93 87 87 88 FD 8C 73 A0 44 30 13 05 C0 0F EF 10 +80 78 36 44 F6 40 E6 42 56 43 C6 43 A6 44 16 45 +86 45 72 56 E2 56 52 57 C2 57 32 58 A2 58 12 59 +82 59 72 4A 62 4E D2 4E 42 4F B2 4F 25 61 73 00 +20 30 C5 F3 83 27 44 1F 95 E7 05 45 EF 10 A0 74 +01 A0 83 25 87 1F 09 65 13 05 85 0B EF 10 A0 77 +B9 BF 37 15 02 50 13 05 45 AB EF 10 C0 74 83 26 +44 1F 29 BF 09 65 81 45 13 05 45 0D EF 10 A0 75 +05 45 EF 10 40 71 E9 B7 1D 71 AA C2 13 05 B0 0F +A2 C6 36 DC 3E D8 86 CE 96 CC 9A CA 9E C8 A6 C4 +AE C0 32 DE 3A DA 42 D6 46 D4 4A D2 4E D0 52 CE +72 CC 76 CA 7A C8 7E C6 37 34 02 50 EF 10 A0 6D +83 26 44 1F 8D 47 63 E3 D7 1A F3 27 B0 BC 73 2A +C0 BC F3 29 10 34 73 29 00 30 F3 24 40 30 73 90 +C7 BC A1 47 73 A0 07 30 37 37 02 50 83 27 87 1F +0D 46 85 07 23 2C F7 1E 63 62 D6 16 B7 16 03 30 +03 A7 86 81 93 77 17 00 81 CF B7 37 02 50 05 46 +23 AC C6 80 93 87 C7 1F D4 5B 93 E6 16 00 D4 DB +93 77 27 00 91 CF B7 16 03 30 B7 37 02 50 09 46 +23 AC C6 80 93 87 C7 1F D4 5B 93 E6 26 00 D4 DB +93 77 47 00 91 CF B7 16 03 30 B7 37 02 50 11 46 +23 AC C6 80 93 87 C7 1F D4 5B 93 E6 46 00 D4 DB +93 77 87 00 13 76 07 01 93 76 07 02 DD C3 37 17 +03 30 B7 37 02 50 A1 45 23 2C B7 80 93 87 C7 1F +D8 5B 13 67 87 00 D8 DB 55 CE 37 17 03 30 41 46 +23 2C C7 80 D8 5B 13 67 07 01 D8 DB 99 CA 37 17 +03 30 93 06 00 02 23 2C D7 80 D8 5B 13 67 07 02 +D8 DB A1 47 73 B0 07 30 73 10 CA BC 73 90 19 34 +89 67 93 87 07 88 33 79 F9 00 73 20 09 30 85 67 +93 87 87 88 FD 8C 73 A0 44 30 13 05 C0 0F EF 10 +80 5B 36 44 F6 40 E6 42 56 43 C6 43 A6 44 16 45 +86 45 72 56 E2 56 52 57 C2 57 32 58 A2 58 12 59 +82 59 72 4A 62 4E D2 4E 42 4F B2 4F 25 61 73 00 +20 30 05 C2 37 17 03 30 B7 37 02 50 41 46 93 87 +C7 1F 23 2C C7 80 D8 5B 13 67 07 01 D8 DB A5 FA +49 B7 B1 E6 3D FF 83 27 44 1F AD E3 05 45 EF 10 +80 55 01 A0 BD D6 37 17 03 30 93 06 00 02 23 2C +D7 80 D8 5B 13 67 07 02 D8 DB A1 BF 83 25 87 1F +09 65 13 05 85 0F EF 10 00 57 49 BD 37 15 02 50 +13 05 85 AC EF 10 20 54 83 26 44 1F B9 B5 37 17 +03 30 B7 37 02 50 93 06 00 02 93 87 C7 1F 23 2C +D7 80 D8 5B 13 67 07 02 D8 DB 21 BF 09 65 81 45 +13 05 05 11 EF 10 20 53 51 BF 1D 71 AA C2 13 05 +B0 0F A2 C6 36 DC 3E D8 86 CE 96 CC 9A CA 9E C8 +A6 C4 AE C0 32 DE 3A DA 42 D6 46 D4 4A D2 4E D0 +52 CE 72 CC 76 CA 7A C8 7E C6 37 34 02 50 EF 10 +80 4B 83 26 44 1F 8D 47 63 E3 D7 1A F3 27 B0 BC +73 2A C0 BC F3 29 10 34 73 29 00 30 F3 24 40 30 +73 90 C7 BC A1 47 73 A0 07 30 37 37 02 50 83 27 +87 1F 0D 46 85 07 23 2C F7 1E 63 62 D6 16 B7 16 +03 30 03 A7 46 81 93 77 17 00 81 CF B7 37 02 50 +05 46 23 AA C6 80 93 87 C7 1F 94 5B 93 E6 16 00 +94 DB 93 77 27 00 91 CF B7 16 03 30 B7 37 02 50 +09 46 23 AA C6 80 93 87 C7 1F 94 5B 93 E6 26 00 +94 DB 93 77 47 00 91 CF B7 16 03 30 B7 37 02 50 +11 46 23 AA C6 80 93 87 C7 1F 94 5B 93 E6 46 00 +94 DB 93 77 87 00 13 76 07 01 93 76 07 02 DD C3 +37 17 03 30 B7 37 02 50 A1 45 23 2A B7 80 93 87 +C7 1F 98 5B 13 67 87 00 98 DB 55 CE 37 17 03 30 +41 46 23 2A C7 80 98 5B 13 67 07 01 98 DB 99 CA +37 17 03 30 93 06 00 02 23 2A D7 80 98 5B 13 67 +07 02 98 DB A1 47 73 B0 07 30 73 10 CA BC 73 90 +19 34 89 67 93 87 07 88 33 79 F9 00 73 20 09 30 +85 67 93 87 87 88 FD 8C 73 A0 44 30 13 05 C0 0F +EF 10 60 39 36 44 F6 40 E6 42 56 43 C6 43 A6 44 +16 45 86 45 72 56 E2 56 52 57 C2 57 32 58 A2 58 +12 59 82 59 72 4A 62 4E D2 4E 42 4F B2 4F 25 61 +73 00 20 30 05 C2 37 17 03 30 B7 37 02 50 41 46 +93 87 C7 1F 23 2A C7 80 98 5B 13 67 07 01 98 DB +A5 FA 49 B7 B1 E6 3D FF 83 27 44 1F AD E3 05 45 +EF 10 60 33 01 A0 BD D6 37 17 03 30 93 06 00 02 +23 2A D7 80 98 5B 13 67 07 02 98 DB A1 BF 83 25 +87 1F 09 65 13 05 05 13 EF 10 E0 34 49 BD 37 15 +02 50 13 05 C5 AD EF 10 00 32 83 26 44 1F B9 B5 +37 17 03 30 B7 37 02 50 93 06 00 02 93 87 C7 1F +23 2A D7 80 98 5B 13 67 07 02 98 DB 21 BF 09 65 +81 45 13 05 85 14 EF 10 00 31 51 BF 1D 71 AA C2 +13 05 B0 0F A2 C6 36 DC 3E D8 86 CE 96 CC 9A CA +9E C8 A6 C4 AE C0 32 DE 3A DA 42 D6 46 D4 4A D2 +4E D0 52 CE 72 CC 76 CA 7A C8 7E C6 37 34 02 50 +EF 10 60 29 83 26 44 1F 8D 47 63 ED D7 0C F3 27 +B0 BC 73 2A C0 BC F3 29 10 34 73 29 00 30 F3 24 +40 30 73 90 C7 BC A1 47 73 A0 07 30 37 37 02 50 +83 27 87 1F 0D 46 85 07 23 2C F7 1E 63 6C D6 08 +37 97 02 10 83 27 87 81 93 F6 17 00 A5 CE B7 37 +02 50 93 87 C7 1F D4 57 05 46 23 2C C7 80 13 E7 +16 00 D8 D7 A1 47 73 B0 07 30 73 10 CA BC 73 90 +19 34 89 67 93 87 07 88 33 79 F9 00 73 20 09 30 +85 67 93 87 87 88 FD 8C 73 A0 44 30 13 05 C0 0F +EF 10 60 20 36 44 F6 40 E6 42 56 43 C6 43 A6 44 +16 45 86 45 72 56 E2 56 52 57 C2 57 32 58 A2 58 +12 59 82 59 72 4A 62 4E D2 4E 42 4F B2 4F 25 61 +73 00 20 30 C5 F3 83 27 44 1F 95 E7 05 45 EF 10 +80 1C 01 A0 83 25 87 1F 09 65 13 05 85 16 EF 10 +80 1F B9 BF 37 15 02 50 13 05 05 AF EF 10 A0 1C +83 26 44 1F 29 BF 09 65 81 45 13 05 05 18 EF 10 +80 1D 05 45 EF 10 20 19 E9 B7 1D 71 AA C2 13 05 +B0 0F A2 C6 36 DC 3E D8 86 CE 96 CC 9A CA 9E C8 +A6 C4 AE C0 32 DE 3A DA 42 D6 46 D4 4A D2 4E D0 +52 CE 72 CC 76 CA 7A C8 7E C6 37 34 02 50 EF 10 +80 15 83 26 44 1F 8D 47 63 ED D7 0C F3 27 B0 BC +73 2A C0 BC F3 29 10 34 73 29 00 30 F3 24 40 30 +73 90 C7 BC A1 47 73 A0 07 30 37 37 02 50 83 27 +87 1F 0D 46 85 07 23 2C F7 1E 63 6C D6 08 37 17 +02 10 83 27 87 81 93 F6 17 00 A5 CE B7 37 02 50 +93 87 C7 1F D4 53 05 46 23 2C C7 80 13 E7 16 00 +D8 D3 A1 47 73 B0 07 30 73 10 CA BC 73 90 19 34 +89 67 93 87 07 88 33 79 F9 00 73 20 09 30 85 67 +93 87 87 88 FD 8C 73 A0 44 30 13 05 C0 0F EF 10 +80 0C 36 44 F6 40 E6 42 56 43 C6 43 A6 44 16 45 +86 45 72 56 E2 56 52 57 C2 57 32 58 A2 58 12 59 +82 59 72 4A 62 4E D2 4E 42 4F B2 4F 25 61 73 00 +20 30 C5 F3 83 27 44 1F 95 E7 05 45 EF 10 A0 08 +01 A0 83 25 87 1F 09 65 13 05 05 1A EF 10 A0 0B +B9 BF 37 15 02 50 13 05 05 B0 EF 10 C0 08 83 26 +44 1F 29 BF 09 65 81 45 13 05 85 1B EF 10 A0 09 +05 45 EF 10 40 05 E9 B7 1D 71 AA C2 13 05 B0 0F +A2 C6 36 DC 3E D8 86 CE 96 CC 9A CA 9E C8 A6 C4 +AE C0 32 DE 3A DA 42 D6 46 D4 4A D2 4E D0 52 CE +72 CC 76 CA 7A C8 7E C6 37 34 02 50 EF 10 A0 01 +83 26 44 1F 8D 47 63 ED D7 0C F3 27 B0 BC 73 2A +C0 BC F3 29 10 34 73 29 00 30 F3 24 40 30 73 90 +C7 BC A1 47 73 A0 07 30 37 37 02 50 83 27 87 1F +0D 46 85 07 23 2C F7 1E 63 6C D6 08 37 17 01 10 +83 27 87 81 93 F6 17 00 A5 CE B7 37 02 50 93 87 +C7 1F D4 4B 05 46 23 2C C7 80 13 E7 16 00 D8 CB +A1 47 73 B0 07 30 73 10 CA BC 73 90 19 34 89 67 +93 87 07 88 33 79 F9 00 73 20 09 30 85 67 93 87 +87 88 FD 8C 73 A0 44 30 13 05 C0 0F EF 00 B0 78 +36 44 F6 40 E6 42 56 43 C6 43 A6 44 16 45 86 45 +72 56 E2 56 52 57 C2 57 32 58 A2 58 12 59 82 59 +72 4A 62 4E D2 4E 42 4F B2 4F 25 61 73 00 20 30 +C5 F3 83 27 44 1F 95 E7 05 45 EF 00 D0 74 01 A0 +83 25 87 1F 09 65 13 05 85 1D EF 00 D0 77 B9 BF +37 15 02 50 13 05 05 B1 EF 00 F0 74 83 26 44 1F +29 BF 09 65 81 45 13 05 C5 1E EF 00 D0 75 05 45 +EF 00 70 71 E9 B7 1D 71 AA C2 13 05 B0 0F A2 C6 +36 DC 3E D8 86 CE 96 CC 9A CA 9E C8 A6 C4 AE C0 +32 DE 3A DA 42 D6 46 D4 4A D2 4E D0 52 CE 72 CC +76 CA 7A C8 7E C6 37 34 02 50 EF 00 D0 6D 83 26 +44 1F 8D 47 63 ED D7 0C F3 27 B0 BC 73 2A C0 BC +F3 29 10 34 73 29 00 30 F3 24 40 30 73 90 C7 BC +A1 47 73 A0 07 30 37 37 02 50 83 27 87 1F 0D 46 +85 07 23 2C F7 1E 63 6C D6 08 37 97 00 10 83 27 +87 81 93 F6 17 00 A5 CE B7 37 02 50 93 87 C7 1F +D4 47 05 46 23 2C C7 80 13 E7 16 00 D8 C7 A1 47 +73 B0 07 30 73 10 CA BC 73 90 19 34 89 67 93 87 +07 88 33 79 F9 00 73 20 09 30 85 67 93 87 87 88 +FD 8C 73 A0 44 30 13 05 C0 0F EF 00 D0 64 36 44 +F6 40 E6 42 56 43 C6 43 A6 44 16 45 86 45 72 56 +E2 56 52 57 C2 57 32 58 A2 58 12 59 82 59 72 4A +62 4E D2 4E 42 4F B2 4F 25 61 73 00 20 30 C5 F3 +83 27 44 1F 95 E7 05 45 EF 00 F0 60 01 A0 83 25 +87 1F 09 65 13 05 85 20 EF 00 F0 63 B9 BF 37 15 +02 50 13 05 05 B2 EF 00 10 61 83 26 44 1F 29 BF +09 65 81 45 13 05 C5 21 EF 00 F0 61 05 45 EF 00 +90 5D E9 B7 1D 71 AA C2 13 05 B0 0F A2 C6 36 DC +3E D8 86 CE 96 CC 9A CA 9E C8 A6 C4 AE C0 32 DE +3A DA 42 D6 46 D4 4A D2 4E D0 52 CE 72 CC 76 CA +7A C8 7E C6 37 34 02 50 EF 00 F0 59 83 26 44 1F +8D 47 63 ED D7 0C F3 27 B0 BC 73 2A C0 BC F3 29 +10 34 73 29 00 30 F3 24 40 30 73 90 C7 BC A1 47 +73 A0 07 30 37 37 02 50 83 27 87 1F 0D 46 85 07 +23 2C F7 1E 63 6C D6 08 37 17 00 10 83 27 87 81 +93 F6 17 00 A5 CE B7 37 02 50 93 87 C7 1F D4 43 +05 46 23 2C C7 80 13 E7 16 00 D8 C3 A1 47 73 B0 +07 30 73 10 CA BC 73 90 19 34 89 67 93 87 07 88 +33 79 F9 00 73 20 09 30 85 67 93 87 87 88 FD 8C +73 A0 44 30 13 05 C0 0F EF 00 F0 50 36 44 F6 40 +E6 42 56 43 C6 43 A6 44 16 45 86 45 72 56 E2 56 +52 57 C2 57 32 58 A2 58 12 59 82 59 72 4A 62 4E +D2 4E 42 4F B2 4F 25 61 73 00 20 30 C5 F3 83 27 +44 1F 95 E7 05 45 EF 00 10 4D 01 A0 83 25 87 1F +09 65 13 05 85 23 EF 00 10 50 B9 BF 37 15 02 50 +13 05 05 B3 EF 00 30 4D 83 26 44 1F 29 BF 09 65 +81 45 13 05 C5 24 EF 00 10 4E 05 45 EF 00 B0 49 +E9 B7 21 47 73 30 07 30 93 07 40 12 93 E7 17 00 +73 90 57 30 97 22 02 50 93 82 C2 89 73 90 82 BC +B7 37 00 60 23 A0 07 00 0F 00 F0 0F 73 50 90 BC +B7 07 00 60 D8 C3 0F 00 F0 0F 9D 46 94 C7 0F 00 +F0 0F D8 C7 0F 00 F0 0F 94 CB 0F 00 F0 0F D8 CB +0F 00 F0 0F 94 CF 0F 00 F0 0F D8 CF 0F 00 F0 0F +94 D3 0F 00 F0 0F D8 D3 0F 00 F0 0F 94 D7 0F 00 +F0 0F D8 D7 0F 00 F0 0F 94 DB 0F 00 F0 0F 91 45 +CC DB 0F 00 F0 0F 0D 46 90 DF 0F 00 F0 0F CC DF +0F 00 F0 0F B0 C3 0F 00 F0 0F F8 C3 0F 00 F0 0F +B4 C7 0F 00 F0 0F F8 C7 0F 00 F0 0F B4 CB 0F 00 +F0 0F F8 CB 0F 00 F0 0F B4 CF 0F 00 F0 0F F8 CF +0F 00 F0 0F B4 D3 0F 00 F0 0F F8 D3 0F 00 F0 0F +B4 D7 0F 00 F0 0F 23 A6 07 06 0F 00 F0 0F 23 A8 +07 06 0F 00 F0 0F 23 AA 07 06 0F 00 F0 0F 23 AC +07 06 0F 00 F0 0F 23 AE 07 06 0F 00 F0 0F 73 50 +B0 BC 73 50 C0 BC 37 47 00 60 11 07 85 47 05 68 +79 75 93 05 00 02 23 20 07 00 0F 00 F0 0F B3 06 +07 01 23 A0 06 00 0F 00 F0 0F B3 06 A7 00 13 B6 +B7 01 90 C2 0F 00 F0 0F 85 07 93 F7 F7 0F 11 07 +E3 9B B7 FC 05 47 B7 16 00 10 23 A4 E6 80 8D 47 +23 A0 F6 80 B7 96 00 10 23 A2 E6 80 23 A4 E6 80 +23 A0 F6 80 3D 46 B7 16 01 10 23 A2 C6 80 23 A4 +E6 80 23 A0 F6 80 B7 16 02 10 23 A4 E6 80 23 A0 +F6 80 B7 96 02 10 23 A2 F6 80 23 A4 E6 80 23 A0 +F6 80 B7 16 04 10 23 A0 F6 40 23 A2 E6 40 23 A4 +F6 40 1D 46 B7 06 04 10 D0 C2 B7 86 03 10 23 A2 +E6 10 23 A4 E6 10 23 A0 F6 10 11 46 B7 16 03 30 +23 AC C6 80 21 46 23 AC C6 80 23 A4 06 98 23 A6 +06 98 93 05 F0 0F 23 A2 B6 80 93 05 F0 03 23 A4 +B6 80 23 A0 F6 80 B7 26 02 30 23 A4 E6 80 23 A0 +F6 80 37 37 02 30 93 06 F0 07 23 22 D7 80 FD 46 +23 24 D7 80 FD 55 B7 06 03 30 23 20 F7 80 23 A4 +B6 64 B7 07 00 D0 23 A6 B6 64 73 90 07 7F 73 90 +17 7F 73 90 27 7F B7 17 00 40 93 87 07 88 73 A0 +47 30 73 20 06 30 82 80 39 71 3A CE 3E CC 7D 57 +B7 07 03 30 06 DE 16 DC 1A DA 1E D8 2A D6 2E D4 +32 D2 36 D0 42 CA 46 C8 72 C6 76 C4 7A C2 7E C0 +23 A4 E7 64 23 A6 E7 64 B7 37 02 50 03 A7 47 1F +8D 47 63 E5 E7 02 F2 50 E2 52 52 53 C2 53 32 55 +A2 55 12 56 82 56 72 47 E2 47 52 48 C2 48 32 4E +A2 4E 12 4F 82 4F 21 61 73 00 20 30 37 15 02 50 +13 05 05 B4 EF 00 30 21 F9 B7 01 00 73 50 40 7D +73 00 20 30 39 71 3E CC B7 37 02 50 3A CE 03 A7 +47 1F 06 DE 16 DC 1A DA 1E D8 2A D6 2E D4 32 D2 +36 D0 42 CA 46 C8 72 C6 76 C4 7A C2 7E C0 91 47 +63 EE E7 02 B7 07 00 08 FD 17 73 B0 07 7F 73 B0 +17 7F 73 B0 27 7F F2 50 E2 52 52 53 C2 53 32 55 +A2 55 12 56 82 56 72 47 E2 47 52 48 C2 48 32 4E +A2 4E 12 4F 82 4F 21 61 73 00 20 30 37 15 02 50 +13 05 C5 B6 EF 00 30 19 75 BF 01 00 5D 71 2A DA +13 05 B0 0F 86 C6 96 C4 9A C2 9E C0 22 DE 26 DC +2E D8 32 D6 36 D4 3A D2 3E D0 42 CE 46 CC 4A CA +72 C8 76 C6 7A C4 7E C2 EF 00 F0 13 F3 24 20 34 +37 34 02 50 83 27 44 1F 05 47 63 6C F7 04 63 C5 +04 04 F3 27 F0 7F F3 27 10 34 F3 27 30 34 05 45 +EF 00 70 11 13 05 C0 0F EF 00 F0 10 72 54 B6 40 +A6 42 16 43 86 43 E2 54 52 55 C2 55 32 56 A2 56 +12 57 82 57 72 48 E2 48 52 49 42 4E B2 4E 22 4F +92 4F 61 61 73 00 20 30 B5 E3 05 45 EF 00 B0 0D +7D BF 09 69 13 09 C9 F7 A6 85 13 05 C9 2E EF 00 +90 10 83 27 44 1F E3 C1 04 FE F3 25 F0 7F 89 44 +63 FB F4 02 13 05 09 32 EF 00 F0 0E F3 25 10 34 +83 27 44 1F E3 F3 F4 F8 13 05 C9 32 EF 00 B0 0D +F3 25 30 34 83 27 44 1F E3 FB F4 F6 13 05 89 33 +EF 00 70 0C AD B7 F3 27 10 34 85 B7 09 65 FD 55 +13 05 45 28 EF 00 30 0B 49 BF 01 00 63 6E 74 5F +61 78 69 5F 64 6D 61 5F 6E 6F 74 69 66 3A 25 78 +0A 00 00 00 63 6E 74 5F 61 78 69 5F 64 6D 61 5F +65 72 72 6F 72 3A 25 78 0A 00 00 00 63 6E 74 5F +61 62 72 5F 6E 6F 74 69 66 3A 25 78 0A 00 00 00 +63 6E 74 5F 61 62 72 5F 65 72 72 6F 72 3A 25 78 +0A 00 00 00 63 6E 74 5F 73 68 61 35 31 32 5F 61 +63 63 5F 65 72 72 6F 72 3A 25 78 0A 00 00 00 00 +63 6E 74 5F 73 68 61 33 5F 6E 6F 74 69 66 3A 25 +78 0A 00 00 63 6E 74 5F 73 68 61 33 5F 65 72 72 +6F 72 3A 25 78 0A 00 00 63 6E 74 5F 73 68 61 32 +35 36 5F 65 72 72 6F 72 3A 25 78 0A 00 00 00 00 +63 6E 74 5F 73 68 61 35 31 32 5F 65 72 72 6F 72 +3A 25 78 0A 00 00 00 00 63 6E 74 5F 6B 76 5F 6E +6F 74 69 66 3A 25 78 0A 00 00 00 00 63 6E 74 5F +6B 76 5F 65 72 72 6F 72 3A 25 78 0A 00 00 00 00 +63 6E 74 5F 68 6D 61 63 5F 65 72 72 6F 72 3A 25 +78 0A 00 00 63 6E 74 5F 65 63 63 5F 65 72 72 6F +72 3A 25 78 0A 00 00 00 63 6E 74 5F 64 6F 65 5F +65 72 72 6F 72 3A 25 78 0A 00 00 00 6D 63 61 75 +73 65 3A 25 78 0A 00 00 63 6E 74 5F 73 68 61 35 +31 32 5F 61 63 63 5F 6E 6F 74 69 66 3A 25 78 0A +00 00 00 00 62 61 64 20 73 68 61 35 31 32 5F 61 +63 63 5F 6E 6F 74 69 66 5F 69 6E 74 72 20 73 74 +73 3A 25 78 0A 00 00 00 63 6E 74 5F 73 6F 63 5F +69 66 63 5F 6E 6F 74 69 66 3A 25 78 0A 00 00 00 +62 61 64 20 73 6F 63 5F 69 66 63 5F 6E 6F 74 69 +66 5F 69 6E 74 72 20 73 74 73 3A 25 78 0A 00 00 +63 6E 74 5F 73 6F 63 5F 69 66 63 5F 65 72 72 6F +72 3A 25 78 0A 00 00 00 62 61 64 20 73 6F 63 5F +69 66 63 5F 65 72 72 6F 72 5F 69 6E 74 72 20 73 +74 73 3A 25 78 0A 00 00 63 6E 74 5F 73 68 61 32 +35 36 5F 6E 6F 74 69 66 3A 25 78 0A 00 00 00 00 +62 61 64 20 73 68 61 32 35 36 5F 6E 6F 74 69 66 +5F 69 6E 74 72 20 73 74 73 3A 25 78 0A 00 00 00 +63 6E 74 5F 73 68 61 35 31 32 5F 6E 6F 74 69 66 +3A 25 78 0A 00 00 00 00 62 61 64 20 73 68 61 35 +31 32 5F 6E 6F 74 69 66 5F 69 6E 74 72 20 73 74 +73 3A 25 78 0A 00 00 00 63 6E 74 5F 68 6D 61 63 +5F 6E 6F 74 69 66 3A 25 78 0A 00 00 62 61 64 20 +68 6D 61 63 5F 6E 6F 74 69 66 5F 69 6E 74 72 20 +73 74 73 3A 25 78 0A 00 63 6E 74 5F 65 63 63 5F +6E 6F 74 69 66 3A 25 78 0A 00 00 00 62 61 64 20 +65 63 63 5F 6E 6F 74 69 66 5F 69 6E 74 72 20 73 +74 73 3A 25 78 0A 00 00 63 6E 74 5F 64 6F 65 5F +6E 6F 74 69 66 3A 25 78 0A 00 00 00 62 61 64 20 +64 6F 65 5F 6E 6F 74 69 66 5F 69 6E 74 72 20 73 +74 73 3A 25 78 0A 00 00 49 6E 3A 53 74 64 20 45 +78 63 70 74 6E 0A 6D 63 61 75 73 65 3A 25 78 0A +00 00 00 00 55 6E 65 78 70 65 63 74 65 64 20 49 +6E 74 72 20 62 69 74 3A 25 78 0A 00 6D 73 63 61 +75 73 65 3A 25 78 0A 00 6D 65 70 63 3A 25 78 0A +00 00 00 00 6D 74 76 61 6C 3A 25 78 0A 00 00 00 +03 47 05 00 63 0E 07 4E B7 3E 02 50 03 AE 0E 1F +39 71 37 0F 02 50 22 DE AA 87 26 DC 4A DA 4E D8 +52 D6 56 D4 5A D2 5E D0 01 45 93 08 50 02 13 06 +00 03 93 03 D0 02 93 02 A0 02 93 0F 00 02 13 0F +0F 00 25 44 63 03 17 03 23 20 EE 00 05 05 03 C7 +17 00 85 07 65 FB 72 54 E2 54 52 59 C2 59 32 5A +A2 5A 12 5B 82 5B 21 61 82 80 03 C7 17 00 65 D7 +85 07 63 0D 17 05 93 04 00 02 63 19 C7 00 03 C7 +17 00 85 07 E3 0D C7 FE 93 04 00 03 63 05 77 02 +63 08 57 02 13 03 07 FD 93 76 F3 0F 01 48 63 7A +D4 02 13 07 87 FA 13 77 F7 0F E3 E2 EF FA 0A 07 +7A 97 18 43 02 87 03 C7 17 00 85 07 E3 1C 57 FC +03 C7 17 00 91 05 85 07 01 48 E1 BF 23 20 1E 01 +BD BF 25 49 03 C7 17 00 93 16 28 00 C2 96 86 06 +33 08 D3 00 13 03 07 FD 93 76 F3 0F 85 07 E3 73 +D9 FE 45 BF 98 41 83 A6 0E 1F 91 05 13 58 C7 01 +63 12 08 14 13 58 87 01 63 15 08 20 13 58 47 01 +63 08 08 34 19 43 B1 AA 03 A3 05 00 81 46 91 05 +13 09 C1 00 A9 49 A5 4B 33 77 33 03 36 8B 85 06 +B3 0A D9 00 1A 8A 13 07 07 03 A3 8F EA FE 33 53 +33 03 E3 E3 4B FF 83 A9 0E 1F 33 07 69 01 36 83 +63 D7 06 01 23 A0 99 00 05 03 E3 1D 68 FE 13 03 +B1 00 03 48 07 00 7D 17 23 A0 09 01 E3 1B 67 FE +36 95 F1 BD 03 A3 05 00 91 05 83 46 03 00 E3 88 +06 EC 03 A8 0E 1F 1A 87 05 07 23 20 D8 00 83 46 +07 00 FD FA 2A 97 33 05 67 40 55 BD 98 41 91 05 +13 58 E7 01 63 16 08 18 13 58 B7 01 63 1A 08 26 +13 58 87 01 63 0E 08 28 83 A6 0E 1F A5 44 61 AA +83 AB 05 00 83 AA 0E 1F 91 05 5E 83 63 D9 0B 00 +13 07 D0 02 33 03 70 41 23 A0 EA 00 7D 18 81 46 +13 09 C1 00 A9 49 33 67 33 03 36 8B 85 06 33 0A +D9 00 33 43 33 03 13 07 07 03 A3 0F EA FE E3 14 +03 FE 33 07 69 01 36 83 63 D7 06 01 23 A0 9A 00 +05 03 E3 1D 03 FF 13 03 B1 00 03 48 07 00 7D 17 +23 A0 0A 01 E3 1B 67 FE E3 D4 0B F4 93 06 2B 00 +36 95 31 BD 83 C6 05 00 03 A7 0E 1F 05 05 91 05 +14 C3 31 B5 93 74 F8 0F 25 49 13 83 04 03 63 6B +09 1B 13 58 87 01 23 A0 66 00 13 78 F8 00 21 43 +93 04 00 03 63 18 08 0A 13 58 47 01 84 C2 13 78 +F8 00 25 49 93 74 F8 0F 63 71 09 19 93 84 74 03 +93 F4 F4 0F 13 58 07 01 84 C2 13 78 F8 00 25 49 +93 74 F8 0F 63 6F 09 19 93 84 04 03 93 F4 F4 0F +13 58 C7 00 84 C2 13 78 F8 00 25 49 93 74 F8 0F +63 6B 09 19 93 84 04 03 93 F4 F4 0F 13 58 87 00 +84 C2 13 78 F8 00 25 49 93 74 F8 0F 63 68 09 17 +93 84 04 03 93 F4 F4 0F 13 58 47 00 84 C2 13 78 +F8 00 25 49 93 74 F8 0F 63 60 09 15 13 88 04 03 +13 78 F8 0F 23 A0 06 01 93 74 F7 00 25 49 13 88 +04 03 63 54 99 00 13 88 74 03 23 A0 06 01 1A 95 +3D BB 1D 43 93 04 78 03 25 49 93 79 F8 0F 93 F4 +F4 0F E3 63 09 F5 93 89 09 03 93 F4 F9 0F 2D BF +83 A6 0E 1F 13 03 08 03 13 58 B7 01 23 A0 66 00 +13 78 78 00 AD 44 13 03 08 03 13 58 87 01 23 A0 +66 00 13 78 78 00 13 08 08 03 13 73 F8 0F 13 58 +57 01 23 A0 66 00 13 78 78 00 13 08 08 03 13 73 +F8 0F 13 58 27 01 23 A0 66 00 13 78 78 00 13 08 +08 03 13 73 F8 0F 13 58 F7 00 23 A0 66 00 13 78 +78 00 13 08 08 03 13 73 F8 0F 13 58 C7 00 23 A0 +66 00 13 78 78 00 13 08 08 03 13 73 F8 0F 13 58 +97 00 23 A0 66 00 13 78 78 00 13 08 08 03 13 73 +F8 0F 13 58 67 00 23 A0 66 00 13 78 78 00 13 08 +08 03 13 73 F8 0F 13 58 37 00 23 A0 66 00 13 78 +78 00 13 08 08 03 13 78 F8 0F 23 A0 06 01 1D 8B +13 07 07 03 98 C2 26 95 99 B9 93 84 04 03 93 F4 +F4 0F 49 B5 13 83 74 03 13 58 87 01 23 A0 66 00 +13 78 F8 00 21 43 93 04 00 03 E3 07 08 E4 DD BD +83 A6 0E 1F A9 44 05 B7 13 88 74 03 13 78 F8 0F +D1 B5 93 84 74 03 93 F4 F4 0F 9D B5 93 84 74 03 +93 F4 F4 0F 51 BD 93 84 74 03 93 F4 F4 0F BD B5 +13 58 57 01 63 0C 08 00 83 A6 0E 1F A1 44 31 B7 +13 58 07 01 63 0C 08 00 15 43 15 B5 13 58 27 01 +63 0C 08 00 83 A6 0E 1F 9D 44 11 B7 13 58 C7 00 +63 0C 08 00 11 43 15 B5 13 58 F7 00 63 0C 08 00 +83 A6 0E 1F 99 44 F5 BD 13 58 87 00 63 0C 08 00 +0D 43 15 B5 13 58 C7 00 63 0D 08 00 83 A6 0E 1F +95 44 D5 BD 13 58 47 00 05 43 E3 0F 08 E2 09 43 +0D B5 13 58 97 00 63 06 08 00 83 A6 0E 1F 91 44 +ED B5 13 58 67 00 63 06 08 00 83 A6 0E 1F 8D 44 +FD B5 13 58 37 00 63 06 08 00 83 A6 0E 1F 89 44 +CD BD 1D 8B E3 0D 07 B4 83 A6 0E 1F 85 44 CD BD +01 45 82 80 39 71 13 03 41 02 2E D2 9A 85 06 CE +32 D4 36 D6 3A D8 3E DA 42 DC 46 DE 1A C6 CD 34 +F2 40 21 61 82 80 B7 37 02 50 83 A7 07 1F 13 75 +F5 0F 88 C3 82 80 B7 37 02 50 83 A7 07 1F 13 75 +F5 0F 88 C3 82 80 83 47 05 00 37 37 02 50 03 27 +07 1F 91 C7 05 05 1C C3 83 47 05 00 E5 FF A9 47 +1C C3 05 45 82 80 39 71 13 03 41 02 2E D2 9A 85 +06 CE 32 D4 36 D6 3A D8 3E DA 42 DC 46 DE 1A C6 +41 34 F2 40 21 61 82 80 F3 25 00 B8 73 25 00 B0 +F3 27 00 B8 E3 9A F5 FE 82 80 00 00 85 47 63 13 +F6 02 93 96 85 01 93 D7 85 01 D5 8F C1 66 13 D7 +85 00 93 86 06 F0 75 8F D9 8F A2 05 37 07 FF 00 +F9 8D DD 8D 0C C1 82 80 01 11 22 CC 26 CA 4A C8 +4E C6 52 C4 06 CE B7 34 02 50 2A 89 2E 8A B2 89 +EF D0 F0 25 03 A7 44 1F 91 47 2A 84 63 EE E7 28 +93 77 14 00 63 99 07 26 13 5F 34 40 93 57 14 40 +23 A0 F9 00 CA 86 D2 8E 93 0F 1F 00 01 4E 25 48 +89 45 0D 45 91 42 95 48 99 43 21 49 85 49 63 0C +CF 1F 83 C7 06 00 13 87 07 FD 13 76 F7 0F 63 6D +C8 1A 12 07 21 46 83 C7 16 00 13 83 07 FD 13 7A +F3 0F 63 70 48 03 13 83 F7 F9 13 73 F3 0F 63 F5 +68 1E 13 83 F7 FB 13 73 F3 0F 63 E6 68 16 13 83 +97 FC 33 67 67 00 63 01 B6 14 83 C7 26 00 13 83 +07 FD 13 7A F3 0F 63 70 48 03 13 83 F7 F9 13 73 +F3 0F 63 FE 68 1A 13 83 F7 FB 13 73 F3 0F 63 EC +68 12 13 83 97 FC 32 03 33 67 67 00 63 06 A6 10 +83 C7 36 00 13 83 07 FD 13 7A F3 0F 63 70 48 03 +13 83 F7 F9 13 73 F3 0F 63 F6 68 18 13 83 F7 FB +13 73 F3 0F 63 E1 68 10 13 83 97 FC 22 03 33 67 +67 00 63 0B 56 0C 83 C7 46 00 13 83 07 FD 13 7A +F3 0F 63 70 48 03 13 83 F7 F9 13 73 F3 0F 63 FE +68 14 13 83 F7 FB 13 73 F3 0F 63 E6 68 0C 13 83 +97 FC 52 03 33 67 67 00 63 00 16 0B 83 C7 56 00 +13 83 07 FD 13 7A F3 0F 63 70 48 03 13 83 F7 F9 +13 73 F3 0F 63 F6 68 12 13 83 F7 FB 13 73 F3 0F +63 EB 68 08 13 83 97 FC 42 03 33 67 67 00 63 05 +76 06 83 C7 66 00 13 83 07 FD 13 7A F3 0F 63 70 +48 03 13 83 F7 F9 13 73 F3 0F 63 FE 68 0E 13 83 +F7 FB 13 73 F3 0F 63 E0 68 06 13 83 97 FC 72 03 +33 67 67 00 63 1A 26 03 83 C7 76 00 13 86 07 FD +13 73 F6 0F 63 70 68 02 13 86 F7 F9 13 76 F6 0F +63 F6 C8 0C 13 86 F7 FB 13 76 F6 0F 63 E5 C8 02 +13 86 97 FC 62 06 51 8F 23 A0 EE 00 05 0E 91 0E +A1 06 E3 16 FE E7 F2 40 62 44 D2 44 42 49 B2 49 +22 4A 05 61 82 80 83 A6 44 1F 11 47 E3 75 D7 FE +62 44 F2 40 D2 44 42 49 B2 49 22 4A 15 65 BE 85 +13 05 C5 A2 05 61 41 B3 21 46 13 87 F7 F9 13 77 +F7 0F 63 FF E8 00 13 87 F7 FB 13 77 F7 0F E3 E4 +E8 FC 93 87 97 FC 13 97 47 00 E3 16 36 E3 69 BF +93 87 97 FA CD BF 13 76 74 00 49 DA 83 C7 06 00 +25 43 13 87 07 FD 13 7A F7 0F E3 60 43 FD 85 47 +12 07 E3 12 F6 E0 8D BF 13 83 97 FA 1D B5 13 83 +97 FA 91 BD 13 83 97 FA 51 B5 13 83 97 FA 55 BD +13 83 97 FA D5 B5 13 83 97 FA 11 BF 13 86 97 FA +62 06 51 8F 91 B7 03 A7 44 1F 91 47 E3 F5 E7 F4 +62 44 F2 40 D2 44 42 49 B2 49 22 4A 37 15 02 50 +13 05 05 B8 05 61 C1 B1 AA 85 15 65 13 05 45 A1 +D9 39 B9 BB 79 71 22 D4 26 D2 4A D0 4E CE 52 CC +56 CA 06 D6 5A C8 5E C6 B7 39 02 50 2A 8A AE 8A +32 84 B6 84 EF D0 A0 78 03 A7 49 1F 89 47 2A 89 +63 E8 E7 2E 93 77 19 00 63 91 07 2C 13 5F 39 40 +93 57 19 40 56 86 52 88 D6 85 1C C0 93 02 1F 00 +81 46 25 43 09 45 8D 4F 91 43 15 4E 19 4A A1 4A +05 4B 63 02 DF 24 83 47 08 00 13 87 07 FD 93 78 +F7 0F 63 63 13 21 12 07 A1 48 83 47 18 00 93 8E +07 FD 93 FB FE 0F 63 70 73 03 93 8E F7 F9 93 FE +FE 0F 63 7C DE 23 93 8E F7 FB 93 FE FE 0F 63 6A +DE 1B 93 8E 97 FC 33 67 D7 01 63 82 A8 14 83 47 +28 00 93 8E 07 FD 93 FB FE 0F 63 70 73 03 93 8E +F7 F9 93 FE FE 0F 63 75 DE 21 93 8E F7 FB 93 FE +FE 0F 63 60 DE 19 93 8E 97 FC B2 0E 33 67 D7 01 +63 87 F8 11 83 47 38 00 93 8E 07 FD 93 FB FE 0F +63 70 73 03 93 8E F7 F9 93 FE FE 0F 63 7D DE 1D +93 8E F7 FB 93 FE FE 0F 63 65 DE 15 93 8E 97 FC +A2 0E 33 67 D7 01 63 8C 78 0C 83 47 48 00 93 8E +07 FD 93 FB FE 0F 63 70 73 03 93 8E F7 F9 93 FE +FE 0F 63 75 DE 1B 93 8E F7 FB 93 FE FE 0F 63 6A +DE 11 93 8E 97 FC D2 0E 33 67 D7 01 63 81 C8 0B +83 47 58 00 93 8E 07 FD 93 FB FE 0F 63 70 73 03 +93 8E F7 F9 93 FE FE 0F 63 7D DE 17 93 8E F7 FB +93 FE FE 0F 63 6F DE 0D 93 8E 97 FC C2 0E 33 67 +D7 01 63 86 48 07 83 47 68 00 93 8E 07 FD 93 FB +FE 0F 63 70 73 03 93 8E F7 F9 93 FE FE 0F 63 75 +DE 15 93 8E F7 FB 93 FE FE 0F 63 64 DE 0B 93 8E +97 FC F2 0E 33 67 D7 01 63 9B 58 03 83 47 78 00 +93 88 07 FD 93 FE F8 0F 63 70 D3 03 93 88 F7 F9 +93 F8 F8 0F 63 7D 1E 11 93 88 F7 FB 93 F8 F8 0F +63 69 1E 07 93 88 97 FC E2 08 33 67 17 01 98 C1 +85 06 91 05 21 08 E3 96 56 E6 85 47 63 90 F4 04 +1C 40 8D CF 41 68 81 45 13 08 08 F0 B7 08 FF 00 +1C 42 11 06 85 05 13 D7 87 01 13 95 87 01 93 D6 +87 00 49 8F B3 F6 06 01 A2 07 55 8F B3 F7 17 01 +D9 8F 23 2E F6 FE 1C 40 E3 EC F5 FC B2 50 22 54 +92 54 02 59 F2 49 62 4A D2 4A 42 4B B2 4B 45 61 +82 80 03 A7 49 1F 7D D3 22 54 B2 50 92 54 02 59 +F2 49 62 4A D2 4A 42 4B B2 4B 15 65 BE 85 13 05 +85 A6 45 61 6F F0 3F A6 A1 48 13 87 F7 F9 13 77 +F7 0F 63 7F EE 00 13 87 F7 FB 13 77 F7 0F E3 62 +EE FC 93 87 97 FC 13 97 47 00 E3 90 68 DF 81 BF +93 87 97 FA CD BF 93 78 79 00 E3 83 08 F4 83 47 +08 00 A5 4E 13 87 07 FD 93 7B F7 0F E3 EF 7E FB +85 47 12 07 E3 9B F8 DA 1D B7 93 8E 97 FA E1 BB +93 8E 97 FA 19 B5 93 8E 97 FA 1D BD 93 8E 97 FA +9D B5 93 8E 97 FA 59 BD 93 8E 97 FA D9 B5 93 88 +97 FA E2 08 33 67 17 01 DD BD 83 A7 49 1F 9D DF +22 54 B2 50 92 54 02 59 F2 49 62 4A D2 4A 42 4B +B2 4B 37 15 02 50 13 05 05 B8 45 61 6F F0 BF 99 +AA 85 15 65 13 05 05 A5 EF F0 FF 9A 21 B3 29 CE +85 47 63 8D F6 00 0A 06 B3 07 C5 00 18 41 11 05 +91 05 23 AE E5 FE E3 9B A7 FE 82 80 93 16 26 00 +C1 68 AA 96 93 88 08 F0 37 03 FF 00 1C 41 91 05 +11 05 13 D7 87 01 13 98 87 01 13 D6 87 00 33 67 +07 01 33 76 16 01 A2 07 51 8F B3 F7 67 00 D9 8F +23 AE F5 FE E3 1C D5 FC 82 80 37 17 01 10 83 27 +47 08 85 8B ED DF 82 80 31 71 22 DD 26 DB 80 01 +4A D9 4E D7 52 D5 56 D3 5A D1 62 CD 66 CB 06 DF +5E CF 6A C9 6E C7 36 8C 03 43 2C 00 B4 4A 83 24 +CC 05 23 2A 64 F8 03 43 3C 00 83 47 0C 00 93 F8 +F4 00 23 24 64 F8 03 43 4C 04 13 F8 F6 00 23 26 +94 F6 23 20 64 F8 03 23 4C 05 23 22 F4 FA 23 20 +14 FB 23 2C 64 F8 03 23 8C 05 23 22 D4 F8 23 28 +04 F9 83 4D 5C 04 23 26 64 F8 03 23 4C 06 93 F7 +C6 FF BD 07 23 24 64 F6 03 23 0C 07 C1 9B 33 01 +F1 40 23 2C 64 F6 03 23 4C 07 03 2B 0C 06 03 4A +8C 06 23 2A 64 F6 03 23 8C 07 93 DC 44 00 93 D9 +46 00 23 28 64 F6 03 23 CC 07 B3 38 10 01 1C 08 +23 22 64 F6 03 43 0C 08 23 26 E4 FA 2A 89 23 24 +64 FA 33 33 00 01 AE 8A B2 84 9A 99 C6 9C 23 2E +F4 F8 37 17 01 10 83 27 47 08 85 8B ED DF 83 26 +C4 FA 37 3D 02 50 05 47 83 27 4D 1F E3 82 E6 44 +09 47 63 67 F7 50 B7 27 01 10 23 AA 07 92 37 17 +01 10 83 2B 47 08 93 FB 1B 00 E3 8C 0B FE 83 27 +44 FA 95 CB 03 47 1C 00 1D E7 37 26 01 10 83 27 +46 A0 85 8B ED DF 83 27 84 F8 13 97 17 00 13 77 +E7 03 13 67 17 00 23 20 E6 A0 37 26 01 10 83 27 +46 A0 89 8B ED DF 83 27 44 FA A2 04 13 77 39 00 +13 96 B7 00 93 F4 04 70 83 27 04 F8 D9 8C 13 97 +2A 00 D1 8C 13 77 F7 0F D9 8C E3 9D 07 3C 83 28 +4D 1F 09 47 63 6E 17 29 37 17 01 10 83 27 44 F9 +64 DB 64 DB 89 EB 83 27 84 F8 63 89 07 46 37 27 +01 10 23 20 77 A1 93 07 00 02 63 8E FA 24 37 17 +01 10 83 27 47 08 85 8B ED DF 83 27 44 FA A5 EB +89 47 63 F4 17 01 6F 00 B0 71 03 27 4C 00 B7 17 +01 10 D8 C3 03 27 4C 02 D8 D3 03 27 8C 00 98 C7 +03 27 8C 02 98 D7 03 27 CC 00 D8 C7 03 27 CC 02 +D8 D7 03 27 0C 01 98 CB 03 27 0C 03 98 DB 03 27 +4C 01 D8 CB 03 27 4C 03 D8 DB 03 27 8C 01 98 CF +03 27 8C 03 98 DF 03 27 CC 01 D8 CF 03 27 CC 03 +D8 DF 03 27 0C 02 98 D3 03 27 0C 04 B8 C3 B7 17 +01 10 83 A6 47 08 85 8A ED DE 89 47 E3 E2 17 35 +03 27 CC 04 B7 17 01 10 13 06 00 02 0C 43 EC C3 +4C 43 AC C7 0C 47 EC C7 58 47 B8 CB E3 80 CA 20 +83 27 44 F8 63 8B 07 14 83 2C CC 06 85 47 E3 8B +FC 5E 63 8D 09 08 95 6C 93 87 4C A1 23 20 F4 FA +83 27 04 F9 83 2D 04 F8 81 4B FD 17 23 22 F4 F6 +83 27 C4 F8 23 2C 84 F7 23 26 04 F8 13 8B C7 00 +83 27 84 F9 5E 8C 23 20 D4 F6 93 8C C7 00 C1 67 +93 87 07 F0 23 2E F4 F8 85 67 93 87 07 80 DA 8B +23 2C F4 F8 66 8B 93 07 00 02 63 84 FA 16 37 17 +01 10 83 27 47 08 C1 8B ED DF 63 15 0A 18 89 47 +63 EF 17 37 05 47 63 00 E9 34 63 09 F9 18 63 88 +0D 1E 03 27 4D 1F 63 00 0C 58 05 0C 83 28 4D 1F +C1 0B 41 0B E3 11 3C FD 03 2C 84 F7 83 27 04 F8 +CD C7 83 27 44 F9 D5 E3 89 47 63 F4 17 01 6F 10 +A0 0C 37 27 01 10 83 27 C7 A0 89 8B ED DF 89 44 +03 49 6C 04 63 F4 14 01 6F 10 40 0C 85 47 63 14 +F9 00 6F 10 60 31 37 25 01 10 13 05 C5 A0 EF 90 +60 53 95 A0 83 27 84 FA 03 2B 04 F7 83 25 44 F7 +13 85 F7 FF 13 35 15 00 CE 87 83 29 44 F6 2A C4 +5E C2 66 C0 A6 88 83 24 44 F8 03 25 84 F7 52 86 +DA 86 4E 87 26 88 EF B0 F0 7C 83 26 C4 F9 13 DA +24 00 81 47 26 87 01 46 5A 85 CE 85 EF B0 D0 07 +63 0B 0A 00 83 27 84 FA 63 14 99 01 6F 10 E0 18 +99 E3 6F 10 60 2E 83 28 4D 1F 37 17 01 10 83 27 +47 08 85 8B ED DF 93 07 00 02 E3 85 FA 28 89 47 +E3 E9 17 41 B7 17 01 10 21 67 F8 DB F8 DB 19 47 +23 A0 E7 08 13 01 04 F4 FA 50 6A 54 DA 54 4A 59 +BA 59 2A 5A 9A 5A 0A 5B FA 4B 6A 4C DA 4C 4A 4D +BA 4D 29 61 82 80 37 17 01 10 83 27 47 08 85 8B +ED DF 93 07 10 40 23 24 F7 08 23 24 F7 08 41 BB +95 68 13 85 C8 AA A6 85 EF F0 EF D1 83 28 4D 1F +A1 BB 93 87 F9 FF 63 03 0C 6C E3 1A FC E8 83 27 +04 F9 E3 86 07 E8 93 95 67 00 93 E5 85 00 37 17 +01 10 83 27 47 08 85 8B ED DF 23 24 B7 08 23 24 +B7 08 B5 B5 64 5B 03 27 84 F9 89 47 B9 8C 63 E8 +17 1F 05 47 63 09 E9 1A 63 12 F9 04 03 27 4D 1F +91 4C 63 E0 EC 20 83 26 C4 FA 85 45 83 A7 4B FF +63 8A B6 5C 37 17 01 10 7C CB 03 A7 8B FF B7 17 +01 10 B8 CF 03 A7 CB FF B7 17 01 10 F8 CF 83 A7 +0B 00 37 17 01 10 3C D3 E3 0B 0A E2 B7 17 01 10 +03 27 4D 1F E4 DB E4 DB 89 47 E3 F2 E7 E2 B7 17 +02 50 13 85 C7 CA EF F0 0F C5 E3 9C 0D E0 37 17 +01 10 83 27 47 08 A1 8B ED DF B7 07 03 30 83 A7 +C7 54 85 8B 95 CB 83 27 84 F7 83 26 44 FA 23 80 +D7 00 83 26 44 F9 23 81 D7 00 83 26 84 F8 A3 81 +D7 00 8C 43 B7 07 00 FF 93 87 F7 0F FD 8D B7 07 +00 10 85 07 63 89 F5 62 37 17 01 10 83 27 47 08 +91 8B 99 C7 83 27 84 FA 99 E3 6F 10 20 05 81 47 +37 17 01 10 83 25 4D 1F 83 2C 47 06 0D 47 63 67 +B7 4A 03 27 C4 F8 93 08 F7 FF 13 87 F9 FF 46 8F +63 0E 87 21 63 93 07 24 85 45 63 03 B9 5A 89 45 +E3 0F B9 08 B7 15 01 10 03 25 4D 1F 83 AC 85 06 +8D 45 63 E9 A5 48 FA 8F 63 04 87 1B 63 9D 07 1C +85 45 63 00 B9 5A 89 45 E3 02 B9 00 B7 15 01 10 +03 25 4D 1F 83 AC C5 06 8D 45 63 E9 A5 48 FE 88 +63 01 87 25 63 98 07 26 85 45 63 0B B9 5A 89 45 +E3 08 B9 06 B7 15 01 10 03 25 4D 1F 83 AC 05 07 +8D 45 63 E9 A5 12 63 02 87 27 63 93 07 28 85 47 +63 02 F9 60 89 47 E3 1A F9 D0 83 27 84 FA E3 96 +07 D0 83 27 0B 00 5A 87 B3 C7 FC 00 B3 F7 17 01 +E3 8D 07 CE E6 87 8D 45 6F 00 60 7B 8D 4B 41 BE +37 15 02 50 13 05 85 BD EF F0 EF B0 B7 27 01 10 +23 AA 07 92 ED B4 03 27 4D 1F 91 4C 63 E6 EC 34 +83 26 C4 FA 85 45 83 27 4B FF 63 83 B6 28 37 17 +01 10 7C CB 03 27 8B FF B7 17 01 10 B8 CF 03 27 +CB FF B7 17 01 10 F8 CF 83 27 0B 00 99 BD 83 27 +04 FA E2 85 13 85 C7 21 EF F0 EF AD 85 47 E3 0C +F9 FA 89 47 E3 12 F9 E4 03 27 4D 1F 91 4C E3 F4 +EC E0 83 27 04 FA 83 A5 4B FF 93 87 C7 23 3E 85 +23 2E F4 F6 EF F0 2F AB 83 26 C4 FA 85 45 03 27 +4D 1F 83 A7 4B FF 63 8F B6 3A 37 13 01 10 23 2A +F3 04 E3 F4 EC DE 83 A5 8B FF 03 25 C4 F7 EF F0 +8F A8 03 A7 8B FF 83 27 4D 1F 37 13 01 10 23 2C +E3 04 E3 F9 FC DC 83 A5 CB FF 03 25 C4 F7 EF F0 +8F A6 03 27 4D 1F 83 A7 CB FF B7 15 01 10 FC CD +91 47 E3 FE E7 DA 83 A5 0B 00 03 25 C4 F7 EF F0 +8F A4 75 B3 23 2A F4 F6 83 27 04 FA E6 85 23 28 +14 F7 13 85 C7 29 23 2E E4 F6 EF F0 CF A2 03 27 +C4 F7 83 28 04 F7 83 27 44 F7 E3 18 87 EB 31 A2 +83 26 04 F9 E3 8C 06 E4 83 26 44 F8 93 F5 C6 00 +E3 86 05 E4 93 FF 86 00 E3 9B 0F 3E 93 F5 36 00 +83 26 04 F6 8E 05 05 4F 33 1F BF 00 23 26 D4 F8 +7D 1F E3 87 07 E2 83 26 84 FA E3 99 06 E2 B3 FC +EC 01 E3 85 0C E2 E6 87 85 45 91 A0 83 26 04 F9 +E3 82 06 DE 83 26 44 F8 13 FF C6 00 E3 14 0F 16 +93 F5 36 00 83 26 04 F6 8E 05 85 48 B3 98 B8 00 +23 26 D4 F8 FD 18 E3 81 07 DC 83 26 84 FA E3 93 +06 DC B3 FC 1C 01 E3 8F 0C DA E6 87 81 45 95 64 +93 84 44 A1 13 85 04 2B 23 26 F4 FA EF F0 AF 97 +83 27 C4 FA 13 85 84 2D BE 85 EF F0 CF 96 37 15 +02 50 13 05 C5 D2 EF F0 0F 94 05 45 EF F0 AF 91 +01 A0 83 26 44 F6 A9 45 E3 EE D5 DA 83 26 44 F8 +93 F5 86 00 E3 88 05 DA 93 F5 36 00 83 26 04 F6 +8E 05 85 4F B3 9F BF 00 23 26 D4 F8 FD 1F 81 48 +E3 8C 07 D8 83 26 84 FA E3 9E 06 D8 B3 FC FC 01 +E3 8A 0C D8 E6 87 89 45 59 B7 83 26 04 F9 2D 47 +E3 7D D7 D8 03 27 44 F8 85 48 0D 8B 0E 07 B3 98 +E8 00 03 27 04 F6 FD 18 23 26 E4 F8 E3 81 07 D8 +83 27 84 FA E3 9B 07 A8 B3 FC 1C 01 E3 87 0C A8 +E6 87 8D 45 A9 B7 83 27 44 FA E3 80 07 A8 89 47 +63 E7 E7 02 B7 25 01 10 83 A7 45 A0 89 8B ED DF +83 26 44 F9 85 47 E3 8E F6 50 89 47 63 EC E7 7A +37 25 01 10 13 05 45 A0 EF 80 D0 7D B9 B4 37 15 +02 50 13 05 05 D4 EF F0 0F 87 03 27 4D 1F D9 B7 +83 26 C4 F9 93 D5 87 01 93 98 87 01 13 D5 87 00 +75 8D B3 E5 15 01 C9 8D A2 07 37 05 FF 00 E9 8F +CD 8F B7 15 01 10 FC C9 91 47 63 ED E7 34 83 27 +8B FF 83 26 C4 F9 93 D5 87 01 93 98 87 01 13 D5 +87 00 75 8D B3 E5 15 01 C9 8D A2 07 37 05 FF 00 +E9 8F CD 8F B7 15 01 10 BC CD 91 47 63 E3 E7 30 +83 27 CB FF 83 26 C4 F9 93 D5 87 01 93 98 87 01 +13 D5 87 00 75 8D B3 E5 15 01 C9 8D A2 07 37 05 +FF 00 E9 8F CD 8F B7 15 01 10 FC CD 91 47 63 EB +E7 2A 83 27 0B 00 83 26 C4 F9 13 D7 87 01 13 95 +87 01 93 D5 87 00 F5 8D 49 8F 4D 8F A2 07 B7 05 +FF 00 ED 8F D9 8F 35 BE 83 25 4B FF 95 67 13 85 +87 C6 EF E0 5F FC 83 26 C4 FA 85 45 03 27 4D 1F +83 27 4B FF E3 86 B6 F2 B7 18 01 10 23 AA F8 04 +E3 F2 EC CA 83 25 8B FF 95 67 13 85 87 C6 EF E0 +9F F9 03 27 8B FF 83 27 4D 1F B7 18 01 10 23 AC +E8 04 E3 F6 FC C8 83 25 CB FF 95 67 13 85 87 C6 +EF E0 7F F7 03 27 4D 1F 83 27 CB FF B7 15 01 10 +FC CD 91 47 E3 FA E7 C6 83 25 0B 00 95 67 13 85 +87 C6 EF E0 5F F5 83 27 0B 00 65 BC 23 2E F4 F6 +83 27 04 FA E6 85 13 85 C7 29 EF E0 DF F3 83 27 +C4 F7 81 B6 23 2A F4 F6 83 27 04 FA E6 85 23 28 +E4 F7 13 85 C7 29 23 2E E4 F6 EF E0 DF F1 03 2F +04 F7 83 27 44 F7 03 27 C4 F7 B1 B6 23 2A F4 F6 +83 27 04 FA E6 85 23 28 F4 F7 13 85 C7 29 23 2E +E4 F6 EF E0 5F EF 83 2F 04 F7 83 27 44 F7 03 27 +C4 F7 B1 B6 83 26 C4 F9 93 D5 87 01 93 98 87 01 +13 D5 87 00 75 8D B3 E5 15 01 C9 8D A2 07 37 05 +FF 00 E9 8F CD 8F B7 15 01 10 FC C9 91 47 63 E7 +E7 5A 83 A7 8B FF 83 26 C4 F9 93 D5 87 01 93 98 +87 01 13 D5 87 00 75 8D B3 E5 15 01 C9 8D A2 07 +37 05 FF 00 E9 8F CD 8F B7 15 01 10 BC CD 91 47 +63 E9 E7 54 83 A7 CB FF 83 26 C4 F9 93 D5 87 01 +93 98 87 01 13 D5 87 00 75 8D B3 E5 15 01 C9 8D +A2 07 37 05 FF 00 E9 8F CD 8F B7 15 01 10 FC CD +91 47 63 E0 E7 50 83 A7 0B 00 B1 BD 85 47 93 05 +80 40 E3 96 F9 94 83 27 04 F9 E3 82 07 94 25 BA +83 26 84 FA E3 90 06 A6 83 A5 4B FF B3 C5 BC 00 +B3 F5 15 01 E3 88 05 A4 E6 87 93 82 4B FF 81 45 +8D A0 83 26 84 FA E3 93 06 A6 83 A5 8B FF B3 C5 +BC 00 B3 F5 E5 01 E3 8B 05 A4 E6 87 93 82 8B FF +FA 88 85 45 3D A8 85 47 E3 98 FA 9C 83 27 47 08 +91 8B 89 E7 83 27 84 FA E3 88 07 3E 85 47 C9 BA +83 26 84 FA E3 98 06 A4 83 A5 CB FF B3 C5 BC 00 +B3 F5 F5 01 E3 80 05 A4 E6 87 93 82 CB FF FE 88 +89 45 95 64 93 84 44 A1 13 85 04 2F 23 24 54 FA +23 22 14 FB 23 26 F4 FA EF E0 FF D9 83 27 C4 FA +83 28 44 FA 13 85 84 31 B3 F5 F8 00 23 26 14 FB +EF E0 7F D8 83 22 84 FA 83 28 C4 FA 13 85 04 33 +83 A5 02 00 B3 F5 B8 00 EF E0 FF D6 05 45 EF E0 +9F D2 01 A0 83 27 84 FA 63 99 07 F0 83 A7 0B 00 +DE 82 B3 C7 FC 00 B3 F7 17 01 63 80 07 F0 E6 87 +8D 45 41 BF 83 25 0B 00 95 67 13 85 87 C6 EF E0 +9F D3 83 26 C4 FA 05 47 83 27 0B 00 E3 8D E6 D2 +49 B8 83 25 CB FF 95 67 13 85 87 C6 EF E0 BF D1 +83 26 C4 FA 85 45 03 27 4D 1F 83 27 CB FF E3 83 +B6 CE 69 BB 83 25 8B FF 95 67 13 85 87 C6 EF E0 +9F CF 03 27 4D 1F 83 27 8B FF 61 B9 83 27 C4 F6 +63 80 07 E0 63 8E 0C DE 03 27 04 FA 93 DF 27 00 +85 47 BA 9F 5A 8F 63 8B FC 72 13 06 40 40 C1 45 +95 67 93 87 47 A1 23 2E F4 F6 C1 67 0D 4B 93 87 +07 F0 23 2E 94 F4 23 2C 34 F5 E6 84 81 4D DA 8C +B7 1B 01 10 56 8B 23 20 F4 F6 CA 8A 23 2A D4 F4 +FE 89 7A 89 83 A7 4B 08 85 8B ED DF 89 47 63 E0 +17 67 23 A4 CB 08 23 A4 CB 08 83 A7 4B 08 C1 8B +ED DF 89 47 63 E5 17 5D 93 97 2D 00 63 E0 37 4F +23 AA 0B 04 93 87 EC FF 63 E4 37 43 23 AC 0B 04 +93 87 FC FF 63 F9 37 57 03 27 C4 FA 85 46 83 27 +89 00 63 0A D7 5C 23 AE FB 04 63 FC 3C 45 83 27 +C9 00 23 A0 FB 06 85 0D 41 09 91 0C 63 8A B4 45 +93 87 F4 FF 63 8C B7 5D 89 47 E3 F0 17 FB B7 17 +02 50 13 85 87 C2 EF E0 1F BF 83 28 4D 1F 71 B7 +09 47 63 67 F7 5C B7 27 01 10 05 47 23 AA E7 92 +6F F0 EF BB 03 26 8C 04 37 25 01 10 EE 85 13 05 +85 A0 EF 80 50 40 83 28 4D 1F 09 47 63 7E 17 C1 +95 68 EE 85 13 85 C8 A8 EF E0 FF BC 6F F0 2F C0 +37 15 02 50 13 05 85 C1 23 2E D4 F6 EF E0 BF B9 +83 28 4D 1F 83 26 C4 F7 6F F0 8F CA 83 26 84 FA +63 9E 06 FE 83 25 8B FF B3 C5 BC 00 B3 F5 E5 01 +63 86 05 FE E6 87 13 07 8B FF FA 88 85 45 95 64 +93 84 44 A1 13 85 84 34 23 24 E4 FA 23 22 14 FB +23 26 F4 FA EF E0 3F B7 83 27 C4 FA 83 28 44 FA +13 85 04 37 B3 F5 F8 00 23 26 14 FB EF E0 BF B5 +03 27 84 FA 83 28 C4 FA 13 85 84 38 0C 43 B3 F5 +B8 00 EF E0 5F B4 05 45 EF E0 FF AF 01 A0 83 26 +84 FA 63 91 06 F6 83 25 4B FF B3 C5 BC 00 B3 F5 +15 01 63 89 05 F4 E6 87 13 07 4B FF 81 45 41 BF +83 26 84 FA 63 98 06 F8 83 25 CB FF B3 C5 BC 00 +B3 F5 F5 01 63 80 05 F8 E6 87 13 07 CB FF FE 88 +89 45 B5 B7 83 27 44 F9 63 9B 07 D6 03 25 C4 F6 +B7 05 FF 00 13 06 00 42 93 16 35 00 93 17 B5 00 +ED 8F 13 D9 86 00 93 D5 86 01 C1 66 23 24 C7 08 +CD 8F 93 86 06 F0 93 15 B5 01 33 79 D9 00 CD 8F +23 24 C7 08 11 47 33 69 F9 00 63 60 17 69 03 27 +C4 FA B7 17 01 10 23 AA 07 04 85 47 63 15 F7 02 +93 16 89 01 93 57 89 01 D5 8F C1 66 13 57 89 00 +93 86 06 F0 75 8F D9 8F 22 09 37 07 FF 00 33 79 +E9 00 33 E9 27 01 03 26 44 F8 B7 06 FF 00 93 17 +36 00 13 17 B6 00 75 8F 93 D6 87 01 93 D4 87 00 +B3 67 D7 00 41 67 13 07 07 F0 F9 8C 93 16 B6 01 +37 17 01 10 D5 8F 23 2C 27 05 11 47 DD 8C 63 6D +17 5F 03 27 C4 FA B7 17 01 10 23 AE 07 04 85 47 +63 13 F7 02 93 96 84 01 93 D7 84 01 D5 8F C1 66 +13 D7 84 00 93 86 06 F0 75 8F D9 8F A2 04 37 07 +FF 00 F9 8C DD 8C B7 17 01 10 A4 D3 37 17 01 10 +83 27 47 08 A1 8B ED DF 03 27 C4 FA 85 47 63 0E +F7 4E 83 25 84 F6 41 46 13 05 04 FB 23 26 14 FB +EF C0 00 26 83 28 C4 FA 89 47 63 E8 17 4B 83 27 +84 FA 63 90 07 44 B7 17 01 10 E4 53 83 27 04 FB +63 9F 97 7A B7 17 01 10 03 27 4D 1F A4 57 8D 47 +63 EB E7 68 83 27 44 FB 63 9A 97 74 37 19 01 10 +83 27 4D 1F 83 24 C9 06 0D 4A 63 62 FA 64 83 27 +84 FB 95 68 93 88 48 A1 63 91 F4 78 83 24 09 07 +83 27 C4 FB 63 96 97 76 83 28 4D 1F 89 47 63 FB +17 BF 37 15 02 50 13 05 C5 E0 EF E0 DF 93 6F F0 +6F BE 83 A5 0B 00 15 65 13 05 05 C5 EF E0 BF 94 +83 26 C4 FA 05 47 83 A7 0B 00 E3 86 E6 94 6F F0 +4F CA 83 A5 CB FF 15 65 93 07 05 C5 3E 85 23 2E +F4 F6 EF E0 5F 92 83 26 C4 FA 85 45 03 27 4D 1F +83 A7 CB FF E3 8A B6 A8 6F F0 2F EB 83 A5 8B FF +15 65 13 05 05 C5 EF E0 1F 90 03 27 4D 1F 83 A7 +8B FF 91 B4 37 15 02 50 13 05 45 D7 EF E0 BF 8C +6F F0 1F 84 89 44 83 49 1C 08 63 ED 14 2D 63 84 +99 31 81 44 81 49 01 4A 83 47 2C 08 93 8B 0A FE +85 4C 93 BB 1B 00 63 97 97 AD 03 27 4D 1F 89 47 +63 EE E7 48 85 47 3E C0 5E C2 03 27 44 F6 03 28 +44 F8 83 26 04 F7 03 25 84 F7 83 25 44 F7 CE 87 +A6 88 52 86 EF B0 00 38 13 07 40 06 B7 17 01 10 +83 A6 47 08 7D 17 F4 DB F4 DB 7D FB 37 15 02 50 +13 05 05 C7 EF E0 3F 85 05 45 EF E0 DF 82 01 A0 +37 15 02 50 13 05 05 C0 EF E0 FF 83 83 28 4D 1F +6F F0 AF 8D 46 8F 6F F0 EF C6 63 FB 17 01 83 25 +49 00 95 67 13 85 07 B3 EF E0 FF 83 83 28 4D 1F +03 27 C4 FA 85 46 83 27 49 00 63 05 D7 06 23 AC +FB 04 13 86 FC FF 8D 47 63 6A 36 0D 63 FD 17 13 +83 27 C4 F7 B2 85 13 85 87 0F EF E0 DF 80 83 28 +4D 1F 23 AE 0B 04 8D 47 63 E1 3C 0F 63 FB 17 01 +83 27 C4 F7 E6 85 13 85 87 0F EF E0 CF FE 83 28 +4D 1F 23 A0 0B 06 85 0D 41 09 91 0C E3 9A B4 BB +56 89 83 24 C4 F5 83 29 84 F5 83 26 44 F5 DA 8A +6F F0 0F 8E 03 27 04 F6 93 D6 87 01 93 95 87 01 +13 D6 87 00 79 8E CD 8E D1 8E A2 07 37 06 FF 00 +F1 8F D5 8F AD BF 63 FB 17 01 83 25 09 00 95 67 +13 85 07 B3 EF E0 2F F9 83 28 4D 1F 03 27 C4 FA +85 46 83 27 09 00 63 0F D7 06 23 AA FB 04 13 86 +EC FF 8D 47 E3 63 36 F3 E3 FA 17 B1 83 27 C4 F7 +B2 85 13 85 87 0F EF E0 0F F6 83 28 4D 1F 13 86 +FC FF 23 AC 0B 04 8D 47 E3 7A 36 F3 E3 FE 17 AF +83 25 89 00 95 67 13 85 07 B3 EF E0 CF F3 03 27 +C4 FA 85 46 83 28 4D 1F 83 27 89 00 63 0D D7 0A +23 AE FB 04 8D 47 E3 F3 3C F3 63 F2 17 05 83 25 +C9 00 95 67 66 86 13 85 07 B3 EF E0 CF F0 83 28 +4D 1F 35 A0 03 27 04 F6 93 D6 87 01 93 95 87 01 +13 D6 87 00 79 8E CD 8E D1 8E A2 07 37 06 FF 00 +F1 8F D5 8F 9D B7 23 AE 0B 04 E3 FC 3C EF 03 27 +C4 FA 85 46 83 27 C9 00 E3 1D D7 A8 03 27 04 F6 +93 D6 87 01 93 95 87 01 13 D6 87 00 79 8E CD 8E +D1 8E A2 07 37 06 FF 00 F1 8F D5 8F 9D BC 83 27 +C4 F7 EE 85 13 85 07 0E EF E0 EF E9 13 96 2D 00 +83 28 4D 1F 8D 47 E3 68 36 EF E3 F3 17 A3 83 27 +C4 F7 B2 85 13 85 87 0F EF E0 EF E7 83 28 4D 1F +23 AA 0B 04 ED BD 03 27 04 F6 93 D6 87 01 93 95 +87 01 13 D6 87 00 79 8E CD 8E D1 8E A2 07 37 06 +FF 00 F1 8F D5 8F 23 AE FB 04 2D B7 83 27 04 FA +E3 84 07 A2 13 96 67 00 BE 85 13 66 46 00 5D B2 +37 15 02 50 13 05 45 BB EF E0 EF E0 2D B4 15 65 +13 05 C5 AC 23 28 C4 F4 EF E0 EF E1 03 26 04 F5 +83 28 4D 1F 23 A4 CB 08 23 A4 CB 08 F5 B2 FA 8F +6F F0 CF A4 03 27 04 F7 83 26 44 F6 03 26 84 F7 +83 25 44 F7 95 68 13 85 48 B5 EF E0 CF DE E3 9A +99 D1 83 27 4D 1F 63 F8 F4 00 37 15 02 50 13 05 +05 C4 EF E0 4F DB D1 44 EF B0 10 47 13 7A F5 0F +EF B0 90 46 93 79 F5 0F EF B0 10 46 33 77 95 02 +B3 67 3A 01 85 8B D9 8F E5 D3 85 47 13 7A 1A 00 +93 F9 19 00 BA 84 23 24 F4 FA F9 B1 13 06 40 40 +C1 45 E3 07 07 8C 13 16 67 00 BA 85 13 66 46 00 +C1 B0 B7 17 01 10 FC 53 B7 19 01 10 83 27 4D 1F +83 A5 89 06 0D 49 63 6B F9 1E B7 17 01 10 FC 57 +B7 17 01 10 BC 5B CD BE 37 15 02 50 13 05 C5 D8 +EF E0 6F D3 83 28 4D 1F 6F E0 BF F2 37 15 02 50 +13 05 C5 DA EF E0 2F D2 85 47 63 0D F9 22 83 27 +4D 1F 63 E4 F4 00 6F E0 1F F3 37 15 02 50 13 05 +C5 DD EF E0 4F D0 6F E0 1F F2 37 15 02 50 13 05 +05 DF EF E0 4F CF 83 27 84 FA 03 27 4D 1F 63 87 +07 22 B7 17 01 10 EC 53 8D 46 63 F5 E6 24 15 65 +13 05 85 DE EF E0 2F CF 85 BF 83 27 84 F6 41 6F +13 0F 0F F0 94 43 03 A8 47 00 88 47 DC 47 13 DE +86 01 93 95 86 01 93 D4 86 00 13 16 88 01 93 5A +88 01 93 53 88 00 13 5A 85 01 93 19 85 01 93 52 +85 00 13 D7 87 01 13 99 87 01 93 DE 87 00 B7 0F +FF 00 B3 E5 C5 01 B3 F4 E4 01 13 9E 86 00 33 66 +56 01 B3 F3 E3 01 22 08 B3 66 3A 01 B3 F2 E2 01 +22 05 33 67 27 01 B3 FE EE 01 A2 07 C5 8D 33 7E +FE 01 33 66 76 00 33 78 F8 01 B3 E6 56 00 33 75 +F5 01 33 67 D7 01 B3 F7 F7 01 B3 E5 C5 01 33 66 +06 01 C9 8E D9 8F 23 28 B4 FA 23 2A C4 FA 23 2C +D4 FA 23 2E F4 FA 8D BC 95 68 13 85 C8 DC A6 85 +EF E0 6F C3 83 28 4D 1F ED BA 95 68 13 85 48 DB +CA 85 EF E0 4F C2 83 28 4D 1F 95 BA 37 15 02 50 +13 05 45 C5 EF E0 2F BF B1 BE 99 C3 6F E0 BF E7 +83 29 C4 F8 83 27 C4 F9 81 44 94 43 03 A7 09 00 +63 8A E6 04 15 69 13 09 49 A1 A6 85 13 05 C9 16 +EF E0 6F BE 03 27 C4 F9 93 97 24 00 13 05 49 19 +BA 97 8C 43 EF E0 2F BD 83 A5 09 00 13 05 C9 1A +EF E0 6F BC 05 45 EF E0 0F B8 01 A0 83 25 47 08 +15 65 13 05 05 C8 91 89 EF E0 EF BA 05 45 EF E0 +8F B6 01 A0 85 04 91 09 91 07 E3 10 9A FA 6F E0 +9F E0 89 47 63 E9 E7 0C 37 25 01 10 13 05 45 A0 +EF 80 60 31 83 28 4D 1F 6F E0 3F DF 95 64 93 84 +84 DE 26 85 EF E0 2F B7 83 27 4D 1F 83 A5 C9 06 +E3 70 F9 E0 26 85 EF E0 0F B6 83 27 4D 1F 83 A5 +09 07 E3 73 F9 9E 26 85 EF E0 EF B4 F1 BA 95 68 +93 88 48 A1 93 89 48 3D A6 85 4E 85 23 26 14 FB +EF E0 6F B3 83 27 84 FB 83 28 C4 FA 63 97 97 12 +83 27 4D 1F 83 24 09 07 E3 74 FA 9A A6 85 4E 85 +EF E0 6F B1 71 BA 95 68 A6 85 13 85 88 DE EF E0 +8F B0 8D B2 83 27 4D 1F 63 F8 F4 00 37 15 02 50 +13 05 85 DC EF E0 2F AD 37 25 01 10 13 05 C5 A0 +EF 80 60 27 83 28 4D 1F 6F E0 3F D5 B7 17 01 10 +E4 53 8D 47 E3 FC E7 90 95 68 A6 85 13 85 88 DE +EF E0 6F AC 21 B2 37 15 02 50 13 05 05 D6 EF E0 +8F A9 1D B7 BC 57 91 B3 89 47 63 04 F9 00 6F E0 +9F D1 83 29 84 F9 83 27 C4 F9 81 44 83 A6 09 00 +98 43 63 8E E6 02 15 69 13 09 49 A1 A6 85 13 05 +49 1C EF E0 4F A8 03 27 C4 F9 93 97 24 00 13 05 +C9 1E BA 97 8C 43 EF E0 0F A7 83 A5 09 00 13 05 +49 20 EF E0 4F A6 05 45 EF E0 EF A1 01 A0 85 04 +91 09 91 07 E3 1C 9A FA 6F E0 FF CB 95 68 05 49 +93 88 48 A1 CA 85 13 85 08 3E 23 26 14 FB EF E0 +8F A3 83 28 C4 FA A6 85 13 85 48 40 EF E0 AF A2 +03 27 84 F6 93 17 29 00 83 28 C4 FA BA 97 8C 43 +13 85 C8 41 EF E0 2F A1 05 45 EF E0 CF 9C 01 A0 +95 68 0D 49 93 88 48 A1 75 BF 09 49 65 BF 95 68 +01 49 93 88 48 A1 7D B7 37 15 02 50 13 05 C5 CC +EF E0 6F 9C 05 45 EF E0 0F 9A 01 A0 13 01 01 C9 +23 26 71 35 B7 3B 02 50 23 2A 51 35 83 AA 4B 1F +23 24 81 36 23 22 91 36 23 20 21 37 23 2C 41 35 +23 28 61 35 2E CF 23 26 11 36 23 2E 31 35 23 24 +81 35 2A CD 89 45 32 84 36 8B 3A 8A 3E 89 C2 84 +63 EC 55 31 C1 47 63 F8 67 01 63 9A 0A 32 05 45 +EF E0 6F 94 01 A0 B7 08 02 50 93 85 48 08 BC 19 +93 88 48 08 13 88 05 04 03 A5 08 00 03 A6 48 00 +83 A6 88 00 03 A7 C8 00 88 C3 D0 C3 94 C7 D8 C7 +C1 08 C1 07 E3 92 08 FF B7 17 58 26 93 87 37 92 +3E D7 3E DF B7 47 63 94 93 87 F7 37 BE C5 B7 27 +2F FE 93 87 97 6E B7 D6 E2 95 BE C7 B7 D7 DC 33 +83 A8 05 05 93 86 B6 DA 93 87 37 85 03 AF 05 04 +83 AE 45 04 03 AE 85 04 03 A3 C5 04 03 A8 45 05 +A8 4D F0 4D 37 47 EA D5 36 D9 BE C9 B7 86 41 5B +B7 07 22 B3 13 07 27 D1 93 87 37 50 93 86 06 37 +3A D5 3A DD C6 D5 BE CB 36 DB 82 C1 82 C3 FA CD +F6 CF F2 D1 9A D3 C2 D7 AA D9 B2 DB 93 87 05 06 +38 1A 93 88 05 0A 03 A8 07 00 C8 43 90 47 D4 47 +23 20 07 01 48 C3 10 C7 54 C7 C1 07 41 07 E3 94 +17 FF 93 87 05 0A B8 1A 93 88 05 0E 03 A8 07 00 +C8 43 90 47 D4 47 23 20 07 01 48 C3 10 C7 54 C7 +C1 07 41 07 E3 94 17 FF 93 87 05 0E 38 1B 93 88 +05 12 03 A8 07 00 C8 43 90 47 D4 47 23 20 07 01 +48 C3 10 C7 54 C7 C1 07 41 07 E3 94 17 FF 93 88 +05 12 BC 1B 13 88 05 16 03 A5 08 00 03 A6 48 00 +83 A6 88 00 03 A7 C8 00 88 C3 D0 C3 94 C7 D8 C7 +C1 08 C1 07 E3 92 08 FF 93 88 05 16 3C 1C 13 88 +05 1A 03 A5 08 00 03 A6 48 00 83 A6 88 00 03 A7 +C8 00 88 C3 D0 C3 94 C7 D8 C7 C1 08 C1 07 E3 92 +08 FF 93 88 05 1A BC 1C 93 85 05 1E 03 A5 08 00 +03 A6 48 00 83 A6 88 00 03 A7 C8 00 88 C3 D0 C3 +94 C7 D8 C7 C1 08 C1 07 E3 92 B8 FE 13 06 80 08 +81 45 28 1D EF B0 30 1A 93 3B 19 00 C1 47 85 0B +63 82 F4 16 85 47 13 0C 81 17 63 81 F4 02 93 07 +00 02 63 88 F4 16 89 47 63 8A F4 16 91 47 63 83 +F4 18 A1 47 93 09 81 0A 63 83 F4 18 5E 57 23 22 +04 02 23 24 04 02 18 D0 4E 57 23 26 04 02 23 28 +04 02 58 CC 3E 57 23 2A 04 02 23 2C 04 02 18 CC +2E 57 23 2E 04 02 23 20 04 04 58 C8 1E 57 18 C8 +0E 57 58 C4 6E 47 58 C0 7E 47 18 C4 63 14 0B 00 +13 0B 00 04 89 47 63 E0 57 13 13 16 2B 00 63 0E +09 0C E2 85 52 85 EF B0 A0 7C BC 01 23 2E F1 30 +22 86 3C 1D 13 08 04 04 08 42 4C 42 14 46 58 46 +88 C3 CC C3 94 C7 D8 C7 41 06 C1 07 E3 16 06 FF +10 42 EA 46 7A 47 90 C3 BC 19 23 26 F1 30 85 47 +23 00 F1 32 23 22 31 31 23 24 61 31 23 28 81 31 +23 2E D1 2E 23 20 E1 30 3C 1D 0A 88 28 1E 8C 43 +D0 43 94 47 D8 47 23 20 B8 00 23 22 C8 00 23 24 +D8 00 23 26 E8 00 C1 07 41 08 E3 92 A7 FE 83 A8 +07 00 DC 43 8A 86 A6 85 5E 85 01 47 11 46 23 20 +18 01 23 22 F8 00 EF E0 2F D7 83 20 C1 36 03 24 +81 36 83 24 41 36 03 29 01 36 83 29 C1 35 03 2A +81 35 83 2A 41 35 03 2B 01 35 83 2B C1 34 03 2C +81 34 13 01 01 37 82 80 37 15 02 50 13 05 45 E2 +EF D0 7F E5 83 AA 4B 1F F1 B9 AC 19 52 85 EF B0 +20 6F 25 B7 93 09 81 0B 13 0C 81 27 C1 B5 15 65 +DA 85 13 05 85 E4 EF D0 1F E5 05 45 EF D0 BF E0 +D1 B1 93 09 81 0A 13 0C 81 13 4D B5 93 09 81 0A +13 0C 81 1B 61 BD 15 65 DA 85 13 05 05 EA EF D0 +9F E2 E1 BD 93 09 81 0A 13 0C 81 1F 41 B5 13 0C +81 23 AD BD 53 74 72 69 6E 67 20 6C 65 6E 67 74 +68 20 69 73 20 25 64 2E 0A 00 00 00 45 72 72 6F +72 3A 20 49 6E 76 61 6C 69 64 20 68 65 78 20 63 +68 61 72 61 63 74 65 72 3A 20 25 63 0A 00 00 00 +53 74 72 69 6E 67 20 6C 65 6E 67 74 68 20 69 73 +20 25 64 2E 0A 00 00 00 45 72 72 6F 72 3A 20 49 +6E 76 61 6C 69 64 20 68 65 78 20 63 68 61 72 61 +63 74 65 72 3A 20 25 63 0A 00 00 00 53 65 74 20 +41 45 53 20 4B 56 20 57 72 69 74 65 20 74 6F 20 +73 6C 6F 74 20 25 64 0A 00 00 00 00 57 72 69 74 +65 20 41 45 53 20 43 54 52 4C 20 77 69 74 68 20 +76 61 6C 75 65 20 30 78 25 78 0A 00 57 72 69 74 +65 20 47 43 4D 5F 41 41 44 20 50 68 61 73 65 2C +20 4E 55 4D 5F 42 59 54 45 53 20 30 78 25 78 0A +00 00 00 00 57 72 69 74 65 20 41 45 53 20 41 41 +44 20 42 6C 6F 63 6B 20 25 64 0A 00 50 61 64 64 +69 6E 67 20 41 41 44 20 77 69 74 68 20 30 73 20 +41 41 44 20 44 57 4F 52 44 3A 20 25 64 00 00 00 +57 72 69 74 65 20 49 6E 20 44 61 74 61 3A 20 30 +78 25 78 20 61 61 64 20 44 57 4F 52 44 3A 20 25 +64 0A 00 00 53 52 43 3A 20 7B 20 30 78 25 30 78 +5F 25 30 78 20 7D 20 74 6F 20 44 53 54 3A 20 7B +20 30 78 25 30 78 5F 25 30 78 20 7D 0A 00 00 00 +41 74 20 6F 66 66 73 65 74 20 5B 25 64 5D 2C 20 +6F 75 74 70 75 74 20 64 61 74 61 20 6D 69 73 6D +61 74 63 68 21 0A 00 00 41 63 74 75 61 6C 20 20 +20 64 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +45 78 70 65 63 74 65 64 20 64 61 74 61 3A 20 30 +78 25 78 0A 00 00 00 00 41 74 20 6F 66 66 73 65 +74 20 5B 25 64 5D 2C 20 6F 75 74 70 75 74 20 64 +61 74 61 20 6D 69 73 6D 61 74 63 68 21 0A 00 00 +41 63 74 75 61 6C 20 20 20 64 61 74 61 3A 20 30 +78 25 78 0A 00 00 00 00 45 78 70 65 63 74 65 64 +20 64 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +57 72 69 74 65 20 41 45 53 20 49 6E 70 75 74 20 +44 61 74 61 20 42 6C 6F 63 6B 20 25 64 0A 00 00 +57 72 69 74 65 20 49 6E 20 44 61 74 61 3A 20 30 +78 25 78 0A 00 00 00 00 57 72 69 74 65 20 49 6E +20 44 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +45 58 50 45 43 54 45 44 20 4F 55 54 50 55 54 5F +4C 4F 53 54 20 74 6F 20 62 65 20 30 78 30 20 2D +20 41 63 74 75 61 6C 3A 20 30 78 25 78 00 00 00 +43 49 50 48 45 52 54 45 58 54 3A 20 30 78 25 78 +0A 00 00 00 41 74 20 6F 66 66 73 65 74 20 5B 25 +64 5D 2C 20 6F 75 74 70 75 74 20 64 61 74 61 20 +6D 69 73 6D 61 74 63 68 21 0A 00 00 41 63 74 75 +61 6C 20 20 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 41 74 20 6F 66 66 73 65 74 20 5B 25 +64 5D 2C 20 6F 75 74 70 75 74 20 64 61 74 61 20 +6D 69 73 6D 61 74 63 68 21 0A 00 00 41 63 74 75 +61 6C 20 20 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 45 78 70 65 63 74 65 64 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 41 74 20 6F +66 66 73 65 74 20 5B 25 64 5D 2C 20 6F 75 74 70 +75 74 20 64 61 74 61 20 6D 69 73 6D 61 74 63 68 +21 0A 00 00 41 63 74 75 61 6C 20 20 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 45 78 70 65 +63 74 65 64 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 57 72 69 74 65 20 41 41 44 20 4C 65 +6E 67 74 68 3A 20 30 78 25 78 0A 00 57 72 69 74 +65 20 54 65 78 74 20 4C 65 6E 67 74 68 3A 20 30 +78 25 78 0A 00 00 00 00 54 41 47 3A 20 30 78 25 +78 0A 00 00 41 74 20 6F 66 66 73 65 74 20 5B 25 +64 5D 2C 20 74 61 67 20 64 61 74 61 20 6D 69 73 +6D 61 74 63 68 21 0A 00 41 63 74 75 61 6C 20 20 +20 64 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +45 78 70 65 63 74 65 64 20 64 61 74 61 3A 20 30 +78 25 78 0A 00 00 00 00 45 52 52 4F 52 3A 20 6F +76 65 72 72 69 64 65 5F 74 65 78 74 5F 6C 65 6E +67 74 68 20 28 25 64 29 20 65 78 63 65 65 64 73 +20 6D 61 78 69 6D 75 6D 20 61 6C 6C 6F 77 65 64 +20 73 69 7A 65 20 6F 66 20 31 36 20 64 77 6F 72 +64 73 20 28 35 31 32 20 62 69 74 73 29 0A 00 00 +50 6F 70 75 6C 61 74 65 20 4B 56 20 77 69 74 68 +20 6B 65 79 20 6C 65 6E 67 74 68 3A 20 25 64 0A +00 00 79 71 4A D0 37 39 02 50 03 28 49 1F 22 D4 +26 D2 4E CE 52 CC 56 CA 5A C8 06 D6 5E C6 89 48 +AA 8A 2E 8B 32 8A 36 84 BA 89 BE 84 63 E6 08 1B +83 A6 0A 00 B7 07 00 10 13 87 47 00 94 C3 83 A6 +4A 00 D4 C3 83 A7 8A 00 5C C3 83 A7 CA 00 1C C7 +93 16 24 00 93 F6 C6 07 93 E6 16 00 B7 07 00 10 +94 CB 37 04 00 10 54 48 89 8A F5 DE 8D 4A 63 EC +0A 11 83 26 0B 00 B7 07 00 10 13 87 47 00 94 C3 +83 26 4B 00 D4 C3 83 27 8B 00 5C C3 83 27 CB 00 +1C C7 13 97 29 00 13 77 C7 07 13 67 27 00 B7 07 +00 10 98 CB 37 04 00 10 58 48 09 8B 75 DF 8D 49 +63 E3 09 07 83 27 0A 00 37 07 00 10 93 06 47 00 +1C C3 03 26 4A 00 B7 07 03 30 83 A7 07 0E 50 C3 +03 27 8A 00 93 F7 07 04 D8 C2 03 27 CA 00 98 C6 +C1 C3 93 97 24 00 93 F7 C7 07 93 E7 07 08 37 07 +00 10 1C CB 5C 4B 89 8B F5 DF 8D 47 63 E7 07 15 +B2 50 22 54 92 54 02 59 F2 49 62 4A D2 4A 42 4B +B2 4B 45 61 82 80 37 15 02 50 13 05 85 EF EF D0 +9F 82 03 28 49 1F E3 F7 09 F9 37 15 02 50 13 05 +85 F2 EF D0 5F 81 83 27 0A 00 03 28 49 1F 1C C0 +83 26 4A 00 B7 07 03 30 83 A7 07 0E 54 C0 83 26 +8A 00 93 F7 07 04 14 C4 83 26 CA 00 54 C4 F9 EB +89 47 E3 FF 07 F9 37 15 02 50 13 05 05 F9 22 54 +B2 50 92 54 02 59 F2 49 62 4A D2 4A 42 4B B2 4B +45 61 6F D0 4F FC 37 15 02 50 13 05 05 E8 EF D0 +8F FB 03 28 49 1F E3 FE 0A ED 37 15 02 50 13 05 +85 EA EF D0 4F FA 03 27 0B 00 03 28 49 1F 18 C0 +03 27 4B 00 58 C0 03 27 8B 00 18 C4 03 27 CB 00 +58 C4 E3 F8 0A ED 37 15 02 50 13 05 85 EC EF D0 +8F F7 03 28 49 1F 75 BD 37 15 02 50 13 05 85 E3 +EF D0 6F F6 03 28 49 1F 8D 4B E3 F3 0B E5 37 15 +02 50 13 05 45 E4 EF D0 0F F5 03 A7 0A 00 B7 07 +00 10 03 28 49 1F 98 C3 83 A6 4A 00 13 87 47 00 +D4 C3 83 A7 8A 00 5C C3 83 A7 CA 00 1C C7 E3 F9 +0B E3 37 15 02 50 13 05 85 E5 EF D0 CF F1 03 28 +49 1F 39 BD E3 F7 09 EB 37 15 02 50 13 05 C5 F3 +EF D0 6F F0 03 28 49 1F 69 BD 37 15 02 50 13 05 +45 F6 31 BF B7 37 02 50 03 A7 47 1F 8D 47 63 E7 +E7 00 B7 07 00 10 0D 47 98 CB 82 80 37 15 02 50 +41 11 13 05 45 FC 06 C6 EF D0 EF EC B2 40 B7 07 +00 10 0D 47 98 CB 41 01 82 80 00 00 41 11 22 C4 +37 34 02 50 03 27 44 1F 06 C6 89 47 63 E0 E7 04 +37 37 02 50 13 07 C7 1F 1C 47 54 47 D5 8F 9D E3 +73 00 50 10 93 07 40 06 01 00 FD 17 C2 07 C1 83 +E5 FF 1C 47 54 47 D5 8F E5 D7 83 26 44 1F 89 47 +63 E5 D7 02 B2 40 22 44 41 01 82 80 37 15 02 50 +13 05 85 FD EF D0 2F E6 37 37 02 50 13 07 C7 1F +1C 47 54 47 D5 8F CD DF C9 BF 22 44 4C 47 B2 40 +10 47 19 65 13 05 C5 73 41 01 6F D0 CF E5 B7 37 +02 50 03 A7 47 1F 89 47 63 E7 E7 00 B7 87 00 10 +11 47 98 CB 82 80 37 15 02 50 41 11 13 05 05 FF +06 C6 EF D0 4F E1 B2 40 B7 87 00 10 11 47 98 CB +41 01 82 80 79 71 26 D2 4A D0 56 CA 5A C8 06 D6 +22 D4 4E CE 52 CC 5E C6 83 4B 15 00 03 CA 06 00 +36 8B 3E 89 B2 86 BA 8A C2 84 B7 87 00 10 80 4F +05 88 75 DC 03 47 05 00 63 03 07 3C 13 97 1B 00 +13 77 E7 03 13 67 17 00 23 A4 E7 60 23 A0 07 08 +23 A2 07 08 23 A4 07 08 23 A6 07 08 23 A8 07 08 +23 AA 07 08 23 AC 07 08 23 AE 07 08 23 A0 07 0A +23 A2 07 0A 23 A4 07 0A 23 A6 07 0A 37 87 00 10 +83 27 C7 60 89 8B ED DF 63 0D 0A 00 83 47 1B 00 +37 87 00 10 86 07 93 F7 E7 03 93 E7 17 20 23 28 +F7 60 D8 41 B7 87 00 10 B7 39 02 50 23 A0 E7 50 +98 45 09 46 23 A2 E7 50 D8 45 23 A4 E7 50 98 49 +23 A6 E7 50 D8 49 23 A8 E7 50 98 4D 23 AA E7 50 +D8 4D 23 AC E7 50 98 51 23 AE E7 50 D8 51 23 A0 +E7 52 98 55 23 A2 E7 52 D8 55 23 A4 E7 52 98 59 +23 A6 E7 52 D8 42 23 A0 E7 48 98 46 23 A2 E7 48 +D8 46 23 A4 E7 48 98 4A 23 A6 E7 48 D8 4A 23 A8 +E7 48 98 4E 23 AA E7 48 D8 4E 23 AC E7 48 98 52 +23 AE E7 48 D8 52 23 A0 E7 4A 98 56 23 A2 E7 4A +D8 56 23 A4 E7 4A 98 5A 23 A6 E7 4A 03 A7 49 1F +63 6B E6 30 B7 87 00 10 85 46 94 CB 63 93 0B 00 +0D 44 B7 87 00 10 23 A4 87 60 23 A0 07 08 23 A2 +07 08 23 A4 07 08 23 A6 07 08 23 A8 07 08 23 AA +07 08 23 AC 07 08 23 AE 07 08 23 A0 07 0A 23 A2 +07 0A 23 A4 07 0A 23 A6 07 0A 89 47 63 EE E7 2A +37 37 02 50 13 07 C7 1F 1C 47 54 47 D5 8F 91 EF +73 00 50 10 93 07 40 06 01 00 FD 17 C2 07 C1 83 +E5 FF 1C 47 54 47 D5 8F E5 D7 83 A7 49 1F 09 44 +63 6D F4 0A 63 1E 0A 0C B7 87 00 10 03 AA 07 18 +03 24 4B 00 63 1C 8A 2A 03 AA 47 18 03 24 8B 00 +63 15 8A 30 03 AA 87 18 03 24 CB 00 63 11 8A 30 +03 AA C7 18 03 24 0B 01 63 1D 8A 2E 03 AA 07 19 +03 24 4B 01 63 19 8A 2E 03 AA 47 19 03 24 8B 01 +63 15 8A 2E 03 AA 87 19 03 24 CB 01 63 11 8A 2E +03 AA C7 19 03 24 0B 02 63 1D 8A 2C 03 AA 07 1A +03 24 4B 02 63 13 8A 2E 03 AA 47 1A 03 24 8B 02 +63 1F 8A 2C 03 AA 87 1A 03 24 CB 02 63 15 8A 2C +03 AA C7 1A 03 24 0B 03 AD 45 63 1A 8A 22 85 47 +63 89 F4 04 B2 50 22 54 92 54 02 59 F2 49 62 4A +D2 4A 42 4B B2 4B 45 61 82 80 4C 47 10 47 19 65 +13 05 C5 73 EF D0 2F BA 83 A7 49 1F 63 0E 0A 1C +63 78 F4 00 37 15 02 50 13 05 05 01 EF D0 AF B6 +37 87 00 10 83 27 47 61 89 8B ED DF 85 47 E3 9B +F4 FA 03 A7 49 1F 89 47 63 E1 E7 1C B7 87 00 10 +83 A4 07 20 03 A4 4A 00 63 99 84 20 83 A4 47 20 +03 A4 8A 00 63 99 84 22 83 A4 87 20 03 A4 CA 00 +63 95 84 22 83 A4 C7 20 03 A4 0A 01 63 91 84 22 +83 A4 07 21 03 A4 4A 01 63 9D 84 20 83 A4 47 21 +03 A4 8A 01 63 91 84 1E 83 A4 87 21 03 A4 CA 01 +63 99 84 2A 83 A4 C7 21 03 A4 0A 02 63 91 84 2A +83 A4 07 22 03 A4 4A 02 63 99 84 28 83 A4 47 22 +03 A4 8A 02 63 91 84 28 83 A4 87 22 03 A4 CA 02 +63 99 84 26 83 A4 C7 22 03 A4 0A 03 AD 45 63 97 +84 18 89 47 63 EC E7 16 B7 87 00 10 83 A4 07 28 +03 24 49 00 63 15 94 24 83 A4 47 28 03 24 89 00 +63 1D 94 22 83 A4 87 28 03 24 C9 00 63 15 94 22 +83 A4 C7 28 03 24 09 01 63 9D 84 20 83 A4 07 29 +03 24 49 01 63 95 84 20 83 A4 47 29 03 24 89 01 +63 9D 84 1E 83 A4 87 29 03 24 C9 01 63 95 84 1E +83 A4 C7 29 03 24 09 02 63 9D 84 1C 83 A4 07 2A +03 24 49 02 63 95 84 1C 83 A4 47 2A 03 24 89 02 +63 9D 84 1A 83 A4 87 2A 03 24 C9 02 63 95 84 1A +83 A4 C7 2A 03 24 09 03 AD 45 E3 8D 84 E6 83 A7 +49 1F 63 90 07 16 05 45 EF D0 EF 9E 01 A0 58 41 +23 A0 E7 08 18 45 23 A2 E7 08 58 45 23 A4 E7 08 +18 49 23 A6 E7 08 58 49 23 A8 E7 08 18 4D 23 AA +E7 08 58 4D 23 AC E7 08 18 51 23 AE E7 08 58 51 +23 A0 E7 0A 18 55 23 A2 E7 0A 58 55 23 A4 E7 0A +18 59 23 A6 E7 0A 89 B1 37 15 02 50 13 05 85 FD +EF D0 6F 9B 35 BB 37 15 02 50 13 05 45 00 EF D0 +8F 9A 03 A7 49 1F F9 B9 E3 70 F4 D6 37 15 02 50 +13 05 45 02 EF D0 2F 99 81 BB 37 15 02 50 13 05 +05 04 EF D0 4F 98 03 A7 49 1F 0D BD 81 45 83 A7 +49 1F 89 E7 05 45 EF D0 0F 95 01 A0 99 64 93 84 +C4 73 13 85 44 03 EF D0 0F 98 83 A7 49 1F FD D3 +D2 85 13 85 04 06 EF D0 0F 97 83 A7 49 1F F9 DB +A2 85 13 85 84 07 EF D0 0F 96 E9 B7 37 15 02 50 +13 05 C5 05 EF D0 2F 93 41 B5 81 45 39 E3 05 45 +EF D0 6F 90 01 A0 95 45 D5 BF 85 45 4D B7 89 45 +79 BF 8D 45 69 BF 91 45 59 BF 95 45 49 BF 99 45 +79 B7 9D 45 69 B7 85 45 D1 BF 89 45 C1 BF 8D 45 +F1 B7 91 45 E1 B7 A9 45 9D BF A1 45 8D BF A5 45 +BD B7 19 69 13 09 C9 73 13 05 09 09 EF D0 AF 8F +83 A7 49 1F CD D7 A6 85 13 05 09 0C EF D0 AF 8E +83 A7 49 1F C9 DF A2 85 13 05 89 0D EF D0 AF 8D +79 B7 19 69 13 09 C9 73 13 05 09 0F EF D0 AF 8C +83 A7 49 1F E3 89 07 E8 A6 85 13 05 09 12 EF D0 +8F 8B 83 A7 49 1F E3 80 07 E8 A2 85 13 05 89 13 +EF D0 6F 8A 8D BD A9 45 9D B5 A5 45 8D B5 A1 45 +B9 BD 9D 45 A9 BD 99 45 99 BD 95 45 89 BD 91 45 +B9 B5 8D 45 A9 B5 89 45 99 B5 85 45 89 B5 81 45 +3D BD A9 45 25 B7 A5 45 15 B7 A1 45 05 B7 9D 45 +31 BF 99 45 21 BF 79 71 4E CE 52 CC 5A C8 5E C6 +06 D6 22 D4 26 D2 4A D0 56 CA 83 CA 15 00 83 44 +07 00 BA 89 2A 8A B2 8B 36 8B B7 87 00 10 80 4F +05 88 75 DC 03 C7 05 00 63 0D 07 2C 13 97 1A 00 +13 77 E7 03 13 67 17 00 23 A0 E7 60 37 87 00 10 +83 27 47 60 89 8B ED DF 37 39 02 50 03 27 49 1F +89 47 63 E3 E7 30 03 A6 4B 00 B7 87 00 10 89 46 +23 A0 C7 20 03 A6 8B 00 23 A2 C7 20 03 A6 CB 00 +23 A4 C7 20 03 A6 0B 01 23 A6 C7 20 03 A6 4B 01 +23 A8 C7 20 03 A6 8B 01 23 AA C7 20 03 A6 CB 01 +23 AC C7 20 03 A6 0B 02 23 AE C7 20 03 A6 4B 02 +23 A0 C7 22 03 A6 8B 02 23 A2 C7 22 03 A6 CB 02 +23 A4 C7 22 03 A6 0B 03 23 A6 C7 22 63 E7 E6 2C +83 26 4B 00 B7 87 00 10 23 A0 D7 28 83 26 8B 00 +23 A2 D7 28 83 26 CB 00 23 A4 D7 28 83 26 0B 01 +23 A6 D7 28 83 26 4B 01 23 A8 D7 28 83 26 8B 01 +23 AA D7 28 83 26 CB 01 23 AC D7 28 83 26 0B 02 +23 AE D7 28 83 26 4B 02 23 A0 D7 2A 83 26 8B 02 +23 A2 D7 2A 83 26 CB 02 23 A4 D7 2A 83 26 0B 03 +23 A6 D7 2A 83 26 4A 00 23 A0 D7 48 83 26 8A 00 +23 A2 D7 48 83 26 CA 00 23 A4 D7 48 83 26 0A 01 +23 A6 D7 48 83 26 4A 01 23 A8 D7 48 83 26 8A 01 +23 AA D7 48 83 26 CA 01 23 AC D7 48 83 26 0A 02 +23 AE D7 48 83 26 4A 02 23 A0 D7 4A 83 26 8A 02 +23 A2 D7 4A 83 26 CA 02 23 A4 D7 4A 83 26 0A 03 +23 A6 D7 4A 81 CC 83 C6 19 00 05 66 13 06 16 AC +86 06 93 F6 F6 0F D1 8E 23 A8 D7 60 89 47 63 ED +E7 1C B7 87 00 10 C1 46 94 CB 63 93 0A 00 0D 44 +B7 87 00 10 23 A0 87 60 23 A0 07 58 23 A2 07 58 +23 A4 07 58 23 A6 07 58 23 A8 07 58 23 AA 07 58 +23 AC 07 58 23 AE 07 58 23 A0 07 5A 23 A2 07 5A +23 A4 07 5A 23 A6 07 5A 89 47 63 E0 E7 18 37 37 +02 50 13 07 C7 1F 1C 47 54 47 D5 8F 91 EF 73 00 +50 10 93 07 40 06 01 00 FD 17 C2 07 C1 83 E5 FF +1C 47 54 47 D5 8F E5 D7 83 27 49 1F 09 44 63 69 +F4 0A E9 E8 B7 87 00 10 83 A4 07 5C 03 A4 49 00 +63 1F 94 16 83 A4 47 5C 03 A4 89 00 63 1B 94 1A +83 A4 87 5C 03 A4 C9 00 63 97 84 1A 83 A4 C7 5C +03 A4 09 01 63 93 84 1A 83 A4 07 5D 03 A4 49 01 +63 9F 84 18 83 A4 47 5D 03 A4 89 01 63 9B 84 18 +83 A4 87 5D 03 A4 C9 01 63 97 84 18 83 A4 C7 5D +03 A4 09 02 63 93 84 18 83 A4 07 5E 03 A4 49 02 +63 9F 84 16 83 A4 47 5E 03 A4 89 02 63 9B 84 16 +83 A4 87 5E 03 A4 C9 02 63 93 84 14 83 A4 C7 5E +03 A4 09 03 AD 45 63 9D 84 0E B2 50 22 54 92 54 +02 59 F2 49 62 4A D2 4A 42 4B B2 4B 45 61 82 80 +4C 47 10 47 19 65 13 05 C5 73 EF C0 DF D7 83 27 +49 1F CD CC 63 78 F4 00 37 15 02 50 13 05 05 01 +EF C0 7F D4 37 87 00 10 83 27 47 61 89 8B ED DF +6D BF D8 41 37 39 02 50 23 A0 E7 58 98 45 23 A2 +E7 58 D8 45 23 A4 E7 58 98 49 23 A6 E7 58 D8 49 +23 A8 E7 58 98 4D 23 AA E7 58 D8 4D 23 AC E7 58 +98 51 23 AE E7 58 D8 51 23 A0 E7 5A 98 55 23 A2 +E7 5A D8 55 23 A4 E7 5A 98 59 23 A6 E7 5A 03 27 +49 1F 89 47 E3 F1 E7 D0 37 15 02 50 13 05 85 07 +EF C0 7F CD 03 27 49 1F FD B1 37 15 02 50 13 05 +85 FD EF C0 5F CC A5 BD 37 15 02 50 13 05 05 0B +EF C0 7F CB 03 27 49 1F 29 BD 37 15 02 50 13 05 +45 09 EF C0 5F CA 03 27 49 1F 1D B3 E3 74 F4 E8 +37 15 02 50 13 05 05 0C EF C0 FF C8 A5 BD 81 45 +83 27 49 1F 89 E7 05 45 EF C0 FF C5 01 A0 99 69 +93 89 C9 73 13 85 09 15 EF C0 FF C8 83 27 49 1F +FD D3 A6 85 13 85 09 18 EF C0 FF C7 83 27 49 1F +F9 DB A2 85 13 85 89 19 EF C0 FF C6 E9 B7 A9 45 +C1 B7 85 45 75 BF 89 45 65 BF 8D 45 55 BF 91 45 +45 BF 95 45 75 B7 99 45 65 B7 9D 45 55 B7 A1 45 +45 B7 A5 45 71 BF 79 71 26 D2 4E CE 52 CC 5A C8 +5E C6 06 D6 22 D4 4A D0 56 CA 83 4A 15 00 BE 84 +AE 8B 32 8B B6 89 3A 8A B7 87 00 10 80 4F 05 88 +75 DC 83 46 05 00 37 39 02 50 03 27 49 1F 63 87 +06 32 89 47 63 E9 E7 38 93 96 1A 00 93 F6 E6 03 +B7 87 00 10 93 E6 16 00 23 A0 D7 60 23 A0 07 58 +23 A2 07 58 23 A4 07 58 23 A6 07 58 23 A8 07 58 +23 AA 07 58 23 AC 07 58 23 AE 07 58 23 A0 07 5A +23 A2 07 5A 23 A4 07 5A 23 A6 07 5A B7 86 00 10 +83 A7 46 60 89 8B ED DF 03 A6 4B 00 B7 87 00 10 +89 46 23 A0 C7 10 03 A6 8B 00 23 A2 C7 10 03 A6 +CB 00 23 A4 C7 10 03 A6 0B 01 23 A6 C7 10 03 A6 +4B 01 23 A8 C7 10 03 A6 8B 01 23 AA C7 10 03 A6 +CB 01 23 AC C7 10 03 A6 0B 02 23 AE C7 10 03 A6 +4B 02 23 A0 C7 12 03 A6 8B 02 23 A2 C7 12 03 A6 +CB 02 23 A4 C7 12 03 A6 0B 03 23 A6 C7 12 03 26 +4B 00 23 A0 C7 48 03 26 8B 00 23 A2 C7 48 03 26 +CB 00 23 A4 C7 48 03 26 0B 01 23 A6 C7 48 03 26 +4B 01 23 A8 C7 48 03 26 8B 01 23 AA C7 48 03 26 +CB 01 23 AC C7 48 03 26 0B 02 23 AE C7 48 03 26 +4B 02 23 A0 C7 4A 03 26 8B 02 23 A2 C7 4A 03 26 +CB 02 23 A4 C7 4A 03 26 0B 03 23 A6 C7 4A 63 E3 +E6 26 B7 87 00 10 89 46 94 CB 63 93 0A 00 0D 44 +B7 87 00 10 23 A0 87 60 23 A0 07 58 23 A2 07 58 +23 A4 07 58 23 A6 07 58 23 A8 07 58 23 AA 07 58 +23 AC 07 58 23 AE 07 58 23 A0 07 5A 23 A2 07 5A +23 A4 07 5A 23 A6 07 5A 89 47 63 E6 E7 20 37 37 +02 50 13 07 C7 1F 1C 47 54 47 D5 8F 91 EF 73 00 +50 10 93 07 40 06 01 00 FD 17 C2 07 C1 83 E5 FF +1C 47 54 47 D5 8F E5 D7 83 26 49 1F 09 44 63 60 +D4 02 85 47 63 83 F4 04 B2 50 22 54 92 54 02 59 +F2 49 62 4A D2 4A 42 4B B2 4B 45 61 82 80 4C 47 +10 47 19 65 13 05 C5 73 EF C0 FF A3 85 47 E3 9D +F4 FC 83 26 49 1F 63 7A D4 00 37 15 02 50 13 05 +05 11 EF C0 5F A0 83 26 49 1F B7 87 00 10 83 A4 +07 30 03 A4 49 00 63 99 84 1A 83 A4 47 30 03 A4 +89 00 63 9C 84 22 83 A4 87 30 03 A4 C9 00 63 9E +84 20 83 A4 C7 30 03 A4 09 01 63 9A 84 20 83 A4 +07 31 03 A4 49 01 63 96 84 20 83 A4 47 31 03 A4 +89 01 63 92 84 20 83 A4 87 31 03 A4 C9 01 63 90 +84 20 83 A4 C7 31 03 A4 09 02 63 9C 84 1E 83 A4 +07 32 03 A4 49 02 63 98 84 1C 83 A4 47 32 03 A4 +89 02 63 90 84 1C 83 A4 87 32 03 A4 C9 02 63 98 +84 1A 83 A4 C7 32 03 A4 09 03 AD 45 63 97 84 12 +89 47 63 E9 D7 12 B7 87 00 10 83 A4 07 38 03 24 +4A 00 63 94 84 18 83 A4 47 38 03 24 8A 00 63 1C +94 16 83 A4 87 38 03 24 CA 00 63 94 84 16 83 A4 +C7 38 03 24 0A 01 63 1C 94 14 83 A4 07 39 03 24 +4A 01 63 94 84 14 83 A4 47 39 03 24 8A 01 63 9C +84 12 83 A4 87 39 03 24 CA 01 63 94 84 12 83 A4 +C7 39 03 24 0A 02 63 9C 84 10 83 A4 07 3A 03 24 +4A 02 63 94 84 10 83 A4 47 3A 03 24 8A 02 63 9C +84 0E 83 A4 87 3A 03 24 CA 02 63 94 84 0E 83 A4 +C7 3A 03 24 0A 03 AD 45 E3 88 84 E8 83 27 49 1F +63 93 07 12 05 45 EF C0 1F 8A 01 A0 54 41 23 A0 +D7 58 14 45 23 A2 D7 58 54 45 23 A4 D7 58 14 49 +23 A6 D7 58 54 49 23 A8 D7 58 14 4D 23 AA D7 58 +54 4D 23 AC D7 58 14 51 23 AE D7 58 54 51 23 A0 +D7 5A 14 55 23 A2 D7 5A 54 55 23 A4 D7 5A 14 59 +23 A6 D7 5A D5 B1 37 15 02 50 13 05 85 FD EF C0 +9F 86 F5 B3 37 15 02 50 13 05 05 10 EF C0 BF 85 +03 27 49 1F 79 B3 37 15 02 50 13 05 05 0E EF C0 +9F 84 03 27 49 1F 8D B1 81 45 81 EE 05 45 EF C0 +9F 81 01 A0 37 15 02 50 13 05 C5 12 EF C0 BF 82 +D9 B5 99 69 93 89 C9 73 13 85 09 1B EF C0 BF 83 +83 27 49 1F E1 DF A6 85 13 85 C9 1D EF C0 BF 82 +83 27 49 1F E1 D7 A2 85 13 85 49 1F EF C0 BF 81 +75 BF A9 45 25 B7 A5 45 15 B7 A1 45 05 B7 9D 45 +31 BF 99 45 21 BF 95 45 11 BF 91 45 01 BF 8D 45 +31 B7 89 45 21 B7 85 45 11 B7 81 45 01 B7 A9 45 +69 B7 A5 45 59 B7 A1 45 49 B7 89 45 BD BF 8D 45 +AD BF 91 45 9D BF 95 45 8D BF 85 45 BD B7 99 45 +AD B7 9D 45 9D B7 99 69 93 89 C9 73 13 85 C9 20 +EF C0 6F FB 83 27 49 1F E3 86 07 EC A6 85 13 85 +89 23 EF C0 4F FA 83 27 49 1F E3 8D 07 EA A2 85 +13 85 09 25 EF C0 2F F9 75 B5 01 11 22 CC 26 CA +06 CE 4A C8 4E C6 B6 84 37 84 00 10 1C 4C 85 8B +F5 DF 5C 41 B7 39 02 50 09 49 23 20 F4 10 1C 45 +23 22 F4 10 5C 45 23 24 F4 10 1C 49 23 26 F4 10 +5C 49 23 28 F4 10 1C 4D 23 2A F4 10 5C 4D 23 2C +F4 10 1C 51 23 2E F4 10 5C 51 23 20 F4 12 1C 55 +23 22 F4 12 5C 55 23 24 F4 12 1C 59 23 26 F4 12 +DC 41 23 20 F4 20 9C 45 23 22 F4 20 DC 45 23 24 +F4 20 9C 49 23 26 F4 20 DC 49 23 28 F4 20 9C 4D +23 2A F4 20 DC 4D 23 2C F4 20 9C 51 23 2E F4 20 +DC 51 23 20 F4 22 9C 55 23 22 F4 22 DC 55 23 24 +F4 22 9C 59 23 26 F4 22 5C 42 23 20 F4 28 1C 46 +23 22 F4 28 5C 46 23 24 F4 28 1C 4A 23 26 F4 28 +5C 4A 23 28 F4 28 1C 4E 23 2A F4 28 5C 4E 23 2C +F4 28 1C 52 23 2E F4 28 5C 52 23 20 F4 2A 1C 56 +23 22 F4 2A 5C 56 23 24 F4 2A 1C 5A 23 26 F4 2A +DC 40 23 20 F4 30 9C 44 23 22 F4 30 DC 44 23 24 +F4 30 9C 48 23 26 F4 30 DC 48 23 28 F4 30 9C 4C +23 2A F4 30 DC 4C 23 2C F4 30 9C 50 23 2E F4 30 +DC 50 23 20 F4 32 9C 54 23 22 F4 32 DC 54 23 24 +F4 32 9C 58 23 26 F4 32 5C 43 23 20 F4 38 1C 47 +23 22 F4 38 5C 47 23 24 F4 38 1C 4B 23 26 F4 38 +5C 4B 23 28 F4 38 1C 4F 23 2A F4 38 5C 4F 23 2C +F4 38 1C 53 23 2E F4 38 5C 53 23 20 F4 3A 1C 57 +23 22 F4 3A 5C 57 23 24 F4 3A 1C 5B 23 26 F4 3A +83 A7 49 1F 63 6E F9 0E 8D 47 1C C8 37 37 02 50 +13 07 C7 1F 1C 47 54 47 D5 8F 9D E3 73 00 50 10 +93 07 40 06 01 00 FD 17 C2 07 C1 83 E5 FF 1C 47 +54 47 D5 8F E5 D7 83 A7 49 1F 09 44 63 60 F4 0A +B7 87 00 10 03 A9 07 40 C0 40 63 11 24 09 03 A9 +47 40 80 44 63 1C 89 10 03 A9 87 40 C0 44 63 15 +89 10 03 A9 C7 40 80 48 63 16 24 11 03 A9 07 41 +C0 48 63 1F 89 0E 03 A9 47 41 80 4C 63 1E 89 0E +03 A9 87 41 C0 4C 63 11 89 10 03 A9 C7 41 80 50 +63 16 89 0E 03 A9 07 42 C0 50 63 19 89 0E 03 A9 +47 42 80 54 63 1E 89 0C 03 A9 87 42 C0 54 63 1B +89 0C 03 A9 C7 42 80 58 AD 45 63 1A 89 00 F2 40 +62 44 D2 44 42 49 B2 49 05 61 82 80 81 45 83 A7 +49 1F BD E3 05 45 EF C0 0F CF 01 A0 4C 47 10 47 +19 65 13 05 C5 73 EF C0 0F D2 83 A7 49 1F E3 79 +F4 F4 37 15 02 50 13 05 85 15 EF C0 CF CE 89 B7 +37 15 02 50 13 05 85 14 EF C0 EF CD 83 A7 49 1F +0D 47 18 C8 E3 7C F9 EE 37 15 02 50 13 05 85 FD +EF C0 6F CC 37 37 02 50 13 07 C7 1F 1C 47 54 47 +D5 8F E3 85 07 EE 01 B7 99 64 93 84 C4 73 13 85 +84 26 EF C0 4F CC 83 A7 49 1F C9 D7 CA 85 13 85 +84 29 EF C0 4F CB 83 A7 49 1F AD DF A2 85 13 85 +04 2B EF C0 4F CA BD B7 89 45 95 B7 85 45 85 B7 +91 45 B1 BF 8D 45 A1 BF 95 45 91 BF 9D 45 81 BF +A5 45 B1 B7 A9 45 A1 B7 99 45 91 B7 A1 45 81 B7 +01 11 22 CC 4E C6 52 C4 06 CE 26 CA 4A C8 2A 87 +AE 89 32 8A 37 84 00 10 1C 4C 85 8B F5 DF 5C 43 +37 39 02 50 89 44 23 20 F4 48 1C 47 23 22 F4 48 +5C 47 23 24 F4 48 1C 4B 23 26 F4 48 5C 4B 23 28 +F4 48 1C 4F 23 2A F4 48 5C 4F 23 2C F4 48 1C 53 +23 2E F4 48 5C 53 23 20 F4 4A 1C 57 23 22 F4 4A +5C 57 23 24 F4 4A 1C 5B 23 26 F4 4A 83 27 49 1F +63 E5 F4 1E A9 47 1C C8 93 07 F0 03 23 20 F4 60 +23 20 04 58 23 22 04 58 23 24 04 58 23 26 04 58 +23 28 04 58 23 2A 04 58 23 2C 04 58 23 2E 04 58 +23 20 04 5A 23 22 04 5A 23 24 04 5A 23 26 04 5A +37 37 02 50 13 07 C7 1F 1C 47 54 47 D5 8F 91 EF +73 00 50 10 93 07 40 06 01 00 FD 17 C2 07 C1 83 +E5 FF 1C 47 54 47 D5 8F E5 D7 83 26 49 1F 09 44 +63 69 D4 14 B7 87 00 10 83 A4 07 30 03 A4 49 00 +63 9B 84 12 83 A4 47 30 03 A4 89 00 63 91 84 24 +83 A4 87 30 03 A4 C9 00 63 99 84 22 83 A4 C7 30 +03 A4 09 01 63 99 84 22 83 A4 07 31 03 A4 49 01 +63 91 84 22 83 A4 47 31 03 A4 89 01 63 97 84 24 +83 A4 87 31 03 A4 C9 01 63 9D 84 22 83 A4 C7 31 +03 A4 09 02 63 95 84 22 83 A4 07 32 03 A4 49 02 +63 9D 84 20 83 A4 47 32 03 A4 89 02 63 91 84 22 +83 A4 87 32 03 A4 C9 02 63 91 84 1E 83 A4 C7 32 +03 A4 09 03 AD 45 63 99 84 0A 89 47 63 E8 D7 1A +B7 87 00 10 83 A4 07 38 03 24 4A 00 63 16 94 12 +83 A4 47 38 03 24 8A 00 63 1B 94 1A 83 A4 87 38 +03 24 CA 00 63 97 84 1A 83 A4 C7 38 03 24 0A 01 +63 93 84 1A 83 A4 07 39 03 24 4A 01 63 9F 84 18 +83 A4 47 39 03 24 8A 01 63 9B 84 18 83 A4 87 39 +03 24 CA 01 63 97 84 18 83 A4 C7 39 03 24 0A 02 +63 93 84 18 83 A4 07 3A 03 24 4A 02 63 9B 84 18 +83 A4 47 3A 03 24 8A 02 63 97 84 18 83 A4 87 3A +03 24 CA 02 63 99 84 16 83 A4 C7 3A 03 24 0A 03 +AD 45 63 94 84 0A F2 40 62 44 D2 44 42 49 B2 49 +22 4A 05 61 82 80 81 45 E1 EA 05 45 EF C0 AF A0 +01 A0 4C 47 10 47 19 65 13 05 C5 73 EF C0 AF A3 +83 26 49 1F E3 70 D4 EA 37 15 02 50 13 05 05 11 +EF C0 6F A0 83 26 49 1F 71 B5 37 15 02 50 13 05 +45 17 EF C0 4F 9F 29 47 83 27 49 1F 18 C8 13 07 +F0 03 23 20 E4 60 23 20 04 58 23 22 04 58 23 24 +04 58 23 26 04 58 23 28 04 58 23 2A 04 58 23 2C +04 58 23 2E 04 58 23 20 04 5A 23 22 04 5A 23 24 +04 5A 23 26 04 5A E3 F5 F4 E0 37 15 02 50 13 05 +85 FD EF C0 4F 9A ED BB 81 45 83 27 49 1F 89 E7 +05 45 EF C0 4F 97 01 A0 99 69 93 89 C9 73 13 85 +49 32 EF C0 4F 9A 83 27 49 1F FD D3 A6 85 13 85 +09 35 EF C0 4F 99 83 27 49 1F F9 DB A2 85 13 85 +89 36 EF C0 4F 98 E9 B7 99 69 93 89 C9 73 13 85 +89 2C EF C0 4F 97 83 27 49 1F E3 80 07 F2 A6 85 +13 85 49 2F EF C0 2F 96 83 27 49 1F E3 87 07 F0 +A2 85 13 85 C9 30 EF C0 0F 95 01 B7 37 15 02 50 +13 05 C5 12 EF C0 2F 92 A1 B5 89 45 F5 B5 85 45 +E5 B5 91 45 D5 B5 8D 45 C5 B5 A9 45 F1 BD 85 45 +AD B7 89 45 9D B7 8D 45 8D B7 91 45 B9 BF 95 45 +A9 BF 99 45 99 BF 9D 45 89 BF A1 45 75 BD 9D 45 +65 BD 99 45 55 BD A9 45 89 B7 95 45 75 B5 A5 45 +65 B5 A1 45 1D BF A5 45 0D BF 01 00 52 65 63 65 +69 76 65 64 20 45 43 43 20 6E 6F 74 69 66 2F 20 +65 72 72 20 69 6E 74 72 20 77 69 74 68 20 73 74 +61 74 75 73 20 3D 20 25 64 2F 20 25 64 0A 00 00 +41 74 20 6F 66 66 73 65 74 20 5B 25 64 5D 2C 20 +65 63 63 5F 70 72 69 76 6B 65 79 20 64 61 74 61 +20 6D 69 73 6D 61 74 63 68 21 0A 00 41 63 74 75 +61 6C 20 20 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 45 78 70 65 63 74 65 64 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 41 74 20 6F +66 66 73 65 74 20 5B 25 64 5D 2C 20 65 63 63 5F +70 75 62 6B 65 79 5F 78 20 64 61 74 61 20 6D 69 +73 6D 61 74 63 68 21 0A 00 00 00 00 41 63 74 75 +61 6C 20 20 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 45 78 70 65 63 74 65 64 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 41 74 20 6F +66 66 73 65 74 20 5B 25 64 5D 2C 20 65 63 63 5F +70 75 62 6B 65 79 5F 79 20 64 61 74 61 20 6D 69 +73 6D 61 74 63 68 21 0A 00 00 00 00 41 63 74 75 +61 6C 20 20 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 45 78 70 65 63 74 65 64 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 41 74 20 6F +66 66 73 65 74 20 5B 25 64 5D 2C 20 65 63 63 5F +73 68 61 72 65 64 6B 65 79 20 64 61 74 61 20 6D +69 73 6D 61 74 63 68 21 0A 00 00 00 41 63 74 75 +61 6C 20 20 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 45 78 70 65 63 74 65 64 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 41 74 20 6F +66 66 73 65 74 20 5B 25 64 5D 2C 20 65 63 63 5F +73 69 67 6E 5F 72 20 64 61 74 61 20 6D 69 73 6D +61 74 63 68 21 0A 00 00 41 63 74 75 61 6C 20 20 +20 64 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +45 78 70 65 63 74 65 64 20 64 61 74 61 3A 20 30 +78 25 78 0A 00 00 00 00 41 74 20 6F 66 66 73 65 +74 20 5B 25 64 5D 2C 20 65 63 63 5F 73 69 67 6E +5F 73 20 64 61 74 61 20 6D 69 73 6D 61 74 63 68 +21 0A 00 00 41 63 74 75 61 6C 20 20 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 45 78 70 65 +63 74 65 64 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 41 74 20 6F 66 66 73 65 74 20 5B 25 +64 5D 2C 20 65 63 63 5F 76 65 72 69 66 79 5F 72 +20 64 61 74 61 20 6D 69 73 6D 61 74 63 68 21 0A +00 00 00 00 41 63 74 75 61 6C 20 20 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 45 78 70 65 +63 74 65 64 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 41 74 20 6F 66 66 73 65 74 20 5B 25 +64 5D 2C 20 65 63 63 5F 73 69 67 6E 5F 72 20 64 +61 74 61 20 6D 69 73 6D 61 74 63 68 21 0A 00 00 +41 63 74 75 61 6C 20 20 20 64 61 74 61 3A 20 30 +78 25 78 0A 00 00 00 00 45 78 70 65 63 74 65 64 +20 64 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +41 74 20 6F 66 66 73 65 74 20 5B 25 64 5D 2C 20 +65 63 63 5F 73 69 67 6E 5F 73 20 64 61 74 61 20 +6D 69 73 6D 61 74 63 68 21 0A 00 00 41 63 74 75 +61 6C 20 20 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 45 78 70 65 63 74 65 64 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 41 11 22 C4 +37 34 02 50 03 27 44 1F 06 C6 89 47 63 E0 E7 04 +37 37 02 50 13 07 C7 1F 3C 43 74 43 D5 8F 9D E3 +73 00 50 10 93 07 40 06 01 00 FD 17 C2 07 C1 83 +E5 FF 3C 43 74 43 D5 8F E5 D7 83 26 44 1F 89 47 +63 E5 D7 02 B2 40 22 44 41 01 82 80 37 15 02 50 +13 05 85 18 EF B0 3F CF 37 37 02 50 13 07 C7 1F +3C 43 74 43 D5 8F CD DF C9 BF 22 44 6C 43 B2 40 +30 43 21 65 13 05 45 2A 41 01 6F B0 DF CE 41 11 +26 C2 B7 34 02 50 83 A7 44 1F 22 C4 06 C6 09 44 +63 60 F4 02 B7 07 03 10 21 47 98 CB 37 07 03 10 +5C 4B 85 8B F5 DF B2 40 22 44 92 44 41 01 82 80 +37 15 02 50 13 05 45 1A EF B0 FF C8 83 A7 44 1F +37 07 03 10 A1 46 14 CB E3 7A F4 FC 37 15 02 50 +13 05 85 1B EF B0 3F C7 D1 B7 19 CA 0A 06 33 87 +C5 00 9C 41 91 05 11 05 23 2E F5 FE E3 9B E5 FE +82 80 79 71 4E CE B7 39 02 50 03 A7 49 1F 26 D2 +4A D0 5A C8 5E C6 06 D6 22 D4 52 CC 56 CA 89 47 +AA 8B 2E 8B B2 84 36 89 63 E3 E7 20 B7 07 03 10 +C0 4B 05 88 75 DC 03 CA 0B 00 83 C6 2B 00 63 09 +0A 16 93 97 16 00 93 F7 E7 03 93 E7 17 00 B7 86 +03 10 9C C2 89 47 63 E3 E7 28 B7 07 03 10 23 AC +07 04 23 AE 07 04 23 A0 07 06 23 A2 07 06 23 A4 +07 06 23 A6 07 06 23 A8 07 06 23 AA 07 06 B7 86 +03 10 DC 42 89 8B F5 DF 03 C6 1B 00 85 47 63 19 +F6 14 DC 42 93 F7 C7 3F 63 84 07 2C 89 47 63 E6 +E7 2C 83 26 0B 00 B7 0A 03 10 89 47 23 AC DA 00 +83 26 4B 00 23 AE DA 00 83 26 8B 00 23 A0 DA 02 +83 26 CB 00 23 A2 DA 02 83 26 0B 01 23 A4 DA 02 +83 26 4B 01 23 A6 DA 02 83 26 8B 01 23 A8 DA 02 +83 26 CB 01 23 AA DA 02 83 26 0B 02 23 AC DA 02 +83 26 4B 02 23 AE DA 02 83 26 8B 02 23 A0 DA 04 +83 26 CB 02 23 A2 DA 04 83 26 0B 03 23 A4 DA 04 +83 26 4B 03 23 A6 DA 04 83 26 8B 03 23 A8 DA 04 +83 26 CB 03 23 AA DA 04 63 ED E7 16 85 47 23 A8 +FA 00 03 C7 2B 00 63 07 07 0E 37 87 03 10 1C C3 +37 37 02 50 13 07 C7 1F 34 43 7C 43 D5 8F 91 EF +73 00 50 10 93 07 40 06 01 00 FD 17 C2 07 C1 83 +E5 FF 3C 43 74 43 D5 8F E5 D7 03 A5 49 1F 09 44 +63 64 A4 08 63 16 0A 0C B7 46 03 10 26 84 81 45 +85 8E 13 06 80 4C 39 A0 93 95 07 01 C1 81 11 04 +63 88 C5 0C B3 87 86 00 84 43 18 40 93 87 15 00 +E3 04 97 FE 63 15 05 14 05 45 EF B0 DF A8 01 A0 +83 A6 4B 00 B4 CF 83 A6 8B 00 F4 CF 83 A6 CB 00 +B4 D3 83 A6 0B 01 F4 D3 83 A6 4B 01 B4 D7 83 A6 +8B 01 F4 D7 83 A6 CB 01 B4 DB 83 A6 0B 02 F4 DB +89 47 E3 F0 E7 EC 37 15 02 50 13 05 45 2B EF B0 +9F A6 03 A7 49 1F 75 B5 6C 43 30 43 21 65 13 05 +45 2A EF B0 5F A7 63 1D 0A 02 03 A5 49 1F E3 75 +A4 F6 37 15 02 50 13 05 45 2D EF B0 DF A3 03 A5 +49 1F 99 BF B7 87 03 10 0D 47 98 C3 11 BF 37 15 +02 50 13 05 85 1D EF B0 1F A2 03 A7 49 1F FD B3 +83 C7 1B 00 81 CF B2 50 22 54 92 54 02 59 F2 49 +62 4A D2 4A 42 4B B2 4B 45 61 82 80 03 A5 49 1F +89 47 63 E0 A7 0C B7 16 03 10 4A 84 81 45 B3 86 +26 41 13 06 80 28 39 A0 93 95 07 01 C1 81 11 04 +E3 83 C5 FC B3 87 86 00 84 43 18 40 93 87 15 00 +E3 04 97 FE 83 A7 49 1F C1 EF 05 45 EF B0 BF 99 +01 A0 37 15 02 50 13 05 45 2C EF B0 DF 9A 85 47 +03 A7 49 1F 23 A8 FA 00 83 C7 2B 00 91 CF B7 87 +03 10 80 C3 89 47 63 FB E7 0A 37 15 02 50 13 05 +85 18 EF B0 5F 98 AD B5 0D 44 D5 B7 37 15 02 50 +13 05 45 20 EF B0 3F 97 03 A7 49 1F BD B3 21 69 +13 09 49 2A 13 05 89 03 EF B0 FF 97 83 A7 49 1F +E3 84 07 EA A6 85 13 05 89 06 EF B0 DF 96 83 A7 +49 1F E3 8B 07 E8 0C 40 13 05 09 08 EF B0 BF 95 +61 B5 37 15 02 50 13 05 45 2F EF B0 DF 92 25 BF +21 69 13 09 49 2A 13 05 89 09 EF B0 DF 93 83 A7 +49 1F A1 DF A6 85 13 05 89 0C EF B0 DF 92 83 A7 +49 1F A1 D7 0C 40 13 05 09 0E EF B0 DF 91 35 BF +15 EB 05 45 EF B0 3F 8D 01 A0 37 15 02 50 13 05 +85 22 EF B0 5F 8E 03 A7 49 1F 9D B5 37 37 02 50 +13 07 C7 1F 3C 43 74 43 D5 8F E3 83 07 DC 03 A5 +49 1F CD B3 37 15 02 50 13 05 C5 26 EF B0 BF 8B +C9 B7 79 71 4E CE B7 39 02 50 03 A8 49 1F 22 D4 +56 CA 5A C8 5E C6 62 C4 06 D6 26 D2 4A D0 52 CC +89 47 AA 8B 2E 8B 32 8C B6 8A 3A 84 63 E7 07 29 +B7 07 03 10 C4 4B 85 88 F5 DC 03 CA 0B 00 63 0C +0A 06 83 C7 2B 00 B7 86 03 10 09 47 86 07 93 F7 +E7 03 93 E7 17 00 9C C2 63 60 07 31 B7 07 03 10 +23 AC 07 04 23 AE 07 04 23 A0 07 06 23 A2 07 06 +23 A4 07 06 23 A6 07 06 23 A8 07 06 23 AA 07 06 +37 87 03 10 5C 43 89 8B F5 DF 83 C6 1B 00 85 47 +63 9B F6 04 5C 43 93 F7 C7 3F 63 81 07 30 89 47 +63 F3 07 05 37 15 02 50 13 05 05 31 EF B0 BF 80 +03 A8 49 1F 0D A8 03 A7 4B 00 B8 CF 03 A7 8B 00 +F8 CF 03 A7 CB 00 B8 D3 03 A7 0B 01 F8 D3 03 A7 +4B 01 B8 D7 03 A7 8B 01 F8 D7 03 A7 CB 01 B8 DB +03 A7 0B 02 F8 DB 03 27 0B 00 37 09 03 10 89 47 +23 2C E9 08 03 27 4B 00 23 2E E9 08 03 27 8B 00 +23 20 E9 0A 03 27 CB 00 23 22 E9 0A 03 27 0B 01 +23 24 E9 0A 03 27 4B 01 23 26 E9 0A 03 27 8B 01 +23 28 E9 0A 03 27 CB 01 23 2A E9 0A 03 27 0B 02 +23 2C E9 0A 03 27 4B 02 23 2E E9 0A 03 27 8B 02 +23 20 E9 0C 03 27 CB 02 23 22 E9 0C 03 27 0B 03 +23 24 E9 0C 03 27 4B 03 23 26 E9 0C 03 27 8B 03 +23 28 E9 0C 03 27 CB 03 23 2A E9 0C 03 27 0C 00 +23 2C E9 06 03 27 4C 00 23 2E E9 06 03 27 8C 00 +23 20 E9 08 03 27 CC 00 23 22 E9 08 03 27 0C 01 +23 24 E9 08 03 27 4C 01 23 26 E9 08 03 27 8C 01 +23 28 E9 08 03 27 CC 01 23 2A E9 08 03 A7 0A 00 +23 2C E9 00 03 A7 4A 00 23 2E E9 00 03 A7 8A 00 +23 20 E9 02 03 A7 CA 00 23 22 E9 02 03 A7 0A 01 +23 24 E9 02 03 A7 4A 01 23 26 E9 02 03 A7 8A 01 +23 28 E9 02 03 A7 CA 01 23 2A E9 02 03 A7 0A 02 +23 2C E9 02 03 A7 4A 02 23 2E E9 02 03 A7 8A 02 +23 20 E9 04 03 A7 CA 02 23 22 E9 04 03 A7 0A 03 +23 24 E9 04 03 A7 4A 03 23 26 E9 04 03 A7 8A 03 +23 28 E9 04 03 A7 CA 03 23 2A E9 04 63 E9 07 0F +91 47 23 28 F9 00 83 C7 2B 00 D5 CF B7 87 03 10 +05 47 98 C3 37 37 02 50 13 07 C7 1F 34 43 7C 43 +D5 8F 91 EF 73 00 50 10 93 07 40 06 01 00 FD 17 +C2 07 C1 83 E5 FF 3C 43 74 43 D5 8F E5 D7 83 A6 +49 1F 89 47 63 EC D7 04 63 05 0A 00 83 C7 1B 00 +D9 E3 B7 26 03 10 81 45 81 8E 13 06 50 48 39 A0 +93 95 07 01 C1 81 11 04 63 87 C5 06 B3 87 86 00 +84 43 18 40 93 87 15 00 E3 04 97 FE 83 A7 49 1F +CD EF 05 45 EF B0 2F DE 01 A0 37 15 02 50 13 05 +85 1D EF B0 4F DF 03 A8 49 1F 9D B3 6C 43 30 43 +21 65 13 05 45 2A EF B0 0F E0 63 13 0A 02 03 A7 +49 1F 89 47 E3 FF E7 F8 37 15 02 50 13 05 45 3C +EF B0 6F DC 79 B7 B7 87 03 10 0D 47 98 C3 99 B7 +83 C7 1B 00 E9 DF B2 50 22 54 92 54 02 59 F2 49 +62 4A D2 4A 42 4B B2 4B 22 4C 45 61 82 80 37 15 +02 50 13 05 C5 3A EF B0 0F D9 91 47 03 A7 49 1F +23 28 F9 00 83 C7 2B 00 91 CF B7 87 03 10 84 C3 +89 47 63 F3 E7 06 37 15 02 50 13 05 85 18 EF B0 +8F D6 CD BD 8D 44 D5 B7 37 15 02 50 13 05 45 20 +EF B0 6F D5 03 A8 49 1F D5 B9 21 69 13 09 49 2A +13 05 89 0F EF B0 2F D6 83 A7 49 1F 9D DB A6 85 +13 05 49 12 EF B0 2F D5 83 A7 49 1F E3 83 07 F2 +0C 40 13 05 C9 13 EF B0 0F D4 21 BF 63 10 08 02 +05 45 EF B0 4F CF 01 A0 37 37 02 50 13 07 C7 1F +3C 43 74 43 D5 8F E3 8F 07 E8 7D BD 37 15 02 50 +13 05 C5 35 EF B0 2F CF E1 BF 01 11 4A C8 37 39 +02 50 03 28 49 1F 22 CC 26 CA 4E C6 52 C4 56 C2 +06 CE 5A C0 89 47 AA 84 2E 8A B2 8A B6 89 3A 84 +63 E8 07 1D 37 07 03 10 5C 4B 85 8B F5 DF 89 47 +63 E7 07 23 05 67 13 07 07 32 B7 65 03 10 A6 87 +33 86 E4 00 85 8D 94 43 33 87 F5 00 91 07 14 C3 +E3 9B C7 FE 89 47 63 EB 07 1F 83 27 0A 00 B7 04 +03 10 09 4B 23 AC F4 08 83 27 4A 00 23 AE F4 08 +83 27 8A 00 23 A0 F4 0A 83 27 CA 00 23 A2 F4 0A +83 27 0A 01 23 A4 F4 0A 83 27 4A 01 23 A6 F4 0A +83 27 8A 01 23 A8 F4 0A 83 27 CA 01 23 AA F4 0A +83 27 0A 02 23 AC F4 0A 83 27 4A 02 23 AE F4 0A +83 27 8A 02 23 A0 F4 0C 83 27 CA 02 23 A2 F4 0C +83 27 0A 03 23 A4 F4 0C 83 27 4A 03 23 A6 F4 0C +83 27 8A 03 23 A8 F4 0C 83 27 CA 03 23 AA F4 0C +83 A7 0A 00 BC DC 83 A7 4A 00 FC DC 83 A7 8A 00 +23 A0 F4 08 83 A7 CA 00 23 A2 F4 08 83 A7 0A 01 +23 A4 F4 08 83 A7 4A 01 23 A6 F4 08 83 A7 8A 01 +23 A8 F4 08 83 A7 CA 01 23 AA F4 08 83 A7 09 00 +9C CC 83 A7 49 00 DC CC 83 A7 89 00 9C D0 83 A7 +C9 00 DC D0 83 A7 09 01 9C D4 83 A7 49 01 DC D4 +83 A7 89 01 9C D8 83 A7 C9 01 DC D8 83 A7 09 02 +9C DC 83 A7 49 02 DC DC 83 A7 89 02 BC C0 83 A7 +C9 02 FC C0 83 A7 09 03 BC C4 83 A7 49 03 FC C4 +83 A7 89 03 BC C8 83 A7 C9 03 FC C8 63 65 0B 0B +23 A8 64 01 37 37 02 50 13 07 C7 1F 34 43 7C 43 +D5 8F 91 EF 73 00 50 10 93 07 40 06 01 00 FD 17 +C2 07 C1 83 E5 FF 3C 43 74 43 D5 8F E5 D7 83 27 +49 1F 89 44 63 E7 F4 04 B7 26 03 10 81 45 81 8E +13 06 50 48 39 A0 93 95 07 01 C1 81 11 04 63 89 +C5 0C B3 87 86 00 84 43 18 40 93 87 15 00 E3 04 +97 FE 83 27 49 1F C9 E7 05 45 EF B0 CF AD 01 A0 +37 15 02 50 13 05 85 1B EF B0 EF AE 03 28 49 1F +15 B5 6C 43 30 43 21 65 13 05 45 2A EF B0 AF AF +83 27 49 1F E3 F2 F4 FA 37 15 02 50 13 05 45 3C +EF B0 6F AC 51 BF 37 15 02 50 13 05 C5 3F EF B0 +8F AB 83 27 49 1F 23 A8 64 01 63 7D FB 06 37 15 +02 50 13 05 85 18 EF B0 0F AA 2D BF 37 15 02 50 +13 05 05 3F EF B0 2F A9 03 28 49 1F FD BB 37 15 +02 50 13 05 05 3E EF B0 0F A8 03 28 49 1F D9 B3 +A1 69 93 89 49 2A 13 85 49 15 EF B0 CF A8 83 27 +49 1F BD D3 A6 85 13 85 09 18 EF B0 CF A7 83 27 +49 1F B9 DB 0C 40 13 85 89 19 EF B0 CF A6 A9 B7 +F2 40 62 44 D2 44 42 49 B2 49 22 4A 92 4A 02 4B +05 61 82 80 37 37 02 50 13 07 C7 1F 34 43 7C 43 +D5 8F E3 89 07 EC CD BD 01 11 22 CC 06 CE 26 CA +4A C8 4E C6 32 88 36 84 37 07 03 10 5C 4B 85 8B +F5 DF 1C 41 23 2C F7 08 54 41 AE 87 23 2E D7 08 +83 28 85 00 85 66 93 86 06 A2 23 20 17 0B 33 86 +D5 00 54 45 B7 15 03 10 9D 8D 23 22 D7 0A 14 49 +23 24 D7 0A 54 49 23 26 D7 0A 14 4D 23 28 D7 0A +54 4D 23 2A D7 0A 14 51 23 2C D7 0A 54 51 23 2E +D7 0A 14 55 23 20 D7 0C 54 55 23 22 D7 0C 14 59 +23 24 D7 0C 54 59 23 26 D7 0C 14 5D 23 28 D7 0C +54 5D 23 2A D7 0C 94 43 33 87 F5 00 91 07 14 C3 +E3 9B C7 FE 05 67 13 07 47 21 B7 25 03 10 C2 87 +33 06 E8 00 B3 85 05 41 94 43 33 87 F5 00 91 07 +14 C3 E3 9B C7 FE 37 39 02 50 83 27 49 1F 89 44 +63 E8 F4 12 B7 07 03 10 0D 47 98 CB 37 37 02 50 +13 07 C7 1F 34 43 7C 43 D5 8F 9D E3 73 00 50 10 +93 07 40 06 01 00 FD 17 C2 07 C1 83 E5 FF 3C 43 +74 43 D5 8F E5 D7 83 27 49 1F 89 44 63 E8 F4 0C +B7 07 03 10 83 A4 87 0D 18 40 63 19 97 0A 83 A4 +C7 0D 58 40 63 94 E4 14 83 A4 07 0E 18 44 63 92 +E4 14 83 A4 47 0E 58 44 63 96 E4 14 83 A4 87 0E +18 48 63 9E E4 12 83 A4 C7 0E 58 48 63 96 E4 12 +83 A4 07 0F 18 4C 63 96 E4 14 83 A4 47 0F 58 4C +63 94 E4 16 83 A4 87 0F 18 50 63 9B E4 14 83 A4 +C7 0F 5C 50 63 92 F4 14 B7 07 03 10 83 A4 07 10 +18 54 63 97 E4 12 83 A4 47 10 58 54 63 97 E4 10 +83 A4 87 10 18 58 63 9E E4 0E 83 A4 C7 10 58 58 +63 94 E4 10 83 A4 07 11 18 5C 63 90 E4 0E 83 A4 +47 11 5C 5C BD 45 13 04 C4 03 63 9A 97 00 F2 40 +62 44 D2 44 42 49 B2 49 05 61 82 80 81 45 83 27 +49 1F AD E7 05 45 EF B0 0F 83 01 A0 6C 43 30 43 +21 65 13 05 45 2A EF B0 0F 86 83 27 49 1F E3 F1 +F4 F2 37 15 02 50 13 05 05 42 EF B0 CF 82 09 BF +37 15 02 50 13 05 C5 40 EF B0 EF 81 83 27 49 1F +37 07 03 10 8D 46 14 CB E3 F2 F4 EC 37 15 02 50 +13 05 85 18 EF B0 2F 80 37 37 02 50 13 07 C7 1F +34 43 7C 43 D5 8F E3 8B 07 EA F1 B5 A1 69 93 89 +49 2A 13 85 09 1B EF B0 0F 80 83 27 49 1F D9 D3 +A6 85 13 85 49 1E EF A0 1F FF 83 27 49 1F BD DB +0C 40 13 85 C9 1F EF A0 1F FE AD B7 11 04 85 45 +B9 BF 21 04 89 45 A1 BF 51 04 95 45 89 BF 41 04 +91 45 B1 B7 31 04 8D 45 99 B7 13 04 84 03 B9 45 +3D BF 13 04 04 03 B1 45 1D BF 13 04 C4 02 AD 45 +3D B7 61 04 99 45 25 B7 13 04 44 03 B5 45 05 B7 +13 04 84 02 A9 45 21 BF 13 04 44 02 A5 45 01 BF +13 04 04 02 A1 45 21 B7 71 04 9D 45 09 B7 79 71 +4A D0 37 39 02 50 03 28 49 1F 22 D4 52 CC 56 CA +5A C8 5E C6 06 D6 26 D2 4E CE 89 47 2A 8B 2E 8A +B2 8B B6 8A 3A 84 63 EB 07 29 B7 07 03 10 C4 4B +85 88 F5 DC 83 49 0B 00 63 8C 09 06 83 47 2B 00 +B7 86 03 10 09 47 86 07 93 F7 E7 03 93 E7 17 00 +9C C2 63 6D 07 31 B7 07 03 10 23 AC 07 04 23 AE +07 04 23 A0 07 06 23 A2 07 06 23 A4 07 06 23 A6 +07 06 23 A8 07 06 23 AA 07 06 37 87 03 10 5C 43 +89 8B F5 DF 83 46 1B 00 85 47 63 9B F6 04 5C 43 +93 F7 C7 3F 63 8F 07 30 89 47 63 F3 07 05 37 15 +02 50 13 05 05 31 EF A0 1F EB 03 28 49 1F 0D A8 +03 27 4B 00 B8 CF 03 27 8B 00 F8 CF 03 27 CB 00 +B8 D3 03 27 0B 01 F8 D3 03 27 4B 01 B8 D7 03 27 +8B 01 F8 D7 03 27 CB 01 B8 DB 03 27 0B 02 F8 DB +83 26 0A 00 B7 07 03 10 09 47 23 AC D7 10 83 26 +4A 00 23 AE D7 10 83 26 8A 00 23 A0 D7 12 83 26 +CA 00 23 A2 D7 12 83 26 0A 01 23 A4 D7 12 83 26 +4A 01 23 A6 D7 12 83 26 8A 01 23 A8 D7 12 83 26 +CA 01 23 AA D7 12 83 26 0A 02 23 AC D7 12 83 26 +4A 02 23 AE D7 12 83 26 8A 02 23 A0 D7 14 83 26 +CA 02 23 A2 D7 14 83 26 0A 03 23 A4 D7 14 83 26 +4A 03 23 A6 D7 14 83 26 8A 03 23 A8 D7 14 83 26 +CA 03 23 AA D7 14 83 A6 0B 00 B4 DF 83 A6 4B 00 +F4 DF 83 A6 8B 00 23 A0 D7 08 83 A6 CB 00 23 A2 +D7 08 83 A6 0B 01 23 A4 D7 08 83 A6 4B 01 23 A6 +D7 08 83 A6 8B 01 23 A8 D7 08 83 A6 CB 01 23 AA +D7 08 63 6A 07 1B 03 A7 0A 00 37 0A 03 10 89 47 +23 2C EA 00 03 A7 4A 00 23 2E EA 00 03 A7 8A 00 +23 20 EA 02 03 A7 CA 00 23 22 EA 02 03 A7 0A 01 +23 24 EA 02 03 A7 4A 01 23 26 EA 02 03 A7 8A 01 +23 28 EA 02 03 A7 CA 01 23 2A EA 02 03 A7 0A 02 +23 2C EA 02 03 A7 4A 02 23 2E EA 02 03 A7 8A 02 +23 20 EA 04 03 A7 CA 02 23 22 EA 04 03 A7 0A 03 +23 24 EA 04 03 A7 4A 03 23 26 EA 04 03 A7 8A 03 +23 28 EA 04 03 A7 CA 03 23 2A EA 04 63 E9 07 0F +93 07 40 02 23 28 FA 00 83 47 2B 00 C9 CB B7 87 +03 10 05 47 98 C3 37 37 02 50 13 07 C7 1F 3C 43 +74 43 D5 8F 91 EF 73 00 50 10 93 07 40 06 01 00 +FD 17 C2 07 C1 83 E5 FF 3C 43 74 43 D5 8F E5 D7 +83 26 49 1F 89 47 63 E1 D7 06 63 85 09 00 83 47 +1B 00 D9 E3 B7 26 03 10 81 45 81 8E 13 06 50 48 +39 A0 93 95 07 01 C1 81 11 04 63 87 C5 06 B3 87 +86 00 84 43 18 40 93 87 15 00 E3 04 97 FE 83 27 +49 1F F1 E7 05 45 EF A0 1F C8 01 A0 37 15 02 50 +13 05 85 1D EF A0 3F C9 03 28 49 1F B9 BB B7 87 +03 10 0D 47 98 C3 85 BF 6C 43 30 43 21 65 13 05 +45 2A EF A0 5F C9 63 9E 09 00 03 27 49 1F 89 47 +E3 FA E7 F8 37 15 02 50 13 05 45 3C EF A0 BF C5 +51 B7 83 47 1B 00 F5 D3 B2 50 22 54 92 54 02 59 +F2 49 62 4A D2 4A 42 4B B2 4B 45 61 82 80 37 15 +02 50 13 05 05 44 EF A0 1F C3 93 07 40 02 03 27 +49 1F 23 28 FA 00 83 47 2B 00 9D C7 B7 87 03 10 +84 C3 89 47 63 FD E7 06 37 15 02 50 13 05 85 18 +EF A0 7F C0 CD BD 37 15 02 50 13 05 45 2B EF A0 +9F BF 03 28 49 1F 81 B5 8D 44 C9 BF 37 15 02 50 +13 05 45 20 EF A0 3F BE 03 28 49 1F E9 B9 A1 69 +93 89 49 2A 13 85 49 21 EF A0 FF BE 83 27 49 1F +E3 82 07 F2 A6 85 13 85 09 24 EF A0 DF BD 83 27 +49 1F E3 89 07 F0 0C 40 13 85 89 25 EF A0 BF BC +11 B7 63 10 08 02 05 45 EF A0 FF B7 01 A0 37 37 +02 50 13 07 C7 1F 3C 43 74 43 D5 8F E3 85 07 E8 +6D B5 37 15 02 50 13 05 C5 35 EF A0 DF B7 E1 BF +01 11 4A C8 37 39 02 50 03 28 49 1F 22 CC 26 CA +4E C6 52 C4 56 C2 06 CE 5A C0 89 47 AA 84 2E 8A +B2 8A B6 89 3A 84 63 E9 07 1D 37 07 03 10 5C 4B +85 8B F5 DF 89 47 63 E9 07 23 05 67 13 07 07 32 +B7 65 03 10 A6 87 33 86 E4 00 85 8D 94 43 33 87 +F5 00 91 07 14 C3 E3 9B C7 FE 89 47 63 ED 07 1F +83 27 0A 00 B7 04 03 10 09 4B 23 AC F4 10 83 27 +4A 00 23 AE F4 10 83 27 8A 00 23 A0 F4 12 83 27 +CA 00 23 A2 F4 12 83 27 0A 01 23 A4 F4 12 83 27 +4A 01 23 A6 F4 12 83 27 8A 01 23 A8 F4 12 83 27 +CA 01 23 AA F4 12 83 27 0A 02 23 AC F4 12 83 27 +4A 02 23 AE F4 12 83 27 8A 02 23 A0 F4 14 83 27 +CA 02 23 A2 F4 14 83 27 0A 03 23 A4 F4 14 83 27 +4A 03 23 A6 F4 14 83 27 8A 03 23 A8 F4 14 83 27 +CA 03 23 AA F4 14 83 A7 0A 00 BC DC 83 A7 4A 00 +FC DC 83 A7 8A 00 23 A0 F4 08 83 A7 CA 00 23 A2 +F4 08 83 A7 0A 01 23 A4 F4 08 83 A7 4A 01 23 A6 +F4 08 83 A7 8A 01 23 A8 F4 08 83 A7 CA 01 23 AA +F4 08 83 A7 09 00 9C CC 83 A7 49 00 DC CC 83 A7 +89 00 9C D0 83 A7 C9 00 DC D0 83 A7 09 01 9C D4 +83 A7 49 01 DC D4 83 A7 89 01 9C D8 83 A7 C9 01 +DC D8 83 A7 09 02 9C DC 83 A7 49 02 DC DC 83 A7 +89 02 BC C0 83 A7 C9 02 FC C0 83 A7 09 03 BC C4 +83 A7 49 03 FC C4 83 A7 89 03 BC C8 83 A7 C9 03 +FC C8 63 66 0B 0B 93 07 20 02 9C C8 37 37 02 50 +13 07 C7 1F 34 43 7C 43 D5 8F 91 EF 73 00 50 10 +93 07 40 06 01 00 FD 17 C2 07 C1 83 E5 FF 3C 43 +74 43 D5 8F E5 D7 83 27 49 1F 89 44 63 E7 F4 04 +B7 26 03 10 81 45 81 8E 13 06 50 48 39 A0 93 95 +07 01 C1 81 11 04 63 8A C5 0C B3 87 86 00 84 43 +18 40 93 87 15 00 E3 04 97 FE 83 27 49 1F D1 E7 +05 45 EF A0 5F 96 01 A0 37 15 02 50 13 05 85 1B +EF A0 7F 97 03 28 49 1F 0D B5 6C 43 30 43 21 65 +13 05 45 2A EF A0 3F 98 83 27 49 1F E3 F2 F4 FA +37 15 02 50 13 05 45 3C EF A0 FF 94 51 BF 37 15 +02 50 13 05 05 48 EF A0 1F 94 83 27 49 1F 13 07 +20 02 98 C8 63 7D FB 06 37 15 02 50 13 05 85 18 +EF A0 7F 92 25 BF 37 15 02 50 13 05 C5 46 EF A0 +9F 91 03 28 49 1F ED BB 37 15 02 50 13 05 05 3E +EF A0 7F 90 03 28 49 1F C9 B3 A1 69 93 89 49 2A +13 85 09 27 EF A0 3F 91 83 27 49 1F B5 D3 A6 85 +13 85 C9 29 EF A0 3F 90 83 27 49 1F B1 DB 0C 40 +13 85 49 2B EF A0 3F 8F A1 B7 F2 40 62 44 D2 44 +42 49 B2 49 22 4A 92 4A 02 4B 05 61 82 80 37 37 +02 50 13 07 C7 1F 34 43 7C 43 D5 8F E3 88 07 EC +C5 BD 01 11 22 CC 26 CA 4E C6 52 C4 06 CE 4A C8 +AA 84 AE 89 32 8A 36 84 37 07 03 10 5C 4B 85 8B +F5 DF 37 39 02 50 03 25 49 1F 89 47 63 E7 A7 20 +9C 40 37 07 03 10 23 2C F7 10 D4 40 CE 87 23 2E +D7 10 8C 44 85 66 93 86 06 A2 23 20 B7 12 33 86 +D9 00 D4 44 B7 15 03 10 B3 85 35 41 23 22 D7 12 +94 48 23 24 D7 12 D4 48 23 26 D7 12 94 4C 23 28 +D7 12 D4 4C 23 2A D7 12 94 50 23 2C D7 12 D4 50 +23 2E D7 12 94 54 23 20 D7 14 D4 54 23 22 D7 14 +94 58 23 24 D7 14 D4 58 23 26 D7 14 94 5C 23 28 +D7 14 D4 5C 23 2A D7 14 94 43 33 87 F5 00 91 07 +14 C3 E3 9B C7 FE 05 67 13 07 47 21 B7 25 03 10 +D2 87 33 06 EA 00 B3 85 45 41 94 43 33 87 F5 00 +91 07 14 C3 E3 9B C7 FE 89 44 63 EA A4 12 B7 07 +03 10 13 07 30 02 98 CB 37 37 02 50 13 07 C7 1F +3C 43 74 43 D5 8F 91 EF 73 00 50 10 93 07 40 06 +01 00 FD 17 C2 07 C1 83 E5 FF 3C 43 74 43 D5 8F +E5 D7 83 27 49 1F 89 44 63 E9 F4 0C B7 07 03 10 +83 A4 87 0D 18 40 63 1A 97 0A 83 A4 C7 0D 58 40 +63 96 E4 14 83 A4 07 0E 18 44 63 97 E4 16 83 A4 +47 0E 58 44 63 9F E4 14 83 A4 87 0E 18 48 63 97 +E4 14 83 A4 C7 0E 58 48 63 9F E4 12 83 A4 07 0F +18 4C 63 96 E4 14 83 A4 47 0F 58 4C 63 98 E4 14 +83 A4 87 0F 18 50 63 9F E4 12 83 A4 C7 0F 5C 50 +63 9D F4 14 B7 07 03 10 83 A4 07 10 18 54 63 92 +E4 14 83 A4 47 10 58 54 63 99 E4 12 83 A4 87 10 +18 58 63 90 E4 12 83 A4 C7 10 58 58 63 9B E4 12 +83 A4 07 11 18 5C 63 9A E4 12 83 A4 47 11 5C 5C +BD 45 13 04 C4 03 63 9B 97 00 F2 40 62 44 D2 44 +42 49 B2 49 22 4A 05 61 82 80 81 45 83 27 49 1F +B5 E7 05 45 EF A0 2F EA 01 A0 6C 43 30 43 21 65 +13 05 45 2A EF A0 2F ED 83 27 49 1F E3 F0 F4 F2 +37 15 02 50 13 05 05 42 EF A0 EF E9 01 BF 37 15 +02 50 13 05 45 4A EF A0 0F E9 83 27 49 1F 37 07 +03 10 93 06 30 02 14 CB 63 FD F4 04 37 15 02 50 +13 05 85 18 EF A0 2F E7 45 BD 37 15 02 50 13 05 +C5 46 EF A0 4F E6 03 25 49 1F DD B3 A1 69 93 89 +49 2A 13 85 C9 2C EF A0 0F E7 83 27 49 1F D1 D3 +A6 85 13 85 89 2F EF A0 0F E6 83 27 49 1F B5 DB +0C 40 13 85 09 31 EF A0 0F E5 A5 B7 11 04 85 45 +B1 BF 37 37 02 50 13 07 C7 1F 34 43 7C 43 D5 8F +E3 84 07 E6 61 B5 51 04 95 45 89 B7 41 04 91 45 +35 BF 31 04 8D 45 1D BF 21 04 89 45 05 BF 61 04 +99 45 2D B7 13 04 04 02 A1 45 0D B7 71 04 9D 45 +31 BF 13 04 04 03 B1 45 11 BF 13 04 C4 02 AD 45 +31 B7 13 04 84 02 A9 45 11 B7 13 04 44 02 A5 45 +F5 BD 13 04 44 03 B5 45 D5 BD 13 04 84 03 B9 45 +F5 B5 B7 37 02 50 03 A7 47 1F 41 11 22 C4 06 C6 +89 47 2A 84 63 E9 E7 02 37 07 03 10 5C 4B 85 8B +F5 DF 13 05 B0 09 EF A0 0F D7 83 47 24 00 B2 40 +22 44 86 07 93 F7 E7 03 93 E7 17 00 37 87 03 10 +1C C3 41 01 82 80 37 15 02 50 13 05 85 1B EF A0 +8F D6 D9 B7 52 65 63 65 69 76 65 64 20 4D 4C 44 +53 41 20 6E 6F 74 69 66 2F 20 65 72 72 20 69 6E +74 72 20 77 69 74 68 20 73 74 61 74 75 73 20 3D +20 25 64 2F 20 25 64 0A 00 00 00 00 41 74 20 6F +66 66 73 65 74 20 5B 25 64 5D 2C 20 6D 6C 64 73 +61 5F 70 72 69 76 6B 65 79 20 64 61 74 61 20 6D +69 73 6D 61 74 63 68 21 0A 00 00 00 41 63 74 75 +61 6C 20 20 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 45 78 70 65 63 74 65 64 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 41 74 20 6F +66 66 73 65 74 20 5B 25 64 5D 2C 20 6D 6C 64 73 +61 5F 70 75 62 6B 65 79 20 64 61 74 61 20 6D 69 +73 6D 61 74 63 68 21 0A 00 00 00 00 41 63 74 75 +61 6C 20 20 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 45 78 70 65 63 74 65 64 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 41 74 20 6F +66 66 73 65 74 20 5B 25 64 5D 2C 20 6D 6C 64 73 +61 5F 73 69 67 6E 20 64 61 74 61 20 6D 69 73 6D +61 74 63 68 21 0A 00 00 41 63 74 75 61 6C 20 20 +20 64 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +45 78 70 65 63 74 65 64 20 64 61 74 61 3A 20 30 +78 25 78 0A 00 00 00 00 41 74 20 6F 66 66 73 65 +74 20 5B 25 64 5D 2C 20 6D 6C 64 73 61 5F 73 69 +67 6E 20 64 61 74 61 20 6D 69 73 6D 61 74 63 68 +21 0A 00 00 41 63 74 75 61 6C 20 20 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 45 78 70 65 +63 74 65 64 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 41 74 20 6F 66 66 73 65 74 20 5B 25 +64 5D 2C 20 6D 6C 64 73 61 5F 76 65 72 69 66 79 +5F 72 65 73 20 64 61 74 61 20 6D 69 73 6D 61 74 +63 68 21 0A 00 00 00 00 41 63 74 75 61 6C 20 20 +20 64 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +45 78 70 65 63 74 65 64 20 64 61 74 61 3A 20 30 +78 25 78 0A 00 00 00 00 41 74 20 6F 66 66 73 65 +74 20 5B 25 64 5D 2C 20 6D 6C 64 73 61 5F 73 69 +67 6E 20 64 61 74 61 20 6D 69 73 6D 61 74 63 68 +21 0A 00 00 41 63 74 75 61 6C 20 20 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 45 78 70 65 +63 74 65 64 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 41 74 20 6F 66 66 73 65 74 20 5B 25 +64 5D 2C 20 6D 6C 64 73 61 5F 73 69 67 6E 20 64 +61 74 61 20 6D 69 73 6D 61 74 63 68 21 0A 00 00 +41 63 74 75 61 6C 20 20 20 64 61 74 61 3A 20 30 +78 25 78 0A 00 00 00 00 45 78 70 65 63 74 65 64 +20 64 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +41 74 20 6F 66 66 73 65 74 20 5B 25 64 5D 2C 20 +61 63 74 75 61 6C 5F 64 61 74 61 20 64 61 74 61 +20 6D 69 73 6D 61 74 63 68 21 0A 00 41 63 74 75 +61 6C 20 20 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 45 78 70 65 63 74 65 64 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 41 11 22 C4 +37 34 02 50 03 27 44 1F 06 C6 89 47 63 E0 E7 04 +37 37 02 50 13 07 C7 1F 3C 43 74 43 D5 8F 9D E3 +73 00 50 10 93 07 40 06 01 00 FD 17 C2 07 C1 83 +E5 FF 3C 43 74 43 D5 8F E5 D7 83 26 44 1F 89 47 +63 E5 D7 02 B2 40 22 44 41 01 82 80 37 15 02 50 +13 05 85 4C EF A0 2F 9E 37 37 02 50 13 07 C7 1F +3C 43 74 43 D5 8F CD DF C9 BF 22 44 6C 43 B2 40 +30 43 2D 65 13 05 C5 D7 41 01 6F A0 CF 9D 41 11 +26 C2 B7 34 02 50 83 A7 44 1F 22 C4 06 C6 09 44 +63 60 F4 02 B7 97 03 10 21 47 98 CB 37 97 03 10 +5C 4B 85 8B F5 DF B2 40 22 44 92 44 41 01 82 80 +37 15 02 50 13 05 85 4E EF A0 EF 97 83 A7 44 1F +37 97 03 10 A1 46 14 CB E3 7A F4 FC 37 15 02 50 +13 05 45 50 EF A0 2F 96 D1 B7 19 CA 0A 06 33 87 +C5 00 9C 41 91 05 11 05 23 2E F5 FE E3 9B E5 FE +82 80 79 71 4E CE B7 39 02 50 03 A7 49 1F 22 D4 +52 CC 5A C8 5E C6 06 D6 26 D2 4A D0 56 CA 62 C4 +89 47 2A 8B AE 8B 32 84 36 8A 63 E5 E7 22 37 99 +03 10 83 24 49 01 85 88 ED DC 83 4A 0B 00 83 47 +2B 00 63 88 0A 16 86 07 93 F7 E7 03 93 E7 17 00 +B7 C6 03 10 9C C2 09 4C 63 61 EC 2A 23 2C 09 00 +23 2E 09 00 23 20 09 02 23 22 09 02 23 24 09 02 +23 26 09 02 23 28 09 02 23 2A 09 02 B7 97 03 10 +23 AC 07 02 23 AE 07 02 23 A0 07 04 23 A2 07 04 +23 A4 07 04 23 A6 07 04 23 A8 07 04 23 AA 07 04 +B7 C6 03 10 DC 42 89 8B F5 DF 03 46 1B 00 85 47 +63 11 F6 18 DC 42 93 F7 C7 3F 63 84 07 2E 89 47 +63 E6 E7 2E 03 A6 0B 00 B7 07 03 10 89 46 90 CF +03 A6 4B 00 D0 CF 03 A6 8B 00 90 D3 03 A6 CB 00 +D0 D3 03 A6 0B 01 90 D7 03 A6 4B 01 D0 D7 03 A6 +8B 01 90 DB 03 A6 CB 01 D0 DB 03 A6 0B 02 90 DF +03 A6 4B 02 D0 DF 03 A6 8B 02 B0 C3 03 A6 CB 02 +F0 C3 03 A6 0B 03 B0 C7 03 A6 4B 03 F0 C7 03 A6 +8B 03 B0 CB 03 A6 CB 03 F0 CB 63 EE E6 12 37 97 +03 10 85 47 1C CB 03 47 2B 00 63 08 07 10 37 C7 +03 10 1C C3 37 37 02 50 13 07 C7 1F 34 43 7C 43 +D5 8F 91 EF 73 00 50 10 93 07 40 06 01 00 FD 17 +C2 07 C1 83 E5 FF 3C 43 74 43 D5 8F E5 D7 83 A7 +49 1F 89 44 63 E5 F4 12 B7 B6 03 10 81 45 81 8E +13 06 80 18 39 A0 93 95 07 01 C1 81 11 04 63 89 +C5 1A B3 87 86 00 84 43 18 40 93 87 15 00 E3 04 +97 FE 83 A7 49 1F 63 9E 07 10 05 45 EF 90 BF F7 +01 A0 83 27 4B 00 23 2C F9 00 83 27 8B 00 23 2E +F9 00 83 27 CB 00 23 20 F9 02 83 27 0B 01 23 22 +F9 02 83 27 4B 01 23 24 F9 02 83 27 8B 01 23 26 +F9 02 83 27 CB 01 23 28 F9 02 83 27 0B 02 23 2A +F9 02 83 27 4B 02 23 2C F9 02 83 27 8B 02 23 2E +F9 02 83 27 CB 02 23 20 F9 04 83 27 0B 03 23 22 +F9 04 83 27 4B 03 23 24 F9 04 83 27 8B 03 23 26 +F9 04 83 27 CB 03 23 28 F9 04 83 27 0B 04 23 2A +F9 04 89 47 E3 F8 E7 E8 37 15 02 50 13 05 85 62 +EF 90 7F F0 03 A7 49 1F B5 BD B7 C7 03 10 0D 47 +98 C3 CD BD 37 15 02 50 13 05 05 52 EF 90 BF EE +03 A7 49 1F E9 B3 37 15 02 50 13 05 85 64 EF 90 +9F ED B7 97 03 10 85 46 03 A7 49 1F 94 CB 83 47 +2B 00 B5 CB B7 C7 03 10 84 C3 89 47 63 F9 E7 12 +37 15 02 50 13 05 85 4C EF 90 FF EA 65 B5 6C 43 +30 43 2D 65 13 05 C5 D7 EF 90 FF EB 83 A7 49 1F +E3 F4 F4 EC 37 15 02 50 13 05 85 66 EF 90 BF E8 +65 BD 2D 69 13 09 C9 D7 13 05 89 03 EF 90 BF E9 +83 A7 49 1F E3 8B 07 EC A6 85 13 05 C9 06 EF 90 +9F E8 83 A7 49 1F E3 82 07 EC 0C 40 13 05 49 08 +EF 90 7F E7 5D BD 8D 44 71 B7 37 15 02 50 13 05 +45 54 EF 90 5F E4 03 A7 49 1F 23 2C 09 00 23 2E +09 00 23 20 09 02 23 22 09 02 23 24 09 02 23 26 +09 02 23 28 09 02 23 2A 09 02 E3 79 EC D4 37 15 +02 50 13 05 05 57 EF 90 1F E1 03 A7 49 1F 3D BB +63 95 0A 04 03 A7 49 1F 89 47 63 E4 E7 0C B7 A7 +03 10 81 45 B3 87 47 41 93 06 80 31 39 A0 93 15 +07 01 C1 81 11 0A 63 82 D5 02 33 87 47 01 04 43 +03 26 0A 00 13 87 15 00 E3 03 96 FE 83 A7 49 1F +A5 E3 05 45 EF 90 3F DA 01 A0 B2 50 22 54 92 54 +02 59 F2 49 62 4A D2 4A 42 4B B2 4B 22 4C 45 61 +82 80 05 EB 05 45 EF 90 1F D8 01 A0 37 15 02 50 +13 05 C5 59 EF 90 3F D9 03 A7 49 1F 9D BD 37 37 +02 50 13 07 C7 1F 34 43 7C 43 D5 8F E3 84 07 D8 +65 B3 37 15 02 50 13 05 05 5E EF 90 DF D6 D9 B7 +2D 64 13 04 C4 D7 13 05 C4 09 EF 90 DF D7 83 A7 +49 1F C1 DB A6 85 13 05 04 0D EF 90 DF D6 83 A7 +49 1F C1 D3 83 25 0A 00 13 05 84 0E EF 90 BF D5 +8D BF 37 15 02 50 13 05 C5 68 EF 90 DF D2 05 BF +79 71 4A D0 37 39 02 50 03 27 49 1F 22 D4 52 CC +5A C8 5E C6 06 D6 26 D2 4E CE 56 CA 62 C4 89 47 +2A 8B AE 8B 32 84 36 8A 63 E1 E7 30 B7 9A 03 10 +83 A4 4A 01 85 88 ED DC 83 49 0B 00 63 8B 09 24 +83 47 2B 00 B7 C6 03 10 09 4C 86 07 93 F7 E7 03 +93 E7 17 00 9C C2 63 64 EC 38 23 AC 0A 00 23 AE +0A 00 23 A0 0A 02 23 A2 0A 02 23 A4 0A 02 23 A6 +0A 02 23 A8 0A 02 23 AA 0A 02 B7 97 03 10 23 AC +07 02 23 AE 07 02 23 A0 07 04 23 A2 07 04 23 A4 +07 04 23 A6 07 04 23 A8 07 04 23 AA 07 04 B7 C6 +03 10 DC 42 89 8B F5 DF 03 46 1B 00 85 47 63 0E +F6 3A 89 47 63 FA E7 00 37 15 02 50 13 05 05 6B +EF 90 7F C6 03 27 49 1F B7 97 03 10 83 AA 87 01 +63 96 0A 3E 94 4F 83 AA C7 01 63 94 0A 46 D4 4F +83 AA 07 02 63 91 0A 46 94 53 83 AA 47 02 63 9E +0A 44 D4 53 83 AA 87 02 63 9B 0A 44 94 57 83 AA +C7 02 63 9C 0A 42 D4 57 83 AA 07 03 63 99 0A 42 +94 5B 83 AA 47 03 9D 45 63 93 0A 3A DC 5B 89 47 +63 E2 E7 30 B7 97 03 10 83 AA 87 03 63 92 0A 38 +94 5F 83 AA C7 03 63 9E 0A 40 D4 5F 83 AA 07 04 +63 9B 0A 40 B4 43 83 AA 47 04 63 98 0A 40 F4 43 +83 AA 87 04 63 95 0A 40 B4 47 83 AA C7 04 63 92 +0A 40 F4 47 83 AA 07 05 63 90 0A 3C B4 4B 83 AA +47 05 9D 45 63 9F 0A 32 FC 4B 89 47 63 EE E7 18 +03 A6 0B 00 B7 07 03 10 89 46 90 CF 03 A6 4B 00 +D0 CF 03 A6 8B 00 90 D3 03 A6 CB 00 D0 D3 03 A6 +0B 01 90 D7 03 A6 4B 01 D0 D7 03 A6 8B 01 90 DB +03 A6 CB 01 D0 DB 03 A6 0B 02 90 DF 03 A6 4B 02 +D0 DF 03 A6 8B 02 B0 C3 03 A6 CB 02 F0 C3 03 A6 +0B 03 B0 C7 03 A6 4B 03 F0 C7 03 A6 8B 03 B0 CB +03 A6 CB 03 F0 CB 63 EB E6 14 37 97 03 10 85 47 +1C CB 03 47 2B 00 63 0B 07 1A 37 C7 03 10 1C C3 +37 37 02 50 13 07 C7 1F 34 43 7C 43 D5 8F 91 EF +73 00 50 10 93 07 40 06 01 00 FD 17 C2 07 C1 83 +E5 FF 3C 43 74 43 D5 8F E5 D7 03 25 49 1F 89 44 +63 E3 A4 18 B7 B7 03 10 B7 55 FC EF 13 86 07 62 +94 43 33 87 B7 00 22 97 14 C3 91 07 E3 9A C7 FE +89 47 63 91 09 12 63 EA A7 22 37 B6 03 10 B7 A7 +03 10 B7 65 FC EF 13 06 06 C6 94 43 33 87 B7 00 +52 97 14 C3 91 07 E3 9A C7 FE B2 50 22 54 92 54 +02 59 F2 49 62 4A D2 4A 42 4B B2 4B 22 4C 45 61 +82 80 83 27 4B 00 23 AC FA 00 83 27 8B 00 23 AE +FA 00 83 27 CB 00 23 A0 FA 02 83 27 0B 01 23 A2 +FA 02 83 27 4B 01 23 A4 FA 02 83 27 8B 01 23 A6 +FA 02 83 27 CB 01 23 A8 FA 02 83 27 0B 02 23 AA +FA 02 83 27 4B 02 23 AC FA 02 83 27 8B 02 23 AE +FA 02 83 27 CB 02 23 A0 FA 04 83 27 0B 03 23 A2 +FA 04 83 27 4B 03 23 A4 FA 04 83 27 8B 03 23 A6 +FA 04 83 27 CB 03 23 A8 FA 04 83 27 0B 04 23 AA +FA 04 89 47 E3 F6 E7 E6 37 15 02 50 13 05 85 62 +EF 90 7F A0 03 27 49 1F A1 BD 37 15 02 50 13 05 +05 52 EF 90 5F 9F 03 27 49 1F CD B9 37 15 02 50 +13 05 85 64 EF 90 3F 9E B7 97 03 10 85 46 03 27 +49 1F 94 CB 83 47 2B 00 F9 CF B7 C7 03 10 84 C3 +89 47 63 F2 E7 20 37 15 02 50 13 05 85 4C EF 90 +9F 9B 79 B5 63 E7 A7 12 B7 A7 03 10 81 45 13 06 +80 31 01 A8 93 15 07 01 9C 43 C1 81 E3 87 C5 EE +B6 87 80 43 13 87 15 00 93 86 47 00 65 D4 83 27 +49 1F C1 EF 05 45 EF 90 1F 96 01 A0 B7 C7 03 10 +0D 47 98 C3 B1 B5 6C 43 30 43 2D 65 13 05 C5 D7 +EF 90 7F 98 03 25 49 1F E3 F6 A4 E6 37 15 02 50 +13 05 85 70 EF 90 3F 95 03 25 49 1F A1 BD 37 15 +02 50 13 05 45 54 EF 90 1F 94 03 27 49 1F 23 AC +0A 00 23 AE 0A 00 23 A0 0A 02 23 A2 0A 02 23 A4 +0A 02 23 A6 0A 02 23 A8 0A 02 23 AA 0A 02 E3 76 +EC C6 37 15 02 50 13 05 05 57 EF 90 DF 90 03 27 +49 1F A1 B9 37 15 02 50 13 05 C5 6D EF 90 BF 8F +03 27 49 1F C5 B9 8D 44 0D B7 AD 64 93 84 C4 D7 +13 85 04 1C EF 90 3F 90 83 27 49 1F A1 DF A2 85 +13 85 C4 1E EF 90 3F 8F 83 27 49 1F A1 D7 81 45 +13 85 44 20 EF 90 3F 8E 35 BF DC 42 93 F7 C7 3F +85 C7 89 47 E3 FA E7 C4 37 15 02 50 13 05 C5 59 +EF 90 7F 8A 03 27 49 1F 2D B1 37 15 02 50 13 05 +85 72 EF 90 5F 89 D1 B3 51 EB 05 45 EF 90 BF 86 +01 A0 37 15 02 50 13 05 85 74 EF 90 DF 87 E9 B5 +81 45 19 EB 05 45 EF 90 1F 85 01 A0 81 45 0D EF +05 45 EF 90 5F 84 01 A0 2D 64 13 04 C4 D7 13 05 +04 16 EF 90 5F 87 83 27 49 1F E9 DF D6 85 13 05 +04 19 EF 90 5F 86 83 27 49 1F E9 D7 81 45 13 05 +84 1A EF 90 5F 85 7D BF 2D 64 13 04 C4 D7 13 05 +04 10 EF 90 5F 84 83 27 49 1F DD DB D6 85 13 05 +04 13 EF 90 5F 83 83 27 49 1F DD D3 81 45 13 05 +84 14 EF 90 5F 82 69 BF 99 45 61 B7 37 15 02 50 +13 05 05 5E EF 90 2F FF 8D B7 95 45 49 B7 99 45 +BD BF 85 45 AD BF 89 45 9D BF 8D 45 8D BF 91 45 +BD B7 85 45 B9 BF 89 45 A9 BF 8D 45 99 BF 91 45 +89 BF 95 45 B9 B7 37 37 02 50 13 07 C7 1F 3C 43 +74 43 D5 8F E3 8E 07 C8 85 B5 79 71 4A D0 37 39 +02 50 03 28 49 1F 22 D4 4E CE 52 CC 5A C8 5E C6 +06 D6 26 D2 56 CA 62 C4 89 47 83 4A 07 00 3A 8A +2A 8B AE 89 B2 8B 36 84 63 EE 07 27 B7 97 03 10 +C4 4B 85 88 F5 DC 89 47 63 E4 07 29 B7 B5 03 10 +DA 87 13 06 0B 62 B3 85 65 41 94 43 33 87 F5 00 +91 07 14 C3 E3 9B C7 FE 03 CB 09 00 63 09 0B 10 +83 C7 29 00 37 C7 03 10 09 4C 86 07 93 F7 E7 03 +93 E7 17 00 1C C7 63 66 0C 2F B7 97 03 10 23 A0 +07 08 23 A2 07 08 23 A4 07 08 23 A6 07 08 23 A8 +07 08 23 AA 07 08 23 AC 07 08 23 AE 07 08 B7 77 +03 10 23 A0 07 2A 23 A2 07 2A 23 A4 07 2A 23 A6 +07 2A 23 A8 07 2A 23 AA 07 2A 23 AC 07 2A 23 AE +07 2A 23 A0 07 2C 37 C7 03 10 5C 47 89 8B F5 DF +83 C6 19 00 85 47 63 8D F6 2C 89 47 63 FA 07 01 +37 25 02 50 13 05 05 8A EF 90 EF EB 03 28 49 1F +B7 97 03 10 03 AC 07 08 63 13 0C 30 03 A7 07 08 +03 AC 47 08 63 14 0C 56 03 A7 47 08 03 AC 87 08 +63 10 0C 56 03 A7 87 08 03 AC C7 08 63 1C 0C 54 +03 A7 C7 08 03 AC 07 09 63 11 0C 4A 03 A7 07 09 +03 AC 47 09 63 1D 0C 48 03 A7 47 09 03 AC 87 09 +63 19 0C 48 03 A7 87 09 03 AC C7 09 9D 45 63 19 +0C 2A 83 A7 C7 09 89 47 63 F0 07 07 37 25 02 50 +13 05 C5 8C EF 90 2F E4 03 28 49 1F B1 A0 03 A7 +49 00 B7 97 03 10 23 A0 E7 08 03 A7 89 00 23 A2 +E7 08 03 A7 C9 00 23 A4 E7 08 03 A7 09 01 23 A6 +E7 08 03 A7 49 01 23 A8 E7 08 03 A7 89 01 23 AA +E7 08 03 A7 C9 01 23 AC E7 08 03 A7 09 02 23 AE +E7 08 89 47 E3 E4 07 FB 03 A7 0B 00 B7 07 03 10 +09 4C 98 CF 03 A7 4B 00 D8 CF 03 A7 8B 00 98 D3 +03 A7 CB 00 D8 D3 03 A7 0B 01 98 D7 03 A7 4B 01 +D8 D7 03 A7 8B 01 98 DB 03 A7 CB 01 D8 DB 03 A7 +0B 02 98 DF 03 A7 4B 02 D8 DF 03 A7 8B 02 B8 C3 +03 A7 CB 02 F8 C3 03 A7 0B 03 B8 C7 03 A7 4B 03 +F8 C7 03 A7 8B 03 B8 CB 03 A7 CB 03 F8 CB 63 6A +0C 0B B7 97 03 10 23 A8 87 01 83 C7 29 00 C1 C7 +B7 C7 03 10 05 47 98 C7 37 37 02 50 13 07 C7 1F +34 43 7C 43 D5 8F 91 EF 73 00 50 10 93 07 40 06 +01 00 FD 17 C2 07 C1 83 E5 FF 3C 43 74 43 D5 8F +E5 D7 03 25 49 1F 89 44 63 E1 A4 0A B7 C6 03 10 +93 86 06 80 81 45 81 8E 13 06 80 18 39 A0 93 95 +07 01 C1 81 11 04 63 85 C5 14 B3 87 86 00 84 43 +18 40 93 87 15 00 E3 04 97 FE 41 ED 05 45 EF 90 +8F CE 01 A0 37 15 02 50 13 05 05 77 EF 90 AF CF +03 28 49 1F A5 BB B7 C7 03 10 0D 47 98 C7 AD BF +37 15 02 50 13 05 45 79 EF 90 EF CD 03 28 49 1F +B5 B3 37 25 02 50 13 05 C5 8E EF 90 CF CC B7 97 +03 10 03 27 49 1F 23 A8 87 01 83 C7 29 00 DD CF +B7 C7 03 10 84 C7 89 47 63 FF E7 2C 37 15 02 50 +13 05 85 4C EF 90 2F CA 05 BF 6C 43 30 43 2D 65 +13 05 C5 D7 EF 90 2F CB 03 25 49 1F E3 F8 A4 F4 +37 25 02 50 13 05 C5 90 EF 90 EF C7 03 25 49 1F +35 BF AD 69 93 89 C9 D7 13 85 89 27 EF 90 AF C8 +83 27 49 1F A1 DF A6 85 13 85 C9 2A EF 90 AF C7 +83 27 49 1F A1 D7 0C 40 13 85 49 2C EF 90 AF C6 +35 BF 37 15 02 50 13 05 85 7B EF 90 CF C3 B7 97 +03 10 03 28 49 1F 23 A0 07 08 23 A2 07 08 23 A4 +07 08 23 A6 07 08 23 A8 07 08 23 AA 07 08 23 AC +07 08 23 AE 07 08 E3 74 0C D1 37 15 02 50 13 05 +C5 7D EF 90 4F C0 03 28 49 1F D5 B9 8D 44 89 B7 +5C 47 93 F7 C7 3F B9 CB 89 47 E3 FB 07 D3 37 25 +02 50 13 05 85 81 EF 90 0F BE 03 28 49 1F 31 B3 +63 84 0A 04 B7 C7 03 10 D8 4B 09 8B 75 DF DC 4B +83 46 1A 00 05 47 93 F7 C7 3F 63 89 E6 22 63 85 +07 20 63 1C 05 1E 05 45 EF 90 EF B8 01 A0 81 45 +63 13 08 08 05 45 EF 90 0F B8 01 A0 63 15 08 0A +05 45 EF 90 4F B7 01 A0 89 47 63 15 0B 0A 63 EC +A7 12 B7 97 03 10 A4 4F 03 24 4A 00 63 13 94 12 +E4 4F 03 24 8A 00 63 1C 94 10 A4 53 03 24 CA 00 +63 95 84 10 E4 53 03 24 0A 01 63 1E 94 0E A4 57 +03 24 4A 01 63 97 84 0E E4 57 03 24 8A 01 63 90 +84 0E A4 5B 03 24 CA 01 63 99 84 0C E4 5B 03 24 +0A 02 9D 45 63 0F 94 06 83 27 49 1F D9 E7 05 45 +EF 90 6F B0 01 A0 2D 64 13 04 C4 D7 13 05 C4 21 +EF 90 6F B3 83 27 49 1F B5 D7 E2 85 13 05 84 24 +EF 90 6F B2 83 27 49 1F B1 DF 81 45 13 05 04 26 +EF 90 6F B1 81 BF 37 25 02 50 13 05 85 85 EF 90 +8F AE B9 B7 63 EC A7 0E B7 97 03 10 A0 4F 59 E8 +E0 4F 63 13 04 0E A0 53 63 1E 04 0C E0 53 69 E8 +A0 57 69 E4 E0 57 69 E0 A0 5B 4D EC E0 5B 9D 45 +3D E8 B2 50 22 54 92 54 02 59 F2 49 62 4A D2 4A +42 4B B2 4B 22 4C 45 61 82 80 AD 69 93 89 C9 D7 +13 85 C9 2D EF 90 2F AB 83 27 49 1F AD D3 A6 85 +13 85 09 31 EF 90 2F AA 83 27 49 1F A9 DB A2 85 +13 85 89 32 EF 90 2F A9 99 B7 99 45 35 BF 95 45 +25 BF 91 45 15 BF 8D 45 05 BF 89 45 35 B7 85 45 +25 B7 81 45 15 B7 37 25 02 50 13 05 C5 A5 EF 90 +8F A4 C1 B5 81 45 83 27 49 1F 89 E7 05 45 EF 90 +8F A1 01 A0 AD 64 93 84 C4 D7 13 85 04 34 EF 90 +8F A4 83 27 49 1F FD D3 A2 85 13 85 44 37 EF 90 +8F A3 83 27 49 1F F9 DB 81 45 13 85 C4 38 EF 90 +8F A2 E9 B7 99 45 C1 B7 95 45 75 BF 91 45 65 BF +8D 45 55 BF 89 45 45 BF 85 45 75 B7 37 25 02 50 +13 05 C5 A7 EF 90 2F 9E 01 B7 91 45 15 BD 95 45 +05 BD 99 45 35 B5 37 37 02 50 13 07 C7 1F 34 43 +7C 43 D5 8F E3 82 07 C6 91 B3 37 25 02 50 13 05 +45 9C EF 90 4F 9B 01 B5 89 47 63 E6 A7 04 03 D7 +09 00 85 47 E3 17 F7 EE 83 47 2A 00 37 07 03 30 +A2 07 93 E7 37 0B 23 26 F7 0C E1 BD 85 CF 89 47 +E3 F9 A7 EC 22 54 B2 50 92 54 02 59 F2 49 62 4A +D2 4A 42 4B B2 4B 22 4C 37 25 02 50 13 05 C5 92 +45 61 6F 90 4F 96 37 25 02 50 13 05 05 A1 EF 90 +8F 95 75 B7 09 E5 05 45 EF 90 EF 92 01 A0 37 25 +02 50 13 05 45 97 EF 90 0F 94 F5 B7 85 45 49 BB +89 45 79 B3 8D 45 69 B3 79 71 22 D4 37 34 02 50 +03 28 44 1F 26 D2 4A D0 52 CC 56 CA 5E C6 66 C2 +3A 8A 06 D6 4E CE 5A C8 62 C4 6A C0 09 47 03 4B +0A 00 83 49 2A 00 AA 8A AE 84 B2 8C B6 8B 3E 89 +63 63 07 2F B7 97 03 10 03 AC 47 01 13 7C 1C 00 +E3 0C 0C FE 89 47 63 E4 07 35 D6 87 37 B6 03 10 +93 8A 0A 62 1D 8E 94 43 33 07 F6 00 91 07 14 C3 +E3 9B 57 FF 83 CA 04 00 63 88 0A 10 83 C7 24 00 +37 C7 03 10 09 4D 86 07 93 F7 E7 03 93 E7 17 00 +1C C7 63 60 0D 39 B7 97 03 10 23 A0 07 08 23 A2 +07 08 23 A4 07 08 23 A6 07 08 23 A8 07 08 23 AA +07 08 23 AC 07 08 23 AE 07 08 B7 77 03 10 23 A0 +07 2A 23 A2 07 2A 23 A4 07 2A 23 A6 07 2A 23 A8 +07 2A 23 AA 07 2A 23 AC 07 2A 23 AE 07 2A 23 A0 +07 2C 37 C7 03 10 5C 47 89 8B F5 DF 83 C6 14 00 +85 47 63 88 F6 38 89 47 63 FA 07 01 37 25 02 50 +13 05 05 8A EF 90 2F 83 03 28 44 1F B7 97 03 10 +03 AD 07 08 63 17 0D 38 03 A7 07 08 03 AD 47 08 +63 11 0D 38 03 A7 47 08 03 AD 87 08 63 1B 0D 36 +03 A7 87 08 03 AD C7 08 63 15 0D 36 03 A7 C7 08 +03 AD 07 09 63 1F 0D 34 03 A7 07 09 03 AD 47 09 +63 19 0D 34 03 A7 47 09 03 AD 87 09 63 13 0D 34 +03 A7 87 09 03 AD C7 09 63 1D 0D 32 83 A7 C7 09 +89 47 63 F8 07 05 37 25 02 50 13 05 C5 8C EF 80 +9F FB 03 28 44 1F 35 A8 D8 40 B7 97 03 10 23 A0 +E7 08 98 44 23 A2 E7 08 D8 44 23 A4 E7 08 98 48 +23 A6 E7 08 D8 48 23 A8 E7 08 98 4C 23 AA E7 08 +D8 4C 23 AC E7 08 98 50 23 AE E7 08 89 47 E3 EC +07 FB 03 A7 0C 00 B7 07 03 10 98 CF 03 A7 4C 00 +D8 CF 03 A7 8C 00 98 D3 03 A7 CC 00 D8 D3 03 A7 +0C 01 98 D7 03 A7 4C 01 D8 D7 03 A7 8C 01 98 DB +03 A7 CC 01 D8 DB 03 A7 0C 02 98 DF 03 A7 4C 02 +D8 DF 03 A7 8C 02 B8 C3 03 A7 CC 02 F8 C3 03 A7 +0C 03 B8 C7 03 A7 4C 03 F8 C7 03 A7 8C 03 B8 CB +03 A7 CC 03 F8 CB 63 14 0B 0A 89 4C 63 EF 0C 0B +B7 97 03 10 23 A8 97 01 83 C7 24 00 63 9E 07 0E +B7 C7 03 10 0D 47 98 C7 37 37 02 50 13 07 C7 1F +34 43 7C 43 D5 8F 91 EF 73 00 50 10 93 07 40 06 +01 00 FD 17 C2 07 C1 83 E5 FF 3C 43 74 43 D5 8F +E5 D7 03 25 44 1F 09 4C 63 6C AC 12 37 C6 03 10 +B7 55 FC EF 93 07 06 80 93 85 05 80 13 06 06 E2 +94 43 33 87 B7 00 5E 97 14 C3 91 07 E3 9A C7 FE +63 01 0B 0A 37 C7 03 10 5C 4B 89 8B F5 DF 83 46 +1A 00 85 47 63 8D F6 1E 5C 4B 93 F7 C7 3F 63 81 +07 1A 63 11 05 2A 05 45 EF 80 FF E4 01 A0 93 97 +19 00 11 67 13 07 17 FC 93 F7 F7 0F D9 8F 37 C7 +03 10 1C CB 89 4C E3 F5 0C F5 37 25 02 50 13 05 +C5 AA EF 80 5F E4 B7 97 03 10 03 27 44 1F 23 A8 +97 01 83 C7 24 00 63 8B 07 14 B7 C7 03 10 23 A4 +87 01 89 47 63 FB E7 26 37 15 02 50 13 05 85 4C +EF 80 7F E1 15 B7 37 15 02 50 13 05 05 77 EF 80 +9F E0 03 28 44 1F 39 B3 B7 C7 03 10 05 47 98 C7 +21 B7 89 47 63 8A 0A 08 63 EC A7 1A B7 97 03 10 +A4 4F 63 9F 04 18 E4 4F 63 91 04 22 A4 53 63 9C +04 20 E4 53 63 97 04 20 A4 57 63 9C 04 20 E4 57 +63 97 04 20 A4 5B 63 98 04 20 E4 5B 9D 45 63 9A +04 16 B2 50 22 54 92 54 02 59 F2 49 62 4A D2 4A +42 4B B2 4B 22 4C 92 4C 02 4D 45 61 82 80 37 15 +02 50 13 05 45 79 EF 80 1F D9 03 28 44 1F 75 B1 +6C 43 30 43 2D 65 13 05 C5 D7 EF 80 DF D9 03 25 +44 1F E3 7D AC EA 37 25 02 50 13 05 C5 AC EF 80 +9F D6 03 25 44 1F 5D B5 63 E5 A7 10 B7 97 03 10 +B8 4F 23 20 E9 00 F8 4F 23 22 E9 00 B8 53 23 24 +E9 00 F8 53 23 26 E9 00 B8 57 23 28 E9 00 F8 57 +23 2A E9 00 B8 5B 23 2C E9 00 FC 5B 23 2E F9 00 +8D BF 37 15 02 50 13 05 85 7B EF 80 DF D1 B7 97 +03 10 03 28 44 1F 23 A0 07 08 23 A2 07 08 23 A4 +07 08 23 A6 07 08 23 A8 07 08 23 AA 07 08 23 AC +07 08 23 AE 07 08 E3 7A 0D C7 37 15 02 50 13 05 +C5 7D EF 80 5F CE 03 28 44 1F 85 B1 0D 4C 75 B5 +89 47 63 E1 A7 0C 03 D7 04 00 85 47 E3 1B F7 F0 +93 97 89 00 93 E7 37 0B 37 07 03 30 23 26 F7 0C +09 B7 5C 47 93 F7 C7 3F D9 C3 89 47 E3 F0 07 C9 +37 25 02 50 13 05 85 81 EF 80 FF C9 03 28 44 1F +99 B9 63 18 08 08 05 45 EF 80 FF C6 01 A0 5C 4B +93 F7 C7 3F BD C3 89 47 E3 F5 A7 EC 22 54 B2 50 +92 54 02 59 F2 49 62 4A D2 4A 42 4B B2 4B 22 4C +92 4C 02 4D 37 25 02 50 13 05 C5 92 45 61 6F 80 +9F C5 37 25 02 50 13 05 85 B3 EF 80 DF C4 FD B5 +81 45 83 27 44 1F F1 E3 05 45 EF 80 DF C1 01 A0 +37 25 02 50 13 05 C5 A7 EF 80 FF C2 81 B5 63 1F +08 08 05 45 EF 80 3F C0 01 A0 51 E1 05 45 EF 80 +9F BF 01 A0 37 25 02 50 13 05 05 A1 EF 80 BF C0 +1D BF AD 64 93 84 C4 D7 81 45 13 85 44 3A EF 80 +9F C1 83 27 44 1F A5 D3 EA 85 13 85 04 3D EF 80 +9F C0 83 27 44 1F A1 DB 81 45 13 85 84 3E EF 80 +9F BF 91 B7 37 25 02 50 13 05 C5 AE EF 80 BF BC +99 BB 8D 45 BD BF 89 45 AD BF 85 45 9D BF 95 45 +8D BF 91 45 BD B7 99 45 AD B7 37 37 02 50 13 07 +C7 1F 3C 43 74 43 D5 8F E3 80 07 CC 1D BD 37 25 +02 50 13 05 45 97 EF 80 1F B9 8D BF 37 25 02 50 +13 05 85 85 EF 80 3F B8 A9 BF 2D 69 13 09 C9 D7 +13 05 09 40 EF 80 3F B9 83 27 44 1F E3 86 07 F2 +A6 85 13 05 49 43 EF 80 1F B8 83 27 44 1F E3 8D +07 F0 81 45 13 05 C9 44 EF 80 FF B6 31 B7 01 11 +22 CC 37 34 02 50 03 28 44 1F 26 CA 4E C6 52 C4 +56 C2 06 CE 4A C8 89 47 03 C9 06 00 B6 84 AA 8A +2E 8A B2 89 63 E4 07 23 37 97 03 10 5C 4B 85 8B +F5 DF 89 47 63 E3 07 27 05 67 13 07 07 C6 B7 A5 +03 10 D6 87 33 86 EA 00 B3 85 55 41 94 43 33 87 +F5 00 91 07 14 C3 E3 9B C7 FE 37 C6 03 10 13 06 +06 80 D2 87 93 05 0A 62 33 06 46 41 94 43 33 07 +F6 00 91 07 14 C3 E3 9B B7 FE 89 47 63 E6 07 21 +03 A7 09 00 B7 07 03 10 98 CF 03 A7 49 00 D8 CF +03 A7 89 00 98 D3 03 A7 C9 00 D8 D3 03 A7 09 01 +98 D7 03 A7 49 01 D8 D7 03 A7 89 01 98 DB 03 A7 +C9 01 D8 DB 03 A7 09 02 98 DF 03 A7 49 02 D8 DF +03 A7 89 02 B8 C3 03 A7 C9 02 F8 C3 03 A7 09 03 +B8 C7 03 A7 49 03 F8 C7 03 A7 89 03 B8 CB 03 A7 +C9 03 F8 CB 63 0E 09 00 83 C7 24 00 11 67 13 07 +17 FC 86 07 93 F7 F7 0F D9 8F 37 C7 03 10 1C CB +89 49 63 EE 09 15 B7 97 03 10 0D 47 98 CB 37 37 +02 50 13 07 C7 1F 34 43 7C 43 D5 8F 91 EF 73 00 +50 10 93 07 40 06 01 00 FD 17 C2 07 C1 83 E5 FF +3C 43 74 43 D5 8F E5 D7 83 26 44 1F 89 49 63 E8 +D9 06 63 09 09 08 37 C7 03 10 5C 4B 89 8B F5 DF +03 C6 14 00 85 47 63 03 F6 16 5C 4B 93 F7 C7 3F +63 96 07 14 89 47 63 E9 D7 1A B7 97 03 10 A4 4F +63 90 04 20 E4 4F 63 96 04 26 A4 53 63 91 04 26 +E4 53 63 9C 04 24 A4 57 63 97 04 24 E4 57 63 92 +04 24 A4 5B 63 9D 04 22 E4 5B 9D 45 D9 CC 83 27 +44 1F 63 9C 07 1E 05 45 EF 80 FF 97 01 A0 6C 43 +30 43 2D 65 13 05 C5 D7 EF 80 FF 9A 63 1D 09 0E +83 27 44 1F 63 F8 F9 00 37 25 02 50 13 05 05 D4 +EF 80 7F 97 B7 97 03 10 83 A9 87 05 03 A9 44 00 +63 9C 29 0F 83 A9 C7 05 03 A9 84 00 63 9C 29 19 +83 A9 07 06 03 A9 C4 00 63 9E 29 17 83 A9 47 06 +03 A9 04 01 63 9A 29 17 83 A9 87 06 03 A9 44 01 +63 96 29 17 83 A9 C7 06 03 A9 84 01 63 92 29 17 +83 A9 07 07 03 A9 C4 01 63 90 29 17 83 A9 47 07 +03 A9 04 02 9D 45 63 12 39 0B F2 40 62 44 D2 44 +42 49 B2 49 22 4A 92 4A 05 61 82 80 37 25 02 50 +13 05 85 B5 EF 80 3F 8F 03 28 44 1F F1 B3 37 25 +02 50 13 05 05 BC EF 80 1F 8E 83 27 44 1F 37 97 +03 10 8D 46 14 CB 63 FF F9 0C 37 15 02 50 13 05 +85 4C EF 80 5F 8C 61 B5 37 25 02 50 13 05 05 BA +EF 80 7F 8B 03 28 44 1F E5 B3 37 25 02 50 13 05 +C5 B7 EF 80 5F 8A 03 28 44 1F 79 B3 C9 EE 05 45 +EF 80 7F 87 01 A0 83 26 44 1F 71 B5 5C 4B 93 F7 +C7 3F AD CF 89 47 E3 F2 D7 EA 37 25 02 50 13 05 +05 BE EF 80 5F 87 B9 A0 81 45 83 27 44 1F 89 E7 +05 45 EF 80 5F 84 01 A0 AD 64 93 84 C4 D7 13 85 +84 4C EF 80 5F 87 83 27 44 1F FD D3 CE 85 13 85 +C4 4F EF 80 5F 86 83 27 44 1F F9 DB CA 85 13 85 +44 51 EF 80 5F 85 E9 B7 37 25 02 50 13 05 45 CC +EF 80 7F 82 03 27 44 1F 89 47 E3 F0 E7 E4 37 25 +02 50 13 05 05 D1 EF 80 1F 81 05 BD A1 EA 05 45 +EF 80 6F FE 01 A0 37 25 02 50 13 05 85 C7 EF 80 +8F FF B1 BF 37 37 02 50 13 07 C7 1F 34 43 7C 43 +D5 8F E3 8E 07 DA 83 26 44 1F E3 1E 09 DC 9D B5 +81 45 35 B5 89 45 95 B7 8D 45 85 B7 91 45 B1 BF +95 45 A1 BF 85 45 91 BF 99 45 81 BF 37 25 02 50 +13 05 85 C2 EF 80 2F FB 5D B7 2D 69 13 09 C9 D7 +13 05 49 46 EF 80 2F FC 83 27 44 1F E3 8D 07 DE +A6 85 13 05 89 49 EF 80 0F FB 83 27 44 1F E3 84 +07 DE 81 45 13 05 09 4B EF 80 EF F9 E9 BB 99 45 +F9 B3 95 45 E9 B3 91 45 D9 B3 8D 45 C9 B3 89 45 +7D BB 85 45 6D BB 01 11 22 CC 37 34 02 50 03 28 +44 1F 26 CA 4E C6 52 C4 56 C2 06 CE 4A C8 89 47 +03 C9 06 00 B6 84 AA 8A 2E 8A B2 89 63 E8 07 1B +37 97 03 10 5C 4B 85 8B F5 DF 89 47 63 E9 07 1B +05 67 13 07 07 C6 B7 A5 03 10 D6 87 33 86 EA 00 +B3 85 55 41 94 43 33 87 F5 00 91 07 14 C3 E3 9B +C7 FE 37 C6 03 10 13 06 06 80 D2 87 93 05 0A 62 +33 06 46 41 94 43 33 07 F6 00 91 07 14 C3 E3 9B +B7 FE 89 47 63 E3 07 1B 03 A7 09 00 B7 07 03 10 +98 CF 03 A7 49 00 D8 CF 03 A7 89 00 98 D3 03 A7 +C9 00 D8 D3 03 A7 09 01 98 D7 03 A7 49 01 D8 D7 +03 A7 89 01 98 DB 03 A7 C9 01 D8 DB 03 A7 09 02 +98 DF 03 A7 49 02 D8 DF 03 A7 89 02 B8 C3 03 A7 +C9 02 F8 C3 03 A7 09 03 B8 C7 03 A7 49 03 F8 C7 +03 A7 89 03 B8 CB 03 A7 C9 03 F8 CB 63 0E 09 00 +83 C7 24 00 11 67 13 07 17 FC 86 07 93 F7 F7 0F +D9 8F 37 C7 03 10 1C CB 89 49 63 EB 09 0F B7 97 +03 10 0D 47 98 CB 37 37 02 50 13 07 C7 1F 34 43 +7C 43 D5 8F 91 EF 73 00 50 10 93 07 40 06 01 00 +FD 17 C2 07 C1 83 E5 FF 3C 43 74 43 D5 8F E5 D7 +83 26 44 1F 89 49 63 E3 D9 04 63 04 09 06 37 C7 +03 10 5C 4B 89 8B F5 DF 03 C6 14 00 85 47 63 07 +F6 0E 5C 4B 93 F7 C7 3F E9 EF 89 47 63 FF D7 04 +37 25 02 50 13 05 45 CC 62 44 F2 40 D2 44 42 49 +B2 49 22 4A 92 4A 05 61 6F 80 EF DD 6C 43 30 43 +2D 65 13 05 C5 D7 EF 80 0F DF 63 11 09 0A 83 27 +44 1F 63 F8 F9 00 37 25 02 50 13 05 45 DF EF 80 +8F DB 37 97 03 10 34 4F 93 07 C7 05 78 4F D8 43 +98 47 D8 47 98 4B D8 4B 9C 4F F2 40 62 44 D2 44 +42 49 B2 49 22 4A 92 4A 05 61 82 80 37 25 02 50 +13 05 85 B5 EF 80 2F D8 03 28 44 1F 91 B5 37 25 +02 50 13 05 C5 B7 EF 80 0F D7 03 28 44 1F 89 B5 +37 25 02 50 13 05 05 BC EF 80 EF D5 83 27 44 1F +37 97 03 10 8D 46 14 CB 63 FD F9 04 37 15 02 50 +13 05 85 4C EF 80 2F D4 FD B5 37 25 02 50 13 05 +05 BA EF 80 4F D3 03 28 44 1F B9 B5 83 26 44 1F +39 B7 8D E2 05 45 EF 80 0F D0 01 A0 5C 4B 93 F7 +C7 3F 95 CF 89 47 E3 FA D7 F6 37 25 02 50 13 05 +05 D6 19 BF 37 25 02 50 13 05 85 C7 EF 80 AF CF +D1 BF 37 37 02 50 13 07 C7 1F 34 43 7C 43 D5 8F +E3 83 07 EA 83 26 44 1F E3 13 09 EC 1D B7 89 E6 +05 45 EF 80 4F CB 01 A0 37 25 02 50 13 05 85 DA +EF 80 6F CC F5 B7 79 71 4A D0 37 39 02 50 03 28 +49 1F 4E CE 5E C6 62 C4 66 C2 06 D6 22 D4 26 D2 +52 CC 56 CA 5A C8 6A C0 89 47 03 CB 06 00 03 CA +26 00 B6 89 2A 8C AE 8B B2 8C 63 EE 07 2B B7 94 +03 10 C0 48 05 88 75 DC 83 4A 0C 00 63 8C 0A 08 +83 47 2C 00 37 C7 03 10 09 4D 86 07 93 F7 E7 03 +93 E7 17 00 1C C3 63 6C 0D 39 23 AC 04 00 23 AE +04 00 23 A0 04 02 23 A2 04 02 23 A4 04 02 23 A6 +04 02 23 A8 04 02 23 AA 04 02 B7 97 03 10 23 AC +07 02 23 AE 07 02 23 A0 07 04 23 A2 07 04 23 A4 +07 04 23 A6 07 04 23 A8 07 04 23 AA 07 04 37 C7 +03 10 5C 43 89 8B F5 DF 83 46 1C 00 85 47 63 93 +F6 08 5C 43 93 F7 C7 3F 63 88 07 3A 89 47 63 FB +07 07 37 15 02 50 13 05 C5 59 EF 80 CF BE 03 28 +49 1F 8D A0 83 27 4C 00 9C CC 83 27 8C 00 DC CC +83 27 CC 00 9C D0 83 27 0C 01 DC D0 83 27 4C 01 +9C D4 83 27 8C 01 DC D4 83 27 CC 01 9C D8 83 27 +0C 02 DC D8 83 27 4C 02 9C DC 83 27 8C 02 DC DC +83 27 CC 02 BC C0 83 27 0C 03 FC C0 83 27 4C 03 +BC C4 83 27 8C 03 FC C4 83 27 CC 03 BC C8 83 27 +0C 04 FC C8 37 C6 03 10 DE 87 13 06 06 80 93 8B +0B 62 1D 8E 94 43 33 07 F6 00 91 07 14 C3 E3 9B +77 FF 89 47 63 EC 07 27 03 A7 0C 00 B7 07 03 10 +98 CF 03 A7 4C 00 D8 CF 03 A7 8C 00 98 D3 03 A7 +CC 00 D8 D3 03 A7 0C 01 98 D7 03 A7 4C 01 D8 D7 +03 A7 8C 01 98 DB 03 A7 CC 01 D8 DB 03 A7 0C 02 +98 DF 03 A7 4C 02 D8 DF 03 A7 8C 02 B8 C3 03 A7 +CC 02 F8 C3 03 A7 0C 03 B8 C7 03 A7 4C 03 F8 C7 +03 A7 8C 03 B8 CB 03 A7 CC 03 F8 CB 63 12 0B 0C +89 47 63 ED 07 0D B7 97 03 10 11 47 98 CB 83 47 +2C 00 63 89 07 14 B7 C7 03 10 05 47 98 C3 37 37 +02 50 13 07 C7 1F 34 43 7C 43 D5 8F 9D E3 73 00 +50 10 93 07 40 06 01 00 FD 17 C2 07 C1 83 E5 FF +3C 43 74 43 D5 8F E5 D7 03 28 49 1F 09 44 63 65 +04 0F 63 1E 0B 10 63 93 0A 16 B7 97 03 10 A4 4F +03 A4 49 00 63 1C 94 32 E4 4F 03 A4 89 00 63 1F +94 30 A4 53 03 A4 C9 00 63 1C 94 30 E4 53 03 A4 +09 01 63 99 84 26 A4 57 03 A4 49 01 63 92 84 26 +E4 57 03 A4 89 01 63 9B 84 24 A4 5B 03 A4 C9 01 +63 9E 84 24 E4 5B 03 A4 09 02 9D 45 63 02 94 14 +83 27 49 1F 63 94 07 26 05 45 EF 80 CF A1 01 A0 +93 17 1A 00 11 67 13 07 17 FC 93 F7 F7 0F D9 8F +37 C7 03 10 1C CB 89 47 E3 F7 07 F3 37 25 02 50 +13 05 45 EC EF 80 2F A1 B7 97 03 10 11 47 03 28 +49 1F 98 CB 83 47 2C 00 63 83 07 12 B7 C7 03 10 +80 C3 89 47 E3 FD 07 F1 37 15 02 50 13 05 85 4C +EF 80 6F 9E 37 37 02 50 13 07 C7 1F 3C 43 74 43 +D5 8F 91 D7 15 B7 37 25 02 50 13 05 45 E1 EF 80 +8F 9C 03 28 49 1F 25 BB 6C 43 30 43 2D 65 13 05 +C5 D7 EF 80 4F 9D 03 28 49 1F 63 12 0B 02 63 9F +0A 04 E3 74 04 F1 37 25 02 50 13 05 85 03 EF 80 +8F 99 E5 BD B7 C7 03 10 0D 47 98 C3 4D BD 37 C7 +03 10 5C 4B 89 8B F5 DF 83 C6 19 00 85 47 63 8B +F6 0E 5C 4B 93 F7 C7 3F C9 EF 89 47 63 E2 07 15 +03 57 0C 00 85 47 63 1D F7 04 93 17 8A 00 93 E7 +37 0B 37 07 03 30 23 26 F7 0C 99 A0 63 78 04 01 +37 25 02 50 13 05 05 06 EF 80 EF 93 B7 97 03 10 +A0 4F 63 19 04 0E E0 4F 63 16 04 1C A0 53 63 15 +04 1C E0 53 63 1A 04 1A A0 57 63 15 04 1A E0 57 +63 10 04 1A A0 5B 63 19 04 10 E0 5B 9D 45 61 E4 +B2 50 22 54 92 54 02 59 F2 49 62 4A D2 4A 42 4B +B2 4B 22 4C 92 4C 02 4D 45 61 82 80 37 25 02 50 +13 05 C5 E9 EF 80 2F 8E 03 28 49 1F B5 BB 0D 44 +F1 BD 63 1E 08 0A 05 45 EF 80 EF 8A 01 A0 37 25 +02 50 13 05 C5 E3 EF 80 0F 8C 03 28 49 1F 23 AC +04 00 23 AE 04 00 23 A0 04 02 23 A2 04 02 23 A4 +04 02 23 A6 04 02 23 A8 04 02 23 AA 04 02 E3 7E +0D C5 37 25 02 50 13 05 C5 E6 EF 80 CF 88 03 28 +49 1F A1 B1 5C 4B 93 F7 C7 3F A9 C7 89 47 E3 F9 +07 F7 22 54 B2 50 92 54 02 59 F2 49 62 4A D2 4A +42 4B B2 4B 22 4C 92 4C 02 4D 37 25 02 50 13 05 +C5 EE 45 61 6F 80 2F 85 63 1C 08 04 05 45 EF 80 +8F 82 01 A0 81 45 83 27 49 1F D9 EB 05 45 EF 80 +8F 81 01 A0 63 15 08 04 05 45 EF 80 CF 80 01 A0 +37 25 02 50 13 05 45 FE EF 80 EF 81 55 BD 37 25 +02 50 13 05 05 F9 EF 80 0F 81 35 BF 95 45 C9 B3 +91 45 7D BB 8D 45 6D BB 99 45 75 BF 99 45 4D BB +37 15 02 50 13 05 05 5E EF 70 FF FE 45 B7 37 25 +02 50 13 05 C5 F3 EF 70 1F FE 7D B7 AD 69 93 89 +C9 D7 13 85 C9 52 EF 70 1F FF 83 27 49 1F E3 85 +07 D8 A6 85 13 85 09 56 EF 70 FF FD 83 27 49 1F +E3 8C 07 D6 A2 85 13 85 89 57 EF 70 DF FC AD B3 +AD 64 93 84 C4 D7 13 85 04 59 EF 70 DF FB 83 27 +49 1F A9 DF A2 85 13 85 44 5C EF 70 DF FA 83 27 +49 1F A9 D7 81 45 13 85 C4 5D EF 70 DF F9 3D BF +95 45 15 BF 91 45 05 BF 8D 45 35 B7 85 45 0D B3 +89 45 39 BB 85 45 05 B7 89 45 31 BF 81 45 09 BB +79 71 26 D2 B7 34 02 50 03 A8 44 1F 4E CE 5A C8 +5E C6 62 C4 06 D6 22 D4 4A D0 52 CC 56 CA 66 C2 +89 47 03 CA 06 00 03 C9 26 00 B6 89 2A 8B AE 8B +32 8C 63 ED 07 29 37 94 03 10 5C 48 85 8B F5 DF +83 4A 0B 00 63 8C 0A 08 83 47 2B 00 37 C7 03 10 +89 4C 86 07 93 F7 E7 03 93 E7 17 00 1C C3 63 E1 +0C 35 23 2C 04 00 23 2E 04 00 23 20 04 02 23 22 +04 02 23 24 04 02 23 26 04 02 23 28 04 02 23 2A +04 02 B7 97 03 10 23 AC 07 02 23 AE 07 02 23 A0 +07 04 23 A2 07 04 23 A4 07 04 23 A6 07 04 23 A8 +07 04 23 AA 07 04 37 C7 03 10 5C 43 89 8B F5 DF +83 46 1B 00 85 47 63 93 F6 08 5C 43 93 F7 C7 3F +63 8C 07 34 89 47 63 FB 07 07 37 15 02 50 13 05 +C5 59 EF 70 5F E8 03 A8 44 1F 8D A0 83 27 4B 00 +1C CC 83 27 8B 00 5C CC 83 27 CB 00 1C D0 83 27 +0B 01 5C D0 83 27 4B 01 1C D4 83 27 8B 01 5C D4 +83 27 CB 01 1C D8 83 27 0B 02 5C D8 83 27 4B 02 +1C DC 83 27 8B 02 5C DC 83 27 CB 02 3C C0 83 27 +0B 03 7C C0 83 27 4B 03 3C C4 83 27 8B 03 7C C4 +83 27 CB 03 3C C8 83 27 0B 04 7C C8 37 C6 03 10 +DE 87 13 06 06 80 93 8B 0B 62 1D 8E 94 43 33 07 +F6 00 91 07 14 C3 E3 9B FB FE 89 47 63 E3 07 23 +03 27 0C 00 B7 07 03 10 98 CF 03 27 4C 00 D8 CF +03 27 8C 00 98 D3 03 27 CC 00 D8 D3 03 27 0C 01 +98 D7 03 27 4C 01 D8 D7 03 27 8C 01 98 DB 03 27 +CC 01 D8 DB 03 27 0C 02 98 DF 03 27 4C 02 D8 DF +03 27 8C 02 B8 C3 03 27 CC 02 F8 C3 03 27 0C 03 +B8 C7 03 27 4C 03 F8 C7 03 27 8C 03 B8 CB 03 27 +CC 03 F8 CB 63 1F 0A 08 09 44 63 6A 04 0B B7 97 +03 10 11 47 98 CB 83 47 2B 00 37 C7 03 10 86 07 +93 F7 E7 03 93 E7 17 00 1C C3 37 37 02 50 13 07 +C7 1F 3C 43 74 43 D5 8F 9D E3 73 00 50 10 93 07 +40 06 01 00 FD 17 C2 07 C1 83 E5 FF 3C 43 74 43 +D5 8F E5 D7 03 A8 44 1F 09 44 63 66 04 11 63 00 +0A 0C 37 C7 03 10 5C 4B 89 8B F5 DF 83 C6 19 00 +85 47 63 8A F6 1A 5C 4B 93 F7 C7 3F 63 9C 07 14 +89 47 63 E7 07 21 03 57 0B 00 85 47 63 1E F7 10 +93 17 89 00 93 E7 37 0B 37 07 03 30 23 26 F7 0C +21 A2 93 17 19 00 11 67 13 07 17 FC 93 F7 F7 0F +D9 8F 37 C7 03 10 1C CB 09 44 E3 7A 04 F5 37 25 +02 50 13 05 45 EC EF 70 1F CD B7 97 03 10 11 47 +03 A8 44 1F 98 CB 83 47 2B 00 37 C7 03 10 86 07 +93 F7 E7 03 93 E7 17 00 1C C3 E3 70 04 F5 37 15 +02 50 13 05 85 4C EF 70 1F CA 37 37 02 50 13 07 +C7 1F 34 43 7C 43 D5 8F 8D DB A9 B7 37 25 02 50 +13 05 45 E1 EF 70 3F C8 03 A8 44 1F A9 BB 63 89 +0A 06 B7 97 03 10 A0 4F 63 11 04 18 E0 4F 63 19 +04 18 A0 53 63 18 04 18 E0 53 63 16 04 16 A0 57 +63 11 04 16 E0 57 63 1C 04 14 A0 5B 63 11 04 16 +E0 5B 9D 45 31 C8 83 A7 44 1F 63 97 07 16 05 45 +EF 70 7F C1 01 A0 6C 43 30 43 2D 65 13 05 C5 D7 +EF 70 7F C4 03 A8 44 1F E3 15 0A EE 63 94 0A 0E +63 78 04 01 37 25 02 50 13 05 85 09 EF 70 BF C0 +37 97 03 10 34 4F 93 07 C7 05 78 4F D8 43 98 47 +D8 47 98 4B D8 4B 9C 4F B2 50 22 54 92 54 02 59 +F2 49 62 4A D2 4A 42 4B B2 4B 22 4C 92 4C 45 61 +82 80 37 25 02 50 13 05 C5 E9 EF 70 DF BC 03 A8 +44 1F F9 B3 63 17 08 0A 05 45 EF 70 DF B9 01 A0 +37 25 02 50 13 05 C5 E3 EF 70 FF BA 03 A8 44 1F +23 2C 04 00 23 2E 04 00 23 20 04 02 23 22 04 02 +23 24 04 02 23 26 04 02 23 28 04 02 23 2A 04 02 +E3 F9 0C CB 37 25 02 50 13 05 C5 E6 EF 70 BF B7 +03 A8 44 1F 79 B9 5C 4B 93 F7 C7 3F A9 C7 89 47 +E3 FC 07 F7 22 54 B2 50 92 54 02 59 F2 49 62 4A +D2 4A 42 4B B2 4B 22 4C 92 4C 37 25 02 50 13 05 +C5 EE 45 61 6F 70 3F B4 63 1D 08 04 05 45 EF 70 +9F B1 01 A0 E3 7F 04 EB 37 25 02 50 13 05 05 06 +EF 70 7F B2 7D B5 63 13 08 08 05 45 EF 70 BF AF +01 A0 37 25 02 50 13 05 05 F9 EF 70 DF B0 A9 B7 +37 25 02 50 13 05 45 FE EF 70 FF AF ED B3 95 45 +5D BD 91 45 4D BD 8D 45 7D B5 81 45 6D B5 99 45 +5D B5 37 15 02 50 13 05 05 5E EF 70 DF AD 79 BF +85 45 51 BD 89 45 41 BD 2D 69 13 09 C9 D7 13 05 +49 5F EF 70 5F AE 83 A7 44 1F E3 82 07 E8 A2 85 +13 05 89 62 EF 70 3F AD 83 A7 44 1F E3 89 07 E6 +81 45 13 05 09 64 EF 70 1F AC 95 B5 37 25 02 50 +13 05 C5 F3 EF 70 3F A9 8D BF 01 00 52 65 63 65 +69 76 65 64 20 4D 4C 4B 45 4D 20 6E 6F 74 69 66 +2F 20 65 72 72 20 69 6E 74 72 20 77 69 74 68 20 +73 74 61 74 75 73 20 3D 20 25 64 2F 20 25 64 0A +00 00 00 00 41 74 20 6F 66 66 73 65 74 20 5B 25 +64 5D 2C 20 6D 6C 6B 65 6D 5F 65 6E 63 61 70 73 +5F 6B 65 79 20 64 61 74 61 20 6D 69 73 6D 61 74 +63 68 21 0A 00 00 00 00 41 63 74 75 61 6C 20 20 +20 64 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +45 78 70 65 63 74 65 64 20 64 61 74 61 3A 20 30 +78 25 78 0A 00 00 00 00 41 74 20 6F 66 66 73 65 +74 20 5B 25 64 5D 2C 20 6D 6C 6B 65 6D 5F 64 65 +63 61 70 73 5F 6B 65 79 20 64 61 74 61 20 6D 69 +73 6D 61 74 63 68 21 0A 00 00 00 00 41 63 74 75 +61 6C 20 20 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 45 78 70 65 63 74 65 64 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 41 74 20 6F +66 66 73 65 74 20 5B 25 64 5D 2C 20 6D 6C 6B 65 +6D 5F 73 65 65 64 5F 64 20 64 61 74 61 20 6D 69 +73 6D 61 74 63 68 21 0A 00 00 00 00 41 63 74 75 +61 6C 20 20 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 45 78 70 65 63 74 65 64 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 41 74 20 6F +66 66 73 65 74 20 5B 25 64 5D 2C 20 6D 6C 6B 65 +6D 5F 73 65 65 64 5F 7A 20 64 61 74 61 20 6D 69 +73 6D 61 74 63 68 21 0A 00 00 00 00 41 63 74 75 +61 6C 20 20 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 45 78 70 65 63 74 65 64 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 41 74 20 6F +66 66 73 65 74 20 5B 25 64 5D 2C 20 6D 6C 6B 65 +6D 5F 64 6B 20 64 61 74 61 20 6D 69 73 6D 61 74 +63 68 21 0A 00 00 00 00 41 63 74 75 61 6C 20 20 +20 64 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +45 78 70 65 63 74 65 64 20 64 61 74 61 3A 20 30 +78 25 78 0A 00 00 00 00 41 74 20 6F 66 66 73 65 +74 20 5B 25 64 5D 2C 20 6D 6C 6B 65 6D 5F 6D 73 +67 20 64 61 74 61 20 6D 69 73 6D 61 74 63 68 21 +0A 00 00 00 41 63 74 75 61 6C 20 20 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 45 78 70 65 +63 74 65 64 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 41 74 20 6F 66 66 73 65 74 20 5B 25 +64 5D 2C 20 6D 6C 6B 65 6D 5F 63 69 70 68 65 72 +74 65 78 74 20 64 61 74 61 20 6D 69 73 6D 61 74 +63 68 21 0A 00 00 00 00 41 63 74 75 61 6C 20 20 +20 64 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +45 78 70 65 63 74 65 64 20 64 61 74 61 3A 20 30 +78 25 78 0A 00 00 00 00 41 74 20 6F 66 66 73 65 +74 20 5B 25 64 5D 2C 20 6D 6C 6B 65 6D 5F 73 68 +61 72 65 64 5F 6B 65 79 20 64 61 74 61 20 6D 69 +73 6D 61 74 63 68 21 0A 00 00 00 00 41 63 74 75 +61 6C 20 20 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 45 78 70 65 63 74 65 64 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 41 74 20 6F +66 66 73 65 74 20 5B 25 64 5D 2C 20 6D 6C 6B 65 +6D 5F 73 68 61 72 65 64 5F 6B 65 79 20 64 61 74 +61 20 6D 69 73 6D 61 74 63 68 21 0A 00 00 00 00 +41 63 74 75 61 6C 20 20 20 64 61 74 61 3A 20 30 +78 25 78 0A 00 00 00 00 45 78 70 65 63 74 65 64 +20 64 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +41 74 20 6F 66 66 73 65 74 20 5B 25 64 5D 2C 20 +6D 6C 6B 65 6D 5F 6D 73 67 20 64 61 74 61 20 6D +69 73 6D 61 74 63 68 21 0A 00 00 00 41 63 74 75 +61 6C 20 20 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 45 78 70 65 63 74 65 64 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 41 74 20 6F +66 66 73 65 74 20 5B 25 64 5D 2C 20 6D 6C 6B 65 +6D 5F 73 68 61 72 65 64 5F 6B 65 79 20 64 61 74 +61 20 6D 69 73 6D 61 74 63 68 21 0A 00 00 00 00 +41 63 74 75 61 6C 20 20 20 64 61 74 61 3A 20 30 +78 25 78 0A 00 00 00 00 45 78 70 65 63 74 65 64 +20 64 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +41 74 20 6F 66 66 73 65 74 20 5B 25 64 5D 2C 20 +6D 6C 6B 65 6D 5F 73 68 61 72 65 64 5F 6B 65 79 +20 64 61 74 61 20 6D 69 73 6D 61 74 63 68 21 0A +00 00 00 00 41 63 74 75 61 6C 20 20 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 45 78 70 65 +63 74 65 64 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 41 74 20 6F 66 66 73 65 74 20 5B 25 +64 5D 2C 20 6D 6C 6B 65 6D 5F 73 68 61 72 65 64 +5F 6B 65 79 20 64 61 74 61 20 6D 69 73 6D 61 74 +63 68 21 0A 00 00 00 00 41 63 74 75 61 6C 20 20 +20 64 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +45 78 70 65 63 74 65 64 20 64 61 74 61 3A 20 30 +78 25 78 0A 00 00 00 00 41 74 20 6F 66 66 73 65 +74 20 5B 25 64 5D 2C 20 6D 6C 6B 65 6D 5F 73 68 +61 72 65 64 5F 6B 65 79 20 64 61 74 61 20 6D 69 +73 6D 61 74 63 68 21 0A 00 00 00 00 41 63 74 75 +61 6C 20 20 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 45 78 70 65 63 74 65 64 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 41 74 20 6F +66 66 73 65 74 20 5B 25 64 5D 2C 20 6D 6C 6B 65 +6D 5F 73 68 61 72 65 64 5F 6B 65 79 20 64 61 74 +61 20 6D 69 73 6D 61 74 63 68 21 0A 00 00 00 00 +41 63 74 75 61 6C 20 20 20 64 61 74 61 3A 20 30 +78 25 78 0A 00 00 00 00 45 78 70 65 63 74 65 64 +20 64 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +41 74 20 6F 66 66 73 65 74 20 5B 25 64 5D 2C 20 +6D 6C 6B 65 6D 5F 73 68 61 72 65 64 5F 6B 65 79 +20 64 61 74 61 20 6D 69 73 6D 61 74 63 68 21 0A +00 00 00 00 41 63 74 75 61 6C 20 20 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 45 78 70 65 +63 74 65 64 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 41 11 22 C4 37 34 02 50 03 27 44 1F +06 C6 89 47 63 E0 E7 04 37 37 02 50 13 07 C7 1F +1C 4B 54 4B D5 8F 9D E3 73 00 50 10 93 07 40 06 +01 00 FD 17 C2 07 C1 83 E5 FF 1C 4B 54 4B D5 8F +E5 D7 83 26 44 1F 89 47 63 E5 D7 02 B2 40 22 44 +41 01 82 80 37 25 02 50 13 05 05 0C EF 70 AF BD +37 37 02 50 13 07 C7 1F 1C 4B 54 4B D5 8F CD DF +C9 BF 22 44 4C 4B B2 40 10 4B 31 65 13 05 45 5E +41 01 6F 70 4F BD B7 37 02 50 03 A7 47 1F 89 47 +63 E7 E7 00 B7 07 01 10 11 47 98 CB 82 80 37 25 +02 50 41 11 13 05 C5 0D 06 C6 EF 70 CF B8 B2 40 +B7 07 01 10 11 47 98 CB 41 01 82 80 19 CA 0A 06 +33 87 C5 00 9C 41 91 05 11 05 23 2E F5 FE E3 9B +E5 FE 82 80 39 71 5A D0 62 CC 66 CA 6A C8 6E C6 +06 DE 22 DC 26 DA 4A D8 4E D6 52 D4 56 D2 5E CE +03 49 15 00 83 4B 25 00 03 CA 15 00 83 C9 25 00 +83 CA 06 00 AA 8D 2E 8C B6 8C 32 8D 3A 8B B7 07 +01 10 80 4F 05 88 75 DC 03 C7 0D 00 B7 34 02 50 +03 A5 44 1F 45 C3 13 97 1B 00 13 77 E7 03 13 67 +17 00 23 A0 E7 60 89 47 63 ED A7 30 B7 07 01 10 +23 A0 07 04 23 A2 07 04 23 A4 07 04 23 A6 07 04 +23 A8 07 04 23 AA 07 04 23 AC 07 04 23 AE 07 04 +23 A0 07 06 23 A2 07 06 23 A4 07 06 23 A6 07 06 +37 07 01 10 83 27 47 60 89 8B ED DF 85 47 63 1C +F9 08 83 27 47 60 93 F7 C7 3F 63 80 07 32 89 47 +63 ED A7 3A 83 47 0C 00 63 96 07 36 37 06 01 10 +B7 05 FF EF 93 07 06 08 93 85 05 F8 13 06 06 10 +BE 86 91 07 33 87 B7 00 62 97 18 43 98 C2 E3 99 +C7 FE 75 A0 89 47 63 EF A7 28 03 A7 4D 00 B7 07 +01 10 B8 C3 03 A7 8D 00 F8 C3 03 A7 CD 00 B8 C7 +03 A7 0D 01 F8 C7 03 A7 4D 01 B8 CB 03 A7 8D 01 +F8 CB 03 A7 CD 01 B8 CF 03 A7 0D 02 F8 CF 03 A7 +4D 02 B8 D3 03 A7 8D 02 F8 D3 03 A7 CD 02 B8 D7 +03 A7 0D 03 F8 D7 83 47 0C 00 C9 D3 93 97 19 00 +93 F7 E7 03 93 E7 17 00 37 07 01 10 23 24 F7 60 +89 47 63 FA A7 00 37 25 02 50 13 05 05 1D EF 70 +8F 9F 03 A5 44 1F B7 06 01 10 93 87 06 08 93 86 +06 10 23 A0 07 00 91 07 E3 9D D7 FE 37 07 01 10 +83 27 C7 60 89 8B ED DF 85 47 63 0F FA 20 03 27 +4D 00 B7 07 01 10 23 A0 E7 14 03 27 8D 00 23 A2 +E7 14 03 27 CD 00 23 A4 E7 14 03 27 0D 01 23 A6 +E7 14 03 27 4D 01 23 A8 E7 14 03 27 8D 01 23 AA +E7 14 03 27 CD 01 23 AC E7 14 03 27 0D 02 23 AE +E7 14 03 27 4D 02 23 A0 E7 16 03 27 8D 02 23 A2 +E7 16 03 27 CD 02 23 A4 E7 16 03 27 0D 03 23 A6 +E7 16 63 8D 0A 00 03 C7 2C 00 85 66 93 86 16 FC +06 07 13 77 F7 0F 55 8F 23 A8 E7 60 B7 07 01 10 +63 0E 0B 12 05 47 98 CB A2 87 63 93 0B 00 8D 47 +37 07 01 10 23 20 F7 60 63 93 09 00 0D 44 B7 07 +01 10 23 A4 87 60 89 47 63 ED A7 10 37 37 02 50 +13 07 C7 1F 1C 4B 54 4B D5 8F 95 EB 73 00 50 10 +93 07 40 06 01 00 FD 17 C2 07 C1 83 E5 FF 1C 4B +54 4B D5 8F E5 D7 83 A6 44 1F 89 47 63 F9 D7 00 +4C 4B 10 4B 31 65 13 05 45 5E EF 70 CF 8F 33 69 +49 01 63 16 09 0A 83 A7 44 1F 09 47 63 95 0A 10 +63 68 F7 16 B7 07 01 10 03 A7 07 10 83 A7 4C 00 +63 1C F7 14 B7 07 01 10 03 A9 47 10 03 A4 8C 00 +63 1E 24 13 03 A9 87 10 03 A4 CC 00 63 1C 24 1F +03 A9 C7 10 03 A4 0C 01 63 14 24 1F 03 A9 07 11 +03 A4 4C 01 63 1C 89 1C 03 A9 47 11 03 A4 8C 01 +63 14 89 1C 03 A9 87 11 03 A4 CC 01 63 1C 89 1A +03 A9 C7 11 03 A4 0C 02 63 14 89 1A 03 A9 07 12 +03 A4 4C 02 63 1C 89 18 03 A9 47 12 03 A4 8C 02 +63 14 89 18 03 A9 87 12 03 A4 CC 02 63 12 89 10 +03 A9 C7 12 03 A4 0C 03 AD 45 63 12 89 0C F2 50 +62 54 D2 54 42 59 B2 59 22 5A 92 5A 02 5B F2 4B +62 4C D2 4C 42 4D B2 4D 21 61 82 80 09 47 98 CB +E1 B5 37 25 02 50 13 05 05 0C EF 60 DF FF 37 37 +02 50 13 07 C7 1F 1C 4B 54 4B D5 8F E3 80 07 EE +DD BD 37 25 02 50 13 05 05 0F EF 60 DF FD 03 A5 +44 1F E9 B9 37 25 02 50 13 05 85 1B EF 60 BF FC +03 A5 44 1F 99 BB 63 64 F7 04 37 07 01 10 83 27 +47 61 89 8B ED DF 61 B7 83 27 C7 60 93 F7 C7 3F +95 C3 89 47 E3 FD A7 DC 37 25 02 50 13 05 45 1F +EF 60 7F F9 03 A5 44 1F D9 B3 61 E1 05 45 EF 60 +9F F6 01 A0 45 E5 05 45 EF 60 FF F5 01 A0 37 25 +02 50 13 05 85 29 EF 60 1F F7 45 BF 85 45 83 A7 +44 1F 09 4A 63 61 FA 04 05 45 EF 60 DF F3 01 A0 +37 25 02 50 13 05 85 2B EF 60 FF F4 B7 07 01 10 +03 A9 07 10 03 A4 4C 00 E3 06 24 E9 81 45 C1 BF +A9 45 F1 B7 93 97 19 00 93 F7 E7 03 93 E7 17 00 +23 24 F7 60 0D BB B1 69 93 89 49 5E 13 85 49 03 +EF 60 7F F3 83 A7 44 1F E3 78 FA FA CA 85 13 85 +09 06 EF 60 5F F2 83 A7 44 1F E3 7F FA F8 A2 85 +13 85 89 07 EF 60 3F F1 41 BF 37 25 02 50 13 05 +85 11 EF 60 5F EE 03 A5 44 1F 75 B9 37 25 02 50 +13 05 45 24 EF 60 3F ED B9 B7 37 25 02 50 13 05 +45 16 EF 60 5F EC 1D BF A5 45 91 BF A1 45 81 BF +9D 45 B1 B7 99 45 A1 B7 95 45 91 B7 91 45 81 B7 +8D 45 35 BF 89 45 25 BF 39 71 5A D0 62 CC 66 CA +6A C8 6E C6 06 DE 22 DC 26 DA 4A D8 4E D6 52 D4 +56 D2 5E CE 03 49 15 00 83 4B 25 00 03 CA 15 00 +83 C9 25 00 83 CA 06 00 AA 8D AE 8C 36 8C 32 8D +3A 8B B7 07 01 10 80 4F 05 88 75 DC 03 C7 0D 00 +B7 34 02 50 03 A5 44 1F 45 CB 13 97 1B 00 13 77 +E7 03 13 67 17 00 23 A0 E7 60 89 47 63 E7 A7 38 +B7 07 01 10 23 A0 07 04 23 A2 07 04 23 A4 07 04 +23 A6 07 04 23 A8 07 04 23 AA 07 04 23 AC 07 04 +23 AE 07 04 23 A0 07 06 23 A2 07 06 23 A4 07 06 +23 A6 07 06 23 A8 07 06 23 AA 07 06 23 AC 07 06 +23 AE 07 06 37 07 01 10 83 27 47 60 89 8B ED DF +85 47 63 18 F9 0A 83 27 47 60 93 F7 C7 3F 63 89 +07 36 89 47 63 EF A7 3E 83 C7 0C 00 63 9A 07 38 +37 06 01 10 B7 05 FF EF 93 07 06 08 93 85 05 F8 +13 06 06 10 BE 86 91 07 33 87 B7 00 66 97 18 43 +98 C2 E3 99 C7 FE D1 A0 89 47 63 E1 A7 30 03 A7 +4D 00 B7 07 01 10 B8 C3 03 A7 8D 00 F8 C3 03 A7 +CD 00 B8 C7 03 A7 0D 01 F8 C7 03 A7 4D 01 B8 CB +03 A7 8D 01 F8 CB 03 A7 CD 01 B8 CF 03 A7 0D 02 +F8 CF 03 A7 4D 02 B8 D3 03 A7 8D 02 F8 D3 03 A7 +CD 02 B8 D7 03 A7 0D 03 F8 D7 03 A7 4D 03 B8 DB +03 A7 8D 03 F8 DB 03 A7 CD 03 B8 DF 03 A7 0D 04 +F8 DF 83 C7 0C 00 AD D7 93 97 19 00 93 F7 E7 03 +93 E7 17 00 37 07 01 10 23 24 F7 60 89 47 63 FA +A7 00 37 25 02 50 13 05 05 1D EF 60 DF D0 03 A5 +44 1F B7 06 01 10 93 87 06 08 93 86 06 10 23 A0 +07 00 91 07 E3 9D D7 FE 37 07 01 10 83 27 C7 60 +89 8B ED DF 85 47 63 0C FA 24 03 27 4D 00 B7 07 +01 10 23 A0 E7 14 03 27 8D 00 23 A2 E7 14 03 27 +CD 00 23 A4 E7 14 03 27 0D 01 23 A6 E7 14 03 27 +4D 01 23 A8 E7 14 03 27 8D 01 23 AA E7 14 03 27 +CD 01 23 AC E7 14 03 27 0D 02 23 AE E7 14 03 27 +4D 02 23 A0 E7 16 03 27 8D 02 23 A2 E7 16 03 27 +CD 02 23 A4 E7 16 03 27 0D 03 23 A6 E7 16 63 8D +0A 00 03 47 2C 00 A1 66 93 86 16 FC 06 07 13 77 +F7 0F 55 8F 23 A8 E7 60 B7 07 01 10 63 04 0B 18 +25 47 98 CB A2 87 63 93 0B 00 8D 47 37 07 01 10 +23 20 F7 60 63 93 09 00 0D 44 B7 07 01 10 23 A4 +87 60 89 47 63 E3 A7 16 37 37 02 50 13 07 C7 1F +1C 4B 54 4B D5 8F 95 EB 73 00 50 10 93 07 40 06 +01 00 FD 17 C2 07 C1 83 E5 FF 1C 4B 54 4B D5 8F +E5 D7 83 A6 44 1F 89 47 63 F9 D7 00 4C 4B 10 4B +31 65 13 05 45 5E EF 60 1F C1 33 69 49 01 63 1C +09 0E 83 A7 44 1F 09 47 63 9F 0A 0C 63 6B F7 18 +B7 07 01 10 03 A9 07 10 03 24 4C 00 63 19 24 1F +03 A9 47 10 03 24 8C 00 63 11 24 1F 03 A9 87 10 +03 24 CC 00 63 14 24 23 03 A9 C7 10 03 24 0C 01 +63 1C 24 21 03 A9 07 11 03 24 4C 01 63 14 89 20 +03 A9 47 11 03 24 8C 01 63 1C 89 1E 03 A9 87 11 +03 24 CC 01 63 14 89 1E 03 A9 C7 11 03 24 0C 02 +63 1C 89 1C 03 A9 07 12 03 24 4C 02 63 14 89 1C +03 A9 47 12 03 24 8C 02 63 1C 89 1A 03 A9 87 12 +03 24 CC 02 63 1D 89 12 03 A9 C7 12 03 24 0C 03 +63 15 89 12 03 A9 07 13 03 24 4C 03 63 1D 89 10 +03 A9 47 13 03 24 8C 03 63 15 89 10 03 A9 87 13 +03 24 CC 03 63 11 89 14 03 A9 C7 13 03 24 0C 04 +BD 45 63 02 89 02 83 A7 44 1F 63 9C 07 0E 05 45 +EF 60 7F AE 01 A0 63 67 F7 0A 37 07 01 10 83 27 +47 61 89 8B ED DF F2 50 62 54 D2 54 42 59 B2 59 +22 5A 92 5A 02 5B F2 4B 62 4C D2 4C 42 4D B2 4D +21 61 82 80 29 47 98 CB B5 BD 37 25 02 50 13 05 +05 0C EF 60 5F AC 37 37 02 50 13 07 C7 1F 1C 4B +54 4B D5 8F E3 8A 07 E8 6D B5 37 25 02 50 13 05 +05 2D EF 60 5F AA 03 A5 44 1F 9D B1 37 25 02 50 +13 05 85 1B EF 60 3F A9 03 A5 44 1F CD B9 83 27 +C7 60 93 F7 C7 3F 95 C3 89 47 E3 F0 A7 DA 37 25 +02 50 13 05 45 1F EF 60 1F A7 03 A5 44 1F 71 B3 +4D E9 05 45 EF 60 3F A4 01 A0 49 ED 05 45 EF 60 +9F A3 01 A0 37 25 02 50 13 05 85 29 EF 60 BF A4 +A9 B7 37 25 02 50 13 05 85 2B EF 60 DF A3 8D B5 +93 97 19 00 93 F7 E7 03 93 E7 17 00 23 24 F7 60 +0D B3 B5 45 09 BF B1 45 39 B7 AD 45 29 B7 A9 45 +19 B7 B1 69 93 89 49 5E 13 85 09 09 EF 60 BF A2 +83 A7 44 1F E3 8D 07 EE CA 85 13 85 C9 0B EF 60 +9F A1 83 A7 44 1F E3 84 07 EE A2 85 13 85 49 0D +EF 60 7F A0 E9 BD B9 45 F9 B5 85 45 E9 B5 81 45 +D9 B5 37 25 02 50 13 05 85 11 EF 60 DF 9C 03 A5 +44 1F 41 B9 37 25 02 50 13 05 45 24 EF 60 BF 9B +B1 BF 37 25 02 50 13 05 45 16 EF 60 DF 9A 91 B7 +A5 45 51 BD A1 45 41 BD 9D 45 71 B5 99 45 61 B5 +95 45 51 B5 91 45 41 B5 8D 45 B5 BD 89 45 A5 BD +79 71 4A D0 56 CA 5E C6 62 C4 66 C2 6A C0 06 D6 +22 D4 26 D2 4E CE 52 CC 5A C8 03 4B 25 00 03 CA +25 00 83 C9 06 00 3E 8C 2A 8D AE 8B 36 89 B2 8C +BA 8A B7 07 01 10 80 4F 05 88 75 DC 03 47 0D 00 +B7 34 02 50 03 A5 44 1F 55 CB 13 17 1B 00 13 77 +E7 03 13 67 17 00 23 A0 E7 60 89 47 63 E3 A7 34 +B7 07 01 10 23 A0 07 04 23 A2 07 04 23 A4 07 04 +23 A6 07 04 23 A8 07 04 23 AA 07 04 23 AC 07 04 +23 AE 07 04 23 A0 07 06 23 A2 07 06 23 A4 07 06 +23 A6 07 06 23 A8 07 06 23 AA 07 06 23 AC 07 06 +23 AE 07 06 37 07 01 10 83 27 47 60 89 8B ED DF +83 46 1D 00 85 47 63 98 F6 0A 83 27 47 60 93 F7 +C7 3F 63 83 07 32 89 47 63 EA A7 32 83 C7 0B 00 +63 9D 07 34 37 06 01 10 B7 05 FF EF 93 07 06 08 +93 85 05 F8 13 06 06 10 BE 86 91 07 33 87 B7 00 +5E 97 18 43 98 C2 E3 99 C7 FE E1 A0 89 47 63 EB +A7 2A 03 27 4D 00 B7 07 01 10 B8 C3 03 27 8D 00 +F8 C3 03 27 CD 00 B8 C7 03 27 0D 01 F8 C7 03 27 +4D 01 B8 CB 03 27 8D 01 F8 CB 03 27 CD 01 B8 CF +03 27 0D 02 F8 CF 03 27 4D 02 B8 D3 03 27 8D 02 +F8 D3 03 27 CD 02 B8 D7 03 27 0D 03 F8 D7 03 27 +4D 03 B8 DB 03 27 8D 03 F8 DB 03 27 CD 03 B8 DF +03 27 0D 04 F8 DF 83 C7 0B 00 AD D7 93 17 1A 00 +93 F7 E7 03 93 E7 17 00 37 07 01 10 23 24 F7 60 +89 47 63 FA A7 00 37 25 02 50 13 05 05 1D EF 60 +8F FF 03 A5 44 1F B7 06 01 10 93 87 06 08 93 86 +06 10 23 A0 07 00 91 07 E3 9D D7 FE 37 07 01 10 +83 27 C7 60 89 8B ED DF 83 C6 1B 00 85 47 63 84 +F6 20 03 A7 4C 00 B7 07 01 10 23 A0 E7 14 03 A7 +8C 00 23 A2 E7 14 03 A7 CC 00 23 A4 E7 14 03 A7 +0C 01 23 A6 E7 14 03 A7 4C 01 23 A8 E7 14 03 A7 +8C 01 23 AA E7 14 03 A7 CC 01 23 AC E7 14 03 A7 +0C 02 23 AE E7 14 03 A7 4C 02 23 A0 E7 16 03 A7 +8C 02 23 A2 E7 16 03 A7 CC 02 23 A4 E7 16 03 A7 +0C 03 23 A6 E7 16 63 8D 09 00 03 47 29 00 91 66 +93 86 16 FC 06 07 13 77 F7 0F 55 8F 23 A8 E7 60 +B7 07 01 10 63 8C 0A 12 25 47 98 CB A2 87 63 13 +0B 00 8D 47 37 07 01 10 23 20 F7 60 63 13 0A 00 +0D 44 B7 07 01 10 23 A4 87 60 89 47 63 EB A7 10 +37 37 02 50 13 07 C7 1F 1C 4B 54 4B D5 8F 91 EF +73 00 50 10 93 07 40 06 01 00 FD 17 C2 07 C1 83 +E5 FF 1C 4B 54 4B D5 8F E5 D7 83 A7 44 1F 09 44 +63 6B F4 00 63 8C 09 02 37 07 01 10 83 27 47 61 +89 8B ED DF 75 A0 4C 4B 10 4B 31 65 13 05 45 5E +EF 60 6F EE 83 A7 44 1F 63 94 09 0C 63 78 F4 00 +37 25 02 50 13 05 85 2B EF 60 EF EA B7 07 01 10 +03 A7 07 10 23 20 EC 00 03 A7 47 10 23 22 EC 00 +03 A7 87 10 23 24 EC 00 03 A7 C7 10 23 26 EC 00 +03 A7 07 11 23 28 EC 00 03 A7 47 11 23 2A EC 00 +03 A7 87 11 23 2C EC 00 03 A7 C7 11 23 2E EC 00 +03 A7 07 12 23 20 EC 02 03 A7 47 12 23 22 EC 02 +03 A7 87 12 23 24 EC 02 03 A7 C7 12 23 26 EC 02 +03 A7 07 13 23 28 EC 02 03 A7 47 13 23 2A EC 02 +03 A7 87 13 23 2C EC 02 83 A7 C7 13 23 2E FC 02 +B2 50 22 54 92 54 02 59 F2 49 62 4A D2 4A 42 4B +B2 4B 22 4C 92 4C 02 4D 45 61 82 80 29 47 98 CB +F1 B5 37 25 02 50 13 05 05 0C EF 60 CF DF CD B5 +E3 7C F4 F0 37 25 02 50 13 05 85 29 EF 60 AF DE +21 B7 37 25 02 50 13 05 05 2D EF 60 CF DD 03 A5 +44 1F 7D B1 37 25 02 50 13 05 85 1B EF 60 AF DC +03 A5 44 1F 3D BB 83 27 C7 60 93 F7 C7 3F 95 C3 +89 47 E3 F8 A7 DE 37 25 02 50 13 05 45 1F EF 60 +8F DA 03 A5 44 1F F1 BB 15 E9 05 45 EF 60 AF D7 +01 A0 11 ED 05 45 EF 60 0F D7 01 A0 37 25 02 50 +13 05 85 11 EF 60 2F D8 03 A5 44 1F A9 BB 37 25 +02 50 13 05 45 24 EF 60 0F D7 E9 BF 37 25 02 50 +13 05 45 16 EF 60 2F D6 C9 B7 93 17 1A 00 93 F7 +E7 03 93 E7 17 00 23 24 F7 60 B1 BB 01 11 26 CA +4A C8 4E C6 56 C2 5A C0 06 CE 22 CC 52 C4 2A 89 +AE 84 B2 8A B6 89 3A 8B B7 07 01 10 80 4F 05 88 +75 DC 37 3A 02 50 03 28 4A 1F 89 47 63 EC 07 27 +83 27 49 00 37 07 01 10 37 05 01 10 3C C3 83 26 +89 00 37 06 FF EF 93 07 07 08 74 C3 83 26 C9 00 +13 06 06 F8 93 05 05 10 34 C7 83 26 09 01 74 C7 +83 26 49 01 34 CB 83 26 89 01 74 CB 83 26 C9 01 +34 CF 83 26 09 02 74 CF 83 26 49 02 34 D3 83 26 +89 02 74 D3 83 26 C9 02 34 D7 83 26 09 03 74 D7 +83 26 49 03 34 DB 83 26 89 03 74 DB 83 26 C9 03 +34 DF 83 26 09 04 74 DF BE 86 91 07 33 87 C7 00 +26 97 18 43 98 C2 E3 99 B7 FE 83 A7 4A 00 23 20 +F5 14 83 A7 8A 00 23 22 F5 14 83 A7 CA 00 23 24 +F5 14 83 A7 0A 01 23 26 F5 14 83 A7 4A 01 23 28 +F5 14 83 A7 8A 01 23 2A F5 14 83 A7 CA 01 23 2C +F5 14 83 A7 0A 02 23 2E F5 14 83 A7 4A 02 23 20 +F5 16 83 A7 8A 02 23 22 F5 16 83 A7 CA 02 23 24 +F5 16 83 A7 0A 03 23 26 F5 16 63 0F 0B 12 E5 47 +1C C9 03 47 29 00 A2 87 11 E3 8D 47 37 07 01 10 +23 20 F7 60 83 C7 24 00 91 E3 0D 44 B7 07 01 10 +23 A4 87 60 89 47 63 E8 07 15 37 37 02 50 13 07 +C7 1F 14 4B 5C 4B D5 8F 91 EF 73 00 50 10 93 07 +40 06 01 00 FD 17 C2 07 C1 83 E5 FF 1C 4B 54 4B +D5 8F E5 D7 83 27 4A 1F 09 44 63 6C F4 0E B7 07 +01 10 83 A4 07 10 03 A4 49 00 63 1A 94 0C 83 A4 +47 10 03 A4 89 00 63 1A 94 14 83 A4 87 10 03 A4 +C9 00 63 1A 94 14 83 A4 C7 10 03 A4 09 01 63 92 +84 14 83 A4 07 11 03 A4 49 01 63 9A 84 12 83 A4 +47 11 03 A4 89 01 63 9A 84 14 83 A4 87 11 03 A4 +C9 01 63 92 84 14 83 A4 C7 11 03 A4 09 02 63 9A +84 12 83 A4 07 12 03 A4 49 02 63 92 84 12 83 A4 +47 12 03 A4 89 02 63 96 84 10 83 A4 87 12 03 A4 +C9 02 63 9C 84 0E 83 A4 C7 12 03 A4 09 03 63 9C +84 0E 83 A4 07 13 03 A4 49 03 63 92 84 10 83 A4 +47 13 03 A4 89 03 63 9C 84 0C 83 A4 87 13 03 A4 +C9 03 63 9C 84 0C 83 A4 C7 13 03 A4 09 04 BD 45 +63 90 84 02 F2 40 62 44 D2 44 42 49 B2 49 22 4A +92 4A 02 4B 05 61 82 80 E9 47 1C C9 D9 B5 81 45 +83 27 4A 1F 89 49 63 E8 F9 04 05 45 EF 60 AF AB +01 A0 4C 4B 10 4B 31 65 13 05 45 5E EF 60 AF AE +83 27 4A 1F E3 7D F4 EE 37 25 02 50 13 05 85 2B +EF 60 6F AB ED B5 37 25 02 50 13 05 05 0C EF 60 +8F AA 65 B5 37 25 02 50 13 05 85 1B EF 60 AF A9 +03 28 4A 1F B5 BB 31 69 13 09 49 5E 13 05 C9 0E +EF 60 6F AA 83 27 4A 1F E3 F1 F9 FA A6 85 13 05 +89 11 EF 60 4F A9 83 27 4A 1F E3 F8 F9 F8 A2 85 +13 05 09 13 EF 60 2F A8 49 B7 85 45 95 BF 91 45 +85 BF 8D 45 B5 B7 89 45 A5 B7 A9 45 95 B7 B5 45 +85 B7 A5 45 B1 BF AD 45 A1 BF B9 45 91 BF A1 45 +81 BF 9D 45 B1 B7 99 45 A1 B7 95 45 91 B7 B1 45 +81 B7 01 00 52 65 63 65 69 76 65 64 20 48 4D 41 +43 20 6E 6F 74 69 66 2F 65 72 72 20 69 6E 74 72 +20 77 69 74 68 20 73 74 61 74 75 73 20 3D 20 25 +64 2F 20 25 64 0A 00 00 41 74 20 6F 66 66 73 65 +74 20 5B 25 64 5D 2C 20 68 6D 61 63 5F 74 61 67 +20 64 61 74 61 20 6D 69 73 6D 61 74 63 68 21 0A +00 00 00 00 41 63 74 75 61 6C 20 20 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 45 78 70 65 +63 74 65 64 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 41 74 20 6F 66 66 73 65 74 20 5B 25 +64 5D 2C 20 68 6D 61 63 5F 74 61 67 20 64 61 74 +61 20 6D 69 73 6D 61 74 63 68 21 0A 00 00 00 00 +41 63 74 75 61 6C 20 20 20 64 61 74 61 3A 20 30 +78 25 78 0A 00 00 00 00 45 78 70 65 63 74 65 64 +20 64 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +41 74 20 6F 66 66 73 65 74 20 5B 25 64 5D 2C 20 +68 6D 61 63 5F 74 61 67 20 64 61 74 61 20 6D 69 +73 6D 61 74 63 68 21 0A 00 00 00 00 41 63 74 75 +61 6C 20 20 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 45 78 70 65 63 74 65 64 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 B7 37 02 50 +03 A7 47 1F 41 11 22 C4 06 C6 8D 47 2A 84 63 EC +E7 00 B7 67 00 04 3E 94 0A 04 91 47 B2 40 1C C0 +22 44 41 01 82 80 AA 85 35 65 13 05 45 92 EF 60 +8F 8C C5 B7 B7 37 02 50 03 A7 47 1F 41 11 22 C4 +06 C6 8D 47 2A 84 63 EA E7 00 1C 40 93 F7 C7 3F +99 EF B2 40 22 44 41 01 82 80 37 25 02 50 13 05 +85 2F EF 60 4F 87 1C 40 93 F7 C7 3F FD D3 37 25 +02 50 13 05 05 31 EF 60 0F 86 22 44 B2 40 05 45 +41 01 6F 60 4F 83 B7 37 02 50 03 A7 47 1F 41 11 +22 C4 06 C6 8D 47 2A 84 63 EA E7 00 1C 40 93 F7 +C7 3F 99 CF B2 40 22 44 41 01 82 80 37 25 02 50 +13 05 C5 31 EF 60 2F 82 1C 40 93 F7 C7 3F FD F3 +37 25 02 50 13 05 85 33 EF 60 EF 80 22 44 B2 40 +05 45 41 01 6F 50 3F FE B7 37 02 50 03 A7 47 1F +41 11 22 C4 26 C2 06 C6 8D 47 AA 84 2E 84 63 ED +E7 00 06 04 13 74 E4 03 13 64 14 00 80 C0 B2 40 +22 44 92 44 41 01 82 80 37 25 02 50 13 05 45 34 +EF 50 7F FC F9 BF B7 37 02 50 03 A7 47 1F 41 11 +22 C4 26 C2 4A C0 06 C6 8D 47 2A 89 AE 84 32 84 +63 EB E7 06 93 77 14 00 13 17 64 00 13 77 07 08 +93 95 14 00 9A 07 D9 8F 93 F5 E5 03 13 17 64 00 +13 77 07 10 93 16 64 00 CD 8F D9 8F 93 F6 06 20 +13 17 64 00 13 56 54 00 D5 8F 13 77 07 40 93 56 +64 00 05 8A D9 8F 2E 06 13 57 74 00 85 8A D1 8F +B2 06 05 8B 21 80 D5 8F 36 07 05 88 3A 04 D9 8F +B2 40 C1 8F 22 44 93 E7 17 00 23 20 F9 00 92 44 +02 49 41 01 82 80 37 25 02 50 13 05 C5 35 EF 50 +9F F2 49 B7 B7 37 02 50 03 A7 47 1F 41 11 22 C4 +06 C6 8D 47 2A 84 63 EF E7 00 06 04 13 74 E4 03 +13 64 14 04 B7 07 02 10 B2 40 23 A0 87 60 22 44 +41 01 82 80 37 25 02 50 13 05 45 37 EF 50 BF EE +E9 BF 01 00 4B 56 3A 20 63 6C 65 61 72 69 6E 67 +20 4B 56 20 65 6E 74 72 79 20 30 78 25 78 0A 00 +00 00 00 00 08 41 B7 25 02 50 41 11 93 85 C5 5D +06 C6 EF 30 B0 53 B2 40 33 35 A0 00 41 01 82 80 +B7 05 02 50 93 85 45 26 93 87 45 00 13 86 C5 20 +01 47 94 43 63 65 D5 00 D4 4B 63 69 D5 00 D1 07 +05 07 E3 98 C7 FE 13 85 85 20 82 80 93 17 27 00 +BA 97 8A 07 33 85 F5 00 82 80 01 11 22 CC 37 04 +02 50 26 CA 4A C8 4E C6 52 C4 06 CE 13 0A 44 26 +2A 89 13 04 44 26 81 44 ED 49 21 A0 85 04 63 8D +34 01 08 40 CA 85 51 04 EF 30 50 4C 65 D9 13 95 +24 00 26 95 0A 05 52 95 F2 40 62 44 D2 44 42 49 +B2 49 22 4A 05 61 82 80 5C 45 63 C0 07 04 1C 49 +63 CF 07 02 5C 49 63 CE 07 02 1C 4D 63 CD 07 02 +5C 4D 63 CC 07 02 1C 51 63 CB 07 02 5C 51 63 CA +07 02 1C 55 63 C9 07 02 5C 55 63 C8 07 02 08 59 +13 45 F5 FF 7D 81 25 05 82 80 01 45 82 80 05 45 +82 80 09 45 82 80 0D 45 82 80 11 45 82 80 15 45 +82 80 19 45 82 80 1D 45 82 80 21 45 82 80 B7 37 +02 50 0A 05 93 87 47 18 AA 97 94 43 05 47 33 17 +B7 00 55 8F 98 C3 82 80 01 11 4E C6 B7 39 02 50 +83 A7 49 1F 06 CE 22 CC 26 CA 4A C8 52 C4 56 C2 +5A C0 09 47 63 6E F7 06 37 09 02 50 B7 34 02 50 +13 09 49 26 93 84 44 18 01 44 09 4B B5 6A 6D 4A +63 62 FB 02 69 47 63 05 E4 00 09 47 63 6B F7 02 +F2 40 62 44 D2 44 42 49 B2 49 22 4A 92 4A 02 4B +05 61 82 80 90 40 83 25 09 00 13 85 CA B6 05 04 +EF 50 7F D5 83 A7 49 1F E3 09 44 FD 51 09 91 04 +C1 B7 62 44 F2 40 D2 44 42 49 B2 49 22 4A 92 4A +02 4B 37 25 02 50 13 05 45 3A 05 61 6F 50 BF D0 +37 25 02 50 13 05 45 3A EF 50 FF CF 83 A7 49 1F +A5 BF 41 11 06 C6 EF 30 70 37 B2 40 33 35 A0 00 +41 01 82 80 63 52 B0 04 01 11 22 CC 26 CA 4A C8 +4E C6 06 CE 2E 89 AA 89 2A 84 81 44 EF 30 40 77 +B3 67 25 03 18 40 11 04 85 04 8A 07 CE 97 94 43 +23 2E D4 FE 98 C3 E3 13 99 FE F2 40 62 44 D2 44 +42 49 B2 49 05 61 82 80 82 80 01 00 20 20 25 34 +30 73 3A 20 30 78 25 2D 33 78 0A 00 00 00 00 00 +01 11 4E C6 B7 39 02 50 03 A7 49 1F 22 CC 4A C8 +06 CE 26 CA 89 47 2A 89 2E 84 63 EB E7 06 B7 34 +02 50 93 84 C4 1F 9C 54 E1 8F 63 8F 87 00 73 00 +50 10 93 07 40 06 01 00 FD 17 C2 07 C1 83 E5 FF +9C 54 E1 8F E3 95 87 FE DC 54 B3 F7 27 01 E3 90 +27 FF 83 A7 49 1F 1D C0 B9 E3 D4 54 13 47 F9 FF +F2 40 75 8F D8 D4 98 54 93 47 F4 FF 62 44 F9 8F +9C D4 42 49 D2 44 B2 49 05 61 82 80 09 47 E3 7E +F7 FC CC 54 35 65 13 05 C5 0A EF 50 DF C1 F1 B7 +37 25 02 50 13 05 45 65 EF 50 FF BE 49 B7 8C 54 +35 65 13 05 05 08 EF 50 1F C0 45 BF B7 37 02 50 +03 A7 47 1F 89 47 63 E7 E7 00 B7 87 02 10 21 47 +98 CB 82 80 37 25 02 50 41 11 13 05 05 67 06 C6 +EF 50 7F BB B2 40 B7 87 02 10 21 47 98 CB 41 01 +82 80 01 11 22 CC 26 CA 4A C8 52 C4 56 C2 3E 89 +06 CE 4E C6 2E 84 B2 84 36 8A BA 8A B7 87 02 10 +98 4F 05 8B 75 DF 54 41 B7 39 02 50 09 47 23 A0 +D7 08 14 45 23 A2 D7 08 54 45 23 A4 D7 08 14 49 +23 A6 D7 08 54 49 23 A8 D7 08 14 4D 23 AA D7 08 +54 4D 23 AC D7 08 14 51 23 AE D7 08 54 51 23 A0 +D7 0A 14 55 23 A2 D7 0A 54 55 23 A4 D7 0A 14 59 +23 A6 D7 0A 54 59 23 A8 D7 0A 14 5D 23 AA D7 0A +54 5D 23 AC D7 0A 34 41 23 AE D7 0A 03 A6 49 1F +63 66 C7 0E 93 17 24 00 13 97 9A 00 13 77 07 20 +91 8B 93 16 5A 00 D9 8F 93 F6 06 1E 13 97 44 00 +41 8B D5 8F D9 8F 93 E7 17 00 37 87 02 10 1C CB +89 47 63 E4 C7 10 37 34 02 50 13 04 C4 1F 1C 54 +5C 54 85 8B 9D E3 73 00 50 10 93 07 40 06 01 00 +FD 17 C2 07 C1 83 E5 FF 1C 54 5C 54 85 8B E5 D7 +83 A7 49 1F 89 44 63 E4 F4 0A 5C 54 F9 9B 5C D4 +1C 54 1C D4 B7 87 02 10 83 A4 07 10 03 24 49 00 +63 9F 84 06 83 A4 47 10 03 24 89 00 63 93 84 10 +83 A4 87 10 03 24 C9 00 63 99 84 0E 83 A4 C7 10 +03 24 09 01 63 9D 84 0E 83 A4 07 11 03 24 49 01 +63 95 84 0E 83 A4 47 11 03 24 89 01 63 9D 84 0C +83 A4 87 11 03 24 C9 01 63 93 84 0C 83 A4 C7 11 +03 24 09 02 9D 45 63 95 84 02 F2 40 62 44 D2 44 +42 49 B2 49 22 4A 92 4A 05 61 82 80 37 25 02 50 +13 05 85 68 EF 50 3F A2 03 A6 49 1F 21 B7 81 45 +83 A7 49 1F B9 EB 05 45 EF 50 FF 9E 01 A0 4C 54 +35 65 13 05 C5 0A EF 50 1F A2 5C 54 03 A7 49 1F +F9 9B 5C D4 1C 54 1C D4 E3 F6 E4 F4 37 25 02 50 +13 05 85 69 EF 50 3F 9E 35 BF 37 25 02 50 13 05 +45 65 37 34 02 50 EF 50 1F 9D 13 04 C4 1F 1C 54 +5C 54 85 8B E3 89 07 EE 21 B7 35 69 13 09 09 08 +13 05 C9 05 EF 50 3F 9D 83 A7 49 1F C9 DF A6 85 +13 05 89 08 EF 50 3F 9C 83 A7 49 1F C9 D7 A2 85 +13 05 09 0A EF 50 3F 9B BD BF 89 45 95 BF 99 45 +85 BF 85 45 B5 B7 95 45 A5 B7 91 45 95 B7 8D 45 +85 B7 01 11 22 CC 26 CA 4A C8 4E C6 52 C4 56 C2 +06 CE 5A C0 AE 84 32 84 36 89 BA 89 3E 8A C6 8A +37 83 02 10 03 28 83 01 13 78 18 00 E3 0C 08 FE +58 41 93 87 FA FF 93 B7 17 00 23 20 E3 08 18 45 +37 3B 02 50 E1 8F 23 22 E3 08 58 45 23 24 E3 08 +18 49 23 26 E3 08 58 49 23 28 E3 08 18 4D 23 2A +E3 08 58 4D 23 2C E3 08 18 51 23 2E E3 08 58 51 +23 20 E3 0A 18 55 23 22 E3 0A 58 55 23 24 E3 0A +18 59 23 26 E3 0A 58 59 23 28 E3 0A 18 5D 23 2A +E3 0A 58 5D 23 2C E3 0A 38 41 23 2E E3 0A 83 26 +4B 1F B5 C3 89 47 63 E9 D7 08 05 45 EF 50 BF 8A +03 27 4B 1F 89 47 63 EA E7 06 06 04 26 0A 93 77 +24 00 13 7A 0A 20 96 09 B3 E7 47 01 93 F9 09 1E +12 09 B3 E7 37 01 13 79 09 01 8A 04 B3 E7 27 01 +91 88 62 44 C5 8F F2 40 D2 44 42 49 B2 49 22 4A +02 4B 93 E7 17 00 37 87 02 10 D6 85 92 4A 1C CB +01 45 05 61 F5 B6 13 87 EA FF 93 47 F4 FF 13 37 +17 00 F9 8F D1 DF 89 47 E3 F9 D7 F8 37 25 02 50 +13 05 85 72 EF 50 3F 85 49 B7 37 25 02 50 13 05 +85 68 EF 50 5F 84 51 B7 37 25 02 50 13 05 85 6B +EF 50 7F 83 9D B7 41 11 06 C6 22 C4 26 C2 37 87 +02 10 1C 4F 85 8B F5 DF B7 34 02 50 83 A7 44 1F +09 44 63 66 F4 04 37 34 02 50 13 04 C4 1F 1C 54 +5C 54 85 8B 9D E3 73 00 50 10 93 07 40 06 01 00 +FD 17 C2 07 C1 83 E5 FF 1C 54 5C 54 85 8B E5 D7 +03 A7 44 1F 89 47 63 E5 E7 04 5C 54 B2 40 92 44 +F9 9B 5C D4 1C 54 1C D4 22 44 41 01 82 80 37 25 +02 50 13 05 85 68 EF 50 0F FC 83 A7 44 1F E3 74 +F4 FA 37 25 02 50 13 05 45 65 37 34 02 50 EF 50 +8F FA 13 04 C4 1F 1C 54 5C 54 85 8B C9 DF 4D BF +4C 54 35 65 13 05 C5 0A EF 50 EF FA 7D B7 01 00 +52 65 63 65 69 76 65 64 20 53 48 41 32 35 36 20 +65 72 72 20 69 6E 74 72 20 77 69 74 68 20 73 74 +61 74 75 73 20 3D 20 25 64 0A 00 00 52 65 63 65 +69 76 65 64 20 53 48 41 32 35 36 20 6E 6F 74 69 +66 20 69 6E 74 72 20 77 69 74 68 20 73 74 61 74 +75 73 20 3D 20 25 64 0A 00 00 00 00 41 74 20 6F +66 66 73 65 74 20 5B 25 64 5D 2C 20 73 68 61 5F +64 69 67 65 73 74 20 64 61 74 61 20 6D 69 73 6D +61 74 63 68 21 0A 00 00 41 63 74 75 61 6C 20 20 +20 64 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +45 78 70 65 63 74 65 64 20 64 61 74 61 3A 20 30 +78 25 78 0A 00 00 00 00 41 11 22 C4 37 34 02 50 +03 27 44 1F 06 C6 89 47 63 E0 E7 04 37 37 02 50 +13 07 C7 1F 1C 53 54 53 D5 8F 9D E3 73 00 50 10 +93 07 40 06 01 00 FD 17 C2 07 C1 83 E5 FF 1C 53 +54 53 D5 8F E5 D7 83 26 44 1F 89 47 63 E5 D7 02 +B2 40 22 44 41 01 82 80 37 25 02 50 13 05 05 78 +EF 50 6F E7 37 37 02 50 13 07 C7 1F 1C 53 54 53 +D5 8F CD DF C9 BF 22 44 B2 40 4C 53 39 65 13 05 +05 81 41 01 6F 50 2F E7 B7 37 02 50 03 A7 47 1F +41 11 22 C4 06 C6 8D 47 2A 84 63 ED E7 00 0A 04 +31 88 13 64 14 00 B7 07 02 10 B2 40 80 CB 22 44 +41 01 82 80 AA 85 39 65 13 05 05 84 EF 50 AF E3 +F9 BF B7 37 02 50 03 A7 47 1F 41 11 22 C4 06 C6 +8D 47 2A 84 63 ED E7 00 0A 04 31 88 13 64 24 00 +B7 07 02 10 B2 40 80 CB 22 44 41 01 82 80 AA 85 +39 65 13 05 45 86 EF 50 0F E0 F9 BF B7 37 02 50 +03 A7 47 1F 41 11 22 C4 06 C6 8D 47 2A 84 63 ED +E7 00 0A 04 31 88 13 64 14 02 B7 07 02 10 B2 40 +80 CB 22 44 41 01 82 80 AA 85 39 65 13 05 85 88 +EF 50 6F DC F9 BF B7 37 02 50 03 A7 47 1F 41 11 +22 C4 06 C6 8D 47 2A 84 63 ED E7 00 0A 04 31 88 +13 64 24 02 B7 07 02 10 B2 40 80 CB 22 44 41 01 +82 80 AA 85 39 65 13 05 45 8B EF 50 CF D8 F9 BF +B7 37 02 50 03 A7 47 1F 8D 47 63 E8 E7 00 B7 07 +02 10 05 47 23 A8 E7 62 82 80 37 25 02 50 41 11 +13 05 C5 79 06 C6 EF 50 0F D4 B2 40 B7 07 02 10 +05 47 23 A8 E7 62 41 01 82 80 B7 37 02 50 03 A7 +47 1F 89 47 63 E7 E7 00 B7 07 02 10 41 47 98 CB +82 80 37 25 02 50 41 11 13 05 05 7C 06 C6 EF 50 +8F D0 B2 40 B7 07 02 10 41 47 98 CB 41 01 82 80 +01 11 22 CC 4A C8 06 CE 26 CA 4E C6 52 C4 2E 84 +32 89 B7 07 02 10 98 4F 05 8B 75 DF B7 04 02 10 +37 06 FE EF 93 87 07 08 13 06 06 F8 93 85 04 10 +BE 86 91 07 33 87 C7 00 2A 97 18 43 98 C2 E3 99 +B7 FE B7 39 02 50 83 A7 49 1F 09 4A 63 66 FA 14 +93 17 24 00 B1 8B 93 E7 17 00 9C C8 37 37 02 50 +13 07 C7 1F 1C 53 54 53 D5 8F 9D E3 73 00 50 10 +93 07 40 06 01 00 FD 17 C2 07 C1 83 E5 FF 1C 53 +54 53 D5 8F E5 D7 83 A7 49 1F 09 44 63 65 F4 0E +B7 07 02 10 83 A4 07 10 03 24 49 00 63 15 94 0C +83 A4 47 10 03 24 89 00 63 92 84 16 83 A4 87 10 +03 24 C9 00 63 9A 84 14 83 A4 C7 10 03 24 09 01 +63 9A 84 14 83 A4 07 11 03 24 49 01 63 92 84 14 +83 A4 47 11 03 24 89 01 63 96 84 14 83 A4 87 11 +03 24 C9 01 63 9A 84 14 83 A4 C7 11 03 24 09 02 +63 92 84 14 83 A4 07 12 03 24 49 02 63 9A 84 12 +83 A4 47 12 03 24 89 02 63 92 84 12 83 A4 87 12 +03 24 C9 02 63 96 84 10 83 A4 C7 12 03 24 09 03 +63 9C 84 0E 83 A4 07 13 03 24 49 03 63 98 84 10 +83 A4 47 13 03 24 89 03 63 92 84 0E 83 A4 87 13 +03 24 C9 03 63 92 84 0E 83 A4 C7 13 03 24 09 04 +BD 45 63 9B 84 00 F2 40 62 44 D2 44 42 49 B2 49 +22 4A 05 61 82 80 81 45 83 A7 49 1F B5 E7 05 45 +EF 50 6F B6 01 A0 4C 53 39 65 13 05 05 81 EF 50 +8F B9 83 A7 49 1F E3 75 F4 F0 37 25 02 50 13 05 +85 7E EF 50 4F B6 ED BD 37 25 02 50 13 05 85 7D +EF 50 6F B5 93 17 24 00 03 A7 49 1F B1 8B 93 E7 +17 00 9C C8 E3 74 EA EA 37 25 02 50 13 05 05 78 +EF 50 6F B3 37 37 02 50 13 07 C7 1F 1C 53 54 53 +D5 8F E3 8D 07 E8 45 BD 39 69 13 09 09 81 13 05 +09 0D EF 50 4F B3 83 A7 49 1F D1 D3 A6 85 13 05 +C9 0F EF 50 4F B2 83 A7 49 1F B5 DB A2 85 13 05 +49 11 EF 50 4F B1 A5 B7 89 45 B9 BF 85 45 A9 BF +91 45 99 BF 8D 45 89 BF AD 45 B9 B7 B5 45 A9 B7 +A9 45 99 B7 95 45 89 B7 B9 45 3D BF A5 45 2D BF +A1 45 1D BF 9D 45 0D BF 99 45 3D B7 B1 45 2D B7 +01 11 26 CA 4A C8 06 CE 22 CC 4E C6 52 C4 AE 84 +32 88 36 89 B7 07 02 10 98 4F 05 8B 75 DF 37 04 +02 10 37 06 FE EF 93 87 07 08 13 06 06 F8 93 05 +04 10 BE 86 91 07 33 87 C7 00 2A 97 18 43 98 C2 +E3 99 B7 FE 03 27 48 00 B7 39 02 50 09 4A 98 C3 +83 27 88 00 23 22 F4 10 83 27 C8 00 23 24 F4 10 +83 27 08 01 23 26 F4 10 83 27 48 01 23 28 F4 10 +83 27 88 01 23 2A F4 10 83 27 C8 01 23 2C F4 10 +83 27 08 02 23 2E F4 10 83 27 48 02 23 20 F4 12 +83 27 88 02 23 22 F4 12 83 27 C8 02 23 24 F4 12 +83 27 08 03 23 26 F4 12 83 27 48 03 23 28 F4 12 +83 27 88 03 23 2A F4 12 83 27 C8 03 23 2C F4 12 +83 27 08 04 23 2E F4 12 83 A7 49 1F 63 66 FA 14 +93 97 24 00 B1 8B 93 E7 27 04 1C C8 37 37 02 50 +13 07 C7 1F 1C 53 54 53 D5 8F 9D E3 73 00 50 10 +93 07 40 06 01 00 FD 17 C2 07 C1 83 E5 FF 1C 53 +54 53 D5 8F E5 D7 83 A7 49 1F 09 44 63 65 F4 0E +B7 07 02 10 83 A4 07 10 03 24 49 00 63 95 84 0C +83 A4 47 10 03 24 89 00 63 92 84 16 83 A4 87 10 +03 24 C9 00 63 9A 84 14 83 A4 C7 10 03 24 09 01 +63 9A 84 14 83 A4 07 11 03 24 49 01 63 92 84 14 +83 A4 47 11 03 24 89 01 63 96 84 14 83 A4 87 11 +03 24 C9 01 63 9A 84 14 83 A4 C7 11 03 24 09 02 +63 92 84 14 83 A4 07 12 03 24 49 02 63 9A 84 12 +83 A4 47 12 03 24 89 02 63 92 84 12 83 A4 87 12 +03 24 C9 02 63 96 84 10 83 A4 C7 12 03 24 09 03 +63 9C 84 0E 83 A4 07 13 03 24 49 03 63 98 84 10 +83 A4 47 13 03 24 89 03 63 92 84 0E 83 A4 87 13 +03 24 C9 03 63 92 84 0E 83 A4 C7 13 03 24 09 04 +BD 45 63 9B 84 00 F2 40 62 44 D2 44 42 49 B2 49 +22 4A 05 61 82 80 81 45 83 A7 49 1F B5 E7 05 45 +EF 50 6F 8A 01 A0 4C 53 39 65 13 05 05 81 EF 50 +8F 8D 83 A7 49 1F E3 75 F4 F0 37 25 02 50 13 05 +85 7E EF 50 4F 8A ED BD 37 25 02 50 13 05 85 7D +EF 50 6F 89 93 97 24 00 03 A7 49 1F B1 8B 93 E7 +27 04 1C C8 E3 74 EA EA 37 25 02 50 13 05 05 78 +EF 50 6F 87 37 37 02 50 13 07 C7 1F 1C 53 54 53 +D5 8F E3 8D 07 E8 45 BD 39 69 13 09 09 81 13 05 +C9 12 EF 50 4F 87 83 A7 49 1F D1 D3 A6 85 13 05 +89 15 EF 50 4F 86 83 A7 49 1F B5 DB A2 85 13 05 +09 17 EF 50 4F 85 A5 B7 89 45 B9 BF 85 45 A9 BF +91 45 99 BF 8D 45 89 BF AD 45 B9 B7 B5 45 A9 B7 +A9 45 99 B7 95 45 89 B7 B9 45 3D BF A5 45 2D BF +A1 45 1D BF 9D 45 0D BF 99 45 3D B7 B1 45 2D B7 +52 65 63 65 69 76 65 64 20 53 48 41 35 31 32 20 +6E 6F 74 69 66 20 69 6E 74 72 20 77 69 74 68 20 +73 74 61 74 75 73 20 3D 20 25 64 0A 00 00 00 00 +53 48 41 35 31 32 3A 20 53 65 74 20 6D 6F 64 65 +3A 20 30 78 25 78 20 61 6E 64 20 69 6E 69 74 0A +00 00 00 00 53 48 41 35 31 32 3A 20 53 65 74 20 +6D 6F 64 65 3A 20 30 78 25 78 20 61 6E 64 20 6E +65 78 74 0A 00 00 00 00 53 48 41 35 31 32 3A 20 +53 65 74 20 6D 6F 64 65 3A 20 30 78 25 78 20 61 +6E 64 20 69 6E 69 74 20 77 69 74 68 20 6C 61 73 +74 0A 00 00 53 48 41 35 31 32 3A 20 53 65 74 20 +6D 6F 64 65 3A 20 30 78 25 78 20 61 6E 64 20 6E +65 78 74 20 77 69 74 68 20 6C 61 73 74 0A 00 00 +41 74 20 6F 66 66 73 65 74 20 5B 25 64 5D 2C 20 +73 68 61 5F 64 69 67 65 73 74 20 64 61 74 61 20 +6D 69 73 6D 61 74 63 68 21 0A 00 00 41 63 74 75 +61 6C 20 20 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 45 78 70 65 63 74 65 64 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 41 74 20 6F +66 66 73 65 74 20 5B 25 64 5D 2C 20 73 68 61 5F +64 69 67 65 73 74 20 64 61 74 61 20 6D 69 73 6D +61 74 63 68 21 0A 00 00 41 63 74 75 61 6C 20 20 +20 64 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +45 78 70 65 63 74 65 64 20 64 61 74 61 3A 20 30 +78 25 78 0A 00 00 00 00 85 47 B3 95 B7 00 71 05 +1C 41 ED 8F F5 DF 82 80 41 11 06 C6 AA 86 2E 87 +B2 87 01 CD 01 CE 13 06 00 02 63 7F B6 04 B7 37 +02 50 83 A7 47 1F B1 E3 01 A0 99 C5 B7 37 02 50 +83 A7 47 1F 85 E7 01 A0 01 46 ED DB 93 05 27 00 +CC D3 85 45 23 80 B7 00 A3 80 C7 00 B2 40 13 85 +27 00 3A 86 B6 85 41 01 6F 20 80 6B 37 35 02 50 +13 05 85 80 EF 40 3F E0 F9 B7 37 35 02 50 13 05 +C5 85 EF 40 5F DF 4D BF 13 96 35 00 42 06 41 82 +93 05 00 10 63 15 B6 02 13 06 37 00 D0 D3 09 46 +23 80 C7 00 05 46 A3 80 C7 00 23 81 07 00 B2 40 +13 85 37 00 3A 86 B6 85 41 01 6F 20 60 66 13 76 +F6 0F 69 B7 41 11 06 C6 B2 87 19 C9 19 CA 11 47 +63 70 B7 02 B7 37 02 50 83 A7 47 1F B9 E3 01 A0 +99 C5 B7 37 02 50 83 A7 47 1F 8D E7 01 A0 75 DA +93 86 25 00 13 97 35 00 94 C7 85 46 23 80 D7 00 +A3 80 E7 00 B2 40 2E 86 AA 85 41 01 13 85 27 00 +6F 20 00 61 37 35 02 50 13 05 45 8A EF 40 BF D5 +F1 B7 37 35 02 50 13 05 85 8E EF 40 DF D4 45 BF +41 11 06 C6 29 C5 A1 C5 89 47 63 0A F6 08 63 ED +C7 04 51 CA 5C 4D 21 47 13 06 20 02 D8 C5 23 A2 +05 00 90 C5 85 8B 11 48 13 07 C5 01 A9 CF A2 06 +23 90 05 00 B3 E7 06 01 5C C9 5C C9 5C 49 F5 47 +1C CD 1C 43 89 8B F5 DF B2 40 41 01 82 80 B7 37 +02 50 83 A7 47 1F 91 E3 01 A0 37 35 02 50 13 05 +85 92 EF 40 5F CE CD BF 8D 47 63 14 F6 02 49 46 +41 47 21 48 5C 4D D8 C5 23 A2 05 00 90 C5 85 8B +13 07 C5 01 CD F7 B7 37 02 50 83 A7 47 1F 8D E3 +01 A0 B7 37 02 50 83 A7 47 1F 95 E3 01 A0 69 46 +31 47 19 48 C1 BF 13 06 40 02 1D 47 09 48 D9 B7 +37 35 02 50 13 05 85 99 EF 40 FF C8 D1 BF 37 35 +02 50 13 05 85 96 EF 40 1F C8 C9 BF 41 11 06 C6 +0D C5 85 C5 31 C6 85 47 63 1E F6 02 5C 4D 13 07 +20 02 98 C5 85 8B 11 46 13 07 C5 01 B1 E3 B7 37 +02 50 83 A7 47 1F AD EB 01 A0 B7 37 02 50 83 A7 +47 1F 91 E3 01 A0 37 35 02 50 13 05 C5 9C EF 40 +9F C3 CD BF B7 37 02 50 83 A7 47 1F 9D EF 01 A0 +5C 4D 13 07 A0 02 98 C5 85 8B 13 07 C5 01 E1 D3 +93 97 86 00 D1 8F 23 90 05 00 23 A6 05 00 23 A2 +05 00 93 E7 07 02 5C C9 5C C9 F5 47 1C CD 1C 43 +89 8B F5 DF B2 40 41 01 82 80 37 35 02 50 13 05 +85 A1 EF 40 5F BE 65 BF 37 35 02 50 13 05 C5 A4 +EF 40 7F BD 51 B7 5D 71 86 C6 A2 C4 A6 C2 CA C0 +15 CD 8D CD 2A 84 B1 CE 03 D8 06 00 05 45 63 0A +A8 04 25 CE 05 45 63 10 A6 04 13 08 20 02 11 46 +48 4C 23 A4 05 01 93 04 C4 01 05 89 35 E1 B7 37 +02 50 83 A7 47 1F 63 95 07 10 01 A0 B7 37 02 50 +83 A7 47 1F 91 E3 01 A0 37 35 02 50 13 05 05 A8 +EF 40 7F B7 CD BF B7 37 02 50 83 A7 47 1F F1 EB +01 A0 11 C7 03 58 07 00 05 45 E3 14 A8 FA 63 06 +06 10 05 47 63 19 E6 0A BE 86 05 46 22 85 26 44 +B6 40 96 44 06 49 61 61 D1 B5 13 08 A0 02 49 BF +A2 07 D1 8F 23 90 05 00 23 A6 05 00 23 A2 05 00 +93 E7 07 03 5C C8 5C C8 02 CA 02 CC 02 CE 02 D0 +02 D2 02 D4 02 D6 02 D8 02 DA 02 DC 02 DE 91 C6 +03 A9 86 00 89 47 63 E8 27 09 85 47 23 1A F1 00 +13 05 61 01 19 C3 50 53 3D EA 85 47 23 00 F5 00 +A3 00 05 00 D2 47 1C D0 E2 47 5C D0 F2 47 1C D4 +82 57 5C D4 92 57 1C D8 A2 57 5C D8 B2 57 1C DC +C2 57 5C DC D2 57 3C C0 E2 57 7C C0 F2 57 3C C4 +F5 47 1C CC 9C 40 89 8B F5 DF B6 40 26 44 96 44 +06 49 61 61 82 80 B7 37 02 50 83 A7 47 1F 9D EF +01 A0 37 35 02 50 13 05 C5 B0 EF 40 DF A8 0D B7 +37 35 02 50 13 05 85 B4 EF 40 FF A7 FD B5 BA 85 +EF 20 00 32 41 BF 4A 86 B6 85 48 08 3A C6 EF 20 +20 31 5C 08 32 47 33 85 27 01 AD B7 37 35 02 50 +13 05 45 AC EF 40 3F A5 65 BF BE 86 01 46 FD BD +41 11 06 C6 19 C3 23 20 07 00 4D C1 C5 C1 51 CE +9C 45 D5 CB 5C 4D 13 03 C5 01 89 8B E5 C3 29 4F +B7 18 04 10 85 4E 8D 4F B5 CE 03 28 03 00 13 58 +88 00 13 78 F8 01 33 08 0F 41 0E 08 63 F3 06 01 +36 88 63 0B 08 04 93 77 16 00 C1 E7 B2 87 42 8E +63 00 D8 05 93 F5 37 00 C1 E9 3E 85 63 F1 CF 03 +13 05 CE FF 71 99 11 05 3E 95 8C 43 91 07 23 A0 +B8 80 E3 9C A7 FE 13 7E 3E 00 63 F5 CE 0B 83 55 +05 00 79 1E 93 07 25 00 23 90 B8 80 63 06 0E 00 +83 C7 07 00 23 80 F8 80 42 96 B3 86 06 41 49 D7 +23 20 07 01 B2 40 41 01 82 80 BD D2 B7 37 02 50 +83 A7 47 1F 91 E3 01 A0 37 35 02 50 13 05 45 B8 +EF 40 7F 98 CD BF B7 37 02 50 83 A7 47 1F 8D EF +01 A0 83 45 06 00 13 0E F8 FF 93 07 16 00 23 80 +B8 80 E3 E9 CE F7 5D B7 83 D5 07 00 79 1E 89 07 +23 90 B8 80 E3 E6 CF F7 3E 85 41 B7 B7 37 02 50 +83 A7 47 1F 89 EB 01 A0 37 35 02 50 13 05 05 BC +EF 40 7F 93 75 BF 37 35 02 50 13 05 45 BF EF 40 +9F 92 D5 B7 AA 87 9D B7 41 11 06 C6 22 C4 61 C5 +F9 C1 69 C2 19 C3 23 20 07 00 03 C8 05 00 63 1A +08 08 03 C8 15 00 63 0F 08 06 83 A8 C5 00 13 03 +F0 0F 05 48 96 08 63 7F 13 05 41 68 33 B8 08 01 +37 03 00 01 13 48 18 00 33 B3 68 00 13 43 13 00 +09 08 1A 98 13 03 F8 FF 0E 03 B3 DE 68 00 93 FE +FE 0F 37 1E 04 10 23 00 DE 81 61 13 9D 4E 63 D1 +6E 02 33 D3 68 00 13 73 F3 0F 23 00 6E 80 11 43 +63 18 68 00 13 D3 88 00 13 73 F3 0F 23 00 6E 80 +13 78 F8 0F 37 13 04 10 93 F8 F8 0F 23 00 13 81 +23 00 03 81 05 48 23 80 05 01 13 08 E0 02 23 2C +05 01 03 A8 C5 00 63 0D 08 02 83 A8 45 00 B3 08 +18 41 63 F7 D8 02 B7 37 02 50 83 A7 47 1F 63 99 +07 14 01 A0 A1 D2 B7 37 02 50 83 A7 47 1F 91 E3 +01 A0 37 35 02 50 13 05 85 C2 EF 40 DF 83 CD BF +E1 C2 83 A8 85 00 93 02 C5 01 93 03 10 03 C0 41 +B3 8E 88 40 63 10 08 02 63 F3 D6 01 B6 8E 63 90 +0E 04 23 2C 75 00 23 A2 05 00 C0 41 B3 8E 88 40 +E3 04 08 FE 63 6E 18 01 63 ED D6 09 63 91 0E 02 +63 94 08 09 B7 37 02 50 83 A7 47 1F F9 EB 01 A0 +B3 0E 88 40 63 F3 D6 01 B6 8E E3 85 0E FE 03 A8 +02 00 13 78 48 00 E3 0C 08 FE B7 0F 01 04 93 8F +0F 10 A2 9F 8A 0F 7E 88 01 4E 03 2F 08 00 03 23 +08 10 B3 08 F8 41 B2 98 33 43 E3 01 23 A0 68 00 +05 0E 11 08 E3 13 DE FF 72 94 13 18 2E 00 C0 C1 +42 96 B3 86 C6 41 11 C7 03 28 07 00 72 98 23 20 +07 01 95 E3 91 C6 03 A8 C5 00 83 A8 85 00 81 BF +B2 40 22 44 41 01 82 80 33 08 18 41 23 A6 05 01 +89 BF B6 8E A5 B7 83 A8 85 00 B7 0E 01 04 93 8E +0E 10 C6 9E 13 08 20 03 8A 0E B3 0F 18 41 E3 83 +08 FD 76 88 01 4E 03 2F 08 00 03 23 08 10 B3 08 +D8 41 BE 98 33 43 E3 01 23 A0 68 00 05 0E 11 08 +E3 63 FE FF 11 48 63 84 0F 00 13 98 2F 00 C2 97 +51 BF 37 35 02 50 13 05 05 CB EF 40 CF F0 05 B7 +37 35 02 50 13 05 C5 C5 EF 40 EF EF 5D B5 41 11 +06 C6 1D C5 95 C5 83 C7 05 00 A1 C3 13 07 C5 01 +1C 43 91 8B F5 DF B2 40 D9 47 1C CD 23 90 05 00 +23 A2 05 00 23 A4 05 00 23 A6 05 00 41 01 82 80 +B7 37 02 50 83 A7 47 1F 91 E3 01 A0 37 35 02 50 +13 05 85 CE EF 40 2F EB CD BF B7 37 02 50 83 A7 +47 1F 91 E3 01 A0 37 35 02 50 13 05 85 D1 EF 40 +8F E9 CD BF B7 07 02 30 C8 4B 82 80 B7 07 04 30 +3E 95 08 41 82 80 B7 07 04 30 AA 97 8C C3 82 80 +B7 37 02 50 03 A7 47 1F 8D 47 63 E8 E7 00 37 07 +02 30 1C 4F F9 9B 1C CF 82 80 41 65 41 11 13 05 +45 9B 06 C6 EF 40 2F E7 37 07 02 30 1C 4F B2 40 +F9 9B 1C CF 41 01 82 80 41 11 22 C4 37 34 02 50 +83 27 44 1F 26 C2 06 C6 91 44 63 EF F4 02 B7 07 +02 30 CC 4F 99 47 99 81 9D 89 63 8F F5 04 B9 CD +9D 47 63 97 F5 00 83 27 44 1F A5 EF 3D 45 01 A8 +41 65 13 05 05 9D EF 40 0F E2 13 05 F0 0F B2 40 +22 44 92 44 41 01 82 80 37 35 02 50 13 05 05 D5 +EF 40 6F DE B7 07 02 30 CC 4F 99 47 99 81 9D 89 +E3 9F F5 FA 83 27 44 1F 63 F8 F4 00 37 35 02 50 +13 05 85 D7 EF 40 2F DC 01 45 D1 B7 03 27 44 1F +85 47 63 E8 E7 00 05 45 B2 40 22 44 92 44 41 01 +82 80 37 35 02 50 13 05 85 DB EF 40 CF D9 05 45 +E5 B7 37 35 02 50 13 05 05 DF EF 40 CF D8 3D 45 +79 B7 B7 37 02 50 03 A7 47 1F 41 11 22 C4 06 C6 +8D 47 2A 84 63 EC E7 00 37 07 02 30 5C 4F B2 40 +C1 9B C1 8F 22 44 5C CF 41 01 82 80 AA 85 41 65 +13 05 45 A1 EF 40 2F D7 C5 B7 B7 37 02 50 03 A7 +47 1F 41 11 22 C4 06 C6 8D 47 2A 84 63 E6 E7 02 +B7 07 03 30 D8 5F 93 17 84 00 B3 66 E4 00 91 C7 +B7 07 00 FF 7D 8F B3 66 87 00 B2 40 22 44 B7 07 +03 30 D4 DF 41 01 82 80 AA 85 41 65 13 05 C5 A3 +EF 40 6F D2 F1 B7 B7 37 02 50 03 A7 47 1F 41 11 +22 C4 06 C6 26 C2 8D 47 2A 84 63 EC E7 04 B7 17 +02 30 84 43 85 47 63 ED 87 02 63 E2 97 02 93 77 +14 00 33 67 94 00 81 C7 F9 98 33 E7 84 00 B2 40 +22 44 B7 17 02 30 98 C3 92 44 41 01 82 80 41 65 +13 05 C5 AB EF 40 2F CD 05 45 EF 40 CF C8 C1 BF +41 65 13 05 05 AA EF 40 0F CC 05 45 EF 40 AF C7 +7D BF AA 85 41 65 13 05 45 A6 EF 40 CF CA 45 B7 +B7 37 02 50 03 A7 47 1F 41 11 22 C4 06 C6 8D 47 +2A 84 63 E0 E7 04 B7 07 03 30 DC 5F 13 17 84 00 +19 CF 37 07 00 FF 79 8C 13 44 F4 FF 7D 8C 79 8C +B7 07 03 30 B2 40 C0 DF 22 44 41 01 82 80 13 44 +F4 FF 7D 8C B7 07 03 30 B2 40 C0 DF 22 44 41 01 +82 80 AA 85 41 65 13 05 85 AD EF 40 CF C4 65 BF +09 CD 01 47 B7 06 02 30 19 A0 63 08 E5 00 9C 42 +05 07 85 8B FD FB 01 45 82 80 05 45 82 80 79 71 +4E CE B7 39 02 50 22 D4 83 A7 49 1F 37 04 02 30 +26 D2 04 44 4A D0 06 D6 52 CC 0D 49 63 6D F9 00 +40 44 B2 50 22 85 22 54 02 59 F2 49 62 4A A6 85 +92 54 45 61 82 80 41 6A 13 0A 4A 9B A6 85 13 05 +CA 14 EF 40 4F BE 83 A7 49 1F 40 44 E3 7B F9 FC +A2 85 13 05 0A 17 EF 40 0F BD E1 B7 79 71 4A D0 +37 39 02 50 03 27 49 1F 22 D4 26 D2 06 D6 4E CE +52 CC 2A C4 2E C6 89 47 2A 84 AE 84 63 E9 E7 14 +B7 07 04 00 63 EB 87 12 B7 C7 5E BA 93 87 17 A1 +63 82 F4 02 B7 D7 BE BA 93 87 E7 AF 63 80 F4 14 +41 65 A6 85 13 05 C5 B7 EF 40 EF B7 05 45 EF 40 +8F B3 01 A0 B7 04 00 50 37 0A 00 40 37 07 02 30 +50 4B 75 C2 13 07 06 02 63 6F E4 0C 13 77 36 00 +11 C3 11 06 37 07 02 30 4C 4B 03 25 49 1F 89 46 +23 20 BA 00 03 28 47 01 93 59 26 00 23 20 0A 01 +58 4B 23 20 EA 00 63 E5 A6 10 93 96 29 00 D2 87 +D2 96 37 05 02 30 63 88 09 00 58 49 91 07 23 AE +E7 FE E3 9C D7 FE B7 07 02 30 D8 4B 69 C7 93 77 +C6 FF 93 06 07 02 B6 97 63 6F F4 0A 93 77 37 00 +91 C3 11 07 B7 07 02 30 D0 4B 83 25 49 1F 13 54 +27 00 90 C0 D0 4B 89 46 90 C0 D8 4B 98 C0 63 E2 +B6 0C 63 0A 04 0C 13 17 24 00 A6 87 26 97 37 06 +02 30 54 4A 91 07 23 AE D7 FE E3 1C F7 FE B7 07 +02 30 23 A6 07 00 8D 47 63 F8 B7 00 41 65 89 45 +13 05 45 A1 EF 40 2F AA 37 07 02 30 5C 4F B2 50 +22 54 C1 9B 93 E7 27 00 5C CF 92 54 02 59 F2 49 +62 4A 45 61 82 80 41 65 A2 85 13 05 05 BB EF 40 +8F A7 05 45 EF 40 2F A3 01 A0 41 65 A2 85 13 05 +85 B4 EF 40 4F A6 05 45 EF 40 EF A1 01 A0 37 35 +02 50 13 05 85 E4 EF 40 0F A3 5D B5 B7 04 02 50 +37 0A 02 40 E1 BD 01 14 41 65 3A 86 B3 05 34 41 +13 05 C5 C0 EF 40 2F A3 05 45 EF 40 CF 9E 01 A0 +37 35 02 50 13 05 85 E6 32 C2 EF 40 CF 9F 12 46 +ED B5 37 35 02 50 13 05 C5 E7 EF 40 CF 9E 83 25 +49 1F 15 F8 A9 B7 23 A6 07 00 B9 BF 79 71 4E CE +B7 39 02 50 03 A7 49 1F 4A D0 06 D6 22 D4 26 D2 +52 CC 56 CA 5A C8 2A C4 2E C6 8D 47 2A 89 63 E6 +E7 04 01 44 B7 04 00 40 63 77 A4 02 B7 07 02 30 +D8 4B 11 04 93 87 44 00 98 C0 B3 05 F4 40 37 06 +02 30 63 7A 24 01 54 4A 91 07 33 87 B7 00 23 AE +D7 FE E3 6A 27 FF B2 50 22 54 92 54 02 59 F2 49 +62 4A D2 4A 42 4B 45 61 82 80 37 35 02 50 01 44 +13 05 05 E9 EF 40 2F 96 E3 7F 24 FD C1 6A B7 04 +00 40 0D 4B 93 8A 8A C6 37 0A 02 30 11 A0 BA 84 +83 A7 49 1F A6 85 56 85 E3 7A FB F8 90 40 11 04 +EF 40 6F 95 83 27 4A 01 13 87 44 00 9C C0 E3 60 +24 FF 55 B7 41 11 26 C2 4A C0 06 C6 22 C4 B7 07 +04 00 2A 89 AE 84 63 E0 A7 06 D5 C4 81 47 37 07 +02 30 19 A0 63 83 F4 06 00 43 85 07 05 88 7D F8 +B7 17 03 30 03 A6 87 80 13 77 D6 FE 23 A4 E7 80 +63 0C 09 00 81 47 B7 06 04 30 33 87 D7 00 23 20 +07 00 91 07 E3 EB 27 FF B2 40 22 44 B7 07 02 30 +05 47 98 D3 B7 17 03 30 23 A4 C7 80 92 44 02 49 +01 45 41 01 82 80 AA 85 41 65 13 05 45 C7 EF 40 +8F 8C 05 45 EF 40 2F 88 49 BF B7 37 02 50 03 A7 +47 1F 85 47 63 F8 E7 00 37 35 02 50 13 05 45 EB +EF 40 6F 88 85 47 E3 85 F4 F8 37 07 02 30 13 06 +07 02 85 46 19 A0 E3 8D 84 F6 14 C2 1C 43 05 04 +85 8B F5 FB B5 B7 B7 37 02 50 03 A7 47 1F 85 47 +E3 F0 E7 F6 37 35 02 50 13 05 45 EB EF 40 AF 84 +81 BF B7 37 02 50 03 A7 47 1F 41 11 22 C4 06 C6 +8D 47 2A 84 63 FB E7 04 95 47 63 FC A7 02 37 36 +02 50 AA 85 41 65 13 06 06 F0 13 05 85 C9 EF 40 +8F 83 B7 07 03 30 23 A4 87 62 37 07 03 30 83 27 +47 62 B2 40 22 44 93 E7 17 00 23 22 F7 62 41 01 +82 80 29 C1 AA 85 37 36 02 50 41 65 13 06 C6 EE +13 05 85 C9 EF 40 2F 80 29 A0 61 D9 95 47 E3 E2 +A7 FC B7 07 03 30 15 47 23 A4 E7 62 37 07 03 30 +83 27 47 62 B2 40 22 44 93 E7 17 00 23 22 F7 62 +41 01 82 80 37 36 02 50 41 65 13 06 C6 ED 81 45 +13 05 85 C9 EF 30 3F FC 37 07 03 30 83 27 47 62 +B2 40 22 44 93 E7 17 00 23 22 F7 62 41 01 82 80 +B7 07 03 30 05 47 23 A0 E7 62 82 80 37 17 02 30 +1C 43 85 8B F5 FF 82 80 0D 89 13 65 45 00 B7 17 +02 30 88 C7 82 80 B7 17 02 30 05 47 98 CF 82 80 +B7 17 02 30 DC 4F 85 8B 89 EB B7 06 04 30 37 17 +02 30 9C 42 5C 4F 85 8B ED DF 82 80 B7 17 02 30 +05 47 98 C3 82 80 B7 28 02 30 03 A8 C8 00 13 78 +18 00 E3 1C 08 FE 23 AE A8 00 23 A0 B8 02 23 A2 +E8 02 23 A4 F8 02 41 C6 B7 07 00 12 85 07 37 26 +02 30 1C C6 50 42 85 65 FD 15 6D 8E 13 75 C7 FF +93 57 27 00 42 06 41 82 36 95 37 27 02 30 99 CB +5C 47 91 83 ED 8F E3 8D C7 FE 9C 42 91 06 5C D7 +E3 98 A6 FE B7 27 02 30 DC 47 05 47 37 26 02 30 +93 F5 37 00 85 46 63 97 E5 00 5C 46 13 F7 37 00 +E3 0D D7 FE 89 8B 85 CB B7 37 02 50 03 A7 47 1F +41 11 06 C6 89 47 63 E1 E7 02 B7 27 02 30 09 47 +98 C7 05 45 EF 30 3F E7 B2 40 41 01 82 80 B7 07 +00 02 85 07 AD BF 82 80 37 35 02 50 13 05 05 F1 +EF 30 7F E7 D9 BF 41 11 06 C6 37 23 02 30 83 28 +C3 00 93 F8 18 00 E3 9C 08 FE 23 2E A3 00 23 20 +B3 02 23 22 E3 02 23 24 F3 02 49 C2 B7 07 00 12 +85 07 37 26 02 30 1C C6 50 42 85 65 FD 15 6D 8E +13 75 C7 FF 93 57 27 00 42 06 41 82 36 95 37 27 +02 30 99 CB 5C 47 91 83 ED 8F E3 8D C7 FE 9C 42 +91 06 5C D7 E3 98 A6 FE B7 27 02 30 DC 47 05 47 +37 26 02 30 93 F5 37 00 85 46 63 97 E5 00 5C 46 +13 F7 37 00 E3 0D D7 FE 89 8B 8D C7 63 06 08 04 +B7 37 02 50 03 A7 47 1F 89 47 63 E4 E7 04 B7 27 +02 30 09 47 98 C7 B2 40 41 01 82 80 B7 07 00 02 +85 07 41 B7 E3 09 08 FE 37 35 02 50 13 05 05 F8 +EF 30 7F DB B7 27 02 30 09 47 98 C7 05 45 EF 30 +9F D8 B2 40 41 01 82 80 37 35 02 50 13 05 05 F4 +C5 B7 37 35 02 50 13 05 05 F4 EF 30 DF D8 45 BF +37 28 02 30 83 26 C8 00 85 8A ED FE 23 2E A8 00 +23 20 B8 02 23 22 E8 02 23 24 F8 02 01 CA B7 07 +00 12 85 07 37 27 02 30 1C C7 82 80 B7 07 00 02 +85 07 37 27 02 30 1C C7 82 80 B7 27 02 30 DC 43 +05 66 7D 16 F1 8F 13 F7 C5 FF 13 D8 25 00 93 96 +07 01 B3 05 E5 00 C1 82 37 27 02 30 63 0C 08 00 +5C 47 91 83 F1 8F E3 8D D7 FE 1C 41 11 05 5C D7 +E3 98 A5 FE 01 45 82 80 B7 28 02 30 03 A8 C8 00 +13 78 18 00 E3 1C 08 FE 23 AA A8 00 23 AC B8 00 +23 A2 E8 02 23 A4 F8 02 41 C2 B7 07 12 00 85 07 +37 26 02 30 1C C6 5C 42 09 83 15 C3 0A 07 05 66 +B3 85 E6 00 7D 16 37 27 02 30 5C 47 91 83 F1 8F +ED DF 1C 5B 91 06 23 AE F6 FE E3 98 B6 FE B7 27 +02 30 DC 47 05 47 93 F6 37 00 63 9A E6 00 37 26 +02 30 85 46 5C 46 13 F7 37 00 E3 0D D7 FE 89 8B +85 CB B7 37 02 50 03 A7 47 1F 41 11 06 C6 89 47 +63 E1 E7 02 B7 27 02 30 09 47 98 C7 05 45 EF 30 +9F C5 B2 40 41 01 82 80 B7 07 02 00 85 07 49 B7 +82 80 37 35 02 50 13 05 05 F1 EF 30 DF C5 D9 BF +41 11 06 C6 37 23 02 30 83 28 C3 00 93 F8 18 00 +E3 9C 08 FE 23 2A A3 00 23 2C B3 00 23 22 E3 02 +23 24 F3 02 2D CE B7 07 12 00 85 07 37 26 02 30 +1C C6 5C 42 09 83 15 C3 0A 07 05 66 B3 85 E6 00 +7D 16 37 27 02 30 5C 47 91 83 F1 8F ED DF 1C 5B +91 06 23 AE F6 FE E3 98 B6 FE B7 27 02 30 DC 47 +05 47 93 F6 37 00 63 9A E6 00 37 26 02 30 85 46 +5C 46 13 F7 37 00 E3 0D D7 FE 89 8B 8D C7 63 06 +08 04 B7 37 02 50 03 A7 47 1F 89 47 63 E4 E7 04 +B7 27 02 30 09 47 98 C7 B2 40 41 01 82 80 B7 07 +02 00 85 07 61 B7 E3 09 08 FE 37 35 02 50 13 05 +05 F8 EF 30 5F BA B7 27 02 30 09 47 98 C7 05 45 +EF 30 7F B7 B2 40 41 01 82 80 37 35 02 50 13 05 +05 F4 C5 B7 37 35 02 50 13 05 05 F4 EF 30 BF B7 +45 BF 37 28 02 30 83 26 C8 00 85 8A ED FE 23 2A +A8 00 23 2C B8 00 23 22 E8 02 23 24 F8 02 01 CA +B7 07 12 00 85 07 37 27 02 30 1C C7 82 80 B7 07 +02 00 85 07 37 27 02 30 1C C7 82 80 B7 27 02 30 +DC 43 93 D7 25 00 95 C3 8A 07 85 66 33 06 F5 00 +37 27 02 30 FD 16 5C 47 91 83 F5 8F ED DF 1C 5B +11 05 23 2E F5 FE E3 18 C5 FE 82 80 B7 08 02 30 +83 A8 08 00 41 11 06 C6 93 F8 18 00 63 8B 08 00 +B7 37 02 50 83 A7 47 1F A1 E3 B2 40 05 45 41 01 +82 80 91 C9 B7 37 02 50 83 A7 47 1F D1 EF 05 45 +EF 30 7F AB 01 A0 B7 05 04 00 E3 75 B5 FE B3 88 +A7 00 63 F2 F8 02 37 37 02 50 03 27 47 1F 41 EB +05 45 EF 30 5F A9 01 A0 37 35 02 50 13 05 85 FC +EF 30 7F AA 5D BF E3 F0 B8 FE B7 25 02 30 83 A8 +C5 00 93 F8 18 00 E3 9C 08 FE C8 C9 23 AC 05 00 +D0 CD 94 D1 DC D1 23 A4 05 03 31 C7 B7 07 00 11 +85 07 37 27 02 30 1C C7 5C 47 05 47 93 F6 37 00 +63 9A E6 00 37 26 02 30 85 46 5C 46 13 F7 37 00 +E3 0D D7 FE 89 8B 85 EF B2 40 B7 07 02 30 05 47 +98 D3 01 45 41 01 82 80 AA 85 41 65 13 05 45 CD +EF 30 7F A5 A9 BF B7 07 00 01 85 07 5D BF 2A 86 +41 65 BE 85 13 05 45 D0 EF 30 FF A3 95 B7 37 35 +02 50 13 05 45 FE EF 30 1F A1 B7 27 02 30 09 47 +98 C7 05 45 EF 30 3F 9E 45 BF B7 08 02 30 83 A8 +08 00 41 11 06 C6 93 F8 18 00 63 8B 08 00 B7 37 +02 50 83 A7 47 1F A1 E3 B2 40 05 45 41 01 82 80 +91 CA B7 37 02 50 83 A7 47 1F A5 EF 05 45 EF 30 +9F 9A 01 A0 B7 06 04 00 E3 75 D6 FE B3 88 C7 00 +63 F2 F8 02 37 37 02 50 03 27 47 1F 2D E7 05 45 +EF 30 7F 98 01 A0 37 35 02 50 13 05 85 FC EF 30 +9F 99 5D BF E3 F0 D8 FE B7 28 02 30 83 A6 C8 00 +85 8A ED FE 23 AA A8 00 23 AC B8 00 23 AE C8 00 +23 A0 08 02 23 A2 F8 02 23 A4 08 03 15 C3 B7 07 +11 00 85 07 B2 40 37 27 02 30 1C C7 01 45 41 01 +82 80 41 65 B2 85 13 05 05 D5 EF 30 DF 96 BD BF +C1 67 85 07 C5 B7 41 65 BE 85 13 05 05 D8 EF 30 +9F 95 71 B7 41 11 06 C6 0D 3F B7 27 02 30 DC 47 +05 47 93 F6 37 00 63 9A E6 00 37 26 02 30 85 46 +5C 46 13 F7 37 00 E3 0D D7 FE 89 8B 99 CF B7 37 +02 50 03 A7 47 1F 89 47 63 E0 E7 02 B7 27 02 30 +09 47 98 C7 05 45 EF 30 1F 8D B2 40 B7 07 02 30 +05 47 98 D3 41 01 82 80 37 35 02 50 13 05 05 F1 +EF 30 7F 8D E1 BF 01 11 4E C6 B7 39 02 50 03 A7 +49 1F 22 CC 26 CA 4A C8 06 CE 89 47 2A 89 AE 84 +32 84 63 E0 E7 0A B7 36 02 30 83 A7 86 80 37 27 +02 30 F9 9B 23 A4 F6 80 5C 47 85 8B F5 FF 23 2E +27 01 04 D3 B7 07 00 04 40 D3 85 07 1C C7 5C 47 +05 47 93 F6 37 00 63 9A E6 00 37 26 02 30 85 46 +5C 46 13 F7 37 00 E3 0D D7 FE 89 8B A9 C3 03 A7 +49 1F 89 47 63 E6 E7 02 B7 27 02 30 09 47 98 C7 +37 37 02 30 83 27 87 80 F2 40 62 44 93 E7 17 00 +23 24 F7 80 D2 44 42 49 B2 49 01 45 05 61 82 80 +37 35 02 50 13 05 05 04 EF 30 FF 82 F1 B7 37 35 +02 50 13 05 45 07 EF 30 1F 82 05 45 EF 30 AF FF +01 A0 37 35 02 50 13 05 05 02 EF 30 DF 80 A1 BF +01 11 4E C6 B7 39 02 50 03 A7 49 1F 22 CC 26 CA +4A C8 06 CE 89 47 2A 89 AE 84 32 84 63 E2 E7 06 +37 27 02 30 5C 47 85 8B F5 FF 23 2E 27 01 04 D3 +B7 07 00 04 40 D3 85 07 1C C7 5C 47 05 47 93 F6 +37 00 63 9A E6 00 37 26 02 30 85 46 5C 46 13 F7 +37 00 E3 0D D7 FE 89 8B 89 CF 03 A7 49 1F 89 47 +63 E7 E7 02 B7 27 02 30 09 47 98 C7 05 45 EF 30 +8F F7 F2 40 62 44 D2 44 42 49 B2 49 05 61 82 80 +37 35 02 50 13 05 45 0B EF 30 EF F7 51 BF 37 35 +02 50 13 05 05 F1 EF 30 0F F7 E9 B7 37 27 02 30 +5C 47 85 8B F5 FF 48 CF 0C D3 B7 07 00 04 50 D3 +85 07 1C C7 82 80 41 11 83 4E 01 01 06 C6 37 2E +02 30 03 23 CE 00 13 73 13 00 E3 1C 03 FE 23 2A +AE 00 23 2C BE 00 23 2E DE 00 23 20 EE 02 23 22 +0E 03 23 24 1E 03 B7 06 03 03 63 83 0E 06 95 06 +03 47 41 01 B3 37 F0 00 F2 07 33 37 E0 00 0E 07 +33 36 C0 00 D9 8F 52 06 D1 8F 37 27 02 30 D5 8F +1C C7 5C 47 05 47 93 F6 37 00 63 9A E6 00 37 26 +02 30 85 46 5C 46 13 F7 37 00 E3 0D D7 FE 89 8B +A1 C3 B7 37 02 50 03 A7 47 1F 89 47 63 EC E7 00 +B2 40 B7 27 02 30 09 47 98 C7 01 45 41 01 82 80 +85 06 79 BF 37 35 02 50 13 05 05 04 EF 30 AF EA +B2 40 B7 27 02 30 09 47 98 C7 01 45 41 01 82 80 +37 35 02 50 13 05 45 07 EF 30 EF E8 05 45 EF 30 +8F E6 01 A0 41 11 83 4E 01 01 06 C6 37 2E 02 30 +03 23 CE 00 13 73 13 00 E3 1C 03 FE 23 2A AE 00 +23 2C BE 00 23 2E DE 00 23 20 EE 02 23 22 0E 03 +23 24 1E 03 B7 06 03 03 63 85 0E 06 95 06 03 47 +41 01 B3 37 F0 00 F2 07 33 37 E0 00 0E 07 33 36 +C0 00 D9 8F 52 06 D1 8F 37 27 02 30 D5 8F 1C C7 +5C 47 05 47 93 F6 37 00 63 9A E6 00 37 26 02 30 +85 46 5C 46 13 F7 37 00 E3 0D D7 FE 89 8B 99 CF +B7 37 02 50 03 A7 47 1F 89 47 63 EE E7 00 B7 27 +02 30 09 47 98 C7 05 45 EF 30 EF DC B2 40 41 01 +82 80 85 06 69 BF 37 35 02 50 13 05 05 F1 EF 30 +8F DD F1 BF 41 11 03 4F 01 01 83 4E 81 01 06 C6 +37 2E 02 30 03 23 CE 00 13 73 13 00 E3 1C 03 FE +23 2A AE 00 23 2C BE 00 23 2E DE 00 23 20 EE 02 +23 22 0E 03 23 24 1E 03 B7 06 03 03 63 04 0F 06 +95 06 03 47 41 01 B3 37 F0 00 F2 07 33 37 E0 00 +0E 07 33 36 C0 00 D9 8F 52 06 D1 8F 37 27 02 30 +D5 8F 1C C7 5C 47 05 47 93 F6 37 00 63 9A E6 00 +37 26 02 30 85 46 5C 46 13 F7 37 00 E3 0D D7 FE +89 8B 9D C3 63 84 0E 04 B7 37 02 50 03 A7 47 1F +89 47 63 E2 E7 04 B7 27 02 30 09 47 98 C7 B2 40 +41 01 82 80 85 06 71 BF E3 8B 0E FE 37 35 02 50 +13 05 05 F8 EF 30 2F D2 B7 27 02 30 09 47 98 C7 +05 45 EF 30 4F CF B2 40 41 01 82 80 37 35 02 50 +13 05 05 F4 C5 B7 37 35 02 50 13 05 05 F4 EF 30 +8F CF 55 BF 83 4E 01 00 37 2E 02 30 03 23 CE 00 +13 73 13 00 E3 1C 03 FE 23 2A AE 00 23 2C BE 00 +23 2E DE 00 23 20 EE 02 23 22 0E 03 23 24 1E 03 +B7 06 03 03 63 85 0E 02 95 06 03 47 41 00 B3 37 +F0 00 33 36 C0 00 52 06 F2 07 33 37 E0 00 D1 8F +0E 07 D9 8F D5 8F 37 27 02 30 1C C7 82 80 85 06 +E9 BF B7 27 02 30 DC 47 41 11 22 C4 06 C6 05 47 +93 F6 37 00 2A 84 63 9A E6 00 37 26 02 30 85 46 +5C 46 13 F7 37 00 E3 0D D7 FE 89 8B 99 CF B7 37 +02 50 03 A7 47 1F 89 47 63 E2 E7 02 B7 27 02 30 +09 47 98 C7 05 45 EF 30 0F C3 09 C4 B7 07 02 30 +05 47 98 D3 B2 40 22 44 41 01 82 80 37 35 02 50 +13 05 05 F1 EF 30 2F C3 B7 27 02 30 09 47 98 C7 +05 45 EF 30 4F C0 D1 BF B7 27 02 30 DC 47 41 11 +22 C4 06 C6 05 47 93 F6 37 00 2A 84 63 9A E6 00 +37 26 02 30 85 46 5C 46 13 F7 37 00 E3 0D D7 FE +89 8B A9 C3 B7 37 02 50 03 A7 47 1F 89 47 63 EF +E7 00 B7 27 02 30 09 47 98 C7 09 C4 B7 07 02 30 +05 47 98 D3 B2 40 22 44 41 01 82 80 37 35 02 50 +13 05 05 04 EF 30 2F BC B7 27 02 30 09 47 98 C7 +71 FC CD B7 37 35 02 50 13 05 45 07 EF 30 AF BA +05 45 EF 30 4F B8 01 A0 1D 71 A6 CA 86 CE A2 CC +CA C8 CE C6 D2 C4 D6 C2 DA C0 5E DE 62 DC 66 DA +6A D8 6E D6 95 47 AA 84 63 01 F5 22 C5 47 63 02 +F5 12 99 47 63 19 F5 2A 8D 47 B7 49 44 23 37 0B +03 03 37 0C 44 23 3E C6 3E CA 8D 09 05 49 A5 47 +63 97 F4 42 41 64 7D 14 37 0A 03 30 EF 00 50 5F +93 57 F5 41 C1 83 33 07 F5 00 61 8F 1D 8F 83 27 +8A 54 0D 07 93 7D C7 FF E3 82 FD FE 02 C4 02 CE +BD 47 CA 8C 4E 84 63 9E F4 22 CD 47 4D 4D 3E C8 +02 CC 93 8B 24 FF 93 BB 1B 00 13 99 2B 00 B7 39 +02 50 03 A6 49 1F 11 4A 63 63 CA 0E B7 35 02 30 +83 A7 85 80 B7 26 02 30 F9 9B 23 A4 F5 80 DC 46 +85 8B F5 FF 89 47 63 E3 C7 0A B7 27 02 30 23 AA +87 01 22 47 85 46 94 CF C0 CF 23 A0 97 03 33 69 +27 01 23 A2 B7 03 33 67 69 01 23 A4 A7 03 13 67 +17 00 98 C7 DC 47 13 F7 37 00 63 19 D7 00 37 26 +02 30 5C 46 13 F7 37 00 E3 0D D7 FE 89 8B B5 C7 +03 A7 49 1F 89 47 63 EF E7 18 B7 27 02 30 09 47 +98 C7 37 37 02 30 83 27 87 80 F6 40 66 44 93 E7 +17 00 23 24 F7 80 D6 44 46 49 B6 49 26 4A 96 4A +06 4B F2 5B 62 5C D2 5C 42 5D B2 5D 01 45 25 61 +82 80 85 47 41 6B 3E C6 02 CA 91 69 01 49 02 C4 +37 0C 44 23 02 CE 93 0D 00 04 19 BF 37 35 02 50 +13 05 C5 0C EF 30 2F A3 89 BF 37 35 02 50 13 05 +45 07 EF 30 4F A2 05 45 EF 30 EF 9F 01 A0 C1 6A +93 8A 4A 9B A6 85 13 85 4A 41 EF 30 CF A2 03 A6 +49 1F E3 75 CA F0 62 86 85 45 13 85 CA 42 EF 30 +8F A1 03 A6 49 1F E3 7B CA EE 22 86 E6 85 13 85 +CA 44 EF 30 4F A0 03 A6 49 1F E3 71 CA EE B2 45 +13 85 CA 46 EF 30 2F 9F 03 A6 49 1F E3 78 CA EC +D2 45 13 85 4A 48 EF 30 0F 9E 03 A6 49 1F E3 7F +CA EA F2 45 13 85 CA 49 EF 30 EF 9C 03 A6 49 1F +E3 76 CA EA E2 45 13 85 4A 4B EF 30 CF 9B 03 A6 +49 1F E3 7D CA E8 DE 85 13 85 CA 4C EF 30 AF 9A +03 A6 49 1F E3 74 CA E8 EE 85 13 85 4A 4E EF 30 +8F 99 03 A6 49 1F E3 7B CA E6 C2 45 13 85 CA 4F +EF 30 6F 98 03 A6 49 1F 95 B5 B7 07 03 30 03 A9 +47 54 83 A9 07 54 37 0C 44 23 8D 47 CA 8C 4E 84 +0D 0C 37 0B 03 00 3E C6 89 47 63 F6 97 1E 13 87 +D4 FF 85 47 B3 97 E7 00 93 F7 17 4D 3E CA 63 9F +07 1C AD 47 63 86 F4 22 91 47 63 8E F4 18 37 07 +00 03 B9 47 33 6B EB 00 63 99 F4 20 EF 00 50 3B +B7 07 10 00 3E C4 8D 47 3E CA 85 47 3E CE 93 0D +00 04 F9 B3 37 35 02 50 13 05 05 04 EF 30 AF 8E +A9 BD 02 CC C1 47 63 8A F4 00 91 47 63 92 F4 18 +11 49 01 4D 02 C8 85 4B D9 B3 91 47 11 49 11 4D +3E C8 85 4B 6D BB 9D 47 63 1A F5 04 B7 07 03 30 +03 AA 47 54 03 A4 07 54 EF 00 90 35 2A 89 EF 00 +30 35 93 57 F5 41 13 57 E5 01 8A 07 0A 09 D9 8F +0A 05 AA 89 33 69 F9 00 63 14 A4 00 E3 0E 2A FD +CA 8C 2A 84 C5 47 63 EB 97 10 37 07 02 50 93 97 +24 00 13 07 07 55 BA 97 9C 43 82 87 B7 07 03 30 +83 AC 47 54 83 A9 07 54 AD 47 66 89 4E 84 63 12 +F5 02 B7 07 10 00 3E C4 89 47 3E CA 85 47 37 0B +00 02 37 0C 44 23 02 C6 3E CE 02 CC 93 0D 00 04 +91 BF 09 47 89 47 3A C6 3A CA 37 0B 02 02 E3 00 +F5 DE 4D B7 37 0C 44 23 01 4B 02 C6 F1 BD EF 00 +30 2C 8D 47 B3 67 F5 02 91 46 37 0C 44 23 37 07 +00 04 36 CA 85 07 3E C6 13 9B 07 01 33 6B EB 00 +93 87 44 FF 05 47 63 68 F7 06 B7 07 00 10 33 6B +FB 00 85 47 02 C4 01 4D 02 C8 3E CC 93 0D 00 04 +02 CE C1 B1 89 47 02 C4 37 0B 02 00 37 0C 44 23 +3E C6 02 CA 02 CE 93 0D 00 04 59 B9 85 47 41 6B +37 0C 44 23 3E C6 02 CA 99 B9 89 47 3E C6 85 47 +37 0B 02 10 02 C4 37 0C 44 23 02 CA 02 CE 3E CC +93 0D 00 04 45 BD 91 47 37 0B 00 04 37 0C 44 23 +3E CA 02 C6 05 B9 A1 47 E3 93 F4 C2 02 C4 01 4D +02 C8 02 CC 93 0D 30 04 02 CE A1 B9 B5 47 37 0C +44 23 37 0B 03 00 63 EF 97 04 8D 47 3E C6 29 BD +01 4D 02 C8 3D B9 85 47 63 89 F4 00 B7 07 00 04 +33 6B FB 00 91 47 3E CA A1 B7 EF 00 70 1E AD 47 +B3 67 F5 02 95 07 3E CA 13 97 87 01 05 BF 02 C4 +02 CE A9 47 E3 95 F4 E2 B7 07 03 30 03 A7 87 54 +CA 8C 4E 84 93 1D 07 01 93 DD 0D 01 01 4D 02 C8 +02 CC C5 BE 8D 47 3E C6 DD B3 8D 47 3E CA 09 B7 +B7 07 00 02 33 6B FB 00 B7 07 10 00 3E C4 89 47 +3E CA 85 47 3E CE 75 BF B7 27 02 30 DC 47 41 11 +22 C4 06 C6 93 F6 37 00 05 47 2A 84 63 9A E6 00 +37 26 02 30 85 46 5C 46 13 F7 37 00 E3 0D D7 FE +89 8B 95 C7 A1 C5 B7 37 02 50 03 A7 47 1F 89 47 +63 E3 E7 04 B7 27 02 30 09 47 98 C7 09 C4 B7 07 +02 30 05 47 98 D3 B2 40 22 44 41 01 82 80 FD D5 +37 35 02 50 13 05 05 F8 EF 20 FF E7 B7 27 02 30 +09 47 98 C7 05 45 EF 20 1F E5 C9 BF 37 35 02 50 +13 05 05 F4 D5 B7 37 35 02 50 13 05 05 F4 EF 20 +9F E5 4D BF 53 4F 43 5F 49 46 43 3A 20 43 6C 65 +61 72 20 65 78 65 63 75 74 65 20 72 65 67 00 00 +53 4F 43 5F 49 46 43 3A 20 43 68 65 63 6B 20 6D +62 6F 78 5F 73 74 61 74 75 73 2E 6D 62 6F 78 5F +66 73 6D 5F 70 73 20 66 6F 75 6E 64 20 75 6E 65 +78 70 65 63 74 65 64 20 73 74 61 74 65 20 30 78 +25 78 0A 00 53 4F 43 5F 49 46 43 3A 20 53 65 74 +20 6D 62 6F 78 5F 73 74 61 74 75 73 20 66 69 65 +6C 64 3A 20 30 78 25 78 0A 00 00 00 53 4F 43 5F +49 46 43 3A 20 53 65 74 20 66 6C 6F 77 5F 73 74 +61 74 75 73 20 66 69 65 6C 64 3A 20 30 78 25 78 +0A 00 00 00 53 4F 43 5F 49 46 43 3A 20 43 6C 65 +61 72 20 53 48 41 20 61 63 63 65 6C 65 72 61 74 +6F 72 20 6C 6F 63 6B 20 62 79 20 77 72 69 74 69 +6E 67 20 27 31 3A 20 30 78 25 78 0A 00 00 00 00 +53 4F 43 5F 49 46 43 3A 20 42 61 64 20 66 69 65 +6C 64 20 76 61 6C 75 65 00 00 00 00 53 4F 43 5F +49 46 43 3A 20 42 61 64 20 66 69 65 6C 64 20 76 +61 6C 75 65 00 00 00 00 53 4F 43 5F 49 46 43 3A +20 43 6C 65 61 72 20 66 6C 6F 77 5F 73 74 61 74 +75 73 20 66 69 65 6C 64 3A 20 30 78 25 78 0A 00 +53 4F 43 5F 49 46 43 3A 20 43 4D 44 20 66 72 6F +6D 20 6D 61 69 6C 62 6F 78 3A 20 30 78 25 78 0A +00 00 00 00 53 4F 43 5F 49 46 43 3A 20 44 4C 45 +4E 20 66 72 6F 6D 20 6D 61 69 6C 62 6F 78 3A 20 +30 78 25 78 0A 00 00 00 46 41 54 41 4C 3A 20 49 +6E 76 61 6C 69 64 20 64 6C 65 6E 20 70 61 73 73 +65 64 20 74 6F 20 6D 62 6F 78 20 66 77 20 66 6C +6F 77 3A 20 30 78 25 78 0A 00 00 00 46 41 54 41 +4C 3A 20 49 6E 76 61 6C 69 64 20 63 6D 64 20 70 +61 73 73 65 64 20 74 6F 20 6D 62 6F 78 20 66 77 +20 66 6C 6F 77 3A 20 30 78 25 78 0A 00 00 00 00 +46 6F 75 6E 64 20 69 6E 76 61 6C 69 64 20 69 63 +63 6D 20 73 69 7A 65 20 69 6E 20 66 69 72 6D 77 +61 72 65 20 69 6D 61 67 65 20 72 65 63 65 69 76 +65 64 20 66 72 6F 6D 20 53 4F 43 21 20 4D 61 78 +20 65 78 70 65 63 74 65 64 20 30 78 25 78 2C 20 +67 6F 74 20 30 78 25 78 0A 00 00 00 46 6F 75 6E +64 20 69 6E 76 61 6C 69 64 20 64 63 63 6D 20 73 +69 7A 65 20 69 6E 20 66 69 72 6D 77 61 72 65 20 +69 6D 61 67 65 20 72 65 63 65 69 76 65 64 20 66 +72 6F 6D 20 53 4F 43 21 20 4D 61 78 20 65 78 70 +65 63 74 65 64 20 30 78 25 78 2C 20 67 6F 74 20 +30 78 25 78 0A 00 00 00 61 74 20 25 78 3A 20 25 +78 0A 00 00 53 4F 43 5F 49 46 43 3A 20 49 6C 6C +65 67 61 6C 20 62 79 74 65 5F 63 6F 75 6E 74 20 +30 78 25 78 0A 00 00 00 53 4F 43 5F 49 46 43 3A +20 53 65 74 20 66 77 20 75 70 64 61 74 65 20 72 +65 73 65 74 20 77 69 74 68 20 77 61 69 74 5F 63 +79 63 6C 65 73 20 5B 25 64 5D 20 28 25 73 29 0A +00 00 00 00 73 72 63 5F 61 64 64 72 20 30 78 25 +78 20 69 73 20 6F 75 74 20 6F 66 20 62 6F 75 6E +64 73 20 66 6F 72 20 6D 62 6F 78 20 73 70 61 6E +21 0A 00 00 72 65 61 64 69 6E 67 20 30 78 25 78 +20 62 79 74 65 73 20 66 72 6F 6D 20 73 72 63 5F +61 64 64 72 20 30 78 25 78 20 67 6F 65 73 20 6F +75 74 20 6F 66 20 62 6F 75 6E 64 73 20 66 6F 72 +20 6D 62 6F 78 20 73 70 61 6E 21 0A 00 00 00 00 +64 73 74 5F 61 64 64 72 20 30 78 25 78 20 69 73 +20 6F 75 74 20 6F 66 20 62 6F 75 6E 64 73 20 66 +6F 72 20 6D 62 6F 78 20 73 70 61 6E 21 0A 00 00 +77 72 69 74 69 6E 67 20 30 78 25 78 20 62 79 74 +65 73 20 74 6F 20 64 73 74 5F 61 64 64 72 20 30 +78 25 78 20 67 6F 65 73 20 6F 75 74 20 6F 66 20 +62 6F 75 6E 64 73 20 66 6F 72 20 6D 62 6F 78 20 +73 70 61 6E 21 0A 00 00 70 61 72 61 6D 3A 20 65 +72 72 5F 74 79 70 65 20 20 20 30 78 25 78 0A 00 +70 61 72 61 6D 3A 20 73 72 63 5F 61 64 64 72 20 +20 20 30 78 25 78 20 30 78 25 78 0A 00 00 00 00 +70 61 72 61 6D 3A 20 64 73 74 5F 61 64 64 72 20 +20 20 30 78 25 78 20 30 78 25 78 0A 00 00 00 00 +70 61 72 61 6D 3A 20 72 64 5F 72 6F 75 74 65 20 +20 20 30 78 25 78 0A 00 70 61 72 61 6D 3A 20 77 +72 5F 72 6F 75 74 65 20 20 20 30 78 25 78 0A 00 +70 61 72 61 6D 3A 20 72 64 5F 66 69 78 65 64 20 +20 20 30 78 25 78 0A 00 70 61 72 61 6D 3A 20 77 +72 5F 66 69 78 65 64 20 20 20 30 78 25 78 0A 00 +70 61 72 61 6D 3A 20 61 65 73 5F 6D 6F 64 65 20 +20 20 30 78 25 78 0A 00 70 61 72 61 6D 3A 20 62 +79 74 65 5F 63 6F 75 6E 74 20 30 78 25 78 0A 00 +70 61 72 61 6D 3A 20 62 6C 6F 63 6B 5F 73 69 7A +65 20 30 78 25 78 0A 00 B7 06 02 50 83 A7 86 59 +13 97 D7 00 3D 8F 93 57 17 01 B9 8F 13 95 57 00 +3D 8D 23 AC A6 58 82 80 B7 37 02 50 03 A7 47 1F +41 11 22 C4 26 C2 06 C6 89 47 AA 84 2E 84 63 E3 +E7 02 73 50 20 7D 73 90 34 7D 73 D0 41 7D 73 10 +44 30 73 50 04 30 73 D0 61 7C B2 40 22 44 92 44 +41 01 82 80 37 35 02 50 13 05 05 0E EF 20 BF 8D +C9 BF 73 50 20 7D 73 10 35 7D 73 D0 41 7D 73 90 +45 30 73 50 04 30 82 80 73 D0 61 7C 82 80 B7 07 +03 30 23 A6 A7 0E 23 A8 B7 0E 82 80 B7 07 03 30 +23 AE A7 0E 23 A0 B7 10 82 80 B7 07 03 30 7D 57 +23 A6 E7 0E 23 A8 E7 0E 82 80 B7 07 03 30 7D 57 +23 AE E7 0E 23 A0 E7 10 82 80 37 17 03 30 83 27 +47 81 93 F7 07 04 E5 DF 93 07 00 04 23 2A F7 80 +82 80 37 17 03 30 83 27 47 81 93 F7 07 08 E5 DF +93 07 00 08 23 2A F7 80 82 80 B7 07 03 30 23 A6 +A7 0E 23 A8 B7 0E 23 AE C7 0E 23 A0 D7 10 05 47 +23 A2 E7 0E 23 A4 E7 0E 82 80 01 11 06 CE 0D E1 +B7 37 02 50 03 A7 47 1F 89 47 63 E2 E7 08 B7 07 +03 30 23 A2 07 0E 23 AA 07 0E F2 40 05 61 82 80 +85 47 63 01 F5 04 89 47 E3 19 F5 FE B7 37 02 50 +83 A7 47 1F 63 6F F5 06 B7 07 03 30 23 A6 B7 0E +23 A8 C7 0E 23 AE D7 0E 23 A0 E7 10 05 47 23 A2 +E7 0E 23 AA E7 0E F2 40 23 A4 E7 0E 23 AC E7 0E +05 61 82 80 B7 37 02 50 03 A6 47 1F 89 47 63 E7 +C7 02 B7 07 03 30 23 AE D7 0E 23 A0 E7 10 F2 40 +05 47 23 AA E7 0E 23 AC E7 0E 05 61 82 80 37 35 +02 50 13 05 85 0F EF 20 0F F9 95 BF 37 35 02 50 +13 05 45 12 3A C2 36 C0 EF 20 EF F7 12 47 82 46 +C9 B7 37 35 02 50 13 05 05 15 3A C6 36 C4 32 C2 +2E C0 EF 20 4F F6 32 47 A2 46 12 46 82 45 AD B7 +B3 47 B5 00 8D 8B B3 08 C5 00 B1 E7 8D 47 63 F4 +C7 04 93 77 35 00 2A 87 B9 EB 13 F6 C8 FF B3 06 +E6 40 93 07 00 02 63 C8 D7 06 AE 86 BA 87 63 71 +C7 02 03 A8 06 00 91 07 91 06 23 AE 07 FF E3 EA +C7 FE 93 07 F6 FF 99 8F F1 9B 91 07 3E 97 BE 95 +63 66 17 01 82 80 2A 87 63 7E 15 03 83 C7 05 00 +05 07 85 05 A3 0F F7 FE E3 9A E8 FE 82 80 83 C6 +05 00 05 07 93 77 37 00 A3 0F D7 FE 85 05 D1 DF +83 C6 05 00 05 07 93 77 37 00 A3 0F D7 FE 85 05 +F9 FF 61 B7 82 80 41 11 22 C6 13 04 00 02 83 A3 +05 00 83 A2 45 00 83 AF 85 00 03 AF C5 00 83 AE +05 01 03 AE 45 01 03 A3 85 01 03 A8 C5 01 94 51 +13 07 47 02 B3 07 E6 40 23 2E 77 FC 23 20 57 FE +23 22 F7 FF 23 24 E7 FF 23 26 D7 FF 23 28 C7 FF +23 2A 67 FE 23 2C 07 FF 23 2E D7 FE 93 85 45 02 +E3 47 F4 FA AE 86 BA 87 63 71 C7 02 03 A8 06 00 +91 07 91 06 23 AE 07 FF E3 EA C7 FE 93 07 F6 FF +99 8F F1 9B 91 07 3E 97 BE 95 63 65 17 01 32 44 +41 01 82 80 83 C7 05 00 05 07 85 05 A3 0F F7 FE +E3 87 E8 FE 83 C7 05 00 05 07 85 05 A3 0F F7 FE +E3 92 E8 FE E9 BF 3D 43 2A 87 63 73 C3 02 93 77 +F7 00 BD EF AD E5 93 76 06 FF 3D 8A BA 96 0C C3 +4C C3 0C C7 4C C7 41 07 E3 6B D7 FE 11 E2 82 80 +B3 06 C3 40 8A 06 97 02 00 00 96 96 67 80 A6 00 +23 07 B7 00 A3 06 B7 00 23 06 B7 00 A3 05 B7 00 +23 05 B7 00 A3 04 B7 00 23 04 B7 00 A3 03 B7 00 +23 03 B7 00 A3 02 B7 00 23 02 B7 00 A3 01 B7 00 +23 01 B7 00 A3 00 B7 00 23 00 B7 00 82 80 93 F5 +F5 0F 93 96 85 00 D5 8D 93 96 05 01 D5 8D 61 B7 +93 96 27 00 97 02 00 00 96 96 86 82 E7 80 86 FA +96 80 C1 17 1D 8F 3E 96 E3 74 C3 F8 A5 B7 B7 37 +02 50 83 A7 07 18 23 A4 A7 0A 23 A6 07 0A 82 80 +B7 37 02 50 03 A8 07 18 B7 85 95 4C 93 85 D5 F2 +83 26 88 0A 03 27 C8 0A B3 87 B6 02 13 86 17 00 +B3 37 F6 00 23 24 C8 0A 37 F6 51 58 13 06 D6 42 +33 86 C6 02 33 07 B7 02 B3 B6 B6 02 32 97 36 97 +BA 97 13 95 17 00 23 26 F8 0A 05 81 82 80 93 77 +35 00 2A 87 9D EF B7 86 7F 7F 93 86 F6 F7 FD 55 +10 43 11 07 B3 77 D6 00 B6 97 D1 8F D5 8F E3 89 +B7 FE 83 46 C7 FF B3 07 A7 40 8D CA 83 46 D7 FF +9D C2 03 45 E7 FF 33 35 A0 00 3E 95 79 15 82 80 +F9 D2 83 47 07 00 05 07 93 76 37 00 F5 FB 09 8F +13 05 F7 FF 82 80 13 85 D7 FF 82 80 13 85 C7 FF +82 80 13 01 01 BC 23 2A 91 42 23 28 21 43 23 20 +61 43 23 2C 81 41 23 2E 11 42 23 2C 81 42 23 26 +31 43 23 24 41 43 23 22 51 43 23 2E 71 41 23 2A +91 41 23 28 A1 41 23 26 B1 41 85 47 36 8B 2A 89 +2E 8C B2 84 63 F1 D7 2E 01 46 85 4C 85 46 FD 5B +09 A8 B3 8C 77 41 3E 86 85 46 B3 07 D6 00 63 F7 +67 03 33 87 74 01 36 97 B3 85 F4 00 83 C5 05 00 +03 47 07 00 E3 EF E5 FC 63 86 E5 14 B2 8B 85 46 +05 06 B3 07 D6 00 85 4C E3 ED 67 FD 81 45 05 48 +05 46 7D 55 05 47 09 A8 33 08 A7 40 BA 85 05 46 +33 87 C5 00 63 77 67 03 B3 87 C4 00 B3 86 E4 00 +AA 97 83 C6 06 00 83 C7 07 00 E3 EF D7 FC 63 87 +D7 10 2E 85 05 46 85 05 33 87 C5 00 05 48 E3 6D +67 FD 05 05 85 0B 63 64 75 01 C2 8C AA 8B 8A 87 +13 07 01 40 23 A0 67 01 91 07 E3 9D E7 FE 63 05 +0B 02 13 06 FB FF B3 05 9B 00 26 87 26 96 83 47 +07 00 B3 06 E6 40 05 07 8A 07 93 87 07 40 8A 97 +23 A0 D7 C0 E3 95 E5 FE 5E 86 B3 85 94 01 26 85 +C9 26 63 1F 05 10 85 69 93 89 09 80 05 4A 81 4D +01 44 B3 06 6C 41 B3 69 3B 01 13 0D FB FF 33 0A +7A 41 B3 0A 9B 41 63 E8 86 02 33 06 89 00 B3 07 +A6 01 83 C7 07 00 8A 07 93 87 07 40 8A 97 83 A7 +07 C0 AD CB 63 85 0D 00 63 F3 97 01 D6 87 3E 94 +81 4D E3 FC 86 FC 33 05 89 01 CE 85 6D 21 2A 9C +B3 06 6C 41 E3 F3 86 FC 01 45 83 20 C1 43 03 24 +81 43 83 24 41 43 03 29 01 43 83 29 C1 42 03 2A +81 42 83 2A 41 42 03 2B 01 42 83 2B C1 41 03 2C +81 41 83 2C 41 41 03 2D 01 41 83 2D C1 40 13 01 +01 44 82 80 63 8A 96 15 85 06 41 BD 63 03 C8 14 +05 06 F9 B5 6E 87 63 F3 7D 01 5E 87 63 70 A7 03 +B3 07 E4 00 33 88 E4 00 CA 97 03 45 08 00 83 C7 +07 00 63 11 F5 04 05 07 E3 64 A7 FF 13 87 FB FF +63 E6 7D 01 39 AA 63 81 ED 02 2A 87 B3 07 E4 00 +B3 85 E4 00 CA 97 83 C5 05 00 83 C7 07 00 13 05 +F7 FF E3 82 F5 FE 05 07 85 0D 63 6A B7 0F 66 94 +D6 8D 11 BF E3 74 A7 FD 52 94 3A 94 81 4D 21 B7 +33 0A 7B 41 63 65 7A 0D 05 64 13 04 04 80 85 49 +05 0A 81 4A B3 06 6C 41 33 64 8B 00 93 0C FB FF +B3 89 79 41 7D 5D 63 E2 56 03 33 05 59 01 B3 07 +95 01 83 C7 07 00 8A 07 93 87 07 40 8A 97 83 A7 +07 C0 95 CB BE 9A E3 F2 56 FF 33 05 89 01 A2 85 +59 2E 2A 9C B3 06 6C 41 E3 E8 56 EF 33 05 59 01 +B3 07 95 01 83 C7 07 00 8A 07 93 87 07 40 8A 97 +83 A7 07 C0 E1 FB 5E 87 63 E6 9B 01 25 A0 05 07 +63 72 97 03 B3 07 57 01 B3 85 E4 00 CA 97 03 C6 +05 00 83 C7 07 00 E3 04 F6 FE 63 75 97 01 CE 9A +BA 9A 51 B7 93 87 FB FF 63 95 A7 01 79 BD E3 8E +A7 E9 33 87 FA 00 33 86 F4 00 4A 97 03 46 06 00 +03 47 07 00 FD 17 E3 04 E6 FE D2 9A A9 BF 5E 8A +25 BF C2 95 05 46 69 B3 36 96 85 46 3D BB 32 85 +AD B5 5E 87 11 B7 85 4C 81 4B 55 BB 1D 71 A2 CC +A6 CA 86 CE CA C8 CE C6 D2 C4 AE 84 83 C5 05 00 +2A 84 E1 C1 03 C6 14 00 63 0E 06 12 03 C7 24 00 +71 C3 03 C5 34 00 63 02 05 14 83 C7 44 00 E1 CF +26 85 EF F0 DF C3 2A 89 93 65 05 20 22 85 65 2C +63 6A 25 0F 93 07 E0 0F 63 E8 27 15 B3 09 25 41 +13 06 00 04 93 05 19 00 0A 85 A2 99 EF F0 BF B0 +63 06 09 02 13 76 F9 0F 26 87 B3 05 99 00 26 96 +83 47 07 00 B3 06 E6 40 05 07 93 F7 F7 03 93 87 +07 04 8A 97 23 80 D7 FC E3 94 E5 FE 7D 14 B3 07 +24 01 83 C7 07 00 93 F7 F7 03 93 87 07 04 8A 97 +83 C7 07 FC 3E 94 63 F6 89 00 79 A0 52 94 63 E5 +89 08 B3 07 24 01 83 C7 07 00 22 85 4A 86 93 F7 +F7 03 93 87 07 04 8A 97 A6 85 03 CA 07 FC D5 20 +71 FD F6 40 22 85 66 44 D6 44 46 49 B6 49 26 4A +25 61 82 80 03 47 05 00 C2 05 D1 8D 81 47 39 C3 +C2 07 A2 86 D9 8F 05 04 03 47 04 00 E3 99 F5 FE +13 84 F6 FF F9 B7 93 97 85 01 42 06 83 46 04 00 +D1 8F C9 8F 22 07 D9 8F 91 CE 01 47 19 A0 63 83 +E7 04 22 86 22 07 05 04 55 8F 83 46 04 00 E5 FA +63 8A E7 02 01 44 71 BF 33 85 29 01 83 47 05 00 +F5 DB 85 65 93 85 05 80 7D 22 AA 99 E3 F0 89 F4 +01 44 41 B7 66 44 F6 40 D6 44 46 49 B6 49 26 4A +25 61 4D A0 13 04 D6 FF AD B7 83 46 04 00 93 97 +85 01 42 06 D1 8F 22 07 D9 8F CD DE 01 47 11 A0 +D5 DA 55 8F 22 86 22 07 05 04 83 46 04 00 E3 19 +F7 FE 13 04 E6 FF 35 BF AA 85 22 85 66 44 F6 40 +B6 49 26 4A CA 86 26 86 46 49 D6 44 25 61 6F F0 +5F B2 8D 47 63 F3 C7 02 B3 67 B5 00 8D 8B 8D 46 +89 CB 93 06 F6 FF 29 A8 71 16 11 05 91 05 63 F6 +C6 00 18 41 9C 41 E3 09 F7 FE 93 06 F6 FF 0D C2 +85 06 AE 96 19 A0 63 8D D5 00 83 47 05 00 03 C7 +05 00 05 05 85 05 E3 88 E7 FE 33 85 E7 40 82 80 +01 45 82 80 93 F6 F5 0F 93 77 35 00 C1 CE 91 CB +83 47 05 00 D1 C7 63 86 D7 08 05 05 93 77 35 00 +E5 FB 93 F5 F5 0F 93 97 85 00 AE 97 18 41 13 93 +07 01 33 63 F3 00 37 08 FF FE 33 46 E3 00 13 08 +F8 EF B3 07 07 01 B3 05 06 01 13 47 F7 FF 13 46 +F6 FF F9 8F B7 88 80 80 33 F7 C5 00 D9 8F 93 88 +08 08 B3 F7 17 01 85 E7 58 41 11 05 33 46 67 00 +B3 07 07 01 B3 05 06 01 13 47 F7 FF 13 46 F6 FF +F9 8F 33 F7 C5 00 D9 8F B3 F7 17 01 F1 DF 83 47 +05 00 99 C7 63 80 F6 06 83 47 15 00 05 05 FD FB +01 45 82 80 81 CB 83 47 05 00 E5 DF 05 05 93 77 +35 00 F5 FB 18 41 37 06 FF FE 13 06 F6 EF 93 47 +F7 FF B7 86 80 80 32 97 F9 8F 93 86 06 08 F5 8F +91 EB 58 41 11 05 B3 07 C7 00 13 47 F7 FF F9 8F +F5 8F E5 DB 83 47 05 00 CD DF 83 47 15 00 05 05 +ED FF 82 80 82 80 B3 06 B5 00 AA 87 89 E5 29 A8 +85 07 63 88 F6 00 03 C7 07 00 7D FB 33 85 A7 40 +82 80 33 85 A6 40 82 80 01 45 82 80 +@000109AC +B4 23 00 00 0E 23 00 00 0E 23 00 00 0E 23 00 00 +0E 23 00 00 0E 23 00 00 0E 23 00 00 0E 23 00 00 +0E 23 00 00 0E 23 00 00 0E 23 00 00 F4 24 00 00 +80 24 00 00 0E 23 00 00 0E 23 00 00 0E 23 00 00 +0E 23 00 00 0E 23 00 00 0E 23 00 00 0E 23 00 00 +0E 23 00 00 0E 23 00 00 0E 23 00 00 5C 24 00 00 +0E 23 00 00 0E 23 00 00 0E 23 00 00 34 24 00 00 +0E 23 00 00 D8 23 00 00 0E 23 00 00 0E 23 00 00 +B4 23 00 00 06 2C 4C C7 74 E2 13 BE 68 66 3B C0 +E9 33 78 7E E2 CA AE 3A FA 44 3E E6 7D EF AA 89 +12 1C A2 61 73 6E 6E BB B8 60 9D 35 68 E6 B7 23 +C9 BC 33 0F 0C A0 0E CA 39 65 91 72 B4 73 B9 36 +2D D3 3C A5 BC 62 30 95 82 3D AF E1 90 99 83 14 +FE DB AC 42 58 39 50 63 23 45 64 53 21 23 AD FC +EF DA 23 44 77 F2 81 7A 9E 46 51 52 25 55 33 2B +89 FC C5 99 0E D7 54 FD 2B F3 47 F7 6F D4 E1 B8 +52 CD AC 30 36 BE C1 6B F9 34 7B D2 68 1F 02 09 +3A 31 B8 A6 83 C6 4C 93 A6 FF 43 D5 7D C5 9C 8A +AB 63 5B AC F0 A5 EB 3C 5D 1F 06 22 D3 E1 2C B7 +6E 4B D9 B4 DD 34 5B A3 53 5C 16 A9 EB 0D 31 CB +2F 6D 8D BE DC 28 CA 92 11 56 3C 29 39 B4 39 82 +8A 8B 2C 5B 2E 88 25 3D C7 1D C1 3E D2 28 F2 9D +A5 D5 5A 7A CA A1 E4 24 C3 1D D2 5C 0A AC 3A A8 +6C EB C5 F3 42 D7 C3 77 A6 8A 47 AF ED 07 7E 39 +C6 35 62 2D 29 28 6E A8 B9 EE 60 EE F3 FA 21 2F +02 47 C8 90 38 E0 8E F9 52 AA C5 8D 22 3C 65 C2 +BC C6 11 69 23 86 AB D4 6D 5C 73 42 D4 AA BF 1A +6F 0B 04 B8 A5 A1 E4 C2 71 F7 0E E1 76 B1 CD F8 +2A D5 5F 56 18 90 CC 73 77 04 61 2D 34 49 A1 79 +BD D4 16 BE B4 B6 1A A7 2B E9 73 60 37 67 AC 66 +F1 E0 35 E8 23 A4 2C 63 43 E0 15 82 63 7C 05 32 +5E B0 1C 18 48 C7 09 1F 8B EC 3C 8A AD EA 25 CE +F2 C4 EB B3 0D EA 0F D3 A6 61 0D 88 23 F3 BA 8E +77 F0 19 8B 3F 84 A6 22 D2 38 50 36 D3 7D A0 D3 +6A 1B AF 6C E1 C4 60 F0 6F A4 7A 18 EA 69 CD C3 +E0 22 B5 BC 8A 3B FA B6 78 70 18 9C 8E 17 3B 0C +E6 FB 90 4E 7E 36 76 97 2B FF 37 87 F4 A3 A6 E1 +C2 2B 6C 4E 18 6B 3A F9 07 CD 14 0A 85 04 FD E7 +C5 15 3A DA C4 23 02 50 00 C0 01 10 0A 00 00 00 +01 00 00 00 00 00 00 00 D8 23 02 50 28 C0 01 10 +0C 00 00 00 FF FF FF FF 00 00 00 00 F4 23 02 50 +58 C0 01 10 0C 00 00 00 FF FF FF FF 00 00 00 00 +10 24 02 50 88 C0 01 10 0C 00 00 00 FF FF FF FF +00 00 00 00 2C 24 02 50 B8 C0 01 10 0C 00 00 00 +FF FF FF FF 00 00 00 00 48 24 02 50 E8 C0 01 10 +0C 00 00 00 FF FF FF FF 00 00 00 00 64 24 02 50 +18 C1 01 10 0C 00 00 00 FF FF FF FF 00 00 00 00 +80 24 02 50 48 C1 01 10 0C 00 00 00 FF FF FF FF +00 00 00 00 9C 24 02 50 78 C1 01 10 0C 00 00 00 +FF FF FF FF 00 00 00 00 B8 24 02 50 A8 C1 01 10 +0C 00 00 00 FF FF FF FF 00 00 00 00 D4 24 02 50 +D8 C1 01 10 0C 00 00 00 FF FF FF FF 00 00 00 00 +F0 24 02 50 08 C2 01 10 0A 00 00 00 00 00 00 00 +00 00 00 00 00 25 02 50 30 C2 01 10 0C 00 00 00 +FF FF FF FF 00 00 00 00 14 25 02 50 60 C2 01 10 +0C 00 00 00 FF FF FF FF 00 00 00 00 28 25 02 50 +90 C2 01 10 0C 00 00 00 FF FF FF FF 00 00 00 00 +3C 25 02 50 C0 C2 01 10 0C 00 00 00 FF FF FF FF +00 00 00 00 50 25 02 50 F0 C2 01 10 0C 00 00 00 +FF FF FF FF 00 00 00 00 64 25 02 50 20 C3 01 10 +0C 00 00 00 FF FF FF FF 00 00 00 00 78 25 02 50 +50 C3 01 10 0C 00 00 00 FF FF FF FF 00 00 00 00 +8C 25 02 50 80 C3 01 10 0C 00 00 00 FF FF FF FF +00 00 00 00 A0 25 02 50 B0 C3 01 10 0C 00 00 00 +FF FF FF FF 00 00 00 00 B4 25 02 50 E0 C3 01 10 +0C 00 00 00 FF FF FF FF 00 00 00 00 C8 25 02 50 +10 C4 01 10 0A 00 00 00 00 00 00 00 00 00 00 00 +E4 25 02 50 38 C4 01 10 0A 00 00 00 FF FF FF FF +00 00 00 00 F8 25 02 50 60 C4 01 10 08 00 00 00 +00 00 00 00 00 00 00 00 18 26 02 50 80 C4 01 10 +08 00 00 00 01 00 00 00 00 00 00 00 38 26 02 50 +A0 C4 01 10 08 00 00 00 FF FF FF FF 00 00 00 00 +00 00 00 00 00 00 00 00 0C 00 00 00 01 00 00 00 +02 00 00 00 03 00 00 00 04 00 00 00 05 00 00 00 +06 00 00 00 07 00 00 00 08 00 00 00 09 00 00 00 +0A 00 00 00 0B 00 00 00 01 00 00 00 0C 00 00 00 +0C 00 00 00 0D 00 00 00 0E 00 00 00 0F 00 00 00 +10 00 00 00 11 00 00 00 12 00 00 00 13 00 00 00 +14 00 00 00 15 00 00 00 16 00 00 00 03 00 00 00 +01 00 00 00 17 00 00 00 17 00 00 00 17 00 00 00 +17 00 00 00 17 00 00 00 17 00 00 00 17 00 00 00 +17 00 00 00 17 00 00 00 17 00 00 00 19 00 00 00 +02 00 00 00 01 00 00 00 1A 00 00 00 1A 00 00 00 +1A 00 00 00 1A 00 00 00 1A 00 00 00 1A 00 00 00 +1A 00 00 00 1A 00 00 00 FF FF FF FF FF FF FF FF +E4 F7 00 00 9C F8 00 00 9C F8 00 00 EE F7 00 00 +34 F8 00 00 9C F8 00 00 9C F8 00 00 E4 F7 00 00 +9C F8 00 00 76 F8 00 00 E4 F7 00 00 9C F8 00 00 +5A F8 00 00 E4 F7 00 00 9C F8 00 00 9C F8 00 00 +9C F8 00 00 4C F8 00 00 2C 63 2C 69 00 00 00 00 +00 00 00 00 8C 08 02 50 F4 08 02 50 5C 09 02 50 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 +0E 33 CD AB 34 12 6D E6 EC DE 05 00 0B 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 49 6E 3A 61 78 69 5F 64 +6D 61 5F 6E 6F 74 69 66 00 00 00 00 49 6E 3A 61 +78 69 5F 64 6D 61 5F 65 72 72 6F 72 00 00 00 00 +49 6E 3A 61 62 72 5F 6E 6F 74 69 66 00 00 00 00 +49 6E 3A 61 62 72 5F 65 72 72 6F 72 00 00 00 00 +49 6E 3A 73 68 61 35 31 32 5F 61 63 63 5F 65 72 +72 6F 72 00 49 6E 3A 73 68 61 33 5F 6E 6F 74 69 +66 00 00 00 49 6E 3A 73 68 61 33 5F 65 72 72 6F +72 00 00 00 49 6E 3A 73 68 61 32 35 36 5F 65 72 +72 6F 72 00 49 6E 3A 73 68 61 35 31 32 5F 65 72 +72 6F 72 00 49 6E 3A 6B 76 5F 6E 6F 74 69 66 00 +49 6E 3A 6B 76 5F 65 72 72 6F 72 00 49 6E 3A 68 +6D 61 63 5F 65 72 72 6F 72 00 00 00 49 6E 3A 65 +63 63 5F 65 72 72 6F 72 00 00 00 00 49 6E 3A 64 +6F 65 5F 65 72 72 6F 72 00 00 00 00 49 6E 3A 30 +00 00 00 00 49 6E 3A 73 68 61 35 31 32 5F 61 63 +63 5F 6E 6F 74 69 66 00 49 6E 3A 73 6F 63 5F 69 +66 63 5F 6E 6F 74 69 66 00 00 00 00 49 6E 3A 73 +6F 63 5F 69 66 63 5F 65 72 72 6F 72 00 00 00 00 +49 6E 3A 73 68 61 32 35 36 5F 6E 6F 74 69 66 00 +49 6E 3A 73 68 61 35 31 32 5F 6E 6F 74 69 66 00 +49 6E 3A 68 6D 61 63 5F 6E 6F 74 69 66 00 00 00 +49 6E 3A 65 63 63 5F 6E 6F 74 69 66 00 00 00 00 +49 6E 3A 64 6F 65 5F 6E 6F 74 69 66 00 00 00 00 +44 6F 6E 65 20 68 61 6E 64 6C 69 6E 67 20 6D 61 +63 68 69 6E 65 2D 6D 6F 64 65 20 54 49 4D 45 52 +20 69 6E 74 65 72 72 75 70 74 00 00 43 6F 72 20 +45 72 72 6F 72 20 4C 6F 63 61 6C 20 49 53 52 00 +45 72 72 6F 72 3A 20 48 65 78 20 73 74 72 69 6E +67 20 6C 65 6E 67 74 68 20 6D 75 73 74 20 62 65 +20 61 20 6D 75 6C 74 69 70 6C 65 20 6F 66 20 32 +2E 00 00 00 43 6F 6E 66 69 67 75 72 69 6E 67 20 +41 45 53 20 66 6F 72 20 62 69 67 20 65 6E 64 69 +61 6E 20 6D 6F 64 65 00 43 6F 6E 66 69 67 75 72 +69 6E 67 20 41 45 53 20 66 6F 72 20 6C 69 74 74 +6C 65 20 65 6E 64 69 61 6E 20 6D 6F 64 65 00 00 +4C 6F 61 64 20 4B 65 79 20 64 61 74 61 20 74 6F +20 41 45 53 00 00 00 00 57 72 69 74 65 20 41 45 +53 20 49 56 00 00 00 00 57 61 69 74 20 66 6F 72 +20 49 4E 50 55 54 5F 52 45 41 44 59 00 00 00 00 +49 6E 6A 65 63 74 69 6E 67 20 44 4D 41 20 65 72 +72 00 00 00 49 6E 6A 65 63 74 69 6E 67 20 41 45 +53 20 63 6F 6C 6C 69 73 69 6F 6E 20 65 72 72 00 +41 45 53 20 63 6F 6C 6C 69 73 69 6F 6E 20 65 72 +72 6F 72 20 6D 75 73 74 20 72 65 73 75 6C 74 20 +69 6E 20 4E 4D 49 2C 20 61 6E 64 20 66 69 72 6D +77 61 72 65 20 72 65 73 65 74 00 00 41 54 54 45 +4D 50 54 20 54 4F 20 46 4C 49 50 20 53 49 44 45 +4C 4F 41 44 20 42 49 54 00 00 00 00 45 58 50 45 +43 54 45 44 20 4F 55 54 50 55 54 5F 4C 4F 53 54 +20 74 6F 20 62 65 20 6E 6F 6E 2D 7A 65 72 6F 20 +73 69 6E 63 65 20 4F 43 50 20 4C 4F 43 4B 20 70 +72 6F 74 65 63 74 69 6F 6E 73 20 61 72 65 20 62 +6C 6F 63 6B 69 6E 67 20 74 68 65 20 6F 75 74 70 +75 74 20 74 6F 20 46 57 00 00 00 00 45 78 70 65 +63 74 65 64 20 64 61 74 61 3A 20 30 78 30 00 00 +57 41 49 54 49 4E 47 20 46 4F 52 20 4B 56 20 52 +45 41 44 20 54 4F 20 46 49 4E 49 53 48 00 00 00 +45 58 50 45 43 54 49 4E 47 20 4B 56 20 52 44 20 +45 52 52 00 45 58 50 45 43 54 49 4E 47 20 4E 4F +20 4B 56 20 52 44 20 45 52 52 00 00 57 41 49 54 +49 4E 47 20 46 4F 52 20 4B 56 20 57 52 49 54 45 +20 54 4F 20 46 49 4E 49 53 48 00 00 43 48 45 43 +4B 49 4E 47 20 46 4F 52 20 4B 56 20 57 52 49 54 +45 20 45 52 52 00 00 00 45 58 50 45 43 54 49 4E +47 20 4B 56 20 45 52 52 00 00 00 00 45 58 50 45 +43 54 49 4E 47 20 4E 4F 20 4B 56 20 45 52 52 00 +52 65 61 64 20 61 6E 64 20 43 6F 6D 70 61 72 65 +20 47 43 4D 20 54 41 47 00 00 00 00 41 45 53 20 +4F 70 65 72 61 74 69 6F 6E 20 43 6F 6D 70 6C 65 +74 65 00 00 4C 6F 61 64 69 6E 67 20 4B 56 20 76 +69 61 20 41 45 53 00 00 44 4F 45 3A 20 49 6E 69 +74 00 00 00 44 4F 45 3A 20 57 72 69 74 69 6E 67 +20 55 44 53 20 49 56 00 44 4F 45 3A 20 53 74 61 +72 74 69 6E 67 20 55 44 53 20 44 65 6F 62 66 75 +73 63 61 74 69 6F 6E 20 66 6C 6F 77 00 00 00 00 +44 4F 45 3A 20 55 44 53 20 44 65 6F 62 66 75 73 +63 61 74 69 6F 6E 20 66 6C 6F 77 20 63 6F 6D 70 +6C 65 74 65 00 00 00 00 44 4F 45 3A 20 57 72 69 +74 69 6E 67 20 46 69 65 6C 64 20 45 6E 74 72 6F +70 79 20 49 56 00 00 00 44 4F 45 3A 20 53 74 61 +72 74 69 6E 67 20 46 69 65 6C 64 20 45 6E 74 72 +6F 70 79 20 44 65 6F 62 66 75 73 63 61 74 69 6F +6E 20 66 6C 6F 77 00 00 44 4F 45 3A 20 46 69 65 +6C 64 20 45 6E 74 72 6F 70 79 20 44 65 6F 62 66 +75 73 63 61 74 69 6F 6E 20 66 6C 6F 77 20 63 6F +6D 70 6C 65 74 65 00 00 44 4F 45 3A 20 57 72 69 +74 69 6E 67 20 48 45 4B 20 49 56 00 44 4F 45 3A +20 53 74 61 72 74 69 6E 67 20 48 45 4B 20 44 65 +6F 62 66 75 73 63 61 74 69 6F 6E 20 66 6C 6F 77 +00 00 00 00 44 4F 45 3A 20 48 45 4B 20 53 65 65 +64 20 44 65 6F 62 66 75 73 63 61 74 69 6F 6E 20 +66 6C 6F 77 20 63 6F 6D 70 6C 65 74 65 00 00 00 +44 4F 45 3A 20 53 6B 69 70 70 69 6E 67 20 48 45 +4B 20 44 65 6F 62 66 75 73 63 61 74 69 6F 6E 20 +64 75 65 20 74 6F 20 48 57 5F 43 4F 4E 46 49 47 +00 00 00 00 44 4F 45 3A 20 43 6C 65 61 72 20 73 +65 63 72 65 74 73 00 00 45 43 43 20 66 6C 6F 77 +20 69 6E 20 70 72 6F 67 72 65 73 73 2E 2E 2E 00 +45 43 43 20 7A 65 72 6F 69 7A 65 20 66 6C 6F 77 +2E 00 00 00 0A 45 43 43 20 4B 45 59 47 45 4E 00 +57 61 69 74 20 66 6F 72 20 4B 56 20 77 72 69 74 +65 00 00 00 4C 6F 61 64 20 50 52 49 56 4B 45 59 +20 64 61 74 61 20 66 72 6F 6D 20 45 43 43 00 00 +4C 6F 61 64 20 50 55 42 4B 45 59 5F 58 20 64 61 +74 61 20 66 72 6F 6D 20 45 43 43 00 4C 6F 61 64 +20 50 55 42 4B 45 59 5F 59 20 64 61 74 61 20 66 +72 6F 6D 20 45 43 43 00 53 74 6F 72 65 20 50 55 +42 4B 45 59 5F 58 20 64 61 74 61 20 69 6E 20 45 +43 43 00 00 53 74 6F 72 65 20 50 55 42 4B 45 59 +5F 59 20 64 61 74 61 20 69 6E 20 45 43 43 00 00 +0A 45 43 43 20 53 48 41 52 45 44 4B 45 59 00 00 +4C 6F 61 64 20 53 48 41 52 45 44 4B 45 59 20 64 +61 74 61 20 66 72 6F 6D 20 45 43 43 00 00 00 00 +49 6E 6A 65 63 74 20 50 52 49 56 4B 45 59 20 66 +72 6F 6D 20 6B 76 20 74 6F 20 45 43 43 00 00 00 +0A 45 43 43 20 53 49 47 4E 49 4E 47 00 00 00 00 +4C 6F 61 64 20 53 49 47 4E 5F 52 20 64 61 74 61 +20 66 72 6F 6D 20 45 43 43 00 00 00 4C 6F 61 64 +20 53 49 47 4E 5F 53 20 64 61 74 61 20 66 72 6F +6D 20 45 43 43 00 00 00 0A 45 43 43 20 56 45 52 +49 46 59 49 4E 47 00 00 4C 6F 61 64 20 56 45 52 +49 46 59 5F 52 20 64 61 74 61 20 66 72 6F 6D 20 +45 43 43 00 0A 45 43 43 20 50 43 52 20 53 49 47 +4E 49 4E 47 00 00 00 00 4D 4C 44 53 41 20 66 6C +6F 77 20 69 6E 20 70 72 6F 67 72 65 73 73 2E 2E +2E 00 00 00 4D 4C 44 53 41 20 7A 65 72 6F 69 7A +65 20 66 6C 6F 77 2E 00 57 61 69 74 69 6E 67 20 +66 6F 72 20 6D 6C 64 73 61 20 73 74 61 74 75 73 +20 72 65 61 64 79 00 00 57 61 69 74 69 6E 67 20 +66 6F 72 20 6D 6C 64 73 61 20 73 74 61 74 75 73 +20 72 65 61 64 79 20 69 6E 20 6B 65 79 67 65 6E +00 00 00 00 54 72 79 20 74 6F 20 4F 76 65 72 77 +72 69 74 65 20 73 65 65 64 20 64 61 74 61 20 69 +6E 20 4D 4C 44 53 41 00 5B 4D 4C 44 53 41 20 4B +65 79 47 65 6E 5D 20 52 65 63 65 69 76 65 64 20 +65 78 70 65 63 74 65 64 20 65 72 72 20 66 6F 72 +20 4D 4C 44 53 41 20 73 65 65 64 20 72 65 61 64 +20 66 72 6F 6D 20 4B 56 00 00 00 00 5B 4D 4C 44 +53 41 20 4B 65 79 47 65 6E 5D 20 52 65 63 65 69 +76 65 64 20 75 6E 65 78 70 65 63 74 65 64 20 73 +75 63 63 65 73 73 20 66 6F 72 20 4D 4C 44 53 41 +20 73 65 65 64 20 72 65 61 64 20 66 72 6F 6D 20 +4B 56 00 00 57 72 69 74 69 6E 67 20 65 6E 74 72 +6F 70 79 00 0A 4D 4C 44 53 41 20 4B 45 59 47 45 +4E 00 00 00 4C 6F 61 64 20 50 52 49 56 4B 45 59 +20 64 61 74 61 20 66 72 6F 6D 20 4D 4C 44 53 41 +00 00 00 00 4C 6F 61 64 20 50 55 42 4B 45 59 20 +64 61 74 61 20 66 72 6F 6D 20 4D 4C 44 53 41 00 +5B 4D 4C 44 53 41 20 4B 65 79 47 65 6E 20 53 69 +67 6E 69 6E 67 5D 20 52 65 63 65 69 76 65 64 20 +65 78 70 65 63 74 65 64 20 65 72 72 20 66 6F 72 +20 4D 4C 44 53 41 20 73 65 65 64 20 72 65 61 64 +20 66 72 6F 6D 20 4B 56 00 00 00 00 5B 4D 4C 44 +53 41 20 4B 65 79 47 65 6E 20 53 69 67 6E 69 6E +67 5D 20 52 65 63 65 69 76 65 64 20 75 6E 65 78 +70 65 63 74 65 64 20 73 75 63 63 65 73 73 20 66 +6F 72 20 4D 4C 44 53 41 20 73 65 65 64 20 72 65 +61 64 20 66 72 6F 6D 20 4B 56 00 00 0A 4D 4C 44 +53 41 20 4B 45 59 47 45 4E 20 2B 20 53 49 47 4E +49 4E 47 00 4C 6F 61 64 20 53 49 47 4E 20 64 61 +74 61 20 66 72 6F 6D 20 4D 4C 44 53 41 00 00 00 +57 72 69 74 69 6E 67 20 70 72 69 76 6B 65 79 00 +57 72 69 74 69 6E 67 20 6D 73 67 00 0A 4D 4C 44 +53 41 20 53 49 47 4E 49 4E 47 00 00 0A 4D 4C 44 +53 41 20 56 45 52 49 46 59 49 4E 47 00 00 00 00 +4C 6F 61 64 20 56 45 52 49 46 59 5F 52 45 53 20 +64 61 74 61 20 66 72 6F 6D 20 4D 4C 44 53 41 00 +0A 4D 4C 44 53 41 20 4B 45 59 47 45 4E 20 2B 20 +53 49 47 4E 49 4E 47 20 69 6E 20 45 78 74 65 72 +6E 61 6C 4D 75 20 6D 6F 64 65 00 00 57 72 69 74 +69 6E 67 20 45 78 74 65 72 6E 61 6C 4D 75 00 00 +0A 4D 4C 44 53 41 20 53 49 47 4E 49 4E 47 20 69 +6E 20 45 78 74 65 72 6E 61 6C 4D 75 20 6D 6F 64 +65 00 00 00 0A 4D 4C 44 53 41 20 56 45 52 49 46 +59 49 4E 47 20 69 6E 20 45 78 74 65 72 6E 61 6C +4D 75 20 6D 6F 64 65 00 5B 4D 4C 4B 45 4D 5D 20 +57 61 69 74 69 6E 67 20 66 6F 72 20 69 6E 74 65 +72 72 75 70 74 00 00 00 5B 4D 4C 4B 45 4D 5D 20 +53 74 61 72 74 69 6E 67 20 7A 65 72 6F 69 7A 65 +00 00 00 00 5B 4D 4C 4B 45 4D 5D 20 57 61 69 74 +69 6E 67 20 66 6F 72 20 72 65 61 64 79 00 00 00 +5B 4D 4C 4B 45 4D 20 4B 65 79 47 65 6E 5D 20 57 +61 69 74 69 6E 67 20 66 6F 72 20 72 65 61 64 79 +00 00 00 00 5B 4D 4C 4B 45 4D 20 4B 65 79 47 65 +6E 5D 20 54 72 79 20 74 6F 20 4F 76 65 72 77 72 +69 74 65 20 73 65 65 64 20 64 20 64 61 74 61 00 +5B 4D 4C 4B 45 4D 20 4B 65 79 47 65 6E 5D 20 54 +72 79 20 74 6F 20 4F 76 65 72 77 72 69 74 65 20 +73 65 65 64 20 7A 20 64 61 74 61 00 5B 4D 4C 4B +45 4D 20 4B 65 79 47 65 6E 5D 20 52 65 63 65 69 +76 65 64 20 65 78 70 65 63 74 65 64 20 65 72 72 +20 66 6F 72 20 4D 4C 4B 45 4D 20 73 65 65 64 20 +72 65 61 64 20 66 72 6F 6D 20 4B 56 00 00 00 00 +5B 4D 4C 4B 45 4D 20 4B 65 79 47 65 6E 5D 20 52 +65 63 65 69 76 65 64 20 75 6E 65 78 70 65 63 74 +65 64 20 73 75 63 63 65 73 73 20 66 6F 72 20 4D +4C 4B 45 4D 20 73 65 65 64 20 72 65 61 64 20 66 +72 6F 6D 20 4B 56 00 00 5B 4D 4C 4B 45 4D 20 4B +65 79 47 65 6E 5D 20 57 72 69 74 69 6E 67 20 65 +6E 74 72 6F 70 79 00 00 5B 4D 4C 4B 45 4D 20 4B +65 79 47 65 6E 5D 20 53 65 6E 64 69 6E 67 20 63 +6F 6D 6D 61 6E 64 00 00 5B 4D 4C 4B 45 4D 20 4B +65 79 47 65 6E 5D 20 43 68 65 63 6B 69 6E 67 20 +65 6E 63 61 70 73 20 6B 65 79 00 00 5B 4D 4C 4B +45 4D 20 4B 65 79 47 65 6E 5D 20 43 68 65 63 6B +69 6E 67 20 64 65 63 61 70 73 20 6B 65 79 00 00 +5B 4D 4C 4B 45 4D 20 4B 65 79 47 65 6E 5D 20 43 +68 65 63 6B 20 74 68 61 74 20 53 45 45 44 5F 44 +20 61 70 69 20 68 61 73 20 30 73 00 5B 4D 4C 4B +45 4D 20 4B 65 79 47 65 6E 5D 20 43 68 65 63 6B +20 74 68 61 74 20 53 45 45 44 5F 5A 20 61 70 69 +20 68 61 73 20 30 73 00 5B 4D 4C 4B 45 4D 20 4B +65 79 47 65 6E 5D 20 52 65 61 64 20 45 6E 63 61 +70 73 20 4B 65 79 00 00 5B 4D 4C 4B 45 4D 20 4B +65 79 47 65 6E 5D 20 52 65 61 64 20 44 65 63 61 +70 73 20 4B 65 79 00 00 5B 4D 4C 4B 45 4D 20 4B +65 79 47 65 6E 5D 20 43 68 65 63 6B 20 74 68 61 +74 20 44 4B 20 61 70 69 20 68 61 73 20 30 73 00 +5B 4D 4C 4B 45 4D 20 45 6E 63 61 70 73 5D 20 57 +61 69 74 69 6E 67 20 66 6F 72 20 72 65 61 64 79 +00 00 00 00 5B 4D 4C 4B 45 4D 20 45 6E 63 61 70 +73 5D 20 57 72 69 74 69 6E 67 20 65 6E 63 61 70 +73 20 6B 65 79 00 00 00 5B 4D 4C 4B 45 4D 20 45 +6E 63 61 70 73 5D 20 54 72 79 20 74 6F 20 4F 76 +65 72 77 72 69 74 65 20 6D 73 67 00 5B 4D 4C 4B +45 4D 20 45 6E 63 61 70 73 5D 20 54 72 79 20 74 +6F 20 4F 76 65 72 77 72 69 74 65 20 6D 73 67 20 +74 68 72 6F 75 67 68 20 4D 4C 44 53 41 20 70 72 +69 76 6B 65 79 00 00 00 5B 4D 4C 4B 45 4D 20 4B +65 79 47 65 6E 5D 20 52 65 63 65 69 76 65 64 20 +65 78 70 65 63 74 65 64 20 65 72 72 20 66 6F 72 +20 4D 4C 4B 45 4D 20 6D 73 67 20 72 65 61 64 20 +66 72 6F 6D 20 4B 56 00 5B 4D 4C 4B 45 4D 20 4B +65 79 47 65 6E 5D 20 52 65 63 65 69 76 65 64 20 +75 6E 65 78 70 65 63 74 65 64 20 73 75 63 63 65 +73 73 20 66 6F 72 20 4D 4C 4B 45 4D 20 6D 73 67 +20 72 65 61 64 20 66 72 6F 6D 20 4B 56 00 00 00 +5B 4D 4C 4B 45 4D 20 45 6E 63 61 70 73 5D 20 43 +68 65 63 6B 20 74 68 61 74 20 4D 53 47 20 61 70 +69 20 68 61 73 20 30 73 00 00 00 00 5B 4D 4C 4B +45 4D 20 45 6E 63 61 70 73 5D 20 57 72 69 74 69 +6E 67 20 65 6E 74 72 6F 70 79 00 00 5B 4D 4C 4B +45 4D 20 45 6E 63 61 70 73 5D 20 53 65 6E 64 69 +6E 67 20 63 6F 6D 6D 61 6E 64 00 00 5B 4D 4C 4B +45 4D 20 45 6E 63 61 70 73 5D 20 43 68 65 63 6B +20 43 69 70 68 65 72 74 65 78 74 00 5B 4D 4C 4B +45 4D 20 45 6E 63 61 70 73 5D 20 52 65 63 65 69 +76 65 64 20 65 78 70 65 63 74 65 64 20 65 72 72 +20 66 6F 72 20 4D 4C 4B 45 4D 20 73 68 61 72 65 +64 6B 65 79 20 77 72 69 74 65 20 66 72 6F 6D 20 +4B 56 00 00 5B 4D 4C 4B 45 4D 20 45 6E 63 61 70 +73 5D 20 52 65 63 65 69 76 65 64 20 75 6E 65 78 +70 65 63 74 65 64 20 73 75 63 63 65 73 73 20 66 +6F 72 20 4D 4C 4B 45 4D 20 73 68 61 72 65 64 6B +65 79 20 77 72 69 74 65 20 66 72 6F 6D 20 4B 56 +00 00 00 00 5B 4D 4C 4B 45 4D 20 45 6E 63 61 70 +73 5D 20 52 65 63 65 69 76 65 64 20 75 6E 65 78 +70 65 63 74 65 64 20 65 72 72 20 66 6F 72 20 4D +4C 4B 45 4D 20 73 68 61 72 65 64 6B 65 79 20 77 +72 69 74 65 20 66 72 6F 6D 20 4B 56 00 00 00 00 +5B 4D 4C 4B 45 4D 20 45 6E 63 61 70 73 5D 20 52 +65 63 65 69 76 65 64 20 65 78 70 65 63 74 65 64 +20 73 75 63 63 65 73 73 20 66 6F 72 20 4D 4C 4B +45 4D 20 73 68 61 72 65 64 6B 65 79 20 77 72 69 +74 65 20 66 72 6F 6D 20 4B 56 00 00 5B 4D 4C 4B +45 4D 20 45 6E 63 61 70 73 5D 20 43 68 65 63 6B +20 53 68 61 72 65 64 20 4B 65 79 00 5B 4D 4C 4B +45 4D 20 45 6E 63 61 70 73 5D 20 4B 56 20 75 73 +65 64 2C 20 63 68 65 63 6B 20 53 68 61 72 65 64 +20 4B 65 79 20 69 73 20 30 00 00 00 5B 4D 4C 4B +45 4D 20 45 6E 63 61 70 73 5D 20 53 65 6E 64 69 +6E 67 20 43 6F 6D 6D 61 6E 64 00 00 5B 4D 4C 4B +45 4D 20 45 6E 63 61 70 73 5D 20 52 65 61 64 20 +43 69 70 68 65 72 74 65 78 74 00 00 5B 4D 4C 4B +45 4D 20 45 6E 63 61 70 73 5D 20 52 65 63 65 69 +76 65 64 20 75 6E 65 78 70 65 63 74 65 64 20 66 +61 69 6C 20 66 6F 72 20 4D 4C 4B 45 4D 20 73 68 +61 72 65 64 6B 65 79 20 77 72 69 74 65 20 66 72 +6F 6D 20 4B 56 00 00 00 5B 4D 4C 4B 45 4D 20 45 +6E 63 61 70 73 5D 20 52 65 61 64 20 53 68 61 72 +65 64 20 4B 65 79 00 00 5B 4D 4C 4B 45 4D 20 44 +65 63 61 70 73 5D 20 57 61 69 74 69 6E 67 20 66 +6F 72 20 72 65 61 64 79 00 00 00 00 5B 4D 4C 4B +45 4D 20 44 65 63 61 70 73 5D 20 57 72 69 74 69 +6E 67 20 64 65 63 61 70 73 20 6B 65 79 00 00 00 +5B 4D 4C 4B 45 4D 20 44 65 63 61 70 73 5D 20 57 +72 69 74 69 6E 67 20 65 6E 74 72 6F 70 79 00 00 +5B 4D 4C 4B 45 4D 20 44 65 63 61 70 73 5D 20 53 +65 6E 64 69 6E 67 20 63 6F 6D 6D 61 6E 64 00 00 +5B 4D 4C 4B 45 4D 20 44 65 63 61 70 73 5D 20 52 +65 63 65 69 76 65 64 20 65 78 70 65 63 74 65 64 +20 65 72 72 20 66 6F 72 20 4D 4C 4B 45 4D 20 73 +68 61 72 65 64 6B 65 79 20 77 72 69 74 65 20 66 +72 6F 6D 20 4B 56 00 00 5B 4D 4C 4B 45 4D 20 44 +65 63 61 70 73 5D 20 52 65 63 65 69 76 65 64 20 +75 6E 65 78 70 65 63 74 65 64 20 73 75 63 63 65 +73 73 20 66 6F 72 20 4D 4C 4B 45 4D 20 73 68 61 +72 65 64 6B 65 79 20 77 72 69 74 65 20 66 72 6F +6D 20 4B 56 00 00 00 00 5B 4D 4C 4B 45 4D 20 44 +65 63 61 70 73 5D 20 52 65 63 65 69 76 65 64 20 +75 6E 65 78 70 65 63 74 65 64 20 66 61 69 6C 20 +66 6F 72 20 4D 4C 4B 45 4D 20 73 68 61 72 65 64 +6B 65 79 20 77 72 69 74 65 20 66 72 6F 6D 20 4B +56 00 00 00 5B 4D 4C 4B 45 4D 20 44 65 63 61 70 +73 5D 20 52 65 63 65 69 76 65 64 20 65 78 70 65 +63 74 65 64 20 73 75 63 63 65 73 73 20 66 6F 72 +20 4D 4C 4B 45 4D 20 73 68 61 72 65 64 6B 65 79 +20 77 72 69 74 65 20 66 72 6F 6D 20 4B 56 00 00 +5B 4D 4C 4B 45 4D 20 44 65 63 61 70 73 5D 20 4B +56 20 75 73 65 64 2C 20 63 68 65 63 6B 20 53 68 +61 72 65 64 20 4B 65 79 20 69 73 20 30 00 00 00 +5B 4D 4C 4B 45 4D 20 44 65 63 61 70 73 5D 20 43 +68 65 63 6B 20 53 68 61 72 65 64 20 4B 65 79 00 +5B 4D 4C 4B 45 4D 20 44 65 63 61 70 73 5D 20 52 +65 63 65 69 76 65 64 20 65 78 70 65 63 74 65 64 +20 65 72 72 20 66 6F 72 20 4D 4C 4B 45 4D 20 73 +68 61 72 65 64 6B 65 79 20 72 65 61 64 20 66 72 +6F 6D 20 4B 56 00 00 00 5B 4D 4C 4B 45 4D 20 44 +65 63 61 70 73 5D 20 52 65 63 65 69 76 65 64 20 +75 6E 65 78 70 65 63 74 65 64 20 73 75 63 63 65 +73 73 20 66 6F 72 20 4D 4C 4B 45 4D 20 73 68 61 +72 65 64 6B 65 79 20 72 65 61 64 20 66 72 6F 6D +20 4B 56 00 5B 4D 4C 4B 45 4D 20 44 65 63 61 70 +73 5D 20 52 65 61 64 20 53 68 61 72 65 64 20 4B +65 79 00 00 5B 4D 4C 4B 45 4D 20 4B 65 79 47 65 +6E 20 44 65 63 61 70 73 5D 20 57 61 69 74 69 6E +67 20 66 6F 72 20 72 65 61 64 79 00 5B 4D 4C 4B +45 4D 20 4B 65 79 47 65 6E 20 44 65 63 61 70 73 +5D 20 54 72 79 20 74 6F 20 4F 76 65 72 77 72 69 +74 65 20 73 65 65 64 20 64 00 00 00 5B 4D 4C 4B +45 4D 20 4B 65 79 47 65 6E 20 44 65 63 61 70 73 +5D 20 54 72 79 20 74 6F 20 4F 76 65 72 77 72 69 +74 65 20 73 65 65 64 20 7A 00 00 00 5B 4D 4C 4B +45 4D 20 4B 65 79 47 65 6E 20 44 65 63 61 70 73 +5D 20 57 72 69 74 69 6E 67 20 65 6E 74 72 6F 70 +79 00 00 00 5B 4D 4C 4B 45 4D 20 4B 65 79 47 65 +6E 20 44 65 63 61 70 73 5D 20 53 65 6E 64 69 6E +67 20 63 6F 6D 6D 61 6E 64 00 00 00 5B 4D 4C 4B +45 4D 20 4B 65 79 47 65 6E 20 44 65 63 61 70 73 +5D 20 52 65 63 65 69 76 65 64 20 65 78 70 65 63 +74 65 64 20 65 72 72 20 66 6F 72 20 4D 4C 4B 45 +4D 20 73 68 61 72 65 64 6B 65 79 20 77 72 69 74 +65 20 66 72 6F 6D 20 4B 56 00 00 00 5B 4D 4C 4B +45 4D 20 4B 65 79 47 65 6E 20 44 65 63 61 70 73 +5D 20 52 65 63 65 69 76 65 64 20 75 6E 65 78 70 +65 63 74 65 64 20 73 75 63 63 65 73 73 20 66 6F +72 20 4D 4C 4B 45 4D 20 73 68 61 72 65 64 6B 65 +79 20 77 72 69 74 65 20 66 72 6F 6D 20 4B 56 00 +5B 4D 4C 4B 45 4D 20 4B 65 79 47 65 6E 20 44 65 +63 61 70 73 5D 20 52 65 63 65 69 76 65 64 20 75 +6E 65 78 70 65 63 74 65 64 20 66 61 69 6C 20 66 +6F 72 20 4D 4C 4B 45 4D 20 73 68 61 72 65 64 6B +65 79 20 77 72 69 74 65 20 66 72 6F 6D 20 4B 56 +00 00 00 00 5B 4D 4C 4B 45 4D 20 4B 65 79 47 65 +6E 20 44 65 63 61 70 73 5D 20 52 65 63 65 69 76 +65 64 20 65 78 70 65 63 74 65 64 20 73 75 63 63 +65 73 73 20 66 6F 72 20 4D 4C 4B 45 4D 20 73 68 +61 72 65 64 6B 65 79 20 77 72 69 74 65 20 66 72 +6F 6D 20 4B 56 00 00 00 5B 4D 4C 4B 45 4D 20 4B +65 79 47 65 6E 20 44 65 63 61 70 73 5D 20 43 68 +65 63 6B 20 53 68 61 72 65 64 20 4B 65 79 00 00 +5B 4D 4C 4B 45 4D 20 4B 65 79 47 65 6E 20 44 65 +63 61 70 73 5D 20 4B 56 20 75 73 65 64 2C 20 63 +68 65 63 6B 20 53 68 61 72 65 64 20 4B 65 79 20 +69 73 20 30 00 00 00 00 5B 4D 4C 4B 45 4D 20 4B +65 79 47 65 6E 20 44 65 63 61 70 73 5D 20 52 65 +61 64 20 53 68 61 72 65 64 20 4B 65 79 00 00 00 +48 4D 41 43 20 66 6C 6F 77 20 69 6E 20 70 72 6F +67 72 65 73 73 2E 2E 2E 00 00 00 00 48 4D 41 43 +20 7A 65 72 6F 69 7A 65 20 66 6C 6F 77 2E 00 00 +54 72 79 20 74 6F 20 4F 76 65 72 77 72 69 74 65 +20 4B 65 79 20 64 61 74 61 20 69 6E 20 48 4D 41 +43 33 38 34 00 00 00 00 52 65 63 65 69 76 65 64 +20 65 78 70 65 63 74 65 64 20 65 72 72 20 66 6F +72 20 48 4D 41 43 20 6B 65 79 20 72 65 61 64 20 +66 72 6F 6D 20 4B 56 20 77 68 69 6C 65 20 4F 43 +50 20 6C 6F 63 6B 20 69 6E 20 70 72 6F 67 72 65 +73 73 00 00 52 65 63 65 69 76 65 64 20 75 6E 65 +78 70 65 63 74 65 64 20 73 75 63 63 65 73 73 20 +66 6F 72 20 48 4D 41 43 20 6B 65 79 20 72 65 61 +64 20 66 72 6F 6D 20 4B 56 20 77 68 69 6C 65 20 +4F 43 50 20 6C 6F 63 6B 20 69 6E 20 70 72 6F 67 +72 65 73 73 00 00 00 00 4C 6F 61 64 20 4B 65 79 +20 64 61 74 61 20 74 6F 20 48 4D 41 43 00 00 00 +54 72 79 20 74 6F 20 4F 76 65 72 77 72 69 74 65 +20 42 6C 6F 63 6B 20 64 61 74 61 20 69 6E 20 48 +4D 41 43 00 52 65 63 65 69 76 65 64 20 65 78 70 +65 63 74 65 64 20 65 72 72 20 66 6F 72 20 48 4D +41 43 20 62 6C 6F 63 6B 20 72 65 61 64 20 66 72 +6F 6D 20 4B 56 20 77 68 69 6C 65 20 4F 43 50 20 +6C 6F 63 6B 20 69 6E 20 70 72 6F 67 72 65 73 73 +00 00 00 00 52 65 63 65 69 76 65 64 20 75 6E 65 +78 70 65 63 74 65 64 20 73 75 63 63 65 73 73 20 +66 6F 72 20 48 4D 41 43 20 62 6C 6F 63 6B 20 72 +65 61 64 20 66 72 6F 6D 20 4B 56 20 77 68 69 6C +65 20 4F 43 50 20 6C 6F 63 6B 20 69 6E 20 70 72 +6F 67 72 65 73 73 00 00 4C 6F 61 64 20 54 41 47 +20 64 61 74 61 20 66 72 6F 6D 20 48 4D 41 43 20 +74 6F 20 4B 56 00 00 00 4C 6F 61 64 20 54 41 47 +20 64 61 74 61 20 66 72 6F 6D 20 48 4D 41 43 00 +54 72 79 20 74 6F 20 4F 76 65 72 77 72 69 74 65 +20 4B 65 79 20 64 61 74 61 20 69 6E 20 48 4D 41 +43 35 31 32 00 00 00 00 4B 56 3A 20 63 68 65 63 +6B 69 6E 67 20 66 6F 72 20 65 72 72 6F 72 73 00 +4B 56 20 45 52 52 4F 52 00 00 00 00 4B 56 3A 20 +63 68 65 63 6B 69 6E 67 20 65 72 72 6F 72 73 20 +70 72 65 73 65 6E 74 00 4E 4F 20 4B 56 20 45 52 +52 4F 52 00 4B 56 3A 20 70 72 6F 67 20 6B 76 20 +72 65 61 64 20 63 74 72 6C 00 00 00 4B 56 3A 20 +70 72 6F 67 20 6B 76 20 77 72 69 74 65 20 63 74 +72 6C 00 00 50 56 3A 20 70 72 6F 67 20 6B 76 20 +72 65 61 64 20 63 74 72 6C 20 69 6E 20 53 48 41 +20 74 6F 20 64 6F 20 68 61 73 68 20 65 78 74 65 +6E 64 00 00 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D +2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D +2D 2D 2D 00 53 54 49 43 4B 59 44 41 54 41 56 41 +55 4C 54 43 54 52 4C 00 53 54 49 43 4B 59 5F 44 +41 54 41 5F 56 41 55 4C 54 5F 45 4E 54 52 59 5F +30 00 00 00 53 54 49 43 4B 59 5F 44 41 54 41 5F +56 41 55 4C 54 5F 45 4E 54 52 59 5F 31 00 00 00 +53 54 49 43 4B 59 5F 44 41 54 41 5F 56 41 55 4C +54 5F 45 4E 54 52 59 5F 32 00 00 00 53 54 49 43 +4B 59 5F 44 41 54 41 5F 56 41 55 4C 54 5F 45 4E +54 52 59 5F 33 00 00 00 53 54 49 43 4B 59 5F 44 +41 54 41 5F 56 41 55 4C 54 5F 45 4E 54 52 59 5F +34 00 00 00 53 54 49 43 4B 59 5F 44 41 54 41 5F +56 41 55 4C 54 5F 45 4E 54 52 59 5F 35 00 00 00 +53 54 49 43 4B 59 5F 44 41 54 41 5F 56 41 55 4C +54 5F 45 4E 54 52 59 5F 36 00 00 00 53 54 49 43 +4B 59 5F 44 41 54 41 5F 56 41 55 4C 54 5F 45 4E +54 52 59 5F 37 00 00 00 53 54 49 43 4B 59 5F 44 +41 54 41 5F 56 41 55 4C 54 5F 45 4E 54 52 59 5F +38 00 00 00 53 54 49 43 4B 59 5F 44 41 54 41 5F +56 41 55 4C 54 5F 45 4E 54 52 59 5F 39 00 00 00 +44 41 54 41 56 41 55 4C 54 43 54 52 4C 00 00 00 +44 41 54 41 5F 56 41 55 4C 54 5F 45 4E 54 52 59 +5F 30 00 00 44 41 54 41 5F 56 41 55 4C 54 5F 45 +4E 54 52 59 5F 31 00 00 44 41 54 41 5F 56 41 55 +4C 54 5F 45 4E 54 52 59 5F 32 00 00 44 41 54 41 +5F 56 41 55 4C 54 5F 45 4E 54 52 59 5F 33 00 00 +44 41 54 41 5F 56 41 55 4C 54 5F 45 4E 54 52 59 +5F 34 00 00 44 41 54 41 5F 56 41 55 4C 54 5F 45 +4E 54 52 59 5F 35 00 00 44 41 54 41 5F 56 41 55 +4C 54 5F 45 4E 54 52 59 5F 36 00 00 44 41 54 41 +5F 56 41 55 4C 54 5F 45 4E 54 52 59 5F 37 00 00 +44 41 54 41 5F 56 41 55 4C 54 5F 45 4E 54 52 59 +5F 38 00 00 44 41 54 41 5F 56 41 55 4C 54 5F 45 +4E 54 52 59 5F 39 00 00 4C 4F 43 4B 41 42 4C 45 +5F 53 43 52 41 54 43 48 52 45 47 5F 43 54 52 4C +00 00 00 00 4C 4F 43 4B 41 42 4C 45 5F 53 43 52 +41 54 43 48 52 45 47 00 4E 4F 4E 53 54 49 43 4B +59 5F 47 45 4E 45 52 49 43 5F 53 43 52 41 54 43 +48 52 45 47 00 00 00 00 53 54 49 43 4B 59 5F 4C +4F 43 4B 41 42 4C 45 5F 53 43 52 41 54 43 48 52 +45 47 5F 43 54 52 4C 00 53 54 49 43 4B 59 5F 4C +4F 43 4B 41 42 4C 45 5F 53 43 52 41 54 43 48 52 +45 47 00 00 53 48 41 32 35 36 20 66 6C 6F 77 20 +69 6E 20 70 72 6F 67 72 65 73 73 2E 2E 2E 00 00 +53 48 41 32 35 36 20 7A 65 72 6F 69 7A 65 20 66 +6C 6F 77 2E 00 00 00 00 45 6E 61 62 6C 65 20 53 +48 41 32 35 36 00 00 00 4C 6F 61 64 20 44 49 47 +45 53 54 20 64 61 74 61 20 66 72 6F 6D 20 53 48 +41 32 35 36 00 00 00 00 45 72 72 6F 72 31 20 69 +73 20 65 78 70 65 63 74 65 64 20 77 68 65 6E 20 +69 6E 69 74 20 61 6E 64 20 6E 65 78 74 20 61 72 +65 20 61 73 73 65 72 74 65 64 20 61 74 20 74 68 +65 20 73 61 6D 65 20 74 69 6D 65 2E 20 43 68 65 +63 6B 20 61 72 67 73 20 67 69 76 65 6E 20 74 6F +20 73 68 61 32 35 36 5F 65 72 72 6F 72 5F 66 6C +6F 77 28 29 00 00 00 00 45 72 72 6F 72 30 20 69 +73 20 65 78 70 65 63 74 65 64 20 66 6F 72 20 69 +6E 76 61 6C 69 64 20 77 6E 74 7A 5F 6D 6F 64 65 +20 6F 72 20 77 2E 20 43 68 65 63 6B 20 61 72 67 +73 20 67 69 76 65 6E 20 74 6F 20 73 68 61 32 35 +36 5F 65 72 72 6F 72 5F 66 6C 6F 77 28 29 00 00 +53 48 41 35 31 32 20 66 6C 6F 77 20 69 6E 20 70 +72 6F 67 72 65 73 73 2E 2E 2E 00 00 53 48 41 35 +31 32 3A 20 53 65 74 20 53 54 41 52 54 20 66 6F +72 20 67 65 6E 20 68 61 73 68 20 66 75 6E 63 00 +53 48 41 35 31 32 20 7A 65 72 6F 69 7A 65 20 66 +6C 6F 77 2E 00 00 00 00 45 6E 61 62 6C 65 20 53 +48 41 35 31 32 00 00 00 4C 6F 61 64 20 44 49 47 +45 53 54 20 64 61 74 61 20 66 72 6F 6D 20 53 48 +41 35 31 32 00 00 00 00 64 69 66 5F 6B 6D 61 63 +5F 63 75 73 74 6F 6D 69 7A 61 74 69 6F 6E 5F 73 +74 72 69 6E 67 5F 69 6E 69 74 3A 20 45 52 52 4F +52 20 64 61 74 61 20 61 6E 64 20 6F 75 74 20 61 +72 67 75 6D 65 6E 74 73 20 6D 75 73 74 20 6E 6F +74 20 62 65 20 6E 75 6C 6C 2E 00 00 64 69 66 5F +6B 6D 61 63 5F 63 75 73 74 6F 6D 69 7A 61 74 69 +6F 6E 5F 73 74 72 69 6E 67 5F 69 6E 69 74 3A 20 +45 52 52 4F 52 20 6C 65 6E 67 74 68 20 67 72 65 +61 74 65 72 20 74 68 61 6E 20 6D 61 78 69 6D 75 +6D 2E 00 00 64 69 66 5F 6B 6D 61 63 5F 66 75 6E +63 74 69 6F 6E 5F 6E 61 6D 65 5F 69 6E 69 74 3A +20 45 52 52 4F 52 20 64 61 74 61 20 61 6E 64 20 +6F 75 74 20 6D 75 73 74 20 6E 6F 74 20 62 65 20 +4E 55 4C 4C 2E 00 00 00 64 69 66 5F 6B 6D 61 63 +5F 66 75 6E 63 74 69 6F 6E 5F 6E 61 6D 65 5F 69 +6E 69 74 3A 20 45 52 52 4F 52 20 6C 65 6E 67 74 +68 20 6C 61 72 67 65 72 20 74 68 61 6E 20 6D 61 +78 69 6D 75 6D 2E 00 00 64 69 66 5F 6B 6D 61 63 +5F 6D 6F 64 65 5F 73 68 61 33 5F 73 74 61 72 74 +3A 20 45 52 52 4F 52 20 6B 6D 61 63 20 6F 72 20 +6F 70 65 72 61 74 69 6F 6E 5F 73 74 61 74 65 20 +4E 55 4C 4C 2E 00 00 00 64 69 66 5F 6B 6D 61 63 +5F 73 68 61 33 5F 73 74 61 72 74 3A 20 45 52 52 +4F 52 20 55 6E 73 75 70 70 6F 72 74 65 64 20 6D +6F 64 65 2E 00 00 00 00 64 69 66 5F 6B 6D 61 63 +5F 73 68 61 33 5F 73 74 61 72 74 3A 20 45 52 52 +4F 52 20 68 61 72 64 77 61 72 65 20 6D 75 73 74 +20 62 65 20 69 64 6C 65 2E 00 00 00 64 69 66 5F +6B 6D 61 63 5F 6D 6F 64 65 5F 73 68 61 6B 65 5F +73 74 61 72 74 3A 20 45 52 52 4F 52 20 6B 6D 61 +63 20 61 6E 64 20 6F 70 65 72 61 74 69 6F 6E 20 +73 74 61 74 65 20 63 61 6E 6E 6F 74 20 62 65 20 +4E 55 4C 4C 2E 00 00 00 64 69 66 5F 6B 6D 61 63 +5F 6D 6F 64 65 5F 73 68 61 6B 65 5F 73 74 61 72 +74 3A 20 45 52 52 4F 52 20 6D 6F 64 65 20 6E 6F +74 20 61 6C 6C 6F 77 65 64 2E 00 00 64 69 66 5F +6B 6D 61 63 5F 73 68 61 6B 65 5F 73 74 61 72 74 +3A 20 45 52 52 4F 52 20 68 61 72 64 77 61 72 65 +20 6D 75 73 74 20 62 65 20 69 64 6C 65 2E 00 00 +64 69 66 5F 6B 6D 61 63 5F 6D 6F 64 65 5F 63 73 +68 61 6B 65 5F 73 74 61 72 74 3A 20 45 52 52 4F +52 20 6B 6D 61 63 20 6F 72 20 6F 70 65 72 61 74 +69 6F 6E 20 73 74 61 74 65 20 69 73 20 4E 55 4C +4C 2E 00 00 64 69 66 5F 6B 6D 61 63 5F 6D 6F 64 +65 5F 63 73 68 61 6B 65 5F 73 74 61 72 74 3A 20 +45 52 52 4F 52 20 75 6E 73 75 70 70 6F 72 74 65 +64 20 6D 6F 64 65 20 66 6F 72 20 65 6D 70 74 79 +20 4E 20 61 6E 64 20 53 2E 00 00 00 64 69 66 5F +6B 6D 61 63 5F 6D 6F 64 65 5F 63 73 68 61 6B 65 +5F 73 74 61 72 74 3A 20 45 52 52 4F 52 20 75 6E +73 75 70 70 6F 72 74 65 64 20 6B 73 74 72 65 6E +67 68 74 2E 00 00 00 00 64 69 66 5F 6B 6D 61 63 +5F 6D 6F 64 65 5F 63 73 68 61 6B 65 5F 73 74 61 +72 74 3A 20 45 52 52 4F 52 20 68 61 72 64 77 61 +72 65 20 6D 75 73 74 20 62 65 20 69 64 6C 65 2E +00 00 00 00 64 69 66 5F 6B 6D 61 63 5F 61 62 73 +6F 72 62 3A 20 45 52 52 4F 52 20 6F 6E 65 20 6F +66 20 66 75 6E 63 74 69 6F 6E 20 61 72 67 75 6D +65 6E 74 73 20 69 73 20 6E 75 6C 6C 00 00 00 00 +64 69 66 5F 6B 6D 61 63 5F 61 62 73 6F 72 62 3A +20 45 52 52 4F 52 20 6F 70 65 72 61 74 69 6F 6E +20 6E 6F 74 20 73 74 61 72 74 65 64 20 79 65 74 +00 00 00 00 64 69 66 5F 6B 6D 61 63 5F 61 62 73 +6F 72 62 3A 20 45 52 52 4F 52 20 68 61 72 64 77 +61 72 65 20 6D 75 73 74 20 62 65 20 61 62 73 6F +72 62 69 6E 67 2E 00 00 64 69 66 5F 6B 6D 61 63 +5F 73 71 75 65 65 7A 65 3A 20 45 52 52 4F 52 20 +61 72 67 75 6D 65 6E 74 73 20 6D 61 79 20 6E 6F +74 20 62 65 20 4E 55 4C 4C 2E 00 00 64 69 66 5F +6B 6D 61 63 5F 73 71 75 65 65 7A 65 3A 20 45 52 +52 4F 52 20 74 6F 74 61 6C 20 62 79 74 65 73 20 +72 65 71 75 65 73 74 65 64 20 6D 75 73 74 20 6E +6F 74 20 65 78 63 65 65 64 20 66 69 78 65 64 20 +6F 75 74 70 75 74 20 6C 65 6E 67 74 68 2E 00 00 +64 69 66 5F 6B 6D 61 63 5F 73 71 75 65 65 7A 65 +3A 20 45 52 52 4F 52 20 6F 70 65 72 61 74 69 6F +6E 20 73 74 61 74 65 20 64 20 6C 65 73 73 20 74 +68 61 6E 20 72 2E 00 00 64 69 66 5F 6B 6D 61 63 +5F 65 6E 64 3A 20 45 52 52 4F 52 20 61 72 67 75 +6D 65 6E 74 73 20 6D 61 79 20 6E 6F 74 20 62 65 +20 4E 55 4C 4C 2E 00 00 64 69 66 5F 6B 6D 61 63 +5F 65 6E 64 3A 20 45 52 52 4F 52 20 68 61 72 64 +77 61 72 65 20 6D 75 73 74 20 62 65 20 64 6F 6E +65 20 73 71 75 65 65 7A 69 6E 67 2E 00 00 00 00 +53 4F 43 5F 49 46 43 3A 20 43 68 65 63 6B 20 6D +62 6F 78 5F 73 74 61 74 75 73 2E 6D 62 6F 78 5F +66 73 6D 5F 70 73 00 00 53 4F 43 5F 49 46 43 3A +20 43 68 65 63 6B 20 6D 62 6F 78 5F 73 74 61 74 +75 73 2E 6D 62 6F 78 5F 66 73 6D 5F 70 73 20 66 +6F 75 6E 64 20 4D 42 4F 58 5F 45 58 45 43 55 54 +45 5F 55 43 00 00 00 00 53 4F 43 5F 49 46 43 3A +20 43 68 65 63 6B 20 6D 62 6F 78 5F 73 74 61 74 +75 73 2E 6D 62 6F 78 5F 66 73 6D 5F 70 73 20 66 +6F 75 6E 64 20 4D 42 4F 58 5F 49 44 4C 45 00 00 +53 4F 43 5F 49 46 43 3A 20 43 68 65 63 6B 20 6D +62 6F 78 5F 73 74 61 74 75 73 2E 6D 62 6F 78 5F +66 73 6D 5F 70 73 20 66 6F 75 6E 64 20 4D 42 4F +58 5F 45 52 52 4F 52 2C 20 6D 61 69 6C 62 6F 78 +20 66 6F 72 63 65 2D 75 6E 6C 6F 63 6B 20 6E 65 +65 64 65 64 00 00 00 00 53 4F 43 5F 49 46 43 3A +20 42 65 67 69 6E 6E 69 6E 67 20 6D 62 6F 78 20 +66 77 20 66 6C 6F 77 00 53 4F 43 5F 49 46 43 3A +20 43 70 20 74 6F 20 49 43 43 4D 00 53 4F 43 5F +49 46 43 3A 20 43 70 20 74 6F 20 44 43 43 4D 00 +43 6F 70 79 69 6E 67 20 63 6F 64 65 20 66 72 6F +6D 20 6D 61 69 6C 62 6F 78 20 74 6F 20 49 43 43 +4D 00 00 00 46 61 69 6C 65 64 20 74 6F 20 61 63 +71 75 69 72 65 20 6C 6F 63 6B 20 2D 20 6D 62 6F +78 20 73 61 6E 69 74 69 7A 65 00 00 77 6F 6E 27 +74 20 6F 76 65 72 72 69 64 65 00 00 77 69 6C 6C +20 75 73 65 20 64 65 66 61 75 6C 74 20 35 00 00 +77 69 6C 6C 20 6F 76 65 72 72 69 64 65 00 00 00 +46 41 54 41 4C 3A 20 41 58 49 20 44 4D 41 20 72 +65 70 6F 72 74 73 20 65 72 72 6F 72 20 73 74 61 +74 75 73 20 66 6F 72 20 78 66 65 72 00 00 00 00 +41 58 49 20 44 4D 41 20 72 65 70 6F 72 74 73 20 +73 74 61 74 75 73 20 66 6F 72 20 78 66 65 72 20 +74 68 61 74 20 77 6F 75 6C 64 20 72 65 71 75 69 +72 65 20 44 4D 41 20 46 6C 75 73 68 00 00 00 00 +41 58 49 20 44 4D 41 20 64 69 64 20 6E 6F 74 20 +72 65 70 6F 72 74 20 65 72 72 20 73 74 61 74 75 +73 20 66 6F 72 20 78 66 65 72 20 74 68 61 74 20 +77 6F 75 6C 64 20 72 65 71 75 69 72 65 20 44 4D +41 20 46 6C 75 73 68 00 41 63 71 75 69 72 65 20 +6D 61 69 6C 62 6F 78 20 6C 6F 63 6B 20 66 61 69 +6C 65 64 00 46 41 54 41 4C 3A 20 41 58 49 20 44 +4D 41 20 72 65 70 6F 72 74 73 20 65 72 72 6F 72 +20 73 74 61 74 75 73 20 66 6F 72 20 4D 42 4F 58 +2D 74 6F 2D 41 58 49 20 78 66 65 72 00 00 00 00 +46 57 3A 20 53 65 6E 64 69 6E 67 20 4B 56 20 74 +6F 20 41 58 49 20 77 69 74 68 20 45 52 52 00 00 +41 58 49 20 44 4D 41 20 72 65 70 6F 72 74 73 20 +65 72 72 20 73 74 61 74 75 73 20 66 6F 72 20 65 +72 72 20 69 6E 6A 65 63 74 69 6F 6E 20 78 66 65 +72 00 00 00 46 41 54 41 4C 3A 20 41 58 49 20 44 +4D 41 20 72 65 70 6F 72 74 73 20 73 75 63 63 65 +73 73 20 73 74 61 74 75 73 20 66 6F 72 20 65 72 +72 20 69 6E 6A 65 63 74 69 6F 6E 20 78 66 65 72 +21 00 00 00 46 57 3A 20 53 65 6E 64 69 6E 67 20 +4B 56 20 74 6F 20 41 58 49 00 00 00 46 57 3A 20 +41 72 6D 20 65 72 72 20 63 6F 6D 6D 61 6E 64 00 +45 6E 20 69 6E 74 20 74 6D 72 30 2C 20 68 6C 74 +20 63 6F 72 65 00 00 00 44 69 73 61 62 6C 69 6E +67 20 62 6F 74 68 20 74 69 6D 65 72 73 20 69 6E +20 69 6E 64 65 70 65 6E 64 65 6E 74 20 6D 6F 64 +65 00 00 00 45 6E 61 62 6C 69 6E 67 20 6F 6E 6C +79 20 74 69 6D 65 72 32 20 69 6E 20 69 6E 64 65 +70 65 6E 64 65 6E 74 20 6D 6F 64 65 00 00 00 00 +45 6E 61 62 6C 69 6E 67 20 62 6F 74 68 20 74 69 +6D 65 72 73 20 69 6E 20 69 6E 64 65 70 65 6E 64 +65 6E 74 20 6D 6F 64 65 00 00 00 00 A0 05 02 50 +A0 05 02 50 +@00013B30 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +@00015B30 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +@00017B30 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 diff --git a/designs/Caliptra/tests/hmac/dccm.hex b/designs/Caliptra/tests/hmac/dccm.hex new file mode 100644 index 0000000..7b0b5ff --- /dev/null +++ b/designs/Caliptra/tests/hmac/dccm.hex @@ -0,0 +1,7364 @@ +@00023458 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 70 15 00 00 80 14 00 00 +D0 22 00 00 90 13 00 00 92 21 00 00 A0 12 00 00 +54 20 00 00 B0 11 00 00 C0 10 00 00 D0 0F 00 00 +16 1F 00 00 E0 0E 00 00 D8 1D 00 00 F0 17 00 00 +F0 17 00 00 F0 17 00 00 F0 17 00 00 F0 0D 00 00 +00 0D 00 00 B6 1B 00 00 94 19 00 00 10 0C 00 00 +56 18 00 00 20 0B 00 00 30 0A 00 00 EA 16 00 00 +E4 15 00 00 F0 17 00 00 F0 17 00 00 F0 17 00 00 +F0 17 00 00 F0 17 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 EF BE AD DE +@00030004 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +@00032004 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +@00034004 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +@00036004 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +@00038004 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +@0003A004 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +@0003C004 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +@0003E004 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 diff --git a/designs/Caliptra/tests/hmac/iccm.hex b/designs/Caliptra/tests/hmac/iccm.hex new file mode 100644 index 0000000..e69de29 diff --git a/designs/Caliptra/tests/hmac/mailbox.hex b/designs/Caliptra/tests/hmac/mailbox.hex new file mode 100644 index 0000000..e69de29 diff --git a/designs/Caliptra/tests/hmac/program.hex b/designs/Caliptra/tests/hmac/program.hex new file mode 100644 index 0000000..6b46130 --- /dev/null +++ b/designs/Caliptra/tests/hmac/program.hex @@ -0,0 +1,6147 @@ +@00000000 +73 10 20 B0 73 10 20 B8 B7 A2 AA AA 93 82 92 0A +73 90 02 7C 91 42 0F 10 00 00 73 90 92 7F 0F 10 +00 00 97 02 00 00 93 82 A2 14 73 90 52 30 97 12 +01 00 93 82 62 27 17 43 01 00 13 03 63 58 97 03 +02 50 93 83 23 FC 63 FA 62 00 03 AE 02 00 23 A0 +C3 01 91 02 91 03 E3 EA 62 FE 97 42 01 00 93 82 +22 56 17 43 01 00 13 03 A3 69 97 33 02 50 93 83 +E3 2A 63 FA 62 00 03 AE 02 00 23 A0 C3 01 91 02 +91 03 E3 EA 62 FE 17 41 03 50 13 01 A1 F8 81 22 +B7 02 03 30 93 82 C2 0C 13 0F F0 0F 23 A0 E2 01 +E3 08 00 FE 01 00 01 00 01 00 01 00 01 00 01 00 +01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00 +01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00 +01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00 +01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00 +01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00 +01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00 +01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00 +01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00 +01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00 +01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00 +01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00 +01 00 01 00 01 00 01 00 01 00 01 00 F3 22 20 34 +73 23 10 34 F3 23 30 34 37 0E 03 30 13 0E CE 0C +97 0E 02 50 93 8E 0E E8 83 82 0E 00 23 20 5E 00 +85 0E E3 9B 02 FE 05 4F 23 20 EE 01 C1 BF 00 00 +49 74 65 72 61 74 69 6F 6E 20 25 30 75 20 6F 66 +20 25 30 75 0A 00 00 00 49 74 65 72 61 74 69 6F +6E 20 25 30 75 20 6F 66 20 25 30 75 0A 00 13 01 +01 9A 13 06 00 07 81 45 48 0D 23 2E 11 64 23 2C +81 64 23 20 61 65 23 2A 91 64 23 28 21 65 23 26 +31 65 23 24 41 65 23 22 51 65 23 2E 71 63 23 2C +81 63 23 2A 91 63 23 28 A1 63 23 26 B1 63 EF 00 +91 0B B7 27 69 48 93 87 47 05 23 24 F1 28 B7 77 +65 68 93 87 57 26 23 26 F1 28 B7 07 00 80 23 28 +F1 28 13 05 F0 07 93 07 00 44 23 22 F1 30 37 0B +02 50 EF 20 50 67 83 27 0B 14 09 44 63 6F F4 6C +EF 20 E0 1B B7 07 03 50 93 87 07 00 3E CC 9C 43 +63 87 07 72 1C 0F 3E C8 7C 07 3E C4 93 07 01 41 +3E C2 B7 77 D5 6E 93 87 C7 C1 3E CA B7 17 9E 3C +93 87 B7 6F 3E CE B7 F7 0A 80 93 87 47 50 3E D0 +B7 D7 A8 B6 93 87 37 56 3E D2 B7 77 5C 6F 93 09 +01 1F 13 0A C1 40 93 0A 01 49 81 4F 37 13 0B 0B +B7 23 F5 C8 B7 22 AA F3 93 87 27 A7 4E C6 13 0F +81 30 D2 89 93 0C 81 38 56 8A 13 09 01 16 84 09 +80 00 13 0C 41 51 93 0B B3 B0 93 8D 43 8D 13 8D +42 BD 3E D4 FE 8A 03 27 0B 14 89 47 63 EE E7 60 +42 47 23 04 01 30 23 26 71 31 23 28 71 31 23 2A +71 31 23 2C 71 31 23 2E 71 31 23 20 71 33 23 22 +71 33 23 24 71 33 23 26 71 33 23 28 71 33 23 2A +71 33 23 2C 71 33 23 06 01 38 3C 05 88 43 CC 43 +90 47 D4 47 08 C3 4C C3 10 C7 54 C7 C1 07 41 07 +E3 96 E7 FF D2 47 72 47 82 56 23 2E F1 40 23 28 +F1 42 92 57 23 20 E1 42 23 2A E1 42 23 2C F1 48 +A2 57 32 47 23 08 01 40 23 2E F1 48 B7 97 F9 24 +93 87 D7 77 23 20 F1 4A B7 E7 7E CF 93 87 77 6C +23 22 F1 4A B7 17 6D FB 93 87 87 C4 23 24 F1 4A +B7 F7 DE CB 93 87 37 97 23 26 F1 4A B7 97 95 7A +93 87 67 79 23 28 F1 4A B7 E7 9B 48 93 87 C7 DB +23 2A F1 4A B7 F7 5D 4C 93 87 D7 61 23 2C F1 4A +B7 97 32 5B 93 87 47 7B 23 2E F1 4A B7 E7 68 FB +93 87 97 AB 23 20 F1 4C B7 87 B5 F1 93 87 27 2C +23 22 F1 4C 23 2A B1 41 23 2C A1 41 23 22 D1 42 +23 24 B1 43 23 26 A1 43 23 2C D1 42 23 2E B1 43 +23 20 A1 45 23 0A 01 48 FA 87 88 43 CC 43 90 47 +D4 47 08 C3 4C C3 10 C7 54 C7 C1 07 41 07 E3 96 +97 FF 03 A6 0C 00 A2 47 CA 86 10 C3 88 43 CC 43 +90 47 D8 47 88 C2 CC C2 90 C6 D8 C6 C1 07 C1 06 +E3 96 37 FF 03 A6 09 00 92 47 26 87 90 C2 88 43 +CC 43 90 47 D4 47 08 C3 4C C3 10 C7 54 C7 C1 07 +41 07 E3 96 47 FF 83 26 0A 00 93 07 41 49 22 88 +14 C3 8C 43 D0 43 94 47 D8 47 23 20 B8 00 23 22 +C8 00 23 24 D8 00 23 26 E8 00 C1 07 41 08 E3 92 +87 FF 83 27 0C 00 32 45 05 47 23 20 F8 00 A2 86 +26 86 CA 85 EF B0 10 0D EF B0 F0 07 E2 47 85 0A +13 0F 81 30 9C 43 E3 E8 FA E2 D2 8A 4E 8A B2 49 +83 27 0B 14 89 4B 63 EB FB 48 E2 47 9C 43 63 88 +07 42 93 07 80 1B 3E DE B7 37 02 50 93 87 C7 31 +3E CE B7 37 02 50 93 87 C7 39 3E CA B7 07 02 50 +13 8D C7 07 B7 07 02 50 93 87 C7 0F 37 E7 7E 63 +3E C6 93 07 E7 C6 37 E7 DC 01 3E D0 93 07 67 7E +37 A7 2A 74 3E D2 93 07 57 94 37 87 AE 1A 3E D4 +93 07 F7 2D 37 47 DA 23 3E D6 93 07 27 E9 37 67 +9E 43 3E D8 93 07 E7 90 37 67 E7 43 37 13 0B 0B +3E DA 93 07 37 1B 81 4B 13 0C 81 59 93 0C C1 61 +93 0D B3 B0 3E DC 83 26 0B 14 09 47 63 60 D7 3C +82 57 37 17 91 3E 13 07 87 FB 23 20 F1 5A 92 57 +23 0C 01 50 23 2E B1 51 23 22 F1 5A A2 57 23 20 +B1 53 23 22 B1 53 23 24 F1 5A B2 57 23 24 B1 53 +23 26 B1 53 23 26 F1 5A C2 57 23 28 B1 53 23 2A +B1 53 23 28 F1 5A D2 57 23 2C B1 53 23 2E B1 53 +23 2A F1 5A E2 57 23 20 B1 55 23 22 B1 55 23 24 +B1 55 23 26 B1 55 23 28 B1 55 23 2A B1 55 23 2C +B1 55 23 0E 01 58 23 2C F1 5A 23 2E E1 5A 37 87 +28 AC 13 07 B7 8E 23 20 E1 5C 37 47 80 D5 13 07 +F7 F6 23 22 E1 5C 37 E7 61 0B 13 07 E7 BC 23 24 +E1 5C 37 27 25 5E 61 17 23 26 E1 5C 37 47 9A 78 +13 07 27 72 23 28 E1 5C 37 67 BE C1 13 07 E7 5A +23 2A E1 5C B7 96 9F E8 37 D7 5F A4 13 07 47 46 +93 86 B6 F5 23 2C E1 5C 23 2E D1 5C 13 07 81 51 +CE 86 08 43 4C 43 10 47 5C 47 88 C2 CC C2 90 C6 +DC C6 41 07 C1 06 E3 16 87 FF 83 25 0C 00 22 47 +4A 86 8C C2 08 43 4C 43 14 47 5C 47 08 C2 4C C2 +14 C6 5C C6 41 07 41 06 E3 16 47 FF 83 25 0A 00 +12 47 A6 86 0C C2 08 43 4C 43 10 47 5C 47 88 C2 +CC C2 90 C6 DC C6 41 07 C1 06 E3 16 57 FF 03 A6 +0A 00 13 07 C1 59 A2 88 90 C2 0C 43 50 43 14 47 +5C 47 23 A0 B8 00 23 A2 C8 00 23 A4 D8 00 23 A6 +F8 00 41 07 C1 08 E3 12 97 FF 03 A3 0C 00 05 47 +A2 86 26 86 CA 85 4E 85 23 A0 68 00 EF B0 D0 35 +EF B0 60 64 72 47 C2 46 5C 47 08 43 4C 43 10 47 +88 C2 CC C2 90 C6 DC C6 D2 47 41 07 C1 06 E3 15 +F7 FE 13 07 00 10 23 16 E1 38 CE 86 13 07 81 51 +08 43 4C 43 10 47 5C 47 88 C2 CC C2 90 C6 DC C6 +41 07 C1 06 E3 16 87 FF 83 25 0C 00 22 47 4A 86 +8C C2 08 43 4C 43 14 47 5C 47 08 C2 4C C2 14 C6 +5C C6 41 07 41 06 E3 16 47 FF 83 25 0A 00 12 47 +A6 86 0C C2 08 43 4C 43 10 47 5C 47 88 C2 CC C2 +90 C6 DC C6 41 07 C1 06 E3 16 57 FF 03 A6 0A 00 +13 07 C1 59 A2 88 90 C2 0C 43 50 43 14 47 5C 47 +23 A0 B8 00 23 A2 C8 00 23 A4 D8 00 23 A6 F8 00 +41 07 C1 08 E3 12 97 FF 03 A3 0C 00 05 47 A2 86 +26 86 CA 85 4E 85 23 A0 68 00 EF B0 F0 28 C2 46 +6A 87 5C 47 08 43 4C 43 10 47 88 C2 CC C2 90 C6 +DC C6 B2 47 41 07 C1 06 E3 15 F7 FE 83 27 8D 0B +83 26 0D 0B 03 27 4D 0B 83 20 4D 08 83 23 8D 08 +83 2F CD 08 03 2F 0D 09 83 2E 4D 09 03 2E 8D 09 +03 23 CD 09 83 28 0D 0A 03 25 4D 0A 83 25 8D 0A +03 26 CD 0A 83 22 0D 08 23 2C F1 5C 83 27 CD 0B +23 28 D1 5C 23 2A E1 5C 23 22 11 5A 23 24 71 5A +23 20 51 5A 23 26 F1 5B 23 28 E1 5B 23 2A D1 5B +23 2C C1 5B 23 2E 61 5A 23 20 11 5D 23 22 A1 5C +23 24 B1 5C 23 26 C1 5C 23 2E F1 5C 13 07 81 51 +CE 86 08 43 4C 43 10 47 5C 47 88 C2 CC C2 90 C6 +DC C6 41 07 C1 06 E3 16 87 FF 83 25 0C 00 22 47 +4A 86 8C C2 08 43 4C 43 14 47 5C 47 08 C2 4C C2 +14 C6 5C C6 41 07 41 06 E3 16 47 FF 83 25 0A 00 +12 47 A6 86 0C C2 08 43 4C 43 10 47 5C 47 88 C2 +CC C2 90 C6 DC C6 41 07 C1 06 E3 16 57 FF 03 A6 +0A 00 13 07 C1 59 A2 88 90 C2 0C 43 50 43 14 47 +5C 47 23 A0 B8 00 23 A2 C8 00 23 A4 D8 00 23 A6 +F8 00 41 07 C1 08 E3 12 97 FF 03 A3 0C 00 01 47 +A2 86 26 86 CA 85 4E 85 23 A0 68 00 EF B0 D0 14 +EF B0 60 43 E2 47 85 0B 98 43 E3 EE EB C4 13 05 +F0 0F EF 20 40 7B 01 A0 E2 47 D6 85 90 43 13 05 +00 1A EF 20 40 7E 13 0F 81 30 D9 BA E2 47 72 55 +DE 85 90 43 EF 20 20 7D 25 B9 B7 14 02 50 13 85 +84 B0 EF 20 40 7A 83 27 0B 14 E3 7B F4 90 37 15 +02 50 13 05 C5 B2 EF 20 00 79 83 27 0B 14 E3 71 +F4 90 13 85 84 B0 EF 20 00 78 DD B8 37 1C 02 50 +13 05 8C B0 EF 20 20 77 83 27 0B 14 E3 FF FB B4 +37 15 02 50 13 05 45 B4 EF 20 E0 75 83 27 0B 14 +E3 F5 FB B4 13 05 8C B0 EF 20 E0 74 3D BE 1C 0F +3E C8 7C 07 3E C4 93 07 01 41 93 09 01 1F 13 09 +01 16 13 0A C1 40 3E C2 84 09 93 0A 01 49 80 00 +01 BE 00 00 6F 10 90 58 6F 00 90 63 00 00 00 00 +6F 00 10 63 00 00 00 00 6F 00 90 62 00 00 00 00 +6F 10 90 47 00 00 00 00 6F 00 90 61 00 00 00 00 +6F 00 10 61 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 6F 10 50 49 6F 10 90 49 +5D 71 2A DA 13 05 B0 0F 22 DE 36 D4 3E D0 86 C6 +96 C4 9A C2 9E C0 26 DC 2E D8 32 D6 3A D2 42 CE +46 CC 4A CA 4E C8 72 C6 76 C4 7A C2 7E C0 37 04 +02 50 EF 20 40 65 83 26 04 14 8D 47 63 E9 D7 08 +F3 27 B0 BC F3 29 C0 BC 73 29 10 34 F3 24 00 30 +73 24 40 30 73 90 C7 BC A1 47 73 A0 07 30 37 37 +02 50 83 27 87 31 0D 46 85 07 23 2C F7 30 63 69 +D6 06 A1 47 73 B0 07 30 73 90 C9 BC 73 10 19 34 +89 67 93 87 07 88 FD 8C 73 A0 04 30 85 67 93 87 +87 88 7D 8C 73 20 44 30 13 05 C0 0F EF 20 A0 5E +72 54 B6 40 A6 42 16 43 86 43 E2 54 52 55 C2 55 +32 56 A2 56 12 57 82 57 72 48 E2 48 52 49 C2 49 +32 4E A2 4E 12 4F 82 4F 61 61 73 00 20 30 37 15 +02 50 13 05 C5 B5 EF 20 00 5D 83 26 04 14 8D B7 +83 25 87 31 0D 65 13 05 C5 83 EF 20 C0 5D 51 B7 +5D 71 2A DA 13 05 B0 0F 22 DE 36 D4 3E D0 86 C6 +96 C4 9A C2 9E C0 26 DC 2E D8 32 D6 3A D2 42 CE +46 CC 4A CA 4E C8 72 C6 76 C4 7A C2 7E C0 37 04 +02 50 EF 20 40 56 83 26 04 14 8D 47 63 E9 D7 08 +F3 27 B0 BC F3 29 C0 BC 73 29 10 34 F3 24 00 30 +73 24 40 30 73 90 C7 BC A1 47 73 A0 07 30 37 37 +02 50 83 27 87 31 0D 46 85 07 23 2C F7 30 63 69 +D6 06 A1 47 73 B0 07 30 73 90 C9 BC 73 10 19 34 +89 67 93 87 07 88 FD 8C 73 A0 04 30 85 67 93 87 +87 88 7D 8C 73 20 44 30 13 05 C0 0F EF 20 A0 4F +72 54 B6 40 A6 42 16 43 86 43 E2 54 52 55 C2 55 +32 56 A2 56 12 57 82 57 72 48 E2 48 52 49 C2 49 +32 4E A2 4E 12 4F 82 4F 61 61 73 00 20 30 37 15 +02 50 13 05 C5 B6 EF 20 00 4E 83 26 04 14 8D B7 +83 25 87 31 0D 65 13 05 05 85 EF 20 C0 4E 51 B7 +5D 71 2A DA 13 05 B0 0F 22 DE 36 D4 3E D0 86 C6 +96 C4 9A C2 9E C0 26 DC 2E D8 32 D6 3A D2 42 CE +46 CC 4A CA 4E C8 72 C6 76 C4 7A C2 7E C0 37 04 +02 50 EF 20 40 47 83 26 04 14 8D 47 63 E9 D7 08 +F3 27 B0 BC F3 29 C0 BC 73 29 10 34 F3 24 00 30 +73 24 40 30 73 90 C7 BC A1 47 73 A0 07 30 37 37 +02 50 83 27 87 31 0D 46 85 07 23 2C F7 30 63 69 +D6 06 A1 47 73 B0 07 30 73 90 C9 BC 73 10 19 34 +89 67 93 87 07 88 FD 8C 73 A0 04 30 85 67 93 87 +87 88 7D 8C 73 20 44 30 13 05 C0 0F EF 20 A0 40 +72 54 B6 40 A6 42 16 43 86 43 E2 54 52 55 C2 55 +32 56 A2 56 12 57 82 57 72 48 E2 48 52 49 C2 49 +32 4E A2 4E 12 4F 82 4F 61 61 73 00 20 30 37 15 +02 50 13 05 C5 B7 EF 20 00 3F 83 26 04 14 8D B7 +83 25 87 31 0D 65 13 05 45 86 EF 20 C0 3F 51 B7 +5D 71 2A DA 13 05 B0 0F 22 DE 36 D4 3E D0 86 C6 +96 C4 9A C2 9E C0 26 DC 2E D8 32 D6 3A D2 42 CE +46 CC 4A CA 4E C8 72 C6 76 C4 7A C2 7E C0 37 04 +02 50 EF 20 40 38 83 26 04 14 8D 47 63 E9 D7 08 +F3 27 B0 BC F3 29 C0 BC 73 29 10 34 F3 24 00 30 +73 24 40 30 73 90 C7 BC A1 47 73 A0 07 30 37 37 +02 50 83 27 87 31 0D 46 85 07 23 2C F7 30 63 69 +D6 06 A1 47 73 B0 07 30 73 90 C9 BC 73 10 19 34 +89 67 93 87 07 88 FD 8C 73 A0 04 30 85 67 93 87 +87 88 7D 8C 73 20 44 30 13 05 C0 0F EF 20 A0 31 +72 54 B6 40 A6 42 16 43 86 43 E2 54 52 55 C2 55 +32 56 A2 56 12 57 82 57 72 48 E2 48 52 49 C2 49 +32 4E A2 4E 12 4F 82 4F 61 61 73 00 20 30 37 15 +02 50 13 05 05 B9 EF 20 00 30 83 26 04 14 8D B7 +83 25 87 31 0D 65 13 05 05 88 EF 20 C0 30 51 B7 +5D 71 2A DA 13 05 B0 0F 22 DE 36 D4 3E D0 86 C6 +96 C4 9A C2 9E C0 26 DC 2E D8 32 D6 3A D2 42 CE +46 CC 4A CA 4E C8 72 C6 76 C4 7A C2 7E C0 37 04 +02 50 EF 20 40 29 83 26 04 14 8D 47 63 E9 D7 08 +F3 27 B0 BC F3 29 C0 BC 73 29 10 34 F3 24 00 30 +73 24 40 30 73 90 C7 BC A1 47 73 A0 07 30 37 37 +02 50 83 27 87 31 0D 46 85 07 23 2C F7 30 63 69 +D6 06 A1 47 73 B0 07 30 73 90 C9 BC 73 10 19 34 +89 67 93 87 07 88 FD 8C 73 A0 04 30 85 67 93 87 +87 88 7D 8C 73 20 44 30 13 05 C0 0F EF 20 A0 22 +72 54 B6 40 A6 42 16 43 86 43 E2 54 52 55 C2 55 +32 56 A2 56 12 57 82 57 72 48 E2 48 52 49 C2 49 +32 4E A2 4E 12 4F 82 4F 61 61 73 00 20 30 37 15 +02 50 13 05 05 BA EF 20 00 21 83 26 04 14 8D B7 +83 25 87 31 0D 65 13 05 45 89 EF 20 C0 21 51 B7 +5D 71 2A DA 13 05 B0 0F 22 DE 36 D4 3E D0 86 C6 +96 C4 9A C2 9E C0 26 DC 2E D8 32 D6 3A D2 42 CE +46 CC 4A CA 4E C8 72 C6 76 C4 7A C2 7E C0 37 04 +02 50 EF 20 40 1A 83 26 04 14 8D 47 63 E9 D7 08 +F3 27 B0 BC F3 29 C0 BC 73 29 10 34 F3 24 00 30 +73 24 40 30 73 90 C7 BC A1 47 73 A0 07 30 37 37 +02 50 83 27 87 31 0D 46 85 07 23 2C F7 30 63 69 +D6 06 A1 47 73 B0 07 30 73 90 C9 BC 73 10 19 34 +89 67 93 87 07 88 FD 8C 73 A0 04 30 85 67 93 87 +87 88 7D 8C 73 20 44 30 13 05 C0 0F EF 20 A0 13 +72 54 B6 40 A6 42 16 43 86 43 E2 54 52 55 C2 55 +32 56 A2 56 12 57 82 57 72 48 E2 48 52 49 C2 49 +32 4E A2 4E 12 4F 82 4F 61 61 73 00 20 30 37 15 +02 50 13 05 05 BB EF 20 00 12 83 26 04 14 8D B7 +83 25 87 31 0D 65 13 05 85 8A EF 20 C0 12 51 B7 +5D 71 2A DA 13 05 B0 0F 22 DE 36 D4 3E D0 86 C6 +96 C4 9A C2 9E C0 26 DC 2E D8 32 D6 3A D2 42 CE +46 CC 4A CA 4E C8 72 C6 76 C4 7A C2 7E C0 37 04 +02 50 EF 20 40 0B 83 26 04 14 8D 47 63 E9 D7 08 +F3 27 B0 BC F3 29 C0 BC 73 29 10 34 F3 24 00 30 +73 24 40 30 73 90 C7 BC A1 47 73 A0 07 30 37 37 +02 50 83 27 87 31 0D 46 85 07 23 2C F7 30 63 69 +D6 06 A1 47 73 B0 07 30 73 90 C9 BC 73 10 19 34 +89 67 93 87 07 88 FD 8C 73 A0 04 30 85 67 93 87 +87 88 7D 8C 73 20 44 30 13 05 C0 0F EF 20 A0 04 +72 54 B6 40 A6 42 16 43 86 43 E2 54 52 55 C2 55 +32 56 A2 56 12 57 82 57 72 48 E2 48 52 49 C2 49 +32 4E A2 4E 12 4F 82 4F 61 61 73 00 20 30 37 15 +02 50 13 05 05 BC EF 20 00 03 83 26 04 14 8D B7 +83 25 87 31 0D 65 13 05 05 8C EF 20 C0 03 51 B7 +5D 71 2A DA 13 05 B0 0F 22 DE 36 D4 3E D0 86 C6 +96 C4 9A C2 9E C0 26 DC 2E D8 32 D6 3A D2 42 CE +46 CC 4A CA 4E C8 72 C6 76 C4 7A C2 7E C0 37 04 +02 50 EF 10 50 7C 83 26 04 14 8D 47 63 E9 D7 08 +F3 27 B0 BC F3 29 C0 BC 73 29 10 34 F3 24 00 30 +73 24 40 30 73 90 C7 BC A1 47 73 A0 07 30 37 37 +02 50 83 27 87 31 0D 46 85 07 23 2C F7 30 63 69 +D6 06 A1 47 73 B0 07 30 73 90 C9 BC 73 10 19 34 +89 67 93 87 07 88 FD 8C 73 A0 04 30 85 67 93 87 +87 88 7D 8C 73 20 44 30 13 05 C0 0F EF 10 B0 75 +72 54 B6 40 A6 42 16 43 86 43 E2 54 52 55 C2 55 +32 56 A2 56 12 57 82 57 72 48 E2 48 52 49 C2 49 +32 4E A2 4E 12 4F 82 4F 61 61 73 00 20 30 37 15 +02 50 13 05 05 BD EF 10 10 74 83 26 04 14 8D B7 +83 25 87 31 0D 65 13 05 85 8D EF 10 D0 74 51 B7 +5D 71 2A DA 13 05 B0 0F 22 DE 36 D4 3E D0 86 C6 +96 C4 9A C2 9E C0 26 DC 2E D8 32 D6 3A D2 42 CE +46 CC 4A CA 4E C8 72 C6 76 C4 7A C2 7E C0 37 04 +02 50 EF 10 50 6D 83 26 04 14 8D 47 63 E9 D7 08 +F3 27 B0 BC F3 29 C0 BC 73 29 10 34 F3 24 00 30 +73 24 40 30 73 90 C7 BC A1 47 73 A0 07 30 37 37 +02 50 83 27 87 31 0D 46 85 07 23 2C F7 30 63 69 +D6 06 A1 47 73 B0 07 30 73 90 C9 BC 73 10 19 34 +89 67 93 87 07 88 FD 8C 73 A0 04 30 85 67 93 87 +87 88 7D 8C 73 20 44 30 13 05 C0 0F EF 10 B0 66 +72 54 B6 40 A6 42 16 43 86 43 E2 54 52 55 C2 55 +32 56 A2 56 12 57 82 57 72 48 E2 48 52 49 C2 49 +32 4E A2 4E 12 4F 82 4F 61 61 73 00 20 30 37 15 +02 50 13 05 C5 BD EF 10 10 65 83 26 04 14 8D B7 +83 25 87 31 0D 65 13 05 C5 8E EF 10 D0 65 51 B7 +5D 71 2A DA 13 05 B0 0F 22 DE 36 D4 3E D0 86 C6 +96 C4 9A C2 9E C0 26 DC 2E D8 32 D6 3A D2 42 CE +46 CC 4A CA 4E C8 72 C6 76 C4 7A C2 7E C0 37 04 +02 50 EF 10 50 5E 83 26 04 14 8D 47 63 E9 D7 08 +F3 27 B0 BC F3 29 C0 BC 73 29 10 34 F3 24 00 30 +73 24 40 30 73 90 C7 BC A1 47 73 A0 07 30 37 37 +02 50 83 27 87 31 0D 46 85 07 23 2C F7 30 63 69 +D6 06 A1 47 73 B0 07 30 73 90 C9 BC 73 10 19 34 +89 67 93 87 07 88 FD 8C 73 A0 04 30 85 67 93 87 +87 88 7D 8C 73 20 44 30 13 05 C0 0F EF 10 B0 57 +72 54 B6 40 A6 42 16 43 86 43 E2 54 52 55 C2 55 +32 56 A2 56 12 57 82 57 72 48 E2 48 52 49 C2 49 +32 4E A2 4E 12 4F 82 4F 61 61 73 00 20 30 37 15 +02 50 13 05 85 BE EF 10 10 56 83 26 04 14 8D B7 +83 25 87 31 0D 65 13 05 05 90 EF 10 D0 56 51 B7 +5D 71 2A DA 13 05 B0 0F 22 DE 36 D4 3E D0 86 C6 +96 C4 9A C2 9E C0 26 DC 2E D8 32 D6 3A D2 42 CE +46 CC 4A CA 4E C8 72 C6 76 C4 7A C2 7E C0 37 04 +02 50 EF 10 50 4F 83 26 04 14 8D 47 63 E9 D7 08 +F3 27 B0 BC F3 29 C0 BC 73 29 10 34 F3 24 00 30 +73 24 40 30 73 90 C7 BC A1 47 73 A0 07 30 37 37 +02 50 83 27 87 31 0D 46 85 07 23 2C F7 30 63 69 +D6 06 A1 47 73 B0 07 30 73 90 C9 BC 73 10 19 34 +89 67 93 87 07 88 FD 8C 73 A0 04 30 85 67 93 87 +87 88 7D 8C 73 20 44 30 13 05 C0 0F EF 10 B0 48 +72 54 B6 40 A6 42 16 43 86 43 E2 54 52 55 C2 55 +32 56 A2 56 12 57 82 57 72 48 E2 48 52 49 C2 49 +32 4E A2 4E 12 4F 82 4F 61 61 73 00 20 30 37 15 +02 50 13 05 85 BF EF 10 10 47 83 26 04 14 8D B7 +83 25 87 31 0D 65 13 05 45 91 EF 10 D0 47 51 B7 +5D 71 2A DA 13 05 B0 0F 22 DE 36 D4 3E D0 86 C6 +96 C4 9A C2 9E C0 26 DC 2E D8 32 D6 3A D2 42 CE +46 CC 4A CA 4E C8 72 C6 76 C4 7A C2 7E C0 37 04 +02 50 EF 10 50 40 83 26 04 14 8D 47 63 E9 D7 08 +F3 27 B0 BC F3 29 C0 BC 73 29 10 34 F3 24 00 30 +73 24 40 30 73 90 C7 BC A1 47 73 A0 07 30 37 37 +02 50 83 27 87 31 0D 46 85 07 23 2C F7 30 63 69 +D6 06 A1 47 73 B0 07 30 73 90 C9 BC 73 10 19 34 +89 67 93 87 07 88 FD 8C 73 A0 04 30 85 67 93 87 +87 88 7D 8C 73 20 44 30 13 05 C0 0F EF 10 B0 39 +72 54 B6 40 A6 42 16 43 86 43 E2 54 52 55 C2 55 +32 56 A2 56 12 57 82 57 72 48 E2 48 52 49 C2 49 +32 4E A2 4E 12 4F 82 4F 61 61 73 00 20 30 37 15 +02 50 13 05 85 C0 EF 10 10 38 83 26 04 14 8D B7 +83 25 87 31 0D 65 13 05 85 92 EF 10 D0 38 51 B7 +39 71 2A D6 13 05 B0 0F 3A CE 3E CC 06 DE 16 DC +1A DA 1E D8 2E D4 32 D2 36 D0 42 CA 46 C8 72 C6 +76 C4 7A C2 7E C0 EF 10 10 32 B7 07 02 50 03 A7 +07 14 8D 47 63 E9 E7 02 13 05 C0 0F EF 10 B0 30 +F2 50 E2 52 52 53 C2 53 32 55 A2 55 12 56 82 56 +72 47 E2 47 52 48 C2 48 32 4E A2 4E 12 4F 82 4F +21 61 73 00 20 30 37 15 02 50 13 05 85 C1 EF 10 +90 2F D9 B7 1D 71 AA C2 13 05 B0 0F 3A DA 3E D8 +4A D2 86 CE 96 CC 9A CA 9E C8 A2 C6 A6 C4 AE C0 +32 DE 36 DC 42 D6 46 D4 4E D0 52 CE 72 CC 76 CA +7A C8 7E C6 37 09 02 50 EF 10 F0 29 83 27 09 14 +0D 47 63 6B F7 0A 73 27 B0 BC 73 2A C0 BC F3 29 +10 34 F3 24 00 30 73 24 40 30 73 10 C7 BC 21 47 +73 20 07 30 B7 36 02 50 03 A7 86 31 0D 46 05 07 +23 AC E6 30 63 62 F6 06 B5 EB A1 47 73 B0 07 30 +73 10 CA BC 73 90 19 34 89 67 93 87 07 88 FD 8C +73 A0 04 30 85 67 93 87 87 88 7D 8C 73 20 44 30 +13 05 C0 0F EF 10 30 23 36 44 F6 40 E6 42 56 43 +C6 43 A6 44 16 45 86 45 72 56 E2 56 52 57 C2 57 +32 58 A2 58 12 59 82 59 72 4A 62 4E D2 4E 42 4F +B2 4F 25 61 73 00 20 30 83 A5 86 31 0D 65 13 05 +C5 93 EF 10 50 23 83 27 09 14 C1 DB 0D 65 13 05 +45 95 EF 10 50 22 51 B7 37 15 02 50 13 05 05 C2 +EF 10 70 1F 83 27 09 14 3D BF 1D 71 AA C2 13 05 +B0 0F 3A DA 3E D8 4A D2 86 CE 96 CC 9A CA 9E C8 +A2 C6 A6 C4 AE C0 32 DE 36 DC 42 D6 46 D4 4E D0 +52 CE 72 CC 76 CA 7A C8 7E C6 37 09 02 50 EF 10 +90 19 83 27 09 14 0D 47 63 6B F7 0A 73 27 B0 BC +73 2A C0 BC F3 29 10 34 F3 24 00 30 73 24 40 30 +73 10 C7 BC 21 47 73 20 07 30 B7 36 02 50 03 A7 +86 31 0D 46 05 07 23 AC E6 30 63 62 F6 06 B5 EB +A1 47 73 B0 07 30 73 10 CA BC 73 90 19 34 89 67 +93 87 07 88 FD 8C 73 A0 04 30 85 67 93 87 87 88 +7D 8C 73 20 44 30 13 05 C0 0F EF 10 D0 12 36 44 +F6 40 E6 42 56 43 C6 43 A6 44 16 45 86 45 72 56 +E2 56 52 57 C2 57 32 58 A2 58 12 59 82 59 72 4A +62 4E D2 4E 42 4F B2 4F 25 61 73 00 20 30 83 A5 +86 31 0D 65 13 05 C5 95 EF 10 F0 12 83 27 09 14 +C1 DB 0D 65 13 05 45 97 EF 10 F0 11 51 B7 37 15 +02 50 13 05 45 C3 EF 10 10 0F 83 27 09 14 3D BF +39 71 3E CC B7 07 02 50 3A CE 03 A7 07 14 06 DE +16 DC 1A DA 1E D8 2A D6 2E D4 32 D2 36 D0 42 CA +46 C8 72 C6 76 C4 7A C2 7E C0 91 47 63 E5 E7 02 +F2 50 E2 52 52 53 C2 53 32 55 A2 55 12 56 82 56 +72 47 E2 47 52 48 C2 48 32 4E A2 4E 12 4F 82 4F +21 61 73 00 20 30 F3 25 20 34 0D 65 13 05 C5 97 +EF 10 70 0A F1 B7 1D 71 AA C2 13 05 B0 0F A2 C6 +36 DC 3E D8 86 CE 96 CC 9A CA 9E C8 A6 C4 AE C0 +32 DE 3A DA 42 D6 46 D4 4A D2 4E D0 52 CE 72 CC +76 CA 7A C8 7E C6 37 04 02 50 EF 10 D0 02 83 26 +04 14 8D 47 63 ED D7 0C F3 27 B0 BC 73 2A C0 BC +F3 29 10 34 73 29 00 30 F3 24 40 30 73 90 C7 BC +A1 47 73 A0 07 30 37 37 02 50 83 27 87 31 0D 46 +85 07 23 2C F7 30 63 6C D6 08 37 27 02 30 83 27 +87 81 93 F6 17 00 A5 CE B7 37 02 50 93 87 C7 39 +D4 5F 05 46 23 2C C7 80 13 E7 16 00 D8 DF A1 47 +73 B0 07 30 73 10 CA BC 73 90 19 34 89 67 93 87 +07 88 33 79 F9 00 73 20 09 30 85 67 93 87 87 88 +FD 8C 73 A0 44 30 13 05 C0 0F EF 10 C0 79 36 44 +F6 40 E6 42 56 43 C6 43 A6 44 16 45 86 45 72 56 +E2 56 52 57 C2 57 32 58 A2 58 12 59 82 59 72 4A +62 4E D2 4E 42 4F B2 4F 25 61 73 00 20 30 C5 F3 +83 27 04 14 95 E7 05 45 EF 10 E0 75 01 A0 83 25 +87 31 0D 65 13 05 85 98 EF 10 E0 78 B9 BF 37 15 +02 50 13 05 85 C4 EF 10 00 76 83 26 04 14 29 BF +0D 65 81 45 13 05 45 9A EF 10 E0 76 05 45 EF 10 +80 72 E9 B7 1D 71 AA C2 13 05 B0 0F A2 C6 36 DC +3E D8 86 CE 96 CC 9A CA 9E C8 A6 C4 AE C0 32 DE +3A DA 42 D6 46 D4 4A D2 4E D0 52 CE 72 CC 76 CA +7A C8 7E C6 37 04 02 50 EF 10 E0 6E 83 26 04 14 +8D 47 63 E3 D7 1A F3 27 B0 BC 73 2A C0 BC F3 29 +10 34 73 29 00 30 F3 24 40 30 73 90 C7 BC A1 47 +73 A0 07 30 37 37 02 50 83 27 87 31 0D 46 85 07 +23 2C F7 30 63 62 D6 16 B7 16 03 30 03 A7 86 81 +93 77 17 00 81 CF B7 37 02 50 05 46 23 AC C6 80 +93 87 C7 39 D4 5B 93 E6 16 00 D4 DB 93 77 27 00 +91 CF B7 16 03 30 B7 37 02 50 09 46 23 AC C6 80 +93 87 C7 39 D4 5B 93 E6 26 00 D4 DB 93 77 47 00 +91 CF B7 16 03 30 B7 37 02 50 11 46 23 AC C6 80 +93 87 C7 39 D4 5B 93 E6 46 00 D4 DB 93 77 87 00 +13 76 07 01 93 76 07 02 DD C3 37 17 03 30 B7 37 +02 50 A1 45 23 2C B7 80 93 87 C7 39 D8 5B 13 67 +87 00 D8 DB 55 CE 37 17 03 30 41 46 23 2C C7 80 +D8 5B 13 67 07 01 D8 DB 99 CA 37 17 03 30 93 06 +00 02 23 2C D7 80 D8 5B 13 67 07 02 D8 DB A1 47 +73 B0 07 30 73 10 CA BC 73 90 19 34 89 67 93 87 +07 88 33 79 F9 00 73 20 09 30 85 67 93 87 87 88 +FD 8C 73 A0 44 30 13 05 C0 0F EF 10 C0 5C 36 44 +F6 40 E6 42 56 43 C6 43 A6 44 16 45 86 45 72 56 +E2 56 52 57 C2 57 32 58 A2 58 12 59 82 59 72 4A +62 4E D2 4E 42 4F B2 4F 25 61 73 00 20 30 05 C2 +37 17 03 30 B7 37 02 50 41 46 93 87 C7 39 23 2C +C7 80 D8 5B 13 67 07 01 D8 DB A5 FA 49 B7 B1 E6 +3D FF 83 27 04 14 AD E3 05 45 EF 10 C0 56 01 A0 +BD D6 37 17 03 30 93 06 00 02 23 2C D7 80 D8 5B +13 67 07 02 D8 DB A1 BF 83 25 87 31 0D 65 13 05 +85 9C EF 10 40 58 49 BD 37 15 02 50 13 05 C5 C5 +EF 10 60 55 83 26 04 14 B9 B5 37 17 03 30 B7 37 +02 50 93 06 00 02 93 87 C7 39 23 2C D7 80 D8 5B +13 67 07 02 D8 DB 21 BF 0D 65 81 45 13 05 05 9E +EF 10 60 54 51 BF 1D 71 AA C2 13 05 B0 0F A2 C6 +36 DC 3E D8 86 CE 96 CC 9A CA 9E C8 A6 C4 AE C0 +32 DE 3A DA 42 D6 46 D4 4A D2 4E D0 52 CE 72 CC +76 CA 7A C8 7E C6 37 04 02 50 EF 10 C0 4C 83 26 +04 14 8D 47 63 E3 D7 1A F3 27 B0 BC 73 2A C0 BC +F3 29 10 34 73 29 00 30 F3 24 40 30 73 90 C7 BC +A1 47 73 A0 07 30 37 37 02 50 83 27 87 31 0D 46 +85 07 23 2C F7 30 63 62 D6 16 B7 16 03 30 03 A7 +46 81 93 77 17 00 81 CF B7 37 02 50 05 46 23 AA +C6 80 93 87 C7 39 94 5B 93 E6 16 00 94 DB 93 77 +27 00 91 CF B7 16 03 30 B7 37 02 50 09 46 23 AA +C6 80 93 87 C7 39 94 5B 93 E6 26 00 94 DB 93 77 +47 00 91 CF B7 16 03 30 B7 37 02 50 11 46 23 AA +C6 80 93 87 C7 39 94 5B 93 E6 46 00 94 DB 93 77 +87 00 13 76 07 01 93 76 07 02 DD C3 37 17 03 30 +B7 37 02 50 A1 45 23 2A B7 80 93 87 C7 39 98 5B +13 67 87 00 98 DB 55 CE 37 17 03 30 41 46 23 2A +C7 80 98 5B 13 67 07 01 98 DB 99 CA 37 17 03 30 +93 06 00 02 23 2A D7 80 98 5B 13 67 07 02 98 DB +A1 47 73 B0 07 30 73 10 CA BC 73 90 19 34 89 67 +93 87 07 88 33 79 F9 00 73 20 09 30 85 67 93 87 +87 88 FD 8C 73 A0 44 30 13 05 C0 0F EF 10 A0 3A +36 44 F6 40 E6 42 56 43 C6 43 A6 44 16 45 86 45 +72 56 E2 56 52 57 C2 57 32 58 A2 58 12 59 82 59 +72 4A 62 4E D2 4E 42 4F B2 4F 25 61 73 00 20 30 +05 C2 37 17 03 30 B7 37 02 50 41 46 93 87 C7 39 +23 2A C7 80 98 5B 13 67 07 01 98 DB A5 FA 49 B7 +B1 E6 3D FF 83 27 04 14 AD E3 05 45 EF 10 A0 34 +01 A0 BD D6 37 17 03 30 93 06 00 02 23 2A D7 80 +98 5B 13 67 07 02 98 DB A1 BF 83 25 87 31 0D 65 +13 05 05 A0 EF 10 20 36 49 BD 37 15 02 50 13 05 +05 C7 EF 10 40 33 83 26 04 14 B9 B5 37 17 03 30 +B7 37 02 50 93 06 00 02 93 87 C7 39 23 2A D7 80 +98 5B 13 67 07 02 98 DB 21 BF 0D 65 81 45 13 05 +85 A1 EF 10 40 32 51 BF 1D 71 AA C2 13 05 B0 0F +A2 C6 36 DC 3E D8 86 CE 96 CC 9A CA 9E C8 A6 C4 +AE C0 32 DE 3A DA 42 D6 46 D4 4A D2 4E D0 52 CE +72 CC 76 CA 7A C8 7E C6 37 04 02 50 EF 10 A0 2A +83 26 04 14 8D 47 63 ED D7 0C F3 27 B0 BC 73 2A +C0 BC F3 29 10 34 73 29 00 30 F3 24 40 30 73 90 +C7 BC A1 47 73 A0 07 30 37 37 02 50 83 27 87 31 +0D 46 85 07 23 2C F7 30 63 6C D6 08 37 97 02 10 +83 27 87 81 93 F6 17 00 A5 CE B7 37 02 50 93 87 +C7 39 D4 57 05 46 23 2C C7 80 13 E7 16 00 D8 D7 +A1 47 73 B0 07 30 73 10 CA BC 73 90 19 34 89 67 +93 87 07 88 33 79 F9 00 73 20 09 30 85 67 93 87 +87 88 FD 8C 73 A0 44 30 13 05 C0 0F EF 10 A0 21 +36 44 F6 40 E6 42 56 43 C6 43 A6 44 16 45 86 45 +72 56 E2 56 52 57 C2 57 32 58 A2 58 12 59 82 59 +72 4A 62 4E D2 4E 42 4F B2 4F 25 61 73 00 20 30 +C5 F3 83 27 04 14 95 E7 05 45 EF 10 C0 1D 01 A0 +83 25 87 31 0D 65 13 05 85 A3 EF 10 C0 20 B9 BF +37 15 02 50 13 05 45 C8 EF 10 E0 1D 83 26 04 14 +29 BF 0D 65 81 45 13 05 05 A5 EF 10 C0 1E 05 45 +EF 10 60 1A E9 B7 1D 71 AA C2 13 05 B0 0F A2 C6 +36 DC 3E D8 86 CE 96 CC 9A CA 9E C8 A6 C4 AE C0 +32 DE 3A DA 42 D6 46 D4 4A D2 4E D0 52 CE 72 CC +76 CA 7A C8 7E C6 37 04 02 50 EF 10 C0 16 83 26 +04 14 8D 47 63 ED D7 0C F3 27 B0 BC 73 2A C0 BC +F3 29 10 34 73 29 00 30 F3 24 40 30 73 90 C7 BC +A1 47 73 A0 07 30 37 37 02 50 83 27 87 31 0D 46 +85 07 23 2C F7 30 63 6C D6 08 37 17 02 10 83 27 +87 81 93 F6 17 00 A5 CE B7 37 02 50 93 87 C7 39 +D4 53 05 46 23 2C C7 80 13 E7 16 00 D8 D3 A1 47 +73 B0 07 30 73 10 CA BC 73 90 19 34 89 67 93 87 +07 88 33 79 F9 00 73 20 09 30 85 67 93 87 87 88 +FD 8C 73 A0 44 30 13 05 C0 0F EF 10 C0 0D 36 44 +F6 40 E6 42 56 43 C6 43 A6 44 16 45 86 45 72 56 +E2 56 52 57 C2 57 32 58 A2 58 12 59 82 59 72 4A +62 4E D2 4E 42 4F B2 4F 25 61 73 00 20 30 C5 F3 +83 27 04 14 95 E7 05 45 EF 10 E0 09 01 A0 83 25 +87 31 0D 65 13 05 05 A7 EF 10 E0 0C B9 BF 37 15 +02 50 13 05 45 C9 EF 10 00 0A 83 26 04 14 29 BF +0D 65 81 45 13 05 85 A8 EF 10 E0 0A 05 45 EF 10 +80 06 E9 B7 1D 71 AA C2 13 05 B0 0F A2 C6 36 DC +3E D8 86 CE 96 CC 9A CA 9E C8 A6 C4 AE C0 32 DE +3A DA 42 D6 46 D4 4A D2 4E D0 52 CE 72 CC 76 CA +7A C8 7E C6 37 04 02 50 EF 10 E0 02 83 26 04 14 +8D 47 63 ED D7 0C F3 27 B0 BC 73 2A C0 BC F3 29 +10 34 73 29 00 30 F3 24 40 30 73 90 C7 BC A1 47 +73 A0 07 30 37 37 02 50 83 27 87 31 0D 46 85 07 +23 2C F7 30 63 6C D6 08 37 17 01 10 83 27 87 81 +93 F6 17 00 A5 CE B7 37 02 50 93 87 C7 39 D4 4B +05 46 23 2C C7 80 13 E7 16 00 D8 CB A1 47 73 B0 +07 30 73 10 CA BC 73 90 19 34 89 67 93 87 07 88 +33 79 F9 00 73 20 09 30 85 67 93 87 87 88 FD 8C +73 A0 44 30 13 05 C0 0F EF 00 F0 79 36 44 F6 40 +E6 42 56 43 C6 43 A6 44 16 45 86 45 72 56 E2 56 +52 57 C2 57 32 58 A2 58 12 59 82 59 72 4A 62 4E +D2 4E 42 4F B2 4F 25 61 73 00 20 30 C5 F3 83 27 +04 14 95 E7 05 45 EF 00 10 76 01 A0 83 25 87 31 +0D 65 13 05 85 AA EF 00 10 79 B9 BF 37 15 02 50 +13 05 45 CA EF 00 30 76 83 26 04 14 29 BF 0D 65 +81 45 13 05 C5 AB EF 00 10 77 05 45 EF 00 B0 72 +E9 B7 1D 71 AA C2 13 05 B0 0F A2 C6 36 DC 3E D8 +86 CE 96 CC 9A CA 9E C8 A6 C4 AE C0 32 DE 3A DA +42 D6 46 D4 4A D2 4E D0 52 CE 72 CC 76 CA 7A C8 +7E C6 37 04 02 50 EF 00 10 6F 83 26 04 14 8D 47 +63 ED D7 0C F3 27 B0 BC 73 2A C0 BC F3 29 10 34 +73 29 00 30 F3 24 40 30 73 90 C7 BC A1 47 73 A0 +07 30 37 37 02 50 83 27 87 31 0D 46 85 07 23 2C +F7 30 63 6C D6 08 37 97 00 10 83 27 87 81 93 F6 +17 00 A5 CE B7 37 02 50 93 87 C7 39 D4 47 05 46 +23 2C C7 80 13 E7 16 00 D8 C7 A1 47 73 B0 07 30 +73 10 CA BC 73 90 19 34 89 67 93 87 07 88 33 79 +F9 00 73 20 09 30 85 67 93 87 87 88 FD 8C 73 A0 +44 30 13 05 C0 0F EF 00 10 66 36 44 F6 40 E6 42 +56 43 C6 43 A6 44 16 45 86 45 72 56 E2 56 52 57 +C2 57 32 58 A2 58 12 59 82 59 72 4A 62 4E D2 4E +42 4F B2 4F 25 61 73 00 20 30 C5 F3 83 27 04 14 +95 E7 05 45 EF 00 30 62 01 A0 83 25 87 31 0D 65 +13 05 85 AD EF 00 30 65 B9 BF 37 15 02 50 13 05 +45 CB EF 00 50 62 83 26 04 14 29 BF 0D 65 81 45 +13 05 C5 AE EF 00 30 63 05 45 EF 00 D0 5E E9 B7 +1D 71 AA C2 13 05 B0 0F A2 C6 36 DC 3E D8 86 CE +96 CC 9A CA 9E C8 A6 C4 AE C0 32 DE 3A DA 42 D6 +46 D4 4A D2 4E D0 52 CE 72 CC 76 CA 7A C8 7E C6 +37 04 02 50 EF 00 30 5B 83 26 04 14 8D 47 63 ED +D7 0C F3 27 B0 BC 73 2A C0 BC F3 29 10 34 73 29 +00 30 F3 24 40 30 73 90 C7 BC A1 47 73 A0 07 30 +37 37 02 50 83 27 87 31 0D 46 85 07 23 2C F7 30 +63 6C D6 08 37 17 00 10 83 27 87 81 93 F6 17 00 +A5 CE B7 37 02 50 93 87 C7 39 D4 43 05 46 23 2C +C7 80 13 E7 16 00 D8 C3 A1 47 73 B0 07 30 73 10 +CA BC 73 90 19 34 89 67 93 87 07 88 33 79 F9 00 +73 20 09 30 85 67 93 87 87 88 FD 8C 73 A0 44 30 +13 05 C0 0F EF 00 30 52 36 44 F6 40 E6 42 56 43 +C6 43 A6 44 16 45 86 45 72 56 E2 56 52 57 C2 57 +32 58 A2 58 12 59 82 59 72 4A 62 4E D2 4E 42 4F +B2 4F 25 61 73 00 20 30 C5 F3 83 27 04 14 95 E7 +05 45 EF 00 50 4E 01 A0 83 25 87 31 0D 65 13 05 +85 B0 EF 00 50 51 B9 BF 37 15 02 50 13 05 45 CC +EF 00 70 4E 83 26 04 14 29 BF 0D 65 81 45 13 05 +C5 B1 EF 00 50 4F 05 45 EF 00 F0 4A E9 B7 21 47 +73 30 07 30 85 67 93 87 47 9B 93 E7 17 00 73 90 +57 30 97 12 02 50 93 82 E2 3D 73 90 82 BC B7 37 +00 60 23 A0 07 00 0F 00 F0 0F 73 50 90 BC B7 07 +00 60 D8 C3 0F 00 F0 0F 9D 46 94 C7 0F 00 F0 0F +D8 C7 0F 00 F0 0F 94 CB 0F 00 F0 0F D8 CB 0F 00 +F0 0F 94 CF 0F 00 F0 0F D8 CF 0F 00 F0 0F 94 D3 +0F 00 F0 0F D8 D3 0F 00 F0 0F 94 D7 0F 00 F0 0F +D8 D7 0F 00 F0 0F 94 DB 0F 00 F0 0F 91 45 CC DB +0F 00 F0 0F 0D 46 90 DF 0F 00 F0 0F CC DF 0F 00 +F0 0F B0 C3 0F 00 F0 0F F8 C3 0F 00 F0 0F B4 C7 +0F 00 F0 0F F8 C7 0F 00 F0 0F B4 CB 0F 00 F0 0F +F8 CB 0F 00 F0 0F B4 CF 0F 00 F0 0F F8 CF 0F 00 +F0 0F B4 D3 0F 00 F0 0F F8 D3 0F 00 F0 0F B4 D7 +0F 00 F0 0F 23 A6 07 06 0F 00 F0 0F 23 A8 07 06 +0F 00 F0 0F 23 AA 07 06 0F 00 F0 0F 23 AC 07 06 +0F 00 F0 0F 23 AE 07 06 0F 00 F0 0F 73 50 B0 BC +73 50 C0 BC 37 47 00 60 11 07 85 47 05 68 79 75 +93 05 00 02 23 20 07 00 0F 00 F0 0F B3 06 07 01 +23 A0 06 00 0F 00 F0 0F B3 06 A7 00 13 B6 B7 01 +90 C2 0F 00 F0 0F 85 07 93 F7 F7 0F 11 07 E3 9B +B7 FC 05 47 B7 16 00 10 23 A4 E6 80 8D 47 23 A0 +F6 80 B7 96 00 10 23 A2 E6 80 23 A4 E6 80 23 A0 +F6 80 3D 46 B7 16 01 10 23 A2 C6 80 23 A4 E6 80 +23 A0 F6 80 B7 16 02 10 23 A4 E6 80 23 A0 F6 80 +B7 96 02 10 23 A2 F6 80 23 A4 E6 80 23 A0 F6 80 +B7 16 04 10 23 A0 F6 40 23 A2 E6 40 23 A4 F6 40 +1D 46 B7 06 04 10 D0 C2 B7 86 03 10 23 A2 E6 10 +23 A4 E6 10 23 A0 F6 10 11 46 B7 16 03 30 23 AC +C6 80 21 46 23 AC C6 80 23 A4 06 98 23 A6 06 98 +93 05 F0 0F 23 A2 B6 80 93 05 F0 03 23 A4 B6 80 +23 A0 F6 80 B7 26 02 30 23 A4 E6 80 23 A0 F6 80 +37 37 02 30 93 06 F0 07 23 22 D7 80 FD 46 23 24 +D7 80 FD 55 B7 06 03 30 23 20 F7 80 23 A4 B6 64 +B7 07 00 D0 23 A6 B6 64 73 90 07 7F 73 90 17 7F +73 90 27 7F B7 17 00 40 93 87 07 88 73 A0 47 30 +73 20 06 30 82 80 01 00 39 71 3A CE 3E CC 7D 57 +B7 07 03 30 06 DE 16 DC 1A DA 1E D8 2A D6 2E D4 +32 D2 36 D0 42 CA 46 C8 72 C6 76 C4 7A C2 7E C0 +23 A4 E7 64 23 A6 E7 64 B7 07 02 50 03 A7 07 14 +8D 47 63 E5 E7 02 F2 50 E2 52 52 53 C2 53 32 55 +A2 55 12 56 82 56 72 47 E2 47 52 48 C2 48 32 4E +A2 4E 12 4F 82 4F 21 61 73 00 20 30 37 15 02 50 +13 05 45 CD EF 00 30 22 F9 B7 01 00 73 50 40 7D +73 00 20 30 39 71 3E CC B7 07 02 50 3A CE 03 A7 +07 14 06 DE 16 DC 1A DA 1E D8 2A D6 2E D4 32 D2 +36 D0 42 CA 46 C8 72 C6 76 C4 7A C2 7E C0 91 47 +63 EE E7 02 B7 07 00 08 FD 17 73 B0 07 7F 73 B0 +17 7F 73 B0 27 7F F2 50 E2 52 52 53 C2 53 32 55 +A2 55 12 56 82 56 72 47 E2 47 52 48 C2 48 32 4E +A2 4E 12 4F 82 4F 21 61 73 00 20 30 37 15 02 50 +13 05 05 D0 EF 00 30 1A 75 BF 01 00 5D 71 2A DA +13 05 B0 0F 86 C6 96 C4 9A C2 9E C0 22 DE 26 DC +2E D8 32 D6 36 D4 3A D2 3E D0 42 CE 46 CC 4A CA +72 C8 76 C6 7A C4 7E C2 EF 00 F0 14 F3 24 20 34 +37 04 02 50 83 27 04 14 05 47 63 6C F7 04 63 C5 +04 04 F3 27 F0 7F F3 27 10 34 F3 27 30 34 05 45 +EF 00 70 12 13 05 C0 0F EF 00 F0 11 72 54 B6 40 +A6 42 16 43 86 43 E2 54 52 55 C2 55 32 56 A2 56 +12 57 82 57 72 48 E2 48 52 49 42 4E B2 4E 22 4F +92 4F 61 61 73 00 20 30 B5 E3 05 45 EF 00 B0 0E +7D BF 0D 69 13 09 C9 83 A6 85 13 05 C9 2F EF 00 +90 11 83 27 04 14 E3 C1 04 FE F3 25 F0 7F 89 44 +63 FB F4 02 13 05 09 33 EF 00 F0 0F F3 25 10 34 +83 27 04 14 E3 F3 F4 F8 13 05 C9 33 EF 00 B0 0E +F3 25 30 34 83 27 04 14 E3 FB F4 F6 13 05 89 34 +EF 00 70 0D AD B7 F3 27 10 34 85 B7 0D 65 FD 55 +13 05 45 B5 EF 00 30 0C 49 BF 01 00 63 6E 74 5F +61 62 72 5F 6E 6F 74 69 66 3A 25 78 0A 00 00 00 +63 6E 74 5F 61 62 72 5F 65 72 72 6F 72 3A 25 78 +0A 00 00 00 63 6E 74 5F 73 68 61 35 31 32 5F 61 +63 63 5F 65 72 72 6F 72 3A 25 78 0A 00 00 00 00 +63 6E 74 5F 73 68 61 33 5F 6E 6F 74 69 66 3A 25 +78 0A 00 00 63 6E 74 5F 73 68 61 33 5F 65 72 72 +6F 72 3A 25 78 0A 00 00 63 6E 74 5F 73 68 61 32 +35 36 5F 65 72 72 6F 72 3A 25 78 0A 00 00 00 00 +63 6E 74 5F 73 68 61 35 31 32 5F 65 72 72 6F 72 +3A 25 78 0A 00 00 00 00 63 6E 74 5F 6B 76 5F 6E +6F 74 69 66 3A 25 78 0A 00 00 00 00 63 6E 74 5F +6B 76 5F 65 72 72 6F 72 3A 25 78 0A 00 00 00 00 +63 6E 74 5F 68 6D 61 63 5F 65 72 72 6F 72 3A 25 +78 0A 00 00 63 6E 74 5F 65 63 63 5F 65 72 72 6F +72 3A 25 78 0A 00 00 00 63 6E 74 5F 64 6F 65 5F +65 72 72 6F 72 3A 25 78 0A 00 00 00 63 6E 74 5F +61 78 69 5F 64 6D 61 5F 6E 6F 74 69 66 3A 25 78 +0A 00 00 00 45 52 52 4F 52 00 00 00 63 6E 74 5F +61 78 69 5F 64 6D 61 5F 65 72 72 6F 72 3A 25 78 +0A 00 00 00 45 52 52 4F 52 00 00 00 6D 63 61 75 +73 65 3A 25 78 0A 00 00 63 6E 74 5F 73 68 61 35 +31 32 5F 61 63 63 5F 6E 6F 74 69 66 3A 25 78 0A +00 00 00 00 62 61 64 20 73 68 61 35 31 32 5F 61 +63 63 5F 6E 6F 74 69 66 5F 69 6E 74 72 20 73 74 +73 3A 25 78 0A 00 00 00 63 6E 74 5F 73 6F 63 5F +69 66 63 5F 6E 6F 74 69 66 3A 25 78 0A 00 00 00 +62 61 64 20 73 6F 63 5F 69 66 63 5F 6E 6F 74 69 +66 5F 69 6E 74 72 20 73 74 73 3A 25 78 0A 00 00 +63 6E 74 5F 73 6F 63 5F 69 66 63 5F 65 72 72 6F +72 3A 25 78 0A 00 00 00 62 61 64 20 73 6F 63 5F +69 66 63 5F 65 72 72 6F 72 5F 69 6E 74 72 20 73 +74 73 3A 25 78 0A 00 00 63 6E 74 5F 73 68 61 32 +35 36 5F 6E 6F 74 69 66 3A 25 78 0A 00 00 00 00 +62 61 64 20 73 68 61 32 35 36 5F 6E 6F 74 69 66 +5F 69 6E 74 72 20 73 74 73 3A 25 78 0A 00 00 00 +63 6E 74 5F 73 68 61 35 31 32 5F 6E 6F 74 69 66 +3A 25 78 0A 00 00 00 00 62 61 64 20 73 68 61 35 +31 32 5F 6E 6F 74 69 66 5F 69 6E 74 72 20 73 74 +73 3A 25 78 0A 00 00 00 63 6E 74 5F 68 6D 61 63 +5F 6E 6F 74 69 66 3A 25 78 0A 00 00 62 61 64 20 +68 6D 61 63 5F 6E 6F 74 69 66 5F 69 6E 74 72 20 +73 74 73 3A 25 78 0A 00 63 6E 74 5F 65 63 63 5F +6E 6F 74 69 66 3A 25 78 0A 00 00 00 62 61 64 20 +65 63 63 5F 6E 6F 74 69 66 5F 69 6E 74 72 20 73 +74 73 3A 25 78 0A 00 00 63 6E 74 5F 64 6F 65 5F +6E 6F 74 69 66 3A 25 78 0A 00 00 00 62 61 64 20 +64 6F 65 5F 6E 6F 74 69 66 5F 69 6E 74 72 20 73 +74 73 3A 25 78 0A 00 00 49 6E 3A 53 74 64 20 45 +78 63 70 74 6E 0A 6D 63 61 75 73 65 3A 25 78 0A +00 00 00 00 55 6E 65 78 70 65 63 74 65 64 20 49 +6E 74 72 20 62 69 74 3A 25 78 0A 00 6D 73 63 61 +75 73 65 3A 25 78 0A 00 6D 65 70 63 3A 25 78 0A +00 00 00 00 6D 74 76 61 6C 3A 25 78 0A 00 00 00 +03 47 05 00 63 0E 07 4E B7 0E 02 50 03 AE CE 13 +39 71 37 0F 02 50 22 DE AA 87 26 DC 4A DA 4E D8 +52 D6 56 D4 5A D2 5E D0 01 45 93 08 50 02 13 06 +00 03 93 03 D0 02 93 02 A0 02 93 0F 00 02 13 0F +4F 14 25 44 63 03 17 03 23 20 EE 00 05 05 03 C7 +17 00 85 07 65 FB 72 54 E2 54 52 59 C2 59 32 5A +A2 5A 12 5B 82 5B 21 61 82 80 03 C7 17 00 65 D7 +85 07 63 0D 17 05 93 04 00 02 63 19 C7 00 03 C7 +17 00 85 07 E3 0D C7 FE 93 04 00 03 63 05 77 02 +63 08 57 02 13 03 07 FD 93 76 F3 0F 01 48 63 7A +D4 02 13 07 87 FA 13 77 F7 0F E3 E2 EF FA 0A 07 +7A 97 18 43 02 87 03 C7 17 00 85 07 E3 1C 57 FC +03 C7 17 00 91 05 85 07 01 48 E1 BF 23 20 1E 01 +BD BF 25 49 03 C7 17 00 93 16 28 00 C2 96 86 06 +33 08 D3 00 13 03 07 FD 93 76 F3 0F 85 07 E3 73 +D9 FE 45 BF 98 41 83 A6 CE 13 91 05 13 58 C7 01 +63 12 08 14 13 58 87 01 63 15 08 20 13 58 47 01 +63 08 08 34 19 43 B1 AA 03 A3 05 00 81 46 91 05 +13 09 C1 00 A9 49 A5 4B 33 77 33 03 36 8B 85 06 +B3 0A D9 00 1A 8A 13 07 07 03 A3 8F EA FE 33 53 +33 03 E3 E3 4B FF 83 A9 CE 13 33 07 69 01 36 83 +63 D7 06 01 23 A0 99 00 05 03 E3 1D 68 FE 13 03 +B1 00 03 48 07 00 7D 17 23 A0 09 01 E3 1B 67 FE +36 95 F1 BD 03 A3 05 00 91 05 83 46 03 00 E3 88 +06 EC 03 A8 CE 13 1A 87 05 07 23 20 D8 00 83 46 +07 00 FD FA 2A 97 33 05 67 40 55 BD 98 41 91 05 +13 58 E7 01 63 16 08 18 13 58 B7 01 63 1A 08 26 +13 58 87 01 63 0E 08 28 83 A6 CE 13 A5 44 61 AA +83 AB 05 00 83 AA CE 13 91 05 5E 83 63 D9 0B 00 +13 07 D0 02 33 03 70 41 23 A0 EA 00 7D 18 81 46 +13 09 C1 00 A9 49 33 67 33 03 36 8B 85 06 33 0A +D9 00 33 43 33 03 13 07 07 03 A3 0F EA FE E3 14 +03 FE 33 07 69 01 36 83 63 D7 06 01 23 A0 9A 00 +05 03 E3 1D 03 FF 13 03 B1 00 03 48 07 00 7D 17 +23 A0 0A 01 E3 1B 67 FE E3 D4 0B F4 93 06 2B 00 +36 95 31 BD 83 C6 05 00 03 A7 CE 13 05 05 91 05 +14 C3 31 B5 93 74 F8 0F 25 49 13 83 04 03 63 6B +09 1B 13 58 87 01 23 A0 66 00 13 78 F8 00 21 43 +93 04 00 03 63 18 08 0A 13 58 47 01 84 C2 13 78 +F8 00 25 49 93 74 F8 0F 63 71 09 19 93 84 74 03 +93 F4 F4 0F 13 58 07 01 84 C2 13 78 F8 00 25 49 +93 74 F8 0F 63 6F 09 19 93 84 04 03 93 F4 F4 0F +13 58 C7 00 84 C2 13 78 F8 00 25 49 93 74 F8 0F +63 6B 09 19 93 84 04 03 93 F4 F4 0F 13 58 87 00 +84 C2 13 78 F8 00 25 49 93 74 F8 0F 63 68 09 17 +93 84 04 03 93 F4 F4 0F 13 58 47 00 84 C2 13 78 +F8 00 25 49 93 74 F8 0F 63 60 09 15 13 88 04 03 +13 78 F8 0F 23 A0 06 01 93 74 F7 00 25 49 13 88 +04 03 63 54 99 00 13 88 74 03 23 A0 06 01 1A 95 +3D BB 1D 43 93 04 78 03 25 49 93 79 F8 0F 93 F4 +F4 0F E3 63 09 F5 93 89 09 03 93 F4 F9 0F 2D BF +83 A6 CE 13 13 03 08 03 13 58 B7 01 23 A0 66 00 +13 78 78 00 AD 44 13 03 08 03 13 58 87 01 23 A0 +66 00 13 78 78 00 13 08 08 03 13 73 F8 0F 13 58 +57 01 23 A0 66 00 13 78 78 00 13 08 08 03 13 73 +F8 0F 13 58 27 01 23 A0 66 00 13 78 78 00 13 08 +08 03 13 73 F8 0F 13 58 F7 00 23 A0 66 00 13 78 +78 00 13 08 08 03 13 73 F8 0F 13 58 C7 00 23 A0 +66 00 13 78 78 00 13 08 08 03 13 73 F8 0F 13 58 +97 00 23 A0 66 00 13 78 78 00 13 08 08 03 13 73 +F8 0F 13 58 67 00 23 A0 66 00 13 78 78 00 13 08 +08 03 13 73 F8 0F 13 58 37 00 23 A0 66 00 13 78 +78 00 13 08 08 03 13 78 F8 0F 23 A0 06 01 1D 8B +13 07 07 03 98 C2 26 95 99 B9 93 84 04 03 93 F4 +F4 0F 49 B5 13 83 74 03 13 58 87 01 23 A0 66 00 +13 78 F8 00 21 43 93 04 00 03 E3 07 08 E4 DD BD +83 A6 CE 13 A9 44 05 B7 13 88 74 03 13 78 F8 0F +D1 B5 93 84 74 03 93 F4 F4 0F 9D B5 93 84 74 03 +93 F4 F4 0F 51 BD 93 84 74 03 93 F4 F4 0F BD B5 +13 58 57 01 63 0C 08 00 83 A6 CE 13 A1 44 31 B7 +13 58 07 01 63 0C 08 00 15 43 15 B5 13 58 27 01 +63 0C 08 00 83 A6 CE 13 9D 44 11 B7 13 58 C7 00 +63 0C 08 00 11 43 15 B5 13 58 F7 00 63 0C 08 00 +83 A6 CE 13 99 44 F5 BD 13 58 87 00 63 0C 08 00 +0D 43 15 B5 13 58 C7 00 63 0D 08 00 83 A6 CE 13 +95 44 D5 BD 13 58 47 00 05 43 E3 0F 08 E2 09 43 +0D B5 13 58 97 00 63 06 08 00 83 A6 CE 13 91 44 +ED B5 13 58 67 00 63 06 08 00 83 A6 CE 13 8D 44 +FD B5 13 58 37 00 63 06 08 00 83 A6 CE 13 89 44 +CD BD 1D 8B E3 0D 07 B4 83 A6 CE 13 85 44 CD BD +01 45 82 80 39 71 13 03 41 02 2E D2 9A 85 06 CE +32 D4 36 D6 3A D8 3E DA 42 DC 46 DE 1A C6 CD 34 +F2 40 21 61 82 80 B7 07 02 50 83 A7 C7 13 13 75 +F5 0F 88 C3 82 80 B7 07 02 50 83 A7 C7 13 13 75 +F5 0F 88 C3 82 80 83 47 05 00 37 07 02 50 03 27 +C7 13 91 C7 05 05 1C C3 83 47 05 00 E5 FF A9 47 +1C C3 05 45 82 80 39 71 13 03 41 02 2E D2 9A 85 +06 CE 32 D4 36 D6 3A D8 3E DA 42 DC 46 DE 1A C6 +41 34 F2 40 21 61 82 80 F3 25 00 B8 73 25 00 B0 +F3 27 00 B8 E3 9A F5 FE 82 80 00 00 85 47 63 13 +F6 02 93 96 85 01 93 D7 85 01 D5 8F C1 66 13 D7 +85 00 93 86 06 F0 75 8F D9 8F A2 05 37 07 FF 00 +F9 8D DD 8D 0C C1 82 80 01 11 22 CC 26 CA 4A C8 +4E C6 52 C4 06 CE B7 04 02 50 2A 89 2E 8A B2 89 +EF D0 F0 25 03 A7 04 14 91 47 2A 84 63 EE E7 28 +93 77 14 00 63 99 07 26 13 5F 34 40 93 57 14 40 +23 A0 F9 00 CA 86 D2 8E 93 0F 1F 00 01 4E 25 48 +89 45 0D 45 91 42 95 48 99 43 21 49 85 49 63 0C +CF 1F 83 C7 06 00 13 87 07 FD 13 76 F7 0F 63 6D +C8 1A 12 07 21 46 83 C7 16 00 13 83 07 FD 13 7A +F3 0F 63 70 48 03 13 83 F7 F9 13 73 F3 0F 63 F5 +68 1E 13 83 F7 FB 13 73 F3 0F 63 E6 68 16 13 83 +97 FC 33 67 67 00 63 01 B6 14 83 C7 26 00 13 83 +07 FD 13 7A F3 0F 63 70 48 03 13 83 F7 F9 13 73 +F3 0F 63 FE 68 1A 13 83 F7 FB 13 73 F3 0F 63 EC +68 12 13 83 97 FC 32 03 33 67 67 00 63 06 A6 10 +83 C7 36 00 13 83 07 FD 13 7A F3 0F 63 70 48 03 +13 83 F7 F9 13 73 F3 0F 63 F6 68 18 13 83 F7 FB +13 73 F3 0F 63 E1 68 10 13 83 97 FC 22 03 33 67 +67 00 63 0B 56 0C 83 C7 46 00 13 83 07 FD 13 7A +F3 0F 63 70 48 03 13 83 F7 F9 13 73 F3 0F 63 FE +68 14 13 83 F7 FB 13 73 F3 0F 63 E6 68 0C 13 83 +97 FC 52 03 33 67 67 00 63 00 16 0B 83 C7 56 00 +13 83 07 FD 13 7A F3 0F 63 70 48 03 13 83 F7 F9 +13 73 F3 0F 63 F6 68 12 13 83 F7 FB 13 73 F3 0F +63 EB 68 08 13 83 97 FC 42 03 33 67 67 00 63 05 +76 06 83 C7 66 00 13 83 07 FD 13 7A F3 0F 63 70 +48 03 13 83 F7 F9 13 73 F3 0F 63 FE 68 0E 13 83 +F7 FB 13 73 F3 0F 63 E0 68 06 13 83 97 FC 72 03 +33 67 67 00 63 1A 26 03 83 C7 76 00 13 86 07 FD +13 73 F6 0F 63 70 68 02 13 86 F7 F9 13 76 F6 0F +63 F6 C8 0C 13 86 F7 FB 13 76 F6 0F 63 E5 C8 02 +13 86 97 FC 62 06 51 8F 23 A0 EE 00 05 0E 91 0E +A1 06 E3 16 FE E7 F2 40 62 44 D2 44 42 49 B2 49 +22 4A 05 61 82 80 83 A6 04 14 11 47 E3 75 D7 FE +62 44 F2 40 D2 44 42 49 B2 49 22 4A 15 65 BE 85 +13 05 C5 2F 05 61 41 B3 21 46 13 87 F7 F9 13 77 +F7 0F 63 FF E8 00 13 87 F7 FB 13 77 F7 0F E3 E4 +E8 FC 93 87 97 FC 13 97 47 00 E3 16 36 E3 69 BF +93 87 97 FA CD BF 13 76 74 00 49 DA 83 C7 06 00 +25 43 13 87 07 FD 13 7A F7 0F E3 60 43 FD 85 47 +12 07 E3 12 F6 E0 8D BF 13 83 97 FA 1D B5 13 83 +97 FA 91 BD 13 83 97 FA 51 B5 13 83 97 FA 55 BD +13 83 97 FA D5 B5 13 83 97 FA 11 BF 13 86 97 FA +62 06 51 8F 91 B7 03 A7 04 14 91 47 E3 F5 E7 F4 +62 44 F2 40 D2 44 42 49 B2 49 22 4A 37 15 02 50 +13 05 45 D1 05 61 C1 B1 AA 85 15 65 13 05 45 2E +D9 39 B9 BB 79 71 22 D4 26 D2 4A D0 4E CE 52 CC +56 CA 06 D6 5A C8 5E C6 B7 09 02 50 2A 8A AE 8A +32 84 B6 84 EF D0 A0 78 03 A7 09 14 89 47 2A 89 +63 E8 E7 2E 93 77 19 00 63 91 07 2C 13 5F 39 40 +93 57 19 40 56 86 52 88 D6 85 1C C0 93 02 1F 00 +81 46 25 43 09 45 8D 4F 91 43 15 4E 19 4A A1 4A +05 4B 63 02 DF 24 83 47 08 00 13 87 07 FD 93 78 +F7 0F 63 63 13 21 12 07 A1 48 83 47 18 00 93 8E +07 FD 93 FB FE 0F 63 70 73 03 93 8E F7 F9 93 FE +FE 0F 63 7C DE 23 93 8E F7 FB 93 FE FE 0F 63 6A +DE 1B 93 8E 97 FC 33 67 D7 01 63 82 A8 14 83 47 +28 00 93 8E 07 FD 93 FB FE 0F 63 70 73 03 93 8E +F7 F9 93 FE FE 0F 63 75 DE 21 93 8E F7 FB 93 FE +FE 0F 63 60 DE 19 93 8E 97 FC B2 0E 33 67 D7 01 +63 87 F8 11 83 47 38 00 93 8E 07 FD 93 FB FE 0F +63 70 73 03 93 8E F7 F9 93 FE FE 0F 63 7D DE 1D +93 8E F7 FB 93 FE FE 0F 63 65 DE 15 93 8E 97 FC +A2 0E 33 67 D7 01 63 8C 78 0C 83 47 48 00 93 8E +07 FD 93 FB FE 0F 63 70 73 03 93 8E F7 F9 93 FE +FE 0F 63 75 DE 1B 93 8E F7 FB 93 FE FE 0F 63 6A +DE 11 93 8E 97 FC D2 0E 33 67 D7 01 63 81 C8 0B +83 47 58 00 93 8E 07 FD 93 FB FE 0F 63 70 73 03 +93 8E F7 F9 93 FE FE 0F 63 7D DE 17 93 8E F7 FB +93 FE FE 0F 63 6F DE 0D 93 8E 97 FC C2 0E 33 67 +D7 01 63 86 48 07 83 47 68 00 93 8E 07 FD 93 FB +FE 0F 63 70 73 03 93 8E F7 F9 93 FE FE 0F 63 75 +DE 15 93 8E F7 FB 93 FE FE 0F 63 64 DE 0B 93 8E +97 FC F2 0E 33 67 D7 01 63 9B 58 03 83 47 78 00 +93 88 07 FD 93 FE F8 0F 63 70 D3 03 93 88 F7 F9 +93 F8 F8 0F 63 7D 1E 11 93 88 F7 FB 93 F8 F8 0F +63 69 1E 07 93 88 97 FC E2 08 33 67 17 01 98 C1 +85 06 91 05 21 08 E3 96 56 E6 85 47 63 90 F4 04 +1C 40 8D CF 41 68 81 45 13 08 08 F0 B7 08 FF 00 +1C 42 11 06 85 05 13 D7 87 01 13 95 87 01 93 D6 +87 00 49 8F B3 F6 06 01 A2 07 55 8F B3 F7 17 01 +D9 8F 23 2E F6 FE 1C 40 E3 EC F5 FC B2 50 22 54 +92 54 02 59 F2 49 62 4A D2 4A 42 4B B2 4B 45 61 +82 80 03 A7 09 14 7D D3 22 54 B2 50 92 54 02 59 +F2 49 62 4A D2 4A 42 4B B2 4B 15 65 BE 85 13 05 +85 33 45 61 6F F0 3F A6 A1 48 13 87 F7 F9 13 77 +F7 0F 63 7F EE 00 13 87 F7 FB 13 77 F7 0F E3 62 +EE FC 93 87 97 FC 13 97 47 00 E3 90 68 DF 81 BF +93 87 97 FA CD BF 93 78 79 00 E3 83 08 F4 83 47 +08 00 A5 4E 13 87 07 FD 93 7B F7 0F E3 EF 7E FB +85 47 12 07 E3 9B F8 DA 1D B7 93 8E 97 FA E1 BB +93 8E 97 FA 19 B5 93 8E 97 FA 1D BD 93 8E 97 FA +9D B5 93 8E 97 FA 59 BD 93 8E 97 FA D9 B5 93 88 +97 FA E2 08 33 67 17 01 DD BD 83 A7 09 14 9D DF +22 54 B2 50 92 54 02 59 F2 49 62 4A D2 4A 42 4B +B2 4B 37 15 02 50 13 05 45 D1 45 61 6F F0 BF 99 +AA 85 15 65 13 05 05 32 EF F0 FF 9A 21 B3 29 CE +85 47 63 8D F6 00 0A 06 B3 07 C5 00 18 41 11 05 +91 05 23 AE E5 FE E3 9B A7 FE 82 80 93 16 26 00 +C1 68 AA 96 93 88 08 F0 37 03 FF 00 1C 41 91 05 +11 05 13 D7 87 01 13 98 87 01 13 D6 87 00 33 67 +07 01 33 76 16 01 A2 07 51 8F B3 F7 67 00 D9 8F +23 AE F5 FE E3 1C D5 FC 82 80 37 17 01 10 83 27 +47 08 85 8B ED DF 82 80 31 71 22 DD 26 DB 80 01 +4A D9 4E D7 52 D5 56 D3 5A D1 62 CD 66 CB 06 DF +5E CF 6A C9 6E C7 36 8C 03 43 2C 00 B4 4A 83 24 +CC 05 23 2A 64 F8 03 43 3C 00 83 47 0C 00 93 F8 +F4 00 23 24 64 F8 03 43 4C 04 13 F8 F6 00 23 26 +94 F6 23 20 64 F8 03 23 4C 05 23 22 F4 FA 23 20 +14 FB 23 2C 64 F8 03 23 8C 05 23 22 D4 F8 23 28 +04 F9 83 4D 5C 04 23 26 64 F8 03 23 4C 06 93 F7 +C6 FF BD 07 23 24 64 F6 03 23 0C 07 C1 9B 33 01 +F1 40 23 2C 64 F6 03 23 4C 07 03 2B 0C 06 03 4A +8C 06 23 2A 64 F6 03 23 8C 07 93 DC 44 00 93 D9 +46 00 23 28 64 F6 03 23 CC 07 B3 38 10 01 1C 08 +23 22 64 F6 03 43 0C 08 23 26 E4 FA 2A 89 23 24 +64 FA 33 33 00 01 AE 8A B2 84 9A 99 C6 9C 23 2E +F4 F8 37 17 01 10 83 27 47 08 85 8B ED DF 83 26 +C4 FA 37 0D 02 50 05 47 83 27 0D 14 E3 82 E6 44 +09 47 63 67 F7 50 B7 27 01 10 23 AA 07 92 37 17 +01 10 83 2B 47 08 93 FB 1B 00 E3 8C 0B FE 83 27 +44 FA 95 CB 03 47 1C 00 1D E7 37 26 01 10 83 27 +46 A0 85 8B ED DF 83 27 84 F8 13 97 17 00 13 77 +E7 03 13 67 17 00 23 20 E6 A0 37 26 01 10 83 27 +46 A0 89 8B ED DF 83 27 44 FA A2 04 13 77 39 00 +13 96 B7 00 93 F4 04 70 83 27 04 F8 D9 8C 13 97 +2A 00 D1 8C 13 77 F7 0F D9 8C E3 9D 07 3C 83 28 +0D 14 09 47 63 6E 17 29 37 17 01 10 83 27 44 F9 +64 DB 64 DB 89 EB 83 27 84 F8 63 89 07 46 37 27 +01 10 23 20 77 A1 93 07 00 02 63 8E FA 24 37 17 +01 10 83 27 47 08 85 8B ED DF 83 27 44 FA A5 EB +89 47 63 F4 17 01 6F 00 B0 71 03 27 4C 00 B7 17 +01 10 D8 C3 03 27 4C 02 D8 D3 03 27 8C 00 98 C7 +03 27 8C 02 98 D7 03 27 CC 00 D8 C7 03 27 CC 02 +D8 D7 03 27 0C 01 98 CB 03 27 0C 03 98 DB 03 27 +4C 01 D8 CB 03 27 4C 03 D8 DB 03 27 8C 01 98 CF +03 27 8C 03 98 DF 03 27 CC 01 D8 CF 03 27 CC 03 +D8 DF 03 27 0C 02 98 D3 03 27 0C 04 B8 C3 B7 17 +01 10 83 A6 47 08 85 8A ED DE 89 47 E3 E2 17 35 +03 27 CC 04 B7 17 01 10 13 06 00 02 0C 43 EC C3 +4C 43 AC C7 0C 47 EC C7 58 47 B8 CB E3 80 CA 20 +83 27 44 F8 63 8B 07 14 83 2C CC 06 85 47 E3 8B +FC 5E 63 8D 09 08 95 6C 93 87 4C 2E 23 20 F4 FA +83 27 04 F9 83 2D 04 F8 81 4B FD 17 23 22 F4 F6 +83 27 C4 F8 23 2C 84 F7 23 26 04 F8 13 8B C7 00 +83 27 84 F9 5E 8C 23 20 D4 F6 93 8C C7 00 C1 67 +93 87 07 F0 23 2E F4 F8 85 67 93 87 07 80 DA 8B +23 2C F4 F8 66 8B 93 07 00 02 63 84 FA 16 37 17 +01 10 83 27 47 08 C1 8B ED DF 63 15 0A 18 89 47 +63 EF 17 37 05 47 63 00 E9 34 63 09 F9 18 63 88 +0D 1E 03 27 0D 14 63 00 0C 58 05 0C 83 28 0D 14 +C1 0B 41 0B E3 11 3C FD 03 2C 84 F7 83 27 04 F8 +CD C7 83 27 44 F9 D5 E3 89 47 63 F4 17 01 6F 10 +A0 0C 37 27 01 10 83 27 C7 A0 89 8B ED DF 89 44 +03 49 6C 04 63 F4 14 01 6F 10 40 0C 85 47 63 14 +F9 00 6F 10 60 31 37 25 01 10 13 05 C5 A0 EF 90 +60 53 95 A0 83 27 84 FA 03 2B 04 F7 83 25 44 F7 +13 85 F7 FF 13 35 15 00 CE 87 83 29 44 F6 2A C4 +5E C2 66 C0 A6 88 83 24 44 F8 03 25 84 F7 52 86 +DA 86 4E 87 26 88 EF B0 F0 7C 83 26 C4 F9 13 DA +24 00 81 47 26 87 01 46 5A 85 CE 85 EF B0 D0 07 +63 0B 0A 00 83 27 84 FA 63 14 99 01 6F 10 E0 18 +99 E3 6F 10 60 2E 83 28 0D 14 37 17 01 10 83 27 +47 08 85 8B ED DF 93 07 00 02 E3 85 FA 28 89 47 +E3 E9 17 41 B7 17 01 10 21 67 F8 DB F8 DB 19 47 +23 A0 E7 08 13 01 04 F4 FA 50 6A 54 DA 54 4A 59 +BA 59 2A 5A 9A 5A 0A 5B FA 4B 6A 4C DA 4C 4A 4D +BA 4D 29 61 82 80 37 17 01 10 83 27 47 08 85 8B +ED DF 93 07 10 40 23 24 F7 08 23 24 F7 08 41 BB +95 68 13 85 C8 37 A6 85 EF F0 EF D1 83 28 0D 14 +A1 BB 93 87 F9 FF 63 03 0C 6C E3 1A FC E8 83 27 +04 F9 E3 86 07 E8 93 95 67 00 93 E5 85 00 37 17 +01 10 83 27 47 08 85 8B ED DF 23 24 B7 08 23 24 +B7 08 B5 B5 64 5B 03 27 84 F9 89 47 B9 8C 63 E8 +17 1F 05 47 63 09 E9 1A 63 12 F9 04 03 27 0D 14 +91 4C 63 E0 EC 20 83 26 C4 FA 85 45 83 A7 4B FF +63 8A B6 5C 37 17 01 10 7C CB 03 A7 8B FF B7 17 +01 10 B8 CF 03 A7 CB FF B7 17 01 10 F8 CF 83 A7 +0B 00 37 17 01 10 3C D3 E3 0B 0A E2 B7 17 01 10 +03 27 0D 14 E4 DB E4 DB 89 47 E3 F2 E7 E2 B7 17 +02 50 13 85 07 E4 EF F0 0F C5 E3 9C 0D E0 37 17 +01 10 83 27 47 08 A1 8B ED DF B7 07 03 30 83 A7 +C7 54 85 8B 95 CB 83 27 84 F7 83 26 44 FA 23 80 +D7 00 83 26 44 F9 23 81 D7 00 83 26 84 F8 A3 81 +D7 00 8C 43 B7 07 00 FF 93 87 F7 0F FD 8D B7 07 +00 10 85 07 63 89 F5 62 37 17 01 10 83 27 47 08 +91 8B 99 C7 83 27 84 FA 99 E3 6F 10 20 05 81 47 +37 17 01 10 83 25 0D 14 83 2C 47 06 0D 47 63 67 +B7 4A 03 27 C4 F8 93 08 F7 FF 13 87 F9 FF 46 8F +63 0E 87 21 63 93 07 24 85 45 63 03 B9 5A 89 45 +E3 0F B9 08 B7 15 01 10 03 25 0D 14 83 AC 85 06 +8D 45 63 E9 A5 48 FA 8F 63 04 87 1B 63 9D 07 1C +85 45 63 00 B9 5A 89 45 E3 02 B9 00 B7 15 01 10 +03 25 0D 14 83 AC C5 06 8D 45 63 E9 A5 48 FE 88 +63 01 87 25 63 98 07 26 85 45 63 0B B9 5A 89 45 +E3 08 B9 06 B7 15 01 10 03 25 0D 14 83 AC 05 07 +8D 45 63 E9 A5 12 63 02 87 27 63 93 07 28 85 47 +63 02 F9 60 89 47 E3 1A F9 D0 83 27 84 FA E3 96 +07 D0 83 27 0B 00 5A 87 B3 C7 FC 00 B3 F7 17 01 +E3 8D 07 CE E6 87 8D 45 6F 00 60 7B 8D 4B 41 BE +37 15 02 50 13 05 C5 D6 EF F0 EF B0 B7 27 01 10 +23 AA 07 92 ED B4 03 27 0D 14 91 4C 63 E6 EC 34 +83 26 C4 FA 85 45 83 27 4B FF 63 83 B6 28 37 17 +01 10 7C CB 03 27 8B FF B7 17 01 10 B8 CF 03 27 +CB FF B7 17 01 10 F8 CF 83 27 0B 00 99 BD 83 27 +04 FA E2 85 13 85 C7 21 EF F0 EF AD 85 47 E3 0C +F9 FA 89 47 E3 12 F9 E4 03 27 0D 14 91 4C E3 F4 +EC E0 83 27 04 FA 83 A5 4B FF 93 87 C7 23 3E 85 +23 2E F4 F6 EF F0 2F AB 83 26 C4 FA 85 45 03 27 +0D 14 83 A7 4B FF 63 8F B6 3A 37 13 01 10 23 2A +F3 04 E3 F4 EC DE 83 A5 8B FF 03 25 C4 F7 EF F0 +8F A8 03 A7 8B FF 83 27 0D 14 37 13 01 10 23 2C +E3 04 E3 F9 FC DC 83 A5 CB FF 03 25 C4 F7 EF F0 +8F A6 03 27 0D 14 83 A7 CB FF B7 15 01 10 FC CD +91 47 E3 FE E7 DA 83 A5 0B 00 03 25 C4 F7 EF F0 +8F A4 75 B3 23 2A F4 F6 83 27 04 FA E6 85 23 28 +14 F7 13 85 C7 29 23 2E E4 F6 EF F0 CF A2 03 27 +C4 F7 83 28 04 F7 83 27 44 F7 E3 18 87 EB 31 A2 +83 26 04 F9 E3 8C 06 E4 83 26 44 F8 93 F5 C6 00 +E3 86 05 E4 93 FF 86 00 E3 9B 0F 3E 93 F5 36 00 +83 26 04 F6 8E 05 05 4F 33 1F BF 00 23 26 D4 F8 +7D 1F E3 87 07 E2 83 26 84 FA E3 99 06 E2 B3 FC +EC 01 E3 85 0C E2 E6 87 85 45 91 A0 83 26 04 F9 +E3 82 06 DE 83 26 44 F8 13 FF C6 00 E3 14 0F 16 +93 F5 36 00 83 26 04 F6 8E 05 85 48 B3 98 B8 00 +23 26 D4 F8 FD 18 E3 81 07 DC 83 26 84 FA E3 93 +06 DC B3 FC 1C 01 E3 8F 0C DA E6 87 81 45 95 64 +93 84 44 2E 13 85 04 2B 23 26 F4 FA EF F0 AF 97 +83 27 C4 FA 13 85 84 2D BE 85 EF F0 CF 96 37 15 +02 50 13 05 05 EC EF F0 0F 94 05 45 EF F0 AF 91 +01 A0 83 26 44 F6 A9 45 E3 EE D5 DA 83 26 44 F8 +93 F5 86 00 E3 88 05 DA 93 F5 36 00 83 26 04 F6 +8E 05 85 4F B3 9F BF 00 23 26 D4 F8 FD 1F 81 48 +E3 8C 07 D8 83 26 84 FA E3 9E 06 D8 B3 FC FC 01 +E3 8A 0C D8 E6 87 89 45 59 B7 83 26 04 F9 2D 47 +E3 7D D7 D8 03 27 44 F8 85 48 0D 8B 0E 07 B3 98 +E8 00 03 27 04 F6 FD 18 23 26 E4 F8 E3 81 07 D8 +83 27 84 FA E3 9B 07 A8 B3 FC 1C 01 E3 87 0C A8 +E6 87 8D 45 A9 B7 83 27 44 FA E3 80 07 A8 89 47 +63 E7 E7 02 B7 25 01 10 83 A7 45 A0 89 8B ED DF +83 26 44 F9 85 47 E3 8E F6 50 89 47 63 EC E7 7A +37 25 01 10 13 05 45 A0 EF 80 D0 7D B9 B4 37 15 +02 50 13 05 45 ED EF F0 0F 87 03 27 0D 14 D9 B7 +83 26 C4 F9 93 D5 87 01 93 98 87 01 13 D5 87 00 +75 8D B3 E5 15 01 C9 8D A2 07 37 05 FF 00 E9 8F +CD 8F B7 15 01 10 FC C9 91 47 63 ED E7 34 83 27 +8B FF 83 26 C4 F9 93 D5 87 01 93 98 87 01 13 D5 +87 00 75 8D B3 E5 15 01 C9 8D A2 07 37 05 FF 00 +E9 8F CD 8F B7 15 01 10 BC CD 91 47 63 E3 E7 30 +83 27 CB FF 83 26 C4 F9 93 D5 87 01 93 98 87 01 +13 D5 87 00 75 8D B3 E5 15 01 C9 8D A2 07 37 05 +FF 00 E9 8F CD 8F B7 15 01 10 FC CD 91 47 63 EB +E7 2A 83 27 0B 00 83 26 C4 F9 13 D7 87 01 13 95 +87 01 93 D5 87 00 F5 8D 49 8F 4D 8F A2 07 B7 05 +FF 00 ED 8F D9 8F 35 BE 83 25 4B FF 95 67 13 85 +87 53 EF E0 5F FC 83 26 C4 FA 85 45 03 27 0D 14 +83 27 4B FF E3 86 B6 F2 B7 18 01 10 23 AA F8 04 +E3 F2 EC CA 83 25 8B FF 95 67 13 85 87 53 EF E0 +9F F9 03 27 8B FF 83 27 0D 14 B7 18 01 10 23 AC +E8 04 E3 F6 FC C8 83 25 CB FF 95 67 13 85 87 53 +EF E0 7F F7 03 27 0D 14 83 27 CB FF B7 15 01 10 +FC CD 91 47 E3 FA E7 C6 83 25 0B 00 95 67 13 85 +87 53 EF E0 5F F5 83 27 0B 00 65 BC 23 2E F4 F6 +83 27 04 FA E6 85 13 85 C7 29 EF E0 DF F3 83 27 +C4 F7 81 B6 23 2A F4 F6 83 27 04 FA E6 85 23 28 +E4 F7 13 85 C7 29 23 2E E4 F6 EF E0 DF F1 03 2F +04 F7 83 27 44 F7 03 27 C4 F7 B1 B6 23 2A F4 F6 +83 27 04 FA E6 85 23 28 F4 F7 13 85 C7 29 23 2E +E4 F6 EF E0 5F EF 83 2F 04 F7 83 27 44 F7 03 27 +C4 F7 B1 B6 83 26 C4 F9 93 D5 87 01 93 98 87 01 +13 D5 87 00 75 8D B3 E5 15 01 C9 8D A2 07 37 05 +FF 00 E9 8F CD 8F B7 15 01 10 FC C9 91 47 63 E7 +E7 5A 83 A7 8B FF 83 26 C4 F9 93 D5 87 01 93 98 +87 01 13 D5 87 00 75 8D B3 E5 15 01 C9 8D A2 07 +37 05 FF 00 E9 8F CD 8F B7 15 01 10 BC CD 91 47 +63 E9 E7 54 83 A7 CB FF 83 26 C4 F9 93 D5 87 01 +93 98 87 01 13 D5 87 00 75 8D B3 E5 15 01 C9 8D +A2 07 37 05 FF 00 E9 8F CD 8F B7 15 01 10 FC CD +91 47 63 E0 E7 50 83 A7 0B 00 B1 BD 85 47 93 05 +80 40 E3 96 F9 94 83 27 04 F9 E3 82 07 94 25 BA +83 26 84 FA E3 90 06 A6 83 A5 4B FF B3 C5 BC 00 +B3 F5 15 01 E3 88 05 A4 E6 87 93 82 4B FF 81 45 +8D A0 83 26 84 FA E3 93 06 A6 83 A5 8B FF B3 C5 +BC 00 B3 F5 E5 01 E3 8B 05 A4 E6 87 93 82 8B FF +FA 88 85 45 3D A8 85 47 E3 98 FA 9C 83 27 47 08 +91 8B 89 E7 83 27 84 FA E3 88 07 3E 85 47 C9 BA +83 26 84 FA E3 98 06 A4 83 A5 CB FF B3 C5 BC 00 +B3 F5 F5 01 E3 80 05 A4 E6 87 93 82 CB FF FE 88 +89 45 95 64 93 84 44 2E 13 85 04 2F 23 24 54 FA +23 22 14 FB 23 26 F4 FA EF E0 FF D9 83 27 C4 FA +83 28 44 FA 13 85 84 31 B3 F5 F8 00 23 26 14 FB +EF E0 7F D8 83 22 84 FA 83 28 C4 FA 13 85 04 33 +83 A5 02 00 B3 F5 B8 00 EF E0 FF D6 05 45 EF E0 +9F D2 01 A0 83 27 84 FA 63 99 07 F0 83 A7 0B 00 +DE 82 B3 C7 FC 00 B3 F7 17 01 63 80 07 F0 E6 87 +8D 45 41 BF 83 25 0B 00 95 67 13 85 87 53 EF E0 +9F D3 83 26 C4 FA 05 47 83 27 0B 00 E3 8D E6 D2 +49 B8 83 25 CB FF 95 67 13 85 87 53 EF E0 BF D1 +83 26 C4 FA 85 45 03 27 0D 14 83 27 CB FF E3 83 +B6 CE 69 BB 83 25 8B FF 95 67 13 85 87 53 EF E0 +9F CF 03 27 0D 14 83 27 8B FF 61 B9 83 27 C4 F6 +63 80 07 E0 63 8E 0C DE 03 27 04 FA 93 DF 27 00 +85 47 BA 9F 5A 8F 63 8B FC 72 13 06 40 40 C1 45 +95 67 93 87 47 2E 23 2E F4 F6 C1 67 0D 4B 93 87 +07 F0 23 2E 94 F4 23 2C 34 F5 E6 84 81 4D DA 8C +B7 1B 01 10 56 8B 23 20 F4 F6 CA 8A 23 2A D4 F4 +FE 89 7A 89 83 A7 4B 08 85 8B ED DF 89 47 63 E0 +17 67 23 A4 CB 08 23 A4 CB 08 83 A7 4B 08 C1 8B +ED DF 89 47 63 E5 17 5D 93 97 2D 00 63 E0 37 4F +23 AA 0B 04 93 87 EC FF 63 E4 37 43 23 AC 0B 04 +93 87 FC FF 63 F9 37 57 03 27 C4 FA 85 46 83 27 +89 00 63 0A D7 5C 23 AE FB 04 63 FC 3C 45 83 27 +C9 00 23 A0 FB 06 85 0D 41 09 91 0C 63 8A B4 45 +93 87 F4 FF 63 8C B7 5D 89 47 E3 F0 17 FB B7 17 +02 50 13 85 C7 DB EF E0 1F BF 83 28 0D 14 71 B7 +09 47 63 67 F7 5C B7 27 01 10 05 47 23 AA E7 92 +6F F0 EF BB 03 26 8C 04 37 25 01 10 EE 85 13 05 +85 A0 EF 80 50 40 83 28 0D 14 09 47 63 7E 17 C1 +95 68 EE 85 13 85 C8 35 EF E0 FF BC 6F F0 2F C0 +37 15 02 50 13 05 C5 DA 23 2E D4 F6 EF E0 BF B9 +83 28 0D 14 83 26 C4 F7 6F F0 8F CA 83 26 84 FA +63 9E 06 FE 83 25 8B FF B3 C5 BC 00 B3 F5 E5 01 +63 86 05 FE E6 87 13 07 8B FF FA 88 85 45 95 64 +93 84 44 2E 13 85 84 34 23 24 E4 FA 23 22 14 FB +23 26 F4 FA EF E0 3F B7 83 27 C4 FA 83 28 44 FA +13 85 04 37 B3 F5 F8 00 23 26 14 FB EF E0 BF B5 +03 27 84 FA 83 28 C4 FA 13 85 84 38 0C 43 B3 F5 +B8 00 EF E0 5F B4 05 45 EF E0 FF AF 01 A0 83 26 +84 FA 63 91 06 F6 83 25 4B FF B3 C5 BC 00 B3 F5 +15 01 63 89 05 F4 E6 87 13 07 4B FF 81 45 41 BF +83 26 84 FA 63 98 06 F8 83 25 CB FF B3 C5 BC 00 +B3 F5 F5 01 63 80 05 F8 E6 87 13 07 CB FF FE 88 +89 45 B5 B7 83 27 44 F9 63 9B 07 D6 03 25 C4 F6 +B7 05 FF 00 13 06 00 42 93 16 35 00 93 17 B5 00 +ED 8F 13 D9 86 00 93 D5 86 01 C1 66 23 24 C7 08 +CD 8F 93 86 06 F0 93 15 B5 01 33 79 D9 00 CD 8F +23 24 C7 08 11 47 33 69 F9 00 63 60 17 69 03 27 +C4 FA B7 17 01 10 23 AA 07 04 85 47 63 15 F7 02 +93 16 89 01 93 57 89 01 D5 8F C1 66 13 57 89 00 +93 86 06 F0 75 8F D9 8F 22 09 37 07 FF 00 33 79 +E9 00 33 E9 27 01 03 26 44 F8 B7 06 FF 00 93 17 +36 00 13 17 B6 00 75 8F 93 D6 87 01 93 D4 87 00 +B3 67 D7 00 41 67 13 07 07 F0 F9 8C 93 16 B6 01 +37 17 01 10 D5 8F 23 2C 27 05 11 47 DD 8C 63 6D +17 5F 03 27 C4 FA B7 17 01 10 23 AE 07 04 85 47 +63 13 F7 02 93 96 84 01 93 D7 84 01 D5 8F C1 66 +13 D7 84 00 93 86 06 F0 75 8F D9 8F A2 04 37 07 +FF 00 F9 8C DD 8C B7 17 01 10 A4 D3 37 17 01 10 +83 27 47 08 A1 8B ED DF 03 27 C4 FA 85 47 63 0E +F7 4E 83 25 84 F6 41 46 13 05 04 FB 23 26 14 FB +EF C0 00 26 83 28 C4 FA 89 47 63 E8 17 4B 83 27 +84 FA 63 90 07 44 B7 17 01 10 E4 53 83 27 04 FB +63 9F 97 7A B7 17 01 10 03 27 0D 14 A4 57 8D 47 +63 EB E7 68 83 27 44 FB 63 9A 97 74 37 19 01 10 +83 27 0D 14 83 24 C9 06 0D 4A 63 62 FA 64 83 27 +84 FB 95 68 93 88 48 2E 63 91 F4 78 83 24 09 07 +83 27 C4 FB 63 96 97 76 83 28 0D 14 89 47 63 FB +17 BF 37 15 02 50 13 05 05 FA EF E0 DF 93 6F F0 +6F BE 83 A5 0B 00 15 65 13 05 05 52 EF E0 BF 94 +83 26 C4 FA 05 47 83 A7 0B 00 E3 86 E6 94 6F F0 +4F CA 83 A5 CB FF 15 65 93 07 05 52 3E 85 23 2E +F4 F6 EF E0 5F 92 83 26 C4 FA 85 45 03 27 0D 14 +83 A7 CB FF E3 8A B6 A8 6F F0 2F EB 83 A5 8B FF +15 65 13 05 05 52 EF E0 1F 90 03 27 0D 14 83 A7 +8B FF 91 B4 37 15 02 50 13 05 85 F0 EF E0 BF 8C +6F F0 1F 84 89 44 83 49 1C 08 63 ED 14 2D 63 84 +99 31 81 44 81 49 01 4A 83 47 2C 08 93 8B 0A FE +85 4C 93 BB 1B 00 63 97 97 AD 03 27 0D 14 89 47 +63 EE E7 48 85 47 3E C0 5E C2 03 27 44 F6 03 28 +44 F8 83 26 04 F7 03 25 84 F7 83 25 44 F7 CE 87 +A6 88 52 86 EF B0 00 38 13 07 40 06 B7 17 01 10 +83 A6 47 08 7D 17 F4 DB F4 DB 7D FB 37 15 02 50 +13 05 45 E0 EF E0 3F 85 05 45 EF E0 DF 82 01 A0 +37 15 02 50 13 05 45 D9 EF E0 FF 83 83 28 0D 14 +6F F0 AF 8D 46 8F 6F F0 EF C6 63 FB 17 01 83 25 +49 00 95 67 13 85 07 40 EF E0 FF 83 83 28 0D 14 +03 27 C4 FA 85 46 83 27 49 00 63 05 D7 06 23 AC +FB 04 13 86 FC FF 8D 47 63 6A 36 0D 63 FD 17 13 +83 27 C4 F7 B2 85 13 85 87 0F EF E0 DF 80 83 28 +0D 14 23 AE 0B 04 8D 47 63 E1 3C 0F 63 FB 17 01 +83 27 C4 F7 E6 85 13 85 87 0F EF E0 CF FE 83 28 +0D 14 23 A0 0B 06 85 0D 41 09 91 0C E3 9A B4 BB +56 89 83 24 C4 F5 83 29 84 F5 83 26 44 F5 DA 8A +6F F0 0F 8E 03 27 04 F6 93 D6 87 01 93 95 87 01 +13 D6 87 00 79 8E CD 8E D1 8E A2 07 37 06 FF 00 +F1 8F D5 8F AD BF 63 FB 17 01 83 25 09 00 95 67 +13 85 07 40 EF E0 2F F9 83 28 0D 14 03 27 C4 FA +85 46 83 27 09 00 63 0F D7 06 23 AA FB 04 13 86 +EC FF 8D 47 E3 63 36 F3 E3 FA 17 B1 83 27 C4 F7 +B2 85 13 85 87 0F EF E0 0F F6 83 28 0D 14 13 86 +FC FF 23 AC 0B 04 8D 47 E3 7A 36 F3 E3 FE 17 AF +83 25 89 00 95 67 13 85 07 40 EF E0 CF F3 03 27 +C4 FA 85 46 83 28 0D 14 83 27 89 00 63 0D D7 0A +23 AE FB 04 8D 47 E3 F3 3C F3 63 F2 17 05 83 25 +C9 00 95 67 66 86 13 85 07 40 EF E0 CF F0 83 28 +0D 14 35 A0 03 27 04 F6 93 D6 87 01 93 95 87 01 +13 D6 87 00 79 8E CD 8E D1 8E A2 07 37 06 FF 00 +F1 8F D5 8F 9D B7 23 AE 0B 04 E3 FC 3C EF 03 27 +C4 FA 85 46 83 27 C9 00 E3 1D D7 A8 03 27 04 F6 +93 D6 87 01 93 95 87 01 13 D6 87 00 79 8E CD 8E +D1 8E A2 07 37 06 FF 00 F1 8F D5 8F 9D BC 83 27 +C4 F7 EE 85 13 85 07 0E EF E0 EF E9 13 96 2D 00 +83 28 0D 14 8D 47 E3 68 36 EF E3 F3 17 A3 83 27 +C4 F7 B2 85 13 85 87 0F EF E0 EF E7 83 28 0D 14 +23 AA 0B 04 ED BD 03 27 04 F6 93 D6 87 01 93 95 +87 01 13 D6 87 00 79 8E CD 8E D1 8E A2 07 37 06 +FF 00 F1 8F D5 8F 23 AE FB 04 2D B7 83 27 04 FA +E3 84 07 A2 13 96 67 00 BE 85 13 66 46 00 5D B2 +37 15 02 50 13 05 85 D4 EF E0 EF E0 2D B4 15 65 +13 05 C5 39 23 28 C4 F4 EF E0 EF E1 03 26 04 F5 +83 28 0D 14 23 A4 CB 08 23 A4 CB 08 F5 B2 FA 8F +6F F0 CF A4 03 27 04 F7 83 26 44 F6 03 26 84 F7 +83 25 44 F7 95 68 13 85 48 42 EF E0 CF DE E3 9A +99 D1 83 27 0D 14 63 F8 F4 00 37 15 02 50 13 05 +45 DD EF E0 4F DB D1 44 EF B0 10 47 13 7A F5 0F +EF B0 90 46 93 79 F5 0F EF B0 10 46 33 77 95 02 +B3 67 3A 01 85 8B D9 8F E5 D3 85 47 13 7A 1A 00 +93 F9 19 00 BA 84 23 24 F4 FA F9 B1 13 06 40 40 +C1 45 E3 07 07 8C 13 16 67 00 BA 85 13 66 46 00 +C1 B0 B7 17 01 10 FC 53 B7 19 01 10 83 27 0D 14 +83 A5 89 06 0D 49 63 6B F9 1E B7 17 01 10 FC 57 +B7 17 01 10 BC 5B CD BE 37 15 02 50 13 05 05 F2 +EF E0 6F D3 83 28 0D 14 6F E0 BF F2 37 15 02 50 +13 05 05 F4 EF E0 2F D2 85 47 63 0D F9 22 83 27 +0D 14 63 E4 F4 00 6F E0 1F F3 37 15 02 50 13 05 +05 F7 EF E0 4F D0 6F E0 1F F2 37 15 02 50 13 05 +45 F8 EF E0 4F CF 83 27 84 FA 03 27 0D 14 63 87 +07 22 B7 17 01 10 EC 53 8D 46 63 F5 E6 24 15 65 +13 05 85 6B EF E0 2F CF 85 BF 83 27 84 F6 41 6F +13 0F 0F F0 94 43 03 A8 47 00 88 47 DC 47 13 DE +86 01 93 95 86 01 93 D4 86 00 13 16 88 01 93 5A +88 01 93 53 88 00 13 5A 85 01 93 19 85 01 93 52 +85 00 13 D7 87 01 13 99 87 01 93 DE 87 00 B7 0F +FF 00 B3 E5 C5 01 B3 F4 E4 01 13 9E 86 00 33 66 +56 01 B3 F3 E3 01 22 08 B3 66 3A 01 B3 F2 E2 01 +22 05 33 67 27 01 B3 FE EE 01 A2 07 C5 8D 33 7E +FE 01 33 66 76 00 33 78 F8 01 B3 E6 56 00 33 75 +F5 01 33 67 D7 01 B3 F7 F7 01 B3 E5 C5 01 33 66 +06 01 C9 8E D9 8F 23 28 B4 FA 23 2A C4 FA 23 2C +D4 FA 23 2E F4 FA 8D BC 95 68 13 85 C8 69 A6 85 +EF E0 6F C3 83 28 0D 14 ED BA 95 68 13 85 48 68 +CA 85 EF E0 4F C2 83 28 0D 14 95 BA 37 15 02 50 +13 05 85 DE EF E0 2F BF B1 BE 99 C3 6F E0 BF E7 +83 29 C4 F8 83 27 C4 F9 81 44 94 43 03 A7 09 00 +63 8A E6 04 15 69 13 09 49 2E A6 85 13 05 C9 16 +EF E0 6F BE 03 27 C4 F9 93 97 24 00 13 05 49 19 +BA 97 8C 43 EF E0 2F BD 83 A5 09 00 13 05 C9 1A +EF E0 6F BC 05 45 EF E0 0F B8 01 A0 83 25 47 08 +15 65 13 05 05 55 91 89 EF E0 EF BA 05 45 EF E0 +8F B6 01 A0 85 04 91 09 91 07 E3 10 9A FA 6F E0 +9F E0 89 47 63 E9 E7 0C 37 25 01 10 13 05 45 A0 +EF 80 60 31 83 28 0D 14 6F E0 3F DF 95 64 93 84 +84 6B 26 85 EF E0 2F B7 83 27 0D 14 83 A5 C9 06 +E3 70 F9 E0 26 85 EF E0 0F B6 83 27 0D 14 83 A5 +09 07 E3 73 F9 9E 26 85 EF E0 EF B4 F1 BA 95 68 +93 88 48 2E 93 89 48 3D A6 85 4E 85 23 26 14 FB +EF E0 6F B3 83 27 84 FB 83 28 C4 FA 63 97 97 12 +83 27 0D 14 83 24 09 07 E3 74 FA 9A A6 85 4E 85 +EF E0 6F B1 71 BA 95 68 A6 85 13 85 88 6B EF E0 +8F B0 8D B2 83 27 0D 14 63 F8 F4 00 37 15 02 50 +13 05 C5 F5 EF E0 2F AD 37 25 01 10 13 05 C5 A0 +EF 80 60 27 83 28 0D 14 6F E0 3F D5 B7 17 01 10 +E4 53 8D 47 E3 FC E7 90 95 68 A6 85 13 85 88 6B +EF E0 6F AC 21 B2 37 15 02 50 13 05 45 EF EF E0 +8F A9 1D B7 BC 57 91 B3 89 47 63 04 F9 00 6F E0 +9F D1 83 29 84 F9 83 27 C4 F9 81 44 83 A6 09 00 +98 43 63 8E E6 02 15 69 13 09 49 2E A6 85 13 05 +49 1C EF E0 4F A8 03 27 C4 F9 93 97 24 00 13 05 +C9 1E BA 97 8C 43 EF E0 0F A7 83 A5 09 00 13 05 +49 20 EF E0 4F A6 05 45 EF E0 EF A1 01 A0 85 04 +91 09 91 07 E3 1C 9A FA 6F E0 FF CB 95 68 05 49 +93 88 48 2E CA 85 13 85 08 3E 23 26 14 FB EF E0 +8F A3 83 28 C4 FA A6 85 13 85 48 40 EF E0 AF A2 +03 27 84 F6 93 17 29 00 83 28 C4 FA BA 97 8C 43 +13 85 C8 41 EF E0 2F A1 05 45 EF E0 CF 9C 01 A0 +95 68 0D 49 93 88 48 2E 75 BF 09 49 65 BF 95 68 +01 49 93 88 48 2E 7D B7 37 15 02 50 13 05 05 E6 +EF E0 6F 9C 05 45 EF E0 0F 9A 01 A0 13 01 01 C9 +23 26 71 35 B7 0B 02 50 23 2A 51 35 83 AA 0B 14 +23 24 81 36 23 22 91 36 23 20 21 37 23 2C 41 35 +23 28 61 35 2E CF 23 26 11 36 23 2E 31 35 23 24 +81 35 2A CD 89 45 32 84 36 8B 3A 8A 3E 89 C2 84 +63 EC 55 31 C1 47 63 F8 67 01 63 9A 0A 32 05 45 +EF E0 6F 94 01 A0 B7 08 02 50 93 85 88 1C BC 19 +93 88 88 1C 13 88 05 04 03 A5 08 00 03 A6 48 00 +83 A6 88 00 03 A7 C8 00 88 C3 D0 C3 94 C7 D8 C7 +C1 08 C1 07 E3 92 08 FF B7 17 58 26 93 87 37 92 +3E D7 3E DF B7 47 63 94 93 87 F7 37 BE C5 B7 27 +2F FE 93 87 97 6E B7 D6 E2 95 BE C7 B7 D7 DC 33 +83 A8 05 05 93 86 B6 DA 93 87 37 85 03 AF 05 04 +83 AE 45 04 03 AE 85 04 03 A3 C5 04 03 A8 45 05 +A8 4D F0 4D 37 47 EA D5 36 D9 BE C9 B7 86 41 5B +B7 07 22 B3 13 07 27 D1 93 87 37 50 93 86 06 37 +3A D5 3A DD C6 D5 BE CB 36 DB 82 C1 82 C3 FA CD +F6 CF F2 D1 9A D3 C2 D7 AA D9 B2 DB 93 87 05 06 +38 1A 93 88 05 0A 03 A8 07 00 C8 43 90 47 D4 47 +23 20 07 01 48 C3 10 C7 54 C7 C1 07 41 07 E3 94 +17 FF 93 87 05 0A B8 1A 93 88 05 0E 03 A8 07 00 +C8 43 90 47 D4 47 23 20 07 01 48 C3 10 C7 54 C7 +C1 07 41 07 E3 94 17 FF 93 87 05 0E 38 1B 93 88 +05 12 03 A8 07 00 C8 43 90 47 D4 47 23 20 07 01 +48 C3 10 C7 54 C7 C1 07 41 07 E3 94 17 FF 93 88 +05 12 BC 1B 13 88 05 16 03 A5 08 00 03 A6 48 00 +83 A6 88 00 03 A7 C8 00 88 C3 D0 C3 94 C7 D8 C7 +C1 08 C1 07 E3 92 08 FF 93 88 05 16 3C 1C 13 88 +05 1A 03 A5 08 00 03 A6 48 00 83 A6 88 00 03 A7 +C8 00 88 C3 D0 C3 94 C7 D8 C7 C1 08 C1 07 E3 92 +08 FF 93 88 05 1A BC 1C 93 85 05 1E 03 A5 08 00 +03 A6 48 00 83 A6 88 00 03 A7 C8 00 88 C3 D0 C3 +94 C7 D8 C7 C1 08 C1 07 E3 92 B8 FE 13 06 80 08 +81 45 28 1D EF B0 30 1A 93 3B 19 00 C1 47 85 0B +63 82 F4 16 85 47 13 0C 81 17 63 81 F4 02 93 07 +00 02 63 88 F4 16 89 47 63 8A F4 16 91 47 63 83 +F4 18 A1 47 93 09 81 0A 63 83 F4 18 5E 57 23 22 +04 02 23 24 04 02 18 D0 4E 57 23 26 04 02 23 28 +04 02 58 CC 3E 57 23 2A 04 02 23 2C 04 02 18 CC +2E 57 23 2E 04 02 23 20 04 04 58 C8 1E 57 18 C8 +0E 57 58 C4 6E 47 58 C0 7E 47 18 C4 63 14 0B 00 +13 0B 00 04 89 47 63 E0 57 13 13 16 2B 00 63 0E +09 0C E2 85 52 85 EF B0 A0 7C BC 01 23 2E F1 30 +22 86 3C 1D 13 08 04 04 08 42 4C 42 14 46 58 46 +88 C3 CC C3 94 C7 D8 C7 41 06 C1 07 E3 16 06 FF +10 42 EA 46 7A 47 90 C3 BC 19 23 26 F1 30 85 47 +23 00 F1 32 23 22 31 31 23 24 61 31 23 28 81 31 +23 2E D1 2E 23 20 E1 30 3C 1D 0A 88 28 1E 8C 43 +D0 43 94 47 D8 47 23 20 B8 00 23 22 C8 00 23 24 +D8 00 23 26 E8 00 C1 07 41 08 E3 92 A7 FE 83 A8 +07 00 DC 43 8A 86 A6 85 5E 85 01 47 11 46 23 20 +18 01 23 22 F8 00 EF E0 2F D7 83 20 C1 36 03 24 +81 36 83 24 41 36 03 29 01 36 83 29 C1 35 03 2A +81 35 83 2A 41 35 03 2B 01 35 83 2B C1 34 03 2C +81 34 13 01 01 37 82 80 37 15 02 50 13 05 85 FB +EF D0 7F E5 83 AA 0B 14 F1 B9 AC 19 52 85 EF B0 +20 6F 25 B7 93 09 81 0B 13 0C 81 27 C1 B5 15 65 +DA 85 13 05 85 71 EF D0 1F E5 05 45 EF D0 BF E0 +D1 B1 93 09 81 0A 13 0C 81 13 4D B5 93 09 81 0A +13 0C 81 1B 61 BD 15 65 DA 85 13 05 05 77 EF D0 +9F E2 E1 BD 93 09 81 0A 13 0C 81 1F 41 B5 13 0C +81 23 AD BD 53 74 72 69 6E 67 20 6C 65 6E 67 74 +68 20 69 73 20 25 64 2E 0A 00 00 00 45 72 72 6F +72 3A 20 49 6E 76 61 6C 69 64 20 68 65 78 20 63 +68 61 72 61 63 74 65 72 3A 20 25 63 0A 00 00 00 +53 74 72 69 6E 67 20 6C 65 6E 67 74 68 20 69 73 +20 25 64 2E 0A 00 00 00 45 72 72 6F 72 3A 20 49 +6E 76 61 6C 69 64 20 68 65 78 20 63 68 61 72 61 +63 74 65 72 3A 20 25 63 0A 00 00 00 53 65 74 20 +41 45 53 20 4B 56 20 57 72 69 74 65 20 74 6F 20 +73 6C 6F 74 20 25 64 0A 00 00 00 00 57 72 69 74 +65 20 41 45 53 20 43 54 52 4C 20 77 69 74 68 20 +76 61 6C 75 65 20 30 78 25 78 0A 00 57 72 69 74 +65 20 47 43 4D 5F 41 41 44 20 50 68 61 73 65 2C +20 4E 55 4D 5F 42 59 54 45 53 20 30 78 25 78 0A +00 00 00 00 57 72 69 74 65 20 41 45 53 20 41 41 +44 20 42 6C 6F 63 6B 20 25 64 0A 00 50 61 64 64 +69 6E 67 20 41 41 44 20 77 69 74 68 20 30 73 20 +41 41 44 20 44 57 4F 52 44 3A 20 25 64 00 00 00 +57 72 69 74 65 20 49 6E 20 44 61 74 61 3A 20 30 +78 25 78 20 61 61 64 20 44 57 4F 52 44 3A 20 25 +64 0A 00 00 53 52 43 3A 20 7B 20 30 78 25 30 78 +5F 25 30 78 20 7D 20 74 6F 20 44 53 54 3A 20 7B +20 30 78 25 30 78 5F 25 30 78 20 7D 0A 00 00 00 +41 74 20 6F 66 66 73 65 74 20 5B 25 64 5D 2C 20 +6F 75 74 70 75 74 20 64 61 74 61 20 6D 69 73 6D +61 74 63 68 21 0A 00 00 41 63 74 75 61 6C 20 20 +20 64 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +45 78 70 65 63 74 65 64 20 64 61 74 61 3A 20 30 +78 25 78 0A 00 00 00 00 41 74 20 6F 66 66 73 65 +74 20 5B 25 64 5D 2C 20 6F 75 74 70 75 74 20 64 +61 74 61 20 6D 69 73 6D 61 74 63 68 21 0A 00 00 +41 63 74 75 61 6C 20 20 20 64 61 74 61 3A 20 30 +78 25 78 0A 00 00 00 00 45 78 70 65 63 74 65 64 +20 64 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +57 72 69 74 65 20 41 45 53 20 49 6E 70 75 74 20 +44 61 74 61 20 42 6C 6F 63 6B 20 25 64 0A 00 00 +57 72 69 74 65 20 49 6E 20 44 61 74 61 3A 20 30 +78 25 78 0A 00 00 00 00 57 72 69 74 65 20 49 6E +20 44 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +45 58 50 45 43 54 45 44 20 4F 55 54 50 55 54 5F +4C 4F 53 54 20 74 6F 20 62 65 20 30 78 30 20 2D +20 41 63 74 75 61 6C 3A 20 30 78 25 78 00 00 00 +43 49 50 48 45 52 54 45 58 54 3A 20 30 78 25 78 +0A 00 00 00 41 74 20 6F 66 66 73 65 74 20 5B 25 +64 5D 2C 20 6F 75 74 70 75 74 20 64 61 74 61 20 +6D 69 73 6D 61 74 63 68 21 0A 00 00 41 63 74 75 +61 6C 20 20 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 41 74 20 6F 66 66 73 65 74 20 5B 25 +64 5D 2C 20 6F 75 74 70 75 74 20 64 61 74 61 20 +6D 69 73 6D 61 74 63 68 21 0A 00 00 41 63 74 75 +61 6C 20 20 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 45 78 70 65 63 74 65 64 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 41 74 20 6F +66 66 73 65 74 20 5B 25 64 5D 2C 20 6F 75 74 70 +75 74 20 64 61 74 61 20 6D 69 73 6D 61 74 63 68 +21 0A 00 00 41 63 74 75 61 6C 20 20 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 45 78 70 65 +63 74 65 64 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 57 72 69 74 65 20 41 41 44 20 4C 65 +6E 67 74 68 3A 20 30 78 25 78 0A 00 57 72 69 74 +65 20 54 65 78 74 20 4C 65 6E 67 74 68 3A 20 30 +78 25 78 0A 00 00 00 00 54 41 47 3A 20 30 78 25 +78 0A 00 00 41 74 20 6F 66 66 73 65 74 20 5B 25 +64 5D 2C 20 74 61 67 20 64 61 74 61 20 6D 69 73 +6D 61 74 63 68 21 0A 00 41 63 74 75 61 6C 20 20 +20 64 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +45 78 70 65 63 74 65 64 20 64 61 74 61 3A 20 30 +78 25 78 0A 00 00 00 00 45 52 52 4F 52 3A 20 6F +76 65 72 72 69 64 65 5F 74 65 78 74 5F 6C 65 6E +67 74 68 20 28 25 64 29 20 65 78 63 65 65 64 73 +20 6D 61 78 69 6D 75 6D 20 61 6C 6C 6F 77 65 64 +20 73 69 7A 65 20 6F 66 20 31 36 20 64 77 6F 72 +64 73 20 28 35 31 32 20 62 69 74 73 29 0A 00 00 +50 6F 70 75 6C 61 74 65 20 4B 56 20 77 69 74 68 +20 6B 65 79 20 6C 65 6E 67 74 68 3A 20 25 64 0A +00 00 79 71 4A D0 37 09 02 50 03 28 09 14 22 D4 +26 D2 4E CE 52 CC 56 CA 5A C8 06 D6 5E C6 89 48 +AA 8A 2E 8B 32 8A 36 84 BA 89 BE 84 63 E6 08 1B +83 A6 0A 00 B7 07 00 10 13 87 47 00 94 C3 83 A6 +4A 00 D4 C3 83 A7 8A 00 5C C3 83 A7 CA 00 1C C7 +93 16 24 00 93 F6 C6 07 93 E6 16 00 B7 07 00 10 +94 CB 37 04 00 10 54 48 89 8A F5 DE 8D 4A 63 EC +0A 11 83 26 0B 00 B7 07 00 10 13 87 47 00 94 C3 +83 26 4B 00 D4 C3 83 27 8B 00 5C C3 83 27 CB 00 +1C C7 13 97 29 00 13 77 C7 07 13 67 27 00 B7 07 +00 10 98 CB 37 04 00 10 58 48 09 8B 75 DF 8D 49 +63 E3 09 07 83 27 0A 00 37 07 00 10 93 06 47 00 +1C C3 03 26 4A 00 B7 07 03 30 83 A7 07 0E 50 C3 +03 27 8A 00 93 F7 07 04 D8 C2 03 27 CA 00 98 C6 +C1 C3 93 97 24 00 93 F7 C7 07 93 E7 07 08 37 07 +00 10 1C CB 5C 4B 89 8B F5 DF 8D 47 63 E7 07 15 +B2 50 22 54 92 54 02 59 F2 49 62 4A D2 4A 42 4B +B2 4B 45 61 82 80 37 15 02 50 13 05 C5 08 EF D0 +9F 82 03 28 09 14 E3 F7 09 F9 37 15 02 50 13 05 +C5 0B EF D0 5F 81 83 27 0A 00 03 28 09 14 1C C0 +83 26 4A 00 B7 07 03 30 83 A7 07 0E 54 C0 83 26 +8A 00 93 F7 07 04 14 C4 83 26 CA 00 54 C4 F9 EB +89 47 E3 FF 07 F9 37 15 02 50 13 05 45 12 22 54 +B2 50 92 54 02 59 F2 49 62 4A D2 4A 42 4B B2 4B +45 61 6F D0 4F FC 37 15 02 50 13 05 45 01 EF D0 +8F FB 03 28 09 14 E3 FE 0A ED 37 15 02 50 13 05 +C5 03 EF D0 4F FA 03 27 0B 00 03 28 09 14 18 C0 +03 27 4B 00 58 C0 03 27 8B 00 18 C4 03 27 CB 00 +58 C4 E3 F8 0A ED 37 15 02 50 13 05 C5 05 EF D0 +8F F7 03 28 09 14 75 BD 37 15 02 50 13 05 C5 FC +EF D0 6F F6 03 28 09 14 8D 4B E3 F3 0B E5 37 15 +02 50 13 05 85 FD EF D0 0F F5 03 A7 0A 00 B7 07 +00 10 03 28 09 14 98 C3 83 A6 4A 00 13 87 47 00 +D4 C3 83 A7 8A 00 5C C3 83 A7 CA 00 1C C7 E3 F9 +0B E3 37 15 02 50 13 05 C5 FE EF D0 CF F1 03 28 +09 14 39 BD E3 F7 09 EB 37 15 02 50 13 05 05 0D +EF D0 6F F0 03 28 09 14 69 BD 37 15 02 50 13 05 +85 0F 31 BF B7 07 02 50 03 A7 07 14 8D 47 63 E7 +E7 00 B7 07 00 10 0D 47 98 CB 82 80 37 15 02 50 +41 11 13 05 85 15 06 C6 EF D0 EF EC B2 40 B7 07 +00 10 0D 47 98 CB 41 01 82 80 00 00 41 11 22 C4 +37 04 02 50 03 27 04 14 06 C6 89 47 63 E0 E7 04 +37 37 02 50 13 07 C7 39 1C 47 54 47 D5 8F 9D E3 +73 00 50 10 93 07 40 06 01 00 FD 17 C2 07 C1 83 +E5 FF 1C 47 54 47 D5 8F E5 D7 83 26 04 14 89 47 +63 E5 D7 02 B2 40 22 44 41 01 82 80 37 15 02 50 +13 05 C5 16 EF D0 2F E6 37 37 02 50 13 07 C7 39 +1C 47 54 47 D5 8F CD DF C9 BF 22 44 4C 47 B2 40 +10 47 1D 65 13 05 C5 00 41 01 6F D0 CF E5 B7 07 +02 50 03 A7 07 14 89 47 63 E7 E7 00 B7 87 00 10 +11 47 98 CB 82 80 37 15 02 50 41 11 13 05 45 18 +06 C6 EF D0 4F E1 B2 40 B7 87 00 10 11 47 98 CB +41 01 82 80 79 71 26 D2 4A D0 56 CA 5A C8 06 D6 +22 D4 4E CE 52 CC 5E C6 83 4B 15 00 03 CA 06 00 +36 8B 3E 89 B2 86 BA 8A C2 84 B7 87 00 10 80 4F +05 88 75 DC 03 47 05 00 63 03 07 3C 13 97 1B 00 +13 77 E7 03 13 67 17 00 23 A4 E7 60 23 A0 07 08 +23 A2 07 08 23 A4 07 08 23 A6 07 08 23 A8 07 08 +23 AA 07 08 23 AC 07 08 23 AE 07 08 23 A0 07 0A +23 A2 07 0A 23 A4 07 0A 23 A6 07 0A 37 87 00 10 +83 27 C7 60 89 8B ED DF 63 0D 0A 00 83 47 1B 00 +37 87 00 10 86 07 93 F7 E7 03 93 E7 17 20 23 28 +F7 60 D8 41 B7 87 00 10 B7 09 02 50 23 A0 E7 50 +98 45 09 46 23 A2 E7 50 D8 45 23 A4 E7 50 98 49 +23 A6 E7 50 D8 49 23 A8 E7 50 98 4D 23 AA E7 50 +D8 4D 23 AC E7 50 98 51 23 AE E7 50 D8 51 23 A0 +E7 52 98 55 23 A2 E7 52 D8 55 23 A4 E7 52 98 59 +23 A6 E7 52 D8 42 23 A0 E7 48 98 46 23 A2 E7 48 +D8 46 23 A4 E7 48 98 4A 23 A6 E7 48 D8 4A 23 A8 +E7 48 98 4E 23 AA E7 48 D8 4E 23 AC E7 48 98 52 +23 AE E7 48 D8 52 23 A0 E7 4A 98 56 23 A2 E7 4A +D8 56 23 A4 E7 4A 98 5A 23 A6 E7 4A 03 A7 09 14 +63 6B E6 30 B7 87 00 10 85 46 94 CB 63 93 0B 00 +0D 44 B7 87 00 10 23 A4 87 60 23 A0 07 08 23 A2 +07 08 23 A4 07 08 23 A6 07 08 23 A8 07 08 23 AA +07 08 23 AC 07 08 23 AE 07 08 23 A0 07 0A 23 A2 +07 0A 23 A4 07 0A 23 A6 07 0A 89 47 63 EE E7 2A +37 37 02 50 13 07 C7 39 1C 47 54 47 D5 8F 91 EF +73 00 50 10 93 07 40 06 01 00 FD 17 C2 07 C1 83 +E5 FF 1C 47 54 47 D5 8F E5 D7 83 A7 09 14 09 44 +63 6D F4 0A 63 1E 0A 0C B7 87 00 10 03 AA 07 18 +03 24 4B 00 63 1C 8A 2A 03 AA 47 18 03 24 8B 00 +63 15 8A 30 03 AA 87 18 03 24 CB 00 63 11 8A 30 +03 AA C7 18 03 24 0B 01 63 1D 8A 2E 03 AA 07 19 +03 24 4B 01 63 19 8A 2E 03 AA 47 19 03 24 8B 01 +63 15 8A 2E 03 AA 87 19 03 24 CB 01 63 11 8A 2E +03 AA C7 19 03 24 0B 02 63 1D 8A 2C 03 AA 07 1A +03 24 4B 02 63 13 8A 2E 03 AA 47 1A 03 24 8B 02 +63 1F 8A 2C 03 AA 87 1A 03 24 CB 02 63 15 8A 2C +03 AA C7 1A 03 24 0B 03 AD 45 63 1A 8A 22 85 47 +63 89 F4 04 B2 50 22 54 92 54 02 59 F2 49 62 4A +D2 4A 42 4B B2 4B 45 61 82 80 4C 47 10 47 1D 65 +13 05 C5 00 EF D0 2F BA 83 A7 09 14 63 0E 0A 1C +63 78 F4 00 37 15 02 50 13 05 45 1A EF D0 AF B6 +37 87 00 10 83 27 47 61 89 8B ED DF 85 47 E3 9B +F4 FA 03 A7 09 14 89 47 63 E1 E7 1C B7 87 00 10 +83 A4 07 20 03 A4 4A 00 63 99 84 20 83 A4 47 20 +03 A4 8A 00 63 99 84 22 83 A4 87 20 03 A4 CA 00 +63 95 84 22 83 A4 C7 20 03 A4 0A 01 63 91 84 22 +83 A4 07 21 03 A4 4A 01 63 9D 84 20 83 A4 47 21 +03 A4 8A 01 63 91 84 1E 83 A4 87 21 03 A4 CA 01 +63 99 84 2A 83 A4 C7 21 03 A4 0A 02 63 91 84 2A +83 A4 07 22 03 A4 4A 02 63 99 84 28 83 A4 47 22 +03 A4 8A 02 63 91 84 28 83 A4 87 22 03 A4 CA 02 +63 99 84 26 83 A4 C7 22 03 A4 0A 03 AD 45 63 97 +84 18 89 47 63 EC E7 16 B7 87 00 10 83 A4 07 28 +03 24 49 00 63 15 94 24 83 A4 47 28 03 24 89 00 +63 1D 94 22 83 A4 87 28 03 24 C9 00 63 15 94 22 +83 A4 C7 28 03 24 09 01 63 9D 84 20 83 A4 07 29 +03 24 49 01 63 95 84 20 83 A4 47 29 03 24 89 01 +63 9D 84 1E 83 A4 87 29 03 24 C9 01 63 95 84 1E +83 A4 C7 29 03 24 09 02 63 9D 84 1C 83 A4 07 2A +03 24 49 02 63 95 84 1C 83 A4 47 2A 03 24 89 02 +63 9D 84 1A 83 A4 87 2A 03 24 C9 02 63 95 84 1A +83 A4 C7 2A 03 24 09 03 AD 45 E3 8D 84 E6 83 A7 +09 14 63 90 07 16 05 45 EF D0 EF 9E 01 A0 58 41 +23 A0 E7 08 18 45 23 A2 E7 08 58 45 23 A4 E7 08 +18 49 23 A6 E7 08 58 49 23 A8 E7 08 18 4D 23 AA +E7 08 58 4D 23 AC E7 08 18 51 23 AE E7 08 58 51 +23 A0 E7 0A 18 55 23 A2 E7 0A 58 55 23 A4 E7 0A +18 59 23 A6 E7 0A 89 B1 37 15 02 50 13 05 C5 16 +EF D0 6F 9B 35 BB 37 15 02 50 13 05 85 19 EF D0 +8F 9A 03 A7 09 14 F9 B9 E3 70 F4 D6 37 15 02 50 +13 05 85 1B EF D0 2F 99 81 BB 37 15 02 50 13 05 +45 1D EF D0 4F 98 03 A7 09 14 0D BD 81 45 83 A7 +09 14 89 E7 05 45 EF D0 0F 95 01 A0 9D 64 93 84 +C4 00 13 85 44 03 EF D0 0F 98 83 A7 09 14 FD D3 +D2 85 13 85 04 06 EF D0 0F 97 83 A7 09 14 F9 DB +A2 85 13 85 84 07 EF D0 0F 96 E9 B7 37 15 02 50 +13 05 05 1F EF D0 2F 93 41 B5 81 45 39 E3 05 45 +EF D0 6F 90 01 A0 95 45 D5 BF 85 45 4D B7 89 45 +79 BF 8D 45 69 BF 91 45 59 BF 95 45 49 BF 99 45 +79 B7 9D 45 69 B7 85 45 D1 BF 89 45 C1 BF 8D 45 +F1 B7 91 45 E1 B7 A9 45 9D BF A1 45 8D BF A5 45 +BD B7 1D 69 13 09 C9 00 13 05 09 09 EF D0 AF 8F +83 A7 09 14 CD D7 A6 85 13 05 09 0C EF D0 AF 8E +83 A7 09 14 C9 DF A2 85 13 05 89 0D EF D0 AF 8D +79 B7 1D 69 13 09 C9 00 13 05 09 0F EF D0 AF 8C +83 A7 09 14 E3 89 07 E8 A6 85 13 05 09 12 EF D0 +8F 8B 83 A7 09 14 E3 80 07 E8 A2 85 13 05 89 13 +EF D0 6F 8A 8D BD A9 45 9D B5 A5 45 8D B5 A1 45 +B9 BD 9D 45 A9 BD 99 45 99 BD 95 45 89 BD 91 45 +B9 B5 8D 45 A9 B5 89 45 99 B5 85 45 89 B5 81 45 +3D BD A9 45 25 B7 A5 45 15 B7 A1 45 05 B7 9D 45 +31 BF 99 45 21 BF 79 71 4E CE 52 CC 5A C8 5E C6 +06 D6 22 D4 26 D2 4A D0 56 CA 83 CA 15 00 83 44 +07 00 BA 89 2A 8A B2 8B 36 8B B7 87 00 10 80 4F +05 88 75 DC 03 C7 05 00 63 0D 07 2C 13 97 1A 00 +13 77 E7 03 13 67 17 00 23 A0 E7 60 37 87 00 10 +83 27 47 60 89 8B ED DF 37 09 02 50 03 27 09 14 +89 47 63 E3 E7 30 03 A6 4B 00 B7 87 00 10 89 46 +23 A0 C7 20 03 A6 8B 00 23 A2 C7 20 03 A6 CB 00 +23 A4 C7 20 03 A6 0B 01 23 A6 C7 20 03 A6 4B 01 +23 A8 C7 20 03 A6 8B 01 23 AA C7 20 03 A6 CB 01 +23 AC C7 20 03 A6 0B 02 23 AE C7 20 03 A6 4B 02 +23 A0 C7 22 03 A6 8B 02 23 A2 C7 22 03 A6 CB 02 +23 A4 C7 22 03 A6 0B 03 23 A6 C7 22 63 E7 E6 2C +83 26 4B 00 B7 87 00 10 23 A0 D7 28 83 26 8B 00 +23 A2 D7 28 83 26 CB 00 23 A4 D7 28 83 26 0B 01 +23 A6 D7 28 83 26 4B 01 23 A8 D7 28 83 26 8B 01 +23 AA D7 28 83 26 CB 01 23 AC D7 28 83 26 0B 02 +23 AE D7 28 83 26 4B 02 23 A0 D7 2A 83 26 8B 02 +23 A2 D7 2A 83 26 CB 02 23 A4 D7 2A 83 26 0B 03 +23 A6 D7 2A 83 26 4A 00 23 A0 D7 48 83 26 8A 00 +23 A2 D7 48 83 26 CA 00 23 A4 D7 48 83 26 0A 01 +23 A6 D7 48 83 26 4A 01 23 A8 D7 48 83 26 8A 01 +23 AA D7 48 83 26 CA 01 23 AC D7 48 83 26 0A 02 +23 AE D7 48 83 26 4A 02 23 A0 D7 4A 83 26 8A 02 +23 A2 D7 4A 83 26 CA 02 23 A4 D7 4A 83 26 0A 03 +23 A6 D7 4A 81 CC 83 C6 19 00 05 66 13 06 16 AC +86 06 93 F6 F6 0F D1 8E 23 A8 D7 60 89 47 63 ED +E7 1C B7 87 00 10 C1 46 94 CB 63 93 0A 00 0D 44 +B7 87 00 10 23 A0 87 60 23 A0 07 58 23 A2 07 58 +23 A4 07 58 23 A6 07 58 23 A8 07 58 23 AA 07 58 +23 AC 07 58 23 AE 07 58 23 A0 07 5A 23 A2 07 5A +23 A4 07 5A 23 A6 07 5A 89 47 63 E0 E7 18 37 37 +02 50 13 07 C7 39 1C 47 54 47 D5 8F 91 EF 73 00 +50 10 93 07 40 06 01 00 FD 17 C2 07 C1 83 E5 FF +1C 47 54 47 D5 8F E5 D7 83 27 09 14 09 44 63 69 +F4 0A E9 E8 B7 87 00 10 83 A4 07 5C 03 A4 49 00 +63 1F 94 16 83 A4 47 5C 03 A4 89 00 63 1B 94 1A +83 A4 87 5C 03 A4 C9 00 63 97 84 1A 83 A4 C7 5C +03 A4 09 01 63 93 84 1A 83 A4 07 5D 03 A4 49 01 +63 9F 84 18 83 A4 47 5D 03 A4 89 01 63 9B 84 18 +83 A4 87 5D 03 A4 C9 01 63 97 84 18 83 A4 C7 5D +03 A4 09 02 63 93 84 18 83 A4 07 5E 03 A4 49 02 +63 9F 84 16 83 A4 47 5E 03 A4 89 02 63 9B 84 16 +83 A4 87 5E 03 A4 C9 02 63 93 84 14 83 A4 C7 5E +03 A4 09 03 AD 45 63 9D 84 0E B2 50 22 54 92 54 +02 59 F2 49 62 4A D2 4A 42 4B B2 4B 45 61 82 80 +4C 47 10 47 1D 65 13 05 C5 00 EF C0 DF D7 83 27 +09 14 CD CC 63 78 F4 00 37 15 02 50 13 05 45 1A +EF C0 7F D4 37 87 00 10 83 27 47 61 89 8B ED DF +6D BF D8 41 37 09 02 50 23 A0 E7 58 98 45 23 A2 +E7 58 D8 45 23 A4 E7 58 98 49 23 A6 E7 58 D8 49 +23 A8 E7 58 98 4D 23 AA E7 58 D8 4D 23 AC E7 58 +98 51 23 AE E7 58 D8 51 23 A0 E7 5A 98 55 23 A2 +E7 5A D8 55 23 A4 E7 5A 98 59 23 A6 E7 5A 03 27 +09 14 89 47 E3 F1 E7 D0 37 15 02 50 13 05 C5 20 +EF C0 7F CD 03 27 09 14 FD B1 37 15 02 50 13 05 +C5 16 EF C0 5F CC A5 BD 37 15 02 50 13 05 45 24 +EF C0 7F CB 03 27 09 14 29 BD 37 15 02 50 13 05 +85 22 EF C0 5F CA 03 27 09 14 1D B3 E3 74 F4 E8 +37 15 02 50 13 05 45 25 EF C0 FF C8 A5 BD 81 45 +83 27 09 14 89 E7 05 45 EF C0 FF C5 01 A0 9D 69 +93 89 C9 00 13 85 09 15 EF C0 FF C8 83 27 09 14 +FD D3 A6 85 13 85 09 18 EF C0 FF C7 83 27 09 14 +F9 DB A2 85 13 85 89 19 EF C0 FF C6 E9 B7 A9 45 +C1 B7 85 45 75 BF 89 45 65 BF 8D 45 55 BF 91 45 +45 BF 95 45 75 B7 99 45 65 B7 9D 45 55 B7 A1 45 +45 B7 A5 45 71 BF 79 71 26 D2 4E CE 52 CC 5A C8 +5E C6 06 D6 22 D4 4A D0 56 CA 83 4A 15 00 BE 84 +AE 8B 32 8B B6 89 3A 8A B7 87 00 10 80 4F 05 88 +75 DC 83 46 05 00 37 09 02 50 03 27 09 14 63 87 +06 32 89 47 63 E9 E7 38 93 96 1A 00 93 F6 E6 03 +B7 87 00 10 93 E6 16 00 23 A0 D7 60 23 A0 07 58 +23 A2 07 58 23 A4 07 58 23 A6 07 58 23 A8 07 58 +23 AA 07 58 23 AC 07 58 23 AE 07 58 23 A0 07 5A +23 A2 07 5A 23 A4 07 5A 23 A6 07 5A B7 86 00 10 +83 A7 46 60 89 8B ED DF 03 A6 4B 00 B7 87 00 10 +89 46 23 A0 C7 10 03 A6 8B 00 23 A2 C7 10 03 A6 +CB 00 23 A4 C7 10 03 A6 0B 01 23 A6 C7 10 03 A6 +4B 01 23 A8 C7 10 03 A6 8B 01 23 AA C7 10 03 A6 +CB 01 23 AC C7 10 03 A6 0B 02 23 AE C7 10 03 A6 +4B 02 23 A0 C7 12 03 A6 8B 02 23 A2 C7 12 03 A6 +CB 02 23 A4 C7 12 03 A6 0B 03 23 A6 C7 12 03 26 +4B 00 23 A0 C7 48 03 26 8B 00 23 A2 C7 48 03 26 +CB 00 23 A4 C7 48 03 26 0B 01 23 A6 C7 48 03 26 +4B 01 23 A8 C7 48 03 26 8B 01 23 AA C7 48 03 26 +CB 01 23 AC C7 48 03 26 0B 02 23 AE C7 48 03 26 +4B 02 23 A0 C7 4A 03 26 8B 02 23 A2 C7 4A 03 26 +CB 02 23 A4 C7 4A 03 26 0B 03 23 A6 C7 4A 63 E3 +E6 26 B7 87 00 10 89 46 94 CB 63 93 0A 00 0D 44 +B7 87 00 10 23 A0 87 60 23 A0 07 58 23 A2 07 58 +23 A4 07 58 23 A6 07 58 23 A8 07 58 23 AA 07 58 +23 AC 07 58 23 AE 07 58 23 A0 07 5A 23 A2 07 5A +23 A4 07 5A 23 A6 07 5A 89 47 63 E6 E7 20 37 37 +02 50 13 07 C7 39 1C 47 54 47 D5 8F 91 EF 73 00 +50 10 93 07 40 06 01 00 FD 17 C2 07 C1 83 E5 FF +1C 47 54 47 D5 8F E5 D7 83 26 09 14 09 44 63 60 +D4 02 85 47 63 83 F4 04 B2 50 22 54 92 54 02 59 +F2 49 62 4A D2 4A 42 4B B2 4B 45 61 82 80 4C 47 +10 47 1D 65 13 05 C5 00 EF C0 FF A3 85 47 E3 9D +F4 FC 83 26 09 14 63 7A D4 00 37 15 02 50 13 05 +45 2A EF C0 5F A0 83 26 09 14 B7 87 00 10 83 A4 +07 30 03 A4 49 00 63 99 84 1A 83 A4 47 30 03 A4 +89 00 63 9C 84 22 83 A4 87 30 03 A4 C9 00 63 9E +84 20 83 A4 C7 30 03 A4 09 01 63 9A 84 20 83 A4 +07 31 03 A4 49 01 63 96 84 20 83 A4 47 31 03 A4 +89 01 63 92 84 20 83 A4 87 31 03 A4 C9 01 63 90 +84 20 83 A4 C7 31 03 A4 09 02 63 9C 84 1E 83 A4 +07 32 03 A4 49 02 63 98 84 1C 83 A4 47 32 03 A4 +89 02 63 90 84 1C 83 A4 87 32 03 A4 C9 02 63 98 +84 1A 83 A4 C7 32 03 A4 09 03 AD 45 63 97 84 12 +89 47 63 E9 D7 12 B7 87 00 10 83 A4 07 38 03 24 +4A 00 63 94 84 18 83 A4 47 38 03 24 8A 00 63 1C +94 16 83 A4 87 38 03 24 CA 00 63 94 84 16 83 A4 +C7 38 03 24 0A 01 63 1C 94 14 83 A4 07 39 03 24 +4A 01 63 94 84 14 83 A4 47 39 03 24 8A 01 63 9C +84 12 83 A4 87 39 03 24 CA 01 63 94 84 12 83 A4 +C7 39 03 24 0A 02 63 9C 84 10 83 A4 07 3A 03 24 +4A 02 63 94 84 10 83 A4 47 3A 03 24 8A 02 63 9C +84 0E 83 A4 87 3A 03 24 CA 02 63 94 84 0E 83 A4 +C7 3A 03 24 0A 03 AD 45 E3 88 84 E8 83 27 09 14 +63 93 07 12 05 45 EF C0 1F 8A 01 A0 54 41 23 A0 +D7 58 14 45 23 A2 D7 58 54 45 23 A4 D7 58 14 49 +23 A6 D7 58 54 49 23 A8 D7 58 14 4D 23 AA D7 58 +54 4D 23 AC D7 58 14 51 23 AE D7 58 54 51 23 A0 +D7 5A 14 55 23 A2 D7 5A 54 55 23 A4 D7 5A 14 59 +23 A6 D7 5A D5 B1 37 15 02 50 13 05 C5 16 EF C0 +9F 86 F5 B3 37 15 02 50 13 05 45 29 EF C0 BF 85 +03 27 09 14 79 B3 37 15 02 50 13 05 45 27 EF C0 +9F 84 03 27 09 14 8D B1 81 45 81 EE 05 45 EF C0 +9F 81 01 A0 37 15 02 50 13 05 05 2C EF C0 BF 82 +D9 B5 9D 69 93 89 C9 00 13 85 09 1B EF C0 BF 83 +83 27 09 14 E1 DF A6 85 13 85 C9 1D EF C0 BF 82 +83 27 09 14 E1 D7 A2 85 13 85 49 1F EF C0 BF 81 +75 BF A9 45 25 B7 A5 45 15 B7 A1 45 05 B7 9D 45 +31 BF 99 45 21 BF 95 45 11 BF 91 45 01 BF 8D 45 +31 B7 89 45 21 B7 85 45 11 B7 81 45 01 B7 A9 45 +69 B7 A5 45 59 B7 A1 45 49 B7 89 45 BD BF 8D 45 +AD BF 91 45 9D BF 95 45 8D BF 85 45 BD B7 99 45 +AD B7 9D 45 9D B7 9D 69 93 89 C9 00 13 85 C9 20 +EF C0 6F FB 83 27 09 14 E3 86 07 EC A6 85 13 85 +89 23 EF C0 4F FA 83 27 09 14 E3 8D 07 EA A2 85 +13 85 09 25 EF C0 2F F9 75 B5 01 11 22 CC 26 CA +06 CE 4A C8 4E C6 B6 84 37 84 00 10 1C 4C 85 8B +F5 DF 5C 41 B7 09 02 50 09 49 23 20 F4 10 1C 45 +23 22 F4 10 5C 45 23 24 F4 10 1C 49 23 26 F4 10 +5C 49 23 28 F4 10 1C 4D 23 2A F4 10 5C 4D 23 2C +F4 10 1C 51 23 2E F4 10 5C 51 23 20 F4 12 1C 55 +23 22 F4 12 5C 55 23 24 F4 12 1C 59 23 26 F4 12 +DC 41 23 20 F4 20 9C 45 23 22 F4 20 DC 45 23 24 +F4 20 9C 49 23 26 F4 20 DC 49 23 28 F4 20 9C 4D +23 2A F4 20 DC 4D 23 2C F4 20 9C 51 23 2E F4 20 +DC 51 23 20 F4 22 9C 55 23 22 F4 22 DC 55 23 24 +F4 22 9C 59 23 26 F4 22 5C 42 23 20 F4 28 1C 46 +23 22 F4 28 5C 46 23 24 F4 28 1C 4A 23 26 F4 28 +5C 4A 23 28 F4 28 1C 4E 23 2A F4 28 5C 4E 23 2C +F4 28 1C 52 23 2E F4 28 5C 52 23 20 F4 2A 1C 56 +23 22 F4 2A 5C 56 23 24 F4 2A 1C 5A 23 26 F4 2A +DC 40 23 20 F4 30 9C 44 23 22 F4 30 DC 44 23 24 +F4 30 9C 48 23 26 F4 30 DC 48 23 28 F4 30 9C 4C +23 2A F4 30 DC 4C 23 2C F4 30 9C 50 23 2E F4 30 +DC 50 23 20 F4 32 9C 54 23 22 F4 32 DC 54 23 24 +F4 32 9C 58 23 26 F4 32 5C 43 23 20 F4 38 1C 47 +23 22 F4 38 5C 47 23 24 F4 38 1C 4B 23 26 F4 38 +5C 4B 23 28 F4 38 1C 4F 23 2A F4 38 5C 4F 23 2C +F4 38 1C 53 23 2E F4 38 5C 53 23 20 F4 3A 1C 57 +23 22 F4 3A 5C 57 23 24 F4 3A 1C 5B 23 26 F4 3A +83 A7 09 14 63 6E F9 0E 8D 47 1C C8 37 37 02 50 +13 07 C7 39 1C 47 54 47 D5 8F 9D E3 73 00 50 10 +93 07 40 06 01 00 FD 17 C2 07 C1 83 E5 FF 1C 47 +54 47 D5 8F E5 D7 83 A7 09 14 09 44 63 60 F4 0A +B7 87 00 10 03 A9 07 40 C0 40 63 11 24 09 03 A9 +47 40 80 44 63 1C 89 10 03 A9 87 40 C0 44 63 15 +89 10 03 A9 C7 40 80 48 63 16 24 11 03 A9 07 41 +C0 48 63 1F 89 0E 03 A9 47 41 80 4C 63 1E 89 0E +03 A9 87 41 C0 4C 63 11 89 10 03 A9 C7 41 80 50 +63 16 89 0E 03 A9 07 42 C0 50 63 19 89 0E 03 A9 +47 42 80 54 63 1E 89 0C 03 A9 87 42 C0 54 63 1B +89 0C 03 A9 C7 42 80 58 AD 45 63 1A 89 00 F2 40 +62 44 D2 44 42 49 B2 49 05 61 82 80 81 45 83 A7 +09 14 BD E3 05 45 EF C0 0F CF 01 A0 4C 47 10 47 +1D 65 13 05 C5 00 EF C0 0F D2 83 A7 09 14 E3 79 +F4 F4 37 15 02 50 13 05 C5 2E EF C0 CF CE 89 B7 +37 15 02 50 13 05 C5 2D EF C0 EF CD 83 A7 09 14 +0D 47 18 C8 E3 7C F9 EE 37 15 02 50 13 05 C5 16 +EF C0 6F CC 37 37 02 50 13 07 C7 39 1C 47 54 47 +D5 8F E3 85 07 EE 01 B7 9D 64 93 84 C4 00 13 85 +84 26 EF C0 4F CC 83 A7 09 14 C9 D7 CA 85 13 85 +84 29 EF C0 4F CB 83 A7 09 14 AD DF A2 85 13 85 +04 2B EF C0 4F CA BD B7 89 45 95 B7 85 45 85 B7 +91 45 B1 BF 8D 45 A1 BF 95 45 91 BF 9D 45 81 BF +A5 45 B1 B7 A9 45 A1 B7 99 45 91 B7 A1 45 81 B7 +01 11 22 CC 4E C6 52 C4 06 CE 26 CA 4A C8 2A 87 +AE 89 32 8A 37 84 00 10 1C 4C 85 8B F5 DF 5C 43 +37 09 02 50 89 44 23 20 F4 48 1C 47 23 22 F4 48 +5C 47 23 24 F4 48 1C 4B 23 26 F4 48 5C 4B 23 28 +F4 48 1C 4F 23 2A F4 48 5C 4F 23 2C F4 48 1C 53 +23 2E F4 48 5C 53 23 20 F4 4A 1C 57 23 22 F4 4A +5C 57 23 24 F4 4A 1C 5B 23 26 F4 4A 83 27 09 14 +63 E5 F4 1E A9 47 1C C8 93 07 F0 03 23 20 F4 60 +23 20 04 58 23 22 04 58 23 24 04 58 23 26 04 58 +23 28 04 58 23 2A 04 58 23 2C 04 58 23 2E 04 58 +23 20 04 5A 23 22 04 5A 23 24 04 5A 23 26 04 5A +37 37 02 50 13 07 C7 39 1C 47 54 47 D5 8F 91 EF +73 00 50 10 93 07 40 06 01 00 FD 17 C2 07 C1 83 +E5 FF 1C 47 54 47 D5 8F E5 D7 83 26 09 14 09 44 +63 69 D4 14 B7 87 00 10 83 A4 07 30 03 A4 49 00 +63 9B 84 12 83 A4 47 30 03 A4 89 00 63 91 84 24 +83 A4 87 30 03 A4 C9 00 63 99 84 22 83 A4 C7 30 +03 A4 09 01 63 99 84 22 83 A4 07 31 03 A4 49 01 +63 91 84 22 83 A4 47 31 03 A4 89 01 63 97 84 24 +83 A4 87 31 03 A4 C9 01 63 9D 84 22 83 A4 C7 31 +03 A4 09 02 63 95 84 22 83 A4 07 32 03 A4 49 02 +63 9D 84 20 83 A4 47 32 03 A4 89 02 63 91 84 22 +83 A4 87 32 03 A4 C9 02 63 91 84 1E 83 A4 C7 32 +03 A4 09 03 AD 45 63 99 84 0A 89 47 63 E8 D7 1A +B7 87 00 10 83 A4 07 38 03 24 4A 00 63 16 94 12 +83 A4 47 38 03 24 8A 00 63 1B 94 1A 83 A4 87 38 +03 24 CA 00 63 97 84 1A 83 A4 C7 38 03 24 0A 01 +63 93 84 1A 83 A4 07 39 03 24 4A 01 63 9F 84 18 +83 A4 47 39 03 24 8A 01 63 9B 84 18 83 A4 87 39 +03 24 CA 01 63 97 84 18 83 A4 C7 39 03 24 0A 02 +63 93 84 18 83 A4 07 3A 03 24 4A 02 63 9B 84 18 +83 A4 47 3A 03 24 8A 02 63 97 84 18 83 A4 87 3A +03 24 CA 02 63 99 84 16 83 A4 C7 3A 03 24 0A 03 +AD 45 63 94 84 0A F2 40 62 44 D2 44 42 49 B2 49 +22 4A 05 61 82 80 81 45 E1 EA 05 45 EF C0 AF A0 +01 A0 4C 47 10 47 1D 65 13 05 C5 00 EF C0 AF A3 +83 26 09 14 E3 70 D4 EA 37 15 02 50 13 05 45 2A +EF C0 6F A0 83 26 09 14 71 B5 37 15 02 50 13 05 +85 30 EF C0 4F 9F 29 47 83 27 09 14 18 C8 13 07 +F0 03 23 20 E4 60 23 20 04 58 23 22 04 58 23 24 +04 58 23 26 04 58 23 28 04 58 23 2A 04 58 23 2C +04 58 23 2E 04 58 23 20 04 5A 23 22 04 5A 23 24 +04 5A 23 26 04 5A E3 F5 F4 E0 37 15 02 50 13 05 +C5 16 EF C0 4F 9A ED BB 81 45 83 27 09 14 89 E7 +05 45 EF C0 4F 97 01 A0 9D 69 93 89 C9 00 13 85 +49 32 EF C0 4F 9A 83 27 09 14 FD D3 A6 85 13 85 +09 35 EF C0 4F 99 83 27 09 14 F9 DB A2 85 13 85 +89 36 EF C0 4F 98 E9 B7 9D 69 93 89 C9 00 13 85 +89 2C EF C0 4F 97 83 27 09 14 E3 80 07 F2 A6 85 +13 85 49 2F EF C0 2F 96 83 27 09 14 E3 87 07 F0 +A2 85 13 85 C9 30 EF C0 0F 95 01 B7 37 15 02 50 +13 05 05 2C EF C0 2F 92 A1 B5 89 45 F5 B5 85 45 +E5 B5 91 45 D5 B5 8D 45 C5 B5 A9 45 F1 BD 85 45 +AD B7 89 45 9D B7 8D 45 8D B7 91 45 B9 BF 95 45 +A9 BF 99 45 99 BF 9D 45 89 BF A1 45 75 BD 9D 45 +65 BD 99 45 55 BD A9 45 89 B7 95 45 75 B5 A5 45 +65 B5 A1 45 1D BF A5 45 0D BF 01 00 52 65 63 65 +69 76 65 64 20 45 43 43 20 6E 6F 74 69 66 2F 20 +65 72 72 20 69 6E 74 72 20 77 69 74 68 20 73 74 +61 74 75 73 20 3D 20 25 64 2F 20 25 64 0A 00 00 +41 74 20 6F 66 66 73 65 74 20 5B 25 64 5D 2C 20 +65 63 63 5F 70 72 69 76 6B 65 79 20 64 61 74 61 +20 6D 69 73 6D 61 74 63 68 21 0A 00 41 63 74 75 +61 6C 20 20 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 45 78 70 65 63 74 65 64 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 41 74 20 6F +66 66 73 65 74 20 5B 25 64 5D 2C 20 65 63 63 5F +70 75 62 6B 65 79 5F 78 20 64 61 74 61 20 6D 69 +73 6D 61 74 63 68 21 0A 00 00 00 00 41 63 74 75 +61 6C 20 20 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 45 78 70 65 63 74 65 64 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 41 74 20 6F +66 66 73 65 74 20 5B 25 64 5D 2C 20 65 63 63 5F +70 75 62 6B 65 79 5F 79 20 64 61 74 61 20 6D 69 +73 6D 61 74 63 68 21 0A 00 00 00 00 41 63 74 75 +61 6C 20 20 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 45 78 70 65 63 74 65 64 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 41 74 20 6F +66 66 73 65 74 20 5B 25 64 5D 2C 20 65 63 63 5F +73 68 61 72 65 64 6B 65 79 20 64 61 74 61 20 6D +69 73 6D 61 74 63 68 21 0A 00 00 00 41 63 74 75 +61 6C 20 20 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 45 78 70 65 63 74 65 64 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 41 74 20 6F +66 66 73 65 74 20 5B 25 64 5D 2C 20 65 63 63 5F +73 69 67 6E 5F 72 20 64 61 74 61 20 6D 69 73 6D +61 74 63 68 21 0A 00 00 41 63 74 75 61 6C 20 20 +20 64 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +45 78 70 65 63 74 65 64 20 64 61 74 61 3A 20 30 +78 25 78 0A 00 00 00 00 41 74 20 6F 66 66 73 65 +74 20 5B 25 64 5D 2C 20 65 63 63 5F 73 69 67 6E +5F 73 20 64 61 74 61 20 6D 69 73 6D 61 74 63 68 +21 0A 00 00 41 63 74 75 61 6C 20 20 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 45 78 70 65 +63 74 65 64 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 41 74 20 6F 66 66 73 65 74 20 5B 25 +64 5D 2C 20 65 63 63 5F 76 65 72 69 66 79 5F 72 +20 64 61 74 61 20 6D 69 73 6D 61 74 63 68 21 0A +00 00 00 00 41 63 74 75 61 6C 20 20 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 45 78 70 65 +63 74 65 64 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 41 74 20 6F 66 66 73 65 74 20 5B 25 +64 5D 2C 20 65 63 63 5F 73 69 67 6E 5F 72 20 64 +61 74 61 20 6D 69 73 6D 61 74 63 68 21 0A 00 00 +41 63 74 75 61 6C 20 20 20 64 61 74 61 3A 20 30 +78 25 78 0A 00 00 00 00 45 78 70 65 63 74 65 64 +20 64 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +41 74 20 6F 66 66 73 65 74 20 5B 25 64 5D 2C 20 +65 63 63 5F 73 69 67 6E 5F 73 20 64 61 74 61 20 +6D 69 73 6D 61 74 63 68 21 0A 00 00 41 63 74 75 +61 6C 20 20 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 45 78 70 65 63 74 65 64 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 41 11 22 C4 +37 04 02 50 03 27 04 14 06 C6 89 47 63 E0 E7 04 +37 37 02 50 13 07 C7 39 3C 43 74 43 D5 8F 9D E3 +73 00 50 10 93 07 40 06 01 00 FD 17 C2 07 C1 83 +E5 FF 3C 43 74 43 D5 8F E5 D7 83 26 04 14 89 47 +63 E5 D7 02 B2 40 22 44 41 01 82 80 37 15 02 50 +13 05 C5 31 EF B0 3F CF 37 37 02 50 13 07 C7 39 +3C 43 74 43 D5 8F CD DF C9 BF 22 44 6C 43 B2 40 +30 43 25 65 13 05 45 B7 41 01 6F B0 DF CE 41 11 +26 C2 B7 04 02 50 83 A7 04 14 22 C4 06 C6 09 44 +63 60 F4 02 B7 07 03 10 21 47 98 CB 37 07 03 10 +5C 4B 85 8B F5 DF B2 40 22 44 92 44 41 01 82 80 +37 15 02 50 13 05 85 33 EF B0 FF C8 83 A7 04 14 +37 07 03 10 A1 46 14 CB E3 7A F4 FC 37 15 02 50 +13 05 C5 34 EF B0 3F C7 D1 B7 19 CA 0A 06 33 87 +C5 00 9C 41 91 05 11 05 23 2E F5 FE E3 9B E5 FE +82 80 79 71 4E CE B7 09 02 50 03 A7 09 14 26 D2 +4A D0 5A C8 5E C6 06 D6 22 D4 52 CC 56 CA 89 47 +AA 8B 2E 8B B2 84 36 89 63 E3 E7 20 B7 07 03 10 +C0 4B 05 88 75 DC 03 CA 0B 00 83 C6 2B 00 63 09 +0A 16 93 97 16 00 93 F7 E7 03 93 E7 17 00 B7 86 +03 10 9C C2 89 47 63 E3 E7 28 B7 07 03 10 23 AC +07 04 23 AE 07 04 23 A0 07 06 23 A2 07 06 23 A4 +07 06 23 A6 07 06 23 A8 07 06 23 AA 07 06 B7 86 +03 10 DC 42 89 8B F5 DF 03 C6 1B 00 85 47 63 19 +F6 14 DC 42 93 F7 C7 3F 63 84 07 2C 89 47 63 E6 +E7 2C 83 26 0B 00 B7 0A 03 10 89 47 23 AC DA 00 +83 26 4B 00 23 AE DA 00 83 26 8B 00 23 A0 DA 02 +83 26 CB 00 23 A2 DA 02 83 26 0B 01 23 A4 DA 02 +83 26 4B 01 23 A6 DA 02 83 26 8B 01 23 A8 DA 02 +83 26 CB 01 23 AA DA 02 83 26 0B 02 23 AC DA 02 +83 26 4B 02 23 AE DA 02 83 26 8B 02 23 A0 DA 04 +83 26 CB 02 23 A2 DA 04 83 26 0B 03 23 A4 DA 04 +83 26 4B 03 23 A6 DA 04 83 26 8B 03 23 A8 DA 04 +83 26 CB 03 23 AA DA 04 63 ED E7 16 85 47 23 A8 +FA 00 03 C7 2B 00 63 07 07 0E 37 87 03 10 1C C3 +37 37 02 50 13 07 C7 39 34 43 7C 43 D5 8F 91 EF +73 00 50 10 93 07 40 06 01 00 FD 17 C2 07 C1 83 +E5 FF 3C 43 74 43 D5 8F E5 D7 03 A5 09 14 09 44 +63 64 A4 08 63 16 0A 0C B7 46 03 10 26 84 81 45 +85 8E 13 06 80 4C 39 A0 93 95 07 01 C1 81 11 04 +63 88 C5 0C B3 87 86 00 84 43 18 40 93 87 15 00 +E3 04 97 FE 63 15 05 14 05 45 EF B0 DF A8 01 A0 +83 A6 4B 00 B4 CF 83 A6 8B 00 F4 CF 83 A6 CB 00 +B4 D3 83 A6 0B 01 F4 D3 83 A6 4B 01 B4 D7 83 A6 +8B 01 F4 D7 83 A6 CB 01 B4 DB 83 A6 0B 02 F4 DB +89 47 E3 F0 E7 EC 37 15 02 50 13 05 85 44 EF B0 +9F A6 03 A7 09 14 75 B5 6C 43 30 43 25 65 13 05 +45 B7 EF B0 5F A7 63 1D 0A 02 03 A5 09 14 E3 75 +A4 F6 37 15 02 50 13 05 85 46 EF B0 DF A3 03 A5 +09 14 99 BF B7 87 03 10 0D 47 98 C3 11 BF 37 15 +02 50 13 05 C5 36 EF B0 1F A2 03 A7 09 14 FD B3 +83 C7 1B 00 81 CF B2 50 22 54 92 54 02 59 F2 49 +62 4A D2 4A 42 4B B2 4B 45 61 82 80 03 A5 09 14 +89 47 63 E0 A7 0C B7 16 03 10 4A 84 81 45 B3 86 +26 41 13 06 80 28 39 A0 93 95 07 01 C1 81 11 04 +E3 83 C5 FC B3 87 86 00 84 43 18 40 93 87 15 00 +E3 04 97 FE 83 A7 09 14 C1 EF 05 45 EF B0 BF 99 +01 A0 37 15 02 50 13 05 85 45 EF B0 DF 9A 85 47 +03 A7 09 14 23 A8 FA 00 83 C7 2B 00 91 CF B7 87 +03 10 80 C3 89 47 63 FB E7 0A 37 15 02 50 13 05 +C5 31 EF B0 5F 98 AD B5 0D 44 D5 B7 37 15 02 50 +13 05 85 39 EF B0 3F 97 03 A7 09 14 BD B3 25 69 +13 09 49 B7 13 05 89 03 EF B0 FF 97 83 A7 09 14 +E3 84 07 EA A6 85 13 05 89 06 EF B0 DF 96 83 A7 +09 14 E3 8B 07 E8 0C 40 13 05 09 08 EF B0 BF 95 +61 B5 37 15 02 50 13 05 85 48 EF B0 DF 92 25 BF +25 69 13 09 49 B7 13 05 89 09 EF B0 DF 93 83 A7 +09 14 A1 DF A6 85 13 05 89 0C EF B0 DF 92 83 A7 +09 14 A1 D7 0C 40 13 05 09 0E EF B0 DF 91 35 BF +15 EB 05 45 EF B0 3F 8D 01 A0 37 15 02 50 13 05 +C5 3B EF B0 5F 8E 03 A7 09 14 9D B5 37 37 02 50 +13 07 C7 39 3C 43 74 43 D5 8F E3 83 07 DC 03 A5 +09 14 CD B3 37 15 02 50 13 05 05 40 EF B0 BF 8B +C9 B7 79 71 4E CE B7 09 02 50 03 A8 09 14 22 D4 +56 CA 5A C8 5E C6 62 C4 06 D6 26 D2 4A D0 52 CC +89 47 AA 8B 2E 8B 32 8C B6 8A 3A 84 63 E7 07 29 +B7 07 03 10 C4 4B 85 88 F5 DC 03 CA 0B 00 63 0C +0A 06 83 C7 2B 00 B7 86 03 10 09 47 86 07 93 F7 +E7 03 93 E7 17 00 9C C2 63 60 07 31 B7 07 03 10 +23 AC 07 04 23 AE 07 04 23 A0 07 06 23 A2 07 06 +23 A4 07 06 23 A6 07 06 23 A8 07 06 23 AA 07 06 +37 87 03 10 5C 43 89 8B F5 DF 83 C6 1B 00 85 47 +63 9B F6 04 5C 43 93 F7 C7 3F 63 81 07 30 89 47 +63 F3 07 05 37 15 02 50 13 05 45 4A EF B0 BF 80 +03 A8 09 14 0D A8 03 A7 4B 00 B8 CF 03 A7 8B 00 +F8 CF 03 A7 CB 00 B8 D3 03 A7 0B 01 F8 D3 03 A7 +4B 01 B8 D7 03 A7 8B 01 F8 D7 03 A7 CB 01 B8 DB +03 A7 0B 02 F8 DB 03 27 0B 00 37 09 03 10 89 47 +23 2C E9 08 03 27 4B 00 23 2E E9 08 03 27 8B 00 +23 20 E9 0A 03 27 CB 00 23 22 E9 0A 03 27 0B 01 +23 24 E9 0A 03 27 4B 01 23 26 E9 0A 03 27 8B 01 +23 28 E9 0A 03 27 CB 01 23 2A E9 0A 03 27 0B 02 +23 2C E9 0A 03 27 4B 02 23 2E E9 0A 03 27 8B 02 +23 20 E9 0C 03 27 CB 02 23 22 E9 0C 03 27 0B 03 +23 24 E9 0C 03 27 4B 03 23 26 E9 0C 03 27 8B 03 +23 28 E9 0C 03 27 CB 03 23 2A E9 0C 03 27 0C 00 +23 2C E9 06 03 27 4C 00 23 2E E9 06 03 27 8C 00 +23 20 E9 08 03 27 CC 00 23 22 E9 08 03 27 0C 01 +23 24 E9 08 03 27 4C 01 23 26 E9 08 03 27 8C 01 +23 28 E9 08 03 27 CC 01 23 2A E9 08 03 A7 0A 00 +23 2C E9 00 03 A7 4A 00 23 2E E9 00 03 A7 8A 00 +23 20 E9 02 03 A7 CA 00 23 22 E9 02 03 A7 0A 01 +23 24 E9 02 03 A7 4A 01 23 26 E9 02 03 A7 8A 01 +23 28 E9 02 03 A7 CA 01 23 2A E9 02 03 A7 0A 02 +23 2C E9 02 03 A7 4A 02 23 2E E9 02 03 A7 8A 02 +23 20 E9 04 03 A7 CA 02 23 22 E9 04 03 A7 0A 03 +23 24 E9 04 03 A7 4A 03 23 26 E9 04 03 A7 8A 03 +23 28 E9 04 03 A7 CA 03 23 2A E9 04 63 E9 07 0F +91 47 23 28 F9 00 83 C7 2B 00 D5 CF B7 87 03 10 +05 47 98 C3 37 37 02 50 13 07 C7 39 34 43 7C 43 +D5 8F 91 EF 73 00 50 10 93 07 40 06 01 00 FD 17 +C2 07 C1 83 E5 FF 3C 43 74 43 D5 8F E5 D7 83 A6 +09 14 89 47 63 EC D7 04 63 05 0A 00 83 C7 1B 00 +D9 E3 B7 26 03 10 81 45 81 8E 13 06 50 48 39 A0 +93 95 07 01 C1 81 11 04 63 87 C5 06 B3 87 86 00 +84 43 18 40 93 87 15 00 E3 04 97 FE 83 A7 09 14 +CD EF 05 45 EF B0 2F DE 01 A0 37 15 02 50 13 05 +C5 36 EF B0 4F DF 03 A8 09 14 9D B3 6C 43 30 43 +25 65 13 05 45 B7 EF B0 0F E0 63 13 0A 02 03 A7 +09 14 89 47 E3 FF E7 F8 37 15 02 50 13 05 85 55 +EF B0 6F DC 79 B7 B7 87 03 10 0D 47 98 C3 99 B7 +83 C7 1B 00 E9 DF B2 50 22 54 92 54 02 59 F2 49 +62 4A D2 4A 42 4B B2 4B 22 4C 45 61 82 80 37 15 +02 50 13 05 05 54 EF B0 0F D9 91 47 03 A7 09 14 +23 28 F9 00 83 C7 2B 00 91 CF B7 87 03 10 84 C3 +89 47 63 F3 E7 06 37 15 02 50 13 05 C5 31 EF B0 +8F D6 CD BD 8D 44 D5 B7 37 15 02 50 13 05 85 39 +EF B0 6F D5 03 A8 09 14 D5 B9 25 69 13 09 49 B7 +13 05 89 0F EF B0 2F D6 83 A7 09 14 9D DB A6 85 +13 05 49 12 EF B0 2F D5 83 A7 09 14 E3 83 07 F2 +0C 40 13 05 C9 13 EF B0 0F D4 21 BF 63 10 08 02 +05 45 EF B0 4F CF 01 A0 37 37 02 50 13 07 C7 39 +3C 43 74 43 D5 8F E3 8F 07 E8 7D BD 37 15 02 50 +13 05 05 4F EF B0 2F CF E1 BF 01 11 4A C8 37 09 +02 50 03 28 09 14 22 CC 26 CA 4E C6 52 C4 56 C2 +06 CE 5A C0 89 47 AA 84 2E 8A B2 8A B6 89 3A 84 +63 E8 07 1D 37 07 03 10 5C 4B 85 8B F5 DF 89 47 +63 E7 07 23 05 67 13 07 07 32 B7 65 03 10 A6 87 +33 86 E4 00 85 8D 94 43 33 87 F5 00 91 07 14 C3 +E3 9B C7 FE 89 47 63 EB 07 1F 83 27 0A 00 B7 04 +03 10 09 4B 23 AC F4 08 83 27 4A 00 23 AE F4 08 +83 27 8A 00 23 A0 F4 0A 83 27 CA 00 23 A2 F4 0A +83 27 0A 01 23 A4 F4 0A 83 27 4A 01 23 A6 F4 0A +83 27 8A 01 23 A8 F4 0A 83 27 CA 01 23 AA F4 0A +83 27 0A 02 23 AC F4 0A 83 27 4A 02 23 AE F4 0A +83 27 8A 02 23 A0 F4 0C 83 27 CA 02 23 A2 F4 0C +83 27 0A 03 23 A4 F4 0C 83 27 4A 03 23 A6 F4 0C +83 27 8A 03 23 A8 F4 0C 83 27 CA 03 23 AA F4 0C +83 A7 0A 00 BC DC 83 A7 4A 00 FC DC 83 A7 8A 00 +23 A0 F4 08 83 A7 CA 00 23 A2 F4 08 83 A7 0A 01 +23 A4 F4 08 83 A7 4A 01 23 A6 F4 08 83 A7 8A 01 +23 A8 F4 08 83 A7 CA 01 23 AA F4 08 83 A7 09 00 +9C CC 83 A7 49 00 DC CC 83 A7 89 00 9C D0 83 A7 +C9 00 DC D0 83 A7 09 01 9C D4 83 A7 49 01 DC D4 +83 A7 89 01 9C D8 83 A7 C9 01 DC D8 83 A7 09 02 +9C DC 83 A7 49 02 DC DC 83 A7 89 02 BC C0 83 A7 +C9 02 FC C0 83 A7 09 03 BC C4 83 A7 49 03 FC C4 +83 A7 89 03 BC C8 83 A7 C9 03 FC C8 63 65 0B 0B +23 A8 64 01 37 37 02 50 13 07 C7 39 34 43 7C 43 +D5 8F 91 EF 73 00 50 10 93 07 40 06 01 00 FD 17 +C2 07 C1 83 E5 FF 3C 43 74 43 D5 8F E5 D7 83 27 +09 14 89 44 63 E7 F4 04 B7 26 03 10 81 45 81 8E +13 06 50 48 39 A0 93 95 07 01 C1 81 11 04 63 89 +C5 0C B3 87 86 00 84 43 18 40 93 87 15 00 E3 04 +97 FE 83 27 09 14 C9 E7 05 45 EF B0 CF AD 01 A0 +37 15 02 50 13 05 C5 34 EF B0 EF AE 03 28 09 14 +15 B5 6C 43 30 43 25 65 13 05 45 B7 EF B0 AF AF +83 27 09 14 E3 F2 F4 FA 37 15 02 50 13 05 85 55 +EF B0 6F AC 51 BF 37 15 02 50 13 05 05 59 EF B0 +8F AB 83 27 09 14 23 A8 64 01 63 7D FB 06 37 15 +02 50 13 05 C5 31 EF B0 0F AA 2D BF 37 15 02 50 +13 05 45 58 EF B0 2F A9 03 28 09 14 FD BB 37 15 +02 50 13 05 45 57 EF B0 0F A8 03 28 09 14 D9 B3 +A5 69 93 89 49 B7 13 85 49 15 EF B0 CF A8 83 27 +09 14 BD D3 A6 85 13 85 09 18 EF B0 CF A7 83 27 +09 14 B9 DB 0C 40 13 85 89 19 EF B0 CF A6 A9 B7 +F2 40 62 44 D2 44 42 49 B2 49 22 4A 92 4A 02 4B +05 61 82 80 37 37 02 50 13 07 C7 39 34 43 7C 43 +D5 8F E3 89 07 EC CD BD 01 11 22 CC 06 CE 26 CA +4A C8 4E C6 32 88 36 84 37 07 03 10 5C 4B 85 8B +F5 DF 1C 41 23 2C F7 08 54 41 AE 87 23 2E D7 08 +83 28 85 00 85 66 93 86 06 A2 23 20 17 0B 33 86 +D5 00 54 45 B7 15 03 10 9D 8D 23 22 D7 0A 14 49 +23 24 D7 0A 54 49 23 26 D7 0A 14 4D 23 28 D7 0A +54 4D 23 2A D7 0A 14 51 23 2C D7 0A 54 51 23 2E +D7 0A 14 55 23 20 D7 0C 54 55 23 22 D7 0C 14 59 +23 24 D7 0C 54 59 23 26 D7 0C 14 5D 23 28 D7 0C +54 5D 23 2A D7 0C 94 43 33 87 F5 00 91 07 14 C3 +E3 9B C7 FE 05 67 13 07 47 21 B7 25 03 10 C2 87 +33 06 E8 00 B3 85 05 41 94 43 33 87 F5 00 91 07 +14 C3 E3 9B C7 FE 37 09 02 50 83 27 09 14 89 44 +63 E8 F4 12 B7 07 03 10 0D 47 98 CB 37 37 02 50 +13 07 C7 39 34 43 7C 43 D5 8F 9D E3 73 00 50 10 +93 07 40 06 01 00 FD 17 C2 07 C1 83 E5 FF 3C 43 +74 43 D5 8F E5 D7 83 27 09 14 89 44 63 E8 F4 0C +B7 07 03 10 83 A4 87 0D 18 40 63 19 97 0A 83 A4 +C7 0D 58 40 63 94 E4 14 83 A4 07 0E 18 44 63 92 +E4 14 83 A4 47 0E 58 44 63 96 E4 14 83 A4 87 0E +18 48 63 9E E4 12 83 A4 C7 0E 58 48 63 96 E4 12 +83 A4 07 0F 18 4C 63 96 E4 14 83 A4 47 0F 58 4C +63 94 E4 16 83 A4 87 0F 18 50 63 9B E4 14 83 A4 +C7 0F 5C 50 63 92 F4 14 B7 07 03 10 83 A4 07 10 +18 54 63 97 E4 12 83 A4 47 10 58 54 63 97 E4 10 +83 A4 87 10 18 58 63 9E E4 0E 83 A4 C7 10 58 58 +63 94 E4 10 83 A4 07 11 18 5C 63 90 E4 0E 83 A4 +47 11 5C 5C BD 45 13 04 C4 03 63 9A 97 00 F2 40 +62 44 D2 44 42 49 B2 49 05 61 82 80 81 45 83 27 +09 14 AD E7 05 45 EF B0 0F 83 01 A0 6C 43 30 43 +25 65 13 05 45 B7 EF B0 0F 86 83 27 09 14 E3 F1 +F4 F2 37 15 02 50 13 05 45 5B EF B0 CF 82 09 BF +37 15 02 50 13 05 05 5A EF B0 EF 81 83 27 09 14 +37 07 03 10 8D 46 14 CB E3 F2 F4 EC 37 15 02 50 +13 05 C5 31 EF B0 2F 80 37 37 02 50 13 07 C7 39 +34 43 7C 43 D5 8F E3 8B 07 EA F1 B5 A5 69 93 89 +49 B7 13 85 09 1B EF B0 0F 80 83 27 09 14 D9 D3 +A6 85 13 85 49 1E EF A0 1F FF 83 27 09 14 BD DB +0C 40 13 85 C9 1F EF A0 1F FE AD B7 11 04 85 45 +B9 BF 21 04 89 45 A1 BF 51 04 95 45 89 BF 41 04 +91 45 B1 B7 31 04 8D 45 99 B7 13 04 84 03 B9 45 +3D BF 13 04 04 03 B1 45 1D BF 13 04 C4 02 AD 45 +3D B7 61 04 99 45 25 B7 13 04 44 03 B5 45 05 B7 +13 04 84 02 A9 45 21 BF 13 04 44 02 A5 45 01 BF +13 04 04 02 A1 45 21 B7 71 04 9D 45 09 B7 79 71 +4A D0 37 09 02 50 03 28 09 14 22 D4 52 CC 56 CA +5A C8 5E C6 06 D6 26 D2 4E CE 89 47 2A 8B 2E 8A +B2 8B B6 8A 3A 84 63 EB 07 29 B7 07 03 10 C4 4B +85 88 F5 DC 83 49 0B 00 63 8C 09 06 83 47 2B 00 +B7 86 03 10 09 47 86 07 93 F7 E7 03 93 E7 17 00 +9C C2 63 6D 07 31 B7 07 03 10 23 AC 07 04 23 AE +07 04 23 A0 07 06 23 A2 07 06 23 A4 07 06 23 A6 +07 06 23 A8 07 06 23 AA 07 06 37 87 03 10 5C 43 +89 8B F5 DF 83 46 1B 00 85 47 63 9B F6 04 5C 43 +93 F7 C7 3F 63 8F 07 30 89 47 63 F3 07 05 37 15 +02 50 13 05 45 4A EF A0 1F EB 03 28 09 14 0D A8 +03 27 4B 00 B8 CF 03 27 8B 00 F8 CF 03 27 CB 00 +B8 D3 03 27 0B 01 F8 D3 03 27 4B 01 B8 D7 03 27 +8B 01 F8 D7 03 27 CB 01 B8 DB 03 27 0B 02 F8 DB +83 26 0A 00 B7 07 03 10 09 47 23 AC D7 10 83 26 +4A 00 23 AE D7 10 83 26 8A 00 23 A0 D7 12 83 26 +CA 00 23 A2 D7 12 83 26 0A 01 23 A4 D7 12 83 26 +4A 01 23 A6 D7 12 83 26 8A 01 23 A8 D7 12 83 26 +CA 01 23 AA D7 12 83 26 0A 02 23 AC D7 12 83 26 +4A 02 23 AE D7 12 83 26 8A 02 23 A0 D7 14 83 26 +CA 02 23 A2 D7 14 83 26 0A 03 23 A4 D7 14 83 26 +4A 03 23 A6 D7 14 83 26 8A 03 23 A8 D7 14 83 26 +CA 03 23 AA D7 14 83 A6 0B 00 B4 DF 83 A6 4B 00 +F4 DF 83 A6 8B 00 23 A0 D7 08 83 A6 CB 00 23 A2 +D7 08 83 A6 0B 01 23 A4 D7 08 83 A6 4B 01 23 A6 +D7 08 83 A6 8B 01 23 A8 D7 08 83 A6 CB 01 23 AA +D7 08 63 6A 07 1B 03 A7 0A 00 37 0A 03 10 89 47 +23 2C EA 00 03 A7 4A 00 23 2E EA 00 03 A7 8A 00 +23 20 EA 02 03 A7 CA 00 23 22 EA 02 03 A7 0A 01 +23 24 EA 02 03 A7 4A 01 23 26 EA 02 03 A7 8A 01 +23 28 EA 02 03 A7 CA 01 23 2A EA 02 03 A7 0A 02 +23 2C EA 02 03 A7 4A 02 23 2E EA 02 03 A7 8A 02 +23 20 EA 04 03 A7 CA 02 23 22 EA 04 03 A7 0A 03 +23 24 EA 04 03 A7 4A 03 23 26 EA 04 03 A7 8A 03 +23 28 EA 04 03 A7 CA 03 23 2A EA 04 63 E9 07 0F +93 07 40 02 23 28 FA 00 83 47 2B 00 C9 CB B7 87 +03 10 05 47 98 C3 37 37 02 50 13 07 C7 39 3C 43 +74 43 D5 8F 91 EF 73 00 50 10 93 07 40 06 01 00 +FD 17 C2 07 C1 83 E5 FF 3C 43 74 43 D5 8F E5 D7 +83 26 09 14 89 47 63 E1 D7 06 63 85 09 00 83 47 +1B 00 D9 E3 B7 26 03 10 81 45 81 8E 13 06 50 48 +39 A0 93 95 07 01 C1 81 11 04 63 87 C5 06 B3 87 +86 00 84 43 18 40 93 87 15 00 E3 04 97 FE 83 27 +09 14 F1 E7 05 45 EF A0 1F C8 01 A0 37 15 02 50 +13 05 C5 36 EF A0 3F C9 03 28 09 14 B9 BB B7 87 +03 10 0D 47 98 C3 85 BF 6C 43 30 43 25 65 13 05 +45 B7 EF A0 5F C9 63 9E 09 00 03 27 09 14 89 47 +E3 FA E7 F8 37 15 02 50 13 05 85 55 EF A0 BF C5 +51 B7 83 47 1B 00 F5 D3 B2 50 22 54 92 54 02 59 +F2 49 62 4A D2 4A 42 4B B2 4B 45 61 82 80 37 15 +02 50 13 05 45 5D EF A0 1F C3 93 07 40 02 03 27 +09 14 23 28 FA 00 83 47 2B 00 9D C7 B7 87 03 10 +84 C3 89 47 63 FD E7 06 37 15 02 50 13 05 C5 31 +EF A0 7F C0 CD BD 37 15 02 50 13 05 85 44 EF A0 +9F BF 03 28 09 14 81 B5 8D 44 C9 BF 37 15 02 50 +13 05 85 39 EF A0 3F BE 03 28 09 14 E9 B9 A5 69 +93 89 49 B7 13 85 49 21 EF A0 FF BE 83 27 09 14 +E3 82 07 F2 A6 85 13 85 09 24 EF A0 DF BD 83 27 +09 14 E3 89 07 F0 0C 40 13 85 89 25 EF A0 BF BC +11 B7 63 10 08 02 05 45 EF A0 FF B7 01 A0 37 37 +02 50 13 07 C7 39 3C 43 74 43 D5 8F E3 85 07 E8 +6D B5 37 15 02 50 13 05 05 4F EF A0 DF B7 E1 BF +01 11 4A C8 37 09 02 50 03 28 09 14 22 CC 26 CA +4E C6 52 C4 56 C2 06 CE 5A C0 89 47 AA 84 2E 8A +B2 8A B6 89 3A 84 63 E9 07 1D 37 07 03 10 5C 4B +85 8B F5 DF 89 47 63 E9 07 23 05 67 13 07 07 32 +B7 65 03 10 A6 87 33 86 E4 00 85 8D 94 43 33 87 +F5 00 91 07 14 C3 E3 9B C7 FE 89 47 63 ED 07 1F +83 27 0A 00 B7 04 03 10 09 4B 23 AC F4 10 83 27 +4A 00 23 AE F4 10 83 27 8A 00 23 A0 F4 12 83 27 +CA 00 23 A2 F4 12 83 27 0A 01 23 A4 F4 12 83 27 +4A 01 23 A6 F4 12 83 27 8A 01 23 A8 F4 12 83 27 +CA 01 23 AA F4 12 83 27 0A 02 23 AC F4 12 83 27 +4A 02 23 AE F4 12 83 27 8A 02 23 A0 F4 14 83 27 +CA 02 23 A2 F4 14 83 27 0A 03 23 A4 F4 14 83 27 +4A 03 23 A6 F4 14 83 27 8A 03 23 A8 F4 14 83 27 +CA 03 23 AA F4 14 83 A7 0A 00 BC DC 83 A7 4A 00 +FC DC 83 A7 8A 00 23 A0 F4 08 83 A7 CA 00 23 A2 +F4 08 83 A7 0A 01 23 A4 F4 08 83 A7 4A 01 23 A6 +F4 08 83 A7 8A 01 23 A8 F4 08 83 A7 CA 01 23 AA +F4 08 83 A7 09 00 9C CC 83 A7 49 00 DC CC 83 A7 +89 00 9C D0 83 A7 C9 00 DC D0 83 A7 09 01 9C D4 +83 A7 49 01 DC D4 83 A7 89 01 9C D8 83 A7 C9 01 +DC D8 83 A7 09 02 9C DC 83 A7 49 02 DC DC 83 A7 +89 02 BC C0 83 A7 C9 02 FC C0 83 A7 09 03 BC C4 +83 A7 49 03 FC C4 83 A7 89 03 BC C8 83 A7 C9 03 +FC C8 63 66 0B 0B 93 07 20 02 9C C8 37 37 02 50 +13 07 C7 39 34 43 7C 43 D5 8F 91 EF 73 00 50 10 +93 07 40 06 01 00 FD 17 C2 07 C1 83 E5 FF 3C 43 +74 43 D5 8F E5 D7 83 27 09 14 89 44 63 E7 F4 04 +B7 26 03 10 81 45 81 8E 13 06 50 48 39 A0 93 95 +07 01 C1 81 11 04 63 8A C5 0C B3 87 86 00 84 43 +18 40 93 87 15 00 E3 04 97 FE 83 27 09 14 D1 E7 +05 45 EF A0 5F 96 01 A0 37 15 02 50 13 05 C5 34 +EF A0 7F 97 03 28 09 14 0D B5 6C 43 30 43 25 65 +13 05 45 B7 EF A0 3F 98 83 27 09 14 E3 F2 F4 FA +37 15 02 50 13 05 85 55 EF A0 FF 94 51 BF 37 15 +02 50 13 05 45 61 EF A0 1F 94 83 27 09 14 13 07 +20 02 98 C8 63 7D FB 06 37 15 02 50 13 05 C5 31 +EF A0 7F 92 25 BF 37 15 02 50 13 05 05 60 EF A0 +9F 91 03 28 09 14 ED BB 37 15 02 50 13 05 45 57 +EF A0 7F 90 03 28 09 14 C9 B3 A5 69 93 89 49 B7 +13 85 09 27 EF A0 3F 91 83 27 09 14 B5 D3 A6 85 +13 85 C9 29 EF A0 3F 90 83 27 09 14 B1 DB 0C 40 +13 85 49 2B EF A0 3F 8F A1 B7 F2 40 62 44 D2 44 +42 49 B2 49 22 4A 92 4A 02 4B 05 61 82 80 37 37 +02 50 13 07 C7 39 34 43 7C 43 D5 8F E3 88 07 EC +C5 BD 01 11 22 CC 26 CA 4E C6 52 C4 06 CE 4A C8 +AA 84 AE 89 32 8A 36 84 37 07 03 10 5C 4B 85 8B +F5 DF 37 09 02 50 03 25 09 14 89 47 63 E7 A7 20 +9C 40 37 07 03 10 23 2C F7 10 D4 40 CE 87 23 2E +D7 10 8C 44 85 66 93 86 06 A2 23 20 B7 12 33 86 +D9 00 D4 44 B7 15 03 10 B3 85 35 41 23 22 D7 12 +94 48 23 24 D7 12 D4 48 23 26 D7 12 94 4C 23 28 +D7 12 D4 4C 23 2A D7 12 94 50 23 2C D7 12 D4 50 +23 2E D7 12 94 54 23 20 D7 14 D4 54 23 22 D7 14 +94 58 23 24 D7 14 D4 58 23 26 D7 14 94 5C 23 28 +D7 14 D4 5C 23 2A D7 14 94 43 33 87 F5 00 91 07 +14 C3 E3 9B C7 FE 05 67 13 07 47 21 B7 25 03 10 +D2 87 33 06 EA 00 B3 85 45 41 94 43 33 87 F5 00 +91 07 14 C3 E3 9B C7 FE 89 44 63 EA A4 12 B7 07 +03 10 13 07 30 02 98 CB 37 37 02 50 13 07 C7 39 +3C 43 74 43 D5 8F 91 EF 73 00 50 10 93 07 40 06 +01 00 FD 17 C2 07 C1 83 E5 FF 3C 43 74 43 D5 8F +E5 D7 83 27 09 14 89 44 63 E9 F4 0C B7 07 03 10 +83 A4 87 0D 18 40 63 1A 97 0A 83 A4 C7 0D 58 40 +63 96 E4 14 83 A4 07 0E 18 44 63 97 E4 16 83 A4 +47 0E 58 44 63 9F E4 14 83 A4 87 0E 18 48 63 97 +E4 14 83 A4 C7 0E 58 48 63 9F E4 12 83 A4 07 0F +18 4C 63 96 E4 14 83 A4 47 0F 58 4C 63 98 E4 14 +83 A4 87 0F 18 50 63 9F E4 12 83 A4 C7 0F 5C 50 +63 9D F4 14 B7 07 03 10 83 A4 07 10 18 54 63 92 +E4 14 83 A4 47 10 58 54 63 99 E4 12 83 A4 87 10 +18 58 63 90 E4 12 83 A4 C7 10 58 58 63 9B E4 12 +83 A4 07 11 18 5C 63 9A E4 12 83 A4 47 11 5C 5C +BD 45 13 04 C4 03 63 9B 97 00 F2 40 62 44 D2 44 +42 49 B2 49 22 4A 05 61 82 80 81 45 83 27 09 14 +B5 E7 05 45 EF A0 2F EA 01 A0 6C 43 30 43 25 65 +13 05 45 B7 EF A0 2F ED 83 27 09 14 E3 F0 F4 F2 +37 15 02 50 13 05 45 5B EF A0 EF E9 01 BF 37 15 +02 50 13 05 85 63 EF A0 0F E9 83 27 09 14 37 07 +03 10 93 06 30 02 14 CB 63 FD F4 04 37 15 02 50 +13 05 C5 31 EF A0 2F E7 45 BD 37 15 02 50 13 05 +05 60 EF A0 4F E6 03 25 09 14 DD B3 A5 69 93 89 +49 B7 13 85 C9 2C EF A0 0F E7 83 27 09 14 D1 D3 +A6 85 13 85 89 2F EF A0 0F E6 83 27 09 14 B5 DB +0C 40 13 85 09 31 EF A0 0F E5 A5 B7 11 04 85 45 +B1 BF 37 37 02 50 13 07 C7 39 34 43 7C 43 D5 8F +E3 84 07 E6 61 B5 51 04 95 45 89 B7 41 04 91 45 +35 BF 31 04 8D 45 1D BF 21 04 89 45 05 BF 61 04 +99 45 2D B7 13 04 04 02 A1 45 0D B7 71 04 9D 45 +31 BF 13 04 04 03 B1 45 11 BF 13 04 C4 02 AD 45 +31 B7 13 04 84 02 A9 45 11 B7 13 04 44 02 A5 45 +F5 BD 13 04 44 03 B5 45 D5 BD 13 04 84 03 B9 45 +F5 B5 B7 07 02 50 03 A7 07 14 41 11 22 C4 06 C6 +89 47 2A 84 63 E9 E7 02 37 07 03 10 5C 4B 85 8B +F5 DF 13 05 B0 09 EF A0 0F D7 83 47 24 00 B2 40 +22 44 86 07 93 F7 E7 03 93 E7 17 00 37 87 03 10 +1C C3 41 01 82 80 37 15 02 50 13 05 C5 34 EF A0 +8F D6 D9 B7 52 65 63 65 69 76 65 64 20 4D 4C 44 +53 41 20 6E 6F 74 69 66 2F 20 65 72 72 20 69 6E +74 72 20 77 69 74 68 20 73 74 61 74 75 73 20 3D +20 25 64 2F 20 25 64 0A 00 00 00 00 41 74 20 6F +66 66 73 65 74 20 5B 25 64 5D 2C 20 6D 6C 64 73 +61 5F 70 72 69 76 6B 65 79 20 64 61 74 61 20 6D +69 73 6D 61 74 63 68 21 0A 00 00 00 41 63 74 75 +61 6C 20 20 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 45 78 70 65 63 74 65 64 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 41 74 20 6F +66 66 73 65 74 20 5B 25 64 5D 2C 20 6D 6C 64 73 +61 5F 70 75 62 6B 65 79 20 64 61 74 61 20 6D 69 +73 6D 61 74 63 68 21 0A 00 00 00 00 41 63 74 75 +61 6C 20 20 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 45 78 70 65 63 74 65 64 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 41 74 20 6F +66 66 73 65 74 20 5B 25 64 5D 2C 20 6D 6C 64 73 +61 5F 73 69 67 6E 20 64 61 74 61 20 6D 69 73 6D +61 74 63 68 21 0A 00 00 41 63 74 75 61 6C 20 20 +20 64 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +45 78 70 65 63 74 65 64 20 64 61 74 61 3A 20 30 +78 25 78 0A 00 00 00 00 41 74 20 6F 66 66 73 65 +74 20 5B 25 64 5D 2C 20 6D 6C 64 73 61 5F 73 69 +67 6E 20 64 61 74 61 20 6D 69 73 6D 61 74 63 68 +21 0A 00 00 41 63 74 75 61 6C 20 20 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 45 78 70 65 +63 74 65 64 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 41 74 20 6F 66 66 73 65 74 20 5B 25 +64 5D 2C 20 6D 6C 64 73 61 5F 76 65 72 69 66 79 +5F 72 65 73 20 64 61 74 61 20 6D 69 73 6D 61 74 +63 68 21 0A 00 00 00 00 41 63 74 75 61 6C 20 20 +20 64 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +45 78 70 65 63 74 65 64 20 64 61 74 61 3A 20 30 +78 25 78 0A 00 00 00 00 41 74 20 6F 66 66 73 65 +74 20 5B 25 64 5D 2C 20 6D 6C 64 73 61 5F 73 69 +67 6E 20 64 61 74 61 20 6D 69 73 6D 61 74 63 68 +21 0A 00 00 41 63 74 75 61 6C 20 20 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 45 78 70 65 +63 74 65 64 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 41 74 20 6F 66 66 73 65 74 20 5B 25 +64 5D 2C 20 6D 6C 64 73 61 5F 73 69 67 6E 20 64 +61 74 61 20 6D 69 73 6D 61 74 63 68 21 0A 00 00 +41 63 74 75 61 6C 20 20 20 64 61 74 61 3A 20 30 +78 25 78 0A 00 00 00 00 45 78 70 65 63 74 65 64 +20 64 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +41 74 20 6F 66 66 73 65 74 20 5B 25 64 5D 2C 20 +61 63 74 75 61 6C 5F 64 61 74 61 20 64 61 74 61 +20 6D 69 73 6D 61 74 63 68 21 0A 00 41 63 74 75 +61 6C 20 20 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 45 78 70 65 63 74 65 64 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 41 11 22 C4 +37 04 02 50 03 27 04 14 06 C6 89 47 63 E0 E7 04 +37 37 02 50 13 07 C7 39 3C 43 74 43 D5 8F 9D E3 +73 00 50 10 93 07 40 06 01 00 FD 17 C2 07 C1 83 +E5 FF 3C 43 74 43 D5 8F E5 D7 83 26 04 14 89 47 +63 E5 D7 02 B2 40 22 44 41 01 82 80 37 15 02 50 +13 05 C5 65 EF A0 2F 9E 37 37 02 50 13 07 C7 39 +3C 43 74 43 D5 8F CD DF C9 BF 22 44 6C 43 B2 40 +30 43 2D 65 13 05 C5 64 41 01 6F A0 CF 9D 41 11 +26 C2 B7 04 02 50 83 A7 04 14 22 C4 06 C6 09 44 +63 60 F4 02 B7 97 03 10 21 47 98 CB 37 97 03 10 +5C 4B 85 8B F5 DF B2 40 22 44 92 44 41 01 82 80 +37 15 02 50 13 05 C5 67 EF A0 EF 97 83 A7 04 14 +37 97 03 10 A1 46 14 CB E3 7A F4 FC 37 15 02 50 +13 05 85 69 EF A0 2F 96 D1 B7 19 CA 0A 06 33 87 +C5 00 9C 41 91 05 11 05 23 2E F5 FE E3 9B E5 FE +82 80 79 71 4E CE B7 09 02 50 03 A7 09 14 22 D4 +52 CC 5A C8 5E C6 06 D6 26 D2 4A D0 56 CA 62 C4 +89 47 2A 8B AE 8B 32 84 36 8A 63 E5 E7 22 37 99 +03 10 83 24 49 01 85 88 ED DC 83 4A 0B 00 83 47 +2B 00 63 88 0A 16 86 07 93 F7 E7 03 93 E7 17 00 +B7 C6 03 10 9C C2 09 4C 63 61 EC 2A 23 2C 09 00 +23 2E 09 00 23 20 09 02 23 22 09 02 23 24 09 02 +23 26 09 02 23 28 09 02 23 2A 09 02 B7 97 03 10 +23 AC 07 02 23 AE 07 02 23 A0 07 04 23 A2 07 04 +23 A4 07 04 23 A6 07 04 23 A8 07 04 23 AA 07 04 +B7 C6 03 10 DC 42 89 8B F5 DF 03 46 1B 00 85 47 +63 11 F6 18 DC 42 93 F7 C7 3F 63 84 07 2E 89 47 +63 E6 E7 2E 03 A6 0B 00 B7 07 03 10 89 46 90 CF +03 A6 4B 00 D0 CF 03 A6 8B 00 90 D3 03 A6 CB 00 +D0 D3 03 A6 0B 01 90 D7 03 A6 4B 01 D0 D7 03 A6 +8B 01 90 DB 03 A6 CB 01 D0 DB 03 A6 0B 02 90 DF +03 A6 4B 02 D0 DF 03 A6 8B 02 B0 C3 03 A6 CB 02 +F0 C3 03 A6 0B 03 B0 C7 03 A6 4B 03 F0 C7 03 A6 +8B 03 B0 CB 03 A6 CB 03 F0 CB 63 EE E6 12 37 97 +03 10 85 47 1C CB 03 47 2B 00 63 08 07 10 37 C7 +03 10 1C C3 37 37 02 50 13 07 C7 39 34 43 7C 43 +D5 8F 91 EF 73 00 50 10 93 07 40 06 01 00 FD 17 +C2 07 C1 83 E5 FF 3C 43 74 43 D5 8F E5 D7 83 A7 +09 14 89 44 63 E5 F4 12 B7 B6 03 10 81 45 81 8E +13 06 80 18 39 A0 93 95 07 01 C1 81 11 04 63 89 +C5 1A B3 87 86 00 84 43 18 40 93 87 15 00 E3 04 +97 FE 83 A7 09 14 63 9E 07 10 05 45 EF 90 BF F7 +01 A0 83 27 4B 00 23 2C F9 00 83 27 8B 00 23 2E +F9 00 83 27 CB 00 23 20 F9 02 83 27 0B 01 23 22 +F9 02 83 27 4B 01 23 24 F9 02 83 27 8B 01 23 26 +F9 02 83 27 CB 01 23 28 F9 02 83 27 0B 02 23 2A +F9 02 83 27 4B 02 23 2C F9 02 83 27 8B 02 23 2E +F9 02 83 27 CB 02 23 20 F9 04 83 27 0B 03 23 22 +F9 04 83 27 4B 03 23 24 F9 04 83 27 8B 03 23 26 +F9 04 83 27 CB 03 23 28 F9 04 83 27 0B 04 23 2A +F9 04 89 47 E3 F8 E7 E8 37 15 02 50 13 05 C5 7B +EF 90 7F F0 03 A7 09 14 B5 BD B7 C7 03 10 0D 47 +98 C3 CD BD 37 15 02 50 13 05 45 6B EF 90 BF EE +03 A7 09 14 E9 B3 37 15 02 50 13 05 C5 7D EF 90 +9F ED B7 97 03 10 85 46 03 A7 09 14 94 CB 83 47 +2B 00 B5 CB B7 C7 03 10 84 C3 89 47 63 F9 E7 12 +37 15 02 50 13 05 C5 65 EF 90 FF EA 65 B5 6C 43 +30 43 2D 65 13 05 C5 64 EF 90 FF EB 83 A7 09 14 +E3 F4 F4 EC 37 15 02 50 13 05 C5 7F EF 90 BF E8 +65 BD 2D 69 13 09 C9 64 13 05 89 03 EF 90 BF E9 +83 A7 09 14 E3 8B 07 EC A6 85 13 05 C9 06 EF 90 +9F E8 83 A7 09 14 E3 82 07 EC 0C 40 13 05 49 08 +EF 90 7F E7 5D BD 8D 44 71 B7 37 15 02 50 13 05 +85 6D EF 90 5F E4 03 A7 09 14 23 2C 09 00 23 2E +09 00 23 20 09 02 23 22 09 02 23 24 09 02 23 26 +09 02 23 28 09 02 23 2A 09 02 E3 79 EC D4 37 15 +02 50 13 05 45 70 EF 90 1F E1 03 A7 09 14 3D BB +63 95 0A 04 03 A7 09 14 89 47 63 E4 E7 0C B7 A7 +03 10 81 45 B3 87 47 41 93 06 80 31 39 A0 93 15 +07 01 C1 81 11 0A 63 82 D5 02 33 87 47 01 04 43 +03 26 0A 00 13 87 15 00 E3 03 96 FE 83 A7 09 14 +A5 E3 05 45 EF 90 3F DA 01 A0 B2 50 22 54 92 54 +02 59 F2 49 62 4A D2 4A 42 4B B2 4B 22 4C 45 61 +82 80 05 EB 05 45 EF 90 1F D8 01 A0 37 15 02 50 +13 05 05 73 EF 90 3F D9 03 A7 09 14 9D BD 37 37 +02 50 13 07 C7 39 34 43 7C 43 D5 8F E3 84 07 D8 +65 B3 37 15 02 50 13 05 45 77 EF 90 DF D6 D9 B7 +2D 64 13 04 C4 64 13 05 C4 09 EF 90 DF D7 83 A7 +09 14 C1 DB A6 85 13 05 04 0D EF 90 DF D6 83 A7 +09 14 C1 D3 83 25 0A 00 13 05 84 0E EF 90 BF D5 +8D BF 37 25 02 50 13 05 05 82 EF 90 DF D2 05 BF +79 71 4A D0 37 09 02 50 03 27 09 14 22 D4 52 CC +5A C8 5E C6 06 D6 26 D2 4E CE 56 CA 62 C4 89 47 +2A 8B AE 8B 32 84 36 8A 63 E1 E7 30 B7 9A 03 10 +83 A4 4A 01 85 88 ED DC 83 49 0B 00 63 8B 09 24 +83 47 2B 00 B7 C6 03 10 09 4C 86 07 93 F7 E7 03 +93 E7 17 00 9C C2 63 64 EC 38 23 AC 0A 00 23 AE +0A 00 23 A0 0A 02 23 A2 0A 02 23 A4 0A 02 23 A6 +0A 02 23 A8 0A 02 23 AA 0A 02 B7 97 03 10 23 AC +07 02 23 AE 07 02 23 A0 07 04 23 A2 07 04 23 A4 +07 04 23 A6 07 04 23 A8 07 04 23 AA 07 04 B7 C6 +03 10 DC 42 89 8B F5 DF 03 46 1B 00 85 47 63 0E +F6 3A 89 47 63 FA E7 00 37 25 02 50 13 05 45 84 +EF 90 7F C6 03 27 09 14 B7 97 03 10 83 AA 87 01 +63 96 0A 3E 94 4F 83 AA C7 01 63 94 0A 46 D4 4F +83 AA 07 02 63 91 0A 46 94 53 83 AA 47 02 63 9E +0A 44 D4 53 83 AA 87 02 63 9B 0A 44 94 57 83 AA +C7 02 63 9C 0A 42 D4 57 83 AA 07 03 63 99 0A 42 +94 5B 83 AA 47 03 9D 45 63 93 0A 3A DC 5B 89 47 +63 E2 E7 30 B7 97 03 10 83 AA 87 03 63 92 0A 38 +94 5F 83 AA C7 03 63 9E 0A 40 D4 5F 83 AA 07 04 +63 9B 0A 40 B4 43 83 AA 47 04 63 98 0A 40 F4 43 +83 AA 87 04 63 95 0A 40 B4 47 83 AA C7 04 63 92 +0A 40 F4 47 83 AA 07 05 63 90 0A 3C B4 4B 83 AA +47 05 9D 45 63 9F 0A 32 FC 4B 89 47 63 EE E7 18 +03 A6 0B 00 B7 07 03 10 89 46 90 CF 03 A6 4B 00 +D0 CF 03 A6 8B 00 90 D3 03 A6 CB 00 D0 D3 03 A6 +0B 01 90 D7 03 A6 4B 01 D0 D7 03 A6 8B 01 90 DB +03 A6 CB 01 D0 DB 03 A6 0B 02 90 DF 03 A6 4B 02 +D0 DF 03 A6 8B 02 B0 C3 03 A6 CB 02 F0 C3 03 A6 +0B 03 B0 C7 03 A6 4B 03 F0 C7 03 A6 8B 03 B0 CB +03 A6 CB 03 F0 CB 63 EB E6 14 37 97 03 10 85 47 +1C CB 03 47 2B 00 63 0B 07 1A 37 C7 03 10 1C C3 +37 37 02 50 13 07 C7 39 34 43 7C 43 D5 8F 91 EF +73 00 50 10 93 07 40 06 01 00 FD 17 C2 07 C1 83 +E5 FF 3C 43 74 43 D5 8F E5 D7 03 25 09 14 89 44 +63 E3 A4 18 B7 B7 03 10 B7 55 FC EF 13 86 07 62 +94 43 33 87 B7 00 22 97 14 C3 91 07 E3 9A C7 FE +89 47 63 91 09 12 63 EA A7 22 37 B6 03 10 B7 A7 +03 10 B7 65 FC EF 13 06 06 C6 94 43 33 87 B7 00 +52 97 14 C3 91 07 E3 9A C7 FE B2 50 22 54 92 54 +02 59 F2 49 62 4A D2 4A 42 4B B2 4B 22 4C 45 61 +82 80 83 27 4B 00 23 AC FA 00 83 27 8B 00 23 AE +FA 00 83 27 CB 00 23 A0 FA 02 83 27 0B 01 23 A2 +FA 02 83 27 4B 01 23 A4 FA 02 83 27 8B 01 23 A6 +FA 02 83 27 CB 01 23 A8 FA 02 83 27 0B 02 23 AA +FA 02 83 27 4B 02 23 AC FA 02 83 27 8B 02 23 AE +FA 02 83 27 CB 02 23 A0 FA 04 83 27 0B 03 23 A2 +FA 04 83 27 4B 03 23 A4 FA 04 83 27 8B 03 23 A6 +FA 04 83 27 CB 03 23 A8 FA 04 83 27 0B 04 23 AA +FA 04 89 47 E3 F6 E7 E6 37 15 02 50 13 05 C5 7B +EF 90 7F A0 03 27 09 14 A1 BD 37 15 02 50 13 05 +45 6B EF 90 5F 9F 03 27 09 14 CD B9 37 15 02 50 +13 05 C5 7D EF 90 3F 9E B7 97 03 10 85 46 03 27 +09 14 94 CB 83 47 2B 00 F9 CF B7 C7 03 10 84 C3 +89 47 63 F2 E7 20 37 15 02 50 13 05 C5 65 EF 90 +9F 9B 79 B5 63 E7 A7 12 B7 A7 03 10 81 45 13 06 +80 31 01 A8 93 15 07 01 9C 43 C1 81 E3 87 C5 EE +B6 87 80 43 13 87 15 00 93 86 47 00 65 D4 83 27 +09 14 C1 EF 05 45 EF 90 1F 96 01 A0 B7 C7 03 10 +0D 47 98 C3 B1 B5 6C 43 30 43 2D 65 13 05 C5 64 +EF 90 7F 98 03 25 09 14 E3 F6 A4 E6 37 25 02 50 +13 05 C5 89 EF 90 3F 95 03 25 09 14 A1 BD 37 15 +02 50 13 05 85 6D EF 90 1F 94 03 27 09 14 23 AC +0A 00 23 AE 0A 00 23 A0 0A 02 23 A2 0A 02 23 A4 +0A 02 23 A6 0A 02 23 A8 0A 02 23 AA 0A 02 E3 76 +EC C6 37 15 02 50 13 05 45 70 EF 90 DF 90 03 27 +09 14 A1 B9 37 25 02 50 13 05 05 87 EF 90 BF 8F +03 27 09 14 C5 B9 8D 44 0D B7 AD 64 93 84 C4 64 +13 85 04 1C EF 90 3F 90 83 27 09 14 A1 DF A2 85 +13 85 C4 1E EF 90 3F 8F 83 27 09 14 A1 D7 81 45 +13 85 44 20 EF 90 3F 8E 35 BF DC 42 93 F7 C7 3F +85 C7 89 47 E3 FA E7 C4 37 15 02 50 13 05 05 73 +EF 90 7F 8A 03 27 09 14 2D B1 37 25 02 50 13 05 +C5 8B EF 90 5F 89 D1 B3 51 EB 05 45 EF 90 BF 86 +01 A0 37 25 02 50 13 05 C5 8D EF 90 DF 87 E9 B5 +81 45 19 EB 05 45 EF 90 1F 85 01 A0 81 45 0D EF +05 45 EF 90 5F 84 01 A0 2D 64 13 04 C4 64 13 05 +04 16 EF 90 5F 87 83 27 09 14 E9 DF D6 85 13 05 +04 19 EF 90 5F 86 83 27 09 14 E9 D7 81 45 13 05 +84 1A EF 90 5F 85 7D BF 2D 64 13 04 C4 64 13 05 +04 10 EF 90 5F 84 83 27 09 14 DD DB D6 85 13 05 +04 13 EF 90 5F 83 83 27 09 14 DD D3 81 45 13 05 +84 14 EF 90 5F 82 69 BF 99 45 61 B7 37 15 02 50 +13 05 45 77 EF 90 2F FF 8D B7 95 45 49 B7 99 45 +BD BF 85 45 AD BF 89 45 9D BF 8D 45 8D BF 91 45 +BD B7 85 45 B9 BF 89 45 A9 BF 8D 45 99 BF 91 45 +89 BF 95 45 B9 B7 37 37 02 50 13 07 C7 39 3C 43 +74 43 D5 8F E3 8E 07 C8 85 B5 79 71 4A D0 37 09 +02 50 03 28 09 14 22 D4 4E CE 52 CC 5A C8 5E C6 +06 D6 26 D2 56 CA 62 C4 89 47 83 4A 07 00 3A 8A +2A 8B AE 89 B2 8B 36 84 63 EE 07 27 B7 97 03 10 +C4 4B 85 88 F5 DC 89 47 63 E4 07 29 B7 B5 03 10 +DA 87 13 06 0B 62 B3 85 65 41 94 43 33 87 F5 00 +91 07 14 C3 E3 9B C7 FE 03 CB 09 00 63 09 0B 10 +83 C7 29 00 37 C7 03 10 09 4C 86 07 93 F7 E7 03 +93 E7 17 00 1C C7 63 66 0C 2F B7 97 03 10 23 A0 +07 08 23 A2 07 08 23 A4 07 08 23 A6 07 08 23 A8 +07 08 23 AA 07 08 23 AC 07 08 23 AE 07 08 B7 77 +03 10 23 A0 07 2A 23 A2 07 2A 23 A4 07 2A 23 A6 +07 2A 23 A8 07 2A 23 AA 07 2A 23 AC 07 2A 23 AE +07 2A 23 A0 07 2C 37 C7 03 10 5C 47 89 8B F5 DF +83 C6 19 00 85 47 63 8D F6 2C 89 47 63 FA 07 01 +37 25 02 50 13 05 45 A3 EF 90 EF EB 03 28 09 14 +B7 97 03 10 03 AC 07 08 63 13 0C 30 03 A7 07 08 +03 AC 47 08 63 14 0C 56 03 A7 47 08 03 AC 87 08 +63 10 0C 56 03 A7 87 08 03 AC C7 08 63 1C 0C 54 +03 A7 C7 08 03 AC 07 09 63 11 0C 4A 03 A7 07 09 +03 AC 47 09 63 1D 0C 48 03 A7 47 09 03 AC 87 09 +63 19 0C 48 03 A7 87 09 03 AC C7 09 9D 45 63 19 +0C 2A 83 A7 C7 09 89 47 63 F0 07 07 37 25 02 50 +13 05 05 A6 EF 90 2F E4 03 28 09 14 B1 A0 03 A7 +49 00 B7 97 03 10 23 A0 E7 08 03 A7 89 00 23 A2 +E7 08 03 A7 C9 00 23 A4 E7 08 03 A7 09 01 23 A6 +E7 08 03 A7 49 01 23 A8 E7 08 03 A7 89 01 23 AA +E7 08 03 A7 C9 01 23 AC E7 08 03 A7 09 02 23 AE +E7 08 89 47 E3 E4 07 FB 03 A7 0B 00 B7 07 03 10 +09 4C 98 CF 03 A7 4B 00 D8 CF 03 A7 8B 00 98 D3 +03 A7 CB 00 D8 D3 03 A7 0B 01 98 D7 03 A7 4B 01 +D8 D7 03 A7 8B 01 98 DB 03 A7 CB 01 D8 DB 03 A7 +0B 02 98 DF 03 A7 4B 02 D8 DF 03 A7 8B 02 B8 C3 +03 A7 CB 02 F8 C3 03 A7 0B 03 B8 C7 03 A7 4B 03 +F8 C7 03 A7 8B 03 B8 CB 03 A7 CB 03 F8 CB 63 6A +0C 0B B7 97 03 10 23 A8 87 01 83 C7 29 00 C1 C7 +B7 C7 03 10 05 47 98 C7 37 37 02 50 13 07 C7 39 +34 43 7C 43 D5 8F 91 EF 73 00 50 10 93 07 40 06 +01 00 FD 17 C2 07 C1 83 E5 FF 3C 43 74 43 D5 8F +E5 D7 03 25 09 14 89 44 63 E1 A4 0A B7 C6 03 10 +93 86 06 80 81 45 81 8E 13 06 80 18 39 A0 93 95 +07 01 C1 81 11 04 63 85 C5 14 B3 87 86 00 84 43 +18 40 93 87 15 00 E3 04 97 FE 41 ED 05 45 EF 90 +8F CE 01 A0 37 25 02 50 13 05 45 90 EF 90 AF CF +03 28 09 14 A5 BB B7 C7 03 10 0D 47 98 C7 AD BF +37 25 02 50 13 05 85 92 EF 90 EF CD 03 28 09 14 +B5 B3 37 25 02 50 13 05 05 A8 EF 90 CF CC B7 97 +03 10 03 27 09 14 23 A8 87 01 83 C7 29 00 DD CF +B7 C7 03 10 84 C7 89 47 63 FF E7 2C 37 15 02 50 +13 05 C5 65 EF 90 2F CA 05 BF 6C 43 30 43 2D 65 +13 05 C5 64 EF 90 2F CB 03 25 09 14 E3 F8 A4 F4 +37 25 02 50 13 05 05 AA EF 90 EF C7 03 25 09 14 +35 BF AD 69 93 89 C9 64 13 85 89 27 EF 90 AF C8 +83 27 09 14 A1 DF A6 85 13 85 C9 2A EF 90 AF C7 +83 27 09 14 A1 D7 0C 40 13 85 49 2C EF 90 AF C6 +35 BF 37 25 02 50 13 05 C5 94 EF 90 CF C3 B7 97 +03 10 03 28 09 14 23 A0 07 08 23 A2 07 08 23 A4 +07 08 23 A6 07 08 23 A8 07 08 23 AA 07 08 23 AC +07 08 23 AE 07 08 E3 74 0C D1 37 25 02 50 13 05 +05 97 EF 90 4F C0 03 28 09 14 D5 B9 8D 44 89 B7 +5C 47 93 F7 C7 3F B9 CB 89 47 E3 FB 07 D3 37 25 +02 50 13 05 C5 9A EF 90 0F BE 03 28 09 14 31 B3 +63 84 0A 04 B7 C7 03 10 D8 4B 09 8B 75 DF DC 4B +83 46 1A 00 05 47 93 F7 C7 3F 63 89 E6 22 63 85 +07 20 63 1C 05 1E 05 45 EF 90 EF B8 01 A0 81 45 +63 13 08 08 05 45 EF 90 0F B8 01 A0 63 15 08 0A +05 45 EF 90 4F B7 01 A0 89 47 63 15 0B 0A 63 EC +A7 12 B7 97 03 10 A4 4F 03 24 4A 00 63 13 94 12 +E4 4F 03 24 8A 00 63 1C 94 10 A4 53 03 24 CA 00 +63 95 84 10 E4 53 03 24 0A 01 63 1E 94 0E A4 57 +03 24 4A 01 63 97 84 0E E4 57 03 24 8A 01 63 90 +84 0E A4 5B 03 24 CA 01 63 99 84 0C E4 5B 03 24 +0A 02 9D 45 63 0F 94 06 83 27 09 14 D9 E7 05 45 +EF 90 6F B0 01 A0 2D 64 13 04 C4 64 13 05 C4 21 +EF 90 6F B3 83 27 09 14 B5 D7 E2 85 13 05 84 24 +EF 90 6F B2 83 27 09 14 B1 DF 81 45 13 05 04 26 +EF 90 6F B1 81 BF 37 25 02 50 13 05 C5 9E EF 90 +8F AE B9 B7 63 EC A7 0E B7 97 03 10 A0 4F 59 E8 +E0 4F 63 13 04 0E A0 53 63 1E 04 0C E0 53 69 E8 +A0 57 69 E4 E0 57 69 E0 A0 5B 4D EC E0 5B 9D 45 +3D E8 B2 50 22 54 92 54 02 59 F2 49 62 4A D2 4A +42 4B B2 4B 22 4C 45 61 82 80 AD 69 93 89 C9 64 +13 85 C9 2D EF 90 2F AB 83 27 09 14 AD D3 A6 85 +13 85 09 31 EF 90 2F AA 83 27 09 14 A9 DB A2 85 +13 85 89 32 EF 90 2F A9 99 B7 99 45 35 BF 95 45 +25 BF 91 45 15 BF 8D 45 05 BF 89 45 35 B7 85 45 +25 B7 81 45 15 B7 37 25 02 50 13 05 05 BF EF 90 +8F A4 C1 B5 81 45 83 27 09 14 89 E7 05 45 EF 90 +8F A1 01 A0 AD 64 93 84 C4 64 13 85 04 34 EF 90 +8F A4 83 27 09 14 FD D3 A2 85 13 85 44 37 EF 90 +8F A3 83 27 09 14 F9 DB 81 45 13 85 C4 38 EF 90 +8F A2 E9 B7 99 45 C1 B7 95 45 75 BF 91 45 65 BF +8D 45 55 BF 89 45 45 BF 85 45 75 B7 37 25 02 50 +13 05 05 C1 EF 90 2F 9E 01 B7 91 45 15 BD 95 45 +05 BD 99 45 35 B5 37 37 02 50 13 07 C7 39 34 43 +7C 43 D5 8F E3 82 07 C6 91 B3 37 25 02 50 13 05 +85 B5 EF 90 4F 9B 01 B5 89 47 63 E6 A7 04 03 D7 +09 00 85 47 E3 17 F7 EE 83 47 2A 00 37 07 03 30 +A2 07 93 E7 37 0B 23 26 F7 0C E1 BD 85 CF 89 47 +E3 F9 A7 EC 22 54 B2 50 92 54 02 59 F2 49 62 4A +D2 4A 42 4B B2 4B 22 4C 37 25 02 50 13 05 05 AC +45 61 6F 90 4F 96 37 25 02 50 13 05 45 BA EF 90 +8F 95 75 B7 09 E5 05 45 EF 90 EF 92 01 A0 37 25 +02 50 13 05 85 B0 EF 90 0F 94 F5 B7 85 45 49 BB +89 45 79 B3 8D 45 69 B3 79 71 22 D4 37 04 02 50 +03 28 04 14 26 D2 4A D0 52 CC 56 CA 5E C6 66 C2 +3A 8A 06 D6 4E CE 5A C8 62 C4 6A C0 09 47 03 4B +0A 00 83 49 2A 00 AA 8A AE 84 B2 8C B6 8B 3E 89 +63 63 07 2F B7 97 03 10 03 AC 47 01 13 7C 1C 00 +E3 0C 0C FE 89 47 63 E4 07 35 D6 87 37 B6 03 10 +93 8A 0A 62 1D 8E 94 43 33 07 F6 00 91 07 14 C3 +E3 9B 57 FF 83 CA 04 00 63 88 0A 10 83 C7 24 00 +37 C7 03 10 09 4D 86 07 93 F7 E7 03 93 E7 17 00 +1C C7 63 60 0D 39 B7 97 03 10 23 A0 07 08 23 A2 +07 08 23 A4 07 08 23 A6 07 08 23 A8 07 08 23 AA +07 08 23 AC 07 08 23 AE 07 08 B7 77 03 10 23 A0 +07 2A 23 A2 07 2A 23 A4 07 2A 23 A6 07 2A 23 A8 +07 2A 23 AA 07 2A 23 AC 07 2A 23 AE 07 2A 23 A0 +07 2C 37 C7 03 10 5C 47 89 8B F5 DF 83 C6 14 00 +85 47 63 88 F6 38 89 47 63 FA 07 01 37 25 02 50 +13 05 45 A3 EF 90 2F 83 03 28 04 14 B7 97 03 10 +03 AD 07 08 63 17 0D 38 03 A7 07 08 03 AD 47 08 +63 11 0D 38 03 A7 47 08 03 AD 87 08 63 1B 0D 36 +03 A7 87 08 03 AD C7 08 63 15 0D 36 03 A7 C7 08 +03 AD 07 09 63 1F 0D 34 03 A7 07 09 03 AD 47 09 +63 19 0D 34 03 A7 47 09 03 AD 87 09 63 13 0D 34 +03 A7 87 09 03 AD C7 09 63 1D 0D 32 83 A7 C7 09 +89 47 63 F8 07 05 37 25 02 50 13 05 05 A6 EF 80 +9F FB 03 28 04 14 35 A8 D8 40 B7 97 03 10 23 A0 +E7 08 98 44 23 A2 E7 08 D8 44 23 A4 E7 08 98 48 +23 A6 E7 08 D8 48 23 A8 E7 08 98 4C 23 AA E7 08 +D8 4C 23 AC E7 08 98 50 23 AE E7 08 89 47 E3 EC +07 FB 03 A7 0C 00 B7 07 03 10 98 CF 03 A7 4C 00 +D8 CF 03 A7 8C 00 98 D3 03 A7 CC 00 D8 D3 03 A7 +0C 01 98 D7 03 A7 4C 01 D8 D7 03 A7 8C 01 98 DB +03 A7 CC 01 D8 DB 03 A7 0C 02 98 DF 03 A7 4C 02 +D8 DF 03 A7 8C 02 B8 C3 03 A7 CC 02 F8 C3 03 A7 +0C 03 B8 C7 03 A7 4C 03 F8 C7 03 A7 8C 03 B8 CB +03 A7 CC 03 F8 CB 63 14 0B 0A 89 4C 63 EF 0C 0B +B7 97 03 10 23 A8 97 01 83 C7 24 00 63 9E 07 0E +B7 C7 03 10 0D 47 98 C7 37 37 02 50 13 07 C7 39 +34 43 7C 43 D5 8F 91 EF 73 00 50 10 93 07 40 06 +01 00 FD 17 C2 07 C1 83 E5 FF 3C 43 74 43 D5 8F +E5 D7 03 25 04 14 09 4C 63 6C AC 12 37 C6 03 10 +B7 55 FC EF 93 07 06 80 93 85 05 80 13 06 06 E2 +94 43 33 87 B7 00 5E 97 14 C3 91 07 E3 9A C7 FE +63 01 0B 0A 37 C7 03 10 5C 4B 89 8B F5 DF 83 46 +1A 00 85 47 63 8D F6 1E 5C 4B 93 F7 C7 3F 63 81 +07 1A 63 11 05 2A 05 45 EF 80 FF E4 01 A0 93 97 +19 00 11 67 13 07 17 FC 93 F7 F7 0F D9 8F 37 C7 +03 10 1C CB 89 4C E3 F5 0C F5 37 25 02 50 13 05 +05 C4 EF 80 5F E4 B7 97 03 10 03 27 04 14 23 A8 +97 01 83 C7 24 00 63 8B 07 14 B7 C7 03 10 23 A4 +87 01 89 47 63 FB E7 26 37 15 02 50 13 05 C5 65 +EF 80 7F E1 15 B7 37 25 02 50 13 05 45 90 EF 80 +9F E0 03 28 04 14 39 B3 B7 C7 03 10 05 47 98 C7 +21 B7 89 47 63 8A 0A 08 63 EC A7 1A B7 97 03 10 +A4 4F 63 9F 04 18 E4 4F 63 91 04 22 A4 53 63 9C +04 20 E4 53 63 97 04 20 A4 57 63 9C 04 20 E4 57 +63 97 04 20 A4 5B 63 98 04 20 E4 5B 9D 45 63 9A +04 16 B2 50 22 54 92 54 02 59 F2 49 62 4A D2 4A +42 4B B2 4B 22 4C 92 4C 02 4D 45 61 82 80 37 25 +02 50 13 05 85 92 EF 80 1F D9 03 28 04 14 75 B1 +6C 43 30 43 2D 65 13 05 C5 64 EF 80 DF D9 03 25 +04 14 E3 7D AC EA 37 25 02 50 13 05 05 C6 EF 80 +9F D6 03 25 04 14 5D B5 63 E5 A7 10 B7 97 03 10 +B8 4F 23 20 E9 00 F8 4F 23 22 E9 00 B8 53 23 24 +E9 00 F8 53 23 26 E9 00 B8 57 23 28 E9 00 F8 57 +23 2A E9 00 B8 5B 23 2C E9 00 FC 5B 23 2E F9 00 +8D BF 37 25 02 50 13 05 C5 94 EF 80 DF D1 B7 97 +03 10 03 28 04 14 23 A0 07 08 23 A2 07 08 23 A4 +07 08 23 A6 07 08 23 A8 07 08 23 AA 07 08 23 AC +07 08 23 AE 07 08 E3 7A 0D C7 37 25 02 50 13 05 +05 97 EF 80 5F CE 03 28 04 14 85 B1 0D 4C 75 B5 +89 47 63 E1 A7 0C 03 D7 04 00 85 47 E3 1B F7 F0 +93 97 89 00 93 E7 37 0B 37 07 03 30 23 26 F7 0C +09 B7 5C 47 93 F7 C7 3F D9 C3 89 47 E3 F0 07 C9 +37 25 02 50 13 05 C5 9A EF 80 FF C9 03 28 04 14 +99 B9 63 18 08 08 05 45 EF 80 FF C6 01 A0 5C 4B +93 F7 C7 3F BD C3 89 47 E3 F5 A7 EC 22 54 B2 50 +92 54 02 59 F2 49 62 4A D2 4A 42 4B B2 4B 22 4C +92 4C 02 4D 37 25 02 50 13 05 05 AC 45 61 6F 80 +9F C5 37 25 02 50 13 05 C5 CC EF 80 DF C4 FD B5 +81 45 83 27 04 14 F1 E3 05 45 EF 80 DF C1 01 A0 +37 25 02 50 13 05 05 C1 EF 80 FF C2 81 B5 63 1F +08 08 05 45 EF 80 3F C0 01 A0 51 E1 05 45 EF 80 +9F BF 01 A0 37 25 02 50 13 05 45 BA EF 80 BF C0 +1D BF AD 64 93 84 C4 64 81 45 13 85 44 3A EF 80 +9F C1 83 27 04 14 A5 D3 EA 85 13 85 04 3D EF 80 +9F C0 83 27 04 14 A1 DB 81 45 13 85 84 3E EF 80 +9F BF 91 B7 37 25 02 50 13 05 05 C8 EF 80 BF BC +99 BB 8D 45 BD BF 89 45 AD BF 85 45 9D BF 95 45 +8D BF 91 45 BD B7 99 45 AD B7 37 37 02 50 13 07 +C7 39 3C 43 74 43 D5 8F E3 80 07 CC 1D BD 37 25 +02 50 13 05 85 B0 EF 80 1F B9 8D BF 37 25 02 50 +13 05 C5 9E EF 80 3F B8 A9 BF 2D 69 13 09 C9 64 +13 05 09 40 EF 80 3F B9 83 27 04 14 E3 86 07 F2 +A6 85 13 05 49 43 EF 80 1F B8 83 27 04 14 E3 8D +07 F0 81 45 13 05 C9 44 EF 80 FF B6 31 B7 01 11 +22 CC 37 04 02 50 03 28 04 14 26 CA 4E C6 52 C4 +56 C2 06 CE 4A C8 89 47 03 C9 06 00 B6 84 AA 8A +2E 8A B2 89 63 E4 07 23 37 97 03 10 5C 4B 85 8B +F5 DF 89 47 63 E3 07 27 05 67 13 07 07 C6 B7 A5 +03 10 D6 87 33 86 EA 00 B3 85 55 41 94 43 33 87 +F5 00 91 07 14 C3 E3 9B C7 FE 37 C6 03 10 13 06 +06 80 D2 87 93 05 0A 62 33 06 46 41 94 43 33 07 +F6 00 91 07 14 C3 E3 9B B7 FE 89 47 63 E6 07 21 +03 A7 09 00 B7 07 03 10 98 CF 03 A7 49 00 D8 CF +03 A7 89 00 98 D3 03 A7 C9 00 D8 D3 03 A7 09 01 +98 D7 03 A7 49 01 D8 D7 03 A7 89 01 98 DB 03 A7 +C9 01 D8 DB 03 A7 09 02 98 DF 03 A7 49 02 D8 DF +03 A7 89 02 B8 C3 03 A7 C9 02 F8 C3 03 A7 09 03 +B8 C7 03 A7 49 03 F8 C7 03 A7 89 03 B8 CB 03 A7 +C9 03 F8 CB 63 0E 09 00 83 C7 24 00 11 67 13 07 +17 FC 86 07 93 F7 F7 0F D9 8F 37 C7 03 10 1C CB +89 49 63 EE 09 15 B7 97 03 10 0D 47 98 CB 37 37 +02 50 13 07 C7 39 34 43 7C 43 D5 8F 91 EF 73 00 +50 10 93 07 40 06 01 00 FD 17 C2 07 C1 83 E5 FF +3C 43 74 43 D5 8F E5 D7 83 26 04 14 89 49 63 E8 +D9 06 63 09 09 08 37 C7 03 10 5C 4B 89 8B F5 DF +03 C6 14 00 85 47 63 03 F6 16 5C 4B 93 F7 C7 3F +63 96 07 14 89 47 63 E9 D7 1A B7 97 03 10 A4 4F +63 90 04 20 E4 4F 63 96 04 26 A4 53 63 91 04 26 +E4 53 63 9C 04 24 A4 57 63 97 04 24 E4 57 63 92 +04 24 A4 5B 63 9D 04 22 E4 5B 9D 45 D9 CC 83 27 +04 14 63 9C 07 1E 05 45 EF 80 FF 97 01 A0 6C 43 +30 43 2D 65 13 05 C5 64 EF 80 FF 9A 63 1D 09 0E +83 27 04 14 63 F8 F9 00 37 25 02 50 13 05 45 ED +EF 80 7F 97 B7 97 03 10 83 A9 87 05 03 A9 44 00 +63 9C 29 0F 83 A9 C7 05 03 A9 84 00 63 9C 29 19 +83 A9 07 06 03 A9 C4 00 63 9E 29 17 83 A9 47 06 +03 A9 04 01 63 9A 29 17 83 A9 87 06 03 A9 44 01 +63 96 29 17 83 A9 C7 06 03 A9 84 01 63 92 29 17 +83 A9 07 07 03 A9 C4 01 63 90 29 17 83 A9 47 07 +03 A9 04 02 9D 45 63 12 39 0B F2 40 62 44 D2 44 +42 49 B2 49 22 4A 92 4A 05 61 82 80 37 25 02 50 +13 05 C5 CE EF 80 3F 8F 03 28 04 14 F1 B3 37 25 +02 50 13 05 45 D5 EF 80 1F 8E 83 27 04 14 37 97 +03 10 8D 46 14 CB 63 FF F9 0C 37 15 02 50 13 05 +C5 65 EF 80 5F 8C 61 B5 37 25 02 50 13 05 45 D3 +EF 80 7F 8B 03 28 04 14 E5 B3 37 25 02 50 13 05 +05 D1 EF 80 5F 8A 03 28 04 14 79 B3 C9 EE 05 45 +EF 80 7F 87 01 A0 83 26 04 14 71 B5 5C 4B 93 F7 +C7 3F AD CF 89 47 E3 F2 D7 EA 37 25 02 50 13 05 +45 D7 EF 80 5F 87 B9 A0 81 45 83 27 04 14 89 E7 +05 45 EF 80 5F 84 01 A0 AD 64 93 84 C4 64 13 85 +84 4C EF 80 5F 87 83 27 04 14 FD D3 CE 85 13 85 +C4 4F EF 80 5F 86 83 27 04 14 F9 DB CA 85 13 85 +44 51 EF 80 5F 85 E9 B7 37 25 02 50 13 05 85 E5 +EF 80 7F 82 03 27 04 14 89 47 E3 F0 E7 E4 37 25 +02 50 13 05 45 EA EF 80 1F 81 05 BD A1 EA 05 45 +EF 80 6F FE 01 A0 37 25 02 50 13 05 C5 E0 EF 80 +8F FF B1 BF 37 37 02 50 13 07 C7 39 34 43 7C 43 +D5 8F E3 8E 07 DA 83 26 04 14 E3 1E 09 DC 9D B5 +81 45 35 B5 89 45 95 B7 8D 45 85 B7 91 45 B1 BF +95 45 A1 BF 85 45 91 BF 99 45 81 BF 37 25 02 50 +13 05 C5 DB EF 80 2F FB 5D B7 2D 69 13 09 C9 64 +13 05 49 46 EF 80 2F FC 83 27 04 14 E3 8D 07 DE +A6 85 13 05 89 49 EF 80 0F FB 83 27 04 14 E3 84 +07 DE 81 45 13 05 09 4B EF 80 EF F9 E9 BB 99 45 +F9 B3 95 45 E9 B3 91 45 D9 B3 8D 45 C9 B3 89 45 +7D BB 85 45 6D BB 01 11 22 CC 37 04 02 50 03 28 +04 14 26 CA 4E C6 52 C4 56 C2 06 CE 4A C8 89 47 +03 C9 06 00 B6 84 AA 8A 2E 8A B2 89 63 E8 07 1B +37 97 03 10 5C 4B 85 8B F5 DF 89 47 63 E9 07 1B +05 67 13 07 07 C6 B7 A5 03 10 D6 87 33 86 EA 00 +B3 85 55 41 94 43 33 87 F5 00 91 07 14 C3 E3 9B +C7 FE 37 C6 03 10 13 06 06 80 D2 87 93 05 0A 62 +33 06 46 41 94 43 33 07 F6 00 91 07 14 C3 E3 9B +B7 FE 89 47 63 E3 07 1B 03 A7 09 00 B7 07 03 10 +98 CF 03 A7 49 00 D8 CF 03 A7 89 00 98 D3 03 A7 +C9 00 D8 D3 03 A7 09 01 98 D7 03 A7 49 01 D8 D7 +03 A7 89 01 98 DB 03 A7 C9 01 D8 DB 03 A7 09 02 +98 DF 03 A7 49 02 D8 DF 03 A7 89 02 B8 C3 03 A7 +C9 02 F8 C3 03 A7 09 03 B8 C7 03 A7 49 03 F8 C7 +03 A7 89 03 B8 CB 03 A7 C9 03 F8 CB 63 0E 09 00 +83 C7 24 00 11 67 13 07 17 FC 86 07 93 F7 F7 0F +D9 8F 37 C7 03 10 1C CB 89 49 63 EB 09 0F B7 97 +03 10 0D 47 98 CB 37 37 02 50 13 07 C7 39 34 43 +7C 43 D5 8F 91 EF 73 00 50 10 93 07 40 06 01 00 +FD 17 C2 07 C1 83 E5 FF 3C 43 74 43 D5 8F E5 D7 +83 26 04 14 89 49 63 E3 D9 04 63 04 09 06 37 C7 +03 10 5C 4B 89 8B F5 DF 03 C6 14 00 85 47 63 07 +F6 0E 5C 4B 93 F7 C7 3F E9 EF 89 47 63 FF D7 04 +37 25 02 50 13 05 85 E5 62 44 F2 40 D2 44 42 49 +B2 49 22 4A 92 4A 05 61 6F 80 EF DD 6C 43 30 43 +2D 65 13 05 C5 64 EF 80 0F DF 63 11 09 0A 83 27 +04 14 63 F8 F9 00 37 25 02 50 13 05 85 F8 EF 80 +8F DB 37 97 03 10 34 4F 93 07 C7 05 78 4F D8 43 +98 47 D8 47 98 4B D8 4B 9C 4F F2 40 62 44 D2 44 +42 49 B2 49 22 4A 92 4A 05 61 82 80 37 25 02 50 +13 05 C5 CE EF 80 2F D8 03 28 04 14 91 B5 37 25 +02 50 13 05 05 D1 EF 80 0F D7 03 28 04 14 89 B5 +37 25 02 50 13 05 45 D5 EF 80 EF D5 83 27 04 14 +37 97 03 10 8D 46 14 CB 63 FD F9 04 37 15 02 50 +13 05 C5 65 EF 80 2F D4 FD B5 37 25 02 50 13 05 +45 D3 EF 80 4F D3 03 28 04 14 B9 B5 83 26 04 14 +39 B7 8D E2 05 45 EF 80 0F D0 01 A0 5C 4B 93 F7 +C7 3F 95 CF 89 47 E3 FA D7 F6 37 25 02 50 13 05 +45 EF 19 BF 37 25 02 50 13 05 C5 E0 EF 80 AF CF +D1 BF 37 37 02 50 13 07 C7 39 34 43 7C 43 D5 8F +E3 83 07 EA 83 26 04 14 E3 13 09 EC 1D B7 89 E6 +05 45 EF 80 4F CB 01 A0 37 25 02 50 13 05 C5 F3 +EF 80 6F CC F5 B7 79 71 4A D0 37 09 02 50 03 28 +09 14 4E CE 5E C6 62 C4 66 C2 06 D6 22 D4 26 D2 +52 CC 56 CA 5A C8 6A C0 89 47 03 CB 06 00 03 CA +26 00 B6 89 2A 8C AE 8B B2 8C 63 EE 07 2B B7 94 +03 10 C0 48 05 88 75 DC 83 4A 0C 00 63 8C 0A 08 +83 47 2C 00 37 C7 03 10 09 4D 86 07 93 F7 E7 03 +93 E7 17 00 1C C3 63 6C 0D 39 23 AC 04 00 23 AE +04 00 23 A0 04 02 23 A2 04 02 23 A4 04 02 23 A6 +04 02 23 A8 04 02 23 AA 04 02 B7 97 03 10 23 AC +07 02 23 AE 07 02 23 A0 07 04 23 A2 07 04 23 A4 +07 04 23 A6 07 04 23 A8 07 04 23 AA 07 04 37 C7 +03 10 5C 43 89 8B F5 DF 83 46 1C 00 85 47 63 93 +F6 08 5C 43 93 F7 C7 3F 63 88 07 3A 89 47 63 FB +07 07 37 15 02 50 13 05 05 73 EF 80 CF BE 03 28 +09 14 8D A0 83 27 4C 00 9C CC 83 27 8C 00 DC CC +83 27 CC 00 9C D0 83 27 0C 01 DC D0 83 27 4C 01 +9C D4 83 27 8C 01 DC D4 83 27 CC 01 9C D8 83 27 +0C 02 DC D8 83 27 4C 02 9C DC 83 27 8C 02 DC DC +83 27 CC 02 BC C0 83 27 0C 03 FC C0 83 27 4C 03 +BC C4 83 27 8C 03 FC C4 83 27 CC 03 BC C8 83 27 +0C 04 FC C8 37 C6 03 10 DE 87 13 06 06 80 93 8B +0B 62 1D 8E 94 43 33 07 F6 00 91 07 14 C3 E3 9B +77 FF 89 47 63 EC 07 27 03 A7 0C 00 B7 07 03 10 +98 CF 03 A7 4C 00 D8 CF 03 A7 8C 00 98 D3 03 A7 +CC 00 D8 D3 03 A7 0C 01 98 D7 03 A7 4C 01 D8 D7 +03 A7 8C 01 98 DB 03 A7 CC 01 D8 DB 03 A7 0C 02 +98 DF 03 A7 4C 02 D8 DF 03 A7 8C 02 B8 C3 03 A7 +CC 02 F8 C3 03 A7 0C 03 B8 C7 03 A7 4C 03 F8 C7 +03 A7 8C 03 B8 CB 03 A7 CC 03 F8 CB 63 12 0B 0C +89 47 63 ED 07 0D B7 97 03 10 11 47 98 CB 83 47 +2C 00 63 89 07 14 B7 C7 03 10 05 47 98 C3 37 37 +02 50 13 07 C7 39 34 43 7C 43 D5 8F 9D E3 73 00 +50 10 93 07 40 06 01 00 FD 17 C2 07 C1 83 E5 FF +3C 43 74 43 D5 8F E5 D7 03 28 09 14 09 44 63 65 +04 0F 63 1E 0B 10 63 93 0A 16 B7 97 03 10 A4 4F +03 A4 49 00 63 1C 94 32 E4 4F 03 A4 89 00 63 1F +94 30 A4 53 03 A4 C9 00 63 1C 94 30 E4 53 03 A4 +09 01 63 99 84 26 A4 57 03 A4 49 01 63 92 84 26 +E4 57 03 A4 89 01 63 9B 84 24 A4 5B 03 A4 C9 01 +63 9E 84 24 E4 5B 03 A4 09 02 9D 45 63 02 94 14 +83 27 09 14 63 94 07 26 05 45 EF 80 CF A1 01 A0 +93 17 1A 00 11 67 13 07 17 FC 93 F7 F7 0F D9 8F +37 C7 03 10 1C CB 89 47 E3 F7 07 F3 37 25 02 50 +13 05 85 05 EF 80 2F A1 B7 97 03 10 11 47 03 28 +09 14 98 CB 83 47 2C 00 63 83 07 12 B7 C7 03 10 +80 C3 89 47 E3 FD 07 F1 37 15 02 50 13 05 C5 65 +EF 80 6F 9E 37 37 02 50 13 07 C7 39 3C 43 74 43 +D5 8F 91 D7 15 B7 37 25 02 50 13 05 85 FA EF 80 +8F 9C 03 28 09 14 25 BB 6C 43 30 43 2D 65 13 05 +C5 64 EF 80 4F 9D 03 28 09 14 63 12 0B 02 63 9F +0A 04 E3 74 04 F1 37 25 02 50 13 05 C5 1C EF 80 +8F 99 E5 BD B7 C7 03 10 0D 47 98 C3 4D BD 37 C7 +03 10 5C 4B 89 8B F5 DF 83 C6 19 00 85 47 63 8B +F6 0E 5C 4B 93 F7 C7 3F C9 EF 89 47 63 E2 07 15 +03 57 0C 00 85 47 63 1D F7 04 93 17 8A 00 93 E7 +37 0B 37 07 03 30 23 26 F7 0C 99 A0 63 78 04 01 +37 25 02 50 13 05 45 1F EF 80 EF 93 B7 97 03 10 +A0 4F 63 19 04 0E E0 4F 63 16 04 1C A0 53 63 15 +04 1C E0 53 63 1A 04 1A A0 57 63 15 04 1A E0 57 +63 10 04 1A A0 5B 63 19 04 10 E0 5B 9D 45 61 E4 +B2 50 22 54 92 54 02 59 F2 49 62 4A D2 4A 42 4B +B2 4B 22 4C 92 4C 02 4D 45 61 82 80 37 25 02 50 +13 05 05 03 EF 80 2F 8E 03 28 09 14 B5 BB 0D 44 +F1 BD 63 1E 08 0A 05 45 EF 80 EF 8A 01 A0 37 25 +02 50 13 05 05 FD EF 80 0F 8C 03 28 09 14 23 AC +04 00 23 AE 04 00 23 A0 04 02 23 A2 04 02 23 A4 +04 02 23 A6 04 02 23 A8 04 02 23 AA 04 02 E3 7E +0D C5 37 25 02 50 13 05 05 00 EF 80 CF 88 03 28 +09 14 A1 B1 5C 4B 93 F7 C7 3F A9 C7 89 47 E3 F9 +07 F7 22 54 B2 50 92 54 02 59 F2 49 62 4A D2 4A +42 4B B2 4B 22 4C 92 4C 02 4D 37 25 02 50 13 05 +05 08 45 61 6F 80 2F 85 63 1C 08 04 05 45 EF 80 +8F 82 01 A0 81 45 83 27 09 14 D9 EB 05 45 EF 80 +8F 81 01 A0 63 15 08 04 05 45 EF 80 CF 80 01 A0 +37 25 02 50 13 05 85 17 EF 80 EF 81 55 BD 37 25 +02 50 13 05 45 12 EF 80 0F 81 35 BF 95 45 C9 B3 +91 45 7D BB 8D 45 6D BB 99 45 75 BF 99 45 4D BB +37 15 02 50 13 05 45 77 EF 70 FF FE 45 B7 37 25 +02 50 13 05 05 0D EF 70 1F FE 7D B7 AD 69 93 89 +C9 64 13 85 C9 52 EF 70 1F FF 83 27 09 14 E3 85 +07 D8 A6 85 13 85 09 56 EF 70 FF FD 83 27 09 14 +E3 8C 07 D6 A2 85 13 85 89 57 EF 70 DF FC AD B3 +AD 64 93 84 C4 64 13 85 04 59 EF 70 DF FB 83 27 +09 14 A9 DF A2 85 13 85 44 5C EF 70 DF FA 83 27 +09 14 A9 D7 81 45 13 85 C4 5D EF 70 DF F9 3D BF +95 45 15 BF 91 45 05 BF 8D 45 35 B7 85 45 0D B3 +89 45 39 BB 85 45 05 B7 89 45 31 BF 81 45 09 BB +79 71 26 D2 B7 04 02 50 03 A8 04 14 4E CE 5A C8 +5E C6 62 C4 06 D6 22 D4 4A D0 52 CC 56 CA 66 C2 +89 47 03 CA 06 00 03 C9 26 00 B6 89 2A 8B AE 8B +32 8C 63 ED 07 29 37 94 03 10 5C 48 85 8B F5 DF +83 4A 0B 00 63 8C 0A 08 83 47 2B 00 37 C7 03 10 +89 4C 86 07 93 F7 E7 03 93 E7 17 00 1C C3 63 E1 +0C 35 23 2C 04 00 23 2E 04 00 23 20 04 02 23 22 +04 02 23 24 04 02 23 26 04 02 23 28 04 02 23 2A +04 02 B7 97 03 10 23 AC 07 02 23 AE 07 02 23 A0 +07 04 23 A2 07 04 23 A4 07 04 23 A6 07 04 23 A8 +07 04 23 AA 07 04 37 C7 03 10 5C 43 89 8B F5 DF +83 46 1B 00 85 47 63 93 F6 08 5C 43 93 F7 C7 3F +63 8C 07 34 89 47 63 FB 07 07 37 15 02 50 13 05 +05 73 EF 70 5F E8 03 A8 04 14 8D A0 83 27 4B 00 +1C CC 83 27 8B 00 5C CC 83 27 CB 00 1C D0 83 27 +0B 01 5C D0 83 27 4B 01 1C D4 83 27 8B 01 5C D4 +83 27 CB 01 1C D8 83 27 0B 02 5C D8 83 27 4B 02 +1C DC 83 27 8B 02 5C DC 83 27 CB 02 3C C0 83 27 +0B 03 7C C0 83 27 4B 03 3C C4 83 27 8B 03 7C C4 +83 27 CB 03 3C C8 83 27 0B 04 7C C8 37 C6 03 10 +DE 87 13 06 06 80 93 8B 0B 62 1D 8E 94 43 33 07 +F6 00 91 07 14 C3 E3 9B FB FE 89 47 63 E3 07 23 +03 27 0C 00 B7 07 03 10 98 CF 03 27 4C 00 D8 CF +03 27 8C 00 98 D3 03 27 CC 00 D8 D3 03 27 0C 01 +98 D7 03 27 4C 01 D8 D7 03 27 8C 01 98 DB 03 27 +CC 01 D8 DB 03 27 0C 02 98 DF 03 27 4C 02 D8 DF +03 27 8C 02 B8 C3 03 27 CC 02 F8 C3 03 27 0C 03 +B8 C7 03 27 4C 03 F8 C7 03 27 8C 03 B8 CB 03 27 +CC 03 F8 CB 63 1F 0A 08 09 44 63 6A 04 0B B7 97 +03 10 11 47 98 CB 83 47 2B 00 37 C7 03 10 86 07 +93 F7 E7 03 93 E7 17 00 1C C3 37 37 02 50 13 07 +C7 39 3C 43 74 43 D5 8F 9D E3 73 00 50 10 93 07 +40 06 01 00 FD 17 C2 07 C1 83 E5 FF 3C 43 74 43 +D5 8F E5 D7 03 A8 04 14 09 44 63 66 04 11 63 00 +0A 0C 37 C7 03 10 5C 4B 89 8B F5 DF 83 C6 19 00 +85 47 63 8A F6 1A 5C 4B 93 F7 C7 3F 63 9C 07 14 +89 47 63 E7 07 21 03 57 0B 00 85 47 63 1E F7 10 +93 17 89 00 93 E7 37 0B 37 07 03 30 23 26 F7 0C +21 A2 93 17 19 00 11 67 13 07 17 FC 93 F7 F7 0F +D9 8F 37 C7 03 10 1C CB 09 44 E3 7A 04 F5 37 25 +02 50 13 05 85 05 EF 70 1F CD B7 97 03 10 11 47 +03 A8 04 14 98 CB 83 47 2B 00 37 C7 03 10 86 07 +93 F7 E7 03 93 E7 17 00 1C C3 E3 70 04 F5 37 15 +02 50 13 05 C5 65 EF 70 1F CA 37 37 02 50 13 07 +C7 39 34 43 7C 43 D5 8F 8D DB A9 B7 37 25 02 50 +13 05 85 FA EF 70 3F C8 03 A8 04 14 A9 BB 63 89 +0A 06 B7 97 03 10 A0 4F 63 11 04 18 E0 4F 63 19 +04 18 A0 53 63 18 04 18 E0 53 63 16 04 16 A0 57 +63 11 04 16 E0 57 63 1C 04 14 A0 5B 63 11 04 16 +E0 5B 9D 45 31 C8 83 A7 04 14 63 97 07 16 05 45 +EF 70 7F C1 01 A0 6C 43 30 43 2D 65 13 05 C5 64 +EF 70 7F C4 03 A8 04 14 E3 15 0A EE 63 94 0A 0E +63 78 04 01 37 25 02 50 13 05 C5 22 EF 70 BF C0 +37 97 03 10 34 4F 93 07 C7 05 78 4F D8 43 98 47 +D8 47 98 4B D8 4B 9C 4F B2 50 22 54 92 54 02 59 +F2 49 62 4A D2 4A 42 4B B2 4B 22 4C 92 4C 45 61 +82 80 37 25 02 50 13 05 05 03 EF 70 DF BC 03 A8 +04 14 F9 B3 63 17 08 0A 05 45 EF 70 DF B9 01 A0 +37 25 02 50 13 05 05 FD EF 70 FF BA 03 A8 04 14 +23 2C 04 00 23 2E 04 00 23 20 04 02 23 22 04 02 +23 24 04 02 23 26 04 02 23 28 04 02 23 2A 04 02 +E3 F9 0C CB 37 25 02 50 13 05 05 00 EF 70 BF B7 +03 A8 04 14 79 B9 5C 4B 93 F7 C7 3F A9 C7 89 47 +E3 FC 07 F7 22 54 B2 50 92 54 02 59 F2 49 62 4A +D2 4A 42 4B B2 4B 22 4C 92 4C 37 25 02 50 13 05 +05 08 45 61 6F 70 3F B4 63 1D 08 04 05 45 EF 70 +9F B1 01 A0 E3 7F 04 EB 37 25 02 50 13 05 45 1F +EF 70 7F B2 7D B5 63 13 08 08 05 45 EF 70 BF AF +01 A0 37 25 02 50 13 05 45 12 EF 70 DF B0 A9 B7 +37 25 02 50 13 05 85 17 EF 70 FF AF ED B3 95 45 +5D BD 91 45 4D BD 8D 45 7D B5 81 45 6D B5 99 45 +5D B5 37 15 02 50 13 05 45 77 EF 70 DF AD 79 BF +85 45 51 BD 89 45 41 BD 2D 69 13 09 C9 64 13 05 +49 5F EF 70 5F AE 83 A7 04 14 E3 82 07 E8 A2 85 +13 05 89 62 EF 70 3F AD 83 A7 04 14 E3 89 07 E6 +81 45 13 05 09 64 EF 70 1F AC 95 B5 37 25 02 50 +13 05 05 0D EF 70 3F A9 8D BF 01 00 52 65 63 65 +69 76 65 64 20 4D 4C 4B 45 4D 20 6E 6F 74 69 66 +2F 20 65 72 72 20 69 6E 74 72 20 77 69 74 68 20 +73 74 61 74 75 73 20 3D 20 25 64 2F 20 25 64 0A +00 00 00 00 41 74 20 6F 66 66 73 65 74 20 5B 25 +64 5D 2C 20 6D 6C 6B 65 6D 5F 65 6E 63 61 70 73 +5F 6B 65 79 20 64 61 74 61 20 6D 69 73 6D 61 74 +63 68 21 0A 00 00 00 00 41 63 74 75 61 6C 20 20 +20 64 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +45 78 70 65 63 74 65 64 20 64 61 74 61 3A 20 30 +78 25 78 0A 00 00 00 00 41 74 20 6F 66 66 73 65 +74 20 5B 25 64 5D 2C 20 6D 6C 6B 65 6D 5F 64 65 +63 61 70 73 5F 6B 65 79 20 64 61 74 61 20 6D 69 +73 6D 61 74 63 68 21 0A 00 00 00 00 41 63 74 75 +61 6C 20 20 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 45 78 70 65 63 74 65 64 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 41 74 20 6F +66 66 73 65 74 20 5B 25 64 5D 2C 20 6D 6C 6B 65 +6D 5F 73 65 65 64 5F 64 20 64 61 74 61 20 6D 69 +73 6D 61 74 63 68 21 0A 00 00 00 00 41 63 74 75 +61 6C 20 20 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 45 78 70 65 63 74 65 64 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 41 74 20 6F +66 66 73 65 74 20 5B 25 64 5D 2C 20 6D 6C 6B 65 +6D 5F 73 65 65 64 5F 7A 20 64 61 74 61 20 6D 69 +73 6D 61 74 63 68 21 0A 00 00 00 00 41 63 74 75 +61 6C 20 20 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 45 78 70 65 63 74 65 64 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 41 74 20 6F +66 66 73 65 74 20 5B 25 64 5D 2C 20 6D 6C 6B 65 +6D 5F 64 6B 20 64 61 74 61 20 6D 69 73 6D 61 74 +63 68 21 0A 00 00 00 00 41 63 74 75 61 6C 20 20 +20 64 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +45 78 70 65 63 74 65 64 20 64 61 74 61 3A 20 30 +78 25 78 0A 00 00 00 00 41 74 20 6F 66 66 73 65 +74 20 5B 25 64 5D 2C 20 6D 6C 6B 65 6D 5F 6D 73 +67 20 64 61 74 61 20 6D 69 73 6D 61 74 63 68 21 +0A 00 00 00 41 63 74 75 61 6C 20 20 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 45 78 70 65 +63 74 65 64 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 41 74 20 6F 66 66 73 65 74 20 5B 25 +64 5D 2C 20 6D 6C 6B 65 6D 5F 63 69 70 68 65 72 +74 65 78 74 20 64 61 74 61 20 6D 69 73 6D 61 74 +63 68 21 0A 00 00 00 00 41 63 74 75 61 6C 20 20 +20 64 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +45 78 70 65 63 74 65 64 20 64 61 74 61 3A 20 30 +78 25 78 0A 00 00 00 00 41 74 20 6F 66 66 73 65 +74 20 5B 25 64 5D 2C 20 6D 6C 6B 65 6D 5F 73 68 +61 72 65 64 5F 6B 65 79 20 64 61 74 61 20 6D 69 +73 6D 61 74 63 68 21 0A 00 00 00 00 41 63 74 75 +61 6C 20 20 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 45 78 70 65 63 74 65 64 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 41 74 20 6F +66 66 73 65 74 20 5B 25 64 5D 2C 20 6D 6C 6B 65 +6D 5F 73 68 61 72 65 64 5F 6B 65 79 20 64 61 74 +61 20 6D 69 73 6D 61 74 63 68 21 0A 00 00 00 00 +41 63 74 75 61 6C 20 20 20 64 61 74 61 3A 20 30 +78 25 78 0A 00 00 00 00 45 78 70 65 63 74 65 64 +20 64 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +41 74 20 6F 66 66 73 65 74 20 5B 25 64 5D 2C 20 +6D 6C 6B 65 6D 5F 6D 73 67 20 64 61 74 61 20 6D +69 73 6D 61 74 63 68 21 0A 00 00 00 41 63 74 75 +61 6C 20 20 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 45 78 70 65 63 74 65 64 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 41 74 20 6F +66 66 73 65 74 20 5B 25 64 5D 2C 20 6D 6C 6B 65 +6D 5F 73 68 61 72 65 64 5F 6B 65 79 20 64 61 74 +61 20 6D 69 73 6D 61 74 63 68 21 0A 00 00 00 00 +41 63 74 75 61 6C 20 20 20 64 61 74 61 3A 20 30 +78 25 78 0A 00 00 00 00 45 78 70 65 63 74 65 64 +20 64 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +41 74 20 6F 66 66 73 65 74 20 5B 25 64 5D 2C 20 +6D 6C 6B 65 6D 5F 73 68 61 72 65 64 5F 6B 65 79 +20 64 61 74 61 20 6D 69 73 6D 61 74 63 68 21 0A +00 00 00 00 41 63 74 75 61 6C 20 20 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 45 78 70 65 +63 74 65 64 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 41 74 20 6F 66 66 73 65 74 20 5B 25 +64 5D 2C 20 6D 6C 6B 65 6D 5F 73 68 61 72 65 64 +5F 6B 65 79 20 64 61 74 61 20 6D 69 73 6D 61 74 +63 68 21 0A 00 00 00 00 41 63 74 75 61 6C 20 20 +20 64 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +45 78 70 65 63 74 65 64 20 64 61 74 61 3A 20 30 +78 25 78 0A 00 00 00 00 41 74 20 6F 66 66 73 65 +74 20 5B 25 64 5D 2C 20 6D 6C 6B 65 6D 5F 73 68 +61 72 65 64 5F 6B 65 79 20 64 61 74 61 20 6D 69 +73 6D 61 74 63 68 21 0A 00 00 00 00 41 63 74 75 +61 6C 20 20 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 45 78 70 65 63 74 65 64 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 41 74 20 6F +66 66 73 65 74 20 5B 25 64 5D 2C 20 6D 6C 6B 65 +6D 5F 73 68 61 72 65 64 5F 6B 65 79 20 64 61 74 +61 20 6D 69 73 6D 61 74 63 68 21 0A 00 00 00 00 +41 63 74 75 61 6C 20 20 20 64 61 74 61 3A 20 30 +78 25 78 0A 00 00 00 00 45 78 70 65 63 74 65 64 +20 64 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +41 74 20 6F 66 66 73 65 74 20 5B 25 64 5D 2C 20 +6D 6C 6B 65 6D 5F 73 68 61 72 65 64 5F 6B 65 79 +20 64 61 74 61 20 6D 69 73 6D 61 74 63 68 21 0A +00 00 00 00 41 63 74 75 61 6C 20 20 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 45 78 70 65 +63 74 65 64 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 41 11 22 C4 37 04 02 50 03 27 04 14 +06 C6 89 47 63 E0 E7 04 37 37 02 50 13 07 C7 39 +1C 4B 54 4B D5 8F 9D E3 73 00 50 10 93 07 40 06 +01 00 FD 17 C2 07 C1 83 E5 FF 1C 4B 54 4B D5 8F +E5 D7 83 26 04 14 89 47 63 E5 D7 02 B2 40 22 44 +41 01 82 80 37 25 02 50 13 05 45 25 EF 70 AF BD +37 37 02 50 13 07 C7 39 1C 4B 54 4B D5 8F CD DF +C9 BF 22 44 4C 4B B2 40 10 4B 35 65 13 05 45 EB +41 01 6F 70 4F BD B7 07 02 50 03 A7 07 14 89 47 +63 E7 E7 00 B7 07 01 10 11 47 98 CB 82 80 37 25 +02 50 41 11 13 05 05 27 06 C6 EF 70 CF B8 B2 40 +B7 07 01 10 11 47 98 CB 41 01 82 80 19 CA 0A 06 +33 87 C5 00 9C 41 91 05 11 05 23 2E F5 FE E3 9B +E5 FE 82 80 39 71 5A D0 62 CC 66 CA 6A C8 6E C6 +06 DE 22 DC 26 DA 4A D8 4E D6 52 D4 56 D2 5E CE +03 49 15 00 83 4B 25 00 03 CA 15 00 83 C9 25 00 +83 CA 06 00 AA 8D 2E 8C B6 8C 32 8D 3A 8B B7 07 +01 10 80 4F 05 88 75 DC 03 C7 0D 00 B7 04 02 50 +03 A5 04 14 45 C3 13 97 1B 00 13 77 E7 03 13 67 +17 00 23 A0 E7 60 89 47 63 ED A7 30 B7 07 01 10 +23 A0 07 04 23 A2 07 04 23 A4 07 04 23 A6 07 04 +23 A8 07 04 23 AA 07 04 23 AC 07 04 23 AE 07 04 +23 A0 07 06 23 A2 07 06 23 A4 07 06 23 A6 07 06 +37 07 01 10 83 27 47 60 89 8B ED DF 85 47 63 1C +F9 08 83 27 47 60 93 F7 C7 3F 63 80 07 32 89 47 +63 ED A7 3A 83 47 0C 00 63 96 07 36 37 06 01 10 +B7 05 FF EF 93 07 06 08 93 85 05 F8 13 06 06 10 +BE 86 91 07 33 87 B7 00 62 97 18 43 98 C2 E3 99 +C7 FE 75 A0 89 47 63 EF A7 28 03 A7 4D 00 B7 07 +01 10 B8 C3 03 A7 8D 00 F8 C3 03 A7 CD 00 B8 C7 +03 A7 0D 01 F8 C7 03 A7 4D 01 B8 CB 03 A7 8D 01 +F8 CB 03 A7 CD 01 B8 CF 03 A7 0D 02 F8 CF 03 A7 +4D 02 B8 D3 03 A7 8D 02 F8 D3 03 A7 CD 02 B8 D7 +03 A7 0D 03 F8 D7 83 47 0C 00 C9 D3 93 97 19 00 +93 F7 E7 03 93 E7 17 00 37 07 01 10 23 24 F7 60 +89 47 63 FA A7 00 37 25 02 50 13 05 45 36 EF 70 +8F 9F 03 A5 04 14 B7 06 01 10 93 87 06 08 93 86 +06 10 23 A0 07 00 91 07 E3 9D D7 FE 37 07 01 10 +83 27 C7 60 89 8B ED DF 85 47 63 0F FA 20 03 27 +4D 00 B7 07 01 10 23 A0 E7 14 03 27 8D 00 23 A2 +E7 14 03 27 CD 00 23 A4 E7 14 03 27 0D 01 23 A6 +E7 14 03 27 4D 01 23 A8 E7 14 03 27 8D 01 23 AA +E7 14 03 27 CD 01 23 AC E7 14 03 27 0D 02 23 AE +E7 14 03 27 4D 02 23 A0 E7 16 03 27 8D 02 23 A2 +E7 16 03 27 CD 02 23 A4 E7 16 03 27 0D 03 23 A6 +E7 16 63 8D 0A 00 03 C7 2C 00 85 66 93 86 16 FC +06 07 13 77 F7 0F 55 8F 23 A8 E7 60 B7 07 01 10 +63 0E 0B 12 05 47 98 CB A2 87 63 93 0B 00 8D 47 +37 07 01 10 23 20 F7 60 63 93 09 00 0D 44 B7 07 +01 10 23 A4 87 60 89 47 63 ED A7 10 37 37 02 50 +13 07 C7 39 1C 4B 54 4B D5 8F 95 EB 73 00 50 10 +93 07 40 06 01 00 FD 17 C2 07 C1 83 E5 FF 1C 4B +54 4B D5 8F E5 D7 83 A6 04 14 89 47 63 F9 D7 00 +4C 4B 10 4B 35 65 13 05 45 EB EF 70 CF 8F 33 69 +49 01 63 16 09 0A 83 A7 04 14 09 47 63 95 0A 10 +63 68 F7 16 B7 07 01 10 03 A7 07 10 83 A7 4C 00 +63 1C F7 14 B7 07 01 10 03 A9 47 10 03 A4 8C 00 +63 1E 24 13 03 A9 87 10 03 A4 CC 00 63 1C 24 1F +03 A9 C7 10 03 A4 0C 01 63 14 24 1F 03 A9 07 11 +03 A4 4C 01 63 1C 89 1C 03 A9 47 11 03 A4 8C 01 +63 14 89 1C 03 A9 87 11 03 A4 CC 01 63 1C 89 1A +03 A9 C7 11 03 A4 0C 02 63 14 89 1A 03 A9 07 12 +03 A4 4C 02 63 1C 89 18 03 A9 47 12 03 A4 8C 02 +63 14 89 18 03 A9 87 12 03 A4 CC 02 63 12 89 10 +03 A9 C7 12 03 A4 0C 03 AD 45 63 12 89 0C F2 50 +62 54 D2 54 42 59 B2 59 22 5A 92 5A 02 5B F2 4B +62 4C D2 4C 42 4D B2 4D 21 61 82 80 09 47 98 CB +E1 B5 37 25 02 50 13 05 45 25 EF 60 DF FF 37 37 +02 50 13 07 C7 39 1C 4B 54 4B D5 8F E3 80 07 EE +DD BD 37 25 02 50 13 05 45 28 EF 60 DF FD 03 A5 +04 14 E9 B9 37 25 02 50 13 05 C5 34 EF 60 BF FC +03 A5 04 14 99 BB 63 64 F7 04 37 07 01 10 83 27 +47 61 89 8B ED DF 61 B7 83 27 C7 60 93 F7 C7 3F +95 C3 89 47 E3 FD A7 DC 37 25 02 50 13 05 85 38 +EF 60 7F F9 03 A5 04 14 D9 B3 61 E1 05 45 EF 60 +9F F6 01 A0 45 E5 05 45 EF 60 FF F5 01 A0 37 25 +02 50 13 05 C5 42 EF 60 1F F7 45 BF 85 45 83 A7 +04 14 09 4A 63 61 FA 04 05 45 EF 60 DF F3 01 A0 +37 25 02 50 13 05 C5 44 EF 60 FF F4 B7 07 01 10 +03 A9 07 10 03 A4 4C 00 E3 06 24 E9 81 45 C1 BF +A9 45 F1 B7 93 97 19 00 93 F7 E7 03 93 E7 17 00 +23 24 F7 60 0D BB B5 69 93 89 49 EB 13 85 49 03 +EF 60 7F F3 83 A7 04 14 E3 78 FA FA CA 85 13 85 +09 06 EF 60 5F F2 83 A7 04 14 E3 7F FA F8 A2 85 +13 85 89 07 EF 60 3F F1 41 BF 37 25 02 50 13 05 +C5 2A EF 60 5F EE 03 A5 04 14 75 B9 37 25 02 50 +13 05 85 3D EF 60 3F ED B9 B7 37 25 02 50 13 05 +85 2F EF 60 5F EC 1D BF A5 45 91 BF A1 45 81 BF +9D 45 B1 B7 99 45 A1 B7 95 45 91 B7 91 45 81 B7 +8D 45 35 BF 89 45 25 BF 39 71 5A D0 62 CC 66 CA +6A C8 6E C6 06 DE 22 DC 26 DA 4A D8 4E D6 52 D4 +56 D2 5E CE 03 49 15 00 83 4B 25 00 03 CA 15 00 +83 C9 25 00 83 CA 06 00 AA 8D AE 8C 36 8C 32 8D +3A 8B B7 07 01 10 80 4F 05 88 75 DC 03 C7 0D 00 +B7 04 02 50 03 A5 04 14 45 CB 13 97 1B 00 13 77 +E7 03 13 67 17 00 23 A0 E7 60 89 47 63 E7 A7 38 +B7 07 01 10 23 A0 07 04 23 A2 07 04 23 A4 07 04 +23 A6 07 04 23 A8 07 04 23 AA 07 04 23 AC 07 04 +23 AE 07 04 23 A0 07 06 23 A2 07 06 23 A4 07 06 +23 A6 07 06 23 A8 07 06 23 AA 07 06 23 AC 07 06 +23 AE 07 06 37 07 01 10 83 27 47 60 89 8B ED DF +85 47 63 18 F9 0A 83 27 47 60 93 F7 C7 3F 63 89 +07 36 89 47 63 EF A7 3E 83 C7 0C 00 63 9A 07 38 +37 06 01 10 B7 05 FF EF 93 07 06 08 93 85 05 F8 +13 06 06 10 BE 86 91 07 33 87 B7 00 66 97 18 43 +98 C2 E3 99 C7 FE D1 A0 89 47 63 E1 A7 30 03 A7 +4D 00 B7 07 01 10 B8 C3 03 A7 8D 00 F8 C3 03 A7 +CD 00 B8 C7 03 A7 0D 01 F8 C7 03 A7 4D 01 B8 CB +03 A7 8D 01 F8 CB 03 A7 CD 01 B8 CF 03 A7 0D 02 +F8 CF 03 A7 4D 02 B8 D3 03 A7 8D 02 F8 D3 03 A7 +CD 02 B8 D7 03 A7 0D 03 F8 D7 03 A7 4D 03 B8 DB +03 A7 8D 03 F8 DB 03 A7 CD 03 B8 DF 03 A7 0D 04 +F8 DF 83 C7 0C 00 AD D7 93 97 19 00 93 F7 E7 03 +93 E7 17 00 37 07 01 10 23 24 F7 60 89 47 63 FA +A7 00 37 25 02 50 13 05 45 36 EF 60 DF D0 03 A5 +04 14 B7 06 01 10 93 87 06 08 93 86 06 10 23 A0 +07 00 91 07 E3 9D D7 FE 37 07 01 10 83 27 C7 60 +89 8B ED DF 85 47 63 0C FA 24 03 27 4D 00 B7 07 +01 10 23 A0 E7 14 03 27 8D 00 23 A2 E7 14 03 27 +CD 00 23 A4 E7 14 03 27 0D 01 23 A6 E7 14 03 27 +4D 01 23 A8 E7 14 03 27 8D 01 23 AA E7 14 03 27 +CD 01 23 AC E7 14 03 27 0D 02 23 AE E7 14 03 27 +4D 02 23 A0 E7 16 03 27 8D 02 23 A2 E7 16 03 27 +CD 02 23 A4 E7 16 03 27 0D 03 23 A6 E7 16 63 8D +0A 00 03 47 2C 00 A1 66 93 86 16 FC 06 07 13 77 +F7 0F 55 8F 23 A8 E7 60 B7 07 01 10 63 04 0B 18 +25 47 98 CB A2 87 63 93 0B 00 8D 47 37 07 01 10 +23 20 F7 60 63 93 09 00 0D 44 B7 07 01 10 23 A4 +87 60 89 47 63 E3 A7 16 37 37 02 50 13 07 C7 39 +1C 4B 54 4B D5 8F 95 EB 73 00 50 10 93 07 40 06 +01 00 FD 17 C2 07 C1 83 E5 FF 1C 4B 54 4B D5 8F +E5 D7 83 A6 04 14 89 47 63 F9 D7 00 4C 4B 10 4B +35 65 13 05 45 EB EF 60 1F C1 33 69 49 01 63 1C +09 0E 83 A7 04 14 09 47 63 9F 0A 0C 63 6B F7 18 +B7 07 01 10 03 A9 07 10 03 24 4C 00 63 19 24 1F +03 A9 47 10 03 24 8C 00 63 11 24 1F 03 A9 87 10 +03 24 CC 00 63 14 24 23 03 A9 C7 10 03 24 0C 01 +63 1C 24 21 03 A9 07 11 03 24 4C 01 63 14 89 20 +03 A9 47 11 03 24 8C 01 63 1C 89 1E 03 A9 87 11 +03 24 CC 01 63 14 89 1E 03 A9 C7 11 03 24 0C 02 +63 1C 89 1C 03 A9 07 12 03 24 4C 02 63 14 89 1C +03 A9 47 12 03 24 8C 02 63 1C 89 1A 03 A9 87 12 +03 24 CC 02 63 1D 89 12 03 A9 C7 12 03 24 0C 03 +63 15 89 12 03 A9 07 13 03 24 4C 03 63 1D 89 10 +03 A9 47 13 03 24 8C 03 63 15 89 10 03 A9 87 13 +03 24 CC 03 63 11 89 14 03 A9 C7 13 03 24 0C 04 +BD 45 63 02 89 02 83 A7 04 14 63 9C 07 0E 05 45 +EF 60 7F AE 01 A0 63 67 F7 0A 37 07 01 10 83 27 +47 61 89 8B ED DF F2 50 62 54 D2 54 42 59 B2 59 +22 5A 92 5A 02 5B F2 4B 62 4C D2 4C 42 4D B2 4D +21 61 82 80 29 47 98 CB B5 BD 37 25 02 50 13 05 +45 25 EF 60 5F AC 37 37 02 50 13 07 C7 39 1C 4B +54 4B D5 8F E3 8A 07 E8 6D B5 37 25 02 50 13 05 +45 46 EF 60 5F AA 03 A5 04 14 9D B1 37 25 02 50 +13 05 C5 34 EF 60 3F A9 03 A5 04 14 CD B9 83 27 +C7 60 93 F7 C7 3F 95 C3 89 47 E3 F0 A7 DA 37 25 +02 50 13 05 85 38 EF 60 1F A7 03 A5 04 14 71 B3 +4D E9 05 45 EF 60 3F A4 01 A0 49 ED 05 45 EF 60 +9F A3 01 A0 37 25 02 50 13 05 C5 42 EF 60 BF A4 +A9 B7 37 25 02 50 13 05 C5 44 EF 60 DF A3 8D B5 +93 97 19 00 93 F7 E7 03 93 E7 17 00 23 24 F7 60 +0D B3 B5 45 09 BF B1 45 39 B7 AD 45 29 B7 A9 45 +19 B7 B5 69 93 89 49 EB 13 85 09 09 EF 60 BF A2 +83 A7 04 14 E3 8D 07 EE CA 85 13 85 C9 0B EF 60 +9F A1 83 A7 04 14 E3 84 07 EE A2 85 13 85 49 0D +EF 60 7F A0 E9 BD B9 45 F9 B5 85 45 E9 B5 81 45 +D9 B5 37 25 02 50 13 05 C5 2A EF 60 DF 9C 03 A5 +04 14 41 B9 37 25 02 50 13 05 85 3D EF 60 BF 9B +B1 BF 37 25 02 50 13 05 85 2F EF 60 DF 9A 91 B7 +A5 45 51 BD A1 45 41 BD 9D 45 71 B5 99 45 61 B5 +95 45 51 B5 91 45 41 B5 8D 45 B5 BD 89 45 A5 BD +79 71 4A D0 56 CA 5E C6 62 C4 66 C2 6A C0 06 D6 +22 D4 26 D2 4E CE 52 CC 5A C8 03 4B 25 00 03 CA +25 00 83 C9 06 00 3E 8C 2A 8D AE 8B 36 89 B2 8C +BA 8A B7 07 01 10 80 4F 05 88 75 DC 03 47 0D 00 +B7 04 02 50 03 A5 04 14 55 CB 13 17 1B 00 13 77 +E7 03 13 67 17 00 23 A0 E7 60 89 47 63 E3 A7 34 +B7 07 01 10 23 A0 07 04 23 A2 07 04 23 A4 07 04 +23 A6 07 04 23 A8 07 04 23 AA 07 04 23 AC 07 04 +23 AE 07 04 23 A0 07 06 23 A2 07 06 23 A4 07 06 +23 A6 07 06 23 A8 07 06 23 AA 07 06 23 AC 07 06 +23 AE 07 06 37 07 01 10 83 27 47 60 89 8B ED DF +83 46 1D 00 85 47 63 98 F6 0A 83 27 47 60 93 F7 +C7 3F 63 83 07 32 89 47 63 EA A7 32 83 C7 0B 00 +63 9D 07 34 37 06 01 10 B7 05 FF EF 93 07 06 08 +93 85 05 F8 13 06 06 10 BE 86 91 07 33 87 B7 00 +5E 97 18 43 98 C2 E3 99 C7 FE E1 A0 89 47 63 EB +A7 2A 03 27 4D 00 B7 07 01 10 B8 C3 03 27 8D 00 +F8 C3 03 27 CD 00 B8 C7 03 27 0D 01 F8 C7 03 27 +4D 01 B8 CB 03 27 8D 01 F8 CB 03 27 CD 01 B8 CF +03 27 0D 02 F8 CF 03 27 4D 02 B8 D3 03 27 8D 02 +F8 D3 03 27 CD 02 B8 D7 03 27 0D 03 F8 D7 03 27 +4D 03 B8 DB 03 27 8D 03 F8 DB 03 27 CD 03 B8 DF +03 27 0D 04 F8 DF 83 C7 0B 00 AD D7 93 17 1A 00 +93 F7 E7 03 93 E7 17 00 37 07 01 10 23 24 F7 60 +89 47 63 FA A7 00 37 25 02 50 13 05 45 36 EF 60 +8F FF 03 A5 04 14 B7 06 01 10 93 87 06 08 93 86 +06 10 23 A0 07 00 91 07 E3 9D D7 FE 37 07 01 10 +83 27 C7 60 89 8B ED DF 83 C6 1B 00 85 47 63 84 +F6 20 03 A7 4C 00 B7 07 01 10 23 A0 E7 14 03 A7 +8C 00 23 A2 E7 14 03 A7 CC 00 23 A4 E7 14 03 A7 +0C 01 23 A6 E7 14 03 A7 4C 01 23 A8 E7 14 03 A7 +8C 01 23 AA E7 14 03 A7 CC 01 23 AC E7 14 03 A7 +0C 02 23 AE E7 14 03 A7 4C 02 23 A0 E7 16 03 A7 +8C 02 23 A2 E7 16 03 A7 CC 02 23 A4 E7 16 03 A7 +0C 03 23 A6 E7 16 63 8D 09 00 03 47 29 00 91 66 +93 86 16 FC 06 07 13 77 F7 0F 55 8F 23 A8 E7 60 +B7 07 01 10 63 8C 0A 12 25 47 98 CB A2 87 63 13 +0B 00 8D 47 37 07 01 10 23 20 F7 60 63 13 0A 00 +0D 44 B7 07 01 10 23 A4 87 60 89 47 63 EB A7 10 +37 37 02 50 13 07 C7 39 1C 4B 54 4B D5 8F 91 EF +73 00 50 10 93 07 40 06 01 00 FD 17 C2 07 C1 83 +E5 FF 1C 4B 54 4B D5 8F E5 D7 83 A7 04 14 09 44 +63 6B F4 00 63 8C 09 02 37 07 01 10 83 27 47 61 +89 8B ED DF 75 A0 4C 4B 10 4B 35 65 13 05 45 EB +EF 60 6F EE 83 A7 04 14 63 94 09 0C 63 78 F4 00 +37 25 02 50 13 05 C5 44 EF 60 EF EA B7 07 01 10 +03 A7 07 10 23 20 EC 00 03 A7 47 10 23 22 EC 00 +03 A7 87 10 23 24 EC 00 03 A7 C7 10 23 26 EC 00 +03 A7 07 11 23 28 EC 00 03 A7 47 11 23 2A EC 00 +03 A7 87 11 23 2C EC 00 03 A7 C7 11 23 2E EC 00 +03 A7 07 12 23 20 EC 02 03 A7 47 12 23 22 EC 02 +03 A7 87 12 23 24 EC 02 03 A7 C7 12 23 26 EC 02 +03 A7 07 13 23 28 EC 02 03 A7 47 13 23 2A EC 02 +03 A7 87 13 23 2C EC 02 83 A7 C7 13 23 2E FC 02 +B2 50 22 54 92 54 02 59 F2 49 62 4A D2 4A 42 4B +B2 4B 22 4C 92 4C 02 4D 45 61 82 80 29 47 98 CB +F1 B5 37 25 02 50 13 05 45 25 EF 60 CF DF CD B5 +E3 7C F4 F0 37 25 02 50 13 05 C5 42 EF 60 AF DE +21 B7 37 25 02 50 13 05 45 46 EF 60 CF DD 03 A5 +04 14 7D B1 37 25 02 50 13 05 C5 34 EF 60 AF DC +03 A5 04 14 3D BB 83 27 C7 60 93 F7 C7 3F 95 C3 +89 47 E3 F8 A7 DE 37 25 02 50 13 05 85 38 EF 60 +8F DA 03 A5 04 14 F1 BB 15 E9 05 45 EF 60 AF D7 +01 A0 11 ED 05 45 EF 60 0F D7 01 A0 37 25 02 50 +13 05 C5 2A EF 60 2F D8 03 A5 04 14 A9 BB 37 25 +02 50 13 05 85 3D EF 60 0F D7 E9 BF 37 25 02 50 +13 05 85 2F EF 60 2F D6 C9 B7 93 17 1A 00 93 F7 +E7 03 93 E7 17 00 23 24 F7 60 B1 BB 01 11 26 CA +4A C8 4E C6 56 C2 5A C0 06 CE 22 CC 52 C4 2A 89 +AE 84 B2 8A B6 89 3A 8B B7 07 01 10 80 4F 05 88 +75 DC 37 0A 02 50 03 28 0A 14 89 47 63 EC 07 27 +83 27 49 00 37 07 01 10 37 05 01 10 3C C3 83 26 +89 00 37 06 FF EF 93 07 07 08 74 C3 83 26 C9 00 +13 06 06 F8 93 05 05 10 34 C7 83 26 09 01 74 C7 +83 26 49 01 34 CB 83 26 89 01 74 CB 83 26 C9 01 +34 CF 83 26 09 02 74 CF 83 26 49 02 34 D3 83 26 +89 02 74 D3 83 26 C9 02 34 D7 83 26 09 03 74 D7 +83 26 49 03 34 DB 83 26 89 03 74 DB 83 26 C9 03 +34 DF 83 26 09 04 74 DF BE 86 91 07 33 87 C7 00 +26 97 18 43 98 C2 E3 99 B7 FE 83 A7 4A 00 23 20 +F5 14 83 A7 8A 00 23 22 F5 14 83 A7 CA 00 23 24 +F5 14 83 A7 0A 01 23 26 F5 14 83 A7 4A 01 23 28 +F5 14 83 A7 8A 01 23 2A F5 14 83 A7 CA 01 23 2C +F5 14 83 A7 0A 02 23 2E F5 14 83 A7 4A 02 23 20 +F5 16 83 A7 8A 02 23 22 F5 16 83 A7 CA 02 23 24 +F5 16 83 A7 0A 03 23 26 F5 16 63 0F 0B 12 E5 47 +1C C9 03 47 29 00 A2 87 11 E3 8D 47 37 07 01 10 +23 20 F7 60 83 C7 24 00 91 E3 0D 44 B7 07 01 10 +23 A4 87 60 89 47 63 E8 07 15 37 37 02 50 13 07 +C7 39 14 4B 5C 4B D5 8F 91 EF 73 00 50 10 93 07 +40 06 01 00 FD 17 C2 07 C1 83 E5 FF 1C 4B 54 4B +D5 8F E5 D7 83 27 0A 14 09 44 63 6C F4 0E B7 07 +01 10 83 A4 07 10 03 A4 49 00 63 1A 94 0C 83 A4 +47 10 03 A4 89 00 63 1A 94 14 83 A4 87 10 03 A4 +C9 00 63 1A 94 14 83 A4 C7 10 03 A4 09 01 63 92 +84 14 83 A4 07 11 03 A4 49 01 63 9A 84 12 83 A4 +47 11 03 A4 89 01 63 9A 84 14 83 A4 87 11 03 A4 +C9 01 63 92 84 14 83 A4 C7 11 03 A4 09 02 63 9A +84 12 83 A4 07 12 03 A4 49 02 63 92 84 12 83 A4 +47 12 03 A4 89 02 63 96 84 10 83 A4 87 12 03 A4 +C9 02 63 9C 84 0E 83 A4 C7 12 03 A4 09 03 63 9C +84 0E 83 A4 07 13 03 A4 49 03 63 92 84 10 83 A4 +47 13 03 A4 89 03 63 9C 84 0C 83 A4 87 13 03 A4 +C9 03 63 9C 84 0C 83 A4 C7 13 03 A4 09 04 BD 45 +63 90 84 02 F2 40 62 44 D2 44 42 49 B2 49 22 4A +92 4A 02 4B 05 61 82 80 E9 47 1C C9 D9 B5 81 45 +83 27 0A 14 89 49 63 E8 F9 04 05 45 EF 60 AF AB +01 A0 4C 4B 10 4B 35 65 13 05 45 EB EF 60 AF AE +83 27 0A 14 E3 7D F4 EE 37 25 02 50 13 05 C5 44 +EF 60 6F AB ED B5 37 25 02 50 13 05 45 25 EF 60 +8F AA 65 B5 37 25 02 50 13 05 C5 34 EF 60 AF A9 +03 28 0A 14 B5 BB 35 69 13 09 49 EB 13 05 C9 0E +EF 60 6F AA 83 27 0A 14 E3 F1 F9 FA A6 85 13 05 +89 11 EF 60 4F A9 83 27 0A 14 E3 F8 F9 F8 A2 85 +13 05 09 13 EF 60 2F A8 49 B7 85 45 95 BF 91 45 +85 BF 8D 45 B5 B7 89 45 A5 B7 A9 45 95 B7 B5 45 +85 B7 A5 45 B1 BF AD 45 A1 BF B9 45 91 BF A1 45 +81 BF 9D 45 B1 B7 99 45 A1 B7 95 45 91 B7 B1 45 +81 B7 01 00 52 65 63 65 69 76 65 64 20 48 4D 41 +43 20 6E 6F 74 69 66 2F 65 72 72 20 69 6E 74 72 +20 77 69 74 68 20 73 74 61 74 75 73 20 3D 20 25 +64 2F 20 25 64 0A 00 00 41 74 20 6F 66 66 73 65 +74 20 5B 25 64 5D 2C 20 68 6D 61 63 5F 74 61 67 +20 64 61 74 61 20 6D 69 73 6D 61 74 63 68 21 0A +00 00 00 00 41 63 74 75 61 6C 20 20 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 45 78 70 65 +63 74 65 64 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 41 74 20 6F 66 66 73 65 74 20 5B 25 +64 5D 2C 20 68 6D 61 63 5F 74 61 67 20 64 61 74 +61 20 6D 69 73 6D 61 74 63 68 21 0A 00 00 00 00 +41 63 74 75 61 6C 20 20 20 64 61 74 61 3A 20 30 +78 25 78 0A 00 00 00 00 45 78 70 65 63 74 65 64 +20 64 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +41 74 20 6F 66 66 73 65 74 20 5B 25 64 5D 2C 20 +68 6D 61 63 5F 74 61 67 20 64 61 74 61 20 6D 69 +73 6D 61 74 63 68 21 0A 00 00 00 00 41 63 74 75 +61 6C 20 20 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 45 78 70 65 63 74 65 64 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 B7 07 02 50 +03 A7 07 14 41 11 22 C4 06 C6 8D 47 2A 84 63 EC +E7 00 B7 67 00 04 3E 94 0A 04 91 47 B2 40 1C C0 +22 44 41 01 82 80 AA 85 35 65 13 05 45 1F EF 60 +8F 8C C5 B7 B7 07 02 50 03 A7 07 14 41 11 22 C4 +06 C6 8D 47 2A 84 63 EA E7 00 1C 40 93 F7 C7 3F +99 EF B2 40 22 44 41 01 82 80 37 25 02 50 13 05 +C5 48 EF 60 4F 87 1C 40 93 F7 C7 3F FD D3 37 25 +02 50 13 05 45 4A EF 60 0F 86 22 44 B2 40 05 45 +41 01 6F 60 4F 83 B7 07 02 50 03 A7 07 14 41 11 +22 C4 06 C6 8D 47 2A 84 63 EA E7 00 1C 40 93 F7 +C7 3F 99 CF B2 40 22 44 41 01 82 80 37 25 02 50 +13 05 05 4B EF 60 2F 82 1C 40 93 F7 C7 3F FD F3 +37 25 02 50 13 05 C5 4C EF 60 EF 80 22 44 B2 40 +05 45 41 01 6F 50 3F FE B7 07 02 50 03 A7 07 14 +41 11 22 C4 26 C2 06 C6 8D 47 AA 84 2E 84 63 ED +E7 00 06 04 13 74 E4 03 13 64 14 00 80 C0 B2 40 +22 44 92 44 41 01 82 80 37 25 02 50 13 05 85 4D +EF 50 7F FC F9 BF B7 07 02 50 03 A7 07 14 41 11 +22 C4 26 C2 4A C0 06 C6 8D 47 2A 89 AE 84 32 84 +63 EB E7 06 93 77 14 00 13 17 64 00 13 77 07 08 +93 95 14 00 9A 07 D9 8F 93 F5 E5 03 13 17 64 00 +13 77 07 10 93 16 64 00 CD 8F D9 8F 93 F6 06 20 +13 17 64 00 13 56 54 00 D5 8F 13 77 07 40 93 56 +64 00 05 8A D9 8F 2E 06 13 57 74 00 85 8A D1 8F +B2 06 05 8B 21 80 D5 8F 36 07 05 88 3A 04 D9 8F +B2 40 C1 8F 22 44 93 E7 17 00 23 20 F9 00 92 44 +02 49 41 01 82 80 37 25 02 50 13 05 05 4F EF 50 +9F F2 49 B7 B7 07 02 50 03 A7 07 14 41 11 22 C4 +06 C6 8D 47 2A 84 63 EF E7 00 06 04 13 74 E4 03 +13 64 14 04 B7 07 02 10 B2 40 23 A0 87 60 22 44 +41 01 82 80 37 25 02 50 13 05 85 50 EF 50 BF EE +E9 BF 01 00 4B 56 3A 20 63 6C 65 61 72 69 6E 67 +20 4B 56 20 65 6E 74 72 79 20 30 78 25 78 0A 00 +00 00 00 00 08 41 B7 25 02 50 41 11 93 85 05 77 +06 C6 EF 30 B0 53 B2 40 33 35 A0 00 41 01 82 80 +B7 05 02 50 93 85 85 3A 93 87 45 00 13 86 C5 20 +01 47 94 43 63 65 D5 00 D4 4B 63 69 D5 00 D1 07 +05 07 E3 98 C7 FE 13 85 85 20 82 80 93 17 27 00 +BA 97 8A 07 33 85 F5 00 82 80 01 11 22 CC 37 04 +02 50 26 CA 4A C8 4E C6 52 C4 06 CE 13 0A 84 3A +2A 89 13 04 84 3A 81 44 ED 49 21 A0 85 04 63 8D +34 01 08 40 CA 85 51 04 EF 30 50 4C 65 D9 13 95 +24 00 26 95 0A 05 52 95 F2 40 62 44 D2 44 42 49 +B2 49 22 4A 05 61 82 80 5C 45 63 C0 07 04 1C 49 +63 CF 07 02 5C 49 63 CE 07 02 1C 4D 63 CD 07 02 +5C 4D 63 CC 07 02 1C 51 63 CB 07 02 5C 51 63 CA +07 02 1C 55 63 C9 07 02 5C 55 63 C8 07 02 08 59 +13 45 F5 FF 7D 81 25 05 82 80 01 45 82 80 05 45 +82 80 09 45 82 80 0D 45 82 80 11 45 82 80 15 45 +82 80 19 45 82 80 1D 45 82 80 21 45 82 80 B7 37 +02 50 0A 05 93 87 C7 3E AA 97 94 43 05 47 33 17 +B7 00 55 8F 98 C3 82 80 01 11 4E C6 B7 09 02 50 +83 A7 09 14 06 CE 22 CC 26 CA 4A C8 52 C4 56 C2 +5A C0 09 47 63 6E F7 06 37 09 02 50 B7 34 02 50 +13 09 89 3A 93 84 C4 3E 01 44 09 4B B5 6A 6D 4A +63 62 FB 02 69 47 63 05 E4 00 09 47 63 6B F7 02 +F2 40 62 44 D2 44 42 49 B2 49 22 4A 92 4A 02 4B +05 61 82 80 90 40 83 25 09 00 13 85 CA 43 05 04 +EF 50 7F D5 83 A7 09 14 E3 09 44 FD 51 09 91 04 +C1 B7 62 44 F2 40 D2 44 42 49 B2 49 22 4A 92 4A +02 4B 37 25 02 50 13 05 85 53 05 61 6F 50 BF D0 +37 25 02 50 13 05 85 53 EF 50 FF CF 83 A7 09 14 +A5 BF 41 11 06 C6 EF 30 70 37 B2 40 33 35 A0 00 +41 01 82 80 63 52 B0 04 01 11 22 CC 26 CA 4A C8 +4E C6 06 CE 2E 89 AA 89 2A 84 81 44 EF 30 40 77 +B3 67 25 03 18 40 11 04 85 04 8A 07 CE 97 94 43 +23 2E D4 FE 98 C3 E3 13 99 FE F2 40 62 44 D2 44 +42 49 B2 49 05 61 82 80 82 80 01 00 20 20 25 34 +30 73 3A 20 30 78 25 2D 33 78 0A 00 00 00 00 00 +01 11 4E C6 B7 09 02 50 03 A7 09 14 22 CC 4A C8 +06 CE 26 CA 89 47 2A 89 2E 84 63 EB E7 06 B7 34 +02 50 93 84 C4 39 9C 54 E1 8F 63 8F 87 00 73 00 +50 10 93 07 40 06 01 00 FD 17 C2 07 C1 83 E5 FF +9C 54 E1 8F E3 95 87 FE DC 54 B3 F7 27 01 E3 90 +27 FF 83 A7 09 14 1D C0 B9 E3 D4 54 13 47 F9 FF +F2 40 75 8F D8 D4 98 54 93 47 F4 FF 62 44 F9 8F +9C D4 42 49 D2 44 B2 49 05 61 82 80 09 47 E3 7E +F7 FC CC 54 39 65 13 05 C5 97 EF 50 DF C1 F1 B7 +37 25 02 50 13 05 85 7E EF 50 FF BE 49 B7 8C 54 +39 65 13 05 05 95 EF 50 1F C0 45 BF B7 07 02 50 +03 A7 07 14 89 47 63 E7 E7 00 B7 87 02 10 21 47 +98 CB 82 80 37 35 02 50 41 11 13 05 45 80 06 C6 +EF 50 7F BB B2 40 B7 87 02 10 21 47 98 CB 41 01 +82 80 01 11 22 CC 26 CA 4A C8 52 C4 56 C2 3E 89 +06 CE 4E C6 2E 84 B2 84 36 8A BA 8A B7 87 02 10 +98 4F 05 8B 75 DF 54 41 B7 09 02 50 09 47 23 A0 +D7 08 14 45 23 A2 D7 08 54 45 23 A4 D7 08 14 49 +23 A6 D7 08 54 49 23 A8 D7 08 14 4D 23 AA D7 08 +54 4D 23 AC D7 08 14 51 23 AE D7 08 54 51 23 A0 +D7 0A 14 55 23 A2 D7 0A 54 55 23 A4 D7 0A 14 59 +23 A6 D7 0A 54 59 23 A8 D7 0A 14 5D 23 AA D7 0A +54 5D 23 AC D7 0A 34 41 23 AE D7 0A 03 A6 09 14 +63 66 C7 0E 93 17 24 00 13 97 9A 00 13 77 07 20 +91 8B 93 16 5A 00 D9 8F 93 F6 06 1E 13 97 44 00 +41 8B D5 8F D9 8F 93 E7 17 00 37 87 02 10 1C CB +89 47 63 E4 C7 10 37 34 02 50 13 04 C4 39 1C 54 +5C 54 85 8B 9D E3 73 00 50 10 93 07 40 06 01 00 +FD 17 C2 07 C1 83 E5 FF 1C 54 5C 54 85 8B E5 D7 +83 A7 09 14 89 44 63 E4 F4 0A 5C 54 F9 9B 5C D4 +1C 54 1C D4 B7 87 02 10 83 A4 07 10 03 24 49 00 +63 9F 84 06 83 A4 47 10 03 24 89 00 63 93 84 10 +83 A4 87 10 03 24 C9 00 63 99 84 0E 83 A4 C7 10 +03 24 09 01 63 9D 84 0E 83 A4 07 11 03 24 49 01 +63 95 84 0E 83 A4 47 11 03 24 89 01 63 9D 84 0C +83 A4 87 11 03 24 C9 01 63 93 84 0C 83 A4 C7 11 +03 24 09 02 9D 45 63 95 84 02 F2 40 62 44 D2 44 +42 49 B2 49 22 4A 92 4A 05 61 82 80 37 35 02 50 +13 05 C5 81 EF 50 3F A2 03 A6 09 14 21 B7 81 45 +83 A7 09 14 B9 EB 05 45 EF 50 FF 9E 01 A0 4C 54 +39 65 13 05 C5 97 EF 50 1F A2 5C 54 03 A7 09 14 +F9 9B 5C D4 1C 54 1C D4 E3 F6 E4 F4 37 35 02 50 +13 05 C5 82 EF 50 3F 9E 35 BF 37 25 02 50 13 05 +85 7E 37 34 02 50 EF 50 1F 9D 13 04 C4 39 1C 54 +5C 54 85 8B E3 89 07 EE 21 B7 39 69 13 09 09 95 +13 05 C9 05 EF 50 3F 9D 83 A7 09 14 C9 DF A6 85 +13 05 89 08 EF 50 3F 9C 83 A7 09 14 C9 D7 A2 85 +13 05 09 0A EF 50 3F 9B BD BF 89 45 95 BF 99 45 +85 BF 85 45 B5 B7 95 45 A5 B7 91 45 95 B7 8D 45 +85 B7 01 11 22 CC 26 CA 4A C8 4E C6 52 C4 56 C2 +06 CE 5A C0 AE 84 32 84 36 89 BA 89 3E 8A C6 8A +37 83 02 10 03 28 83 01 13 78 18 00 E3 0C 08 FE +58 41 93 87 FA FF 93 B7 17 00 23 20 E3 08 18 45 +37 0B 02 50 E1 8F 23 22 E3 08 58 45 23 24 E3 08 +18 49 23 26 E3 08 58 49 23 28 E3 08 18 4D 23 2A +E3 08 58 4D 23 2C E3 08 18 51 23 2E E3 08 58 51 +23 20 E3 0A 18 55 23 22 E3 0A 58 55 23 24 E3 0A +18 59 23 26 E3 0A 58 59 23 28 E3 0A 18 5D 23 2A +E3 0A 58 5D 23 2C E3 0A 38 41 23 2E E3 0A 83 26 +0B 14 B5 C3 89 47 63 E9 D7 08 05 45 EF 50 BF 8A +03 27 0B 14 89 47 63 EA E7 06 06 04 26 0A 93 77 +24 00 13 7A 0A 20 96 09 B3 E7 47 01 93 F9 09 1E +12 09 B3 E7 37 01 13 79 09 01 8A 04 B3 E7 27 01 +91 88 62 44 C5 8F F2 40 D2 44 42 49 B2 49 22 4A +02 4B 93 E7 17 00 37 87 02 10 D6 85 92 4A 1C CB +01 45 05 61 F5 B6 13 87 EA FF 93 47 F4 FF 13 37 +17 00 F9 8F D1 DF 89 47 E3 F9 D7 F8 37 35 02 50 +13 05 C5 8B EF 50 3F 85 49 B7 37 35 02 50 13 05 +C5 81 EF 50 5F 84 51 B7 37 35 02 50 13 05 C5 84 +EF 50 7F 83 9D B7 41 11 06 C6 22 C4 26 C2 37 87 +02 10 1C 4F 85 8B F5 DF B7 04 02 50 83 A7 04 14 +09 44 63 66 F4 04 37 34 02 50 13 04 C4 39 1C 54 +5C 54 85 8B 9D E3 73 00 50 10 93 07 40 06 01 00 +FD 17 C2 07 C1 83 E5 FF 1C 54 5C 54 85 8B E5 D7 +03 A7 04 14 89 47 63 E5 E7 04 5C 54 B2 40 92 44 +F9 9B 5C D4 1C 54 1C D4 22 44 41 01 82 80 37 35 +02 50 13 05 C5 81 EF 50 0F FC 83 A7 04 14 E3 74 +F4 FA 37 25 02 50 13 05 85 7E 37 34 02 50 EF 50 +8F FA 13 04 C4 39 1C 54 5C 54 85 8B C9 DF 4D BF +4C 54 39 65 13 05 C5 97 EF 50 EF FA 7D B7 01 00 +52 65 63 65 69 76 65 64 20 53 48 41 32 35 36 20 +65 72 72 20 69 6E 74 72 20 77 69 74 68 20 73 74 +61 74 75 73 20 3D 20 25 64 0A 00 00 52 65 63 65 +69 76 65 64 20 53 48 41 32 35 36 20 6E 6F 74 69 +66 20 69 6E 74 72 20 77 69 74 68 20 73 74 61 74 +75 73 20 3D 20 25 64 0A 00 00 00 00 41 74 20 6F +66 66 73 65 74 20 5B 25 64 5D 2C 20 73 68 61 5F +64 69 67 65 73 74 20 64 61 74 61 20 6D 69 73 6D +61 74 63 68 21 0A 00 00 41 63 74 75 61 6C 20 20 +20 64 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +45 78 70 65 63 74 65 64 20 64 61 74 61 3A 20 30 +78 25 78 0A 00 00 00 00 41 11 22 C4 37 04 02 50 +03 27 04 14 06 C6 89 47 63 E0 E7 04 37 37 02 50 +13 07 C7 39 1C 53 54 53 D5 8F 9D E3 73 00 50 10 +93 07 40 06 01 00 FD 17 C2 07 C1 83 E5 FF 1C 53 +54 53 D5 8F E5 D7 83 26 04 14 89 47 63 E5 D7 02 +B2 40 22 44 41 01 82 80 37 35 02 50 13 05 45 91 +EF 50 6F E7 37 37 02 50 13 07 C7 39 1C 53 54 53 +D5 8F CD DF C9 BF 22 44 B2 40 4C 53 39 65 13 05 +05 0E 41 01 6F 50 2F E7 B7 07 02 50 03 A7 07 14 +41 11 22 C4 06 C6 8D 47 2A 84 63 ED E7 00 0A 04 +31 88 13 64 14 00 B7 07 02 10 B2 40 80 CB 22 44 +41 01 82 80 AA 85 39 65 13 05 05 11 EF 50 AF E3 +F9 BF B7 07 02 50 03 A7 07 14 41 11 22 C4 06 C6 +8D 47 2A 84 63 ED E7 00 0A 04 31 88 13 64 24 00 +B7 07 02 10 B2 40 80 CB 22 44 41 01 82 80 AA 85 +39 65 13 05 45 13 EF 50 0F E0 F9 BF B7 07 02 50 +03 A7 07 14 41 11 22 C4 06 C6 8D 47 2A 84 63 ED +E7 00 0A 04 31 88 13 64 14 02 B7 07 02 10 B2 40 +80 CB 22 44 41 01 82 80 AA 85 39 65 13 05 85 15 +EF 50 6F DC F9 BF B7 07 02 50 03 A7 07 14 41 11 +22 C4 06 C6 8D 47 2A 84 63 ED E7 00 0A 04 31 88 +13 64 24 02 B7 07 02 10 B2 40 80 CB 22 44 41 01 +82 80 AA 85 39 65 13 05 45 18 EF 50 CF D8 F9 BF +B7 07 02 50 03 A7 07 14 8D 47 63 E8 E7 00 B7 07 +02 10 05 47 23 A8 E7 62 82 80 37 35 02 50 41 11 +13 05 05 93 06 C6 EF 50 0F D4 B2 40 B7 07 02 10 +05 47 23 A8 E7 62 41 01 82 80 B7 07 02 50 03 A7 +07 14 89 47 63 E7 E7 00 B7 07 02 10 41 47 98 CB +82 80 37 35 02 50 41 11 13 05 45 95 06 C6 EF 50 +8F D0 B2 40 B7 07 02 10 41 47 98 CB 41 01 82 80 +01 11 22 CC 4A C8 06 CE 26 CA 4E C6 52 C4 2E 84 +32 89 B7 07 02 10 98 4F 05 8B 75 DF B7 04 02 10 +37 06 FE EF 93 87 07 08 13 06 06 F8 93 85 04 10 +BE 86 91 07 33 87 C7 00 2A 97 18 43 98 C2 E3 99 +B7 FE B7 09 02 50 83 A7 09 14 09 4A 63 66 FA 14 +93 17 24 00 B1 8B 93 E7 17 00 9C C8 37 37 02 50 +13 07 C7 39 1C 53 54 53 D5 8F 9D E3 73 00 50 10 +93 07 40 06 01 00 FD 17 C2 07 C1 83 E5 FF 1C 53 +54 53 D5 8F E5 D7 83 A7 09 14 09 44 63 65 F4 0E +B7 07 02 10 83 A4 07 10 03 24 49 00 63 15 94 0C +83 A4 47 10 03 24 89 00 63 92 84 16 83 A4 87 10 +03 24 C9 00 63 9A 84 14 83 A4 C7 10 03 24 09 01 +63 9A 84 14 83 A4 07 11 03 24 49 01 63 92 84 14 +83 A4 47 11 03 24 89 01 63 96 84 14 83 A4 87 11 +03 24 C9 01 63 9A 84 14 83 A4 C7 11 03 24 09 02 +63 92 84 14 83 A4 07 12 03 24 49 02 63 9A 84 12 +83 A4 47 12 03 24 89 02 63 92 84 12 83 A4 87 12 +03 24 C9 02 63 96 84 10 83 A4 C7 12 03 24 09 03 +63 9C 84 0E 83 A4 07 13 03 24 49 03 63 98 84 10 +83 A4 47 13 03 24 89 03 63 92 84 0E 83 A4 87 13 +03 24 C9 03 63 92 84 0E 83 A4 C7 13 03 24 09 04 +BD 45 63 9B 84 00 F2 40 62 44 D2 44 42 49 B2 49 +22 4A 05 61 82 80 81 45 83 A7 09 14 B5 E7 05 45 +EF 50 6F B6 01 A0 4C 53 39 65 13 05 05 0E EF 50 +8F B9 83 A7 09 14 E3 75 F4 F0 37 35 02 50 13 05 +C5 97 EF 50 4F B6 ED BD 37 35 02 50 13 05 C5 96 +EF 50 6F B5 93 17 24 00 03 A7 09 14 B1 8B 93 E7 +17 00 9C C8 E3 74 EA EA 37 35 02 50 13 05 45 91 +EF 50 6F B3 37 37 02 50 13 07 C7 39 1C 53 54 53 +D5 8F E3 8D 07 E8 45 BD 39 69 13 09 09 0E 13 05 +09 0D EF 50 4F B3 83 A7 09 14 D1 D3 A6 85 13 05 +C9 0F EF 50 4F B2 83 A7 09 14 B5 DB A2 85 13 05 +49 11 EF 50 4F B1 A5 B7 89 45 B9 BF 85 45 A9 BF +91 45 99 BF 8D 45 89 BF AD 45 B9 B7 B5 45 A9 B7 +A9 45 99 B7 95 45 89 B7 B9 45 3D BF A5 45 2D BF +A1 45 1D BF 9D 45 0D BF 99 45 3D B7 B1 45 2D B7 +01 11 26 CA 4A C8 06 CE 22 CC 4E C6 52 C4 AE 84 +32 88 36 89 B7 07 02 10 98 4F 05 8B 75 DF 37 04 +02 10 37 06 FE EF 93 87 07 08 13 06 06 F8 93 05 +04 10 BE 86 91 07 33 87 C7 00 2A 97 18 43 98 C2 +E3 99 B7 FE 03 27 48 00 B7 09 02 50 09 4A 98 C3 +83 27 88 00 23 22 F4 10 83 27 C8 00 23 24 F4 10 +83 27 08 01 23 26 F4 10 83 27 48 01 23 28 F4 10 +83 27 88 01 23 2A F4 10 83 27 C8 01 23 2C F4 10 +83 27 08 02 23 2E F4 10 83 27 48 02 23 20 F4 12 +83 27 88 02 23 22 F4 12 83 27 C8 02 23 24 F4 12 +83 27 08 03 23 26 F4 12 83 27 48 03 23 28 F4 12 +83 27 88 03 23 2A F4 12 83 27 C8 03 23 2C F4 12 +83 27 08 04 23 2E F4 12 83 A7 09 14 63 66 FA 14 +93 97 24 00 B1 8B 93 E7 27 04 1C C8 37 37 02 50 +13 07 C7 39 1C 53 54 53 D5 8F 9D E3 73 00 50 10 +93 07 40 06 01 00 FD 17 C2 07 C1 83 E5 FF 1C 53 +54 53 D5 8F E5 D7 83 A7 09 14 09 44 63 65 F4 0E +B7 07 02 10 83 A4 07 10 03 24 49 00 63 95 84 0C +83 A4 47 10 03 24 89 00 63 92 84 16 83 A4 87 10 +03 24 C9 00 63 9A 84 14 83 A4 C7 10 03 24 09 01 +63 9A 84 14 83 A4 07 11 03 24 49 01 63 92 84 14 +83 A4 47 11 03 24 89 01 63 96 84 14 83 A4 87 11 +03 24 C9 01 63 9A 84 14 83 A4 C7 11 03 24 09 02 +63 92 84 14 83 A4 07 12 03 24 49 02 63 9A 84 12 +83 A4 47 12 03 24 89 02 63 92 84 12 83 A4 87 12 +03 24 C9 02 63 96 84 10 83 A4 C7 12 03 24 09 03 +63 9C 84 0E 83 A4 07 13 03 24 49 03 63 98 84 10 +83 A4 47 13 03 24 89 03 63 92 84 0E 83 A4 87 13 +03 24 C9 03 63 92 84 0E 83 A4 C7 13 03 24 09 04 +BD 45 63 9B 84 00 F2 40 62 44 D2 44 42 49 B2 49 +22 4A 05 61 82 80 81 45 83 A7 09 14 B5 E7 05 45 +EF 50 6F 8A 01 A0 4C 53 39 65 13 05 05 0E EF 50 +8F 8D 83 A7 09 14 E3 75 F4 F0 37 35 02 50 13 05 +C5 97 EF 50 4F 8A ED BD 37 35 02 50 13 05 C5 96 +EF 50 6F 89 93 97 24 00 03 A7 09 14 B1 8B 93 E7 +27 04 1C C8 E3 74 EA EA 37 35 02 50 13 05 45 91 +EF 50 6F 87 37 37 02 50 13 07 C7 39 1C 53 54 53 +D5 8F E3 8D 07 E8 45 BD 39 69 13 09 09 0E 13 05 +C9 12 EF 50 4F 87 83 A7 09 14 D1 D3 A6 85 13 05 +89 15 EF 50 4F 86 83 A7 09 14 B5 DB A2 85 13 05 +09 17 EF 50 4F 85 A5 B7 89 45 B9 BF 85 45 A9 BF +91 45 99 BF 8D 45 89 BF AD 45 B9 B7 B5 45 A9 B7 +A9 45 99 B7 95 45 89 B7 B9 45 3D BF A5 45 2D BF +A1 45 1D BF 9D 45 0D BF 99 45 3D B7 B1 45 2D B7 +52 65 63 65 69 76 65 64 20 53 48 41 35 31 32 20 +6E 6F 74 69 66 20 69 6E 74 72 20 77 69 74 68 20 +73 74 61 74 75 73 20 3D 20 25 64 0A 00 00 00 00 +53 48 41 35 31 32 3A 20 53 65 74 20 6D 6F 64 65 +3A 20 30 78 25 78 20 61 6E 64 20 69 6E 69 74 0A +00 00 00 00 53 48 41 35 31 32 3A 20 53 65 74 20 +6D 6F 64 65 3A 20 30 78 25 78 20 61 6E 64 20 6E +65 78 74 0A 00 00 00 00 53 48 41 35 31 32 3A 20 +53 65 74 20 6D 6F 64 65 3A 20 30 78 25 78 20 61 +6E 64 20 69 6E 69 74 20 77 69 74 68 20 6C 61 73 +74 0A 00 00 53 48 41 35 31 32 3A 20 53 65 74 20 +6D 6F 64 65 3A 20 30 78 25 78 20 61 6E 64 20 6E +65 78 74 20 77 69 74 68 20 6C 61 73 74 0A 00 00 +41 74 20 6F 66 66 73 65 74 20 5B 25 64 5D 2C 20 +73 68 61 5F 64 69 67 65 73 74 20 64 61 74 61 20 +6D 69 73 6D 61 74 63 68 21 0A 00 00 41 63 74 75 +61 6C 20 20 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 45 78 70 65 63 74 65 64 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 41 74 20 6F +66 66 73 65 74 20 5B 25 64 5D 2C 20 73 68 61 5F +64 69 67 65 73 74 20 64 61 74 61 20 6D 69 73 6D +61 74 63 68 21 0A 00 00 41 63 74 75 61 6C 20 20 +20 64 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +45 78 70 65 63 74 65 64 20 64 61 74 61 3A 20 30 +78 25 78 0A 00 00 00 00 85 47 B3 95 B7 00 71 05 +1C 41 ED 8F F5 DF 82 80 41 11 06 C6 AA 86 2E 87 +B2 87 01 CD 01 CE 13 06 00 02 63 7F B6 04 B7 07 +02 50 83 A7 07 14 B1 E3 01 A0 99 C5 B7 07 02 50 +83 A7 07 14 85 E7 01 A0 01 46 ED DB 93 05 27 00 +CC D3 85 45 23 80 B7 00 A3 80 C7 00 B2 40 13 85 +27 00 3A 86 B6 85 41 01 6F 20 80 6B 37 35 02 50 +13 05 C5 99 EF 40 3F E0 F9 B7 37 35 02 50 13 05 +05 9F EF 40 5F DF 4D BF 13 96 35 00 42 06 41 82 +93 05 00 10 63 15 B6 02 13 06 37 00 D0 D3 09 46 +23 80 C7 00 05 46 A3 80 C7 00 23 81 07 00 B2 40 +13 85 37 00 3A 86 B6 85 41 01 6F 20 60 66 13 76 +F6 0F 69 B7 41 11 06 C6 B2 87 19 C9 19 CA 11 47 +63 70 B7 02 B7 07 02 50 83 A7 07 14 B9 E3 01 A0 +99 C5 B7 07 02 50 83 A7 07 14 8D E7 01 A0 75 DA +93 86 25 00 13 97 35 00 94 C7 85 46 23 80 D7 00 +A3 80 E7 00 B2 40 2E 86 AA 85 41 01 13 85 27 00 +6F 20 00 61 37 35 02 50 13 05 85 A3 EF 40 BF D5 +F1 B7 37 35 02 50 13 05 C5 A7 EF 40 DF D4 45 BF +41 11 06 C6 29 C5 A1 C5 89 47 63 0A F6 08 63 ED +C7 04 51 CA 5C 4D 21 47 13 06 20 02 D8 C5 23 A2 +05 00 90 C5 85 8B 11 48 13 07 C5 01 A9 CF A2 06 +23 90 05 00 B3 E7 06 01 5C C9 5C C9 5C 49 F5 47 +1C CD 1C 43 89 8B F5 DF B2 40 41 01 82 80 B7 07 +02 50 83 A7 07 14 91 E3 01 A0 37 35 02 50 13 05 +C5 AB EF 40 5F CE CD BF 8D 47 63 14 F6 02 49 46 +41 47 21 48 5C 4D D8 C5 23 A2 05 00 90 C5 85 8B +13 07 C5 01 CD F7 B7 07 02 50 83 A7 07 14 8D E3 +01 A0 B7 07 02 50 83 A7 07 14 95 E3 01 A0 69 46 +31 47 19 48 C1 BF 13 06 40 02 1D 47 09 48 D9 B7 +37 35 02 50 13 05 C5 B2 EF 40 FF C8 D1 BF 37 35 +02 50 13 05 C5 AF EF 40 1F C8 C9 BF 41 11 06 C6 +0D C5 85 C5 31 C6 85 47 63 1E F6 02 5C 4D 13 07 +20 02 98 C5 85 8B 11 46 13 07 C5 01 B1 E3 B7 07 +02 50 83 A7 07 14 AD EB 01 A0 B7 07 02 50 83 A7 +07 14 91 E3 01 A0 37 35 02 50 13 05 05 B6 EF 40 +9F C3 CD BF B7 07 02 50 83 A7 07 14 9D EF 01 A0 +5C 4D 13 07 A0 02 98 C5 85 8B 13 07 C5 01 E1 D3 +93 97 86 00 D1 8F 23 90 05 00 23 A6 05 00 23 A2 +05 00 93 E7 07 02 5C C9 5C C9 F5 47 1C CD 1C 43 +89 8B F5 DF B2 40 41 01 82 80 37 35 02 50 13 05 +C5 BA EF 40 5F BE 65 BF 37 35 02 50 13 05 05 BE +EF 40 7F BD 51 B7 5D 71 86 C6 A2 C4 A6 C2 CA C0 +15 CD 8D CD 2A 84 B1 CE 03 D8 06 00 05 45 63 0A +A8 04 25 CE 05 45 63 10 A6 04 13 08 20 02 11 46 +48 4C 23 A4 05 01 93 04 C4 01 05 89 35 E1 B7 07 +02 50 83 A7 07 14 63 95 07 10 01 A0 B7 07 02 50 +83 A7 07 14 91 E3 01 A0 37 35 02 50 13 05 45 C1 +EF 40 7F B7 CD BF B7 07 02 50 83 A7 07 14 F1 EB +01 A0 11 C7 03 58 07 00 05 45 E3 14 A8 FA 63 06 +06 10 05 47 63 19 E6 0A BE 86 05 46 22 85 26 44 +B6 40 96 44 06 49 61 61 D1 B5 13 08 A0 02 49 BF +A2 07 D1 8F 23 90 05 00 23 A6 05 00 23 A2 05 00 +93 E7 07 03 5C C8 5C C8 02 CA 02 CC 02 CE 02 D0 +02 D2 02 D4 02 D6 02 D8 02 DA 02 DC 02 DE 91 C6 +03 A9 86 00 89 47 63 E8 27 09 85 47 23 1A F1 00 +13 05 61 01 19 C3 50 53 3D EA 85 47 23 00 F5 00 +A3 00 05 00 D2 47 1C D0 E2 47 5C D0 F2 47 1C D4 +82 57 5C D4 92 57 1C D8 A2 57 5C D8 B2 57 1C DC +C2 57 5C DC D2 57 3C C0 E2 57 7C C0 F2 57 3C C4 +F5 47 1C CC 9C 40 89 8B F5 DF B6 40 26 44 96 44 +06 49 61 61 82 80 B7 07 02 50 83 A7 07 14 9D EF +01 A0 37 35 02 50 13 05 05 CA EF 40 DF A8 0D B7 +37 35 02 50 13 05 C5 CD EF 40 FF A7 FD B5 BA 85 +EF 20 00 32 41 BF 4A 86 B6 85 48 08 3A C6 EF 20 +20 31 5C 08 32 47 33 85 27 01 AD B7 37 35 02 50 +13 05 85 C5 EF 40 3F A5 65 BF BE 86 01 46 FD BD +41 11 06 C6 19 C3 23 20 07 00 4D C1 C5 C1 51 CE +9C 45 D5 CB 5C 4D 13 03 C5 01 89 8B E5 C3 29 4F +B7 18 04 10 85 4E 8D 4F B5 CE 03 28 03 00 13 58 +88 00 13 78 F8 01 33 08 0F 41 0E 08 63 F3 06 01 +36 88 63 0B 08 04 93 77 16 00 C1 E7 B2 87 42 8E +63 00 D8 05 93 F5 37 00 C1 E9 3E 85 63 F1 CF 03 +13 05 CE FF 71 99 11 05 3E 95 8C 43 91 07 23 A0 +B8 80 E3 9C A7 FE 13 7E 3E 00 63 F5 CE 0B 83 55 +05 00 79 1E 93 07 25 00 23 90 B8 80 63 06 0E 00 +83 C7 07 00 23 80 F8 80 42 96 B3 86 06 41 49 D7 +23 20 07 01 B2 40 41 01 82 80 BD D2 B7 07 02 50 +83 A7 07 14 91 E3 01 A0 37 35 02 50 13 05 85 D1 +EF 40 7F 98 CD BF B7 07 02 50 83 A7 07 14 8D EF +01 A0 83 45 06 00 13 0E F8 FF 93 07 16 00 23 80 +B8 80 E3 E9 CE F7 5D B7 83 D5 07 00 79 1E 89 07 +23 90 B8 80 E3 E6 CF F7 3E 85 41 B7 B7 07 02 50 +83 A7 07 14 89 EB 01 A0 37 35 02 50 13 05 45 D5 +EF 40 7F 93 75 BF 37 35 02 50 13 05 85 D8 EF 40 +9F 92 D5 B7 AA 87 9D B7 41 11 06 C6 22 C4 61 C5 +F9 C1 69 C2 19 C3 23 20 07 00 03 C8 05 00 63 1A +08 08 03 C8 15 00 63 0F 08 06 83 A8 C5 00 13 03 +F0 0F 05 48 96 08 63 7F 13 05 41 68 33 B8 08 01 +37 03 00 01 13 48 18 00 33 B3 68 00 13 43 13 00 +09 08 1A 98 13 03 F8 FF 0E 03 B3 DE 68 00 93 FE +FE 0F 37 1E 04 10 23 00 DE 81 61 13 9D 4E 63 D1 +6E 02 33 D3 68 00 13 73 F3 0F 23 00 6E 80 11 43 +63 18 68 00 13 D3 88 00 13 73 F3 0F 23 00 6E 80 +13 78 F8 0F 37 13 04 10 93 F8 F8 0F 23 00 13 81 +23 00 03 81 05 48 23 80 05 01 13 08 E0 02 23 2C +05 01 03 A8 C5 00 63 0D 08 02 83 A8 45 00 B3 08 +18 41 63 F7 D8 02 B7 07 02 50 83 A7 07 14 63 99 +07 14 01 A0 A1 D2 B7 07 02 50 83 A7 07 14 91 E3 +01 A0 37 35 02 50 13 05 C5 DB EF 40 DF 83 CD BF +E1 C2 83 A8 85 00 93 02 C5 01 93 03 10 03 C0 41 +B3 8E 88 40 63 10 08 02 63 F3 D6 01 B6 8E 63 90 +0E 04 23 2C 75 00 23 A2 05 00 C0 41 B3 8E 88 40 +E3 04 08 FE 63 6E 18 01 63 ED D6 09 63 91 0E 02 +63 94 08 09 B7 07 02 50 83 A7 07 14 F9 EB 01 A0 +B3 0E 88 40 63 F3 D6 01 B6 8E E3 85 0E FE 03 A8 +02 00 13 78 48 00 E3 0C 08 FE B7 0F 01 04 93 8F +0F 10 A2 9F 8A 0F 7E 88 01 4E 03 2F 08 00 03 23 +08 10 B3 08 F8 41 B2 98 33 43 E3 01 23 A0 68 00 +05 0E 11 08 E3 13 DE FF 72 94 13 18 2E 00 C0 C1 +42 96 B3 86 C6 41 11 C7 03 28 07 00 72 98 23 20 +07 01 95 E3 91 C6 03 A8 C5 00 83 A8 85 00 81 BF +B2 40 22 44 41 01 82 80 33 08 18 41 23 A6 05 01 +89 BF B6 8E A5 B7 83 A8 85 00 B7 0E 01 04 93 8E +0E 10 C6 9E 13 08 20 03 8A 0E B3 0F 18 41 E3 83 +08 FD 76 88 01 4E 03 2F 08 00 03 23 08 10 B3 08 +D8 41 BE 98 33 43 E3 01 23 A0 68 00 05 0E 11 08 +E3 63 FE FF 11 48 63 84 0F 00 13 98 2F 00 C2 97 +51 BF 37 35 02 50 13 05 45 E4 EF 40 CF F0 05 B7 +37 35 02 50 13 05 05 DF EF 40 EF EF 5D B5 41 11 +06 C6 1D C5 95 C5 83 C7 05 00 A1 C3 13 07 C5 01 +1C 43 91 8B F5 DF B2 40 D9 47 1C CD 23 90 05 00 +23 A2 05 00 23 A4 05 00 23 A6 05 00 41 01 82 80 +B7 07 02 50 83 A7 07 14 91 E3 01 A0 37 35 02 50 +13 05 C5 E7 EF 40 2F EB CD BF B7 07 02 50 83 A7 +07 14 91 E3 01 A0 37 35 02 50 13 05 C5 EA EF 40 +8F E9 CD BF B7 07 02 30 C8 4B 82 80 B7 07 04 30 +3E 95 08 41 82 80 B7 07 04 30 AA 97 8C C3 82 80 +B7 07 02 50 03 A7 07 14 8D 47 63 E8 E7 00 37 07 +02 30 1C 4F F9 9B 1C CF 82 80 41 65 41 11 13 05 +45 28 06 C6 EF 40 2F E7 37 07 02 30 1C 4F B2 40 +F9 9B 1C CF 41 01 82 80 41 11 22 C4 37 04 02 50 +83 27 04 14 26 C2 06 C6 91 44 63 EF F4 02 B7 07 +02 30 CC 4F 99 47 99 81 9D 89 63 8F F5 04 B9 CD +9D 47 63 97 F5 00 83 27 04 14 A5 EF 3D 45 01 A8 +41 65 13 05 05 2A EF 40 0F E2 13 05 F0 0F B2 40 +22 44 92 44 41 01 82 80 37 35 02 50 13 05 45 EE +EF 40 6F DE B7 07 02 30 CC 4F 99 47 99 81 9D 89 +E3 9F F5 FA 83 27 04 14 63 F8 F4 00 37 35 02 50 +13 05 C5 F0 EF 40 2F DC 01 45 D1 B7 03 27 04 14 +85 47 63 E8 E7 00 05 45 B2 40 22 44 92 44 41 01 +82 80 37 35 02 50 13 05 C5 F4 EF 40 CF D9 05 45 +E5 B7 37 35 02 50 13 05 45 F8 EF 40 CF D8 3D 45 +79 B7 B7 07 02 50 03 A7 07 14 41 11 22 C4 06 C6 +8D 47 2A 84 63 EC E7 00 37 07 02 30 5C 4F B2 40 +C1 9B C1 8F 22 44 5C CF 41 01 82 80 AA 85 41 65 +13 05 45 2E EF 40 2F D7 C5 B7 B7 07 02 50 03 A7 +07 14 41 11 22 C4 06 C6 8D 47 2A 84 63 E6 E7 02 +B7 07 03 30 D8 5F 93 17 84 00 B3 66 E4 00 91 C7 +B7 07 00 FF 7D 8F B3 66 87 00 B2 40 22 44 B7 07 +03 30 D4 DF 41 01 82 80 AA 85 41 65 13 05 C5 30 +EF 40 6F D2 F1 B7 B7 07 02 50 03 A7 07 14 41 11 +22 C4 06 C6 26 C2 8D 47 2A 84 63 EC E7 04 B7 17 +02 30 84 43 85 47 63 ED 87 02 63 E2 97 02 93 77 +14 00 33 67 94 00 81 C7 F9 98 33 E7 84 00 B2 40 +22 44 B7 17 02 30 98 C3 92 44 41 01 82 80 41 65 +13 05 C5 38 EF 40 2F CD 05 45 EF 40 CF C8 C1 BF +41 65 13 05 05 37 EF 40 0F CC 05 45 EF 40 AF C7 +7D BF AA 85 41 65 13 05 45 33 EF 40 CF CA 45 B7 +B7 07 02 50 03 A7 07 14 41 11 22 C4 06 C6 8D 47 +2A 84 63 E0 E7 04 B7 07 03 30 DC 5F 13 17 84 00 +19 CF 37 07 00 FF 79 8C 13 44 F4 FF 7D 8C 79 8C +B7 07 03 30 B2 40 C0 DF 22 44 41 01 82 80 13 44 +F4 FF 7D 8C B7 07 03 30 B2 40 C0 DF 22 44 41 01 +82 80 AA 85 41 65 13 05 85 3A EF 40 CF C4 65 BF +09 CD 01 47 B7 06 02 30 19 A0 63 08 E5 00 9C 42 +05 07 85 8B FD FB 01 45 82 80 05 45 82 80 79 71 +4E CE B7 09 02 50 22 D4 83 A7 09 14 37 04 02 30 +26 D2 04 44 4A D0 06 D6 52 CC 0D 49 63 6D F9 00 +40 44 B2 50 22 85 22 54 02 59 F2 49 62 4A A6 85 +92 54 45 61 82 80 41 6A 13 0A 4A 28 A6 85 13 05 +CA 14 EF 40 4F BE 83 A7 09 14 40 44 E3 7B F9 FC +A2 85 13 05 0A 17 EF 40 0F BD E1 B7 79 71 4A D0 +37 09 02 50 03 27 09 14 22 D4 26 D2 06 D6 4E CE +52 CC 2A C4 2E C6 89 47 2A 84 AE 84 63 E9 E7 14 +B7 07 04 00 63 EB 87 12 B7 C7 5E BA 93 87 17 A1 +63 82 F4 02 B7 D7 BE BA 93 87 E7 AF 63 80 F4 14 +41 65 A6 85 13 05 C5 44 EF 40 EF B7 05 45 EF 40 +8F B3 01 A0 B7 04 00 50 37 0A 00 40 37 07 02 30 +50 4B 75 C2 13 07 06 02 63 6F E4 0C 13 77 36 00 +11 C3 11 06 37 07 02 30 4C 4B 03 25 09 14 89 46 +23 20 BA 00 03 28 47 01 93 59 26 00 23 20 0A 01 +58 4B 23 20 EA 00 63 E5 A6 10 93 96 29 00 D2 87 +D2 96 37 05 02 30 63 88 09 00 58 49 91 07 23 AE +E7 FE E3 9C D7 FE B7 07 02 30 D8 4B 69 C7 93 77 +C6 FF 93 06 07 02 B6 97 63 6F F4 0A 93 77 37 00 +91 C3 11 07 B7 07 02 30 D0 4B 83 25 09 14 13 54 +27 00 90 C0 D0 4B 89 46 90 C0 D8 4B 98 C0 63 E2 +B6 0C 63 0A 04 0C 13 17 24 00 A6 87 26 97 37 06 +02 30 54 4A 91 07 23 AE D7 FE E3 1C F7 FE B7 07 +02 30 23 A6 07 00 8D 47 63 F8 B7 00 41 65 89 45 +13 05 45 2E EF 40 2F AA 37 07 02 30 5C 4F B2 50 +22 54 C1 9B 93 E7 27 00 5C CF 92 54 02 59 F2 49 +62 4A 45 61 82 80 41 65 A2 85 13 05 05 48 EF 40 +8F A7 05 45 EF 40 2F A3 01 A0 41 65 A2 85 13 05 +85 41 EF 40 4F A6 05 45 EF 40 EF A1 01 A0 37 35 +02 50 13 05 C5 FD EF 40 0F A3 5D B5 B7 04 02 50 +37 0A 02 40 E1 BD 01 14 41 65 3A 86 B3 05 34 41 +13 05 C5 4D EF 40 2F A3 05 45 EF 40 CF 9E 01 A0 +37 35 02 50 13 05 C5 FF 32 C2 EF 40 CF 9F 12 46 +ED B5 37 35 02 50 13 05 05 01 EF 40 CF 9E 83 25 +09 14 15 F8 A9 B7 23 A6 07 00 B9 BF 79 71 4E CE +B7 09 02 50 03 A7 09 14 4A D0 06 D6 22 D4 26 D2 +52 CC 56 CA 5A C8 2A C4 2E C6 8D 47 2A 89 63 E6 +E7 04 01 44 B7 04 00 40 63 77 A4 02 B7 07 02 30 +D8 4B 11 04 93 87 44 00 98 C0 B3 05 F4 40 37 06 +02 30 63 7A 24 01 54 4A 91 07 33 87 B7 00 23 AE +D7 FE E3 6A 27 FF B2 50 22 54 92 54 02 59 F2 49 +62 4A D2 4A 42 4B 45 61 82 80 37 35 02 50 01 44 +13 05 45 02 EF 40 2F 96 E3 7F 24 FD C1 6A B7 04 +00 40 0D 4B 93 8A 8A 53 37 0A 02 30 11 A0 BA 84 +83 A7 09 14 A6 85 56 85 E3 7A FB F8 90 40 11 04 +EF 40 6F 95 83 27 4A 01 13 87 44 00 9C C0 E3 60 +24 FF 55 B7 41 11 26 C2 4A C0 06 C6 22 C4 B7 07 +04 00 2A 89 AE 84 63 E0 A7 06 D5 C4 81 47 37 07 +02 30 19 A0 63 83 F4 06 00 43 85 07 05 88 7D F8 +B7 17 03 30 03 A6 87 80 13 77 D6 FE 23 A4 E7 80 +63 0C 09 00 81 47 B7 06 04 30 33 87 D7 00 23 20 +07 00 91 07 E3 EB 27 FF B2 40 22 44 B7 07 02 30 +05 47 98 D3 B7 17 03 30 23 A4 C7 80 92 44 02 49 +01 45 41 01 82 80 AA 85 41 65 13 05 45 54 EF 40 +8F 8C 05 45 EF 40 2F 88 49 BF B7 07 02 50 03 A7 +07 14 85 47 63 F8 E7 00 37 35 02 50 13 05 85 04 +EF 40 6F 88 85 47 E3 85 F4 F8 37 07 02 30 13 06 +07 02 85 46 19 A0 E3 8D 84 F6 14 C2 1C 43 05 04 +85 8B F5 FB B5 B7 B7 07 02 50 03 A7 07 14 85 47 +E3 F0 E7 F6 37 35 02 50 13 05 85 04 EF 40 AF 84 +81 BF B7 07 02 50 03 A7 07 14 41 11 22 C4 06 C6 +8D 47 2A 84 63 FB E7 04 95 47 63 FC A7 02 37 36 +02 50 AA 85 41 65 13 06 46 09 13 05 85 56 EF 40 +8F 83 B7 07 03 30 23 A4 87 62 37 07 03 30 83 27 +47 62 B2 40 22 44 93 E7 17 00 23 22 F7 62 41 01 +82 80 29 C1 AA 85 37 36 02 50 41 65 13 06 06 08 +13 05 85 56 EF 40 2F 80 29 A0 61 D9 95 47 E3 E2 +A7 FC B7 07 03 30 15 47 23 A4 E7 62 37 07 03 30 +83 27 47 62 B2 40 22 44 93 E7 17 00 23 22 F7 62 +41 01 82 80 37 36 02 50 41 65 13 06 06 07 81 45 +13 05 85 56 EF 30 3F FC 37 07 03 30 83 27 47 62 +B2 40 22 44 93 E7 17 00 23 22 F7 62 41 01 82 80 +B7 07 03 30 05 47 23 A0 E7 62 82 80 37 17 02 30 +1C 43 85 8B F5 FF 82 80 0D 89 13 65 45 00 B7 17 +02 30 88 C7 82 80 B7 17 02 30 05 47 98 CF 82 80 +B7 17 02 30 DC 4F 85 8B 89 EB B7 06 04 30 37 17 +02 30 9C 42 5C 4F 85 8B ED DF 82 80 B7 17 02 30 +05 47 98 C3 82 80 B7 28 02 30 03 A8 C8 00 13 78 +18 00 E3 1C 08 FE 23 AE A8 00 23 A0 B8 02 23 A2 +E8 02 23 A4 F8 02 41 C6 B7 07 00 12 85 07 37 26 +02 30 1C C6 50 42 85 65 FD 15 6D 8E 13 75 C7 FF +93 57 27 00 42 06 41 82 36 95 37 27 02 30 99 CB +5C 47 91 83 ED 8F E3 8D C7 FE 9C 42 91 06 5C D7 +E3 98 A6 FE B7 27 02 30 DC 47 05 47 37 26 02 30 +93 F5 37 00 85 46 63 97 E5 00 5C 46 13 F7 37 00 +E3 0D D7 FE 89 8B 85 CB B7 07 02 50 03 A7 07 14 +41 11 06 C6 89 47 63 E1 E7 02 B7 27 02 30 09 47 +98 C7 05 45 EF 30 3F E7 B2 40 41 01 82 80 B7 07 +00 02 85 07 AD BF 82 80 37 35 02 50 13 05 45 0A +EF 30 7F E7 D9 BF 41 11 06 C6 37 23 02 30 83 28 +C3 00 93 F8 18 00 E3 9C 08 FE 23 2E A3 00 23 20 +B3 02 23 22 E3 02 23 24 F3 02 49 C2 B7 07 00 12 +85 07 37 26 02 30 1C C6 50 42 85 65 FD 15 6D 8E +13 75 C7 FF 93 57 27 00 42 06 41 82 36 95 37 27 +02 30 99 CB 5C 47 91 83 ED 8F E3 8D C7 FE 9C 42 +91 06 5C D7 E3 98 A6 FE B7 27 02 30 DC 47 05 47 +37 26 02 30 93 F5 37 00 85 46 63 97 E5 00 5C 46 +13 F7 37 00 E3 0D D7 FE 89 8B 8D C7 63 06 08 04 +B7 07 02 50 03 A7 07 14 89 47 63 E4 E7 04 B7 27 +02 30 09 47 98 C7 B2 40 41 01 82 80 B7 07 00 02 +85 07 41 B7 E3 09 08 FE 37 35 02 50 13 05 45 11 +EF 30 7F DB B7 27 02 30 09 47 98 C7 05 45 EF 30 +9F D8 B2 40 41 01 82 80 37 35 02 50 13 05 45 0D +C5 B7 37 35 02 50 13 05 45 0D EF 30 DF D8 45 BF +37 28 02 30 83 26 C8 00 85 8A ED FE 23 2E A8 00 +23 20 B8 02 23 22 E8 02 23 24 F8 02 01 CA B7 07 +00 12 85 07 37 27 02 30 1C C7 82 80 B7 07 00 02 +85 07 37 27 02 30 1C C7 82 80 B7 27 02 30 DC 43 +05 66 7D 16 F1 8F 13 F7 C5 FF 13 D8 25 00 93 96 +07 01 B3 05 E5 00 C1 82 37 27 02 30 63 0C 08 00 +5C 47 91 83 F1 8F E3 8D D7 FE 1C 41 11 05 5C D7 +E3 98 A5 FE 01 45 82 80 B7 28 02 30 03 A8 C8 00 +13 78 18 00 E3 1C 08 FE 23 AA A8 00 23 AC B8 00 +23 A2 E8 02 23 A4 F8 02 41 C2 B7 07 12 00 85 07 +37 26 02 30 1C C6 5C 42 09 83 15 C3 0A 07 05 66 +B3 85 E6 00 7D 16 37 27 02 30 5C 47 91 83 F1 8F +ED DF 1C 5B 91 06 23 AE F6 FE E3 98 B6 FE B7 27 +02 30 DC 47 05 47 93 F6 37 00 63 9A E6 00 37 26 +02 30 85 46 5C 46 13 F7 37 00 E3 0D D7 FE 89 8B +85 CB B7 07 02 50 03 A7 07 14 41 11 06 C6 89 47 +63 E1 E7 02 B7 27 02 30 09 47 98 C7 05 45 EF 30 +9F C5 B2 40 41 01 82 80 B7 07 02 00 85 07 49 B7 +82 80 37 35 02 50 13 05 45 0A EF 30 DF C5 D9 BF +41 11 06 C6 37 23 02 30 83 28 C3 00 93 F8 18 00 +E3 9C 08 FE 23 2A A3 00 23 2C B3 00 23 22 E3 02 +23 24 F3 02 2D CE B7 07 12 00 85 07 37 26 02 30 +1C C6 5C 42 09 83 15 C3 0A 07 05 66 B3 85 E6 00 +7D 16 37 27 02 30 5C 47 91 83 F1 8F ED DF 1C 5B +91 06 23 AE F6 FE E3 98 B6 FE B7 27 02 30 DC 47 +05 47 93 F6 37 00 63 9A E6 00 37 26 02 30 85 46 +5C 46 13 F7 37 00 E3 0D D7 FE 89 8B 8D C7 63 06 +08 04 B7 07 02 50 03 A7 07 14 89 47 63 E4 E7 04 +B7 27 02 30 09 47 98 C7 B2 40 41 01 82 80 B7 07 +02 00 85 07 61 B7 E3 09 08 FE 37 35 02 50 13 05 +45 11 EF 30 5F BA B7 27 02 30 09 47 98 C7 05 45 +EF 30 7F B7 B2 40 41 01 82 80 37 35 02 50 13 05 +45 0D C5 B7 37 35 02 50 13 05 45 0D EF 30 BF B7 +45 BF 37 28 02 30 83 26 C8 00 85 8A ED FE 23 2A +A8 00 23 2C B8 00 23 22 E8 02 23 24 F8 02 01 CA +B7 07 12 00 85 07 37 27 02 30 1C C7 82 80 B7 07 +02 00 85 07 37 27 02 30 1C C7 82 80 B7 27 02 30 +DC 43 93 D7 25 00 95 C3 8A 07 85 66 33 06 F5 00 +37 27 02 30 FD 16 5C 47 91 83 F5 8F ED DF 1C 5B +11 05 23 2E F5 FE E3 18 C5 FE 82 80 B7 08 02 30 +83 A8 08 00 41 11 06 C6 93 F8 18 00 63 8B 08 00 +B7 07 02 50 83 A7 07 14 A1 E3 B2 40 05 45 41 01 +82 80 91 C9 B7 07 02 50 83 A7 07 14 D1 EF 05 45 +EF 30 7F AB 01 A0 B7 05 04 00 E3 75 B5 FE B3 88 +A7 00 63 F2 F8 02 37 07 02 50 03 27 07 14 41 EB +05 45 EF 30 5F A9 01 A0 37 35 02 50 13 05 C5 15 +EF 30 7F AA 5D BF E3 F0 B8 FE B7 25 02 30 83 A8 +C5 00 93 F8 18 00 E3 9C 08 FE C8 C9 23 AC 05 00 +D0 CD 94 D1 DC D1 23 A4 05 03 31 C7 B7 07 00 11 +85 07 37 27 02 30 1C C7 5C 47 05 47 93 F6 37 00 +63 9A E6 00 37 26 02 30 85 46 5C 46 13 F7 37 00 +E3 0D D7 FE 89 8B 85 EF B2 40 B7 07 02 30 05 47 +98 D3 01 45 41 01 82 80 AA 85 41 65 13 05 45 5A +EF 30 7F A5 A9 BF B7 07 00 01 85 07 5D BF 2A 86 +41 65 BE 85 13 05 45 5D EF 30 FF A3 95 B7 37 35 +02 50 13 05 85 17 EF 30 1F A1 B7 27 02 30 09 47 +98 C7 05 45 EF 30 3F 9E 45 BF B7 08 02 30 83 A8 +08 00 41 11 06 C6 93 F8 18 00 63 8B 08 00 B7 07 +02 50 83 A7 07 14 A1 E3 B2 40 05 45 41 01 82 80 +91 CA B7 07 02 50 83 A7 07 14 A5 EF 05 45 EF 30 +9F 9A 01 A0 B7 06 04 00 E3 75 D6 FE B3 88 C7 00 +63 F2 F8 02 37 07 02 50 03 27 07 14 2D E7 05 45 +EF 30 7F 98 01 A0 37 35 02 50 13 05 C5 15 EF 30 +9F 99 5D BF E3 F0 D8 FE B7 28 02 30 83 A6 C8 00 +85 8A ED FE 23 AA A8 00 23 AC B8 00 23 AE C8 00 +23 A0 08 02 23 A2 F8 02 23 A4 08 03 15 C3 B7 07 +11 00 85 07 B2 40 37 27 02 30 1C C7 01 45 41 01 +82 80 41 65 B2 85 13 05 05 62 EF 30 DF 96 BD BF +C1 67 85 07 C5 B7 41 65 BE 85 13 05 05 65 EF 30 +9F 95 71 B7 41 11 06 C6 0D 3F B7 27 02 30 DC 47 +05 47 93 F6 37 00 63 9A E6 00 37 26 02 30 85 46 +5C 46 13 F7 37 00 E3 0D D7 FE 89 8B 99 CF B7 07 +02 50 03 A7 07 14 89 47 63 E0 E7 02 B7 27 02 30 +09 47 98 C7 05 45 EF 30 1F 8D B2 40 B7 07 02 30 +05 47 98 D3 41 01 82 80 37 35 02 50 13 05 45 0A +EF 30 7F 8D E1 BF 01 11 4E C6 B7 09 02 50 03 A7 +09 14 22 CC 26 CA 4A C8 06 CE 89 47 2A 89 AE 84 +32 84 63 E0 E7 0A B7 36 02 30 83 A7 86 80 37 27 +02 30 F9 9B 23 A4 F6 80 5C 47 85 8B F5 FF 23 2E +27 01 04 D3 B7 07 00 04 40 D3 85 07 1C C7 5C 47 +05 47 93 F6 37 00 63 9A E6 00 37 26 02 30 85 46 +5C 46 13 F7 37 00 E3 0D D7 FE 89 8B A9 C3 03 A7 +09 14 89 47 63 E6 E7 02 B7 27 02 30 09 47 98 C7 +37 37 02 30 83 27 87 80 F2 40 62 44 93 E7 17 00 +23 24 F7 80 D2 44 42 49 B2 49 01 45 05 61 82 80 +37 35 02 50 13 05 45 1D EF 30 FF 82 F1 B7 37 35 +02 50 13 05 85 20 EF 30 1F 82 05 45 EF 30 AF FF +01 A0 37 35 02 50 13 05 45 1B EF 30 DF 80 A1 BF +01 11 4E C6 B7 09 02 50 03 A7 09 14 22 CC 26 CA +4A C8 06 CE 89 47 2A 89 AE 84 32 84 63 E2 E7 06 +37 27 02 30 5C 47 85 8B F5 FF 23 2E 27 01 04 D3 +B7 07 00 04 40 D3 85 07 1C C7 5C 47 05 47 93 F6 +37 00 63 9A E6 00 37 26 02 30 85 46 5C 46 13 F7 +37 00 E3 0D D7 FE 89 8B 89 CF 03 A7 09 14 89 47 +63 E7 E7 02 B7 27 02 30 09 47 98 C7 05 45 EF 30 +8F F7 F2 40 62 44 D2 44 42 49 B2 49 05 61 82 80 +37 35 02 50 13 05 85 24 EF 30 EF F7 51 BF 37 35 +02 50 13 05 45 0A EF 30 0F F7 E9 B7 37 27 02 30 +5C 47 85 8B F5 FF 48 CF 0C D3 B7 07 00 04 50 D3 +85 07 1C C7 82 80 41 11 83 4E 01 01 06 C6 37 2E +02 30 03 23 CE 00 13 73 13 00 E3 1C 03 FE 23 2A +AE 00 23 2C BE 00 23 2E DE 00 23 20 EE 02 23 22 +0E 03 23 24 1E 03 B7 06 03 03 63 83 0E 06 95 06 +03 47 41 01 B3 37 F0 00 F2 07 33 37 E0 00 0E 07 +33 36 C0 00 D9 8F 52 06 D1 8F 37 27 02 30 D5 8F +1C C7 5C 47 05 47 93 F6 37 00 63 9A E6 00 37 26 +02 30 85 46 5C 46 13 F7 37 00 E3 0D D7 FE 89 8B +A1 C3 B7 07 02 50 03 A7 07 14 89 47 63 EC E7 00 +B2 40 B7 27 02 30 09 47 98 C7 01 45 41 01 82 80 +85 06 79 BF 37 35 02 50 13 05 45 1D EF 30 AF EA +B2 40 B7 27 02 30 09 47 98 C7 01 45 41 01 82 80 +37 35 02 50 13 05 85 20 EF 30 EF E8 05 45 EF 30 +8F E6 01 A0 41 11 83 4E 01 01 06 C6 37 2E 02 30 +03 23 CE 00 13 73 13 00 E3 1C 03 FE 23 2A AE 00 +23 2C BE 00 23 2E DE 00 23 20 EE 02 23 22 0E 03 +23 24 1E 03 B7 06 03 03 63 85 0E 06 95 06 03 47 +41 01 B3 37 F0 00 F2 07 33 37 E0 00 0E 07 33 36 +C0 00 D9 8F 52 06 D1 8F 37 27 02 30 D5 8F 1C C7 +5C 47 05 47 93 F6 37 00 63 9A E6 00 37 26 02 30 +85 46 5C 46 13 F7 37 00 E3 0D D7 FE 89 8B 99 CF +B7 07 02 50 03 A7 07 14 89 47 63 EE E7 00 B7 27 +02 30 09 47 98 C7 05 45 EF 30 EF DC B2 40 41 01 +82 80 85 06 69 BF 37 35 02 50 13 05 45 0A EF 30 +8F DD F1 BF 41 11 03 4F 01 01 83 4E 81 01 06 C6 +37 2E 02 30 03 23 CE 00 13 73 13 00 E3 1C 03 FE +23 2A AE 00 23 2C BE 00 23 2E DE 00 23 20 EE 02 +23 22 0E 03 23 24 1E 03 B7 06 03 03 63 04 0F 06 +95 06 03 47 41 01 B3 37 F0 00 F2 07 33 37 E0 00 +0E 07 33 36 C0 00 D9 8F 52 06 D1 8F 37 27 02 30 +D5 8F 1C C7 5C 47 05 47 93 F6 37 00 63 9A E6 00 +37 26 02 30 85 46 5C 46 13 F7 37 00 E3 0D D7 FE +89 8B 9D C3 63 84 0E 04 B7 07 02 50 03 A7 07 14 +89 47 63 E2 E7 04 B7 27 02 30 09 47 98 C7 B2 40 +41 01 82 80 85 06 71 BF E3 8B 0E FE 37 35 02 50 +13 05 45 11 EF 30 2F D2 B7 27 02 30 09 47 98 C7 +05 45 EF 30 4F CF B2 40 41 01 82 80 37 35 02 50 +13 05 45 0D C5 B7 37 35 02 50 13 05 45 0D EF 30 +8F CF 55 BF 83 4E 01 00 37 2E 02 30 03 23 CE 00 +13 73 13 00 E3 1C 03 FE 23 2A AE 00 23 2C BE 00 +23 2E DE 00 23 20 EE 02 23 22 0E 03 23 24 1E 03 +B7 06 03 03 63 85 0E 02 95 06 03 47 41 00 B3 37 +F0 00 33 36 C0 00 52 06 F2 07 33 37 E0 00 D1 8F +0E 07 D9 8F D5 8F 37 27 02 30 1C C7 82 80 85 06 +E9 BF B7 27 02 30 DC 47 41 11 22 C4 06 C6 05 47 +93 F6 37 00 2A 84 63 9A E6 00 37 26 02 30 85 46 +5C 46 13 F7 37 00 E3 0D D7 FE 89 8B 99 CF B7 07 +02 50 03 A7 07 14 89 47 63 E2 E7 02 B7 27 02 30 +09 47 98 C7 05 45 EF 30 0F C3 09 C4 B7 07 02 30 +05 47 98 D3 B2 40 22 44 41 01 82 80 37 35 02 50 +13 05 45 0A EF 30 2F C3 B7 27 02 30 09 47 98 C7 +05 45 EF 30 4F C0 D1 BF B7 27 02 30 DC 47 41 11 +22 C4 06 C6 05 47 93 F6 37 00 2A 84 63 9A E6 00 +37 26 02 30 85 46 5C 46 13 F7 37 00 E3 0D D7 FE +89 8B A9 C3 B7 07 02 50 03 A7 07 14 89 47 63 EF +E7 00 B7 27 02 30 09 47 98 C7 09 C4 B7 07 02 30 +05 47 98 D3 B2 40 22 44 41 01 82 80 37 35 02 50 +13 05 45 1D EF 30 2F BC B7 27 02 30 09 47 98 C7 +71 FC CD B7 37 35 02 50 13 05 85 20 EF 30 AF BA +05 45 EF 30 4F B8 01 A0 1D 71 A6 CA 86 CE A2 CC +CA C8 CE C6 D2 C4 D6 C2 DA C0 5E DE 62 DC 66 DA +6A D8 6E D6 95 47 AA 84 63 01 F5 22 C5 47 63 02 +F5 12 99 47 63 19 F5 2A 8D 47 B7 49 44 23 37 0B +03 03 37 0C 44 23 3E C6 3E CA 8D 09 05 49 A5 47 +63 97 F4 42 41 64 7D 14 37 0A 03 30 EF 00 50 5F +93 57 F5 41 C1 83 33 07 F5 00 61 8F 1D 8F 83 27 +8A 54 0D 07 93 7D C7 FF E3 82 FD FE 02 C4 02 CE +BD 47 CA 8C 4E 84 63 9E F4 22 CD 47 4D 4D 3E C8 +02 CC 93 8B 24 FF 93 BB 1B 00 13 99 2B 00 B7 09 +02 50 03 A6 09 14 11 4A 63 63 CA 0E B7 35 02 30 +83 A7 85 80 B7 26 02 30 F9 9B 23 A4 F5 80 DC 46 +85 8B F5 FF 89 47 63 E3 C7 0A B7 27 02 30 23 AA +87 01 22 47 85 46 94 CF C0 CF 23 A0 97 03 33 69 +27 01 23 A2 B7 03 33 67 69 01 23 A4 A7 03 13 67 +17 00 98 C7 DC 47 13 F7 37 00 63 19 D7 00 37 26 +02 30 5C 46 13 F7 37 00 E3 0D D7 FE 89 8B B5 C7 +03 A7 09 14 89 47 63 EF E7 18 B7 27 02 30 09 47 +98 C7 37 37 02 30 83 27 87 80 F6 40 66 44 93 E7 +17 00 23 24 F7 80 D6 44 46 49 B6 49 26 4A 96 4A +06 4B F2 5B 62 5C D2 5C 42 5D B2 5D 01 45 25 61 +82 80 85 47 41 6B 3E C6 02 CA 91 69 01 49 02 C4 +37 0C 44 23 02 CE 93 0D 00 04 19 BF 37 35 02 50 +13 05 05 26 EF 30 2F A3 89 BF 37 35 02 50 13 05 +85 20 EF 30 4F A2 05 45 EF 30 EF 9F 01 A0 C1 6A +93 8A 4A 28 A6 85 13 85 4A 41 EF 30 CF A2 03 A6 +09 14 E3 75 CA F0 62 86 85 45 13 85 CA 42 EF 30 +8F A1 03 A6 09 14 E3 7B CA EE 22 86 E6 85 13 85 +CA 44 EF 30 4F A0 03 A6 09 14 E3 71 CA EE B2 45 +13 85 CA 46 EF 30 2F 9F 03 A6 09 14 E3 78 CA EC +D2 45 13 85 4A 48 EF 30 0F 9E 03 A6 09 14 E3 7F +CA EA F2 45 13 85 CA 49 EF 30 EF 9C 03 A6 09 14 +E3 76 CA EA E2 45 13 85 4A 4B EF 30 CF 9B 03 A6 +09 14 E3 7D CA E8 DE 85 13 85 CA 4C EF 30 AF 9A +03 A6 09 14 E3 74 CA E8 EE 85 13 85 4A 4E EF 30 +8F 99 03 A6 09 14 E3 7B CA E6 C2 45 13 85 CA 4F +EF 30 6F 98 03 A6 09 14 95 B5 B7 07 03 30 03 A9 +47 54 83 A9 07 54 37 0C 44 23 8D 47 CA 8C 4E 84 +0D 0C 37 0B 03 00 3E C6 89 47 63 F6 97 1E 13 87 +D4 FF 85 47 B3 97 E7 00 93 F7 17 4D 3E CA 63 9F +07 1C AD 47 63 86 F4 22 91 47 63 8E F4 18 37 07 +00 03 B9 47 33 6B EB 00 63 99 F4 20 EF 00 50 3B +B7 07 10 00 3E C4 8D 47 3E CA 85 47 3E CE 93 0D +00 04 F9 B3 37 35 02 50 13 05 45 1D EF 30 AF 8E +A9 BD 02 CC C1 47 63 8A F4 00 91 47 63 92 F4 18 +11 49 01 4D 02 C8 85 4B D9 B3 91 47 11 49 11 4D +3E C8 85 4B 6D BB 9D 47 63 1A F5 04 B7 07 03 30 +03 AA 47 54 03 A4 07 54 EF 00 90 35 2A 89 EF 00 +30 35 93 57 F5 41 13 57 E5 01 8A 07 0A 09 D9 8F +0A 05 AA 89 33 69 F9 00 63 14 A4 00 E3 0E 2A FD +CA 8C 2A 84 C5 47 63 EB 97 10 37 07 02 50 93 97 +24 00 13 07 47 69 BA 97 9C 43 82 87 B7 07 03 30 +83 AC 47 54 83 A9 07 54 AD 47 66 89 4E 84 63 12 +F5 02 B7 07 10 00 3E C4 89 47 3E CA 85 47 37 0B +00 02 37 0C 44 23 02 C6 3E CE 02 CC 93 0D 00 04 +91 BF 09 47 89 47 3A C6 3A CA 37 0B 02 02 E3 00 +F5 DE 4D B7 37 0C 44 23 01 4B 02 C6 F1 BD EF 00 +30 2C 8D 47 B3 67 F5 02 91 46 37 0C 44 23 37 07 +00 04 36 CA 85 07 3E C6 13 9B 07 01 33 6B EB 00 +93 87 44 FF 05 47 63 68 F7 06 B7 07 00 10 33 6B +FB 00 85 47 02 C4 01 4D 02 C8 3E CC 93 0D 00 04 +02 CE C1 B1 89 47 02 C4 37 0B 02 00 37 0C 44 23 +3E C6 02 CA 02 CE 93 0D 00 04 59 B9 85 47 41 6B +37 0C 44 23 3E C6 02 CA 99 B9 89 47 3E C6 85 47 +37 0B 02 10 02 C4 37 0C 44 23 02 CA 02 CE 3E CC +93 0D 00 04 45 BD 91 47 37 0B 00 04 37 0C 44 23 +3E CA 02 C6 05 B9 A1 47 E3 93 F4 C2 02 C4 01 4D +02 C8 02 CC 93 0D 30 04 02 CE A1 B9 B5 47 37 0C +44 23 37 0B 03 00 63 EF 97 04 8D 47 3E C6 29 BD +01 4D 02 C8 3D B9 85 47 63 89 F4 00 B7 07 00 04 +33 6B FB 00 91 47 3E CA A1 B7 EF 00 70 1E AD 47 +B3 67 F5 02 95 07 3E CA 13 97 87 01 05 BF 02 C4 +02 CE A9 47 E3 95 F4 E2 B7 07 03 30 03 A7 87 54 +CA 8C 4E 84 93 1D 07 01 93 DD 0D 01 01 4D 02 C8 +02 CC C5 BE 8D 47 3E C6 DD B3 8D 47 3E CA 09 B7 +B7 07 00 02 33 6B FB 00 B7 07 10 00 3E C4 89 47 +3E CA 85 47 3E CE 75 BF B7 27 02 30 DC 47 41 11 +22 C4 06 C6 93 F6 37 00 05 47 2A 84 63 9A E6 00 +37 26 02 30 85 46 5C 46 13 F7 37 00 E3 0D D7 FE +89 8B 95 C7 A1 C5 B7 07 02 50 03 A7 07 14 89 47 +63 E3 E7 04 B7 27 02 30 09 47 98 C7 09 C4 B7 07 +02 30 05 47 98 D3 B2 40 22 44 41 01 82 80 FD D5 +37 35 02 50 13 05 45 11 EF 20 FF E7 B7 27 02 30 +09 47 98 C7 05 45 EF 20 1F E5 C9 BF 37 35 02 50 +13 05 45 0D D5 B7 37 35 02 50 13 05 45 0D EF 20 +9F E5 4D BF 53 4F 43 5F 49 46 43 3A 20 43 6C 65 +61 72 20 65 78 65 63 75 74 65 20 72 65 67 00 00 +53 4F 43 5F 49 46 43 3A 20 43 68 65 63 6B 20 6D +62 6F 78 5F 73 74 61 74 75 73 2E 6D 62 6F 78 5F +66 73 6D 5F 70 73 20 66 6F 75 6E 64 20 75 6E 65 +78 70 65 63 74 65 64 20 73 74 61 74 65 20 30 78 +25 78 0A 00 53 4F 43 5F 49 46 43 3A 20 53 65 74 +20 6D 62 6F 78 5F 73 74 61 74 75 73 20 66 69 65 +6C 64 3A 20 30 78 25 78 0A 00 00 00 53 4F 43 5F +49 46 43 3A 20 53 65 74 20 66 6C 6F 77 5F 73 74 +61 74 75 73 20 66 69 65 6C 64 3A 20 30 78 25 78 +0A 00 00 00 53 4F 43 5F 49 46 43 3A 20 43 6C 65 +61 72 20 53 48 41 20 61 63 63 65 6C 65 72 61 74 +6F 72 20 6C 6F 63 6B 20 62 79 20 77 72 69 74 69 +6E 67 20 27 31 3A 20 30 78 25 78 0A 00 00 00 00 +53 4F 43 5F 49 46 43 3A 20 42 61 64 20 66 69 65 +6C 64 20 76 61 6C 75 65 00 00 00 00 53 4F 43 5F +49 46 43 3A 20 42 61 64 20 66 69 65 6C 64 20 76 +61 6C 75 65 00 00 00 00 53 4F 43 5F 49 46 43 3A +20 43 6C 65 61 72 20 66 6C 6F 77 5F 73 74 61 74 +75 73 20 66 69 65 6C 64 3A 20 30 78 25 78 0A 00 +53 4F 43 5F 49 46 43 3A 20 43 4D 44 20 66 72 6F +6D 20 6D 61 69 6C 62 6F 78 3A 20 30 78 25 78 0A +00 00 00 00 53 4F 43 5F 49 46 43 3A 20 44 4C 45 +4E 20 66 72 6F 6D 20 6D 61 69 6C 62 6F 78 3A 20 +30 78 25 78 0A 00 00 00 46 41 54 41 4C 3A 20 49 +6E 76 61 6C 69 64 20 64 6C 65 6E 20 70 61 73 73 +65 64 20 74 6F 20 6D 62 6F 78 20 66 77 20 66 6C +6F 77 3A 20 30 78 25 78 0A 00 00 00 46 41 54 41 +4C 3A 20 49 6E 76 61 6C 69 64 20 63 6D 64 20 70 +61 73 73 65 64 20 74 6F 20 6D 62 6F 78 20 66 77 +20 66 6C 6F 77 3A 20 30 78 25 78 0A 00 00 00 00 +46 6F 75 6E 64 20 69 6E 76 61 6C 69 64 20 69 63 +63 6D 20 73 69 7A 65 20 69 6E 20 66 69 72 6D 77 +61 72 65 20 69 6D 61 67 65 20 72 65 63 65 69 76 +65 64 20 66 72 6F 6D 20 53 4F 43 21 20 4D 61 78 +20 65 78 70 65 63 74 65 64 20 30 78 25 78 2C 20 +67 6F 74 20 30 78 25 78 0A 00 00 00 46 6F 75 6E +64 20 69 6E 76 61 6C 69 64 20 64 63 63 6D 20 73 +69 7A 65 20 69 6E 20 66 69 72 6D 77 61 72 65 20 +69 6D 61 67 65 20 72 65 63 65 69 76 65 64 20 66 +72 6F 6D 20 53 4F 43 21 20 4D 61 78 20 65 78 70 +65 63 74 65 64 20 30 78 25 78 2C 20 67 6F 74 20 +30 78 25 78 0A 00 00 00 61 74 20 25 78 3A 20 25 +78 0A 00 00 53 4F 43 5F 49 46 43 3A 20 49 6C 6C +65 67 61 6C 20 62 79 74 65 5F 63 6F 75 6E 74 20 +30 78 25 78 0A 00 00 00 53 4F 43 5F 49 46 43 3A +20 53 65 74 20 66 77 20 75 70 64 61 74 65 20 72 +65 73 65 74 20 77 69 74 68 20 77 61 69 74 5F 63 +79 63 6C 65 73 20 5B 25 64 5D 20 28 25 73 29 0A +00 00 00 00 73 72 63 5F 61 64 64 72 20 30 78 25 +78 20 69 73 20 6F 75 74 20 6F 66 20 62 6F 75 6E +64 73 20 66 6F 72 20 6D 62 6F 78 20 73 70 61 6E +21 0A 00 00 72 65 61 64 69 6E 67 20 30 78 25 78 +20 62 79 74 65 73 20 66 72 6F 6D 20 73 72 63 5F +61 64 64 72 20 30 78 25 78 20 67 6F 65 73 20 6F +75 74 20 6F 66 20 62 6F 75 6E 64 73 20 66 6F 72 +20 6D 62 6F 78 20 73 70 61 6E 21 0A 00 00 00 00 +64 73 74 5F 61 64 64 72 20 30 78 25 78 20 69 73 +20 6F 75 74 20 6F 66 20 62 6F 75 6E 64 73 20 66 +6F 72 20 6D 62 6F 78 20 73 70 61 6E 21 0A 00 00 +77 72 69 74 69 6E 67 20 30 78 25 78 20 62 79 74 +65 73 20 74 6F 20 64 73 74 5F 61 64 64 72 20 30 +78 25 78 20 67 6F 65 73 20 6F 75 74 20 6F 66 20 +62 6F 75 6E 64 73 20 66 6F 72 20 6D 62 6F 78 20 +73 70 61 6E 21 0A 00 00 70 61 72 61 6D 3A 20 65 +72 72 5F 74 79 70 65 20 20 20 30 78 25 78 0A 00 +70 61 72 61 6D 3A 20 73 72 63 5F 61 64 64 72 20 +20 20 30 78 25 78 20 30 78 25 78 0A 00 00 00 00 +70 61 72 61 6D 3A 20 64 73 74 5F 61 64 64 72 20 +20 20 30 78 25 78 20 30 78 25 78 0A 00 00 00 00 +70 61 72 61 6D 3A 20 72 64 5F 72 6F 75 74 65 20 +20 20 30 78 25 78 0A 00 70 61 72 61 6D 3A 20 77 +72 5F 72 6F 75 74 65 20 20 20 30 78 25 78 0A 00 +70 61 72 61 6D 3A 20 72 64 5F 66 69 78 65 64 20 +20 20 30 78 25 78 0A 00 70 61 72 61 6D 3A 20 77 +72 5F 66 69 78 65 64 20 20 20 30 78 25 78 0A 00 +70 61 72 61 6D 3A 20 61 65 73 5F 6D 6F 64 65 20 +20 20 30 78 25 78 0A 00 70 61 72 61 6D 3A 20 62 +79 74 65 5F 63 6F 75 6E 74 20 30 78 25 78 0A 00 +70 61 72 61 6D 3A 20 62 6C 6F 63 6B 5F 73 69 7A +65 20 30 78 25 78 0A 00 B7 06 02 50 83 A7 C6 6D +13 97 D7 00 3D 8F 93 57 17 01 B9 8F 13 95 57 00 +3D 8D 23 AE A6 6C 82 80 B7 07 02 50 03 A7 07 14 +41 11 22 C4 26 C2 06 C6 89 47 AA 84 2E 84 63 E3 +E7 02 73 50 20 7D 73 90 34 7D 73 D0 41 7D 73 10 +44 30 73 50 04 30 73 D0 61 7C B2 40 22 44 92 44 +41 01 82 80 37 35 02 50 13 05 45 27 EF 20 BF 8D +C9 BF 73 50 20 7D 73 10 35 7D 73 D0 41 7D 73 90 +45 30 73 50 04 30 82 80 73 D0 61 7C 82 80 B7 07 +03 30 23 A6 A7 0E 23 A8 B7 0E 82 80 B7 07 03 30 +23 AE A7 0E 23 A0 B7 10 82 80 B7 07 03 30 7D 57 +23 A6 E7 0E 23 A8 E7 0E 82 80 B7 07 03 30 7D 57 +23 AE E7 0E 23 A0 E7 10 82 80 37 17 03 30 83 27 +47 81 93 F7 07 04 E5 DF 93 07 00 04 23 2A F7 80 +82 80 37 17 03 30 83 27 47 81 93 F7 07 08 E5 DF +93 07 00 08 23 2A F7 80 82 80 B7 07 03 30 23 A6 +A7 0E 23 A8 B7 0E 23 AE C7 0E 23 A0 D7 10 05 47 +23 A2 E7 0E 23 A4 E7 0E 82 80 01 11 06 CE 0D E1 +B7 07 02 50 03 A7 07 14 89 47 63 E2 E7 08 B7 07 +03 30 23 A2 07 0E 23 AA 07 0E F2 40 05 61 82 80 +85 47 63 01 F5 04 89 47 E3 19 F5 FE B7 07 02 50 +83 A7 07 14 63 6F F5 06 B7 07 03 30 23 A6 B7 0E +23 A8 C7 0E 23 AE D7 0E 23 A0 E7 10 05 47 23 A2 +E7 0E 23 AA E7 0E F2 40 23 A4 E7 0E 23 AC E7 0E +05 61 82 80 B7 07 02 50 03 A6 07 14 89 47 63 E7 +C7 02 B7 07 03 30 23 AE D7 0E 23 A0 E7 10 F2 40 +05 47 23 AA E7 0E 23 AC E7 0E 05 61 82 80 37 35 +02 50 13 05 C5 28 EF 20 0F F9 95 BF 37 35 02 50 +13 05 85 2B 3A C2 36 C0 EF 20 EF F7 12 47 82 46 +C9 B7 37 35 02 50 13 05 45 2E 3A C6 36 C4 32 C2 +2E C0 EF 20 4F F6 32 47 A2 46 12 46 82 45 AD B7 +B3 47 B5 00 8D 8B B3 08 C5 00 B1 E7 8D 47 63 F4 +C7 04 93 77 35 00 2A 87 B9 EB 13 F6 C8 FF B3 06 +E6 40 93 07 00 02 63 C8 D7 06 AE 86 BA 87 63 71 +C7 02 03 A8 06 00 91 07 91 06 23 AE 07 FF E3 EA +C7 FE 93 07 F6 FF 99 8F F1 9B 91 07 3E 97 BE 95 +63 66 17 01 82 80 2A 87 63 7E 15 03 83 C7 05 00 +05 07 85 05 A3 0F F7 FE E3 9A E8 FE 82 80 83 C6 +05 00 05 07 93 77 37 00 A3 0F D7 FE 85 05 D1 DF +83 C6 05 00 05 07 93 77 37 00 A3 0F D7 FE 85 05 +F9 FF 61 B7 82 80 41 11 22 C6 13 04 00 02 83 A3 +05 00 83 A2 45 00 83 AF 85 00 03 AF C5 00 83 AE +05 01 03 AE 45 01 03 A3 85 01 03 A8 C5 01 94 51 +13 07 47 02 B3 07 E6 40 23 2E 77 FC 23 20 57 FE +23 22 F7 FF 23 24 E7 FF 23 26 D7 FF 23 28 C7 FF +23 2A 67 FE 23 2C 07 FF 23 2E D7 FE 93 85 45 02 +E3 47 F4 FA AE 86 BA 87 63 71 C7 02 03 A8 06 00 +91 07 91 06 23 AE 07 FF E3 EA C7 FE 93 07 F6 FF +99 8F F1 9B 91 07 3E 97 BE 95 63 65 17 01 32 44 +41 01 82 80 83 C7 05 00 05 07 85 05 A3 0F F7 FE +E3 87 E8 FE 83 C7 05 00 05 07 85 05 A3 0F F7 FE +E3 92 E8 FE E9 BF 3D 43 2A 87 63 73 C3 02 93 77 +F7 00 BD EF AD E5 93 76 06 FF 3D 8A BA 96 0C C3 +4C C3 0C C7 4C C7 41 07 E3 6B D7 FE 11 E2 82 80 +B3 06 C3 40 8A 06 97 02 00 00 96 96 67 80 A6 00 +23 07 B7 00 A3 06 B7 00 23 06 B7 00 A3 05 B7 00 +23 05 B7 00 A3 04 B7 00 23 04 B7 00 A3 03 B7 00 +23 03 B7 00 A3 02 B7 00 23 02 B7 00 A3 01 B7 00 +23 01 B7 00 A3 00 B7 00 23 00 B7 00 82 80 93 F5 +F5 0F 93 96 85 00 D5 8D 93 96 05 01 D5 8D 61 B7 +93 96 27 00 97 02 00 00 96 96 86 82 E7 80 86 FA +96 80 C1 17 1D 8F 3E 96 E3 74 C3 F8 A5 B7 B7 37 +02 50 83 A7 47 31 23 A4 A7 0A 23 A6 07 0A 82 80 +B7 37 02 50 03 A8 47 31 B7 85 95 4C 93 85 D5 F2 +83 26 88 0A 03 27 C8 0A B3 87 B6 02 13 86 17 00 +B3 37 F6 00 23 24 C8 0A 37 F6 51 58 13 06 D6 42 +33 86 C6 02 33 07 B7 02 B3 B6 B6 02 32 97 36 97 +BA 97 13 95 17 00 23 26 F8 0A 05 81 82 80 93 77 +35 00 2A 87 9D EF B7 86 7F 7F 93 86 F6 F7 FD 55 +10 43 11 07 B3 77 D6 00 B6 97 D1 8F D5 8F E3 89 +B7 FE 83 46 C7 FF B3 07 A7 40 8D CA 83 46 D7 FF +9D C2 03 45 E7 FF 33 35 A0 00 3E 95 79 15 82 80 +F9 D2 83 47 07 00 05 07 93 76 37 00 F5 FB 09 8F +13 05 F7 FF 82 80 13 85 D7 FF 82 80 13 85 C7 FF +82 80 13 01 01 BC 23 2A 91 42 23 28 21 43 23 20 +61 43 23 2C 81 41 23 2E 11 42 23 2C 81 42 23 26 +31 43 23 24 41 43 23 22 51 43 23 2E 71 41 23 2A +91 41 23 28 A1 41 23 26 B1 41 85 47 36 8B 2A 89 +2E 8C B2 84 63 F1 D7 2E 01 46 85 4C 85 46 FD 5B +09 A8 B3 8C 77 41 3E 86 85 46 B3 07 D6 00 63 F7 +67 03 33 87 74 01 36 97 B3 85 F4 00 83 C5 05 00 +03 47 07 00 E3 EF E5 FC 63 86 E5 14 B2 8B 85 46 +05 06 B3 07 D6 00 85 4C E3 ED 67 FD 81 45 05 48 +05 46 7D 55 05 47 09 A8 33 08 A7 40 BA 85 05 46 +33 87 C5 00 63 77 67 03 B3 87 C4 00 B3 86 E4 00 +AA 97 83 C6 06 00 83 C7 07 00 E3 EF D7 FC 63 87 +D7 10 2E 85 05 46 85 05 33 87 C5 00 05 48 E3 6D +67 FD 05 05 85 0B 63 64 75 01 C2 8C AA 8B 8A 87 +13 07 01 40 23 A0 67 01 91 07 E3 9D E7 FE 63 05 +0B 02 13 06 FB FF B3 05 9B 00 26 87 26 96 83 47 +07 00 B3 06 E6 40 05 07 8A 07 93 87 07 40 8A 97 +23 A0 D7 C0 E3 95 E5 FE 5E 86 B3 85 94 01 26 85 +C9 26 63 1F 05 10 85 69 93 89 09 80 05 4A 81 4D +01 44 B3 06 6C 41 B3 69 3B 01 13 0D FB FF 33 0A +7A 41 B3 0A 9B 41 63 E8 86 02 33 06 89 00 B3 07 +A6 01 83 C7 07 00 8A 07 93 87 07 40 8A 97 83 A7 +07 C0 AD CB 63 85 0D 00 63 F3 97 01 D6 87 3E 94 +81 4D E3 FC 86 FC 33 05 89 01 CE 85 6D 21 2A 9C +B3 06 6C 41 E3 F3 86 FC 01 45 83 20 C1 43 03 24 +81 43 83 24 41 43 03 29 01 43 83 29 C1 42 03 2A +81 42 83 2A 41 42 03 2B 01 42 83 2B C1 41 03 2C +81 41 83 2C 41 41 03 2D 01 41 83 2D C1 40 13 01 +01 44 82 80 63 8A 96 15 85 06 41 BD 63 03 C8 14 +05 06 F9 B5 6E 87 63 F3 7D 01 5E 87 63 70 A7 03 +B3 07 E4 00 33 88 E4 00 CA 97 03 45 08 00 83 C7 +07 00 63 11 F5 04 05 07 E3 64 A7 FF 13 87 FB FF +63 E6 7D 01 39 AA 63 81 ED 02 2A 87 B3 07 E4 00 +B3 85 E4 00 CA 97 83 C5 05 00 83 C7 07 00 13 05 +F7 FF E3 82 F5 FE 05 07 85 0D 63 6A B7 0F 66 94 +D6 8D 11 BF E3 74 A7 FD 52 94 3A 94 81 4D 21 B7 +33 0A 7B 41 63 65 7A 0D 05 64 13 04 04 80 85 49 +05 0A 81 4A B3 06 6C 41 33 64 8B 00 93 0C FB FF +B3 89 79 41 7D 5D 63 E2 56 03 33 05 59 01 B3 07 +95 01 83 C7 07 00 8A 07 93 87 07 40 8A 97 83 A7 +07 C0 95 CB BE 9A E3 F2 56 FF 33 05 89 01 A2 85 +59 2E 2A 9C B3 06 6C 41 E3 E8 56 EF 33 05 59 01 +B3 07 95 01 83 C7 07 00 8A 07 93 87 07 40 8A 97 +83 A7 07 C0 E1 FB 5E 87 63 E6 9B 01 25 A0 05 07 +63 72 97 03 B3 07 57 01 B3 85 E4 00 CA 97 03 C6 +05 00 83 C7 07 00 E3 04 F6 FE 63 75 97 01 CE 9A +BA 9A 51 B7 93 87 FB FF 63 95 A7 01 79 BD E3 8E +A7 E9 33 87 FA 00 33 86 F4 00 4A 97 03 46 06 00 +03 47 07 00 FD 17 E3 04 E6 FE D2 9A A9 BF 5E 8A +25 BF C2 95 05 46 69 B3 36 96 85 46 3D BB 32 85 +AD B5 5E 87 11 B7 85 4C 81 4B 55 BB 1D 71 A2 CC +A6 CA 86 CE CA C8 CE C6 D2 C4 AE 84 83 C5 05 00 +2A 84 E1 C1 03 C6 14 00 63 0E 06 12 03 C7 24 00 +71 C3 03 C5 34 00 63 02 05 14 83 C7 44 00 E1 CF +26 85 EF F0 DF C3 2A 89 93 65 05 20 22 85 65 2C +63 6A 25 0F 93 07 E0 0F 63 E8 27 15 B3 09 25 41 +13 06 00 04 93 05 19 00 0A 85 A2 99 EF F0 BF B0 +63 06 09 02 13 76 F9 0F 26 87 B3 05 99 00 26 96 +83 47 07 00 B3 06 E6 40 05 07 93 F7 F7 03 93 87 +07 04 8A 97 23 80 D7 FC E3 94 E5 FE 7D 14 B3 07 +24 01 83 C7 07 00 93 F7 F7 03 93 87 07 04 8A 97 +83 C7 07 FC 3E 94 63 F6 89 00 79 A0 52 94 63 E5 +89 08 B3 07 24 01 83 C7 07 00 22 85 4A 86 93 F7 +F7 03 93 87 07 04 8A 97 A6 85 03 CA 07 FC D5 20 +71 FD F6 40 22 85 66 44 D6 44 46 49 B6 49 26 4A +25 61 82 80 03 47 05 00 C2 05 D1 8D 81 47 39 C3 +C2 07 A2 86 D9 8F 05 04 03 47 04 00 E3 99 F5 FE +13 84 F6 FF F9 B7 93 97 85 01 42 06 83 46 04 00 +D1 8F C9 8F 22 07 D9 8F 91 CE 01 47 19 A0 63 83 +E7 04 22 86 22 07 05 04 55 8F 83 46 04 00 E5 FA +63 8A E7 02 01 44 71 BF 33 85 29 01 83 47 05 00 +F5 DB 85 65 93 85 05 80 7D 22 AA 99 E3 F0 89 F4 +01 44 41 B7 66 44 F6 40 D6 44 46 49 B6 49 26 4A +25 61 4D A0 13 04 D6 FF AD B7 83 46 04 00 93 97 +85 01 42 06 D1 8F 22 07 D9 8F CD DE 01 47 11 A0 +D5 DA 55 8F 22 86 22 07 05 04 83 46 04 00 E3 19 +F7 FE 13 04 E6 FF 35 BF AA 85 22 85 66 44 F6 40 +B6 49 26 4A CA 86 26 86 46 49 D6 44 25 61 6F F0 +5F B2 8D 47 63 F3 C7 02 B3 67 B5 00 8D 8B 8D 46 +89 CB 93 06 F6 FF 29 A8 71 16 11 05 91 05 63 F6 +C6 00 18 41 9C 41 E3 09 F7 FE 93 06 F6 FF 0D C2 +85 06 AE 96 19 A0 63 8D D5 00 83 47 05 00 03 C7 +05 00 05 05 85 05 E3 88 E7 FE 33 85 E7 40 82 80 +01 45 82 80 93 F6 F5 0F 93 77 35 00 C1 CE 91 CB +83 47 05 00 D1 C7 63 86 D7 08 05 05 93 77 35 00 +E5 FB 93 F5 F5 0F 93 97 85 00 AE 97 18 41 13 93 +07 01 33 63 F3 00 37 08 FF FE 33 46 E3 00 13 08 +F8 EF B3 07 07 01 B3 05 06 01 13 47 F7 FF 13 46 +F6 FF F9 8F B7 88 80 80 33 F7 C5 00 D9 8F 93 88 +08 08 B3 F7 17 01 85 E7 58 41 11 05 33 46 67 00 +B3 07 07 01 B3 05 06 01 13 47 F7 FF 13 46 F6 FF +F9 8F 33 F7 C5 00 D9 8F B3 F7 17 01 F1 DF 83 47 +05 00 99 C7 63 80 F6 06 83 47 15 00 05 05 FD FB +01 45 82 80 81 CB 83 47 05 00 E5 DF 05 05 93 77 +35 00 F5 FB 18 41 37 06 FF FE 13 06 F6 EF 93 47 +F7 FF B7 86 80 80 32 97 F9 8F 93 86 06 08 F5 8F +91 EB 58 41 11 05 B3 07 C7 00 13 47 F7 FF F9 8F +F5 8F E5 DB 83 47 05 00 CD DF 83 47 15 00 05 05 +ED FF 82 80 82 80 B3 06 B5 00 AA 87 89 E5 29 A8 +85 07 63 88 F6 00 03 C7 07 00 7D FB 33 85 A7 40 +82 80 33 85 A6 40 82 80 01 45 82 80 +@000112A4 +78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 +78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 +78 78 78 78 78 78 78 78 0A 20 20 20 54 52 41 50 +20 56 45 43 54 4F 52 20 45 58 45 43 55 54 49 4E +47 21 20 4B 49 4C 4C 20 53 49 4D 21 21 21 20 20 +20 0A 78 78 78 78 78 78 78 78 78 78 78 78 78 78 +78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 +78 78 78 78 78 78 78 78 78 78 0A 00 00 00 00 80 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 08 00 00 DF BB 8A AE +8F 00 DF B0 FF 7D 0D 9C E9 8E C6 39 1A BF 99 F1 +34 54 29 31 61 D2 D8 6F 02 7F 1A C2 EE 64 6C 58 +44 46 BE F6 1B E8 3C EC F3 DB FF A8 1D BD 3B 1C +89 FE 23 D6 25 3E 7E 02 D8 ED B0 93 CC 00 03 30 +03 00 00 00 84 2C 00 00 DE 2B 00 00 DE 2B 00 00 +DE 2B 00 00 DE 2B 00 00 DE 2B 00 00 DE 2B 00 00 +DE 2B 00 00 DE 2B 00 00 DE 2B 00 00 DE 2B 00 00 +C4 2D 00 00 50 2D 00 00 DE 2B 00 00 DE 2B 00 00 +DE 2B 00 00 DE 2B 00 00 DE 2B 00 00 DE 2B 00 00 +DE 2B 00 00 DE 2B 00 00 DE 2B 00 00 DE 2B 00 00 +2C 2D 00 00 DE 2B 00 00 DE 2B 00 00 DE 2B 00 00 +04 2D 00 00 DE 2B 00 00 A8 2C 00 00 DE 2B 00 00 +DE 2B 00 00 84 2C 00 00 06 2C 4C C7 74 E2 13 BE +68 66 3B C0 E9 33 78 7E E2 CA AE 3A FA 44 3E E6 +7D EF AA 89 12 1C A2 61 73 6E 6E BB B8 60 9D 35 +68 E6 B7 23 C9 BC 33 0F 0C A0 0E CA 39 65 91 72 +B4 73 B9 36 2D D3 3C A5 BC 62 30 95 82 3D AF E1 +90 99 83 14 FE DB AC 42 58 39 50 63 23 45 64 53 +21 23 AD FC EF DA 23 44 77 F2 81 7A 9E 46 51 52 +25 55 33 2B 89 FC C5 99 0E D7 54 FD 2B F3 47 F7 +6F D4 E1 B8 52 CD AC 30 36 BE C1 6B F9 34 7B D2 +68 1F 02 09 3A 31 B8 A6 83 C6 4C 93 A6 FF 43 D5 +7D C5 9C 8A AB 63 5B AC F0 A5 EB 3C 5D 1F 06 22 +D3 E1 2C B7 6E 4B D9 B4 DD 34 5B A3 53 5C 16 A9 +EB 0D 31 CB 2F 6D 8D BE DC 28 CA 92 11 56 3C 29 +39 B4 39 82 8A 8B 2C 5B 2E 88 25 3D C7 1D C1 3E +D2 28 F2 9D A5 D5 5A 7A CA A1 E4 24 C3 1D D2 5C +0A AC 3A A8 6C EB C5 F3 42 D7 C3 77 A6 8A 47 AF +ED 07 7E 39 C6 35 62 2D 29 28 6E A8 B9 EE 60 EE +F3 FA 21 2F 02 47 C8 90 38 E0 8E F9 52 AA C5 8D +22 3C 65 C2 BC C6 11 69 23 86 AB D4 6D 5C 73 42 +D4 AA BF 1A 6F 0B 04 B8 A5 A1 E4 C2 71 F7 0E E1 +76 B1 CD F8 2A D5 5F 56 18 90 CC 73 77 04 61 2D +34 49 A1 79 BD D4 16 BE B4 B6 1A A7 2B E9 73 60 +37 67 AC 66 F1 E0 35 E8 23 A4 2C 63 43 E0 15 82 +63 7C 05 32 5E B0 1C 18 48 C7 09 1F 8B EC 3C 8A +AD EA 25 CE F2 C4 EB B3 0D EA 0F D3 A6 61 0D 88 +23 F3 BA 8E 77 F0 19 8B 3F 84 A6 22 D2 38 50 36 +D3 7D A0 D3 6A 1B AF 6C E1 C4 60 F0 6F A4 7A 18 +EA 69 CD C3 E0 22 B5 BC 8A 3B FA B6 78 70 18 9C +8E 17 3B 0C E6 FB 90 4E 7E 36 76 97 2B FF 37 87 +F4 A3 A6 E1 C2 2B 6C 4E 18 6B 3A F9 07 CD 14 0A +85 04 FD E7 C5 15 3A DA 58 25 02 50 00 C0 01 10 +0A 00 00 00 01 00 00 00 00 00 00 00 6C 25 02 50 +28 C0 01 10 0C 00 00 00 FF FF FF FF 00 00 00 00 +88 25 02 50 58 C0 01 10 0C 00 00 00 FF FF FF FF +00 00 00 00 A4 25 02 50 88 C0 01 10 0C 00 00 00 +FF FF FF FF 00 00 00 00 C0 25 02 50 B8 C0 01 10 +0C 00 00 00 FF FF FF FF 00 00 00 00 DC 25 02 50 +E8 C0 01 10 0C 00 00 00 FF FF FF FF 00 00 00 00 +F8 25 02 50 18 C1 01 10 0C 00 00 00 FF FF FF FF +00 00 00 00 14 26 02 50 48 C1 01 10 0C 00 00 00 +FF FF FF FF 00 00 00 00 30 26 02 50 78 C1 01 10 +0C 00 00 00 FF FF FF FF 00 00 00 00 4C 26 02 50 +A8 C1 01 10 0C 00 00 00 FF FF FF FF 00 00 00 00 +68 26 02 50 D8 C1 01 10 0C 00 00 00 FF FF FF FF +00 00 00 00 84 26 02 50 08 C2 01 10 0A 00 00 00 +00 00 00 00 00 00 00 00 94 26 02 50 30 C2 01 10 +0C 00 00 00 FF FF FF FF 00 00 00 00 A8 26 02 50 +60 C2 01 10 0C 00 00 00 FF FF FF FF 00 00 00 00 +BC 26 02 50 90 C2 01 10 0C 00 00 00 FF FF FF FF +00 00 00 00 D0 26 02 50 C0 C2 01 10 0C 00 00 00 +FF FF FF FF 00 00 00 00 E4 26 02 50 F0 C2 01 10 +0C 00 00 00 FF FF FF FF 00 00 00 00 F8 26 02 50 +20 C3 01 10 0C 00 00 00 FF FF FF FF 00 00 00 00 +0C 27 02 50 50 C3 01 10 0C 00 00 00 FF FF FF FF +00 00 00 00 20 27 02 50 80 C3 01 10 0C 00 00 00 +FF FF FF FF 00 00 00 00 34 27 02 50 B0 C3 01 10 +0C 00 00 00 FF FF FF FF 00 00 00 00 48 27 02 50 +E0 C3 01 10 0C 00 00 00 FF FF FF FF 00 00 00 00 +5C 27 02 50 10 C4 01 10 0A 00 00 00 00 00 00 00 +00 00 00 00 78 27 02 50 38 C4 01 10 0A 00 00 00 +FF FF FF FF 00 00 00 00 8C 27 02 50 60 C4 01 10 +08 00 00 00 00 00 00 00 00 00 00 00 AC 27 02 50 +80 C4 01 10 08 00 00 00 01 00 00 00 00 00 00 00 +CC 27 02 50 A0 C4 01 10 08 00 00 00 FF FF FF FF +00 00 00 00 00 00 00 00 00 00 00 00 0C 00 00 00 +01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00 +05 00 00 00 06 00 00 00 07 00 00 00 08 00 00 00 +09 00 00 00 0A 00 00 00 0B 00 00 00 01 00 00 00 +0C 00 00 00 0C 00 00 00 0D 00 00 00 0E 00 00 00 +0F 00 00 00 10 00 00 00 11 00 00 00 12 00 00 00 +13 00 00 00 14 00 00 00 15 00 00 00 16 00 00 00 +03 00 00 00 01 00 00 00 17 00 00 00 17 00 00 00 +17 00 00 00 17 00 00 00 17 00 00 00 17 00 00 00 +17 00 00 00 17 00 00 00 17 00 00 00 17 00 00 00 +19 00 00 00 02 00 00 00 01 00 00 00 1A 00 00 00 +1A 00 00 00 1A 00 00 00 1A 00 00 00 1A 00 00 00 +1A 00 00 00 1A 00 00 00 1A 00 00 00 FF FF FF FF +FF FF FF FF B4 00 01 00 6C 01 01 00 6C 01 01 00 +BE 00 01 00 04 01 01 00 6C 01 01 00 6C 01 01 00 +B4 00 01 00 6C 01 01 00 46 01 01 00 B4 00 01 00 +6C 01 01 00 2A 01 01 00 B4 00 01 00 6C 01 01 00 +6C 01 01 00 6C 01 01 00 1C 01 01 00 66 88 2C 69 +00 00 00 00 CC 09 02 50 34 0A 02 50 9C 0A 02 50 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 +0E 33 CD AB 34 12 6D E6 EC DE 05 00 0B 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 2D 2D 2D 2D 2D 2D 2D 2D +2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D +2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 00 00 20 48 4D 41 +43 33 38 34 20 73 6D 6F 6B 65 20 74 65 73 74 20 +21 21 00 00 20 48 4D 41 43 35 31 32 20 73 6D 6F +6B 65 20 74 65 73 74 20 21 21 00 00 49 6E 3A 61 +62 72 5F 6E 6F 74 69 66 00 00 00 00 49 6E 3A 61 +62 72 5F 65 72 72 6F 72 00 00 00 00 49 6E 3A 73 +68 61 35 31 32 5F 61 63 63 5F 65 72 72 6F 72 00 +49 6E 3A 73 68 61 33 5F 6E 6F 74 69 66 00 00 00 +49 6E 3A 73 68 61 33 5F 65 72 72 6F 72 00 00 00 +49 6E 3A 73 68 61 32 35 36 5F 65 72 72 6F 72 00 +49 6E 3A 73 68 61 35 31 32 5F 65 72 72 6F 72 00 +49 6E 3A 6B 76 5F 6E 6F 74 69 66 00 49 6E 3A 6B +76 5F 65 72 72 6F 72 00 49 6E 3A 68 6D 61 63 5F +65 72 72 6F 72 00 00 00 49 6E 3A 65 63 63 5F 65 +72 72 6F 72 00 00 00 00 49 6E 3A 64 6F 65 5F 65 +72 72 6F 72 00 00 00 00 49 6E 3A 30 00 00 00 00 +49 6E 3A 61 78 69 5F 64 6D 61 5F 6E 6F 74 69 66 +00 00 00 00 49 6E 3A 61 78 69 5F 64 6D 61 5F 65 +72 72 6F 72 00 00 00 00 49 6E 3A 73 68 61 35 31 +32 5F 61 63 63 5F 6E 6F 74 69 66 00 49 6E 3A 73 +6F 63 5F 69 66 63 5F 6E 6F 74 69 66 00 00 00 00 +49 6E 3A 73 6F 63 5F 69 66 63 5F 65 72 72 6F 72 +00 00 00 00 49 6E 3A 73 68 61 32 35 36 5F 6E 6F +74 69 66 00 49 6E 3A 73 68 61 35 31 32 5F 6E 6F +74 69 66 00 49 6E 3A 68 6D 61 63 5F 6E 6F 74 69 +66 00 00 00 49 6E 3A 65 63 63 5F 6E 6F 74 69 66 +00 00 00 00 49 6E 3A 64 6F 65 5F 6E 6F 74 69 66 +00 00 00 00 44 6F 6E 65 20 68 61 6E 64 6C 69 6E +67 20 6D 61 63 68 69 6E 65 2D 6D 6F 64 65 20 54 +49 4D 45 52 20 69 6E 74 65 72 72 75 70 74 00 00 +43 6F 72 20 45 72 72 6F 72 20 4C 6F 63 61 6C 20 +49 53 52 00 45 72 72 6F 72 3A 20 48 65 78 20 73 +74 72 69 6E 67 20 6C 65 6E 67 74 68 20 6D 75 73 +74 20 62 65 20 61 20 6D 75 6C 74 69 70 6C 65 20 +6F 66 20 32 2E 00 00 00 43 6F 6E 66 69 67 75 72 +69 6E 67 20 41 45 53 20 66 6F 72 20 62 69 67 20 +65 6E 64 69 61 6E 20 6D 6F 64 65 00 43 6F 6E 66 +69 67 75 72 69 6E 67 20 41 45 53 20 66 6F 72 20 +6C 69 74 74 6C 65 20 65 6E 64 69 61 6E 20 6D 6F +64 65 00 00 4C 6F 61 64 20 4B 65 79 20 64 61 74 +61 20 74 6F 20 41 45 53 00 00 00 00 57 72 69 74 +65 20 41 45 53 20 49 56 00 00 00 00 57 61 69 74 +20 66 6F 72 20 49 4E 50 55 54 5F 52 45 41 44 59 +00 00 00 00 49 6E 6A 65 63 74 69 6E 67 20 44 4D +41 20 65 72 72 00 00 00 49 6E 6A 65 63 74 69 6E +67 20 41 45 53 20 63 6F 6C 6C 69 73 69 6F 6E 20 +65 72 72 00 41 45 53 20 63 6F 6C 6C 69 73 69 6F +6E 20 65 72 72 6F 72 20 6D 75 73 74 20 72 65 73 +75 6C 74 20 69 6E 20 4E 4D 49 2C 20 61 6E 64 20 +66 69 72 6D 77 61 72 65 20 72 65 73 65 74 00 00 +41 54 54 45 4D 50 54 20 54 4F 20 46 4C 49 50 20 +53 49 44 45 4C 4F 41 44 20 42 49 54 00 00 00 00 +45 58 50 45 43 54 45 44 20 4F 55 54 50 55 54 5F +4C 4F 53 54 20 74 6F 20 62 65 20 6E 6F 6E 2D 7A +65 72 6F 20 73 69 6E 63 65 20 4F 43 50 20 4C 4F +43 4B 20 70 72 6F 74 65 63 74 69 6F 6E 73 20 61 +72 65 20 62 6C 6F 63 6B 69 6E 67 20 74 68 65 20 +6F 75 74 70 75 74 20 74 6F 20 46 57 00 00 00 00 +45 78 70 65 63 74 65 64 20 64 61 74 61 3A 20 30 +78 30 00 00 57 41 49 54 49 4E 47 20 46 4F 52 20 +4B 56 20 52 45 41 44 20 54 4F 20 46 49 4E 49 53 +48 00 00 00 45 58 50 45 43 54 49 4E 47 20 4B 56 +20 52 44 20 45 52 52 00 45 58 50 45 43 54 49 4E +47 20 4E 4F 20 4B 56 20 52 44 20 45 52 52 00 00 +57 41 49 54 49 4E 47 20 46 4F 52 20 4B 56 20 57 +52 49 54 45 20 54 4F 20 46 49 4E 49 53 48 00 00 +43 48 45 43 4B 49 4E 47 20 46 4F 52 20 4B 56 20 +57 52 49 54 45 20 45 52 52 00 00 00 45 58 50 45 +43 54 49 4E 47 20 4B 56 20 45 52 52 00 00 00 00 +45 58 50 45 43 54 49 4E 47 20 4E 4F 20 4B 56 20 +45 52 52 00 52 65 61 64 20 61 6E 64 20 43 6F 6D +70 61 72 65 20 47 43 4D 20 54 41 47 00 00 00 00 +41 45 53 20 4F 70 65 72 61 74 69 6F 6E 20 43 6F +6D 70 6C 65 74 65 00 00 4C 6F 61 64 69 6E 67 20 +4B 56 20 76 69 61 20 41 45 53 00 00 44 4F 45 3A +20 49 6E 69 74 00 00 00 44 4F 45 3A 20 57 72 69 +74 69 6E 67 20 55 44 53 20 49 56 00 44 4F 45 3A +20 53 74 61 72 74 69 6E 67 20 55 44 53 20 44 65 +6F 62 66 75 73 63 61 74 69 6F 6E 20 66 6C 6F 77 +00 00 00 00 44 4F 45 3A 20 55 44 53 20 44 65 6F +62 66 75 73 63 61 74 69 6F 6E 20 66 6C 6F 77 20 +63 6F 6D 70 6C 65 74 65 00 00 00 00 44 4F 45 3A +20 57 72 69 74 69 6E 67 20 46 69 65 6C 64 20 45 +6E 74 72 6F 70 79 20 49 56 00 00 00 44 4F 45 3A +20 53 74 61 72 74 69 6E 67 20 46 69 65 6C 64 20 +45 6E 74 72 6F 70 79 20 44 65 6F 62 66 75 73 63 +61 74 69 6F 6E 20 66 6C 6F 77 00 00 44 4F 45 3A +20 46 69 65 6C 64 20 45 6E 74 72 6F 70 79 20 44 +65 6F 62 66 75 73 63 61 74 69 6F 6E 20 66 6C 6F +77 20 63 6F 6D 70 6C 65 74 65 00 00 44 4F 45 3A +20 57 72 69 74 69 6E 67 20 48 45 4B 20 49 56 00 +44 4F 45 3A 20 53 74 61 72 74 69 6E 67 20 48 45 +4B 20 44 65 6F 62 66 75 73 63 61 74 69 6F 6E 20 +66 6C 6F 77 00 00 00 00 44 4F 45 3A 20 48 45 4B +20 53 65 65 64 20 44 65 6F 62 66 75 73 63 61 74 +69 6F 6E 20 66 6C 6F 77 20 63 6F 6D 70 6C 65 74 +65 00 00 00 44 4F 45 3A 20 53 6B 69 70 70 69 6E +67 20 48 45 4B 20 44 65 6F 62 66 75 73 63 61 74 +69 6F 6E 20 64 75 65 20 74 6F 20 48 57 5F 43 4F +4E 46 49 47 00 00 00 00 44 4F 45 3A 20 43 6C 65 +61 72 20 73 65 63 72 65 74 73 00 00 45 43 43 20 +66 6C 6F 77 20 69 6E 20 70 72 6F 67 72 65 73 73 +2E 2E 2E 00 45 43 43 20 7A 65 72 6F 69 7A 65 20 +66 6C 6F 77 2E 00 00 00 0A 45 43 43 20 4B 45 59 +47 45 4E 00 57 61 69 74 20 66 6F 72 20 4B 56 20 +77 72 69 74 65 00 00 00 4C 6F 61 64 20 50 52 49 +56 4B 45 59 20 64 61 74 61 20 66 72 6F 6D 20 45 +43 43 00 00 4C 6F 61 64 20 50 55 42 4B 45 59 5F +58 20 64 61 74 61 20 66 72 6F 6D 20 45 43 43 00 +4C 6F 61 64 20 50 55 42 4B 45 59 5F 59 20 64 61 +74 61 20 66 72 6F 6D 20 45 43 43 00 53 74 6F 72 +65 20 50 55 42 4B 45 59 5F 58 20 64 61 74 61 20 +69 6E 20 45 43 43 00 00 53 74 6F 72 65 20 50 55 +42 4B 45 59 5F 59 20 64 61 74 61 20 69 6E 20 45 +43 43 00 00 0A 45 43 43 20 53 48 41 52 45 44 4B +45 59 00 00 4C 6F 61 64 20 53 48 41 52 45 44 4B +45 59 20 64 61 74 61 20 66 72 6F 6D 20 45 43 43 +00 00 00 00 49 6E 6A 65 63 74 20 50 52 49 56 4B +45 59 20 66 72 6F 6D 20 6B 76 20 74 6F 20 45 43 +43 00 00 00 0A 45 43 43 20 53 49 47 4E 49 4E 47 +00 00 00 00 4C 6F 61 64 20 53 49 47 4E 5F 52 20 +64 61 74 61 20 66 72 6F 6D 20 45 43 43 00 00 00 +4C 6F 61 64 20 53 49 47 4E 5F 53 20 64 61 74 61 +20 66 72 6F 6D 20 45 43 43 00 00 00 0A 45 43 43 +20 56 45 52 49 46 59 49 4E 47 00 00 4C 6F 61 64 +20 56 45 52 49 46 59 5F 52 20 64 61 74 61 20 66 +72 6F 6D 20 45 43 43 00 0A 45 43 43 20 50 43 52 +20 53 49 47 4E 49 4E 47 00 00 00 00 4D 4C 44 53 +41 20 66 6C 6F 77 20 69 6E 20 70 72 6F 67 72 65 +73 73 2E 2E 2E 00 00 00 4D 4C 44 53 41 20 7A 65 +72 6F 69 7A 65 20 66 6C 6F 77 2E 00 57 61 69 74 +69 6E 67 20 66 6F 72 20 6D 6C 64 73 61 20 73 74 +61 74 75 73 20 72 65 61 64 79 00 00 57 61 69 74 +69 6E 67 20 66 6F 72 20 6D 6C 64 73 61 20 73 74 +61 74 75 73 20 72 65 61 64 79 20 69 6E 20 6B 65 +79 67 65 6E 00 00 00 00 54 72 79 20 74 6F 20 4F +76 65 72 77 72 69 74 65 20 73 65 65 64 20 64 61 +74 61 20 69 6E 20 4D 4C 44 53 41 00 5B 4D 4C 44 +53 41 20 4B 65 79 47 65 6E 5D 20 52 65 63 65 69 +76 65 64 20 65 78 70 65 63 74 65 64 20 65 72 72 +20 66 6F 72 20 4D 4C 44 53 41 20 73 65 65 64 20 +72 65 61 64 20 66 72 6F 6D 20 4B 56 00 00 00 00 +5B 4D 4C 44 53 41 20 4B 65 79 47 65 6E 5D 20 52 +65 63 65 69 76 65 64 20 75 6E 65 78 70 65 63 74 +65 64 20 73 75 63 63 65 73 73 20 66 6F 72 20 4D +4C 44 53 41 20 73 65 65 64 20 72 65 61 64 20 66 +72 6F 6D 20 4B 56 00 00 57 72 69 74 69 6E 67 20 +65 6E 74 72 6F 70 79 00 0A 4D 4C 44 53 41 20 4B +45 59 47 45 4E 00 00 00 4C 6F 61 64 20 50 52 49 +56 4B 45 59 20 64 61 74 61 20 66 72 6F 6D 20 4D +4C 44 53 41 00 00 00 00 4C 6F 61 64 20 50 55 42 +4B 45 59 20 64 61 74 61 20 66 72 6F 6D 20 4D 4C +44 53 41 00 5B 4D 4C 44 53 41 20 4B 65 79 47 65 +6E 20 53 69 67 6E 69 6E 67 5D 20 52 65 63 65 69 +76 65 64 20 65 78 70 65 63 74 65 64 20 65 72 72 +20 66 6F 72 20 4D 4C 44 53 41 20 73 65 65 64 20 +72 65 61 64 20 66 72 6F 6D 20 4B 56 00 00 00 00 +5B 4D 4C 44 53 41 20 4B 65 79 47 65 6E 20 53 69 +67 6E 69 6E 67 5D 20 52 65 63 65 69 76 65 64 20 +75 6E 65 78 70 65 63 74 65 64 20 73 75 63 63 65 +73 73 20 66 6F 72 20 4D 4C 44 53 41 20 73 65 65 +64 20 72 65 61 64 20 66 72 6F 6D 20 4B 56 00 00 +0A 4D 4C 44 53 41 20 4B 45 59 47 45 4E 20 2B 20 +53 49 47 4E 49 4E 47 00 4C 6F 61 64 20 53 49 47 +4E 20 64 61 74 61 20 66 72 6F 6D 20 4D 4C 44 53 +41 00 00 00 57 72 69 74 69 6E 67 20 70 72 69 76 +6B 65 79 00 57 72 69 74 69 6E 67 20 6D 73 67 00 +0A 4D 4C 44 53 41 20 53 49 47 4E 49 4E 47 00 00 +0A 4D 4C 44 53 41 20 56 45 52 49 46 59 49 4E 47 +00 00 00 00 4C 6F 61 64 20 56 45 52 49 46 59 5F +52 45 53 20 64 61 74 61 20 66 72 6F 6D 20 4D 4C +44 53 41 00 0A 4D 4C 44 53 41 20 4B 45 59 47 45 +4E 20 2B 20 53 49 47 4E 49 4E 47 20 69 6E 20 45 +78 74 65 72 6E 61 6C 4D 75 20 6D 6F 64 65 00 00 +57 72 69 74 69 6E 67 20 45 78 74 65 72 6E 61 6C +4D 75 00 00 0A 4D 4C 44 53 41 20 53 49 47 4E 49 +4E 47 20 69 6E 20 45 78 74 65 72 6E 61 6C 4D 75 +20 6D 6F 64 65 00 00 00 0A 4D 4C 44 53 41 20 56 +45 52 49 46 59 49 4E 47 20 69 6E 20 45 78 74 65 +72 6E 61 6C 4D 75 20 6D 6F 64 65 00 5B 4D 4C 4B +45 4D 5D 20 57 61 69 74 69 6E 67 20 66 6F 72 20 +69 6E 74 65 72 72 75 70 74 00 00 00 5B 4D 4C 4B +45 4D 5D 20 53 74 61 72 74 69 6E 67 20 7A 65 72 +6F 69 7A 65 00 00 00 00 5B 4D 4C 4B 45 4D 5D 20 +57 61 69 74 69 6E 67 20 66 6F 72 20 72 65 61 64 +79 00 00 00 5B 4D 4C 4B 45 4D 20 4B 65 79 47 65 +6E 5D 20 57 61 69 74 69 6E 67 20 66 6F 72 20 72 +65 61 64 79 00 00 00 00 5B 4D 4C 4B 45 4D 20 4B +65 79 47 65 6E 5D 20 54 72 79 20 74 6F 20 4F 76 +65 72 77 72 69 74 65 20 73 65 65 64 20 64 20 64 +61 74 61 00 5B 4D 4C 4B 45 4D 20 4B 65 79 47 65 +6E 5D 20 54 72 79 20 74 6F 20 4F 76 65 72 77 72 +69 74 65 20 73 65 65 64 20 7A 20 64 61 74 61 00 +5B 4D 4C 4B 45 4D 20 4B 65 79 47 65 6E 5D 20 52 +65 63 65 69 76 65 64 20 65 78 70 65 63 74 65 64 +20 65 72 72 20 66 6F 72 20 4D 4C 4B 45 4D 20 73 +65 65 64 20 72 65 61 64 20 66 72 6F 6D 20 4B 56 +00 00 00 00 5B 4D 4C 4B 45 4D 20 4B 65 79 47 65 +6E 5D 20 52 65 63 65 69 76 65 64 20 75 6E 65 78 +70 65 63 74 65 64 20 73 75 63 63 65 73 73 20 66 +6F 72 20 4D 4C 4B 45 4D 20 73 65 65 64 20 72 65 +61 64 20 66 72 6F 6D 20 4B 56 00 00 5B 4D 4C 4B +45 4D 20 4B 65 79 47 65 6E 5D 20 57 72 69 74 69 +6E 67 20 65 6E 74 72 6F 70 79 00 00 5B 4D 4C 4B +45 4D 20 4B 65 79 47 65 6E 5D 20 53 65 6E 64 69 +6E 67 20 63 6F 6D 6D 61 6E 64 00 00 5B 4D 4C 4B +45 4D 20 4B 65 79 47 65 6E 5D 20 43 68 65 63 6B +69 6E 67 20 65 6E 63 61 70 73 20 6B 65 79 00 00 +5B 4D 4C 4B 45 4D 20 4B 65 79 47 65 6E 5D 20 43 +68 65 63 6B 69 6E 67 20 64 65 63 61 70 73 20 6B +65 79 00 00 5B 4D 4C 4B 45 4D 20 4B 65 79 47 65 +6E 5D 20 43 68 65 63 6B 20 74 68 61 74 20 53 45 +45 44 5F 44 20 61 70 69 20 68 61 73 20 30 73 00 +5B 4D 4C 4B 45 4D 20 4B 65 79 47 65 6E 5D 20 43 +68 65 63 6B 20 74 68 61 74 20 53 45 45 44 5F 5A +20 61 70 69 20 68 61 73 20 30 73 00 5B 4D 4C 4B +45 4D 20 4B 65 79 47 65 6E 5D 20 52 65 61 64 20 +45 6E 63 61 70 73 20 4B 65 79 00 00 5B 4D 4C 4B +45 4D 20 4B 65 79 47 65 6E 5D 20 52 65 61 64 20 +44 65 63 61 70 73 20 4B 65 79 00 00 5B 4D 4C 4B +45 4D 20 4B 65 79 47 65 6E 5D 20 43 68 65 63 6B +20 74 68 61 74 20 44 4B 20 61 70 69 20 68 61 73 +20 30 73 00 5B 4D 4C 4B 45 4D 20 45 6E 63 61 70 +73 5D 20 57 61 69 74 69 6E 67 20 66 6F 72 20 72 +65 61 64 79 00 00 00 00 5B 4D 4C 4B 45 4D 20 45 +6E 63 61 70 73 5D 20 57 72 69 74 69 6E 67 20 65 +6E 63 61 70 73 20 6B 65 79 00 00 00 5B 4D 4C 4B +45 4D 20 45 6E 63 61 70 73 5D 20 54 72 79 20 74 +6F 20 4F 76 65 72 77 72 69 74 65 20 6D 73 67 00 +5B 4D 4C 4B 45 4D 20 45 6E 63 61 70 73 5D 20 54 +72 79 20 74 6F 20 4F 76 65 72 77 72 69 74 65 20 +6D 73 67 20 74 68 72 6F 75 67 68 20 4D 4C 44 53 +41 20 70 72 69 76 6B 65 79 00 00 00 5B 4D 4C 4B +45 4D 20 4B 65 79 47 65 6E 5D 20 52 65 63 65 69 +76 65 64 20 65 78 70 65 63 74 65 64 20 65 72 72 +20 66 6F 72 20 4D 4C 4B 45 4D 20 6D 73 67 20 72 +65 61 64 20 66 72 6F 6D 20 4B 56 00 5B 4D 4C 4B +45 4D 20 4B 65 79 47 65 6E 5D 20 52 65 63 65 69 +76 65 64 20 75 6E 65 78 70 65 63 74 65 64 20 73 +75 63 63 65 73 73 20 66 6F 72 20 4D 4C 4B 45 4D +20 6D 73 67 20 72 65 61 64 20 66 72 6F 6D 20 4B +56 00 00 00 5B 4D 4C 4B 45 4D 20 45 6E 63 61 70 +73 5D 20 43 68 65 63 6B 20 74 68 61 74 20 4D 53 +47 20 61 70 69 20 68 61 73 20 30 73 00 00 00 00 +5B 4D 4C 4B 45 4D 20 45 6E 63 61 70 73 5D 20 57 +72 69 74 69 6E 67 20 65 6E 74 72 6F 70 79 00 00 +5B 4D 4C 4B 45 4D 20 45 6E 63 61 70 73 5D 20 53 +65 6E 64 69 6E 67 20 63 6F 6D 6D 61 6E 64 00 00 +5B 4D 4C 4B 45 4D 20 45 6E 63 61 70 73 5D 20 43 +68 65 63 6B 20 43 69 70 68 65 72 74 65 78 74 00 +5B 4D 4C 4B 45 4D 20 45 6E 63 61 70 73 5D 20 52 +65 63 65 69 76 65 64 20 65 78 70 65 63 74 65 64 +20 65 72 72 20 66 6F 72 20 4D 4C 4B 45 4D 20 73 +68 61 72 65 64 6B 65 79 20 77 72 69 74 65 20 66 +72 6F 6D 20 4B 56 00 00 5B 4D 4C 4B 45 4D 20 45 +6E 63 61 70 73 5D 20 52 65 63 65 69 76 65 64 20 +75 6E 65 78 70 65 63 74 65 64 20 73 75 63 63 65 +73 73 20 66 6F 72 20 4D 4C 4B 45 4D 20 73 68 61 +72 65 64 6B 65 79 20 77 72 69 74 65 20 66 72 6F +6D 20 4B 56 00 00 00 00 5B 4D 4C 4B 45 4D 20 45 +6E 63 61 70 73 5D 20 52 65 63 65 69 76 65 64 20 +75 6E 65 78 70 65 63 74 65 64 20 65 72 72 20 66 +6F 72 20 4D 4C 4B 45 4D 20 73 68 61 72 65 64 6B +65 79 20 77 72 69 74 65 20 66 72 6F 6D 20 4B 56 +00 00 00 00 5B 4D 4C 4B 45 4D 20 45 6E 63 61 70 +73 5D 20 52 65 63 65 69 76 65 64 20 65 78 70 65 +63 74 65 64 20 73 75 63 63 65 73 73 20 66 6F 72 +20 4D 4C 4B 45 4D 20 73 68 61 72 65 64 6B 65 79 +20 77 72 69 74 65 20 66 72 6F 6D 20 4B 56 00 00 +5B 4D 4C 4B 45 4D 20 45 6E 63 61 70 73 5D 20 43 +68 65 63 6B 20 53 68 61 72 65 64 20 4B 65 79 00 +5B 4D 4C 4B 45 4D 20 45 6E 63 61 70 73 5D 20 4B +56 20 75 73 65 64 2C 20 63 68 65 63 6B 20 53 68 +61 72 65 64 20 4B 65 79 20 69 73 20 30 00 00 00 +5B 4D 4C 4B 45 4D 20 45 6E 63 61 70 73 5D 20 53 +65 6E 64 69 6E 67 20 43 6F 6D 6D 61 6E 64 00 00 +5B 4D 4C 4B 45 4D 20 45 6E 63 61 70 73 5D 20 52 +65 61 64 20 43 69 70 68 65 72 74 65 78 74 00 00 +5B 4D 4C 4B 45 4D 20 45 6E 63 61 70 73 5D 20 52 +65 63 65 69 76 65 64 20 75 6E 65 78 70 65 63 74 +65 64 20 66 61 69 6C 20 66 6F 72 20 4D 4C 4B 45 +4D 20 73 68 61 72 65 64 6B 65 79 20 77 72 69 74 +65 20 66 72 6F 6D 20 4B 56 00 00 00 5B 4D 4C 4B +45 4D 20 45 6E 63 61 70 73 5D 20 52 65 61 64 20 +53 68 61 72 65 64 20 4B 65 79 00 00 5B 4D 4C 4B +45 4D 20 44 65 63 61 70 73 5D 20 57 61 69 74 69 +6E 67 20 66 6F 72 20 72 65 61 64 79 00 00 00 00 +5B 4D 4C 4B 45 4D 20 44 65 63 61 70 73 5D 20 57 +72 69 74 69 6E 67 20 64 65 63 61 70 73 20 6B 65 +79 00 00 00 5B 4D 4C 4B 45 4D 20 44 65 63 61 70 +73 5D 20 57 72 69 74 69 6E 67 20 65 6E 74 72 6F +70 79 00 00 5B 4D 4C 4B 45 4D 20 44 65 63 61 70 +73 5D 20 53 65 6E 64 69 6E 67 20 63 6F 6D 6D 61 +6E 64 00 00 5B 4D 4C 4B 45 4D 20 44 65 63 61 70 +73 5D 20 52 65 63 65 69 76 65 64 20 65 78 70 65 +63 74 65 64 20 65 72 72 20 66 6F 72 20 4D 4C 4B +45 4D 20 73 68 61 72 65 64 6B 65 79 20 77 72 69 +74 65 20 66 72 6F 6D 20 4B 56 00 00 5B 4D 4C 4B +45 4D 20 44 65 63 61 70 73 5D 20 52 65 63 65 69 +76 65 64 20 75 6E 65 78 70 65 63 74 65 64 20 73 +75 63 63 65 73 73 20 66 6F 72 20 4D 4C 4B 45 4D +20 73 68 61 72 65 64 6B 65 79 20 77 72 69 74 65 +20 66 72 6F 6D 20 4B 56 00 00 00 00 5B 4D 4C 4B +45 4D 20 44 65 63 61 70 73 5D 20 52 65 63 65 69 +76 65 64 20 75 6E 65 78 70 65 63 74 65 64 20 66 +61 69 6C 20 66 6F 72 20 4D 4C 4B 45 4D 20 73 68 +61 72 65 64 6B 65 79 20 77 72 69 74 65 20 66 72 +6F 6D 20 4B 56 00 00 00 5B 4D 4C 4B 45 4D 20 44 +65 63 61 70 73 5D 20 52 65 63 65 69 76 65 64 20 +65 78 70 65 63 74 65 64 20 73 75 63 63 65 73 73 +20 66 6F 72 20 4D 4C 4B 45 4D 20 73 68 61 72 65 +64 6B 65 79 20 77 72 69 74 65 20 66 72 6F 6D 20 +4B 56 00 00 5B 4D 4C 4B 45 4D 20 44 65 63 61 70 +73 5D 20 4B 56 20 75 73 65 64 2C 20 63 68 65 63 +6B 20 53 68 61 72 65 64 20 4B 65 79 20 69 73 20 +30 00 00 00 5B 4D 4C 4B 45 4D 20 44 65 63 61 70 +73 5D 20 43 68 65 63 6B 20 53 68 61 72 65 64 20 +4B 65 79 00 5B 4D 4C 4B 45 4D 20 44 65 63 61 70 +73 5D 20 52 65 63 65 69 76 65 64 20 65 78 70 65 +63 74 65 64 20 65 72 72 20 66 6F 72 20 4D 4C 4B +45 4D 20 73 68 61 72 65 64 6B 65 79 20 72 65 61 +64 20 66 72 6F 6D 20 4B 56 00 00 00 5B 4D 4C 4B +45 4D 20 44 65 63 61 70 73 5D 20 52 65 63 65 69 +76 65 64 20 75 6E 65 78 70 65 63 74 65 64 20 73 +75 63 63 65 73 73 20 66 6F 72 20 4D 4C 4B 45 4D +20 73 68 61 72 65 64 6B 65 79 20 72 65 61 64 20 +66 72 6F 6D 20 4B 56 00 5B 4D 4C 4B 45 4D 20 44 +65 63 61 70 73 5D 20 52 65 61 64 20 53 68 61 72 +65 64 20 4B 65 79 00 00 5B 4D 4C 4B 45 4D 20 4B +65 79 47 65 6E 20 44 65 63 61 70 73 5D 20 57 61 +69 74 69 6E 67 20 66 6F 72 20 72 65 61 64 79 00 +5B 4D 4C 4B 45 4D 20 4B 65 79 47 65 6E 20 44 65 +63 61 70 73 5D 20 54 72 79 20 74 6F 20 4F 76 65 +72 77 72 69 74 65 20 73 65 65 64 20 64 00 00 00 +5B 4D 4C 4B 45 4D 20 4B 65 79 47 65 6E 20 44 65 +63 61 70 73 5D 20 54 72 79 20 74 6F 20 4F 76 65 +72 77 72 69 74 65 20 73 65 65 64 20 7A 00 00 00 +5B 4D 4C 4B 45 4D 20 4B 65 79 47 65 6E 20 44 65 +63 61 70 73 5D 20 57 72 69 74 69 6E 67 20 65 6E +74 72 6F 70 79 00 00 00 5B 4D 4C 4B 45 4D 20 4B +65 79 47 65 6E 20 44 65 63 61 70 73 5D 20 53 65 +6E 64 69 6E 67 20 63 6F 6D 6D 61 6E 64 00 00 00 +5B 4D 4C 4B 45 4D 20 4B 65 79 47 65 6E 20 44 65 +63 61 70 73 5D 20 52 65 63 65 69 76 65 64 20 65 +78 70 65 63 74 65 64 20 65 72 72 20 66 6F 72 20 +4D 4C 4B 45 4D 20 73 68 61 72 65 64 6B 65 79 20 +77 72 69 74 65 20 66 72 6F 6D 20 4B 56 00 00 00 +5B 4D 4C 4B 45 4D 20 4B 65 79 47 65 6E 20 44 65 +63 61 70 73 5D 20 52 65 63 65 69 76 65 64 20 75 +6E 65 78 70 65 63 74 65 64 20 73 75 63 63 65 73 +73 20 66 6F 72 20 4D 4C 4B 45 4D 20 73 68 61 72 +65 64 6B 65 79 20 77 72 69 74 65 20 66 72 6F 6D +20 4B 56 00 5B 4D 4C 4B 45 4D 20 4B 65 79 47 65 +6E 20 44 65 63 61 70 73 5D 20 52 65 63 65 69 76 +65 64 20 75 6E 65 78 70 65 63 74 65 64 20 66 61 +69 6C 20 66 6F 72 20 4D 4C 4B 45 4D 20 73 68 61 +72 65 64 6B 65 79 20 77 72 69 74 65 20 66 72 6F +6D 20 4B 56 00 00 00 00 5B 4D 4C 4B 45 4D 20 4B +65 79 47 65 6E 20 44 65 63 61 70 73 5D 20 52 65 +63 65 69 76 65 64 20 65 78 70 65 63 74 65 64 20 +73 75 63 63 65 73 73 20 66 6F 72 20 4D 4C 4B 45 +4D 20 73 68 61 72 65 64 6B 65 79 20 77 72 69 74 +65 20 66 72 6F 6D 20 4B 56 00 00 00 5B 4D 4C 4B +45 4D 20 4B 65 79 47 65 6E 20 44 65 63 61 70 73 +5D 20 43 68 65 63 6B 20 53 68 61 72 65 64 20 4B +65 79 00 00 5B 4D 4C 4B 45 4D 20 4B 65 79 47 65 +6E 20 44 65 63 61 70 73 5D 20 4B 56 20 75 73 65 +64 2C 20 63 68 65 63 6B 20 53 68 61 72 65 64 20 +4B 65 79 20 69 73 20 30 00 00 00 00 5B 4D 4C 4B +45 4D 20 4B 65 79 47 65 6E 20 44 65 63 61 70 73 +5D 20 52 65 61 64 20 53 68 61 72 65 64 20 4B 65 +79 00 00 00 48 4D 41 43 20 66 6C 6F 77 20 69 6E +20 70 72 6F 67 72 65 73 73 2E 2E 2E 00 00 00 00 +48 4D 41 43 20 7A 65 72 6F 69 7A 65 20 66 6C 6F +77 2E 00 00 54 72 79 20 74 6F 20 4F 76 65 72 77 +72 69 74 65 20 4B 65 79 20 64 61 74 61 20 69 6E +20 48 4D 41 43 33 38 34 00 00 00 00 52 65 63 65 +69 76 65 64 20 65 78 70 65 63 74 65 64 20 65 72 +72 20 66 6F 72 20 48 4D 41 43 20 6B 65 79 20 72 +65 61 64 20 66 72 6F 6D 20 4B 56 20 77 68 69 6C +65 20 4F 43 50 20 6C 6F 63 6B 20 69 6E 20 70 72 +6F 67 72 65 73 73 00 00 52 65 63 65 69 76 65 64 +20 75 6E 65 78 70 65 63 74 65 64 20 73 75 63 63 +65 73 73 20 66 6F 72 20 48 4D 41 43 20 6B 65 79 +20 72 65 61 64 20 66 72 6F 6D 20 4B 56 20 77 68 +69 6C 65 20 4F 43 50 20 6C 6F 63 6B 20 69 6E 20 +70 72 6F 67 72 65 73 73 00 00 00 00 4C 6F 61 64 +20 4B 65 79 20 64 61 74 61 20 74 6F 20 48 4D 41 +43 00 00 00 54 72 79 20 74 6F 20 4F 76 65 72 77 +72 69 74 65 20 42 6C 6F 63 6B 20 64 61 74 61 20 +69 6E 20 48 4D 41 43 00 52 65 63 65 69 76 65 64 +20 65 78 70 65 63 74 65 64 20 65 72 72 20 66 6F +72 20 48 4D 41 43 20 62 6C 6F 63 6B 20 72 65 61 +64 20 66 72 6F 6D 20 4B 56 20 77 68 69 6C 65 20 +4F 43 50 20 6C 6F 63 6B 20 69 6E 20 70 72 6F 67 +72 65 73 73 00 00 00 00 52 65 63 65 69 76 65 64 +20 75 6E 65 78 70 65 63 74 65 64 20 73 75 63 63 +65 73 73 20 66 6F 72 20 48 4D 41 43 20 62 6C 6F +63 6B 20 72 65 61 64 20 66 72 6F 6D 20 4B 56 20 +77 68 69 6C 65 20 4F 43 50 20 6C 6F 63 6B 20 69 +6E 20 70 72 6F 67 72 65 73 73 00 00 4C 6F 61 64 +20 54 41 47 20 64 61 74 61 20 66 72 6F 6D 20 48 +4D 41 43 20 74 6F 20 4B 56 00 00 00 4C 6F 61 64 +20 54 41 47 20 64 61 74 61 20 66 72 6F 6D 20 48 +4D 41 43 00 54 72 79 20 74 6F 20 4F 76 65 72 77 +72 69 74 65 20 4B 65 79 20 64 61 74 61 20 69 6E +20 48 4D 41 43 35 31 32 00 00 00 00 4B 56 3A 20 +63 68 65 63 6B 69 6E 67 20 66 6F 72 20 65 72 72 +6F 72 73 00 4B 56 20 45 52 52 4F 52 00 00 00 00 +4B 56 3A 20 63 68 65 63 6B 69 6E 67 20 65 72 72 +6F 72 73 20 70 72 65 73 65 6E 74 00 4E 4F 20 4B +56 20 45 52 52 4F 52 00 4B 56 3A 20 70 72 6F 67 +20 6B 76 20 72 65 61 64 20 63 74 72 6C 00 00 00 +4B 56 3A 20 70 72 6F 67 20 6B 76 20 77 72 69 74 +65 20 63 74 72 6C 00 00 50 56 3A 20 70 72 6F 67 +20 6B 76 20 72 65 61 64 20 63 74 72 6C 20 69 6E +20 53 48 41 20 74 6F 20 64 6F 20 68 61 73 68 20 +65 78 74 65 6E 64 00 00 2D 2D 2D 2D 2D 2D 2D 2D +2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D +2D 2D 2D 2D 2D 2D 2D 00 53 54 49 43 4B 59 44 41 +54 41 56 41 55 4C 54 43 54 52 4C 00 53 54 49 43 +4B 59 5F 44 41 54 41 5F 56 41 55 4C 54 5F 45 4E +54 52 59 5F 30 00 00 00 53 54 49 43 4B 59 5F 44 +41 54 41 5F 56 41 55 4C 54 5F 45 4E 54 52 59 5F +31 00 00 00 53 54 49 43 4B 59 5F 44 41 54 41 5F +56 41 55 4C 54 5F 45 4E 54 52 59 5F 32 00 00 00 +53 54 49 43 4B 59 5F 44 41 54 41 5F 56 41 55 4C +54 5F 45 4E 54 52 59 5F 33 00 00 00 53 54 49 43 +4B 59 5F 44 41 54 41 5F 56 41 55 4C 54 5F 45 4E +54 52 59 5F 34 00 00 00 53 54 49 43 4B 59 5F 44 +41 54 41 5F 56 41 55 4C 54 5F 45 4E 54 52 59 5F +35 00 00 00 53 54 49 43 4B 59 5F 44 41 54 41 5F +56 41 55 4C 54 5F 45 4E 54 52 59 5F 36 00 00 00 +53 54 49 43 4B 59 5F 44 41 54 41 5F 56 41 55 4C +54 5F 45 4E 54 52 59 5F 37 00 00 00 53 54 49 43 +4B 59 5F 44 41 54 41 5F 56 41 55 4C 54 5F 45 4E +54 52 59 5F 38 00 00 00 53 54 49 43 4B 59 5F 44 +41 54 41 5F 56 41 55 4C 54 5F 45 4E 54 52 59 5F +39 00 00 00 44 41 54 41 56 41 55 4C 54 43 54 52 +4C 00 00 00 44 41 54 41 5F 56 41 55 4C 54 5F 45 +4E 54 52 59 5F 30 00 00 44 41 54 41 5F 56 41 55 +4C 54 5F 45 4E 54 52 59 5F 31 00 00 44 41 54 41 +5F 56 41 55 4C 54 5F 45 4E 54 52 59 5F 32 00 00 +44 41 54 41 5F 56 41 55 4C 54 5F 45 4E 54 52 59 +5F 33 00 00 44 41 54 41 5F 56 41 55 4C 54 5F 45 +4E 54 52 59 5F 34 00 00 44 41 54 41 5F 56 41 55 +4C 54 5F 45 4E 54 52 59 5F 35 00 00 44 41 54 41 +5F 56 41 55 4C 54 5F 45 4E 54 52 59 5F 36 00 00 +44 41 54 41 5F 56 41 55 4C 54 5F 45 4E 54 52 59 +5F 37 00 00 44 41 54 41 5F 56 41 55 4C 54 5F 45 +4E 54 52 59 5F 38 00 00 44 41 54 41 5F 56 41 55 +4C 54 5F 45 4E 54 52 59 5F 39 00 00 4C 4F 43 4B +41 42 4C 45 5F 53 43 52 41 54 43 48 52 45 47 5F +43 54 52 4C 00 00 00 00 4C 4F 43 4B 41 42 4C 45 +5F 53 43 52 41 54 43 48 52 45 47 00 4E 4F 4E 53 +54 49 43 4B 59 5F 47 45 4E 45 52 49 43 5F 53 43 +52 41 54 43 48 52 45 47 00 00 00 00 53 54 49 43 +4B 59 5F 4C 4F 43 4B 41 42 4C 45 5F 53 43 52 41 +54 43 48 52 45 47 5F 43 54 52 4C 00 53 54 49 43 +4B 59 5F 4C 4F 43 4B 41 42 4C 45 5F 53 43 52 41 +54 43 48 52 45 47 00 00 53 48 41 32 35 36 20 66 +6C 6F 77 20 69 6E 20 70 72 6F 67 72 65 73 73 2E +2E 2E 00 00 53 48 41 32 35 36 20 7A 65 72 6F 69 +7A 65 20 66 6C 6F 77 2E 00 00 00 00 45 6E 61 62 +6C 65 20 53 48 41 32 35 36 00 00 00 4C 6F 61 64 +20 44 49 47 45 53 54 20 64 61 74 61 20 66 72 6F +6D 20 53 48 41 32 35 36 00 00 00 00 45 72 72 6F +72 31 20 69 73 20 65 78 70 65 63 74 65 64 20 77 +68 65 6E 20 69 6E 69 74 20 61 6E 64 20 6E 65 78 +74 20 61 72 65 20 61 73 73 65 72 74 65 64 20 61 +74 20 74 68 65 20 73 61 6D 65 20 74 69 6D 65 2E +20 43 68 65 63 6B 20 61 72 67 73 20 67 69 76 65 +6E 20 74 6F 20 73 68 61 32 35 36 5F 65 72 72 6F +72 5F 66 6C 6F 77 28 29 00 00 00 00 45 72 72 6F +72 30 20 69 73 20 65 78 70 65 63 74 65 64 20 66 +6F 72 20 69 6E 76 61 6C 69 64 20 77 6E 74 7A 5F +6D 6F 64 65 20 6F 72 20 77 2E 20 43 68 65 63 6B +20 61 72 67 73 20 67 69 76 65 6E 20 74 6F 20 73 +68 61 32 35 36 5F 65 72 72 6F 72 5F 66 6C 6F 77 +28 29 00 00 53 48 41 35 31 32 20 66 6C 6F 77 20 +69 6E 20 70 72 6F 67 72 65 73 73 2E 2E 2E 00 00 +53 48 41 35 31 32 3A 20 53 65 74 20 53 54 41 52 +54 20 66 6F 72 20 67 65 6E 20 68 61 73 68 20 66 +75 6E 63 00 53 48 41 35 31 32 20 7A 65 72 6F 69 +7A 65 20 66 6C 6F 77 2E 00 00 00 00 45 6E 61 62 +6C 65 20 53 48 41 35 31 32 00 00 00 4C 6F 61 64 +20 44 49 47 45 53 54 20 64 61 74 61 20 66 72 6F +6D 20 53 48 41 35 31 32 00 00 00 00 64 69 66 5F +6B 6D 61 63 5F 63 75 73 74 6F 6D 69 7A 61 74 69 +6F 6E 5F 73 74 72 69 6E 67 5F 69 6E 69 74 3A 20 +45 52 52 4F 52 20 64 61 74 61 20 61 6E 64 20 6F +75 74 20 61 72 67 75 6D 65 6E 74 73 20 6D 75 73 +74 20 6E 6F 74 20 62 65 20 6E 75 6C 6C 2E 00 00 +64 69 66 5F 6B 6D 61 63 5F 63 75 73 74 6F 6D 69 +7A 61 74 69 6F 6E 5F 73 74 72 69 6E 67 5F 69 6E +69 74 3A 20 45 52 52 4F 52 20 6C 65 6E 67 74 68 +20 67 72 65 61 74 65 72 20 74 68 61 6E 20 6D 61 +78 69 6D 75 6D 2E 00 00 64 69 66 5F 6B 6D 61 63 +5F 66 75 6E 63 74 69 6F 6E 5F 6E 61 6D 65 5F 69 +6E 69 74 3A 20 45 52 52 4F 52 20 64 61 74 61 20 +61 6E 64 20 6F 75 74 20 6D 75 73 74 20 6E 6F 74 +20 62 65 20 4E 55 4C 4C 2E 00 00 00 64 69 66 5F +6B 6D 61 63 5F 66 75 6E 63 74 69 6F 6E 5F 6E 61 +6D 65 5F 69 6E 69 74 3A 20 45 52 52 4F 52 20 6C +65 6E 67 74 68 20 6C 61 72 67 65 72 20 74 68 61 +6E 20 6D 61 78 69 6D 75 6D 2E 00 00 64 69 66 5F +6B 6D 61 63 5F 6D 6F 64 65 5F 73 68 61 33 5F 73 +74 61 72 74 3A 20 45 52 52 4F 52 20 6B 6D 61 63 +20 6F 72 20 6F 70 65 72 61 74 69 6F 6E 5F 73 74 +61 74 65 20 4E 55 4C 4C 2E 00 00 00 64 69 66 5F +6B 6D 61 63 5F 73 68 61 33 5F 73 74 61 72 74 3A +20 45 52 52 4F 52 20 55 6E 73 75 70 70 6F 72 74 +65 64 20 6D 6F 64 65 2E 00 00 00 00 64 69 66 5F +6B 6D 61 63 5F 73 68 61 33 5F 73 74 61 72 74 3A +20 45 52 52 4F 52 20 68 61 72 64 77 61 72 65 20 +6D 75 73 74 20 62 65 20 69 64 6C 65 2E 00 00 00 +64 69 66 5F 6B 6D 61 63 5F 6D 6F 64 65 5F 73 68 +61 6B 65 5F 73 74 61 72 74 3A 20 45 52 52 4F 52 +20 6B 6D 61 63 20 61 6E 64 20 6F 70 65 72 61 74 +69 6F 6E 20 73 74 61 74 65 20 63 61 6E 6E 6F 74 +20 62 65 20 4E 55 4C 4C 2E 00 00 00 64 69 66 5F +6B 6D 61 63 5F 6D 6F 64 65 5F 73 68 61 6B 65 5F +73 74 61 72 74 3A 20 45 52 52 4F 52 20 6D 6F 64 +65 20 6E 6F 74 20 61 6C 6C 6F 77 65 64 2E 00 00 +64 69 66 5F 6B 6D 61 63 5F 73 68 61 6B 65 5F 73 +74 61 72 74 3A 20 45 52 52 4F 52 20 68 61 72 64 +77 61 72 65 20 6D 75 73 74 20 62 65 20 69 64 6C +65 2E 00 00 64 69 66 5F 6B 6D 61 63 5F 6D 6F 64 +65 5F 63 73 68 61 6B 65 5F 73 74 61 72 74 3A 20 +45 52 52 4F 52 20 6B 6D 61 63 20 6F 72 20 6F 70 +65 72 61 74 69 6F 6E 20 73 74 61 74 65 20 69 73 +20 4E 55 4C 4C 2E 00 00 64 69 66 5F 6B 6D 61 63 +5F 6D 6F 64 65 5F 63 73 68 61 6B 65 5F 73 74 61 +72 74 3A 20 45 52 52 4F 52 20 75 6E 73 75 70 70 +6F 72 74 65 64 20 6D 6F 64 65 20 66 6F 72 20 65 +6D 70 74 79 20 4E 20 61 6E 64 20 53 2E 00 00 00 +64 69 66 5F 6B 6D 61 63 5F 6D 6F 64 65 5F 63 73 +68 61 6B 65 5F 73 74 61 72 74 3A 20 45 52 52 4F +52 20 75 6E 73 75 70 70 6F 72 74 65 64 20 6B 73 +74 72 65 6E 67 68 74 2E 00 00 00 00 64 69 66 5F +6B 6D 61 63 5F 6D 6F 64 65 5F 63 73 68 61 6B 65 +5F 73 74 61 72 74 3A 20 45 52 52 4F 52 20 68 61 +72 64 77 61 72 65 20 6D 75 73 74 20 62 65 20 69 +64 6C 65 2E 00 00 00 00 64 69 66 5F 6B 6D 61 63 +5F 61 62 73 6F 72 62 3A 20 45 52 52 4F 52 20 6F +6E 65 20 6F 66 20 66 75 6E 63 74 69 6F 6E 20 61 +72 67 75 6D 65 6E 74 73 20 69 73 20 6E 75 6C 6C +00 00 00 00 64 69 66 5F 6B 6D 61 63 5F 61 62 73 +6F 72 62 3A 20 45 52 52 4F 52 20 6F 70 65 72 61 +74 69 6F 6E 20 6E 6F 74 20 73 74 61 72 74 65 64 +20 79 65 74 00 00 00 00 64 69 66 5F 6B 6D 61 63 +5F 61 62 73 6F 72 62 3A 20 45 52 52 4F 52 20 68 +61 72 64 77 61 72 65 20 6D 75 73 74 20 62 65 20 +61 62 73 6F 72 62 69 6E 67 2E 00 00 64 69 66 5F +6B 6D 61 63 5F 73 71 75 65 65 7A 65 3A 20 45 52 +52 4F 52 20 61 72 67 75 6D 65 6E 74 73 20 6D 61 +79 20 6E 6F 74 20 62 65 20 4E 55 4C 4C 2E 00 00 +64 69 66 5F 6B 6D 61 63 5F 73 71 75 65 65 7A 65 +3A 20 45 52 52 4F 52 20 74 6F 74 61 6C 20 62 79 +74 65 73 20 72 65 71 75 65 73 74 65 64 20 6D 75 +73 74 20 6E 6F 74 20 65 78 63 65 65 64 20 66 69 +78 65 64 20 6F 75 74 70 75 74 20 6C 65 6E 67 74 +68 2E 00 00 64 69 66 5F 6B 6D 61 63 5F 73 71 75 +65 65 7A 65 3A 20 45 52 52 4F 52 20 6F 70 65 72 +61 74 69 6F 6E 20 73 74 61 74 65 20 64 20 6C 65 +73 73 20 74 68 61 6E 20 72 2E 00 00 64 69 66 5F +6B 6D 61 63 5F 65 6E 64 3A 20 45 52 52 4F 52 20 +61 72 67 75 6D 65 6E 74 73 20 6D 61 79 20 6E 6F +74 20 62 65 20 4E 55 4C 4C 2E 00 00 64 69 66 5F +6B 6D 61 63 5F 65 6E 64 3A 20 45 52 52 4F 52 20 +68 61 72 64 77 61 72 65 20 6D 75 73 74 20 62 65 +20 64 6F 6E 65 20 73 71 75 65 65 7A 69 6E 67 2E +00 00 00 00 53 4F 43 5F 49 46 43 3A 20 43 68 65 +63 6B 20 6D 62 6F 78 5F 73 74 61 74 75 73 2E 6D +62 6F 78 5F 66 73 6D 5F 70 73 00 00 53 4F 43 5F +49 46 43 3A 20 43 68 65 63 6B 20 6D 62 6F 78 5F +73 74 61 74 75 73 2E 6D 62 6F 78 5F 66 73 6D 5F +70 73 20 66 6F 75 6E 64 20 4D 42 4F 58 5F 45 58 +45 43 55 54 45 5F 55 43 00 00 00 00 53 4F 43 5F +49 46 43 3A 20 43 68 65 63 6B 20 6D 62 6F 78 5F +73 74 61 74 75 73 2E 6D 62 6F 78 5F 66 73 6D 5F +70 73 20 66 6F 75 6E 64 20 4D 42 4F 58 5F 49 44 +4C 45 00 00 53 4F 43 5F 49 46 43 3A 20 43 68 65 +63 6B 20 6D 62 6F 78 5F 73 74 61 74 75 73 2E 6D +62 6F 78 5F 66 73 6D 5F 70 73 20 66 6F 75 6E 64 +20 4D 42 4F 58 5F 45 52 52 4F 52 2C 20 6D 61 69 +6C 62 6F 78 20 66 6F 72 63 65 2D 75 6E 6C 6F 63 +6B 20 6E 65 65 64 65 64 00 00 00 00 53 4F 43 5F +49 46 43 3A 20 42 65 67 69 6E 6E 69 6E 67 20 6D +62 6F 78 20 66 77 20 66 6C 6F 77 00 53 4F 43 5F +49 46 43 3A 20 43 70 20 74 6F 20 49 43 43 4D 00 +53 4F 43 5F 49 46 43 3A 20 43 70 20 74 6F 20 44 +43 43 4D 00 43 6F 70 79 69 6E 67 20 63 6F 64 65 +20 66 72 6F 6D 20 6D 61 69 6C 62 6F 78 20 74 6F +20 49 43 43 4D 00 00 00 46 61 69 6C 65 64 20 74 +6F 20 61 63 71 75 69 72 65 20 6C 6F 63 6B 20 2D +20 6D 62 6F 78 20 73 61 6E 69 74 69 7A 65 00 00 +77 6F 6E 27 74 20 6F 76 65 72 72 69 64 65 00 00 +77 69 6C 6C 20 75 73 65 20 64 65 66 61 75 6C 74 +20 35 00 00 77 69 6C 6C 20 6F 76 65 72 72 69 64 +65 00 00 00 46 41 54 41 4C 3A 20 41 58 49 20 44 +4D 41 20 72 65 70 6F 72 74 73 20 65 72 72 6F 72 +20 73 74 61 74 75 73 20 66 6F 72 20 78 66 65 72 +00 00 00 00 41 58 49 20 44 4D 41 20 72 65 70 6F +72 74 73 20 73 74 61 74 75 73 20 66 6F 72 20 78 +66 65 72 20 74 68 61 74 20 77 6F 75 6C 64 20 72 +65 71 75 69 72 65 20 44 4D 41 20 46 6C 75 73 68 +00 00 00 00 41 58 49 20 44 4D 41 20 64 69 64 20 +6E 6F 74 20 72 65 70 6F 72 74 20 65 72 72 20 73 +74 61 74 75 73 20 66 6F 72 20 78 66 65 72 20 74 +68 61 74 20 77 6F 75 6C 64 20 72 65 71 75 69 72 +65 20 44 4D 41 20 46 6C 75 73 68 00 41 63 71 75 +69 72 65 20 6D 61 69 6C 62 6F 78 20 6C 6F 63 6B +20 66 61 69 6C 65 64 00 46 41 54 41 4C 3A 20 41 +58 49 20 44 4D 41 20 72 65 70 6F 72 74 73 20 65 +72 72 6F 72 20 73 74 61 74 75 73 20 66 6F 72 20 +4D 42 4F 58 2D 74 6F 2D 41 58 49 20 78 66 65 72 +00 00 00 00 46 57 3A 20 53 65 6E 64 69 6E 67 20 +4B 56 20 74 6F 20 41 58 49 20 77 69 74 68 20 45 +52 52 00 00 41 58 49 20 44 4D 41 20 72 65 70 6F +72 74 73 20 65 72 72 20 73 74 61 74 75 73 20 66 +6F 72 20 65 72 72 20 69 6E 6A 65 63 74 69 6F 6E +20 78 66 65 72 00 00 00 46 41 54 41 4C 3A 20 41 +58 49 20 44 4D 41 20 72 65 70 6F 72 74 73 20 73 +75 63 63 65 73 73 20 73 74 61 74 75 73 20 66 6F +72 20 65 72 72 20 69 6E 6A 65 63 74 69 6F 6E 20 +78 66 65 72 21 00 00 00 46 57 3A 20 53 65 6E 64 +69 6E 67 20 4B 56 20 74 6F 20 41 58 49 00 00 00 +46 57 3A 20 41 72 6D 20 65 72 72 20 63 6F 6D 6D +61 6E 64 00 45 6E 20 69 6E 74 20 74 6D 72 30 2C +20 68 6C 74 20 63 6F 72 65 00 00 00 44 69 73 61 +62 6C 69 6E 67 20 62 6F 74 68 20 74 69 6D 65 72 +73 20 69 6E 20 69 6E 64 65 70 65 6E 64 65 6E 74 +20 6D 6F 64 65 00 00 00 45 6E 61 62 6C 69 6E 67 +20 6F 6E 6C 79 20 74 69 6D 65 72 32 20 69 6E 20 +69 6E 64 65 70 65 6E 64 65 6E 74 20 6D 6F 64 65 +00 00 00 00 45 6E 61 62 6C 69 6E 67 20 62 6F 74 +68 20 74 69 6D 65 72 73 20 69 6E 20 69 6E 64 65 +70 65 6E 64 65 6E 74 20 6D 6F 64 65 00 00 00 00 +E0 06 02 50 E0 06 02 50 +@000145BC +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +@000165BC +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 diff --git a/designs/Caliptra/tests/mlkem/dccm.hex b/designs/Caliptra/tests/mlkem/dccm.hex new file mode 100644 index 0000000..0e692a2 --- /dev/null +++ b/designs/Caliptra/tests/mlkem/dccm.hex @@ -0,0 +1,6683 @@ +@00025EE4 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 F0 1A 00 00 +00 1A 00 00 10 19 00 00 20 18 00 00 30 17 00 00 +40 16 00 00 50 15 00 00 60 14 00 00 70 13 00 00 +80 12 00 00 90 11 00 00 A0 10 00 00 B0 0F 00 00 +64 1B 00 00 64 1B 00 00 64 1B 00 00 64 1B 00 00 +C0 0E 00 00 D0 0D 00 00 E0 0C 00 00 F0 0B 00 00 +00 0B 00 00 10 0A 00 00 20 09 00 00 CA 1B 00 00 +30 08 00 00 40 07 00 00 64 1B 00 00 64 1B 00 00 +64 1B 00 00 64 1B 00 00 64 1B 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 EF BE AD DE +@00030004 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +@00032004 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +@00034004 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +@00036004 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +@00038004 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +@0003A004 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +@0003C004 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +@0003E004 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 diff --git a/designs/Caliptra/tests/mlkem/iccm.hex b/designs/Caliptra/tests/mlkem/iccm.hex new file mode 100644 index 0000000..e69de29 diff --git a/designs/Caliptra/tests/mlkem/mailbox.hex b/designs/Caliptra/tests/mlkem/mailbox.hex new file mode 100644 index 0000000..e69de29 diff --git a/designs/Caliptra/tests/mlkem/program.hex b/designs/Caliptra/tests/mlkem/program.hex new file mode 100644 index 0000000..e8b68b4 --- /dev/null +++ b/designs/Caliptra/tests/mlkem/program.hex @@ -0,0 +1,6146 @@ +@00000000 +73 10 20 B0 73 10 20 B8 B7 A2 AA AA 93 82 92 0A +73 90 02 7C 91 42 0F 10 00 00 73 90 92 7F 0F 10 +00 00 97 02 00 00 93 82 A2 14 73 90 52 30 97 12 +01 00 93 82 E2 A7 17 73 01 00 13 03 A3 89 97 03 +02 50 93 83 23 FC 63 FA 62 00 03 AE 02 00 23 A0 +C3 01 91 02 91 03 E3 EA 62 FE 97 72 01 00 93 82 +62 87 17 73 01 00 13 03 E3 92 97 63 02 50 93 83 +A3 DB 63 FA 62 00 03 AE 02 00 23 A0 C3 01 91 02 +91 03 E3 EA 62 FE 17 41 03 50 13 01 A1 F8 25 22 +B7 02 03 30 93 82 C2 0C 13 0F F0 0F 23 A0 E2 01 +E3 08 00 FE 01 00 01 00 01 00 01 00 01 00 01 00 +01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00 +01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00 +01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00 +01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00 +01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00 +01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00 +01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00 +01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00 +01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00 +01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00 +01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00 +01 00 01 00 01 00 01 00 01 00 01 00 F3 22 20 34 +73 23 10 34 F3 23 30 34 37 0E 03 30 13 0E CE 0C +97 0E 02 50 93 8E 0E E8 83 82 0E 00 23 20 5E 00 +85 0E E3 9B 02 FE 05 4F 23 20 EE 01 C1 BF 00 00 +49 74 65 72 61 74 69 6F 6E 20 25 30 75 20 6F 66 +20 25 30 75 0A 00 5D 71 6E CE B7 3D 02 50 83 A7 +CD C5 F9 72 A2 C4 86 C6 A6 C2 CA C0 4E DE 52 DC +56 DA 5A D8 5E D6 62 D4 66 D2 6A D0 93 82 02 5E +09 44 16 91 63 67 F4 4A B7 0C 03 50 EF 10 D0 31 +93 8C 0C 00 83 A7 0C 00 63 8E 07 44 37 07 02 50 +13 07 C7 0F 37 0C 02 50 3A D6 13 07 CC 75 3A C4 +37 17 02 50 13 07 C7 D7 79 7B 3A D4 09 67 13 0A +0B 66 13 06 07 A0 0C 18 52 96 13 09 0B 60 33 0A +B6 00 13 06 07 A0 4A 96 93 0B 0B 63 33 09 B6 00 +13 06 07 A0 FD 77 5E 96 93 86 07 3A B3 0B B6 00 +93 87 07 D8 13 06 07 A0 13 07 07 A0 36 96 3E 97 +37 08 02 50 B7 04 02 50 37 64 02 50 B3 06 B6 00 +B3 07 B7 00 81 49 93 0A C8 07 93 84 C4 71 13 04 +84 E2 13 0D C1 18 36 D2 3E C2 03 A7 CD C5 89 47 +63 E9 E7 3E 83 A7 8A 03 83 A3 4A 00 83 A2 8A 00 +83 AF CA 00 03 AF 0A 01 83 AE 4A 01 03 AE 8A 01 +03 A3 CA 01 83 A8 0A 02 03 A5 4A 02 83 A5 8A 02 +03 A6 CA 02 83 A6 0A 03 03 A7 4A 03 83 A0 0A 00 +23 24 F1 18 83 A7 CA 03 23 28 11 14 23 2A 71 14 +23 2C 51 14 23 2E F1 15 23 20 E1 17 23 22 D1 17 +23 24 C1 17 23 26 61 16 23 28 11 17 23 2A A1 16 +23 2C B1 16 23 2E C1 16 23 20 D1 18 23 22 E1 18 +23 06 01 14 23 26 F1 18 83 A7 8A 07 83 A3 4A 04 +83 A2 8A 04 83 AF CA 04 03 AF 0A 05 83 AE 4A 05 +03 AE 8A 05 03 A3 CA 05 83 A0 0A 04 03 A5 4A 06 +83 A5 8A 06 03 A6 CA 06 83 A6 0A 07 03 A7 4A 07 +83 A8 0A 06 23 22 F1 14 23 02 01 10 23 24 11 10 +23 26 71 10 23 28 51 10 23 2A F1 11 23 2C E1 11 +23 2E D1 11 23 20 C1 13 23 22 61 12 23 04 01 12 +23 26 11 13 23 28 A1 12 23 2A B1 12 23 2C C1 12 +23 2E D1 12 23 20 E1 14 03 A7 CA 07 FC 02 23 24 +E1 14 18 09 88 43 CC 43 90 47 D4 47 08 C3 4C C3 +10 C7 54 C7 C1 07 41 07 E3 96 A7 FF 83 27 0D 00 +32 56 B7 26 02 50 1C C3 93 86 C6 FF A6 85 52 85 +EF 80 A0 3C EF 80 20 35 03 27 41 13 83 20 41 10 +83 23 81 10 83 22 C1 10 83 2F 01 11 03 2F 41 11 +83 2E 81 11 83 26 C1 13 03 26 01 14 83 25 41 14 +03 25 81 14 3A C6 03 27 81 13 03 2E C1 11 83 27 +81 12 86 D0 9E D2 96 D4 FE D6 FA D8 F6 DA 36 CA +32 CC 2E CE 2A D0 3A C8 03 23 01 12 83 28 41 12 +A2 46 22 55 03 28 C1 12 03 2C 01 13 F2 DC 3E D8 +B2 47 9A DE 46 C1 3E DE D2 47 42 DA 62 DC 23 22 +04 04 BE C2 E2 47 42 48 4A 87 BE C4 F2 47 26 86 +DE 85 BE C6 82 57 C2 C0 BE C8 EF 80 90 4C EF 80 +80 2B 03 27 41 14 83 27 81 14 83 22 81 12 83 2F +C1 12 03 2F 01 13 83 2E 41 13 03 2E 81 13 03 23 +C1 13 83 28 01 14 A2 45 37 15 02 50 23 22 04 04 +CA 86 26 86 13 05 C5 39 BA C6 BE C8 16 D8 7E DA +7A DC 76 DE F2 C0 9A C2 C6 C4 EF 90 D0 0D EF 80 +80 26 FC 02 23 22 04 04 18 09 88 43 CC 43 90 47 +D4 47 08 C3 4C C3 10 C7 54 C7 C1 07 41 07 E3 96 +A7 FF 89 66 93 08 0B 76 93 86 06 A0 C6 96 83 27 +0D 00 10 18 33 8C C6 00 92 56 62 86 1C C3 A6 85 +52 85 EF 80 60 6B EF 80 00 22 83 27 41 14 83 20 +41 10 83 23 81 10 3E C8 83 27 81 14 83 22 C1 10 +83 2F 01 11 03 2F 41 11 83 2E 81 11 03 2E C1 11 +03 23 01 12 03 25 41 12 83 25 81 12 03 26 C1 12 +3E CA 83 27 81 13 03 27 41 13 83 26 01 13 03 28 +C1 13 86 D0 9E D2 96 D4 FE D6 FA D8 F6 DA F2 DC +3E C6 9A DE 2A C1 2E D8 32 DA 83 28 01 14 36 DC +3A DE 23 22 04 04 C2 C2 42 48 89 66 32 43 93 07 +4B 6B 13 87 06 A0 C2 C6 92 46 52 48 3E 97 1C 18 +BA 97 26 86 4A 87 DE 85 62 85 9A C0 C6 C4 C2 C8 +EF 90 00 21 EF 80 20 18 7E 57 83 27 01 10 2E 53 +3E 55 CE 55 5E 56 EE 56 9E 58 23 22 E1 14 23 24 +F1 14 23 22 04 04 23 28 61 12 23 26 11 13 23 2A +A1 12 23 2C B1 12 23 2E C1 12 23 20 D1 14 FC 02 +18 09 88 43 CC 43 90 47 D4 47 08 C3 4C C3 10 C7 +54 C7 C1 07 41 07 E3 96 A7 FF 83 26 0D 00 83 27 +81 14 83 23 81 12 83 22 C1 12 83 2F 01 13 03 2F +41 13 83 2E 81 13 03 2E C1 13 03 23 01 14 83 28 +41 14 92 45 14 C3 26 86 CA 86 52 85 BE C8 1E D8 +16 DA 7E DC 7A DE F6 C0 F2 C2 9A C4 C6 C6 EF 90 +10 5E EF 80 40 0E 23 22 04 04 83 A7 0C 00 85 09 +E3 ED F9 C2 13 05 F0 0F EF 20 60 26 89 62 93 82 +02 A2 16 91 B6 40 26 44 96 44 06 49 F2 59 62 5A +D2 5A 42 5B B2 5B 22 5C 92 5C 02 5D F2 4D 61 61 +82 80 03 A6 0C 00 CE 85 13 05 00 1A EF 20 20 27 +11 B1 B7 34 02 50 13 85 84 62 EF 20 40 24 83 A7 +CD C5 E3 73 F4 B4 37 35 02 50 13 05 85 64 EF 20 +00 23 83 A7 CD C5 E3 79 F4 B2 13 85 84 62 EF 20 +00 22 1D B6 6F 10 10 17 6F 10 C0 49 00 00 00 00 +6F 10 40 49 00 00 00 00 6F 10 C0 48 00 00 00 00 +6F 10 10 06 00 00 00 00 6F 10 C0 47 00 00 00 00 +6F 10 40 47 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 6F 10 D0 07 6F 10 10 08 +5D 71 2A DA 13 05 B0 0F 22 DE 36 D4 3E D0 86 C6 +96 C4 9A C2 9E C0 26 DC 2E D8 32 D6 3A D2 42 CE +46 CC 4A CA 4E C8 72 C6 76 C4 7A C2 7E C0 37 34 +02 50 EF 20 C0 14 83 26 C4 C5 8D 47 63 E9 D7 08 +F3 27 B0 BC F3 29 C0 BC 73 29 10 34 F3 24 00 30 +73 24 40 30 73 90 C7 BC A1 47 73 A0 07 30 37 67 +02 50 83 27 47 E2 0D 46 85 07 23 22 F7 E2 63 69 +D6 06 A1 47 73 B0 07 30 73 90 C9 BC 73 10 19 34 +89 67 93 87 07 88 FD 8C 73 A0 04 30 85 67 93 87 +87 88 7D 8C 73 20 44 30 13 05 C0 0F EF 20 20 0E +72 54 B6 40 A6 42 16 43 86 43 E2 54 52 55 C2 55 +32 56 A2 56 12 57 82 57 72 48 E2 48 52 49 C2 49 +32 4E A2 4E 12 4F 82 4F 61 61 73 00 20 30 37 35 +02 50 13 05 85 66 EF 20 80 0C 83 26 C4 C5 8D B7 +83 25 47 E2 09 65 13 05 05 13 EF 20 40 0D 51 B7 +5D 71 2A DA 13 05 B0 0F 22 DE 36 D4 3E D0 86 C6 +96 C4 9A C2 9E C0 26 DC 2E D8 32 D6 3A D2 42 CE +46 CC 4A CA 4E C8 72 C6 76 C4 7A C2 7E C0 37 34 +02 50 EF 20 C0 05 83 26 C4 C5 8D 47 63 E9 D7 08 +F3 27 B0 BC F3 29 C0 BC 73 29 10 34 F3 24 00 30 +73 24 40 30 73 90 C7 BC A1 47 73 A0 07 30 37 67 +02 50 83 27 47 E2 0D 46 85 07 23 22 F7 E2 63 69 +D6 06 A1 47 73 B0 07 30 73 90 C9 BC 73 10 19 34 +89 67 93 87 07 88 FD 8C 73 A0 04 30 85 67 93 87 +87 88 7D 8C 73 20 44 30 13 05 C0 0F EF 10 30 7F +72 54 B6 40 A6 42 16 43 86 43 E2 54 52 55 C2 55 +32 56 A2 56 12 57 82 57 72 48 E2 48 52 49 C2 49 +32 4E A2 4E 12 4F 82 4F 61 61 73 00 20 30 37 35 +02 50 13 05 C5 67 EF 10 90 7D 83 26 C4 C5 8D B7 +83 25 47 E2 09 65 13 05 85 14 EF 10 50 7E 51 B7 +5D 71 2A DA 13 05 B0 0F 22 DE 36 D4 3E D0 86 C6 +96 C4 9A C2 9E C0 26 DC 2E D8 32 D6 3A D2 42 CE +46 CC 4A CA 4E C8 72 C6 76 C4 7A C2 7E C0 37 34 +02 50 EF 10 D0 76 83 26 C4 C5 8D 47 63 E9 D7 08 +F3 27 B0 BC F3 29 C0 BC 73 29 10 34 F3 24 00 30 +73 24 40 30 73 90 C7 BC A1 47 73 A0 07 30 37 67 +02 50 83 27 47 E2 0D 46 85 07 23 22 F7 E2 63 69 +D6 06 A1 47 73 B0 07 30 73 90 C9 BC 73 10 19 34 +89 67 93 87 07 88 FD 8C 73 A0 04 30 85 67 93 87 +87 88 7D 8C 73 20 44 30 13 05 C0 0F EF 10 30 70 +72 54 B6 40 A6 42 16 43 86 43 E2 54 52 55 C2 55 +32 56 A2 56 12 57 82 57 72 48 E2 48 52 49 C2 49 +32 4E A2 4E 12 4F 82 4F 61 61 73 00 20 30 37 35 +02 50 13 05 05 69 EF 10 90 6E 83 26 C4 C5 8D B7 +83 25 47 E2 09 65 13 05 05 16 EF 10 50 6F 51 B7 +5D 71 2A DA 13 05 B0 0F 22 DE 36 D4 3E D0 86 C6 +96 C4 9A C2 9E C0 26 DC 2E D8 32 D6 3A D2 42 CE +46 CC 4A CA 4E C8 72 C6 76 C4 7A C2 7E C0 37 34 +02 50 EF 10 D0 67 83 26 C4 C5 8D 47 63 E9 D7 08 +F3 27 B0 BC F3 29 C0 BC 73 29 10 34 F3 24 00 30 +73 24 40 30 73 90 C7 BC A1 47 73 A0 07 30 37 67 +02 50 83 27 47 E2 0D 46 85 07 23 22 F7 E2 63 69 +D6 06 A1 47 73 B0 07 30 73 90 C9 BC 73 10 19 34 +89 67 93 87 07 88 FD 8C 73 A0 04 30 85 67 93 87 +87 88 7D 8C 73 20 44 30 13 05 C0 0F EF 10 30 61 +72 54 B6 40 A6 42 16 43 86 43 E2 54 52 55 C2 55 +32 56 A2 56 12 57 82 57 72 48 E2 48 52 49 C2 49 +32 4E A2 4E 12 4F 82 4F 61 61 73 00 20 30 37 35 +02 50 13 05 05 6A EF 10 90 5F 83 26 C4 C5 8D B7 +83 25 47 E2 09 65 13 05 45 17 EF 10 50 60 51 B7 +5D 71 2A DA 13 05 B0 0F 22 DE 36 D4 3E D0 86 C6 +96 C4 9A C2 9E C0 26 DC 2E D8 32 D6 3A D2 42 CE +46 CC 4A CA 4E C8 72 C6 76 C4 7A C2 7E C0 37 34 +02 50 EF 10 D0 58 83 26 C4 C5 8D 47 63 E9 D7 08 +F3 27 B0 BC F3 29 C0 BC 73 29 10 34 F3 24 00 30 +73 24 40 30 73 90 C7 BC A1 47 73 A0 07 30 37 67 +02 50 83 27 47 E2 0D 46 85 07 23 22 F7 E2 63 69 +D6 06 A1 47 73 B0 07 30 73 90 C9 BC 73 10 19 34 +89 67 93 87 07 88 FD 8C 73 A0 04 30 85 67 93 87 +87 88 7D 8C 73 20 44 30 13 05 C0 0F EF 10 30 52 +72 54 B6 40 A6 42 16 43 86 43 E2 54 52 55 C2 55 +32 56 A2 56 12 57 82 57 72 48 E2 48 52 49 C2 49 +32 4E A2 4E 12 4F 82 4F 61 61 73 00 20 30 37 35 +02 50 13 05 45 6B EF 10 90 50 83 26 C4 C5 8D B7 +83 25 47 E2 09 65 13 05 05 19 EF 10 50 51 51 B7 +5D 71 2A DA 13 05 B0 0F 22 DE 36 D4 3E D0 86 C6 +96 C4 9A C2 9E C0 26 DC 2E D8 32 D6 3A D2 42 CE +46 CC 4A CA 4E C8 72 C6 76 C4 7A C2 7E C0 37 34 +02 50 EF 10 D0 49 83 26 C4 C5 8D 47 63 E9 D7 08 +F3 27 B0 BC F3 29 C0 BC 73 29 10 34 F3 24 00 30 +73 24 40 30 73 90 C7 BC A1 47 73 A0 07 30 37 67 +02 50 83 27 47 E2 0D 46 85 07 23 22 F7 E2 63 69 +D6 06 A1 47 73 B0 07 30 73 90 C9 BC 73 10 19 34 +89 67 93 87 07 88 FD 8C 73 A0 04 30 85 67 93 87 +87 88 7D 8C 73 20 44 30 13 05 C0 0F EF 10 30 43 +72 54 B6 40 A6 42 16 43 86 43 E2 54 52 55 C2 55 +32 56 A2 56 12 57 82 57 72 48 E2 48 52 49 C2 49 +32 4E A2 4E 12 4F 82 4F 61 61 73 00 20 30 37 35 +02 50 13 05 85 6C EF 10 90 41 83 26 C4 C5 8D B7 +83 25 47 E2 09 65 13 05 C5 1A EF 10 50 42 51 B7 +5D 71 2A DA 13 05 B0 0F 22 DE 36 D4 3E D0 86 C6 +96 C4 9A C2 9E C0 26 DC 2E D8 32 D6 3A D2 42 CE +46 CC 4A CA 4E C8 72 C6 76 C4 7A C2 7E C0 37 34 +02 50 EF 10 D0 3A 83 26 C4 C5 8D 47 63 E9 D7 08 +F3 27 B0 BC F3 29 C0 BC 73 29 10 34 F3 24 00 30 +73 24 40 30 73 90 C7 BC A1 47 73 A0 07 30 37 67 +02 50 83 27 47 E2 0D 46 85 07 23 22 F7 E2 63 69 +D6 06 A1 47 73 B0 07 30 73 90 C9 BC 73 10 19 34 +89 67 93 87 07 88 FD 8C 73 A0 04 30 85 67 93 87 +87 88 7D 8C 73 20 44 30 13 05 C0 0F EF 10 30 34 +72 54 B6 40 A6 42 16 43 86 43 E2 54 52 55 C2 55 +32 56 A2 56 12 57 82 57 72 48 E2 48 52 49 C2 49 +32 4E A2 4E 12 4F 82 4F 61 61 73 00 20 30 37 35 +02 50 13 05 C5 6D EF 10 90 32 83 26 C4 C5 8D B7 +83 25 47 E2 09 65 13 05 45 1C EF 10 50 33 51 B7 +5D 71 2A DA 13 05 B0 0F 22 DE 36 D4 3E D0 86 C6 +96 C4 9A C2 9E C0 26 DC 2E D8 32 D6 3A D2 42 CE +46 CC 4A CA 4E C8 72 C6 76 C4 7A C2 7E C0 37 34 +02 50 EF 10 D0 2B 83 26 C4 C5 8D 47 63 E9 D7 08 +F3 27 B0 BC F3 29 C0 BC 73 29 10 34 F3 24 00 30 +73 24 40 30 73 90 C7 BC A1 47 73 A0 07 30 37 67 +02 50 83 27 47 E2 0D 46 85 07 23 22 F7 E2 63 69 +D6 06 A1 47 73 B0 07 30 73 90 C9 BC 73 10 19 34 +89 67 93 87 07 88 FD 8C 73 A0 04 30 85 67 93 87 +87 88 7D 8C 73 20 44 30 13 05 C0 0F EF 10 30 25 +72 54 B6 40 A6 42 16 43 86 43 E2 54 52 55 C2 55 +32 56 A2 56 12 57 82 57 72 48 E2 48 52 49 C2 49 +32 4E A2 4E 12 4F 82 4F 61 61 73 00 20 30 37 35 +02 50 13 05 05 6F EF 10 90 23 83 26 C4 C5 8D B7 +83 25 47 E2 09 65 13 05 C5 1D EF 10 50 24 51 B7 +5D 71 2A DA 13 05 B0 0F 22 DE 36 D4 3E D0 86 C6 +96 C4 9A C2 9E C0 26 DC 2E D8 32 D6 3A D2 42 CE +46 CC 4A CA 4E C8 72 C6 76 C4 7A C2 7E C0 37 34 +02 50 EF 10 D0 1C 83 26 C4 C5 8D 47 63 E9 D7 08 +F3 27 B0 BC F3 29 C0 BC 73 29 10 34 F3 24 00 30 +73 24 40 30 73 90 C7 BC A1 47 73 A0 07 30 37 67 +02 50 83 27 47 E2 0D 46 85 07 23 22 F7 E2 63 69 +D6 06 A1 47 73 B0 07 30 73 90 C9 BC 73 10 19 34 +89 67 93 87 07 88 FD 8C 73 A0 04 30 85 67 93 87 +87 88 7D 8C 73 20 44 30 13 05 C0 0F EF 10 30 16 +72 54 B6 40 A6 42 16 43 86 43 E2 54 52 55 C2 55 +32 56 A2 56 12 57 82 57 72 48 E2 48 52 49 C2 49 +32 4E A2 4E 12 4F 82 4F 61 61 73 00 20 30 37 35 +02 50 13 05 05 70 EF 10 90 14 83 26 C4 C5 8D B7 +83 25 47 E2 09 65 13 05 05 1F EF 10 50 15 51 B7 +5D 71 2A DA 13 05 B0 0F 22 DE 36 D4 3E D0 86 C6 +96 C4 9A C2 9E C0 26 DC 2E D8 32 D6 3A D2 42 CE +46 CC 4A CA 4E C8 72 C6 76 C4 7A C2 7E C0 37 34 +02 50 EF 10 D0 0D 83 26 C4 C5 8D 47 63 E9 D7 08 +F3 27 B0 BC F3 29 C0 BC 73 29 10 34 F3 24 00 30 +73 24 40 30 73 90 C7 BC A1 47 73 A0 07 30 37 67 +02 50 83 27 47 E2 0D 46 85 07 23 22 F7 E2 63 69 +D6 06 A1 47 73 B0 07 30 73 90 C9 BC 73 10 19 34 +89 67 93 87 07 88 FD 8C 73 A0 04 30 85 67 93 87 +87 88 7D 8C 73 20 44 30 13 05 C0 0F EF 10 30 07 +72 54 B6 40 A6 42 16 43 86 43 E2 54 52 55 C2 55 +32 56 A2 56 12 57 82 57 72 48 E2 48 52 49 C2 49 +32 4E A2 4E 12 4F 82 4F 61 61 73 00 20 30 37 35 +02 50 13 05 05 71 EF 10 90 05 83 26 C4 C5 8D B7 +83 25 47 E2 09 65 13 05 45 20 EF 10 50 06 51 B7 +5D 71 2A DA 13 05 B0 0F 22 DE 36 D4 3E D0 86 C6 +96 C4 9A C2 9E C0 26 DC 2E D8 32 D6 3A D2 42 CE +46 CC 4A CA 4E C8 72 C6 76 C4 7A C2 7E C0 37 34 +02 50 EF 10 C0 7E 83 26 C4 C5 8D 47 63 E9 D7 08 +F3 27 B0 BC F3 29 C0 BC 73 29 10 34 F3 24 00 30 +73 24 40 30 73 90 C7 BC A1 47 73 A0 07 30 37 67 +02 50 83 27 47 E2 0D 46 85 07 23 22 F7 E2 63 69 +D6 06 A1 47 73 B0 07 30 73 90 C9 BC 73 10 19 34 +89 67 93 87 07 88 FD 8C 73 A0 04 30 85 67 93 87 +87 88 7D 8C 73 20 44 30 13 05 C0 0F EF 10 20 78 +72 54 B6 40 A6 42 16 43 86 43 E2 54 52 55 C2 55 +32 56 A2 56 12 57 82 57 72 48 E2 48 52 49 C2 49 +32 4E A2 4E 12 4F 82 4F 61 61 73 00 20 30 37 35 +02 50 13 05 05 72 EF 10 80 76 83 26 C4 C5 8D B7 +83 25 47 E2 09 65 13 05 C5 21 EF 10 40 77 51 B7 +5D 71 2A DA 13 05 B0 0F 22 DE 36 D4 3E D0 86 C6 +96 C4 9A C2 9E C0 26 DC 2E D8 32 D6 3A D2 42 CE +46 CC 4A CA 4E C8 72 C6 76 C4 7A C2 7E C0 37 34 +02 50 EF 10 C0 6F 83 26 C4 C5 8D 47 63 E9 D7 08 +F3 27 B0 BC F3 29 C0 BC 73 29 10 34 F3 24 00 30 +73 24 40 30 73 90 C7 BC A1 47 73 A0 07 30 37 67 +02 50 83 27 47 E2 0D 46 85 07 23 22 F7 E2 63 69 +D6 06 A1 47 73 B0 07 30 73 90 C9 BC 73 10 19 34 +89 67 93 87 07 88 FD 8C 73 A0 04 30 85 67 93 87 +87 88 7D 8C 73 20 44 30 13 05 C0 0F EF 10 20 69 +72 54 B6 40 A6 42 16 43 86 43 E2 54 52 55 C2 55 +32 56 A2 56 12 57 82 57 72 48 E2 48 52 49 C2 49 +32 4E A2 4E 12 4F 82 4F 61 61 73 00 20 30 37 35 +02 50 13 05 05 73 EF 10 80 67 83 26 C4 C5 8D B7 +83 25 47 E2 09 65 13 05 45 23 EF 10 40 68 51 B7 +5D 71 2A DA 13 05 B0 0F 22 DE 36 D4 3E D0 86 C6 +96 C4 9A C2 9E C0 26 DC 2E D8 32 D6 3A D2 42 CE +46 CC 4A CA 4E C8 72 C6 76 C4 7A C2 7E C0 37 34 +02 50 EF 10 C0 60 83 26 C4 C5 8D 47 63 E9 D7 08 +F3 27 B0 BC F3 29 C0 BC 73 29 10 34 F3 24 00 30 +73 24 40 30 73 90 C7 BC A1 47 73 A0 07 30 37 67 +02 50 83 27 47 E2 0D 46 85 07 23 22 F7 E2 63 69 +D6 06 A1 47 73 B0 07 30 73 90 C9 BC 73 10 19 34 +89 67 93 87 07 88 FD 8C 73 A0 04 30 85 67 93 87 +87 88 7D 8C 73 20 44 30 13 05 C0 0F EF 10 20 5A +72 54 B6 40 A6 42 16 43 86 43 E2 54 52 55 C2 55 +32 56 A2 56 12 57 82 57 72 48 E2 48 52 49 C2 49 +32 4E A2 4E 12 4F 82 4F 61 61 73 00 20 30 37 35 +02 50 13 05 05 74 EF 10 80 58 83 26 C4 C5 8D B7 +83 25 47 E2 09 65 13 05 C5 24 EF 10 40 59 51 B7 +5D 71 2A DA 13 05 B0 0F 22 DE 36 D4 3E D0 86 C6 +96 C4 9A C2 9E C0 26 DC 2E D8 32 D6 3A D2 42 CE +46 CC 4A CA 4E C8 72 C6 76 C4 7A C2 7E C0 37 34 +02 50 EF 10 C0 51 83 26 C4 C5 8D 47 63 E9 D7 08 +F3 27 B0 BC F3 29 C0 BC 73 29 10 34 F3 24 00 30 +73 24 40 30 73 90 C7 BC A1 47 73 A0 07 30 37 67 +02 50 83 27 47 E2 0D 46 85 07 23 22 F7 E2 63 69 +D6 06 A1 47 73 B0 07 30 73 90 C9 BC 73 10 19 34 +89 67 93 87 07 88 FD 8C 73 A0 04 30 85 67 93 87 +87 88 7D 8C 73 20 44 30 13 05 C0 0F EF 10 20 4B +72 54 B6 40 A6 42 16 43 86 43 E2 54 52 55 C2 55 +32 56 A2 56 12 57 82 57 72 48 E2 48 52 49 C2 49 +32 4E A2 4E 12 4F 82 4F 61 61 73 00 20 30 37 35 +02 50 13 05 05 75 EF 10 80 49 83 26 C4 C5 8D B7 +83 25 47 E2 09 65 13 05 45 26 EF 10 40 4A 51 B7 +5D 71 2A DA 13 05 B0 0F 22 DE 36 D4 3E D0 86 C6 +96 C4 9A C2 9E C0 26 DC 2E D8 32 D6 3A D2 42 CE +46 CC 4A CA 4E C8 72 C6 76 C4 7A C2 7E C0 37 34 +02 50 EF 10 C0 42 83 26 C4 C5 8D 47 63 E9 D7 08 +F3 27 B0 BC F3 29 C0 BC 73 29 10 34 F3 24 00 30 +73 24 40 30 73 90 C7 BC A1 47 73 A0 07 30 37 67 +02 50 83 27 47 E2 0D 46 85 07 23 22 F7 E2 63 69 +D6 06 A1 47 73 B0 07 30 73 90 C9 BC 73 10 19 34 +89 67 93 87 07 88 FD 8C 73 A0 04 30 85 67 93 87 +87 88 7D 8C 73 20 44 30 13 05 C0 0F EF 10 20 3C +72 54 B6 40 A6 42 16 43 86 43 E2 54 52 55 C2 55 +32 56 A2 56 12 57 82 57 72 48 E2 48 52 49 C2 49 +32 4E A2 4E 12 4F 82 4F 61 61 73 00 20 30 37 35 +02 50 13 05 C5 75 EF 10 80 3A 83 26 C4 C5 8D B7 +83 25 47 E2 09 65 13 05 85 27 EF 10 40 3B 51 B7 +5D 71 2A DA 13 05 B0 0F 22 DE 36 D4 3E D0 86 C6 +96 C4 9A C2 9E C0 26 DC 2E D8 32 D6 3A D2 42 CE +46 CC 4A CA 4E C8 72 C6 76 C4 7A C2 7E C0 37 34 +02 50 EF 10 C0 33 83 26 C4 C5 8D 47 63 E9 D7 08 +F3 27 B0 BC F3 29 C0 BC 73 29 10 34 F3 24 00 30 +73 24 40 30 73 90 C7 BC A1 47 73 A0 07 30 37 67 +02 50 83 27 47 E2 0D 46 85 07 23 22 F7 E2 63 69 +D6 06 A1 47 73 B0 07 30 73 90 C9 BC 73 10 19 34 +89 67 93 87 07 88 FD 8C 73 A0 04 30 85 67 93 87 +87 88 7D 8C 73 20 44 30 13 05 C0 0F EF 10 20 2D +72 54 B6 40 A6 42 16 43 86 43 E2 54 52 55 C2 55 +32 56 A2 56 12 57 82 57 72 48 E2 48 52 49 C2 49 +32 4E A2 4E 12 4F 82 4F 61 61 73 00 20 30 37 35 +02 50 13 05 85 76 EF 10 80 2B 83 26 C4 C5 8D B7 +83 25 47 E2 09 65 13 05 C5 28 EF 10 40 2C 51 B7 +5D 71 2A DA 13 05 B0 0F 22 DE 36 D4 3E D0 86 C6 +96 C4 9A C2 9E C0 26 DC 2E D8 32 D6 3A D2 42 CE +46 CC 4A CA 4E C8 72 C6 76 C4 7A C2 7E C0 37 34 +02 50 EF 10 C0 24 83 26 C4 C5 8D 47 63 E9 D7 08 +F3 27 B0 BC F3 29 C0 BC 73 29 10 34 F3 24 00 30 +73 24 40 30 73 90 C7 BC A1 47 73 A0 07 30 37 67 +02 50 83 27 47 E2 0D 46 85 07 23 22 F7 E2 63 69 +D6 06 A1 47 73 B0 07 30 73 90 C9 BC 73 10 19 34 +89 67 93 87 07 88 FD 8C 73 A0 04 30 85 67 93 87 +87 88 7D 8C 73 20 44 30 13 05 C0 0F EF 10 20 1E +72 54 B6 40 A6 42 16 43 86 43 E2 54 52 55 C2 55 +32 56 A2 56 12 57 82 57 72 48 E2 48 52 49 C2 49 +32 4E A2 4E 12 4F 82 4F 61 61 73 00 20 30 37 35 +02 50 13 05 85 77 EF 10 80 1C 83 26 C4 C5 8D B7 +83 25 47 E2 09 65 13 05 05 2A EF 10 40 1D 51 B7 +5D 71 2A DA 13 05 B0 0F 22 DE 36 D4 3E D0 86 C6 +96 C4 9A C2 9E C0 26 DC 2E D8 32 D6 3A D2 42 CE +46 CC 4A CA 4E C8 72 C6 76 C4 7A C2 7E C0 37 34 +02 50 EF 10 C0 15 83 26 C4 C5 8D 47 63 E9 D7 08 +F3 27 B0 BC F3 29 C0 BC 73 29 10 34 F3 24 00 30 +73 24 40 30 73 90 C7 BC A1 47 73 A0 07 30 37 67 +02 50 83 27 47 E2 0D 46 85 07 23 22 F7 E2 63 69 +D6 06 A1 47 73 B0 07 30 73 90 C9 BC 73 10 19 34 +89 67 93 87 07 88 FD 8C 73 A0 04 30 85 67 93 87 +87 88 7D 8C 73 20 44 30 13 05 C0 0F EF 10 20 0F +72 54 B6 40 A6 42 16 43 86 43 E2 54 52 55 C2 55 +32 56 A2 56 12 57 82 57 72 48 E2 48 52 49 C2 49 +32 4E A2 4E 12 4F 82 4F 61 61 73 00 20 30 37 35 +02 50 13 05 85 78 EF 10 80 0D 83 26 C4 C5 8D B7 +83 25 47 E2 09 65 13 05 45 2B EF 10 40 0E 51 B7 +5D 71 2A DA 13 05 B0 0F 22 DE 36 D4 3E D0 86 C6 +96 C4 9A C2 9E C0 26 DC 2E D8 32 D6 3A D2 42 CE +46 CC 4A CA 4E C8 72 C6 76 C4 7A C2 7E C0 37 34 +02 50 EF 10 C0 06 83 26 C4 C5 8D 47 63 E9 D7 08 +F3 27 B0 BC F3 29 C0 BC 73 29 10 34 F3 24 00 30 +73 24 40 30 73 90 C7 BC A1 47 73 A0 07 30 37 67 +02 50 83 27 47 E2 0D 46 85 07 23 22 F7 E2 63 69 +D6 06 A1 47 73 B0 07 30 73 90 C9 BC 73 10 19 34 +89 67 93 87 07 88 FD 8C 73 A0 04 30 85 67 93 87 +87 88 7D 8C 73 20 44 30 13 05 C0 0F EF 10 20 00 +72 54 B6 40 A6 42 16 43 86 43 E2 54 52 55 C2 55 +32 56 A2 56 12 57 82 57 72 48 E2 48 52 49 C2 49 +32 4E A2 4E 12 4F 82 4F 61 61 73 00 20 30 37 35 +02 50 13 05 85 79 EF 00 90 7E 83 26 C4 C5 8D B7 +83 25 47 E2 09 65 13 05 85 2C EF 00 50 7F 51 B7 +5D 71 2A DA 13 05 B0 0F 22 DE 36 D4 3E D0 86 C6 +96 C4 9A C2 9E C0 26 DC 2E D8 32 D6 3A D2 42 CE +46 CC 4A CA 4E C8 72 C6 76 C4 7A C2 7E C0 37 34 +02 50 EF 00 D0 77 83 26 C4 C5 8D 47 63 E9 D7 08 +F3 27 B0 BC F3 29 C0 BC 73 29 10 34 F3 24 00 30 +73 24 40 30 73 90 C7 BC A1 47 73 A0 07 30 37 67 +02 50 83 27 47 E2 0D 46 85 07 23 22 F7 E2 63 69 +D6 06 A1 47 73 B0 07 30 73 90 C9 BC 73 10 19 34 +89 67 93 87 07 88 FD 8C 73 A0 04 30 85 67 93 87 +87 88 7D 8C 73 20 44 30 13 05 C0 0F EF 00 30 71 +72 54 B6 40 A6 42 16 43 86 43 E2 54 52 55 C2 55 +32 56 A2 56 12 57 82 57 72 48 E2 48 52 49 C2 49 +32 4E A2 4E 12 4F 82 4F 61 61 73 00 20 30 37 35 +02 50 13 05 85 7A EF 00 90 6F 83 26 C4 C5 8D B7 +83 25 47 E2 09 65 13 05 C5 2D EF 00 50 70 51 B7 +5D 71 2A DA 13 05 B0 0F 22 DE 36 D4 3E D0 86 C6 +96 C4 9A C2 9E C0 26 DC 2E D8 32 D6 3A D2 42 CE +46 CC 4A CA 4E C8 72 C6 76 C4 7A C2 7E C0 37 34 +02 50 EF 00 D0 68 83 26 C4 C5 8D 47 63 E9 D7 08 +F3 27 B0 BC F3 29 C0 BC 73 29 10 34 F3 24 00 30 +73 24 40 30 73 90 C7 BC A1 47 73 A0 07 30 37 67 +02 50 83 27 47 E2 0D 46 85 07 23 22 F7 E2 63 69 +D6 06 A1 47 73 B0 07 30 73 90 C9 BC 73 10 19 34 +89 67 93 87 07 88 FD 8C 73 A0 04 30 85 67 93 87 +87 88 7D 8C 73 20 44 30 13 05 C0 0F EF 00 30 62 +72 54 B6 40 A6 42 16 43 86 43 E2 54 52 55 C2 55 +32 56 A2 56 12 57 82 57 72 48 E2 48 52 49 C2 49 +32 4E A2 4E 12 4F 82 4F 61 61 73 00 20 30 37 35 +02 50 13 05 85 7B EF 00 90 60 83 26 C4 C5 8D B7 +83 25 47 E2 09 65 13 05 05 2F EF 00 50 61 51 B7 +39 71 2A D6 13 05 B0 0F 3A CE 3E CC 06 DE 16 DC +1A DA 1E D8 2E D4 32 D2 36 D0 42 CA 46 C8 72 C6 +76 C4 7A C2 7E C0 EF 00 90 5A B7 37 02 50 03 A7 +C7 C5 8D 47 63 E9 E7 02 13 05 C0 0F EF 00 30 59 +F2 50 E2 52 52 53 C2 53 32 55 A2 55 12 56 82 56 +72 47 E2 47 52 48 C2 48 32 4E A2 4E 12 4F 82 4F +21 61 73 00 20 30 37 35 02 50 13 05 85 7C EF 00 +10 58 D9 B7 39 71 3E CC B7 37 02 50 3A CE 03 A7 +C7 C5 06 DE 16 DC 1A DA 1E D8 2A D6 2E D4 32 D2 +36 D0 42 CA 46 C8 72 C6 76 C4 7A C2 7E C0 91 47 +63 E5 E7 02 F2 50 E2 52 52 53 C2 53 32 55 A2 55 +12 56 82 56 72 47 E2 47 52 48 C2 48 32 4E A2 4E +12 4F 82 4F 21 61 73 00 20 30 F3 25 20 34 09 65 +13 05 45 30 EF 00 B0 53 F1 B7 1D 71 AA C2 13 05 +B0 0F A2 C6 36 DC 3E D8 86 CE 96 CC 9A CA 9E C8 +A6 C4 AE C0 32 DE 3A DA 42 D6 46 D4 4A D2 4E D0 +52 CE 72 CC 76 CA 7A C8 7E C6 37 34 02 50 EF 00 +10 4C 83 26 C4 C5 8D 47 63 ED D7 0C F3 27 B0 BC +73 2A C0 BC F3 29 10 34 73 29 00 30 F3 24 40 30 +73 90 C7 BC A1 47 73 A0 07 30 37 67 02 50 83 27 +47 E2 0D 46 85 07 23 22 F7 E2 63 6C D6 08 37 87 +03 10 83 27 87 11 93 F6 17 00 A5 CE B7 67 02 50 +93 87 87 E2 F4 43 05 46 23 2C C7 10 13 E7 16 00 +F8 C3 A1 47 73 B0 07 30 73 10 CA BC 73 90 19 34 +89 67 93 87 07 88 33 79 F9 00 73 20 09 30 85 67 +93 87 87 88 FD 8C 73 A0 44 30 13 05 C0 0F EF 00 +10 43 36 44 F6 40 E6 42 56 43 C6 43 A6 44 16 45 +86 45 72 56 E2 56 52 57 C2 57 32 58 A2 58 12 59 +82 59 72 4A 62 4E D2 4E 42 4F B2 4F 25 61 73 00 +20 30 C5 F3 83 27 C4 C5 95 E7 05 45 EF 00 30 3F +01 A0 83 25 47 E2 09 65 13 05 05 31 EF 00 30 42 +B9 BF 37 35 02 50 13 05 05 7D EF 00 50 3F 83 26 +C4 C5 29 BF 09 65 81 45 13 05 45 32 EF 00 30 40 +05 45 EF 00 D0 3B E9 B7 21 47 73 30 07 30 93 07 +40 6C 93 E7 17 00 73 90 57 30 97 42 02 50 93 82 +62 2E 73 90 82 BC B7 37 00 60 23 A0 07 00 0F 00 +F0 0F 73 50 90 BC B7 07 00 60 D8 C3 0F 00 F0 0F +9D 46 94 C7 0F 00 F0 0F D8 C7 0F 00 F0 0F 94 CB +0F 00 F0 0F D8 CB 0F 00 F0 0F 94 CF 0F 00 F0 0F +D8 CF 0F 00 F0 0F 94 D3 0F 00 F0 0F D8 D3 0F 00 +F0 0F 94 D7 0F 00 F0 0F D8 D7 0F 00 F0 0F 94 DB +0F 00 F0 0F 91 45 CC DB 0F 00 F0 0F 0D 46 90 DF +0F 00 F0 0F CC DF 0F 00 F0 0F B0 C3 0F 00 F0 0F +F8 C3 0F 00 F0 0F B4 C7 0F 00 F0 0F F8 C7 0F 00 +F0 0F B4 CB 0F 00 F0 0F F8 CB 0F 00 F0 0F B4 CF +0F 00 F0 0F F8 CF 0F 00 F0 0F B4 D3 0F 00 F0 0F +F8 D3 0F 00 F0 0F B4 D7 0F 00 F0 0F 23 A6 07 06 +0F 00 F0 0F 23 A8 07 06 0F 00 F0 0F 23 AA 07 06 +0F 00 F0 0F 23 AC 07 06 0F 00 F0 0F 23 AE 07 06 +0F 00 F0 0F 73 50 B0 BC 73 50 C0 BC 37 47 00 60 +11 07 85 47 05 68 79 75 93 05 00 02 23 20 07 00 +0F 00 F0 0F B3 06 07 01 23 A0 06 00 0F 00 F0 0F +B3 06 A7 00 13 B6 B7 01 90 C2 0F 00 F0 0F 85 07 +93 F7 F7 0F 11 07 E3 9B B7 FC 05 47 B7 16 00 10 +23 A4 E6 80 8D 47 23 A0 F6 80 B7 96 00 10 23 A2 +E6 80 23 A4 E6 80 23 A0 F6 80 3D 46 B7 16 01 10 +23 A2 C6 80 23 A4 E6 80 23 A0 F6 80 B7 16 02 10 +23 A4 E6 80 23 A0 F6 80 B7 96 02 10 23 A2 F6 80 +23 A4 E6 80 23 A0 F6 80 B7 16 04 10 23 A0 F6 40 +23 A2 E6 40 23 A4 F6 40 1D 46 B7 06 04 10 D0 C2 +B7 86 03 10 23 A2 E6 10 23 A4 E6 10 23 A0 F6 10 +11 46 B7 16 03 30 23 AC C6 80 21 46 23 AC C6 80 +23 A4 06 98 23 A6 06 98 93 05 F0 0F 23 A2 B6 80 +93 05 F0 03 23 A4 B6 80 23 A0 F6 80 B7 26 02 30 +23 A4 E6 80 23 A0 F6 80 37 37 02 30 93 06 F0 07 +23 22 D7 80 FD 46 23 24 D7 80 FD 55 B7 06 03 30 +23 20 F7 80 23 A4 B6 64 B7 07 00 D0 23 A6 B6 64 +73 90 07 7F 73 90 17 7F 73 90 27 7F B7 17 00 40 +93 87 07 88 73 A0 47 30 73 20 06 30 82 80 01 00 +39 71 3A CE 3E CC 7D 57 B7 07 03 30 06 DE 16 DC +1A DA 1E D8 2A D6 2E D4 32 D2 36 D0 42 CA 46 C8 +72 C6 76 C4 7A C2 7E C0 23 A4 E7 64 23 A6 E7 64 +B7 37 02 50 03 A7 C7 C5 8D 47 63 E5 E7 02 F2 50 +E2 52 52 53 C2 53 32 55 A2 55 12 56 82 56 72 47 +E2 47 52 48 C2 48 32 4E A2 4E 12 4F 82 4F 21 61 +73 00 20 30 37 35 02 50 13 05 05 7E EF 00 30 13 +F9 B7 01 00 73 50 40 7D 73 00 20 30 39 71 3E CC +B7 37 02 50 3A CE 03 A7 C7 C5 06 DE 16 DC 1A DA +1E D8 2A D6 2E D4 32 D2 36 D0 42 CA 46 C8 72 C6 +76 C4 7A C2 7E C0 91 47 63 EE E7 02 B7 07 00 08 +FD 17 73 B0 07 7F 73 B0 17 7F 73 B0 27 7F F2 50 +E2 52 52 53 C2 53 32 55 A2 55 12 56 82 56 72 47 +E2 47 52 48 C2 48 32 4E A2 4E 12 4F 82 4F 21 61 +73 00 20 30 37 45 02 50 13 05 C5 80 EF 00 30 0B +75 BF 01 00 5D 71 2A DA 13 05 B0 0F 86 C6 96 C4 +9A C2 9E C0 22 DE 26 DC 2E D8 32 D6 36 D4 3A D2 +3E D0 42 CE 46 CC 4A CA 72 C8 76 C6 7A C4 7E C2 +EF 00 F0 05 F3 24 20 34 37 34 02 50 83 27 C4 C5 +05 47 63 6C F7 04 63 C5 04 04 F3 27 F0 7F F3 27 +10 34 F3 27 30 34 05 45 EF 00 70 03 13 05 C0 0F +EF 00 F0 02 72 54 B6 40 A6 42 16 43 86 43 E2 54 +52 55 C2 55 32 56 A2 56 12 57 82 57 72 48 E2 48 +52 49 42 4E B2 4E 22 4F 92 4F 61 61 73 00 20 30 +AD E3 05 45 EF 00 A0 7F 7D BF 09 69 13 09 09 13 +A6 85 13 05 09 21 EF 00 90 02 83 27 C4 C5 E3 C1 +04 FE F3 25 F0 7F 89 44 63 FA F4 02 13 05 49 24 +EF 00 F0 00 F3 25 10 34 83 27 C4 C5 E3 F3 F4 F8 +13 05 09 25 EF 00 A0 7F F3 25 30 34 83 27 C4 C5 +E3 FB F4 F6 13 05 C9 25 DD 27 B5 B7 F3 27 10 34 +8D B7 09 65 FD 55 13 05 C5 35 D1 2F 59 BF 01 00 +63 6E 74 5F 61 78 69 5F 64 6D 61 5F 6E 6F 74 69 +66 3A 25 78 0A 00 00 00 63 6E 74 5F 61 78 69 5F +64 6D 61 5F 65 72 72 6F 72 3A 25 78 0A 00 00 00 +63 6E 74 5F 61 62 72 5F 65 72 72 6F 72 3A 25 78 +0A 00 00 00 63 6E 74 5F 73 68 61 35 31 32 5F 61 +63 63 5F 6E 6F 74 69 66 3A 25 78 0A 00 00 00 00 +63 6E 74 5F 73 68 61 35 31 32 5F 61 63 63 5F 65 +72 72 6F 72 3A 25 78 0A 00 00 00 00 63 6E 74 5F +73 6F 63 5F 69 66 63 5F 6E 6F 74 69 66 3A 25 78 +0A 00 00 00 63 6E 74 5F 73 6F 63 5F 69 66 63 5F +65 72 72 6F 72 3A 25 78 0A 00 00 00 63 6E 74 5F +73 68 61 33 5F 6E 6F 74 69 66 3A 25 78 0A 00 00 +63 6E 74 5F 73 68 61 33 5F 65 72 72 6F 72 3A 25 +78 0A 00 00 63 6E 74 5F 73 68 61 32 35 36 5F 6E +6F 74 69 66 3A 25 78 0A 00 00 00 00 63 6E 74 5F +73 68 61 32 35 36 5F 65 72 72 6F 72 3A 25 78 0A +00 00 00 00 63 6E 74 5F 73 68 61 35 31 32 5F 6E +6F 74 69 66 3A 25 78 0A 00 00 00 00 63 6E 74 5F +73 68 61 35 31 32 5F 65 72 72 6F 72 3A 25 78 0A +00 00 00 00 63 6E 74 5F 6B 76 5F 6E 6F 74 69 66 +3A 25 78 0A 00 00 00 00 63 6E 74 5F 6B 76 5F 65 +72 72 6F 72 3A 25 78 0A 00 00 00 00 63 6E 74 5F +68 6D 61 63 5F 6E 6F 74 69 66 3A 25 78 0A 00 00 +63 6E 74 5F 68 6D 61 63 5F 65 72 72 6F 72 3A 25 +78 0A 00 00 63 6E 74 5F 65 63 63 5F 6E 6F 74 69 +66 3A 25 78 0A 00 00 00 63 6E 74 5F 65 63 63 5F +65 72 72 6F 72 3A 25 78 0A 00 00 00 63 6E 74 5F +64 6F 65 5F 6E 6F 74 69 66 3A 25 78 0A 00 00 00 +63 6E 74 5F 64 6F 65 5F 65 72 72 6F 72 3A 25 78 +0A 00 00 00 6D 63 61 75 73 65 3A 25 78 0A 00 00 +63 6E 74 5F 61 62 72 5F 6E 6F 74 69 66 3A 25 78 +0A 00 00 00 62 61 64 20 61 62 72 5F 6E 6F 74 69 +66 5F 69 6E 74 72 20 73 74 73 3A 25 78 0A 00 00 +49 6E 3A 53 74 64 20 45 78 63 70 74 6E 0A 6D 63 +61 75 73 65 3A 25 78 0A 00 00 00 00 55 6E 65 78 +70 65 63 74 65 64 20 49 6E 74 72 20 62 69 74 3A +25 78 0A 00 6D 73 63 61 75 73 65 3A 25 78 0A 00 +6D 65 70 63 3A 25 78 0A 00 00 00 00 6D 74 76 61 +6C 3A 25 78 0A 00 00 00 03 47 05 00 63 0E 07 4E +B7 3E 02 50 03 AE 0E C6 39 71 37 3F 02 50 22 DE +AA 87 26 DC 4A DA 4E D8 52 D6 56 D4 5A D2 5E D0 +01 45 93 08 50 02 13 06 00 03 93 03 D0 02 93 02 +A0 02 93 0F 00 02 13 0F 4F C6 25 44 63 03 17 03 +23 20 EE 00 05 05 03 C7 17 00 85 07 65 FB 72 54 +E2 54 52 59 C2 59 32 5A A2 5A 12 5B 82 5B 21 61 +82 80 03 C7 17 00 65 D7 85 07 63 0D 17 05 93 04 +00 02 63 19 C7 00 03 C7 17 00 85 07 E3 0D C7 FE +93 04 00 03 63 05 77 02 63 08 57 02 13 03 07 FD +93 76 F3 0F 01 48 63 7A D4 02 13 07 87 FA 13 77 +F7 0F E3 E2 EF FA 0A 07 7A 97 18 43 02 87 03 C7 +17 00 85 07 E3 1C 57 FC 03 C7 17 00 91 05 85 07 +01 48 E1 BF 23 20 1E 01 BD BF 25 49 03 C7 17 00 +93 16 28 00 C2 96 86 06 33 08 D3 00 13 03 07 FD +93 76 F3 0F 85 07 E3 73 D9 FE 45 BF 98 41 83 A6 +0E C6 91 05 13 58 C7 01 63 12 08 14 13 58 87 01 +63 15 08 20 13 58 47 01 63 08 08 34 19 43 B1 AA +03 A3 05 00 81 46 91 05 13 09 C1 00 A9 49 A5 4B +33 77 33 03 36 8B 85 06 B3 0A D9 00 1A 8A 13 07 +07 03 A3 8F EA FE 33 53 33 03 E3 E3 4B FF 83 A9 +0E C6 33 07 69 01 36 83 63 D7 06 01 23 A0 99 00 +05 03 E3 1D 68 FE 13 03 B1 00 03 48 07 00 7D 17 +23 A0 09 01 E3 1B 67 FE 36 95 F1 BD 03 A3 05 00 +91 05 83 46 03 00 E3 88 06 EC 03 A8 0E C6 1A 87 +05 07 23 20 D8 00 83 46 07 00 FD FA 2A 97 33 05 +67 40 55 BD 98 41 91 05 13 58 E7 01 63 16 08 18 +13 58 B7 01 63 1A 08 26 13 58 87 01 63 0E 08 28 +83 A6 0E C6 A5 44 61 AA 83 AB 05 00 83 AA 0E C6 +91 05 5E 83 63 D9 0B 00 13 07 D0 02 33 03 70 41 +23 A0 EA 00 7D 18 81 46 13 09 C1 00 A9 49 33 67 +33 03 36 8B 85 06 33 0A D9 00 33 43 33 03 13 07 +07 03 A3 0F EA FE E3 14 03 FE 33 07 69 01 36 83 +63 D7 06 01 23 A0 9A 00 05 03 E3 1D 03 FF 13 03 +B1 00 03 48 07 00 7D 17 23 A0 0A 01 E3 1B 67 FE +E3 D4 0B F4 93 06 2B 00 36 95 31 BD 83 C6 05 00 +03 A7 0E C6 05 05 91 05 14 C3 31 B5 93 74 F8 0F +25 49 13 83 04 03 63 6B 09 1B 13 58 87 01 23 A0 +66 00 13 78 F8 00 21 43 93 04 00 03 63 18 08 0A +13 58 47 01 84 C2 13 78 F8 00 25 49 93 74 F8 0F +63 71 09 19 93 84 74 03 93 F4 F4 0F 13 58 07 01 +84 C2 13 78 F8 00 25 49 93 74 F8 0F 63 6F 09 19 +93 84 04 03 93 F4 F4 0F 13 58 C7 00 84 C2 13 78 +F8 00 25 49 93 74 F8 0F 63 6B 09 19 93 84 04 03 +93 F4 F4 0F 13 58 87 00 84 C2 13 78 F8 00 25 49 +93 74 F8 0F 63 68 09 17 93 84 04 03 93 F4 F4 0F +13 58 47 00 84 C2 13 78 F8 00 25 49 93 74 F8 0F +63 60 09 15 13 88 04 03 13 78 F8 0F 23 A0 06 01 +93 74 F7 00 25 49 13 88 04 03 63 54 99 00 13 88 +74 03 23 A0 06 01 1A 95 3D BB 1D 43 93 04 78 03 +25 49 93 79 F8 0F 93 F4 F4 0F E3 63 09 F5 93 89 +09 03 93 F4 F9 0F 2D BF 83 A6 0E C6 13 03 08 03 +13 58 B7 01 23 A0 66 00 13 78 78 00 AD 44 13 03 +08 03 13 58 87 01 23 A0 66 00 13 78 78 00 13 08 +08 03 13 73 F8 0F 13 58 57 01 23 A0 66 00 13 78 +78 00 13 08 08 03 13 73 F8 0F 13 58 27 01 23 A0 +66 00 13 78 78 00 13 08 08 03 13 73 F8 0F 13 58 +F7 00 23 A0 66 00 13 78 78 00 13 08 08 03 13 73 +F8 0F 13 58 C7 00 23 A0 66 00 13 78 78 00 13 08 +08 03 13 73 F8 0F 13 58 97 00 23 A0 66 00 13 78 +78 00 13 08 08 03 13 73 F8 0F 13 58 67 00 23 A0 +66 00 13 78 78 00 13 08 08 03 13 73 F8 0F 13 58 +37 00 23 A0 66 00 13 78 78 00 13 08 08 03 13 78 +F8 0F 23 A0 06 01 1D 8B 13 07 07 03 98 C2 26 95 +99 B9 93 84 04 03 93 F4 F4 0F 49 B5 13 83 74 03 +13 58 87 01 23 A0 66 00 13 78 F8 00 21 43 93 04 +00 03 E3 07 08 E4 DD BD 83 A6 0E C6 A9 44 05 B7 +13 88 74 03 13 78 F8 0F D1 B5 93 84 74 03 93 F4 +F4 0F 9D B5 93 84 74 03 93 F4 F4 0F 51 BD 93 84 +74 03 93 F4 F4 0F BD B5 13 58 57 01 63 0C 08 00 +83 A6 0E C6 A1 44 31 B7 13 58 07 01 63 0C 08 00 +15 43 15 B5 13 58 27 01 63 0C 08 00 83 A6 0E C6 +9D 44 11 B7 13 58 C7 00 63 0C 08 00 11 43 15 B5 +13 58 F7 00 63 0C 08 00 83 A6 0E C6 99 44 F5 BD +13 58 87 00 63 0C 08 00 0D 43 15 B5 13 58 C7 00 +63 0D 08 00 83 A6 0E C6 95 44 D5 BD 13 58 47 00 +05 43 E3 0F 08 E2 09 43 0D B5 13 58 97 00 63 06 +08 00 83 A6 0E C6 91 44 ED B5 13 58 67 00 63 06 +08 00 83 A6 0E C6 8D 44 FD B5 13 58 37 00 63 06 +08 00 83 A6 0E C6 89 44 CD BD 1D 8B E3 0D 07 B4 +83 A6 0E C6 85 44 CD BD 01 45 82 80 39 71 13 03 +41 02 2E D2 9A 85 06 CE 32 D4 36 D6 3A D8 3E DA +42 DC 46 DE 1A C6 CD 34 F2 40 21 61 82 80 B7 37 +02 50 83 A7 07 C6 13 75 F5 0F 88 C3 82 80 B7 37 +02 50 83 A7 07 C6 13 75 F5 0F 88 C3 82 80 83 47 +05 00 37 37 02 50 03 27 07 C6 91 C7 05 05 1C C3 +83 47 05 00 E5 FF A9 47 1C C3 05 45 82 80 39 71 +13 03 41 02 2E D2 9A 85 06 CE 32 D4 36 D6 3A D8 +3E DA 42 DC 46 DE 1A C6 41 34 F2 40 21 61 82 80 +F3 25 00 B8 73 25 00 B0 F3 27 00 B8 E3 9A F5 FE +82 80 00 00 85 47 63 13 F6 02 93 96 85 01 93 D7 +85 01 D5 8F C1 66 13 D7 85 00 93 86 06 F0 75 8F +D9 8F A2 05 37 07 FF 00 F9 8D DD 8D 0C C1 82 80 +01 11 22 CC 26 CA 4A C8 4E C6 52 C4 06 CE B7 34 +02 50 2A 89 2E 8A B2 89 EF D0 F0 25 03 A7 C4 C5 +91 47 2A 84 63 EE E7 28 93 77 14 00 63 99 07 26 +13 5F 34 40 93 57 14 40 23 A0 F9 00 CA 86 D2 8E +93 0F 1F 00 01 4E 25 48 89 45 0D 45 91 42 95 48 +99 43 21 49 85 49 63 0C CF 1F 83 C7 06 00 13 87 +07 FD 13 76 F7 0F 63 6D C8 1A 12 07 21 46 83 C7 +16 00 13 83 07 FD 13 7A F3 0F 63 70 48 03 13 83 +F7 F9 13 73 F3 0F 63 F5 68 1E 13 83 F7 FB 13 73 +F3 0F 63 E6 68 16 13 83 97 FC 33 67 67 00 63 01 +B6 14 83 C7 26 00 13 83 07 FD 13 7A F3 0F 63 70 +48 03 13 83 F7 F9 13 73 F3 0F 63 FE 68 1A 13 83 +F7 FB 13 73 F3 0F 63 EC 68 12 13 83 97 FC 32 03 +33 67 67 00 63 06 A6 10 83 C7 36 00 13 83 07 FD +13 7A F3 0F 63 70 48 03 13 83 F7 F9 13 73 F3 0F +63 F6 68 18 13 83 F7 FB 13 73 F3 0F 63 E1 68 10 +13 83 97 FC 22 03 33 67 67 00 63 0B 56 0C 83 C7 +46 00 13 83 07 FD 13 7A F3 0F 63 70 48 03 13 83 +F7 F9 13 73 F3 0F 63 FE 68 14 13 83 F7 FB 13 73 +F3 0F 63 E6 68 0C 13 83 97 FC 52 03 33 67 67 00 +63 00 16 0B 83 C7 56 00 13 83 07 FD 13 7A F3 0F +63 70 48 03 13 83 F7 F9 13 73 F3 0F 63 F6 68 12 +13 83 F7 FB 13 73 F3 0F 63 EB 68 08 13 83 97 FC +42 03 33 67 67 00 63 05 76 06 83 C7 66 00 13 83 +07 FD 13 7A F3 0F 63 70 48 03 13 83 F7 F9 13 73 +F3 0F 63 FE 68 0E 13 83 F7 FB 13 73 F3 0F 63 E0 +68 06 13 83 97 FC 72 03 33 67 67 00 63 1A 26 03 +83 C7 76 00 13 86 07 FD 13 73 F6 0F 63 70 68 02 +13 86 F7 F9 13 76 F6 0F 63 F6 C8 0C 13 86 F7 FB +13 76 F6 0F 63 E5 C8 02 13 86 97 FC 62 06 51 8F +23 A0 EE 00 05 0E 91 0E A1 06 E3 16 FE E7 F2 40 +62 44 D2 44 42 49 B2 49 22 4A 05 61 82 80 83 A6 +C4 C5 11 47 E3 75 D7 FE 62 44 F2 40 D2 44 42 49 +B2 49 22 4A 15 65 BE 85 13 05 45 B0 05 61 41 B3 +21 46 13 87 F7 F9 13 77 F7 0F 63 FF E8 00 13 87 +F7 FB 13 77 F7 0F E3 E4 E8 FC 93 87 97 FC 13 97 +47 00 E3 16 36 E3 69 BF 93 87 97 FA CD BF 13 76 +74 00 49 DA 83 C7 06 00 25 43 13 87 07 FD 13 7A +F7 0F E3 60 43 FD 85 47 12 07 E3 12 F6 E0 8D BF +13 83 97 FA 1D B5 13 83 97 FA 91 BD 13 83 97 FA +51 B5 13 83 97 FA 55 BD 13 83 97 FA D5 B5 13 83 +97 FA 11 BF 13 86 97 FA 62 06 51 8F 91 B7 03 A7 +C4 C5 91 47 E3 F5 E7 F4 62 44 F2 40 D2 44 42 49 +B2 49 22 4A 37 45 02 50 13 05 05 82 05 61 C1 B1 +AA 85 15 65 13 05 C5 AE D9 39 B9 BB 79 71 22 D4 +26 D2 4A D0 4E CE 52 CC 56 CA 06 D6 5A C8 5E C6 +B7 39 02 50 2A 8A AE 8A 32 84 B6 84 EF D0 A0 78 +03 A7 C9 C5 89 47 2A 89 63 E8 E7 2E 93 77 19 00 +63 91 07 2C 13 5F 39 40 93 57 19 40 56 86 52 88 +D6 85 1C C0 93 02 1F 00 81 46 25 43 09 45 8D 4F +91 43 15 4E 19 4A A1 4A 05 4B 63 02 DF 24 83 47 +08 00 13 87 07 FD 93 78 F7 0F 63 63 13 21 12 07 +A1 48 83 47 18 00 93 8E 07 FD 93 FB FE 0F 63 70 +73 03 93 8E F7 F9 93 FE FE 0F 63 7C DE 23 93 8E +F7 FB 93 FE FE 0F 63 6A DE 1B 93 8E 97 FC 33 67 +D7 01 63 82 A8 14 83 47 28 00 93 8E 07 FD 93 FB +FE 0F 63 70 73 03 93 8E F7 F9 93 FE FE 0F 63 75 +DE 21 93 8E F7 FB 93 FE FE 0F 63 60 DE 19 93 8E +97 FC B2 0E 33 67 D7 01 63 87 F8 11 83 47 38 00 +93 8E 07 FD 93 FB FE 0F 63 70 73 03 93 8E F7 F9 +93 FE FE 0F 63 7D DE 1D 93 8E F7 FB 93 FE FE 0F +63 65 DE 15 93 8E 97 FC A2 0E 33 67 D7 01 63 8C +78 0C 83 47 48 00 93 8E 07 FD 93 FB FE 0F 63 70 +73 03 93 8E F7 F9 93 FE FE 0F 63 75 DE 1B 93 8E +F7 FB 93 FE FE 0F 63 6A DE 11 93 8E 97 FC D2 0E +33 67 D7 01 63 81 C8 0B 83 47 58 00 93 8E 07 FD +93 FB FE 0F 63 70 73 03 93 8E F7 F9 93 FE FE 0F +63 7D DE 17 93 8E F7 FB 93 FE FE 0F 63 6F DE 0D +93 8E 97 FC C2 0E 33 67 D7 01 63 86 48 07 83 47 +68 00 93 8E 07 FD 93 FB FE 0F 63 70 73 03 93 8E +F7 F9 93 FE FE 0F 63 75 DE 15 93 8E F7 FB 93 FE +FE 0F 63 64 DE 0B 93 8E 97 FC F2 0E 33 67 D7 01 +63 9B 58 03 83 47 78 00 93 88 07 FD 93 FE F8 0F +63 70 D3 03 93 88 F7 F9 93 F8 F8 0F 63 7D 1E 11 +93 88 F7 FB 93 F8 F8 0F 63 69 1E 07 93 88 97 FC +E2 08 33 67 17 01 98 C1 85 06 91 05 21 08 E3 96 +56 E6 85 47 63 90 F4 04 1C 40 8D CF 41 68 81 45 +13 08 08 F0 B7 08 FF 00 1C 42 11 06 85 05 13 D7 +87 01 13 95 87 01 93 D6 87 00 49 8F B3 F6 06 01 +A2 07 55 8F B3 F7 17 01 D9 8F 23 2E F6 FE 1C 40 +E3 EC F5 FC B2 50 22 54 92 54 02 59 F2 49 62 4A +D2 4A 42 4B B2 4B 45 61 82 80 03 A7 C9 C5 7D D3 +22 54 B2 50 92 54 02 59 F2 49 62 4A D2 4A 42 4B +B2 4B 15 65 BE 85 13 05 05 B4 45 61 6F F0 3F A6 +A1 48 13 87 F7 F9 13 77 F7 0F 63 7F EE 00 13 87 +F7 FB 13 77 F7 0F E3 62 EE FC 93 87 97 FC 13 97 +47 00 E3 90 68 DF 81 BF 93 87 97 FA CD BF 93 78 +79 00 E3 83 08 F4 83 47 08 00 A5 4E 13 87 07 FD +93 7B F7 0F E3 EF 7E FB 85 47 12 07 E3 9B F8 DA +1D B7 93 8E 97 FA E1 BB 93 8E 97 FA 19 B5 93 8E +97 FA 1D BD 93 8E 97 FA 9D B5 93 8E 97 FA 59 BD +93 8E 97 FA D9 B5 93 88 97 FA E2 08 33 67 17 01 +DD BD 83 A7 C9 C5 9D DF 22 54 B2 50 92 54 02 59 +F2 49 62 4A D2 4A 42 4B B2 4B 37 45 02 50 13 05 +05 82 45 61 6F F0 BF 99 AA 85 15 65 13 05 85 B2 +EF F0 FF 9A 21 B3 29 CE 85 47 63 8D F6 00 0A 06 +B3 07 C5 00 18 41 11 05 91 05 23 AE E5 FE E3 9B +A7 FE 82 80 93 16 26 00 C1 68 AA 96 93 88 08 F0 +37 03 FF 00 1C 41 91 05 11 05 13 D7 87 01 13 98 +87 01 13 D6 87 00 33 67 07 01 33 76 16 01 A2 07 +51 8F B3 F7 67 00 D9 8F 23 AE F5 FE E3 1C D5 FC +82 80 37 17 01 10 83 27 47 08 85 8B ED DF 82 80 +31 71 22 DD 26 DB 80 01 4A D9 4E D7 52 D5 56 D3 +5A D1 62 CD 66 CB 06 DF 5E CF 6A C9 6E C7 36 8C +03 43 2C 00 B4 4A 83 24 CC 05 23 2A 64 F8 03 43 +3C 00 83 47 0C 00 93 F8 F4 00 23 24 64 F8 03 43 +4C 04 13 F8 F6 00 23 26 94 F6 23 20 64 F8 03 23 +4C 05 23 22 F4 FA 23 20 14 FB 23 2C 64 F8 03 23 +8C 05 23 22 D4 F8 23 28 04 F9 83 4D 5C 04 23 26 +64 F8 03 23 4C 06 93 F7 C6 FF BD 07 23 24 64 F6 +03 23 0C 07 C1 9B 33 01 F1 40 23 2C 64 F6 03 23 +4C 07 03 2B 0C 06 03 4A 8C 06 23 2A 64 F6 03 23 +8C 07 93 DC 44 00 93 D9 46 00 23 28 64 F6 03 23 +CC 07 B3 38 10 01 1C 08 23 22 64 F6 03 43 0C 08 +23 26 E4 FA 2A 89 23 24 64 FA 33 33 00 01 AE 8A +B2 84 9A 99 C6 9C 23 2E F4 F8 37 17 01 10 83 27 +47 08 85 8B ED DF 83 26 C4 FA 37 3D 02 50 05 47 +83 27 CD C5 E3 82 E6 44 09 47 63 67 F7 50 B7 27 +01 10 23 AA 07 92 37 17 01 10 83 2B 47 08 93 FB +1B 00 E3 8C 0B FE 83 27 44 FA 95 CB 03 47 1C 00 +1D E7 37 26 01 10 83 27 46 A0 85 8B ED DF 83 27 +84 F8 13 97 17 00 13 77 E7 03 13 67 17 00 23 20 +E6 A0 37 26 01 10 83 27 46 A0 89 8B ED DF 83 27 +44 FA A2 04 13 77 39 00 13 96 B7 00 93 F4 04 70 +83 27 04 F8 D9 8C 13 97 2A 00 D1 8C 13 77 F7 0F +D9 8C E3 9D 07 3C 83 28 CD C5 09 47 63 6E 17 29 +37 17 01 10 83 27 44 F9 64 DB 64 DB 89 EB 83 27 +84 F8 63 89 07 46 37 27 01 10 23 20 77 A1 93 07 +00 02 63 8E FA 24 37 17 01 10 83 27 47 08 85 8B +ED DF 83 27 44 FA A5 EB 89 47 63 F4 17 01 6F 00 +B0 71 03 27 4C 00 B7 17 01 10 D8 C3 03 27 4C 02 +D8 D3 03 27 8C 00 98 C7 03 27 8C 02 98 D7 03 27 +CC 00 D8 C7 03 27 CC 02 D8 D7 03 27 0C 01 98 CB +03 27 0C 03 98 DB 03 27 4C 01 D8 CB 03 27 4C 03 +D8 DB 03 27 8C 01 98 CF 03 27 8C 03 98 DF 03 27 +CC 01 D8 CF 03 27 CC 03 D8 DF 03 27 0C 02 98 D3 +03 27 0C 04 B8 C3 B7 17 01 10 83 A6 47 08 85 8A +ED DE 89 47 E3 E2 17 35 03 27 CC 04 B7 17 01 10 +13 06 00 02 0C 43 EC C3 4C 43 AC C7 0C 47 EC C7 +58 47 B8 CB E3 80 CA 20 83 27 44 F8 63 8B 07 14 +83 2C CC 06 85 47 E3 8B FC 5E 63 8D 09 08 95 6C +93 87 CC AE 23 20 F4 FA 83 27 04 F9 83 2D 04 F8 +81 4B FD 17 23 22 F4 F6 83 27 C4 F8 23 2C 84 F7 +23 26 04 F8 13 8B C7 00 83 27 84 F9 5E 8C 23 20 +D4 F6 93 8C C7 00 C1 67 93 87 07 F0 23 2E F4 F8 +85 67 93 87 07 80 DA 8B 23 2C F4 F8 66 8B 93 07 +00 02 63 84 FA 16 37 17 01 10 83 27 47 08 C1 8B +ED DF 63 15 0A 18 89 47 63 EF 17 37 05 47 63 00 +E9 34 63 09 F9 18 63 88 0D 1E 03 27 CD C5 63 00 +0C 58 05 0C 83 28 CD C5 C1 0B 41 0B E3 11 3C FD +03 2C 84 F7 83 27 04 F8 CD C7 83 27 44 F9 D5 E3 +89 47 63 F4 17 01 6F 10 A0 0C 37 27 01 10 83 27 +C7 A0 89 8B ED DF 89 44 03 49 6C 04 63 F4 14 01 +6F 10 40 0C 85 47 63 14 F9 00 6F 10 60 31 37 25 +01 10 13 05 C5 A0 EF 90 60 53 95 A0 83 27 84 FA +03 2B 04 F7 83 25 44 F7 13 85 F7 FF 13 35 15 00 +CE 87 83 29 44 F6 2A C4 5E C2 66 C0 A6 88 83 24 +44 F8 03 25 84 F7 52 86 DA 86 4E 87 26 88 EF B0 +F0 7C 83 26 C4 F9 13 DA 24 00 81 47 26 87 01 46 +5A 85 CE 85 EF B0 D0 07 63 0B 0A 00 83 27 84 FA +63 14 99 01 6F 10 E0 18 99 E3 6F 10 60 2E 83 28 +CD C5 37 17 01 10 83 27 47 08 85 8B ED DF 93 07 +00 02 E3 85 FA 28 89 47 E3 E9 17 41 B7 17 01 10 +21 67 F8 DB F8 DB 19 47 23 A0 E7 08 13 01 04 F4 +FA 50 6A 54 DA 54 4A 59 BA 59 2A 5A 9A 5A 0A 5B +FA 4B 6A 4C DA 4C 4A 4D BA 4D 29 61 82 80 37 17 +01 10 83 27 47 08 85 8B ED DF 93 07 10 40 23 24 +F7 08 23 24 F7 08 41 BB 95 68 13 85 48 B8 A6 85 +EF F0 EF D1 83 28 CD C5 A1 BB 93 87 F9 FF 63 03 +0C 6C E3 1A FC E8 83 27 04 F9 E3 86 07 E8 93 95 +67 00 93 E5 85 00 37 17 01 10 83 27 47 08 85 8B +ED DF 23 24 B7 08 23 24 B7 08 B5 B5 64 5B 03 27 +84 F9 89 47 B9 8C 63 E8 17 1F 05 47 63 09 E9 1A +63 12 F9 04 03 27 CD C5 91 4C 63 E0 EC 20 83 26 +C4 FA 85 45 83 A7 4B FF 63 8A B6 5C 37 17 01 10 +7C CB 03 A7 8B FF B7 17 01 10 B8 CF 03 A7 CB FF +B7 17 01 10 F8 CF 83 A7 0B 00 37 17 01 10 3C D3 +E3 0B 0A E2 B7 17 01 10 03 27 CD C5 E4 DB E4 DB +89 47 E3 F2 E7 E2 B7 47 02 50 13 85 C7 94 EF F0 +0F C5 E3 9C 0D E0 37 17 01 10 83 27 47 08 A1 8B +ED DF B7 07 03 30 83 A7 C7 54 85 8B 95 CB 83 27 +84 F7 83 26 44 FA 23 80 D7 00 83 26 44 F9 23 81 +D7 00 83 26 84 F8 A3 81 D7 00 8C 43 B7 07 00 FF +93 87 F7 0F FD 8D B7 07 00 10 85 07 63 89 F5 62 +37 17 01 10 83 27 47 08 91 8B 99 C7 83 27 84 FA +99 E3 6F 10 20 05 81 47 37 17 01 10 83 25 CD C5 +83 2C 47 06 0D 47 63 67 B7 4A 03 27 C4 F8 93 08 +F7 FF 13 87 F9 FF 46 8F 63 0E 87 21 63 93 07 24 +85 45 63 03 B9 5A 89 45 E3 0F B9 08 B7 15 01 10 +03 25 CD C5 83 AC 85 06 8D 45 63 E9 A5 48 FA 8F +63 04 87 1B 63 9D 07 1C 85 45 63 00 B9 5A 89 45 +E3 02 B9 00 B7 15 01 10 03 25 CD C5 83 AC C5 06 +8D 45 63 E9 A5 48 FE 88 63 01 87 25 63 98 07 26 +85 45 63 0B B9 5A 89 45 E3 08 B9 06 B7 15 01 10 +03 25 CD C5 83 AC 05 07 8D 45 63 E9 A5 12 63 02 +87 27 63 93 07 28 85 47 63 02 F9 60 89 47 E3 1A +F9 D0 83 27 84 FA E3 96 07 D0 83 27 0B 00 5A 87 +B3 C7 FC 00 B3 F7 17 01 E3 8D 07 CE E6 87 8D 45 +6F 00 60 7B 8D 4B 41 BE 37 45 02 50 13 05 85 87 +EF F0 EF B0 B7 27 01 10 23 AA 07 92 ED B4 03 27 +CD C5 91 4C 63 E6 EC 34 83 26 C4 FA 85 45 83 27 +4B FF 63 83 B6 28 37 17 01 10 7C CB 03 27 8B FF +B7 17 01 10 B8 CF 03 27 CB FF B7 17 01 10 F8 CF +83 27 0B 00 99 BD 83 27 04 FA E2 85 13 85 C7 21 +EF F0 EF AD 85 47 E3 0C F9 FA 89 47 E3 12 F9 E4 +03 27 CD C5 91 4C E3 F4 EC E0 83 27 04 FA 83 A5 +4B FF 93 87 C7 23 3E 85 23 2E F4 F6 EF F0 2F AB +83 26 C4 FA 85 45 03 27 CD C5 83 A7 4B FF 63 8F +B6 3A 37 13 01 10 23 2A F3 04 E3 F4 EC DE 83 A5 +8B FF 03 25 C4 F7 EF F0 8F A8 03 A7 8B FF 83 27 +CD C5 37 13 01 10 23 2C E3 04 E3 F9 FC DC 83 A5 +CB FF 03 25 C4 F7 EF F0 8F A6 03 27 CD C5 83 A7 +CB FF B7 15 01 10 FC CD 91 47 E3 FE E7 DA 83 A5 +0B 00 03 25 C4 F7 EF F0 8F A4 75 B3 23 2A F4 F6 +83 27 04 FA E6 85 23 28 14 F7 13 85 C7 29 23 2E +E4 F6 EF F0 CF A2 03 27 C4 F7 83 28 04 F7 83 27 +44 F7 E3 18 87 EB 31 A2 83 26 04 F9 E3 8C 06 E4 +83 26 44 F8 93 F5 C6 00 E3 86 05 E4 93 FF 86 00 +E3 9B 0F 3E 93 F5 36 00 83 26 04 F6 8E 05 05 4F +33 1F BF 00 23 26 D4 F8 7D 1F E3 87 07 E2 83 26 +84 FA E3 99 06 E2 B3 FC EC 01 E3 85 0C E2 E6 87 +85 45 91 A0 83 26 04 F9 E3 82 06 DE 83 26 44 F8 +13 FF C6 00 E3 14 0F 16 93 F5 36 00 83 26 04 F6 +8E 05 85 48 B3 98 B8 00 23 26 D4 F8 FD 18 E3 81 +07 DC 83 26 84 FA E3 93 06 DC B3 FC 1C 01 E3 8F +0C DA E6 87 81 45 95 64 93 84 C4 AE 13 85 04 2B +23 26 F4 FA EF F0 AF 97 83 27 C4 FA 13 85 84 2D +BE 85 EF F0 CF 96 37 45 02 50 13 05 C5 9C EF F0 +0F 94 05 45 EF F0 AF 91 01 A0 83 26 44 F6 A9 45 +E3 EE D5 DA 83 26 44 F8 93 F5 86 00 E3 88 05 DA +93 F5 36 00 83 26 04 F6 8E 05 85 4F B3 9F BF 00 +23 26 D4 F8 FD 1F 81 48 E3 8C 07 D8 83 26 84 FA +E3 9E 06 D8 B3 FC FC 01 E3 8A 0C D8 E6 87 89 45 +59 B7 83 26 04 F9 2D 47 E3 7D D7 D8 03 27 44 F8 +85 48 0D 8B 0E 07 B3 98 E8 00 03 27 04 F6 FD 18 +23 26 E4 F8 E3 81 07 D8 83 27 84 FA E3 9B 07 A8 +B3 FC 1C 01 E3 87 0C A8 E6 87 8D 45 A9 B7 83 27 +44 FA E3 80 07 A8 89 47 63 E7 E7 02 B7 25 01 10 +83 A7 45 A0 89 8B ED DF 83 26 44 F9 85 47 E3 8E +F6 50 89 47 63 EC E7 7A 37 25 01 10 13 05 45 A0 +EF 80 D0 7D B9 B4 37 45 02 50 13 05 05 9E EF F0 +0F 87 03 27 CD C5 D9 B7 83 26 C4 F9 93 D5 87 01 +93 98 87 01 13 D5 87 00 75 8D B3 E5 15 01 C9 8D +A2 07 37 05 FF 00 E9 8F CD 8F B7 15 01 10 FC C9 +91 47 63 ED E7 34 83 27 8B FF 83 26 C4 F9 93 D5 +87 01 93 98 87 01 13 D5 87 00 75 8D B3 E5 15 01 +C9 8D A2 07 37 05 FF 00 E9 8F CD 8F B7 15 01 10 +BC CD 91 47 63 E3 E7 30 83 27 CB FF 83 26 C4 F9 +93 D5 87 01 93 98 87 01 13 D5 87 00 75 8D B3 E5 +15 01 C9 8D A2 07 37 05 FF 00 E9 8F CD 8F B7 15 +01 10 FC CD 91 47 63 EB E7 2A 83 27 0B 00 83 26 +C4 F9 13 D7 87 01 13 95 87 01 93 D5 87 00 F5 8D +49 8F 4D 8F A2 07 B7 05 FF 00 ED 8F D9 8F 35 BE +83 25 4B FF 95 67 13 85 07 D4 EF E0 5F FC 83 26 +C4 FA 85 45 03 27 CD C5 83 27 4B FF E3 86 B6 F2 +B7 18 01 10 23 AA F8 04 E3 F2 EC CA 83 25 8B FF +95 67 13 85 07 D4 EF E0 9F F9 03 27 8B FF 83 27 +CD C5 B7 18 01 10 23 AC E8 04 E3 F6 FC C8 83 25 +CB FF 95 67 13 85 07 D4 EF E0 7F F7 03 27 CD C5 +83 27 CB FF B7 15 01 10 FC CD 91 47 E3 FA E7 C6 +83 25 0B 00 95 67 13 85 07 D4 EF E0 5F F5 83 27 +0B 00 65 BC 23 2E F4 F6 83 27 04 FA E6 85 13 85 +C7 29 EF E0 DF F3 83 27 C4 F7 81 B6 23 2A F4 F6 +83 27 04 FA E6 85 23 28 E4 F7 13 85 C7 29 23 2E +E4 F6 EF E0 DF F1 03 2F 04 F7 83 27 44 F7 03 27 +C4 F7 B1 B6 23 2A F4 F6 83 27 04 FA E6 85 23 28 +F4 F7 13 85 C7 29 23 2E E4 F6 EF E0 5F EF 83 2F +04 F7 83 27 44 F7 03 27 C4 F7 B1 B6 83 26 C4 F9 +93 D5 87 01 93 98 87 01 13 D5 87 00 75 8D B3 E5 +15 01 C9 8D A2 07 37 05 FF 00 E9 8F CD 8F B7 15 +01 10 FC C9 91 47 63 E7 E7 5A 83 A7 8B FF 83 26 +C4 F9 93 D5 87 01 93 98 87 01 13 D5 87 00 75 8D +B3 E5 15 01 C9 8D A2 07 37 05 FF 00 E9 8F CD 8F +B7 15 01 10 BC CD 91 47 63 E9 E7 54 83 A7 CB FF +83 26 C4 F9 93 D5 87 01 93 98 87 01 13 D5 87 00 +75 8D B3 E5 15 01 C9 8D A2 07 37 05 FF 00 E9 8F +CD 8F B7 15 01 10 FC CD 91 47 63 E0 E7 50 83 A7 +0B 00 B1 BD 85 47 93 05 80 40 E3 96 F9 94 83 27 +04 F9 E3 82 07 94 25 BA 83 26 84 FA E3 90 06 A6 +83 A5 4B FF B3 C5 BC 00 B3 F5 15 01 E3 88 05 A4 +E6 87 93 82 4B FF 81 45 8D A0 83 26 84 FA E3 93 +06 A6 83 A5 8B FF B3 C5 BC 00 B3 F5 E5 01 E3 8B +05 A4 E6 87 93 82 8B FF FA 88 85 45 3D A8 85 47 +E3 98 FA 9C 83 27 47 08 91 8B 89 E7 83 27 84 FA +E3 88 07 3E 85 47 C9 BA 83 26 84 FA E3 98 06 A4 +83 A5 CB FF B3 C5 BC 00 B3 F5 F5 01 E3 80 05 A4 +E6 87 93 82 CB FF FE 88 89 45 95 64 93 84 C4 AE +13 85 04 2F 23 24 54 FA 23 22 14 FB 23 26 F4 FA +EF E0 FF D9 83 27 C4 FA 83 28 44 FA 13 85 84 31 +B3 F5 F8 00 23 26 14 FB EF E0 7F D8 83 22 84 FA +83 28 C4 FA 13 85 04 33 83 A5 02 00 B3 F5 B8 00 +EF E0 FF D6 05 45 EF E0 9F D2 01 A0 83 27 84 FA +63 99 07 F0 83 A7 0B 00 DE 82 B3 C7 FC 00 B3 F7 +17 01 63 80 07 F0 E6 87 8D 45 41 BF 83 25 0B 00 +95 67 13 85 07 D4 EF E0 9F D3 83 26 C4 FA 05 47 +83 27 0B 00 E3 8D E6 D2 49 B8 83 25 CB FF 95 67 +13 85 07 D4 EF E0 BF D1 83 26 C4 FA 85 45 03 27 +CD C5 83 27 CB FF E3 83 B6 CE 69 BB 83 25 8B FF +95 67 13 85 07 D4 EF E0 9F CF 03 27 CD C5 83 27 +8B FF 61 B9 83 27 C4 F6 63 80 07 E0 63 8E 0C DE +03 27 04 FA 93 DF 27 00 85 47 BA 9F 5A 8F 63 8B +FC 72 13 06 40 40 C1 45 95 67 93 87 C7 AE 23 2E +F4 F6 C1 67 0D 4B 93 87 07 F0 23 2E 94 F4 23 2C +34 F5 E6 84 81 4D DA 8C B7 1B 01 10 56 8B 23 20 +F4 F6 CA 8A 23 2A D4 F4 FE 89 7A 89 83 A7 4B 08 +85 8B ED DF 89 47 63 E0 17 67 23 A4 CB 08 23 A4 +CB 08 83 A7 4B 08 C1 8B ED DF 89 47 63 E5 17 5D +93 97 2D 00 63 E0 37 4F 23 AA 0B 04 93 87 EC FF +63 E4 37 43 23 AC 0B 04 93 87 FC FF 63 F9 37 57 +03 27 C4 FA 85 46 83 27 89 00 63 0A D7 5C 23 AE +FB 04 63 FC 3C 45 83 27 C9 00 23 A0 FB 06 85 0D +41 09 91 0C 63 8A B4 45 93 87 F4 FF 63 8C B7 5D +89 47 E3 F0 17 FB B7 47 02 50 13 85 87 8C EF E0 +1F BF 83 28 CD C5 71 B7 09 47 63 67 F7 5C B7 27 +01 10 05 47 23 AA E7 92 6F F0 EF BB 03 26 8C 04 +37 25 01 10 EE 85 13 05 85 A0 EF 80 50 40 83 28 +CD C5 09 47 63 7E 17 C1 95 68 EE 85 13 85 48 B6 +EF E0 FF BC 6F F0 2F C0 37 45 02 50 13 05 85 8B +23 2E D4 F6 EF E0 BF B9 83 28 CD C5 83 26 C4 F7 +6F F0 8F CA 83 26 84 FA 63 9E 06 FE 83 25 8B FF +B3 C5 BC 00 B3 F5 E5 01 63 86 05 FE E6 87 13 07 +8B FF FA 88 85 45 95 64 93 84 C4 AE 13 85 84 34 +23 24 E4 FA 23 22 14 FB 23 26 F4 FA EF E0 3F B7 +83 27 C4 FA 83 28 44 FA 13 85 04 37 B3 F5 F8 00 +23 26 14 FB EF E0 BF B5 03 27 84 FA 83 28 C4 FA +13 85 84 38 0C 43 B3 F5 B8 00 EF E0 5F B4 05 45 +EF E0 FF AF 01 A0 83 26 84 FA 63 91 06 F6 83 25 +4B FF B3 C5 BC 00 B3 F5 15 01 63 89 05 F4 E6 87 +13 07 4B FF 81 45 41 BF 83 26 84 FA 63 98 06 F8 +83 25 CB FF B3 C5 BC 00 B3 F5 F5 01 63 80 05 F8 +E6 87 13 07 CB FF FE 88 89 45 B5 B7 83 27 44 F9 +63 9B 07 D6 03 25 C4 F6 B7 05 FF 00 13 06 00 42 +93 16 35 00 93 17 B5 00 ED 8F 13 D9 86 00 93 D5 +86 01 C1 66 23 24 C7 08 CD 8F 93 86 06 F0 93 15 +B5 01 33 79 D9 00 CD 8F 23 24 C7 08 11 47 33 69 +F9 00 63 60 17 69 03 27 C4 FA B7 17 01 10 23 AA +07 04 85 47 63 15 F7 02 93 16 89 01 93 57 89 01 +D5 8F C1 66 13 57 89 00 93 86 06 F0 75 8F D9 8F +22 09 37 07 FF 00 33 79 E9 00 33 E9 27 01 03 26 +44 F8 B7 06 FF 00 93 17 36 00 13 17 B6 00 75 8F +93 D6 87 01 93 D4 87 00 B3 67 D7 00 41 67 13 07 +07 F0 F9 8C 93 16 B6 01 37 17 01 10 D5 8F 23 2C +27 05 11 47 DD 8C 63 6D 17 5F 03 27 C4 FA B7 17 +01 10 23 AE 07 04 85 47 63 13 F7 02 93 96 84 01 +93 D7 84 01 D5 8F C1 66 13 D7 84 00 93 86 06 F0 +75 8F D9 8F A2 04 37 07 FF 00 F9 8C DD 8C B7 17 +01 10 A4 D3 37 17 01 10 83 27 47 08 A1 8B ED DF +03 27 C4 FA 85 47 63 0E F7 4E 83 25 84 F6 41 46 +13 05 04 FB 23 26 14 FB EF C0 00 26 83 28 C4 FA +89 47 63 E8 17 4B 83 27 84 FA 63 90 07 44 B7 17 +01 10 E4 53 83 27 04 FB 63 9F 97 7A B7 17 01 10 +03 27 CD C5 A4 57 8D 47 63 EB E7 68 83 27 44 FB +63 9A 97 74 37 19 01 10 83 27 CD C5 83 24 C9 06 +0D 4A 63 62 FA 64 83 27 84 FB 95 68 93 88 C8 AE +63 91 F4 78 83 24 09 07 83 27 C4 FB 63 96 97 76 +83 28 CD C5 89 47 63 FB 17 BF 37 45 02 50 13 05 +C5 AA EF E0 DF 93 6F F0 6F BE 83 A5 0B 00 15 65 +13 05 85 D2 EF E0 BF 94 83 26 C4 FA 05 47 83 A7 +0B 00 E3 86 E6 94 6F F0 4F CA 83 A5 CB FF 15 65 +93 07 85 D2 3E 85 23 2E F4 F6 EF E0 5F 92 83 26 +C4 FA 85 45 03 27 CD C5 83 A7 CB FF E3 8A B6 A8 +6F F0 2F EB 83 A5 8B FF 15 65 13 05 85 D2 EF E0 +1F 90 03 27 CD C5 83 A7 8B FF 91 B4 37 45 02 50 +13 05 45 A1 EF E0 BF 8C 6F F0 1F 84 89 44 83 49 +1C 08 63 ED 14 2D 63 84 99 31 81 44 81 49 01 4A +83 47 2C 08 93 8B 0A FE 85 4C 93 BB 1B 00 63 97 +97 AD 03 27 CD C5 89 47 63 EE E7 48 85 47 3E C0 +5E C2 03 27 44 F6 03 28 44 F8 83 26 04 F7 03 25 +84 F7 83 25 44 F7 CE 87 A6 88 52 86 EF B0 00 38 +13 07 40 06 B7 17 01 10 83 A6 47 08 7D 17 F4 DB +F4 DB 7D FB 37 45 02 50 13 05 05 91 EF E0 3F 85 +05 45 EF E0 DF 82 01 A0 37 45 02 50 13 05 05 8A +EF E0 FF 83 83 28 CD C5 6F F0 AF 8D 46 8F 6F F0 +EF C6 63 FB 17 01 83 25 49 00 95 67 13 85 87 C0 +EF E0 FF 83 83 28 CD C5 03 27 C4 FA 85 46 83 27 +49 00 63 05 D7 06 23 AC FB 04 13 86 FC FF 8D 47 +63 6A 36 0D 63 FD 17 13 83 27 C4 F7 B2 85 13 85 +87 0F EF E0 DF 80 83 28 CD C5 23 AE 0B 04 8D 47 +63 E1 3C 0F 63 FB 17 01 83 27 C4 F7 E6 85 13 85 +87 0F EF E0 CF FE 83 28 CD C5 23 A0 0B 06 85 0D +41 09 91 0C E3 9A B4 BB 56 89 83 24 C4 F5 83 29 +84 F5 83 26 44 F5 DA 8A 6F F0 0F 8E 03 27 04 F6 +93 D6 87 01 93 95 87 01 13 D6 87 00 79 8E CD 8E +D1 8E A2 07 37 06 FF 00 F1 8F D5 8F AD BF 63 FB +17 01 83 25 09 00 95 67 13 85 87 C0 EF E0 2F F9 +83 28 CD C5 03 27 C4 FA 85 46 83 27 09 00 63 0F +D7 06 23 AA FB 04 13 86 EC FF 8D 47 E3 63 36 F3 +E3 FA 17 B1 83 27 C4 F7 B2 85 13 85 87 0F EF E0 +0F F6 83 28 CD C5 13 86 FC FF 23 AC 0B 04 8D 47 +E3 7A 36 F3 E3 FE 17 AF 83 25 89 00 95 67 13 85 +87 C0 EF E0 CF F3 03 27 C4 FA 85 46 83 28 CD C5 +83 27 89 00 63 0D D7 0A 23 AE FB 04 8D 47 E3 F3 +3C F3 63 F2 17 05 83 25 C9 00 95 67 66 86 13 85 +87 C0 EF E0 CF F0 83 28 CD C5 35 A0 03 27 04 F6 +93 D6 87 01 93 95 87 01 13 D6 87 00 79 8E CD 8E +D1 8E A2 07 37 06 FF 00 F1 8F D5 8F 9D B7 23 AE +0B 04 E3 FC 3C EF 03 27 C4 FA 85 46 83 27 C9 00 +E3 1D D7 A8 03 27 04 F6 93 D6 87 01 93 95 87 01 +13 D6 87 00 79 8E CD 8E D1 8E A2 07 37 06 FF 00 +F1 8F D5 8F 9D BC 83 27 C4 F7 EE 85 13 85 07 0E +EF E0 EF E9 13 96 2D 00 83 28 CD C5 8D 47 E3 68 +36 EF E3 F3 17 A3 83 27 C4 F7 B2 85 13 85 87 0F +EF E0 EF E7 83 28 CD C5 23 AA 0B 04 ED BD 03 27 +04 F6 93 D6 87 01 93 95 87 01 13 D6 87 00 79 8E +CD 8E D1 8E A2 07 37 06 FF 00 F1 8F D5 8F 23 AE +FB 04 2D B7 83 27 04 FA E3 84 07 A2 13 96 67 00 +BE 85 13 66 46 00 5D B2 37 45 02 50 13 05 45 85 +EF E0 EF E0 2D B4 15 65 13 05 45 BA 23 28 C4 F4 +EF E0 EF E1 03 26 04 F5 83 28 CD C5 23 A4 CB 08 +23 A4 CB 08 F5 B2 FA 8F 6F F0 CF A4 03 27 04 F7 +83 26 44 F6 03 26 84 F7 83 25 44 F7 95 68 13 85 +C8 C2 EF E0 CF DE E3 9A 99 D1 83 27 CD C5 63 F8 +F4 00 37 45 02 50 13 05 05 8E EF E0 4F DB D1 44 +EF B0 10 47 13 7A F5 0F EF B0 90 46 93 79 F5 0F +EF B0 10 46 33 77 95 02 B3 67 3A 01 85 8B D9 8F +E5 D3 85 47 13 7A 1A 00 93 F9 19 00 BA 84 23 24 +F4 FA F9 B1 13 06 40 40 C1 45 E3 07 07 8C 13 16 +67 00 BA 85 13 66 46 00 C1 B0 B7 17 01 10 FC 53 +B7 19 01 10 83 27 CD C5 83 A5 89 06 0D 49 63 6B +F9 1E B7 17 01 10 FC 57 B7 17 01 10 BC 5B CD BE +37 45 02 50 13 05 C5 A2 EF E0 6F D3 83 28 CD C5 +6F E0 BF F2 37 45 02 50 13 05 C5 A4 EF E0 2F D2 +85 47 63 0D F9 22 83 27 CD C5 63 E4 F4 00 6F E0 +1F F3 37 45 02 50 13 05 C5 A7 EF E0 4F D0 6F E0 +1F F2 37 45 02 50 13 05 05 A9 EF E0 4F CF 83 27 +84 FA 03 27 CD C5 63 87 07 22 B7 17 01 10 EC 53 +8D 46 63 F5 E6 24 15 65 13 05 05 EC EF E0 2F CF +85 BF 83 27 84 F6 41 6F 13 0F 0F F0 94 43 03 A8 +47 00 88 47 DC 47 13 DE 86 01 93 95 86 01 93 D4 +86 00 13 16 88 01 93 5A 88 01 93 53 88 00 13 5A +85 01 93 19 85 01 93 52 85 00 13 D7 87 01 13 99 +87 01 93 DE 87 00 B7 0F FF 00 B3 E5 C5 01 B3 F4 +E4 01 13 9E 86 00 33 66 56 01 B3 F3 E3 01 22 08 +B3 66 3A 01 B3 F2 E2 01 22 05 33 67 27 01 B3 FE +EE 01 A2 07 C5 8D 33 7E FE 01 33 66 76 00 33 78 +F8 01 B3 E6 56 00 33 75 F5 01 33 67 D7 01 B3 F7 +F7 01 B3 E5 C5 01 33 66 06 01 C9 8E D9 8F 23 28 +B4 FA 23 2A C4 FA 23 2C D4 FA 23 2E F4 FA 8D BC +95 68 13 85 48 EA A6 85 EF E0 6F C3 83 28 CD C5 +ED BA 95 68 13 85 C8 E8 CA 85 EF E0 4F C2 83 28 +CD C5 95 BA 37 45 02 50 13 05 45 8F EF E0 2F BF +B1 BE 99 C3 6F E0 BF E7 83 29 C4 F8 83 27 C4 F9 +81 44 94 43 03 A7 09 00 63 8A E6 04 15 69 13 09 +C9 AE A6 85 13 05 C9 16 EF E0 6F BE 03 27 C4 F9 +93 97 24 00 13 05 49 19 BA 97 8C 43 EF E0 2F BD +83 A5 09 00 13 05 C9 1A EF E0 6F BC 05 45 EF E0 +0F B8 01 A0 83 25 47 08 15 65 13 05 85 D5 91 89 +EF E0 EF BA 05 45 EF E0 8F B6 01 A0 85 04 91 09 +91 07 E3 10 9A FA 6F E0 9F E0 89 47 63 E9 E7 0C +37 25 01 10 13 05 45 A0 EF 80 60 31 83 28 CD C5 +6F E0 3F DF 95 64 93 84 04 EC 26 85 EF E0 2F B7 +83 27 CD C5 83 A5 C9 06 E3 70 F9 E0 26 85 EF E0 +0F B6 83 27 CD C5 83 A5 09 07 E3 73 F9 9E 26 85 +EF E0 EF B4 F1 BA 95 68 93 88 C8 AE 93 89 48 3D +A6 85 4E 85 23 26 14 FB EF E0 6F B3 83 27 84 FB +83 28 C4 FA 63 97 97 12 83 27 CD C5 83 24 09 07 +E3 74 FA 9A A6 85 4E 85 EF E0 6F B1 71 BA 95 68 +A6 85 13 85 08 EC EF E0 8F B0 8D B2 83 27 CD C5 +63 F8 F4 00 37 45 02 50 13 05 85 A6 EF E0 2F AD +37 25 01 10 13 05 C5 A0 EF 80 60 27 83 28 CD C5 +6F E0 3F D5 B7 17 01 10 E4 53 8D 47 E3 FC E7 90 +95 68 A6 85 13 85 08 EC EF E0 6F AC 21 B2 37 45 +02 50 13 05 05 A0 EF E0 8F A9 1D B7 BC 57 91 B3 +89 47 63 04 F9 00 6F E0 9F D1 83 29 84 F9 83 27 +C4 F9 81 44 83 A6 09 00 98 43 63 8E E6 02 15 69 +13 09 C9 AE A6 85 13 05 49 1C EF E0 4F A8 03 27 +C4 F9 93 97 24 00 13 05 C9 1E BA 97 8C 43 EF E0 +0F A7 83 A5 09 00 13 05 49 20 EF E0 4F A6 05 45 +EF E0 EF A1 01 A0 85 04 91 09 91 07 E3 1C 9A FA +6F E0 FF CB 95 68 05 49 93 88 C8 AE CA 85 13 85 +08 3E 23 26 14 FB EF E0 8F A3 83 28 C4 FA A6 85 +13 85 48 40 EF E0 AF A2 03 27 84 F6 93 17 29 00 +83 28 C4 FA BA 97 8C 43 13 85 C8 41 EF E0 2F A1 +05 45 EF E0 CF 9C 01 A0 95 68 0D 49 93 88 C8 AE +75 BF 09 49 65 BF 95 68 01 49 93 88 C8 AE 7D B7 +37 45 02 50 13 05 C5 96 EF E0 6F 9C 05 45 EF E0 +0F 9A 01 A0 13 01 01 C9 23 26 71 35 B7 3B 02 50 +23 2A 51 35 83 AA CB C5 23 24 81 36 23 22 91 36 +23 20 21 37 23 2C 41 35 23 28 61 35 2E CF 23 26 +11 36 23 2E 31 35 23 24 81 35 2A CD 89 45 32 84 +36 8B 3A 8A 3E 89 C2 84 63 EC 55 31 C1 47 63 F8 +67 01 63 9A 0A 32 05 45 EF E0 6F 94 01 A0 B7 38 +02 50 93 85 88 CE BC 19 93 88 88 CE 13 88 05 04 +03 A5 08 00 03 A6 48 00 83 A6 88 00 03 A7 C8 00 +88 C3 D0 C3 94 C7 D8 C7 C1 08 C1 07 E3 92 08 FF +B7 17 58 26 93 87 37 92 3E D7 3E DF B7 47 63 94 +93 87 F7 37 BE C5 B7 27 2F FE 93 87 97 6E B7 D6 +E2 95 BE C7 B7 D7 DC 33 83 A8 05 05 93 86 B6 DA +93 87 37 85 03 AF 05 04 83 AE 45 04 03 AE 85 04 +03 A3 C5 04 03 A8 45 05 A8 4D F0 4D 37 47 EA D5 +36 D9 BE C9 B7 86 41 5B B7 07 22 B3 13 07 27 D1 +93 87 37 50 93 86 06 37 3A D5 3A DD C6 D5 BE CB +36 DB 82 C1 82 C3 FA CD F6 CF F2 D1 9A D3 C2 D7 +AA D9 B2 DB 93 87 05 06 38 1A 93 88 05 0A 03 A8 +07 00 C8 43 90 47 D4 47 23 20 07 01 48 C3 10 C7 +54 C7 C1 07 41 07 E3 94 17 FF 93 87 05 0A B8 1A +93 88 05 0E 03 A8 07 00 C8 43 90 47 D4 47 23 20 +07 01 48 C3 10 C7 54 C7 C1 07 41 07 E3 94 17 FF +93 87 05 0E 38 1B 93 88 05 12 03 A8 07 00 C8 43 +90 47 D4 47 23 20 07 01 48 C3 10 C7 54 C7 C1 07 +41 07 E3 94 17 FF 93 88 05 12 BC 1B 13 88 05 16 +03 A5 08 00 03 A6 48 00 83 A6 88 00 03 A7 C8 00 +88 C3 D0 C3 94 C7 D8 C7 C1 08 C1 07 E3 92 08 FF +93 88 05 16 3C 1C 13 88 05 1A 03 A5 08 00 03 A6 +48 00 83 A6 88 00 03 A7 C8 00 88 C3 D0 C3 94 C7 +D8 C7 C1 08 C1 07 E3 92 08 FF 93 88 05 1A BC 1C +93 85 05 1E 03 A5 08 00 03 A6 48 00 83 A6 88 00 +03 A7 C8 00 88 C3 D0 C3 94 C7 D8 C7 C1 08 C1 07 +E3 92 B8 FE 13 06 80 08 81 45 28 1D EF B0 30 1A +93 3B 19 00 C1 47 85 0B 63 82 F4 16 85 47 13 0C +81 17 63 81 F4 02 93 07 00 02 63 88 F4 16 89 47 +63 8A F4 16 91 47 63 83 F4 18 A1 47 93 09 81 0A +63 83 F4 18 5E 57 23 22 04 02 23 24 04 02 18 D0 +4E 57 23 26 04 02 23 28 04 02 58 CC 3E 57 23 2A +04 02 23 2C 04 02 18 CC 2E 57 23 2E 04 02 23 20 +04 04 58 C8 1E 57 18 C8 0E 57 58 C4 6E 47 58 C0 +7E 47 18 C4 63 14 0B 00 13 0B 00 04 89 47 63 E0 +57 13 13 16 2B 00 63 0E 09 0C E2 85 52 85 EF B0 +A0 7C BC 01 23 2E F1 30 22 86 3C 1D 13 08 04 04 +08 42 4C 42 14 46 58 46 88 C3 CC C3 94 C7 D8 C7 +41 06 C1 07 E3 16 06 FF 10 42 EA 46 7A 47 90 C3 +BC 19 23 26 F1 30 85 47 23 00 F1 32 23 22 31 31 +23 24 61 31 23 28 81 31 23 2E D1 2E 23 20 E1 30 +3C 1D 0A 88 28 1E 8C 43 D0 43 94 47 D8 47 23 20 +B8 00 23 22 C8 00 23 24 D8 00 23 26 E8 00 C1 07 +41 08 E3 92 A7 FE 83 A8 07 00 DC 43 8A 86 A6 85 +5E 85 01 47 11 46 23 20 18 01 23 22 F8 00 EF E0 +2F D7 83 20 C1 36 03 24 81 36 83 24 41 36 03 29 +01 36 83 29 C1 35 03 2A 81 35 83 2A 41 35 03 2B +01 35 83 2B C1 34 03 2C 81 34 13 01 01 37 82 80 +37 45 02 50 13 05 45 AC EF D0 7F E5 83 AA CB C5 +F1 B9 AC 19 52 85 EF B0 20 6F 25 B7 93 09 81 0B +13 0C 81 27 C1 B5 15 65 DA 85 13 05 05 F2 EF D0 +1F E5 05 45 EF D0 BF E0 D1 B1 93 09 81 0A 13 0C +81 13 4D B5 93 09 81 0A 13 0C 81 1B 61 BD 15 65 +DA 85 13 05 85 F7 EF D0 9F E2 E1 BD 93 09 81 0A +13 0C 81 1F 41 B5 13 0C 81 23 AD BD 53 74 72 69 +6E 67 20 6C 65 6E 67 74 68 20 69 73 20 25 64 2E +0A 00 00 00 45 72 72 6F 72 3A 20 49 6E 76 61 6C +69 64 20 68 65 78 20 63 68 61 72 61 63 74 65 72 +3A 20 25 63 0A 00 00 00 53 74 72 69 6E 67 20 6C +65 6E 67 74 68 20 69 73 20 25 64 2E 0A 00 00 00 +45 72 72 6F 72 3A 20 49 6E 76 61 6C 69 64 20 68 +65 78 20 63 68 61 72 61 63 74 65 72 3A 20 25 63 +0A 00 00 00 53 65 74 20 41 45 53 20 4B 56 20 57 +72 69 74 65 20 74 6F 20 73 6C 6F 74 20 25 64 0A +00 00 00 00 57 72 69 74 65 20 41 45 53 20 43 54 +52 4C 20 77 69 74 68 20 76 61 6C 75 65 20 30 78 +25 78 0A 00 57 72 69 74 65 20 47 43 4D 5F 41 41 +44 20 50 68 61 73 65 2C 20 4E 55 4D 5F 42 59 54 +45 53 20 30 78 25 78 0A 00 00 00 00 57 72 69 74 +65 20 41 45 53 20 41 41 44 20 42 6C 6F 63 6B 20 +25 64 0A 00 50 61 64 64 69 6E 67 20 41 41 44 20 +77 69 74 68 20 30 73 20 41 41 44 20 44 57 4F 52 +44 3A 20 25 64 00 00 00 57 72 69 74 65 20 49 6E +20 44 61 74 61 3A 20 30 78 25 78 20 61 61 64 20 +44 57 4F 52 44 3A 20 25 64 0A 00 00 53 52 43 3A +20 7B 20 30 78 25 30 78 5F 25 30 78 20 7D 20 74 +6F 20 44 53 54 3A 20 7B 20 30 78 25 30 78 5F 25 +30 78 20 7D 0A 00 00 00 41 74 20 6F 66 66 73 65 +74 20 5B 25 64 5D 2C 20 6F 75 74 70 75 74 20 64 +61 74 61 20 6D 69 73 6D 61 74 63 68 21 0A 00 00 +41 63 74 75 61 6C 20 20 20 64 61 74 61 3A 20 30 +78 25 78 0A 00 00 00 00 45 78 70 65 63 74 65 64 +20 64 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +41 74 20 6F 66 66 73 65 74 20 5B 25 64 5D 2C 20 +6F 75 74 70 75 74 20 64 61 74 61 20 6D 69 73 6D +61 74 63 68 21 0A 00 00 41 63 74 75 61 6C 20 20 +20 64 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +45 78 70 65 63 74 65 64 20 64 61 74 61 3A 20 30 +78 25 78 0A 00 00 00 00 57 72 69 74 65 20 41 45 +53 20 49 6E 70 75 74 20 44 61 74 61 20 42 6C 6F +63 6B 20 25 64 0A 00 00 57 72 69 74 65 20 49 6E +20 44 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +57 72 69 74 65 20 49 6E 20 44 61 74 61 3A 20 30 +78 25 78 0A 00 00 00 00 45 58 50 45 43 54 45 44 +20 4F 55 54 50 55 54 5F 4C 4F 53 54 20 74 6F 20 +62 65 20 30 78 30 20 2D 20 41 63 74 75 61 6C 3A +20 30 78 25 78 00 00 00 43 49 50 48 45 52 54 45 +58 54 3A 20 30 78 25 78 0A 00 00 00 41 74 20 6F +66 66 73 65 74 20 5B 25 64 5D 2C 20 6F 75 74 70 +75 74 20 64 61 74 61 20 6D 69 73 6D 61 74 63 68 +21 0A 00 00 41 63 74 75 61 6C 20 20 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 41 74 20 6F +66 66 73 65 74 20 5B 25 64 5D 2C 20 6F 75 74 70 +75 74 20 64 61 74 61 20 6D 69 73 6D 61 74 63 68 +21 0A 00 00 41 63 74 75 61 6C 20 20 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 45 78 70 65 +63 74 65 64 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 41 74 20 6F 66 66 73 65 74 20 5B 25 +64 5D 2C 20 6F 75 74 70 75 74 20 64 61 74 61 20 +6D 69 73 6D 61 74 63 68 21 0A 00 00 41 63 74 75 +61 6C 20 20 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 45 78 70 65 63 74 65 64 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 57 72 69 74 +65 20 41 41 44 20 4C 65 6E 67 74 68 3A 20 30 78 +25 78 0A 00 57 72 69 74 65 20 54 65 78 74 20 4C +65 6E 67 74 68 3A 20 30 78 25 78 0A 00 00 00 00 +54 41 47 3A 20 30 78 25 78 0A 00 00 41 74 20 6F +66 66 73 65 74 20 5B 25 64 5D 2C 20 74 61 67 20 +64 61 74 61 20 6D 69 73 6D 61 74 63 68 21 0A 00 +41 63 74 75 61 6C 20 20 20 64 61 74 61 3A 20 30 +78 25 78 0A 00 00 00 00 45 78 70 65 63 74 65 64 +20 64 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +45 52 52 4F 52 3A 20 6F 76 65 72 72 69 64 65 5F +74 65 78 74 5F 6C 65 6E 67 74 68 20 28 25 64 29 +20 65 78 63 65 65 64 73 20 6D 61 78 69 6D 75 6D +20 61 6C 6C 6F 77 65 64 20 73 69 7A 65 20 6F 66 +20 31 36 20 64 77 6F 72 64 73 20 28 35 31 32 20 +62 69 74 73 29 0A 00 00 50 6F 70 75 6C 61 74 65 +20 4B 56 20 77 69 74 68 20 6B 65 79 20 6C 65 6E +67 74 68 3A 20 25 64 0A 00 00 79 71 4A D0 37 39 +02 50 03 28 C9 C5 22 D4 26 D2 4E CE 52 CC 56 CA +5A C8 06 D6 5E C6 89 48 AA 8A 2E 8B 32 8A 36 84 +BA 89 BE 84 63 E6 08 1B 83 A6 0A 00 B7 07 00 10 +13 87 47 00 94 C3 83 A6 4A 00 D4 C3 83 A7 8A 00 +5C C3 83 A7 CA 00 1C C7 93 16 24 00 93 F6 C6 07 +93 E6 16 00 B7 07 00 10 94 CB 37 04 00 10 54 48 +89 8A F5 DE 8D 4A 63 EC 0A 11 83 26 0B 00 B7 07 +00 10 13 87 47 00 94 C3 83 26 4B 00 D4 C3 83 27 +8B 00 5C C3 83 27 CB 00 1C C7 13 97 29 00 13 77 +C7 07 13 67 27 00 B7 07 00 10 98 CB 37 04 00 10 +58 48 09 8B 75 DF 8D 49 63 E3 09 07 83 27 0A 00 +37 07 00 10 93 06 47 00 1C C3 03 26 4A 00 B7 07 +03 30 83 A7 07 0E 50 C3 03 27 8A 00 93 F7 07 04 +D8 C2 03 27 CA 00 98 C6 C1 C3 93 97 24 00 93 F7 +C7 07 93 E7 07 08 37 07 00 10 1C CB 5C 4B 89 8B +F5 DF 8D 47 63 E7 07 15 B2 50 22 54 92 54 02 59 +F2 49 62 4A D2 4A 42 4B B2 4B 45 61 82 80 37 45 +02 50 13 05 85 B9 EF D0 9F 82 03 28 C9 C5 E3 F7 +09 F9 37 45 02 50 13 05 85 BC EF D0 5F 81 83 27 +0A 00 03 28 C9 C5 1C C0 83 26 4A 00 B7 07 03 30 +83 A7 07 0E 54 C0 83 26 8A 00 93 F7 07 04 14 C4 +83 26 CA 00 54 C4 F9 EB 89 47 E3 FF 07 F9 37 45 +02 50 13 05 05 C3 22 54 B2 50 92 54 02 59 F2 49 +62 4A D2 4A 42 4B B2 4B 45 61 6F D0 4F FC 37 45 +02 50 13 05 05 B2 EF D0 8F FB 03 28 C9 C5 E3 FE +0A ED 37 45 02 50 13 05 85 B4 EF D0 4F FA 03 27 +0B 00 03 28 C9 C5 18 C0 03 27 4B 00 58 C0 03 27 +8B 00 18 C4 03 27 CB 00 58 C4 E3 F8 0A ED 37 45 +02 50 13 05 85 B6 EF D0 8F F7 03 28 C9 C5 75 BD +37 45 02 50 13 05 85 AD EF D0 6F F6 03 28 C9 C5 +8D 4B E3 F3 0B E5 37 45 02 50 13 05 45 AE EF D0 +0F F5 03 A7 0A 00 B7 07 00 10 03 28 C9 C5 98 C3 +83 A6 4A 00 13 87 47 00 D4 C3 83 A7 8A 00 5C C3 +83 A7 CA 00 1C C7 E3 F9 0B E3 37 45 02 50 13 05 +85 AF EF D0 CF F1 03 28 C9 C5 39 BD E3 F7 09 EB +37 45 02 50 13 05 C5 BD EF D0 6F F0 03 28 C9 C5 +69 BD 37 45 02 50 13 05 45 C0 31 BF B7 37 02 50 +03 A7 C7 C5 8D 47 63 E7 E7 00 B7 07 00 10 0D 47 +98 CB 82 80 37 45 02 50 41 11 13 05 45 C6 06 C6 +EF D0 EF EC B2 40 B7 07 00 10 0D 47 98 CB 41 01 +82 80 00 00 41 11 22 C4 37 34 02 50 03 27 C4 C5 +06 C6 89 47 63 E0 E7 04 37 67 02 50 13 07 87 E2 +1C 47 54 47 D5 8F 9D E3 73 00 50 10 93 07 40 06 +01 00 FD 17 C2 07 C1 83 E5 FF 1C 47 54 47 D5 8F +E5 D7 83 26 C4 C5 89 47 63 E5 D7 02 B2 40 22 44 +41 01 82 80 37 45 02 50 13 05 85 C7 EF D0 2F E6 +37 67 02 50 13 07 87 E2 1C 47 54 47 D5 8F CD DF +C9 BF 22 44 4C 47 B2 40 10 47 1D 65 13 05 45 81 +41 01 6F D0 CF E5 B7 37 02 50 03 A7 C7 C5 89 47 +63 E7 E7 00 B7 87 00 10 11 47 98 CB 82 80 37 45 +02 50 41 11 13 05 05 C9 06 C6 EF D0 4F E1 B2 40 +B7 87 00 10 11 47 98 CB 41 01 82 80 79 71 26 D2 +4A D0 56 CA 5A C8 06 D6 22 D4 4E CE 52 CC 5E C6 +83 4B 15 00 03 CA 06 00 36 8B 3E 89 B2 86 BA 8A +C2 84 B7 87 00 10 80 4F 05 88 75 DC 03 47 05 00 +63 03 07 3C 13 97 1B 00 13 77 E7 03 13 67 17 00 +23 A4 E7 60 23 A0 07 08 23 A2 07 08 23 A4 07 08 +23 A6 07 08 23 A8 07 08 23 AA 07 08 23 AC 07 08 +23 AE 07 08 23 A0 07 0A 23 A2 07 0A 23 A4 07 0A +23 A6 07 0A 37 87 00 10 83 27 C7 60 89 8B ED DF +63 0D 0A 00 83 47 1B 00 37 87 00 10 86 07 93 F7 +E7 03 93 E7 17 20 23 28 F7 60 D8 41 B7 87 00 10 +B7 39 02 50 23 A0 E7 50 98 45 09 46 23 A2 E7 50 +D8 45 23 A4 E7 50 98 49 23 A6 E7 50 D8 49 23 A8 +E7 50 98 4D 23 AA E7 50 D8 4D 23 AC E7 50 98 51 +23 AE E7 50 D8 51 23 A0 E7 52 98 55 23 A2 E7 52 +D8 55 23 A4 E7 52 98 59 23 A6 E7 52 D8 42 23 A0 +E7 48 98 46 23 A2 E7 48 D8 46 23 A4 E7 48 98 4A +23 A6 E7 48 D8 4A 23 A8 E7 48 98 4E 23 AA E7 48 +D8 4E 23 AC E7 48 98 52 23 AE E7 48 D8 52 23 A0 +E7 4A 98 56 23 A2 E7 4A D8 56 23 A4 E7 4A 98 5A +23 A6 E7 4A 03 A7 C9 C5 63 6B E6 30 B7 87 00 10 +85 46 94 CB 63 93 0B 00 0D 44 B7 87 00 10 23 A4 +87 60 23 A0 07 08 23 A2 07 08 23 A4 07 08 23 A6 +07 08 23 A8 07 08 23 AA 07 08 23 AC 07 08 23 AE +07 08 23 A0 07 0A 23 A2 07 0A 23 A4 07 0A 23 A6 +07 0A 89 47 63 EE E7 2A 37 67 02 50 13 07 87 E2 +1C 47 54 47 D5 8F 91 EF 73 00 50 10 93 07 40 06 +01 00 FD 17 C2 07 C1 83 E5 FF 1C 47 54 47 D5 8F +E5 D7 83 A7 C9 C5 09 44 63 6D F4 0A 63 1E 0A 0C +B7 87 00 10 03 AA 07 18 03 24 4B 00 63 1C 8A 2A +03 AA 47 18 03 24 8B 00 63 15 8A 30 03 AA 87 18 +03 24 CB 00 63 11 8A 30 03 AA C7 18 03 24 0B 01 +63 1D 8A 2E 03 AA 07 19 03 24 4B 01 63 19 8A 2E +03 AA 47 19 03 24 8B 01 63 15 8A 2E 03 AA 87 19 +03 24 CB 01 63 11 8A 2E 03 AA C7 19 03 24 0B 02 +63 1D 8A 2C 03 AA 07 1A 03 24 4B 02 63 13 8A 2E +03 AA 47 1A 03 24 8B 02 63 1F 8A 2C 03 AA 87 1A +03 24 CB 02 63 15 8A 2C 03 AA C7 1A 03 24 0B 03 +AD 45 63 1A 8A 22 85 47 63 89 F4 04 B2 50 22 54 +92 54 02 59 F2 49 62 4A D2 4A 42 4B B2 4B 45 61 +82 80 4C 47 10 47 1D 65 13 05 45 81 EF D0 2F BA +83 A7 C9 C5 63 0E 0A 1C 63 78 F4 00 37 45 02 50 +13 05 05 CB EF D0 AF B6 37 87 00 10 83 27 47 61 +89 8B ED DF 85 47 E3 9B F4 FA 03 A7 C9 C5 89 47 +63 E1 E7 1C B7 87 00 10 83 A4 07 20 03 A4 4A 00 +63 99 84 20 83 A4 47 20 03 A4 8A 00 63 99 84 22 +83 A4 87 20 03 A4 CA 00 63 95 84 22 83 A4 C7 20 +03 A4 0A 01 63 91 84 22 83 A4 07 21 03 A4 4A 01 +63 9D 84 20 83 A4 47 21 03 A4 8A 01 63 91 84 1E +83 A4 87 21 03 A4 CA 01 63 99 84 2A 83 A4 C7 21 +03 A4 0A 02 63 91 84 2A 83 A4 07 22 03 A4 4A 02 +63 99 84 28 83 A4 47 22 03 A4 8A 02 63 91 84 28 +83 A4 87 22 03 A4 CA 02 63 99 84 26 83 A4 C7 22 +03 A4 0A 03 AD 45 63 97 84 18 89 47 63 EC E7 16 +B7 87 00 10 83 A4 07 28 03 24 49 00 63 15 94 24 +83 A4 47 28 03 24 89 00 63 1D 94 22 83 A4 87 28 +03 24 C9 00 63 15 94 22 83 A4 C7 28 03 24 09 01 +63 9D 84 20 83 A4 07 29 03 24 49 01 63 95 84 20 +83 A4 47 29 03 24 89 01 63 9D 84 1E 83 A4 87 29 +03 24 C9 01 63 95 84 1E 83 A4 C7 29 03 24 09 02 +63 9D 84 1C 83 A4 07 2A 03 24 49 02 63 95 84 1C +83 A4 47 2A 03 24 89 02 63 9D 84 1A 83 A4 87 2A +03 24 C9 02 63 95 84 1A 83 A4 C7 2A 03 24 09 03 +AD 45 E3 8D 84 E6 83 A7 C9 C5 63 90 07 16 05 45 +EF D0 EF 9E 01 A0 58 41 23 A0 E7 08 18 45 23 A2 +E7 08 58 45 23 A4 E7 08 18 49 23 A6 E7 08 58 49 +23 A8 E7 08 18 4D 23 AA E7 08 58 4D 23 AC E7 08 +18 51 23 AE E7 08 58 51 23 A0 E7 0A 18 55 23 A2 +E7 0A 58 55 23 A4 E7 0A 18 59 23 A6 E7 0A 89 B1 +37 45 02 50 13 05 85 C7 EF D0 6F 9B 35 BB 37 45 +02 50 13 05 45 CA EF D0 8F 9A 03 A7 C9 C5 F9 B9 +E3 70 F4 D6 37 45 02 50 13 05 45 CC EF D0 2F 99 +81 BB 37 45 02 50 13 05 05 CE EF D0 4F 98 03 A7 +C9 C5 0D BD 81 45 83 A7 C9 C5 89 E7 05 45 EF D0 +0F 95 01 A0 9D 64 93 84 44 81 13 85 44 03 EF D0 +0F 98 83 A7 C9 C5 FD D3 D2 85 13 85 04 06 EF D0 +0F 97 83 A7 C9 C5 F9 DB A2 85 13 85 84 07 EF D0 +0F 96 E9 B7 37 45 02 50 13 05 C5 CF EF D0 2F 93 +41 B5 81 45 39 E3 05 45 EF D0 6F 90 01 A0 95 45 +D5 BF 85 45 4D B7 89 45 79 BF 8D 45 69 BF 91 45 +59 BF 95 45 49 BF 99 45 79 B7 9D 45 69 B7 85 45 +D1 BF 89 45 C1 BF 8D 45 F1 B7 91 45 E1 B7 A9 45 +9D BF A1 45 8D BF A5 45 BD B7 1D 69 13 09 49 81 +13 05 09 09 EF D0 AF 8F 83 A7 C9 C5 CD D7 A6 85 +13 05 09 0C EF D0 AF 8E 83 A7 C9 C5 C9 DF A2 85 +13 05 89 0D EF D0 AF 8D 79 B7 1D 69 13 09 49 81 +13 05 09 0F EF D0 AF 8C 83 A7 C9 C5 E3 89 07 E8 +A6 85 13 05 09 12 EF D0 8F 8B 83 A7 C9 C5 E3 80 +07 E8 A2 85 13 05 89 13 EF D0 6F 8A 8D BD A9 45 +9D B5 A5 45 8D B5 A1 45 B9 BD 9D 45 A9 BD 99 45 +99 BD 95 45 89 BD 91 45 B9 B5 8D 45 A9 B5 89 45 +99 B5 85 45 89 B5 81 45 3D BD A9 45 25 B7 A5 45 +15 B7 A1 45 05 B7 9D 45 31 BF 99 45 21 BF 79 71 +4E CE 52 CC 5A C8 5E C6 06 D6 22 D4 26 D2 4A D0 +56 CA 83 CA 15 00 83 44 07 00 BA 89 2A 8A B2 8B +36 8B B7 87 00 10 80 4F 05 88 75 DC 03 C7 05 00 +63 0D 07 2C 13 97 1A 00 13 77 E7 03 13 67 17 00 +23 A0 E7 60 37 87 00 10 83 27 47 60 89 8B ED DF +37 39 02 50 03 27 C9 C5 89 47 63 E3 E7 30 03 A6 +4B 00 B7 87 00 10 89 46 23 A0 C7 20 03 A6 8B 00 +23 A2 C7 20 03 A6 CB 00 23 A4 C7 20 03 A6 0B 01 +23 A6 C7 20 03 A6 4B 01 23 A8 C7 20 03 A6 8B 01 +23 AA C7 20 03 A6 CB 01 23 AC C7 20 03 A6 0B 02 +23 AE C7 20 03 A6 4B 02 23 A0 C7 22 03 A6 8B 02 +23 A2 C7 22 03 A6 CB 02 23 A4 C7 22 03 A6 0B 03 +23 A6 C7 22 63 E7 E6 2C 83 26 4B 00 B7 87 00 10 +23 A0 D7 28 83 26 8B 00 23 A2 D7 28 83 26 CB 00 +23 A4 D7 28 83 26 0B 01 23 A6 D7 28 83 26 4B 01 +23 A8 D7 28 83 26 8B 01 23 AA D7 28 83 26 CB 01 +23 AC D7 28 83 26 0B 02 23 AE D7 28 83 26 4B 02 +23 A0 D7 2A 83 26 8B 02 23 A2 D7 2A 83 26 CB 02 +23 A4 D7 2A 83 26 0B 03 23 A6 D7 2A 83 26 4A 00 +23 A0 D7 48 83 26 8A 00 23 A2 D7 48 83 26 CA 00 +23 A4 D7 48 83 26 0A 01 23 A6 D7 48 83 26 4A 01 +23 A8 D7 48 83 26 8A 01 23 AA D7 48 83 26 CA 01 +23 AC D7 48 83 26 0A 02 23 AE D7 48 83 26 4A 02 +23 A0 D7 4A 83 26 8A 02 23 A2 D7 4A 83 26 CA 02 +23 A4 D7 4A 83 26 0A 03 23 A6 D7 4A 81 CC 83 C6 +19 00 05 66 13 06 16 AC 86 06 93 F6 F6 0F D1 8E +23 A8 D7 60 89 47 63 ED E7 1C B7 87 00 10 C1 46 +94 CB 63 93 0A 00 0D 44 B7 87 00 10 23 A0 87 60 +23 A0 07 58 23 A2 07 58 23 A4 07 58 23 A6 07 58 +23 A8 07 58 23 AA 07 58 23 AC 07 58 23 AE 07 58 +23 A0 07 5A 23 A2 07 5A 23 A4 07 5A 23 A6 07 5A +89 47 63 E0 E7 18 37 67 02 50 13 07 87 E2 1C 47 +54 47 D5 8F 91 EF 73 00 50 10 93 07 40 06 01 00 +FD 17 C2 07 C1 83 E5 FF 1C 47 54 47 D5 8F E5 D7 +83 27 C9 C5 09 44 63 69 F4 0A E9 E8 B7 87 00 10 +83 A4 07 5C 03 A4 49 00 63 1F 94 16 83 A4 47 5C +03 A4 89 00 63 1B 94 1A 83 A4 87 5C 03 A4 C9 00 +63 97 84 1A 83 A4 C7 5C 03 A4 09 01 63 93 84 1A +83 A4 07 5D 03 A4 49 01 63 9F 84 18 83 A4 47 5D +03 A4 89 01 63 9B 84 18 83 A4 87 5D 03 A4 C9 01 +63 97 84 18 83 A4 C7 5D 03 A4 09 02 63 93 84 18 +83 A4 07 5E 03 A4 49 02 63 9F 84 16 83 A4 47 5E +03 A4 89 02 63 9B 84 16 83 A4 87 5E 03 A4 C9 02 +63 93 84 14 83 A4 C7 5E 03 A4 09 03 AD 45 63 9D +84 0E B2 50 22 54 92 54 02 59 F2 49 62 4A D2 4A +42 4B B2 4B 45 61 82 80 4C 47 10 47 1D 65 13 05 +45 81 EF C0 DF D7 83 27 C9 C5 CD CC 63 78 F4 00 +37 45 02 50 13 05 05 CB EF C0 7F D4 37 87 00 10 +83 27 47 61 89 8B ED DF 6D BF D8 41 37 39 02 50 +23 A0 E7 58 98 45 23 A2 E7 58 D8 45 23 A4 E7 58 +98 49 23 A6 E7 58 D8 49 23 A8 E7 58 98 4D 23 AA +E7 58 D8 4D 23 AC E7 58 98 51 23 AE E7 58 D8 51 +23 A0 E7 5A 98 55 23 A2 E7 5A D8 55 23 A4 E7 5A +98 59 23 A6 E7 5A 03 27 C9 C5 89 47 E3 F1 E7 D0 +37 45 02 50 13 05 85 D1 EF C0 7F CD 03 27 C9 C5 +FD B1 37 45 02 50 13 05 85 C7 EF C0 5F CC A5 BD +37 45 02 50 13 05 05 D5 EF C0 7F CB 03 27 C9 C5 +29 BD 37 45 02 50 13 05 45 D3 EF C0 5F CA 03 27 +C9 C5 1D B3 E3 74 F4 E8 37 45 02 50 13 05 05 D6 +EF C0 FF C8 A5 BD 81 45 83 27 C9 C5 89 E7 05 45 +EF C0 FF C5 01 A0 9D 69 93 89 49 81 13 85 09 15 +EF C0 FF C8 83 27 C9 C5 FD D3 A6 85 13 85 09 18 +EF C0 FF C7 83 27 C9 C5 F9 DB A2 85 13 85 89 19 +EF C0 FF C6 E9 B7 A9 45 C1 B7 85 45 75 BF 89 45 +65 BF 8D 45 55 BF 91 45 45 BF 95 45 75 B7 99 45 +65 B7 9D 45 55 B7 A1 45 45 B7 A5 45 71 BF 79 71 +26 D2 4E CE 52 CC 5A C8 5E C6 06 D6 22 D4 4A D0 +56 CA 83 4A 15 00 BE 84 AE 8B 32 8B B6 89 3A 8A +B7 87 00 10 80 4F 05 88 75 DC 83 46 05 00 37 39 +02 50 03 27 C9 C5 63 87 06 32 89 47 63 E9 E7 38 +93 96 1A 00 93 F6 E6 03 B7 87 00 10 93 E6 16 00 +23 A0 D7 60 23 A0 07 58 23 A2 07 58 23 A4 07 58 +23 A6 07 58 23 A8 07 58 23 AA 07 58 23 AC 07 58 +23 AE 07 58 23 A0 07 5A 23 A2 07 5A 23 A4 07 5A +23 A6 07 5A B7 86 00 10 83 A7 46 60 89 8B ED DF +03 A6 4B 00 B7 87 00 10 89 46 23 A0 C7 10 03 A6 +8B 00 23 A2 C7 10 03 A6 CB 00 23 A4 C7 10 03 A6 +0B 01 23 A6 C7 10 03 A6 4B 01 23 A8 C7 10 03 A6 +8B 01 23 AA C7 10 03 A6 CB 01 23 AC C7 10 03 A6 +0B 02 23 AE C7 10 03 A6 4B 02 23 A0 C7 12 03 A6 +8B 02 23 A2 C7 12 03 A6 CB 02 23 A4 C7 12 03 A6 +0B 03 23 A6 C7 12 03 26 4B 00 23 A0 C7 48 03 26 +8B 00 23 A2 C7 48 03 26 CB 00 23 A4 C7 48 03 26 +0B 01 23 A6 C7 48 03 26 4B 01 23 A8 C7 48 03 26 +8B 01 23 AA C7 48 03 26 CB 01 23 AC C7 48 03 26 +0B 02 23 AE C7 48 03 26 4B 02 23 A0 C7 4A 03 26 +8B 02 23 A2 C7 4A 03 26 CB 02 23 A4 C7 4A 03 26 +0B 03 23 A6 C7 4A 63 E3 E6 26 B7 87 00 10 89 46 +94 CB 63 93 0A 00 0D 44 B7 87 00 10 23 A0 87 60 +23 A0 07 58 23 A2 07 58 23 A4 07 58 23 A6 07 58 +23 A8 07 58 23 AA 07 58 23 AC 07 58 23 AE 07 58 +23 A0 07 5A 23 A2 07 5A 23 A4 07 5A 23 A6 07 5A +89 47 63 E6 E7 20 37 67 02 50 13 07 87 E2 1C 47 +54 47 D5 8F 91 EF 73 00 50 10 93 07 40 06 01 00 +FD 17 C2 07 C1 83 E5 FF 1C 47 54 47 D5 8F E5 D7 +83 26 C9 C5 09 44 63 60 D4 02 85 47 63 83 F4 04 +B2 50 22 54 92 54 02 59 F2 49 62 4A D2 4A 42 4B +B2 4B 45 61 82 80 4C 47 10 47 1D 65 13 05 45 81 +EF C0 FF A3 85 47 E3 9D F4 FC 83 26 C9 C5 63 7A +D4 00 37 45 02 50 13 05 05 DB EF C0 5F A0 83 26 +C9 C5 B7 87 00 10 83 A4 07 30 03 A4 49 00 63 99 +84 1A 83 A4 47 30 03 A4 89 00 63 9C 84 22 83 A4 +87 30 03 A4 C9 00 63 9E 84 20 83 A4 C7 30 03 A4 +09 01 63 9A 84 20 83 A4 07 31 03 A4 49 01 63 96 +84 20 83 A4 47 31 03 A4 89 01 63 92 84 20 83 A4 +87 31 03 A4 C9 01 63 90 84 20 83 A4 C7 31 03 A4 +09 02 63 9C 84 1E 83 A4 07 32 03 A4 49 02 63 98 +84 1C 83 A4 47 32 03 A4 89 02 63 90 84 1C 83 A4 +87 32 03 A4 C9 02 63 98 84 1A 83 A4 C7 32 03 A4 +09 03 AD 45 63 97 84 12 89 47 63 E9 D7 12 B7 87 +00 10 83 A4 07 38 03 24 4A 00 63 94 84 18 83 A4 +47 38 03 24 8A 00 63 1C 94 16 83 A4 87 38 03 24 +CA 00 63 94 84 16 83 A4 C7 38 03 24 0A 01 63 1C +94 14 83 A4 07 39 03 24 4A 01 63 94 84 14 83 A4 +47 39 03 24 8A 01 63 9C 84 12 83 A4 87 39 03 24 +CA 01 63 94 84 12 83 A4 C7 39 03 24 0A 02 63 9C +84 10 83 A4 07 3A 03 24 4A 02 63 94 84 10 83 A4 +47 3A 03 24 8A 02 63 9C 84 0E 83 A4 87 3A 03 24 +CA 02 63 94 84 0E 83 A4 C7 3A 03 24 0A 03 AD 45 +E3 88 84 E8 83 27 C9 C5 63 93 07 12 05 45 EF C0 +1F 8A 01 A0 54 41 23 A0 D7 58 14 45 23 A2 D7 58 +54 45 23 A4 D7 58 14 49 23 A6 D7 58 54 49 23 A8 +D7 58 14 4D 23 AA D7 58 54 4D 23 AC D7 58 14 51 +23 AE D7 58 54 51 23 A0 D7 5A 14 55 23 A2 D7 5A +54 55 23 A4 D7 5A 14 59 23 A6 D7 5A D5 B1 37 45 +02 50 13 05 85 C7 EF C0 9F 86 F5 B3 37 45 02 50 +13 05 05 DA EF C0 BF 85 03 27 C9 C5 79 B3 37 45 +02 50 13 05 05 D8 EF C0 9F 84 03 27 C9 C5 8D B1 +81 45 81 EE 05 45 EF C0 9F 81 01 A0 37 45 02 50 +13 05 C5 DC EF C0 BF 82 D9 B5 9D 69 93 89 49 81 +13 85 09 1B EF C0 BF 83 83 27 C9 C5 E1 DF A6 85 +13 85 C9 1D EF C0 BF 82 83 27 C9 C5 E1 D7 A2 85 +13 85 49 1F EF C0 BF 81 75 BF A9 45 25 B7 A5 45 +15 B7 A1 45 05 B7 9D 45 31 BF 99 45 21 BF 95 45 +11 BF 91 45 01 BF 8D 45 31 B7 89 45 21 B7 85 45 +11 B7 81 45 01 B7 A9 45 69 B7 A5 45 59 B7 A1 45 +49 B7 89 45 BD BF 8D 45 AD BF 91 45 9D BF 95 45 +8D BF 85 45 BD B7 99 45 AD B7 9D 45 9D B7 9D 69 +93 89 49 81 13 85 C9 20 EF C0 6F FB 83 27 C9 C5 +E3 86 07 EC A6 85 13 85 89 23 EF C0 4F FA 83 27 +C9 C5 E3 8D 07 EA A2 85 13 85 09 25 EF C0 2F F9 +75 B5 01 11 22 CC 26 CA 06 CE 4A C8 4E C6 B6 84 +37 84 00 10 1C 4C 85 8B F5 DF 5C 41 B7 39 02 50 +09 49 23 20 F4 10 1C 45 23 22 F4 10 5C 45 23 24 +F4 10 1C 49 23 26 F4 10 5C 49 23 28 F4 10 1C 4D +23 2A F4 10 5C 4D 23 2C F4 10 1C 51 23 2E F4 10 +5C 51 23 20 F4 12 1C 55 23 22 F4 12 5C 55 23 24 +F4 12 1C 59 23 26 F4 12 DC 41 23 20 F4 20 9C 45 +23 22 F4 20 DC 45 23 24 F4 20 9C 49 23 26 F4 20 +DC 49 23 28 F4 20 9C 4D 23 2A F4 20 DC 4D 23 2C +F4 20 9C 51 23 2E F4 20 DC 51 23 20 F4 22 9C 55 +23 22 F4 22 DC 55 23 24 F4 22 9C 59 23 26 F4 22 +5C 42 23 20 F4 28 1C 46 23 22 F4 28 5C 46 23 24 +F4 28 1C 4A 23 26 F4 28 5C 4A 23 28 F4 28 1C 4E +23 2A F4 28 5C 4E 23 2C F4 28 1C 52 23 2E F4 28 +5C 52 23 20 F4 2A 1C 56 23 22 F4 2A 5C 56 23 24 +F4 2A 1C 5A 23 26 F4 2A DC 40 23 20 F4 30 9C 44 +23 22 F4 30 DC 44 23 24 F4 30 9C 48 23 26 F4 30 +DC 48 23 28 F4 30 9C 4C 23 2A F4 30 DC 4C 23 2C +F4 30 9C 50 23 2E F4 30 DC 50 23 20 F4 32 9C 54 +23 22 F4 32 DC 54 23 24 F4 32 9C 58 23 26 F4 32 +5C 43 23 20 F4 38 1C 47 23 22 F4 38 5C 47 23 24 +F4 38 1C 4B 23 26 F4 38 5C 4B 23 28 F4 38 1C 4F +23 2A F4 38 5C 4F 23 2C F4 38 1C 53 23 2E F4 38 +5C 53 23 20 F4 3A 1C 57 23 22 F4 3A 5C 57 23 24 +F4 3A 1C 5B 23 26 F4 3A 83 A7 C9 C5 63 6E F9 0E +8D 47 1C C8 37 67 02 50 13 07 87 E2 1C 47 54 47 +D5 8F 9D E3 73 00 50 10 93 07 40 06 01 00 FD 17 +C2 07 C1 83 E5 FF 1C 47 54 47 D5 8F E5 D7 83 A7 +C9 C5 09 44 63 60 F4 0A B7 87 00 10 03 A9 07 40 +C0 40 63 11 24 09 03 A9 47 40 80 44 63 1C 89 10 +03 A9 87 40 C0 44 63 15 89 10 03 A9 C7 40 80 48 +63 16 24 11 03 A9 07 41 C0 48 63 1F 89 0E 03 A9 +47 41 80 4C 63 1E 89 0E 03 A9 87 41 C0 4C 63 11 +89 10 03 A9 C7 41 80 50 63 16 89 0E 03 A9 07 42 +C0 50 63 19 89 0E 03 A9 47 42 80 54 63 1E 89 0C +03 A9 87 42 C0 54 63 1B 89 0C 03 A9 C7 42 80 58 +AD 45 63 1A 89 00 F2 40 62 44 D2 44 42 49 B2 49 +05 61 82 80 81 45 83 A7 C9 C5 BD E3 05 45 EF C0 +0F CF 01 A0 4C 47 10 47 1D 65 13 05 45 81 EF C0 +0F D2 83 A7 C9 C5 E3 79 F4 F4 37 45 02 50 13 05 +85 DF EF C0 CF CE 89 B7 37 45 02 50 13 05 85 DE +EF C0 EF CD 83 A7 C9 C5 0D 47 18 C8 E3 7C F9 EE +37 45 02 50 13 05 85 C7 EF C0 6F CC 37 67 02 50 +13 07 87 E2 1C 47 54 47 D5 8F E3 85 07 EE 01 B7 +9D 64 93 84 44 81 13 85 84 26 EF C0 4F CC 83 A7 +C9 C5 C9 D7 CA 85 13 85 84 29 EF C0 4F CB 83 A7 +C9 C5 AD DF A2 85 13 85 04 2B EF C0 4F CA BD B7 +89 45 95 B7 85 45 85 B7 91 45 B1 BF 8D 45 A1 BF +95 45 91 BF 9D 45 81 BF A5 45 B1 B7 A9 45 A1 B7 +99 45 91 B7 A1 45 81 B7 01 11 22 CC 4E C6 52 C4 +06 CE 26 CA 4A C8 2A 87 AE 89 32 8A 37 84 00 10 +1C 4C 85 8B F5 DF 5C 43 37 39 02 50 89 44 23 20 +F4 48 1C 47 23 22 F4 48 5C 47 23 24 F4 48 1C 4B +23 26 F4 48 5C 4B 23 28 F4 48 1C 4F 23 2A F4 48 +5C 4F 23 2C F4 48 1C 53 23 2E F4 48 5C 53 23 20 +F4 4A 1C 57 23 22 F4 4A 5C 57 23 24 F4 4A 1C 5B +23 26 F4 4A 83 27 C9 C5 63 E5 F4 1E A9 47 1C C8 +93 07 F0 03 23 20 F4 60 23 20 04 58 23 22 04 58 +23 24 04 58 23 26 04 58 23 28 04 58 23 2A 04 58 +23 2C 04 58 23 2E 04 58 23 20 04 5A 23 22 04 5A +23 24 04 5A 23 26 04 5A 37 67 02 50 13 07 87 E2 +1C 47 54 47 D5 8F 91 EF 73 00 50 10 93 07 40 06 +01 00 FD 17 C2 07 C1 83 E5 FF 1C 47 54 47 D5 8F +E5 D7 83 26 C9 C5 09 44 63 69 D4 14 B7 87 00 10 +83 A4 07 30 03 A4 49 00 63 9B 84 12 83 A4 47 30 +03 A4 89 00 63 91 84 24 83 A4 87 30 03 A4 C9 00 +63 99 84 22 83 A4 C7 30 03 A4 09 01 63 99 84 22 +83 A4 07 31 03 A4 49 01 63 91 84 22 83 A4 47 31 +03 A4 89 01 63 97 84 24 83 A4 87 31 03 A4 C9 01 +63 9D 84 22 83 A4 C7 31 03 A4 09 02 63 95 84 22 +83 A4 07 32 03 A4 49 02 63 9D 84 20 83 A4 47 32 +03 A4 89 02 63 91 84 22 83 A4 87 32 03 A4 C9 02 +63 91 84 1E 83 A4 C7 32 03 A4 09 03 AD 45 63 99 +84 0A 89 47 63 E8 D7 1A B7 87 00 10 83 A4 07 38 +03 24 4A 00 63 16 94 12 83 A4 47 38 03 24 8A 00 +63 1B 94 1A 83 A4 87 38 03 24 CA 00 63 97 84 1A +83 A4 C7 38 03 24 0A 01 63 93 84 1A 83 A4 07 39 +03 24 4A 01 63 9F 84 18 83 A4 47 39 03 24 8A 01 +63 9B 84 18 83 A4 87 39 03 24 CA 01 63 97 84 18 +83 A4 C7 39 03 24 0A 02 63 93 84 18 83 A4 07 3A +03 24 4A 02 63 9B 84 18 83 A4 47 3A 03 24 8A 02 +63 97 84 18 83 A4 87 3A 03 24 CA 02 63 99 84 16 +83 A4 C7 3A 03 24 0A 03 AD 45 63 94 84 0A F2 40 +62 44 D2 44 42 49 B2 49 22 4A 05 61 82 80 81 45 +E1 EA 05 45 EF C0 AF A0 01 A0 4C 47 10 47 1D 65 +13 05 45 81 EF C0 AF A3 83 26 C9 C5 E3 70 D4 EA +37 45 02 50 13 05 05 DB EF C0 6F A0 83 26 C9 C5 +71 B5 37 45 02 50 13 05 45 E1 EF C0 4F 9F 29 47 +83 27 C9 C5 18 C8 13 07 F0 03 23 20 E4 60 23 20 +04 58 23 22 04 58 23 24 04 58 23 26 04 58 23 28 +04 58 23 2A 04 58 23 2C 04 58 23 2E 04 58 23 20 +04 5A 23 22 04 5A 23 24 04 5A 23 26 04 5A E3 F5 +F4 E0 37 45 02 50 13 05 85 C7 EF C0 4F 9A ED BB +81 45 83 27 C9 C5 89 E7 05 45 EF C0 4F 97 01 A0 +9D 69 93 89 49 81 13 85 49 32 EF C0 4F 9A 83 27 +C9 C5 FD D3 A6 85 13 85 09 35 EF C0 4F 99 83 27 +C9 C5 F9 DB A2 85 13 85 89 36 EF C0 4F 98 E9 B7 +9D 69 93 89 49 81 13 85 89 2C EF C0 4F 97 83 27 +C9 C5 E3 80 07 F2 A6 85 13 85 49 2F EF C0 2F 96 +83 27 C9 C5 E3 87 07 F0 A2 85 13 85 C9 30 EF C0 +0F 95 01 B7 37 45 02 50 13 05 C5 DC EF C0 2F 92 +A1 B5 89 45 F5 B5 85 45 E5 B5 91 45 D5 B5 8D 45 +C5 B5 A9 45 F1 BD 85 45 AD B7 89 45 9D B7 8D 45 +8D B7 91 45 B9 BF 95 45 A9 BF 99 45 99 BF 9D 45 +89 BF A1 45 75 BD 9D 45 65 BD 99 45 55 BD A9 45 +89 B7 95 45 75 B5 A5 45 65 B5 A1 45 1D BF A5 45 +0D BF 01 00 52 65 63 65 69 76 65 64 20 45 43 43 +20 6E 6F 74 69 66 2F 20 65 72 72 20 69 6E 74 72 +20 77 69 74 68 20 73 74 61 74 75 73 20 3D 20 25 +64 2F 20 25 64 0A 00 00 41 74 20 6F 66 66 73 65 +74 20 5B 25 64 5D 2C 20 65 63 63 5F 70 72 69 76 +6B 65 79 20 64 61 74 61 20 6D 69 73 6D 61 74 63 +68 21 0A 00 41 63 74 75 61 6C 20 20 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 45 78 70 65 +63 74 65 64 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 41 74 20 6F 66 66 73 65 74 20 5B 25 +64 5D 2C 20 65 63 63 5F 70 75 62 6B 65 79 5F 78 +20 64 61 74 61 20 6D 69 73 6D 61 74 63 68 21 0A +00 00 00 00 41 63 74 75 61 6C 20 20 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 45 78 70 65 +63 74 65 64 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 41 74 20 6F 66 66 73 65 74 20 5B 25 +64 5D 2C 20 65 63 63 5F 70 75 62 6B 65 79 5F 79 +20 64 61 74 61 20 6D 69 73 6D 61 74 63 68 21 0A +00 00 00 00 41 63 74 75 61 6C 20 20 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 45 78 70 65 +63 74 65 64 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 41 74 20 6F 66 66 73 65 74 20 5B 25 +64 5D 2C 20 65 63 63 5F 73 68 61 72 65 64 6B 65 +79 20 64 61 74 61 20 6D 69 73 6D 61 74 63 68 21 +0A 00 00 00 41 63 74 75 61 6C 20 20 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 45 78 70 65 +63 74 65 64 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 41 74 20 6F 66 66 73 65 74 20 5B 25 +64 5D 2C 20 65 63 63 5F 73 69 67 6E 5F 72 20 64 +61 74 61 20 6D 69 73 6D 61 74 63 68 21 0A 00 00 +41 63 74 75 61 6C 20 20 20 64 61 74 61 3A 20 30 +78 25 78 0A 00 00 00 00 45 78 70 65 63 74 65 64 +20 64 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +41 74 20 6F 66 66 73 65 74 20 5B 25 64 5D 2C 20 +65 63 63 5F 73 69 67 6E 5F 73 20 64 61 74 61 20 +6D 69 73 6D 61 74 63 68 21 0A 00 00 41 63 74 75 +61 6C 20 20 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 45 78 70 65 63 74 65 64 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 41 74 20 6F +66 66 73 65 74 20 5B 25 64 5D 2C 20 65 63 63 5F +76 65 72 69 66 79 5F 72 20 64 61 74 61 20 6D 69 +73 6D 61 74 63 68 21 0A 00 00 00 00 41 63 74 75 +61 6C 20 20 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 45 78 70 65 63 74 65 64 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 41 74 20 6F +66 66 73 65 74 20 5B 25 64 5D 2C 20 65 63 63 5F +73 69 67 6E 5F 72 20 64 61 74 61 20 6D 69 73 6D +61 74 63 68 21 0A 00 00 41 63 74 75 61 6C 20 20 +20 64 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +45 78 70 65 63 74 65 64 20 64 61 74 61 3A 20 30 +78 25 78 0A 00 00 00 00 41 74 20 6F 66 66 73 65 +74 20 5B 25 64 5D 2C 20 65 63 63 5F 73 69 67 6E +5F 73 20 64 61 74 61 20 6D 69 73 6D 61 74 63 68 +21 0A 00 00 41 63 74 75 61 6C 20 20 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 45 78 70 65 +63 74 65 64 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 41 11 22 C4 37 34 02 50 03 27 C4 C5 +06 C6 89 47 63 E0 E7 04 37 67 02 50 13 07 87 E2 +3C 43 74 43 D5 8F 9D E3 73 00 50 10 93 07 40 06 +01 00 FD 17 C2 07 C1 83 E5 FF 3C 43 74 43 D5 8F +E5 D7 83 26 C4 C5 89 47 63 E5 D7 02 B2 40 22 44 +41 01 82 80 37 45 02 50 13 05 85 E2 EF B0 3F CF +37 67 02 50 13 07 87 E2 3C 43 74 43 D5 8F CD DF +C9 BF 22 44 6C 43 B2 40 30 43 21 65 13 05 C5 37 +41 01 6F B0 DF CE 41 11 26 C2 B7 34 02 50 83 A7 +C4 C5 22 C4 06 C6 09 44 63 60 F4 02 B7 07 03 10 +21 47 98 CB 37 07 03 10 5C 4B 85 8B F5 DF B2 40 +22 44 92 44 41 01 82 80 37 45 02 50 13 05 45 E4 +EF B0 FF C8 83 A7 C4 C5 37 07 03 10 A1 46 14 CB +E3 7A F4 FC 37 45 02 50 13 05 85 E5 EF B0 3F C7 +D1 B7 19 CA 0A 06 33 87 C5 00 9C 41 91 05 11 05 +23 2E F5 FE E3 9B E5 FE 82 80 79 71 4E CE B7 39 +02 50 03 A7 C9 C5 26 D2 4A D0 5A C8 5E C6 06 D6 +22 D4 52 CC 56 CA 89 47 AA 8B 2E 8B B2 84 36 89 +63 E3 E7 20 B7 07 03 10 C0 4B 05 88 75 DC 03 CA +0B 00 83 C6 2B 00 63 09 0A 16 93 97 16 00 93 F7 +E7 03 93 E7 17 00 B7 86 03 10 9C C2 89 47 63 E3 +E7 28 B7 07 03 10 23 AC 07 04 23 AE 07 04 23 A0 +07 06 23 A2 07 06 23 A4 07 06 23 A6 07 06 23 A8 +07 06 23 AA 07 06 B7 86 03 10 DC 42 89 8B F5 DF +03 C6 1B 00 85 47 63 19 F6 14 DC 42 93 F7 C7 3F +63 84 07 2C 89 47 63 E6 E7 2C 83 26 0B 00 B7 0A +03 10 89 47 23 AC DA 00 83 26 4B 00 23 AE DA 00 +83 26 8B 00 23 A0 DA 02 83 26 CB 00 23 A2 DA 02 +83 26 0B 01 23 A4 DA 02 83 26 4B 01 23 A6 DA 02 +83 26 8B 01 23 A8 DA 02 83 26 CB 01 23 AA DA 02 +83 26 0B 02 23 AC DA 02 83 26 4B 02 23 AE DA 02 +83 26 8B 02 23 A0 DA 04 83 26 CB 02 23 A2 DA 04 +83 26 0B 03 23 A4 DA 04 83 26 4B 03 23 A6 DA 04 +83 26 8B 03 23 A8 DA 04 83 26 CB 03 23 AA DA 04 +63 ED E7 16 85 47 23 A8 FA 00 03 C7 2B 00 63 07 +07 0E 37 87 03 10 1C C3 37 67 02 50 13 07 87 E2 +34 43 7C 43 D5 8F 91 EF 73 00 50 10 93 07 40 06 +01 00 FD 17 C2 07 C1 83 E5 FF 3C 43 74 43 D5 8F +E5 D7 03 A5 C9 C5 09 44 63 64 A4 08 63 16 0A 0C +B7 46 03 10 26 84 81 45 85 8E 13 06 80 4C 39 A0 +93 95 07 01 C1 81 11 04 63 88 C5 0C B3 87 86 00 +84 43 18 40 93 87 15 00 E3 04 97 FE 63 15 05 14 +05 45 EF B0 DF A8 01 A0 83 A6 4B 00 B4 CF 83 A6 +8B 00 F4 CF 83 A6 CB 00 B4 D3 83 A6 0B 01 F4 D3 +83 A6 4B 01 B4 D7 83 A6 8B 01 F4 D7 83 A6 CB 01 +B4 DB 83 A6 0B 02 F4 DB 89 47 E3 F0 E7 EC 37 45 +02 50 13 05 45 F5 EF B0 9F A6 03 A7 C9 C5 75 B5 +6C 43 30 43 21 65 13 05 C5 37 EF B0 5F A7 63 1D +0A 02 03 A5 C9 C5 E3 75 A4 F6 37 45 02 50 13 05 +45 F7 EF B0 DF A3 03 A5 C9 C5 99 BF B7 87 03 10 +0D 47 98 C3 11 BF 37 45 02 50 13 05 85 E7 EF B0 +1F A2 03 A7 C9 C5 FD B3 83 C7 1B 00 81 CF B2 50 +22 54 92 54 02 59 F2 49 62 4A D2 4A 42 4B B2 4B +45 61 82 80 03 A5 C9 C5 89 47 63 E0 A7 0C B7 16 +03 10 4A 84 81 45 B3 86 26 41 13 06 80 28 39 A0 +93 95 07 01 C1 81 11 04 E3 83 C5 FC B3 87 86 00 +84 43 18 40 93 87 15 00 E3 04 97 FE 83 A7 C9 C5 +C1 EF 05 45 EF B0 BF 99 01 A0 37 45 02 50 13 05 +45 F6 EF B0 DF 9A 85 47 03 A7 C9 C5 23 A8 FA 00 +83 C7 2B 00 91 CF B7 87 03 10 80 C3 89 47 63 FB +E7 0A 37 45 02 50 13 05 85 E2 EF B0 5F 98 AD B5 +0D 44 D5 B7 37 45 02 50 13 05 45 EA EF B0 3F 97 +03 A7 C9 C5 BD B3 21 69 13 09 C9 37 13 05 89 03 +EF B0 FF 97 83 A7 C9 C5 E3 84 07 EA A6 85 13 05 +89 06 EF B0 DF 96 83 A7 C9 C5 E3 8B 07 E8 0C 40 +13 05 09 08 EF B0 BF 95 61 B5 37 45 02 50 13 05 +45 F9 EF B0 DF 92 25 BF 21 69 13 09 C9 37 13 05 +89 09 EF B0 DF 93 83 A7 C9 C5 A1 DF A6 85 13 05 +89 0C EF B0 DF 92 83 A7 C9 C5 A1 D7 0C 40 13 05 +09 0E EF B0 DF 91 35 BF 15 EB 05 45 EF B0 3F 8D +01 A0 37 45 02 50 13 05 85 EC EF B0 5F 8E 03 A7 +C9 C5 9D B5 37 67 02 50 13 07 87 E2 3C 43 74 43 +D5 8F E3 83 07 DC 03 A5 C9 C5 CD B3 37 45 02 50 +13 05 C5 F0 EF B0 BF 8B C9 B7 79 71 4E CE B7 39 +02 50 03 A8 C9 C5 22 D4 56 CA 5A C8 5E C6 62 C4 +06 D6 26 D2 4A D0 52 CC 89 47 AA 8B 2E 8B 32 8C +B6 8A 3A 84 63 E7 07 29 B7 07 03 10 C4 4B 85 88 +F5 DC 03 CA 0B 00 63 0C 0A 06 83 C7 2B 00 B7 86 +03 10 09 47 86 07 93 F7 E7 03 93 E7 17 00 9C C2 +63 60 07 31 B7 07 03 10 23 AC 07 04 23 AE 07 04 +23 A0 07 06 23 A2 07 06 23 A4 07 06 23 A6 07 06 +23 A8 07 06 23 AA 07 06 37 87 03 10 5C 43 89 8B +F5 DF 83 C6 1B 00 85 47 63 9B F6 04 5C 43 93 F7 +C7 3F 63 81 07 30 89 47 63 F3 07 05 37 45 02 50 +13 05 05 FB EF B0 BF 80 03 A8 C9 C5 0D A8 03 A7 +4B 00 B8 CF 03 A7 8B 00 F8 CF 03 A7 CB 00 B8 D3 +03 A7 0B 01 F8 D3 03 A7 4B 01 B8 D7 03 A7 8B 01 +F8 D7 03 A7 CB 01 B8 DB 03 A7 0B 02 F8 DB 03 27 +0B 00 37 09 03 10 89 47 23 2C E9 08 03 27 4B 00 +23 2E E9 08 03 27 8B 00 23 20 E9 0A 03 27 CB 00 +23 22 E9 0A 03 27 0B 01 23 24 E9 0A 03 27 4B 01 +23 26 E9 0A 03 27 8B 01 23 28 E9 0A 03 27 CB 01 +23 2A E9 0A 03 27 0B 02 23 2C E9 0A 03 27 4B 02 +23 2E E9 0A 03 27 8B 02 23 20 E9 0C 03 27 CB 02 +23 22 E9 0C 03 27 0B 03 23 24 E9 0C 03 27 4B 03 +23 26 E9 0C 03 27 8B 03 23 28 E9 0C 03 27 CB 03 +23 2A E9 0C 03 27 0C 00 23 2C E9 06 03 27 4C 00 +23 2E E9 06 03 27 8C 00 23 20 E9 08 03 27 CC 00 +23 22 E9 08 03 27 0C 01 23 24 E9 08 03 27 4C 01 +23 26 E9 08 03 27 8C 01 23 28 E9 08 03 27 CC 01 +23 2A E9 08 03 A7 0A 00 23 2C E9 00 03 A7 4A 00 +23 2E E9 00 03 A7 8A 00 23 20 E9 02 03 A7 CA 00 +23 22 E9 02 03 A7 0A 01 23 24 E9 02 03 A7 4A 01 +23 26 E9 02 03 A7 8A 01 23 28 E9 02 03 A7 CA 01 +23 2A E9 02 03 A7 0A 02 23 2C E9 02 03 A7 4A 02 +23 2E E9 02 03 A7 8A 02 23 20 E9 04 03 A7 CA 02 +23 22 E9 04 03 A7 0A 03 23 24 E9 04 03 A7 4A 03 +23 26 E9 04 03 A7 8A 03 23 28 E9 04 03 A7 CA 03 +23 2A E9 04 63 E9 07 0F 91 47 23 28 F9 00 83 C7 +2B 00 D5 CF B7 87 03 10 05 47 98 C3 37 67 02 50 +13 07 87 E2 34 43 7C 43 D5 8F 91 EF 73 00 50 10 +93 07 40 06 01 00 FD 17 C2 07 C1 83 E5 FF 3C 43 +74 43 D5 8F E5 D7 83 A6 C9 C5 89 47 63 EC D7 04 +63 05 0A 00 83 C7 1B 00 D9 E3 B7 26 03 10 81 45 +81 8E 13 06 50 48 39 A0 93 95 07 01 C1 81 11 04 +63 87 C5 06 B3 87 86 00 84 43 18 40 93 87 15 00 +E3 04 97 FE 83 A7 C9 C5 CD EF 05 45 EF B0 2F DE +01 A0 37 45 02 50 13 05 85 E7 EF B0 4F DF 03 A8 +C9 C5 9D B3 6C 43 30 43 21 65 13 05 C5 37 EF B0 +0F E0 63 13 0A 02 03 A7 C9 C5 89 47 E3 FF E7 F8 +37 45 02 50 13 05 45 06 EF B0 6F DC 79 B7 B7 87 +03 10 0D 47 98 C3 99 B7 83 C7 1B 00 E9 DF B2 50 +22 54 92 54 02 59 F2 49 62 4A D2 4A 42 4B B2 4B +22 4C 45 61 82 80 37 45 02 50 13 05 C5 04 EF B0 +0F D9 91 47 03 A7 C9 C5 23 28 F9 00 83 C7 2B 00 +91 CF B7 87 03 10 84 C3 89 47 63 F3 E7 06 37 45 +02 50 13 05 85 E2 EF B0 8F D6 CD BD 8D 44 D5 B7 +37 45 02 50 13 05 45 EA EF B0 6F D5 03 A8 C9 C5 +D5 B9 21 69 13 09 C9 37 13 05 89 0F EF B0 2F D6 +83 A7 C9 C5 9D DB A6 85 13 05 49 12 EF B0 2F D5 +83 A7 C9 C5 E3 83 07 F2 0C 40 13 05 C9 13 EF B0 +0F D4 21 BF 63 10 08 02 05 45 EF B0 4F CF 01 A0 +37 67 02 50 13 07 87 E2 3C 43 74 43 D5 8F E3 8F +07 E8 7D BD 37 45 02 50 13 05 C5 FF EF B0 2F CF +E1 BF 01 11 4A C8 37 39 02 50 03 28 C9 C5 22 CC +26 CA 4E C6 52 C4 56 C2 06 CE 5A C0 89 47 AA 84 +2E 8A B2 8A B6 89 3A 84 63 E8 07 1D 37 07 03 10 +5C 4B 85 8B F5 DF 89 47 63 E7 07 23 05 67 13 07 +07 32 B7 65 03 10 A6 87 33 86 E4 00 85 8D 94 43 +33 87 F5 00 91 07 14 C3 E3 9B C7 FE 89 47 63 EB +07 1F 83 27 0A 00 B7 04 03 10 09 4B 23 AC F4 08 +83 27 4A 00 23 AE F4 08 83 27 8A 00 23 A0 F4 0A +83 27 CA 00 23 A2 F4 0A 83 27 0A 01 23 A4 F4 0A +83 27 4A 01 23 A6 F4 0A 83 27 8A 01 23 A8 F4 0A +83 27 CA 01 23 AA F4 0A 83 27 0A 02 23 AC F4 0A +83 27 4A 02 23 AE F4 0A 83 27 8A 02 23 A0 F4 0C +83 27 CA 02 23 A2 F4 0C 83 27 0A 03 23 A4 F4 0C +83 27 4A 03 23 A6 F4 0C 83 27 8A 03 23 A8 F4 0C +83 27 CA 03 23 AA F4 0C 83 A7 0A 00 BC DC 83 A7 +4A 00 FC DC 83 A7 8A 00 23 A0 F4 08 83 A7 CA 00 +23 A2 F4 08 83 A7 0A 01 23 A4 F4 08 83 A7 4A 01 +23 A6 F4 08 83 A7 8A 01 23 A8 F4 08 83 A7 CA 01 +23 AA F4 08 83 A7 09 00 9C CC 83 A7 49 00 DC CC +83 A7 89 00 9C D0 83 A7 C9 00 DC D0 83 A7 09 01 +9C D4 83 A7 49 01 DC D4 83 A7 89 01 9C D8 83 A7 +C9 01 DC D8 83 A7 09 02 9C DC 83 A7 49 02 DC DC +83 A7 89 02 BC C0 83 A7 C9 02 FC C0 83 A7 09 03 +BC C4 83 A7 49 03 FC C4 83 A7 89 03 BC C8 83 A7 +C9 03 FC C8 63 65 0B 0B 23 A8 64 01 37 67 02 50 +13 07 87 E2 34 43 7C 43 D5 8F 91 EF 73 00 50 10 +93 07 40 06 01 00 FD 17 C2 07 C1 83 E5 FF 3C 43 +74 43 D5 8F E5 D7 83 27 C9 C5 89 44 63 E7 F4 04 +B7 26 03 10 81 45 81 8E 13 06 50 48 39 A0 93 95 +07 01 C1 81 11 04 63 89 C5 0C B3 87 86 00 84 43 +18 40 93 87 15 00 E3 04 97 FE 83 27 C9 C5 C9 E7 +05 45 EF B0 CF AD 01 A0 37 45 02 50 13 05 85 E5 +EF B0 EF AE 03 28 C9 C5 15 B5 6C 43 30 43 21 65 +13 05 C5 37 EF B0 AF AF 83 27 C9 C5 E3 F2 F4 FA +37 45 02 50 13 05 45 06 EF B0 6F AC 51 BF 37 45 +02 50 13 05 C5 09 EF B0 8F AB 83 27 C9 C5 23 A8 +64 01 63 7D FB 06 37 45 02 50 13 05 85 E2 EF B0 +0F AA 2D BF 37 45 02 50 13 05 05 09 EF B0 2F A9 +03 28 C9 C5 FD BB 37 45 02 50 13 05 05 08 EF B0 +0F A8 03 28 C9 C5 D9 B3 A1 69 93 89 C9 37 13 85 +49 15 EF B0 CF A8 83 27 C9 C5 BD D3 A6 85 13 85 +09 18 EF B0 CF A7 83 27 C9 C5 B9 DB 0C 40 13 85 +89 19 EF B0 CF A6 A9 B7 F2 40 62 44 D2 44 42 49 +B2 49 22 4A 92 4A 02 4B 05 61 82 80 37 67 02 50 +13 07 87 E2 34 43 7C 43 D5 8F E3 89 07 EC CD BD +01 11 22 CC 06 CE 26 CA 4A C8 4E C6 32 88 36 84 +37 07 03 10 5C 4B 85 8B F5 DF 1C 41 23 2C F7 08 +54 41 AE 87 23 2E D7 08 83 28 85 00 85 66 93 86 +06 A2 23 20 17 0B 33 86 D5 00 54 45 B7 15 03 10 +9D 8D 23 22 D7 0A 14 49 23 24 D7 0A 54 49 23 26 +D7 0A 14 4D 23 28 D7 0A 54 4D 23 2A D7 0A 14 51 +23 2C D7 0A 54 51 23 2E D7 0A 14 55 23 20 D7 0C +54 55 23 22 D7 0C 14 59 23 24 D7 0C 54 59 23 26 +D7 0C 14 5D 23 28 D7 0C 54 5D 23 2A D7 0C 94 43 +33 87 F5 00 91 07 14 C3 E3 9B C7 FE 05 67 13 07 +47 21 B7 25 03 10 C2 87 33 06 E8 00 B3 85 05 41 +94 43 33 87 F5 00 91 07 14 C3 E3 9B C7 FE 37 39 +02 50 83 27 C9 C5 89 44 63 E8 F4 12 B7 07 03 10 +0D 47 98 CB 37 67 02 50 13 07 87 E2 34 43 7C 43 +D5 8F 9D E3 73 00 50 10 93 07 40 06 01 00 FD 17 +C2 07 C1 83 E5 FF 3C 43 74 43 D5 8F E5 D7 83 27 +C9 C5 89 44 63 E8 F4 0C B7 07 03 10 83 A4 87 0D +18 40 63 19 97 0A 83 A4 C7 0D 58 40 63 94 E4 14 +83 A4 07 0E 18 44 63 92 E4 14 83 A4 47 0E 58 44 +63 96 E4 14 83 A4 87 0E 18 48 63 9E E4 12 83 A4 +C7 0E 58 48 63 96 E4 12 83 A4 07 0F 18 4C 63 96 +E4 14 83 A4 47 0F 58 4C 63 94 E4 16 83 A4 87 0F +18 50 63 9B E4 14 83 A4 C7 0F 5C 50 63 92 F4 14 +B7 07 03 10 83 A4 07 10 18 54 63 97 E4 12 83 A4 +47 10 58 54 63 97 E4 10 83 A4 87 10 18 58 63 9E +E4 0E 83 A4 C7 10 58 58 63 94 E4 10 83 A4 07 11 +18 5C 63 90 E4 0E 83 A4 47 11 5C 5C BD 45 13 04 +C4 03 63 9A 97 00 F2 40 62 44 D2 44 42 49 B2 49 +05 61 82 80 81 45 83 27 C9 C5 AD E7 05 45 EF B0 +0F 83 01 A0 6C 43 30 43 21 65 13 05 C5 37 EF B0 +0F 86 83 27 C9 C5 E3 F1 F4 F2 37 45 02 50 13 05 +05 0C EF B0 CF 82 09 BF 37 45 02 50 13 05 C5 0A +EF B0 EF 81 83 27 C9 C5 37 07 03 10 8D 46 14 CB +E3 F2 F4 EC 37 45 02 50 13 05 85 E2 EF B0 2F 80 +37 67 02 50 13 07 87 E2 34 43 7C 43 D5 8F E3 8B +07 EA F1 B5 A1 69 93 89 C9 37 13 85 09 1B EF B0 +0F 80 83 27 C9 C5 D9 D3 A6 85 13 85 49 1E EF A0 +1F FF 83 27 C9 C5 BD DB 0C 40 13 85 C9 1F EF A0 +1F FE AD B7 11 04 85 45 B9 BF 21 04 89 45 A1 BF +51 04 95 45 89 BF 41 04 91 45 B1 B7 31 04 8D 45 +99 B7 13 04 84 03 B9 45 3D BF 13 04 04 03 B1 45 +1D BF 13 04 C4 02 AD 45 3D B7 61 04 99 45 25 B7 +13 04 44 03 B5 45 05 B7 13 04 84 02 A9 45 21 BF +13 04 44 02 A5 45 01 BF 13 04 04 02 A1 45 21 B7 +71 04 9D 45 09 B7 79 71 4A D0 37 39 02 50 03 28 +C9 C5 22 D4 52 CC 56 CA 5A C8 5E C6 06 D6 26 D2 +4E CE 89 47 2A 8B 2E 8A B2 8B B6 8A 3A 84 63 EB +07 29 B7 07 03 10 C4 4B 85 88 F5 DC 83 49 0B 00 +63 8C 09 06 83 47 2B 00 B7 86 03 10 09 47 86 07 +93 F7 E7 03 93 E7 17 00 9C C2 63 6D 07 31 B7 07 +03 10 23 AC 07 04 23 AE 07 04 23 A0 07 06 23 A2 +07 06 23 A4 07 06 23 A6 07 06 23 A8 07 06 23 AA +07 06 37 87 03 10 5C 43 89 8B F5 DF 83 46 1B 00 +85 47 63 9B F6 04 5C 43 93 F7 C7 3F 63 8F 07 30 +89 47 63 F3 07 05 37 45 02 50 13 05 05 FB EF A0 +1F EB 03 28 C9 C5 0D A8 03 27 4B 00 B8 CF 03 27 +8B 00 F8 CF 03 27 CB 00 B8 D3 03 27 0B 01 F8 D3 +03 27 4B 01 B8 D7 03 27 8B 01 F8 D7 03 27 CB 01 +B8 DB 03 27 0B 02 F8 DB 83 26 0A 00 B7 07 03 10 +09 47 23 AC D7 10 83 26 4A 00 23 AE D7 10 83 26 +8A 00 23 A0 D7 12 83 26 CA 00 23 A2 D7 12 83 26 +0A 01 23 A4 D7 12 83 26 4A 01 23 A6 D7 12 83 26 +8A 01 23 A8 D7 12 83 26 CA 01 23 AA D7 12 83 26 +0A 02 23 AC D7 12 83 26 4A 02 23 AE D7 12 83 26 +8A 02 23 A0 D7 14 83 26 CA 02 23 A2 D7 14 83 26 +0A 03 23 A4 D7 14 83 26 4A 03 23 A6 D7 14 83 26 +8A 03 23 A8 D7 14 83 26 CA 03 23 AA D7 14 83 A6 +0B 00 B4 DF 83 A6 4B 00 F4 DF 83 A6 8B 00 23 A0 +D7 08 83 A6 CB 00 23 A2 D7 08 83 A6 0B 01 23 A4 +D7 08 83 A6 4B 01 23 A6 D7 08 83 A6 8B 01 23 A8 +D7 08 83 A6 CB 01 23 AA D7 08 63 6A 07 1B 03 A7 +0A 00 37 0A 03 10 89 47 23 2C EA 00 03 A7 4A 00 +23 2E EA 00 03 A7 8A 00 23 20 EA 02 03 A7 CA 00 +23 22 EA 02 03 A7 0A 01 23 24 EA 02 03 A7 4A 01 +23 26 EA 02 03 A7 8A 01 23 28 EA 02 03 A7 CA 01 +23 2A EA 02 03 A7 0A 02 23 2C EA 02 03 A7 4A 02 +23 2E EA 02 03 A7 8A 02 23 20 EA 04 03 A7 CA 02 +23 22 EA 04 03 A7 0A 03 23 24 EA 04 03 A7 4A 03 +23 26 EA 04 03 A7 8A 03 23 28 EA 04 03 A7 CA 03 +23 2A EA 04 63 E9 07 0F 93 07 40 02 23 28 FA 00 +83 47 2B 00 C9 CB B7 87 03 10 05 47 98 C3 37 67 +02 50 13 07 87 E2 3C 43 74 43 D5 8F 91 EF 73 00 +50 10 93 07 40 06 01 00 FD 17 C2 07 C1 83 E5 FF +3C 43 74 43 D5 8F E5 D7 83 26 C9 C5 89 47 63 E1 +D7 06 63 85 09 00 83 47 1B 00 D9 E3 B7 26 03 10 +81 45 81 8E 13 06 50 48 39 A0 93 95 07 01 C1 81 +11 04 63 87 C5 06 B3 87 86 00 84 43 18 40 93 87 +15 00 E3 04 97 FE 83 27 C9 C5 F1 E7 05 45 EF A0 +1F C8 01 A0 37 45 02 50 13 05 85 E7 EF A0 3F C9 +03 28 C9 C5 B9 BB B7 87 03 10 0D 47 98 C3 85 BF +6C 43 30 43 21 65 13 05 C5 37 EF A0 5F C9 63 9E +09 00 03 27 C9 C5 89 47 E3 FA E7 F8 37 45 02 50 +13 05 45 06 EF A0 BF C5 51 B7 83 47 1B 00 F5 D3 +B2 50 22 54 92 54 02 59 F2 49 62 4A D2 4A 42 4B +B2 4B 45 61 82 80 37 45 02 50 13 05 05 0E EF A0 +1F C3 93 07 40 02 03 27 C9 C5 23 28 FA 00 83 47 +2B 00 9D C7 B7 87 03 10 84 C3 89 47 63 FD E7 06 +37 45 02 50 13 05 85 E2 EF A0 7F C0 CD BD 37 45 +02 50 13 05 45 F5 EF A0 9F BF 03 28 C9 C5 81 B5 +8D 44 C9 BF 37 45 02 50 13 05 45 EA EF A0 3F BE +03 28 C9 C5 E9 B9 A1 69 93 89 C9 37 13 85 49 21 +EF A0 FF BE 83 27 C9 C5 E3 82 07 F2 A6 85 13 85 +09 24 EF A0 DF BD 83 27 C9 C5 E3 89 07 F0 0C 40 +13 85 89 25 EF A0 BF BC 11 B7 63 10 08 02 05 45 +EF A0 FF B7 01 A0 37 67 02 50 13 07 87 E2 3C 43 +74 43 D5 8F E3 85 07 E8 6D B5 37 45 02 50 13 05 +C5 FF EF A0 DF B7 E1 BF 01 11 4A C8 37 39 02 50 +03 28 C9 C5 22 CC 26 CA 4E C6 52 C4 56 C2 06 CE +5A C0 89 47 AA 84 2E 8A B2 8A B6 89 3A 84 63 E9 +07 1D 37 07 03 10 5C 4B 85 8B F5 DF 89 47 63 E9 +07 23 05 67 13 07 07 32 B7 65 03 10 A6 87 33 86 +E4 00 85 8D 94 43 33 87 F5 00 91 07 14 C3 E3 9B +C7 FE 89 47 63 ED 07 1F 83 27 0A 00 B7 04 03 10 +09 4B 23 AC F4 10 83 27 4A 00 23 AE F4 10 83 27 +8A 00 23 A0 F4 12 83 27 CA 00 23 A2 F4 12 83 27 +0A 01 23 A4 F4 12 83 27 4A 01 23 A6 F4 12 83 27 +8A 01 23 A8 F4 12 83 27 CA 01 23 AA F4 12 83 27 +0A 02 23 AC F4 12 83 27 4A 02 23 AE F4 12 83 27 +8A 02 23 A0 F4 14 83 27 CA 02 23 A2 F4 14 83 27 +0A 03 23 A4 F4 14 83 27 4A 03 23 A6 F4 14 83 27 +8A 03 23 A8 F4 14 83 27 CA 03 23 AA F4 14 83 A7 +0A 00 BC DC 83 A7 4A 00 FC DC 83 A7 8A 00 23 A0 +F4 08 83 A7 CA 00 23 A2 F4 08 83 A7 0A 01 23 A4 +F4 08 83 A7 4A 01 23 A6 F4 08 83 A7 8A 01 23 A8 +F4 08 83 A7 CA 01 23 AA F4 08 83 A7 09 00 9C CC +83 A7 49 00 DC CC 83 A7 89 00 9C D0 83 A7 C9 00 +DC D0 83 A7 09 01 9C D4 83 A7 49 01 DC D4 83 A7 +89 01 9C D8 83 A7 C9 01 DC D8 83 A7 09 02 9C DC +83 A7 49 02 DC DC 83 A7 89 02 BC C0 83 A7 C9 02 +FC C0 83 A7 09 03 BC C4 83 A7 49 03 FC C4 83 A7 +89 03 BC C8 83 A7 C9 03 FC C8 63 66 0B 0B 93 07 +20 02 9C C8 37 67 02 50 13 07 87 E2 34 43 7C 43 +D5 8F 91 EF 73 00 50 10 93 07 40 06 01 00 FD 17 +C2 07 C1 83 E5 FF 3C 43 74 43 D5 8F E5 D7 83 27 +C9 C5 89 44 63 E7 F4 04 B7 26 03 10 81 45 81 8E +13 06 50 48 39 A0 93 95 07 01 C1 81 11 04 63 8A +C5 0C B3 87 86 00 84 43 18 40 93 87 15 00 E3 04 +97 FE 83 27 C9 C5 D1 E7 05 45 EF A0 5F 96 01 A0 +37 45 02 50 13 05 85 E5 EF A0 7F 97 03 28 C9 C5 +0D B5 6C 43 30 43 21 65 13 05 C5 37 EF A0 3F 98 +83 27 C9 C5 E3 F2 F4 FA 37 45 02 50 13 05 45 06 +EF A0 FF 94 51 BF 37 45 02 50 13 05 05 12 EF A0 +1F 94 83 27 C9 C5 13 07 20 02 98 C8 63 7D FB 06 +37 45 02 50 13 05 85 E2 EF A0 7F 92 25 BF 37 45 +02 50 13 05 C5 10 EF A0 9F 91 03 28 C9 C5 ED BB +37 45 02 50 13 05 05 08 EF A0 7F 90 03 28 C9 C5 +C9 B3 A1 69 93 89 C9 37 13 85 09 27 EF A0 3F 91 +83 27 C9 C5 B5 D3 A6 85 13 85 C9 29 EF A0 3F 90 +83 27 C9 C5 B1 DB 0C 40 13 85 49 2B EF A0 3F 8F +A1 B7 F2 40 62 44 D2 44 42 49 B2 49 22 4A 92 4A +02 4B 05 61 82 80 37 67 02 50 13 07 87 E2 34 43 +7C 43 D5 8F E3 88 07 EC C5 BD 01 11 22 CC 26 CA +4E C6 52 C4 06 CE 4A C8 AA 84 AE 89 32 8A 36 84 +37 07 03 10 5C 4B 85 8B F5 DF 37 39 02 50 03 25 +C9 C5 89 47 63 E7 A7 20 9C 40 37 07 03 10 23 2C +F7 10 D4 40 CE 87 23 2E D7 10 8C 44 85 66 93 86 +06 A2 23 20 B7 12 33 86 D9 00 D4 44 B7 15 03 10 +B3 85 35 41 23 22 D7 12 94 48 23 24 D7 12 D4 48 +23 26 D7 12 94 4C 23 28 D7 12 D4 4C 23 2A D7 12 +94 50 23 2C D7 12 D4 50 23 2E D7 12 94 54 23 20 +D7 14 D4 54 23 22 D7 14 94 58 23 24 D7 14 D4 58 +23 26 D7 14 94 5C 23 28 D7 14 D4 5C 23 2A D7 14 +94 43 33 87 F5 00 91 07 14 C3 E3 9B C7 FE 05 67 +13 07 47 21 B7 25 03 10 D2 87 33 06 EA 00 B3 85 +45 41 94 43 33 87 F5 00 91 07 14 C3 E3 9B C7 FE +89 44 63 EA A4 12 B7 07 03 10 13 07 30 02 98 CB +37 67 02 50 13 07 87 E2 3C 43 74 43 D5 8F 91 EF +73 00 50 10 93 07 40 06 01 00 FD 17 C2 07 C1 83 +E5 FF 3C 43 74 43 D5 8F E5 D7 83 27 C9 C5 89 44 +63 E9 F4 0C B7 07 03 10 83 A4 87 0D 18 40 63 1A +97 0A 83 A4 C7 0D 58 40 63 96 E4 14 83 A4 07 0E +18 44 63 97 E4 16 83 A4 47 0E 58 44 63 9F E4 14 +83 A4 87 0E 18 48 63 97 E4 14 83 A4 C7 0E 58 48 +63 9F E4 12 83 A4 07 0F 18 4C 63 96 E4 14 83 A4 +47 0F 58 4C 63 98 E4 14 83 A4 87 0F 18 50 63 9F +E4 12 83 A4 C7 0F 5C 50 63 9D F4 14 B7 07 03 10 +83 A4 07 10 18 54 63 92 E4 14 83 A4 47 10 58 54 +63 99 E4 12 83 A4 87 10 18 58 63 90 E4 12 83 A4 +C7 10 58 58 63 9B E4 12 83 A4 07 11 18 5C 63 9A +E4 12 83 A4 47 11 5C 5C BD 45 13 04 C4 03 63 9B +97 00 F2 40 62 44 D2 44 42 49 B2 49 22 4A 05 61 +82 80 81 45 83 27 C9 C5 B5 E7 05 45 EF A0 2F EA +01 A0 6C 43 30 43 21 65 13 05 C5 37 EF A0 2F ED +83 27 C9 C5 E3 F0 F4 F2 37 45 02 50 13 05 05 0C +EF A0 EF E9 01 BF 37 45 02 50 13 05 45 14 EF A0 +0F E9 83 27 C9 C5 37 07 03 10 93 06 30 02 14 CB +63 FD F4 04 37 45 02 50 13 05 85 E2 EF A0 2F E7 +45 BD 37 45 02 50 13 05 C5 10 EF A0 4F E6 03 25 +C9 C5 DD B3 A1 69 93 89 C9 37 13 85 C9 2C EF A0 +0F E7 83 27 C9 C5 D1 D3 A6 85 13 85 89 2F EF A0 +0F E6 83 27 C9 C5 B5 DB 0C 40 13 85 09 31 EF A0 +0F E5 A5 B7 11 04 85 45 B1 BF 37 67 02 50 13 07 +87 E2 34 43 7C 43 D5 8F E3 84 07 E6 61 B5 51 04 +95 45 89 B7 41 04 91 45 35 BF 31 04 8D 45 1D BF +21 04 89 45 05 BF 61 04 99 45 2D B7 13 04 04 02 +A1 45 0D B7 71 04 9D 45 31 BF 13 04 04 03 B1 45 +11 BF 13 04 C4 02 AD 45 31 B7 13 04 84 02 A9 45 +11 B7 13 04 44 02 A5 45 F5 BD 13 04 44 03 B5 45 +D5 BD 13 04 84 03 B9 45 F5 B5 B7 37 02 50 03 A7 +C7 C5 41 11 22 C4 06 C6 89 47 2A 84 63 E9 E7 02 +37 07 03 10 5C 4B 85 8B F5 DF 13 05 B0 09 EF A0 +0F D7 83 47 24 00 B2 40 22 44 86 07 93 F7 E7 03 +93 E7 17 00 37 87 03 10 1C C3 41 01 82 80 37 45 +02 50 13 05 85 E5 EF A0 8F D6 D9 B7 52 65 63 65 +69 76 65 64 20 4D 4C 44 53 41 20 6E 6F 74 69 66 +2F 20 65 72 72 20 69 6E 74 72 20 77 69 74 68 20 +73 74 61 74 75 73 20 3D 20 25 64 2F 20 25 64 0A +00 00 00 00 41 74 20 6F 66 66 73 65 74 20 5B 25 +64 5D 2C 20 6D 6C 64 73 61 5F 70 72 69 76 6B 65 +79 20 64 61 74 61 20 6D 69 73 6D 61 74 63 68 21 +0A 00 00 00 41 63 74 75 61 6C 20 20 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 45 78 70 65 +63 74 65 64 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 41 74 20 6F 66 66 73 65 74 20 5B 25 +64 5D 2C 20 6D 6C 64 73 61 5F 70 75 62 6B 65 79 +20 64 61 74 61 20 6D 69 73 6D 61 74 63 68 21 0A +00 00 00 00 41 63 74 75 61 6C 20 20 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 45 78 70 65 +63 74 65 64 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 41 74 20 6F 66 66 73 65 74 20 5B 25 +64 5D 2C 20 6D 6C 64 73 61 5F 73 69 67 6E 20 64 +61 74 61 20 6D 69 73 6D 61 74 63 68 21 0A 00 00 +41 63 74 75 61 6C 20 20 20 64 61 74 61 3A 20 30 +78 25 78 0A 00 00 00 00 45 78 70 65 63 74 65 64 +20 64 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +41 74 20 6F 66 66 73 65 74 20 5B 25 64 5D 2C 20 +6D 6C 64 73 61 5F 73 69 67 6E 20 64 61 74 61 20 +6D 69 73 6D 61 74 63 68 21 0A 00 00 41 63 74 75 +61 6C 20 20 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 45 78 70 65 63 74 65 64 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 41 74 20 6F +66 66 73 65 74 20 5B 25 64 5D 2C 20 6D 6C 64 73 +61 5F 76 65 72 69 66 79 5F 72 65 73 20 64 61 74 +61 20 6D 69 73 6D 61 74 63 68 21 0A 00 00 00 00 +41 63 74 75 61 6C 20 20 20 64 61 74 61 3A 20 30 +78 25 78 0A 00 00 00 00 45 78 70 65 63 74 65 64 +20 64 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +41 74 20 6F 66 66 73 65 74 20 5B 25 64 5D 2C 20 +6D 6C 64 73 61 5F 73 69 67 6E 20 64 61 74 61 20 +6D 69 73 6D 61 74 63 68 21 0A 00 00 41 63 74 75 +61 6C 20 20 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 45 78 70 65 63 74 65 64 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 41 74 20 6F +66 66 73 65 74 20 5B 25 64 5D 2C 20 6D 6C 64 73 +61 5F 73 69 67 6E 20 64 61 74 61 20 6D 69 73 6D +61 74 63 68 21 0A 00 00 41 63 74 75 61 6C 20 20 +20 64 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +45 78 70 65 63 74 65 64 20 64 61 74 61 3A 20 30 +78 25 78 0A 00 00 00 00 41 74 20 6F 66 66 73 65 +74 20 5B 25 64 5D 2C 20 61 63 74 75 61 6C 5F 64 +61 74 61 20 64 61 74 61 20 6D 69 73 6D 61 74 63 +68 21 0A 00 41 63 74 75 61 6C 20 20 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 45 78 70 65 +63 74 65 64 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 41 11 22 C4 37 34 02 50 03 27 C4 C5 +06 C6 89 47 63 E0 E7 04 37 67 02 50 13 07 87 E2 +3C 43 74 43 D5 8F 9D E3 73 00 50 10 93 07 40 06 +01 00 FD 17 C2 07 C1 83 E5 FF 3C 43 74 43 D5 8F +E5 D7 83 26 C4 C5 89 47 63 E5 D7 02 B2 40 22 44 +41 01 82 80 37 45 02 50 13 05 85 16 EF A0 2F 9E +37 67 02 50 13 07 87 E2 3C 43 74 43 D5 8F CD DF +C9 BF 22 44 6C 43 B2 40 30 43 2D 65 13 05 45 E5 +41 01 6F A0 CF 9D 41 11 26 C2 B7 34 02 50 83 A7 +C4 C5 22 C4 06 C6 09 44 63 60 F4 02 B7 97 03 10 +21 47 98 CB 37 97 03 10 5C 4B 85 8B F5 DF B2 40 +22 44 92 44 41 01 82 80 37 45 02 50 13 05 85 18 +EF A0 EF 97 83 A7 C4 C5 37 97 03 10 A1 46 14 CB +E3 7A F4 FC 37 45 02 50 13 05 45 1A EF A0 2F 96 +D1 B7 19 CA 0A 06 33 87 C5 00 9C 41 91 05 11 05 +23 2E F5 FE E3 9B E5 FE 82 80 79 71 4E CE B7 39 +02 50 03 A7 C9 C5 22 D4 52 CC 5A C8 5E C6 06 D6 +26 D2 4A D0 56 CA 62 C4 89 47 2A 8B AE 8B 32 84 +36 8A 63 E5 E7 22 37 99 03 10 83 24 49 01 85 88 +ED DC 83 4A 0B 00 83 47 2B 00 63 88 0A 16 86 07 +93 F7 E7 03 93 E7 17 00 B7 C6 03 10 9C C2 09 4C +63 61 EC 2A 23 2C 09 00 23 2E 09 00 23 20 09 02 +23 22 09 02 23 24 09 02 23 26 09 02 23 28 09 02 +23 2A 09 02 B7 97 03 10 23 AC 07 02 23 AE 07 02 +23 A0 07 04 23 A2 07 04 23 A4 07 04 23 A6 07 04 +23 A8 07 04 23 AA 07 04 B7 C6 03 10 DC 42 89 8B +F5 DF 03 46 1B 00 85 47 63 11 F6 18 DC 42 93 F7 +C7 3F 63 84 07 2E 89 47 63 E6 E7 2E 03 A6 0B 00 +B7 07 03 10 89 46 90 CF 03 A6 4B 00 D0 CF 03 A6 +8B 00 90 D3 03 A6 CB 00 D0 D3 03 A6 0B 01 90 D7 +03 A6 4B 01 D0 D7 03 A6 8B 01 90 DB 03 A6 CB 01 +D0 DB 03 A6 0B 02 90 DF 03 A6 4B 02 D0 DF 03 A6 +8B 02 B0 C3 03 A6 CB 02 F0 C3 03 A6 0B 03 B0 C7 +03 A6 4B 03 F0 C7 03 A6 8B 03 B0 CB 03 A6 CB 03 +F0 CB 63 EE E6 12 37 97 03 10 85 47 1C CB 03 47 +2B 00 63 08 07 10 37 C7 03 10 1C C3 37 67 02 50 +13 07 87 E2 34 43 7C 43 D5 8F 91 EF 73 00 50 10 +93 07 40 06 01 00 FD 17 C2 07 C1 83 E5 FF 3C 43 +74 43 D5 8F E5 D7 83 A7 C9 C5 89 44 63 E5 F4 12 +B7 B6 03 10 81 45 81 8E 13 06 80 18 39 A0 93 95 +07 01 C1 81 11 04 63 89 C5 1A B3 87 86 00 84 43 +18 40 93 87 15 00 E3 04 97 FE 83 A7 C9 C5 63 9E +07 10 05 45 EF 90 BF F7 01 A0 83 27 4B 00 23 2C +F9 00 83 27 8B 00 23 2E F9 00 83 27 CB 00 23 20 +F9 02 83 27 0B 01 23 22 F9 02 83 27 4B 01 23 24 +F9 02 83 27 8B 01 23 26 F9 02 83 27 CB 01 23 28 +F9 02 83 27 0B 02 23 2A F9 02 83 27 4B 02 23 2C +F9 02 83 27 8B 02 23 2E F9 02 83 27 CB 02 23 20 +F9 04 83 27 0B 03 23 22 F9 04 83 27 4B 03 23 24 +F9 04 83 27 8B 03 23 26 F9 04 83 27 CB 03 23 28 +F9 04 83 27 0B 04 23 2A F9 04 89 47 E3 F8 E7 E8 +37 45 02 50 13 05 85 2C EF 90 7F F0 03 A7 C9 C5 +B5 BD B7 C7 03 10 0D 47 98 C3 CD BD 37 45 02 50 +13 05 05 1C EF 90 BF EE 03 A7 C9 C5 E9 B3 37 45 +02 50 13 05 85 2E EF 90 9F ED B7 97 03 10 85 46 +03 A7 C9 C5 94 CB 83 47 2B 00 B5 CB B7 C7 03 10 +84 C3 89 47 63 F9 E7 12 37 45 02 50 13 05 85 16 +EF 90 FF EA 65 B5 6C 43 30 43 2D 65 13 05 45 E5 +EF 90 FF EB 83 A7 C9 C5 E3 F4 F4 EC 37 45 02 50 +13 05 85 30 EF 90 BF E8 65 BD 2D 69 13 09 49 E5 +13 05 89 03 EF 90 BF E9 83 A7 C9 C5 E3 8B 07 EC +A6 85 13 05 C9 06 EF 90 9F E8 83 A7 C9 C5 E3 82 +07 EC 0C 40 13 05 49 08 EF 90 7F E7 5D BD 8D 44 +71 B7 37 45 02 50 13 05 45 1E EF 90 5F E4 03 A7 +C9 C5 23 2C 09 00 23 2E 09 00 23 20 09 02 23 22 +09 02 23 24 09 02 23 26 09 02 23 28 09 02 23 2A +09 02 E3 79 EC D4 37 45 02 50 13 05 05 21 EF 90 +1F E1 03 A7 C9 C5 3D BB 63 95 0A 04 03 A7 C9 C5 +89 47 63 E4 E7 0C B7 A7 03 10 81 45 B3 87 47 41 +93 06 80 31 39 A0 93 15 07 01 C1 81 11 0A 63 82 +D5 02 33 87 47 01 04 43 03 26 0A 00 13 87 15 00 +E3 03 96 FE 83 A7 C9 C5 A5 E3 05 45 EF 90 3F DA +01 A0 B2 50 22 54 92 54 02 59 F2 49 62 4A D2 4A +42 4B B2 4B 22 4C 45 61 82 80 05 EB 05 45 EF 90 +1F D8 01 A0 37 45 02 50 13 05 C5 23 EF 90 3F D9 +03 A7 C9 C5 9D BD 37 67 02 50 13 07 87 E2 34 43 +7C 43 D5 8F E3 84 07 D8 65 B3 37 45 02 50 13 05 +05 28 EF 90 DF D6 D9 B7 2D 64 13 04 44 E5 13 05 +C4 09 EF 90 DF D7 83 A7 C9 C5 C1 DB A6 85 13 05 +04 0D EF 90 DF D6 83 A7 C9 C5 C1 D3 83 25 0A 00 +13 05 84 0E EF 90 BF D5 8D BF 37 45 02 50 13 05 +C5 32 EF 90 DF D2 05 BF 79 71 4A D0 37 39 02 50 +03 27 C9 C5 22 D4 52 CC 5A C8 5E C6 06 D6 26 D2 +4E CE 56 CA 62 C4 89 47 2A 8B AE 8B 32 84 36 8A +63 E1 E7 30 B7 9A 03 10 83 A4 4A 01 85 88 ED DC +83 49 0B 00 63 8B 09 24 83 47 2B 00 B7 C6 03 10 +09 4C 86 07 93 F7 E7 03 93 E7 17 00 9C C2 63 64 +EC 38 23 AC 0A 00 23 AE 0A 00 23 A0 0A 02 23 A2 +0A 02 23 A4 0A 02 23 A6 0A 02 23 A8 0A 02 23 AA +0A 02 B7 97 03 10 23 AC 07 02 23 AE 07 02 23 A0 +07 04 23 A2 07 04 23 A4 07 04 23 A6 07 04 23 A8 +07 04 23 AA 07 04 B7 C6 03 10 DC 42 89 8B F5 DF +03 46 1B 00 85 47 63 0E F6 3A 89 47 63 FA E7 00 +37 45 02 50 13 05 05 35 EF 90 7F C6 03 27 C9 C5 +B7 97 03 10 83 AA 87 01 63 96 0A 3E 94 4F 83 AA +C7 01 63 94 0A 46 D4 4F 83 AA 07 02 63 91 0A 46 +94 53 83 AA 47 02 63 9E 0A 44 D4 53 83 AA 87 02 +63 9B 0A 44 94 57 83 AA C7 02 63 9C 0A 42 D4 57 +83 AA 07 03 63 99 0A 42 94 5B 83 AA 47 03 9D 45 +63 93 0A 3A DC 5B 89 47 63 E2 E7 30 B7 97 03 10 +83 AA 87 03 63 92 0A 38 94 5F 83 AA C7 03 63 9E +0A 40 D4 5F 83 AA 07 04 63 9B 0A 40 B4 43 83 AA +47 04 63 98 0A 40 F4 43 83 AA 87 04 63 95 0A 40 +B4 47 83 AA C7 04 63 92 0A 40 F4 47 83 AA 07 05 +63 90 0A 3C B4 4B 83 AA 47 05 9D 45 63 9F 0A 32 +FC 4B 89 47 63 EE E7 18 03 A6 0B 00 B7 07 03 10 +89 46 90 CF 03 A6 4B 00 D0 CF 03 A6 8B 00 90 D3 +03 A6 CB 00 D0 D3 03 A6 0B 01 90 D7 03 A6 4B 01 +D0 D7 03 A6 8B 01 90 DB 03 A6 CB 01 D0 DB 03 A6 +0B 02 90 DF 03 A6 4B 02 D0 DF 03 A6 8B 02 B0 C3 +03 A6 CB 02 F0 C3 03 A6 0B 03 B0 C7 03 A6 4B 03 +F0 C7 03 A6 8B 03 B0 CB 03 A6 CB 03 F0 CB 63 EB +E6 14 37 97 03 10 85 47 1C CB 03 47 2B 00 63 0B +07 1A 37 C7 03 10 1C C3 37 67 02 50 13 07 87 E2 +34 43 7C 43 D5 8F 91 EF 73 00 50 10 93 07 40 06 +01 00 FD 17 C2 07 C1 83 E5 FF 3C 43 74 43 D5 8F +E5 D7 03 25 C9 C5 89 44 63 E3 A4 18 B7 B7 03 10 +B7 55 FC EF 13 86 07 62 94 43 33 87 B7 00 22 97 +14 C3 91 07 E3 9A C7 FE 89 47 63 91 09 12 63 EA +A7 22 37 B6 03 10 B7 A7 03 10 B7 65 FC EF 13 06 +06 C6 94 43 33 87 B7 00 52 97 14 C3 91 07 E3 9A +C7 FE B2 50 22 54 92 54 02 59 F2 49 62 4A D2 4A +42 4B B2 4B 22 4C 45 61 82 80 83 27 4B 00 23 AC +FA 00 83 27 8B 00 23 AE FA 00 83 27 CB 00 23 A0 +FA 02 83 27 0B 01 23 A2 FA 02 83 27 4B 01 23 A4 +FA 02 83 27 8B 01 23 A6 FA 02 83 27 CB 01 23 A8 +FA 02 83 27 0B 02 23 AA FA 02 83 27 4B 02 23 AC +FA 02 83 27 8B 02 23 AE FA 02 83 27 CB 02 23 A0 +FA 04 83 27 0B 03 23 A2 FA 04 83 27 4B 03 23 A4 +FA 04 83 27 8B 03 23 A6 FA 04 83 27 CB 03 23 A8 +FA 04 83 27 0B 04 23 AA FA 04 89 47 E3 F6 E7 E6 +37 45 02 50 13 05 85 2C EF 90 7F A0 03 27 C9 C5 +A1 BD 37 45 02 50 13 05 05 1C EF 90 5F 9F 03 27 +C9 C5 CD B9 37 45 02 50 13 05 85 2E EF 90 3F 9E +B7 97 03 10 85 46 03 27 C9 C5 94 CB 83 47 2B 00 +F9 CF B7 C7 03 10 84 C3 89 47 63 F2 E7 20 37 45 +02 50 13 05 85 16 EF 90 9F 9B 79 B5 63 E7 A7 12 +B7 A7 03 10 81 45 13 06 80 31 01 A8 93 15 07 01 +9C 43 C1 81 E3 87 C5 EE B6 87 80 43 13 87 15 00 +93 86 47 00 65 D4 83 27 C9 C5 C1 EF 05 45 EF 90 +1F 96 01 A0 B7 C7 03 10 0D 47 98 C3 B1 B5 6C 43 +30 43 2D 65 13 05 45 E5 EF 90 7F 98 03 25 C9 C5 +E3 F6 A4 E6 37 45 02 50 13 05 85 3A EF 90 3F 95 +03 25 C9 C5 A1 BD 37 45 02 50 13 05 45 1E EF 90 +1F 94 03 27 C9 C5 23 AC 0A 00 23 AE 0A 00 23 A0 +0A 02 23 A2 0A 02 23 A4 0A 02 23 A6 0A 02 23 A8 +0A 02 23 AA 0A 02 E3 76 EC C6 37 45 02 50 13 05 +05 21 EF 90 DF 90 03 27 C9 C5 A1 B9 37 45 02 50 +13 05 C5 37 EF 90 BF 8F 03 27 C9 C5 C5 B9 8D 44 +0D B7 AD 64 93 84 44 E5 13 85 04 1C EF 90 3F 90 +83 27 C9 C5 A1 DF A2 85 13 85 C4 1E EF 90 3F 8F +83 27 C9 C5 A1 D7 81 45 13 85 44 20 EF 90 3F 8E +35 BF DC 42 93 F7 C7 3F 85 C7 89 47 E3 FA E7 C4 +37 45 02 50 13 05 C5 23 EF 90 7F 8A 03 27 C9 C5 +2D B1 37 45 02 50 13 05 85 3C EF 90 5F 89 D1 B3 +51 EB 05 45 EF 90 BF 86 01 A0 37 45 02 50 13 05 +85 3E EF 90 DF 87 E9 B5 81 45 19 EB 05 45 EF 90 +1F 85 01 A0 81 45 0D EF 05 45 EF 90 5F 84 01 A0 +2D 64 13 04 44 E5 13 05 04 16 EF 90 5F 87 83 27 +C9 C5 E9 DF D6 85 13 05 04 19 EF 90 5F 86 83 27 +C9 C5 E9 D7 81 45 13 05 84 1A EF 90 5F 85 7D BF +2D 64 13 04 44 E5 13 05 04 10 EF 90 5F 84 83 27 +C9 C5 DD DB D6 85 13 05 04 13 EF 90 5F 83 83 27 +C9 C5 DD D3 81 45 13 05 84 14 EF 90 5F 82 69 BF +99 45 61 B7 37 45 02 50 13 05 05 28 EF 90 2F FF +8D B7 95 45 49 B7 99 45 BD BF 85 45 AD BF 89 45 +9D BF 8D 45 8D BF 91 45 BD B7 85 45 B9 BF 89 45 +A9 BF 8D 45 99 BF 91 45 89 BF 95 45 B9 B7 37 67 +02 50 13 07 87 E2 3C 43 74 43 D5 8F E3 8E 07 C8 +85 B5 79 71 4A D0 37 39 02 50 03 28 C9 C5 22 D4 +4E CE 52 CC 5A C8 5E C6 06 D6 26 D2 56 CA 62 C4 +89 47 83 4A 07 00 3A 8A 2A 8B AE 89 B2 8B 36 84 +63 EE 07 27 B7 97 03 10 C4 4B 85 88 F5 DC 89 47 +63 E4 07 29 B7 B5 03 10 DA 87 13 06 0B 62 B3 85 +65 41 94 43 33 87 F5 00 91 07 14 C3 E3 9B C7 FE +03 CB 09 00 63 09 0B 10 83 C7 29 00 37 C7 03 10 +09 4C 86 07 93 F7 E7 03 93 E7 17 00 1C C7 63 66 +0C 2F B7 97 03 10 23 A0 07 08 23 A2 07 08 23 A4 +07 08 23 A6 07 08 23 A8 07 08 23 AA 07 08 23 AC +07 08 23 AE 07 08 B7 77 03 10 23 A0 07 2A 23 A2 +07 2A 23 A4 07 2A 23 A6 07 2A 23 A8 07 2A 23 AA +07 2A 23 AC 07 2A 23 AE 07 2A 23 A0 07 2C 37 C7 +03 10 5C 47 89 8B F5 DF 83 C6 19 00 85 47 63 8D +F6 2C 89 47 63 FA 07 01 37 45 02 50 13 05 05 54 +EF 90 EF EB 03 28 C9 C5 B7 97 03 10 03 AC 07 08 +63 13 0C 30 03 A7 07 08 03 AC 47 08 63 14 0C 56 +03 A7 47 08 03 AC 87 08 63 10 0C 56 03 A7 87 08 +03 AC C7 08 63 1C 0C 54 03 A7 C7 08 03 AC 07 09 +63 11 0C 4A 03 A7 07 09 03 AC 47 09 63 1D 0C 48 +03 A7 47 09 03 AC 87 09 63 19 0C 48 03 A7 87 09 +03 AC C7 09 9D 45 63 19 0C 2A 83 A7 C7 09 89 47 +63 F0 07 07 37 45 02 50 13 05 C5 56 EF 90 2F E4 +03 28 C9 C5 B1 A0 03 A7 49 00 B7 97 03 10 23 A0 +E7 08 03 A7 89 00 23 A2 E7 08 03 A7 C9 00 23 A4 +E7 08 03 A7 09 01 23 A6 E7 08 03 A7 49 01 23 A8 +E7 08 03 A7 89 01 23 AA E7 08 03 A7 C9 01 23 AC +E7 08 03 A7 09 02 23 AE E7 08 89 47 E3 E4 07 FB +03 A7 0B 00 B7 07 03 10 09 4C 98 CF 03 A7 4B 00 +D8 CF 03 A7 8B 00 98 D3 03 A7 CB 00 D8 D3 03 A7 +0B 01 98 D7 03 A7 4B 01 D8 D7 03 A7 8B 01 98 DB +03 A7 CB 01 D8 DB 03 A7 0B 02 98 DF 03 A7 4B 02 +D8 DF 03 A7 8B 02 B8 C3 03 A7 CB 02 F8 C3 03 A7 +0B 03 B8 C7 03 A7 4B 03 F8 C7 03 A7 8B 03 B8 CB +03 A7 CB 03 F8 CB 63 6A 0C 0B B7 97 03 10 23 A8 +87 01 83 C7 29 00 C1 C7 B7 C7 03 10 05 47 98 C7 +37 67 02 50 13 07 87 E2 34 43 7C 43 D5 8F 91 EF +73 00 50 10 93 07 40 06 01 00 FD 17 C2 07 C1 83 +E5 FF 3C 43 74 43 D5 8F E5 D7 03 25 C9 C5 89 44 +63 E1 A4 0A B7 C6 03 10 93 86 06 80 81 45 81 8E +13 06 80 18 39 A0 93 95 07 01 C1 81 11 04 63 85 +C5 14 B3 87 86 00 84 43 18 40 93 87 15 00 E3 04 +97 FE 41 ED 05 45 EF 90 8F CE 01 A0 37 45 02 50 +13 05 05 41 EF 90 AF CF 03 28 C9 C5 A5 BB B7 C7 +03 10 0D 47 98 C7 AD BF 37 45 02 50 13 05 45 43 +EF 90 EF CD 03 28 C9 C5 B5 B3 37 45 02 50 13 05 +C5 58 EF 90 CF CC B7 97 03 10 03 27 C9 C5 23 A8 +87 01 83 C7 29 00 DD CF B7 C7 03 10 84 C7 89 47 +63 FF E7 2C 37 45 02 50 13 05 85 16 EF 90 2F CA +05 BF 6C 43 30 43 2D 65 13 05 45 E5 EF 90 2F CB +03 25 C9 C5 E3 F8 A4 F4 37 45 02 50 13 05 C5 5A +EF 90 EF C7 03 25 C9 C5 35 BF AD 69 93 89 49 E5 +13 85 89 27 EF 90 AF C8 83 27 C9 C5 A1 DF A6 85 +13 85 C9 2A EF 90 AF C7 83 27 C9 C5 A1 D7 0C 40 +13 85 49 2C EF 90 AF C6 35 BF 37 45 02 50 13 05 +85 45 EF 90 CF C3 B7 97 03 10 03 28 C9 C5 23 A0 +07 08 23 A2 07 08 23 A4 07 08 23 A6 07 08 23 A8 +07 08 23 AA 07 08 23 AC 07 08 23 AE 07 08 E3 74 +0C D1 37 45 02 50 13 05 C5 47 EF 90 4F C0 03 28 +C9 C5 D5 B9 8D 44 89 B7 5C 47 93 F7 C7 3F B9 CB +89 47 E3 FB 07 D3 37 45 02 50 13 05 85 4B EF 90 +0F BE 03 28 C9 C5 31 B3 63 84 0A 04 B7 C7 03 10 +D8 4B 09 8B 75 DF DC 4B 83 46 1A 00 05 47 93 F7 +C7 3F 63 89 E6 22 63 85 07 20 63 1C 05 1E 05 45 +EF 90 EF B8 01 A0 81 45 63 13 08 08 05 45 EF 90 +0F B8 01 A0 63 15 08 0A 05 45 EF 90 4F B7 01 A0 +89 47 63 15 0B 0A 63 EC A7 12 B7 97 03 10 A4 4F +03 24 4A 00 63 13 94 12 E4 4F 03 24 8A 00 63 1C +94 10 A4 53 03 24 CA 00 63 95 84 10 E4 53 03 24 +0A 01 63 1E 94 0E A4 57 03 24 4A 01 63 97 84 0E +E4 57 03 24 8A 01 63 90 84 0E A4 5B 03 24 CA 01 +63 99 84 0C E4 5B 03 24 0A 02 9D 45 63 0F 94 06 +83 27 C9 C5 D9 E7 05 45 EF 90 6F B0 01 A0 2D 64 +13 04 44 E5 13 05 C4 21 EF 90 6F B3 83 27 C9 C5 +B5 D7 E2 85 13 05 84 24 EF 90 6F B2 83 27 C9 C5 +B1 DF 81 45 13 05 04 26 EF 90 6F B1 81 BF 37 45 +02 50 13 05 85 4F EF 90 8F AE B9 B7 63 EC A7 0E +B7 97 03 10 A0 4F 59 E8 E0 4F 63 13 04 0E A0 53 +63 1E 04 0C E0 53 69 E8 A0 57 69 E4 E0 57 69 E0 +A0 5B 4D EC E0 5B 9D 45 3D E8 B2 50 22 54 92 54 +02 59 F2 49 62 4A D2 4A 42 4B B2 4B 22 4C 45 61 +82 80 AD 69 93 89 49 E5 13 85 C9 2D EF 90 2F AB +83 27 C9 C5 AD D3 A6 85 13 85 09 31 EF 90 2F AA +83 27 C9 C5 A9 DB A2 85 13 85 89 32 EF 90 2F A9 +99 B7 99 45 35 BF 95 45 25 BF 91 45 15 BF 8D 45 +05 BF 89 45 35 B7 85 45 25 B7 81 45 15 B7 37 45 +02 50 13 05 C5 6F EF 90 8F A4 C1 B5 81 45 83 27 +C9 C5 89 E7 05 45 EF 90 8F A1 01 A0 AD 64 93 84 +44 E5 13 85 04 34 EF 90 8F A4 83 27 C9 C5 FD D3 +A2 85 13 85 44 37 EF 90 8F A3 83 27 C9 C5 F9 DB +81 45 13 85 C4 38 EF 90 8F A2 E9 B7 99 45 C1 B7 +95 45 75 BF 91 45 65 BF 8D 45 55 BF 89 45 45 BF +85 45 75 B7 37 45 02 50 13 05 C5 71 EF 90 2F 9E +01 B7 91 45 15 BD 95 45 05 BD 99 45 35 B5 37 67 +02 50 13 07 87 E2 34 43 7C 43 D5 8F E3 82 07 C6 +91 B3 37 45 02 50 13 05 45 66 EF 90 4F 9B 01 B5 +89 47 63 E6 A7 04 03 D7 09 00 85 47 E3 17 F7 EE +83 47 2A 00 37 07 03 30 A2 07 93 E7 37 0B 23 26 +F7 0C E1 BD 85 CF 89 47 E3 F9 A7 EC 22 54 B2 50 +92 54 02 59 F2 49 62 4A D2 4A 42 4B B2 4B 22 4C +37 45 02 50 13 05 C5 5C 45 61 6F 90 4F 96 37 45 +02 50 13 05 05 6B EF 90 8F 95 75 B7 09 E5 05 45 +EF 90 EF 92 01 A0 37 45 02 50 13 05 45 61 EF 90 +0F 94 F5 B7 85 45 49 BB 89 45 79 B3 8D 45 69 B3 +79 71 22 D4 37 34 02 50 03 28 C4 C5 26 D2 4A D0 +52 CC 56 CA 5E C6 66 C2 3A 8A 06 D6 4E CE 5A C8 +62 C4 6A C0 09 47 03 4B 0A 00 83 49 2A 00 AA 8A +AE 84 B2 8C B6 8B 3E 89 63 63 07 2F B7 97 03 10 +03 AC 47 01 13 7C 1C 00 E3 0C 0C FE 89 47 63 E4 +07 35 D6 87 37 B6 03 10 93 8A 0A 62 1D 8E 94 43 +33 07 F6 00 91 07 14 C3 E3 9B 57 FF 83 CA 04 00 +63 88 0A 10 83 C7 24 00 37 C7 03 10 09 4D 86 07 +93 F7 E7 03 93 E7 17 00 1C C7 63 60 0D 39 B7 97 +03 10 23 A0 07 08 23 A2 07 08 23 A4 07 08 23 A6 +07 08 23 A8 07 08 23 AA 07 08 23 AC 07 08 23 AE +07 08 B7 77 03 10 23 A0 07 2A 23 A2 07 2A 23 A4 +07 2A 23 A6 07 2A 23 A8 07 2A 23 AA 07 2A 23 AC +07 2A 23 AE 07 2A 23 A0 07 2C 37 C7 03 10 5C 47 +89 8B F5 DF 83 C6 14 00 85 47 63 88 F6 38 89 47 +63 FA 07 01 37 45 02 50 13 05 05 54 EF 90 2F 83 +03 28 C4 C5 B7 97 03 10 03 AD 07 08 63 17 0D 38 +03 A7 07 08 03 AD 47 08 63 11 0D 38 03 A7 47 08 +03 AD 87 08 63 1B 0D 36 03 A7 87 08 03 AD C7 08 +63 15 0D 36 03 A7 C7 08 03 AD 07 09 63 1F 0D 34 +03 A7 07 09 03 AD 47 09 63 19 0D 34 03 A7 47 09 +03 AD 87 09 63 13 0D 34 03 A7 87 09 03 AD C7 09 +63 1D 0D 32 83 A7 C7 09 89 47 63 F8 07 05 37 45 +02 50 13 05 C5 56 EF 80 9F FB 03 28 C4 C5 35 A8 +D8 40 B7 97 03 10 23 A0 E7 08 98 44 23 A2 E7 08 +D8 44 23 A4 E7 08 98 48 23 A6 E7 08 D8 48 23 A8 +E7 08 98 4C 23 AA E7 08 D8 4C 23 AC E7 08 98 50 +23 AE E7 08 89 47 E3 EC 07 FB 03 A7 0C 00 B7 07 +03 10 98 CF 03 A7 4C 00 D8 CF 03 A7 8C 00 98 D3 +03 A7 CC 00 D8 D3 03 A7 0C 01 98 D7 03 A7 4C 01 +D8 D7 03 A7 8C 01 98 DB 03 A7 CC 01 D8 DB 03 A7 +0C 02 98 DF 03 A7 4C 02 D8 DF 03 A7 8C 02 B8 C3 +03 A7 CC 02 F8 C3 03 A7 0C 03 B8 C7 03 A7 4C 03 +F8 C7 03 A7 8C 03 B8 CB 03 A7 CC 03 F8 CB 63 14 +0B 0A 89 4C 63 EF 0C 0B B7 97 03 10 23 A8 97 01 +83 C7 24 00 63 9E 07 0E B7 C7 03 10 0D 47 98 C7 +37 67 02 50 13 07 87 E2 34 43 7C 43 D5 8F 91 EF +73 00 50 10 93 07 40 06 01 00 FD 17 C2 07 C1 83 +E5 FF 3C 43 74 43 D5 8F E5 D7 03 25 C4 C5 09 4C +63 6C AC 12 37 C6 03 10 B7 55 FC EF 93 07 06 80 +93 85 05 80 13 06 06 E2 94 43 33 87 B7 00 5E 97 +14 C3 91 07 E3 9A C7 FE 63 01 0B 0A 37 C7 03 10 +5C 4B 89 8B F5 DF 83 46 1A 00 85 47 63 8D F6 1E +5C 4B 93 F7 C7 3F 63 81 07 1A 63 11 05 2A 05 45 +EF 80 FF E4 01 A0 93 97 19 00 11 67 13 07 17 FC +93 F7 F7 0F D9 8F 37 C7 03 10 1C CB 89 4C E3 F5 +0C F5 37 45 02 50 13 05 C5 74 EF 80 5F E4 B7 97 +03 10 03 27 C4 C5 23 A8 97 01 83 C7 24 00 63 8B +07 14 B7 C7 03 10 23 A4 87 01 89 47 63 FB E7 26 +37 45 02 50 13 05 85 16 EF 80 7F E1 15 B7 37 45 +02 50 13 05 05 41 EF 80 9F E0 03 28 C4 C5 39 B3 +B7 C7 03 10 05 47 98 C7 21 B7 89 47 63 8A 0A 08 +63 EC A7 1A B7 97 03 10 A4 4F 63 9F 04 18 E4 4F +63 91 04 22 A4 53 63 9C 04 20 E4 53 63 97 04 20 +A4 57 63 9C 04 20 E4 57 63 97 04 20 A4 5B 63 98 +04 20 E4 5B 9D 45 63 9A 04 16 B2 50 22 54 92 54 +02 59 F2 49 62 4A D2 4A 42 4B B2 4B 22 4C 92 4C +02 4D 45 61 82 80 37 45 02 50 13 05 45 43 EF 80 +1F D9 03 28 C4 C5 75 B1 6C 43 30 43 2D 65 13 05 +45 E5 EF 80 DF D9 03 25 C4 C5 E3 7D AC EA 37 45 +02 50 13 05 C5 76 EF 80 9F D6 03 25 C4 C5 5D B5 +63 E5 A7 10 B7 97 03 10 B8 4F 23 20 E9 00 F8 4F +23 22 E9 00 B8 53 23 24 E9 00 F8 53 23 26 E9 00 +B8 57 23 28 E9 00 F8 57 23 2A E9 00 B8 5B 23 2C +E9 00 FC 5B 23 2E F9 00 8D BF 37 45 02 50 13 05 +85 45 EF 80 DF D1 B7 97 03 10 03 28 C4 C5 23 A0 +07 08 23 A2 07 08 23 A4 07 08 23 A6 07 08 23 A8 +07 08 23 AA 07 08 23 AC 07 08 23 AE 07 08 E3 7A +0D C7 37 45 02 50 13 05 C5 47 EF 80 5F CE 03 28 +C4 C5 85 B1 0D 4C 75 B5 89 47 63 E1 A7 0C 03 D7 +04 00 85 47 E3 1B F7 F0 93 97 89 00 93 E7 37 0B +37 07 03 30 23 26 F7 0C 09 B7 5C 47 93 F7 C7 3F +D9 C3 89 47 E3 F0 07 C9 37 45 02 50 13 05 85 4B +EF 80 FF C9 03 28 C4 C5 99 B9 63 18 08 08 05 45 +EF 80 FF C6 01 A0 5C 4B 93 F7 C7 3F BD C3 89 47 +E3 F5 A7 EC 22 54 B2 50 92 54 02 59 F2 49 62 4A +D2 4A 42 4B B2 4B 22 4C 92 4C 02 4D 37 45 02 50 +13 05 C5 5C 45 61 6F 80 9F C5 37 45 02 50 13 05 +85 7D EF 80 DF C4 FD B5 81 45 83 27 C4 C5 F1 E3 +05 45 EF 80 DF C1 01 A0 37 45 02 50 13 05 C5 71 +EF 80 FF C2 81 B5 63 1F 08 08 05 45 EF 80 3F C0 +01 A0 51 E1 05 45 EF 80 9F BF 01 A0 37 45 02 50 +13 05 05 6B EF 80 BF C0 1D BF AD 64 93 84 44 E5 +81 45 13 85 44 3A EF 80 9F C1 83 27 C4 C5 A5 D3 +EA 85 13 85 04 3D EF 80 9F C0 83 27 C4 C5 A1 DB +81 45 13 85 84 3E EF 80 9F BF 91 B7 37 45 02 50 +13 05 C5 78 EF 80 BF BC 99 BB 8D 45 BD BF 89 45 +AD BF 85 45 9D BF 95 45 8D BF 91 45 BD B7 99 45 +AD B7 37 67 02 50 13 07 87 E2 3C 43 74 43 D5 8F +E3 80 07 CC 1D BD 37 45 02 50 13 05 45 61 EF 80 +1F B9 8D BF 37 45 02 50 13 05 85 4F EF 80 3F B8 +A9 BF 2D 69 13 09 49 E5 13 05 09 40 EF 80 3F B9 +83 27 C4 C5 E3 86 07 F2 A6 85 13 05 49 43 EF 80 +1F B8 83 27 C4 C5 E3 8D 07 F0 81 45 13 05 C9 44 +EF 80 FF B6 31 B7 01 11 22 CC 37 34 02 50 03 28 +C4 C5 26 CA 4E C6 52 C4 56 C2 06 CE 4A C8 89 47 +03 C9 06 00 B6 84 AA 8A 2E 8A B2 89 63 E4 07 23 +37 97 03 10 5C 4B 85 8B F5 DF 89 47 63 E3 07 27 +05 67 13 07 07 C6 B7 A5 03 10 D6 87 33 86 EA 00 +B3 85 55 41 94 43 33 87 F5 00 91 07 14 C3 E3 9B +C7 FE 37 C6 03 10 13 06 06 80 D2 87 93 05 0A 62 +33 06 46 41 94 43 33 07 F6 00 91 07 14 C3 E3 9B +B7 FE 89 47 63 E6 07 21 03 A7 09 00 B7 07 03 10 +98 CF 03 A7 49 00 D8 CF 03 A7 89 00 98 D3 03 A7 +C9 00 D8 D3 03 A7 09 01 98 D7 03 A7 49 01 D8 D7 +03 A7 89 01 98 DB 03 A7 C9 01 D8 DB 03 A7 09 02 +98 DF 03 A7 49 02 D8 DF 03 A7 89 02 B8 C3 03 A7 +C9 02 F8 C3 03 A7 09 03 B8 C7 03 A7 49 03 F8 C7 +03 A7 89 03 B8 CB 03 A7 C9 03 F8 CB 63 0E 09 00 +83 C7 24 00 11 67 13 07 17 FC 86 07 93 F7 F7 0F +D9 8F 37 C7 03 10 1C CB 89 49 63 EE 09 15 B7 97 +03 10 0D 47 98 CB 37 67 02 50 13 07 87 E2 34 43 +7C 43 D5 8F 91 EF 73 00 50 10 93 07 40 06 01 00 +FD 17 C2 07 C1 83 E5 FF 3C 43 74 43 D5 8F E5 D7 +83 26 C4 C5 89 49 63 E8 D9 06 63 09 09 08 37 C7 +03 10 5C 4B 89 8B F5 DF 03 C6 14 00 85 47 63 03 +F6 16 5C 4B 93 F7 C7 3F 63 96 07 14 89 47 63 E9 +D7 1A B7 97 03 10 A4 4F 63 90 04 20 E4 4F 63 96 +04 26 A4 53 63 91 04 26 E4 53 63 9C 04 24 A4 57 +63 97 04 24 E4 57 63 92 04 24 A4 5B 63 9D 04 22 +E4 5B 9D 45 D9 CC 83 27 C4 C5 63 9C 07 1E 05 45 +EF 80 FF 97 01 A0 6C 43 30 43 2D 65 13 05 45 E5 +EF 80 FF 9A 63 1D 09 0E 83 27 C4 C5 63 F8 F9 00 +37 55 02 50 13 05 05 9E EF 80 7F 97 B7 97 03 10 +83 A9 87 05 03 A9 44 00 63 9C 29 0F 83 A9 C7 05 +03 A9 84 00 63 9C 29 19 83 A9 07 06 03 A9 C4 00 +63 9E 29 17 83 A9 47 06 03 A9 04 01 63 9A 29 17 +83 A9 87 06 03 A9 44 01 63 96 29 17 83 A9 C7 06 +03 A9 84 01 63 92 29 17 83 A9 07 07 03 A9 C4 01 +63 90 29 17 83 A9 47 07 03 A9 04 02 9D 45 63 12 +39 0B F2 40 62 44 D2 44 42 49 B2 49 22 4A 92 4A +05 61 82 80 37 45 02 50 13 05 85 7F EF 80 3F 8F +03 28 C4 C5 F1 B3 37 55 02 50 13 05 05 86 EF 80 +1F 8E 83 27 C4 C5 37 97 03 10 8D 46 14 CB 63 FF +F9 0C 37 45 02 50 13 05 85 16 EF 80 5F 8C 61 B5 +37 55 02 50 13 05 05 84 EF 80 7F 8B 03 28 C4 C5 +E5 B3 37 55 02 50 13 05 C5 81 EF 80 5F 8A 03 28 +C4 C5 79 B3 C9 EE 05 45 EF 80 7F 87 01 A0 83 26 +C4 C5 71 B5 5C 4B 93 F7 C7 3F AD CF 89 47 E3 F2 +D7 EA 37 55 02 50 13 05 05 88 EF 80 5F 87 B9 A0 +81 45 83 27 C4 C5 89 E7 05 45 EF 80 5F 84 01 A0 +AD 64 93 84 44 E5 13 85 84 4C EF 80 5F 87 83 27 +C4 C5 FD D3 CE 85 13 85 C4 4F EF 80 5F 86 83 27 +C4 C5 F9 DB CA 85 13 85 44 51 EF 80 5F 85 E9 B7 +37 55 02 50 13 05 45 96 EF 80 7F 82 03 27 C4 C5 +89 47 E3 F0 E7 E4 37 55 02 50 13 05 05 9B EF 80 +1F 81 05 BD A1 EA 05 45 EF 80 6F FE 01 A0 37 55 +02 50 13 05 85 91 EF 80 8F FF B1 BF 37 67 02 50 +13 07 87 E2 34 43 7C 43 D5 8F E3 8E 07 DA 83 26 +C4 C5 E3 1E 09 DC 9D B5 81 45 35 B5 89 45 95 B7 +8D 45 85 B7 91 45 B1 BF 95 45 A1 BF 85 45 91 BF +99 45 81 BF 37 55 02 50 13 05 85 8C EF 80 2F FB +5D B7 2D 69 13 09 49 E5 13 05 49 46 EF 80 2F FC +83 27 C4 C5 E3 8D 07 DE A6 85 13 05 89 49 EF 80 +0F FB 83 27 C4 C5 E3 84 07 DE 81 45 13 05 09 4B +EF 80 EF F9 E9 BB 99 45 F9 B3 95 45 E9 B3 91 45 +D9 B3 8D 45 C9 B3 89 45 7D BB 85 45 6D BB 01 11 +22 CC 37 34 02 50 03 28 C4 C5 26 CA 4E C6 52 C4 +56 C2 06 CE 4A C8 89 47 03 C9 06 00 B6 84 AA 8A +2E 8A B2 89 63 E8 07 1B 37 97 03 10 5C 4B 85 8B +F5 DF 89 47 63 E9 07 1B 05 67 13 07 07 C6 B7 A5 +03 10 D6 87 33 86 EA 00 B3 85 55 41 94 43 33 87 +F5 00 91 07 14 C3 E3 9B C7 FE 37 C6 03 10 13 06 +06 80 D2 87 93 05 0A 62 33 06 46 41 94 43 33 07 +F6 00 91 07 14 C3 E3 9B B7 FE 89 47 63 E3 07 1B +03 A7 09 00 B7 07 03 10 98 CF 03 A7 49 00 D8 CF +03 A7 89 00 98 D3 03 A7 C9 00 D8 D3 03 A7 09 01 +98 D7 03 A7 49 01 D8 D7 03 A7 89 01 98 DB 03 A7 +C9 01 D8 DB 03 A7 09 02 98 DF 03 A7 49 02 D8 DF +03 A7 89 02 B8 C3 03 A7 C9 02 F8 C3 03 A7 09 03 +B8 C7 03 A7 49 03 F8 C7 03 A7 89 03 B8 CB 03 A7 +C9 03 F8 CB 63 0E 09 00 83 C7 24 00 11 67 13 07 +17 FC 86 07 93 F7 F7 0F D9 8F 37 C7 03 10 1C CB +89 49 63 EB 09 0F B7 97 03 10 0D 47 98 CB 37 67 +02 50 13 07 87 E2 34 43 7C 43 D5 8F 91 EF 73 00 +50 10 93 07 40 06 01 00 FD 17 C2 07 C1 83 E5 FF +3C 43 74 43 D5 8F E5 D7 83 26 C4 C5 89 49 63 E3 +D9 04 63 04 09 06 37 C7 03 10 5C 4B 89 8B F5 DF +03 C6 14 00 85 47 63 07 F6 0E 5C 4B 93 F7 C7 3F +E9 EF 89 47 63 FF D7 04 37 55 02 50 13 05 45 96 +62 44 F2 40 D2 44 42 49 B2 49 22 4A 92 4A 05 61 +6F 80 EF DD 6C 43 30 43 2D 65 13 05 45 E5 EF 80 +0F DF 63 11 09 0A 83 27 C4 C5 63 F8 F9 00 37 55 +02 50 13 05 45 A9 EF 80 8F DB 37 97 03 10 34 4F +93 07 C7 05 78 4F D8 43 98 47 D8 47 98 4B D8 4B +9C 4F F2 40 62 44 D2 44 42 49 B2 49 22 4A 92 4A +05 61 82 80 37 45 02 50 13 05 85 7F EF 80 2F D8 +03 28 C4 C5 91 B5 37 55 02 50 13 05 C5 81 EF 80 +0F D7 03 28 C4 C5 89 B5 37 55 02 50 13 05 05 86 +EF 80 EF D5 83 27 C4 C5 37 97 03 10 8D 46 14 CB +63 FD F9 04 37 45 02 50 13 05 85 16 EF 80 2F D4 +FD B5 37 55 02 50 13 05 05 84 EF 80 4F D3 03 28 +C4 C5 B9 B5 83 26 C4 C5 39 B7 8D E2 05 45 EF 80 +0F D0 01 A0 5C 4B 93 F7 C7 3F 95 CF 89 47 E3 FA +D7 F6 37 55 02 50 13 05 05 A0 19 BF 37 55 02 50 +13 05 85 91 EF 80 AF CF D1 BF 37 67 02 50 13 07 +87 E2 34 43 7C 43 D5 8F E3 83 07 EA 83 26 C4 C5 +E3 13 09 EC 1D B7 89 E6 05 45 EF 80 4F CB 01 A0 +37 55 02 50 13 05 85 A4 EF 80 6F CC F5 B7 79 71 +4A D0 37 39 02 50 03 28 C9 C5 4E CE 5E C6 62 C4 +66 C2 06 D6 22 D4 26 D2 52 CC 56 CA 5A C8 6A C0 +89 47 03 CB 06 00 03 CA 26 00 B6 89 2A 8C AE 8B +B2 8C 63 EE 07 2B B7 94 03 10 C0 48 05 88 75 DC +83 4A 0C 00 63 8C 0A 08 83 47 2C 00 37 C7 03 10 +09 4D 86 07 93 F7 E7 03 93 E7 17 00 1C C3 63 6C +0D 39 23 AC 04 00 23 AE 04 00 23 A0 04 02 23 A2 +04 02 23 A4 04 02 23 A6 04 02 23 A8 04 02 23 AA +04 02 B7 97 03 10 23 AC 07 02 23 AE 07 02 23 A0 +07 04 23 A2 07 04 23 A4 07 04 23 A6 07 04 23 A8 +07 04 23 AA 07 04 37 C7 03 10 5C 43 89 8B F5 DF +83 46 1C 00 85 47 63 93 F6 08 5C 43 93 F7 C7 3F +63 88 07 3A 89 47 63 FB 07 07 37 45 02 50 13 05 +C5 23 EF 80 CF BE 03 28 C9 C5 8D A0 83 27 4C 00 +9C CC 83 27 8C 00 DC CC 83 27 CC 00 9C D0 83 27 +0C 01 DC D0 83 27 4C 01 9C D4 83 27 8C 01 DC D4 +83 27 CC 01 9C D8 83 27 0C 02 DC D8 83 27 4C 02 +9C DC 83 27 8C 02 DC DC 83 27 CC 02 BC C0 83 27 +0C 03 FC C0 83 27 4C 03 BC C4 83 27 8C 03 FC C4 +83 27 CC 03 BC C8 83 27 0C 04 FC C8 37 C6 03 10 +DE 87 13 06 06 80 93 8B 0B 62 1D 8E 94 43 33 07 +F6 00 91 07 14 C3 E3 9B 77 FF 89 47 63 EC 07 27 +03 A7 0C 00 B7 07 03 10 98 CF 03 A7 4C 00 D8 CF +03 A7 8C 00 98 D3 03 A7 CC 00 D8 D3 03 A7 0C 01 +98 D7 03 A7 4C 01 D8 D7 03 A7 8C 01 98 DB 03 A7 +CC 01 D8 DB 03 A7 0C 02 98 DF 03 A7 4C 02 D8 DF +03 A7 8C 02 B8 C3 03 A7 CC 02 F8 C3 03 A7 0C 03 +B8 C7 03 A7 4C 03 F8 C7 03 A7 8C 03 B8 CB 03 A7 +CC 03 F8 CB 63 12 0B 0C 89 47 63 ED 07 0D B7 97 +03 10 11 47 98 CB 83 47 2C 00 63 89 07 14 B7 C7 +03 10 05 47 98 C3 37 67 02 50 13 07 87 E2 34 43 +7C 43 D5 8F 9D E3 73 00 50 10 93 07 40 06 01 00 +FD 17 C2 07 C1 83 E5 FF 3C 43 74 43 D5 8F E5 D7 +03 28 C9 C5 09 44 63 65 04 0F 63 1E 0B 10 63 93 +0A 16 B7 97 03 10 A4 4F 03 A4 49 00 63 1C 94 32 +E4 4F 03 A4 89 00 63 1F 94 30 A4 53 03 A4 C9 00 +63 1C 94 30 E4 53 03 A4 09 01 63 99 84 26 A4 57 +03 A4 49 01 63 92 84 26 E4 57 03 A4 89 01 63 9B +84 24 A4 5B 03 A4 C9 01 63 9E 84 24 E4 5B 03 A4 +09 02 9D 45 63 02 94 14 83 27 C9 C5 63 94 07 26 +05 45 EF 80 CF A1 01 A0 93 17 1A 00 11 67 13 07 +17 FC 93 F7 F7 0F D9 8F 37 C7 03 10 1C CB 89 47 +E3 F7 07 F3 37 55 02 50 13 05 45 B6 EF 80 2F A1 +B7 97 03 10 11 47 03 28 C9 C5 98 CB 83 47 2C 00 +63 83 07 12 B7 C7 03 10 80 C3 89 47 E3 FD 07 F1 +37 45 02 50 13 05 85 16 EF 80 6F 9E 37 67 02 50 +13 07 87 E2 3C 43 74 43 D5 8F 91 D7 15 B7 37 55 +02 50 13 05 45 AB EF 80 8F 9C 03 28 C9 C5 25 BB +6C 43 30 43 2D 65 13 05 45 E5 EF 80 4F 9D 03 28 +C9 C5 63 12 0B 02 63 9F 0A 04 E3 74 04 F1 37 55 +02 50 13 05 85 CD EF 80 8F 99 E5 BD B7 C7 03 10 +0D 47 98 C3 4D BD 37 C7 03 10 5C 4B 89 8B F5 DF +83 C6 19 00 85 47 63 8B F6 0E 5C 4B 93 F7 C7 3F +C9 EF 89 47 63 E2 07 15 03 57 0C 00 85 47 63 1D +F7 04 93 17 8A 00 93 E7 37 0B 37 07 03 30 23 26 +F7 0C 99 A0 63 78 04 01 37 55 02 50 13 05 05 D0 +EF 80 EF 93 B7 97 03 10 A0 4F 63 19 04 0E E0 4F +63 16 04 1C A0 53 63 15 04 1C E0 53 63 1A 04 1A +A0 57 63 15 04 1A E0 57 63 10 04 1A A0 5B 63 19 +04 10 E0 5B 9D 45 61 E4 B2 50 22 54 92 54 02 59 +F2 49 62 4A D2 4A 42 4B B2 4B 22 4C 92 4C 02 4D +45 61 82 80 37 55 02 50 13 05 C5 B3 EF 80 2F 8E +03 28 C9 C5 B5 BB 0D 44 F1 BD 63 1E 08 0A 05 45 +EF 80 EF 8A 01 A0 37 55 02 50 13 05 C5 AD EF 80 +0F 8C 03 28 C9 C5 23 AC 04 00 23 AE 04 00 23 A0 +04 02 23 A2 04 02 23 A4 04 02 23 A6 04 02 23 A8 +04 02 23 AA 04 02 E3 7E 0D C5 37 55 02 50 13 05 +C5 B0 EF 80 CF 88 03 28 C9 C5 A1 B1 5C 4B 93 F7 +C7 3F A9 C7 89 47 E3 F9 07 F7 22 54 B2 50 92 54 +02 59 F2 49 62 4A D2 4A 42 4B B2 4B 22 4C 92 4C +02 4D 37 55 02 50 13 05 C5 B8 45 61 6F 80 2F 85 +63 1C 08 04 05 45 EF 80 8F 82 01 A0 81 45 83 27 +C9 C5 D9 EB 05 45 EF 80 8F 81 01 A0 63 15 08 04 +05 45 EF 80 CF 80 01 A0 37 55 02 50 13 05 45 C8 +EF 80 EF 81 55 BD 37 55 02 50 13 05 05 C3 EF 80 +0F 81 35 BF 95 45 C9 B3 91 45 7D BB 8D 45 6D BB +99 45 75 BF 99 45 4D BB 37 45 02 50 13 05 05 28 +EF 70 FF FE 45 B7 37 55 02 50 13 05 C5 BD EF 70 +1F FE 7D B7 AD 69 93 89 49 E5 13 85 C9 52 EF 70 +1F FF 83 27 C9 C5 E3 85 07 D8 A6 85 13 85 09 56 +EF 70 FF FD 83 27 C9 C5 E3 8C 07 D6 A2 85 13 85 +89 57 EF 70 DF FC AD B3 AD 64 93 84 44 E5 13 85 +04 59 EF 70 DF FB 83 27 C9 C5 A9 DF A2 85 13 85 +44 5C EF 70 DF FA 83 27 C9 C5 A9 D7 81 45 13 85 +C4 5D EF 70 DF F9 3D BF 95 45 15 BF 91 45 05 BF +8D 45 35 B7 85 45 0D B3 89 45 39 BB 85 45 05 B7 +89 45 31 BF 81 45 09 BB 79 71 26 D2 B7 34 02 50 +03 A8 C4 C5 4E CE 5A C8 5E C6 62 C4 06 D6 22 D4 +4A D0 52 CC 56 CA 66 C2 89 47 03 CA 06 00 03 C9 +26 00 B6 89 2A 8B AE 8B 32 8C 63 ED 07 29 37 94 +03 10 5C 48 85 8B F5 DF 83 4A 0B 00 63 8C 0A 08 +83 47 2B 00 37 C7 03 10 89 4C 86 07 93 F7 E7 03 +93 E7 17 00 1C C3 63 E1 0C 35 23 2C 04 00 23 2E +04 00 23 20 04 02 23 22 04 02 23 24 04 02 23 26 +04 02 23 28 04 02 23 2A 04 02 B7 97 03 10 23 AC +07 02 23 AE 07 02 23 A0 07 04 23 A2 07 04 23 A4 +07 04 23 A6 07 04 23 A8 07 04 23 AA 07 04 37 C7 +03 10 5C 43 89 8B F5 DF 83 46 1B 00 85 47 63 93 +F6 08 5C 43 93 F7 C7 3F 63 8C 07 34 89 47 63 FB +07 07 37 45 02 50 13 05 C5 23 EF 70 5F E8 03 A8 +C4 C5 8D A0 83 27 4B 00 1C CC 83 27 8B 00 5C CC +83 27 CB 00 1C D0 83 27 0B 01 5C D0 83 27 4B 01 +1C D4 83 27 8B 01 5C D4 83 27 CB 01 1C D8 83 27 +0B 02 5C D8 83 27 4B 02 1C DC 83 27 8B 02 5C DC +83 27 CB 02 3C C0 83 27 0B 03 7C C0 83 27 4B 03 +3C C4 83 27 8B 03 7C C4 83 27 CB 03 3C C8 83 27 +0B 04 7C C8 37 C6 03 10 DE 87 13 06 06 80 93 8B +0B 62 1D 8E 94 43 33 07 F6 00 91 07 14 C3 E3 9B +FB FE 89 47 63 E3 07 23 03 27 0C 00 B7 07 03 10 +98 CF 03 27 4C 00 D8 CF 03 27 8C 00 98 D3 03 27 +CC 00 D8 D3 03 27 0C 01 98 D7 03 27 4C 01 D8 D7 +03 27 8C 01 98 DB 03 27 CC 01 D8 DB 03 27 0C 02 +98 DF 03 27 4C 02 D8 DF 03 27 8C 02 B8 C3 03 27 +CC 02 F8 C3 03 27 0C 03 B8 C7 03 27 4C 03 F8 C7 +03 27 8C 03 B8 CB 03 27 CC 03 F8 CB 63 1F 0A 08 +09 44 63 6A 04 0B B7 97 03 10 11 47 98 CB 83 47 +2B 00 37 C7 03 10 86 07 93 F7 E7 03 93 E7 17 00 +1C C3 37 67 02 50 13 07 87 E2 3C 43 74 43 D5 8F +9D E3 73 00 50 10 93 07 40 06 01 00 FD 17 C2 07 +C1 83 E5 FF 3C 43 74 43 D5 8F E5 D7 03 A8 C4 C5 +09 44 63 66 04 11 63 00 0A 0C 37 C7 03 10 5C 4B +89 8B F5 DF 83 C6 19 00 85 47 63 8A F6 1A 5C 4B +93 F7 C7 3F 63 9C 07 14 89 47 63 E7 07 21 03 57 +0B 00 85 47 63 1E F7 10 93 17 89 00 93 E7 37 0B +37 07 03 30 23 26 F7 0C 21 A2 93 17 19 00 11 67 +13 07 17 FC 93 F7 F7 0F D9 8F 37 C7 03 10 1C CB +09 44 E3 7A 04 F5 37 55 02 50 13 05 45 B6 EF 70 +1F CD B7 97 03 10 11 47 03 A8 C4 C5 98 CB 83 47 +2B 00 37 C7 03 10 86 07 93 F7 E7 03 93 E7 17 00 +1C C3 E3 70 04 F5 37 45 02 50 13 05 85 16 EF 70 +1F CA 37 67 02 50 13 07 87 E2 34 43 7C 43 D5 8F +8D DB A9 B7 37 55 02 50 13 05 45 AB EF 70 3F C8 +03 A8 C4 C5 A9 BB 63 89 0A 06 B7 97 03 10 A0 4F +63 11 04 18 E0 4F 63 19 04 18 A0 53 63 18 04 18 +E0 53 63 16 04 16 A0 57 63 11 04 16 E0 57 63 1C +04 14 A0 5B 63 11 04 16 E0 5B 9D 45 31 C8 83 A7 +C4 C5 63 97 07 16 05 45 EF 70 7F C1 01 A0 6C 43 +30 43 2D 65 13 05 45 E5 EF 70 7F C4 03 A8 C4 C5 +E3 15 0A EE 63 94 0A 0E 63 78 04 01 37 55 02 50 +13 05 85 D3 EF 70 BF C0 37 97 03 10 34 4F 93 07 +C7 05 78 4F D8 43 98 47 D8 47 98 4B D8 4B 9C 4F +B2 50 22 54 92 54 02 59 F2 49 62 4A D2 4A 42 4B +B2 4B 22 4C 92 4C 45 61 82 80 37 55 02 50 13 05 +C5 B3 EF 70 DF BC 03 A8 C4 C5 F9 B3 63 17 08 0A +05 45 EF 70 DF B9 01 A0 37 55 02 50 13 05 C5 AD +EF 70 FF BA 03 A8 C4 C5 23 2C 04 00 23 2E 04 00 +23 20 04 02 23 22 04 02 23 24 04 02 23 26 04 02 +23 28 04 02 23 2A 04 02 E3 F9 0C CB 37 55 02 50 +13 05 C5 B0 EF 70 BF B7 03 A8 C4 C5 79 B9 5C 4B +93 F7 C7 3F A9 C7 89 47 E3 FC 07 F7 22 54 B2 50 +92 54 02 59 F2 49 62 4A D2 4A 42 4B B2 4B 22 4C +92 4C 37 55 02 50 13 05 C5 B8 45 61 6F 70 3F B4 +63 1D 08 04 05 45 EF 70 9F B1 01 A0 E3 7F 04 EB +37 55 02 50 13 05 05 D0 EF 70 7F B2 7D B5 63 13 +08 08 05 45 EF 70 BF AF 01 A0 37 55 02 50 13 05 +05 C3 EF 70 DF B0 A9 B7 37 55 02 50 13 05 45 C8 +EF 70 FF AF ED B3 95 45 5D BD 91 45 4D BD 8D 45 +7D B5 81 45 6D B5 99 45 5D B5 37 45 02 50 13 05 +05 28 EF 70 DF AD 79 BF 85 45 51 BD 89 45 41 BD +2D 69 13 09 49 E5 13 05 49 5F EF 70 5F AE 83 A7 +C4 C5 E3 82 07 E8 A2 85 13 05 89 62 EF 70 3F AD +83 A7 C4 C5 E3 89 07 E6 81 45 13 05 09 64 EF 70 +1F AC 95 B5 37 55 02 50 13 05 C5 BD EF 70 3F A9 +8D BF 01 00 52 65 63 65 69 76 65 64 20 4D 4C 4B +45 4D 20 6E 6F 74 69 66 2F 20 65 72 72 20 69 6E +74 72 20 77 69 74 68 20 73 74 61 74 75 73 20 3D +20 25 64 2F 20 25 64 0A 00 00 00 00 41 74 20 6F +66 66 73 65 74 20 5B 25 64 5D 2C 20 6D 6C 6B 65 +6D 5F 65 6E 63 61 70 73 5F 6B 65 79 20 64 61 74 +61 20 6D 69 73 6D 61 74 63 68 21 0A 00 00 00 00 +41 63 74 75 61 6C 20 20 20 64 61 74 61 3A 20 30 +78 25 78 0A 00 00 00 00 45 78 70 65 63 74 65 64 +20 64 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +41 74 20 6F 66 66 73 65 74 20 5B 25 64 5D 2C 20 +6D 6C 6B 65 6D 5F 64 65 63 61 70 73 5F 6B 65 79 +20 64 61 74 61 20 6D 69 73 6D 61 74 63 68 21 0A +00 00 00 00 41 63 74 75 61 6C 20 20 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 45 78 70 65 +63 74 65 64 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 41 74 20 6F 66 66 73 65 74 20 5B 25 +64 5D 2C 20 6D 6C 6B 65 6D 5F 73 65 65 64 5F 64 +20 64 61 74 61 20 6D 69 73 6D 61 74 63 68 21 0A +00 00 00 00 41 63 74 75 61 6C 20 20 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 45 78 70 65 +63 74 65 64 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 41 74 20 6F 66 66 73 65 74 20 5B 25 +64 5D 2C 20 6D 6C 6B 65 6D 5F 73 65 65 64 5F 7A +20 64 61 74 61 20 6D 69 73 6D 61 74 63 68 21 0A +00 00 00 00 41 63 74 75 61 6C 20 20 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 45 78 70 65 +63 74 65 64 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 41 74 20 6F 66 66 73 65 74 20 5B 25 +64 5D 2C 20 6D 6C 6B 65 6D 5F 64 6B 20 64 61 74 +61 20 6D 69 73 6D 61 74 63 68 21 0A 00 00 00 00 +41 63 74 75 61 6C 20 20 20 64 61 74 61 3A 20 30 +78 25 78 0A 00 00 00 00 45 78 70 65 63 74 65 64 +20 64 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +41 74 20 6F 66 66 73 65 74 20 5B 25 64 5D 2C 20 +6D 6C 6B 65 6D 5F 6D 73 67 20 64 61 74 61 20 6D +69 73 6D 61 74 63 68 21 0A 00 00 00 41 63 74 75 +61 6C 20 20 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 45 78 70 65 63 74 65 64 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 41 74 20 6F +66 66 73 65 74 20 5B 25 64 5D 2C 20 6D 6C 6B 65 +6D 5F 63 69 70 68 65 72 74 65 78 74 20 64 61 74 +61 20 6D 69 73 6D 61 74 63 68 21 0A 00 00 00 00 +41 63 74 75 61 6C 20 20 20 64 61 74 61 3A 20 30 +78 25 78 0A 00 00 00 00 45 78 70 65 63 74 65 64 +20 64 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +41 74 20 6F 66 66 73 65 74 20 5B 25 64 5D 2C 20 +6D 6C 6B 65 6D 5F 73 68 61 72 65 64 5F 6B 65 79 +20 64 61 74 61 20 6D 69 73 6D 61 74 63 68 21 0A +00 00 00 00 41 63 74 75 61 6C 20 20 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 45 78 70 65 +63 74 65 64 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 41 74 20 6F 66 66 73 65 74 20 5B 25 +64 5D 2C 20 6D 6C 6B 65 6D 5F 73 68 61 72 65 64 +5F 6B 65 79 20 64 61 74 61 20 6D 69 73 6D 61 74 +63 68 21 0A 00 00 00 00 41 63 74 75 61 6C 20 20 +20 64 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +45 78 70 65 63 74 65 64 20 64 61 74 61 3A 20 30 +78 25 78 0A 00 00 00 00 41 74 20 6F 66 66 73 65 +74 20 5B 25 64 5D 2C 20 6D 6C 6B 65 6D 5F 6D 73 +67 20 64 61 74 61 20 6D 69 73 6D 61 74 63 68 21 +0A 00 00 00 41 63 74 75 61 6C 20 20 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 45 78 70 65 +63 74 65 64 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 41 74 20 6F 66 66 73 65 74 20 5B 25 +64 5D 2C 20 6D 6C 6B 65 6D 5F 73 68 61 72 65 64 +5F 6B 65 79 20 64 61 74 61 20 6D 69 73 6D 61 74 +63 68 21 0A 00 00 00 00 41 63 74 75 61 6C 20 20 +20 64 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +45 78 70 65 63 74 65 64 20 64 61 74 61 3A 20 30 +78 25 78 0A 00 00 00 00 41 74 20 6F 66 66 73 65 +74 20 5B 25 64 5D 2C 20 6D 6C 6B 65 6D 5F 73 68 +61 72 65 64 5F 6B 65 79 20 64 61 74 61 20 6D 69 +73 6D 61 74 63 68 21 0A 00 00 00 00 41 63 74 75 +61 6C 20 20 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 45 78 70 65 63 74 65 64 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 41 74 20 6F +66 66 73 65 74 20 5B 25 64 5D 2C 20 6D 6C 6B 65 +6D 5F 73 68 61 72 65 64 5F 6B 65 79 20 64 61 74 +61 20 6D 69 73 6D 61 74 63 68 21 0A 00 00 00 00 +41 63 74 75 61 6C 20 20 20 64 61 74 61 3A 20 30 +78 25 78 0A 00 00 00 00 45 78 70 65 63 74 65 64 +20 64 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +41 74 20 6F 66 66 73 65 74 20 5B 25 64 5D 2C 20 +6D 6C 6B 65 6D 5F 73 68 61 72 65 64 5F 6B 65 79 +20 64 61 74 61 20 6D 69 73 6D 61 74 63 68 21 0A +00 00 00 00 41 63 74 75 61 6C 20 20 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 45 78 70 65 +63 74 65 64 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 41 74 20 6F 66 66 73 65 74 20 5B 25 +64 5D 2C 20 6D 6C 6B 65 6D 5F 73 68 61 72 65 64 +5F 6B 65 79 20 64 61 74 61 20 6D 69 73 6D 61 74 +63 68 21 0A 00 00 00 00 41 63 74 75 61 6C 20 20 +20 64 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +45 78 70 65 63 74 65 64 20 64 61 74 61 3A 20 30 +78 25 78 0A 00 00 00 00 41 74 20 6F 66 66 73 65 +74 20 5B 25 64 5D 2C 20 6D 6C 6B 65 6D 5F 73 68 +61 72 65 64 5F 6B 65 79 20 64 61 74 61 20 6D 69 +73 6D 61 74 63 68 21 0A 00 00 00 00 41 63 74 75 +61 6C 20 20 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 45 78 70 65 63 74 65 64 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 41 11 22 C4 +37 34 02 50 03 27 C4 C5 06 C6 89 47 63 E0 E7 04 +37 67 02 50 13 07 87 E2 1C 4B 54 4B D5 8F 9D E3 +73 00 50 10 93 07 40 06 01 00 FD 17 C2 07 C1 83 +E5 FF 1C 4B 54 4B D5 8F E5 D7 83 26 C4 C5 89 47 +63 E5 D7 02 B2 40 22 44 41 01 82 80 37 55 02 50 +13 05 05 D6 EF 70 AF BD 37 67 02 50 13 07 87 E2 +1C 4B 54 4B D5 8F CD DF C9 BF 22 44 4C 4B B2 40 +10 4B 31 65 13 05 C5 6B 41 01 6F 70 4F BD B7 37 +02 50 03 A7 C7 C5 89 47 63 E7 E7 00 B7 07 01 10 +11 47 98 CB 82 80 37 55 02 50 41 11 13 05 C5 D7 +06 C6 EF 70 CF B8 B2 40 B7 07 01 10 11 47 98 CB +41 01 82 80 19 CA 0A 06 33 87 C5 00 9C 41 91 05 +11 05 23 2E F5 FE E3 9B E5 FE 82 80 39 71 5A D0 +62 CC 66 CA 6A C8 6E C6 06 DE 22 DC 26 DA 4A D8 +4E D6 52 D4 56 D2 5E CE 03 49 15 00 83 4B 25 00 +03 CA 15 00 83 C9 25 00 83 CA 06 00 AA 8D 2E 8C +B6 8C 32 8D 3A 8B B7 07 01 10 80 4F 05 88 75 DC +03 C7 0D 00 B7 34 02 50 03 A5 C4 C5 45 C3 13 97 +1B 00 13 77 E7 03 13 67 17 00 23 A0 E7 60 89 47 +63 ED A7 30 B7 07 01 10 23 A0 07 04 23 A2 07 04 +23 A4 07 04 23 A6 07 04 23 A8 07 04 23 AA 07 04 +23 AC 07 04 23 AE 07 04 23 A0 07 06 23 A2 07 06 +23 A4 07 06 23 A6 07 06 37 07 01 10 83 27 47 60 +89 8B ED DF 85 47 63 1C F9 08 83 27 47 60 93 F7 +C7 3F 63 80 07 32 89 47 63 ED A7 3A 83 47 0C 00 +63 96 07 36 37 06 01 10 B7 05 FF EF 93 07 06 08 +93 85 05 F8 13 06 06 10 BE 86 91 07 33 87 B7 00 +62 97 18 43 98 C2 E3 99 C7 FE 75 A0 89 47 63 EF +A7 28 03 A7 4D 00 B7 07 01 10 B8 C3 03 A7 8D 00 +F8 C3 03 A7 CD 00 B8 C7 03 A7 0D 01 F8 C7 03 A7 +4D 01 B8 CB 03 A7 8D 01 F8 CB 03 A7 CD 01 B8 CF +03 A7 0D 02 F8 CF 03 A7 4D 02 B8 D3 03 A7 8D 02 +F8 D3 03 A7 CD 02 B8 D7 03 A7 0D 03 F8 D7 83 47 +0C 00 C9 D3 93 97 19 00 93 F7 E7 03 93 E7 17 00 +37 07 01 10 23 24 F7 60 89 47 63 FA A7 00 37 55 +02 50 13 05 05 E7 EF 70 8F 9F 03 A5 C4 C5 B7 06 +01 10 93 87 06 08 93 86 06 10 23 A0 07 00 91 07 +E3 9D D7 FE 37 07 01 10 83 27 C7 60 89 8B ED DF +85 47 63 0F FA 20 03 27 4D 00 B7 07 01 10 23 A0 +E7 14 03 27 8D 00 23 A2 E7 14 03 27 CD 00 23 A4 +E7 14 03 27 0D 01 23 A6 E7 14 03 27 4D 01 23 A8 +E7 14 03 27 8D 01 23 AA E7 14 03 27 CD 01 23 AC +E7 14 03 27 0D 02 23 AE E7 14 03 27 4D 02 23 A0 +E7 16 03 27 8D 02 23 A2 E7 16 03 27 CD 02 23 A4 +E7 16 03 27 0D 03 23 A6 E7 16 63 8D 0A 00 03 C7 +2C 00 85 66 93 86 16 FC 06 07 13 77 F7 0F 55 8F +23 A8 E7 60 B7 07 01 10 63 0E 0B 12 05 47 98 CB +A2 87 63 93 0B 00 8D 47 37 07 01 10 23 20 F7 60 +63 93 09 00 0D 44 B7 07 01 10 23 A4 87 60 89 47 +63 ED A7 10 37 67 02 50 13 07 87 E2 1C 4B 54 4B +D5 8F 95 EB 73 00 50 10 93 07 40 06 01 00 FD 17 +C2 07 C1 83 E5 FF 1C 4B 54 4B D5 8F E5 D7 83 A6 +C4 C5 89 47 63 F9 D7 00 4C 4B 10 4B 31 65 13 05 +C5 6B EF 70 CF 8F 33 69 49 01 63 16 09 0A 83 A7 +C4 C5 09 47 63 95 0A 10 63 68 F7 16 B7 07 01 10 +03 A7 07 10 83 A7 4C 00 63 1C F7 14 B7 07 01 10 +03 A9 47 10 03 A4 8C 00 63 1E 24 13 03 A9 87 10 +03 A4 CC 00 63 1C 24 1F 03 A9 C7 10 03 A4 0C 01 +63 14 24 1F 03 A9 07 11 03 A4 4C 01 63 1C 89 1C +03 A9 47 11 03 A4 8C 01 63 14 89 1C 03 A9 87 11 +03 A4 CC 01 63 1C 89 1A 03 A9 C7 11 03 A4 0C 02 +63 14 89 1A 03 A9 07 12 03 A4 4C 02 63 1C 89 18 +03 A9 47 12 03 A4 8C 02 63 14 89 18 03 A9 87 12 +03 A4 CC 02 63 12 89 10 03 A9 C7 12 03 A4 0C 03 +AD 45 63 12 89 0C F2 50 62 54 D2 54 42 59 B2 59 +22 5A 92 5A 02 5B F2 4B 62 4C D2 4C 42 4D B2 4D +21 61 82 80 09 47 98 CB E1 B5 37 55 02 50 13 05 +05 D6 EF 60 DF FF 37 67 02 50 13 07 87 E2 1C 4B +54 4B D5 8F E3 80 07 EE DD BD 37 55 02 50 13 05 +05 D9 EF 60 DF FD 03 A5 C4 C5 E9 B9 37 55 02 50 +13 05 85 E5 EF 60 BF FC 03 A5 C4 C5 99 BB 63 64 +F7 04 37 07 01 10 83 27 47 61 89 8B ED DF 61 B7 +83 27 C7 60 93 F7 C7 3F 95 C3 89 47 E3 FD A7 DC +37 55 02 50 13 05 45 E9 EF 60 7F F9 03 A5 C4 C5 +D9 B3 61 E1 05 45 EF 60 9F F6 01 A0 45 E5 05 45 +EF 60 FF F5 01 A0 37 55 02 50 13 05 85 F3 EF 60 +1F F7 45 BF 85 45 83 A7 C4 C5 09 4A 63 61 FA 04 +05 45 EF 60 DF F3 01 A0 37 55 02 50 13 05 85 F5 +EF 60 FF F4 B7 07 01 10 03 A9 07 10 03 A4 4C 00 +E3 06 24 E9 81 45 C1 BF A9 45 F1 B7 93 97 19 00 +93 F7 E7 03 93 E7 17 00 23 24 F7 60 0D BB B1 69 +93 89 C9 6B 13 85 49 03 EF 60 7F F3 83 A7 C4 C5 +E3 78 FA FA CA 85 13 85 09 06 EF 60 5F F2 83 A7 +C4 C5 E3 7F FA F8 A2 85 13 85 89 07 EF 60 3F F1 +41 BF 37 55 02 50 13 05 85 DB EF 60 5F EE 03 A5 +C4 C5 75 B9 37 55 02 50 13 05 45 EE EF 60 3F ED +B9 B7 37 55 02 50 13 05 45 E0 EF 60 5F EC 1D BF +A5 45 91 BF A1 45 81 BF 9D 45 B1 B7 99 45 A1 B7 +95 45 91 B7 91 45 81 B7 8D 45 35 BF 89 45 25 BF +39 71 5A D0 62 CC 66 CA 6A C8 6E C6 06 DE 22 DC +26 DA 4A D8 4E D6 52 D4 56 D2 5E CE 03 49 15 00 +83 4B 25 00 03 CA 15 00 83 C9 25 00 83 CA 06 00 +AA 8D AE 8C 36 8C 32 8D 3A 8B B7 07 01 10 80 4F +05 88 75 DC 03 C7 0D 00 B7 34 02 50 03 A5 C4 C5 +45 CB 13 97 1B 00 13 77 E7 03 13 67 17 00 23 A0 +E7 60 89 47 63 E7 A7 38 B7 07 01 10 23 A0 07 04 +23 A2 07 04 23 A4 07 04 23 A6 07 04 23 A8 07 04 +23 AA 07 04 23 AC 07 04 23 AE 07 04 23 A0 07 06 +23 A2 07 06 23 A4 07 06 23 A6 07 06 23 A8 07 06 +23 AA 07 06 23 AC 07 06 23 AE 07 06 37 07 01 10 +83 27 47 60 89 8B ED DF 85 47 63 18 F9 0A 83 27 +47 60 93 F7 C7 3F 63 89 07 36 89 47 63 EF A7 3E +83 C7 0C 00 63 9A 07 38 37 06 01 10 B7 05 FF EF +93 07 06 08 93 85 05 F8 13 06 06 10 BE 86 91 07 +33 87 B7 00 66 97 18 43 98 C2 E3 99 C7 FE D1 A0 +89 47 63 E1 A7 30 03 A7 4D 00 B7 07 01 10 B8 C3 +03 A7 8D 00 F8 C3 03 A7 CD 00 B8 C7 03 A7 0D 01 +F8 C7 03 A7 4D 01 B8 CB 03 A7 8D 01 F8 CB 03 A7 +CD 01 B8 CF 03 A7 0D 02 F8 CF 03 A7 4D 02 B8 D3 +03 A7 8D 02 F8 D3 03 A7 CD 02 B8 D7 03 A7 0D 03 +F8 D7 03 A7 4D 03 B8 DB 03 A7 8D 03 F8 DB 03 A7 +CD 03 B8 DF 03 A7 0D 04 F8 DF 83 C7 0C 00 AD D7 +93 97 19 00 93 F7 E7 03 93 E7 17 00 37 07 01 10 +23 24 F7 60 89 47 63 FA A7 00 37 55 02 50 13 05 +05 E7 EF 60 DF D0 03 A5 C4 C5 B7 06 01 10 93 87 +06 08 93 86 06 10 23 A0 07 00 91 07 E3 9D D7 FE +37 07 01 10 83 27 C7 60 89 8B ED DF 85 47 63 0C +FA 24 03 27 4D 00 B7 07 01 10 23 A0 E7 14 03 27 +8D 00 23 A2 E7 14 03 27 CD 00 23 A4 E7 14 03 27 +0D 01 23 A6 E7 14 03 27 4D 01 23 A8 E7 14 03 27 +8D 01 23 AA E7 14 03 27 CD 01 23 AC E7 14 03 27 +0D 02 23 AE E7 14 03 27 4D 02 23 A0 E7 16 03 27 +8D 02 23 A2 E7 16 03 27 CD 02 23 A4 E7 16 03 27 +0D 03 23 A6 E7 16 63 8D 0A 00 03 47 2C 00 A1 66 +93 86 16 FC 06 07 13 77 F7 0F 55 8F 23 A8 E7 60 +B7 07 01 10 63 04 0B 18 25 47 98 CB A2 87 63 93 +0B 00 8D 47 37 07 01 10 23 20 F7 60 63 93 09 00 +0D 44 B7 07 01 10 23 A4 87 60 89 47 63 E3 A7 16 +37 67 02 50 13 07 87 E2 1C 4B 54 4B D5 8F 95 EB +73 00 50 10 93 07 40 06 01 00 FD 17 C2 07 C1 83 +E5 FF 1C 4B 54 4B D5 8F E5 D7 83 A6 C4 C5 89 47 +63 F9 D7 00 4C 4B 10 4B 31 65 13 05 C5 6B EF 60 +1F C1 33 69 49 01 63 1C 09 0E 83 A7 C4 C5 09 47 +63 9F 0A 0C 63 6B F7 18 B7 07 01 10 03 A9 07 10 +03 24 4C 00 63 19 24 1F 03 A9 47 10 03 24 8C 00 +63 11 24 1F 03 A9 87 10 03 24 CC 00 63 14 24 23 +03 A9 C7 10 03 24 0C 01 63 1C 24 21 03 A9 07 11 +03 24 4C 01 63 14 89 20 03 A9 47 11 03 24 8C 01 +63 1C 89 1E 03 A9 87 11 03 24 CC 01 63 14 89 1E +03 A9 C7 11 03 24 0C 02 63 1C 89 1C 03 A9 07 12 +03 24 4C 02 63 14 89 1C 03 A9 47 12 03 24 8C 02 +63 1C 89 1A 03 A9 87 12 03 24 CC 02 63 1D 89 12 +03 A9 C7 12 03 24 0C 03 63 15 89 12 03 A9 07 13 +03 24 4C 03 63 1D 89 10 03 A9 47 13 03 24 8C 03 +63 15 89 10 03 A9 87 13 03 24 CC 03 63 11 89 14 +03 A9 C7 13 03 24 0C 04 BD 45 63 02 89 02 83 A7 +C4 C5 63 9C 07 0E 05 45 EF 60 7F AE 01 A0 63 67 +F7 0A 37 07 01 10 83 27 47 61 89 8B ED DF F2 50 +62 54 D2 54 42 59 B2 59 22 5A 92 5A 02 5B F2 4B +62 4C D2 4C 42 4D B2 4D 21 61 82 80 29 47 98 CB +B5 BD 37 55 02 50 13 05 05 D6 EF 60 5F AC 37 67 +02 50 13 07 87 E2 1C 4B 54 4B D5 8F E3 8A 07 E8 +6D B5 37 55 02 50 13 05 05 F7 EF 60 5F AA 03 A5 +C4 C5 9D B1 37 55 02 50 13 05 85 E5 EF 60 3F A9 +03 A5 C4 C5 CD B9 83 27 C7 60 93 F7 C7 3F 95 C3 +89 47 E3 F0 A7 DA 37 55 02 50 13 05 45 E9 EF 60 +1F A7 03 A5 C4 C5 71 B3 4D E9 05 45 EF 60 3F A4 +01 A0 49 ED 05 45 EF 60 9F A3 01 A0 37 55 02 50 +13 05 85 F3 EF 60 BF A4 A9 B7 37 55 02 50 13 05 +85 F5 EF 60 DF A3 8D B5 93 97 19 00 93 F7 E7 03 +93 E7 17 00 23 24 F7 60 0D B3 B5 45 09 BF B1 45 +39 B7 AD 45 29 B7 A9 45 19 B7 B1 69 93 89 C9 6B +13 85 09 09 EF 60 BF A2 83 A7 C4 C5 E3 8D 07 EE +CA 85 13 85 C9 0B EF 60 9F A1 83 A7 C4 C5 E3 84 +07 EE A2 85 13 85 49 0D EF 60 7F A0 E9 BD B9 45 +F9 B5 85 45 E9 B5 81 45 D9 B5 37 55 02 50 13 05 +85 DB EF 60 DF 9C 03 A5 C4 C5 41 B9 37 55 02 50 +13 05 45 EE EF 60 BF 9B B1 BF 37 55 02 50 13 05 +45 E0 EF 60 DF 9A 91 B7 A5 45 51 BD A1 45 41 BD +9D 45 71 B5 99 45 61 B5 95 45 51 B5 91 45 41 B5 +8D 45 B5 BD 89 45 A5 BD 79 71 4A D0 56 CA 5E C6 +62 C4 66 C2 6A C0 06 D6 22 D4 26 D2 4E CE 52 CC +5A C8 03 4B 25 00 03 CA 25 00 83 C9 06 00 3E 8C +2A 8D AE 8B 36 89 B2 8C BA 8A B7 07 01 10 80 4F +05 88 75 DC 03 47 0D 00 B7 34 02 50 03 A5 C4 C5 +55 CB 13 17 1B 00 13 77 E7 03 13 67 17 00 23 A0 +E7 60 89 47 63 E3 A7 34 B7 07 01 10 23 A0 07 04 +23 A2 07 04 23 A4 07 04 23 A6 07 04 23 A8 07 04 +23 AA 07 04 23 AC 07 04 23 AE 07 04 23 A0 07 06 +23 A2 07 06 23 A4 07 06 23 A6 07 06 23 A8 07 06 +23 AA 07 06 23 AC 07 06 23 AE 07 06 37 07 01 10 +83 27 47 60 89 8B ED DF 83 46 1D 00 85 47 63 98 +F6 0A 83 27 47 60 93 F7 C7 3F 63 83 07 32 89 47 +63 EA A7 32 83 C7 0B 00 63 9D 07 34 37 06 01 10 +B7 05 FF EF 93 07 06 08 93 85 05 F8 13 06 06 10 +BE 86 91 07 33 87 B7 00 5E 97 18 43 98 C2 E3 99 +C7 FE E1 A0 89 47 63 EB A7 2A 03 27 4D 00 B7 07 +01 10 B8 C3 03 27 8D 00 F8 C3 03 27 CD 00 B8 C7 +03 27 0D 01 F8 C7 03 27 4D 01 B8 CB 03 27 8D 01 +F8 CB 03 27 CD 01 B8 CF 03 27 0D 02 F8 CF 03 27 +4D 02 B8 D3 03 27 8D 02 F8 D3 03 27 CD 02 B8 D7 +03 27 0D 03 F8 D7 03 27 4D 03 B8 DB 03 27 8D 03 +F8 DB 03 27 CD 03 B8 DF 03 27 0D 04 F8 DF 83 C7 +0B 00 AD D7 93 17 1A 00 93 F7 E7 03 93 E7 17 00 +37 07 01 10 23 24 F7 60 89 47 63 FA A7 00 37 55 +02 50 13 05 05 E7 EF 60 8F FF 03 A5 C4 C5 B7 06 +01 10 93 87 06 08 93 86 06 10 23 A0 07 00 91 07 +E3 9D D7 FE 37 07 01 10 83 27 C7 60 89 8B ED DF +83 C6 1B 00 85 47 63 84 F6 20 03 A7 4C 00 B7 07 +01 10 23 A0 E7 14 03 A7 8C 00 23 A2 E7 14 03 A7 +CC 00 23 A4 E7 14 03 A7 0C 01 23 A6 E7 14 03 A7 +4C 01 23 A8 E7 14 03 A7 8C 01 23 AA E7 14 03 A7 +CC 01 23 AC E7 14 03 A7 0C 02 23 AE E7 14 03 A7 +4C 02 23 A0 E7 16 03 A7 8C 02 23 A2 E7 16 03 A7 +CC 02 23 A4 E7 16 03 A7 0C 03 23 A6 E7 16 63 8D +09 00 03 47 29 00 91 66 93 86 16 FC 06 07 13 77 +F7 0F 55 8F 23 A8 E7 60 B7 07 01 10 63 8C 0A 12 +25 47 98 CB A2 87 63 13 0B 00 8D 47 37 07 01 10 +23 20 F7 60 63 13 0A 00 0D 44 B7 07 01 10 23 A4 +87 60 89 47 63 EB A7 10 37 67 02 50 13 07 87 E2 +1C 4B 54 4B D5 8F 91 EF 73 00 50 10 93 07 40 06 +01 00 FD 17 C2 07 C1 83 E5 FF 1C 4B 54 4B D5 8F +E5 D7 83 A7 C4 C5 09 44 63 6B F4 00 63 8C 09 02 +37 07 01 10 83 27 47 61 89 8B ED DF 75 A0 4C 4B +10 4B 31 65 13 05 C5 6B EF 60 6F EE 83 A7 C4 C5 +63 94 09 0C 63 78 F4 00 37 55 02 50 13 05 85 F5 +EF 60 EF EA B7 07 01 10 03 A7 07 10 23 20 EC 00 +03 A7 47 10 23 22 EC 00 03 A7 87 10 23 24 EC 00 +03 A7 C7 10 23 26 EC 00 03 A7 07 11 23 28 EC 00 +03 A7 47 11 23 2A EC 00 03 A7 87 11 23 2C EC 00 +03 A7 C7 11 23 2E EC 00 03 A7 07 12 23 20 EC 02 +03 A7 47 12 23 22 EC 02 03 A7 87 12 23 24 EC 02 +03 A7 C7 12 23 26 EC 02 03 A7 07 13 23 28 EC 02 +03 A7 47 13 23 2A EC 02 03 A7 87 13 23 2C EC 02 +83 A7 C7 13 23 2E FC 02 B2 50 22 54 92 54 02 59 +F2 49 62 4A D2 4A 42 4B B2 4B 22 4C 92 4C 02 4D +45 61 82 80 29 47 98 CB F1 B5 37 55 02 50 13 05 +05 D6 EF 60 CF DF CD B5 E3 7C F4 F0 37 55 02 50 +13 05 85 F3 EF 60 AF DE 21 B7 37 55 02 50 13 05 +05 F7 EF 60 CF DD 03 A5 C4 C5 7D B1 37 55 02 50 +13 05 85 E5 EF 60 AF DC 03 A5 C4 C5 3D BB 83 27 +C7 60 93 F7 C7 3F 95 C3 89 47 E3 F8 A7 DE 37 55 +02 50 13 05 45 E9 EF 60 8F DA 03 A5 C4 C5 F1 BB +15 E9 05 45 EF 60 AF D7 01 A0 11 ED 05 45 EF 60 +0F D7 01 A0 37 55 02 50 13 05 85 DB EF 60 2F D8 +03 A5 C4 C5 A9 BB 37 55 02 50 13 05 45 EE EF 60 +0F D7 E9 BF 37 55 02 50 13 05 45 E0 EF 60 2F D6 +C9 B7 93 17 1A 00 93 F7 E7 03 93 E7 17 00 23 24 +F7 60 B1 BB 01 11 26 CA 4A C8 4E C6 56 C2 5A C0 +06 CE 22 CC 52 C4 2A 89 AE 84 B2 8A B6 89 3A 8B +B7 07 01 10 80 4F 05 88 75 DC 37 3A 02 50 03 28 +CA C5 89 47 63 EC 07 27 83 27 49 00 37 07 01 10 +37 05 01 10 3C C3 83 26 89 00 37 06 FF EF 93 07 +07 08 74 C3 83 26 C9 00 13 06 06 F8 93 05 05 10 +34 C7 83 26 09 01 74 C7 83 26 49 01 34 CB 83 26 +89 01 74 CB 83 26 C9 01 34 CF 83 26 09 02 74 CF +83 26 49 02 34 D3 83 26 89 02 74 D3 83 26 C9 02 +34 D7 83 26 09 03 74 D7 83 26 49 03 34 DB 83 26 +89 03 74 DB 83 26 C9 03 34 DF 83 26 09 04 74 DF +BE 86 91 07 33 87 C7 00 26 97 18 43 98 C2 E3 99 +B7 FE 83 A7 4A 00 23 20 F5 14 83 A7 8A 00 23 22 +F5 14 83 A7 CA 00 23 24 F5 14 83 A7 0A 01 23 26 +F5 14 83 A7 4A 01 23 28 F5 14 83 A7 8A 01 23 2A +F5 14 83 A7 CA 01 23 2C F5 14 83 A7 0A 02 23 2E +F5 14 83 A7 4A 02 23 20 F5 16 83 A7 8A 02 23 22 +F5 16 83 A7 CA 02 23 24 F5 16 83 A7 0A 03 23 26 +F5 16 63 0F 0B 12 E5 47 1C C9 03 47 29 00 A2 87 +11 E3 8D 47 37 07 01 10 23 20 F7 60 83 C7 24 00 +91 E3 0D 44 B7 07 01 10 23 A4 87 60 89 47 63 E8 +07 15 37 67 02 50 13 07 87 E2 14 4B 5C 4B D5 8F +91 EF 73 00 50 10 93 07 40 06 01 00 FD 17 C2 07 +C1 83 E5 FF 1C 4B 54 4B D5 8F E5 D7 83 27 CA C5 +09 44 63 6C F4 0E B7 07 01 10 83 A4 07 10 03 A4 +49 00 63 1A 94 0C 83 A4 47 10 03 A4 89 00 63 1A +94 14 83 A4 87 10 03 A4 C9 00 63 1A 94 14 83 A4 +C7 10 03 A4 09 01 63 92 84 14 83 A4 07 11 03 A4 +49 01 63 9A 84 12 83 A4 47 11 03 A4 89 01 63 9A +84 14 83 A4 87 11 03 A4 C9 01 63 92 84 14 83 A4 +C7 11 03 A4 09 02 63 9A 84 12 83 A4 07 12 03 A4 +49 02 63 92 84 12 83 A4 47 12 03 A4 89 02 63 96 +84 10 83 A4 87 12 03 A4 C9 02 63 9C 84 0E 83 A4 +C7 12 03 A4 09 03 63 9C 84 0E 83 A4 07 13 03 A4 +49 03 63 92 84 10 83 A4 47 13 03 A4 89 03 63 9C +84 0C 83 A4 87 13 03 A4 C9 03 63 9C 84 0C 83 A4 +C7 13 03 A4 09 04 BD 45 63 90 84 02 F2 40 62 44 +D2 44 42 49 B2 49 22 4A 92 4A 02 4B 05 61 82 80 +E9 47 1C C9 D9 B5 81 45 83 27 CA C5 89 49 63 E8 +F9 04 05 45 EF 60 AF AB 01 A0 4C 4B 10 4B 31 65 +13 05 C5 6B EF 60 AF AE 83 27 CA C5 E3 7D F4 EE +37 55 02 50 13 05 85 F5 EF 60 6F AB ED B5 37 55 +02 50 13 05 05 D6 EF 60 8F AA 65 B5 37 55 02 50 +13 05 85 E5 EF 60 AF A9 03 28 CA C5 B5 BB 31 69 +13 09 C9 6B 13 05 C9 0E EF 60 6F AA 83 27 CA C5 +E3 F1 F9 FA A6 85 13 05 89 11 EF 60 4F A9 83 27 +CA C5 E3 F8 F9 F8 A2 85 13 05 09 13 EF 60 2F A8 +49 B7 85 45 95 BF 91 45 85 BF 8D 45 B5 B7 89 45 +A5 B7 A9 45 95 B7 B5 45 85 B7 A5 45 B1 BF AD 45 +A1 BF B9 45 91 BF A1 45 81 BF 9D 45 B1 B7 99 45 +A1 B7 95 45 91 B7 B1 45 81 B7 01 00 52 65 63 65 +69 76 65 64 20 48 4D 41 43 20 6E 6F 74 69 66 2F +65 72 72 20 69 6E 74 72 20 77 69 74 68 20 73 74 +61 74 75 73 20 3D 20 25 64 2F 20 25 64 0A 00 00 +41 74 20 6F 66 66 73 65 74 20 5B 25 64 5D 2C 20 +68 6D 61 63 5F 74 61 67 20 64 61 74 61 20 6D 69 +73 6D 61 74 63 68 21 0A 00 00 00 00 41 63 74 75 +61 6C 20 20 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 45 78 70 65 63 74 65 64 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 41 74 20 6F +66 66 73 65 74 20 5B 25 64 5D 2C 20 68 6D 61 63 +5F 74 61 67 20 64 61 74 61 20 6D 69 73 6D 61 74 +63 68 21 0A 00 00 00 00 41 63 74 75 61 6C 20 20 +20 64 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +45 78 70 65 63 74 65 64 20 64 61 74 61 3A 20 30 +78 25 78 0A 00 00 00 00 41 74 20 6F 66 66 73 65 +74 20 5B 25 64 5D 2C 20 68 6D 61 63 5F 74 61 67 +20 64 61 74 61 20 6D 69 73 6D 61 74 63 68 21 0A +00 00 00 00 41 63 74 75 61 6C 20 20 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 45 78 70 65 +63 74 65 64 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 B7 37 02 50 03 A7 C7 C5 41 11 22 C4 +06 C6 8D 47 2A 84 63 EC E7 00 B7 67 00 04 3E 94 +0A 04 91 47 B2 40 1C C0 22 44 41 01 82 80 AA 85 +35 65 13 05 C5 9F EF 60 8F 8C C5 B7 B7 37 02 50 +03 A7 C7 C5 41 11 22 C4 06 C6 8D 47 2A 84 63 EA +E7 00 1C 40 93 F7 C7 3F 99 EF B2 40 22 44 41 01 +82 80 37 55 02 50 13 05 85 F9 EF 60 4F 87 1C 40 +93 F7 C7 3F FD D3 37 55 02 50 13 05 05 FB EF 60 +0F 86 22 44 B2 40 05 45 41 01 6F 60 4F 83 B7 37 +02 50 03 A7 C7 C5 41 11 22 C4 06 C6 8D 47 2A 84 +63 EA E7 00 1C 40 93 F7 C7 3F 99 CF B2 40 22 44 +41 01 82 80 37 55 02 50 13 05 C5 FB EF 60 2F 82 +1C 40 93 F7 C7 3F FD F3 37 55 02 50 13 05 85 FD +EF 60 EF 80 22 44 B2 40 05 45 41 01 6F 50 3F FE +B7 37 02 50 03 A7 C7 C5 41 11 22 C4 26 C2 06 C6 +8D 47 AA 84 2E 84 63 ED E7 00 06 04 13 74 E4 03 +13 64 14 00 80 C0 B2 40 22 44 92 44 41 01 82 80 +37 55 02 50 13 05 45 FE EF 50 7F FC F9 BF B7 37 +02 50 03 A7 C7 C5 41 11 22 C4 26 C2 4A C0 06 C6 +8D 47 2A 89 AE 84 32 84 63 EB E7 06 93 77 14 00 +13 17 64 00 13 77 07 08 93 95 14 00 9A 07 D9 8F +93 F5 E5 03 13 17 64 00 13 77 07 10 93 16 64 00 +CD 8F D9 8F 93 F6 06 20 13 17 64 00 13 56 54 00 +D5 8F 13 77 07 40 93 56 64 00 05 8A D9 8F 2E 06 +13 57 74 00 85 8A D1 8F B2 06 05 8B 21 80 D5 8F +36 07 05 88 3A 04 D9 8F B2 40 C1 8F 22 44 93 E7 +17 00 23 20 F9 00 92 44 02 49 41 01 82 80 37 55 +02 50 13 05 C5 FF EF 50 9F F2 49 B7 B7 37 02 50 +03 A7 C7 C5 41 11 22 C4 06 C6 8D 47 2A 84 63 EF +E7 00 06 04 13 74 E4 03 13 64 14 04 B7 07 02 10 +B2 40 23 A0 87 60 22 44 41 01 82 80 37 55 02 50 +13 05 45 01 EF 50 BF EE E9 BF 01 00 4B 56 3A 20 +63 6C 65 61 72 69 6E 67 20 4B 56 20 65 6E 74 72 +79 20 30 78 25 78 0A 00 00 00 00 00 08 41 B7 55 +02 50 41 11 93 85 C5 27 06 C6 EF 30 B0 53 B2 40 +33 35 A0 00 41 01 82 80 B7 35 02 50 93 85 85 EC +93 87 45 00 13 86 C5 20 01 47 94 43 63 65 D5 00 +D4 4B 63 69 D5 00 D1 07 05 07 E3 98 C7 FE 13 85 +85 20 82 80 93 17 27 00 BA 97 8A 07 33 85 F5 00 +82 80 01 11 22 CC 37 34 02 50 26 CA 4A C8 4E C6 +52 C4 06 CE 13 0A 84 EC 2A 89 13 04 84 EC 81 44 +ED 49 21 A0 85 04 63 8D 34 01 08 40 CA 85 51 04 +EF 30 50 4C 65 D9 13 95 24 00 26 95 0A 05 52 95 +F2 40 62 44 D2 44 42 49 B2 49 22 4A 05 61 82 80 +5C 45 63 C0 07 04 1C 49 63 CF 07 02 5C 49 63 CE +07 02 1C 4D 63 CD 07 02 5C 4D 63 CC 07 02 1C 51 +63 CB 07 02 5C 51 63 CA 07 02 1C 55 63 C9 07 02 +5C 55 63 C8 07 02 08 59 13 45 F5 FF 7D 81 25 05 +82 80 01 45 82 80 05 45 82 80 09 45 82 80 0D 45 +82 80 11 45 82 80 15 45 82 80 19 45 82 80 1D 45 +82 80 21 45 82 80 B7 67 02 50 0A 05 93 87 87 E7 +AA 97 94 43 05 47 33 17 B7 00 55 8F 98 C3 82 80 +01 11 4E C6 B7 39 02 50 83 A7 C9 C5 06 CE 22 CC +26 CA 4A C8 52 C4 56 C2 5A C0 09 47 63 6E F7 06 +37 39 02 50 B7 64 02 50 13 09 89 EC 93 84 84 E7 +01 44 09 4B B5 6A 6D 4A 63 62 FB 02 69 47 63 05 +E4 00 09 47 63 6B F7 02 F2 40 62 44 D2 44 42 49 +B2 49 22 4A 92 4A 02 4B 05 61 82 80 90 40 83 25 +09 00 13 85 4A C4 05 04 EF 50 7F D5 83 A7 C9 C5 +E3 09 44 FD 51 09 91 04 C1 B7 62 44 F2 40 D2 44 +42 49 B2 49 22 4A 92 4A 02 4B 37 55 02 50 13 05 +45 04 05 61 6F 50 BF D0 37 55 02 50 13 05 45 04 +EF 50 FF CF 83 A7 C9 C5 A5 BF 41 11 06 C6 EF 30 +70 37 B2 40 33 35 A0 00 41 01 82 80 63 52 B0 04 +01 11 22 CC 26 CA 4A C8 4E C6 06 CE 2E 89 AA 89 +2A 84 81 44 EF 30 40 77 B3 67 25 03 18 40 11 04 +85 04 8A 07 CE 97 94 43 23 2E D4 FE 98 C3 E3 13 +99 FE F2 40 62 44 D2 44 42 49 B2 49 05 61 82 80 +82 80 01 00 20 20 25 34 30 73 3A 20 30 78 25 2D +33 78 0A 00 00 00 00 00 01 11 4E C6 B7 39 02 50 +03 A7 C9 C5 22 CC 4A C8 06 CE 26 CA 89 47 2A 89 +2E 84 63 EB E7 06 B7 64 02 50 93 84 84 E2 9C 54 +E1 8F 63 8F 87 00 73 00 50 10 93 07 40 06 01 00 +FD 17 C2 07 C1 83 E5 FF 9C 54 E1 8F E3 95 87 FE +DC 54 B3 F7 27 01 E3 90 27 FF 83 A7 C9 C5 1D C0 +B9 E3 D4 54 13 47 F9 FF F2 40 75 8F D8 D4 98 54 +93 47 F4 FF 62 44 F9 8F 9C D4 42 49 D2 44 B2 49 +05 61 82 80 09 47 E3 7E F7 FC CC 54 35 65 13 05 +45 18 EF 50 DF C1 F1 B7 37 55 02 50 13 05 45 2F +EF 50 FF BE 49 B7 8C 54 35 65 13 05 85 15 EF 50 +1F C0 45 BF B7 37 02 50 03 A7 C7 C5 89 47 63 E7 +E7 00 B7 87 02 10 21 47 98 CB 82 80 37 55 02 50 +41 11 13 05 05 31 06 C6 EF 50 7F BB B2 40 B7 87 +02 10 21 47 98 CB 41 01 82 80 01 11 22 CC 26 CA +4A C8 52 C4 56 C2 3E 89 06 CE 4E C6 2E 84 B2 84 +36 8A BA 8A B7 87 02 10 98 4F 05 8B 75 DF 54 41 +B7 39 02 50 09 47 23 A0 D7 08 14 45 23 A2 D7 08 +54 45 23 A4 D7 08 14 49 23 A6 D7 08 54 49 23 A8 +D7 08 14 4D 23 AA D7 08 54 4D 23 AC D7 08 14 51 +23 AE D7 08 54 51 23 A0 D7 0A 14 55 23 A2 D7 0A +54 55 23 A4 D7 0A 14 59 23 A6 D7 0A 54 59 23 A8 +D7 0A 14 5D 23 AA D7 0A 54 5D 23 AC D7 0A 34 41 +23 AE D7 0A 03 A6 C9 C5 63 66 C7 0E 93 17 24 00 +13 97 9A 00 13 77 07 20 91 8B 93 16 5A 00 D9 8F +93 F6 06 1E 13 97 44 00 41 8B D5 8F D9 8F 93 E7 +17 00 37 87 02 10 1C CB 89 47 63 E4 C7 10 37 64 +02 50 13 04 84 E2 1C 54 5C 54 85 8B 9D E3 73 00 +50 10 93 07 40 06 01 00 FD 17 C2 07 C1 83 E5 FF +1C 54 5C 54 85 8B E5 D7 83 A7 C9 C5 89 44 63 E4 +F4 0A 5C 54 F9 9B 5C D4 1C 54 1C D4 B7 87 02 10 +83 A4 07 10 03 24 49 00 63 9F 84 06 83 A4 47 10 +03 24 89 00 63 93 84 10 83 A4 87 10 03 24 C9 00 +63 99 84 0E 83 A4 C7 10 03 24 09 01 63 9D 84 0E +83 A4 07 11 03 24 49 01 63 95 84 0E 83 A4 47 11 +03 24 89 01 63 9D 84 0C 83 A4 87 11 03 24 C9 01 +63 93 84 0C 83 A4 C7 11 03 24 09 02 9D 45 63 95 +84 02 F2 40 62 44 D2 44 42 49 B2 49 22 4A 92 4A +05 61 82 80 37 55 02 50 13 05 85 32 EF 50 3F A2 +03 A6 C9 C5 21 B7 81 45 83 A7 C9 C5 B9 EB 05 45 +EF 50 FF 9E 01 A0 4C 54 35 65 13 05 45 18 EF 50 +1F A2 5C 54 03 A7 C9 C5 F9 9B 5C D4 1C 54 1C D4 +E3 F6 E4 F4 37 55 02 50 13 05 85 33 EF 50 3F 9E +35 BF 37 55 02 50 13 05 45 2F 37 64 02 50 EF 50 +1F 9D 13 04 84 E2 1C 54 5C 54 85 8B E3 89 07 EE +21 B7 35 69 13 09 89 15 13 05 C9 05 EF 50 3F 9D +83 A7 C9 C5 C9 DF A6 85 13 05 89 08 EF 50 3F 9C +83 A7 C9 C5 C9 D7 A2 85 13 05 09 0A EF 50 3F 9B +BD BF 89 45 95 BF 99 45 85 BF 85 45 B5 B7 95 45 +A5 B7 91 45 95 B7 8D 45 85 B7 01 11 22 CC 26 CA +4A C8 4E C6 52 C4 56 C2 06 CE 5A C0 AE 84 32 84 +36 89 BA 89 3E 8A C6 8A 37 83 02 10 03 28 83 01 +13 78 18 00 E3 0C 08 FE 58 41 93 87 FA FF 93 B7 +17 00 23 20 E3 08 18 45 37 3B 02 50 E1 8F 23 22 +E3 08 58 45 23 24 E3 08 18 49 23 26 E3 08 58 49 +23 28 E3 08 18 4D 23 2A E3 08 58 4D 23 2C E3 08 +18 51 23 2E E3 08 58 51 23 20 E3 0A 18 55 23 22 +E3 0A 58 55 23 24 E3 0A 18 59 23 26 E3 0A 58 59 +23 28 E3 0A 18 5D 23 2A E3 0A 58 5D 23 2C E3 0A +38 41 23 2E E3 0A 83 26 CB C5 B5 C3 89 47 63 E9 +D7 08 05 45 EF 50 BF 8A 03 27 CB C5 89 47 63 EA +E7 06 06 04 26 0A 93 77 24 00 13 7A 0A 20 96 09 +B3 E7 47 01 93 F9 09 1E 12 09 B3 E7 37 01 13 79 +09 01 8A 04 B3 E7 27 01 91 88 62 44 C5 8F F2 40 +D2 44 42 49 B2 49 22 4A 02 4B 93 E7 17 00 37 87 +02 10 D6 85 92 4A 1C CB 01 45 05 61 F5 B6 13 87 +EA FF 93 47 F4 FF 13 37 17 00 F9 8F D1 DF 89 47 +E3 F9 D7 F8 37 55 02 50 13 05 85 3C EF 50 3F 85 +49 B7 37 55 02 50 13 05 85 32 EF 50 5F 84 51 B7 +37 55 02 50 13 05 85 35 EF 50 7F 83 9D B7 41 11 +06 C6 22 C4 26 C2 37 87 02 10 1C 4F 85 8B F5 DF +B7 34 02 50 83 A7 C4 C5 09 44 63 66 F4 04 37 64 +02 50 13 04 84 E2 1C 54 5C 54 85 8B 9D E3 73 00 +50 10 93 07 40 06 01 00 FD 17 C2 07 C1 83 E5 FF +1C 54 5C 54 85 8B E5 D7 03 A7 C4 C5 89 47 63 E5 +E7 04 5C 54 B2 40 92 44 F9 9B 5C D4 1C 54 1C D4 +22 44 41 01 82 80 37 55 02 50 13 05 85 32 EF 50 +0F FC 83 A7 C4 C5 E3 74 F4 FA 37 55 02 50 13 05 +45 2F 37 64 02 50 EF 50 8F FA 13 04 84 E2 1C 54 +5C 54 85 8B C9 DF 4D BF 4C 54 35 65 13 05 45 18 +EF 50 EF FA 7D B7 01 00 52 65 63 65 69 76 65 64 +20 53 48 41 32 35 36 20 65 72 72 20 69 6E 74 72 +20 77 69 74 68 20 73 74 61 74 75 73 20 3D 20 25 +64 0A 00 00 52 65 63 65 69 76 65 64 20 53 48 41 +32 35 36 20 6E 6F 74 69 66 20 69 6E 74 72 20 77 +69 74 68 20 73 74 61 74 75 73 20 3D 20 25 64 0A +00 00 00 00 41 74 20 6F 66 66 73 65 74 20 5B 25 +64 5D 2C 20 73 68 61 5F 64 69 67 65 73 74 20 64 +61 74 61 20 6D 69 73 6D 61 74 63 68 21 0A 00 00 +41 63 74 75 61 6C 20 20 20 64 61 74 61 3A 20 30 +78 25 78 0A 00 00 00 00 45 78 70 65 63 74 65 64 +20 64 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +41 11 22 C4 37 34 02 50 03 27 C4 C5 06 C6 89 47 +63 E0 E7 04 37 67 02 50 13 07 87 E2 1C 53 54 53 +D5 8F 9D E3 73 00 50 10 93 07 40 06 01 00 FD 17 +C2 07 C1 83 E5 FF 1C 53 54 53 D5 8F E5 D7 83 26 +C4 C5 89 47 63 E5 D7 02 B2 40 22 44 41 01 82 80 +37 55 02 50 13 05 05 42 EF 50 6F E7 37 67 02 50 +13 07 87 E2 1C 53 54 53 D5 8F CD DF C9 BF 22 44 +B2 40 4C 53 39 65 13 05 85 8E 41 01 6F 50 2F E7 +B7 37 02 50 03 A7 C7 C5 41 11 22 C4 06 C6 8D 47 +2A 84 63 ED E7 00 0A 04 31 88 13 64 14 00 B7 07 +02 10 B2 40 80 CB 22 44 41 01 82 80 AA 85 39 65 +13 05 85 91 EF 50 AF E3 F9 BF B7 37 02 50 03 A7 +C7 C5 41 11 22 C4 06 C6 8D 47 2A 84 63 ED E7 00 +0A 04 31 88 13 64 24 00 B7 07 02 10 B2 40 80 CB +22 44 41 01 82 80 AA 85 39 65 13 05 C5 93 EF 50 +0F E0 F9 BF B7 37 02 50 03 A7 C7 C5 41 11 22 C4 +06 C6 8D 47 2A 84 63 ED E7 00 0A 04 31 88 13 64 +14 02 B7 07 02 10 B2 40 80 CB 22 44 41 01 82 80 +AA 85 39 65 13 05 05 96 EF 50 6F DC F9 BF B7 37 +02 50 03 A7 C7 C5 41 11 22 C4 06 C6 8D 47 2A 84 +63 ED E7 00 0A 04 31 88 13 64 24 02 B7 07 02 10 +B2 40 80 CB 22 44 41 01 82 80 AA 85 39 65 13 05 +C5 98 EF 50 CF D8 F9 BF B7 37 02 50 03 A7 C7 C5 +8D 47 63 E8 E7 00 B7 07 02 10 05 47 23 A8 E7 62 +82 80 37 55 02 50 41 11 13 05 C5 43 06 C6 EF 50 +0F D4 B2 40 B7 07 02 10 05 47 23 A8 E7 62 41 01 +82 80 B7 37 02 50 03 A7 C7 C5 89 47 63 E7 E7 00 +B7 07 02 10 41 47 98 CB 82 80 37 55 02 50 41 11 +13 05 05 46 06 C6 EF 50 8F D0 B2 40 B7 07 02 10 +41 47 98 CB 41 01 82 80 01 11 22 CC 4A C8 06 CE +26 CA 4E C6 52 C4 2E 84 32 89 B7 07 02 10 98 4F +05 8B 75 DF B7 04 02 10 37 06 FE EF 93 87 07 08 +13 06 06 F8 93 85 04 10 BE 86 91 07 33 87 C7 00 +2A 97 18 43 98 C2 E3 99 B7 FE B7 39 02 50 83 A7 +C9 C5 09 4A 63 66 FA 14 93 17 24 00 B1 8B 93 E7 +17 00 9C C8 37 67 02 50 13 07 87 E2 1C 53 54 53 +D5 8F 9D E3 73 00 50 10 93 07 40 06 01 00 FD 17 +C2 07 C1 83 E5 FF 1C 53 54 53 D5 8F E5 D7 83 A7 +C9 C5 09 44 63 65 F4 0E B7 07 02 10 83 A4 07 10 +03 24 49 00 63 15 94 0C 83 A4 47 10 03 24 89 00 +63 92 84 16 83 A4 87 10 03 24 C9 00 63 9A 84 14 +83 A4 C7 10 03 24 09 01 63 9A 84 14 83 A4 07 11 +03 24 49 01 63 92 84 14 83 A4 47 11 03 24 89 01 +63 96 84 14 83 A4 87 11 03 24 C9 01 63 9A 84 14 +83 A4 C7 11 03 24 09 02 63 92 84 14 83 A4 07 12 +03 24 49 02 63 9A 84 12 83 A4 47 12 03 24 89 02 +63 92 84 12 83 A4 87 12 03 24 C9 02 63 96 84 10 +83 A4 C7 12 03 24 09 03 63 9C 84 0E 83 A4 07 13 +03 24 49 03 63 98 84 10 83 A4 47 13 03 24 89 03 +63 92 84 0E 83 A4 87 13 03 24 C9 03 63 92 84 0E +83 A4 C7 13 03 24 09 04 BD 45 63 9B 84 00 F2 40 +62 44 D2 44 42 49 B2 49 22 4A 05 61 82 80 81 45 +83 A7 C9 C5 B5 E7 05 45 EF 50 6F B6 01 A0 4C 53 +39 65 13 05 85 8E EF 50 8F B9 83 A7 C9 C5 E3 75 +F4 F0 37 55 02 50 13 05 85 48 EF 50 4F B6 ED BD +37 55 02 50 13 05 85 47 EF 50 6F B5 93 17 24 00 +03 A7 C9 C5 B1 8B 93 E7 17 00 9C C8 E3 74 EA EA +37 55 02 50 13 05 05 42 EF 50 6F B3 37 67 02 50 +13 07 87 E2 1C 53 54 53 D5 8F E3 8D 07 E8 45 BD +39 69 13 09 89 8E 13 05 09 0D EF 50 4F B3 83 A7 +C9 C5 D1 D3 A6 85 13 05 C9 0F EF 50 4F B2 83 A7 +C9 C5 B5 DB A2 85 13 05 49 11 EF 50 4F B1 A5 B7 +89 45 B9 BF 85 45 A9 BF 91 45 99 BF 8D 45 89 BF +AD 45 B9 B7 B5 45 A9 B7 A9 45 99 B7 95 45 89 B7 +B9 45 3D BF A5 45 2D BF A1 45 1D BF 9D 45 0D BF +99 45 3D B7 B1 45 2D B7 01 11 26 CA 4A C8 06 CE +22 CC 4E C6 52 C4 AE 84 32 88 36 89 B7 07 02 10 +98 4F 05 8B 75 DF 37 04 02 10 37 06 FE EF 93 87 +07 08 13 06 06 F8 93 05 04 10 BE 86 91 07 33 87 +C7 00 2A 97 18 43 98 C2 E3 99 B7 FE 03 27 48 00 +B7 39 02 50 09 4A 98 C3 83 27 88 00 23 22 F4 10 +83 27 C8 00 23 24 F4 10 83 27 08 01 23 26 F4 10 +83 27 48 01 23 28 F4 10 83 27 88 01 23 2A F4 10 +83 27 C8 01 23 2C F4 10 83 27 08 02 23 2E F4 10 +83 27 48 02 23 20 F4 12 83 27 88 02 23 22 F4 12 +83 27 C8 02 23 24 F4 12 83 27 08 03 23 26 F4 12 +83 27 48 03 23 28 F4 12 83 27 88 03 23 2A F4 12 +83 27 C8 03 23 2C F4 12 83 27 08 04 23 2E F4 12 +83 A7 C9 C5 63 66 FA 14 93 97 24 00 B1 8B 93 E7 +27 04 1C C8 37 67 02 50 13 07 87 E2 1C 53 54 53 +D5 8F 9D E3 73 00 50 10 93 07 40 06 01 00 FD 17 +C2 07 C1 83 E5 FF 1C 53 54 53 D5 8F E5 D7 83 A7 +C9 C5 09 44 63 65 F4 0E B7 07 02 10 83 A4 07 10 +03 24 49 00 63 95 84 0C 83 A4 47 10 03 24 89 00 +63 92 84 16 83 A4 87 10 03 24 C9 00 63 9A 84 14 +83 A4 C7 10 03 24 09 01 63 9A 84 14 83 A4 07 11 +03 24 49 01 63 92 84 14 83 A4 47 11 03 24 89 01 +63 96 84 14 83 A4 87 11 03 24 C9 01 63 9A 84 14 +83 A4 C7 11 03 24 09 02 63 92 84 14 83 A4 07 12 +03 24 49 02 63 9A 84 12 83 A4 47 12 03 24 89 02 +63 92 84 12 83 A4 87 12 03 24 C9 02 63 96 84 10 +83 A4 C7 12 03 24 09 03 63 9C 84 0E 83 A4 07 13 +03 24 49 03 63 98 84 10 83 A4 47 13 03 24 89 03 +63 92 84 0E 83 A4 87 13 03 24 C9 03 63 92 84 0E +83 A4 C7 13 03 24 09 04 BD 45 63 9B 84 00 F2 40 +62 44 D2 44 42 49 B2 49 22 4A 05 61 82 80 81 45 +83 A7 C9 C5 B5 E7 05 45 EF 50 6F 8A 01 A0 4C 53 +39 65 13 05 85 8E EF 50 8F 8D 83 A7 C9 C5 E3 75 +F4 F0 37 55 02 50 13 05 85 48 EF 50 4F 8A ED BD +37 55 02 50 13 05 85 47 EF 50 6F 89 93 97 24 00 +03 A7 C9 C5 B1 8B 93 E7 27 04 1C C8 E3 74 EA EA +37 55 02 50 13 05 05 42 EF 50 6F 87 37 67 02 50 +13 07 87 E2 1C 53 54 53 D5 8F E3 8D 07 E8 45 BD +39 69 13 09 89 8E 13 05 C9 12 EF 50 4F 87 83 A7 +C9 C5 D1 D3 A6 85 13 05 89 15 EF 50 4F 86 83 A7 +C9 C5 B5 DB A2 85 13 05 09 17 EF 50 4F 85 A5 B7 +89 45 B9 BF 85 45 A9 BF 91 45 99 BF 8D 45 89 BF +AD 45 B9 B7 B5 45 A9 B7 A9 45 99 B7 95 45 89 B7 +B9 45 3D BF A5 45 2D BF A1 45 1D BF 9D 45 0D BF +99 45 3D B7 B1 45 2D B7 52 65 63 65 69 76 65 64 +20 53 48 41 35 31 32 20 6E 6F 74 69 66 20 69 6E +74 72 20 77 69 74 68 20 73 74 61 74 75 73 20 3D +20 25 64 0A 00 00 00 00 53 48 41 35 31 32 3A 20 +53 65 74 20 6D 6F 64 65 3A 20 30 78 25 78 20 61 +6E 64 20 69 6E 69 74 0A 00 00 00 00 53 48 41 35 +31 32 3A 20 53 65 74 20 6D 6F 64 65 3A 20 30 78 +25 78 20 61 6E 64 20 6E 65 78 74 0A 00 00 00 00 +53 48 41 35 31 32 3A 20 53 65 74 20 6D 6F 64 65 +3A 20 30 78 25 78 20 61 6E 64 20 69 6E 69 74 20 +77 69 74 68 20 6C 61 73 74 0A 00 00 53 48 41 35 +31 32 3A 20 53 65 74 20 6D 6F 64 65 3A 20 30 78 +25 78 20 61 6E 64 20 6E 65 78 74 20 77 69 74 68 +20 6C 61 73 74 0A 00 00 41 74 20 6F 66 66 73 65 +74 20 5B 25 64 5D 2C 20 73 68 61 5F 64 69 67 65 +73 74 20 64 61 74 61 20 6D 69 73 6D 61 74 63 68 +21 0A 00 00 41 63 74 75 61 6C 20 20 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 45 78 70 65 +63 74 65 64 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 41 74 20 6F 66 66 73 65 74 20 5B 25 +64 5D 2C 20 73 68 61 5F 64 69 67 65 73 74 20 64 +61 74 61 20 6D 69 73 6D 61 74 63 68 21 0A 00 00 +41 63 74 75 61 6C 20 20 20 64 61 74 61 3A 20 30 +78 25 78 0A 00 00 00 00 45 78 70 65 63 74 65 64 +20 64 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +85 47 B3 95 B7 00 71 05 1C 41 ED 8F F5 DF 82 80 +41 11 06 C6 AA 86 2E 87 B2 87 01 CD 01 CE 13 06 +00 02 63 7F B6 04 B7 37 02 50 83 A7 C7 C5 B1 E3 +01 A0 99 C5 B7 37 02 50 83 A7 C7 C5 85 E7 01 A0 +01 46 ED DB 93 05 27 00 CC D3 85 45 23 80 B7 00 +A3 80 C7 00 B2 40 13 85 27 00 3A 86 B6 85 41 01 +6F 20 80 6B 37 55 02 50 13 05 85 4A EF 40 3F E0 +F9 B7 37 55 02 50 13 05 C5 4F EF 40 5F DF 4D BF +13 96 35 00 42 06 41 82 93 05 00 10 63 15 B6 02 +13 06 37 00 D0 D3 09 46 23 80 C7 00 05 46 A3 80 +C7 00 23 81 07 00 B2 40 13 85 37 00 3A 86 B6 85 +41 01 6F 20 60 66 13 76 F6 0F 69 B7 41 11 06 C6 +B2 87 19 C9 19 CA 11 47 63 70 B7 02 B7 37 02 50 +83 A7 C7 C5 B9 E3 01 A0 99 C5 B7 37 02 50 83 A7 +C7 C5 8D E7 01 A0 75 DA 93 86 25 00 13 97 35 00 +94 C7 85 46 23 80 D7 00 A3 80 E7 00 B2 40 2E 86 +AA 85 41 01 13 85 27 00 6F 20 00 61 37 55 02 50 +13 05 45 54 EF 40 BF D5 F1 B7 37 55 02 50 13 05 +85 58 EF 40 DF D4 45 BF 41 11 06 C6 29 C5 A1 C5 +89 47 63 0A F6 08 63 ED C7 04 51 CA 5C 4D 21 47 +13 06 20 02 D8 C5 23 A2 05 00 90 C5 85 8B 11 48 +13 07 C5 01 A9 CF A2 06 23 90 05 00 B3 E7 06 01 +5C C9 5C C9 5C 49 F5 47 1C CD 1C 43 89 8B F5 DF +B2 40 41 01 82 80 B7 37 02 50 83 A7 C7 C5 91 E3 +01 A0 37 55 02 50 13 05 85 5C EF 40 5F CE CD BF +8D 47 63 14 F6 02 49 46 41 47 21 48 5C 4D D8 C5 +23 A2 05 00 90 C5 85 8B 13 07 C5 01 CD F7 B7 37 +02 50 83 A7 C7 C5 8D E3 01 A0 B7 37 02 50 83 A7 +C7 C5 95 E3 01 A0 69 46 31 47 19 48 C1 BF 13 06 +40 02 1D 47 09 48 D9 B7 37 55 02 50 13 05 85 63 +EF 40 FF C8 D1 BF 37 55 02 50 13 05 85 60 EF 40 +1F C8 C9 BF 41 11 06 C6 0D C5 85 C5 31 C6 85 47 +63 1E F6 02 5C 4D 13 07 20 02 98 C5 85 8B 11 46 +13 07 C5 01 B1 E3 B7 37 02 50 83 A7 C7 C5 AD EB +01 A0 B7 37 02 50 83 A7 C7 C5 91 E3 01 A0 37 55 +02 50 13 05 C5 66 EF 40 9F C3 CD BF B7 37 02 50 +83 A7 C7 C5 9D EF 01 A0 5C 4D 13 07 A0 02 98 C5 +85 8B 13 07 C5 01 E1 D3 93 97 86 00 D1 8F 23 90 +05 00 23 A6 05 00 23 A2 05 00 93 E7 07 02 5C C9 +5C C9 F5 47 1C CD 1C 43 89 8B F5 DF B2 40 41 01 +82 80 37 55 02 50 13 05 85 6B EF 40 5F BE 65 BF +37 55 02 50 13 05 C5 6E EF 40 7F BD 51 B7 5D 71 +86 C6 A2 C4 A6 C2 CA C0 15 CD 8D CD 2A 84 B1 CE +03 D8 06 00 05 45 63 0A A8 04 25 CE 05 45 63 10 +A6 04 13 08 20 02 11 46 48 4C 23 A4 05 01 93 04 +C4 01 05 89 35 E1 B7 37 02 50 83 A7 C7 C5 63 95 +07 10 01 A0 B7 37 02 50 83 A7 C7 C5 91 E3 01 A0 +37 55 02 50 13 05 05 72 EF 40 7F B7 CD BF B7 37 +02 50 83 A7 C7 C5 F1 EB 01 A0 11 C7 03 58 07 00 +05 45 E3 14 A8 FA 63 06 06 10 05 47 63 19 E6 0A +BE 86 05 46 22 85 26 44 B6 40 96 44 06 49 61 61 +D1 B5 13 08 A0 02 49 BF A2 07 D1 8F 23 90 05 00 +23 A6 05 00 23 A2 05 00 93 E7 07 03 5C C8 5C C8 +02 CA 02 CC 02 CE 02 D0 02 D2 02 D4 02 D6 02 D8 +02 DA 02 DC 02 DE 91 C6 03 A9 86 00 89 47 63 E8 +27 09 85 47 23 1A F1 00 13 05 61 01 19 C3 50 53 +3D EA 85 47 23 00 F5 00 A3 00 05 00 D2 47 1C D0 +E2 47 5C D0 F2 47 1C D4 82 57 5C D4 92 57 1C D8 +A2 57 5C D8 B2 57 1C DC C2 57 5C DC D2 57 3C C0 +E2 57 7C C0 F2 57 3C C4 F5 47 1C CC 9C 40 89 8B +F5 DF B6 40 26 44 96 44 06 49 61 61 82 80 B7 37 +02 50 83 A7 C7 C5 9D EF 01 A0 37 55 02 50 13 05 +C5 7A EF 40 DF A8 0D B7 37 55 02 50 13 05 85 7E +EF 40 FF A7 FD B5 BA 85 EF 20 00 32 41 BF 4A 86 +B6 85 48 08 3A C6 EF 20 20 31 5C 08 32 47 33 85 +27 01 AD B7 37 55 02 50 13 05 45 76 EF 40 3F A5 +65 BF BE 86 01 46 FD BD 41 11 06 C6 19 C3 23 20 +07 00 4D C1 C5 C1 51 CE 9C 45 D5 CB 5C 4D 13 03 +C5 01 89 8B E5 C3 29 4F B7 18 04 10 85 4E 8D 4F +B5 CE 03 28 03 00 13 58 88 00 13 78 F8 01 33 08 +0F 41 0E 08 63 F3 06 01 36 88 63 0B 08 04 93 77 +16 00 C1 E7 B2 87 42 8E 63 00 D8 05 93 F5 37 00 +C1 E9 3E 85 63 F1 CF 03 13 05 CE FF 71 99 11 05 +3E 95 8C 43 91 07 23 A0 B8 80 E3 9C A7 FE 13 7E +3E 00 63 F5 CE 0B 83 55 05 00 79 1E 93 07 25 00 +23 90 B8 80 63 06 0E 00 83 C7 07 00 23 80 F8 80 +42 96 B3 86 06 41 49 D7 23 20 07 01 B2 40 41 01 +82 80 BD D2 B7 37 02 50 83 A7 C7 C5 91 E3 01 A0 +37 65 02 50 13 05 45 82 EF 40 7F 98 CD BF B7 37 +02 50 83 A7 C7 C5 8D EF 01 A0 83 45 06 00 13 0E +F8 FF 93 07 16 00 23 80 B8 80 E3 E9 CE F7 5D B7 +83 D5 07 00 79 1E 89 07 23 90 B8 80 E3 E6 CF F7 +3E 85 41 B7 B7 37 02 50 83 A7 C7 C5 89 EB 01 A0 +37 65 02 50 13 05 05 86 EF 40 7F 93 75 BF 37 65 +02 50 13 05 45 89 EF 40 9F 92 D5 B7 AA 87 9D B7 +41 11 06 C6 22 C4 61 C5 F9 C1 69 C2 19 C3 23 20 +07 00 03 C8 05 00 63 1A 08 08 03 C8 15 00 63 0F +08 06 83 A8 C5 00 13 03 F0 0F 05 48 96 08 63 7F +13 05 41 68 33 B8 08 01 37 03 00 01 13 48 18 00 +33 B3 68 00 13 43 13 00 09 08 1A 98 13 03 F8 FF +0E 03 B3 DE 68 00 93 FE FE 0F 37 1E 04 10 23 00 +DE 81 61 13 9D 4E 63 D1 6E 02 33 D3 68 00 13 73 +F3 0F 23 00 6E 80 11 43 63 18 68 00 13 D3 88 00 +13 73 F3 0F 23 00 6E 80 13 78 F8 0F 37 13 04 10 +93 F8 F8 0F 23 00 13 81 23 00 03 81 05 48 23 80 +05 01 13 08 E0 02 23 2C 05 01 03 A8 C5 00 63 0D +08 02 83 A8 45 00 B3 08 18 41 63 F7 D8 02 B7 37 +02 50 83 A7 C7 C5 63 99 07 14 01 A0 A1 D2 B7 37 +02 50 83 A7 C7 C5 91 E3 01 A0 37 65 02 50 13 05 +85 8C EF 40 DF 83 CD BF E1 C2 83 A8 85 00 93 02 +C5 01 93 03 10 03 C0 41 B3 8E 88 40 63 10 08 02 +63 F3 D6 01 B6 8E 63 90 0E 04 23 2C 75 00 23 A2 +05 00 C0 41 B3 8E 88 40 E3 04 08 FE 63 6E 18 01 +63 ED D6 09 63 91 0E 02 63 94 08 09 B7 37 02 50 +83 A7 C7 C5 F9 EB 01 A0 B3 0E 88 40 63 F3 D6 01 +B6 8E E3 85 0E FE 03 A8 02 00 13 78 48 00 E3 0C +08 FE B7 0F 01 04 93 8F 0F 10 A2 9F 8A 0F 7E 88 +01 4E 03 2F 08 00 03 23 08 10 B3 08 F8 41 B2 98 +33 43 E3 01 23 A0 68 00 05 0E 11 08 E3 13 DE FF +72 94 13 18 2E 00 C0 C1 42 96 B3 86 C6 41 11 C7 +03 28 07 00 72 98 23 20 07 01 95 E3 91 C6 03 A8 +C5 00 83 A8 85 00 81 BF B2 40 22 44 41 01 82 80 +33 08 18 41 23 A6 05 01 89 BF B6 8E A5 B7 83 A8 +85 00 B7 0E 01 04 93 8E 0E 10 C6 9E 13 08 20 03 +8A 0E B3 0F 18 41 E3 83 08 FD 76 88 01 4E 03 2F +08 00 03 23 08 10 B3 08 D8 41 BE 98 33 43 E3 01 +23 A0 68 00 05 0E 11 08 E3 63 FE FF 11 48 63 84 +0F 00 13 98 2F 00 C2 97 51 BF 37 65 02 50 13 05 +05 95 EF 40 CF F0 05 B7 37 65 02 50 13 05 C5 8F +EF 40 EF EF 5D B5 41 11 06 C6 1D C5 95 C5 83 C7 +05 00 A1 C3 13 07 C5 01 1C 43 91 8B F5 DF B2 40 +D9 47 1C CD 23 90 05 00 23 A2 05 00 23 A4 05 00 +23 A6 05 00 41 01 82 80 B7 37 02 50 83 A7 C7 C5 +91 E3 01 A0 37 65 02 50 13 05 85 98 EF 40 2F EB +CD BF B7 37 02 50 83 A7 C7 C5 91 E3 01 A0 37 65 +02 50 13 05 85 9B EF 40 8F E9 CD BF B7 07 02 30 +C8 4B 82 80 B7 07 04 30 3E 95 08 41 82 80 B7 07 +04 30 AA 97 8C C3 82 80 B7 37 02 50 03 A7 C7 C5 +8D 47 63 E8 E7 00 37 07 02 30 1C 4F F9 9B 1C CF +82 80 41 65 41 11 13 05 C5 A8 06 C6 EF 40 2F E7 +37 07 02 30 1C 4F B2 40 F9 9B 1C CF 41 01 82 80 +41 11 22 C4 37 34 02 50 83 27 C4 C5 26 C2 06 C6 +91 44 63 EF F4 02 B7 07 02 30 CC 4F 99 47 99 81 +9D 89 63 8F F5 04 B9 CD 9D 47 63 97 F5 00 83 27 +C4 C5 A5 EF 3D 45 01 A8 41 65 13 05 85 AA EF 40 +0F E2 13 05 F0 0F B2 40 22 44 92 44 41 01 82 80 +37 65 02 50 13 05 05 9F EF 40 6F DE B7 07 02 30 +CC 4F 99 47 99 81 9D 89 E3 9F F5 FA 83 27 C4 C5 +63 F8 F4 00 37 65 02 50 13 05 85 A1 EF 40 2F DC +01 45 D1 B7 03 27 C4 C5 85 47 63 E8 E7 00 05 45 +B2 40 22 44 92 44 41 01 82 80 37 65 02 50 13 05 +85 A5 EF 40 CF D9 05 45 E5 B7 37 65 02 50 13 05 +05 A9 EF 40 CF D8 3D 45 79 B7 B7 37 02 50 03 A7 +C7 C5 41 11 22 C4 06 C6 8D 47 2A 84 63 EC E7 00 +37 07 02 30 5C 4F B2 40 C1 9B C1 8F 22 44 5C CF +41 01 82 80 AA 85 41 65 13 05 C5 AE EF 40 2F D7 +C5 B7 B7 37 02 50 03 A7 C7 C5 41 11 22 C4 06 C6 +8D 47 2A 84 63 E6 E7 02 B7 07 03 30 D8 5F 93 17 +84 00 B3 66 E4 00 91 C7 B7 07 00 FF 7D 8F B3 66 +87 00 B2 40 22 44 B7 07 03 30 D4 DF 41 01 82 80 +AA 85 41 65 13 05 45 B1 EF 40 6F D2 F1 B7 B7 37 +02 50 03 A7 C7 C5 41 11 22 C4 06 C6 26 C2 8D 47 +2A 84 63 EC E7 04 B7 17 02 30 84 43 85 47 63 ED +87 02 63 E2 97 02 93 77 14 00 33 67 94 00 81 C7 +F9 98 33 E7 84 00 B2 40 22 44 B7 17 02 30 98 C3 +92 44 41 01 82 80 41 65 13 05 45 B9 EF 40 2F CD +05 45 EF 40 CF C8 C1 BF 41 65 13 05 85 B7 EF 40 +0F CC 05 45 EF 40 AF C7 7D BF AA 85 41 65 13 05 +C5 B3 EF 40 CF CA 45 B7 B7 37 02 50 03 A7 C7 C5 +41 11 22 C4 06 C6 8D 47 2A 84 63 E0 E7 04 B7 07 +03 30 DC 5F 13 17 84 00 19 CF 37 07 00 FF 79 8C +13 44 F4 FF 7D 8C 79 8C B7 07 03 30 B2 40 C0 DF +22 44 41 01 82 80 13 44 F4 FF 7D 8C B7 07 03 30 +B2 40 C0 DF 22 44 41 01 82 80 AA 85 41 65 13 05 +05 BB EF 40 CF C4 65 BF 09 CD 01 47 B7 06 02 30 +19 A0 63 08 E5 00 9C 42 05 07 85 8B FD FB 01 45 +82 80 05 45 82 80 79 71 4E CE B7 39 02 50 22 D4 +83 A7 C9 C5 37 04 02 30 26 D2 04 44 4A D0 06 D6 +52 CC 0D 49 63 6D F9 00 40 44 B2 50 22 85 22 54 +02 59 F2 49 62 4A A6 85 92 54 45 61 82 80 41 6A +13 0A CA A8 A6 85 13 05 CA 14 EF 40 4F BE 83 A7 +C9 C5 40 44 E3 7B F9 FC A2 85 13 05 0A 17 EF 40 +0F BD E1 B7 79 71 4A D0 37 39 02 50 03 27 C9 C5 +22 D4 26 D2 06 D6 4E CE 52 CC 2A C4 2E C6 89 47 +2A 84 AE 84 63 E9 E7 14 B7 07 04 00 63 EB 87 12 +B7 C7 5E BA 93 87 17 A1 63 82 F4 02 B7 D7 BE BA +93 87 E7 AF 63 80 F4 14 41 65 A6 85 13 05 45 C5 +EF 40 EF B7 05 45 EF 40 8F B3 01 A0 B7 04 00 50 +37 0A 00 40 37 07 02 30 50 4B 75 C2 13 07 06 02 +63 6F E4 0C 13 77 36 00 11 C3 11 06 37 07 02 30 +4C 4B 03 25 C9 C5 89 46 23 20 BA 00 03 28 47 01 +93 59 26 00 23 20 0A 01 58 4B 23 20 EA 00 63 E5 +A6 10 93 96 29 00 D2 87 D2 96 37 05 02 30 63 88 +09 00 58 49 91 07 23 AE E7 FE E3 9C D7 FE B7 07 +02 30 D8 4B 69 C7 93 77 C6 FF 93 06 07 02 B6 97 +63 6F F4 0A 93 77 37 00 91 C3 11 07 B7 07 02 30 +D0 4B 83 25 C9 C5 13 54 27 00 90 C0 D0 4B 89 46 +90 C0 D8 4B 98 C0 63 E2 B6 0C 63 0A 04 0C 13 17 +24 00 A6 87 26 97 37 06 02 30 54 4A 91 07 23 AE +D7 FE E3 1C F7 FE B7 07 02 30 23 A6 07 00 8D 47 +63 F8 B7 00 41 65 89 45 13 05 C5 AE EF 40 2F AA +37 07 02 30 5C 4F B2 50 22 54 C1 9B 93 E7 27 00 +5C CF 92 54 02 59 F2 49 62 4A 45 61 82 80 41 65 +A2 85 13 05 85 C8 EF 40 8F A7 05 45 EF 40 2F A3 +01 A0 41 65 A2 85 13 05 05 C2 EF 40 4F A6 05 45 +EF 40 EF A1 01 A0 37 65 02 50 13 05 85 AE EF 40 +0F A3 5D B5 B7 04 02 50 37 0A 02 40 E1 BD 01 14 +41 65 3A 86 B3 05 34 41 13 05 45 CE EF 40 2F A3 +05 45 EF 40 CF 9E 01 A0 37 65 02 50 13 05 85 B0 +32 C2 EF 40 CF 9F 12 46 ED B5 37 65 02 50 13 05 +C5 B1 EF 40 CF 9E 83 25 C9 C5 15 F8 A9 B7 23 A6 +07 00 B9 BF 79 71 4E CE B7 39 02 50 03 A7 C9 C5 +4A D0 06 D6 22 D4 26 D2 52 CC 56 CA 5A C8 2A C4 +2E C6 8D 47 2A 89 63 E6 E7 04 01 44 B7 04 00 40 +63 77 A4 02 B7 07 02 30 D8 4B 11 04 93 87 44 00 +98 C0 B3 05 F4 40 37 06 02 30 63 7A 24 01 54 4A +91 07 33 87 B7 00 23 AE D7 FE E3 6A 27 FF B2 50 +22 54 92 54 02 59 F2 49 62 4A D2 4A 42 4B 45 61 +82 80 37 65 02 50 01 44 13 05 05 B3 EF 40 2F 96 +E3 7F 24 FD C1 6A B7 04 00 40 0D 4B 93 8A 0A D4 +37 0A 02 30 11 A0 BA 84 83 A7 C9 C5 A6 85 56 85 +E3 7A FB F8 90 40 11 04 EF 40 6F 95 83 27 4A 01 +13 87 44 00 9C C0 E3 60 24 FF 55 B7 41 11 26 C2 +4A C0 06 C6 22 C4 B7 07 04 00 2A 89 AE 84 63 E0 +A7 06 D5 C4 81 47 37 07 02 30 19 A0 63 83 F4 06 +00 43 85 07 05 88 7D F8 B7 17 03 30 03 A6 87 80 +13 77 D6 FE 23 A4 E7 80 63 0C 09 00 81 47 B7 06 +04 30 33 87 D7 00 23 20 07 00 91 07 E3 EB 27 FF +B2 40 22 44 B7 07 02 30 05 47 98 D3 B7 17 03 30 +23 A4 C7 80 92 44 02 49 01 45 41 01 82 80 AA 85 +41 65 13 05 C5 D4 EF 40 8F 8C 05 45 EF 40 2F 88 +49 BF B7 37 02 50 03 A7 C7 C5 85 47 63 F8 E7 00 +37 65 02 50 13 05 45 B5 EF 40 6F 88 85 47 E3 85 +F4 F8 37 07 02 30 13 06 07 02 85 46 19 A0 E3 8D +84 F6 14 C2 1C 43 05 04 85 8B F5 FB B5 B7 B7 37 +02 50 03 A7 C7 C5 85 47 E3 F0 E7 F6 37 65 02 50 +13 05 45 B5 EF 40 AF 84 81 BF B7 37 02 50 03 A7 +C7 C5 41 11 22 C4 06 C6 8D 47 2A 84 63 FB E7 04 +95 47 63 FC A7 02 37 66 02 50 AA 85 41 65 13 06 +06 BA 13 05 05 D7 EF 40 8F 83 B7 07 03 30 23 A4 +87 62 37 07 03 30 83 27 47 62 B2 40 22 44 93 E7 +17 00 23 22 F7 62 41 01 82 80 29 C1 AA 85 37 66 +02 50 41 65 13 06 C6 B8 13 05 05 D7 EF 40 2F 80 +29 A0 61 D9 95 47 E3 E2 A7 FC B7 07 03 30 15 47 +23 A4 E7 62 37 07 03 30 83 27 47 62 B2 40 22 44 +93 E7 17 00 23 22 F7 62 41 01 82 80 37 66 02 50 +41 65 13 06 C6 B7 81 45 13 05 05 D7 EF 30 3F FC +37 07 03 30 83 27 47 62 B2 40 22 44 93 E7 17 00 +23 22 F7 62 41 01 82 80 B7 07 03 30 05 47 23 A0 +E7 62 82 80 37 17 02 30 1C 43 85 8B F5 FF 82 80 +0D 89 13 65 45 00 B7 17 02 30 88 C7 82 80 B7 17 +02 30 05 47 98 CF 82 80 B7 17 02 30 DC 4F 85 8B +89 EB B7 06 04 30 37 17 02 30 9C 42 5C 4F 85 8B +ED DF 82 80 B7 17 02 30 05 47 98 C3 82 80 B7 28 +02 30 03 A8 C8 00 13 78 18 00 E3 1C 08 FE 23 AE +A8 00 23 A0 B8 02 23 A2 E8 02 23 A4 F8 02 41 C6 +B7 07 00 12 85 07 37 26 02 30 1C C6 50 42 85 65 +FD 15 6D 8E 13 75 C7 FF 93 57 27 00 42 06 41 82 +36 95 37 27 02 30 99 CB 5C 47 91 83 ED 8F E3 8D +C7 FE 9C 42 91 06 5C D7 E3 98 A6 FE B7 27 02 30 +DC 47 05 47 37 26 02 30 93 F5 37 00 85 46 63 97 +E5 00 5C 46 13 F7 37 00 E3 0D D7 FE 89 8B 85 CB +B7 37 02 50 03 A7 C7 C5 41 11 06 C6 89 47 63 E1 +E7 02 B7 27 02 30 09 47 98 C7 05 45 EF 30 3F E7 +B2 40 41 01 82 80 B7 07 00 02 85 07 AD BF 82 80 +37 65 02 50 13 05 05 BB EF 30 7F E7 D9 BF 41 11 +06 C6 37 23 02 30 83 28 C3 00 93 F8 18 00 E3 9C +08 FE 23 2E A3 00 23 20 B3 02 23 22 E3 02 23 24 +F3 02 49 C2 B7 07 00 12 85 07 37 26 02 30 1C C6 +50 42 85 65 FD 15 6D 8E 13 75 C7 FF 93 57 27 00 +42 06 41 82 36 95 37 27 02 30 99 CB 5C 47 91 83 +ED 8F E3 8D C7 FE 9C 42 91 06 5C D7 E3 98 A6 FE +B7 27 02 30 DC 47 05 47 37 26 02 30 93 F5 37 00 +85 46 63 97 E5 00 5C 46 13 F7 37 00 E3 0D D7 FE +89 8B 8D C7 63 06 08 04 B7 37 02 50 03 A7 C7 C5 +89 47 63 E4 E7 04 B7 27 02 30 09 47 98 C7 B2 40 +41 01 82 80 B7 07 00 02 85 07 41 B7 E3 09 08 FE +37 65 02 50 13 05 05 C2 EF 30 7F DB B7 27 02 30 +09 47 98 C7 05 45 EF 30 9F D8 B2 40 41 01 82 80 +37 65 02 50 13 05 05 BE C5 B7 37 65 02 50 13 05 +05 BE EF 30 DF D8 45 BF 37 28 02 30 83 26 C8 00 +85 8A ED FE 23 2E A8 00 23 20 B8 02 23 22 E8 02 +23 24 F8 02 01 CA B7 07 00 12 85 07 37 27 02 30 +1C C7 82 80 B7 07 00 02 85 07 37 27 02 30 1C C7 +82 80 B7 27 02 30 DC 43 05 66 7D 16 F1 8F 13 F7 +C5 FF 13 D8 25 00 93 96 07 01 B3 05 E5 00 C1 82 +37 27 02 30 63 0C 08 00 5C 47 91 83 F1 8F E3 8D +D7 FE 1C 41 11 05 5C D7 E3 98 A5 FE 01 45 82 80 +B7 28 02 30 03 A8 C8 00 13 78 18 00 E3 1C 08 FE +23 AA A8 00 23 AC B8 00 23 A2 E8 02 23 A4 F8 02 +41 C2 B7 07 12 00 85 07 37 26 02 30 1C C6 5C 42 +09 83 15 C3 0A 07 05 66 B3 85 E6 00 7D 16 37 27 +02 30 5C 47 91 83 F1 8F ED DF 1C 5B 91 06 23 AE +F6 FE E3 98 B6 FE B7 27 02 30 DC 47 05 47 93 F6 +37 00 63 9A E6 00 37 26 02 30 85 46 5C 46 13 F7 +37 00 E3 0D D7 FE 89 8B 85 CB B7 37 02 50 03 A7 +C7 C5 41 11 06 C6 89 47 63 E1 E7 02 B7 27 02 30 +09 47 98 C7 05 45 EF 30 9F C5 B2 40 41 01 82 80 +B7 07 02 00 85 07 49 B7 82 80 37 65 02 50 13 05 +05 BB EF 30 DF C5 D9 BF 41 11 06 C6 37 23 02 30 +83 28 C3 00 93 F8 18 00 E3 9C 08 FE 23 2A A3 00 +23 2C B3 00 23 22 E3 02 23 24 F3 02 2D CE B7 07 +12 00 85 07 37 26 02 30 1C C6 5C 42 09 83 15 C3 +0A 07 05 66 B3 85 E6 00 7D 16 37 27 02 30 5C 47 +91 83 F1 8F ED DF 1C 5B 91 06 23 AE F6 FE E3 98 +B6 FE B7 27 02 30 DC 47 05 47 93 F6 37 00 63 9A +E6 00 37 26 02 30 85 46 5C 46 13 F7 37 00 E3 0D +D7 FE 89 8B 8D C7 63 06 08 04 B7 37 02 50 03 A7 +C7 C5 89 47 63 E4 E7 04 B7 27 02 30 09 47 98 C7 +B2 40 41 01 82 80 B7 07 02 00 85 07 61 B7 E3 09 +08 FE 37 65 02 50 13 05 05 C2 EF 30 5F BA B7 27 +02 30 09 47 98 C7 05 45 EF 30 7F B7 B2 40 41 01 +82 80 37 65 02 50 13 05 05 BE C5 B7 37 65 02 50 +13 05 05 BE EF 30 BF B7 45 BF 37 28 02 30 83 26 +C8 00 85 8A ED FE 23 2A A8 00 23 2C B8 00 23 22 +E8 02 23 24 F8 02 01 CA B7 07 12 00 85 07 37 27 +02 30 1C C7 82 80 B7 07 02 00 85 07 37 27 02 30 +1C C7 82 80 B7 27 02 30 DC 43 93 D7 25 00 95 C3 +8A 07 85 66 33 06 F5 00 37 27 02 30 FD 16 5C 47 +91 83 F5 8F ED DF 1C 5B 11 05 23 2E F5 FE E3 18 +C5 FE 82 80 B7 08 02 30 83 A8 08 00 41 11 06 C6 +93 F8 18 00 63 8B 08 00 B7 37 02 50 83 A7 C7 C5 +A1 E3 B2 40 05 45 41 01 82 80 91 C9 B7 37 02 50 +83 A7 C7 C5 D1 EF 05 45 EF 30 7F AB 01 A0 B7 05 +04 00 E3 75 B5 FE B3 88 A7 00 63 F2 F8 02 37 37 +02 50 03 27 C7 C5 41 EB 05 45 EF 30 5F A9 01 A0 +37 65 02 50 13 05 85 C6 EF 30 7F AA 5D BF E3 F0 +B8 FE B7 25 02 30 83 A8 C5 00 93 F8 18 00 E3 9C +08 FE C8 C9 23 AC 05 00 D0 CD 94 D1 DC D1 23 A4 +05 03 31 C7 B7 07 00 11 85 07 37 27 02 30 1C C7 +5C 47 05 47 93 F6 37 00 63 9A E6 00 37 26 02 30 +85 46 5C 46 13 F7 37 00 E3 0D D7 FE 89 8B 85 EF +B2 40 B7 07 02 30 05 47 98 D3 01 45 41 01 82 80 +AA 85 41 65 13 05 C5 DA EF 30 7F A5 A9 BF B7 07 +00 01 85 07 5D BF 2A 86 41 65 BE 85 13 05 C5 DD +EF 30 FF A3 95 B7 37 65 02 50 13 05 45 C8 EF 30 +1F A1 B7 27 02 30 09 47 98 C7 05 45 EF 30 3F 9E +45 BF B7 08 02 30 83 A8 08 00 41 11 06 C6 93 F8 +18 00 63 8B 08 00 B7 37 02 50 83 A7 C7 C5 A1 E3 +B2 40 05 45 41 01 82 80 91 CA B7 37 02 50 83 A7 +C7 C5 A5 EF 05 45 EF 30 9F 9A 01 A0 B7 06 04 00 +E3 75 D6 FE B3 88 C7 00 63 F2 F8 02 37 37 02 50 +03 27 C7 C5 2D E7 05 45 EF 30 7F 98 01 A0 37 65 +02 50 13 05 85 C6 EF 30 9F 99 5D BF E3 F0 D8 FE +B7 28 02 30 83 A6 C8 00 85 8A ED FE 23 AA A8 00 +23 AC B8 00 23 AE C8 00 23 A0 08 02 23 A2 F8 02 +23 A4 08 03 15 C3 B7 07 11 00 85 07 B2 40 37 27 +02 30 1C C7 01 45 41 01 82 80 41 65 B2 85 13 05 +85 E2 EF 30 DF 96 BD BF C1 67 85 07 C5 B7 41 65 +BE 85 13 05 85 E5 EF 30 9F 95 71 B7 41 11 06 C6 +0D 3F B7 27 02 30 DC 47 05 47 93 F6 37 00 63 9A +E6 00 37 26 02 30 85 46 5C 46 13 F7 37 00 E3 0D +D7 FE 89 8B 99 CF B7 37 02 50 03 A7 C7 C5 89 47 +63 E0 E7 02 B7 27 02 30 09 47 98 C7 05 45 EF 30 +1F 8D B2 40 B7 07 02 30 05 47 98 D3 41 01 82 80 +37 65 02 50 13 05 05 BB EF 30 7F 8D E1 BF 01 11 +4E C6 B7 39 02 50 03 A7 C9 C5 22 CC 26 CA 4A C8 +06 CE 89 47 2A 89 AE 84 32 84 63 E0 E7 0A B7 36 +02 30 83 A7 86 80 37 27 02 30 F9 9B 23 A4 F6 80 +5C 47 85 8B F5 FF 23 2E 27 01 04 D3 B7 07 00 04 +40 D3 85 07 1C C7 5C 47 05 47 93 F6 37 00 63 9A +E6 00 37 26 02 30 85 46 5C 46 13 F7 37 00 E3 0D +D7 FE 89 8B A9 C3 03 A7 C9 C5 89 47 63 E6 E7 02 +B7 27 02 30 09 47 98 C7 37 37 02 30 83 27 87 80 +F2 40 62 44 93 E7 17 00 23 24 F7 80 D2 44 42 49 +B2 49 01 45 05 61 82 80 37 65 02 50 13 05 05 CE +EF 30 FF 82 F1 B7 37 65 02 50 13 05 45 D1 EF 30 +1F 82 05 45 EF 30 AF FF 01 A0 37 65 02 50 13 05 +05 CC EF 30 DF 80 A1 BF 01 11 4E C6 B7 39 02 50 +03 A7 C9 C5 22 CC 26 CA 4A C8 06 CE 89 47 2A 89 +AE 84 32 84 63 E2 E7 06 37 27 02 30 5C 47 85 8B +F5 FF 23 2E 27 01 04 D3 B7 07 00 04 40 D3 85 07 +1C C7 5C 47 05 47 93 F6 37 00 63 9A E6 00 37 26 +02 30 85 46 5C 46 13 F7 37 00 E3 0D D7 FE 89 8B +89 CF 03 A7 C9 C5 89 47 63 E7 E7 02 B7 27 02 30 +09 47 98 C7 05 45 EF 30 8F F7 F2 40 62 44 D2 44 +42 49 B2 49 05 61 82 80 37 65 02 50 13 05 45 D5 +EF 30 EF F7 51 BF 37 65 02 50 13 05 05 BB EF 30 +0F F7 E9 B7 37 27 02 30 5C 47 85 8B F5 FF 48 CF +0C D3 B7 07 00 04 50 D3 85 07 1C C7 82 80 41 11 +83 4E 01 01 06 C6 37 2E 02 30 03 23 CE 00 13 73 +13 00 E3 1C 03 FE 23 2A AE 00 23 2C BE 00 23 2E +DE 00 23 20 EE 02 23 22 0E 03 23 24 1E 03 B7 06 +03 03 63 83 0E 06 95 06 03 47 41 01 B3 37 F0 00 +F2 07 33 37 E0 00 0E 07 33 36 C0 00 D9 8F 52 06 +D1 8F 37 27 02 30 D5 8F 1C C7 5C 47 05 47 93 F6 +37 00 63 9A E6 00 37 26 02 30 85 46 5C 46 13 F7 +37 00 E3 0D D7 FE 89 8B A1 C3 B7 37 02 50 03 A7 +C7 C5 89 47 63 EC E7 00 B2 40 B7 27 02 30 09 47 +98 C7 01 45 41 01 82 80 85 06 79 BF 37 65 02 50 +13 05 05 CE EF 30 AF EA B2 40 B7 27 02 30 09 47 +98 C7 01 45 41 01 82 80 37 65 02 50 13 05 45 D1 +EF 30 EF E8 05 45 EF 30 8F E6 01 A0 41 11 83 4E +01 01 06 C6 37 2E 02 30 03 23 CE 00 13 73 13 00 +E3 1C 03 FE 23 2A AE 00 23 2C BE 00 23 2E DE 00 +23 20 EE 02 23 22 0E 03 23 24 1E 03 B7 06 03 03 +63 85 0E 06 95 06 03 47 41 01 B3 37 F0 00 F2 07 +33 37 E0 00 0E 07 33 36 C0 00 D9 8F 52 06 D1 8F +37 27 02 30 D5 8F 1C C7 5C 47 05 47 93 F6 37 00 +63 9A E6 00 37 26 02 30 85 46 5C 46 13 F7 37 00 +E3 0D D7 FE 89 8B 99 CF B7 37 02 50 03 A7 C7 C5 +89 47 63 EE E7 00 B7 27 02 30 09 47 98 C7 05 45 +EF 30 EF DC B2 40 41 01 82 80 85 06 69 BF 37 65 +02 50 13 05 05 BB EF 30 8F DD F1 BF 41 11 03 4F +01 01 83 4E 81 01 06 C6 37 2E 02 30 03 23 CE 00 +13 73 13 00 E3 1C 03 FE 23 2A AE 00 23 2C BE 00 +23 2E DE 00 23 20 EE 02 23 22 0E 03 23 24 1E 03 +B7 06 03 03 63 04 0F 06 95 06 03 47 41 01 B3 37 +F0 00 F2 07 33 37 E0 00 0E 07 33 36 C0 00 D9 8F +52 06 D1 8F 37 27 02 30 D5 8F 1C C7 5C 47 05 47 +93 F6 37 00 63 9A E6 00 37 26 02 30 85 46 5C 46 +13 F7 37 00 E3 0D D7 FE 89 8B 9D C3 63 84 0E 04 +B7 37 02 50 03 A7 C7 C5 89 47 63 E2 E7 04 B7 27 +02 30 09 47 98 C7 B2 40 41 01 82 80 85 06 71 BF +E3 8B 0E FE 37 65 02 50 13 05 05 C2 EF 30 2F D2 +B7 27 02 30 09 47 98 C7 05 45 EF 30 4F CF B2 40 +41 01 82 80 37 65 02 50 13 05 05 BE C5 B7 37 65 +02 50 13 05 05 BE EF 30 8F CF 55 BF 83 4E 01 00 +37 2E 02 30 03 23 CE 00 13 73 13 00 E3 1C 03 FE +23 2A AE 00 23 2C BE 00 23 2E DE 00 23 20 EE 02 +23 22 0E 03 23 24 1E 03 B7 06 03 03 63 85 0E 02 +95 06 03 47 41 00 B3 37 F0 00 33 36 C0 00 52 06 +F2 07 33 37 E0 00 D1 8F 0E 07 D9 8F D5 8F 37 27 +02 30 1C C7 82 80 85 06 E9 BF B7 27 02 30 DC 47 +41 11 22 C4 06 C6 05 47 93 F6 37 00 2A 84 63 9A +E6 00 37 26 02 30 85 46 5C 46 13 F7 37 00 E3 0D +D7 FE 89 8B 99 CF B7 37 02 50 03 A7 C7 C5 89 47 +63 E2 E7 02 B7 27 02 30 09 47 98 C7 05 45 EF 30 +0F C3 09 C4 B7 07 02 30 05 47 98 D3 B2 40 22 44 +41 01 82 80 37 65 02 50 13 05 05 BB EF 30 2F C3 +B7 27 02 30 09 47 98 C7 05 45 EF 30 4F C0 D1 BF +B7 27 02 30 DC 47 41 11 22 C4 06 C6 05 47 93 F6 +37 00 2A 84 63 9A E6 00 37 26 02 30 85 46 5C 46 +13 F7 37 00 E3 0D D7 FE 89 8B A9 C3 B7 37 02 50 +03 A7 C7 C5 89 47 63 EF E7 00 B7 27 02 30 09 47 +98 C7 09 C4 B7 07 02 30 05 47 98 D3 B2 40 22 44 +41 01 82 80 37 65 02 50 13 05 05 CE EF 30 2F BC +B7 27 02 30 09 47 98 C7 71 FC CD B7 37 65 02 50 +13 05 45 D1 EF 30 AF BA 05 45 EF 30 4F B8 01 A0 +1D 71 A6 CA 86 CE A2 CC CA C8 CE C6 D2 C4 D6 C2 +DA C0 5E DE 62 DC 66 DA 6A D8 6E D6 95 47 AA 84 +63 01 F5 22 C5 47 63 02 F5 12 99 47 63 19 F5 2A +8D 47 B7 49 44 23 37 0B 03 03 37 0C 44 23 3E C6 +3E CA 8D 09 05 49 A5 47 63 97 F4 42 41 64 7D 14 +37 0A 03 30 EF 00 50 5F 93 57 F5 41 C1 83 33 07 +F5 00 61 8F 1D 8F 83 27 8A 54 0D 07 93 7D C7 FF +E3 82 FD FE 02 C4 02 CE BD 47 CA 8C 4E 84 63 9E +F4 22 CD 47 4D 4D 3E C8 02 CC 93 8B 24 FF 93 BB +1B 00 13 99 2B 00 B7 39 02 50 03 A6 C9 C5 11 4A +63 63 CA 0E B7 35 02 30 83 A7 85 80 B7 26 02 30 +F9 9B 23 A4 F5 80 DC 46 85 8B F5 FF 89 47 63 E3 +C7 0A B7 27 02 30 23 AA 87 01 22 47 85 46 94 CF +C0 CF 23 A0 97 03 33 69 27 01 23 A2 B7 03 33 67 +69 01 23 A4 A7 03 13 67 17 00 98 C7 DC 47 13 F7 +37 00 63 19 D7 00 37 26 02 30 5C 46 13 F7 37 00 +E3 0D D7 FE 89 8B B5 C7 03 A7 C9 C5 89 47 63 EF +E7 18 B7 27 02 30 09 47 98 C7 37 37 02 30 83 27 +87 80 F6 40 66 44 93 E7 17 00 23 24 F7 80 D6 44 +46 49 B6 49 26 4A 96 4A 06 4B F2 5B 62 5C D2 5C +42 5D B2 5D 01 45 25 61 82 80 85 47 41 6B 3E C6 +02 CA 91 69 01 49 02 C4 37 0C 44 23 02 CE 93 0D +00 04 19 BF 37 65 02 50 13 05 C5 D6 EF 30 2F A3 +89 BF 37 65 02 50 13 05 45 D1 EF 30 4F A2 05 45 +EF 30 EF 9F 01 A0 C1 6A 93 8A CA A8 A6 85 13 85 +4A 41 EF 30 CF A2 03 A6 C9 C5 E3 75 CA F0 62 86 +85 45 13 85 CA 42 EF 30 8F A1 03 A6 C9 C5 E3 7B +CA EE 22 86 E6 85 13 85 CA 44 EF 30 4F A0 03 A6 +C9 C5 E3 71 CA EE B2 45 13 85 CA 46 EF 30 2F 9F +03 A6 C9 C5 E3 78 CA EC D2 45 13 85 4A 48 EF 30 +0F 9E 03 A6 C9 C5 E3 7F CA EA F2 45 13 85 CA 49 +EF 30 EF 9C 03 A6 C9 C5 E3 76 CA EA E2 45 13 85 +4A 4B EF 30 CF 9B 03 A6 C9 C5 E3 7D CA E8 DE 85 +13 85 CA 4C EF 30 AF 9A 03 A6 C9 C5 E3 74 CA E8 +EE 85 13 85 4A 4E EF 30 8F 99 03 A6 C9 C5 E3 7B +CA E6 C2 45 13 85 CA 4F EF 30 6F 98 03 A6 C9 C5 +95 B5 B7 07 03 30 03 A9 47 54 83 A9 07 54 37 0C +44 23 8D 47 CA 8C 4E 84 0D 0C 37 0B 03 00 3E C6 +89 47 63 F6 97 1E 13 87 D4 FF 85 47 B3 97 E7 00 +93 F7 17 4D 3E CA 63 9F 07 1C AD 47 63 86 F4 22 +91 47 63 8E F4 18 37 07 00 03 B9 47 33 6B EB 00 +63 99 F4 20 EF 00 50 3B B7 07 10 00 3E C4 8D 47 +3E CA 85 47 3E CE 93 0D 00 04 F9 B3 37 65 02 50 +13 05 05 CE EF 30 AF 8E A9 BD 02 CC C1 47 63 8A +F4 00 91 47 63 92 F4 18 11 49 01 4D 02 C8 85 4B +D9 B3 91 47 11 49 11 4D 3E C8 85 4B 6D BB 9D 47 +63 1A F5 04 B7 07 03 30 03 AA 47 54 03 A4 07 54 +EF 00 90 35 2A 89 EF 00 30 35 93 57 F5 41 13 57 +E5 01 8A 07 0A 09 D9 8F 0A 05 AA 89 33 69 F9 00 +63 14 A4 00 E3 0E 2A FD CA 8C 2A 84 C5 47 63 EB +97 10 37 37 02 50 93 97 24 00 13 07 47 1B BA 97 +9C 43 82 87 B7 07 03 30 83 AC 47 54 83 A9 07 54 +AD 47 66 89 4E 84 63 12 F5 02 B7 07 10 00 3E C4 +89 47 3E CA 85 47 37 0B 00 02 37 0C 44 23 02 C6 +3E CE 02 CC 93 0D 00 04 91 BF 09 47 89 47 3A C6 +3A CA 37 0B 02 02 E3 00 F5 DE 4D B7 37 0C 44 23 +01 4B 02 C6 F1 BD EF 00 30 2C 8D 47 B3 67 F5 02 +91 46 37 0C 44 23 37 07 00 04 36 CA 85 07 3E C6 +13 9B 07 01 33 6B EB 00 93 87 44 FF 05 47 63 68 +F7 06 B7 07 00 10 33 6B FB 00 85 47 02 C4 01 4D +02 C8 3E CC 93 0D 00 04 02 CE C1 B1 89 47 02 C4 +37 0B 02 00 37 0C 44 23 3E C6 02 CA 02 CE 93 0D +00 04 59 B9 85 47 41 6B 37 0C 44 23 3E C6 02 CA +99 B9 89 47 3E C6 85 47 37 0B 02 10 02 C4 37 0C +44 23 02 CA 02 CE 3E CC 93 0D 00 04 45 BD 91 47 +37 0B 00 04 37 0C 44 23 3E CA 02 C6 05 B9 A1 47 +E3 93 F4 C2 02 C4 01 4D 02 C8 02 CC 93 0D 30 04 +02 CE A1 B9 B5 47 37 0C 44 23 37 0B 03 00 63 EF +97 04 8D 47 3E C6 29 BD 01 4D 02 C8 3D B9 85 47 +63 89 F4 00 B7 07 00 04 33 6B FB 00 91 47 3E CA +A1 B7 EF 00 70 1E AD 47 B3 67 F5 02 95 07 3E CA +13 97 87 01 05 BF 02 C4 02 CE A9 47 E3 95 F4 E2 +B7 07 03 30 03 A7 87 54 CA 8C 4E 84 93 1D 07 01 +93 DD 0D 01 01 4D 02 C8 02 CC C5 BE 8D 47 3E C6 +DD B3 8D 47 3E CA 09 B7 B7 07 00 02 33 6B FB 00 +B7 07 10 00 3E C4 89 47 3E CA 85 47 3E CE 75 BF +B7 27 02 30 DC 47 41 11 22 C4 06 C6 93 F6 37 00 +05 47 2A 84 63 9A E6 00 37 26 02 30 85 46 5C 46 +13 F7 37 00 E3 0D D7 FE 89 8B 95 C7 A1 C5 B7 37 +02 50 03 A7 C7 C5 89 47 63 E3 E7 04 B7 27 02 30 +09 47 98 C7 09 C4 B7 07 02 30 05 47 98 D3 B2 40 +22 44 41 01 82 80 FD D5 37 65 02 50 13 05 05 C2 +EF 20 FF E7 B7 27 02 30 09 47 98 C7 05 45 EF 20 +1F E5 C9 BF 37 65 02 50 13 05 05 BE D5 B7 37 65 +02 50 13 05 05 BE EF 20 9F E5 4D BF 53 4F 43 5F +49 46 43 3A 20 43 6C 65 61 72 20 65 78 65 63 75 +74 65 20 72 65 67 00 00 53 4F 43 5F 49 46 43 3A +20 43 68 65 63 6B 20 6D 62 6F 78 5F 73 74 61 74 +75 73 2E 6D 62 6F 78 5F 66 73 6D 5F 70 73 20 66 +6F 75 6E 64 20 75 6E 65 78 70 65 63 74 65 64 20 +73 74 61 74 65 20 30 78 25 78 0A 00 53 4F 43 5F +49 46 43 3A 20 53 65 74 20 6D 62 6F 78 5F 73 74 +61 74 75 73 20 66 69 65 6C 64 3A 20 30 78 25 78 +0A 00 00 00 53 4F 43 5F 49 46 43 3A 20 53 65 74 +20 66 6C 6F 77 5F 73 74 61 74 75 73 20 66 69 65 +6C 64 3A 20 30 78 25 78 0A 00 00 00 53 4F 43 5F +49 46 43 3A 20 43 6C 65 61 72 20 53 48 41 20 61 +63 63 65 6C 65 72 61 74 6F 72 20 6C 6F 63 6B 20 +62 79 20 77 72 69 74 69 6E 67 20 27 31 3A 20 30 +78 25 78 0A 00 00 00 00 53 4F 43 5F 49 46 43 3A +20 42 61 64 20 66 69 65 6C 64 20 76 61 6C 75 65 +00 00 00 00 53 4F 43 5F 49 46 43 3A 20 42 61 64 +20 66 69 65 6C 64 20 76 61 6C 75 65 00 00 00 00 +53 4F 43 5F 49 46 43 3A 20 43 6C 65 61 72 20 66 +6C 6F 77 5F 73 74 61 74 75 73 20 66 69 65 6C 64 +3A 20 30 78 25 78 0A 00 53 4F 43 5F 49 46 43 3A +20 43 4D 44 20 66 72 6F 6D 20 6D 61 69 6C 62 6F +78 3A 20 30 78 25 78 0A 00 00 00 00 53 4F 43 5F +49 46 43 3A 20 44 4C 45 4E 20 66 72 6F 6D 20 6D +61 69 6C 62 6F 78 3A 20 30 78 25 78 0A 00 00 00 +46 41 54 41 4C 3A 20 49 6E 76 61 6C 69 64 20 64 +6C 65 6E 20 70 61 73 73 65 64 20 74 6F 20 6D 62 +6F 78 20 66 77 20 66 6C 6F 77 3A 20 30 78 25 78 +0A 00 00 00 46 41 54 41 4C 3A 20 49 6E 76 61 6C +69 64 20 63 6D 64 20 70 61 73 73 65 64 20 74 6F +20 6D 62 6F 78 20 66 77 20 66 6C 6F 77 3A 20 30 +78 25 78 0A 00 00 00 00 46 6F 75 6E 64 20 69 6E +76 61 6C 69 64 20 69 63 63 6D 20 73 69 7A 65 20 +69 6E 20 66 69 72 6D 77 61 72 65 20 69 6D 61 67 +65 20 72 65 63 65 69 76 65 64 20 66 72 6F 6D 20 +53 4F 43 21 20 4D 61 78 20 65 78 70 65 63 74 65 +64 20 30 78 25 78 2C 20 67 6F 74 20 30 78 25 78 +0A 00 00 00 46 6F 75 6E 64 20 69 6E 76 61 6C 69 +64 20 64 63 63 6D 20 73 69 7A 65 20 69 6E 20 66 +69 72 6D 77 61 72 65 20 69 6D 61 67 65 20 72 65 +63 65 69 76 65 64 20 66 72 6F 6D 20 53 4F 43 21 +20 4D 61 78 20 65 78 70 65 63 74 65 64 20 30 78 +25 78 2C 20 67 6F 74 20 30 78 25 78 0A 00 00 00 +61 74 20 25 78 3A 20 25 78 0A 00 00 53 4F 43 5F +49 46 43 3A 20 49 6C 6C 65 67 61 6C 20 62 79 74 +65 5F 63 6F 75 6E 74 20 30 78 25 78 0A 00 00 00 +53 4F 43 5F 49 46 43 3A 20 53 65 74 20 66 77 20 +75 70 64 61 74 65 20 72 65 73 65 74 20 77 69 74 +68 20 77 61 69 74 5F 63 79 63 6C 65 73 20 5B 25 +64 5D 20 28 25 73 29 0A 00 00 00 00 73 72 63 5F +61 64 64 72 20 30 78 25 78 20 69 73 20 6F 75 74 +20 6F 66 20 62 6F 75 6E 64 73 20 66 6F 72 20 6D +62 6F 78 20 73 70 61 6E 21 0A 00 00 72 65 61 64 +69 6E 67 20 30 78 25 78 20 62 79 74 65 73 20 66 +72 6F 6D 20 73 72 63 5F 61 64 64 72 20 30 78 25 +78 20 67 6F 65 73 20 6F 75 74 20 6F 66 20 62 6F +75 6E 64 73 20 66 6F 72 20 6D 62 6F 78 20 73 70 +61 6E 21 0A 00 00 00 00 64 73 74 5F 61 64 64 72 +20 30 78 25 78 20 69 73 20 6F 75 74 20 6F 66 20 +62 6F 75 6E 64 73 20 66 6F 72 20 6D 62 6F 78 20 +73 70 61 6E 21 0A 00 00 77 72 69 74 69 6E 67 20 +30 78 25 78 20 62 79 74 65 73 20 74 6F 20 64 73 +74 5F 61 64 64 72 20 30 78 25 78 20 67 6F 65 73 +20 6F 75 74 20 6F 66 20 62 6F 75 6E 64 73 20 66 +6F 72 20 6D 62 6F 78 20 73 70 61 6E 21 0A 00 00 +70 61 72 61 6D 3A 20 65 72 72 5F 74 79 70 65 20 +20 20 30 78 25 78 0A 00 70 61 72 61 6D 3A 20 73 +72 63 5F 61 64 64 72 20 20 20 30 78 25 78 20 30 +78 25 78 0A 00 00 00 00 70 61 72 61 6D 3A 20 64 +73 74 5F 61 64 64 72 20 20 20 30 78 25 78 20 30 +78 25 78 0A 00 00 00 00 70 61 72 61 6D 3A 20 72 +64 5F 72 6F 75 74 65 20 20 20 30 78 25 78 0A 00 +70 61 72 61 6D 3A 20 77 72 5F 72 6F 75 74 65 20 +20 20 30 78 25 78 0A 00 70 61 72 61 6D 3A 20 72 +64 5F 66 69 78 65 64 20 20 20 30 78 25 78 0A 00 +70 61 72 61 6D 3A 20 77 72 5F 66 69 78 65 64 20 +20 20 30 78 25 78 0A 00 70 61 72 61 6D 3A 20 61 +65 73 5F 6D 6F 64 65 20 20 20 30 78 25 78 0A 00 +70 61 72 61 6D 3A 20 62 79 74 65 5F 63 6F 75 6E +74 20 30 78 25 78 0A 00 70 61 72 61 6D 3A 20 62 +6C 6F 63 6B 5F 73 69 7A 65 20 30 78 25 78 0A 00 +B7 36 02 50 83 A7 C6 1F 13 97 D7 00 3D 8F 93 57 +17 01 B9 8F 13 95 57 00 3D 8D 23 AE A6 1E 82 80 +B7 37 02 50 03 A7 C7 C5 41 11 22 C4 26 C2 06 C6 +89 47 AA 84 2E 84 63 E3 E7 02 73 50 20 7D 73 90 +34 7D 73 D0 41 7D 73 10 44 30 73 50 04 30 73 D0 +61 7C B2 40 22 44 92 44 41 01 82 80 37 65 02 50 +13 05 05 D8 EF 20 BF 8D C9 BF 73 50 20 7D 73 10 +35 7D 73 D0 41 7D 73 90 45 30 73 50 04 30 82 80 +73 D0 61 7C 82 80 B7 07 03 30 23 A6 A7 0E 23 A8 +B7 0E 82 80 B7 07 03 30 23 AE A7 0E 23 A0 B7 10 +82 80 B7 07 03 30 7D 57 23 A6 E7 0E 23 A8 E7 0E +82 80 B7 07 03 30 7D 57 23 AE E7 0E 23 A0 E7 10 +82 80 37 17 03 30 83 27 47 81 93 F7 07 04 E5 DF +93 07 00 04 23 2A F7 80 82 80 37 17 03 30 83 27 +47 81 93 F7 07 08 E5 DF 93 07 00 08 23 2A F7 80 +82 80 B7 07 03 30 23 A6 A7 0E 23 A8 B7 0E 23 AE +C7 0E 23 A0 D7 10 05 47 23 A2 E7 0E 23 A4 E7 0E +82 80 01 11 06 CE 0D E1 B7 37 02 50 03 A7 C7 C5 +89 47 63 E2 E7 08 B7 07 03 30 23 A2 07 0E 23 AA +07 0E F2 40 05 61 82 80 85 47 63 01 F5 04 89 47 +E3 19 F5 FE B7 37 02 50 83 A7 C7 C5 63 6F F5 06 +B7 07 03 30 23 A6 B7 0E 23 A8 C7 0E 23 AE D7 0E +23 A0 E7 10 05 47 23 A2 E7 0E 23 AA E7 0E F2 40 +23 A4 E7 0E 23 AC E7 0E 05 61 82 80 B7 37 02 50 +03 A6 C7 C5 89 47 63 E7 C7 02 B7 07 03 30 23 AE +D7 0E 23 A0 E7 10 F2 40 05 47 23 AA E7 0E 23 AC +E7 0E 05 61 82 80 37 65 02 50 13 05 85 D9 EF 20 +0F F9 95 BF 37 65 02 50 13 05 45 DC 3A C2 36 C0 +EF 20 EF F7 12 47 82 46 C9 B7 37 65 02 50 13 05 +05 DF 3A C6 36 C4 32 C2 2E C0 EF 20 4F F6 32 47 +A2 46 12 46 82 45 AD B7 B3 47 B5 00 8D 8B B3 08 +C5 00 B1 E7 8D 47 63 F4 C7 04 93 77 35 00 2A 87 +B9 EB 13 F6 C8 FF B3 06 E6 40 93 07 00 02 63 C8 +D7 06 AE 86 BA 87 63 71 C7 02 03 A8 06 00 91 07 +91 06 23 AE 07 FF E3 EA C7 FE 93 07 F6 FF 99 8F +F1 9B 91 07 3E 97 BE 95 63 66 17 01 82 80 2A 87 +63 7E 15 03 83 C7 05 00 05 07 85 05 A3 0F F7 FE +E3 9A E8 FE 82 80 83 C6 05 00 05 07 93 77 37 00 +A3 0F D7 FE 85 05 D1 DF 83 C6 05 00 05 07 93 77 +37 00 A3 0F D7 FE 85 05 F9 FF 61 B7 82 80 41 11 +22 C6 13 04 00 02 83 A3 05 00 83 A2 45 00 83 AF +85 00 03 AF C5 00 83 AE 05 01 03 AE 45 01 03 A3 +85 01 03 A8 C5 01 94 51 13 07 47 02 B3 07 E6 40 +23 2E 77 FC 23 20 57 FE 23 22 F7 FF 23 24 E7 FF +23 26 D7 FF 23 28 C7 FF 23 2A 67 FE 23 2C 07 FF +23 2E D7 FE 93 85 45 02 E3 47 F4 FA AE 86 BA 87 +63 71 C7 02 03 A8 06 00 91 07 91 06 23 AE 07 FF +E3 EA C7 FE 93 07 F6 FF 99 8F F1 9B 91 07 3E 97 +BE 95 63 65 17 01 32 44 41 01 82 80 83 C7 05 00 +05 07 85 05 A3 0F F7 FE E3 87 E8 FE 83 C7 05 00 +05 07 85 05 A3 0F F7 FE E3 92 E8 FE E9 BF 3D 43 +2A 87 63 73 C3 02 93 77 F7 00 BD EF AD E5 93 76 +06 FF 3D 8A BA 96 0C C3 4C C3 0C C7 4C C7 41 07 +E3 6B D7 FE 11 E2 82 80 B3 06 C3 40 8A 06 97 02 +00 00 96 96 67 80 A6 00 23 07 B7 00 A3 06 B7 00 +23 06 B7 00 A3 05 B7 00 23 05 B7 00 A3 04 B7 00 +23 04 B7 00 A3 03 B7 00 23 03 B7 00 A3 02 B7 00 +23 02 B7 00 A3 01 B7 00 23 01 B7 00 A3 00 B7 00 +23 00 B7 00 82 80 93 F5 F5 0F 93 96 85 00 D5 8D +93 96 05 01 D5 8D 61 B7 93 96 27 00 97 02 00 00 +96 96 86 82 E7 80 86 FA 96 80 C1 17 1D 8F 3E 96 +E3 74 C3 F8 A5 B7 B7 67 02 50 83 A7 07 E2 23 A4 +A7 0A 23 A6 07 0A 82 80 B7 67 02 50 03 A8 07 E2 +B7 85 95 4C 93 85 D5 F2 83 26 88 0A 03 27 C8 0A +B3 87 B6 02 13 86 17 00 B3 37 F6 00 23 24 C8 0A +37 F6 51 58 13 06 D6 42 33 86 C6 02 33 07 B7 02 +B3 B6 B6 02 32 97 36 97 BA 97 13 95 17 00 23 26 +F8 0A 05 81 82 80 93 77 35 00 2A 87 9D EF B7 86 +7F 7F 93 86 F6 F7 FD 55 10 43 11 07 B3 77 D6 00 +B6 97 D1 8F D5 8F E3 89 B7 FE 83 46 C7 FF B3 07 +A7 40 8D CA 83 46 D7 FF 9D C2 03 45 E7 FF 33 35 +A0 00 3E 95 79 15 82 80 F9 D2 83 47 07 00 05 07 +93 76 37 00 F5 FB 09 8F 13 05 F7 FF 82 80 13 85 +D7 FF 82 80 13 85 C7 FF 82 80 13 01 01 BC 23 2A +91 42 23 28 21 43 23 20 61 43 23 2C 81 41 23 2E +11 42 23 2C 81 42 23 26 31 43 23 24 41 43 23 22 +51 43 23 2E 71 41 23 2A 91 41 23 28 A1 41 23 26 +B1 41 85 47 36 8B 2A 89 2E 8C B2 84 63 F1 D7 2E +01 46 85 4C 85 46 FD 5B 09 A8 B3 8C 77 41 3E 86 +85 46 B3 07 D6 00 63 F7 67 03 33 87 74 01 36 97 +B3 85 F4 00 83 C5 05 00 03 47 07 00 E3 EF E5 FC +63 86 E5 14 B2 8B 85 46 05 06 B3 07 D6 00 85 4C +E3 ED 67 FD 81 45 05 48 05 46 7D 55 05 47 09 A8 +33 08 A7 40 BA 85 05 46 33 87 C5 00 63 77 67 03 +B3 87 C4 00 B3 86 E4 00 AA 97 83 C6 06 00 83 C7 +07 00 E3 EF D7 FC 63 87 D7 10 2E 85 05 46 85 05 +33 87 C5 00 05 48 E3 6D 67 FD 05 05 85 0B 63 64 +75 01 C2 8C AA 8B 8A 87 13 07 01 40 23 A0 67 01 +91 07 E3 9D E7 FE 63 05 0B 02 13 06 FB FF B3 05 +9B 00 26 87 26 96 83 47 07 00 B3 06 E6 40 05 07 +8A 07 93 87 07 40 8A 97 23 A0 D7 C0 E3 95 E5 FE +5E 86 B3 85 94 01 26 85 C9 26 63 1F 05 10 85 69 +93 89 09 80 05 4A 81 4D 01 44 B3 06 6C 41 B3 69 +3B 01 13 0D FB FF 33 0A 7A 41 B3 0A 9B 41 63 E8 +86 02 33 06 89 00 B3 07 A6 01 83 C7 07 00 8A 07 +93 87 07 40 8A 97 83 A7 07 C0 AD CB 63 85 0D 00 +63 F3 97 01 D6 87 3E 94 81 4D E3 FC 86 FC 33 05 +89 01 CE 85 6D 21 2A 9C B3 06 6C 41 E3 F3 86 FC +01 45 83 20 C1 43 03 24 81 43 83 24 41 43 03 29 +01 43 83 29 C1 42 03 2A 81 42 83 2A 41 42 03 2B +01 42 83 2B C1 41 03 2C 81 41 83 2C 41 41 03 2D +01 41 83 2D C1 40 13 01 01 44 82 80 63 8A 96 15 +85 06 41 BD 63 03 C8 14 05 06 F9 B5 6E 87 63 F3 +7D 01 5E 87 63 70 A7 03 B3 07 E4 00 33 88 E4 00 +CA 97 03 45 08 00 83 C7 07 00 63 11 F5 04 05 07 +E3 64 A7 FF 13 87 FB FF 63 E6 7D 01 39 AA 63 81 +ED 02 2A 87 B3 07 E4 00 B3 85 E4 00 CA 97 83 C5 +05 00 83 C7 07 00 13 05 F7 FF E3 82 F5 FE 05 07 +85 0D 63 6A B7 0F 66 94 D6 8D 11 BF E3 74 A7 FD +52 94 3A 94 81 4D 21 B7 33 0A 7B 41 63 65 7A 0D +05 64 13 04 04 80 85 49 05 0A 81 4A B3 06 6C 41 +33 64 8B 00 93 0C FB FF B3 89 79 41 7D 5D 63 E2 +56 03 33 05 59 01 B3 07 95 01 83 C7 07 00 8A 07 +93 87 07 40 8A 97 83 A7 07 C0 95 CB BE 9A E3 F2 +56 FF 33 05 89 01 A2 85 59 2E 2A 9C B3 06 6C 41 +E3 E8 56 EF 33 05 59 01 B3 07 95 01 83 C7 07 00 +8A 07 93 87 07 40 8A 97 83 A7 07 C0 E1 FB 5E 87 +63 E6 9B 01 25 A0 05 07 63 72 97 03 B3 07 57 01 +B3 85 E4 00 CA 97 03 C6 05 00 83 C7 07 00 E3 04 +F6 FE 63 75 97 01 CE 9A BA 9A 51 B7 93 87 FB FF +63 95 A7 01 79 BD E3 8E A7 E9 33 87 FA 00 33 86 +F4 00 4A 97 03 46 06 00 03 47 07 00 FD 17 E3 04 +E6 FE D2 9A A9 BF 5E 8A 25 BF C2 95 05 46 69 B3 +36 96 85 46 3D BB 32 85 AD B5 5E 87 11 B7 85 4C +81 4B 55 BB 1D 71 A2 CC A6 CA 86 CE CA C8 CE C6 +D2 C4 AE 84 83 C5 05 00 2A 84 E1 C1 03 C6 14 00 +63 0E 06 12 03 C7 24 00 71 C3 03 C5 34 00 63 02 +05 14 83 C7 44 00 E1 CF 26 85 EF F0 DF C3 2A 89 +93 65 05 20 22 85 65 2C 63 6A 25 0F 93 07 E0 0F +63 E8 27 15 B3 09 25 41 13 06 00 04 93 05 19 00 +0A 85 A2 99 EF F0 BF B0 63 06 09 02 13 76 F9 0F +26 87 B3 05 99 00 26 96 83 47 07 00 B3 06 E6 40 +05 07 93 F7 F7 03 93 87 07 04 8A 97 23 80 D7 FC +E3 94 E5 FE 7D 14 B3 07 24 01 83 C7 07 00 93 F7 +F7 03 93 87 07 04 8A 97 83 C7 07 FC 3E 94 63 F6 +89 00 79 A0 52 94 63 E5 89 08 B3 07 24 01 83 C7 +07 00 22 85 4A 86 93 F7 F7 03 93 87 07 04 8A 97 +A6 85 03 CA 07 FC D5 20 71 FD F6 40 22 85 66 44 +D6 44 46 49 B6 49 26 4A 25 61 82 80 03 47 05 00 +C2 05 D1 8D 81 47 39 C3 C2 07 A2 86 D9 8F 05 04 +03 47 04 00 E3 99 F5 FE 13 84 F6 FF F9 B7 93 97 +85 01 42 06 83 46 04 00 D1 8F C9 8F 22 07 D9 8F +91 CE 01 47 19 A0 63 83 E7 04 22 86 22 07 05 04 +55 8F 83 46 04 00 E5 FA 63 8A E7 02 01 44 71 BF +33 85 29 01 83 47 05 00 F5 DB 85 65 93 85 05 80 +7D 22 AA 99 E3 F0 89 F4 01 44 41 B7 66 44 F6 40 +D6 44 46 49 B6 49 26 4A 25 61 4D A0 13 04 D6 FF +AD B7 83 46 04 00 93 97 85 01 42 06 D1 8F 22 07 +D9 8F CD DE 01 47 11 A0 D5 DA 55 8F 22 86 22 07 +05 04 83 46 04 00 E3 19 F7 FE 13 04 E6 FF 35 BF +AA 85 22 85 66 44 F6 40 B6 49 26 4A CA 86 26 86 +46 49 D6 44 25 61 6F F0 5F B2 8D 47 63 F3 C7 02 +B3 67 B5 00 8D 8B 8D 46 89 CB 93 06 F6 FF 29 A8 +71 16 11 05 91 05 63 F6 C6 00 18 41 9C 41 E3 09 +F7 FE 93 06 F6 FF 0D C2 85 06 AE 96 19 A0 63 8D +D5 00 83 47 05 00 03 C7 05 00 05 05 85 05 E3 88 +E7 FE 33 85 E7 40 82 80 01 45 82 80 93 F6 F5 0F +93 77 35 00 C1 CE 91 CB 83 47 05 00 D1 C7 63 86 +D7 08 05 05 93 77 35 00 E5 FB 93 F5 F5 0F 93 97 +85 00 AE 97 18 41 13 93 07 01 33 63 F3 00 37 08 +FF FE 33 46 E3 00 13 08 F8 EF B3 07 07 01 B3 05 +06 01 13 47 F7 FF 13 46 F6 FF F9 8F B7 88 80 80 +33 F7 C5 00 D9 8F 93 88 08 08 B3 F7 17 01 85 E7 +58 41 11 05 33 46 67 00 B3 07 07 01 B3 05 06 01 +13 47 F7 FF 13 46 F6 FF F9 8F 33 F7 C5 00 D9 8F +B3 F7 17 01 F1 DF 83 47 05 00 99 C7 63 80 F6 06 +83 47 15 00 05 05 FD FB 01 45 82 80 81 CB 83 47 +05 00 E5 DF 05 05 93 77 35 00 F5 FB 18 41 37 06 +FF FE 13 06 F6 EF 93 47 F7 FF B7 86 80 80 32 97 +F9 8F 93 86 06 08 F5 8F 91 EB 58 41 11 05 B3 07 +C7 00 13 47 F7 FF F9 8F F5 8F E5 DB 83 47 05 00 +CD DF 83 47 15 00 05 05 ED FF 82 80 82 80 B3 06 +B5 00 AA 87 89 E5 29 A8 85 07 63 88 F6 00 03 C7 +07 00 7D FB 33 85 A7 40 82 80 33 85 A6 40 82 80 +01 45 82 80 +@00010AAC +78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 +78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 +78 78 78 78 78 78 78 78 0A 20 20 20 54 52 41 50 +20 56 45 43 54 4F 52 20 45 58 45 43 55 54 49 4E +47 21 20 4B 49 4C 4C 20 53 49 4D 21 21 21 20 20 +20 0A 78 78 78 78 78 78 78 78 78 78 78 78 78 78 +78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 +78 78 78 78 78 78 78 78 78 78 0A 00 87 4E 71 D5 +DE BD AC 24 68 D8 9D DB 4B 0C 1B 27 76 6A 94 D9 +05 59 1D 8E 60 8F 57 15 EE C5 3F 3C 7E A8 CA D3 +46 5D 01 BB B2 27 C9 D3 F1 E0 DC 79 42 51 CC 8F +E6 5F 6F 51 21 B8 32 E0 78 5F 4B 32 D4 25 29 A8 +BC 0F BD 97 56 ED 1E B1 D7 86 8B 16 98 5C C6 DC +E0 75 C3 9E A8 5C 81 72 88 DE F2 9B F4 15 12 01 +1C 4A 9D 65 F4 69 D0 C9 7D D9 5E C6 E4 F9 C9 3A +DA BD 4C 6D F9 34 4C B4 E4 4C 95 53 2E 2C 62 88 +04 0B D6 D8 30 0B 76 1B A2 F8 B4 CC F6 59 75 38 +2F E2 F5 14 E5 B5 50 C8 43 BA 66 C8 5B 70 90 0E +E5 D9 73 C9 29 7A 8A C8 4A 82 F2 16 48 A4 9C 44 +D7 31 D9 08 8D B7 A8 43 31 13 50 01 1B 1C B9 57 +C7 58 DA 99 89 4C 2C 72 B7 6D 5F 16 81 47 B4 C0 +26 82 67 B3 F3 6C 04 E5 49 81 99 01 FD F7 A9 3A +10 97 72 93 CB D5 2B 66 2C F7 7D 90 20 5E F3 4C +B6 2A 88 5F 61 0C 5D 28 68 A9 BF 6A 73 0A 88 30 +0C 6A 52 74 42 12 1C 22 6E 8A B4 14 1D 88 5A F0 +B1 AA FF 42 51 C0 D7 C3 EB 89 38 44 D4 B5 69 9B +4A DE 3B A9 57 5B 45 8D C3 08 EA BC 0C 54 5C 10 +02 9B 72 70 CA 82 84 D3 03 33 C6 21 9C 15 14 A3 +91 0A 82 CC 80 73 B7 27 C7 D9 04 70 92 49 8F 38 +02 4C FC 79 F3 34 7B 58 AA AC 83 40 77 7C DA 1A +5E 65 21 6F B4 A5 52 15 77 79 80 30 FC B1 42 CD +73 38 39 A6 C1 A2 48 4D E2 11 A1 D0 69 6A 41 5C +AA 11 39 34 B9 74 28 BE E9 6C 74 47 07 32 61 09 +27 F0 2E B6 4B 1C 32 54 B9 D1 05 0A 22 D2 77 31 +06 6C 14 63 3B BC 24 06 3A 7A 14 9B C9 08 8D 2B +73 F6 7A 87 24 44 37 B0 21 8B 37 1B 4A E1 8B 40 +B0 C2 38 A7 8B 66 6D C8 C9 C0 F0 BD 38 90 1A FB +E7 7E 67 91 4D 4E D7 0F 7C F4 B8 1F E0 8B 56 2A +BC DE 55 CD 58 F9 57 92 92 1B 5E 75 8E 65 93 8E +47 F8 01 6C 4A CF 01 BB 60 D6 06 90 63 2A 07 51 +59 30 51 89 44 17 14 05 B0 EC AF C7 76 71 83 F9 +9E CA A5 1E 60 17 C8 05 73 73 47 C0 19 AC 91 C3 +AB 3C 5F C5 7A C5 EF 12 46 22 5C 23 CF 8B 43 CE +7C C5 74 A1 AE 49 69 34 13 27 0A DB 04 98 D6 60 +9E ED 80 43 2C 6C 5E 13 27 93 4F 16 85 82 D9 86 +3D 11 2C AA F7 4D 0A 20 B9 A5 79 AC 9D 77 37 6F +8C 12 D6 30 AD 14 94 29 6F 99 22 3A DC 46 BD 5A +A1 C9 1C A9 96 5C 72 F3 33 0C C3 E5 00 AE 78 02 +DD 16 47 14 75 77 A9 F1 8E 74 F7 B0 22 E7 2E 9D +C2 27 C5 3B 75 8E 86 16 BC F7 AC 6A 0C 21 FD 96 +67 9E 65 45 6C CB C8 82 91 4C 35 8C 99 D7 BC 2B +55 5A 19 03 96 8B 5A 23 64 EB 1B 28 CF FB 37 CD +6B C3 E3 45 69 F8 B0 B8 8D D1 84 91 24 93 F2 63 +05 9B E4 A6 E1 32 B4 C2 DB 37 65 51 50 EF 22 23 +B0 46 4B 8C 44 3D 9C BB 99 83 B7 3A 68 CB B0 8A +96 8B 77 48 71 53 D9 73 07 03 54 D9 28 A8 5A A8 +C8 AA 66 43 E9 B0 6A 60 A8 42 BA 78 63 DF 8C 26 +FE 09 A9 98 D7 53 C2 B2 AF 25 C2 9D FD 45 8C 03 +33 8F B8 18 84 6A 52 57 D8 2A A9 C2 42 1B F2 B4 +42 7D B9 34 B0 B0 8A DC A0 4D 10 E0 54 74 4C C6 +BE 68 BA 77 11 20 D6 63 AF C2 20 18 A0 E2 C4 75 +70 2A 29 B8 25 05 73 81 26 75 55 FA FA A4 71 6C +CB 3A D9 5F 4F 62 77 67 B3 30 13 88 A0 87 00 38 +CC 58 0B D3 6A 8C 40 6C A3 AD E3 43 0F 41 5F 79 +C4 3D 80 C0 B8 2A D8 69 6B F6 08 8F 25 BB EA 36 +AC 7D DB BB C5 E6 53 F7 A2 1A 10 E5 4A CE 07 14 +B9 A2 58 40 60 C4 F0 43 2C C5 EA 07 85 BB 95 5D +7B 75 63 CB 15 CD 60 9F 9D 97 4E 97 99 B4 F1 75 +2F C9 F1 69 31 50 B8 B5 12 7C FD 41 0C 5B B7 B9 +78 4B 0F 8A 42 B7 B1 EB 54 78 A4 B5 EB CB 77 E3 +D4 8E 07 38 06 E3 C4 A7 16 36 44 6B 41 37 B3 92 +90 28 13 A2 CD 47 41 91 C2 21 BC 4B C7 B0 25 70 +B9 F4 0A 28 7B 59 8C 66 82 B4 99 B9 F7 B2 20 AD +19 B2 97 92 99 DD 53 6B 7A 85 78 98 27 91 DD 39 +22 3F F3 57 A2 B0 CA C8 DC 73 AA 1C 98 1A B0 99 +E2 98 A2 A9 39 91 13 E5 A4 FA 33 BA 11 C5 38 8A +D0 A8 A7 03 1F 40 C4 AA C1 B2 7D 9B D8 A9 AE A2 +6D 42 C2 05 D4 46 56 89 14 CD 31 A8 66 36 87 82 +DD DB C4 41 A2 A6 EE 75 58 AC E6 B9 F1 48 18 58 +6A 5E 3A 11 88 E4 05 CA 21 20 A4 E5 08 29 55 83 +7E EB 80 78 15 A6 42 4C 81 4E 54 32 51 DC B2 61 +71 99 7D 4D C7 20 1E 98 4B 83 D4 9F 27 C9 99 7F +24 A7 6C 62 49 5B E0 B2 AC 12 10 09 9C 3B BD C6 +90 C8 82 6B DD 20 9C 72 4B 6C A8 B7 C9 8D 20 06 +E9 E9 C4 9E 96 00 44 F1 AD 39 B7 6F DA B1 B5 94 +21 58 3F F2 CE C7 F6 32 2D 32 3D 86 A4 15 C1 46 +42 1B 29 49 37 2B 52 A6 2B 27 2F 35 3D AD CB 23 +8C 77 C1 64 24 46 40 67 83 16 79 B6 B2 9A AA 69 +48 09 56 C0 6D 42 B2 64 F7 FC BA 85 E0 9D 54 B9 +C3 DB F4 4F A8 28 11 12 09 C5 8C 7A 22 2C C9 3B +AE 3B 49 19 A2 AA 20 28 B2 EF 3C 1E ED 56 70 04 +9B CC FD C5 22 70 70 23 78 49 A8 02 42 24 30 E3 +96 E4 92 90 BE 1A 08 44 BB 8B 64 C4 71 84 B7 23 +8F A4 2C CC E2 A9 7E 25 58 F8 36 14 BC E6 7A 88 +C3 80 EA 53 A8 DC B1 AB F3 14 61 DE 12 5B 79 50 +74 31 13 A5 A9 CC 1A D4 DC 31 79 EB 8C A6 C3 71 +29 42 89 2F C5 0F EA 04 84 93 A0 7F 61 20 7B 35 +84 19 DE 59 9F D2 91 1B ED 84 C4 DC 38 37 AA 67 +1E AE 25 0C B9 04 26 86 9C 3E F1 DC 78 7B D6 37 +23 E4 27 7C D8 6A 0B 5C 07 25 01 B4 F5 E8 13 77 +4C AE 05 38 88 9F 95 23 B2 1C C1 77 8A 57 38 A3 +41 8E DB 1C FA 27 0F 69 64 CA 6A 38 3B C0 A9 CB +9A 25 99 5E 67 C0 58 84 3A C2 A1 68 AD 77 2D E2 +83 02 C2 D2 91 93 A8 27 02 AA C1 34 68 0D B1 53 +C2 2B 40 9D DA 56 B5 CC B6 24 EC B5 73 90 C8 62 +B1 55 65 CA 53 39 8F 09 2A 7B 61 C0 F2 4A 87 03 +F2 9A 8B 32 A0 A0 57 0F 51 02 B0 08 D4 C4 57 A5 +72 60 13 99 E4 6B 0C 63 70 BA 94 21 36 13 CB 66 +00 73 6E 85 42 7E ED 05 67 1B 16 3B 39 E1 C9 23 +9C A6 98 74 81 1B C8 70 11 73 41 4B 24 68 20 CB +6B 81 F3 8B 1D F7 6C 80 E8 87 C7 13 1A 94 79 76 +CA E2 13 DB E9 5B D1 1B 24 85 09 35 E5 2E 03 4F +F5 86 AF 42 92 32 01 AE 5A 7A 33 41 9E B0 9C 47 +FE E0 85 02 69 96 B9 2E B3 56 A1 77 FA CE 01 34 +76 73 0A E2 C1 3A 07 49 29 E3 51 A3 D0 9E DB 26 +FF 1C 6B DB DA 93 04 AB DD 3D B9 AF A2 DE 3E D8 +0D 3D 80 8A 33 26 3B 00 BF F1 D0 B9 FA CE 01 34 +76 73 0A E2 C1 3A 07 49 29 E3 51 A3 7E BE 9B 15 +63 F0 E8 4E E8 4C 9B A9 BE 16 A0 C9 A5 46 8E E6 +0B 69 72 DC 22 92 45 61 B8 63 CF A5 12 EF BF 42 +F7 27 AC 80 73 5D BE 86 0E EF EA 7B 86 7D 07 AF +E8 A4 A5 56 E4 D5 B1 52 52 D2 D6 EB FE 51 47 24 +44 EC C3 AC A0 75 9C 10 9D 42 26 0C 77 6E 27 A5 +D8 A3 8A 94 DF E8 65 92 7C EC CF 48 20 75 B0 77 +9A 3B DC A0 1C FF 59 F5 34 A0 AC C0 B3 08 0A 13 +A0 18 72 62 6E 06 9F D7 07 98 C4 D1 8A FE C5 39 +7E 7C 13 DD AB 12 56 8F BB 94 2D 53 4D FB C4 EF +31 F5 09 6E 48 A9 7A 18 9C 91 AE 53 3B C1 80 FD +D4 66 16 84 53 C1 C6 20 ED F1 56 09 60 31 EC 83 +09 66 C9 23 35 8A F6 5C CC FF 21 8F FD 51 D7 D3 +22 AE 33 88 B3 CD 81 D1 2F 1F 4A 70 E7 6E 58 9E +84 25 EE 06 67 43 2B 74 2B C4 E5 90 30 5B 4E 28 +7B D8 B9 C1 50 83 77 86 50 6E 30 AA 65 14 A9 8B +EB D7 CD AE 90 39 47 45 4A 0A 65 D2 9A 35 D5 AE +EC 24 B5 9D 0E 85 F4 A0 43 B9 71 22 64 78 BB F3 +23 77 40 64 36 71 EE 6B 04 83 BE 15 97 6A 3A 81 +BD 30 A5 43 6A 4A A8 DC BB 29 6C D9 DB AA 84 CD +9E D6 89 FB F9 08 27 05 92 F6 70 A6 BE 53 5A 1E +54 D3 28 E3 38 34 CE BD 02 E9 A8 0A 1A 93 E7 EE +67 A6 34 1C CE A3 40 6C D7 5D 4E 0D 55 3C 23 95 +A9 15 6A 57 9B E1 C9 DD 92 F4 31 AA 77 AE F0 B7 +61 DE 31 D9 6C 1A 8A 36 EB 01 93 C5 F4 18 93 3E +7B E9 C1 01 C4 3A DC F5 1D 67 74 7B 14 B5 60 60 +C3 91 BC 56 EF 22 30 6B F4 9F 0C BC A5 2C FC 91 +82 9B D6 DC 8F 60 24 10 04 78 16 54 8B B0 FA A1 +9F BC 79 DF B3 F7 BE AF FE 36 02 D2 6F ED FB D3 +02 BD 05 38 31 9F 0A E2 B1 4C 51 10 AA 97 ED 7E +33 1A 84 03 49 75 DB 36 AF 8D BB CD 09 E5 45 F0 +DF C0 EF 50 F7 62 C6 DA 53 F7 40 95 5B 9E 16 9F +5D D4 EE 45 38 96 75 FD 28 FF 91 6D AE AC 24 DC +51 68 7C 04 23 FE 40 95 D5 05 4E 1F CF CF 02 63 +D1 E9 AB 41 CD 0F 66 25 05 48 FC 49 42 F0 89 9F +08 85 E0 B2 A5 48 7A C5 4D 8F 79 B4 2D 94 DD 27 +E9 F5 0F 69 92 C8 A3 17 27 4B FC B9 18 08 B5 BE +68 F3 16 C8 D5 54 D3 45 21 0C D8 25 51 71 BD 73 +21 2E DA 70 56 A9 EC D6 EE 4D AA CB EB 3D 3E 6D +50 90 C3 B2 9F 20 14 3E A9 4D 7E DA AB DB 97 D3 +25 F5 77 00 DA 9F E6 DF 3A 2C 07 82 71 32 8A A3 +A2 39 AD 30 C7 52 FD 02 AA 94 05 D1 FE A8 91 03 +48 24 A4 D3 15 31 42 6D 3D 3C 9D C8 81 E4 1C 1C +5E 3A 12 AB E6 2F 87 21 F1 CE 50 1C F4 9E EA BD +30 20 2B 01 52 15 89 5A 2A 4F EF 02 8F 3B C8 B7 +1E 30 0F 09 DC 41 36 92 0B 19 6F 1E C6 74 21 30 +59 7B 6A B9 1A 7A 56 84 B2 72 07 62 C8 94 1D 63 +D3 07 AA 95 12 1F FB 3C 3B 93 01 56 87 AE D2 45 +47 99 51 D8 3D 87 70 B8 EF 6F 79 B4 03 FC AF 9E +76 AB 41 77 FF EF 6F 76 90 23 A7 6A 33 A8 FD 98 +91 40 20 B5 86 1D 31 E1 CB 72 EA C9 14 02 15 B2 +F3 19 0E 69 0F AC FC 77 42 CA 31 9D 3D 40 2C 0C +B6 8A 18 C6 A1 91 9E 6C F3 CC BB D3 0A 0A 16 3B +2D D2 9A 8E 61 C4 D5 44 C4 5A E5 E3 15 9F 86 D9 +50 50 92 A1 73 72 D1 E0 BB 86 49 DA 41 A8 20 F0 +6D 10 B5 D2 A4 0A D3 31 BD 10 BE 2A 8C 0E 29 4E +4C 18 C2 4C 9B 13 2A F5 DB 82 58 B2 92 DA A1 FD +6F 87 43 43 5E C1 FF D4 97 FC 16 EC 17 69 ED 85 +30 CF 82 B6 4B 4E 91 2E D4 07 9D 6D CB 3F 65 FF +A2 87 6C 72 39 95 E8 75 CF E7 F9 EA 6B D7 C4 92 +98 3B 4D 46 79 01 06 56 1B 42 D8 E4 B2 E6 AE A0 +B5 2B 57 06 95 01 D0 BD 0F DD AD 3A D8 31 B7 63 +C3 F0 49 7A 75 74 2F CC 8E DD 1E 07 08 68 13 C1 +6C E9 49 43 F3 D9 13 18 13 60 F1 01 08 57 AA 7E +7B 5F 63 75 6C EC 56 71 70 00 50 51 D7 EC 56 1D +56 9A A9 E6 68 E7 D1 19 B9 35 47 48 03 60 0D B0 +81 C2 B1 0B E5 DB B9 9A B8 56 E9 3F 26 5E EA 21 +9E 0D 50 02 CA E3 2D 39 07 B7 D2 78 A6 97 BF 4E +C1 74 EF AF A4 91 83 BE F1 06 EA C9 47 0D 5B A4 +C7 00 71 03 36 50 06 EA 4C B8 FE 3B 5A E6 F6 5D +BA B4 6E 38 AB 2E 3B 38 50 2B A2 80 A8 DA F9 39 +3D DD 53 0A 84 08 4C 68 7C 3E 39 2F A5 F3 B0 42 +8E 8E 39 12 A9 EF EA 2D E3 AE DE 3C FA 78 BC D4 +32 85 E5 E9 EB 7D F8 97 E5 43 44 E4 8C 96 3C 54 +2E 57 BB 5B EB D8 4F A8 45 E1 39 68 CE 29 EF A2 +59 AD E6 BC 3E 8B E8 AB C3 85 E6 05 51 B4 54 00 +22 95 72 C3 F9 DE D0 49 05 8F BD C8 1A 39 EB 4C +6E 4C 31 FB 33 28 7F 00 D1 29 B0 7E AB 74 EC 69 +5F A3 4A F6 44 A6 D5 22 79 D8 40 DF 67 EF 4F 20 +BF 16 EF AE C7 86 AD 7D B2 75 6B 8B 35 A2 66 41 +95 51 30 6B 38 3F 81 76 28 0E 72 5D 35 42 BE 05 +42 70 F9 20 EE 1F 87 0C E2 22 8B A3 60 CD E4 1A +16 7F 38 5A BC 87 00 4C E1 48 5E 6D 63 3C 8A 58 +48 33 FD 7B 5C 1E A3 48 80 AB 31 97 3B BE AB 9E +F3 F5 B1 C2 57 EC FA 50 7A CB 84 A8 2B 38 D5 A5 +3D 4A EF 12 43 AB 7E 0C 5F FA 4A F0 9C D3 AF C5 +F5 E3 CF A8 DE 0D 9B 30 9E C9 C5 38 3C 89 50 5A +7B 2C E1 6F 04 7D E1 BD B4 FC EF 95 8B 94 79 D6 +BE 5F D0 9D B6 D7 04 6F 6C 28 C8 DB AB AB 81 AF +8E BB E9 28 BE F1 29 62 7C 94 88 E9 AE 6E 9F BB +E3 21 21 46 34 A0 BA 68 D9 39 14 25 15 56 8F 3C +A7 62 8D 3C 3D 13 2B 1B 97 2E 54 21 F8 98 9B EF +A3 3C A1 C3 82 9C 6B 6E 13 63 EF 1D C2 BE 83 11 +99 BC F1 A9 8B 23 35 5B 8C F4 45 E5 58 2F F0 A5 +6C 72 06 C3 F0 58 46 C2 26 35 47 2F B0 BD 96 2D +46 22 EF 14 4F D0 7E 63 4B 1E 27 2C 6B 25 65 8A +E6 C6 C6 84 1C 47 B9 0B 73 24 10 81 E1 EA BA F5 +E7 6D 14 4D C7 BB 42 30 6D 10 2A C9 1A C8 9C 08 +41 1E 4D B7 54 0B 3D C1 5B 75 9E 60 52 B3 40 AF +13 C1 D0 15 CE 9E C2 4F 73 08 C3 AA CA 0C 9E 28 +4F D0 DB 24 8B D9 54 36 1B 82 30 08 08 08 33 8D +3F E7 CC 85 83 10 E9 EB 9D B7 8A 3D 08 07 44 55 +D9 CE 0E D9 3C 82 74 39 AC C4 BD 47 01 62 B5 9C +41 61 04 6C 8A 54 70 96 10 7E A6 26 B4 B6 60 C7 +1A 41 92 2F B8 66 AC 23 85 E2 E9 4B F7 48 AB 75 +B5 82 24 E5 AD C2 E3 33 72 01 1E BD FC 75 9D DA +BF 6A FB 15 B1 90 A4 76 A1 CB CB 5C 68 09 B5 BE +DC D0 92 A8 D5 27 80 D6 5E 1C EC C2 18 C0 2C 17 +47 68 D9 E8 53 A0 E0 BF 71 A8 C0 07 3A 0A 7E A2 +9C 1D 99 45 06 A8 C3 83 A7 03 97 32 02 6C A6 41 +F6 68 83 E1 36 54 86 A6 0F 20 F6 08 8E 34 77 55 +24 A8 18 1C 2E AA 89 35 D0 6C 7E AA C4 8D DA 30 +C6 B7 63 B2 A1 CB 0C 56 58 3F C1 55 B2 F9 57 1E +EB 16 46 B7 AB 54 B6 B0 55 A8 AA 16 EA AB 0B 38 +F7 51 8F 71 6F 23 6A BD 89 84 CF CC 9A BA 38 B2 +23 8B B7 C2 02 50 88 A8 33 74 C5 05 48 50 54 43 +CD 73 88 3D 85 B9 7D CB 97 14 FA 42 47 70 4D A3 +06 B5 24 F6 09 D9 C5 8B 83 84 95 1C 64 26 A8 32 +9B 0F 33 C5 E5 03 14 89 02 6B 28 E8 A9 E0 F0 25 +EA 96 CF E1 A1 BE F4 D2 02 D8 B6 18 15 82 91 C3 +42 12 A9 3B 36 C7 AC 2B 08 C4 9F 36 A9 54 7B D4 +3C C9 F5 B5 60 95 7B 33 09 1C A2 53 1B 14 76 C8 +54 90 4B 18 58 67 CA C1 AE 2C 47 9C EF 65 78 2B +AC 5F D5 46 77 A2 43 90 DC FA 27 82 C2 BE 85 6C +2D 0E A2 20 AF EC 3A C5 62 39 B8 77 8C B5 5C 15 +43 D0 3A 5E 81 CF A5 35 B7 4C 43 8C 03 79 52 90 +26 03 5B 30 B4 DE 61 13 16 E2 AA 32 F7 23 EA 20 +50 D3 0B 6F F9 02 B9 4B F4 8A C6 80 39 C3 3B AC +0C 76 A3 9C B9 A8 59 26 63 F0 D3 94 FA F2 BD 74 +A2 13 3A 35 8C 9D B8 64 7A 60 AB 84 2B CD 94 A1 +BC 2E E4 08 66 2B B8 A2 97 C2 8D 0C 07 7A 27 43 +97 CC 54 ED C0 BD FF 88 7A 1B C2 9A 23 7A 61 AE +D2 0A DF 15 B5 A9 92 23 AA D4 45 D0 19 43 AD 90 +23 82 05 65 82 65 A8 99 98 AF 96 D7 8A DC 0B C6 +A3 07 A0 6E A9 22 6E 67 08 56 E0 72 D3 3B C4 61 +69 BB C5 6B 5D D3 60 AE 12 4A 90 FC 44 3A 17 49 +3D D6 55 04 73 FB 7C F2 40 5B C0 C0 32 EF 90 58 +A3 12 AB D4 D9 87 38 21 A1 4B C5 45 0E 15 BC F9 +B2 3E FF E8 9C F7 40 2F 12 08 C9 E6 76 C6 0F AB +51 AA 1B 2D A9 E7 B8 7C 10 52 2A 17 C3 68 40 8E +85 B8 7E A9 EB 52 8C 80 22 DA E0 BE 8F 26 43 BC +55 B1 8A 88 66 DC E9 36 FC B3 23 EB 8A 37 41 09 +38 72 52 C7 15 51 6F A7 6C 9D A2 96 81 ED 06 6A +B7 9B 53 C3 94 C6 43 15 60 EC FB 25 84 D2 6D 16 +54 11 2E FC 1F A2 FB 9D F8 F0 46 4E 06 0E 60 02 +09 1F 2C 35 6B E5 CC F0 CB 3E 13 3C AE 47 76 49 +5B 5B BE 11 F3 0F 0D 24 09 89 B3 47 2B 19 66 49 +66 06 C5 32 96 B8 C5 89 64 BC 36 F5 89 0B B2 18 +AB 79 C9 00 C7 C2 73 A0 05 1D 01 6C BD 0D F7 91 +5C 74 05 90 5C 36 4E F8 C1 77 45 C0 17 28 B5 2F +59 CE 60 22 C9 33 C0 C0 32 B9 06 16 4A 77 53 B8 +1C 6A B5 0E BE EA C0 E5 44 01 1F FC 20 70 67 53 +02 75 B3 AC EA 02 82 71 45 4C D4 BC 57 D9 49 BB +CA 49 D9 6B C9 EF 26 A9 DD EC 78 CE 6B 19 9B A3 +B5 50 52 16 BA 64 44 84 72 5B 96 31 47 7C 11 99 +11 A1 17 B4 17 54 18 59 83 A7 E3 72 36 A9 9E A9 +82 64 F1 6C 30 D6 94 B4 7A A2 8F D3 D9 C7 D1 6A +47 D2 10 9B A0 A4 1B 31 E2 86 B7 32 39 95 2B 04 +7C 4B 9C AC 59 35 3F D9 54 F0 99 68 E8 81 14 E1 +F1 3F FB 08 85 8D 49 26 B0 16 CD 87 65 A7 68 19 +85 9E F6 26 98 E5 B5 5D A9 3D FF CA 7D C7 A5 70 +92 4A 85 FF 23 88 4D 37 3E C0 D0 52 79 64 5A 0A +CA A2 4F 73 B4 05 42 53 66 56 A0 08 94 B7 87 45 +02 21 8A 51 48 2C 0E 7D C8 27 1C C5 AD 0D 41 19 +CE 92 18 EC 1A A3 89 A2 51 52 1B 2E 65 9B B4 D9 +B6 76 58 6C 91 30 28 53 E8 A4 4D 54 35 AF 4D B0 +96 15 48 3D 00 2A 9A A8 24 0C 61 F8 45 3D 0B 1C +26 53 CF 28 AC 52 D5 EA C2 E0 A8 0D EC 06 05 A1 +80 95 D7 66 97 95 81 92 F2 4B AC 11 32 B9 50 22 +39 62 0B 64 66 19 3E 4B 15 CB 14 76 C3 18 9C 54 +95 38 04 8B F7 2A F0 6B 52 E5 DB 63 D0 11 07 57 +97 96 D0 B0 6B 5E 55 28 6C 50 2F 18 3C 51 85 33 +C2 C8 E9 8A B9 44 BA 6B E6 82 E9 41 57 11 D0 A8 +A1 B3 52 E1 A8 A1 40 4A 6C 76 98 19 A8 45 C8 F0 +F8 61 42 20 7E B1 B6 CF 11 7A 9A A1 2C B2 2A 72 +1F C8 F7 98 2F 99 08 67 20 99 0D 04 21 74 A2 A8 +3F 76 0E B3 13 38 81 90 49 4A 9B C4 81 59 C5 28 +DA B1 D9 CB 9D 95 68 57 D6 F8 7A 48 90 89 45 0A +61 01 70 7D E4 C9 49 95 29 16 75 C3 C2 A0 B0 71 +D8 C5 35 10 DB 15 48 44 C6 14 E7 13 9F 16 02 3D +38 49 84 83 86 4B 7B A9 B2 C0 50 7B CB 23 51 73 +AC 38 75 2F 90 D3 62 54 52 50 6B 41 AA 8D 69 A8 +6B C7 1A A8 53 18 95 56 B3 F7 27 B3 0D 86 B3 8D +20 CA 8B 67 53 00 43 7E 50 4A AA 0D 53 91 65 BC +31 BA E4 90 1F C0 33 62 F2 A0 49 09 5A F0 1B 2F +F3 76 12 CB 5A 67 D3 97 89 62 EA 15 89 CC AE 70 +B1 2D 21 2B 27 2F 5A 32 6C 08 2F 51 A3 25 C0 29 +5E 5B 14 8A 08 25 6B 1B 31 1C C3 A8 80 09 2B 20 +00 D6 95 EB D5 42 9D CC B6 67 84 44 FD 38 A1 74 +40 C4 10 26 56 90 25 39 DD 69 0D 0B BA 4F EE C8 +30 29 38 BF 76 55 52 1A 5A 91 BB 2C 2E 9A 00 A7 +5B A3 19 87 45 B7 20 58 1C 67 6B 8F A6 E9 93 9B +C0 5C 00 7A 42 E7 3C A1 2D CB B7 4A E5 27 A4 3A +6C 3D 64 27 FD 3A 21 84 83 47 02 95 40 CB D9 8F +40 68 6C DB 7C 24 74 1A 4F 70 65 05 61 2D D2 1F +5A 97 51 07 2D 86 2E 2C 8B 92 5E EF 35 C1 83 6A +47 54 2D 80 94 86 7C AB A8 DD 01 53 E8 D2 30 1F +B9 1E C5 F8 0F 96 D9 3E F3 41 31 ED 75 66 16 98 +B0 57 59 9B 8A F2 9D AE 42 11 84 F4 A6 28 64 54 +C9 7A AF C4 57 7C 21 0B 43 75 22 CF B7 44 68 3B +EC 47 C3 DC 4D B7 C7 11 54 2A B6 C4 23 0D C8 43 +A8 D9 0B 0A C7 0A A6 41 77 3F 4C 0C 52 C3 96 8B +91 DB 5A A5 04 5E CC 1B AF 1E C0 86 FD 27 6C 71 +A2 BE 24 E5 6B 4D 27 4E 4F 1B B4 18 D7 36 3E 43 +49 35 10 06 DC 22 A6 73 A2 1D F0 75 1F E2 C2 75 +7E 8C 3F 61 39 B7 7E B0 66 4E 69 9D DD EB 30 DA +6C 33 98 44 2B 78 A2 38 B9 C8 43 C0 14 A5 E2 A4 +6B 04 F4 79 44 A0 61 D8 52 5F A1 01 A0 62 AA C2 +19 E8 0F CE F7 93 73 F7 82 EB BB AD 5C 03 9C 92 +DA 95 AE C0 07 EA B3 43 62 A1 08 78 A2 A5 14 5A +72 1F 2C 85 EF 6A AB 28 42 4C B0 81 B8 D2 18 4A +E8 B2 95 37 3A A9 54 B3 17 A5 B9 03 44 B0 88 9D +7A 53 2D 49 10 46 01 0E 94 3C 1E C0 CC 69 6F C9 +9E 98 1C 33 76 76 79 B5 3B 57 4F 27 77 ED C8 C9 +66 3C 4C 15 32 91 F4 F3 26 48 A5 06 DA 25 33 AF +1A 43 24 69 B8 28 4C AC 2B 59 4A 47 EC 92 82 03 +58 17 B7 25 BA E8 B0 E3 09 4B 88 9C 61 CF 10 43 +0D 49 58 E1 12 66 27 94 BF BC E3 BE 65 A9 33 3A +B0 8B 51 69 C8 6F 26 A0 9F 19 BA 5C 43 82 A2 57 +94 28 E4 89 5E 88 64 F1 B3 63 73 D9 3A 6F E9 4F +01 42 48 98 51 1E 31 1B 57 4D 23 0C DA 56 17 A8 +57 07 C6 C8 64 AA 01 55 80 F3 03 A7 7A 5F F7 E4 +21 8D D0 98 EE 61 CE 0C 27 61 3C BC 3D 86 21 67 +44 E6 7F 0E 64 A6 FD CB 89 EE 40 CC 06 0C 34 4C +D1 B2 AA 13 44 9E 34 6A C8 FA 1C BC 8A B6 68 96 +3A AE D0 90 D6 94 26 82 CA 2A AC 9B 9A 4F D9 42 +73 D4 C3 1E 98 C4 CF 9C 9D 4D 2B AE 92 59 AF 67 +C7 2B 55 1B 56 23 44 34 04 84 B7 DC 01 CE B1 4C +76 4D 46 B9 0F F3 49 6B 27 B9 CE 1B A8 0A 14 45 +84 D8 AB FB F2 84 3B 52 2F E7 21 45 B8 C0 4E 9D +CA 6A 6C 15 46 BD B0 04 4A 1C 33 B3 6A 90 7F B9 +8D DC 59 1A 4E 30 C0 BF B4 BA 62 59 3E B4 A2 9E +EF A5 78 D2 7B C6 DE FC 34 BD 58 0F 96 B8 89 06 +C1 72 46 C1 9D 99 85 7C 36 22 2B AC 80 78 11 FC +CF 60 A4 CA 95 05 22 4C 04 51 3C AC 9A 4A D6 50 +55 E5 69 56 8C 9C 45 D8 28 B9 A3 29 DF 80 5E 00 +F7 48 BB 96 0C 30 0C 83 AA EC 1B 70 1C 2D 29 E0 +0C 0E C6 4E 1B A8 A3 AA A9 71 9F 0C 93 C4 8B 2D +37 35 47 7C DC 06 14 4A 87 18 3C A3 4D 7C 7D 78 +D7 89 35 8B 0B DD 17 CF 28 0A 4C 5F 83 48 28 26 +7E 31 EC 8B 8F E5 A9 CD 66 99 93 D2 25 09 56 72 +8F D5 30 BC 1B 55 B7 D5 44 0A 9B AC 24 E9 C3 9F +C3 9F AF 64 2A A2 49 5A F6 D5 4A 07 35 95 44 AA +C4 D8 1A 0F 5F A7 0B 6A 3C C6 AB 81 30 CE 46 B7 +79 FA C2 50 E3 09 E4 D4 05 8D F2 3A BC 79 0C E1 +B9 8B D2 76 CF 8A 78 43 FC 01 38 27 78 28 F7 59 +B3 59 37 33 5A 76 1F 4F 66 AB 95 11 A2 87 D5 3D +8C AC 24 68 33 22 3F 62 B7 75 F1 4B 71 34 70 49 +64 41 00 ED 94 E6 F1 7D 4F 08 52 AA 29 17 96 91 +96 EA 6B C2 D2 F1 1F 9A 94 14 96 92 5C 9A A6 BE +53 F8 B6 5A 15 91 9E C1 97 77 6A AF 31 84 42 66 +D8 6A 05 A1 64 DA 66 07 49 07 82 41 F9 82 21 4A +BD 6B 35 41 54 13 03 4F AB 37 44 D1 BC FE 4C 90 +2D 8B 12 6C 6B CD 7A 29 68 C0 62 BF 33 9A 65 7D +E3 AA A3 91 68 79 E3 91 B9 89 32 E5 76 AB 9D C8 +C8 4A D9 73 46 75 4F 71 41 17 98 F5 2A FA C4 5B +1F 38 04 48 66 93 81 B4 32 8A 6C 99 3C F5 12 DF +07 14 57 C5 BB 69 B3 44 41 C7 5C D8 29 3A FA 17 +1A 99 A5 5B 4F A8 0E 71 43 AA 04 6A 44 DB B0 91 +33 C0 1B CB 17 BE ED 21 55 53 5C A2 00 FC BF C0 +18 89 67 42 69 C9 38 89 5C 42 9F 0B 08 4E 4C 74 +A1 4C 7A 1C 65 9A 1C 96 35 71 4E 23 5F A6 E7 12 +B4 A5 1A 2C 3A 00 81 2B AD 7C 87 80 9B B3 9A 9C +04 56 31 19 43 56 22 B2 FD 21 C7 6D F0 A4 88 63 +CE 01 F3 8D C3 FA 1A 4F D2 07 7E F1 3A B0 C7 B1 +AE 83 6C 92 E2 1B F7 9C 04 CA A9 47 92 83 7C C6 +76 00 08 C3 5A 62 49 AC 1D 07 46 F8 F0 1C B4 84 +78 E7 98 01 2B 82 6C 65 B7 98 6B C1 88 C0 3C 45 +6E 20 28 FD 40 76 66 69 49 8E C2 84 73 71 07 16 +29 99 0C 84 68 5B 6A 67 B4 C1 C8 29 71 C1 CB F5 +62 FA 04 48 23 A3 AA 26 B8 09 95 E8 BB F1 B3 68 +EC 79 3D 8E 32 C0 3F 40 A2 98 C7 A5 96 70 32 C9 +0C 16 67 AC 6B AA 57 19 BD 38 B4 7B D7 81 29 90 +A8 28 34 3F BC 08 7F 86 39 3B CB C6 93 99 D8 0B +14 D1 A9 20 E7 0B 5D BA 3F 4D C1 CE 4E 40 3A 7B +B3 A7 7A BB 2E 79 CC 00 AA 60 53 68 94 29 87 56 +2D C5 9B B4 19 5A 02 9A C3 8C 17 11 42 A8 C6 B6 +76 C5 CC 6B D2 49 F3 A3 74 86 B6 44 1E 72 B0 FE +6C 69 84 91 06 D2 B9 96 37 46 1E 9C A6 52 2B 44 +63 49 7C 15 0C B5 B8 18 55 0D 03 63 7A EE C6 BF +0D 6B 7A 1A 29 72 25 72 C9 2F 5B 0E 6D A8 9E 2B +60 CA C5 F3 47 D0 16 7C CD 91 BB BD D6 9E 1E 91 +32 11 C7 BD 58 B3 3F 27 9B 33 12 E8 88 53 76 6E +5E 8A C5 DD 12 0D F0 06 0C 23 2C 13 0D 45 89 32 +BC 0D 19 12 B9 39 FB 7A 7D D8 CF 48 CC B6 C7 E5 +48 DC B1 81 53 61 12 C7 48 B1 53 CC BC 1D E5 31 +EF 75 2D 08 89 26 D4 00 0B 31 E6 CB 40 E5 8C 57 +54 B4 70 A8 2F 1D 65 8C A6 D6 44 09 A2 45 BE D3 +CB 4B 7B 22 60 54 C7 6F 4B B1 35 98 62 83 C4 88 +82 47 2E 96 13 B1 56 F0 72 E8 E7 36 6B 19 3F 12 +3B 25 E8 C4 A5 54 E8 4C 5D 5B 3C D5 25 69 08 99 +41 96 5A AF 5D 69 82 64 78 0C 61 81 4C 7D C7 35 +40 39 12 3B 81 7E EC 98 12 82 9C 28 52 B3 40 AF +13 C1 D0 15 CE 9E C2 4F 73 08 C3 AA CA 0C 9E 28 +4F D0 DB 24 8B D9 54 36 1B 82 30 08 08 08 33 8D +3F E7 CC 85 83 10 E9 EB 9D B7 8A 3D 08 07 44 55 +D9 CE 0E D9 3C 82 74 39 AC C4 BD 47 01 62 B5 9C +41 61 04 6C 8A 54 70 96 10 7E A6 26 B4 B6 60 C7 +1A 41 92 2F B8 66 AC 23 85 E2 E9 4B F7 48 AB 75 +B5 82 24 E5 AD C2 E3 33 72 01 1E BD FC 75 9D DA +BF 6A FB 15 B1 90 A4 76 A1 CB CB 5C 68 09 B5 BE +DC D0 92 A8 D5 27 80 D6 5E 1C EC C2 18 C0 2C 17 +47 68 D9 E8 53 A0 E0 BF 71 A8 C0 07 3A 0A 7E A2 +9C 1D 99 45 06 A8 C3 83 A7 03 97 32 02 6C A6 41 +F6 68 83 E1 36 54 86 A6 0F 20 F6 08 8E 34 77 55 +24 A8 18 1C 2E AA 89 35 D0 6C 7E AA C4 8D DA 30 +C6 B7 63 B2 A1 CB 0C 56 58 3F C1 55 B2 F9 57 1E +EB 16 46 B7 AB 54 B6 B0 55 A8 AA 16 EA AB 0B 38 +F7 51 8F 71 6F 23 6A BD 89 84 CF CC 9A BA 38 B2 +23 8B B7 C2 02 50 88 A8 33 74 C5 05 48 50 54 43 +CD 73 88 3D 85 B9 7D CB 97 14 FA 42 47 70 4D A3 +06 B5 24 F6 09 D9 C5 8B 83 84 95 1C 64 26 A8 32 +9B 0F 33 C5 E5 03 14 89 02 6B 28 E8 A9 E0 F0 25 +EA 96 CF E1 A1 BE F4 D2 02 D8 B6 18 15 82 91 C3 +42 12 A9 3B 36 C7 AC 2B 08 C4 9F 36 A9 54 7B D4 +3C C9 F5 B5 60 95 7B 33 09 1C A2 53 1B 14 76 C8 +54 90 4B 18 58 67 CA C1 AE 2C 47 9C EF 65 78 2B +AC 5F D5 46 77 A2 43 90 DC FA 27 82 C2 BE 85 6C +2D 0E A2 20 AF EC 3A C5 62 39 B8 77 8C B5 5C 15 +43 D0 3A 5E 81 CF A5 35 B7 4C 43 8C 03 79 52 90 +26 03 5B 30 B4 DE 61 13 16 E2 AA 32 F7 23 EA 20 +50 D3 0B 6F F9 02 B9 4B F4 8A C6 80 39 C3 3B AC +0C 76 A3 9C B9 A8 59 26 63 F0 D3 94 FA F2 BD 74 +A2 13 3A 35 8C 9D B8 64 7A 60 AB 84 2B CD 94 A1 +BC 2E E4 08 66 2B B8 A2 97 C2 8D 0C 07 7A 27 43 +97 CC 54 ED C0 BD FF 88 7A 1B C2 9A 23 7A 61 AE +D2 0A DF 15 B5 A9 92 23 AA D4 45 D0 19 43 AD 90 +23 82 05 65 82 65 A8 99 98 AF 96 D7 8A DC 0B C6 +A3 07 A0 6E A9 22 6E 67 08 56 E0 72 D3 3B C4 61 +69 BB C5 6B 5D D3 60 AE 12 4A 90 FC 44 3A 17 49 +3D D6 55 04 73 FB 7C F2 40 5B C0 C0 32 EF 90 58 +A3 12 AB D4 D9 87 38 21 A1 4B C5 45 0E 15 BC F9 +B2 3E FF E8 9C F7 40 2F 12 08 C9 E6 76 C6 0F AB +51 AA 1B 2D A9 E7 B8 7C 10 52 2A 17 C3 68 40 8E +85 B8 7E A9 EB 52 8C 80 22 DA E0 BE 8F 26 43 BC +55 B1 8A 88 66 DC E9 36 FC B3 23 EB 8A 37 41 09 +38 72 52 C7 15 51 6F A7 6C 9D A2 96 81 ED 06 6A +B7 9B 53 C3 94 C6 43 15 60 EC FB 25 84 D2 6D 16 +54 11 2E FC 1F A2 FB 9D F8 F0 46 4E 06 0E 60 02 +09 1F 2C 35 6B E5 CC F0 CB 3E 13 3C AE 47 76 49 +5B 5B BE 11 F3 0F 0D 24 09 89 B3 47 2B 19 66 49 +66 06 C5 32 96 B8 C5 89 64 BC 36 F5 89 0B B2 18 +AB 79 C9 00 C7 C2 73 A0 05 1D 01 6C BD 0D F7 91 +5C 74 05 90 5C 36 4E F8 C1 77 45 C0 17 28 B5 2F +59 CE 60 22 C9 33 C0 C0 32 B9 06 16 4A 77 53 B8 +1C 6A B5 0E BE EA C0 E5 44 01 1F FC 20 70 67 53 +02 75 B3 AC EA 02 82 71 45 4C D4 BC 57 D9 49 BB +CA 49 D9 6B C9 EF 26 A9 DD EC 78 CE 6B 19 9B A3 +B5 50 52 16 BA 64 44 84 72 5B 96 31 47 7C 11 99 +11 A1 17 B4 17 54 18 59 83 A7 E3 72 36 A9 9E A9 +82 64 F1 6C 30 D6 94 B4 7A A2 8F D3 D9 C7 D1 6A +47 D2 10 9B A0 A4 1B 31 E2 86 B7 32 39 95 2B 04 +7C 4B 9C AC 59 35 3F D9 54 F0 99 68 E8 81 14 E1 +F1 3F FB 08 85 8D 49 26 B0 16 CD 87 65 A7 68 19 +85 9E F6 26 98 E5 B5 5D A9 3D FF CA 7D C7 A5 70 +92 4A 85 FF 23 88 4D 37 3E C0 D0 52 79 64 5A 0A +CA A2 4F 73 B4 05 42 53 66 56 A0 08 94 B7 87 45 +02 21 8A 51 48 2C 0E 7D C8 27 1C C5 AD 0D 41 19 +CE 92 18 EC 1A A3 89 A2 51 52 1B 2E 65 9B B4 D9 +B6 76 58 6C 91 30 28 53 E8 A4 4D 54 35 AF 4D B0 +96 15 48 3D 00 2A 9A A8 24 0C 61 F8 45 3D 0B 1C +26 53 CF 28 AC 52 D5 EA C2 E0 A8 0D EC 06 05 A1 +80 95 D7 66 97 95 81 92 F2 4B AC 11 32 B9 50 22 +39 62 0B 64 66 19 3E 4B 15 CB 14 76 C3 18 9C 54 +95 38 04 8B F7 2A F0 6B 52 E5 DB 63 D0 11 07 57 +97 96 D0 B0 6B 5E 55 28 6C 50 2F 18 3C 51 85 33 +C2 C8 E9 8A B9 44 BA 6B E6 82 E9 41 57 11 D0 A8 +A1 B3 52 E1 A8 A1 40 4A 6C 76 98 19 A8 45 C8 F0 +F8 61 42 20 7E B1 B6 CF 11 7A 9A A1 2C B2 2A 72 +1F C8 F7 98 2F 99 08 67 20 99 0D 04 21 74 A2 A8 +3F 76 0E B3 13 38 81 90 49 4A 9B C4 81 59 C5 28 +DA B1 D9 CB 9D 95 68 57 D6 F8 7A 48 90 89 45 0A +61 01 70 7D E4 C9 49 95 29 16 75 C3 C2 A0 B0 71 +D8 C5 35 10 DB 15 48 44 C6 14 E7 13 9F 16 02 3D +38 49 84 83 86 4B 7B A9 B2 C0 50 7B CB 23 51 73 +AC 38 75 2F 90 D3 62 54 52 50 6B 41 AA 8D 69 A8 +6B C7 1A A8 53 18 95 56 B3 F7 27 B3 0D 86 B3 8D +20 CA 8B 67 53 00 43 7E 50 4A AA 0D 53 91 65 BC +31 BA E4 90 1F C0 33 62 F2 A0 49 09 5A F0 1B 2F +F3 76 12 CB 5A 67 D3 97 89 62 EA 15 89 CC AE 70 +B1 2D 21 2B 27 2F 5A 32 6C 08 2F 51 A3 25 C0 29 +5E 5B 14 8A 08 25 6B 1B 31 1C C3 A8 80 09 2B 20 +00 D6 95 EB D5 42 9D CC B6 67 84 44 FD 38 A1 74 +40 C4 10 26 56 90 25 39 DD 69 0D 0B BA 4F EE C8 +30 29 38 BF 76 55 52 1A 5A 91 BB 2C 2E 9A 00 A7 +5B A3 19 87 45 B7 20 58 1C 67 6B 8F A6 E9 93 9B +C0 5C 00 7A 42 E7 3C A1 2D CB B7 4A E5 27 A4 3A +6C 3D 64 27 FD 3A 21 84 83 47 02 95 40 CB D9 8F +40 68 6C DB 7C 24 74 1A 4F 70 65 05 61 2D D2 1F +5A 97 51 07 2D 86 2E 2C 8B 92 5E EF 35 C1 83 6A +47 54 2D 80 94 86 7C AB A8 DD 01 53 83 71 4B AD +48 B7 82 9C A0 75 B3 E9 05 B2 BD 65 1E C8 F4 A7 +DF 95 4A A9 5F 44 8C 0F 64 CF 82 F9 2D BE E7 43 +73 A7 66 F5 54 CD 73 D6 72 55 95 A1 6B BA CB B8 +35 35 48 FE AB CF 5F 70 3A 42 DF F8 18 EB 63 EF +9B 8D E0 24 20 D4 D8 90 41 C1 2F 0D 4A 0C 1F C6 +7E 92 7B 10 4A 00 10 16 F9 48 93 70 CC ED 15 19 +B7 81 07 57 62 CE 89 64 B1 78 83 51 FE E8 B5 62 +AA 7B 1A E7 C3 F6 E8 A8 8D 03 BC F0 EA 14 6F 81 +1F 69 C6 36 94 82 92 64 84 87 1A 17 BE 9C C0 68 +CE B8 61 E3 E1 44 FF 28 93 BB D9 8F 35 00 92 95 +DA 23 C2 E8 69 32 C0 53 56 92 8B E6 32 C1 AA 46 +6C 89 E1 B9 F6 65 2E 1B 0A 75 89 95 2C 59 92 21 +01 B4 CB C0 C5 4E 8D F8 89 DA 15 71 8C F1 61 E0 +69 2E 8D EB 0D 88 89 80 D3 B1 1B 34 B1 57 34 31 +40 9F B1 78 70 F2 08 2E 20 0B 13 6C 15 1A 70 B2 +72 F7 2D 6A 77 12 3C DA 5B CC 21 87 45 99 A2 06 +F2 CC 14 60 69 99 85 A2 77 D3 0B 21 DA 6D 8D C6 +15 7D D3 7C 85 EB B9 66 19 46 0A FB 22 24 AC 81 +F3 9A A1 E1 B4 5A 42 8B 51 51 DC BA DC F9 B9 DA +A0 92 1B 8B 50 DE D8 16 F1 FC 5F 1D 94 4C CC C6 +03 5C CB 52 E3 A4 52 BB D5 42 4D 32 39 77 83 22 +52 96 36 14 74 2E 01 15 44 52 5B A6 1B 03 43 18 +E7 96 E3 27 02 A8 31 5A 37 4B BA 7A 39 24 57 08 +70 75 98 24 3B E9 2C DD C6 BE 2B 40 A0 27 A2 8A +E0 58 21 9E 1C 14 31 C1 B3 78 91 AA BD 12 00 9F +08 AA 66 D6 97 8E C4 35 A7 11 2A C4 17 7C DF C1 +86 84 56 A1 BD B1 8F 0E F0 21 C8 B1 10 DB 92 A8 +B7 54 8C 88 96 05 F6 02 8E BA 12 A8 17 74 8F 82 +36 AE 7D 52 06 BF 69 2D 7C A9 4E 2E F3 47 EB D4 +95 19 E8 8D 89 5A 08 0C 29 6A 95 98 76 38 D7 07 +AA 44 B8 84 04 4C C2 97 47 67 35 65 F1 30 6D 81 +37 87 85 35 80 99 75 BC 9F 10 5F 33 5A 7C AA 52 +0F AC A1 42 ED 34 83 65 05 17 60 EA C0 2E 7C 52 +84 20 4E 17 24 B5 65 5C 80 A3 C8 CC A4 FB 5B E6 +FB 26 5F 42 B6 70 09 2E C6 32 95 07 36 91 D8 E9 +3A 4E EB B4 67 29 9E C0 7B 69 48 82 17 E1 84 20 +77 E7 4A 7F EA 88 74 D1 9A D1 BB 97 E3 37 1B 87 +A8 2D AD 62 07 0E E6 49 7C 26 8E FC 21 26 19 45 +8F 7E 35 02 60 62 6E 13 B3 1E 87 04 7E EB 02 08 +60 21 8C 44 2B 09 DE FB 78 39 44 A2 FB 81 8D 3E +4A B2 67 30 0A 29 12 A1 C2 E9 66 6B 90 25 49 5A +8B 9C 37 A4 51 A1 2C 48 69 C2 56 A0 77 A2 07 5C +DA 0A 2A B3 80 44 37 F6 1E 0F C7 55 FF 92 A4 6C +E0 AF 94 86 23 6C 6A 94 4C 41 55 83 D6 4D 32 62 +22 D9 88 74 34 B2 71 DC 37 60 6C AB 79 4B CA 99 +F5 AA 8A F8 31 A1 27 63 96 20 3C 8D 4B A0 28 5D +DA 37 B7 CA CD 81 53 C7 61 51 73 95 16 8A DB 36 +CC F2 08 B3 96 17 A8 C6 F5 AC CD 19 33 D2 77 7D +4B FC 77 B6 05 2B 87 F4 C4 E9 99 6F 2D 4A A1 9F +D1 10 25 4C 82 53 6A 4D 64 E7 2D 4F 78 3A 93 47 +9D CE B6 25 15 AB 23 98 A5 24 45 F7 9C 56 F6 8F +8C C8 72 E5 90 48 80 06 48 7E 31 30 34 10 0D B4 +F5 9E 60 12 19 D5 59 19 0C EC 24 AF E2 58 08 F4 +A5 73 7B 84 B7 16 00 23 7C 2B 60 37 4F 31 B6 BE +4C 85 4F C3 69 3B 2E 84 32 FE 8C 9A 4C 16 53 16 +32 47 DE 1C B9 3C 23 09 2E 9A 6E B3 10 0B B4 95 +6A DC 10 C2 3F 43 95 B6 E4 65 53 D4 65 D6 25 B7 +8C 77 80 04 59 81 62 F3 4C D9 26 B8 69 31 19 39 +71 4F CB 85 59 00 34 55 7F 2B 5E 8F A6 20 66 26 +4A F5 4C 1A 1E 41 CD 08 BC 40 35 3B 7F D7 11 98 +00 BB 5C 60 46 74 DD 87 A7 F6 CC 92 B3 61 8C 7F +17 2D EE 42 75 23 91 87 2F 3B 8F 1F 2C 80 57 88 +85 68 25 5E A4 F1 10 0A E3 33 E9 43 07 42 FB 1F +3C 00 C6 9D 7A 01 75 15 49 1E E2 6B EE 13 61 60 +79 90 AE 7B C4 38 AA 2F D2 7B 37 D1 52 28 01 10 +63 C7 60 31 2F FB 4E 8F D6 83 A4 C1 03 20 13 99 +67 B0 55 EF 47 32 87 46 BE F3 17 4F 79 E4 5B BF +86 4A 2E A7 37 E5 F8 BF 40 2A 2D 91 EB CF 47 A7 +48 CC 95 2E ED 2B AA FA 26 94 15 E8 AB BD E9 98 +C3 01 95 A3 83 11 7B BB A9 B0 4B 8B FE 77 59 99 +3C 83 E2 A2 A1 B0 7B AE C2 C7 09 2E CC C3 A5 4C +51 56 94 91 14 AC 61 89 13 5C 36 27 07 50 89 31 +EE F1 C4 9F 67 72 81 9C 5E 64 C0 4D 9F 16 A6 2A +43 89 E6 DC 8E 1F A6 63 B8 63 CF 4D B1 B5 11 35 +CB 14 45 76 E9 44 3E B1 D8 13 78 9C C8 72 71 98 +39 78 54 C3 A8 13 96 6C 21 82 73 13 3F C8 CF 27 +5B 3E 3D 1B 91 1F C3 3F 84 37 99 65 95 C0 86 69 +50 43 F0 27 A2 B8 02 D2 57 32 75 06 3A C4 3A 35 +1F C3 62 6E C5 17 46 21 14 D9 41 0E A4 9C 7F 38 +B7 77 06 02 9F 1C 27 7F C3 67 89 71 98 B3 17 82 +0E 22 42 95 0D 2A A6 C3 A2 77 E6 70 01 C1 15 A9 +9B DA 83 CC 80 1C BE 77 2C C3 D7 14 77 90 2D BF +5C C9 85 CB 52 EC 76 B4 D5 2A 03 94 46 C2 7A 3C +38 14 96 6F 65 12 AC 32 8B 5D FA F7 2A BC 6A B3 +B1 58 13 DA 16 4D F2 81 70 3B F4 1B 3A 66 39 49 +66 97 BC 85 B7 8A D4 8D 55 2C 85 B0 40 70 E2 07 +3A E8 7C 3F 57 E1 5E E4 99 64 37 B1 40 73 E8 3B +FF 56 B2 E1 30 95 40 EB 46 28 D3 6E 3F E7 C7 90 +AC 08 15 F9 5B 2A 32 BB 24 4B 17 D4 E0 6C AA D9 +A9 51 51 26 8F FB 9D BA D2 11 D1 AA 6F E2 51 A8 +C6 17 3F F1 06 88 FC 4C 0C E7 39 4F 40 58 0E 4D +07 BE 78 A1 AF F8 94 79 2A BB 77 13 53 98 2F 94 +9D E7 95 57 44 5B 7E 43 EB B7 DD B2 C9 11 46 9C +F0 09 C7 A6 A3 58 2D 5A 3D 5B E0 AC C3 B8 48 67 +95 48 E0 FC 0A 2C D7 94 E2 4A 5D BB 41 6E 57 1B +C6 29 25 58 EE 34 4D 85 88 B8 72 44 A2 EF 93 76 +36 B4 A0 A6 E0 20 1C C8 4F 02 4C 0A 59 58 74 87 +A4 84 0F 50 A9 C2 19 6F 25 27 3A 58 13 B1 B5 83 +A3 7B 0B 3E 8D C7 50 21 AA 60 D0 C0 73 CE 48 1A +F5 48 A8 CA 47 2C DF 17 55 E0 E7 0D 2E 2C 62 88 +04 0B D6 D8 30 0B 76 1B A2 F8 B4 CC F6 59 75 38 +2F E2 F5 14 E5 B5 50 C8 43 BA 66 C8 5B 70 90 0E +E5 D9 73 C9 29 7A 8A C8 4A 82 F2 16 48 A4 9C 44 +D7 31 D9 08 8D B7 A8 43 31 13 50 01 1B 1C B9 57 +C7 58 DA 99 89 4C 2C 72 B7 6D 5F 16 81 47 B4 C0 +26 82 67 B3 F3 6C 04 E5 49 81 99 01 FD F7 A9 3A +10 97 72 93 CB D5 2B 66 2C F7 7D 90 20 5E F3 4C +B6 2A 88 5F 61 0C 5D 28 68 A9 BF 6A 73 0A 88 30 +0C 6A 52 74 42 12 1C 22 6E 8A B4 14 1D 88 5A F0 +B1 AA FF 42 51 C0 D7 C3 EB 89 38 44 D4 B5 69 9B +4A DE 3B A9 57 5B 45 8D C3 08 EA BC 0C 54 5C 10 +02 9B 72 70 CA 82 84 D3 03 33 C6 21 9C 15 14 A3 +91 0A 82 CC 80 73 B7 27 C7 D9 04 70 92 49 8F 38 +02 4C FC 79 F3 34 7B 58 AA AC 83 40 77 7C DA 1A +5E 65 21 6F B4 A5 52 15 77 79 80 30 FC B1 42 CD +73 38 39 A6 C1 A2 48 4D E2 11 A1 D0 69 6A 41 5C +AA 11 39 34 B9 74 28 BE E9 6C 74 47 07 32 61 09 +27 F0 2E B6 4B 1C 32 54 B9 D1 05 0A 22 D2 77 31 +06 6C 14 63 3B BC 24 06 3A 7A 14 9B C9 08 8D 2B +73 F6 7A 87 24 44 37 B0 21 8B 37 1B 4A E1 8B 40 +B0 C2 38 A7 8B 66 6D C8 C9 C0 F0 BD 38 90 1A FB +E7 7E 67 91 4D 4E D7 0F 7C F4 B8 1F E0 8B 56 2A +BC DE 55 CD 58 F9 57 92 92 1B 5E 75 8E 65 93 8E +47 F8 01 6C 4A CF 01 BB 60 D6 06 90 63 2A 07 51 +59 30 51 89 44 17 14 05 B0 EC AF C7 76 71 83 F9 +9E CA A5 1E 60 17 C8 05 73 73 47 C0 19 AC 91 C3 +AB 3C 5F C5 7A C5 EF 12 46 22 5C 23 CF 8B 43 CE +7C C5 74 A1 AE 49 69 34 13 27 0A DB 04 98 D6 60 +9E ED 80 43 2C 6C 5E 13 27 93 4F 16 85 82 D9 86 +3D 11 2C AA F7 4D 0A 20 B9 A5 79 AC 9D 77 37 6F +8C 12 D6 30 AD 14 94 29 6F 99 22 3A DC 46 BD 5A +A1 C9 1C A9 96 5C 72 F3 33 0C C3 E5 00 AE 78 02 +DD 16 47 14 75 77 A9 F1 8E 74 F7 B0 22 E7 2E 9D +C2 27 C5 3B 75 8E 86 16 BC F7 AC 6A 0C 21 FD 96 +67 9E 65 45 6C CB C8 82 91 4C 35 8C 99 D7 BC 2B +55 5A 19 03 96 8B 5A 23 64 EB 1B 28 CF FB 37 CD +6B C3 E3 45 69 F8 B0 B8 8D D1 84 91 24 93 F2 63 +05 9B E4 A6 E1 32 B4 C2 DB 37 65 51 50 EF 22 23 +B0 46 4B 8C 44 3D 9C BB 99 83 B7 3A 68 CB B0 8A +96 8B 77 48 71 53 D9 73 07 03 54 D9 28 A8 5A A8 +C8 AA 66 43 E9 B0 6A 60 A8 42 BA 78 63 DF 8C 26 +FE 09 A9 98 D7 53 C2 B2 AF 25 C2 9D FD 45 8C 03 +33 8F B8 18 84 6A 52 57 D8 2A A9 C2 42 1B F2 B4 +42 7D B9 34 B0 B0 8A DC A0 4D 10 E0 54 74 4C C6 +BE 68 BA 77 11 20 D6 63 AF C2 20 18 A0 E2 C4 75 +70 2A 29 B8 25 05 73 81 26 75 55 FA FA A4 71 6C +CB 3A D9 5F 4F 62 77 67 B3 30 13 88 A0 87 00 38 +CC 58 0B D3 6A 8C 40 6C A3 AD E3 43 0F 41 5F 79 +C4 3D 80 C0 B8 2A D8 69 6B F6 08 8F 25 BB EA 36 +AC 7D DB BB C5 E6 53 F7 A2 1A 10 E5 4A CE 07 14 +B9 A2 58 40 60 C4 F0 43 2C C5 EA 07 85 BB 95 5D +7B 75 63 CB 15 CD 60 9F 9D 97 4E 97 99 B4 F1 75 +2F C9 F1 69 31 50 B8 B5 12 7C FD 41 0C 5B B7 B9 +78 4B 0F 8A 42 B7 B1 EB 54 78 A4 B5 EB CB 77 E3 +D4 8E 07 38 06 E3 C4 A7 16 36 44 6B 41 37 B3 92 +90 28 13 A2 CD 47 41 91 C2 21 BC 4B C7 B0 25 70 +B9 F4 0A 28 7B 59 8C 66 82 B4 99 B9 F7 B2 20 AD +19 B2 97 92 99 DD 53 6B 7A 85 78 98 27 91 DD 39 +22 3F F3 57 A2 B0 CA C8 DC 73 AA 1C 98 1A B0 99 +E2 98 A2 A9 39 91 13 E5 A4 FA 33 BA 11 C5 38 8A +D0 A8 A7 03 1F 40 C4 AA C1 B2 7D 9B D8 A9 AE A2 +6D 42 C2 05 D4 46 56 89 14 CD 31 A8 66 36 87 82 +DD DB C4 41 A2 A6 EE 75 58 AC E6 B9 F1 48 18 58 +6A 5E 3A 11 88 E4 05 CA 21 20 A4 E5 08 29 55 83 +7E EB 80 78 15 A6 42 4C 81 4E 54 32 51 DC B2 61 +71 99 7D 4D C7 20 1E 98 4B 83 D4 9F 27 C9 99 7F +24 A7 6C 62 49 5B E0 B2 AC 12 10 09 9C 3B BD C6 +90 C8 82 6B DD 20 9C 72 4B 6C A8 B7 C9 8D 20 06 +E9 E9 C4 9E 96 00 44 F1 AD 39 B7 6F DA B1 B5 94 +21 58 3F F2 CE C7 F6 32 2D 32 3D 86 A4 15 C1 46 +42 1B 29 49 37 2B 52 A6 2B 27 2F 35 3D AD CB 23 +8C 77 C1 64 24 46 40 67 83 16 79 B6 B2 9A AA 69 +48 09 56 C0 6D 42 B2 64 F7 FC BA 85 E0 9D 54 B9 +C3 DB F4 4F A8 28 11 12 09 C5 8C 7A 22 2C C9 3B +AE 3B 49 19 A2 AA 20 28 B2 EF 3C 1E ED 56 70 04 +9B CC FD C5 22 70 70 23 78 49 A8 02 42 24 30 E3 +96 E4 92 90 BE 1A 08 44 BB 8B 64 C4 71 84 B7 23 +8F A4 2C CC E2 A9 7E 25 58 F8 36 14 BC E6 7A 88 +C3 80 EA 53 A8 DC B1 AB F3 14 61 DE 12 5B 79 50 +74 31 13 A5 A9 CC 1A D4 DC 31 79 EB 8C A6 C3 71 +29 42 89 2F C5 0F EA 04 84 93 A0 7F 61 20 7B 35 +84 19 DE 59 9F D2 91 1B ED 84 C4 DC 38 37 AA 67 +1E AE 25 0C B9 04 26 86 9C 3E F1 DC 78 7B D6 37 +23 E4 27 7C D8 6A 0B 5C 07 25 01 B4 F5 E8 13 77 +4C AE 05 38 88 9F 95 23 B2 1C C1 77 8A 57 38 A3 +41 8E DB 1C FA 27 0F 69 64 CA 6A 38 3B C0 A9 CB +9A 25 99 5E 67 C0 58 84 3A C2 A1 68 AD 77 2D E2 +83 02 C2 D2 91 93 A8 27 02 AA C1 34 68 0D B1 53 +C2 2B 40 9D DA 56 B5 CC B6 24 EC B5 73 90 C8 62 +B1 55 65 CA 53 39 8F 09 2A 7B 61 C0 F2 4A 87 03 +F2 9A 8B 32 A0 A0 57 0F 51 02 B0 08 D4 C4 57 A5 +72 60 13 99 E4 6B 0C 63 70 BA 94 21 36 13 CB 66 +00 73 6E 85 42 7E ED 05 67 1B 16 3B 39 E1 C9 23 +9C A6 98 74 81 1B C8 70 11 73 41 4B 24 68 20 CB +6B 81 F3 8B 1D F7 6C 80 E8 87 C7 13 1A 94 79 76 +CA E2 13 DB E9 5B D1 1B 24 85 09 35 E5 2E 03 4F +F5 86 AF 42 92 32 01 AE 5A 7A 33 41 9E B0 9C 47 +FE E0 85 02 69 96 B9 2E B3 56 A1 77 AC C8 44 B3 +F8 87 F1 E5 B7 BF BA 07 32 A4 BC 47 51 FA 39 43 +D4 31 7C DB 2E 7E 55 E2 9A A5 1F 20 7E A8 CA D3 +46 5D 01 BB B2 27 C9 D3 F1 E0 DC 79 42 51 CC 8F +E6 5F 6F 51 21 B8 32 E0 78 5F 4B 32 03 00 00 00 +CC 00 03 30 8C 24 00 00 E6 23 00 00 E6 23 00 00 +E6 23 00 00 E6 23 00 00 E6 23 00 00 E6 23 00 00 +E6 23 00 00 E6 23 00 00 E6 23 00 00 E6 23 00 00 +CC 25 00 00 58 25 00 00 E6 23 00 00 E6 23 00 00 +E6 23 00 00 E6 23 00 00 E6 23 00 00 E6 23 00 00 +E6 23 00 00 E6 23 00 00 E6 23 00 00 E6 23 00 00 +34 25 00 00 E6 23 00 00 E6 23 00 00 E6 23 00 00 +0C 25 00 00 E6 23 00 00 B0 24 00 00 E6 23 00 00 +E6 23 00 00 8C 24 00 00 06 2C 4C C7 74 E2 13 BE +68 66 3B C0 E9 33 78 7E E2 CA AE 3A FA 44 3E E6 +7D EF AA 89 12 1C A2 61 73 6E 6E BB B8 60 9D 35 +68 E6 B7 23 C9 BC 33 0F 0C A0 0E CA 39 65 91 72 +B4 73 B9 36 2D D3 3C A5 BC 62 30 95 82 3D AF E1 +90 99 83 14 FE DB AC 42 58 39 50 63 23 45 64 53 +21 23 AD FC EF DA 23 44 77 F2 81 7A 9E 46 51 52 +25 55 33 2B 89 FC C5 99 0E D7 54 FD 2B F3 47 F7 +6F D4 E1 B8 52 CD AC 30 36 BE C1 6B F9 34 7B D2 +68 1F 02 09 3A 31 B8 A6 83 C6 4C 93 A6 FF 43 D5 +7D C5 9C 8A AB 63 5B AC F0 A5 EB 3C 5D 1F 06 22 +D3 E1 2C B7 6E 4B D9 B4 DD 34 5B A3 53 5C 16 A9 +EB 0D 31 CB 2F 6D 8D BE DC 28 CA 92 11 56 3C 29 +39 B4 39 82 8A 8B 2C 5B 2E 88 25 3D C7 1D C1 3E +D2 28 F2 9D A5 D5 5A 7A CA A1 E4 24 C3 1D D2 5C +0A AC 3A A8 6C EB C5 F3 42 D7 C3 77 A6 8A 47 AF +ED 07 7E 39 C6 35 62 2D 29 28 6E A8 B9 EE 60 EE +F3 FA 21 2F 02 47 C8 90 38 E0 8E F9 52 AA C5 8D +22 3C 65 C2 BC C6 11 69 23 86 AB D4 6D 5C 73 42 +D4 AA BF 1A 6F 0B 04 B8 A5 A1 E4 C2 71 F7 0E E1 +76 B1 CD F8 2A D5 5F 56 18 90 CC 73 77 04 61 2D +34 49 A1 79 BD D4 16 BE B4 B6 1A A7 2B E9 73 60 +37 67 AC 66 F1 E0 35 E8 23 A4 2C 63 43 E0 15 82 +63 7C 05 32 5E B0 1C 18 48 C7 09 1F 8B EC 3C 8A +AD EA 25 CE F2 C4 EB B3 0D EA 0F D3 A6 61 0D 88 +23 F3 BA 8E 77 F0 19 8B 3F 84 A6 22 D2 38 50 36 +D3 7D A0 D3 6A 1B AF 6C E1 C4 60 F0 6F A4 7A 18 +EA 69 CD C3 E0 22 B5 BC 8A 3B FA B6 78 70 18 9C +8E 17 3B 0C E6 FB 90 4E 7E 36 76 97 2B FF 37 87 +F4 A3 A6 E1 C2 2B 6C 4E 18 6B 3A F9 07 CD 14 0A +85 04 FD E7 C5 15 3A DA 64 50 02 50 00 C0 01 10 +0A 00 00 00 01 00 00 00 00 00 00 00 78 50 02 50 +28 C0 01 10 0C 00 00 00 FF FF FF FF 00 00 00 00 +94 50 02 50 58 C0 01 10 0C 00 00 00 FF FF FF FF +00 00 00 00 B0 50 02 50 88 C0 01 10 0C 00 00 00 +FF FF FF FF 00 00 00 00 CC 50 02 50 B8 C0 01 10 +0C 00 00 00 FF FF FF FF 00 00 00 00 E8 50 02 50 +E8 C0 01 10 0C 00 00 00 FF FF FF FF 00 00 00 00 +04 51 02 50 18 C1 01 10 0C 00 00 00 FF FF FF FF +00 00 00 00 20 51 02 50 48 C1 01 10 0C 00 00 00 +FF FF FF FF 00 00 00 00 3C 51 02 50 78 C1 01 10 +0C 00 00 00 FF FF FF FF 00 00 00 00 58 51 02 50 +A8 C1 01 10 0C 00 00 00 FF FF FF FF 00 00 00 00 +74 51 02 50 D8 C1 01 10 0C 00 00 00 FF FF FF FF +00 00 00 00 90 51 02 50 08 C2 01 10 0A 00 00 00 +00 00 00 00 00 00 00 00 A0 51 02 50 30 C2 01 10 +0C 00 00 00 FF FF FF FF 00 00 00 00 B4 51 02 50 +60 C2 01 10 0C 00 00 00 FF FF FF FF 00 00 00 00 +C8 51 02 50 90 C2 01 10 0C 00 00 00 FF FF FF FF +00 00 00 00 DC 51 02 50 C0 C2 01 10 0C 00 00 00 +FF FF FF FF 00 00 00 00 F0 51 02 50 F0 C2 01 10 +0C 00 00 00 FF FF FF FF 00 00 00 00 04 52 02 50 +20 C3 01 10 0C 00 00 00 FF FF FF FF 00 00 00 00 +18 52 02 50 50 C3 01 10 0C 00 00 00 FF FF FF FF +00 00 00 00 2C 52 02 50 80 C3 01 10 0C 00 00 00 +FF FF FF FF 00 00 00 00 40 52 02 50 B0 C3 01 10 +0C 00 00 00 FF FF FF FF 00 00 00 00 54 52 02 50 +E0 C3 01 10 0C 00 00 00 FF FF FF FF 00 00 00 00 +68 52 02 50 10 C4 01 10 0A 00 00 00 00 00 00 00 +00 00 00 00 84 52 02 50 38 C4 01 10 0A 00 00 00 +FF FF FF FF 00 00 00 00 98 52 02 50 60 C4 01 10 +08 00 00 00 00 00 00 00 00 00 00 00 B8 52 02 50 +80 C4 01 10 08 00 00 00 01 00 00 00 00 00 00 00 +D8 52 02 50 A0 C4 01 10 08 00 00 00 FF FF FF FF +00 00 00 00 00 00 00 00 00 00 00 00 0C 00 00 00 +01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00 +05 00 00 00 06 00 00 00 07 00 00 00 08 00 00 00 +09 00 00 00 0A 00 00 00 0B 00 00 00 01 00 00 00 +0C 00 00 00 0C 00 00 00 0D 00 00 00 0E 00 00 00 +0F 00 00 00 10 00 00 00 11 00 00 00 12 00 00 00 +13 00 00 00 14 00 00 00 15 00 00 00 16 00 00 00 +03 00 00 00 01 00 00 00 17 00 00 00 17 00 00 00 +17 00 00 00 17 00 00 00 17 00 00 00 17 00 00 00 +17 00 00 00 17 00 00 00 17 00 00 00 17 00 00 00 +19 00 00 00 02 00 00 00 01 00 00 00 1A 00 00 00 +1A 00 00 00 1A 00 00 00 1A 00 00 00 1A 00 00 00 +1A 00 00 00 1A 00 00 00 1A 00 00 00 FF FF FF FF +FF FF FF FF BC F8 00 00 74 F9 00 00 74 F9 00 00 +C6 F8 00 00 0C F9 00 00 74 F9 00 00 74 F9 00 00 +BC F8 00 00 74 F9 00 00 4E F9 00 00 BC F8 00 00 +74 F9 00 00 32 F9 00 00 BC F8 00 00 74 F9 00 00 +74 F9 00 00 74 F9 00 00 24 F9 00 00 F0 8D 2C 69 +00 00 00 00 EC 34 02 50 54 35 02 50 BC 35 02 50 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 +0E 33 CD AB 34 12 6D E6 EC DE 05 00 0B 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 2D 2D 2D 2D 2D 2D 2D 2D +2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D +2D 2D 2D 2D 00 00 00 00 20 52 75 6E 6E 69 6E 67 +20 4D 4C 4B 45 4D 20 53 6D 6F 6B 65 20 54 65 73 +74 20 21 21 00 00 00 00 49 6E 3A 61 78 69 5F 64 +6D 61 5F 6E 6F 74 69 66 00 00 00 00 49 6E 3A 61 +78 69 5F 64 6D 61 5F 65 72 72 6F 72 00 00 00 00 +49 6E 3A 61 62 72 5F 65 72 72 6F 72 00 00 00 00 +49 6E 3A 73 68 61 35 31 32 5F 61 63 63 5F 6E 6F +74 69 66 00 49 6E 3A 73 68 61 35 31 32 5F 61 63 +63 5F 65 72 72 6F 72 00 49 6E 3A 73 6F 63 5F 69 +66 63 5F 6E 6F 74 69 66 00 00 00 00 49 6E 3A 73 +6F 63 5F 69 66 63 5F 65 72 72 6F 72 00 00 00 00 +49 6E 3A 73 68 61 33 5F 6E 6F 74 69 66 00 00 00 +49 6E 3A 73 68 61 33 5F 65 72 72 6F 72 00 00 00 +49 6E 3A 73 68 61 32 35 36 5F 6E 6F 74 69 66 00 +49 6E 3A 73 68 61 32 35 36 5F 65 72 72 6F 72 00 +49 6E 3A 73 68 61 35 31 32 5F 6E 6F 74 69 66 00 +49 6E 3A 73 68 61 35 31 32 5F 65 72 72 6F 72 00 +49 6E 3A 6B 76 5F 6E 6F 74 69 66 00 49 6E 3A 6B +76 5F 65 72 72 6F 72 00 49 6E 3A 68 6D 61 63 5F +6E 6F 74 69 66 00 00 00 49 6E 3A 68 6D 61 63 5F +65 72 72 6F 72 00 00 00 49 6E 3A 65 63 63 5F 6E +6F 74 69 66 00 00 00 00 49 6E 3A 65 63 63 5F 65 +72 72 6F 72 00 00 00 00 49 6E 3A 64 6F 65 5F 6E +6F 74 69 66 00 00 00 00 49 6E 3A 64 6F 65 5F 65 +72 72 6F 72 00 00 00 00 49 6E 3A 30 00 00 00 00 +49 6E 3A 61 62 72 5F 6E 6F 74 69 66 00 00 00 00 +44 6F 6E 65 20 68 61 6E 64 6C 69 6E 67 20 6D 61 +63 68 69 6E 65 2D 6D 6F 64 65 20 54 49 4D 45 52 +20 69 6E 74 65 72 72 75 70 74 00 00 43 6F 72 20 +45 72 72 6F 72 20 4C 6F 63 61 6C 20 49 53 52 00 +45 72 72 6F 72 3A 20 48 65 78 20 73 74 72 69 6E +67 20 6C 65 6E 67 74 68 20 6D 75 73 74 20 62 65 +20 61 20 6D 75 6C 74 69 70 6C 65 20 6F 66 20 32 +2E 00 00 00 43 6F 6E 66 69 67 75 72 69 6E 67 20 +41 45 53 20 66 6F 72 20 62 69 67 20 65 6E 64 69 +61 6E 20 6D 6F 64 65 00 43 6F 6E 66 69 67 75 72 +69 6E 67 20 41 45 53 20 66 6F 72 20 6C 69 74 74 +6C 65 20 65 6E 64 69 61 6E 20 6D 6F 64 65 00 00 +4C 6F 61 64 20 4B 65 79 20 64 61 74 61 20 74 6F +20 41 45 53 00 00 00 00 57 72 69 74 65 20 41 45 +53 20 49 56 00 00 00 00 57 61 69 74 20 66 6F 72 +20 49 4E 50 55 54 5F 52 45 41 44 59 00 00 00 00 +49 6E 6A 65 63 74 69 6E 67 20 44 4D 41 20 65 72 +72 00 00 00 49 6E 6A 65 63 74 69 6E 67 20 41 45 +53 20 63 6F 6C 6C 69 73 69 6F 6E 20 65 72 72 00 +41 45 53 20 63 6F 6C 6C 69 73 69 6F 6E 20 65 72 +72 6F 72 20 6D 75 73 74 20 72 65 73 75 6C 74 20 +69 6E 20 4E 4D 49 2C 20 61 6E 64 20 66 69 72 6D +77 61 72 65 20 72 65 73 65 74 00 00 41 54 54 45 +4D 50 54 20 54 4F 20 46 4C 49 50 20 53 49 44 45 +4C 4F 41 44 20 42 49 54 00 00 00 00 45 58 50 45 +43 54 45 44 20 4F 55 54 50 55 54 5F 4C 4F 53 54 +20 74 6F 20 62 65 20 6E 6F 6E 2D 7A 65 72 6F 20 +73 69 6E 63 65 20 4F 43 50 20 4C 4F 43 4B 20 70 +72 6F 74 65 63 74 69 6F 6E 73 20 61 72 65 20 62 +6C 6F 63 6B 69 6E 67 20 74 68 65 20 6F 75 74 70 +75 74 20 74 6F 20 46 57 00 00 00 00 45 78 70 65 +63 74 65 64 20 64 61 74 61 3A 20 30 78 30 00 00 +57 41 49 54 49 4E 47 20 46 4F 52 20 4B 56 20 52 +45 41 44 20 54 4F 20 46 49 4E 49 53 48 00 00 00 +45 58 50 45 43 54 49 4E 47 20 4B 56 20 52 44 20 +45 52 52 00 45 58 50 45 43 54 49 4E 47 20 4E 4F +20 4B 56 20 52 44 20 45 52 52 00 00 57 41 49 54 +49 4E 47 20 46 4F 52 20 4B 56 20 57 52 49 54 45 +20 54 4F 20 46 49 4E 49 53 48 00 00 43 48 45 43 +4B 49 4E 47 20 46 4F 52 20 4B 56 20 57 52 49 54 +45 20 45 52 52 00 00 00 45 58 50 45 43 54 49 4E +47 20 4B 56 20 45 52 52 00 00 00 00 45 58 50 45 +43 54 49 4E 47 20 4E 4F 20 4B 56 20 45 52 52 00 +52 65 61 64 20 61 6E 64 20 43 6F 6D 70 61 72 65 +20 47 43 4D 20 54 41 47 00 00 00 00 41 45 53 20 +4F 70 65 72 61 74 69 6F 6E 20 43 6F 6D 70 6C 65 +74 65 00 00 4C 6F 61 64 69 6E 67 20 4B 56 20 76 +69 61 20 41 45 53 00 00 44 4F 45 3A 20 49 6E 69 +74 00 00 00 44 4F 45 3A 20 57 72 69 74 69 6E 67 +20 55 44 53 20 49 56 00 44 4F 45 3A 20 53 74 61 +72 74 69 6E 67 20 55 44 53 20 44 65 6F 62 66 75 +73 63 61 74 69 6F 6E 20 66 6C 6F 77 00 00 00 00 +44 4F 45 3A 20 55 44 53 20 44 65 6F 62 66 75 73 +63 61 74 69 6F 6E 20 66 6C 6F 77 20 63 6F 6D 70 +6C 65 74 65 00 00 00 00 44 4F 45 3A 20 57 72 69 +74 69 6E 67 20 46 69 65 6C 64 20 45 6E 74 72 6F +70 79 20 49 56 00 00 00 44 4F 45 3A 20 53 74 61 +72 74 69 6E 67 20 46 69 65 6C 64 20 45 6E 74 72 +6F 70 79 20 44 65 6F 62 66 75 73 63 61 74 69 6F +6E 20 66 6C 6F 77 00 00 44 4F 45 3A 20 46 69 65 +6C 64 20 45 6E 74 72 6F 70 79 20 44 65 6F 62 66 +75 73 63 61 74 69 6F 6E 20 66 6C 6F 77 20 63 6F +6D 70 6C 65 74 65 00 00 44 4F 45 3A 20 57 72 69 +74 69 6E 67 20 48 45 4B 20 49 56 00 44 4F 45 3A +20 53 74 61 72 74 69 6E 67 20 48 45 4B 20 44 65 +6F 62 66 75 73 63 61 74 69 6F 6E 20 66 6C 6F 77 +00 00 00 00 44 4F 45 3A 20 48 45 4B 20 53 65 65 +64 20 44 65 6F 62 66 75 73 63 61 74 69 6F 6E 20 +66 6C 6F 77 20 63 6F 6D 70 6C 65 74 65 00 00 00 +44 4F 45 3A 20 53 6B 69 70 70 69 6E 67 20 48 45 +4B 20 44 65 6F 62 66 75 73 63 61 74 69 6F 6E 20 +64 75 65 20 74 6F 20 48 57 5F 43 4F 4E 46 49 47 +00 00 00 00 44 4F 45 3A 20 43 6C 65 61 72 20 73 +65 63 72 65 74 73 00 00 45 43 43 20 66 6C 6F 77 +20 69 6E 20 70 72 6F 67 72 65 73 73 2E 2E 2E 00 +45 43 43 20 7A 65 72 6F 69 7A 65 20 66 6C 6F 77 +2E 00 00 00 0A 45 43 43 20 4B 45 59 47 45 4E 00 +57 61 69 74 20 66 6F 72 20 4B 56 20 77 72 69 74 +65 00 00 00 4C 6F 61 64 20 50 52 49 56 4B 45 59 +20 64 61 74 61 20 66 72 6F 6D 20 45 43 43 00 00 +4C 6F 61 64 20 50 55 42 4B 45 59 5F 58 20 64 61 +74 61 20 66 72 6F 6D 20 45 43 43 00 4C 6F 61 64 +20 50 55 42 4B 45 59 5F 59 20 64 61 74 61 20 66 +72 6F 6D 20 45 43 43 00 53 74 6F 72 65 20 50 55 +42 4B 45 59 5F 58 20 64 61 74 61 20 69 6E 20 45 +43 43 00 00 53 74 6F 72 65 20 50 55 42 4B 45 59 +5F 59 20 64 61 74 61 20 69 6E 20 45 43 43 00 00 +0A 45 43 43 20 53 48 41 52 45 44 4B 45 59 00 00 +4C 6F 61 64 20 53 48 41 52 45 44 4B 45 59 20 64 +61 74 61 20 66 72 6F 6D 20 45 43 43 00 00 00 00 +49 6E 6A 65 63 74 20 50 52 49 56 4B 45 59 20 66 +72 6F 6D 20 6B 76 20 74 6F 20 45 43 43 00 00 00 +0A 45 43 43 20 53 49 47 4E 49 4E 47 00 00 00 00 +4C 6F 61 64 20 53 49 47 4E 5F 52 20 64 61 74 61 +20 66 72 6F 6D 20 45 43 43 00 00 00 4C 6F 61 64 +20 53 49 47 4E 5F 53 20 64 61 74 61 20 66 72 6F +6D 20 45 43 43 00 00 00 0A 45 43 43 20 56 45 52 +49 46 59 49 4E 47 00 00 4C 6F 61 64 20 56 45 52 +49 46 59 5F 52 20 64 61 74 61 20 66 72 6F 6D 20 +45 43 43 00 0A 45 43 43 20 50 43 52 20 53 49 47 +4E 49 4E 47 00 00 00 00 4D 4C 44 53 41 20 66 6C +6F 77 20 69 6E 20 70 72 6F 67 72 65 73 73 2E 2E +2E 00 00 00 4D 4C 44 53 41 20 7A 65 72 6F 69 7A +65 20 66 6C 6F 77 2E 00 57 61 69 74 69 6E 67 20 +66 6F 72 20 6D 6C 64 73 61 20 73 74 61 74 75 73 +20 72 65 61 64 79 00 00 57 61 69 74 69 6E 67 20 +66 6F 72 20 6D 6C 64 73 61 20 73 74 61 74 75 73 +20 72 65 61 64 79 20 69 6E 20 6B 65 79 67 65 6E +00 00 00 00 54 72 79 20 74 6F 20 4F 76 65 72 77 +72 69 74 65 20 73 65 65 64 20 64 61 74 61 20 69 +6E 20 4D 4C 44 53 41 00 5B 4D 4C 44 53 41 20 4B +65 79 47 65 6E 5D 20 52 65 63 65 69 76 65 64 20 +65 78 70 65 63 74 65 64 20 65 72 72 20 66 6F 72 +20 4D 4C 44 53 41 20 73 65 65 64 20 72 65 61 64 +20 66 72 6F 6D 20 4B 56 00 00 00 00 5B 4D 4C 44 +53 41 20 4B 65 79 47 65 6E 5D 20 52 65 63 65 69 +76 65 64 20 75 6E 65 78 70 65 63 74 65 64 20 73 +75 63 63 65 73 73 20 66 6F 72 20 4D 4C 44 53 41 +20 73 65 65 64 20 72 65 61 64 20 66 72 6F 6D 20 +4B 56 00 00 57 72 69 74 69 6E 67 20 65 6E 74 72 +6F 70 79 00 0A 4D 4C 44 53 41 20 4B 45 59 47 45 +4E 00 00 00 4C 6F 61 64 20 50 52 49 56 4B 45 59 +20 64 61 74 61 20 66 72 6F 6D 20 4D 4C 44 53 41 +00 00 00 00 4C 6F 61 64 20 50 55 42 4B 45 59 20 +64 61 74 61 20 66 72 6F 6D 20 4D 4C 44 53 41 00 +5B 4D 4C 44 53 41 20 4B 65 79 47 65 6E 20 53 69 +67 6E 69 6E 67 5D 20 52 65 63 65 69 76 65 64 20 +65 78 70 65 63 74 65 64 20 65 72 72 20 66 6F 72 +20 4D 4C 44 53 41 20 73 65 65 64 20 72 65 61 64 +20 66 72 6F 6D 20 4B 56 00 00 00 00 5B 4D 4C 44 +53 41 20 4B 65 79 47 65 6E 20 53 69 67 6E 69 6E +67 5D 20 52 65 63 65 69 76 65 64 20 75 6E 65 78 +70 65 63 74 65 64 20 73 75 63 63 65 73 73 20 66 +6F 72 20 4D 4C 44 53 41 20 73 65 65 64 20 72 65 +61 64 20 66 72 6F 6D 20 4B 56 00 00 0A 4D 4C 44 +53 41 20 4B 45 59 47 45 4E 20 2B 20 53 49 47 4E +49 4E 47 00 4C 6F 61 64 20 53 49 47 4E 20 64 61 +74 61 20 66 72 6F 6D 20 4D 4C 44 53 41 00 00 00 +57 72 69 74 69 6E 67 20 70 72 69 76 6B 65 79 00 +57 72 69 74 69 6E 67 20 6D 73 67 00 0A 4D 4C 44 +53 41 20 53 49 47 4E 49 4E 47 00 00 0A 4D 4C 44 +53 41 20 56 45 52 49 46 59 49 4E 47 00 00 00 00 +4C 6F 61 64 20 56 45 52 49 46 59 5F 52 45 53 20 +64 61 74 61 20 66 72 6F 6D 20 4D 4C 44 53 41 00 +0A 4D 4C 44 53 41 20 4B 45 59 47 45 4E 20 2B 20 +53 49 47 4E 49 4E 47 20 69 6E 20 45 78 74 65 72 +6E 61 6C 4D 75 20 6D 6F 64 65 00 00 57 72 69 74 +69 6E 67 20 45 78 74 65 72 6E 61 6C 4D 75 00 00 +0A 4D 4C 44 53 41 20 53 49 47 4E 49 4E 47 20 69 +6E 20 45 78 74 65 72 6E 61 6C 4D 75 20 6D 6F 64 +65 00 00 00 0A 4D 4C 44 53 41 20 56 45 52 49 46 +59 49 4E 47 20 69 6E 20 45 78 74 65 72 6E 61 6C +4D 75 20 6D 6F 64 65 00 5B 4D 4C 4B 45 4D 5D 20 +57 61 69 74 69 6E 67 20 66 6F 72 20 69 6E 74 65 +72 72 75 70 74 00 00 00 5B 4D 4C 4B 45 4D 5D 20 +53 74 61 72 74 69 6E 67 20 7A 65 72 6F 69 7A 65 +00 00 00 00 5B 4D 4C 4B 45 4D 5D 20 57 61 69 74 +69 6E 67 20 66 6F 72 20 72 65 61 64 79 00 00 00 +5B 4D 4C 4B 45 4D 20 4B 65 79 47 65 6E 5D 20 57 +61 69 74 69 6E 67 20 66 6F 72 20 72 65 61 64 79 +00 00 00 00 5B 4D 4C 4B 45 4D 20 4B 65 79 47 65 +6E 5D 20 54 72 79 20 74 6F 20 4F 76 65 72 77 72 +69 74 65 20 73 65 65 64 20 64 20 64 61 74 61 00 +5B 4D 4C 4B 45 4D 20 4B 65 79 47 65 6E 5D 20 54 +72 79 20 74 6F 20 4F 76 65 72 77 72 69 74 65 20 +73 65 65 64 20 7A 20 64 61 74 61 00 5B 4D 4C 4B +45 4D 20 4B 65 79 47 65 6E 5D 20 52 65 63 65 69 +76 65 64 20 65 78 70 65 63 74 65 64 20 65 72 72 +20 66 6F 72 20 4D 4C 4B 45 4D 20 73 65 65 64 20 +72 65 61 64 20 66 72 6F 6D 20 4B 56 00 00 00 00 +5B 4D 4C 4B 45 4D 20 4B 65 79 47 65 6E 5D 20 52 +65 63 65 69 76 65 64 20 75 6E 65 78 70 65 63 74 +65 64 20 73 75 63 63 65 73 73 20 66 6F 72 20 4D +4C 4B 45 4D 20 73 65 65 64 20 72 65 61 64 20 66 +72 6F 6D 20 4B 56 00 00 5B 4D 4C 4B 45 4D 20 4B +65 79 47 65 6E 5D 20 57 72 69 74 69 6E 67 20 65 +6E 74 72 6F 70 79 00 00 5B 4D 4C 4B 45 4D 20 4B +65 79 47 65 6E 5D 20 53 65 6E 64 69 6E 67 20 63 +6F 6D 6D 61 6E 64 00 00 5B 4D 4C 4B 45 4D 20 4B +65 79 47 65 6E 5D 20 43 68 65 63 6B 69 6E 67 20 +65 6E 63 61 70 73 20 6B 65 79 00 00 5B 4D 4C 4B +45 4D 20 4B 65 79 47 65 6E 5D 20 43 68 65 63 6B +69 6E 67 20 64 65 63 61 70 73 20 6B 65 79 00 00 +5B 4D 4C 4B 45 4D 20 4B 65 79 47 65 6E 5D 20 43 +68 65 63 6B 20 74 68 61 74 20 53 45 45 44 5F 44 +20 61 70 69 20 68 61 73 20 30 73 00 5B 4D 4C 4B +45 4D 20 4B 65 79 47 65 6E 5D 20 43 68 65 63 6B +20 74 68 61 74 20 53 45 45 44 5F 5A 20 61 70 69 +20 68 61 73 20 30 73 00 5B 4D 4C 4B 45 4D 20 4B +65 79 47 65 6E 5D 20 52 65 61 64 20 45 6E 63 61 +70 73 20 4B 65 79 00 00 5B 4D 4C 4B 45 4D 20 4B +65 79 47 65 6E 5D 20 52 65 61 64 20 44 65 63 61 +70 73 20 4B 65 79 00 00 5B 4D 4C 4B 45 4D 20 4B +65 79 47 65 6E 5D 20 43 68 65 63 6B 20 74 68 61 +74 20 44 4B 20 61 70 69 20 68 61 73 20 30 73 00 +5B 4D 4C 4B 45 4D 20 45 6E 63 61 70 73 5D 20 57 +61 69 74 69 6E 67 20 66 6F 72 20 72 65 61 64 79 +00 00 00 00 5B 4D 4C 4B 45 4D 20 45 6E 63 61 70 +73 5D 20 57 72 69 74 69 6E 67 20 65 6E 63 61 70 +73 20 6B 65 79 00 00 00 5B 4D 4C 4B 45 4D 20 45 +6E 63 61 70 73 5D 20 54 72 79 20 74 6F 20 4F 76 +65 72 77 72 69 74 65 20 6D 73 67 00 5B 4D 4C 4B +45 4D 20 45 6E 63 61 70 73 5D 20 54 72 79 20 74 +6F 20 4F 76 65 72 77 72 69 74 65 20 6D 73 67 20 +74 68 72 6F 75 67 68 20 4D 4C 44 53 41 20 70 72 +69 76 6B 65 79 00 00 00 5B 4D 4C 4B 45 4D 20 4B +65 79 47 65 6E 5D 20 52 65 63 65 69 76 65 64 20 +65 78 70 65 63 74 65 64 20 65 72 72 20 66 6F 72 +20 4D 4C 4B 45 4D 20 6D 73 67 20 72 65 61 64 20 +66 72 6F 6D 20 4B 56 00 5B 4D 4C 4B 45 4D 20 4B +65 79 47 65 6E 5D 20 52 65 63 65 69 76 65 64 20 +75 6E 65 78 70 65 63 74 65 64 20 73 75 63 63 65 +73 73 20 66 6F 72 20 4D 4C 4B 45 4D 20 6D 73 67 +20 72 65 61 64 20 66 72 6F 6D 20 4B 56 00 00 00 +5B 4D 4C 4B 45 4D 20 45 6E 63 61 70 73 5D 20 43 +68 65 63 6B 20 74 68 61 74 20 4D 53 47 20 61 70 +69 20 68 61 73 20 30 73 00 00 00 00 5B 4D 4C 4B +45 4D 20 45 6E 63 61 70 73 5D 20 57 72 69 74 69 +6E 67 20 65 6E 74 72 6F 70 79 00 00 5B 4D 4C 4B +45 4D 20 45 6E 63 61 70 73 5D 20 53 65 6E 64 69 +6E 67 20 63 6F 6D 6D 61 6E 64 00 00 5B 4D 4C 4B +45 4D 20 45 6E 63 61 70 73 5D 20 43 68 65 63 6B +20 43 69 70 68 65 72 74 65 78 74 00 5B 4D 4C 4B +45 4D 20 45 6E 63 61 70 73 5D 20 52 65 63 65 69 +76 65 64 20 65 78 70 65 63 74 65 64 20 65 72 72 +20 66 6F 72 20 4D 4C 4B 45 4D 20 73 68 61 72 65 +64 6B 65 79 20 77 72 69 74 65 20 66 72 6F 6D 20 +4B 56 00 00 5B 4D 4C 4B 45 4D 20 45 6E 63 61 70 +73 5D 20 52 65 63 65 69 76 65 64 20 75 6E 65 78 +70 65 63 74 65 64 20 73 75 63 63 65 73 73 20 66 +6F 72 20 4D 4C 4B 45 4D 20 73 68 61 72 65 64 6B +65 79 20 77 72 69 74 65 20 66 72 6F 6D 20 4B 56 +00 00 00 00 5B 4D 4C 4B 45 4D 20 45 6E 63 61 70 +73 5D 20 52 65 63 65 69 76 65 64 20 75 6E 65 78 +70 65 63 74 65 64 20 65 72 72 20 66 6F 72 20 4D +4C 4B 45 4D 20 73 68 61 72 65 64 6B 65 79 20 77 +72 69 74 65 20 66 72 6F 6D 20 4B 56 00 00 00 00 +5B 4D 4C 4B 45 4D 20 45 6E 63 61 70 73 5D 20 52 +65 63 65 69 76 65 64 20 65 78 70 65 63 74 65 64 +20 73 75 63 63 65 73 73 20 66 6F 72 20 4D 4C 4B +45 4D 20 73 68 61 72 65 64 6B 65 79 20 77 72 69 +74 65 20 66 72 6F 6D 20 4B 56 00 00 5B 4D 4C 4B +45 4D 20 45 6E 63 61 70 73 5D 20 43 68 65 63 6B +20 53 68 61 72 65 64 20 4B 65 79 00 5B 4D 4C 4B +45 4D 20 45 6E 63 61 70 73 5D 20 4B 56 20 75 73 +65 64 2C 20 63 68 65 63 6B 20 53 68 61 72 65 64 +20 4B 65 79 20 69 73 20 30 00 00 00 5B 4D 4C 4B +45 4D 20 45 6E 63 61 70 73 5D 20 53 65 6E 64 69 +6E 67 20 43 6F 6D 6D 61 6E 64 00 00 5B 4D 4C 4B +45 4D 20 45 6E 63 61 70 73 5D 20 52 65 61 64 20 +43 69 70 68 65 72 74 65 78 74 00 00 5B 4D 4C 4B +45 4D 20 45 6E 63 61 70 73 5D 20 52 65 63 65 69 +76 65 64 20 75 6E 65 78 70 65 63 74 65 64 20 66 +61 69 6C 20 66 6F 72 20 4D 4C 4B 45 4D 20 73 68 +61 72 65 64 6B 65 79 20 77 72 69 74 65 20 66 72 +6F 6D 20 4B 56 00 00 00 5B 4D 4C 4B 45 4D 20 45 +6E 63 61 70 73 5D 20 52 65 61 64 20 53 68 61 72 +65 64 20 4B 65 79 00 00 5B 4D 4C 4B 45 4D 20 44 +65 63 61 70 73 5D 20 57 61 69 74 69 6E 67 20 66 +6F 72 20 72 65 61 64 79 00 00 00 00 5B 4D 4C 4B +45 4D 20 44 65 63 61 70 73 5D 20 57 72 69 74 69 +6E 67 20 64 65 63 61 70 73 20 6B 65 79 00 00 00 +5B 4D 4C 4B 45 4D 20 44 65 63 61 70 73 5D 20 57 +72 69 74 69 6E 67 20 65 6E 74 72 6F 70 79 00 00 +5B 4D 4C 4B 45 4D 20 44 65 63 61 70 73 5D 20 53 +65 6E 64 69 6E 67 20 63 6F 6D 6D 61 6E 64 00 00 +5B 4D 4C 4B 45 4D 20 44 65 63 61 70 73 5D 20 52 +65 63 65 69 76 65 64 20 65 78 70 65 63 74 65 64 +20 65 72 72 20 66 6F 72 20 4D 4C 4B 45 4D 20 73 +68 61 72 65 64 6B 65 79 20 77 72 69 74 65 20 66 +72 6F 6D 20 4B 56 00 00 5B 4D 4C 4B 45 4D 20 44 +65 63 61 70 73 5D 20 52 65 63 65 69 76 65 64 20 +75 6E 65 78 70 65 63 74 65 64 20 73 75 63 63 65 +73 73 20 66 6F 72 20 4D 4C 4B 45 4D 20 73 68 61 +72 65 64 6B 65 79 20 77 72 69 74 65 20 66 72 6F +6D 20 4B 56 00 00 00 00 5B 4D 4C 4B 45 4D 20 44 +65 63 61 70 73 5D 20 52 65 63 65 69 76 65 64 20 +75 6E 65 78 70 65 63 74 65 64 20 66 61 69 6C 20 +66 6F 72 20 4D 4C 4B 45 4D 20 73 68 61 72 65 64 +6B 65 79 20 77 72 69 74 65 20 66 72 6F 6D 20 4B +56 00 00 00 5B 4D 4C 4B 45 4D 20 44 65 63 61 70 +73 5D 20 52 65 63 65 69 76 65 64 20 65 78 70 65 +63 74 65 64 20 73 75 63 63 65 73 73 20 66 6F 72 +20 4D 4C 4B 45 4D 20 73 68 61 72 65 64 6B 65 79 +20 77 72 69 74 65 20 66 72 6F 6D 20 4B 56 00 00 +5B 4D 4C 4B 45 4D 20 44 65 63 61 70 73 5D 20 4B +56 20 75 73 65 64 2C 20 63 68 65 63 6B 20 53 68 +61 72 65 64 20 4B 65 79 20 69 73 20 30 00 00 00 +5B 4D 4C 4B 45 4D 20 44 65 63 61 70 73 5D 20 43 +68 65 63 6B 20 53 68 61 72 65 64 20 4B 65 79 00 +5B 4D 4C 4B 45 4D 20 44 65 63 61 70 73 5D 20 52 +65 63 65 69 76 65 64 20 65 78 70 65 63 74 65 64 +20 65 72 72 20 66 6F 72 20 4D 4C 4B 45 4D 20 73 +68 61 72 65 64 6B 65 79 20 72 65 61 64 20 66 72 +6F 6D 20 4B 56 00 00 00 5B 4D 4C 4B 45 4D 20 44 +65 63 61 70 73 5D 20 52 65 63 65 69 76 65 64 20 +75 6E 65 78 70 65 63 74 65 64 20 73 75 63 63 65 +73 73 20 66 6F 72 20 4D 4C 4B 45 4D 20 73 68 61 +72 65 64 6B 65 79 20 72 65 61 64 20 66 72 6F 6D +20 4B 56 00 5B 4D 4C 4B 45 4D 20 44 65 63 61 70 +73 5D 20 52 65 61 64 20 53 68 61 72 65 64 20 4B +65 79 00 00 5B 4D 4C 4B 45 4D 20 4B 65 79 47 65 +6E 20 44 65 63 61 70 73 5D 20 57 61 69 74 69 6E +67 20 66 6F 72 20 72 65 61 64 79 00 5B 4D 4C 4B +45 4D 20 4B 65 79 47 65 6E 20 44 65 63 61 70 73 +5D 20 54 72 79 20 74 6F 20 4F 76 65 72 77 72 69 +74 65 20 73 65 65 64 20 64 00 00 00 5B 4D 4C 4B +45 4D 20 4B 65 79 47 65 6E 20 44 65 63 61 70 73 +5D 20 54 72 79 20 74 6F 20 4F 76 65 72 77 72 69 +74 65 20 73 65 65 64 20 7A 00 00 00 5B 4D 4C 4B +45 4D 20 4B 65 79 47 65 6E 20 44 65 63 61 70 73 +5D 20 57 72 69 74 69 6E 67 20 65 6E 74 72 6F 70 +79 00 00 00 5B 4D 4C 4B 45 4D 20 4B 65 79 47 65 +6E 20 44 65 63 61 70 73 5D 20 53 65 6E 64 69 6E +67 20 63 6F 6D 6D 61 6E 64 00 00 00 5B 4D 4C 4B +45 4D 20 4B 65 79 47 65 6E 20 44 65 63 61 70 73 +5D 20 52 65 63 65 69 76 65 64 20 65 78 70 65 63 +74 65 64 20 65 72 72 20 66 6F 72 20 4D 4C 4B 45 +4D 20 73 68 61 72 65 64 6B 65 79 20 77 72 69 74 +65 20 66 72 6F 6D 20 4B 56 00 00 00 5B 4D 4C 4B +45 4D 20 4B 65 79 47 65 6E 20 44 65 63 61 70 73 +5D 20 52 65 63 65 69 76 65 64 20 75 6E 65 78 70 +65 63 74 65 64 20 73 75 63 63 65 73 73 20 66 6F +72 20 4D 4C 4B 45 4D 20 73 68 61 72 65 64 6B 65 +79 20 77 72 69 74 65 20 66 72 6F 6D 20 4B 56 00 +5B 4D 4C 4B 45 4D 20 4B 65 79 47 65 6E 20 44 65 +63 61 70 73 5D 20 52 65 63 65 69 76 65 64 20 75 +6E 65 78 70 65 63 74 65 64 20 66 61 69 6C 20 66 +6F 72 20 4D 4C 4B 45 4D 20 73 68 61 72 65 64 6B +65 79 20 77 72 69 74 65 20 66 72 6F 6D 20 4B 56 +00 00 00 00 5B 4D 4C 4B 45 4D 20 4B 65 79 47 65 +6E 20 44 65 63 61 70 73 5D 20 52 65 63 65 69 76 +65 64 20 65 78 70 65 63 74 65 64 20 73 75 63 63 +65 73 73 20 66 6F 72 20 4D 4C 4B 45 4D 20 73 68 +61 72 65 64 6B 65 79 20 77 72 69 74 65 20 66 72 +6F 6D 20 4B 56 00 00 00 5B 4D 4C 4B 45 4D 20 4B +65 79 47 65 6E 20 44 65 63 61 70 73 5D 20 43 68 +65 63 6B 20 53 68 61 72 65 64 20 4B 65 79 00 00 +5B 4D 4C 4B 45 4D 20 4B 65 79 47 65 6E 20 44 65 +63 61 70 73 5D 20 4B 56 20 75 73 65 64 2C 20 63 +68 65 63 6B 20 53 68 61 72 65 64 20 4B 65 79 20 +69 73 20 30 00 00 00 00 5B 4D 4C 4B 45 4D 20 4B +65 79 47 65 6E 20 44 65 63 61 70 73 5D 20 52 65 +61 64 20 53 68 61 72 65 64 20 4B 65 79 00 00 00 +48 4D 41 43 20 66 6C 6F 77 20 69 6E 20 70 72 6F +67 72 65 73 73 2E 2E 2E 00 00 00 00 48 4D 41 43 +20 7A 65 72 6F 69 7A 65 20 66 6C 6F 77 2E 00 00 +54 72 79 20 74 6F 20 4F 76 65 72 77 72 69 74 65 +20 4B 65 79 20 64 61 74 61 20 69 6E 20 48 4D 41 +43 33 38 34 00 00 00 00 52 65 63 65 69 76 65 64 +20 65 78 70 65 63 74 65 64 20 65 72 72 20 66 6F +72 20 48 4D 41 43 20 6B 65 79 20 72 65 61 64 20 +66 72 6F 6D 20 4B 56 20 77 68 69 6C 65 20 4F 43 +50 20 6C 6F 63 6B 20 69 6E 20 70 72 6F 67 72 65 +73 73 00 00 52 65 63 65 69 76 65 64 20 75 6E 65 +78 70 65 63 74 65 64 20 73 75 63 63 65 73 73 20 +66 6F 72 20 48 4D 41 43 20 6B 65 79 20 72 65 61 +64 20 66 72 6F 6D 20 4B 56 20 77 68 69 6C 65 20 +4F 43 50 20 6C 6F 63 6B 20 69 6E 20 70 72 6F 67 +72 65 73 73 00 00 00 00 4C 6F 61 64 20 4B 65 79 +20 64 61 74 61 20 74 6F 20 48 4D 41 43 00 00 00 +54 72 79 20 74 6F 20 4F 76 65 72 77 72 69 74 65 +20 42 6C 6F 63 6B 20 64 61 74 61 20 69 6E 20 48 +4D 41 43 00 52 65 63 65 69 76 65 64 20 65 78 70 +65 63 74 65 64 20 65 72 72 20 66 6F 72 20 48 4D +41 43 20 62 6C 6F 63 6B 20 72 65 61 64 20 66 72 +6F 6D 20 4B 56 20 77 68 69 6C 65 20 4F 43 50 20 +6C 6F 63 6B 20 69 6E 20 70 72 6F 67 72 65 73 73 +00 00 00 00 52 65 63 65 69 76 65 64 20 75 6E 65 +78 70 65 63 74 65 64 20 73 75 63 63 65 73 73 20 +66 6F 72 20 48 4D 41 43 20 62 6C 6F 63 6B 20 72 +65 61 64 20 66 72 6F 6D 20 4B 56 20 77 68 69 6C +65 20 4F 43 50 20 6C 6F 63 6B 20 69 6E 20 70 72 +6F 67 72 65 73 73 00 00 4C 6F 61 64 20 54 41 47 +20 64 61 74 61 20 66 72 6F 6D 20 48 4D 41 43 20 +74 6F 20 4B 56 00 00 00 4C 6F 61 64 20 54 41 47 +20 64 61 74 61 20 66 72 6F 6D 20 48 4D 41 43 00 +54 72 79 20 74 6F 20 4F 76 65 72 77 72 69 74 65 +20 4B 65 79 20 64 61 74 61 20 69 6E 20 48 4D 41 +43 35 31 32 00 00 00 00 4B 56 3A 20 63 68 65 63 +6B 69 6E 67 20 66 6F 72 20 65 72 72 6F 72 73 00 +4B 56 20 45 52 52 4F 52 00 00 00 00 4B 56 3A 20 +63 68 65 63 6B 69 6E 67 20 65 72 72 6F 72 73 20 +70 72 65 73 65 6E 74 00 4E 4F 20 4B 56 20 45 52 +52 4F 52 00 4B 56 3A 20 70 72 6F 67 20 6B 76 20 +72 65 61 64 20 63 74 72 6C 00 00 00 4B 56 3A 20 +70 72 6F 67 20 6B 76 20 77 72 69 74 65 20 63 74 +72 6C 00 00 50 56 3A 20 70 72 6F 67 20 6B 76 20 +72 65 61 64 20 63 74 72 6C 20 69 6E 20 53 48 41 +20 74 6F 20 64 6F 20 68 61 73 68 20 65 78 74 65 +6E 64 00 00 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D +2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D +2D 2D 2D 00 53 54 49 43 4B 59 44 41 54 41 56 41 +55 4C 54 43 54 52 4C 00 53 54 49 43 4B 59 5F 44 +41 54 41 5F 56 41 55 4C 54 5F 45 4E 54 52 59 5F +30 00 00 00 53 54 49 43 4B 59 5F 44 41 54 41 5F +56 41 55 4C 54 5F 45 4E 54 52 59 5F 31 00 00 00 +53 54 49 43 4B 59 5F 44 41 54 41 5F 56 41 55 4C +54 5F 45 4E 54 52 59 5F 32 00 00 00 53 54 49 43 +4B 59 5F 44 41 54 41 5F 56 41 55 4C 54 5F 45 4E +54 52 59 5F 33 00 00 00 53 54 49 43 4B 59 5F 44 +41 54 41 5F 56 41 55 4C 54 5F 45 4E 54 52 59 5F +34 00 00 00 53 54 49 43 4B 59 5F 44 41 54 41 5F +56 41 55 4C 54 5F 45 4E 54 52 59 5F 35 00 00 00 +53 54 49 43 4B 59 5F 44 41 54 41 5F 56 41 55 4C +54 5F 45 4E 54 52 59 5F 36 00 00 00 53 54 49 43 +4B 59 5F 44 41 54 41 5F 56 41 55 4C 54 5F 45 4E +54 52 59 5F 37 00 00 00 53 54 49 43 4B 59 5F 44 +41 54 41 5F 56 41 55 4C 54 5F 45 4E 54 52 59 5F +38 00 00 00 53 54 49 43 4B 59 5F 44 41 54 41 5F +56 41 55 4C 54 5F 45 4E 54 52 59 5F 39 00 00 00 +44 41 54 41 56 41 55 4C 54 43 54 52 4C 00 00 00 +44 41 54 41 5F 56 41 55 4C 54 5F 45 4E 54 52 59 +5F 30 00 00 44 41 54 41 5F 56 41 55 4C 54 5F 45 +4E 54 52 59 5F 31 00 00 44 41 54 41 5F 56 41 55 +4C 54 5F 45 4E 54 52 59 5F 32 00 00 44 41 54 41 +5F 56 41 55 4C 54 5F 45 4E 54 52 59 5F 33 00 00 +44 41 54 41 5F 56 41 55 4C 54 5F 45 4E 54 52 59 +5F 34 00 00 44 41 54 41 5F 56 41 55 4C 54 5F 45 +4E 54 52 59 5F 35 00 00 44 41 54 41 5F 56 41 55 +4C 54 5F 45 4E 54 52 59 5F 36 00 00 44 41 54 41 +5F 56 41 55 4C 54 5F 45 4E 54 52 59 5F 37 00 00 +44 41 54 41 5F 56 41 55 4C 54 5F 45 4E 54 52 59 +5F 38 00 00 44 41 54 41 5F 56 41 55 4C 54 5F 45 +4E 54 52 59 5F 39 00 00 4C 4F 43 4B 41 42 4C 45 +5F 53 43 52 41 54 43 48 52 45 47 5F 43 54 52 4C +00 00 00 00 4C 4F 43 4B 41 42 4C 45 5F 53 43 52 +41 54 43 48 52 45 47 00 4E 4F 4E 53 54 49 43 4B +59 5F 47 45 4E 45 52 49 43 5F 53 43 52 41 54 43 +48 52 45 47 00 00 00 00 53 54 49 43 4B 59 5F 4C +4F 43 4B 41 42 4C 45 5F 53 43 52 41 54 43 48 52 +45 47 5F 43 54 52 4C 00 53 54 49 43 4B 59 5F 4C +4F 43 4B 41 42 4C 45 5F 53 43 52 41 54 43 48 52 +45 47 00 00 53 48 41 32 35 36 20 66 6C 6F 77 20 +69 6E 20 70 72 6F 67 72 65 73 73 2E 2E 2E 00 00 +53 48 41 32 35 36 20 7A 65 72 6F 69 7A 65 20 66 +6C 6F 77 2E 00 00 00 00 45 6E 61 62 6C 65 20 53 +48 41 32 35 36 00 00 00 4C 6F 61 64 20 44 49 47 +45 53 54 20 64 61 74 61 20 66 72 6F 6D 20 53 48 +41 32 35 36 00 00 00 00 45 72 72 6F 72 31 20 69 +73 20 65 78 70 65 63 74 65 64 20 77 68 65 6E 20 +69 6E 69 74 20 61 6E 64 20 6E 65 78 74 20 61 72 +65 20 61 73 73 65 72 74 65 64 20 61 74 20 74 68 +65 20 73 61 6D 65 20 74 69 6D 65 2E 20 43 68 65 +63 6B 20 61 72 67 73 20 67 69 76 65 6E 20 74 6F +20 73 68 61 32 35 36 5F 65 72 72 6F 72 5F 66 6C +6F 77 28 29 00 00 00 00 45 72 72 6F 72 30 20 69 +73 20 65 78 70 65 63 74 65 64 20 66 6F 72 20 69 +6E 76 61 6C 69 64 20 77 6E 74 7A 5F 6D 6F 64 65 +20 6F 72 20 77 2E 20 43 68 65 63 6B 20 61 72 67 +73 20 67 69 76 65 6E 20 74 6F 20 73 68 61 32 35 +36 5F 65 72 72 6F 72 5F 66 6C 6F 77 28 29 00 00 +53 48 41 35 31 32 20 66 6C 6F 77 20 69 6E 20 70 +72 6F 67 72 65 73 73 2E 2E 2E 00 00 53 48 41 35 +31 32 3A 20 53 65 74 20 53 54 41 52 54 20 66 6F +72 20 67 65 6E 20 68 61 73 68 20 66 75 6E 63 00 +53 48 41 35 31 32 20 7A 65 72 6F 69 7A 65 20 66 +6C 6F 77 2E 00 00 00 00 45 6E 61 62 6C 65 20 53 +48 41 35 31 32 00 00 00 4C 6F 61 64 20 44 49 47 +45 53 54 20 64 61 74 61 20 66 72 6F 6D 20 53 48 +41 35 31 32 00 00 00 00 64 69 66 5F 6B 6D 61 63 +5F 63 75 73 74 6F 6D 69 7A 61 74 69 6F 6E 5F 73 +74 72 69 6E 67 5F 69 6E 69 74 3A 20 45 52 52 4F +52 20 64 61 74 61 20 61 6E 64 20 6F 75 74 20 61 +72 67 75 6D 65 6E 74 73 20 6D 75 73 74 20 6E 6F +74 20 62 65 20 6E 75 6C 6C 2E 00 00 64 69 66 5F +6B 6D 61 63 5F 63 75 73 74 6F 6D 69 7A 61 74 69 +6F 6E 5F 73 74 72 69 6E 67 5F 69 6E 69 74 3A 20 +45 52 52 4F 52 20 6C 65 6E 67 74 68 20 67 72 65 +61 74 65 72 20 74 68 61 6E 20 6D 61 78 69 6D 75 +6D 2E 00 00 64 69 66 5F 6B 6D 61 63 5F 66 75 6E +63 74 69 6F 6E 5F 6E 61 6D 65 5F 69 6E 69 74 3A +20 45 52 52 4F 52 20 64 61 74 61 20 61 6E 64 20 +6F 75 74 20 6D 75 73 74 20 6E 6F 74 20 62 65 20 +4E 55 4C 4C 2E 00 00 00 64 69 66 5F 6B 6D 61 63 +5F 66 75 6E 63 74 69 6F 6E 5F 6E 61 6D 65 5F 69 +6E 69 74 3A 20 45 52 52 4F 52 20 6C 65 6E 67 74 +68 20 6C 61 72 67 65 72 20 74 68 61 6E 20 6D 61 +78 69 6D 75 6D 2E 00 00 64 69 66 5F 6B 6D 61 63 +5F 6D 6F 64 65 5F 73 68 61 33 5F 73 74 61 72 74 +3A 20 45 52 52 4F 52 20 6B 6D 61 63 20 6F 72 20 +6F 70 65 72 61 74 69 6F 6E 5F 73 74 61 74 65 20 +4E 55 4C 4C 2E 00 00 00 64 69 66 5F 6B 6D 61 63 +5F 73 68 61 33 5F 73 74 61 72 74 3A 20 45 52 52 +4F 52 20 55 6E 73 75 70 70 6F 72 74 65 64 20 6D +6F 64 65 2E 00 00 00 00 64 69 66 5F 6B 6D 61 63 +5F 73 68 61 33 5F 73 74 61 72 74 3A 20 45 52 52 +4F 52 20 68 61 72 64 77 61 72 65 20 6D 75 73 74 +20 62 65 20 69 64 6C 65 2E 00 00 00 64 69 66 5F +6B 6D 61 63 5F 6D 6F 64 65 5F 73 68 61 6B 65 5F +73 74 61 72 74 3A 20 45 52 52 4F 52 20 6B 6D 61 +63 20 61 6E 64 20 6F 70 65 72 61 74 69 6F 6E 20 +73 74 61 74 65 20 63 61 6E 6E 6F 74 20 62 65 20 +4E 55 4C 4C 2E 00 00 00 64 69 66 5F 6B 6D 61 63 +5F 6D 6F 64 65 5F 73 68 61 6B 65 5F 73 74 61 72 +74 3A 20 45 52 52 4F 52 20 6D 6F 64 65 20 6E 6F +74 20 61 6C 6C 6F 77 65 64 2E 00 00 64 69 66 5F +6B 6D 61 63 5F 73 68 61 6B 65 5F 73 74 61 72 74 +3A 20 45 52 52 4F 52 20 68 61 72 64 77 61 72 65 +20 6D 75 73 74 20 62 65 20 69 64 6C 65 2E 00 00 +64 69 66 5F 6B 6D 61 63 5F 6D 6F 64 65 5F 63 73 +68 61 6B 65 5F 73 74 61 72 74 3A 20 45 52 52 4F +52 20 6B 6D 61 63 20 6F 72 20 6F 70 65 72 61 74 +69 6F 6E 20 73 74 61 74 65 20 69 73 20 4E 55 4C +4C 2E 00 00 64 69 66 5F 6B 6D 61 63 5F 6D 6F 64 +65 5F 63 73 68 61 6B 65 5F 73 74 61 72 74 3A 20 +45 52 52 4F 52 20 75 6E 73 75 70 70 6F 72 74 65 +64 20 6D 6F 64 65 20 66 6F 72 20 65 6D 70 74 79 +20 4E 20 61 6E 64 20 53 2E 00 00 00 64 69 66 5F +6B 6D 61 63 5F 6D 6F 64 65 5F 63 73 68 61 6B 65 +5F 73 74 61 72 74 3A 20 45 52 52 4F 52 20 75 6E +73 75 70 70 6F 72 74 65 64 20 6B 73 74 72 65 6E +67 68 74 2E 00 00 00 00 64 69 66 5F 6B 6D 61 63 +5F 6D 6F 64 65 5F 63 73 68 61 6B 65 5F 73 74 61 +72 74 3A 20 45 52 52 4F 52 20 68 61 72 64 77 61 +72 65 20 6D 75 73 74 20 62 65 20 69 64 6C 65 2E +00 00 00 00 64 69 66 5F 6B 6D 61 63 5F 61 62 73 +6F 72 62 3A 20 45 52 52 4F 52 20 6F 6E 65 20 6F +66 20 66 75 6E 63 74 69 6F 6E 20 61 72 67 75 6D +65 6E 74 73 20 69 73 20 6E 75 6C 6C 00 00 00 00 +64 69 66 5F 6B 6D 61 63 5F 61 62 73 6F 72 62 3A +20 45 52 52 4F 52 20 6F 70 65 72 61 74 69 6F 6E +20 6E 6F 74 20 73 74 61 72 74 65 64 20 79 65 74 +00 00 00 00 64 69 66 5F 6B 6D 61 63 5F 61 62 73 +6F 72 62 3A 20 45 52 52 4F 52 20 68 61 72 64 77 +61 72 65 20 6D 75 73 74 20 62 65 20 61 62 73 6F +72 62 69 6E 67 2E 00 00 64 69 66 5F 6B 6D 61 63 +5F 73 71 75 65 65 7A 65 3A 20 45 52 52 4F 52 20 +61 72 67 75 6D 65 6E 74 73 20 6D 61 79 20 6E 6F +74 20 62 65 20 4E 55 4C 4C 2E 00 00 64 69 66 5F +6B 6D 61 63 5F 73 71 75 65 65 7A 65 3A 20 45 52 +52 4F 52 20 74 6F 74 61 6C 20 62 79 74 65 73 20 +72 65 71 75 65 73 74 65 64 20 6D 75 73 74 20 6E +6F 74 20 65 78 63 65 65 64 20 66 69 78 65 64 20 +6F 75 74 70 75 74 20 6C 65 6E 67 74 68 2E 00 00 +64 69 66 5F 6B 6D 61 63 5F 73 71 75 65 65 7A 65 +3A 20 45 52 52 4F 52 20 6F 70 65 72 61 74 69 6F +6E 20 73 74 61 74 65 20 64 20 6C 65 73 73 20 74 +68 61 6E 20 72 2E 00 00 64 69 66 5F 6B 6D 61 63 +5F 65 6E 64 3A 20 45 52 52 4F 52 20 61 72 67 75 +6D 65 6E 74 73 20 6D 61 79 20 6E 6F 74 20 62 65 +20 4E 55 4C 4C 2E 00 00 64 69 66 5F 6B 6D 61 63 +5F 65 6E 64 3A 20 45 52 52 4F 52 20 68 61 72 64 +77 61 72 65 20 6D 75 73 74 20 62 65 20 64 6F 6E +65 20 73 71 75 65 65 7A 69 6E 67 2E 00 00 00 00 +53 4F 43 5F 49 46 43 3A 20 43 68 65 63 6B 20 6D +62 6F 78 5F 73 74 61 74 75 73 2E 6D 62 6F 78 5F +66 73 6D 5F 70 73 00 00 53 4F 43 5F 49 46 43 3A +20 43 68 65 63 6B 20 6D 62 6F 78 5F 73 74 61 74 +75 73 2E 6D 62 6F 78 5F 66 73 6D 5F 70 73 20 66 +6F 75 6E 64 20 4D 42 4F 58 5F 45 58 45 43 55 54 +45 5F 55 43 00 00 00 00 53 4F 43 5F 49 46 43 3A +20 43 68 65 63 6B 20 6D 62 6F 78 5F 73 74 61 74 +75 73 2E 6D 62 6F 78 5F 66 73 6D 5F 70 73 20 66 +6F 75 6E 64 20 4D 42 4F 58 5F 49 44 4C 45 00 00 +53 4F 43 5F 49 46 43 3A 20 43 68 65 63 6B 20 6D +62 6F 78 5F 73 74 61 74 75 73 2E 6D 62 6F 78 5F +66 73 6D 5F 70 73 20 66 6F 75 6E 64 20 4D 42 4F +58 5F 45 52 52 4F 52 2C 20 6D 61 69 6C 62 6F 78 +20 66 6F 72 63 65 2D 75 6E 6C 6F 63 6B 20 6E 65 +65 64 65 64 00 00 00 00 53 4F 43 5F 49 46 43 3A +20 42 65 67 69 6E 6E 69 6E 67 20 6D 62 6F 78 20 +66 77 20 66 6C 6F 77 00 53 4F 43 5F 49 46 43 3A +20 43 70 20 74 6F 20 49 43 43 4D 00 53 4F 43 5F +49 46 43 3A 20 43 70 20 74 6F 20 44 43 43 4D 00 +43 6F 70 79 69 6E 67 20 63 6F 64 65 20 66 72 6F +6D 20 6D 61 69 6C 62 6F 78 20 74 6F 20 49 43 43 +4D 00 00 00 46 61 69 6C 65 64 20 74 6F 20 61 63 +71 75 69 72 65 20 6C 6F 63 6B 20 2D 20 6D 62 6F +78 20 73 61 6E 69 74 69 7A 65 00 00 77 6F 6E 27 +74 20 6F 76 65 72 72 69 64 65 00 00 77 69 6C 6C +20 75 73 65 20 64 65 66 61 75 6C 74 20 35 00 00 +77 69 6C 6C 20 6F 76 65 72 72 69 64 65 00 00 00 +46 41 54 41 4C 3A 20 41 58 49 20 44 4D 41 20 72 +65 70 6F 72 74 73 20 65 72 72 6F 72 20 73 74 61 +74 75 73 20 66 6F 72 20 78 66 65 72 00 00 00 00 +41 58 49 20 44 4D 41 20 72 65 70 6F 72 74 73 20 +73 74 61 74 75 73 20 66 6F 72 20 78 66 65 72 20 +74 68 61 74 20 77 6F 75 6C 64 20 72 65 71 75 69 +72 65 20 44 4D 41 20 46 6C 75 73 68 00 00 00 00 +41 58 49 20 44 4D 41 20 64 69 64 20 6E 6F 74 20 +72 65 70 6F 72 74 20 65 72 72 20 73 74 61 74 75 +73 20 66 6F 72 20 78 66 65 72 20 74 68 61 74 20 +77 6F 75 6C 64 20 72 65 71 75 69 72 65 20 44 4D +41 20 46 6C 75 73 68 00 41 63 71 75 69 72 65 20 +6D 61 69 6C 62 6F 78 20 6C 6F 63 6B 20 66 61 69 +6C 65 64 00 46 41 54 41 4C 3A 20 41 58 49 20 44 +4D 41 20 72 65 70 6F 72 74 73 20 65 72 72 6F 72 +20 73 74 61 74 75 73 20 66 6F 72 20 4D 42 4F 58 +2D 74 6F 2D 41 58 49 20 78 66 65 72 00 00 00 00 +46 57 3A 20 53 65 6E 64 69 6E 67 20 4B 56 20 74 +6F 20 41 58 49 20 77 69 74 68 20 45 52 52 00 00 +41 58 49 20 44 4D 41 20 72 65 70 6F 72 74 73 20 +65 72 72 20 73 74 61 74 75 73 20 66 6F 72 20 65 +72 72 20 69 6E 6A 65 63 74 69 6F 6E 20 78 66 65 +72 00 00 00 46 41 54 41 4C 3A 20 41 58 49 20 44 +4D 41 20 72 65 70 6F 72 74 73 20 73 75 63 63 65 +73 73 20 73 74 61 74 75 73 20 66 6F 72 20 65 72 +72 20 69 6E 6A 65 63 74 69 6F 6E 20 78 66 65 72 +21 00 00 00 46 57 3A 20 53 65 6E 64 69 6E 67 20 +4B 56 20 74 6F 20 41 58 49 00 00 00 46 57 3A 20 +41 72 6D 20 65 72 72 20 63 6F 6D 6D 61 6E 64 00 +45 6E 20 69 6E 74 20 74 6D 72 30 2C 20 68 6C 74 +20 63 6F 72 65 00 00 00 44 69 73 61 62 6C 69 6E +67 20 62 6F 74 68 20 74 69 6D 65 72 73 20 69 6E +20 69 6E 64 65 70 65 6E 64 65 6E 74 20 6D 6F 64 +65 00 00 00 45 6E 61 62 6C 69 6E 67 20 6F 6E 6C +79 20 74 69 6D 65 72 32 20 69 6E 20 69 6E 64 65 +70 65 6E 64 65 6E 74 20 6D 6F 64 65 00 00 00 00 +45 6E 61 62 6C 69 6E 67 20 62 6F 74 68 20 74 69 +6D 65 72 73 20 69 6E 20 69 6E 64 65 70 65 6E 64 +65 6E 74 20 6D 6F 64 65 00 00 00 00 00 32 02 50 +00 32 02 50 +@000168D0 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 diff --git a/designs/Caliptra/tests/post.bash b/designs/Caliptra/tests/post.bash new file mode 100755 index 0000000..07111e1 --- /dev/null +++ b/designs/Caliptra/tests/post.bash @@ -0,0 +1,5 @@ +#!/bin/bash +set -x +set -e +# stdout must contain 'TESTCASE PASSED' +grep -q "TESTCASE PASSED" _execute/stdout.log diff --git a/designs/Caliptra/tests/sha3/dccm.hex b/designs/Caliptra/tests/sha3/dccm.hex new file mode 100644 index 0000000..3bd4599 --- /dev/null +++ b/designs/Caliptra/tests/sha3/dccm.hex @@ -0,0 +1,7282 @@ +@00023974 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 7C 14 00 00 +8C 13 00 00 E6 23 00 00 9C 12 00 00 A8 22 00 00 +AC 11 00 00 6A 21 00 00 BC 10 00 00 CC 0F 00 00 +DC 0E 00 00 2C 20 00 00 F0 14 00 00 EE 1E 00 00 +04 16 00 00 04 16 00 00 04 16 00 00 04 16 00 00 +8C 1D 00 00 EC 1B 00 00 CA 19 00 00 A8 17 00 00 +EC 0D 00 00 6A 16 00 00 FC 0C 00 00 0C 0C 00 00 +1C 0B 00 00 2C 0A 00 00 04 16 00 00 04 16 00 00 +04 16 00 00 04 16 00 00 04 16 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 EF BE AD DE +@00030004 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +@00032004 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +@00034004 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +@00036004 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +@00038004 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +@0003A004 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +@0003C004 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +@0003E004 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 diff --git a/designs/Caliptra/tests/sha3/iccm.hex b/designs/Caliptra/tests/sha3/iccm.hex new file mode 100644 index 0000000..e69de29 diff --git a/designs/Caliptra/tests/sha3/mailbox.hex b/designs/Caliptra/tests/sha3/mailbox.hex new file mode 100644 index 0000000..e69de29 diff --git a/designs/Caliptra/tests/sha3/program.hex b/designs/Caliptra/tests/sha3/program.hex new file mode 100644 index 0000000..c527d90 --- /dev/null +++ b/designs/Caliptra/tests/sha3/program.hex @@ -0,0 +1,6147 @@ +@00000000 +73 10 20 B0 73 10 20 B8 B7 A2 AA AA 93 82 92 0A +73 90 02 7C 91 42 0F 10 00 00 73 90 92 7F 0F 10 +00 00 97 02 00 00 93 82 E2 14 73 90 52 30 97 12 +01 00 93 82 22 3B 17 53 01 00 13 03 63 C5 97 03 +02 50 93 83 23 FC 63 FA 62 00 03 AE 02 00 23 A0 +C3 01 91 02 91 03 E3 EA 62 FE 97 52 01 00 93 82 +22 C3 17 53 01 00 13 03 23 CF 97 43 02 50 93 83 +23 84 63 FA 62 00 03 AE 02 00 23 A0 C3 01 91 02 +91 03 E3 EA 62 FE 17 41 03 50 13 01 A1 F8 EF 00 +F0 00 B7 02 03 30 93 82 C2 0C 13 0F F0 0F 23 A0 +E2 01 E3 08 00 FE 01 00 01 00 01 00 01 00 01 00 +01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00 +01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00 +01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00 +01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00 +01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00 +01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00 +01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00 +01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00 +01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00 +01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00 +01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00 +01 00 01 00 01 00 01 00 01 00 01 00 01 00 00 00 +F3 22 20 34 73 23 10 34 F3 23 30 34 37 0E 03 30 +13 0E CE 0C 97 0E 02 50 93 8E CE E7 83 82 0E 00 +23 20 5E 00 85 0E E3 9B 02 FE 05 4F 23 20 EE 01 +C1 BF 00 00 55 71 A2 C5 37 04 02 50 A6 C3 4E DF +52 DD 56 DB 5A D9 5E D7 86 C7 CA C1 62 D5 66 D3 +AA 84 13 04 C4 07 81 49 B7 0A 02 50 09 4A 41 4B +85 4B 83 A7 4A 5A 63 67 FA 16 A2 87 98 08 13 09 +04 05 88 43 CC 43 90 47 D4 47 08 C3 4C C3 10 C7 +54 C7 C1 07 41 07 E3 96 27 FF 03 2C 84 00 10 40 +81 46 8A 85 26 85 83 2C 44 00 60 44 EF E0 00 2C +63 12 0C 12 63 63 8B 16 81 47 01 47 A2 86 10 08 +8A 85 26 85 EF E0 00 6D 8A 85 26 85 EF E0 F0 0E +81 45 26 85 EF E0 00 17 61 CC C2 46 76 47 63 19 +D7 10 63 07 74 0D D2 46 06 57 63 92 E6 12 63 01 +44 0D E2 46 16 57 63 9E E6 10 8D 47 63 0A F4 0A +F2 46 26 57 63 92 E6 12 91 47 63 03 F4 0A 82 56 +36 57 63 9D E6 10 95 47 63 0C F4 08 92 56 46 57 +63 98 E6 10 99 47 63 05 F4 08 A2 56 56 57 63 93 +E6 10 9D 47 63 0E F4 06 B2 56 66 57 63 9E E6 0E +A1 47 63 07 F4 06 C2 56 76 57 63 9B E6 0E A5 47 +63 00 F4 06 D2 56 0A 47 63 92 E6 0E A9 47 63 09 +F4 04 E2 56 1A 47 63 99 E6 0E AD 47 63 02 F4 04 +F2 56 2A 47 63 9E E6 0C B1 47 63 0B F4 02 86 46 +3A 47 63 99 E6 0C B5 47 63 04 F4 02 96 46 4A 47 +63 96 E6 0C B9 47 63 0D F4 00 A6 46 5A 47 63 91 +E6 0C C1 47 63 16 F4 00 B6 46 6A 47 63 95 E6 06 +85 09 91 47 4A 84 E3 9E F9 EA BE 40 2E 44 9E 44 +0E 49 FA 59 6A 5A DA 5A 4A 5B BA 5B 2A 5C 9A 5C +69 61 82 80 01 47 E2 86 66 86 8A 85 26 85 EF E0 +E0 48 C9 BD CE 85 13 05 C0 70 EF 20 90 6E 71 B5 +01 46 83 A7 4A 5A 89 E7 05 45 EF 20 90 69 01 A0 +01 45 CE 85 13 05 80 77 EF 20 B0 6C F5 B7 05 46 +CD B7 09 46 F9 BF 3D 46 E9 BF 83 A7 4A 5A 9D E3 +05 45 EF 20 10 67 01 A0 0D 46 E1 B7 11 46 D1 B7 +15 46 C1 B7 19 46 75 BF 1D 46 65 BF 25 46 55 BF +21 46 45 BF A2 85 13 05 C0 73 EF 20 90 68 C9 BF +2D 46 45 B7 31 46 71 BF 29 46 61 BF 35 46 51 BF +39 46 41 BF 59 71 A2 D4 A6 D2 CA D0 CE CE D6 CA +DA C8 DE C6 E2 C4 80 18 86 D6 D2 CC B7 17 02 50 +93 87 07 F7 8C 43 D0 43 94 47 D8 47 83 C7 07 01 +81 4B B7 A9 F9 29 2A 8C 23 22 B4 FA 23 24 C4 FA +23 26 D4 FA 23 28 E4 FA 23 0A F4 FA 93 04 84 FB +01 49 B7 0A 02 50 09 4B 93 0B 40 7A 93 89 B9 6D +83 A7 4A 5A 0A 8A 63 62 FB 12 45 46 93 05 44 FA +26 85 23 2C 04 FA 23 2E 04 FA 23 20 04 FC 23 22 +04 FC 23 24 04 FC 23 06 04 FC EF 00 21 67 81 46 +09 46 93 05 44 F9 62 85 EF E0 40 07 26 86 01 47 +C5 46 93 05 44 F9 62 85 EF E0 40 36 81 47 13 06 +04 F9 01 47 91 46 93 05 44 F9 62 85 EF E0 80 47 +93 05 44 F9 62 85 EF E0 40 69 81 45 62 85 EF D0 +70 71 03 26 04 F9 91 47 85 04 63 13 36 0F 05 09 +52 81 E3 1F F9 F6 81 46 09 46 93 05 44 F9 62 85 +EF E0 C0 01 01 47 85 46 13 06 44 FA 93 05 44 F9 +62 85 EF E0 A0 30 01 47 89 46 13 06 54 FA 93 05 +44 F9 62 85 EF E0 80 2F 01 47 95 46 13 06 74 FA +93 05 44 F9 62 85 EF E0 60 2E 01 47 91 46 13 06 +C4 FA 93 05 44 F9 62 85 EF E0 40 2D 01 47 95 46 +13 06 04 FB 93 05 44 F9 62 85 EF E0 20 2C 81 47 +01 47 91 46 13 06 84 FB 93 05 44 F9 62 85 EF E0 +60 3D 93 05 44 F9 62 85 EF E0 20 5F 81 45 62 85 +EF D0 50 67 83 25 84 FB 63 8E 35 01 83 A7 4A 5A +95 E7 05 45 EF 20 F0 4A 01 A0 CA 85 5E 85 EF 20 +50 4E E1 BD B6 50 26 54 96 54 06 59 F6 49 66 4A +D6 4A 46 4B B6 4B 26 4C 65 61 82 80 05 65 4E 86 +13 05 C5 80 EF 20 F0 4B 05 45 EF 20 90 47 E9 B7 +83 A7 4A 5A 89 E7 05 45 EF 20 B0 46 01 A0 01 45 +CE 86 CA 85 13 05 00 7E EF 20 B0 49 ED B7 13 01 +01 C8 23 2A 91 36 B7 04 02 50 83 A7 44 5A 23 2C +81 36 23 28 21 37 23 26 31 37 23 24 41 37 23 20 +61 37 23 2E 11 36 37 0B 02 50 23 22 51 37 23 2E +71 35 23 2C 81 35 09 4A 2A 84 13 0B CB 1B 01 49 +93 09 60 06 63 60 FA 0C DA 87 38 13 93 08 4B 1A +03 A8 07 00 C8 43 8C 47 D0 47 94 4B 23 20 07 01 +48 C3 0C C7 50 C7 14 CB D1 07 51 07 E3 92 17 FF +9C 43 83 2B 8B 00 03 26 0B 00 03 2C 4B 00 83 2A +4B 1A 81 46 8A 85 22 85 1C C3 EF D0 F0 76 63 9A +0B 04 63 EE 59 0B 81 47 01 47 D6 86 10 08 8A 85 +22 85 EF E0 20 2B 8A 85 22 85 EF E0 00 4D 81 45 +22 85 EF D0 30 55 63 8E 0A 02 0C 08 5C 1B 01 46 +21 A0 05 06 63 07 56 03 94 41 98 43 91 05 91 07 +E3 89 E6 FE 83 A7 44 5A A5 E7 05 45 EF 20 70 37 +01 A0 01 47 DE 86 62 86 8A 85 22 85 EF E0 00 14 +4D B7 13 0B 8B 1A 63 1E 09 00 83 A7 44 5A 05 49 +E3 74 FA F4 05 65 CA 85 13 05 85 82 EF 20 70 38 +25 BF 83 20 C1 37 03 24 81 37 83 24 41 37 03 29 +01 37 83 29 C1 36 03 2A 81 36 83 2A 41 36 03 2B +01 36 83 2B C1 35 03 2C 81 35 13 01 01 38 82 80 +05 65 CA 85 13 05 85 85 EF 20 B0 34 79 B7 83 A7 +44 5A 89 E7 05 45 EF 20 D0 2F 01 A0 37 15 02 50 +13 05 45 F8 EF 20 F0 30 F5 B7 01 00 72 75 6E 5F +73 68 61 33 5F 74 65 73 74 3A 20 70 72 6F 63 65 +73 73 69 6E 67 20 74 65 73 74 20 77 69 74 68 20 +69 6E 64 65 78 20 25 64 0A 00 00 00 74 65 73 74 +2E 64 69 67 65 73 74 5F 6C 65 6E 20 28 25 64 29 +20 69 73 20 67 72 65 61 74 65 72 20 74 68 61 6E +20 44 49 47 45 53 54 5F 4C 45 4E 5F 53 48 41 33 +5F 4D 41 58 2E 0A 00 00 74 65 73 74 20 25 64 3A +20 6D 69 73 6D 61 74 63 68 20 61 74 20 25 64 20 +67 6F 74 3D 30 78 25 78 20 77 61 6E 74 3D 30 78 +25 78 00 00 72 75 6E 5F 73 68 61 33 5F 61 6C 69 +67 6E 6D 65 6E 74 5F 74 65 73 74 3A 20 70 72 6F +63 65 73 73 69 6E 67 20 74 65 73 74 20 77 69 74 +68 20 61 6C 69 67 6E 6D 65 6E 74 20 25 64 0A 00 +6D 69 73 6D 61 74 63 68 20 61 74 20 61 6C 69 67 +6E 6D 65 6E 74 20 25 75 20 67 6F 74 20 30 78 25 +75 20 77 61 6E 74 20 30 78 25 78 00 6D 69 73 6D +61 74 63 68 20 67 6F 74 20 30 78 25 75 20 77 61 +6E 74 20 30 78 25 78 00 72 75 6E 5F 73 68 61 6B +65 5F 74 65 73 74 3A 20 70 72 6F 63 65 73 73 69 +6E 67 20 74 65 73 74 20 77 69 74 68 20 69 6E 64 +65 78 20 25 64 0A 00 00 74 65 73 74 20 25 64 3A +20 6D 69 73 6D 61 74 63 68 20 61 74 20 25 64 20 +67 6F 74 3D 30 78 25 78 20 77 61 6E 74 3D 30 78 +25 78 00 00 49 74 65 72 61 74 69 6F 6E 20 25 30 +75 20 6F 66 20 25 30 75 0A 00 00 00 79 71 22 D4 +37 04 02 50 83 27 44 5A 26 D2 06 D6 4A D0 4E CE +52 CC 56 CA 5A C8 5E C6 89 44 63 E1 F4 0C B7 09 +03 50 EF 10 30 46 93 89 09 00 83 A7 09 00 B9 C7 +05 6A 01 49 13 0A 4A 88 B7 1B 02 50 37 1B 02 50 +B7 1A 02 50 89 44 83 27 44 5A 63 EE F4 04 37 05 +04 10 EF F0 3F 8B 83 27 44 5A 63 EC F4 06 37 05 +04 10 C9 34 83 27 44 5A 37 05 04 10 63 ED F4 00 +79 31 83 A7 09 00 05 09 E3 67 F9 FC 13 05 F0 0F +EF 20 30 0D 01 A0 13 85 0A 02 EF 20 90 0E 37 05 +04 10 B5 31 83 A7 09 00 05 09 E3 71 F9 FE 83 27 +44 5A E3 F6 F4 FA 03 A6 09 00 CA 85 52 85 EF 20 +50 0E 83 27 44 5A 13 85 CB FE E3 FA F4 F8 EF 20 +50 0B 37 05 04 10 EF F0 FF 83 83 27 44 5A E3 F8 +F4 F8 13 05 0B 00 EF 20 D0 09 51 B7 37 19 02 50 +13 05 49 FB EF 20 F0 08 83 27 44 5A E3 F9 F4 F2 +37 15 02 50 13 05 85 FD EF 20 B0 07 83 27 44 5A +E3 FF F4 F0 13 05 49 FB EF 20 B0 06 09 BF 00 00 +6F 10 10 6A 6F 00 10 45 00 00 00 00 6F 00 90 44 +00 00 00 00 6F 00 10 44 00 00 00 00 6F 10 10 59 +00 00 00 00 6F 00 10 43 00 00 00 00 6F 00 90 42 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 6F 10 D0 5A 6F 10 10 5B 5D 71 2A DA +13 05 B0 0F 22 DE 36 D4 3E D0 86 C6 96 C4 9A C2 +9E C0 26 DC 2E D8 32 D6 3A D2 42 CE 46 CC 4A CA +4E C8 72 C6 76 C4 7A C2 7E C0 37 04 02 50 EF 20 +40 79 83 26 44 5A 8D 47 63 E9 D7 08 F3 27 B0 BC +F3 29 C0 BC 73 29 10 34 F3 24 00 30 73 24 40 30 +73 90 C7 BC A1 47 73 A0 07 30 37 47 02 50 83 27 +C7 8A 0D 46 85 07 23 26 F7 8A 63 69 D6 06 A1 47 +73 B0 07 30 73 90 C9 BC 73 10 19 34 89 67 93 87 +07 88 FD 8C 73 A0 04 30 85 67 93 87 87 88 7D 8C +73 20 44 30 13 05 C0 0F EF 20 A0 72 72 54 B6 40 +A6 42 16 43 86 43 E2 54 52 55 C2 55 32 56 A2 56 +12 57 82 57 72 48 E2 48 52 49 C2 49 32 4E A2 4E +12 4F 82 4F 61 61 73 00 20 30 37 15 02 50 13 05 +85 04 EF 20 00 71 83 26 44 5A 8D B7 83 25 C7 8A +0D 65 13 05 05 95 EF 20 C0 71 51 B7 5D 71 2A DA +13 05 B0 0F 22 DE 36 D4 3E D0 86 C6 96 C4 9A C2 +9E C0 26 DC 2E D8 32 D6 3A D2 42 CE 46 CC 4A CA +4E C8 72 C6 76 C4 7A C2 7E C0 37 04 02 50 EF 20 +40 6A 83 26 44 5A 8D 47 63 E9 D7 08 F3 27 B0 BC +F3 29 C0 BC 73 29 10 34 F3 24 00 30 73 24 40 30 +73 90 C7 BC A1 47 73 A0 07 30 37 47 02 50 83 27 +C7 8A 0D 46 85 07 23 26 F7 8A 63 69 D6 06 A1 47 +73 B0 07 30 73 90 C9 BC 73 10 19 34 89 67 93 87 +07 88 FD 8C 73 A0 04 30 85 67 93 87 87 88 7D 8C +73 20 44 30 13 05 C0 0F EF 20 A0 63 72 54 B6 40 +A6 42 16 43 86 43 E2 54 52 55 C2 55 32 56 A2 56 +12 57 82 57 72 48 E2 48 52 49 C2 49 32 4E A2 4E +12 4F 82 4F 61 61 73 00 20 30 37 15 02 50 13 05 +C5 05 EF 20 00 62 83 26 44 5A 8D B7 83 25 C7 8A +0D 65 13 05 85 96 EF 20 C0 62 51 B7 5D 71 2A DA +13 05 B0 0F 22 DE 36 D4 3E D0 86 C6 96 C4 9A C2 +9E C0 26 DC 2E D8 32 D6 3A D2 42 CE 46 CC 4A CA +4E C8 72 C6 76 C4 7A C2 7E C0 37 04 02 50 EF 20 +40 5B 83 26 44 5A 8D 47 63 E9 D7 08 F3 27 B0 BC +F3 29 C0 BC 73 29 10 34 F3 24 00 30 73 24 40 30 +73 90 C7 BC A1 47 73 A0 07 30 37 47 02 50 83 27 +C7 8A 0D 46 85 07 23 26 F7 8A 63 69 D6 06 A1 47 +73 B0 07 30 73 90 C9 BC 73 10 19 34 89 67 93 87 +07 88 FD 8C 73 A0 04 30 85 67 93 87 87 88 7D 8C +73 20 44 30 13 05 C0 0F EF 20 A0 54 72 54 B6 40 +A6 42 16 43 86 43 E2 54 52 55 C2 55 32 56 A2 56 +12 57 82 57 72 48 E2 48 52 49 C2 49 32 4E A2 4E +12 4F 82 4F 61 61 73 00 20 30 37 15 02 50 13 05 +05 07 EF 20 00 53 83 26 44 5A 8D B7 83 25 C7 8A +0D 65 13 05 05 98 EF 20 C0 53 51 B7 5D 71 2A DA +13 05 B0 0F 22 DE 36 D4 3E D0 86 C6 96 C4 9A C2 +9E C0 26 DC 2E D8 32 D6 3A D2 42 CE 46 CC 4A CA +4E C8 72 C6 76 C4 7A C2 7E C0 37 04 02 50 EF 20 +40 4C 83 26 44 5A 8D 47 63 E9 D7 08 F3 27 B0 BC +F3 29 C0 BC 73 29 10 34 F3 24 00 30 73 24 40 30 +73 90 C7 BC A1 47 73 A0 07 30 37 47 02 50 83 27 +C7 8A 0D 46 85 07 23 26 F7 8A 63 69 D6 06 A1 47 +73 B0 07 30 73 90 C9 BC 73 10 19 34 89 67 93 87 +07 88 FD 8C 73 A0 04 30 85 67 93 87 87 88 7D 8C +73 20 44 30 13 05 C0 0F EF 20 A0 45 72 54 B6 40 +A6 42 16 43 86 43 E2 54 52 55 C2 55 32 56 A2 56 +12 57 82 57 72 48 E2 48 52 49 C2 49 32 4E A2 4E +12 4F 82 4F 61 61 73 00 20 30 37 15 02 50 13 05 +05 08 EF 20 00 44 83 26 44 5A 8D B7 83 25 C7 8A +0D 65 13 05 45 99 EF 20 C0 44 51 B7 5D 71 2A DA +13 05 B0 0F 22 DE 36 D4 3E D0 86 C6 96 C4 9A C2 +9E C0 26 DC 2E D8 32 D6 3A D2 42 CE 46 CC 4A CA +4E C8 72 C6 76 C4 7A C2 7E C0 37 04 02 50 EF 20 +40 3D 83 26 44 5A 8D 47 63 E9 D7 08 F3 27 B0 BC +F3 29 C0 BC 73 29 10 34 F3 24 00 30 73 24 40 30 +73 90 C7 BC A1 47 73 A0 07 30 37 47 02 50 83 27 +C7 8A 0D 46 85 07 23 26 F7 8A 63 69 D6 06 A1 47 +73 B0 07 30 73 90 C9 BC 73 10 19 34 89 67 93 87 +07 88 FD 8C 73 A0 04 30 85 67 93 87 87 88 7D 8C +73 20 44 30 13 05 C0 0F EF 20 A0 36 72 54 B6 40 +A6 42 16 43 86 43 E2 54 52 55 C2 55 32 56 A2 56 +12 57 82 57 72 48 E2 48 52 49 C2 49 32 4E A2 4E +12 4F 82 4F 61 61 73 00 20 30 37 15 02 50 13 05 +05 09 EF 20 00 35 83 26 44 5A 8D B7 83 25 C7 8A +0D 65 13 05 85 9A EF 20 C0 35 51 B7 5D 71 2A DA +13 05 B0 0F 22 DE 36 D4 3E D0 86 C6 96 C4 9A C2 +9E C0 26 DC 2E D8 32 D6 3A D2 42 CE 46 CC 4A CA +4E C8 72 C6 76 C4 7A C2 7E C0 37 04 02 50 EF 20 +40 2E 83 26 44 5A 8D 47 63 E9 D7 08 F3 27 B0 BC +F3 29 C0 BC 73 29 10 34 F3 24 00 30 73 24 40 30 +73 90 C7 BC A1 47 73 A0 07 30 37 47 02 50 83 27 +C7 8A 0D 46 85 07 23 26 F7 8A 63 69 D6 06 A1 47 +73 B0 07 30 73 90 C9 BC 73 10 19 34 89 67 93 87 +07 88 FD 8C 73 A0 04 30 85 67 93 87 87 88 7D 8C +73 20 44 30 13 05 C0 0F EF 20 A0 27 72 54 B6 40 +A6 42 16 43 86 43 E2 54 52 55 C2 55 32 56 A2 56 +12 57 82 57 72 48 E2 48 52 49 C2 49 32 4E A2 4E +12 4F 82 4F 61 61 73 00 20 30 37 15 02 50 13 05 +45 0A EF 20 00 26 83 26 44 5A 8D B7 83 25 C7 8A +0D 65 13 05 45 9C EF 20 C0 26 51 B7 5D 71 2A DA +13 05 B0 0F 22 DE 36 D4 3E D0 86 C6 96 C4 9A C2 +9E C0 26 DC 2E D8 32 D6 3A D2 42 CE 46 CC 4A CA +4E C8 72 C6 76 C4 7A C2 7E C0 37 04 02 50 EF 20 +40 1F 83 26 44 5A 8D 47 63 E9 D7 08 F3 27 B0 BC +F3 29 C0 BC 73 29 10 34 F3 24 00 30 73 24 40 30 +73 90 C7 BC A1 47 73 A0 07 30 37 47 02 50 83 27 +C7 8A 0D 46 85 07 23 26 F7 8A 63 69 D6 06 A1 47 +73 B0 07 30 73 90 C9 BC 73 10 19 34 89 67 93 87 +07 88 FD 8C 73 A0 04 30 85 67 93 87 87 88 7D 8C +73 20 44 30 13 05 C0 0F EF 20 A0 18 72 54 B6 40 +A6 42 16 43 86 43 E2 54 52 55 C2 55 32 56 A2 56 +12 57 82 57 72 48 E2 48 52 49 C2 49 32 4E A2 4E +12 4F 82 4F 61 61 73 00 20 30 37 15 02 50 13 05 +45 0B EF 20 00 17 83 26 44 5A 8D B7 83 25 C7 8A +0D 65 13 05 C5 9D EF 20 C0 17 51 B7 5D 71 2A DA +13 05 B0 0F 22 DE 36 D4 3E D0 86 C6 96 C4 9A C2 +9E C0 26 DC 2E D8 32 D6 3A D2 42 CE 46 CC 4A CA +4E C8 72 C6 76 C4 7A C2 7E C0 37 04 02 50 EF 20 +40 10 83 26 44 5A 8D 47 63 E9 D7 08 F3 27 B0 BC +F3 29 C0 BC 73 29 10 34 F3 24 00 30 73 24 40 30 +73 90 C7 BC A1 47 73 A0 07 30 37 47 02 50 83 27 +C7 8A 0D 46 85 07 23 26 F7 8A 63 69 D6 06 A1 47 +73 B0 07 30 73 90 C9 BC 73 10 19 34 89 67 93 87 +07 88 FD 8C 73 A0 04 30 85 67 93 87 87 88 7D 8C +73 20 44 30 13 05 C0 0F EF 20 A0 09 72 54 B6 40 +A6 42 16 43 86 43 E2 54 52 55 C2 55 32 56 A2 56 +12 57 82 57 72 48 E2 48 52 49 C2 49 32 4E A2 4E +12 4F 82 4F 61 61 73 00 20 30 37 15 02 50 13 05 +05 0C EF 20 00 08 83 26 44 5A 8D B7 83 25 C7 8A +0D 65 13 05 05 9F EF 20 C0 08 51 B7 5D 71 2A DA +13 05 B0 0F 22 DE 36 D4 3E D0 86 C6 96 C4 9A C2 +9E C0 26 DC 2E D8 32 D6 3A D2 42 CE 46 CC 4A CA +4E C8 72 C6 76 C4 7A C2 7E C0 37 04 02 50 EF 20 +40 01 83 26 44 5A 8D 47 63 E9 D7 08 F3 27 B0 BC +F3 29 C0 BC 73 29 10 34 F3 24 00 30 73 24 40 30 +73 90 C7 BC A1 47 73 A0 07 30 37 47 02 50 83 27 +C7 8A 0D 46 85 07 23 26 F7 8A 63 69 D6 06 A1 47 +73 B0 07 30 73 90 C9 BC 73 10 19 34 89 67 93 87 +07 88 FD 8C 73 A0 04 30 85 67 93 87 87 88 7D 8C +73 20 44 30 13 05 C0 0F EF 10 B0 7A 72 54 B6 40 +A6 42 16 43 86 43 E2 54 52 55 C2 55 32 56 A2 56 +12 57 82 57 72 48 E2 48 52 49 C2 49 32 4E A2 4E +12 4F 82 4F 61 61 73 00 20 30 37 15 02 50 13 05 +C5 0C EF 10 10 79 83 26 44 5A 8D B7 83 25 C7 8A +0D 65 13 05 45 A0 EF 10 D0 79 51 B7 5D 71 2A DA +13 05 B0 0F 22 DE 36 D4 3E D0 86 C6 96 C4 9A C2 +9E C0 26 DC 2E D8 32 D6 3A D2 42 CE 46 CC 4A CA +4E C8 72 C6 76 C4 7A C2 7E C0 37 04 02 50 EF 10 +50 72 83 26 44 5A 8D 47 63 E9 D7 08 F3 27 B0 BC +F3 29 C0 BC 73 29 10 34 F3 24 00 30 73 24 40 30 +73 90 C7 BC A1 47 73 A0 07 30 37 47 02 50 83 27 +C7 8A 0D 46 85 07 23 26 F7 8A 63 69 D6 06 A1 47 +73 B0 07 30 73 90 C9 BC 73 10 19 34 89 67 93 87 +07 88 FD 8C 73 A0 04 30 85 67 93 87 87 88 7D 8C +73 20 44 30 13 05 C0 0F EF 10 B0 6B 72 54 B6 40 +A6 42 16 43 86 43 E2 54 52 55 C2 55 32 56 A2 56 +12 57 82 57 72 48 E2 48 52 49 C2 49 32 4E A2 4E +12 4F 82 4F 61 61 73 00 20 30 37 15 02 50 13 05 +C5 0D EF 10 10 6A 83 26 44 5A 8D B7 83 25 C7 8A +0D 65 13 05 85 A1 EF 10 D0 6A 51 B7 5D 71 2A DA +13 05 B0 0F 22 DE 36 D4 3E D0 86 C6 96 C4 9A C2 +9E C0 26 DC 2E D8 32 D6 3A D2 42 CE 46 CC 4A CA +4E C8 72 C6 76 C4 7A C2 7E C0 37 04 02 50 EF 10 +50 63 83 26 44 5A 8D 47 63 E9 D7 08 F3 27 B0 BC +F3 29 C0 BC 73 29 10 34 F3 24 00 30 73 24 40 30 +73 90 C7 BC A1 47 73 A0 07 30 37 47 02 50 83 27 +C7 8A 0D 46 85 07 23 26 F7 8A 63 69 D6 06 A1 47 +73 B0 07 30 73 90 C9 BC 73 10 19 34 89 67 93 87 +07 88 FD 8C 73 A0 04 30 85 67 93 87 87 88 7D 8C +73 20 44 30 13 05 C0 0F EF 10 B0 5C 72 54 B6 40 +A6 42 16 43 86 43 E2 54 52 55 C2 55 32 56 A2 56 +12 57 82 57 72 48 E2 48 52 49 C2 49 32 4E A2 4E +12 4F 82 4F 61 61 73 00 20 30 37 15 02 50 13 05 +C5 0E EF 10 10 5B 83 26 44 5A 8D B7 83 25 C7 8A +0D 65 13 05 C5 A2 EF 10 D0 5B 51 B7 39 71 2A D6 +13 05 B0 0F 3A CE 3E CC 06 DE 16 DC 1A DA 1E D8 +2E D4 32 D2 36 D0 42 CA 46 C8 72 C6 76 C4 7A C2 +7E C0 EF 10 10 55 B7 07 02 50 03 A7 47 5A 8D 47 +63 E9 E7 02 13 05 C0 0F EF 10 B0 53 F2 50 E2 52 +52 53 C2 53 32 55 A2 55 12 56 82 56 72 47 E2 47 +52 48 C2 48 32 4E A2 4E 12 4F 82 4F 21 61 73 00 +20 30 37 15 02 50 13 05 C5 0F EF 10 90 52 D9 B7 +5D 71 2A DA 13 05 B0 0F 22 DE 36 D4 3E D0 86 C6 +96 C4 9A C2 9E C0 26 DC 2E D8 32 D6 3A D2 42 CE +46 CC 4A CA 4E C8 72 C6 76 C4 7A C2 7E C0 37 04 +02 50 EF 10 10 4D 83 26 44 5A 8D 47 63 EA D7 0A +F3 27 B0 BC F3 29 C0 BC 73 29 10 34 F3 24 00 30 +73 24 40 30 73 90 C7 BC A1 47 73 A0 07 30 37 47 +02 50 83 27 C7 8A 0D 46 85 07 23 26 F7 8A 63 6A +D6 08 37 97 02 10 83 27 47 81 85 8B 81 CF B7 47 +02 50 93 87 07 8B 94 57 05 46 23 2A C7 80 13 E7 +16 00 98 D7 A1 47 73 B0 07 30 73 90 C9 BC 73 10 +19 34 89 67 93 87 07 88 FD 8C 73 A0 04 30 85 67 +93 87 87 88 7D 8C 73 20 44 30 13 05 C0 0F EF 10 +50 44 72 54 B6 40 A6 42 16 43 86 43 E2 54 52 55 +C2 55 32 56 A2 56 12 57 82 57 72 48 E2 48 52 49 +C2 49 32 4E A2 4E 12 4F 82 4F 61 61 73 00 20 30 +37 15 02 50 13 05 45 10 EF 10 B0 42 83 26 44 5A +81 B7 83 25 C7 8A 0D 65 13 05 05 A4 EF 10 70 43 +8D B7 01 00 39 71 3E CC B7 07 02 50 3A CE 03 A7 +47 5A 06 DE 16 DC 1A DA 1E D8 2A D6 2E D4 32 D2 +36 D0 42 CA 46 C8 72 C6 76 C4 7A C2 7E C0 91 47 +63 E5 E7 02 F2 50 E2 52 52 53 C2 53 32 55 A2 55 +12 56 82 56 72 47 E2 47 52 48 C2 48 32 4E A2 4E +12 4F 82 4F 21 61 73 00 20 30 F3 25 20 34 0D 65 +13 05 85 A5 EF 10 F0 3C F1 B7 1D 71 AA C2 13 05 +B0 0F A2 C6 36 DC 3E D8 86 CE 96 CC 9A CA 9E C8 +A6 C4 AE C0 32 DE 3A DA 42 D6 46 D4 4A D2 4E D0 +52 CE 72 CC 76 CA 7A C8 7E C6 37 04 02 50 EF 10 +50 35 83 26 44 5A 8D 47 63 ED D7 0C F3 27 B0 BC +73 2A C0 BC F3 29 10 34 73 29 00 30 F3 24 40 30 +73 90 C7 BC A1 47 73 A0 07 30 37 47 02 50 83 27 +C7 8A 0D 46 85 07 23 26 F7 8A 63 6C D6 08 37 27 +02 30 83 27 87 81 93 F6 17 00 A5 CE B7 47 02 50 +93 87 07 8B F4 43 05 46 23 2C C7 80 13 E7 16 00 +F8 C3 A1 47 73 B0 07 30 73 10 CA BC 73 90 19 34 +89 67 93 87 07 88 33 79 F9 00 73 20 09 30 85 67 +93 87 87 88 FD 8C 73 A0 44 30 13 05 C0 0F EF 10 +50 2C 36 44 F6 40 E6 42 56 43 C6 43 A6 44 16 45 +86 45 72 56 E2 56 52 57 C2 57 32 58 A2 58 12 59 +82 59 72 4A 62 4E D2 4E 42 4F B2 4F 25 61 73 00 +20 30 C5 F3 83 27 44 5A 95 E7 05 45 EF 10 70 28 +01 A0 83 25 C7 8A 0D 65 13 05 45 A6 EF 10 70 2B +B9 BF 37 15 02 50 13 05 45 11 EF 10 90 28 83 26 +44 5A 29 BF 0D 65 81 45 13 05 05 A8 EF 10 70 29 +05 45 EF 10 10 25 E9 B7 1D 71 AA C2 13 05 B0 0F +A2 C6 36 DC 3E D8 86 CE 96 CC 9A CA 9E C8 A6 C4 +AE C0 32 DE 3A DA 42 D6 46 D4 4A D2 4E D0 52 CE +72 CC 76 CA 7A C8 7E C6 37 04 02 50 EF 10 70 21 +83 26 44 5A 8D 47 63 E3 D7 1A F3 27 B0 BC 73 2A +C0 BC F3 29 10 34 73 29 00 30 F3 24 40 30 73 90 +C7 BC A1 47 73 A0 07 30 37 47 02 50 83 27 C7 8A +0D 46 85 07 23 26 F7 8A 63 62 D6 16 B7 16 03 30 +03 A7 86 81 93 77 17 00 81 CF B7 47 02 50 05 46 +23 AC C6 80 93 87 07 8B D4 5F 93 E6 16 00 D4 DF +93 77 27 00 91 CF B7 16 03 30 B7 47 02 50 09 46 +23 AC C6 80 93 87 07 8B D4 5F 93 E6 26 00 D4 DF +93 77 47 00 91 CF B7 16 03 30 B7 47 02 50 11 46 +23 AC C6 80 93 87 07 8B D4 5F 93 E6 46 00 D4 DF +93 77 87 00 13 76 07 01 93 76 07 02 DD C3 37 17 +03 30 B7 47 02 50 A1 45 23 2C B7 80 93 87 07 8B +D8 5F 13 67 87 00 D8 DF 55 CE 37 17 03 30 41 46 +23 2C C7 80 D8 5F 13 67 07 01 D8 DF 99 CA 37 17 +03 30 93 06 00 02 23 2C D7 80 D8 5F 13 67 07 02 +D8 DF A1 47 73 B0 07 30 73 10 CA BC 73 90 19 34 +89 67 93 87 07 88 33 79 F9 00 73 20 09 30 85 67 +93 87 87 88 FD 8C 73 A0 44 30 13 05 C0 0F EF 10 +50 0F 36 44 F6 40 E6 42 56 43 C6 43 A6 44 16 45 +86 45 72 56 E2 56 52 57 C2 57 32 58 A2 58 12 59 +82 59 72 4A 62 4E D2 4E 42 4F B2 4F 25 61 73 00 +20 30 05 C2 37 17 03 30 B7 47 02 50 41 46 93 87 +07 8B 23 2C C7 80 D8 5F 13 67 07 01 D8 DF A5 FA +49 B7 B1 E6 3D FF 83 27 44 5A AD E3 05 45 EF 10 +50 09 01 A0 BD D6 37 17 03 30 93 06 00 02 23 2C +D7 80 D8 5F 13 67 07 02 D8 DF A1 BF 83 25 C7 8A +0D 65 13 05 45 AA EF 10 D0 0A 49 BD 37 15 02 50 +13 05 85 12 EF 10 F0 07 83 26 44 5A B9 B5 37 17 +03 30 B7 47 02 50 93 06 00 02 93 87 07 8B 23 2C +D7 80 D8 5F 13 67 07 02 D8 DF 21 BF 0D 65 81 45 +13 05 C5 AB EF 10 F0 06 51 BF 1D 71 AA C2 13 05 +B0 0F A2 C6 36 DC 3E D8 86 CE 96 CC 9A CA 9E C8 +A6 C4 AE C0 32 DE 3A DA 42 D6 46 D4 4A D2 4E D0 +52 CE 72 CC 76 CA 7A C8 7E C6 37 04 02 50 EF 10 +40 7F 83 26 44 5A 8D 47 63 E3 D7 1A F3 27 B0 BC +73 2A C0 BC F3 29 10 34 73 29 00 30 F3 24 40 30 +73 90 C7 BC A1 47 73 A0 07 30 37 47 02 50 83 27 +C7 8A 0D 46 85 07 23 26 F7 8A 63 62 D6 16 B7 16 +03 30 03 A7 46 81 93 77 17 00 81 CF B7 47 02 50 +05 46 23 AA C6 80 93 87 07 8B 94 5F 93 E6 16 00 +94 DF 93 77 27 00 91 CF B7 16 03 30 B7 47 02 50 +09 46 23 AA C6 80 93 87 07 8B 94 5F 93 E6 26 00 +94 DF 93 77 47 00 91 CF B7 16 03 30 B7 47 02 50 +11 46 23 AA C6 80 93 87 07 8B 94 5F 93 E6 46 00 +94 DF 93 77 87 00 13 76 07 01 93 76 07 02 DD C3 +37 17 03 30 B7 47 02 50 A1 45 23 2A B7 80 93 87 +07 8B 98 5F 13 67 87 00 98 DF 55 CE 37 17 03 30 +41 46 23 2A C7 80 98 5F 13 67 07 01 98 DF 99 CA +37 17 03 30 93 06 00 02 23 2A D7 80 98 5F 13 67 +07 02 98 DF A1 47 73 B0 07 30 73 10 CA BC 73 90 +19 34 89 67 93 87 07 88 33 79 F9 00 73 20 09 30 +85 67 93 87 87 88 FD 8C 73 A0 44 30 13 05 C0 0F +EF 10 20 6D 36 44 F6 40 E6 42 56 43 C6 43 A6 44 +16 45 86 45 72 56 E2 56 52 57 C2 57 32 58 A2 58 +12 59 82 59 72 4A 62 4E D2 4E 42 4F B2 4F 25 61 +73 00 20 30 05 C2 37 17 03 30 B7 47 02 50 41 46 +93 87 07 8B 23 2A C7 80 98 5F 13 67 07 01 98 DF +A5 FA 49 B7 B1 E6 3D FF 83 27 44 5A AD E3 05 45 +EF 10 20 67 01 A0 BD D6 37 17 03 30 93 06 00 02 +23 2A D7 80 98 5F 13 67 07 02 98 DF A1 BF 83 25 +C7 8A 0D 65 13 05 C5 AD EF 10 A0 68 49 BD 37 15 +02 50 13 05 C5 13 EF 10 C0 65 83 26 44 5A B9 B5 +37 17 03 30 B7 47 02 50 93 06 00 02 93 87 07 8B +23 2A D7 80 98 5F 13 67 07 02 98 DF 21 BF 0D 65 +81 45 13 05 45 AF EF 10 C0 64 51 BF 1D 71 AA C2 +13 05 B0 0F A2 C6 36 DC 3E D8 86 CE 96 CC 9A CA +9E C8 A6 C4 AE C0 32 DE 3A DA 42 D6 46 D4 4A D2 +4E D0 52 CE 72 CC 76 CA 7A C8 7E C6 37 04 02 50 +EF 10 20 5D 83 26 44 5A 8D 47 63 E0 D7 12 F3 27 +B0 BC 73 2A C0 BC F3 29 10 34 73 29 00 30 F3 24 +40 30 73 90 C7 BC A1 47 73 A0 07 30 37 47 02 50 +83 27 C7 8A 0D 46 85 07 23 26 F7 8A 63 6F D6 0C +37 07 04 10 0C 43 37 16 04 10 83 27 86 41 93 F6 +15 00 BD CE B7 46 02 50 93 86 06 8B CC 5A 05 45 +08 C3 13 E7 15 00 D8 DA 85 8B CD C3 23 2C A6 40 +A1 47 73 B0 07 30 73 10 CA BC 73 90 19 34 89 67 +93 87 07 88 33 79 F9 00 73 20 09 30 85 67 93 87 +87 88 FD 8C 73 A0 44 30 13 05 C0 0F EF 10 60 53 +36 44 F6 40 E6 42 56 43 C6 43 A6 44 16 45 86 45 +72 56 E2 56 52 57 C2 57 32 58 A2 58 12 59 82 59 +72 4A 62 4E D2 4E 42 4F B2 4F 25 61 73 00 20 30 +13 F7 25 00 15 C3 37 47 02 50 13 07 07 8B 54 5B +89 8B 93 E6 26 00 54 DB B1 EB 83 27 44 5A B5 E3 +05 45 EF 10 00 4E 01 A0 93 F7 45 00 B5 FB 83 27 +44 5A B9 EF 05 45 EF 10 C0 4C 01 A0 83 27 44 5A +95 EB 05 45 EF 10 E0 4B 01 A0 83 25 C7 8A 0D 65 +13 05 45 B1 EF 10 E0 4E 21 BF 37 15 02 50 13 05 +05 15 EF 10 00 4C 83 26 44 5A D1 BD 89 47 23 2C +F6 40 3D B7 37 15 02 50 13 05 05 16 EF 10 60 4A +C9 B7 37 15 02 50 13 05 45 19 EF 10 80 49 49 BF +0D 65 13 05 85 B2 EF 10 C0 4A 69 BF 1D 71 AA C2 +13 05 B0 0F 36 DC 3E D8 4A D2 86 CE 96 CC 9A CA +9E C8 A2 C6 A6 C4 AE C0 32 DE 3A DA 42 D6 46 D4 +4E D0 52 CE 72 CC 76 CA 7A C8 7E C6 37 09 02 50 +EF 10 20 43 83 26 49 5A 8D 47 63 EC D7 0E F3 27 +B0 BC 73 2A C0 BC F3 29 10 34 F3 24 00 30 73 24 +40 30 73 90 C7 BC A1 47 73 A0 07 30 37 47 02 50 +83 27 C7 8A 0D 46 85 07 23 26 F7 8A 63 6B D6 0A +B7 07 04 10 8C 43 37 16 04 10 03 27 46 41 93 F6 +45 00 BD CE B7 46 02 50 93 86 06 8B 8C 5A 11 45 +88 C3 93 E7 45 00 9C DA 05 8B 2D CF 85 47 23 2A +F6 40 A1 47 73 B0 07 30 73 10 CA BC 73 90 19 34 +89 67 93 87 07 88 FD 8C 73 A0 04 30 85 67 93 87 +87 88 7D 8C 73 20 44 30 13 05 C0 0F EF 10 60 39 +36 44 F6 40 E6 42 56 43 C6 43 A6 44 16 45 86 45 +72 56 E2 56 52 57 C2 57 32 58 A2 58 12 59 82 59 +72 4A 62 4E D2 4E 42 4F B2 4F 25 61 73 00 20 30 +93 F7 35 00 D9 FF 83 27 49 5A A1 E7 05 45 EF 10 +40 35 01 A0 83 27 49 5A 95 E7 05 45 EF 10 60 34 +01 A0 83 25 C7 8A 0D 65 13 05 45 B4 EF 10 60 37 +81 B7 37 15 02 50 13 05 05 1D EF 10 80 34 83 26 +49 5A F5 BD 37 15 02 50 13 05 05 1E EF 10 60 33 +E9 B7 0D 65 13 05 85 B5 EF 10 A0 34 45 BF 1D 71 +AA C2 13 05 B0 0F A2 C6 36 DC 3E D8 86 CE 96 CC +9A CA 9E C8 A6 C4 AE C0 32 DE 3A DA 42 D6 46 D4 +4A D2 4E D0 52 CE 72 CC 76 CA 7A C8 7E C6 37 04 +02 50 EF 10 00 2D 83 26 44 5A 8D 47 63 ED D7 0C +F3 27 B0 BC 73 2A C0 BC F3 29 10 34 73 29 00 30 +F3 24 40 30 73 90 C7 BC A1 47 73 A0 07 30 37 47 +02 50 83 27 C7 8A 0D 46 85 07 23 26 F7 8A 63 6C +D6 08 37 97 02 10 83 27 87 81 93 F6 17 00 A5 CE +B7 47 02 50 93 87 07 8B D4 57 05 46 23 2C C7 80 +13 E7 16 00 D8 D7 A1 47 73 B0 07 30 73 10 CA BC +73 90 19 34 89 67 93 87 07 88 33 79 F9 00 73 20 +09 30 85 67 93 87 87 88 FD 8C 73 A0 44 30 13 05 +C0 0F EF 10 00 24 36 44 F6 40 E6 42 56 43 C6 43 +A6 44 16 45 86 45 72 56 E2 56 52 57 C2 57 32 58 +A2 58 12 59 82 59 72 4A 62 4E D2 4E 42 4F B2 4F +25 61 73 00 20 30 C5 F3 83 27 44 5A 95 E7 05 45 +EF 10 20 20 01 A0 83 25 C7 8A 0D 65 13 05 45 B7 +EF 10 20 23 B9 BF 37 15 02 50 13 05 85 21 EF 10 +40 20 83 26 44 5A 29 BF 0D 65 81 45 13 05 C5 B8 +EF 10 20 21 05 45 EF 10 C0 1C E9 B7 1D 71 AA C2 +13 05 B0 0F A2 C6 36 DC 3E D8 86 CE 96 CC 9A CA +9E C8 A6 C4 AE C0 32 DE 3A DA 42 D6 46 D4 4A D2 +4E D0 52 CE 72 CC 76 CA 7A C8 7E C6 37 04 02 50 +EF 10 20 19 83 26 44 5A 8D 47 63 ED D7 0C F3 27 +B0 BC 73 2A C0 BC F3 29 10 34 73 29 00 30 F3 24 +40 30 73 90 C7 BC A1 47 73 A0 07 30 37 47 02 50 +83 27 C7 8A 0D 46 85 07 23 26 F7 8A 63 6C D6 08 +37 17 02 10 83 27 87 81 93 F6 17 00 A5 CE B7 47 +02 50 93 87 07 8B D4 53 05 46 23 2C C7 80 13 E7 +16 00 D8 D3 A1 47 73 B0 07 30 73 10 CA BC 73 90 +19 34 89 67 93 87 07 88 33 79 F9 00 73 20 09 30 +85 67 93 87 87 88 FD 8C 73 A0 44 30 13 05 C0 0F +EF 10 20 10 36 44 F6 40 E6 42 56 43 C6 43 A6 44 +16 45 86 45 72 56 E2 56 52 57 C2 57 32 58 A2 58 +12 59 82 59 72 4A 62 4E D2 4E 42 4F B2 4F 25 61 +73 00 20 30 C5 F3 83 27 44 5A 95 E7 05 45 EF 10 +40 0C 01 A0 83 25 C7 8A 0D 65 13 05 C5 BA EF 10 +40 0F B9 BF 37 15 02 50 13 05 85 22 EF 10 60 0C +83 26 44 5A 29 BF 0D 65 81 45 13 05 45 BC EF 10 +40 0D 05 45 EF 10 E0 08 E9 B7 1D 71 AA C2 13 05 +B0 0F A2 C6 36 DC 3E D8 86 CE 96 CC 9A CA 9E C8 +A6 C4 AE C0 32 DE 3A DA 42 D6 46 D4 4A D2 4E D0 +52 CE 72 CC 76 CA 7A C8 7E C6 37 04 02 50 EF 10 +40 05 83 26 44 5A 8D 47 63 ED D7 0C F3 27 B0 BC +73 2A C0 BC F3 29 10 34 73 29 00 30 F3 24 40 30 +73 90 C7 BC A1 47 73 A0 07 30 37 47 02 50 83 27 +C7 8A 0D 46 85 07 23 26 F7 8A 63 6C D6 08 37 17 +01 10 83 27 87 81 93 F6 17 00 A5 CE B7 47 02 50 +93 87 07 8B D4 4B 05 46 23 2C C7 80 13 E7 16 00 +D8 CB A1 47 73 B0 07 30 73 10 CA BC 73 90 19 34 +89 67 93 87 07 88 33 79 F9 00 73 20 09 30 85 67 +93 87 87 88 FD 8C 73 A0 44 30 13 05 C0 0F EF 00 +50 7C 36 44 F6 40 E6 42 56 43 C6 43 A6 44 16 45 +86 45 72 56 E2 56 52 57 C2 57 32 58 A2 58 12 59 +82 59 72 4A 62 4E D2 4E 42 4F B2 4F 25 61 73 00 +20 30 C5 F3 83 27 44 5A 95 E7 05 45 EF 00 70 78 +01 A0 83 25 C7 8A 0D 65 13 05 45 BE EF 00 70 7B +B9 BF 37 15 02 50 13 05 85 23 EF 00 90 78 83 26 +44 5A 29 BF 0D 65 81 45 13 05 85 BF EF 00 70 79 +05 45 EF 00 10 75 E9 B7 1D 71 AA C2 13 05 B0 0F +A2 C6 36 DC 3E D8 86 CE 96 CC 9A CA 9E C8 A6 C4 +AE C0 32 DE 3A DA 42 D6 46 D4 4A D2 4E D0 52 CE +72 CC 76 CA 7A C8 7E C6 37 04 02 50 EF 00 70 71 +83 26 44 5A 8D 47 63 ED D7 0C F3 27 B0 BC 73 2A +C0 BC F3 29 10 34 73 29 00 30 F3 24 40 30 73 90 +C7 BC A1 47 73 A0 07 30 37 47 02 50 83 27 C7 8A +0D 46 85 07 23 26 F7 8A 63 6C D6 08 37 97 00 10 +83 27 87 81 93 F6 17 00 A5 CE B7 47 02 50 93 87 +07 8B D4 47 05 46 23 2C C7 80 13 E7 16 00 D8 C7 +A1 47 73 B0 07 30 73 10 CA BC 73 90 19 34 89 67 +93 87 07 88 33 79 F9 00 73 20 09 30 85 67 93 87 +87 88 FD 8C 73 A0 44 30 13 05 C0 0F EF 00 70 68 +36 44 F6 40 E6 42 56 43 C6 43 A6 44 16 45 86 45 +72 56 E2 56 52 57 C2 57 32 58 A2 58 12 59 82 59 +72 4A 62 4E D2 4E 42 4F B2 4F 25 61 73 00 20 30 +C5 F3 83 27 44 5A 95 E7 05 45 EF 00 90 64 01 A0 +83 25 C7 8A 0D 65 13 05 45 C1 EF 00 90 67 B9 BF +37 15 02 50 13 05 85 24 EF 00 B0 64 83 26 44 5A +29 BF 0D 65 81 45 13 05 85 C2 EF 00 90 65 05 45 +EF 00 30 61 E9 B7 1D 71 AA C2 13 05 B0 0F A2 C6 +36 DC 3E D8 86 CE 96 CC 9A CA 9E C8 A6 C4 AE C0 +32 DE 3A DA 42 D6 46 D4 4A D2 4E D0 52 CE 72 CC +76 CA 7A C8 7E C6 37 04 02 50 EF 00 90 5D 83 26 +44 5A 8D 47 63 ED D7 0C F3 27 B0 BC 73 2A C0 BC +F3 29 10 34 73 29 00 30 F3 24 40 30 73 90 C7 BC +A1 47 73 A0 07 30 37 47 02 50 83 27 C7 8A 0D 46 +85 07 23 26 F7 8A 63 6C D6 08 37 17 00 10 83 27 +87 81 93 F6 17 00 A5 CE B7 47 02 50 93 87 07 8B +D4 43 05 46 23 2C C7 80 13 E7 16 00 D8 C3 A1 47 +73 B0 07 30 73 10 CA BC 73 90 19 34 89 67 93 87 +07 88 33 79 F9 00 73 20 09 30 85 67 93 87 87 88 +FD 8C 73 A0 44 30 13 05 C0 0F EF 00 90 54 36 44 +F6 40 E6 42 56 43 C6 43 A6 44 16 45 86 45 72 56 +E2 56 52 57 C2 57 32 58 A2 58 12 59 82 59 72 4A +62 4E D2 4E 42 4F B2 4F 25 61 73 00 20 30 C5 F3 +83 27 44 5A 95 E7 05 45 EF 00 B0 50 01 A0 83 25 +C7 8A 0D 65 13 05 45 C4 EF 00 B0 53 B9 BF 37 15 +02 50 13 05 85 25 EF 00 D0 50 83 26 44 5A 29 BF +0D 65 81 45 13 05 85 C5 EF 00 B0 51 05 45 EF 00 +50 4D E9 B7 21 47 73 30 07 30 85 67 93 87 07 9B +93 E7 17 00 73 90 57 30 97 12 02 50 93 82 82 6C +73 90 82 BC B7 37 00 60 23 A0 07 00 0F 00 F0 0F +73 50 90 BC B7 07 00 60 D8 C3 0F 00 F0 0F 9D 46 +94 C7 0F 00 F0 0F D8 C7 0F 00 F0 0F 94 CB 0F 00 +F0 0F D8 CB 0F 00 F0 0F 94 CF 0F 00 F0 0F D8 CF +0F 00 F0 0F 94 D3 0F 00 F0 0F D8 D3 0F 00 F0 0F +94 D7 0F 00 F0 0F D8 D7 0F 00 F0 0F 94 DB 0F 00 +F0 0F 91 45 CC DB 0F 00 F0 0F 0D 46 90 DF 0F 00 +F0 0F CC DF 0F 00 F0 0F B0 C3 0F 00 F0 0F F8 C3 +0F 00 F0 0F B4 C7 0F 00 F0 0F F8 C7 0F 00 F0 0F +B4 CB 0F 00 F0 0F F8 CB 0F 00 F0 0F B4 CF 0F 00 +F0 0F F8 CF 0F 00 F0 0F B4 D3 0F 00 F0 0F F8 D3 +0F 00 F0 0F B4 D7 0F 00 F0 0F 23 A6 07 06 0F 00 +F0 0F 23 A8 07 06 0F 00 F0 0F 23 AA 07 06 0F 00 +F0 0F 23 AC 07 06 0F 00 F0 0F 23 AE 07 06 0F 00 +F0 0F 73 50 B0 BC 73 50 C0 BC 37 47 00 60 11 07 +85 47 05 68 79 75 93 05 00 02 23 20 07 00 0F 00 +F0 0F B3 06 07 01 23 A0 06 00 0F 00 F0 0F B3 06 +A7 00 13 B6 B7 01 90 C2 0F 00 F0 0F 85 07 93 F7 +F7 0F 11 07 E3 9B B7 FC 05 47 B7 16 00 10 23 A4 +E6 80 8D 47 23 A0 F6 80 B7 96 00 10 23 A2 E6 80 +23 A4 E6 80 23 A0 F6 80 3D 46 B7 16 01 10 23 A2 +C6 80 23 A4 E6 80 23 A0 F6 80 B7 16 02 10 23 A4 +E6 80 23 A0 F6 80 B7 96 02 10 23 A2 F6 80 23 A4 +E6 80 23 A0 F6 80 B7 16 04 10 23 A0 F6 40 23 A2 +E6 40 23 A4 F6 40 1D 46 B7 06 04 10 D0 C2 B7 86 +03 10 23 A2 E6 10 23 A4 E6 10 23 A0 F6 10 11 46 +B7 16 03 30 23 AC C6 80 21 46 23 AC C6 80 23 A4 +06 98 23 A6 06 98 93 05 F0 0F 23 A2 B6 80 93 05 +F0 03 23 A4 B6 80 23 A0 F6 80 B7 26 02 30 23 A4 +E6 80 23 A0 F6 80 37 37 02 30 93 06 F0 07 23 22 +D7 80 FD 46 23 24 D7 80 FD 55 B7 06 03 30 23 20 +F7 80 23 A4 B6 64 B7 07 00 D0 23 A6 B6 64 73 90 +07 7F 73 90 17 7F 73 90 27 7F B7 17 00 40 93 87 +07 88 73 A0 47 30 73 20 06 30 82 80 39 71 3A CE +3E CC 7D 57 B7 07 03 30 06 DE 16 DC 1A DA 1E D8 +2A D6 2E D4 32 D2 36 D0 42 CA 46 C8 72 C6 76 C4 +7A C2 7E C0 23 A4 E7 64 23 A6 E7 64 B7 07 02 50 +03 A7 47 5A 8D 47 63 E5 E7 02 F2 50 E2 52 52 53 +C2 53 32 55 A2 55 12 56 82 56 72 47 E2 47 52 48 +C2 48 32 4E A2 4E 12 4F 82 4F 21 61 73 00 20 30 +37 15 02 50 13 05 85 26 EF 00 B0 24 F9 B7 01 00 +73 50 40 7D 73 00 20 30 39 71 3E CC B7 07 02 50 +3A CE 03 A7 47 5A 06 DE 16 DC 1A DA 1E D8 2A D6 +2E D4 32 D2 36 D0 42 CA 46 C8 72 C6 76 C4 7A C2 +7E C0 91 47 63 EE E7 02 B7 07 00 08 FD 17 73 B0 +07 7F 73 B0 17 7F 73 B0 27 7F F2 50 E2 52 52 53 +C2 53 32 55 A2 55 12 56 82 56 72 47 E2 47 52 48 +C2 48 32 4E A2 4E 12 4F 82 4F 21 61 73 00 20 30 +37 15 02 50 13 05 45 29 EF 00 B0 1C 75 BF 01 00 +5D 71 2A DA 13 05 B0 0F 86 C6 96 C4 9A C2 9E C0 +22 DE 26 DC 2E D8 32 D6 36 D4 3A D2 3E D0 42 CE +46 CC 4A CA 72 C8 76 C6 7A C4 7E C2 EF 00 70 17 +F3 24 20 34 37 04 02 50 83 27 44 5A 05 47 63 6C +F7 04 63 C5 04 04 F3 27 F0 7F F3 27 10 34 F3 27 +30 34 05 45 EF 00 F0 14 13 05 C0 0F EF 00 70 14 +72 54 B6 40 A6 42 16 43 86 43 E2 54 52 55 C2 55 +32 56 A2 56 12 57 82 57 72 48 E2 48 52 49 42 4E +B2 4E 22 4F 92 4F 61 61 73 00 20 30 B5 E3 05 45 +EF 00 30 11 7D BF 0D 69 13 09 09 95 A6 85 13 05 +49 32 EF 00 10 14 83 27 44 5A E3 C1 04 FE F3 25 +F0 7F 89 44 63 FB F4 02 13 05 89 35 EF 00 70 12 +F3 25 10 34 83 27 44 5A E3 F3 F4 F8 13 05 49 36 +EF 00 30 11 F3 25 30 34 83 27 44 5A E3 FB F4 F6 +13 05 09 37 EF 00 F0 0F AD B7 F3 27 10 34 85 B7 +0D 65 FD 55 13 05 05 C9 EF 00 B0 0E 49 BF 01 00 +63 6E 74 5F 61 78 69 5F 64 6D 61 5F 6E 6F 74 69 +66 3A 25 78 0A 00 00 00 63 6E 74 5F 61 78 69 5F +64 6D 61 5F 65 72 72 6F 72 3A 25 78 0A 00 00 00 +63 6E 74 5F 61 62 72 5F 6E 6F 74 69 66 3A 25 78 +0A 00 00 00 63 6E 74 5F 61 62 72 5F 65 72 72 6F +72 3A 25 78 0A 00 00 00 63 6E 74 5F 73 68 61 35 +31 32 5F 61 63 63 5F 65 72 72 6F 72 3A 25 78 0A +00 00 00 00 63 6E 74 5F 73 68 61 35 31 32 5F 65 +72 72 6F 72 3A 25 78 0A 00 00 00 00 63 6E 74 5F +6B 76 5F 6E 6F 74 69 66 3A 25 78 0A 00 00 00 00 +63 6E 74 5F 6B 76 5F 65 72 72 6F 72 3A 25 78 0A +00 00 00 00 63 6E 74 5F 68 6D 61 63 5F 65 72 72 +6F 72 3A 25 78 0A 00 00 63 6E 74 5F 65 63 63 5F +65 72 72 6F 72 3A 25 78 0A 00 00 00 63 6E 74 5F +64 6F 65 5F 65 72 72 6F 72 3A 25 78 0A 00 00 00 +63 6E 74 5F 73 68 61 32 35 36 5F 65 72 72 6F 72 +3A 25 78 0A 00 00 00 00 6D 63 61 75 73 65 3A 25 +78 0A 00 00 63 6E 74 5F 73 68 61 35 31 32 5F 61 +63 63 5F 6E 6F 74 69 66 3A 25 78 0A 00 00 00 00 +62 61 64 20 73 68 61 35 31 32 5F 61 63 63 5F 6E +6F 74 69 66 5F 69 6E 74 72 20 73 74 73 3A 25 78 +0A 00 00 00 63 6E 74 5F 73 6F 63 5F 69 66 63 5F +6E 6F 74 69 66 3A 25 78 0A 00 00 00 62 61 64 20 +73 6F 63 5F 69 66 63 5F 6E 6F 74 69 66 5F 69 6E +74 72 20 73 74 73 3A 25 78 0A 00 00 63 6E 74 5F +73 6F 63 5F 69 66 63 5F 65 72 72 6F 72 3A 25 78 +0A 00 00 00 62 61 64 20 73 6F 63 5F 69 66 63 5F +65 72 72 6F 72 5F 69 6E 74 72 20 73 74 73 3A 25 +78 0A 00 00 63 6E 74 5F 73 68 61 33 5F 6E 6F 74 +69 66 3A 25 78 0A 00 00 62 61 64 20 73 68 61 33 +5F 6E 6F 74 69 66 5F 69 6E 74 72 20 73 74 73 3A +25 78 0A 00 63 6E 74 5F 73 68 61 33 5F 65 72 72 +6F 72 3A 25 78 0A 00 00 62 61 64 20 73 68 61 33 +5F 65 72 72 6F 72 5F 69 6E 74 72 20 73 74 73 3A +25 78 0A 00 63 6E 74 5F 73 68 61 32 35 36 5F 6E +6F 74 69 66 3A 25 78 0A 00 00 00 00 62 61 64 20 +73 68 61 32 35 36 5F 6E 6F 74 69 66 5F 69 6E 74 +72 20 73 74 73 3A 25 78 0A 00 00 00 63 6E 74 5F +73 68 61 35 31 32 5F 6E 6F 74 69 66 3A 25 78 0A +00 00 00 00 62 61 64 20 73 68 61 35 31 32 5F 6E +6F 74 69 66 5F 69 6E 74 72 20 73 74 73 3A 25 78 +0A 00 00 00 63 6E 74 5F 68 6D 61 63 5F 6E 6F 74 +69 66 3A 25 78 0A 00 00 62 61 64 20 68 6D 61 63 +5F 6E 6F 74 69 66 5F 69 6E 74 72 20 73 74 73 3A +25 78 0A 00 63 6E 74 5F 65 63 63 5F 6E 6F 74 69 +66 3A 25 78 0A 00 00 00 62 61 64 20 65 63 63 5F +6E 6F 74 69 66 5F 69 6E 74 72 20 73 74 73 3A 25 +78 0A 00 00 63 6E 74 5F 64 6F 65 5F 6E 6F 74 69 +66 3A 25 78 0A 00 00 00 62 61 64 20 64 6F 65 5F +6E 6F 74 69 66 5F 69 6E 74 72 20 73 74 73 3A 25 +78 0A 00 00 49 6E 3A 53 74 64 20 45 78 63 70 74 +6E 0A 6D 63 61 75 73 65 3A 25 78 0A 00 00 00 00 +55 6E 65 78 70 65 63 74 65 64 20 49 6E 74 72 20 +62 69 74 3A 25 78 0A 00 6D 73 63 61 75 73 65 3A +25 78 0A 00 6D 65 70 63 3A 25 78 0A 00 00 00 00 +6D 74 76 61 6C 3A 25 78 0A 00 00 00 03 47 05 00 +63 0E 07 4E B7 0E 02 50 03 AE 0E 5A 39 71 37 0F +02 50 22 DE AA 87 26 DC 4A DA 4E D8 52 D6 56 D4 +5A D2 5E D0 01 45 93 08 50 02 13 06 00 03 93 03 +D0 02 93 02 A0 02 93 0F 00 02 13 0F 8F 5A 25 44 +63 03 17 03 23 20 EE 00 05 05 03 C7 17 00 85 07 +65 FB 72 54 E2 54 52 59 C2 59 32 5A A2 5A 12 5B +82 5B 21 61 82 80 03 C7 17 00 65 D7 85 07 63 0D +17 05 93 04 00 02 63 19 C7 00 03 C7 17 00 85 07 +E3 0D C7 FE 93 04 00 03 63 05 77 02 63 08 57 02 +13 03 07 FD 93 76 F3 0F 01 48 63 7A D4 02 13 07 +87 FA 13 77 F7 0F E3 E2 EF FA 0A 07 7A 97 18 43 +02 87 03 C7 17 00 85 07 E3 1C 57 FC 03 C7 17 00 +91 05 85 07 01 48 E1 BF 23 20 1E 01 BD BF 25 49 +03 C7 17 00 93 16 28 00 C2 96 86 06 33 08 D3 00 +13 03 07 FD 93 76 F3 0F 85 07 E3 73 D9 FE 45 BF +98 41 83 A6 0E 5A 91 05 13 58 C7 01 63 12 08 14 +13 58 87 01 63 15 08 20 13 58 47 01 63 08 08 34 +19 43 B1 AA 03 A3 05 00 81 46 91 05 13 09 C1 00 +A9 49 A5 4B 33 77 33 03 36 8B 85 06 B3 0A D9 00 +1A 8A 13 07 07 03 A3 8F EA FE 33 53 33 03 E3 E3 +4B FF 83 A9 0E 5A 33 07 69 01 36 83 63 D7 06 01 +23 A0 99 00 05 03 E3 1D 68 FE 13 03 B1 00 03 48 +07 00 7D 17 23 A0 09 01 E3 1B 67 FE 36 95 F1 BD +03 A3 05 00 91 05 83 46 03 00 E3 88 06 EC 03 A8 +0E 5A 1A 87 05 07 23 20 D8 00 83 46 07 00 FD FA +2A 97 33 05 67 40 55 BD 98 41 91 05 13 58 E7 01 +63 16 08 18 13 58 B7 01 63 1A 08 26 13 58 87 01 +63 0E 08 28 83 A6 0E 5A A5 44 61 AA 83 AB 05 00 +83 AA 0E 5A 91 05 5E 83 63 D9 0B 00 13 07 D0 02 +33 03 70 41 23 A0 EA 00 7D 18 81 46 13 09 C1 00 +A9 49 33 67 33 03 36 8B 85 06 33 0A D9 00 33 43 +33 03 13 07 07 03 A3 0F EA FE E3 14 03 FE 33 07 +69 01 36 83 63 D7 06 01 23 A0 9A 00 05 03 E3 1D +03 FF 13 03 B1 00 03 48 07 00 7D 17 23 A0 0A 01 +E3 1B 67 FE E3 D4 0B F4 93 06 2B 00 36 95 31 BD +83 C6 05 00 03 A7 0E 5A 05 05 91 05 14 C3 31 B5 +93 74 F8 0F 25 49 13 83 04 03 63 6B 09 1B 13 58 +87 01 23 A0 66 00 13 78 F8 00 21 43 93 04 00 03 +63 18 08 0A 13 58 47 01 84 C2 13 78 F8 00 25 49 +93 74 F8 0F 63 71 09 19 93 84 74 03 93 F4 F4 0F +13 58 07 01 84 C2 13 78 F8 00 25 49 93 74 F8 0F +63 6F 09 19 93 84 04 03 93 F4 F4 0F 13 58 C7 00 +84 C2 13 78 F8 00 25 49 93 74 F8 0F 63 6B 09 19 +93 84 04 03 93 F4 F4 0F 13 58 87 00 84 C2 13 78 +F8 00 25 49 93 74 F8 0F 63 68 09 17 93 84 04 03 +93 F4 F4 0F 13 58 47 00 84 C2 13 78 F8 00 25 49 +93 74 F8 0F 63 60 09 15 13 88 04 03 13 78 F8 0F +23 A0 06 01 93 74 F7 00 25 49 13 88 04 03 63 54 +99 00 13 88 74 03 23 A0 06 01 1A 95 3D BB 1D 43 +93 04 78 03 25 49 93 79 F8 0F 93 F4 F4 0F E3 63 +09 F5 93 89 09 03 93 F4 F9 0F 2D BF 83 A6 0E 5A +13 03 08 03 13 58 B7 01 23 A0 66 00 13 78 78 00 +AD 44 13 03 08 03 13 58 87 01 23 A0 66 00 13 78 +78 00 13 08 08 03 13 73 F8 0F 13 58 57 01 23 A0 +66 00 13 78 78 00 13 08 08 03 13 73 F8 0F 13 58 +27 01 23 A0 66 00 13 78 78 00 13 08 08 03 13 73 +F8 0F 13 58 F7 00 23 A0 66 00 13 78 78 00 13 08 +08 03 13 73 F8 0F 13 58 C7 00 23 A0 66 00 13 78 +78 00 13 08 08 03 13 73 F8 0F 13 58 97 00 23 A0 +66 00 13 78 78 00 13 08 08 03 13 73 F8 0F 13 58 +67 00 23 A0 66 00 13 78 78 00 13 08 08 03 13 73 +F8 0F 13 58 37 00 23 A0 66 00 13 78 78 00 13 08 +08 03 13 78 F8 0F 23 A0 06 01 1D 8B 13 07 07 03 +98 C2 26 95 99 B9 93 84 04 03 93 F4 F4 0F 49 B5 +13 83 74 03 13 58 87 01 23 A0 66 00 13 78 F8 00 +21 43 93 04 00 03 E3 07 08 E4 DD BD 83 A6 0E 5A +A9 44 05 B7 13 88 74 03 13 78 F8 0F D1 B5 93 84 +74 03 93 F4 F4 0F 9D B5 93 84 74 03 93 F4 F4 0F +51 BD 93 84 74 03 93 F4 F4 0F BD B5 13 58 57 01 +63 0C 08 00 83 A6 0E 5A A1 44 31 B7 13 58 07 01 +63 0C 08 00 15 43 15 B5 13 58 27 01 63 0C 08 00 +83 A6 0E 5A 9D 44 11 B7 13 58 C7 00 63 0C 08 00 +11 43 15 B5 13 58 F7 00 63 0C 08 00 83 A6 0E 5A +99 44 F5 BD 13 58 87 00 63 0C 08 00 0D 43 15 B5 +13 58 C7 00 63 0D 08 00 83 A6 0E 5A 95 44 D5 BD +13 58 47 00 05 43 E3 0F 08 E2 09 43 0D B5 13 58 +97 00 63 06 08 00 83 A6 0E 5A 91 44 ED B5 13 58 +67 00 63 06 08 00 83 A6 0E 5A 8D 44 FD B5 13 58 +37 00 63 06 08 00 83 A6 0E 5A 89 44 CD BD 1D 8B +E3 0D 07 B4 83 A6 0E 5A 85 44 CD BD 01 45 82 80 +39 71 13 03 41 02 2E D2 9A 85 06 CE 32 D4 36 D6 +3A D8 3E DA 42 DC 46 DE 1A C6 CD 34 F2 40 21 61 +82 80 B7 07 02 50 83 A7 07 5A 13 75 F5 0F 88 C3 +82 80 B7 07 02 50 83 A7 07 5A 13 75 F5 0F 88 C3 +82 80 83 47 05 00 37 07 02 50 03 27 07 5A 91 C7 +05 05 1C C3 83 47 05 00 E5 FF A9 47 1C C3 05 45 +82 80 39 71 13 03 41 02 2E D2 9A 85 06 CE 32 D4 +36 D6 3A D8 3E DA 42 DC 46 DE 1A C6 41 34 F2 40 +21 61 82 80 F3 25 00 B8 73 25 00 B0 F3 27 00 B8 +E3 9A F5 FE 82 80 00 00 85 47 63 13 F6 02 93 96 +85 01 93 D7 85 01 D5 8F C1 66 13 D7 85 00 93 86 +06 F0 75 8F D9 8F A2 05 37 07 FF 00 F9 8D DD 8D +0C C1 82 80 01 11 22 CC 26 CA 4A C8 4E C6 52 C4 +06 CE B7 04 02 50 2A 89 2E 8A B2 89 EF D0 F0 25 +03 A7 44 5A 91 47 2A 84 63 EE E7 28 93 77 14 00 +63 99 07 26 13 5F 34 40 93 57 14 40 23 A0 F9 00 +CA 86 D2 8E 93 0F 1F 00 01 4E 25 48 89 45 0D 45 +91 42 95 48 99 43 21 49 85 49 63 0C CF 1F 83 C7 +06 00 13 87 07 FD 13 76 F7 0F 63 6D C8 1A 12 07 +21 46 83 C7 16 00 13 83 07 FD 13 7A F3 0F 63 70 +48 03 13 83 F7 F9 13 73 F3 0F 63 F5 68 1E 13 83 +F7 FB 13 73 F3 0F 63 E6 68 16 13 83 97 FC 33 67 +67 00 63 01 B6 14 83 C7 26 00 13 83 07 FD 13 7A +F3 0F 63 70 48 03 13 83 F7 F9 13 73 F3 0F 63 FE +68 1A 13 83 F7 FB 13 73 F3 0F 63 EC 68 12 13 83 +97 FC 32 03 33 67 67 00 63 06 A6 10 83 C7 36 00 +13 83 07 FD 13 7A F3 0F 63 70 48 03 13 83 F7 F9 +13 73 F3 0F 63 F6 68 18 13 83 F7 FB 13 73 F3 0F +63 E1 68 10 13 83 97 FC 22 03 33 67 67 00 63 0B +56 0C 83 C7 46 00 13 83 07 FD 13 7A F3 0F 63 70 +48 03 13 83 F7 F9 13 73 F3 0F 63 FE 68 14 13 83 +F7 FB 13 73 F3 0F 63 E6 68 0C 13 83 97 FC 52 03 +33 67 67 00 63 00 16 0B 83 C7 56 00 13 83 07 FD +13 7A F3 0F 63 70 48 03 13 83 F7 F9 13 73 F3 0F +63 F6 68 12 13 83 F7 FB 13 73 F3 0F 63 EB 68 08 +13 83 97 FC 42 03 33 67 67 00 63 05 76 06 83 C7 +66 00 13 83 07 FD 13 7A F3 0F 63 70 48 03 13 83 +F7 F9 13 73 F3 0F 63 FE 68 0E 13 83 F7 FB 13 73 +F3 0F 63 E0 68 06 13 83 97 FC 72 03 33 67 67 00 +63 1A 26 03 83 C7 76 00 13 86 07 FD 13 73 F6 0F +63 70 68 02 13 86 F7 F9 13 76 F6 0F 63 F6 C8 0C +13 86 F7 FB 13 76 F6 0F 63 E5 C8 02 13 86 97 FC +62 06 51 8F 23 A0 EE 00 05 0E 91 0E A1 06 E3 16 +FE E7 F2 40 62 44 D2 44 42 49 B2 49 22 4A 05 61 +82 80 83 A6 44 5A 11 47 E3 75 D7 FE 62 44 F2 40 +D2 44 42 49 B2 49 22 4A 15 65 BE 85 13 05 85 43 +05 61 41 B3 21 46 13 87 F7 F9 13 77 F7 0F 63 FF +E8 00 13 87 F7 FB 13 77 F7 0F E3 E4 E8 FC 93 87 +97 FC 13 97 47 00 E3 16 36 E3 69 BF 93 87 97 FA +CD BF 13 76 74 00 49 DA 83 C7 06 00 25 43 13 87 +07 FD 13 7A F7 0F E3 60 43 FD 85 47 12 07 E3 12 +F6 E0 8D BF 13 83 97 FA 1D B5 13 83 97 FA 91 BD +13 83 97 FA 51 B5 13 83 97 FA 55 BD 13 83 97 FA +D5 B5 13 83 97 FA 11 BF 13 86 97 FA 62 06 51 8F +91 B7 03 A7 44 5A 91 47 E3 F5 E7 F4 62 44 F2 40 +D2 44 42 49 B2 49 22 4A 37 15 02 50 13 05 85 2A +05 61 C1 B1 AA 85 15 65 13 05 05 42 D9 39 B9 BB +79 71 22 D4 26 D2 4A D0 4E CE 52 CC 56 CA 06 D6 +5A C8 5E C6 B7 09 02 50 2A 8A AE 8A 32 84 B6 84 +EF D0 A0 78 03 A7 49 5A 89 47 2A 89 63 E8 E7 2E +93 77 19 00 63 91 07 2C 13 5F 39 40 93 57 19 40 +56 86 52 88 D6 85 1C C0 93 02 1F 00 81 46 25 43 +09 45 8D 4F 91 43 15 4E 19 4A A1 4A 05 4B 63 02 +DF 24 83 47 08 00 13 87 07 FD 93 78 F7 0F 63 63 +13 21 12 07 A1 48 83 47 18 00 93 8E 07 FD 93 FB +FE 0F 63 70 73 03 93 8E F7 F9 93 FE FE 0F 63 7C +DE 23 93 8E F7 FB 93 FE FE 0F 63 6A DE 1B 93 8E +97 FC 33 67 D7 01 63 82 A8 14 83 47 28 00 93 8E +07 FD 93 FB FE 0F 63 70 73 03 93 8E F7 F9 93 FE +FE 0F 63 75 DE 21 93 8E F7 FB 93 FE FE 0F 63 60 +DE 19 93 8E 97 FC B2 0E 33 67 D7 01 63 87 F8 11 +83 47 38 00 93 8E 07 FD 93 FB FE 0F 63 70 73 03 +93 8E F7 F9 93 FE FE 0F 63 7D DE 1D 93 8E F7 FB +93 FE FE 0F 63 65 DE 15 93 8E 97 FC A2 0E 33 67 +D7 01 63 8C 78 0C 83 47 48 00 93 8E 07 FD 93 FB +FE 0F 63 70 73 03 93 8E F7 F9 93 FE FE 0F 63 75 +DE 1B 93 8E F7 FB 93 FE FE 0F 63 6A DE 11 93 8E +97 FC D2 0E 33 67 D7 01 63 81 C8 0B 83 47 58 00 +93 8E 07 FD 93 FB FE 0F 63 70 73 03 93 8E F7 F9 +93 FE FE 0F 63 7D DE 17 93 8E F7 FB 93 FE FE 0F +63 6F DE 0D 93 8E 97 FC C2 0E 33 67 D7 01 63 86 +48 07 83 47 68 00 93 8E 07 FD 93 FB FE 0F 63 70 +73 03 93 8E F7 F9 93 FE FE 0F 63 75 DE 15 93 8E +F7 FB 93 FE FE 0F 63 64 DE 0B 93 8E 97 FC F2 0E +33 67 D7 01 63 9B 58 03 83 47 78 00 93 88 07 FD +93 FE F8 0F 63 70 D3 03 93 88 F7 F9 93 F8 F8 0F +63 7D 1E 11 93 88 F7 FB 93 F8 F8 0F 63 69 1E 07 +93 88 97 FC E2 08 33 67 17 01 98 C1 85 06 91 05 +21 08 E3 96 56 E6 85 47 63 90 F4 04 1C 40 8D CF +41 68 81 45 13 08 08 F0 B7 08 FF 00 1C 42 11 06 +85 05 13 D7 87 01 13 95 87 01 93 D6 87 00 49 8F +B3 F6 06 01 A2 07 55 8F B3 F7 17 01 D9 8F 23 2E +F6 FE 1C 40 E3 EC F5 FC B2 50 22 54 92 54 02 59 +F2 49 62 4A D2 4A 42 4B B2 4B 45 61 82 80 03 A7 +49 5A 7D D3 22 54 B2 50 92 54 02 59 F2 49 62 4A +D2 4A 42 4B B2 4B 15 65 BE 85 13 05 45 47 45 61 +6F F0 3F A6 A1 48 13 87 F7 F9 13 77 F7 0F 63 7F +EE 00 13 87 F7 FB 13 77 F7 0F E3 62 EE FC 93 87 +97 FC 13 97 47 00 E3 90 68 DF 81 BF 93 87 97 FA +CD BF 93 78 79 00 E3 83 08 F4 83 47 08 00 A5 4E +13 87 07 FD 93 7B F7 0F E3 EF 7E FB 85 47 12 07 +E3 9B F8 DA 1D B7 93 8E 97 FA E1 BB 93 8E 97 FA +19 B5 93 8E 97 FA 1D BD 93 8E 97 FA 9D B5 93 8E +97 FA 59 BD 93 8E 97 FA D9 B5 93 88 97 FA E2 08 +33 67 17 01 DD BD 83 A7 49 5A 9D DF 22 54 B2 50 +92 54 02 59 F2 49 62 4A D2 4A 42 4B B2 4B 37 15 +02 50 13 05 85 2A 45 61 6F F0 BF 99 AA 85 15 65 +13 05 C5 45 EF F0 FF 9A 21 B3 29 CE 85 47 63 8D +F6 00 0A 06 B3 07 C5 00 18 41 11 05 91 05 23 AE +E5 FE E3 9B A7 FE 82 80 93 16 26 00 C1 68 AA 96 +93 88 08 F0 37 03 FF 00 1C 41 91 05 11 05 13 D7 +87 01 13 98 87 01 13 D6 87 00 33 67 07 01 33 76 +16 01 A2 07 51 8F B3 F7 67 00 D9 8F 23 AE F5 FE +E3 1C D5 FC 82 80 37 17 01 10 83 27 47 08 85 8B +ED DF 82 80 31 71 22 DD 26 DB 80 01 4A D9 4E D7 +52 D5 56 D3 5A D1 62 CD 66 CB 06 DF 5E CF 6A C9 +6E C7 36 8C 03 43 2C 00 B4 4A 83 24 CC 05 23 2A +64 F8 03 43 3C 00 83 47 0C 00 93 F8 F4 00 23 24 +64 F8 03 43 4C 04 13 F8 F6 00 23 26 94 F6 23 20 +64 F8 03 23 4C 05 23 22 F4 FA 23 20 14 FB 23 2C +64 F8 03 23 8C 05 23 22 D4 F8 23 28 04 F9 83 4D +5C 04 23 26 64 F8 03 23 4C 06 93 F7 C6 FF BD 07 +23 24 64 F6 03 23 0C 07 C1 9B 33 01 F1 40 23 2C +64 F6 03 23 4C 07 03 2B 0C 06 03 4A 8C 06 23 2A +64 F6 03 23 8C 07 93 DC 44 00 93 D9 46 00 23 28 +64 F6 03 23 CC 07 B3 38 10 01 1C 08 23 22 64 F6 +03 43 0C 08 23 26 E4 FA 2A 89 23 24 64 FA 33 33 +00 01 AE 8A B2 84 9A 99 C6 9C 23 2E F4 F8 37 17 +01 10 83 27 47 08 85 8B ED DF 83 26 C4 FA 37 0D +02 50 05 47 83 27 4D 5A E3 82 E6 44 09 47 63 67 +F7 50 B7 27 01 10 23 AA 07 92 37 17 01 10 83 2B +47 08 93 FB 1B 00 E3 8C 0B FE 83 27 44 FA 95 CB +03 47 1C 00 1D E7 37 26 01 10 83 27 46 A0 85 8B +ED DF 83 27 84 F8 13 97 17 00 13 77 E7 03 13 67 +17 00 23 20 E6 A0 37 26 01 10 83 27 46 A0 89 8B +ED DF 83 27 44 FA A2 04 13 77 39 00 13 96 B7 00 +93 F4 04 70 83 27 04 F8 D9 8C 13 97 2A 00 D1 8C +13 77 F7 0F D9 8C E3 9D 07 3C 83 28 4D 5A 09 47 +63 6E 17 29 37 17 01 10 83 27 44 F9 64 DB 64 DB +89 EB 83 27 84 F8 63 89 07 46 37 27 01 10 23 20 +77 A1 93 07 00 02 63 8E FA 24 37 17 01 10 83 27 +47 08 85 8B ED DF 83 27 44 FA A5 EB 89 47 63 F4 +17 01 6F 00 B0 71 03 27 4C 00 B7 17 01 10 D8 C3 +03 27 4C 02 D8 D3 03 27 8C 00 98 C7 03 27 8C 02 +98 D7 03 27 CC 00 D8 C7 03 27 CC 02 D8 D7 03 27 +0C 01 98 CB 03 27 0C 03 98 DB 03 27 4C 01 D8 CB +03 27 4C 03 D8 DB 03 27 8C 01 98 CF 03 27 8C 03 +98 DF 03 27 CC 01 D8 CF 03 27 CC 03 D8 DF 03 27 +0C 02 98 D3 03 27 0C 04 B8 C3 B7 17 01 10 83 A6 +47 08 85 8A ED DE 89 47 E3 E2 17 35 03 27 CC 04 +B7 17 01 10 13 06 00 02 0C 43 EC C3 4C 43 AC C7 +0C 47 EC C7 58 47 B8 CB E3 80 CA 20 83 27 44 F8 +63 8B 07 14 83 2C CC 06 85 47 E3 8B FC 5E 63 8D +09 08 95 6C 93 87 0C 42 23 20 F4 FA 83 27 04 F9 +83 2D 04 F8 81 4B FD 17 23 22 F4 F6 83 27 C4 F8 +23 2C 84 F7 23 26 04 F8 13 8B C7 00 83 27 84 F9 +5E 8C 23 20 D4 F6 93 8C C7 00 C1 67 93 87 07 F0 +23 2E F4 F8 85 67 93 87 07 80 DA 8B 23 2C F4 F8 +66 8B 93 07 00 02 63 84 FA 16 37 17 01 10 83 27 +47 08 C1 8B ED DF 63 15 0A 18 89 47 63 EF 17 37 +05 47 63 00 E9 34 63 09 F9 18 63 88 0D 1E 03 27 +4D 5A 63 00 0C 58 05 0C 83 28 4D 5A C1 0B 41 0B +E3 11 3C FD 03 2C 84 F7 83 27 04 F8 CD C7 83 27 +44 F9 D5 E3 89 47 63 F4 17 01 6F 10 A0 0C 37 27 +01 10 83 27 C7 A0 89 8B ED DF 89 44 03 49 6C 04 +63 F4 14 01 6F 10 40 0C 85 47 63 14 F9 00 6F 10 +60 31 37 25 01 10 13 05 C5 A0 EF 90 60 53 95 A0 +83 27 84 FA 03 2B 04 F7 83 25 44 F7 13 85 F7 FF +13 35 15 00 CE 87 83 29 44 F6 2A C4 5E C2 66 C0 +A6 88 83 24 44 F8 03 25 84 F7 52 86 DA 86 4E 87 +26 88 EF B0 F0 7C 83 26 C4 F9 13 DA 24 00 81 47 +26 87 01 46 5A 85 CE 85 EF B0 D0 07 63 0B 0A 00 +83 27 84 FA 63 14 99 01 6F 10 E0 18 99 E3 6F 10 +60 2E 83 28 4D 5A 37 17 01 10 83 27 47 08 85 8B +ED DF 93 07 00 02 E3 85 FA 28 89 47 E3 E9 17 41 +B7 17 01 10 21 67 F8 DB F8 DB 19 47 23 A0 E7 08 +13 01 04 F4 FA 50 6A 54 DA 54 4A 59 BA 59 2A 5A +9A 5A 0A 5B FA 4B 6A 4C DA 4C 4A 4D BA 4D 29 61 +82 80 37 17 01 10 83 27 47 08 85 8B ED DF 93 07 +10 40 23 24 F7 08 23 24 F7 08 41 BB 95 68 13 85 +88 4B A6 85 EF F0 EF D1 83 28 4D 5A A1 BB 93 87 +F9 FF 63 03 0C 6C E3 1A FC E8 83 27 04 F9 E3 86 +07 E8 93 95 67 00 93 E5 85 00 37 17 01 10 83 27 +47 08 85 8B ED DF 23 24 B7 08 23 24 B7 08 B5 B5 +64 5B 03 27 84 F9 89 47 B9 8C 63 E8 17 1F 05 47 +63 09 E9 1A 63 12 F9 04 03 27 4D 5A 91 4C 63 E0 +EC 20 83 26 C4 FA 85 45 83 A7 4B FF 63 8A B6 5C +37 17 01 10 7C CB 03 A7 8B FF B7 17 01 10 B8 CF +03 A7 CB FF B7 17 01 10 F8 CF 83 A7 0B 00 37 17 +01 10 3C D3 E3 0B 0A E2 B7 17 01 10 03 27 4D 5A +E4 DB E4 DB 89 47 E3 F2 E7 E2 B7 17 02 50 13 85 +47 3D EF F0 0F C5 E3 9C 0D E0 37 17 01 10 83 27 +47 08 A1 8B ED DF B7 07 03 30 83 A7 C7 54 85 8B +95 CB 83 27 84 F7 83 26 44 FA 23 80 D7 00 83 26 +44 F9 23 81 D7 00 83 26 84 F8 A3 81 D7 00 8C 43 +B7 07 00 FF 93 87 F7 0F FD 8D B7 07 00 10 85 07 +63 89 F5 62 37 17 01 10 83 27 47 08 91 8B 99 C7 +83 27 84 FA 99 E3 6F 10 20 05 81 47 37 17 01 10 +83 25 4D 5A 83 2C 47 06 0D 47 63 67 B7 4A 03 27 +C4 F8 93 08 F7 FF 13 87 F9 FF 46 8F 63 0E 87 21 +63 93 07 24 85 45 63 03 B9 5A 89 45 E3 0F B9 08 +B7 15 01 10 03 25 4D 5A 83 AC 85 06 8D 45 63 E9 +A5 48 FA 8F 63 04 87 1B 63 9D 07 1C 85 45 63 00 +B9 5A 89 45 E3 02 B9 00 B7 15 01 10 03 25 4D 5A +83 AC C5 06 8D 45 63 E9 A5 48 FE 88 63 01 87 25 +63 98 07 26 85 45 63 0B B9 5A 89 45 E3 08 B9 06 +B7 15 01 10 03 25 4D 5A 83 AC 05 07 8D 45 63 E9 +A5 12 63 02 87 27 63 93 07 28 85 47 63 02 F9 60 +89 47 E3 1A F9 D0 83 27 84 FA E3 96 07 D0 83 27 +0B 00 5A 87 B3 C7 FC 00 B3 F7 17 01 E3 8D 07 CE +E6 87 8D 45 6F 00 60 7B 8D 4B 41 BE 37 15 02 50 +13 05 05 30 EF F0 EF B0 B7 27 01 10 23 AA 07 92 +ED B4 03 27 4D 5A 91 4C 63 E6 EC 34 83 26 C4 FA +85 45 83 27 4B FF 63 83 B6 28 37 17 01 10 7C CB +03 27 8B FF B7 17 01 10 B8 CF 03 27 CB FF B7 17 +01 10 F8 CF 83 27 0B 00 99 BD 83 27 04 FA E2 85 +13 85 C7 21 EF F0 EF AD 85 47 E3 0C F9 FA 89 47 +E3 12 F9 E4 03 27 4D 5A 91 4C E3 F4 EC E0 83 27 +04 FA 83 A5 4B FF 93 87 C7 23 3E 85 23 2E F4 F6 +EF F0 2F AB 83 26 C4 FA 85 45 03 27 4D 5A 83 A7 +4B FF 63 8F B6 3A 37 13 01 10 23 2A F3 04 E3 F4 +EC DE 83 A5 8B FF 03 25 C4 F7 EF F0 8F A8 03 A7 +8B FF 83 27 4D 5A 37 13 01 10 23 2C E3 04 E3 F9 +FC DC 83 A5 CB FF 03 25 C4 F7 EF F0 8F A6 03 27 +4D 5A 83 A7 CB FF B7 15 01 10 FC CD 91 47 E3 FE +E7 DA 83 A5 0B 00 03 25 C4 F7 EF F0 8F A4 75 B3 +23 2A F4 F6 83 27 04 FA E6 85 23 28 14 F7 13 85 +C7 29 23 2E E4 F6 EF F0 CF A2 03 27 C4 F7 83 28 +04 F7 83 27 44 F7 E3 18 87 EB 31 A2 83 26 04 F9 +E3 8C 06 E4 83 26 44 F8 93 F5 C6 00 E3 86 05 E4 +93 FF 86 00 E3 9B 0F 3E 93 F5 36 00 83 26 04 F6 +8E 05 05 4F 33 1F BF 00 23 26 D4 F8 7D 1F E3 87 +07 E2 83 26 84 FA E3 99 06 E2 B3 FC EC 01 E3 85 +0C E2 E6 87 85 45 91 A0 83 26 04 F9 E3 82 06 DE +83 26 44 F8 13 FF C6 00 E3 14 0F 16 93 F5 36 00 +83 26 04 F6 8E 05 85 48 B3 98 B8 00 23 26 D4 F8 +FD 18 E3 81 07 DC 83 26 84 FA E3 93 06 DC B3 FC +1C 01 E3 8F 0C DA E6 87 81 45 95 64 93 84 04 42 +13 85 04 2B 23 26 F4 FA EF F0 AF 97 83 27 C4 FA +13 85 84 2D BE 85 EF F0 CF 96 37 15 02 50 13 05 +45 45 EF F0 0F 94 05 45 EF F0 AF 91 01 A0 83 26 +44 F6 A9 45 E3 EE D5 DA 83 26 44 F8 93 F5 86 00 +E3 88 05 DA 93 F5 36 00 83 26 04 F6 8E 05 85 4F +B3 9F BF 00 23 26 D4 F8 FD 1F 81 48 E3 8C 07 D8 +83 26 84 FA E3 9E 06 D8 B3 FC FC 01 E3 8A 0C D8 +E6 87 89 45 59 B7 83 26 04 F9 2D 47 E3 7D D7 D8 +03 27 44 F8 85 48 0D 8B 0E 07 B3 98 E8 00 03 27 +04 F6 FD 18 23 26 E4 F8 E3 81 07 D8 83 27 84 FA +E3 9B 07 A8 B3 FC 1C 01 E3 87 0C A8 E6 87 8D 45 +A9 B7 83 27 44 FA E3 80 07 A8 89 47 63 E7 E7 02 +B7 25 01 10 83 A7 45 A0 89 8B ED DF 83 26 44 F9 +85 47 E3 8E F6 50 89 47 63 EC E7 7A 37 25 01 10 +13 05 45 A0 EF 80 D0 7D B9 B4 37 15 02 50 13 05 +85 46 EF F0 0F 87 03 27 4D 5A D9 B7 83 26 C4 F9 +93 D5 87 01 93 98 87 01 13 D5 87 00 75 8D B3 E5 +15 01 C9 8D A2 07 37 05 FF 00 E9 8F CD 8F B7 15 +01 10 FC C9 91 47 63 ED E7 34 83 27 8B FF 83 26 +C4 F9 93 D5 87 01 93 98 87 01 13 D5 87 00 75 8D +B3 E5 15 01 C9 8D A2 07 37 05 FF 00 E9 8F CD 8F +B7 15 01 10 BC CD 91 47 63 E3 E7 30 83 27 CB FF +83 26 C4 F9 93 D5 87 01 93 98 87 01 13 D5 87 00 +75 8D B3 E5 15 01 C9 8D A2 07 37 05 FF 00 E9 8F +CD 8F B7 15 01 10 FC CD 91 47 63 EB E7 2A 83 27 +0B 00 83 26 C4 F9 13 D7 87 01 13 95 87 01 93 D5 +87 00 F5 8D 49 8F 4D 8F A2 07 B7 05 FF 00 ED 8F +D9 8F 35 BE 83 25 4B FF 95 67 13 85 47 67 EF E0 +5F FC 83 26 C4 FA 85 45 03 27 4D 5A 83 27 4B FF +E3 86 B6 F2 B7 18 01 10 23 AA F8 04 E3 F2 EC CA +83 25 8B FF 95 67 13 85 47 67 EF E0 9F F9 03 27 +8B FF 83 27 4D 5A B7 18 01 10 23 AC E8 04 E3 F6 +FC C8 83 25 CB FF 95 67 13 85 47 67 EF E0 7F F7 +03 27 4D 5A 83 27 CB FF B7 15 01 10 FC CD 91 47 +E3 FA E7 C6 83 25 0B 00 95 67 13 85 47 67 EF E0 +5F F5 83 27 0B 00 65 BC 23 2E F4 F6 83 27 04 FA +E6 85 13 85 C7 29 EF E0 DF F3 83 27 C4 F7 81 B6 +23 2A F4 F6 83 27 04 FA E6 85 23 28 E4 F7 13 85 +C7 29 23 2E E4 F6 EF E0 DF F1 03 2F 04 F7 83 27 +44 F7 03 27 C4 F7 B1 B6 23 2A F4 F6 83 27 04 FA +E6 85 23 28 F4 F7 13 85 C7 29 23 2E E4 F6 EF E0 +5F EF 83 2F 04 F7 83 27 44 F7 03 27 C4 F7 B1 B6 +83 26 C4 F9 93 D5 87 01 93 98 87 01 13 D5 87 00 +75 8D B3 E5 15 01 C9 8D A2 07 37 05 FF 00 E9 8F +CD 8F B7 15 01 10 FC C9 91 47 63 E7 E7 5A 83 A7 +8B FF 83 26 C4 F9 93 D5 87 01 93 98 87 01 13 D5 +87 00 75 8D B3 E5 15 01 C9 8D A2 07 37 05 FF 00 +E9 8F CD 8F B7 15 01 10 BC CD 91 47 63 E9 E7 54 +83 A7 CB FF 83 26 C4 F9 93 D5 87 01 93 98 87 01 +13 D5 87 00 75 8D B3 E5 15 01 C9 8D A2 07 37 05 +FF 00 E9 8F CD 8F B7 15 01 10 FC CD 91 47 63 E0 +E7 50 83 A7 0B 00 B1 BD 85 47 93 05 80 40 E3 96 +F9 94 83 27 04 F9 E3 82 07 94 25 BA 83 26 84 FA +E3 90 06 A6 83 A5 4B FF B3 C5 BC 00 B3 F5 15 01 +E3 88 05 A4 E6 87 93 82 4B FF 81 45 8D A0 83 26 +84 FA E3 93 06 A6 83 A5 8B FF B3 C5 BC 00 B3 F5 +E5 01 E3 8B 05 A4 E6 87 93 82 8B FF FA 88 85 45 +3D A8 85 47 E3 98 FA 9C 83 27 47 08 91 8B 89 E7 +83 27 84 FA E3 88 07 3E 85 47 C9 BA 83 26 84 FA +E3 98 06 A4 83 A5 CB FF B3 C5 BC 00 B3 F5 F5 01 +E3 80 05 A4 E6 87 93 82 CB FF FE 88 89 45 95 64 +93 84 04 42 13 85 04 2F 23 24 54 FA 23 22 14 FB +23 26 F4 FA EF E0 FF D9 83 27 C4 FA 83 28 44 FA +13 85 84 31 B3 F5 F8 00 23 26 14 FB EF E0 7F D8 +83 22 84 FA 83 28 C4 FA 13 85 04 33 83 A5 02 00 +B3 F5 B8 00 EF E0 FF D6 05 45 EF E0 9F D2 01 A0 +83 27 84 FA 63 99 07 F0 83 A7 0B 00 DE 82 B3 C7 +FC 00 B3 F7 17 01 63 80 07 F0 E6 87 8D 45 41 BF +83 25 0B 00 95 67 13 85 47 67 EF E0 9F D3 83 26 +C4 FA 05 47 83 27 0B 00 E3 8D E6 D2 49 B8 83 25 +CB FF 95 67 13 85 47 67 EF E0 BF D1 83 26 C4 FA +85 45 03 27 4D 5A 83 27 CB FF E3 83 B6 CE 69 BB +83 25 8B FF 95 67 13 85 47 67 EF E0 9F CF 03 27 +4D 5A 83 27 8B FF 61 B9 83 27 C4 F6 63 80 07 E0 +63 8E 0C DE 03 27 04 FA 93 DF 27 00 85 47 BA 9F +5A 8F 63 8B FC 72 13 06 40 40 C1 45 95 67 93 87 +07 42 23 2E F4 F6 C1 67 0D 4B 93 87 07 F0 23 2E +94 F4 23 2C 34 F5 E6 84 81 4D DA 8C B7 1B 01 10 +56 8B 23 20 F4 F6 CA 8A 23 2A D4 F4 FE 89 7A 89 +83 A7 4B 08 85 8B ED DF 89 47 63 E0 17 67 23 A4 +CB 08 23 A4 CB 08 83 A7 4B 08 C1 8B ED DF 89 47 +63 E5 17 5D 93 97 2D 00 63 E0 37 4F 23 AA 0B 04 +93 87 EC FF 63 E4 37 43 23 AC 0B 04 93 87 FC FF +63 F9 37 57 03 27 C4 FA 85 46 83 27 89 00 63 0A +D7 5C 23 AE FB 04 63 FC 3C 45 83 27 C9 00 23 A0 +FB 06 85 0D 41 09 91 0C 63 8A B4 45 93 87 F4 FF +63 8C B7 5D 89 47 E3 F0 17 FB B7 17 02 50 13 85 +07 35 EF E0 1F BF 83 28 4D 5A 71 B7 09 47 63 67 +F7 5C B7 27 01 10 05 47 23 AA E7 92 6F F0 EF BB +03 26 8C 04 37 25 01 10 EE 85 13 05 85 A0 EF 80 +50 40 83 28 4D 5A 09 47 63 7E 17 C1 95 68 EE 85 +13 85 88 49 EF E0 FF BC 6F F0 2F C0 37 15 02 50 +13 05 05 34 23 2E D4 F6 EF E0 BF B9 83 28 4D 5A +83 26 C4 F7 6F F0 8F CA 83 26 84 FA 63 9E 06 FE +83 25 8B FF B3 C5 BC 00 B3 F5 E5 01 63 86 05 FE +E6 87 13 07 8B FF FA 88 85 45 95 64 93 84 04 42 +13 85 84 34 23 24 E4 FA 23 22 14 FB 23 26 F4 FA +EF E0 3F B7 83 27 C4 FA 83 28 44 FA 13 85 04 37 +B3 F5 F8 00 23 26 14 FB EF E0 BF B5 03 27 84 FA +83 28 C4 FA 13 85 84 38 0C 43 B3 F5 B8 00 EF E0 +5F B4 05 45 EF E0 FF AF 01 A0 83 26 84 FA 63 91 +06 F6 83 25 4B FF B3 C5 BC 00 B3 F5 15 01 63 89 +05 F4 E6 87 13 07 4B FF 81 45 41 BF 83 26 84 FA +63 98 06 F8 83 25 CB FF B3 C5 BC 00 B3 F5 F5 01 +63 80 05 F8 E6 87 13 07 CB FF FE 88 89 45 B5 B7 +83 27 44 F9 63 9B 07 D6 03 25 C4 F6 B7 05 FF 00 +13 06 00 42 93 16 35 00 93 17 B5 00 ED 8F 13 D9 +86 00 93 D5 86 01 C1 66 23 24 C7 08 CD 8F 93 86 +06 F0 93 15 B5 01 33 79 D9 00 CD 8F 23 24 C7 08 +11 47 33 69 F9 00 63 60 17 69 03 27 C4 FA B7 17 +01 10 23 AA 07 04 85 47 63 15 F7 02 93 16 89 01 +93 57 89 01 D5 8F C1 66 13 57 89 00 93 86 06 F0 +75 8F D9 8F 22 09 37 07 FF 00 33 79 E9 00 33 E9 +27 01 03 26 44 F8 B7 06 FF 00 93 17 36 00 13 17 +B6 00 75 8F 93 D6 87 01 93 D4 87 00 B3 67 D7 00 +41 67 13 07 07 F0 F9 8C 93 16 B6 01 37 17 01 10 +D5 8F 23 2C 27 05 11 47 DD 8C 63 6D 17 5F 03 27 +C4 FA B7 17 01 10 23 AE 07 04 85 47 63 13 F7 02 +93 96 84 01 93 D7 84 01 D5 8F C1 66 13 D7 84 00 +93 86 06 F0 75 8F D9 8F A2 04 37 07 FF 00 F9 8C +DD 8C B7 17 01 10 A4 D3 37 17 01 10 83 27 47 08 +A1 8B ED DF 03 27 C4 FA 85 47 63 0E F7 4E 83 25 +84 F6 41 46 13 05 04 FB 23 26 14 FB EF C0 00 26 +83 28 C4 FA 89 47 63 E8 17 4B 83 27 84 FA 63 90 +07 44 B7 17 01 10 E4 53 83 27 04 FB 63 9F 97 7A +B7 17 01 10 03 27 4D 5A A4 57 8D 47 63 EB E7 68 +83 27 44 FB 63 9A 97 74 37 19 01 10 83 27 4D 5A +83 24 C9 06 0D 4A 63 62 FA 64 83 27 84 FB 95 68 +93 88 08 42 63 91 F4 78 83 24 09 07 83 27 C4 FB +63 96 97 76 83 28 4D 5A 89 47 63 FB 17 BF 37 15 +02 50 13 05 45 53 EF E0 DF 93 6F F0 6F BE 83 A5 +0B 00 15 65 13 05 C5 65 EF E0 BF 94 83 26 C4 FA +05 47 83 A7 0B 00 E3 86 E6 94 6F F0 4F CA 83 A5 +CB FF 15 65 93 07 C5 65 3E 85 23 2E F4 F6 EF E0 +5F 92 83 26 C4 FA 85 45 03 27 4D 5A 83 A7 CB FF +E3 8A B6 A8 6F F0 2F EB 83 A5 8B FF 15 65 13 05 +C5 65 EF E0 1F 90 03 27 4D 5A 83 A7 8B FF 91 B4 +37 15 02 50 13 05 C5 49 EF E0 BF 8C 6F F0 1F 84 +89 44 83 49 1C 08 63 ED 14 2D 63 84 99 31 81 44 +81 49 01 4A 83 47 2C 08 93 8B 0A FE 85 4C 93 BB +1B 00 63 97 97 AD 03 27 4D 5A 89 47 63 EE E7 48 +85 47 3E C0 5E C2 03 27 44 F6 03 28 44 F8 83 26 +04 F7 03 25 84 F7 83 25 44 F7 CE 87 A6 88 52 86 +EF B0 00 38 13 07 40 06 B7 17 01 10 83 A6 47 08 +7D 17 F4 DB F4 DB 7D FB 37 15 02 50 13 05 85 39 +EF E0 3F 85 05 45 EF E0 DF 82 01 A0 37 15 02 50 +13 05 85 32 EF E0 FF 83 83 28 4D 5A 6F F0 AF 8D +46 8F 6F F0 EF C6 63 FB 17 01 83 25 49 00 95 67 +13 85 C7 53 EF E0 FF 83 83 28 4D 5A 03 27 C4 FA +85 46 83 27 49 00 63 05 D7 06 23 AC FB 04 13 86 +FC FF 8D 47 63 6A 36 0D 63 FD 17 13 83 27 C4 F7 +B2 85 13 85 87 0F EF E0 DF 80 83 28 4D 5A 23 AE +0B 04 8D 47 63 E1 3C 0F 63 FB 17 01 83 27 C4 F7 +E6 85 13 85 87 0F EF E0 CF FE 83 28 4D 5A 23 A0 +0B 06 85 0D 41 09 91 0C E3 9A B4 BB 56 89 83 24 +C4 F5 83 29 84 F5 83 26 44 F5 DA 8A 6F F0 0F 8E +03 27 04 F6 93 D6 87 01 93 95 87 01 13 D6 87 00 +79 8E CD 8E D1 8E A2 07 37 06 FF 00 F1 8F D5 8F +AD BF 63 FB 17 01 83 25 09 00 95 67 13 85 C7 53 +EF E0 2F F9 83 28 4D 5A 03 27 C4 FA 85 46 83 27 +09 00 63 0F D7 06 23 AA FB 04 13 86 EC FF 8D 47 +E3 63 36 F3 E3 FA 17 B1 83 27 C4 F7 B2 85 13 85 +87 0F EF E0 0F F6 83 28 4D 5A 13 86 FC FF 23 AC +0B 04 8D 47 E3 7A 36 F3 E3 FE 17 AF 83 25 89 00 +95 67 13 85 C7 53 EF E0 CF F3 03 27 C4 FA 85 46 +83 28 4D 5A 83 27 89 00 63 0D D7 0A 23 AE FB 04 +8D 47 E3 F3 3C F3 63 F2 17 05 83 25 C9 00 95 67 +66 86 13 85 C7 53 EF E0 CF F0 83 28 4D 5A 35 A0 +03 27 04 F6 93 D6 87 01 93 95 87 01 13 D6 87 00 +79 8E CD 8E D1 8E A2 07 37 06 FF 00 F1 8F D5 8F +9D B7 23 AE 0B 04 E3 FC 3C EF 03 27 C4 FA 85 46 +83 27 C9 00 E3 1D D7 A8 03 27 04 F6 93 D6 87 01 +93 95 87 01 13 D6 87 00 79 8E CD 8E D1 8E A2 07 +37 06 FF 00 F1 8F D5 8F 9D BC 83 27 C4 F7 EE 85 +13 85 07 0E EF E0 EF E9 13 96 2D 00 83 28 4D 5A +8D 47 E3 68 36 EF E3 F3 17 A3 83 27 C4 F7 B2 85 +13 85 87 0F EF E0 EF E7 83 28 4D 5A 23 AA 0B 04 +ED BD 03 27 04 F6 93 D6 87 01 93 95 87 01 13 D6 +87 00 79 8E CD 8E D1 8E A2 07 37 06 FF 00 F1 8F +D5 8F 23 AE FB 04 2D B7 83 27 04 FA E3 84 07 A2 +13 96 67 00 BE 85 13 66 46 00 5D B2 37 15 02 50 +13 05 C5 2D EF E0 EF E0 2D B4 15 65 13 05 85 4D +23 28 C4 F4 EF E0 EF E1 03 26 04 F5 83 28 4D 5A +23 A4 CB 08 23 A4 CB 08 F5 B2 FA 8F 6F F0 CF A4 +03 27 04 F7 83 26 44 F6 03 26 84 F7 83 25 44 F7 +95 68 13 85 08 56 EF E0 CF DE E3 9A 99 D1 83 27 +4D 5A 63 F8 F4 00 37 15 02 50 13 05 85 36 EF E0 +4F DB D1 44 EF B0 10 47 13 7A F5 0F EF B0 90 46 +93 79 F5 0F EF B0 10 46 33 77 95 02 B3 67 3A 01 +85 8B D9 8F E5 D3 85 47 13 7A 1A 00 93 F9 19 00 +BA 84 23 24 F4 FA F9 B1 13 06 40 40 C1 45 E3 07 +07 8C 13 16 67 00 BA 85 13 66 46 00 C1 B0 B7 17 +01 10 FC 53 B7 19 01 10 83 27 4D 5A 83 A5 89 06 +0D 49 63 6B F9 1E B7 17 01 10 FC 57 B7 17 01 10 +BC 5B CD BE 37 15 02 50 13 05 45 4B EF E0 6F D3 +83 28 4D 5A 6F E0 BF F2 37 15 02 50 13 05 45 4D +EF E0 2F D2 85 47 63 0D F9 22 83 27 4D 5A 63 E4 +F4 00 6F E0 1F F3 37 15 02 50 13 05 45 50 EF E0 +4F D0 6F E0 1F F2 37 15 02 50 13 05 85 51 EF E0 +4F CF 83 27 84 FA 03 27 4D 5A 63 87 07 22 B7 17 +01 10 EC 53 8D 46 63 F5 E6 24 15 65 13 05 45 7F +EF E0 2F CF 85 BF 83 27 84 F6 41 6F 13 0F 0F F0 +94 43 03 A8 47 00 88 47 DC 47 13 DE 86 01 93 95 +86 01 93 D4 86 00 13 16 88 01 93 5A 88 01 93 53 +88 00 13 5A 85 01 93 19 85 01 93 52 85 00 13 D7 +87 01 13 99 87 01 93 DE 87 00 B7 0F FF 00 B3 E5 +C5 01 B3 F4 E4 01 13 9E 86 00 33 66 56 01 B3 F3 +E3 01 22 08 B3 66 3A 01 B3 F2 E2 01 22 05 33 67 +27 01 B3 FE EE 01 A2 07 C5 8D 33 7E FE 01 33 66 +76 00 33 78 F8 01 B3 E6 56 00 33 75 F5 01 33 67 +D7 01 B3 F7 F7 01 B3 E5 C5 01 33 66 06 01 C9 8E +D9 8F 23 28 B4 FA 23 2A C4 FA 23 2C D4 FA 23 2E +F4 FA 8D BC 95 68 13 85 88 7D A6 85 EF E0 6F C3 +83 28 4D 5A ED BA 95 68 13 85 08 7C CA 85 EF E0 +4F C2 83 28 4D 5A 95 BA 37 15 02 50 13 05 C5 37 +EF E0 2F BF B1 BE 99 C3 6F E0 BF E7 83 29 C4 F8 +83 27 C4 F9 81 44 94 43 03 A7 09 00 63 8A E6 04 +15 69 13 09 09 42 A6 85 13 05 C9 16 EF E0 6F BE +03 27 C4 F9 93 97 24 00 13 05 49 19 BA 97 8C 43 +EF E0 2F BD 83 A5 09 00 13 05 C9 1A EF E0 6F BC +05 45 EF E0 0F B8 01 A0 83 25 47 08 15 65 13 05 +C5 68 91 89 EF E0 EF BA 05 45 EF E0 8F B6 01 A0 +85 04 91 09 91 07 E3 10 9A FA 6F E0 9F E0 89 47 +63 E9 E7 0C 37 25 01 10 13 05 45 A0 EF 80 60 31 +83 28 4D 5A 6F E0 3F DF 95 64 93 84 44 7F 26 85 +EF E0 2F B7 83 27 4D 5A 83 A5 C9 06 E3 70 F9 E0 +26 85 EF E0 0F B6 83 27 4D 5A 83 A5 09 07 E3 73 +F9 9E 26 85 EF E0 EF B4 F1 BA 95 68 93 88 08 42 +93 89 48 3D A6 85 4E 85 23 26 14 FB EF E0 6F B3 +83 27 84 FB 83 28 C4 FA 63 97 97 12 83 27 4D 5A +83 24 09 07 E3 74 FA 9A A6 85 4E 85 EF E0 6F B1 +71 BA 95 68 A6 85 13 85 48 7F EF E0 8F B0 8D B2 +83 27 4D 5A 63 F8 F4 00 37 15 02 50 13 05 05 4F +EF E0 2F AD 37 25 01 10 13 05 C5 A0 EF 80 60 27 +83 28 4D 5A 6F E0 3F D5 B7 17 01 10 E4 53 8D 47 +E3 FC E7 90 95 68 A6 85 13 85 48 7F EF E0 6F AC +21 B2 37 15 02 50 13 05 85 48 EF E0 8F A9 1D B7 +BC 57 91 B3 89 47 63 04 F9 00 6F E0 9F D1 83 29 +84 F9 83 27 C4 F9 81 44 83 A6 09 00 98 43 63 8E +E6 02 15 69 13 09 09 42 A6 85 13 05 49 1C EF E0 +4F A8 03 27 C4 F9 93 97 24 00 13 05 C9 1E BA 97 +8C 43 EF E0 0F A7 83 A5 09 00 13 05 49 20 EF E0 +4F A6 05 45 EF E0 EF A1 01 A0 85 04 91 09 91 07 +E3 1C 9A FA 6F E0 FF CB 95 68 05 49 93 88 08 42 +CA 85 13 85 08 3E 23 26 14 FB EF E0 8F A3 83 28 +C4 FA A6 85 13 85 48 40 EF E0 AF A2 03 27 84 F6 +93 17 29 00 83 28 C4 FA BA 97 8C 43 13 85 C8 41 +EF E0 2F A1 05 45 EF E0 CF 9C 01 A0 95 68 0D 49 +93 88 08 42 75 BF 09 49 65 BF 95 68 01 49 93 88 +08 42 7D B7 37 15 02 50 13 05 45 3F EF E0 6F 9C +05 45 EF E0 0F 9A 01 A0 13 01 01 C9 23 26 71 35 +B7 0B 02 50 23 2A 51 35 83 AA 4B 5A 23 24 81 36 +23 22 91 36 23 20 21 37 23 2C 41 35 23 28 61 35 +2E CF 23 26 11 36 23 2E 31 35 23 24 81 35 2A CD +89 45 32 84 36 8B 3A 8A 3E 89 C2 84 63 EC 55 31 +C1 47 63 F8 67 01 63 9A 0A 32 05 45 EF E0 6F 94 +01 A0 B7 08 02 50 93 85 C8 62 BC 19 93 88 C8 62 +13 88 05 04 03 A5 08 00 03 A6 48 00 83 A6 88 00 +03 A7 C8 00 88 C3 D0 C3 94 C7 D8 C7 C1 08 C1 07 +E3 92 08 FF B7 17 58 26 93 87 37 92 3E D7 3E DF +B7 47 63 94 93 87 F7 37 BE C5 B7 27 2F FE 93 87 +97 6E B7 D6 E2 95 BE C7 B7 D7 DC 33 83 A8 05 05 +93 86 B6 DA 93 87 37 85 03 AF 05 04 83 AE 45 04 +03 AE 85 04 03 A3 C5 04 03 A8 45 05 A8 4D F0 4D +37 47 EA D5 36 D9 BE C9 B7 86 41 5B B7 07 22 B3 +13 07 27 D1 93 87 37 50 93 86 06 37 3A D5 3A DD +C6 D5 BE CB 36 DB 82 C1 82 C3 FA CD F6 CF F2 D1 +9A D3 C2 D7 AA D9 B2 DB 93 87 05 06 38 1A 93 88 +05 0A 03 A8 07 00 C8 43 90 47 D4 47 23 20 07 01 +48 C3 10 C7 54 C7 C1 07 41 07 E3 94 17 FF 93 87 +05 0A B8 1A 93 88 05 0E 03 A8 07 00 C8 43 90 47 +D4 47 23 20 07 01 48 C3 10 C7 54 C7 C1 07 41 07 +E3 94 17 FF 93 87 05 0E 38 1B 93 88 05 12 03 A8 +07 00 C8 43 90 47 D4 47 23 20 07 01 48 C3 10 C7 +54 C7 C1 07 41 07 E3 94 17 FF 93 88 05 12 BC 1B +13 88 05 16 03 A5 08 00 03 A6 48 00 83 A6 88 00 +03 A7 C8 00 88 C3 D0 C3 94 C7 D8 C7 C1 08 C1 07 +E3 92 08 FF 93 88 05 16 3C 1C 13 88 05 1A 03 A5 +08 00 03 A6 48 00 83 A6 88 00 03 A7 C8 00 88 C3 +D0 C3 94 C7 D8 C7 C1 08 C1 07 E3 92 08 FF 93 88 +05 1A BC 1C 93 85 05 1E 03 A5 08 00 03 A6 48 00 +83 A6 88 00 03 A7 C8 00 88 C3 D0 C3 94 C7 D8 C7 +C1 08 C1 07 E3 92 B8 FE 13 06 80 08 81 45 28 1D +EF B0 30 1A 93 3B 19 00 C1 47 85 0B 63 82 F4 16 +85 47 13 0C 81 17 63 81 F4 02 93 07 00 02 63 88 +F4 16 89 47 63 8A F4 16 91 47 63 83 F4 18 A1 47 +93 09 81 0A 63 83 F4 18 5E 57 23 22 04 02 23 24 +04 02 18 D0 4E 57 23 26 04 02 23 28 04 02 58 CC +3E 57 23 2A 04 02 23 2C 04 02 18 CC 2E 57 23 2E +04 02 23 20 04 04 58 C8 1E 57 18 C8 0E 57 58 C4 +6E 47 58 C0 7E 47 18 C4 63 14 0B 00 13 0B 00 04 +89 47 63 E0 57 13 13 16 2B 00 63 0E 09 0C E2 85 +52 85 EF B0 A0 7C BC 01 23 2E F1 30 22 86 3C 1D +13 08 04 04 08 42 4C 42 14 46 58 46 88 C3 CC C3 +94 C7 D8 C7 41 06 C1 07 E3 16 06 FF 10 42 EA 46 +7A 47 90 C3 BC 19 23 26 F1 30 85 47 23 00 F1 32 +23 22 31 31 23 24 61 31 23 28 81 31 23 2E D1 2E +23 20 E1 30 3C 1D 0A 88 28 1E 8C 43 D0 43 94 47 +D8 47 23 20 B8 00 23 22 C8 00 23 24 D8 00 23 26 +E8 00 C1 07 41 08 E3 92 A7 FE 83 A8 07 00 DC 43 +8A 86 A6 85 5E 85 01 47 11 46 23 20 18 01 23 22 +F8 00 EF E0 2F D7 83 20 C1 36 03 24 81 36 83 24 +41 36 03 29 01 36 83 29 C1 35 03 2A 81 35 83 2A +41 35 03 2B 01 35 83 2B C1 34 03 2C 81 34 13 01 +01 37 82 80 37 15 02 50 13 05 C5 54 EF D0 7F E5 +83 AA 4B 5A F1 B9 AC 19 52 85 EF B0 20 6F 25 B7 +93 09 81 0B 13 0C 81 27 C1 B5 19 65 DA 85 13 05 +45 85 EF D0 1F E5 05 45 EF D0 BF E0 D1 B1 93 09 +81 0A 13 0C 81 13 4D B5 93 09 81 0A 13 0C 81 1B +61 BD 19 65 DA 85 13 05 C5 8A EF D0 9F E2 E1 BD +93 09 81 0A 13 0C 81 1F 41 B5 13 0C 81 23 AD BD +53 74 72 69 6E 67 20 6C 65 6E 67 74 68 20 69 73 +20 25 64 2E 0A 00 00 00 45 72 72 6F 72 3A 20 49 +6E 76 61 6C 69 64 20 68 65 78 20 63 68 61 72 61 +63 74 65 72 3A 20 25 63 0A 00 00 00 53 74 72 69 +6E 67 20 6C 65 6E 67 74 68 20 69 73 20 25 64 2E +0A 00 00 00 45 72 72 6F 72 3A 20 49 6E 76 61 6C +69 64 20 68 65 78 20 63 68 61 72 61 63 74 65 72 +3A 20 25 63 0A 00 00 00 53 65 74 20 41 45 53 20 +4B 56 20 57 72 69 74 65 20 74 6F 20 73 6C 6F 74 +20 25 64 0A 00 00 00 00 57 72 69 74 65 20 41 45 +53 20 43 54 52 4C 20 77 69 74 68 20 76 61 6C 75 +65 20 30 78 25 78 0A 00 57 72 69 74 65 20 47 43 +4D 5F 41 41 44 20 50 68 61 73 65 2C 20 4E 55 4D +5F 42 59 54 45 53 20 30 78 25 78 0A 00 00 00 00 +57 72 69 74 65 20 41 45 53 20 41 41 44 20 42 6C +6F 63 6B 20 25 64 0A 00 50 61 64 64 69 6E 67 20 +41 41 44 20 77 69 74 68 20 30 73 20 41 41 44 20 +44 57 4F 52 44 3A 20 25 64 00 00 00 57 72 69 74 +65 20 49 6E 20 44 61 74 61 3A 20 30 78 25 78 20 +61 61 64 20 44 57 4F 52 44 3A 20 25 64 0A 00 00 +53 52 43 3A 20 7B 20 30 78 25 30 78 5F 25 30 78 +20 7D 20 74 6F 20 44 53 54 3A 20 7B 20 30 78 25 +30 78 5F 25 30 78 20 7D 0A 00 00 00 41 74 20 6F +66 66 73 65 74 20 5B 25 64 5D 2C 20 6F 75 74 70 +75 74 20 64 61 74 61 20 6D 69 73 6D 61 74 63 68 +21 0A 00 00 41 63 74 75 61 6C 20 20 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 45 78 70 65 +63 74 65 64 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 41 74 20 6F 66 66 73 65 74 20 5B 25 +64 5D 2C 20 6F 75 74 70 75 74 20 64 61 74 61 20 +6D 69 73 6D 61 74 63 68 21 0A 00 00 41 63 74 75 +61 6C 20 20 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 45 78 70 65 63 74 65 64 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 57 72 69 74 +65 20 41 45 53 20 49 6E 70 75 74 20 44 61 74 61 +20 42 6C 6F 63 6B 20 25 64 0A 00 00 57 72 69 74 +65 20 49 6E 20 44 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 57 72 69 74 65 20 49 6E 20 44 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 45 58 50 45 +43 54 45 44 20 4F 55 54 50 55 54 5F 4C 4F 53 54 +20 74 6F 20 62 65 20 30 78 30 20 2D 20 41 63 74 +75 61 6C 3A 20 30 78 25 78 00 00 00 43 49 50 48 +45 52 54 45 58 54 3A 20 30 78 25 78 0A 00 00 00 +41 74 20 6F 66 66 73 65 74 20 5B 25 64 5D 2C 20 +6F 75 74 70 75 74 20 64 61 74 61 20 6D 69 73 6D +61 74 63 68 21 0A 00 00 41 63 74 75 61 6C 20 20 +20 64 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +41 74 20 6F 66 66 73 65 74 20 5B 25 64 5D 2C 20 +6F 75 74 70 75 74 20 64 61 74 61 20 6D 69 73 6D +61 74 63 68 21 0A 00 00 41 63 74 75 61 6C 20 20 +20 64 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +45 78 70 65 63 74 65 64 20 64 61 74 61 3A 20 30 +78 25 78 0A 00 00 00 00 41 74 20 6F 66 66 73 65 +74 20 5B 25 64 5D 2C 20 6F 75 74 70 75 74 20 64 +61 74 61 20 6D 69 73 6D 61 74 63 68 21 0A 00 00 +41 63 74 75 61 6C 20 20 20 64 61 74 61 3A 20 30 +78 25 78 0A 00 00 00 00 45 78 70 65 63 74 65 64 +20 64 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +57 72 69 74 65 20 41 41 44 20 4C 65 6E 67 74 68 +3A 20 30 78 25 78 0A 00 57 72 69 74 65 20 54 65 +78 74 20 4C 65 6E 67 74 68 3A 20 30 78 25 78 0A +00 00 00 00 54 41 47 3A 20 30 78 25 78 0A 00 00 +41 74 20 6F 66 66 73 65 74 20 5B 25 64 5D 2C 20 +74 61 67 20 64 61 74 61 20 6D 69 73 6D 61 74 63 +68 21 0A 00 41 63 74 75 61 6C 20 20 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 45 78 70 65 +63 74 65 64 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 45 52 52 4F 52 3A 20 6F 76 65 72 72 +69 64 65 5F 74 65 78 74 5F 6C 65 6E 67 74 68 20 +28 25 64 29 20 65 78 63 65 65 64 73 20 6D 61 78 +69 6D 75 6D 20 61 6C 6C 6F 77 65 64 20 73 69 7A +65 20 6F 66 20 31 36 20 64 77 6F 72 64 73 20 28 +35 31 32 20 62 69 74 73 29 0A 00 00 50 6F 70 75 +6C 61 74 65 20 4B 56 20 77 69 74 68 20 6B 65 79 +20 6C 65 6E 67 74 68 3A 20 25 64 0A 00 00 79 71 +4A D0 37 09 02 50 03 28 49 5A 22 D4 26 D2 4E CE +52 CC 56 CA 5A C8 06 D6 5E C6 89 48 AA 8A 2E 8B +32 8A 36 84 BA 89 BE 84 63 E6 08 1B 83 A6 0A 00 +B7 07 00 10 13 87 47 00 94 C3 83 A6 4A 00 D4 C3 +83 A7 8A 00 5C C3 83 A7 CA 00 1C C7 93 16 24 00 +93 F6 C6 07 93 E6 16 00 B7 07 00 10 94 CB 37 04 +00 10 54 48 89 8A F5 DE 8D 4A 63 EC 0A 11 83 26 +0B 00 B7 07 00 10 13 87 47 00 94 C3 83 26 4B 00 +D4 C3 83 27 8B 00 5C C3 83 27 CB 00 1C C7 13 97 +29 00 13 77 C7 07 13 67 27 00 B7 07 00 10 98 CB +37 04 00 10 58 48 09 8B 75 DF 8D 49 63 E3 09 07 +83 27 0A 00 37 07 00 10 93 06 47 00 1C C3 03 26 +4A 00 B7 07 03 30 83 A7 07 0E 50 C3 03 27 8A 00 +93 F7 07 04 D8 C2 03 27 CA 00 98 C6 C1 C3 93 97 +24 00 93 F7 C7 07 93 E7 07 08 37 07 00 10 1C CB +5C 4B 89 8B F5 DF 8D 47 63 E7 07 15 B2 50 22 54 +92 54 02 59 F2 49 62 4A D2 4A 42 4B B2 4B 45 61 +82 80 37 15 02 50 13 05 05 62 EF D0 9F 82 03 28 +49 5A E3 F7 09 F9 37 15 02 50 13 05 05 65 EF D0 +5F 81 83 27 0A 00 03 28 49 5A 1C C0 83 26 4A 00 +B7 07 03 30 83 A7 07 0E 54 C0 83 26 8A 00 93 F7 +07 04 14 C4 83 26 CA 00 54 C4 F9 EB 89 47 E3 FF +07 F9 37 15 02 50 13 05 85 6B 22 54 B2 50 92 54 +02 59 F2 49 62 4A D2 4A 42 4B B2 4B 45 61 6F D0 +4F FC 37 15 02 50 13 05 85 5A EF D0 8F FB 03 28 +49 5A E3 FE 0A ED 37 15 02 50 13 05 05 5D EF D0 +4F FA 03 27 0B 00 03 28 49 5A 18 C0 03 27 4B 00 +58 C0 03 27 8B 00 18 C4 03 27 CB 00 58 C4 E3 F8 +0A ED 37 15 02 50 13 05 05 5F EF D0 8F F7 03 28 +49 5A 75 BD 37 15 02 50 13 05 05 56 EF D0 6F F6 +03 28 49 5A 8D 4B E3 F3 0B E5 37 15 02 50 13 05 +C5 56 EF D0 0F F5 03 A7 0A 00 B7 07 00 10 03 28 +49 5A 98 C3 83 A6 4A 00 13 87 47 00 D4 C3 83 A7 +8A 00 5C C3 83 A7 CA 00 1C C7 E3 F9 0B E3 37 15 +02 50 13 05 05 58 EF D0 CF F1 03 28 49 5A 39 BD +E3 F7 09 EB 37 15 02 50 13 05 45 66 EF D0 6F F0 +03 28 49 5A 69 BD 37 15 02 50 13 05 C5 68 31 BF +B7 07 02 50 03 A7 47 5A 8D 47 63 E7 E7 00 B7 07 +00 10 0D 47 98 CB 82 80 37 15 02 50 41 11 13 05 +C5 6E 06 C6 EF D0 EF EC B2 40 B7 07 00 10 0D 47 +98 CB 41 01 82 80 00 00 41 11 22 C4 37 04 02 50 +03 27 44 5A 06 C6 89 47 63 E0 E7 04 37 47 02 50 +13 07 07 8B 1C 47 54 47 D5 8F 9D E3 73 00 50 10 +93 07 40 06 01 00 FD 17 C2 07 C1 83 E5 FF 1C 47 +54 47 D5 8F E5 D7 83 26 44 5A 89 47 63 E5 D7 02 +B2 40 22 44 41 01 82 80 37 15 02 50 13 05 05 70 +EF D0 2F E6 37 47 02 50 13 07 07 8B 1C 47 54 47 +D5 8F CD DF C9 BF 22 44 4C 47 B2 40 10 47 1D 65 +13 05 85 14 41 01 6F D0 CF E5 B7 07 02 50 03 A7 +47 5A 89 47 63 E7 E7 00 B7 87 00 10 11 47 98 CB +82 80 37 15 02 50 41 11 13 05 85 71 06 C6 EF D0 +4F E1 B2 40 B7 87 00 10 11 47 98 CB 41 01 82 80 +79 71 26 D2 4A D0 56 CA 5A C8 06 D6 22 D4 4E CE +52 CC 5E C6 83 4B 15 00 03 CA 06 00 36 8B 3E 89 +B2 86 BA 8A C2 84 B7 87 00 10 80 4F 05 88 75 DC +03 47 05 00 63 03 07 3C 13 97 1B 00 13 77 E7 03 +13 67 17 00 23 A4 E7 60 23 A0 07 08 23 A2 07 08 +23 A4 07 08 23 A6 07 08 23 A8 07 08 23 AA 07 08 +23 AC 07 08 23 AE 07 08 23 A0 07 0A 23 A2 07 0A +23 A4 07 0A 23 A6 07 0A 37 87 00 10 83 27 C7 60 +89 8B ED DF 63 0D 0A 00 83 47 1B 00 37 87 00 10 +86 07 93 F7 E7 03 93 E7 17 20 23 28 F7 60 D8 41 +B7 87 00 10 B7 09 02 50 23 A0 E7 50 98 45 09 46 +23 A2 E7 50 D8 45 23 A4 E7 50 98 49 23 A6 E7 50 +D8 49 23 A8 E7 50 98 4D 23 AA E7 50 D8 4D 23 AC +E7 50 98 51 23 AE E7 50 D8 51 23 A0 E7 52 98 55 +23 A2 E7 52 D8 55 23 A4 E7 52 98 59 23 A6 E7 52 +D8 42 23 A0 E7 48 98 46 23 A2 E7 48 D8 46 23 A4 +E7 48 98 4A 23 A6 E7 48 D8 4A 23 A8 E7 48 98 4E +23 AA E7 48 D8 4E 23 AC E7 48 98 52 23 AE E7 48 +D8 52 23 A0 E7 4A 98 56 23 A2 E7 4A D8 56 23 A4 +E7 4A 98 5A 23 A6 E7 4A 03 A7 49 5A 63 6B E6 30 +B7 87 00 10 85 46 94 CB 63 93 0B 00 0D 44 B7 87 +00 10 23 A4 87 60 23 A0 07 08 23 A2 07 08 23 A4 +07 08 23 A6 07 08 23 A8 07 08 23 AA 07 08 23 AC +07 08 23 AE 07 08 23 A0 07 0A 23 A2 07 0A 23 A4 +07 0A 23 A6 07 0A 89 47 63 EE E7 2A 37 47 02 50 +13 07 07 8B 1C 47 54 47 D5 8F 91 EF 73 00 50 10 +93 07 40 06 01 00 FD 17 C2 07 C1 83 E5 FF 1C 47 +54 47 D5 8F E5 D7 83 A7 49 5A 09 44 63 6D F4 0A +63 1E 0A 0C B7 87 00 10 03 AA 07 18 03 24 4B 00 +63 1C 8A 2A 03 AA 47 18 03 24 8B 00 63 15 8A 30 +03 AA 87 18 03 24 CB 00 63 11 8A 30 03 AA C7 18 +03 24 0B 01 63 1D 8A 2E 03 AA 07 19 03 24 4B 01 +63 19 8A 2E 03 AA 47 19 03 24 8B 01 63 15 8A 2E +03 AA 87 19 03 24 CB 01 63 11 8A 2E 03 AA C7 19 +03 24 0B 02 63 1D 8A 2C 03 AA 07 1A 03 24 4B 02 +63 13 8A 2E 03 AA 47 1A 03 24 8B 02 63 1F 8A 2C +03 AA 87 1A 03 24 CB 02 63 15 8A 2C 03 AA C7 1A +03 24 0B 03 AD 45 63 1A 8A 22 85 47 63 89 F4 04 +B2 50 22 54 92 54 02 59 F2 49 62 4A D2 4A 42 4B +B2 4B 45 61 82 80 4C 47 10 47 1D 65 13 05 85 14 +EF D0 2F BA 83 A7 49 5A 63 0E 0A 1C 63 78 F4 00 +37 15 02 50 13 05 85 73 EF D0 AF B6 37 87 00 10 +83 27 47 61 89 8B ED DF 85 47 E3 9B F4 FA 03 A7 +49 5A 89 47 63 E1 E7 1C B7 87 00 10 83 A4 07 20 +03 A4 4A 00 63 99 84 20 83 A4 47 20 03 A4 8A 00 +63 99 84 22 83 A4 87 20 03 A4 CA 00 63 95 84 22 +83 A4 C7 20 03 A4 0A 01 63 91 84 22 83 A4 07 21 +03 A4 4A 01 63 9D 84 20 83 A4 47 21 03 A4 8A 01 +63 91 84 1E 83 A4 87 21 03 A4 CA 01 63 99 84 2A +83 A4 C7 21 03 A4 0A 02 63 91 84 2A 83 A4 07 22 +03 A4 4A 02 63 99 84 28 83 A4 47 22 03 A4 8A 02 +63 91 84 28 83 A4 87 22 03 A4 CA 02 63 99 84 26 +83 A4 C7 22 03 A4 0A 03 AD 45 63 97 84 18 89 47 +63 EC E7 16 B7 87 00 10 83 A4 07 28 03 24 49 00 +63 15 94 24 83 A4 47 28 03 24 89 00 63 1D 94 22 +83 A4 87 28 03 24 C9 00 63 15 94 22 83 A4 C7 28 +03 24 09 01 63 9D 84 20 83 A4 07 29 03 24 49 01 +63 95 84 20 83 A4 47 29 03 24 89 01 63 9D 84 1E +83 A4 87 29 03 24 C9 01 63 95 84 1E 83 A4 C7 29 +03 24 09 02 63 9D 84 1C 83 A4 07 2A 03 24 49 02 +63 95 84 1C 83 A4 47 2A 03 24 89 02 63 9D 84 1A +83 A4 87 2A 03 24 C9 02 63 95 84 1A 83 A4 C7 2A +03 24 09 03 AD 45 E3 8D 84 E6 83 A7 49 5A 63 90 +07 16 05 45 EF D0 EF 9E 01 A0 58 41 23 A0 E7 08 +18 45 23 A2 E7 08 58 45 23 A4 E7 08 18 49 23 A6 +E7 08 58 49 23 A8 E7 08 18 4D 23 AA E7 08 58 4D +23 AC E7 08 18 51 23 AE E7 08 58 51 23 A0 E7 0A +18 55 23 A2 E7 0A 58 55 23 A4 E7 0A 18 59 23 A6 +E7 0A 89 B1 37 15 02 50 13 05 05 70 EF D0 6F 9B +35 BB 37 15 02 50 13 05 C5 72 EF D0 8F 9A 03 A7 +49 5A F9 B9 E3 70 F4 D6 37 15 02 50 13 05 C5 74 +EF D0 2F 99 81 BB 37 15 02 50 13 05 85 76 EF D0 +4F 98 03 A7 49 5A 0D BD 81 45 83 A7 49 5A 89 E7 +05 45 EF D0 0F 95 01 A0 9D 64 93 84 84 14 13 85 +44 03 EF D0 0F 98 83 A7 49 5A FD D3 D2 85 13 85 +04 06 EF D0 0F 97 83 A7 49 5A F9 DB A2 85 13 85 +84 07 EF D0 0F 96 E9 B7 37 15 02 50 13 05 45 78 +EF D0 2F 93 41 B5 81 45 39 E3 05 45 EF D0 6F 90 +01 A0 95 45 D5 BF 85 45 4D B7 89 45 79 BF 8D 45 +69 BF 91 45 59 BF 95 45 49 BF 99 45 79 B7 9D 45 +69 B7 85 45 D1 BF 89 45 C1 BF 8D 45 F1 B7 91 45 +E1 B7 A9 45 9D BF A1 45 8D BF A5 45 BD B7 1D 69 +13 09 89 14 13 05 09 09 EF D0 AF 8F 83 A7 49 5A +CD D7 A6 85 13 05 09 0C EF D0 AF 8E 83 A7 49 5A +C9 DF A2 85 13 05 89 0D EF D0 AF 8D 79 B7 1D 69 +13 09 89 14 13 05 09 0F EF D0 AF 8C 83 A7 49 5A +E3 89 07 E8 A6 85 13 05 09 12 EF D0 8F 8B 83 A7 +49 5A E3 80 07 E8 A2 85 13 05 89 13 EF D0 6F 8A +8D BD A9 45 9D B5 A5 45 8D B5 A1 45 B9 BD 9D 45 +A9 BD 99 45 99 BD 95 45 89 BD 91 45 B9 B5 8D 45 +A9 B5 89 45 99 B5 85 45 89 B5 81 45 3D BD A9 45 +25 B7 A5 45 15 B7 A1 45 05 B7 9D 45 31 BF 99 45 +21 BF 79 71 4E CE 52 CC 5A C8 5E C6 06 D6 22 D4 +26 D2 4A D0 56 CA 83 CA 15 00 83 44 07 00 BA 89 +2A 8A B2 8B 36 8B B7 87 00 10 80 4F 05 88 75 DC +03 C7 05 00 63 0D 07 2C 13 97 1A 00 13 77 E7 03 +13 67 17 00 23 A0 E7 60 37 87 00 10 83 27 47 60 +89 8B ED DF 37 09 02 50 03 27 49 5A 89 47 63 E3 +E7 30 03 A6 4B 00 B7 87 00 10 89 46 23 A0 C7 20 +03 A6 8B 00 23 A2 C7 20 03 A6 CB 00 23 A4 C7 20 +03 A6 0B 01 23 A6 C7 20 03 A6 4B 01 23 A8 C7 20 +03 A6 8B 01 23 AA C7 20 03 A6 CB 01 23 AC C7 20 +03 A6 0B 02 23 AE C7 20 03 A6 4B 02 23 A0 C7 22 +03 A6 8B 02 23 A2 C7 22 03 A6 CB 02 23 A4 C7 22 +03 A6 0B 03 23 A6 C7 22 63 E7 E6 2C 83 26 4B 00 +B7 87 00 10 23 A0 D7 28 83 26 8B 00 23 A2 D7 28 +83 26 CB 00 23 A4 D7 28 83 26 0B 01 23 A6 D7 28 +83 26 4B 01 23 A8 D7 28 83 26 8B 01 23 AA D7 28 +83 26 CB 01 23 AC D7 28 83 26 0B 02 23 AE D7 28 +83 26 4B 02 23 A0 D7 2A 83 26 8B 02 23 A2 D7 2A +83 26 CB 02 23 A4 D7 2A 83 26 0B 03 23 A6 D7 2A +83 26 4A 00 23 A0 D7 48 83 26 8A 00 23 A2 D7 48 +83 26 CA 00 23 A4 D7 48 83 26 0A 01 23 A6 D7 48 +83 26 4A 01 23 A8 D7 48 83 26 8A 01 23 AA D7 48 +83 26 CA 01 23 AC D7 48 83 26 0A 02 23 AE D7 48 +83 26 4A 02 23 A0 D7 4A 83 26 8A 02 23 A2 D7 4A +83 26 CA 02 23 A4 D7 4A 83 26 0A 03 23 A6 D7 4A +81 CC 83 C6 19 00 05 66 13 06 16 AC 86 06 93 F6 +F6 0F D1 8E 23 A8 D7 60 89 47 63 ED E7 1C B7 87 +00 10 C1 46 94 CB 63 93 0A 00 0D 44 B7 87 00 10 +23 A0 87 60 23 A0 07 58 23 A2 07 58 23 A4 07 58 +23 A6 07 58 23 A8 07 58 23 AA 07 58 23 AC 07 58 +23 AE 07 58 23 A0 07 5A 23 A2 07 5A 23 A4 07 5A +23 A6 07 5A 89 47 63 E0 E7 18 37 47 02 50 13 07 +07 8B 1C 47 54 47 D5 8F 91 EF 73 00 50 10 93 07 +40 06 01 00 FD 17 C2 07 C1 83 E5 FF 1C 47 54 47 +D5 8F E5 D7 83 27 49 5A 09 44 63 69 F4 0A E9 E8 +B7 87 00 10 83 A4 07 5C 03 A4 49 00 63 1F 94 16 +83 A4 47 5C 03 A4 89 00 63 1B 94 1A 83 A4 87 5C +03 A4 C9 00 63 97 84 1A 83 A4 C7 5C 03 A4 09 01 +63 93 84 1A 83 A4 07 5D 03 A4 49 01 63 9F 84 18 +83 A4 47 5D 03 A4 89 01 63 9B 84 18 83 A4 87 5D +03 A4 C9 01 63 97 84 18 83 A4 C7 5D 03 A4 09 02 +63 93 84 18 83 A4 07 5E 03 A4 49 02 63 9F 84 16 +83 A4 47 5E 03 A4 89 02 63 9B 84 16 83 A4 87 5E +03 A4 C9 02 63 93 84 14 83 A4 C7 5E 03 A4 09 03 +AD 45 63 9D 84 0E B2 50 22 54 92 54 02 59 F2 49 +62 4A D2 4A 42 4B B2 4B 45 61 82 80 4C 47 10 47 +1D 65 13 05 85 14 EF C0 DF D7 83 27 49 5A CD CC +63 78 F4 00 37 15 02 50 13 05 85 73 EF C0 7F D4 +37 87 00 10 83 27 47 61 89 8B ED DF 6D BF D8 41 +37 09 02 50 23 A0 E7 58 98 45 23 A2 E7 58 D8 45 +23 A4 E7 58 98 49 23 A6 E7 58 D8 49 23 A8 E7 58 +98 4D 23 AA E7 58 D8 4D 23 AC E7 58 98 51 23 AE +E7 58 D8 51 23 A0 E7 5A 98 55 23 A2 E7 5A D8 55 +23 A4 E7 5A 98 59 23 A6 E7 5A 03 27 49 5A 89 47 +E3 F1 E7 D0 37 15 02 50 13 05 05 7A EF C0 7F CD +03 27 49 5A FD B1 37 15 02 50 13 05 05 70 EF C0 +5F CC A5 BD 37 15 02 50 13 05 85 7D EF C0 7F CB +03 27 49 5A 29 BD 37 15 02 50 13 05 C5 7B EF C0 +5F CA 03 27 49 5A 1D B3 E3 74 F4 E8 37 15 02 50 +13 05 85 7E EF C0 FF C8 A5 BD 81 45 83 27 49 5A +89 E7 05 45 EF C0 FF C5 01 A0 9D 69 93 89 89 14 +13 85 09 15 EF C0 FF C8 83 27 49 5A FD D3 A6 85 +13 85 09 18 EF C0 FF C7 83 27 49 5A F9 DB A2 85 +13 85 89 19 EF C0 FF C6 E9 B7 A9 45 C1 B7 85 45 +75 BF 89 45 65 BF 8D 45 55 BF 91 45 45 BF 95 45 +75 B7 99 45 65 B7 9D 45 55 B7 A1 45 45 B7 A5 45 +71 BF 79 71 26 D2 4E CE 52 CC 5A C8 5E C6 06 D6 +22 D4 4A D0 56 CA 83 4A 15 00 BE 84 AE 8B 32 8B +B6 89 3A 8A B7 87 00 10 80 4F 05 88 75 DC 83 46 +05 00 37 09 02 50 03 27 49 5A 63 87 06 32 89 47 +63 E9 E7 38 93 96 1A 00 93 F6 E6 03 B7 87 00 10 +93 E6 16 00 23 A0 D7 60 23 A0 07 58 23 A2 07 58 +23 A4 07 58 23 A6 07 58 23 A8 07 58 23 AA 07 58 +23 AC 07 58 23 AE 07 58 23 A0 07 5A 23 A2 07 5A +23 A4 07 5A 23 A6 07 5A B7 86 00 10 83 A7 46 60 +89 8B ED DF 03 A6 4B 00 B7 87 00 10 89 46 23 A0 +C7 10 03 A6 8B 00 23 A2 C7 10 03 A6 CB 00 23 A4 +C7 10 03 A6 0B 01 23 A6 C7 10 03 A6 4B 01 23 A8 +C7 10 03 A6 8B 01 23 AA C7 10 03 A6 CB 01 23 AC +C7 10 03 A6 0B 02 23 AE C7 10 03 A6 4B 02 23 A0 +C7 12 03 A6 8B 02 23 A2 C7 12 03 A6 CB 02 23 A4 +C7 12 03 A6 0B 03 23 A6 C7 12 03 26 4B 00 23 A0 +C7 48 03 26 8B 00 23 A2 C7 48 03 26 CB 00 23 A4 +C7 48 03 26 0B 01 23 A6 C7 48 03 26 4B 01 23 A8 +C7 48 03 26 8B 01 23 AA C7 48 03 26 CB 01 23 AC +C7 48 03 26 0B 02 23 AE C7 48 03 26 4B 02 23 A0 +C7 4A 03 26 8B 02 23 A2 C7 4A 03 26 CB 02 23 A4 +C7 4A 03 26 0B 03 23 A6 C7 4A 63 E3 E6 26 B7 87 +00 10 89 46 94 CB 63 93 0A 00 0D 44 B7 87 00 10 +23 A0 87 60 23 A0 07 58 23 A2 07 58 23 A4 07 58 +23 A6 07 58 23 A8 07 58 23 AA 07 58 23 AC 07 58 +23 AE 07 58 23 A0 07 5A 23 A2 07 5A 23 A4 07 5A +23 A6 07 5A 89 47 63 E6 E7 20 37 47 02 50 13 07 +07 8B 1C 47 54 47 D5 8F 91 EF 73 00 50 10 93 07 +40 06 01 00 FD 17 C2 07 C1 83 E5 FF 1C 47 54 47 +D5 8F E5 D7 83 26 49 5A 09 44 63 60 D4 02 85 47 +63 83 F4 04 B2 50 22 54 92 54 02 59 F2 49 62 4A +D2 4A 42 4B B2 4B 45 61 82 80 4C 47 10 47 1D 65 +13 05 85 14 EF C0 FF A3 85 47 E3 9D F4 FC 83 26 +49 5A 63 7A D4 00 37 25 02 50 13 05 85 83 EF C0 +5F A0 83 26 49 5A B7 87 00 10 83 A4 07 30 03 A4 +49 00 63 99 84 1A 83 A4 47 30 03 A4 89 00 63 9C +84 22 83 A4 87 30 03 A4 C9 00 63 9E 84 20 83 A4 +C7 30 03 A4 09 01 63 9A 84 20 83 A4 07 31 03 A4 +49 01 63 96 84 20 83 A4 47 31 03 A4 89 01 63 92 +84 20 83 A4 87 31 03 A4 C9 01 63 90 84 20 83 A4 +C7 31 03 A4 09 02 63 9C 84 1E 83 A4 07 32 03 A4 +49 02 63 98 84 1C 83 A4 47 32 03 A4 89 02 63 90 +84 1C 83 A4 87 32 03 A4 C9 02 63 98 84 1A 83 A4 +C7 32 03 A4 09 03 AD 45 63 97 84 12 89 47 63 E9 +D7 12 B7 87 00 10 83 A4 07 38 03 24 4A 00 63 94 +84 18 83 A4 47 38 03 24 8A 00 63 1C 94 16 83 A4 +87 38 03 24 CA 00 63 94 84 16 83 A4 C7 38 03 24 +0A 01 63 1C 94 14 83 A4 07 39 03 24 4A 01 63 94 +84 14 83 A4 47 39 03 24 8A 01 63 9C 84 12 83 A4 +87 39 03 24 CA 01 63 94 84 12 83 A4 C7 39 03 24 +0A 02 63 9C 84 10 83 A4 07 3A 03 24 4A 02 63 94 +84 10 83 A4 47 3A 03 24 8A 02 63 9C 84 0E 83 A4 +87 3A 03 24 CA 02 63 94 84 0E 83 A4 C7 3A 03 24 +0A 03 AD 45 E3 88 84 E8 83 27 49 5A 63 93 07 12 +05 45 EF C0 1F 8A 01 A0 54 41 23 A0 D7 58 14 45 +23 A2 D7 58 54 45 23 A4 D7 58 14 49 23 A6 D7 58 +54 49 23 A8 D7 58 14 4D 23 AA D7 58 54 4D 23 AC +D7 58 14 51 23 AE D7 58 54 51 23 A0 D7 5A 14 55 +23 A2 D7 5A 54 55 23 A4 D7 5A 14 59 23 A6 D7 5A +D5 B1 37 15 02 50 13 05 05 70 EF C0 9F 86 F5 B3 +37 25 02 50 13 05 85 82 EF C0 BF 85 03 27 49 5A +79 B3 37 25 02 50 13 05 85 80 EF C0 9F 84 03 27 +49 5A 8D B1 81 45 81 EE 05 45 EF C0 9F 81 01 A0 +37 25 02 50 13 05 45 85 EF C0 BF 82 D9 B5 9D 69 +93 89 89 14 13 85 09 1B EF C0 BF 83 83 27 49 5A +E1 DF A6 85 13 85 C9 1D EF C0 BF 82 83 27 49 5A +E1 D7 A2 85 13 85 49 1F EF C0 BF 81 75 BF A9 45 +25 B7 A5 45 15 B7 A1 45 05 B7 9D 45 31 BF 99 45 +21 BF 95 45 11 BF 91 45 01 BF 8D 45 31 B7 89 45 +21 B7 85 45 11 B7 81 45 01 B7 A9 45 69 B7 A5 45 +59 B7 A1 45 49 B7 89 45 BD BF 8D 45 AD BF 91 45 +9D BF 95 45 8D BF 85 45 BD B7 99 45 AD B7 9D 45 +9D B7 9D 69 93 89 89 14 13 85 C9 20 EF C0 6F FB +83 27 49 5A E3 86 07 EC A6 85 13 85 89 23 EF C0 +4F FA 83 27 49 5A E3 8D 07 EA A2 85 13 85 09 25 +EF C0 2F F9 75 B5 01 11 22 CC 26 CA 06 CE 4A C8 +4E C6 B6 84 37 84 00 10 1C 4C 85 8B F5 DF 5C 41 +B7 09 02 50 09 49 23 20 F4 10 1C 45 23 22 F4 10 +5C 45 23 24 F4 10 1C 49 23 26 F4 10 5C 49 23 28 +F4 10 1C 4D 23 2A F4 10 5C 4D 23 2C F4 10 1C 51 +23 2E F4 10 5C 51 23 20 F4 12 1C 55 23 22 F4 12 +5C 55 23 24 F4 12 1C 59 23 26 F4 12 DC 41 23 20 +F4 20 9C 45 23 22 F4 20 DC 45 23 24 F4 20 9C 49 +23 26 F4 20 DC 49 23 28 F4 20 9C 4D 23 2A F4 20 +DC 4D 23 2C F4 20 9C 51 23 2E F4 20 DC 51 23 20 +F4 22 9C 55 23 22 F4 22 DC 55 23 24 F4 22 9C 59 +23 26 F4 22 5C 42 23 20 F4 28 1C 46 23 22 F4 28 +5C 46 23 24 F4 28 1C 4A 23 26 F4 28 5C 4A 23 28 +F4 28 1C 4E 23 2A F4 28 5C 4E 23 2C F4 28 1C 52 +23 2E F4 28 5C 52 23 20 F4 2A 1C 56 23 22 F4 2A +5C 56 23 24 F4 2A 1C 5A 23 26 F4 2A DC 40 23 20 +F4 30 9C 44 23 22 F4 30 DC 44 23 24 F4 30 9C 48 +23 26 F4 30 DC 48 23 28 F4 30 9C 4C 23 2A F4 30 +DC 4C 23 2C F4 30 9C 50 23 2E F4 30 DC 50 23 20 +F4 32 9C 54 23 22 F4 32 DC 54 23 24 F4 32 9C 58 +23 26 F4 32 5C 43 23 20 F4 38 1C 47 23 22 F4 38 +5C 47 23 24 F4 38 1C 4B 23 26 F4 38 5C 4B 23 28 +F4 38 1C 4F 23 2A F4 38 5C 4F 23 2C F4 38 1C 53 +23 2E F4 38 5C 53 23 20 F4 3A 1C 57 23 22 F4 3A +5C 57 23 24 F4 3A 1C 5B 23 26 F4 3A 83 A7 49 5A +63 6E F9 0E 8D 47 1C C8 37 47 02 50 13 07 07 8B +1C 47 54 47 D5 8F 9D E3 73 00 50 10 93 07 40 06 +01 00 FD 17 C2 07 C1 83 E5 FF 1C 47 54 47 D5 8F +E5 D7 83 A7 49 5A 09 44 63 60 F4 0A B7 87 00 10 +03 A9 07 40 C0 40 63 11 24 09 03 A9 47 40 80 44 +63 1C 89 10 03 A9 87 40 C0 44 63 15 89 10 03 A9 +C7 40 80 48 63 16 24 11 03 A9 07 41 C0 48 63 1F +89 0E 03 A9 47 41 80 4C 63 1E 89 0E 03 A9 87 41 +C0 4C 63 11 89 10 03 A9 C7 41 80 50 63 16 89 0E +03 A9 07 42 C0 50 63 19 89 0E 03 A9 47 42 80 54 +63 1E 89 0C 03 A9 87 42 C0 54 63 1B 89 0C 03 A9 +C7 42 80 58 AD 45 63 1A 89 00 F2 40 62 44 D2 44 +42 49 B2 49 05 61 82 80 81 45 83 A7 49 5A BD E3 +05 45 EF C0 0F CF 01 A0 4C 47 10 47 1D 65 13 05 +85 14 EF C0 0F D2 83 A7 49 5A E3 79 F4 F4 37 25 +02 50 13 05 05 88 EF C0 CF CE 89 B7 37 25 02 50 +13 05 05 87 EF C0 EF CD 83 A7 49 5A 0D 47 18 C8 +E3 7C F9 EE 37 15 02 50 13 05 05 70 EF C0 6F CC +37 47 02 50 13 07 07 8B 1C 47 54 47 D5 8F E3 85 +07 EE 01 B7 9D 64 93 84 84 14 13 85 84 26 EF C0 +4F CC 83 A7 49 5A C9 D7 CA 85 13 85 84 29 EF C0 +4F CB 83 A7 49 5A AD DF A2 85 13 85 04 2B EF C0 +4F CA BD B7 89 45 95 B7 85 45 85 B7 91 45 B1 BF +8D 45 A1 BF 95 45 91 BF 9D 45 81 BF A5 45 B1 B7 +A9 45 A1 B7 99 45 91 B7 A1 45 81 B7 01 11 22 CC +4E C6 52 C4 06 CE 26 CA 4A C8 2A 87 AE 89 32 8A +37 84 00 10 1C 4C 85 8B F5 DF 5C 43 37 09 02 50 +89 44 23 20 F4 48 1C 47 23 22 F4 48 5C 47 23 24 +F4 48 1C 4B 23 26 F4 48 5C 4B 23 28 F4 48 1C 4F +23 2A F4 48 5C 4F 23 2C F4 48 1C 53 23 2E F4 48 +5C 53 23 20 F4 4A 1C 57 23 22 F4 4A 5C 57 23 24 +F4 4A 1C 5B 23 26 F4 4A 83 27 49 5A 63 E5 F4 1E +A9 47 1C C8 93 07 F0 03 23 20 F4 60 23 20 04 58 +23 22 04 58 23 24 04 58 23 26 04 58 23 28 04 58 +23 2A 04 58 23 2C 04 58 23 2E 04 58 23 20 04 5A +23 22 04 5A 23 24 04 5A 23 26 04 5A 37 47 02 50 +13 07 07 8B 1C 47 54 47 D5 8F 91 EF 73 00 50 10 +93 07 40 06 01 00 FD 17 C2 07 C1 83 E5 FF 1C 47 +54 47 D5 8F E5 D7 83 26 49 5A 09 44 63 69 D4 14 +B7 87 00 10 83 A4 07 30 03 A4 49 00 63 9B 84 12 +83 A4 47 30 03 A4 89 00 63 91 84 24 83 A4 87 30 +03 A4 C9 00 63 99 84 22 83 A4 C7 30 03 A4 09 01 +63 99 84 22 83 A4 07 31 03 A4 49 01 63 91 84 22 +83 A4 47 31 03 A4 89 01 63 97 84 24 83 A4 87 31 +03 A4 C9 01 63 9D 84 22 83 A4 C7 31 03 A4 09 02 +63 95 84 22 83 A4 07 32 03 A4 49 02 63 9D 84 20 +83 A4 47 32 03 A4 89 02 63 91 84 22 83 A4 87 32 +03 A4 C9 02 63 91 84 1E 83 A4 C7 32 03 A4 09 03 +AD 45 63 99 84 0A 89 47 63 E8 D7 1A B7 87 00 10 +83 A4 07 38 03 24 4A 00 63 16 94 12 83 A4 47 38 +03 24 8A 00 63 1B 94 1A 83 A4 87 38 03 24 CA 00 +63 97 84 1A 83 A4 C7 38 03 24 0A 01 63 93 84 1A +83 A4 07 39 03 24 4A 01 63 9F 84 18 83 A4 47 39 +03 24 8A 01 63 9B 84 18 83 A4 87 39 03 24 CA 01 +63 97 84 18 83 A4 C7 39 03 24 0A 02 63 93 84 18 +83 A4 07 3A 03 24 4A 02 63 9B 84 18 83 A4 47 3A +03 24 8A 02 63 97 84 18 83 A4 87 3A 03 24 CA 02 +63 99 84 16 83 A4 C7 3A 03 24 0A 03 AD 45 63 94 +84 0A F2 40 62 44 D2 44 42 49 B2 49 22 4A 05 61 +82 80 81 45 E1 EA 05 45 EF C0 AF A0 01 A0 4C 47 +10 47 1D 65 13 05 85 14 EF C0 AF A3 83 26 49 5A +E3 70 D4 EA 37 25 02 50 13 05 85 83 EF C0 6F A0 +83 26 49 5A 71 B5 37 25 02 50 13 05 C5 89 EF C0 +4F 9F 29 47 83 27 49 5A 18 C8 13 07 F0 03 23 20 +E4 60 23 20 04 58 23 22 04 58 23 24 04 58 23 26 +04 58 23 28 04 58 23 2A 04 58 23 2C 04 58 23 2E +04 58 23 20 04 5A 23 22 04 5A 23 24 04 5A 23 26 +04 5A E3 F5 F4 E0 37 15 02 50 13 05 05 70 EF C0 +4F 9A ED BB 81 45 83 27 49 5A 89 E7 05 45 EF C0 +4F 97 01 A0 9D 69 93 89 89 14 13 85 49 32 EF C0 +4F 9A 83 27 49 5A FD D3 A6 85 13 85 09 35 EF C0 +4F 99 83 27 49 5A F9 DB A2 85 13 85 89 36 EF C0 +4F 98 E9 B7 9D 69 93 89 89 14 13 85 89 2C EF C0 +4F 97 83 27 49 5A E3 80 07 F2 A6 85 13 85 49 2F +EF C0 2F 96 83 27 49 5A E3 87 07 F0 A2 85 13 85 +C9 30 EF C0 0F 95 01 B7 37 25 02 50 13 05 45 85 +EF C0 2F 92 A1 B5 89 45 F5 B5 85 45 E5 B5 91 45 +D5 B5 8D 45 C5 B5 A9 45 F1 BD 85 45 AD B7 89 45 +9D B7 8D 45 8D B7 91 45 B9 BF 95 45 A9 BF 99 45 +99 BF 9D 45 89 BF A1 45 75 BD 9D 45 65 BD 99 45 +55 BD A9 45 89 B7 95 45 75 B5 A5 45 65 B5 A1 45 +1D BF A5 45 0D BF 01 00 52 65 63 65 69 76 65 64 +20 45 43 43 20 6E 6F 74 69 66 2F 20 65 72 72 20 +69 6E 74 72 20 77 69 74 68 20 73 74 61 74 75 73 +20 3D 20 25 64 2F 20 25 64 0A 00 00 41 74 20 6F +66 66 73 65 74 20 5B 25 64 5D 2C 20 65 63 63 5F +70 72 69 76 6B 65 79 20 64 61 74 61 20 6D 69 73 +6D 61 74 63 68 21 0A 00 41 63 74 75 61 6C 20 20 +20 64 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +45 78 70 65 63 74 65 64 20 64 61 74 61 3A 20 30 +78 25 78 0A 00 00 00 00 41 74 20 6F 66 66 73 65 +74 20 5B 25 64 5D 2C 20 65 63 63 5F 70 75 62 6B +65 79 5F 78 20 64 61 74 61 20 6D 69 73 6D 61 74 +63 68 21 0A 00 00 00 00 41 63 74 75 61 6C 20 20 +20 64 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +45 78 70 65 63 74 65 64 20 64 61 74 61 3A 20 30 +78 25 78 0A 00 00 00 00 41 74 20 6F 66 66 73 65 +74 20 5B 25 64 5D 2C 20 65 63 63 5F 70 75 62 6B +65 79 5F 79 20 64 61 74 61 20 6D 69 73 6D 61 74 +63 68 21 0A 00 00 00 00 41 63 74 75 61 6C 20 20 +20 64 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +45 78 70 65 63 74 65 64 20 64 61 74 61 3A 20 30 +78 25 78 0A 00 00 00 00 41 74 20 6F 66 66 73 65 +74 20 5B 25 64 5D 2C 20 65 63 63 5F 73 68 61 72 +65 64 6B 65 79 20 64 61 74 61 20 6D 69 73 6D 61 +74 63 68 21 0A 00 00 00 41 63 74 75 61 6C 20 20 +20 64 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +45 78 70 65 63 74 65 64 20 64 61 74 61 3A 20 30 +78 25 78 0A 00 00 00 00 41 74 20 6F 66 66 73 65 +74 20 5B 25 64 5D 2C 20 65 63 63 5F 73 69 67 6E +5F 72 20 64 61 74 61 20 6D 69 73 6D 61 74 63 68 +21 0A 00 00 41 63 74 75 61 6C 20 20 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 45 78 70 65 +63 74 65 64 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 41 74 20 6F 66 66 73 65 74 20 5B 25 +64 5D 2C 20 65 63 63 5F 73 69 67 6E 5F 73 20 64 +61 74 61 20 6D 69 73 6D 61 74 63 68 21 0A 00 00 +41 63 74 75 61 6C 20 20 20 64 61 74 61 3A 20 30 +78 25 78 0A 00 00 00 00 45 78 70 65 63 74 65 64 +20 64 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +41 74 20 6F 66 66 73 65 74 20 5B 25 64 5D 2C 20 +65 63 63 5F 76 65 72 69 66 79 5F 72 20 64 61 74 +61 20 6D 69 73 6D 61 74 63 68 21 0A 00 00 00 00 +41 63 74 75 61 6C 20 20 20 64 61 74 61 3A 20 30 +78 25 78 0A 00 00 00 00 45 78 70 65 63 74 65 64 +20 64 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +41 74 20 6F 66 66 73 65 74 20 5B 25 64 5D 2C 20 +65 63 63 5F 73 69 67 6E 5F 72 20 64 61 74 61 20 +6D 69 73 6D 61 74 63 68 21 0A 00 00 41 63 74 75 +61 6C 20 20 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 45 78 70 65 63 74 65 64 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 41 74 20 6F +66 66 73 65 74 20 5B 25 64 5D 2C 20 65 63 63 5F +73 69 67 6E 5F 73 20 64 61 74 61 20 6D 69 73 6D +61 74 63 68 21 0A 00 00 41 63 74 75 61 6C 20 20 +20 64 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +45 78 70 65 63 74 65 64 20 64 61 74 61 3A 20 30 +78 25 78 0A 00 00 00 00 41 11 22 C4 37 04 02 50 +03 27 44 5A 06 C6 89 47 63 E0 E7 04 37 47 02 50 +13 07 07 8B 3C 47 74 47 D5 8F 9D E3 73 00 50 10 +93 07 40 06 01 00 FD 17 C2 07 C1 83 E5 FF 3C 47 +74 47 D5 8F E5 D7 83 26 44 5A 89 47 63 E5 D7 02 +B2 40 22 44 41 01 82 80 37 25 02 50 13 05 05 8B +EF B0 3F CF 37 47 02 50 13 07 07 8B 3C 47 74 47 +D5 8F CD DF C9 BF 22 44 6C 47 B2 40 30 47 25 65 +13 05 05 CB 41 01 6F B0 DF CE 41 11 26 C2 B7 04 +02 50 83 A7 44 5A 22 C4 06 C6 09 44 63 60 F4 02 +B7 07 03 10 21 47 98 CB 37 07 03 10 5C 4B 85 8B +F5 DF B2 40 22 44 92 44 41 01 82 80 37 25 02 50 +13 05 C5 8C EF B0 FF C8 83 A7 44 5A 37 07 03 10 +A1 46 14 CB E3 7A F4 FC 37 25 02 50 13 05 05 8E +EF B0 3F C7 D1 B7 19 CA 0A 06 33 87 C5 00 9C 41 +91 05 11 05 23 2E F5 FE E3 9B E5 FE 82 80 79 71 +4E CE B7 09 02 50 03 A7 49 5A 26 D2 4A D0 5A C8 +5E C6 06 D6 22 D4 52 CC 56 CA 89 47 AA 8B 2E 8B +B2 84 36 89 63 E3 E7 20 B7 07 03 10 C0 4B 05 88 +75 DC 03 CA 0B 00 83 C6 2B 00 63 09 0A 16 93 97 +16 00 93 F7 E7 03 93 E7 17 00 B7 86 03 10 9C C2 +89 47 63 E3 E7 28 B7 07 03 10 23 AC 07 04 23 AE +07 04 23 A0 07 06 23 A2 07 06 23 A4 07 06 23 A6 +07 06 23 A8 07 06 23 AA 07 06 B7 86 03 10 DC 42 +89 8B F5 DF 03 C6 1B 00 85 47 63 19 F6 14 DC 42 +93 F7 C7 3F 63 84 07 2C 89 47 63 E6 E7 2C 83 26 +0B 00 B7 0A 03 10 89 47 23 AC DA 00 83 26 4B 00 +23 AE DA 00 83 26 8B 00 23 A0 DA 02 83 26 CB 00 +23 A2 DA 02 83 26 0B 01 23 A4 DA 02 83 26 4B 01 +23 A6 DA 02 83 26 8B 01 23 A8 DA 02 83 26 CB 01 +23 AA DA 02 83 26 0B 02 23 AC DA 02 83 26 4B 02 +23 AE DA 02 83 26 8B 02 23 A0 DA 04 83 26 CB 02 +23 A2 DA 04 83 26 0B 03 23 A4 DA 04 83 26 4B 03 +23 A6 DA 04 83 26 8B 03 23 A8 DA 04 83 26 CB 03 +23 AA DA 04 63 ED E7 16 85 47 23 A8 FA 00 03 C7 +2B 00 63 07 07 0E 37 87 03 10 1C C3 37 47 02 50 +13 07 07 8B 34 47 7C 47 D5 8F 91 EF 73 00 50 10 +93 07 40 06 01 00 FD 17 C2 07 C1 83 E5 FF 3C 47 +74 47 D5 8F E5 D7 03 A5 49 5A 09 44 63 64 A4 08 +63 16 0A 0C B7 46 03 10 26 84 81 45 85 8E 13 06 +80 4C 39 A0 93 95 07 01 C1 81 11 04 63 88 C5 0C +B3 87 86 00 84 43 18 40 93 87 15 00 E3 04 97 FE +63 15 05 14 05 45 EF B0 DF A8 01 A0 83 A6 4B 00 +B4 CF 83 A6 8B 00 F4 CF 83 A6 CB 00 B4 D3 83 A6 +0B 01 F4 D3 83 A6 4B 01 B4 D7 83 A6 8B 01 F4 D7 +83 A6 CB 01 B4 DB 83 A6 0B 02 F4 DB 89 47 E3 F0 +E7 EC 37 25 02 50 13 05 C5 9D EF B0 9F A6 03 A7 +49 5A 75 B5 6C 47 30 47 25 65 13 05 05 CB EF B0 +5F A7 63 1D 0A 02 03 A5 49 5A E3 75 A4 F6 37 25 +02 50 13 05 C5 9F EF B0 DF A3 03 A5 49 5A 99 BF +B7 87 03 10 0D 47 98 C3 11 BF 37 25 02 50 13 05 +05 90 EF B0 1F A2 03 A7 49 5A FD B3 83 C7 1B 00 +81 CF B2 50 22 54 92 54 02 59 F2 49 62 4A D2 4A +42 4B B2 4B 45 61 82 80 03 A5 49 5A 89 47 63 E0 +A7 0C B7 16 03 10 4A 84 81 45 B3 86 26 41 13 06 +80 28 39 A0 93 95 07 01 C1 81 11 04 E3 83 C5 FC +B3 87 86 00 84 43 18 40 93 87 15 00 E3 04 97 FE +83 A7 49 5A C1 EF 05 45 EF B0 BF 99 01 A0 37 25 +02 50 13 05 C5 9E EF B0 DF 9A 85 47 03 A7 49 5A +23 A8 FA 00 83 C7 2B 00 91 CF B7 87 03 10 80 C3 +89 47 63 FB E7 0A 37 25 02 50 13 05 05 8B EF B0 +5F 98 AD B5 0D 44 D5 B7 37 25 02 50 13 05 C5 92 +EF B0 3F 97 03 A7 49 5A BD B3 25 69 13 09 09 CB +13 05 89 03 EF B0 FF 97 83 A7 49 5A E3 84 07 EA +A6 85 13 05 89 06 EF B0 DF 96 83 A7 49 5A E3 8B +07 E8 0C 40 13 05 09 08 EF B0 BF 95 61 B5 37 25 +02 50 13 05 C5 A1 EF B0 DF 92 25 BF 25 69 13 09 +09 CB 13 05 89 09 EF B0 DF 93 83 A7 49 5A A1 DF +A6 85 13 05 89 0C EF B0 DF 92 83 A7 49 5A A1 D7 +0C 40 13 05 09 0E EF B0 DF 91 35 BF 15 EB 05 45 +EF B0 3F 8D 01 A0 37 25 02 50 13 05 05 95 EF B0 +5F 8E 03 A7 49 5A 9D B5 37 47 02 50 13 07 07 8B +3C 47 74 47 D5 8F E3 83 07 DC 03 A5 49 5A CD B3 +37 25 02 50 13 05 45 99 EF B0 BF 8B C9 B7 79 71 +4E CE B7 09 02 50 03 A8 49 5A 22 D4 56 CA 5A C8 +5E C6 62 C4 06 D6 26 D2 4A D0 52 CC 89 47 AA 8B +2E 8B 32 8C B6 8A 3A 84 63 E7 07 29 B7 07 03 10 +C4 4B 85 88 F5 DC 03 CA 0B 00 63 0C 0A 06 83 C7 +2B 00 B7 86 03 10 09 47 86 07 93 F7 E7 03 93 E7 +17 00 9C C2 63 60 07 31 B7 07 03 10 23 AC 07 04 +23 AE 07 04 23 A0 07 06 23 A2 07 06 23 A4 07 06 +23 A6 07 06 23 A8 07 06 23 AA 07 06 37 87 03 10 +5C 43 89 8B F5 DF 83 C6 1B 00 85 47 63 9B F6 04 +5C 43 93 F7 C7 3F 63 81 07 30 89 47 63 F3 07 05 +37 25 02 50 13 05 85 A3 EF B0 BF 80 03 A8 49 5A +0D A8 03 A7 4B 00 B8 CF 03 A7 8B 00 F8 CF 03 A7 +CB 00 B8 D3 03 A7 0B 01 F8 D3 03 A7 4B 01 B8 D7 +03 A7 8B 01 F8 D7 03 A7 CB 01 B8 DB 03 A7 0B 02 +F8 DB 03 27 0B 00 37 09 03 10 89 47 23 2C E9 08 +03 27 4B 00 23 2E E9 08 03 27 8B 00 23 20 E9 0A +03 27 CB 00 23 22 E9 0A 03 27 0B 01 23 24 E9 0A +03 27 4B 01 23 26 E9 0A 03 27 8B 01 23 28 E9 0A +03 27 CB 01 23 2A E9 0A 03 27 0B 02 23 2C E9 0A +03 27 4B 02 23 2E E9 0A 03 27 8B 02 23 20 E9 0C +03 27 CB 02 23 22 E9 0C 03 27 0B 03 23 24 E9 0C +03 27 4B 03 23 26 E9 0C 03 27 8B 03 23 28 E9 0C +03 27 CB 03 23 2A E9 0C 03 27 0C 00 23 2C E9 06 +03 27 4C 00 23 2E E9 06 03 27 8C 00 23 20 E9 08 +03 27 CC 00 23 22 E9 08 03 27 0C 01 23 24 E9 08 +03 27 4C 01 23 26 E9 08 03 27 8C 01 23 28 E9 08 +03 27 CC 01 23 2A E9 08 03 A7 0A 00 23 2C E9 00 +03 A7 4A 00 23 2E E9 00 03 A7 8A 00 23 20 E9 02 +03 A7 CA 00 23 22 E9 02 03 A7 0A 01 23 24 E9 02 +03 A7 4A 01 23 26 E9 02 03 A7 8A 01 23 28 E9 02 +03 A7 CA 01 23 2A E9 02 03 A7 0A 02 23 2C E9 02 +03 A7 4A 02 23 2E E9 02 03 A7 8A 02 23 20 E9 04 +03 A7 CA 02 23 22 E9 04 03 A7 0A 03 23 24 E9 04 +03 A7 4A 03 23 26 E9 04 03 A7 8A 03 23 28 E9 04 +03 A7 CA 03 23 2A E9 04 63 E9 07 0F 91 47 23 28 +F9 00 83 C7 2B 00 D5 CF B7 87 03 10 05 47 98 C3 +37 47 02 50 13 07 07 8B 34 47 7C 47 D5 8F 91 EF +73 00 50 10 93 07 40 06 01 00 FD 17 C2 07 C1 83 +E5 FF 3C 47 74 47 D5 8F E5 D7 83 A6 49 5A 89 47 +63 EC D7 04 63 05 0A 00 83 C7 1B 00 D9 E3 B7 26 +03 10 81 45 81 8E 13 06 50 48 39 A0 93 95 07 01 +C1 81 11 04 63 87 C5 06 B3 87 86 00 84 43 18 40 +93 87 15 00 E3 04 97 FE 83 A7 49 5A CD EF 05 45 +EF B0 2F DE 01 A0 37 25 02 50 13 05 05 90 EF B0 +4F DF 03 A8 49 5A 9D B3 6C 47 30 47 25 65 13 05 +05 CB EF B0 0F E0 63 13 0A 02 03 A7 49 5A 89 47 +E3 FF E7 F8 37 25 02 50 13 05 C5 AE EF B0 6F DC +79 B7 B7 87 03 10 0D 47 98 C3 99 B7 83 C7 1B 00 +E9 DF B2 50 22 54 92 54 02 59 F2 49 62 4A D2 4A +42 4B B2 4B 22 4C 45 61 82 80 37 25 02 50 13 05 +45 AD EF B0 0F D9 91 47 03 A7 49 5A 23 28 F9 00 +83 C7 2B 00 91 CF B7 87 03 10 84 C3 89 47 63 F3 +E7 06 37 25 02 50 13 05 05 8B EF B0 8F D6 CD BD +8D 44 D5 B7 37 25 02 50 13 05 C5 92 EF B0 6F D5 +03 A8 49 5A D5 B9 25 69 13 09 09 CB 13 05 89 0F +EF B0 2F D6 83 A7 49 5A 9D DB A6 85 13 05 49 12 +EF B0 2F D5 83 A7 49 5A E3 83 07 F2 0C 40 13 05 +C9 13 EF B0 0F D4 21 BF 63 10 08 02 05 45 EF B0 +4F CF 01 A0 37 47 02 50 13 07 07 8B 3C 47 74 47 +D5 8F E3 8F 07 E8 7D BD 37 25 02 50 13 05 45 A8 +EF B0 2F CF E1 BF 01 11 4A C8 37 09 02 50 03 28 +49 5A 22 CC 26 CA 4E C6 52 C4 56 C2 06 CE 5A C0 +89 47 AA 84 2E 8A B2 8A B6 89 3A 84 63 E8 07 1D +37 07 03 10 5C 4B 85 8B F5 DF 89 47 63 E7 07 23 +05 67 13 07 07 32 B7 65 03 10 A6 87 33 86 E4 00 +85 8D 94 43 33 87 F5 00 91 07 14 C3 E3 9B C7 FE +89 47 63 EB 07 1F 83 27 0A 00 B7 04 03 10 09 4B +23 AC F4 08 83 27 4A 00 23 AE F4 08 83 27 8A 00 +23 A0 F4 0A 83 27 CA 00 23 A2 F4 0A 83 27 0A 01 +23 A4 F4 0A 83 27 4A 01 23 A6 F4 0A 83 27 8A 01 +23 A8 F4 0A 83 27 CA 01 23 AA F4 0A 83 27 0A 02 +23 AC F4 0A 83 27 4A 02 23 AE F4 0A 83 27 8A 02 +23 A0 F4 0C 83 27 CA 02 23 A2 F4 0C 83 27 0A 03 +23 A4 F4 0C 83 27 4A 03 23 A6 F4 0C 83 27 8A 03 +23 A8 F4 0C 83 27 CA 03 23 AA F4 0C 83 A7 0A 00 +BC DC 83 A7 4A 00 FC DC 83 A7 8A 00 23 A0 F4 08 +83 A7 CA 00 23 A2 F4 08 83 A7 0A 01 23 A4 F4 08 +83 A7 4A 01 23 A6 F4 08 83 A7 8A 01 23 A8 F4 08 +83 A7 CA 01 23 AA F4 08 83 A7 09 00 9C CC 83 A7 +49 00 DC CC 83 A7 89 00 9C D0 83 A7 C9 00 DC D0 +83 A7 09 01 9C D4 83 A7 49 01 DC D4 83 A7 89 01 +9C D8 83 A7 C9 01 DC D8 83 A7 09 02 9C DC 83 A7 +49 02 DC DC 83 A7 89 02 BC C0 83 A7 C9 02 FC C0 +83 A7 09 03 BC C4 83 A7 49 03 FC C4 83 A7 89 03 +BC C8 83 A7 C9 03 FC C8 63 65 0B 0B 23 A8 64 01 +37 47 02 50 13 07 07 8B 34 47 7C 47 D5 8F 91 EF +73 00 50 10 93 07 40 06 01 00 FD 17 C2 07 C1 83 +E5 FF 3C 47 74 47 D5 8F E5 D7 83 27 49 5A 89 44 +63 E7 F4 04 B7 26 03 10 81 45 81 8E 13 06 50 48 +39 A0 93 95 07 01 C1 81 11 04 63 89 C5 0C B3 87 +86 00 84 43 18 40 93 87 15 00 E3 04 97 FE 83 27 +49 5A C9 E7 05 45 EF B0 CF AD 01 A0 37 25 02 50 +13 05 05 8E EF B0 EF AE 03 28 49 5A 15 B5 6C 47 +30 47 25 65 13 05 05 CB EF B0 AF AF 83 27 49 5A +E3 F2 F4 FA 37 25 02 50 13 05 C5 AE EF B0 6F AC +51 BF 37 25 02 50 13 05 45 B2 EF B0 8F AB 83 27 +49 5A 23 A8 64 01 63 7D FB 06 37 25 02 50 13 05 +05 8B EF B0 0F AA 2D BF 37 25 02 50 13 05 85 B1 +EF B0 2F A9 03 28 49 5A FD BB 37 25 02 50 13 05 +85 B0 EF B0 0F A8 03 28 49 5A D9 B3 A5 69 93 89 +09 CB 13 85 49 15 EF B0 CF A8 83 27 49 5A BD D3 +A6 85 13 85 09 18 EF B0 CF A7 83 27 49 5A B9 DB +0C 40 13 85 89 19 EF B0 CF A6 A9 B7 F2 40 62 44 +D2 44 42 49 B2 49 22 4A 92 4A 02 4B 05 61 82 80 +37 47 02 50 13 07 07 8B 34 47 7C 47 D5 8F E3 89 +07 EC CD BD 01 11 22 CC 06 CE 26 CA 4A C8 4E C6 +32 88 36 84 37 07 03 10 5C 4B 85 8B F5 DF 1C 41 +23 2C F7 08 54 41 AE 87 23 2E D7 08 83 28 85 00 +85 66 93 86 06 A2 23 20 17 0B 33 86 D5 00 54 45 +B7 15 03 10 9D 8D 23 22 D7 0A 14 49 23 24 D7 0A +54 49 23 26 D7 0A 14 4D 23 28 D7 0A 54 4D 23 2A +D7 0A 14 51 23 2C D7 0A 54 51 23 2E D7 0A 14 55 +23 20 D7 0C 54 55 23 22 D7 0C 14 59 23 24 D7 0C +54 59 23 26 D7 0C 14 5D 23 28 D7 0C 54 5D 23 2A +D7 0C 94 43 33 87 F5 00 91 07 14 C3 E3 9B C7 FE +05 67 13 07 47 21 B7 25 03 10 C2 87 33 06 E8 00 +B3 85 05 41 94 43 33 87 F5 00 91 07 14 C3 E3 9B +C7 FE 37 09 02 50 83 27 49 5A 89 44 63 E8 F4 12 +B7 07 03 10 0D 47 98 CB 37 47 02 50 13 07 07 8B +34 47 7C 47 D5 8F 9D E3 73 00 50 10 93 07 40 06 +01 00 FD 17 C2 07 C1 83 E5 FF 3C 47 74 47 D5 8F +E5 D7 83 27 49 5A 89 44 63 E8 F4 0C B7 07 03 10 +83 A4 87 0D 18 40 63 19 97 0A 83 A4 C7 0D 58 40 +63 94 E4 14 83 A4 07 0E 18 44 63 92 E4 14 83 A4 +47 0E 58 44 63 96 E4 14 83 A4 87 0E 18 48 63 9E +E4 12 83 A4 C7 0E 58 48 63 96 E4 12 83 A4 07 0F +18 4C 63 96 E4 14 83 A4 47 0F 58 4C 63 94 E4 16 +83 A4 87 0F 18 50 63 9B E4 14 83 A4 C7 0F 5C 50 +63 92 F4 14 B7 07 03 10 83 A4 07 10 18 54 63 97 +E4 12 83 A4 47 10 58 54 63 97 E4 10 83 A4 87 10 +18 58 63 9E E4 0E 83 A4 C7 10 58 58 63 94 E4 10 +83 A4 07 11 18 5C 63 90 E4 0E 83 A4 47 11 5C 5C +BD 45 13 04 C4 03 63 9A 97 00 F2 40 62 44 D2 44 +42 49 B2 49 05 61 82 80 81 45 83 27 49 5A AD E7 +05 45 EF B0 0F 83 01 A0 6C 47 30 47 25 65 13 05 +05 CB EF B0 0F 86 83 27 49 5A E3 F1 F4 F2 37 25 +02 50 13 05 85 B4 EF B0 CF 82 09 BF 37 25 02 50 +13 05 45 B3 EF B0 EF 81 83 27 49 5A 37 07 03 10 +8D 46 14 CB E3 F2 F4 EC 37 25 02 50 13 05 05 8B +EF B0 2F 80 37 47 02 50 13 07 07 8B 34 47 7C 47 +D5 8F E3 8B 07 EA F1 B5 A5 69 93 89 09 CB 13 85 +09 1B EF B0 0F 80 83 27 49 5A D9 D3 A6 85 13 85 +49 1E EF A0 1F FF 83 27 49 5A BD DB 0C 40 13 85 +C9 1F EF A0 1F FE AD B7 11 04 85 45 B9 BF 21 04 +89 45 A1 BF 51 04 95 45 89 BF 41 04 91 45 B1 B7 +31 04 8D 45 99 B7 13 04 84 03 B9 45 3D BF 13 04 +04 03 B1 45 1D BF 13 04 C4 02 AD 45 3D B7 61 04 +99 45 25 B7 13 04 44 03 B5 45 05 B7 13 04 84 02 +A9 45 21 BF 13 04 44 02 A5 45 01 BF 13 04 04 02 +A1 45 21 B7 71 04 9D 45 09 B7 79 71 4A D0 37 09 +02 50 03 28 49 5A 22 D4 52 CC 56 CA 5A C8 5E C6 +06 D6 26 D2 4E CE 89 47 2A 8B 2E 8A B2 8B B6 8A +3A 84 63 EB 07 29 B7 07 03 10 C4 4B 85 88 F5 DC +83 49 0B 00 63 8C 09 06 83 47 2B 00 B7 86 03 10 +09 47 86 07 93 F7 E7 03 93 E7 17 00 9C C2 63 6D +07 31 B7 07 03 10 23 AC 07 04 23 AE 07 04 23 A0 +07 06 23 A2 07 06 23 A4 07 06 23 A6 07 06 23 A8 +07 06 23 AA 07 06 37 87 03 10 5C 43 89 8B F5 DF +83 46 1B 00 85 47 63 9B F6 04 5C 43 93 F7 C7 3F +63 8F 07 30 89 47 63 F3 07 05 37 25 02 50 13 05 +85 A3 EF A0 1F EB 03 28 49 5A 0D A8 03 27 4B 00 +B8 CF 03 27 8B 00 F8 CF 03 27 CB 00 B8 D3 03 27 +0B 01 F8 D3 03 27 4B 01 B8 D7 03 27 8B 01 F8 D7 +03 27 CB 01 B8 DB 03 27 0B 02 F8 DB 83 26 0A 00 +B7 07 03 10 09 47 23 AC D7 10 83 26 4A 00 23 AE +D7 10 83 26 8A 00 23 A0 D7 12 83 26 CA 00 23 A2 +D7 12 83 26 0A 01 23 A4 D7 12 83 26 4A 01 23 A6 +D7 12 83 26 8A 01 23 A8 D7 12 83 26 CA 01 23 AA +D7 12 83 26 0A 02 23 AC D7 12 83 26 4A 02 23 AE +D7 12 83 26 8A 02 23 A0 D7 14 83 26 CA 02 23 A2 +D7 14 83 26 0A 03 23 A4 D7 14 83 26 4A 03 23 A6 +D7 14 83 26 8A 03 23 A8 D7 14 83 26 CA 03 23 AA +D7 14 83 A6 0B 00 B4 DF 83 A6 4B 00 F4 DF 83 A6 +8B 00 23 A0 D7 08 83 A6 CB 00 23 A2 D7 08 83 A6 +0B 01 23 A4 D7 08 83 A6 4B 01 23 A6 D7 08 83 A6 +8B 01 23 A8 D7 08 83 A6 CB 01 23 AA D7 08 63 6A +07 1B 03 A7 0A 00 37 0A 03 10 89 47 23 2C EA 00 +03 A7 4A 00 23 2E EA 00 03 A7 8A 00 23 20 EA 02 +03 A7 CA 00 23 22 EA 02 03 A7 0A 01 23 24 EA 02 +03 A7 4A 01 23 26 EA 02 03 A7 8A 01 23 28 EA 02 +03 A7 CA 01 23 2A EA 02 03 A7 0A 02 23 2C EA 02 +03 A7 4A 02 23 2E EA 02 03 A7 8A 02 23 20 EA 04 +03 A7 CA 02 23 22 EA 04 03 A7 0A 03 23 24 EA 04 +03 A7 4A 03 23 26 EA 04 03 A7 8A 03 23 28 EA 04 +03 A7 CA 03 23 2A EA 04 63 E9 07 0F 93 07 40 02 +23 28 FA 00 83 47 2B 00 C9 CB B7 87 03 10 05 47 +98 C3 37 47 02 50 13 07 07 8B 3C 47 74 47 D5 8F +91 EF 73 00 50 10 93 07 40 06 01 00 FD 17 C2 07 +C1 83 E5 FF 3C 47 74 47 D5 8F E5 D7 83 26 49 5A +89 47 63 E1 D7 06 63 85 09 00 83 47 1B 00 D9 E3 +B7 26 03 10 81 45 81 8E 13 06 50 48 39 A0 93 95 +07 01 C1 81 11 04 63 87 C5 06 B3 87 86 00 84 43 +18 40 93 87 15 00 E3 04 97 FE 83 27 49 5A F1 E7 +05 45 EF A0 1F C8 01 A0 37 25 02 50 13 05 05 90 +EF A0 3F C9 03 28 49 5A B9 BB B7 87 03 10 0D 47 +98 C3 85 BF 6C 47 30 47 25 65 13 05 05 CB EF A0 +5F C9 63 9E 09 00 03 27 49 5A 89 47 E3 FA E7 F8 +37 25 02 50 13 05 C5 AE EF A0 BF C5 51 B7 83 47 +1B 00 F5 D3 B2 50 22 54 92 54 02 59 F2 49 62 4A +D2 4A 42 4B B2 4B 45 61 82 80 37 25 02 50 13 05 +85 B6 EF A0 1F C3 93 07 40 02 03 27 49 5A 23 28 +FA 00 83 47 2B 00 9D C7 B7 87 03 10 84 C3 89 47 +63 FD E7 06 37 25 02 50 13 05 05 8B EF A0 7F C0 +CD BD 37 25 02 50 13 05 C5 9D EF A0 9F BF 03 28 +49 5A 81 B5 8D 44 C9 BF 37 25 02 50 13 05 C5 92 +EF A0 3F BE 03 28 49 5A E9 B9 A5 69 93 89 09 CB +13 85 49 21 EF A0 FF BE 83 27 49 5A E3 82 07 F2 +A6 85 13 85 09 24 EF A0 DF BD 83 27 49 5A E3 89 +07 F0 0C 40 13 85 89 25 EF A0 BF BC 11 B7 63 10 +08 02 05 45 EF A0 FF B7 01 A0 37 47 02 50 13 07 +07 8B 3C 47 74 47 D5 8F E3 85 07 E8 6D B5 37 25 +02 50 13 05 45 A8 EF A0 DF B7 E1 BF 01 11 4A C8 +37 09 02 50 03 28 49 5A 22 CC 26 CA 4E C6 52 C4 +56 C2 06 CE 5A C0 89 47 AA 84 2E 8A B2 8A B6 89 +3A 84 63 E9 07 1D 37 07 03 10 5C 4B 85 8B F5 DF +89 47 63 E9 07 23 05 67 13 07 07 32 B7 65 03 10 +A6 87 33 86 E4 00 85 8D 94 43 33 87 F5 00 91 07 +14 C3 E3 9B C7 FE 89 47 63 ED 07 1F 83 27 0A 00 +B7 04 03 10 09 4B 23 AC F4 10 83 27 4A 00 23 AE +F4 10 83 27 8A 00 23 A0 F4 12 83 27 CA 00 23 A2 +F4 12 83 27 0A 01 23 A4 F4 12 83 27 4A 01 23 A6 +F4 12 83 27 8A 01 23 A8 F4 12 83 27 CA 01 23 AA +F4 12 83 27 0A 02 23 AC F4 12 83 27 4A 02 23 AE +F4 12 83 27 8A 02 23 A0 F4 14 83 27 CA 02 23 A2 +F4 14 83 27 0A 03 23 A4 F4 14 83 27 4A 03 23 A6 +F4 14 83 27 8A 03 23 A8 F4 14 83 27 CA 03 23 AA +F4 14 83 A7 0A 00 BC DC 83 A7 4A 00 FC DC 83 A7 +8A 00 23 A0 F4 08 83 A7 CA 00 23 A2 F4 08 83 A7 +0A 01 23 A4 F4 08 83 A7 4A 01 23 A6 F4 08 83 A7 +8A 01 23 A8 F4 08 83 A7 CA 01 23 AA F4 08 83 A7 +09 00 9C CC 83 A7 49 00 DC CC 83 A7 89 00 9C D0 +83 A7 C9 00 DC D0 83 A7 09 01 9C D4 83 A7 49 01 +DC D4 83 A7 89 01 9C D8 83 A7 C9 01 DC D8 83 A7 +09 02 9C DC 83 A7 49 02 DC DC 83 A7 89 02 BC C0 +83 A7 C9 02 FC C0 83 A7 09 03 BC C4 83 A7 49 03 +FC C4 83 A7 89 03 BC C8 83 A7 C9 03 FC C8 63 66 +0B 0B 93 07 20 02 9C C8 37 47 02 50 13 07 07 8B +34 47 7C 47 D5 8F 91 EF 73 00 50 10 93 07 40 06 +01 00 FD 17 C2 07 C1 83 E5 FF 3C 47 74 47 D5 8F +E5 D7 83 27 49 5A 89 44 63 E7 F4 04 B7 26 03 10 +81 45 81 8E 13 06 50 48 39 A0 93 95 07 01 C1 81 +11 04 63 8A C5 0C B3 87 86 00 84 43 18 40 93 87 +15 00 E3 04 97 FE 83 27 49 5A D1 E7 05 45 EF A0 +5F 96 01 A0 37 25 02 50 13 05 05 8E EF A0 7F 97 +03 28 49 5A 0D B5 6C 47 30 47 25 65 13 05 05 CB +EF A0 3F 98 83 27 49 5A E3 F2 F4 FA 37 25 02 50 +13 05 C5 AE EF A0 FF 94 51 BF 37 25 02 50 13 05 +85 BA EF A0 1F 94 83 27 49 5A 13 07 20 02 98 C8 +63 7D FB 06 37 25 02 50 13 05 05 8B EF A0 7F 92 +25 BF 37 25 02 50 13 05 45 B9 EF A0 9F 91 03 28 +49 5A ED BB 37 25 02 50 13 05 85 B0 EF A0 7F 90 +03 28 49 5A C9 B3 A5 69 93 89 09 CB 13 85 09 27 +EF A0 3F 91 83 27 49 5A B5 D3 A6 85 13 85 C9 29 +EF A0 3F 90 83 27 49 5A B1 DB 0C 40 13 85 49 2B +EF A0 3F 8F A1 B7 F2 40 62 44 D2 44 42 49 B2 49 +22 4A 92 4A 02 4B 05 61 82 80 37 47 02 50 13 07 +07 8B 34 47 7C 47 D5 8F E3 88 07 EC C5 BD 01 11 +22 CC 26 CA 4E C6 52 C4 06 CE 4A C8 AA 84 AE 89 +32 8A 36 84 37 07 03 10 5C 4B 85 8B F5 DF 37 09 +02 50 03 25 49 5A 89 47 63 E7 A7 20 9C 40 37 07 +03 10 23 2C F7 10 D4 40 CE 87 23 2E D7 10 8C 44 +85 66 93 86 06 A2 23 20 B7 12 33 86 D9 00 D4 44 +B7 15 03 10 B3 85 35 41 23 22 D7 12 94 48 23 24 +D7 12 D4 48 23 26 D7 12 94 4C 23 28 D7 12 D4 4C +23 2A D7 12 94 50 23 2C D7 12 D4 50 23 2E D7 12 +94 54 23 20 D7 14 D4 54 23 22 D7 14 94 58 23 24 +D7 14 D4 58 23 26 D7 14 94 5C 23 28 D7 14 D4 5C +23 2A D7 14 94 43 33 87 F5 00 91 07 14 C3 E3 9B +C7 FE 05 67 13 07 47 21 B7 25 03 10 D2 87 33 06 +EA 00 B3 85 45 41 94 43 33 87 F5 00 91 07 14 C3 +E3 9B C7 FE 89 44 63 EA A4 12 B7 07 03 10 13 07 +30 02 98 CB 37 47 02 50 13 07 07 8B 3C 47 74 47 +D5 8F 91 EF 73 00 50 10 93 07 40 06 01 00 FD 17 +C2 07 C1 83 E5 FF 3C 47 74 47 D5 8F E5 D7 83 27 +49 5A 89 44 63 E9 F4 0C B7 07 03 10 83 A4 87 0D +18 40 63 1A 97 0A 83 A4 C7 0D 58 40 63 96 E4 14 +83 A4 07 0E 18 44 63 97 E4 16 83 A4 47 0E 58 44 +63 9F E4 14 83 A4 87 0E 18 48 63 97 E4 14 83 A4 +C7 0E 58 48 63 9F E4 12 83 A4 07 0F 18 4C 63 96 +E4 14 83 A4 47 0F 58 4C 63 98 E4 14 83 A4 87 0F +18 50 63 9F E4 12 83 A4 C7 0F 5C 50 63 9D F4 14 +B7 07 03 10 83 A4 07 10 18 54 63 92 E4 14 83 A4 +47 10 58 54 63 99 E4 12 83 A4 87 10 18 58 63 90 +E4 12 83 A4 C7 10 58 58 63 9B E4 12 83 A4 07 11 +18 5C 63 9A E4 12 83 A4 47 11 5C 5C BD 45 13 04 +C4 03 63 9B 97 00 F2 40 62 44 D2 44 42 49 B2 49 +22 4A 05 61 82 80 81 45 83 27 49 5A B5 E7 05 45 +EF A0 2F EA 01 A0 6C 47 30 47 25 65 13 05 05 CB +EF A0 2F ED 83 27 49 5A E3 F0 F4 F2 37 25 02 50 +13 05 85 B4 EF A0 EF E9 01 BF 37 25 02 50 13 05 +C5 BC EF A0 0F E9 83 27 49 5A 37 07 03 10 93 06 +30 02 14 CB 63 FD F4 04 37 25 02 50 13 05 05 8B +EF A0 2F E7 45 BD 37 25 02 50 13 05 45 B9 EF A0 +4F E6 03 25 49 5A DD B3 A5 69 93 89 09 CB 13 85 +C9 2C EF A0 0F E7 83 27 49 5A D1 D3 A6 85 13 85 +89 2F EF A0 0F E6 83 27 49 5A B5 DB 0C 40 13 85 +09 31 EF A0 0F E5 A5 B7 11 04 85 45 B1 BF 37 47 +02 50 13 07 07 8B 34 47 7C 47 D5 8F E3 84 07 E6 +61 B5 51 04 95 45 89 B7 41 04 91 45 35 BF 31 04 +8D 45 1D BF 21 04 89 45 05 BF 61 04 99 45 2D B7 +13 04 04 02 A1 45 0D B7 71 04 9D 45 31 BF 13 04 +04 03 B1 45 11 BF 13 04 C4 02 AD 45 31 B7 13 04 +84 02 A9 45 11 B7 13 04 44 02 A5 45 F5 BD 13 04 +44 03 B5 45 D5 BD 13 04 84 03 B9 45 F5 B5 B7 07 +02 50 03 A7 47 5A 41 11 22 C4 06 C6 89 47 2A 84 +63 E9 E7 02 37 07 03 10 5C 4B 85 8B F5 DF 13 05 +B0 09 EF A0 0F D7 83 47 24 00 B2 40 22 44 86 07 +93 F7 E7 03 93 E7 17 00 37 87 03 10 1C C3 41 01 +82 80 37 25 02 50 13 05 05 8E EF A0 8F D6 D9 B7 +52 65 63 65 69 76 65 64 20 4D 4C 44 53 41 20 6E +6F 74 69 66 2F 20 65 72 72 20 69 6E 74 72 20 77 +69 74 68 20 73 74 61 74 75 73 20 3D 20 25 64 2F +20 25 64 0A 00 00 00 00 41 74 20 6F 66 66 73 65 +74 20 5B 25 64 5D 2C 20 6D 6C 64 73 61 5F 70 72 +69 76 6B 65 79 20 64 61 74 61 20 6D 69 73 6D 61 +74 63 68 21 0A 00 00 00 41 63 74 75 61 6C 20 20 +20 64 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +45 78 70 65 63 74 65 64 20 64 61 74 61 3A 20 30 +78 25 78 0A 00 00 00 00 41 74 20 6F 66 66 73 65 +74 20 5B 25 64 5D 2C 20 6D 6C 64 73 61 5F 70 75 +62 6B 65 79 20 64 61 74 61 20 6D 69 73 6D 61 74 +63 68 21 0A 00 00 00 00 41 63 74 75 61 6C 20 20 +20 64 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +45 78 70 65 63 74 65 64 20 64 61 74 61 3A 20 30 +78 25 78 0A 00 00 00 00 41 74 20 6F 66 66 73 65 +74 20 5B 25 64 5D 2C 20 6D 6C 64 73 61 5F 73 69 +67 6E 20 64 61 74 61 20 6D 69 73 6D 61 74 63 68 +21 0A 00 00 41 63 74 75 61 6C 20 20 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 45 78 70 65 +63 74 65 64 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 41 74 20 6F 66 66 73 65 74 20 5B 25 +64 5D 2C 20 6D 6C 64 73 61 5F 73 69 67 6E 20 64 +61 74 61 20 6D 69 73 6D 61 74 63 68 21 0A 00 00 +41 63 74 75 61 6C 20 20 20 64 61 74 61 3A 20 30 +78 25 78 0A 00 00 00 00 45 78 70 65 63 74 65 64 +20 64 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +41 74 20 6F 66 66 73 65 74 20 5B 25 64 5D 2C 20 +6D 6C 64 73 61 5F 76 65 72 69 66 79 5F 72 65 73 +20 64 61 74 61 20 6D 69 73 6D 61 74 63 68 21 0A +00 00 00 00 41 63 74 75 61 6C 20 20 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 45 78 70 65 +63 74 65 64 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 41 74 20 6F 66 66 73 65 74 20 5B 25 +64 5D 2C 20 6D 6C 64 73 61 5F 73 69 67 6E 20 64 +61 74 61 20 6D 69 73 6D 61 74 63 68 21 0A 00 00 +41 63 74 75 61 6C 20 20 20 64 61 74 61 3A 20 30 +78 25 78 0A 00 00 00 00 45 78 70 65 63 74 65 64 +20 64 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +41 74 20 6F 66 66 73 65 74 20 5B 25 64 5D 2C 20 +6D 6C 64 73 61 5F 73 69 67 6E 20 64 61 74 61 20 +6D 69 73 6D 61 74 63 68 21 0A 00 00 41 63 74 75 +61 6C 20 20 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 45 78 70 65 63 74 65 64 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 41 74 20 6F +66 66 73 65 74 20 5B 25 64 5D 2C 20 61 63 74 75 +61 6C 5F 64 61 74 61 20 64 61 74 61 20 6D 69 73 +6D 61 74 63 68 21 0A 00 41 63 74 75 61 6C 20 20 +20 64 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +45 78 70 65 63 74 65 64 20 64 61 74 61 3A 20 30 +78 25 78 0A 00 00 00 00 41 11 22 C4 37 04 02 50 +03 27 44 5A 06 C6 89 47 63 E0 E7 04 37 47 02 50 +13 07 07 8B 3C 47 74 47 D5 8F 9D E3 73 00 50 10 +93 07 40 06 01 00 FD 17 C2 07 C1 83 E5 FF 3C 47 +74 47 D5 8F E5 D7 83 26 44 5A 89 47 63 E5 D7 02 +B2 40 22 44 41 01 82 80 37 25 02 50 13 05 05 BF +EF A0 2F 9E 37 47 02 50 13 07 07 8B 3C 47 74 47 +D5 8F CD DF C9 BF 22 44 6C 47 B2 40 30 47 2D 65 +13 05 85 78 41 01 6F A0 CF 9D 41 11 26 C2 B7 04 +02 50 83 A7 44 5A 22 C4 06 C6 09 44 63 60 F4 02 +B7 97 03 10 21 47 98 CB 37 97 03 10 5C 4B 85 8B +F5 DF B2 40 22 44 92 44 41 01 82 80 37 25 02 50 +13 05 05 C1 EF A0 EF 97 83 A7 44 5A 37 97 03 10 +A1 46 14 CB E3 7A F4 FC 37 25 02 50 13 05 C5 C2 +EF A0 2F 96 D1 B7 19 CA 0A 06 33 87 C5 00 9C 41 +91 05 11 05 23 2E F5 FE E3 9B E5 FE 82 80 79 71 +4E CE B7 09 02 50 03 A7 49 5A 22 D4 52 CC 5A C8 +5E C6 06 D6 26 D2 4A D0 56 CA 62 C4 89 47 2A 8B +AE 8B 32 84 36 8A 63 E5 E7 22 37 99 03 10 83 24 +49 01 85 88 ED DC 83 4A 0B 00 83 47 2B 00 63 88 +0A 16 86 07 93 F7 E7 03 93 E7 17 00 B7 C6 03 10 +9C C2 09 4C 63 61 EC 2A 23 2C 09 00 23 2E 09 00 +23 20 09 02 23 22 09 02 23 24 09 02 23 26 09 02 +23 28 09 02 23 2A 09 02 B7 97 03 10 23 AC 07 02 +23 AE 07 02 23 A0 07 04 23 A2 07 04 23 A4 07 04 +23 A6 07 04 23 A8 07 04 23 AA 07 04 B7 C6 03 10 +DC 42 89 8B F5 DF 03 46 1B 00 85 47 63 11 F6 18 +DC 42 93 F7 C7 3F 63 84 07 2E 89 47 63 E6 E7 2E +03 A6 0B 00 B7 07 03 10 89 46 90 CF 03 A6 4B 00 +D0 CF 03 A6 8B 00 90 D3 03 A6 CB 00 D0 D3 03 A6 +0B 01 90 D7 03 A6 4B 01 D0 D7 03 A6 8B 01 90 DB +03 A6 CB 01 D0 DB 03 A6 0B 02 90 DF 03 A6 4B 02 +D0 DF 03 A6 8B 02 B0 C3 03 A6 CB 02 F0 C3 03 A6 +0B 03 B0 C7 03 A6 4B 03 F0 C7 03 A6 8B 03 B0 CB +03 A6 CB 03 F0 CB 63 EE E6 12 37 97 03 10 85 47 +1C CB 03 47 2B 00 63 08 07 10 37 C7 03 10 1C C3 +37 47 02 50 13 07 07 8B 34 47 7C 47 D5 8F 91 EF +73 00 50 10 93 07 40 06 01 00 FD 17 C2 07 C1 83 +E5 FF 3C 47 74 47 D5 8F E5 D7 83 A7 49 5A 89 44 +63 E5 F4 12 B7 B6 03 10 81 45 81 8E 13 06 80 18 +39 A0 93 95 07 01 C1 81 11 04 63 89 C5 1A B3 87 +86 00 84 43 18 40 93 87 15 00 E3 04 97 FE 83 A7 +49 5A 63 9E 07 10 05 45 EF 90 BF F7 01 A0 83 27 +4B 00 23 2C F9 00 83 27 8B 00 23 2E F9 00 83 27 +CB 00 23 20 F9 02 83 27 0B 01 23 22 F9 02 83 27 +4B 01 23 24 F9 02 83 27 8B 01 23 26 F9 02 83 27 +CB 01 23 28 F9 02 83 27 0B 02 23 2A F9 02 83 27 +4B 02 23 2C F9 02 83 27 8B 02 23 2E F9 02 83 27 +CB 02 23 20 F9 04 83 27 0B 03 23 22 F9 04 83 27 +4B 03 23 24 F9 04 83 27 8B 03 23 26 F9 04 83 27 +CB 03 23 28 F9 04 83 27 0B 04 23 2A F9 04 89 47 +E3 F8 E7 E8 37 25 02 50 13 05 05 D5 EF 90 7F F0 +03 A7 49 5A B5 BD B7 C7 03 10 0D 47 98 C3 CD BD +37 25 02 50 13 05 85 C4 EF 90 BF EE 03 A7 49 5A +E9 B3 37 25 02 50 13 05 05 D7 EF 90 9F ED B7 97 +03 10 85 46 03 A7 49 5A 94 CB 83 47 2B 00 B5 CB +B7 C7 03 10 84 C3 89 47 63 F9 E7 12 37 25 02 50 +13 05 05 BF EF 90 FF EA 65 B5 6C 47 30 47 2D 65 +13 05 85 78 EF 90 FF EB 83 A7 49 5A E3 F4 F4 EC +37 25 02 50 13 05 05 D9 EF 90 BF E8 65 BD 2D 69 +13 09 89 78 13 05 89 03 EF 90 BF E9 83 A7 49 5A +E3 8B 07 EC A6 85 13 05 C9 06 EF 90 9F E8 83 A7 +49 5A E3 82 07 EC 0C 40 13 05 49 08 EF 90 7F E7 +5D BD 8D 44 71 B7 37 25 02 50 13 05 C5 C6 EF 90 +5F E4 03 A7 49 5A 23 2C 09 00 23 2E 09 00 23 20 +09 02 23 22 09 02 23 24 09 02 23 26 09 02 23 28 +09 02 23 2A 09 02 E3 79 EC D4 37 25 02 50 13 05 +85 C9 EF 90 1F E1 03 A7 49 5A 3D BB 63 95 0A 04 +03 A7 49 5A 89 47 63 E4 E7 0C B7 A7 03 10 81 45 +B3 87 47 41 93 06 80 31 39 A0 93 15 07 01 C1 81 +11 0A 63 82 D5 02 33 87 47 01 04 43 03 26 0A 00 +13 87 15 00 E3 03 96 FE 83 A7 49 5A A5 E3 05 45 +EF 90 3F DA 01 A0 B2 50 22 54 92 54 02 59 F2 49 +62 4A D2 4A 42 4B B2 4B 22 4C 45 61 82 80 05 EB +05 45 EF 90 1F D8 01 A0 37 25 02 50 13 05 45 CC +EF 90 3F D9 03 A7 49 5A 9D BD 37 47 02 50 13 07 +07 8B 34 47 7C 47 D5 8F E3 84 07 D8 65 B3 37 25 +02 50 13 05 85 D0 EF 90 DF D6 D9 B7 2D 64 13 04 +84 78 13 05 C4 09 EF 90 DF D7 83 A7 49 5A C1 DB +A6 85 13 05 04 0D EF 90 DF D6 83 A7 49 5A C1 D3 +83 25 0A 00 13 05 84 0E EF 90 BF D5 8D BF 37 25 +02 50 13 05 45 DB EF 90 DF D2 05 BF 79 71 4A D0 +37 09 02 50 03 27 49 5A 22 D4 52 CC 5A C8 5E C6 +06 D6 26 D2 4E CE 56 CA 62 C4 89 47 2A 8B AE 8B +32 84 36 8A 63 E1 E7 30 B7 9A 03 10 83 A4 4A 01 +85 88 ED DC 83 49 0B 00 63 8B 09 24 83 47 2B 00 +B7 C6 03 10 09 4C 86 07 93 F7 E7 03 93 E7 17 00 +9C C2 63 64 EC 38 23 AC 0A 00 23 AE 0A 00 23 A0 +0A 02 23 A2 0A 02 23 A4 0A 02 23 A6 0A 02 23 A8 +0A 02 23 AA 0A 02 B7 97 03 10 23 AC 07 02 23 AE +07 02 23 A0 07 04 23 A2 07 04 23 A4 07 04 23 A6 +07 04 23 A8 07 04 23 AA 07 04 B7 C6 03 10 DC 42 +89 8B F5 DF 03 46 1B 00 85 47 63 0E F6 3A 89 47 +63 FA E7 00 37 25 02 50 13 05 85 DD EF 90 7F C6 +03 27 49 5A B7 97 03 10 83 AA 87 01 63 96 0A 3E +94 4F 83 AA C7 01 63 94 0A 46 D4 4F 83 AA 07 02 +63 91 0A 46 94 53 83 AA 47 02 63 9E 0A 44 D4 53 +83 AA 87 02 63 9B 0A 44 94 57 83 AA C7 02 63 9C +0A 42 D4 57 83 AA 07 03 63 99 0A 42 94 5B 83 AA +47 03 9D 45 63 93 0A 3A DC 5B 89 47 63 E2 E7 30 +B7 97 03 10 83 AA 87 03 63 92 0A 38 94 5F 83 AA +C7 03 63 9E 0A 40 D4 5F 83 AA 07 04 63 9B 0A 40 +B4 43 83 AA 47 04 63 98 0A 40 F4 43 83 AA 87 04 +63 95 0A 40 B4 47 83 AA C7 04 63 92 0A 40 F4 47 +83 AA 07 05 63 90 0A 3C B4 4B 83 AA 47 05 9D 45 +63 9F 0A 32 FC 4B 89 47 63 EE E7 18 03 A6 0B 00 +B7 07 03 10 89 46 90 CF 03 A6 4B 00 D0 CF 03 A6 +8B 00 90 D3 03 A6 CB 00 D0 D3 03 A6 0B 01 90 D7 +03 A6 4B 01 D0 D7 03 A6 8B 01 90 DB 03 A6 CB 01 +D0 DB 03 A6 0B 02 90 DF 03 A6 4B 02 D0 DF 03 A6 +8B 02 B0 C3 03 A6 CB 02 F0 C3 03 A6 0B 03 B0 C7 +03 A6 4B 03 F0 C7 03 A6 8B 03 B0 CB 03 A6 CB 03 +F0 CB 63 EB E6 14 37 97 03 10 85 47 1C CB 03 47 +2B 00 63 0B 07 1A 37 C7 03 10 1C C3 37 47 02 50 +13 07 07 8B 34 47 7C 47 D5 8F 91 EF 73 00 50 10 +93 07 40 06 01 00 FD 17 C2 07 C1 83 E5 FF 3C 47 +74 47 D5 8F E5 D7 03 25 49 5A 89 44 63 E3 A4 18 +B7 B7 03 10 B7 55 FC EF 13 86 07 62 94 43 33 87 +B7 00 22 97 14 C3 91 07 E3 9A C7 FE 89 47 63 91 +09 12 63 EA A7 22 37 B6 03 10 B7 A7 03 10 B7 65 +FC EF 13 06 06 C6 94 43 33 87 B7 00 52 97 14 C3 +91 07 E3 9A C7 FE B2 50 22 54 92 54 02 59 F2 49 +62 4A D2 4A 42 4B B2 4B 22 4C 45 61 82 80 83 27 +4B 00 23 AC FA 00 83 27 8B 00 23 AE FA 00 83 27 +CB 00 23 A0 FA 02 83 27 0B 01 23 A2 FA 02 83 27 +4B 01 23 A4 FA 02 83 27 8B 01 23 A6 FA 02 83 27 +CB 01 23 A8 FA 02 83 27 0B 02 23 AA FA 02 83 27 +4B 02 23 AC FA 02 83 27 8B 02 23 AE FA 02 83 27 +CB 02 23 A0 FA 04 83 27 0B 03 23 A2 FA 04 83 27 +4B 03 23 A4 FA 04 83 27 8B 03 23 A6 FA 04 83 27 +CB 03 23 A8 FA 04 83 27 0B 04 23 AA FA 04 89 47 +E3 F6 E7 E6 37 25 02 50 13 05 05 D5 EF 90 7F A0 +03 27 49 5A A1 BD 37 25 02 50 13 05 85 C4 EF 90 +5F 9F 03 27 49 5A CD B9 37 25 02 50 13 05 05 D7 +EF 90 3F 9E B7 97 03 10 85 46 03 27 49 5A 94 CB +83 47 2B 00 F9 CF B7 C7 03 10 84 C3 89 47 63 F2 +E7 20 37 25 02 50 13 05 05 BF EF 90 9F 9B 79 B5 +63 E7 A7 12 B7 A7 03 10 81 45 13 06 80 31 01 A8 +93 15 07 01 9C 43 C1 81 E3 87 C5 EE B6 87 80 43 +13 87 15 00 93 86 47 00 65 D4 83 27 49 5A C1 EF +05 45 EF 90 1F 96 01 A0 B7 C7 03 10 0D 47 98 C3 +B1 B5 6C 47 30 47 2D 65 13 05 85 78 EF 90 7F 98 +03 25 49 5A E3 F6 A4 E6 37 25 02 50 13 05 05 E3 +EF 90 3F 95 03 25 49 5A A1 BD 37 25 02 50 13 05 +C5 C6 EF 90 1F 94 03 27 49 5A 23 AC 0A 00 23 AE +0A 00 23 A0 0A 02 23 A2 0A 02 23 A4 0A 02 23 A6 +0A 02 23 A8 0A 02 23 AA 0A 02 E3 76 EC C6 37 25 +02 50 13 05 85 C9 EF 90 DF 90 03 27 49 5A A1 B9 +37 25 02 50 13 05 45 E0 EF 90 BF 8F 03 27 49 5A +C5 B9 8D 44 0D B7 AD 64 93 84 84 78 13 85 04 1C +EF 90 3F 90 83 27 49 5A A1 DF A2 85 13 85 C4 1E +EF 90 3F 8F 83 27 49 5A A1 D7 81 45 13 85 44 20 +EF 90 3F 8E 35 BF DC 42 93 F7 C7 3F 85 C7 89 47 +E3 FA E7 C4 37 25 02 50 13 05 45 CC EF 90 7F 8A +03 27 49 5A 2D B1 37 25 02 50 13 05 05 E5 EF 90 +5F 89 D1 B3 51 EB 05 45 EF 90 BF 86 01 A0 37 25 +02 50 13 05 05 E7 EF 90 DF 87 E9 B5 81 45 19 EB +05 45 EF 90 1F 85 01 A0 81 45 0D EF 05 45 EF 90 +5F 84 01 A0 2D 64 13 04 84 78 13 05 04 16 EF 90 +5F 87 83 27 49 5A E9 DF D6 85 13 05 04 19 EF 90 +5F 86 83 27 49 5A E9 D7 81 45 13 05 84 1A EF 90 +5F 85 7D BF 2D 64 13 04 84 78 13 05 04 10 EF 90 +5F 84 83 27 49 5A DD DB D6 85 13 05 04 13 EF 90 +5F 83 83 27 49 5A DD D3 81 45 13 05 84 14 EF 90 +5F 82 69 BF 99 45 61 B7 37 25 02 50 13 05 85 D0 +EF 90 2F FF 8D B7 95 45 49 B7 99 45 BD BF 85 45 +AD BF 89 45 9D BF 8D 45 8D BF 91 45 BD B7 85 45 +B9 BF 89 45 A9 BF 8D 45 99 BF 91 45 89 BF 95 45 +B9 B7 37 47 02 50 13 07 07 8B 3C 47 74 47 D5 8F +E3 8E 07 C8 85 B5 79 71 4A D0 37 09 02 50 03 28 +49 5A 22 D4 4E CE 52 CC 5A C8 5E C6 06 D6 26 D2 +56 CA 62 C4 89 47 83 4A 07 00 3A 8A 2A 8B AE 89 +B2 8B 36 84 63 EE 07 27 B7 97 03 10 C4 4B 85 88 +F5 DC 89 47 63 E4 07 29 B7 B5 03 10 DA 87 13 06 +0B 62 B3 85 65 41 94 43 33 87 F5 00 91 07 14 C3 +E3 9B C7 FE 03 CB 09 00 63 09 0B 10 83 C7 29 00 +37 C7 03 10 09 4C 86 07 93 F7 E7 03 93 E7 17 00 +1C C7 63 66 0C 2F B7 97 03 10 23 A0 07 08 23 A2 +07 08 23 A4 07 08 23 A6 07 08 23 A8 07 08 23 AA +07 08 23 AC 07 08 23 AE 07 08 B7 77 03 10 23 A0 +07 2A 23 A2 07 2A 23 A4 07 2A 23 A6 07 2A 23 A8 +07 2A 23 AA 07 2A 23 AC 07 2A 23 AE 07 2A 23 A0 +07 2C 37 C7 03 10 5C 47 89 8B F5 DF 83 C6 19 00 +85 47 63 8D F6 2C 89 47 63 FA 07 01 37 25 02 50 +13 05 85 FC EF 90 EF EB 03 28 49 5A B7 97 03 10 +03 AC 07 08 63 13 0C 30 03 A7 07 08 03 AC 47 08 +63 14 0C 56 03 A7 47 08 03 AC 87 08 63 10 0C 56 +03 A7 87 08 03 AC C7 08 63 1C 0C 54 03 A7 C7 08 +03 AC 07 09 63 11 0C 4A 03 A7 07 09 03 AC 47 09 +63 1D 0C 48 03 A7 47 09 03 AC 87 09 63 19 0C 48 +03 A7 87 09 03 AC C7 09 9D 45 63 19 0C 2A 83 A7 +C7 09 89 47 63 F0 07 07 37 25 02 50 13 05 45 FF +EF 90 2F E4 03 28 49 5A B1 A0 03 A7 49 00 B7 97 +03 10 23 A0 E7 08 03 A7 89 00 23 A2 E7 08 03 A7 +C9 00 23 A4 E7 08 03 A7 09 01 23 A6 E7 08 03 A7 +49 01 23 A8 E7 08 03 A7 89 01 23 AA E7 08 03 A7 +C9 01 23 AC E7 08 03 A7 09 02 23 AE E7 08 89 47 +E3 E4 07 FB 03 A7 0B 00 B7 07 03 10 09 4C 98 CF +03 A7 4B 00 D8 CF 03 A7 8B 00 98 D3 03 A7 CB 00 +D8 D3 03 A7 0B 01 98 D7 03 A7 4B 01 D8 D7 03 A7 +8B 01 98 DB 03 A7 CB 01 D8 DB 03 A7 0B 02 98 DF +03 A7 4B 02 D8 DF 03 A7 8B 02 B8 C3 03 A7 CB 02 +F8 C3 03 A7 0B 03 B8 C7 03 A7 4B 03 F8 C7 03 A7 +8B 03 B8 CB 03 A7 CB 03 F8 CB 63 6A 0C 0B B7 97 +03 10 23 A8 87 01 83 C7 29 00 C1 C7 B7 C7 03 10 +05 47 98 C7 37 47 02 50 13 07 07 8B 34 47 7C 47 +D5 8F 91 EF 73 00 50 10 93 07 40 06 01 00 FD 17 +C2 07 C1 83 E5 FF 3C 47 74 47 D5 8F E5 D7 03 25 +49 5A 89 44 63 E1 A4 0A B7 C6 03 10 93 86 06 80 +81 45 81 8E 13 06 80 18 39 A0 93 95 07 01 C1 81 +11 04 63 85 C5 14 B3 87 86 00 84 43 18 40 93 87 +15 00 E3 04 97 FE 41 ED 05 45 EF 90 8F CE 01 A0 +37 25 02 50 13 05 85 E9 EF 90 AF CF 03 28 49 5A +A5 BB B7 C7 03 10 0D 47 98 C7 AD BF 37 25 02 50 +13 05 C5 EB EF 90 EF CD 03 28 49 5A B5 B3 37 25 +02 50 13 05 45 01 EF 90 CF CC B7 97 03 10 03 27 +49 5A 23 A8 87 01 83 C7 29 00 DD CF B7 C7 03 10 +84 C7 89 47 63 FF E7 2C 37 25 02 50 13 05 05 BF +EF 90 2F CA 05 BF 6C 47 30 47 2D 65 13 05 85 78 +EF 90 2F CB 03 25 49 5A E3 F8 A4 F4 37 25 02 50 +13 05 45 03 EF 90 EF C7 03 25 49 5A 35 BF AD 69 +93 89 89 78 13 85 89 27 EF 90 AF C8 83 27 49 5A +A1 DF A6 85 13 85 C9 2A EF 90 AF C7 83 27 49 5A +A1 D7 0C 40 13 85 49 2C EF 90 AF C6 35 BF 37 25 +02 50 13 05 05 EE EF 90 CF C3 B7 97 03 10 03 28 +49 5A 23 A0 07 08 23 A2 07 08 23 A4 07 08 23 A6 +07 08 23 A8 07 08 23 AA 07 08 23 AC 07 08 23 AE +07 08 E3 74 0C D1 37 25 02 50 13 05 45 F0 EF 90 +4F C0 03 28 49 5A D5 B9 8D 44 89 B7 5C 47 93 F7 +C7 3F B9 CB 89 47 E3 FB 07 D3 37 25 02 50 13 05 +05 F4 EF 90 0F BE 03 28 49 5A 31 B3 63 84 0A 04 +B7 C7 03 10 D8 4B 09 8B 75 DF DC 4B 83 46 1A 00 +05 47 93 F7 C7 3F 63 89 E6 22 63 85 07 20 63 1C +05 1E 05 45 EF 90 EF B8 01 A0 81 45 63 13 08 08 +05 45 EF 90 0F B8 01 A0 63 15 08 0A 05 45 EF 90 +4F B7 01 A0 89 47 63 15 0B 0A 63 EC A7 12 B7 97 +03 10 A4 4F 03 24 4A 00 63 13 94 12 E4 4F 03 24 +8A 00 63 1C 94 10 A4 53 03 24 CA 00 63 95 84 10 +E4 53 03 24 0A 01 63 1E 94 0E A4 57 03 24 4A 01 +63 97 84 0E E4 57 03 24 8A 01 63 90 84 0E A4 5B +03 24 CA 01 63 99 84 0C E4 5B 03 24 0A 02 9D 45 +63 0F 94 06 83 27 49 5A D9 E7 05 45 EF 90 6F B0 +01 A0 2D 64 13 04 84 78 13 05 C4 21 EF 90 6F B3 +83 27 49 5A B5 D7 E2 85 13 05 84 24 EF 90 6F B2 +83 27 49 5A B1 DF 81 45 13 05 04 26 EF 90 6F B1 +81 BF 37 25 02 50 13 05 05 F8 EF 90 8F AE B9 B7 +63 EC A7 0E B7 97 03 10 A0 4F 59 E8 E0 4F 63 13 +04 0E A0 53 63 1E 04 0C E0 53 69 E8 A0 57 69 E4 +E0 57 69 E0 A0 5B 4D EC E0 5B 9D 45 3D E8 B2 50 +22 54 92 54 02 59 F2 49 62 4A D2 4A 42 4B B2 4B +22 4C 45 61 82 80 AD 69 93 89 89 78 13 85 C9 2D +EF 90 2F AB 83 27 49 5A AD D3 A6 85 13 85 09 31 +EF 90 2F AA 83 27 49 5A A9 DB A2 85 13 85 89 32 +EF 90 2F A9 99 B7 99 45 35 BF 95 45 25 BF 91 45 +15 BF 8D 45 05 BF 89 45 35 B7 85 45 25 B7 81 45 +15 B7 37 25 02 50 13 05 45 18 EF 90 8F A4 C1 B5 +81 45 83 27 49 5A 89 E7 05 45 EF 90 8F A1 01 A0 +AD 64 93 84 84 78 13 85 04 34 EF 90 8F A4 83 27 +49 5A FD D3 A2 85 13 85 44 37 EF 90 8F A3 83 27 +49 5A F9 DB 81 45 13 85 C4 38 EF 90 8F A2 E9 B7 +99 45 C1 B7 95 45 75 BF 91 45 65 BF 8D 45 55 BF +89 45 45 BF 85 45 75 B7 37 25 02 50 13 05 45 1A +EF 90 2F 9E 01 B7 91 45 15 BD 95 45 05 BD 99 45 +35 B5 37 47 02 50 13 07 07 8B 34 47 7C 47 D5 8F +E3 82 07 C6 91 B3 37 25 02 50 13 05 C5 0E EF 90 +4F 9B 01 B5 89 47 63 E6 A7 04 03 D7 09 00 85 47 +E3 17 F7 EE 83 47 2A 00 37 07 03 30 A2 07 93 E7 +37 0B 23 26 F7 0C E1 BD 85 CF 89 47 E3 F9 A7 EC +22 54 B2 50 92 54 02 59 F2 49 62 4A D2 4A 42 4B +B2 4B 22 4C 37 25 02 50 13 05 45 05 45 61 6F 90 +4F 96 37 25 02 50 13 05 85 13 EF 90 8F 95 75 B7 +09 E5 05 45 EF 90 EF 92 01 A0 37 25 02 50 13 05 +C5 09 EF 90 0F 94 F5 B7 85 45 49 BB 89 45 79 B3 +8D 45 69 B3 79 71 22 D4 37 04 02 50 03 28 44 5A +26 D2 4A D0 52 CC 56 CA 5E C6 66 C2 3A 8A 06 D6 +4E CE 5A C8 62 C4 6A C0 09 47 03 4B 0A 00 83 49 +2A 00 AA 8A AE 84 B2 8C B6 8B 3E 89 63 63 07 2F +B7 97 03 10 03 AC 47 01 13 7C 1C 00 E3 0C 0C FE +89 47 63 E4 07 35 D6 87 37 B6 03 10 93 8A 0A 62 +1D 8E 94 43 33 07 F6 00 91 07 14 C3 E3 9B 57 FF +83 CA 04 00 63 88 0A 10 83 C7 24 00 37 C7 03 10 +09 4D 86 07 93 F7 E7 03 93 E7 17 00 1C C7 63 60 +0D 39 B7 97 03 10 23 A0 07 08 23 A2 07 08 23 A4 +07 08 23 A6 07 08 23 A8 07 08 23 AA 07 08 23 AC +07 08 23 AE 07 08 B7 77 03 10 23 A0 07 2A 23 A2 +07 2A 23 A4 07 2A 23 A6 07 2A 23 A8 07 2A 23 AA +07 2A 23 AC 07 2A 23 AE 07 2A 23 A0 07 2C 37 C7 +03 10 5C 47 89 8B F5 DF 83 C6 14 00 85 47 63 88 +F6 38 89 47 63 FA 07 01 37 25 02 50 13 05 85 FC +EF 90 2F 83 03 28 44 5A B7 97 03 10 03 AD 07 08 +63 17 0D 38 03 A7 07 08 03 AD 47 08 63 11 0D 38 +03 A7 47 08 03 AD 87 08 63 1B 0D 36 03 A7 87 08 +03 AD C7 08 63 15 0D 36 03 A7 C7 08 03 AD 07 09 +63 1F 0D 34 03 A7 07 09 03 AD 47 09 63 19 0D 34 +03 A7 47 09 03 AD 87 09 63 13 0D 34 03 A7 87 09 +03 AD C7 09 63 1D 0D 32 83 A7 C7 09 89 47 63 F8 +07 05 37 25 02 50 13 05 45 FF EF 80 9F FB 03 28 +44 5A 35 A8 D8 40 B7 97 03 10 23 A0 E7 08 98 44 +23 A2 E7 08 D8 44 23 A4 E7 08 98 48 23 A6 E7 08 +D8 48 23 A8 E7 08 98 4C 23 AA E7 08 D8 4C 23 AC +E7 08 98 50 23 AE E7 08 89 47 E3 EC 07 FB 03 A7 +0C 00 B7 07 03 10 98 CF 03 A7 4C 00 D8 CF 03 A7 +8C 00 98 D3 03 A7 CC 00 D8 D3 03 A7 0C 01 98 D7 +03 A7 4C 01 D8 D7 03 A7 8C 01 98 DB 03 A7 CC 01 +D8 DB 03 A7 0C 02 98 DF 03 A7 4C 02 D8 DF 03 A7 +8C 02 B8 C3 03 A7 CC 02 F8 C3 03 A7 0C 03 B8 C7 +03 A7 4C 03 F8 C7 03 A7 8C 03 B8 CB 03 A7 CC 03 +F8 CB 63 14 0B 0A 89 4C 63 EF 0C 0B B7 97 03 10 +23 A8 97 01 83 C7 24 00 63 9E 07 0E B7 C7 03 10 +0D 47 98 C7 37 47 02 50 13 07 07 8B 34 47 7C 47 +D5 8F 91 EF 73 00 50 10 93 07 40 06 01 00 FD 17 +C2 07 C1 83 E5 FF 3C 47 74 47 D5 8F E5 D7 03 25 +44 5A 09 4C 63 6C AC 12 37 C6 03 10 B7 55 FC EF +93 07 06 80 93 85 05 80 13 06 06 E2 94 43 33 87 +B7 00 5E 97 14 C3 91 07 E3 9A C7 FE 63 01 0B 0A +37 C7 03 10 5C 4B 89 8B F5 DF 83 46 1A 00 85 47 +63 8D F6 1E 5C 4B 93 F7 C7 3F 63 81 07 1A 63 11 +05 2A 05 45 EF 80 FF E4 01 A0 93 97 19 00 11 67 +13 07 17 FC 93 F7 F7 0F D9 8F 37 C7 03 10 1C CB +89 4C E3 F5 0C F5 37 25 02 50 13 05 45 1D EF 80 +5F E4 B7 97 03 10 03 27 44 5A 23 A8 97 01 83 C7 +24 00 63 8B 07 14 B7 C7 03 10 23 A4 87 01 89 47 +63 FB E7 26 37 25 02 50 13 05 05 BF EF 80 7F E1 +15 B7 37 25 02 50 13 05 85 E9 EF 80 9F E0 03 28 +44 5A 39 B3 B7 C7 03 10 05 47 98 C7 21 B7 89 47 +63 8A 0A 08 63 EC A7 1A B7 97 03 10 A4 4F 63 9F +04 18 E4 4F 63 91 04 22 A4 53 63 9C 04 20 E4 53 +63 97 04 20 A4 57 63 9C 04 20 E4 57 63 97 04 20 +A4 5B 63 98 04 20 E4 5B 9D 45 63 9A 04 16 B2 50 +22 54 92 54 02 59 F2 49 62 4A D2 4A 42 4B B2 4B +22 4C 92 4C 02 4D 45 61 82 80 37 25 02 50 13 05 +C5 EB EF 80 1F D9 03 28 44 5A 75 B1 6C 47 30 47 +2D 65 13 05 85 78 EF 80 DF D9 03 25 44 5A E3 7D +AC EA 37 25 02 50 13 05 45 1F EF 80 9F D6 03 25 +44 5A 5D B5 63 E5 A7 10 B7 97 03 10 B8 4F 23 20 +E9 00 F8 4F 23 22 E9 00 B8 53 23 24 E9 00 F8 53 +23 26 E9 00 B8 57 23 28 E9 00 F8 57 23 2A E9 00 +B8 5B 23 2C E9 00 FC 5B 23 2E F9 00 8D BF 37 25 +02 50 13 05 05 EE EF 80 DF D1 B7 97 03 10 03 28 +44 5A 23 A0 07 08 23 A2 07 08 23 A4 07 08 23 A6 +07 08 23 A8 07 08 23 AA 07 08 23 AC 07 08 23 AE +07 08 E3 7A 0D C7 37 25 02 50 13 05 45 F0 EF 80 +5F CE 03 28 44 5A 85 B1 0D 4C 75 B5 89 47 63 E1 +A7 0C 03 D7 04 00 85 47 E3 1B F7 F0 93 97 89 00 +93 E7 37 0B 37 07 03 30 23 26 F7 0C 09 B7 5C 47 +93 F7 C7 3F D9 C3 89 47 E3 F0 07 C9 37 25 02 50 +13 05 05 F4 EF 80 FF C9 03 28 44 5A 99 B9 63 18 +08 08 05 45 EF 80 FF C6 01 A0 5C 4B 93 F7 C7 3F +BD C3 89 47 E3 F5 A7 EC 22 54 B2 50 92 54 02 59 +F2 49 62 4A D2 4A 42 4B B2 4B 22 4C 92 4C 02 4D +37 25 02 50 13 05 45 05 45 61 6F 80 9F C5 37 25 +02 50 13 05 05 26 EF 80 DF C4 FD B5 81 45 83 27 +44 5A F1 E3 05 45 EF 80 DF C1 01 A0 37 25 02 50 +13 05 45 1A EF 80 FF C2 81 B5 63 1F 08 08 05 45 +EF 80 3F C0 01 A0 51 E1 05 45 EF 80 9F BF 01 A0 +37 25 02 50 13 05 85 13 EF 80 BF C0 1D BF AD 64 +93 84 84 78 81 45 13 85 44 3A EF 80 9F C1 83 27 +44 5A A5 D3 EA 85 13 85 04 3D EF 80 9F C0 83 27 +44 5A A1 DB 81 45 13 85 84 3E EF 80 9F BF 91 B7 +37 25 02 50 13 05 45 21 EF 80 BF BC 99 BB 8D 45 +BD BF 89 45 AD BF 85 45 9D BF 95 45 8D BF 91 45 +BD B7 99 45 AD B7 37 47 02 50 13 07 07 8B 3C 47 +74 47 D5 8F E3 80 07 CC 1D BD 37 25 02 50 13 05 +C5 09 EF 80 1F B9 8D BF 37 25 02 50 13 05 05 F8 +EF 80 3F B8 A9 BF 2D 69 13 09 89 78 13 05 09 40 +EF 80 3F B9 83 27 44 5A E3 86 07 F2 A6 85 13 05 +49 43 EF 80 1F B8 83 27 44 5A E3 8D 07 F0 81 45 +13 05 C9 44 EF 80 FF B6 31 B7 01 11 22 CC 37 04 +02 50 03 28 44 5A 26 CA 4E C6 52 C4 56 C2 06 CE +4A C8 89 47 03 C9 06 00 B6 84 AA 8A 2E 8A B2 89 +63 E4 07 23 37 97 03 10 5C 4B 85 8B F5 DF 89 47 +63 E3 07 27 05 67 13 07 07 C6 B7 A5 03 10 D6 87 +33 86 EA 00 B3 85 55 41 94 43 33 87 F5 00 91 07 +14 C3 E3 9B C7 FE 37 C6 03 10 13 06 06 80 D2 87 +93 05 0A 62 33 06 46 41 94 43 33 07 F6 00 91 07 +14 C3 E3 9B B7 FE 89 47 63 E6 07 21 03 A7 09 00 +B7 07 03 10 98 CF 03 A7 49 00 D8 CF 03 A7 89 00 +98 D3 03 A7 C9 00 D8 D3 03 A7 09 01 98 D7 03 A7 +49 01 D8 D7 03 A7 89 01 98 DB 03 A7 C9 01 D8 DB +03 A7 09 02 98 DF 03 A7 49 02 D8 DF 03 A7 89 02 +B8 C3 03 A7 C9 02 F8 C3 03 A7 09 03 B8 C7 03 A7 +49 03 F8 C7 03 A7 89 03 B8 CB 03 A7 C9 03 F8 CB +63 0E 09 00 83 C7 24 00 11 67 13 07 17 FC 86 07 +93 F7 F7 0F D9 8F 37 C7 03 10 1C CB 89 49 63 EE +09 15 B7 97 03 10 0D 47 98 CB 37 47 02 50 13 07 +07 8B 34 47 7C 47 D5 8F 91 EF 73 00 50 10 93 07 +40 06 01 00 FD 17 C2 07 C1 83 E5 FF 3C 47 74 47 +D5 8F E5 D7 83 26 44 5A 89 49 63 E8 D9 06 63 09 +09 08 37 C7 03 10 5C 4B 89 8B F5 DF 03 C6 14 00 +85 47 63 03 F6 16 5C 4B 93 F7 C7 3F 63 96 07 14 +89 47 63 E9 D7 1A B7 97 03 10 A4 4F 63 90 04 20 +E4 4F 63 96 04 26 A4 53 63 91 04 26 E4 53 63 9C +04 24 A4 57 63 97 04 24 E4 57 63 92 04 24 A4 5B +63 9D 04 22 E4 5B 9D 45 D9 CC 83 27 44 5A 63 9C +07 1E 05 45 EF 80 FF 97 01 A0 6C 47 30 47 2D 65 +13 05 85 78 EF 80 FF 9A 63 1D 09 0E 83 27 44 5A +63 F8 F9 00 37 25 02 50 13 05 85 46 EF 80 7F 97 +B7 97 03 10 83 A9 87 05 03 A9 44 00 63 9C 29 0F +83 A9 C7 05 03 A9 84 00 63 9C 29 19 83 A9 07 06 +03 A9 C4 00 63 9E 29 17 83 A9 47 06 03 A9 04 01 +63 9A 29 17 83 A9 87 06 03 A9 44 01 63 96 29 17 +83 A9 C7 06 03 A9 84 01 63 92 29 17 83 A9 07 07 +03 A9 C4 01 63 90 29 17 83 A9 47 07 03 A9 04 02 +9D 45 63 12 39 0B F2 40 62 44 D2 44 42 49 B2 49 +22 4A 92 4A 05 61 82 80 37 25 02 50 13 05 05 28 +EF 80 3F 8F 03 28 44 5A F1 B3 37 25 02 50 13 05 +85 2E EF 80 1F 8E 83 27 44 5A 37 97 03 10 8D 46 +14 CB 63 FF F9 0C 37 25 02 50 13 05 05 BF EF 80 +5F 8C 61 B5 37 25 02 50 13 05 85 2C EF 80 7F 8B +03 28 44 5A E5 B3 37 25 02 50 13 05 45 2A EF 80 +5F 8A 03 28 44 5A 79 B3 C9 EE 05 45 EF 80 7F 87 +01 A0 83 26 44 5A 71 B5 5C 4B 93 F7 C7 3F AD CF +89 47 E3 F2 D7 EA 37 25 02 50 13 05 85 30 EF 80 +5F 87 B9 A0 81 45 83 27 44 5A 89 E7 05 45 EF 80 +5F 84 01 A0 AD 64 93 84 84 78 13 85 84 4C EF 80 +5F 87 83 27 44 5A FD D3 CE 85 13 85 C4 4F EF 80 +5F 86 83 27 44 5A F9 DB CA 85 13 85 44 51 EF 80 +5F 85 E9 B7 37 25 02 50 13 05 C5 3E EF 80 7F 82 +03 27 44 5A 89 47 E3 F0 E7 E4 37 25 02 50 13 05 +85 43 EF 80 1F 81 05 BD A1 EA 05 45 EF 80 6F FE +01 A0 37 25 02 50 13 05 05 3A EF 80 8F FF B1 BF +37 47 02 50 13 07 07 8B 34 47 7C 47 D5 8F E3 8E +07 DA 83 26 44 5A E3 1E 09 DC 9D B5 81 45 35 B5 +89 45 95 B7 8D 45 85 B7 91 45 B1 BF 95 45 A1 BF +85 45 91 BF 99 45 81 BF 37 25 02 50 13 05 05 35 +EF 80 2F FB 5D B7 2D 69 13 09 89 78 13 05 49 46 +EF 80 2F FC 83 27 44 5A E3 8D 07 DE A6 85 13 05 +89 49 EF 80 0F FB 83 27 44 5A E3 84 07 DE 81 45 +13 05 09 4B EF 80 EF F9 E9 BB 99 45 F9 B3 95 45 +E9 B3 91 45 D9 B3 8D 45 C9 B3 89 45 7D BB 85 45 +6D BB 01 11 22 CC 37 04 02 50 03 28 44 5A 26 CA +4E C6 52 C4 56 C2 06 CE 4A C8 89 47 03 C9 06 00 +B6 84 AA 8A 2E 8A B2 89 63 E8 07 1B 37 97 03 10 +5C 4B 85 8B F5 DF 89 47 63 E9 07 1B 05 67 13 07 +07 C6 B7 A5 03 10 D6 87 33 86 EA 00 B3 85 55 41 +94 43 33 87 F5 00 91 07 14 C3 E3 9B C7 FE 37 C6 +03 10 13 06 06 80 D2 87 93 05 0A 62 33 06 46 41 +94 43 33 07 F6 00 91 07 14 C3 E3 9B B7 FE 89 47 +63 E3 07 1B 03 A7 09 00 B7 07 03 10 98 CF 03 A7 +49 00 D8 CF 03 A7 89 00 98 D3 03 A7 C9 00 D8 D3 +03 A7 09 01 98 D7 03 A7 49 01 D8 D7 03 A7 89 01 +98 DB 03 A7 C9 01 D8 DB 03 A7 09 02 98 DF 03 A7 +49 02 D8 DF 03 A7 89 02 B8 C3 03 A7 C9 02 F8 C3 +03 A7 09 03 B8 C7 03 A7 49 03 F8 C7 03 A7 89 03 +B8 CB 03 A7 C9 03 F8 CB 63 0E 09 00 83 C7 24 00 +11 67 13 07 17 FC 86 07 93 F7 F7 0F D9 8F 37 C7 +03 10 1C CB 89 49 63 EB 09 0F B7 97 03 10 0D 47 +98 CB 37 47 02 50 13 07 07 8B 34 47 7C 47 D5 8F +91 EF 73 00 50 10 93 07 40 06 01 00 FD 17 C2 07 +C1 83 E5 FF 3C 47 74 47 D5 8F E5 D7 83 26 44 5A +89 49 63 E3 D9 04 63 04 09 06 37 C7 03 10 5C 4B +89 8B F5 DF 03 C6 14 00 85 47 63 07 F6 0E 5C 4B +93 F7 C7 3F E9 EF 89 47 63 FF D7 04 37 25 02 50 +13 05 C5 3E 62 44 F2 40 D2 44 42 49 B2 49 22 4A +92 4A 05 61 6F 80 EF DD 6C 47 30 47 2D 65 13 05 +85 78 EF 80 0F DF 63 11 09 0A 83 27 44 5A 63 F8 +F9 00 37 25 02 50 13 05 C5 51 EF 80 8F DB 37 97 +03 10 34 4F 93 07 C7 05 78 4F D8 43 98 47 D8 47 +98 4B D8 4B 9C 4F F2 40 62 44 D2 44 42 49 B2 49 +22 4A 92 4A 05 61 82 80 37 25 02 50 13 05 05 28 +EF 80 2F D8 03 28 44 5A 91 B5 37 25 02 50 13 05 +45 2A EF 80 0F D7 03 28 44 5A 89 B5 37 25 02 50 +13 05 85 2E EF 80 EF D5 83 27 44 5A 37 97 03 10 +8D 46 14 CB 63 FD F9 04 37 25 02 50 13 05 05 BF +EF 80 2F D4 FD B5 37 25 02 50 13 05 85 2C EF 80 +4F D3 03 28 44 5A B9 B5 83 26 44 5A 39 B7 8D E2 +05 45 EF 80 0F D0 01 A0 5C 4B 93 F7 C7 3F 95 CF +89 47 E3 FA D7 F6 37 25 02 50 13 05 85 48 19 BF +37 25 02 50 13 05 05 3A EF 80 AF CF D1 BF 37 47 +02 50 13 07 07 8B 34 47 7C 47 D5 8F E3 83 07 EA +83 26 44 5A E3 13 09 EC 1D B7 89 E6 05 45 EF 80 +4F CB 01 A0 37 25 02 50 13 05 05 4D EF 80 6F CC +F5 B7 79 71 4A D0 37 09 02 50 03 28 49 5A 4E CE +5E C6 62 C4 66 C2 06 D6 22 D4 26 D2 52 CC 56 CA +5A C8 6A C0 89 47 03 CB 06 00 03 CA 26 00 B6 89 +2A 8C AE 8B B2 8C 63 EE 07 2B B7 94 03 10 C0 48 +05 88 75 DC 83 4A 0C 00 63 8C 0A 08 83 47 2C 00 +37 C7 03 10 09 4D 86 07 93 F7 E7 03 93 E7 17 00 +1C C3 63 6C 0D 39 23 AC 04 00 23 AE 04 00 23 A0 +04 02 23 A2 04 02 23 A4 04 02 23 A6 04 02 23 A8 +04 02 23 AA 04 02 B7 97 03 10 23 AC 07 02 23 AE +07 02 23 A0 07 04 23 A2 07 04 23 A4 07 04 23 A6 +07 04 23 A8 07 04 23 AA 07 04 37 C7 03 10 5C 43 +89 8B F5 DF 83 46 1C 00 85 47 63 93 F6 08 5C 43 +93 F7 C7 3F 63 88 07 3A 89 47 63 FB 07 07 37 25 +02 50 13 05 45 CC EF 80 CF BE 03 28 49 5A 8D A0 +83 27 4C 00 9C CC 83 27 8C 00 DC CC 83 27 CC 00 +9C D0 83 27 0C 01 DC D0 83 27 4C 01 9C D4 83 27 +8C 01 DC D4 83 27 CC 01 9C D8 83 27 0C 02 DC D8 +83 27 4C 02 9C DC 83 27 8C 02 DC DC 83 27 CC 02 +BC C0 83 27 0C 03 FC C0 83 27 4C 03 BC C4 83 27 +8C 03 FC C4 83 27 CC 03 BC C8 83 27 0C 04 FC C8 +37 C6 03 10 DE 87 13 06 06 80 93 8B 0B 62 1D 8E +94 43 33 07 F6 00 91 07 14 C3 E3 9B 77 FF 89 47 +63 EC 07 27 03 A7 0C 00 B7 07 03 10 98 CF 03 A7 +4C 00 D8 CF 03 A7 8C 00 98 D3 03 A7 CC 00 D8 D3 +03 A7 0C 01 98 D7 03 A7 4C 01 D8 D7 03 A7 8C 01 +98 DB 03 A7 CC 01 D8 DB 03 A7 0C 02 98 DF 03 A7 +4C 02 D8 DF 03 A7 8C 02 B8 C3 03 A7 CC 02 F8 C3 +03 A7 0C 03 B8 C7 03 A7 4C 03 F8 C7 03 A7 8C 03 +B8 CB 03 A7 CC 03 F8 CB 63 12 0B 0C 89 47 63 ED +07 0D B7 97 03 10 11 47 98 CB 83 47 2C 00 63 89 +07 14 B7 C7 03 10 05 47 98 C3 37 47 02 50 13 07 +07 8B 34 47 7C 47 D5 8F 9D E3 73 00 50 10 93 07 +40 06 01 00 FD 17 C2 07 C1 83 E5 FF 3C 47 74 47 +D5 8F E5 D7 03 28 49 5A 09 44 63 65 04 0F 63 1E +0B 10 63 93 0A 16 B7 97 03 10 A4 4F 03 A4 49 00 +63 1C 94 32 E4 4F 03 A4 89 00 63 1F 94 30 A4 53 +03 A4 C9 00 63 1C 94 30 E4 53 03 A4 09 01 63 99 +84 26 A4 57 03 A4 49 01 63 92 84 26 E4 57 03 A4 +89 01 63 9B 84 24 A4 5B 03 A4 C9 01 63 9E 84 24 +E4 5B 03 A4 09 02 9D 45 63 02 94 14 83 27 49 5A +63 94 07 26 05 45 EF 80 CF A1 01 A0 93 17 1A 00 +11 67 13 07 17 FC 93 F7 F7 0F D9 8F 37 C7 03 10 +1C CB 89 47 E3 F7 07 F3 37 25 02 50 13 05 C5 5E +EF 80 2F A1 B7 97 03 10 11 47 03 28 49 5A 98 CB +83 47 2C 00 63 83 07 12 B7 C7 03 10 80 C3 89 47 +E3 FD 07 F1 37 25 02 50 13 05 05 BF EF 80 6F 9E +37 47 02 50 13 07 07 8B 3C 47 74 47 D5 8F 91 D7 +15 B7 37 25 02 50 13 05 C5 53 EF 80 8F 9C 03 28 +49 5A 25 BB 6C 47 30 47 2D 65 13 05 85 78 EF 80 +4F 9D 03 28 49 5A 63 12 0B 02 63 9F 0A 04 E3 74 +04 F1 37 25 02 50 13 05 05 76 EF 80 8F 99 E5 BD +B7 C7 03 10 0D 47 98 C3 4D BD 37 C7 03 10 5C 4B +89 8B F5 DF 83 C6 19 00 85 47 63 8B F6 0E 5C 4B +93 F7 C7 3F C9 EF 89 47 63 E2 07 15 03 57 0C 00 +85 47 63 1D F7 04 93 17 8A 00 93 E7 37 0B 37 07 +03 30 23 26 F7 0C 99 A0 63 78 04 01 37 25 02 50 +13 05 85 78 EF 80 EF 93 B7 97 03 10 A0 4F 63 19 +04 0E E0 4F 63 16 04 1C A0 53 63 15 04 1C E0 53 +63 1A 04 1A A0 57 63 15 04 1A E0 57 63 10 04 1A +A0 5B 63 19 04 10 E0 5B 9D 45 61 E4 B2 50 22 54 +92 54 02 59 F2 49 62 4A D2 4A 42 4B B2 4B 22 4C +92 4C 02 4D 45 61 82 80 37 25 02 50 13 05 45 5C +EF 80 2F 8E 03 28 49 5A B5 BB 0D 44 F1 BD 63 1E +08 0A 05 45 EF 80 EF 8A 01 A0 37 25 02 50 13 05 +45 56 EF 80 0F 8C 03 28 49 5A 23 AC 04 00 23 AE +04 00 23 A0 04 02 23 A2 04 02 23 A4 04 02 23 A6 +04 02 23 A8 04 02 23 AA 04 02 E3 7E 0D C5 37 25 +02 50 13 05 45 59 EF 80 CF 88 03 28 49 5A A1 B1 +5C 4B 93 F7 C7 3F A9 C7 89 47 E3 F9 07 F7 22 54 +B2 50 92 54 02 59 F2 49 62 4A D2 4A 42 4B B2 4B +22 4C 92 4C 02 4D 37 25 02 50 13 05 45 61 45 61 +6F 80 2F 85 63 1C 08 04 05 45 EF 80 8F 82 01 A0 +81 45 83 27 49 5A D9 EB 05 45 EF 80 8F 81 01 A0 +63 15 08 04 05 45 EF 80 CF 80 01 A0 37 25 02 50 +13 05 C5 70 EF 80 EF 81 55 BD 37 25 02 50 13 05 +85 6B EF 80 0F 81 35 BF 95 45 C9 B3 91 45 7D BB +8D 45 6D BB 99 45 75 BF 99 45 4D BB 37 25 02 50 +13 05 85 D0 EF 70 FF FE 45 B7 37 25 02 50 13 05 +45 66 EF 70 1F FE 7D B7 AD 69 93 89 89 78 13 85 +C9 52 EF 70 1F FF 83 27 49 5A E3 85 07 D8 A6 85 +13 85 09 56 EF 70 FF FD 83 27 49 5A E3 8C 07 D6 +A2 85 13 85 89 57 EF 70 DF FC AD B3 AD 64 93 84 +84 78 13 85 04 59 EF 70 DF FB 83 27 49 5A A9 DF +A2 85 13 85 44 5C EF 70 DF FA 83 27 49 5A A9 D7 +81 45 13 85 C4 5D EF 70 DF F9 3D BF 95 45 15 BF +91 45 05 BF 8D 45 35 B7 85 45 0D B3 89 45 39 BB +85 45 05 B7 89 45 31 BF 81 45 09 BB 79 71 26 D2 +B7 04 02 50 03 A8 44 5A 4E CE 5A C8 5E C6 62 C4 +06 D6 22 D4 4A D0 52 CC 56 CA 66 C2 89 47 03 CA +06 00 03 C9 26 00 B6 89 2A 8B AE 8B 32 8C 63 ED +07 29 37 94 03 10 5C 48 85 8B F5 DF 83 4A 0B 00 +63 8C 0A 08 83 47 2B 00 37 C7 03 10 89 4C 86 07 +93 F7 E7 03 93 E7 17 00 1C C3 63 E1 0C 35 23 2C +04 00 23 2E 04 00 23 20 04 02 23 22 04 02 23 24 +04 02 23 26 04 02 23 28 04 02 23 2A 04 02 B7 97 +03 10 23 AC 07 02 23 AE 07 02 23 A0 07 04 23 A2 +07 04 23 A4 07 04 23 A6 07 04 23 A8 07 04 23 AA +07 04 37 C7 03 10 5C 43 89 8B F5 DF 83 46 1B 00 +85 47 63 93 F6 08 5C 43 93 F7 C7 3F 63 8C 07 34 +89 47 63 FB 07 07 37 25 02 50 13 05 45 CC EF 70 +5F E8 03 A8 44 5A 8D A0 83 27 4B 00 1C CC 83 27 +8B 00 5C CC 83 27 CB 00 1C D0 83 27 0B 01 5C D0 +83 27 4B 01 1C D4 83 27 8B 01 5C D4 83 27 CB 01 +1C D8 83 27 0B 02 5C D8 83 27 4B 02 1C DC 83 27 +8B 02 5C DC 83 27 CB 02 3C C0 83 27 0B 03 7C C0 +83 27 4B 03 3C C4 83 27 8B 03 7C C4 83 27 CB 03 +3C C8 83 27 0B 04 7C C8 37 C6 03 10 DE 87 13 06 +06 80 93 8B 0B 62 1D 8E 94 43 33 07 F6 00 91 07 +14 C3 E3 9B FB FE 89 47 63 E3 07 23 03 27 0C 00 +B7 07 03 10 98 CF 03 27 4C 00 D8 CF 03 27 8C 00 +98 D3 03 27 CC 00 D8 D3 03 27 0C 01 98 D7 03 27 +4C 01 D8 D7 03 27 8C 01 98 DB 03 27 CC 01 D8 DB +03 27 0C 02 98 DF 03 27 4C 02 D8 DF 03 27 8C 02 +B8 C3 03 27 CC 02 F8 C3 03 27 0C 03 B8 C7 03 27 +4C 03 F8 C7 03 27 8C 03 B8 CB 03 27 CC 03 F8 CB +63 1F 0A 08 09 44 63 6A 04 0B B7 97 03 10 11 47 +98 CB 83 47 2B 00 37 C7 03 10 86 07 93 F7 E7 03 +93 E7 17 00 1C C3 37 47 02 50 13 07 07 8B 3C 47 +74 47 D5 8F 9D E3 73 00 50 10 93 07 40 06 01 00 +FD 17 C2 07 C1 83 E5 FF 3C 47 74 47 D5 8F E5 D7 +03 A8 44 5A 09 44 63 66 04 11 63 00 0A 0C 37 C7 +03 10 5C 4B 89 8B F5 DF 83 C6 19 00 85 47 63 8A +F6 1A 5C 4B 93 F7 C7 3F 63 9C 07 14 89 47 63 E7 +07 21 03 57 0B 00 85 47 63 1E F7 10 93 17 89 00 +93 E7 37 0B 37 07 03 30 23 26 F7 0C 21 A2 93 17 +19 00 11 67 13 07 17 FC 93 F7 F7 0F D9 8F 37 C7 +03 10 1C CB 09 44 E3 7A 04 F5 37 25 02 50 13 05 +C5 5E EF 70 1F CD B7 97 03 10 11 47 03 A8 44 5A +98 CB 83 47 2B 00 37 C7 03 10 86 07 93 F7 E7 03 +93 E7 17 00 1C C3 E3 70 04 F5 37 25 02 50 13 05 +05 BF EF 70 1F CA 37 47 02 50 13 07 07 8B 34 47 +7C 47 D5 8F 8D DB A9 B7 37 25 02 50 13 05 C5 53 +EF 70 3F C8 03 A8 44 5A A9 BB 63 89 0A 06 B7 97 +03 10 A0 4F 63 11 04 18 E0 4F 63 19 04 18 A0 53 +63 18 04 18 E0 53 63 16 04 16 A0 57 63 11 04 16 +E0 57 63 1C 04 14 A0 5B 63 11 04 16 E0 5B 9D 45 +31 C8 83 A7 44 5A 63 97 07 16 05 45 EF 70 7F C1 +01 A0 6C 47 30 47 2D 65 13 05 85 78 EF 70 7F C4 +03 A8 44 5A E3 15 0A EE 63 94 0A 0E 63 78 04 01 +37 25 02 50 13 05 05 7C EF 70 BF C0 37 97 03 10 +34 4F 93 07 C7 05 78 4F D8 43 98 47 D8 47 98 4B +D8 4B 9C 4F B2 50 22 54 92 54 02 59 F2 49 62 4A +D2 4A 42 4B B2 4B 22 4C 92 4C 45 61 82 80 37 25 +02 50 13 05 45 5C EF 70 DF BC 03 A8 44 5A F9 B3 +63 17 08 0A 05 45 EF 70 DF B9 01 A0 37 25 02 50 +13 05 45 56 EF 70 FF BA 03 A8 44 5A 23 2C 04 00 +23 2E 04 00 23 20 04 02 23 22 04 02 23 24 04 02 +23 26 04 02 23 28 04 02 23 2A 04 02 E3 F9 0C CB +37 25 02 50 13 05 45 59 EF 70 BF B7 03 A8 44 5A +79 B9 5C 4B 93 F7 C7 3F A9 C7 89 47 E3 FC 07 F7 +22 54 B2 50 92 54 02 59 F2 49 62 4A D2 4A 42 4B +B2 4B 22 4C 92 4C 37 25 02 50 13 05 45 61 45 61 +6F 70 3F B4 63 1D 08 04 05 45 EF 70 9F B1 01 A0 +E3 7F 04 EB 37 25 02 50 13 05 85 78 EF 70 7F B2 +7D B5 63 13 08 08 05 45 EF 70 BF AF 01 A0 37 25 +02 50 13 05 85 6B EF 70 DF B0 A9 B7 37 25 02 50 +13 05 C5 70 EF 70 FF AF ED B3 95 45 5D BD 91 45 +4D BD 8D 45 7D B5 81 45 6D B5 99 45 5D B5 37 25 +02 50 13 05 85 D0 EF 70 DF AD 79 BF 85 45 51 BD +89 45 41 BD 2D 69 13 09 89 78 13 05 49 5F EF 70 +5F AE 83 A7 44 5A E3 82 07 E8 A2 85 13 05 89 62 +EF 70 3F AD 83 A7 44 5A E3 89 07 E6 81 45 13 05 +09 64 EF 70 1F AC 95 B5 37 25 02 50 13 05 45 66 +EF 70 3F A9 8D BF 01 00 52 65 63 65 69 76 65 64 +20 4D 4C 4B 45 4D 20 6E 6F 74 69 66 2F 20 65 72 +72 20 69 6E 74 72 20 77 69 74 68 20 73 74 61 74 +75 73 20 3D 20 25 64 2F 20 25 64 0A 00 00 00 00 +41 74 20 6F 66 66 73 65 74 20 5B 25 64 5D 2C 20 +6D 6C 6B 65 6D 5F 65 6E 63 61 70 73 5F 6B 65 79 +20 64 61 74 61 20 6D 69 73 6D 61 74 63 68 21 0A +00 00 00 00 41 63 74 75 61 6C 20 20 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 45 78 70 65 +63 74 65 64 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 41 74 20 6F 66 66 73 65 74 20 5B 25 +64 5D 2C 20 6D 6C 6B 65 6D 5F 64 65 63 61 70 73 +5F 6B 65 79 20 64 61 74 61 20 6D 69 73 6D 61 74 +63 68 21 0A 00 00 00 00 41 63 74 75 61 6C 20 20 +20 64 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +45 78 70 65 63 74 65 64 20 64 61 74 61 3A 20 30 +78 25 78 0A 00 00 00 00 41 74 20 6F 66 66 73 65 +74 20 5B 25 64 5D 2C 20 6D 6C 6B 65 6D 5F 73 65 +65 64 5F 64 20 64 61 74 61 20 6D 69 73 6D 61 74 +63 68 21 0A 00 00 00 00 41 63 74 75 61 6C 20 20 +20 64 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +45 78 70 65 63 74 65 64 20 64 61 74 61 3A 20 30 +78 25 78 0A 00 00 00 00 41 74 20 6F 66 66 73 65 +74 20 5B 25 64 5D 2C 20 6D 6C 6B 65 6D 5F 73 65 +65 64 5F 7A 20 64 61 74 61 20 6D 69 73 6D 61 74 +63 68 21 0A 00 00 00 00 41 63 74 75 61 6C 20 20 +20 64 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +45 78 70 65 63 74 65 64 20 64 61 74 61 3A 20 30 +78 25 78 0A 00 00 00 00 41 74 20 6F 66 66 73 65 +74 20 5B 25 64 5D 2C 20 6D 6C 6B 65 6D 5F 64 6B +20 64 61 74 61 20 6D 69 73 6D 61 74 63 68 21 0A +00 00 00 00 41 63 74 75 61 6C 20 20 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 45 78 70 65 +63 74 65 64 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 41 74 20 6F 66 66 73 65 74 20 5B 25 +64 5D 2C 20 6D 6C 6B 65 6D 5F 6D 73 67 20 64 61 +74 61 20 6D 69 73 6D 61 74 63 68 21 0A 00 00 00 +41 63 74 75 61 6C 20 20 20 64 61 74 61 3A 20 30 +78 25 78 0A 00 00 00 00 45 78 70 65 63 74 65 64 +20 64 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +41 74 20 6F 66 66 73 65 74 20 5B 25 64 5D 2C 20 +6D 6C 6B 65 6D 5F 63 69 70 68 65 72 74 65 78 74 +20 64 61 74 61 20 6D 69 73 6D 61 74 63 68 21 0A +00 00 00 00 41 63 74 75 61 6C 20 20 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 45 78 70 65 +63 74 65 64 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 41 74 20 6F 66 66 73 65 74 20 5B 25 +64 5D 2C 20 6D 6C 6B 65 6D 5F 73 68 61 72 65 64 +5F 6B 65 79 20 64 61 74 61 20 6D 69 73 6D 61 74 +63 68 21 0A 00 00 00 00 41 63 74 75 61 6C 20 20 +20 64 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +45 78 70 65 63 74 65 64 20 64 61 74 61 3A 20 30 +78 25 78 0A 00 00 00 00 41 74 20 6F 66 66 73 65 +74 20 5B 25 64 5D 2C 20 6D 6C 6B 65 6D 5F 73 68 +61 72 65 64 5F 6B 65 79 20 64 61 74 61 20 6D 69 +73 6D 61 74 63 68 21 0A 00 00 00 00 41 63 74 75 +61 6C 20 20 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 45 78 70 65 63 74 65 64 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 41 74 20 6F +66 66 73 65 74 20 5B 25 64 5D 2C 20 6D 6C 6B 65 +6D 5F 6D 73 67 20 64 61 74 61 20 6D 69 73 6D 61 +74 63 68 21 0A 00 00 00 41 63 74 75 61 6C 20 20 +20 64 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +45 78 70 65 63 74 65 64 20 64 61 74 61 3A 20 30 +78 25 78 0A 00 00 00 00 41 74 20 6F 66 66 73 65 +74 20 5B 25 64 5D 2C 20 6D 6C 6B 65 6D 5F 73 68 +61 72 65 64 5F 6B 65 79 20 64 61 74 61 20 6D 69 +73 6D 61 74 63 68 21 0A 00 00 00 00 41 63 74 75 +61 6C 20 20 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 45 78 70 65 63 74 65 64 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 41 74 20 6F +66 66 73 65 74 20 5B 25 64 5D 2C 20 6D 6C 6B 65 +6D 5F 73 68 61 72 65 64 5F 6B 65 79 20 64 61 74 +61 20 6D 69 73 6D 61 74 63 68 21 0A 00 00 00 00 +41 63 74 75 61 6C 20 20 20 64 61 74 61 3A 20 30 +78 25 78 0A 00 00 00 00 45 78 70 65 63 74 65 64 +20 64 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +41 74 20 6F 66 66 73 65 74 20 5B 25 64 5D 2C 20 +6D 6C 6B 65 6D 5F 73 68 61 72 65 64 5F 6B 65 79 +20 64 61 74 61 20 6D 69 73 6D 61 74 63 68 21 0A +00 00 00 00 41 63 74 75 61 6C 20 20 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 45 78 70 65 +63 74 65 64 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 41 74 20 6F 66 66 73 65 74 20 5B 25 +64 5D 2C 20 6D 6C 6B 65 6D 5F 73 68 61 72 65 64 +5F 6B 65 79 20 64 61 74 61 20 6D 69 73 6D 61 74 +63 68 21 0A 00 00 00 00 41 63 74 75 61 6C 20 20 +20 64 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +45 78 70 65 63 74 65 64 20 64 61 74 61 3A 20 30 +78 25 78 0A 00 00 00 00 41 74 20 6F 66 66 73 65 +74 20 5B 25 64 5D 2C 20 6D 6C 6B 65 6D 5F 73 68 +61 72 65 64 5F 6B 65 79 20 64 61 74 61 20 6D 69 +73 6D 61 74 63 68 21 0A 00 00 00 00 41 63 74 75 +61 6C 20 20 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 45 78 70 65 63 74 65 64 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 41 74 20 6F +66 66 73 65 74 20 5B 25 64 5D 2C 20 6D 6C 6B 65 +6D 5F 73 68 61 72 65 64 5F 6B 65 79 20 64 61 74 +61 20 6D 69 73 6D 61 74 63 68 21 0A 00 00 00 00 +41 63 74 75 61 6C 20 20 20 64 61 74 61 3A 20 30 +78 25 78 0A 00 00 00 00 45 78 70 65 63 74 65 64 +20 64 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +41 11 22 C4 37 04 02 50 03 27 44 5A 06 C6 89 47 +63 E0 E7 04 37 47 02 50 13 07 07 8B 1C 4B 54 4B +D5 8F 9D E3 73 00 50 10 93 07 40 06 01 00 FD 17 +C2 07 C1 83 E5 FF 1C 4B 54 4B D5 8F E5 D7 83 26 +44 5A 89 47 63 E5 D7 02 B2 40 22 44 41 01 82 80 +37 25 02 50 13 05 85 7E EF 70 AF BD 37 47 02 50 +13 07 07 8B 1C 4B 54 4B D5 8F CD DF C9 BF 22 44 +4C 4B B2 40 10 4B 35 65 13 05 05 FF 41 01 6F 70 +4F BD B7 07 02 50 03 A7 47 5A 89 47 63 E7 E7 00 +B7 07 01 10 11 47 98 CB 82 80 37 35 02 50 41 11 +13 05 45 80 06 C6 EF 70 CF B8 B2 40 B7 07 01 10 +11 47 98 CB 41 01 82 80 19 CA 0A 06 33 87 C5 00 +9C 41 91 05 11 05 23 2E F5 FE E3 9B E5 FE 82 80 +39 71 5A D0 62 CC 66 CA 6A C8 6E C6 06 DE 22 DC +26 DA 4A D8 4E D6 52 D4 56 D2 5E CE 03 49 15 00 +83 4B 25 00 03 CA 15 00 83 C9 25 00 83 CA 06 00 +AA 8D 2E 8C B6 8C 32 8D 3A 8B B7 07 01 10 80 4F +05 88 75 DC 03 C7 0D 00 B7 04 02 50 03 A5 44 5A +45 C3 13 97 1B 00 13 77 E7 03 13 67 17 00 23 A0 +E7 60 89 47 63 ED A7 30 B7 07 01 10 23 A0 07 04 +23 A2 07 04 23 A4 07 04 23 A6 07 04 23 A8 07 04 +23 AA 07 04 23 AC 07 04 23 AE 07 04 23 A0 07 06 +23 A2 07 06 23 A4 07 06 23 A6 07 06 37 07 01 10 +83 27 47 60 89 8B ED DF 85 47 63 1C F9 08 83 27 +47 60 93 F7 C7 3F 63 80 07 32 89 47 63 ED A7 3A +83 47 0C 00 63 96 07 36 37 06 01 10 B7 05 FF EF +93 07 06 08 93 85 05 F8 13 06 06 10 BE 86 91 07 +33 87 B7 00 62 97 18 43 98 C2 E3 99 C7 FE 75 A0 +89 47 63 EF A7 28 03 A7 4D 00 B7 07 01 10 B8 C3 +03 A7 8D 00 F8 C3 03 A7 CD 00 B8 C7 03 A7 0D 01 +F8 C7 03 A7 4D 01 B8 CB 03 A7 8D 01 F8 CB 03 A7 +CD 01 B8 CF 03 A7 0D 02 F8 CF 03 A7 4D 02 B8 D3 +03 A7 8D 02 F8 D3 03 A7 CD 02 B8 D7 03 A7 0D 03 +F8 D7 83 47 0C 00 C9 D3 93 97 19 00 93 F7 E7 03 +93 E7 17 00 37 07 01 10 23 24 F7 60 89 47 63 FA +A7 00 37 35 02 50 13 05 85 8F EF 70 8F 9F 03 A5 +44 5A B7 06 01 10 93 87 06 08 93 86 06 10 23 A0 +07 00 91 07 E3 9D D7 FE 37 07 01 10 83 27 C7 60 +89 8B ED DF 85 47 63 0F FA 20 03 27 4D 00 B7 07 +01 10 23 A0 E7 14 03 27 8D 00 23 A2 E7 14 03 27 +CD 00 23 A4 E7 14 03 27 0D 01 23 A6 E7 14 03 27 +4D 01 23 A8 E7 14 03 27 8D 01 23 AA E7 14 03 27 +CD 01 23 AC E7 14 03 27 0D 02 23 AE E7 14 03 27 +4D 02 23 A0 E7 16 03 27 8D 02 23 A2 E7 16 03 27 +CD 02 23 A4 E7 16 03 27 0D 03 23 A6 E7 16 63 8D +0A 00 03 C7 2C 00 85 66 93 86 16 FC 06 07 13 77 +F7 0F 55 8F 23 A8 E7 60 B7 07 01 10 63 0E 0B 12 +05 47 98 CB A2 87 63 93 0B 00 8D 47 37 07 01 10 +23 20 F7 60 63 93 09 00 0D 44 B7 07 01 10 23 A4 +87 60 89 47 63 ED A7 10 37 47 02 50 13 07 07 8B +1C 4B 54 4B D5 8F 95 EB 73 00 50 10 93 07 40 06 +01 00 FD 17 C2 07 C1 83 E5 FF 1C 4B 54 4B D5 8F +E5 D7 83 A6 44 5A 89 47 63 F9 D7 00 4C 4B 10 4B +35 65 13 05 05 FF EF 70 CF 8F 33 69 49 01 63 16 +09 0A 83 A7 44 5A 09 47 63 95 0A 10 63 68 F7 16 +B7 07 01 10 03 A7 07 10 83 A7 4C 00 63 1C F7 14 +B7 07 01 10 03 A9 47 10 03 A4 8C 00 63 1E 24 13 +03 A9 87 10 03 A4 CC 00 63 1C 24 1F 03 A9 C7 10 +03 A4 0C 01 63 14 24 1F 03 A9 07 11 03 A4 4C 01 +63 1C 89 1C 03 A9 47 11 03 A4 8C 01 63 14 89 1C +03 A9 87 11 03 A4 CC 01 63 1C 89 1A 03 A9 C7 11 +03 A4 0C 02 63 14 89 1A 03 A9 07 12 03 A4 4C 02 +63 1C 89 18 03 A9 47 12 03 A4 8C 02 63 14 89 18 +03 A9 87 12 03 A4 CC 02 63 12 89 10 03 A9 C7 12 +03 A4 0C 03 AD 45 63 12 89 0C F2 50 62 54 D2 54 +42 59 B2 59 22 5A 92 5A 02 5B F2 4B 62 4C D2 4C +42 4D B2 4D 21 61 82 80 09 47 98 CB E1 B5 37 25 +02 50 13 05 85 7E EF 60 DF FF 37 47 02 50 13 07 +07 8B 1C 4B 54 4B D5 8F E3 80 07 EE DD BD 37 35 +02 50 13 05 85 81 EF 60 DF FD 03 A5 44 5A E9 B9 +37 35 02 50 13 05 05 8E EF 60 BF FC 03 A5 44 5A +99 BB 63 64 F7 04 37 07 01 10 83 27 47 61 89 8B +ED DF 61 B7 83 27 C7 60 93 F7 C7 3F 95 C3 89 47 +E3 FD A7 DC 37 35 02 50 13 05 C5 91 EF 60 7F F9 +03 A5 44 5A D9 B3 61 E1 05 45 EF 60 9F F6 01 A0 +45 E5 05 45 EF 60 FF F5 01 A0 37 35 02 50 13 05 +05 9C EF 60 1F F7 45 BF 85 45 83 A7 44 5A 09 4A +63 61 FA 04 05 45 EF 60 DF F3 01 A0 37 35 02 50 +13 05 05 9E EF 60 FF F4 B7 07 01 10 03 A9 07 10 +03 A4 4C 00 E3 06 24 E9 81 45 C1 BF A9 45 F1 B7 +93 97 19 00 93 F7 E7 03 93 E7 17 00 23 24 F7 60 +0D BB B5 69 93 89 09 FF 13 85 49 03 EF 60 7F F3 +83 A7 44 5A E3 78 FA FA CA 85 13 85 09 06 EF 60 +5F F2 83 A7 44 5A E3 7F FA F8 A2 85 13 85 89 07 +EF 60 3F F1 41 BF 37 35 02 50 13 05 05 84 EF 60 +5F EE 03 A5 44 5A 75 B9 37 35 02 50 13 05 C5 96 +EF 60 3F ED B9 B7 37 35 02 50 13 05 C5 88 EF 60 +5F EC 1D BF A5 45 91 BF A1 45 81 BF 9D 45 B1 B7 +99 45 A1 B7 95 45 91 B7 91 45 81 B7 8D 45 35 BF +89 45 25 BF 39 71 5A D0 62 CC 66 CA 6A C8 6E C6 +06 DE 22 DC 26 DA 4A D8 4E D6 52 D4 56 D2 5E CE +03 49 15 00 83 4B 25 00 03 CA 15 00 83 C9 25 00 +83 CA 06 00 AA 8D AE 8C 36 8C 32 8D 3A 8B B7 07 +01 10 80 4F 05 88 75 DC 03 C7 0D 00 B7 04 02 50 +03 A5 44 5A 45 CB 13 97 1B 00 13 77 E7 03 13 67 +17 00 23 A0 E7 60 89 47 63 E7 A7 38 B7 07 01 10 +23 A0 07 04 23 A2 07 04 23 A4 07 04 23 A6 07 04 +23 A8 07 04 23 AA 07 04 23 AC 07 04 23 AE 07 04 +23 A0 07 06 23 A2 07 06 23 A4 07 06 23 A6 07 06 +23 A8 07 06 23 AA 07 06 23 AC 07 06 23 AE 07 06 +37 07 01 10 83 27 47 60 89 8B ED DF 85 47 63 18 +F9 0A 83 27 47 60 93 F7 C7 3F 63 89 07 36 89 47 +63 EF A7 3E 83 C7 0C 00 63 9A 07 38 37 06 01 10 +B7 05 FF EF 93 07 06 08 93 85 05 F8 13 06 06 10 +BE 86 91 07 33 87 B7 00 66 97 18 43 98 C2 E3 99 +C7 FE D1 A0 89 47 63 E1 A7 30 03 A7 4D 00 B7 07 +01 10 B8 C3 03 A7 8D 00 F8 C3 03 A7 CD 00 B8 C7 +03 A7 0D 01 F8 C7 03 A7 4D 01 B8 CB 03 A7 8D 01 +F8 CB 03 A7 CD 01 B8 CF 03 A7 0D 02 F8 CF 03 A7 +4D 02 B8 D3 03 A7 8D 02 F8 D3 03 A7 CD 02 B8 D7 +03 A7 0D 03 F8 D7 03 A7 4D 03 B8 DB 03 A7 8D 03 +F8 DB 03 A7 CD 03 B8 DF 03 A7 0D 04 F8 DF 83 C7 +0C 00 AD D7 93 97 19 00 93 F7 E7 03 93 E7 17 00 +37 07 01 10 23 24 F7 60 89 47 63 FA A7 00 37 35 +02 50 13 05 85 8F EF 60 DF D0 03 A5 44 5A B7 06 +01 10 93 87 06 08 93 86 06 10 23 A0 07 00 91 07 +E3 9D D7 FE 37 07 01 10 83 27 C7 60 89 8B ED DF +85 47 63 0C FA 24 03 27 4D 00 B7 07 01 10 23 A0 +E7 14 03 27 8D 00 23 A2 E7 14 03 27 CD 00 23 A4 +E7 14 03 27 0D 01 23 A6 E7 14 03 27 4D 01 23 A8 +E7 14 03 27 8D 01 23 AA E7 14 03 27 CD 01 23 AC +E7 14 03 27 0D 02 23 AE E7 14 03 27 4D 02 23 A0 +E7 16 03 27 8D 02 23 A2 E7 16 03 27 CD 02 23 A4 +E7 16 03 27 0D 03 23 A6 E7 16 63 8D 0A 00 03 47 +2C 00 A1 66 93 86 16 FC 06 07 13 77 F7 0F 55 8F +23 A8 E7 60 B7 07 01 10 63 04 0B 18 25 47 98 CB +A2 87 63 93 0B 00 8D 47 37 07 01 10 23 20 F7 60 +63 93 09 00 0D 44 B7 07 01 10 23 A4 87 60 89 47 +63 E3 A7 16 37 47 02 50 13 07 07 8B 1C 4B 54 4B +D5 8F 95 EB 73 00 50 10 93 07 40 06 01 00 FD 17 +C2 07 C1 83 E5 FF 1C 4B 54 4B D5 8F E5 D7 83 A6 +44 5A 89 47 63 F9 D7 00 4C 4B 10 4B 35 65 13 05 +05 FF EF 60 1F C1 33 69 49 01 63 1C 09 0E 83 A7 +44 5A 09 47 63 9F 0A 0C 63 6B F7 18 B7 07 01 10 +03 A9 07 10 03 24 4C 00 63 19 24 1F 03 A9 47 10 +03 24 8C 00 63 11 24 1F 03 A9 87 10 03 24 CC 00 +63 14 24 23 03 A9 C7 10 03 24 0C 01 63 1C 24 21 +03 A9 07 11 03 24 4C 01 63 14 89 20 03 A9 47 11 +03 24 8C 01 63 1C 89 1E 03 A9 87 11 03 24 CC 01 +63 14 89 1E 03 A9 C7 11 03 24 0C 02 63 1C 89 1C +03 A9 07 12 03 24 4C 02 63 14 89 1C 03 A9 47 12 +03 24 8C 02 63 1C 89 1A 03 A9 87 12 03 24 CC 02 +63 1D 89 12 03 A9 C7 12 03 24 0C 03 63 15 89 12 +03 A9 07 13 03 24 4C 03 63 1D 89 10 03 A9 47 13 +03 24 8C 03 63 15 89 10 03 A9 87 13 03 24 CC 03 +63 11 89 14 03 A9 C7 13 03 24 0C 04 BD 45 63 02 +89 02 83 A7 44 5A 63 9C 07 0E 05 45 EF 60 7F AE +01 A0 63 67 F7 0A 37 07 01 10 83 27 47 61 89 8B +ED DF F2 50 62 54 D2 54 42 59 B2 59 22 5A 92 5A +02 5B F2 4B 62 4C D2 4C 42 4D B2 4D 21 61 82 80 +29 47 98 CB B5 BD 37 25 02 50 13 05 85 7E EF 60 +5F AC 37 47 02 50 13 07 07 8B 1C 4B 54 4B D5 8F +E3 8A 07 E8 6D B5 37 35 02 50 13 05 85 9F EF 60 +5F AA 03 A5 44 5A 9D B1 37 35 02 50 13 05 05 8E +EF 60 3F A9 03 A5 44 5A CD B9 83 27 C7 60 93 F7 +C7 3F 95 C3 89 47 E3 F0 A7 DA 37 35 02 50 13 05 +C5 91 EF 60 1F A7 03 A5 44 5A 71 B3 4D E9 05 45 +EF 60 3F A4 01 A0 49 ED 05 45 EF 60 9F A3 01 A0 +37 35 02 50 13 05 05 9C EF 60 BF A4 A9 B7 37 35 +02 50 13 05 05 9E EF 60 DF A3 8D B5 93 97 19 00 +93 F7 E7 03 93 E7 17 00 23 24 F7 60 0D B3 B5 45 +09 BF B1 45 39 B7 AD 45 29 B7 A9 45 19 B7 B5 69 +93 89 09 FF 13 85 09 09 EF 60 BF A2 83 A7 44 5A +E3 8D 07 EE CA 85 13 85 C9 0B EF 60 9F A1 83 A7 +44 5A E3 84 07 EE A2 85 13 85 49 0D EF 60 7F A0 +E9 BD B9 45 F9 B5 85 45 E9 B5 81 45 D9 B5 37 35 +02 50 13 05 05 84 EF 60 DF 9C 03 A5 44 5A 41 B9 +37 35 02 50 13 05 C5 96 EF 60 BF 9B B1 BF 37 35 +02 50 13 05 C5 88 EF 60 DF 9A 91 B7 A5 45 51 BD +A1 45 41 BD 9D 45 71 B5 99 45 61 B5 95 45 51 B5 +91 45 41 B5 8D 45 B5 BD 89 45 A5 BD 79 71 4A D0 +56 CA 5E C6 62 C4 66 C2 6A C0 06 D6 22 D4 26 D2 +4E CE 52 CC 5A C8 03 4B 25 00 03 CA 25 00 83 C9 +06 00 3E 8C 2A 8D AE 8B 36 89 B2 8C BA 8A B7 07 +01 10 80 4F 05 88 75 DC 03 47 0D 00 B7 04 02 50 +03 A5 44 5A 55 CB 13 17 1B 00 13 77 E7 03 13 67 +17 00 23 A0 E7 60 89 47 63 E3 A7 34 B7 07 01 10 +23 A0 07 04 23 A2 07 04 23 A4 07 04 23 A6 07 04 +23 A8 07 04 23 AA 07 04 23 AC 07 04 23 AE 07 04 +23 A0 07 06 23 A2 07 06 23 A4 07 06 23 A6 07 06 +23 A8 07 06 23 AA 07 06 23 AC 07 06 23 AE 07 06 +37 07 01 10 83 27 47 60 89 8B ED DF 83 46 1D 00 +85 47 63 98 F6 0A 83 27 47 60 93 F7 C7 3F 63 83 +07 32 89 47 63 EA A7 32 83 C7 0B 00 63 9D 07 34 +37 06 01 10 B7 05 FF EF 93 07 06 08 93 85 05 F8 +13 06 06 10 BE 86 91 07 33 87 B7 00 5E 97 18 43 +98 C2 E3 99 C7 FE E1 A0 89 47 63 EB A7 2A 03 27 +4D 00 B7 07 01 10 B8 C3 03 27 8D 00 F8 C3 03 27 +CD 00 B8 C7 03 27 0D 01 F8 C7 03 27 4D 01 B8 CB +03 27 8D 01 F8 CB 03 27 CD 01 B8 CF 03 27 0D 02 +F8 CF 03 27 4D 02 B8 D3 03 27 8D 02 F8 D3 03 27 +CD 02 B8 D7 03 27 0D 03 F8 D7 03 27 4D 03 B8 DB +03 27 8D 03 F8 DB 03 27 CD 03 B8 DF 03 27 0D 04 +F8 DF 83 C7 0B 00 AD D7 93 17 1A 00 93 F7 E7 03 +93 E7 17 00 37 07 01 10 23 24 F7 60 89 47 63 FA +A7 00 37 35 02 50 13 05 85 8F EF 60 8F FF 03 A5 +44 5A B7 06 01 10 93 87 06 08 93 86 06 10 23 A0 +07 00 91 07 E3 9D D7 FE 37 07 01 10 83 27 C7 60 +89 8B ED DF 83 C6 1B 00 85 47 63 84 F6 20 03 A7 +4C 00 B7 07 01 10 23 A0 E7 14 03 A7 8C 00 23 A2 +E7 14 03 A7 CC 00 23 A4 E7 14 03 A7 0C 01 23 A6 +E7 14 03 A7 4C 01 23 A8 E7 14 03 A7 8C 01 23 AA +E7 14 03 A7 CC 01 23 AC E7 14 03 A7 0C 02 23 AE +E7 14 03 A7 4C 02 23 A0 E7 16 03 A7 8C 02 23 A2 +E7 16 03 A7 CC 02 23 A4 E7 16 03 A7 0C 03 23 A6 +E7 16 63 8D 09 00 03 47 29 00 91 66 93 86 16 FC +06 07 13 77 F7 0F 55 8F 23 A8 E7 60 B7 07 01 10 +63 8C 0A 12 25 47 98 CB A2 87 63 13 0B 00 8D 47 +37 07 01 10 23 20 F7 60 63 13 0A 00 0D 44 B7 07 +01 10 23 A4 87 60 89 47 63 EB A7 10 37 47 02 50 +13 07 07 8B 1C 4B 54 4B D5 8F 91 EF 73 00 50 10 +93 07 40 06 01 00 FD 17 C2 07 C1 83 E5 FF 1C 4B +54 4B D5 8F E5 D7 83 A7 44 5A 09 44 63 6B F4 00 +63 8C 09 02 37 07 01 10 83 27 47 61 89 8B ED DF +75 A0 4C 4B 10 4B 35 65 13 05 05 FF EF 60 6F EE +83 A7 44 5A 63 94 09 0C 63 78 F4 00 37 35 02 50 +13 05 05 9E EF 60 EF EA B7 07 01 10 03 A7 07 10 +23 20 EC 00 03 A7 47 10 23 22 EC 00 03 A7 87 10 +23 24 EC 00 03 A7 C7 10 23 26 EC 00 03 A7 07 11 +23 28 EC 00 03 A7 47 11 23 2A EC 00 03 A7 87 11 +23 2C EC 00 03 A7 C7 11 23 2E EC 00 03 A7 07 12 +23 20 EC 02 03 A7 47 12 23 22 EC 02 03 A7 87 12 +23 24 EC 02 03 A7 C7 12 23 26 EC 02 03 A7 07 13 +23 28 EC 02 03 A7 47 13 23 2A EC 02 03 A7 87 13 +23 2C EC 02 83 A7 C7 13 23 2E FC 02 B2 50 22 54 +92 54 02 59 F2 49 62 4A D2 4A 42 4B B2 4B 22 4C +92 4C 02 4D 45 61 82 80 29 47 98 CB F1 B5 37 25 +02 50 13 05 85 7E EF 60 CF DF CD B5 E3 7C F4 F0 +37 35 02 50 13 05 05 9C EF 60 AF DE 21 B7 37 35 +02 50 13 05 85 9F EF 60 CF DD 03 A5 44 5A 7D B1 +37 35 02 50 13 05 05 8E EF 60 AF DC 03 A5 44 5A +3D BB 83 27 C7 60 93 F7 C7 3F 95 C3 89 47 E3 F8 +A7 DE 37 35 02 50 13 05 C5 91 EF 60 8F DA 03 A5 +44 5A F1 BB 15 E9 05 45 EF 60 AF D7 01 A0 11 ED +05 45 EF 60 0F D7 01 A0 37 35 02 50 13 05 05 84 +EF 60 2F D8 03 A5 44 5A A9 BB 37 35 02 50 13 05 +C5 96 EF 60 0F D7 E9 BF 37 35 02 50 13 05 C5 88 +EF 60 2F D6 C9 B7 93 17 1A 00 93 F7 E7 03 93 E7 +17 00 23 24 F7 60 B1 BB 01 11 26 CA 4A C8 4E C6 +56 C2 5A C0 06 CE 22 CC 52 C4 2A 89 AE 84 B2 8A +B6 89 3A 8B B7 07 01 10 80 4F 05 88 75 DC 37 0A +02 50 03 28 4A 5A 89 47 63 EC 07 27 83 27 49 00 +37 07 01 10 37 05 01 10 3C C3 83 26 89 00 37 06 +FF EF 93 07 07 08 74 C3 83 26 C9 00 13 06 06 F8 +93 05 05 10 34 C7 83 26 09 01 74 C7 83 26 49 01 +34 CB 83 26 89 01 74 CB 83 26 C9 01 34 CF 83 26 +09 02 74 CF 83 26 49 02 34 D3 83 26 89 02 74 D3 +83 26 C9 02 34 D7 83 26 09 03 74 D7 83 26 49 03 +34 DB 83 26 89 03 74 DB 83 26 C9 03 34 DF 83 26 +09 04 74 DF BE 86 91 07 33 87 C7 00 26 97 18 43 +98 C2 E3 99 B7 FE 83 A7 4A 00 23 20 F5 14 83 A7 +8A 00 23 22 F5 14 83 A7 CA 00 23 24 F5 14 83 A7 +0A 01 23 26 F5 14 83 A7 4A 01 23 28 F5 14 83 A7 +8A 01 23 2A F5 14 83 A7 CA 01 23 2C F5 14 83 A7 +0A 02 23 2E F5 14 83 A7 4A 02 23 20 F5 16 83 A7 +8A 02 23 22 F5 16 83 A7 CA 02 23 24 F5 16 83 A7 +0A 03 23 26 F5 16 63 0F 0B 12 E5 47 1C C9 03 47 +29 00 A2 87 11 E3 8D 47 37 07 01 10 23 20 F7 60 +83 C7 24 00 91 E3 0D 44 B7 07 01 10 23 A4 87 60 +89 47 63 E8 07 15 37 47 02 50 13 07 07 8B 14 4B +5C 4B D5 8F 91 EF 73 00 50 10 93 07 40 06 01 00 +FD 17 C2 07 C1 83 E5 FF 1C 4B 54 4B D5 8F E5 D7 +83 27 4A 5A 09 44 63 6C F4 0E B7 07 01 10 83 A4 +07 10 03 A4 49 00 63 1A 94 0C 83 A4 47 10 03 A4 +89 00 63 1A 94 14 83 A4 87 10 03 A4 C9 00 63 1A +94 14 83 A4 C7 10 03 A4 09 01 63 92 84 14 83 A4 +07 11 03 A4 49 01 63 9A 84 12 83 A4 47 11 03 A4 +89 01 63 9A 84 14 83 A4 87 11 03 A4 C9 01 63 92 +84 14 83 A4 C7 11 03 A4 09 02 63 9A 84 12 83 A4 +07 12 03 A4 49 02 63 92 84 12 83 A4 47 12 03 A4 +89 02 63 96 84 10 83 A4 87 12 03 A4 C9 02 63 9C +84 0E 83 A4 C7 12 03 A4 09 03 63 9C 84 0E 83 A4 +07 13 03 A4 49 03 63 92 84 10 83 A4 47 13 03 A4 +89 03 63 9C 84 0C 83 A4 87 13 03 A4 C9 03 63 9C +84 0C 83 A4 C7 13 03 A4 09 04 BD 45 63 90 84 02 +F2 40 62 44 D2 44 42 49 B2 49 22 4A 92 4A 02 4B +05 61 82 80 E9 47 1C C9 D9 B5 81 45 83 27 4A 5A +89 49 63 E8 F9 04 05 45 EF 60 AF AB 01 A0 4C 4B +10 4B 35 65 13 05 05 FF EF 60 AF AE 83 27 4A 5A +E3 7D F4 EE 37 35 02 50 13 05 05 9E EF 60 6F AB +ED B5 37 25 02 50 13 05 85 7E EF 60 8F AA 65 B5 +37 35 02 50 13 05 05 8E EF 60 AF A9 03 28 4A 5A +B5 BB 35 69 13 09 09 FF 13 05 C9 0E EF 60 6F AA +83 27 4A 5A E3 F1 F9 FA A6 85 13 05 89 11 EF 60 +4F A9 83 27 4A 5A E3 F8 F9 F8 A2 85 13 05 09 13 +EF 60 2F A8 49 B7 85 45 95 BF 91 45 85 BF 8D 45 +B5 B7 89 45 A5 B7 A9 45 95 B7 B5 45 85 B7 A5 45 +B1 BF AD 45 A1 BF B9 45 91 BF A1 45 81 BF 9D 45 +B1 B7 99 45 A1 B7 95 45 91 B7 B1 45 81 B7 01 00 +52 65 63 65 69 76 65 64 20 48 4D 41 43 20 6E 6F +74 69 66 2F 65 72 72 20 69 6E 74 72 20 77 69 74 +68 20 73 74 61 74 75 73 20 3D 20 25 64 2F 20 25 +64 0A 00 00 41 74 20 6F 66 66 73 65 74 20 5B 25 +64 5D 2C 20 68 6D 61 63 5F 74 61 67 20 64 61 74 +61 20 6D 69 73 6D 61 74 63 68 21 0A 00 00 00 00 +41 63 74 75 61 6C 20 20 20 64 61 74 61 3A 20 30 +78 25 78 0A 00 00 00 00 45 78 70 65 63 74 65 64 +20 64 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +41 74 20 6F 66 66 73 65 74 20 5B 25 64 5D 2C 20 +68 6D 61 63 5F 74 61 67 20 64 61 74 61 20 6D 69 +73 6D 61 74 63 68 21 0A 00 00 00 00 41 63 74 75 +61 6C 20 20 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 45 78 70 65 63 74 65 64 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 41 74 20 6F +66 66 73 65 74 20 5B 25 64 5D 2C 20 68 6D 61 63 +5F 74 61 67 20 64 61 74 61 20 6D 69 73 6D 61 74 +63 68 21 0A 00 00 00 00 41 63 74 75 61 6C 20 20 +20 64 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +45 78 70 65 63 74 65 64 20 64 61 74 61 3A 20 30 +78 25 78 0A 00 00 00 00 B7 07 02 50 03 A7 47 5A +41 11 22 C4 06 C6 8D 47 2A 84 63 EC E7 00 B7 67 +00 04 3E 94 0A 04 91 47 B2 40 1C C0 22 44 41 01 +82 80 AA 85 35 65 13 05 05 33 EF 60 8F 8C C5 B7 +B7 07 02 50 03 A7 47 5A 41 11 22 C4 06 C6 8D 47 +2A 84 63 EA E7 00 1C 40 93 F7 C7 3F 99 EF B2 40 +22 44 41 01 82 80 37 35 02 50 13 05 05 A2 EF 60 +4F 87 1C 40 93 F7 C7 3F FD D3 37 35 02 50 13 05 +85 A3 EF 60 0F 86 22 44 B2 40 05 45 41 01 6F 60 +4F 83 B7 07 02 50 03 A7 47 5A 41 11 22 C4 06 C6 +8D 47 2A 84 63 EA E7 00 1C 40 93 F7 C7 3F 99 CF +B2 40 22 44 41 01 82 80 37 35 02 50 13 05 45 A4 +EF 60 2F 82 1C 40 93 F7 C7 3F FD F3 37 35 02 50 +13 05 05 A6 EF 60 EF 80 22 44 B2 40 05 45 41 01 +6F 50 3F FE B7 07 02 50 03 A7 47 5A 41 11 22 C4 +26 C2 06 C6 8D 47 AA 84 2E 84 63 ED E7 00 06 04 +13 74 E4 03 13 64 14 00 80 C0 B2 40 22 44 92 44 +41 01 82 80 37 35 02 50 13 05 C5 A6 EF 50 7F FC +F9 BF B7 07 02 50 03 A7 47 5A 41 11 22 C4 26 C2 +4A C0 06 C6 8D 47 2A 89 AE 84 32 84 63 EB E7 06 +93 77 14 00 13 17 64 00 13 77 07 08 93 95 14 00 +9A 07 D9 8F 93 F5 E5 03 13 17 64 00 13 77 07 10 +93 16 64 00 CD 8F D9 8F 93 F6 06 20 13 17 64 00 +13 56 54 00 D5 8F 13 77 07 40 93 56 64 00 05 8A +D9 8F 2E 06 13 57 74 00 85 8A D1 8F B2 06 05 8B +21 80 D5 8F 36 07 05 88 3A 04 D9 8F B2 40 C1 8F +22 44 93 E7 17 00 23 20 F9 00 92 44 02 49 41 01 +82 80 37 35 02 50 13 05 45 A8 EF 50 9F F2 49 B7 +B7 07 02 50 03 A7 47 5A 41 11 22 C4 06 C6 8D 47 +2A 84 63 EF E7 00 06 04 13 74 E4 03 13 64 14 04 +B7 07 02 10 B2 40 23 A0 87 60 22 44 41 01 82 80 +37 35 02 50 13 05 C5 A9 EF 50 BF EE E9 BF 01 00 +4B 56 3A 20 63 6C 65 61 72 69 6E 67 20 4B 56 20 +65 6E 74 72 79 20 30 78 25 78 0A 00 00 00 00 00 +08 41 B7 35 02 50 41 11 93 85 45 D0 06 C6 EF 30 +B0 53 B2 40 33 35 A0 00 41 01 82 80 B7 15 02 50 +93 85 C5 80 93 87 45 00 13 86 C5 20 01 47 94 43 +63 65 D5 00 D4 4B 63 69 D5 00 D1 07 05 07 E3 98 +C7 FE 13 85 85 20 82 80 93 17 27 00 BA 97 8A 07 +33 85 F5 00 82 80 01 11 22 CC 37 14 02 50 26 CA +4A C8 4E C6 52 C4 06 CE 13 0A C4 80 2A 89 13 04 +C4 80 81 44 ED 49 21 A0 85 04 63 8D 34 01 08 40 +CA 85 51 04 EF 30 50 4C 65 D9 13 95 24 00 26 95 +0A 05 52 95 F2 40 62 44 D2 44 42 49 B2 49 22 4A +05 61 82 80 5C 45 63 C0 07 04 1C 49 63 CF 07 02 +5C 49 63 CE 07 02 1C 4D 63 CD 07 02 5C 4D 63 CC +07 02 1C 51 63 CB 07 02 5C 51 63 CA 07 02 1C 55 +63 C9 07 02 5C 55 63 C8 07 02 08 59 13 45 F5 FF +7D 81 25 05 82 80 01 45 82 80 05 45 82 80 09 45 +82 80 0D 45 82 80 11 45 82 80 15 45 82 80 19 45 +82 80 1D 45 82 80 21 45 82 80 B7 47 02 50 0A 05 +93 87 87 90 AA 97 94 43 05 47 33 17 B7 00 55 8F +98 C3 82 80 01 11 4E C6 B7 09 02 50 83 A7 49 5A +06 CE 22 CC 26 CA 4A C8 52 C4 56 C2 5A C0 09 47 +63 6E F7 06 37 19 02 50 B7 44 02 50 13 09 C9 80 +93 84 84 90 01 44 09 4B B5 6A 6D 4A 63 62 FB 02 +69 47 63 05 E4 00 09 47 63 6B F7 02 F2 40 62 44 +D2 44 42 49 B2 49 22 4A 92 4A 02 4B 05 61 82 80 +90 40 83 25 09 00 13 85 8A 57 05 04 EF 50 7F D5 +83 A7 49 5A E3 09 44 FD 51 09 91 04 C1 B7 62 44 +F2 40 D2 44 42 49 B2 49 22 4A 92 4A 02 4B 37 35 +02 50 13 05 C5 AC 05 61 6F 50 BF D0 37 35 02 50 +13 05 C5 AC EF 50 FF CF 83 A7 49 5A A5 BF 41 11 +06 C6 EF 30 70 37 B2 40 33 35 A0 00 41 01 82 80 +63 52 B0 04 01 11 22 CC 26 CA 4A C8 4E C6 06 CE +2E 89 AA 89 2A 84 81 44 EF 30 40 77 B3 67 25 03 +18 40 11 04 85 04 8A 07 CE 97 94 43 23 2E D4 FE +98 C3 E3 13 99 FE F2 40 62 44 D2 44 42 49 B2 49 +05 61 82 80 82 80 01 00 20 20 25 34 30 73 3A 20 +30 78 25 2D 33 78 0A 00 00 00 00 00 01 11 4E C6 +B7 09 02 50 03 A7 49 5A 22 CC 4A C8 06 CE 26 CA +89 47 2A 89 2E 84 63 EB E7 06 B7 44 02 50 93 84 +04 8B 9C 54 E1 8F 63 8F 87 00 73 00 50 10 93 07 +40 06 01 00 FD 17 C2 07 C1 83 E5 FF 9C 54 E1 8F +E3 95 87 FE DC 54 B3 F7 27 01 E3 90 27 FF 83 A7 +49 5A 1D C0 B9 E3 D4 54 13 47 F9 FF F2 40 75 8F +D8 D4 98 54 93 47 F4 FF 62 44 F9 8F 9C D4 42 49 +D2 44 B2 49 05 61 82 80 09 47 E3 7E F7 FC CC 54 +39 65 13 05 85 AB EF 50 DF C1 F1 B7 37 35 02 50 +13 05 C5 D7 EF 50 FF BE 49 B7 8C 54 39 65 13 05 +C5 A8 EF 50 1F C0 45 BF B7 07 02 50 03 A7 47 5A +89 47 63 E7 E7 00 B7 87 02 10 21 47 98 CB 82 80 +37 35 02 50 41 11 13 05 85 D9 06 C6 EF 50 7F BB +B2 40 B7 87 02 10 21 47 98 CB 41 01 82 80 01 11 +22 CC 26 CA 4A C8 52 C4 56 C2 3E 89 06 CE 4E C6 +2E 84 B2 84 36 8A BA 8A B7 87 02 10 98 4F 05 8B +75 DF 54 41 B7 09 02 50 09 47 23 A0 D7 08 14 45 +23 A2 D7 08 54 45 23 A4 D7 08 14 49 23 A6 D7 08 +54 49 23 A8 D7 08 14 4D 23 AA D7 08 54 4D 23 AC +D7 08 14 51 23 AE D7 08 54 51 23 A0 D7 0A 14 55 +23 A2 D7 0A 54 55 23 A4 D7 0A 14 59 23 A6 D7 0A +54 59 23 A8 D7 0A 14 5D 23 AA D7 0A 54 5D 23 AC +D7 0A 34 41 23 AE D7 0A 03 A6 49 5A 63 66 C7 0E +93 17 24 00 13 97 9A 00 13 77 07 20 91 8B 93 16 +5A 00 D9 8F 93 F6 06 1E 13 97 44 00 41 8B D5 8F +D9 8F 93 E7 17 00 37 87 02 10 1C CB 89 47 63 E4 +C7 10 37 44 02 50 13 04 04 8B 1C 54 5C 54 85 8B +9D E3 73 00 50 10 93 07 40 06 01 00 FD 17 C2 07 +C1 83 E5 FF 1C 54 5C 54 85 8B E5 D7 83 A7 49 5A +89 44 63 E4 F4 0A 5C 54 F9 9B 5C D4 1C 54 1C D4 +B7 87 02 10 83 A4 07 10 03 24 49 00 63 9F 84 06 +83 A4 47 10 03 24 89 00 63 93 84 10 83 A4 87 10 +03 24 C9 00 63 99 84 0E 83 A4 C7 10 03 24 09 01 +63 9D 84 0E 83 A4 07 11 03 24 49 01 63 95 84 0E +83 A4 47 11 03 24 89 01 63 9D 84 0C 83 A4 87 11 +03 24 C9 01 63 93 84 0C 83 A4 C7 11 03 24 09 02 +9D 45 63 95 84 02 F2 40 62 44 D2 44 42 49 B2 49 +22 4A 92 4A 05 61 82 80 37 35 02 50 13 05 05 DB +EF 50 3F A2 03 A6 49 5A 21 B7 81 45 83 A7 49 5A +B9 EB 05 45 EF 50 FF 9E 01 A0 4C 54 39 65 13 05 +85 AB EF 50 1F A2 5C 54 03 A7 49 5A F9 9B 5C D4 +1C 54 1C D4 E3 F6 E4 F4 37 35 02 50 13 05 05 DC +EF 50 3F 9E 35 BF 37 35 02 50 13 05 C5 D7 37 44 +02 50 EF 50 1F 9D 13 04 04 8B 1C 54 5C 54 85 8B +E3 89 07 EE 21 B7 39 69 13 09 C9 A8 13 05 C9 05 +EF 50 3F 9D 83 A7 49 5A C9 DF A6 85 13 05 89 08 +EF 50 3F 9C 83 A7 49 5A C9 D7 A2 85 13 05 09 0A +EF 50 3F 9B BD BF 89 45 95 BF 99 45 85 BF 85 45 +B5 B7 95 45 A5 B7 91 45 95 B7 8D 45 85 B7 01 11 +22 CC 26 CA 4A C8 4E C6 52 C4 56 C2 06 CE 5A C0 +AE 84 32 84 36 89 BA 89 3E 8A C6 8A 37 83 02 10 +03 28 83 01 13 78 18 00 E3 0C 08 FE 58 41 93 87 +FA FF 93 B7 17 00 23 20 E3 08 18 45 37 0B 02 50 +E1 8F 23 22 E3 08 58 45 23 24 E3 08 18 49 23 26 +E3 08 58 49 23 28 E3 08 18 4D 23 2A E3 08 58 4D +23 2C E3 08 18 51 23 2E E3 08 58 51 23 20 E3 0A +18 55 23 22 E3 0A 58 55 23 24 E3 0A 18 59 23 26 +E3 0A 58 59 23 28 E3 0A 18 5D 23 2A E3 0A 58 5D +23 2C E3 0A 38 41 23 2E E3 0A 83 26 4B 5A B5 C3 +89 47 63 E9 D7 08 05 45 EF 50 BF 8A 03 27 4B 5A +89 47 63 EA E7 06 06 04 26 0A 93 77 24 00 13 7A +0A 20 96 09 B3 E7 47 01 93 F9 09 1E 12 09 B3 E7 +37 01 13 79 09 01 8A 04 B3 E7 27 01 91 88 62 44 +C5 8F F2 40 D2 44 42 49 B2 49 22 4A 02 4B 93 E7 +17 00 37 87 02 10 D6 85 92 4A 1C CB 01 45 05 61 +F5 B6 13 87 EA FF 93 47 F4 FF 13 37 17 00 F9 8F +D1 DF 89 47 E3 F9 D7 F8 37 35 02 50 13 05 05 E5 +EF 50 3F 85 49 B7 37 35 02 50 13 05 05 DB EF 50 +5F 84 51 B7 37 35 02 50 13 05 05 DE EF 50 7F 83 +9D B7 41 11 06 C6 22 C4 26 C2 37 87 02 10 1C 4F +85 8B F5 DF B7 04 02 50 83 A7 44 5A 09 44 63 66 +F4 04 37 44 02 50 13 04 04 8B 1C 54 5C 54 85 8B +9D E3 73 00 50 10 93 07 40 06 01 00 FD 17 C2 07 +C1 83 E5 FF 1C 54 5C 54 85 8B E5 D7 03 A7 44 5A +89 47 63 E5 E7 04 5C 54 B2 40 92 44 F9 9B 5C D4 +1C 54 1C D4 22 44 41 01 82 80 37 35 02 50 13 05 +05 DB EF 50 0F FC 83 A7 44 5A E3 74 F4 FA 37 35 +02 50 13 05 C5 D7 37 44 02 50 EF 50 8F FA 13 04 +04 8B 1C 54 5C 54 85 8B C9 DF 4D BF 4C 54 39 65 +13 05 85 AB EF 50 EF FA 7D B7 01 00 52 65 63 65 +69 76 65 64 20 53 48 41 32 35 36 20 65 72 72 20 +69 6E 74 72 20 77 69 74 68 20 73 74 61 74 75 73 +20 3D 20 25 64 0A 00 00 52 65 63 65 69 76 65 64 +20 53 48 41 32 35 36 20 6E 6F 74 69 66 20 69 6E +74 72 20 77 69 74 68 20 73 74 61 74 75 73 20 3D +20 25 64 0A 00 00 00 00 41 74 20 6F 66 66 73 65 +74 20 5B 25 64 5D 2C 20 73 68 61 5F 64 69 67 65 +73 74 20 64 61 74 61 20 6D 69 73 6D 61 74 63 68 +21 0A 00 00 41 63 74 75 61 6C 20 20 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 45 78 70 65 +63 74 65 64 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 41 11 22 C4 37 04 02 50 03 27 44 5A +06 C6 89 47 63 E0 E7 04 37 47 02 50 13 07 07 8B +1C 53 54 53 D5 8F 9D E3 73 00 50 10 93 07 40 06 +01 00 FD 17 C2 07 C1 83 E5 FF 1C 53 54 53 D5 8F +E5 D7 83 26 44 5A 89 47 63 E5 D7 02 B2 40 22 44 +41 01 82 80 37 35 02 50 13 05 85 EA EF 50 6F E7 +37 47 02 50 13 07 07 8B 1C 53 54 53 D5 8F CD DF +C9 BF 22 44 B2 40 4C 53 39 65 13 05 C5 21 41 01 +6F 50 2F E7 B7 07 02 50 03 A7 47 5A 41 11 22 C4 +06 C6 8D 47 2A 84 63 ED E7 00 0A 04 31 88 13 64 +14 00 B7 07 02 10 B2 40 80 CB 22 44 41 01 82 80 +AA 85 39 65 13 05 C5 24 EF 50 AF E3 F9 BF B7 07 +02 50 03 A7 47 5A 41 11 22 C4 06 C6 8D 47 2A 84 +63 ED E7 00 0A 04 31 88 13 64 24 00 B7 07 02 10 +B2 40 80 CB 22 44 41 01 82 80 AA 85 39 65 13 05 +05 27 EF 50 0F E0 F9 BF B7 07 02 50 03 A7 47 5A +41 11 22 C4 06 C6 8D 47 2A 84 63 ED E7 00 0A 04 +31 88 13 64 14 02 B7 07 02 10 B2 40 80 CB 22 44 +41 01 82 80 AA 85 39 65 13 05 45 29 EF 50 6F DC +F9 BF B7 07 02 50 03 A7 47 5A 41 11 22 C4 06 C6 +8D 47 2A 84 63 ED E7 00 0A 04 31 88 13 64 24 02 +B7 07 02 10 B2 40 80 CB 22 44 41 01 82 80 AA 85 +39 65 13 05 05 2C EF 50 CF D8 F9 BF B7 07 02 50 +03 A7 47 5A 8D 47 63 E8 E7 00 B7 07 02 10 05 47 +23 A8 E7 62 82 80 37 35 02 50 41 11 13 05 45 EC +06 C6 EF 50 0F D4 B2 40 B7 07 02 10 05 47 23 A8 +E7 62 41 01 82 80 B7 07 02 50 03 A7 47 5A 89 47 +63 E7 E7 00 B7 07 02 10 41 47 98 CB 82 80 37 35 +02 50 41 11 13 05 85 EE 06 C6 EF 50 8F D0 B2 40 +B7 07 02 10 41 47 98 CB 41 01 82 80 01 11 22 CC +4A C8 06 CE 26 CA 4E C6 52 C4 2E 84 32 89 B7 07 +02 10 98 4F 05 8B 75 DF B7 04 02 10 37 06 FE EF +93 87 07 08 13 06 06 F8 93 85 04 10 BE 86 91 07 +33 87 C7 00 2A 97 18 43 98 C2 E3 99 B7 FE B7 09 +02 50 83 A7 49 5A 09 4A 63 66 FA 14 93 17 24 00 +B1 8B 93 E7 17 00 9C C8 37 47 02 50 13 07 07 8B +1C 53 54 53 D5 8F 9D E3 73 00 50 10 93 07 40 06 +01 00 FD 17 C2 07 C1 83 E5 FF 1C 53 54 53 D5 8F +E5 D7 83 A7 49 5A 09 44 63 65 F4 0E B7 07 02 10 +83 A4 07 10 03 24 49 00 63 15 94 0C 83 A4 47 10 +03 24 89 00 63 92 84 16 83 A4 87 10 03 24 C9 00 +63 9A 84 14 83 A4 C7 10 03 24 09 01 63 9A 84 14 +83 A4 07 11 03 24 49 01 63 92 84 14 83 A4 47 11 +03 24 89 01 63 96 84 14 83 A4 87 11 03 24 C9 01 +63 9A 84 14 83 A4 C7 11 03 24 09 02 63 92 84 14 +83 A4 07 12 03 24 49 02 63 9A 84 12 83 A4 47 12 +03 24 89 02 63 92 84 12 83 A4 87 12 03 24 C9 02 +63 96 84 10 83 A4 C7 12 03 24 09 03 63 9C 84 0E +83 A4 07 13 03 24 49 03 63 98 84 10 83 A4 47 13 +03 24 89 03 63 92 84 0E 83 A4 87 13 03 24 C9 03 +63 92 84 0E 83 A4 C7 13 03 24 09 04 BD 45 63 9B +84 00 F2 40 62 44 D2 44 42 49 B2 49 22 4A 05 61 +82 80 81 45 83 A7 49 5A B5 E7 05 45 EF 50 6F B6 +01 A0 4C 53 39 65 13 05 C5 21 EF 50 8F B9 83 A7 +49 5A E3 75 F4 F0 37 35 02 50 13 05 05 F1 EF 50 +4F B6 ED BD 37 35 02 50 13 05 05 F0 EF 50 6F B5 +93 17 24 00 03 A7 49 5A B1 8B 93 E7 17 00 9C C8 +E3 74 EA EA 37 35 02 50 13 05 85 EA EF 50 6F B3 +37 47 02 50 13 07 07 8B 1C 53 54 53 D5 8F E3 8D +07 E8 45 BD 39 69 13 09 C9 21 13 05 09 0D EF 50 +4F B3 83 A7 49 5A D1 D3 A6 85 13 05 C9 0F EF 50 +4F B2 83 A7 49 5A B5 DB A2 85 13 05 49 11 EF 50 +4F B1 A5 B7 89 45 B9 BF 85 45 A9 BF 91 45 99 BF +8D 45 89 BF AD 45 B9 B7 B5 45 A9 B7 A9 45 99 B7 +95 45 89 B7 B9 45 3D BF A5 45 2D BF A1 45 1D BF +9D 45 0D BF 99 45 3D B7 B1 45 2D B7 01 11 26 CA +4A C8 06 CE 22 CC 4E C6 52 C4 AE 84 32 88 36 89 +B7 07 02 10 98 4F 05 8B 75 DF 37 04 02 10 37 06 +FE EF 93 87 07 08 13 06 06 F8 93 05 04 10 BE 86 +91 07 33 87 C7 00 2A 97 18 43 98 C2 E3 99 B7 FE +03 27 48 00 B7 09 02 50 09 4A 98 C3 83 27 88 00 +23 22 F4 10 83 27 C8 00 23 24 F4 10 83 27 08 01 +23 26 F4 10 83 27 48 01 23 28 F4 10 83 27 88 01 +23 2A F4 10 83 27 C8 01 23 2C F4 10 83 27 08 02 +23 2E F4 10 83 27 48 02 23 20 F4 12 83 27 88 02 +23 22 F4 12 83 27 C8 02 23 24 F4 12 83 27 08 03 +23 26 F4 12 83 27 48 03 23 28 F4 12 83 27 88 03 +23 2A F4 12 83 27 C8 03 23 2C F4 12 83 27 08 04 +23 2E F4 12 83 A7 49 5A 63 66 FA 14 93 97 24 00 +B1 8B 93 E7 27 04 1C C8 37 47 02 50 13 07 07 8B +1C 53 54 53 D5 8F 9D E3 73 00 50 10 93 07 40 06 +01 00 FD 17 C2 07 C1 83 E5 FF 1C 53 54 53 D5 8F +E5 D7 83 A7 49 5A 09 44 63 65 F4 0E B7 07 02 10 +83 A4 07 10 03 24 49 00 63 95 84 0C 83 A4 47 10 +03 24 89 00 63 92 84 16 83 A4 87 10 03 24 C9 00 +63 9A 84 14 83 A4 C7 10 03 24 09 01 63 9A 84 14 +83 A4 07 11 03 24 49 01 63 92 84 14 83 A4 47 11 +03 24 89 01 63 96 84 14 83 A4 87 11 03 24 C9 01 +63 9A 84 14 83 A4 C7 11 03 24 09 02 63 92 84 14 +83 A4 07 12 03 24 49 02 63 9A 84 12 83 A4 47 12 +03 24 89 02 63 92 84 12 83 A4 87 12 03 24 C9 02 +63 96 84 10 83 A4 C7 12 03 24 09 03 63 9C 84 0E +83 A4 07 13 03 24 49 03 63 98 84 10 83 A4 47 13 +03 24 89 03 63 92 84 0E 83 A4 87 13 03 24 C9 03 +63 92 84 0E 83 A4 C7 13 03 24 09 04 BD 45 63 9B +84 00 F2 40 62 44 D2 44 42 49 B2 49 22 4A 05 61 +82 80 81 45 83 A7 49 5A B5 E7 05 45 EF 50 6F 8A +01 A0 4C 53 39 65 13 05 C5 21 EF 50 8F 8D 83 A7 +49 5A E3 75 F4 F0 37 35 02 50 13 05 05 F1 EF 50 +4F 8A ED BD 37 35 02 50 13 05 05 F0 EF 50 6F 89 +93 97 24 00 03 A7 49 5A B1 8B 93 E7 27 04 1C C8 +E3 74 EA EA 37 35 02 50 13 05 85 EA EF 50 6F 87 +37 47 02 50 13 07 07 8B 1C 53 54 53 D5 8F E3 8D +07 E8 45 BD 39 69 13 09 C9 21 13 05 C9 12 EF 50 +4F 87 83 A7 49 5A D1 D3 A6 85 13 05 89 15 EF 50 +4F 86 83 A7 49 5A B5 DB A2 85 13 05 09 17 EF 50 +4F 85 A5 B7 89 45 B9 BF 85 45 A9 BF 91 45 99 BF +8D 45 89 BF AD 45 B9 B7 B5 45 A9 B7 A9 45 99 B7 +95 45 89 B7 B9 45 3D BF A5 45 2D BF A1 45 1D BF +9D 45 0D BF 99 45 3D B7 B1 45 2D B7 52 65 63 65 +69 76 65 64 20 53 48 41 35 31 32 20 6E 6F 74 69 +66 20 69 6E 74 72 20 77 69 74 68 20 73 74 61 74 +75 73 20 3D 20 25 64 0A 00 00 00 00 53 48 41 35 +31 32 3A 20 53 65 74 20 6D 6F 64 65 3A 20 30 78 +25 78 20 61 6E 64 20 69 6E 69 74 0A 00 00 00 00 +53 48 41 35 31 32 3A 20 53 65 74 20 6D 6F 64 65 +3A 20 30 78 25 78 20 61 6E 64 20 6E 65 78 74 0A +00 00 00 00 53 48 41 35 31 32 3A 20 53 65 74 20 +6D 6F 64 65 3A 20 30 78 25 78 20 61 6E 64 20 69 +6E 69 74 20 77 69 74 68 20 6C 61 73 74 0A 00 00 +53 48 41 35 31 32 3A 20 53 65 74 20 6D 6F 64 65 +3A 20 30 78 25 78 20 61 6E 64 20 6E 65 78 74 20 +77 69 74 68 20 6C 61 73 74 0A 00 00 41 74 20 6F +66 66 73 65 74 20 5B 25 64 5D 2C 20 73 68 61 5F +64 69 67 65 73 74 20 64 61 74 61 20 6D 69 73 6D +61 74 63 68 21 0A 00 00 41 63 74 75 61 6C 20 20 +20 64 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +45 78 70 65 63 74 65 64 20 64 61 74 61 3A 20 30 +78 25 78 0A 00 00 00 00 41 74 20 6F 66 66 73 65 +74 20 5B 25 64 5D 2C 20 73 68 61 5F 64 69 67 65 +73 74 20 64 61 74 61 20 6D 69 73 6D 61 74 63 68 +21 0A 00 00 41 63 74 75 61 6C 20 20 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 45 78 70 65 +63 74 65 64 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 85 47 B3 95 B7 00 71 05 1C 41 ED 8F +F5 DF 82 80 41 11 06 C6 AA 86 2E 87 B2 87 01 CD +01 CE 13 06 00 02 63 7F B6 04 B7 07 02 50 83 A7 +47 5A B1 E3 01 A0 99 C5 B7 07 02 50 83 A7 47 5A +85 E7 01 A0 01 46 ED DB 93 05 27 00 CC D3 85 45 +23 80 B7 00 A3 80 C7 00 B2 40 13 85 27 00 3A 86 +B6 85 41 01 6F 20 80 6B 37 35 02 50 13 05 05 F3 +EF 40 3F E0 F9 B7 37 35 02 50 13 05 45 F8 EF 40 +5F DF 4D BF 13 96 35 00 42 06 41 82 93 05 00 10 +63 15 B6 02 13 06 37 00 D0 D3 09 46 23 80 C7 00 +05 46 A3 80 C7 00 23 81 07 00 B2 40 13 85 37 00 +3A 86 B6 85 41 01 6F 20 60 66 13 76 F6 0F 69 B7 +41 11 06 C6 B2 87 19 C9 19 CA 11 47 63 70 B7 02 +B7 07 02 50 83 A7 47 5A B9 E3 01 A0 99 C5 B7 07 +02 50 83 A7 47 5A 8D E7 01 A0 75 DA 93 86 25 00 +13 97 35 00 94 C7 85 46 23 80 D7 00 A3 80 E7 00 +B2 40 2E 86 AA 85 41 01 13 85 27 00 6F 20 00 61 +37 35 02 50 13 05 C5 FC EF 40 BF D5 F1 B7 37 35 +02 50 13 05 05 01 EF 40 DF D4 45 BF 41 11 06 C6 +29 C5 A1 C5 89 47 63 0A F6 08 63 ED C7 04 51 CA +5C 4D 21 47 13 06 20 02 D8 C5 23 A2 05 00 90 C5 +85 8B 11 48 13 07 C5 01 A9 CF A2 06 23 90 05 00 +B3 E7 06 01 5C C9 5C C9 5C 49 F5 47 1C CD 1C 43 +89 8B F5 DF B2 40 41 01 82 80 B7 07 02 50 83 A7 +47 5A 91 E3 01 A0 37 35 02 50 13 05 05 05 EF 40 +5F CE CD BF 8D 47 63 14 F6 02 49 46 41 47 21 48 +5C 4D D8 C5 23 A2 05 00 90 C5 85 8B 13 07 C5 01 +CD F7 B7 07 02 50 83 A7 47 5A 8D E3 01 A0 B7 07 +02 50 83 A7 47 5A 95 E3 01 A0 69 46 31 47 19 48 +C1 BF 13 06 40 02 1D 47 09 48 D9 B7 37 35 02 50 +13 05 05 0C EF 40 FF C8 D1 BF 37 35 02 50 13 05 +05 09 EF 40 1F C8 C9 BF 41 11 06 C6 0D C5 85 C5 +31 C6 85 47 63 1E F6 02 5C 4D 13 07 20 02 98 C5 +85 8B 11 46 13 07 C5 01 B1 E3 B7 07 02 50 83 A7 +47 5A AD EB 01 A0 B7 07 02 50 83 A7 47 5A 91 E3 +01 A0 37 35 02 50 13 05 45 0F EF 40 9F C3 CD BF +B7 07 02 50 83 A7 47 5A 9D EF 01 A0 5C 4D 13 07 +A0 02 98 C5 85 8B 13 07 C5 01 E1 D3 93 97 86 00 +D1 8F 23 90 05 00 23 A6 05 00 23 A2 05 00 93 E7 +07 02 5C C9 5C C9 F5 47 1C CD 1C 43 89 8B F5 DF +B2 40 41 01 82 80 37 35 02 50 13 05 05 14 EF 40 +5F BE 65 BF 37 35 02 50 13 05 45 17 EF 40 7F BD +51 B7 5D 71 86 C6 A2 C4 A6 C2 CA C0 15 CD 8D CD +2A 84 B1 CE 03 D8 06 00 05 45 63 0A A8 04 25 CE +05 45 63 10 A6 04 13 08 20 02 11 46 48 4C 23 A4 +05 01 93 04 C4 01 05 89 35 E1 B7 07 02 50 83 A7 +47 5A 63 95 07 10 01 A0 B7 07 02 50 83 A7 47 5A +91 E3 01 A0 37 35 02 50 13 05 85 1A EF 40 7F B7 +CD BF B7 07 02 50 83 A7 47 5A F1 EB 01 A0 11 C7 +03 58 07 00 05 45 E3 14 A8 FA 63 06 06 10 05 47 +63 19 E6 0A BE 86 05 46 22 85 26 44 B6 40 96 44 +06 49 61 61 D1 B5 13 08 A0 02 49 BF A2 07 D1 8F +23 90 05 00 23 A6 05 00 23 A2 05 00 93 E7 07 03 +5C C8 5C C8 02 CA 02 CC 02 CE 02 D0 02 D2 02 D4 +02 D6 02 D8 02 DA 02 DC 02 DE 91 C6 03 A9 86 00 +89 47 63 E8 27 09 85 47 23 1A F1 00 13 05 61 01 +19 C3 50 53 3D EA 85 47 23 00 F5 00 A3 00 05 00 +D2 47 1C D0 E2 47 5C D0 F2 47 1C D4 82 57 5C D4 +92 57 1C D8 A2 57 5C D8 B2 57 1C DC C2 57 5C DC +D2 57 3C C0 E2 57 7C C0 F2 57 3C C4 F5 47 1C CC +9C 40 89 8B F5 DF B6 40 26 44 96 44 06 49 61 61 +82 80 B7 07 02 50 83 A7 47 5A 9D EF 01 A0 37 35 +02 50 13 05 45 23 EF 40 DF A8 0D B7 37 35 02 50 +13 05 05 27 EF 40 FF A7 FD B5 BA 85 EF 20 00 32 +41 BF 4A 86 B6 85 48 08 3A C6 EF 20 20 31 5C 08 +32 47 33 85 27 01 AD B7 37 35 02 50 13 05 C5 1E +EF 40 3F A5 65 BF BE 86 01 46 FD BD 41 11 06 C6 +19 C3 23 20 07 00 4D C1 C5 C1 51 CE 9C 45 D5 CB +5C 4D 13 03 C5 01 89 8B E5 C3 29 4F B7 18 04 10 +85 4E 8D 4F B5 CE 03 28 03 00 13 58 88 00 13 78 +F8 01 33 08 0F 41 0E 08 63 F3 06 01 36 88 63 0B +08 04 93 77 16 00 C1 E7 B2 87 42 8E 63 00 D8 05 +93 F5 37 00 C1 E9 3E 85 63 F1 CF 03 13 05 CE FF +71 99 11 05 3E 95 8C 43 91 07 23 A0 B8 80 E3 9C +A7 FE 13 7E 3E 00 63 F5 CE 0B 83 55 05 00 79 1E +93 07 25 00 23 90 B8 80 63 06 0E 00 83 C7 07 00 +23 80 F8 80 42 96 B3 86 06 41 49 D7 23 20 07 01 +B2 40 41 01 82 80 BD D2 B7 07 02 50 83 A7 47 5A +91 E3 01 A0 37 35 02 50 13 05 C5 2A EF 40 7F 98 +CD BF B7 07 02 50 83 A7 47 5A 8D EF 01 A0 83 45 +06 00 13 0E F8 FF 93 07 16 00 23 80 B8 80 E3 E9 +CE F7 5D B7 83 D5 07 00 79 1E 89 07 23 90 B8 80 +E3 E6 CF F7 3E 85 41 B7 B7 07 02 50 83 A7 47 5A +89 EB 01 A0 37 35 02 50 13 05 85 2E EF 40 7F 93 +75 BF 37 35 02 50 13 05 C5 31 EF 40 9F 92 D5 B7 +AA 87 9D B7 41 11 06 C6 22 C4 61 C5 F9 C1 69 C2 +19 C3 23 20 07 00 03 C8 05 00 63 1A 08 08 03 C8 +15 00 63 0F 08 06 83 A8 C5 00 13 03 F0 0F 05 48 +96 08 63 7F 13 05 41 68 33 B8 08 01 37 03 00 01 +13 48 18 00 33 B3 68 00 13 43 13 00 09 08 1A 98 +13 03 F8 FF 0E 03 B3 DE 68 00 93 FE FE 0F 37 1E +04 10 23 00 DE 81 61 13 9D 4E 63 D1 6E 02 33 D3 +68 00 13 73 F3 0F 23 00 6E 80 11 43 63 18 68 00 +13 D3 88 00 13 73 F3 0F 23 00 6E 80 13 78 F8 0F +37 13 04 10 93 F8 F8 0F 23 00 13 81 23 00 03 81 +05 48 23 80 05 01 13 08 E0 02 23 2C 05 01 03 A8 +C5 00 63 0D 08 02 83 A8 45 00 B3 08 18 41 63 F7 +D8 02 B7 07 02 50 83 A7 47 5A 63 99 07 14 01 A0 +A1 D2 B7 07 02 50 83 A7 47 5A 91 E3 01 A0 37 35 +02 50 13 05 05 35 EF 40 DF 83 CD BF E1 C2 83 A8 +85 00 93 02 C5 01 93 03 10 03 C0 41 B3 8E 88 40 +63 10 08 02 63 F3 D6 01 B6 8E 63 90 0E 04 23 2C +75 00 23 A2 05 00 C0 41 B3 8E 88 40 E3 04 08 FE +63 6E 18 01 63 ED D6 09 63 91 0E 02 63 94 08 09 +B7 07 02 50 83 A7 47 5A F9 EB 01 A0 B3 0E 88 40 +63 F3 D6 01 B6 8E E3 85 0E FE 03 A8 02 00 13 78 +48 00 E3 0C 08 FE B7 0F 01 04 93 8F 0F 10 A2 9F +8A 0F 7E 88 01 4E 03 2F 08 00 03 23 08 10 B3 08 +F8 41 B2 98 33 43 E3 01 23 A0 68 00 05 0E 11 08 +E3 13 DE FF 72 94 13 18 2E 00 C0 C1 42 96 B3 86 +C6 41 11 C7 03 28 07 00 72 98 23 20 07 01 95 E3 +91 C6 03 A8 C5 00 83 A8 85 00 81 BF B2 40 22 44 +41 01 82 80 33 08 18 41 23 A6 05 01 89 BF B6 8E +A5 B7 83 A8 85 00 B7 0E 01 04 93 8E 0E 10 C6 9E +13 08 20 03 8A 0E B3 0F 18 41 E3 83 08 FD 76 88 +01 4E 03 2F 08 00 03 23 08 10 B3 08 D8 41 BE 98 +33 43 E3 01 23 A0 68 00 05 0E 11 08 E3 63 FE FF +11 48 63 84 0F 00 13 98 2F 00 C2 97 51 BF 37 35 +02 50 13 05 85 3D EF 40 CF F0 05 B7 37 35 02 50 +13 05 45 38 EF 40 EF EF 5D B5 41 11 06 C6 1D C5 +95 C5 83 C7 05 00 A1 C3 13 07 C5 01 1C 43 91 8B +F5 DF B2 40 D9 47 1C CD 23 90 05 00 23 A2 05 00 +23 A4 05 00 23 A6 05 00 41 01 82 80 B7 07 02 50 +83 A7 47 5A 91 E3 01 A0 37 35 02 50 13 05 05 41 +EF 40 2F EB CD BF B7 07 02 50 83 A7 47 5A 91 E3 +01 A0 37 35 02 50 13 05 05 44 EF 40 8F E9 CD BF +B7 07 02 30 C8 4B 82 80 B7 07 04 30 3E 95 08 41 +82 80 B7 07 04 30 AA 97 8C C3 82 80 B7 07 02 50 +03 A7 47 5A 8D 47 63 E8 E7 00 37 07 02 30 1C 4F +F9 9B 1C CF 82 80 41 65 41 11 13 05 05 3C 06 C6 +EF 40 2F E7 37 07 02 30 1C 4F B2 40 F9 9B 1C CF +41 01 82 80 41 11 22 C4 37 04 02 50 83 27 44 5A +26 C2 06 C6 91 44 63 EF F4 02 B7 07 02 30 CC 4F +99 47 99 81 9D 89 63 8F F5 04 B9 CD 9D 47 63 97 +F5 00 83 27 44 5A A5 EF 3D 45 01 A8 41 65 13 05 +C5 3D EF 40 0F E2 13 05 F0 0F B2 40 22 44 92 44 +41 01 82 80 37 35 02 50 13 05 85 47 EF 40 6F DE +B7 07 02 30 CC 4F 99 47 99 81 9D 89 E3 9F F5 FA +83 27 44 5A 63 F8 F4 00 37 35 02 50 13 05 05 4A +EF 40 2F DC 01 45 D1 B7 03 27 44 5A 85 47 63 E8 +E7 00 05 45 B2 40 22 44 92 44 41 01 82 80 37 35 +02 50 13 05 05 4E EF 40 CF D9 05 45 E5 B7 37 35 +02 50 13 05 85 51 EF 40 CF D8 3D 45 79 B7 B7 07 +02 50 03 A7 47 5A 41 11 22 C4 06 C6 8D 47 2A 84 +63 EC E7 00 37 07 02 30 5C 4F B2 40 C1 9B C1 8F +22 44 5C CF 41 01 82 80 AA 85 41 65 13 05 05 42 +EF 40 2F D7 C5 B7 B7 07 02 50 03 A7 47 5A 41 11 +22 C4 06 C6 8D 47 2A 84 63 E6 E7 02 B7 07 03 30 +D8 5F 93 17 84 00 B3 66 E4 00 91 C7 B7 07 00 FF +7D 8F B3 66 87 00 B2 40 22 44 B7 07 03 30 D4 DF +41 01 82 80 AA 85 41 65 13 05 85 44 EF 40 6F D2 +F1 B7 B7 07 02 50 03 A7 47 5A 41 11 22 C4 06 C6 +26 C2 8D 47 2A 84 63 EC E7 04 B7 17 02 30 84 43 +85 47 63 ED 87 02 63 E2 97 02 93 77 14 00 33 67 +94 00 81 C7 F9 98 33 E7 84 00 B2 40 22 44 B7 17 +02 30 98 C3 92 44 41 01 82 80 41 65 13 05 85 4C +EF 40 2F CD 05 45 EF 40 CF C8 C1 BF 41 65 13 05 +C5 4A EF 40 0F CC 05 45 EF 40 AF C7 7D BF AA 85 +41 65 13 05 05 47 EF 40 CF CA 45 B7 B7 07 02 50 +03 A7 47 5A 41 11 22 C4 06 C6 8D 47 2A 84 63 E0 +E7 04 B7 07 03 30 DC 5F 13 17 84 00 19 CF 37 07 +00 FF 79 8C 13 44 F4 FF 7D 8C 79 8C B7 07 03 30 +B2 40 C0 DF 22 44 41 01 82 80 13 44 F4 FF 7D 8C +B7 07 03 30 B2 40 C0 DF 22 44 41 01 82 80 AA 85 +41 65 13 05 45 4E EF 40 CF C4 65 BF 09 CD 01 47 +B7 06 02 30 19 A0 63 08 E5 00 9C 42 05 07 85 8B +FD FB 01 45 82 80 05 45 82 80 79 71 4E CE B7 09 +02 50 22 D4 83 A7 49 5A 37 04 02 30 26 D2 04 44 +4A D0 06 D6 52 CC 0D 49 63 6D F9 00 40 44 B2 50 +22 85 22 54 02 59 F2 49 62 4A A6 85 92 54 45 61 +82 80 41 6A 13 0A 0A 3C A6 85 13 05 CA 14 EF 40 +4F BE 83 A7 49 5A 40 44 E3 7B F9 FC A2 85 13 05 +0A 17 EF 40 0F BD E1 B7 79 71 4A D0 37 09 02 50 +03 27 49 5A 22 D4 26 D2 06 D6 4E CE 52 CC 2A C4 +2E C6 89 47 2A 84 AE 84 63 E9 E7 14 B7 07 04 00 +63 EB 87 12 B7 C7 5E BA 93 87 17 A1 63 82 F4 02 +B7 D7 BE BA 93 87 E7 AF 63 80 F4 14 41 65 A6 85 +13 05 85 58 EF 40 EF B7 05 45 EF 40 8F B3 01 A0 +B7 04 00 50 37 0A 00 40 37 07 02 30 50 4B 75 C2 +13 07 06 02 63 6F E4 0C 13 77 36 00 11 C3 11 06 +37 07 02 30 4C 4B 03 25 49 5A 89 46 23 20 BA 00 +03 28 47 01 93 59 26 00 23 20 0A 01 58 4B 23 20 +EA 00 63 E5 A6 10 93 96 29 00 D2 87 D2 96 37 05 +02 30 63 88 09 00 58 49 91 07 23 AE E7 FE E3 9C +D7 FE B7 07 02 30 D8 4B 69 C7 93 77 C6 FF 93 06 +07 02 B6 97 63 6F F4 0A 93 77 37 00 91 C3 11 07 +B7 07 02 30 D0 4B 83 25 49 5A 13 54 27 00 90 C0 +D0 4B 89 46 90 C0 D8 4B 98 C0 63 E2 B6 0C 63 0A +04 0C 13 17 24 00 A6 87 26 97 37 06 02 30 54 4A +91 07 23 AE D7 FE E3 1C F7 FE B7 07 02 30 23 A6 +07 00 8D 47 63 F8 B7 00 41 65 89 45 13 05 05 42 +EF 40 2F AA 37 07 02 30 5C 4F B2 50 22 54 C1 9B +93 E7 27 00 5C CF 92 54 02 59 F2 49 62 4A 45 61 +82 80 41 65 A2 85 13 05 C5 5B EF 40 8F A7 05 45 +EF 40 2F A3 01 A0 41 65 A2 85 13 05 45 55 EF 40 +4F A6 05 45 EF 40 EF A1 01 A0 37 35 02 50 13 05 +05 57 EF 40 0F A3 5D B5 B7 04 02 50 37 0A 02 40 +E1 BD 01 14 41 65 3A 86 B3 05 34 41 13 05 85 61 +EF 40 2F A3 05 45 EF 40 CF 9E 01 A0 37 35 02 50 +13 05 05 59 32 C2 EF 40 CF 9F 12 46 ED B5 37 35 +02 50 13 05 45 5A EF 40 CF 9E 83 25 49 5A 15 F8 +A9 B7 23 A6 07 00 B9 BF 79 71 4E CE B7 09 02 50 +03 A7 49 5A 4A D0 06 D6 22 D4 26 D2 52 CC 56 CA +5A C8 2A C4 2E C6 8D 47 2A 89 63 E6 E7 04 01 44 +B7 04 00 40 63 77 A4 02 B7 07 02 30 D8 4B 11 04 +93 87 44 00 98 C0 B3 05 F4 40 37 06 02 30 63 7A +24 01 54 4A 91 07 33 87 B7 00 23 AE D7 FE E3 6A +27 FF B2 50 22 54 92 54 02 59 F2 49 62 4A D2 4A +42 4B 45 61 82 80 37 35 02 50 01 44 13 05 85 5B +EF 40 2F 96 E3 7F 24 FD C1 6A B7 04 00 40 0D 4B +93 8A 4A 67 37 0A 02 30 11 A0 BA 84 83 A7 49 5A +A6 85 56 85 E3 7A FB F8 90 40 11 04 EF 40 6F 95 +83 27 4A 01 13 87 44 00 9C C0 E3 60 24 FF 55 B7 +41 11 26 C2 4A C0 06 C6 22 C4 B7 07 04 00 2A 89 +AE 84 63 E0 A7 06 D5 C4 81 47 37 07 02 30 19 A0 +63 83 F4 06 00 43 85 07 05 88 7D F8 B7 17 03 30 +03 A6 87 80 13 77 D6 FE 23 A4 E7 80 63 0C 09 00 +81 47 B7 06 04 30 33 87 D7 00 23 20 07 00 91 07 +E3 EB 27 FF B2 40 22 44 B7 07 02 30 05 47 98 D3 +B7 17 03 30 23 A4 C7 80 92 44 02 49 01 45 41 01 +82 80 AA 85 41 65 13 05 05 68 EF 40 8F 8C 05 45 +EF 40 2F 88 49 BF B7 07 02 50 03 A7 47 5A 85 47 +63 F8 E7 00 37 35 02 50 13 05 C5 5D EF 40 6F 88 +85 47 E3 85 F4 F8 37 07 02 30 13 06 07 02 85 46 +19 A0 E3 8D 84 F6 14 C2 1C 43 05 04 85 8B F5 FB +B5 B7 B7 07 02 50 03 A7 47 5A 85 47 E3 F0 E7 F6 +37 35 02 50 13 05 C5 5D EF 40 AF 84 81 BF B7 07 +02 50 03 A7 47 5A 41 11 22 C4 06 C6 8D 47 2A 84 +63 FB E7 04 95 47 63 FC A7 02 37 36 02 50 AA 85 +41 65 13 06 86 62 13 05 45 6A EF 40 8F 83 B7 07 +03 30 23 A4 87 62 37 07 03 30 83 27 47 62 B2 40 +22 44 93 E7 17 00 23 22 F7 62 41 01 82 80 29 C1 +AA 85 37 36 02 50 41 65 13 06 46 61 13 05 45 6A +EF 40 2F 80 29 A0 61 D9 95 47 E3 E2 A7 FC B7 07 +03 30 15 47 23 A4 E7 62 37 07 03 30 83 27 47 62 +B2 40 22 44 93 E7 17 00 23 22 F7 62 41 01 82 80 +37 36 02 50 41 65 13 06 46 60 81 45 13 05 45 6A +EF 30 3F FC 37 07 03 30 83 27 47 62 B2 40 22 44 +93 E7 17 00 23 22 F7 62 41 01 82 80 B7 07 03 30 +05 47 23 A0 E7 62 82 80 37 17 02 30 1C 43 85 8B +F5 FF 82 80 0D 89 13 65 45 00 B7 17 02 30 88 C7 +82 80 B7 17 02 30 05 47 98 CF 82 80 B7 17 02 30 +DC 4F 85 8B 89 EB B7 06 04 30 37 17 02 30 9C 42 +5C 4F 85 8B ED DF 82 80 B7 17 02 30 05 47 98 C3 +82 80 B7 28 02 30 03 A8 C8 00 13 78 18 00 E3 1C +08 FE 23 AE A8 00 23 A0 B8 02 23 A2 E8 02 23 A4 +F8 02 41 C6 B7 07 00 12 85 07 37 26 02 30 1C C6 +50 42 85 65 FD 15 6D 8E 13 75 C7 FF 93 57 27 00 +42 06 41 82 36 95 37 27 02 30 99 CB 5C 47 91 83 +ED 8F E3 8D C7 FE 9C 42 91 06 5C D7 E3 98 A6 FE +B7 27 02 30 DC 47 05 47 37 26 02 30 93 F5 37 00 +85 46 63 97 E5 00 5C 46 13 F7 37 00 E3 0D D7 FE +89 8B 85 CB B7 07 02 50 03 A7 47 5A 41 11 06 C6 +89 47 63 E1 E7 02 B7 27 02 30 09 47 98 C7 05 45 +EF 30 3F E7 B2 40 41 01 82 80 B7 07 00 02 85 07 +AD BF 82 80 37 35 02 50 13 05 85 63 EF 30 7F E7 +D9 BF 41 11 06 C6 37 23 02 30 83 28 C3 00 93 F8 +18 00 E3 9C 08 FE 23 2E A3 00 23 20 B3 02 23 22 +E3 02 23 24 F3 02 49 C2 B7 07 00 12 85 07 37 26 +02 30 1C C6 50 42 85 65 FD 15 6D 8E 13 75 C7 FF +93 57 27 00 42 06 41 82 36 95 37 27 02 30 99 CB +5C 47 91 83 ED 8F E3 8D C7 FE 9C 42 91 06 5C D7 +E3 98 A6 FE B7 27 02 30 DC 47 05 47 37 26 02 30 +93 F5 37 00 85 46 63 97 E5 00 5C 46 13 F7 37 00 +E3 0D D7 FE 89 8B 8D C7 63 06 08 04 B7 07 02 50 +03 A7 47 5A 89 47 63 E4 E7 04 B7 27 02 30 09 47 +98 C7 B2 40 41 01 82 80 B7 07 00 02 85 07 41 B7 +E3 09 08 FE 37 35 02 50 13 05 85 6A EF 30 7F DB +B7 27 02 30 09 47 98 C7 05 45 EF 30 9F D8 B2 40 +41 01 82 80 37 35 02 50 13 05 85 66 C5 B7 37 35 +02 50 13 05 85 66 EF 30 DF D8 45 BF 37 28 02 30 +83 26 C8 00 85 8A ED FE 23 2E A8 00 23 20 B8 02 +23 22 E8 02 23 24 F8 02 01 CA B7 07 00 12 85 07 +37 27 02 30 1C C7 82 80 B7 07 00 02 85 07 37 27 +02 30 1C C7 82 80 B7 27 02 30 DC 43 05 66 7D 16 +F1 8F 13 F7 C5 FF 13 D8 25 00 93 96 07 01 B3 05 +E5 00 C1 82 37 27 02 30 63 0C 08 00 5C 47 91 83 +F1 8F E3 8D D7 FE 1C 41 11 05 5C D7 E3 98 A5 FE +01 45 82 80 B7 28 02 30 03 A8 C8 00 13 78 18 00 +E3 1C 08 FE 23 AA A8 00 23 AC B8 00 23 A2 E8 02 +23 A4 F8 02 41 C2 B7 07 12 00 85 07 37 26 02 30 +1C C6 5C 42 09 83 15 C3 0A 07 05 66 B3 85 E6 00 +7D 16 37 27 02 30 5C 47 91 83 F1 8F ED DF 1C 5B +91 06 23 AE F6 FE E3 98 B6 FE B7 27 02 30 DC 47 +05 47 93 F6 37 00 63 9A E6 00 37 26 02 30 85 46 +5C 46 13 F7 37 00 E3 0D D7 FE 89 8B 85 CB B7 07 +02 50 03 A7 47 5A 41 11 06 C6 89 47 63 E1 E7 02 +B7 27 02 30 09 47 98 C7 05 45 EF 30 9F C5 B2 40 +41 01 82 80 B7 07 02 00 85 07 49 B7 82 80 37 35 +02 50 13 05 85 63 EF 30 DF C5 D9 BF 41 11 06 C6 +37 23 02 30 83 28 C3 00 93 F8 18 00 E3 9C 08 FE +23 2A A3 00 23 2C B3 00 23 22 E3 02 23 24 F3 02 +2D CE B7 07 12 00 85 07 37 26 02 30 1C C6 5C 42 +09 83 15 C3 0A 07 05 66 B3 85 E6 00 7D 16 37 27 +02 30 5C 47 91 83 F1 8F ED DF 1C 5B 91 06 23 AE +F6 FE E3 98 B6 FE B7 27 02 30 DC 47 05 47 93 F6 +37 00 63 9A E6 00 37 26 02 30 85 46 5C 46 13 F7 +37 00 E3 0D D7 FE 89 8B 8D C7 63 06 08 04 B7 07 +02 50 03 A7 47 5A 89 47 63 E4 E7 04 B7 27 02 30 +09 47 98 C7 B2 40 41 01 82 80 B7 07 02 00 85 07 +61 B7 E3 09 08 FE 37 35 02 50 13 05 85 6A EF 30 +5F BA B7 27 02 30 09 47 98 C7 05 45 EF 30 7F B7 +B2 40 41 01 82 80 37 35 02 50 13 05 85 66 C5 B7 +37 35 02 50 13 05 85 66 EF 30 BF B7 45 BF 37 28 +02 30 83 26 C8 00 85 8A ED FE 23 2A A8 00 23 2C +B8 00 23 22 E8 02 23 24 F8 02 01 CA B7 07 12 00 +85 07 37 27 02 30 1C C7 82 80 B7 07 02 00 85 07 +37 27 02 30 1C C7 82 80 B7 27 02 30 DC 43 93 D7 +25 00 95 C3 8A 07 85 66 33 06 F5 00 37 27 02 30 +FD 16 5C 47 91 83 F5 8F ED DF 1C 5B 11 05 23 2E +F5 FE E3 18 C5 FE 82 80 B7 08 02 30 83 A8 08 00 +41 11 06 C6 93 F8 18 00 63 8B 08 00 B7 07 02 50 +83 A7 47 5A A1 E3 B2 40 05 45 41 01 82 80 91 C9 +B7 07 02 50 83 A7 47 5A D1 EF 05 45 EF 30 7F AB +01 A0 B7 05 04 00 E3 75 B5 FE B3 88 A7 00 63 F2 +F8 02 37 07 02 50 03 27 47 5A 41 EB 05 45 EF 30 +5F A9 01 A0 37 35 02 50 13 05 05 6F EF 30 7F AA +5D BF E3 F0 B8 FE B7 25 02 30 83 A8 C5 00 93 F8 +18 00 E3 9C 08 FE C8 C9 23 AC 05 00 D0 CD 94 D1 +DC D1 23 A4 05 03 31 C7 B7 07 00 11 85 07 37 27 +02 30 1C C7 5C 47 05 47 93 F6 37 00 63 9A E6 00 +37 26 02 30 85 46 5C 46 13 F7 37 00 E3 0D D7 FE +89 8B 85 EF B2 40 B7 07 02 30 05 47 98 D3 01 45 +41 01 82 80 AA 85 41 65 13 05 05 6E EF 30 7F A5 +A9 BF B7 07 00 01 85 07 5D BF 2A 86 41 65 BE 85 +13 05 05 71 EF 30 FF A3 95 B7 37 35 02 50 13 05 +C5 70 EF 30 1F A1 B7 27 02 30 09 47 98 C7 05 45 +EF 30 3F 9E 45 BF B7 08 02 30 83 A8 08 00 41 11 +06 C6 93 F8 18 00 63 8B 08 00 B7 07 02 50 83 A7 +47 5A A1 E3 B2 40 05 45 41 01 82 80 91 CA B7 07 +02 50 83 A7 47 5A A5 EF 05 45 EF 30 9F 9A 01 A0 +B7 06 04 00 E3 75 D6 FE B3 88 C7 00 63 F2 F8 02 +37 07 02 50 03 27 47 5A 2D E7 05 45 EF 30 7F 98 +01 A0 37 35 02 50 13 05 05 6F EF 30 9F 99 5D BF +E3 F0 D8 FE B7 28 02 30 83 A6 C8 00 85 8A ED FE +23 AA A8 00 23 AC B8 00 23 AE C8 00 23 A0 08 02 +23 A2 F8 02 23 A4 08 03 15 C3 B7 07 11 00 85 07 +B2 40 37 27 02 30 1C C7 01 45 41 01 82 80 41 65 +B2 85 13 05 C5 75 EF 30 DF 96 BD BF C1 67 85 07 +C5 B7 41 65 BE 85 13 05 C5 78 EF 30 9F 95 71 B7 +41 11 06 C6 0D 3F B7 27 02 30 DC 47 05 47 93 F6 +37 00 63 9A E6 00 37 26 02 30 85 46 5C 46 13 F7 +37 00 E3 0D D7 FE 89 8B 99 CF B7 07 02 50 03 A7 +47 5A 89 47 63 E0 E7 02 B7 27 02 30 09 47 98 C7 +05 45 EF 30 1F 8D B2 40 B7 07 02 30 05 47 98 D3 +41 01 82 80 37 35 02 50 13 05 85 63 EF 30 7F 8D +E1 BF 01 11 4E C6 B7 09 02 50 03 A7 49 5A 22 CC +26 CA 4A C8 06 CE 89 47 2A 89 AE 84 32 84 63 E0 +E7 0A B7 36 02 30 83 A7 86 80 37 27 02 30 F9 9B +23 A4 F6 80 5C 47 85 8B F5 FF 23 2E 27 01 04 D3 +B7 07 00 04 40 D3 85 07 1C C7 5C 47 05 47 93 F6 +37 00 63 9A E6 00 37 26 02 30 85 46 5C 46 13 F7 +37 00 E3 0D D7 FE 89 8B A9 C3 03 A7 49 5A 89 47 +63 E6 E7 02 B7 27 02 30 09 47 98 C7 37 37 02 30 +83 27 87 80 F2 40 62 44 93 E7 17 00 23 24 F7 80 +D2 44 42 49 B2 49 01 45 05 61 82 80 37 35 02 50 +13 05 85 76 EF 30 FF 82 F1 B7 37 35 02 50 13 05 +C5 79 EF 30 1F 82 05 45 EF 30 AF FF 01 A0 37 35 +02 50 13 05 85 74 EF 30 DF 80 A1 BF 01 11 4E C6 +B7 09 02 50 03 A7 49 5A 22 CC 26 CA 4A C8 06 CE +89 47 2A 89 AE 84 32 84 63 E2 E7 06 37 27 02 30 +5C 47 85 8B F5 FF 23 2E 27 01 04 D3 B7 07 00 04 +40 D3 85 07 1C C7 5C 47 05 47 93 F6 37 00 63 9A +E6 00 37 26 02 30 85 46 5C 46 13 F7 37 00 E3 0D +D7 FE 89 8B 89 CF 03 A7 49 5A 89 47 63 E7 E7 02 +B7 27 02 30 09 47 98 C7 05 45 EF 30 8F F7 F2 40 +62 44 D2 44 42 49 B2 49 05 61 82 80 37 35 02 50 +13 05 C5 7D EF 30 EF F7 51 BF 37 35 02 50 13 05 +85 63 EF 30 0F F7 E9 B7 37 27 02 30 5C 47 85 8B +F5 FF 48 CF 0C D3 B7 07 00 04 50 D3 85 07 1C C7 +82 80 41 11 83 4E 01 01 06 C6 37 2E 02 30 03 23 +CE 00 13 73 13 00 E3 1C 03 FE 23 2A AE 00 23 2C +BE 00 23 2E DE 00 23 20 EE 02 23 22 0E 03 23 24 +1E 03 B7 06 03 03 63 83 0E 06 95 06 03 47 41 01 +B3 37 F0 00 F2 07 33 37 E0 00 0E 07 33 36 C0 00 +D9 8F 52 06 D1 8F 37 27 02 30 D5 8F 1C C7 5C 47 +05 47 93 F6 37 00 63 9A E6 00 37 26 02 30 85 46 +5C 46 13 F7 37 00 E3 0D D7 FE 89 8B A1 C3 B7 07 +02 50 03 A7 47 5A 89 47 63 EC E7 00 B2 40 B7 27 +02 30 09 47 98 C7 01 45 41 01 82 80 85 06 79 BF +37 35 02 50 13 05 85 76 EF 30 AF EA B2 40 B7 27 +02 30 09 47 98 C7 01 45 41 01 82 80 37 35 02 50 +13 05 C5 79 EF 30 EF E8 05 45 EF 30 8F E6 01 A0 +41 11 83 4E 01 01 06 C6 37 2E 02 30 03 23 CE 00 +13 73 13 00 E3 1C 03 FE 23 2A AE 00 23 2C BE 00 +23 2E DE 00 23 20 EE 02 23 22 0E 03 23 24 1E 03 +B7 06 03 03 63 85 0E 06 95 06 03 47 41 01 B3 37 +F0 00 F2 07 33 37 E0 00 0E 07 33 36 C0 00 D9 8F +52 06 D1 8F 37 27 02 30 D5 8F 1C C7 5C 47 05 47 +93 F6 37 00 63 9A E6 00 37 26 02 30 85 46 5C 46 +13 F7 37 00 E3 0D D7 FE 89 8B 99 CF B7 07 02 50 +03 A7 47 5A 89 47 63 EE E7 00 B7 27 02 30 09 47 +98 C7 05 45 EF 30 EF DC B2 40 41 01 82 80 85 06 +69 BF 37 35 02 50 13 05 85 63 EF 30 8F DD F1 BF +41 11 03 4F 01 01 83 4E 81 01 06 C6 37 2E 02 30 +03 23 CE 00 13 73 13 00 E3 1C 03 FE 23 2A AE 00 +23 2C BE 00 23 2E DE 00 23 20 EE 02 23 22 0E 03 +23 24 1E 03 B7 06 03 03 63 04 0F 06 95 06 03 47 +41 01 B3 37 F0 00 F2 07 33 37 E0 00 0E 07 33 36 +C0 00 D9 8F 52 06 D1 8F 37 27 02 30 D5 8F 1C C7 +5C 47 05 47 93 F6 37 00 63 9A E6 00 37 26 02 30 +85 46 5C 46 13 F7 37 00 E3 0D D7 FE 89 8B 9D C3 +63 84 0E 04 B7 07 02 50 03 A7 47 5A 89 47 63 E2 +E7 04 B7 27 02 30 09 47 98 C7 B2 40 41 01 82 80 +85 06 71 BF E3 8B 0E FE 37 35 02 50 13 05 85 6A +EF 30 2F D2 B7 27 02 30 09 47 98 C7 05 45 EF 30 +4F CF B2 40 41 01 82 80 37 35 02 50 13 05 85 66 +C5 B7 37 35 02 50 13 05 85 66 EF 30 8F CF 55 BF +83 4E 01 00 37 2E 02 30 03 23 CE 00 13 73 13 00 +E3 1C 03 FE 23 2A AE 00 23 2C BE 00 23 2E DE 00 +23 20 EE 02 23 22 0E 03 23 24 1E 03 B7 06 03 03 +63 85 0E 02 95 06 03 47 41 00 B3 37 F0 00 33 36 +C0 00 52 06 F2 07 33 37 E0 00 D1 8F 0E 07 D9 8F +D5 8F 37 27 02 30 1C C7 82 80 85 06 E9 BF B7 27 +02 30 DC 47 41 11 22 C4 06 C6 05 47 93 F6 37 00 +2A 84 63 9A E6 00 37 26 02 30 85 46 5C 46 13 F7 +37 00 E3 0D D7 FE 89 8B 99 CF B7 07 02 50 03 A7 +47 5A 89 47 63 E2 E7 02 B7 27 02 30 09 47 98 C7 +05 45 EF 30 0F C3 09 C4 B7 07 02 30 05 47 98 D3 +B2 40 22 44 41 01 82 80 37 35 02 50 13 05 85 63 +EF 30 2F C3 B7 27 02 30 09 47 98 C7 05 45 EF 30 +4F C0 D1 BF B7 27 02 30 DC 47 41 11 22 C4 06 C6 +05 47 93 F6 37 00 2A 84 63 9A E6 00 37 26 02 30 +85 46 5C 46 13 F7 37 00 E3 0D D7 FE 89 8B A9 C3 +B7 07 02 50 03 A7 47 5A 89 47 63 EF E7 00 B7 27 +02 30 09 47 98 C7 09 C4 B7 07 02 30 05 47 98 D3 +B2 40 22 44 41 01 82 80 37 35 02 50 13 05 85 76 +EF 30 2F BC B7 27 02 30 09 47 98 C7 71 FC CD B7 +37 35 02 50 13 05 C5 79 EF 30 AF BA 05 45 EF 30 +4F B8 01 A0 1D 71 A6 CA 86 CE A2 CC CA C8 CE C6 +D2 C4 D6 C2 DA C0 5E DE 62 DC 66 DA 6A D8 6E D6 +95 47 AA 84 63 01 F5 22 C5 47 63 02 F5 12 99 47 +63 19 F5 2A 8D 47 B7 49 44 23 37 0B 03 03 37 0C +44 23 3E C6 3E CA 8D 09 05 49 A5 47 63 97 F4 42 +41 64 7D 14 37 0A 03 30 EF 00 50 5F 93 57 F5 41 +C1 83 33 07 F5 00 61 8F 1D 8F 83 27 8A 54 0D 07 +93 7D C7 FF E3 82 FD FE 02 C4 02 CE BD 47 CA 8C +4E 84 63 9E F4 22 CD 47 4D 4D 3E C8 02 CC 93 8B +24 FF 93 BB 1B 00 13 99 2B 00 B7 09 02 50 03 A6 +49 5A 11 4A 63 63 CA 0E B7 35 02 30 83 A7 85 80 +B7 26 02 30 F9 9B 23 A4 F5 80 DC 46 85 8B F5 FF +89 47 63 E3 C7 0A B7 27 02 30 23 AA 87 01 22 47 +85 46 94 CF C0 CF 23 A0 97 03 33 69 27 01 23 A2 +B7 03 33 67 69 01 23 A4 A7 03 13 67 17 00 98 C7 +DC 47 13 F7 37 00 63 19 D7 00 37 26 02 30 5C 46 +13 F7 37 00 E3 0D D7 FE 89 8B B5 C7 03 A7 49 5A +89 47 63 EF E7 18 B7 27 02 30 09 47 98 C7 37 37 +02 30 83 27 87 80 F6 40 66 44 93 E7 17 00 23 24 +F7 80 D6 44 46 49 B6 49 26 4A 96 4A 06 4B F2 5B +62 5C D2 5C 42 5D B2 5D 01 45 25 61 82 80 85 47 +41 6B 3E C6 02 CA 91 69 01 49 02 C4 37 0C 44 23 +02 CE 93 0D 00 04 19 BF 37 35 02 50 13 05 45 7F +EF 30 2F A3 89 BF 37 35 02 50 13 05 C5 79 EF 30 +4F A2 05 45 EF 30 EF 9F 01 A0 C1 6A 93 8A 0A 3C +A6 85 13 85 4A 41 EF 30 CF A2 03 A6 49 5A E3 75 +CA F0 62 86 85 45 13 85 CA 42 EF 30 8F A1 03 A6 +49 5A E3 7B CA EE 22 86 E6 85 13 85 CA 44 EF 30 +4F A0 03 A6 49 5A E3 71 CA EE B2 45 13 85 CA 46 +EF 30 2F 9F 03 A6 49 5A E3 78 CA EC D2 45 13 85 +4A 48 EF 30 0F 9E 03 A6 49 5A E3 7F CA EA F2 45 +13 85 CA 49 EF 30 EF 9C 03 A6 49 5A E3 76 CA EA +E2 45 13 85 4A 4B EF 30 CF 9B 03 A6 49 5A E3 7D +CA E8 DE 85 13 85 CA 4C EF 30 AF 9A 03 A6 49 5A +E3 74 CA E8 EE 85 13 85 4A 4E EF 30 8F 99 03 A6 +49 5A E3 7B CA E6 C2 45 13 85 CA 4F EF 30 6F 98 +03 A6 49 5A 95 B5 B7 07 03 30 03 A9 47 54 83 A9 +07 54 37 0C 44 23 8D 47 CA 8C 4E 84 0D 0C 37 0B +03 00 3E C6 89 47 63 F6 97 1E 13 87 D4 FF 85 47 +B3 97 E7 00 93 F7 17 4D 3E CA 63 9F 07 1C AD 47 +63 86 F4 22 91 47 63 8E F4 18 37 07 00 03 B9 47 +33 6B EB 00 63 99 F4 20 EF 00 50 3B B7 07 10 00 +3E C4 8D 47 3E CA 85 47 3E CE 93 0D 00 04 F9 B3 +37 35 02 50 13 05 85 76 EF 30 AF 8E A9 BD 02 CC +C1 47 63 8A F4 00 91 47 63 92 F4 18 11 49 01 4D +02 C8 85 4B D9 B3 91 47 11 49 11 4D 3E C8 85 4B +6D BB 9D 47 63 1A F5 04 B7 07 03 30 03 AA 47 54 +03 A4 07 54 EF 00 90 35 2A 89 EF 00 30 35 93 57 +F5 41 13 57 E5 01 8A 07 0A 09 D9 8F 0A 05 AA 89 +33 69 F9 00 63 14 A4 00 E3 0E 2A FD CA 8C 2A 84 +C5 47 63 EB 97 10 37 17 02 50 93 97 24 00 13 07 +87 AF BA 97 9C 43 82 87 B7 07 03 30 83 AC 47 54 +83 A9 07 54 AD 47 66 89 4E 84 63 12 F5 02 B7 07 +10 00 3E C4 89 47 3E CA 85 47 37 0B 00 02 37 0C +44 23 02 C6 3E CE 02 CC 93 0D 00 04 91 BF 09 47 +89 47 3A C6 3A CA 37 0B 02 02 E3 00 F5 DE 4D B7 +37 0C 44 23 01 4B 02 C6 F1 BD EF 00 30 2C 8D 47 +B3 67 F5 02 91 46 37 0C 44 23 37 07 00 04 36 CA +85 07 3E C6 13 9B 07 01 33 6B EB 00 93 87 44 FF +05 47 63 68 F7 06 B7 07 00 10 33 6B FB 00 85 47 +02 C4 01 4D 02 C8 3E CC 93 0D 00 04 02 CE C1 B1 +89 47 02 C4 37 0B 02 00 37 0C 44 23 3E C6 02 CA +02 CE 93 0D 00 04 59 B9 85 47 41 6B 37 0C 44 23 +3E C6 02 CA 99 B9 89 47 3E C6 85 47 37 0B 02 10 +02 C4 37 0C 44 23 02 CA 02 CE 3E CC 93 0D 00 04 +45 BD 91 47 37 0B 00 04 37 0C 44 23 3E CA 02 C6 +05 B9 A1 47 E3 93 F4 C2 02 C4 01 4D 02 C8 02 CC +93 0D 30 04 02 CE A1 B9 B5 47 37 0C 44 23 37 0B +03 00 63 EF 97 04 8D 47 3E C6 29 BD 01 4D 02 C8 +3D B9 85 47 63 89 F4 00 B7 07 00 04 33 6B FB 00 +91 47 3E CA A1 B7 EF 00 70 1E AD 47 B3 67 F5 02 +95 07 3E CA 13 97 87 01 05 BF 02 C4 02 CE A9 47 +E3 95 F4 E2 B7 07 03 30 03 A7 87 54 CA 8C 4E 84 +93 1D 07 01 93 DD 0D 01 01 4D 02 C8 02 CC C5 BE +8D 47 3E C6 DD B3 8D 47 3E CA 09 B7 B7 07 00 02 +33 6B FB 00 B7 07 10 00 3E C4 89 47 3E CA 85 47 +3E CE 75 BF B7 27 02 30 DC 47 41 11 22 C4 06 C6 +93 F6 37 00 05 47 2A 84 63 9A E6 00 37 26 02 30 +85 46 5C 46 13 F7 37 00 E3 0D D7 FE 89 8B 95 C7 +A1 C5 B7 07 02 50 03 A7 47 5A 89 47 63 E3 E7 04 +B7 27 02 30 09 47 98 C7 09 C4 B7 07 02 30 05 47 +98 D3 B2 40 22 44 41 01 82 80 FD D5 37 35 02 50 +13 05 85 6A EF 20 FF E7 B7 27 02 30 09 47 98 C7 +05 45 EF 20 1F E5 C9 BF 37 35 02 50 13 05 85 66 +D5 B7 37 35 02 50 13 05 85 66 EF 20 9F E5 4D BF +53 4F 43 5F 49 46 43 3A 20 43 6C 65 61 72 20 65 +78 65 63 75 74 65 20 72 65 67 00 00 53 4F 43 5F +49 46 43 3A 20 43 68 65 63 6B 20 6D 62 6F 78 5F +73 74 61 74 75 73 2E 6D 62 6F 78 5F 66 73 6D 5F +70 73 20 66 6F 75 6E 64 20 75 6E 65 78 70 65 63 +74 65 64 20 73 74 61 74 65 20 30 78 25 78 0A 00 +53 4F 43 5F 49 46 43 3A 20 53 65 74 20 6D 62 6F +78 5F 73 74 61 74 75 73 20 66 69 65 6C 64 3A 20 +30 78 25 78 0A 00 00 00 53 4F 43 5F 49 46 43 3A +20 53 65 74 20 66 6C 6F 77 5F 73 74 61 74 75 73 +20 66 69 65 6C 64 3A 20 30 78 25 78 0A 00 00 00 +53 4F 43 5F 49 46 43 3A 20 43 6C 65 61 72 20 53 +48 41 20 61 63 63 65 6C 65 72 61 74 6F 72 20 6C +6F 63 6B 20 62 79 20 77 72 69 74 69 6E 67 20 27 +31 3A 20 30 78 25 78 0A 00 00 00 00 53 4F 43 5F +49 46 43 3A 20 42 61 64 20 66 69 65 6C 64 20 76 +61 6C 75 65 00 00 00 00 53 4F 43 5F 49 46 43 3A +20 42 61 64 20 66 69 65 6C 64 20 76 61 6C 75 65 +00 00 00 00 53 4F 43 5F 49 46 43 3A 20 43 6C 65 +61 72 20 66 6C 6F 77 5F 73 74 61 74 75 73 20 66 +69 65 6C 64 3A 20 30 78 25 78 0A 00 53 4F 43 5F +49 46 43 3A 20 43 4D 44 20 66 72 6F 6D 20 6D 61 +69 6C 62 6F 78 3A 20 30 78 25 78 0A 00 00 00 00 +53 4F 43 5F 49 46 43 3A 20 44 4C 45 4E 20 66 72 +6F 6D 20 6D 61 69 6C 62 6F 78 3A 20 30 78 25 78 +0A 00 00 00 46 41 54 41 4C 3A 20 49 6E 76 61 6C +69 64 20 64 6C 65 6E 20 70 61 73 73 65 64 20 74 +6F 20 6D 62 6F 78 20 66 77 20 66 6C 6F 77 3A 20 +30 78 25 78 0A 00 00 00 46 41 54 41 4C 3A 20 49 +6E 76 61 6C 69 64 20 63 6D 64 20 70 61 73 73 65 +64 20 74 6F 20 6D 62 6F 78 20 66 77 20 66 6C 6F +77 3A 20 30 78 25 78 0A 00 00 00 00 46 6F 75 6E +64 20 69 6E 76 61 6C 69 64 20 69 63 63 6D 20 73 +69 7A 65 20 69 6E 20 66 69 72 6D 77 61 72 65 20 +69 6D 61 67 65 20 72 65 63 65 69 76 65 64 20 66 +72 6F 6D 20 53 4F 43 21 20 4D 61 78 20 65 78 70 +65 63 74 65 64 20 30 78 25 78 2C 20 67 6F 74 20 +30 78 25 78 0A 00 00 00 46 6F 75 6E 64 20 69 6E +76 61 6C 69 64 20 64 63 63 6D 20 73 69 7A 65 20 +69 6E 20 66 69 72 6D 77 61 72 65 20 69 6D 61 67 +65 20 72 65 63 65 69 76 65 64 20 66 72 6F 6D 20 +53 4F 43 21 20 4D 61 78 20 65 78 70 65 63 74 65 +64 20 30 78 25 78 2C 20 67 6F 74 20 30 78 25 78 +0A 00 00 00 61 74 20 25 78 3A 20 25 78 0A 00 00 +53 4F 43 5F 49 46 43 3A 20 49 6C 6C 65 67 61 6C +20 62 79 74 65 5F 63 6F 75 6E 74 20 30 78 25 78 +0A 00 00 00 53 4F 43 5F 49 46 43 3A 20 53 65 74 +20 66 77 20 75 70 64 61 74 65 20 72 65 73 65 74 +20 77 69 74 68 20 77 61 69 74 5F 63 79 63 6C 65 +73 20 5B 25 64 5D 20 28 25 73 29 0A 00 00 00 00 +73 72 63 5F 61 64 64 72 20 30 78 25 78 20 69 73 +20 6F 75 74 20 6F 66 20 62 6F 75 6E 64 73 20 66 +6F 72 20 6D 62 6F 78 20 73 70 61 6E 21 0A 00 00 +72 65 61 64 69 6E 67 20 30 78 25 78 20 62 79 74 +65 73 20 66 72 6F 6D 20 73 72 63 5F 61 64 64 72 +20 30 78 25 78 20 67 6F 65 73 20 6F 75 74 20 6F +66 20 62 6F 75 6E 64 73 20 66 6F 72 20 6D 62 6F +78 20 73 70 61 6E 21 0A 00 00 00 00 64 73 74 5F +61 64 64 72 20 30 78 25 78 20 69 73 20 6F 75 74 +20 6F 66 20 62 6F 75 6E 64 73 20 66 6F 72 20 6D +62 6F 78 20 73 70 61 6E 21 0A 00 00 77 72 69 74 +69 6E 67 20 30 78 25 78 20 62 79 74 65 73 20 74 +6F 20 64 73 74 5F 61 64 64 72 20 30 78 25 78 20 +67 6F 65 73 20 6F 75 74 20 6F 66 20 62 6F 75 6E +64 73 20 66 6F 72 20 6D 62 6F 78 20 73 70 61 6E +21 0A 00 00 70 61 72 61 6D 3A 20 65 72 72 5F 74 +79 70 65 20 20 20 30 78 25 78 0A 00 70 61 72 61 +6D 3A 20 73 72 63 5F 61 64 64 72 20 20 20 30 78 +25 78 20 30 78 25 78 0A 00 00 00 00 70 61 72 61 +6D 3A 20 64 73 74 5F 61 64 64 72 20 20 20 30 78 +25 78 20 30 78 25 78 0A 00 00 00 00 70 61 72 61 +6D 3A 20 72 64 5F 72 6F 75 74 65 20 20 20 30 78 +25 78 0A 00 70 61 72 61 6D 3A 20 77 72 5F 72 6F +75 74 65 20 20 20 30 78 25 78 0A 00 70 61 72 61 +6D 3A 20 72 64 5F 66 69 78 65 64 20 20 20 30 78 +25 78 0A 00 70 61 72 61 6D 3A 20 77 72 5F 66 69 +78 65 64 20 20 20 30 78 25 78 0A 00 70 61 72 61 +6D 3A 20 61 65 73 5F 6D 6F 64 65 20 20 20 30 78 +25 78 0A 00 70 61 72 61 6D 3A 20 62 79 74 65 5F +63 6F 75 6E 74 20 30 78 25 78 0A 00 70 61 72 61 +6D 3A 20 62 6C 6F 63 6B 5F 73 69 7A 65 20 30 78 +25 78 0A 00 B7 16 02 50 83 A7 06 B4 13 97 D7 00 +3D 8F 93 57 17 01 B9 8F 13 95 57 00 3D 8D 23 A0 +A6 B4 82 80 B7 07 02 50 03 A7 47 5A 41 11 22 C4 +26 C2 06 C6 89 47 AA 84 2E 84 63 E3 E7 02 73 50 +20 7D 73 90 34 7D 73 D0 41 7D 73 10 44 30 73 50 +04 30 73 D0 61 7C B2 40 22 44 92 44 41 01 82 80 +37 45 02 50 13 05 85 80 EF 20 BF 8D C9 BF 73 50 +20 7D 73 10 35 7D 73 D0 41 7D 73 90 45 30 73 50 +04 30 82 80 73 D0 61 7C 82 80 B7 07 03 30 23 A6 +A7 0E 23 A8 B7 0E 82 80 B7 07 03 30 23 AE A7 0E +23 A0 B7 10 82 80 B7 07 03 30 7D 57 23 A6 E7 0E +23 A8 E7 0E 82 80 B7 07 03 30 7D 57 23 AE E7 0E +23 A0 E7 10 82 80 37 17 03 30 83 27 47 81 93 F7 +07 04 E5 DF 93 07 00 04 23 2A F7 80 82 80 37 17 +03 30 83 27 47 81 93 F7 07 08 E5 DF 93 07 00 08 +23 2A F7 80 82 80 B7 07 03 30 23 A6 A7 0E 23 A8 +B7 0E 23 AE C7 0E 23 A0 D7 10 05 47 23 A2 E7 0E +23 A4 E7 0E 82 80 01 11 06 CE 0D E1 B7 07 02 50 +03 A7 47 5A 89 47 63 E2 E7 08 B7 07 03 30 23 A2 +07 0E 23 AA 07 0E F2 40 05 61 82 80 85 47 63 01 +F5 04 89 47 E3 19 F5 FE B7 07 02 50 83 A7 47 5A +63 6F F5 06 B7 07 03 30 23 A6 B7 0E 23 A8 C7 0E +23 AE D7 0E 23 A0 E7 10 05 47 23 A2 E7 0E 23 AA +E7 0E F2 40 23 A4 E7 0E 23 AC E7 0E 05 61 82 80 +B7 07 02 50 03 A6 47 5A 89 47 63 E7 C7 02 B7 07 +03 30 23 AE D7 0E 23 A0 E7 10 F2 40 05 47 23 AA +E7 0E 23 AC E7 0E 05 61 82 80 37 45 02 50 13 05 +05 82 EF 20 0F F9 95 BF 37 45 02 50 13 05 C5 84 +3A C2 36 C0 EF 20 EF F7 12 47 82 46 C9 B7 37 45 +02 50 13 05 85 87 3A C6 36 C4 32 C2 2E C0 EF 20 +4F F6 32 47 A2 46 12 46 82 45 AD B7 B3 47 B5 00 +8D 8B B3 08 C5 00 B1 E7 8D 47 63 F4 C7 04 93 77 +35 00 2A 87 B9 EB 13 F6 C8 FF B3 06 E6 40 93 07 +00 02 63 C8 D7 06 AE 86 BA 87 63 71 C7 02 03 A8 +06 00 91 07 91 06 23 AE 07 FF E3 EA C7 FE 93 07 +F6 FF 99 8F F1 9B 91 07 3E 97 BE 95 63 66 17 01 +82 80 2A 87 63 7E 15 03 83 C7 05 00 05 07 85 05 +A3 0F F7 FE E3 9A E8 FE 82 80 83 C6 05 00 05 07 +93 77 37 00 A3 0F D7 FE 85 05 D1 DF 83 C6 05 00 +05 07 93 77 37 00 A3 0F D7 FE 85 05 F9 FF 61 B7 +82 80 41 11 22 C6 13 04 00 02 83 A3 05 00 83 A2 +45 00 83 AF 85 00 03 AF C5 00 83 AE 05 01 03 AE +45 01 03 A3 85 01 03 A8 C5 01 94 51 13 07 47 02 +B3 07 E6 40 23 2E 77 FC 23 20 57 FE 23 22 F7 FF +23 24 E7 FF 23 26 D7 FF 23 28 C7 FF 23 2A 67 FE +23 2C 07 FF 23 2E D7 FE 93 85 45 02 E3 47 F4 FA +AE 86 BA 87 63 71 C7 02 03 A8 06 00 91 07 91 06 +23 AE 07 FF E3 EA C7 FE 93 07 F6 FF 99 8F F1 9B +91 07 3E 97 BE 95 63 65 17 01 32 44 41 01 82 80 +83 C7 05 00 05 07 85 05 A3 0F F7 FE E3 87 E8 FE +83 C7 05 00 05 07 85 05 A3 0F F7 FE E3 92 E8 FE +E9 BF 3D 43 2A 87 63 73 C3 02 93 77 F7 00 BD EF +AD E5 93 76 06 FF 3D 8A BA 96 0C C3 4C C3 0C C7 +4C C7 41 07 E3 6B D7 FE 11 E2 82 80 B3 06 C3 40 +8A 06 97 02 00 00 96 96 67 80 A6 00 23 07 B7 00 +A3 06 B7 00 23 06 B7 00 A3 05 B7 00 23 05 B7 00 +A3 04 B7 00 23 04 B7 00 A3 03 B7 00 23 03 B7 00 +A3 02 B7 00 23 02 B7 00 A3 01 B7 00 23 01 B7 00 +A3 00 B7 00 23 00 B7 00 82 80 93 F5 F5 0F 93 96 +85 00 D5 8D 93 96 05 01 D5 8D 61 B7 93 96 27 00 +97 02 00 00 96 96 86 82 E7 80 86 FA 96 80 C1 17 +1D 8F 3E 96 E3 74 C3 F8 A5 B7 B7 47 02 50 83 A7 +87 8A 23 A4 A7 0A 23 A6 07 0A 82 80 B7 47 02 50 +03 A8 87 8A B7 85 95 4C 93 85 D5 F2 83 26 88 0A +03 27 C8 0A B3 87 B6 02 13 86 17 00 B3 37 F6 00 +23 24 C8 0A 37 F6 51 58 13 06 D6 42 33 86 C6 02 +33 07 B7 02 B3 B6 B6 02 32 97 36 97 BA 97 13 95 +17 00 23 26 F8 0A 05 81 82 80 93 77 35 00 2A 87 +9D EF B7 86 7F 7F 93 86 F6 F7 FD 55 10 43 11 07 +B3 77 D6 00 B6 97 D1 8F D5 8F E3 89 B7 FE 83 46 +C7 FF B3 07 A7 40 8D CA 83 46 D7 FF 9D C2 03 45 +E7 FF 33 35 A0 00 3E 95 79 15 82 80 F9 D2 83 47 +07 00 05 07 93 76 37 00 F5 FB 09 8F 13 05 F7 FF +82 80 13 85 D7 FF 82 80 13 85 C7 FF 82 80 13 01 +01 BC 23 2A 91 42 23 28 21 43 23 20 61 43 23 2C +81 41 23 2E 11 42 23 2C 81 42 23 26 31 43 23 24 +41 43 23 22 51 43 23 2E 71 41 23 2A 91 41 23 28 +A1 41 23 26 B1 41 85 47 36 8B 2A 89 2E 8C B2 84 +63 F1 D7 2E 01 46 85 4C 85 46 FD 5B 09 A8 B3 8C +77 41 3E 86 85 46 B3 07 D6 00 63 F7 67 03 33 87 +74 01 36 97 B3 85 F4 00 83 C5 05 00 03 47 07 00 +E3 EF E5 FC 63 86 E5 14 B2 8B 85 46 05 06 B3 07 +D6 00 85 4C E3 ED 67 FD 81 45 05 48 05 46 7D 55 +05 47 09 A8 33 08 A7 40 BA 85 05 46 33 87 C5 00 +63 77 67 03 B3 87 C4 00 B3 86 E4 00 AA 97 83 C6 +06 00 83 C7 07 00 E3 EF D7 FC 63 87 D7 10 2E 85 +05 46 85 05 33 87 C5 00 05 48 E3 6D 67 FD 05 05 +85 0B 63 64 75 01 C2 8C AA 8B 8A 87 13 07 01 40 +23 A0 67 01 91 07 E3 9D E7 FE 63 05 0B 02 13 06 +FB FF B3 05 9B 00 26 87 26 96 83 47 07 00 B3 06 +E6 40 05 07 8A 07 93 87 07 40 8A 97 23 A0 D7 C0 +E3 95 E5 FE 5E 86 B3 85 94 01 26 85 C9 26 63 1F +05 10 85 69 93 89 09 80 05 4A 81 4D 01 44 B3 06 +6C 41 B3 69 3B 01 13 0D FB FF 33 0A 7A 41 B3 0A +9B 41 63 E8 86 02 33 06 89 00 B3 07 A6 01 83 C7 +07 00 8A 07 93 87 07 40 8A 97 83 A7 07 C0 AD CB +63 85 0D 00 63 F3 97 01 D6 87 3E 94 81 4D E3 FC +86 FC 33 05 89 01 CE 85 6D 21 2A 9C B3 06 6C 41 +E3 F3 86 FC 01 45 83 20 C1 43 03 24 81 43 83 24 +41 43 03 29 01 43 83 29 C1 42 03 2A 81 42 83 2A +41 42 03 2B 01 42 83 2B C1 41 03 2C 81 41 83 2C +41 41 03 2D 01 41 83 2D C1 40 13 01 01 44 82 80 +63 8A 96 15 85 06 41 BD 63 03 C8 14 05 06 F9 B5 +6E 87 63 F3 7D 01 5E 87 63 70 A7 03 B3 07 E4 00 +33 88 E4 00 CA 97 03 45 08 00 83 C7 07 00 63 11 +F5 04 05 07 E3 64 A7 FF 13 87 FB FF 63 E6 7D 01 +39 AA 63 81 ED 02 2A 87 B3 07 E4 00 B3 85 E4 00 +CA 97 83 C5 05 00 83 C7 07 00 13 05 F7 FF E3 82 +F5 FE 05 07 85 0D 63 6A B7 0F 66 94 D6 8D 11 BF +E3 74 A7 FD 52 94 3A 94 81 4D 21 B7 33 0A 7B 41 +63 65 7A 0D 05 64 13 04 04 80 85 49 05 0A 81 4A +B3 06 6C 41 33 64 8B 00 93 0C FB FF B3 89 79 41 +7D 5D 63 E2 56 03 33 05 59 01 B3 07 95 01 83 C7 +07 00 8A 07 93 87 07 40 8A 97 83 A7 07 C0 95 CB +BE 9A E3 F2 56 FF 33 05 89 01 A2 85 59 2E 2A 9C +B3 06 6C 41 E3 E8 56 EF 33 05 59 01 B3 07 95 01 +83 C7 07 00 8A 07 93 87 07 40 8A 97 83 A7 07 C0 +E1 FB 5E 87 63 E6 9B 01 25 A0 05 07 63 72 97 03 +B3 07 57 01 B3 85 E4 00 CA 97 03 C6 05 00 83 C7 +07 00 E3 04 F6 FE 63 75 97 01 CE 9A BA 9A 51 B7 +93 87 FB FF 63 95 A7 01 79 BD E3 8E A7 E9 33 87 +FA 00 33 86 F4 00 4A 97 03 46 06 00 03 47 07 00 +FD 17 E3 04 E6 FE D2 9A A9 BF 5E 8A 25 BF C2 95 +05 46 69 B3 36 96 85 46 3D BB 32 85 AD B5 5E 87 +11 B7 85 4C 81 4B 55 BB 1D 71 A2 CC A6 CA 86 CE +CA C8 CE C6 D2 C4 AE 84 83 C5 05 00 2A 84 E1 C1 +03 C6 14 00 63 0E 06 12 03 C7 24 00 71 C3 03 C5 +34 00 63 02 05 14 83 C7 44 00 E1 CF 26 85 EF F0 +DF C3 2A 89 93 65 05 20 22 85 65 2C 63 6A 25 0F +93 07 E0 0F 63 E8 27 15 B3 09 25 41 13 06 00 04 +93 05 19 00 0A 85 A2 99 EF F0 BF B0 63 06 09 02 +13 76 F9 0F 26 87 B3 05 99 00 26 96 83 47 07 00 +B3 06 E6 40 05 07 93 F7 F7 03 93 87 07 04 8A 97 +23 80 D7 FC E3 94 E5 FE 7D 14 B3 07 24 01 83 C7 +07 00 93 F7 F7 03 93 87 07 04 8A 97 83 C7 07 FC +3E 94 63 F6 89 00 79 A0 52 94 63 E5 89 08 B3 07 +24 01 83 C7 07 00 22 85 4A 86 93 F7 F7 03 93 87 +07 04 8A 97 A6 85 03 CA 07 FC D5 20 71 FD F6 40 +22 85 66 44 D6 44 46 49 B6 49 26 4A 25 61 82 80 +03 47 05 00 C2 05 D1 8D 81 47 39 C3 C2 07 A2 86 +D9 8F 05 04 03 47 04 00 E3 99 F5 FE 13 84 F6 FF +F9 B7 93 97 85 01 42 06 83 46 04 00 D1 8F C9 8F +22 07 D9 8F 91 CE 01 47 19 A0 63 83 E7 04 22 86 +22 07 05 04 55 8F 83 46 04 00 E5 FA 63 8A E7 02 +01 44 71 BF 33 85 29 01 83 47 05 00 F5 DB 85 65 +93 85 05 80 7D 22 AA 99 E3 F0 89 F4 01 44 41 B7 +66 44 F6 40 D6 44 46 49 B6 49 26 4A 25 61 4D A0 +13 04 D6 FF AD B7 83 46 04 00 93 97 85 01 42 06 +D1 8F 22 07 D9 8F CD DE 01 47 11 A0 D5 DA 55 8F +22 86 22 07 05 04 83 46 04 00 E3 19 F7 FE 13 04 +E6 FF 35 BF AA 85 22 85 66 44 F6 40 B6 49 26 4A +CA 86 26 86 46 49 D6 44 25 61 6F F0 5F B2 8D 47 +63 F3 C7 02 B3 67 B5 00 8D 8B 8D 46 89 CB 93 06 +F6 FF 29 A8 71 16 11 05 91 05 63 F6 C6 00 18 41 +9C 41 E3 09 F7 FE 93 06 F6 FF 0D C2 85 06 AE 96 +19 A0 63 8D D5 00 83 47 05 00 03 C7 05 00 05 05 +85 05 E3 88 E7 FE 33 85 E7 40 82 80 01 45 82 80 +93 F6 F5 0F 93 77 35 00 C1 CE 91 CB 83 47 05 00 +D1 C7 63 86 D7 08 05 05 93 77 35 00 E5 FB 93 F5 +F5 0F 93 97 85 00 AE 97 18 41 13 93 07 01 33 63 +F3 00 37 08 FF FE 33 46 E3 00 13 08 F8 EF B3 07 +07 01 B3 05 06 01 13 47 F7 FF 13 46 F6 FF F9 8F +B7 88 80 80 33 F7 C5 00 D9 8F 93 88 08 08 B3 F7 +17 01 85 E7 58 41 11 05 33 46 67 00 B3 07 07 01 +B3 05 06 01 13 47 F7 FF 13 46 F6 FF F9 8F 33 F7 +C5 00 D9 8F B3 F7 17 01 F1 DF 83 47 05 00 99 C7 +63 80 F6 06 83 47 15 00 05 05 FD FB 01 45 82 80 +81 CB 83 47 05 00 E5 DF 05 05 93 77 35 00 F5 FB +18 41 37 06 FF FE 13 06 F6 EF 93 47 F7 FF B7 86 +80 80 32 97 F9 8F 93 86 06 08 F5 8F 91 EB 58 41 +11 05 B3 07 C7 00 13 47 F7 FF F9 8F F5 8F E5 DB +83 47 05 00 CD DF 83 47 15 00 05 05 ED FF 82 80 +82 80 B3 06 B5 00 AA 87 89 E5 29 A8 85 07 63 88 +F6 00 03 C7 07 00 7D FB 33 85 A7 40 82 80 33 85 +A6 40 82 80 01 45 82 80 +@000113E0 +78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 +78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 +78 78 78 78 78 78 78 78 0A 20 20 20 54 52 41 50 +20 56 45 43 54 4F 52 20 45 58 45 43 55 54 49 4E +47 21 20 4B 49 4C 4C 20 53 49 4D 21 21 21 20 20 +20 0A 78 78 78 78 78 78 78 78 78 78 78 78 78 78 +78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 +78 78 78 78 78 78 78 78 78 78 0A 00 00 00 00 00 +00 00 00 00 00 00 00 00 6B 4E 03 42 36 67 DB B7 +3B 6E 15 45 4F 0E B1 AB D4 59 7F 9A 1B 07 8E 3F +5B 5A 6B C7 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 07 00 00 00 01 00 00 00 +40 10 02 50 04 00 00 00 3A 42 B6 8A B0 79 F2 8C +4C A3 C7 52 29 6F 27 90 06 C4 FE 78 B1 EB 79 D9 +89 77 7F 05 1E 40 46 AE 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 08 00 00 00 02 00 00 00 +70 0F 02 50 11 00 00 00 DB A6 F9 29 FE 55 F9 D6 +6C 5F 67 C0 AF 3B 82 F1 7B CF 58 B3 67 52 F3 16 +5C 16 08 3F EA 8F D4 78 EE 69 03 F2 7F 82 0A D2 +DD 99 50 AF B4 8C 67 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 0C 00 00 00 03 00 00 00 +0C 05 02 50 91 00 00 00 E5 82 5F F1 A3 C0 70 D5 +A5 2F BB E7 11 85 4A 44 05 54 29 5F FB 7A 79 69 +A1 79 08 D1 01 63 BF BE 8F 1D 52 A6 76 E8 A0 13 +7B 56 A1 1C DF 0F FB B4 56 BC 89 9F C7 27 D1 4B +D8 88 22 32 54 9D 91 4E 10 00 00 00 00 00 00 00 +34 10 02 50 09 00 00 00 22 65 5A 23 AC 35 D7 3B +47 22 83 77 19 29 B1 C6 F0 EF 80 FB 5A 8A 30 B8 +1F DB 25 CB F2 4C CE C5 FC 30 97 34 4C 02 DF CE +EC EF 0E FF 35 FE 85 69 36 A7 46 3C 4B 04 84 00 +20 99 9F 6D 55 B0 0A 7C CE D3 D1 19 49 39 35 B4 +CD FB 8F FE C6 2E 7F 5A 5F 79 CF C3 7B 0D 6D A5 +58 33 0C 52 C9 7E 23 11 53 ED A5 4C C0 ED 99 29 +8F C6 59 6C 0C 89 D9 54 92 30 A3 89 74 C6 06 F4 +F1 EB B4 E2 B2 8B E6 14 72 EB 8C 89 5F 87 78 18 +D2 B8 7B 9D 5A 4A 8E 26 0F 51 DA E5 BC D3 E5 97 +BC B7 E1 AA 0B F7 37 A3 65 CC E3 EA 58 90 42 B8 +08 9C 31 E4 86 27 5E D3 6E AF 99 BC A8 4A A0 19 +BF 18 BF CC D4 EB 81 F6 75 A5 6D 3D 06 94 0B 2F +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +32 00 00 00 01 00 00 00 34 10 02 50 09 00 00 00 +CD AC 0F 6A 1A CB 29 BF 04 F6 31 B6 36 AB BC 0D +7B 16 5D A1 8B 66 DC 18 1B 41 2E 27 1A 65 5E 86 +2A DB BE 8A 78 8E B3 8D A2 C9 03 E5 A9 AC 4F E6 +D0 67 D8 CB 0F F2 A6 DB B9 9D 12 BE 5C C1 2D 84 +0B 41 06 14 21 E6 4C 01 F2 EA 24 5D 16 F8 BD 63 +50 6F 23 FB 0C 91 BA BD 9A 0E BA F4 1F A5 B5 74 +FD DF 44 D6 65 01 65 CD 7D 5E EC E4 48 54 DF 64 +E7 B5 F7 DC 07 9C 70 68 DB D1 EE 47 24 5B E5 C1 +D9 FA 02 3C 2E B6 2D D7 AF 8E A4 C5 C4 B0 4B D1 +BA 43 71 0F 3E B6 71 40 4B EC F0 21 39 50 06 41 +C0 41 3E 1B D0 B1 D3 D0 B9 AC 16 CA AA 55 6F A0 +75 CE C7 7B CE 25 DA 08 4B 65 6A 59 54 AE 57 0B +63 C8 88 4B D7 02 92 19 B6 12 C1 88 95 4A DC F6 +FA EF CF E1 6F 9E 80 A7 CD 6D 79 3A 44 2E 96 B5 +F0 6F 9D 17 A9 C5 98 C8 95 21 F0 D3 28 30 62 43 +E7 4F 3A 4C DA 7B AB 2F D4 B4 E5 04 92 06 42 E0 +2A AA FC 32 07 2F E9 05 EA 64 05 BA 78 97 16 7B +3E CA D4 61 EC 92 5D 4A BA B3 9C 07 40 4E 78 9A +8C 49 81 63 6A 8B 6D ED 42 4D E7 2B DB A3 34 A2 +E8 0D D1 60 DA 7D C7 F0 72 4B F9 C8 DF 2B 9A 23 +A6 A4 EB BF E9 42 10 C9 10 13 A1 A5 6A D6 44 8B +2F FF 9B EA 5F 44 1A 44 5D E3 8E E8 12 6C 38 89 +1E E1 8D 1A 50 F6 AF 46 C9 23 33 42 B4 8D 7B BA +B0 6E C3 06 36 5B D7 4F 01 00 C7 F0 DF B1 EF 0A +E6 99 E3 6A A6 30 19 F7 06 22 EF 0D 40 A6 E2 5C +F4 FC 82 6A 15 08 1B A9 66 00 00 00 66 4E F2 E3 +A7 05 9D AF 1C 58 CA F5 20 08 C5 22 7E 85 CD CB +83 B4 C5 94 57 F0 2C 50 8D 4F 4F 69 F8 26 BD 82 +C0 CF FC 5C B6 A9 7A F6 E5 61 C6 F9 69 70 00 52 +85 E5 8F 21 EF 65 11 D2 6E 70 98 89 A7 E5 13 C4 +34 C9 0A 3C F7 44 8F 0C AE EC 71 14 C7 47 B2 A0 +75 8A 3B 45 03 A7 CF 0C 69 87 3E D3 1D 94 DB EF +2B 7B 2F 16 88 30 EF 7D A3 32 2C 3D 3E 10 CA FB +7C 2C 33 C8 3B BF 4C 46 A3 1D A9 0C FF 3B FD 4C +CC 6E D4 B3 10 75 84 91 EE BA 60 3A 76 00 00 00 +CC 00 03 30 03 00 00 00 C0 2D 00 00 1A 2D 00 00 +1A 2D 00 00 1A 2D 00 00 1A 2D 00 00 1A 2D 00 00 +1A 2D 00 00 1A 2D 00 00 1A 2D 00 00 1A 2D 00 00 +1A 2D 00 00 00 2F 00 00 8C 2E 00 00 1A 2D 00 00 +1A 2D 00 00 1A 2D 00 00 1A 2D 00 00 1A 2D 00 00 +1A 2D 00 00 1A 2D 00 00 1A 2D 00 00 1A 2D 00 00 +1A 2D 00 00 68 2E 00 00 1A 2D 00 00 1A 2D 00 00 +1A 2D 00 00 40 2E 00 00 1A 2D 00 00 E4 2D 00 00 +1A 2D 00 00 1A 2D 00 00 C0 2D 00 00 06 2C 4C C7 +74 E2 13 BE 68 66 3B C0 E9 33 78 7E E2 CA AE 3A +FA 44 3E E6 7D EF AA 89 12 1C A2 61 73 6E 6E BB +B8 60 9D 35 68 E6 B7 23 C9 BC 33 0F 0C A0 0E CA +39 65 91 72 B4 73 B9 36 2D D3 3C A5 BC 62 30 95 +82 3D AF E1 90 99 83 14 FE DB AC 42 58 39 50 63 +23 45 64 53 21 23 AD FC EF DA 23 44 77 F2 81 7A +9E 46 51 52 25 55 33 2B 89 FC C5 99 0E D7 54 FD +2B F3 47 F7 6F D4 E1 B8 52 CD AC 30 36 BE C1 6B +F9 34 7B D2 68 1F 02 09 3A 31 B8 A6 83 C6 4C 93 +A6 FF 43 D5 7D C5 9C 8A AB 63 5B AC F0 A5 EB 3C +5D 1F 06 22 D3 E1 2C B7 6E 4B D9 B4 DD 34 5B A3 +53 5C 16 A9 EB 0D 31 CB 2F 6D 8D BE DC 28 CA 92 +11 56 3C 29 39 B4 39 82 8A 8B 2C 5B 2E 88 25 3D +C7 1D C1 3E D2 28 F2 9D A5 D5 5A 7A CA A1 E4 24 +C3 1D D2 5C 0A AC 3A A8 6C EB C5 F3 42 D7 C3 77 +A6 8A 47 AF ED 07 7E 39 C6 35 62 2D 29 28 6E A8 +B9 EE 60 EE F3 FA 21 2F 02 47 C8 90 38 E0 8E F9 +52 AA C5 8D 22 3C 65 C2 BC C6 11 69 23 86 AB D4 +6D 5C 73 42 D4 AA BF 1A 6F 0B 04 B8 A5 A1 E4 C2 +71 F7 0E E1 76 B1 CD F8 2A D5 5F 56 18 90 CC 73 +77 04 61 2D 34 49 A1 79 BD D4 16 BE B4 B6 1A A7 +2B E9 73 60 37 67 AC 66 F1 E0 35 E8 23 A4 2C 63 +43 E0 15 82 63 7C 05 32 5E B0 1C 18 48 C7 09 1F +8B EC 3C 8A AD EA 25 CE F2 C4 EB B3 0D EA 0F D3 +A6 61 0D 88 23 F3 BA 8E 77 F0 19 8B 3F 84 A6 22 +D2 38 50 36 D3 7D A0 D3 6A 1B AF 6C E1 C4 60 F0 +6F A4 7A 18 EA 69 CD C3 E0 22 B5 BC 8A 3B FA B6 +78 70 18 9C 8E 17 3B 0C E6 FB 90 4E 7E 36 76 97 +2B FF 37 87 F4 A3 A6 E1 C2 2B 6C 4E 18 6B 3A F9 +07 CD 14 0A 85 04 FD E7 C5 15 3A DA EC 2A 02 50 +00 C0 01 10 0A 00 00 00 01 00 00 00 00 00 00 00 +00 2B 02 50 28 C0 01 10 0C 00 00 00 FF FF FF FF +00 00 00 00 1C 2B 02 50 58 C0 01 10 0C 00 00 00 +FF FF FF FF 00 00 00 00 38 2B 02 50 88 C0 01 10 +0C 00 00 00 FF FF FF FF 00 00 00 00 54 2B 02 50 +B8 C0 01 10 0C 00 00 00 FF FF FF FF 00 00 00 00 +70 2B 02 50 E8 C0 01 10 0C 00 00 00 FF FF FF FF +00 00 00 00 8C 2B 02 50 18 C1 01 10 0C 00 00 00 +FF FF FF FF 00 00 00 00 A8 2B 02 50 48 C1 01 10 +0C 00 00 00 FF FF FF FF 00 00 00 00 C4 2B 02 50 +78 C1 01 10 0C 00 00 00 FF FF FF FF 00 00 00 00 +E0 2B 02 50 A8 C1 01 10 0C 00 00 00 FF FF FF FF +00 00 00 00 FC 2B 02 50 D8 C1 01 10 0C 00 00 00 +FF FF FF FF 00 00 00 00 18 2C 02 50 08 C2 01 10 +0A 00 00 00 00 00 00 00 00 00 00 00 28 2C 02 50 +30 C2 01 10 0C 00 00 00 FF FF FF FF 00 00 00 00 +3C 2C 02 50 60 C2 01 10 0C 00 00 00 FF FF FF FF +00 00 00 00 50 2C 02 50 90 C2 01 10 0C 00 00 00 +FF FF FF FF 00 00 00 00 64 2C 02 50 C0 C2 01 10 +0C 00 00 00 FF FF FF FF 00 00 00 00 78 2C 02 50 +F0 C2 01 10 0C 00 00 00 FF FF FF FF 00 00 00 00 +8C 2C 02 50 20 C3 01 10 0C 00 00 00 FF FF FF FF +00 00 00 00 A0 2C 02 50 50 C3 01 10 0C 00 00 00 +FF FF FF FF 00 00 00 00 B4 2C 02 50 80 C3 01 10 +0C 00 00 00 FF FF FF FF 00 00 00 00 C8 2C 02 50 +B0 C3 01 10 0C 00 00 00 FF FF FF FF 00 00 00 00 +DC 2C 02 50 E0 C3 01 10 0C 00 00 00 FF FF FF FF +00 00 00 00 F0 2C 02 50 10 C4 01 10 0A 00 00 00 +00 00 00 00 00 00 00 00 0C 2D 02 50 38 C4 01 10 +0A 00 00 00 FF FF FF FF 00 00 00 00 20 2D 02 50 +60 C4 01 10 08 00 00 00 00 00 00 00 00 00 00 00 +40 2D 02 50 80 C4 01 10 08 00 00 00 01 00 00 00 +00 00 00 00 60 2D 02 50 A0 C4 01 10 08 00 00 00 +FF FF FF FF 00 00 00 00 00 00 00 00 00 00 00 00 +0C 00 00 00 01 00 00 00 02 00 00 00 03 00 00 00 +04 00 00 00 05 00 00 00 06 00 00 00 07 00 00 00 +08 00 00 00 09 00 00 00 0A 00 00 00 0B 00 00 00 +01 00 00 00 0C 00 00 00 0C 00 00 00 0D 00 00 00 +0E 00 00 00 0F 00 00 00 10 00 00 00 11 00 00 00 +12 00 00 00 13 00 00 00 14 00 00 00 15 00 00 00 +16 00 00 00 03 00 00 00 01 00 00 00 17 00 00 00 +17 00 00 00 17 00 00 00 17 00 00 00 17 00 00 00 +17 00 00 00 17 00 00 00 17 00 00 00 17 00 00 00 +17 00 00 00 19 00 00 00 02 00 00 00 01 00 00 00 +1A 00 00 00 1A 00 00 00 1A 00 00 00 1A 00 00 00 +1A 00 00 00 1A 00 00 00 1A 00 00 00 1A 00 00 00 +FF FF FF FF FF FF FF FF F0 01 01 00 A8 02 01 00 +A8 02 01 00 FA 01 01 00 40 02 01 00 A8 02 01 00 +A8 02 01 00 F0 01 01 00 A8 02 01 00 82 02 01 00 +F0 01 01 00 A8 02 01 00 66 02 01 00 F0 01 01 00 +A8 02 01 00 A8 02 01 00 A8 02 01 00 58 02 01 00 +A8 76 2C 69 00 00 00 00 00 00 00 00 34 0E 02 50 +9C 0E 02 50 04 0F 02 50 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +01 00 00 00 00 00 00 00 0E 33 CD AB 34 12 6D E6 +EC DE 05 00 0B 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +A7 48 47 93 0A 03 AB EE A4 73 E1 F3 DC 30 B8 88 +15 00 00 00 44 49 47 45 53 54 5F 4C 45 4E 5F 53 +48 41 4B 45 5F 4D 41 58 20 6C 65 73 73 20 74 68 +61 6E 20 64 69 67 65 73 74 20 6C 65 6E 67 74 68 +2E 00 00 00 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D +2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D +2D 2D 2D 2D 2D 2D 00 00 20 53 48 41 33 20 73 6D +6F 6B 65 20 74 65 73 74 21 00 00 00 52 75 6E 6E +69 6E 67 20 53 48 41 33 20 74 65 73 74 2E 00 00 +52 75 6E 6E 69 6E 67 20 53 48 41 33 20 61 6C 6C +69 67 6E 6D 65 6E 74 20 74 65 73 74 2E 00 00 00 +52 75 6E 6E 69 6E 67 20 53 48 41 4B 45 20 74 65 +73 74 2E 00 4F 70 65 6E 54 69 74 61 6E 00 00 00 +E7 37 21 05 00 00 00 00 49 6E 3A 61 78 69 5F 64 +6D 61 5F 6E 6F 74 69 66 00 00 00 00 49 6E 3A 61 +78 69 5F 64 6D 61 5F 65 72 72 6F 72 00 00 00 00 +49 6E 3A 61 62 72 5F 6E 6F 74 69 66 00 00 00 00 +49 6E 3A 61 62 72 5F 65 72 72 6F 72 00 00 00 00 +49 6E 3A 73 68 61 35 31 32 5F 61 63 63 5F 65 72 +72 6F 72 00 49 6E 3A 73 68 61 35 31 32 5F 65 72 +72 6F 72 00 49 6E 3A 6B 76 5F 6E 6F 74 69 66 00 +49 6E 3A 6B 76 5F 65 72 72 6F 72 00 49 6E 3A 68 +6D 61 63 5F 65 72 72 6F 72 00 00 00 49 6E 3A 65 +63 63 5F 65 72 72 6F 72 00 00 00 00 49 6E 3A 64 +6F 65 5F 65 72 72 6F 72 00 00 00 00 49 6E 3A 30 +00 00 00 00 49 6E 3A 73 68 61 32 35 36 5F 65 72 +72 6F 72 00 49 6E 3A 73 68 61 35 31 32 5F 61 63 +63 5F 6E 6F 74 69 66 00 49 6E 3A 73 6F 63 5F 69 +66 63 5F 6E 6F 74 69 66 00 00 00 00 49 6E 3A 73 +6F 63 5F 69 66 63 5F 65 72 72 6F 72 00 00 00 00 +49 6E 3A 73 68 61 33 5F 6E 6F 74 69 66 00 00 00 +53 48 41 33 20 61 6E 64 20 4B 4D 41 43 20 69 6E +74 65 72 72 75 70 74 73 20 6F 75 74 20 6F 66 20 +73 79 6E 63 20 66 6F 72 20 43 4D 44 5F 44 4F 4E +45 2E 00 00 53 48 41 33 20 61 6E 64 20 4B 4D 41 +43 20 69 6E 74 65 72 72 75 70 74 73 20 6F 75 74 +20 6F 66 20 73 79 6E 63 20 66 6F 72 20 4D 53 47 +5F 46 49 46 4F 5F 45 4D 50 54 59 2E 00 00 00 00 +49 6E 3A 73 68 61 33 5F 65 72 72 6F 72 00 00 00 +53 48 41 33 20 61 6E 64 20 4B 4D 41 43 20 69 6E +74 65 72 72 75 70 74 73 20 6F 75 74 20 6F 66 20 +73 79 6E 63 20 66 6F 72 20 53 48 41 33 5F 45 52 +52 4F 52 2E 00 00 00 00 49 6E 3A 73 68 61 32 35 +36 5F 6E 6F 74 69 66 00 49 6E 3A 73 68 61 35 31 +32 5F 6E 6F 74 69 66 00 49 6E 3A 68 6D 61 63 5F +6E 6F 74 69 66 00 00 00 49 6E 3A 65 63 63 5F 6E +6F 74 69 66 00 00 00 00 49 6E 3A 64 6F 65 5F 6E +6F 74 69 66 00 00 00 00 44 6F 6E 65 20 68 61 6E +64 6C 69 6E 67 20 6D 61 63 68 69 6E 65 2D 6D 6F +64 65 20 54 49 4D 45 52 20 69 6E 74 65 72 72 75 +70 74 00 00 43 6F 72 20 45 72 72 6F 72 20 4C 6F +63 61 6C 20 49 53 52 00 45 72 72 6F 72 3A 20 48 +65 78 20 73 74 72 69 6E 67 20 6C 65 6E 67 74 68 +20 6D 75 73 74 20 62 65 20 61 20 6D 75 6C 74 69 +70 6C 65 20 6F 66 20 32 2E 00 00 00 43 6F 6E 66 +69 67 75 72 69 6E 67 20 41 45 53 20 66 6F 72 20 +62 69 67 20 65 6E 64 69 61 6E 20 6D 6F 64 65 00 +43 6F 6E 66 69 67 75 72 69 6E 67 20 41 45 53 20 +66 6F 72 20 6C 69 74 74 6C 65 20 65 6E 64 69 61 +6E 20 6D 6F 64 65 00 00 4C 6F 61 64 20 4B 65 79 +20 64 61 74 61 20 74 6F 20 41 45 53 00 00 00 00 +57 72 69 74 65 20 41 45 53 20 49 56 00 00 00 00 +57 61 69 74 20 66 6F 72 20 49 4E 50 55 54 5F 52 +45 41 44 59 00 00 00 00 49 6E 6A 65 63 74 69 6E +67 20 44 4D 41 20 65 72 72 00 00 00 49 6E 6A 65 +63 74 69 6E 67 20 41 45 53 20 63 6F 6C 6C 69 73 +69 6F 6E 20 65 72 72 00 41 45 53 20 63 6F 6C 6C +69 73 69 6F 6E 20 65 72 72 6F 72 20 6D 75 73 74 +20 72 65 73 75 6C 74 20 69 6E 20 4E 4D 49 2C 20 +61 6E 64 20 66 69 72 6D 77 61 72 65 20 72 65 73 +65 74 00 00 41 54 54 45 4D 50 54 20 54 4F 20 46 +4C 49 50 20 53 49 44 45 4C 4F 41 44 20 42 49 54 +00 00 00 00 45 58 50 45 43 54 45 44 20 4F 55 54 +50 55 54 5F 4C 4F 53 54 20 74 6F 20 62 65 20 6E +6F 6E 2D 7A 65 72 6F 20 73 69 6E 63 65 20 4F 43 +50 20 4C 4F 43 4B 20 70 72 6F 74 65 63 74 69 6F +6E 73 20 61 72 65 20 62 6C 6F 63 6B 69 6E 67 20 +74 68 65 20 6F 75 74 70 75 74 20 74 6F 20 46 57 +00 00 00 00 45 78 70 65 63 74 65 64 20 64 61 74 +61 3A 20 30 78 30 00 00 57 41 49 54 49 4E 47 20 +46 4F 52 20 4B 56 20 52 45 41 44 20 54 4F 20 46 +49 4E 49 53 48 00 00 00 45 58 50 45 43 54 49 4E +47 20 4B 56 20 52 44 20 45 52 52 00 45 58 50 45 +43 54 49 4E 47 20 4E 4F 20 4B 56 20 52 44 20 45 +52 52 00 00 57 41 49 54 49 4E 47 20 46 4F 52 20 +4B 56 20 57 52 49 54 45 20 54 4F 20 46 49 4E 49 +53 48 00 00 43 48 45 43 4B 49 4E 47 20 46 4F 52 +20 4B 56 20 57 52 49 54 45 20 45 52 52 00 00 00 +45 58 50 45 43 54 49 4E 47 20 4B 56 20 45 52 52 +00 00 00 00 45 58 50 45 43 54 49 4E 47 20 4E 4F +20 4B 56 20 45 52 52 00 52 65 61 64 20 61 6E 64 +20 43 6F 6D 70 61 72 65 20 47 43 4D 20 54 41 47 +00 00 00 00 41 45 53 20 4F 70 65 72 61 74 69 6F +6E 20 43 6F 6D 70 6C 65 74 65 00 00 4C 6F 61 64 +69 6E 67 20 4B 56 20 76 69 61 20 41 45 53 00 00 +44 4F 45 3A 20 49 6E 69 74 00 00 00 44 4F 45 3A +20 57 72 69 74 69 6E 67 20 55 44 53 20 49 56 00 +44 4F 45 3A 20 53 74 61 72 74 69 6E 67 20 55 44 +53 20 44 65 6F 62 66 75 73 63 61 74 69 6F 6E 20 +66 6C 6F 77 00 00 00 00 44 4F 45 3A 20 55 44 53 +20 44 65 6F 62 66 75 73 63 61 74 69 6F 6E 20 66 +6C 6F 77 20 63 6F 6D 70 6C 65 74 65 00 00 00 00 +44 4F 45 3A 20 57 72 69 74 69 6E 67 20 46 69 65 +6C 64 20 45 6E 74 72 6F 70 79 20 49 56 00 00 00 +44 4F 45 3A 20 53 74 61 72 74 69 6E 67 20 46 69 +65 6C 64 20 45 6E 74 72 6F 70 79 20 44 65 6F 62 +66 75 73 63 61 74 69 6F 6E 20 66 6C 6F 77 00 00 +44 4F 45 3A 20 46 69 65 6C 64 20 45 6E 74 72 6F +70 79 20 44 65 6F 62 66 75 73 63 61 74 69 6F 6E +20 66 6C 6F 77 20 63 6F 6D 70 6C 65 74 65 00 00 +44 4F 45 3A 20 57 72 69 74 69 6E 67 20 48 45 4B +20 49 56 00 44 4F 45 3A 20 53 74 61 72 74 69 6E +67 20 48 45 4B 20 44 65 6F 62 66 75 73 63 61 74 +69 6F 6E 20 66 6C 6F 77 00 00 00 00 44 4F 45 3A +20 48 45 4B 20 53 65 65 64 20 44 65 6F 62 66 75 +73 63 61 74 69 6F 6E 20 66 6C 6F 77 20 63 6F 6D +70 6C 65 74 65 00 00 00 44 4F 45 3A 20 53 6B 69 +70 70 69 6E 67 20 48 45 4B 20 44 65 6F 62 66 75 +73 63 61 74 69 6F 6E 20 64 75 65 20 74 6F 20 48 +57 5F 43 4F 4E 46 49 47 00 00 00 00 44 4F 45 3A +20 43 6C 65 61 72 20 73 65 63 72 65 74 73 00 00 +45 43 43 20 66 6C 6F 77 20 69 6E 20 70 72 6F 67 +72 65 73 73 2E 2E 2E 00 45 43 43 20 7A 65 72 6F +69 7A 65 20 66 6C 6F 77 2E 00 00 00 0A 45 43 43 +20 4B 45 59 47 45 4E 00 57 61 69 74 20 66 6F 72 +20 4B 56 20 77 72 69 74 65 00 00 00 4C 6F 61 64 +20 50 52 49 56 4B 45 59 20 64 61 74 61 20 66 72 +6F 6D 20 45 43 43 00 00 4C 6F 61 64 20 50 55 42 +4B 45 59 5F 58 20 64 61 74 61 20 66 72 6F 6D 20 +45 43 43 00 4C 6F 61 64 20 50 55 42 4B 45 59 5F +59 20 64 61 74 61 20 66 72 6F 6D 20 45 43 43 00 +53 74 6F 72 65 20 50 55 42 4B 45 59 5F 58 20 64 +61 74 61 20 69 6E 20 45 43 43 00 00 53 74 6F 72 +65 20 50 55 42 4B 45 59 5F 59 20 64 61 74 61 20 +69 6E 20 45 43 43 00 00 0A 45 43 43 20 53 48 41 +52 45 44 4B 45 59 00 00 4C 6F 61 64 20 53 48 41 +52 45 44 4B 45 59 20 64 61 74 61 20 66 72 6F 6D +20 45 43 43 00 00 00 00 49 6E 6A 65 63 74 20 50 +52 49 56 4B 45 59 20 66 72 6F 6D 20 6B 76 20 74 +6F 20 45 43 43 00 00 00 0A 45 43 43 20 53 49 47 +4E 49 4E 47 00 00 00 00 4C 6F 61 64 20 53 49 47 +4E 5F 52 20 64 61 74 61 20 66 72 6F 6D 20 45 43 +43 00 00 00 4C 6F 61 64 20 53 49 47 4E 5F 53 20 +64 61 74 61 20 66 72 6F 6D 20 45 43 43 00 00 00 +0A 45 43 43 20 56 45 52 49 46 59 49 4E 47 00 00 +4C 6F 61 64 20 56 45 52 49 46 59 5F 52 20 64 61 +74 61 20 66 72 6F 6D 20 45 43 43 00 0A 45 43 43 +20 50 43 52 20 53 49 47 4E 49 4E 47 00 00 00 00 +4D 4C 44 53 41 20 66 6C 6F 77 20 69 6E 20 70 72 +6F 67 72 65 73 73 2E 2E 2E 00 00 00 4D 4C 44 53 +41 20 7A 65 72 6F 69 7A 65 20 66 6C 6F 77 2E 00 +57 61 69 74 69 6E 67 20 66 6F 72 20 6D 6C 64 73 +61 20 73 74 61 74 75 73 20 72 65 61 64 79 00 00 +57 61 69 74 69 6E 67 20 66 6F 72 20 6D 6C 64 73 +61 20 73 74 61 74 75 73 20 72 65 61 64 79 20 69 +6E 20 6B 65 79 67 65 6E 00 00 00 00 54 72 79 20 +74 6F 20 4F 76 65 72 77 72 69 74 65 20 73 65 65 +64 20 64 61 74 61 20 69 6E 20 4D 4C 44 53 41 00 +5B 4D 4C 44 53 41 20 4B 65 79 47 65 6E 5D 20 52 +65 63 65 69 76 65 64 20 65 78 70 65 63 74 65 64 +20 65 72 72 20 66 6F 72 20 4D 4C 44 53 41 20 73 +65 65 64 20 72 65 61 64 20 66 72 6F 6D 20 4B 56 +00 00 00 00 5B 4D 4C 44 53 41 20 4B 65 79 47 65 +6E 5D 20 52 65 63 65 69 76 65 64 20 75 6E 65 78 +70 65 63 74 65 64 20 73 75 63 63 65 73 73 20 66 +6F 72 20 4D 4C 44 53 41 20 73 65 65 64 20 72 65 +61 64 20 66 72 6F 6D 20 4B 56 00 00 57 72 69 74 +69 6E 67 20 65 6E 74 72 6F 70 79 00 0A 4D 4C 44 +53 41 20 4B 45 59 47 45 4E 00 00 00 4C 6F 61 64 +20 50 52 49 56 4B 45 59 20 64 61 74 61 20 66 72 +6F 6D 20 4D 4C 44 53 41 00 00 00 00 4C 6F 61 64 +20 50 55 42 4B 45 59 20 64 61 74 61 20 66 72 6F +6D 20 4D 4C 44 53 41 00 5B 4D 4C 44 53 41 20 4B +65 79 47 65 6E 20 53 69 67 6E 69 6E 67 5D 20 52 +65 63 65 69 76 65 64 20 65 78 70 65 63 74 65 64 +20 65 72 72 20 66 6F 72 20 4D 4C 44 53 41 20 73 +65 65 64 20 72 65 61 64 20 66 72 6F 6D 20 4B 56 +00 00 00 00 5B 4D 4C 44 53 41 20 4B 65 79 47 65 +6E 20 53 69 67 6E 69 6E 67 5D 20 52 65 63 65 69 +76 65 64 20 75 6E 65 78 70 65 63 74 65 64 20 73 +75 63 63 65 73 73 20 66 6F 72 20 4D 4C 44 53 41 +20 73 65 65 64 20 72 65 61 64 20 66 72 6F 6D 20 +4B 56 00 00 0A 4D 4C 44 53 41 20 4B 45 59 47 45 +4E 20 2B 20 53 49 47 4E 49 4E 47 00 4C 6F 61 64 +20 53 49 47 4E 20 64 61 74 61 20 66 72 6F 6D 20 +4D 4C 44 53 41 00 00 00 57 72 69 74 69 6E 67 20 +70 72 69 76 6B 65 79 00 57 72 69 74 69 6E 67 20 +6D 73 67 00 0A 4D 4C 44 53 41 20 53 49 47 4E 49 +4E 47 00 00 0A 4D 4C 44 53 41 20 56 45 52 49 46 +59 49 4E 47 00 00 00 00 4C 6F 61 64 20 56 45 52 +49 46 59 5F 52 45 53 20 64 61 74 61 20 66 72 6F +6D 20 4D 4C 44 53 41 00 0A 4D 4C 44 53 41 20 4B +45 59 47 45 4E 20 2B 20 53 49 47 4E 49 4E 47 20 +69 6E 20 45 78 74 65 72 6E 61 6C 4D 75 20 6D 6F +64 65 00 00 57 72 69 74 69 6E 67 20 45 78 74 65 +72 6E 61 6C 4D 75 00 00 0A 4D 4C 44 53 41 20 53 +49 47 4E 49 4E 47 20 69 6E 20 45 78 74 65 72 6E +61 6C 4D 75 20 6D 6F 64 65 00 00 00 0A 4D 4C 44 +53 41 20 56 45 52 49 46 59 49 4E 47 20 69 6E 20 +45 78 74 65 72 6E 61 6C 4D 75 20 6D 6F 64 65 00 +5B 4D 4C 4B 45 4D 5D 20 57 61 69 74 69 6E 67 20 +66 6F 72 20 69 6E 74 65 72 72 75 70 74 00 00 00 +5B 4D 4C 4B 45 4D 5D 20 53 74 61 72 74 69 6E 67 +20 7A 65 72 6F 69 7A 65 00 00 00 00 5B 4D 4C 4B +45 4D 5D 20 57 61 69 74 69 6E 67 20 66 6F 72 20 +72 65 61 64 79 00 00 00 5B 4D 4C 4B 45 4D 20 4B +65 79 47 65 6E 5D 20 57 61 69 74 69 6E 67 20 66 +6F 72 20 72 65 61 64 79 00 00 00 00 5B 4D 4C 4B +45 4D 20 4B 65 79 47 65 6E 5D 20 54 72 79 20 74 +6F 20 4F 76 65 72 77 72 69 74 65 20 73 65 65 64 +20 64 20 64 61 74 61 00 5B 4D 4C 4B 45 4D 20 4B +65 79 47 65 6E 5D 20 54 72 79 20 74 6F 20 4F 76 +65 72 77 72 69 74 65 20 73 65 65 64 20 7A 20 64 +61 74 61 00 5B 4D 4C 4B 45 4D 20 4B 65 79 47 65 +6E 5D 20 52 65 63 65 69 76 65 64 20 65 78 70 65 +63 74 65 64 20 65 72 72 20 66 6F 72 20 4D 4C 4B +45 4D 20 73 65 65 64 20 72 65 61 64 20 66 72 6F +6D 20 4B 56 00 00 00 00 5B 4D 4C 4B 45 4D 20 4B +65 79 47 65 6E 5D 20 52 65 63 65 69 76 65 64 20 +75 6E 65 78 70 65 63 74 65 64 20 73 75 63 63 65 +73 73 20 66 6F 72 20 4D 4C 4B 45 4D 20 73 65 65 +64 20 72 65 61 64 20 66 72 6F 6D 20 4B 56 00 00 +5B 4D 4C 4B 45 4D 20 4B 65 79 47 65 6E 5D 20 57 +72 69 74 69 6E 67 20 65 6E 74 72 6F 70 79 00 00 +5B 4D 4C 4B 45 4D 20 4B 65 79 47 65 6E 5D 20 53 +65 6E 64 69 6E 67 20 63 6F 6D 6D 61 6E 64 00 00 +5B 4D 4C 4B 45 4D 20 4B 65 79 47 65 6E 5D 20 43 +68 65 63 6B 69 6E 67 20 65 6E 63 61 70 73 20 6B +65 79 00 00 5B 4D 4C 4B 45 4D 20 4B 65 79 47 65 +6E 5D 20 43 68 65 63 6B 69 6E 67 20 64 65 63 61 +70 73 20 6B 65 79 00 00 5B 4D 4C 4B 45 4D 20 4B +65 79 47 65 6E 5D 20 43 68 65 63 6B 20 74 68 61 +74 20 53 45 45 44 5F 44 20 61 70 69 20 68 61 73 +20 30 73 00 5B 4D 4C 4B 45 4D 20 4B 65 79 47 65 +6E 5D 20 43 68 65 63 6B 20 74 68 61 74 20 53 45 +45 44 5F 5A 20 61 70 69 20 68 61 73 20 30 73 00 +5B 4D 4C 4B 45 4D 20 4B 65 79 47 65 6E 5D 20 52 +65 61 64 20 45 6E 63 61 70 73 20 4B 65 79 00 00 +5B 4D 4C 4B 45 4D 20 4B 65 79 47 65 6E 5D 20 52 +65 61 64 20 44 65 63 61 70 73 20 4B 65 79 00 00 +5B 4D 4C 4B 45 4D 20 4B 65 79 47 65 6E 5D 20 43 +68 65 63 6B 20 74 68 61 74 20 44 4B 20 61 70 69 +20 68 61 73 20 30 73 00 5B 4D 4C 4B 45 4D 20 45 +6E 63 61 70 73 5D 20 57 61 69 74 69 6E 67 20 66 +6F 72 20 72 65 61 64 79 00 00 00 00 5B 4D 4C 4B +45 4D 20 45 6E 63 61 70 73 5D 20 57 72 69 74 69 +6E 67 20 65 6E 63 61 70 73 20 6B 65 79 00 00 00 +5B 4D 4C 4B 45 4D 20 45 6E 63 61 70 73 5D 20 54 +72 79 20 74 6F 20 4F 76 65 72 77 72 69 74 65 20 +6D 73 67 00 5B 4D 4C 4B 45 4D 20 45 6E 63 61 70 +73 5D 20 54 72 79 20 74 6F 20 4F 76 65 72 77 72 +69 74 65 20 6D 73 67 20 74 68 72 6F 75 67 68 20 +4D 4C 44 53 41 20 70 72 69 76 6B 65 79 00 00 00 +5B 4D 4C 4B 45 4D 20 4B 65 79 47 65 6E 5D 20 52 +65 63 65 69 76 65 64 20 65 78 70 65 63 74 65 64 +20 65 72 72 20 66 6F 72 20 4D 4C 4B 45 4D 20 6D +73 67 20 72 65 61 64 20 66 72 6F 6D 20 4B 56 00 +5B 4D 4C 4B 45 4D 20 4B 65 79 47 65 6E 5D 20 52 +65 63 65 69 76 65 64 20 75 6E 65 78 70 65 63 74 +65 64 20 73 75 63 63 65 73 73 20 66 6F 72 20 4D +4C 4B 45 4D 20 6D 73 67 20 72 65 61 64 20 66 72 +6F 6D 20 4B 56 00 00 00 5B 4D 4C 4B 45 4D 20 45 +6E 63 61 70 73 5D 20 43 68 65 63 6B 20 74 68 61 +74 20 4D 53 47 20 61 70 69 20 68 61 73 20 30 73 +00 00 00 00 5B 4D 4C 4B 45 4D 20 45 6E 63 61 70 +73 5D 20 57 72 69 74 69 6E 67 20 65 6E 74 72 6F +70 79 00 00 5B 4D 4C 4B 45 4D 20 45 6E 63 61 70 +73 5D 20 53 65 6E 64 69 6E 67 20 63 6F 6D 6D 61 +6E 64 00 00 5B 4D 4C 4B 45 4D 20 45 6E 63 61 70 +73 5D 20 43 68 65 63 6B 20 43 69 70 68 65 72 74 +65 78 74 00 5B 4D 4C 4B 45 4D 20 45 6E 63 61 70 +73 5D 20 52 65 63 65 69 76 65 64 20 65 78 70 65 +63 74 65 64 20 65 72 72 20 66 6F 72 20 4D 4C 4B +45 4D 20 73 68 61 72 65 64 6B 65 79 20 77 72 69 +74 65 20 66 72 6F 6D 20 4B 56 00 00 5B 4D 4C 4B +45 4D 20 45 6E 63 61 70 73 5D 20 52 65 63 65 69 +76 65 64 20 75 6E 65 78 70 65 63 74 65 64 20 73 +75 63 63 65 73 73 20 66 6F 72 20 4D 4C 4B 45 4D +20 73 68 61 72 65 64 6B 65 79 20 77 72 69 74 65 +20 66 72 6F 6D 20 4B 56 00 00 00 00 5B 4D 4C 4B +45 4D 20 45 6E 63 61 70 73 5D 20 52 65 63 65 69 +76 65 64 20 75 6E 65 78 70 65 63 74 65 64 20 65 +72 72 20 66 6F 72 20 4D 4C 4B 45 4D 20 73 68 61 +72 65 64 6B 65 79 20 77 72 69 74 65 20 66 72 6F +6D 20 4B 56 00 00 00 00 5B 4D 4C 4B 45 4D 20 45 +6E 63 61 70 73 5D 20 52 65 63 65 69 76 65 64 20 +65 78 70 65 63 74 65 64 20 73 75 63 63 65 73 73 +20 66 6F 72 20 4D 4C 4B 45 4D 20 73 68 61 72 65 +64 6B 65 79 20 77 72 69 74 65 20 66 72 6F 6D 20 +4B 56 00 00 5B 4D 4C 4B 45 4D 20 45 6E 63 61 70 +73 5D 20 43 68 65 63 6B 20 53 68 61 72 65 64 20 +4B 65 79 00 5B 4D 4C 4B 45 4D 20 45 6E 63 61 70 +73 5D 20 4B 56 20 75 73 65 64 2C 20 63 68 65 63 +6B 20 53 68 61 72 65 64 20 4B 65 79 20 69 73 20 +30 00 00 00 5B 4D 4C 4B 45 4D 20 45 6E 63 61 70 +73 5D 20 53 65 6E 64 69 6E 67 20 43 6F 6D 6D 61 +6E 64 00 00 5B 4D 4C 4B 45 4D 20 45 6E 63 61 70 +73 5D 20 52 65 61 64 20 43 69 70 68 65 72 74 65 +78 74 00 00 5B 4D 4C 4B 45 4D 20 45 6E 63 61 70 +73 5D 20 52 65 63 65 69 76 65 64 20 75 6E 65 78 +70 65 63 74 65 64 20 66 61 69 6C 20 66 6F 72 20 +4D 4C 4B 45 4D 20 73 68 61 72 65 64 6B 65 79 20 +77 72 69 74 65 20 66 72 6F 6D 20 4B 56 00 00 00 +5B 4D 4C 4B 45 4D 20 45 6E 63 61 70 73 5D 20 52 +65 61 64 20 53 68 61 72 65 64 20 4B 65 79 00 00 +5B 4D 4C 4B 45 4D 20 44 65 63 61 70 73 5D 20 57 +61 69 74 69 6E 67 20 66 6F 72 20 72 65 61 64 79 +00 00 00 00 5B 4D 4C 4B 45 4D 20 44 65 63 61 70 +73 5D 20 57 72 69 74 69 6E 67 20 64 65 63 61 70 +73 20 6B 65 79 00 00 00 5B 4D 4C 4B 45 4D 20 44 +65 63 61 70 73 5D 20 57 72 69 74 69 6E 67 20 65 +6E 74 72 6F 70 79 00 00 5B 4D 4C 4B 45 4D 20 44 +65 63 61 70 73 5D 20 53 65 6E 64 69 6E 67 20 63 +6F 6D 6D 61 6E 64 00 00 5B 4D 4C 4B 45 4D 20 44 +65 63 61 70 73 5D 20 52 65 63 65 69 76 65 64 20 +65 78 70 65 63 74 65 64 20 65 72 72 20 66 6F 72 +20 4D 4C 4B 45 4D 20 73 68 61 72 65 64 6B 65 79 +20 77 72 69 74 65 20 66 72 6F 6D 20 4B 56 00 00 +5B 4D 4C 4B 45 4D 20 44 65 63 61 70 73 5D 20 52 +65 63 65 69 76 65 64 20 75 6E 65 78 70 65 63 74 +65 64 20 73 75 63 63 65 73 73 20 66 6F 72 20 4D +4C 4B 45 4D 20 73 68 61 72 65 64 6B 65 79 20 77 +72 69 74 65 20 66 72 6F 6D 20 4B 56 00 00 00 00 +5B 4D 4C 4B 45 4D 20 44 65 63 61 70 73 5D 20 52 +65 63 65 69 76 65 64 20 75 6E 65 78 70 65 63 74 +65 64 20 66 61 69 6C 20 66 6F 72 20 4D 4C 4B 45 +4D 20 73 68 61 72 65 64 6B 65 79 20 77 72 69 74 +65 20 66 72 6F 6D 20 4B 56 00 00 00 5B 4D 4C 4B +45 4D 20 44 65 63 61 70 73 5D 20 52 65 63 65 69 +76 65 64 20 65 78 70 65 63 74 65 64 20 73 75 63 +63 65 73 73 20 66 6F 72 20 4D 4C 4B 45 4D 20 73 +68 61 72 65 64 6B 65 79 20 77 72 69 74 65 20 66 +72 6F 6D 20 4B 56 00 00 5B 4D 4C 4B 45 4D 20 44 +65 63 61 70 73 5D 20 4B 56 20 75 73 65 64 2C 20 +63 68 65 63 6B 20 53 68 61 72 65 64 20 4B 65 79 +20 69 73 20 30 00 00 00 5B 4D 4C 4B 45 4D 20 44 +65 63 61 70 73 5D 20 43 68 65 63 6B 20 53 68 61 +72 65 64 20 4B 65 79 00 5B 4D 4C 4B 45 4D 20 44 +65 63 61 70 73 5D 20 52 65 63 65 69 76 65 64 20 +65 78 70 65 63 74 65 64 20 65 72 72 20 66 6F 72 +20 4D 4C 4B 45 4D 20 73 68 61 72 65 64 6B 65 79 +20 72 65 61 64 20 66 72 6F 6D 20 4B 56 00 00 00 +5B 4D 4C 4B 45 4D 20 44 65 63 61 70 73 5D 20 52 +65 63 65 69 76 65 64 20 75 6E 65 78 70 65 63 74 +65 64 20 73 75 63 63 65 73 73 20 66 6F 72 20 4D +4C 4B 45 4D 20 73 68 61 72 65 64 6B 65 79 20 72 +65 61 64 20 66 72 6F 6D 20 4B 56 00 5B 4D 4C 4B +45 4D 20 44 65 63 61 70 73 5D 20 52 65 61 64 20 +53 68 61 72 65 64 20 4B 65 79 00 00 5B 4D 4C 4B +45 4D 20 4B 65 79 47 65 6E 20 44 65 63 61 70 73 +5D 20 57 61 69 74 69 6E 67 20 66 6F 72 20 72 65 +61 64 79 00 5B 4D 4C 4B 45 4D 20 4B 65 79 47 65 +6E 20 44 65 63 61 70 73 5D 20 54 72 79 20 74 6F +20 4F 76 65 72 77 72 69 74 65 20 73 65 65 64 20 +64 00 00 00 5B 4D 4C 4B 45 4D 20 4B 65 79 47 65 +6E 20 44 65 63 61 70 73 5D 20 54 72 79 20 74 6F +20 4F 76 65 72 77 72 69 74 65 20 73 65 65 64 20 +7A 00 00 00 5B 4D 4C 4B 45 4D 20 4B 65 79 47 65 +6E 20 44 65 63 61 70 73 5D 20 57 72 69 74 69 6E +67 20 65 6E 74 72 6F 70 79 00 00 00 5B 4D 4C 4B +45 4D 20 4B 65 79 47 65 6E 20 44 65 63 61 70 73 +5D 20 53 65 6E 64 69 6E 67 20 63 6F 6D 6D 61 6E +64 00 00 00 5B 4D 4C 4B 45 4D 20 4B 65 79 47 65 +6E 20 44 65 63 61 70 73 5D 20 52 65 63 65 69 76 +65 64 20 65 78 70 65 63 74 65 64 20 65 72 72 20 +66 6F 72 20 4D 4C 4B 45 4D 20 73 68 61 72 65 64 +6B 65 79 20 77 72 69 74 65 20 66 72 6F 6D 20 4B +56 00 00 00 5B 4D 4C 4B 45 4D 20 4B 65 79 47 65 +6E 20 44 65 63 61 70 73 5D 20 52 65 63 65 69 76 +65 64 20 75 6E 65 78 70 65 63 74 65 64 20 73 75 +63 63 65 73 73 20 66 6F 72 20 4D 4C 4B 45 4D 20 +73 68 61 72 65 64 6B 65 79 20 77 72 69 74 65 20 +66 72 6F 6D 20 4B 56 00 5B 4D 4C 4B 45 4D 20 4B +65 79 47 65 6E 20 44 65 63 61 70 73 5D 20 52 65 +63 65 69 76 65 64 20 75 6E 65 78 70 65 63 74 65 +64 20 66 61 69 6C 20 66 6F 72 20 4D 4C 4B 45 4D +20 73 68 61 72 65 64 6B 65 79 20 77 72 69 74 65 +20 66 72 6F 6D 20 4B 56 00 00 00 00 5B 4D 4C 4B +45 4D 20 4B 65 79 47 65 6E 20 44 65 63 61 70 73 +5D 20 52 65 63 65 69 76 65 64 20 65 78 70 65 63 +74 65 64 20 73 75 63 63 65 73 73 20 66 6F 72 20 +4D 4C 4B 45 4D 20 73 68 61 72 65 64 6B 65 79 20 +77 72 69 74 65 20 66 72 6F 6D 20 4B 56 00 00 00 +5B 4D 4C 4B 45 4D 20 4B 65 79 47 65 6E 20 44 65 +63 61 70 73 5D 20 43 68 65 63 6B 20 53 68 61 72 +65 64 20 4B 65 79 00 00 5B 4D 4C 4B 45 4D 20 4B +65 79 47 65 6E 20 44 65 63 61 70 73 5D 20 4B 56 +20 75 73 65 64 2C 20 63 68 65 63 6B 20 53 68 61 +72 65 64 20 4B 65 79 20 69 73 20 30 00 00 00 00 +5B 4D 4C 4B 45 4D 20 4B 65 79 47 65 6E 20 44 65 +63 61 70 73 5D 20 52 65 61 64 20 53 68 61 72 65 +64 20 4B 65 79 00 00 00 48 4D 41 43 20 66 6C 6F +77 20 69 6E 20 70 72 6F 67 72 65 73 73 2E 2E 2E +00 00 00 00 48 4D 41 43 20 7A 65 72 6F 69 7A 65 +20 66 6C 6F 77 2E 00 00 54 72 79 20 74 6F 20 4F +76 65 72 77 72 69 74 65 20 4B 65 79 20 64 61 74 +61 20 69 6E 20 48 4D 41 43 33 38 34 00 00 00 00 +52 65 63 65 69 76 65 64 20 65 78 70 65 63 74 65 +64 20 65 72 72 20 66 6F 72 20 48 4D 41 43 20 6B +65 79 20 72 65 61 64 20 66 72 6F 6D 20 4B 56 20 +77 68 69 6C 65 20 4F 43 50 20 6C 6F 63 6B 20 69 +6E 20 70 72 6F 67 72 65 73 73 00 00 52 65 63 65 +69 76 65 64 20 75 6E 65 78 70 65 63 74 65 64 20 +73 75 63 63 65 73 73 20 66 6F 72 20 48 4D 41 43 +20 6B 65 79 20 72 65 61 64 20 66 72 6F 6D 20 4B +56 20 77 68 69 6C 65 20 4F 43 50 20 6C 6F 63 6B +20 69 6E 20 70 72 6F 67 72 65 73 73 00 00 00 00 +4C 6F 61 64 20 4B 65 79 20 64 61 74 61 20 74 6F +20 48 4D 41 43 00 00 00 54 72 79 20 74 6F 20 4F +76 65 72 77 72 69 74 65 20 42 6C 6F 63 6B 20 64 +61 74 61 20 69 6E 20 48 4D 41 43 00 52 65 63 65 +69 76 65 64 20 65 78 70 65 63 74 65 64 20 65 72 +72 20 66 6F 72 20 48 4D 41 43 20 62 6C 6F 63 6B +20 72 65 61 64 20 66 72 6F 6D 20 4B 56 20 77 68 +69 6C 65 20 4F 43 50 20 6C 6F 63 6B 20 69 6E 20 +70 72 6F 67 72 65 73 73 00 00 00 00 52 65 63 65 +69 76 65 64 20 75 6E 65 78 70 65 63 74 65 64 20 +73 75 63 63 65 73 73 20 66 6F 72 20 48 4D 41 43 +20 62 6C 6F 63 6B 20 72 65 61 64 20 66 72 6F 6D +20 4B 56 20 77 68 69 6C 65 20 4F 43 50 20 6C 6F +63 6B 20 69 6E 20 70 72 6F 67 72 65 73 73 00 00 +4C 6F 61 64 20 54 41 47 20 64 61 74 61 20 66 72 +6F 6D 20 48 4D 41 43 20 74 6F 20 4B 56 00 00 00 +4C 6F 61 64 20 54 41 47 20 64 61 74 61 20 66 72 +6F 6D 20 48 4D 41 43 00 54 72 79 20 74 6F 20 4F +76 65 72 77 72 69 74 65 20 4B 65 79 20 64 61 74 +61 20 69 6E 20 48 4D 41 43 35 31 32 00 00 00 00 +4B 56 3A 20 63 68 65 63 6B 69 6E 67 20 66 6F 72 +20 65 72 72 6F 72 73 00 4B 56 20 45 52 52 4F 52 +00 00 00 00 4B 56 3A 20 63 68 65 63 6B 69 6E 67 +20 65 72 72 6F 72 73 20 70 72 65 73 65 6E 74 00 +4E 4F 20 4B 56 20 45 52 52 4F 52 00 4B 56 3A 20 +70 72 6F 67 20 6B 76 20 72 65 61 64 20 63 74 72 +6C 00 00 00 4B 56 3A 20 70 72 6F 67 20 6B 76 20 +77 72 69 74 65 20 63 74 72 6C 00 00 50 56 3A 20 +70 72 6F 67 20 6B 76 20 72 65 61 64 20 63 74 72 +6C 20 69 6E 20 53 48 41 20 74 6F 20 64 6F 20 68 +61 73 68 20 65 78 74 65 6E 64 00 00 2D 2D 2D 2D +2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D +2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 00 53 54 49 43 +4B 59 44 41 54 41 56 41 55 4C 54 43 54 52 4C 00 +53 54 49 43 4B 59 5F 44 41 54 41 5F 56 41 55 4C +54 5F 45 4E 54 52 59 5F 30 00 00 00 53 54 49 43 +4B 59 5F 44 41 54 41 5F 56 41 55 4C 54 5F 45 4E +54 52 59 5F 31 00 00 00 53 54 49 43 4B 59 5F 44 +41 54 41 5F 56 41 55 4C 54 5F 45 4E 54 52 59 5F +32 00 00 00 53 54 49 43 4B 59 5F 44 41 54 41 5F +56 41 55 4C 54 5F 45 4E 54 52 59 5F 33 00 00 00 +53 54 49 43 4B 59 5F 44 41 54 41 5F 56 41 55 4C +54 5F 45 4E 54 52 59 5F 34 00 00 00 53 54 49 43 +4B 59 5F 44 41 54 41 5F 56 41 55 4C 54 5F 45 4E +54 52 59 5F 35 00 00 00 53 54 49 43 4B 59 5F 44 +41 54 41 5F 56 41 55 4C 54 5F 45 4E 54 52 59 5F +36 00 00 00 53 54 49 43 4B 59 5F 44 41 54 41 5F +56 41 55 4C 54 5F 45 4E 54 52 59 5F 37 00 00 00 +53 54 49 43 4B 59 5F 44 41 54 41 5F 56 41 55 4C +54 5F 45 4E 54 52 59 5F 38 00 00 00 53 54 49 43 +4B 59 5F 44 41 54 41 5F 56 41 55 4C 54 5F 45 4E +54 52 59 5F 39 00 00 00 44 41 54 41 56 41 55 4C +54 43 54 52 4C 00 00 00 44 41 54 41 5F 56 41 55 +4C 54 5F 45 4E 54 52 59 5F 30 00 00 44 41 54 41 +5F 56 41 55 4C 54 5F 45 4E 54 52 59 5F 31 00 00 +44 41 54 41 5F 56 41 55 4C 54 5F 45 4E 54 52 59 +5F 32 00 00 44 41 54 41 5F 56 41 55 4C 54 5F 45 +4E 54 52 59 5F 33 00 00 44 41 54 41 5F 56 41 55 +4C 54 5F 45 4E 54 52 59 5F 34 00 00 44 41 54 41 +5F 56 41 55 4C 54 5F 45 4E 54 52 59 5F 35 00 00 +44 41 54 41 5F 56 41 55 4C 54 5F 45 4E 54 52 59 +5F 36 00 00 44 41 54 41 5F 56 41 55 4C 54 5F 45 +4E 54 52 59 5F 37 00 00 44 41 54 41 5F 56 41 55 +4C 54 5F 45 4E 54 52 59 5F 38 00 00 44 41 54 41 +5F 56 41 55 4C 54 5F 45 4E 54 52 59 5F 39 00 00 +4C 4F 43 4B 41 42 4C 45 5F 53 43 52 41 54 43 48 +52 45 47 5F 43 54 52 4C 00 00 00 00 4C 4F 43 4B +41 42 4C 45 5F 53 43 52 41 54 43 48 52 45 47 00 +4E 4F 4E 53 54 49 43 4B 59 5F 47 45 4E 45 52 49 +43 5F 53 43 52 41 54 43 48 52 45 47 00 00 00 00 +53 54 49 43 4B 59 5F 4C 4F 43 4B 41 42 4C 45 5F +53 43 52 41 54 43 48 52 45 47 5F 43 54 52 4C 00 +53 54 49 43 4B 59 5F 4C 4F 43 4B 41 42 4C 45 5F +53 43 52 41 54 43 48 52 45 47 00 00 53 48 41 32 +35 36 20 66 6C 6F 77 20 69 6E 20 70 72 6F 67 72 +65 73 73 2E 2E 2E 00 00 53 48 41 32 35 36 20 7A +65 72 6F 69 7A 65 20 66 6C 6F 77 2E 00 00 00 00 +45 6E 61 62 6C 65 20 53 48 41 32 35 36 00 00 00 +4C 6F 61 64 20 44 49 47 45 53 54 20 64 61 74 61 +20 66 72 6F 6D 20 53 48 41 32 35 36 00 00 00 00 +45 72 72 6F 72 31 20 69 73 20 65 78 70 65 63 74 +65 64 20 77 68 65 6E 20 69 6E 69 74 20 61 6E 64 +20 6E 65 78 74 20 61 72 65 20 61 73 73 65 72 74 +65 64 20 61 74 20 74 68 65 20 73 61 6D 65 20 74 +69 6D 65 2E 20 43 68 65 63 6B 20 61 72 67 73 20 +67 69 76 65 6E 20 74 6F 20 73 68 61 32 35 36 5F +65 72 72 6F 72 5F 66 6C 6F 77 28 29 00 00 00 00 +45 72 72 6F 72 30 20 69 73 20 65 78 70 65 63 74 +65 64 20 66 6F 72 20 69 6E 76 61 6C 69 64 20 77 +6E 74 7A 5F 6D 6F 64 65 20 6F 72 20 77 2E 20 43 +68 65 63 6B 20 61 72 67 73 20 67 69 76 65 6E 20 +74 6F 20 73 68 61 32 35 36 5F 65 72 72 6F 72 5F +66 6C 6F 77 28 29 00 00 53 48 41 35 31 32 20 66 +6C 6F 77 20 69 6E 20 70 72 6F 67 72 65 73 73 2E +2E 2E 00 00 53 48 41 35 31 32 3A 20 53 65 74 20 +53 54 41 52 54 20 66 6F 72 20 67 65 6E 20 68 61 +73 68 20 66 75 6E 63 00 53 48 41 35 31 32 20 7A +65 72 6F 69 7A 65 20 66 6C 6F 77 2E 00 00 00 00 +45 6E 61 62 6C 65 20 53 48 41 35 31 32 00 00 00 +4C 6F 61 64 20 44 49 47 45 53 54 20 64 61 74 61 +20 66 72 6F 6D 20 53 48 41 35 31 32 00 00 00 00 +64 69 66 5F 6B 6D 61 63 5F 63 75 73 74 6F 6D 69 +7A 61 74 69 6F 6E 5F 73 74 72 69 6E 67 5F 69 6E +69 74 3A 20 45 52 52 4F 52 20 64 61 74 61 20 61 +6E 64 20 6F 75 74 20 61 72 67 75 6D 65 6E 74 73 +20 6D 75 73 74 20 6E 6F 74 20 62 65 20 6E 75 6C +6C 2E 00 00 64 69 66 5F 6B 6D 61 63 5F 63 75 73 +74 6F 6D 69 7A 61 74 69 6F 6E 5F 73 74 72 69 6E +67 5F 69 6E 69 74 3A 20 45 52 52 4F 52 20 6C 65 +6E 67 74 68 20 67 72 65 61 74 65 72 20 74 68 61 +6E 20 6D 61 78 69 6D 75 6D 2E 00 00 64 69 66 5F +6B 6D 61 63 5F 66 75 6E 63 74 69 6F 6E 5F 6E 61 +6D 65 5F 69 6E 69 74 3A 20 45 52 52 4F 52 20 64 +61 74 61 20 61 6E 64 20 6F 75 74 20 6D 75 73 74 +20 6E 6F 74 20 62 65 20 4E 55 4C 4C 2E 00 00 00 +64 69 66 5F 6B 6D 61 63 5F 66 75 6E 63 74 69 6F +6E 5F 6E 61 6D 65 5F 69 6E 69 74 3A 20 45 52 52 +4F 52 20 6C 65 6E 67 74 68 20 6C 61 72 67 65 72 +20 74 68 61 6E 20 6D 61 78 69 6D 75 6D 2E 00 00 +64 69 66 5F 6B 6D 61 63 5F 6D 6F 64 65 5F 73 68 +61 33 5F 73 74 61 72 74 3A 20 45 52 52 4F 52 20 +6B 6D 61 63 20 6F 72 20 6F 70 65 72 61 74 69 6F +6E 5F 73 74 61 74 65 20 4E 55 4C 4C 2E 00 00 00 +64 69 66 5F 6B 6D 61 63 5F 73 68 61 33 5F 73 74 +61 72 74 3A 20 45 52 52 4F 52 20 55 6E 73 75 70 +70 6F 72 74 65 64 20 6D 6F 64 65 2E 00 00 00 00 +64 69 66 5F 6B 6D 61 63 5F 73 68 61 33 5F 73 74 +61 72 74 3A 20 45 52 52 4F 52 20 68 61 72 64 77 +61 72 65 20 6D 75 73 74 20 62 65 20 69 64 6C 65 +2E 00 00 00 64 69 66 5F 6B 6D 61 63 5F 6D 6F 64 +65 5F 73 68 61 6B 65 5F 73 74 61 72 74 3A 20 45 +52 52 4F 52 20 6B 6D 61 63 20 61 6E 64 20 6F 70 +65 72 61 74 69 6F 6E 20 73 74 61 74 65 20 63 61 +6E 6E 6F 74 20 62 65 20 4E 55 4C 4C 2E 00 00 00 +64 69 66 5F 6B 6D 61 63 5F 6D 6F 64 65 5F 73 68 +61 6B 65 5F 73 74 61 72 74 3A 20 45 52 52 4F 52 +20 6D 6F 64 65 20 6E 6F 74 20 61 6C 6C 6F 77 65 +64 2E 00 00 64 69 66 5F 6B 6D 61 63 5F 73 68 61 +6B 65 5F 73 74 61 72 74 3A 20 45 52 52 4F 52 20 +68 61 72 64 77 61 72 65 20 6D 75 73 74 20 62 65 +20 69 64 6C 65 2E 00 00 64 69 66 5F 6B 6D 61 63 +5F 6D 6F 64 65 5F 63 73 68 61 6B 65 5F 73 74 61 +72 74 3A 20 45 52 52 4F 52 20 6B 6D 61 63 20 6F +72 20 6F 70 65 72 61 74 69 6F 6E 20 73 74 61 74 +65 20 69 73 20 4E 55 4C 4C 2E 00 00 64 69 66 5F +6B 6D 61 63 5F 6D 6F 64 65 5F 63 73 68 61 6B 65 +5F 73 74 61 72 74 3A 20 45 52 52 4F 52 20 75 6E +73 75 70 70 6F 72 74 65 64 20 6D 6F 64 65 20 66 +6F 72 20 65 6D 70 74 79 20 4E 20 61 6E 64 20 53 +2E 00 00 00 64 69 66 5F 6B 6D 61 63 5F 6D 6F 64 +65 5F 63 73 68 61 6B 65 5F 73 74 61 72 74 3A 20 +45 52 52 4F 52 20 75 6E 73 75 70 70 6F 72 74 65 +64 20 6B 73 74 72 65 6E 67 68 74 2E 00 00 00 00 +64 69 66 5F 6B 6D 61 63 5F 6D 6F 64 65 5F 63 73 +68 61 6B 65 5F 73 74 61 72 74 3A 20 45 52 52 4F +52 20 68 61 72 64 77 61 72 65 20 6D 75 73 74 20 +62 65 20 69 64 6C 65 2E 00 00 00 00 64 69 66 5F +6B 6D 61 63 5F 61 62 73 6F 72 62 3A 20 45 52 52 +4F 52 20 6F 6E 65 20 6F 66 20 66 75 6E 63 74 69 +6F 6E 20 61 72 67 75 6D 65 6E 74 73 20 69 73 20 +6E 75 6C 6C 00 00 00 00 64 69 66 5F 6B 6D 61 63 +5F 61 62 73 6F 72 62 3A 20 45 52 52 4F 52 20 6F +70 65 72 61 74 69 6F 6E 20 6E 6F 74 20 73 74 61 +72 74 65 64 20 79 65 74 00 00 00 00 64 69 66 5F +6B 6D 61 63 5F 61 62 73 6F 72 62 3A 20 45 52 52 +4F 52 20 68 61 72 64 77 61 72 65 20 6D 75 73 74 +20 62 65 20 61 62 73 6F 72 62 69 6E 67 2E 00 00 +64 69 66 5F 6B 6D 61 63 5F 73 71 75 65 65 7A 65 +3A 20 45 52 52 4F 52 20 61 72 67 75 6D 65 6E 74 +73 20 6D 61 79 20 6E 6F 74 20 62 65 20 4E 55 4C +4C 2E 00 00 64 69 66 5F 6B 6D 61 63 5F 73 71 75 +65 65 7A 65 3A 20 45 52 52 4F 52 20 74 6F 74 61 +6C 20 62 79 74 65 73 20 72 65 71 75 65 73 74 65 +64 20 6D 75 73 74 20 6E 6F 74 20 65 78 63 65 65 +64 20 66 69 78 65 64 20 6F 75 74 70 75 74 20 6C +65 6E 67 74 68 2E 00 00 64 69 66 5F 6B 6D 61 63 +5F 73 71 75 65 65 7A 65 3A 20 45 52 52 4F 52 20 +6F 70 65 72 61 74 69 6F 6E 20 73 74 61 74 65 20 +64 20 6C 65 73 73 20 74 68 61 6E 20 72 2E 00 00 +64 69 66 5F 6B 6D 61 63 5F 65 6E 64 3A 20 45 52 +52 4F 52 20 61 72 67 75 6D 65 6E 74 73 20 6D 61 +79 20 6E 6F 74 20 62 65 20 4E 55 4C 4C 2E 00 00 +64 69 66 5F 6B 6D 61 63 5F 65 6E 64 3A 20 45 52 +52 4F 52 20 68 61 72 64 77 61 72 65 20 6D 75 73 +74 20 62 65 20 64 6F 6E 65 20 73 71 75 65 65 7A +69 6E 67 2E 00 00 00 00 53 4F 43 5F 49 46 43 3A +20 43 68 65 63 6B 20 6D 62 6F 78 5F 73 74 61 74 +75 73 2E 6D 62 6F 78 5F 66 73 6D 5F 70 73 00 00 +53 4F 43 5F 49 46 43 3A 20 43 68 65 63 6B 20 6D +62 6F 78 5F 73 74 61 74 75 73 2E 6D 62 6F 78 5F +66 73 6D 5F 70 73 20 66 6F 75 6E 64 20 4D 42 4F +58 5F 45 58 45 43 55 54 45 5F 55 43 00 00 00 00 +53 4F 43 5F 49 46 43 3A 20 43 68 65 63 6B 20 6D +62 6F 78 5F 73 74 61 74 75 73 2E 6D 62 6F 78 5F +66 73 6D 5F 70 73 20 66 6F 75 6E 64 20 4D 42 4F +58 5F 49 44 4C 45 00 00 53 4F 43 5F 49 46 43 3A +20 43 68 65 63 6B 20 6D 62 6F 78 5F 73 74 61 74 +75 73 2E 6D 62 6F 78 5F 66 73 6D 5F 70 73 20 66 +6F 75 6E 64 20 4D 42 4F 58 5F 45 52 52 4F 52 2C +20 6D 61 69 6C 62 6F 78 20 66 6F 72 63 65 2D 75 +6E 6C 6F 63 6B 20 6E 65 65 64 65 64 00 00 00 00 +53 4F 43 5F 49 46 43 3A 20 42 65 67 69 6E 6E 69 +6E 67 20 6D 62 6F 78 20 66 77 20 66 6C 6F 77 00 +53 4F 43 5F 49 46 43 3A 20 43 70 20 74 6F 20 49 +43 43 4D 00 53 4F 43 5F 49 46 43 3A 20 43 70 20 +74 6F 20 44 43 43 4D 00 43 6F 70 79 69 6E 67 20 +63 6F 64 65 20 66 72 6F 6D 20 6D 61 69 6C 62 6F +78 20 74 6F 20 49 43 43 4D 00 00 00 46 61 69 6C +65 64 20 74 6F 20 61 63 71 75 69 72 65 20 6C 6F +63 6B 20 2D 20 6D 62 6F 78 20 73 61 6E 69 74 69 +7A 65 00 00 77 6F 6E 27 74 20 6F 76 65 72 72 69 +64 65 00 00 77 69 6C 6C 20 75 73 65 20 64 65 66 +61 75 6C 74 20 35 00 00 77 69 6C 6C 20 6F 76 65 +72 72 69 64 65 00 00 00 46 41 54 41 4C 3A 20 41 +58 49 20 44 4D 41 20 72 65 70 6F 72 74 73 20 65 +72 72 6F 72 20 73 74 61 74 75 73 20 66 6F 72 20 +78 66 65 72 00 00 00 00 41 58 49 20 44 4D 41 20 +72 65 70 6F 72 74 73 20 73 74 61 74 75 73 20 66 +6F 72 20 78 66 65 72 20 74 68 61 74 20 77 6F 75 +6C 64 20 72 65 71 75 69 72 65 20 44 4D 41 20 46 +6C 75 73 68 00 00 00 00 41 58 49 20 44 4D 41 20 +64 69 64 20 6E 6F 74 20 72 65 70 6F 72 74 20 65 +72 72 20 73 74 61 74 75 73 20 66 6F 72 20 78 66 +65 72 20 74 68 61 74 20 77 6F 75 6C 64 20 72 65 +71 75 69 72 65 20 44 4D 41 20 46 6C 75 73 68 00 +41 63 71 75 69 72 65 20 6D 61 69 6C 62 6F 78 20 +6C 6F 63 6B 20 66 61 69 6C 65 64 00 46 41 54 41 +4C 3A 20 41 58 49 20 44 4D 41 20 72 65 70 6F 72 +74 73 20 65 72 72 6F 72 20 73 74 61 74 75 73 20 +66 6F 72 20 4D 42 4F 58 2D 74 6F 2D 41 58 49 20 +78 66 65 72 00 00 00 00 46 57 3A 20 53 65 6E 64 +69 6E 67 20 4B 56 20 74 6F 20 41 58 49 20 77 69 +74 68 20 45 52 52 00 00 41 58 49 20 44 4D 41 20 +72 65 70 6F 72 74 73 20 65 72 72 20 73 74 61 74 +75 73 20 66 6F 72 20 65 72 72 20 69 6E 6A 65 63 +74 69 6F 6E 20 78 66 65 72 00 00 00 46 41 54 41 +4C 3A 20 41 58 49 20 44 4D 41 20 72 65 70 6F 72 +74 73 20 73 75 63 63 65 73 73 20 73 74 61 74 75 +73 20 66 6F 72 20 65 72 72 20 69 6E 6A 65 63 74 +69 6F 6E 20 78 66 65 72 21 00 00 00 46 57 3A 20 +53 65 6E 64 69 6E 67 20 4B 56 20 74 6F 20 41 58 +49 00 00 00 46 57 3A 20 41 72 6D 20 65 72 72 20 +63 6F 6D 6D 61 6E 64 00 45 6E 20 69 6E 74 20 74 +6D 72 30 2C 20 68 6C 74 20 63 6F 72 65 00 00 00 +44 69 73 61 62 6C 69 6E 67 20 62 6F 74 68 20 74 +69 6D 65 72 73 20 69 6E 20 69 6E 64 65 70 65 6E +64 65 6E 74 20 6D 6F 64 65 00 00 00 45 6E 61 62 +6C 69 6E 67 20 6F 6E 6C 79 20 74 69 6D 65 72 32 +20 69 6E 20 69 6E 64 65 70 65 6E 64 65 6E 74 20 +6D 6F 64 65 00 00 00 00 45 6E 61 62 6C 69 6E 67 +20 62 6F 74 68 20 74 69 6D 65 72 73 20 69 6E 20 +69 6E 64 65 70 65 6E 64 65 6E 74 20 6D 6F 64 65 +00 00 00 00 48 0B 02 50 48 0B 02 50 +@00014C8C +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +@00016C8C +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 diff --git a/designs/Caliptra/tests/trng/dccm.hex b/designs/Caliptra/tests/trng/dccm.hex new file mode 100644 index 0000000..ba85215 --- /dev/null +++ b/designs/Caliptra/tests/trng/dccm.hex @@ -0,0 +1,7365 @@ +@00023450 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +B0 1D 00 00 C0 1C 00 00 10 2B 00 00 D0 1B 00 00 +D2 29 00 00 E0 1A 00 00 94 28 00 00 F0 19 00 00 +00 19 00 00 10 18 00 00 56 27 00 00 20 17 00 00 +18 26 00 00 30 20 00 00 30 20 00 00 30 20 00 00 +30 20 00 00 30 16 00 00 40 15 00 00 F6 23 00 00 +D4 21 00 00 50 14 00 00 96 20 00 00 60 13 00 00 +70 12 00 00 2A 1F 00 00 24 1E 00 00 30 20 00 00 +30 20 00 00 30 20 00 00 30 20 00 00 30 20 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +EF BE AD DE +@00030004 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +@00032004 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +@00034004 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +@00036004 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +@00038004 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +@0003A004 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +@0003C004 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +@0003E004 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 diff --git a/designs/Caliptra/tests/trng/iccm.hex b/designs/Caliptra/tests/trng/iccm.hex new file mode 100644 index 0000000..e69de29 diff --git a/designs/Caliptra/tests/trng/mailbox.hex b/designs/Caliptra/tests/trng/mailbox.hex new file mode 100644 index 0000000..e69de29 diff --git a/designs/Caliptra/tests/trng/program.hex b/designs/Caliptra/tests/trng/program.hex new file mode 100644 index 0000000..a532150 --- /dev/null +++ b/designs/Caliptra/tests/trng/program.hex @@ -0,0 +1,6146 @@ +@00000000 +73 10 20 B0 73 10 20 B8 B7 A2 AA AA 93 82 92 0A +73 90 02 7C 91 42 0F 10 00 00 73 90 92 7F 0F 10 +00 00 97 02 00 00 93 82 E2 14 73 90 52 30 97 22 +01 00 93 82 62 AB 17 53 01 00 13 03 E3 E3 97 03 +02 50 93 83 23 FC 63 FA 62 00 03 AE 02 00 23 A0 +C3 01 91 02 91 03 E3 EA 62 FE 97 52 01 00 93 82 +A2 E1 17 53 01 00 13 03 23 ED 97 33 02 50 93 83 +63 32 63 FA 62 00 03 AE 02 00 23 A0 C3 01 91 02 +91 03 E3 EA 62 FE 17 41 03 50 13 01 A1 F8 EF 10 +A0 04 B7 02 03 30 93 82 C2 0C 13 0F F0 0F 23 A0 +E2 01 E3 08 00 FE 01 00 01 00 01 00 01 00 01 00 +01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00 +01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00 +01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00 +01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00 +01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00 +01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00 +01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00 +01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00 +01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00 +01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00 +01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00 +01 00 01 00 01 00 01 00 01 00 01 00 01 00 00 00 +F3 22 20 34 73 23 10 34 F3 23 30 34 37 0E 03 30 +13 0E CE 0C 97 0E 02 50 93 8E CE E7 83 82 0E 00 +23 20 5E 00 85 0E E3 9B 02 FE 05 4F 23 20 EE 01 +C1 BF 00 00 1C 41 63 89 F5 00 37 07 02 50 03 27 +C7 07 09 E7 05 45 82 80 01 45 82 80 05 65 41 11 +2E 86 13 05 85 06 BE 85 06 C6 EF 30 C0 76 B2 40 +05 45 41 01 82 80 B7 07 02 50 03 A7 C7 07 41 11 +22 C4 26 C2 06 C6 89 47 2A 84 AE 84 63 EA E7 00 +1C 40 E3 9F F4 FE B2 40 22 44 92 44 41 01 82 80 +2E 86 AA 85 05 65 13 05 85 07 EF 30 C0 72 CD B7 +B7 07 03 30 83 A7 07 0E 85 8B 99 CF B7 07 02 50 +03 A7 C7 07 89 47 63 E3 E7 00 82 80 37 15 02 50 +13 05 85 A4 6F 30 20 6E 37 15 02 50 41 11 13 05 +C5 A7 06 C6 EF 30 20 6D 13 05 F0 0F EF 30 A0 6A +01 A0 41 11 26 C2 B7 04 02 50 83 A7 C4 07 22 C4 +06 C6 4A C0 09 44 63 62 F4 04 B7 A7 64 02 37 37 +00 20 93 87 97 99 5C D3 99 47 1C D3 37 27 00 20 +93 07 60 66 5C CB 85 67 93 87 17 90 1C CF B7 36 +00 20 37 07 02 00 83 A7 06 0D E3 9E E7 FE B2 40 +22 44 92 44 02 49 41 01 82 80 37 15 02 50 13 05 +45 AB EF 30 40 66 B7 A7 64 02 03 A7 C4 07 37 39 +00 20 93 87 97 99 23 22 F9 02 99 47 23 20 F9 02 +E3 76 E4 FA 37 15 02 50 13 05 C5 AC EF 30 A0 63 +37 27 00 20 93 07 60 66 83 A6 C4 07 5C CB 85 67 +93 87 17 90 1C CF E3 7C D4 F8 37 15 02 50 13 05 +C5 AD EF 30 40 61 83 A7 C4 07 E3 72 F4 F8 05 65 +37 06 02 00 93 05 09 0D 13 05 85 07 EF 30 A0 61 +BD B7 41 11 26 C2 B7 04 02 50 83 A7 C4 07 22 C4 +06 C6 4A C0 09 44 63 67 F4 08 85 67 37 27 00 20 +8D 07 1C CF 37 27 00 20 85 46 1C 5B E3 9F D7 FE +4C 5B 37 36 EB 15 13 06 46 A4 01 44 63 86 C5 00 +83 A7 C4 07 E1 E7 05 44 B7 27 00 20 CC 5B 37 56 +08 31 13 06 D6 1D 63 86 C5 00 83 A7 C4 07 C5 E3 +05 04 B7 27 00 20 CC 5B 37 66 13 BA 13 06 B6 5A +63 86 C5 00 83 A7 C4 07 CD E3 05 04 B7 27 00 20 +CC 5B 37 26 73 4C 13 06 46 2F 63 86 C5 00 83 A7 +C4 07 D9 EB 05 04 B2 40 22 85 22 44 92 44 02 49 +41 01 82 80 37 15 02 50 13 05 C5 AF EF 30 A0 54 +83 A7 C4 07 E3 73 F4 F6 37 15 02 50 13 05 85 B1 +EF 30 60 53 03 A7 C4 07 85 67 37 29 00 20 8D 07 +23 2C F9 00 E3 78 E4 F4 37 15 02 50 13 05 C5 B2 +EF 30 60 51 83 A7 C4 07 E3 7E F4 F2 05 65 05 46 +93 05 09 03 13 05 85 07 EF 30 E0 51 25 B7 05 65 +13 05 85 06 EF 30 20 51 05 04 A1 BF 05 65 13 05 +85 06 EF 30 40 50 05 44 05 BF 05 65 13 05 85 06 +EF 30 60 4F 05 04 99 BF 05 65 13 05 85 06 EF 30 +80 4E 05 04 8D B7 01 11 26 CA B7 04 02 50 83 A7 +C4 07 22 CC 06 CE 4A C8 4E C6 09 44 E3 69 F4 34 +05 67 B7 26 00 20 13 07 57 90 98 CE 37 24 00 20 +99 46 58 54 13 09 C4 02 E3 1D D7 FE 89 49 E3 E5 +F9 28 13 07 10 6C 18 CC 37 C7 BE 73 41 07 18 CC +37 47 62 92 13 07 C7 74 18 CC 37 17 A3 16 13 07 +67 F7 18 CC 37 57 1B 53 13 07 E7 1D 18 CC 37 97 +E4 2E 13 07 57 4E 18 CC 37 A7 EC DF 13 07 37 DB +18 CC 37 87 7A CB 13 07 D7 79 18 CC 37 47 00 56 +13 07 C7 19 18 CC 37 B7 79 CA 13 07 07 0B 18 CC +37 47 A3 DD 13 07 C7 B5 18 CC 37 67 68 A4 13 07 +E7 49 18 CC 37 77 5D DF 13 07 A7 3F 18 CC 37 24 +00 20 99 46 58 54 E3 1F D7 FE 09 49 E3 6A F9 18 +15 67 13 07 37 90 18 CC B7 26 00 20 05 46 98 5A +E3 1F C7 FE CC 5A 37 D6 8F 37 13 06 E6 A1 63 8E +C5 02 E3 98 07 2C D0 5A 37 47 76 CF 13 07 87 D0 +09 44 63 14 E6 10 D0 5A 37 77 16 17 13 07 07 E9 +09 44 63 16 E6 7E C0 5A 37 57 16 0B 13 07 87 30 +19 8C 33 34 80 00 05 04 BD A8 01 44 37 27 00 20 +4C 5B 37 46 76 CF 13 06 86 D0 63 9E C5 0A 37 27 +00 20 4C 5B 37 76 16 17 13 06 06 E9 63 8C C5 00 +05 04 63 86 07 7A 05 65 13 05 85 06 EF 30 A0 38 +83 A7 C4 07 37 27 00 20 4C 5B 37 56 16 0B 13 06 +86 30 63 8B C5 00 05 04 9D C7 05 65 13 05 85 06 +EF 30 60 36 83 A7 C4 07 09 47 63 7E F7 00 B7 25 +00 20 05 65 05 46 93 85 05 03 13 05 85 07 EF 30 +80 34 83 A7 C4 07 B7 26 00 20 05 46 98 5A E3 1F +C7 FE CC 5A 37 C6 9F 35 13 06 E6 E3 63 81 C5 08 +13 09 14 00 AD E7 D0 5A 37 27 9B A6 13 07 17 BF +63 15 E6 74 D0 5A 37 77 11 14 13 07 17 21 E3 1E +E6 1E D4 5A 37 17 1A C0 13 07 97 83 09 04 63 9F +E6 0C 4A 84 E1 A8 05 04 89 CB 05 65 13 05 85 06 +EF 30 60 2E 83 A7 C4 07 1D BF 37 27 00 20 54 5B +B7 77 16 17 93 87 07 E9 63 92 F6 6E 58 5B B7 57 +16 0B 93 87 87 30 E3 1C F7 1A 81 47 AD BF 05 65 +13 05 85 06 EF 30 20 2B 83 A7 C4 07 4A 84 37 27 +00 20 4C 5B 37 26 9B A6 13 06 16 BF 63 8C C5 00 +05 04 63 85 07 6C 05 65 13 05 85 06 EF 30 A0 28 +83 A7 C4 07 37 27 00 20 4C 5B 37 76 11 14 13 06 +16 21 63 8C C5 00 05 04 63 85 07 6C 05 65 13 05 +85 06 EF 30 40 26 83 A7 C4 07 37 27 00 20 4C 5B +37 16 1A C0 13 06 96 83 63 8B C5 00 05 04 9D C7 +05 65 13 05 85 06 EF 30 00 24 83 A7 C4 07 09 47 +63 7E F7 00 B7 25 00 20 05 65 05 46 93 85 05 03 +13 05 85 07 EF 30 20 22 83 A7 C4 07 B7 26 00 20 +05 46 98 5A E3 1F C7 FE CC 5A 37 E6 D7 58 13 06 +D6 45 63 85 C5 04 13 09 14 00 8D EB D0 5A 37 17 +E0 C5 13 07 87 EB 63 13 E6 66 D0 5A 37 B7 7A CE +13 07 F7 38 E3 11 E6 0E D4 5A 37 E7 48 6E 13 07 +67 54 09 04 63 93 E6 0A 4A 84 45 A0 05 65 13 05 +85 06 EF 30 40 1C 83 A7 C4 07 4A 84 37 27 00 20 +4C 5B 37 16 E0 C5 13 06 86 EB 63 8C C5 00 05 04 +63 8F 07 60 05 65 13 05 85 06 EF 30 C0 19 83 A7 +C4 07 37 27 00 20 4C 5B 37 B6 7A CE 13 06 F6 38 +63 8C C5 00 05 04 63 8F 07 60 05 65 13 05 85 06 +EF 30 60 17 83 A7 C4 07 37 27 00 20 4C 5B 37 E6 +48 6E 13 06 66 54 63 8B C5 00 05 04 9D C7 05 65 +13 05 85 06 EF 30 20 15 83 A7 C4 07 09 47 63 7E +F7 00 B7 25 00 20 05 65 05 46 93 85 05 03 13 05 +85 07 EF 30 40 13 83 A7 C4 07 B7 26 00 20 05 46 +98 5A E3 1F C7 FE CC 5A 37 96 DE 49 13 06 96 3F +63 84 C5 04 13 09 14 00 85 EB D0 5A 37 67 A6 88 +13 07 77 EC 63 1D E6 5A D0 5A 37 57 8A C5 13 07 +E7 53 63 12 E6 7E D4 5A 37 17 6E 5D 49 07 09 04 +63 92 E6 0A 4A 84 79 A8 05 65 13 05 85 06 EF 30 +80 0D 83 A7 C4 07 4A 84 37 27 00 20 4C 5B 37 66 +A6 88 13 06 76 EC 63 8C C5 00 05 04 63 8A 07 56 +05 65 13 05 85 06 EF 30 00 0B 83 A7 C4 07 37 27 +00 20 4C 5B 37 56 8A C5 13 06 E6 53 63 8C C5 00 +05 04 63 89 07 56 05 65 13 05 85 06 EF 30 A0 08 +83 A7 C4 07 37 27 00 20 4C 5B 37 16 6E 5D 49 06 +63 8B C5 00 05 04 9D C7 05 65 13 05 85 06 EF 30 +80 06 83 A7 C4 07 09 47 63 7E F7 00 B7 25 00 20 +05 65 19 46 93 85 C5 02 13 05 85 07 EF 30 A0 04 +83 A7 C4 07 37 29 00 20 99 46 03 27 C9 02 E3 1E +D7 FE 89 49 63 E0 F9 5E 15 67 13 07 37 90 23 2C +E9 00 B7 26 00 20 05 46 98 5A E3 1F C7 FE CC 5A +37 C6 8B E4 13 06 B6 8C 63 85 C5 04 13 09 14 00 +8D EB D0 5A 37 D7 12 10 13 07 C7 84 63 18 E6 4E +D0 5A 37 A7 F8 5A 13 07 17 7F 63 15 E6 70 D4 5A +37 87 C0 D1 13 07 97 CD 09 04 63 93 E6 0A 4A 84 +45 A0 05 65 13 05 85 06 EF 20 F0 7C 83 A7 C4 07 +4A 84 37 27 00 20 4C 5B 37 D6 12 10 13 06 C6 84 +63 8C C5 00 05 04 63 84 07 4A 05 65 13 05 85 06 +EF 20 70 7A 83 A7 C4 07 37 27 00 20 4C 5B 37 A6 +F8 5A 13 06 16 7F 63 8C C5 00 05 04 63 84 07 4A +05 65 13 05 85 06 EF 20 10 78 83 A7 C4 07 37 27 +00 20 4C 5B 37 86 C0 D1 13 06 96 CD 63 8B C5 00 +05 04 9D C7 05 65 13 05 85 06 EF 20 D0 75 83 A7 +C4 07 09 47 63 7E F7 00 B7 25 00 20 05 65 05 46 +93 85 05 03 13 05 85 07 EF 20 F0 73 83 A7 C4 07 +B7 26 00 20 05 46 98 5A E3 1F C7 FE CC 5A 37 B6 +82 DF 13 06 26 B2 63 85 C5 04 13 09 14 00 8D EB +D0 5A 37 67 1C 77 13 07 B7 19 63 12 E6 44 D0 5A +37 D7 0F D4 13 07 17 CB 63 1C E6 60 D4 5A 37 A7 +18 87 13 07 97 E9 09 04 63 93 E6 0A 4A 84 45 A0 +05 65 13 05 85 06 EF 20 10 6E 83 A7 C4 07 4A 84 +37 27 00 20 4C 5B 37 66 1C 77 13 06 B6 19 63 8C +C5 00 05 04 63 8E 07 3E 05 65 13 05 85 06 EF 20 +90 6B 83 A7 C4 07 37 27 00 20 4C 5B 37 D6 0F D4 +13 06 16 CB 63 8C C5 00 05 04 63 8E 07 3E 05 65 +13 05 85 06 EF 20 30 69 83 A7 C4 07 37 27 00 20 +4C 5B 37 A6 18 87 13 06 96 E9 63 8B C5 00 05 04 +9D C7 05 65 13 05 85 06 EF 20 F0 66 83 A7 C4 07 +09 47 63 7E F7 00 B7 25 00 20 05 65 05 46 93 85 +05 03 13 05 85 07 EF 20 10 65 83 A7 C4 07 B7 26 +00 20 05 46 98 5A E3 1F C7 FE CC 5A 37 96 04 51 +13 06 36 4B 63 85 C5 04 13 09 14 00 8D EB D0 5A +37 B7 F7 64 13 07 C7 C0 63 12 E6 20 D0 5A 37 F7 +81 25 13 07 17 39 09 04 63 15 E6 20 CC 5A 37 E7 +B1 80 13 07 F7 C2 4A 84 63 9A E5 06 65 A0 05 65 +13 05 85 06 EF 20 30 5F 83 A7 C4 07 4A 84 37 27 +00 20 4C 5B 37 B6 F7 64 13 06 C6 C0 63 8C C5 00 +05 04 63 8E 07 1A 05 65 13 05 85 06 EF 20 B0 5C +83 A7 C4 07 37 27 00 20 4C 5B 37 F6 81 25 13 06 +16 39 63 8C C5 00 05 04 63 85 07 1A 05 65 13 05 +85 06 EF 20 50 5A 83 A7 C4 07 37 27 00 20 4C 5B +37 E7 B1 80 13 07 F7 C2 63 8F E5 00 05 04 9D CB +37 E6 B1 80 05 65 13 06 F6 C2 13 05 85 06 EF 20 +90 57 83 A7 C4 07 09 47 63 7E F7 00 B7 25 00 20 +05 65 05 46 93 85 05 03 13 05 85 07 EF 20 B0 55 +83 A7 C4 07 B7 26 00 20 05 46 98 5A E3 1F C7 FE +CC 5A 37 06 3E 79 13 06 56 1C 63 85 C5 04 13 09 +14 00 8D EB D0 5A 37 07 B1 87 13 07 E7 7A 63 10 +E6 0E D0 5A 37 57 17 DB 13 07 C7 14 09 04 63 13 +E6 0E CC 5A 37 47 3C A4 13 07 77 1B 4A 84 63 98 +E5 06 45 A0 05 65 13 05 85 06 EF 20 D0 4F 83 A7 +C4 07 4A 84 37 27 00 20 4C 5B 37 06 B1 87 13 06 +E6 7A 63 8B C5 00 05 04 C1 CF 05 65 13 05 85 06 +EF 20 70 4D 83 A7 C4 07 37 27 00 20 4C 5B 37 56 +17 DB 13 06 C6 14 63 8B C5 00 05 04 C1 C7 05 65 +13 05 85 06 EF 20 30 4B 83 A7 C4 07 37 27 00 20 +4C 5B 37 47 3C A4 13 07 77 1B 63 8F E5 00 05 04 +8D CB 37 46 3C A4 05 65 13 06 76 1B 13 05 85 06 +EF 20 70 48 83 A7 C4 07 09 47 63 7C F7 00 B7 25 +00 20 05 65 19 46 93 85 C5 02 13 05 85 07 EF 20 +90 46 B7 26 00 20 19 47 DC 56 E3 9F E7 FE F2 40 +22 85 62 44 D2 44 42 49 B2 49 05 61 82 80 09 04 +37 27 00 20 54 5B B7 57 17 DB 93 87 C7 14 63 88 +F6 30 05 04 B7 27 00 20 DC 5B 37 47 3C A4 13 07 +77 1B 99 8F B3 37 F0 00 3E 94 65 BF 09 04 37 27 +00 20 54 5B B7 F7 81 25 93 87 17 39 63 8F F6 2C +05 04 B7 27 00 20 D8 5B B7 E7 B1 80 93 87 F7 C2 +1D 8F 33 37 E0 00 81 47 3A 94 69 BD 05 04 B7 27 +00 20 D8 5B B7 57 16 0B 93 87 87 30 1D 8F 33 37 +E0 00 81 47 3A 94 6F F0 1F 89 09 04 37 27 00 20 +54 5B B7 77 11 14 93 87 17 21 63 9B F6 00 58 5B +B7 17 1A C0 93 87 97 83 63 10 F7 2C 81 47 79 B2 +05 04 B7 27 00 20 D8 5B B7 17 1A C0 93 87 97 83 +1D 8F 33 37 E0 00 81 47 3A 94 8D BA 09 04 37 27 +00 20 54 5B B7 B7 7A CE 93 87 F7 38 63 9B F6 00 +58 5B B7 E7 48 6E 93 87 67 54 63 18 F7 26 81 47 +2D BC 05 04 B7 27 00 20 D8 5B B7 E7 48 6E 93 87 +67 54 1D 8F 33 37 E0 00 81 47 3A 94 39 BC 09 04 +37 27 00 20 54 5B B7 57 8A C5 93 87 E7 53 63 9A +F6 00 58 5B B7 17 6E 5D C9 07 63 1A F7 24 81 47 +D5 B4 05 04 B7 27 00 20 D8 5B B7 17 6E 5D C9 07 +1D 8F 33 37 E0 00 81 47 3A 94 E9 B4 09 04 37 27 +00 20 54 5B B7 A7 F8 5A 93 87 17 7F 63 9B F6 00 +58 5B B7 87 C0 D1 93 87 97 CD 63 1C F7 1E 81 47 +45 BE 05 04 B7 27 00 20 D8 5B B7 87 C0 D1 93 87 +97 CD 1D 8F 33 37 E0 00 81 47 3A 94 51 BE 09 04 +37 27 00 20 54 5B B7 D7 0F D4 93 87 17 CB 63 9B +F6 00 58 5B B7 A7 18 87 93 87 97 E9 63 16 F7 1C +81 47 B1 B9 05 04 B7 27 00 20 D8 5B B7 A7 18 87 +93 87 97 E9 1D 8F 33 37 E0 00 81 47 3A 94 81 B1 +37 15 02 50 13 05 85 BA EF 20 F0 25 83 A7 C4 07 +15 67 13 07 37 90 18 CC 63 70 F9 E6 05 65 05 46 +93 05 04 03 13 05 85 07 EF 20 F0 25 83 A7 C4 07 +6F F0 8F E4 37 15 02 50 13 05 85 BA EF 20 B0 22 +83 A7 C4 07 15 67 13 07 37 90 23 2C E9 00 E3 FA +F9 A0 05 65 05 46 93 05 09 03 13 05 85 07 EF 20 +90 22 83 A7 C4 07 F5 BA 37 15 02 50 13 05 05 B8 +EF 20 70 1F 13 07 10 6C 83 A7 C4 07 18 CC 37 C7 +BE 73 41 07 18 CC 37 47 62 92 13 07 C7 74 18 CC +37 17 A3 16 13 07 67 F7 18 CC 37 57 1B 53 13 07 +E7 1D 18 CC 37 97 E4 2E 13 07 57 4E 18 CC 37 A7 +EC DF 13 07 37 DB 18 CC 37 87 7A CB 13 07 D7 79 +18 CC 37 47 00 56 13 07 C7 19 18 CC 37 B7 79 CA +13 07 07 0B 18 CC 37 47 A3 DD 13 07 C7 B5 18 CC +37 67 68 A4 13 07 E7 49 18 CC 37 77 5D DF 13 07 +A7 3F 18 CC 63 F5 F9 D6 05 65 19 46 CA 85 13 05 +85 07 EF 20 50 18 83 A7 C4 07 6F F0 4F D5 37 15 +02 50 13 05 85 B5 EF 20 10 15 83 A7 C4 07 63 71 +F4 CA 37 15 02 50 13 05 C5 B6 EF 20 D0 13 83 A7 +C4 07 05 67 B7 25 00 20 13 07 57 90 98 CD 63 77 +F4 C8 05 65 19 46 93 85 C5 02 13 05 85 07 EF 20 +90 13 83 A7 C4 07 6F F0 6F C7 58 5B 35 B3 5C 5B +ED B9 05 65 13 05 85 06 EF 20 F0 11 83 A7 C4 07 +05 44 6F F0 AF D5 09 04 F5 B3 09 04 9D B3 05 04 +81 47 6F F0 4F DC 09 04 71 BB 05 04 81 47 6F F0 +CF FC 05 04 81 47 6D BA 05 04 81 47 6F F0 0F ED +09 04 91 B5 09 04 FD BB 05 04 81 47 49 BC 05 04 +81 47 6F F0 3F 89 01 00 47 6F 74 3A 25 78 20 57 +61 6E 74 3A 20 25 78 00 20 20 2D 20 50 6F 6C 6C +69 6E 67 20 61 64 64 72 3D 25 78 20 75 6E 74 69 +6C 20 69 74 20 72 65 61 64 73 20 62 61 63 6B 20 +25 78 2E 2E 2E 0A 00 00 45 72 72 6F 72 3A 20 25 +64 0A 00 00 49 74 65 72 61 74 69 6F 6E 20 25 30 +75 20 6F 66 20 25 30 75 0A 00 00 00 45 72 72 6F +72 3A 20 25 64 0A 00 00 01 11 4A C8 37 09 02 50 +83 27 C9 07 22 CC 06 CE 26 CA 4E C6 52 C4 56 C2 +5A C0 09 44 63 6F F4 0A EF F0 8F 91 EF F0 6F 95 +EF F0 2F A2 2A 84 63 5E A0 08 83 27 C9 07 F9 EB +B7 09 03 50 93 89 09 00 83 A7 09 00 BD C7 05 65 +13 05 85 06 81 44 09 4A 13 0B C5 04 93 0A 45 06 +31 A8 EF F0 4F B2 2A 94 85 04 63 55 80 00 83 27 +C9 07 85 E3 83 A7 09 00 63 F5 F4 02 83 27 C9 07 +E3 71 FA FE 03 A6 09 00 A6 85 5A 85 EF 20 A0 7D +C9 BF A2 85 56 85 EF 20 00 7D 83 A7 09 00 E3 EF +F4 FC 63 4C 80 00 F2 40 62 44 D2 44 42 49 B2 49 +22 4A 92 4A 02 4B 05 61 82 80 62 44 F2 40 D2 44 +42 49 B2 49 22 4A 92 4A 02 4B 05 45 05 61 6F 20 +80 75 B7 09 03 50 93 89 09 00 83 A7 09 00 A5 FB +D9 B7 B7 24 02 50 13 85 44 5B EF 20 C0 75 83 27 +C9 07 E3 7B F4 F2 37 15 02 50 13 05 05 BC EF 20 +80 74 83 27 C9 07 E3 71 F4 F2 13 85 44 5B EF 20 +80 73 19 BF AA 85 05 65 13 05 85 0A EF 20 A0 74 +05 B7 00 00 6F 10 90 58 6F 00 90 63 00 00 00 00 +6F 00 10 63 00 00 00 00 6F 00 90 62 00 00 00 00 +6F 10 90 47 00 00 00 00 6F 00 90 61 00 00 00 00 +6F 00 10 61 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 6F 10 50 49 6F 10 90 49 +5D 71 2A DA 13 05 B0 0F 22 DE 36 D4 3E D0 86 C6 +96 C4 9A C2 9E C0 26 DC 2E D8 32 D6 3A D2 42 CE +46 CC 4A CA 4E C8 72 C6 76 C4 7A C2 7E C0 37 04 +02 50 EF 20 40 65 83 26 C4 07 8D 47 63 E9 D7 08 +F3 27 B0 BC F3 29 C0 BC 73 29 10 34 F3 24 00 30 +73 24 40 30 73 90 C7 BC A1 47 73 A0 07 30 37 37 +02 50 83 27 07 39 0D 46 85 07 23 28 F7 38 63 69 +D6 06 A1 47 73 B0 07 30 73 90 C9 BC 73 10 19 34 +89 67 93 87 07 88 FD 8C 73 A0 04 30 85 67 93 87 +87 88 7D 8C 73 20 44 30 13 05 C0 0F EF 20 A0 5E +72 54 B6 40 A6 42 16 43 86 43 E2 54 52 55 C2 55 +32 56 A2 56 12 57 82 57 72 48 E2 48 52 49 C2 49 +32 4E A2 4E 12 4F 82 4F 61 61 73 00 20 30 37 15 +02 50 13 05 45 BD EF 20 00 5D 83 26 C4 07 8D B7 +83 25 07 39 0D 65 13 05 C5 07 EF 20 C0 5D 51 B7 +5D 71 2A DA 13 05 B0 0F 22 DE 36 D4 3E D0 86 C6 +96 C4 9A C2 9E C0 26 DC 2E D8 32 D6 3A D2 42 CE +46 CC 4A CA 4E C8 72 C6 76 C4 7A C2 7E C0 37 04 +02 50 EF 20 40 56 83 26 C4 07 8D 47 63 E9 D7 08 +F3 27 B0 BC F3 29 C0 BC 73 29 10 34 F3 24 00 30 +73 24 40 30 73 90 C7 BC A1 47 73 A0 07 30 37 37 +02 50 83 27 07 39 0D 46 85 07 23 28 F7 38 63 69 +D6 06 A1 47 73 B0 07 30 73 90 C9 BC 73 10 19 34 +89 67 93 87 07 88 FD 8C 73 A0 04 30 85 67 93 87 +87 88 7D 8C 73 20 44 30 13 05 C0 0F EF 20 A0 4F +72 54 B6 40 A6 42 16 43 86 43 E2 54 52 55 C2 55 +32 56 A2 56 12 57 82 57 72 48 E2 48 52 49 C2 49 +32 4E A2 4E 12 4F 82 4F 61 61 73 00 20 30 37 15 +02 50 13 05 45 BE EF 20 00 4E 83 26 C4 07 8D B7 +83 25 07 39 0D 65 13 05 05 09 EF 20 C0 4E 51 B7 +5D 71 2A DA 13 05 B0 0F 22 DE 36 D4 3E D0 86 C6 +96 C4 9A C2 9E C0 26 DC 2E D8 32 D6 3A D2 42 CE +46 CC 4A CA 4E C8 72 C6 76 C4 7A C2 7E C0 37 04 +02 50 EF 20 40 47 83 26 C4 07 8D 47 63 E9 D7 08 +F3 27 B0 BC F3 29 C0 BC 73 29 10 34 F3 24 00 30 +73 24 40 30 73 90 C7 BC A1 47 73 A0 07 30 37 37 +02 50 83 27 07 39 0D 46 85 07 23 28 F7 38 63 69 +D6 06 A1 47 73 B0 07 30 73 90 C9 BC 73 10 19 34 +89 67 93 87 07 88 FD 8C 73 A0 04 30 85 67 93 87 +87 88 7D 8C 73 20 44 30 13 05 C0 0F EF 20 A0 40 +72 54 B6 40 A6 42 16 43 86 43 E2 54 52 55 C2 55 +32 56 A2 56 12 57 82 57 72 48 E2 48 52 49 C2 49 +32 4E A2 4E 12 4F 82 4F 61 61 73 00 20 30 37 15 +02 50 13 05 45 BF EF 20 00 3F 83 26 C4 07 8D B7 +83 25 07 39 0D 65 13 05 45 0A EF 20 C0 3F 51 B7 +5D 71 2A DA 13 05 B0 0F 22 DE 36 D4 3E D0 86 C6 +96 C4 9A C2 9E C0 26 DC 2E D8 32 D6 3A D2 42 CE +46 CC 4A CA 4E C8 72 C6 76 C4 7A C2 7E C0 37 04 +02 50 EF 20 40 38 83 26 C4 07 8D 47 63 E9 D7 08 +F3 27 B0 BC F3 29 C0 BC 73 29 10 34 F3 24 00 30 +73 24 40 30 73 90 C7 BC A1 47 73 A0 07 30 37 37 +02 50 83 27 07 39 0D 46 85 07 23 28 F7 38 63 69 +D6 06 A1 47 73 B0 07 30 73 90 C9 BC 73 10 19 34 +89 67 93 87 07 88 FD 8C 73 A0 04 30 85 67 93 87 +87 88 7D 8C 73 20 44 30 13 05 C0 0F EF 20 A0 31 +72 54 B6 40 A6 42 16 43 86 43 E2 54 52 55 C2 55 +32 56 A2 56 12 57 82 57 72 48 E2 48 52 49 C2 49 +32 4E A2 4E 12 4F 82 4F 61 61 73 00 20 30 37 15 +02 50 13 05 85 C0 EF 20 00 30 83 26 C4 07 8D B7 +83 25 07 39 0D 65 13 05 05 0C EF 20 C0 30 51 B7 +5D 71 2A DA 13 05 B0 0F 22 DE 36 D4 3E D0 86 C6 +96 C4 9A C2 9E C0 26 DC 2E D8 32 D6 3A D2 42 CE +46 CC 4A CA 4E C8 72 C6 76 C4 7A C2 7E C0 37 04 +02 50 EF 20 40 29 83 26 C4 07 8D 47 63 E9 D7 08 +F3 27 B0 BC F3 29 C0 BC 73 29 10 34 F3 24 00 30 +73 24 40 30 73 90 C7 BC A1 47 73 A0 07 30 37 37 +02 50 83 27 07 39 0D 46 85 07 23 28 F7 38 63 69 +D6 06 A1 47 73 B0 07 30 73 90 C9 BC 73 10 19 34 +89 67 93 87 07 88 FD 8C 73 A0 04 30 85 67 93 87 +87 88 7D 8C 73 20 44 30 13 05 C0 0F EF 20 A0 22 +72 54 B6 40 A6 42 16 43 86 43 E2 54 52 55 C2 55 +32 56 A2 56 12 57 82 57 72 48 E2 48 52 49 C2 49 +32 4E A2 4E 12 4F 82 4F 61 61 73 00 20 30 37 15 +02 50 13 05 85 C1 EF 20 00 21 83 26 C4 07 8D B7 +83 25 07 39 0D 65 13 05 45 0D EF 20 C0 21 51 B7 +5D 71 2A DA 13 05 B0 0F 22 DE 36 D4 3E D0 86 C6 +96 C4 9A C2 9E C0 26 DC 2E D8 32 D6 3A D2 42 CE +46 CC 4A CA 4E C8 72 C6 76 C4 7A C2 7E C0 37 04 +02 50 EF 20 40 1A 83 26 C4 07 8D 47 63 E9 D7 08 +F3 27 B0 BC F3 29 C0 BC 73 29 10 34 F3 24 00 30 +73 24 40 30 73 90 C7 BC A1 47 73 A0 07 30 37 37 +02 50 83 27 07 39 0D 46 85 07 23 28 F7 38 63 69 +D6 06 A1 47 73 B0 07 30 73 90 C9 BC 73 10 19 34 +89 67 93 87 07 88 FD 8C 73 A0 04 30 85 67 93 87 +87 88 7D 8C 73 20 44 30 13 05 C0 0F EF 20 A0 13 +72 54 B6 40 A6 42 16 43 86 43 E2 54 52 55 C2 55 +32 56 A2 56 12 57 82 57 72 48 E2 48 52 49 C2 49 +32 4E A2 4E 12 4F 82 4F 61 61 73 00 20 30 37 15 +02 50 13 05 85 C2 EF 20 00 12 83 26 C4 07 8D B7 +83 25 07 39 0D 65 13 05 85 0E EF 20 C0 12 51 B7 +5D 71 2A DA 13 05 B0 0F 22 DE 36 D4 3E D0 86 C6 +96 C4 9A C2 9E C0 26 DC 2E D8 32 D6 3A D2 42 CE +46 CC 4A CA 4E C8 72 C6 76 C4 7A C2 7E C0 37 04 +02 50 EF 20 40 0B 83 26 C4 07 8D 47 63 E9 D7 08 +F3 27 B0 BC F3 29 C0 BC 73 29 10 34 F3 24 00 30 +73 24 40 30 73 90 C7 BC A1 47 73 A0 07 30 37 37 +02 50 83 27 07 39 0D 46 85 07 23 28 F7 38 63 69 +D6 06 A1 47 73 B0 07 30 73 90 C9 BC 73 10 19 34 +89 67 93 87 07 88 FD 8C 73 A0 04 30 85 67 93 87 +87 88 7D 8C 73 20 44 30 13 05 C0 0F EF 20 A0 04 +72 54 B6 40 A6 42 16 43 86 43 E2 54 52 55 C2 55 +32 56 A2 56 12 57 82 57 72 48 E2 48 52 49 C2 49 +32 4E A2 4E 12 4F 82 4F 61 61 73 00 20 30 37 15 +02 50 13 05 85 C3 EF 20 00 03 83 26 C4 07 8D B7 +83 25 07 39 0D 65 13 05 05 10 EF 20 C0 03 51 B7 +5D 71 2A DA 13 05 B0 0F 22 DE 36 D4 3E D0 86 C6 +96 C4 9A C2 9E C0 26 DC 2E D8 32 D6 3A D2 42 CE +46 CC 4A CA 4E C8 72 C6 76 C4 7A C2 7E C0 37 04 +02 50 EF 10 50 7C 83 26 C4 07 8D 47 63 E9 D7 08 +F3 27 B0 BC F3 29 C0 BC 73 29 10 34 F3 24 00 30 +73 24 40 30 73 90 C7 BC A1 47 73 A0 07 30 37 37 +02 50 83 27 07 39 0D 46 85 07 23 28 F7 38 63 69 +D6 06 A1 47 73 B0 07 30 73 90 C9 BC 73 10 19 34 +89 67 93 87 07 88 FD 8C 73 A0 04 30 85 67 93 87 +87 88 7D 8C 73 20 44 30 13 05 C0 0F EF 10 B0 75 +72 54 B6 40 A6 42 16 43 86 43 E2 54 52 55 C2 55 +32 56 A2 56 12 57 82 57 72 48 E2 48 52 49 C2 49 +32 4E A2 4E 12 4F 82 4F 61 61 73 00 20 30 37 15 +02 50 13 05 85 C4 EF 10 10 74 83 26 C4 07 8D B7 +83 25 07 39 0D 65 13 05 85 11 EF 10 D0 74 51 B7 +5D 71 2A DA 13 05 B0 0F 22 DE 36 D4 3E D0 86 C6 +96 C4 9A C2 9E C0 26 DC 2E D8 32 D6 3A D2 42 CE +46 CC 4A CA 4E C8 72 C6 76 C4 7A C2 7E C0 37 04 +02 50 EF 10 50 6D 83 26 C4 07 8D 47 63 E9 D7 08 +F3 27 B0 BC F3 29 C0 BC 73 29 10 34 F3 24 00 30 +73 24 40 30 73 90 C7 BC A1 47 73 A0 07 30 37 37 +02 50 83 27 07 39 0D 46 85 07 23 28 F7 38 63 69 +D6 06 A1 47 73 B0 07 30 73 90 C9 BC 73 10 19 34 +89 67 93 87 07 88 FD 8C 73 A0 04 30 85 67 93 87 +87 88 7D 8C 73 20 44 30 13 05 C0 0F EF 10 B0 66 +72 54 B6 40 A6 42 16 43 86 43 E2 54 52 55 C2 55 +32 56 A2 56 12 57 82 57 72 48 E2 48 52 49 C2 49 +32 4E A2 4E 12 4F 82 4F 61 61 73 00 20 30 37 15 +02 50 13 05 45 C5 EF 10 10 65 83 26 C4 07 8D B7 +83 25 07 39 0D 65 13 05 C5 12 EF 10 D0 65 51 B7 +5D 71 2A DA 13 05 B0 0F 22 DE 36 D4 3E D0 86 C6 +96 C4 9A C2 9E C0 26 DC 2E D8 32 D6 3A D2 42 CE +46 CC 4A CA 4E C8 72 C6 76 C4 7A C2 7E C0 37 04 +02 50 EF 10 50 5E 83 26 C4 07 8D 47 63 E9 D7 08 +F3 27 B0 BC F3 29 C0 BC 73 29 10 34 F3 24 00 30 +73 24 40 30 73 90 C7 BC A1 47 73 A0 07 30 37 37 +02 50 83 27 07 39 0D 46 85 07 23 28 F7 38 63 69 +D6 06 A1 47 73 B0 07 30 73 90 C9 BC 73 10 19 34 +89 67 93 87 07 88 FD 8C 73 A0 04 30 85 67 93 87 +87 88 7D 8C 73 20 44 30 13 05 C0 0F EF 10 B0 57 +72 54 B6 40 A6 42 16 43 86 43 E2 54 52 55 C2 55 +32 56 A2 56 12 57 82 57 72 48 E2 48 52 49 C2 49 +32 4E A2 4E 12 4F 82 4F 61 61 73 00 20 30 37 15 +02 50 13 05 05 C6 EF 10 10 56 83 26 C4 07 8D B7 +83 25 07 39 0D 65 13 05 05 14 EF 10 D0 56 51 B7 +5D 71 2A DA 13 05 B0 0F 22 DE 36 D4 3E D0 86 C6 +96 C4 9A C2 9E C0 26 DC 2E D8 32 D6 3A D2 42 CE +46 CC 4A CA 4E C8 72 C6 76 C4 7A C2 7E C0 37 04 +02 50 EF 10 50 4F 83 26 C4 07 8D 47 63 E9 D7 08 +F3 27 B0 BC F3 29 C0 BC 73 29 10 34 F3 24 00 30 +73 24 40 30 73 90 C7 BC A1 47 73 A0 07 30 37 37 +02 50 83 27 07 39 0D 46 85 07 23 28 F7 38 63 69 +D6 06 A1 47 73 B0 07 30 73 90 C9 BC 73 10 19 34 +89 67 93 87 07 88 FD 8C 73 A0 04 30 85 67 93 87 +87 88 7D 8C 73 20 44 30 13 05 C0 0F EF 10 B0 48 +72 54 B6 40 A6 42 16 43 86 43 E2 54 52 55 C2 55 +32 56 A2 56 12 57 82 57 72 48 E2 48 52 49 C2 49 +32 4E A2 4E 12 4F 82 4F 61 61 73 00 20 30 37 15 +02 50 13 05 05 C7 EF 10 10 47 83 26 C4 07 8D B7 +83 25 07 39 0D 65 13 05 45 15 EF 10 D0 47 51 B7 +5D 71 2A DA 13 05 B0 0F 22 DE 36 D4 3E D0 86 C6 +96 C4 9A C2 9E C0 26 DC 2E D8 32 D6 3A D2 42 CE +46 CC 4A CA 4E C8 72 C6 76 C4 7A C2 7E C0 37 04 +02 50 EF 10 50 40 83 26 C4 07 8D 47 63 E9 D7 08 +F3 27 B0 BC F3 29 C0 BC 73 29 10 34 F3 24 00 30 +73 24 40 30 73 90 C7 BC A1 47 73 A0 07 30 37 37 +02 50 83 27 07 39 0D 46 85 07 23 28 F7 38 63 69 +D6 06 A1 47 73 B0 07 30 73 90 C9 BC 73 10 19 34 +89 67 93 87 07 88 FD 8C 73 A0 04 30 85 67 93 87 +87 88 7D 8C 73 20 44 30 13 05 C0 0F EF 10 B0 39 +72 54 B6 40 A6 42 16 43 86 43 E2 54 52 55 C2 55 +32 56 A2 56 12 57 82 57 72 48 E2 48 52 49 C2 49 +32 4E A2 4E 12 4F 82 4F 61 61 73 00 20 30 37 15 +02 50 13 05 05 C8 EF 10 10 38 83 26 C4 07 8D B7 +83 25 07 39 0D 65 13 05 85 16 EF 10 D0 38 51 B7 +39 71 2A D6 13 05 B0 0F 3A CE 3E CC 06 DE 16 DC +1A DA 1E D8 2E D4 32 D2 36 D0 42 CA 46 C8 72 C6 +76 C4 7A C2 7E C0 EF 10 10 32 B7 07 02 50 03 A7 +C7 07 8D 47 63 E9 E7 02 13 05 C0 0F EF 10 B0 30 +F2 50 E2 52 52 53 C2 53 32 55 A2 55 12 56 82 56 +72 47 E2 47 52 48 C2 48 32 4E A2 4E 12 4F 82 4F +21 61 73 00 20 30 37 15 02 50 13 05 05 C9 EF 10 +90 2F D9 B7 1D 71 AA C2 13 05 B0 0F 3A DA 3E D8 +4A D2 86 CE 96 CC 9A CA 9E C8 A2 C6 A6 C4 AE C0 +32 DE 36 DC 42 D6 46 D4 4E D0 52 CE 72 CC 76 CA +7A C8 7E C6 37 09 02 50 EF 10 F0 29 83 27 C9 07 +0D 47 63 6B F7 0A 73 27 B0 BC 73 2A C0 BC F3 29 +10 34 F3 24 00 30 73 24 40 30 73 10 C7 BC 21 47 +73 20 07 30 B7 36 02 50 03 A7 06 39 0D 46 05 07 +23 A8 E6 38 63 62 F6 06 B5 EB A1 47 73 B0 07 30 +73 10 CA BC 73 90 19 34 89 67 93 87 07 88 FD 8C +73 A0 04 30 85 67 93 87 87 88 7D 8C 73 20 44 30 +13 05 C0 0F EF 10 30 23 36 44 F6 40 E6 42 56 43 +C6 43 A6 44 16 45 86 45 72 56 E2 56 52 57 C2 57 +32 58 A2 58 12 59 82 59 72 4A 62 4E D2 4E 42 4F +B2 4F 25 61 73 00 20 30 83 A5 06 39 0D 65 13 05 +C5 17 EF 10 50 23 83 27 C9 07 C1 DB 0D 65 13 05 +45 19 EF 10 50 22 51 B7 37 15 02 50 13 05 85 C9 +EF 10 70 1F 83 27 C9 07 3D BF 1D 71 AA C2 13 05 +B0 0F 3A DA 3E D8 4A D2 86 CE 96 CC 9A CA 9E C8 +A2 C6 A6 C4 AE C0 32 DE 36 DC 42 D6 46 D4 4E D0 +52 CE 72 CC 76 CA 7A C8 7E C6 37 09 02 50 EF 10 +90 19 83 27 C9 07 0D 47 63 6B F7 0A 73 27 B0 BC +73 2A C0 BC F3 29 10 34 F3 24 00 30 73 24 40 30 +73 10 C7 BC 21 47 73 20 07 30 B7 36 02 50 03 A7 +06 39 0D 46 05 07 23 A8 E6 38 63 62 F6 06 B5 EB +A1 47 73 B0 07 30 73 10 CA BC 73 90 19 34 89 67 +93 87 07 88 FD 8C 73 A0 04 30 85 67 93 87 87 88 +7D 8C 73 20 44 30 13 05 C0 0F EF 10 D0 12 36 44 +F6 40 E6 42 56 43 C6 43 A6 44 16 45 86 45 72 56 +E2 56 52 57 C2 57 32 58 A2 58 12 59 82 59 72 4A +62 4E D2 4E 42 4F B2 4F 25 61 73 00 20 30 83 A5 +06 39 0D 65 13 05 C5 19 EF 10 F0 12 83 27 C9 07 +C1 DB 0D 65 13 05 45 1B EF 10 F0 11 51 B7 37 15 +02 50 13 05 C5 CA EF 10 10 0F 83 27 C9 07 3D BF +39 71 3E CC B7 07 02 50 3A CE 03 A7 C7 07 06 DE +16 DC 1A DA 1E D8 2A D6 2E D4 32 D2 36 D0 42 CA +46 C8 72 C6 76 C4 7A C2 7E C0 91 47 63 E5 E7 02 +F2 50 E2 52 52 53 C2 53 32 55 A2 55 12 56 82 56 +72 47 E2 47 52 48 C2 48 32 4E A2 4E 12 4F 82 4F +21 61 73 00 20 30 F3 25 20 34 0D 65 13 05 C5 1B +EF 10 70 0A F1 B7 1D 71 AA C2 13 05 B0 0F A2 C6 +36 DC 3E D8 86 CE 96 CC 9A CA 9E C8 A6 C4 AE C0 +32 DE 3A DA 42 D6 46 D4 4A D2 4E D0 52 CE 72 CC +76 CA 7A C8 7E C6 37 04 02 50 EF 10 D0 02 83 26 +C4 07 8D 47 63 ED D7 0C F3 27 B0 BC 73 2A C0 BC +F3 29 10 34 73 29 00 30 F3 24 40 30 73 90 C7 BC +A1 47 73 A0 07 30 37 37 02 50 83 27 07 39 0D 46 +85 07 23 28 F7 38 63 6C D6 08 37 27 02 30 83 27 +87 81 93 F6 17 00 A5 CE B7 37 02 50 93 87 47 39 +D4 5F 05 46 23 2C C7 80 13 E7 16 00 D8 DF A1 47 +73 B0 07 30 73 10 CA BC 73 90 19 34 89 67 93 87 +07 88 33 79 F9 00 73 20 09 30 85 67 93 87 87 88 +FD 8C 73 A0 44 30 13 05 C0 0F EF 10 C0 79 36 44 +F6 40 E6 42 56 43 C6 43 A6 44 16 45 86 45 72 56 +E2 56 52 57 C2 57 32 58 A2 58 12 59 82 59 72 4A +62 4E D2 4E 42 4F B2 4F 25 61 73 00 20 30 C5 F3 +83 27 C4 07 95 E7 05 45 EF 10 E0 75 01 A0 83 25 +07 39 0D 65 13 05 85 1C EF 10 E0 78 B9 BF 37 15 +02 50 13 05 05 CC EF 10 00 76 83 26 C4 07 29 BF +0D 65 81 45 13 05 45 1E EF 10 E0 76 05 45 EF 10 +80 72 E9 B7 1D 71 AA C2 13 05 B0 0F A2 C6 36 DC +3E D8 86 CE 96 CC 9A CA 9E C8 A6 C4 AE C0 32 DE +3A DA 42 D6 46 D4 4A D2 4E D0 52 CE 72 CC 76 CA +7A C8 7E C6 37 04 02 50 EF 10 E0 6E 83 26 C4 07 +8D 47 63 E3 D7 1A F3 27 B0 BC 73 2A C0 BC F3 29 +10 34 73 29 00 30 F3 24 40 30 73 90 C7 BC A1 47 +73 A0 07 30 37 37 02 50 83 27 07 39 0D 46 85 07 +23 28 F7 38 63 62 D6 16 B7 16 03 30 03 A7 86 81 +93 77 17 00 81 CF B7 37 02 50 05 46 23 AC C6 80 +93 87 47 39 D4 5B 93 E6 16 00 D4 DB 93 77 27 00 +91 CF B7 16 03 30 B7 37 02 50 09 46 23 AC C6 80 +93 87 47 39 D4 5B 93 E6 26 00 D4 DB 93 77 47 00 +91 CF B7 16 03 30 B7 37 02 50 11 46 23 AC C6 80 +93 87 47 39 D4 5B 93 E6 46 00 D4 DB 93 77 87 00 +13 76 07 01 93 76 07 02 DD C3 37 17 03 30 B7 37 +02 50 A1 45 23 2C B7 80 93 87 47 39 D8 5B 13 67 +87 00 D8 DB 55 CE 37 17 03 30 41 46 23 2C C7 80 +D8 5B 13 67 07 01 D8 DB 99 CA 37 17 03 30 93 06 +00 02 23 2C D7 80 D8 5B 13 67 07 02 D8 DB A1 47 +73 B0 07 30 73 10 CA BC 73 90 19 34 89 67 93 87 +07 88 33 79 F9 00 73 20 09 30 85 67 93 87 87 88 +FD 8C 73 A0 44 30 13 05 C0 0F EF 10 C0 5C 36 44 +F6 40 E6 42 56 43 C6 43 A6 44 16 45 86 45 72 56 +E2 56 52 57 C2 57 32 58 A2 58 12 59 82 59 72 4A +62 4E D2 4E 42 4F B2 4F 25 61 73 00 20 30 05 C2 +37 17 03 30 B7 37 02 50 41 46 93 87 47 39 23 2C +C7 80 D8 5B 13 67 07 01 D8 DB A5 FA 49 B7 B1 E6 +3D FF 83 27 C4 07 AD E3 05 45 EF 10 C0 56 01 A0 +BD D6 37 17 03 30 93 06 00 02 23 2C D7 80 D8 5B +13 67 07 02 D8 DB A1 BF 83 25 07 39 0D 65 13 05 +85 20 EF 10 40 58 49 BD 37 15 02 50 13 05 45 CD +EF 10 60 55 83 26 C4 07 B9 B5 37 17 03 30 B7 37 +02 50 93 06 00 02 93 87 47 39 23 2C D7 80 D8 5B +13 67 07 02 D8 DB 21 BF 0D 65 81 45 13 05 05 22 +EF 10 60 54 51 BF 1D 71 AA C2 13 05 B0 0F A2 C6 +36 DC 3E D8 86 CE 96 CC 9A CA 9E C8 A6 C4 AE C0 +32 DE 3A DA 42 D6 46 D4 4A D2 4E D0 52 CE 72 CC +76 CA 7A C8 7E C6 37 04 02 50 EF 10 C0 4C 83 26 +C4 07 8D 47 63 E3 D7 1A F3 27 B0 BC 73 2A C0 BC +F3 29 10 34 73 29 00 30 F3 24 40 30 73 90 C7 BC +A1 47 73 A0 07 30 37 37 02 50 83 27 07 39 0D 46 +85 07 23 28 F7 38 63 62 D6 16 B7 16 03 30 03 A7 +46 81 93 77 17 00 81 CF B7 37 02 50 05 46 23 AA +C6 80 93 87 47 39 94 5B 93 E6 16 00 94 DB 93 77 +27 00 91 CF B7 16 03 30 B7 37 02 50 09 46 23 AA +C6 80 93 87 47 39 94 5B 93 E6 26 00 94 DB 93 77 +47 00 91 CF B7 16 03 30 B7 37 02 50 11 46 23 AA +C6 80 93 87 47 39 94 5B 93 E6 46 00 94 DB 93 77 +87 00 13 76 07 01 93 76 07 02 DD C3 37 17 03 30 +B7 37 02 50 A1 45 23 2A B7 80 93 87 47 39 98 5B +13 67 87 00 98 DB 55 CE 37 17 03 30 41 46 23 2A +C7 80 98 5B 13 67 07 01 98 DB 99 CA 37 17 03 30 +93 06 00 02 23 2A D7 80 98 5B 13 67 07 02 98 DB +A1 47 73 B0 07 30 73 10 CA BC 73 90 19 34 89 67 +93 87 07 88 33 79 F9 00 73 20 09 30 85 67 93 87 +87 88 FD 8C 73 A0 44 30 13 05 C0 0F EF 10 A0 3A +36 44 F6 40 E6 42 56 43 C6 43 A6 44 16 45 86 45 +72 56 E2 56 52 57 C2 57 32 58 A2 58 12 59 82 59 +72 4A 62 4E D2 4E 42 4F B2 4F 25 61 73 00 20 30 +05 C2 37 17 03 30 B7 37 02 50 41 46 93 87 47 39 +23 2A C7 80 98 5B 13 67 07 01 98 DB A5 FA 49 B7 +B1 E6 3D FF 83 27 C4 07 AD E3 05 45 EF 10 A0 34 +01 A0 BD D6 37 17 03 30 93 06 00 02 23 2A D7 80 +98 5B 13 67 07 02 98 DB A1 BF 83 25 07 39 0D 65 +13 05 05 24 EF 10 20 36 49 BD 37 15 02 50 13 05 +85 CE EF 10 40 33 83 26 C4 07 B9 B5 37 17 03 30 +B7 37 02 50 93 06 00 02 93 87 47 39 23 2A D7 80 +98 5B 13 67 07 02 98 DB 21 BF 0D 65 81 45 13 05 +85 25 EF 10 40 32 51 BF 1D 71 AA C2 13 05 B0 0F +A2 C6 36 DC 3E D8 86 CE 96 CC 9A CA 9E C8 A6 C4 +AE C0 32 DE 3A DA 42 D6 46 D4 4A D2 4E D0 52 CE +72 CC 76 CA 7A C8 7E C6 37 04 02 50 EF 10 A0 2A +83 26 C4 07 8D 47 63 ED D7 0C F3 27 B0 BC 73 2A +C0 BC F3 29 10 34 73 29 00 30 F3 24 40 30 73 90 +C7 BC A1 47 73 A0 07 30 37 37 02 50 83 27 07 39 +0D 46 85 07 23 28 F7 38 63 6C D6 08 37 97 02 10 +83 27 87 81 93 F6 17 00 A5 CE B7 37 02 50 93 87 +47 39 D4 57 05 46 23 2C C7 80 13 E7 16 00 D8 D7 +A1 47 73 B0 07 30 73 10 CA BC 73 90 19 34 89 67 +93 87 07 88 33 79 F9 00 73 20 09 30 85 67 93 87 +87 88 FD 8C 73 A0 44 30 13 05 C0 0F EF 10 A0 21 +36 44 F6 40 E6 42 56 43 C6 43 A6 44 16 45 86 45 +72 56 E2 56 52 57 C2 57 32 58 A2 58 12 59 82 59 +72 4A 62 4E D2 4E 42 4F B2 4F 25 61 73 00 20 30 +C5 F3 83 27 C4 07 95 E7 05 45 EF 10 C0 1D 01 A0 +83 25 07 39 0D 65 13 05 85 27 EF 10 C0 20 B9 BF +37 15 02 50 13 05 C5 CF EF 10 E0 1D 83 26 C4 07 +29 BF 0D 65 81 45 13 05 05 29 EF 10 C0 1E 05 45 +EF 10 60 1A E9 B7 1D 71 AA C2 13 05 B0 0F A2 C6 +36 DC 3E D8 86 CE 96 CC 9A CA 9E C8 A6 C4 AE C0 +32 DE 3A DA 42 D6 46 D4 4A D2 4E D0 52 CE 72 CC +76 CA 7A C8 7E C6 37 04 02 50 EF 10 C0 16 83 26 +C4 07 8D 47 63 ED D7 0C F3 27 B0 BC 73 2A C0 BC +F3 29 10 34 73 29 00 30 F3 24 40 30 73 90 C7 BC +A1 47 73 A0 07 30 37 37 02 50 83 27 07 39 0D 46 +85 07 23 28 F7 38 63 6C D6 08 37 17 02 10 83 27 +87 81 93 F6 17 00 A5 CE B7 37 02 50 93 87 47 39 +D4 53 05 46 23 2C C7 80 13 E7 16 00 D8 D3 A1 47 +73 B0 07 30 73 10 CA BC 73 90 19 34 89 67 93 87 +07 88 33 79 F9 00 73 20 09 30 85 67 93 87 87 88 +FD 8C 73 A0 44 30 13 05 C0 0F EF 10 C0 0D 36 44 +F6 40 E6 42 56 43 C6 43 A6 44 16 45 86 45 72 56 +E2 56 52 57 C2 57 32 58 A2 58 12 59 82 59 72 4A +62 4E D2 4E 42 4F B2 4F 25 61 73 00 20 30 C5 F3 +83 27 C4 07 95 E7 05 45 EF 10 E0 09 01 A0 83 25 +07 39 0D 65 13 05 05 2B EF 10 E0 0C B9 BF 37 15 +02 50 13 05 C5 D0 EF 10 00 0A 83 26 C4 07 29 BF +0D 65 81 45 13 05 85 2C EF 10 E0 0A 05 45 EF 10 +80 06 E9 B7 1D 71 AA C2 13 05 B0 0F A2 C6 36 DC +3E D8 86 CE 96 CC 9A CA 9E C8 A6 C4 AE C0 32 DE +3A DA 42 D6 46 D4 4A D2 4E D0 52 CE 72 CC 76 CA +7A C8 7E C6 37 04 02 50 EF 10 E0 02 83 26 C4 07 +8D 47 63 ED D7 0C F3 27 B0 BC 73 2A C0 BC F3 29 +10 34 73 29 00 30 F3 24 40 30 73 90 C7 BC A1 47 +73 A0 07 30 37 37 02 50 83 27 07 39 0D 46 85 07 +23 28 F7 38 63 6C D6 08 37 17 01 10 83 27 87 81 +93 F6 17 00 A5 CE B7 37 02 50 93 87 47 39 D4 4B +05 46 23 2C C7 80 13 E7 16 00 D8 CB A1 47 73 B0 +07 30 73 10 CA BC 73 90 19 34 89 67 93 87 07 88 +33 79 F9 00 73 20 09 30 85 67 93 87 87 88 FD 8C +73 A0 44 30 13 05 C0 0F EF 00 F0 79 36 44 F6 40 +E6 42 56 43 C6 43 A6 44 16 45 86 45 72 56 E2 56 +52 57 C2 57 32 58 A2 58 12 59 82 59 72 4A 62 4E +D2 4E 42 4F B2 4F 25 61 73 00 20 30 C5 F3 83 27 +C4 07 95 E7 05 45 EF 00 10 76 01 A0 83 25 07 39 +0D 65 13 05 85 2E EF 00 10 79 B9 BF 37 15 02 50 +13 05 C5 D1 EF 00 30 76 83 26 C4 07 29 BF 0D 65 +81 45 13 05 C5 2F EF 00 10 77 05 45 EF 00 B0 72 +E9 B7 1D 71 AA C2 13 05 B0 0F A2 C6 36 DC 3E D8 +86 CE 96 CC 9A CA 9E C8 A6 C4 AE C0 32 DE 3A DA +42 D6 46 D4 4A D2 4E D0 52 CE 72 CC 76 CA 7A C8 +7E C6 37 04 02 50 EF 00 10 6F 83 26 C4 07 8D 47 +63 ED D7 0C F3 27 B0 BC 73 2A C0 BC F3 29 10 34 +73 29 00 30 F3 24 40 30 73 90 C7 BC A1 47 73 A0 +07 30 37 37 02 50 83 27 07 39 0D 46 85 07 23 28 +F7 38 63 6C D6 08 37 97 00 10 83 27 87 81 93 F6 +17 00 A5 CE B7 37 02 50 93 87 47 39 D4 47 05 46 +23 2C C7 80 13 E7 16 00 D8 C7 A1 47 73 B0 07 30 +73 10 CA BC 73 90 19 34 89 67 93 87 07 88 33 79 +F9 00 73 20 09 30 85 67 93 87 87 88 FD 8C 73 A0 +44 30 13 05 C0 0F EF 00 10 66 36 44 F6 40 E6 42 +56 43 C6 43 A6 44 16 45 86 45 72 56 E2 56 52 57 +C2 57 32 58 A2 58 12 59 82 59 72 4A 62 4E D2 4E +42 4F B2 4F 25 61 73 00 20 30 C5 F3 83 27 C4 07 +95 E7 05 45 EF 00 30 62 01 A0 83 25 07 39 0D 65 +13 05 85 31 EF 00 30 65 B9 BF 37 15 02 50 13 05 +C5 D2 EF 00 50 62 83 26 C4 07 29 BF 0D 65 81 45 +13 05 C5 32 EF 00 30 63 05 45 EF 00 D0 5E E9 B7 +1D 71 AA C2 13 05 B0 0F A2 C6 36 DC 3E D8 86 CE +96 CC 9A CA 9E C8 A6 C4 AE C0 32 DE 3A DA 42 D6 +46 D4 4A D2 4E D0 52 CE 72 CC 76 CA 7A C8 7E C6 +37 04 02 50 EF 00 30 5B 83 26 C4 07 8D 47 63 ED +D7 0C F3 27 B0 BC 73 2A C0 BC F3 29 10 34 73 29 +00 30 F3 24 40 30 73 90 C7 BC A1 47 73 A0 07 30 +37 37 02 50 83 27 07 39 0D 46 85 07 23 28 F7 38 +63 6C D6 08 37 17 00 10 83 27 87 81 93 F6 17 00 +A5 CE B7 37 02 50 93 87 47 39 D4 43 05 46 23 2C +C7 80 13 E7 16 00 D8 C3 A1 47 73 B0 07 30 73 10 +CA BC 73 90 19 34 89 67 93 87 07 88 33 79 F9 00 +73 20 09 30 85 67 93 87 87 88 FD 8C 73 A0 44 30 +13 05 C0 0F EF 00 30 52 36 44 F6 40 E6 42 56 43 +C6 43 A6 44 16 45 86 45 72 56 E2 56 52 57 C2 57 +32 58 A2 58 12 59 82 59 72 4A 62 4E D2 4E 42 4F +B2 4F 25 61 73 00 20 30 C5 F3 83 27 C4 07 95 E7 +05 45 EF 00 50 4E 01 A0 83 25 07 39 0D 65 13 05 +85 34 EF 00 50 51 B9 BF 37 15 02 50 13 05 C5 D3 +EF 00 70 4E 83 26 C4 07 29 BF 0D 65 81 45 13 05 +C5 35 EF 00 50 4F 05 45 EF 00 F0 4A E9 B7 21 47 +73 30 07 30 85 67 93 87 47 1F 93 E7 17 00 73 90 +57 30 97 12 02 50 93 82 E2 B9 73 90 82 BC B7 37 +00 60 23 A0 07 00 0F 00 F0 0F 73 50 90 BC B7 07 +00 60 D8 C3 0F 00 F0 0F 9D 46 94 C7 0F 00 F0 0F +D8 C7 0F 00 F0 0F 94 CB 0F 00 F0 0F D8 CB 0F 00 +F0 0F 94 CF 0F 00 F0 0F D8 CF 0F 00 F0 0F 94 D3 +0F 00 F0 0F D8 D3 0F 00 F0 0F 94 D7 0F 00 F0 0F +D8 D7 0F 00 F0 0F 94 DB 0F 00 F0 0F 91 45 CC DB +0F 00 F0 0F 0D 46 90 DF 0F 00 F0 0F CC DF 0F 00 +F0 0F B0 C3 0F 00 F0 0F F8 C3 0F 00 F0 0F B4 C7 +0F 00 F0 0F F8 C7 0F 00 F0 0F B4 CB 0F 00 F0 0F +F8 CB 0F 00 F0 0F B4 CF 0F 00 F0 0F F8 CF 0F 00 +F0 0F B4 D3 0F 00 F0 0F F8 D3 0F 00 F0 0F B4 D7 +0F 00 F0 0F 23 A6 07 06 0F 00 F0 0F 23 A8 07 06 +0F 00 F0 0F 23 AA 07 06 0F 00 F0 0F 23 AC 07 06 +0F 00 F0 0F 23 AE 07 06 0F 00 F0 0F 73 50 B0 BC +73 50 C0 BC 37 47 00 60 11 07 85 47 05 68 79 75 +93 05 00 02 23 20 07 00 0F 00 F0 0F B3 06 07 01 +23 A0 06 00 0F 00 F0 0F B3 06 A7 00 13 B6 B7 01 +90 C2 0F 00 F0 0F 85 07 93 F7 F7 0F 11 07 E3 9B +B7 FC 05 47 B7 16 00 10 23 A4 E6 80 8D 47 23 A0 +F6 80 B7 96 00 10 23 A2 E6 80 23 A4 E6 80 23 A0 +F6 80 3D 46 B7 16 01 10 23 A2 C6 80 23 A4 E6 80 +23 A0 F6 80 B7 16 02 10 23 A4 E6 80 23 A0 F6 80 +B7 96 02 10 23 A2 F6 80 23 A4 E6 80 23 A0 F6 80 +B7 16 04 10 23 A0 F6 40 23 A2 E6 40 23 A4 F6 40 +1D 46 B7 06 04 10 D0 C2 B7 86 03 10 23 A2 E6 10 +23 A4 E6 10 23 A0 F6 10 11 46 B7 16 03 30 23 AC +C6 80 21 46 23 AC C6 80 23 A4 06 98 23 A6 06 98 +93 05 F0 0F 23 A2 B6 80 93 05 F0 03 23 A4 B6 80 +23 A0 F6 80 B7 26 02 30 23 A4 E6 80 23 A0 F6 80 +37 37 02 30 93 06 F0 07 23 22 D7 80 FD 46 23 24 +D7 80 FD 55 B7 06 03 30 23 20 F7 80 23 A4 B6 64 +B7 07 00 D0 23 A6 B6 64 73 90 07 7F 73 90 17 7F +73 90 27 7F B7 17 00 40 93 87 07 88 73 A0 47 30 +73 20 06 30 82 80 01 00 39 71 3A CE 3E CC 7D 57 +B7 07 03 30 06 DE 16 DC 1A DA 1E D8 2A D6 2E D4 +32 D2 36 D0 42 CA 46 C8 72 C6 76 C4 7A C2 7E C0 +23 A4 E7 64 23 A6 E7 64 B7 07 02 50 03 A7 C7 07 +8D 47 63 E5 E7 02 F2 50 E2 52 52 53 C2 53 32 55 +A2 55 12 56 82 56 72 47 E2 47 52 48 C2 48 32 4E +A2 4E 12 4F 82 4F 21 61 73 00 20 30 37 15 02 50 +13 05 C5 D4 EF 00 30 22 F9 B7 01 00 73 50 40 7D +73 00 20 30 39 71 3E CC B7 07 02 50 3A CE 03 A7 +C7 07 06 DE 16 DC 1A DA 1E D8 2A D6 2E D4 32 D2 +36 D0 42 CA 46 C8 72 C6 76 C4 7A C2 7E C0 91 47 +63 EE E7 02 B7 07 00 08 FD 17 73 B0 07 7F 73 B0 +17 7F 73 B0 27 7F F2 50 E2 52 52 53 C2 53 32 55 +A2 55 12 56 82 56 72 47 E2 47 52 48 C2 48 32 4E +A2 4E 12 4F 82 4F 21 61 73 00 20 30 37 15 02 50 +13 05 85 D7 EF 00 30 1A 75 BF 01 00 5D 71 2A DA +13 05 B0 0F 86 C6 96 C4 9A C2 9E C0 22 DE 26 DC +2E D8 32 D6 36 D4 3A D2 3E D0 42 CE 46 CC 4A CA +72 C8 76 C6 7A C4 7E C2 EF 00 F0 14 F3 24 20 34 +37 04 02 50 83 27 C4 07 05 47 63 6C F7 04 63 C5 +04 04 F3 27 F0 7F F3 27 10 34 F3 27 30 34 05 45 +EF 00 70 12 13 05 C0 0F EF 00 F0 11 72 54 B6 40 +A6 42 16 43 86 43 E2 54 52 55 C2 55 32 56 A2 56 +12 57 82 57 72 48 E2 48 52 49 42 4E B2 4E 22 4F +92 4F 61 61 73 00 20 30 B5 E3 05 45 EF 00 B0 0E +7D BF 0D 69 13 09 C9 07 A6 85 13 05 C9 2F EF 00 +90 11 83 27 C4 07 E3 C1 04 FE F3 25 F0 7F 89 44 +63 FB F4 02 13 05 09 33 EF 00 F0 0F F3 25 10 34 +83 27 C4 07 E3 F3 F4 F8 13 05 C9 33 EF 00 B0 0E +F3 25 30 34 83 27 C4 07 E3 FB F4 F6 13 05 89 34 +EF 00 70 0D AD B7 F3 27 10 34 85 B7 0D 65 FD 55 +13 05 45 39 EF 00 30 0C 49 BF 01 00 63 6E 74 5F +61 62 72 5F 6E 6F 74 69 66 3A 25 78 0A 00 00 00 +63 6E 74 5F 61 62 72 5F 65 72 72 6F 72 3A 25 78 +0A 00 00 00 63 6E 74 5F 73 68 61 35 31 32 5F 61 +63 63 5F 65 72 72 6F 72 3A 25 78 0A 00 00 00 00 +63 6E 74 5F 73 68 61 33 5F 6E 6F 74 69 66 3A 25 +78 0A 00 00 63 6E 74 5F 73 68 61 33 5F 65 72 72 +6F 72 3A 25 78 0A 00 00 63 6E 74 5F 73 68 61 32 +35 36 5F 65 72 72 6F 72 3A 25 78 0A 00 00 00 00 +63 6E 74 5F 73 68 61 35 31 32 5F 65 72 72 6F 72 +3A 25 78 0A 00 00 00 00 63 6E 74 5F 6B 76 5F 6E +6F 74 69 66 3A 25 78 0A 00 00 00 00 63 6E 74 5F +6B 76 5F 65 72 72 6F 72 3A 25 78 0A 00 00 00 00 +63 6E 74 5F 68 6D 61 63 5F 65 72 72 6F 72 3A 25 +78 0A 00 00 63 6E 74 5F 65 63 63 5F 65 72 72 6F +72 3A 25 78 0A 00 00 00 63 6E 74 5F 64 6F 65 5F +65 72 72 6F 72 3A 25 78 0A 00 00 00 63 6E 74 5F +61 78 69 5F 64 6D 61 5F 6E 6F 74 69 66 3A 25 78 +0A 00 00 00 45 52 52 4F 52 00 00 00 63 6E 74 5F +61 78 69 5F 64 6D 61 5F 65 72 72 6F 72 3A 25 78 +0A 00 00 00 45 52 52 4F 52 00 00 00 6D 63 61 75 +73 65 3A 25 78 0A 00 00 63 6E 74 5F 73 68 61 35 +31 32 5F 61 63 63 5F 6E 6F 74 69 66 3A 25 78 0A +00 00 00 00 62 61 64 20 73 68 61 35 31 32 5F 61 +63 63 5F 6E 6F 74 69 66 5F 69 6E 74 72 20 73 74 +73 3A 25 78 0A 00 00 00 63 6E 74 5F 73 6F 63 5F +69 66 63 5F 6E 6F 74 69 66 3A 25 78 0A 00 00 00 +62 61 64 20 73 6F 63 5F 69 66 63 5F 6E 6F 74 69 +66 5F 69 6E 74 72 20 73 74 73 3A 25 78 0A 00 00 +63 6E 74 5F 73 6F 63 5F 69 66 63 5F 65 72 72 6F +72 3A 25 78 0A 00 00 00 62 61 64 20 73 6F 63 5F +69 66 63 5F 65 72 72 6F 72 5F 69 6E 74 72 20 73 +74 73 3A 25 78 0A 00 00 63 6E 74 5F 73 68 61 32 +35 36 5F 6E 6F 74 69 66 3A 25 78 0A 00 00 00 00 +62 61 64 20 73 68 61 32 35 36 5F 6E 6F 74 69 66 +5F 69 6E 74 72 20 73 74 73 3A 25 78 0A 00 00 00 +63 6E 74 5F 73 68 61 35 31 32 5F 6E 6F 74 69 66 +3A 25 78 0A 00 00 00 00 62 61 64 20 73 68 61 35 +31 32 5F 6E 6F 74 69 66 5F 69 6E 74 72 20 73 74 +73 3A 25 78 0A 00 00 00 63 6E 74 5F 68 6D 61 63 +5F 6E 6F 74 69 66 3A 25 78 0A 00 00 62 61 64 20 +68 6D 61 63 5F 6E 6F 74 69 66 5F 69 6E 74 72 20 +73 74 73 3A 25 78 0A 00 63 6E 74 5F 65 63 63 5F +6E 6F 74 69 66 3A 25 78 0A 00 00 00 62 61 64 20 +65 63 63 5F 6E 6F 74 69 66 5F 69 6E 74 72 20 73 +74 73 3A 25 78 0A 00 00 63 6E 74 5F 64 6F 65 5F +6E 6F 74 69 66 3A 25 78 0A 00 00 00 62 61 64 20 +64 6F 65 5F 6E 6F 74 69 66 5F 69 6E 74 72 20 73 +74 73 3A 25 78 0A 00 00 49 6E 3A 53 74 64 20 45 +78 63 70 74 6E 0A 6D 63 61 75 73 65 3A 25 78 0A +00 00 00 00 55 6E 65 78 70 65 63 74 65 64 20 49 +6E 74 72 20 62 69 74 3A 25 78 0A 00 6D 73 63 61 +75 73 65 3A 25 78 0A 00 6D 65 70 63 3A 25 78 0A +00 00 00 00 6D 74 76 61 6C 3A 25 78 0A 00 00 00 +03 47 05 00 63 0E 07 4E B7 0E 02 50 03 AE 0E 08 +39 71 37 0F 02 50 22 DE AA 87 26 DC 4A DA 4E D8 +52 D6 56 D4 5A D2 5E D0 01 45 93 08 50 02 13 06 +00 03 93 03 D0 02 93 02 A0 02 93 0F 00 02 13 0F +4F 08 25 44 63 03 17 03 23 20 EE 00 05 05 03 C7 +17 00 85 07 65 FB 72 54 E2 54 52 59 C2 59 32 5A +A2 5A 12 5B 82 5B 21 61 82 80 03 C7 17 00 65 D7 +85 07 63 0D 17 05 93 04 00 02 63 19 C7 00 03 C7 +17 00 85 07 E3 0D C7 FE 93 04 00 03 63 05 77 02 +63 08 57 02 13 03 07 FD 93 76 F3 0F 01 48 63 7A +D4 02 13 07 87 FA 13 77 F7 0F E3 E2 EF FA 0A 07 +7A 97 18 43 02 87 03 C7 17 00 85 07 E3 1C 57 FC +03 C7 17 00 91 05 85 07 01 48 E1 BF 23 20 1E 01 +BD BF 25 49 03 C7 17 00 93 16 28 00 C2 96 86 06 +33 08 D3 00 13 03 07 FD 93 76 F3 0F 85 07 E3 73 +D9 FE 45 BF 98 41 83 A6 0E 08 91 05 13 58 C7 01 +63 12 08 14 13 58 87 01 63 15 08 20 13 58 47 01 +63 08 08 34 19 43 B1 AA 03 A3 05 00 81 46 91 05 +13 09 C1 00 A9 49 A5 4B 33 77 33 03 36 8B 85 06 +B3 0A D9 00 1A 8A 13 07 07 03 A3 8F EA FE 33 53 +33 03 E3 E3 4B FF 83 A9 0E 08 33 07 69 01 36 83 +63 D7 06 01 23 A0 99 00 05 03 E3 1D 68 FE 13 03 +B1 00 03 48 07 00 7D 17 23 A0 09 01 E3 1B 67 FE +36 95 F1 BD 03 A3 05 00 91 05 83 46 03 00 E3 88 +06 EC 03 A8 0E 08 1A 87 05 07 23 20 D8 00 83 46 +07 00 FD FA 2A 97 33 05 67 40 55 BD 98 41 91 05 +13 58 E7 01 63 16 08 18 13 58 B7 01 63 1A 08 26 +13 58 87 01 63 0E 08 28 83 A6 0E 08 A5 44 61 AA +83 AB 05 00 83 AA 0E 08 91 05 5E 83 63 D9 0B 00 +13 07 D0 02 33 03 70 41 23 A0 EA 00 7D 18 81 46 +13 09 C1 00 A9 49 33 67 33 03 36 8B 85 06 33 0A +D9 00 33 43 33 03 13 07 07 03 A3 0F EA FE E3 14 +03 FE 33 07 69 01 36 83 63 D7 06 01 23 A0 9A 00 +05 03 E3 1D 03 FF 13 03 B1 00 03 48 07 00 7D 17 +23 A0 0A 01 E3 1B 67 FE E3 D4 0B F4 93 06 2B 00 +36 95 31 BD 83 C6 05 00 03 A7 0E 08 05 05 91 05 +14 C3 31 B5 93 74 F8 0F 25 49 13 83 04 03 63 6B +09 1B 13 58 87 01 23 A0 66 00 13 78 F8 00 21 43 +93 04 00 03 63 18 08 0A 13 58 47 01 84 C2 13 78 +F8 00 25 49 93 74 F8 0F 63 71 09 19 93 84 74 03 +93 F4 F4 0F 13 58 07 01 84 C2 13 78 F8 00 25 49 +93 74 F8 0F 63 6F 09 19 93 84 04 03 93 F4 F4 0F +13 58 C7 00 84 C2 13 78 F8 00 25 49 93 74 F8 0F +63 6B 09 19 93 84 04 03 93 F4 F4 0F 13 58 87 00 +84 C2 13 78 F8 00 25 49 93 74 F8 0F 63 68 09 17 +93 84 04 03 93 F4 F4 0F 13 58 47 00 84 C2 13 78 +F8 00 25 49 93 74 F8 0F 63 60 09 15 13 88 04 03 +13 78 F8 0F 23 A0 06 01 93 74 F7 00 25 49 13 88 +04 03 63 54 99 00 13 88 74 03 23 A0 06 01 1A 95 +3D BB 1D 43 93 04 78 03 25 49 93 79 F8 0F 93 F4 +F4 0F E3 63 09 F5 93 89 09 03 93 F4 F9 0F 2D BF +83 A6 0E 08 13 03 08 03 13 58 B7 01 23 A0 66 00 +13 78 78 00 AD 44 13 03 08 03 13 58 87 01 23 A0 +66 00 13 78 78 00 13 08 08 03 13 73 F8 0F 13 58 +57 01 23 A0 66 00 13 78 78 00 13 08 08 03 13 73 +F8 0F 13 58 27 01 23 A0 66 00 13 78 78 00 13 08 +08 03 13 73 F8 0F 13 58 F7 00 23 A0 66 00 13 78 +78 00 13 08 08 03 13 73 F8 0F 13 58 C7 00 23 A0 +66 00 13 78 78 00 13 08 08 03 13 73 F8 0F 13 58 +97 00 23 A0 66 00 13 78 78 00 13 08 08 03 13 73 +F8 0F 13 58 67 00 23 A0 66 00 13 78 78 00 13 08 +08 03 13 73 F8 0F 13 58 37 00 23 A0 66 00 13 78 +78 00 13 08 08 03 13 78 F8 0F 23 A0 06 01 1D 8B +13 07 07 03 98 C2 26 95 99 B9 93 84 04 03 93 F4 +F4 0F 49 B5 13 83 74 03 13 58 87 01 23 A0 66 00 +13 78 F8 00 21 43 93 04 00 03 E3 07 08 E4 DD BD +83 A6 0E 08 A9 44 05 B7 13 88 74 03 13 78 F8 0F +D1 B5 93 84 74 03 93 F4 F4 0F 9D B5 93 84 74 03 +93 F4 F4 0F 51 BD 93 84 74 03 93 F4 F4 0F BD B5 +13 58 57 01 63 0C 08 00 83 A6 0E 08 A1 44 31 B7 +13 58 07 01 63 0C 08 00 15 43 15 B5 13 58 27 01 +63 0C 08 00 83 A6 0E 08 9D 44 11 B7 13 58 C7 00 +63 0C 08 00 11 43 15 B5 13 58 F7 00 63 0C 08 00 +83 A6 0E 08 99 44 F5 BD 13 58 87 00 63 0C 08 00 +0D 43 15 B5 13 58 C7 00 63 0D 08 00 83 A6 0E 08 +95 44 D5 BD 13 58 47 00 05 43 E3 0F 08 E2 09 43 +0D B5 13 58 97 00 63 06 08 00 83 A6 0E 08 91 44 +ED B5 13 58 67 00 63 06 08 00 83 A6 0E 08 8D 44 +FD B5 13 58 37 00 63 06 08 00 83 A6 0E 08 89 44 +CD BD 1D 8B E3 0D 07 B4 83 A6 0E 08 85 44 CD BD +01 45 82 80 39 71 13 03 41 02 2E D2 9A 85 06 CE +32 D4 36 D6 3A D8 3E DA 42 DC 46 DE 1A C6 CD 34 +F2 40 21 61 82 80 B7 07 02 50 83 A7 07 08 13 75 +F5 0F 88 C3 82 80 B7 07 02 50 83 A7 07 08 13 75 +F5 0F 88 C3 82 80 83 47 05 00 37 07 02 50 03 27 +07 08 91 C7 05 05 1C C3 83 47 05 00 E5 FF A9 47 +1C C3 05 45 82 80 39 71 13 03 41 02 2E D2 9A 85 +06 CE 32 D4 36 D6 3A D8 3E DA 42 DC 46 DE 1A C6 +41 34 F2 40 21 61 82 80 F3 25 00 B8 73 25 00 B0 +F3 27 00 B8 E3 9A F5 FE 82 80 00 00 85 47 63 13 +F6 02 93 96 85 01 93 D7 85 01 D5 8F C1 66 13 D7 +85 00 93 86 06 F0 75 8F D9 8F A2 05 37 07 FF 00 +F9 8D DD 8D 0C C1 82 80 01 11 22 CC 26 CA 4A C8 +4E C6 52 C4 06 CE B7 04 02 50 2A 89 2E 8A B2 89 +EF D0 F0 25 03 A7 C4 07 91 47 2A 84 63 EE E7 28 +93 77 14 00 63 99 07 26 13 5F 34 40 93 57 14 40 +23 A0 F9 00 CA 86 D2 8E 93 0F 1F 00 01 4E 25 48 +89 45 0D 45 91 42 95 48 99 43 21 49 85 49 63 0C +CF 1F 83 C7 06 00 13 87 07 FD 13 76 F7 0F 63 6D +C8 1A 12 07 21 46 83 C7 16 00 13 83 07 FD 13 7A +F3 0F 63 70 48 03 13 83 F7 F9 13 73 F3 0F 63 F5 +68 1E 13 83 F7 FB 13 73 F3 0F 63 E6 68 16 13 83 +97 FC 33 67 67 00 63 01 B6 14 83 C7 26 00 13 83 +07 FD 13 7A F3 0F 63 70 48 03 13 83 F7 F9 13 73 +F3 0F 63 FE 68 1A 13 83 F7 FB 13 73 F3 0F 63 EC +68 12 13 83 97 FC 32 03 33 67 67 00 63 06 A6 10 +83 C7 36 00 13 83 07 FD 13 7A F3 0F 63 70 48 03 +13 83 F7 F9 13 73 F3 0F 63 F6 68 18 13 83 F7 FB +13 73 F3 0F 63 E1 68 10 13 83 97 FC 22 03 33 67 +67 00 63 0B 56 0C 83 C7 46 00 13 83 07 FD 13 7A +F3 0F 63 70 48 03 13 83 F7 F9 13 73 F3 0F 63 FE +68 14 13 83 F7 FB 13 73 F3 0F 63 E6 68 0C 13 83 +97 FC 52 03 33 67 67 00 63 00 16 0B 83 C7 56 00 +13 83 07 FD 13 7A F3 0F 63 70 48 03 13 83 F7 F9 +13 73 F3 0F 63 F6 68 12 13 83 F7 FB 13 73 F3 0F +63 EB 68 08 13 83 97 FC 42 03 33 67 67 00 63 05 +76 06 83 C7 66 00 13 83 07 FD 13 7A F3 0F 63 70 +48 03 13 83 F7 F9 13 73 F3 0F 63 FE 68 0E 13 83 +F7 FB 13 73 F3 0F 63 E0 68 06 13 83 97 FC 72 03 +33 67 67 00 63 1A 26 03 83 C7 76 00 13 86 07 FD +13 73 F6 0F 63 70 68 02 13 86 F7 F9 13 76 F6 0F +63 F6 C8 0C 13 86 F7 FB 13 76 F6 0F 63 E5 C8 02 +13 86 97 FC 62 06 51 8F 23 A0 EE 00 05 0E 91 0E +A1 06 E3 16 FE E7 F2 40 62 44 D2 44 42 49 B2 49 +22 4A 05 61 82 80 83 A6 C4 07 11 47 E3 75 D7 FE +62 44 F2 40 D2 44 42 49 B2 49 22 4A 19 65 BE 85 +13 05 C5 B3 05 61 41 B3 21 46 13 87 F7 F9 13 77 +F7 0F 63 FF E8 00 13 87 F7 FB 13 77 F7 0F E3 E4 +E8 FC 93 87 97 FC 13 97 47 00 E3 16 36 E3 69 BF +93 87 97 FA CD BF 13 76 74 00 49 DA 83 C7 06 00 +25 43 13 87 07 FD 13 7A F7 0F E3 60 43 FD 85 47 +12 07 E3 12 F6 E0 8D BF 13 83 97 FA 1D B5 13 83 +97 FA 91 BD 13 83 97 FA 51 B5 13 83 97 FA 55 BD +13 83 97 FA D5 B5 13 83 97 FA 11 BF 13 86 97 FA +62 06 51 8F 91 B7 03 A7 C4 07 91 47 E3 F5 E7 F4 +62 44 F2 40 D2 44 42 49 B2 49 22 4A 37 15 02 50 +13 05 C5 D8 05 61 C1 B1 AA 85 19 65 13 05 45 B2 +D9 39 B9 BB 79 71 22 D4 26 D2 4A D0 4E CE 52 CC +56 CA 06 D6 5A C8 5E C6 B7 09 02 50 2A 8A AE 8A +32 84 B6 84 EF D0 A0 78 03 A7 C9 07 89 47 2A 89 +63 E8 E7 2E 93 77 19 00 63 91 07 2C 13 5F 39 40 +93 57 19 40 56 86 52 88 D6 85 1C C0 93 02 1F 00 +81 46 25 43 09 45 8D 4F 91 43 15 4E 19 4A A1 4A +05 4B 63 02 DF 24 83 47 08 00 13 87 07 FD 93 78 +F7 0F 63 63 13 21 12 07 A1 48 83 47 18 00 93 8E +07 FD 93 FB FE 0F 63 70 73 03 93 8E F7 F9 93 FE +FE 0F 63 7C DE 23 93 8E F7 FB 93 FE FE 0F 63 6A +DE 1B 93 8E 97 FC 33 67 D7 01 63 82 A8 14 83 47 +28 00 93 8E 07 FD 93 FB FE 0F 63 70 73 03 93 8E +F7 F9 93 FE FE 0F 63 75 DE 21 93 8E F7 FB 93 FE +FE 0F 63 60 DE 19 93 8E 97 FC B2 0E 33 67 D7 01 +63 87 F8 11 83 47 38 00 93 8E 07 FD 93 FB FE 0F +63 70 73 03 93 8E F7 F9 93 FE FE 0F 63 7D DE 1D +93 8E F7 FB 93 FE FE 0F 63 65 DE 15 93 8E 97 FC +A2 0E 33 67 D7 01 63 8C 78 0C 83 47 48 00 93 8E +07 FD 93 FB FE 0F 63 70 73 03 93 8E F7 F9 93 FE +FE 0F 63 75 DE 1B 93 8E F7 FB 93 FE FE 0F 63 6A +DE 11 93 8E 97 FC D2 0E 33 67 D7 01 63 81 C8 0B +83 47 58 00 93 8E 07 FD 93 FB FE 0F 63 70 73 03 +93 8E F7 F9 93 FE FE 0F 63 7D DE 17 93 8E F7 FB +93 FE FE 0F 63 6F DE 0D 93 8E 97 FC C2 0E 33 67 +D7 01 63 86 48 07 83 47 68 00 93 8E 07 FD 93 FB +FE 0F 63 70 73 03 93 8E F7 F9 93 FE FE 0F 63 75 +DE 15 93 8E F7 FB 93 FE FE 0F 63 64 DE 0B 93 8E +97 FC F2 0E 33 67 D7 01 63 9B 58 03 83 47 78 00 +93 88 07 FD 93 FE F8 0F 63 70 D3 03 93 88 F7 F9 +93 F8 F8 0F 63 7D 1E 11 93 88 F7 FB 93 F8 F8 0F +63 69 1E 07 93 88 97 FC E2 08 33 67 17 01 98 C1 +85 06 91 05 21 08 E3 96 56 E6 85 47 63 90 F4 04 +1C 40 8D CF 41 68 81 45 13 08 08 F0 B7 08 FF 00 +1C 42 11 06 85 05 13 D7 87 01 13 95 87 01 93 D6 +87 00 49 8F B3 F6 06 01 A2 07 55 8F B3 F7 17 01 +D9 8F 23 2E F6 FE 1C 40 E3 EC F5 FC B2 50 22 54 +92 54 02 59 F2 49 62 4A D2 4A 42 4B B2 4B 45 61 +82 80 03 A7 C9 07 7D D3 22 54 B2 50 92 54 02 59 +F2 49 62 4A D2 4A 42 4B B2 4B 19 65 BE 85 13 05 +85 B7 45 61 6F F0 3F A6 A1 48 13 87 F7 F9 13 77 +F7 0F 63 7F EE 00 13 87 F7 FB 13 77 F7 0F E3 62 +EE FC 93 87 97 FC 13 97 47 00 E3 90 68 DF 81 BF +93 87 97 FA CD BF 93 78 79 00 E3 83 08 F4 83 47 +08 00 A5 4E 13 87 07 FD 93 7B F7 0F E3 EF 7E FB +85 47 12 07 E3 9B F8 DA 1D B7 93 8E 97 FA E1 BB +93 8E 97 FA 19 B5 93 8E 97 FA 1D BD 93 8E 97 FA +9D B5 93 8E 97 FA 59 BD 93 8E 97 FA D9 B5 93 88 +97 FA E2 08 33 67 17 01 DD BD 83 A7 C9 07 9D DF +22 54 B2 50 92 54 02 59 F2 49 62 4A D2 4A 42 4B +B2 4B 37 15 02 50 13 05 C5 D8 45 61 6F F0 BF 99 +AA 85 19 65 13 05 05 B6 EF F0 FF 9A 21 B3 29 CE +85 47 63 8D F6 00 0A 06 B3 07 C5 00 18 41 11 05 +91 05 23 AE E5 FE E3 9B A7 FE 82 80 93 16 26 00 +C1 68 AA 96 93 88 08 F0 37 03 FF 00 1C 41 91 05 +11 05 13 D7 87 01 13 98 87 01 13 D6 87 00 33 67 +07 01 33 76 16 01 A2 07 51 8F B3 F7 67 00 D9 8F +23 AE F5 FE E3 1C D5 FC 82 80 37 17 01 10 83 27 +47 08 85 8B ED DF 82 80 31 71 22 DD 26 DB 80 01 +4A D9 4E D7 52 D5 56 D3 5A D1 62 CD 66 CB 06 DF +5E CF 6A C9 6E C7 36 8C 03 43 2C 00 B4 4A 83 24 +CC 05 23 2A 64 F8 03 43 3C 00 83 47 0C 00 93 F8 +F4 00 23 24 64 F8 03 43 4C 04 13 F8 F6 00 23 26 +94 F6 23 20 64 F8 03 23 4C 05 23 22 F4 FA 23 20 +14 FB 23 2C 64 F8 03 23 8C 05 23 22 D4 F8 23 28 +04 F9 83 4D 5C 04 23 26 64 F8 03 23 4C 06 93 F7 +C6 FF BD 07 23 24 64 F6 03 23 0C 07 C1 9B 33 01 +F1 40 23 2C 64 F6 03 23 4C 07 03 2B 0C 06 03 4A +8C 06 23 2A 64 F6 03 23 8C 07 93 DC 44 00 93 D9 +46 00 23 28 64 F6 03 23 CC 07 B3 38 10 01 1C 08 +23 22 64 F6 03 43 0C 08 23 26 E4 FA 2A 89 23 24 +64 FA 33 33 00 01 AE 8A B2 84 9A 99 C6 9C 23 2E +F4 F8 37 17 01 10 83 27 47 08 85 8B ED DF 83 26 +C4 FA 37 0D 02 50 05 47 83 27 CD 07 E3 82 E6 44 +09 47 63 67 F7 50 B7 27 01 10 23 AA 07 92 37 17 +01 10 83 2B 47 08 93 FB 1B 00 E3 8C 0B FE 83 27 +44 FA 95 CB 03 47 1C 00 1D E7 37 26 01 10 83 27 +46 A0 85 8B ED DF 83 27 84 F8 13 97 17 00 13 77 +E7 03 13 67 17 00 23 20 E6 A0 37 26 01 10 83 27 +46 A0 89 8B ED DF 83 27 44 FA A2 04 13 77 39 00 +13 96 B7 00 93 F4 04 70 83 27 04 F8 D9 8C 13 97 +2A 00 D1 8C 13 77 F7 0F D9 8C E3 9D 07 3C 83 28 +CD 07 09 47 63 6E 17 29 37 17 01 10 83 27 44 F9 +64 DB 64 DB 89 EB 83 27 84 F8 63 89 07 46 37 27 +01 10 23 20 77 A1 93 07 00 02 63 8E FA 24 37 17 +01 10 83 27 47 08 85 8B ED DF 83 27 44 FA A5 EB +89 47 63 F4 17 01 6F 00 B0 71 03 27 4C 00 B7 17 +01 10 D8 C3 03 27 4C 02 D8 D3 03 27 8C 00 98 C7 +03 27 8C 02 98 D7 03 27 CC 00 D8 C7 03 27 CC 02 +D8 D7 03 27 0C 01 98 CB 03 27 0C 03 98 DB 03 27 +4C 01 D8 CB 03 27 4C 03 D8 DB 03 27 8C 01 98 CF +03 27 8C 03 98 DF 03 27 CC 01 D8 CF 03 27 CC 03 +D8 DF 03 27 0C 02 98 D3 03 27 0C 04 B8 C3 B7 17 +01 10 83 A6 47 08 85 8A ED DE 89 47 E3 E2 17 35 +03 27 CC 04 B7 17 01 10 13 06 00 02 0C 43 EC C3 +4C 43 AC C7 0C 47 EC C7 58 47 B8 CB E3 80 CA 20 +83 27 44 F8 63 8B 07 14 83 2C CC 06 85 47 E3 8B +FC 5E 63 8D 09 08 99 6C 93 87 4C B2 23 20 F4 FA +83 27 04 F9 83 2D 04 F8 81 4B FD 17 23 22 F4 F6 +83 27 C4 F8 23 2C 84 F7 23 26 04 F8 13 8B C7 00 +83 27 84 F9 5E 8C 23 20 D4 F6 93 8C C7 00 C1 67 +93 87 07 F0 23 2E F4 F8 85 67 93 87 07 80 DA 8B +23 2C F4 F8 66 8B 93 07 00 02 63 84 FA 16 37 17 +01 10 83 27 47 08 C1 8B ED DF 63 15 0A 18 89 47 +63 EF 17 37 05 47 63 00 E9 34 63 09 F9 18 63 88 +0D 1E 03 27 CD 07 63 00 0C 58 05 0C 83 28 CD 07 +C1 0B 41 0B E3 11 3C FD 03 2C 84 F7 83 27 04 F8 +CD C7 83 27 44 F9 D5 E3 89 47 63 F4 17 01 6F 10 +A0 0C 37 27 01 10 83 27 C7 A0 89 8B ED DF 89 44 +03 49 6C 04 63 F4 14 01 6F 10 40 0C 85 47 63 14 +F9 00 6F 10 60 31 37 25 01 10 13 05 C5 A0 EF 90 +60 53 95 A0 83 27 84 FA 03 2B 04 F7 83 25 44 F7 +13 85 F7 FF 13 35 15 00 CE 87 83 29 44 F6 2A C4 +5E C2 66 C0 A6 88 83 24 44 F8 03 25 84 F7 52 86 +DA 86 4E 87 26 88 EF B0 F0 7C 83 26 C4 F9 13 DA +24 00 81 47 26 87 01 46 5A 85 CE 85 EF B0 D0 07 +63 0B 0A 00 83 27 84 FA 63 14 99 01 6F 10 E0 18 +99 E3 6F 10 60 2E 83 28 CD 07 37 17 01 10 83 27 +47 08 85 8B ED DF 93 07 00 02 E3 85 FA 28 89 47 +E3 E9 17 41 B7 17 01 10 21 67 F8 DB F8 DB 19 47 +23 A0 E7 08 13 01 04 F4 FA 50 6A 54 DA 54 4A 59 +BA 59 2A 5A 9A 5A 0A 5B FA 4B 6A 4C DA 4C 4A 4D +BA 4D 29 61 82 80 37 17 01 10 83 27 47 08 85 8B +ED DF 93 07 10 40 23 24 F7 08 23 24 F7 08 41 BB +99 68 13 85 C8 BB A6 85 EF F0 EF D1 83 28 CD 07 +A1 BB 93 87 F9 FF 63 03 0C 6C E3 1A FC E8 83 27 +04 F9 E3 86 07 E8 93 95 67 00 93 E5 85 00 37 17 +01 10 83 27 47 08 85 8B ED DF 23 24 B7 08 23 24 +B7 08 B5 B5 64 5B 03 27 84 F9 89 47 B9 8C 63 E8 +17 1F 05 47 63 09 E9 1A 63 12 F9 04 03 27 CD 07 +91 4C 63 E0 EC 20 83 26 C4 FA 85 45 83 A7 4B FF +63 8A B6 5C 37 17 01 10 7C CB 03 A7 8B FF B7 17 +01 10 B8 CF 03 A7 CB FF B7 17 01 10 F8 CF 83 A7 +0B 00 37 17 01 10 3C D3 E3 0B 0A E2 B7 17 01 10 +03 27 CD 07 E4 DB E4 DB 89 47 E3 F2 E7 E2 B7 17 +02 50 13 85 87 EB EF F0 0F C5 E3 9C 0D E0 37 17 +01 10 83 27 47 08 A1 8B ED DF B7 07 03 30 83 A7 +C7 54 85 8B 95 CB 83 27 84 F7 83 26 44 FA 23 80 +D7 00 83 26 44 F9 23 81 D7 00 83 26 84 F8 A3 81 +D7 00 8C 43 B7 07 00 FF 93 87 F7 0F FD 8D B7 07 +00 10 85 07 63 89 F5 62 37 17 01 10 83 27 47 08 +91 8B 99 C7 83 27 84 FA 99 E3 6F 10 20 05 81 47 +37 17 01 10 83 25 CD 07 83 2C 47 06 0D 47 63 67 +B7 4A 03 27 C4 F8 93 08 F7 FF 13 87 F9 FF 46 8F +63 0E 87 21 63 93 07 24 85 45 63 03 B9 5A 89 45 +E3 0F B9 08 B7 15 01 10 03 25 CD 07 83 AC 85 06 +8D 45 63 E9 A5 48 FA 8F 63 04 87 1B 63 9D 07 1C +85 45 63 00 B9 5A 89 45 E3 02 B9 00 B7 15 01 10 +03 25 CD 07 83 AC C5 06 8D 45 63 E9 A5 48 FE 88 +63 01 87 25 63 98 07 26 85 45 63 0B B9 5A 89 45 +E3 08 B9 06 B7 15 01 10 03 25 CD 07 83 AC 05 07 +8D 45 63 E9 A5 12 63 02 87 27 63 93 07 28 85 47 +63 02 F9 60 89 47 E3 1A F9 D0 83 27 84 FA E3 96 +07 D0 83 27 0B 00 5A 87 B3 C7 FC 00 B3 F7 17 01 +E3 8D 07 CE E6 87 8D 45 6F 00 60 7B 8D 4B 41 BE +37 15 02 50 13 05 45 DE EF F0 EF B0 B7 27 01 10 +23 AA 07 92 ED B4 03 27 CD 07 91 4C 63 E6 EC 34 +83 26 C4 FA 85 45 83 27 4B FF 63 83 B6 28 37 17 +01 10 7C CB 03 27 8B FF B7 17 01 10 B8 CF 03 27 +CB FF B7 17 01 10 F8 CF 83 27 0B 00 99 BD 83 27 +04 FA E2 85 13 85 C7 21 EF F0 EF AD 85 47 E3 0C +F9 FA 89 47 E3 12 F9 E4 03 27 CD 07 91 4C E3 F4 +EC E0 83 27 04 FA 83 A5 4B FF 93 87 C7 23 3E 85 +23 2E F4 F6 EF F0 2F AB 83 26 C4 FA 85 45 03 27 +CD 07 83 A7 4B FF 63 8F B6 3A 37 13 01 10 23 2A +F3 04 E3 F4 EC DE 83 A5 8B FF 03 25 C4 F7 EF F0 +8F A8 03 A7 8B FF 83 27 CD 07 37 13 01 10 23 2C +E3 04 E3 F9 FC DC 83 A5 CB FF 03 25 C4 F7 EF F0 +8F A6 03 27 CD 07 83 A7 CB FF B7 15 01 10 FC CD +91 47 E3 FE E7 DA 83 A5 0B 00 03 25 C4 F7 EF F0 +8F A4 75 B3 23 2A F4 F6 83 27 04 FA E6 85 23 28 +14 F7 13 85 C7 29 23 2E E4 F6 EF F0 CF A2 03 27 +C4 F7 83 28 04 F7 83 27 44 F7 E3 18 87 EB 31 A2 +83 26 04 F9 E3 8C 06 E4 83 26 44 F8 93 F5 C6 00 +E3 86 05 E4 93 FF 86 00 E3 9B 0F 3E 93 F5 36 00 +83 26 04 F6 8E 05 05 4F 33 1F BF 00 23 26 D4 F8 +7D 1F E3 87 07 E2 83 26 84 FA E3 99 06 E2 B3 FC +EC 01 E3 85 0C E2 E6 87 85 45 91 A0 83 26 04 F9 +E3 82 06 DE 83 26 44 F8 13 FF C6 00 E3 14 0F 16 +93 F5 36 00 83 26 04 F6 8E 05 85 48 B3 98 B8 00 +23 26 D4 F8 FD 18 E3 81 07 DC 83 26 84 FA E3 93 +06 DC B3 FC 1C 01 E3 8F 0C DA E6 87 81 45 99 64 +93 84 44 B2 13 85 04 2B 23 26 F4 FA EF F0 AF 97 +83 27 C4 FA 13 85 84 2D BE 85 EF F0 CF 96 37 15 +02 50 13 05 85 F3 EF F0 0F 94 05 45 EF F0 AF 91 +01 A0 83 26 44 F6 A9 45 E3 EE D5 DA 83 26 44 F8 +93 F5 86 00 E3 88 05 DA 93 F5 36 00 83 26 04 F6 +8E 05 85 4F B3 9F BF 00 23 26 D4 F8 FD 1F 81 48 +E3 8C 07 D8 83 26 84 FA E3 9E 06 D8 B3 FC FC 01 +E3 8A 0C D8 E6 87 89 45 59 B7 83 26 04 F9 2D 47 +E3 7D D7 D8 03 27 44 F8 85 48 0D 8B 0E 07 B3 98 +E8 00 03 27 04 F6 FD 18 23 26 E4 F8 E3 81 07 D8 +83 27 84 FA E3 9B 07 A8 B3 FC 1C 01 E3 87 0C A8 +E6 87 8D 45 A9 B7 83 27 44 FA E3 80 07 A8 89 47 +63 E7 E7 02 B7 25 01 10 83 A7 45 A0 89 8B ED DF +83 26 44 F9 85 47 E3 8E F6 50 89 47 63 EC E7 7A +37 25 01 10 13 05 45 A0 EF 80 D0 7D B9 B4 37 15 +02 50 13 05 C5 F4 EF F0 0F 87 03 27 CD 07 D9 B7 +83 26 C4 F9 93 D5 87 01 93 98 87 01 13 D5 87 00 +75 8D B3 E5 15 01 C9 8D A2 07 37 05 FF 00 E9 8F +CD 8F B7 15 01 10 FC C9 91 47 63 ED E7 34 83 27 +8B FF 83 26 C4 F9 93 D5 87 01 93 98 87 01 13 D5 +87 00 75 8D B3 E5 15 01 C9 8D A2 07 37 05 FF 00 +E9 8F CD 8F B7 15 01 10 BC CD 91 47 63 E3 E7 30 +83 27 CB FF 83 26 C4 F9 93 D5 87 01 93 98 87 01 +13 D5 87 00 75 8D B3 E5 15 01 C9 8D A2 07 37 05 +FF 00 E9 8F CD 8F B7 15 01 10 FC CD 91 47 63 EB +E7 2A 83 27 0B 00 83 26 C4 F9 13 D7 87 01 13 95 +87 01 93 D5 87 00 F5 8D 49 8F 4D 8F A2 07 B7 05 +FF 00 ED 8F D9 8F 35 BE 83 25 4B FF 99 67 13 85 +87 D7 EF E0 5F FC 83 26 C4 FA 85 45 03 27 CD 07 +83 27 4B FF E3 86 B6 F2 B7 18 01 10 23 AA F8 04 +E3 F2 EC CA 83 25 8B FF 99 67 13 85 87 D7 EF E0 +9F F9 03 27 8B FF 83 27 CD 07 B7 18 01 10 23 AC +E8 04 E3 F6 FC C8 83 25 CB FF 99 67 13 85 87 D7 +EF E0 7F F7 03 27 CD 07 83 27 CB FF B7 15 01 10 +FC CD 91 47 E3 FA E7 C6 83 25 0B 00 99 67 13 85 +87 D7 EF E0 5F F5 83 27 0B 00 65 BC 23 2E F4 F6 +83 27 04 FA E6 85 13 85 C7 29 EF E0 DF F3 83 27 +C4 F7 81 B6 23 2A F4 F6 83 27 04 FA E6 85 23 28 +E4 F7 13 85 C7 29 23 2E E4 F6 EF E0 DF F1 03 2F +04 F7 83 27 44 F7 03 27 C4 F7 B1 B6 23 2A F4 F6 +83 27 04 FA E6 85 23 28 F4 F7 13 85 C7 29 23 2E +E4 F6 EF E0 5F EF 83 2F 04 F7 83 27 44 F7 03 27 +C4 F7 B1 B6 83 26 C4 F9 93 D5 87 01 93 98 87 01 +13 D5 87 00 75 8D B3 E5 15 01 C9 8D A2 07 37 05 +FF 00 E9 8F CD 8F B7 15 01 10 FC C9 91 47 63 E7 +E7 5A 83 A7 8B FF 83 26 C4 F9 93 D5 87 01 93 98 +87 01 13 D5 87 00 75 8D B3 E5 15 01 C9 8D A2 07 +37 05 FF 00 E9 8F CD 8F B7 15 01 10 BC CD 91 47 +63 E9 E7 54 83 A7 CB FF 83 26 C4 F9 93 D5 87 01 +93 98 87 01 13 D5 87 00 75 8D B3 E5 15 01 C9 8D +A2 07 37 05 FF 00 E9 8F CD 8F B7 15 01 10 FC CD +91 47 63 E0 E7 50 83 A7 0B 00 B1 BD 85 47 93 05 +80 40 E3 96 F9 94 83 27 04 F9 E3 82 07 94 25 BA +83 26 84 FA E3 90 06 A6 83 A5 4B FF B3 C5 BC 00 +B3 F5 15 01 E3 88 05 A4 E6 87 93 82 4B FF 81 45 +8D A0 83 26 84 FA E3 93 06 A6 83 A5 8B FF B3 C5 +BC 00 B3 F5 E5 01 E3 8B 05 A4 E6 87 93 82 8B FF +FA 88 85 45 3D A8 85 47 E3 98 FA 9C 83 27 47 08 +91 8B 89 E7 83 27 84 FA E3 88 07 3E 85 47 C9 BA +83 26 84 FA E3 98 06 A4 83 A5 CB FF B3 C5 BC 00 +B3 F5 F5 01 E3 80 05 A4 E6 87 93 82 CB FF FE 88 +89 45 99 64 93 84 44 B2 13 85 04 2F 23 24 54 FA +23 22 14 FB 23 26 F4 FA EF E0 FF D9 83 27 C4 FA +83 28 44 FA 13 85 84 31 B3 F5 F8 00 23 26 14 FB +EF E0 7F D8 83 22 84 FA 83 28 C4 FA 13 85 04 33 +83 A5 02 00 B3 F5 B8 00 EF E0 FF D6 05 45 EF E0 +9F D2 01 A0 83 27 84 FA 63 99 07 F0 83 A7 0B 00 +DE 82 B3 C7 FC 00 B3 F7 17 01 63 80 07 F0 E6 87 +8D 45 41 BF 83 25 0B 00 99 67 13 85 87 D7 EF E0 +9F D3 83 26 C4 FA 05 47 83 27 0B 00 E3 8D E6 D2 +49 B8 83 25 CB FF 99 67 13 85 87 D7 EF E0 BF D1 +83 26 C4 FA 85 45 03 27 CD 07 83 27 CB FF E3 83 +B6 CE 69 BB 83 25 8B FF 99 67 13 85 87 D7 EF E0 +9F CF 03 27 CD 07 83 27 8B FF 61 B9 83 27 C4 F6 +63 80 07 E0 63 8E 0C DE 03 27 04 FA 93 DF 27 00 +85 47 BA 9F 5A 8F 63 8B FC 72 13 06 40 40 C1 45 +99 67 93 87 47 B2 23 2E F4 F6 C1 67 0D 4B 93 87 +07 F0 23 2E 94 F4 23 2C 34 F5 E6 84 81 4D DA 8C +B7 1B 01 10 56 8B 23 20 F4 F6 CA 8A 23 2A D4 F4 +FE 89 7A 89 83 A7 4B 08 85 8B ED DF 89 47 63 E0 +17 67 23 A4 CB 08 23 A4 CB 08 83 A7 4B 08 C1 8B +ED DF 89 47 63 E5 17 5D 93 97 2D 00 63 E0 37 4F +23 AA 0B 04 93 87 EC FF 63 E4 37 43 23 AC 0B 04 +93 87 FC FF 63 F9 37 57 03 27 C4 FA 85 46 83 27 +89 00 63 0A D7 5C 23 AE FB 04 63 FC 3C 45 83 27 +C9 00 23 A0 FB 06 85 0D 41 09 91 0C 63 8A B4 45 +93 87 F4 FF 63 8C B7 5D 89 47 E3 F0 17 FB B7 17 +02 50 13 85 47 E3 EF E0 1F BF 83 28 CD 07 71 B7 +09 47 63 67 F7 5C B7 27 01 10 05 47 23 AA E7 92 +6F F0 EF BB 03 26 8C 04 37 25 01 10 EE 85 13 05 +85 A0 EF 80 50 40 83 28 CD 07 09 47 63 7E 17 C1 +99 68 EE 85 13 85 C8 B9 EF E0 FF BC 6F F0 2F C0 +37 15 02 50 13 05 45 E2 23 2E D4 F6 EF E0 BF B9 +83 28 CD 07 83 26 C4 F7 6F F0 8F CA 83 26 84 FA +63 9E 06 FE 83 25 8B FF B3 C5 BC 00 B3 F5 E5 01 +63 86 05 FE E6 87 13 07 8B FF FA 88 85 45 99 64 +93 84 44 B2 13 85 84 34 23 24 E4 FA 23 22 14 FB +23 26 F4 FA EF E0 3F B7 83 27 C4 FA 83 28 44 FA +13 85 04 37 B3 F5 F8 00 23 26 14 FB EF E0 BF B5 +03 27 84 FA 83 28 C4 FA 13 85 84 38 0C 43 B3 F5 +B8 00 EF E0 5F B4 05 45 EF E0 FF AF 01 A0 83 26 +84 FA 63 91 06 F6 83 25 4B FF B3 C5 BC 00 B3 F5 +15 01 63 89 05 F4 E6 87 13 07 4B FF 81 45 41 BF +83 26 84 FA 63 98 06 F8 83 25 CB FF B3 C5 BC 00 +B3 F5 F5 01 63 80 05 F8 E6 87 13 07 CB FF FE 88 +89 45 B5 B7 83 27 44 F9 63 9B 07 D6 03 25 C4 F6 +B7 05 FF 00 13 06 00 42 93 16 35 00 93 17 B5 00 +ED 8F 13 D9 86 00 93 D5 86 01 C1 66 23 24 C7 08 +CD 8F 93 86 06 F0 93 15 B5 01 33 79 D9 00 CD 8F +23 24 C7 08 11 47 33 69 F9 00 63 60 17 69 03 27 +C4 FA B7 17 01 10 23 AA 07 04 85 47 63 15 F7 02 +93 16 89 01 93 57 89 01 D5 8F C1 66 13 57 89 00 +93 86 06 F0 75 8F D9 8F 22 09 37 07 FF 00 33 79 +E9 00 33 E9 27 01 03 26 44 F8 B7 06 FF 00 93 17 +36 00 13 17 B6 00 75 8F 93 D6 87 01 93 D4 87 00 +B3 67 D7 00 41 67 13 07 07 F0 F9 8C 93 16 B6 01 +37 17 01 10 D5 8F 23 2C 27 05 11 47 DD 8C 63 6D +17 5F 03 27 C4 FA B7 17 01 10 23 AE 07 04 85 47 +63 13 F7 02 93 96 84 01 93 D7 84 01 D5 8F C1 66 +13 D7 84 00 93 86 06 F0 75 8F D9 8F A2 04 37 07 +FF 00 F9 8C DD 8C B7 17 01 10 A4 D3 37 17 01 10 +83 27 47 08 A1 8B ED DF 03 27 C4 FA 85 47 63 0E +F7 4E 83 25 84 F6 41 46 13 05 04 FB 23 26 14 FB +EF C0 00 26 83 28 C4 FA 89 47 63 E8 17 4B 83 27 +84 FA 63 90 07 44 B7 17 01 10 E4 53 83 27 04 FB +63 9F 97 7A B7 17 01 10 03 27 CD 07 A4 57 8D 47 +63 EB E7 68 83 27 44 FB 63 9A 97 74 37 19 01 10 +83 27 CD 07 83 24 C9 06 0D 4A 63 62 FA 64 83 27 +84 FB 99 68 93 88 48 B2 63 91 F4 78 83 24 09 07 +83 27 C4 FB 63 96 97 76 83 28 CD 07 89 47 63 FB +17 BF 37 15 02 50 13 05 85 01 EF E0 DF 93 6F F0 +6F BE 83 A5 0B 00 19 65 13 05 05 D6 EF E0 BF 94 +83 26 C4 FA 05 47 83 A7 0B 00 E3 86 E6 94 6F F0 +4F CA 83 A5 CB FF 19 65 93 07 05 D6 3E 85 23 2E +F4 F6 EF E0 5F 92 83 26 C4 FA 85 45 03 27 CD 07 +83 A7 CB FF E3 8A B6 A8 6F F0 2F EB 83 A5 8B FF +19 65 13 05 05 D6 EF E0 1F 90 03 27 CD 07 83 A7 +8B FF 91 B4 37 15 02 50 13 05 05 F8 EF E0 BF 8C +6F F0 1F 84 89 44 83 49 1C 08 63 ED 14 2D 63 84 +99 31 81 44 81 49 01 4A 83 47 2C 08 93 8B 0A FE +85 4C 93 BB 1B 00 63 97 97 AD 03 27 CD 07 89 47 +63 EE E7 48 85 47 3E C0 5E C2 03 27 44 F6 03 28 +44 F8 83 26 04 F7 03 25 84 F7 83 25 44 F7 CE 87 +A6 88 52 86 EF B0 00 38 13 07 40 06 B7 17 01 10 +83 A6 47 08 7D 17 F4 DB F4 DB 7D FB 37 15 02 50 +13 05 C5 E7 EF E0 3F 85 05 45 EF E0 DF 82 01 A0 +37 15 02 50 13 05 C5 E0 EF E0 FF 83 83 28 CD 07 +6F F0 AF 8D 46 8F 6F F0 EF C6 63 FB 17 01 83 25 +49 00 99 67 13 85 07 C4 EF E0 FF 83 83 28 CD 07 +03 27 C4 FA 85 46 83 27 49 00 63 05 D7 06 23 AC +FB 04 13 86 FC FF 8D 47 63 6A 36 0D 63 FD 17 13 +83 27 C4 F7 B2 85 13 85 87 0F EF E0 DF 80 83 28 +CD 07 23 AE 0B 04 8D 47 63 E1 3C 0F 63 FB 17 01 +83 27 C4 F7 E6 85 13 85 87 0F EF E0 CF FE 83 28 +CD 07 23 A0 0B 06 85 0D 41 09 91 0C E3 9A B4 BB +56 89 83 24 C4 F5 83 29 84 F5 83 26 44 F5 DA 8A +6F F0 0F 8E 03 27 04 F6 93 D6 87 01 93 95 87 01 +13 D6 87 00 79 8E CD 8E D1 8E A2 07 37 06 FF 00 +F1 8F D5 8F AD BF 63 FB 17 01 83 25 09 00 99 67 +13 85 07 C4 EF E0 2F F9 83 28 CD 07 03 27 C4 FA +85 46 83 27 09 00 63 0F D7 06 23 AA FB 04 13 86 +EC FF 8D 47 E3 63 36 F3 E3 FA 17 B1 83 27 C4 F7 +B2 85 13 85 87 0F EF E0 0F F6 83 28 CD 07 13 86 +FC FF 23 AC 0B 04 8D 47 E3 7A 36 F3 E3 FE 17 AF +83 25 89 00 99 67 13 85 07 C4 EF E0 CF F3 03 27 +C4 FA 85 46 83 28 CD 07 83 27 89 00 63 0D D7 0A +23 AE FB 04 8D 47 E3 F3 3C F3 63 F2 17 05 83 25 +C9 00 99 67 66 86 13 85 07 C4 EF E0 CF F0 83 28 +CD 07 35 A0 03 27 04 F6 93 D6 87 01 93 95 87 01 +13 D6 87 00 79 8E CD 8E D1 8E A2 07 37 06 FF 00 +F1 8F D5 8F 9D B7 23 AE 0B 04 E3 FC 3C EF 03 27 +C4 FA 85 46 83 27 C9 00 E3 1D D7 A8 03 27 04 F6 +93 D6 87 01 93 95 87 01 13 D6 87 00 79 8E CD 8E +D1 8E A2 07 37 06 FF 00 F1 8F D5 8F 9D BC 83 27 +C4 F7 EE 85 13 85 07 0E EF E0 EF E9 13 96 2D 00 +83 28 CD 07 8D 47 E3 68 36 EF E3 F3 17 A3 83 27 +C4 F7 B2 85 13 85 87 0F EF E0 EF E7 83 28 CD 07 +23 AA 0B 04 ED BD 03 27 04 F6 93 D6 87 01 93 95 +87 01 13 D6 87 00 79 8E CD 8E D1 8E A2 07 37 06 +FF 00 F1 8F D5 8F 23 AE FB 04 2D B7 83 27 04 FA +E3 84 07 A2 13 96 67 00 BE 85 13 66 46 00 5D B2 +37 15 02 50 13 05 05 DC EF E0 EF E0 2D B4 19 65 +13 05 C5 BD 23 28 C4 F4 EF E0 EF E1 03 26 04 F5 +83 28 CD 07 23 A4 CB 08 23 A4 CB 08 F5 B2 FA 8F +6F F0 CF A4 03 27 04 F7 83 26 44 F6 03 26 84 F7 +83 25 44 F7 99 68 13 85 48 C6 EF E0 CF DE E3 9A +99 D1 83 27 CD 07 63 F8 F4 00 37 15 02 50 13 05 +C5 E4 EF E0 4F DB D1 44 EF B0 10 47 13 7A F5 0F +EF B0 90 46 93 79 F5 0F EF B0 10 46 33 77 95 02 +B3 67 3A 01 85 8B D9 8F E5 D3 85 47 13 7A 1A 00 +93 F9 19 00 BA 84 23 24 F4 FA F9 B1 13 06 40 40 +C1 45 E3 07 07 8C 13 16 67 00 BA 85 13 66 46 00 +C1 B0 B7 17 01 10 FC 53 B7 19 01 10 83 27 CD 07 +83 A5 89 06 0D 49 63 6B F9 1E B7 17 01 10 FC 57 +B7 17 01 10 BC 5B CD BE 37 15 02 50 13 05 85 F9 +EF E0 6F D3 83 28 CD 07 6F E0 BF F2 37 15 02 50 +13 05 85 FB EF E0 2F D2 85 47 63 0D F9 22 83 27 +CD 07 63 E4 F4 00 6F E0 1F F3 37 15 02 50 13 05 +85 FE EF E0 4F D0 6F E0 1F F2 37 15 02 50 13 05 +C5 FF EF E0 4F CF 83 27 84 FA 03 27 CD 07 63 87 +07 22 B7 17 01 10 EC 53 8D 46 63 F5 E6 24 19 65 +13 05 85 EF EF E0 2F CF 85 BF 83 27 84 F6 41 6F +13 0F 0F F0 94 43 03 A8 47 00 88 47 DC 47 13 DE +86 01 93 95 86 01 93 D4 86 00 13 16 88 01 93 5A +88 01 93 53 88 00 13 5A 85 01 93 19 85 01 93 52 +85 00 13 D7 87 01 13 99 87 01 93 DE 87 00 B7 0F +FF 00 B3 E5 C5 01 B3 F4 E4 01 13 9E 86 00 33 66 +56 01 B3 F3 E3 01 22 08 B3 66 3A 01 B3 F2 E2 01 +22 05 33 67 27 01 B3 FE EE 01 A2 07 C5 8D 33 7E +FE 01 33 66 76 00 33 78 F8 01 B3 E6 56 00 33 75 +F5 01 33 67 D7 01 B3 F7 F7 01 B3 E5 C5 01 33 66 +06 01 C9 8E D9 8F 23 28 B4 FA 23 2A C4 FA 23 2C +D4 FA 23 2E F4 FA 8D BC 99 68 13 85 C8 ED A6 85 +EF E0 6F C3 83 28 CD 07 ED BA 99 68 13 85 48 EC +CA 85 EF E0 4F C2 83 28 CD 07 95 BA 37 15 02 50 +13 05 05 E6 EF E0 2F BF B1 BE 99 C3 6F E0 BF E7 +83 29 C4 F8 83 27 C4 F9 81 44 94 43 03 A7 09 00 +63 8A E6 04 19 69 13 09 49 B2 A6 85 13 05 C9 16 +EF E0 6F BE 03 27 C4 F9 93 97 24 00 13 05 49 19 +BA 97 8C 43 EF E0 2F BD 83 A5 09 00 13 05 C9 1A +EF E0 6F BC 05 45 EF E0 0F B8 01 A0 83 25 47 08 +19 65 13 05 05 D9 91 89 EF E0 EF BA 05 45 EF E0 +8F B6 01 A0 85 04 91 09 91 07 E3 10 9A FA 6F E0 +9F E0 89 47 63 E9 E7 0C 37 25 01 10 13 05 45 A0 +EF 80 60 31 83 28 CD 07 6F E0 3F DF 99 64 93 84 +84 EF 26 85 EF E0 2F B7 83 27 CD 07 83 A5 C9 06 +E3 70 F9 E0 26 85 EF E0 0F B6 83 27 CD 07 83 A5 +09 07 E3 73 F9 9E 26 85 EF E0 EF B4 F1 BA 99 68 +93 88 48 B2 93 89 48 3D A6 85 4E 85 23 26 14 FB +EF E0 6F B3 83 27 84 FB 83 28 C4 FA 63 97 97 12 +83 27 CD 07 83 24 09 07 E3 74 FA 9A A6 85 4E 85 +EF E0 6F B1 71 BA 99 68 A6 85 13 85 88 EF EF E0 +8F B0 8D B2 83 27 CD 07 63 F8 F4 00 37 15 02 50 +13 05 45 FD EF E0 2F AD 37 25 01 10 13 05 C5 A0 +EF 80 60 27 83 28 CD 07 6F E0 3F D5 B7 17 01 10 +E4 53 8D 47 E3 FC E7 90 99 68 A6 85 13 85 88 EF +EF E0 6F AC 21 B2 37 15 02 50 13 05 C5 F6 EF E0 +8F A9 1D B7 BC 57 91 B3 89 47 63 04 F9 00 6F E0 +9F D1 83 29 84 F9 83 27 C4 F9 81 44 83 A6 09 00 +98 43 63 8E E6 02 19 69 13 09 49 B2 A6 85 13 05 +49 1C EF E0 4F A8 03 27 C4 F9 93 97 24 00 13 05 +C9 1E BA 97 8C 43 EF E0 0F A7 83 A5 09 00 13 05 +49 20 EF E0 4F A6 05 45 EF E0 EF A1 01 A0 85 04 +91 09 91 07 E3 1C 9A FA 6F E0 FF CB 99 68 05 49 +93 88 48 B2 CA 85 13 85 08 3E 23 26 14 FB EF E0 +8F A3 83 28 C4 FA A6 85 13 85 48 40 EF E0 AF A2 +03 27 84 F6 93 17 29 00 83 28 C4 FA BA 97 8C 43 +13 85 C8 41 EF E0 2F A1 05 45 EF E0 CF 9C 01 A0 +99 68 0D 49 93 88 48 B2 75 BF 09 49 65 BF 99 68 +01 49 93 88 48 B2 7D B7 37 15 02 50 13 05 85 ED +EF E0 6F 9C 05 45 EF E0 0F 9A 01 A0 13 01 01 C9 +23 26 71 35 B7 0B 02 50 23 2A 51 35 83 AA CB 07 +23 24 81 36 23 22 91 36 23 20 21 37 23 2C 41 35 +23 28 61 35 2E CF 23 26 11 36 23 2E 31 35 23 24 +81 35 2A CD 89 45 32 84 36 8B 3A 8A 3E 89 C2 84 +63 EC 55 31 C1 47 63 F8 67 01 63 9A 0A 32 05 45 +EF E0 6F 94 01 A0 B7 08 02 50 93 85 88 10 BC 19 +93 88 88 10 13 88 05 04 03 A5 08 00 03 A6 48 00 +83 A6 88 00 03 A7 C8 00 88 C3 D0 C3 94 C7 D8 C7 +C1 08 C1 07 E3 92 08 FF B7 17 58 26 93 87 37 92 +3E D7 3E DF B7 47 63 94 93 87 F7 37 BE C5 B7 27 +2F FE 93 87 97 6E B7 D6 E2 95 BE C7 B7 D7 DC 33 +83 A8 05 05 93 86 B6 DA 93 87 37 85 03 AF 05 04 +83 AE 45 04 03 AE 85 04 03 A3 C5 04 03 A8 45 05 +A8 4D F0 4D 37 47 EA D5 36 D9 BE C9 B7 86 41 5B +B7 07 22 B3 13 07 27 D1 93 87 37 50 93 86 06 37 +3A D5 3A DD C6 D5 BE CB 36 DB 82 C1 82 C3 FA CD +F6 CF F2 D1 9A D3 C2 D7 AA D9 B2 DB 93 87 05 06 +38 1A 93 88 05 0A 03 A8 07 00 C8 43 90 47 D4 47 +23 20 07 01 48 C3 10 C7 54 C7 C1 07 41 07 E3 94 +17 FF 93 87 05 0A B8 1A 93 88 05 0E 03 A8 07 00 +C8 43 90 47 D4 47 23 20 07 01 48 C3 10 C7 54 C7 +C1 07 41 07 E3 94 17 FF 93 87 05 0E 38 1B 93 88 +05 12 03 A8 07 00 C8 43 90 47 D4 47 23 20 07 01 +48 C3 10 C7 54 C7 C1 07 41 07 E3 94 17 FF 93 88 +05 12 BC 1B 13 88 05 16 03 A5 08 00 03 A6 48 00 +83 A6 88 00 03 A7 C8 00 88 C3 D0 C3 94 C7 D8 C7 +C1 08 C1 07 E3 92 08 FF 93 88 05 16 3C 1C 13 88 +05 1A 03 A5 08 00 03 A6 48 00 83 A6 88 00 03 A7 +C8 00 88 C3 D0 C3 94 C7 D8 C7 C1 08 C1 07 E3 92 +08 FF 93 88 05 1A BC 1C 93 85 05 1E 03 A5 08 00 +03 A6 48 00 83 A6 88 00 03 A7 C8 00 88 C3 D0 C3 +94 C7 D8 C7 C1 08 C1 07 E3 92 B8 FE 13 06 80 08 +81 45 28 1D EF B0 30 1A 93 3B 19 00 C1 47 85 0B +63 82 F4 16 85 47 13 0C 81 17 63 81 F4 02 93 07 +00 02 63 88 F4 16 89 47 63 8A F4 16 91 47 63 83 +F4 18 A1 47 93 09 81 0A 63 83 F4 18 5E 57 23 22 +04 02 23 24 04 02 18 D0 4E 57 23 26 04 02 23 28 +04 02 58 CC 3E 57 23 2A 04 02 23 2C 04 02 18 CC +2E 57 23 2E 04 02 23 20 04 04 58 C8 1E 57 18 C8 +0E 57 58 C4 6E 47 58 C0 7E 47 18 C4 63 14 0B 00 +13 0B 00 04 89 47 63 E0 57 13 13 16 2B 00 63 0E +09 0C E2 85 52 85 EF B0 A0 7C BC 01 23 2E F1 30 +22 86 3C 1D 13 08 04 04 08 42 4C 42 14 46 58 46 +88 C3 CC C3 94 C7 D8 C7 41 06 C1 07 E3 16 06 FF +10 42 EA 46 7A 47 90 C3 BC 19 23 26 F1 30 85 47 +23 00 F1 32 23 22 31 31 23 24 61 31 23 28 81 31 +23 2E D1 2E 23 20 E1 30 3C 1D 0A 88 28 1E 8C 43 +D0 43 94 47 D8 47 23 20 B8 00 23 22 C8 00 23 24 +D8 00 23 26 E8 00 C1 07 41 08 E3 92 A7 FE 83 A8 +07 00 DC 43 8A 86 A6 85 5E 85 01 47 11 46 23 20 +18 01 23 22 F8 00 EF E0 2F D7 83 20 C1 36 03 24 +81 36 83 24 41 36 03 29 01 36 83 29 C1 35 03 2A +81 35 83 2A 41 35 03 2B 01 35 83 2B C1 34 03 2C +81 34 13 01 01 37 82 80 37 15 02 50 13 05 05 03 +EF D0 7F E5 83 AA CB 07 F1 B9 AC 19 52 85 EF B0 +20 6F 25 B7 93 09 81 0B 13 0C 81 27 C1 B5 19 65 +DA 85 13 05 85 F5 EF D0 1F E5 05 45 EF D0 BF E0 +D1 B1 93 09 81 0A 13 0C 81 13 4D B5 93 09 81 0A +13 0C 81 1B 61 BD 19 65 DA 85 13 05 05 FB EF D0 +9F E2 E1 BD 93 09 81 0A 13 0C 81 1F 41 B5 13 0C +81 23 AD BD 53 74 72 69 6E 67 20 6C 65 6E 67 74 +68 20 69 73 20 25 64 2E 0A 00 00 00 45 72 72 6F +72 3A 20 49 6E 76 61 6C 69 64 20 68 65 78 20 63 +68 61 72 61 63 74 65 72 3A 20 25 63 0A 00 00 00 +53 74 72 69 6E 67 20 6C 65 6E 67 74 68 20 69 73 +20 25 64 2E 0A 00 00 00 45 72 72 6F 72 3A 20 49 +6E 76 61 6C 69 64 20 68 65 78 20 63 68 61 72 61 +63 74 65 72 3A 20 25 63 0A 00 00 00 53 65 74 20 +41 45 53 20 4B 56 20 57 72 69 74 65 20 74 6F 20 +73 6C 6F 74 20 25 64 0A 00 00 00 00 57 72 69 74 +65 20 41 45 53 20 43 54 52 4C 20 77 69 74 68 20 +76 61 6C 75 65 20 30 78 25 78 0A 00 57 72 69 74 +65 20 47 43 4D 5F 41 41 44 20 50 68 61 73 65 2C +20 4E 55 4D 5F 42 59 54 45 53 20 30 78 25 78 0A +00 00 00 00 57 72 69 74 65 20 41 45 53 20 41 41 +44 20 42 6C 6F 63 6B 20 25 64 0A 00 50 61 64 64 +69 6E 67 20 41 41 44 20 77 69 74 68 20 30 73 20 +41 41 44 20 44 57 4F 52 44 3A 20 25 64 00 00 00 +57 72 69 74 65 20 49 6E 20 44 61 74 61 3A 20 30 +78 25 78 20 61 61 64 20 44 57 4F 52 44 3A 20 25 +64 0A 00 00 53 52 43 3A 20 7B 20 30 78 25 30 78 +5F 25 30 78 20 7D 20 74 6F 20 44 53 54 3A 20 7B +20 30 78 25 30 78 5F 25 30 78 20 7D 0A 00 00 00 +41 74 20 6F 66 66 73 65 74 20 5B 25 64 5D 2C 20 +6F 75 74 70 75 74 20 64 61 74 61 20 6D 69 73 6D +61 74 63 68 21 0A 00 00 41 63 74 75 61 6C 20 20 +20 64 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +45 78 70 65 63 74 65 64 20 64 61 74 61 3A 20 30 +78 25 78 0A 00 00 00 00 41 74 20 6F 66 66 73 65 +74 20 5B 25 64 5D 2C 20 6F 75 74 70 75 74 20 64 +61 74 61 20 6D 69 73 6D 61 74 63 68 21 0A 00 00 +41 63 74 75 61 6C 20 20 20 64 61 74 61 3A 20 30 +78 25 78 0A 00 00 00 00 45 78 70 65 63 74 65 64 +20 64 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +57 72 69 74 65 20 41 45 53 20 49 6E 70 75 74 20 +44 61 74 61 20 42 6C 6F 63 6B 20 25 64 0A 00 00 +57 72 69 74 65 20 49 6E 20 44 61 74 61 3A 20 30 +78 25 78 0A 00 00 00 00 57 72 69 74 65 20 49 6E +20 44 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +45 58 50 45 43 54 45 44 20 4F 55 54 50 55 54 5F +4C 4F 53 54 20 74 6F 20 62 65 20 30 78 30 20 2D +20 41 63 74 75 61 6C 3A 20 30 78 25 78 00 00 00 +43 49 50 48 45 52 54 45 58 54 3A 20 30 78 25 78 +0A 00 00 00 41 74 20 6F 66 66 73 65 74 20 5B 25 +64 5D 2C 20 6F 75 74 70 75 74 20 64 61 74 61 20 +6D 69 73 6D 61 74 63 68 21 0A 00 00 41 63 74 75 +61 6C 20 20 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 41 74 20 6F 66 66 73 65 74 20 5B 25 +64 5D 2C 20 6F 75 74 70 75 74 20 64 61 74 61 20 +6D 69 73 6D 61 74 63 68 21 0A 00 00 41 63 74 75 +61 6C 20 20 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 45 78 70 65 63 74 65 64 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 41 74 20 6F +66 66 73 65 74 20 5B 25 64 5D 2C 20 6F 75 74 70 +75 74 20 64 61 74 61 20 6D 69 73 6D 61 74 63 68 +21 0A 00 00 41 63 74 75 61 6C 20 20 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 45 78 70 65 +63 74 65 64 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 57 72 69 74 65 20 41 41 44 20 4C 65 +6E 67 74 68 3A 20 30 78 25 78 0A 00 57 72 69 74 +65 20 54 65 78 74 20 4C 65 6E 67 74 68 3A 20 30 +78 25 78 0A 00 00 00 00 54 41 47 3A 20 30 78 25 +78 0A 00 00 41 74 20 6F 66 66 73 65 74 20 5B 25 +64 5D 2C 20 74 61 67 20 64 61 74 61 20 6D 69 73 +6D 61 74 63 68 21 0A 00 41 63 74 75 61 6C 20 20 +20 64 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +45 78 70 65 63 74 65 64 20 64 61 74 61 3A 20 30 +78 25 78 0A 00 00 00 00 45 52 52 4F 52 3A 20 6F +76 65 72 72 69 64 65 5F 74 65 78 74 5F 6C 65 6E +67 74 68 20 28 25 64 29 20 65 78 63 65 65 64 73 +20 6D 61 78 69 6D 75 6D 20 61 6C 6C 6F 77 65 64 +20 73 69 7A 65 20 6F 66 20 31 36 20 64 77 6F 72 +64 73 20 28 35 31 32 20 62 69 74 73 29 0A 00 00 +50 6F 70 75 6C 61 74 65 20 4B 56 20 77 69 74 68 +20 6B 65 79 20 6C 65 6E 67 74 68 3A 20 25 64 0A +00 00 79 71 4A D0 37 09 02 50 03 28 C9 07 22 D4 +26 D2 4E CE 52 CC 56 CA 5A C8 06 D6 5E C6 89 48 +AA 8A 2E 8B 32 8A 36 84 BA 89 BE 84 63 E6 08 1B +83 A6 0A 00 B7 07 00 10 13 87 47 00 94 C3 83 A6 +4A 00 D4 C3 83 A7 8A 00 5C C3 83 A7 CA 00 1C C7 +93 16 24 00 93 F6 C6 07 93 E6 16 00 B7 07 00 10 +94 CB 37 04 00 10 54 48 89 8A F5 DE 8D 4A 63 EC +0A 11 83 26 0B 00 B7 07 00 10 13 87 47 00 94 C3 +83 26 4B 00 D4 C3 83 27 8B 00 5C C3 83 27 CB 00 +1C C7 13 97 29 00 13 77 C7 07 13 67 27 00 B7 07 +00 10 98 CB 37 04 00 10 58 48 09 8B 75 DF 8D 49 +63 E3 09 07 83 27 0A 00 37 07 00 10 93 06 47 00 +1C C3 03 26 4A 00 B7 07 03 30 83 A7 07 0E 50 C3 +03 27 8A 00 93 F7 07 04 D8 C2 03 27 CA 00 98 C6 +C1 C3 93 97 24 00 93 F7 C7 07 93 E7 07 08 37 07 +00 10 1C CB 5C 4B 89 8B F5 DF 8D 47 63 E7 07 15 +B2 50 22 54 92 54 02 59 F2 49 62 4A D2 4A 42 4B +B2 4B 45 61 82 80 37 15 02 50 13 05 45 10 EF D0 +9F 82 03 28 C9 07 E3 F7 09 F9 37 15 02 50 13 05 +45 13 EF D0 5F 81 83 27 0A 00 03 28 C9 07 1C C0 +83 26 4A 00 B7 07 03 30 83 A7 07 0E 54 C0 83 26 +8A 00 93 F7 07 04 14 C4 83 26 CA 00 54 C4 F9 EB +89 47 E3 FF 07 F9 37 15 02 50 13 05 C5 19 22 54 +B2 50 92 54 02 59 F2 49 62 4A D2 4A 42 4B B2 4B +45 61 6F D0 4F FC 37 15 02 50 13 05 C5 08 EF D0 +8F FB 03 28 C9 07 E3 FE 0A ED 37 15 02 50 13 05 +45 0B EF D0 4F FA 03 27 0B 00 03 28 C9 07 18 C0 +03 27 4B 00 58 C0 03 27 8B 00 18 C4 03 27 CB 00 +58 C4 E3 F8 0A ED 37 15 02 50 13 05 45 0D EF D0 +8F F7 03 28 C9 07 75 BD 37 15 02 50 13 05 45 04 +EF D0 6F F6 03 28 C9 07 8D 4B E3 F3 0B E5 37 15 +02 50 13 05 05 05 EF D0 0F F5 03 A7 0A 00 B7 07 +00 10 03 28 C9 07 98 C3 83 A6 4A 00 13 87 47 00 +D4 C3 83 A7 8A 00 5C C3 83 A7 CA 00 1C C7 E3 F9 +0B E3 37 15 02 50 13 05 45 06 EF D0 CF F1 03 28 +C9 07 39 BD E3 F7 09 EB 37 15 02 50 13 05 85 14 +EF D0 6F F0 03 28 C9 07 69 BD 37 15 02 50 13 05 +05 17 31 BF B7 07 02 50 03 A7 C7 07 8D 47 63 E7 +E7 00 B7 07 00 10 0D 47 98 CB 82 80 37 15 02 50 +41 11 13 05 05 1D 06 C6 EF D0 EF EC B2 40 B7 07 +00 10 0D 47 98 CB 41 01 82 80 00 00 41 11 22 C4 +37 04 02 50 03 27 C4 07 06 C6 89 47 63 E0 E7 04 +37 37 02 50 13 07 47 39 1C 47 54 47 D5 8F 9D E3 +73 00 50 10 93 07 40 06 01 00 FD 17 C2 07 C1 83 +E5 FF 1C 47 54 47 D5 8F E5 D7 83 26 C4 07 89 47 +63 E5 D7 02 B2 40 22 44 41 01 82 80 37 15 02 50 +13 05 45 1E EF D0 2F E6 37 37 02 50 13 07 47 39 +1C 47 54 47 D5 8F CD DF C9 BF 22 44 4C 47 B2 40 +10 47 21 65 13 05 C5 84 41 01 6F D0 CF E5 B7 07 +02 50 03 A7 C7 07 89 47 63 E7 E7 00 B7 87 00 10 +11 47 98 CB 82 80 37 15 02 50 41 11 13 05 C5 1F +06 C6 EF D0 4F E1 B2 40 B7 87 00 10 11 47 98 CB +41 01 82 80 79 71 26 D2 4A D0 56 CA 5A C8 06 D6 +22 D4 4E CE 52 CC 5E C6 83 4B 15 00 03 CA 06 00 +36 8B 3E 89 B2 86 BA 8A C2 84 B7 87 00 10 80 4F +05 88 75 DC 03 47 05 00 63 03 07 3C 13 97 1B 00 +13 77 E7 03 13 67 17 00 23 A4 E7 60 23 A0 07 08 +23 A2 07 08 23 A4 07 08 23 A6 07 08 23 A8 07 08 +23 AA 07 08 23 AC 07 08 23 AE 07 08 23 A0 07 0A +23 A2 07 0A 23 A4 07 0A 23 A6 07 0A 37 87 00 10 +83 27 C7 60 89 8B ED DF 63 0D 0A 00 83 47 1B 00 +37 87 00 10 86 07 93 F7 E7 03 93 E7 17 20 23 28 +F7 60 D8 41 B7 87 00 10 B7 09 02 50 23 A0 E7 50 +98 45 09 46 23 A2 E7 50 D8 45 23 A4 E7 50 98 49 +23 A6 E7 50 D8 49 23 A8 E7 50 98 4D 23 AA E7 50 +D8 4D 23 AC E7 50 98 51 23 AE E7 50 D8 51 23 A0 +E7 52 98 55 23 A2 E7 52 D8 55 23 A4 E7 52 98 59 +23 A6 E7 52 D8 42 23 A0 E7 48 98 46 23 A2 E7 48 +D8 46 23 A4 E7 48 98 4A 23 A6 E7 48 D8 4A 23 A8 +E7 48 98 4E 23 AA E7 48 D8 4E 23 AC E7 48 98 52 +23 AE E7 48 D8 52 23 A0 E7 4A 98 56 23 A2 E7 4A +D8 56 23 A4 E7 4A 98 5A 23 A6 E7 4A 03 A7 C9 07 +63 6B E6 30 B7 87 00 10 85 46 94 CB 63 93 0B 00 +0D 44 B7 87 00 10 23 A4 87 60 23 A0 07 08 23 A2 +07 08 23 A4 07 08 23 A6 07 08 23 A8 07 08 23 AA +07 08 23 AC 07 08 23 AE 07 08 23 A0 07 0A 23 A2 +07 0A 23 A4 07 0A 23 A6 07 0A 89 47 63 EE E7 2A +37 37 02 50 13 07 47 39 1C 47 54 47 D5 8F 91 EF +73 00 50 10 93 07 40 06 01 00 FD 17 C2 07 C1 83 +E5 FF 1C 47 54 47 D5 8F E5 D7 83 A7 C9 07 09 44 +63 6D F4 0A 63 1E 0A 0C B7 87 00 10 03 AA 07 18 +03 24 4B 00 63 1C 8A 2A 03 AA 47 18 03 24 8B 00 +63 15 8A 30 03 AA 87 18 03 24 CB 00 63 11 8A 30 +03 AA C7 18 03 24 0B 01 63 1D 8A 2E 03 AA 07 19 +03 24 4B 01 63 19 8A 2E 03 AA 47 19 03 24 8B 01 +63 15 8A 2E 03 AA 87 19 03 24 CB 01 63 11 8A 2E +03 AA C7 19 03 24 0B 02 63 1D 8A 2C 03 AA 07 1A +03 24 4B 02 63 13 8A 2E 03 AA 47 1A 03 24 8B 02 +63 1F 8A 2C 03 AA 87 1A 03 24 CB 02 63 15 8A 2C +03 AA C7 1A 03 24 0B 03 AD 45 63 1A 8A 22 85 47 +63 89 F4 04 B2 50 22 54 92 54 02 59 F2 49 62 4A +D2 4A 42 4B B2 4B 45 61 82 80 4C 47 10 47 21 65 +13 05 C5 84 EF D0 2F BA 83 A7 C9 07 63 0E 0A 1C +63 78 F4 00 37 15 02 50 13 05 C5 21 EF D0 AF B6 +37 87 00 10 83 27 47 61 89 8B ED DF 85 47 E3 9B +F4 FA 03 A7 C9 07 89 47 63 E1 E7 1C B7 87 00 10 +83 A4 07 20 03 A4 4A 00 63 99 84 20 83 A4 47 20 +03 A4 8A 00 63 99 84 22 83 A4 87 20 03 A4 CA 00 +63 95 84 22 83 A4 C7 20 03 A4 0A 01 63 91 84 22 +83 A4 07 21 03 A4 4A 01 63 9D 84 20 83 A4 47 21 +03 A4 8A 01 63 91 84 1E 83 A4 87 21 03 A4 CA 01 +63 99 84 2A 83 A4 C7 21 03 A4 0A 02 63 91 84 2A +83 A4 07 22 03 A4 4A 02 63 99 84 28 83 A4 47 22 +03 A4 8A 02 63 91 84 28 83 A4 87 22 03 A4 CA 02 +63 99 84 26 83 A4 C7 22 03 A4 0A 03 AD 45 63 97 +84 18 89 47 63 EC E7 16 B7 87 00 10 83 A4 07 28 +03 24 49 00 63 15 94 24 83 A4 47 28 03 24 89 00 +63 1D 94 22 83 A4 87 28 03 24 C9 00 63 15 94 22 +83 A4 C7 28 03 24 09 01 63 9D 84 20 83 A4 07 29 +03 24 49 01 63 95 84 20 83 A4 47 29 03 24 89 01 +63 9D 84 1E 83 A4 87 29 03 24 C9 01 63 95 84 1E +83 A4 C7 29 03 24 09 02 63 9D 84 1C 83 A4 07 2A +03 24 49 02 63 95 84 1C 83 A4 47 2A 03 24 89 02 +63 9D 84 1A 83 A4 87 2A 03 24 C9 02 63 95 84 1A +83 A4 C7 2A 03 24 09 03 AD 45 E3 8D 84 E6 83 A7 +C9 07 63 90 07 16 05 45 EF D0 EF 9E 01 A0 58 41 +23 A0 E7 08 18 45 23 A2 E7 08 58 45 23 A4 E7 08 +18 49 23 A6 E7 08 58 49 23 A8 E7 08 18 4D 23 AA +E7 08 58 4D 23 AC E7 08 18 51 23 AE E7 08 58 51 +23 A0 E7 0A 18 55 23 A2 E7 0A 58 55 23 A4 E7 0A +18 59 23 A6 E7 0A 89 B1 37 15 02 50 13 05 45 1E +EF D0 6F 9B 35 BB 37 15 02 50 13 05 05 21 EF D0 +8F 9A 03 A7 C9 07 F9 B9 E3 70 F4 D6 37 15 02 50 +13 05 05 23 EF D0 2F 99 81 BB 37 15 02 50 13 05 +C5 24 EF D0 4F 98 03 A7 C9 07 0D BD 81 45 83 A7 +C9 07 89 E7 05 45 EF D0 0F 95 01 A0 A1 64 93 84 +C4 84 13 85 44 03 EF D0 0F 98 83 A7 C9 07 FD D3 +D2 85 13 85 04 06 EF D0 0F 97 83 A7 C9 07 F9 DB +A2 85 13 85 84 07 EF D0 0F 96 E9 B7 37 15 02 50 +13 05 85 26 EF D0 2F 93 41 B5 81 45 39 E3 05 45 +EF D0 6F 90 01 A0 95 45 D5 BF 85 45 4D B7 89 45 +79 BF 8D 45 69 BF 91 45 59 BF 95 45 49 BF 99 45 +79 B7 9D 45 69 B7 85 45 D1 BF 89 45 C1 BF 8D 45 +F1 B7 91 45 E1 B7 A9 45 9D BF A1 45 8D BF A5 45 +BD B7 21 69 13 09 C9 84 13 05 09 09 EF D0 AF 8F +83 A7 C9 07 CD D7 A6 85 13 05 09 0C EF D0 AF 8E +83 A7 C9 07 C9 DF A2 85 13 05 89 0D EF D0 AF 8D +79 B7 21 69 13 09 C9 84 13 05 09 0F EF D0 AF 8C +83 A7 C9 07 E3 89 07 E8 A6 85 13 05 09 12 EF D0 +8F 8B 83 A7 C9 07 E3 80 07 E8 A2 85 13 05 89 13 +EF D0 6F 8A 8D BD A9 45 9D B5 A5 45 8D B5 A1 45 +B9 BD 9D 45 A9 BD 99 45 99 BD 95 45 89 BD 91 45 +B9 B5 8D 45 A9 B5 89 45 99 B5 85 45 89 B5 81 45 +3D BD A9 45 25 B7 A5 45 15 B7 A1 45 05 B7 9D 45 +31 BF 99 45 21 BF 79 71 4E CE 52 CC 5A C8 5E C6 +06 D6 22 D4 26 D2 4A D0 56 CA 83 CA 15 00 83 44 +07 00 BA 89 2A 8A B2 8B 36 8B B7 87 00 10 80 4F +05 88 75 DC 03 C7 05 00 63 0D 07 2C 13 97 1A 00 +13 77 E7 03 13 67 17 00 23 A0 E7 60 37 87 00 10 +83 27 47 60 89 8B ED DF 37 09 02 50 03 27 C9 07 +89 47 63 E3 E7 30 03 A6 4B 00 B7 87 00 10 89 46 +23 A0 C7 20 03 A6 8B 00 23 A2 C7 20 03 A6 CB 00 +23 A4 C7 20 03 A6 0B 01 23 A6 C7 20 03 A6 4B 01 +23 A8 C7 20 03 A6 8B 01 23 AA C7 20 03 A6 CB 01 +23 AC C7 20 03 A6 0B 02 23 AE C7 20 03 A6 4B 02 +23 A0 C7 22 03 A6 8B 02 23 A2 C7 22 03 A6 CB 02 +23 A4 C7 22 03 A6 0B 03 23 A6 C7 22 63 E7 E6 2C +83 26 4B 00 B7 87 00 10 23 A0 D7 28 83 26 8B 00 +23 A2 D7 28 83 26 CB 00 23 A4 D7 28 83 26 0B 01 +23 A6 D7 28 83 26 4B 01 23 A8 D7 28 83 26 8B 01 +23 AA D7 28 83 26 CB 01 23 AC D7 28 83 26 0B 02 +23 AE D7 28 83 26 4B 02 23 A0 D7 2A 83 26 8B 02 +23 A2 D7 2A 83 26 CB 02 23 A4 D7 2A 83 26 0B 03 +23 A6 D7 2A 83 26 4A 00 23 A0 D7 48 83 26 8A 00 +23 A2 D7 48 83 26 CA 00 23 A4 D7 48 83 26 0A 01 +23 A6 D7 48 83 26 4A 01 23 A8 D7 48 83 26 8A 01 +23 AA D7 48 83 26 CA 01 23 AC D7 48 83 26 0A 02 +23 AE D7 48 83 26 4A 02 23 A0 D7 4A 83 26 8A 02 +23 A2 D7 4A 83 26 CA 02 23 A4 D7 4A 83 26 0A 03 +23 A6 D7 4A 81 CC 83 C6 19 00 05 66 13 06 16 AC +86 06 93 F6 F6 0F D1 8E 23 A8 D7 60 89 47 63 ED +E7 1C B7 87 00 10 C1 46 94 CB 63 93 0A 00 0D 44 +B7 87 00 10 23 A0 87 60 23 A0 07 58 23 A2 07 58 +23 A4 07 58 23 A6 07 58 23 A8 07 58 23 AA 07 58 +23 AC 07 58 23 AE 07 58 23 A0 07 5A 23 A2 07 5A +23 A4 07 5A 23 A6 07 5A 89 47 63 E0 E7 18 37 37 +02 50 13 07 47 39 1C 47 54 47 D5 8F 91 EF 73 00 +50 10 93 07 40 06 01 00 FD 17 C2 07 C1 83 E5 FF +1C 47 54 47 D5 8F E5 D7 83 27 C9 07 09 44 63 69 +F4 0A E9 E8 B7 87 00 10 83 A4 07 5C 03 A4 49 00 +63 1F 94 16 83 A4 47 5C 03 A4 89 00 63 1B 94 1A +83 A4 87 5C 03 A4 C9 00 63 97 84 1A 83 A4 C7 5C +03 A4 09 01 63 93 84 1A 83 A4 07 5D 03 A4 49 01 +63 9F 84 18 83 A4 47 5D 03 A4 89 01 63 9B 84 18 +83 A4 87 5D 03 A4 C9 01 63 97 84 18 83 A4 C7 5D +03 A4 09 02 63 93 84 18 83 A4 07 5E 03 A4 49 02 +63 9F 84 16 83 A4 47 5E 03 A4 89 02 63 9B 84 16 +83 A4 87 5E 03 A4 C9 02 63 93 84 14 83 A4 C7 5E +03 A4 09 03 AD 45 63 9D 84 0E B2 50 22 54 92 54 +02 59 F2 49 62 4A D2 4A 42 4B B2 4B 45 61 82 80 +4C 47 10 47 21 65 13 05 C5 84 EF C0 DF D7 83 27 +C9 07 CD CC 63 78 F4 00 37 15 02 50 13 05 C5 21 +EF C0 7F D4 37 87 00 10 83 27 47 61 89 8B ED DF +6D BF D8 41 37 09 02 50 23 A0 E7 58 98 45 23 A2 +E7 58 D8 45 23 A4 E7 58 98 49 23 A6 E7 58 D8 49 +23 A8 E7 58 98 4D 23 AA E7 58 D8 4D 23 AC E7 58 +98 51 23 AE E7 58 D8 51 23 A0 E7 5A 98 55 23 A2 +E7 5A D8 55 23 A4 E7 5A 98 59 23 A6 E7 5A 03 27 +C9 07 89 47 E3 F1 E7 D0 37 15 02 50 13 05 45 28 +EF C0 7F CD 03 27 C9 07 FD B1 37 15 02 50 13 05 +45 1E EF C0 5F CC A5 BD 37 15 02 50 13 05 C5 2B +EF C0 7F CB 03 27 C9 07 29 BD 37 15 02 50 13 05 +05 2A EF C0 5F CA 03 27 C9 07 1D B3 E3 74 F4 E8 +37 15 02 50 13 05 C5 2C EF C0 FF C8 A5 BD 81 45 +83 27 C9 07 89 E7 05 45 EF C0 FF C5 01 A0 A1 69 +93 89 C9 84 13 85 09 15 EF C0 FF C8 83 27 C9 07 +FD D3 A6 85 13 85 09 18 EF C0 FF C7 83 27 C9 07 +F9 DB A2 85 13 85 89 19 EF C0 FF C6 E9 B7 A9 45 +C1 B7 85 45 75 BF 89 45 65 BF 8D 45 55 BF 91 45 +45 BF 95 45 75 B7 99 45 65 B7 9D 45 55 B7 A1 45 +45 B7 A5 45 71 BF 79 71 26 D2 4E CE 52 CC 5A C8 +5E C6 06 D6 22 D4 4A D0 56 CA 83 4A 15 00 BE 84 +AE 8B 32 8B B6 89 3A 8A B7 87 00 10 80 4F 05 88 +75 DC 83 46 05 00 37 09 02 50 03 27 C9 07 63 87 +06 32 89 47 63 E9 E7 38 93 96 1A 00 93 F6 E6 03 +B7 87 00 10 93 E6 16 00 23 A0 D7 60 23 A0 07 58 +23 A2 07 58 23 A4 07 58 23 A6 07 58 23 A8 07 58 +23 AA 07 58 23 AC 07 58 23 AE 07 58 23 A0 07 5A +23 A2 07 5A 23 A4 07 5A 23 A6 07 5A B7 86 00 10 +83 A7 46 60 89 8B ED DF 03 A6 4B 00 B7 87 00 10 +89 46 23 A0 C7 10 03 A6 8B 00 23 A2 C7 10 03 A6 +CB 00 23 A4 C7 10 03 A6 0B 01 23 A6 C7 10 03 A6 +4B 01 23 A8 C7 10 03 A6 8B 01 23 AA C7 10 03 A6 +CB 01 23 AC C7 10 03 A6 0B 02 23 AE C7 10 03 A6 +4B 02 23 A0 C7 12 03 A6 8B 02 23 A2 C7 12 03 A6 +CB 02 23 A4 C7 12 03 A6 0B 03 23 A6 C7 12 03 26 +4B 00 23 A0 C7 48 03 26 8B 00 23 A2 C7 48 03 26 +CB 00 23 A4 C7 48 03 26 0B 01 23 A6 C7 48 03 26 +4B 01 23 A8 C7 48 03 26 8B 01 23 AA C7 48 03 26 +CB 01 23 AC C7 48 03 26 0B 02 23 AE C7 48 03 26 +4B 02 23 A0 C7 4A 03 26 8B 02 23 A2 C7 4A 03 26 +CB 02 23 A4 C7 4A 03 26 0B 03 23 A6 C7 4A 63 E3 +E6 26 B7 87 00 10 89 46 94 CB 63 93 0A 00 0D 44 +B7 87 00 10 23 A0 87 60 23 A0 07 58 23 A2 07 58 +23 A4 07 58 23 A6 07 58 23 A8 07 58 23 AA 07 58 +23 AC 07 58 23 AE 07 58 23 A0 07 5A 23 A2 07 5A +23 A4 07 5A 23 A6 07 5A 89 47 63 E6 E7 20 37 37 +02 50 13 07 47 39 1C 47 54 47 D5 8F 91 EF 73 00 +50 10 93 07 40 06 01 00 FD 17 C2 07 C1 83 E5 FF +1C 47 54 47 D5 8F E5 D7 83 26 C9 07 09 44 63 60 +D4 02 85 47 63 83 F4 04 B2 50 22 54 92 54 02 59 +F2 49 62 4A D2 4A 42 4B B2 4B 45 61 82 80 4C 47 +10 47 21 65 13 05 C5 84 EF C0 FF A3 85 47 E3 9D +F4 FC 83 26 C9 07 63 7A D4 00 37 15 02 50 13 05 +C5 31 EF C0 5F A0 83 26 C9 07 B7 87 00 10 83 A4 +07 30 03 A4 49 00 63 99 84 1A 83 A4 47 30 03 A4 +89 00 63 9C 84 22 83 A4 87 30 03 A4 C9 00 63 9E +84 20 83 A4 C7 30 03 A4 09 01 63 9A 84 20 83 A4 +07 31 03 A4 49 01 63 96 84 20 83 A4 47 31 03 A4 +89 01 63 92 84 20 83 A4 87 31 03 A4 C9 01 63 90 +84 20 83 A4 C7 31 03 A4 09 02 63 9C 84 1E 83 A4 +07 32 03 A4 49 02 63 98 84 1C 83 A4 47 32 03 A4 +89 02 63 90 84 1C 83 A4 87 32 03 A4 C9 02 63 98 +84 1A 83 A4 C7 32 03 A4 09 03 AD 45 63 97 84 12 +89 47 63 E9 D7 12 B7 87 00 10 83 A4 07 38 03 24 +4A 00 63 94 84 18 83 A4 47 38 03 24 8A 00 63 1C +94 16 83 A4 87 38 03 24 CA 00 63 94 84 16 83 A4 +C7 38 03 24 0A 01 63 1C 94 14 83 A4 07 39 03 24 +4A 01 63 94 84 14 83 A4 47 39 03 24 8A 01 63 9C +84 12 83 A4 87 39 03 24 CA 01 63 94 84 12 83 A4 +C7 39 03 24 0A 02 63 9C 84 10 83 A4 07 3A 03 24 +4A 02 63 94 84 10 83 A4 47 3A 03 24 8A 02 63 9C +84 0E 83 A4 87 3A 03 24 CA 02 63 94 84 0E 83 A4 +C7 3A 03 24 0A 03 AD 45 E3 88 84 E8 83 27 C9 07 +63 93 07 12 05 45 EF C0 1F 8A 01 A0 54 41 23 A0 +D7 58 14 45 23 A2 D7 58 54 45 23 A4 D7 58 14 49 +23 A6 D7 58 54 49 23 A8 D7 58 14 4D 23 AA D7 58 +54 4D 23 AC D7 58 14 51 23 AE D7 58 54 51 23 A0 +D7 5A 14 55 23 A2 D7 5A 54 55 23 A4 D7 5A 14 59 +23 A6 D7 5A D5 B1 37 15 02 50 13 05 45 1E EF C0 +9F 86 F5 B3 37 15 02 50 13 05 C5 30 EF C0 BF 85 +03 27 C9 07 79 B3 37 15 02 50 13 05 C5 2E EF C0 +9F 84 03 27 C9 07 8D B1 81 45 81 EE 05 45 EF C0 +9F 81 01 A0 37 15 02 50 13 05 85 33 EF C0 BF 82 +D9 B5 A1 69 93 89 C9 84 13 85 09 1B EF C0 BF 83 +83 27 C9 07 E1 DF A6 85 13 85 C9 1D EF C0 BF 82 +83 27 C9 07 E1 D7 A2 85 13 85 49 1F EF C0 BF 81 +75 BF A9 45 25 B7 A5 45 15 B7 A1 45 05 B7 9D 45 +31 BF 99 45 21 BF 95 45 11 BF 91 45 01 BF 8D 45 +31 B7 89 45 21 B7 85 45 11 B7 81 45 01 B7 A9 45 +69 B7 A5 45 59 B7 A1 45 49 B7 89 45 BD BF 8D 45 +AD BF 91 45 9D BF 95 45 8D BF 85 45 BD B7 99 45 +AD B7 9D 45 9D B7 A1 69 93 89 C9 84 13 85 C9 20 +EF C0 6F FB 83 27 C9 07 E3 86 07 EC A6 85 13 85 +89 23 EF C0 4F FA 83 27 C9 07 E3 8D 07 EA A2 85 +13 85 09 25 EF C0 2F F9 75 B5 01 11 22 CC 26 CA +06 CE 4A C8 4E C6 B6 84 37 84 00 10 1C 4C 85 8B +F5 DF 5C 41 B7 09 02 50 09 49 23 20 F4 10 1C 45 +23 22 F4 10 5C 45 23 24 F4 10 1C 49 23 26 F4 10 +5C 49 23 28 F4 10 1C 4D 23 2A F4 10 5C 4D 23 2C +F4 10 1C 51 23 2E F4 10 5C 51 23 20 F4 12 1C 55 +23 22 F4 12 5C 55 23 24 F4 12 1C 59 23 26 F4 12 +DC 41 23 20 F4 20 9C 45 23 22 F4 20 DC 45 23 24 +F4 20 9C 49 23 26 F4 20 DC 49 23 28 F4 20 9C 4D +23 2A F4 20 DC 4D 23 2C F4 20 9C 51 23 2E F4 20 +DC 51 23 20 F4 22 9C 55 23 22 F4 22 DC 55 23 24 +F4 22 9C 59 23 26 F4 22 5C 42 23 20 F4 28 1C 46 +23 22 F4 28 5C 46 23 24 F4 28 1C 4A 23 26 F4 28 +5C 4A 23 28 F4 28 1C 4E 23 2A F4 28 5C 4E 23 2C +F4 28 1C 52 23 2E F4 28 5C 52 23 20 F4 2A 1C 56 +23 22 F4 2A 5C 56 23 24 F4 2A 1C 5A 23 26 F4 2A +DC 40 23 20 F4 30 9C 44 23 22 F4 30 DC 44 23 24 +F4 30 9C 48 23 26 F4 30 DC 48 23 28 F4 30 9C 4C +23 2A F4 30 DC 4C 23 2C F4 30 9C 50 23 2E F4 30 +DC 50 23 20 F4 32 9C 54 23 22 F4 32 DC 54 23 24 +F4 32 9C 58 23 26 F4 32 5C 43 23 20 F4 38 1C 47 +23 22 F4 38 5C 47 23 24 F4 38 1C 4B 23 26 F4 38 +5C 4B 23 28 F4 38 1C 4F 23 2A F4 38 5C 4F 23 2C +F4 38 1C 53 23 2E F4 38 5C 53 23 20 F4 3A 1C 57 +23 22 F4 3A 5C 57 23 24 F4 3A 1C 5B 23 26 F4 3A +83 A7 C9 07 63 6E F9 0E 8D 47 1C C8 37 37 02 50 +13 07 47 39 1C 47 54 47 D5 8F 9D E3 73 00 50 10 +93 07 40 06 01 00 FD 17 C2 07 C1 83 E5 FF 1C 47 +54 47 D5 8F E5 D7 83 A7 C9 07 09 44 63 60 F4 0A +B7 87 00 10 03 A9 07 40 C0 40 63 11 24 09 03 A9 +47 40 80 44 63 1C 89 10 03 A9 87 40 C0 44 63 15 +89 10 03 A9 C7 40 80 48 63 16 24 11 03 A9 07 41 +C0 48 63 1F 89 0E 03 A9 47 41 80 4C 63 1E 89 0E +03 A9 87 41 C0 4C 63 11 89 10 03 A9 C7 41 80 50 +63 16 89 0E 03 A9 07 42 C0 50 63 19 89 0E 03 A9 +47 42 80 54 63 1E 89 0C 03 A9 87 42 C0 54 63 1B +89 0C 03 A9 C7 42 80 58 AD 45 63 1A 89 00 F2 40 +62 44 D2 44 42 49 B2 49 05 61 82 80 81 45 83 A7 +C9 07 BD E3 05 45 EF C0 0F CF 01 A0 4C 47 10 47 +21 65 13 05 C5 84 EF C0 0F D2 83 A7 C9 07 E3 79 +F4 F4 37 15 02 50 13 05 45 36 EF C0 CF CE 89 B7 +37 15 02 50 13 05 45 35 EF C0 EF CD 83 A7 C9 07 +0D 47 18 C8 E3 7C F9 EE 37 15 02 50 13 05 45 1E +EF C0 6F CC 37 37 02 50 13 07 47 39 1C 47 54 47 +D5 8F E3 85 07 EE 01 B7 A1 64 93 84 C4 84 13 85 +84 26 EF C0 4F CC 83 A7 C9 07 C9 D7 CA 85 13 85 +84 29 EF C0 4F CB 83 A7 C9 07 AD DF A2 85 13 85 +04 2B EF C0 4F CA BD B7 89 45 95 B7 85 45 85 B7 +91 45 B1 BF 8D 45 A1 BF 95 45 91 BF 9D 45 81 BF +A5 45 B1 B7 A9 45 A1 B7 99 45 91 B7 A1 45 81 B7 +01 11 22 CC 4E C6 52 C4 06 CE 26 CA 4A C8 2A 87 +AE 89 32 8A 37 84 00 10 1C 4C 85 8B F5 DF 5C 43 +37 09 02 50 89 44 23 20 F4 48 1C 47 23 22 F4 48 +5C 47 23 24 F4 48 1C 4B 23 26 F4 48 5C 4B 23 28 +F4 48 1C 4F 23 2A F4 48 5C 4F 23 2C F4 48 1C 53 +23 2E F4 48 5C 53 23 20 F4 4A 1C 57 23 22 F4 4A +5C 57 23 24 F4 4A 1C 5B 23 26 F4 4A 83 27 C9 07 +63 E5 F4 1E A9 47 1C C8 93 07 F0 03 23 20 F4 60 +23 20 04 58 23 22 04 58 23 24 04 58 23 26 04 58 +23 28 04 58 23 2A 04 58 23 2C 04 58 23 2E 04 58 +23 20 04 5A 23 22 04 5A 23 24 04 5A 23 26 04 5A +37 37 02 50 13 07 47 39 1C 47 54 47 D5 8F 91 EF +73 00 50 10 93 07 40 06 01 00 FD 17 C2 07 C1 83 +E5 FF 1C 47 54 47 D5 8F E5 D7 83 26 C9 07 09 44 +63 69 D4 14 B7 87 00 10 83 A4 07 30 03 A4 49 00 +63 9B 84 12 83 A4 47 30 03 A4 89 00 63 91 84 24 +83 A4 87 30 03 A4 C9 00 63 99 84 22 83 A4 C7 30 +03 A4 09 01 63 99 84 22 83 A4 07 31 03 A4 49 01 +63 91 84 22 83 A4 47 31 03 A4 89 01 63 97 84 24 +83 A4 87 31 03 A4 C9 01 63 9D 84 22 83 A4 C7 31 +03 A4 09 02 63 95 84 22 83 A4 07 32 03 A4 49 02 +63 9D 84 20 83 A4 47 32 03 A4 89 02 63 91 84 22 +83 A4 87 32 03 A4 C9 02 63 91 84 1E 83 A4 C7 32 +03 A4 09 03 AD 45 63 99 84 0A 89 47 63 E8 D7 1A +B7 87 00 10 83 A4 07 38 03 24 4A 00 63 16 94 12 +83 A4 47 38 03 24 8A 00 63 1B 94 1A 83 A4 87 38 +03 24 CA 00 63 97 84 1A 83 A4 C7 38 03 24 0A 01 +63 93 84 1A 83 A4 07 39 03 24 4A 01 63 9F 84 18 +83 A4 47 39 03 24 8A 01 63 9B 84 18 83 A4 87 39 +03 24 CA 01 63 97 84 18 83 A4 C7 39 03 24 0A 02 +63 93 84 18 83 A4 07 3A 03 24 4A 02 63 9B 84 18 +83 A4 47 3A 03 24 8A 02 63 97 84 18 83 A4 87 3A +03 24 CA 02 63 99 84 16 83 A4 C7 3A 03 24 0A 03 +AD 45 63 94 84 0A F2 40 62 44 D2 44 42 49 B2 49 +22 4A 05 61 82 80 81 45 E1 EA 05 45 EF C0 AF A0 +01 A0 4C 47 10 47 21 65 13 05 C5 84 EF C0 AF A3 +83 26 C9 07 E3 70 D4 EA 37 15 02 50 13 05 C5 31 +EF C0 6F A0 83 26 C9 07 71 B5 37 15 02 50 13 05 +05 38 EF C0 4F 9F 29 47 83 27 C9 07 18 C8 13 07 +F0 03 23 20 E4 60 23 20 04 58 23 22 04 58 23 24 +04 58 23 26 04 58 23 28 04 58 23 2A 04 58 23 2C +04 58 23 2E 04 58 23 20 04 5A 23 22 04 5A 23 24 +04 5A 23 26 04 5A E3 F5 F4 E0 37 15 02 50 13 05 +45 1E EF C0 4F 9A ED BB 81 45 83 27 C9 07 89 E7 +05 45 EF C0 4F 97 01 A0 A1 69 93 89 C9 84 13 85 +49 32 EF C0 4F 9A 83 27 C9 07 FD D3 A6 85 13 85 +09 35 EF C0 4F 99 83 27 C9 07 F9 DB A2 85 13 85 +89 36 EF C0 4F 98 E9 B7 A1 69 93 89 C9 84 13 85 +89 2C EF C0 4F 97 83 27 C9 07 E3 80 07 F2 A6 85 +13 85 49 2F EF C0 2F 96 83 27 C9 07 E3 87 07 F0 +A2 85 13 85 C9 30 EF C0 0F 95 01 B7 37 15 02 50 +13 05 85 33 EF C0 2F 92 A1 B5 89 45 F5 B5 85 45 +E5 B5 91 45 D5 B5 8D 45 C5 B5 A9 45 F1 BD 85 45 +AD B7 89 45 9D B7 8D 45 8D B7 91 45 B9 BF 95 45 +A9 BF 99 45 99 BF 9D 45 89 BF A1 45 75 BD 9D 45 +65 BD 99 45 55 BD A9 45 89 B7 95 45 75 B5 A5 45 +65 B5 A1 45 1D BF A5 45 0D BF 01 00 52 65 63 65 +69 76 65 64 20 45 43 43 20 6E 6F 74 69 66 2F 20 +65 72 72 20 69 6E 74 72 20 77 69 74 68 20 73 74 +61 74 75 73 20 3D 20 25 64 2F 20 25 64 0A 00 00 +41 74 20 6F 66 66 73 65 74 20 5B 25 64 5D 2C 20 +65 63 63 5F 70 72 69 76 6B 65 79 20 64 61 74 61 +20 6D 69 73 6D 61 74 63 68 21 0A 00 41 63 74 75 +61 6C 20 20 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 45 78 70 65 63 74 65 64 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 41 74 20 6F +66 66 73 65 74 20 5B 25 64 5D 2C 20 65 63 63 5F +70 75 62 6B 65 79 5F 78 20 64 61 74 61 20 6D 69 +73 6D 61 74 63 68 21 0A 00 00 00 00 41 63 74 75 +61 6C 20 20 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 45 78 70 65 63 74 65 64 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 41 74 20 6F +66 66 73 65 74 20 5B 25 64 5D 2C 20 65 63 63 5F +70 75 62 6B 65 79 5F 79 20 64 61 74 61 20 6D 69 +73 6D 61 74 63 68 21 0A 00 00 00 00 41 63 74 75 +61 6C 20 20 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 45 78 70 65 63 74 65 64 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 41 74 20 6F +66 66 73 65 74 20 5B 25 64 5D 2C 20 65 63 63 5F +73 68 61 72 65 64 6B 65 79 20 64 61 74 61 20 6D +69 73 6D 61 74 63 68 21 0A 00 00 00 41 63 74 75 +61 6C 20 20 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 45 78 70 65 63 74 65 64 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 41 74 20 6F +66 66 73 65 74 20 5B 25 64 5D 2C 20 65 63 63 5F +73 69 67 6E 5F 72 20 64 61 74 61 20 6D 69 73 6D +61 74 63 68 21 0A 00 00 41 63 74 75 61 6C 20 20 +20 64 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +45 78 70 65 63 74 65 64 20 64 61 74 61 3A 20 30 +78 25 78 0A 00 00 00 00 41 74 20 6F 66 66 73 65 +74 20 5B 25 64 5D 2C 20 65 63 63 5F 73 69 67 6E +5F 73 20 64 61 74 61 20 6D 69 73 6D 61 74 63 68 +21 0A 00 00 41 63 74 75 61 6C 20 20 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 45 78 70 65 +63 74 65 64 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 41 74 20 6F 66 66 73 65 74 20 5B 25 +64 5D 2C 20 65 63 63 5F 76 65 72 69 66 79 5F 72 +20 64 61 74 61 20 6D 69 73 6D 61 74 63 68 21 0A +00 00 00 00 41 63 74 75 61 6C 20 20 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 45 78 70 65 +63 74 65 64 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 41 74 20 6F 66 66 73 65 74 20 5B 25 +64 5D 2C 20 65 63 63 5F 73 69 67 6E 5F 72 20 64 +61 74 61 20 6D 69 73 6D 61 74 63 68 21 0A 00 00 +41 63 74 75 61 6C 20 20 20 64 61 74 61 3A 20 30 +78 25 78 0A 00 00 00 00 45 78 70 65 63 74 65 64 +20 64 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +41 74 20 6F 66 66 73 65 74 20 5B 25 64 5D 2C 20 +65 63 63 5F 73 69 67 6E 5F 73 20 64 61 74 61 20 +6D 69 73 6D 61 74 63 68 21 0A 00 00 41 63 74 75 +61 6C 20 20 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 45 78 70 65 63 74 65 64 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 41 11 22 C4 +37 04 02 50 03 27 C4 07 06 C6 89 47 63 E0 E7 04 +37 37 02 50 13 07 47 39 3C 43 74 43 D5 8F 9D E3 +73 00 50 10 93 07 40 06 01 00 FD 17 C2 07 C1 83 +E5 FF 3C 43 74 43 D5 8F E5 D7 83 26 C4 07 89 47 +63 E5 D7 02 B2 40 22 44 41 01 82 80 37 15 02 50 +13 05 45 39 EF B0 3F CF 37 37 02 50 13 07 47 39 +3C 43 74 43 D5 8F CD DF C9 BF 22 44 6C 43 B2 40 +30 43 25 65 13 05 45 3B 41 01 6F B0 DF CE 41 11 +26 C2 B7 04 02 50 83 A7 C4 07 22 C4 06 C6 09 44 +63 60 F4 02 B7 07 03 10 21 47 98 CB 37 07 03 10 +5C 4B 85 8B F5 DF B2 40 22 44 92 44 41 01 82 80 +37 15 02 50 13 05 05 3B EF B0 FF C8 83 A7 C4 07 +37 07 03 10 A1 46 14 CB E3 7A F4 FC 37 15 02 50 +13 05 45 3C EF B0 3F C7 D1 B7 19 CA 0A 06 33 87 +C5 00 9C 41 91 05 11 05 23 2E F5 FE E3 9B E5 FE +82 80 79 71 4E CE B7 09 02 50 03 A7 C9 07 26 D2 +4A D0 5A C8 5E C6 06 D6 22 D4 52 CC 56 CA 89 47 +AA 8B 2E 8B B2 84 36 89 63 E3 E7 20 B7 07 03 10 +C0 4B 05 88 75 DC 03 CA 0B 00 83 C6 2B 00 63 09 +0A 16 93 97 16 00 93 F7 E7 03 93 E7 17 00 B7 86 +03 10 9C C2 89 47 63 E3 E7 28 B7 07 03 10 23 AC +07 04 23 AE 07 04 23 A0 07 06 23 A2 07 06 23 A4 +07 06 23 A6 07 06 23 A8 07 06 23 AA 07 06 B7 86 +03 10 DC 42 89 8B F5 DF 03 C6 1B 00 85 47 63 19 +F6 14 DC 42 93 F7 C7 3F 63 84 07 2C 89 47 63 E6 +E7 2C 83 26 0B 00 B7 0A 03 10 89 47 23 AC DA 00 +83 26 4B 00 23 AE DA 00 83 26 8B 00 23 A0 DA 02 +83 26 CB 00 23 A2 DA 02 83 26 0B 01 23 A4 DA 02 +83 26 4B 01 23 A6 DA 02 83 26 8B 01 23 A8 DA 02 +83 26 CB 01 23 AA DA 02 83 26 0B 02 23 AC DA 02 +83 26 4B 02 23 AE DA 02 83 26 8B 02 23 A0 DA 04 +83 26 CB 02 23 A2 DA 04 83 26 0B 03 23 A4 DA 04 +83 26 4B 03 23 A6 DA 04 83 26 8B 03 23 A8 DA 04 +83 26 CB 03 23 AA DA 04 63 ED E7 16 85 47 23 A8 +FA 00 03 C7 2B 00 63 07 07 0E 37 87 03 10 1C C3 +37 37 02 50 13 07 47 39 34 43 7C 43 D5 8F 91 EF +73 00 50 10 93 07 40 06 01 00 FD 17 C2 07 C1 83 +E5 FF 3C 43 74 43 D5 8F E5 D7 03 A5 C9 07 09 44 +63 64 A4 08 63 16 0A 0C B7 46 03 10 26 84 81 45 +85 8E 13 06 80 4C 39 A0 93 95 07 01 C1 81 11 04 +63 88 C5 0C B3 87 86 00 84 43 18 40 93 87 15 00 +E3 04 97 FE 63 15 05 14 05 45 EF B0 DF A8 01 A0 +83 A6 4B 00 B4 CF 83 A6 8B 00 F4 CF 83 A6 CB 00 +B4 D3 83 A6 0B 01 F4 D3 83 A6 4B 01 B4 D7 83 A6 +8B 01 F4 D7 83 A6 CB 01 B4 DB 83 A6 0B 02 F4 DB +89 47 E3 F0 E7 EC 37 15 02 50 13 05 05 4C EF B0 +9F A6 03 A7 C9 07 75 B5 6C 43 30 43 25 65 13 05 +45 3B EF B0 5F A7 63 1D 0A 02 03 A5 C9 07 E3 75 +A4 F6 37 15 02 50 13 05 05 4E EF B0 DF A3 03 A5 +C9 07 99 BF B7 87 03 10 0D 47 98 C3 11 BF 37 15 +02 50 13 05 45 3E EF B0 1F A2 03 A7 C9 07 FD B3 +83 C7 1B 00 81 CF B2 50 22 54 92 54 02 59 F2 49 +62 4A D2 4A 42 4B B2 4B 45 61 82 80 03 A5 C9 07 +89 47 63 E0 A7 0C B7 16 03 10 4A 84 81 45 B3 86 +26 41 13 06 80 28 39 A0 93 95 07 01 C1 81 11 04 +E3 83 C5 FC B3 87 86 00 84 43 18 40 93 87 15 00 +E3 04 97 FE 83 A7 C9 07 C1 EF 05 45 EF B0 BF 99 +01 A0 37 15 02 50 13 05 05 4D EF B0 DF 9A 85 47 +03 A7 C9 07 23 A8 FA 00 83 C7 2B 00 91 CF B7 87 +03 10 80 C3 89 47 63 FB E7 0A 37 15 02 50 13 05 +45 39 EF B0 5F 98 AD B5 0D 44 D5 B7 37 15 02 50 +13 05 05 41 EF B0 3F 97 03 A7 C9 07 BD B3 25 69 +13 09 49 3B 13 05 89 03 EF B0 FF 97 83 A7 C9 07 +E3 84 07 EA A6 85 13 05 89 06 EF B0 DF 96 83 A7 +C9 07 E3 8B 07 E8 0C 40 13 05 09 08 EF B0 BF 95 +61 B5 37 15 02 50 13 05 05 50 EF B0 DF 92 25 BF +25 69 13 09 49 3B 13 05 89 09 EF B0 DF 93 83 A7 +C9 07 A1 DF A6 85 13 05 89 0C EF B0 DF 92 83 A7 +C9 07 A1 D7 0C 40 13 05 09 0E EF B0 DF 91 35 BF +15 EB 05 45 EF B0 3F 8D 01 A0 37 15 02 50 13 05 +45 43 EF B0 5F 8E 03 A7 C9 07 9D B5 37 37 02 50 +13 07 47 39 3C 43 74 43 D5 8F E3 83 07 DC 03 A5 +C9 07 CD B3 37 15 02 50 13 05 85 47 EF B0 BF 8B +C9 B7 79 71 4E CE B7 09 02 50 03 A8 C9 07 22 D4 +56 CA 5A C8 5E C6 62 C4 06 D6 26 D2 4A D0 52 CC +89 47 AA 8B 2E 8B 32 8C B6 8A 3A 84 63 E7 07 29 +B7 07 03 10 C4 4B 85 88 F5 DC 03 CA 0B 00 63 0C +0A 06 83 C7 2B 00 B7 86 03 10 09 47 86 07 93 F7 +E7 03 93 E7 17 00 9C C2 63 60 07 31 B7 07 03 10 +23 AC 07 04 23 AE 07 04 23 A0 07 06 23 A2 07 06 +23 A4 07 06 23 A6 07 06 23 A8 07 06 23 AA 07 06 +37 87 03 10 5C 43 89 8B F5 DF 83 C6 1B 00 85 47 +63 9B F6 04 5C 43 93 F7 C7 3F 63 81 07 30 89 47 +63 F3 07 05 37 15 02 50 13 05 C5 51 EF B0 BF 80 +03 A8 C9 07 0D A8 03 A7 4B 00 B8 CF 03 A7 8B 00 +F8 CF 03 A7 CB 00 B8 D3 03 A7 0B 01 F8 D3 03 A7 +4B 01 B8 D7 03 A7 8B 01 F8 D7 03 A7 CB 01 B8 DB +03 A7 0B 02 F8 DB 03 27 0B 00 37 09 03 10 89 47 +23 2C E9 08 03 27 4B 00 23 2E E9 08 03 27 8B 00 +23 20 E9 0A 03 27 CB 00 23 22 E9 0A 03 27 0B 01 +23 24 E9 0A 03 27 4B 01 23 26 E9 0A 03 27 8B 01 +23 28 E9 0A 03 27 CB 01 23 2A E9 0A 03 27 0B 02 +23 2C E9 0A 03 27 4B 02 23 2E E9 0A 03 27 8B 02 +23 20 E9 0C 03 27 CB 02 23 22 E9 0C 03 27 0B 03 +23 24 E9 0C 03 27 4B 03 23 26 E9 0C 03 27 8B 03 +23 28 E9 0C 03 27 CB 03 23 2A E9 0C 03 27 0C 00 +23 2C E9 06 03 27 4C 00 23 2E E9 06 03 27 8C 00 +23 20 E9 08 03 27 CC 00 23 22 E9 08 03 27 0C 01 +23 24 E9 08 03 27 4C 01 23 26 E9 08 03 27 8C 01 +23 28 E9 08 03 27 CC 01 23 2A E9 08 03 A7 0A 00 +23 2C E9 00 03 A7 4A 00 23 2E E9 00 03 A7 8A 00 +23 20 E9 02 03 A7 CA 00 23 22 E9 02 03 A7 0A 01 +23 24 E9 02 03 A7 4A 01 23 26 E9 02 03 A7 8A 01 +23 28 E9 02 03 A7 CA 01 23 2A E9 02 03 A7 0A 02 +23 2C E9 02 03 A7 4A 02 23 2E E9 02 03 A7 8A 02 +23 20 E9 04 03 A7 CA 02 23 22 E9 04 03 A7 0A 03 +23 24 E9 04 03 A7 4A 03 23 26 E9 04 03 A7 8A 03 +23 28 E9 04 03 A7 CA 03 23 2A E9 04 63 E9 07 0F +91 47 23 28 F9 00 83 C7 2B 00 D5 CF B7 87 03 10 +05 47 98 C3 37 37 02 50 13 07 47 39 34 43 7C 43 +D5 8F 91 EF 73 00 50 10 93 07 40 06 01 00 FD 17 +C2 07 C1 83 E5 FF 3C 43 74 43 D5 8F E5 D7 83 A6 +C9 07 89 47 63 EC D7 04 63 05 0A 00 83 C7 1B 00 +D9 E3 B7 26 03 10 81 45 81 8E 13 06 50 48 39 A0 +93 95 07 01 C1 81 11 04 63 87 C5 06 B3 87 86 00 +84 43 18 40 93 87 15 00 E3 04 97 FE 83 A7 C9 07 +CD EF 05 45 EF B0 2F DE 01 A0 37 15 02 50 13 05 +45 3E EF B0 4F DF 03 A8 C9 07 9D B3 6C 43 30 43 +25 65 13 05 45 3B EF B0 0F E0 63 13 0A 02 03 A7 +C9 07 89 47 E3 FF E7 F8 37 15 02 50 13 05 05 5D +EF B0 6F DC 79 B7 B7 87 03 10 0D 47 98 C3 99 B7 +83 C7 1B 00 E9 DF B2 50 22 54 92 54 02 59 F2 49 +62 4A D2 4A 42 4B B2 4B 22 4C 45 61 82 80 37 15 +02 50 13 05 85 5B EF B0 0F D9 91 47 03 A7 C9 07 +23 28 F9 00 83 C7 2B 00 91 CF B7 87 03 10 84 C3 +89 47 63 F3 E7 06 37 15 02 50 13 05 45 39 EF B0 +8F D6 CD BD 8D 44 D5 B7 37 15 02 50 13 05 05 41 +EF B0 6F D5 03 A8 C9 07 D5 B9 25 69 13 09 49 3B +13 05 89 0F EF B0 2F D6 83 A7 C9 07 9D DB A6 85 +13 05 49 12 EF B0 2F D5 83 A7 C9 07 E3 83 07 F2 +0C 40 13 05 C9 13 EF B0 0F D4 21 BF 63 10 08 02 +05 45 EF B0 4F CF 01 A0 37 37 02 50 13 07 47 39 +3C 43 74 43 D5 8F E3 8F 07 E8 7D BD 37 15 02 50 +13 05 85 56 EF B0 2F CF E1 BF 01 11 4A C8 37 09 +02 50 03 28 C9 07 22 CC 26 CA 4E C6 52 C4 56 C2 +06 CE 5A C0 89 47 AA 84 2E 8A B2 8A B6 89 3A 84 +63 E8 07 1D 37 07 03 10 5C 4B 85 8B F5 DF 89 47 +63 E7 07 23 05 67 13 07 07 32 B7 65 03 10 A6 87 +33 86 E4 00 85 8D 94 43 33 87 F5 00 91 07 14 C3 +E3 9B C7 FE 89 47 63 EB 07 1F 83 27 0A 00 B7 04 +03 10 09 4B 23 AC F4 08 83 27 4A 00 23 AE F4 08 +83 27 8A 00 23 A0 F4 0A 83 27 CA 00 23 A2 F4 0A +83 27 0A 01 23 A4 F4 0A 83 27 4A 01 23 A6 F4 0A +83 27 8A 01 23 A8 F4 0A 83 27 CA 01 23 AA F4 0A +83 27 0A 02 23 AC F4 0A 83 27 4A 02 23 AE F4 0A +83 27 8A 02 23 A0 F4 0C 83 27 CA 02 23 A2 F4 0C +83 27 0A 03 23 A4 F4 0C 83 27 4A 03 23 A6 F4 0C +83 27 8A 03 23 A8 F4 0C 83 27 CA 03 23 AA F4 0C +83 A7 0A 00 BC DC 83 A7 4A 00 FC DC 83 A7 8A 00 +23 A0 F4 08 83 A7 CA 00 23 A2 F4 08 83 A7 0A 01 +23 A4 F4 08 83 A7 4A 01 23 A6 F4 08 83 A7 8A 01 +23 A8 F4 08 83 A7 CA 01 23 AA F4 08 83 A7 09 00 +9C CC 83 A7 49 00 DC CC 83 A7 89 00 9C D0 83 A7 +C9 00 DC D0 83 A7 09 01 9C D4 83 A7 49 01 DC D4 +83 A7 89 01 9C D8 83 A7 C9 01 DC D8 83 A7 09 02 +9C DC 83 A7 49 02 DC DC 83 A7 89 02 BC C0 83 A7 +C9 02 FC C0 83 A7 09 03 BC C4 83 A7 49 03 FC C4 +83 A7 89 03 BC C8 83 A7 C9 03 FC C8 63 65 0B 0B +23 A8 64 01 37 37 02 50 13 07 47 39 34 43 7C 43 +D5 8F 91 EF 73 00 50 10 93 07 40 06 01 00 FD 17 +C2 07 C1 83 E5 FF 3C 43 74 43 D5 8F E5 D7 83 27 +C9 07 89 44 63 E7 F4 04 B7 26 03 10 81 45 81 8E +13 06 50 48 39 A0 93 95 07 01 C1 81 11 04 63 89 +C5 0C B3 87 86 00 84 43 18 40 93 87 15 00 E3 04 +97 FE 83 27 C9 07 C9 E7 05 45 EF B0 CF AD 01 A0 +37 15 02 50 13 05 45 3C EF B0 EF AE 03 28 C9 07 +15 B5 6C 43 30 43 25 65 13 05 45 3B EF B0 AF AF +83 27 C9 07 E3 F2 F4 FA 37 15 02 50 13 05 05 5D +EF B0 6F AC 51 BF 37 15 02 50 13 05 85 60 EF B0 +8F AB 83 27 C9 07 23 A8 64 01 63 7D FB 06 37 15 +02 50 13 05 45 39 EF B0 0F AA 2D BF 37 15 02 50 +13 05 C5 5F EF B0 2F A9 03 28 C9 07 FD BB 37 15 +02 50 13 05 C5 5E EF B0 0F A8 03 28 C9 07 D9 B3 +A5 69 93 89 49 3B 13 85 49 15 EF B0 CF A8 83 27 +C9 07 BD D3 A6 85 13 85 09 18 EF B0 CF A7 83 27 +C9 07 B9 DB 0C 40 13 85 89 19 EF B0 CF A6 A9 B7 +F2 40 62 44 D2 44 42 49 B2 49 22 4A 92 4A 02 4B +05 61 82 80 37 37 02 50 13 07 47 39 34 43 7C 43 +D5 8F E3 89 07 EC CD BD 01 11 22 CC 06 CE 26 CA +4A C8 4E C6 32 88 36 84 37 07 03 10 5C 4B 85 8B +F5 DF 1C 41 23 2C F7 08 54 41 AE 87 23 2E D7 08 +83 28 85 00 85 66 93 86 06 A2 23 20 17 0B 33 86 +D5 00 54 45 B7 15 03 10 9D 8D 23 22 D7 0A 14 49 +23 24 D7 0A 54 49 23 26 D7 0A 14 4D 23 28 D7 0A +54 4D 23 2A D7 0A 14 51 23 2C D7 0A 54 51 23 2E +D7 0A 14 55 23 20 D7 0C 54 55 23 22 D7 0C 14 59 +23 24 D7 0C 54 59 23 26 D7 0C 14 5D 23 28 D7 0C +54 5D 23 2A D7 0C 94 43 33 87 F5 00 91 07 14 C3 +E3 9B C7 FE 05 67 13 07 47 21 B7 25 03 10 C2 87 +33 06 E8 00 B3 85 05 41 94 43 33 87 F5 00 91 07 +14 C3 E3 9B C7 FE 37 09 02 50 83 27 C9 07 89 44 +63 E8 F4 12 B7 07 03 10 0D 47 98 CB 37 37 02 50 +13 07 47 39 34 43 7C 43 D5 8F 9D E3 73 00 50 10 +93 07 40 06 01 00 FD 17 C2 07 C1 83 E5 FF 3C 43 +74 43 D5 8F E5 D7 83 27 C9 07 89 44 63 E8 F4 0C +B7 07 03 10 83 A4 87 0D 18 40 63 19 97 0A 83 A4 +C7 0D 58 40 63 94 E4 14 83 A4 07 0E 18 44 63 92 +E4 14 83 A4 47 0E 58 44 63 96 E4 14 83 A4 87 0E +18 48 63 9E E4 12 83 A4 C7 0E 58 48 63 96 E4 12 +83 A4 07 0F 18 4C 63 96 E4 14 83 A4 47 0F 58 4C +63 94 E4 16 83 A4 87 0F 18 50 63 9B E4 14 83 A4 +C7 0F 5C 50 63 92 F4 14 B7 07 03 10 83 A4 07 10 +18 54 63 97 E4 12 83 A4 47 10 58 54 63 97 E4 10 +83 A4 87 10 18 58 63 9E E4 0E 83 A4 C7 10 58 58 +63 94 E4 10 83 A4 07 11 18 5C 63 90 E4 0E 83 A4 +47 11 5C 5C BD 45 13 04 C4 03 63 9A 97 00 F2 40 +62 44 D2 44 42 49 B2 49 05 61 82 80 81 45 83 27 +C9 07 AD E7 05 45 EF B0 0F 83 01 A0 6C 43 30 43 +25 65 13 05 45 3B EF B0 0F 86 83 27 C9 07 E3 F1 +F4 F2 37 15 02 50 13 05 C5 62 EF B0 CF 82 09 BF +37 15 02 50 13 05 85 61 EF B0 EF 81 83 27 C9 07 +37 07 03 10 8D 46 14 CB E3 F2 F4 EC 37 15 02 50 +13 05 45 39 EF B0 2F 80 37 37 02 50 13 07 47 39 +34 43 7C 43 D5 8F E3 8B 07 EA F1 B5 A5 69 93 89 +49 3B 13 85 09 1B EF B0 0F 80 83 27 C9 07 D9 D3 +A6 85 13 85 49 1E EF A0 1F FF 83 27 C9 07 BD DB +0C 40 13 85 C9 1F EF A0 1F FE AD B7 11 04 85 45 +B9 BF 21 04 89 45 A1 BF 51 04 95 45 89 BF 41 04 +91 45 B1 B7 31 04 8D 45 99 B7 13 04 84 03 B9 45 +3D BF 13 04 04 03 B1 45 1D BF 13 04 C4 02 AD 45 +3D B7 61 04 99 45 25 B7 13 04 44 03 B5 45 05 B7 +13 04 84 02 A9 45 21 BF 13 04 44 02 A5 45 01 BF +13 04 04 02 A1 45 21 B7 71 04 9D 45 09 B7 79 71 +4A D0 37 09 02 50 03 28 C9 07 22 D4 52 CC 56 CA +5A C8 5E C6 06 D6 26 D2 4E CE 89 47 2A 8B 2E 8A +B2 8B B6 8A 3A 84 63 EB 07 29 B7 07 03 10 C4 4B +85 88 F5 DC 83 49 0B 00 63 8C 09 06 83 47 2B 00 +B7 86 03 10 09 47 86 07 93 F7 E7 03 93 E7 17 00 +9C C2 63 6D 07 31 B7 07 03 10 23 AC 07 04 23 AE +07 04 23 A0 07 06 23 A2 07 06 23 A4 07 06 23 A6 +07 06 23 A8 07 06 23 AA 07 06 37 87 03 10 5C 43 +89 8B F5 DF 83 46 1B 00 85 47 63 9B F6 04 5C 43 +93 F7 C7 3F 63 8F 07 30 89 47 63 F3 07 05 37 15 +02 50 13 05 C5 51 EF A0 1F EB 03 28 C9 07 0D A8 +03 27 4B 00 B8 CF 03 27 8B 00 F8 CF 03 27 CB 00 +B8 D3 03 27 0B 01 F8 D3 03 27 4B 01 B8 D7 03 27 +8B 01 F8 D7 03 27 CB 01 B8 DB 03 27 0B 02 F8 DB +83 26 0A 00 B7 07 03 10 09 47 23 AC D7 10 83 26 +4A 00 23 AE D7 10 83 26 8A 00 23 A0 D7 12 83 26 +CA 00 23 A2 D7 12 83 26 0A 01 23 A4 D7 12 83 26 +4A 01 23 A6 D7 12 83 26 8A 01 23 A8 D7 12 83 26 +CA 01 23 AA D7 12 83 26 0A 02 23 AC D7 12 83 26 +4A 02 23 AE D7 12 83 26 8A 02 23 A0 D7 14 83 26 +CA 02 23 A2 D7 14 83 26 0A 03 23 A4 D7 14 83 26 +4A 03 23 A6 D7 14 83 26 8A 03 23 A8 D7 14 83 26 +CA 03 23 AA D7 14 83 A6 0B 00 B4 DF 83 A6 4B 00 +F4 DF 83 A6 8B 00 23 A0 D7 08 83 A6 CB 00 23 A2 +D7 08 83 A6 0B 01 23 A4 D7 08 83 A6 4B 01 23 A6 +D7 08 83 A6 8B 01 23 A8 D7 08 83 A6 CB 01 23 AA +D7 08 63 6A 07 1B 03 A7 0A 00 37 0A 03 10 89 47 +23 2C EA 00 03 A7 4A 00 23 2E EA 00 03 A7 8A 00 +23 20 EA 02 03 A7 CA 00 23 22 EA 02 03 A7 0A 01 +23 24 EA 02 03 A7 4A 01 23 26 EA 02 03 A7 8A 01 +23 28 EA 02 03 A7 CA 01 23 2A EA 02 03 A7 0A 02 +23 2C EA 02 03 A7 4A 02 23 2E EA 02 03 A7 8A 02 +23 20 EA 04 03 A7 CA 02 23 22 EA 04 03 A7 0A 03 +23 24 EA 04 03 A7 4A 03 23 26 EA 04 03 A7 8A 03 +23 28 EA 04 03 A7 CA 03 23 2A EA 04 63 E9 07 0F +93 07 40 02 23 28 FA 00 83 47 2B 00 C9 CB B7 87 +03 10 05 47 98 C3 37 37 02 50 13 07 47 39 3C 43 +74 43 D5 8F 91 EF 73 00 50 10 93 07 40 06 01 00 +FD 17 C2 07 C1 83 E5 FF 3C 43 74 43 D5 8F E5 D7 +83 26 C9 07 89 47 63 E1 D7 06 63 85 09 00 83 47 +1B 00 D9 E3 B7 26 03 10 81 45 81 8E 13 06 50 48 +39 A0 93 95 07 01 C1 81 11 04 63 87 C5 06 B3 87 +86 00 84 43 18 40 93 87 15 00 E3 04 97 FE 83 27 +C9 07 F1 E7 05 45 EF A0 1F C8 01 A0 37 15 02 50 +13 05 45 3E EF A0 3F C9 03 28 C9 07 B9 BB B7 87 +03 10 0D 47 98 C3 85 BF 6C 43 30 43 25 65 13 05 +45 3B EF A0 5F C9 63 9E 09 00 03 27 C9 07 89 47 +E3 FA E7 F8 37 15 02 50 13 05 05 5D EF A0 BF C5 +51 B7 83 47 1B 00 F5 D3 B2 50 22 54 92 54 02 59 +F2 49 62 4A D2 4A 42 4B B2 4B 45 61 82 80 37 15 +02 50 13 05 C5 64 EF A0 1F C3 93 07 40 02 03 27 +C9 07 23 28 FA 00 83 47 2B 00 9D C7 B7 87 03 10 +84 C3 89 47 63 FD E7 06 37 15 02 50 13 05 45 39 +EF A0 7F C0 CD BD 37 15 02 50 13 05 05 4C EF A0 +9F BF 03 28 C9 07 81 B5 8D 44 C9 BF 37 15 02 50 +13 05 05 41 EF A0 3F BE 03 28 C9 07 E9 B9 A5 69 +93 89 49 3B 13 85 49 21 EF A0 FF BE 83 27 C9 07 +E3 82 07 F2 A6 85 13 85 09 24 EF A0 DF BD 83 27 +C9 07 E3 89 07 F0 0C 40 13 85 89 25 EF A0 BF BC +11 B7 63 10 08 02 05 45 EF A0 FF B7 01 A0 37 37 +02 50 13 07 47 39 3C 43 74 43 D5 8F E3 85 07 E8 +6D B5 37 15 02 50 13 05 85 56 EF A0 DF B7 E1 BF +01 11 4A C8 37 09 02 50 03 28 C9 07 22 CC 26 CA +4E C6 52 C4 56 C2 06 CE 5A C0 89 47 AA 84 2E 8A +B2 8A B6 89 3A 84 63 E9 07 1D 37 07 03 10 5C 4B +85 8B F5 DF 89 47 63 E9 07 23 05 67 13 07 07 32 +B7 65 03 10 A6 87 33 86 E4 00 85 8D 94 43 33 87 +F5 00 91 07 14 C3 E3 9B C7 FE 89 47 63 ED 07 1F +83 27 0A 00 B7 04 03 10 09 4B 23 AC F4 10 83 27 +4A 00 23 AE F4 10 83 27 8A 00 23 A0 F4 12 83 27 +CA 00 23 A2 F4 12 83 27 0A 01 23 A4 F4 12 83 27 +4A 01 23 A6 F4 12 83 27 8A 01 23 A8 F4 12 83 27 +CA 01 23 AA F4 12 83 27 0A 02 23 AC F4 12 83 27 +4A 02 23 AE F4 12 83 27 8A 02 23 A0 F4 14 83 27 +CA 02 23 A2 F4 14 83 27 0A 03 23 A4 F4 14 83 27 +4A 03 23 A6 F4 14 83 27 8A 03 23 A8 F4 14 83 27 +CA 03 23 AA F4 14 83 A7 0A 00 BC DC 83 A7 4A 00 +FC DC 83 A7 8A 00 23 A0 F4 08 83 A7 CA 00 23 A2 +F4 08 83 A7 0A 01 23 A4 F4 08 83 A7 4A 01 23 A6 +F4 08 83 A7 8A 01 23 A8 F4 08 83 A7 CA 01 23 AA +F4 08 83 A7 09 00 9C CC 83 A7 49 00 DC CC 83 A7 +89 00 9C D0 83 A7 C9 00 DC D0 83 A7 09 01 9C D4 +83 A7 49 01 DC D4 83 A7 89 01 9C D8 83 A7 C9 01 +DC D8 83 A7 09 02 9C DC 83 A7 49 02 DC DC 83 A7 +89 02 BC C0 83 A7 C9 02 FC C0 83 A7 09 03 BC C4 +83 A7 49 03 FC C4 83 A7 89 03 BC C8 83 A7 C9 03 +FC C8 63 66 0B 0B 93 07 20 02 9C C8 37 37 02 50 +13 07 47 39 34 43 7C 43 D5 8F 91 EF 73 00 50 10 +93 07 40 06 01 00 FD 17 C2 07 C1 83 E5 FF 3C 43 +74 43 D5 8F E5 D7 83 27 C9 07 89 44 63 E7 F4 04 +B7 26 03 10 81 45 81 8E 13 06 50 48 39 A0 93 95 +07 01 C1 81 11 04 63 8A C5 0C B3 87 86 00 84 43 +18 40 93 87 15 00 E3 04 97 FE 83 27 C9 07 D1 E7 +05 45 EF A0 5F 96 01 A0 37 15 02 50 13 05 45 3C +EF A0 7F 97 03 28 C9 07 0D B5 6C 43 30 43 25 65 +13 05 45 3B EF A0 3F 98 83 27 C9 07 E3 F2 F4 FA +37 15 02 50 13 05 05 5D EF A0 FF 94 51 BF 37 15 +02 50 13 05 C5 68 EF A0 1F 94 83 27 C9 07 13 07 +20 02 98 C8 63 7D FB 06 37 15 02 50 13 05 45 39 +EF A0 7F 92 25 BF 37 15 02 50 13 05 85 67 EF A0 +9F 91 03 28 C9 07 ED BB 37 15 02 50 13 05 C5 5E +EF A0 7F 90 03 28 C9 07 C9 B3 A5 69 93 89 49 3B +13 85 09 27 EF A0 3F 91 83 27 C9 07 B5 D3 A6 85 +13 85 C9 29 EF A0 3F 90 83 27 C9 07 B1 DB 0C 40 +13 85 49 2B EF A0 3F 8F A1 B7 F2 40 62 44 D2 44 +42 49 B2 49 22 4A 92 4A 02 4B 05 61 82 80 37 37 +02 50 13 07 47 39 34 43 7C 43 D5 8F E3 88 07 EC +C5 BD 01 11 22 CC 26 CA 4E C6 52 C4 06 CE 4A C8 +AA 84 AE 89 32 8A 36 84 37 07 03 10 5C 4B 85 8B +F5 DF 37 09 02 50 03 25 C9 07 89 47 63 E7 A7 20 +9C 40 37 07 03 10 23 2C F7 10 D4 40 CE 87 23 2E +D7 10 8C 44 85 66 93 86 06 A2 23 20 B7 12 33 86 +D9 00 D4 44 B7 15 03 10 B3 85 35 41 23 22 D7 12 +94 48 23 24 D7 12 D4 48 23 26 D7 12 94 4C 23 28 +D7 12 D4 4C 23 2A D7 12 94 50 23 2C D7 12 D4 50 +23 2E D7 12 94 54 23 20 D7 14 D4 54 23 22 D7 14 +94 58 23 24 D7 14 D4 58 23 26 D7 14 94 5C 23 28 +D7 14 D4 5C 23 2A D7 14 94 43 33 87 F5 00 91 07 +14 C3 E3 9B C7 FE 05 67 13 07 47 21 B7 25 03 10 +D2 87 33 06 EA 00 B3 85 45 41 94 43 33 87 F5 00 +91 07 14 C3 E3 9B C7 FE 89 44 63 EA A4 12 B7 07 +03 10 13 07 30 02 98 CB 37 37 02 50 13 07 47 39 +3C 43 74 43 D5 8F 91 EF 73 00 50 10 93 07 40 06 +01 00 FD 17 C2 07 C1 83 E5 FF 3C 43 74 43 D5 8F +E5 D7 83 27 C9 07 89 44 63 E9 F4 0C B7 07 03 10 +83 A4 87 0D 18 40 63 1A 97 0A 83 A4 C7 0D 58 40 +63 96 E4 14 83 A4 07 0E 18 44 63 97 E4 16 83 A4 +47 0E 58 44 63 9F E4 14 83 A4 87 0E 18 48 63 97 +E4 14 83 A4 C7 0E 58 48 63 9F E4 12 83 A4 07 0F +18 4C 63 96 E4 14 83 A4 47 0F 58 4C 63 98 E4 14 +83 A4 87 0F 18 50 63 9F E4 12 83 A4 C7 0F 5C 50 +63 9D F4 14 B7 07 03 10 83 A4 07 10 18 54 63 92 +E4 14 83 A4 47 10 58 54 63 99 E4 12 83 A4 87 10 +18 58 63 90 E4 12 83 A4 C7 10 58 58 63 9B E4 12 +83 A4 07 11 18 5C 63 9A E4 12 83 A4 47 11 5C 5C +BD 45 13 04 C4 03 63 9B 97 00 F2 40 62 44 D2 44 +42 49 B2 49 22 4A 05 61 82 80 81 45 83 27 C9 07 +B5 E7 05 45 EF A0 2F EA 01 A0 6C 43 30 43 25 65 +13 05 45 3B EF A0 2F ED 83 27 C9 07 E3 F0 F4 F2 +37 15 02 50 13 05 C5 62 EF A0 EF E9 01 BF 37 15 +02 50 13 05 05 6B EF A0 0F E9 83 27 C9 07 37 07 +03 10 93 06 30 02 14 CB 63 FD F4 04 37 15 02 50 +13 05 45 39 EF A0 2F E7 45 BD 37 15 02 50 13 05 +85 67 EF A0 4F E6 03 25 C9 07 DD B3 A5 69 93 89 +49 3B 13 85 C9 2C EF A0 0F E7 83 27 C9 07 D1 D3 +A6 85 13 85 89 2F EF A0 0F E6 83 27 C9 07 B5 DB +0C 40 13 85 09 31 EF A0 0F E5 A5 B7 11 04 85 45 +B1 BF 37 37 02 50 13 07 47 39 34 43 7C 43 D5 8F +E3 84 07 E6 61 B5 51 04 95 45 89 B7 41 04 91 45 +35 BF 31 04 8D 45 1D BF 21 04 89 45 05 BF 61 04 +99 45 2D B7 13 04 04 02 A1 45 0D B7 71 04 9D 45 +31 BF 13 04 04 03 B1 45 11 BF 13 04 C4 02 AD 45 +31 B7 13 04 84 02 A9 45 11 B7 13 04 44 02 A5 45 +F5 BD 13 04 44 03 B5 45 D5 BD 13 04 84 03 B9 45 +F5 B5 B7 07 02 50 03 A7 C7 07 41 11 22 C4 06 C6 +89 47 2A 84 63 E9 E7 02 37 07 03 10 5C 4B 85 8B +F5 DF 13 05 B0 09 EF A0 0F D7 83 47 24 00 B2 40 +22 44 86 07 93 F7 E7 03 93 E7 17 00 37 87 03 10 +1C C3 41 01 82 80 37 15 02 50 13 05 45 3C EF A0 +8F D6 D9 B7 52 65 63 65 69 76 65 64 20 4D 4C 44 +53 41 20 6E 6F 74 69 66 2F 20 65 72 72 20 69 6E +74 72 20 77 69 74 68 20 73 74 61 74 75 73 20 3D +20 25 64 2F 20 25 64 0A 00 00 00 00 41 74 20 6F +66 66 73 65 74 20 5B 25 64 5D 2C 20 6D 6C 64 73 +61 5F 70 72 69 76 6B 65 79 20 64 61 74 61 20 6D +69 73 6D 61 74 63 68 21 0A 00 00 00 41 63 74 75 +61 6C 20 20 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 45 78 70 65 63 74 65 64 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 41 74 20 6F +66 66 73 65 74 20 5B 25 64 5D 2C 20 6D 6C 64 73 +61 5F 70 75 62 6B 65 79 20 64 61 74 61 20 6D 69 +73 6D 61 74 63 68 21 0A 00 00 00 00 41 63 74 75 +61 6C 20 20 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 45 78 70 65 63 74 65 64 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 41 74 20 6F +66 66 73 65 74 20 5B 25 64 5D 2C 20 6D 6C 64 73 +61 5F 73 69 67 6E 20 64 61 74 61 20 6D 69 73 6D +61 74 63 68 21 0A 00 00 41 63 74 75 61 6C 20 20 +20 64 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +45 78 70 65 63 74 65 64 20 64 61 74 61 3A 20 30 +78 25 78 0A 00 00 00 00 41 74 20 6F 66 66 73 65 +74 20 5B 25 64 5D 2C 20 6D 6C 64 73 61 5F 73 69 +67 6E 20 64 61 74 61 20 6D 69 73 6D 61 74 63 68 +21 0A 00 00 41 63 74 75 61 6C 20 20 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 45 78 70 65 +63 74 65 64 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 41 74 20 6F 66 66 73 65 74 20 5B 25 +64 5D 2C 20 6D 6C 64 73 61 5F 76 65 72 69 66 79 +5F 72 65 73 20 64 61 74 61 20 6D 69 73 6D 61 74 +63 68 21 0A 00 00 00 00 41 63 74 75 61 6C 20 20 +20 64 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +45 78 70 65 63 74 65 64 20 64 61 74 61 3A 20 30 +78 25 78 0A 00 00 00 00 41 74 20 6F 66 66 73 65 +74 20 5B 25 64 5D 2C 20 6D 6C 64 73 61 5F 73 69 +67 6E 20 64 61 74 61 20 6D 69 73 6D 61 74 63 68 +21 0A 00 00 41 63 74 75 61 6C 20 20 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 45 78 70 65 +63 74 65 64 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 41 74 20 6F 66 66 73 65 74 20 5B 25 +64 5D 2C 20 6D 6C 64 73 61 5F 73 69 67 6E 20 64 +61 74 61 20 6D 69 73 6D 61 74 63 68 21 0A 00 00 +41 63 74 75 61 6C 20 20 20 64 61 74 61 3A 20 30 +78 25 78 0A 00 00 00 00 45 78 70 65 63 74 65 64 +20 64 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +41 74 20 6F 66 66 73 65 74 20 5B 25 64 5D 2C 20 +61 63 74 75 61 6C 5F 64 61 74 61 20 64 61 74 61 +20 6D 69 73 6D 61 74 63 68 21 0A 00 41 63 74 75 +61 6C 20 20 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 45 78 70 65 63 74 65 64 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 41 11 22 C4 +37 04 02 50 03 27 C4 07 06 C6 89 47 63 E0 E7 04 +37 37 02 50 13 07 47 39 3C 43 74 43 D5 8F 9D E3 +73 00 50 10 93 07 40 06 01 00 FD 17 C2 07 C1 83 +E5 FF 3C 43 74 43 D5 8F E5 D7 83 26 C4 07 89 47 +63 E5 D7 02 B2 40 22 44 41 01 82 80 37 15 02 50 +13 05 45 6D EF A0 2F 9E 37 37 02 50 13 07 47 39 +3C 43 74 43 D5 8F CD DF C9 BF 22 44 6C 43 B2 40 +30 43 31 65 13 05 C5 E8 41 01 6F A0 CF 9D 41 11 +26 C2 B7 04 02 50 83 A7 C4 07 22 C4 06 C6 09 44 +63 60 F4 02 B7 97 03 10 21 47 98 CB 37 97 03 10 +5C 4B 85 8B F5 DF B2 40 22 44 92 44 41 01 82 80 +37 15 02 50 13 05 45 6F EF A0 EF 97 83 A7 C4 07 +37 97 03 10 A1 46 14 CB E3 7A F4 FC 37 15 02 50 +13 05 05 71 EF A0 2F 96 D1 B7 19 CA 0A 06 33 87 +C5 00 9C 41 91 05 11 05 23 2E F5 FE E3 9B E5 FE +82 80 79 71 4E CE B7 09 02 50 03 A7 C9 07 22 D4 +52 CC 5A C8 5E C6 06 D6 26 D2 4A D0 56 CA 62 C4 +89 47 2A 8B AE 8B 32 84 36 8A 63 E5 E7 22 37 99 +03 10 83 24 49 01 85 88 ED DC 83 4A 0B 00 83 47 +2B 00 63 88 0A 16 86 07 93 F7 E7 03 93 E7 17 00 +B7 C6 03 10 9C C2 09 4C 63 61 EC 2A 23 2C 09 00 +23 2E 09 00 23 20 09 02 23 22 09 02 23 24 09 02 +23 26 09 02 23 28 09 02 23 2A 09 02 B7 97 03 10 +23 AC 07 02 23 AE 07 02 23 A0 07 04 23 A2 07 04 +23 A4 07 04 23 A6 07 04 23 A8 07 04 23 AA 07 04 +B7 C6 03 10 DC 42 89 8B F5 DF 03 46 1B 00 85 47 +63 11 F6 18 DC 42 93 F7 C7 3F 63 84 07 2E 89 47 +63 E6 E7 2E 03 A6 0B 00 B7 07 03 10 89 46 90 CF +03 A6 4B 00 D0 CF 03 A6 8B 00 90 D3 03 A6 CB 00 +D0 D3 03 A6 0B 01 90 D7 03 A6 4B 01 D0 D7 03 A6 +8B 01 90 DB 03 A6 CB 01 D0 DB 03 A6 0B 02 90 DF +03 A6 4B 02 D0 DF 03 A6 8B 02 B0 C3 03 A6 CB 02 +F0 C3 03 A6 0B 03 B0 C7 03 A6 4B 03 F0 C7 03 A6 +8B 03 B0 CB 03 A6 CB 03 F0 CB 63 EE E6 12 37 97 +03 10 85 47 1C CB 03 47 2B 00 63 08 07 10 37 C7 +03 10 1C C3 37 37 02 50 13 07 47 39 34 43 7C 43 +D5 8F 91 EF 73 00 50 10 93 07 40 06 01 00 FD 17 +C2 07 C1 83 E5 FF 3C 43 74 43 D5 8F E5 D7 83 A7 +C9 07 89 44 63 E5 F4 12 B7 B6 03 10 81 45 81 8E +13 06 80 18 39 A0 93 95 07 01 C1 81 11 04 63 89 +C5 1A B3 87 86 00 84 43 18 40 93 87 15 00 E3 04 +97 FE 83 A7 C9 07 63 9E 07 10 05 45 EF 90 BF F7 +01 A0 83 27 4B 00 23 2C F9 00 83 27 8B 00 23 2E +F9 00 83 27 CB 00 23 20 F9 02 83 27 0B 01 23 22 +F9 02 83 27 4B 01 23 24 F9 02 83 27 8B 01 23 26 +F9 02 83 27 CB 01 23 28 F9 02 83 27 0B 02 23 2A +F9 02 83 27 4B 02 23 2C F9 02 83 27 8B 02 23 2E +F9 02 83 27 CB 02 23 20 F9 04 83 27 0B 03 23 22 +F9 04 83 27 4B 03 23 24 F9 04 83 27 8B 03 23 26 +F9 04 83 27 CB 03 23 28 F9 04 83 27 0B 04 23 2A +F9 04 89 47 E3 F8 E7 E8 37 25 02 50 13 05 45 83 +EF 90 7F F0 03 A7 C9 07 B5 BD B7 C7 03 10 0D 47 +98 C3 CD BD 37 15 02 50 13 05 C5 72 EF 90 BF EE +03 A7 C9 07 E9 B3 37 25 02 50 13 05 45 85 EF 90 +9F ED B7 97 03 10 85 46 03 A7 C9 07 94 CB 83 47 +2B 00 B5 CB B7 C7 03 10 84 C3 89 47 63 F9 E7 12 +37 15 02 50 13 05 45 6D EF 90 FF EA 65 B5 6C 43 +30 43 31 65 13 05 C5 E8 EF 90 FF EB 83 A7 C9 07 +E3 F4 F4 EC 37 25 02 50 13 05 45 87 EF 90 BF E8 +65 BD 31 69 13 09 C9 E8 13 05 89 03 EF 90 BF E9 +83 A7 C9 07 E3 8B 07 EC A6 85 13 05 C9 06 EF 90 +9F E8 83 A7 C9 07 E3 82 07 EC 0C 40 13 05 49 08 +EF 90 7F E7 5D BD 8D 44 71 B7 37 15 02 50 13 05 +05 75 EF 90 5F E4 03 A7 C9 07 23 2C 09 00 23 2E +09 00 23 20 09 02 23 22 09 02 23 24 09 02 23 26 +09 02 23 28 09 02 23 2A 09 02 E3 79 EC D4 37 15 +02 50 13 05 C5 77 EF 90 1F E1 03 A7 C9 07 3D BB +63 95 0A 04 03 A7 C9 07 89 47 63 E4 E7 0C B7 A7 +03 10 81 45 B3 87 47 41 93 06 80 31 39 A0 93 15 +07 01 C1 81 11 0A 63 82 D5 02 33 87 47 01 04 43 +03 26 0A 00 13 87 15 00 E3 03 96 FE 83 A7 C9 07 +A5 E3 05 45 EF 90 3F DA 01 A0 B2 50 22 54 92 54 +02 59 F2 49 62 4A D2 4A 42 4B B2 4B 22 4C 45 61 +82 80 05 EB 05 45 EF 90 1F D8 01 A0 37 15 02 50 +13 05 85 7A EF 90 3F D9 03 A7 C9 07 9D BD 37 37 +02 50 13 07 47 39 34 43 7C 43 D5 8F E3 84 07 D8 +65 B3 37 15 02 50 13 05 C5 7E EF 90 DF D6 D9 B7 +31 64 13 04 C4 E8 13 05 C4 09 EF 90 DF D7 83 A7 +C9 07 C1 DB A6 85 13 05 04 0D EF 90 DF D6 83 A7 +C9 07 C1 D3 83 25 0A 00 13 05 84 0E EF 90 BF D5 +8D BF 37 25 02 50 13 05 85 89 EF 90 DF D2 05 BF +79 71 4A D0 37 09 02 50 03 27 C9 07 22 D4 52 CC +5A C8 5E C6 06 D6 26 D2 4E CE 56 CA 62 C4 89 47 +2A 8B AE 8B 32 84 36 8A 63 E1 E7 30 B7 9A 03 10 +83 A4 4A 01 85 88 ED DC 83 49 0B 00 63 8B 09 24 +83 47 2B 00 B7 C6 03 10 09 4C 86 07 93 F7 E7 03 +93 E7 17 00 9C C2 63 64 EC 38 23 AC 0A 00 23 AE +0A 00 23 A0 0A 02 23 A2 0A 02 23 A4 0A 02 23 A6 +0A 02 23 A8 0A 02 23 AA 0A 02 B7 97 03 10 23 AC +07 02 23 AE 07 02 23 A0 07 04 23 A2 07 04 23 A4 +07 04 23 A6 07 04 23 A8 07 04 23 AA 07 04 B7 C6 +03 10 DC 42 89 8B F5 DF 03 46 1B 00 85 47 63 0E +F6 3A 89 47 63 FA E7 00 37 25 02 50 13 05 C5 8B +EF 90 7F C6 03 27 C9 07 B7 97 03 10 83 AA 87 01 +63 96 0A 3E 94 4F 83 AA C7 01 63 94 0A 46 D4 4F +83 AA 07 02 63 91 0A 46 94 53 83 AA 47 02 63 9E +0A 44 D4 53 83 AA 87 02 63 9B 0A 44 94 57 83 AA +C7 02 63 9C 0A 42 D4 57 83 AA 07 03 63 99 0A 42 +94 5B 83 AA 47 03 9D 45 63 93 0A 3A DC 5B 89 47 +63 E2 E7 30 B7 97 03 10 83 AA 87 03 63 92 0A 38 +94 5F 83 AA C7 03 63 9E 0A 40 D4 5F 83 AA 07 04 +63 9B 0A 40 B4 43 83 AA 47 04 63 98 0A 40 F4 43 +83 AA 87 04 63 95 0A 40 B4 47 83 AA C7 04 63 92 +0A 40 F4 47 83 AA 07 05 63 90 0A 3C B4 4B 83 AA +47 05 9D 45 63 9F 0A 32 FC 4B 89 47 63 EE E7 18 +03 A6 0B 00 B7 07 03 10 89 46 90 CF 03 A6 4B 00 +D0 CF 03 A6 8B 00 90 D3 03 A6 CB 00 D0 D3 03 A6 +0B 01 90 D7 03 A6 4B 01 D0 D7 03 A6 8B 01 90 DB +03 A6 CB 01 D0 DB 03 A6 0B 02 90 DF 03 A6 4B 02 +D0 DF 03 A6 8B 02 B0 C3 03 A6 CB 02 F0 C3 03 A6 +0B 03 B0 C7 03 A6 4B 03 F0 C7 03 A6 8B 03 B0 CB +03 A6 CB 03 F0 CB 63 EB E6 14 37 97 03 10 85 47 +1C CB 03 47 2B 00 63 0B 07 1A 37 C7 03 10 1C C3 +37 37 02 50 13 07 47 39 34 43 7C 43 D5 8F 91 EF +73 00 50 10 93 07 40 06 01 00 FD 17 C2 07 C1 83 +E5 FF 3C 43 74 43 D5 8F E5 D7 03 25 C9 07 89 44 +63 E3 A4 18 B7 B7 03 10 B7 55 FC EF 13 86 07 62 +94 43 33 87 B7 00 22 97 14 C3 91 07 E3 9A C7 FE +89 47 63 91 09 12 63 EA A7 22 37 B6 03 10 B7 A7 +03 10 B7 65 FC EF 13 06 06 C6 94 43 33 87 B7 00 +52 97 14 C3 91 07 E3 9A C7 FE B2 50 22 54 92 54 +02 59 F2 49 62 4A D2 4A 42 4B B2 4B 22 4C 45 61 +82 80 83 27 4B 00 23 AC FA 00 83 27 8B 00 23 AE +FA 00 83 27 CB 00 23 A0 FA 02 83 27 0B 01 23 A2 +FA 02 83 27 4B 01 23 A4 FA 02 83 27 8B 01 23 A6 +FA 02 83 27 CB 01 23 A8 FA 02 83 27 0B 02 23 AA +FA 02 83 27 4B 02 23 AC FA 02 83 27 8B 02 23 AE +FA 02 83 27 CB 02 23 A0 FA 04 83 27 0B 03 23 A2 +FA 04 83 27 4B 03 23 A4 FA 04 83 27 8B 03 23 A6 +FA 04 83 27 CB 03 23 A8 FA 04 83 27 0B 04 23 AA +FA 04 89 47 E3 F6 E7 E6 37 25 02 50 13 05 45 83 +EF 90 7F A0 03 27 C9 07 A1 BD 37 15 02 50 13 05 +C5 72 EF 90 5F 9F 03 27 C9 07 CD B9 37 25 02 50 +13 05 45 85 EF 90 3F 9E B7 97 03 10 85 46 03 27 +C9 07 94 CB 83 47 2B 00 F9 CF B7 C7 03 10 84 C3 +89 47 63 F2 E7 20 37 15 02 50 13 05 45 6D EF 90 +9F 9B 79 B5 63 E7 A7 12 B7 A7 03 10 81 45 13 06 +80 31 01 A8 93 15 07 01 9C 43 C1 81 E3 87 C5 EE +B6 87 80 43 13 87 15 00 93 86 47 00 65 D4 83 27 +C9 07 C1 EF 05 45 EF 90 1F 96 01 A0 B7 C7 03 10 +0D 47 98 C3 B1 B5 6C 43 30 43 31 65 13 05 C5 E8 +EF 90 7F 98 03 25 C9 07 E3 F6 A4 E6 37 25 02 50 +13 05 45 91 EF 90 3F 95 03 25 C9 07 A1 BD 37 15 +02 50 13 05 05 75 EF 90 1F 94 03 27 C9 07 23 AC +0A 00 23 AE 0A 00 23 A0 0A 02 23 A2 0A 02 23 A4 +0A 02 23 A6 0A 02 23 A8 0A 02 23 AA 0A 02 E3 76 +EC C6 37 15 02 50 13 05 C5 77 EF 90 DF 90 03 27 +C9 07 A1 B9 37 25 02 50 13 05 85 8E EF 90 BF 8F +03 27 C9 07 C5 B9 8D 44 0D B7 B1 64 93 84 C4 E8 +13 85 04 1C EF 90 3F 90 83 27 C9 07 A1 DF A2 85 +13 85 C4 1E EF 90 3F 8F 83 27 C9 07 A1 D7 81 45 +13 85 44 20 EF 90 3F 8E 35 BF DC 42 93 F7 C7 3F +85 C7 89 47 E3 FA E7 C4 37 15 02 50 13 05 85 7A +EF 90 7F 8A 03 27 C9 07 2D B1 37 25 02 50 13 05 +45 93 EF 90 5F 89 D1 B3 51 EB 05 45 EF 90 BF 86 +01 A0 37 25 02 50 13 05 45 95 EF 90 DF 87 E9 B5 +81 45 19 EB 05 45 EF 90 1F 85 01 A0 81 45 0D EF +05 45 EF 90 5F 84 01 A0 31 64 13 04 C4 E8 13 05 +04 16 EF 90 5F 87 83 27 C9 07 E9 DF D6 85 13 05 +04 19 EF 90 5F 86 83 27 C9 07 E9 D7 81 45 13 05 +84 1A EF 90 5F 85 7D BF 31 64 13 04 C4 E8 13 05 +04 10 EF 90 5F 84 83 27 C9 07 DD DB D6 85 13 05 +04 13 EF 90 5F 83 83 27 C9 07 DD D3 81 45 13 05 +84 14 EF 90 5F 82 69 BF 99 45 61 B7 37 15 02 50 +13 05 C5 7E EF 90 2F FF 8D B7 95 45 49 B7 99 45 +BD BF 85 45 AD BF 89 45 9D BF 8D 45 8D BF 91 45 +BD B7 85 45 B9 BF 89 45 A9 BF 8D 45 99 BF 91 45 +89 BF 95 45 B9 B7 37 37 02 50 13 07 47 39 3C 43 +74 43 D5 8F E3 8E 07 C8 85 B5 79 71 4A D0 37 09 +02 50 03 28 C9 07 22 D4 4E CE 52 CC 5A C8 5E C6 +06 D6 26 D2 56 CA 62 C4 89 47 83 4A 07 00 3A 8A +2A 8B AE 89 B2 8B 36 84 63 EE 07 27 B7 97 03 10 +C4 4B 85 88 F5 DC 89 47 63 E4 07 29 B7 B5 03 10 +DA 87 13 06 0B 62 B3 85 65 41 94 43 33 87 F5 00 +91 07 14 C3 E3 9B C7 FE 03 CB 09 00 63 09 0B 10 +83 C7 29 00 37 C7 03 10 09 4C 86 07 93 F7 E7 03 +93 E7 17 00 1C C7 63 66 0C 2F B7 97 03 10 23 A0 +07 08 23 A2 07 08 23 A4 07 08 23 A6 07 08 23 A8 +07 08 23 AA 07 08 23 AC 07 08 23 AE 07 08 B7 77 +03 10 23 A0 07 2A 23 A2 07 2A 23 A4 07 2A 23 A6 +07 2A 23 A8 07 2A 23 AA 07 2A 23 AC 07 2A 23 AE +07 2A 23 A0 07 2C 37 C7 03 10 5C 47 89 8B F5 DF +83 C6 19 00 85 47 63 8D F6 2C 89 47 63 FA 07 01 +37 25 02 50 13 05 C5 AA EF 90 EF EB 03 28 C9 07 +B7 97 03 10 03 AC 07 08 63 13 0C 30 03 A7 07 08 +03 AC 47 08 63 14 0C 56 03 A7 47 08 03 AC 87 08 +63 10 0C 56 03 A7 87 08 03 AC C7 08 63 1C 0C 54 +03 A7 C7 08 03 AC 07 09 63 11 0C 4A 03 A7 07 09 +03 AC 47 09 63 1D 0C 48 03 A7 47 09 03 AC 87 09 +63 19 0C 48 03 A7 87 09 03 AC C7 09 9D 45 63 19 +0C 2A 83 A7 C7 09 89 47 63 F0 07 07 37 25 02 50 +13 05 85 AD EF 90 2F E4 03 28 C9 07 B1 A0 03 A7 +49 00 B7 97 03 10 23 A0 E7 08 03 A7 89 00 23 A2 +E7 08 03 A7 C9 00 23 A4 E7 08 03 A7 09 01 23 A6 +E7 08 03 A7 49 01 23 A8 E7 08 03 A7 89 01 23 AA +E7 08 03 A7 C9 01 23 AC E7 08 03 A7 09 02 23 AE +E7 08 89 47 E3 E4 07 FB 03 A7 0B 00 B7 07 03 10 +09 4C 98 CF 03 A7 4B 00 D8 CF 03 A7 8B 00 98 D3 +03 A7 CB 00 D8 D3 03 A7 0B 01 98 D7 03 A7 4B 01 +D8 D7 03 A7 8B 01 98 DB 03 A7 CB 01 D8 DB 03 A7 +0B 02 98 DF 03 A7 4B 02 D8 DF 03 A7 8B 02 B8 C3 +03 A7 CB 02 F8 C3 03 A7 0B 03 B8 C7 03 A7 4B 03 +F8 C7 03 A7 8B 03 B8 CB 03 A7 CB 03 F8 CB 63 6A +0C 0B B7 97 03 10 23 A8 87 01 83 C7 29 00 C1 C7 +B7 C7 03 10 05 47 98 C7 37 37 02 50 13 07 47 39 +34 43 7C 43 D5 8F 91 EF 73 00 50 10 93 07 40 06 +01 00 FD 17 C2 07 C1 83 E5 FF 3C 43 74 43 D5 8F +E5 D7 03 25 C9 07 89 44 63 E1 A4 0A B7 C6 03 10 +93 86 06 80 81 45 81 8E 13 06 80 18 39 A0 93 95 +07 01 C1 81 11 04 63 85 C5 14 B3 87 86 00 84 43 +18 40 93 87 15 00 E3 04 97 FE 41 ED 05 45 EF 90 +8F CE 01 A0 37 25 02 50 13 05 C5 97 EF 90 AF CF +03 28 C9 07 A5 BB B7 C7 03 10 0D 47 98 C7 AD BF +37 25 02 50 13 05 05 9A EF 90 EF CD 03 28 C9 07 +B5 B3 37 25 02 50 13 05 85 AF EF 90 CF CC B7 97 +03 10 03 27 C9 07 23 A8 87 01 83 C7 29 00 DD CF +B7 C7 03 10 84 C7 89 47 63 FF E7 2C 37 15 02 50 +13 05 45 6D EF 90 2F CA 05 BF 6C 43 30 43 31 65 +13 05 C5 E8 EF 90 2F CB 03 25 C9 07 E3 F8 A4 F4 +37 25 02 50 13 05 85 B1 EF 90 EF C7 03 25 C9 07 +35 BF B1 69 93 89 C9 E8 13 85 89 27 EF 90 AF C8 +83 27 C9 07 A1 DF A6 85 13 85 C9 2A EF 90 AF C7 +83 27 C9 07 A1 D7 0C 40 13 85 49 2C EF 90 AF C6 +35 BF 37 25 02 50 13 05 45 9C EF 90 CF C3 B7 97 +03 10 03 28 C9 07 23 A0 07 08 23 A2 07 08 23 A4 +07 08 23 A6 07 08 23 A8 07 08 23 AA 07 08 23 AC +07 08 23 AE 07 08 E3 74 0C D1 37 25 02 50 13 05 +85 9E EF 90 4F C0 03 28 C9 07 D5 B9 8D 44 89 B7 +5C 47 93 F7 C7 3F B9 CB 89 47 E3 FB 07 D3 37 25 +02 50 13 05 45 A2 EF 90 0F BE 03 28 C9 07 31 B3 +63 84 0A 04 B7 C7 03 10 D8 4B 09 8B 75 DF DC 4B +83 46 1A 00 05 47 93 F7 C7 3F 63 89 E6 22 63 85 +07 20 63 1C 05 1E 05 45 EF 90 EF B8 01 A0 81 45 +63 13 08 08 05 45 EF 90 0F B8 01 A0 63 15 08 0A +05 45 EF 90 4F B7 01 A0 89 47 63 15 0B 0A 63 EC +A7 12 B7 97 03 10 A4 4F 03 24 4A 00 63 13 94 12 +E4 4F 03 24 8A 00 63 1C 94 10 A4 53 03 24 CA 00 +63 95 84 10 E4 53 03 24 0A 01 63 1E 94 0E A4 57 +03 24 4A 01 63 97 84 0E E4 57 03 24 8A 01 63 90 +84 0E A4 5B 03 24 CA 01 63 99 84 0C E4 5B 03 24 +0A 02 9D 45 63 0F 94 06 83 27 C9 07 D9 E7 05 45 +EF 90 6F B0 01 A0 31 64 13 04 C4 E8 13 05 C4 21 +EF 90 6F B3 83 27 C9 07 B5 D7 E2 85 13 05 84 24 +EF 90 6F B2 83 27 C9 07 B1 DF 81 45 13 05 04 26 +EF 90 6F B1 81 BF 37 25 02 50 13 05 45 A6 EF 90 +8F AE B9 B7 63 EC A7 0E B7 97 03 10 A0 4F 59 E8 +E0 4F 63 13 04 0E A0 53 63 1E 04 0C E0 53 69 E8 +A0 57 69 E4 E0 57 69 E0 A0 5B 4D EC E0 5B 9D 45 +3D E8 B2 50 22 54 92 54 02 59 F2 49 62 4A D2 4A +42 4B B2 4B 22 4C 45 61 82 80 B1 69 93 89 C9 E8 +13 85 C9 2D EF 90 2F AB 83 27 C9 07 AD D3 A6 85 +13 85 09 31 EF 90 2F AA 83 27 C9 07 A9 DB A2 85 +13 85 89 32 EF 90 2F A9 99 B7 99 45 35 BF 95 45 +25 BF 91 45 15 BF 8D 45 05 BF 89 45 35 B7 85 45 +25 B7 81 45 15 B7 37 25 02 50 13 05 85 C6 EF 90 +8F A4 C1 B5 81 45 83 27 C9 07 89 E7 05 45 EF 90 +8F A1 01 A0 B1 64 93 84 C4 E8 13 85 04 34 EF 90 +8F A4 83 27 C9 07 FD D3 A2 85 13 85 44 37 EF 90 +8F A3 83 27 C9 07 F9 DB 81 45 13 85 C4 38 EF 90 +8F A2 E9 B7 99 45 C1 B7 95 45 75 BF 91 45 65 BF +8D 45 55 BF 89 45 45 BF 85 45 75 B7 37 25 02 50 +13 05 85 C8 EF 90 2F 9E 01 B7 91 45 15 BD 95 45 +05 BD 99 45 35 B5 37 37 02 50 13 07 47 39 34 43 +7C 43 D5 8F E3 82 07 C6 91 B3 37 25 02 50 13 05 +05 BD EF 90 4F 9B 01 B5 89 47 63 E6 A7 04 03 D7 +09 00 85 47 E3 17 F7 EE 83 47 2A 00 37 07 03 30 +A2 07 93 E7 37 0B 23 26 F7 0C E1 BD 85 CF 89 47 +E3 F9 A7 EC 22 54 B2 50 92 54 02 59 F2 49 62 4A +D2 4A 42 4B B2 4B 22 4C 37 25 02 50 13 05 85 B3 +45 61 6F 90 4F 96 37 25 02 50 13 05 C5 C1 EF 90 +8F 95 75 B7 09 E5 05 45 EF 90 EF 92 01 A0 37 25 +02 50 13 05 05 B8 EF 90 0F 94 F5 B7 85 45 49 BB +89 45 79 B3 8D 45 69 B3 79 71 22 D4 37 04 02 50 +03 28 C4 07 26 D2 4A D0 52 CC 56 CA 5E C6 66 C2 +3A 8A 06 D6 4E CE 5A C8 62 C4 6A C0 09 47 03 4B +0A 00 83 49 2A 00 AA 8A AE 84 B2 8C B6 8B 3E 89 +63 63 07 2F B7 97 03 10 03 AC 47 01 13 7C 1C 00 +E3 0C 0C FE 89 47 63 E4 07 35 D6 87 37 B6 03 10 +93 8A 0A 62 1D 8E 94 43 33 07 F6 00 91 07 14 C3 +E3 9B 57 FF 83 CA 04 00 63 88 0A 10 83 C7 24 00 +37 C7 03 10 09 4D 86 07 93 F7 E7 03 93 E7 17 00 +1C C7 63 60 0D 39 B7 97 03 10 23 A0 07 08 23 A2 +07 08 23 A4 07 08 23 A6 07 08 23 A8 07 08 23 AA +07 08 23 AC 07 08 23 AE 07 08 B7 77 03 10 23 A0 +07 2A 23 A2 07 2A 23 A4 07 2A 23 A6 07 2A 23 A8 +07 2A 23 AA 07 2A 23 AC 07 2A 23 AE 07 2A 23 A0 +07 2C 37 C7 03 10 5C 47 89 8B F5 DF 83 C6 14 00 +85 47 63 88 F6 38 89 47 63 FA 07 01 37 25 02 50 +13 05 C5 AA EF 90 2F 83 03 28 C4 07 B7 97 03 10 +03 AD 07 08 63 17 0D 38 03 A7 07 08 03 AD 47 08 +63 11 0D 38 03 A7 47 08 03 AD 87 08 63 1B 0D 36 +03 A7 87 08 03 AD C7 08 63 15 0D 36 03 A7 C7 08 +03 AD 07 09 63 1F 0D 34 03 A7 07 09 03 AD 47 09 +63 19 0D 34 03 A7 47 09 03 AD 87 09 63 13 0D 34 +03 A7 87 09 03 AD C7 09 63 1D 0D 32 83 A7 C7 09 +89 47 63 F8 07 05 37 25 02 50 13 05 85 AD EF 80 +9F FB 03 28 C4 07 35 A8 D8 40 B7 97 03 10 23 A0 +E7 08 98 44 23 A2 E7 08 D8 44 23 A4 E7 08 98 48 +23 A6 E7 08 D8 48 23 A8 E7 08 98 4C 23 AA E7 08 +D8 4C 23 AC E7 08 98 50 23 AE E7 08 89 47 E3 EC +07 FB 03 A7 0C 00 B7 07 03 10 98 CF 03 A7 4C 00 +D8 CF 03 A7 8C 00 98 D3 03 A7 CC 00 D8 D3 03 A7 +0C 01 98 D7 03 A7 4C 01 D8 D7 03 A7 8C 01 98 DB +03 A7 CC 01 D8 DB 03 A7 0C 02 98 DF 03 A7 4C 02 +D8 DF 03 A7 8C 02 B8 C3 03 A7 CC 02 F8 C3 03 A7 +0C 03 B8 C7 03 A7 4C 03 F8 C7 03 A7 8C 03 B8 CB +03 A7 CC 03 F8 CB 63 14 0B 0A 89 4C 63 EF 0C 0B +B7 97 03 10 23 A8 97 01 83 C7 24 00 63 9E 07 0E +B7 C7 03 10 0D 47 98 C7 37 37 02 50 13 07 47 39 +34 43 7C 43 D5 8F 91 EF 73 00 50 10 93 07 40 06 +01 00 FD 17 C2 07 C1 83 E5 FF 3C 43 74 43 D5 8F +E5 D7 03 25 C4 07 09 4C 63 6C AC 12 37 C6 03 10 +B7 55 FC EF 93 07 06 80 93 85 05 80 13 06 06 E2 +94 43 33 87 B7 00 5E 97 14 C3 91 07 E3 9A C7 FE +63 01 0B 0A 37 C7 03 10 5C 4B 89 8B F5 DF 83 46 +1A 00 85 47 63 8D F6 1E 5C 4B 93 F7 C7 3F 63 81 +07 1A 63 11 05 2A 05 45 EF 80 FF E4 01 A0 93 97 +19 00 11 67 13 07 17 FC 93 F7 F7 0F D9 8F 37 C7 +03 10 1C CB 89 4C E3 F5 0C F5 37 25 02 50 13 05 +85 CB EF 80 5F E4 B7 97 03 10 03 27 C4 07 23 A8 +97 01 83 C7 24 00 63 8B 07 14 B7 C7 03 10 23 A4 +87 01 89 47 63 FB E7 26 37 15 02 50 13 05 45 6D +EF 80 7F E1 15 B7 37 25 02 50 13 05 C5 97 EF 80 +9F E0 03 28 C4 07 39 B3 B7 C7 03 10 05 47 98 C7 +21 B7 89 47 63 8A 0A 08 63 EC A7 1A B7 97 03 10 +A4 4F 63 9F 04 18 E4 4F 63 91 04 22 A4 53 63 9C +04 20 E4 53 63 97 04 20 A4 57 63 9C 04 20 E4 57 +63 97 04 20 A4 5B 63 98 04 20 E4 5B 9D 45 63 9A +04 16 B2 50 22 54 92 54 02 59 F2 49 62 4A D2 4A +42 4B B2 4B 22 4C 92 4C 02 4D 45 61 82 80 37 25 +02 50 13 05 05 9A EF 80 1F D9 03 28 C4 07 75 B1 +6C 43 30 43 31 65 13 05 C5 E8 EF 80 DF D9 03 25 +C4 07 E3 7D AC EA 37 25 02 50 13 05 85 CD EF 80 +9F D6 03 25 C4 07 5D B5 63 E5 A7 10 B7 97 03 10 +B8 4F 23 20 E9 00 F8 4F 23 22 E9 00 B8 53 23 24 +E9 00 F8 53 23 26 E9 00 B8 57 23 28 E9 00 F8 57 +23 2A E9 00 B8 5B 23 2C E9 00 FC 5B 23 2E F9 00 +8D BF 37 25 02 50 13 05 45 9C EF 80 DF D1 B7 97 +03 10 03 28 C4 07 23 A0 07 08 23 A2 07 08 23 A4 +07 08 23 A6 07 08 23 A8 07 08 23 AA 07 08 23 AC +07 08 23 AE 07 08 E3 7A 0D C7 37 25 02 50 13 05 +85 9E EF 80 5F CE 03 28 C4 07 85 B1 0D 4C 75 B5 +89 47 63 E1 A7 0C 03 D7 04 00 85 47 E3 1B F7 F0 +93 97 89 00 93 E7 37 0B 37 07 03 30 23 26 F7 0C +09 B7 5C 47 93 F7 C7 3F D9 C3 89 47 E3 F0 07 C9 +37 25 02 50 13 05 45 A2 EF 80 FF C9 03 28 C4 07 +99 B9 63 18 08 08 05 45 EF 80 FF C6 01 A0 5C 4B +93 F7 C7 3F BD C3 89 47 E3 F5 A7 EC 22 54 B2 50 +92 54 02 59 F2 49 62 4A D2 4A 42 4B B2 4B 22 4C +92 4C 02 4D 37 25 02 50 13 05 85 B3 45 61 6F 80 +9F C5 37 25 02 50 13 05 45 D4 EF 80 DF C4 FD B5 +81 45 83 27 C4 07 F1 E3 05 45 EF 80 DF C1 01 A0 +37 25 02 50 13 05 85 C8 EF 80 FF C2 81 B5 63 1F +08 08 05 45 EF 80 3F C0 01 A0 51 E1 05 45 EF 80 +9F BF 01 A0 37 25 02 50 13 05 C5 C1 EF 80 BF C0 +1D BF B1 64 93 84 C4 E8 81 45 13 85 44 3A EF 80 +9F C1 83 27 C4 07 A5 D3 EA 85 13 85 04 3D EF 80 +9F C0 83 27 C4 07 A1 DB 81 45 13 85 84 3E EF 80 +9F BF 91 B7 37 25 02 50 13 05 85 CF EF 80 BF BC +99 BB 8D 45 BD BF 89 45 AD BF 85 45 9D BF 95 45 +8D BF 91 45 BD B7 99 45 AD B7 37 37 02 50 13 07 +47 39 3C 43 74 43 D5 8F E3 80 07 CC 1D BD 37 25 +02 50 13 05 05 B8 EF 80 1F B9 8D BF 37 25 02 50 +13 05 45 A6 EF 80 3F B8 A9 BF 31 69 13 09 C9 E8 +13 05 09 40 EF 80 3F B9 83 27 C4 07 E3 86 07 F2 +A6 85 13 05 49 43 EF 80 1F B8 83 27 C4 07 E3 8D +07 F0 81 45 13 05 C9 44 EF 80 FF B6 31 B7 01 11 +22 CC 37 04 02 50 03 28 C4 07 26 CA 4E C6 52 C4 +56 C2 06 CE 4A C8 89 47 03 C9 06 00 B6 84 AA 8A +2E 8A B2 89 63 E4 07 23 37 97 03 10 5C 4B 85 8B +F5 DF 89 47 63 E3 07 27 05 67 13 07 07 C6 B7 A5 +03 10 D6 87 33 86 EA 00 B3 85 55 41 94 43 33 87 +F5 00 91 07 14 C3 E3 9B C7 FE 37 C6 03 10 13 06 +06 80 D2 87 93 05 0A 62 33 06 46 41 94 43 33 07 +F6 00 91 07 14 C3 E3 9B B7 FE 89 47 63 E6 07 21 +03 A7 09 00 B7 07 03 10 98 CF 03 A7 49 00 D8 CF +03 A7 89 00 98 D3 03 A7 C9 00 D8 D3 03 A7 09 01 +98 D7 03 A7 49 01 D8 D7 03 A7 89 01 98 DB 03 A7 +C9 01 D8 DB 03 A7 09 02 98 DF 03 A7 49 02 D8 DF +03 A7 89 02 B8 C3 03 A7 C9 02 F8 C3 03 A7 09 03 +B8 C7 03 A7 49 03 F8 C7 03 A7 89 03 B8 CB 03 A7 +C9 03 F8 CB 63 0E 09 00 83 C7 24 00 11 67 13 07 +17 FC 86 07 93 F7 F7 0F D9 8F 37 C7 03 10 1C CB +89 49 63 EE 09 15 B7 97 03 10 0D 47 98 CB 37 37 +02 50 13 07 47 39 34 43 7C 43 D5 8F 91 EF 73 00 +50 10 93 07 40 06 01 00 FD 17 C2 07 C1 83 E5 FF +3C 43 74 43 D5 8F E5 D7 83 26 C4 07 89 49 63 E8 +D9 06 63 09 09 08 37 C7 03 10 5C 4B 89 8B F5 DF +03 C6 14 00 85 47 63 03 F6 16 5C 4B 93 F7 C7 3F +63 96 07 14 89 47 63 E9 D7 1A B7 97 03 10 A4 4F +63 90 04 20 E4 4F 63 96 04 26 A4 53 63 91 04 26 +E4 53 63 9C 04 24 A4 57 63 97 04 24 E4 57 63 92 +04 24 A4 5B 63 9D 04 22 E4 5B 9D 45 D9 CC 83 27 +C4 07 63 9C 07 1E 05 45 EF 80 FF 97 01 A0 6C 43 +30 43 31 65 13 05 C5 E8 EF 80 FF 9A 63 1D 09 0E +83 27 C4 07 63 F8 F9 00 37 25 02 50 13 05 C5 F4 +EF 80 7F 97 B7 97 03 10 83 A9 87 05 03 A9 44 00 +63 9C 29 0F 83 A9 C7 05 03 A9 84 00 63 9C 29 19 +83 A9 07 06 03 A9 C4 00 63 9E 29 17 83 A9 47 06 +03 A9 04 01 63 9A 29 17 83 A9 87 06 03 A9 44 01 +63 96 29 17 83 A9 C7 06 03 A9 84 01 63 92 29 17 +83 A9 07 07 03 A9 C4 01 63 90 29 17 83 A9 47 07 +03 A9 04 02 9D 45 63 12 39 0B F2 40 62 44 D2 44 +42 49 B2 49 22 4A 92 4A 05 61 82 80 37 25 02 50 +13 05 45 D6 EF 80 3F 8F 03 28 C4 07 F1 B3 37 25 +02 50 13 05 C5 DC EF 80 1F 8E 83 27 C4 07 37 97 +03 10 8D 46 14 CB 63 FF F9 0C 37 15 02 50 13 05 +45 6D EF 80 5F 8C 61 B5 37 25 02 50 13 05 C5 DA +EF 80 7F 8B 03 28 C4 07 E5 B3 37 25 02 50 13 05 +85 D8 EF 80 5F 8A 03 28 C4 07 79 B3 C9 EE 05 45 +EF 80 7F 87 01 A0 83 26 C4 07 71 B5 5C 4B 93 F7 +C7 3F AD CF 89 47 E3 F2 D7 EA 37 25 02 50 13 05 +C5 DE EF 80 5F 87 B9 A0 81 45 83 27 C4 07 89 E7 +05 45 EF 80 5F 84 01 A0 B1 64 93 84 C4 E8 13 85 +84 4C EF 80 5F 87 83 27 C4 07 FD D3 CE 85 13 85 +C4 4F EF 80 5F 86 83 27 C4 07 F9 DB CA 85 13 85 +44 51 EF 80 5F 85 E9 B7 37 25 02 50 13 05 05 ED +EF 80 7F 82 03 27 C4 07 89 47 E3 F0 E7 E4 37 25 +02 50 13 05 C5 F1 EF 80 1F 81 05 BD A1 EA 05 45 +EF 80 6F FE 01 A0 37 25 02 50 13 05 45 E8 EF 80 +8F FF B1 BF 37 37 02 50 13 07 47 39 34 43 7C 43 +D5 8F E3 8E 07 DA 83 26 C4 07 E3 1E 09 DC 9D B5 +81 45 35 B5 89 45 95 B7 8D 45 85 B7 91 45 B1 BF +95 45 A1 BF 85 45 91 BF 99 45 81 BF 37 25 02 50 +13 05 45 E3 EF 80 2F FB 5D B7 31 69 13 09 C9 E8 +13 05 49 46 EF 80 2F FC 83 27 C4 07 E3 8D 07 DE +A6 85 13 05 89 49 EF 80 0F FB 83 27 C4 07 E3 84 +07 DE 81 45 13 05 09 4B EF 80 EF F9 E9 BB 99 45 +F9 B3 95 45 E9 B3 91 45 D9 B3 8D 45 C9 B3 89 45 +7D BB 85 45 6D BB 01 11 22 CC 37 04 02 50 03 28 +C4 07 26 CA 4E C6 52 C4 56 C2 06 CE 4A C8 89 47 +03 C9 06 00 B6 84 AA 8A 2E 8A B2 89 63 E8 07 1B +37 97 03 10 5C 4B 85 8B F5 DF 89 47 63 E9 07 1B +05 67 13 07 07 C6 B7 A5 03 10 D6 87 33 86 EA 00 +B3 85 55 41 94 43 33 87 F5 00 91 07 14 C3 E3 9B +C7 FE 37 C6 03 10 13 06 06 80 D2 87 93 05 0A 62 +33 06 46 41 94 43 33 07 F6 00 91 07 14 C3 E3 9B +B7 FE 89 47 63 E3 07 1B 03 A7 09 00 B7 07 03 10 +98 CF 03 A7 49 00 D8 CF 03 A7 89 00 98 D3 03 A7 +C9 00 D8 D3 03 A7 09 01 98 D7 03 A7 49 01 D8 D7 +03 A7 89 01 98 DB 03 A7 C9 01 D8 DB 03 A7 09 02 +98 DF 03 A7 49 02 D8 DF 03 A7 89 02 B8 C3 03 A7 +C9 02 F8 C3 03 A7 09 03 B8 C7 03 A7 49 03 F8 C7 +03 A7 89 03 B8 CB 03 A7 C9 03 F8 CB 63 0E 09 00 +83 C7 24 00 11 67 13 07 17 FC 86 07 93 F7 F7 0F +D9 8F 37 C7 03 10 1C CB 89 49 63 EB 09 0F B7 97 +03 10 0D 47 98 CB 37 37 02 50 13 07 47 39 34 43 +7C 43 D5 8F 91 EF 73 00 50 10 93 07 40 06 01 00 +FD 17 C2 07 C1 83 E5 FF 3C 43 74 43 D5 8F E5 D7 +83 26 C4 07 89 49 63 E3 D9 04 63 04 09 06 37 C7 +03 10 5C 4B 89 8B F5 DF 03 C6 14 00 85 47 63 07 +F6 0E 5C 4B 93 F7 C7 3F E9 EF 89 47 63 FF D7 04 +37 25 02 50 13 05 05 ED 62 44 F2 40 D2 44 42 49 +B2 49 22 4A 92 4A 05 61 6F 80 EF DD 6C 43 30 43 +31 65 13 05 C5 E8 EF 80 0F DF 63 11 09 0A 83 27 +C4 07 63 F8 F9 00 37 25 02 50 13 05 05 00 EF 80 +8F DB 37 97 03 10 34 4F 93 07 C7 05 78 4F D8 43 +98 47 D8 47 98 4B D8 4B 9C 4F F2 40 62 44 D2 44 +42 49 B2 49 22 4A 92 4A 05 61 82 80 37 25 02 50 +13 05 45 D6 EF 80 2F D8 03 28 C4 07 91 B5 37 25 +02 50 13 05 85 D8 EF 80 0F D7 03 28 C4 07 89 B5 +37 25 02 50 13 05 C5 DC EF 80 EF D5 83 27 C4 07 +37 97 03 10 8D 46 14 CB 63 FD F9 04 37 15 02 50 +13 05 45 6D EF 80 2F D4 FD B5 37 25 02 50 13 05 +C5 DA EF 80 4F D3 03 28 C4 07 B9 B5 83 26 C4 07 +39 B7 8D E2 05 45 EF 80 0F D0 01 A0 5C 4B 93 F7 +C7 3F 95 CF 89 47 E3 FA D7 F6 37 25 02 50 13 05 +C5 F6 19 BF 37 25 02 50 13 05 45 E8 EF 80 AF CF +D1 BF 37 37 02 50 13 07 47 39 34 43 7C 43 D5 8F +E3 83 07 EA 83 26 C4 07 E3 13 09 EC 1D B7 89 E6 +05 45 EF 80 4F CB 01 A0 37 25 02 50 13 05 45 FB +EF 80 6F CC F5 B7 79 71 4A D0 37 09 02 50 03 28 +C9 07 4E CE 5E C6 62 C4 66 C2 06 D6 22 D4 26 D2 +52 CC 56 CA 5A C8 6A C0 89 47 03 CB 06 00 03 CA +26 00 B6 89 2A 8C AE 8B B2 8C 63 EE 07 2B B7 94 +03 10 C0 48 05 88 75 DC 83 4A 0C 00 63 8C 0A 08 +83 47 2C 00 37 C7 03 10 09 4D 86 07 93 F7 E7 03 +93 E7 17 00 1C C3 63 6C 0D 39 23 AC 04 00 23 AE +04 00 23 A0 04 02 23 A2 04 02 23 A4 04 02 23 A6 +04 02 23 A8 04 02 23 AA 04 02 B7 97 03 10 23 AC +07 02 23 AE 07 02 23 A0 07 04 23 A2 07 04 23 A4 +07 04 23 A6 07 04 23 A8 07 04 23 AA 07 04 37 C7 +03 10 5C 43 89 8B F5 DF 83 46 1C 00 85 47 63 93 +F6 08 5C 43 93 F7 C7 3F 63 88 07 3A 89 47 63 FB +07 07 37 15 02 50 13 05 85 7A EF 80 CF BE 03 28 +C9 07 8D A0 83 27 4C 00 9C CC 83 27 8C 00 DC CC +83 27 CC 00 9C D0 83 27 0C 01 DC D0 83 27 4C 01 +9C D4 83 27 8C 01 DC D4 83 27 CC 01 9C D8 83 27 +0C 02 DC D8 83 27 4C 02 9C DC 83 27 8C 02 DC DC +83 27 CC 02 BC C0 83 27 0C 03 FC C0 83 27 4C 03 +BC C4 83 27 8C 03 FC C4 83 27 CC 03 BC C8 83 27 +0C 04 FC C8 37 C6 03 10 DE 87 13 06 06 80 93 8B +0B 62 1D 8E 94 43 33 07 F6 00 91 07 14 C3 E3 9B +77 FF 89 47 63 EC 07 27 03 A7 0C 00 B7 07 03 10 +98 CF 03 A7 4C 00 D8 CF 03 A7 8C 00 98 D3 03 A7 +CC 00 D8 D3 03 A7 0C 01 98 D7 03 A7 4C 01 D8 D7 +03 A7 8C 01 98 DB 03 A7 CC 01 D8 DB 03 A7 0C 02 +98 DF 03 A7 4C 02 D8 DF 03 A7 8C 02 B8 C3 03 A7 +CC 02 F8 C3 03 A7 0C 03 B8 C7 03 A7 4C 03 F8 C7 +03 A7 8C 03 B8 CB 03 A7 CC 03 F8 CB 63 12 0B 0C +89 47 63 ED 07 0D B7 97 03 10 11 47 98 CB 83 47 +2C 00 63 89 07 14 B7 C7 03 10 05 47 98 C3 37 37 +02 50 13 07 47 39 34 43 7C 43 D5 8F 9D E3 73 00 +50 10 93 07 40 06 01 00 FD 17 C2 07 C1 83 E5 FF +3C 43 74 43 D5 8F E5 D7 03 28 C9 07 09 44 63 65 +04 0F 63 1E 0B 10 63 93 0A 16 B7 97 03 10 A4 4F +03 A4 49 00 63 1C 94 32 E4 4F 03 A4 89 00 63 1F +94 30 A4 53 03 A4 C9 00 63 1C 94 30 E4 53 03 A4 +09 01 63 99 84 26 A4 57 03 A4 49 01 63 92 84 26 +E4 57 03 A4 89 01 63 9B 84 24 A4 5B 03 A4 C9 01 +63 9E 84 24 E4 5B 03 A4 09 02 9D 45 63 02 94 14 +83 27 C9 07 63 94 07 26 05 45 EF 80 CF A1 01 A0 +93 17 1A 00 11 67 13 07 17 FC 93 F7 F7 0F D9 8F +37 C7 03 10 1C CB 89 47 E3 F7 07 F3 37 25 02 50 +13 05 05 0D EF 80 2F A1 B7 97 03 10 11 47 03 28 +C9 07 98 CB 83 47 2C 00 63 83 07 12 B7 C7 03 10 +80 C3 89 47 E3 FD 07 F1 37 15 02 50 13 05 45 6D +EF 80 6F 9E 37 37 02 50 13 07 47 39 3C 43 74 43 +D5 8F 91 D7 15 B7 37 25 02 50 13 05 05 02 EF 80 +8F 9C 03 28 C9 07 25 BB 6C 43 30 43 31 65 13 05 +C5 E8 EF 80 4F 9D 03 28 C9 07 63 12 0B 02 63 9F +0A 04 E3 74 04 F1 37 25 02 50 13 05 45 24 EF 80 +8F 99 E5 BD B7 C7 03 10 0D 47 98 C3 4D BD 37 C7 +03 10 5C 4B 89 8B F5 DF 83 C6 19 00 85 47 63 8B +F6 0E 5C 4B 93 F7 C7 3F C9 EF 89 47 63 E2 07 15 +03 57 0C 00 85 47 63 1D F7 04 93 17 8A 00 93 E7 +37 0B 37 07 03 30 23 26 F7 0C 99 A0 63 78 04 01 +37 25 02 50 13 05 C5 26 EF 80 EF 93 B7 97 03 10 +A0 4F 63 19 04 0E E0 4F 63 16 04 1C A0 53 63 15 +04 1C E0 53 63 1A 04 1A A0 57 63 15 04 1A E0 57 +63 10 04 1A A0 5B 63 19 04 10 E0 5B 9D 45 61 E4 +B2 50 22 54 92 54 02 59 F2 49 62 4A D2 4A 42 4B +B2 4B 22 4C 92 4C 02 4D 45 61 82 80 37 25 02 50 +13 05 85 0A EF 80 2F 8E 03 28 C9 07 B5 BB 0D 44 +F1 BD 63 1E 08 0A 05 45 EF 80 EF 8A 01 A0 37 25 +02 50 13 05 85 04 EF 80 0F 8C 03 28 C9 07 23 AC +04 00 23 AE 04 00 23 A0 04 02 23 A2 04 02 23 A4 +04 02 23 A6 04 02 23 A8 04 02 23 AA 04 02 E3 7E +0D C5 37 25 02 50 13 05 85 07 EF 80 CF 88 03 28 +C9 07 A1 B1 5C 4B 93 F7 C7 3F A9 C7 89 47 E3 F9 +07 F7 22 54 B2 50 92 54 02 59 F2 49 62 4A D2 4A +42 4B B2 4B 22 4C 92 4C 02 4D 37 25 02 50 13 05 +85 0F 45 61 6F 80 2F 85 63 1C 08 04 05 45 EF 80 +8F 82 01 A0 81 45 83 27 C9 07 D9 EB 05 45 EF 80 +8F 81 01 A0 63 15 08 04 05 45 EF 80 CF 80 01 A0 +37 25 02 50 13 05 05 1F EF 80 EF 81 55 BD 37 25 +02 50 13 05 C5 19 EF 80 0F 81 35 BF 95 45 C9 B3 +91 45 7D BB 8D 45 6D BB 99 45 75 BF 99 45 4D BB +37 15 02 50 13 05 C5 7E EF 70 FF FE 45 B7 37 25 +02 50 13 05 85 14 EF 70 1F FE 7D B7 B1 69 93 89 +C9 E8 13 85 C9 52 EF 70 1F FF 83 27 C9 07 E3 85 +07 D8 A6 85 13 85 09 56 EF 70 FF FD 83 27 C9 07 +E3 8C 07 D6 A2 85 13 85 89 57 EF 70 DF FC AD B3 +B1 64 93 84 C4 E8 13 85 04 59 EF 70 DF FB 83 27 +C9 07 A9 DF A2 85 13 85 44 5C EF 70 DF FA 83 27 +C9 07 A9 D7 81 45 13 85 C4 5D EF 70 DF F9 3D BF +95 45 15 BF 91 45 05 BF 8D 45 35 B7 85 45 0D B3 +89 45 39 BB 85 45 05 B7 89 45 31 BF 81 45 09 BB +79 71 26 D2 B7 04 02 50 03 A8 C4 07 4E CE 5A C8 +5E C6 62 C4 06 D6 22 D4 4A D0 52 CC 56 CA 66 C2 +89 47 03 CA 06 00 03 C9 26 00 B6 89 2A 8B AE 8B +32 8C 63 ED 07 29 37 94 03 10 5C 48 85 8B F5 DF +83 4A 0B 00 63 8C 0A 08 83 47 2B 00 37 C7 03 10 +89 4C 86 07 93 F7 E7 03 93 E7 17 00 1C C3 63 E1 +0C 35 23 2C 04 00 23 2E 04 00 23 20 04 02 23 22 +04 02 23 24 04 02 23 26 04 02 23 28 04 02 23 2A +04 02 B7 97 03 10 23 AC 07 02 23 AE 07 02 23 A0 +07 04 23 A2 07 04 23 A4 07 04 23 A6 07 04 23 A8 +07 04 23 AA 07 04 37 C7 03 10 5C 43 89 8B F5 DF +83 46 1B 00 85 47 63 93 F6 08 5C 43 93 F7 C7 3F +63 8C 07 34 89 47 63 FB 07 07 37 15 02 50 13 05 +85 7A EF 70 5F E8 03 A8 C4 07 8D A0 83 27 4B 00 +1C CC 83 27 8B 00 5C CC 83 27 CB 00 1C D0 83 27 +0B 01 5C D0 83 27 4B 01 1C D4 83 27 8B 01 5C D4 +83 27 CB 01 1C D8 83 27 0B 02 5C D8 83 27 4B 02 +1C DC 83 27 8B 02 5C DC 83 27 CB 02 3C C0 83 27 +0B 03 7C C0 83 27 4B 03 3C C4 83 27 8B 03 7C C4 +83 27 CB 03 3C C8 83 27 0B 04 7C C8 37 C6 03 10 +DE 87 13 06 06 80 93 8B 0B 62 1D 8E 94 43 33 07 +F6 00 91 07 14 C3 E3 9B FB FE 89 47 63 E3 07 23 +03 27 0C 00 B7 07 03 10 98 CF 03 27 4C 00 D8 CF +03 27 8C 00 98 D3 03 27 CC 00 D8 D3 03 27 0C 01 +98 D7 03 27 4C 01 D8 D7 03 27 8C 01 98 DB 03 27 +CC 01 D8 DB 03 27 0C 02 98 DF 03 27 4C 02 D8 DF +03 27 8C 02 B8 C3 03 27 CC 02 F8 C3 03 27 0C 03 +B8 C7 03 27 4C 03 F8 C7 03 27 8C 03 B8 CB 03 27 +CC 03 F8 CB 63 1F 0A 08 09 44 63 6A 04 0B B7 97 +03 10 11 47 98 CB 83 47 2B 00 37 C7 03 10 86 07 +93 F7 E7 03 93 E7 17 00 1C C3 37 37 02 50 13 07 +47 39 3C 43 74 43 D5 8F 9D E3 73 00 50 10 93 07 +40 06 01 00 FD 17 C2 07 C1 83 E5 FF 3C 43 74 43 +D5 8F E5 D7 03 A8 C4 07 09 44 63 66 04 11 63 00 +0A 0C 37 C7 03 10 5C 4B 89 8B F5 DF 83 C6 19 00 +85 47 63 8A F6 1A 5C 4B 93 F7 C7 3F 63 9C 07 14 +89 47 63 E7 07 21 03 57 0B 00 85 47 63 1E F7 10 +93 17 89 00 93 E7 37 0B 37 07 03 30 23 26 F7 0C +21 A2 93 17 19 00 11 67 13 07 17 FC 93 F7 F7 0F +D9 8F 37 C7 03 10 1C CB 09 44 E3 7A 04 F5 37 25 +02 50 13 05 05 0D EF 70 1F CD B7 97 03 10 11 47 +03 A8 C4 07 98 CB 83 47 2B 00 37 C7 03 10 86 07 +93 F7 E7 03 93 E7 17 00 1C C3 E3 70 04 F5 37 15 +02 50 13 05 45 6D EF 70 1F CA 37 37 02 50 13 07 +47 39 34 43 7C 43 D5 8F 8D DB A9 B7 37 25 02 50 +13 05 05 02 EF 70 3F C8 03 A8 C4 07 A9 BB 63 89 +0A 06 B7 97 03 10 A0 4F 63 11 04 18 E0 4F 63 19 +04 18 A0 53 63 18 04 18 E0 53 63 16 04 16 A0 57 +63 11 04 16 E0 57 63 1C 04 14 A0 5B 63 11 04 16 +E0 5B 9D 45 31 C8 83 A7 C4 07 63 97 07 16 05 45 +EF 70 7F C1 01 A0 6C 43 30 43 31 65 13 05 C5 E8 +EF 70 7F C4 03 A8 C4 07 E3 15 0A EE 63 94 0A 0E +63 78 04 01 37 25 02 50 13 05 45 2A EF 70 BF C0 +37 97 03 10 34 4F 93 07 C7 05 78 4F D8 43 98 47 +D8 47 98 4B D8 4B 9C 4F B2 50 22 54 92 54 02 59 +F2 49 62 4A D2 4A 42 4B B2 4B 22 4C 92 4C 45 61 +82 80 37 25 02 50 13 05 85 0A EF 70 DF BC 03 A8 +C4 07 F9 B3 63 17 08 0A 05 45 EF 70 DF B9 01 A0 +37 25 02 50 13 05 85 04 EF 70 FF BA 03 A8 C4 07 +23 2C 04 00 23 2E 04 00 23 20 04 02 23 22 04 02 +23 24 04 02 23 26 04 02 23 28 04 02 23 2A 04 02 +E3 F9 0C CB 37 25 02 50 13 05 85 07 EF 70 BF B7 +03 A8 C4 07 79 B9 5C 4B 93 F7 C7 3F A9 C7 89 47 +E3 FC 07 F7 22 54 B2 50 92 54 02 59 F2 49 62 4A +D2 4A 42 4B B2 4B 22 4C 92 4C 37 25 02 50 13 05 +85 0F 45 61 6F 70 3F B4 63 1D 08 04 05 45 EF 70 +9F B1 01 A0 E3 7F 04 EB 37 25 02 50 13 05 C5 26 +EF 70 7F B2 7D B5 63 13 08 08 05 45 EF 70 BF AF +01 A0 37 25 02 50 13 05 C5 19 EF 70 DF B0 A9 B7 +37 25 02 50 13 05 05 1F EF 70 FF AF ED B3 95 45 +5D BD 91 45 4D BD 8D 45 7D B5 81 45 6D B5 99 45 +5D B5 37 15 02 50 13 05 C5 7E EF 70 DF AD 79 BF +85 45 51 BD 89 45 41 BD 31 69 13 09 C9 E8 13 05 +49 5F EF 70 5F AE 83 A7 C4 07 E3 82 07 E8 A2 85 +13 05 89 62 EF 70 3F AD 83 A7 C4 07 E3 89 07 E6 +81 45 13 05 09 64 EF 70 1F AC 95 B5 37 25 02 50 +13 05 85 14 EF 70 3F A9 8D BF 01 00 52 65 63 65 +69 76 65 64 20 4D 4C 4B 45 4D 20 6E 6F 74 69 66 +2F 20 65 72 72 20 69 6E 74 72 20 77 69 74 68 20 +73 74 61 74 75 73 20 3D 20 25 64 2F 20 25 64 0A +00 00 00 00 41 74 20 6F 66 66 73 65 74 20 5B 25 +64 5D 2C 20 6D 6C 6B 65 6D 5F 65 6E 63 61 70 73 +5F 6B 65 79 20 64 61 74 61 20 6D 69 73 6D 61 74 +63 68 21 0A 00 00 00 00 41 63 74 75 61 6C 20 20 +20 64 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +45 78 70 65 63 74 65 64 20 64 61 74 61 3A 20 30 +78 25 78 0A 00 00 00 00 41 74 20 6F 66 66 73 65 +74 20 5B 25 64 5D 2C 20 6D 6C 6B 65 6D 5F 64 65 +63 61 70 73 5F 6B 65 79 20 64 61 74 61 20 6D 69 +73 6D 61 74 63 68 21 0A 00 00 00 00 41 63 74 75 +61 6C 20 20 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 45 78 70 65 63 74 65 64 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 41 74 20 6F +66 66 73 65 74 20 5B 25 64 5D 2C 20 6D 6C 6B 65 +6D 5F 73 65 65 64 5F 64 20 64 61 74 61 20 6D 69 +73 6D 61 74 63 68 21 0A 00 00 00 00 41 63 74 75 +61 6C 20 20 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 45 78 70 65 63 74 65 64 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 41 74 20 6F +66 66 73 65 74 20 5B 25 64 5D 2C 20 6D 6C 6B 65 +6D 5F 73 65 65 64 5F 7A 20 64 61 74 61 20 6D 69 +73 6D 61 74 63 68 21 0A 00 00 00 00 41 63 74 75 +61 6C 20 20 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 45 78 70 65 63 74 65 64 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 41 74 20 6F +66 66 73 65 74 20 5B 25 64 5D 2C 20 6D 6C 6B 65 +6D 5F 64 6B 20 64 61 74 61 20 6D 69 73 6D 61 74 +63 68 21 0A 00 00 00 00 41 63 74 75 61 6C 20 20 +20 64 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +45 78 70 65 63 74 65 64 20 64 61 74 61 3A 20 30 +78 25 78 0A 00 00 00 00 41 74 20 6F 66 66 73 65 +74 20 5B 25 64 5D 2C 20 6D 6C 6B 65 6D 5F 6D 73 +67 20 64 61 74 61 20 6D 69 73 6D 61 74 63 68 21 +0A 00 00 00 41 63 74 75 61 6C 20 20 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 45 78 70 65 +63 74 65 64 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 41 74 20 6F 66 66 73 65 74 20 5B 25 +64 5D 2C 20 6D 6C 6B 65 6D 5F 63 69 70 68 65 72 +74 65 78 74 20 64 61 74 61 20 6D 69 73 6D 61 74 +63 68 21 0A 00 00 00 00 41 63 74 75 61 6C 20 20 +20 64 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +45 78 70 65 63 74 65 64 20 64 61 74 61 3A 20 30 +78 25 78 0A 00 00 00 00 41 74 20 6F 66 66 73 65 +74 20 5B 25 64 5D 2C 20 6D 6C 6B 65 6D 5F 73 68 +61 72 65 64 5F 6B 65 79 20 64 61 74 61 20 6D 69 +73 6D 61 74 63 68 21 0A 00 00 00 00 41 63 74 75 +61 6C 20 20 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 45 78 70 65 63 74 65 64 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 41 74 20 6F +66 66 73 65 74 20 5B 25 64 5D 2C 20 6D 6C 6B 65 +6D 5F 73 68 61 72 65 64 5F 6B 65 79 20 64 61 74 +61 20 6D 69 73 6D 61 74 63 68 21 0A 00 00 00 00 +41 63 74 75 61 6C 20 20 20 64 61 74 61 3A 20 30 +78 25 78 0A 00 00 00 00 45 78 70 65 63 74 65 64 +20 64 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +41 74 20 6F 66 66 73 65 74 20 5B 25 64 5D 2C 20 +6D 6C 6B 65 6D 5F 6D 73 67 20 64 61 74 61 20 6D +69 73 6D 61 74 63 68 21 0A 00 00 00 41 63 74 75 +61 6C 20 20 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 45 78 70 65 63 74 65 64 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 41 74 20 6F +66 66 73 65 74 20 5B 25 64 5D 2C 20 6D 6C 6B 65 +6D 5F 73 68 61 72 65 64 5F 6B 65 79 20 64 61 74 +61 20 6D 69 73 6D 61 74 63 68 21 0A 00 00 00 00 +41 63 74 75 61 6C 20 20 20 64 61 74 61 3A 20 30 +78 25 78 0A 00 00 00 00 45 78 70 65 63 74 65 64 +20 64 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +41 74 20 6F 66 66 73 65 74 20 5B 25 64 5D 2C 20 +6D 6C 6B 65 6D 5F 73 68 61 72 65 64 5F 6B 65 79 +20 64 61 74 61 20 6D 69 73 6D 61 74 63 68 21 0A +00 00 00 00 41 63 74 75 61 6C 20 20 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 45 78 70 65 +63 74 65 64 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 41 74 20 6F 66 66 73 65 74 20 5B 25 +64 5D 2C 20 6D 6C 6B 65 6D 5F 73 68 61 72 65 64 +5F 6B 65 79 20 64 61 74 61 20 6D 69 73 6D 61 74 +63 68 21 0A 00 00 00 00 41 63 74 75 61 6C 20 20 +20 64 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +45 78 70 65 63 74 65 64 20 64 61 74 61 3A 20 30 +78 25 78 0A 00 00 00 00 41 74 20 6F 66 66 73 65 +74 20 5B 25 64 5D 2C 20 6D 6C 6B 65 6D 5F 73 68 +61 72 65 64 5F 6B 65 79 20 64 61 74 61 20 6D 69 +73 6D 61 74 63 68 21 0A 00 00 00 00 41 63 74 75 +61 6C 20 20 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 45 78 70 65 63 74 65 64 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 41 74 20 6F +66 66 73 65 74 20 5B 25 64 5D 2C 20 6D 6C 6B 65 +6D 5F 73 68 61 72 65 64 5F 6B 65 79 20 64 61 74 +61 20 6D 69 73 6D 61 74 63 68 21 0A 00 00 00 00 +41 63 74 75 61 6C 20 20 20 64 61 74 61 3A 20 30 +78 25 78 0A 00 00 00 00 45 78 70 65 63 74 65 64 +20 64 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +41 74 20 6F 66 66 73 65 74 20 5B 25 64 5D 2C 20 +6D 6C 6B 65 6D 5F 73 68 61 72 65 64 5F 6B 65 79 +20 64 61 74 61 20 6D 69 73 6D 61 74 63 68 21 0A +00 00 00 00 41 63 74 75 61 6C 20 20 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 45 78 70 65 +63 74 65 64 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 41 11 22 C4 37 04 02 50 03 27 C4 07 +06 C6 89 47 63 E0 E7 04 37 37 02 50 13 07 47 39 +1C 4B 54 4B D5 8F 9D E3 73 00 50 10 93 07 40 06 +01 00 FD 17 C2 07 C1 83 E5 FF 1C 4B 54 4B D5 8F +E5 D7 83 26 C4 07 89 47 63 E5 D7 02 B2 40 22 44 +41 01 82 80 37 25 02 50 13 05 C5 2C EF 70 AF BD +37 37 02 50 13 07 47 39 1C 4B 54 4B D5 8F CD DF +C9 BF 22 44 4C 4B B2 40 10 4B 35 65 13 05 45 6F +41 01 6F 70 4F BD B7 07 02 50 03 A7 C7 07 89 47 +63 E7 E7 00 B7 07 01 10 11 47 98 CB 82 80 37 25 +02 50 41 11 13 05 85 2E 06 C6 EF 70 CF B8 B2 40 +B7 07 01 10 11 47 98 CB 41 01 82 80 19 CA 0A 06 +33 87 C5 00 9C 41 91 05 11 05 23 2E F5 FE E3 9B +E5 FE 82 80 39 71 5A D0 62 CC 66 CA 6A C8 6E C6 +06 DE 22 DC 26 DA 4A D8 4E D6 52 D4 56 D2 5E CE +03 49 15 00 83 4B 25 00 03 CA 15 00 83 C9 25 00 +83 CA 06 00 AA 8D 2E 8C B6 8C 32 8D 3A 8B B7 07 +01 10 80 4F 05 88 75 DC 03 C7 0D 00 B7 04 02 50 +03 A5 C4 07 45 C3 13 97 1B 00 13 77 E7 03 13 67 +17 00 23 A0 E7 60 89 47 63 ED A7 30 B7 07 01 10 +23 A0 07 04 23 A2 07 04 23 A4 07 04 23 A6 07 04 +23 A8 07 04 23 AA 07 04 23 AC 07 04 23 AE 07 04 +23 A0 07 06 23 A2 07 06 23 A4 07 06 23 A6 07 06 +37 07 01 10 83 27 47 60 89 8B ED DF 85 47 63 1C +F9 08 83 27 47 60 93 F7 C7 3F 63 80 07 32 89 47 +63 ED A7 3A 83 47 0C 00 63 96 07 36 37 06 01 10 +B7 05 FF EF 93 07 06 08 93 85 05 F8 13 06 06 10 +BE 86 91 07 33 87 B7 00 62 97 18 43 98 C2 E3 99 +C7 FE 75 A0 89 47 63 EF A7 28 03 A7 4D 00 B7 07 +01 10 B8 C3 03 A7 8D 00 F8 C3 03 A7 CD 00 B8 C7 +03 A7 0D 01 F8 C7 03 A7 4D 01 B8 CB 03 A7 8D 01 +F8 CB 03 A7 CD 01 B8 CF 03 A7 0D 02 F8 CF 03 A7 +4D 02 B8 D3 03 A7 8D 02 F8 D3 03 A7 CD 02 B8 D7 +03 A7 0D 03 F8 D7 83 47 0C 00 C9 D3 93 97 19 00 +93 F7 E7 03 93 E7 17 00 37 07 01 10 23 24 F7 60 +89 47 63 FA A7 00 37 25 02 50 13 05 C5 3D EF 70 +8F 9F 03 A5 C4 07 B7 06 01 10 93 87 06 08 93 86 +06 10 23 A0 07 00 91 07 E3 9D D7 FE 37 07 01 10 +83 27 C7 60 89 8B ED DF 85 47 63 0F FA 20 03 27 +4D 00 B7 07 01 10 23 A0 E7 14 03 27 8D 00 23 A2 +E7 14 03 27 CD 00 23 A4 E7 14 03 27 0D 01 23 A6 +E7 14 03 27 4D 01 23 A8 E7 14 03 27 8D 01 23 AA +E7 14 03 27 CD 01 23 AC E7 14 03 27 0D 02 23 AE +E7 14 03 27 4D 02 23 A0 E7 16 03 27 8D 02 23 A2 +E7 16 03 27 CD 02 23 A4 E7 16 03 27 0D 03 23 A6 +E7 16 63 8D 0A 00 03 C7 2C 00 85 66 93 86 16 FC +06 07 13 77 F7 0F 55 8F 23 A8 E7 60 B7 07 01 10 +63 0E 0B 12 05 47 98 CB A2 87 63 93 0B 00 8D 47 +37 07 01 10 23 20 F7 60 63 93 09 00 0D 44 B7 07 +01 10 23 A4 87 60 89 47 63 ED A7 10 37 37 02 50 +13 07 47 39 1C 4B 54 4B D5 8F 95 EB 73 00 50 10 +93 07 40 06 01 00 FD 17 C2 07 C1 83 E5 FF 1C 4B +54 4B D5 8F E5 D7 83 A6 C4 07 89 47 63 F9 D7 00 +4C 4B 10 4B 35 65 13 05 45 6F EF 70 CF 8F 33 69 +49 01 63 16 09 0A 83 A7 C4 07 09 47 63 95 0A 10 +63 68 F7 16 B7 07 01 10 03 A7 07 10 83 A7 4C 00 +63 1C F7 14 B7 07 01 10 03 A9 47 10 03 A4 8C 00 +63 1E 24 13 03 A9 87 10 03 A4 CC 00 63 1C 24 1F +03 A9 C7 10 03 A4 0C 01 63 14 24 1F 03 A9 07 11 +03 A4 4C 01 63 1C 89 1C 03 A9 47 11 03 A4 8C 01 +63 14 89 1C 03 A9 87 11 03 A4 CC 01 63 1C 89 1A +03 A9 C7 11 03 A4 0C 02 63 14 89 1A 03 A9 07 12 +03 A4 4C 02 63 1C 89 18 03 A9 47 12 03 A4 8C 02 +63 14 89 18 03 A9 87 12 03 A4 CC 02 63 12 89 10 +03 A9 C7 12 03 A4 0C 03 AD 45 63 12 89 0C F2 50 +62 54 D2 54 42 59 B2 59 22 5A 92 5A 02 5B F2 4B +62 4C D2 4C 42 4D B2 4D 21 61 82 80 09 47 98 CB +E1 B5 37 25 02 50 13 05 C5 2C EF 60 DF FF 37 37 +02 50 13 07 47 39 1C 4B 54 4B D5 8F E3 80 07 EE +DD BD 37 25 02 50 13 05 C5 2F EF 60 DF FD 03 A5 +C4 07 E9 B9 37 25 02 50 13 05 45 3C EF 60 BF FC +03 A5 C4 07 99 BB 63 64 F7 04 37 07 01 10 83 27 +47 61 89 8B ED DF 61 B7 83 27 C7 60 93 F7 C7 3F +95 C3 89 47 E3 FD A7 DC 37 25 02 50 13 05 05 40 +EF 60 7F F9 03 A5 C4 07 D9 B3 61 E1 05 45 EF 60 +9F F6 01 A0 45 E5 05 45 EF 60 FF F5 01 A0 37 25 +02 50 13 05 45 4A EF 60 1F F7 45 BF 85 45 83 A7 +C4 07 09 4A 63 61 FA 04 05 45 EF 60 DF F3 01 A0 +37 25 02 50 13 05 45 4C EF 60 FF F4 B7 07 01 10 +03 A9 07 10 03 A4 4C 00 E3 06 24 E9 81 45 C1 BF +A9 45 F1 B7 93 97 19 00 93 F7 E7 03 93 E7 17 00 +23 24 F7 60 0D BB B5 69 93 89 49 6F 13 85 49 03 +EF 60 7F F3 83 A7 C4 07 E3 78 FA FA CA 85 13 85 +09 06 EF 60 5F F2 83 A7 C4 07 E3 7F FA F8 A2 85 +13 85 89 07 EF 60 3F F1 41 BF 37 25 02 50 13 05 +45 32 EF 60 5F EE 03 A5 C4 07 75 B9 37 25 02 50 +13 05 05 45 EF 60 3F ED B9 B7 37 25 02 50 13 05 +05 37 EF 60 5F EC 1D BF A5 45 91 BF A1 45 81 BF +9D 45 B1 B7 99 45 A1 B7 95 45 91 B7 91 45 81 B7 +8D 45 35 BF 89 45 25 BF 39 71 5A D0 62 CC 66 CA +6A C8 6E C6 06 DE 22 DC 26 DA 4A D8 4E D6 52 D4 +56 D2 5E CE 03 49 15 00 83 4B 25 00 03 CA 15 00 +83 C9 25 00 83 CA 06 00 AA 8D AE 8C 36 8C 32 8D +3A 8B B7 07 01 10 80 4F 05 88 75 DC 03 C7 0D 00 +B7 04 02 50 03 A5 C4 07 45 CB 13 97 1B 00 13 77 +E7 03 13 67 17 00 23 A0 E7 60 89 47 63 E7 A7 38 +B7 07 01 10 23 A0 07 04 23 A2 07 04 23 A4 07 04 +23 A6 07 04 23 A8 07 04 23 AA 07 04 23 AC 07 04 +23 AE 07 04 23 A0 07 06 23 A2 07 06 23 A4 07 06 +23 A6 07 06 23 A8 07 06 23 AA 07 06 23 AC 07 06 +23 AE 07 06 37 07 01 10 83 27 47 60 89 8B ED DF +85 47 63 18 F9 0A 83 27 47 60 93 F7 C7 3F 63 89 +07 36 89 47 63 EF A7 3E 83 C7 0C 00 63 9A 07 38 +37 06 01 10 B7 05 FF EF 93 07 06 08 93 85 05 F8 +13 06 06 10 BE 86 91 07 33 87 B7 00 66 97 18 43 +98 C2 E3 99 C7 FE D1 A0 89 47 63 E1 A7 30 03 A7 +4D 00 B7 07 01 10 B8 C3 03 A7 8D 00 F8 C3 03 A7 +CD 00 B8 C7 03 A7 0D 01 F8 C7 03 A7 4D 01 B8 CB +03 A7 8D 01 F8 CB 03 A7 CD 01 B8 CF 03 A7 0D 02 +F8 CF 03 A7 4D 02 B8 D3 03 A7 8D 02 F8 D3 03 A7 +CD 02 B8 D7 03 A7 0D 03 F8 D7 03 A7 4D 03 B8 DB +03 A7 8D 03 F8 DB 03 A7 CD 03 B8 DF 03 A7 0D 04 +F8 DF 83 C7 0C 00 AD D7 93 97 19 00 93 F7 E7 03 +93 E7 17 00 37 07 01 10 23 24 F7 60 89 47 63 FA +A7 00 37 25 02 50 13 05 C5 3D EF 60 DF D0 03 A5 +C4 07 B7 06 01 10 93 87 06 08 93 86 06 10 23 A0 +07 00 91 07 E3 9D D7 FE 37 07 01 10 83 27 C7 60 +89 8B ED DF 85 47 63 0C FA 24 03 27 4D 00 B7 07 +01 10 23 A0 E7 14 03 27 8D 00 23 A2 E7 14 03 27 +CD 00 23 A4 E7 14 03 27 0D 01 23 A6 E7 14 03 27 +4D 01 23 A8 E7 14 03 27 8D 01 23 AA E7 14 03 27 +CD 01 23 AC E7 14 03 27 0D 02 23 AE E7 14 03 27 +4D 02 23 A0 E7 16 03 27 8D 02 23 A2 E7 16 03 27 +CD 02 23 A4 E7 16 03 27 0D 03 23 A6 E7 16 63 8D +0A 00 03 47 2C 00 A1 66 93 86 16 FC 06 07 13 77 +F7 0F 55 8F 23 A8 E7 60 B7 07 01 10 63 04 0B 18 +25 47 98 CB A2 87 63 93 0B 00 8D 47 37 07 01 10 +23 20 F7 60 63 93 09 00 0D 44 B7 07 01 10 23 A4 +87 60 89 47 63 E3 A7 16 37 37 02 50 13 07 47 39 +1C 4B 54 4B D5 8F 95 EB 73 00 50 10 93 07 40 06 +01 00 FD 17 C2 07 C1 83 E5 FF 1C 4B 54 4B D5 8F +E5 D7 83 A6 C4 07 89 47 63 F9 D7 00 4C 4B 10 4B +35 65 13 05 45 6F EF 60 1F C1 33 69 49 01 63 1C +09 0E 83 A7 C4 07 09 47 63 9F 0A 0C 63 6B F7 18 +B7 07 01 10 03 A9 07 10 03 24 4C 00 63 19 24 1F +03 A9 47 10 03 24 8C 00 63 11 24 1F 03 A9 87 10 +03 24 CC 00 63 14 24 23 03 A9 C7 10 03 24 0C 01 +63 1C 24 21 03 A9 07 11 03 24 4C 01 63 14 89 20 +03 A9 47 11 03 24 8C 01 63 1C 89 1E 03 A9 87 11 +03 24 CC 01 63 14 89 1E 03 A9 C7 11 03 24 0C 02 +63 1C 89 1C 03 A9 07 12 03 24 4C 02 63 14 89 1C +03 A9 47 12 03 24 8C 02 63 1C 89 1A 03 A9 87 12 +03 24 CC 02 63 1D 89 12 03 A9 C7 12 03 24 0C 03 +63 15 89 12 03 A9 07 13 03 24 4C 03 63 1D 89 10 +03 A9 47 13 03 24 8C 03 63 15 89 10 03 A9 87 13 +03 24 CC 03 63 11 89 14 03 A9 C7 13 03 24 0C 04 +BD 45 63 02 89 02 83 A7 C4 07 63 9C 07 0E 05 45 +EF 60 7F AE 01 A0 63 67 F7 0A 37 07 01 10 83 27 +47 61 89 8B ED DF F2 50 62 54 D2 54 42 59 B2 59 +22 5A 92 5A 02 5B F2 4B 62 4C D2 4C 42 4D B2 4D +21 61 82 80 29 47 98 CB B5 BD 37 25 02 50 13 05 +C5 2C EF 60 5F AC 37 37 02 50 13 07 47 39 1C 4B +54 4B D5 8F E3 8A 07 E8 6D B5 37 25 02 50 13 05 +C5 4D EF 60 5F AA 03 A5 C4 07 9D B1 37 25 02 50 +13 05 45 3C EF 60 3F A9 03 A5 C4 07 CD B9 83 27 +C7 60 93 F7 C7 3F 95 C3 89 47 E3 F0 A7 DA 37 25 +02 50 13 05 05 40 EF 60 1F A7 03 A5 C4 07 71 B3 +4D E9 05 45 EF 60 3F A4 01 A0 49 ED 05 45 EF 60 +9F A3 01 A0 37 25 02 50 13 05 45 4A EF 60 BF A4 +A9 B7 37 25 02 50 13 05 45 4C EF 60 DF A3 8D B5 +93 97 19 00 93 F7 E7 03 93 E7 17 00 23 24 F7 60 +0D B3 B5 45 09 BF B1 45 39 B7 AD 45 29 B7 A9 45 +19 B7 B5 69 93 89 49 6F 13 85 09 09 EF 60 BF A2 +83 A7 C4 07 E3 8D 07 EE CA 85 13 85 C9 0B EF 60 +9F A1 83 A7 C4 07 E3 84 07 EE A2 85 13 85 49 0D +EF 60 7F A0 E9 BD B9 45 F9 B5 85 45 E9 B5 81 45 +D9 B5 37 25 02 50 13 05 45 32 EF 60 DF 9C 03 A5 +C4 07 41 B9 37 25 02 50 13 05 05 45 EF 60 BF 9B +B1 BF 37 25 02 50 13 05 05 37 EF 60 DF 9A 91 B7 +A5 45 51 BD A1 45 41 BD 9D 45 71 B5 99 45 61 B5 +95 45 51 B5 91 45 41 B5 8D 45 B5 BD 89 45 A5 BD +79 71 4A D0 56 CA 5E C6 62 C4 66 C2 6A C0 06 D6 +22 D4 26 D2 4E CE 52 CC 5A C8 03 4B 25 00 03 CA +25 00 83 C9 06 00 3E 8C 2A 8D AE 8B 36 89 B2 8C +BA 8A B7 07 01 10 80 4F 05 88 75 DC 03 47 0D 00 +B7 04 02 50 03 A5 C4 07 55 CB 13 17 1B 00 13 77 +E7 03 13 67 17 00 23 A0 E7 60 89 47 63 E3 A7 34 +B7 07 01 10 23 A0 07 04 23 A2 07 04 23 A4 07 04 +23 A6 07 04 23 A8 07 04 23 AA 07 04 23 AC 07 04 +23 AE 07 04 23 A0 07 06 23 A2 07 06 23 A4 07 06 +23 A6 07 06 23 A8 07 06 23 AA 07 06 23 AC 07 06 +23 AE 07 06 37 07 01 10 83 27 47 60 89 8B ED DF +83 46 1D 00 85 47 63 98 F6 0A 83 27 47 60 93 F7 +C7 3F 63 83 07 32 89 47 63 EA A7 32 83 C7 0B 00 +63 9D 07 34 37 06 01 10 B7 05 FF EF 93 07 06 08 +93 85 05 F8 13 06 06 10 BE 86 91 07 33 87 B7 00 +5E 97 18 43 98 C2 E3 99 C7 FE E1 A0 89 47 63 EB +A7 2A 03 27 4D 00 B7 07 01 10 B8 C3 03 27 8D 00 +F8 C3 03 27 CD 00 B8 C7 03 27 0D 01 F8 C7 03 27 +4D 01 B8 CB 03 27 8D 01 F8 CB 03 27 CD 01 B8 CF +03 27 0D 02 F8 CF 03 27 4D 02 B8 D3 03 27 8D 02 +F8 D3 03 27 CD 02 B8 D7 03 27 0D 03 F8 D7 03 27 +4D 03 B8 DB 03 27 8D 03 F8 DB 03 27 CD 03 B8 DF +03 27 0D 04 F8 DF 83 C7 0B 00 AD D7 93 17 1A 00 +93 F7 E7 03 93 E7 17 00 37 07 01 10 23 24 F7 60 +89 47 63 FA A7 00 37 25 02 50 13 05 C5 3D EF 60 +8F FF 03 A5 C4 07 B7 06 01 10 93 87 06 08 93 86 +06 10 23 A0 07 00 91 07 E3 9D D7 FE 37 07 01 10 +83 27 C7 60 89 8B ED DF 83 C6 1B 00 85 47 63 84 +F6 20 03 A7 4C 00 B7 07 01 10 23 A0 E7 14 03 A7 +8C 00 23 A2 E7 14 03 A7 CC 00 23 A4 E7 14 03 A7 +0C 01 23 A6 E7 14 03 A7 4C 01 23 A8 E7 14 03 A7 +8C 01 23 AA E7 14 03 A7 CC 01 23 AC E7 14 03 A7 +0C 02 23 AE E7 14 03 A7 4C 02 23 A0 E7 16 03 A7 +8C 02 23 A2 E7 16 03 A7 CC 02 23 A4 E7 16 03 A7 +0C 03 23 A6 E7 16 63 8D 09 00 03 47 29 00 91 66 +93 86 16 FC 06 07 13 77 F7 0F 55 8F 23 A8 E7 60 +B7 07 01 10 63 8C 0A 12 25 47 98 CB A2 87 63 13 +0B 00 8D 47 37 07 01 10 23 20 F7 60 63 13 0A 00 +0D 44 B7 07 01 10 23 A4 87 60 89 47 63 EB A7 10 +37 37 02 50 13 07 47 39 1C 4B 54 4B D5 8F 91 EF +73 00 50 10 93 07 40 06 01 00 FD 17 C2 07 C1 83 +E5 FF 1C 4B 54 4B D5 8F E5 D7 83 A7 C4 07 09 44 +63 6B F4 00 63 8C 09 02 37 07 01 10 83 27 47 61 +89 8B ED DF 75 A0 4C 4B 10 4B 35 65 13 05 45 6F +EF 60 6F EE 83 A7 C4 07 63 94 09 0C 63 78 F4 00 +37 25 02 50 13 05 45 4C EF 60 EF EA B7 07 01 10 +03 A7 07 10 23 20 EC 00 03 A7 47 10 23 22 EC 00 +03 A7 87 10 23 24 EC 00 03 A7 C7 10 23 26 EC 00 +03 A7 07 11 23 28 EC 00 03 A7 47 11 23 2A EC 00 +03 A7 87 11 23 2C EC 00 03 A7 C7 11 23 2E EC 00 +03 A7 07 12 23 20 EC 02 03 A7 47 12 23 22 EC 02 +03 A7 87 12 23 24 EC 02 03 A7 C7 12 23 26 EC 02 +03 A7 07 13 23 28 EC 02 03 A7 47 13 23 2A EC 02 +03 A7 87 13 23 2C EC 02 83 A7 C7 13 23 2E FC 02 +B2 50 22 54 92 54 02 59 F2 49 62 4A D2 4A 42 4B +B2 4B 22 4C 92 4C 02 4D 45 61 82 80 29 47 98 CB +F1 B5 37 25 02 50 13 05 C5 2C EF 60 CF DF CD B5 +E3 7C F4 F0 37 25 02 50 13 05 45 4A EF 60 AF DE +21 B7 37 25 02 50 13 05 C5 4D EF 60 CF DD 03 A5 +C4 07 7D B1 37 25 02 50 13 05 45 3C EF 60 AF DC +03 A5 C4 07 3D BB 83 27 C7 60 93 F7 C7 3F 95 C3 +89 47 E3 F8 A7 DE 37 25 02 50 13 05 05 40 EF 60 +8F DA 03 A5 C4 07 F1 BB 15 E9 05 45 EF 60 AF D7 +01 A0 11 ED 05 45 EF 60 0F D7 01 A0 37 25 02 50 +13 05 45 32 EF 60 2F D8 03 A5 C4 07 A9 BB 37 25 +02 50 13 05 05 45 EF 60 0F D7 E9 BF 37 25 02 50 +13 05 05 37 EF 60 2F D6 C9 B7 93 17 1A 00 93 F7 +E7 03 93 E7 17 00 23 24 F7 60 B1 BB 01 11 26 CA +4A C8 4E C6 56 C2 5A C0 06 CE 22 CC 52 C4 2A 89 +AE 84 B2 8A B6 89 3A 8B B7 07 01 10 80 4F 05 88 +75 DC 37 0A 02 50 03 28 CA 07 89 47 63 EC 07 27 +83 27 49 00 37 07 01 10 37 05 01 10 3C C3 83 26 +89 00 37 06 FF EF 93 07 07 08 74 C3 83 26 C9 00 +13 06 06 F8 93 05 05 10 34 C7 83 26 09 01 74 C7 +83 26 49 01 34 CB 83 26 89 01 74 CB 83 26 C9 01 +34 CF 83 26 09 02 74 CF 83 26 49 02 34 D3 83 26 +89 02 74 D3 83 26 C9 02 34 D7 83 26 09 03 74 D7 +83 26 49 03 34 DB 83 26 89 03 74 DB 83 26 C9 03 +34 DF 83 26 09 04 74 DF BE 86 91 07 33 87 C7 00 +26 97 18 43 98 C2 E3 99 B7 FE 83 A7 4A 00 23 20 +F5 14 83 A7 8A 00 23 22 F5 14 83 A7 CA 00 23 24 +F5 14 83 A7 0A 01 23 26 F5 14 83 A7 4A 01 23 28 +F5 14 83 A7 8A 01 23 2A F5 14 83 A7 CA 01 23 2C +F5 14 83 A7 0A 02 23 2E F5 14 83 A7 4A 02 23 20 +F5 16 83 A7 8A 02 23 22 F5 16 83 A7 CA 02 23 24 +F5 16 83 A7 0A 03 23 26 F5 16 63 0F 0B 12 E5 47 +1C C9 03 47 29 00 A2 87 11 E3 8D 47 37 07 01 10 +23 20 F7 60 83 C7 24 00 91 E3 0D 44 B7 07 01 10 +23 A4 87 60 89 47 63 E8 07 15 37 37 02 50 13 07 +47 39 14 4B 5C 4B D5 8F 91 EF 73 00 50 10 93 07 +40 06 01 00 FD 17 C2 07 C1 83 E5 FF 1C 4B 54 4B +D5 8F E5 D7 83 27 CA 07 09 44 63 6C F4 0E B7 07 +01 10 83 A4 07 10 03 A4 49 00 63 1A 94 0C 83 A4 +47 10 03 A4 89 00 63 1A 94 14 83 A4 87 10 03 A4 +C9 00 63 1A 94 14 83 A4 C7 10 03 A4 09 01 63 92 +84 14 83 A4 07 11 03 A4 49 01 63 9A 84 12 83 A4 +47 11 03 A4 89 01 63 9A 84 14 83 A4 87 11 03 A4 +C9 01 63 92 84 14 83 A4 C7 11 03 A4 09 02 63 9A +84 12 83 A4 07 12 03 A4 49 02 63 92 84 12 83 A4 +47 12 03 A4 89 02 63 96 84 10 83 A4 87 12 03 A4 +C9 02 63 9C 84 0E 83 A4 C7 12 03 A4 09 03 63 9C +84 0E 83 A4 07 13 03 A4 49 03 63 92 84 10 83 A4 +47 13 03 A4 89 03 63 9C 84 0C 83 A4 87 13 03 A4 +C9 03 63 9C 84 0C 83 A4 C7 13 03 A4 09 04 BD 45 +63 90 84 02 F2 40 62 44 D2 44 42 49 B2 49 22 4A +92 4A 02 4B 05 61 82 80 E9 47 1C C9 D9 B5 81 45 +83 27 CA 07 89 49 63 E8 F9 04 05 45 EF 60 AF AB +01 A0 4C 4B 10 4B 35 65 13 05 45 6F EF 60 AF AE +83 27 CA 07 E3 7D F4 EE 37 25 02 50 13 05 45 4C +EF 60 6F AB ED B5 37 25 02 50 13 05 C5 2C EF 60 +8F AA 65 B5 37 25 02 50 13 05 45 3C EF 60 AF A9 +03 28 CA 07 B5 BB 35 69 13 09 49 6F 13 05 C9 0E +EF 60 6F AA 83 27 CA 07 E3 F1 F9 FA A6 85 13 05 +89 11 EF 60 4F A9 83 27 CA 07 E3 F8 F9 F8 A2 85 +13 05 09 13 EF 60 2F A8 49 B7 85 45 95 BF 91 45 +85 BF 8D 45 B5 B7 89 45 A5 B7 A9 45 95 B7 B5 45 +85 B7 A5 45 B1 BF AD 45 A1 BF B9 45 91 BF A1 45 +81 BF 9D 45 B1 B7 99 45 A1 B7 95 45 91 B7 B1 45 +81 B7 01 00 52 65 63 65 69 76 65 64 20 48 4D 41 +43 20 6E 6F 74 69 66 2F 65 72 72 20 69 6E 74 72 +20 77 69 74 68 20 73 74 61 74 75 73 20 3D 20 25 +64 2F 20 25 64 0A 00 00 41 74 20 6F 66 66 73 65 +74 20 5B 25 64 5D 2C 20 68 6D 61 63 5F 74 61 67 +20 64 61 74 61 20 6D 69 73 6D 61 74 63 68 21 0A +00 00 00 00 41 63 74 75 61 6C 20 20 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 45 78 70 65 +63 74 65 64 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 41 74 20 6F 66 66 73 65 74 20 5B 25 +64 5D 2C 20 68 6D 61 63 5F 74 61 67 20 64 61 74 +61 20 6D 69 73 6D 61 74 63 68 21 0A 00 00 00 00 +41 63 74 75 61 6C 20 20 20 64 61 74 61 3A 20 30 +78 25 78 0A 00 00 00 00 45 78 70 65 63 74 65 64 +20 64 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +41 74 20 6F 66 66 73 65 74 20 5B 25 64 5D 2C 20 +68 6D 61 63 5F 74 61 67 20 64 61 74 61 20 6D 69 +73 6D 61 74 63 68 21 0A 00 00 00 00 41 63 74 75 +61 6C 20 20 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 45 78 70 65 63 74 65 64 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 B7 07 02 50 +03 A7 C7 07 41 11 22 C4 06 C6 8D 47 2A 84 63 EC +E7 00 B7 67 00 04 3E 94 0A 04 91 47 B2 40 1C C0 +22 44 41 01 82 80 AA 85 39 65 13 05 45 A3 EF 60 +8F 8C C5 B7 B7 07 02 50 03 A7 C7 07 41 11 22 C4 +06 C6 8D 47 2A 84 63 EA E7 00 1C 40 93 F7 C7 3F +99 EF B2 40 22 44 41 01 82 80 37 25 02 50 13 05 +45 50 EF 60 4F 87 1C 40 93 F7 C7 3F FD D3 37 25 +02 50 13 05 C5 51 EF 60 0F 86 22 44 B2 40 05 45 +41 01 6F 60 4F 83 B7 07 02 50 03 A7 C7 07 41 11 +22 C4 06 C6 8D 47 2A 84 63 EA E7 00 1C 40 93 F7 +C7 3F 99 CF B2 40 22 44 41 01 82 80 37 25 02 50 +13 05 85 52 EF 60 2F 82 1C 40 93 F7 C7 3F FD F3 +37 25 02 50 13 05 45 54 EF 60 EF 80 22 44 B2 40 +05 45 41 01 6F 50 3F FE B7 07 02 50 03 A7 C7 07 +41 11 22 C4 26 C2 06 C6 8D 47 AA 84 2E 84 63 ED +E7 00 06 04 13 74 E4 03 13 64 14 00 80 C0 B2 40 +22 44 92 44 41 01 82 80 37 25 02 50 13 05 05 55 +EF 50 7F FC F9 BF B7 07 02 50 03 A7 C7 07 41 11 +22 C4 26 C2 4A C0 06 C6 8D 47 2A 89 AE 84 32 84 +63 EB E7 06 93 77 14 00 13 17 64 00 13 77 07 08 +93 95 14 00 9A 07 D9 8F 93 F5 E5 03 13 17 64 00 +13 77 07 10 93 16 64 00 CD 8F D9 8F 93 F6 06 20 +13 17 64 00 13 56 54 00 D5 8F 13 77 07 40 93 56 +64 00 05 8A D9 8F 2E 06 13 57 74 00 85 8A D1 8F +B2 06 05 8B 21 80 D5 8F 36 07 05 88 3A 04 D9 8F +B2 40 C1 8F 22 44 93 E7 17 00 23 20 F9 00 92 44 +02 49 41 01 82 80 37 25 02 50 13 05 85 56 EF 50 +9F F2 49 B7 B7 07 02 50 03 A7 C7 07 41 11 22 C4 +06 C6 8D 47 2A 84 63 EF E7 00 06 04 13 74 E4 03 +13 64 14 04 B7 07 02 10 B2 40 23 A0 87 60 22 44 +41 01 82 80 37 25 02 50 13 05 05 58 EF 50 BF EE +E9 BF 01 00 4B 56 3A 20 63 6C 65 61 72 69 6E 67 +20 4B 56 20 65 6E 74 72 79 20 30 78 25 78 0A 00 +00 00 00 00 08 41 B7 25 02 50 41 11 93 85 85 7E +06 C6 EF 30 B0 53 B2 40 33 35 A0 00 41 01 82 80 +B7 05 02 50 93 85 85 2E 93 87 45 00 13 86 C5 20 +01 47 94 43 63 65 D5 00 D4 4B 63 69 D5 00 D1 07 +05 07 E3 98 C7 FE 13 85 85 20 82 80 93 17 27 00 +BA 97 8A 07 33 85 F5 00 82 80 01 11 22 CC 37 04 +02 50 26 CA 4A C8 4E C6 52 C4 06 CE 13 0A 84 2E +2A 89 13 04 84 2E 81 44 ED 49 21 A0 85 04 63 8D +34 01 08 40 CA 85 51 04 EF 30 50 4C 65 D9 13 95 +24 00 26 95 0A 05 52 95 F2 40 62 44 D2 44 42 49 +B2 49 22 4A 05 61 82 80 5C 45 63 C0 07 04 1C 49 +63 CF 07 02 5C 49 63 CE 07 02 1C 4D 63 CD 07 02 +5C 4D 63 CC 07 02 1C 51 63 CB 07 02 5C 51 63 CA +07 02 1C 55 63 C9 07 02 5C 55 63 C8 07 02 08 59 +13 45 F5 FF 7D 81 25 05 82 80 01 45 82 80 05 45 +82 80 09 45 82 80 0D 45 82 80 11 45 82 80 15 45 +82 80 19 45 82 80 1D 45 82 80 21 45 82 80 B7 37 +02 50 0A 05 93 87 47 3E AA 97 94 43 05 47 33 17 +B7 00 55 8F 98 C3 82 80 01 11 4E C6 B7 09 02 50 +83 A7 C9 07 06 CE 22 CC 26 CA 4A C8 52 C4 56 C2 +5A C0 09 47 63 6E F7 06 37 09 02 50 B7 34 02 50 +13 09 89 2E 93 84 44 3E 01 44 09 4B B9 6A 6D 4A +63 62 FB 02 69 47 63 05 E4 00 09 47 63 6B F7 02 +F2 40 62 44 D2 44 42 49 B2 49 22 4A 92 4A 02 4B +05 61 82 80 90 40 83 25 09 00 13 85 CA C7 05 04 +EF 50 7F D5 83 A7 C9 07 E3 09 44 FD 51 09 91 04 +C1 B7 62 44 F2 40 D2 44 42 49 B2 49 22 4A 92 4A +02 4B 37 25 02 50 13 05 05 5B 05 61 6F 50 BF D0 +37 25 02 50 13 05 05 5B EF 50 FF CF 83 A7 C9 07 +A5 BF 41 11 06 C6 EF 30 70 37 B2 40 33 35 A0 00 +41 01 82 80 63 52 B0 04 01 11 22 CC 26 CA 4A C8 +4E C6 06 CE 2E 89 AA 89 2A 84 81 44 EF 30 40 77 +B3 67 25 03 18 40 11 04 85 04 8A 07 CE 97 94 43 +23 2E D4 FE 98 C3 E3 13 99 FE F2 40 62 44 D2 44 +42 49 B2 49 05 61 82 80 82 80 01 00 20 20 25 34 +30 73 3A 20 30 78 25 2D 33 78 0A 00 00 00 00 00 +01 11 4E C6 B7 09 02 50 03 A7 C9 07 22 CC 4A C8 +06 CE 26 CA 89 47 2A 89 2E 84 63 EB E7 06 B7 34 +02 50 93 84 44 39 9C 54 E1 8F 63 8F 87 00 73 00 +50 10 93 07 40 06 01 00 FD 17 C2 07 C1 83 E5 FF +9C 54 E1 8F E3 95 87 FE DC 54 B3 F7 27 01 E3 90 +27 FF 83 A7 C9 07 1D C0 B9 E3 D4 54 13 47 F9 FF +F2 40 75 8F D8 D4 98 54 93 47 F4 FF 62 44 F9 8F +9C D4 42 49 D2 44 B2 49 05 61 82 80 09 47 E3 7E +F7 FC CC 54 39 65 13 05 C5 1B EF 50 DF C1 F1 B7 +37 35 02 50 13 05 05 86 EF 50 FF BE 49 B7 8C 54 +39 65 13 05 05 19 EF 50 1F C0 45 BF B7 07 02 50 +03 A7 C7 07 89 47 63 E7 E7 00 B7 87 02 10 21 47 +98 CB 82 80 37 35 02 50 41 11 13 05 C5 87 06 C6 +EF 50 7F BB B2 40 B7 87 02 10 21 47 98 CB 41 01 +82 80 01 11 22 CC 26 CA 4A C8 52 C4 56 C2 3E 89 +06 CE 4E C6 2E 84 B2 84 36 8A BA 8A B7 87 02 10 +98 4F 05 8B 75 DF 54 41 B7 09 02 50 09 47 23 A0 +D7 08 14 45 23 A2 D7 08 54 45 23 A4 D7 08 14 49 +23 A6 D7 08 54 49 23 A8 D7 08 14 4D 23 AA D7 08 +54 4D 23 AC D7 08 14 51 23 AE D7 08 54 51 23 A0 +D7 0A 14 55 23 A2 D7 0A 54 55 23 A4 D7 0A 14 59 +23 A6 D7 0A 54 59 23 A8 D7 0A 14 5D 23 AA D7 0A +54 5D 23 AC D7 0A 34 41 23 AE D7 0A 03 A6 C9 07 +63 66 C7 0E 93 17 24 00 13 97 9A 00 13 77 07 20 +91 8B 93 16 5A 00 D9 8F 93 F6 06 1E 13 97 44 00 +41 8B D5 8F D9 8F 93 E7 17 00 37 87 02 10 1C CB +89 47 63 E4 C7 10 37 34 02 50 13 04 44 39 1C 54 +5C 54 85 8B 9D E3 73 00 50 10 93 07 40 06 01 00 +FD 17 C2 07 C1 83 E5 FF 1C 54 5C 54 85 8B E5 D7 +83 A7 C9 07 89 44 63 E4 F4 0A 5C 54 F9 9B 5C D4 +1C 54 1C D4 B7 87 02 10 83 A4 07 10 03 24 49 00 +63 9F 84 06 83 A4 47 10 03 24 89 00 63 93 84 10 +83 A4 87 10 03 24 C9 00 63 99 84 0E 83 A4 C7 10 +03 24 09 01 63 9D 84 0E 83 A4 07 11 03 24 49 01 +63 95 84 0E 83 A4 47 11 03 24 89 01 63 9D 84 0C +83 A4 87 11 03 24 C9 01 63 93 84 0C 83 A4 C7 11 +03 24 09 02 9D 45 63 95 84 02 F2 40 62 44 D2 44 +42 49 B2 49 22 4A 92 4A 05 61 82 80 37 35 02 50 +13 05 45 89 EF 50 3F A2 03 A6 C9 07 21 B7 81 45 +83 A7 C9 07 B9 EB 05 45 EF 50 FF 9E 01 A0 4C 54 +39 65 13 05 C5 1B EF 50 1F A2 5C 54 03 A7 C9 07 +F9 9B 5C D4 1C 54 1C D4 E3 F6 E4 F4 37 35 02 50 +13 05 45 8A EF 50 3F 9E 35 BF 37 35 02 50 13 05 +05 86 37 34 02 50 EF 50 1F 9D 13 04 44 39 1C 54 +5C 54 85 8B E3 89 07 EE 21 B7 39 69 13 09 09 19 +13 05 C9 05 EF 50 3F 9D 83 A7 C9 07 C9 DF A6 85 +13 05 89 08 EF 50 3F 9C 83 A7 C9 07 C9 D7 A2 85 +13 05 09 0A EF 50 3F 9B BD BF 89 45 95 BF 99 45 +85 BF 85 45 B5 B7 95 45 A5 B7 91 45 95 B7 8D 45 +85 B7 01 11 22 CC 26 CA 4A C8 4E C6 52 C4 56 C2 +06 CE 5A C0 AE 84 32 84 36 89 BA 89 3E 8A C6 8A +37 83 02 10 03 28 83 01 13 78 18 00 E3 0C 08 FE +58 41 93 87 FA FF 93 B7 17 00 23 20 E3 08 18 45 +37 0B 02 50 E1 8F 23 22 E3 08 58 45 23 24 E3 08 +18 49 23 26 E3 08 58 49 23 28 E3 08 18 4D 23 2A +E3 08 58 4D 23 2C E3 08 18 51 23 2E E3 08 58 51 +23 20 E3 0A 18 55 23 22 E3 0A 58 55 23 24 E3 0A +18 59 23 26 E3 0A 58 59 23 28 E3 0A 18 5D 23 2A +E3 0A 58 5D 23 2C E3 0A 38 41 23 2E E3 0A 83 26 +CB 07 B5 C3 89 47 63 E9 D7 08 05 45 EF 50 BF 8A +03 27 CB 07 89 47 63 EA E7 06 06 04 26 0A 93 77 +24 00 13 7A 0A 20 96 09 B3 E7 47 01 93 F9 09 1E +12 09 B3 E7 37 01 13 79 09 01 8A 04 B3 E7 27 01 +91 88 62 44 C5 8F F2 40 D2 44 42 49 B2 49 22 4A +02 4B 93 E7 17 00 37 87 02 10 D6 85 92 4A 1C CB +01 45 05 61 F5 B6 13 87 EA FF 93 47 F4 FF 13 37 +17 00 F9 8F D1 DF 89 47 E3 F9 D7 F8 37 35 02 50 +13 05 45 93 EF 50 3F 85 49 B7 37 35 02 50 13 05 +45 89 EF 50 5F 84 51 B7 37 35 02 50 13 05 45 8C +EF 50 7F 83 9D B7 41 11 06 C6 22 C4 26 C2 37 87 +02 10 1C 4F 85 8B F5 DF B7 04 02 50 83 A7 C4 07 +09 44 63 66 F4 04 37 34 02 50 13 04 44 39 1C 54 +5C 54 85 8B 9D E3 73 00 50 10 93 07 40 06 01 00 +FD 17 C2 07 C1 83 E5 FF 1C 54 5C 54 85 8B E5 D7 +03 A7 C4 07 89 47 63 E5 E7 04 5C 54 B2 40 92 44 +F9 9B 5C D4 1C 54 1C D4 22 44 41 01 82 80 37 35 +02 50 13 05 45 89 EF 50 0F FC 83 A7 C4 07 E3 74 +F4 FA 37 35 02 50 13 05 05 86 37 34 02 50 EF 50 +8F FA 13 04 44 39 1C 54 5C 54 85 8B C9 DF 4D BF +4C 54 39 65 13 05 C5 1B EF 50 EF FA 7D B7 01 00 +52 65 63 65 69 76 65 64 20 53 48 41 32 35 36 20 +65 72 72 20 69 6E 74 72 20 77 69 74 68 20 73 74 +61 74 75 73 20 3D 20 25 64 0A 00 00 52 65 63 65 +69 76 65 64 20 53 48 41 32 35 36 20 6E 6F 74 69 +66 20 69 6E 74 72 20 77 69 74 68 20 73 74 61 74 +75 73 20 3D 20 25 64 0A 00 00 00 00 41 74 20 6F +66 66 73 65 74 20 5B 25 64 5D 2C 20 73 68 61 5F +64 69 67 65 73 74 20 64 61 74 61 20 6D 69 73 6D +61 74 63 68 21 0A 00 00 41 63 74 75 61 6C 20 20 +20 64 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +45 78 70 65 63 74 65 64 20 64 61 74 61 3A 20 30 +78 25 78 0A 00 00 00 00 41 11 22 C4 37 04 02 50 +03 27 C4 07 06 C6 89 47 63 E0 E7 04 37 37 02 50 +13 07 47 39 1C 53 54 53 D5 8F 9D E3 73 00 50 10 +93 07 40 06 01 00 FD 17 C2 07 C1 83 E5 FF 1C 53 +54 53 D5 8F E5 D7 83 26 C4 07 89 47 63 E5 D7 02 +B2 40 22 44 41 01 82 80 37 35 02 50 13 05 C5 98 +EF 50 6F E7 37 37 02 50 13 07 47 39 1C 53 54 53 +D5 8F CD DF C9 BF 22 44 B2 40 4C 53 3D 65 13 05 +05 92 41 01 6F 50 2F E7 B7 07 02 50 03 A7 C7 07 +41 11 22 C4 06 C6 8D 47 2A 84 63 ED E7 00 0A 04 +31 88 13 64 14 00 B7 07 02 10 B2 40 80 CB 22 44 +41 01 82 80 AA 85 3D 65 13 05 05 95 EF 50 AF E3 +F9 BF B7 07 02 50 03 A7 C7 07 41 11 22 C4 06 C6 +8D 47 2A 84 63 ED E7 00 0A 04 31 88 13 64 24 00 +B7 07 02 10 B2 40 80 CB 22 44 41 01 82 80 AA 85 +3D 65 13 05 45 97 EF 50 0F E0 F9 BF B7 07 02 50 +03 A7 C7 07 41 11 22 C4 06 C6 8D 47 2A 84 63 ED +E7 00 0A 04 31 88 13 64 14 02 B7 07 02 10 B2 40 +80 CB 22 44 41 01 82 80 AA 85 3D 65 13 05 85 99 +EF 50 6F DC F9 BF B7 07 02 50 03 A7 C7 07 41 11 +22 C4 06 C6 8D 47 2A 84 63 ED E7 00 0A 04 31 88 +13 64 24 02 B7 07 02 10 B2 40 80 CB 22 44 41 01 +82 80 AA 85 3D 65 13 05 45 9C EF 50 CF D8 F9 BF +B7 07 02 50 03 A7 C7 07 8D 47 63 E8 E7 00 B7 07 +02 10 05 47 23 A8 E7 62 82 80 37 35 02 50 41 11 +13 05 85 9A 06 C6 EF 50 0F D4 B2 40 B7 07 02 10 +05 47 23 A8 E7 62 41 01 82 80 B7 07 02 50 03 A7 +C7 07 89 47 63 E7 E7 00 B7 07 02 10 41 47 98 CB +82 80 37 35 02 50 41 11 13 05 C5 9C 06 C6 EF 50 +8F D0 B2 40 B7 07 02 10 41 47 98 CB 41 01 82 80 +01 11 22 CC 4A C8 06 CE 26 CA 4E C6 52 C4 2E 84 +32 89 B7 07 02 10 98 4F 05 8B 75 DF B7 04 02 10 +37 06 FE EF 93 87 07 08 13 06 06 F8 93 85 04 10 +BE 86 91 07 33 87 C7 00 2A 97 18 43 98 C2 E3 99 +B7 FE B7 09 02 50 83 A7 C9 07 09 4A 63 66 FA 14 +93 17 24 00 B1 8B 93 E7 17 00 9C C8 37 37 02 50 +13 07 47 39 1C 53 54 53 D5 8F 9D E3 73 00 50 10 +93 07 40 06 01 00 FD 17 C2 07 C1 83 E5 FF 1C 53 +54 53 D5 8F E5 D7 83 A7 C9 07 09 44 63 65 F4 0E +B7 07 02 10 83 A4 07 10 03 24 49 00 63 15 94 0C +83 A4 47 10 03 24 89 00 63 92 84 16 83 A4 87 10 +03 24 C9 00 63 9A 84 14 83 A4 C7 10 03 24 09 01 +63 9A 84 14 83 A4 07 11 03 24 49 01 63 92 84 14 +83 A4 47 11 03 24 89 01 63 96 84 14 83 A4 87 11 +03 24 C9 01 63 9A 84 14 83 A4 C7 11 03 24 09 02 +63 92 84 14 83 A4 07 12 03 24 49 02 63 9A 84 12 +83 A4 47 12 03 24 89 02 63 92 84 12 83 A4 87 12 +03 24 C9 02 63 96 84 10 83 A4 C7 12 03 24 09 03 +63 9C 84 0E 83 A4 07 13 03 24 49 03 63 98 84 10 +83 A4 47 13 03 24 89 03 63 92 84 0E 83 A4 87 13 +03 24 C9 03 63 92 84 0E 83 A4 C7 13 03 24 09 04 +BD 45 63 9B 84 00 F2 40 62 44 D2 44 42 49 B2 49 +22 4A 05 61 82 80 81 45 83 A7 C9 07 B5 E7 05 45 +EF 50 6F B6 01 A0 4C 53 3D 65 13 05 05 92 EF 50 +8F B9 83 A7 C9 07 E3 75 F4 F0 37 35 02 50 13 05 +45 9F EF 50 4F B6 ED BD 37 35 02 50 13 05 45 9E +EF 50 6F B5 93 17 24 00 03 A7 C9 07 B1 8B 93 E7 +17 00 9C C8 E3 74 EA EA 37 35 02 50 13 05 C5 98 +EF 50 6F B3 37 37 02 50 13 07 47 39 1C 53 54 53 +D5 8F E3 8D 07 E8 45 BD 3D 69 13 09 09 92 13 05 +09 0D EF 50 4F B3 83 A7 C9 07 D1 D3 A6 85 13 05 +C9 0F EF 50 4F B2 83 A7 C9 07 B5 DB A2 85 13 05 +49 11 EF 50 4F B1 A5 B7 89 45 B9 BF 85 45 A9 BF +91 45 99 BF 8D 45 89 BF AD 45 B9 B7 B5 45 A9 B7 +A9 45 99 B7 95 45 89 B7 B9 45 3D BF A5 45 2D BF +A1 45 1D BF 9D 45 0D BF 99 45 3D B7 B1 45 2D B7 +01 11 26 CA 4A C8 06 CE 22 CC 4E C6 52 C4 AE 84 +32 88 36 89 B7 07 02 10 98 4F 05 8B 75 DF 37 04 +02 10 37 06 FE EF 93 87 07 08 13 06 06 F8 93 05 +04 10 BE 86 91 07 33 87 C7 00 2A 97 18 43 98 C2 +E3 99 B7 FE 03 27 48 00 B7 09 02 50 09 4A 98 C3 +83 27 88 00 23 22 F4 10 83 27 C8 00 23 24 F4 10 +83 27 08 01 23 26 F4 10 83 27 48 01 23 28 F4 10 +83 27 88 01 23 2A F4 10 83 27 C8 01 23 2C F4 10 +83 27 08 02 23 2E F4 10 83 27 48 02 23 20 F4 12 +83 27 88 02 23 22 F4 12 83 27 C8 02 23 24 F4 12 +83 27 08 03 23 26 F4 12 83 27 48 03 23 28 F4 12 +83 27 88 03 23 2A F4 12 83 27 C8 03 23 2C F4 12 +83 27 08 04 23 2E F4 12 83 A7 C9 07 63 66 FA 14 +93 97 24 00 B1 8B 93 E7 27 04 1C C8 37 37 02 50 +13 07 47 39 1C 53 54 53 D5 8F 9D E3 73 00 50 10 +93 07 40 06 01 00 FD 17 C2 07 C1 83 E5 FF 1C 53 +54 53 D5 8F E5 D7 83 A7 C9 07 09 44 63 65 F4 0E +B7 07 02 10 83 A4 07 10 03 24 49 00 63 95 84 0C +83 A4 47 10 03 24 89 00 63 92 84 16 83 A4 87 10 +03 24 C9 00 63 9A 84 14 83 A4 C7 10 03 24 09 01 +63 9A 84 14 83 A4 07 11 03 24 49 01 63 92 84 14 +83 A4 47 11 03 24 89 01 63 96 84 14 83 A4 87 11 +03 24 C9 01 63 9A 84 14 83 A4 C7 11 03 24 09 02 +63 92 84 14 83 A4 07 12 03 24 49 02 63 9A 84 12 +83 A4 47 12 03 24 89 02 63 92 84 12 83 A4 87 12 +03 24 C9 02 63 96 84 10 83 A4 C7 12 03 24 09 03 +63 9C 84 0E 83 A4 07 13 03 24 49 03 63 98 84 10 +83 A4 47 13 03 24 89 03 63 92 84 0E 83 A4 87 13 +03 24 C9 03 63 92 84 0E 83 A4 C7 13 03 24 09 04 +BD 45 63 9B 84 00 F2 40 62 44 D2 44 42 49 B2 49 +22 4A 05 61 82 80 81 45 83 A7 C9 07 B5 E7 05 45 +EF 50 6F 8A 01 A0 4C 53 3D 65 13 05 05 92 EF 50 +8F 8D 83 A7 C9 07 E3 75 F4 F0 37 35 02 50 13 05 +45 9F EF 50 4F 8A ED BD 37 35 02 50 13 05 45 9E +EF 50 6F 89 93 97 24 00 03 A7 C9 07 B1 8B 93 E7 +27 04 1C C8 E3 74 EA EA 37 35 02 50 13 05 C5 98 +EF 50 6F 87 37 37 02 50 13 07 47 39 1C 53 54 53 +D5 8F E3 8D 07 E8 45 BD 3D 69 13 09 09 92 13 05 +C9 12 EF 50 4F 87 83 A7 C9 07 D1 D3 A6 85 13 05 +89 15 EF 50 4F 86 83 A7 C9 07 B5 DB A2 85 13 05 +09 17 EF 50 4F 85 A5 B7 89 45 B9 BF 85 45 A9 BF +91 45 99 BF 8D 45 89 BF AD 45 B9 B7 B5 45 A9 B7 +A9 45 99 B7 95 45 89 B7 B9 45 3D BF A5 45 2D BF +A1 45 1D BF 9D 45 0D BF 99 45 3D B7 B1 45 2D B7 +52 65 63 65 69 76 65 64 20 53 48 41 35 31 32 20 +6E 6F 74 69 66 20 69 6E 74 72 20 77 69 74 68 20 +73 74 61 74 75 73 20 3D 20 25 64 0A 00 00 00 00 +53 48 41 35 31 32 3A 20 53 65 74 20 6D 6F 64 65 +3A 20 30 78 25 78 20 61 6E 64 20 69 6E 69 74 0A +00 00 00 00 53 48 41 35 31 32 3A 20 53 65 74 20 +6D 6F 64 65 3A 20 30 78 25 78 20 61 6E 64 20 6E +65 78 74 0A 00 00 00 00 53 48 41 35 31 32 3A 20 +53 65 74 20 6D 6F 64 65 3A 20 30 78 25 78 20 61 +6E 64 20 69 6E 69 74 20 77 69 74 68 20 6C 61 73 +74 0A 00 00 53 48 41 35 31 32 3A 20 53 65 74 20 +6D 6F 64 65 3A 20 30 78 25 78 20 61 6E 64 20 6E +65 78 74 20 77 69 74 68 20 6C 61 73 74 0A 00 00 +41 74 20 6F 66 66 73 65 74 20 5B 25 64 5D 2C 20 +73 68 61 5F 64 69 67 65 73 74 20 64 61 74 61 20 +6D 69 73 6D 61 74 63 68 21 0A 00 00 41 63 74 75 +61 6C 20 20 20 64 61 74 61 3A 20 30 78 25 78 0A +00 00 00 00 45 78 70 65 63 74 65 64 20 64 61 74 +61 3A 20 30 78 25 78 0A 00 00 00 00 41 74 20 6F +66 66 73 65 74 20 5B 25 64 5D 2C 20 73 68 61 5F +64 69 67 65 73 74 20 64 61 74 61 20 6D 69 73 6D +61 74 63 68 21 0A 00 00 41 63 74 75 61 6C 20 20 +20 64 61 74 61 3A 20 30 78 25 78 0A 00 00 00 00 +45 78 70 65 63 74 65 64 20 64 61 74 61 3A 20 30 +78 25 78 0A 00 00 00 00 85 47 B3 95 B7 00 71 05 +1C 41 ED 8F F5 DF 82 80 41 11 06 C6 AA 86 2E 87 +B2 87 01 CD 01 CE 13 06 00 02 63 7F B6 04 B7 07 +02 50 83 A7 C7 07 B1 E3 01 A0 99 C5 B7 07 02 50 +83 A7 C7 07 85 E7 01 A0 01 46 ED DB 93 05 27 00 +CC D3 85 45 23 80 B7 00 A3 80 C7 00 B2 40 13 85 +27 00 3A 86 B6 85 41 01 6F 20 80 6B 37 35 02 50 +13 05 45 A1 EF 40 3F E0 F9 B7 37 35 02 50 13 05 +85 A6 EF 40 5F DF 4D BF 13 96 35 00 42 06 41 82 +93 05 00 10 63 15 B6 02 13 06 37 00 D0 D3 09 46 +23 80 C7 00 05 46 A3 80 C7 00 23 81 07 00 B2 40 +13 85 37 00 3A 86 B6 85 41 01 6F 20 60 66 13 76 +F6 0F 69 B7 41 11 06 C6 B2 87 19 C9 19 CA 11 47 +63 70 B7 02 B7 07 02 50 83 A7 C7 07 B9 E3 01 A0 +99 C5 B7 07 02 50 83 A7 C7 07 8D E7 01 A0 75 DA +93 86 25 00 13 97 35 00 94 C7 85 46 23 80 D7 00 +A3 80 E7 00 B2 40 2E 86 AA 85 41 01 13 85 27 00 +6F 20 00 61 37 35 02 50 13 05 05 AB EF 40 BF D5 +F1 B7 37 35 02 50 13 05 45 AF EF 40 DF D4 45 BF +41 11 06 C6 29 C5 A1 C5 89 47 63 0A F6 08 63 ED +C7 04 51 CA 5C 4D 21 47 13 06 20 02 D8 C5 23 A2 +05 00 90 C5 85 8B 11 48 13 07 C5 01 A9 CF A2 06 +23 90 05 00 B3 E7 06 01 5C C9 5C C9 5C 49 F5 47 +1C CD 1C 43 89 8B F5 DF B2 40 41 01 82 80 B7 07 +02 50 83 A7 C7 07 91 E3 01 A0 37 35 02 50 13 05 +45 B3 EF 40 5F CE CD BF 8D 47 63 14 F6 02 49 46 +41 47 21 48 5C 4D D8 C5 23 A2 05 00 90 C5 85 8B +13 07 C5 01 CD F7 B7 07 02 50 83 A7 C7 07 8D E3 +01 A0 B7 07 02 50 83 A7 C7 07 95 E3 01 A0 69 46 +31 47 19 48 C1 BF 13 06 40 02 1D 47 09 48 D9 B7 +37 35 02 50 13 05 45 BA EF 40 FF C8 D1 BF 37 35 +02 50 13 05 45 B7 EF 40 1F C8 C9 BF 41 11 06 C6 +0D C5 85 C5 31 C6 85 47 63 1E F6 02 5C 4D 13 07 +20 02 98 C5 85 8B 11 46 13 07 C5 01 B1 E3 B7 07 +02 50 83 A7 C7 07 AD EB 01 A0 B7 07 02 50 83 A7 +C7 07 91 E3 01 A0 37 35 02 50 13 05 85 BD EF 40 +9F C3 CD BF B7 07 02 50 83 A7 C7 07 9D EF 01 A0 +5C 4D 13 07 A0 02 98 C5 85 8B 13 07 C5 01 E1 D3 +93 97 86 00 D1 8F 23 90 05 00 23 A6 05 00 23 A2 +05 00 93 E7 07 02 5C C9 5C C9 F5 47 1C CD 1C 43 +89 8B F5 DF B2 40 41 01 82 80 37 35 02 50 13 05 +45 C2 EF 40 5F BE 65 BF 37 35 02 50 13 05 85 C5 +EF 40 7F BD 51 B7 5D 71 86 C6 A2 C4 A6 C2 CA C0 +15 CD 8D CD 2A 84 B1 CE 03 D8 06 00 05 45 63 0A +A8 04 25 CE 05 45 63 10 A6 04 13 08 20 02 11 46 +48 4C 23 A4 05 01 93 04 C4 01 05 89 35 E1 B7 07 +02 50 83 A7 C7 07 63 95 07 10 01 A0 B7 07 02 50 +83 A7 C7 07 91 E3 01 A0 37 35 02 50 13 05 C5 C8 +EF 40 7F B7 CD BF B7 07 02 50 83 A7 C7 07 F1 EB +01 A0 11 C7 03 58 07 00 05 45 E3 14 A8 FA 63 06 +06 10 05 47 63 19 E6 0A BE 86 05 46 22 85 26 44 +B6 40 96 44 06 49 61 61 D1 B5 13 08 A0 02 49 BF +A2 07 D1 8F 23 90 05 00 23 A6 05 00 23 A2 05 00 +93 E7 07 03 5C C8 5C C8 02 CA 02 CC 02 CE 02 D0 +02 D2 02 D4 02 D6 02 D8 02 DA 02 DC 02 DE 91 C6 +03 A9 86 00 89 47 63 E8 27 09 85 47 23 1A F1 00 +13 05 61 01 19 C3 50 53 3D EA 85 47 23 00 F5 00 +A3 00 05 00 D2 47 1C D0 E2 47 5C D0 F2 47 1C D4 +82 57 5C D4 92 57 1C D8 A2 57 5C D8 B2 57 1C DC +C2 57 5C DC D2 57 3C C0 E2 57 7C C0 F2 57 3C C4 +F5 47 1C CC 9C 40 89 8B F5 DF B6 40 26 44 96 44 +06 49 61 61 82 80 B7 07 02 50 83 A7 C7 07 9D EF +01 A0 37 35 02 50 13 05 85 D1 EF 40 DF A8 0D B7 +37 35 02 50 13 05 45 D5 EF 40 FF A7 FD B5 BA 85 +EF 20 00 32 41 BF 4A 86 B6 85 48 08 3A C6 EF 20 +20 31 5C 08 32 47 33 85 27 01 AD B7 37 35 02 50 +13 05 05 CD EF 40 3F A5 65 BF BE 86 01 46 FD BD +41 11 06 C6 19 C3 23 20 07 00 4D C1 C5 C1 51 CE +9C 45 D5 CB 5C 4D 13 03 C5 01 89 8B E5 C3 29 4F +B7 18 04 10 85 4E 8D 4F B5 CE 03 28 03 00 13 58 +88 00 13 78 F8 01 33 08 0F 41 0E 08 63 F3 06 01 +36 88 63 0B 08 04 93 77 16 00 C1 E7 B2 87 42 8E +63 00 D8 05 93 F5 37 00 C1 E9 3E 85 63 F1 CF 03 +13 05 CE FF 71 99 11 05 3E 95 8C 43 91 07 23 A0 +B8 80 E3 9C A7 FE 13 7E 3E 00 63 F5 CE 0B 83 55 +05 00 79 1E 93 07 25 00 23 90 B8 80 63 06 0E 00 +83 C7 07 00 23 80 F8 80 42 96 B3 86 06 41 49 D7 +23 20 07 01 B2 40 41 01 82 80 BD D2 B7 07 02 50 +83 A7 C7 07 91 E3 01 A0 37 35 02 50 13 05 05 D9 +EF 40 7F 98 CD BF B7 07 02 50 83 A7 C7 07 8D EF +01 A0 83 45 06 00 13 0E F8 FF 93 07 16 00 23 80 +B8 80 E3 E9 CE F7 5D B7 83 D5 07 00 79 1E 89 07 +23 90 B8 80 E3 E6 CF F7 3E 85 41 B7 B7 07 02 50 +83 A7 C7 07 89 EB 01 A0 37 35 02 50 13 05 C5 DC +EF 40 7F 93 75 BF 37 35 02 50 13 05 05 E0 EF 40 +9F 92 D5 B7 AA 87 9D B7 41 11 06 C6 22 C4 61 C5 +F9 C1 69 C2 19 C3 23 20 07 00 03 C8 05 00 63 1A +08 08 03 C8 15 00 63 0F 08 06 83 A8 C5 00 13 03 +F0 0F 05 48 96 08 63 7F 13 05 41 68 33 B8 08 01 +37 03 00 01 13 48 18 00 33 B3 68 00 13 43 13 00 +09 08 1A 98 13 03 F8 FF 0E 03 B3 DE 68 00 93 FE +FE 0F 37 1E 04 10 23 00 DE 81 61 13 9D 4E 63 D1 +6E 02 33 D3 68 00 13 73 F3 0F 23 00 6E 80 11 43 +63 18 68 00 13 D3 88 00 13 73 F3 0F 23 00 6E 80 +13 78 F8 0F 37 13 04 10 93 F8 F8 0F 23 00 13 81 +23 00 03 81 05 48 23 80 05 01 13 08 E0 02 23 2C +05 01 03 A8 C5 00 63 0D 08 02 83 A8 45 00 B3 08 +18 41 63 F7 D8 02 B7 07 02 50 83 A7 C7 07 63 99 +07 14 01 A0 A1 D2 B7 07 02 50 83 A7 C7 07 91 E3 +01 A0 37 35 02 50 13 05 45 E3 EF 40 DF 83 CD BF +E1 C2 83 A8 85 00 93 02 C5 01 93 03 10 03 C0 41 +B3 8E 88 40 63 10 08 02 63 F3 D6 01 B6 8E 63 90 +0E 04 23 2C 75 00 23 A2 05 00 C0 41 B3 8E 88 40 +E3 04 08 FE 63 6E 18 01 63 ED D6 09 63 91 0E 02 +63 94 08 09 B7 07 02 50 83 A7 C7 07 F9 EB 01 A0 +B3 0E 88 40 63 F3 D6 01 B6 8E E3 85 0E FE 03 A8 +02 00 13 78 48 00 E3 0C 08 FE B7 0F 01 04 93 8F +0F 10 A2 9F 8A 0F 7E 88 01 4E 03 2F 08 00 03 23 +08 10 B3 08 F8 41 B2 98 33 43 E3 01 23 A0 68 00 +05 0E 11 08 E3 13 DE FF 72 94 13 18 2E 00 C0 C1 +42 96 B3 86 C6 41 11 C7 03 28 07 00 72 98 23 20 +07 01 95 E3 91 C6 03 A8 C5 00 83 A8 85 00 81 BF +B2 40 22 44 41 01 82 80 33 08 18 41 23 A6 05 01 +89 BF B6 8E A5 B7 83 A8 85 00 B7 0E 01 04 93 8E +0E 10 C6 9E 13 08 20 03 8A 0E B3 0F 18 41 E3 83 +08 FD 76 88 01 4E 03 2F 08 00 03 23 08 10 B3 08 +D8 41 BE 98 33 43 E3 01 23 A0 68 00 05 0E 11 08 +E3 63 FE FF 11 48 63 84 0F 00 13 98 2F 00 C2 97 +51 BF 37 35 02 50 13 05 C5 EB EF 40 CF F0 05 B7 +37 35 02 50 13 05 85 E6 EF 40 EF EF 5D B5 41 11 +06 C6 1D C5 95 C5 83 C7 05 00 A1 C3 13 07 C5 01 +1C 43 91 8B F5 DF B2 40 D9 47 1C CD 23 90 05 00 +23 A2 05 00 23 A4 05 00 23 A6 05 00 41 01 82 80 +B7 07 02 50 83 A7 C7 07 91 E3 01 A0 37 35 02 50 +13 05 45 EF EF 40 2F EB CD BF B7 07 02 50 83 A7 +C7 07 91 E3 01 A0 37 35 02 50 13 05 45 F2 EF 40 +8F E9 CD BF B7 07 02 30 C8 4B 82 80 B7 07 04 30 +3E 95 08 41 82 80 B7 07 04 30 AA 97 8C C3 82 80 +B7 07 02 50 03 A7 C7 07 8D 47 63 E8 E7 00 37 07 +02 30 1C 4F F9 9B 1C CF 82 80 45 65 41 11 13 05 +45 AC 06 C6 EF 40 2F E7 37 07 02 30 1C 4F B2 40 +F9 9B 1C CF 41 01 82 80 41 11 22 C4 37 04 02 50 +83 27 C4 07 26 C2 06 C6 91 44 63 EF F4 02 B7 07 +02 30 CC 4F 99 47 99 81 9D 89 63 8F F5 04 B9 CD +9D 47 63 97 F5 00 83 27 C4 07 A5 EF 3D 45 01 A8 +45 65 13 05 05 AE EF 40 0F E2 13 05 F0 0F B2 40 +22 44 92 44 41 01 82 80 37 35 02 50 13 05 C5 F5 +EF 40 6F DE B7 07 02 30 CC 4F 99 47 99 81 9D 89 +E3 9F F5 FA 83 27 C4 07 63 F8 F4 00 37 35 02 50 +13 05 45 F8 EF 40 2F DC 01 45 D1 B7 03 27 C4 07 +85 47 63 E8 E7 00 05 45 B2 40 22 44 92 44 41 01 +82 80 37 35 02 50 13 05 45 FC EF 40 CF D9 05 45 +E5 B7 37 35 02 50 13 05 C5 FF EF 40 CF D8 3D 45 +79 B7 B7 07 02 50 03 A7 C7 07 41 11 22 C4 06 C6 +8D 47 2A 84 63 EC E7 00 37 07 02 30 5C 4F B2 40 +C1 9B C1 8F 22 44 5C CF 41 01 82 80 AA 85 45 65 +13 05 45 B2 EF 40 2F D7 C5 B7 B7 07 02 50 03 A7 +C7 07 41 11 22 C4 06 C6 8D 47 2A 84 63 E6 E7 02 +B7 07 03 30 D8 5F 93 17 84 00 B3 66 E4 00 91 C7 +B7 07 00 FF 7D 8F B3 66 87 00 B2 40 22 44 B7 07 +03 30 D4 DF 41 01 82 80 AA 85 45 65 13 05 C5 B4 +EF 40 6F D2 F1 B7 B7 07 02 50 03 A7 C7 07 41 11 +22 C4 06 C6 26 C2 8D 47 2A 84 63 EC E7 04 B7 17 +02 30 84 43 85 47 63 ED 87 02 63 E2 97 02 93 77 +14 00 33 67 94 00 81 C7 F9 98 33 E7 84 00 B2 40 +22 44 B7 17 02 30 98 C3 92 44 41 01 82 80 45 65 +13 05 C5 BC EF 40 2F CD 05 45 EF 40 CF C8 C1 BF +45 65 13 05 05 BB EF 40 0F CC 05 45 EF 40 AF C7 +7D BF AA 85 45 65 13 05 45 B7 EF 40 CF CA 45 B7 +B7 07 02 50 03 A7 C7 07 41 11 22 C4 06 C6 8D 47 +2A 84 63 E0 E7 04 B7 07 03 30 DC 5F 13 17 84 00 +19 CF 37 07 00 FF 79 8C 13 44 F4 FF 7D 8C 79 8C +B7 07 03 30 B2 40 C0 DF 22 44 41 01 82 80 13 44 +F4 FF 7D 8C B7 07 03 30 B2 40 C0 DF 22 44 41 01 +82 80 AA 85 45 65 13 05 85 BE EF 40 CF C4 65 BF +09 CD 01 47 B7 06 02 30 19 A0 63 08 E5 00 9C 42 +05 07 85 8B FD FB 01 45 82 80 05 45 82 80 79 71 +4E CE B7 09 02 50 22 D4 83 A7 C9 07 37 04 02 30 +26 D2 04 44 4A D0 06 D6 52 CC 0D 49 63 6D F9 00 +40 44 B2 50 22 85 22 54 02 59 F2 49 62 4A A6 85 +92 54 45 61 82 80 45 6A 13 0A 4A AC A6 85 13 05 +CA 14 EF 40 4F BE 83 A7 C9 07 40 44 E3 7B F9 FC +A2 85 13 05 0A 17 EF 40 0F BD E1 B7 79 71 4A D0 +37 09 02 50 03 27 C9 07 22 D4 26 D2 06 D6 4E CE +52 CC 2A C4 2E C6 89 47 2A 84 AE 84 63 E9 E7 14 +B7 07 04 00 63 EB 87 12 B7 C7 5E BA 93 87 17 A1 +63 82 F4 02 B7 D7 BE BA 93 87 E7 AF 63 80 F4 14 +45 65 A6 85 13 05 C5 C8 EF 40 EF B7 05 45 EF 40 +8F B3 01 A0 B7 04 00 50 37 0A 00 40 37 07 02 30 +50 4B 75 C2 13 07 06 02 63 6F E4 0C 13 77 36 00 +11 C3 11 06 37 07 02 30 4C 4B 03 25 C9 07 89 46 +23 20 BA 00 03 28 47 01 93 59 26 00 23 20 0A 01 +58 4B 23 20 EA 00 63 E5 A6 10 93 96 29 00 D2 87 +D2 96 37 05 02 30 63 88 09 00 58 49 91 07 23 AE +E7 FE E3 9C D7 FE B7 07 02 30 D8 4B 69 C7 93 77 +C6 FF 93 06 07 02 B6 97 63 6F F4 0A 93 77 37 00 +91 C3 11 07 B7 07 02 30 D0 4B 83 25 C9 07 13 54 +27 00 90 C0 D0 4B 89 46 90 C0 D8 4B 98 C0 63 E2 +B6 0C 63 0A 04 0C 13 17 24 00 A6 87 26 97 37 06 +02 30 54 4A 91 07 23 AE D7 FE E3 1C F7 FE B7 07 +02 30 23 A6 07 00 8D 47 63 F8 B7 00 45 65 89 45 +13 05 45 B2 EF 40 2F AA 37 07 02 30 5C 4F B2 50 +22 54 C1 9B 93 E7 27 00 5C CF 92 54 02 59 F2 49 +62 4A 45 61 82 80 45 65 A2 85 13 05 05 CC EF 40 +8F A7 05 45 EF 40 2F A3 01 A0 45 65 A2 85 13 05 +85 C5 EF 40 4F A6 05 45 EF 40 EF A1 01 A0 37 35 +02 50 13 05 45 05 EF 40 0F A3 5D B5 B7 04 02 50 +37 0A 02 40 E1 BD 01 14 45 65 3A 86 B3 05 34 41 +13 05 C5 D1 EF 40 2F A3 05 45 EF 40 CF 9E 01 A0 +37 35 02 50 13 05 45 07 32 C2 EF 40 CF 9F 12 46 +ED B5 37 35 02 50 13 05 85 08 EF 40 CF 9E 83 25 +C9 07 15 F8 A9 B7 23 A6 07 00 B9 BF 79 71 4E CE +B7 09 02 50 03 A7 C9 07 4A D0 06 D6 22 D4 26 D2 +52 CC 56 CA 5A C8 2A C4 2E C6 8D 47 2A 89 63 E6 +E7 04 01 44 B7 04 00 40 63 77 A4 02 B7 07 02 30 +D8 4B 11 04 93 87 44 00 98 C0 B3 05 F4 40 37 06 +02 30 63 7A 24 01 54 4A 91 07 33 87 B7 00 23 AE +D7 FE E3 6A 27 FF B2 50 22 54 92 54 02 59 F2 49 +62 4A D2 4A 42 4B 45 61 82 80 37 35 02 50 01 44 +13 05 C5 09 EF 40 2F 96 E3 7F 24 FD C5 6A B7 04 +00 40 0D 4B 93 8A 8A D7 37 0A 02 30 11 A0 BA 84 +83 A7 C9 07 A6 85 56 85 E3 7A FB F8 90 40 11 04 +EF 40 6F 95 83 27 4A 01 13 87 44 00 9C C0 E3 60 +24 FF 55 B7 41 11 26 C2 4A C0 06 C6 22 C4 B7 07 +04 00 2A 89 AE 84 63 E0 A7 06 D5 C4 81 47 37 07 +02 30 19 A0 63 83 F4 06 00 43 85 07 05 88 7D F8 +B7 17 03 30 03 A6 87 80 13 77 D6 FE 23 A4 E7 80 +63 0C 09 00 81 47 B7 06 04 30 33 87 D7 00 23 20 +07 00 91 07 E3 EB 27 FF B2 40 22 44 B7 07 02 30 +05 47 98 D3 B7 17 03 30 23 A4 C7 80 92 44 02 49 +01 45 41 01 82 80 AA 85 45 65 13 05 45 D8 EF 40 +8F 8C 05 45 EF 40 2F 88 49 BF B7 07 02 50 03 A7 +C7 07 85 47 63 F8 E7 00 37 35 02 50 13 05 05 0C +EF 40 6F 88 85 47 E3 85 F4 F8 37 07 02 30 13 06 +07 02 85 46 19 A0 E3 8D 84 F6 14 C2 1C 43 05 04 +85 8B F5 FB B5 B7 B7 07 02 50 03 A7 C7 07 85 47 +E3 F0 E7 F6 37 35 02 50 13 05 05 0C EF 40 AF 84 +81 BF B7 07 02 50 03 A7 C7 07 41 11 22 C4 06 C6 +8D 47 2A 84 63 FB E7 04 95 47 63 FC A7 02 37 36 +02 50 AA 85 45 65 13 06 C6 10 13 05 85 DA EF 40 +8F 83 B7 07 03 30 23 A4 87 62 37 07 03 30 83 27 +47 62 B2 40 22 44 93 E7 17 00 23 22 F7 62 41 01 +82 80 29 C1 AA 85 37 36 02 50 45 65 13 06 86 0F +13 05 85 DA EF 40 2F 80 29 A0 61 D9 95 47 E3 E2 +A7 FC B7 07 03 30 15 47 23 A4 E7 62 37 07 03 30 +83 27 47 62 B2 40 22 44 93 E7 17 00 23 22 F7 62 +41 01 82 80 37 36 02 50 45 65 13 06 86 0E 81 45 +13 05 85 DA EF 30 3F FC 37 07 03 30 83 27 47 62 +B2 40 22 44 93 E7 17 00 23 22 F7 62 41 01 82 80 +B7 07 03 30 05 47 23 A0 E7 62 82 80 37 17 02 30 +1C 43 85 8B F5 FF 82 80 0D 89 13 65 45 00 B7 17 +02 30 88 C7 82 80 B7 17 02 30 05 47 98 CF 82 80 +B7 17 02 30 DC 4F 85 8B 89 EB B7 06 04 30 37 17 +02 30 9C 42 5C 4F 85 8B ED DF 82 80 B7 17 02 30 +05 47 98 C3 82 80 B7 28 02 30 03 A8 C8 00 13 78 +18 00 E3 1C 08 FE 23 AE A8 00 23 A0 B8 02 23 A2 +E8 02 23 A4 F8 02 41 C6 B7 07 00 12 85 07 37 26 +02 30 1C C6 50 42 85 65 FD 15 6D 8E 13 75 C7 FF +93 57 27 00 42 06 41 82 36 95 37 27 02 30 99 CB +5C 47 91 83 ED 8F E3 8D C7 FE 9C 42 91 06 5C D7 +E3 98 A6 FE B7 27 02 30 DC 47 05 47 37 26 02 30 +93 F5 37 00 85 46 63 97 E5 00 5C 46 13 F7 37 00 +E3 0D D7 FE 89 8B 85 CB B7 07 02 50 03 A7 C7 07 +41 11 06 C6 89 47 63 E1 E7 02 B7 27 02 30 09 47 +98 C7 05 45 EF 30 3F E7 B2 40 41 01 82 80 B7 07 +00 02 85 07 AD BF 82 80 37 35 02 50 13 05 C5 11 +EF 30 7F E7 D9 BF 41 11 06 C6 37 23 02 30 83 28 +C3 00 93 F8 18 00 E3 9C 08 FE 23 2E A3 00 23 20 +B3 02 23 22 E3 02 23 24 F3 02 49 C2 B7 07 00 12 +85 07 37 26 02 30 1C C6 50 42 85 65 FD 15 6D 8E +13 75 C7 FF 93 57 27 00 42 06 41 82 36 95 37 27 +02 30 99 CB 5C 47 91 83 ED 8F E3 8D C7 FE 9C 42 +91 06 5C D7 E3 98 A6 FE B7 27 02 30 DC 47 05 47 +37 26 02 30 93 F5 37 00 85 46 63 97 E5 00 5C 46 +13 F7 37 00 E3 0D D7 FE 89 8B 8D C7 63 06 08 04 +B7 07 02 50 03 A7 C7 07 89 47 63 E4 E7 04 B7 27 +02 30 09 47 98 C7 B2 40 41 01 82 80 B7 07 00 02 +85 07 41 B7 E3 09 08 FE 37 35 02 50 13 05 C5 18 +EF 30 7F DB B7 27 02 30 09 47 98 C7 05 45 EF 30 +9F D8 B2 40 41 01 82 80 37 35 02 50 13 05 C5 14 +C5 B7 37 35 02 50 13 05 C5 14 EF 30 DF D8 45 BF +37 28 02 30 83 26 C8 00 85 8A ED FE 23 2E A8 00 +23 20 B8 02 23 22 E8 02 23 24 F8 02 01 CA B7 07 +00 12 85 07 37 27 02 30 1C C7 82 80 B7 07 00 02 +85 07 37 27 02 30 1C C7 82 80 B7 27 02 30 DC 43 +05 66 7D 16 F1 8F 13 F7 C5 FF 13 D8 25 00 93 96 +07 01 B3 05 E5 00 C1 82 37 27 02 30 63 0C 08 00 +5C 47 91 83 F1 8F E3 8D D7 FE 1C 41 11 05 5C D7 +E3 98 A5 FE 01 45 82 80 B7 28 02 30 03 A8 C8 00 +13 78 18 00 E3 1C 08 FE 23 AA A8 00 23 AC B8 00 +23 A2 E8 02 23 A4 F8 02 41 C2 B7 07 12 00 85 07 +37 26 02 30 1C C6 5C 42 09 83 15 C3 0A 07 05 66 +B3 85 E6 00 7D 16 37 27 02 30 5C 47 91 83 F1 8F +ED DF 1C 5B 91 06 23 AE F6 FE E3 98 B6 FE B7 27 +02 30 DC 47 05 47 93 F6 37 00 63 9A E6 00 37 26 +02 30 85 46 5C 46 13 F7 37 00 E3 0D D7 FE 89 8B +85 CB B7 07 02 50 03 A7 C7 07 41 11 06 C6 89 47 +63 E1 E7 02 B7 27 02 30 09 47 98 C7 05 45 EF 30 +9F C5 B2 40 41 01 82 80 B7 07 02 00 85 07 49 B7 +82 80 37 35 02 50 13 05 C5 11 EF 30 DF C5 D9 BF +41 11 06 C6 37 23 02 30 83 28 C3 00 93 F8 18 00 +E3 9C 08 FE 23 2A A3 00 23 2C B3 00 23 22 E3 02 +23 24 F3 02 2D CE B7 07 12 00 85 07 37 26 02 30 +1C C6 5C 42 09 83 15 C3 0A 07 05 66 B3 85 E6 00 +7D 16 37 27 02 30 5C 47 91 83 F1 8F ED DF 1C 5B +91 06 23 AE F6 FE E3 98 B6 FE B7 27 02 30 DC 47 +05 47 93 F6 37 00 63 9A E6 00 37 26 02 30 85 46 +5C 46 13 F7 37 00 E3 0D D7 FE 89 8B 8D C7 63 06 +08 04 B7 07 02 50 03 A7 C7 07 89 47 63 E4 E7 04 +B7 27 02 30 09 47 98 C7 B2 40 41 01 82 80 B7 07 +02 00 85 07 61 B7 E3 09 08 FE 37 35 02 50 13 05 +C5 18 EF 30 5F BA B7 27 02 30 09 47 98 C7 05 45 +EF 30 7F B7 B2 40 41 01 82 80 37 35 02 50 13 05 +C5 14 C5 B7 37 35 02 50 13 05 C5 14 EF 30 BF B7 +45 BF 37 28 02 30 83 26 C8 00 85 8A ED FE 23 2A +A8 00 23 2C B8 00 23 22 E8 02 23 24 F8 02 01 CA +B7 07 12 00 85 07 37 27 02 30 1C C7 82 80 B7 07 +02 00 85 07 37 27 02 30 1C C7 82 80 B7 27 02 30 +DC 43 93 D7 25 00 95 C3 8A 07 85 66 33 06 F5 00 +37 27 02 30 FD 16 5C 47 91 83 F5 8F ED DF 1C 5B +11 05 23 2E F5 FE E3 18 C5 FE 82 80 B7 08 02 30 +83 A8 08 00 41 11 06 C6 93 F8 18 00 63 8B 08 00 +B7 07 02 50 83 A7 C7 07 A1 E3 B2 40 05 45 41 01 +82 80 91 C9 B7 07 02 50 83 A7 C7 07 D1 EF 05 45 +EF 30 7F AB 01 A0 B7 05 04 00 E3 75 B5 FE B3 88 +A7 00 63 F2 F8 02 37 07 02 50 03 27 C7 07 41 EB +05 45 EF 30 5F A9 01 A0 37 35 02 50 13 05 45 1D +EF 30 7F AA 5D BF E3 F0 B8 FE B7 25 02 30 83 A8 +C5 00 93 F8 18 00 E3 9C 08 FE C8 C9 23 AC 05 00 +D0 CD 94 D1 DC D1 23 A4 05 03 31 C7 B7 07 00 11 +85 07 37 27 02 30 1C C7 5C 47 05 47 93 F6 37 00 +63 9A E6 00 37 26 02 30 85 46 5C 46 13 F7 37 00 +E3 0D D7 FE 89 8B 85 EF B2 40 B7 07 02 30 05 47 +98 D3 01 45 41 01 82 80 AA 85 45 65 13 05 45 DE +EF 30 7F A5 A9 BF B7 07 00 01 85 07 5D BF 2A 86 +45 65 BE 85 13 05 45 E1 EF 30 FF A3 95 B7 37 35 +02 50 13 05 05 1F EF 30 1F A1 B7 27 02 30 09 47 +98 C7 05 45 EF 30 3F 9E 45 BF B7 08 02 30 83 A8 +08 00 41 11 06 C6 93 F8 18 00 63 8B 08 00 B7 07 +02 50 83 A7 C7 07 A1 E3 B2 40 05 45 41 01 82 80 +91 CA B7 07 02 50 83 A7 C7 07 A5 EF 05 45 EF 30 +9F 9A 01 A0 B7 06 04 00 E3 75 D6 FE B3 88 C7 00 +63 F2 F8 02 37 07 02 50 03 27 C7 07 2D E7 05 45 +EF 30 7F 98 01 A0 37 35 02 50 13 05 45 1D EF 30 +9F 99 5D BF E3 F0 D8 FE B7 28 02 30 83 A6 C8 00 +85 8A ED FE 23 AA A8 00 23 AC B8 00 23 AE C8 00 +23 A0 08 02 23 A2 F8 02 23 A4 08 03 15 C3 B7 07 +11 00 85 07 B2 40 37 27 02 30 1C C7 01 45 41 01 +82 80 45 65 B2 85 13 05 05 E6 EF 30 DF 96 BD BF +C1 67 85 07 C5 B7 45 65 BE 85 13 05 05 E9 EF 30 +9F 95 71 B7 41 11 06 C6 0D 3F B7 27 02 30 DC 47 +05 47 93 F6 37 00 63 9A E6 00 37 26 02 30 85 46 +5C 46 13 F7 37 00 E3 0D D7 FE 89 8B 99 CF B7 07 +02 50 03 A7 C7 07 89 47 63 E0 E7 02 B7 27 02 30 +09 47 98 C7 05 45 EF 30 1F 8D B2 40 B7 07 02 30 +05 47 98 D3 41 01 82 80 37 35 02 50 13 05 C5 11 +EF 30 7F 8D E1 BF 01 11 4E C6 B7 09 02 50 03 A7 +C9 07 22 CC 26 CA 4A C8 06 CE 89 47 2A 89 AE 84 +32 84 63 E0 E7 0A B7 36 02 30 83 A7 86 80 37 27 +02 30 F9 9B 23 A4 F6 80 5C 47 85 8B F5 FF 23 2E +27 01 04 D3 B7 07 00 04 40 D3 85 07 1C C7 5C 47 +05 47 93 F6 37 00 63 9A E6 00 37 26 02 30 85 46 +5C 46 13 F7 37 00 E3 0D D7 FE 89 8B A9 C3 03 A7 +C9 07 89 47 63 E6 E7 02 B7 27 02 30 09 47 98 C7 +37 37 02 30 83 27 87 80 F2 40 62 44 93 E7 17 00 +23 24 F7 80 D2 44 42 49 B2 49 01 45 05 61 82 80 +37 35 02 50 13 05 C5 24 EF 30 FF 82 F1 B7 37 35 +02 50 13 05 05 28 EF 30 1F 82 05 45 EF 30 AF FF +01 A0 37 35 02 50 13 05 C5 22 EF 30 DF 80 A1 BF +01 11 4E C6 B7 09 02 50 03 A7 C9 07 22 CC 26 CA +4A C8 06 CE 89 47 2A 89 AE 84 32 84 63 E2 E7 06 +37 27 02 30 5C 47 85 8B F5 FF 23 2E 27 01 04 D3 +B7 07 00 04 40 D3 85 07 1C C7 5C 47 05 47 93 F6 +37 00 63 9A E6 00 37 26 02 30 85 46 5C 46 13 F7 +37 00 E3 0D D7 FE 89 8B 89 CF 03 A7 C9 07 89 47 +63 E7 E7 02 B7 27 02 30 09 47 98 C7 05 45 EF 30 +8F F7 F2 40 62 44 D2 44 42 49 B2 49 05 61 82 80 +37 35 02 50 13 05 05 2C EF 30 EF F7 51 BF 37 35 +02 50 13 05 C5 11 EF 30 0F F7 E9 B7 37 27 02 30 +5C 47 85 8B F5 FF 48 CF 0C D3 B7 07 00 04 50 D3 +85 07 1C C7 82 80 41 11 83 4E 01 01 06 C6 37 2E +02 30 03 23 CE 00 13 73 13 00 E3 1C 03 FE 23 2A +AE 00 23 2C BE 00 23 2E DE 00 23 20 EE 02 23 22 +0E 03 23 24 1E 03 B7 06 03 03 63 83 0E 06 95 06 +03 47 41 01 B3 37 F0 00 F2 07 33 37 E0 00 0E 07 +33 36 C0 00 D9 8F 52 06 D1 8F 37 27 02 30 D5 8F +1C C7 5C 47 05 47 93 F6 37 00 63 9A E6 00 37 26 +02 30 85 46 5C 46 13 F7 37 00 E3 0D D7 FE 89 8B +A1 C3 B7 07 02 50 03 A7 C7 07 89 47 63 EC E7 00 +B2 40 B7 27 02 30 09 47 98 C7 01 45 41 01 82 80 +85 06 79 BF 37 35 02 50 13 05 C5 24 EF 30 AF EA +B2 40 B7 27 02 30 09 47 98 C7 01 45 41 01 82 80 +37 35 02 50 13 05 05 28 EF 30 EF E8 05 45 EF 30 +8F E6 01 A0 41 11 83 4E 01 01 06 C6 37 2E 02 30 +03 23 CE 00 13 73 13 00 E3 1C 03 FE 23 2A AE 00 +23 2C BE 00 23 2E DE 00 23 20 EE 02 23 22 0E 03 +23 24 1E 03 B7 06 03 03 63 85 0E 06 95 06 03 47 +41 01 B3 37 F0 00 F2 07 33 37 E0 00 0E 07 33 36 +C0 00 D9 8F 52 06 D1 8F 37 27 02 30 D5 8F 1C C7 +5C 47 05 47 93 F6 37 00 63 9A E6 00 37 26 02 30 +85 46 5C 46 13 F7 37 00 E3 0D D7 FE 89 8B 99 CF +B7 07 02 50 03 A7 C7 07 89 47 63 EE E7 00 B7 27 +02 30 09 47 98 C7 05 45 EF 30 EF DC B2 40 41 01 +82 80 85 06 69 BF 37 35 02 50 13 05 C5 11 EF 30 +8F DD F1 BF 41 11 03 4F 01 01 83 4E 81 01 06 C6 +37 2E 02 30 03 23 CE 00 13 73 13 00 E3 1C 03 FE +23 2A AE 00 23 2C BE 00 23 2E DE 00 23 20 EE 02 +23 22 0E 03 23 24 1E 03 B7 06 03 03 63 04 0F 06 +95 06 03 47 41 01 B3 37 F0 00 F2 07 33 37 E0 00 +0E 07 33 36 C0 00 D9 8F 52 06 D1 8F 37 27 02 30 +D5 8F 1C C7 5C 47 05 47 93 F6 37 00 63 9A E6 00 +37 26 02 30 85 46 5C 46 13 F7 37 00 E3 0D D7 FE +89 8B 9D C3 63 84 0E 04 B7 07 02 50 03 A7 C7 07 +89 47 63 E2 E7 04 B7 27 02 30 09 47 98 C7 B2 40 +41 01 82 80 85 06 71 BF E3 8B 0E FE 37 35 02 50 +13 05 C5 18 EF 30 2F D2 B7 27 02 30 09 47 98 C7 +05 45 EF 30 4F CF B2 40 41 01 82 80 37 35 02 50 +13 05 C5 14 C5 B7 37 35 02 50 13 05 C5 14 EF 30 +8F CF 55 BF 83 4E 01 00 37 2E 02 30 03 23 CE 00 +13 73 13 00 E3 1C 03 FE 23 2A AE 00 23 2C BE 00 +23 2E DE 00 23 20 EE 02 23 22 0E 03 23 24 1E 03 +B7 06 03 03 63 85 0E 02 95 06 03 47 41 00 B3 37 +F0 00 33 36 C0 00 52 06 F2 07 33 37 E0 00 D1 8F +0E 07 D9 8F D5 8F 37 27 02 30 1C C7 82 80 85 06 +E9 BF B7 27 02 30 DC 47 41 11 22 C4 06 C6 05 47 +93 F6 37 00 2A 84 63 9A E6 00 37 26 02 30 85 46 +5C 46 13 F7 37 00 E3 0D D7 FE 89 8B 99 CF B7 07 +02 50 03 A7 C7 07 89 47 63 E2 E7 02 B7 27 02 30 +09 47 98 C7 05 45 EF 30 0F C3 09 C4 B7 07 02 30 +05 47 98 D3 B2 40 22 44 41 01 82 80 37 35 02 50 +13 05 C5 11 EF 30 2F C3 B7 27 02 30 09 47 98 C7 +05 45 EF 30 4F C0 D1 BF B7 27 02 30 DC 47 41 11 +22 C4 06 C6 05 47 93 F6 37 00 2A 84 63 9A E6 00 +37 26 02 30 85 46 5C 46 13 F7 37 00 E3 0D D7 FE +89 8B A9 C3 B7 07 02 50 03 A7 C7 07 89 47 63 EF +E7 00 B7 27 02 30 09 47 98 C7 09 C4 B7 07 02 30 +05 47 98 D3 B2 40 22 44 41 01 82 80 37 35 02 50 +13 05 C5 24 EF 30 2F BC B7 27 02 30 09 47 98 C7 +71 FC CD B7 37 35 02 50 13 05 05 28 EF 30 AF BA +05 45 EF 30 4F B8 01 A0 1D 71 A6 CA 86 CE A2 CC +CA C8 CE C6 D2 C4 D6 C2 DA C0 5E DE 62 DC 66 DA +6A D8 6E D6 95 47 AA 84 63 01 F5 22 C5 47 63 02 +F5 12 99 47 63 19 F5 2A 8D 47 B7 49 44 23 37 0B +03 03 37 0C 44 23 3E C6 3E CA 8D 09 05 49 A5 47 +63 97 F4 42 41 64 7D 14 37 0A 03 30 EF 00 50 5F +93 57 F5 41 C1 83 33 07 F5 00 61 8F 1D 8F 83 27 +8A 54 0D 07 93 7D C7 FF E3 82 FD FE 02 C4 02 CE +BD 47 CA 8C 4E 84 63 9E F4 22 CD 47 4D 4D 3E C8 +02 CC 93 8B 24 FF 93 BB 1B 00 13 99 2B 00 B7 09 +02 50 03 A6 C9 07 11 4A 63 63 CA 0E B7 35 02 30 +83 A7 85 80 B7 26 02 30 F9 9B 23 A4 F5 80 DC 46 +85 8B F5 FF 89 47 63 E3 C7 0A B7 27 02 30 23 AA +87 01 22 47 85 46 94 CF C0 CF 23 A0 97 03 33 69 +27 01 23 A2 B7 03 33 67 69 01 23 A4 A7 03 13 67 +17 00 98 C7 DC 47 13 F7 37 00 63 19 D7 00 37 26 +02 30 5C 46 13 F7 37 00 E3 0D D7 FE 89 8B B5 C7 +03 A7 C9 07 89 47 63 EF E7 18 B7 27 02 30 09 47 +98 C7 37 37 02 30 83 27 87 80 F6 40 66 44 93 E7 +17 00 23 24 F7 80 D6 44 46 49 B6 49 26 4A 96 4A +06 4B F2 5B 62 5C D2 5C 42 5D B2 5D 01 45 25 61 +82 80 85 47 41 6B 3E C6 02 CA 91 69 01 49 02 C4 +37 0C 44 23 02 CE 93 0D 00 04 19 BF 37 35 02 50 +13 05 85 2D EF 30 2F A3 89 BF 37 35 02 50 13 05 +05 28 EF 30 4F A2 05 45 EF 30 EF 9F 01 A0 C5 6A +93 8A 4A AC A6 85 13 85 4A 41 EF 30 CF A2 03 A6 +C9 07 E3 75 CA F0 62 86 85 45 13 85 CA 42 EF 30 +8F A1 03 A6 C9 07 E3 7B CA EE 22 86 E6 85 13 85 +CA 44 EF 30 4F A0 03 A6 C9 07 E3 71 CA EE B2 45 +13 85 CA 46 EF 30 2F 9F 03 A6 C9 07 E3 78 CA EC +D2 45 13 85 4A 48 EF 30 0F 9E 03 A6 C9 07 E3 7F +CA EA F2 45 13 85 CA 49 EF 30 EF 9C 03 A6 C9 07 +E3 76 CA EA E2 45 13 85 4A 4B EF 30 CF 9B 03 A6 +C9 07 E3 7D CA E8 DE 85 13 85 CA 4C EF 30 AF 9A +03 A6 C9 07 E3 74 CA E8 EE 85 13 85 4A 4E EF 30 +8F 99 03 A6 C9 07 E3 7B CA E6 C2 45 13 85 CA 4F +EF 30 6F 98 03 A6 C9 07 95 B5 B7 07 03 30 03 A9 +47 54 83 A9 07 54 37 0C 44 23 8D 47 CA 8C 4E 84 +0D 0C 37 0B 03 00 3E C6 89 47 63 F6 97 1E 13 87 +D4 FF 85 47 B3 97 E7 00 93 F7 17 4D 3E CA 63 9F +07 1C AD 47 63 86 F4 22 91 47 63 8E F4 18 37 07 +00 03 B9 47 33 6B EB 00 63 99 F4 20 EF 00 50 3B +B7 07 10 00 3E C4 8D 47 3E CA 85 47 3E CE 93 0D +00 04 F9 B3 37 35 02 50 13 05 C5 24 EF 30 AF 8E +A9 BD 02 CC C1 47 63 8A F4 00 91 47 63 92 F4 18 +11 49 01 4D 02 C8 85 4B D9 B3 91 47 11 49 11 4D +3E C8 85 4B 6D BB 9D 47 63 1A F5 04 B7 07 03 30 +03 AA 47 54 03 A4 07 54 EF 00 90 35 2A 89 EF 00 +30 35 93 57 F5 41 13 57 E5 01 8A 07 0A 09 D9 8F +0A 05 AA 89 33 69 F9 00 63 14 A4 00 E3 0E 2A FD +CA 8C 2A 84 C5 47 63 EB 97 10 37 07 02 50 93 97 +24 00 13 07 47 5D BA 97 9C 43 82 87 B7 07 03 30 +83 AC 47 54 83 A9 07 54 AD 47 66 89 4E 84 63 12 +F5 02 B7 07 10 00 3E C4 89 47 3E CA 85 47 37 0B +00 02 37 0C 44 23 02 C6 3E CE 02 CC 93 0D 00 04 +91 BF 09 47 89 47 3A C6 3A CA 37 0B 02 02 E3 00 +F5 DE 4D B7 37 0C 44 23 01 4B 02 C6 F1 BD EF 00 +30 2C 8D 47 B3 67 F5 02 91 46 37 0C 44 23 37 07 +00 04 36 CA 85 07 3E C6 13 9B 07 01 33 6B EB 00 +93 87 44 FF 05 47 63 68 F7 06 B7 07 00 10 33 6B +FB 00 85 47 02 C4 01 4D 02 C8 3E CC 93 0D 00 04 +02 CE C1 B1 89 47 02 C4 37 0B 02 00 37 0C 44 23 +3E C6 02 CA 02 CE 93 0D 00 04 59 B9 85 47 41 6B +37 0C 44 23 3E C6 02 CA 99 B9 89 47 3E C6 85 47 +37 0B 02 10 02 C4 37 0C 44 23 02 CA 02 CE 3E CC +93 0D 00 04 45 BD 91 47 37 0B 00 04 37 0C 44 23 +3E CA 02 C6 05 B9 A1 47 E3 93 F4 C2 02 C4 01 4D +02 C8 02 CC 93 0D 30 04 02 CE A1 B9 B5 47 37 0C +44 23 37 0B 03 00 63 EF 97 04 8D 47 3E C6 29 BD +01 4D 02 C8 3D B9 85 47 63 89 F4 00 B7 07 00 04 +33 6B FB 00 91 47 3E CA A1 B7 EF 00 70 1E AD 47 +B3 67 F5 02 95 07 3E CA 13 97 87 01 05 BF 02 C4 +02 CE A9 47 E3 95 F4 E2 B7 07 03 30 03 A7 87 54 +CA 8C 4E 84 93 1D 07 01 93 DD 0D 01 01 4D 02 C8 +02 CC C5 BE 8D 47 3E C6 DD B3 8D 47 3E CA 09 B7 +B7 07 00 02 33 6B FB 00 B7 07 10 00 3E C4 89 47 +3E CA 85 47 3E CE 75 BF B7 27 02 30 DC 47 41 11 +22 C4 06 C6 93 F6 37 00 05 47 2A 84 63 9A E6 00 +37 26 02 30 85 46 5C 46 13 F7 37 00 E3 0D D7 FE +89 8B 95 C7 A1 C5 B7 07 02 50 03 A7 C7 07 89 47 +63 E3 E7 04 B7 27 02 30 09 47 98 C7 09 C4 B7 07 +02 30 05 47 98 D3 B2 40 22 44 41 01 82 80 FD D5 +37 35 02 50 13 05 C5 18 EF 20 FF E7 B7 27 02 30 +09 47 98 C7 05 45 EF 20 1F E5 C9 BF 37 35 02 50 +13 05 C5 14 D5 B7 37 35 02 50 13 05 C5 14 EF 20 +9F E5 4D BF 53 4F 43 5F 49 46 43 3A 20 43 6C 65 +61 72 20 65 78 65 63 75 74 65 20 72 65 67 00 00 +53 4F 43 5F 49 46 43 3A 20 43 68 65 63 6B 20 6D +62 6F 78 5F 73 74 61 74 75 73 2E 6D 62 6F 78 5F +66 73 6D 5F 70 73 20 66 6F 75 6E 64 20 75 6E 65 +78 70 65 63 74 65 64 20 73 74 61 74 65 20 30 78 +25 78 0A 00 53 4F 43 5F 49 46 43 3A 20 53 65 74 +20 6D 62 6F 78 5F 73 74 61 74 75 73 20 66 69 65 +6C 64 3A 20 30 78 25 78 0A 00 00 00 53 4F 43 5F +49 46 43 3A 20 53 65 74 20 66 6C 6F 77 5F 73 74 +61 74 75 73 20 66 69 65 6C 64 3A 20 30 78 25 78 +0A 00 00 00 53 4F 43 5F 49 46 43 3A 20 43 6C 65 +61 72 20 53 48 41 20 61 63 63 65 6C 65 72 61 74 +6F 72 20 6C 6F 63 6B 20 62 79 20 77 72 69 74 69 +6E 67 20 27 31 3A 20 30 78 25 78 0A 00 00 00 00 +53 4F 43 5F 49 46 43 3A 20 42 61 64 20 66 69 65 +6C 64 20 76 61 6C 75 65 00 00 00 00 53 4F 43 5F +49 46 43 3A 20 42 61 64 20 66 69 65 6C 64 20 76 +61 6C 75 65 00 00 00 00 53 4F 43 5F 49 46 43 3A +20 43 6C 65 61 72 20 66 6C 6F 77 5F 73 74 61 74 +75 73 20 66 69 65 6C 64 3A 20 30 78 25 78 0A 00 +53 4F 43 5F 49 46 43 3A 20 43 4D 44 20 66 72 6F +6D 20 6D 61 69 6C 62 6F 78 3A 20 30 78 25 78 0A +00 00 00 00 53 4F 43 5F 49 46 43 3A 20 44 4C 45 +4E 20 66 72 6F 6D 20 6D 61 69 6C 62 6F 78 3A 20 +30 78 25 78 0A 00 00 00 46 41 54 41 4C 3A 20 49 +6E 76 61 6C 69 64 20 64 6C 65 6E 20 70 61 73 73 +65 64 20 74 6F 20 6D 62 6F 78 20 66 77 20 66 6C +6F 77 3A 20 30 78 25 78 0A 00 00 00 46 41 54 41 +4C 3A 20 49 6E 76 61 6C 69 64 20 63 6D 64 20 70 +61 73 73 65 64 20 74 6F 20 6D 62 6F 78 20 66 77 +20 66 6C 6F 77 3A 20 30 78 25 78 0A 00 00 00 00 +46 6F 75 6E 64 20 69 6E 76 61 6C 69 64 20 69 63 +63 6D 20 73 69 7A 65 20 69 6E 20 66 69 72 6D 77 +61 72 65 20 69 6D 61 67 65 20 72 65 63 65 69 76 +65 64 20 66 72 6F 6D 20 53 4F 43 21 20 4D 61 78 +20 65 78 70 65 63 74 65 64 20 30 78 25 78 2C 20 +67 6F 74 20 30 78 25 78 0A 00 00 00 46 6F 75 6E +64 20 69 6E 76 61 6C 69 64 20 64 63 63 6D 20 73 +69 7A 65 20 69 6E 20 66 69 72 6D 77 61 72 65 20 +69 6D 61 67 65 20 72 65 63 65 69 76 65 64 20 66 +72 6F 6D 20 53 4F 43 21 20 4D 61 78 20 65 78 70 +65 63 74 65 64 20 30 78 25 78 2C 20 67 6F 74 20 +30 78 25 78 0A 00 00 00 61 74 20 25 78 3A 20 25 +78 0A 00 00 53 4F 43 5F 49 46 43 3A 20 49 6C 6C +65 67 61 6C 20 62 79 74 65 5F 63 6F 75 6E 74 20 +30 78 25 78 0A 00 00 00 53 4F 43 5F 49 46 43 3A +20 53 65 74 20 66 77 20 75 70 64 61 74 65 20 72 +65 73 65 74 20 77 69 74 68 20 77 61 69 74 5F 63 +79 63 6C 65 73 20 5B 25 64 5D 20 28 25 73 29 0A +00 00 00 00 73 72 63 5F 61 64 64 72 20 30 78 25 +78 20 69 73 20 6F 75 74 20 6F 66 20 62 6F 75 6E +64 73 20 66 6F 72 20 6D 62 6F 78 20 73 70 61 6E +21 0A 00 00 72 65 61 64 69 6E 67 20 30 78 25 78 +20 62 79 74 65 73 20 66 72 6F 6D 20 73 72 63 5F +61 64 64 72 20 30 78 25 78 20 67 6F 65 73 20 6F +75 74 20 6F 66 20 62 6F 75 6E 64 73 20 66 6F 72 +20 6D 62 6F 78 20 73 70 61 6E 21 0A 00 00 00 00 +64 73 74 5F 61 64 64 72 20 30 78 25 78 20 69 73 +20 6F 75 74 20 6F 66 20 62 6F 75 6E 64 73 20 66 +6F 72 20 6D 62 6F 78 20 73 70 61 6E 21 0A 00 00 +77 72 69 74 69 6E 67 20 30 78 25 78 20 62 79 74 +65 73 20 74 6F 20 64 73 74 5F 61 64 64 72 20 30 +78 25 78 20 67 6F 65 73 20 6F 75 74 20 6F 66 20 +62 6F 75 6E 64 73 20 66 6F 72 20 6D 62 6F 78 20 +73 70 61 6E 21 0A 00 00 70 61 72 61 6D 3A 20 65 +72 72 5F 74 79 70 65 20 20 20 30 78 25 78 0A 00 +70 61 72 61 6D 3A 20 73 72 63 5F 61 64 64 72 20 +20 20 30 78 25 78 20 30 78 25 78 0A 00 00 00 00 +70 61 72 61 6D 3A 20 64 73 74 5F 61 64 64 72 20 +20 20 30 78 25 78 20 30 78 25 78 0A 00 00 00 00 +70 61 72 61 6D 3A 20 72 64 5F 72 6F 75 74 65 20 +20 20 30 78 25 78 0A 00 70 61 72 61 6D 3A 20 77 +72 5F 72 6F 75 74 65 20 20 20 30 78 25 78 0A 00 +70 61 72 61 6D 3A 20 72 64 5F 66 69 78 65 64 20 +20 20 30 78 25 78 0A 00 70 61 72 61 6D 3A 20 77 +72 5F 66 69 78 65 64 20 20 20 30 78 25 78 0A 00 +70 61 72 61 6D 3A 20 61 65 73 5F 6D 6F 64 65 20 +20 20 30 78 25 78 0A 00 70 61 72 61 6D 3A 20 62 +79 74 65 5F 63 6F 75 6E 74 20 30 78 25 78 0A 00 +70 61 72 61 6D 3A 20 62 6C 6F 63 6B 5F 73 69 7A +65 20 30 78 25 78 0A 00 B7 06 02 50 83 A7 C6 61 +13 97 D7 00 3D 8F 93 57 17 01 B9 8F 13 95 57 00 +3D 8D 23 AE A6 60 82 80 B7 07 02 50 03 A7 C7 07 +41 11 22 C4 26 C2 06 C6 89 47 AA 84 2E 84 63 E3 +E7 02 73 50 20 7D 73 90 34 7D 73 D0 41 7D 73 10 +44 30 73 50 04 30 73 D0 61 7C B2 40 22 44 92 44 +41 01 82 80 37 35 02 50 13 05 C5 2E EF 20 BF 8D +C9 BF 73 50 20 7D 73 10 35 7D 73 D0 41 7D 73 90 +45 30 73 50 04 30 82 80 73 D0 61 7C 82 80 B7 07 +03 30 23 A6 A7 0E 23 A8 B7 0E 82 80 B7 07 03 30 +23 AE A7 0E 23 A0 B7 10 82 80 B7 07 03 30 7D 57 +23 A6 E7 0E 23 A8 E7 0E 82 80 B7 07 03 30 7D 57 +23 AE E7 0E 23 A0 E7 10 82 80 37 17 03 30 83 27 +47 81 93 F7 07 04 E5 DF 93 07 00 04 23 2A F7 80 +82 80 37 17 03 30 83 27 47 81 93 F7 07 08 E5 DF +93 07 00 08 23 2A F7 80 82 80 B7 07 03 30 23 A6 +A7 0E 23 A8 B7 0E 23 AE C7 0E 23 A0 D7 10 05 47 +23 A2 E7 0E 23 A4 E7 0E 82 80 01 11 06 CE 0D E1 +B7 07 02 50 03 A7 C7 07 89 47 63 E2 E7 08 B7 07 +03 30 23 A2 07 0E 23 AA 07 0E F2 40 05 61 82 80 +85 47 63 01 F5 04 89 47 E3 19 F5 FE B7 07 02 50 +83 A7 C7 07 63 6F F5 06 B7 07 03 30 23 A6 B7 0E +23 A8 C7 0E 23 AE D7 0E 23 A0 E7 10 05 47 23 A2 +E7 0E 23 AA E7 0E F2 40 23 A4 E7 0E 23 AC E7 0E +05 61 82 80 B7 07 02 50 03 A6 C7 07 89 47 63 E7 +C7 02 B7 07 03 30 23 AE D7 0E 23 A0 E7 10 F2 40 +05 47 23 AA E7 0E 23 AC E7 0E 05 61 82 80 37 35 +02 50 13 05 45 30 EF 20 0F F9 95 BF 37 35 02 50 +13 05 05 33 3A C2 36 C0 EF 20 EF F7 12 47 82 46 +C9 B7 37 35 02 50 13 05 C5 35 3A C6 36 C4 32 C2 +2E C0 EF 20 4F F6 32 47 A2 46 12 46 82 45 AD B7 +B3 47 B5 00 8D 8B B3 08 C5 00 B1 E7 8D 47 63 F4 +C7 04 93 77 35 00 2A 87 B9 EB 13 F6 C8 FF B3 06 +E6 40 93 07 00 02 63 C8 D7 06 AE 86 BA 87 63 71 +C7 02 03 A8 06 00 91 07 91 06 23 AE 07 FF E3 EA +C7 FE 93 07 F6 FF 99 8F F1 9B 91 07 3E 97 BE 95 +63 66 17 01 82 80 2A 87 63 7E 15 03 83 C7 05 00 +05 07 85 05 A3 0F F7 FE E3 9A E8 FE 82 80 83 C6 +05 00 05 07 93 77 37 00 A3 0F D7 FE 85 05 D1 DF +83 C6 05 00 05 07 93 77 37 00 A3 0F D7 FE 85 05 +F9 FF 61 B7 82 80 41 11 22 C6 13 04 00 02 83 A3 +05 00 83 A2 45 00 83 AF 85 00 03 AF C5 00 83 AE +05 01 03 AE 45 01 03 A3 85 01 03 A8 C5 01 94 51 +13 07 47 02 B3 07 E6 40 23 2E 77 FC 23 20 57 FE +23 22 F7 FF 23 24 E7 FF 23 26 D7 FF 23 28 C7 FF +23 2A 67 FE 23 2C 07 FF 23 2E D7 FE 93 85 45 02 +E3 47 F4 FA AE 86 BA 87 63 71 C7 02 03 A8 06 00 +91 07 91 06 23 AE 07 FF E3 EA C7 FE 93 07 F6 FF +99 8F F1 9B 91 07 3E 97 BE 95 63 65 17 01 32 44 +41 01 82 80 83 C7 05 00 05 07 85 05 A3 0F F7 FE +E3 87 E8 FE 83 C7 05 00 05 07 85 05 A3 0F F7 FE +E3 92 E8 FE E9 BF 3D 43 2A 87 63 73 C3 02 93 77 +F7 00 BD EF AD E5 93 76 06 FF 3D 8A BA 96 0C C3 +4C C3 0C C7 4C C7 41 07 E3 6B D7 FE 11 E2 82 80 +B3 06 C3 40 8A 06 97 02 00 00 96 96 67 80 A6 00 +23 07 B7 00 A3 06 B7 00 23 06 B7 00 A3 05 B7 00 +23 05 B7 00 A3 04 B7 00 23 04 B7 00 A3 03 B7 00 +23 03 B7 00 A3 02 B7 00 23 02 B7 00 A3 01 B7 00 +23 01 B7 00 A3 00 B7 00 23 00 B7 00 82 80 93 F5 +F5 0F 93 96 85 00 D5 8D 93 96 05 01 D5 8D 61 B7 +93 96 27 00 97 02 00 00 96 96 86 82 E7 80 86 FA +96 80 C1 17 1D 8F 3E 96 E3 74 C3 F8 A5 B7 B7 37 +02 50 83 A7 C7 38 23 A4 A7 0A 23 A6 07 0A 82 80 +B7 37 02 50 03 A8 C7 38 B7 85 95 4C 93 85 D5 F2 +83 26 88 0A 03 27 C8 0A B3 87 B6 02 13 86 17 00 +B3 37 F6 00 23 24 C8 0A 37 F6 51 58 13 06 D6 42 +33 86 C6 02 33 07 B7 02 B3 B6 B6 02 32 97 36 97 +BA 97 13 95 17 00 23 26 F8 0A 05 81 82 80 93 77 +35 00 2A 87 9D EF B7 86 7F 7F 93 86 F6 F7 FD 55 +10 43 11 07 B3 77 D6 00 B6 97 D1 8F D5 8F E3 89 +B7 FE 83 46 C7 FF B3 07 A7 40 8D CA 83 46 D7 FF +9D C2 03 45 E7 FF 33 35 A0 00 3E 95 79 15 82 80 +F9 D2 83 47 07 00 05 07 93 76 37 00 F5 FB 09 8F +13 05 F7 FF 82 80 13 85 D7 FF 82 80 13 85 C7 FF +82 80 13 01 01 BC 23 2A 91 42 23 28 21 43 23 20 +61 43 23 2C 81 41 23 2E 11 42 23 2C 81 42 23 26 +31 43 23 24 41 43 23 22 51 43 23 2E 71 41 23 2A +91 41 23 28 A1 41 23 26 B1 41 85 47 36 8B 2A 89 +2E 8C B2 84 63 F1 D7 2E 01 46 85 4C 85 46 FD 5B +09 A8 B3 8C 77 41 3E 86 85 46 B3 07 D6 00 63 F7 +67 03 33 87 74 01 36 97 B3 85 F4 00 83 C5 05 00 +03 47 07 00 E3 EF E5 FC 63 86 E5 14 B2 8B 85 46 +05 06 B3 07 D6 00 85 4C E3 ED 67 FD 81 45 05 48 +05 46 7D 55 05 47 09 A8 33 08 A7 40 BA 85 05 46 +33 87 C5 00 63 77 67 03 B3 87 C4 00 B3 86 E4 00 +AA 97 83 C6 06 00 83 C7 07 00 E3 EF D7 FC 63 87 +D7 10 2E 85 05 46 85 05 33 87 C5 00 05 48 E3 6D +67 FD 05 05 85 0B 63 64 75 01 C2 8C AA 8B 8A 87 +13 07 01 40 23 A0 67 01 91 07 E3 9D E7 FE 63 05 +0B 02 13 06 FB FF B3 05 9B 00 26 87 26 96 83 47 +07 00 B3 06 E6 40 05 07 8A 07 93 87 07 40 8A 97 +23 A0 D7 C0 E3 95 E5 FE 5E 86 B3 85 94 01 26 85 +C9 26 63 1F 05 10 85 69 93 89 09 80 05 4A 81 4D +01 44 B3 06 6C 41 B3 69 3B 01 13 0D FB FF 33 0A +7A 41 B3 0A 9B 41 63 E8 86 02 33 06 89 00 B3 07 +A6 01 83 C7 07 00 8A 07 93 87 07 40 8A 97 83 A7 +07 C0 AD CB 63 85 0D 00 63 F3 97 01 D6 87 3E 94 +81 4D E3 FC 86 FC 33 05 89 01 CE 85 6D 21 2A 9C +B3 06 6C 41 E3 F3 86 FC 01 45 83 20 C1 43 03 24 +81 43 83 24 41 43 03 29 01 43 83 29 C1 42 03 2A +81 42 83 2A 41 42 03 2B 01 42 83 2B C1 41 03 2C +81 41 83 2C 41 41 03 2D 01 41 83 2D C1 40 13 01 +01 44 82 80 63 8A 96 15 85 06 41 BD 63 03 C8 14 +05 06 F9 B5 6E 87 63 F3 7D 01 5E 87 63 70 A7 03 +B3 07 E4 00 33 88 E4 00 CA 97 03 45 08 00 83 C7 +07 00 63 11 F5 04 05 07 E3 64 A7 FF 13 87 FB FF +63 E6 7D 01 39 AA 63 81 ED 02 2A 87 B3 07 E4 00 +B3 85 E4 00 CA 97 83 C5 05 00 83 C7 07 00 13 05 +F7 FF E3 82 F5 FE 05 07 85 0D 63 6A B7 0F 66 94 +D6 8D 11 BF E3 74 A7 FD 52 94 3A 94 81 4D 21 B7 +33 0A 7B 41 63 65 7A 0D 05 64 13 04 04 80 85 49 +05 0A 81 4A B3 06 6C 41 33 64 8B 00 93 0C FB FF +B3 89 79 41 7D 5D 63 E2 56 03 33 05 59 01 B3 07 +95 01 83 C7 07 00 8A 07 93 87 07 40 8A 97 83 A7 +07 C0 95 CB BE 9A E3 F2 56 FF 33 05 89 01 A2 85 +59 2E 2A 9C B3 06 6C 41 E3 E8 56 EF 33 05 59 01 +B3 07 95 01 83 C7 07 00 8A 07 93 87 07 40 8A 97 +83 A7 07 C0 E1 FB 5E 87 63 E6 9B 01 25 A0 05 07 +63 72 97 03 B3 07 57 01 B3 85 E4 00 CA 97 03 C6 +05 00 83 C7 07 00 E3 04 F6 FE 63 75 97 01 CE 9A +BA 9A 51 B7 93 87 FB FF 63 95 A7 01 79 BD E3 8E +A7 E9 33 87 FA 00 33 86 F4 00 4A 97 03 46 06 00 +03 47 07 00 FD 17 E3 04 E6 FE D2 9A A9 BF 5E 8A +25 BF C2 95 05 46 69 B3 36 96 85 46 3D BB 32 85 +AD B5 5E 87 11 B7 85 4C 81 4B 55 BB 1D 71 A2 CC +A6 CA 86 CE CA C8 CE C6 D2 C4 AE 84 83 C5 05 00 +2A 84 E1 C1 03 C6 14 00 63 0E 06 12 03 C7 24 00 +71 C3 03 C5 34 00 63 02 05 14 83 C7 44 00 E1 CF +26 85 EF F0 DF C3 2A 89 93 65 05 20 22 85 65 2C +63 6A 25 0F 93 07 E0 0F 63 E8 27 15 B3 09 25 41 +13 06 00 04 93 05 19 00 0A 85 A2 99 EF F0 BF B0 +63 06 09 02 13 76 F9 0F 26 87 B3 05 99 00 26 96 +83 47 07 00 B3 06 E6 40 05 07 93 F7 F7 03 93 87 +07 04 8A 97 23 80 D7 FC E3 94 E5 FE 7D 14 B3 07 +24 01 83 C7 07 00 93 F7 F7 03 93 87 07 04 8A 97 +83 C7 07 FC 3E 94 63 F6 89 00 79 A0 52 94 63 E5 +89 08 B3 07 24 01 83 C7 07 00 22 85 4A 86 93 F7 +F7 03 93 87 07 04 8A 97 A6 85 03 CA 07 FC D5 20 +71 FD F6 40 22 85 66 44 D6 44 46 49 B6 49 26 4A +25 61 82 80 03 47 05 00 C2 05 D1 8D 81 47 39 C3 +C2 07 A2 86 D9 8F 05 04 03 47 04 00 E3 99 F5 FE +13 84 F6 FF F9 B7 93 97 85 01 42 06 83 46 04 00 +D1 8F C9 8F 22 07 D9 8F 91 CE 01 47 19 A0 63 83 +E7 04 22 86 22 07 05 04 55 8F 83 46 04 00 E5 FA +63 8A E7 02 01 44 71 BF 33 85 29 01 83 47 05 00 +F5 DB 85 65 93 85 05 80 7D 22 AA 99 E3 F0 89 F4 +01 44 41 B7 66 44 F6 40 D6 44 46 49 B6 49 26 4A +25 61 4D A0 13 04 D6 FF AD B7 83 46 04 00 93 97 +85 01 42 06 D1 8F 22 07 D9 8F CD DE 01 47 11 A0 +D5 DA 55 8F 22 86 22 07 05 04 83 46 04 00 E3 19 +F7 FE 13 04 E6 FF 35 BF AA 85 22 85 66 44 F6 40 +B6 49 26 4A CA 86 26 86 46 49 D6 44 25 61 6F F0 +5F B2 8D 47 63 F3 C7 02 B3 67 B5 00 8D 8B 8D 46 +89 CB 93 06 F6 FF 29 A8 71 16 11 05 91 05 63 F6 +C6 00 18 41 9C 41 E3 09 F7 FE 93 06 F6 FF 0D C2 +85 06 AE 96 19 A0 63 8D D5 00 83 47 05 00 03 C7 +05 00 05 05 85 05 E3 88 E7 FE 33 85 E7 40 82 80 +01 45 82 80 93 F6 F5 0F 93 77 35 00 C1 CE 91 CB +83 47 05 00 D1 C7 63 86 D7 08 05 05 93 77 35 00 +E5 FB 93 F5 F5 0F 93 97 85 00 AE 97 18 41 13 93 +07 01 33 63 F3 00 37 08 FF FE 33 46 E3 00 13 08 +F8 EF B3 07 07 01 B3 05 06 01 13 47 F7 FF 13 46 +F6 FF F9 8F B7 88 80 80 33 F7 C5 00 D9 8F 93 88 +08 08 B3 F7 17 01 85 E7 58 41 11 05 33 46 67 00 +B3 07 07 01 B3 05 06 01 13 47 F7 FF 13 46 F6 FF +F9 8F 33 F7 C5 00 D9 8F B3 F7 17 01 F1 DF 83 47 +05 00 99 C7 63 80 F6 06 83 47 15 00 05 05 FD FB +01 45 82 80 81 CB 83 47 05 00 E5 DF 05 05 93 77 +35 00 F5 FB 18 41 37 06 FF FE 13 06 F6 EF 93 47 +F7 FF B7 86 80 80 32 97 F9 8F 93 86 06 08 F5 8F +91 EB 58 41 11 05 B3 07 C7 00 13 47 F7 FF F9 8F +F5 8F E5 DB 83 47 05 00 CD DF 83 47 15 00 05 05 +ED FF 82 80 82 80 B3 06 B5 00 AA 87 89 E5 29 A8 +85 07 63 88 F6 00 03 C7 07 00 7D FB 33 85 A7 40 +82 80 33 85 A6 40 82 80 01 45 82 80 +@00011AE4 +78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 +78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 +78 78 78 78 78 78 78 78 0A 20 20 20 54 52 41 50 +20 56 45 43 54 4F 52 20 45 58 45 43 55 54 49 4E +47 21 20 4B 49 4C 4C 20 53 49 4D 21 21 21 20 20 +20 0A 78 78 78 78 78 78 78 78 78 78 78 78 78 78 +78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 +78 78 78 78 78 78 78 78 78 78 0A 00 03 00 00 00 +CC 00 03 30 C4 34 00 00 1E 34 00 00 1E 34 00 00 +1E 34 00 00 1E 34 00 00 1E 34 00 00 1E 34 00 00 +1E 34 00 00 1E 34 00 00 1E 34 00 00 1E 34 00 00 +04 36 00 00 90 35 00 00 1E 34 00 00 1E 34 00 00 +1E 34 00 00 1E 34 00 00 1E 34 00 00 1E 34 00 00 +1E 34 00 00 1E 34 00 00 1E 34 00 00 1E 34 00 00 +6C 35 00 00 1E 34 00 00 1E 34 00 00 1E 34 00 00 +44 35 00 00 1E 34 00 00 E8 34 00 00 1E 34 00 00 +1E 34 00 00 C4 34 00 00 06 2C 4C C7 74 E2 13 BE +68 66 3B C0 E9 33 78 7E E2 CA AE 3A FA 44 3E E6 +7D EF AA 89 12 1C A2 61 73 6E 6E BB B8 60 9D 35 +68 E6 B7 23 C9 BC 33 0F 0C A0 0E CA 39 65 91 72 +B4 73 B9 36 2D D3 3C A5 BC 62 30 95 82 3D AF E1 +90 99 83 14 FE DB AC 42 58 39 50 63 23 45 64 53 +21 23 AD FC EF DA 23 44 77 F2 81 7A 9E 46 51 52 +25 55 33 2B 89 FC C5 99 0E D7 54 FD 2B F3 47 F7 +6F D4 E1 B8 52 CD AC 30 36 BE C1 6B F9 34 7B D2 +68 1F 02 09 3A 31 B8 A6 83 C6 4C 93 A6 FF 43 D5 +7D C5 9C 8A AB 63 5B AC F0 A5 EB 3C 5D 1F 06 22 +D3 E1 2C B7 6E 4B D9 B4 DD 34 5B A3 53 5C 16 A9 +EB 0D 31 CB 2F 6D 8D BE DC 28 CA 92 11 56 3C 29 +39 B4 39 82 8A 8B 2C 5B 2E 88 25 3D C7 1D C1 3E +D2 28 F2 9D A5 D5 5A 7A CA A1 E4 24 C3 1D D2 5C +0A AC 3A A8 6C EB C5 F3 42 D7 C3 77 A6 8A 47 AF +ED 07 7E 39 C6 35 62 2D 29 28 6E A8 B9 EE 60 EE +F3 FA 21 2F 02 47 C8 90 38 E0 8E F9 52 AA C5 8D +22 3C 65 C2 BC C6 11 69 23 86 AB D4 6D 5C 73 42 +D4 AA BF 1A 6F 0B 04 B8 A5 A1 E4 C2 71 F7 0E E1 +76 B1 CD F8 2A D5 5F 56 18 90 CC 73 77 04 61 2D +34 49 A1 79 BD D4 16 BE B4 B6 1A A7 2B E9 73 60 +37 67 AC 66 F1 E0 35 E8 23 A4 2C 63 43 E0 15 82 +63 7C 05 32 5E B0 1C 18 48 C7 09 1F 8B EC 3C 8A +AD EA 25 CE F2 C4 EB B3 0D EA 0F D3 A6 61 0D 88 +23 F3 BA 8E 77 F0 19 8B 3F 84 A6 22 D2 38 50 36 +D3 7D A0 D3 6A 1B AF 6C E1 C4 60 F0 6F A4 7A 18 +EA 69 CD C3 E0 22 B5 BC 8A 3B FA B6 78 70 18 9C +8E 17 3B 0C E6 FB 90 4E 7E 36 76 97 2B FF 37 87 +F4 A3 A6 E1 C2 2B 6C 4E 18 6B 3A F9 07 CD 14 0A +85 04 FD E7 C5 15 3A DA D0 25 02 50 00 C0 01 10 +0A 00 00 00 01 00 00 00 00 00 00 00 E4 25 02 50 +28 C0 01 10 0C 00 00 00 FF FF FF FF 00 00 00 00 +00 26 02 50 58 C0 01 10 0C 00 00 00 FF FF FF FF +00 00 00 00 1C 26 02 50 88 C0 01 10 0C 00 00 00 +FF FF FF FF 00 00 00 00 38 26 02 50 B8 C0 01 10 +0C 00 00 00 FF FF FF FF 00 00 00 00 54 26 02 50 +E8 C0 01 10 0C 00 00 00 FF FF FF FF 00 00 00 00 +70 26 02 50 18 C1 01 10 0C 00 00 00 FF FF FF FF +00 00 00 00 8C 26 02 50 48 C1 01 10 0C 00 00 00 +FF FF FF FF 00 00 00 00 A8 26 02 50 78 C1 01 10 +0C 00 00 00 FF FF FF FF 00 00 00 00 C4 26 02 50 +A8 C1 01 10 0C 00 00 00 FF FF FF FF 00 00 00 00 +E0 26 02 50 D8 C1 01 10 0C 00 00 00 FF FF FF FF +00 00 00 00 FC 26 02 50 08 C2 01 10 0A 00 00 00 +00 00 00 00 00 00 00 00 0C 27 02 50 30 C2 01 10 +0C 00 00 00 FF FF FF FF 00 00 00 00 20 27 02 50 +60 C2 01 10 0C 00 00 00 FF FF FF FF 00 00 00 00 +34 27 02 50 90 C2 01 10 0C 00 00 00 FF FF FF FF +00 00 00 00 48 27 02 50 C0 C2 01 10 0C 00 00 00 +FF FF FF FF 00 00 00 00 5C 27 02 50 F0 C2 01 10 +0C 00 00 00 FF FF FF FF 00 00 00 00 70 27 02 50 +20 C3 01 10 0C 00 00 00 FF FF FF FF 00 00 00 00 +84 27 02 50 50 C3 01 10 0C 00 00 00 FF FF FF FF +00 00 00 00 98 27 02 50 80 C3 01 10 0C 00 00 00 +FF FF FF FF 00 00 00 00 AC 27 02 50 B0 C3 01 10 +0C 00 00 00 FF FF FF FF 00 00 00 00 C0 27 02 50 +E0 C3 01 10 0C 00 00 00 FF FF FF FF 00 00 00 00 +D4 27 02 50 10 C4 01 10 0A 00 00 00 00 00 00 00 +00 00 00 00 F0 27 02 50 38 C4 01 10 0A 00 00 00 +FF FF FF FF 00 00 00 00 04 28 02 50 60 C4 01 10 +08 00 00 00 00 00 00 00 00 00 00 00 24 28 02 50 +80 C4 01 10 08 00 00 00 01 00 00 00 00 00 00 00 +44 28 02 50 A0 C4 01 10 08 00 00 00 FF FF FF FF +00 00 00 00 00 00 00 00 00 00 00 00 0C 00 00 00 +01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00 +05 00 00 00 06 00 00 00 07 00 00 00 08 00 00 00 +09 00 00 00 0A 00 00 00 0B 00 00 00 01 00 00 00 +0C 00 00 00 0C 00 00 00 0D 00 00 00 0E 00 00 00 +0F 00 00 00 10 00 00 00 11 00 00 00 12 00 00 00 +13 00 00 00 14 00 00 00 15 00 00 00 16 00 00 00 +03 00 00 00 01 00 00 00 17 00 00 00 17 00 00 00 +17 00 00 00 17 00 00 00 17 00 00 00 17 00 00 00 +17 00 00 00 17 00 00 00 17 00 00 00 17 00 00 00 +19 00 00 00 02 00 00 00 01 00 00 00 1A 00 00 00 +1A 00 00 00 1A 00 00 00 1A 00 00 00 1A 00 00 00 +1A 00 00 00 1A 00 00 00 1A 00 00 00 FF FF FF FF +FF FF FF FF F4 08 01 00 AC 09 01 00 AC 09 01 00 +FE 08 01 00 44 09 01 00 AC 09 01 00 AC 09 01 00 +F4 08 01 00 AC 09 01 00 86 09 01 00 F4 08 01 00 +AC 09 01 00 6A 09 01 00 F4 08 01 00 AC 09 01 00 +AC 09 01 00 AC 09 01 00 5C 09 01 00 66 88 2C 69 +00 00 00 00 0C 09 02 50 74 09 02 50 DC 09 02 50 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 +0E 33 CD AB 34 12 6D E6 EC DE 05 00 0B 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 49 6E 74 65 72 6E 61 6C +20 54 52 4E 47 20 69 73 20 65 6E 61 62 6C 65 64 +2C 20 72 75 6E 6E 69 6E 67 20 54 52 4E 47 20 73 +6D 6F 6B 65 20 74 65 73 74 00 00 00 49 6E 74 65 +72 6E 61 6C 20 54 52 4E 47 20 69 73 20 6E 6F 74 +20 65 6E 61 62 6C 65 64 2C 20 73 6B 69 70 70 69 +6E 67 20 54 52 4E 47 20 73 6D 6F 6B 65 20 74 65 +73 74 00 00 45 6E 61 62 6C 69 6E 67 20 65 6E 74 +72 6F 70 79 5F 73 72 63 00 00 00 00 45 6E 61 62 +6C 69 6E 67 20 63 73 72 6E 67 00 00 20 20 2D 20 +57 61 69 74 69 6E 67 20 66 6F 72 20 62 6F 6F 74 +20 64 6F 6E 65 2E 2E 2E 00 00 00 00 0A 45 6E 74 +72 6F 70 79 20 53 6F 75 72 63 65 20 53 65 65 64 +20 54 65 73 74 00 00 00 49 6E 73 74 61 6E 74 69 +61 74 65 20 43 6F 6D 6D 61 6E 64 00 20 20 2D 20 +57 61 69 74 69 6E 67 20 66 6F 72 20 63 73 72 6E +67 20 74 6F 20 67 65 6E 65 72 61 74 65 20 62 69 +74 73 20 2E 2E 2E 00 00 0A 54 52 4E 47 20 53 6D +6F 6B 65 20 54 65 73 74 00 00 00 00 55 6E 69 6E +69 74 69 61 74 65 20 43 6F 6D 6D 61 6E 64 00 00 +49 6E 69 74 69 61 74 65 20 43 6F 6D 6D 61 6E 64 +20 2D 20 57 72 69 74 69 6E 67 20 34 38 42 20 6F +66 20 73 65 65 64 00 00 47 65 6E 65 72 61 74 65 +20 43 6F 6D 6D 61 6E 64 20 2D 20 35 31 32 62 00 +20 54 52 4E 47 20 53 6D 6F 6B 65 20 54 65 73 74 +20 00 00 00 49 6E 3A 61 62 72 5F 6E 6F 74 69 66 +00 00 00 00 49 6E 3A 61 62 72 5F 65 72 72 6F 72 +00 00 00 00 49 6E 3A 73 68 61 35 31 32 5F 61 63 +63 5F 65 72 72 6F 72 00 49 6E 3A 73 68 61 33 5F +6E 6F 74 69 66 00 00 00 49 6E 3A 73 68 61 33 5F +65 72 72 6F 72 00 00 00 49 6E 3A 73 68 61 32 35 +36 5F 65 72 72 6F 72 00 49 6E 3A 73 68 61 35 31 +32 5F 65 72 72 6F 72 00 49 6E 3A 6B 76 5F 6E 6F +74 69 66 00 49 6E 3A 6B 76 5F 65 72 72 6F 72 00 +49 6E 3A 68 6D 61 63 5F 65 72 72 6F 72 00 00 00 +49 6E 3A 65 63 63 5F 65 72 72 6F 72 00 00 00 00 +49 6E 3A 64 6F 65 5F 65 72 72 6F 72 00 00 00 00 +49 6E 3A 30 00 00 00 00 49 6E 3A 61 78 69 5F 64 +6D 61 5F 6E 6F 74 69 66 00 00 00 00 49 6E 3A 61 +78 69 5F 64 6D 61 5F 65 72 72 6F 72 00 00 00 00 +49 6E 3A 73 68 61 35 31 32 5F 61 63 63 5F 6E 6F +74 69 66 00 49 6E 3A 73 6F 63 5F 69 66 63 5F 6E +6F 74 69 66 00 00 00 00 49 6E 3A 73 6F 63 5F 69 +66 63 5F 65 72 72 6F 72 00 00 00 00 49 6E 3A 73 +68 61 32 35 36 5F 6E 6F 74 69 66 00 49 6E 3A 73 +68 61 35 31 32 5F 6E 6F 74 69 66 00 49 6E 3A 68 +6D 61 63 5F 6E 6F 74 69 66 00 00 00 49 6E 3A 65 +63 63 5F 6E 6F 74 69 66 00 00 00 00 49 6E 3A 64 +6F 65 5F 6E 6F 74 69 66 00 00 00 00 44 6F 6E 65 +20 68 61 6E 64 6C 69 6E 67 20 6D 61 63 68 69 6E +65 2D 6D 6F 64 65 20 54 49 4D 45 52 20 69 6E 74 +65 72 72 75 70 74 00 00 43 6F 72 20 45 72 72 6F +72 20 4C 6F 63 61 6C 20 49 53 52 00 45 72 72 6F +72 3A 20 48 65 78 20 73 74 72 69 6E 67 20 6C 65 +6E 67 74 68 20 6D 75 73 74 20 62 65 20 61 20 6D +75 6C 74 69 70 6C 65 20 6F 66 20 32 2E 00 00 00 +43 6F 6E 66 69 67 75 72 69 6E 67 20 41 45 53 20 +66 6F 72 20 62 69 67 20 65 6E 64 69 61 6E 20 6D +6F 64 65 00 43 6F 6E 66 69 67 75 72 69 6E 67 20 +41 45 53 20 66 6F 72 20 6C 69 74 74 6C 65 20 65 +6E 64 69 61 6E 20 6D 6F 64 65 00 00 4C 6F 61 64 +20 4B 65 79 20 64 61 74 61 20 74 6F 20 41 45 53 +00 00 00 00 57 72 69 74 65 20 41 45 53 20 49 56 +00 00 00 00 57 61 69 74 20 66 6F 72 20 49 4E 50 +55 54 5F 52 45 41 44 59 00 00 00 00 49 6E 6A 65 +63 74 69 6E 67 20 44 4D 41 20 65 72 72 00 00 00 +49 6E 6A 65 63 74 69 6E 67 20 41 45 53 20 63 6F +6C 6C 69 73 69 6F 6E 20 65 72 72 00 41 45 53 20 +63 6F 6C 6C 69 73 69 6F 6E 20 65 72 72 6F 72 20 +6D 75 73 74 20 72 65 73 75 6C 74 20 69 6E 20 4E +4D 49 2C 20 61 6E 64 20 66 69 72 6D 77 61 72 65 +20 72 65 73 65 74 00 00 41 54 54 45 4D 50 54 20 +54 4F 20 46 4C 49 50 20 53 49 44 45 4C 4F 41 44 +20 42 49 54 00 00 00 00 45 58 50 45 43 54 45 44 +20 4F 55 54 50 55 54 5F 4C 4F 53 54 20 74 6F 20 +62 65 20 6E 6F 6E 2D 7A 65 72 6F 20 73 69 6E 63 +65 20 4F 43 50 20 4C 4F 43 4B 20 70 72 6F 74 65 +63 74 69 6F 6E 73 20 61 72 65 20 62 6C 6F 63 6B +69 6E 67 20 74 68 65 20 6F 75 74 70 75 74 20 74 +6F 20 46 57 00 00 00 00 45 78 70 65 63 74 65 64 +20 64 61 74 61 3A 20 30 78 30 00 00 57 41 49 54 +49 4E 47 20 46 4F 52 20 4B 56 20 52 45 41 44 20 +54 4F 20 46 49 4E 49 53 48 00 00 00 45 58 50 45 +43 54 49 4E 47 20 4B 56 20 52 44 20 45 52 52 00 +45 58 50 45 43 54 49 4E 47 20 4E 4F 20 4B 56 20 +52 44 20 45 52 52 00 00 57 41 49 54 49 4E 47 20 +46 4F 52 20 4B 56 20 57 52 49 54 45 20 54 4F 20 +46 49 4E 49 53 48 00 00 43 48 45 43 4B 49 4E 47 +20 46 4F 52 20 4B 56 20 57 52 49 54 45 20 45 52 +52 00 00 00 45 58 50 45 43 54 49 4E 47 20 4B 56 +20 45 52 52 00 00 00 00 45 58 50 45 43 54 49 4E +47 20 4E 4F 20 4B 56 20 45 52 52 00 52 65 61 64 +20 61 6E 64 20 43 6F 6D 70 61 72 65 20 47 43 4D +20 54 41 47 00 00 00 00 41 45 53 20 4F 70 65 72 +61 74 69 6F 6E 20 43 6F 6D 70 6C 65 74 65 00 00 +4C 6F 61 64 69 6E 67 20 4B 56 20 76 69 61 20 41 +45 53 00 00 44 4F 45 3A 20 49 6E 69 74 00 00 00 +44 4F 45 3A 20 57 72 69 74 69 6E 67 20 55 44 53 +20 49 56 00 44 4F 45 3A 20 53 74 61 72 74 69 6E +67 20 55 44 53 20 44 65 6F 62 66 75 73 63 61 74 +69 6F 6E 20 66 6C 6F 77 00 00 00 00 44 4F 45 3A +20 55 44 53 20 44 65 6F 62 66 75 73 63 61 74 69 +6F 6E 20 66 6C 6F 77 20 63 6F 6D 70 6C 65 74 65 +00 00 00 00 44 4F 45 3A 20 57 72 69 74 69 6E 67 +20 46 69 65 6C 64 20 45 6E 74 72 6F 70 79 20 49 +56 00 00 00 44 4F 45 3A 20 53 74 61 72 74 69 6E +67 20 46 69 65 6C 64 20 45 6E 74 72 6F 70 79 20 +44 65 6F 62 66 75 73 63 61 74 69 6F 6E 20 66 6C +6F 77 00 00 44 4F 45 3A 20 46 69 65 6C 64 20 45 +6E 74 72 6F 70 79 20 44 65 6F 62 66 75 73 63 61 +74 69 6F 6E 20 66 6C 6F 77 20 63 6F 6D 70 6C 65 +74 65 00 00 44 4F 45 3A 20 57 72 69 74 69 6E 67 +20 48 45 4B 20 49 56 00 44 4F 45 3A 20 53 74 61 +72 74 69 6E 67 20 48 45 4B 20 44 65 6F 62 66 75 +73 63 61 74 69 6F 6E 20 66 6C 6F 77 00 00 00 00 +44 4F 45 3A 20 48 45 4B 20 53 65 65 64 20 44 65 +6F 62 66 75 73 63 61 74 69 6F 6E 20 66 6C 6F 77 +20 63 6F 6D 70 6C 65 74 65 00 00 00 44 4F 45 3A +20 53 6B 69 70 70 69 6E 67 20 48 45 4B 20 44 65 +6F 62 66 75 73 63 61 74 69 6F 6E 20 64 75 65 20 +74 6F 20 48 57 5F 43 4F 4E 46 49 47 00 00 00 00 +44 4F 45 3A 20 43 6C 65 61 72 20 73 65 63 72 65 +74 73 00 00 45 43 43 20 66 6C 6F 77 20 69 6E 20 +70 72 6F 67 72 65 73 73 2E 2E 2E 00 45 43 43 20 +7A 65 72 6F 69 7A 65 20 66 6C 6F 77 2E 00 00 00 +0A 45 43 43 20 4B 45 59 47 45 4E 00 57 61 69 74 +20 66 6F 72 20 4B 56 20 77 72 69 74 65 00 00 00 +4C 6F 61 64 20 50 52 49 56 4B 45 59 20 64 61 74 +61 20 66 72 6F 6D 20 45 43 43 00 00 4C 6F 61 64 +20 50 55 42 4B 45 59 5F 58 20 64 61 74 61 20 66 +72 6F 6D 20 45 43 43 00 4C 6F 61 64 20 50 55 42 +4B 45 59 5F 59 20 64 61 74 61 20 66 72 6F 6D 20 +45 43 43 00 53 74 6F 72 65 20 50 55 42 4B 45 59 +5F 58 20 64 61 74 61 20 69 6E 20 45 43 43 00 00 +53 74 6F 72 65 20 50 55 42 4B 45 59 5F 59 20 64 +61 74 61 20 69 6E 20 45 43 43 00 00 0A 45 43 43 +20 53 48 41 52 45 44 4B 45 59 00 00 4C 6F 61 64 +20 53 48 41 52 45 44 4B 45 59 20 64 61 74 61 20 +66 72 6F 6D 20 45 43 43 00 00 00 00 49 6E 6A 65 +63 74 20 50 52 49 56 4B 45 59 20 66 72 6F 6D 20 +6B 76 20 74 6F 20 45 43 43 00 00 00 0A 45 43 43 +20 53 49 47 4E 49 4E 47 00 00 00 00 4C 6F 61 64 +20 53 49 47 4E 5F 52 20 64 61 74 61 20 66 72 6F +6D 20 45 43 43 00 00 00 4C 6F 61 64 20 53 49 47 +4E 5F 53 20 64 61 74 61 20 66 72 6F 6D 20 45 43 +43 00 00 00 0A 45 43 43 20 56 45 52 49 46 59 49 +4E 47 00 00 4C 6F 61 64 20 56 45 52 49 46 59 5F +52 20 64 61 74 61 20 66 72 6F 6D 20 45 43 43 00 +0A 45 43 43 20 50 43 52 20 53 49 47 4E 49 4E 47 +00 00 00 00 4D 4C 44 53 41 20 66 6C 6F 77 20 69 +6E 20 70 72 6F 67 72 65 73 73 2E 2E 2E 00 00 00 +4D 4C 44 53 41 20 7A 65 72 6F 69 7A 65 20 66 6C +6F 77 2E 00 57 61 69 74 69 6E 67 20 66 6F 72 20 +6D 6C 64 73 61 20 73 74 61 74 75 73 20 72 65 61 +64 79 00 00 57 61 69 74 69 6E 67 20 66 6F 72 20 +6D 6C 64 73 61 20 73 74 61 74 75 73 20 72 65 61 +64 79 20 69 6E 20 6B 65 79 67 65 6E 00 00 00 00 +54 72 79 20 74 6F 20 4F 76 65 72 77 72 69 74 65 +20 73 65 65 64 20 64 61 74 61 20 69 6E 20 4D 4C +44 53 41 00 5B 4D 4C 44 53 41 20 4B 65 79 47 65 +6E 5D 20 52 65 63 65 69 76 65 64 20 65 78 70 65 +63 74 65 64 20 65 72 72 20 66 6F 72 20 4D 4C 44 +53 41 20 73 65 65 64 20 72 65 61 64 20 66 72 6F +6D 20 4B 56 00 00 00 00 5B 4D 4C 44 53 41 20 4B +65 79 47 65 6E 5D 20 52 65 63 65 69 76 65 64 20 +75 6E 65 78 70 65 63 74 65 64 20 73 75 63 63 65 +73 73 20 66 6F 72 20 4D 4C 44 53 41 20 73 65 65 +64 20 72 65 61 64 20 66 72 6F 6D 20 4B 56 00 00 +57 72 69 74 69 6E 67 20 65 6E 74 72 6F 70 79 00 +0A 4D 4C 44 53 41 20 4B 45 59 47 45 4E 00 00 00 +4C 6F 61 64 20 50 52 49 56 4B 45 59 20 64 61 74 +61 20 66 72 6F 6D 20 4D 4C 44 53 41 00 00 00 00 +4C 6F 61 64 20 50 55 42 4B 45 59 20 64 61 74 61 +20 66 72 6F 6D 20 4D 4C 44 53 41 00 5B 4D 4C 44 +53 41 20 4B 65 79 47 65 6E 20 53 69 67 6E 69 6E +67 5D 20 52 65 63 65 69 76 65 64 20 65 78 70 65 +63 74 65 64 20 65 72 72 20 66 6F 72 20 4D 4C 44 +53 41 20 73 65 65 64 20 72 65 61 64 20 66 72 6F +6D 20 4B 56 00 00 00 00 5B 4D 4C 44 53 41 20 4B +65 79 47 65 6E 20 53 69 67 6E 69 6E 67 5D 20 52 +65 63 65 69 76 65 64 20 75 6E 65 78 70 65 63 74 +65 64 20 73 75 63 63 65 73 73 20 66 6F 72 20 4D +4C 44 53 41 20 73 65 65 64 20 72 65 61 64 20 66 +72 6F 6D 20 4B 56 00 00 0A 4D 4C 44 53 41 20 4B +45 59 47 45 4E 20 2B 20 53 49 47 4E 49 4E 47 00 +4C 6F 61 64 20 53 49 47 4E 20 64 61 74 61 20 66 +72 6F 6D 20 4D 4C 44 53 41 00 00 00 57 72 69 74 +69 6E 67 20 70 72 69 76 6B 65 79 00 57 72 69 74 +69 6E 67 20 6D 73 67 00 0A 4D 4C 44 53 41 20 53 +49 47 4E 49 4E 47 00 00 0A 4D 4C 44 53 41 20 56 +45 52 49 46 59 49 4E 47 00 00 00 00 4C 6F 61 64 +20 56 45 52 49 46 59 5F 52 45 53 20 64 61 74 61 +20 66 72 6F 6D 20 4D 4C 44 53 41 00 0A 4D 4C 44 +53 41 20 4B 45 59 47 45 4E 20 2B 20 53 49 47 4E +49 4E 47 20 69 6E 20 45 78 74 65 72 6E 61 6C 4D +75 20 6D 6F 64 65 00 00 57 72 69 74 69 6E 67 20 +45 78 74 65 72 6E 61 6C 4D 75 00 00 0A 4D 4C 44 +53 41 20 53 49 47 4E 49 4E 47 20 69 6E 20 45 78 +74 65 72 6E 61 6C 4D 75 20 6D 6F 64 65 00 00 00 +0A 4D 4C 44 53 41 20 56 45 52 49 46 59 49 4E 47 +20 69 6E 20 45 78 74 65 72 6E 61 6C 4D 75 20 6D +6F 64 65 00 5B 4D 4C 4B 45 4D 5D 20 57 61 69 74 +69 6E 67 20 66 6F 72 20 69 6E 74 65 72 72 75 70 +74 00 00 00 5B 4D 4C 4B 45 4D 5D 20 53 74 61 72 +74 69 6E 67 20 7A 65 72 6F 69 7A 65 00 00 00 00 +5B 4D 4C 4B 45 4D 5D 20 57 61 69 74 69 6E 67 20 +66 6F 72 20 72 65 61 64 79 00 00 00 5B 4D 4C 4B +45 4D 20 4B 65 79 47 65 6E 5D 20 57 61 69 74 69 +6E 67 20 66 6F 72 20 72 65 61 64 79 00 00 00 00 +5B 4D 4C 4B 45 4D 20 4B 65 79 47 65 6E 5D 20 54 +72 79 20 74 6F 20 4F 76 65 72 77 72 69 74 65 20 +73 65 65 64 20 64 20 64 61 74 61 00 5B 4D 4C 4B +45 4D 20 4B 65 79 47 65 6E 5D 20 54 72 79 20 74 +6F 20 4F 76 65 72 77 72 69 74 65 20 73 65 65 64 +20 7A 20 64 61 74 61 00 5B 4D 4C 4B 45 4D 20 4B +65 79 47 65 6E 5D 20 52 65 63 65 69 76 65 64 20 +65 78 70 65 63 74 65 64 20 65 72 72 20 66 6F 72 +20 4D 4C 4B 45 4D 20 73 65 65 64 20 72 65 61 64 +20 66 72 6F 6D 20 4B 56 00 00 00 00 5B 4D 4C 4B +45 4D 20 4B 65 79 47 65 6E 5D 20 52 65 63 65 69 +76 65 64 20 75 6E 65 78 70 65 63 74 65 64 20 73 +75 63 63 65 73 73 20 66 6F 72 20 4D 4C 4B 45 4D +20 73 65 65 64 20 72 65 61 64 20 66 72 6F 6D 20 +4B 56 00 00 5B 4D 4C 4B 45 4D 20 4B 65 79 47 65 +6E 5D 20 57 72 69 74 69 6E 67 20 65 6E 74 72 6F +70 79 00 00 5B 4D 4C 4B 45 4D 20 4B 65 79 47 65 +6E 5D 20 53 65 6E 64 69 6E 67 20 63 6F 6D 6D 61 +6E 64 00 00 5B 4D 4C 4B 45 4D 20 4B 65 79 47 65 +6E 5D 20 43 68 65 63 6B 69 6E 67 20 65 6E 63 61 +70 73 20 6B 65 79 00 00 5B 4D 4C 4B 45 4D 20 4B +65 79 47 65 6E 5D 20 43 68 65 63 6B 69 6E 67 20 +64 65 63 61 70 73 20 6B 65 79 00 00 5B 4D 4C 4B +45 4D 20 4B 65 79 47 65 6E 5D 20 43 68 65 63 6B +20 74 68 61 74 20 53 45 45 44 5F 44 20 61 70 69 +20 68 61 73 20 30 73 00 5B 4D 4C 4B 45 4D 20 4B +65 79 47 65 6E 5D 20 43 68 65 63 6B 20 74 68 61 +74 20 53 45 45 44 5F 5A 20 61 70 69 20 68 61 73 +20 30 73 00 5B 4D 4C 4B 45 4D 20 4B 65 79 47 65 +6E 5D 20 52 65 61 64 20 45 6E 63 61 70 73 20 4B +65 79 00 00 5B 4D 4C 4B 45 4D 20 4B 65 79 47 65 +6E 5D 20 52 65 61 64 20 44 65 63 61 70 73 20 4B +65 79 00 00 5B 4D 4C 4B 45 4D 20 4B 65 79 47 65 +6E 5D 20 43 68 65 63 6B 20 74 68 61 74 20 44 4B +20 61 70 69 20 68 61 73 20 30 73 00 5B 4D 4C 4B +45 4D 20 45 6E 63 61 70 73 5D 20 57 61 69 74 69 +6E 67 20 66 6F 72 20 72 65 61 64 79 00 00 00 00 +5B 4D 4C 4B 45 4D 20 45 6E 63 61 70 73 5D 20 57 +72 69 74 69 6E 67 20 65 6E 63 61 70 73 20 6B 65 +79 00 00 00 5B 4D 4C 4B 45 4D 20 45 6E 63 61 70 +73 5D 20 54 72 79 20 74 6F 20 4F 76 65 72 77 72 +69 74 65 20 6D 73 67 00 5B 4D 4C 4B 45 4D 20 45 +6E 63 61 70 73 5D 20 54 72 79 20 74 6F 20 4F 76 +65 72 77 72 69 74 65 20 6D 73 67 20 74 68 72 6F +75 67 68 20 4D 4C 44 53 41 20 70 72 69 76 6B 65 +79 00 00 00 5B 4D 4C 4B 45 4D 20 4B 65 79 47 65 +6E 5D 20 52 65 63 65 69 76 65 64 20 65 78 70 65 +63 74 65 64 20 65 72 72 20 66 6F 72 20 4D 4C 4B +45 4D 20 6D 73 67 20 72 65 61 64 20 66 72 6F 6D +20 4B 56 00 5B 4D 4C 4B 45 4D 20 4B 65 79 47 65 +6E 5D 20 52 65 63 65 69 76 65 64 20 75 6E 65 78 +70 65 63 74 65 64 20 73 75 63 63 65 73 73 20 66 +6F 72 20 4D 4C 4B 45 4D 20 6D 73 67 20 72 65 61 +64 20 66 72 6F 6D 20 4B 56 00 00 00 5B 4D 4C 4B +45 4D 20 45 6E 63 61 70 73 5D 20 43 68 65 63 6B +20 74 68 61 74 20 4D 53 47 20 61 70 69 20 68 61 +73 20 30 73 00 00 00 00 5B 4D 4C 4B 45 4D 20 45 +6E 63 61 70 73 5D 20 57 72 69 74 69 6E 67 20 65 +6E 74 72 6F 70 79 00 00 5B 4D 4C 4B 45 4D 20 45 +6E 63 61 70 73 5D 20 53 65 6E 64 69 6E 67 20 63 +6F 6D 6D 61 6E 64 00 00 5B 4D 4C 4B 45 4D 20 45 +6E 63 61 70 73 5D 20 43 68 65 63 6B 20 43 69 70 +68 65 72 74 65 78 74 00 5B 4D 4C 4B 45 4D 20 45 +6E 63 61 70 73 5D 20 52 65 63 65 69 76 65 64 20 +65 78 70 65 63 74 65 64 20 65 72 72 20 66 6F 72 +20 4D 4C 4B 45 4D 20 73 68 61 72 65 64 6B 65 79 +20 77 72 69 74 65 20 66 72 6F 6D 20 4B 56 00 00 +5B 4D 4C 4B 45 4D 20 45 6E 63 61 70 73 5D 20 52 +65 63 65 69 76 65 64 20 75 6E 65 78 70 65 63 74 +65 64 20 73 75 63 63 65 73 73 20 66 6F 72 20 4D +4C 4B 45 4D 20 73 68 61 72 65 64 6B 65 79 20 77 +72 69 74 65 20 66 72 6F 6D 20 4B 56 00 00 00 00 +5B 4D 4C 4B 45 4D 20 45 6E 63 61 70 73 5D 20 52 +65 63 65 69 76 65 64 20 75 6E 65 78 70 65 63 74 +65 64 20 65 72 72 20 66 6F 72 20 4D 4C 4B 45 4D +20 73 68 61 72 65 64 6B 65 79 20 77 72 69 74 65 +20 66 72 6F 6D 20 4B 56 00 00 00 00 5B 4D 4C 4B +45 4D 20 45 6E 63 61 70 73 5D 20 52 65 63 65 69 +76 65 64 20 65 78 70 65 63 74 65 64 20 73 75 63 +63 65 73 73 20 66 6F 72 20 4D 4C 4B 45 4D 20 73 +68 61 72 65 64 6B 65 79 20 77 72 69 74 65 20 66 +72 6F 6D 20 4B 56 00 00 5B 4D 4C 4B 45 4D 20 45 +6E 63 61 70 73 5D 20 43 68 65 63 6B 20 53 68 61 +72 65 64 20 4B 65 79 00 5B 4D 4C 4B 45 4D 20 45 +6E 63 61 70 73 5D 20 4B 56 20 75 73 65 64 2C 20 +63 68 65 63 6B 20 53 68 61 72 65 64 20 4B 65 79 +20 69 73 20 30 00 00 00 5B 4D 4C 4B 45 4D 20 45 +6E 63 61 70 73 5D 20 53 65 6E 64 69 6E 67 20 43 +6F 6D 6D 61 6E 64 00 00 5B 4D 4C 4B 45 4D 20 45 +6E 63 61 70 73 5D 20 52 65 61 64 20 43 69 70 68 +65 72 74 65 78 74 00 00 5B 4D 4C 4B 45 4D 20 45 +6E 63 61 70 73 5D 20 52 65 63 65 69 76 65 64 20 +75 6E 65 78 70 65 63 74 65 64 20 66 61 69 6C 20 +66 6F 72 20 4D 4C 4B 45 4D 20 73 68 61 72 65 64 +6B 65 79 20 77 72 69 74 65 20 66 72 6F 6D 20 4B +56 00 00 00 5B 4D 4C 4B 45 4D 20 45 6E 63 61 70 +73 5D 20 52 65 61 64 20 53 68 61 72 65 64 20 4B +65 79 00 00 5B 4D 4C 4B 45 4D 20 44 65 63 61 70 +73 5D 20 57 61 69 74 69 6E 67 20 66 6F 72 20 72 +65 61 64 79 00 00 00 00 5B 4D 4C 4B 45 4D 20 44 +65 63 61 70 73 5D 20 57 72 69 74 69 6E 67 20 64 +65 63 61 70 73 20 6B 65 79 00 00 00 5B 4D 4C 4B +45 4D 20 44 65 63 61 70 73 5D 20 57 72 69 74 69 +6E 67 20 65 6E 74 72 6F 70 79 00 00 5B 4D 4C 4B +45 4D 20 44 65 63 61 70 73 5D 20 53 65 6E 64 69 +6E 67 20 63 6F 6D 6D 61 6E 64 00 00 5B 4D 4C 4B +45 4D 20 44 65 63 61 70 73 5D 20 52 65 63 65 69 +76 65 64 20 65 78 70 65 63 74 65 64 20 65 72 72 +20 66 6F 72 20 4D 4C 4B 45 4D 20 73 68 61 72 65 +64 6B 65 79 20 77 72 69 74 65 20 66 72 6F 6D 20 +4B 56 00 00 5B 4D 4C 4B 45 4D 20 44 65 63 61 70 +73 5D 20 52 65 63 65 69 76 65 64 20 75 6E 65 78 +70 65 63 74 65 64 20 73 75 63 63 65 73 73 20 66 +6F 72 20 4D 4C 4B 45 4D 20 73 68 61 72 65 64 6B +65 79 20 77 72 69 74 65 20 66 72 6F 6D 20 4B 56 +00 00 00 00 5B 4D 4C 4B 45 4D 20 44 65 63 61 70 +73 5D 20 52 65 63 65 69 76 65 64 20 75 6E 65 78 +70 65 63 74 65 64 20 66 61 69 6C 20 66 6F 72 20 +4D 4C 4B 45 4D 20 73 68 61 72 65 64 6B 65 79 20 +77 72 69 74 65 20 66 72 6F 6D 20 4B 56 00 00 00 +5B 4D 4C 4B 45 4D 20 44 65 63 61 70 73 5D 20 52 +65 63 65 69 76 65 64 20 65 78 70 65 63 74 65 64 +20 73 75 63 63 65 73 73 20 66 6F 72 20 4D 4C 4B +45 4D 20 73 68 61 72 65 64 6B 65 79 20 77 72 69 +74 65 20 66 72 6F 6D 20 4B 56 00 00 5B 4D 4C 4B +45 4D 20 44 65 63 61 70 73 5D 20 4B 56 20 75 73 +65 64 2C 20 63 68 65 63 6B 20 53 68 61 72 65 64 +20 4B 65 79 20 69 73 20 30 00 00 00 5B 4D 4C 4B +45 4D 20 44 65 63 61 70 73 5D 20 43 68 65 63 6B +20 53 68 61 72 65 64 20 4B 65 79 00 5B 4D 4C 4B +45 4D 20 44 65 63 61 70 73 5D 20 52 65 63 65 69 +76 65 64 20 65 78 70 65 63 74 65 64 20 65 72 72 +20 66 6F 72 20 4D 4C 4B 45 4D 20 73 68 61 72 65 +64 6B 65 79 20 72 65 61 64 20 66 72 6F 6D 20 4B +56 00 00 00 5B 4D 4C 4B 45 4D 20 44 65 63 61 70 +73 5D 20 52 65 63 65 69 76 65 64 20 75 6E 65 78 +70 65 63 74 65 64 20 73 75 63 63 65 73 73 20 66 +6F 72 20 4D 4C 4B 45 4D 20 73 68 61 72 65 64 6B +65 79 20 72 65 61 64 20 66 72 6F 6D 20 4B 56 00 +5B 4D 4C 4B 45 4D 20 44 65 63 61 70 73 5D 20 52 +65 61 64 20 53 68 61 72 65 64 20 4B 65 79 00 00 +5B 4D 4C 4B 45 4D 20 4B 65 79 47 65 6E 20 44 65 +63 61 70 73 5D 20 57 61 69 74 69 6E 67 20 66 6F +72 20 72 65 61 64 79 00 5B 4D 4C 4B 45 4D 20 4B +65 79 47 65 6E 20 44 65 63 61 70 73 5D 20 54 72 +79 20 74 6F 20 4F 76 65 72 77 72 69 74 65 20 73 +65 65 64 20 64 00 00 00 5B 4D 4C 4B 45 4D 20 4B +65 79 47 65 6E 20 44 65 63 61 70 73 5D 20 54 72 +79 20 74 6F 20 4F 76 65 72 77 72 69 74 65 20 73 +65 65 64 20 7A 00 00 00 5B 4D 4C 4B 45 4D 20 4B +65 79 47 65 6E 20 44 65 63 61 70 73 5D 20 57 72 +69 74 69 6E 67 20 65 6E 74 72 6F 70 79 00 00 00 +5B 4D 4C 4B 45 4D 20 4B 65 79 47 65 6E 20 44 65 +63 61 70 73 5D 20 53 65 6E 64 69 6E 67 20 63 6F +6D 6D 61 6E 64 00 00 00 5B 4D 4C 4B 45 4D 20 4B +65 79 47 65 6E 20 44 65 63 61 70 73 5D 20 52 65 +63 65 69 76 65 64 20 65 78 70 65 63 74 65 64 20 +65 72 72 20 66 6F 72 20 4D 4C 4B 45 4D 20 73 68 +61 72 65 64 6B 65 79 20 77 72 69 74 65 20 66 72 +6F 6D 20 4B 56 00 00 00 5B 4D 4C 4B 45 4D 20 4B +65 79 47 65 6E 20 44 65 63 61 70 73 5D 20 52 65 +63 65 69 76 65 64 20 75 6E 65 78 70 65 63 74 65 +64 20 73 75 63 63 65 73 73 20 66 6F 72 20 4D 4C +4B 45 4D 20 73 68 61 72 65 64 6B 65 79 20 77 72 +69 74 65 20 66 72 6F 6D 20 4B 56 00 5B 4D 4C 4B +45 4D 20 4B 65 79 47 65 6E 20 44 65 63 61 70 73 +5D 20 52 65 63 65 69 76 65 64 20 75 6E 65 78 70 +65 63 74 65 64 20 66 61 69 6C 20 66 6F 72 20 4D +4C 4B 45 4D 20 73 68 61 72 65 64 6B 65 79 20 77 +72 69 74 65 20 66 72 6F 6D 20 4B 56 00 00 00 00 +5B 4D 4C 4B 45 4D 20 4B 65 79 47 65 6E 20 44 65 +63 61 70 73 5D 20 52 65 63 65 69 76 65 64 20 65 +78 70 65 63 74 65 64 20 73 75 63 63 65 73 73 20 +66 6F 72 20 4D 4C 4B 45 4D 20 73 68 61 72 65 64 +6B 65 79 20 77 72 69 74 65 20 66 72 6F 6D 20 4B +56 00 00 00 5B 4D 4C 4B 45 4D 20 4B 65 79 47 65 +6E 20 44 65 63 61 70 73 5D 20 43 68 65 63 6B 20 +53 68 61 72 65 64 20 4B 65 79 00 00 5B 4D 4C 4B +45 4D 20 4B 65 79 47 65 6E 20 44 65 63 61 70 73 +5D 20 4B 56 20 75 73 65 64 2C 20 63 68 65 63 6B +20 53 68 61 72 65 64 20 4B 65 79 20 69 73 20 30 +00 00 00 00 5B 4D 4C 4B 45 4D 20 4B 65 79 47 65 +6E 20 44 65 63 61 70 73 5D 20 52 65 61 64 20 53 +68 61 72 65 64 20 4B 65 79 00 00 00 48 4D 41 43 +20 66 6C 6F 77 20 69 6E 20 70 72 6F 67 72 65 73 +73 2E 2E 2E 00 00 00 00 48 4D 41 43 20 7A 65 72 +6F 69 7A 65 20 66 6C 6F 77 2E 00 00 54 72 79 20 +74 6F 20 4F 76 65 72 77 72 69 74 65 20 4B 65 79 +20 64 61 74 61 20 69 6E 20 48 4D 41 43 33 38 34 +00 00 00 00 52 65 63 65 69 76 65 64 20 65 78 70 +65 63 74 65 64 20 65 72 72 20 66 6F 72 20 48 4D +41 43 20 6B 65 79 20 72 65 61 64 20 66 72 6F 6D +20 4B 56 20 77 68 69 6C 65 20 4F 43 50 20 6C 6F +63 6B 20 69 6E 20 70 72 6F 67 72 65 73 73 00 00 +52 65 63 65 69 76 65 64 20 75 6E 65 78 70 65 63 +74 65 64 20 73 75 63 63 65 73 73 20 66 6F 72 20 +48 4D 41 43 20 6B 65 79 20 72 65 61 64 20 66 72 +6F 6D 20 4B 56 20 77 68 69 6C 65 20 4F 43 50 20 +6C 6F 63 6B 20 69 6E 20 70 72 6F 67 72 65 73 73 +00 00 00 00 4C 6F 61 64 20 4B 65 79 20 64 61 74 +61 20 74 6F 20 48 4D 41 43 00 00 00 54 72 79 20 +74 6F 20 4F 76 65 72 77 72 69 74 65 20 42 6C 6F +63 6B 20 64 61 74 61 20 69 6E 20 48 4D 41 43 00 +52 65 63 65 69 76 65 64 20 65 78 70 65 63 74 65 +64 20 65 72 72 20 66 6F 72 20 48 4D 41 43 20 62 +6C 6F 63 6B 20 72 65 61 64 20 66 72 6F 6D 20 4B +56 20 77 68 69 6C 65 20 4F 43 50 20 6C 6F 63 6B +20 69 6E 20 70 72 6F 67 72 65 73 73 00 00 00 00 +52 65 63 65 69 76 65 64 20 75 6E 65 78 70 65 63 +74 65 64 20 73 75 63 63 65 73 73 20 66 6F 72 20 +48 4D 41 43 20 62 6C 6F 63 6B 20 72 65 61 64 20 +66 72 6F 6D 20 4B 56 20 77 68 69 6C 65 20 4F 43 +50 20 6C 6F 63 6B 20 69 6E 20 70 72 6F 67 72 65 +73 73 00 00 4C 6F 61 64 20 54 41 47 20 64 61 74 +61 20 66 72 6F 6D 20 48 4D 41 43 20 74 6F 20 4B +56 00 00 00 4C 6F 61 64 20 54 41 47 20 64 61 74 +61 20 66 72 6F 6D 20 48 4D 41 43 00 54 72 79 20 +74 6F 20 4F 76 65 72 77 72 69 74 65 20 4B 65 79 +20 64 61 74 61 20 69 6E 20 48 4D 41 43 35 31 32 +00 00 00 00 4B 56 3A 20 63 68 65 63 6B 69 6E 67 +20 66 6F 72 20 65 72 72 6F 72 73 00 4B 56 20 45 +52 52 4F 52 00 00 00 00 4B 56 3A 20 63 68 65 63 +6B 69 6E 67 20 65 72 72 6F 72 73 20 70 72 65 73 +65 6E 74 00 4E 4F 20 4B 56 20 45 52 52 4F 52 00 +4B 56 3A 20 70 72 6F 67 20 6B 76 20 72 65 61 64 +20 63 74 72 6C 00 00 00 4B 56 3A 20 70 72 6F 67 +20 6B 76 20 77 72 69 74 65 20 63 74 72 6C 00 00 +50 56 3A 20 70 72 6F 67 20 6B 76 20 72 65 61 64 +20 63 74 72 6C 20 69 6E 20 53 48 41 20 74 6F 20 +64 6F 20 68 61 73 68 20 65 78 74 65 6E 64 00 00 +2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D +2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 00 +53 54 49 43 4B 59 44 41 54 41 56 41 55 4C 54 43 +54 52 4C 00 53 54 49 43 4B 59 5F 44 41 54 41 5F +56 41 55 4C 54 5F 45 4E 54 52 59 5F 30 00 00 00 +53 54 49 43 4B 59 5F 44 41 54 41 5F 56 41 55 4C +54 5F 45 4E 54 52 59 5F 31 00 00 00 53 54 49 43 +4B 59 5F 44 41 54 41 5F 56 41 55 4C 54 5F 45 4E +54 52 59 5F 32 00 00 00 53 54 49 43 4B 59 5F 44 +41 54 41 5F 56 41 55 4C 54 5F 45 4E 54 52 59 5F +33 00 00 00 53 54 49 43 4B 59 5F 44 41 54 41 5F +56 41 55 4C 54 5F 45 4E 54 52 59 5F 34 00 00 00 +53 54 49 43 4B 59 5F 44 41 54 41 5F 56 41 55 4C +54 5F 45 4E 54 52 59 5F 35 00 00 00 53 54 49 43 +4B 59 5F 44 41 54 41 5F 56 41 55 4C 54 5F 45 4E +54 52 59 5F 36 00 00 00 53 54 49 43 4B 59 5F 44 +41 54 41 5F 56 41 55 4C 54 5F 45 4E 54 52 59 5F +37 00 00 00 53 54 49 43 4B 59 5F 44 41 54 41 5F +56 41 55 4C 54 5F 45 4E 54 52 59 5F 38 00 00 00 +53 54 49 43 4B 59 5F 44 41 54 41 5F 56 41 55 4C +54 5F 45 4E 54 52 59 5F 39 00 00 00 44 41 54 41 +56 41 55 4C 54 43 54 52 4C 00 00 00 44 41 54 41 +5F 56 41 55 4C 54 5F 45 4E 54 52 59 5F 30 00 00 +44 41 54 41 5F 56 41 55 4C 54 5F 45 4E 54 52 59 +5F 31 00 00 44 41 54 41 5F 56 41 55 4C 54 5F 45 +4E 54 52 59 5F 32 00 00 44 41 54 41 5F 56 41 55 +4C 54 5F 45 4E 54 52 59 5F 33 00 00 44 41 54 41 +5F 56 41 55 4C 54 5F 45 4E 54 52 59 5F 34 00 00 +44 41 54 41 5F 56 41 55 4C 54 5F 45 4E 54 52 59 +5F 35 00 00 44 41 54 41 5F 56 41 55 4C 54 5F 45 +4E 54 52 59 5F 36 00 00 44 41 54 41 5F 56 41 55 +4C 54 5F 45 4E 54 52 59 5F 37 00 00 44 41 54 41 +5F 56 41 55 4C 54 5F 45 4E 54 52 59 5F 38 00 00 +44 41 54 41 5F 56 41 55 4C 54 5F 45 4E 54 52 59 +5F 39 00 00 4C 4F 43 4B 41 42 4C 45 5F 53 43 52 +41 54 43 48 52 45 47 5F 43 54 52 4C 00 00 00 00 +4C 4F 43 4B 41 42 4C 45 5F 53 43 52 41 54 43 48 +52 45 47 00 4E 4F 4E 53 54 49 43 4B 59 5F 47 45 +4E 45 52 49 43 5F 53 43 52 41 54 43 48 52 45 47 +00 00 00 00 53 54 49 43 4B 59 5F 4C 4F 43 4B 41 +42 4C 45 5F 53 43 52 41 54 43 48 52 45 47 5F 43 +54 52 4C 00 53 54 49 43 4B 59 5F 4C 4F 43 4B 41 +42 4C 45 5F 53 43 52 41 54 43 48 52 45 47 00 00 +53 48 41 32 35 36 20 66 6C 6F 77 20 69 6E 20 70 +72 6F 67 72 65 73 73 2E 2E 2E 00 00 53 48 41 32 +35 36 20 7A 65 72 6F 69 7A 65 20 66 6C 6F 77 2E +00 00 00 00 45 6E 61 62 6C 65 20 53 48 41 32 35 +36 00 00 00 4C 6F 61 64 20 44 49 47 45 53 54 20 +64 61 74 61 20 66 72 6F 6D 20 53 48 41 32 35 36 +00 00 00 00 45 72 72 6F 72 31 20 69 73 20 65 78 +70 65 63 74 65 64 20 77 68 65 6E 20 69 6E 69 74 +20 61 6E 64 20 6E 65 78 74 20 61 72 65 20 61 73 +73 65 72 74 65 64 20 61 74 20 74 68 65 20 73 61 +6D 65 20 74 69 6D 65 2E 20 43 68 65 63 6B 20 61 +72 67 73 20 67 69 76 65 6E 20 74 6F 20 73 68 61 +32 35 36 5F 65 72 72 6F 72 5F 66 6C 6F 77 28 29 +00 00 00 00 45 72 72 6F 72 30 20 69 73 20 65 78 +70 65 63 74 65 64 20 66 6F 72 20 69 6E 76 61 6C +69 64 20 77 6E 74 7A 5F 6D 6F 64 65 20 6F 72 20 +77 2E 20 43 68 65 63 6B 20 61 72 67 73 20 67 69 +76 65 6E 20 74 6F 20 73 68 61 32 35 36 5F 65 72 +72 6F 72 5F 66 6C 6F 77 28 29 00 00 53 48 41 35 +31 32 20 66 6C 6F 77 20 69 6E 20 70 72 6F 67 72 +65 73 73 2E 2E 2E 00 00 53 48 41 35 31 32 3A 20 +53 65 74 20 53 54 41 52 54 20 66 6F 72 20 67 65 +6E 20 68 61 73 68 20 66 75 6E 63 00 53 48 41 35 +31 32 20 7A 65 72 6F 69 7A 65 20 66 6C 6F 77 2E +00 00 00 00 45 6E 61 62 6C 65 20 53 48 41 35 31 +32 00 00 00 4C 6F 61 64 20 44 49 47 45 53 54 20 +64 61 74 61 20 66 72 6F 6D 20 53 48 41 35 31 32 +00 00 00 00 64 69 66 5F 6B 6D 61 63 5F 63 75 73 +74 6F 6D 69 7A 61 74 69 6F 6E 5F 73 74 72 69 6E +67 5F 69 6E 69 74 3A 20 45 52 52 4F 52 20 64 61 +74 61 20 61 6E 64 20 6F 75 74 20 61 72 67 75 6D +65 6E 74 73 20 6D 75 73 74 20 6E 6F 74 20 62 65 +20 6E 75 6C 6C 2E 00 00 64 69 66 5F 6B 6D 61 63 +5F 63 75 73 74 6F 6D 69 7A 61 74 69 6F 6E 5F 73 +74 72 69 6E 67 5F 69 6E 69 74 3A 20 45 52 52 4F +52 20 6C 65 6E 67 74 68 20 67 72 65 61 74 65 72 +20 74 68 61 6E 20 6D 61 78 69 6D 75 6D 2E 00 00 +64 69 66 5F 6B 6D 61 63 5F 66 75 6E 63 74 69 6F +6E 5F 6E 61 6D 65 5F 69 6E 69 74 3A 20 45 52 52 +4F 52 20 64 61 74 61 20 61 6E 64 20 6F 75 74 20 +6D 75 73 74 20 6E 6F 74 20 62 65 20 4E 55 4C 4C +2E 00 00 00 64 69 66 5F 6B 6D 61 63 5F 66 75 6E +63 74 69 6F 6E 5F 6E 61 6D 65 5F 69 6E 69 74 3A +20 45 52 52 4F 52 20 6C 65 6E 67 74 68 20 6C 61 +72 67 65 72 20 74 68 61 6E 20 6D 61 78 69 6D 75 +6D 2E 00 00 64 69 66 5F 6B 6D 61 63 5F 6D 6F 64 +65 5F 73 68 61 33 5F 73 74 61 72 74 3A 20 45 52 +52 4F 52 20 6B 6D 61 63 20 6F 72 20 6F 70 65 72 +61 74 69 6F 6E 5F 73 74 61 74 65 20 4E 55 4C 4C +2E 00 00 00 64 69 66 5F 6B 6D 61 63 5F 73 68 61 +33 5F 73 74 61 72 74 3A 20 45 52 52 4F 52 20 55 +6E 73 75 70 70 6F 72 74 65 64 20 6D 6F 64 65 2E +00 00 00 00 64 69 66 5F 6B 6D 61 63 5F 73 68 61 +33 5F 73 74 61 72 74 3A 20 45 52 52 4F 52 20 68 +61 72 64 77 61 72 65 20 6D 75 73 74 20 62 65 20 +69 64 6C 65 2E 00 00 00 64 69 66 5F 6B 6D 61 63 +5F 6D 6F 64 65 5F 73 68 61 6B 65 5F 73 74 61 72 +74 3A 20 45 52 52 4F 52 20 6B 6D 61 63 20 61 6E +64 20 6F 70 65 72 61 74 69 6F 6E 20 73 74 61 74 +65 20 63 61 6E 6E 6F 74 20 62 65 20 4E 55 4C 4C +2E 00 00 00 64 69 66 5F 6B 6D 61 63 5F 6D 6F 64 +65 5F 73 68 61 6B 65 5F 73 74 61 72 74 3A 20 45 +52 52 4F 52 20 6D 6F 64 65 20 6E 6F 74 20 61 6C +6C 6F 77 65 64 2E 00 00 64 69 66 5F 6B 6D 61 63 +5F 73 68 61 6B 65 5F 73 74 61 72 74 3A 20 45 52 +52 4F 52 20 68 61 72 64 77 61 72 65 20 6D 75 73 +74 20 62 65 20 69 64 6C 65 2E 00 00 64 69 66 5F +6B 6D 61 63 5F 6D 6F 64 65 5F 63 73 68 61 6B 65 +5F 73 74 61 72 74 3A 20 45 52 52 4F 52 20 6B 6D +61 63 20 6F 72 20 6F 70 65 72 61 74 69 6F 6E 20 +73 74 61 74 65 20 69 73 20 4E 55 4C 4C 2E 00 00 +64 69 66 5F 6B 6D 61 63 5F 6D 6F 64 65 5F 63 73 +68 61 6B 65 5F 73 74 61 72 74 3A 20 45 52 52 4F +52 20 75 6E 73 75 70 70 6F 72 74 65 64 20 6D 6F +64 65 20 66 6F 72 20 65 6D 70 74 79 20 4E 20 61 +6E 64 20 53 2E 00 00 00 64 69 66 5F 6B 6D 61 63 +5F 6D 6F 64 65 5F 63 73 68 61 6B 65 5F 73 74 61 +72 74 3A 20 45 52 52 4F 52 20 75 6E 73 75 70 70 +6F 72 74 65 64 20 6B 73 74 72 65 6E 67 68 74 2E +00 00 00 00 64 69 66 5F 6B 6D 61 63 5F 6D 6F 64 +65 5F 63 73 68 61 6B 65 5F 73 74 61 72 74 3A 20 +45 52 52 4F 52 20 68 61 72 64 77 61 72 65 20 6D +75 73 74 20 62 65 20 69 64 6C 65 2E 00 00 00 00 +64 69 66 5F 6B 6D 61 63 5F 61 62 73 6F 72 62 3A +20 45 52 52 4F 52 20 6F 6E 65 20 6F 66 20 66 75 +6E 63 74 69 6F 6E 20 61 72 67 75 6D 65 6E 74 73 +20 69 73 20 6E 75 6C 6C 00 00 00 00 64 69 66 5F +6B 6D 61 63 5F 61 62 73 6F 72 62 3A 20 45 52 52 +4F 52 20 6F 70 65 72 61 74 69 6F 6E 20 6E 6F 74 +20 73 74 61 72 74 65 64 20 79 65 74 00 00 00 00 +64 69 66 5F 6B 6D 61 63 5F 61 62 73 6F 72 62 3A +20 45 52 52 4F 52 20 68 61 72 64 77 61 72 65 20 +6D 75 73 74 20 62 65 20 61 62 73 6F 72 62 69 6E +67 2E 00 00 64 69 66 5F 6B 6D 61 63 5F 73 71 75 +65 65 7A 65 3A 20 45 52 52 4F 52 20 61 72 67 75 +6D 65 6E 74 73 20 6D 61 79 20 6E 6F 74 20 62 65 +20 4E 55 4C 4C 2E 00 00 64 69 66 5F 6B 6D 61 63 +5F 73 71 75 65 65 7A 65 3A 20 45 52 52 4F 52 20 +74 6F 74 61 6C 20 62 79 74 65 73 20 72 65 71 75 +65 73 74 65 64 20 6D 75 73 74 20 6E 6F 74 20 65 +78 63 65 65 64 20 66 69 78 65 64 20 6F 75 74 70 +75 74 20 6C 65 6E 67 74 68 2E 00 00 64 69 66 5F +6B 6D 61 63 5F 73 71 75 65 65 7A 65 3A 20 45 52 +52 4F 52 20 6F 70 65 72 61 74 69 6F 6E 20 73 74 +61 74 65 20 64 20 6C 65 73 73 20 74 68 61 6E 20 +72 2E 00 00 64 69 66 5F 6B 6D 61 63 5F 65 6E 64 +3A 20 45 52 52 4F 52 20 61 72 67 75 6D 65 6E 74 +73 20 6D 61 79 20 6E 6F 74 20 62 65 20 4E 55 4C +4C 2E 00 00 64 69 66 5F 6B 6D 61 63 5F 65 6E 64 +3A 20 45 52 52 4F 52 20 68 61 72 64 77 61 72 65 +20 6D 75 73 74 20 62 65 20 64 6F 6E 65 20 73 71 +75 65 65 7A 69 6E 67 2E 00 00 00 00 53 4F 43 5F +49 46 43 3A 20 43 68 65 63 6B 20 6D 62 6F 78 5F +73 74 61 74 75 73 2E 6D 62 6F 78 5F 66 73 6D 5F +70 73 00 00 53 4F 43 5F 49 46 43 3A 20 43 68 65 +63 6B 20 6D 62 6F 78 5F 73 74 61 74 75 73 2E 6D +62 6F 78 5F 66 73 6D 5F 70 73 20 66 6F 75 6E 64 +20 4D 42 4F 58 5F 45 58 45 43 55 54 45 5F 55 43 +00 00 00 00 53 4F 43 5F 49 46 43 3A 20 43 68 65 +63 6B 20 6D 62 6F 78 5F 73 74 61 74 75 73 2E 6D +62 6F 78 5F 66 73 6D 5F 70 73 20 66 6F 75 6E 64 +20 4D 42 4F 58 5F 49 44 4C 45 00 00 53 4F 43 5F +49 46 43 3A 20 43 68 65 63 6B 20 6D 62 6F 78 5F +73 74 61 74 75 73 2E 6D 62 6F 78 5F 66 73 6D 5F +70 73 20 66 6F 75 6E 64 20 4D 42 4F 58 5F 45 52 +52 4F 52 2C 20 6D 61 69 6C 62 6F 78 20 66 6F 72 +63 65 2D 75 6E 6C 6F 63 6B 20 6E 65 65 64 65 64 +00 00 00 00 53 4F 43 5F 49 46 43 3A 20 42 65 67 +69 6E 6E 69 6E 67 20 6D 62 6F 78 20 66 77 20 66 +6C 6F 77 00 53 4F 43 5F 49 46 43 3A 20 43 70 20 +74 6F 20 49 43 43 4D 00 53 4F 43 5F 49 46 43 3A +20 43 70 20 74 6F 20 44 43 43 4D 00 43 6F 70 79 +69 6E 67 20 63 6F 64 65 20 66 72 6F 6D 20 6D 61 +69 6C 62 6F 78 20 74 6F 20 49 43 43 4D 00 00 00 +46 61 69 6C 65 64 20 74 6F 20 61 63 71 75 69 72 +65 20 6C 6F 63 6B 20 2D 20 6D 62 6F 78 20 73 61 +6E 69 74 69 7A 65 00 00 77 6F 6E 27 74 20 6F 76 +65 72 72 69 64 65 00 00 77 69 6C 6C 20 75 73 65 +20 64 65 66 61 75 6C 74 20 35 00 00 77 69 6C 6C +20 6F 76 65 72 72 69 64 65 00 00 00 46 41 54 41 +4C 3A 20 41 58 49 20 44 4D 41 20 72 65 70 6F 72 +74 73 20 65 72 72 6F 72 20 73 74 61 74 75 73 20 +66 6F 72 20 78 66 65 72 00 00 00 00 41 58 49 20 +44 4D 41 20 72 65 70 6F 72 74 73 20 73 74 61 74 +75 73 20 66 6F 72 20 78 66 65 72 20 74 68 61 74 +20 77 6F 75 6C 64 20 72 65 71 75 69 72 65 20 44 +4D 41 20 46 6C 75 73 68 00 00 00 00 41 58 49 20 +44 4D 41 20 64 69 64 20 6E 6F 74 20 72 65 70 6F +72 74 20 65 72 72 20 73 74 61 74 75 73 20 66 6F +72 20 78 66 65 72 20 74 68 61 74 20 77 6F 75 6C +64 20 72 65 71 75 69 72 65 20 44 4D 41 20 46 6C +75 73 68 00 41 63 71 75 69 72 65 20 6D 61 69 6C +62 6F 78 20 6C 6F 63 6B 20 66 61 69 6C 65 64 00 +46 41 54 41 4C 3A 20 41 58 49 20 44 4D 41 20 72 +65 70 6F 72 74 73 20 65 72 72 6F 72 20 73 74 61 +74 75 73 20 66 6F 72 20 4D 42 4F 58 2D 74 6F 2D +41 58 49 20 78 66 65 72 00 00 00 00 46 57 3A 20 +53 65 6E 64 69 6E 67 20 4B 56 20 74 6F 20 41 58 +49 20 77 69 74 68 20 45 52 52 00 00 41 58 49 20 +44 4D 41 20 72 65 70 6F 72 74 73 20 65 72 72 20 +73 74 61 74 75 73 20 66 6F 72 20 65 72 72 20 69 +6E 6A 65 63 74 69 6F 6E 20 78 66 65 72 00 00 00 +46 41 54 41 4C 3A 20 41 58 49 20 44 4D 41 20 72 +65 70 6F 72 74 73 20 73 75 63 63 65 73 73 20 73 +74 61 74 75 73 20 66 6F 72 20 65 72 72 20 69 6E +6A 65 63 74 69 6F 6E 20 78 66 65 72 21 00 00 00 +46 57 3A 20 53 65 6E 64 69 6E 67 20 4B 56 20 74 +6F 20 41 58 49 00 00 00 46 57 3A 20 41 72 6D 20 +65 72 72 20 63 6F 6D 6D 61 6E 64 00 45 6E 20 69 +6E 74 20 74 6D 72 30 2C 20 68 6C 74 20 63 6F 72 +65 00 00 00 44 69 73 61 62 6C 69 6E 67 20 62 6F +74 68 20 74 69 6D 65 72 73 20 69 6E 20 69 6E 64 +65 70 65 6E 64 65 6E 74 20 6D 6F 64 65 00 00 00 +45 6E 61 62 6C 69 6E 67 20 6F 6E 6C 79 20 74 69 +6D 65 72 32 20 69 6E 20 69 6E 64 65 70 65 6E 64 +65 6E 74 20 6D 6F 64 65 00 00 00 00 45 6E 61 62 +6C 69 6E 67 20 62 6F 74 68 20 74 69 6D 65 72 73 +20 69 6E 20 69 6E 64 65 70 65 6E 64 65 6E 74 20 +6D 6F 64 65 00 00 00 00 20 06 02 50 20 06 02 50 +@00014E74 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +@00016E74 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00